Fix issue for pointers to anonymous types with -fdump-ada-spec
[official-gcc.git] / gcc / gimplify.cc
blobf62f150fc0858f9c62e3e817ae9da81b04de4d46
1 /* Tree lowering pass. This pass converts the GENERIC functions-as-trees
2 tree representation into the GIMPLE form.
3 Copyright (C) 2002-2022 Free Software Foundation, Inc.
4 Major work done by Sebastian Pop <s.pop@laposte.net>,
5 Diego Novillo <dnovillo@redhat.com> and Jason Merrill <jason@redhat.com>.
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
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 "tree-hash-traits.h"
57 #include "omp-general.h"
58 #include "omp-low.h"
59 #include "gimple-low.h"
60 #include "gomp-constants.h"
61 #include "splay-tree.h"
62 #include "gimple-walk.h"
63 #include "langhooks-def.h" /* FIXME: for lhd_set_decl_assembler_name */
64 #include "builtins.h"
65 #include "stringpool.h"
66 #include "attribs.h"
67 #include "asan.h"
68 #include "dbgcnt.h"
69 #include "omp-offload.h"
70 #include "context.h"
71 #include "tree-nested.h"
73 /* Hash set of poisoned variables in a bind expr. */
74 static hash_set<tree> *asan_poisoned_variables = NULL;
76 enum gimplify_omp_var_data
78 GOVD_SEEN = 0x000001,
79 GOVD_EXPLICIT = 0x000002,
80 GOVD_SHARED = 0x000004,
81 GOVD_PRIVATE = 0x000008,
82 GOVD_FIRSTPRIVATE = 0x000010,
83 GOVD_LASTPRIVATE = 0x000020,
84 GOVD_REDUCTION = 0x000040,
85 GOVD_LOCAL = 0x00080,
86 GOVD_MAP = 0x000100,
87 GOVD_DEBUG_PRIVATE = 0x000200,
88 GOVD_PRIVATE_OUTER_REF = 0x000400,
89 GOVD_LINEAR = 0x000800,
90 GOVD_ALIGNED = 0x001000,
92 /* Flag for GOVD_MAP: don't copy back. */
93 GOVD_MAP_TO_ONLY = 0x002000,
95 /* Flag for GOVD_LINEAR or GOVD_LASTPRIVATE: no outer reference. */
96 GOVD_LINEAR_LASTPRIVATE_NO_OUTER = 0x004000,
98 GOVD_MAP_0LEN_ARRAY = 0x008000,
100 /* Flag for GOVD_MAP, if it is always, to or always, tofrom mapping. */
101 GOVD_MAP_ALWAYS_TO = 0x010000,
103 /* Flag for shared vars that are or might be stored to in the region. */
104 GOVD_WRITTEN = 0x020000,
106 /* Flag for GOVD_MAP, if it is a forced mapping. */
107 GOVD_MAP_FORCE = 0x040000,
109 /* Flag for GOVD_MAP: must be present already. */
110 GOVD_MAP_FORCE_PRESENT = 0x080000,
112 /* Flag for GOVD_MAP: only allocate. */
113 GOVD_MAP_ALLOC_ONLY = 0x100000,
115 /* Flag for GOVD_MAP: only copy back. */
116 GOVD_MAP_FROM_ONLY = 0x200000,
118 GOVD_NONTEMPORAL = 0x400000,
120 /* Flag for GOVD_LASTPRIVATE: conditional modifier. */
121 GOVD_LASTPRIVATE_CONDITIONAL = 0x800000,
123 GOVD_CONDTEMP = 0x1000000,
125 /* Flag for GOVD_REDUCTION: inscan seen in {in,ex}clusive clause. */
126 GOVD_REDUCTION_INSCAN = 0x2000000,
128 /* Flag for GOVD_MAP: (struct) vars that have pointer attachments for
129 fields. */
130 GOVD_MAP_HAS_ATTACHMENTS = 0x4000000,
132 /* Flag for GOVD_FIRSTPRIVATE: OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT. */
133 GOVD_FIRSTPRIVATE_IMPLICIT = 0x8000000,
135 GOVD_DATA_SHARE_CLASS = (GOVD_SHARED | GOVD_PRIVATE | GOVD_FIRSTPRIVATE
136 | GOVD_LASTPRIVATE | GOVD_REDUCTION | GOVD_LINEAR
137 | GOVD_LOCAL)
141 enum omp_region_type
143 ORT_WORKSHARE = 0x00,
144 ORT_TASKGROUP = 0x01,
145 ORT_SIMD = 0x04,
147 ORT_PARALLEL = 0x08,
148 ORT_COMBINED_PARALLEL = ORT_PARALLEL | 1,
150 ORT_TASK = 0x10,
151 ORT_UNTIED_TASK = ORT_TASK | 1,
152 ORT_TASKLOOP = ORT_TASK | 2,
153 ORT_UNTIED_TASKLOOP = ORT_UNTIED_TASK | 2,
155 ORT_TEAMS = 0x20,
156 ORT_COMBINED_TEAMS = ORT_TEAMS | 1,
157 ORT_HOST_TEAMS = ORT_TEAMS | 2,
158 ORT_COMBINED_HOST_TEAMS = ORT_COMBINED_TEAMS | 2,
160 /* Data region. */
161 ORT_TARGET_DATA = 0x40,
163 /* Data region with offloading. */
164 ORT_TARGET = 0x80,
165 ORT_COMBINED_TARGET = ORT_TARGET | 1,
166 ORT_IMPLICIT_TARGET = ORT_TARGET | 2,
168 /* OpenACC variants. */
169 ORT_ACC = 0x100, /* A generic OpenACC region. */
170 ORT_ACC_DATA = ORT_ACC | ORT_TARGET_DATA, /* Data construct. */
171 ORT_ACC_PARALLEL = ORT_ACC | ORT_TARGET, /* Parallel construct */
172 ORT_ACC_KERNELS = ORT_ACC | ORT_TARGET | 2, /* Kernels construct. */
173 ORT_ACC_SERIAL = ORT_ACC | ORT_TARGET | 4, /* Serial construct. */
174 ORT_ACC_HOST_DATA = ORT_ACC | ORT_TARGET_DATA | 2, /* Host data. */
176 /* Dummy OpenMP region, used to disable expansion of
177 DECL_VALUE_EXPRs in taskloop pre body. */
178 ORT_NONE = 0x200
181 /* Gimplify hashtable helper. */
183 struct gimplify_hasher : free_ptr_hash <elt_t>
185 static inline hashval_t hash (const elt_t *);
186 static inline bool equal (const elt_t *, const elt_t *);
189 struct gimplify_ctx
191 struct gimplify_ctx *prev_context;
193 vec<gbind *> bind_expr_stack;
194 tree temps;
195 gimple_seq conditional_cleanups;
196 tree exit_label;
197 tree return_temp;
199 vec<tree> case_labels;
200 hash_set<tree> *live_switch_vars;
201 /* The formal temporary table. Should this be persistent? */
202 hash_table<gimplify_hasher> *temp_htab;
204 int conditions;
205 unsigned into_ssa : 1;
206 unsigned allow_rhs_cond_expr : 1;
207 unsigned in_cleanup_point_expr : 1;
208 unsigned keep_stack : 1;
209 unsigned save_stack : 1;
210 unsigned in_switch_expr : 1;
213 enum gimplify_defaultmap_kind
215 GDMK_SCALAR,
216 GDMK_SCALAR_TARGET, /* w/ Fortran's target attr, implicit mapping, only. */
217 GDMK_AGGREGATE,
218 GDMK_ALLOCATABLE,
219 GDMK_POINTER
222 struct gimplify_omp_ctx
224 struct gimplify_omp_ctx *outer_context;
225 splay_tree variables;
226 hash_set<tree> *privatized_types;
227 tree clauses;
228 /* Iteration variables in an OMP_FOR. */
229 vec<tree> loop_iter_var;
230 location_t location;
231 enum omp_clause_default_kind default_kind;
232 enum omp_region_type region_type;
233 enum tree_code code;
234 bool combined_loop;
235 bool distribute;
236 bool target_firstprivatize_array_bases;
237 bool add_safelen1;
238 bool order_concurrent;
239 bool has_depend;
240 bool in_for_exprs;
241 int defaultmap[5];
244 static struct gimplify_ctx *gimplify_ctxp;
245 static struct gimplify_omp_ctx *gimplify_omp_ctxp;
246 static bool in_omp_construct;
248 /* Forward declaration. */
249 static enum gimplify_status gimplify_compound_expr (tree *, gimple_seq *, bool);
250 static hash_map<tree, tree> *oacc_declare_returns;
251 static enum gimplify_status gimplify_expr (tree *, gimple_seq *, gimple_seq *,
252 bool (*) (tree), fallback_t, bool);
253 static void prepare_gimple_addressable (tree *, gimple_seq *);
255 /* Shorter alias name for the above function for use in gimplify.cc
256 only. */
258 static inline void
259 gimplify_seq_add_stmt (gimple_seq *seq_p, gimple *gs)
261 gimple_seq_add_stmt_without_update (seq_p, gs);
264 /* Append sequence SRC to the end of sequence *DST_P. If *DST_P is
265 NULL, a new sequence is allocated. This function is
266 similar to gimple_seq_add_seq, but does not scan the operands.
267 During gimplification, we need to manipulate statement sequences
268 before the def/use vectors have been constructed. */
270 static void
271 gimplify_seq_add_seq (gimple_seq *dst_p, gimple_seq src)
273 gimple_stmt_iterator si;
275 if (src == NULL)
276 return;
278 si = gsi_last (*dst_p);
279 gsi_insert_seq_after_without_update (&si, src, GSI_NEW_STMT);
283 /* Pointer to a list of allocated gimplify_ctx structs to be used for pushing
284 and popping gimplify contexts. */
286 static struct gimplify_ctx *ctx_pool = NULL;
288 /* Return a gimplify context struct from the pool. */
290 static inline struct gimplify_ctx *
291 ctx_alloc (void)
293 struct gimplify_ctx * c = ctx_pool;
295 if (c)
296 ctx_pool = c->prev_context;
297 else
298 c = XNEW (struct gimplify_ctx);
300 memset (c, '\0', sizeof (*c));
301 return c;
304 /* Put gimplify context C back into the pool. */
306 static inline void
307 ctx_free (struct gimplify_ctx *c)
309 c->prev_context = ctx_pool;
310 ctx_pool = c;
313 /* Free allocated ctx stack memory. */
315 void
316 free_gimplify_stack (void)
318 struct gimplify_ctx *c;
320 while ((c = ctx_pool))
322 ctx_pool = c->prev_context;
323 free (c);
328 /* Set up a context for the gimplifier. */
330 void
331 push_gimplify_context (bool in_ssa, bool rhs_cond_ok)
333 struct gimplify_ctx *c = ctx_alloc ();
335 c->prev_context = gimplify_ctxp;
336 gimplify_ctxp = c;
337 gimplify_ctxp->into_ssa = in_ssa;
338 gimplify_ctxp->allow_rhs_cond_expr = rhs_cond_ok;
341 /* Tear down a context for the gimplifier. If BODY is non-null, then
342 put the temporaries into the outer BIND_EXPR. Otherwise, put them
343 in the local_decls.
345 BODY is not a sequence, but the first tuple in a sequence. */
347 void
348 pop_gimplify_context (gimple *body)
350 struct gimplify_ctx *c = gimplify_ctxp;
352 gcc_assert (c
353 && (!c->bind_expr_stack.exists ()
354 || c->bind_expr_stack.is_empty ()));
355 c->bind_expr_stack.release ();
356 gimplify_ctxp = c->prev_context;
358 if (body)
359 declare_vars (c->temps, body, false);
360 else
361 record_vars (c->temps);
363 delete c->temp_htab;
364 c->temp_htab = NULL;
365 ctx_free (c);
368 /* Push a GIMPLE_BIND tuple onto the stack of bindings. */
370 static void
371 gimple_push_bind_expr (gbind *bind_stmt)
373 gimplify_ctxp->bind_expr_stack.reserve (8);
374 gimplify_ctxp->bind_expr_stack.safe_push (bind_stmt);
377 /* Pop the first element off the stack of bindings. */
379 static void
380 gimple_pop_bind_expr (void)
382 gimplify_ctxp->bind_expr_stack.pop ();
385 /* Return the first element of the stack of bindings. */
387 gbind *
388 gimple_current_bind_expr (void)
390 return gimplify_ctxp->bind_expr_stack.last ();
393 /* Return the stack of bindings created during gimplification. */
395 vec<gbind *>
396 gimple_bind_expr_stack (void)
398 return gimplify_ctxp->bind_expr_stack;
401 /* Return true iff there is a COND_EXPR between us and the innermost
402 CLEANUP_POINT_EXPR. This info is used by gimple_push_cleanup. */
404 static bool
405 gimple_conditional_context (void)
407 return gimplify_ctxp->conditions > 0;
410 /* Note that we've entered a COND_EXPR. */
412 static void
413 gimple_push_condition (void)
415 #ifdef ENABLE_GIMPLE_CHECKING
416 if (gimplify_ctxp->conditions == 0)
417 gcc_assert (gimple_seq_empty_p (gimplify_ctxp->conditional_cleanups));
418 #endif
419 ++(gimplify_ctxp->conditions);
422 /* Note that we've left a COND_EXPR. If we're back at unconditional scope
423 now, add any conditional cleanups we've seen to the prequeue. */
425 static void
426 gimple_pop_condition (gimple_seq *pre_p)
428 int conds = --(gimplify_ctxp->conditions);
430 gcc_assert (conds >= 0);
431 if (conds == 0)
433 gimplify_seq_add_seq (pre_p, gimplify_ctxp->conditional_cleanups);
434 gimplify_ctxp->conditional_cleanups = NULL;
438 /* A stable comparison routine for use with splay trees and DECLs. */
440 static int
441 splay_tree_compare_decl_uid (splay_tree_key xa, splay_tree_key xb)
443 tree a = (tree) xa;
444 tree b = (tree) xb;
446 return DECL_UID (a) - DECL_UID (b);
449 /* Create a new omp construct that deals with variable remapping. */
451 static struct gimplify_omp_ctx *
452 new_omp_context (enum omp_region_type region_type)
454 struct gimplify_omp_ctx *c;
456 c = XCNEW (struct gimplify_omp_ctx);
457 c->outer_context = gimplify_omp_ctxp;
458 c->variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0);
459 c->privatized_types = new hash_set<tree>;
460 c->location = input_location;
461 c->region_type = region_type;
462 if ((region_type & ORT_TASK) == 0)
463 c->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
464 else
465 c->default_kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
466 c->defaultmap[GDMK_SCALAR] = GOVD_MAP;
467 c->defaultmap[GDMK_SCALAR_TARGET] = GOVD_MAP;
468 c->defaultmap[GDMK_AGGREGATE] = GOVD_MAP;
469 c->defaultmap[GDMK_ALLOCATABLE] = GOVD_MAP;
470 c->defaultmap[GDMK_POINTER] = GOVD_MAP;
472 return c;
475 /* Destroy an omp construct that deals with variable remapping. */
477 static void
478 delete_omp_context (struct gimplify_omp_ctx *c)
480 splay_tree_delete (c->variables);
481 delete c->privatized_types;
482 c->loop_iter_var.release ();
483 XDELETE (c);
486 static void omp_add_variable (struct gimplify_omp_ctx *, tree, unsigned int);
487 static bool omp_notice_variable (struct gimplify_omp_ctx *, tree, bool);
489 /* Both gimplify the statement T and append it to *SEQ_P. This function
490 behaves exactly as gimplify_stmt, but you don't have to pass T as a
491 reference. */
493 void
494 gimplify_and_add (tree t, gimple_seq *seq_p)
496 gimplify_stmt (&t, seq_p);
499 /* Gimplify statement T into sequence *SEQ_P, and return the first
500 tuple in the sequence of generated tuples for this statement.
501 Return NULL if gimplifying T produced no tuples. */
503 static gimple *
504 gimplify_and_return_first (tree t, gimple_seq *seq_p)
506 gimple_stmt_iterator last = gsi_last (*seq_p);
508 gimplify_and_add (t, seq_p);
510 if (!gsi_end_p (last))
512 gsi_next (&last);
513 return gsi_stmt (last);
515 else
516 return gimple_seq_first_stmt (*seq_p);
519 /* Returns true iff T is a valid RHS for an assignment to an un-renamed
520 LHS, or for a call argument. */
522 static bool
523 is_gimple_mem_rhs (tree t)
525 /* If we're dealing with a renamable type, either source or dest must be
526 a renamed variable. */
527 if (is_gimple_reg_type (TREE_TYPE (t)))
528 return is_gimple_val (t);
529 else
530 return is_gimple_val (t) || is_gimple_lvalue (t);
533 /* Return true if T is a CALL_EXPR or an expression that can be
534 assigned to a temporary. Note that this predicate should only be
535 used during gimplification. See the rationale for this in
536 gimplify_modify_expr. */
538 static bool
539 is_gimple_reg_rhs_or_call (tree t)
541 return (get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS
542 || TREE_CODE (t) == CALL_EXPR);
545 /* Return true if T is a valid memory RHS or a CALL_EXPR. Note that
546 this predicate should only be used during gimplification. See the
547 rationale for this in gimplify_modify_expr. */
549 static bool
550 is_gimple_mem_rhs_or_call (tree t)
552 /* If we're dealing with a renamable type, either source or dest must be
553 a renamed variable. */
554 if (is_gimple_reg_type (TREE_TYPE (t)))
555 return is_gimple_val (t);
556 else
557 return (is_gimple_val (t)
558 || is_gimple_lvalue (t)
559 || TREE_CLOBBER_P (t)
560 || TREE_CODE (t) == CALL_EXPR);
563 /* Create a temporary with a name derived from VAL. Subroutine of
564 lookup_tmp_var; nobody else should call this function. */
566 static inline tree
567 create_tmp_from_val (tree val)
569 /* Drop all qualifiers and address-space information from the value type. */
570 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (val));
571 tree var = create_tmp_var (type, get_name (val));
572 return var;
575 /* Create a temporary to hold the value of VAL. If IS_FORMAL, try to reuse
576 an existing expression temporary. */
578 static tree
579 lookup_tmp_var (tree val, bool is_formal)
581 tree ret;
583 /* If not optimizing, never really reuse a temporary. local-alloc
584 won't allocate any variable that is used in more than one basic
585 block, which means it will go into memory, causing much extra
586 work in reload and final and poorer code generation, outweighing
587 the extra memory allocation here. */
588 if (!optimize || !is_formal || TREE_SIDE_EFFECTS (val))
589 ret = create_tmp_from_val (val);
590 else
592 elt_t elt, *elt_p;
593 elt_t **slot;
595 elt.val = val;
596 if (!gimplify_ctxp->temp_htab)
597 gimplify_ctxp->temp_htab = new hash_table<gimplify_hasher> (1000);
598 slot = gimplify_ctxp->temp_htab->find_slot (&elt, INSERT);
599 if (*slot == NULL)
601 elt_p = XNEW (elt_t);
602 elt_p->val = val;
603 elt_p->temp = ret = create_tmp_from_val (val);
604 *slot = elt_p;
606 else
608 elt_p = *slot;
609 ret = elt_p->temp;
613 return ret;
616 /* Helper for get_formal_tmp_var and get_initialized_tmp_var. */
618 static tree
619 internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
620 bool is_formal, bool allow_ssa)
622 tree t, mod;
624 /* Notice that we explicitly allow VAL to be a CALL_EXPR so that we
625 can create an INIT_EXPR and convert it into a GIMPLE_CALL below. */
626 gimplify_expr (&val, pre_p, post_p, is_gimple_reg_rhs_or_call,
627 fb_rvalue);
629 if (allow_ssa
630 && gimplify_ctxp->into_ssa
631 && is_gimple_reg_type (TREE_TYPE (val)))
633 t = make_ssa_name (TYPE_MAIN_VARIANT (TREE_TYPE (val)));
634 if (! gimple_in_ssa_p (cfun))
636 const char *name = get_name (val);
637 if (name)
638 SET_SSA_NAME_VAR_OR_IDENTIFIER (t, create_tmp_var_name (name));
641 else
642 t = lookup_tmp_var (val, is_formal);
644 mod = build2 (INIT_EXPR, TREE_TYPE (t), t, unshare_expr (val));
646 SET_EXPR_LOCATION (mod, EXPR_LOC_OR_LOC (val, input_location));
648 /* gimplify_modify_expr might want to reduce this further. */
649 gimplify_and_add (mod, pre_p);
650 ggc_free (mod);
652 return t;
655 /* Return a formal temporary variable initialized with VAL. PRE_P is as
656 in gimplify_expr. Only use this function if:
658 1) The value of the unfactored expression represented by VAL will not
659 change between the initialization and use of the temporary, and
660 2) The temporary will not be otherwise modified.
662 For instance, #1 means that this is inappropriate for SAVE_EXPR temps,
663 and #2 means it is inappropriate for && temps.
665 For other cases, use get_initialized_tmp_var instead. */
667 tree
668 get_formal_tmp_var (tree val, gimple_seq *pre_p)
670 return internal_get_tmp_var (val, pre_p, NULL, true, true);
673 /* Return a temporary variable initialized with VAL. PRE_P and POST_P
674 are as in gimplify_expr. */
676 tree
677 get_initialized_tmp_var (tree val, gimple_seq *pre_p,
678 gimple_seq *post_p /* = NULL */,
679 bool allow_ssa /* = true */)
681 return internal_get_tmp_var (val, pre_p, post_p, false, allow_ssa);
684 /* Declare all the variables in VARS in SCOPE. If DEBUG_INFO is true,
685 generate debug info for them; otherwise don't. */
687 void
688 declare_vars (tree vars, gimple *gs, bool debug_info)
690 tree last = vars;
691 if (last)
693 tree temps, block;
695 gbind *scope = as_a <gbind *> (gs);
697 temps = nreverse (last);
699 block = gimple_bind_block (scope);
700 gcc_assert (!block || TREE_CODE (block) == BLOCK);
701 if (!block || !debug_info)
703 DECL_CHAIN (last) = gimple_bind_vars (scope);
704 gimple_bind_set_vars (scope, temps);
706 else
708 /* We need to attach the nodes both to the BIND_EXPR and to its
709 associated BLOCK for debugging purposes. The key point here
710 is that the BLOCK_VARS of the BIND_EXPR_BLOCK of a BIND_EXPR
711 is a subchain of the BIND_EXPR_VARS of the BIND_EXPR. */
712 if (BLOCK_VARS (block))
713 BLOCK_VARS (block) = chainon (BLOCK_VARS (block), temps);
714 else
716 gimple_bind_set_vars (scope,
717 chainon (gimple_bind_vars (scope), temps));
718 BLOCK_VARS (block) = temps;
724 /* For VAR a VAR_DECL of variable size, try to find a constant upper bound
725 for the size and adjust DECL_SIZE/DECL_SIZE_UNIT accordingly. Abort if
726 no such upper bound can be obtained. */
728 static void
729 force_constant_size (tree var)
731 /* The only attempt we make is by querying the maximum size of objects
732 of the variable's type. */
734 HOST_WIDE_INT max_size;
736 gcc_assert (VAR_P (var));
738 max_size = max_int_size_in_bytes (TREE_TYPE (var));
740 gcc_assert (max_size >= 0);
742 DECL_SIZE_UNIT (var)
743 = build_int_cst (TREE_TYPE (DECL_SIZE_UNIT (var)), max_size);
744 DECL_SIZE (var)
745 = build_int_cst (TREE_TYPE (DECL_SIZE (var)), max_size * BITS_PER_UNIT);
748 /* Push the temporary variable TMP into the current binding. */
750 void
751 gimple_add_tmp_var_fn (struct function *fn, tree tmp)
753 gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
755 /* Later processing assumes that the object size is constant, which might
756 not be true at this point. Force the use of a constant upper bound in
757 this case. */
758 if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp)))
759 force_constant_size (tmp);
761 DECL_CONTEXT (tmp) = fn->decl;
762 DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
764 record_vars_into (tmp, fn->decl);
767 /* Push the temporary variable TMP into the current binding. */
769 void
770 gimple_add_tmp_var (tree tmp)
772 gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
774 /* Later processing assumes that the object size is constant, which might
775 not be true at this point. Force the use of a constant upper bound in
776 this case. */
777 if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp)))
778 force_constant_size (tmp);
780 DECL_CONTEXT (tmp) = current_function_decl;
781 DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
783 if (gimplify_ctxp)
785 DECL_CHAIN (tmp) = gimplify_ctxp->temps;
786 gimplify_ctxp->temps = tmp;
788 /* Mark temporaries local within the nearest enclosing parallel. */
789 if (gimplify_omp_ctxp)
791 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
792 int flag = GOVD_LOCAL | GOVD_SEEN;
793 while (ctx
794 && (ctx->region_type == ORT_WORKSHARE
795 || ctx->region_type == ORT_TASKGROUP
796 || ctx->region_type == ORT_SIMD
797 || ctx->region_type == ORT_ACC))
799 if (ctx->region_type == ORT_SIMD
800 && TREE_ADDRESSABLE (tmp)
801 && !TREE_STATIC (tmp))
803 if (TREE_CODE (DECL_SIZE_UNIT (tmp)) != INTEGER_CST)
804 ctx->add_safelen1 = true;
805 else if (ctx->in_for_exprs)
806 flag = GOVD_PRIVATE;
807 else
808 flag = GOVD_PRIVATE | GOVD_SEEN;
809 break;
811 ctx = ctx->outer_context;
813 if (ctx)
814 omp_add_variable (ctx, tmp, flag);
817 else if (cfun)
818 record_vars (tmp);
819 else
821 gimple_seq body_seq;
823 /* This case is for nested functions. We need to expose the locals
824 they create. */
825 body_seq = gimple_body (current_function_decl);
826 declare_vars (tmp, gimple_seq_first_stmt (body_seq), false);
832 /* This page contains routines to unshare tree nodes, i.e. to duplicate tree
833 nodes that are referenced more than once in GENERIC functions. This is
834 necessary because gimplification (translation into GIMPLE) is performed
835 by modifying tree nodes in-place, so gimplication of a shared node in a
836 first context could generate an invalid GIMPLE form in a second context.
838 This is achieved with a simple mark/copy/unmark algorithm that walks the
839 GENERIC representation top-down, marks nodes with TREE_VISITED the first
840 time it encounters them, duplicates them if they already have TREE_VISITED
841 set, and finally removes the TREE_VISITED marks it has set.
843 The algorithm works only at the function level, i.e. it generates a GENERIC
844 representation of a function with no nodes shared within the function when
845 passed a GENERIC function (except for nodes that are allowed to be shared).
847 At the global level, it is also necessary to unshare tree nodes that are
848 referenced in more than one function, for the same aforementioned reason.
849 This requires some cooperation from the front-end. There are 2 strategies:
851 1. Manual unsharing. The front-end needs to call unshare_expr on every
852 expression that might end up being shared across functions.
854 2. Deep unsharing. This is an extension of regular unsharing. Instead
855 of calling unshare_expr on expressions that might be shared across
856 functions, the front-end pre-marks them with TREE_VISITED. This will
857 ensure that they are unshared on the first reference within functions
858 when the regular unsharing algorithm runs. The counterpart is that
859 this algorithm must look deeper than for manual unsharing, which is
860 specified by LANG_HOOKS_DEEP_UNSHARING.
862 If there are only few specific cases of node sharing across functions, it is
863 probably easier for a front-end to unshare the expressions manually. On the
864 contrary, if the expressions generated at the global level are as widespread
865 as expressions generated within functions, deep unsharing is very likely the
866 way to go. */
868 /* Similar to copy_tree_r but do not copy SAVE_EXPR or TARGET_EXPR nodes.
869 These nodes model computations that must be done once. If we were to
870 unshare something like SAVE_EXPR(i++), the gimplification process would
871 create wrong code. However, if DATA is non-null, it must hold a pointer
872 set that is used to unshare the subtrees of these nodes. */
874 static tree
875 mostly_copy_tree_r (tree *tp, int *walk_subtrees, void *data)
877 tree t = *tp;
878 enum tree_code code = TREE_CODE (t);
880 /* Do not copy SAVE_EXPR, TARGET_EXPR or BIND_EXPR nodes themselves, but
881 copy their subtrees if we can make sure to do it only once. */
882 if (code == SAVE_EXPR || code == TARGET_EXPR || code == BIND_EXPR)
884 if (data && !((hash_set<tree> *)data)->add (t))
886 else
887 *walk_subtrees = 0;
890 /* Stop at types, decls, constants like copy_tree_r. */
891 else if (TREE_CODE_CLASS (code) == tcc_type
892 || TREE_CODE_CLASS (code) == tcc_declaration
893 || TREE_CODE_CLASS (code) == tcc_constant)
894 *walk_subtrees = 0;
896 /* Cope with the statement expression extension. */
897 else if (code == STATEMENT_LIST)
900 /* Leave the bulk of the work to copy_tree_r itself. */
901 else
902 copy_tree_r (tp, walk_subtrees, NULL);
904 return NULL_TREE;
907 /* Callback for walk_tree to unshare most of the shared trees rooted at *TP.
908 If *TP has been visited already, then *TP is deeply copied by calling
909 mostly_copy_tree_r. DATA is passed to mostly_copy_tree_r unmodified. */
911 static tree
912 copy_if_shared_r (tree *tp, int *walk_subtrees, void *data)
914 tree t = *tp;
915 enum tree_code code = TREE_CODE (t);
917 /* Skip types, decls, and constants. But we do want to look at their
918 types and the bounds of types. Mark them as visited so we properly
919 unmark their subtrees on the unmark pass. If we've already seen them,
920 don't look down further. */
921 if (TREE_CODE_CLASS (code) == tcc_type
922 || TREE_CODE_CLASS (code) == tcc_declaration
923 || TREE_CODE_CLASS (code) == tcc_constant)
925 if (TREE_VISITED (t))
926 *walk_subtrees = 0;
927 else
928 TREE_VISITED (t) = 1;
931 /* If this node has been visited already, unshare it and don't look
932 any deeper. */
933 else if (TREE_VISITED (t))
935 walk_tree (tp, mostly_copy_tree_r, data, NULL);
936 *walk_subtrees = 0;
939 /* Otherwise, mark the node as visited and keep looking. */
940 else
941 TREE_VISITED (t) = 1;
943 return NULL_TREE;
946 /* Unshare most of the shared trees rooted at *TP. DATA is passed to the
947 copy_if_shared_r callback unmodified. */
949 void
950 copy_if_shared (tree *tp, void *data)
952 walk_tree (tp, copy_if_shared_r, data, NULL);
955 /* Unshare all the trees in the body of FNDECL, as well as in the bodies of
956 any nested functions. */
958 static void
959 unshare_body (tree fndecl)
961 struct cgraph_node *cgn = cgraph_node::get (fndecl);
962 /* If the language requires deep unsharing, we need a pointer set to make
963 sure we don't repeatedly unshare subtrees of unshareable nodes. */
964 hash_set<tree> *visited
965 = lang_hooks.deep_unsharing ? new hash_set<tree> : NULL;
967 copy_if_shared (&DECL_SAVED_TREE (fndecl), visited);
968 copy_if_shared (&DECL_SIZE (DECL_RESULT (fndecl)), visited);
969 copy_if_shared (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)), visited);
971 delete visited;
973 if (cgn)
974 for (cgn = first_nested_function (cgn); cgn;
975 cgn = next_nested_function (cgn))
976 unshare_body (cgn->decl);
979 /* Callback for walk_tree to unmark the visited trees rooted at *TP.
980 Subtrees are walked until the first unvisited node is encountered. */
982 static tree
983 unmark_visited_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
985 tree t = *tp;
987 /* If this node has been visited, unmark it and keep looking. */
988 if (TREE_VISITED (t))
989 TREE_VISITED (t) = 0;
991 /* Otherwise, don't look any deeper. */
992 else
993 *walk_subtrees = 0;
995 return NULL_TREE;
998 /* Unmark the visited trees rooted at *TP. */
1000 static inline void
1001 unmark_visited (tree *tp)
1003 walk_tree (tp, unmark_visited_r, NULL, NULL);
1006 /* Likewise, but mark all trees as not visited. */
1008 static void
1009 unvisit_body (tree fndecl)
1011 struct cgraph_node *cgn = cgraph_node::get (fndecl);
1013 unmark_visited (&DECL_SAVED_TREE (fndecl));
1014 unmark_visited (&DECL_SIZE (DECL_RESULT (fndecl)));
1015 unmark_visited (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)));
1017 if (cgn)
1018 for (cgn = first_nested_function (cgn);
1019 cgn; cgn = next_nested_function (cgn))
1020 unvisit_body (cgn->decl);
1023 /* Unconditionally make an unshared copy of EXPR. This is used when using
1024 stored expressions which span multiple functions, such as BINFO_VTABLE,
1025 as the normal unsharing process can't tell that they're shared. */
1027 tree
1028 unshare_expr (tree expr)
1030 walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
1031 return expr;
1034 /* Worker for unshare_expr_without_location. */
1036 static tree
1037 prune_expr_location (tree *tp, int *walk_subtrees, void *)
1039 if (EXPR_P (*tp))
1040 SET_EXPR_LOCATION (*tp, UNKNOWN_LOCATION);
1041 else
1042 *walk_subtrees = 0;
1043 return NULL_TREE;
1046 /* Similar to unshare_expr but also prune all expression locations
1047 from EXPR. */
1049 tree
1050 unshare_expr_without_location (tree expr)
1052 walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
1053 if (EXPR_P (expr))
1054 walk_tree (&expr, prune_expr_location, NULL, NULL);
1055 return expr;
1058 /* Return the EXPR_LOCATION of EXPR, if it (maybe recursively) has
1059 one, OR_ELSE otherwise. The location of a STATEMENT_LISTs
1060 comprising at least one DEBUG_BEGIN_STMT followed by exactly one
1061 EXPR is the location of the EXPR. */
1063 static location_t
1064 rexpr_location (tree expr, location_t or_else = UNKNOWN_LOCATION)
1066 if (!expr)
1067 return or_else;
1069 if (EXPR_HAS_LOCATION (expr))
1070 return EXPR_LOCATION (expr);
1072 if (TREE_CODE (expr) != STATEMENT_LIST)
1073 return or_else;
1075 tree_stmt_iterator i = tsi_start (expr);
1077 bool found = false;
1078 while (!tsi_end_p (i) && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT)
1080 found = true;
1081 tsi_next (&i);
1084 if (!found || !tsi_one_before_end_p (i))
1085 return or_else;
1087 return rexpr_location (tsi_stmt (i), or_else);
1090 /* Return TRUE iff EXPR (maybe recursively) has a location; see
1091 rexpr_location for the potential recursion. */
1093 static inline bool
1094 rexpr_has_location (tree expr)
1096 return rexpr_location (expr) != UNKNOWN_LOCATION;
1100 /* WRAPPER is a code such as BIND_EXPR or CLEANUP_POINT_EXPR which can both
1101 contain statements and have a value. Assign its value to a temporary
1102 and give it void_type_node. Return the temporary, or NULL_TREE if
1103 WRAPPER was already void. */
1105 tree
1106 voidify_wrapper_expr (tree wrapper, tree temp)
1108 tree type = TREE_TYPE (wrapper);
1109 if (type && !VOID_TYPE_P (type))
1111 tree *p;
1113 /* Set p to point to the body of the wrapper. Loop until we find
1114 something that isn't a wrapper. */
1115 for (p = &wrapper; p && *p; )
1117 switch (TREE_CODE (*p))
1119 case BIND_EXPR:
1120 TREE_SIDE_EFFECTS (*p) = 1;
1121 TREE_TYPE (*p) = void_type_node;
1122 /* For a BIND_EXPR, the body is operand 1. */
1123 p = &BIND_EXPR_BODY (*p);
1124 break;
1126 case CLEANUP_POINT_EXPR:
1127 case TRY_FINALLY_EXPR:
1128 case TRY_CATCH_EXPR:
1129 TREE_SIDE_EFFECTS (*p) = 1;
1130 TREE_TYPE (*p) = void_type_node;
1131 p = &TREE_OPERAND (*p, 0);
1132 break;
1134 case STATEMENT_LIST:
1136 tree_stmt_iterator i = tsi_last (*p);
1137 TREE_SIDE_EFFECTS (*p) = 1;
1138 TREE_TYPE (*p) = void_type_node;
1139 p = tsi_end_p (i) ? NULL : tsi_stmt_ptr (i);
1141 break;
1143 case COMPOUND_EXPR:
1144 /* Advance to the last statement. Set all container types to
1145 void. */
1146 for (; TREE_CODE (*p) == COMPOUND_EXPR; p = &TREE_OPERAND (*p, 1))
1148 TREE_SIDE_EFFECTS (*p) = 1;
1149 TREE_TYPE (*p) = void_type_node;
1151 break;
1153 case TRANSACTION_EXPR:
1154 TREE_SIDE_EFFECTS (*p) = 1;
1155 TREE_TYPE (*p) = void_type_node;
1156 p = &TRANSACTION_EXPR_BODY (*p);
1157 break;
1159 default:
1160 /* Assume that any tree upon which voidify_wrapper_expr is
1161 directly called is a wrapper, and that its body is op0. */
1162 if (p == &wrapper)
1164 TREE_SIDE_EFFECTS (*p) = 1;
1165 TREE_TYPE (*p) = void_type_node;
1166 p = &TREE_OPERAND (*p, 0);
1167 break;
1169 goto out;
1173 out:
1174 if (p == NULL || IS_EMPTY_STMT (*p))
1175 temp = NULL_TREE;
1176 else if (temp)
1178 /* The wrapper is on the RHS of an assignment that we're pushing
1179 down. */
1180 gcc_assert (TREE_CODE (temp) == INIT_EXPR
1181 || TREE_CODE (temp) == MODIFY_EXPR);
1182 TREE_OPERAND (temp, 1) = *p;
1183 *p = temp;
1185 else
1187 temp = create_tmp_var (type, "retval");
1188 *p = build2 (INIT_EXPR, type, temp, *p);
1191 return temp;
1194 return NULL_TREE;
1197 /* Prepare calls to builtins to SAVE and RESTORE the stack as well as
1198 a temporary through which they communicate. */
1200 static void
1201 build_stack_save_restore (gcall **save, gcall **restore)
1203 tree tmp_var;
1205 *save = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_SAVE), 0);
1206 tmp_var = create_tmp_var (ptr_type_node, "saved_stack");
1207 gimple_call_set_lhs (*save, tmp_var);
1209 *restore
1210 = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_RESTORE),
1211 1, tmp_var);
1214 /* Generate IFN_ASAN_MARK call that poisons shadow of a for DECL variable. */
1216 static tree
1217 build_asan_poison_call_expr (tree decl)
1219 /* Do not poison variables that have size equal to zero. */
1220 tree unit_size = DECL_SIZE_UNIT (decl);
1221 if (zerop (unit_size))
1222 return NULL_TREE;
1224 tree base = build_fold_addr_expr (decl);
1226 return build_call_expr_internal_loc (UNKNOWN_LOCATION, IFN_ASAN_MARK,
1227 void_type_node, 3,
1228 build_int_cst (integer_type_node,
1229 ASAN_MARK_POISON),
1230 base, unit_size);
1233 /* Generate IFN_ASAN_MARK call that would poison or unpoison, depending
1234 on POISON flag, shadow memory of a DECL variable. The call will be
1235 put on location identified by IT iterator, where BEFORE flag drives
1236 position where the stmt will be put. */
1238 static void
1239 asan_poison_variable (tree decl, bool poison, gimple_stmt_iterator *it,
1240 bool before)
1242 tree unit_size = DECL_SIZE_UNIT (decl);
1243 tree base = build_fold_addr_expr (decl);
1245 /* Do not poison variables that have size equal to zero. */
1246 if (zerop (unit_size))
1247 return;
1249 /* It's necessary to have all stack variables aligned to ASAN granularity
1250 bytes. */
1251 gcc_assert (!hwasan_sanitize_p () || hwasan_sanitize_stack_p ());
1252 unsigned shadow_granularity
1253 = hwasan_sanitize_p () ? HWASAN_TAG_GRANULE_SIZE : ASAN_SHADOW_GRANULARITY;
1254 if (DECL_ALIGN_UNIT (decl) <= shadow_granularity)
1255 SET_DECL_ALIGN (decl, BITS_PER_UNIT * shadow_granularity);
1257 HOST_WIDE_INT flags = poison ? ASAN_MARK_POISON : ASAN_MARK_UNPOISON;
1259 gimple *g
1260 = gimple_build_call_internal (IFN_ASAN_MARK, 3,
1261 build_int_cst (integer_type_node, flags),
1262 base, unit_size);
1264 if (before)
1265 gsi_insert_before (it, g, GSI_NEW_STMT);
1266 else
1267 gsi_insert_after (it, g, GSI_NEW_STMT);
1270 /* Generate IFN_ASAN_MARK internal call that depending on POISON flag
1271 either poisons or unpoisons a DECL. Created statement is appended
1272 to SEQ_P gimple sequence. */
1274 static void
1275 asan_poison_variable (tree decl, bool poison, gimple_seq *seq_p)
1277 gimple_stmt_iterator it = gsi_last (*seq_p);
1278 bool before = false;
1280 if (gsi_end_p (it))
1281 before = true;
1283 asan_poison_variable (decl, poison, &it, before);
1286 /* Sort pair of VAR_DECLs A and B by DECL_UID. */
1288 static int
1289 sort_by_decl_uid (const void *a, const void *b)
1291 const tree *t1 = (const tree *)a;
1292 const tree *t2 = (const tree *)b;
1294 int uid1 = DECL_UID (*t1);
1295 int uid2 = DECL_UID (*t2);
1297 if (uid1 < uid2)
1298 return -1;
1299 else if (uid1 > uid2)
1300 return 1;
1301 else
1302 return 0;
1305 /* Generate IFN_ASAN_MARK internal call for all VARIABLES
1306 depending on POISON flag. Created statement is appended
1307 to SEQ_P gimple sequence. */
1309 static void
1310 asan_poison_variables (hash_set<tree> *variables, bool poison, gimple_seq *seq_p)
1312 unsigned c = variables->elements ();
1313 if (c == 0)
1314 return;
1316 auto_vec<tree> sorted_variables (c);
1318 for (hash_set<tree>::iterator it = variables->begin ();
1319 it != variables->end (); ++it)
1320 sorted_variables.safe_push (*it);
1322 sorted_variables.qsort (sort_by_decl_uid);
1324 unsigned i;
1325 tree var;
1326 FOR_EACH_VEC_ELT (sorted_variables, i, var)
1328 asan_poison_variable (var, poison, seq_p);
1330 /* Add use_after_scope_memory attribute for the variable in order
1331 to prevent re-written into SSA. */
1332 if (!lookup_attribute (ASAN_USE_AFTER_SCOPE_ATTRIBUTE,
1333 DECL_ATTRIBUTES (var)))
1334 DECL_ATTRIBUTES (var)
1335 = tree_cons (get_identifier (ASAN_USE_AFTER_SCOPE_ATTRIBUTE),
1336 integer_one_node,
1337 DECL_ATTRIBUTES (var));
1341 /* Gimplify a BIND_EXPR. Just voidify and recurse. */
1343 static enum gimplify_status
1344 gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p)
1346 tree bind_expr = *expr_p;
1347 bool old_keep_stack = gimplify_ctxp->keep_stack;
1348 bool old_save_stack = gimplify_ctxp->save_stack;
1349 tree t;
1350 gbind *bind_stmt;
1351 gimple_seq body, cleanup;
1352 gcall *stack_save;
1353 location_t start_locus = 0, end_locus = 0;
1354 tree ret_clauses = NULL;
1356 tree temp = voidify_wrapper_expr (bind_expr, NULL);
1358 /* Mark variables seen in this bind expr. */
1359 for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t))
1361 if (VAR_P (t))
1363 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
1365 /* Mark variable as local. */
1366 if (ctx && ctx->region_type != ORT_NONE && !DECL_EXTERNAL (t))
1368 if (! DECL_SEEN_IN_BIND_EXPR_P (t)
1369 || splay_tree_lookup (ctx->variables,
1370 (splay_tree_key) t) == NULL)
1372 int flag = GOVD_LOCAL;
1373 if (ctx->region_type == ORT_SIMD
1374 && TREE_ADDRESSABLE (t)
1375 && !TREE_STATIC (t))
1377 if (TREE_CODE (DECL_SIZE_UNIT (t)) != INTEGER_CST)
1378 ctx->add_safelen1 = true;
1379 else
1380 flag = GOVD_PRIVATE;
1382 omp_add_variable (ctx, t, flag | GOVD_SEEN);
1384 /* Static locals inside of target construct or offloaded
1385 routines need to be "omp declare target". */
1386 if (TREE_STATIC (t))
1387 for (; ctx; ctx = ctx->outer_context)
1388 if ((ctx->region_type & ORT_TARGET) != 0)
1390 if (!lookup_attribute ("omp declare target",
1391 DECL_ATTRIBUTES (t)))
1393 tree id = get_identifier ("omp declare target");
1394 DECL_ATTRIBUTES (t)
1395 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
1396 varpool_node *node = varpool_node::get (t);
1397 if (node)
1399 node->offloadable = 1;
1400 if (ENABLE_OFFLOADING && !DECL_EXTERNAL (t))
1402 g->have_offload = true;
1403 if (!in_lto_p)
1404 vec_safe_push (offload_vars, t);
1408 break;
1412 DECL_SEEN_IN_BIND_EXPR_P (t) = 1;
1414 if (DECL_HARD_REGISTER (t) && !is_global_var (t) && cfun)
1415 cfun->has_local_explicit_reg_vars = true;
1419 bind_stmt = gimple_build_bind (BIND_EXPR_VARS (bind_expr), NULL,
1420 BIND_EXPR_BLOCK (bind_expr));
1421 gimple_push_bind_expr (bind_stmt);
1423 gimplify_ctxp->keep_stack = false;
1424 gimplify_ctxp->save_stack = false;
1426 /* Gimplify the body into the GIMPLE_BIND tuple's body. */
1427 body = NULL;
1428 gimplify_stmt (&BIND_EXPR_BODY (bind_expr), &body);
1429 gimple_bind_set_body (bind_stmt, body);
1431 /* Source location wise, the cleanup code (stack_restore and clobbers)
1432 belongs to the end of the block, so propagate what we have. The
1433 stack_save operation belongs to the beginning of block, which we can
1434 infer from the bind_expr directly if the block has no explicit
1435 assignment. */
1436 if (BIND_EXPR_BLOCK (bind_expr))
1438 end_locus = BLOCK_SOURCE_END_LOCATION (BIND_EXPR_BLOCK (bind_expr));
1439 start_locus = BLOCK_SOURCE_LOCATION (BIND_EXPR_BLOCK (bind_expr));
1441 if (start_locus == 0)
1442 start_locus = EXPR_LOCATION (bind_expr);
1444 cleanup = NULL;
1445 stack_save = NULL;
1447 /* If the code both contains VLAs and calls alloca, then we cannot reclaim
1448 the stack space allocated to the VLAs. */
1449 if (gimplify_ctxp->save_stack && !gimplify_ctxp->keep_stack)
1451 gcall *stack_restore;
1453 /* Save stack on entry and restore it on exit. Add a try_finally
1454 block to achieve this. */
1455 build_stack_save_restore (&stack_save, &stack_restore);
1457 gimple_set_location (stack_save, start_locus);
1458 gimple_set_location (stack_restore, end_locus);
1460 gimplify_seq_add_stmt (&cleanup, stack_restore);
1463 /* Add clobbers for all variables that go out of scope. */
1464 for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t))
1466 if (VAR_P (t)
1467 && !is_global_var (t)
1468 && DECL_CONTEXT (t) == current_function_decl)
1470 if (!DECL_HARD_REGISTER (t)
1471 && !TREE_THIS_VOLATILE (t)
1472 && !DECL_HAS_VALUE_EXPR_P (t)
1473 /* Only care for variables that have to be in memory. Others
1474 will be rewritten into SSA names, hence moved to the
1475 top-level. */
1476 && !is_gimple_reg (t)
1477 && flag_stack_reuse != SR_NONE)
1479 tree clobber = build_clobber (TREE_TYPE (t), CLOBBER_EOL);
1480 gimple *clobber_stmt;
1481 clobber_stmt = gimple_build_assign (t, clobber);
1482 gimple_set_location (clobber_stmt, end_locus);
1483 gimplify_seq_add_stmt (&cleanup, clobber_stmt);
1486 if (flag_openacc && oacc_declare_returns != NULL)
1488 tree key = t;
1489 if (DECL_HAS_VALUE_EXPR_P (key))
1491 key = DECL_VALUE_EXPR (key);
1492 if (TREE_CODE (key) == INDIRECT_REF)
1493 key = TREE_OPERAND (key, 0);
1495 tree *c = oacc_declare_returns->get (key);
1496 if (c != NULL)
1498 if (ret_clauses)
1499 OMP_CLAUSE_CHAIN (*c) = ret_clauses;
1501 ret_clauses = unshare_expr (*c);
1503 oacc_declare_returns->remove (key);
1505 if (oacc_declare_returns->is_empty ())
1507 delete oacc_declare_returns;
1508 oacc_declare_returns = NULL;
1514 if (asan_poisoned_variables != NULL
1515 && asan_poisoned_variables->contains (t))
1517 asan_poisoned_variables->remove (t);
1518 asan_poison_variable (t, true, &cleanup);
1521 if (gimplify_ctxp->live_switch_vars != NULL
1522 && gimplify_ctxp->live_switch_vars->contains (t))
1523 gimplify_ctxp->live_switch_vars->remove (t);
1526 if (ret_clauses)
1528 gomp_target *stmt;
1529 gimple_stmt_iterator si = gsi_start (cleanup);
1531 stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
1532 ret_clauses);
1533 gsi_insert_seq_before_without_update (&si, stmt, GSI_NEW_STMT);
1536 if (cleanup)
1538 gtry *gs;
1539 gimple_seq new_body;
1541 new_body = NULL;
1542 gs = gimple_build_try (gimple_bind_body (bind_stmt), cleanup,
1543 GIMPLE_TRY_FINALLY);
1545 if (stack_save)
1546 gimplify_seq_add_stmt (&new_body, stack_save);
1547 gimplify_seq_add_stmt (&new_body, gs);
1548 gimple_bind_set_body (bind_stmt, new_body);
1551 /* keep_stack propagates all the way up to the outermost BIND_EXPR. */
1552 if (!gimplify_ctxp->keep_stack)
1553 gimplify_ctxp->keep_stack = old_keep_stack;
1554 gimplify_ctxp->save_stack = old_save_stack;
1556 gimple_pop_bind_expr ();
1558 gimplify_seq_add_stmt (pre_p, bind_stmt);
1560 if (temp)
1562 *expr_p = temp;
1563 return GS_OK;
1566 *expr_p = NULL_TREE;
1567 return GS_ALL_DONE;
1570 /* Maybe add early return predict statement to PRE_P sequence. */
1572 static void
1573 maybe_add_early_return_predict_stmt (gimple_seq *pre_p)
1575 /* If we are not in a conditional context, add PREDICT statement. */
1576 if (gimple_conditional_context ())
1578 gimple *predict = gimple_build_predict (PRED_TREE_EARLY_RETURN,
1579 NOT_TAKEN);
1580 gimplify_seq_add_stmt (pre_p, predict);
1584 /* Gimplify a RETURN_EXPR. If the expression to be returned is not a
1585 GIMPLE value, it is assigned to a new temporary and the statement is
1586 re-written to return the temporary.
1588 PRE_P points to the sequence where side effects that must happen before
1589 STMT should be stored. */
1591 static enum gimplify_status
1592 gimplify_return_expr (tree stmt, gimple_seq *pre_p)
1594 greturn *ret;
1595 tree ret_expr = TREE_OPERAND (stmt, 0);
1596 tree result_decl, result;
1598 if (ret_expr == error_mark_node)
1599 return GS_ERROR;
1601 if (!ret_expr
1602 || TREE_CODE (ret_expr) == RESULT_DECL)
1604 maybe_add_early_return_predict_stmt (pre_p);
1605 greturn *ret = gimple_build_return (ret_expr);
1606 copy_warning (ret, stmt);
1607 gimplify_seq_add_stmt (pre_p, ret);
1608 return GS_ALL_DONE;
1611 if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))))
1612 result_decl = NULL_TREE;
1613 else if (TREE_CODE (ret_expr) == COMPOUND_EXPR)
1615 /* Used in C++ for handling EH cleanup of the return value if a local
1616 cleanup throws. Assume the front-end knows what it's doing. */
1617 result_decl = DECL_RESULT (current_function_decl);
1618 /* But crash if we end up trying to modify ret_expr below. */
1619 ret_expr = NULL_TREE;
1621 else
1623 result_decl = TREE_OPERAND (ret_expr, 0);
1625 /* See through a return by reference. */
1626 if (TREE_CODE (result_decl) == INDIRECT_REF)
1627 result_decl = TREE_OPERAND (result_decl, 0);
1629 gcc_assert ((TREE_CODE (ret_expr) == MODIFY_EXPR
1630 || TREE_CODE (ret_expr) == INIT_EXPR)
1631 && TREE_CODE (result_decl) == RESULT_DECL);
1634 /* If aggregate_value_p is true, then we can return the bare RESULT_DECL.
1635 Recall that aggregate_value_p is FALSE for any aggregate type that is
1636 returned in registers. If we're returning values in registers, then
1637 we don't want to extend the lifetime of the RESULT_DECL, particularly
1638 across another call. In addition, for those aggregates for which
1639 hard_function_value generates a PARALLEL, we'll die during normal
1640 expansion of structure assignments; there's special code in expand_return
1641 to handle this case that does not exist in expand_expr. */
1642 if (!result_decl)
1643 result = NULL_TREE;
1644 else if (aggregate_value_p (result_decl, TREE_TYPE (current_function_decl)))
1646 if (!poly_int_tree_p (DECL_SIZE (result_decl)))
1648 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (result_decl)))
1649 gimplify_type_sizes (TREE_TYPE (result_decl), pre_p);
1650 /* Note that we don't use gimplify_vla_decl because the RESULT_DECL
1651 should be effectively allocated by the caller, i.e. all calls to
1652 this function must be subject to the Return Slot Optimization. */
1653 gimplify_one_sizepos (&DECL_SIZE (result_decl), pre_p);
1654 gimplify_one_sizepos (&DECL_SIZE_UNIT (result_decl), pre_p);
1656 result = result_decl;
1658 else if (gimplify_ctxp->return_temp)
1659 result = gimplify_ctxp->return_temp;
1660 else
1662 result = create_tmp_reg (TREE_TYPE (result_decl));
1664 /* ??? With complex control flow (usually involving abnormal edges),
1665 we can wind up warning about an uninitialized value for this. Due
1666 to how this variable is constructed and initialized, this is never
1667 true. Give up and never warn. */
1668 suppress_warning (result, OPT_Wuninitialized);
1670 gimplify_ctxp->return_temp = result;
1673 /* Smash the lhs of the MODIFY_EXPR to the temporary we plan to use.
1674 Then gimplify the whole thing. */
1675 if (result != result_decl)
1676 TREE_OPERAND (ret_expr, 0) = result;
1678 gimplify_and_add (TREE_OPERAND (stmt, 0), pre_p);
1680 maybe_add_early_return_predict_stmt (pre_p);
1681 ret = gimple_build_return (result);
1682 copy_warning (ret, stmt);
1683 gimplify_seq_add_stmt (pre_p, ret);
1685 return GS_ALL_DONE;
1688 /* Gimplify a variable-length array DECL. */
1690 static void
1691 gimplify_vla_decl (tree decl, gimple_seq *seq_p)
1693 /* This is a variable-sized decl. Simplify its size and mark it
1694 for deferred expansion. */
1695 tree t, addr, ptr_type;
1697 gimplify_one_sizepos (&DECL_SIZE (decl), seq_p);
1698 gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), seq_p);
1700 /* Don't mess with a DECL_VALUE_EXPR set by the front-end. */
1701 if (DECL_HAS_VALUE_EXPR_P (decl))
1702 return;
1704 /* All occurrences of this decl in final gimplified code will be
1705 replaced by indirection. Setting DECL_VALUE_EXPR does two
1706 things: First, it lets the rest of the gimplifier know what
1707 replacement to use. Second, it lets the debug info know
1708 where to find the value. */
1709 ptr_type = build_pointer_type (TREE_TYPE (decl));
1710 addr = create_tmp_var (ptr_type, get_name (decl));
1711 DECL_IGNORED_P (addr) = 0;
1712 t = build_fold_indirect_ref (addr);
1713 TREE_THIS_NOTRAP (t) = 1;
1714 SET_DECL_VALUE_EXPR (decl, t);
1715 DECL_HAS_VALUE_EXPR_P (decl) = 1;
1717 t = build_alloca_call_expr (DECL_SIZE_UNIT (decl), DECL_ALIGN (decl),
1718 max_int_size_in_bytes (TREE_TYPE (decl)));
1719 /* The call has been built for a variable-sized object. */
1720 CALL_ALLOCA_FOR_VAR_P (t) = 1;
1721 t = fold_convert (ptr_type, t);
1722 t = build2 (MODIFY_EXPR, TREE_TYPE (addr), addr, t);
1724 gimplify_and_add (t, seq_p);
1726 /* Record the dynamic allocation associated with DECL if requested. */
1727 if (flag_callgraph_info & CALLGRAPH_INFO_DYNAMIC_ALLOC)
1728 record_dynamic_alloc (decl);
1731 /* A helper function to be called via walk_tree. Mark all labels under *TP
1732 as being forced. To be called for DECL_INITIAL of static variables. */
1734 static tree
1735 force_labels_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
1737 if (TYPE_P (*tp))
1738 *walk_subtrees = 0;
1739 if (TREE_CODE (*tp) == LABEL_DECL)
1741 FORCED_LABEL (*tp) = 1;
1742 cfun->has_forced_label_in_static = 1;
1745 return NULL_TREE;
1748 /* Generate an initialization to automatic variable DECL based on INIT_TYPE.
1749 Build a call to internal const function DEFERRED_INIT:
1750 1st argument: SIZE of the DECL;
1751 2nd argument: INIT_TYPE;
1752 3rd argument: NAME of the DECL;
1754 as LHS = DEFERRED_INIT (SIZE of the DECL, INIT_TYPE, NAME of the DECL). */
1756 static void
1757 gimple_add_init_for_auto_var (tree decl,
1758 enum auto_init_type init_type,
1759 gimple_seq *seq_p)
1761 gcc_assert (auto_var_p (decl));
1762 gcc_assert (init_type > AUTO_INIT_UNINITIALIZED);
1763 location_t loc = EXPR_LOCATION (decl);
1764 tree decl_size = TYPE_SIZE_UNIT (TREE_TYPE (decl));
1766 tree init_type_node
1767 = build_int_cst (integer_type_node, (int) init_type);
1769 tree decl_name = NULL_TREE;
1770 if (DECL_NAME (decl))
1772 decl_name = build_string_literal (IDENTIFIER_LENGTH (DECL_NAME (decl)) + 1,
1773 IDENTIFIER_POINTER (DECL_NAME (decl)));
1775 else
1777 char *decl_name_anonymous = xasprintf ("D.%u", DECL_UID (decl));
1778 decl_name = build_string_literal (strlen (decl_name_anonymous) + 1,
1779 decl_name_anonymous);
1780 free (decl_name_anonymous);
1783 tree call = build_call_expr_internal_loc (loc, IFN_DEFERRED_INIT,
1784 TREE_TYPE (decl), 3,
1785 decl_size, init_type_node,
1786 decl_name);
1788 gimplify_assign (decl, call, seq_p);
1791 /* Generate padding initialization for automatic vairable DECL.
1792 C guarantees that brace-init with fewer initializers than members
1793 aggregate will initialize the rest of the aggregate as-if it were
1794 static initialization. In turn static initialization guarantees
1795 that padding is initialized to zero. So, we always initialize paddings
1796 to zeroes regardless INIT_TYPE.
1797 To do the padding initialization, we insert a call to
1798 __builtin_clear_padding (&decl, 0, for_auto_init = true).
1799 Note, we add an additional dummy argument for __builtin_clear_padding,
1800 'for_auto_init' to distinguish whether this call is for automatic
1801 variable initialization or not.
1803 static void
1804 gimple_add_padding_init_for_auto_var (tree decl, bool is_vla,
1805 gimple_seq *seq_p)
1807 tree addr_of_decl = NULL_TREE;
1808 tree fn = builtin_decl_explicit (BUILT_IN_CLEAR_PADDING);
1810 if (is_vla)
1812 /* The temporary address variable for this vla should be
1813 created in gimplify_vla_decl. */
1814 gcc_assert (DECL_HAS_VALUE_EXPR_P (decl));
1815 gcc_assert (TREE_CODE (DECL_VALUE_EXPR (decl)) == INDIRECT_REF);
1816 addr_of_decl = TREE_OPERAND (DECL_VALUE_EXPR (decl), 0);
1818 else
1820 mark_addressable (decl);
1821 addr_of_decl = build_fold_addr_expr (decl);
1824 gimple *call = gimple_build_call (fn, 2, addr_of_decl,
1825 build_one_cst (TREE_TYPE (addr_of_decl)));
1826 gimplify_seq_add_stmt (seq_p, call);
1829 /* Return true if the DECL need to be automaticly initialized by the
1830 compiler. */
1831 static bool
1832 is_var_need_auto_init (tree decl)
1834 if (auto_var_p (decl)
1835 && (TREE_CODE (decl) != VAR_DECL
1836 || !DECL_HARD_REGISTER (decl))
1837 && (flag_auto_var_init > AUTO_INIT_UNINITIALIZED)
1838 && (!lookup_attribute ("uninitialized", DECL_ATTRIBUTES (decl)))
1839 && !OPAQUE_TYPE_P (TREE_TYPE (decl))
1840 && !is_empty_type (TREE_TYPE (decl)))
1841 return true;
1842 return false;
1845 /* Gimplify a DECL_EXPR node *STMT_P by making any necessary allocation
1846 and initialization explicit. */
1848 static enum gimplify_status
1849 gimplify_decl_expr (tree *stmt_p, gimple_seq *seq_p)
1851 tree stmt = *stmt_p;
1852 tree decl = DECL_EXPR_DECL (stmt);
1854 *stmt_p = NULL_TREE;
1856 if (TREE_TYPE (decl) == error_mark_node)
1857 return GS_ERROR;
1859 if ((TREE_CODE (decl) == TYPE_DECL
1860 || VAR_P (decl))
1861 && !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl)))
1863 gimplify_type_sizes (TREE_TYPE (decl), seq_p);
1864 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
1865 gimplify_type_sizes (TREE_TYPE (TREE_TYPE (decl)), seq_p);
1868 /* ??? DECL_ORIGINAL_TYPE is streamed for LTO so it needs to be gimplified
1869 in case its size expressions contain problematic nodes like CALL_EXPR. */
1870 if (TREE_CODE (decl) == TYPE_DECL
1871 && DECL_ORIGINAL_TYPE (decl)
1872 && !TYPE_SIZES_GIMPLIFIED (DECL_ORIGINAL_TYPE (decl)))
1874 gimplify_type_sizes (DECL_ORIGINAL_TYPE (decl), seq_p);
1875 if (TREE_CODE (DECL_ORIGINAL_TYPE (decl)) == REFERENCE_TYPE)
1876 gimplify_type_sizes (TREE_TYPE (DECL_ORIGINAL_TYPE (decl)), seq_p);
1879 if (VAR_P (decl) && !DECL_EXTERNAL (decl))
1881 tree init = DECL_INITIAL (decl);
1882 bool is_vla = false;
1883 /* Check whether a decl has FE created VALUE_EXPR here BEFORE
1884 gimplify_vla_decl creates VALUE_EXPR for a vla decl.
1885 If the decl has VALUE_EXPR that was created by FE (usually
1886 C++FE), it's a proxy varaible, and FE already initialized
1887 the VALUE_EXPR of it, we should not initialize it anymore. */
1888 bool decl_had_value_expr_p = DECL_HAS_VALUE_EXPR_P (decl);
1890 poly_uint64 size;
1891 if (!poly_int_tree_p (DECL_SIZE_UNIT (decl), &size)
1892 || (!TREE_STATIC (decl)
1893 && flag_stack_check == GENERIC_STACK_CHECK
1894 && maybe_gt (size,
1895 (unsigned HOST_WIDE_INT) STACK_CHECK_MAX_VAR_SIZE)))
1897 gimplify_vla_decl (decl, seq_p);
1898 is_vla = true;
1901 if (asan_poisoned_variables
1902 && !is_vla
1903 && TREE_ADDRESSABLE (decl)
1904 && !TREE_STATIC (decl)
1905 && !DECL_HAS_VALUE_EXPR_P (decl)
1906 && DECL_ALIGN (decl) <= MAX_SUPPORTED_STACK_ALIGNMENT
1907 && dbg_cnt (asan_use_after_scope)
1908 && !gimplify_omp_ctxp
1909 /* GNAT introduces temporaries to hold return values of calls in
1910 initializers of variables defined in other units, so the
1911 declaration of the variable is discarded completely. We do not
1912 want to issue poison calls for such dropped variables. */
1913 && (DECL_SEEN_IN_BIND_EXPR_P (decl)
1914 || (DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)))
1916 asan_poisoned_variables->add (decl);
1917 asan_poison_variable (decl, false, seq_p);
1918 if (!DECL_ARTIFICIAL (decl) && gimplify_ctxp->live_switch_vars)
1919 gimplify_ctxp->live_switch_vars->add (decl);
1922 /* Some front ends do not explicitly declare all anonymous
1923 artificial variables. We compensate here by declaring the
1924 variables, though it would be better if the front ends would
1925 explicitly declare them. */
1926 if (!DECL_SEEN_IN_BIND_EXPR_P (decl)
1927 && DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
1928 gimple_add_tmp_var (decl);
1930 if (init && init != error_mark_node)
1932 if (!TREE_STATIC (decl))
1934 DECL_INITIAL (decl) = NULL_TREE;
1935 init = build2 (INIT_EXPR, void_type_node, decl, init);
1936 gimplify_and_add (init, seq_p);
1937 ggc_free (init);
1938 /* Clear TREE_READONLY if we really have an initialization. */
1939 if (!DECL_INITIAL (decl)
1940 && !omp_privatize_by_reference (decl))
1941 TREE_READONLY (decl) = 0;
1943 else
1944 /* We must still examine initializers for static variables
1945 as they may contain a label address. */
1946 walk_tree (&init, force_labels_r, NULL, NULL);
1948 /* When there is no explicit initializer, if the user requested,
1949 We should insert an artifical initializer for this automatic
1950 variable. */
1951 else if (is_var_need_auto_init (decl)
1952 && !decl_had_value_expr_p)
1954 gimple_add_init_for_auto_var (decl,
1955 flag_auto_var_init,
1956 seq_p);
1957 /* The expanding of a call to the above .DEFERRED_INIT will apply
1958 block initialization to the whole space covered by this variable.
1959 As a result, all the paddings will be initialized to zeroes
1960 for zero initialization and 0xFE byte-repeatable patterns for
1961 pattern initialization.
1962 In order to make the paddings as zeroes for pattern init, We
1963 should add a call to __builtin_clear_padding to clear the
1964 paddings to zero in compatiple with CLANG.
1965 We cannot insert this call if the variable is a gimple register
1966 since __builtin_clear_padding will take the address of the
1967 variable. As a result, if a long double/_Complex long double
1968 variable will spilled into stack later, its padding is 0XFE. */
1969 if (flag_auto_var_init == AUTO_INIT_PATTERN
1970 && !is_gimple_reg (decl)
1971 && clear_padding_type_may_have_padding_p (TREE_TYPE (decl)))
1972 gimple_add_padding_init_for_auto_var (decl, is_vla, seq_p);
1976 return GS_ALL_DONE;
1979 /* Gimplify a LOOP_EXPR. Normally this just involves gimplifying the body
1980 and replacing the LOOP_EXPR with goto, but if the loop contains an
1981 EXIT_EXPR, we need to append a label for it to jump to. */
1983 static enum gimplify_status
1984 gimplify_loop_expr (tree *expr_p, gimple_seq *pre_p)
1986 tree saved_label = gimplify_ctxp->exit_label;
1987 tree start_label = create_artificial_label (UNKNOWN_LOCATION);
1989 gimplify_seq_add_stmt (pre_p, gimple_build_label (start_label));
1991 gimplify_ctxp->exit_label = NULL_TREE;
1993 gimplify_and_add (LOOP_EXPR_BODY (*expr_p), pre_p);
1995 gimplify_seq_add_stmt (pre_p, gimple_build_goto (start_label));
1997 if (gimplify_ctxp->exit_label)
1998 gimplify_seq_add_stmt (pre_p,
1999 gimple_build_label (gimplify_ctxp->exit_label));
2001 gimplify_ctxp->exit_label = saved_label;
2003 *expr_p = NULL;
2004 return GS_ALL_DONE;
2007 /* Gimplify a statement list onto a sequence. These may be created either
2008 by an enlightened front-end, or by shortcut_cond_expr. */
2010 static enum gimplify_status
2011 gimplify_statement_list (tree *expr_p, gimple_seq *pre_p)
2013 tree temp = voidify_wrapper_expr (*expr_p, NULL);
2015 tree_stmt_iterator i = tsi_start (*expr_p);
2017 while (!tsi_end_p (i))
2019 gimplify_stmt (tsi_stmt_ptr (i), pre_p);
2020 tsi_delink (&i);
2023 if (temp)
2025 *expr_p = temp;
2026 return GS_OK;
2029 return GS_ALL_DONE;
2033 /* Emit warning for the unreachable statment STMT if needed.
2034 Return the gimple itself when the warning is emitted, otherwise
2035 return NULL. */
2036 static gimple *
2037 emit_warn_switch_unreachable (gimple *stmt)
2039 if (gimple_code (stmt) == GIMPLE_GOTO
2040 && TREE_CODE (gimple_goto_dest (stmt)) == LABEL_DECL
2041 && DECL_ARTIFICIAL (gimple_goto_dest (stmt)))
2042 /* Don't warn for compiler-generated gotos. These occur
2043 in Duff's devices, for example. */
2044 return NULL;
2045 else if ((flag_auto_var_init > AUTO_INIT_UNINITIALIZED)
2046 && ((gimple_call_internal_p (stmt, IFN_DEFERRED_INIT))
2047 || (gimple_call_builtin_p (stmt, BUILT_IN_CLEAR_PADDING)
2048 && (bool) TREE_INT_CST_LOW (gimple_call_arg (stmt, 1)))
2049 || (is_gimple_assign (stmt)
2050 && gimple_assign_single_p (stmt)
2051 && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
2052 && gimple_call_internal_p (
2053 SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt)),
2054 IFN_DEFERRED_INIT))))
2055 /* Don't warn for compiler-generated initializations for
2056 -ftrivial-auto-var-init.
2057 There are 3 cases:
2058 case 1: a call to .DEFERRED_INIT;
2059 case 2: a call to __builtin_clear_padding with the 2nd argument is
2060 present and non-zero;
2061 case 3: a gimple assign store right after the call to .DEFERRED_INIT
2062 that has the LHS of .DEFERRED_INIT as the RHS as following:
2063 _1 = .DEFERRED_INIT (4, 2, &"i1"[0]);
2064 i1 = _1. */
2065 return NULL;
2066 else
2067 warning_at (gimple_location (stmt), OPT_Wswitch_unreachable,
2068 "statement will never be executed");
2069 return stmt;
2072 /* Callback for walk_gimple_seq. */
2074 static tree
2075 warn_switch_unreachable_and_auto_init_r (gimple_stmt_iterator *gsi_p,
2076 bool *handled_ops_p,
2077 struct walk_stmt_info *wi)
2079 gimple *stmt = gsi_stmt (*gsi_p);
2080 bool unreachable_issued = wi->info != NULL;
2082 *handled_ops_p = true;
2083 switch (gimple_code (stmt))
2085 case GIMPLE_TRY:
2086 /* A compiler-generated cleanup or a user-written try block.
2087 If it's empty, don't dive into it--that would result in
2088 worse location info. */
2089 if (gimple_try_eval (stmt) == NULL)
2091 if (warn_switch_unreachable && !unreachable_issued)
2092 wi->info = emit_warn_switch_unreachable (stmt);
2094 /* Stop when auto var init warning is not on. */
2095 if (!warn_trivial_auto_var_init)
2096 return integer_zero_node;
2098 /* Fall through. */
2099 case GIMPLE_BIND:
2100 case GIMPLE_CATCH:
2101 case GIMPLE_EH_FILTER:
2102 case GIMPLE_TRANSACTION:
2103 /* Walk the sub-statements. */
2104 *handled_ops_p = false;
2105 break;
2107 case GIMPLE_DEBUG:
2108 /* Ignore these. We may generate them before declarations that
2109 are never executed. If there's something to warn about,
2110 there will be non-debug stmts too, and we'll catch those. */
2111 break;
2113 case GIMPLE_LABEL:
2114 /* Stop till the first Label. */
2115 return integer_zero_node;
2116 case GIMPLE_CALL:
2117 if (gimple_call_internal_p (stmt, IFN_ASAN_MARK))
2119 *handled_ops_p = false;
2120 break;
2122 if (warn_trivial_auto_var_init
2123 && flag_auto_var_init > AUTO_INIT_UNINITIALIZED
2124 && gimple_call_internal_p (stmt, IFN_DEFERRED_INIT))
2126 /* Get the variable name from the 3rd argument of call. */
2127 tree var_name = gimple_call_arg (stmt, 2);
2128 var_name = TREE_OPERAND (TREE_OPERAND (var_name, 0), 0);
2129 const char *var_name_str = TREE_STRING_POINTER (var_name);
2131 warning_at (gimple_location (stmt), OPT_Wtrivial_auto_var_init,
2132 "%qs cannot be initialized with"
2133 "%<-ftrivial-auto-var_init%>",
2134 var_name_str);
2135 break;
2138 /* Fall through. */
2139 default:
2140 /* check the first "real" statement (not a decl/lexical scope/...), issue
2141 warning if needed. */
2142 if (warn_switch_unreachable && !unreachable_issued)
2143 wi->info = emit_warn_switch_unreachable (stmt);
2144 /* Stop when auto var init warning is not on. */
2145 if (!warn_trivial_auto_var_init)
2146 return integer_zero_node;
2147 break;
2149 return NULL_TREE;
2153 /* Possibly warn about unreachable statements between switch's controlling
2154 expression and the first case. Also warn about -ftrivial-auto-var-init
2155 cannot initialize the auto variable under such situation.
2156 SEQ is the body of a switch expression. */
2158 static void
2159 maybe_warn_switch_unreachable_and_auto_init (gimple_seq seq)
2161 if ((!warn_switch_unreachable && !warn_trivial_auto_var_init)
2162 /* This warning doesn't play well with Fortran when optimizations
2163 are on. */
2164 || lang_GNU_Fortran ()
2165 || seq == NULL)
2166 return;
2168 struct walk_stmt_info wi;
2170 memset (&wi, 0, sizeof (wi));
2171 walk_gimple_seq (seq, warn_switch_unreachable_and_auto_init_r, NULL, &wi);
2175 /* A label entry that pairs label and a location. */
2176 struct label_entry
2178 tree label;
2179 location_t loc;
2182 /* Find LABEL in vector of label entries VEC. */
2184 static struct label_entry *
2185 find_label_entry (const auto_vec<struct label_entry> *vec, tree label)
2187 unsigned int i;
2188 struct label_entry *l;
2190 FOR_EACH_VEC_ELT (*vec, i, l)
2191 if (l->label == label)
2192 return l;
2193 return NULL;
2196 /* Return true if LABEL, a LABEL_DECL, represents a case label
2197 in a vector of labels CASES. */
2199 static bool
2200 case_label_p (const vec<tree> *cases, tree label)
2202 unsigned int i;
2203 tree l;
2205 FOR_EACH_VEC_ELT (*cases, i, l)
2206 if (CASE_LABEL (l) == label)
2207 return true;
2208 return false;
2211 /* Find the last nondebug statement in a scope STMT. */
2213 static gimple *
2214 last_stmt_in_scope (gimple *stmt)
2216 if (!stmt)
2217 return NULL;
2219 switch (gimple_code (stmt))
2221 case GIMPLE_BIND:
2223 gbind *bind = as_a <gbind *> (stmt);
2224 stmt = gimple_seq_last_nondebug_stmt (gimple_bind_body (bind));
2225 return last_stmt_in_scope (stmt);
2228 case GIMPLE_TRY:
2230 gtry *try_stmt = as_a <gtry *> (stmt);
2231 stmt = gimple_seq_last_nondebug_stmt (gimple_try_eval (try_stmt));
2232 gimple *last_eval = last_stmt_in_scope (stmt);
2233 if (gimple_stmt_may_fallthru (last_eval)
2234 && (last_eval == NULL
2235 || !gimple_call_internal_p (last_eval, IFN_FALLTHROUGH))
2236 && gimple_try_kind (try_stmt) == GIMPLE_TRY_FINALLY)
2238 stmt = gimple_seq_last_nondebug_stmt (gimple_try_cleanup (try_stmt));
2239 return last_stmt_in_scope (stmt);
2241 else
2242 return last_eval;
2245 case GIMPLE_DEBUG:
2246 gcc_unreachable ();
2248 default:
2249 return stmt;
2253 /* Collect interesting labels in LABELS and return the statement preceding
2254 another case label, or a user-defined label. Store a location useful
2255 to give warnings at *PREVLOC (usually the location of the returned
2256 statement or of its surrounding scope). */
2258 static gimple *
2259 collect_fallthrough_labels (gimple_stmt_iterator *gsi_p,
2260 auto_vec <struct label_entry> *labels,
2261 location_t *prevloc)
2263 gimple *prev = NULL;
2265 *prevloc = UNKNOWN_LOCATION;
2268 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND)
2270 /* Recognize the special GIMPLE_BIND added by gimplify_switch_expr,
2271 which starts on a GIMPLE_SWITCH and ends with a break label.
2272 Handle that as a single statement that can fall through. */
2273 gbind *bind = as_a <gbind *> (gsi_stmt (*gsi_p));
2274 gimple *first = gimple_seq_first_stmt (gimple_bind_body (bind));
2275 gimple *last = gimple_seq_last_stmt (gimple_bind_body (bind));
2276 if (last
2277 && gimple_code (first) == GIMPLE_SWITCH
2278 && gimple_code (last) == GIMPLE_LABEL)
2280 tree label = gimple_label_label (as_a <glabel *> (last));
2281 if (SWITCH_BREAK_LABEL_P (label))
2283 prev = bind;
2284 gsi_next (gsi_p);
2285 continue;
2289 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND
2290 || gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_TRY)
2292 /* Nested scope. Only look at the last statement of
2293 the innermost scope. */
2294 location_t bind_loc = gimple_location (gsi_stmt (*gsi_p));
2295 gimple *last = last_stmt_in_scope (gsi_stmt (*gsi_p));
2296 if (last)
2298 prev = last;
2299 /* It might be a label without a location. Use the
2300 location of the scope then. */
2301 if (!gimple_has_location (prev))
2302 *prevloc = bind_loc;
2304 gsi_next (gsi_p);
2305 continue;
2308 /* Ifs are tricky. */
2309 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_COND)
2311 gcond *cond_stmt = as_a <gcond *> (gsi_stmt (*gsi_p));
2312 tree false_lab = gimple_cond_false_label (cond_stmt);
2313 location_t if_loc = gimple_location (cond_stmt);
2315 /* If we have e.g.
2316 if (i > 1) goto <D.2259>; else goto D;
2317 we can't do much with the else-branch. */
2318 if (!DECL_ARTIFICIAL (false_lab))
2319 break;
2321 /* Go on until the false label, then one step back. */
2322 for (; !gsi_end_p (*gsi_p); gsi_next (gsi_p))
2324 gimple *stmt = gsi_stmt (*gsi_p);
2325 if (gimple_code (stmt) == GIMPLE_LABEL
2326 && gimple_label_label (as_a <glabel *> (stmt)) == false_lab)
2327 break;
2330 /* Not found? Oops. */
2331 if (gsi_end_p (*gsi_p))
2332 break;
2334 struct label_entry l = { false_lab, if_loc };
2335 labels->safe_push (l);
2337 /* Go to the last statement of the then branch. */
2338 gsi_prev (gsi_p);
2340 /* if (i != 0) goto <D.1759>; else goto <D.1760>;
2341 <D.1759>:
2342 <stmt>;
2343 goto <D.1761>;
2344 <D.1760>:
2346 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_GOTO
2347 && !gimple_has_location (gsi_stmt (*gsi_p)))
2349 /* Look at the statement before, it might be
2350 attribute fallthrough, in which case don't warn. */
2351 gsi_prev (gsi_p);
2352 bool fallthru_before_dest
2353 = gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_FALLTHROUGH);
2354 gsi_next (gsi_p);
2355 tree goto_dest = gimple_goto_dest (gsi_stmt (*gsi_p));
2356 if (!fallthru_before_dest)
2358 struct label_entry l = { goto_dest, if_loc };
2359 labels->safe_push (l);
2362 /* And move back. */
2363 gsi_next (gsi_p);
2366 /* Remember the last statement. Skip labels that are of no interest
2367 to us. */
2368 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
2370 tree label = gimple_label_label (as_a <glabel *> (gsi_stmt (*gsi_p)));
2371 if (find_label_entry (labels, label))
2372 prev = gsi_stmt (*gsi_p);
2374 else if (gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_ASAN_MARK))
2376 else if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_PREDICT)
2378 else if (!is_gimple_debug (gsi_stmt (*gsi_p)))
2379 prev = gsi_stmt (*gsi_p);
2380 gsi_next (gsi_p);
2382 while (!gsi_end_p (*gsi_p)
2383 /* Stop if we find a case or a user-defined label. */
2384 && (gimple_code (gsi_stmt (*gsi_p)) != GIMPLE_LABEL
2385 || !gimple_has_location (gsi_stmt (*gsi_p))));
2387 if (prev && gimple_has_location (prev))
2388 *prevloc = gimple_location (prev);
2389 return prev;
2392 /* Return true if the switch fallthough warning should occur. LABEL is
2393 the label statement that we're falling through to. */
2395 static bool
2396 should_warn_for_implicit_fallthrough (gimple_stmt_iterator *gsi_p, tree label)
2398 gimple_stmt_iterator gsi = *gsi_p;
2400 /* Don't warn if the label is marked with a "falls through" comment. */
2401 if (FALLTHROUGH_LABEL_P (label))
2402 return false;
2404 /* Don't warn for non-case labels followed by a statement:
2405 case 0:
2406 foo ();
2407 label:
2408 bar ();
2409 as these are likely intentional. */
2410 if (!case_label_p (&gimplify_ctxp->case_labels, label))
2412 tree l;
2413 while (!gsi_end_p (gsi)
2414 && gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
2415 && (l = gimple_label_label (as_a <glabel *> (gsi_stmt (gsi))))
2416 && !case_label_p (&gimplify_ctxp->case_labels, l))
2417 gsi_next_nondebug (&gsi);
2418 if (gsi_end_p (gsi) || gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL)
2419 return false;
2422 /* Don't warn for terminated branches, i.e. when the subsequent case labels
2423 immediately breaks. */
2424 gsi = *gsi_p;
2426 /* Skip all immediately following labels. */
2427 while (!gsi_end_p (gsi)
2428 && (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
2429 || gimple_code (gsi_stmt (gsi)) == GIMPLE_PREDICT))
2430 gsi_next_nondebug (&gsi);
2432 /* { ... something; default:; } */
2433 if (gsi_end_p (gsi)
2434 /* { ... something; default: break; } or
2435 { ... something; default: goto L; } */
2436 || gimple_code (gsi_stmt (gsi)) == GIMPLE_GOTO
2437 /* { ... something; default: return; } */
2438 || gimple_code (gsi_stmt (gsi)) == GIMPLE_RETURN)
2439 return false;
2441 return true;
2444 /* Callback for walk_gimple_seq. */
2446 static tree
2447 warn_implicit_fallthrough_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
2448 struct walk_stmt_info *)
2450 gimple *stmt = gsi_stmt (*gsi_p);
2452 *handled_ops_p = true;
2453 switch (gimple_code (stmt))
2455 case GIMPLE_TRY:
2456 case GIMPLE_BIND:
2457 case GIMPLE_CATCH:
2458 case GIMPLE_EH_FILTER:
2459 case GIMPLE_TRANSACTION:
2460 /* Walk the sub-statements. */
2461 *handled_ops_p = false;
2462 break;
2464 /* Find a sequence of form:
2466 GIMPLE_LABEL
2467 [...]
2468 <may fallthru stmt>
2469 GIMPLE_LABEL
2471 and possibly warn. */
2472 case GIMPLE_LABEL:
2474 /* Found a label. Skip all immediately following labels. */
2475 while (!gsi_end_p (*gsi_p)
2476 && gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
2477 gsi_next_nondebug (gsi_p);
2479 /* There might be no more statements. */
2480 if (gsi_end_p (*gsi_p))
2481 return integer_zero_node;
2483 /* Vector of labels that fall through. */
2484 auto_vec <struct label_entry> labels;
2485 location_t prevloc;
2486 gimple *prev = collect_fallthrough_labels (gsi_p, &labels, &prevloc);
2488 /* There might be no more statements. */
2489 if (gsi_end_p (*gsi_p))
2490 return integer_zero_node;
2492 gimple *next = gsi_stmt (*gsi_p);
2493 tree label;
2494 /* If what follows is a label, then we may have a fallthrough. */
2495 if (gimple_code (next) == GIMPLE_LABEL
2496 && gimple_has_location (next)
2497 && (label = gimple_label_label (as_a <glabel *> (next)))
2498 && prev != NULL)
2500 struct label_entry *l;
2501 bool warned_p = false;
2502 auto_diagnostic_group d;
2503 if (!should_warn_for_implicit_fallthrough (gsi_p, label))
2504 /* Quiet. */;
2505 else if (gimple_code (prev) == GIMPLE_LABEL
2506 && (label = gimple_label_label (as_a <glabel *> (prev)))
2507 && (l = find_label_entry (&labels, label)))
2508 warned_p = warning_at (l->loc, OPT_Wimplicit_fallthrough_,
2509 "this statement may fall through");
2510 else if (!gimple_call_internal_p (prev, IFN_FALLTHROUGH)
2511 /* Try to be clever and don't warn when the statement
2512 can't actually fall through. */
2513 && gimple_stmt_may_fallthru (prev)
2514 && prevloc != UNKNOWN_LOCATION)
2515 warned_p = warning_at (prevloc,
2516 OPT_Wimplicit_fallthrough_,
2517 "this statement may fall through");
2518 if (warned_p)
2519 inform (gimple_location (next), "here");
2521 /* Mark this label as processed so as to prevent multiple
2522 warnings in nested switches. */
2523 FALLTHROUGH_LABEL_P (label) = true;
2525 /* So that next warn_implicit_fallthrough_r will start looking for
2526 a new sequence starting with this label. */
2527 gsi_prev (gsi_p);
2530 break;
2531 default:
2532 break;
2534 return NULL_TREE;
2537 /* Warn when a switch case falls through. */
2539 static void
2540 maybe_warn_implicit_fallthrough (gimple_seq seq)
2542 if (!warn_implicit_fallthrough)
2543 return;
2545 /* This warning is meant for C/C++/ObjC/ObjC++ only. */
2546 if (!(lang_GNU_C ()
2547 || lang_GNU_CXX ()
2548 || lang_GNU_OBJC ()))
2549 return;
2551 struct walk_stmt_info wi;
2552 memset (&wi, 0, sizeof (wi));
2553 walk_gimple_seq (seq, warn_implicit_fallthrough_r, NULL, &wi);
2556 /* Callback for walk_gimple_seq. */
2558 static tree
2559 expand_FALLTHROUGH_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
2560 struct walk_stmt_info *wi)
2562 gimple *stmt = gsi_stmt (*gsi_p);
2564 *handled_ops_p = true;
2565 switch (gimple_code (stmt))
2567 case GIMPLE_TRY:
2568 case GIMPLE_BIND:
2569 case GIMPLE_CATCH:
2570 case GIMPLE_EH_FILTER:
2571 case GIMPLE_TRANSACTION:
2572 /* Walk the sub-statements. */
2573 *handled_ops_p = false;
2574 break;
2575 case GIMPLE_CALL:
2576 if (gimple_call_internal_p (stmt, IFN_FALLTHROUGH))
2578 gsi_remove (gsi_p, true);
2579 if (gsi_end_p (*gsi_p))
2581 *static_cast<location_t *>(wi->info) = gimple_location (stmt);
2582 return integer_zero_node;
2585 bool found = false;
2586 location_t loc = gimple_location (stmt);
2588 gimple_stmt_iterator gsi2 = *gsi_p;
2589 stmt = gsi_stmt (gsi2);
2590 if (gimple_code (stmt) == GIMPLE_GOTO && !gimple_has_location (stmt))
2592 /* Go on until the artificial label. */
2593 tree goto_dest = gimple_goto_dest (stmt);
2594 for (; !gsi_end_p (gsi2); gsi_next (&gsi2))
2596 if (gimple_code (gsi_stmt (gsi2)) == GIMPLE_LABEL
2597 && gimple_label_label (as_a <glabel *> (gsi_stmt (gsi2)))
2598 == goto_dest)
2599 break;
2602 /* Not found? Stop. */
2603 if (gsi_end_p (gsi2))
2604 break;
2606 /* Look one past it. */
2607 gsi_next (&gsi2);
2610 /* We're looking for a case label or default label here. */
2611 while (!gsi_end_p (gsi2))
2613 stmt = gsi_stmt (gsi2);
2614 if (gimple_code (stmt) == GIMPLE_LABEL)
2616 tree label = gimple_label_label (as_a <glabel *> (stmt));
2617 if (gimple_has_location (stmt) && DECL_ARTIFICIAL (label))
2619 found = true;
2620 break;
2623 else if (gimple_call_internal_p (stmt, IFN_ASAN_MARK))
2625 else if (!is_gimple_debug (stmt))
2626 /* Anything else is not expected. */
2627 break;
2628 gsi_next (&gsi2);
2630 if (!found)
2631 pedwarn (loc, 0, "attribute %<fallthrough%> not preceding "
2632 "a case label or default label");
2634 break;
2635 default:
2636 break;
2638 return NULL_TREE;
2641 /* Expand all FALLTHROUGH () calls in SEQ. */
2643 static void
2644 expand_FALLTHROUGH (gimple_seq *seq_p)
2646 struct walk_stmt_info wi;
2647 location_t loc;
2648 memset (&wi, 0, sizeof (wi));
2649 wi.info = (void *) &loc;
2650 walk_gimple_seq_mod (seq_p, expand_FALLTHROUGH_r, NULL, &wi);
2651 if (wi.callback_result == integer_zero_node)
2652 /* We've found [[fallthrough]]; at the end of a switch, which the C++
2653 standard says is ill-formed; see [dcl.attr.fallthrough]. */
2654 pedwarn (loc, 0, "attribute %<fallthrough%> not preceding "
2655 "a case label or default label");
2659 /* Gimplify a SWITCH_EXPR, and collect the vector of labels it can
2660 branch to. */
2662 static enum gimplify_status
2663 gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p)
2665 tree switch_expr = *expr_p;
2666 gimple_seq switch_body_seq = NULL;
2667 enum gimplify_status ret;
2668 tree index_type = TREE_TYPE (switch_expr);
2669 if (index_type == NULL_TREE)
2670 index_type = TREE_TYPE (SWITCH_COND (switch_expr));
2672 ret = gimplify_expr (&SWITCH_COND (switch_expr), pre_p, NULL, is_gimple_val,
2673 fb_rvalue);
2674 if (ret == GS_ERROR || ret == GS_UNHANDLED)
2675 return ret;
2677 if (SWITCH_BODY (switch_expr))
2679 vec<tree> labels;
2680 vec<tree> saved_labels;
2681 hash_set<tree> *saved_live_switch_vars = NULL;
2682 tree default_case = NULL_TREE;
2683 gswitch *switch_stmt;
2685 /* Save old labels, get new ones from body, then restore the old
2686 labels. Save all the things from the switch body to append after. */
2687 saved_labels = gimplify_ctxp->case_labels;
2688 gimplify_ctxp->case_labels.create (8);
2690 /* Do not create live_switch_vars if SWITCH_BODY is not a BIND_EXPR. */
2691 saved_live_switch_vars = gimplify_ctxp->live_switch_vars;
2692 tree_code body_type = TREE_CODE (SWITCH_BODY (switch_expr));
2693 if (body_type == BIND_EXPR || body_type == STATEMENT_LIST)
2694 gimplify_ctxp->live_switch_vars = new hash_set<tree> (4);
2695 else
2696 gimplify_ctxp->live_switch_vars = NULL;
2698 bool old_in_switch_expr = gimplify_ctxp->in_switch_expr;
2699 gimplify_ctxp->in_switch_expr = true;
2701 gimplify_stmt (&SWITCH_BODY (switch_expr), &switch_body_seq);
2703 gimplify_ctxp->in_switch_expr = old_in_switch_expr;
2704 maybe_warn_switch_unreachable_and_auto_init (switch_body_seq);
2705 maybe_warn_implicit_fallthrough (switch_body_seq);
2706 /* Only do this for the outermost GIMPLE_SWITCH. */
2707 if (!gimplify_ctxp->in_switch_expr)
2708 expand_FALLTHROUGH (&switch_body_seq);
2710 labels = gimplify_ctxp->case_labels;
2711 gimplify_ctxp->case_labels = saved_labels;
2713 if (gimplify_ctxp->live_switch_vars)
2715 gcc_assert (gimplify_ctxp->live_switch_vars->is_empty ());
2716 delete gimplify_ctxp->live_switch_vars;
2718 gimplify_ctxp->live_switch_vars = saved_live_switch_vars;
2720 preprocess_case_label_vec_for_gimple (labels, index_type,
2721 &default_case);
2723 bool add_bind = false;
2724 if (!default_case)
2726 glabel *new_default;
2728 default_case
2729 = build_case_label (NULL_TREE, NULL_TREE,
2730 create_artificial_label (UNKNOWN_LOCATION));
2731 if (old_in_switch_expr)
2733 SWITCH_BREAK_LABEL_P (CASE_LABEL (default_case)) = 1;
2734 add_bind = true;
2736 new_default = gimple_build_label (CASE_LABEL (default_case));
2737 gimplify_seq_add_stmt (&switch_body_seq, new_default);
2739 else if (old_in_switch_expr)
2741 gimple *last = gimple_seq_last_stmt (switch_body_seq);
2742 if (last && gimple_code (last) == GIMPLE_LABEL)
2744 tree label = gimple_label_label (as_a <glabel *> (last));
2745 if (SWITCH_BREAK_LABEL_P (label))
2746 add_bind = true;
2750 switch_stmt = gimple_build_switch (SWITCH_COND (switch_expr),
2751 default_case, labels);
2752 /* For the benefit of -Wimplicit-fallthrough, if switch_body_seq
2753 ends with a GIMPLE_LABEL holding SWITCH_BREAK_LABEL_P LABEL_DECL,
2754 wrap the GIMPLE_SWITCH up to that GIMPLE_LABEL into a GIMPLE_BIND,
2755 so that we can easily find the start and end of the switch
2756 statement. */
2757 if (add_bind)
2759 gimple_seq bind_body = NULL;
2760 gimplify_seq_add_stmt (&bind_body, switch_stmt);
2761 gimple_seq_add_seq (&bind_body, switch_body_seq);
2762 gbind *bind = gimple_build_bind (NULL_TREE, bind_body, NULL_TREE);
2763 gimple_set_location (bind, EXPR_LOCATION (switch_expr));
2764 gimplify_seq_add_stmt (pre_p, bind);
2766 else
2768 gimplify_seq_add_stmt (pre_p, switch_stmt);
2769 gimplify_seq_add_seq (pre_p, switch_body_seq);
2771 labels.release ();
2773 else
2774 gcc_unreachable ();
2776 return GS_ALL_DONE;
2779 /* Gimplify the LABEL_EXPR pointed to by EXPR_P. */
2781 static enum gimplify_status
2782 gimplify_label_expr (tree *expr_p, gimple_seq *pre_p)
2784 gcc_assert (decl_function_context (LABEL_EXPR_LABEL (*expr_p))
2785 == current_function_decl);
2787 tree label = LABEL_EXPR_LABEL (*expr_p);
2788 glabel *label_stmt = gimple_build_label (label);
2789 gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
2790 gimplify_seq_add_stmt (pre_p, label_stmt);
2792 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label)))
2793 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_COLD_LABEL,
2794 NOT_TAKEN));
2795 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label)))
2796 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_HOT_LABEL,
2797 TAKEN));
2799 return GS_ALL_DONE;
2802 /* Gimplify the CASE_LABEL_EXPR pointed to by EXPR_P. */
2804 static enum gimplify_status
2805 gimplify_case_label_expr (tree *expr_p, gimple_seq *pre_p)
2807 struct gimplify_ctx *ctxp;
2808 glabel *label_stmt;
2810 /* Invalid programs can play Duff's Device type games with, for example,
2811 #pragma omp parallel. At least in the C front end, we don't
2812 detect such invalid branches until after gimplification, in the
2813 diagnose_omp_blocks pass. */
2814 for (ctxp = gimplify_ctxp; ; ctxp = ctxp->prev_context)
2815 if (ctxp->case_labels.exists ())
2816 break;
2818 tree label = CASE_LABEL (*expr_p);
2819 label_stmt = gimple_build_label (label);
2820 gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
2821 ctxp->case_labels.safe_push (*expr_p);
2822 gimplify_seq_add_stmt (pre_p, label_stmt);
2824 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label)))
2825 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_COLD_LABEL,
2826 NOT_TAKEN));
2827 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label)))
2828 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_HOT_LABEL,
2829 TAKEN));
2831 return GS_ALL_DONE;
2834 /* Build a GOTO to the LABEL_DECL pointed to by LABEL_P, building it first
2835 if necessary. */
2837 tree
2838 build_and_jump (tree *label_p)
2840 if (label_p == NULL)
2841 /* If there's nowhere to jump, just fall through. */
2842 return NULL_TREE;
2844 if (*label_p == NULL_TREE)
2846 tree label = create_artificial_label (UNKNOWN_LOCATION);
2847 *label_p = label;
2850 return build1 (GOTO_EXPR, void_type_node, *label_p);
2853 /* Gimplify an EXIT_EXPR by converting to a GOTO_EXPR inside a COND_EXPR.
2854 This also involves building a label to jump to and communicating it to
2855 gimplify_loop_expr through gimplify_ctxp->exit_label. */
2857 static enum gimplify_status
2858 gimplify_exit_expr (tree *expr_p)
2860 tree cond = TREE_OPERAND (*expr_p, 0);
2861 tree expr;
2863 expr = build_and_jump (&gimplify_ctxp->exit_label);
2864 expr = build3 (COND_EXPR, void_type_node, cond, expr, NULL_TREE);
2865 *expr_p = expr;
2867 return GS_OK;
2870 /* *EXPR_P is a COMPONENT_REF being used as an rvalue. If its type is
2871 different from its canonical type, wrap the whole thing inside a
2872 NOP_EXPR and force the type of the COMPONENT_REF to be the canonical
2873 type.
2875 The canonical type of a COMPONENT_REF is the type of the field being
2876 referenced--unless the field is a bit-field which can be read directly
2877 in a smaller mode, in which case the canonical type is the
2878 sign-appropriate type corresponding to that mode. */
2880 static void
2881 canonicalize_component_ref (tree *expr_p)
2883 tree expr = *expr_p;
2884 tree type;
2886 gcc_assert (TREE_CODE (expr) == COMPONENT_REF);
2888 if (INTEGRAL_TYPE_P (TREE_TYPE (expr)))
2889 type = TREE_TYPE (get_unwidened (expr, NULL_TREE));
2890 else
2891 type = TREE_TYPE (TREE_OPERAND (expr, 1));
2893 /* One could argue that all the stuff below is not necessary for
2894 the non-bitfield case and declare it a FE error if type
2895 adjustment would be needed. */
2896 if (TREE_TYPE (expr) != type)
2898 #ifdef ENABLE_TYPES_CHECKING
2899 tree old_type = TREE_TYPE (expr);
2900 #endif
2901 int type_quals;
2903 /* We need to preserve qualifiers and propagate them from
2904 operand 0. */
2905 type_quals = TYPE_QUALS (type)
2906 | TYPE_QUALS (TREE_TYPE (TREE_OPERAND (expr, 0)));
2907 if (TYPE_QUALS (type) != type_quals)
2908 type = build_qualified_type (TYPE_MAIN_VARIANT (type), type_quals);
2910 /* Set the type of the COMPONENT_REF to the underlying type. */
2911 TREE_TYPE (expr) = type;
2913 #ifdef ENABLE_TYPES_CHECKING
2914 /* It is now a FE error, if the conversion from the canonical
2915 type to the original expression type is not useless. */
2916 gcc_assert (useless_type_conversion_p (old_type, type));
2917 #endif
2921 /* If a NOP conversion is changing a pointer to array of foo to a pointer
2922 to foo, embed that change in the ADDR_EXPR by converting
2923 T array[U];
2924 (T *)&array
2926 &array[L]
2927 where L is the lower bound. For simplicity, only do this for constant
2928 lower bound.
2929 The constraint is that the type of &array[L] is trivially convertible
2930 to T *. */
2932 static void
2933 canonicalize_addr_expr (tree *expr_p)
2935 tree expr = *expr_p;
2936 tree addr_expr = TREE_OPERAND (expr, 0);
2937 tree datype, ddatype, pddatype;
2939 /* We simplify only conversions from an ADDR_EXPR to a pointer type. */
2940 if (!POINTER_TYPE_P (TREE_TYPE (expr))
2941 || TREE_CODE (addr_expr) != ADDR_EXPR)
2942 return;
2944 /* The addr_expr type should be a pointer to an array. */
2945 datype = TREE_TYPE (TREE_TYPE (addr_expr));
2946 if (TREE_CODE (datype) != ARRAY_TYPE)
2947 return;
2949 /* The pointer to element type shall be trivially convertible to
2950 the expression pointer type. */
2951 ddatype = TREE_TYPE (datype);
2952 pddatype = build_pointer_type (ddatype);
2953 if (!useless_type_conversion_p (TYPE_MAIN_VARIANT (TREE_TYPE (expr)),
2954 pddatype))
2955 return;
2957 /* The lower bound and element sizes must be constant. */
2958 if (!TYPE_SIZE_UNIT (ddatype)
2959 || TREE_CODE (TYPE_SIZE_UNIT (ddatype)) != INTEGER_CST
2960 || !TYPE_DOMAIN (datype) || !TYPE_MIN_VALUE (TYPE_DOMAIN (datype))
2961 || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (datype))) != INTEGER_CST)
2962 return;
2964 /* All checks succeeded. Build a new node to merge the cast. */
2965 *expr_p = build4 (ARRAY_REF, ddatype, TREE_OPERAND (addr_expr, 0),
2966 TYPE_MIN_VALUE (TYPE_DOMAIN (datype)),
2967 NULL_TREE, NULL_TREE);
2968 *expr_p = build1 (ADDR_EXPR, pddatype, *expr_p);
2970 /* We can have stripped a required restrict qualifier above. */
2971 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
2972 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
2975 /* *EXPR_P is a NOP_EXPR or CONVERT_EXPR. Remove it and/or other conversions
2976 underneath as appropriate. */
2978 static enum gimplify_status
2979 gimplify_conversion (tree *expr_p)
2981 location_t loc = EXPR_LOCATION (*expr_p);
2982 gcc_assert (CONVERT_EXPR_P (*expr_p));
2984 /* Then strip away all but the outermost conversion. */
2985 STRIP_SIGN_NOPS (TREE_OPERAND (*expr_p, 0));
2987 /* And remove the outermost conversion if it's useless. */
2988 if (tree_ssa_useless_type_conversion (*expr_p))
2989 *expr_p = TREE_OPERAND (*expr_p, 0);
2991 /* If we still have a conversion at the toplevel,
2992 then canonicalize some constructs. */
2993 if (CONVERT_EXPR_P (*expr_p))
2995 tree sub = TREE_OPERAND (*expr_p, 0);
2997 /* If a NOP conversion is changing the type of a COMPONENT_REF
2998 expression, then canonicalize its type now in order to expose more
2999 redundant conversions. */
3000 if (TREE_CODE (sub) == COMPONENT_REF)
3001 canonicalize_component_ref (&TREE_OPERAND (*expr_p, 0));
3003 /* If a NOP conversion is changing a pointer to array of foo
3004 to a pointer to foo, embed that change in the ADDR_EXPR. */
3005 else if (TREE_CODE (sub) == ADDR_EXPR)
3006 canonicalize_addr_expr (expr_p);
3009 /* If we have a conversion to a non-register type force the
3010 use of a VIEW_CONVERT_EXPR instead. */
3011 if (CONVERT_EXPR_P (*expr_p) && !is_gimple_reg_type (TREE_TYPE (*expr_p)))
3012 *expr_p = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (*expr_p),
3013 TREE_OPERAND (*expr_p, 0));
3015 /* Canonicalize CONVERT_EXPR to NOP_EXPR. */
3016 if (TREE_CODE (*expr_p) == CONVERT_EXPR)
3017 TREE_SET_CODE (*expr_p, NOP_EXPR);
3019 return GS_OK;
3022 /* Gimplify a VAR_DECL or PARM_DECL. Return GS_OK if we expanded a
3023 DECL_VALUE_EXPR, and it's worth re-examining things. */
3025 static enum gimplify_status
3026 gimplify_var_or_parm_decl (tree *expr_p)
3028 tree decl = *expr_p;
3030 /* ??? If this is a local variable, and it has not been seen in any
3031 outer BIND_EXPR, then it's probably the result of a duplicate
3032 declaration, for which we've already issued an error. It would
3033 be really nice if the front end wouldn't leak these at all.
3034 Currently the only known culprit is C++ destructors, as seen
3035 in g++.old-deja/g++.jason/binding.C.
3036 Another possible culpit are size expressions for variably modified
3037 types which are lost in the FE or not gimplified correctly. */
3038 if (VAR_P (decl)
3039 && !DECL_SEEN_IN_BIND_EXPR_P (decl)
3040 && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl)
3041 && decl_function_context (decl) == current_function_decl)
3043 gcc_assert (seen_error ());
3044 return GS_ERROR;
3047 /* When within an OMP context, notice uses of variables. */
3048 if (gimplify_omp_ctxp && omp_notice_variable (gimplify_omp_ctxp, decl, true))
3049 return GS_ALL_DONE;
3051 /* If the decl is an alias for another expression, substitute it now. */
3052 if (DECL_HAS_VALUE_EXPR_P (decl))
3054 *expr_p = unshare_expr (DECL_VALUE_EXPR (decl));
3055 return GS_OK;
3058 return GS_ALL_DONE;
3061 /* Recalculate the value of the TREE_SIDE_EFFECTS flag for T. */
3063 static void
3064 recalculate_side_effects (tree t)
3066 enum tree_code code = TREE_CODE (t);
3067 int len = TREE_OPERAND_LENGTH (t);
3068 int i;
3070 switch (TREE_CODE_CLASS (code))
3072 case tcc_expression:
3073 switch (code)
3075 case INIT_EXPR:
3076 case MODIFY_EXPR:
3077 case VA_ARG_EXPR:
3078 case PREDECREMENT_EXPR:
3079 case PREINCREMENT_EXPR:
3080 case POSTDECREMENT_EXPR:
3081 case POSTINCREMENT_EXPR:
3082 /* All of these have side-effects, no matter what their
3083 operands are. */
3084 return;
3086 default:
3087 break;
3089 /* Fall through. */
3091 case tcc_comparison: /* a comparison expression */
3092 case tcc_unary: /* a unary arithmetic expression */
3093 case tcc_binary: /* a binary arithmetic expression */
3094 case tcc_reference: /* a reference */
3095 case tcc_vl_exp: /* a function call */
3096 TREE_SIDE_EFFECTS (t) = TREE_THIS_VOLATILE (t);
3097 for (i = 0; i < len; ++i)
3099 tree op = TREE_OPERAND (t, i);
3100 if (op && TREE_SIDE_EFFECTS (op))
3101 TREE_SIDE_EFFECTS (t) = 1;
3103 break;
3105 case tcc_constant:
3106 /* No side-effects. */
3107 return;
3109 default:
3110 gcc_unreachable ();
3114 /* Gimplify the COMPONENT_REF, ARRAY_REF, REALPART_EXPR or IMAGPART_EXPR
3115 node *EXPR_P.
3117 compound_lval
3118 : min_lval '[' val ']'
3119 | min_lval '.' ID
3120 | compound_lval '[' val ']'
3121 | compound_lval '.' ID
3123 This is not part of the original SIMPLE definition, which separates
3124 array and member references, but it seems reasonable to handle them
3125 together. Also, this way we don't run into problems with union
3126 aliasing; gcc requires that for accesses through a union to alias, the
3127 union reference must be explicit, which was not always the case when we
3128 were splitting up array and member refs.
3130 PRE_P points to the sequence where side effects that must happen before
3131 *EXPR_P should be stored.
3133 POST_P points to the sequence where side effects that must happen after
3134 *EXPR_P should be stored. */
3136 static enum gimplify_status
3137 gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
3138 fallback_t fallback)
3140 tree *p;
3141 enum gimplify_status ret = GS_ALL_DONE, tret;
3142 int i;
3143 location_t loc = EXPR_LOCATION (*expr_p);
3144 tree expr = *expr_p;
3146 /* Create a stack of the subexpressions so later we can walk them in
3147 order from inner to outer. */
3148 auto_vec<tree, 10> expr_stack;
3150 /* We can handle anything that get_inner_reference can deal with. */
3151 for (p = expr_p; ; p = &TREE_OPERAND (*p, 0))
3153 restart:
3154 /* Fold INDIRECT_REFs now to turn them into ARRAY_REFs. */
3155 if (TREE_CODE (*p) == INDIRECT_REF)
3156 *p = fold_indirect_ref_loc (loc, *p);
3158 if (handled_component_p (*p))
3160 /* Expand DECL_VALUE_EXPR now. In some cases that may expose
3161 additional COMPONENT_REFs. */
3162 else if ((VAR_P (*p) || TREE_CODE (*p) == PARM_DECL)
3163 && gimplify_var_or_parm_decl (p) == GS_OK)
3164 goto restart;
3165 else
3166 break;
3168 expr_stack.safe_push (*p);
3171 gcc_assert (expr_stack.length ());
3173 /* Now EXPR_STACK is a stack of pointers to all the refs we've
3174 walked through and P points to the innermost expression.
3176 Java requires that we elaborated nodes in source order. That
3177 means we must gimplify the inner expression followed by each of
3178 the indices, in order. But we can't gimplify the inner
3179 expression until we deal with any variable bounds, sizes, or
3180 positions in order to deal with PLACEHOLDER_EXPRs.
3182 The base expression may contain a statement expression that
3183 has declarations used in size expressions, so has to be
3184 gimplified before gimplifying the size expressions.
3186 So we do this in three steps. First we deal with variable
3187 bounds, sizes, and positions, then we gimplify the base and
3188 ensure it is memory if needed, then we deal with the annotations
3189 for any variables in the components and any indices, from left
3190 to right. */
3192 bool need_non_reg = false;
3193 for (i = expr_stack.length () - 1; i >= 0; i--)
3195 tree t = expr_stack[i];
3197 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
3199 /* Deal with the low bound and element type size and put them into
3200 the ARRAY_REF. If these values are set, they have already been
3201 gimplified. */
3202 if (TREE_OPERAND (t, 2) == NULL_TREE)
3204 tree low = unshare_expr (array_ref_low_bound (t));
3205 if (!is_gimple_min_invariant (low))
3207 TREE_OPERAND (t, 2) = low;
3211 if (TREE_OPERAND (t, 3) == NULL_TREE)
3213 tree elmt_size = array_ref_element_size (t);
3214 if (!is_gimple_min_invariant (elmt_size))
3216 elmt_size = unshare_expr (elmt_size);
3217 tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0)));
3218 tree factor = size_int (TYPE_ALIGN_UNIT (elmt_type));
3220 /* Divide the element size by the alignment of the element
3221 type (above). */
3222 elmt_size = size_binop_loc (loc, EXACT_DIV_EXPR,
3223 elmt_size, factor);
3225 TREE_OPERAND (t, 3) = elmt_size;
3228 need_non_reg = true;
3230 else if (TREE_CODE (t) == COMPONENT_REF)
3232 /* Set the field offset into T and gimplify it. */
3233 if (TREE_OPERAND (t, 2) == NULL_TREE)
3235 tree offset = component_ref_field_offset (t);
3236 if (!is_gimple_min_invariant (offset))
3238 offset = unshare_expr (offset);
3239 tree field = TREE_OPERAND (t, 1);
3240 tree factor
3241 = size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT);
3243 /* Divide the offset by its alignment. */
3244 offset = size_binop_loc (loc, EXACT_DIV_EXPR,
3245 offset, factor);
3247 TREE_OPERAND (t, 2) = offset;
3250 need_non_reg = true;
3254 /* Step 2 is to gimplify the base expression. Make sure lvalue is set
3255 so as to match the min_lval predicate. Failure to do so may result
3256 in the creation of large aggregate temporaries. */
3257 tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval,
3258 fallback | fb_lvalue);
3259 ret = MIN (ret, tret);
3261 /* Step 2a: if we have component references we do not support on
3262 registers then make sure the base isn't a register. Of course
3263 we can only do so if an rvalue is OK. */
3264 if (need_non_reg && (fallback & fb_rvalue))
3265 prepare_gimple_addressable (p, pre_p);
3267 /* Step 3: gimplify size expressions and the indices and operands of
3268 ARRAY_REF. During this loop we also remove any useless conversions. */
3270 for (; expr_stack.length () > 0; )
3272 tree t = expr_stack.pop ();
3274 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
3276 /* Gimplify the low bound and element type size. */
3277 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
3278 is_gimple_reg, fb_rvalue);
3279 ret = MIN (ret, tret);
3281 tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p, post_p,
3282 is_gimple_reg, fb_rvalue);
3283 ret = MIN (ret, tret);
3285 /* Gimplify the dimension. */
3286 tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
3287 is_gimple_val, fb_rvalue);
3288 ret = MIN (ret, tret);
3290 else if (TREE_CODE (t) == COMPONENT_REF)
3292 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
3293 is_gimple_reg, fb_rvalue);
3294 ret = MIN (ret, tret);
3297 STRIP_USELESS_TYPE_CONVERSION (TREE_OPERAND (t, 0));
3299 /* The innermost expression P may have originally had
3300 TREE_SIDE_EFFECTS set which would have caused all the outer
3301 expressions in *EXPR_P leading to P to also have had
3302 TREE_SIDE_EFFECTS set. */
3303 recalculate_side_effects (t);
3306 /* If the outermost expression is a COMPONENT_REF, canonicalize its type. */
3307 if ((fallback & fb_rvalue) && TREE_CODE (*expr_p) == COMPONENT_REF)
3309 canonicalize_component_ref (expr_p);
3312 expr_stack.release ();
3314 gcc_assert (*expr_p == expr || ret != GS_ALL_DONE);
3316 return ret;
3319 /* Gimplify the self modifying expression pointed to by EXPR_P
3320 (++, --, +=, -=).
3322 PRE_P points to the list where side effects that must happen before
3323 *EXPR_P should be stored.
3325 POST_P points to the list where side effects that must happen after
3326 *EXPR_P should be stored.
3328 WANT_VALUE is nonzero iff we want to use the value of this expression
3329 in another expression.
3331 ARITH_TYPE is the type the computation should be performed in. */
3333 enum gimplify_status
3334 gimplify_self_mod_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
3335 bool want_value, tree arith_type)
3337 enum tree_code code;
3338 tree lhs, lvalue, rhs, t1;
3339 gimple_seq post = NULL, *orig_post_p = post_p;
3340 bool postfix;
3341 enum tree_code arith_code;
3342 enum gimplify_status ret;
3343 location_t loc = EXPR_LOCATION (*expr_p);
3345 code = TREE_CODE (*expr_p);
3347 gcc_assert (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR
3348 || code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR);
3350 /* Prefix or postfix? */
3351 if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
3352 /* Faster to treat as prefix if result is not used. */
3353 postfix = want_value;
3354 else
3355 postfix = false;
3357 /* For postfix, make sure the inner expression's post side effects
3358 are executed after side effects from this expression. */
3359 if (postfix)
3360 post_p = &post;
3362 /* Add or subtract? */
3363 if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
3364 arith_code = PLUS_EXPR;
3365 else
3366 arith_code = MINUS_EXPR;
3368 /* Gimplify the LHS into a GIMPLE lvalue. */
3369 lvalue = TREE_OPERAND (*expr_p, 0);
3370 ret = gimplify_expr (&lvalue, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
3371 if (ret == GS_ERROR)
3372 return ret;
3374 /* Extract the operands to the arithmetic operation. */
3375 lhs = lvalue;
3376 rhs = TREE_OPERAND (*expr_p, 1);
3378 /* For postfix operator, we evaluate the LHS to an rvalue and then use
3379 that as the result value and in the postqueue operation. */
3380 if (postfix)
3382 ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue);
3383 if (ret == GS_ERROR)
3384 return ret;
3386 lhs = get_initialized_tmp_var (lhs, pre_p);
3389 /* For POINTERs increment, use POINTER_PLUS_EXPR. */
3390 if (POINTER_TYPE_P (TREE_TYPE (lhs)))
3392 rhs = convert_to_ptrofftype_loc (loc, rhs);
3393 if (arith_code == MINUS_EXPR)
3394 rhs = fold_build1_loc (loc, NEGATE_EXPR, TREE_TYPE (rhs), rhs);
3395 t1 = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (*expr_p), lhs, rhs);
3397 else
3398 t1 = fold_convert (TREE_TYPE (*expr_p),
3399 fold_build2 (arith_code, arith_type,
3400 fold_convert (arith_type, lhs),
3401 fold_convert (arith_type, rhs)));
3403 if (postfix)
3405 gimplify_assign (lvalue, t1, pre_p);
3406 gimplify_seq_add_seq (orig_post_p, post);
3407 *expr_p = lhs;
3408 return GS_ALL_DONE;
3410 else
3412 *expr_p = build2 (MODIFY_EXPR, TREE_TYPE (lvalue), lvalue, t1);
3413 return GS_OK;
3417 /* If *EXPR_P has a variable sized type, wrap it in a WITH_SIZE_EXPR. */
3419 static void
3420 maybe_with_size_expr (tree *expr_p)
3422 tree expr = *expr_p;
3423 tree type = TREE_TYPE (expr);
3424 tree size;
3426 /* If we've already wrapped this or the type is error_mark_node, we can't do
3427 anything. */
3428 if (TREE_CODE (expr) == WITH_SIZE_EXPR
3429 || type == error_mark_node)
3430 return;
3432 /* If the size isn't known or is a constant, we have nothing to do. */
3433 size = TYPE_SIZE_UNIT (type);
3434 if (!size || poly_int_tree_p (size))
3435 return;
3437 /* Otherwise, make a WITH_SIZE_EXPR. */
3438 size = unshare_expr (size);
3439 size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, expr);
3440 *expr_p = build2 (WITH_SIZE_EXPR, type, expr, size);
3443 /* Helper for gimplify_call_expr. Gimplify a single argument *ARG_P
3444 Store any side-effects in PRE_P. CALL_LOCATION is the location of
3445 the CALL_EXPR. If ALLOW_SSA is set the actual parameter may be
3446 gimplified to an SSA name. */
3448 enum gimplify_status
3449 gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location,
3450 bool allow_ssa)
3452 bool (*test) (tree);
3453 fallback_t fb;
3455 /* In general, we allow lvalues for function arguments to avoid
3456 extra overhead of copying large aggregates out of even larger
3457 aggregates into temporaries only to copy the temporaries to
3458 the argument list. Make optimizers happy by pulling out to
3459 temporaries those types that fit in registers. */
3460 if (is_gimple_reg_type (TREE_TYPE (*arg_p)))
3461 test = is_gimple_val, fb = fb_rvalue;
3462 else
3464 test = is_gimple_lvalue, fb = fb_either;
3465 /* Also strip a TARGET_EXPR that would force an extra copy. */
3466 if (TREE_CODE (*arg_p) == TARGET_EXPR)
3468 tree init = TARGET_EXPR_INITIAL (*arg_p);
3469 if (init
3470 && !VOID_TYPE_P (TREE_TYPE (init)))
3471 *arg_p = init;
3475 /* If this is a variable sized type, we must remember the size. */
3476 maybe_with_size_expr (arg_p);
3478 /* FIXME diagnostics: This will mess up gcc.dg/Warray-bounds.c. */
3479 /* Make sure arguments have the same location as the function call
3480 itself. */
3481 protected_set_expr_location (*arg_p, call_location);
3483 /* There is a sequence point before a function call. Side effects in
3484 the argument list must occur before the actual call. So, when
3485 gimplifying arguments, force gimplify_expr to use an internal
3486 post queue which is then appended to the end of PRE_P. */
3487 return gimplify_expr (arg_p, pre_p, NULL, test, fb, allow_ssa);
3490 /* Don't fold inside offloading or taskreg regions: it can break code by
3491 adding decl references that weren't in the source. We'll do it during
3492 omplower pass instead. */
3494 static bool
3495 maybe_fold_stmt (gimple_stmt_iterator *gsi)
3497 struct gimplify_omp_ctx *ctx;
3498 for (ctx = gimplify_omp_ctxp; ctx; ctx = ctx->outer_context)
3499 if ((ctx->region_type & (ORT_TARGET | ORT_PARALLEL | ORT_TASK)) != 0)
3500 return false;
3501 else if ((ctx->region_type & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
3502 return false;
3503 /* Delay folding of builtins until the IL is in consistent state
3504 so the diagnostic machinery can do a better job. */
3505 if (gimple_call_builtin_p (gsi_stmt (*gsi)))
3506 return false;
3507 return fold_stmt (gsi);
3510 /* Gimplify the CALL_EXPR node *EXPR_P into the GIMPLE sequence PRE_P.
3511 WANT_VALUE is true if the result of the call is desired. */
3513 static enum gimplify_status
3514 gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
3516 tree fndecl, parms, p, fnptrtype;
3517 enum gimplify_status ret;
3518 int i, nargs;
3519 gcall *call;
3520 bool builtin_va_start_p = false;
3521 location_t loc = EXPR_LOCATION (*expr_p);
3523 gcc_assert (TREE_CODE (*expr_p) == CALL_EXPR);
3525 /* For reliable diagnostics during inlining, it is necessary that
3526 every call_expr be annotated with file and line. */
3527 if (! EXPR_HAS_LOCATION (*expr_p))
3528 SET_EXPR_LOCATION (*expr_p, input_location);
3530 /* Gimplify internal functions created in the FEs. */
3531 if (CALL_EXPR_FN (*expr_p) == NULL_TREE)
3533 if (want_value)
3534 return GS_ALL_DONE;
3536 nargs = call_expr_nargs (*expr_p);
3537 enum internal_fn ifn = CALL_EXPR_IFN (*expr_p);
3538 auto_vec<tree> vargs (nargs);
3540 for (i = 0; i < nargs; i++)
3542 gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
3543 EXPR_LOCATION (*expr_p));
3544 vargs.quick_push (CALL_EXPR_ARG (*expr_p, i));
3547 gcall *call = gimple_build_call_internal_vec (ifn, vargs);
3548 gimple_call_set_nothrow (call, TREE_NOTHROW (*expr_p));
3549 gimplify_seq_add_stmt (pre_p, call);
3550 return GS_ALL_DONE;
3553 /* This may be a call to a builtin function.
3555 Builtin function calls may be transformed into different
3556 (and more efficient) builtin function calls under certain
3557 circumstances. Unfortunately, gimplification can muck things
3558 up enough that the builtin expanders are not aware that certain
3559 transformations are still valid.
3561 So we attempt transformation/gimplification of the call before
3562 we gimplify the CALL_EXPR. At this time we do not manage to
3563 transform all calls in the same manner as the expanders do, but
3564 we do transform most of them. */
3565 fndecl = get_callee_fndecl (*expr_p);
3566 if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
3567 switch (DECL_FUNCTION_CODE (fndecl))
3569 CASE_BUILT_IN_ALLOCA:
3570 /* If the call has been built for a variable-sized object, then we
3571 want to restore the stack level when the enclosing BIND_EXPR is
3572 exited to reclaim the allocated space; otherwise, we precisely
3573 need to do the opposite and preserve the latest stack level. */
3574 if (CALL_ALLOCA_FOR_VAR_P (*expr_p))
3575 gimplify_ctxp->save_stack = true;
3576 else
3577 gimplify_ctxp->keep_stack = true;
3578 break;
3580 case BUILT_IN_VA_START:
3582 builtin_va_start_p = TRUE;
3583 if (call_expr_nargs (*expr_p) < 2)
3585 error ("too few arguments to function %<va_start%>");
3586 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
3587 return GS_OK;
3590 if (fold_builtin_next_arg (*expr_p, true))
3592 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
3593 return GS_OK;
3595 break;
3598 case BUILT_IN_EH_RETURN:
3599 cfun->calls_eh_return = true;
3600 break;
3602 case BUILT_IN_CLEAR_PADDING:
3603 if (call_expr_nargs (*expr_p) == 1)
3605 /* Remember the original type of the argument in an internal
3606 dummy second argument, as in GIMPLE pointer conversions are
3607 useless. Also mark this call as not for automatic
3608 initialization in the internal dummy third argument. */
3609 p = CALL_EXPR_ARG (*expr_p, 0);
3610 *expr_p
3611 = build_call_expr_loc (EXPR_LOCATION (*expr_p), fndecl, 2, p,
3612 build_zero_cst (TREE_TYPE (p)));
3613 return GS_OK;
3615 break;
3617 default:
3620 if (fndecl && fndecl_built_in_p (fndecl))
3622 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
3623 if (new_tree && new_tree != *expr_p)
3625 /* There was a transformation of this call which computes the
3626 same value, but in a more efficient way. Return and try
3627 again. */
3628 *expr_p = new_tree;
3629 return GS_OK;
3633 /* Remember the original function pointer type. */
3634 fnptrtype = TREE_TYPE (CALL_EXPR_FN (*expr_p));
3636 if (flag_openmp
3637 && fndecl
3638 && cfun
3639 && (cfun->curr_properties & PROP_gimple_any) == 0)
3641 tree variant = omp_resolve_declare_variant (fndecl);
3642 if (variant != fndecl)
3643 CALL_EXPR_FN (*expr_p) = build1 (ADDR_EXPR, fnptrtype, variant);
3646 /* There is a sequence point before the call, so any side effects in
3647 the calling expression must occur before the actual call. Force
3648 gimplify_expr to use an internal post queue. */
3649 ret = gimplify_expr (&CALL_EXPR_FN (*expr_p), pre_p, NULL,
3650 is_gimple_call_addr, fb_rvalue);
3652 nargs = call_expr_nargs (*expr_p);
3654 /* Get argument types for verification. */
3655 fndecl = get_callee_fndecl (*expr_p);
3656 parms = NULL_TREE;
3657 if (fndecl)
3658 parms = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
3659 else
3660 parms = TYPE_ARG_TYPES (TREE_TYPE (fnptrtype));
3662 if (fndecl && DECL_ARGUMENTS (fndecl))
3663 p = DECL_ARGUMENTS (fndecl);
3664 else if (parms)
3665 p = parms;
3666 else
3667 p = NULL_TREE;
3668 for (i = 0; i < nargs && p; i++, p = TREE_CHAIN (p))
3671 /* If the last argument is __builtin_va_arg_pack () and it is not
3672 passed as a named argument, decrease the number of CALL_EXPR
3673 arguments and set instead the CALL_EXPR_VA_ARG_PACK flag. */
3674 if (!p
3675 && i < nargs
3676 && TREE_CODE (CALL_EXPR_ARG (*expr_p, nargs - 1)) == CALL_EXPR)
3678 tree last_arg = CALL_EXPR_ARG (*expr_p, nargs - 1);
3679 tree last_arg_fndecl = get_callee_fndecl (last_arg);
3681 if (last_arg_fndecl
3682 && fndecl_built_in_p (last_arg_fndecl, BUILT_IN_VA_ARG_PACK))
3684 tree call = *expr_p;
3686 --nargs;
3687 *expr_p = build_call_array_loc (loc, TREE_TYPE (call),
3688 CALL_EXPR_FN (call),
3689 nargs, CALL_EXPR_ARGP (call));
3691 /* Copy all CALL_EXPR flags, location and block, except
3692 CALL_EXPR_VA_ARG_PACK flag. */
3693 CALL_EXPR_STATIC_CHAIN (*expr_p) = CALL_EXPR_STATIC_CHAIN (call);
3694 CALL_EXPR_TAILCALL (*expr_p) = CALL_EXPR_TAILCALL (call);
3695 CALL_EXPR_RETURN_SLOT_OPT (*expr_p)
3696 = CALL_EXPR_RETURN_SLOT_OPT (call);
3697 CALL_FROM_THUNK_P (*expr_p) = CALL_FROM_THUNK_P (call);
3698 SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (call));
3700 /* Set CALL_EXPR_VA_ARG_PACK. */
3701 CALL_EXPR_VA_ARG_PACK (*expr_p) = 1;
3705 /* If the call returns twice then after building the CFG the call
3706 argument computations will no longer dominate the call because
3707 we add an abnormal incoming edge to the call. So do not use SSA
3708 vars there. */
3709 bool returns_twice = call_expr_flags (*expr_p) & ECF_RETURNS_TWICE;
3711 /* Gimplify the function arguments. */
3712 if (nargs > 0)
3714 for (i = (PUSH_ARGS_REVERSED ? nargs - 1 : 0);
3715 PUSH_ARGS_REVERSED ? i >= 0 : i < nargs;
3716 PUSH_ARGS_REVERSED ? i-- : i++)
3718 enum gimplify_status t;
3720 /* Avoid gimplifying the second argument to va_start, which needs to
3721 be the plain PARM_DECL. */
3722 if ((i != 1) || !builtin_va_start_p)
3724 t = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
3725 EXPR_LOCATION (*expr_p), ! returns_twice);
3727 if (t == GS_ERROR)
3728 ret = GS_ERROR;
3733 /* Gimplify the static chain. */
3734 if (CALL_EXPR_STATIC_CHAIN (*expr_p))
3736 if (fndecl && !DECL_STATIC_CHAIN (fndecl))
3737 CALL_EXPR_STATIC_CHAIN (*expr_p) = NULL;
3738 else
3740 enum gimplify_status t;
3741 t = gimplify_arg (&CALL_EXPR_STATIC_CHAIN (*expr_p), pre_p,
3742 EXPR_LOCATION (*expr_p), ! returns_twice);
3743 if (t == GS_ERROR)
3744 ret = GS_ERROR;
3748 /* Verify the function result. */
3749 if (want_value && fndecl
3750 && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fnptrtype))))
3752 error_at (loc, "using result of function returning %<void%>");
3753 ret = GS_ERROR;
3756 /* Try this again in case gimplification exposed something. */
3757 if (ret != GS_ERROR)
3759 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
3761 if (new_tree && new_tree != *expr_p)
3763 /* There was a transformation of this call which computes the
3764 same value, but in a more efficient way. Return and try
3765 again. */
3766 *expr_p = new_tree;
3767 return GS_OK;
3770 else
3772 *expr_p = error_mark_node;
3773 return GS_ERROR;
3776 /* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its
3777 decl. This allows us to eliminate redundant or useless
3778 calls to "const" functions. */
3779 if (TREE_CODE (*expr_p) == CALL_EXPR)
3781 int flags = call_expr_flags (*expr_p);
3782 if (flags & (ECF_CONST | ECF_PURE)
3783 /* An infinite loop is considered a side effect. */
3784 && !(flags & (ECF_LOOPING_CONST_OR_PURE)))
3785 TREE_SIDE_EFFECTS (*expr_p) = 0;
3788 /* If the value is not needed by the caller, emit a new GIMPLE_CALL
3789 and clear *EXPR_P. Otherwise, leave *EXPR_P in its gimplified
3790 form and delegate the creation of a GIMPLE_CALL to
3791 gimplify_modify_expr. This is always possible because when
3792 WANT_VALUE is true, the caller wants the result of this call into
3793 a temporary, which means that we will emit an INIT_EXPR in
3794 internal_get_tmp_var which will then be handled by
3795 gimplify_modify_expr. */
3796 if (!want_value)
3798 /* The CALL_EXPR in *EXPR_P is already in GIMPLE form, so all we
3799 have to do is replicate it as a GIMPLE_CALL tuple. */
3800 gimple_stmt_iterator gsi;
3801 call = gimple_build_call_from_tree (*expr_p, fnptrtype);
3802 notice_special_calls (call);
3803 gimplify_seq_add_stmt (pre_p, call);
3804 gsi = gsi_last (*pre_p);
3805 maybe_fold_stmt (&gsi);
3806 *expr_p = NULL_TREE;
3808 else
3809 /* Remember the original function type. */
3810 CALL_EXPR_FN (*expr_p) = build1 (NOP_EXPR, fnptrtype,
3811 CALL_EXPR_FN (*expr_p));
3813 return ret;
3816 /* Handle shortcut semantics in the predicate operand of a COND_EXPR by
3817 rewriting it into multiple COND_EXPRs, and possibly GOTO_EXPRs.
3819 TRUE_LABEL_P and FALSE_LABEL_P point to the labels to jump to if the
3820 condition is true or false, respectively. If null, we should generate
3821 our own to skip over the evaluation of this specific expression.
3823 LOCUS is the source location of the COND_EXPR.
3825 This function is the tree equivalent of do_jump.
3827 shortcut_cond_r should only be called by shortcut_cond_expr. */
3829 static tree
3830 shortcut_cond_r (tree pred, tree *true_label_p, tree *false_label_p,
3831 location_t locus)
3833 tree local_label = NULL_TREE;
3834 tree t, expr = NULL;
3836 /* OK, it's not a simple case; we need to pull apart the COND_EXPR to
3837 retain the shortcut semantics. Just insert the gotos here;
3838 shortcut_cond_expr will append the real blocks later. */
3839 if (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
3841 location_t new_locus;
3843 /* Turn if (a && b) into
3845 if (a); else goto no;
3846 if (b) goto yes; else goto no;
3847 (no:) */
3849 if (false_label_p == NULL)
3850 false_label_p = &local_label;
3852 /* Keep the original source location on the first 'if'. */
3853 t = shortcut_cond_r (TREE_OPERAND (pred, 0), NULL, false_label_p, locus);
3854 append_to_statement_list (t, &expr);
3856 /* Set the source location of the && on the second 'if'. */
3857 new_locus = rexpr_location (pred, locus);
3858 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
3859 new_locus);
3860 append_to_statement_list (t, &expr);
3862 else if (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
3864 location_t new_locus;
3866 /* Turn if (a || b) into
3868 if (a) goto yes;
3869 if (b) goto yes; else goto no;
3870 (yes:) */
3872 if (true_label_p == NULL)
3873 true_label_p = &local_label;
3875 /* Keep the original source location on the first 'if'. */
3876 t = shortcut_cond_r (TREE_OPERAND (pred, 0), true_label_p, NULL, locus);
3877 append_to_statement_list (t, &expr);
3879 /* Set the source location of the || on the second 'if'. */
3880 new_locus = rexpr_location (pred, locus);
3881 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
3882 new_locus);
3883 append_to_statement_list (t, &expr);
3885 else if (TREE_CODE (pred) == COND_EXPR
3886 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 1)))
3887 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 2))))
3889 location_t new_locus;
3891 /* As long as we're messing with gotos, turn if (a ? b : c) into
3892 if (a)
3893 if (b) goto yes; else goto no;
3894 else
3895 if (c) goto yes; else goto no;
3897 Don't do this if one of the arms has void type, which can happen
3898 in C++ when the arm is throw. */
3900 /* Keep the original source location on the first 'if'. Set the source
3901 location of the ? on the second 'if'. */
3902 new_locus = rexpr_location (pred, locus);
3903 expr = build3 (COND_EXPR, void_type_node, TREE_OPERAND (pred, 0),
3904 shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p,
3905 false_label_p, locus),
3906 shortcut_cond_r (TREE_OPERAND (pred, 2), true_label_p,
3907 false_label_p, new_locus));
3909 else
3911 expr = build3 (COND_EXPR, void_type_node, pred,
3912 build_and_jump (true_label_p),
3913 build_and_jump (false_label_p));
3914 SET_EXPR_LOCATION (expr, locus);
3917 if (local_label)
3919 t = build1 (LABEL_EXPR, void_type_node, local_label);
3920 append_to_statement_list (t, &expr);
3923 return expr;
3926 /* If EXPR is a GOTO_EXPR, return it. If it is a STATEMENT_LIST, skip
3927 any of its leading DEBUG_BEGIN_STMTS and recurse on the subsequent
3928 statement, if it is the last one. Otherwise, return NULL. */
3930 static tree
3931 find_goto (tree expr)
3933 if (!expr)
3934 return NULL_TREE;
3936 if (TREE_CODE (expr) == GOTO_EXPR)
3937 return expr;
3939 if (TREE_CODE (expr) != STATEMENT_LIST)
3940 return NULL_TREE;
3942 tree_stmt_iterator i = tsi_start (expr);
3944 while (!tsi_end_p (i) && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT)
3945 tsi_next (&i);
3947 if (!tsi_one_before_end_p (i))
3948 return NULL_TREE;
3950 return find_goto (tsi_stmt (i));
3953 /* Same as find_goto, except that it returns NULL if the destination
3954 is not a LABEL_DECL. */
3956 static inline tree
3957 find_goto_label (tree expr)
3959 tree dest = find_goto (expr);
3960 if (dest && TREE_CODE (GOTO_DESTINATION (dest)) == LABEL_DECL)
3961 return dest;
3962 return NULL_TREE;
3965 /* Given a conditional expression EXPR with short-circuit boolean
3966 predicates using TRUTH_ANDIF_EXPR or TRUTH_ORIF_EXPR, break the
3967 predicate apart into the equivalent sequence of conditionals. */
3969 static tree
3970 shortcut_cond_expr (tree expr)
3972 tree pred = TREE_OPERAND (expr, 0);
3973 tree then_ = TREE_OPERAND (expr, 1);
3974 tree else_ = TREE_OPERAND (expr, 2);
3975 tree true_label, false_label, end_label, t;
3976 tree *true_label_p;
3977 tree *false_label_p;
3978 bool emit_end, emit_false, jump_over_else;
3979 bool then_se = then_ && TREE_SIDE_EFFECTS (then_);
3980 bool else_se = else_ && TREE_SIDE_EFFECTS (else_);
3982 /* First do simple transformations. */
3983 if (!else_se)
3985 /* If there is no 'else', turn
3986 if (a && b) then c
3987 into
3988 if (a) if (b) then c. */
3989 while (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
3991 /* Keep the original source location on the first 'if'. */
3992 location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
3993 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
3994 /* Set the source location of the && on the second 'if'. */
3995 if (rexpr_has_location (pred))
3996 SET_EXPR_LOCATION (expr, rexpr_location (pred));
3997 then_ = shortcut_cond_expr (expr);
3998 then_se = then_ && TREE_SIDE_EFFECTS (then_);
3999 pred = TREE_OPERAND (pred, 0);
4000 expr = build3 (COND_EXPR, void_type_node, pred, then_, NULL_TREE);
4001 SET_EXPR_LOCATION (expr, locus);
4005 if (!then_se)
4007 /* If there is no 'then', turn
4008 if (a || b); else d
4009 into
4010 if (a); else if (b); else d. */
4011 while (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
4013 /* Keep the original source location on the first 'if'. */
4014 location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
4015 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
4016 /* Set the source location of the || on the second 'if'. */
4017 if (rexpr_has_location (pred))
4018 SET_EXPR_LOCATION (expr, rexpr_location (pred));
4019 else_ = shortcut_cond_expr (expr);
4020 else_se = else_ && TREE_SIDE_EFFECTS (else_);
4021 pred = TREE_OPERAND (pred, 0);
4022 expr = build3 (COND_EXPR, void_type_node, pred, NULL_TREE, else_);
4023 SET_EXPR_LOCATION (expr, locus);
4027 /* If we're done, great. */
4028 if (TREE_CODE (pred) != TRUTH_ANDIF_EXPR
4029 && TREE_CODE (pred) != TRUTH_ORIF_EXPR)
4030 return expr;
4032 /* Otherwise we need to mess with gotos. Change
4033 if (a) c; else d;
4035 if (a); else goto no;
4036 c; goto end;
4037 no: d; end:
4038 and recursively gimplify the condition. */
4040 true_label = false_label = end_label = NULL_TREE;
4042 /* If our arms just jump somewhere, hijack those labels so we don't
4043 generate jumps to jumps. */
4045 if (tree then_goto = find_goto_label (then_))
4047 true_label = GOTO_DESTINATION (then_goto);
4048 then_ = NULL;
4049 then_se = false;
4052 if (tree else_goto = find_goto_label (else_))
4054 false_label = GOTO_DESTINATION (else_goto);
4055 else_ = NULL;
4056 else_se = false;
4059 /* If we aren't hijacking a label for the 'then' branch, it falls through. */
4060 if (true_label)
4061 true_label_p = &true_label;
4062 else
4063 true_label_p = NULL;
4065 /* The 'else' branch also needs a label if it contains interesting code. */
4066 if (false_label || else_se)
4067 false_label_p = &false_label;
4068 else
4069 false_label_p = NULL;
4071 /* If there was nothing else in our arms, just forward the label(s). */
4072 if (!then_se && !else_se)
4073 return shortcut_cond_r (pred, true_label_p, false_label_p,
4074 EXPR_LOC_OR_LOC (expr, input_location));
4076 /* If our last subexpression already has a terminal label, reuse it. */
4077 if (else_se)
4078 t = expr_last (else_);
4079 else if (then_se)
4080 t = expr_last (then_);
4081 else
4082 t = NULL;
4083 if (t && TREE_CODE (t) == LABEL_EXPR)
4084 end_label = LABEL_EXPR_LABEL (t);
4086 /* If we don't care about jumping to the 'else' branch, jump to the end
4087 if the condition is false. */
4088 if (!false_label_p)
4089 false_label_p = &end_label;
4091 /* We only want to emit these labels if we aren't hijacking them. */
4092 emit_end = (end_label == NULL_TREE);
4093 emit_false = (false_label == NULL_TREE);
4095 /* We only emit the jump over the else clause if we have to--if the
4096 then clause may fall through. Otherwise we can wind up with a
4097 useless jump and a useless label at the end of gimplified code,
4098 which will cause us to think that this conditional as a whole
4099 falls through even if it doesn't. If we then inline a function
4100 which ends with such a condition, that can cause us to issue an
4101 inappropriate warning about control reaching the end of a
4102 non-void function. */
4103 jump_over_else = block_may_fallthru (then_);
4105 pred = shortcut_cond_r (pred, true_label_p, false_label_p,
4106 EXPR_LOC_OR_LOC (expr, input_location));
4108 expr = NULL;
4109 append_to_statement_list (pred, &expr);
4111 append_to_statement_list (then_, &expr);
4112 if (else_se)
4114 if (jump_over_else)
4116 tree last = expr_last (expr);
4117 t = build_and_jump (&end_label);
4118 if (rexpr_has_location (last))
4119 SET_EXPR_LOCATION (t, rexpr_location (last));
4120 append_to_statement_list (t, &expr);
4122 if (emit_false)
4124 t = build1 (LABEL_EXPR, void_type_node, false_label);
4125 append_to_statement_list (t, &expr);
4127 append_to_statement_list (else_, &expr);
4129 if (emit_end && end_label)
4131 t = build1 (LABEL_EXPR, void_type_node, end_label);
4132 append_to_statement_list (t, &expr);
4135 return expr;
4138 /* EXPR is used in a boolean context; make sure it has BOOLEAN_TYPE. */
4140 tree
4141 gimple_boolify (tree expr)
4143 tree type = TREE_TYPE (expr);
4144 location_t loc = EXPR_LOCATION (expr);
4146 if (TREE_CODE (expr) == NE_EXPR
4147 && TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR
4148 && integer_zerop (TREE_OPERAND (expr, 1)))
4150 tree call = TREE_OPERAND (expr, 0);
4151 tree fn = get_callee_fndecl (call);
4153 /* For __builtin_expect ((long) (x), y) recurse into x as well
4154 if x is truth_value_p. */
4155 if (fn
4156 && fndecl_built_in_p (fn, BUILT_IN_EXPECT)
4157 && call_expr_nargs (call) == 2)
4159 tree arg = CALL_EXPR_ARG (call, 0);
4160 if (arg)
4162 if (TREE_CODE (arg) == NOP_EXPR
4163 && TREE_TYPE (arg) == TREE_TYPE (call))
4164 arg = TREE_OPERAND (arg, 0);
4165 if (truth_value_p (TREE_CODE (arg)))
4167 arg = gimple_boolify (arg);
4168 CALL_EXPR_ARG (call, 0)
4169 = fold_convert_loc (loc, TREE_TYPE (call), arg);
4175 switch (TREE_CODE (expr))
4177 case TRUTH_AND_EXPR:
4178 case TRUTH_OR_EXPR:
4179 case TRUTH_XOR_EXPR:
4180 case TRUTH_ANDIF_EXPR:
4181 case TRUTH_ORIF_EXPR:
4182 /* Also boolify the arguments of truth exprs. */
4183 TREE_OPERAND (expr, 1) = gimple_boolify (TREE_OPERAND (expr, 1));
4184 /* FALLTHRU */
4186 case TRUTH_NOT_EXPR:
4187 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
4189 /* These expressions always produce boolean results. */
4190 if (TREE_CODE (type) != BOOLEAN_TYPE)
4191 TREE_TYPE (expr) = boolean_type_node;
4192 return expr;
4194 case ANNOTATE_EXPR:
4195 switch ((enum annot_expr_kind) TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)))
4197 case annot_expr_ivdep_kind:
4198 case annot_expr_unroll_kind:
4199 case annot_expr_no_vector_kind:
4200 case annot_expr_vector_kind:
4201 case annot_expr_parallel_kind:
4202 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
4203 if (TREE_CODE (type) != BOOLEAN_TYPE)
4204 TREE_TYPE (expr) = boolean_type_node;
4205 return expr;
4206 default:
4207 gcc_unreachable ();
4210 default:
4211 if (COMPARISON_CLASS_P (expr))
4213 /* There expressions always prduce boolean results. */
4214 if (TREE_CODE (type) != BOOLEAN_TYPE)
4215 TREE_TYPE (expr) = boolean_type_node;
4216 return expr;
4218 /* Other expressions that get here must have boolean values, but
4219 might need to be converted to the appropriate mode. */
4220 if (TREE_CODE (type) == BOOLEAN_TYPE)
4221 return expr;
4222 return fold_convert_loc (loc, boolean_type_node, expr);
4226 /* Given a conditional expression *EXPR_P without side effects, gimplify
4227 its operands. New statements are inserted to PRE_P. */
4229 static enum gimplify_status
4230 gimplify_pure_cond_expr (tree *expr_p, gimple_seq *pre_p)
4232 tree expr = *expr_p, cond;
4233 enum gimplify_status ret, tret;
4234 enum tree_code code;
4236 cond = gimple_boolify (COND_EXPR_COND (expr));
4238 /* We need to handle && and || specially, as their gimplification
4239 creates pure cond_expr, thus leading to an infinite cycle otherwise. */
4240 code = TREE_CODE (cond);
4241 if (code == TRUTH_ANDIF_EXPR)
4242 TREE_SET_CODE (cond, TRUTH_AND_EXPR);
4243 else if (code == TRUTH_ORIF_EXPR)
4244 TREE_SET_CODE (cond, TRUTH_OR_EXPR);
4245 ret = gimplify_expr (&cond, pre_p, NULL, is_gimple_condexpr, fb_rvalue);
4246 COND_EXPR_COND (*expr_p) = cond;
4248 tret = gimplify_expr (&COND_EXPR_THEN (expr), pre_p, NULL,
4249 is_gimple_val, fb_rvalue);
4250 ret = MIN (ret, tret);
4251 tret = gimplify_expr (&COND_EXPR_ELSE (expr), pre_p, NULL,
4252 is_gimple_val, fb_rvalue);
4254 return MIN (ret, tret);
4257 /* Return true if evaluating EXPR could trap.
4258 EXPR is GENERIC, while tree_could_trap_p can be called
4259 only on GIMPLE. */
4261 bool
4262 generic_expr_could_trap_p (tree expr)
4264 unsigned i, n;
4266 if (!expr || is_gimple_val (expr))
4267 return false;
4269 if (!EXPR_P (expr) || tree_could_trap_p (expr))
4270 return true;
4272 n = TREE_OPERAND_LENGTH (expr);
4273 for (i = 0; i < n; i++)
4274 if (generic_expr_could_trap_p (TREE_OPERAND (expr, i)))
4275 return true;
4277 return false;
4280 /* Convert the conditional expression pointed to by EXPR_P '(p) ? a : b;'
4281 into
4283 if (p) if (p)
4284 t1 = a; a;
4285 else or else
4286 t1 = b; b;
4289 The second form is used when *EXPR_P is of type void.
4291 PRE_P points to the list where side effects that must happen before
4292 *EXPR_P should be stored. */
4294 static enum gimplify_status
4295 gimplify_cond_expr (tree *expr_p, gimple_seq *pre_p, fallback_t fallback)
4297 tree expr = *expr_p;
4298 tree type = TREE_TYPE (expr);
4299 location_t loc = EXPR_LOCATION (expr);
4300 tree tmp, arm1, arm2;
4301 enum gimplify_status ret;
4302 tree label_true, label_false, label_cont;
4303 bool have_then_clause_p, have_else_clause_p;
4304 gcond *cond_stmt;
4305 enum tree_code pred_code;
4306 gimple_seq seq = NULL;
4308 /* If this COND_EXPR has a value, copy the values into a temporary within
4309 the arms. */
4310 if (!VOID_TYPE_P (type))
4312 tree then_ = TREE_OPERAND (expr, 1), else_ = TREE_OPERAND (expr, 2);
4313 tree result;
4315 /* If either an rvalue is ok or we do not require an lvalue, create the
4316 temporary. But we cannot do that if the type is addressable. */
4317 if (((fallback & fb_rvalue) || !(fallback & fb_lvalue))
4318 && !TREE_ADDRESSABLE (type))
4320 if (gimplify_ctxp->allow_rhs_cond_expr
4321 /* If either branch has side effects or could trap, it can't be
4322 evaluated unconditionally. */
4323 && !TREE_SIDE_EFFECTS (then_)
4324 && !generic_expr_could_trap_p (then_)
4325 && !TREE_SIDE_EFFECTS (else_)
4326 && !generic_expr_could_trap_p (else_))
4327 return gimplify_pure_cond_expr (expr_p, pre_p);
4329 tmp = create_tmp_var (type, "iftmp");
4330 result = tmp;
4333 /* Otherwise, only create and copy references to the values. */
4334 else
4336 type = build_pointer_type (type);
4338 if (!VOID_TYPE_P (TREE_TYPE (then_)))
4339 then_ = build_fold_addr_expr_loc (loc, then_);
4341 if (!VOID_TYPE_P (TREE_TYPE (else_)))
4342 else_ = build_fold_addr_expr_loc (loc, else_);
4344 expr
4345 = build3 (COND_EXPR, type, TREE_OPERAND (expr, 0), then_, else_);
4347 tmp = create_tmp_var (type, "iftmp");
4348 result = build_simple_mem_ref_loc (loc, tmp);
4351 /* Build the new then clause, `tmp = then_;'. But don't build the
4352 assignment if the value is void; in C++ it can be if it's a throw. */
4353 if (!VOID_TYPE_P (TREE_TYPE (then_)))
4354 TREE_OPERAND (expr, 1) = build2 (INIT_EXPR, type, tmp, then_);
4356 /* Similarly, build the new else clause, `tmp = else_;'. */
4357 if (!VOID_TYPE_P (TREE_TYPE (else_)))
4358 TREE_OPERAND (expr, 2) = build2 (INIT_EXPR, type, tmp, else_);
4360 TREE_TYPE (expr) = void_type_node;
4361 recalculate_side_effects (expr);
4363 /* Move the COND_EXPR to the prequeue. */
4364 gimplify_stmt (&expr, pre_p);
4366 *expr_p = result;
4367 return GS_ALL_DONE;
4370 /* Remove any COMPOUND_EXPR so the following cases will be caught. */
4371 STRIP_TYPE_NOPS (TREE_OPERAND (expr, 0));
4372 if (TREE_CODE (TREE_OPERAND (expr, 0)) == COMPOUND_EXPR)
4373 gimplify_compound_expr (&TREE_OPERAND (expr, 0), pre_p, true);
4375 /* Make sure the condition has BOOLEAN_TYPE. */
4376 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
4378 /* Break apart && and || conditions. */
4379 if (TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ANDIF_EXPR
4380 || TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ORIF_EXPR)
4382 expr = shortcut_cond_expr (expr);
4384 if (expr != *expr_p)
4386 *expr_p = expr;
4388 /* We can't rely on gimplify_expr to re-gimplify the expanded
4389 form properly, as cleanups might cause the target labels to be
4390 wrapped in a TRY_FINALLY_EXPR. To prevent that, we need to
4391 set up a conditional context. */
4392 gimple_push_condition ();
4393 gimplify_stmt (expr_p, &seq);
4394 gimple_pop_condition (pre_p);
4395 gimple_seq_add_seq (pre_p, seq);
4397 return GS_ALL_DONE;
4401 /* Now do the normal gimplification. */
4403 /* Gimplify condition. */
4404 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL,
4405 is_gimple_condexpr_for_cond, fb_rvalue);
4406 if (ret == GS_ERROR)
4407 return GS_ERROR;
4408 gcc_assert (TREE_OPERAND (expr, 0) != NULL_TREE);
4410 gimple_push_condition ();
4412 have_then_clause_p = have_else_clause_p = false;
4413 label_true = find_goto_label (TREE_OPERAND (expr, 1));
4414 if (label_true
4415 && DECL_CONTEXT (GOTO_DESTINATION (label_true)) == current_function_decl
4416 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4417 have different locations, otherwise we end up with incorrect
4418 location information on the branches. */
4419 && (optimize
4420 || !EXPR_HAS_LOCATION (expr)
4421 || !rexpr_has_location (label_true)
4422 || EXPR_LOCATION (expr) == rexpr_location (label_true)))
4424 have_then_clause_p = true;
4425 label_true = GOTO_DESTINATION (label_true);
4427 else
4428 label_true = create_artificial_label (UNKNOWN_LOCATION);
4429 label_false = find_goto_label (TREE_OPERAND (expr, 2));
4430 if (label_false
4431 && DECL_CONTEXT (GOTO_DESTINATION (label_false)) == current_function_decl
4432 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4433 have different locations, otherwise we end up with incorrect
4434 location information on the branches. */
4435 && (optimize
4436 || !EXPR_HAS_LOCATION (expr)
4437 || !rexpr_has_location (label_false)
4438 || EXPR_LOCATION (expr) == rexpr_location (label_false)))
4440 have_else_clause_p = true;
4441 label_false = GOTO_DESTINATION (label_false);
4443 else
4444 label_false = create_artificial_label (UNKNOWN_LOCATION);
4446 gimple_cond_get_ops_from_tree (COND_EXPR_COND (expr), &pred_code, &arm1,
4447 &arm2);
4448 cond_stmt = gimple_build_cond (pred_code, arm1, arm2, label_true,
4449 label_false);
4450 gimple_set_location (cond_stmt, EXPR_LOCATION (expr));
4451 copy_warning (cond_stmt, COND_EXPR_COND (expr));
4452 gimplify_seq_add_stmt (&seq, cond_stmt);
4453 gimple_stmt_iterator gsi = gsi_last (seq);
4454 maybe_fold_stmt (&gsi);
4456 label_cont = NULL_TREE;
4457 if (!have_then_clause_p)
4459 /* For if (...) {} else { code; } put label_true after
4460 the else block. */
4461 if (TREE_OPERAND (expr, 1) == NULL_TREE
4462 && !have_else_clause_p
4463 && TREE_OPERAND (expr, 2) != NULL_TREE)
4464 label_cont = label_true;
4465 else
4467 gimplify_seq_add_stmt (&seq, gimple_build_label (label_true));
4468 have_then_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 1), &seq);
4469 /* For if (...) { code; } else {} or
4470 if (...) { code; } else goto label; or
4471 if (...) { code; return; } else { ... }
4472 label_cont isn't needed. */
4473 if (!have_else_clause_p
4474 && TREE_OPERAND (expr, 2) != NULL_TREE
4475 && gimple_seq_may_fallthru (seq))
4477 gimple *g;
4478 label_cont = create_artificial_label (UNKNOWN_LOCATION);
4480 g = gimple_build_goto (label_cont);
4482 /* GIMPLE_COND's are very low level; they have embedded
4483 gotos. This particular embedded goto should not be marked
4484 with the location of the original COND_EXPR, as it would
4485 correspond to the COND_EXPR's condition, not the ELSE or the
4486 THEN arms. To avoid marking it with the wrong location, flag
4487 it as "no location". */
4488 gimple_set_do_not_emit_location (g);
4490 gimplify_seq_add_stmt (&seq, g);
4494 if (!have_else_clause_p)
4496 gimplify_seq_add_stmt (&seq, gimple_build_label (label_false));
4497 have_else_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 2), &seq);
4499 if (label_cont)
4500 gimplify_seq_add_stmt (&seq, gimple_build_label (label_cont));
4502 gimple_pop_condition (pre_p);
4503 gimple_seq_add_seq (pre_p, seq);
4505 if (ret == GS_ERROR)
4506 ; /* Do nothing. */
4507 else if (have_then_clause_p || have_else_clause_p)
4508 ret = GS_ALL_DONE;
4509 else
4511 /* Both arms are empty; replace the COND_EXPR with its predicate. */
4512 expr = TREE_OPERAND (expr, 0);
4513 gimplify_stmt (&expr, pre_p);
4516 *expr_p = NULL;
4517 return ret;
4520 /* Prepare the node pointed to by EXPR_P, an is_gimple_addressable expression,
4521 to be marked addressable.
4523 We cannot rely on such an expression being directly markable if a temporary
4524 has been created by the gimplification. In this case, we create another
4525 temporary and initialize it with a copy, which will become a store after we
4526 mark it addressable. This can happen if the front-end passed us something
4527 that it could not mark addressable yet, like a Fortran pass-by-reference
4528 parameter (int) floatvar. */
4530 static void
4531 prepare_gimple_addressable (tree *expr_p, gimple_seq *seq_p)
4533 while (handled_component_p (*expr_p))
4534 expr_p = &TREE_OPERAND (*expr_p, 0);
4535 if (is_gimple_reg (*expr_p))
4537 /* Do not allow an SSA name as the temporary. */
4538 tree var = get_initialized_tmp_var (*expr_p, seq_p, NULL, false);
4539 DECL_NOT_GIMPLE_REG_P (var) = 1;
4540 *expr_p = var;
4544 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4545 a call to __builtin_memcpy. */
4547 static enum gimplify_status
4548 gimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value,
4549 gimple_seq *seq_p)
4551 tree t, to, to_ptr, from, from_ptr;
4552 gcall *gs;
4553 location_t loc = EXPR_LOCATION (*expr_p);
4555 to = TREE_OPERAND (*expr_p, 0);
4556 from = TREE_OPERAND (*expr_p, 1);
4558 /* Mark the RHS addressable. Beware that it may not be possible to do so
4559 directly if a temporary has been created by the gimplification. */
4560 prepare_gimple_addressable (&from, seq_p);
4562 mark_addressable (from);
4563 from_ptr = build_fold_addr_expr_loc (loc, from);
4564 gimplify_arg (&from_ptr, seq_p, loc);
4566 mark_addressable (to);
4567 to_ptr = build_fold_addr_expr_loc (loc, to);
4568 gimplify_arg (&to_ptr, seq_p, loc);
4570 t = builtin_decl_implicit (BUILT_IN_MEMCPY);
4572 gs = gimple_build_call (t, 3, to_ptr, from_ptr, size);
4573 gimple_call_set_alloca_for_var (gs, true);
4575 if (want_value)
4577 /* tmp = memcpy() */
4578 t = create_tmp_var (TREE_TYPE (to_ptr));
4579 gimple_call_set_lhs (gs, t);
4580 gimplify_seq_add_stmt (seq_p, gs);
4582 *expr_p = build_simple_mem_ref (t);
4583 return GS_ALL_DONE;
4586 gimplify_seq_add_stmt (seq_p, gs);
4587 *expr_p = NULL;
4588 return GS_ALL_DONE;
4591 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4592 a call to __builtin_memset. In this case we know that the RHS is
4593 a CONSTRUCTOR with an empty element list. */
4595 static enum gimplify_status
4596 gimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value,
4597 gimple_seq *seq_p)
4599 tree t, from, to, to_ptr;
4600 gcall *gs;
4601 location_t loc = EXPR_LOCATION (*expr_p);
4603 /* Assert our assumptions, to abort instead of producing wrong code
4604 silently if they are not met. Beware that the RHS CONSTRUCTOR might
4605 not be immediately exposed. */
4606 from = TREE_OPERAND (*expr_p, 1);
4607 if (TREE_CODE (from) == WITH_SIZE_EXPR)
4608 from = TREE_OPERAND (from, 0);
4610 gcc_assert (TREE_CODE (from) == CONSTRUCTOR
4611 && vec_safe_is_empty (CONSTRUCTOR_ELTS (from)));
4613 /* Now proceed. */
4614 to = TREE_OPERAND (*expr_p, 0);
4616 to_ptr = build_fold_addr_expr_loc (loc, to);
4617 gimplify_arg (&to_ptr, seq_p, loc);
4618 t = builtin_decl_implicit (BUILT_IN_MEMSET);
4620 gs = gimple_build_call (t, 3, to_ptr, integer_zero_node, size);
4622 if (want_value)
4624 /* tmp = memset() */
4625 t = create_tmp_var (TREE_TYPE (to_ptr));
4626 gimple_call_set_lhs (gs, t);
4627 gimplify_seq_add_stmt (seq_p, gs);
4629 *expr_p = build1 (INDIRECT_REF, TREE_TYPE (to), t);
4630 return GS_ALL_DONE;
4633 gimplify_seq_add_stmt (seq_p, gs);
4634 *expr_p = NULL;
4635 return GS_ALL_DONE;
4638 /* A subroutine of gimplify_init_ctor_preeval. Called via walk_tree,
4639 determine, cautiously, if a CONSTRUCTOR overlaps the lhs of an
4640 assignment. Return non-null if we detect a potential overlap. */
4642 struct gimplify_init_ctor_preeval_data
4644 /* The base decl of the lhs object. May be NULL, in which case we
4645 have to assume the lhs is indirect. */
4646 tree lhs_base_decl;
4648 /* The alias set of the lhs object. */
4649 alias_set_type lhs_alias_set;
4652 static tree
4653 gimplify_init_ctor_preeval_1 (tree *tp, int *walk_subtrees, void *xdata)
4655 struct gimplify_init_ctor_preeval_data *data
4656 = (struct gimplify_init_ctor_preeval_data *) xdata;
4657 tree t = *tp;
4659 /* If we find the base object, obviously we have overlap. */
4660 if (data->lhs_base_decl == t)
4661 return t;
4663 /* If the constructor component is indirect, determine if we have a
4664 potential overlap with the lhs. The only bits of information we
4665 have to go on at this point are addressability and alias sets. */
4666 if ((INDIRECT_REF_P (t)
4667 || TREE_CODE (t) == MEM_REF)
4668 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
4669 && alias_sets_conflict_p (data->lhs_alias_set, get_alias_set (t)))
4670 return t;
4672 /* If the constructor component is a call, determine if it can hide a
4673 potential overlap with the lhs through an INDIRECT_REF like above.
4674 ??? Ugh - this is completely broken. In fact this whole analysis
4675 doesn't look conservative. */
4676 if (TREE_CODE (t) == CALL_EXPR)
4678 tree type, fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (t)));
4680 for (type = TYPE_ARG_TYPES (fntype); type; type = TREE_CHAIN (type))
4681 if (POINTER_TYPE_P (TREE_VALUE (type))
4682 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
4683 && alias_sets_conflict_p (data->lhs_alias_set,
4684 get_alias_set
4685 (TREE_TYPE (TREE_VALUE (type)))))
4686 return t;
4689 if (IS_TYPE_OR_DECL_P (t))
4690 *walk_subtrees = 0;
4691 return NULL;
4694 /* A subroutine of gimplify_init_constructor. Pre-evaluate EXPR,
4695 force values that overlap with the lhs (as described by *DATA)
4696 into temporaries. */
4698 static void
4699 gimplify_init_ctor_preeval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
4700 struct gimplify_init_ctor_preeval_data *data)
4702 enum gimplify_status one;
4704 /* If the value is constant, then there's nothing to pre-evaluate. */
4705 if (TREE_CONSTANT (*expr_p))
4707 /* Ensure it does not have side effects, it might contain a reference to
4708 the object we're initializing. */
4709 gcc_assert (!TREE_SIDE_EFFECTS (*expr_p));
4710 return;
4713 /* If the type has non-trivial constructors, we can't pre-evaluate. */
4714 if (TREE_ADDRESSABLE (TREE_TYPE (*expr_p)))
4715 return;
4717 /* Recurse for nested constructors. */
4718 if (TREE_CODE (*expr_p) == CONSTRUCTOR)
4720 unsigned HOST_WIDE_INT ix;
4721 constructor_elt *ce;
4722 vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (*expr_p);
4724 FOR_EACH_VEC_SAFE_ELT (v, ix, ce)
4725 gimplify_init_ctor_preeval (&ce->value, pre_p, post_p, data);
4727 return;
4730 /* If this is a variable sized type, we must remember the size. */
4731 maybe_with_size_expr (expr_p);
4733 /* Gimplify the constructor element to something appropriate for the rhs
4734 of a MODIFY_EXPR. Given that we know the LHS is an aggregate, we know
4735 the gimplifier will consider this a store to memory. Doing this
4736 gimplification now means that we won't have to deal with complicated
4737 language-specific trees, nor trees like SAVE_EXPR that can induce
4738 exponential search behavior. */
4739 one = gimplify_expr (expr_p, pre_p, post_p, is_gimple_mem_rhs, fb_rvalue);
4740 if (one == GS_ERROR)
4742 *expr_p = NULL;
4743 return;
4746 /* If we gimplified to a bare decl, we can be sure that it doesn't overlap
4747 with the lhs, since "a = { .x=a }" doesn't make sense. This will
4748 always be true for all scalars, since is_gimple_mem_rhs insists on a
4749 temporary variable for them. */
4750 if (DECL_P (*expr_p))
4751 return;
4753 /* If this is of variable size, we have no choice but to assume it doesn't
4754 overlap since we can't make a temporary for it. */
4755 if (TREE_CODE (TYPE_SIZE (TREE_TYPE (*expr_p))) != INTEGER_CST)
4756 return;
4758 /* Otherwise, we must search for overlap ... */
4759 if (!walk_tree (expr_p, gimplify_init_ctor_preeval_1, data, NULL))
4760 return;
4762 /* ... and if found, force the value into a temporary. */
4763 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
4766 /* A subroutine of gimplify_init_ctor_eval. Create a loop for
4767 a RANGE_EXPR in a CONSTRUCTOR for an array.
4769 var = lower;
4770 loop_entry:
4771 object[var] = value;
4772 if (var == upper)
4773 goto loop_exit;
4774 var = var + 1;
4775 goto loop_entry;
4776 loop_exit:
4778 We increment var _after_ the loop exit check because we might otherwise
4779 fail if upper == TYPE_MAX_VALUE (type for upper).
4781 Note that we never have to deal with SAVE_EXPRs here, because this has
4782 already been taken care of for us, in gimplify_init_ctor_preeval(). */
4784 static void gimplify_init_ctor_eval (tree, vec<constructor_elt, va_gc> *,
4785 gimple_seq *, bool);
4787 static void
4788 gimplify_init_ctor_eval_range (tree object, tree lower, tree upper,
4789 tree value, tree array_elt_type,
4790 gimple_seq *pre_p, bool cleared)
4792 tree loop_entry_label, loop_exit_label, fall_thru_label;
4793 tree var, var_type, cref, tmp;
4795 loop_entry_label = create_artificial_label (UNKNOWN_LOCATION);
4796 loop_exit_label = create_artificial_label (UNKNOWN_LOCATION);
4797 fall_thru_label = create_artificial_label (UNKNOWN_LOCATION);
4799 /* Create and initialize the index variable. */
4800 var_type = TREE_TYPE (upper);
4801 var = create_tmp_var (var_type);
4802 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, lower));
4804 /* Add the loop entry label. */
4805 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_entry_label));
4807 /* Build the reference. */
4808 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
4809 var, NULL_TREE, NULL_TREE);
4811 /* If we are a constructor, just call gimplify_init_ctor_eval to do
4812 the store. Otherwise just assign value to the reference. */
4814 if (TREE_CODE (value) == CONSTRUCTOR)
4815 /* NB we might have to call ourself recursively through
4816 gimplify_init_ctor_eval if the value is a constructor. */
4817 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
4818 pre_p, cleared);
4819 else
4821 if (gimplify_expr (&value, pre_p, NULL, is_gimple_val, fb_rvalue)
4822 != GS_ERROR)
4823 gimplify_seq_add_stmt (pre_p, gimple_build_assign (cref, value));
4826 /* We exit the loop when the index var is equal to the upper bound. */
4827 gimplify_seq_add_stmt (pre_p,
4828 gimple_build_cond (EQ_EXPR, var, upper,
4829 loop_exit_label, fall_thru_label));
4831 gimplify_seq_add_stmt (pre_p, gimple_build_label (fall_thru_label));
4833 /* Otherwise, increment the index var... */
4834 tmp = build2 (PLUS_EXPR, var_type, var,
4835 fold_convert (var_type, integer_one_node));
4836 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, tmp));
4838 /* ...and jump back to the loop entry. */
4839 gimplify_seq_add_stmt (pre_p, gimple_build_goto (loop_entry_label));
4841 /* Add the loop exit label. */
4842 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_exit_label));
4845 /* A subroutine of gimplify_init_constructor. Generate individual
4846 MODIFY_EXPRs for a CONSTRUCTOR. OBJECT is the LHS against which the
4847 assignments should happen. ELTS is the CONSTRUCTOR_ELTS of the
4848 CONSTRUCTOR. CLEARED is true if the entire LHS object has been
4849 zeroed first. */
4851 static void
4852 gimplify_init_ctor_eval (tree object, vec<constructor_elt, va_gc> *elts,
4853 gimple_seq *pre_p, bool cleared)
4855 tree array_elt_type = NULL;
4856 unsigned HOST_WIDE_INT ix;
4857 tree purpose, value;
4859 if (TREE_CODE (TREE_TYPE (object)) == ARRAY_TYPE)
4860 array_elt_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (object)));
4862 FOR_EACH_CONSTRUCTOR_ELT (elts, ix, purpose, value)
4864 tree cref;
4866 /* NULL values are created above for gimplification errors. */
4867 if (value == NULL)
4868 continue;
4870 if (cleared && initializer_zerop (value))
4871 continue;
4873 /* ??? Here's to hoping the front end fills in all of the indices,
4874 so we don't have to figure out what's missing ourselves. */
4875 gcc_assert (purpose);
4877 /* Skip zero-sized fields, unless value has side-effects. This can
4878 happen with calls to functions returning a empty type, which
4879 we shouldn't discard. As a number of downstream passes don't
4880 expect sets of empty type fields, we rely on the gimplification of
4881 the MODIFY_EXPR we make below to drop the assignment statement. */
4882 if (!TREE_SIDE_EFFECTS (value)
4883 && TREE_CODE (purpose) == FIELD_DECL
4884 && is_empty_type (TREE_TYPE (purpose)))
4885 continue;
4887 /* If we have a RANGE_EXPR, we have to build a loop to assign the
4888 whole range. */
4889 if (TREE_CODE (purpose) == RANGE_EXPR)
4891 tree lower = TREE_OPERAND (purpose, 0);
4892 tree upper = TREE_OPERAND (purpose, 1);
4894 /* If the lower bound is equal to upper, just treat it as if
4895 upper was the index. */
4896 if (simple_cst_equal (lower, upper))
4897 purpose = upper;
4898 else
4900 gimplify_init_ctor_eval_range (object, lower, upper, value,
4901 array_elt_type, pre_p, cleared);
4902 continue;
4906 if (array_elt_type)
4908 /* Do not use bitsizetype for ARRAY_REF indices. */
4909 if (TYPE_DOMAIN (TREE_TYPE (object)))
4910 purpose
4911 = fold_convert (TREE_TYPE (TYPE_DOMAIN (TREE_TYPE (object))),
4912 purpose);
4913 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
4914 purpose, NULL_TREE, NULL_TREE);
4916 else
4918 gcc_assert (TREE_CODE (purpose) == FIELD_DECL);
4919 cref = build3 (COMPONENT_REF, TREE_TYPE (purpose),
4920 unshare_expr (object), purpose, NULL_TREE);
4923 if (TREE_CODE (value) == CONSTRUCTOR
4924 && TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE)
4925 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
4926 pre_p, cleared);
4927 else
4929 tree init = build2 (INIT_EXPR, TREE_TYPE (cref), cref, value);
4930 gimplify_and_add (init, pre_p);
4931 ggc_free (init);
4936 /* Return the appropriate RHS predicate for this LHS. */
4938 gimple_predicate
4939 rhs_predicate_for (tree lhs)
4941 if (is_gimple_reg (lhs))
4942 return is_gimple_reg_rhs_or_call;
4943 else
4944 return is_gimple_mem_rhs_or_call;
4947 /* Return the initial guess for an appropriate RHS predicate for this LHS,
4948 before the LHS has been gimplified. */
4950 static gimple_predicate
4951 initial_rhs_predicate_for (tree lhs)
4953 if (is_gimple_reg_type (TREE_TYPE (lhs)))
4954 return is_gimple_reg_rhs_or_call;
4955 else
4956 return is_gimple_mem_rhs_or_call;
4959 /* Gimplify a C99 compound literal expression. This just means adding
4960 the DECL_EXPR before the current statement and using its anonymous
4961 decl instead. */
4963 static enum gimplify_status
4964 gimplify_compound_literal_expr (tree *expr_p, gimple_seq *pre_p,
4965 bool (*gimple_test_f) (tree),
4966 fallback_t fallback)
4968 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (*expr_p);
4969 tree decl = DECL_EXPR_DECL (decl_s);
4970 tree init = DECL_INITIAL (decl);
4971 /* Mark the decl as addressable if the compound literal
4972 expression is addressable now, otherwise it is marked too late
4973 after we gimplify the initialization expression. */
4974 if (TREE_ADDRESSABLE (*expr_p))
4975 TREE_ADDRESSABLE (decl) = 1;
4976 /* Otherwise, if we don't need an lvalue and have a literal directly
4977 substitute it. Check if it matches the gimple predicate, as
4978 otherwise we'd generate a new temporary, and we can as well just
4979 use the decl we already have. */
4980 else if (!TREE_ADDRESSABLE (decl)
4981 && !TREE_THIS_VOLATILE (decl)
4982 && init
4983 && (fallback & fb_lvalue) == 0
4984 && gimple_test_f (init))
4986 *expr_p = init;
4987 return GS_OK;
4990 /* If the decl is not addressable, then it is being used in some
4991 expression or on the right hand side of a statement, and it can
4992 be put into a readonly data section. */
4993 if (!TREE_ADDRESSABLE (decl) && (fallback & fb_lvalue) == 0)
4994 TREE_READONLY (decl) = 1;
4996 /* This decl isn't mentioned in the enclosing block, so add it to the
4997 list of temps. FIXME it seems a bit of a kludge to say that
4998 anonymous artificial vars aren't pushed, but everything else is. */
4999 if (DECL_NAME (decl) == NULL_TREE && !DECL_SEEN_IN_BIND_EXPR_P (decl))
5000 gimple_add_tmp_var (decl);
5002 gimplify_and_add (decl_s, pre_p);
5003 *expr_p = decl;
5004 return GS_OK;
5007 /* Optimize embedded COMPOUND_LITERAL_EXPRs within a CONSTRUCTOR,
5008 return a new CONSTRUCTOR if something changed. */
5010 static tree
5011 optimize_compound_literals_in_ctor (tree orig_ctor)
5013 tree ctor = orig_ctor;
5014 vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ctor);
5015 unsigned int idx, num = vec_safe_length (elts);
5017 for (idx = 0; idx < num; idx++)
5019 tree value = (*elts)[idx].value;
5020 tree newval = value;
5021 if (TREE_CODE (value) == CONSTRUCTOR)
5022 newval = optimize_compound_literals_in_ctor (value);
5023 else if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR)
5025 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (value);
5026 tree decl = DECL_EXPR_DECL (decl_s);
5027 tree init = DECL_INITIAL (decl);
5029 if (!TREE_ADDRESSABLE (value)
5030 && !TREE_ADDRESSABLE (decl)
5031 && init
5032 && TREE_CODE (init) == CONSTRUCTOR)
5033 newval = optimize_compound_literals_in_ctor (init);
5035 if (newval == value)
5036 continue;
5038 if (ctor == orig_ctor)
5040 ctor = copy_node (orig_ctor);
5041 CONSTRUCTOR_ELTS (ctor) = vec_safe_copy (elts);
5042 elts = CONSTRUCTOR_ELTS (ctor);
5044 (*elts)[idx].value = newval;
5046 return ctor;
5049 /* A subroutine of gimplify_modify_expr. Break out elements of a
5050 CONSTRUCTOR used as an initializer into separate MODIFY_EXPRs.
5052 Note that we still need to clear any elements that don't have explicit
5053 initializers, so if not all elements are initialized we keep the
5054 original MODIFY_EXPR, we just remove all of the constructor elements.
5056 If NOTIFY_TEMP_CREATION is true, do not gimplify, just return
5057 GS_ERROR if we would have to create a temporary when gimplifying
5058 this constructor. Otherwise, return GS_OK.
5060 If NOTIFY_TEMP_CREATION is false, just do the gimplification. */
5062 static enum gimplify_status
5063 gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
5064 bool want_value, bool notify_temp_creation)
5066 tree object, ctor, type;
5067 enum gimplify_status ret;
5068 vec<constructor_elt, va_gc> *elts;
5069 bool cleared = false;
5070 bool is_empty_ctor = false;
5071 bool is_init_expr = (TREE_CODE (*expr_p) == INIT_EXPR);
5073 gcc_assert (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == CONSTRUCTOR);
5075 if (!notify_temp_creation)
5077 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
5078 is_gimple_lvalue, fb_lvalue);
5079 if (ret == GS_ERROR)
5080 return ret;
5083 object = TREE_OPERAND (*expr_p, 0);
5084 ctor = TREE_OPERAND (*expr_p, 1)
5085 = optimize_compound_literals_in_ctor (TREE_OPERAND (*expr_p, 1));
5086 type = TREE_TYPE (ctor);
5087 elts = CONSTRUCTOR_ELTS (ctor);
5088 ret = GS_ALL_DONE;
5090 switch (TREE_CODE (type))
5092 case RECORD_TYPE:
5093 case UNION_TYPE:
5094 case QUAL_UNION_TYPE:
5095 case ARRAY_TYPE:
5097 /* Use readonly data for initializers of this or smaller size
5098 regardless of the num_nonzero_elements / num_unique_nonzero_elements
5099 ratio. */
5100 const HOST_WIDE_INT min_unique_size = 64;
5101 /* If num_nonzero_elements / num_unique_nonzero_elements ratio
5102 is smaller than this, use readonly data. */
5103 const int unique_nonzero_ratio = 8;
5104 /* True if a single access of the object must be ensured. This is the
5105 case if the target is volatile, the type is non-addressable and more
5106 than one field need to be assigned. */
5107 const bool ensure_single_access
5108 = TREE_THIS_VOLATILE (object)
5109 && !TREE_ADDRESSABLE (type)
5110 && vec_safe_length (elts) > 1;
5111 struct gimplify_init_ctor_preeval_data preeval_data;
5112 HOST_WIDE_INT num_ctor_elements, num_nonzero_elements;
5113 HOST_WIDE_INT num_unique_nonzero_elements;
5114 bool complete_p, valid_const_initializer;
5116 /* Aggregate types must lower constructors to initialization of
5117 individual elements. The exception is that a CONSTRUCTOR node
5118 with no elements indicates zero-initialization of the whole. */
5119 if (vec_safe_is_empty (elts))
5121 if (notify_temp_creation)
5122 return GS_OK;
5124 /* The var will be initialized and so appear on lhs of
5125 assignment, it can't be TREE_READONLY anymore. */
5126 if (VAR_P (object))
5127 TREE_READONLY (object) = 0;
5129 is_empty_ctor = true;
5130 break;
5133 /* Fetch information about the constructor to direct later processing.
5134 We might want to make static versions of it in various cases, and
5135 can only do so if it known to be a valid constant initializer. */
5136 valid_const_initializer
5137 = categorize_ctor_elements (ctor, &num_nonzero_elements,
5138 &num_unique_nonzero_elements,
5139 &num_ctor_elements, &complete_p);
5141 /* If a const aggregate variable is being initialized, then it
5142 should never be a lose to promote the variable to be static. */
5143 if (valid_const_initializer
5144 && num_nonzero_elements > 1
5145 && TREE_READONLY (object)
5146 && VAR_P (object)
5147 && !DECL_REGISTER (object)
5148 && (flag_merge_constants >= 2 || !TREE_ADDRESSABLE (object))
5149 /* For ctors that have many repeated nonzero elements
5150 represented through RANGE_EXPRs, prefer initializing
5151 those through runtime loops over copies of large amounts
5152 of data from readonly data section. */
5153 && (num_unique_nonzero_elements
5154 > num_nonzero_elements / unique_nonzero_ratio
5155 || ((unsigned HOST_WIDE_INT) int_size_in_bytes (type)
5156 <= (unsigned HOST_WIDE_INT) min_unique_size)))
5158 if (notify_temp_creation)
5159 return GS_ERROR;
5161 DECL_INITIAL (object) = ctor;
5162 TREE_STATIC (object) = 1;
5163 if (!DECL_NAME (object))
5164 DECL_NAME (object) = create_tmp_var_name ("C");
5165 walk_tree (&DECL_INITIAL (object), force_labels_r, NULL, NULL);
5167 /* ??? C++ doesn't automatically append a .<number> to the
5168 assembler name, and even when it does, it looks at FE private
5169 data structures to figure out what that number should be,
5170 which are not set for this variable. I suppose this is
5171 important for local statics for inline functions, which aren't
5172 "local" in the object file sense. So in order to get a unique
5173 TU-local symbol, we must invoke the lhd version now. */
5174 lhd_set_decl_assembler_name (object);
5176 *expr_p = NULL_TREE;
5177 break;
5180 /* The var will be initialized and so appear on lhs of
5181 assignment, it can't be TREE_READONLY anymore. */
5182 if (VAR_P (object) && !notify_temp_creation)
5183 TREE_READONLY (object) = 0;
5185 /* If there are "lots" of initialized elements, even discounting
5186 those that are not address constants (and thus *must* be
5187 computed at runtime), then partition the constructor into
5188 constant and non-constant parts. Block copy the constant
5189 parts in, then generate code for the non-constant parts. */
5190 /* TODO. There's code in cp/typeck.cc to do this. */
5192 if (int_size_in_bytes (TREE_TYPE (ctor)) < 0)
5193 /* store_constructor will ignore the clearing of variable-sized
5194 objects. Initializers for such objects must explicitly set
5195 every field that needs to be set. */
5196 cleared = false;
5197 else if (!complete_p)
5198 /* If the constructor isn't complete, clear the whole object
5199 beforehand, unless CONSTRUCTOR_NO_CLEARING is set on it.
5201 ??? This ought not to be needed. For any element not present
5202 in the initializer, we should simply set them to zero. Except
5203 we'd need to *find* the elements that are not present, and that
5204 requires trickery to avoid quadratic compile-time behavior in
5205 large cases or excessive memory use in small cases. */
5206 cleared = !CONSTRUCTOR_NO_CLEARING (ctor);
5207 else if (num_ctor_elements - num_nonzero_elements
5208 > CLEAR_RATIO (optimize_function_for_speed_p (cfun))
5209 && num_nonzero_elements < num_ctor_elements / 4)
5210 /* If there are "lots" of zeros, it's more efficient to clear
5211 the memory and then set the nonzero elements. */
5212 cleared = true;
5213 else if (ensure_single_access && num_nonzero_elements == 0)
5214 /* If a single access to the target must be ensured and all elements
5215 are zero, then it's optimal to clear whatever their number. */
5216 cleared = true;
5217 else
5218 cleared = false;
5220 /* If there are "lots" of initialized elements, and all of them
5221 are valid address constants, then the entire initializer can
5222 be dropped to memory, and then memcpy'd out. Don't do this
5223 for sparse arrays, though, as it's more efficient to follow
5224 the standard CONSTRUCTOR behavior of memset followed by
5225 individual element initialization. Also don't do this for small
5226 all-zero initializers (which aren't big enough to merit
5227 clearing), and don't try to make bitwise copies of
5228 TREE_ADDRESSABLE types. */
5229 if (valid_const_initializer
5230 && complete_p
5231 && !(cleared || num_nonzero_elements == 0)
5232 && !TREE_ADDRESSABLE (type))
5234 HOST_WIDE_INT size = int_size_in_bytes (type);
5235 unsigned int align;
5237 /* ??? We can still get unbounded array types, at least
5238 from the C++ front end. This seems wrong, but attempt
5239 to work around it for now. */
5240 if (size < 0)
5242 size = int_size_in_bytes (TREE_TYPE (object));
5243 if (size >= 0)
5244 TREE_TYPE (ctor) = type = TREE_TYPE (object);
5247 /* Find the maximum alignment we can assume for the object. */
5248 /* ??? Make use of DECL_OFFSET_ALIGN. */
5249 if (DECL_P (object))
5250 align = DECL_ALIGN (object);
5251 else
5252 align = TYPE_ALIGN (type);
5254 /* Do a block move either if the size is so small as to make
5255 each individual move a sub-unit move on average, or if it
5256 is so large as to make individual moves inefficient. */
5257 if (size > 0
5258 && num_nonzero_elements > 1
5259 /* For ctors that have many repeated nonzero elements
5260 represented through RANGE_EXPRs, prefer initializing
5261 those through runtime loops over copies of large amounts
5262 of data from readonly data section. */
5263 && (num_unique_nonzero_elements
5264 > num_nonzero_elements / unique_nonzero_ratio
5265 || size <= min_unique_size)
5266 && (size < num_nonzero_elements
5267 || !can_move_by_pieces (size, align)))
5269 if (notify_temp_creation)
5270 return GS_ERROR;
5272 walk_tree (&ctor, force_labels_r, NULL, NULL);
5273 ctor = tree_output_constant_def (ctor);
5274 if (!useless_type_conversion_p (type, TREE_TYPE (ctor)))
5275 ctor = build1 (VIEW_CONVERT_EXPR, type, ctor);
5276 TREE_OPERAND (*expr_p, 1) = ctor;
5278 /* This is no longer an assignment of a CONSTRUCTOR, but
5279 we still may have processing to do on the LHS. So
5280 pretend we didn't do anything here to let that happen. */
5281 return GS_UNHANDLED;
5285 /* If a single access to the target must be ensured and there are
5286 nonzero elements or the zero elements are not assigned en masse,
5287 initialize the target from a temporary. */
5288 if (ensure_single_access && (num_nonzero_elements > 0 || !cleared))
5290 if (notify_temp_creation)
5291 return GS_ERROR;
5293 tree temp = create_tmp_var (TYPE_MAIN_VARIANT (type));
5294 TREE_OPERAND (*expr_p, 0) = temp;
5295 *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p),
5296 *expr_p,
5297 build2 (MODIFY_EXPR, void_type_node,
5298 object, temp));
5299 return GS_OK;
5302 if (notify_temp_creation)
5303 return GS_OK;
5305 /* If there are nonzero elements and if needed, pre-evaluate to capture
5306 elements overlapping with the lhs into temporaries. We must do this
5307 before clearing to fetch the values before they are zeroed-out. */
5308 if (num_nonzero_elements > 0 && TREE_CODE (*expr_p) != INIT_EXPR)
5310 preeval_data.lhs_base_decl = get_base_address (object);
5311 if (!DECL_P (preeval_data.lhs_base_decl))
5312 preeval_data.lhs_base_decl = NULL;
5313 preeval_data.lhs_alias_set = get_alias_set (object);
5315 gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p, 1),
5316 pre_p, post_p, &preeval_data);
5319 bool ctor_has_side_effects_p
5320 = TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p, 1));
5322 if (cleared)
5324 /* Zap the CONSTRUCTOR element list, which simplifies this case.
5325 Note that we still have to gimplify, in order to handle the
5326 case of variable sized types. Avoid shared tree structures. */
5327 CONSTRUCTOR_ELTS (ctor) = NULL;
5328 TREE_SIDE_EFFECTS (ctor) = 0;
5329 object = unshare_expr (object);
5330 gimplify_stmt (expr_p, pre_p);
5333 /* If we have not block cleared the object, or if there are nonzero
5334 elements in the constructor, or if the constructor has side effects,
5335 add assignments to the individual scalar fields of the object. */
5336 if (!cleared
5337 || num_nonzero_elements > 0
5338 || ctor_has_side_effects_p)
5339 gimplify_init_ctor_eval (object, elts, pre_p, cleared);
5341 *expr_p = NULL_TREE;
5343 break;
5345 case COMPLEX_TYPE:
5347 tree r, i;
5349 if (notify_temp_creation)
5350 return GS_OK;
5352 /* Extract the real and imaginary parts out of the ctor. */
5353 gcc_assert (elts->length () == 2);
5354 r = (*elts)[0].value;
5355 i = (*elts)[1].value;
5356 if (r == NULL || i == NULL)
5358 tree zero = build_zero_cst (TREE_TYPE (type));
5359 if (r == NULL)
5360 r = zero;
5361 if (i == NULL)
5362 i = zero;
5365 /* Complex types have either COMPLEX_CST or COMPLEX_EXPR to
5366 represent creation of a complex value. */
5367 if (TREE_CONSTANT (r) && TREE_CONSTANT (i))
5369 ctor = build_complex (type, r, i);
5370 TREE_OPERAND (*expr_p, 1) = ctor;
5372 else
5374 ctor = build2 (COMPLEX_EXPR, type, r, i);
5375 TREE_OPERAND (*expr_p, 1) = ctor;
5376 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 1),
5377 pre_p,
5378 post_p,
5379 rhs_predicate_for (TREE_OPERAND (*expr_p, 0)),
5380 fb_rvalue);
5383 break;
5385 case VECTOR_TYPE:
5387 unsigned HOST_WIDE_INT ix;
5388 constructor_elt *ce;
5390 if (notify_temp_creation)
5391 return GS_OK;
5393 /* Go ahead and simplify constant constructors to VECTOR_CST. */
5394 if (TREE_CONSTANT (ctor))
5396 bool constant_p = true;
5397 tree value;
5399 /* Even when ctor is constant, it might contain non-*_CST
5400 elements, such as addresses or trapping values like
5401 1.0/0.0 - 1.0/0.0. Such expressions don't belong
5402 in VECTOR_CST nodes. */
5403 FOR_EACH_CONSTRUCTOR_VALUE (elts, ix, value)
5404 if (!CONSTANT_CLASS_P (value))
5406 constant_p = false;
5407 break;
5410 if (constant_p)
5412 TREE_OPERAND (*expr_p, 1) = build_vector_from_ctor (type, elts);
5413 break;
5416 TREE_CONSTANT (ctor) = 0;
5419 /* Vector types use CONSTRUCTOR all the way through gimple
5420 compilation as a general initializer. */
5421 FOR_EACH_VEC_SAFE_ELT (elts, ix, ce)
5423 enum gimplify_status tret;
5424 tret = gimplify_expr (&ce->value, pre_p, post_p, is_gimple_val,
5425 fb_rvalue);
5426 if (tret == GS_ERROR)
5427 ret = GS_ERROR;
5428 else if (TREE_STATIC (ctor)
5429 && !initializer_constant_valid_p (ce->value,
5430 TREE_TYPE (ce->value)))
5431 TREE_STATIC (ctor) = 0;
5433 recompute_constructor_flags (ctor);
5434 if (!is_gimple_reg (TREE_OPERAND (*expr_p, 0)))
5435 TREE_OPERAND (*expr_p, 1) = get_formal_tmp_var (ctor, pre_p);
5437 break;
5439 default:
5440 /* So how did we get a CONSTRUCTOR for a scalar type? */
5441 gcc_unreachable ();
5444 if (ret == GS_ERROR)
5445 return GS_ERROR;
5446 /* If we have gimplified both sides of the initializer but have
5447 not emitted an assignment, do so now. */
5448 if (*expr_p)
5450 tree lhs = TREE_OPERAND (*expr_p, 0);
5451 tree rhs = TREE_OPERAND (*expr_p, 1);
5452 if (want_value && object == lhs)
5453 lhs = unshare_expr (lhs);
5454 gassign *init = gimple_build_assign (lhs, rhs);
5455 gimplify_seq_add_stmt (pre_p, init);
5457 if (want_value)
5459 *expr_p = object;
5460 ret = GS_OK;
5462 else
5464 *expr_p = NULL;
5465 ret = GS_ALL_DONE;
5468 /* If the user requests to initialize automatic variables, we
5469 should initialize paddings inside the variable. Add a call to
5470 __builtin_clear_pading (&object, 0, for_auto_init = true) to
5471 initialize paddings of object always to zero regardless of
5472 INIT_TYPE. Note, we will not insert this call if the aggregate
5473 variable has be completely cleared already or it's initialized
5474 with an empty constructor. We cannot insert this call if the
5475 variable is a gimple register since __builtin_clear_padding will take
5476 the address of the variable. As a result, if a long double/_Complex long
5477 double variable will be spilled into stack later, its padding cannot
5478 be cleared with __builtin_clear_padding. We should clear its padding
5479 when it is spilled into memory. */
5480 if (is_init_expr
5481 && !is_gimple_reg (object)
5482 && clear_padding_type_may_have_padding_p (type)
5483 && ((AGGREGATE_TYPE_P (type) && !cleared && !is_empty_ctor)
5484 || !AGGREGATE_TYPE_P (type))
5485 && is_var_need_auto_init (object))
5486 gimple_add_padding_init_for_auto_var (object, false, pre_p);
5488 return ret;
5491 /* Given a pointer value OP0, return a simplified version of an
5492 indirection through OP0, or NULL_TREE if no simplification is
5493 possible. This may only be applied to a rhs of an expression.
5494 Note that the resulting type may be different from the type pointed
5495 to in the sense that it is still compatible from the langhooks
5496 point of view. */
5498 static tree
5499 gimple_fold_indirect_ref_rhs (tree t)
5501 return gimple_fold_indirect_ref (t);
5504 /* Subroutine of gimplify_modify_expr to do simplifications of
5505 MODIFY_EXPRs based on the code of the RHS. We loop for as long as
5506 something changes. */
5508 static enum gimplify_status
5509 gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p,
5510 gimple_seq *pre_p, gimple_seq *post_p,
5511 bool want_value)
5513 enum gimplify_status ret = GS_UNHANDLED;
5514 bool changed;
5518 changed = false;
5519 switch (TREE_CODE (*from_p))
5521 case VAR_DECL:
5522 /* If we're assigning from a read-only variable initialized with
5523 a constructor and not volatile, do the direct assignment from
5524 the constructor, but only if the target is not volatile either
5525 since this latter assignment might end up being done on a per
5526 field basis. However, if the target is volatile and the type
5527 is aggregate and non-addressable, gimplify_init_constructor
5528 knows that it needs to ensure a single access to the target
5529 and it will return GS_OK only in this case. */
5530 if (TREE_READONLY (*from_p)
5531 && DECL_INITIAL (*from_p)
5532 && TREE_CODE (DECL_INITIAL (*from_p)) == CONSTRUCTOR
5533 && !TREE_THIS_VOLATILE (*from_p)
5534 && (!TREE_THIS_VOLATILE (*to_p)
5535 || (AGGREGATE_TYPE_P (TREE_TYPE (*to_p))
5536 && !TREE_ADDRESSABLE (TREE_TYPE (*to_p)))))
5538 tree old_from = *from_p;
5539 enum gimplify_status subret;
5541 /* Move the constructor into the RHS. */
5542 *from_p = unshare_expr (DECL_INITIAL (*from_p));
5544 /* Let's see if gimplify_init_constructor will need to put
5545 it in memory. */
5546 subret = gimplify_init_constructor (expr_p, NULL, NULL,
5547 false, true);
5548 if (subret == GS_ERROR)
5550 /* If so, revert the change. */
5551 *from_p = old_from;
5553 else
5555 ret = GS_OK;
5556 changed = true;
5559 break;
5560 case INDIRECT_REF:
5562 /* If we have code like
5564 *(const A*)(A*)&x
5566 where the type of "x" is a (possibly cv-qualified variant
5567 of "A"), treat the entire expression as identical to "x".
5568 This kind of code arises in C++ when an object is bound
5569 to a const reference, and if "x" is a TARGET_EXPR we want
5570 to take advantage of the optimization below. */
5571 bool volatile_p = TREE_THIS_VOLATILE (*from_p);
5572 tree t = gimple_fold_indirect_ref_rhs (TREE_OPERAND (*from_p, 0));
5573 if (t)
5575 if (TREE_THIS_VOLATILE (t) != volatile_p)
5577 if (DECL_P (t))
5578 t = build_simple_mem_ref_loc (EXPR_LOCATION (*from_p),
5579 build_fold_addr_expr (t));
5580 if (REFERENCE_CLASS_P (t))
5581 TREE_THIS_VOLATILE (t) = volatile_p;
5583 *from_p = t;
5584 ret = GS_OK;
5585 changed = true;
5587 break;
5590 case TARGET_EXPR:
5592 /* If we are initializing something from a TARGET_EXPR, strip the
5593 TARGET_EXPR and initialize it directly, if possible. This can't
5594 be done if the initializer is void, since that implies that the
5595 temporary is set in some non-trivial way.
5597 ??? What about code that pulls out the temp and uses it
5598 elsewhere? I think that such code never uses the TARGET_EXPR as
5599 an initializer. If I'm wrong, we'll die because the temp won't
5600 have any RTL. In that case, I guess we'll need to replace
5601 references somehow. */
5602 tree init = TARGET_EXPR_INITIAL (*from_p);
5604 if (init
5605 && (TREE_CODE (*expr_p) != MODIFY_EXPR
5606 || !TARGET_EXPR_NO_ELIDE (*from_p))
5607 && !VOID_TYPE_P (TREE_TYPE (init)))
5609 *from_p = init;
5610 ret = GS_OK;
5611 changed = true;
5614 break;
5616 case COMPOUND_EXPR:
5617 /* Remove any COMPOUND_EXPR in the RHS so the following cases will be
5618 caught. */
5619 gimplify_compound_expr (from_p, pre_p, true);
5620 ret = GS_OK;
5621 changed = true;
5622 break;
5624 case CONSTRUCTOR:
5625 /* If we already made some changes, let the front end have a
5626 crack at this before we break it down. */
5627 if (ret != GS_UNHANDLED)
5628 break;
5630 /* If we're initializing from a CONSTRUCTOR, break this into
5631 individual MODIFY_EXPRs. */
5632 ret = gimplify_init_constructor (expr_p, pre_p, post_p, want_value,
5633 false);
5634 return ret;
5636 case COND_EXPR:
5637 /* If we're assigning to a non-register type, push the assignment
5638 down into the branches. This is mandatory for ADDRESSABLE types,
5639 since we cannot generate temporaries for such, but it saves a
5640 copy in other cases as well. */
5641 if (!is_gimple_reg_type (TREE_TYPE (*from_p)))
5643 /* This code should mirror the code in gimplify_cond_expr. */
5644 enum tree_code code = TREE_CODE (*expr_p);
5645 tree cond = *from_p;
5646 tree result = *to_p;
5648 ret = gimplify_expr (&result, pre_p, post_p,
5649 is_gimple_lvalue, fb_lvalue);
5650 if (ret != GS_ERROR)
5651 ret = GS_OK;
5653 /* If we are going to write RESULT more than once, clear
5654 TREE_READONLY flag, otherwise we might incorrectly promote
5655 the variable to static const and initialize it at compile
5656 time in one of the branches. */
5657 if (VAR_P (result)
5658 && TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node
5659 && TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
5660 TREE_READONLY (result) = 0;
5661 if (TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node)
5662 TREE_OPERAND (cond, 1)
5663 = build2 (code, void_type_node, result,
5664 TREE_OPERAND (cond, 1));
5665 if (TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
5666 TREE_OPERAND (cond, 2)
5667 = build2 (code, void_type_node, unshare_expr (result),
5668 TREE_OPERAND (cond, 2));
5670 TREE_TYPE (cond) = void_type_node;
5671 recalculate_side_effects (cond);
5673 if (want_value)
5675 gimplify_and_add (cond, pre_p);
5676 *expr_p = unshare_expr (result);
5678 else
5679 *expr_p = cond;
5680 return ret;
5682 break;
5684 case CALL_EXPR:
5685 /* For calls that return in memory, give *to_p as the CALL_EXPR's
5686 return slot so that we don't generate a temporary. */
5687 if (!CALL_EXPR_RETURN_SLOT_OPT (*from_p)
5688 && aggregate_value_p (*from_p, *from_p))
5690 bool use_target;
5692 if (!(rhs_predicate_for (*to_p))(*from_p))
5693 /* If we need a temporary, *to_p isn't accurate. */
5694 use_target = false;
5695 /* It's OK to use the return slot directly unless it's an NRV. */
5696 else if (TREE_CODE (*to_p) == RESULT_DECL
5697 && DECL_NAME (*to_p) == NULL_TREE
5698 && needs_to_live_in_memory (*to_p))
5699 use_target = true;
5700 else if (is_gimple_reg_type (TREE_TYPE (*to_p))
5701 || (DECL_P (*to_p) && DECL_REGISTER (*to_p)))
5702 /* Don't force regs into memory. */
5703 use_target = false;
5704 else if (TREE_CODE (*expr_p) == INIT_EXPR)
5705 /* It's OK to use the target directly if it's being
5706 initialized. */
5707 use_target = true;
5708 else if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p)))
5709 != INTEGER_CST)
5710 /* Always use the target and thus RSO for variable-sized types.
5711 GIMPLE cannot deal with a variable-sized assignment
5712 embedded in a call statement. */
5713 use_target = true;
5714 else if (TREE_CODE (*to_p) != SSA_NAME
5715 && (!is_gimple_variable (*to_p)
5716 || needs_to_live_in_memory (*to_p)))
5717 /* Don't use the original target if it's already addressable;
5718 if its address escapes, and the called function uses the
5719 NRV optimization, a conforming program could see *to_p
5720 change before the called function returns; see c++/19317.
5721 When optimizing, the return_slot pass marks more functions
5722 as safe after we have escape info. */
5723 use_target = false;
5724 else
5725 use_target = true;
5727 if (use_target)
5729 CALL_EXPR_RETURN_SLOT_OPT (*from_p) = 1;
5730 mark_addressable (*to_p);
5733 break;
5735 case WITH_SIZE_EXPR:
5736 /* Likewise for calls that return an aggregate of non-constant size,
5737 since we would not be able to generate a temporary at all. */
5738 if (TREE_CODE (TREE_OPERAND (*from_p, 0)) == CALL_EXPR)
5740 *from_p = TREE_OPERAND (*from_p, 0);
5741 /* We don't change ret in this case because the
5742 WITH_SIZE_EXPR might have been added in
5743 gimplify_modify_expr, so returning GS_OK would lead to an
5744 infinite loop. */
5745 changed = true;
5747 break;
5749 /* If we're initializing from a container, push the initialization
5750 inside it. */
5751 case CLEANUP_POINT_EXPR:
5752 case BIND_EXPR:
5753 case STATEMENT_LIST:
5755 tree wrap = *from_p;
5756 tree t;
5758 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_min_lval,
5759 fb_lvalue);
5760 if (ret != GS_ERROR)
5761 ret = GS_OK;
5763 t = voidify_wrapper_expr (wrap, *expr_p);
5764 gcc_assert (t == *expr_p);
5766 if (want_value)
5768 gimplify_and_add (wrap, pre_p);
5769 *expr_p = unshare_expr (*to_p);
5771 else
5772 *expr_p = wrap;
5773 return GS_OK;
5776 case NOP_EXPR:
5777 /* Pull out compound literal expressions from a NOP_EXPR.
5778 Those are created in the C FE to drop qualifiers during
5779 lvalue conversion. */
5780 if ((TREE_CODE (TREE_OPERAND (*from_p, 0)) == COMPOUND_LITERAL_EXPR)
5781 && tree_ssa_useless_type_conversion (*from_p))
5783 *from_p = TREE_OPERAND (*from_p, 0);
5784 ret = GS_OK;
5785 changed = true;
5787 break;
5789 case COMPOUND_LITERAL_EXPR:
5791 tree complit = TREE_OPERAND (*expr_p, 1);
5792 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (complit);
5793 tree decl = DECL_EXPR_DECL (decl_s);
5794 tree init = DECL_INITIAL (decl);
5796 /* struct T x = (struct T) { 0, 1, 2 } can be optimized
5797 into struct T x = { 0, 1, 2 } if the address of the
5798 compound literal has never been taken. */
5799 if (!TREE_ADDRESSABLE (complit)
5800 && !TREE_ADDRESSABLE (decl)
5801 && init)
5803 *expr_p = copy_node (*expr_p);
5804 TREE_OPERAND (*expr_p, 1) = init;
5805 return GS_OK;
5809 default:
5810 break;
5813 while (changed);
5815 return ret;
5819 /* Return true if T looks like a valid GIMPLE statement. */
5821 static bool
5822 is_gimple_stmt (tree t)
5824 const enum tree_code code = TREE_CODE (t);
5826 switch (code)
5828 case NOP_EXPR:
5829 /* The only valid NOP_EXPR is the empty statement. */
5830 return IS_EMPTY_STMT (t);
5832 case BIND_EXPR:
5833 case COND_EXPR:
5834 /* These are only valid if they're void. */
5835 return TREE_TYPE (t) == NULL || VOID_TYPE_P (TREE_TYPE (t));
5837 case SWITCH_EXPR:
5838 case GOTO_EXPR:
5839 case RETURN_EXPR:
5840 case LABEL_EXPR:
5841 case CASE_LABEL_EXPR:
5842 case TRY_CATCH_EXPR:
5843 case TRY_FINALLY_EXPR:
5844 case EH_FILTER_EXPR:
5845 case CATCH_EXPR:
5846 case ASM_EXPR:
5847 case STATEMENT_LIST:
5848 case OACC_PARALLEL:
5849 case OACC_KERNELS:
5850 case OACC_SERIAL:
5851 case OACC_DATA:
5852 case OACC_HOST_DATA:
5853 case OACC_DECLARE:
5854 case OACC_UPDATE:
5855 case OACC_ENTER_DATA:
5856 case OACC_EXIT_DATA:
5857 case OACC_CACHE:
5858 case OMP_PARALLEL:
5859 case OMP_FOR:
5860 case OMP_SIMD:
5861 case OMP_DISTRIBUTE:
5862 case OMP_LOOP:
5863 case OACC_LOOP:
5864 case OMP_SCAN:
5865 case OMP_SCOPE:
5866 case OMP_SECTIONS:
5867 case OMP_SECTION:
5868 case OMP_SINGLE:
5869 case OMP_MASTER:
5870 case OMP_MASKED:
5871 case OMP_TASKGROUP:
5872 case OMP_ORDERED:
5873 case OMP_CRITICAL:
5874 case OMP_TASK:
5875 case OMP_TARGET:
5876 case OMP_TARGET_DATA:
5877 case OMP_TARGET_UPDATE:
5878 case OMP_TARGET_ENTER_DATA:
5879 case OMP_TARGET_EXIT_DATA:
5880 case OMP_TASKLOOP:
5881 case OMP_TEAMS:
5882 /* These are always void. */
5883 return true;
5885 case CALL_EXPR:
5886 case MODIFY_EXPR:
5887 case PREDICT_EXPR:
5888 /* These are valid regardless of their type. */
5889 return true;
5891 default:
5892 return false;
5897 /* Promote partial stores to COMPLEX variables to total stores. *EXPR_P is
5898 a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a gimple register.
5900 IMPORTANT NOTE: This promotion is performed by introducing a load of the
5901 other, unmodified part of the complex object just before the total store.
5902 As a consequence, if the object is still uninitialized, an undefined value
5903 will be loaded into a register, which may result in a spurious exception
5904 if the register is floating-point and the value happens to be a signaling
5905 NaN for example. Then the fully-fledged complex operations lowering pass
5906 followed by a DCE pass are necessary in order to fix things up. */
5908 static enum gimplify_status
5909 gimplify_modify_expr_complex_part (tree *expr_p, gimple_seq *pre_p,
5910 bool want_value)
5912 enum tree_code code, ocode;
5913 tree lhs, rhs, new_rhs, other, realpart, imagpart;
5915 lhs = TREE_OPERAND (*expr_p, 0);
5916 rhs = TREE_OPERAND (*expr_p, 1);
5917 code = TREE_CODE (lhs);
5918 lhs = TREE_OPERAND (lhs, 0);
5920 ocode = code == REALPART_EXPR ? IMAGPART_EXPR : REALPART_EXPR;
5921 other = build1 (ocode, TREE_TYPE (rhs), lhs);
5922 suppress_warning (other);
5923 other = get_formal_tmp_var (other, pre_p);
5925 realpart = code == REALPART_EXPR ? rhs : other;
5926 imagpart = code == REALPART_EXPR ? other : rhs;
5928 if (TREE_CONSTANT (realpart) && TREE_CONSTANT (imagpart))
5929 new_rhs = build_complex (TREE_TYPE (lhs), realpart, imagpart);
5930 else
5931 new_rhs = build2 (COMPLEX_EXPR, TREE_TYPE (lhs), realpart, imagpart);
5933 gimplify_seq_add_stmt (pre_p, gimple_build_assign (lhs, new_rhs));
5934 *expr_p = (want_value) ? rhs : NULL_TREE;
5936 return GS_ALL_DONE;
5939 /* Gimplify the MODIFY_EXPR node pointed to by EXPR_P.
5941 modify_expr
5942 : varname '=' rhs
5943 | '*' ID '=' rhs
5945 PRE_P points to the list where side effects that must happen before
5946 *EXPR_P should be stored.
5948 POST_P points to the list where side effects that must happen after
5949 *EXPR_P should be stored.
5951 WANT_VALUE is nonzero iff we want to use the value of this expression
5952 in another expression. */
5954 static enum gimplify_status
5955 gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
5956 bool want_value)
5958 tree *from_p = &TREE_OPERAND (*expr_p, 1);
5959 tree *to_p = &TREE_OPERAND (*expr_p, 0);
5960 enum gimplify_status ret = GS_UNHANDLED;
5961 gimple *assign;
5962 location_t loc = EXPR_LOCATION (*expr_p);
5963 gimple_stmt_iterator gsi;
5965 gcc_assert (TREE_CODE (*expr_p) == MODIFY_EXPR
5966 || TREE_CODE (*expr_p) == INIT_EXPR);
5968 /* Trying to simplify a clobber using normal logic doesn't work,
5969 so handle it here. */
5970 if (TREE_CLOBBER_P (*from_p))
5972 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
5973 if (ret == GS_ERROR)
5974 return ret;
5975 gcc_assert (!want_value);
5976 if (!VAR_P (*to_p) && TREE_CODE (*to_p) != MEM_REF)
5978 tree addr = get_initialized_tmp_var (build_fold_addr_expr (*to_p),
5979 pre_p, post_p);
5980 *to_p = build_simple_mem_ref_loc (EXPR_LOCATION (*to_p), addr);
5982 gimplify_seq_add_stmt (pre_p, gimple_build_assign (*to_p, *from_p));
5983 *expr_p = NULL;
5984 return GS_ALL_DONE;
5987 /* Insert pointer conversions required by the middle-end that are not
5988 required by the frontend. This fixes middle-end type checking for
5989 for example gcc.dg/redecl-6.c. */
5990 if (POINTER_TYPE_P (TREE_TYPE (*to_p)))
5992 STRIP_USELESS_TYPE_CONVERSION (*from_p);
5993 if (!useless_type_conversion_p (TREE_TYPE (*to_p), TREE_TYPE (*from_p)))
5994 *from_p = fold_convert_loc (loc, TREE_TYPE (*to_p), *from_p);
5997 /* See if any simplifications can be done based on what the RHS is. */
5998 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
5999 want_value);
6000 if (ret != GS_UNHANDLED)
6001 return ret;
6003 /* For empty types only gimplify the left hand side and right hand
6004 side as statements and throw away the assignment. Do this after
6005 gimplify_modify_expr_rhs so we handle TARGET_EXPRs of addressable
6006 types properly. */
6007 if (is_empty_type (TREE_TYPE (*from_p))
6008 && !want_value
6009 /* Don't do this for calls that return addressable types, expand_call
6010 relies on those having a lhs. */
6011 && !(TREE_ADDRESSABLE (TREE_TYPE (*from_p))
6012 && TREE_CODE (*from_p) == CALL_EXPR))
6014 gimplify_stmt (from_p, pre_p);
6015 gimplify_stmt (to_p, pre_p);
6016 *expr_p = NULL_TREE;
6017 return GS_ALL_DONE;
6020 /* If the value being copied is of variable width, compute the length
6021 of the copy into a WITH_SIZE_EXPR. Note that we need to do this
6022 before gimplifying any of the operands so that we can resolve any
6023 PLACEHOLDER_EXPRs in the size. Also note that the RTL expander uses
6024 the size of the expression to be copied, not of the destination, so
6025 that is what we must do here. */
6026 maybe_with_size_expr (from_p);
6028 /* As a special case, we have to temporarily allow for assignments
6029 with a CALL_EXPR on the RHS. Since in GIMPLE a function call is
6030 a toplevel statement, when gimplifying the GENERIC expression
6031 MODIFY_EXPR <a, CALL_EXPR <foo>>, we cannot create the tuple
6032 GIMPLE_ASSIGN <a, GIMPLE_CALL <foo>>.
6034 Instead, we need to create the tuple GIMPLE_CALL <a, foo>. To
6035 prevent gimplify_expr from trying to create a new temporary for
6036 foo's LHS, we tell it that it should only gimplify until it
6037 reaches the CALL_EXPR. On return from gimplify_expr, the newly
6038 created GIMPLE_CALL <foo> will be the last statement in *PRE_P
6039 and all we need to do here is set 'a' to be its LHS. */
6041 /* Gimplify the RHS first for C++17 and bug 71104. */
6042 gimple_predicate initial_pred = initial_rhs_predicate_for (*to_p);
6043 ret = gimplify_expr (from_p, pre_p, post_p, initial_pred, fb_rvalue);
6044 if (ret == GS_ERROR)
6045 return ret;
6047 /* Then gimplify the LHS. */
6048 /* If we gimplified the RHS to a CALL_EXPR and that call may return
6049 twice we have to make sure to gimplify into non-SSA as otherwise
6050 the abnormal edge added later will make those defs not dominate
6051 their uses.
6052 ??? Technically this applies only to the registers used in the
6053 resulting non-register *TO_P. */
6054 bool saved_into_ssa = gimplify_ctxp->into_ssa;
6055 if (saved_into_ssa
6056 && TREE_CODE (*from_p) == CALL_EXPR
6057 && call_expr_flags (*from_p) & ECF_RETURNS_TWICE)
6058 gimplify_ctxp->into_ssa = false;
6059 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
6060 gimplify_ctxp->into_ssa = saved_into_ssa;
6061 if (ret == GS_ERROR)
6062 return ret;
6064 /* Now that the LHS is gimplified, re-gimplify the RHS if our initial
6065 guess for the predicate was wrong. */
6066 gimple_predicate final_pred = rhs_predicate_for (*to_p);
6067 if (final_pred != initial_pred)
6069 ret = gimplify_expr (from_p, pre_p, post_p, final_pred, fb_rvalue);
6070 if (ret == GS_ERROR)
6071 return ret;
6074 /* In case of va_arg internal fn wrappped in a WITH_SIZE_EXPR, add the type
6075 size as argument to the call. */
6076 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
6078 tree call = TREE_OPERAND (*from_p, 0);
6079 tree vlasize = TREE_OPERAND (*from_p, 1);
6081 if (TREE_CODE (call) == CALL_EXPR
6082 && CALL_EXPR_IFN (call) == IFN_VA_ARG)
6084 int nargs = call_expr_nargs (call);
6085 tree type = TREE_TYPE (call);
6086 tree ap = CALL_EXPR_ARG (call, 0);
6087 tree tag = CALL_EXPR_ARG (call, 1);
6088 tree aptag = CALL_EXPR_ARG (call, 2);
6089 tree newcall = build_call_expr_internal_loc (EXPR_LOCATION (call),
6090 IFN_VA_ARG, type,
6091 nargs + 1, ap, tag,
6092 aptag, vlasize);
6093 TREE_OPERAND (*from_p, 0) = newcall;
6097 /* Now see if the above changed *from_p to something we handle specially. */
6098 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
6099 want_value);
6100 if (ret != GS_UNHANDLED)
6101 return ret;
6103 /* If we've got a variable sized assignment between two lvalues (i.e. does
6104 not involve a call), then we can make things a bit more straightforward
6105 by converting the assignment to memcpy or memset. */
6106 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
6108 tree from = TREE_OPERAND (*from_p, 0);
6109 tree size = TREE_OPERAND (*from_p, 1);
6111 if (TREE_CODE (from) == CONSTRUCTOR)
6112 return gimplify_modify_expr_to_memset (expr_p, size, want_value, pre_p);
6114 if (is_gimple_addressable (from))
6116 *from_p = from;
6117 return gimplify_modify_expr_to_memcpy (expr_p, size, want_value,
6118 pre_p);
6122 /* Transform partial stores to non-addressable complex variables into
6123 total stores. This allows us to use real instead of virtual operands
6124 for these variables, which improves optimization. */
6125 if ((TREE_CODE (*to_p) == REALPART_EXPR
6126 || TREE_CODE (*to_p) == IMAGPART_EXPR)
6127 && is_gimple_reg (TREE_OPERAND (*to_p, 0)))
6128 return gimplify_modify_expr_complex_part (expr_p, pre_p, want_value);
6130 /* Try to alleviate the effects of the gimplification creating artificial
6131 temporaries (see for example is_gimple_reg_rhs) on the debug info, but
6132 make sure not to create DECL_DEBUG_EXPR links across functions. */
6133 if (!gimplify_ctxp->into_ssa
6134 && VAR_P (*from_p)
6135 && DECL_IGNORED_P (*from_p)
6136 && DECL_P (*to_p)
6137 && !DECL_IGNORED_P (*to_p)
6138 && decl_function_context (*to_p) == current_function_decl
6139 && decl_function_context (*from_p) == current_function_decl)
6141 if (!DECL_NAME (*from_p) && DECL_NAME (*to_p))
6142 DECL_NAME (*from_p)
6143 = create_tmp_var_name (IDENTIFIER_POINTER (DECL_NAME (*to_p)));
6144 DECL_HAS_DEBUG_EXPR_P (*from_p) = 1;
6145 SET_DECL_DEBUG_EXPR (*from_p, *to_p);
6148 if (want_value && TREE_THIS_VOLATILE (*to_p))
6149 *from_p = get_initialized_tmp_var (*from_p, pre_p, post_p);
6151 if (TREE_CODE (*from_p) == CALL_EXPR)
6153 /* Since the RHS is a CALL_EXPR, we need to create a GIMPLE_CALL
6154 instead of a GIMPLE_ASSIGN. */
6155 gcall *call_stmt;
6156 if (CALL_EXPR_FN (*from_p) == NULL_TREE)
6158 /* Gimplify internal functions created in the FEs. */
6159 int nargs = call_expr_nargs (*from_p), i;
6160 enum internal_fn ifn = CALL_EXPR_IFN (*from_p);
6161 auto_vec<tree> vargs (nargs);
6163 for (i = 0; i < nargs; i++)
6165 gimplify_arg (&CALL_EXPR_ARG (*from_p, i), pre_p,
6166 EXPR_LOCATION (*from_p));
6167 vargs.quick_push (CALL_EXPR_ARG (*from_p, i));
6169 call_stmt = gimple_build_call_internal_vec (ifn, vargs);
6170 gimple_call_set_nothrow (call_stmt, TREE_NOTHROW (*from_p));
6171 gimple_set_location (call_stmt, EXPR_LOCATION (*expr_p));
6173 else
6175 tree fnptrtype = TREE_TYPE (CALL_EXPR_FN (*from_p));
6176 CALL_EXPR_FN (*from_p) = TREE_OPERAND (CALL_EXPR_FN (*from_p), 0);
6177 STRIP_USELESS_TYPE_CONVERSION (CALL_EXPR_FN (*from_p));
6178 tree fndecl = get_callee_fndecl (*from_p);
6179 if (fndecl
6180 && fndecl_built_in_p (fndecl, BUILT_IN_EXPECT)
6181 && call_expr_nargs (*from_p) == 3)
6182 call_stmt = gimple_build_call_internal (IFN_BUILTIN_EXPECT, 3,
6183 CALL_EXPR_ARG (*from_p, 0),
6184 CALL_EXPR_ARG (*from_p, 1),
6185 CALL_EXPR_ARG (*from_p, 2));
6186 else
6188 call_stmt = gimple_build_call_from_tree (*from_p, fnptrtype);
6191 notice_special_calls (call_stmt);
6192 if (!gimple_call_noreturn_p (call_stmt) || !should_remove_lhs_p (*to_p))
6193 gimple_call_set_lhs (call_stmt, *to_p);
6194 else if (TREE_CODE (*to_p) == SSA_NAME)
6195 /* The above is somewhat premature, avoid ICEing later for a
6196 SSA name w/o a definition. We may have uses in the GIMPLE IL.
6197 ??? This doesn't make it a default-def. */
6198 SSA_NAME_DEF_STMT (*to_p) = gimple_build_nop ();
6200 assign = call_stmt;
6202 else
6204 assign = gimple_build_assign (*to_p, *from_p);
6205 gimple_set_location (assign, EXPR_LOCATION (*expr_p));
6206 if (COMPARISON_CLASS_P (*from_p))
6207 copy_warning (assign, *from_p);
6210 if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p))
6212 /* We should have got an SSA name from the start. */
6213 gcc_assert (TREE_CODE (*to_p) == SSA_NAME
6214 || ! gimple_in_ssa_p (cfun));
6217 gimplify_seq_add_stmt (pre_p, assign);
6218 gsi = gsi_last (*pre_p);
6219 maybe_fold_stmt (&gsi);
6221 if (want_value)
6223 *expr_p = TREE_THIS_VOLATILE (*to_p) ? *from_p : unshare_expr (*to_p);
6224 return GS_OK;
6226 else
6227 *expr_p = NULL;
6229 return GS_ALL_DONE;
6232 /* Gimplify a comparison between two variable-sized objects. Do this
6233 with a call to BUILT_IN_MEMCMP. */
6235 static enum gimplify_status
6236 gimplify_variable_sized_compare (tree *expr_p)
6238 location_t loc = EXPR_LOCATION (*expr_p);
6239 tree op0 = TREE_OPERAND (*expr_p, 0);
6240 tree op1 = TREE_OPERAND (*expr_p, 1);
6241 tree t, arg, dest, src, expr;
6243 arg = TYPE_SIZE_UNIT (TREE_TYPE (op0));
6244 arg = unshare_expr (arg);
6245 arg = SUBSTITUTE_PLACEHOLDER_IN_EXPR (arg, op0);
6246 src = build_fold_addr_expr_loc (loc, op1);
6247 dest = build_fold_addr_expr_loc (loc, op0);
6248 t = builtin_decl_implicit (BUILT_IN_MEMCMP);
6249 t = build_call_expr_loc (loc, t, 3, dest, src, arg);
6251 expr
6252 = build2 (TREE_CODE (*expr_p), TREE_TYPE (*expr_p), t, integer_zero_node);
6253 SET_EXPR_LOCATION (expr, loc);
6254 *expr_p = expr;
6256 return GS_OK;
6259 /* Gimplify a comparison between two aggregate objects of integral scalar
6260 mode as a comparison between the bitwise equivalent scalar values. */
6262 static enum gimplify_status
6263 gimplify_scalar_mode_aggregate_compare (tree *expr_p)
6265 location_t loc = EXPR_LOCATION (*expr_p);
6266 tree op0 = TREE_OPERAND (*expr_p, 0);
6267 tree op1 = TREE_OPERAND (*expr_p, 1);
6269 tree type = TREE_TYPE (op0);
6270 tree scalar_type = lang_hooks.types.type_for_mode (TYPE_MODE (type), 1);
6272 op0 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op0);
6273 op1 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op1);
6275 *expr_p
6276 = fold_build2_loc (loc, TREE_CODE (*expr_p), TREE_TYPE (*expr_p), op0, op1);
6278 return GS_OK;
6281 /* Gimplify an expression sequence. This function gimplifies each
6282 expression and rewrites the original expression with the last
6283 expression of the sequence in GIMPLE form.
6285 PRE_P points to the list where the side effects for all the
6286 expressions in the sequence will be emitted.
6288 WANT_VALUE is true when the result of the last COMPOUND_EXPR is used. */
6290 static enum gimplify_status
6291 gimplify_compound_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
6293 tree t = *expr_p;
6297 tree *sub_p = &TREE_OPERAND (t, 0);
6299 if (TREE_CODE (*sub_p) == COMPOUND_EXPR)
6300 gimplify_compound_expr (sub_p, pre_p, false);
6301 else
6302 gimplify_stmt (sub_p, pre_p);
6304 t = TREE_OPERAND (t, 1);
6306 while (TREE_CODE (t) == COMPOUND_EXPR);
6308 *expr_p = t;
6309 if (want_value)
6310 return GS_OK;
6311 else
6313 gimplify_stmt (expr_p, pre_p);
6314 return GS_ALL_DONE;
6318 /* Gimplify a SAVE_EXPR node. EXPR_P points to the expression to
6319 gimplify. After gimplification, EXPR_P will point to a new temporary
6320 that holds the original value of the SAVE_EXPR node.
6322 PRE_P points to the list where side effects that must happen before
6323 *EXPR_P should be stored. */
6325 static enum gimplify_status
6326 gimplify_save_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6328 enum gimplify_status ret = GS_ALL_DONE;
6329 tree val;
6331 gcc_assert (TREE_CODE (*expr_p) == SAVE_EXPR);
6332 val = TREE_OPERAND (*expr_p, 0);
6334 if (TREE_TYPE (val) == error_mark_node)
6335 return GS_ERROR;
6337 /* If the SAVE_EXPR has not been resolved, then evaluate it once. */
6338 if (!SAVE_EXPR_RESOLVED_P (*expr_p))
6340 /* The operand may be a void-valued expression. It is
6341 being executed only for its side-effects. */
6342 if (TREE_TYPE (val) == void_type_node)
6344 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
6345 is_gimple_stmt, fb_none);
6346 val = NULL;
6348 else
6349 /* The temporary may not be an SSA name as later abnormal and EH
6350 control flow may invalidate use/def domination. When in SSA
6351 form then assume there are no such issues and SAVE_EXPRs only
6352 appear via GENERIC foldings. */
6353 val = get_initialized_tmp_var (val, pre_p, post_p,
6354 gimple_in_ssa_p (cfun));
6356 TREE_OPERAND (*expr_p, 0) = val;
6357 SAVE_EXPR_RESOLVED_P (*expr_p) = 1;
6360 *expr_p = val;
6362 return ret;
6365 /* Rewrite the ADDR_EXPR node pointed to by EXPR_P
6367 unary_expr
6368 : ...
6369 | '&' varname
6372 PRE_P points to the list where side effects that must happen before
6373 *EXPR_P should be stored.
6375 POST_P points to the list where side effects that must happen after
6376 *EXPR_P should be stored. */
6378 static enum gimplify_status
6379 gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6381 tree expr = *expr_p;
6382 tree op0 = TREE_OPERAND (expr, 0);
6383 enum gimplify_status ret;
6384 location_t loc = EXPR_LOCATION (*expr_p);
6386 switch (TREE_CODE (op0))
6388 case INDIRECT_REF:
6389 do_indirect_ref:
6390 /* Check if we are dealing with an expression of the form '&*ptr'.
6391 While the front end folds away '&*ptr' into 'ptr', these
6392 expressions may be generated internally by the compiler (e.g.,
6393 builtins like __builtin_va_end). */
6394 /* Caution: the silent array decomposition semantics we allow for
6395 ADDR_EXPR means we can't always discard the pair. */
6396 /* Gimplification of the ADDR_EXPR operand may drop
6397 cv-qualification conversions, so make sure we add them if
6398 needed. */
6400 tree op00 = TREE_OPERAND (op0, 0);
6401 tree t_expr = TREE_TYPE (expr);
6402 tree t_op00 = TREE_TYPE (op00);
6404 if (!useless_type_conversion_p (t_expr, t_op00))
6405 op00 = fold_convert_loc (loc, TREE_TYPE (expr), op00);
6406 *expr_p = op00;
6407 ret = GS_OK;
6409 break;
6411 case VIEW_CONVERT_EXPR:
6412 /* Take the address of our operand and then convert it to the type of
6413 this ADDR_EXPR.
6415 ??? The interactions of VIEW_CONVERT_EXPR and aliasing is not at
6416 all clear. The impact of this transformation is even less clear. */
6418 /* If the operand is a useless conversion, look through it. Doing so
6419 guarantees that the ADDR_EXPR and its operand will remain of the
6420 same type. */
6421 if (tree_ssa_useless_type_conversion (TREE_OPERAND (op0, 0)))
6422 op0 = TREE_OPERAND (op0, 0);
6424 *expr_p = fold_convert_loc (loc, TREE_TYPE (expr),
6425 build_fold_addr_expr_loc (loc,
6426 TREE_OPERAND (op0, 0)));
6427 ret = GS_OK;
6428 break;
6430 case MEM_REF:
6431 if (integer_zerop (TREE_OPERAND (op0, 1)))
6432 goto do_indirect_ref;
6434 /* fall through */
6436 default:
6437 /* If we see a call to a declared builtin or see its address
6438 being taken (we can unify those cases here) then we can mark
6439 the builtin for implicit generation by GCC. */
6440 if (TREE_CODE (op0) == FUNCTION_DECL
6441 && fndecl_built_in_p (op0, BUILT_IN_NORMAL)
6442 && builtin_decl_declared_p (DECL_FUNCTION_CODE (op0)))
6443 set_builtin_decl_implicit_p (DECL_FUNCTION_CODE (op0), true);
6445 /* We use fb_either here because the C frontend sometimes takes
6446 the address of a call that returns a struct; see
6447 gcc.dg/c99-array-lval-1.c. The gimplifier will correctly make
6448 the implied temporary explicit. */
6450 /* Make the operand addressable. */
6451 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, post_p,
6452 is_gimple_addressable, fb_either);
6453 if (ret == GS_ERROR)
6454 break;
6456 /* Then mark it. Beware that it may not be possible to do so directly
6457 if a temporary has been created by the gimplification. */
6458 prepare_gimple_addressable (&TREE_OPERAND (expr, 0), pre_p);
6460 op0 = TREE_OPERAND (expr, 0);
6462 /* For various reasons, the gimplification of the expression
6463 may have made a new INDIRECT_REF. */
6464 if (TREE_CODE (op0) == INDIRECT_REF
6465 || (TREE_CODE (op0) == MEM_REF
6466 && integer_zerop (TREE_OPERAND (op0, 1))))
6467 goto do_indirect_ref;
6469 mark_addressable (TREE_OPERAND (expr, 0));
6471 /* The FEs may end up building ADDR_EXPRs early on a decl with
6472 an incomplete type. Re-build ADDR_EXPRs in canonical form
6473 here. */
6474 if (!types_compatible_p (TREE_TYPE (op0), TREE_TYPE (TREE_TYPE (expr))))
6475 *expr_p = build_fold_addr_expr (op0);
6477 /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly. */
6478 recompute_tree_invariant_for_addr_expr (*expr_p);
6480 /* If we re-built the ADDR_EXPR add a conversion to the original type
6481 if required. */
6482 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
6483 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
6485 break;
6488 return ret;
6491 /* Gimplify the operands of an ASM_EXPR. Input operands should be a gimple
6492 value; output operands should be a gimple lvalue. */
6494 static enum gimplify_status
6495 gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6497 tree expr;
6498 int noutputs;
6499 const char **oconstraints;
6500 int i;
6501 tree link;
6502 const char *constraint;
6503 bool allows_mem, allows_reg, is_inout;
6504 enum gimplify_status ret, tret;
6505 gasm *stmt;
6506 vec<tree, va_gc> *inputs;
6507 vec<tree, va_gc> *outputs;
6508 vec<tree, va_gc> *clobbers;
6509 vec<tree, va_gc> *labels;
6510 tree link_next;
6512 expr = *expr_p;
6513 noutputs = list_length (ASM_OUTPUTS (expr));
6514 oconstraints = (const char **) alloca ((noutputs) * sizeof (const char *));
6516 inputs = NULL;
6517 outputs = NULL;
6518 clobbers = NULL;
6519 labels = NULL;
6521 ret = GS_ALL_DONE;
6522 link_next = NULL_TREE;
6523 for (i = 0, link = ASM_OUTPUTS (expr); link; ++i, link = link_next)
6525 bool ok;
6526 size_t constraint_len;
6528 link_next = TREE_CHAIN (link);
6530 oconstraints[i]
6531 = constraint
6532 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
6533 constraint_len = strlen (constraint);
6534 if (constraint_len == 0)
6535 continue;
6537 ok = parse_output_constraint (&constraint, i, 0, 0,
6538 &allows_mem, &allows_reg, &is_inout);
6539 if (!ok)
6541 ret = GS_ERROR;
6542 is_inout = false;
6545 /* If we can't make copies, we can only accept memory.
6546 Similarly for VLAs. */
6547 tree outtype = TREE_TYPE (TREE_VALUE (link));
6548 if (outtype != error_mark_node
6549 && (TREE_ADDRESSABLE (outtype)
6550 || !COMPLETE_TYPE_P (outtype)
6551 || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (outtype))))
6553 if (allows_mem)
6554 allows_reg = 0;
6555 else
6557 error ("impossible constraint in %<asm%>");
6558 error ("non-memory output %d must stay in memory", i);
6559 return GS_ERROR;
6563 if (!allows_reg && allows_mem)
6564 mark_addressable (TREE_VALUE (link));
6566 tree orig = TREE_VALUE (link);
6567 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6568 is_inout ? is_gimple_min_lval : is_gimple_lvalue,
6569 fb_lvalue | fb_mayfail);
6570 if (tret == GS_ERROR)
6572 if (orig != error_mark_node)
6573 error ("invalid lvalue in %<asm%> output %d", i);
6574 ret = tret;
6577 /* If the constraint does not allow memory make sure we gimplify
6578 it to a register if it is not already but its base is. This
6579 happens for complex and vector components. */
6580 if (!allows_mem)
6582 tree op = TREE_VALUE (link);
6583 if (! is_gimple_val (op)
6584 && is_gimple_reg_type (TREE_TYPE (op))
6585 && is_gimple_reg (get_base_address (op)))
6587 tree tem = create_tmp_reg (TREE_TYPE (op));
6588 tree ass;
6589 if (is_inout)
6591 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem),
6592 tem, unshare_expr (op));
6593 gimplify_and_add (ass, pre_p);
6595 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem), op, tem);
6596 gimplify_and_add (ass, post_p);
6598 TREE_VALUE (link) = tem;
6599 tret = GS_OK;
6603 vec_safe_push (outputs, link);
6604 TREE_CHAIN (link) = NULL_TREE;
6606 if (is_inout)
6608 /* An input/output operand. To give the optimizers more
6609 flexibility, split it into separate input and output
6610 operands. */
6611 tree input;
6612 /* Buffer big enough to format a 32-bit UINT_MAX into. */
6613 char buf[11];
6615 /* Turn the in/out constraint into an output constraint. */
6616 char *p = xstrdup (constraint);
6617 p[0] = '=';
6618 TREE_VALUE (TREE_PURPOSE (link)) = build_string (constraint_len, p);
6620 /* And add a matching input constraint. */
6621 if (allows_reg)
6623 sprintf (buf, "%u", i);
6625 /* If there are multiple alternatives in the constraint,
6626 handle each of them individually. Those that allow register
6627 will be replaced with operand number, the others will stay
6628 unchanged. */
6629 if (strchr (p, ',') != NULL)
6631 size_t len = 0, buflen = strlen (buf);
6632 char *beg, *end, *str, *dst;
6634 for (beg = p + 1;;)
6636 end = strchr (beg, ',');
6637 if (end == NULL)
6638 end = strchr (beg, '\0');
6639 if ((size_t) (end - beg) < buflen)
6640 len += buflen + 1;
6641 else
6642 len += end - beg + 1;
6643 if (*end)
6644 beg = end + 1;
6645 else
6646 break;
6649 str = (char *) alloca (len);
6650 for (beg = p + 1, dst = str;;)
6652 const char *tem;
6653 bool mem_p, reg_p, inout_p;
6655 end = strchr (beg, ',');
6656 if (end)
6657 *end = '\0';
6658 beg[-1] = '=';
6659 tem = beg - 1;
6660 parse_output_constraint (&tem, i, 0, 0,
6661 &mem_p, &reg_p, &inout_p);
6662 if (dst != str)
6663 *dst++ = ',';
6664 if (reg_p)
6666 memcpy (dst, buf, buflen);
6667 dst += buflen;
6669 else
6671 if (end)
6672 len = end - beg;
6673 else
6674 len = strlen (beg);
6675 memcpy (dst, beg, len);
6676 dst += len;
6678 if (end)
6679 beg = end + 1;
6680 else
6681 break;
6683 *dst = '\0';
6684 input = build_string (dst - str, str);
6686 else
6687 input = build_string (strlen (buf), buf);
6689 else
6690 input = build_string (constraint_len - 1, constraint + 1);
6692 free (p);
6694 input = build_tree_list (build_tree_list (NULL_TREE, input),
6695 unshare_expr (TREE_VALUE (link)));
6696 ASM_INPUTS (expr) = chainon (ASM_INPUTS (expr), input);
6700 link_next = NULL_TREE;
6701 for (link = ASM_INPUTS (expr); link; ++i, link = link_next)
6703 link_next = TREE_CHAIN (link);
6704 constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
6705 parse_input_constraint (&constraint, 0, 0, noutputs, 0,
6706 oconstraints, &allows_mem, &allows_reg);
6708 /* If we can't make copies, we can only accept memory. */
6709 tree intype = TREE_TYPE (TREE_VALUE (link));
6710 if (intype != error_mark_node
6711 && (TREE_ADDRESSABLE (intype)
6712 || !COMPLETE_TYPE_P (intype)
6713 || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (intype))))
6715 if (allows_mem)
6716 allows_reg = 0;
6717 else
6719 error ("impossible constraint in %<asm%>");
6720 error ("non-memory input %d must stay in memory", i);
6721 return GS_ERROR;
6725 /* If the operand is a memory input, it should be an lvalue. */
6726 if (!allows_reg && allows_mem)
6728 tree inputv = TREE_VALUE (link);
6729 STRIP_NOPS (inputv);
6730 if (TREE_CODE (inputv) == PREDECREMENT_EXPR
6731 || TREE_CODE (inputv) == PREINCREMENT_EXPR
6732 || TREE_CODE (inputv) == POSTDECREMENT_EXPR
6733 || TREE_CODE (inputv) == POSTINCREMENT_EXPR
6734 || TREE_CODE (inputv) == MODIFY_EXPR)
6735 TREE_VALUE (link) = error_mark_node;
6736 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6737 is_gimple_lvalue, fb_lvalue | fb_mayfail);
6738 if (tret != GS_ERROR)
6740 /* Unlike output operands, memory inputs are not guaranteed
6741 to be lvalues by the FE, and while the expressions are
6742 marked addressable there, if it is e.g. a statement
6743 expression, temporaries in it might not end up being
6744 addressable. They might be already used in the IL and thus
6745 it is too late to make them addressable now though. */
6746 tree x = TREE_VALUE (link);
6747 while (handled_component_p (x))
6748 x = TREE_OPERAND (x, 0);
6749 if (TREE_CODE (x) == MEM_REF
6750 && TREE_CODE (TREE_OPERAND (x, 0)) == ADDR_EXPR)
6751 x = TREE_OPERAND (TREE_OPERAND (x, 0), 0);
6752 if ((VAR_P (x)
6753 || TREE_CODE (x) == PARM_DECL
6754 || TREE_CODE (x) == RESULT_DECL)
6755 && !TREE_ADDRESSABLE (x)
6756 && is_gimple_reg (x))
6758 warning_at (EXPR_LOC_OR_LOC (TREE_VALUE (link),
6759 input_location), 0,
6760 "memory input %d is not directly addressable",
6762 prepare_gimple_addressable (&TREE_VALUE (link), pre_p);
6765 mark_addressable (TREE_VALUE (link));
6766 if (tret == GS_ERROR)
6768 if (inputv != error_mark_node)
6769 error_at (EXPR_LOC_OR_LOC (TREE_VALUE (link), input_location),
6770 "memory input %d is not directly addressable", i);
6771 ret = tret;
6774 else
6776 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6777 is_gimple_asm_val, fb_rvalue);
6778 if (tret == GS_ERROR)
6779 ret = tret;
6782 TREE_CHAIN (link) = NULL_TREE;
6783 vec_safe_push (inputs, link);
6786 link_next = NULL_TREE;
6787 for (link = ASM_CLOBBERS (expr); link; ++i, link = link_next)
6789 link_next = TREE_CHAIN (link);
6790 TREE_CHAIN (link) = NULL_TREE;
6791 vec_safe_push (clobbers, link);
6794 link_next = NULL_TREE;
6795 for (link = ASM_LABELS (expr); link; ++i, link = link_next)
6797 link_next = TREE_CHAIN (link);
6798 TREE_CHAIN (link) = NULL_TREE;
6799 vec_safe_push (labels, link);
6802 /* Do not add ASMs with errors to the gimple IL stream. */
6803 if (ret != GS_ERROR)
6805 stmt = gimple_build_asm_vec (TREE_STRING_POINTER (ASM_STRING (expr)),
6806 inputs, outputs, clobbers, labels);
6808 gimple_asm_set_volatile (stmt, ASM_VOLATILE_P (expr) || noutputs == 0);
6809 gimple_asm_set_input (stmt, ASM_INPUT_P (expr));
6810 gimple_asm_set_inline (stmt, ASM_INLINE_P (expr));
6812 gimplify_seq_add_stmt (pre_p, stmt);
6815 return ret;
6818 /* Gimplify a CLEANUP_POINT_EXPR. Currently this works by adding
6819 GIMPLE_WITH_CLEANUP_EXPRs to the prequeue as we encounter cleanups while
6820 gimplifying the body, and converting them to TRY_FINALLY_EXPRs when we
6821 return to this function.
6823 FIXME should we complexify the prequeue handling instead? Or use flags
6824 for all the cleanups and let the optimizer tighten them up? The current
6825 code seems pretty fragile; it will break on a cleanup within any
6826 non-conditional nesting. But any such nesting would be broken, anyway;
6827 we can't write a TRY_FINALLY_EXPR that starts inside a nesting construct
6828 and continues out of it. We can do that at the RTL level, though, so
6829 having an optimizer to tighten up try/finally regions would be a Good
6830 Thing. */
6832 static enum gimplify_status
6833 gimplify_cleanup_point_expr (tree *expr_p, gimple_seq *pre_p)
6835 gimple_stmt_iterator iter;
6836 gimple_seq body_sequence = NULL;
6838 tree temp = voidify_wrapper_expr (*expr_p, NULL);
6840 /* We only care about the number of conditions between the innermost
6841 CLEANUP_POINT_EXPR and the cleanup. So save and reset the count and
6842 any cleanups collected outside the CLEANUP_POINT_EXPR. */
6843 int old_conds = gimplify_ctxp->conditions;
6844 gimple_seq old_cleanups = gimplify_ctxp->conditional_cleanups;
6845 bool old_in_cleanup_point_expr = gimplify_ctxp->in_cleanup_point_expr;
6846 gimplify_ctxp->conditions = 0;
6847 gimplify_ctxp->conditional_cleanups = NULL;
6848 gimplify_ctxp->in_cleanup_point_expr = true;
6850 gimplify_stmt (&TREE_OPERAND (*expr_p, 0), &body_sequence);
6852 gimplify_ctxp->conditions = old_conds;
6853 gimplify_ctxp->conditional_cleanups = old_cleanups;
6854 gimplify_ctxp->in_cleanup_point_expr = old_in_cleanup_point_expr;
6856 for (iter = gsi_start (body_sequence); !gsi_end_p (iter); )
6858 gimple *wce = gsi_stmt (iter);
6860 if (gimple_code (wce) == GIMPLE_WITH_CLEANUP_EXPR)
6862 if (gsi_one_before_end_p (iter))
6864 /* Note that gsi_insert_seq_before and gsi_remove do not
6865 scan operands, unlike some other sequence mutators. */
6866 if (!gimple_wce_cleanup_eh_only (wce))
6867 gsi_insert_seq_before_without_update (&iter,
6868 gimple_wce_cleanup (wce),
6869 GSI_SAME_STMT);
6870 gsi_remove (&iter, true);
6871 break;
6873 else
6875 gtry *gtry;
6876 gimple_seq seq;
6877 enum gimple_try_flags kind;
6879 if (gimple_wce_cleanup_eh_only (wce))
6880 kind = GIMPLE_TRY_CATCH;
6881 else
6882 kind = GIMPLE_TRY_FINALLY;
6883 seq = gsi_split_seq_after (iter);
6885 gtry = gimple_build_try (seq, gimple_wce_cleanup (wce), kind);
6886 /* Do not use gsi_replace here, as it may scan operands.
6887 We want to do a simple structural modification only. */
6888 gsi_set_stmt (&iter, gtry);
6889 iter = gsi_start (gtry->eval);
6892 else
6893 gsi_next (&iter);
6896 gimplify_seq_add_seq (pre_p, body_sequence);
6897 if (temp)
6899 *expr_p = temp;
6900 return GS_OK;
6902 else
6904 *expr_p = NULL;
6905 return GS_ALL_DONE;
6909 /* Insert a cleanup marker for gimplify_cleanup_point_expr. CLEANUP
6910 is the cleanup action required. EH_ONLY is true if the cleanup should
6911 only be executed if an exception is thrown, not on normal exit.
6912 If FORCE_UNCOND is true perform the cleanup unconditionally; this is
6913 only valid for clobbers. */
6915 static void
6916 gimple_push_cleanup (tree var, tree cleanup, bool eh_only, gimple_seq *pre_p,
6917 bool force_uncond = false)
6919 gimple *wce;
6920 gimple_seq cleanup_stmts = NULL;
6922 /* Errors can result in improperly nested cleanups. Which results in
6923 confusion when trying to resolve the GIMPLE_WITH_CLEANUP_EXPR. */
6924 if (seen_error ())
6925 return;
6927 if (gimple_conditional_context ())
6929 /* If we're in a conditional context, this is more complex. We only
6930 want to run the cleanup if we actually ran the initialization that
6931 necessitates it, but we want to run it after the end of the
6932 conditional context. So we wrap the try/finally around the
6933 condition and use a flag to determine whether or not to actually
6934 run the destructor. Thus
6936 test ? f(A()) : 0
6938 becomes (approximately)
6940 flag = 0;
6941 try {
6942 if (test) { A::A(temp); flag = 1; val = f(temp); }
6943 else { val = 0; }
6944 } finally {
6945 if (flag) A::~A(temp);
6949 if (force_uncond)
6951 gimplify_stmt (&cleanup, &cleanup_stmts);
6952 wce = gimple_build_wce (cleanup_stmts);
6953 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
6955 else
6957 tree flag = create_tmp_var (boolean_type_node, "cleanup");
6958 gassign *ffalse = gimple_build_assign (flag, boolean_false_node);
6959 gassign *ftrue = gimple_build_assign (flag, boolean_true_node);
6961 cleanup = build3 (COND_EXPR, void_type_node, flag, cleanup, NULL);
6962 gimplify_stmt (&cleanup, &cleanup_stmts);
6963 wce = gimple_build_wce (cleanup_stmts);
6964 gimple_wce_set_cleanup_eh_only (wce, eh_only);
6966 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, ffalse);
6967 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
6968 gimplify_seq_add_stmt (pre_p, ftrue);
6970 /* Because of this manipulation, and the EH edges that jump
6971 threading cannot redirect, the temporary (VAR) will appear
6972 to be used uninitialized. Don't warn. */
6973 suppress_warning (var, OPT_Wuninitialized);
6976 else
6978 gimplify_stmt (&cleanup, &cleanup_stmts);
6979 wce = gimple_build_wce (cleanup_stmts);
6980 gimple_wce_set_cleanup_eh_only (wce, eh_only);
6981 gimplify_seq_add_stmt (pre_p, wce);
6985 /* Gimplify a TARGET_EXPR which doesn't appear on the rhs of an INIT_EXPR. */
6987 static enum gimplify_status
6988 gimplify_target_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6990 tree targ = *expr_p;
6991 tree temp = TARGET_EXPR_SLOT (targ);
6992 tree init = TARGET_EXPR_INITIAL (targ);
6993 enum gimplify_status ret;
6995 bool unpoison_empty_seq = false;
6996 gimple_stmt_iterator unpoison_it;
6998 if (init)
7000 gimple_seq init_pre_p = NULL;
7002 /* TARGET_EXPR temps aren't part of the enclosing block, so add it
7003 to the temps list. Handle also variable length TARGET_EXPRs. */
7004 if (!poly_int_tree_p (DECL_SIZE (temp)))
7006 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (temp)))
7007 gimplify_type_sizes (TREE_TYPE (temp), &init_pre_p);
7008 /* FIXME: this is correct only when the size of the type does
7009 not depend on expressions evaluated in init. */
7010 gimplify_vla_decl (temp, &init_pre_p);
7012 else
7014 /* Save location where we need to place unpoisoning. It's possible
7015 that a variable will be converted to needs_to_live_in_memory. */
7016 unpoison_it = gsi_last (*pre_p);
7017 unpoison_empty_seq = gsi_end_p (unpoison_it);
7019 gimple_add_tmp_var (temp);
7022 /* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the
7023 expression is supposed to initialize the slot. */
7024 if (VOID_TYPE_P (TREE_TYPE (init)))
7025 ret = gimplify_expr (&init, &init_pre_p, post_p, is_gimple_stmt,
7026 fb_none);
7027 else
7029 tree init_expr = build2 (INIT_EXPR, void_type_node, temp, init);
7030 init = init_expr;
7031 ret = gimplify_expr (&init, &init_pre_p, post_p, is_gimple_stmt,
7032 fb_none);
7033 init = NULL;
7034 ggc_free (init_expr);
7036 if (ret == GS_ERROR)
7038 /* PR c++/28266 Make sure this is expanded only once. */
7039 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
7040 return GS_ERROR;
7043 if (init)
7044 gimplify_and_add (init, &init_pre_p);
7046 /* Add a clobber for the temporary going out of scope, like
7047 gimplify_bind_expr. */
7048 if (gimplify_ctxp->in_cleanup_point_expr
7049 && needs_to_live_in_memory (temp))
7051 if (flag_stack_reuse == SR_ALL)
7053 tree clobber = build_clobber (TREE_TYPE (temp), CLOBBER_EOL);
7054 clobber = build2 (MODIFY_EXPR, TREE_TYPE (temp), temp, clobber);
7055 gimple_push_cleanup (temp, clobber, false, pre_p, true);
7057 if (asan_poisoned_variables
7058 && DECL_ALIGN (temp) <= MAX_SUPPORTED_STACK_ALIGNMENT
7059 && !TREE_STATIC (temp)
7060 && dbg_cnt (asan_use_after_scope)
7061 && !gimplify_omp_ctxp)
7063 tree asan_cleanup = build_asan_poison_call_expr (temp);
7064 if (asan_cleanup)
7066 if (unpoison_empty_seq)
7067 unpoison_it = gsi_start (*pre_p);
7069 asan_poison_variable (temp, false, &unpoison_it,
7070 unpoison_empty_seq);
7071 gimple_push_cleanup (temp, asan_cleanup, false, pre_p);
7076 gimple_seq_add_seq (pre_p, init_pre_p);
7078 /* If needed, push the cleanup for the temp. */
7079 if (TARGET_EXPR_CLEANUP (targ))
7080 gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ),
7081 CLEANUP_EH_ONLY (targ), pre_p);
7083 /* Only expand this once. */
7084 TREE_OPERAND (targ, 3) = init;
7085 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
7087 else
7088 /* We should have expanded this before. */
7089 gcc_assert (DECL_SEEN_IN_BIND_EXPR_P (temp));
7091 *expr_p = temp;
7092 return GS_OK;
7095 /* Gimplification of expression trees. */
7097 /* Gimplify an expression which appears at statement context. The
7098 corresponding GIMPLE statements are added to *SEQ_P. If *SEQ_P is
7099 NULL, a new sequence is allocated.
7101 Return true if we actually added a statement to the queue. */
7103 bool
7104 gimplify_stmt (tree *stmt_p, gimple_seq *seq_p)
7106 gimple_seq_node last;
7108 last = gimple_seq_last (*seq_p);
7109 gimplify_expr (stmt_p, seq_p, NULL, is_gimple_stmt, fb_none);
7110 return last != gimple_seq_last (*seq_p);
7113 /* Add FIRSTPRIVATE entries for DECL in the OpenMP the surrounding parallels
7114 to CTX. If entries already exist, force them to be some flavor of private.
7115 If there is no enclosing parallel, do nothing. */
7117 void
7118 omp_firstprivatize_variable (struct gimplify_omp_ctx *ctx, tree decl)
7120 splay_tree_node n;
7122 if (decl == NULL || !DECL_P (decl) || ctx->region_type == ORT_NONE)
7123 return;
7127 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7128 if (n != NULL)
7130 if (n->value & GOVD_SHARED)
7131 n->value = GOVD_FIRSTPRIVATE | (n->value & GOVD_SEEN);
7132 else if (n->value & GOVD_MAP)
7133 n->value |= GOVD_MAP_TO_ONLY;
7134 else
7135 return;
7137 else if ((ctx->region_type & ORT_TARGET) != 0)
7139 if (ctx->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE)
7140 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
7141 else
7142 omp_add_variable (ctx, decl, GOVD_MAP | GOVD_MAP_TO_ONLY);
7144 else if (ctx->region_type != ORT_WORKSHARE
7145 && ctx->region_type != ORT_TASKGROUP
7146 && ctx->region_type != ORT_SIMD
7147 && ctx->region_type != ORT_ACC
7148 && !(ctx->region_type & ORT_TARGET_DATA))
7149 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
7151 ctx = ctx->outer_context;
7153 while (ctx);
7156 /* Similarly for each of the type sizes of TYPE. */
7158 static void
7159 omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type)
7161 if (type == NULL || type == error_mark_node)
7162 return;
7163 type = TYPE_MAIN_VARIANT (type);
7165 if (ctx->privatized_types->add (type))
7166 return;
7168 switch (TREE_CODE (type))
7170 case INTEGER_TYPE:
7171 case ENUMERAL_TYPE:
7172 case BOOLEAN_TYPE:
7173 case REAL_TYPE:
7174 case FIXED_POINT_TYPE:
7175 omp_firstprivatize_variable (ctx, TYPE_MIN_VALUE (type));
7176 omp_firstprivatize_variable (ctx, TYPE_MAX_VALUE (type));
7177 break;
7179 case ARRAY_TYPE:
7180 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
7181 omp_firstprivatize_type_sizes (ctx, TYPE_DOMAIN (type));
7182 break;
7184 case RECORD_TYPE:
7185 case UNION_TYPE:
7186 case QUAL_UNION_TYPE:
7188 tree field;
7189 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
7190 if (TREE_CODE (field) == FIELD_DECL)
7192 omp_firstprivatize_variable (ctx, DECL_FIELD_OFFSET (field));
7193 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (field));
7196 break;
7198 case POINTER_TYPE:
7199 case REFERENCE_TYPE:
7200 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
7201 break;
7203 default:
7204 break;
7207 omp_firstprivatize_variable (ctx, TYPE_SIZE (type));
7208 omp_firstprivatize_variable (ctx, TYPE_SIZE_UNIT (type));
7209 lang_hooks.types.omp_firstprivatize_type_sizes (ctx, type);
7212 /* Add an entry for DECL in the OMP context CTX with FLAGS. */
7214 static void
7215 omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
7217 splay_tree_node n;
7218 unsigned int nflags;
7219 tree t;
7221 if (error_operand_p (decl) || ctx->region_type == ORT_NONE)
7222 return;
7224 /* Never elide decls whose type has TREE_ADDRESSABLE set. This means
7225 there are constructors involved somewhere. Exception is a shared clause,
7226 there is nothing privatized in that case. */
7227 if ((flags & GOVD_SHARED) == 0
7228 && (TREE_ADDRESSABLE (TREE_TYPE (decl))
7229 || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))))
7230 flags |= GOVD_SEEN;
7232 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7233 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
7235 /* We shouldn't be re-adding the decl with the same data
7236 sharing class. */
7237 gcc_assert ((n->value & GOVD_DATA_SHARE_CLASS & flags) == 0);
7238 nflags = n->value | flags;
7239 /* The only combination of data sharing classes we should see is
7240 FIRSTPRIVATE and LASTPRIVATE. However, OpenACC permits
7241 reduction variables to be used in data sharing clauses. */
7242 gcc_assert ((ctx->region_type & ORT_ACC) != 0
7243 || ((nflags & GOVD_DATA_SHARE_CLASS)
7244 == (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE))
7245 || (flags & GOVD_DATA_SHARE_CLASS) == 0);
7246 n->value = nflags;
7247 return;
7250 /* When adding a variable-sized variable, we have to handle all sorts
7251 of additional bits of data: the pointer replacement variable, and
7252 the parameters of the type. */
7253 if (DECL_SIZE (decl) && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
7255 /* Add the pointer replacement variable as PRIVATE if the variable
7256 replacement is private, else FIRSTPRIVATE since we'll need the
7257 address of the original variable either for SHARED, or for the
7258 copy into or out of the context. */
7259 if (!(flags & GOVD_LOCAL) && ctx->region_type != ORT_TASKGROUP)
7261 if (flags & GOVD_MAP)
7262 nflags = GOVD_MAP | GOVD_MAP_TO_ONLY | GOVD_EXPLICIT;
7263 else if (flags & GOVD_PRIVATE)
7264 nflags = GOVD_PRIVATE;
7265 else if (((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
7266 && (flags & GOVD_FIRSTPRIVATE))
7267 || (ctx->region_type == ORT_TARGET_DATA
7268 && (flags & GOVD_DATA_SHARE_CLASS) == 0))
7269 nflags = GOVD_PRIVATE | GOVD_EXPLICIT;
7270 else
7271 nflags = GOVD_FIRSTPRIVATE;
7272 nflags |= flags & GOVD_SEEN;
7273 t = DECL_VALUE_EXPR (decl);
7274 gcc_assert (TREE_CODE (t) == INDIRECT_REF);
7275 t = TREE_OPERAND (t, 0);
7276 gcc_assert (DECL_P (t));
7277 omp_add_variable (ctx, t, nflags);
7280 /* Add all of the variable and type parameters (which should have
7281 been gimplified to a formal temporary) as FIRSTPRIVATE. */
7282 omp_firstprivatize_variable (ctx, DECL_SIZE_UNIT (decl));
7283 omp_firstprivatize_variable (ctx, DECL_SIZE (decl));
7284 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
7286 /* The variable-sized variable itself is never SHARED, only some form
7287 of PRIVATE. The sharing would take place via the pointer variable
7288 which we remapped above. */
7289 if (flags & GOVD_SHARED)
7290 flags = GOVD_SHARED | GOVD_DEBUG_PRIVATE
7291 | (flags & (GOVD_SEEN | GOVD_EXPLICIT));
7293 /* We're going to make use of the TYPE_SIZE_UNIT at least in the
7294 alloca statement we generate for the variable, so make sure it
7295 is available. This isn't automatically needed for the SHARED
7296 case, since we won't be allocating local storage then.
7297 For local variables TYPE_SIZE_UNIT might not be gimplified yet,
7298 in this case omp_notice_variable will be called later
7299 on when it is gimplified. */
7300 else if (! (flags & (GOVD_LOCAL | GOVD_MAP))
7301 && DECL_P (TYPE_SIZE_UNIT (TREE_TYPE (decl))))
7302 omp_notice_variable (ctx, TYPE_SIZE_UNIT (TREE_TYPE (decl)), true);
7304 else if ((flags & (GOVD_MAP | GOVD_LOCAL)) == 0
7305 && omp_privatize_by_reference (decl))
7307 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
7309 /* Similar to the direct variable sized case above, we'll need the
7310 size of references being privatized. */
7311 if ((flags & GOVD_SHARED) == 0)
7313 t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
7314 if (t && DECL_P (t))
7315 omp_notice_variable (ctx, t, true);
7319 if (n != NULL)
7320 n->value |= flags;
7321 else
7322 splay_tree_insert (ctx->variables, (splay_tree_key)decl, flags);
7324 /* For reductions clauses in OpenACC loop directives, by default create a
7325 copy clause on the enclosing parallel construct for carrying back the
7326 results. */
7327 if (ctx->region_type == ORT_ACC && (flags & GOVD_REDUCTION))
7329 struct gimplify_omp_ctx *outer_ctx = ctx->outer_context;
7330 while (outer_ctx)
7332 n = splay_tree_lookup (outer_ctx->variables, (splay_tree_key)decl);
7333 if (n != NULL)
7335 /* Ignore local variables and explicitly declared clauses. */
7336 if (n->value & (GOVD_LOCAL | GOVD_EXPLICIT))
7337 break;
7338 else if (outer_ctx->region_type == ORT_ACC_KERNELS)
7340 /* According to the OpenACC spec, such a reduction variable
7341 should already have a copy map on a kernels construct,
7342 verify that here. */
7343 gcc_assert (!(n->value & GOVD_FIRSTPRIVATE)
7344 && (n->value & GOVD_MAP));
7346 else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
7348 /* Remove firstprivate and make it a copy map. */
7349 n->value &= ~GOVD_FIRSTPRIVATE;
7350 n->value |= GOVD_MAP;
7353 else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
7355 splay_tree_insert (outer_ctx->variables, (splay_tree_key)decl,
7356 GOVD_MAP | GOVD_SEEN);
7357 break;
7359 outer_ctx = outer_ctx->outer_context;
7364 /* Notice a threadprivate variable DECL used in OMP context CTX.
7365 This just prints out diagnostics about threadprivate variable uses
7366 in untied tasks. If DECL2 is non-NULL, prevent this warning
7367 on that variable. */
7369 static bool
7370 omp_notice_threadprivate_variable (struct gimplify_omp_ctx *ctx, tree decl,
7371 tree decl2)
7373 splay_tree_node n;
7374 struct gimplify_omp_ctx *octx;
7376 for (octx = ctx; octx; octx = octx->outer_context)
7377 if ((octx->region_type & ORT_TARGET) != 0
7378 || octx->order_concurrent)
7380 n = splay_tree_lookup (octx->variables, (splay_tree_key)decl);
7381 if (n == NULL)
7383 if (octx->order_concurrent)
7385 error ("threadprivate variable %qE used in a region with"
7386 " %<order(concurrent)%> clause", DECL_NAME (decl));
7387 inform (octx->location, "enclosing region");
7389 else
7391 error ("threadprivate variable %qE used in target region",
7392 DECL_NAME (decl));
7393 inform (octx->location, "enclosing target region");
7395 splay_tree_insert (octx->variables, (splay_tree_key)decl, 0);
7397 if (decl2)
7398 splay_tree_insert (octx->variables, (splay_tree_key)decl2, 0);
7401 if (ctx->region_type != ORT_UNTIED_TASK)
7402 return false;
7403 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7404 if (n == NULL)
7406 error ("threadprivate variable %qE used in untied task",
7407 DECL_NAME (decl));
7408 inform (ctx->location, "enclosing task");
7409 splay_tree_insert (ctx->variables, (splay_tree_key)decl, 0);
7411 if (decl2)
7412 splay_tree_insert (ctx->variables, (splay_tree_key)decl2, 0);
7413 return false;
7416 /* Return true if global var DECL is device resident. */
7418 static bool
7419 device_resident_p (tree decl)
7421 tree attr = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (decl));
7423 if (!attr)
7424 return false;
7426 for (tree t = TREE_VALUE (attr); t; t = TREE_PURPOSE (t))
7428 tree c = TREE_VALUE (t);
7429 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DEVICE_RESIDENT)
7430 return true;
7433 return false;
7436 /* Return true if DECL has an ACC DECLARE attribute. */
7438 static bool
7439 is_oacc_declared (tree decl)
7441 tree t = TREE_CODE (decl) == MEM_REF ? TREE_OPERAND (decl, 0) : decl;
7442 tree declared = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (t));
7443 return declared != NULL_TREE;
7446 /* Determine outer default flags for DECL mentioned in an OMP region
7447 but not declared in an enclosing clause.
7449 ??? Some compiler-generated variables (like SAVE_EXPRs) could be
7450 remapped firstprivate instead of shared. To some extent this is
7451 addressed in omp_firstprivatize_type_sizes, but not
7452 effectively. */
7454 static unsigned
7455 omp_default_clause (struct gimplify_omp_ctx *ctx, tree decl,
7456 bool in_code, unsigned flags)
7458 enum omp_clause_default_kind default_kind = ctx->default_kind;
7459 enum omp_clause_default_kind kind;
7461 kind = lang_hooks.decls.omp_predetermined_sharing (decl);
7462 if (ctx->region_type & ORT_TASK)
7464 tree detach_clause = omp_find_clause (ctx->clauses, OMP_CLAUSE_DETACH);
7466 /* The event-handle specified by a detach clause should always be firstprivate,
7467 regardless of the current default. */
7468 if (detach_clause && OMP_CLAUSE_DECL (detach_clause) == decl)
7469 kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
7471 if (kind != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
7472 default_kind = kind;
7473 else if (VAR_P (decl) && TREE_STATIC (decl) && DECL_IN_CONSTANT_POOL (decl))
7474 default_kind = OMP_CLAUSE_DEFAULT_SHARED;
7475 /* For C/C++ default({,first}private), variables with static storage duration
7476 declared in a namespace or global scope and referenced in construct
7477 must be explicitly specified, i.e. acts as default(none). */
7478 else if ((default_kind == OMP_CLAUSE_DEFAULT_PRIVATE
7479 || default_kind == OMP_CLAUSE_DEFAULT_FIRSTPRIVATE)
7480 && VAR_P (decl)
7481 && is_global_var (decl)
7482 && (DECL_FILE_SCOPE_P (decl)
7483 || (DECL_CONTEXT (decl)
7484 && TREE_CODE (DECL_CONTEXT (decl)) == NAMESPACE_DECL))
7485 && !lang_GNU_Fortran ())
7486 default_kind = OMP_CLAUSE_DEFAULT_NONE;
7488 switch (default_kind)
7490 case OMP_CLAUSE_DEFAULT_NONE:
7492 const char *rtype;
7494 if (ctx->region_type & ORT_PARALLEL)
7495 rtype = "parallel";
7496 else if ((ctx->region_type & ORT_TASKLOOP) == ORT_TASKLOOP)
7497 rtype = "taskloop";
7498 else if (ctx->region_type & ORT_TASK)
7499 rtype = "task";
7500 else if (ctx->region_type & ORT_TEAMS)
7501 rtype = "teams";
7502 else
7503 gcc_unreachable ();
7505 error ("%qE not specified in enclosing %qs",
7506 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rtype);
7507 inform (ctx->location, "enclosing %qs", rtype);
7509 /* FALLTHRU */
7510 case OMP_CLAUSE_DEFAULT_SHARED:
7511 flags |= GOVD_SHARED;
7512 break;
7513 case OMP_CLAUSE_DEFAULT_PRIVATE:
7514 flags |= GOVD_PRIVATE;
7515 break;
7516 case OMP_CLAUSE_DEFAULT_FIRSTPRIVATE:
7517 flags |= GOVD_FIRSTPRIVATE;
7518 break;
7519 case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
7520 /* decl will be either GOVD_FIRSTPRIVATE or GOVD_SHARED. */
7521 gcc_assert ((ctx->region_type & ORT_TASK) != 0);
7522 if (struct gimplify_omp_ctx *octx = ctx->outer_context)
7524 omp_notice_variable (octx, decl, in_code);
7525 for (; octx; octx = octx->outer_context)
7527 splay_tree_node n2;
7529 n2 = splay_tree_lookup (octx->variables, (splay_tree_key) decl);
7530 if ((octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)) != 0
7531 && (n2 == NULL || (n2->value & GOVD_DATA_SHARE_CLASS) == 0))
7532 continue;
7533 if (n2 && (n2->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED)
7535 flags |= GOVD_FIRSTPRIVATE;
7536 goto found_outer;
7538 if ((octx->region_type & (ORT_PARALLEL | ORT_TEAMS)) != 0)
7540 flags |= GOVD_SHARED;
7541 goto found_outer;
7546 if (TREE_CODE (decl) == PARM_DECL
7547 || (!is_global_var (decl)
7548 && DECL_CONTEXT (decl) == current_function_decl))
7549 flags |= GOVD_FIRSTPRIVATE;
7550 else
7551 flags |= GOVD_SHARED;
7552 found_outer:
7553 break;
7555 default:
7556 gcc_unreachable ();
7559 return flags;
7563 /* Determine outer default flags for DECL mentioned in an OACC region
7564 but not declared in an enclosing clause. */
7566 static unsigned
7567 oacc_default_clause (struct gimplify_omp_ctx *ctx, tree decl, unsigned flags)
7569 const char *rkind;
7570 bool on_device = false;
7571 bool is_private = false;
7572 bool declared = is_oacc_declared (decl);
7573 tree type = TREE_TYPE (decl);
7575 if (omp_privatize_by_reference (decl))
7576 type = TREE_TYPE (type);
7578 /* For Fortran COMMON blocks, only used variables in those blocks are
7579 transfered and remapped. The block itself will have a private clause to
7580 avoid transfering the data twice.
7581 The hook evaluates to false by default. For a variable in Fortran's COMMON
7582 or EQUIVALENCE block, returns 'true' (as we have shared=false) - as only
7583 the variables in such a COMMON/EQUIVALENCE block shall be privatized not
7584 the whole block. For C++ and Fortran, it can also be true under certain
7585 other conditions, if DECL_HAS_VALUE_EXPR. */
7586 if (RECORD_OR_UNION_TYPE_P (type))
7587 is_private = lang_hooks.decls.omp_disregard_value_expr (decl, false);
7589 if ((ctx->region_type & (ORT_ACC_PARALLEL | ORT_ACC_KERNELS)) != 0
7590 && is_global_var (decl)
7591 && device_resident_p (decl)
7592 && !is_private)
7594 on_device = true;
7595 flags |= GOVD_MAP_TO_ONLY;
7598 switch (ctx->region_type)
7600 case ORT_ACC_KERNELS:
7601 rkind = "kernels";
7603 if (is_private)
7604 flags |= GOVD_FIRSTPRIVATE;
7605 else if (AGGREGATE_TYPE_P (type))
7607 /* Aggregates default to 'present_or_copy', or 'present'. */
7608 if (ctx->default_kind != OMP_CLAUSE_DEFAULT_PRESENT)
7609 flags |= GOVD_MAP;
7610 else
7611 flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
7613 else
7614 /* Scalars default to 'copy'. */
7615 flags |= GOVD_MAP | GOVD_MAP_FORCE;
7617 break;
7619 case ORT_ACC_PARALLEL:
7620 case ORT_ACC_SERIAL:
7621 rkind = ctx->region_type == ORT_ACC_PARALLEL ? "parallel" : "serial";
7623 if (is_private)
7624 flags |= GOVD_FIRSTPRIVATE;
7625 else if (on_device || declared)
7626 flags |= GOVD_MAP;
7627 else if (AGGREGATE_TYPE_P (type))
7629 /* Aggregates default to 'present_or_copy', or 'present'. */
7630 if (ctx->default_kind != OMP_CLAUSE_DEFAULT_PRESENT)
7631 flags |= GOVD_MAP;
7632 else
7633 flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
7635 else
7636 /* Scalars default to 'firstprivate'. */
7637 flags |= GOVD_FIRSTPRIVATE;
7639 break;
7641 default:
7642 gcc_unreachable ();
7645 if (DECL_ARTIFICIAL (decl))
7646 ; /* We can get compiler-generated decls, and should not complain
7647 about them. */
7648 else if (ctx->default_kind == OMP_CLAUSE_DEFAULT_NONE)
7650 error ("%qE not specified in enclosing OpenACC %qs construct",
7651 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rkind);
7652 inform (ctx->location, "enclosing OpenACC %qs construct", rkind);
7654 else if (ctx->default_kind == OMP_CLAUSE_DEFAULT_PRESENT)
7655 ; /* Handled above. */
7656 else
7657 gcc_checking_assert (ctx->default_kind == OMP_CLAUSE_DEFAULT_SHARED);
7659 return flags;
7662 /* Record the fact that DECL was used within the OMP context CTX.
7663 IN_CODE is true when real code uses DECL, and false when we should
7664 merely emit default(none) errors. Return true if DECL is going to
7665 be remapped and thus DECL shouldn't be gimplified into its
7666 DECL_VALUE_EXPR (if any). */
7668 static bool
7669 omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
7671 splay_tree_node n;
7672 unsigned flags = in_code ? GOVD_SEEN : 0;
7673 bool ret = false, shared;
7675 if (error_operand_p (decl))
7676 return false;
7678 if (ctx->region_type == ORT_NONE)
7679 return lang_hooks.decls.omp_disregard_value_expr (decl, false);
7681 if (is_global_var (decl))
7683 /* Threadprivate variables are predetermined. */
7684 if (DECL_THREAD_LOCAL_P (decl))
7685 return omp_notice_threadprivate_variable (ctx, decl, NULL_TREE);
7687 if (DECL_HAS_VALUE_EXPR_P (decl))
7689 if (ctx->region_type & ORT_ACC)
7690 /* For OpenACC, defer expansion of value to avoid transfering
7691 privatized common block data instead of im-/explicitly transfered
7692 variables which are in common blocks. */
7694 else
7696 tree value = get_base_address (DECL_VALUE_EXPR (decl));
7698 if (value && DECL_P (value) && DECL_THREAD_LOCAL_P (value))
7699 return omp_notice_threadprivate_variable (ctx, decl, value);
7703 if (gimplify_omp_ctxp->outer_context == NULL
7704 && VAR_P (decl)
7705 && oacc_get_fn_attrib (current_function_decl))
7707 location_t loc = DECL_SOURCE_LOCATION (decl);
7709 if (lookup_attribute ("omp declare target link",
7710 DECL_ATTRIBUTES (decl)))
7712 error_at (loc,
7713 "%qE with %<link%> clause used in %<routine%> function",
7714 DECL_NAME (decl));
7715 return false;
7717 else if (!lookup_attribute ("omp declare target",
7718 DECL_ATTRIBUTES (decl)))
7720 error_at (loc,
7721 "%qE requires a %<declare%> directive for use "
7722 "in a %<routine%> function", DECL_NAME (decl));
7723 return false;
7728 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7729 if ((ctx->region_type & ORT_TARGET) != 0)
7731 if (ctx->region_type & ORT_ACC)
7732 /* For OpenACC, as remarked above, defer expansion. */
7733 shared = false;
7734 else
7735 shared = true;
7737 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7738 if (n == NULL)
7740 unsigned nflags = flags;
7741 if ((ctx->region_type & ORT_ACC) == 0)
7743 bool is_declare_target = false;
7744 if (is_global_var (decl)
7745 && varpool_node::get_create (decl)->offloadable)
7747 struct gimplify_omp_ctx *octx;
7748 for (octx = ctx->outer_context;
7749 octx; octx = octx->outer_context)
7751 n = splay_tree_lookup (octx->variables,
7752 (splay_tree_key)decl);
7753 if (n
7754 && (n->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED
7755 && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
7756 break;
7758 is_declare_target = octx == NULL;
7760 if (!is_declare_target)
7762 int gdmk;
7763 enum omp_clause_defaultmap_kind kind;
7764 if (lang_hooks.decls.omp_allocatable_p (decl))
7765 gdmk = GDMK_ALLOCATABLE;
7766 else if (lang_hooks.decls.omp_scalar_target_p (decl))
7767 gdmk = GDMK_SCALAR_TARGET;
7768 else if (lang_hooks.decls.omp_scalar_p (decl, false))
7769 gdmk = GDMK_SCALAR;
7770 else if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
7771 || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
7772 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
7773 == POINTER_TYPE)))
7774 gdmk = GDMK_POINTER;
7775 else
7776 gdmk = GDMK_AGGREGATE;
7777 kind = lang_hooks.decls.omp_predetermined_mapping (decl);
7778 if (kind != OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
7780 if (kind == OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE)
7781 nflags |= GOVD_FIRSTPRIVATE;
7782 else if (kind == OMP_CLAUSE_DEFAULTMAP_TO)
7783 nflags |= GOVD_MAP | GOVD_MAP_TO_ONLY;
7784 else
7785 gcc_unreachable ();
7787 else if (ctx->defaultmap[gdmk] == 0)
7789 tree d = lang_hooks.decls.omp_report_decl (decl);
7790 error ("%qE not specified in enclosing %<target%>",
7791 DECL_NAME (d));
7792 inform (ctx->location, "enclosing %<target%>");
7794 else if (ctx->defaultmap[gdmk]
7795 & (GOVD_MAP_0LEN_ARRAY | GOVD_FIRSTPRIVATE))
7796 nflags |= ctx->defaultmap[gdmk];
7797 else
7799 gcc_assert (ctx->defaultmap[gdmk] & GOVD_MAP);
7800 nflags |= ctx->defaultmap[gdmk] & ~GOVD_MAP;
7805 struct gimplify_omp_ctx *octx = ctx->outer_context;
7806 if ((ctx->region_type & ORT_ACC) && octx)
7808 /* Look in outer OpenACC contexts, to see if there's a
7809 data attribute for this variable. */
7810 omp_notice_variable (octx, decl, in_code);
7812 for (; octx; octx = octx->outer_context)
7814 if (!(octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)))
7815 break;
7816 splay_tree_node n2
7817 = splay_tree_lookup (octx->variables,
7818 (splay_tree_key) decl);
7819 if (n2)
7821 if (octx->region_type == ORT_ACC_HOST_DATA)
7822 error ("variable %qE declared in enclosing "
7823 "%<host_data%> region", DECL_NAME (decl));
7824 nflags |= GOVD_MAP;
7825 if (octx->region_type == ORT_ACC_DATA
7826 && (n2->value & GOVD_MAP_0LEN_ARRAY))
7827 nflags |= GOVD_MAP_0LEN_ARRAY;
7828 goto found_outer;
7833 if ((nflags & ~(GOVD_MAP_TO_ONLY | GOVD_MAP_FROM_ONLY
7834 | GOVD_MAP_ALLOC_ONLY)) == flags)
7836 tree type = TREE_TYPE (decl);
7838 if (gimplify_omp_ctxp->target_firstprivatize_array_bases
7839 && omp_privatize_by_reference (decl))
7840 type = TREE_TYPE (type);
7841 if (!lang_hooks.types.omp_mappable_type (type))
7843 error ("%qD referenced in target region does not have "
7844 "a mappable type", decl);
7845 nflags |= GOVD_MAP | GOVD_EXPLICIT;
7847 else
7849 if ((ctx->region_type & ORT_ACC) != 0)
7850 nflags = oacc_default_clause (ctx, decl, flags);
7851 else
7852 nflags |= GOVD_MAP;
7855 found_outer:
7856 omp_add_variable (ctx, decl, nflags);
7858 else
7860 /* If nothing changed, there's nothing left to do. */
7861 if ((n->value & flags) == flags)
7862 return ret;
7863 flags |= n->value;
7864 n->value = flags;
7866 goto do_outer;
7869 if (n == NULL)
7871 if (ctx->region_type == ORT_WORKSHARE
7872 || ctx->region_type == ORT_TASKGROUP
7873 || ctx->region_type == ORT_SIMD
7874 || ctx->region_type == ORT_ACC
7875 || (ctx->region_type & ORT_TARGET_DATA) != 0)
7876 goto do_outer;
7878 flags = omp_default_clause (ctx, decl, in_code, flags);
7880 if ((flags & GOVD_PRIVATE)
7881 && lang_hooks.decls.omp_private_outer_ref (decl))
7882 flags |= GOVD_PRIVATE_OUTER_REF;
7884 omp_add_variable (ctx, decl, flags);
7886 shared = (flags & GOVD_SHARED) != 0;
7887 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7888 goto do_outer;
7891 /* Don't mark as GOVD_SEEN addressable temporaries seen only in simd
7892 lb, b or incr expressions, those shouldn't be turned into simd arrays. */
7893 if (ctx->region_type == ORT_SIMD
7894 && ctx->in_for_exprs
7895 && ((n->value & (GOVD_PRIVATE | GOVD_SEEN | GOVD_EXPLICIT))
7896 == GOVD_PRIVATE))
7897 flags &= ~GOVD_SEEN;
7899 if ((n->value & (GOVD_SEEN | GOVD_LOCAL)) == 0
7900 && (flags & (GOVD_SEEN | GOVD_LOCAL)) == GOVD_SEEN
7901 && DECL_SIZE (decl))
7903 if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
7905 splay_tree_node n2;
7906 tree t = DECL_VALUE_EXPR (decl);
7907 gcc_assert (TREE_CODE (t) == INDIRECT_REF);
7908 t = TREE_OPERAND (t, 0);
7909 gcc_assert (DECL_P (t));
7910 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
7911 n2->value |= GOVD_SEEN;
7913 else if (omp_privatize_by_reference (decl)
7914 && TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)))
7915 && (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))))
7916 != INTEGER_CST))
7918 splay_tree_node n2;
7919 tree t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
7920 gcc_assert (DECL_P (t));
7921 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
7922 if (n2)
7923 omp_notice_variable (ctx, t, true);
7927 if (ctx->region_type & ORT_ACC)
7928 /* For OpenACC, as remarked above, defer expansion. */
7929 shared = false;
7930 else
7931 shared = ((flags | n->value) & GOVD_SHARED) != 0;
7932 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7934 /* If nothing changed, there's nothing left to do. */
7935 if ((n->value & flags) == flags)
7936 return ret;
7937 flags |= n->value;
7938 n->value = flags;
7940 do_outer:
7941 /* If the variable is private in the current context, then we don't
7942 need to propagate anything to an outer context. */
7943 if ((flags & GOVD_PRIVATE) && !(flags & GOVD_PRIVATE_OUTER_REF))
7944 return ret;
7945 if ((flags & (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7946 == (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7947 return ret;
7948 if ((flags & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
7949 | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7950 == (GOVD_LASTPRIVATE | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7951 return ret;
7952 if (ctx->outer_context
7953 && omp_notice_variable (ctx->outer_context, decl, in_code))
7954 return true;
7955 return ret;
7958 /* Verify that DECL is private within CTX. If there's specific information
7959 to the contrary in the innermost scope, generate an error. */
7961 static bool
7962 omp_is_private (struct gimplify_omp_ctx *ctx, tree decl, int simd)
7964 splay_tree_node n;
7966 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7967 if (n != NULL)
7969 if (n->value & GOVD_SHARED)
7971 if (ctx == gimplify_omp_ctxp)
7973 if (simd)
7974 error ("iteration variable %qE is predetermined linear",
7975 DECL_NAME (decl));
7976 else
7977 error ("iteration variable %qE should be private",
7978 DECL_NAME (decl));
7979 n->value = GOVD_PRIVATE;
7980 return true;
7982 else
7983 return false;
7985 else if ((n->value & GOVD_EXPLICIT) != 0
7986 && (ctx == gimplify_omp_ctxp
7987 || (ctx->region_type == ORT_COMBINED_PARALLEL
7988 && gimplify_omp_ctxp->outer_context == ctx)))
7990 if ((n->value & GOVD_FIRSTPRIVATE) != 0)
7991 error ("iteration variable %qE should not be firstprivate",
7992 DECL_NAME (decl));
7993 else if ((n->value & GOVD_REDUCTION) != 0)
7994 error ("iteration variable %qE should not be reduction",
7995 DECL_NAME (decl));
7996 else if (simd != 1 && (n->value & GOVD_LINEAR) != 0)
7997 error ("iteration variable %qE should not be linear",
7998 DECL_NAME (decl));
8000 return (ctx == gimplify_omp_ctxp
8001 || (ctx->region_type == ORT_COMBINED_PARALLEL
8002 && gimplify_omp_ctxp->outer_context == ctx));
8005 if (ctx->region_type != ORT_WORKSHARE
8006 && ctx->region_type != ORT_TASKGROUP
8007 && ctx->region_type != ORT_SIMD
8008 && ctx->region_type != ORT_ACC)
8009 return false;
8010 else if (ctx->outer_context)
8011 return omp_is_private (ctx->outer_context, decl, simd);
8012 return false;
8015 /* Return true if DECL is private within a parallel region
8016 that binds to the current construct's context or in parallel
8017 region's REDUCTION clause. */
8019 static bool
8020 omp_check_private (struct gimplify_omp_ctx *ctx, tree decl, bool copyprivate)
8022 splay_tree_node n;
8026 ctx = ctx->outer_context;
8027 if (ctx == NULL)
8029 if (is_global_var (decl))
8030 return false;
8032 /* References might be private, but might be shared too,
8033 when checking for copyprivate, assume they might be
8034 private, otherwise assume they might be shared. */
8035 if (copyprivate)
8036 return true;
8038 if (omp_privatize_by_reference (decl))
8039 return false;
8041 /* Treat C++ privatized non-static data members outside
8042 of the privatization the same. */
8043 if (omp_member_access_dummy_var (decl))
8044 return false;
8046 return true;
8049 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
8051 if ((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
8052 && (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0))
8054 if ((ctx->region_type & ORT_TARGET_DATA) != 0
8055 || n == NULL
8056 || (n->value & GOVD_MAP) == 0)
8057 continue;
8058 return false;
8061 if (n != NULL)
8063 if ((n->value & GOVD_LOCAL) != 0
8064 && omp_member_access_dummy_var (decl))
8065 return false;
8066 return (n->value & GOVD_SHARED) == 0;
8069 if (ctx->region_type == ORT_WORKSHARE
8070 || ctx->region_type == ORT_TASKGROUP
8071 || ctx->region_type == ORT_SIMD
8072 || ctx->region_type == ORT_ACC)
8073 continue;
8075 break;
8077 while (1);
8078 return false;
8081 /* Callback for walk_tree to find a DECL_EXPR for the given DECL. */
8083 static tree
8084 find_decl_expr (tree *tp, int *walk_subtrees, void *data)
8086 tree t = *tp;
8088 /* If this node has been visited, unmark it and keep looking. */
8089 if (TREE_CODE (t) == DECL_EXPR && DECL_EXPR_DECL (t) == (tree) data)
8090 return t;
8092 if (IS_TYPE_OR_DECL_P (t))
8093 *walk_subtrees = 0;
8094 return NULL_TREE;
8098 /* Gimplify the affinity clause but effectively ignore it.
8099 Generate:
8100 var = begin;
8101 if ((step > 1) ? var <= end : var > end)
8102 locatator_var_expr; */
8104 static void
8105 gimplify_omp_affinity (tree *list_p, gimple_seq *pre_p)
8107 tree last_iter = NULL_TREE;
8108 tree last_bind = NULL_TREE;
8109 tree label = NULL_TREE;
8110 tree *last_body = NULL;
8111 for (tree c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
8112 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY)
8114 tree t = OMP_CLAUSE_DECL (c);
8115 if (TREE_CODE (t) == TREE_LIST
8116 && TREE_PURPOSE (t)
8117 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
8119 if (TREE_VALUE (t) == null_pointer_node)
8120 continue;
8121 if (TREE_PURPOSE (t) != last_iter)
8123 if (last_bind)
8125 append_to_statement_list (label, last_body);
8126 gimplify_and_add (last_bind, pre_p);
8127 last_bind = NULL_TREE;
8129 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8131 if (gimplify_expr (&TREE_VEC_ELT (it, 1), pre_p, NULL,
8132 is_gimple_val, fb_rvalue) == GS_ERROR
8133 || gimplify_expr (&TREE_VEC_ELT (it, 2), pre_p, NULL,
8134 is_gimple_val, fb_rvalue) == GS_ERROR
8135 || gimplify_expr (&TREE_VEC_ELT (it, 3), pre_p, NULL,
8136 is_gimple_val, fb_rvalue) == GS_ERROR
8137 || (gimplify_expr (&TREE_VEC_ELT (it, 4), pre_p, NULL,
8138 is_gimple_val, fb_rvalue)
8139 == GS_ERROR))
8140 return;
8142 last_iter = TREE_PURPOSE (t);
8143 tree block = TREE_VEC_ELT (TREE_PURPOSE (t), 5);
8144 last_bind = build3 (BIND_EXPR, void_type_node, BLOCK_VARS (block),
8145 NULL, block);
8146 last_body = &BIND_EXPR_BODY (last_bind);
8147 tree cond = NULL_TREE;
8148 location_t loc = OMP_CLAUSE_LOCATION (c);
8149 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8151 tree var = TREE_VEC_ELT (it, 0);
8152 tree begin = TREE_VEC_ELT (it, 1);
8153 tree end = TREE_VEC_ELT (it, 2);
8154 tree step = TREE_VEC_ELT (it, 3);
8155 loc = DECL_SOURCE_LOCATION (var);
8156 tree tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
8157 var, begin);
8158 append_to_statement_list_force (tem, last_body);
8160 tree cond1 = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8161 step, build_zero_cst (TREE_TYPE (step)));
8162 tree cond2 = fold_build2_loc (loc, LE_EXPR, boolean_type_node,
8163 var, end);
8164 tree cond3 = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8165 var, end);
8166 cond1 = fold_build3_loc (loc, COND_EXPR, boolean_type_node,
8167 cond1, cond2, cond3);
8168 if (cond)
8169 cond = fold_build2_loc (loc, TRUTH_AND_EXPR,
8170 boolean_type_node, cond, cond1);
8171 else
8172 cond = cond1;
8174 tree cont_label = create_artificial_label (loc);
8175 label = build1 (LABEL_EXPR, void_type_node, cont_label);
8176 tree tem = fold_build3_loc (loc, COND_EXPR, void_type_node, cond,
8177 void_node,
8178 build_and_jump (&cont_label));
8179 append_to_statement_list_force (tem, last_body);
8181 if (TREE_CODE (TREE_VALUE (t)) == COMPOUND_EXPR)
8183 append_to_statement_list (TREE_OPERAND (TREE_VALUE (t), 0),
8184 last_body);
8185 TREE_VALUE (t) = TREE_OPERAND (TREE_VALUE (t), 1);
8187 if (error_operand_p (TREE_VALUE (t)))
8188 return;
8189 append_to_statement_list_force (TREE_VALUE (t), last_body);
8190 TREE_VALUE (t) = null_pointer_node;
8192 else
8194 if (last_bind)
8196 append_to_statement_list (label, last_body);
8197 gimplify_and_add (last_bind, pre_p);
8198 last_bind = NULL_TREE;
8200 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
8202 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
8203 NULL, is_gimple_val, fb_rvalue);
8204 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
8206 if (error_operand_p (OMP_CLAUSE_DECL (c)))
8207 return;
8208 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
8209 is_gimple_lvalue, fb_lvalue) == GS_ERROR)
8210 return;
8211 gimplify_and_add (OMP_CLAUSE_DECL (c), pre_p);
8214 if (last_bind)
8216 append_to_statement_list (label, last_body);
8217 gimplify_and_add (last_bind, pre_p);
8219 return;
8222 /* If *LIST_P contains any OpenMP depend clauses with iterators,
8223 lower all the depend clauses by populating corresponding depend
8224 array. Returns 0 if there are no such depend clauses, or
8225 2 if all depend clauses should be removed, 1 otherwise. */
8227 static int
8228 gimplify_omp_depend (tree *list_p, gimple_seq *pre_p)
8230 tree c;
8231 gimple *g;
8232 size_t n[4] = { 0, 0, 0, 0 };
8233 bool unused[4];
8234 tree counts[4] = { NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE };
8235 tree last_iter = NULL_TREE, last_count = NULL_TREE;
8236 size_t i, j;
8237 location_t first_loc = UNKNOWN_LOCATION;
8239 for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
8240 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
8242 switch (OMP_CLAUSE_DEPEND_KIND (c))
8244 case OMP_CLAUSE_DEPEND_IN:
8245 i = 2;
8246 break;
8247 case OMP_CLAUSE_DEPEND_OUT:
8248 case OMP_CLAUSE_DEPEND_INOUT:
8249 i = 0;
8250 break;
8251 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
8252 i = 1;
8253 break;
8254 case OMP_CLAUSE_DEPEND_DEPOBJ:
8255 i = 3;
8256 break;
8257 case OMP_CLAUSE_DEPEND_SOURCE:
8258 case OMP_CLAUSE_DEPEND_SINK:
8259 continue;
8260 default:
8261 gcc_unreachable ();
8263 tree t = OMP_CLAUSE_DECL (c);
8264 if (first_loc == UNKNOWN_LOCATION)
8265 first_loc = OMP_CLAUSE_LOCATION (c);
8266 if (TREE_CODE (t) == TREE_LIST
8267 && TREE_PURPOSE (t)
8268 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
8270 if (TREE_PURPOSE (t) != last_iter)
8272 tree tcnt = size_one_node;
8273 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8275 if (gimplify_expr (&TREE_VEC_ELT (it, 1), pre_p, NULL,
8276 is_gimple_val, fb_rvalue) == GS_ERROR
8277 || gimplify_expr (&TREE_VEC_ELT (it, 2), pre_p, NULL,
8278 is_gimple_val, fb_rvalue) == GS_ERROR
8279 || gimplify_expr (&TREE_VEC_ELT (it, 3), pre_p, NULL,
8280 is_gimple_val, fb_rvalue) == GS_ERROR
8281 || (gimplify_expr (&TREE_VEC_ELT (it, 4), pre_p, NULL,
8282 is_gimple_val, fb_rvalue)
8283 == GS_ERROR))
8284 return 2;
8285 tree var = TREE_VEC_ELT (it, 0);
8286 tree begin = TREE_VEC_ELT (it, 1);
8287 tree end = TREE_VEC_ELT (it, 2);
8288 tree step = TREE_VEC_ELT (it, 3);
8289 tree orig_step = TREE_VEC_ELT (it, 4);
8290 tree type = TREE_TYPE (var);
8291 tree stype = TREE_TYPE (step);
8292 location_t loc = DECL_SOURCE_LOCATION (var);
8293 tree endmbegin;
8294 /* Compute count for this iterator as
8295 orig_step > 0
8296 ? (begin < end ? (end - begin + (step - 1)) / step : 0)
8297 : (begin > end ? (end - begin + (step + 1)) / step : 0)
8298 and compute product of those for the entire depend
8299 clause. */
8300 if (POINTER_TYPE_P (type))
8301 endmbegin = fold_build2_loc (loc, POINTER_DIFF_EXPR,
8302 stype, end, begin);
8303 else
8304 endmbegin = fold_build2_loc (loc, MINUS_EXPR, type,
8305 end, begin);
8306 tree stepm1 = fold_build2_loc (loc, MINUS_EXPR, stype,
8307 step,
8308 build_int_cst (stype, 1));
8309 tree stepp1 = fold_build2_loc (loc, PLUS_EXPR, stype, step,
8310 build_int_cst (stype, 1));
8311 tree pos = fold_build2_loc (loc, PLUS_EXPR, stype,
8312 unshare_expr (endmbegin),
8313 stepm1);
8314 pos = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype,
8315 pos, step);
8316 tree neg = fold_build2_loc (loc, PLUS_EXPR, stype,
8317 endmbegin, stepp1);
8318 if (TYPE_UNSIGNED (stype))
8320 neg = fold_build1_loc (loc, NEGATE_EXPR, stype, neg);
8321 step = fold_build1_loc (loc, NEGATE_EXPR, stype, step);
8323 neg = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype,
8324 neg, step);
8325 step = NULL_TREE;
8326 tree cond = fold_build2_loc (loc, LT_EXPR,
8327 boolean_type_node,
8328 begin, end);
8329 pos = fold_build3_loc (loc, COND_EXPR, stype, cond, pos,
8330 build_int_cst (stype, 0));
8331 cond = fold_build2_loc (loc, LT_EXPR, boolean_type_node,
8332 end, begin);
8333 neg = fold_build3_loc (loc, COND_EXPR, stype, cond, neg,
8334 build_int_cst (stype, 0));
8335 tree osteptype = TREE_TYPE (orig_step);
8336 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8337 orig_step,
8338 build_int_cst (osteptype, 0));
8339 tree cnt = fold_build3_loc (loc, COND_EXPR, stype,
8340 cond, pos, neg);
8341 cnt = fold_convert_loc (loc, sizetype, cnt);
8342 if (gimplify_expr (&cnt, pre_p, NULL, is_gimple_val,
8343 fb_rvalue) == GS_ERROR)
8344 return 2;
8345 tcnt = size_binop_loc (loc, MULT_EXPR, tcnt, cnt);
8347 if (gimplify_expr (&tcnt, pre_p, NULL, is_gimple_val,
8348 fb_rvalue) == GS_ERROR)
8349 return 2;
8350 last_iter = TREE_PURPOSE (t);
8351 last_count = tcnt;
8353 if (counts[i] == NULL_TREE)
8354 counts[i] = last_count;
8355 else
8356 counts[i] = size_binop_loc (OMP_CLAUSE_LOCATION (c),
8357 PLUS_EXPR, counts[i], last_count);
8359 else
8360 n[i]++;
8362 for (i = 0; i < 4; i++)
8363 if (counts[i])
8364 break;
8365 if (i == 4)
8366 return 0;
8368 tree total = size_zero_node;
8369 for (i = 0; i < 4; i++)
8371 unused[i] = counts[i] == NULL_TREE && n[i] == 0;
8372 if (counts[i] == NULL_TREE)
8373 counts[i] = size_zero_node;
8374 if (n[i])
8375 counts[i] = size_binop (PLUS_EXPR, counts[i], size_int (n[i]));
8376 if (gimplify_expr (&counts[i], pre_p, NULL, is_gimple_val,
8377 fb_rvalue) == GS_ERROR)
8378 return 2;
8379 total = size_binop (PLUS_EXPR, total, counts[i]);
8382 if (gimplify_expr (&total, pre_p, NULL, is_gimple_val, fb_rvalue)
8383 == GS_ERROR)
8384 return 2;
8385 bool is_old = unused[1] && unused[3];
8386 tree totalpx = size_binop (PLUS_EXPR, unshare_expr (total),
8387 size_int (is_old ? 1 : 4));
8388 tree type = build_array_type (ptr_type_node, build_index_type (totalpx));
8389 tree array = create_tmp_var_raw (type);
8390 TREE_ADDRESSABLE (array) = 1;
8391 if (!poly_int_tree_p (totalpx))
8393 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (array)))
8394 gimplify_type_sizes (TREE_TYPE (array), pre_p);
8395 if (gimplify_omp_ctxp)
8397 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
8398 while (ctx
8399 && (ctx->region_type == ORT_WORKSHARE
8400 || ctx->region_type == ORT_TASKGROUP
8401 || ctx->region_type == ORT_SIMD
8402 || ctx->region_type == ORT_ACC))
8403 ctx = ctx->outer_context;
8404 if (ctx)
8405 omp_add_variable (ctx, array, GOVD_LOCAL | GOVD_SEEN);
8407 gimplify_vla_decl (array, pre_p);
8409 else
8410 gimple_add_tmp_var (array);
8411 tree r = build4 (ARRAY_REF, ptr_type_node, array, size_int (0), NULL_TREE,
8412 NULL_TREE);
8413 tree tem;
8414 if (!is_old)
8416 tem = build2 (MODIFY_EXPR, void_type_node, r,
8417 build_int_cst (ptr_type_node, 0));
8418 gimplify_and_add (tem, pre_p);
8419 r = build4 (ARRAY_REF, ptr_type_node, array, size_int (1), NULL_TREE,
8420 NULL_TREE);
8422 tem = build2 (MODIFY_EXPR, void_type_node, r,
8423 fold_convert (ptr_type_node, total));
8424 gimplify_and_add (tem, pre_p);
8425 for (i = 1; i < (is_old ? 2 : 4); i++)
8427 r = build4 (ARRAY_REF, ptr_type_node, array, size_int (i + !is_old),
8428 NULL_TREE, NULL_TREE);
8429 tem = build2 (MODIFY_EXPR, void_type_node, r, counts[i - 1]);
8430 gimplify_and_add (tem, pre_p);
8433 tree cnts[4];
8434 for (j = 4; j; j--)
8435 if (!unused[j - 1])
8436 break;
8437 for (i = 0; i < 4; i++)
8439 if (i && (i >= j || unused[i - 1]))
8441 cnts[i] = cnts[i - 1];
8442 continue;
8444 cnts[i] = create_tmp_var (sizetype);
8445 if (i == 0)
8446 g = gimple_build_assign (cnts[i], size_int (is_old ? 2 : 5));
8447 else
8449 tree t;
8450 if (is_old)
8451 t = size_binop (PLUS_EXPR, counts[0], size_int (2));
8452 else
8453 t = size_binop (PLUS_EXPR, cnts[i - 1], counts[i - 1]);
8454 if (gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue)
8455 == GS_ERROR)
8456 return 2;
8457 g = gimple_build_assign (cnts[i], t);
8459 gimple_seq_add_stmt (pre_p, g);
8462 last_iter = NULL_TREE;
8463 tree last_bind = NULL_TREE;
8464 tree *last_body = NULL;
8465 for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
8466 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
8468 switch (OMP_CLAUSE_DEPEND_KIND (c))
8470 case OMP_CLAUSE_DEPEND_IN:
8471 i = 2;
8472 break;
8473 case OMP_CLAUSE_DEPEND_OUT:
8474 case OMP_CLAUSE_DEPEND_INOUT:
8475 i = 0;
8476 break;
8477 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
8478 i = 1;
8479 break;
8480 case OMP_CLAUSE_DEPEND_DEPOBJ:
8481 i = 3;
8482 break;
8483 case OMP_CLAUSE_DEPEND_SOURCE:
8484 case OMP_CLAUSE_DEPEND_SINK:
8485 continue;
8486 default:
8487 gcc_unreachable ();
8489 tree t = OMP_CLAUSE_DECL (c);
8490 if (TREE_CODE (t) == TREE_LIST
8491 && TREE_PURPOSE (t)
8492 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
8494 if (TREE_PURPOSE (t) != last_iter)
8496 if (last_bind)
8497 gimplify_and_add (last_bind, pre_p);
8498 tree block = TREE_VEC_ELT (TREE_PURPOSE (t), 5);
8499 last_bind = build3 (BIND_EXPR, void_type_node,
8500 BLOCK_VARS (block), NULL, block);
8501 TREE_SIDE_EFFECTS (last_bind) = 1;
8502 SET_EXPR_LOCATION (last_bind, OMP_CLAUSE_LOCATION (c));
8503 tree *p = &BIND_EXPR_BODY (last_bind);
8504 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8506 tree var = TREE_VEC_ELT (it, 0);
8507 tree begin = TREE_VEC_ELT (it, 1);
8508 tree end = TREE_VEC_ELT (it, 2);
8509 tree step = TREE_VEC_ELT (it, 3);
8510 tree orig_step = TREE_VEC_ELT (it, 4);
8511 tree type = TREE_TYPE (var);
8512 location_t loc = DECL_SOURCE_LOCATION (var);
8513 /* Emit:
8514 var = begin;
8515 goto cond_label;
8516 beg_label:
8518 var = var + step;
8519 cond_label:
8520 if (orig_step > 0) {
8521 if (var < end) goto beg_label;
8522 } else {
8523 if (var > end) goto beg_label;
8525 for each iterator, with inner iterators added to
8526 the ... above. */
8527 tree beg_label = create_artificial_label (loc);
8528 tree cond_label = NULL_TREE;
8529 tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
8530 var, begin);
8531 append_to_statement_list_force (tem, p);
8532 tem = build_and_jump (&cond_label);
8533 append_to_statement_list_force (tem, p);
8534 tem = build1 (LABEL_EXPR, void_type_node, beg_label);
8535 append_to_statement_list (tem, p);
8536 tree bind = build3 (BIND_EXPR, void_type_node, NULL_TREE,
8537 NULL_TREE, NULL_TREE);
8538 TREE_SIDE_EFFECTS (bind) = 1;
8539 SET_EXPR_LOCATION (bind, loc);
8540 append_to_statement_list_force (bind, p);
8541 if (POINTER_TYPE_P (type))
8542 tem = build2_loc (loc, POINTER_PLUS_EXPR, type,
8543 var, fold_convert_loc (loc, sizetype,
8544 step));
8545 else
8546 tem = build2_loc (loc, PLUS_EXPR, type, var, step);
8547 tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
8548 var, tem);
8549 append_to_statement_list_force (tem, p);
8550 tem = build1 (LABEL_EXPR, void_type_node, cond_label);
8551 append_to_statement_list (tem, p);
8552 tree cond = fold_build2_loc (loc, LT_EXPR,
8553 boolean_type_node,
8554 var, end);
8555 tree pos
8556 = fold_build3_loc (loc, COND_EXPR, void_type_node,
8557 cond, build_and_jump (&beg_label),
8558 void_node);
8559 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8560 var, end);
8561 tree neg
8562 = fold_build3_loc (loc, COND_EXPR, void_type_node,
8563 cond, build_and_jump (&beg_label),
8564 void_node);
8565 tree osteptype = TREE_TYPE (orig_step);
8566 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8567 orig_step,
8568 build_int_cst (osteptype, 0));
8569 tem = fold_build3_loc (loc, COND_EXPR, void_type_node,
8570 cond, pos, neg);
8571 append_to_statement_list_force (tem, p);
8572 p = &BIND_EXPR_BODY (bind);
8574 last_body = p;
8576 last_iter = TREE_PURPOSE (t);
8577 if (TREE_CODE (TREE_VALUE (t)) == COMPOUND_EXPR)
8579 append_to_statement_list (TREE_OPERAND (TREE_VALUE (t),
8580 0), last_body);
8581 TREE_VALUE (t) = TREE_OPERAND (TREE_VALUE (t), 1);
8583 if (error_operand_p (TREE_VALUE (t)))
8584 return 2;
8585 TREE_VALUE (t) = build_fold_addr_expr (TREE_VALUE (t));
8586 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
8587 NULL_TREE, NULL_TREE);
8588 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
8589 void_type_node, r, TREE_VALUE (t));
8590 append_to_statement_list_force (tem, last_body);
8591 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
8592 void_type_node, cnts[i],
8593 size_binop (PLUS_EXPR, cnts[i], size_int (1)));
8594 append_to_statement_list_force (tem, last_body);
8595 TREE_VALUE (t) = null_pointer_node;
8597 else
8599 if (last_bind)
8601 gimplify_and_add (last_bind, pre_p);
8602 last_bind = NULL_TREE;
8604 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
8606 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
8607 NULL, is_gimple_val, fb_rvalue);
8608 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
8610 if (error_operand_p (OMP_CLAUSE_DECL (c)))
8611 return 2;
8612 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
8613 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
8614 is_gimple_val, fb_rvalue) == GS_ERROR)
8615 return 2;
8616 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
8617 NULL_TREE, NULL_TREE);
8618 tem = build2 (MODIFY_EXPR, void_type_node, r, OMP_CLAUSE_DECL (c));
8619 gimplify_and_add (tem, pre_p);
8620 g = gimple_build_assign (cnts[i], size_binop (PLUS_EXPR, cnts[i],
8621 size_int (1)));
8622 gimple_seq_add_stmt (pre_p, g);
8625 if (last_bind)
8626 gimplify_and_add (last_bind, pre_p);
8627 tree cond = boolean_false_node;
8628 if (is_old)
8630 if (!unused[0])
8631 cond = build2_loc (first_loc, NE_EXPR, boolean_type_node, cnts[0],
8632 size_binop_loc (first_loc, PLUS_EXPR, counts[0],
8633 size_int (2)));
8634 if (!unused[2])
8635 cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond,
8636 build2_loc (first_loc, NE_EXPR, boolean_type_node,
8637 cnts[2],
8638 size_binop_loc (first_loc, PLUS_EXPR,
8639 totalpx,
8640 size_int (1))));
8642 else
8644 tree prev = size_int (5);
8645 for (i = 0; i < 4; i++)
8647 if (unused[i])
8648 continue;
8649 prev = size_binop_loc (first_loc, PLUS_EXPR, counts[i], prev);
8650 cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond,
8651 build2_loc (first_loc, NE_EXPR, boolean_type_node,
8652 cnts[i], unshare_expr (prev)));
8655 tem = build3_loc (first_loc, COND_EXPR, void_type_node, cond,
8656 build_call_expr_loc (first_loc,
8657 builtin_decl_explicit (BUILT_IN_TRAP),
8658 0), void_node);
8659 gimplify_and_add (tem, pre_p);
8660 c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_DEPEND);
8661 OMP_CLAUSE_DEPEND_KIND (c) = OMP_CLAUSE_DEPEND_LAST;
8662 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (array);
8663 OMP_CLAUSE_CHAIN (c) = *list_p;
8664 *list_p = c;
8665 return 1;
8668 /* Insert a GOMP_MAP_ALLOC or GOMP_MAP_RELEASE node following a
8669 GOMP_MAP_STRUCT mapping. C is an always_pointer mapping. STRUCT_NODE is
8670 the struct node to insert the new mapping after (when the struct node is
8671 initially created). PREV_NODE is the first of two or three mappings for a
8672 pointer, and is either:
8673 - the node before C, when a pair of mappings is used, e.g. for a C/C++
8674 array section.
8675 - not the node before C. This is true when we have a reference-to-pointer
8676 type (with a mapping for the reference and for the pointer), or for
8677 Fortran derived-type mappings with a GOMP_MAP_TO_PSET.
8678 If SCP is non-null, the new node is inserted before *SCP.
8679 if SCP is null, the new node is inserted before PREV_NODE.
8680 The return type is:
8681 - PREV_NODE, if SCP is non-null.
8682 - The newly-created ALLOC or RELEASE node, if SCP is null.
8683 - The second newly-created ALLOC or RELEASE node, if we are mapping a
8684 reference to a pointer. */
8686 static tree
8687 insert_struct_comp_map (enum tree_code code, tree c, tree struct_node,
8688 tree prev_node, tree *scp)
8690 enum gomp_map_kind mkind
8691 = (code == OMP_TARGET_EXIT_DATA || code == OACC_EXIT_DATA)
8692 ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
8694 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
8695 tree cl = scp ? prev_node : c2;
8696 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
8697 OMP_CLAUSE_DECL (c2) = unshare_expr (OMP_CLAUSE_DECL (c));
8698 OMP_CLAUSE_CHAIN (c2) = scp ? *scp : prev_node;
8699 if (OMP_CLAUSE_CHAIN (prev_node) != c
8700 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (prev_node)) == OMP_CLAUSE_MAP
8701 && (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node))
8702 == GOMP_MAP_TO_PSET))
8703 OMP_CLAUSE_SIZE (c2) = OMP_CLAUSE_SIZE (OMP_CLAUSE_CHAIN (prev_node));
8704 else
8705 OMP_CLAUSE_SIZE (c2) = TYPE_SIZE_UNIT (ptr_type_node);
8706 if (struct_node)
8707 OMP_CLAUSE_CHAIN (struct_node) = c2;
8709 /* We might need to create an additional mapping if we have a reference to a
8710 pointer (in C++). Don't do this if we have something other than a
8711 GOMP_MAP_ALWAYS_POINTER though, i.e. a GOMP_MAP_TO_PSET. */
8712 if (OMP_CLAUSE_CHAIN (prev_node) != c
8713 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (prev_node)) == OMP_CLAUSE_MAP
8714 && ((OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node))
8715 == GOMP_MAP_ALWAYS_POINTER)
8716 || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node))
8717 == GOMP_MAP_ATTACH_DETACH)))
8719 tree c4 = OMP_CLAUSE_CHAIN (prev_node);
8720 tree c3 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
8721 OMP_CLAUSE_SET_MAP_KIND (c3, mkind);
8722 OMP_CLAUSE_DECL (c3) = unshare_expr (OMP_CLAUSE_DECL (c4));
8723 OMP_CLAUSE_SIZE (c3) = TYPE_SIZE_UNIT (ptr_type_node);
8724 OMP_CLAUSE_CHAIN (c3) = prev_node;
8725 if (!scp)
8726 OMP_CLAUSE_CHAIN (c2) = c3;
8727 else
8728 cl = c3;
8731 if (scp)
8732 *scp = c2;
8734 return cl;
8737 /* Strip ARRAY_REFS or an indirect ref off BASE, find the containing object,
8738 and set *BITPOSP and *POFFSETP to the bit offset of the access.
8739 If BASE_REF is non-NULL and the containing object is a reference, set
8740 *BASE_REF to that reference before dereferencing the object.
8741 If BASE_REF is NULL, check that the containing object is a COMPONENT_REF or
8742 has array type, else return NULL. */
8744 static tree
8745 extract_base_bit_offset (tree base, tree *base_ref, poly_int64 *bitposp,
8746 poly_offset_int *poffsetp, tree *offsetp)
8748 tree offset;
8749 poly_int64 bitsize, bitpos;
8750 machine_mode mode;
8751 int unsignedp, reversep, volatilep = 0;
8752 poly_offset_int poffset;
8754 if (base_ref)
8756 *base_ref = NULL_TREE;
8758 while (TREE_CODE (base) == ARRAY_REF)
8759 base = TREE_OPERAND (base, 0);
8761 if (TREE_CODE (base) == INDIRECT_REF)
8762 base = TREE_OPERAND (base, 0);
8764 else
8766 if (TREE_CODE (base) == ARRAY_REF)
8768 while (TREE_CODE (base) == ARRAY_REF)
8769 base = TREE_OPERAND (base, 0);
8770 if (TREE_CODE (base) != COMPONENT_REF
8771 || TREE_CODE (TREE_TYPE (base)) != ARRAY_TYPE)
8772 return NULL_TREE;
8774 else if (TREE_CODE (base) == INDIRECT_REF
8775 && TREE_CODE (TREE_OPERAND (base, 0)) == COMPONENT_REF
8776 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0)))
8777 == REFERENCE_TYPE))
8778 base = TREE_OPERAND (base, 0);
8781 base = get_inner_reference (base, &bitsize, &bitpos, &offset, &mode,
8782 &unsignedp, &reversep, &volatilep);
8784 tree orig_base = base;
8786 if ((TREE_CODE (base) == INDIRECT_REF
8787 || (TREE_CODE (base) == MEM_REF
8788 && integer_zerop (TREE_OPERAND (base, 1))))
8789 && DECL_P (TREE_OPERAND (base, 0))
8790 && TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0))) == REFERENCE_TYPE)
8791 base = TREE_OPERAND (base, 0);
8793 if (offset && poly_int_tree_p (offset))
8795 poffset = wi::to_poly_offset (offset);
8796 offset = NULL_TREE;
8798 else
8799 poffset = 0;
8801 if (maybe_ne (bitpos, 0))
8802 poffset += bits_to_bytes_round_down (bitpos);
8804 *bitposp = bitpos;
8805 *poffsetp = poffset;
8806 *offsetp = offset;
8808 /* Set *BASE_REF if BASE was a dereferenced reference variable. */
8809 if (base_ref && orig_base != base)
8810 *base_ref = orig_base;
8812 return base;
8815 /* Returns true if EXPR is or contains (as a sub-component) BASE_PTR. */
8817 static bool
8818 is_or_contains_p (tree expr, tree base_ptr)
8820 if ((TREE_CODE (expr) == INDIRECT_REF && TREE_CODE (base_ptr) == MEM_REF)
8821 || (TREE_CODE (expr) == MEM_REF && TREE_CODE (base_ptr) == INDIRECT_REF))
8822 return operand_equal_p (TREE_OPERAND (expr, 0),
8823 TREE_OPERAND (base_ptr, 0));
8824 while (!operand_equal_p (expr, base_ptr))
8826 if (TREE_CODE (base_ptr) == COMPOUND_EXPR)
8827 base_ptr = TREE_OPERAND (base_ptr, 1);
8828 if (TREE_CODE (base_ptr) == COMPONENT_REF
8829 || TREE_CODE (base_ptr) == POINTER_PLUS_EXPR
8830 || TREE_CODE (base_ptr) == SAVE_EXPR)
8831 base_ptr = TREE_OPERAND (base_ptr, 0);
8832 else
8833 break;
8835 return operand_equal_p (expr, base_ptr);
8838 /* Implement OpenMP 5.x map ordering rules for target directives. There are
8839 several rules, and with some level of ambiguity, hopefully we can at least
8840 collect the complexity here in one place. */
8842 static void
8843 omp_target_reorder_clauses (tree *list_p)
8845 /* Collect refs to alloc/release/delete maps. */
8846 auto_vec<tree, 32> ard;
8847 tree *cp = list_p;
8848 while (*cp != NULL_TREE)
8849 if (OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP
8850 && (OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_ALLOC
8851 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_RELEASE
8852 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_DELETE))
8854 /* Unlink cp and push to ard. */
8855 tree c = *cp;
8856 tree nc = OMP_CLAUSE_CHAIN (c);
8857 *cp = nc;
8858 ard.safe_push (c);
8860 /* Any associated pointer type maps should also move along. */
8861 while (*cp != NULL_TREE
8862 && OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP
8863 && (OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
8864 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_FIRSTPRIVATE_POINTER
8865 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_ATTACH_DETACH
8866 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_POINTER
8867 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_ALWAYS_POINTER
8868 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_TO_PSET))
8870 c = *cp;
8871 nc = OMP_CLAUSE_CHAIN (c);
8872 *cp = nc;
8873 ard.safe_push (c);
8876 else
8877 cp = &OMP_CLAUSE_CHAIN (*cp);
8879 /* Link alloc/release/delete maps to the end of list. */
8880 for (unsigned int i = 0; i < ard.length (); i++)
8882 *cp = ard[i];
8883 cp = &OMP_CLAUSE_CHAIN (ard[i]);
8885 *cp = NULL_TREE;
8887 /* OpenMP 5.0 requires that pointer variables are mapped before
8888 its use as a base-pointer. */
8889 auto_vec<tree *, 32> atf;
8890 for (tree *cp = list_p; *cp; cp = &OMP_CLAUSE_CHAIN (*cp))
8891 if (OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP)
8893 /* Collect alloc, to, from, to/from clause tree pointers. */
8894 gomp_map_kind k = OMP_CLAUSE_MAP_KIND (*cp);
8895 if (k == GOMP_MAP_ALLOC
8896 || k == GOMP_MAP_TO
8897 || k == GOMP_MAP_FROM
8898 || k == GOMP_MAP_TOFROM
8899 || k == GOMP_MAP_ALWAYS_TO
8900 || k == GOMP_MAP_ALWAYS_FROM
8901 || k == GOMP_MAP_ALWAYS_TOFROM)
8902 atf.safe_push (cp);
8905 for (unsigned int i = 0; i < atf.length (); i++)
8906 if (atf[i])
8908 tree *cp = atf[i];
8909 tree decl = OMP_CLAUSE_DECL (*cp);
8910 if (TREE_CODE (decl) == INDIRECT_REF || TREE_CODE (decl) == MEM_REF)
8912 tree base_ptr = TREE_OPERAND (decl, 0);
8913 STRIP_TYPE_NOPS (base_ptr);
8914 for (unsigned int j = i + 1; j < atf.length (); j++)
8915 if (atf[j])
8917 tree *cp2 = atf[j];
8918 tree decl2 = OMP_CLAUSE_DECL (*cp2);
8920 decl2 = OMP_CLAUSE_DECL (*cp2);
8921 if (is_or_contains_p (decl2, base_ptr))
8923 /* Move *cp2 to before *cp. */
8924 tree c = *cp2;
8925 *cp2 = OMP_CLAUSE_CHAIN (c);
8926 OMP_CLAUSE_CHAIN (c) = *cp;
8927 *cp = c;
8929 if (*cp2 != NULL_TREE
8930 && OMP_CLAUSE_CODE (*cp2) == OMP_CLAUSE_MAP
8931 && OMP_CLAUSE_MAP_KIND (*cp2) == GOMP_MAP_ALWAYS_POINTER)
8933 tree c2 = *cp2;
8934 *cp2 = OMP_CLAUSE_CHAIN (c2);
8935 OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (c);
8936 OMP_CLAUSE_CHAIN (c) = c2;
8939 atf[j] = NULL;
8945 /* For attach_detach map clauses, if there is another map that maps the
8946 attached/detached pointer, make sure that map is ordered before the
8947 attach_detach. */
8948 atf.truncate (0);
8949 for (tree *cp = list_p; *cp; cp = &OMP_CLAUSE_CHAIN (*cp))
8950 if (OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP)
8952 /* Collect alloc, to, from, to/from clauses, and
8953 always_pointer/attach_detach clauses. */
8954 gomp_map_kind k = OMP_CLAUSE_MAP_KIND (*cp);
8955 if (k == GOMP_MAP_ALLOC
8956 || k == GOMP_MAP_TO
8957 || k == GOMP_MAP_FROM
8958 || k == GOMP_MAP_TOFROM
8959 || k == GOMP_MAP_ALWAYS_TO
8960 || k == GOMP_MAP_ALWAYS_FROM
8961 || k == GOMP_MAP_ALWAYS_TOFROM
8962 || k == GOMP_MAP_ATTACH_DETACH
8963 || k == GOMP_MAP_ALWAYS_POINTER)
8964 atf.safe_push (cp);
8967 for (unsigned int i = 0; i < atf.length (); i++)
8968 if (atf[i])
8970 tree *cp = atf[i];
8971 tree ptr = OMP_CLAUSE_DECL (*cp);
8972 STRIP_TYPE_NOPS (ptr);
8973 if (OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_ATTACH_DETACH)
8974 for (unsigned int j = i + 1; j < atf.length (); j++)
8976 tree *cp2 = atf[j];
8977 tree decl2 = OMP_CLAUSE_DECL (*cp2);
8978 if (OMP_CLAUSE_MAP_KIND (*cp2) != GOMP_MAP_ATTACH_DETACH
8979 && OMP_CLAUSE_MAP_KIND (*cp2) != GOMP_MAP_ALWAYS_POINTER
8980 && is_or_contains_p (decl2, ptr))
8982 /* Move *cp2 to before *cp. */
8983 tree c = *cp2;
8984 *cp2 = OMP_CLAUSE_CHAIN (c);
8985 OMP_CLAUSE_CHAIN (c) = *cp;
8986 *cp = c;
8987 atf[j] = NULL;
8989 /* If decl2 is of the form '*decl2_opnd0', and followed by an
8990 ALWAYS_POINTER or ATTACH_DETACH of 'decl2_opnd0', move the
8991 pointer operation along with *cp2. This can happen for C++
8992 reference sequences. */
8993 if (j + 1 < atf.length ()
8994 && (TREE_CODE (decl2) == INDIRECT_REF
8995 || TREE_CODE (decl2) == MEM_REF))
8997 tree *cp3 = atf[j + 1];
8998 tree decl3 = OMP_CLAUSE_DECL (*cp3);
8999 tree decl2_opnd0 = TREE_OPERAND (decl2, 0);
9000 if ((OMP_CLAUSE_MAP_KIND (*cp3) == GOMP_MAP_ALWAYS_POINTER
9001 || OMP_CLAUSE_MAP_KIND (*cp3) == GOMP_MAP_ATTACH_DETACH)
9002 && operand_equal_p (decl3, decl2_opnd0))
9004 /* Also move *cp3 to before *cp. */
9005 c = *cp3;
9006 *cp2 = OMP_CLAUSE_CHAIN (c);
9007 OMP_CLAUSE_CHAIN (c) = *cp;
9008 *cp = c;
9009 atf[j + 1] = NULL;
9010 j += 1;
9018 /* DECL is supposed to have lastprivate semantics in the outer contexts
9019 of combined/composite constructs, starting with OCTX.
9020 Add needed lastprivate, shared or map clause if no data sharing or
9021 mapping clause are present. IMPLICIT_P is true if it is an implicit
9022 clause (IV on simd), in which case the lastprivate will not be
9023 copied to some constructs. */
9025 static void
9026 omp_lastprivate_for_combined_outer_constructs (struct gimplify_omp_ctx *octx,
9027 tree decl, bool implicit_p)
9029 struct gimplify_omp_ctx *orig_octx = octx;
9030 for (; octx; octx = octx->outer_context)
9032 if ((octx->region_type == ORT_COMBINED_PARALLEL
9033 || (octx->region_type & ORT_COMBINED_TEAMS) == ORT_COMBINED_TEAMS)
9034 && splay_tree_lookup (octx->variables,
9035 (splay_tree_key) decl) == NULL)
9037 omp_add_variable (octx, decl, GOVD_SHARED | GOVD_SEEN);
9038 continue;
9040 if ((octx->region_type & ORT_TASK) != 0
9041 && octx->combined_loop
9042 && splay_tree_lookup (octx->variables,
9043 (splay_tree_key) decl) == NULL)
9045 omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
9046 continue;
9048 if (implicit_p
9049 && octx->region_type == ORT_WORKSHARE
9050 && octx->combined_loop
9051 && splay_tree_lookup (octx->variables,
9052 (splay_tree_key) decl) == NULL
9053 && octx->outer_context
9054 && octx->outer_context->region_type == ORT_COMBINED_PARALLEL
9055 && splay_tree_lookup (octx->outer_context->variables,
9056 (splay_tree_key) decl) == NULL)
9058 octx = octx->outer_context;
9059 omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
9060 continue;
9062 if ((octx->region_type == ORT_WORKSHARE || octx->region_type == ORT_ACC)
9063 && octx->combined_loop
9064 && splay_tree_lookup (octx->variables,
9065 (splay_tree_key) decl) == NULL
9066 && !omp_check_private (octx, decl, false))
9068 omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
9069 continue;
9071 if (octx->region_type == ORT_COMBINED_TARGET)
9073 splay_tree_node n = splay_tree_lookup (octx->variables,
9074 (splay_tree_key) decl);
9075 if (n == NULL)
9077 omp_add_variable (octx, decl, GOVD_MAP | GOVD_SEEN);
9078 octx = octx->outer_context;
9080 else if (!implicit_p
9081 && (n->value & GOVD_FIRSTPRIVATE_IMPLICIT))
9083 n->value &= ~(GOVD_FIRSTPRIVATE
9084 | GOVD_FIRSTPRIVATE_IMPLICIT
9085 | GOVD_EXPLICIT);
9086 omp_add_variable (octx, decl, GOVD_MAP | GOVD_SEEN);
9087 octx = octx->outer_context;
9090 break;
9092 if (octx && (implicit_p || octx != orig_octx))
9093 omp_notice_variable (octx, decl, true);
9096 /* Scan the OMP clauses in *LIST_P, installing mappings into a new
9097 and previous omp contexts. */
9099 static void
9100 gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
9101 enum omp_region_type region_type,
9102 enum tree_code code)
9104 struct gimplify_omp_ctx *ctx, *outer_ctx;
9105 tree c;
9106 hash_map<tree_operand_hash, tree> *struct_map_to_clause = NULL;
9107 hash_map<tree_operand_hash, tree *> *struct_seen_clause = NULL;
9108 hash_set<tree> *struct_deref_set = NULL;
9109 tree *prev_list_p = NULL, *orig_list_p = list_p;
9110 int handled_depend_iterators = -1;
9111 int nowait = -1;
9113 ctx = new_omp_context (region_type);
9114 ctx->code = code;
9115 outer_ctx = ctx->outer_context;
9116 if (code == OMP_TARGET)
9118 if (!lang_GNU_Fortran ())
9119 ctx->defaultmap[GDMK_POINTER] = GOVD_MAP | GOVD_MAP_0LEN_ARRAY;
9120 ctx->defaultmap[GDMK_SCALAR] = GOVD_FIRSTPRIVATE;
9121 ctx->defaultmap[GDMK_SCALAR_TARGET] = (lang_GNU_Fortran ()
9122 ? GOVD_MAP : GOVD_FIRSTPRIVATE);
9124 if (!lang_GNU_Fortran ())
9125 switch (code)
9127 case OMP_TARGET:
9128 case OMP_TARGET_DATA:
9129 case OMP_TARGET_ENTER_DATA:
9130 case OMP_TARGET_EXIT_DATA:
9131 case OACC_DECLARE:
9132 case OACC_HOST_DATA:
9133 case OACC_PARALLEL:
9134 case OACC_KERNELS:
9135 ctx->target_firstprivatize_array_bases = true;
9136 default:
9137 break;
9140 if (code == OMP_TARGET
9141 || code == OMP_TARGET_DATA
9142 || code == OMP_TARGET_ENTER_DATA
9143 || code == OMP_TARGET_EXIT_DATA)
9144 omp_target_reorder_clauses (list_p);
9146 while ((c = *list_p) != NULL)
9148 bool remove = false;
9149 bool notice_outer = true;
9150 const char *check_non_private = NULL;
9151 unsigned int flags;
9152 tree decl;
9154 switch (OMP_CLAUSE_CODE (c))
9156 case OMP_CLAUSE_PRIVATE:
9157 flags = GOVD_PRIVATE | GOVD_EXPLICIT;
9158 if (lang_hooks.decls.omp_private_outer_ref (OMP_CLAUSE_DECL (c)))
9160 flags |= GOVD_PRIVATE_OUTER_REF;
9161 OMP_CLAUSE_PRIVATE_OUTER_REF (c) = 1;
9163 else
9164 notice_outer = false;
9165 goto do_add;
9166 case OMP_CLAUSE_SHARED:
9167 flags = GOVD_SHARED | GOVD_EXPLICIT;
9168 goto do_add;
9169 case OMP_CLAUSE_FIRSTPRIVATE:
9170 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
9171 check_non_private = "firstprivate";
9172 if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c))
9174 gcc_assert (code == OMP_TARGET);
9175 flags |= GOVD_FIRSTPRIVATE_IMPLICIT;
9177 goto do_add;
9178 case OMP_CLAUSE_LASTPRIVATE:
9179 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
9180 switch (code)
9182 case OMP_DISTRIBUTE:
9183 error_at (OMP_CLAUSE_LOCATION (c),
9184 "conditional %<lastprivate%> clause on "
9185 "%qs construct", "distribute");
9186 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
9187 break;
9188 case OMP_TASKLOOP:
9189 error_at (OMP_CLAUSE_LOCATION (c),
9190 "conditional %<lastprivate%> clause on "
9191 "%qs construct", "taskloop");
9192 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
9193 break;
9194 default:
9195 break;
9197 flags = GOVD_LASTPRIVATE | GOVD_SEEN | GOVD_EXPLICIT;
9198 if (code != OMP_LOOP)
9199 check_non_private = "lastprivate";
9200 decl = OMP_CLAUSE_DECL (c);
9201 if (error_operand_p (decl))
9202 goto do_add;
9203 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)
9204 && !lang_hooks.decls.omp_scalar_p (decl, true))
9206 error_at (OMP_CLAUSE_LOCATION (c),
9207 "non-scalar variable %qD in conditional "
9208 "%<lastprivate%> clause", decl);
9209 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
9211 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
9212 flags |= GOVD_LASTPRIVATE_CONDITIONAL;
9213 omp_lastprivate_for_combined_outer_constructs (outer_ctx, decl,
9214 false);
9215 goto do_add;
9216 case OMP_CLAUSE_REDUCTION:
9217 if (OMP_CLAUSE_REDUCTION_TASK (c))
9219 if (region_type == ORT_WORKSHARE || code == OMP_SCOPE)
9221 if (nowait == -1)
9222 nowait = omp_find_clause (*list_p,
9223 OMP_CLAUSE_NOWAIT) != NULL_TREE;
9224 if (nowait
9225 && (outer_ctx == NULL
9226 || outer_ctx->region_type != ORT_COMBINED_PARALLEL))
9228 error_at (OMP_CLAUSE_LOCATION (c),
9229 "%<task%> reduction modifier on a construct "
9230 "with a %<nowait%> clause");
9231 OMP_CLAUSE_REDUCTION_TASK (c) = 0;
9234 else if ((region_type & ORT_PARALLEL) != ORT_PARALLEL)
9236 error_at (OMP_CLAUSE_LOCATION (c),
9237 "invalid %<task%> reduction modifier on construct "
9238 "other than %<parallel%>, %qs, %<sections%> or "
9239 "%<scope%>", lang_GNU_Fortran () ? "do" : "for");
9240 OMP_CLAUSE_REDUCTION_TASK (c) = 0;
9243 if (OMP_CLAUSE_REDUCTION_INSCAN (c))
9244 switch (code)
9246 case OMP_SECTIONS:
9247 error_at (OMP_CLAUSE_LOCATION (c),
9248 "%<inscan%> %<reduction%> clause on "
9249 "%qs construct", "sections");
9250 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
9251 break;
9252 case OMP_PARALLEL:
9253 error_at (OMP_CLAUSE_LOCATION (c),
9254 "%<inscan%> %<reduction%> clause on "
9255 "%qs construct", "parallel");
9256 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
9257 break;
9258 case OMP_TEAMS:
9259 error_at (OMP_CLAUSE_LOCATION (c),
9260 "%<inscan%> %<reduction%> clause on "
9261 "%qs construct", "teams");
9262 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
9263 break;
9264 case OMP_TASKLOOP:
9265 error_at (OMP_CLAUSE_LOCATION (c),
9266 "%<inscan%> %<reduction%> clause on "
9267 "%qs construct", "taskloop");
9268 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
9269 break;
9270 case OMP_SCOPE:
9271 error_at (OMP_CLAUSE_LOCATION (c),
9272 "%<inscan%> %<reduction%> clause on "
9273 "%qs construct", "scope");
9274 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
9275 break;
9276 default:
9277 break;
9279 /* FALLTHRU */
9280 case OMP_CLAUSE_IN_REDUCTION:
9281 case OMP_CLAUSE_TASK_REDUCTION:
9282 flags = GOVD_REDUCTION | GOVD_SEEN | GOVD_EXPLICIT;
9283 /* OpenACC permits reductions on private variables. */
9284 if (!(region_type & ORT_ACC)
9285 /* taskgroup is actually not a worksharing region. */
9286 && code != OMP_TASKGROUP)
9287 check_non_private = omp_clause_code_name[OMP_CLAUSE_CODE (c)];
9288 decl = OMP_CLAUSE_DECL (c);
9289 if (TREE_CODE (decl) == MEM_REF)
9291 tree type = TREE_TYPE (decl);
9292 bool saved_into_ssa = gimplify_ctxp->into_ssa;
9293 gimplify_ctxp->into_ssa = false;
9294 if (gimplify_expr (&TYPE_MAX_VALUE (TYPE_DOMAIN (type)), pre_p,
9295 NULL, is_gimple_val, fb_rvalue, false)
9296 == GS_ERROR)
9298 gimplify_ctxp->into_ssa = saved_into_ssa;
9299 remove = true;
9300 break;
9302 gimplify_ctxp->into_ssa = saved_into_ssa;
9303 tree v = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
9304 if (DECL_P (v))
9306 omp_firstprivatize_variable (ctx, v);
9307 omp_notice_variable (ctx, v, true);
9309 decl = TREE_OPERAND (decl, 0);
9310 if (TREE_CODE (decl) == POINTER_PLUS_EXPR)
9312 gimplify_ctxp->into_ssa = false;
9313 if (gimplify_expr (&TREE_OPERAND (decl, 1), pre_p,
9314 NULL, is_gimple_val, fb_rvalue, false)
9315 == GS_ERROR)
9317 gimplify_ctxp->into_ssa = saved_into_ssa;
9318 remove = true;
9319 break;
9321 gimplify_ctxp->into_ssa = saved_into_ssa;
9322 v = TREE_OPERAND (decl, 1);
9323 if (DECL_P (v))
9325 omp_firstprivatize_variable (ctx, v);
9326 omp_notice_variable (ctx, v, true);
9328 decl = TREE_OPERAND (decl, 0);
9330 if (TREE_CODE (decl) == ADDR_EXPR
9331 || TREE_CODE (decl) == INDIRECT_REF)
9332 decl = TREE_OPERAND (decl, 0);
9334 goto do_add_decl;
9335 case OMP_CLAUSE_LINEAR:
9336 if (gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c), pre_p, NULL,
9337 is_gimple_val, fb_rvalue) == GS_ERROR)
9339 remove = true;
9340 break;
9342 else
9344 if (code == OMP_SIMD
9345 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
9347 struct gimplify_omp_ctx *octx = outer_ctx;
9348 if (octx
9349 && octx->region_type == ORT_WORKSHARE
9350 && octx->combined_loop
9351 && !octx->distribute)
9353 if (octx->outer_context
9354 && (octx->outer_context->region_type
9355 == ORT_COMBINED_PARALLEL))
9356 octx = octx->outer_context->outer_context;
9357 else
9358 octx = octx->outer_context;
9360 if (octx
9361 && octx->region_type == ORT_WORKSHARE
9362 && octx->combined_loop
9363 && octx->distribute)
9365 error_at (OMP_CLAUSE_LOCATION (c),
9366 "%<linear%> clause for variable other than "
9367 "loop iterator specified on construct "
9368 "combined with %<distribute%>");
9369 remove = true;
9370 break;
9373 /* For combined #pragma omp parallel for simd, need to put
9374 lastprivate and perhaps firstprivate too on the
9375 parallel. Similarly for #pragma omp for simd. */
9376 struct gimplify_omp_ctx *octx = outer_ctx;
9377 bool taskloop_seen = false;
9378 decl = NULL_TREE;
9381 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
9382 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
9383 break;
9384 decl = OMP_CLAUSE_DECL (c);
9385 if (error_operand_p (decl))
9387 decl = NULL_TREE;
9388 break;
9390 flags = GOVD_SEEN;
9391 if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c))
9392 flags |= GOVD_FIRSTPRIVATE;
9393 if (!OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
9394 flags |= GOVD_LASTPRIVATE;
9395 if (octx
9396 && octx->region_type == ORT_WORKSHARE
9397 && octx->combined_loop)
9399 if (octx->outer_context
9400 && (octx->outer_context->region_type
9401 == ORT_COMBINED_PARALLEL))
9402 octx = octx->outer_context;
9403 else if (omp_check_private (octx, decl, false))
9404 break;
9406 else if (octx
9407 && (octx->region_type & ORT_TASK) != 0
9408 && octx->combined_loop)
9409 taskloop_seen = true;
9410 else if (octx
9411 && octx->region_type == ORT_COMBINED_PARALLEL
9412 && ((ctx->region_type == ORT_WORKSHARE
9413 && octx == outer_ctx)
9414 || taskloop_seen))
9415 flags = GOVD_SEEN | GOVD_SHARED;
9416 else if (octx
9417 && ((octx->region_type & ORT_COMBINED_TEAMS)
9418 == ORT_COMBINED_TEAMS))
9419 flags = GOVD_SEEN | GOVD_SHARED;
9420 else if (octx
9421 && octx->region_type == ORT_COMBINED_TARGET)
9423 if (flags & GOVD_LASTPRIVATE)
9424 flags = GOVD_SEEN | GOVD_MAP;
9426 else
9427 break;
9428 splay_tree_node on
9429 = splay_tree_lookup (octx->variables,
9430 (splay_tree_key) decl);
9431 if (on && (on->value & GOVD_DATA_SHARE_CLASS) != 0)
9433 octx = NULL;
9434 break;
9436 omp_add_variable (octx, decl, flags);
9437 if (octx->outer_context == NULL)
9438 break;
9439 octx = octx->outer_context;
9441 while (1);
9442 if (octx
9443 && decl
9444 && (!OMP_CLAUSE_LINEAR_NO_COPYIN (c)
9445 || !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
9446 omp_notice_variable (octx, decl, true);
9448 flags = GOVD_LINEAR | GOVD_EXPLICIT;
9449 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
9450 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
9452 notice_outer = false;
9453 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
9455 goto do_add;
9457 case OMP_CLAUSE_MAP:
9458 decl = OMP_CLAUSE_DECL (c);
9459 if (error_operand_p (decl))
9460 remove = true;
9461 switch (code)
9463 case OMP_TARGET:
9464 break;
9465 case OACC_DATA:
9466 if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
9467 break;
9468 /* FALLTHRU */
9469 case OMP_TARGET_DATA:
9470 case OMP_TARGET_ENTER_DATA:
9471 case OMP_TARGET_EXIT_DATA:
9472 case OACC_ENTER_DATA:
9473 case OACC_EXIT_DATA:
9474 case OACC_HOST_DATA:
9475 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
9476 || (OMP_CLAUSE_MAP_KIND (c)
9477 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
9478 /* For target {,enter ,exit }data only the array slice is
9479 mapped, but not the pointer to it. */
9480 remove = true;
9481 break;
9482 default:
9483 break;
9485 /* For Fortran, not only the pointer to the data is mapped but also
9486 the address of the pointer, the array descriptor etc.; for
9487 'exit data' - and in particular for 'delete:' - having an 'alloc:'
9488 does not make sense. Likewise, for 'update' only transferring the
9489 data itself is needed as the rest has been handled in previous
9490 directives. However, for 'exit data', the array descriptor needs
9491 to be delete; hence, we turn the MAP_TO_PSET into a MAP_DELETE.
9493 NOTE: Generally, it is not safe to perform "enter data" operations
9494 on arrays where the data *or the descriptor* may go out of scope
9495 before a corresponding "exit data" operation -- and such a
9496 descriptor may be synthesized temporarily, e.g. to pass an
9497 explicit-shape array to a function expecting an assumed-shape
9498 argument. Performing "enter data" inside the called function
9499 would thus be problematic. */
9500 if (code == OMP_TARGET_EXIT_DATA
9501 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_TO_PSET)
9502 OMP_CLAUSE_SET_MAP_KIND (c, OMP_CLAUSE_MAP_KIND (*prev_list_p)
9503 == GOMP_MAP_DELETE
9504 ? GOMP_MAP_DELETE : GOMP_MAP_RELEASE);
9505 else if ((code == OMP_TARGET_EXIT_DATA || code == OMP_TARGET_UPDATE)
9506 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
9507 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_TO_PSET))
9508 remove = true;
9510 if (remove)
9511 break;
9512 if (DECL_P (decl) && outer_ctx && (region_type & ORT_ACC))
9514 struct gimplify_omp_ctx *octx;
9515 for (octx = outer_ctx; octx; octx = octx->outer_context)
9517 if (octx->region_type != ORT_ACC_HOST_DATA)
9518 break;
9519 splay_tree_node n2
9520 = splay_tree_lookup (octx->variables,
9521 (splay_tree_key) decl);
9522 if (n2)
9523 error_at (OMP_CLAUSE_LOCATION (c), "variable %qE "
9524 "declared in enclosing %<host_data%> region",
9525 DECL_NAME (decl));
9528 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
9529 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
9530 : TYPE_SIZE_UNIT (TREE_TYPE (decl));
9531 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
9532 NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
9534 remove = true;
9535 break;
9537 else if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
9538 || (OMP_CLAUSE_MAP_KIND (c)
9539 == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
9540 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
9541 && TREE_CODE (OMP_CLAUSE_SIZE (c)) != INTEGER_CST)
9543 OMP_CLAUSE_SIZE (c)
9544 = get_initialized_tmp_var (OMP_CLAUSE_SIZE (c), pre_p, NULL,
9545 false);
9546 if ((region_type & ORT_TARGET) != 0)
9547 omp_add_variable (ctx, OMP_CLAUSE_SIZE (c),
9548 GOVD_FIRSTPRIVATE | GOVD_SEEN);
9551 if (TREE_CODE (decl) == TARGET_EXPR)
9553 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
9554 is_gimple_lvalue, fb_lvalue)
9555 == GS_ERROR)
9556 remove = true;
9558 else if (!DECL_P (decl))
9560 tree d = decl, *pd;
9561 if (TREE_CODE (d) == ARRAY_REF)
9563 while (TREE_CODE (d) == ARRAY_REF)
9564 d = TREE_OPERAND (d, 0);
9565 if (TREE_CODE (d) == COMPONENT_REF
9566 && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE)
9567 decl = d;
9569 pd = &OMP_CLAUSE_DECL (c);
9570 if (d == decl
9571 && TREE_CODE (decl) == INDIRECT_REF
9572 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
9573 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
9574 == REFERENCE_TYPE)
9575 && (OMP_CLAUSE_MAP_KIND (c)
9576 != GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION))
9578 pd = &TREE_OPERAND (decl, 0);
9579 decl = TREE_OPERAND (decl, 0);
9581 bool indir_p = false;
9582 bool component_ref_p = false;
9583 tree indir_base = NULL_TREE;
9584 tree orig_decl = decl;
9585 tree decl_ref = NULL_TREE;
9586 if ((region_type & (ORT_ACC | ORT_TARGET | ORT_TARGET_DATA)) != 0
9587 && TREE_CODE (*pd) == COMPONENT_REF
9588 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH
9589 && code != OACC_UPDATE)
9591 while (TREE_CODE (decl) == COMPONENT_REF)
9593 decl = TREE_OPERAND (decl, 0);
9594 component_ref_p = true;
9595 if (((TREE_CODE (decl) == MEM_REF
9596 && integer_zerop (TREE_OPERAND (decl, 1)))
9597 || INDIRECT_REF_P (decl))
9598 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
9599 == POINTER_TYPE))
9601 indir_p = true;
9602 indir_base = decl;
9603 decl = TREE_OPERAND (decl, 0);
9604 STRIP_NOPS (decl);
9606 if (TREE_CODE (decl) == INDIRECT_REF
9607 && DECL_P (TREE_OPERAND (decl, 0))
9608 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
9609 == REFERENCE_TYPE))
9611 decl_ref = decl;
9612 decl = TREE_OPERAND (decl, 0);
9616 else if (TREE_CODE (decl) == COMPONENT_REF
9617 && (OMP_CLAUSE_MAP_KIND (c)
9618 != GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION))
9620 component_ref_p = true;
9621 while (TREE_CODE (decl) == COMPONENT_REF)
9622 decl = TREE_OPERAND (decl, 0);
9623 if (TREE_CODE (decl) == INDIRECT_REF
9624 && DECL_P (TREE_OPERAND (decl, 0))
9625 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
9626 == REFERENCE_TYPE))
9627 decl = TREE_OPERAND (decl, 0);
9629 if (decl != orig_decl && DECL_P (decl) && indir_p
9630 && (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
9631 || (decl_ref
9632 && TREE_CODE (TREE_TYPE (decl_ref)) == POINTER_TYPE)))
9634 gomp_map_kind k
9635 = ((code == OACC_EXIT_DATA || code == OMP_TARGET_EXIT_DATA)
9636 ? GOMP_MAP_DETACH : GOMP_MAP_ATTACH);
9637 /* We have a dereference of a struct member. Make this an
9638 attach/detach operation, and ensure the base pointer is
9639 mapped as a FIRSTPRIVATE_POINTER. */
9640 OMP_CLAUSE_SET_MAP_KIND (c, k);
9641 flags = GOVD_MAP | GOVD_SEEN | GOVD_EXPLICIT;
9642 tree next_clause = OMP_CLAUSE_CHAIN (c);
9643 if (k == GOMP_MAP_ATTACH
9644 && code != OACC_ENTER_DATA
9645 && code != OMP_TARGET_ENTER_DATA
9646 && (!next_clause
9647 || (OMP_CLAUSE_CODE (next_clause) != OMP_CLAUSE_MAP)
9648 || (OMP_CLAUSE_MAP_KIND (next_clause)
9649 != GOMP_MAP_POINTER)
9650 || OMP_CLAUSE_DECL (next_clause) != decl)
9651 && (!struct_deref_set
9652 || !struct_deref_set->contains (decl))
9653 && (!struct_map_to_clause
9654 || !struct_map_to_clause->get (indir_base)))
9656 if (!struct_deref_set)
9657 struct_deref_set = new hash_set<tree> ();
9658 /* As well as the attach, we also need a
9659 FIRSTPRIVATE_POINTER clause to properly map the
9660 pointer to the struct base. */
9661 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9662 OMP_CLAUSE_MAP);
9663 OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_ALLOC);
9664 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (c2)
9665 = 1;
9666 tree charptr_zero
9667 = build_int_cst (build_pointer_type (char_type_node),
9669 OMP_CLAUSE_DECL (c2)
9670 = build2 (MEM_REF, char_type_node,
9671 decl_ref ? decl_ref : decl, charptr_zero);
9672 OMP_CLAUSE_SIZE (c2) = size_zero_node;
9673 tree c3 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9674 OMP_CLAUSE_MAP);
9675 OMP_CLAUSE_SET_MAP_KIND (c3,
9676 GOMP_MAP_FIRSTPRIVATE_POINTER);
9677 OMP_CLAUSE_DECL (c3) = decl;
9678 OMP_CLAUSE_SIZE (c3) = size_zero_node;
9679 tree mapgrp = *prev_list_p;
9680 *prev_list_p = c2;
9681 OMP_CLAUSE_CHAIN (c3) = mapgrp;
9682 OMP_CLAUSE_CHAIN (c2) = c3;
9684 struct_deref_set->add (decl);
9686 goto do_add_decl;
9688 /* An "attach/detach" operation on an update directive should
9689 behave as a GOMP_MAP_ALWAYS_POINTER. Beware that
9690 unlike attach or detach map kinds, GOMP_MAP_ALWAYS_POINTER
9691 depends on the previous mapping. */
9692 if (code == OACC_UPDATE
9693 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
9694 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_ALWAYS_POINTER);
9695 if ((DECL_P (decl)
9696 || (component_ref_p
9697 && (INDIRECT_REF_P (decl)
9698 || TREE_CODE (decl) == MEM_REF
9699 || TREE_CODE (decl) == ARRAY_REF)))
9700 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_TO_PSET
9701 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH
9702 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_DETACH
9703 && code != OACC_UPDATE
9704 && code != OMP_TARGET_UPDATE)
9706 if (error_operand_p (decl))
9708 remove = true;
9709 break;
9712 tree stype = TREE_TYPE (decl);
9713 if (TREE_CODE (stype) == REFERENCE_TYPE)
9714 stype = TREE_TYPE (stype);
9715 if (TYPE_SIZE_UNIT (stype) == NULL
9716 || TREE_CODE (TYPE_SIZE_UNIT (stype)) != INTEGER_CST)
9718 error_at (OMP_CLAUSE_LOCATION (c),
9719 "mapping field %qE of variable length "
9720 "structure", OMP_CLAUSE_DECL (c));
9721 remove = true;
9722 break;
9725 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER
9726 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
9728 /* Error recovery. */
9729 if (prev_list_p == NULL)
9731 remove = true;
9732 break;
9735 /* The below prev_list_p based error recovery code is
9736 currently no longer valid for OpenMP. */
9737 if (code != OMP_TARGET
9738 && code != OMP_TARGET_DATA
9739 && code != OMP_TARGET_UPDATE
9740 && code != OMP_TARGET_ENTER_DATA
9741 && code != OMP_TARGET_EXIT_DATA
9742 && OMP_CLAUSE_CHAIN (*prev_list_p) != c)
9744 tree ch = OMP_CLAUSE_CHAIN (*prev_list_p);
9745 if (ch == NULL_TREE || OMP_CLAUSE_CHAIN (ch) != c)
9747 remove = true;
9748 break;
9753 poly_offset_int offset1;
9754 poly_int64 bitpos1;
9755 tree tree_offset1;
9756 tree base_ref;
9758 tree base
9759 = extract_base_bit_offset (OMP_CLAUSE_DECL (c), &base_ref,
9760 &bitpos1, &offset1,
9761 &tree_offset1);
9763 bool do_map_struct = (base == decl && !tree_offset1);
9765 splay_tree_node n
9766 = (DECL_P (decl)
9767 ? splay_tree_lookup (ctx->variables,
9768 (splay_tree_key) decl)
9769 : NULL);
9770 bool ptr = (OMP_CLAUSE_MAP_KIND (c)
9771 == GOMP_MAP_ALWAYS_POINTER);
9772 bool attach_detach = (OMP_CLAUSE_MAP_KIND (c)
9773 == GOMP_MAP_ATTACH_DETACH);
9774 bool attach = OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
9775 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH;
9776 bool has_attachments = false;
9777 /* For OpenACC, pointers in structs should trigger an
9778 attach action. */
9779 if (attach_detach
9780 && ((region_type & (ORT_ACC | ORT_TARGET | ORT_TARGET_DATA))
9781 || code == OMP_TARGET_ENTER_DATA
9782 || code == OMP_TARGET_EXIT_DATA))
9785 /* Turn a GOMP_MAP_ATTACH_DETACH clause into a
9786 GOMP_MAP_ATTACH or GOMP_MAP_DETACH clause after we
9787 have detected a case that needs a GOMP_MAP_STRUCT
9788 mapping added. */
9789 gomp_map_kind k
9790 = ((code == OACC_EXIT_DATA || code == OMP_TARGET_EXIT_DATA)
9791 ? GOMP_MAP_DETACH : GOMP_MAP_ATTACH);
9792 OMP_CLAUSE_SET_MAP_KIND (c, k);
9793 has_attachments = true;
9796 /* We currently don't handle non-constant offset accesses wrt to
9797 GOMP_MAP_STRUCT elements. */
9798 if (!do_map_struct)
9799 goto skip_map_struct;
9801 /* Nor for attach_detach for OpenMP. */
9802 if ((code == OMP_TARGET
9803 || code == OMP_TARGET_DATA
9804 || code == OMP_TARGET_UPDATE
9805 || code == OMP_TARGET_ENTER_DATA
9806 || code == OMP_TARGET_EXIT_DATA)
9807 && attach_detach)
9809 if (DECL_P (decl))
9811 if (struct_seen_clause == NULL)
9812 struct_seen_clause
9813 = new hash_map<tree_operand_hash, tree *>;
9814 if (!struct_seen_clause->get (decl))
9815 struct_seen_clause->put (decl, list_p);
9818 goto skip_map_struct;
9821 if ((DECL_P (decl)
9822 && (n == NULL || (n->value & GOVD_MAP) == 0))
9823 || (!DECL_P (decl)
9824 && (!struct_map_to_clause
9825 || struct_map_to_clause->get (decl) == NULL)))
9827 tree l = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9828 OMP_CLAUSE_MAP);
9829 gomp_map_kind k = attach ? GOMP_MAP_FORCE_PRESENT
9830 : GOMP_MAP_STRUCT;
9832 OMP_CLAUSE_SET_MAP_KIND (l, k);
9833 if (base_ref)
9834 OMP_CLAUSE_DECL (l) = unshare_expr (base_ref);
9835 else
9837 OMP_CLAUSE_DECL (l) = unshare_expr (decl);
9838 if (!DECL_P (OMP_CLAUSE_DECL (l))
9839 && (gimplify_expr (&OMP_CLAUSE_DECL (l),
9840 pre_p, NULL, is_gimple_lvalue,
9841 fb_lvalue)
9842 == GS_ERROR))
9844 remove = true;
9845 break;
9848 OMP_CLAUSE_SIZE (l)
9849 = (!attach
9850 ? size_int (1)
9851 : DECL_P (OMP_CLAUSE_DECL (l))
9852 ? DECL_SIZE_UNIT (OMP_CLAUSE_DECL (l))
9853 : TYPE_SIZE_UNIT (TREE_TYPE (OMP_CLAUSE_DECL (l))));
9854 if (struct_map_to_clause == NULL)
9855 struct_map_to_clause
9856 = new hash_map<tree_operand_hash, tree>;
9857 struct_map_to_clause->put (decl, l);
9858 if (ptr || attach_detach)
9860 tree **sc = (struct_seen_clause
9861 ? struct_seen_clause->get (decl)
9862 : NULL);
9863 tree *insert_node_pos = sc ? *sc : prev_list_p;
9865 insert_struct_comp_map (code, c, l, *insert_node_pos,
9866 NULL);
9867 *insert_node_pos = l;
9868 prev_list_p = NULL;
9870 else
9872 OMP_CLAUSE_CHAIN (l) = c;
9873 *list_p = l;
9874 list_p = &OMP_CLAUSE_CHAIN (l);
9876 if (base_ref && code == OMP_TARGET)
9878 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9879 OMP_CLAUSE_MAP);
9880 enum gomp_map_kind mkind
9881 = GOMP_MAP_FIRSTPRIVATE_REFERENCE;
9882 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
9883 OMP_CLAUSE_DECL (c2) = decl;
9884 OMP_CLAUSE_SIZE (c2) = size_zero_node;
9885 OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (l);
9886 OMP_CLAUSE_CHAIN (l) = c2;
9888 flags = GOVD_MAP | GOVD_EXPLICIT;
9889 if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c))
9890 || ptr
9891 || attach_detach)
9892 flags |= GOVD_SEEN;
9893 if (has_attachments)
9894 flags |= GOVD_MAP_HAS_ATTACHMENTS;
9896 /* If this is a *pointer-to-struct expression, make sure a
9897 firstprivate map of the base-pointer exists. */
9898 if (component_ref_p
9899 && ((TREE_CODE (decl) == MEM_REF
9900 && integer_zerop (TREE_OPERAND (decl, 1)))
9901 || INDIRECT_REF_P (decl))
9902 && DECL_P (TREE_OPERAND (decl, 0))
9903 && !splay_tree_lookup (ctx->variables,
9904 ((splay_tree_key)
9905 TREE_OPERAND (decl, 0))))
9907 decl = TREE_OPERAND (decl, 0);
9908 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9909 OMP_CLAUSE_MAP);
9910 enum gomp_map_kind mkind
9911 = GOMP_MAP_FIRSTPRIVATE_POINTER;
9912 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
9913 OMP_CLAUSE_DECL (c2) = decl;
9914 OMP_CLAUSE_SIZE (c2) = size_zero_node;
9915 OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (c);
9916 OMP_CLAUSE_CHAIN (c) = c2;
9919 if (DECL_P (decl))
9920 goto do_add_decl;
9922 else if (struct_map_to_clause)
9924 tree *osc = struct_map_to_clause->get (decl);
9925 tree *sc = NULL, *scp = NULL;
9926 if (n != NULL
9927 && (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c))
9928 || ptr
9929 || attach_detach))
9930 n->value |= GOVD_SEEN;
9931 sc = &OMP_CLAUSE_CHAIN (*osc);
9932 if (*sc != c
9933 && (OMP_CLAUSE_MAP_KIND (*sc)
9934 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
9935 sc = &OMP_CLAUSE_CHAIN (*sc);
9936 /* Here "prev_list_p" is the end of the inserted
9937 alloc/release nodes after the struct node, OSC. */
9938 for (; *sc != c; sc = &OMP_CLAUSE_CHAIN (*sc))
9939 if ((ptr || attach_detach) && sc == prev_list_p)
9940 break;
9941 else if (TREE_CODE (OMP_CLAUSE_DECL (*sc))
9942 != COMPONENT_REF
9943 && (TREE_CODE (OMP_CLAUSE_DECL (*sc))
9944 != INDIRECT_REF)
9945 && (TREE_CODE (OMP_CLAUSE_DECL (*sc))
9946 != ARRAY_REF))
9947 break;
9948 else
9950 tree sc_decl = OMP_CLAUSE_DECL (*sc);
9951 poly_offset_int offsetn;
9952 poly_int64 bitposn;
9953 tree tree_offsetn;
9954 tree base
9955 = extract_base_bit_offset (sc_decl, NULL,
9956 &bitposn, &offsetn,
9957 &tree_offsetn);
9958 if (base != decl)
9959 break;
9960 if (scp)
9961 continue;
9962 if ((region_type & ORT_ACC) != 0)
9964 /* This duplicate checking code is currently only
9965 enabled for OpenACC. */
9966 tree d1 = OMP_CLAUSE_DECL (*sc);
9967 tree d2 = OMP_CLAUSE_DECL (c);
9968 while (TREE_CODE (d1) == ARRAY_REF)
9969 d1 = TREE_OPERAND (d1, 0);
9970 while (TREE_CODE (d2) == ARRAY_REF)
9971 d2 = TREE_OPERAND (d2, 0);
9972 if (TREE_CODE (d1) == INDIRECT_REF)
9973 d1 = TREE_OPERAND (d1, 0);
9974 if (TREE_CODE (d2) == INDIRECT_REF)
9975 d2 = TREE_OPERAND (d2, 0);
9976 while (TREE_CODE (d1) == COMPONENT_REF)
9977 if (TREE_CODE (d2) == COMPONENT_REF
9978 && TREE_OPERAND (d1, 1)
9979 == TREE_OPERAND (d2, 1))
9981 d1 = TREE_OPERAND (d1, 0);
9982 d2 = TREE_OPERAND (d2, 0);
9984 else
9985 break;
9986 if (d1 == d2)
9988 error_at (OMP_CLAUSE_LOCATION (c),
9989 "%qE appears more than once in map "
9990 "clauses", OMP_CLAUSE_DECL (c));
9991 remove = true;
9992 break;
9995 if (maybe_lt (offset1, offsetn)
9996 || (known_eq (offset1, offsetn)
9997 && maybe_lt (bitpos1, bitposn)))
9999 if (ptr || attach_detach)
10000 scp = sc;
10001 else
10002 break;
10005 if (remove)
10006 break;
10007 if (!attach)
10008 OMP_CLAUSE_SIZE (*osc)
10009 = size_binop (PLUS_EXPR, OMP_CLAUSE_SIZE (*osc),
10010 size_one_node);
10011 if (ptr || attach_detach)
10013 tree cl = insert_struct_comp_map (code, c, NULL,
10014 *prev_list_p, scp);
10015 if (sc == prev_list_p)
10017 *sc = cl;
10018 prev_list_p = NULL;
10020 else
10022 *prev_list_p = OMP_CLAUSE_CHAIN (c);
10023 list_p = prev_list_p;
10024 prev_list_p = NULL;
10025 OMP_CLAUSE_CHAIN (c) = *sc;
10026 *sc = cl;
10027 continue;
10030 else if (*sc != c)
10032 if (gimplify_expr (pd, pre_p, NULL, is_gimple_lvalue,
10033 fb_lvalue)
10034 == GS_ERROR)
10036 remove = true;
10037 break;
10039 *list_p = OMP_CLAUSE_CHAIN (c);
10040 OMP_CLAUSE_CHAIN (c) = *sc;
10041 *sc = c;
10042 continue;
10045 skip_map_struct:
10048 else if ((code == OACC_ENTER_DATA
10049 || code == OACC_EXIT_DATA
10050 || code == OACC_DATA
10051 || code == OACC_PARALLEL
10052 || code == OACC_KERNELS
10053 || code == OACC_SERIAL
10054 || code == OMP_TARGET_ENTER_DATA
10055 || code == OMP_TARGET_EXIT_DATA)
10056 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
10058 gomp_map_kind k = ((code == OACC_EXIT_DATA
10059 || code == OMP_TARGET_EXIT_DATA)
10060 ? GOMP_MAP_DETACH : GOMP_MAP_ATTACH);
10061 OMP_CLAUSE_SET_MAP_KIND (c, k);
10064 if (code == OMP_TARGET && OMP_CLAUSE_MAP_IN_REDUCTION (c))
10066 /* Don't gimplify *pd fully at this point, as the base
10067 will need to be adjusted during omp lowering. */
10068 auto_vec<tree, 10> expr_stack;
10069 tree *p = pd;
10070 while (handled_component_p (*p)
10071 || TREE_CODE (*p) == INDIRECT_REF
10072 || TREE_CODE (*p) == ADDR_EXPR
10073 || TREE_CODE (*p) == MEM_REF
10074 || TREE_CODE (*p) == NON_LVALUE_EXPR)
10076 expr_stack.safe_push (*p);
10077 p = &TREE_OPERAND (*p, 0);
10079 for (int i = expr_stack.length () - 1; i >= 0; i--)
10081 tree t = expr_stack[i];
10082 if (TREE_CODE (t) == ARRAY_REF
10083 || TREE_CODE (t) == ARRAY_RANGE_REF)
10085 if (TREE_OPERAND (t, 2) == NULL_TREE)
10087 tree low = unshare_expr (array_ref_low_bound (t));
10088 if (!is_gimple_min_invariant (low))
10090 TREE_OPERAND (t, 2) = low;
10091 if (gimplify_expr (&TREE_OPERAND (t, 2),
10092 pre_p, NULL,
10093 is_gimple_reg,
10094 fb_rvalue) == GS_ERROR)
10095 remove = true;
10098 else if (gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
10099 NULL, is_gimple_reg,
10100 fb_rvalue) == GS_ERROR)
10101 remove = true;
10102 if (TREE_OPERAND (t, 3) == NULL_TREE)
10104 tree elmt_size = array_ref_element_size (t);
10105 if (!is_gimple_min_invariant (elmt_size))
10107 elmt_size = unshare_expr (elmt_size);
10108 tree elmt_type
10109 = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t,
10110 0)));
10111 tree factor
10112 = size_int (TYPE_ALIGN_UNIT (elmt_type));
10113 elmt_size
10114 = size_binop (EXACT_DIV_EXPR, elmt_size,
10115 factor);
10116 TREE_OPERAND (t, 3) = elmt_size;
10117 if (gimplify_expr (&TREE_OPERAND (t, 3),
10118 pre_p, NULL,
10119 is_gimple_reg,
10120 fb_rvalue) == GS_ERROR)
10121 remove = true;
10124 else if (gimplify_expr (&TREE_OPERAND (t, 3), pre_p,
10125 NULL, is_gimple_reg,
10126 fb_rvalue) == GS_ERROR)
10127 remove = true;
10129 else if (TREE_CODE (t) == COMPONENT_REF)
10131 if (TREE_OPERAND (t, 2) == NULL_TREE)
10133 tree offset = component_ref_field_offset (t);
10134 if (!is_gimple_min_invariant (offset))
10136 offset = unshare_expr (offset);
10137 tree field = TREE_OPERAND (t, 1);
10138 tree factor
10139 = size_int (DECL_OFFSET_ALIGN (field)
10140 / BITS_PER_UNIT);
10141 offset = size_binop (EXACT_DIV_EXPR, offset,
10142 factor);
10143 TREE_OPERAND (t, 2) = offset;
10144 if (gimplify_expr (&TREE_OPERAND (t, 2),
10145 pre_p, NULL,
10146 is_gimple_reg,
10147 fb_rvalue) == GS_ERROR)
10148 remove = true;
10151 else if (gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
10152 NULL, is_gimple_reg,
10153 fb_rvalue) == GS_ERROR)
10154 remove = true;
10157 for (; expr_stack.length () > 0; )
10159 tree t = expr_stack.pop ();
10161 if (TREE_CODE (t) == ARRAY_REF
10162 || TREE_CODE (t) == ARRAY_RANGE_REF)
10164 if (!is_gimple_min_invariant (TREE_OPERAND (t, 1))
10165 && gimplify_expr (&TREE_OPERAND (t, 1), pre_p,
10166 NULL, is_gimple_val,
10167 fb_rvalue) == GS_ERROR)
10168 remove = true;
10172 else if (gimplify_expr (pd, pre_p, NULL, is_gimple_lvalue,
10173 fb_lvalue) == GS_ERROR)
10175 remove = true;
10176 break;
10179 /* If this was of the form map(*pointer_to_struct), then the
10180 'pointer_to_struct' DECL should be considered deref'ed. */
10181 if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALLOC
10182 || GOMP_MAP_COPY_TO_P (OMP_CLAUSE_MAP_KIND (c))
10183 || GOMP_MAP_COPY_FROM_P (OMP_CLAUSE_MAP_KIND (c)))
10184 && INDIRECT_REF_P (orig_decl)
10185 && DECL_P (TREE_OPERAND (orig_decl, 0))
10186 && TREE_CODE (TREE_TYPE (orig_decl)) == RECORD_TYPE)
10188 tree ptr = TREE_OPERAND (orig_decl, 0);
10189 if (!struct_deref_set || !struct_deref_set->contains (ptr))
10191 if (!struct_deref_set)
10192 struct_deref_set = new hash_set<tree> ();
10193 struct_deref_set->add (ptr);
10197 if (!remove
10198 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_POINTER
10199 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH_DETACH
10200 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_TO_PSET
10201 && OMP_CLAUSE_CHAIN (c)
10202 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (c)) == OMP_CLAUSE_MAP
10203 && ((OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
10204 == GOMP_MAP_ALWAYS_POINTER)
10205 || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
10206 == GOMP_MAP_ATTACH_DETACH)
10207 || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
10208 == GOMP_MAP_TO_PSET)))
10209 prev_list_p = list_p;
10211 break;
10213 else
10215 /* DECL_P (decl) == true */
10216 tree *sc;
10217 if (struct_map_to_clause
10218 && (sc = struct_map_to_clause->get (decl)) != NULL
10219 && OMP_CLAUSE_MAP_KIND (*sc) == GOMP_MAP_STRUCT
10220 && decl == OMP_CLAUSE_DECL (*sc))
10222 /* We have found a map of the whole structure after a
10223 leading GOMP_MAP_STRUCT has been created, so refill the
10224 leading clause into a map of the whole structure
10225 variable, and remove the current one.
10226 TODO: we should be able to remove some maps of the
10227 following structure element maps if they are of
10228 compatible TO/FROM/ALLOC type. */
10229 OMP_CLAUSE_SET_MAP_KIND (*sc, OMP_CLAUSE_MAP_KIND (c));
10230 OMP_CLAUSE_SIZE (*sc) = unshare_expr (OMP_CLAUSE_SIZE (c));
10231 remove = true;
10232 break;
10235 flags = GOVD_MAP | GOVD_EXPLICIT;
10236 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TO
10237 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TOFROM)
10238 flags |= GOVD_MAP_ALWAYS_TO;
10240 if ((code == OMP_TARGET
10241 || code == OMP_TARGET_DATA
10242 || code == OMP_TARGET_ENTER_DATA
10243 || code == OMP_TARGET_EXIT_DATA)
10244 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
10246 for (struct gimplify_omp_ctx *octx = outer_ctx; octx;
10247 octx = octx->outer_context)
10249 splay_tree_node n
10250 = splay_tree_lookup (octx->variables,
10251 (splay_tree_key) OMP_CLAUSE_DECL (c));
10252 /* If this is contained in an outer OpenMP region as a
10253 firstprivate value, remove the attach/detach. */
10254 if (n && (n->value & GOVD_FIRSTPRIVATE))
10256 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FIRSTPRIVATE_POINTER);
10257 goto do_add;
10261 enum gomp_map_kind map_kind = (code == OMP_TARGET_EXIT_DATA
10262 ? GOMP_MAP_DETACH
10263 : GOMP_MAP_ATTACH);
10264 OMP_CLAUSE_SET_MAP_KIND (c, map_kind);
10267 goto do_add;
10269 case OMP_CLAUSE_AFFINITY:
10270 gimplify_omp_affinity (list_p, pre_p);
10271 remove = true;
10272 break;
10273 case OMP_CLAUSE_DEPEND:
10274 if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
10276 tree deps = OMP_CLAUSE_DECL (c);
10277 while (deps && TREE_CODE (deps) == TREE_LIST)
10279 if (TREE_CODE (TREE_PURPOSE (deps)) == TRUNC_DIV_EXPR
10280 && DECL_P (TREE_OPERAND (TREE_PURPOSE (deps), 1)))
10281 gimplify_expr (&TREE_OPERAND (TREE_PURPOSE (deps), 1),
10282 pre_p, NULL, is_gimple_val, fb_rvalue);
10283 deps = TREE_CHAIN (deps);
10285 break;
10287 else if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
10288 break;
10289 if (handled_depend_iterators == -1)
10290 handled_depend_iterators = gimplify_omp_depend (list_p, pre_p);
10291 if (handled_depend_iterators)
10293 if (handled_depend_iterators == 2)
10294 remove = true;
10295 break;
10297 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
10299 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
10300 NULL, is_gimple_val, fb_rvalue);
10301 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
10303 if (error_operand_p (OMP_CLAUSE_DECL (c)))
10305 remove = true;
10306 break;
10308 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
10309 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
10310 is_gimple_val, fb_rvalue) == GS_ERROR)
10312 remove = true;
10313 break;
10315 if (code == OMP_TASK)
10316 ctx->has_depend = true;
10317 break;
10319 case OMP_CLAUSE_TO:
10320 case OMP_CLAUSE_FROM:
10321 case OMP_CLAUSE__CACHE_:
10322 decl = OMP_CLAUSE_DECL (c);
10323 if (error_operand_p (decl))
10325 remove = true;
10326 break;
10328 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
10329 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
10330 : TYPE_SIZE_UNIT (TREE_TYPE (decl));
10331 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
10332 NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
10334 remove = true;
10335 break;
10337 if (!DECL_P (decl))
10339 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p,
10340 NULL, is_gimple_lvalue, fb_lvalue)
10341 == GS_ERROR)
10343 remove = true;
10344 break;
10346 break;
10348 goto do_notice;
10350 case OMP_CLAUSE_USE_DEVICE_PTR:
10351 case OMP_CLAUSE_USE_DEVICE_ADDR:
10352 flags = GOVD_EXPLICIT;
10353 goto do_add;
10355 case OMP_CLAUSE_HAS_DEVICE_ADDR:
10356 decl = OMP_CLAUSE_DECL (c);
10357 while (TREE_CODE (decl) == INDIRECT_REF
10358 || TREE_CODE (decl) == ARRAY_REF)
10359 decl = TREE_OPERAND (decl, 0);
10360 flags = GOVD_EXPLICIT;
10361 goto do_add_decl;
10363 case OMP_CLAUSE_IS_DEVICE_PTR:
10364 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
10365 goto do_add;
10367 do_add:
10368 decl = OMP_CLAUSE_DECL (c);
10369 do_add_decl:
10370 if (error_operand_p (decl))
10372 remove = true;
10373 break;
10375 if (DECL_NAME (decl) == NULL_TREE && (flags & GOVD_SHARED) == 0)
10377 tree t = omp_member_access_dummy_var (decl);
10378 if (t)
10380 tree v = DECL_VALUE_EXPR (decl);
10381 DECL_NAME (decl) = DECL_NAME (TREE_OPERAND (v, 1));
10382 if (outer_ctx)
10383 omp_notice_variable (outer_ctx, t, true);
10386 if (code == OACC_DATA
10387 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
10388 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
10389 flags |= GOVD_MAP_0LEN_ARRAY;
10390 omp_add_variable (ctx, decl, flags);
10391 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10392 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
10393 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
10394 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
10396 struct gimplify_omp_ctx *pctx
10397 = code == OMP_TARGET ? outer_ctx : ctx;
10398 if (pctx)
10399 omp_add_variable (pctx, OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
10400 GOVD_LOCAL | GOVD_SEEN);
10401 if (pctx
10402 && OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
10403 && walk_tree (&OMP_CLAUSE_REDUCTION_INIT (c),
10404 find_decl_expr,
10405 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
10406 NULL) == NULL_TREE)
10407 omp_add_variable (pctx,
10408 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
10409 GOVD_LOCAL | GOVD_SEEN);
10410 gimplify_omp_ctxp = pctx;
10411 push_gimplify_context ();
10413 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
10414 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
10416 gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c),
10417 &OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c));
10418 pop_gimplify_context
10419 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c)));
10420 push_gimplify_context ();
10421 gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c),
10422 &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
10423 pop_gimplify_context
10424 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c)));
10425 OMP_CLAUSE_REDUCTION_INIT (c) = NULL_TREE;
10426 OMP_CLAUSE_REDUCTION_MERGE (c) = NULL_TREE;
10428 gimplify_omp_ctxp = outer_ctx;
10430 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
10431 && OMP_CLAUSE_LASTPRIVATE_STMT (c))
10433 gimplify_omp_ctxp = ctx;
10434 push_gimplify_context ();
10435 if (TREE_CODE (OMP_CLAUSE_LASTPRIVATE_STMT (c)) != BIND_EXPR)
10437 tree bind = build3 (BIND_EXPR, void_type_node, NULL,
10438 NULL, NULL);
10439 TREE_SIDE_EFFECTS (bind) = 1;
10440 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LASTPRIVATE_STMT (c);
10441 OMP_CLAUSE_LASTPRIVATE_STMT (c) = bind;
10443 gimplify_and_add (OMP_CLAUSE_LASTPRIVATE_STMT (c),
10444 &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
10445 pop_gimplify_context
10446 (gimple_seq_first_stmt (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c)));
10447 OMP_CLAUSE_LASTPRIVATE_STMT (c) = NULL_TREE;
10449 gimplify_omp_ctxp = outer_ctx;
10451 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
10452 && OMP_CLAUSE_LINEAR_STMT (c))
10454 gimplify_omp_ctxp = ctx;
10455 push_gimplify_context ();
10456 if (TREE_CODE (OMP_CLAUSE_LINEAR_STMT (c)) != BIND_EXPR)
10458 tree bind = build3 (BIND_EXPR, void_type_node, NULL,
10459 NULL, NULL);
10460 TREE_SIDE_EFFECTS (bind) = 1;
10461 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LINEAR_STMT (c);
10462 OMP_CLAUSE_LINEAR_STMT (c) = bind;
10464 gimplify_and_add (OMP_CLAUSE_LINEAR_STMT (c),
10465 &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c));
10466 pop_gimplify_context
10467 (gimple_seq_first_stmt (OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c)));
10468 OMP_CLAUSE_LINEAR_STMT (c) = NULL_TREE;
10470 gimplify_omp_ctxp = outer_ctx;
10472 if (notice_outer)
10473 goto do_notice;
10474 break;
10476 case OMP_CLAUSE_COPYIN:
10477 case OMP_CLAUSE_COPYPRIVATE:
10478 decl = OMP_CLAUSE_DECL (c);
10479 if (error_operand_p (decl))
10481 remove = true;
10482 break;
10484 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_COPYPRIVATE
10485 && !remove
10486 && !omp_check_private (ctx, decl, true))
10488 remove = true;
10489 if (is_global_var (decl))
10491 if (DECL_THREAD_LOCAL_P (decl))
10492 remove = false;
10493 else if (DECL_HAS_VALUE_EXPR_P (decl))
10495 tree value = get_base_address (DECL_VALUE_EXPR (decl));
10497 if (value
10498 && DECL_P (value)
10499 && DECL_THREAD_LOCAL_P (value))
10500 remove = false;
10503 if (remove)
10504 error_at (OMP_CLAUSE_LOCATION (c),
10505 "copyprivate variable %qE is not threadprivate"
10506 " or private in outer context", DECL_NAME (decl));
10508 do_notice:
10509 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10510 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
10511 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
10512 && outer_ctx
10513 && ((region_type & ORT_TASKLOOP) == ORT_TASKLOOP
10514 || (region_type == ORT_WORKSHARE
10515 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10516 && (OMP_CLAUSE_REDUCTION_INSCAN (c)
10517 || code == OMP_LOOP)))
10518 && (outer_ctx->region_type == ORT_COMBINED_PARALLEL
10519 || (code == OMP_LOOP
10520 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10521 && ((outer_ctx->region_type & ORT_COMBINED_TEAMS)
10522 == ORT_COMBINED_TEAMS))))
10524 splay_tree_node on
10525 = splay_tree_lookup (outer_ctx->variables,
10526 (splay_tree_key)decl);
10527 if (on == NULL || (on->value & GOVD_DATA_SHARE_CLASS) == 0)
10529 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10530 && TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
10531 && (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
10532 || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
10533 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
10534 == POINTER_TYPE))))
10535 omp_firstprivatize_variable (outer_ctx, decl);
10536 else
10538 omp_add_variable (outer_ctx, decl,
10539 GOVD_SEEN | GOVD_SHARED);
10540 if (outer_ctx->outer_context)
10541 omp_notice_variable (outer_ctx->outer_context, decl,
10542 true);
10546 if (outer_ctx)
10547 omp_notice_variable (outer_ctx, decl, true);
10548 if (check_non_private
10549 && (region_type == ORT_WORKSHARE || code == OMP_SCOPE)
10550 && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
10551 || decl == OMP_CLAUSE_DECL (c)
10552 || (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
10553 && (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
10554 == ADDR_EXPR
10555 || (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
10556 == POINTER_PLUS_EXPR
10557 && (TREE_CODE (TREE_OPERAND (TREE_OPERAND
10558 (OMP_CLAUSE_DECL (c), 0), 0))
10559 == ADDR_EXPR)))))
10560 && omp_check_private (ctx, decl, false))
10562 error ("%s variable %qE is private in outer context",
10563 check_non_private, DECL_NAME (decl));
10564 remove = true;
10566 break;
10568 case OMP_CLAUSE_DETACH:
10569 flags = GOVD_FIRSTPRIVATE | GOVD_SEEN;
10570 goto do_add;
10572 case OMP_CLAUSE_IF:
10573 if (OMP_CLAUSE_IF_MODIFIER (c) != ERROR_MARK
10574 && OMP_CLAUSE_IF_MODIFIER (c) != code)
10576 const char *p[2];
10577 for (int i = 0; i < 2; i++)
10578 switch (i ? OMP_CLAUSE_IF_MODIFIER (c) : code)
10580 case VOID_CST: p[i] = "cancel"; break;
10581 case OMP_PARALLEL: p[i] = "parallel"; break;
10582 case OMP_SIMD: p[i] = "simd"; break;
10583 case OMP_TASK: p[i] = "task"; break;
10584 case OMP_TASKLOOP: p[i] = "taskloop"; break;
10585 case OMP_TARGET_DATA: p[i] = "target data"; break;
10586 case OMP_TARGET: p[i] = "target"; break;
10587 case OMP_TARGET_UPDATE: p[i] = "target update"; break;
10588 case OMP_TARGET_ENTER_DATA:
10589 p[i] = "target enter data"; break;
10590 case OMP_TARGET_EXIT_DATA: p[i] = "target exit data"; break;
10591 default: gcc_unreachable ();
10593 error_at (OMP_CLAUSE_LOCATION (c),
10594 "expected %qs %<if%> clause modifier rather than %qs",
10595 p[0], p[1]);
10596 remove = true;
10598 /* Fall through. */
10600 case OMP_CLAUSE_FINAL:
10601 OMP_CLAUSE_OPERAND (c, 0)
10602 = gimple_boolify (OMP_CLAUSE_OPERAND (c, 0));
10603 /* Fall through. */
10605 case OMP_CLAUSE_NUM_TEAMS:
10606 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
10607 && OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
10608 && !is_gimple_min_invariant (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)))
10610 if (error_operand_p (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)))
10612 remove = true;
10613 break;
10615 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
10616 = get_initialized_tmp_var (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c),
10617 pre_p, NULL, true);
10619 /* Fall through. */
10621 case OMP_CLAUSE_SCHEDULE:
10622 case OMP_CLAUSE_NUM_THREADS:
10623 case OMP_CLAUSE_THREAD_LIMIT:
10624 case OMP_CLAUSE_DIST_SCHEDULE:
10625 case OMP_CLAUSE_DEVICE:
10626 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE
10627 && OMP_CLAUSE_DEVICE_ANCESTOR (c))
10629 if (code != OMP_TARGET)
10631 error_at (OMP_CLAUSE_LOCATION (c),
10632 "%<device%> clause with %<ancestor%> is only "
10633 "allowed on %<target%> construct");
10634 remove = true;
10635 break;
10638 tree clauses = *orig_list_p;
10639 for (; clauses ; clauses = OMP_CLAUSE_CHAIN (clauses))
10640 if (OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_DEVICE
10641 && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_FIRSTPRIVATE
10642 && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_PRIVATE
10643 && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_DEFAULTMAP
10644 && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_MAP
10647 error_at (OMP_CLAUSE_LOCATION (c),
10648 "with %<ancestor%>, only the %<device%>, "
10649 "%<firstprivate%>, %<private%>, %<defaultmap%>, "
10650 "and %<map%> clauses may appear on the "
10651 "construct");
10652 remove = true;
10653 break;
10656 /* Fall through. */
10658 case OMP_CLAUSE_PRIORITY:
10659 case OMP_CLAUSE_GRAINSIZE:
10660 case OMP_CLAUSE_NUM_TASKS:
10661 case OMP_CLAUSE_FILTER:
10662 case OMP_CLAUSE_HINT:
10663 case OMP_CLAUSE_ASYNC:
10664 case OMP_CLAUSE_WAIT:
10665 case OMP_CLAUSE_NUM_GANGS:
10666 case OMP_CLAUSE_NUM_WORKERS:
10667 case OMP_CLAUSE_VECTOR_LENGTH:
10668 case OMP_CLAUSE_WORKER:
10669 case OMP_CLAUSE_VECTOR:
10670 if (OMP_CLAUSE_OPERAND (c, 0)
10671 && !is_gimple_min_invariant (OMP_CLAUSE_OPERAND (c, 0)))
10673 if (error_operand_p (OMP_CLAUSE_OPERAND (c, 0)))
10675 remove = true;
10676 break;
10678 /* All these clauses care about value, not a particular decl,
10679 so try to force it into a SSA_NAME or fresh temporary. */
10680 OMP_CLAUSE_OPERAND (c, 0)
10681 = get_initialized_tmp_var (OMP_CLAUSE_OPERAND (c, 0),
10682 pre_p, NULL, true);
10684 break;
10686 case OMP_CLAUSE_GANG:
10687 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
10688 is_gimple_val, fb_rvalue) == GS_ERROR)
10689 remove = true;
10690 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 1), pre_p, NULL,
10691 is_gimple_val, fb_rvalue) == GS_ERROR)
10692 remove = true;
10693 break;
10695 case OMP_CLAUSE_NOWAIT:
10696 nowait = 1;
10697 break;
10699 case OMP_CLAUSE_ORDERED:
10700 case OMP_CLAUSE_UNTIED:
10701 case OMP_CLAUSE_COLLAPSE:
10702 case OMP_CLAUSE_TILE:
10703 case OMP_CLAUSE_AUTO:
10704 case OMP_CLAUSE_SEQ:
10705 case OMP_CLAUSE_INDEPENDENT:
10706 case OMP_CLAUSE_MERGEABLE:
10707 case OMP_CLAUSE_PROC_BIND:
10708 case OMP_CLAUSE_SAFELEN:
10709 case OMP_CLAUSE_SIMDLEN:
10710 case OMP_CLAUSE_NOGROUP:
10711 case OMP_CLAUSE_THREADS:
10712 case OMP_CLAUSE_SIMD:
10713 case OMP_CLAUSE_BIND:
10714 case OMP_CLAUSE_IF_PRESENT:
10715 case OMP_CLAUSE_FINALIZE:
10716 break;
10718 case OMP_CLAUSE_ORDER:
10719 ctx->order_concurrent = true;
10720 break;
10722 case OMP_CLAUSE_DEFAULTMAP:
10723 enum gimplify_defaultmap_kind gdmkmin, gdmkmax;
10724 switch (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c))
10726 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
10727 gdmkmin = GDMK_SCALAR;
10728 gdmkmax = GDMK_POINTER;
10729 break;
10730 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
10731 gdmkmin = GDMK_SCALAR;
10732 gdmkmax = GDMK_SCALAR_TARGET;
10733 break;
10734 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
10735 gdmkmin = gdmkmax = GDMK_AGGREGATE;
10736 break;
10737 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALLOCATABLE:
10738 gdmkmin = gdmkmax = GDMK_ALLOCATABLE;
10739 break;
10740 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
10741 gdmkmin = gdmkmax = GDMK_POINTER;
10742 break;
10743 default:
10744 gcc_unreachable ();
10746 for (int gdmk = gdmkmin; gdmk <= gdmkmax; gdmk++)
10747 switch (OMP_CLAUSE_DEFAULTMAP_BEHAVIOR (c))
10749 case OMP_CLAUSE_DEFAULTMAP_ALLOC:
10750 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_ALLOC_ONLY;
10751 break;
10752 case OMP_CLAUSE_DEFAULTMAP_TO:
10753 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_TO_ONLY;
10754 break;
10755 case OMP_CLAUSE_DEFAULTMAP_FROM:
10756 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_FROM_ONLY;
10757 break;
10758 case OMP_CLAUSE_DEFAULTMAP_TOFROM:
10759 ctx->defaultmap[gdmk] = GOVD_MAP;
10760 break;
10761 case OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE:
10762 ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE;
10763 break;
10764 case OMP_CLAUSE_DEFAULTMAP_NONE:
10765 ctx->defaultmap[gdmk] = 0;
10766 break;
10767 case OMP_CLAUSE_DEFAULTMAP_DEFAULT:
10768 switch (gdmk)
10770 case GDMK_SCALAR:
10771 ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE;
10772 break;
10773 case GDMK_SCALAR_TARGET:
10774 ctx->defaultmap[gdmk] = (lang_GNU_Fortran ()
10775 ? GOVD_MAP : GOVD_FIRSTPRIVATE);
10776 break;
10777 case GDMK_AGGREGATE:
10778 case GDMK_ALLOCATABLE:
10779 ctx->defaultmap[gdmk] = GOVD_MAP;
10780 break;
10781 case GDMK_POINTER:
10782 ctx->defaultmap[gdmk] = GOVD_MAP;
10783 if (!lang_GNU_Fortran ())
10784 ctx->defaultmap[gdmk] |= GOVD_MAP_0LEN_ARRAY;
10785 break;
10786 default:
10787 gcc_unreachable ();
10789 break;
10790 default:
10791 gcc_unreachable ();
10793 break;
10795 case OMP_CLAUSE_ALIGNED:
10796 decl = OMP_CLAUSE_DECL (c);
10797 if (error_operand_p (decl))
10799 remove = true;
10800 break;
10802 if (gimplify_expr (&OMP_CLAUSE_ALIGNED_ALIGNMENT (c), pre_p, NULL,
10803 is_gimple_val, fb_rvalue) == GS_ERROR)
10805 remove = true;
10806 break;
10808 if (!is_global_var (decl)
10809 && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
10810 omp_add_variable (ctx, decl, GOVD_ALIGNED);
10811 break;
10813 case OMP_CLAUSE_NONTEMPORAL:
10814 decl = OMP_CLAUSE_DECL (c);
10815 if (error_operand_p (decl))
10817 remove = true;
10818 break;
10820 omp_add_variable (ctx, decl, GOVD_NONTEMPORAL);
10821 break;
10823 case OMP_CLAUSE_ALLOCATE:
10824 decl = OMP_CLAUSE_DECL (c);
10825 if (error_operand_p (decl))
10827 remove = true;
10828 break;
10830 if (gimplify_expr (&OMP_CLAUSE_ALLOCATE_ALLOCATOR (c), pre_p, NULL,
10831 is_gimple_val, fb_rvalue) == GS_ERROR)
10833 remove = true;
10834 break;
10836 else if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) == NULL_TREE
10837 || (TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c))
10838 == INTEGER_CST))
10840 else if (code == OMP_TASKLOOP
10841 || !DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)))
10842 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
10843 = get_initialized_tmp_var (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
10844 pre_p, NULL, false);
10845 break;
10847 case OMP_CLAUSE_DEFAULT:
10848 ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
10849 break;
10851 case OMP_CLAUSE_INCLUSIVE:
10852 case OMP_CLAUSE_EXCLUSIVE:
10853 decl = OMP_CLAUSE_DECL (c);
10855 splay_tree_node n = splay_tree_lookup (outer_ctx->variables,
10856 (splay_tree_key) decl);
10857 if (n == NULL || (n->value & GOVD_REDUCTION) == 0)
10859 error_at (OMP_CLAUSE_LOCATION (c),
10860 "%qD specified in %qs clause but not in %<inscan%> "
10861 "%<reduction%> clause on the containing construct",
10862 decl, omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
10863 remove = true;
10865 else
10867 n->value |= GOVD_REDUCTION_INSCAN;
10868 if (outer_ctx->region_type == ORT_SIMD
10869 && outer_ctx->outer_context
10870 && outer_ctx->outer_context->region_type == ORT_WORKSHARE)
10872 n = splay_tree_lookup (outer_ctx->outer_context->variables,
10873 (splay_tree_key) decl);
10874 if (n && (n->value & GOVD_REDUCTION) != 0)
10875 n->value |= GOVD_REDUCTION_INSCAN;
10879 break;
10881 case OMP_CLAUSE_NOHOST:
10882 default:
10883 gcc_unreachable ();
10886 if (code == OACC_DATA
10887 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
10888 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
10889 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
10890 remove = true;
10891 if (remove)
10892 *list_p = OMP_CLAUSE_CHAIN (c);
10893 else
10894 list_p = &OMP_CLAUSE_CHAIN (c);
10897 ctx->clauses = *orig_list_p;
10898 gimplify_omp_ctxp = ctx;
10899 if (struct_seen_clause)
10900 delete struct_seen_clause;
10901 if (struct_map_to_clause)
10902 delete struct_map_to_clause;
10903 if (struct_deref_set)
10904 delete struct_deref_set;
10907 /* Return true if DECL is a candidate for shared to firstprivate
10908 optimization. We only consider non-addressable scalars, not
10909 too big, and not references. */
10911 static bool
10912 omp_shared_to_firstprivate_optimizable_decl_p (tree decl)
10914 if (TREE_ADDRESSABLE (decl))
10915 return false;
10916 tree type = TREE_TYPE (decl);
10917 if (!is_gimple_reg_type (type)
10918 || TREE_CODE (type) == REFERENCE_TYPE
10919 || TREE_ADDRESSABLE (type))
10920 return false;
10921 /* Don't optimize too large decls, as each thread/task will have
10922 its own. */
10923 HOST_WIDE_INT len = int_size_in_bytes (type);
10924 if (len == -1 || len > 4 * POINTER_SIZE / BITS_PER_UNIT)
10925 return false;
10926 if (omp_privatize_by_reference (decl))
10927 return false;
10928 return true;
10931 /* Helper function of omp_find_stores_op and gimplify_adjust_omp_clauses*.
10932 For omp_shared_to_firstprivate_optimizable_decl_p decl mark it as
10933 GOVD_WRITTEN in outer contexts. */
10935 static void
10936 omp_mark_stores (struct gimplify_omp_ctx *ctx, tree decl)
10938 for (; ctx; ctx = ctx->outer_context)
10940 splay_tree_node n = splay_tree_lookup (ctx->variables,
10941 (splay_tree_key) decl);
10942 if (n == NULL)
10943 continue;
10944 else if (n->value & GOVD_SHARED)
10946 n->value |= GOVD_WRITTEN;
10947 return;
10949 else if (n->value & GOVD_DATA_SHARE_CLASS)
10950 return;
10954 /* Helper callback for walk_gimple_seq to discover possible stores
10955 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
10956 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
10957 for those. */
10959 static tree
10960 omp_find_stores_op (tree *tp, int *walk_subtrees, void *data)
10962 struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
10964 *walk_subtrees = 0;
10965 if (!wi->is_lhs)
10966 return NULL_TREE;
10968 tree op = *tp;
10971 if (handled_component_p (op))
10972 op = TREE_OPERAND (op, 0);
10973 else if ((TREE_CODE (op) == MEM_REF || TREE_CODE (op) == TARGET_MEM_REF)
10974 && TREE_CODE (TREE_OPERAND (op, 0)) == ADDR_EXPR)
10975 op = TREE_OPERAND (TREE_OPERAND (op, 0), 0);
10976 else
10977 break;
10979 while (1);
10980 if (!DECL_P (op) || !omp_shared_to_firstprivate_optimizable_decl_p (op))
10981 return NULL_TREE;
10983 omp_mark_stores (gimplify_omp_ctxp, op);
10984 return NULL_TREE;
10987 /* Helper callback for walk_gimple_seq to discover possible stores
10988 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
10989 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
10990 for those. */
10992 static tree
10993 omp_find_stores_stmt (gimple_stmt_iterator *gsi_p,
10994 bool *handled_ops_p,
10995 struct walk_stmt_info *wi)
10997 gimple *stmt = gsi_stmt (*gsi_p);
10998 switch (gimple_code (stmt))
11000 /* Don't recurse on OpenMP constructs for which
11001 gimplify_adjust_omp_clauses already handled the bodies,
11002 except handle gimple_omp_for_pre_body. */
11003 case GIMPLE_OMP_FOR:
11004 *handled_ops_p = true;
11005 if (gimple_omp_for_pre_body (stmt))
11006 walk_gimple_seq (gimple_omp_for_pre_body (stmt),
11007 omp_find_stores_stmt, omp_find_stores_op, wi);
11008 break;
11009 case GIMPLE_OMP_PARALLEL:
11010 case GIMPLE_OMP_TASK:
11011 case GIMPLE_OMP_SECTIONS:
11012 case GIMPLE_OMP_SINGLE:
11013 case GIMPLE_OMP_SCOPE:
11014 case GIMPLE_OMP_TARGET:
11015 case GIMPLE_OMP_TEAMS:
11016 case GIMPLE_OMP_CRITICAL:
11017 *handled_ops_p = true;
11018 break;
11019 default:
11020 break;
11022 return NULL_TREE;
11025 struct gimplify_adjust_omp_clauses_data
11027 tree *list_p;
11028 gimple_seq *pre_p;
11031 /* For all variables that were not actually used within the context,
11032 remove PRIVATE, SHARED, and FIRSTPRIVATE clauses. */
11034 static int
11035 gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
11037 tree *list_p = ((struct gimplify_adjust_omp_clauses_data *) data)->list_p;
11038 gimple_seq *pre_p
11039 = ((struct gimplify_adjust_omp_clauses_data *) data)->pre_p;
11040 tree decl = (tree) n->key;
11041 unsigned flags = n->value;
11042 enum omp_clause_code code;
11043 tree clause;
11044 bool private_debug;
11046 if (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
11047 && (flags & GOVD_LASTPRIVATE_CONDITIONAL) != 0)
11048 flags = GOVD_SHARED | GOVD_SEEN | GOVD_WRITTEN;
11049 if (flags & (GOVD_EXPLICIT | GOVD_LOCAL))
11050 return 0;
11051 if ((flags & GOVD_SEEN) == 0)
11052 return 0;
11053 if ((flags & GOVD_MAP_HAS_ATTACHMENTS) != 0)
11054 return 0;
11055 if (flags & GOVD_DEBUG_PRIVATE)
11057 gcc_assert ((flags & GOVD_DATA_SHARE_CLASS) == GOVD_SHARED);
11058 private_debug = true;
11060 else if (flags & GOVD_MAP)
11061 private_debug = false;
11062 else
11063 private_debug
11064 = lang_hooks.decls.omp_private_debug_clause (decl,
11065 !!(flags & GOVD_SHARED));
11066 if (private_debug)
11067 code = OMP_CLAUSE_PRIVATE;
11068 else if (flags & GOVD_MAP)
11070 code = OMP_CLAUSE_MAP;
11071 if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0
11072 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
11074 error ("%<_Atomic%> %qD in implicit %<map%> clause", decl);
11075 return 0;
11077 if (VAR_P (decl)
11078 && DECL_IN_CONSTANT_POOL (decl)
11079 && !lookup_attribute ("omp declare target",
11080 DECL_ATTRIBUTES (decl)))
11082 tree id = get_identifier ("omp declare target");
11083 DECL_ATTRIBUTES (decl)
11084 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
11085 varpool_node *node = varpool_node::get (decl);
11086 if (node)
11088 node->offloadable = 1;
11089 if (ENABLE_OFFLOADING)
11090 g->have_offload = true;
11094 else if (flags & GOVD_SHARED)
11096 if (is_global_var (decl))
11098 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
11099 while (ctx != NULL)
11101 splay_tree_node on
11102 = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11103 if (on && (on->value & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
11104 | GOVD_PRIVATE | GOVD_REDUCTION
11105 | GOVD_LINEAR | GOVD_MAP)) != 0)
11106 break;
11107 ctx = ctx->outer_context;
11109 if (ctx == NULL)
11110 return 0;
11112 code = OMP_CLAUSE_SHARED;
11113 /* Don't optimize shared into firstprivate for read-only vars
11114 on tasks with depend clause, we shouldn't try to copy them
11115 until the dependencies are satisfied. */
11116 if (gimplify_omp_ctxp->has_depend)
11117 flags |= GOVD_WRITTEN;
11119 else if (flags & GOVD_PRIVATE)
11120 code = OMP_CLAUSE_PRIVATE;
11121 else if (flags & GOVD_FIRSTPRIVATE)
11123 code = OMP_CLAUSE_FIRSTPRIVATE;
11124 if ((gimplify_omp_ctxp->region_type & ORT_TARGET)
11125 && (gimplify_omp_ctxp->region_type & ORT_ACC) == 0
11126 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
11128 error ("%<_Atomic%> %qD in implicit %<firstprivate%> clause on "
11129 "%<target%> construct", decl);
11130 return 0;
11133 else if (flags & GOVD_LASTPRIVATE)
11134 code = OMP_CLAUSE_LASTPRIVATE;
11135 else if (flags & (GOVD_ALIGNED | GOVD_NONTEMPORAL))
11136 return 0;
11137 else if (flags & GOVD_CONDTEMP)
11139 code = OMP_CLAUSE__CONDTEMP_;
11140 gimple_add_tmp_var (decl);
11142 else
11143 gcc_unreachable ();
11145 if (((flags & GOVD_LASTPRIVATE)
11146 || (code == OMP_CLAUSE_SHARED && (flags & GOVD_WRITTEN)))
11147 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
11148 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
11150 tree chain = *list_p;
11151 clause = build_omp_clause (input_location, code);
11152 OMP_CLAUSE_DECL (clause) = decl;
11153 OMP_CLAUSE_CHAIN (clause) = chain;
11154 if (private_debug)
11155 OMP_CLAUSE_PRIVATE_DEBUG (clause) = 1;
11156 else if (code == OMP_CLAUSE_PRIVATE && (flags & GOVD_PRIVATE_OUTER_REF))
11157 OMP_CLAUSE_PRIVATE_OUTER_REF (clause) = 1;
11158 else if (code == OMP_CLAUSE_SHARED
11159 && (flags & GOVD_WRITTEN) == 0
11160 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
11161 OMP_CLAUSE_SHARED_READONLY (clause) = 1;
11162 else if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_EXPLICIT) == 0)
11163 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (clause) = 1;
11164 else if (code == OMP_CLAUSE_MAP && (flags & GOVD_MAP_0LEN_ARRAY) != 0)
11166 tree nc = build_omp_clause (input_location, OMP_CLAUSE_MAP);
11167 OMP_CLAUSE_DECL (nc) = decl;
11168 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
11169 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == POINTER_TYPE)
11170 OMP_CLAUSE_DECL (clause)
11171 = build_simple_mem_ref_loc (input_location, decl);
11172 OMP_CLAUSE_DECL (clause)
11173 = build2 (MEM_REF, char_type_node, OMP_CLAUSE_DECL (clause),
11174 build_int_cst (build_pointer_type (char_type_node), 0));
11175 OMP_CLAUSE_SIZE (clause) = size_zero_node;
11176 OMP_CLAUSE_SIZE (nc) = size_zero_node;
11177 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_ALLOC);
11178 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (clause) = 1;
11179 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
11180 OMP_CLAUSE_CHAIN (nc) = chain;
11181 OMP_CLAUSE_CHAIN (clause) = nc;
11182 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
11183 gimplify_omp_ctxp = ctx->outer_context;
11184 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (clause), 0),
11185 pre_p, NULL, is_gimple_val, fb_rvalue);
11186 gimplify_omp_ctxp = ctx;
11188 else if (code == OMP_CLAUSE_MAP)
11190 int kind;
11191 /* Not all combinations of these GOVD_MAP flags are actually valid. */
11192 switch (flags & (GOVD_MAP_TO_ONLY
11193 | GOVD_MAP_FORCE
11194 | GOVD_MAP_FORCE_PRESENT
11195 | GOVD_MAP_ALLOC_ONLY
11196 | GOVD_MAP_FROM_ONLY))
11198 case 0:
11199 kind = GOMP_MAP_TOFROM;
11200 break;
11201 case GOVD_MAP_FORCE:
11202 kind = GOMP_MAP_TOFROM | GOMP_MAP_FLAG_FORCE;
11203 break;
11204 case GOVD_MAP_TO_ONLY:
11205 kind = GOMP_MAP_TO;
11206 break;
11207 case GOVD_MAP_FROM_ONLY:
11208 kind = GOMP_MAP_FROM;
11209 break;
11210 case GOVD_MAP_ALLOC_ONLY:
11211 kind = GOMP_MAP_ALLOC;
11212 break;
11213 case GOVD_MAP_TO_ONLY | GOVD_MAP_FORCE:
11214 kind = GOMP_MAP_TO | GOMP_MAP_FLAG_FORCE;
11215 break;
11216 case GOVD_MAP_FORCE_PRESENT:
11217 kind = GOMP_MAP_FORCE_PRESENT;
11218 break;
11219 default:
11220 gcc_unreachable ();
11222 OMP_CLAUSE_SET_MAP_KIND (clause, kind);
11223 /* Setting of the implicit flag for the runtime is currently disabled for
11224 OpenACC. */
11225 if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0)
11226 OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (clause) = 1;
11227 if (DECL_SIZE (decl)
11228 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
11230 tree decl2 = DECL_VALUE_EXPR (decl);
11231 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
11232 decl2 = TREE_OPERAND (decl2, 0);
11233 gcc_assert (DECL_P (decl2));
11234 tree mem = build_simple_mem_ref (decl2);
11235 OMP_CLAUSE_DECL (clause) = mem;
11236 OMP_CLAUSE_SIZE (clause) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
11237 if (gimplify_omp_ctxp->outer_context)
11239 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
11240 omp_notice_variable (ctx, decl2, true);
11241 omp_notice_variable (ctx, OMP_CLAUSE_SIZE (clause), true);
11243 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
11244 OMP_CLAUSE_MAP);
11245 OMP_CLAUSE_DECL (nc) = decl;
11246 OMP_CLAUSE_SIZE (nc) = size_zero_node;
11247 if (gimplify_omp_ctxp->target_firstprivatize_array_bases)
11248 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
11249 else
11250 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
11251 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
11252 OMP_CLAUSE_CHAIN (clause) = nc;
11254 else if (gimplify_omp_ctxp->target_firstprivatize_array_bases
11255 && omp_privatize_by_reference (decl))
11257 OMP_CLAUSE_DECL (clause) = build_simple_mem_ref (decl);
11258 OMP_CLAUSE_SIZE (clause)
11259 = unshare_expr (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))));
11260 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
11261 gimplify_omp_ctxp = ctx->outer_context;
11262 gimplify_expr (&OMP_CLAUSE_SIZE (clause),
11263 pre_p, NULL, is_gimple_val, fb_rvalue);
11264 gimplify_omp_ctxp = ctx;
11265 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
11266 OMP_CLAUSE_MAP);
11267 OMP_CLAUSE_DECL (nc) = decl;
11268 OMP_CLAUSE_SIZE (nc) = size_zero_node;
11269 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_REFERENCE);
11270 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
11271 OMP_CLAUSE_CHAIN (clause) = nc;
11273 else
11274 OMP_CLAUSE_SIZE (clause) = DECL_SIZE_UNIT (decl);
11276 if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_LASTPRIVATE) != 0)
11278 tree nc = build_omp_clause (input_location, OMP_CLAUSE_LASTPRIVATE);
11279 OMP_CLAUSE_DECL (nc) = decl;
11280 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (nc) = 1;
11281 OMP_CLAUSE_CHAIN (nc) = chain;
11282 OMP_CLAUSE_CHAIN (clause) = nc;
11283 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
11284 gimplify_omp_ctxp = ctx->outer_context;
11285 lang_hooks.decls.omp_finish_clause (nc, pre_p,
11286 (ctx->region_type & ORT_ACC) != 0);
11287 gimplify_omp_ctxp = ctx;
11289 *list_p = clause;
11290 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
11291 gimplify_omp_ctxp = ctx->outer_context;
11292 /* Don't call omp_finish_clause on implicitly added OMP_CLAUSE_PRIVATE
11293 in simd. Those are only added for the local vars inside of simd body
11294 and they don't need to be e.g. default constructible. */
11295 if (code != OMP_CLAUSE_PRIVATE || ctx->region_type != ORT_SIMD)
11296 lang_hooks.decls.omp_finish_clause (clause, pre_p,
11297 (ctx->region_type & ORT_ACC) != 0);
11298 if (gimplify_omp_ctxp)
11299 for (; clause != chain; clause = OMP_CLAUSE_CHAIN (clause))
11300 if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_MAP
11301 && DECL_P (OMP_CLAUSE_SIZE (clause)))
11302 omp_notice_variable (gimplify_omp_ctxp, OMP_CLAUSE_SIZE (clause),
11303 true);
11304 gimplify_omp_ctxp = ctx;
11305 return 0;
11308 static void
11309 gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
11310 enum tree_code code)
11312 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
11313 tree *orig_list_p = list_p;
11314 tree c, decl;
11315 bool has_inscan_reductions = false;
11317 if (body)
11319 struct gimplify_omp_ctx *octx;
11320 for (octx = ctx; octx; octx = octx->outer_context)
11321 if ((octx->region_type & (ORT_PARALLEL | ORT_TASK | ORT_TEAMS)) != 0)
11322 break;
11323 if (octx)
11325 struct walk_stmt_info wi;
11326 memset (&wi, 0, sizeof (wi));
11327 walk_gimple_seq (body, omp_find_stores_stmt,
11328 omp_find_stores_op, &wi);
11332 if (ctx->add_safelen1)
11334 /* If there are VLAs in the body of simd loop, prevent
11335 vectorization. */
11336 gcc_assert (ctx->region_type == ORT_SIMD);
11337 c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_SAFELEN);
11338 OMP_CLAUSE_SAFELEN_EXPR (c) = integer_one_node;
11339 OMP_CLAUSE_CHAIN (c) = *list_p;
11340 *list_p = c;
11341 list_p = &OMP_CLAUSE_CHAIN (c);
11344 if (ctx->region_type == ORT_WORKSHARE
11345 && ctx->outer_context
11346 && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL)
11348 for (c = ctx->outer_context->clauses; c; c = OMP_CLAUSE_CHAIN (c))
11349 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
11350 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
11352 decl = OMP_CLAUSE_DECL (c);
11353 splay_tree_node n
11354 = splay_tree_lookup (ctx->outer_context->variables,
11355 (splay_tree_key) decl);
11356 gcc_checking_assert (!splay_tree_lookup (ctx->variables,
11357 (splay_tree_key) decl));
11358 omp_add_variable (ctx, decl, n->value);
11359 tree c2 = copy_node (c);
11360 OMP_CLAUSE_CHAIN (c2) = *list_p;
11361 *list_p = c2;
11362 if ((n->value & GOVD_FIRSTPRIVATE) == 0)
11363 continue;
11364 c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
11365 OMP_CLAUSE_FIRSTPRIVATE);
11366 OMP_CLAUSE_DECL (c2) = decl;
11367 OMP_CLAUSE_CHAIN (c2) = *list_p;
11368 *list_p = c2;
11371 while ((c = *list_p) != NULL)
11373 splay_tree_node n;
11374 bool remove = false;
11376 switch (OMP_CLAUSE_CODE (c))
11378 case OMP_CLAUSE_FIRSTPRIVATE:
11379 if ((ctx->region_type & ORT_TARGET)
11380 && (ctx->region_type & ORT_ACC) == 0
11381 && TYPE_ATOMIC (strip_array_types
11382 (TREE_TYPE (OMP_CLAUSE_DECL (c)))))
11384 error_at (OMP_CLAUSE_LOCATION (c),
11385 "%<_Atomic%> %qD in %<firstprivate%> clause on "
11386 "%<target%> construct", OMP_CLAUSE_DECL (c));
11387 remove = true;
11388 break;
11390 if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c))
11392 decl = OMP_CLAUSE_DECL (c);
11393 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11394 if ((n->value & GOVD_MAP) != 0)
11396 remove = true;
11397 break;
11399 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT_TARGET (c) = 0;
11400 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c) = 0;
11402 /* FALLTHRU */
11403 case OMP_CLAUSE_PRIVATE:
11404 case OMP_CLAUSE_SHARED:
11405 case OMP_CLAUSE_LINEAR:
11406 decl = OMP_CLAUSE_DECL (c);
11407 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11408 remove = !(n->value & GOVD_SEEN);
11409 if ((n->value & GOVD_LASTPRIVATE_CONDITIONAL) != 0
11410 && code == OMP_PARALLEL
11411 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
11412 remove = true;
11413 if (! remove)
11415 bool shared = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED;
11416 if ((n->value & GOVD_DEBUG_PRIVATE)
11417 || lang_hooks.decls.omp_private_debug_clause (decl, shared))
11419 gcc_assert ((n->value & GOVD_DEBUG_PRIVATE) == 0
11420 || ((n->value & GOVD_DATA_SHARE_CLASS)
11421 == GOVD_SHARED));
11422 OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_PRIVATE);
11423 OMP_CLAUSE_PRIVATE_DEBUG (c) = 1;
11425 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
11426 && ctx->has_depend
11427 && DECL_P (decl))
11428 n->value |= GOVD_WRITTEN;
11429 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
11430 && (n->value & GOVD_WRITTEN) == 0
11431 && DECL_P (decl)
11432 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
11433 OMP_CLAUSE_SHARED_READONLY (c) = 1;
11434 else if (DECL_P (decl)
11435 && ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
11436 && (n->value & GOVD_WRITTEN) != 0)
11437 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
11438 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
11439 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
11440 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
11442 else
11443 n->value &= ~GOVD_EXPLICIT;
11444 break;
11446 case OMP_CLAUSE_LASTPRIVATE:
11447 /* Make sure OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE is set to
11448 accurately reflect the presence of a FIRSTPRIVATE clause. */
11449 decl = OMP_CLAUSE_DECL (c);
11450 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11451 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c)
11452 = (n->value & GOVD_FIRSTPRIVATE) != 0;
11453 if (code == OMP_DISTRIBUTE
11454 && OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
11456 remove = true;
11457 error_at (OMP_CLAUSE_LOCATION (c),
11458 "same variable used in %<firstprivate%> and "
11459 "%<lastprivate%> clauses on %<distribute%> "
11460 "construct");
11462 if (!remove
11463 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
11464 && DECL_P (decl)
11465 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
11466 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
11467 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) && code == OMP_PARALLEL)
11468 remove = true;
11469 break;
11471 case OMP_CLAUSE_ALIGNED:
11472 decl = OMP_CLAUSE_DECL (c);
11473 if (!is_global_var (decl))
11475 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11476 remove = n == NULL || !(n->value & GOVD_SEEN);
11477 if (!remove && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
11479 struct gimplify_omp_ctx *octx;
11480 if (n != NULL
11481 && (n->value & (GOVD_DATA_SHARE_CLASS
11482 & ~GOVD_FIRSTPRIVATE)))
11483 remove = true;
11484 else
11485 for (octx = ctx->outer_context; octx;
11486 octx = octx->outer_context)
11488 n = splay_tree_lookup (octx->variables,
11489 (splay_tree_key) decl);
11490 if (n == NULL)
11491 continue;
11492 if (n->value & GOVD_LOCAL)
11493 break;
11494 /* We have to avoid assigning a shared variable
11495 to itself when trying to add
11496 __builtin_assume_aligned. */
11497 if (n->value & GOVD_SHARED)
11499 remove = true;
11500 break;
11505 else if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
11507 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11508 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
11509 remove = true;
11511 break;
11513 case OMP_CLAUSE_HAS_DEVICE_ADDR:
11514 decl = OMP_CLAUSE_DECL (c);
11515 while (TREE_CODE (decl) == INDIRECT_REF
11516 || TREE_CODE (decl) == ARRAY_REF)
11517 decl = TREE_OPERAND (decl, 0);
11518 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11519 remove = n == NULL || !(n->value & GOVD_SEEN);
11520 break;
11522 case OMP_CLAUSE_IS_DEVICE_PTR:
11523 case OMP_CLAUSE_NONTEMPORAL:
11524 decl = OMP_CLAUSE_DECL (c);
11525 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11526 remove = n == NULL || !(n->value & GOVD_SEEN);
11527 break;
11529 case OMP_CLAUSE_MAP:
11530 if (code == OMP_TARGET_EXIT_DATA
11531 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER)
11533 remove = true;
11534 break;
11536 decl = OMP_CLAUSE_DECL (c);
11537 /* Data clauses associated with reductions must be
11538 compatible with present_or_copy. Warn and adjust the clause
11539 if that is not the case. */
11540 if (ctx->region_type == ORT_ACC_PARALLEL
11541 || ctx->region_type == ORT_ACC_SERIAL)
11543 tree t = DECL_P (decl) ? decl : TREE_OPERAND (decl, 0);
11544 n = NULL;
11546 if (DECL_P (t))
11547 n = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
11549 if (n && (n->value & GOVD_REDUCTION))
11551 enum gomp_map_kind kind = OMP_CLAUSE_MAP_KIND (c);
11553 OMP_CLAUSE_MAP_IN_REDUCTION (c) = 1;
11554 if ((kind & GOMP_MAP_TOFROM) != GOMP_MAP_TOFROM
11555 && kind != GOMP_MAP_FORCE_PRESENT
11556 && kind != GOMP_MAP_POINTER)
11558 warning_at (OMP_CLAUSE_LOCATION (c), 0,
11559 "incompatible data clause with reduction "
11560 "on %qE; promoting to %<present_or_copy%>",
11561 DECL_NAME (t));
11562 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TOFROM);
11566 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT
11567 && (code == OMP_TARGET_EXIT_DATA || code == OACC_EXIT_DATA))
11569 remove = true;
11570 break;
11572 if (!DECL_P (decl))
11574 if ((ctx->region_type & ORT_TARGET) != 0
11575 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
11577 if (TREE_CODE (decl) == INDIRECT_REF
11578 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
11579 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
11580 == REFERENCE_TYPE))
11581 decl = TREE_OPERAND (decl, 0);
11582 if (TREE_CODE (decl) == COMPONENT_REF)
11584 while (TREE_CODE (decl) == COMPONENT_REF)
11585 decl = TREE_OPERAND (decl, 0);
11586 if (DECL_P (decl))
11588 n = splay_tree_lookup (ctx->variables,
11589 (splay_tree_key) decl);
11590 if (!(n->value & GOVD_SEEN))
11591 remove = true;
11595 break;
11597 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11598 if ((ctx->region_type & ORT_TARGET) != 0
11599 && !(n->value & GOVD_SEEN)
11600 && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) == 0
11601 && (!is_global_var (decl)
11602 || !lookup_attribute ("omp declare target link",
11603 DECL_ATTRIBUTES (decl))))
11605 remove = true;
11606 /* For struct element mapping, if struct is never referenced
11607 in target block and none of the mapping has always modifier,
11608 remove all the struct element mappings, which immediately
11609 follow the GOMP_MAP_STRUCT map clause. */
11610 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT)
11612 HOST_WIDE_INT cnt = tree_to_shwi (OMP_CLAUSE_SIZE (c));
11613 while (cnt--)
11614 OMP_CLAUSE_CHAIN (c)
11615 = OMP_CLAUSE_CHAIN (OMP_CLAUSE_CHAIN (c));
11618 else if (DECL_SIZE (decl)
11619 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST
11620 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_POINTER
11621 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_POINTER
11622 && (OMP_CLAUSE_MAP_KIND (c)
11623 != GOMP_MAP_FIRSTPRIVATE_REFERENCE))
11625 /* For GOMP_MAP_FORCE_DEVICEPTR, we'll never enter here, because
11626 for these, TREE_CODE (DECL_SIZE (decl)) will always be
11627 INTEGER_CST. */
11628 gcc_assert (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FORCE_DEVICEPTR);
11630 tree decl2 = DECL_VALUE_EXPR (decl);
11631 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
11632 decl2 = TREE_OPERAND (decl2, 0);
11633 gcc_assert (DECL_P (decl2));
11634 tree mem = build_simple_mem_ref (decl2);
11635 OMP_CLAUSE_DECL (c) = mem;
11636 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
11637 if (ctx->outer_context)
11639 omp_notice_variable (ctx->outer_context, decl2, true);
11640 omp_notice_variable (ctx->outer_context,
11641 OMP_CLAUSE_SIZE (c), true);
11643 if (((ctx->region_type & ORT_TARGET) != 0
11644 || !ctx->target_firstprivatize_array_bases)
11645 && ((n->value & GOVD_SEEN) == 0
11646 || (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) == 0))
11648 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
11649 OMP_CLAUSE_MAP);
11650 OMP_CLAUSE_DECL (nc) = decl;
11651 OMP_CLAUSE_SIZE (nc) = size_zero_node;
11652 if (ctx->target_firstprivatize_array_bases)
11653 OMP_CLAUSE_SET_MAP_KIND (nc,
11654 GOMP_MAP_FIRSTPRIVATE_POINTER);
11655 else
11656 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
11657 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
11658 OMP_CLAUSE_CHAIN (c) = nc;
11659 c = nc;
11662 else
11664 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
11665 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
11666 gcc_assert ((n->value & GOVD_SEEN) == 0
11667 || ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
11668 == 0));
11670 break;
11672 case OMP_CLAUSE_TO:
11673 case OMP_CLAUSE_FROM:
11674 case OMP_CLAUSE__CACHE_:
11675 decl = OMP_CLAUSE_DECL (c);
11676 if (!DECL_P (decl))
11677 break;
11678 if (DECL_SIZE (decl)
11679 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
11681 tree decl2 = DECL_VALUE_EXPR (decl);
11682 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
11683 decl2 = TREE_OPERAND (decl2, 0);
11684 gcc_assert (DECL_P (decl2));
11685 tree mem = build_simple_mem_ref (decl2);
11686 OMP_CLAUSE_DECL (c) = mem;
11687 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
11688 if (ctx->outer_context)
11690 omp_notice_variable (ctx->outer_context, decl2, true);
11691 omp_notice_variable (ctx->outer_context,
11692 OMP_CLAUSE_SIZE (c), true);
11695 else if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
11696 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
11697 break;
11699 case OMP_CLAUSE_REDUCTION:
11700 if (OMP_CLAUSE_REDUCTION_INSCAN (c))
11702 decl = OMP_CLAUSE_DECL (c);
11703 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11704 if ((n->value & GOVD_REDUCTION_INSCAN) == 0)
11706 remove = true;
11707 error_at (OMP_CLAUSE_LOCATION (c),
11708 "%qD specified in %<inscan%> %<reduction%> clause "
11709 "but not in %<scan%> directive clause", decl);
11710 break;
11712 has_inscan_reductions = true;
11714 /* FALLTHRU */
11715 case OMP_CLAUSE_IN_REDUCTION:
11716 case OMP_CLAUSE_TASK_REDUCTION:
11717 decl = OMP_CLAUSE_DECL (c);
11718 /* OpenACC reductions need a present_or_copy data clause.
11719 Add one if necessary. Emit error when the reduction is private. */
11720 if (ctx->region_type == ORT_ACC_PARALLEL
11721 || ctx->region_type == ORT_ACC_SERIAL)
11723 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11724 if (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
11726 remove = true;
11727 error_at (OMP_CLAUSE_LOCATION (c), "invalid private "
11728 "reduction on %qE", DECL_NAME (decl));
11730 else if ((n->value & GOVD_MAP) == 0)
11732 tree next = OMP_CLAUSE_CHAIN (c);
11733 tree nc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_MAP);
11734 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_TOFROM);
11735 OMP_CLAUSE_DECL (nc) = decl;
11736 OMP_CLAUSE_CHAIN (c) = nc;
11737 lang_hooks.decls.omp_finish_clause (nc, pre_p,
11738 (ctx->region_type
11739 & ORT_ACC) != 0);
11740 while (1)
11742 OMP_CLAUSE_MAP_IN_REDUCTION (nc) = 1;
11743 if (OMP_CLAUSE_CHAIN (nc) == NULL)
11744 break;
11745 nc = OMP_CLAUSE_CHAIN (nc);
11747 OMP_CLAUSE_CHAIN (nc) = next;
11748 n->value |= GOVD_MAP;
11751 if (DECL_P (decl)
11752 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
11753 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
11754 break;
11756 case OMP_CLAUSE_ALLOCATE:
11757 decl = OMP_CLAUSE_DECL (c);
11758 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11759 if (n != NULL && !(n->value & GOVD_SEEN))
11761 if ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE | GOVD_LINEAR))
11762 != 0
11763 && (n->value & (GOVD_REDUCTION | GOVD_LASTPRIVATE)) == 0)
11764 remove = true;
11766 if (!remove
11767 && OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
11768 && TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)) != INTEGER_CST
11769 && ((ctx->region_type & (ORT_PARALLEL | ORT_TARGET)) != 0
11770 || (ctx->region_type & ORT_TASKLOOP) == ORT_TASK
11771 || (ctx->region_type & ORT_HOST_TEAMS) == ORT_HOST_TEAMS))
11773 tree allocator = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
11774 n = splay_tree_lookup (ctx->variables, (splay_tree_key) allocator);
11775 if (n == NULL)
11777 enum omp_clause_default_kind default_kind
11778 = ctx->default_kind;
11779 ctx->default_kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
11780 omp_notice_variable (ctx, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
11781 true);
11782 ctx->default_kind = default_kind;
11784 else
11785 omp_notice_variable (ctx, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
11786 true);
11788 break;
11790 case OMP_CLAUSE_COPYIN:
11791 case OMP_CLAUSE_COPYPRIVATE:
11792 case OMP_CLAUSE_IF:
11793 case OMP_CLAUSE_NUM_THREADS:
11794 case OMP_CLAUSE_NUM_TEAMS:
11795 case OMP_CLAUSE_THREAD_LIMIT:
11796 case OMP_CLAUSE_DIST_SCHEDULE:
11797 case OMP_CLAUSE_DEVICE:
11798 case OMP_CLAUSE_SCHEDULE:
11799 case OMP_CLAUSE_NOWAIT:
11800 case OMP_CLAUSE_ORDERED:
11801 case OMP_CLAUSE_DEFAULT:
11802 case OMP_CLAUSE_UNTIED:
11803 case OMP_CLAUSE_COLLAPSE:
11804 case OMP_CLAUSE_FINAL:
11805 case OMP_CLAUSE_MERGEABLE:
11806 case OMP_CLAUSE_PROC_BIND:
11807 case OMP_CLAUSE_SAFELEN:
11808 case OMP_CLAUSE_SIMDLEN:
11809 case OMP_CLAUSE_DEPEND:
11810 case OMP_CLAUSE_PRIORITY:
11811 case OMP_CLAUSE_GRAINSIZE:
11812 case OMP_CLAUSE_NUM_TASKS:
11813 case OMP_CLAUSE_NOGROUP:
11814 case OMP_CLAUSE_THREADS:
11815 case OMP_CLAUSE_SIMD:
11816 case OMP_CLAUSE_FILTER:
11817 case OMP_CLAUSE_HINT:
11818 case OMP_CLAUSE_DEFAULTMAP:
11819 case OMP_CLAUSE_ORDER:
11820 case OMP_CLAUSE_BIND:
11821 case OMP_CLAUSE_DETACH:
11822 case OMP_CLAUSE_USE_DEVICE_PTR:
11823 case OMP_CLAUSE_USE_DEVICE_ADDR:
11824 case OMP_CLAUSE_ASYNC:
11825 case OMP_CLAUSE_WAIT:
11826 case OMP_CLAUSE_INDEPENDENT:
11827 case OMP_CLAUSE_NUM_GANGS:
11828 case OMP_CLAUSE_NUM_WORKERS:
11829 case OMP_CLAUSE_VECTOR_LENGTH:
11830 case OMP_CLAUSE_GANG:
11831 case OMP_CLAUSE_WORKER:
11832 case OMP_CLAUSE_VECTOR:
11833 case OMP_CLAUSE_AUTO:
11834 case OMP_CLAUSE_SEQ:
11835 case OMP_CLAUSE_TILE:
11836 case OMP_CLAUSE_IF_PRESENT:
11837 case OMP_CLAUSE_FINALIZE:
11838 case OMP_CLAUSE_INCLUSIVE:
11839 case OMP_CLAUSE_EXCLUSIVE:
11840 break;
11842 case OMP_CLAUSE_NOHOST:
11843 default:
11844 gcc_unreachable ();
11847 if (remove)
11848 *list_p = OMP_CLAUSE_CHAIN (c);
11849 else
11850 list_p = &OMP_CLAUSE_CHAIN (c);
11853 /* Add in any implicit data sharing. */
11854 struct gimplify_adjust_omp_clauses_data data;
11855 if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0)
11857 /* OpenMP. Implicit clauses are added at the start of the clause list,
11858 but after any non-map clauses. */
11859 tree *implicit_add_list_p = orig_list_p;
11860 while (*implicit_add_list_p
11861 && OMP_CLAUSE_CODE (*implicit_add_list_p) != OMP_CLAUSE_MAP)
11862 implicit_add_list_p = &OMP_CLAUSE_CHAIN (*implicit_add_list_p);
11863 data.list_p = implicit_add_list_p;
11865 else
11866 /* OpenACC. */
11867 data.list_p = list_p;
11868 data.pre_p = pre_p;
11869 splay_tree_foreach (ctx->variables, gimplify_adjust_omp_clauses_1, &data);
11871 if (has_inscan_reductions)
11872 for (c = *orig_list_p; c; c = OMP_CLAUSE_CHAIN (c))
11873 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
11874 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
11876 error_at (OMP_CLAUSE_LOCATION (c),
11877 "%<inscan%> %<reduction%> clause used together with "
11878 "%<linear%> clause for a variable other than loop "
11879 "iterator");
11880 break;
11883 gimplify_omp_ctxp = ctx->outer_context;
11884 delete_omp_context (ctx);
11887 /* Return 0 if CONSTRUCTS selectors don't match the OpenMP context,
11888 -1 if unknown yet (simd is involved, won't be known until vectorization)
11889 and 1 if they do. If SCORES is non-NULL, it should point to an array
11890 of at least 2*NCONSTRUCTS+2 ints, and will be filled with the positions
11891 of the CONSTRUCTS (position -1 if it will never match) followed by
11892 number of constructs in the OpenMP context construct trait. If the
11893 score depends on whether it will be in a declare simd clone or not,
11894 the function returns 2 and there will be two sets of the scores, the first
11895 one for the case that it is not in a declare simd clone, the other
11896 that it is in a declare simd clone. */
11899 omp_construct_selector_matches (enum tree_code *constructs, int nconstructs,
11900 int *scores)
11902 int matched = 0, cnt = 0;
11903 bool simd_seen = false;
11904 bool target_seen = false;
11905 int declare_simd_cnt = -1;
11906 auto_vec<enum tree_code, 16> codes;
11907 for (struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; ctx;)
11909 if (((ctx->region_type & ORT_PARALLEL) && ctx->code == OMP_PARALLEL)
11910 || ((ctx->region_type & (ORT_TARGET | ORT_IMPLICIT_TARGET | ORT_ACC))
11911 == ORT_TARGET && ctx->code == OMP_TARGET)
11912 || ((ctx->region_type & ORT_TEAMS) && ctx->code == OMP_TEAMS)
11913 || (ctx->region_type == ORT_WORKSHARE && ctx->code == OMP_FOR)
11914 || (ctx->region_type == ORT_SIMD
11915 && ctx->code == OMP_SIMD
11916 && !omp_find_clause (ctx->clauses, OMP_CLAUSE_BIND)))
11918 ++cnt;
11919 if (scores)
11920 codes.safe_push (ctx->code);
11921 else if (matched < nconstructs && ctx->code == constructs[matched])
11923 if (ctx->code == OMP_SIMD)
11925 if (matched)
11926 return 0;
11927 simd_seen = true;
11929 ++matched;
11931 if (ctx->code == OMP_TARGET)
11933 if (scores == NULL)
11934 return matched < nconstructs ? 0 : simd_seen ? -1 : 1;
11935 target_seen = true;
11936 break;
11939 else if (ctx->region_type == ORT_WORKSHARE
11940 && ctx->code == OMP_LOOP
11941 && ctx->outer_context
11942 && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL
11943 && ctx->outer_context->outer_context
11944 && ctx->outer_context->outer_context->code == OMP_LOOP
11945 && ctx->outer_context->outer_context->distribute)
11946 ctx = ctx->outer_context->outer_context;
11947 ctx = ctx->outer_context;
11949 if (!target_seen
11950 && lookup_attribute ("omp declare simd",
11951 DECL_ATTRIBUTES (current_function_decl)))
11953 /* Declare simd is a maybe case, it is supposed to be added only to the
11954 omp-simd-clone.cc added clones and not to the base function. */
11955 declare_simd_cnt = cnt++;
11956 if (scores)
11957 codes.safe_push (OMP_SIMD);
11958 else if (cnt == 0
11959 && constructs[0] == OMP_SIMD)
11961 gcc_assert (matched == 0);
11962 simd_seen = true;
11963 if (++matched == nconstructs)
11964 return -1;
11967 if (tree attr = lookup_attribute ("omp declare variant variant",
11968 DECL_ATTRIBUTES (current_function_decl)))
11970 enum tree_code variant_constructs[5];
11971 int variant_nconstructs = 0;
11972 if (!target_seen)
11973 variant_nconstructs
11974 = omp_constructor_traits_to_codes (TREE_VALUE (attr),
11975 variant_constructs);
11976 for (int i = 0; i < variant_nconstructs; i++)
11978 ++cnt;
11979 if (scores)
11980 codes.safe_push (variant_constructs[i]);
11981 else if (matched < nconstructs
11982 && variant_constructs[i] == constructs[matched])
11984 if (variant_constructs[i] == OMP_SIMD)
11986 if (matched)
11987 return 0;
11988 simd_seen = true;
11990 ++matched;
11994 if (!target_seen
11995 && lookup_attribute ("omp declare target block",
11996 DECL_ATTRIBUTES (current_function_decl)))
11998 if (scores)
11999 codes.safe_push (OMP_TARGET);
12000 else if (matched < nconstructs && constructs[matched] == OMP_TARGET)
12001 ++matched;
12003 if (scores)
12005 for (int pass = 0; pass < (declare_simd_cnt == -1 ? 1 : 2); pass++)
12007 int j = codes.length () - 1;
12008 for (int i = nconstructs - 1; i >= 0; i--)
12010 while (j >= 0
12011 && (pass != 0 || declare_simd_cnt != j)
12012 && constructs[i] != codes[j])
12013 --j;
12014 if (pass == 0 && declare_simd_cnt != -1 && j > declare_simd_cnt)
12015 *scores++ = j - 1;
12016 else
12017 *scores++ = j;
12019 *scores++ = ((pass == 0 && declare_simd_cnt != -1)
12020 ? codes.length () - 1 : codes.length ());
12022 return declare_simd_cnt == -1 ? 1 : 2;
12024 if (matched == nconstructs)
12025 return simd_seen ? -1 : 1;
12026 return 0;
12029 /* Gimplify OACC_CACHE. */
12031 static void
12032 gimplify_oacc_cache (tree *expr_p, gimple_seq *pre_p)
12034 tree expr = *expr_p;
12036 gimplify_scan_omp_clauses (&OACC_CACHE_CLAUSES (expr), pre_p, ORT_ACC,
12037 OACC_CACHE);
12038 gimplify_adjust_omp_clauses (pre_p, NULL, &OACC_CACHE_CLAUSES (expr),
12039 OACC_CACHE);
12041 /* TODO: Do something sensible with this information. */
12043 *expr_p = NULL_TREE;
12046 /* Helper function of gimplify_oacc_declare. The helper's purpose is to,
12047 if required, translate 'kind' in CLAUSE into an 'entry' kind and 'exit'
12048 kind. The entry kind will replace the one in CLAUSE, while the exit
12049 kind will be used in a new omp_clause and returned to the caller. */
12051 static tree
12052 gimplify_oacc_declare_1 (tree clause)
12054 HOST_WIDE_INT kind, new_op;
12055 bool ret = false;
12056 tree c = NULL;
12058 kind = OMP_CLAUSE_MAP_KIND (clause);
12060 switch (kind)
12062 case GOMP_MAP_ALLOC:
12063 new_op = GOMP_MAP_RELEASE;
12064 ret = true;
12065 break;
12067 case GOMP_MAP_FROM:
12068 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_FORCE_ALLOC);
12069 new_op = GOMP_MAP_FROM;
12070 ret = true;
12071 break;
12073 case GOMP_MAP_TOFROM:
12074 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_TO);
12075 new_op = GOMP_MAP_FROM;
12076 ret = true;
12077 break;
12079 case GOMP_MAP_DEVICE_RESIDENT:
12080 case GOMP_MAP_FORCE_DEVICEPTR:
12081 case GOMP_MAP_FORCE_PRESENT:
12082 case GOMP_MAP_LINK:
12083 case GOMP_MAP_POINTER:
12084 case GOMP_MAP_TO:
12085 break;
12087 default:
12088 gcc_unreachable ();
12089 break;
12092 if (ret)
12094 c = build_omp_clause (OMP_CLAUSE_LOCATION (clause), OMP_CLAUSE_MAP);
12095 OMP_CLAUSE_SET_MAP_KIND (c, new_op);
12096 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clause);
12099 return c;
12102 /* Gimplify OACC_DECLARE. */
12104 static void
12105 gimplify_oacc_declare (tree *expr_p, gimple_seq *pre_p)
12107 tree expr = *expr_p;
12108 gomp_target *stmt;
12109 tree clauses, t, decl;
12111 clauses = OACC_DECLARE_CLAUSES (expr);
12113 gimplify_scan_omp_clauses (&clauses, pre_p, ORT_TARGET_DATA, OACC_DECLARE);
12114 gimplify_adjust_omp_clauses (pre_p, NULL, &clauses, OACC_DECLARE);
12116 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
12118 decl = OMP_CLAUSE_DECL (t);
12120 if (TREE_CODE (decl) == MEM_REF)
12121 decl = TREE_OPERAND (decl, 0);
12123 if (VAR_P (decl) && !is_oacc_declared (decl))
12125 tree attr = get_identifier ("oacc declare target");
12126 DECL_ATTRIBUTES (decl) = tree_cons (attr, NULL_TREE,
12127 DECL_ATTRIBUTES (decl));
12130 if (VAR_P (decl)
12131 && !is_global_var (decl)
12132 && DECL_CONTEXT (decl) == current_function_decl)
12134 tree c = gimplify_oacc_declare_1 (t);
12135 if (c)
12137 if (oacc_declare_returns == NULL)
12138 oacc_declare_returns = new hash_map<tree, tree>;
12140 oacc_declare_returns->put (decl, c);
12144 if (gimplify_omp_ctxp)
12145 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_SEEN);
12148 stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
12149 clauses);
12151 gimplify_seq_add_stmt (pre_p, stmt);
12153 *expr_p = NULL_TREE;
12156 /* Gimplify the contents of an OMP_PARALLEL statement. This involves
12157 gimplification of the body, as well as scanning the body for used
12158 variables. We need to do this scan now, because variable-sized
12159 decls will be decomposed during gimplification. */
12161 static void
12162 gimplify_omp_parallel (tree *expr_p, gimple_seq *pre_p)
12164 tree expr = *expr_p;
12165 gimple *g;
12166 gimple_seq body = NULL;
12168 gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr), pre_p,
12169 OMP_PARALLEL_COMBINED (expr)
12170 ? ORT_COMBINED_PARALLEL
12171 : ORT_PARALLEL, OMP_PARALLEL);
12173 push_gimplify_context ();
12175 g = gimplify_and_return_first (OMP_PARALLEL_BODY (expr), &body);
12176 if (gimple_code (g) == GIMPLE_BIND)
12177 pop_gimplify_context (g);
12178 else
12179 pop_gimplify_context (NULL);
12181 gimplify_adjust_omp_clauses (pre_p, body, &OMP_PARALLEL_CLAUSES (expr),
12182 OMP_PARALLEL);
12184 g = gimple_build_omp_parallel (body,
12185 OMP_PARALLEL_CLAUSES (expr),
12186 NULL_TREE, NULL_TREE);
12187 if (OMP_PARALLEL_COMBINED (expr))
12188 gimple_omp_set_subcode (g, GF_OMP_PARALLEL_COMBINED);
12189 gimplify_seq_add_stmt (pre_p, g);
12190 *expr_p = NULL_TREE;
12193 /* Gimplify the contents of an OMP_TASK statement. This involves
12194 gimplification of the body, as well as scanning the body for used
12195 variables. We need to do this scan now, because variable-sized
12196 decls will be decomposed during gimplification. */
12198 static void
12199 gimplify_omp_task (tree *expr_p, gimple_seq *pre_p)
12201 tree expr = *expr_p;
12202 gimple *g;
12203 gimple_seq body = NULL;
12205 if (OMP_TASK_BODY (expr) == NULL_TREE)
12206 for (tree c = OMP_TASK_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
12207 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
12208 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_MUTEXINOUTSET)
12210 error_at (OMP_CLAUSE_LOCATION (c),
12211 "%<mutexinoutset%> kind in %<depend%> clause on a "
12212 "%<taskwait%> construct");
12213 break;
12216 gimplify_scan_omp_clauses (&OMP_TASK_CLAUSES (expr), pre_p,
12217 omp_find_clause (OMP_TASK_CLAUSES (expr),
12218 OMP_CLAUSE_UNTIED)
12219 ? ORT_UNTIED_TASK : ORT_TASK, OMP_TASK);
12221 if (OMP_TASK_BODY (expr))
12223 push_gimplify_context ();
12225 g = gimplify_and_return_first (OMP_TASK_BODY (expr), &body);
12226 if (gimple_code (g) == GIMPLE_BIND)
12227 pop_gimplify_context (g);
12228 else
12229 pop_gimplify_context (NULL);
12232 gimplify_adjust_omp_clauses (pre_p, body, &OMP_TASK_CLAUSES (expr),
12233 OMP_TASK);
12235 g = gimple_build_omp_task (body,
12236 OMP_TASK_CLAUSES (expr),
12237 NULL_TREE, NULL_TREE,
12238 NULL_TREE, NULL_TREE, NULL_TREE);
12239 if (OMP_TASK_BODY (expr) == NULL_TREE)
12240 gimple_omp_task_set_taskwait_p (g, true);
12241 gimplify_seq_add_stmt (pre_p, g);
12242 *expr_p = NULL_TREE;
12245 /* Helper function for gimplify_omp_for. If *TP is not a gimple constant,
12246 force it into a temporary initialized in PRE_P and add firstprivate clause
12247 to ORIG_FOR_STMT. */
12249 static void
12250 gimplify_omp_taskloop_expr (tree type, tree *tp, gimple_seq *pre_p,
12251 tree orig_for_stmt)
12253 if (*tp == NULL || is_gimple_constant (*tp))
12254 return;
12256 *tp = get_initialized_tmp_var (*tp, pre_p, NULL, false);
12257 /* Reference to pointer conversion is considered useless,
12258 but is significant for firstprivate clause. Force it
12259 here. */
12260 if (type
12261 && TREE_CODE (type) == POINTER_TYPE
12262 && TREE_CODE (TREE_TYPE (*tp)) == REFERENCE_TYPE)
12264 tree v = create_tmp_var (TYPE_MAIN_VARIANT (type));
12265 tree m = build2 (INIT_EXPR, TREE_TYPE (v), v, *tp);
12266 gimplify_and_add (m, pre_p);
12267 *tp = v;
12270 tree c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
12271 OMP_CLAUSE_DECL (c) = *tp;
12272 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
12273 OMP_FOR_CLAUSES (orig_for_stmt) = c;
12276 /* Gimplify the gross structure of an OMP_FOR statement. */
12278 static enum gimplify_status
12279 gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
12281 tree for_stmt, orig_for_stmt, inner_for_stmt = NULL_TREE, decl, var, t;
12282 enum gimplify_status ret = GS_ALL_DONE;
12283 enum gimplify_status tret;
12284 gomp_for *gfor;
12285 gimple_seq for_body, for_pre_body;
12286 int i;
12287 bitmap has_decl_expr = NULL;
12288 enum omp_region_type ort = ORT_WORKSHARE;
12289 bool openacc = TREE_CODE (*expr_p) == OACC_LOOP;
12291 orig_for_stmt = for_stmt = *expr_p;
12293 bool loop_p = (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_BIND)
12294 != NULL_TREE);
12295 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
12297 tree *data[4] = { NULL, NULL, NULL, NULL };
12298 gcc_assert (TREE_CODE (for_stmt) != OACC_LOOP);
12299 inner_for_stmt = walk_tree (&OMP_FOR_BODY (for_stmt),
12300 find_combined_omp_for, data, NULL);
12301 if (inner_for_stmt == NULL_TREE)
12303 gcc_assert (seen_error ());
12304 *expr_p = NULL_TREE;
12305 return GS_ERROR;
12307 if (data[2] && OMP_FOR_PRE_BODY (*data[2]))
12309 append_to_statement_list_force (OMP_FOR_PRE_BODY (*data[2]),
12310 &OMP_FOR_PRE_BODY (for_stmt));
12311 OMP_FOR_PRE_BODY (*data[2]) = NULL_TREE;
12313 if (OMP_FOR_PRE_BODY (inner_for_stmt))
12315 append_to_statement_list_force (OMP_FOR_PRE_BODY (inner_for_stmt),
12316 &OMP_FOR_PRE_BODY (for_stmt));
12317 OMP_FOR_PRE_BODY (inner_for_stmt) = NULL_TREE;
12320 if (data[0])
12322 /* We have some statements or variable declarations in between
12323 the composite construct directives. Move them around the
12324 inner_for_stmt. */
12325 data[0] = expr_p;
12326 for (i = 0; i < 3; i++)
12327 if (data[i])
12329 tree t = *data[i];
12330 if (i < 2 && data[i + 1] == &OMP_BODY (t))
12331 data[i + 1] = data[i];
12332 *data[i] = OMP_BODY (t);
12333 tree body = build3 (BIND_EXPR, void_type_node, NULL_TREE,
12334 NULL_TREE, make_node (BLOCK));
12335 OMP_BODY (t) = body;
12336 append_to_statement_list_force (inner_for_stmt,
12337 &BIND_EXPR_BODY (body));
12338 *data[3] = t;
12339 data[3] = tsi_stmt_ptr (tsi_start (BIND_EXPR_BODY (body)));
12340 gcc_assert (*data[3] == inner_for_stmt);
12342 return GS_OK;
12345 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
12346 if (!loop_p
12347 && OMP_FOR_ORIG_DECLS (inner_for_stmt)
12348 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
12349 i)) == TREE_LIST
12350 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
12351 i)))
12353 tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
12354 /* Class iterators aren't allowed on OMP_SIMD, so the only
12355 case we need to solve is distribute parallel for. They are
12356 allowed on the loop construct, but that is already handled
12357 in gimplify_omp_loop. */
12358 gcc_assert (TREE_CODE (inner_for_stmt) == OMP_FOR
12359 && TREE_CODE (for_stmt) == OMP_DISTRIBUTE
12360 && data[1]);
12361 tree orig_decl = TREE_PURPOSE (orig);
12362 tree last = TREE_VALUE (orig);
12363 tree *pc;
12364 for (pc = &OMP_FOR_CLAUSES (inner_for_stmt);
12365 *pc; pc = &OMP_CLAUSE_CHAIN (*pc))
12366 if ((OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE
12367 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LASTPRIVATE)
12368 && OMP_CLAUSE_DECL (*pc) == orig_decl)
12369 break;
12370 if (*pc == NULL_TREE)
12372 tree *spc;
12373 for (spc = &OMP_PARALLEL_CLAUSES (*data[1]);
12374 *spc; spc = &OMP_CLAUSE_CHAIN (*spc))
12375 if (OMP_CLAUSE_CODE (*spc) == OMP_CLAUSE_PRIVATE
12376 && OMP_CLAUSE_DECL (*spc) == orig_decl)
12377 break;
12378 if (*spc)
12380 tree c = *spc;
12381 *spc = OMP_CLAUSE_CHAIN (c);
12382 OMP_CLAUSE_CHAIN (c) = NULL_TREE;
12383 *pc = c;
12386 if (*pc == NULL_TREE)
12388 else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE)
12390 /* private clause will appear only on inner_for_stmt.
12391 Change it into firstprivate, and add private clause
12392 on for_stmt. */
12393 tree c = copy_node (*pc);
12394 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
12395 OMP_FOR_CLAUSES (for_stmt) = c;
12396 OMP_CLAUSE_CODE (*pc) = OMP_CLAUSE_FIRSTPRIVATE;
12397 lang_hooks.decls.omp_finish_clause (*pc, pre_p, openacc);
12399 else
12401 /* lastprivate clause will appear on both inner_for_stmt
12402 and for_stmt. Add firstprivate clause to
12403 inner_for_stmt. */
12404 tree c = build_omp_clause (OMP_CLAUSE_LOCATION (*pc),
12405 OMP_CLAUSE_FIRSTPRIVATE);
12406 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (*pc);
12407 OMP_CLAUSE_CHAIN (c) = *pc;
12408 *pc = c;
12409 lang_hooks.decls.omp_finish_clause (*pc, pre_p, openacc);
12411 tree c = build_omp_clause (UNKNOWN_LOCATION,
12412 OMP_CLAUSE_FIRSTPRIVATE);
12413 OMP_CLAUSE_DECL (c) = last;
12414 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
12415 OMP_PARALLEL_CLAUSES (*data[1]) = c;
12416 c = build_omp_clause (UNKNOWN_LOCATION,
12417 *pc ? OMP_CLAUSE_SHARED
12418 : OMP_CLAUSE_FIRSTPRIVATE);
12419 OMP_CLAUSE_DECL (c) = orig_decl;
12420 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
12421 OMP_PARALLEL_CLAUSES (*data[1]) = c;
12423 /* Similarly, take care of C++ range for temporaries, those should
12424 be firstprivate on OMP_PARALLEL if any. */
12425 if (data[1])
12426 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
12427 if (OMP_FOR_ORIG_DECLS (inner_for_stmt)
12428 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
12429 i)) == TREE_LIST
12430 && TREE_CHAIN (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
12431 i)))
12433 tree orig
12434 = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
12435 tree v = TREE_CHAIN (orig);
12436 tree c = build_omp_clause (UNKNOWN_LOCATION,
12437 OMP_CLAUSE_FIRSTPRIVATE);
12438 /* First add firstprivate clause for the __for_end artificial
12439 decl. */
12440 OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 1);
12441 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
12442 == REFERENCE_TYPE)
12443 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
12444 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
12445 OMP_PARALLEL_CLAUSES (*data[1]) = c;
12446 if (TREE_VEC_ELT (v, 0))
12448 /* And now the same for __for_range artificial decl if it
12449 exists. */
12450 c = build_omp_clause (UNKNOWN_LOCATION,
12451 OMP_CLAUSE_FIRSTPRIVATE);
12452 OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 0);
12453 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
12454 == REFERENCE_TYPE)
12455 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
12456 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
12457 OMP_PARALLEL_CLAUSES (*data[1]) = c;
12462 switch (TREE_CODE (for_stmt))
12464 case OMP_FOR:
12465 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt))
12467 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
12468 OMP_CLAUSE_SCHEDULE))
12469 error_at (EXPR_LOCATION (for_stmt),
12470 "%qs clause may not appear on non-rectangular %qs",
12471 "schedule", "for");
12472 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED))
12473 error_at (EXPR_LOCATION (for_stmt),
12474 "%qs clause may not appear on non-rectangular %qs",
12475 "ordered", "for");
12477 break;
12478 case OMP_DISTRIBUTE:
12479 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt)
12480 && omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
12481 OMP_CLAUSE_DIST_SCHEDULE))
12482 error_at (EXPR_LOCATION (for_stmt),
12483 "%qs clause may not appear on non-rectangular %qs",
12484 "dist_schedule", "distribute");
12485 break;
12486 case OACC_LOOP:
12487 ort = ORT_ACC;
12488 break;
12489 case OMP_TASKLOOP:
12490 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_UNTIED))
12491 ort = ORT_UNTIED_TASKLOOP;
12492 else
12493 ort = ORT_TASKLOOP;
12494 break;
12495 case OMP_SIMD:
12496 ort = ORT_SIMD;
12497 break;
12498 default:
12499 gcc_unreachable ();
12502 /* Set OMP_CLAUSE_LINEAR_NO_COPYIN flag on explicit linear
12503 clause for the IV. */
12504 if (ort == ORT_SIMD && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
12506 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), 0);
12507 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
12508 decl = TREE_OPERAND (t, 0);
12509 for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
12510 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
12511 && OMP_CLAUSE_DECL (c) == decl)
12513 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
12514 break;
12518 if (TREE_CODE (for_stmt) != OMP_TASKLOOP)
12519 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p, ort,
12520 loop_p && TREE_CODE (for_stmt) != OMP_SIMD
12521 ? OMP_LOOP : TREE_CODE (for_stmt));
12523 if (TREE_CODE (for_stmt) == OMP_DISTRIBUTE)
12524 gimplify_omp_ctxp->distribute = true;
12526 /* Handle OMP_FOR_INIT. */
12527 for_pre_body = NULL;
12528 if ((ort == ORT_SIMD
12529 || (inner_for_stmt && TREE_CODE (inner_for_stmt) == OMP_SIMD))
12530 && OMP_FOR_PRE_BODY (for_stmt))
12532 has_decl_expr = BITMAP_ALLOC (NULL);
12533 if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == DECL_EXPR
12534 && TREE_CODE (DECL_EXPR_DECL (OMP_FOR_PRE_BODY (for_stmt)))
12535 == VAR_DECL)
12537 t = OMP_FOR_PRE_BODY (for_stmt);
12538 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
12540 else if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == STATEMENT_LIST)
12542 tree_stmt_iterator si;
12543 for (si = tsi_start (OMP_FOR_PRE_BODY (for_stmt)); !tsi_end_p (si);
12544 tsi_next (&si))
12546 t = tsi_stmt (si);
12547 if (TREE_CODE (t) == DECL_EXPR
12548 && TREE_CODE (DECL_EXPR_DECL (t)) == VAR_DECL)
12549 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
12553 if (OMP_FOR_PRE_BODY (for_stmt))
12555 if (TREE_CODE (for_stmt) != OMP_TASKLOOP || gimplify_omp_ctxp)
12556 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
12557 else
12559 struct gimplify_omp_ctx ctx;
12560 memset (&ctx, 0, sizeof (ctx));
12561 ctx.region_type = ORT_NONE;
12562 gimplify_omp_ctxp = &ctx;
12563 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
12564 gimplify_omp_ctxp = NULL;
12567 OMP_FOR_PRE_BODY (for_stmt) = NULL_TREE;
12569 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
12570 for_stmt = inner_for_stmt;
12572 /* For taskloop, need to gimplify the start, end and step before the
12573 taskloop, outside of the taskloop omp context. */
12574 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
12576 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
12578 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
12579 gimple_seq *for_pre_p = (gimple_seq_empty_p (for_pre_body)
12580 ? pre_p : &for_pre_body);
12581 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
12582 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
12584 tree v = TREE_OPERAND (t, 1);
12585 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 1),
12586 for_pre_p, orig_for_stmt);
12587 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 2),
12588 for_pre_p, orig_for_stmt);
12590 else
12591 gimplify_omp_taskloop_expr (type, &TREE_OPERAND (t, 1), for_pre_p,
12592 orig_for_stmt);
12594 /* Handle OMP_FOR_COND. */
12595 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
12596 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
12598 tree v = TREE_OPERAND (t, 1);
12599 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 1),
12600 for_pre_p, orig_for_stmt);
12601 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 2),
12602 for_pre_p, orig_for_stmt);
12604 else
12605 gimplify_omp_taskloop_expr (type, &TREE_OPERAND (t, 1), for_pre_p,
12606 orig_for_stmt);
12608 /* Handle OMP_FOR_INCR. */
12609 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
12610 if (TREE_CODE (t) == MODIFY_EXPR)
12612 decl = TREE_OPERAND (t, 0);
12613 t = TREE_OPERAND (t, 1);
12614 tree *tp = &TREE_OPERAND (t, 1);
12615 if (TREE_CODE (t) == PLUS_EXPR && *tp == decl)
12616 tp = &TREE_OPERAND (t, 0);
12618 gimplify_omp_taskloop_expr (NULL_TREE, tp, for_pre_p,
12619 orig_for_stmt);
12623 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (orig_for_stmt), pre_p, ort,
12624 OMP_TASKLOOP);
12627 if (orig_for_stmt != for_stmt)
12628 gimplify_omp_ctxp->combined_loop = true;
12630 for_body = NULL;
12631 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
12632 == TREE_VEC_LENGTH (OMP_FOR_COND (for_stmt)));
12633 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
12634 == TREE_VEC_LENGTH (OMP_FOR_INCR (for_stmt)));
12636 tree c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED);
12637 bool is_doacross = false;
12638 if (c && OMP_CLAUSE_ORDERED_EXPR (c))
12640 is_doacross = true;
12641 gimplify_omp_ctxp->loop_iter_var.create (TREE_VEC_LENGTH
12642 (OMP_FOR_INIT (for_stmt))
12643 * 2);
12645 int collapse = 1, tile = 0;
12646 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_COLLAPSE);
12647 if (c)
12648 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (c));
12649 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_TILE);
12650 if (c)
12651 tile = list_length (OMP_CLAUSE_TILE_LIST (c));
12652 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ALLOCATE);
12653 hash_set<tree> *allocate_uids = NULL;
12654 if (c)
12656 allocate_uids = new hash_set<tree>;
12657 for (; c; c = OMP_CLAUSE_CHAIN (c))
12658 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ALLOCATE)
12659 allocate_uids->add (OMP_CLAUSE_DECL (c));
12661 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
12663 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
12664 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
12665 decl = TREE_OPERAND (t, 0);
12666 gcc_assert (DECL_P (decl));
12667 gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl))
12668 || POINTER_TYPE_P (TREE_TYPE (decl)));
12669 if (is_doacross)
12671 if (TREE_CODE (for_stmt) == OMP_FOR && OMP_FOR_ORIG_DECLS (for_stmt))
12673 tree orig_decl = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
12674 if (TREE_CODE (orig_decl) == TREE_LIST)
12676 orig_decl = TREE_PURPOSE (orig_decl);
12677 if (!orig_decl)
12678 orig_decl = decl;
12680 gimplify_omp_ctxp->loop_iter_var.quick_push (orig_decl);
12682 else
12683 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
12684 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
12687 if (for_stmt == orig_for_stmt)
12689 tree orig_decl = decl;
12690 if (OMP_FOR_ORIG_DECLS (for_stmt))
12692 tree orig_decl = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
12693 if (TREE_CODE (orig_decl) == TREE_LIST)
12695 orig_decl = TREE_PURPOSE (orig_decl);
12696 if (!orig_decl)
12697 orig_decl = decl;
12700 if (is_global_var (orig_decl) && DECL_THREAD_LOCAL_P (orig_decl))
12701 error_at (EXPR_LOCATION (for_stmt),
12702 "threadprivate iteration variable %qD", orig_decl);
12705 /* Make sure the iteration variable is private. */
12706 tree c = NULL_TREE;
12707 tree c2 = NULL_TREE;
12708 if (orig_for_stmt != for_stmt)
12710 /* Preserve this information until we gimplify the inner simd. */
12711 if (has_decl_expr
12712 && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
12713 TREE_PRIVATE (t) = 1;
12715 else if (ort == ORT_SIMD)
12717 splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
12718 (splay_tree_key) decl);
12719 omp_is_private (gimplify_omp_ctxp, decl,
12720 1 + (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
12721 != 1));
12722 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
12724 omp_notice_variable (gimplify_omp_ctxp, decl, true);
12725 if (n->value & GOVD_LASTPRIVATE_CONDITIONAL)
12726 for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
12727 OMP_CLAUSE_LASTPRIVATE);
12728 c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
12729 OMP_CLAUSE_LASTPRIVATE))
12730 if (OMP_CLAUSE_DECL (c3) == decl)
12732 warning_at (OMP_CLAUSE_LOCATION (c3), 0,
12733 "conditional %<lastprivate%> on loop "
12734 "iterator %qD ignored", decl);
12735 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
12736 n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
12739 else if (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1 && !loop_p)
12741 c = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
12742 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
12743 unsigned int flags = GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN;
12744 if ((has_decl_expr
12745 && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
12746 || TREE_PRIVATE (t))
12748 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
12749 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
12751 struct gimplify_omp_ctx *outer
12752 = gimplify_omp_ctxp->outer_context;
12753 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
12755 if (outer->region_type == ORT_WORKSHARE
12756 && outer->combined_loop)
12758 n = splay_tree_lookup (outer->variables,
12759 (splay_tree_key)decl);
12760 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
12762 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
12763 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
12765 else
12767 struct gimplify_omp_ctx *octx = outer->outer_context;
12768 if (octx
12769 && octx->region_type == ORT_COMBINED_PARALLEL
12770 && octx->outer_context
12771 && (octx->outer_context->region_type
12772 == ORT_WORKSHARE)
12773 && octx->outer_context->combined_loop)
12775 octx = octx->outer_context;
12776 n = splay_tree_lookup (octx->variables,
12777 (splay_tree_key)decl);
12778 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
12780 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
12781 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
12788 OMP_CLAUSE_DECL (c) = decl;
12789 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
12790 OMP_FOR_CLAUSES (for_stmt) = c;
12791 omp_add_variable (gimplify_omp_ctxp, decl, flags);
12792 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
12793 omp_lastprivate_for_combined_outer_constructs (outer, decl,
12794 true);
12796 else
12798 bool lastprivate
12799 = (!has_decl_expr
12800 || !bitmap_bit_p (has_decl_expr, DECL_UID (decl)));
12801 if (TREE_PRIVATE (t))
12802 lastprivate = false;
12803 if (loop_p && OMP_FOR_ORIG_DECLS (for_stmt))
12805 tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
12806 if (TREE_CODE (elt) == TREE_LIST && TREE_PURPOSE (elt))
12807 lastprivate = false;
12810 struct gimplify_omp_ctx *outer
12811 = gimplify_omp_ctxp->outer_context;
12812 if (outer && lastprivate)
12813 omp_lastprivate_for_combined_outer_constructs (outer, decl,
12814 true);
12816 c = build_omp_clause (input_location,
12817 lastprivate ? OMP_CLAUSE_LASTPRIVATE
12818 : OMP_CLAUSE_PRIVATE);
12819 OMP_CLAUSE_DECL (c) = decl;
12820 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
12821 OMP_FOR_CLAUSES (for_stmt) = c;
12822 omp_add_variable (gimplify_omp_ctxp, decl,
12823 (lastprivate ? GOVD_LASTPRIVATE : GOVD_PRIVATE)
12824 | GOVD_EXPLICIT | GOVD_SEEN);
12825 c = NULL_TREE;
12828 else if (omp_is_private (gimplify_omp_ctxp, decl, 0))
12830 omp_notice_variable (gimplify_omp_ctxp, decl, true);
12831 splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
12832 (splay_tree_key) decl);
12833 if (n && (n->value & GOVD_LASTPRIVATE_CONDITIONAL))
12834 for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
12835 OMP_CLAUSE_LASTPRIVATE);
12836 c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
12837 OMP_CLAUSE_LASTPRIVATE))
12838 if (OMP_CLAUSE_DECL (c3) == decl)
12840 warning_at (OMP_CLAUSE_LOCATION (c3), 0,
12841 "conditional %<lastprivate%> on loop "
12842 "iterator %qD ignored", decl);
12843 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
12844 n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
12847 else
12848 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN);
12850 /* If DECL is not a gimple register, create a temporary variable to act
12851 as an iteration counter. This is valid, since DECL cannot be
12852 modified in the body of the loop. Similarly for any iteration vars
12853 in simd with collapse > 1 where the iterator vars must be
12854 lastprivate. And similarly for vars mentioned in allocate clauses. */
12855 if (orig_for_stmt != for_stmt)
12856 var = decl;
12857 else if (!is_gimple_reg (decl)
12858 || (ort == ORT_SIMD
12859 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) > 1)
12860 || (allocate_uids && allocate_uids->contains (decl)))
12862 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
12863 /* Make sure omp_add_variable is not called on it prematurely.
12864 We call it ourselves a few lines later. */
12865 gimplify_omp_ctxp = NULL;
12866 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
12867 gimplify_omp_ctxp = ctx;
12868 TREE_OPERAND (t, 0) = var;
12870 gimplify_seq_add_stmt (&for_body, gimple_build_assign (decl, var));
12872 if (ort == ORT_SIMD
12873 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
12875 c2 = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
12876 OMP_CLAUSE_LINEAR_NO_COPYIN (c2) = 1;
12877 OMP_CLAUSE_LINEAR_NO_COPYOUT (c2) = 1;
12878 OMP_CLAUSE_DECL (c2) = var;
12879 OMP_CLAUSE_CHAIN (c2) = OMP_FOR_CLAUSES (for_stmt);
12880 OMP_FOR_CLAUSES (for_stmt) = c2;
12881 omp_add_variable (gimplify_omp_ctxp, var,
12882 GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN);
12883 if (c == NULL_TREE)
12885 c = c2;
12886 c2 = NULL_TREE;
12889 else
12890 omp_add_variable (gimplify_omp_ctxp, var,
12891 GOVD_PRIVATE | GOVD_SEEN);
12893 else
12894 var = decl;
12896 gimplify_omp_ctxp->in_for_exprs = true;
12897 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
12899 tree lb = TREE_OPERAND (t, 1);
12900 tret = gimplify_expr (&TREE_VEC_ELT (lb, 1), &for_pre_body, NULL,
12901 is_gimple_val, fb_rvalue, false);
12902 ret = MIN (ret, tret);
12903 tret = gimplify_expr (&TREE_VEC_ELT (lb, 2), &for_pre_body, NULL,
12904 is_gimple_val, fb_rvalue, false);
12906 else
12907 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
12908 is_gimple_val, fb_rvalue, false);
12909 gimplify_omp_ctxp->in_for_exprs = false;
12910 ret = MIN (ret, tret);
12911 if (ret == GS_ERROR)
12912 return ret;
12914 /* Handle OMP_FOR_COND. */
12915 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
12916 gcc_assert (COMPARISON_CLASS_P (t));
12917 gcc_assert (TREE_OPERAND (t, 0) == decl);
12919 gimplify_omp_ctxp->in_for_exprs = true;
12920 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
12922 tree ub = TREE_OPERAND (t, 1);
12923 tret = gimplify_expr (&TREE_VEC_ELT (ub, 1), &for_pre_body, NULL,
12924 is_gimple_val, fb_rvalue, false);
12925 ret = MIN (ret, tret);
12926 tret = gimplify_expr (&TREE_VEC_ELT (ub, 2), &for_pre_body, NULL,
12927 is_gimple_val, fb_rvalue, false);
12929 else
12930 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
12931 is_gimple_val, fb_rvalue, false);
12932 gimplify_omp_ctxp->in_for_exprs = false;
12933 ret = MIN (ret, tret);
12935 /* Handle OMP_FOR_INCR. */
12936 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
12937 switch (TREE_CODE (t))
12939 case PREINCREMENT_EXPR:
12940 case POSTINCREMENT_EXPR:
12942 tree decl = TREE_OPERAND (t, 0);
12943 /* c_omp_for_incr_canonicalize_ptr() should have been
12944 called to massage things appropriately. */
12945 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
12947 if (orig_for_stmt != for_stmt)
12948 break;
12949 t = build_int_cst (TREE_TYPE (decl), 1);
12950 if (c)
12951 OMP_CLAUSE_LINEAR_STEP (c) = t;
12952 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
12953 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
12954 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
12955 break;
12958 case PREDECREMENT_EXPR:
12959 case POSTDECREMENT_EXPR:
12960 /* c_omp_for_incr_canonicalize_ptr() should have been
12961 called to massage things appropriately. */
12962 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
12963 if (orig_for_stmt != for_stmt)
12964 break;
12965 t = build_int_cst (TREE_TYPE (decl), -1);
12966 if (c)
12967 OMP_CLAUSE_LINEAR_STEP (c) = t;
12968 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
12969 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
12970 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
12971 break;
12973 case MODIFY_EXPR:
12974 gcc_assert (TREE_OPERAND (t, 0) == decl);
12975 TREE_OPERAND (t, 0) = var;
12977 t = TREE_OPERAND (t, 1);
12978 switch (TREE_CODE (t))
12980 case PLUS_EXPR:
12981 if (TREE_OPERAND (t, 1) == decl)
12983 TREE_OPERAND (t, 1) = TREE_OPERAND (t, 0);
12984 TREE_OPERAND (t, 0) = var;
12985 break;
12988 /* Fallthru. */
12989 case MINUS_EXPR:
12990 case POINTER_PLUS_EXPR:
12991 gcc_assert (TREE_OPERAND (t, 0) == decl);
12992 TREE_OPERAND (t, 0) = var;
12993 break;
12994 default:
12995 gcc_unreachable ();
12998 gimplify_omp_ctxp->in_for_exprs = true;
12999 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
13000 is_gimple_val, fb_rvalue, false);
13001 ret = MIN (ret, tret);
13002 if (c)
13004 tree step = TREE_OPERAND (t, 1);
13005 tree stept = TREE_TYPE (decl);
13006 if (POINTER_TYPE_P (stept))
13007 stept = sizetype;
13008 step = fold_convert (stept, step);
13009 if (TREE_CODE (t) == MINUS_EXPR)
13010 step = fold_build1 (NEGATE_EXPR, stept, step);
13011 OMP_CLAUSE_LINEAR_STEP (c) = step;
13012 if (step != TREE_OPERAND (t, 1))
13014 tret = gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c),
13015 &for_pre_body, NULL,
13016 is_gimple_val, fb_rvalue, false);
13017 ret = MIN (ret, tret);
13020 gimplify_omp_ctxp->in_for_exprs = false;
13021 break;
13023 default:
13024 gcc_unreachable ();
13027 if (c2)
13029 gcc_assert (c);
13030 OMP_CLAUSE_LINEAR_STEP (c2) = OMP_CLAUSE_LINEAR_STEP (c);
13033 if ((var != decl || collapse > 1 || tile) && orig_for_stmt == for_stmt)
13035 for (c = OMP_FOR_CLAUSES (for_stmt); c ; c = OMP_CLAUSE_CHAIN (c))
13036 if (((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
13037 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) == NULL)
13038 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
13039 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)
13040 && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c) == NULL))
13041 && OMP_CLAUSE_DECL (c) == decl)
13043 if (is_doacross && (collapse == 1 || i >= collapse))
13044 t = var;
13045 else
13047 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
13048 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
13049 gcc_assert (TREE_OPERAND (t, 0) == var);
13050 t = TREE_OPERAND (t, 1);
13051 gcc_assert (TREE_CODE (t) == PLUS_EXPR
13052 || TREE_CODE (t) == MINUS_EXPR
13053 || TREE_CODE (t) == POINTER_PLUS_EXPR);
13054 gcc_assert (TREE_OPERAND (t, 0) == var);
13055 t = build2 (TREE_CODE (t), TREE_TYPE (decl),
13056 is_doacross ? var : decl,
13057 TREE_OPERAND (t, 1));
13059 gimple_seq *seq;
13060 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
13061 seq = &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c);
13062 else
13063 seq = &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c);
13064 push_gimplify_context ();
13065 gimplify_assign (decl, t, seq);
13066 gimple *bind = NULL;
13067 if (gimplify_ctxp->temps)
13069 bind = gimple_build_bind (NULL_TREE, *seq, NULL_TREE);
13070 *seq = NULL;
13071 gimplify_seq_add_stmt (seq, bind);
13073 pop_gimplify_context (bind);
13076 if (OMP_FOR_NON_RECTANGULAR (for_stmt) && var != decl)
13077 for (int j = i + 1; j < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); j++)
13079 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), j);
13080 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
13081 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
13082 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
13083 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
13084 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), j);
13085 gcc_assert (COMPARISON_CLASS_P (t));
13086 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
13087 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
13088 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
13092 BITMAP_FREE (has_decl_expr);
13093 delete allocate_uids;
13095 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP
13096 || (loop_p && orig_for_stmt == for_stmt))
13098 push_gimplify_context ();
13099 if (TREE_CODE (OMP_FOR_BODY (orig_for_stmt)) != BIND_EXPR)
13101 OMP_FOR_BODY (orig_for_stmt)
13102 = build3 (BIND_EXPR, void_type_node, NULL,
13103 OMP_FOR_BODY (orig_for_stmt), NULL);
13104 TREE_SIDE_EFFECTS (OMP_FOR_BODY (orig_for_stmt)) = 1;
13108 gimple *g = gimplify_and_return_first (OMP_FOR_BODY (orig_for_stmt),
13109 &for_body);
13111 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP
13112 || (loop_p && orig_for_stmt == for_stmt))
13114 if (gimple_code (g) == GIMPLE_BIND)
13115 pop_gimplify_context (g);
13116 else
13117 pop_gimplify_context (NULL);
13120 if (orig_for_stmt != for_stmt)
13121 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
13123 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
13124 decl = TREE_OPERAND (t, 0);
13125 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
13126 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
13127 gimplify_omp_ctxp = ctx->outer_context;
13128 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
13129 gimplify_omp_ctxp = ctx;
13130 omp_add_variable (gimplify_omp_ctxp, var, GOVD_PRIVATE | GOVD_SEEN);
13131 TREE_OPERAND (t, 0) = var;
13132 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
13133 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
13134 TREE_OPERAND (TREE_OPERAND (t, 1), 0) = var;
13135 if (OMP_FOR_NON_RECTANGULAR (for_stmt))
13136 for (int j = i + 1;
13137 j < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); j++)
13139 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), j);
13140 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
13141 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
13142 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
13144 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
13145 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
13147 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), j);
13148 gcc_assert (COMPARISON_CLASS_P (t));
13149 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
13150 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
13152 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
13153 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
13158 gimplify_adjust_omp_clauses (pre_p, for_body,
13159 &OMP_FOR_CLAUSES (orig_for_stmt),
13160 TREE_CODE (orig_for_stmt));
13162 int kind;
13163 switch (TREE_CODE (orig_for_stmt))
13165 case OMP_FOR: kind = GF_OMP_FOR_KIND_FOR; break;
13166 case OMP_SIMD: kind = GF_OMP_FOR_KIND_SIMD; break;
13167 case OMP_DISTRIBUTE: kind = GF_OMP_FOR_KIND_DISTRIBUTE; break;
13168 case OMP_TASKLOOP: kind = GF_OMP_FOR_KIND_TASKLOOP; break;
13169 case OACC_LOOP: kind = GF_OMP_FOR_KIND_OACC_LOOP; break;
13170 default:
13171 gcc_unreachable ();
13173 if (loop_p && kind == GF_OMP_FOR_KIND_SIMD)
13175 gimplify_seq_add_seq (pre_p, for_pre_body);
13176 for_pre_body = NULL;
13178 gfor = gimple_build_omp_for (for_body, kind, OMP_FOR_CLAUSES (orig_for_stmt),
13179 TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)),
13180 for_pre_body);
13181 if (orig_for_stmt != for_stmt)
13182 gimple_omp_for_set_combined_p (gfor, true);
13183 if (gimplify_omp_ctxp
13184 && (gimplify_omp_ctxp->combined_loop
13185 || (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
13186 && gimplify_omp_ctxp->outer_context
13187 && gimplify_omp_ctxp->outer_context->combined_loop)))
13189 gimple_omp_for_set_combined_into_p (gfor, true);
13190 if (gimplify_omp_ctxp->combined_loop)
13191 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_SIMD);
13192 else
13193 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_FOR);
13196 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
13198 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
13199 gimple_omp_for_set_index (gfor, i, TREE_OPERAND (t, 0));
13200 gimple_omp_for_set_initial (gfor, i, TREE_OPERAND (t, 1));
13201 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
13202 gimple_omp_for_set_cond (gfor, i, TREE_CODE (t));
13203 gimple_omp_for_set_final (gfor, i, TREE_OPERAND (t, 1));
13204 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
13205 gimple_omp_for_set_incr (gfor, i, TREE_OPERAND (t, 1));
13208 /* OMP_TASKLOOP is gimplified as two GIMPLE_OMP_FOR taskloop
13209 constructs with GIMPLE_OMP_TASK sandwiched in between them.
13210 The outer taskloop stands for computing the number of iterations,
13211 counts for collapsed loops and holding taskloop specific clauses.
13212 The task construct stands for the effect of data sharing on the
13213 explicit task it creates and the inner taskloop stands for expansion
13214 of the static loop inside of the explicit task construct. */
13215 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
13217 tree *gfor_clauses_ptr = gimple_omp_for_clauses_ptr (gfor);
13218 tree task_clauses = NULL_TREE;
13219 tree c = *gfor_clauses_ptr;
13220 tree *gtask_clauses_ptr = &task_clauses;
13221 tree outer_for_clauses = NULL_TREE;
13222 tree *gforo_clauses_ptr = &outer_for_clauses;
13223 bitmap lastprivate_uids = NULL;
13224 if (omp_find_clause (c, OMP_CLAUSE_ALLOCATE))
13226 c = omp_find_clause (c, OMP_CLAUSE_LASTPRIVATE);
13227 if (c)
13229 lastprivate_uids = BITMAP_ALLOC (NULL);
13230 for (; c; c = omp_find_clause (OMP_CLAUSE_CHAIN (c),
13231 OMP_CLAUSE_LASTPRIVATE))
13232 bitmap_set_bit (lastprivate_uids,
13233 DECL_UID (OMP_CLAUSE_DECL (c)));
13235 c = *gfor_clauses_ptr;
13237 for (; c; c = OMP_CLAUSE_CHAIN (c))
13238 switch (OMP_CLAUSE_CODE (c))
13240 /* These clauses are allowed on task, move them there. */
13241 case OMP_CLAUSE_SHARED:
13242 case OMP_CLAUSE_FIRSTPRIVATE:
13243 case OMP_CLAUSE_DEFAULT:
13244 case OMP_CLAUSE_IF:
13245 case OMP_CLAUSE_UNTIED:
13246 case OMP_CLAUSE_FINAL:
13247 case OMP_CLAUSE_MERGEABLE:
13248 case OMP_CLAUSE_PRIORITY:
13249 case OMP_CLAUSE_REDUCTION:
13250 case OMP_CLAUSE_IN_REDUCTION:
13251 *gtask_clauses_ptr = c;
13252 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13253 break;
13254 case OMP_CLAUSE_PRIVATE:
13255 if (OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c))
13257 /* We want private on outer for and firstprivate
13258 on task. */
13259 *gtask_clauses_ptr
13260 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
13261 OMP_CLAUSE_FIRSTPRIVATE);
13262 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
13263 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL,
13264 openacc);
13265 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
13266 *gforo_clauses_ptr = c;
13267 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13269 else
13271 *gtask_clauses_ptr = c;
13272 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13274 break;
13275 /* These clauses go into outer taskloop clauses. */
13276 case OMP_CLAUSE_GRAINSIZE:
13277 case OMP_CLAUSE_NUM_TASKS:
13278 case OMP_CLAUSE_NOGROUP:
13279 *gforo_clauses_ptr = c;
13280 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13281 break;
13282 /* Collapse clause we duplicate on both taskloops. */
13283 case OMP_CLAUSE_COLLAPSE:
13284 *gfor_clauses_ptr = c;
13285 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13286 *gforo_clauses_ptr = copy_node (c);
13287 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
13288 break;
13289 /* For lastprivate, keep the clause on inner taskloop, and add
13290 a shared clause on task. If the same decl is also firstprivate,
13291 add also firstprivate clause on the inner taskloop. */
13292 case OMP_CLAUSE_LASTPRIVATE:
13293 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
13295 /* For taskloop C++ lastprivate IVs, we want:
13296 1) private on outer taskloop
13297 2) firstprivate and shared on task
13298 3) lastprivate on inner taskloop */
13299 *gtask_clauses_ptr
13300 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
13301 OMP_CLAUSE_FIRSTPRIVATE);
13302 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
13303 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL,
13304 openacc);
13305 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
13306 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c) = 1;
13307 *gforo_clauses_ptr = build_omp_clause (OMP_CLAUSE_LOCATION (c),
13308 OMP_CLAUSE_PRIVATE);
13309 OMP_CLAUSE_DECL (*gforo_clauses_ptr) = OMP_CLAUSE_DECL (c);
13310 OMP_CLAUSE_PRIVATE_TASKLOOP_IV (*gforo_clauses_ptr) = 1;
13311 TREE_TYPE (*gforo_clauses_ptr) = TREE_TYPE (c);
13312 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
13314 *gfor_clauses_ptr = c;
13315 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13316 *gtask_clauses_ptr
13317 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_SHARED);
13318 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
13319 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
13320 OMP_CLAUSE_SHARED_FIRSTPRIVATE (*gtask_clauses_ptr) = 1;
13321 gtask_clauses_ptr
13322 = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
13323 break;
13324 /* Allocate clause we duplicate on task and inner taskloop
13325 if the decl is lastprivate, otherwise just put on task. */
13326 case OMP_CLAUSE_ALLOCATE:
13327 if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
13328 && DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)))
13330 /* Additionally, put firstprivate clause on task
13331 for the allocator if it is not constant. */
13332 *gtask_clauses_ptr
13333 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
13334 OMP_CLAUSE_FIRSTPRIVATE);
13335 OMP_CLAUSE_DECL (*gtask_clauses_ptr)
13336 = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
13337 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
13339 if (lastprivate_uids
13340 && bitmap_bit_p (lastprivate_uids,
13341 DECL_UID (OMP_CLAUSE_DECL (c))))
13343 *gfor_clauses_ptr = c;
13344 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13345 *gtask_clauses_ptr = copy_node (c);
13346 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
13348 else
13350 *gtask_clauses_ptr = c;
13351 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13353 break;
13354 default:
13355 gcc_unreachable ();
13357 *gfor_clauses_ptr = NULL_TREE;
13358 *gtask_clauses_ptr = NULL_TREE;
13359 *gforo_clauses_ptr = NULL_TREE;
13360 BITMAP_FREE (lastprivate_uids);
13361 gimple_set_location (gfor, input_location);
13362 g = gimple_build_bind (NULL_TREE, gfor, NULL_TREE);
13363 g = gimple_build_omp_task (g, task_clauses, NULL_TREE, NULL_TREE,
13364 NULL_TREE, NULL_TREE, NULL_TREE);
13365 gimple_set_location (g, input_location);
13366 gimple_omp_task_set_taskloop_p (g, true);
13367 g = gimple_build_bind (NULL_TREE, g, NULL_TREE);
13368 gomp_for *gforo
13369 = gimple_build_omp_for (g, GF_OMP_FOR_KIND_TASKLOOP, outer_for_clauses,
13370 gimple_omp_for_collapse (gfor),
13371 gimple_omp_for_pre_body (gfor));
13372 gimple_omp_for_set_pre_body (gfor, NULL);
13373 gimple_omp_for_set_combined_p (gforo, true);
13374 gimple_omp_for_set_combined_into_p (gfor, true);
13375 for (i = 0; i < (int) gimple_omp_for_collapse (gfor); i++)
13377 tree type = TREE_TYPE (gimple_omp_for_index (gfor, i));
13378 tree v = create_tmp_var (type);
13379 gimple_omp_for_set_index (gforo, i, v);
13380 t = unshare_expr (gimple_omp_for_initial (gfor, i));
13381 gimple_omp_for_set_initial (gforo, i, t);
13382 gimple_omp_for_set_cond (gforo, i,
13383 gimple_omp_for_cond (gfor, i));
13384 t = unshare_expr (gimple_omp_for_final (gfor, i));
13385 gimple_omp_for_set_final (gforo, i, t);
13386 t = unshare_expr (gimple_omp_for_incr (gfor, i));
13387 gcc_assert (TREE_OPERAND (t, 0) == gimple_omp_for_index (gfor, i));
13388 TREE_OPERAND (t, 0) = v;
13389 gimple_omp_for_set_incr (gforo, i, t);
13390 t = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
13391 OMP_CLAUSE_DECL (t) = v;
13392 OMP_CLAUSE_CHAIN (t) = gimple_omp_for_clauses (gforo);
13393 gimple_omp_for_set_clauses (gforo, t);
13394 if (OMP_FOR_NON_RECTANGULAR (for_stmt))
13396 tree *p1 = NULL, *p2 = NULL;
13397 t = gimple_omp_for_initial (gforo, i);
13398 if (TREE_CODE (t) == TREE_VEC)
13399 p1 = &TREE_VEC_ELT (t, 0);
13400 t = gimple_omp_for_final (gforo, i);
13401 if (TREE_CODE (t) == TREE_VEC)
13403 if (p1)
13404 p2 = &TREE_VEC_ELT (t, 0);
13405 else
13406 p1 = &TREE_VEC_ELT (t, 0);
13408 if (p1)
13410 int j;
13411 for (j = 0; j < i; j++)
13412 if (*p1 == gimple_omp_for_index (gfor, j))
13414 *p1 = gimple_omp_for_index (gforo, j);
13415 if (p2)
13416 *p2 = *p1;
13417 break;
13419 gcc_assert (j < i);
13423 gimplify_seq_add_stmt (pre_p, gforo);
13425 else
13426 gimplify_seq_add_stmt (pre_p, gfor);
13428 if (TREE_CODE (orig_for_stmt) == OMP_FOR)
13430 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
13431 unsigned lastprivate_conditional = 0;
13432 while (ctx
13433 && (ctx->region_type == ORT_TARGET_DATA
13434 || ctx->region_type == ORT_TASKGROUP))
13435 ctx = ctx->outer_context;
13436 if (ctx && (ctx->region_type & ORT_PARALLEL) != 0)
13437 for (tree c = gimple_omp_for_clauses (gfor);
13438 c; c = OMP_CLAUSE_CHAIN (c))
13439 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
13440 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
13441 ++lastprivate_conditional;
13442 if (lastprivate_conditional)
13444 struct omp_for_data fd;
13445 omp_extract_for_data (gfor, &fd, NULL);
13446 tree type = build_array_type_nelts (unsigned_type_for (fd.iter_type),
13447 lastprivate_conditional);
13448 tree var = create_tmp_var_raw (type);
13449 tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__CONDTEMP_);
13450 OMP_CLAUSE_DECL (c) = var;
13451 OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor);
13452 gimple_omp_for_set_clauses (gfor, c);
13453 omp_add_variable (ctx, var, GOVD_CONDTEMP | GOVD_SEEN);
13456 else if (TREE_CODE (orig_for_stmt) == OMP_SIMD)
13458 unsigned lastprivate_conditional = 0;
13459 for (tree c = gimple_omp_for_clauses (gfor); c; c = OMP_CLAUSE_CHAIN (c))
13460 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
13461 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
13462 ++lastprivate_conditional;
13463 if (lastprivate_conditional)
13465 struct omp_for_data fd;
13466 omp_extract_for_data (gfor, &fd, NULL);
13467 tree type = unsigned_type_for (fd.iter_type);
13468 while (lastprivate_conditional--)
13470 tree c = build_omp_clause (UNKNOWN_LOCATION,
13471 OMP_CLAUSE__CONDTEMP_);
13472 OMP_CLAUSE_DECL (c) = create_tmp_var (type);
13473 OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor);
13474 gimple_omp_for_set_clauses (gfor, c);
13479 if (ret != GS_ALL_DONE)
13480 return GS_ERROR;
13481 *expr_p = NULL_TREE;
13482 return GS_ALL_DONE;
13485 /* Helper for gimplify_omp_loop, called through walk_tree. */
13487 static tree
13488 note_no_context_vars (tree *tp, int *, void *data)
13490 if (VAR_P (*tp)
13491 && DECL_CONTEXT (*tp) == NULL_TREE
13492 && !is_global_var (*tp))
13494 vec<tree> *d = (vec<tree> *) data;
13495 d->safe_push (*tp);
13496 DECL_CONTEXT (*tp) = current_function_decl;
13498 return NULL_TREE;
13501 /* Gimplify the gross structure of an OMP_LOOP statement. */
13503 static enum gimplify_status
13504 gimplify_omp_loop (tree *expr_p, gimple_seq *pre_p)
13506 tree for_stmt = *expr_p;
13507 tree clauses = OMP_FOR_CLAUSES (for_stmt);
13508 struct gimplify_omp_ctx *octx = gimplify_omp_ctxp;
13509 enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
13510 int i;
13512 /* If order is not present, the behavior is as if order(concurrent)
13513 appeared. */
13514 tree order = omp_find_clause (clauses, OMP_CLAUSE_ORDER);
13515 if (order == NULL_TREE)
13517 order = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_ORDER);
13518 OMP_CLAUSE_CHAIN (order) = clauses;
13519 OMP_FOR_CLAUSES (for_stmt) = clauses = order;
13522 tree bind = omp_find_clause (clauses, OMP_CLAUSE_BIND);
13523 if (bind == NULL_TREE)
13525 if (!flag_openmp) /* flag_openmp_simd */
13527 else if (octx && (octx->region_type & ORT_TEAMS) != 0)
13528 kind = OMP_CLAUSE_BIND_TEAMS;
13529 else if (octx && (octx->region_type & ORT_PARALLEL) != 0)
13530 kind = OMP_CLAUSE_BIND_PARALLEL;
13531 else
13533 for (; octx; octx = octx->outer_context)
13535 if ((octx->region_type & ORT_ACC) != 0
13536 || octx->region_type == ORT_NONE
13537 || octx->region_type == ORT_IMPLICIT_TARGET)
13538 continue;
13539 break;
13541 if (octx == NULL && !in_omp_construct)
13542 error_at (EXPR_LOCATION (for_stmt),
13543 "%<bind%> clause not specified on a %<loop%> "
13544 "construct not nested inside another OpenMP construct");
13546 bind = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_BIND);
13547 OMP_CLAUSE_CHAIN (bind) = clauses;
13548 OMP_CLAUSE_BIND_KIND (bind) = kind;
13549 OMP_FOR_CLAUSES (for_stmt) = bind;
13551 else
13552 switch (OMP_CLAUSE_BIND_KIND (bind))
13554 case OMP_CLAUSE_BIND_THREAD:
13555 break;
13556 case OMP_CLAUSE_BIND_PARALLEL:
13557 if (!flag_openmp) /* flag_openmp_simd */
13559 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
13560 break;
13562 for (; octx; octx = octx->outer_context)
13563 if (octx->region_type == ORT_SIMD
13564 && omp_find_clause (octx->clauses, OMP_CLAUSE_BIND) == NULL_TREE)
13566 error_at (EXPR_LOCATION (for_stmt),
13567 "%<bind(parallel)%> on a %<loop%> construct nested "
13568 "inside %<simd%> construct");
13569 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
13570 break;
13572 kind = OMP_CLAUSE_BIND_PARALLEL;
13573 break;
13574 case OMP_CLAUSE_BIND_TEAMS:
13575 if (!flag_openmp) /* flag_openmp_simd */
13577 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
13578 break;
13580 if ((octx
13581 && octx->region_type != ORT_IMPLICIT_TARGET
13582 && octx->region_type != ORT_NONE
13583 && (octx->region_type & ORT_TEAMS) == 0)
13584 || in_omp_construct)
13586 error_at (EXPR_LOCATION (for_stmt),
13587 "%<bind(teams)%> on a %<loop%> region not strictly "
13588 "nested inside of a %<teams%> region");
13589 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
13590 break;
13592 kind = OMP_CLAUSE_BIND_TEAMS;
13593 break;
13594 default:
13595 gcc_unreachable ();
13598 for (tree *pc = &OMP_FOR_CLAUSES (for_stmt); *pc; )
13599 switch (OMP_CLAUSE_CODE (*pc))
13601 case OMP_CLAUSE_REDUCTION:
13602 if (OMP_CLAUSE_REDUCTION_INSCAN (*pc))
13604 error_at (OMP_CLAUSE_LOCATION (*pc),
13605 "%<inscan%> %<reduction%> clause on "
13606 "%qs construct", "loop");
13607 OMP_CLAUSE_REDUCTION_INSCAN (*pc) = 0;
13609 if (OMP_CLAUSE_REDUCTION_TASK (*pc))
13611 error_at (OMP_CLAUSE_LOCATION (*pc),
13612 "invalid %<task%> reduction modifier on construct "
13613 "other than %<parallel%>, %qs or %<sections%>",
13614 lang_GNU_Fortran () ? "do" : "for");
13615 OMP_CLAUSE_REDUCTION_TASK (*pc) = 0;
13617 pc = &OMP_CLAUSE_CHAIN (*pc);
13618 break;
13619 case OMP_CLAUSE_LASTPRIVATE:
13620 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
13622 tree t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
13623 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
13624 if (OMP_CLAUSE_DECL (*pc) == TREE_OPERAND (t, 0))
13625 break;
13626 if (OMP_FOR_ORIG_DECLS (for_stmt)
13627 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt),
13628 i)) == TREE_LIST
13629 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt),
13630 i)))
13632 tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
13633 if (OMP_CLAUSE_DECL (*pc) == TREE_PURPOSE (orig))
13634 break;
13637 if (i == TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)))
13639 error_at (OMP_CLAUSE_LOCATION (*pc),
13640 "%<lastprivate%> clause on a %<loop%> construct refers "
13641 "to a variable %qD which is not the loop iterator",
13642 OMP_CLAUSE_DECL (*pc));
13643 *pc = OMP_CLAUSE_CHAIN (*pc);
13644 break;
13646 pc = &OMP_CLAUSE_CHAIN (*pc);
13647 break;
13648 default:
13649 pc = &OMP_CLAUSE_CHAIN (*pc);
13650 break;
13653 TREE_SET_CODE (for_stmt, OMP_SIMD);
13655 int last;
13656 switch (kind)
13658 case OMP_CLAUSE_BIND_THREAD: last = 0; break;
13659 case OMP_CLAUSE_BIND_PARALLEL: last = 1; break;
13660 case OMP_CLAUSE_BIND_TEAMS: last = 2; break;
13662 for (int pass = 1; pass <= last; pass++)
13664 if (pass == 2)
13666 tree bind = build3 (BIND_EXPR, void_type_node, NULL, NULL,
13667 make_node (BLOCK));
13668 append_to_statement_list (*expr_p, &BIND_EXPR_BODY (bind));
13669 *expr_p = make_node (OMP_PARALLEL);
13670 TREE_TYPE (*expr_p) = void_type_node;
13671 OMP_PARALLEL_BODY (*expr_p) = bind;
13672 OMP_PARALLEL_COMBINED (*expr_p) = 1;
13673 SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (for_stmt));
13674 tree *pc = &OMP_PARALLEL_CLAUSES (*expr_p);
13675 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
13676 if (OMP_FOR_ORIG_DECLS (for_stmt)
13677 && (TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i))
13678 == TREE_LIST))
13680 tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
13681 if (TREE_PURPOSE (elt) && TREE_VALUE (elt))
13683 *pc = build_omp_clause (UNKNOWN_LOCATION,
13684 OMP_CLAUSE_FIRSTPRIVATE);
13685 OMP_CLAUSE_DECL (*pc) = TREE_VALUE (elt);
13686 pc = &OMP_CLAUSE_CHAIN (*pc);
13690 tree t = make_node (pass == 2 ? OMP_DISTRIBUTE : OMP_FOR);
13691 tree *pc = &OMP_FOR_CLAUSES (t);
13692 TREE_TYPE (t) = void_type_node;
13693 OMP_FOR_BODY (t) = *expr_p;
13694 SET_EXPR_LOCATION (t, EXPR_LOCATION (for_stmt));
13695 for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
13696 switch (OMP_CLAUSE_CODE (c))
13698 case OMP_CLAUSE_BIND:
13699 case OMP_CLAUSE_ORDER:
13700 case OMP_CLAUSE_COLLAPSE:
13701 *pc = copy_node (c);
13702 pc = &OMP_CLAUSE_CHAIN (*pc);
13703 break;
13704 case OMP_CLAUSE_PRIVATE:
13705 case OMP_CLAUSE_FIRSTPRIVATE:
13706 /* Only needed on innermost. */
13707 break;
13708 case OMP_CLAUSE_LASTPRIVATE:
13709 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c) && pass != last)
13711 *pc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
13712 OMP_CLAUSE_FIRSTPRIVATE);
13713 OMP_CLAUSE_DECL (*pc) = OMP_CLAUSE_DECL (c);
13714 lang_hooks.decls.omp_finish_clause (*pc, NULL, false);
13715 pc = &OMP_CLAUSE_CHAIN (*pc);
13717 *pc = copy_node (c);
13718 OMP_CLAUSE_LASTPRIVATE_STMT (*pc) = NULL_TREE;
13719 TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
13720 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
13722 if (pass != last)
13723 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (*pc) = 1;
13724 else
13725 lang_hooks.decls.omp_finish_clause (*pc, NULL, false);
13726 OMP_CLAUSE_LASTPRIVATE_LOOP_IV (*pc) = 0;
13728 pc = &OMP_CLAUSE_CHAIN (*pc);
13729 break;
13730 case OMP_CLAUSE_REDUCTION:
13731 *pc = copy_node (c);
13732 OMP_CLAUSE_DECL (*pc) = unshare_expr (OMP_CLAUSE_DECL (c));
13733 TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
13734 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc))
13736 auto_vec<tree> no_context_vars;
13737 int walk_subtrees = 0;
13738 note_no_context_vars (&OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
13739 &walk_subtrees, &no_context_vars);
13740 if (tree p = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c))
13741 note_no_context_vars (&p, &walk_subtrees, &no_context_vars);
13742 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_INIT (c),
13743 note_no_context_vars,
13744 &no_context_vars);
13745 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_MERGE (c),
13746 note_no_context_vars,
13747 &no_context_vars);
13749 OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc)
13750 = copy_node (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c));
13751 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc))
13752 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc)
13753 = copy_node (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c));
13755 hash_map<tree, tree> decl_map;
13756 decl_map.put (OMP_CLAUSE_DECL (c), OMP_CLAUSE_DECL (c));
13757 decl_map.put (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
13758 OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc));
13759 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc))
13760 decl_map.put (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
13761 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc));
13763 copy_body_data id;
13764 memset (&id, 0, sizeof (id));
13765 id.src_fn = current_function_decl;
13766 id.dst_fn = current_function_decl;
13767 id.src_cfun = cfun;
13768 id.decl_map = &decl_map;
13769 id.copy_decl = copy_decl_no_change;
13770 id.transform_call_graph_edges = CB_CGE_DUPLICATE;
13771 id.transform_new_cfg = true;
13772 id.transform_return_to_modify = false;
13773 id.eh_lp_nr = 0;
13774 walk_tree (&OMP_CLAUSE_REDUCTION_INIT (*pc), copy_tree_body_r,
13775 &id, NULL);
13776 walk_tree (&OMP_CLAUSE_REDUCTION_MERGE (*pc), copy_tree_body_r,
13777 &id, NULL);
13779 for (tree d : no_context_vars)
13781 DECL_CONTEXT (d) = NULL_TREE;
13782 DECL_CONTEXT (*decl_map.get (d)) = NULL_TREE;
13785 else
13787 OMP_CLAUSE_REDUCTION_INIT (*pc)
13788 = unshare_expr (OMP_CLAUSE_REDUCTION_INIT (c));
13789 OMP_CLAUSE_REDUCTION_MERGE (*pc)
13790 = unshare_expr (OMP_CLAUSE_REDUCTION_MERGE (c));
13792 pc = &OMP_CLAUSE_CHAIN (*pc);
13793 break;
13794 default:
13795 gcc_unreachable ();
13797 *pc = NULL_TREE;
13798 *expr_p = t;
13800 return gimplify_expr (expr_p, pre_p, NULL, is_gimple_stmt, fb_none);
13804 /* Helper function of optimize_target_teams, find OMP_TEAMS inside
13805 of OMP_TARGET's body. */
13807 static tree
13808 find_omp_teams (tree *tp, int *walk_subtrees, void *)
13810 *walk_subtrees = 0;
13811 switch (TREE_CODE (*tp))
13813 case OMP_TEAMS:
13814 return *tp;
13815 case BIND_EXPR:
13816 case STATEMENT_LIST:
13817 *walk_subtrees = 1;
13818 break;
13819 default:
13820 break;
13822 return NULL_TREE;
13825 /* Helper function of optimize_target_teams, determine if the expression
13826 can be computed safely before the target construct on the host. */
13828 static tree
13829 computable_teams_clause (tree *tp, int *walk_subtrees, void *)
13831 splay_tree_node n;
13833 if (TYPE_P (*tp))
13835 *walk_subtrees = 0;
13836 return NULL_TREE;
13838 switch (TREE_CODE (*tp))
13840 case VAR_DECL:
13841 case PARM_DECL:
13842 case RESULT_DECL:
13843 *walk_subtrees = 0;
13844 if (error_operand_p (*tp)
13845 || !INTEGRAL_TYPE_P (TREE_TYPE (*tp))
13846 || DECL_HAS_VALUE_EXPR_P (*tp)
13847 || DECL_THREAD_LOCAL_P (*tp)
13848 || TREE_SIDE_EFFECTS (*tp)
13849 || TREE_THIS_VOLATILE (*tp))
13850 return *tp;
13851 if (is_global_var (*tp)
13852 && (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (*tp))
13853 || lookup_attribute ("omp declare target link",
13854 DECL_ATTRIBUTES (*tp))))
13855 return *tp;
13856 if (VAR_P (*tp)
13857 && !DECL_SEEN_IN_BIND_EXPR_P (*tp)
13858 && !is_global_var (*tp)
13859 && decl_function_context (*tp) == current_function_decl)
13860 return *tp;
13861 n = splay_tree_lookup (gimplify_omp_ctxp->variables,
13862 (splay_tree_key) *tp);
13863 if (n == NULL)
13865 if (gimplify_omp_ctxp->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE)
13866 return NULL_TREE;
13867 return *tp;
13869 else if (n->value & GOVD_LOCAL)
13870 return *tp;
13871 else if (n->value & GOVD_FIRSTPRIVATE)
13872 return NULL_TREE;
13873 else if ((n->value & (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
13874 == (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
13875 return NULL_TREE;
13876 return *tp;
13877 case INTEGER_CST:
13878 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
13879 return *tp;
13880 return NULL_TREE;
13881 case TARGET_EXPR:
13882 if (TARGET_EXPR_INITIAL (*tp)
13883 || TREE_CODE (TARGET_EXPR_SLOT (*tp)) != VAR_DECL)
13884 return *tp;
13885 return computable_teams_clause (&TARGET_EXPR_SLOT (*tp),
13886 walk_subtrees, NULL);
13887 /* Allow some reasonable subset of integral arithmetics. */
13888 case PLUS_EXPR:
13889 case MINUS_EXPR:
13890 case MULT_EXPR:
13891 case TRUNC_DIV_EXPR:
13892 case CEIL_DIV_EXPR:
13893 case FLOOR_DIV_EXPR:
13894 case ROUND_DIV_EXPR:
13895 case TRUNC_MOD_EXPR:
13896 case CEIL_MOD_EXPR:
13897 case FLOOR_MOD_EXPR:
13898 case ROUND_MOD_EXPR:
13899 case RDIV_EXPR:
13900 case EXACT_DIV_EXPR:
13901 case MIN_EXPR:
13902 case MAX_EXPR:
13903 case LSHIFT_EXPR:
13904 case RSHIFT_EXPR:
13905 case BIT_IOR_EXPR:
13906 case BIT_XOR_EXPR:
13907 case BIT_AND_EXPR:
13908 case NEGATE_EXPR:
13909 case ABS_EXPR:
13910 case BIT_NOT_EXPR:
13911 case NON_LVALUE_EXPR:
13912 CASE_CONVERT:
13913 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
13914 return *tp;
13915 return NULL_TREE;
13916 /* And disallow anything else, except for comparisons. */
13917 default:
13918 if (COMPARISON_CLASS_P (*tp))
13919 return NULL_TREE;
13920 return *tp;
13924 /* Try to determine if the num_teams and/or thread_limit expressions
13925 can have their values determined already before entering the
13926 target construct.
13927 INTEGER_CSTs trivially are,
13928 integral decls that are firstprivate (explicitly or implicitly)
13929 or explicitly map(always, to:) or map(always, tofrom:) on the target
13930 region too, and expressions involving simple arithmetics on those
13931 too, function calls are not ok, dereferencing something neither etc.
13932 Add NUM_TEAMS and THREAD_LIMIT clauses to the OMP_CLAUSES of
13933 EXPR based on what we find:
13934 0 stands for clause not specified at all, use implementation default
13935 -1 stands for value that can't be determined easily before entering
13936 the target construct.
13937 If teams construct is not present at all, use 1 for num_teams
13938 and 0 for thread_limit (only one team is involved, and the thread
13939 limit is implementation defined. */
13941 static void
13942 optimize_target_teams (tree target, gimple_seq *pre_p)
13944 tree body = OMP_BODY (target);
13945 tree teams = walk_tree (&body, find_omp_teams, NULL, NULL);
13946 tree num_teams_lower = NULL_TREE;
13947 tree num_teams_upper = integer_zero_node;
13948 tree thread_limit = integer_zero_node;
13949 location_t num_teams_loc = EXPR_LOCATION (target);
13950 location_t thread_limit_loc = EXPR_LOCATION (target);
13951 tree c, *p, expr;
13952 struct gimplify_omp_ctx *target_ctx = gimplify_omp_ctxp;
13954 if (teams == NULL_TREE)
13955 num_teams_upper = integer_one_node;
13956 else
13957 for (c = OMP_TEAMS_CLAUSES (teams); c; c = OMP_CLAUSE_CHAIN (c))
13959 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS)
13961 p = &num_teams_upper;
13962 num_teams_loc = OMP_CLAUSE_LOCATION (c);
13963 if (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c))
13965 expr = OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c);
13966 if (TREE_CODE (expr) == INTEGER_CST)
13967 num_teams_lower = expr;
13968 else if (walk_tree (&expr, computable_teams_clause,
13969 NULL, NULL))
13970 num_teams_lower = integer_minus_one_node;
13971 else
13973 num_teams_lower = expr;
13974 gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
13975 if (gimplify_expr (&num_teams_lower, pre_p, NULL,
13976 is_gimple_val, fb_rvalue, false)
13977 == GS_ERROR)
13979 gimplify_omp_ctxp = target_ctx;
13980 num_teams_lower = integer_minus_one_node;
13982 else
13984 gimplify_omp_ctxp = target_ctx;
13985 if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR)
13986 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
13987 = num_teams_lower;
13992 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
13994 p = &thread_limit;
13995 thread_limit_loc = OMP_CLAUSE_LOCATION (c);
13997 else
13998 continue;
13999 expr = OMP_CLAUSE_OPERAND (c, 0);
14000 if (TREE_CODE (expr) == INTEGER_CST)
14002 *p = expr;
14003 continue;
14005 if (walk_tree (&expr, computable_teams_clause, NULL, NULL))
14007 *p = integer_minus_one_node;
14008 continue;
14010 *p = expr;
14011 gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
14012 if (gimplify_expr (p, pre_p, NULL, is_gimple_val, fb_rvalue, false)
14013 == GS_ERROR)
14015 gimplify_omp_ctxp = target_ctx;
14016 *p = integer_minus_one_node;
14017 continue;
14019 gimplify_omp_ctxp = target_ctx;
14020 if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR)
14021 OMP_CLAUSE_OPERAND (c, 0) = *p;
14023 if (!omp_find_clause (OMP_TARGET_CLAUSES (target), OMP_CLAUSE_THREAD_LIMIT))
14025 c = build_omp_clause (thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
14026 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = thread_limit;
14027 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
14028 OMP_TARGET_CLAUSES (target) = c;
14030 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
14031 OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c) = num_teams_upper;
14032 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) = num_teams_lower;
14033 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
14034 OMP_TARGET_CLAUSES (target) = c;
14037 /* Gimplify the gross structure of several OMP constructs. */
14039 static void
14040 gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
14042 tree expr = *expr_p;
14043 gimple *stmt;
14044 gimple_seq body = NULL;
14045 enum omp_region_type ort;
14047 switch (TREE_CODE (expr))
14049 case OMP_SECTIONS:
14050 case OMP_SINGLE:
14051 ort = ORT_WORKSHARE;
14052 break;
14053 case OMP_SCOPE:
14054 ort = ORT_TASKGROUP;
14055 break;
14056 case OMP_TARGET:
14057 ort = OMP_TARGET_COMBINED (expr) ? ORT_COMBINED_TARGET : ORT_TARGET;
14058 break;
14059 case OACC_KERNELS:
14060 ort = ORT_ACC_KERNELS;
14061 break;
14062 case OACC_PARALLEL:
14063 ort = ORT_ACC_PARALLEL;
14064 break;
14065 case OACC_SERIAL:
14066 ort = ORT_ACC_SERIAL;
14067 break;
14068 case OACC_DATA:
14069 ort = ORT_ACC_DATA;
14070 break;
14071 case OMP_TARGET_DATA:
14072 ort = ORT_TARGET_DATA;
14073 break;
14074 case OMP_TEAMS:
14075 ort = OMP_TEAMS_COMBINED (expr) ? ORT_COMBINED_TEAMS : ORT_TEAMS;
14076 if (gimplify_omp_ctxp == NULL
14077 || gimplify_omp_ctxp->region_type == ORT_IMPLICIT_TARGET)
14078 ort = (enum omp_region_type) (ort | ORT_HOST_TEAMS);
14079 break;
14080 case OACC_HOST_DATA:
14081 ort = ORT_ACC_HOST_DATA;
14082 break;
14083 default:
14084 gcc_unreachable ();
14087 bool save_in_omp_construct = in_omp_construct;
14088 if ((ort & ORT_ACC) == 0)
14089 in_omp_construct = false;
14090 gimplify_scan_omp_clauses (&OMP_CLAUSES (expr), pre_p, ort,
14091 TREE_CODE (expr));
14092 if (TREE_CODE (expr) == OMP_TARGET)
14093 optimize_target_teams (expr, pre_p);
14094 if ((ort & (ORT_TARGET | ORT_TARGET_DATA)) != 0
14095 || (ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
14097 push_gimplify_context ();
14098 gimple *g = gimplify_and_return_first (OMP_BODY (expr), &body);
14099 if (gimple_code (g) == GIMPLE_BIND)
14100 pop_gimplify_context (g);
14101 else
14102 pop_gimplify_context (NULL);
14103 if ((ort & ORT_TARGET_DATA) != 0)
14105 enum built_in_function end_ix;
14106 switch (TREE_CODE (expr))
14108 case OACC_DATA:
14109 case OACC_HOST_DATA:
14110 end_ix = BUILT_IN_GOACC_DATA_END;
14111 break;
14112 case OMP_TARGET_DATA:
14113 end_ix = BUILT_IN_GOMP_TARGET_END_DATA;
14114 break;
14115 default:
14116 gcc_unreachable ();
14118 tree fn = builtin_decl_explicit (end_ix);
14119 g = gimple_build_call (fn, 0);
14120 gimple_seq cleanup = NULL;
14121 gimple_seq_add_stmt (&cleanup, g);
14122 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
14123 body = NULL;
14124 gimple_seq_add_stmt (&body, g);
14127 else
14128 gimplify_and_add (OMP_BODY (expr), &body);
14129 gimplify_adjust_omp_clauses (pre_p, body, &OMP_CLAUSES (expr),
14130 TREE_CODE (expr));
14131 in_omp_construct = save_in_omp_construct;
14133 switch (TREE_CODE (expr))
14135 case OACC_DATA:
14136 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_DATA,
14137 OMP_CLAUSES (expr));
14138 break;
14139 case OACC_HOST_DATA:
14140 if (omp_find_clause (OMP_CLAUSES (expr), OMP_CLAUSE_IF_PRESENT))
14142 for (tree c = OMP_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
14143 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_PTR)
14144 OMP_CLAUSE_USE_DEVICE_PTR_IF_PRESENT (c) = 1;
14147 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_HOST_DATA,
14148 OMP_CLAUSES (expr));
14149 break;
14150 case OACC_KERNELS:
14151 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_KERNELS,
14152 OMP_CLAUSES (expr));
14153 break;
14154 case OACC_PARALLEL:
14155 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_PARALLEL,
14156 OMP_CLAUSES (expr));
14157 break;
14158 case OACC_SERIAL:
14159 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_SERIAL,
14160 OMP_CLAUSES (expr));
14161 break;
14162 case OMP_SECTIONS:
14163 stmt = gimple_build_omp_sections (body, OMP_CLAUSES (expr));
14164 break;
14165 case OMP_SINGLE:
14166 stmt = gimple_build_omp_single (body, OMP_CLAUSES (expr));
14167 break;
14168 case OMP_SCOPE:
14169 stmt = gimple_build_omp_scope (body, OMP_CLAUSES (expr));
14170 break;
14171 case OMP_TARGET:
14172 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_REGION,
14173 OMP_CLAUSES (expr));
14174 break;
14175 case OMP_TARGET_DATA:
14176 /* Put use_device_{ptr,addr} clauses last, as map clauses are supposed
14177 to be evaluated before the use_device_{ptr,addr} clauses if they
14178 refer to the same variables. */
14180 tree use_device_clauses;
14181 tree *pc, *uc = &use_device_clauses;
14182 for (pc = &OMP_CLAUSES (expr); *pc; )
14183 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
14184 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
14186 *uc = *pc;
14187 *pc = OMP_CLAUSE_CHAIN (*pc);
14188 uc = &OMP_CLAUSE_CHAIN (*uc);
14190 else
14191 pc = &OMP_CLAUSE_CHAIN (*pc);
14192 *uc = NULL_TREE;
14193 *pc = use_device_clauses;
14194 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_DATA,
14195 OMP_CLAUSES (expr));
14197 break;
14198 case OMP_TEAMS:
14199 stmt = gimple_build_omp_teams (body, OMP_CLAUSES (expr));
14200 if ((ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
14201 gimple_omp_teams_set_host (as_a <gomp_teams *> (stmt), true);
14202 break;
14203 default:
14204 gcc_unreachable ();
14207 gimplify_seq_add_stmt (pre_p, stmt);
14208 *expr_p = NULL_TREE;
14211 /* Gimplify the gross structure of OpenACC enter/exit data, update, and OpenMP
14212 target update constructs. */
14214 static void
14215 gimplify_omp_target_update (tree *expr_p, gimple_seq *pre_p)
14217 tree expr = *expr_p;
14218 int kind;
14219 gomp_target *stmt;
14220 enum omp_region_type ort = ORT_WORKSHARE;
14222 switch (TREE_CODE (expr))
14224 case OACC_ENTER_DATA:
14225 kind = GF_OMP_TARGET_KIND_OACC_ENTER_DATA;
14226 ort = ORT_ACC;
14227 break;
14228 case OACC_EXIT_DATA:
14229 kind = GF_OMP_TARGET_KIND_OACC_EXIT_DATA;
14230 ort = ORT_ACC;
14231 break;
14232 case OACC_UPDATE:
14233 kind = GF_OMP_TARGET_KIND_OACC_UPDATE;
14234 ort = ORT_ACC;
14235 break;
14236 case OMP_TARGET_UPDATE:
14237 kind = GF_OMP_TARGET_KIND_UPDATE;
14238 break;
14239 case OMP_TARGET_ENTER_DATA:
14240 kind = GF_OMP_TARGET_KIND_ENTER_DATA;
14241 break;
14242 case OMP_TARGET_EXIT_DATA:
14243 kind = GF_OMP_TARGET_KIND_EXIT_DATA;
14244 break;
14245 default:
14246 gcc_unreachable ();
14248 gimplify_scan_omp_clauses (&OMP_STANDALONE_CLAUSES (expr), pre_p,
14249 ort, TREE_CODE (expr));
14250 gimplify_adjust_omp_clauses (pre_p, NULL, &OMP_STANDALONE_CLAUSES (expr),
14251 TREE_CODE (expr));
14252 if (TREE_CODE (expr) == OACC_UPDATE
14253 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
14254 OMP_CLAUSE_IF_PRESENT))
14256 /* The runtime uses GOMP_MAP_{TO,FROM} to denote the if_present
14257 clause. */
14258 for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
14259 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
14260 switch (OMP_CLAUSE_MAP_KIND (c))
14262 case GOMP_MAP_FORCE_TO:
14263 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TO);
14264 break;
14265 case GOMP_MAP_FORCE_FROM:
14266 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FROM);
14267 break;
14268 default:
14269 break;
14272 else if (TREE_CODE (expr) == OACC_EXIT_DATA
14273 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
14274 OMP_CLAUSE_FINALIZE))
14276 /* Use GOMP_MAP_DELETE/GOMP_MAP_FORCE_FROM to denote "finalize"
14277 semantics. */
14278 bool have_clause = false;
14279 for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
14280 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
14281 switch (OMP_CLAUSE_MAP_KIND (c))
14283 case GOMP_MAP_FROM:
14284 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_FROM);
14285 have_clause = true;
14286 break;
14287 case GOMP_MAP_RELEASE:
14288 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_DELETE);
14289 have_clause = true;
14290 break;
14291 case GOMP_MAP_TO_PSET:
14292 /* Fortran arrays with descriptors must map that descriptor when
14293 doing standalone "attach" operations (in OpenACC). In that
14294 case GOMP_MAP_TO_PSET appears by itself with no preceding
14295 clause (see trans-openmp.cc:gfc_trans_omp_clauses). */
14296 break;
14297 case GOMP_MAP_POINTER:
14298 /* TODO PR92929: we may see these here, but they'll always follow
14299 one of the clauses above, and will be handled by libgomp as
14300 one group, so no handling required here. */
14301 gcc_assert (have_clause);
14302 break;
14303 case GOMP_MAP_DETACH:
14304 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_DETACH);
14305 have_clause = false;
14306 break;
14307 case GOMP_MAP_STRUCT:
14308 have_clause = false;
14309 break;
14310 default:
14311 gcc_unreachable ();
14314 stmt = gimple_build_omp_target (NULL, kind, OMP_STANDALONE_CLAUSES (expr));
14316 gimplify_seq_add_stmt (pre_p, stmt);
14317 *expr_p = NULL_TREE;
14320 /* A subroutine of gimplify_omp_atomic. The front end is supposed to have
14321 stabilized the lhs of the atomic operation as *ADDR. Return true if
14322 EXPR is this stabilized form. */
14324 static bool
14325 goa_lhs_expr_p (tree expr, tree addr)
14327 /* Also include casts to other type variants. The C front end is fond
14328 of adding these for e.g. volatile variables. This is like
14329 STRIP_TYPE_NOPS but includes the main variant lookup. */
14330 STRIP_USELESS_TYPE_CONVERSION (expr);
14332 if (TREE_CODE (expr) == INDIRECT_REF)
14334 expr = TREE_OPERAND (expr, 0);
14335 while (expr != addr
14336 && (CONVERT_EXPR_P (expr)
14337 || TREE_CODE (expr) == NON_LVALUE_EXPR)
14338 && TREE_CODE (expr) == TREE_CODE (addr)
14339 && types_compatible_p (TREE_TYPE (expr), TREE_TYPE (addr)))
14341 expr = TREE_OPERAND (expr, 0);
14342 addr = TREE_OPERAND (addr, 0);
14344 if (expr == addr)
14345 return true;
14346 return (TREE_CODE (addr) == ADDR_EXPR
14347 && TREE_CODE (expr) == ADDR_EXPR
14348 && TREE_OPERAND (addr, 0) == TREE_OPERAND (expr, 0));
14350 if (TREE_CODE (addr) == ADDR_EXPR && expr == TREE_OPERAND (addr, 0))
14351 return true;
14352 return false;
14355 /* Walk *EXPR_P and replace appearances of *LHS_ADDR with LHS_VAR. If an
14356 expression does not involve the lhs, evaluate it into a temporary.
14357 Return 1 if the lhs appeared as a subexpression, 0 if it did not,
14358 or -1 if an error was encountered. */
14360 static int
14361 goa_stabilize_expr (tree *expr_p, gimple_seq *pre_p, tree lhs_addr,
14362 tree lhs_var, tree &target_expr, bool rhs, int depth)
14364 tree expr = *expr_p;
14365 int saw_lhs = 0;
14367 if (goa_lhs_expr_p (expr, lhs_addr))
14369 if (pre_p)
14370 *expr_p = lhs_var;
14371 return 1;
14373 if (is_gimple_val (expr))
14374 return 0;
14376 /* Maximum depth of lhs in expression is for the
14377 __builtin_clear_padding (...), __builtin_clear_padding (...),
14378 __builtin_memcmp (&TARGET_EXPR <lhs, >, ...) == 0 ? ... : lhs; */
14379 if (++depth > 7)
14380 goto finish;
14382 switch (TREE_CODE_CLASS (TREE_CODE (expr)))
14384 case tcc_binary:
14385 case tcc_comparison:
14386 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p, lhs_addr,
14387 lhs_var, target_expr, true, depth);
14388 /* FALLTHRU */
14389 case tcc_unary:
14390 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p, lhs_addr,
14391 lhs_var, target_expr, true, depth);
14392 break;
14393 case tcc_expression:
14394 switch (TREE_CODE (expr))
14396 case TRUTH_ANDIF_EXPR:
14397 case TRUTH_ORIF_EXPR:
14398 case TRUTH_AND_EXPR:
14399 case TRUTH_OR_EXPR:
14400 case TRUTH_XOR_EXPR:
14401 case BIT_INSERT_EXPR:
14402 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
14403 lhs_addr, lhs_var, target_expr, true,
14404 depth);
14405 /* FALLTHRU */
14406 case TRUTH_NOT_EXPR:
14407 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
14408 lhs_addr, lhs_var, target_expr, true,
14409 depth);
14410 break;
14411 case MODIFY_EXPR:
14412 if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr, lhs_var,
14413 target_expr, true, depth))
14414 break;
14415 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
14416 lhs_addr, lhs_var, target_expr, true,
14417 depth);
14418 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
14419 lhs_addr, lhs_var, target_expr, false,
14420 depth);
14421 break;
14422 /* FALLTHRU */
14423 case ADDR_EXPR:
14424 if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr, lhs_var,
14425 target_expr, true, depth))
14426 break;
14427 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
14428 lhs_addr, lhs_var, target_expr, false,
14429 depth);
14430 break;
14431 case COMPOUND_EXPR:
14432 /* Break out any preevaluations from cp_build_modify_expr. */
14433 for (; TREE_CODE (expr) == COMPOUND_EXPR;
14434 expr = TREE_OPERAND (expr, 1))
14436 /* Special-case __builtin_clear_padding call before
14437 __builtin_memcmp. */
14438 if (TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR)
14440 tree fndecl = get_callee_fndecl (TREE_OPERAND (expr, 0));
14441 if (fndecl
14442 && fndecl_built_in_p (fndecl, BUILT_IN_CLEAR_PADDING)
14443 && VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 0)))
14444 && (!pre_p
14445 || goa_stabilize_expr (&TREE_OPERAND (expr, 0), NULL,
14446 lhs_addr, lhs_var,
14447 target_expr, true, depth)))
14449 if (pre_p)
14450 *expr_p = expr;
14451 saw_lhs = goa_stabilize_expr (&TREE_OPERAND (expr, 0),
14452 pre_p, lhs_addr, lhs_var,
14453 target_expr, true, depth);
14454 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1),
14455 pre_p, lhs_addr, lhs_var,
14456 target_expr, rhs, depth);
14457 return saw_lhs;
14461 if (pre_p)
14462 gimplify_stmt (&TREE_OPERAND (expr, 0), pre_p);
14464 if (!pre_p)
14465 return goa_stabilize_expr (&expr, pre_p, lhs_addr, lhs_var,
14466 target_expr, rhs, depth);
14467 *expr_p = expr;
14468 return goa_stabilize_expr (expr_p, pre_p, lhs_addr, lhs_var,
14469 target_expr, rhs, depth);
14470 case COND_EXPR:
14471 if (!goa_stabilize_expr (&TREE_OPERAND (expr, 0), NULL, lhs_addr,
14472 lhs_var, target_expr, true, depth))
14473 break;
14474 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
14475 lhs_addr, lhs_var, target_expr, true,
14476 depth);
14477 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
14478 lhs_addr, lhs_var, target_expr, true,
14479 depth);
14480 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 2), pre_p,
14481 lhs_addr, lhs_var, target_expr, true,
14482 depth);
14483 break;
14484 case TARGET_EXPR:
14485 if (TARGET_EXPR_INITIAL (expr))
14487 if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr,
14488 lhs_var, target_expr, true,
14489 depth))
14490 break;
14491 if (expr == target_expr)
14492 saw_lhs = 1;
14493 else
14495 saw_lhs = goa_stabilize_expr (&TARGET_EXPR_INITIAL (expr),
14496 pre_p, lhs_addr, lhs_var,
14497 target_expr, true, depth);
14498 if (saw_lhs && target_expr == NULL_TREE && pre_p)
14499 target_expr = expr;
14502 break;
14503 default:
14504 break;
14506 break;
14507 case tcc_reference:
14508 if (TREE_CODE (expr) == BIT_FIELD_REF
14509 || TREE_CODE (expr) == VIEW_CONVERT_EXPR)
14510 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
14511 lhs_addr, lhs_var, target_expr, true,
14512 depth);
14513 break;
14514 case tcc_vl_exp:
14515 if (TREE_CODE (expr) == CALL_EXPR)
14517 if (tree fndecl = get_callee_fndecl (expr))
14518 if (fndecl_built_in_p (fndecl, BUILT_IN_CLEAR_PADDING)
14519 || fndecl_built_in_p (fndecl, BUILT_IN_MEMCMP))
14521 int nargs = call_expr_nargs (expr);
14522 for (int i = 0; i < nargs; i++)
14523 saw_lhs |= goa_stabilize_expr (&CALL_EXPR_ARG (expr, i),
14524 pre_p, lhs_addr, lhs_var,
14525 target_expr, true, depth);
14528 break;
14529 default:
14530 break;
14533 finish:
14534 if (saw_lhs == 0 && pre_p)
14536 enum gimplify_status gs;
14537 if (TREE_CODE (expr) == CALL_EXPR && VOID_TYPE_P (TREE_TYPE (expr)))
14539 gimplify_stmt (&expr, pre_p);
14540 return saw_lhs;
14542 else if (rhs)
14543 gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_val, fb_rvalue);
14544 else
14545 gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_lvalue, fb_lvalue);
14546 if (gs != GS_ALL_DONE)
14547 saw_lhs = -1;
14550 return saw_lhs;
14553 /* Gimplify an OMP_ATOMIC statement. */
14555 static enum gimplify_status
14556 gimplify_omp_atomic (tree *expr_p, gimple_seq *pre_p)
14558 tree addr = TREE_OPERAND (*expr_p, 0);
14559 tree rhs = TREE_CODE (*expr_p) == OMP_ATOMIC_READ
14560 ? NULL : TREE_OPERAND (*expr_p, 1);
14561 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
14562 tree tmp_load;
14563 gomp_atomic_load *loadstmt;
14564 gomp_atomic_store *storestmt;
14565 tree target_expr = NULL_TREE;
14567 tmp_load = create_tmp_reg (type);
14568 if (rhs
14569 && goa_stabilize_expr (&rhs, pre_p, addr, tmp_load, target_expr,
14570 true, 0) < 0)
14571 return GS_ERROR;
14573 if (gimplify_expr (&addr, pre_p, NULL, is_gimple_val, fb_rvalue)
14574 != GS_ALL_DONE)
14575 return GS_ERROR;
14577 loadstmt = gimple_build_omp_atomic_load (tmp_load, addr,
14578 OMP_ATOMIC_MEMORY_ORDER (*expr_p));
14579 gimplify_seq_add_stmt (pre_p, loadstmt);
14580 if (rhs)
14582 /* BIT_INSERT_EXPR is not valid for non-integral bitfield
14583 representatives. Use BIT_FIELD_REF on the lhs instead. */
14584 tree rhsarg = rhs;
14585 if (TREE_CODE (rhs) == COND_EXPR)
14586 rhsarg = TREE_OPERAND (rhs, 1);
14587 if (TREE_CODE (rhsarg) == BIT_INSERT_EXPR
14588 && !INTEGRAL_TYPE_P (TREE_TYPE (tmp_load)))
14590 tree bitpos = TREE_OPERAND (rhsarg, 2);
14591 tree op1 = TREE_OPERAND (rhsarg, 1);
14592 tree bitsize;
14593 tree tmp_store = tmp_load;
14594 if (TREE_CODE (*expr_p) == OMP_ATOMIC_CAPTURE_OLD)
14595 tmp_store = get_initialized_tmp_var (tmp_load, pre_p);
14596 if (INTEGRAL_TYPE_P (TREE_TYPE (op1)))
14597 bitsize = bitsize_int (TYPE_PRECISION (TREE_TYPE (op1)));
14598 else
14599 bitsize = TYPE_SIZE (TREE_TYPE (op1));
14600 gcc_assert (TREE_OPERAND (rhsarg, 0) == tmp_load);
14601 tree t = build2_loc (EXPR_LOCATION (rhsarg),
14602 MODIFY_EXPR, void_type_node,
14603 build3_loc (EXPR_LOCATION (rhsarg),
14604 BIT_FIELD_REF, TREE_TYPE (op1),
14605 tmp_store, bitsize, bitpos), op1);
14606 if (TREE_CODE (rhs) == COND_EXPR)
14607 t = build3_loc (EXPR_LOCATION (rhs), COND_EXPR, void_type_node,
14608 TREE_OPERAND (rhs, 0), t, void_node);
14609 gimplify_and_add (t, pre_p);
14610 rhs = tmp_store;
14612 bool save_allow_rhs_cond_expr = gimplify_ctxp->allow_rhs_cond_expr;
14613 if (TREE_CODE (rhs) == COND_EXPR)
14614 gimplify_ctxp->allow_rhs_cond_expr = true;
14615 enum gimplify_status gs = gimplify_expr (&rhs, pre_p, NULL,
14616 is_gimple_val, fb_rvalue);
14617 gimplify_ctxp->allow_rhs_cond_expr = save_allow_rhs_cond_expr;
14618 if (gs != GS_ALL_DONE)
14619 return GS_ERROR;
14622 if (TREE_CODE (*expr_p) == OMP_ATOMIC_READ)
14623 rhs = tmp_load;
14624 storestmt
14625 = gimple_build_omp_atomic_store (rhs, OMP_ATOMIC_MEMORY_ORDER (*expr_p));
14626 if (TREE_CODE (*expr_p) != OMP_ATOMIC_READ && OMP_ATOMIC_WEAK (*expr_p))
14628 gimple_omp_atomic_set_weak (loadstmt);
14629 gimple_omp_atomic_set_weak (storestmt);
14631 gimplify_seq_add_stmt (pre_p, storestmt);
14632 switch (TREE_CODE (*expr_p))
14634 case OMP_ATOMIC_READ:
14635 case OMP_ATOMIC_CAPTURE_OLD:
14636 *expr_p = tmp_load;
14637 gimple_omp_atomic_set_need_value (loadstmt);
14638 break;
14639 case OMP_ATOMIC_CAPTURE_NEW:
14640 *expr_p = rhs;
14641 gimple_omp_atomic_set_need_value (storestmt);
14642 break;
14643 default:
14644 *expr_p = NULL;
14645 break;
14648 return GS_ALL_DONE;
14651 /* Gimplify a TRANSACTION_EXPR. This involves gimplification of the
14652 body, and adding some EH bits. */
14654 static enum gimplify_status
14655 gimplify_transaction (tree *expr_p, gimple_seq *pre_p)
14657 tree expr = *expr_p, temp, tbody = TRANSACTION_EXPR_BODY (expr);
14658 gimple *body_stmt;
14659 gtransaction *trans_stmt;
14660 gimple_seq body = NULL;
14661 int subcode = 0;
14663 /* Wrap the transaction body in a BIND_EXPR so we have a context
14664 where to put decls for OMP. */
14665 if (TREE_CODE (tbody) != BIND_EXPR)
14667 tree bind = build3 (BIND_EXPR, void_type_node, NULL, tbody, NULL);
14668 TREE_SIDE_EFFECTS (bind) = 1;
14669 SET_EXPR_LOCATION (bind, EXPR_LOCATION (tbody));
14670 TRANSACTION_EXPR_BODY (expr) = bind;
14673 push_gimplify_context ();
14674 temp = voidify_wrapper_expr (*expr_p, NULL);
14676 body_stmt = gimplify_and_return_first (TRANSACTION_EXPR_BODY (expr), &body);
14677 pop_gimplify_context (body_stmt);
14679 trans_stmt = gimple_build_transaction (body);
14680 if (TRANSACTION_EXPR_OUTER (expr))
14681 subcode = GTMA_IS_OUTER;
14682 else if (TRANSACTION_EXPR_RELAXED (expr))
14683 subcode = GTMA_IS_RELAXED;
14684 gimple_transaction_set_subcode (trans_stmt, subcode);
14686 gimplify_seq_add_stmt (pre_p, trans_stmt);
14688 if (temp)
14690 *expr_p = temp;
14691 return GS_OK;
14694 *expr_p = NULL_TREE;
14695 return GS_ALL_DONE;
14698 /* Gimplify an OMP_ORDERED construct. EXPR is the tree version. BODY
14699 is the OMP_BODY of the original EXPR (which has already been
14700 gimplified so it's not present in the EXPR).
14702 Return the gimplified GIMPLE_OMP_ORDERED tuple. */
14704 static gimple *
14705 gimplify_omp_ordered (tree expr, gimple_seq body)
14707 tree c, decls;
14708 int failures = 0;
14709 unsigned int i;
14710 tree source_c = NULL_TREE;
14711 tree sink_c = NULL_TREE;
14713 if (gimplify_omp_ctxp)
14715 for (c = OMP_ORDERED_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
14716 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
14717 && gimplify_omp_ctxp->loop_iter_var.is_empty ()
14718 && (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK
14719 || OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE))
14721 error_at (OMP_CLAUSE_LOCATION (c),
14722 "%<ordered%> construct with %<depend%> clause must be "
14723 "closely nested inside a loop with %<ordered%> clause "
14724 "with a parameter");
14725 failures++;
14727 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
14728 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
14730 bool fail = false;
14731 for (decls = OMP_CLAUSE_DECL (c), i = 0;
14732 decls && TREE_CODE (decls) == TREE_LIST;
14733 decls = TREE_CHAIN (decls), ++i)
14734 if (i >= gimplify_omp_ctxp->loop_iter_var.length () / 2)
14735 continue;
14736 else if (TREE_VALUE (decls)
14737 != gimplify_omp_ctxp->loop_iter_var[2 * i])
14739 error_at (OMP_CLAUSE_LOCATION (c),
14740 "variable %qE is not an iteration "
14741 "of outermost loop %d, expected %qE",
14742 TREE_VALUE (decls), i + 1,
14743 gimplify_omp_ctxp->loop_iter_var[2 * i]);
14744 fail = true;
14745 failures++;
14747 else
14748 TREE_VALUE (decls)
14749 = gimplify_omp_ctxp->loop_iter_var[2 * i + 1];
14750 if (!fail && i != gimplify_omp_ctxp->loop_iter_var.length () / 2)
14752 error_at (OMP_CLAUSE_LOCATION (c),
14753 "number of variables in %<depend%> clause with "
14754 "%<sink%> modifier does not match number of "
14755 "iteration variables");
14756 failures++;
14758 sink_c = c;
14760 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
14761 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
14763 if (source_c)
14765 error_at (OMP_CLAUSE_LOCATION (c),
14766 "more than one %<depend%> clause with %<source%> "
14767 "modifier on an %<ordered%> construct");
14768 failures++;
14770 else
14771 source_c = c;
14774 if (source_c && sink_c)
14776 error_at (OMP_CLAUSE_LOCATION (source_c),
14777 "%<depend%> clause with %<source%> modifier specified "
14778 "together with %<depend%> clauses with %<sink%> modifier "
14779 "on the same construct");
14780 failures++;
14783 if (failures)
14784 return gimple_build_nop ();
14785 return gimple_build_omp_ordered (body, OMP_ORDERED_CLAUSES (expr));
14788 /* Convert the GENERIC expression tree *EXPR_P to GIMPLE. If the
14789 expression produces a value to be used as an operand inside a GIMPLE
14790 statement, the value will be stored back in *EXPR_P. This value will
14791 be a tree of class tcc_declaration, tcc_constant, tcc_reference or
14792 an SSA_NAME. The corresponding sequence of GIMPLE statements is
14793 emitted in PRE_P and POST_P.
14795 Additionally, this process may overwrite parts of the input
14796 expression during gimplification. Ideally, it should be
14797 possible to do non-destructive gimplification.
14799 EXPR_P points to the GENERIC expression to convert to GIMPLE. If
14800 the expression needs to evaluate to a value to be used as
14801 an operand in a GIMPLE statement, this value will be stored in
14802 *EXPR_P on exit. This happens when the caller specifies one
14803 of fb_lvalue or fb_rvalue fallback flags.
14805 PRE_P will contain the sequence of GIMPLE statements corresponding
14806 to the evaluation of EXPR and all the side-effects that must
14807 be executed before the main expression. On exit, the last
14808 statement of PRE_P is the core statement being gimplified. For
14809 instance, when gimplifying 'if (++a)' the last statement in
14810 PRE_P will be 'if (t.1)' where t.1 is the result of
14811 pre-incrementing 'a'.
14813 POST_P will contain the sequence of GIMPLE statements corresponding
14814 to the evaluation of all the side-effects that must be executed
14815 after the main expression. If this is NULL, the post
14816 side-effects are stored at the end of PRE_P.
14818 The reason why the output is split in two is to handle post
14819 side-effects explicitly. In some cases, an expression may have
14820 inner and outer post side-effects which need to be emitted in
14821 an order different from the one given by the recursive
14822 traversal. For instance, for the expression (*p--)++ the post
14823 side-effects of '--' must actually occur *after* the post
14824 side-effects of '++'. However, gimplification will first visit
14825 the inner expression, so if a separate POST sequence was not
14826 used, the resulting sequence would be:
14828 1 t.1 = *p
14829 2 p = p - 1
14830 3 t.2 = t.1 + 1
14831 4 *p = t.2
14833 However, the post-decrement operation in line #2 must not be
14834 evaluated until after the store to *p at line #4, so the
14835 correct sequence should be:
14837 1 t.1 = *p
14838 2 t.2 = t.1 + 1
14839 3 *p = t.2
14840 4 p = p - 1
14842 So, by specifying a separate post queue, it is possible
14843 to emit the post side-effects in the correct order.
14844 If POST_P is NULL, an internal queue will be used. Before
14845 returning to the caller, the sequence POST_P is appended to
14846 the main output sequence PRE_P.
14848 GIMPLE_TEST_F points to a function that takes a tree T and
14849 returns nonzero if T is in the GIMPLE form requested by the
14850 caller. The GIMPLE predicates are in gimple.cc.
14852 FALLBACK tells the function what sort of a temporary we want if
14853 gimplification cannot produce an expression that complies with
14854 GIMPLE_TEST_F.
14856 fb_none means that no temporary should be generated
14857 fb_rvalue means that an rvalue is OK to generate
14858 fb_lvalue means that an lvalue is OK to generate
14859 fb_either means that either is OK, but an lvalue is preferable.
14860 fb_mayfail means that gimplification may fail (in which case
14861 GS_ERROR will be returned)
14863 The return value is either GS_ERROR or GS_ALL_DONE, since this
14864 function iterates until EXPR is completely gimplified or an error
14865 occurs. */
14867 enum gimplify_status
14868 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
14869 bool (*gimple_test_f) (tree), fallback_t fallback)
14871 tree tmp;
14872 gimple_seq internal_pre = NULL;
14873 gimple_seq internal_post = NULL;
14874 tree save_expr;
14875 bool is_statement;
14876 location_t saved_location;
14877 enum gimplify_status ret;
14878 gimple_stmt_iterator pre_last_gsi, post_last_gsi;
14879 tree label;
14881 save_expr = *expr_p;
14882 if (save_expr == NULL_TREE)
14883 return GS_ALL_DONE;
14885 /* If we are gimplifying a top-level statement, PRE_P must be valid. */
14886 is_statement = gimple_test_f == is_gimple_stmt;
14887 if (is_statement)
14888 gcc_assert (pre_p);
14890 /* Consistency checks. */
14891 if (gimple_test_f == is_gimple_reg)
14892 gcc_assert (fallback & (fb_rvalue | fb_lvalue));
14893 else if (gimple_test_f == is_gimple_val
14894 || gimple_test_f == is_gimple_call_addr
14895 || gimple_test_f == is_gimple_condexpr
14896 || gimple_test_f == is_gimple_condexpr_for_cond
14897 || gimple_test_f == is_gimple_mem_rhs
14898 || gimple_test_f == is_gimple_mem_rhs_or_call
14899 || gimple_test_f == is_gimple_reg_rhs
14900 || gimple_test_f == is_gimple_reg_rhs_or_call
14901 || gimple_test_f == is_gimple_asm_val
14902 || gimple_test_f == is_gimple_mem_ref_addr)
14903 gcc_assert (fallback & fb_rvalue);
14904 else if (gimple_test_f == is_gimple_min_lval
14905 || gimple_test_f == is_gimple_lvalue)
14906 gcc_assert (fallback & fb_lvalue);
14907 else if (gimple_test_f == is_gimple_addressable)
14908 gcc_assert (fallback & fb_either);
14909 else if (gimple_test_f == is_gimple_stmt)
14910 gcc_assert (fallback == fb_none);
14911 else
14913 /* We should have recognized the GIMPLE_TEST_F predicate to
14914 know what kind of fallback to use in case a temporary is
14915 needed to hold the value or address of *EXPR_P. */
14916 gcc_unreachable ();
14919 /* We used to check the predicate here and return immediately if it
14920 succeeds. This is wrong; the design is for gimplification to be
14921 idempotent, and for the predicates to only test for valid forms, not
14922 whether they are fully simplified. */
14923 if (pre_p == NULL)
14924 pre_p = &internal_pre;
14926 if (post_p == NULL)
14927 post_p = &internal_post;
14929 /* Remember the last statements added to PRE_P and POST_P. Every
14930 new statement added by the gimplification helpers needs to be
14931 annotated with location information. To centralize the
14932 responsibility, we remember the last statement that had been
14933 added to both queues before gimplifying *EXPR_P. If
14934 gimplification produces new statements in PRE_P and POST_P, those
14935 statements will be annotated with the same location information
14936 as *EXPR_P. */
14937 pre_last_gsi = gsi_last (*pre_p);
14938 post_last_gsi = gsi_last (*post_p);
14940 saved_location = input_location;
14941 if (save_expr != error_mark_node
14942 && EXPR_HAS_LOCATION (*expr_p))
14943 input_location = EXPR_LOCATION (*expr_p);
14945 /* Loop over the specific gimplifiers until the toplevel node
14946 remains the same. */
14949 /* Strip away as many useless type conversions as possible
14950 at the toplevel. */
14951 STRIP_USELESS_TYPE_CONVERSION (*expr_p);
14953 /* Remember the expr. */
14954 save_expr = *expr_p;
14956 /* Die, die, die, my darling. */
14957 if (error_operand_p (save_expr))
14959 ret = GS_ERROR;
14960 break;
14963 /* Do any language-specific gimplification. */
14964 ret = ((enum gimplify_status)
14965 lang_hooks.gimplify_expr (expr_p, pre_p, post_p));
14966 if (ret == GS_OK)
14968 if (*expr_p == NULL_TREE)
14969 break;
14970 if (*expr_p != save_expr)
14971 continue;
14973 else if (ret != GS_UNHANDLED)
14974 break;
14976 /* Make sure that all the cases set 'ret' appropriately. */
14977 ret = GS_UNHANDLED;
14978 switch (TREE_CODE (*expr_p))
14980 /* First deal with the special cases. */
14982 case POSTINCREMENT_EXPR:
14983 case POSTDECREMENT_EXPR:
14984 case PREINCREMENT_EXPR:
14985 case PREDECREMENT_EXPR:
14986 ret = gimplify_self_mod_expr (expr_p, pre_p, post_p,
14987 fallback != fb_none,
14988 TREE_TYPE (*expr_p));
14989 break;
14991 case VIEW_CONVERT_EXPR:
14992 if ((fallback & fb_rvalue)
14993 && is_gimple_reg_type (TREE_TYPE (*expr_p))
14994 && is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0))))
14996 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
14997 post_p, is_gimple_val, fb_rvalue);
14998 recalculate_side_effects (*expr_p);
14999 break;
15001 /* Fallthru. */
15003 case ARRAY_REF:
15004 case ARRAY_RANGE_REF:
15005 case REALPART_EXPR:
15006 case IMAGPART_EXPR:
15007 case COMPONENT_REF:
15008 ret = gimplify_compound_lval (expr_p, pre_p, post_p,
15009 fallback ? fallback : fb_rvalue);
15010 break;
15012 case COND_EXPR:
15013 ret = gimplify_cond_expr (expr_p, pre_p, fallback);
15015 /* C99 code may assign to an array in a structure value of a
15016 conditional expression, and this has undefined behavior
15017 only on execution, so create a temporary if an lvalue is
15018 required. */
15019 if (fallback == fb_lvalue)
15021 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
15022 mark_addressable (*expr_p);
15023 ret = GS_OK;
15025 break;
15027 case CALL_EXPR:
15028 ret = gimplify_call_expr (expr_p, pre_p, fallback != fb_none);
15030 /* C99 code may assign to an array in a structure returned
15031 from a function, and this has undefined behavior only on
15032 execution, so create a temporary if an lvalue is
15033 required. */
15034 if (fallback == fb_lvalue)
15036 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
15037 mark_addressable (*expr_p);
15038 ret = GS_OK;
15040 break;
15042 case TREE_LIST:
15043 gcc_unreachable ();
15045 case COMPOUND_EXPR:
15046 ret = gimplify_compound_expr (expr_p, pre_p, fallback != fb_none);
15047 break;
15049 case COMPOUND_LITERAL_EXPR:
15050 ret = gimplify_compound_literal_expr (expr_p, pre_p,
15051 gimple_test_f, fallback);
15052 break;
15054 case MODIFY_EXPR:
15055 case INIT_EXPR:
15056 ret = gimplify_modify_expr (expr_p, pre_p, post_p,
15057 fallback != fb_none);
15058 break;
15060 case TRUTH_ANDIF_EXPR:
15061 case TRUTH_ORIF_EXPR:
15063 /* Preserve the original type of the expression and the
15064 source location of the outer expression. */
15065 tree org_type = TREE_TYPE (*expr_p);
15066 *expr_p = gimple_boolify (*expr_p);
15067 *expr_p = build3_loc (input_location, COND_EXPR,
15068 org_type, *expr_p,
15069 fold_convert_loc
15070 (input_location,
15071 org_type, boolean_true_node),
15072 fold_convert_loc
15073 (input_location,
15074 org_type, boolean_false_node));
15075 ret = GS_OK;
15076 break;
15079 case TRUTH_NOT_EXPR:
15081 tree type = TREE_TYPE (*expr_p);
15082 /* The parsers are careful to generate TRUTH_NOT_EXPR
15083 only with operands that are always zero or one.
15084 We do not fold here but handle the only interesting case
15085 manually, as fold may re-introduce the TRUTH_NOT_EXPR. */
15086 *expr_p = gimple_boolify (*expr_p);
15087 if (TYPE_PRECISION (TREE_TYPE (*expr_p)) == 1)
15088 *expr_p = build1_loc (input_location, BIT_NOT_EXPR,
15089 TREE_TYPE (*expr_p),
15090 TREE_OPERAND (*expr_p, 0));
15091 else
15092 *expr_p = build2_loc (input_location, BIT_XOR_EXPR,
15093 TREE_TYPE (*expr_p),
15094 TREE_OPERAND (*expr_p, 0),
15095 build_int_cst (TREE_TYPE (*expr_p), 1));
15096 if (!useless_type_conversion_p (type, TREE_TYPE (*expr_p)))
15097 *expr_p = fold_convert_loc (input_location, type, *expr_p);
15098 ret = GS_OK;
15099 break;
15102 case ADDR_EXPR:
15103 ret = gimplify_addr_expr (expr_p, pre_p, post_p);
15104 break;
15106 case ANNOTATE_EXPR:
15108 tree cond = TREE_OPERAND (*expr_p, 0);
15109 tree kind = TREE_OPERAND (*expr_p, 1);
15110 tree data = TREE_OPERAND (*expr_p, 2);
15111 tree type = TREE_TYPE (cond);
15112 if (!INTEGRAL_TYPE_P (type))
15114 *expr_p = cond;
15115 ret = GS_OK;
15116 break;
15118 tree tmp = create_tmp_var (type);
15119 gimplify_arg (&cond, pre_p, EXPR_LOCATION (*expr_p));
15120 gcall *call
15121 = gimple_build_call_internal (IFN_ANNOTATE, 3, cond, kind, data);
15122 gimple_call_set_lhs (call, tmp);
15123 gimplify_seq_add_stmt (pre_p, call);
15124 *expr_p = tmp;
15125 ret = GS_ALL_DONE;
15126 break;
15129 case VA_ARG_EXPR:
15130 ret = gimplify_va_arg_expr (expr_p, pre_p, post_p);
15131 break;
15133 CASE_CONVERT:
15134 if (IS_EMPTY_STMT (*expr_p))
15136 ret = GS_ALL_DONE;
15137 break;
15140 if (VOID_TYPE_P (TREE_TYPE (*expr_p))
15141 || fallback == fb_none)
15143 /* Just strip a conversion to void (or in void context) and
15144 try again. */
15145 *expr_p = TREE_OPERAND (*expr_p, 0);
15146 ret = GS_OK;
15147 break;
15150 ret = gimplify_conversion (expr_p);
15151 if (ret == GS_ERROR)
15152 break;
15153 if (*expr_p != save_expr)
15154 break;
15155 /* FALLTHRU */
15157 case FIX_TRUNC_EXPR:
15158 /* unary_expr: ... | '(' cast ')' val | ... */
15159 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
15160 is_gimple_val, fb_rvalue);
15161 recalculate_side_effects (*expr_p);
15162 break;
15164 case INDIRECT_REF:
15166 bool volatilep = TREE_THIS_VOLATILE (*expr_p);
15167 bool notrap = TREE_THIS_NOTRAP (*expr_p);
15168 tree saved_ptr_type = TREE_TYPE (TREE_OPERAND (*expr_p, 0));
15170 *expr_p = fold_indirect_ref_loc (input_location, *expr_p);
15171 if (*expr_p != save_expr)
15173 ret = GS_OK;
15174 break;
15177 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
15178 is_gimple_reg, fb_rvalue);
15179 if (ret == GS_ERROR)
15180 break;
15182 recalculate_side_effects (*expr_p);
15183 *expr_p = fold_build2_loc (input_location, MEM_REF,
15184 TREE_TYPE (*expr_p),
15185 TREE_OPERAND (*expr_p, 0),
15186 build_int_cst (saved_ptr_type, 0));
15187 TREE_THIS_VOLATILE (*expr_p) = volatilep;
15188 TREE_THIS_NOTRAP (*expr_p) = notrap;
15189 ret = GS_OK;
15190 break;
15193 /* We arrive here through the various re-gimplifcation paths. */
15194 case MEM_REF:
15195 /* First try re-folding the whole thing. */
15196 tmp = fold_binary (MEM_REF, TREE_TYPE (*expr_p),
15197 TREE_OPERAND (*expr_p, 0),
15198 TREE_OPERAND (*expr_p, 1));
15199 if (tmp)
15201 REF_REVERSE_STORAGE_ORDER (tmp)
15202 = REF_REVERSE_STORAGE_ORDER (*expr_p);
15203 *expr_p = tmp;
15204 recalculate_side_effects (*expr_p);
15205 ret = GS_OK;
15206 break;
15208 /* Avoid re-gimplifying the address operand if it is already
15209 in suitable form. Re-gimplifying would mark the address
15210 operand addressable. Always gimplify when not in SSA form
15211 as we still may have to gimplify decls with value-exprs. */
15212 if (!gimplify_ctxp || !gimple_in_ssa_p (cfun)
15213 || !is_gimple_mem_ref_addr (TREE_OPERAND (*expr_p, 0)))
15215 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
15216 is_gimple_mem_ref_addr, fb_rvalue);
15217 if (ret == GS_ERROR)
15218 break;
15220 recalculate_side_effects (*expr_p);
15221 ret = GS_ALL_DONE;
15222 break;
15224 /* Constants need not be gimplified. */
15225 case INTEGER_CST:
15226 case REAL_CST:
15227 case FIXED_CST:
15228 case STRING_CST:
15229 case COMPLEX_CST:
15230 case VECTOR_CST:
15231 /* Drop the overflow flag on constants, we do not want
15232 that in the GIMPLE IL. */
15233 if (TREE_OVERFLOW_P (*expr_p))
15234 *expr_p = drop_tree_overflow (*expr_p);
15235 ret = GS_ALL_DONE;
15236 break;
15238 case CONST_DECL:
15239 /* If we require an lvalue, such as for ADDR_EXPR, retain the
15240 CONST_DECL node. Otherwise the decl is replaceable by its
15241 value. */
15242 /* ??? Should be == fb_lvalue, but ADDR_EXPR passes fb_either. */
15243 if (fallback & fb_lvalue)
15244 ret = GS_ALL_DONE;
15245 else
15247 *expr_p = DECL_INITIAL (*expr_p);
15248 ret = GS_OK;
15250 break;
15252 case DECL_EXPR:
15253 ret = gimplify_decl_expr (expr_p, pre_p);
15254 break;
15256 case BIND_EXPR:
15257 ret = gimplify_bind_expr (expr_p, pre_p);
15258 break;
15260 case LOOP_EXPR:
15261 ret = gimplify_loop_expr (expr_p, pre_p);
15262 break;
15264 case SWITCH_EXPR:
15265 ret = gimplify_switch_expr (expr_p, pre_p);
15266 break;
15268 case EXIT_EXPR:
15269 ret = gimplify_exit_expr (expr_p);
15270 break;
15272 case GOTO_EXPR:
15273 /* If the target is not LABEL, then it is a computed jump
15274 and the target needs to be gimplified. */
15275 if (TREE_CODE (GOTO_DESTINATION (*expr_p)) != LABEL_DECL)
15277 ret = gimplify_expr (&GOTO_DESTINATION (*expr_p), pre_p,
15278 NULL, is_gimple_val, fb_rvalue);
15279 if (ret == GS_ERROR)
15280 break;
15282 gimplify_seq_add_stmt (pre_p,
15283 gimple_build_goto (GOTO_DESTINATION (*expr_p)));
15284 ret = GS_ALL_DONE;
15285 break;
15287 case PREDICT_EXPR:
15288 gimplify_seq_add_stmt (pre_p,
15289 gimple_build_predict (PREDICT_EXPR_PREDICTOR (*expr_p),
15290 PREDICT_EXPR_OUTCOME (*expr_p)));
15291 ret = GS_ALL_DONE;
15292 break;
15294 case LABEL_EXPR:
15295 ret = gimplify_label_expr (expr_p, pre_p);
15296 label = LABEL_EXPR_LABEL (*expr_p);
15297 gcc_assert (decl_function_context (label) == current_function_decl);
15299 /* If the label is used in a goto statement, or address of the label
15300 is taken, we need to unpoison all variables that were seen so far.
15301 Doing so would prevent us from reporting a false positives. */
15302 if (asan_poisoned_variables
15303 && asan_used_labels != NULL
15304 && asan_used_labels->contains (label)
15305 && !gimplify_omp_ctxp)
15306 asan_poison_variables (asan_poisoned_variables, false, pre_p);
15307 break;
15309 case CASE_LABEL_EXPR:
15310 ret = gimplify_case_label_expr (expr_p, pre_p);
15312 if (gimplify_ctxp->live_switch_vars)
15313 asan_poison_variables (gimplify_ctxp->live_switch_vars, false,
15314 pre_p);
15315 break;
15317 case RETURN_EXPR:
15318 ret = gimplify_return_expr (*expr_p, pre_p);
15319 break;
15321 case CONSTRUCTOR:
15322 /* Don't reduce this in place; let gimplify_init_constructor work its
15323 magic. Buf if we're just elaborating this for side effects, just
15324 gimplify any element that has side-effects. */
15325 if (fallback == fb_none)
15327 unsigned HOST_WIDE_INT ix;
15328 tree val;
15329 tree temp = NULL_TREE;
15330 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (*expr_p), ix, val)
15331 if (TREE_SIDE_EFFECTS (val))
15332 append_to_statement_list (val, &temp);
15334 *expr_p = temp;
15335 ret = temp ? GS_OK : GS_ALL_DONE;
15337 /* C99 code may assign to an array in a constructed
15338 structure or union, and this has undefined behavior only
15339 on execution, so create a temporary if an lvalue is
15340 required. */
15341 else if (fallback == fb_lvalue)
15343 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
15344 mark_addressable (*expr_p);
15345 ret = GS_OK;
15347 else
15348 ret = GS_ALL_DONE;
15349 break;
15351 /* The following are special cases that are not handled by the
15352 original GIMPLE grammar. */
15354 /* SAVE_EXPR nodes are converted into a GIMPLE identifier and
15355 eliminated. */
15356 case SAVE_EXPR:
15357 ret = gimplify_save_expr (expr_p, pre_p, post_p);
15358 break;
15360 case BIT_FIELD_REF:
15361 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15362 post_p, is_gimple_lvalue, fb_either);
15363 recalculate_side_effects (*expr_p);
15364 break;
15366 case TARGET_MEM_REF:
15368 enum gimplify_status r0 = GS_ALL_DONE, r1 = GS_ALL_DONE;
15370 if (TMR_BASE (*expr_p))
15371 r0 = gimplify_expr (&TMR_BASE (*expr_p), pre_p,
15372 post_p, is_gimple_mem_ref_addr, fb_either);
15373 if (TMR_INDEX (*expr_p))
15374 r1 = gimplify_expr (&TMR_INDEX (*expr_p), pre_p,
15375 post_p, is_gimple_val, fb_rvalue);
15376 if (TMR_INDEX2 (*expr_p))
15377 r1 = gimplify_expr (&TMR_INDEX2 (*expr_p), pre_p,
15378 post_p, is_gimple_val, fb_rvalue);
15379 /* TMR_STEP and TMR_OFFSET are always integer constants. */
15380 ret = MIN (r0, r1);
15382 break;
15384 case NON_LVALUE_EXPR:
15385 /* This should have been stripped above. */
15386 gcc_unreachable ();
15388 case ASM_EXPR:
15389 ret = gimplify_asm_expr (expr_p, pre_p, post_p);
15390 break;
15392 case TRY_FINALLY_EXPR:
15393 case TRY_CATCH_EXPR:
15395 gimple_seq eval, cleanup;
15396 gtry *try_;
15398 /* Calls to destructors are generated automatically in FINALLY/CATCH
15399 block. They should have location as UNKNOWN_LOCATION. However,
15400 gimplify_call_expr will reset these call stmts to input_location
15401 if it finds stmt's location is unknown. To prevent resetting for
15402 destructors, we set the input_location to unknown.
15403 Note that this only affects the destructor calls in FINALLY/CATCH
15404 block, and will automatically reset to its original value by the
15405 end of gimplify_expr. */
15406 input_location = UNKNOWN_LOCATION;
15407 eval = cleanup = NULL;
15408 gimplify_and_add (TREE_OPERAND (*expr_p, 0), &eval);
15409 if (TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
15410 && TREE_CODE (TREE_OPERAND (*expr_p, 1)) == EH_ELSE_EXPR)
15412 gimple_seq n = NULL, e = NULL;
15413 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1),
15414 0), &n);
15415 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1),
15416 1), &e);
15417 if (!gimple_seq_empty_p (n) && !gimple_seq_empty_p (e))
15419 geh_else *stmt = gimple_build_eh_else (n, e);
15420 gimple_seq_add_stmt (&cleanup, stmt);
15423 else
15424 gimplify_and_add (TREE_OPERAND (*expr_p, 1), &cleanup);
15425 /* Don't create bogus GIMPLE_TRY with empty cleanup. */
15426 if (gimple_seq_empty_p (cleanup))
15428 gimple_seq_add_seq (pre_p, eval);
15429 ret = GS_ALL_DONE;
15430 break;
15432 try_ = gimple_build_try (eval, cleanup,
15433 TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
15434 ? GIMPLE_TRY_FINALLY
15435 : GIMPLE_TRY_CATCH);
15436 if (EXPR_HAS_LOCATION (save_expr))
15437 gimple_set_location (try_, EXPR_LOCATION (save_expr));
15438 else if (LOCATION_LOCUS (saved_location) != UNKNOWN_LOCATION)
15439 gimple_set_location (try_, saved_location);
15440 if (TREE_CODE (*expr_p) == TRY_CATCH_EXPR)
15441 gimple_try_set_catch_is_cleanup (try_,
15442 TRY_CATCH_IS_CLEANUP (*expr_p));
15443 gimplify_seq_add_stmt (pre_p, try_);
15444 ret = GS_ALL_DONE;
15445 break;
15448 case CLEANUP_POINT_EXPR:
15449 ret = gimplify_cleanup_point_expr (expr_p, pre_p);
15450 break;
15452 case TARGET_EXPR:
15453 ret = gimplify_target_expr (expr_p, pre_p, post_p);
15454 break;
15456 case CATCH_EXPR:
15458 gimple *c;
15459 gimple_seq handler = NULL;
15460 gimplify_and_add (CATCH_BODY (*expr_p), &handler);
15461 c = gimple_build_catch (CATCH_TYPES (*expr_p), handler);
15462 gimplify_seq_add_stmt (pre_p, c);
15463 ret = GS_ALL_DONE;
15464 break;
15467 case EH_FILTER_EXPR:
15469 gimple *ehf;
15470 gimple_seq failure = NULL;
15472 gimplify_and_add (EH_FILTER_FAILURE (*expr_p), &failure);
15473 ehf = gimple_build_eh_filter (EH_FILTER_TYPES (*expr_p), failure);
15474 copy_warning (ehf, *expr_p);
15475 gimplify_seq_add_stmt (pre_p, ehf);
15476 ret = GS_ALL_DONE;
15477 break;
15480 case OBJ_TYPE_REF:
15482 enum gimplify_status r0, r1;
15483 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p,
15484 post_p, is_gimple_val, fb_rvalue);
15485 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p,
15486 post_p, is_gimple_val, fb_rvalue);
15487 TREE_SIDE_EFFECTS (*expr_p) = 0;
15488 ret = MIN (r0, r1);
15490 break;
15492 case LABEL_DECL:
15493 /* We get here when taking the address of a label. We mark
15494 the label as "forced"; meaning it can never be removed and
15495 it is a potential target for any computed goto. */
15496 FORCED_LABEL (*expr_p) = 1;
15497 ret = GS_ALL_DONE;
15498 break;
15500 case STATEMENT_LIST:
15501 ret = gimplify_statement_list (expr_p, pre_p);
15502 break;
15504 case WITH_SIZE_EXPR:
15506 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15507 post_p == &internal_post ? NULL : post_p,
15508 gimple_test_f, fallback);
15509 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
15510 is_gimple_val, fb_rvalue);
15511 ret = GS_ALL_DONE;
15513 break;
15515 case VAR_DECL:
15516 case PARM_DECL:
15517 ret = gimplify_var_or_parm_decl (expr_p);
15518 break;
15520 case RESULT_DECL:
15521 /* When within an OMP context, notice uses of variables. */
15522 if (gimplify_omp_ctxp)
15523 omp_notice_variable (gimplify_omp_ctxp, *expr_p, true);
15524 ret = GS_ALL_DONE;
15525 break;
15527 case DEBUG_EXPR_DECL:
15528 gcc_unreachable ();
15530 case DEBUG_BEGIN_STMT:
15531 gimplify_seq_add_stmt (pre_p,
15532 gimple_build_debug_begin_stmt
15533 (TREE_BLOCK (*expr_p),
15534 EXPR_LOCATION (*expr_p)));
15535 ret = GS_ALL_DONE;
15536 *expr_p = NULL;
15537 break;
15539 case SSA_NAME:
15540 /* Allow callbacks into the gimplifier during optimization. */
15541 ret = GS_ALL_DONE;
15542 break;
15544 case OMP_PARALLEL:
15545 gimplify_omp_parallel (expr_p, pre_p);
15546 ret = GS_ALL_DONE;
15547 break;
15549 case OMP_TASK:
15550 gimplify_omp_task (expr_p, pre_p);
15551 ret = GS_ALL_DONE;
15552 break;
15554 case OMP_SIMD:
15556 /* Temporarily disable into_ssa, as scan_omp_simd
15557 which calls copy_gimple_seq_and_replace_locals can't deal
15558 with SSA_NAMEs defined outside of the body properly. */
15559 bool saved_into_ssa = gimplify_ctxp->into_ssa;
15560 gimplify_ctxp->into_ssa = false;
15561 ret = gimplify_omp_for (expr_p, pre_p);
15562 gimplify_ctxp->into_ssa = saved_into_ssa;
15563 break;
15566 case OMP_FOR:
15567 case OMP_DISTRIBUTE:
15568 case OMP_TASKLOOP:
15569 case OACC_LOOP:
15570 ret = gimplify_omp_for (expr_p, pre_p);
15571 break;
15573 case OMP_LOOP:
15574 ret = gimplify_omp_loop (expr_p, pre_p);
15575 break;
15577 case OACC_CACHE:
15578 gimplify_oacc_cache (expr_p, pre_p);
15579 ret = GS_ALL_DONE;
15580 break;
15582 case OACC_DECLARE:
15583 gimplify_oacc_declare (expr_p, pre_p);
15584 ret = GS_ALL_DONE;
15585 break;
15587 case OACC_HOST_DATA:
15588 case OACC_DATA:
15589 case OACC_KERNELS:
15590 case OACC_PARALLEL:
15591 case OACC_SERIAL:
15592 case OMP_SCOPE:
15593 case OMP_SECTIONS:
15594 case OMP_SINGLE:
15595 case OMP_TARGET:
15596 case OMP_TARGET_DATA:
15597 case OMP_TEAMS:
15598 gimplify_omp_workshare (expr_p, pre_p);
15599 ret = GS_ALL_DONE;
15600 break;
15602 case OACC_ENTER_DATA:
15603 case OACC_EXIT_DATA:
15604 case OACC_UPDATE:
15605 case OMP_TARGET_UPDATE:
15606 case OMP_TARGET_ENTER_DATA:
15607 case OMP_TARGET_EXIT_DATA:
15608 gimplify_omp_target_update (expr_p, pre_p);
15609 ret = GS_ALL_DONE;
15610 break;
15612 case OMP_SECTION:
15613 case OMP_MASTER:
15614 case OMP_MASKED:
15615 case OMP_ORDERED:
15616 case OMP_CRITICAL:
15617 case OMP_SCAN:
15619 gimple_seq body = NULL;
15620 gimple *g;
15621 bool saved_in_omp_construct = in_omp_construct;
15623 in_omp_construct = true;
15624 gimplify_and_add (OMP_BODY (*expr_p), &body);
15625 in_omp_construct = saved_in_omp_construct;
15626 switch (TREE_CODE (*expr_p))
15628 case OMP_SECTION:
15629 g = gimple_build_omp_section (body);
15630 break;
15631 case OMP_MASTER:
15632 g = gimple_build_omp_master (body);
15633 break;
15634 case OMP_ORDERED:
15635 g = gimplify_omp_ordered (*expr_p, body);
15636 break;
15637 case OMP_MASKED:
15638 gimplify_scan_omp_clauses (&OMP_MASKED_CLAUSES (*expr_p),
15639 pre_p, ORT_WORKSHARE, OMP_MASKED);
15640 gimplify_adjust_omp_clauses (pre_p, body,
15641 &OMP_MASKED_CLAUSES (*expr_p),
15642 OMP_MASKED);
15643 g = gimple_build_omp_masked (body,
15644 OMP_MASKED_CLAUSES (*expr_p));
15645 break;
15646 case OMP_CRITICAL:
15647 gimplify_scan_omp_clauses (&OMP_CRITICAL_CLAUSES (*expr_p),
15648 pre_p, ORT_WORKSHARE, OMP_CRITICAL);
15649 gimplify_adjust_omp_clauses (pre_p, body,
15650 &OMP_CRITICAL_CLAUSES (*expr_p),
15651 OMP_CRITICAL);
15652 g = gimple_build_omp_critical (body,
15653 OMP_CRITICAL_NAME (*expr_p),
15654 OMP_CRITICAL_CLAUSES (*expr_p));
15655 break;
15656 case OMP_SCAN:
15657 gimplify_scan_omp_clauses (&OMP_SCAN_CLAUSES (*expr_p),
15658 pre_p, ORT_WORKSHARE, OMP_SCAN);
15659 gimplify_adjust_omp_clauses (pre_p, body,
15660 &OMP_SCAN_CLAUSES (*expr_p),
15661 OMP_SCAN);
15662 g = gimple_build_omp_scan (body, OMP_SCAN_CLAUSES (*expr_p));
15663 break;
15664 default:
15665 gcc_unreachable ();
15667 gimplify_seq_add_stmt (pre_p, g);
15668 ret = GS_ALL_DONE;
15669 break;
15672 case OMP_TASKGROUP:
15674 gimple_seq body = NULL;
15676 tree *pclauses = &OMP_TASKGROUP_CLAUSES (*expr_p);
15677 bool saved_in_omp_construct = in_omp_construct;
15678 gimplify_scan_omp_clauses (pclauses, pre_p, ORT_TASKGROUP,
15679 OMP_TASKGROUP);
15680 gimplify_adjust_omp_clauses (pre_p, NULL, pclauses, OMP_TASKGROUP);
15682 in_omp_construct = true;
15683 gimplify_and_add (OMP_BODY (*expr_p), &body);
15684 in_omp_construct = saved_in_omp_construct;
15685 gimple_seq cleanup = NULL;
15686 tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_END);
15687 gimple *g = gimple_build_call (fn, 0);
15688 gimple_seq_add_stmt (&cleanup, g);
15689 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
15690 body = NULL;
15691 gimple_seq_add_stmt (&body, g);
15692 g = gimple_build_omp_taskgroup (body, *pclauses);
15693 gimplify_seq_add_stmt (pre_p, g);
15694 ret = GS_ALL_DONE;
15695 break;
15698 case OMP_ATOMIC:
15699 case OMP_ATOMIC_READ:
15700 case OMP_ATOMIC_CAPTURE_OLD:
15701 case OMP_ATOMIC_CAPTURE_NEW:
15702 ret = gimplify_omp_atomic (expr_p, pre_p);
15703 break;
15705 case TRANSACTION_EXPR:
15706 ret = gimplify_transaction (expr_p, pre_p);
15707 break;
15709 case TRUTH_AND_EXPR:
15710 case TRUTH_OR_EXPR:
15711 case TRUTH_XOR_EXPR:
15713 tree orig_type = TREE_TYPE (*expr_p);
15714 tree new_type, xop0, xop1;
15715 *expr_p = gimple_boolify (*expr_p);
15716 new_type = TREE_TYPE (*expr_p);
15717 if (!useless_type_conversion_p (orig_type, new_type))
15719 *expr_p = fold_convert_loc (input_location, orig_type, *expr_p);
15720 ret = GS_OK;
15721 break;
15724 /* Boolified binary truth expressions are semantically equivalent
15725 to bitwise binary expressions. Canonicalize them to the
15726 bitwise variant. */
15727 switch (TREE_CODE (*expr_p))
15729 case TRUTH_AND_EXPR:
15730 TREE_SET_CODE (*expr_p, BIT_AND_EXPR);
15731 break;
15732 case TRUTH_OR_EXPR:
15733 TREE_SET_CODE (*expr_p, BIT_IOR_EXPR);
15734 break;
15735 case TRUTH_XOR_EXPR:
15736 TREE_SET_CODE (*expr_p, BIT_XOR_EXPR);
15737 break;
15738 default:
15739 break;
15741 /* Now make sure that operands have compatible type to
15742 expression's new_type. */
15743 xop0 = TREE_OPERAND (*expr_p, 0);
15744 xop1 = TREE_OPERAND (*expr_p, 1);
15745 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop0)))
15746 TREE_OPERAND (*expr_p, 0) = fold_convert_loc (input_location,
15747 new_type,
15748 xop0);
15749 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop1)))
15750 TREE_OPERAND (*expr_p, 1) = fold_convert_loc (input_location,
15751 new_type,
15752 xop1);
15753 /* Continue classified as tcc_binary. */
15754 goto expr_2;
15757 case VEC_COND_EXPR:
15758 goto expr_3;
15760 case VEC_PERM_EXPR:
15761 /* Classified as tcc_expression. */
15762 goto expr_3;
15764 case BIT_INSERT_EXPR:
15765 /* Argument 3 is a constant. */
15766 goto expr_2;
15768 case POINTER_PLUS_EXPR:
15770 enum gimplify_status r0, r1;
15771 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15772 post_p, is_gimple_val, fb_rvalue);
15773 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
15774 post_p, is_gimple_val, fb_rvalue);
15775 recalculate_side_effects (*expr_p);
15776 ret = MIN (r0, r1);
15777 break;
15780 default:
15781 switch (TREE_CODE_CLASS (TREE_CODE (*expr_p)))
15783 case tcc_comparison:
15784 /* Handle comparison of objects of non scalar mode aggregates
15785 with a call to memcmp. It would be nice to only have to do
15786 this for variable-sized objects, but then we'd have to allow
15787 the same nest of reference nodes we allow for MODIFY_EXPR and
15788 that's too complex.
15790 Compare scalar mode aggregates as scalar mode values. Using
15791 memcmp for them would be very inefficient at best, and is
15792 plain wrong if bitfields are involved. */
15794 tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 1));
15796 /* Vector comparisons need no boolification. */
15797 if (TREE_CODE (type) == VECTOR_TYPE)
15798 goto expr_2;
15799 else if (!AGGREGATE_TYPE_P (type))
15801 tree org_type = TREE_TYPE (*expr_p);
15802 *expr_p = gimple_boolify (*expr_p);
15803 if (!useless_type_conversion_p (org_type,
15804 TREE_TYPE (*expr_p)))
15806 *expr_p = fold_convert_loc (input_location,
15807 org_type, *expr_p);
15808 ret = GS_OK;
15810 else
15811 goto expr_2;
15813 else if (TYPE_MODE (type) != BLKmode)
15814 ret = gimplify_scalar_mode_aggregate_compare (expr_p);
15815 else
15816 ret = gimplify_variable_sized_compare (expr_p);
15818 break;
15821 /* If *EXPR_P does not need to be special-cased, handle it
15822 according to its class. */
15823 case tcc_unary:
15824 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15825 post_p, is_gimple_val, fb_rvalue);
15826 break;
15828 case tcc_binary:
15829 expr_2:
15831 enum gimplify_status r0, r1;
15833 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15834 post_p, is_gimple_val, fb_rvalue);
15835 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
15836 post_p, is_gimple_val, fb_rvalue);
15838 ret = MIN (r0, r1);
15839 break;
15842 expr_3:
15844 enum gimplify_status r0, r1, r2;
15846 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15847 post_p, is_gimple_val, fb_rvalue);
15848 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
15849 post_p, is_gimple_val, fb_rvalue);
15850 r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p,
15851 post_p, is_gimple_val, fb_rvalue);
15853 ret = MIN (MIN (r0, r1), r2);
15854 break;
15857 case tcc_declaration:
15858 case tcc_constant:
15859 ret = GS_ALL_DONE;
15860 goto dont_recalculate;
15862 default:
15863 gcc_unreachable ();
15866 recalculate_side_effects (*expr_p);
15868 dont_recalculate:
15869 break;
15872 gcc_assert (*expr_p || ret != GS_OK);
15874 while (ret == GS_OK);
15876 /* If we encountered an error_mark somewhere nested inside, either
15877 stub out the statement or propagate the error back out. */
15878 if (ret == GS_ERROR)
15880 if (is_statement)
15881 *expr_p = NULL;
15882 goto out;
15885 /* This was only valid as a return value from the langhook, which
15886 we handled. Make sure it doesn't escape from any other context. */
15887 gcc_assert (ret != GS_UNHANDLED);
15889 if (fallback == fb_none && *expr_p && !is_gimple_stmt (*expr_p))
15891 /* We aren't looking for a value, and we don't have a valid
15892 statement. If it doesn't have side-effects, throw it away.
15893 We can also get here with code such as "*&&L;", where L is
15894 a LABEL_DECL that is marked as FORCED_LABEL. */
15895 if (TREE_CODE (*expr_p) == LABEL_DECL
15896 || !TREE_SIDE_EFFECTS (*expr_p))
15897 *expr_p = NULL;
15898 else if (!TREE_THIS_VOLATILE (*expr_p))
15900 /* This is probably a _REF that contains something nested that
15901 has side effects. Recurse through the operands to find it. */
15902 enum tree_code code = TREE_CODE (*expr_p);
15904 switch (code)
15906 case COMPONENT_REF:
15907 case REALPART_EXPR:
15908 case IMAGPART_EXPR:
15909 case VIEW_CONVERT_EXPR:
15910 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
15911 gimple_test_f, fallback);
15912 break;
15914 case ARRAY_REF:
15915 case ARRAY_RANGE_REF:
15916 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
15917 gimple_test_f, fallback);
15918 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
15919 gimple_test_f, fallback);
15920 break;
15922 default:
15923 /* Anything else with side-effects must be converted to
15924 a valid statement before we get here. */
15925 gcc_unreachable ();
15928 *expr_p = NULL;
15930 else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p))
15931 && TYPE_MODE (TREE_TYPE (*expr_p)) != BLKmode
15932 && !is_empty_type (TREE_TYPE (*expr_p)))
15934 /* Historically, the compiler has treated a bare reference
15935 to a non-BLKmode volatile lvalue as forcing a load. */
15936 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p));
15938 /* Normally, we do not want to create a temporary for a
15939 TREE_ADDRESSABLE type because such a type should not be
15940 copied by bitwise-assignment. However, we make an
15941 exception here, as all we are doing here is ensuring that
15942 we read the bytes that make up the type. We use
15943 create_tmp_var_raw because create_tmp_var will abort when
15944 given a TREE_ADDRESSABLE type. */
15945 tree tmp = create_tmp_var_raw (type, "vol");
15946 gimple_add_tmp_var (tmp);
15947 gimplify_assign (tmp, *expr_p, pre_p);
15948 *expr_p = NULL;
15950 else
15951 /* We can't do anything useful with a volatile reference to
15952 an incomplete type, so just throw it away. Likewise for
15953 a BLKmode type, since any implicit inner load should
15954 already have been turned into an explicit one by the
15955 gimplification process. */
15956 *expr_p = NULL;
15959 /* If we are gimplifying at the statement level, we're done. Tack
15960 everything together and return. */
15961 if (fallback == fb_none || is_statement)
15963 /* Since *EXPR_P has been converted into a GIMPLE tuple, clear
15964 it out for GC to reclaim it. */
15965 *expr_p = NULL_TREE;
15967 if (!gimple_seq_empty_p (internal_pre)
15968 || !gimple_seq_empty_p (internal_post))
15970 gimplify_seq_add_seq (&internal_pre, internal_post);
15971 gimplify_seq_add_seq (pre_p, internal_pre);
15974 /* The result of gimplifying *EXPR_P is going to be the last few
15975 statements in *PRE_P and *POST_P. Add location information
15976 to all the statements that were added by the gimplification
15977 helpers. */
15978 if (!gimple_seq_empty_p (*pre_p))
15979 annotate_all_with_location_after (*pre_p, pre_last_gsi, input_location);
15981 if (!gimple_seq_empty_p (*post_p))
15982 annotate_all_with_location_after (*post_p, post_last_gsi,
15983 input_location);
15985 goto out;
15988 #ifdef ENABLE_GIMPLE_CHECKING
15989 if (*expr_p)
15991 enum tree_code code = TREE_CODE (*expr_p);
15992 /* These expressions should already be in gimple IR form. */
15993 gcc_assert (code != MODIFY_EXPR
15994 && code != ASM_EXPR
15995 && code != BIND_EXPR
15996 && code != CATCH_EXPR
15997 && (code != COND_EXPR || gimplify_ctxp->allow_rhs_cond_expr)
15998 && code != EH_FILTER_EXPR
15999 && code != GOTO_EXPR
16000 && code != LABEL_EXPR
16001 && code != LOOP_EXPR
16002 && code != SWITCH_EXPR
16003 && code != TRY_FINALLY_EXPR
16004 && code != EH_ELSE_EXPR
16005 && code != OACC_PARALLEL
16006 && code != OACC_KERNELS
16007 && code != OACC_SERIAL
16008 && code != OACC_DATA
16009 && code != OACC_HOST_DATA
16010 && code != OACC_DECLARE
16011 && code != OACC_UPDATE
16012 && code != OACC_ENTER_DATA
16013 && code != OACC_EXIT_DATA
16014 && code != OACC_CACHE
16015 && code != OMP_CRITICAL
16016 && code != OMP_FOR
16017 && code != OACC_LOOP
16018 && code != OMP_MASTER
16019 && code != OMP_MASKED
16020 && code != OMP_TASKGROUP
16021 && code != OMP_ORDERED
16022 && code != OMP_PARALLEL
16023 && code != OMP_SCAN
16024 && code != OMP_SECTIONS
16025 && code != OMP_SECTION
16026 && code != OMP_SINGLE
16027 && code != OMP_SCOPE);
16029 #endif
16031 /* Otherwise we're gimplifying a subexpression, so the resulting
16032 value is interesting. If it's a valid operand that matches
16033 GIMPLE_TEST_F, we're done. Unless we are handling some
16034 post-effects internally; if that's the case, we need to copy into
16035 a temporary before adding the post-effects to POST_P. */
16036 if (gimple_seq_empty_p (internal_post) && (*gimple_test_f) (*expr_p))
16037 goto out;
16039 /* Otherwise, we need to create a new temporary for the gimplified
16040 expression. */
16042 /* We can't return an lvalue if we have an internal postqueue. The
16043 object the lvalue refers to would (probably) be modified by the
16044 postqueue; we need to copy the value out first, which means an
16045 rvalue. */
16046 if ((fallback & fb_lvalue)
16047 && gimple_seq_empty_p (internal_post)
16048 && is_gimple_addressable (*expr_p))
16050 /* An lvalue will do. Take the address of the expression, store it
16051 in a temporary, and replace the expression with an INDIRECT_REF of
16052 that temporary. */
16053 tree ref_alias_type = reference_alias_ptr_type (*expr_p);
16054 unsigned int ref_align = get_object_alignment (*expr_p);
16055 tree ref_type = TREE_TYPE (*expr_p);
16056 tmp = build_fold_addr_expr_loc (input_location, *expr_p);
16057 gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue);
16058 if (TYPE_ALIGN (ref_type) != ref_align)
16059 ref_type = build_aligned_type (ref_type, ref_align);
16060 *expr_p = build2 (MEM_REF, ref_type,
16061 tmp, build_zero_cst (ref_alias_type));
16063 else if ((fallback & fb_rvalue) && is_gimple_reg_rhs_or_call (*expr_p))
16065 /* An rvalue will do. Assign the gimplified expression into a
16066 new temporary TMP and replace the original expression with
16067 TMP. First, make sure that the expression has a type so that
16068 it can be assigned into a temporary. */
16069 gcc_assert (!VOID_TYPE_P (TREE_TYPE (*expr_p)));
16070 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
16072 else
16074 #ifdef ENABLE_GIMPLE_CHECKING
16075 if (!(fallback & fb_mayfail))
16077 fprintf (stderr, "gimplification failed:\n");
16078 print_generic_expr (stderr, *expr_p);
16079 debug_tree (*expr_p);
16080 internal_error ("gimplification failed");
16082 #endif
16083 gcc_assert (fallback & fb_mayfail);
16085 /* If this is an asm statement, and the user asked for the
16086 impossible, don't die. Fail and let gimplify_asm_expr
16087 issue an error. */
16088 ret = GS_ERROR;
16089 goto out;
16092 /* Make sure the temporary matches our predicate. */
16093 gcc_assert ((*gimple_test_f) (*expr_p));
16095 if (!gimple_seq_empty_p (internal_post))
16097 annotate_all_with_location (internal_post, input_location);
16098 gimplify_seq_add_seq (pre_p, internal_post);
16101 out:
16102 input_location = saved_location;
16103 return ret;
16106 /* Like gimplify_expr but make sure the gimplified result is not itself
16107 a SSA name (but a decl if it were). Temporaries required by
16108 evaluating *EXPR_P may be still SSA names. */
16110 static enum gimplify_status
16111 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
16112 bool (*gimple_test_f) (tree), fallback_t fallback,
16113 bool allow_ssa)
16115 enum gimplify_status ret = gimplify_expr (expr_p, pre_p, post_p,
16116 gimple_test_f, fallback);
16117 if (! allow_ssa
16118 && TREE_CODE (*expr_p) == SSA_NAME)
16119 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, NULL, false);
16120 return ret;
16123 /* Look through TYPE for variable-sized objects and gimplify each such
16124 size that we find. Add to LIST_P any statements generated. */
16126 void
16127 gimplify_type_sizes (tree type, gimple_seq *list_p)
16129 if (type == NULL || type == error_mark_node)
16130 return;
16132 const bool ignored_p
16133 = TYPE_NAME (type)
16134 && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
16135 && DECL_IGNORED_P (TYPE_NAME (type));
16136 tree t;
16138 /* We first do the main variant, then copy into any other variants. */
16139 type = TYPE_MAIN_VARIANT (type);
16141 /* Avoid infinite recursion. */
16142 if (TYPE_SIZES_GIMPLIFIED (type))
16143 return;
16145 TYPE_SIZES_GIMPLIFIED (type) = 1;
16147 switch (TREE_CODE (type))
16149 case INTEGER_TYPE:
16150 case ENUMERAL_TYPE:
16151 case BOOLEAN_TYPE:
16152 case REAL_TYPE:
16153 case FIXED_POINT_TYPE:
16154 gimplify_one_sizepos (&TYPE_MIN_VALUE (type), list_p);
16155 gimplify_one_sizepos (&TYPE_MAX_VALUE (type), list_p);
16157 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
16159 TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type);
16160 TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type);
16162 break;
16164 case ARRAY_TYPE:
16165 /* These types may not have declarations, so handle them here. */
16166 gimplify_type_sizes (TREE_TYPE (type), list_p);
16167 gimplify_type_sizes (TYPE_DOMAIN (type), list_p);
16168 /* Ensure VLA bounds aren't removed, for -O0 they should be variables
16169 with assigned stack slots, for -O1+ -g they should be tracked
16170 by VTA. */
16171 if (!ignored_p
16172 && TYPE_DOMAIN (type)
16173 && INTEGRAL_TYPE_P (TYPE_DOMAIN (type)))
16175 t = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
16176 if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
16177 DECL_IGNORED_P (t) = 0;
16178 t = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
16179 if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
16180 DECL_IGNORED_P (t) = 0;
16182 break;
16184 case RECORD_TYPE:
16185 case UNION_TYPE:
16186 case QUAL_UNION_TYPE:
16187 for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
16188 if (TREE_CODE (field) == FIELD_DECL)
16190 gimplify_one_sizepos (&DECL_FIELD_OFFSET (field), list_p);
16191 /* Likewise, ensure variable offsets aren't removed. */
16192 if (!ignored_p
16193 && (t = DECL_FIELD_OFFSET (field))
16194 && VAR_P (t)
16195 && DECL_ARTIFICIAL (t))
16196 DECL_IGNORED_P (t) = 0;
16197 gimplify_one_sizepos (&DECL_SIZE (field), list_p);
16198 gimplify_one_sizepos (&DECL_SIZE_UNIT (field), list_p);
16199 gimplify_type_sizes (TREE_TYPE (field), list_p);
16201 break;
16203 case POINTER_TYPE:
16204 case REFERENCE_TYPE:
16205 /* We used to recurse on the pointed-to type here, which turned out to
16206 be incorrect because its definition might refer to variables not
16207 yet initialized at this point if a forward declaration is involved.
16209 It was actually useful for anonymous pointed-to types to ensure
16210 that the sizes evaluation dominates every possible later use of the
16211 values. Restricting to such types here would be safe since there
16212 is no possible forward declaration around, but would introduce an
16213 undesirable middle-end semantic to anonymity. We then defer to
16214 front-ends the responsibility of ensuring that the sizes are
16215 evaluated both early and late enough, e.g. by attaching artificial
16216 type declarations to the tree. */
16217 break;
16219 default:
16220 break;
16223 gimplify_one_sizepos (&TYPE_SIZE (type), list_p);
16224 gimplify_one_sizepos (&TYPE_SIZE_UNIT (type), list_p);
16226 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
16228 TYPE_SIZE (t) = TYPE_SIZE (type);
16229 TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (type);
16230 TYPE_SIZES_GIMPLIFIED (t) = 1;
16234 /* A subroutine of gimplify_type_sizes to make sure that *EXPR_P,
16235 a size or position, has had all of its SAVE_EXPRs evaluated.
16236 We add any required statements to *STMT_P. */
16238 void
16239 gimplify_one_sizepos (tree *expr_p, gimple_seq *stmt_p)
16241 tree expr = *expr_p;
16243 /* We don't do anything if the value isn't there, is constant, or contains
16244 A PLACEHOLDER_EXPR. We also don't want to do anything if it's already
16245 a VAR_DECL. If it's a VAR_DECL from another function, the gimplifier
16246 will want to replace it with a new variable, but that will cause problems
16247 if this type is from outside the function. It's OK to have that here. */
16248 if (expr == NULL_TREE
16249 || is_gimple_constant (expr)
16250 || TREE_CODE (expr) == VAR_DECL
16251 || CONTAINS_PLACEHOLDER_P (expr))
16252 return;
16254 *expr_p = unshare_expr (expr);
16256 /* SSA names in decl/type fields are a bad idea - they'll get reclaimed
16257 if the def vanishes. */
16258 gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue, false);
16260 /* If expr wasn't already is_gimple_sizepos or is_gimple_constant from the
16261 FE, ensure that it is a VAR_DECL, otherwise we might handle some decls
16262 as gimplify_vla_decl even when they would have all sizes INTEGER_CSTs. */
16263 if (is_gimple_constant (*expr_p))
16264 *expr_p = get_initialized_tmp_var (*expr_p, stmt_p, NULL, false);
16267 /* Gimplify the body of statements of FNDECL and return a GIMPLE_BIND node
16268 containing the sequence of corresponding GIMPLE statements. If DO_PARMS
16269 is true, also gimplify the parameters. */
16271 gbind *
16272 gimplify_body (tree fndecl, bool do_parms)
16274 location_t saved_location = input_location;
16275 gimple_seq parm_stmts, parm_cleanup = NULL, seq;
16276 gimple *outer_stmt;
16277 gbind *outer_bind;
16279 timevar_push (TV_TREE_GIMPLIFY);
16281 init_tree_ssa (cfun);
16283 /* Initialize for optimize_insn_for_s{ize,peed}_p possibly called during
16284 gimplification. */
16285 default_rtl_profile ();
16287 gcc_assert (gimplify_ctxp == NULL);
16288 push_gimplify_context (true);
16290 if (flag_openacc || flag_openmp)
16292 gcc_assert (gimplify_omp_ctxp == NULL);
16293 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (fndecl)))
16294 gimplify_omp_ctxp = new_omp_context (ORT_IMPLICIT_TARGET);
16297 /* Unshare most shared trees in the body and in that of any nested functions.
16298 It would seem we don't have to do this for nested functions because
16299 they are supposed to be output and then the outer function gimplified
16300 first, but the g++ front end doesn't always do it that way. */
16301 unshare_body (fndecl);
16302 unvisit_body (fndecl);
16304 /* Make sure input_location isn't set to something weird. */
16305 input_location = DECL_SOURCE_LOCATION (fndecl);
16307 /* Resolve callee-copies. This has to be done before processing
16308 the body so that DECL_VALUE_EXPR gets processed correctly. */
16309 parm_stmts = do_parms ? gimplify_parameters (&parm_cleanup) : NULL;
16311 /* Gimplify the function's body. */
16312 seq = NULL;
16313 gimplify_stmt (&DECL_SAVED_TREE (fndecl), &seq);
16314 outer_stmt = gimple_seq_first_nondebug_stmt (seq);
16315 if (!outer_stmt)
16317 outer_stmt = gimple_build_nop ();
16318 gimplify_seq_add_stmt (&seq, outer_stmt);
16321 /* The body must contain exactly one statement, a GIMPLE_BIND. If this is
16322 not the case, wrap everything in a GIMPLE_BIND to make it so. */
16323 if (gimple_code (outer_stmt) == GIMPLE_BIND
16324 && (gimple_seq_first_nondebug_stmt (seq)
16325 == gimple_seq_last_nondebug_stmt (seq)))
16327 outer_bind = as_a <gbind *> (outer_stmt);
16328 if (gimple_seq_first_stmt (seq) != outer_stmt
16329 || gimple_seq_last_stmt (seq) != outer_stmt)
16331 /* If there are debug stmts before or after outer_stmt, move them
16332 inside of outer_bind body. */
16333 gimple_stmt_iterator gsi = gsi_for_stmt (outer_stmt, &seq);
16334 gimple_seq second_seq = NULL;
16335 if (gimple_seq_first_stmt (seq) != outer_stmt
16336 && gimple_seq_last_stmt (seq) != outer_stmt)
16338 second_seq = gsi_split_seq_after (gsi);
16339 gsi_remove (&gsi, false);
16341 else if (gimple_seq_first_stmt (seq) != outer_stmt)
16342 gsi_remove (&gsi, false);
16343 else
16345 gsi_remove (&gsi, false);
16346 second_seq = seq;
16347 seq = NULL;
16349 gimple_seq_add_seq_without_update (&seq,
16350 gimple_bind_body (outer_bind));
16351 gimple_seq_add_seq_without_update (&seq, second_seq);
16352 gimple_bind_set_body (outer_bind, seq);
16355 else
16356 outer_bind = gimple_build_bind (NULL_TREE, seq, NULL);
16358 DECL_SAVED_TREE (fndecl) = NULL_TREE;
16360 /* If we had callee-copies statements, insert them at the beginning
16361 of the function and clear DECL_VALUE_EXPR_P on the parameters. */
16362 if (!gimple_seq_empty_p (parm_stmts))
16364 tree parm;
16366 gimplify_seq_add_seq (&parm_stmts, gimple_bind_body (outer_bind));
16367 if (parm_cleanup)
16369 gtry *g = gimple_build_try (parm_stmts, parm_cleanup,
16370 GIMPLE_TRY_FINALLY);
16371 parm_stmts = NULL;
16372 gimple_seq_add_stmt (&parm_stmts, g);
16374 gimple_bind_set_body (outer_bind, parm_stmts);
16376 for (parm = DECL_ARGUMENTS (current_function_decl);
16377 parm; parm = DECL_CHAIN (parm))
16378 if (DECL_HAS_VALUE_EXPR_P (parm))
16380 DECL_HAS_VALUE_EXPR_P (parm) = 0;
16381 DECL_IGNORED_P (parm) = 0;
16385 if ((flag_openacc || flag_openmp || flag_openmp_simd)
16386 && gimplify_omp_ctxp)
16388 delete_omp_context (gimplify_omp_ctxp);
16389 gimplify_omp_ctxp = NULL;
16392 pop_gimplify_context (outer_bind);
16393 gcc_assert (gimplify_ctxp == NULL);
16395 if (flag_checking && !seen_error ())
16396 verify_gimple_in_seq (gimple_bind_body (outer_bind));
16398 timevar_pop (TV_TREE_GIMPLIFY);
16399 input_location = saved_location;
16401 return outer_bind;
16404 typedef char *char_p; /* For DEF_VEC_P. */
16406 /* Return whether we should exclude FNDECL from instrumentation. */
16408 static bool
16409 flag_instrument_functions_exclude_p (tree fndecl)
16411 vec<char_p> *v;
16413 v = (vec<char_p> *) flag_instrument_functions_exclude_functions;
16414 if (v && v->length () > 0)
16416 const char *name;
16417 int i;
16418 char *s;
16420 name = lang_hooks.decl_printable_name (fndecl, 1);
16421 FOR_EACH_VEC_ELT (*v, i, s)
16422 if (strstr (name, s) != NULL)
16423 return true;
16426 v = (vec<char_p> *) flag_instrument_functions_exclude_files;
16427 if (v && v->length () > 0)
16429 const char *name;
16430 int i;
16431 char *s;
16433 name = DECL_SOURCE_FILE (fndecl);
16434 FOR_EACH_VEC_ELT (*v, i, s)
16435 if (strstr (name, s) != NULL)
16436 return true;
16439 return false;
16442 /* Entry point to the gimplification pass. FNDECL is the FUNCTION_DECL
16443 node for the function we want to gimplify.
16445 Return the sequence of GIMPLE statements corresponding to the body
16446 of FNDECL. */
16448 void
16449 gimplify_function_tree (tree fndecl)
16451 gimple_seq seq;
16452 gbind *bind;
16454 gcc_assert (!gimple_body (fndecl));
16456 if (DECL_STRUCT_FUNCTION (fndecl))
16457 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
16458 else
16459 push_struct_function (fndecl);
16461 /* Tentatively set PROP_gimple_lva here, and reset it in gimplify_va_arg_expr
16462 if necessary. */
16463 cfun->curr_properties |= PROP_gimple_lva;
16465 if (asan_sanitize_use_after_scope ())
16466 asan_poisoned_variables = new hash_set<tree> ();
16467 bind = gimplify_body (fndecl, true);
16468 if (asan_poisoned_variables)
16470 delete asan_poisoned_variables;
16471 asan_poisoned_variables = NULL;
16474 /* The tree body of the function is no longer needed, replace it
16475 with the new GIMPLE body. */
16476 seq = NULL;
16477 gimple_seq_add_stmt (&seq, bind);
16478 gimple_set_body (fndecl, seq);
16480 /* If we're instrumenting function entry/exit, then prepend the call to
16481 the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to
16482 catch the exit hook. */
16483 /* ??? Add some way to ignore exceptions for this TFE. */
16484 if (flag_instrument_function_entry_exit
16485 && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl)
16486 /* Do not instrument extern inline functions. */
16487 && !(DECL_DECLARED_INLINE_P (fndecl)
16488 && DECL_EXTERNAL (fndecl)
16489 && DECL_DISREGARD_INLINE_LIMITS (fndecl))
16490 && !flag_instrument_functions_exclude_p (fndecl))
16492 tree x;
16493 gbind *new_bind;
16494 gimple *tf;
16495 gimple_seq cleanup = NULL, body = NULL;
16496 tree tmp_var, this_fn_addr;
16497 gcall *call;
16499 /* The instrumentation hooks aren't going to call the instrumented
16500 function and the address they receive is expected to be matchable
16501 against symbol addresses. Make sure we don't create a trampoline,
16502 in case the current function is nested. */
16503 this_fn_addr = build_fold_addr_expr (current_function_decl);
16504 TREE_NO_TRAMPOLINE (this_fn_addr) = 1;
16506 x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
16507 call = gimple_build_call (x, 1, integer_zero_node);
16508 tmp_var = create_tmp_var (ptr_type_node, "return_addr");
16509 gimple_call_set_lhs (call, tmp_var);
16510 gimplify_seq_add_stmt (&cleanup, call);
16511 x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_EXIT);
16512 call = gimple_build_call (x, 2, this_fn_addr, tmp_var);
16513 gimplify_seq_add_stmt (&cleanup, call);
16514 tf = gimple_build_try (seq, cleanup, GIMPLE_TRY_FINALLY);
16516 x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
16517 call = gimple_build_call (x, 1, integer_zero_node);
16518 tmp_var = create_tmp_var (ptr_type_node, "return_addr");
16519 gimple_call_set_lhs (call, tmp_var);
16520 gimplify_seq_add_stmt (&body, call);
16521 x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_ENTER);
16522 call = gimple_build_call (x, 2, this_fn_addr, tmp_var);
16523 gimplify_seq_add_stmt (&body, call);
16524 gimplify_seq_add_stmt (&body, tf);
16525 new_bind = gimple_build_bind (NULL, body, NULL);
16527 /* Replace the current function body with the body
16528 wrapped in the try/finally TF. */
16529 seq = NULL;
16530 gimple_seq_add_stmt (&seq, new_bind);
16531 gimple_set_body (fndecl, seq);
16532 bind = new_bind;
16535 if (sanitize_flags_p (SANITIZE_THREAD)
16536 && param_tsan_instrument_func_entry_exit)
16538 gcall *call = gimple_build_call_internal (IFN_TSAN_FUNC_EXIT, 0);
16539 gimple *tf = gimple_build_try (seq, call, GIMPLE_TRY_FINALLY);
16540 gbind *new_bind = gimple_build_bind (NULL, tf, NULL);
16541 /* Replace the current function body with the body
16542 wrapped in the try/finally TF. */
16543 seq = NULL;
16544 gimple_seq_add_stmt (&seq, new_bind);
16545 gimple_set_body (fndecl, seq);
16548 DECL_SAVED_TREE (fndecl) = NULL_TREE;
16549 cfun->curr_properties |= PROP_gimple_any;
16551 pop_cfun ();
16553 dump_function (TDI_gimple, fndecl);
16556 /* Return a dummy expression of type TYPE in order to keep going after an
16557 error. */
16559 static tree
16560 dummy_object (tree type)
16562 tree t = build_int_cst (build_pointer_type (type), 0);
16563 return build2 (MEM_REF, type, t, t);
16566 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
16567 builtin function, but a very special sort of operator. */
16569 enum gimplify_status
16570 gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p,
16571 gimple_seq *post_p ATTRIBUTE_UNUSED)
16573 tree promoted_type, have_va_type;
16574 tree valist = TREE_OPERAND (*expr_p, 0);
16575 tree type = TREE_TYPE (*expr_p);
16576 tree t, tag, aptag;
16577 location_t loc = EXPR_LOCATION (*expr_p);
16579 /* Verify that valist is of the proper type. */
16580 have_va_type = TREE_TYPE (valist);
16581 if (have_va_type == error_mark_node)
16582 return GS_ERROR;
16583 have_va_type = targetm.canonical_va_list_type (have_va_type);
16584 if (have_va_type == NULL_TREE
16585 && POINTER_TYPE_P (TREE_TYPE (valist)))
16586 /* Handle 'Case 1: Not an array type' from c-common.cc/build_va_arg. */
16587 have_va_type
16588 = targetm.canonical_va_list_type (TREE_TYPE (TREE_TYPE (valist)));
16589 gcc_assert (have_va_type != NULL_TREE);
16591 /* Generate a diagnostic for requesting data of a type that cannot
16592 be passed through `...' due to type promotion at the call site. */
16593 if ((promoted_type = lang_hooks.types.type_promotes_to (type))
16594 != type)
16596 static bool gave_help;
16597 bool warned;
16598 /* Use the expansion point to handle cases such as passing bool (defined
16599 in a system header) through `...'. */
16600 location_t xloc
16601 = expansion_point_location_if_in_system_header (loc);
16603 /* Unfortunately, this is merely undefined, rather than a constraint
16604 violation, so we cannot make this an error. If this call is never
16605 executed, the program is still strictly conforming. */
16606 auto_diagnostic_group d;
16607 warned = warning_at (xloc, 0,
16608 "%qT is promoted to %qT when passed through %<...%>",
16609 type, promoted_type);
16610 if (!gave_help && warned)
16612 gave_help = true;
16613 inform (xloc, "(so you should pass %qT not %qT to %<va_arg%>)",
16614 promoted_type, type);
16617 /* We can, however, treat "undefined" any way we please.
16618 Call abort to encourage the user to fix the program. */
16619 if (warned)
16620 inform (xloc, "if this code is reached, the program will abort");
16621 /* Before the abort, allow the evaluation of the va_list
16622 expression to exit or longjmp. */
16623 gimplify_and_add (valist, pre_p);
16624 t = build_call_expr_loc (loc,
16625 builtin_decl_implicit (BUILT_IN_TRAP), 0);
16626 gimplify_and_add (t, pre_p);
16628 /* This is dead code, but go ahead and finish so that the
16629 mode of the result comes out right. */
16630 *expr_p = dummy_object (type);
16631 return GS_ALL_DONE;
16634 tag = build_int_cst (build_pointer_type (type), 0);
16635 aptag = build_int_cst (TREE_TYPE (valist), 0);
16637 *expr_p = build_call_expr_internal_loc (loc, IFN_VA_ARG, type, 3,
16638 valist, tag, aptag);
16640 /* Clear the tentatively set PROP_gimple_lva, to indicate that IFN_VA_ARG
16641 needs to be expanded. */
16642 cfun->curr_properties &= ~PROP_gimple_lva;
16644 return GS_OK;
16647 /* Build a new GIMPLE_ASSIGN tuple and append it to the end of *SEQ_P.
16649 DST/SRC are the destination and source respectively. You can pass
16650 ungimplified trees in DST or SRC, in which case they will be
16651 converted to a gimple operand if necessary.
16653 This function returns the newly created GIMPLE_ASSIGN tuple. */
16655 gimple *
16656 gimplify_assign (tree dst, tree src, gimple_seq *seq_p)
16658 tree t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
16659 gimplify_and_add (t, seq_p);
16660 ggc_free (t);
16661 return gimple_seq_last_stmt (*seq_p);
16664 inline hashval_t
16665 gimplify_hasher::hash (const elt_t *p)
16667 tree t = p->val;
16668 return iterative_hash_expr (t, 0);
16671 inline bool
16672 gimplify_hasher::equal (const elt_t *p1, const elt_t *p2)
16674 tree t1 = p1->val;
16675 tree t2 = p2->val;
16676 enum tree_code code = TREE_CODE (t1);
16678 if (TREE_CODE (t2) != code
16679 || TREE_TYPE (t1) != TREE_TYPE (t2))
16680 return false;
16682 if (!operand_equal_p (t1, t2, 0))
16683 return false;
16685 /* Only allow them to compare equal if they also hash equal; otherwise
16686 results are nondeterminate, and we fail bootstrap comparison. */
16687 gcc_checking_assert (hash (p1) == hash (p2));
16689 return true;