c, c++: attribute format on a ctor with a vbase [PR101833, PR47634]
[official-gcc.git] / gcc / gimplify.cc
blob822e0cfbf220d0914be2c94773e81474f8949f7e
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 labels that may fall through into LABELS and return the statement
2254 preceding another case label, or a user-defined label. Store a location
2255 useful 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 /* A dead label can't fall through. */
2335 if (!UNUSED_LABEL_P (false_lab))
2337 struct label_entry l = { false_lab, if_loc };
2338 labels->safe_push (l);
2341 /* Go to the last statement of the then branch. */
2342 gsi_prev (gsi_p);
2344 /* if (i != 0) goto <D.1759>; else goto <D.1760>;
2345 <D.1759>:
2346 <stmt>;
2347 goto <D.1761>;
2348 <D.1760>:
2350 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_GOTO
2351 && !gimple_has_location (gsi_stmt (*gsi_p)))
2353 /* Look at the statement before, it might be
2354 attribute fallthrough, in which case don't warn. */
2355 gsi_prev (gsi_p);
2356 bool fallthru_before_dest
2357 = gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_FALLTHROUGH);
2358 gsi_next (gsi_p);
2359 tree goto_dest = gimple_goto_dest (gsi_stmt (*gsi_p));
2360 if (!fallthru_before_dest)
2362 struct label_entry l = { goto_dest, if_loc };
2363 labels->safe_push (l);
2366 /* This case is about
2367 if (1 != 0) goto <D.2022>; else goto <D.2023>;
2368 <D.2022>:
2369 n = n + 1; // #1
2370 <D.2023>: // #2
2371 <D.1988>: // #3
2372 where #2 is UNUSED_LABEL_P and we want to warn about #1 falling
2373 through to #3. So set PREV to #1. */
2374 else if (UNUSED_LABEL_P (false_lab))
2375 prev = gsi_stmt (*gsi_p);
2377 /* And move back. */
2378 gsi_next (gsi_p);
2381 /* Remember the last statement. Skip labels that are of no interest
2382 to us. */
2383 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
2385 tree label = gimple_label_label (as_a <glabel *> (gsi_stmt (*gsi_p)));
2386 if (find_label_entry (labels, label))
2387 prev = gsi_stmt (*gsi_p);
2389 else if (gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_ASAN_MARK))
2391 else if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_PREDICT)
2393 else if (!is_gimple_debug (gsi_stmt (*gsi_p)))
2394 prev = gsi_stmt (*gsi_p);
2395 gsi_next (gsi_p);
2397 while (!gsi_end_p (*gsi_p)
2398 /* Stop if we find a case or a user-defined label. */
2399 && (gimple_code (gsi_stmt (*gsi_p)) != GIMPLE_LABEL
2400 || !gimple_has_location (gsi_stmt (*gsi_p))));
2402 if (prev && gimple_has_location (prev))
2403 *prevloc = gimple_location (prev);
2404 return prev;
2407 /* Return true if the switch fallthough warning should occur. LABEL is
2408 the label statement that we're falling through to. */
2410 static bool
2411 should_warn_for_implicit_fallthrough (gimple_stmt_iterator *gsi_p, tree label)
2413 gimple_stmt_iterator gsi = *gsi_p;
2415 /* Don't warn if the label is marked with a "falls through" comment. */
2416 if (FALLTHROUGH_LABEL_P (label))
2417 return false;
2419 /* Don't warn for non-case labels followed by a statement:
2420 case 0:
2421 foo ();
2422 label:
2423 bar ();
2424 as these are likely intentional. */
2425 if (!case_label_p (&gimplify_ctxp->case_labels, label))
2427 tree l;
2428 while (!gsi_end_p (gsi)
2429 && gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
2430 && (l = gimple_label_label (as_a <glabel *> (gsi_stmt (gsi))))
2431 && !case_label_p (&gimplify_ctxp->case_labels, l))
2432 gsi_next_nondebug (&gsi);
2433 if (gsi_end_p (gsi) || gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL)
2434 return false;
2437 /* Don't warn for terminated branches, i.e. when the subsequent case labels
2438 immediately breaks. */
2439 gsi = *gsi_p;
2441 /* Skip all immediately following labels. */
2442 while (!gsi_end_p (gsi)
2443 && (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
2444 || gimple_code (gsi_stmt (gsi)) == GIMPLE_PREDICT))
2445 gsi_next_nondebug (&gsi);
2447 /* { ... something; default:; } */
2448 if (gsi_end_p (gsi)
2449 /* { ... something; default: break; } or
2450 { ... something; default: goto L; } */
2451 || gimple_code (gsi_stmt (gsi)) == GIMPLE_GOTO
2452 /* { ... something; default: return; } */
2453 || gimple_code (gsi_stmt (gsi)) == GIMPLE_RETURN)
2454 return false;
2456 return true;
2459 /* Callback for walk_gimple_seq. */
2461 static tree
2462 warn_implicit_fallthrough_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
2463 struct walk_stmt_info *)
2465 gimple *stmt = gsi_stmt (*gsi_p);
2467 *handled_ops_p = true;
2468 switch (gimple_code (stmt))
2470 case GIMPLE_TRY:
2471 case GIMPLE_BIND:
2472 case GIMPLE_CATCH:
2473 case GIMPLE_EH_FILTER:
2474 case GIMPLE_TRANSACTION:
2475 /* Walk the sub-statements. */
2476 *handled_ops_p = false;
2477 break;
2479 /* Find a sequence of form:
2481 GIMPLE_LABEL
2482 [...]
2483 <may fallthru stmt>
2484 GIMPLE_LABEL
2486 and possibly warn. */
2487 case GIMPLE_LABEL:
2489 /* Found a label. Skip all immediately following labels. */
2490 while (!gsi_end_p (*gsi_p)
2491 && gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
2492 gsi_next_nondebug (gsi_p);
2494 /* There might be no more statements. */
2495 if (gsi_end_p (*gsi_p))
2496 return integer_zero_node;
2498 /* Vector of labels that fall through. */
2499 auto_vec <struct label_entry> labels;
2500 location_t prevloc;
2501 gimple *prev = collect_fallthrough_labels (gsi_p, &labels, &prevloc);
2503 /* There might be no more statements. */
2504 if (gsi_end_p (*gsi_p))
2505 return integer_zero_node;
2507 gimple *next = gsi_stmt (*gsi_p);
2508 tree label;
2509 /* If what follows is a label, then we may have a fallthrough. */
2510 if (gimple_code (next) == GIMPLE_LABEL
2511 && gimple_has_location (next)
2512 && (label = gimple_label_label (as_a <glabel *> (next)))
2513 && prev != NULL)
2515 struct label_entry *l;
2516 bool warned_p = false;
2517 auto_diagnostic_group d;
2518 if (!should_warn_for_implicit_fallthrough (gsi_p, label))
2519 /* Quiet. */;
2520 else if (gimple_code (prev) == GIMPLE_LABEL
2521 && (label = gimple_label_label (as_a <glabel *> (prev)))
2522 && (l = find_label_entry (&labels, label)))
2523 warned_p = warning_at (l->loc, OPT_Wimplicit_fallthrough_,
2524 "this statement may fall through");
2525 else if (!gimple_call_internal_p (prev, IFN_FALLTHROUGH)
2526 /* Try to be clever and don't warn when the statement
2527 can't actually fall through. */
2528 && gimple_stmt_may_fallthru (prev)
2529 && prevloc != UNKNOWN_LOCATION)
2530 warned_p = warning_at (prevloc,
2531 OPT_Wimplicit_fallthrough_,
2532 "this statement may fall through");
2533 if (warned_p)
2534 inform (gimple_location (next), "here");
2536 /* Mark this label as processed so as to prevent multiple
2537 warnings in nested switches. */
2538 FALLTHROUGH_LABEL_P (label) = true;
2540 /* So that next warn_implicit_fallthrough_r will start looking for
2541 a new sequence starting with this label. */
2542 gsi_prev (gsi_p);
2545 break;
2546 default:
2547 break;
2549 return NULL_TREE;
2552 /* Warn when a switch case falls through. */
2554 static void
2555 maybe_warn_implicit_fallthrough (gimple_seq seq)
2557 if (!warn_implicit_fallthrough)
2558 return;
2560 /* This warning is meant for C/C++/ObjC/ObjC++ only. */
2561 if (!(lang_GNU_C ()
2562 || lang_GNU_CXX ()
2563 || lang_GNU_OBJC ()))
2564 return;
2566 struct walk_stmt_info wi;
2567 memset (&wi, 0, sizeof (wi));
2568 walk_gimple_seq (seq, warn_implicit_fallthrough_r, NULL, &wi);
2571 /* Callback for walk_gimple_seq. */
2573 static tree
2574 expand_FALLTHROUGH_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
2575 struct walk_stmt_info *wi)
2577 gimple *stmt = gsi_stmt (*gsi_p);
2579 *handled_ops_p = true;
2580 switch (gimple_code (stmt))
2582 case GIMPLE_TRY:
2583 case GIMPLE_BIND:
2584 case GIMPLE_CATCH:
2585 case GIMPLE_EH_FILTER:
2586 case GIMPLE_TRANSACTION:
2587 /* Walk the sub-statements. */
2588 *handled_ops_p = false;
2589 break;
2590 case GIMPLE_CALL:
2591 if (gimple_call_internal_p (stmt, IFN_FALLTHROUGH))
2593 gsi_remove (gsi_p, true);
2594 if (gsi_end_p (*gsi_p))
2596 *static_cast<location_t *>(wi->info) = gimple_location (stmt);
2597 return integer_zero_node;
2600 bool found = false;
2601 location_t loc = gimple_location (stmt);
2603 gimple_stmt_iterator gsi2 = *gsi_p;
2604 stmt = gsi_stmt (gsi2);
2605 if (gimple_code (stmt) == GIMPLE_GOTO && !gimple_has_location (stmt))
2607 /* Go on until the artificial label. */
2608 tree goto_dest = gimple_goto_dest (stmt);
2609 for (; !gsi_end_p (gsi2); gsi_next (&gsi2))
2611 if (gimple_code (gsi_stmt (gsi2)) == GIMPLE_LABEL
2612 && gimple_label_label (as_a <glabel *> (gsi_stmt (gsi2)))
2613 == goto_dest)
2614 break;
2617 /* Not found? Stop. */
2618 if (gsi_end_p (gsi2))
2619 break;
2621 /* Look one past it. */
2622 gsi_next (&gsi2);
2625 /* We're looking for a case label or default label here. */
2626 while (!gsi_end_p (gsi2))
2628 stmt = gsi_stmt (gsi2);
2629 if (gimple_code (stmt) == GIMPLE_LABEL)
2631 tree label = gimple_label_label (as_a <glabel *> (stmt));
2632 if (gimple_has_location (stmt) && DECL_ARTIFICIAL (label))
2634 found = true;
2635 break;
2638 else if (gimple_call_internal_p (stmt, IFN_ASAN_MARK))
2640 else if (!is_gimple_debug (stmt))
2641 /* Anything else is not expected. */
2642 break;
2643 gsi_next (&gsi2);
2645 if (!found)
2646 pedwarn (loc, 0, "attribute %<fallthrough%> not preceding "
2647 "a case label or default label");
2649 break;
2650 default:
2651 break;
2653 return NULL_TREE;
2656 /* Expand all FALLTHROUGH () calls in SEQ. */
2658 static void
2659 expand_FALLTHROUGH (gimple_seq *seq_p)
2661 struct walk_stmt_info wi;
2662 location_t loc;
2663 memset (&wi, 0, sizeof (wi));
2664 wi.info = (void *) &loc;
2665 walk_gimple_seq_mod (seq_p, expand_FALLTHROUGH_r, NULL, &wi);
2666 if (wi.callback_result == integer_zero_node)
2667 /* We've found [[fallthrough]]; at the end of a switch, which the C++
2668 standard says is ill-formed; see [dcl.attr.fallthrough]. */
2669 pedwarn (loc, 0, "attribute %<fallthrough%> not preceding "
2670 "a case label or default label");
2674 /* Gimplify a SWITCH_EXPR, and collect the vector of labels it can
2675 branch to. */
2677 static enum gimplify_status
2678 gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p)
2680 tree switch_expr = *expr_p;
2681 gimple_seq switch_body_seq = NULL;
2682 enum gimplify_status ret;
2683 tree index_type = TREE_TYPE (switch_expr);
2684 if (index_type == NULL_TREE)
2685 index_type = TREE_TYPE (SWITCH_COND (switch_expr));
2687 ret = gimplify_expr (&SWITCH_COND (switch_expr), pre_p, NULL, is_gimple_val,
2688 fb_rvalue);
2689 if (ret == GS_ERROR || ret == GS_UNHANDLED)
2690 return ret;
2692 if (SWITCH_BODY (switch_expr))
2694 vec<tree> labels;
2695 vec<tree> saved_labels;
2696 hash_set<tree> *saved_live_switch_vars = NULL;
2697 tree default_case = NULL_TREE;
2698 gswitch *switch_stmt;
2700 /* Save old labels, get new ones from body, then restore the old
2701 labels. Save all the things from the switch body to append after. */
2702 saved_labels = gimplify_ctxp->case_labels;
2703 gimplify_ctxp->case_labels.create (8);
2705 /* Do not create live_switch_vars if SWITCH_BODY is not a BIND_EXPR. */
2706 saved_live_switch_vars = gimplify_ctxp->live_switch_vars;
2707 tree_code body_type = TREE_CODE (SWITCH_BODY (switch_expr));
2708 if (body_type == BIND_EXPR || body_type == STATEMENT_LIST)
2709 gimplify_ctxp->live_switch_vars = new hash_set<tree> (4);
2710 else
2711 gimplify_ctxp->live_switch_vars = NULL;
2713 bool old_in_switch_expr = gimplify_ctxp->in_switch_expr;
2714 gimplify_ctxp->in_switch_expr = true;
2716 gimplify_stmt (&SWITCH_BODY (switch_expr), &switch_body_seq);
2718 gimplify_ctxp->in_switch_expr = old_in_switch_expr;
2719 maybe_warn_switch_unreachable_and_auto_init (switch_body_seq);
2720 maybe_warn_implicit_fallthrough (switch_body_seq);
2721 /* Only do this for the outermost GIMPLE_SWITCH. */
2722 if (!gimplify_ctxp->in_switch_expr)
2723 expand_FALLTHROUGH (&switch_body_seq);
2725 labels = gimplify_ctxp->case_labels;
2726 gimplify_ctxp->case_labels = saved_labels;
2728 if (gimplify_ctxp->live_switch_vars)
2730 gcc_assert (gimplify_ctxp->live_switch_vars->is_empty ());
2731 delete gimplify_ctxp->live_switch_vars;
2733 gimplify_ctxp->live_switch_vars = saved_live_switch_vars;
2735 preprocess_case_label_vec_for_gimple (labels, index_type,
2736 &default_case);
2738 bool add_bind = false;
2739 if (!default_case)
2741 glabel *new_default;
2743 default_case
2744 = build_case_label (NULL_TREE, NULL_TREE,
2745 create_artificial_label (UNKNOWN_LOCATION));
2746 if (old_in_switch_expr)
2748 SWITCH_BREAK_LABEL_P (CASE_LABEL (default_case)) = 1;
2749 add_bind = true;
2751 new_default = gimple_build_label (CASE_LABEL (default_case));
2752 gimplify_seq_add_stmt (&switch_body_seq, new_default);
2754 else if (old_in_switch_expr)
2756 gimple *last = gimple_seq_last_stmt (switch_body_seq);
2757 if (last && gimple_code (last) == GIMPLE_LABEL)
2759 tree label = gimple_label_label (as_a <glabel *> (last));
2760 if (SWITCH_BREAK_LABEL_P (label))
2761 add_bind = true;
2765 switch_stmt = gimple_build_switch (SWITCH_COND (switch_expr),
2766 default_case, labels);
2767 /* For the benefit of -Wimplicit-fallthrough, if switch_body_seq
2768 ends with a GIMPLE_LABEL holding SWITCH_BREAK_LABEL_P LABEL_DECL,
2769 wrap the GIMPLE_SWITCH up to that GIMPLE_LABEL into a GIMPLE_BIND,
2770 so that we can easily find the start and end of the switch
2771 statement. */
2772 if (add_bind)
2774 gimple_seq bind_body = NULL;
2775 gimplify_seq_add_stmt (&bind_body, switch_stmt);
2776 gimple_seq_add_seq (&bind_body, switch_body_seq);
2777 gbind *bind = gimple_build_bind (NULL_TREE, bind_body, NULL_TREE);
2778 gimple_set_location (bind, EXPR_LOCATION (switch_expr));
2779 gimplify_seq_add_stmt (pre_p, bind);
2781 else
2783 gimplify_seq_add_stmt (pre_p, switch_stmt);
2784 gimplify_seq_add_seq (pre_p, switch_body_seq);
2786 labels.release ();
2788 else
2789 gcc_unreachable ();
2791 return GS_ALL_DONE;
2794 /* Gimplify the LABEL_EXPR pointed to by EXPR_P. */
2796 static enum gimplify_status
2797 gimplify_label_expr (tree *expr_p, gimple_seq *pre_p)
2799 gcc_assert (decl_function_context (LABEL_EXPR_LABEL (*expr_p))
2800 == current_function_decl);
2802 tree label = LABEL_EXPR_LABEL (*expr_p);
2803 glabel *label_stmt = gimple_build_label (label);
2804 gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
2805 gimplify_seq_add_stmt (pre_p, label_stmt);
2807 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label)))
2808 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_COLD_LABEL,
2809 NOT_TAKEN));
2810 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label)))
2811 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_HOT_LABEL,
2812 TAKEN));
2814 return GS_ALL_DONE;
2817 /* Gimplify the CASE_LABEL_EXPR pointed to by EXPR_P. */
2819 static enum gimplify_status
2820 gimplify_case_label_expr (tree *expr_p, gimple_seq *pre_p)
2822 struct gimplify_ctx *ctxp;
2823 glabel *label_stmt;
2825 /* Invalid programs can play Duff's Device type games with, for example,
2826 #pragma omp parallel. At least in the C front end, we don't
2827 detect such invalid branches until after gimplification, in the
2828 diagnose_omp_blocks pass. */
2829 for (ctxp = gimplify_ctxp; ; ctxp = ctxp->prev_context)
2830 if (ctxp->case_labels.exists ())
2831 break;
2833 tree label = CASE_LABEL (*expr_p);
2834 label_stmt = gimple_build_label (label);
2835 gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
2836 ctxp->case_labels.safe_push (*expr_p);
2837 gimplify_seq_add_stmt (pre_p, label_stmt);
2839 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label)))
2840 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_COLD_LABEL,
2841 NOT_TAKEN));
2842 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label)))
2843 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_HOT_LABEL,
2844 TAKEN));
2846 return GS_ALL_DONE;
2849 /* Build a GOTO to the LABEL_DECL pointed to by LABEL_P, building it first
2850 if necessary. */
2852 tree
2853 build_and_jump (tree *label_p)
2855 if (label_p == NULL)
2856 /* If there's nowhere to jump, just fall through. */
2857 return NULL_TREE;
2859 if (*label_p == NULL_TREE)
2861 tree label = create_artificial_label (UNKNOWN_LOCATION);
2862 *label_p = label;
2865 return build1 (GOTO_EXPR, void_type_node, *label_p);
2868 /* Gimplify an EXIT_EXPR by converting to a GOTO_EXPR inside a COND_EXPR.
2869 This also involves building a label to jump to and communicating it to
2870 gimplify_loop_expr through gimplify_ctxp->exit_label. */
2872 static enum gimplify_status
2873 gimplify_exit_expr (tree *expr_p)
2875 tree cond = TREE_OPERAND (*expr_p, 0);
2876 tree expr;
2878 expr = build_and_jump (&gimplify_ctxp->exit_label);
2879 expr = build3 (COND_EXPR, void_type_node, cond, expr, NULL_TREE);
2880 *expr_p = expr;
2882 return GS_OK;
2885 /* *EXPR_P is a COMPONENT_REF being used as an rvalue. If its type is
2886 different from its canonical type, wrap the whole thing inside a
2887 NOP_EXPR and force the type of the COMPONENT_REF to be the canonical
2888 type.
2890 The canonical type of a COMPONENT_REF is the type of the field being
2891 referenced--unless the field is a bit-field which can be read directly
2892 in a smaller mode, in which case the canonical type is the
2893 sign-appropriate type corresponding to that mode. */
2895 static void
2896 canonicalize_component_ref (tree *expr_p)
2898 tree expr = *expr_p;
2899 tree type;
2901 gcc_assert (TREE_CODE (expr) == COMPONENT_REF);
2903 if (INTEGRAL_TYPE_P (TREE_TYPE (expr)))
2904 type = TREE_TYPE (get_unwidened (expr, NULL_TREE));
2905 else
2906 type = TREE_TYPE (TREE_OPERAND (expr, 1));
2908 /* One could argue that all the stuff below is not necessary for
2909 the non-bitfield case and declare it a FE error if type
2910 adjustment would be needed. */
2911 if (TREE_TYPE (expr) != type)
2913 #ifdef ENABLE_TYPES_CHECKING
2914 tree old_type = TREE_TYPE (expr);
2915 #endif
2916 int type_quals;
2918 /* We need to preserve qualifiers and propagate them from
2919 operand 0. */
2920 type_quals = TYPE_QUALS (type)
2921 | TYPE_QUALS (TREE_TYPE (TREE_OPERAND (expr, 0)));
2922 if (TYPE_QUALS (type) != type_quals)
2923 type = build_qualified_type (TYPE_MAIN_VARIANT (type), type_quals);
2925 /* Set the type of the COMPONENT_REF to the underlying type. */
2926 TREE_TYPE (expr) = type;
2928 #ifdef ENABLE_TYPES_CHECKING
2929 /* It is now a FE error, if the conversion from the canonical
2930 type to the original expression type is not useless. */
2931 gcc_assert (useless_type_conversion_p (old_type, type));
2932 #endif
2936 /* If a NOP conversion is changing a pointer to array of foo to a pointer
2937 to foo, embed that change in the ADDR_EXPR by converting
2938 T array[U];
2939 (T *)&array
2941 &array[L]
2942 where L is the lower bound. For simplicity, only do this for constant
2943 lower bound.
2944 The constraint is that the type of &array[L] is trivially convertible
2945 to T *. */
2947 static void
2948 canonicalize_addr_expr (tree *expr_p)
2950 tree expr = *expr_p;
2951 tree addr_expr = TREE_OPERAND (expr, 0);
2952 tree datype, ddatype, pddatype;
2954 /* We simplify only conversions from an ADDR_EXPR to a pointer type. */
2955 if (!POINTER_TYPE_P (TREE_TYPE (expr))
2956 || TREE_CODE (addr_expr) != ADDR_EXPR)
2957 return;
2959 /* The addr_expr type should be a pointer to an array. */
2960 datype = TREE_TYPE (TREE_TYPE (addr_expr));
2961 if (TREE_CODE (datype) != ARRAY_TYPE)
2962 return;
2964 /* The pointer to element type shall be trivially convertible to
2965 the expression pointer type. */
2966 ddatype = TREE_TYPE (datype);
2967 pddatype = build_pointer_type (ddatype);
2968 if (!useless_type_conversion_p (TYPE_MAIN_VARIANT (TREE_TYPE (expr)),
2969 pddatype))
2970 return;
2972 /* The lower bound and element sizes must be constant. */
2973 if (!TYPE_SIZE_UNIT (ddatype)
2974 || TREE_CODE (TYPE_SIZE_UNIT (ddatype)) != INTEGER_CST
2975 || !TYPE_DOMAIN (datype) || !TYPE_MIN_VALUE (TYPE_DOMAIN (datype))
2976 || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (datype))) != INTEGER_CST)
2977 return;
2979 /* All checks succeeded. Build a new node to merge the cast. */
2980 *expr_p = build4 (ARRAY_REF, ddatype, TREE_OPERAND (addr_expr, 0),
2981 TYPE_MIN_VALUE (TYPE_DOMAIN (datype)),
2982 NULL_TREE, NULL_TREE);
2983 *expr_p = build1 (ADDR_EXPR, pddatype, *expr_p);
2985 /* We can have stripped a required restrict qualifier above. */
2986 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
2987 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
2990 /* *EXPR_P is a NOP_EXPR or CONVERT_EXPR. Remove it and/or other conversions
2991 underneath as appropriate. */
2993 static enum gimplify_status
2994 gimplify_conversion (tree *expr_p)
2996 location_t loc = EXPR_LOCATION (*expr_p);
2997 gcc_assert (CONVERT_EXPR_P (*expr_p));
2999 /* Then strip away all but the outermost conversion. */
3000 STRIP_SIGN_NOPS (TREE_OPERAND (*expr_p, 0));
3002 /* And remove the outermost conversion if it's useless. */
3003 if (tree_ssa_useless_type_conversion (*expr_p))
3004 *expr_p = TREE_OPERAND (*expr_p, 0);
3006 /* If we still have a conversion at the toplevel,
3007 then canonicalize some constructs. */
3008 if (CONVERT_EXPR_P (*expr_p))
3010 tree sub = TREE_OPERAND (*expr_p, 0);
3012 /* If a NOP conversion is changing the type of a COMPONENT_REF
3013 expression, then canonicalize its type now in order to expose more
3014 redundant conversions. */
3015 if (TREE_CODE (sub) == COMPONENT_REF)
3016 canonicalize_component_ref (&TREE_OPERAND (*expr_p, 0));
3018 /* If a NOP conversion is changing a pointer to array of foo
3019 to a pointer to foo, embed that change in the ADDR_EXPR. */
3020 else if (TREE_CODE (sub) == ADDR_EXPR)
3021 canonicalize_addr_expr (expr_p);
3024 /* If we have a conversion to a non-register type force the
3025 use of a VIEW_CONVERT_EXPR instead. */
3026 if (CONVERT_EXPR_P (*expr_p) && !is_gimple_reg_type (TREE_TYPE (*expr_p)))
3027 *expr_p = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (*expr_p),
3028 TREE_OPERAND (*expr_p, 0));
3030 /* Canonicalize CONVERT_EXPR to NOP_EXPR. */
3031 if (TREE_CODE (*expr_p) == CONVERT_EXPR)
3032 TREE_SET_CODE (*expr_p, NOP_EXPR);
3034 return GS_OK;
3037 /* Gimplify a VAR_DECL or PARM_DECL. Return GS_OK if we expanded a
3038 DECL_VALUE_EXPR, and it's worth re-examining things. */
3040 static enum gimplify_status
3041 gimplify_var_or_parm_decl (tree *expr_p)
3043 tree decl = *expr_p;
3045 /* ??? If this is a local variable, and it has not been seen in any
3046 outer BIND_EXPR, then it's probably the result of a duplicate
3047 declaration, for which we've already issued an error. It would
3048 be really nice if the front end wouldn't leak these at all.
3049 Currently the only known culprit is C++ destructors, as seen
3050 in g++.old-deja/g++.jason/binding.C.
3051 Another possible culpit are size expressions for variably modified
3052 types which are lost in the FE or not gimplified correctly. */
3053 if (VAR_P (decl)
3054 && !DECL_SEEN_IN_BIND_EXPR_P (decl)
3055 && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl)
3056 && decl_function_context (decl) == current_function_decl)
3058 gcc_assert (seen_error ());
3059 return GS_ERROR;
3062 /* When within an OMP context, notice uses of variables. */
3063 if (gimplify_omp_ctxp && omp_notice_variable (gimplify_omp_ctxp, decl, true))
3064 return GS_ALL_DONE;
3066 /* If the decl is an alias for another expression, substitute it now. */
3067 if (DECL_HAS_VALUE_EXPR_P (decl))
3069 *expr_p = unshare_expr (DECL_VALUE_EXPR (decl));
3070 return GS_OK;
3073 return GS_ALL_DONE;
3076 /* Recalculate the value of the TREE_SIDE_EFFECTS flag for T. */
3078 static void
3079 recalculate_side_effects (tree t)
3081 enum tree_code code = TREE_CODE (t);
3082 int len = TREE_OPERAND_LENGTH (t);
3083 int i;
3085 switch (TREE_CODE_CLASS (code))
3087 case tcc_expression:
3088 switch (code)
3090 case INIT_EXPR:
3091 case MODIFY_EXPR:
3092 case VA_ARG_EXPR:
3093 case PREDECREMENT_EXPR:
3094 case PREINCREMENT_EXPR:
3095 case POSTDECREMENT_EXPR:
3096 case POSTINCREMENT_EXPR:
3097 /* All of these have side-effects, no matter what their
3098 operands are. */
3099 return;
3101 default:
3102 break;
3104 /* Fall through. */
3106 case tcc_comparison: /* a comparison expression */
3107 case tcc_unary: /* a unary arithmetic expression */
3108 case tcc_binary: /* a binary arithmetic expression */
3109 case tcc_reference: /* a reference */
3110 case tcc_vl_exp: /* a function call */
3111 TREE_SIDE_EFFECTS (t) = TREE_THIS_VOLATILE (t);
3112 for (i = 0; i < len; ++i)
3114 tree op = TREE_OPERAND (t, i);
3115 if (op && TREE_SIDE_EFFECTS (op))
3116 TREE_SIDE_EFFECTS (t) = 1;
3118 break;
3120 case tcc_constant:
3121 /* No side-effects. */
3122 return;
3124 default:
3125 gcc_unreachable ();
3129 /* Gimplify the COMPONENT_REF, ARRAY_REF, REALPART_EXPR or IMAGPART_EXPR
3130 node *EXPR_P.
3132 compound_lval
3133 : min_lval '[' val ']'
3134 | min_lval '.' ID
3135 | compound_lval '[' val ']'
3136 | compound_lval '.' ID
3138 This is not part of the original SIMPLE definition, which separates
3139 array and member references, but it seems reasonable to handle them
3140 together. Also, this way we don't run into problems with union
3141 aliasing; gcc requires that for accesses through a union to alias, the
3142 union reference must be explicit, which was not always the case when we
3143 were splitting up array and member refs.
3145 PRE_P points to the sequence where side effects that must happen before
3146 *EXPR_P should be stored.
3148 POST_P points to the sequence where side effects that must happen after
3149 *EXPR_P should be stored. */
3151 static enum gimplify_status
3152 gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
3153 fallback_t fallback)
3155 tree *p;
3156 enum gimplify_status ret = GS_ALL_DONE, tret;
3157 int i;
3158 location_t loc = EXPR_LOCATION (*expr_p);
3159 tree expr = *expr_p;
3161 /* Create a stack of the subexpressions so later we can walk them in
3162 order from inner to outer. */
3163 auto_vec<tree, 10> expr_stack;
3165 /* We can handle anything that get_inner_reference can deal with. */
3166 for (p = expr_p; ; p = &TREE_OPERAND (*p, 0))
3168 restart:
3169 /* Fold INDIRECT_REFs now to turn them into ARRAY_REFs. */
3170 if (TREE_CODE (*p) == INDIRECT_REF)
3171 *p = fold_indirect_ref_loc (loc, *p);
3173 if (handled_component_p (*p))
3175 /* Expand DECL_VALUE_EXPR now. In some cases that may expose
3176 additional COMPONENT_REFs. */
3177 else if ((VAR_P (*p) || TREE_CODE (*p) == PARM_DECL)
3178 && gimplify_var_or_parm_decl (p) == GS_OK)
3179 goto restart;
3180 else
3181 break;
3183 expr_stack.safe_push (*p);
3186 gcc_assert (expr_stack.length ());
3188 /* Now EXPR_STACK is a stack of pointers to all the refs we've
3189 walked through and P points to the innermost expression.
3191 Java requires that we elaborated nodes in source order. That
3192 means we must gimplify the inner expression followed by each of
3193 the indices, in order. But we can't gimplify the inner
3194 expression until we deal with any variable bounds, sizes, or
3195 positions in order to deal with PLACEHOLDER_EXPRs.
3197 The base expression may contain a statement expression that
3198 has declarations used in size expressions, so has to be
3199 gimplified before gimplifying the size expressions.
3201 So we do this in three steps. First we deal with variable
3202 bounds, sizes, and positions, then we gimplify the base and
3203 ensure it is memory if needed, then we deal with the annotations
3204 for any variables in the components and any indices, from left
3205 to right. */
3207 bool need_non_reg = false;
3208 for (i = expr_stack.length () - 1; i >= 0; i--)
3210 tree t = expr_stack[i];
3212 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
3214 /* Deal with the low bound and element type size and put them into
3215 the ARRAY_REF. If these values are set, they have already been
3216 gimplified. */
3217 if (TREE_OPERAND (t, 2) == NULL_TREE)
3219 tree low = unshare_expr (array_ref_low_bound (t));
3220 if (!is_gimple_min_invariant (low))
3222 TREE_OPERAND (t, 2) = low;
3226 if (TREE_OPERAND (t, 3) == NULL_TREE)
3228 tree elmt_size = array_ref_element_size (t);
3229 if (!is_gimple_min_invariant (elmt_size))
3231 elmt_size = unshare_expr (elmt_size);
3232 tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0)));
3233 tree factor = size_int (TYPE_ALIGN_UNIT (elmt_type));
3235 /* Divide the element size by the alignment of the element
3236 type (above). */
3237 elmt_size = size_binop_loc (loc, EXACT_DIV_EXPR,
3238 elmt_size, factor);
3240 TREE_OPERAND (t, 3) = elmt_size;
3243 need_non_reg = true;
3245 else if (TREE_CODE (t) == COMPONENT_REF)
3247 /* Set the field offset into T and gimplify it. */
3248 if (TREE_OPERAND (t, 2) == NULL_TREE)
3250 tree offset = component_ref_field_offset (t);
3251 if (!is_gimple_min_invariant (offset))
3253 offset = unshare_expr (offset);
3254 tree field = TREE_OPERAND (t, 1);
3255 tree factor
3256 = size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT);
3258 /* Divide the offset by its alignment. */
3259 offset = size_binop_loc (loc, EXACT_DIV_EXPR,
3260 offset, factor);
3262 TREE_OPERAND (t, 2) = offset;
3265 need_non_reg = true;
3269 /* Step 2 is to gimplify the base expression. Make sure lvalue is set
3270 so as to match the min_lval predicate. Failure to do so may result
3271 in the creation of large aggregate temporaries. */
3272 tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval,
3273 fallback | fb_lvalue);
3274 ret = MIN (ret, tret);
3276 /* Step 2a: if we have component references we do not support on
3277 registers then make sure the base isn't a register. Of course
3278 we can only do so if an rvalue is OK. */
3279 if (need_non_reg && (fallback & fb_rvalue))
3280 prepare_gimple_addressable (p, pre_p);
3282 /* Step 3: gimplify size expressions and the indices and operands of
3283 ARRAY_REF. During this loop we also remove any useless conversions. */
3285 for (; expr_stack.length () > 0; )
3287 tree t = expr_stack.pop ();
3289 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
3291 /* Gimplify the low bound and element type size. */
3292 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
3293 is_gimple_reg, fb_rvalue);
3294 ret = MIN (ret, tret);
3296 tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p, post_p,
3297 is_gimple_reg, fb_rvalue);
3298 ret = MIN (ret, tret);
3300 /* Gimplify the dimension. */
3301 tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
3302 is_gimple_val, fb_rvalue);
3303 ret = MIN (ret, tret);
3305 else if (TREE_CODE (t) == COMPONENT_REF)
3307 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
3308 is_gimple_reg, fb_rvalue);
3309 ret = MIN (ret, tret);
3312 STRIP_USELESS_TYPE_CONVERSION (TREE_OPERAND (t, 0));
3314 /* The innermost expression P may have originally had
3315 TREE_SIDE_EFFECTS set which would have caused all the outer
3316 expressions in *EXPR_P leading to P to also have had
3317 TREE_SIDE_EFFECTS set. */
3318 recalculate_side_effects (t);
3321 /* If the outermost expression is a COMPONENT_REF, canonicalize its type. */
3322 if ((fallback & fb_rvalue) && TREE_CODE (*expr_p) == COMPONENT_REF)
3324 canonicalize_component_ref (expr_p);
3327 expr_stack.release ();
3329 gcc_assert (*expr_p == expr || ret != GS_ALL_DONE);
3331 return ret;
3334 /* Gimplify the self modifying expression pointed to by EXPR_P
3335 (++, --, +=, -=).
3337 PRE_P points to the list where side effects that must happen before
3338 *EXPR_P should be stored.
3340 POST_P points to the list where side effects that must happen after
3341 *EXPR_P should be stored.
3343 WANT_VALUE is nonzero iff we want to use the value of this expression
3344 in another expression.
3346 ARITH_TYPE is the type the computation should be performed in. */
3348 enum gimplify_status
3349 gimplify_self_mod_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
3350 bool want_value, tree arith_type)
3352 enum tree_code code;
3353 tree lhs, lvalue, rhs, t1;
3354 gimple_seq post = NULL, *orig_post_p = post_p;
3355 bool postfix;
3356 enum tree_code arith_code;
3357 enum gimplify_status ret;
3358 location_t loc = EXPR_LOCATION (*expr_p);
3360 code = TREE_CODE (*expr_p);
3362 gcc_assert (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR
3363 || code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR);
3365 /* Prefix or postfix? */
3366 if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
3367 /* Faster to treat as prefix if result is not used. */
3368 postfix = want_value;
3369 else
3370 postfix = false;
3372 /* For postfix, make sure the inner expression's post side effects
3373 are executed after side effects from this expression. */
3374 if (postfix)
3375 post_p = &post;
3377 /* Add or subtract? */
3378 if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
3379 arith_code = PLUS_EXPR;
3380 else
3381 arith_code = MINUS_EXPR;
3383 /* Gimplify the LHS into a GIMPLE lvalue. */
3384 lvalue = TREE_OPERAND (*expr_p, 0);
3385 ret = gimplify_expr (&lvalue, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
3386 if (ret == GS_ERROR)
3387 return ret;
3389 /* Extract the operands to the arithmetic operation. */
3390 lhs = lvalue;
3391 rhs = TREE_OPERAND (*expr_p, 1);
3393 /* For postfix operator, we evaluate the LHS to an rvalue and then use
3394 that as the result value and in the postqueue operation. */
3395 if (postfix)
3397 ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue);
3398 if (ret == GS_ERROR)
3399 return ret;
3401 lhs = get_initialized_tmp_var (lhs, pre_p);
3404 /* For POINTERs increment, use POINTER_PLUS_EXPR. */
3405 if (POINTER_TYPE_P (TREE_TYPE (lhs)))
3407 rhs = convert_to_ptrofftype_loc (loc, rhs);
3408 if (arith_code == MINUS_EXPR)
3409 rhs = fold_build1_loc (loc, NEGATE_EXPR, TREE_TYPE (rhs), rhs);
3410 t1 = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (*expr_p), lhs, rhs);
3412 else
3413 t1 = fold_convert (TREE_TYPE (*expr_p),
3414 fold_build2 (arith_code, arith_type,
3415 fold_convert (arith_type, lhs),
3416 fold_convert (arith_type, rhs)));
3418 if (postfix)
3420 gimplify_assign (lvalue, t1, pre_p);
3421 gimplify_seq_add_seq (orig_post_p, post);
3422 *expr_p = lhs;
3423 return GS_ALL_DONE;
3425 else
3427 *expr_p = build2 (MODIFY_EXPR, TREE_TYPE (lvalue), lvalue, t1);
3428 return GS_OK;
3432 /* If *EXPR_P has a variable sized type, wrap it in a WITH_SIZE_EXPR. */
3434 static void
3435 maybe_with_size_expr (tree *expr_p)
3437 tree expr = *expr_p;
3438 tree type = TREE_TYPE (expr);
3439 tree size;
3441 /* If we've already wrapped this or the type is error_mark_node, we can't do
3442 anything. */
3443 if (TREE_CODE (expr) == WITH_SIZE_EXPR
3444 || type == error_mark_node)
3445 return;
3447 /* If the size isn't known or is a constant, we have nothing to do. */
3448 size = TYPE_SIZE_UNIT (type);
3449 if (!size || poly_int_tree_p (size))
3450 return;
3452 /* Otherwise, make a WITH_SIZE_EXPR. */
3453 size = unshare_expr (size);
3454 size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, expr);
3455 *expr_p = build2 (WITH_SIZE_EXPR, type, expr, size);
3458 /* Helper for gimplify_call_expr. Gimplify a single argument *ARG_P
3459 Store any side-effects in PRE_P. CALL_LOCATION is the location of
3460 the CALL_EXPR. If ALLOW_SSA is set the actual parameter may be
3461 gimplified to an SSA name. */
3463 enum gimplify_status
3464 gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location,
3465 bool allow_ssa)
3467 bool (*test) (tree);
3468 fallback_t fb;
3470 /* In general, we allow lvalues for function arguments to avoid
3471 extra overhead of copying large aggregates out of even larger
3472 aggregates into temporaries only to copy the temporaries to
3473 the argument list. Make optimizers happy by pulling out to
3474 temporaries those types that fit in registers. */
3475 if (is_gimple_reg_type (TREE_TYPE (*arg_p)))
3476 test = is_gimple_val, fb = fb_rvalue;
3477 else
3479 test = is_gimple_lvalue, fb = fb_either;
3480 /* Also strip a TARGET_EXPR that would force an extra copy. */
3481 if (TREE_CODE (*arg_p) == TARGET_EXPR)
3483 tree init = TARGET_EXPR_INITIAL (*arg_p);
3484 if (init
3485 && !VOID_TYPE_P (TREE_TYPE (init)))
3486 *arg_p = init;
3490 /* If this is a variable sized type, we must remember the size. */
3491 maybe_with_size_expr (arg_p);
3493 /* FIXME diagnostics: This will mess up gcc.dg/Warray-bounds.c. */
3494 /* Make sure arguments have the same location as the function call
3495 itself. */
3496 protected_set_expr_location (*arg_p, call_location);
3498 /* There is a sequence point before a function call. Side effects in
3499 the argument list must occur before the actual call. So, when
3500 gimplifying arguments, force gimplify_expr to use an internal
3501 post queue which is then appended to the end of PRE_P. */
3502 return gimplify_expr (arg_p, pre_p, NULL, test, fb, allow_ssa);
3505 /* Don't fold inside offloading or taskreg regions: it can break code by
3506 adding decl references that weren't in the source. We'll do it during
3507 omplower pass instead. */
3509 static bool
3510 maybe_fold_stmt (gimple_stmt_iterator *gsi)
3512 struct gimplify_omp_ctx *ctx;
3513 for (ctx = gimplify_omp_ctxp; ctx; ctx = ctx->outer_context)
3514 if ((ctx->region_type & (ORT_TARGET | ORT_PARALLEL | ORT_TASK)) != 0)
3515 return false;
3516 else if ((ctx->region_type & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
3517 return false;
3518 /* Delay folding of builtins until the IL is in consistent state
3519 so the diagnostic machinery can do a better job. */
3520 if (gimple_call_builtin_p (gsi_stmt (*gsi)))
3521 return false;
3522 return fold_stmt (gsi);
3525 /* Gimplify the CALL_EXPR node *EXPR_P into the GIMPLE sequence PRE_P.
3526 WANT_VALUE is true if the result of the call is desired. */
3528 static enum gimplify_status
3529 gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
3531 tree fndecl, parms, p, fnptrtype;
3532 enum gimplify_status ret;
3533 int i, nargs;
3534 gcall *call;
3535 bool builtin_va_start_p = false;
3536 location_t loc = EXPR_LOCATION (*expr_p);
3538 gcc_assert (TREE_CODE (*expr_p) == CALL_EXPR);
3540 /* For reliable diagnostics during inlining, it is necessary that
3541 every call_expr be annotated with file and line. */
3542 if (! EXPR_HAS_LOCATION (*expr_p))
3543 SET_EXPR_LOCATION (*expr_p, input_location);
3545 /* Gimplify internal functions created in the FEs. */
3546 if (CALL_EXPR_FN (*expr_p) == NULL_TREE)
3548 if (want_value)
3549 return GS_ALL_DONE;
3551 nargs = call_expr_nargs (*expr_p);
3552 enum internal_fn ifn = CALL_EXPR_IFN (*expr_p);
3553 auto_vec<tree> vargs (nargs);
3555 for (i = 0; i < nargs; i++)
3557 gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
3558 EXPR_LOCATION (*expr_p));
3559 vargs.quick_push (CALL_EXPR_ARG (*expr_p, i));
3562 gcall *call = gimple_build_call_internal_vec (ifn, vargs);
3563 gimple_call_set_nothrow (call, TREE_NOTHROW (*expr_p));
3564 gimplify_seq_add_stmt (pre_p, call);
3565 return GS_ALL_DONE;
3568 /* This may be a call to a builtin function.
3570 Builtin function calls may be transformed into different
3571 (and more efficient) builtin function calls under certain
3572 circumstances. Unfortunately, gimplification can muck things
3573 up enough that the builtin expanders are not aware that certain
3574 transformations are still valid.
3576 So we attempt transformation/gimplification of the call before
3577 we gimplify the CALL_EXPR. At this time we do not manage to
3578 transform all calls in the same manner as the expanders do, but
3579 we do transform most of them. */
3580 fndecl = get_callee_fndecl (*expr_p);
3581 if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
3582 switch (DECL_FUNCTION_CODE (fndecl))
3584 CASE_BUILT_IN_ALLOCA:
3585 /* If the call has been built for a variable-sized object, then we
3586 want to restore the stack level when the enclosing BIND_EXPR is
3587 exited to reclaim the allocated space; otherwise, we precisely
3588 need to do the opposite and preserve the latest stack level. */
3589 if (CALL_ALLOCA_FOR_VAR_P (*expr_p))
3590 gimplify_ctxp->save_stack = true;
3591 else
3592 gimplify_ctxp->keep_stack = true;
3593 break;
3595 case BUILT_IN_VA_START:
3597 builtin_va_start_p = TRUE;
3598 if (call_expr_nargs (*expr_p) < 2)
3600 error ("too few arguments to function %<va_start%>");
3601 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
3602 return GS_OK;
3605 if (fold_builtin_next_arg (*expr_p, true))
3607 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
3608 return GS_OK;
3610 break;
3613 case BUILT_IN_EH_RETURN:
3614 cfun->calls_eh_return = true;
3615 break;
3617 case BUILT_IN_CLEAR_PADDING:
3618 if (call_expr_nargs (*expr_p) == 1)
3620 /* Remember the original type of the argument in an internal
3621 dummy second argument, as in GIMPLE pointer conversions are
3622 useless. Also mark this call as not for automatic
3623 initialization in the internal dummy third argument. */
3624 p = CALL_EXPR_ARG (*expr_p, 0);
3625 *expr_p
3626 = build_call_expr_loc (EXPR_LOCATION (*expr_p), fndecl, 2, p,
3627 build_zero_cst (TREE_TYPE (p)));
3628 return GS_OK;
3630 break;
3632 default:
3635 if (fndecl && fndecl_built_in_p (fndecl))
3637 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
3638 if (new_tree && new_tree != *expr_p)
3640 /* There was a transformation of this call which computes the
3641 same value, but in a more efficient way. Return and try
3642 again. */
3643 *expr_p = new_tree;
3644 return GS_OK;
3648 /* Remember the original function pointer type. */
3649 fnptrtype = TREE_TYPE (CALL_EXPR_FN (*expr_p));
3651 if (flag_openmp
3652 && fndecl
3653 && cfun
3654 && (cfun->curr_properties & PROP_gimple_any) == 0)
3656 tree variant = omp_resolve_declare_variant (fndecl);
3657 if (variant != fndecl)
3658 CALL_EXPR_FN (*expr_p) = build1 (ADDR_EXPR, fnptrtype, variant);
3661 /* There is a sequence point before the call, so any side effects in
3662 the calling expression must occur before the actual call. Force
3663 gimplify_expr to use an internal post queue. */
3664 ret = gimplify_expr (&CALL_EXPR_FN (*expr_p), pre_p, NULL,
3665 is_gimple_call_addr, fb_rvalue);
3667 nargs = call_expr_nargs (*expr_p);
3669 /* Get argument types for verification. */
3670 fndecl = get_callee_fndecl (*expr_p);
3671 parms = NULL_TREE;
3672 if (fndecl)
3673 parms = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
3674 else
3675 parms = TYPE_ARG_TYPES (TREE_TYPE (fnptrtype));
3677 if (fndecl && DECL_ARGUMENTS (fndecl))
3678 p = DECL_ARGUMENTS (fndecl);
3679 else if (parms)
3680 p = parms;
3681 else
3682 p = NULL_TREE;
3683 for (i = 0; i < nargs && p; i++, p = TREE_CHAIN (p))
3686 /* If the last argument is __builtin_va_arg_pack () and it is not
3687 passed as a named argument, decrease the number of CALL_EXPR
3688 arguments and set instead the CALL_EXPR_VA_ARG_PACK flag. */
3689 if (!p
3690 && i < nargs
3691 && TREE_CODE (CALL_EXPR_ARG (*expr_p, nargs - 1)) == CALL_EXPR)
3693 tree last_arg = CALL_EXPR_ARG (*expr_p, nargs - 1);
3694 tree last_arg_fndecl = get_callee_fndecl (last_arg);
3696 if (last_arg_fndecl
3697 && fndecl_built_in_p (last_arg_fndecl, BUILT_IN_VA_ARG_PACK))
3699 tree call = *expr_p;
3701 --nargs;
3702 *expr_p = build_call_array_loc (loc, TREE_TYPE (call),
3703 CALL_EXPR_FN (call),
3704 nargs, CALL_EXPR_ARGP (call));
3706 /* Copy all CALL_EXPR flags, location and block, except
3707 CALL_EXPR_VA_ARG_PACK flag. */
3708 CALL_EXPR_STATIC_CHAIN (*expr_p) = CALL_EXPR_STATIC_CHAIN (call);
3709 CALL_EXPR_TAILCALL (*expr_p) = CALL_EXPR_TAILCALL (call);
3710 CALL_EXPR_RETURN_SLOT_OPT (*expr_p)
3711 = CALL_EXPR_RETURN_SLOT_OPT (call);
3712 CALL_FROM_THUNK_P (*expr_p) = CALL_FROM_THUNK_P (call);
3713 SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (call));
3715 /* Set CALL_EXPR_VA_ARG_PACK. */
3716 CALL_EXPR_VA_ARG_PACK (*expr_p) = 1;
3720 /* If the call returns twice then after building the CFG the call
3721 argument computations will no longer dominate the call because
3722 we add an abnormal incoming edge to the call. So do not use SSA
3723 vars there. */
3724 bool returns_twice = call_expr_flags (*expr_p) & ECF_RETURNS_TWICE;
3726 /* Gimplify the function arguments. */
3727 if (nargs > 0)
3729 for (i = (PUSH_ARGS_REVERSED ? nargs - 1 : 0);
3730 PUSH_ARGS_REVERSED ? i >= 0 : i < nargs;
3731 PUSH_ARGS_REVERSED ? i-- : i++)
3733 enum gimplify_status t;
3735 /* Avoid gimplifying the second argument to va_start, which needs to
3736 be the plain PARM_DECL. */
3737 if ((i != 1) || !builtin_va_start_p)
3739 t = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
3740 EXPR_LOCATION (*expr_p), ! returns_twice);
3742 if (t == GS_ERROR)
3743 ret = GS_ERROR;
3748 /* Gimplify the static chain. */
3749 if (CALL_EXPR_STATIC_CHAIN (*expr_p))
3751 if (fndecl && !DECL_STATIC_CHAIN (fndecl))
3752 CALL_EXPR_STATIC_CHAIN (*expr_p) = NULL;
3753 else
3755 enum gimplify_status t;
3756 t = gimplify_arg (&CALL_EXPR_STATIC_CHAIN (*expr_p), pre_p,
3757 EXPR_LOCATION (*expr_p), ! returns_twice);
3758 if (t == GS_ERROR)
3759 ret = GS_ERROR;
3763 /* Verify the function result. */
3764 if (want_value && fndecl
3765 && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fnptrtype))))
3767 error_at (loc, "using result of function returning %<void%>");
3768 ret = GS_ERROR;
3771 /* Try this again in case gimplification exposed something. */
3772 if (ret != GS_ERROR)
3774 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
3776 if (new_tree && new_tree != *expr_p)
3778 /* There was a transformation of this call which computes the
3779 same value, but in a more efficient way. Return and try
3780 again. */
3781 *expr_p = new_tree;
3782 return GS_OK;
3785 else
3787 *expr_p = error_mark_node;
3788 return GS_ERROR;
3791 /* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its
3792 decl. This allows us to eliminate redundant or useless
3793 calls to "const" functions. */
3794 if (TREE_CODE (*expr_p) == CALL_EXPR)
3796 int flags = call_expr_flags (*expr_p);
3797 if (flags & (ECF_CONST | ECF_PURE)
3798 /* An infinite loop is considered a side effect. */
3799 && !(flags & (ECF_LOOPING_CONST_OR_PURE)))
3800 TREE_SIDE_EFFECTS (*expr_p) = 0;
3803 /* If the value is not needed by the caller, emit a new GIMPLE_CALL
3804 and clear *EXPR_P. Otherwise, leave *EXPR_P in its gimplified
3805 form and delegate the creation of a GIMPLE_CALL to
3806 gimplify_modify_expr. This is always possible because when
3807 WANT_VALUE is true, the caller wants the result of this call into
3808 a temporary, which means that we will emit an INIT_EXPR in
3809 internal_get_tmp_var which will then be handled by
3810 gimplify_modify_expr. */
3811 if (!want_value)
3813 /* The CALL_EXPR in *EXPR_P is already in GIMPLE form, so all we
3814 have to do is replicate it as a GIMPLE_CALL tuple. */
3815 gimple_stmt_iterator gsi;
3816 call = gimple_build_call_from_tree (*expr_p, fnptrtype);
3817 notice_special_calls (call);
3818 gimplify_seq_add_stmt (pre_p, call);
3819 gsi = gsi_last (*pre_p);
3820 maybe_fold_stmt (&gsi);
3821 *expr_p = NULL_TREE;
3823 else
3824 /* Remember the original function type. */
3825 CALL_EXPR_FN (*expr_p) = build1 (NOP_EXPR, fnptrtype,
3826 CALL_EXPR_FN (*expr_p));
3828 return ret;
3831 /* Handle shortcut semantics in the predicate operand of a COND_EXPR by
3832 rewriting it into multiple COND_EXPRs, and possibly GOTO_EXPRs.
3834 TRUE_LABEL_P and FALSE_LABEL_P point to the labels to jump to if the
3835 condition is true or false, respectively. If null, we should generate
3836 our own to skip over the evaluation of this specific expression.
3838 LOCUS is the source location of the COND_EXPR.
3840 This function is the tree equivalent of do_jump.
3842 shortcut_cond_r should only be called by shortcut_cond_expr. */
3844 static tree
3845 shortcut_cond_r (tree pred, tree *true_label_p, tree *false_label_p,
3846 location_t locus)
3848 tree local_label = NULL_TREE;
3849 tree t, expr = NULL;
3851 /* OK, it's not a simple case; we need to pull apart the COND_EXPR to
3852 retain the shortcut semantics. Just insert the gotos here;
3853 shortcut_cond_expr will append the real blocks later. */
3854 if (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
3856 location_t new_locus;
3858 /* Turn if (a && b) into
3860 if (a); else goto no;
3861 if (b) goto yes; else goto no;
3862 (no:) */
3864 if (false_label_p == NULL)
3865 false_label_p = &local_label;
3867 /* Keep the original source location on the first 'if'. */
3868 t = shortcut_cond_r (TREE_OPERAND (pred, 0), NULL, false_label_p, locus);
3869 append_to_statement_list (t, &expr);
3871 /* Set the source location of the && on the second 'if'. */
3872 new_locus = rexpr_location (pred, locus);
3873 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
3874 new_locus);
3875 append_to_statement_list (t, &expr);
3877 else if (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
3879 location_t new_locus;
3881 /* Turn if (a || b) into
3883 if (a) goto yes;
3884 if (b) goto yes; else goto no;
3885 (yes:) */
3887 if (true_label_p == NULL)
3888 true_label_p = &local_label;
3890 /* Keep the original source location on the first 'if'. */
3891 t = shortcut_cond_r (TREE_OPERAND (pred, 0), true_label_p, NULL, locus);
3892 append_to_statement_list (t, &expr);
3894 /* Set the source location of the || on the second 'if'. */
3895 new_locus = rexpr_location (pred, locus);
3896 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
3897 new_locus);
3898 append_to_statement_list (t, &expr);
3900 else if (TREE_CODE (pred) == COND_EXPR
3901 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 1)))
3902 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 2))))
3904 location_t new_locus;
3906 /* As long as we're messing with gotos, turn if (a ? b : c) into
3907 if (a)
3908 if (b) goto yes; else goto no;
3909 else
3910 if (c) goto yes; else goto no;
3912 Don't do this if one of the arms has void type, which can happen
3913 in C++ when the arm is throw. */
3915 /* Keep the original source location on the first 'if'. Set the source
3916 location of the ? on the second 'if'. */
3917 new_locus = rexpr_location (pred, locus);
3918 expr = build3 (COND_EXPR, void_type_node, TREE_OPERAND (pred, 0),
3919 shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p,
3920 false_label_p, locus),
3921 shortcut_cond_r (TREE_OPERAND (pred, 2), true_label_p,
3922 false_label_p, new_locus));
3924 else
3926 expr = build3 (COND_EXPR, void_type_node, pred,
3927 build_and_jump (true_label_p),
3928 build_and_jump (false_label_p));
3929 SET_EXPR_LOCATION (expr, locus);
3932 if (local_label)
3934 t = build1 (LABEL_EXPR, void_type_node, local_label);
3935 append_to_statement_list (t, &expr);
3938 return expr;
3941 /* If EXPR is a GOTO_EXPR, return it. If it is a STATEMENT_LIST, skip
3942 any of its leading DEBUG_BEGIN_STMTS and recurse on the subsequent
3943 statement, if it is the last one. Otherwise, return NULL. */
3945 static tree
3946 find_goto (tree expr)
3948 if (!expr)
3949 return NULL_TREE;
3951 if (TREE_CODE (expr) == GOTO_EXPR)
3952 return expr;
3954 if (TREE_CODE (expr) != STATEMENT_LIST)
3955 return NULL_TREE;
3957 tree_stmt_iterator i = tsi_start (expr);
3959 while (!tsi_end_p (i) && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT)
3960 tsi_next (&i);
3962 if (!tsi_one_before_end_p (i))
3963 return NULL_TREE;
3965 return find_goto (tsi_stmt (i));
3968 /* Same as find_goto, except that it returns NULL if the destination
3969 is not a LABEL_DECL. */
3971 static inline tree
3972 find_goto_label (tree expr)
3974 tree dest = find_goto (expr);
3975 if (dest && TREE_CODE (GOTO_DESTINATION (dest)) == LABEL_DECL)
3976 return dest;
3977 return NULL_TREE;
3980 /* Given a conditional expression EXPR with short-circuit boolean
3981 predicates using TRUTH_ANDIF_EXPR or TRUTH_ORIF_EXPR, break the
3982 predicate apart into the equivalent sequence of conditionals. */
3984 static tree
3985 shortcut_cond_expr (tree expr)
3987 tree pred = TREE_OPERAND (expr, 0);
3988 tree then_ = TREE_OPERAND (expr, 1);
3989 tree else_ = TREE_OPERAND (expr, 2);
3990 tree true_label, false_label, end_label, t;
3991 tree *true_label_p;
3992 tree *false_label_p;
3993 bool emit_end, emit_false, jump_over_else;
3994 bool then_se = then_ && TREE_SIDE_EFFECTS (then_);
3995 bool else_se = else_ && TREE_SIDE_EFFECTS (else_);
3997 /* First do simple transformations. */
3998 if (!else_se)
4000 /* If there is no 'else', turn
4001 if (a && b) then c
4002 into
4003 if (a) if (b) then c. */
4004 while (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
4006 /* Keep the original source location on the first 'if'. */
4007 location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
4008 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
4009 /* Set the source location of the && on the second 'if'. */
4010 if (rexpr_has_location (pred))
4011 SET_EXPR_LOCATION (expr, rexpr_location (pred));
4012 then_ = shortcut_cond_expr (expr);
4013 then_se = then_ && TREE_SIDE_EFFECTS (then_);
4014 pred = TREE_OPERAND (pred, 0);
4015 expr = build3 (COND_EXPR, void_type_node, pred, then_, NULL_TREE);
4016 SET_EXPR_LOCATION (expr, locus);
4020 if (!then_se)
4022 /* If there is no 'then', turn
4023 if (a || b); else d
4024 into
4025 if (a); else if (b); else d. */
4026 while (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
4028 /* Keep the original source location on the first 'if'. */
4029 location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
4030 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
4031 /* Set the source location of the || on the second 'if'. */
4032 if (rexpr_has_location (pred))
4033 SET_EXPR_LOCATION (expr, rexpr_location (pred));
4034 else_ = shortcut_cond_expr (expr);
4035 else_se = else_ && TREE_SIDE_EFFECTS (else_);
4036 pred = TREE_OPERAND (pred, 0);
4037 expr = build3 (COND_EXPR, void_type_node, pred, NULL_TREE, else_);
4038 SET_EXPR_LOCATION (expr, locus);
4042 /* If we're done, great. */
4043 if (TREE_CODE (pred) != TRUTH_ANDIF_EXPR
4044 && TREE_CODE (pred) != TRUTH_ORIF_EXPR)
4045 return expr;
4047 /* Otherwise we need to mess with gotos. Change
4048 if (a) c; else d;
4050 if (a); else goto no;
4051 c; goto end;
4052 no: d; end:
4053 and recursively gimplify the condition. */
4055 true_label = false_label = end_label = NULL_TREE;
4057 /* If our arms just jump somewhere, hijack those labels so we don't
4058 generate jumps to jumps. */
4060 if (tree then_goto = find_goto_label (then_))
4062 true_label = GOTO_DESTINATION (then_goto);
4063 then_ = NULL;
4064 then_se = false;
4067 if (tree else_goto = find_goto_label (else_))
4069 false_label = GOTO_DESTINATION (else_goto);
4070 else_ = NULL;
4071 else_se = false;
4074 /* If we aren't hijacking a label for the 'then' branch, it falls through. */
4075 if (true_label)
4076 true_label_p = &true_label;
4077 else
4078 true_label_p = NULL;
4080 /* The 'else' branch also needs a label if it contains interesting code. */
4081 if (false_label || else_se)
4082 false_label_p = &false_label;
4083 else
4084 false_label_p = NULL;
4086 /* If there was nothing else in our arms, just forward the label(s). */
4087 if (!then_se && !else_se)
4088 return shortcut_cond_r (pred, true_label_p, false_label_p,
4089 EXPR_LOC_OR_LOC (expr, input_location));
4091 /* If our last subexpression already has a terminal label, reuse it. */
4092 if (else_se)
4093 t = expr_last (else_);
4094 else if (then_se)
4095 t = expr_last (then_);
4096 else
4097 t = NULL;
4098 if (t && TREE_CODE (t) == LABEL_EXPR)
4099 end_label = LABEL_EXPR_LABEL (t);
4101 /* If we don't care about jumping to the 'else' branch, jump to the end
4102 if the condition is false. */
4103 if (!false_label_p)
4104 false_label_p = &end_label;
4106 /* We only want to emit these labels if we aren't hijacking them. */
4107 emit_end = (end_label == NULL_TREE);
4108 emit_false = (false_label == NULL_TREE);
4110 /* We only emit the jump over the else clause if we have to--if the
4111 then clause may fall through. Otherwise we can wind up with a
4112 useless jump and a useless label at the end of gimplified code,
4113 which will cause us to think that this conditional as a whole
4114 falls through even if it doesn't. If we then inline a function
4115 which ends with such a condition, that can cause us to issue an
4116 inappropriate warning about control reaching the end of a
4117 non-void function. */
4118 jump_over_else = block_may_fallthru (then_);
4120 pred = shortcut_cond_r (pred, true_label_p, false_label_p,
4121 EXPR_LOC_OR_LOC (expr, input_location));
4123 expr = NULL;
4124 append_to_statement_list (pred, &expr);
4126 append_to_statement_list (then_, &expr);
4127 if (else_se)
4129 if (jump_over_else)
4131 tree last = expr_last (expr);
4132 t = build_and_jump (&end_label);
4133 if (rexpr_has_location (last))
4134 SET_EXPR_LOCATION (t, rexpr_location (last));
4135 append_to_statement_list (t, &expr);
4137 if (emit_false)
4139 t = build1 (LABEL_EXPR, void_type_node, false_label);
4140 append_to_statement_list (t, &expr);
4142 append_to_statement_list (else_, &expr);
4144 if (emit_end && end_label)
4146 t = build1 (LABEL_EXPR, void_type_node, end_label);
4147 append_to_statement_list (t, &expr);
4150 return expr;
4153 /* EXPR is used in a boolean context; make sure it has BOOLEAN_TYPE. */
4155 tree
4156 gimple_boolify (tree expr)
4158 tree type = TREE_TYPE (expr);
4159 location_t loc = EXPR_LOCATION (expr);
4161 if (TREE_CODE (expr) == NE_EXPR
4162 && TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR
4163 && integer_zerop (TREE_OPERAND (expr, 1)))
4165 tree call = TREE_OPERAND (expr, 0);
4166 tree fn = get_callee_fndecl (call);
4168 /* For __builtin_expect ((long) (x), y) recurse into x as well
4169 if x is truth_value_p. */
4170 if (fn
4171 && fndecl_built_in_p (fn, BUILT_IN_EXPECT)
4172 && call_expr_nargs (call) == 2)
4174 tree arg = CALL_EXPR_ARG (call, 0);
4175 if (arg)
4177 if (TREE_CODE (arg) == NOP_EXPR
4178 && TREE_TYPE (arg) == TREE_TYPE (call))
4179 arg = TREE_OPERAND (arg, 0);
4180 if (truth_value_p (TREE_CODE (arg)))
4182 arg = gimple_boolify (arg);
4183 CALL_EXPR_ARG (call, 0)
4184 = fold_convert_loc (loc, TREE_TYPE (call), arg);
4190 switch (TREE_CODE (expr))
4192 case TRUTH_AND_EXPR:
4193 case TRUTH_OR_EXPR:
4194 case TRUTH_XOR_EXPR:
4195 case TRUTH_ANDIF_EXPR:
4196 case TRUTH_ORIF_EXPR:
4197 /* Also boolify the arguments of truth exprs. */
4198 TREE_OPERAND (expr, 1) = gimple_boolify (TREE_OPERAND (expr, 1));
4199 /* FALLTHRU */
4201 case TRUTH_NOT_EXPR:
4202 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
4204 /* These expressions always produce boolean results. */
4205 if (TREE_CODE (type) != BOOLEAN_TYPE)
4206 TREE_TYPE (expr) = boolean_type_node;
4207 return expr;
4209 case ANNOTATE_EXPR:
4210 switch ((enum annot_expr_kind) TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)))
4212 case annot_expr_ivdep_kind:
4213 case annot_expr_unroll_kind:
4214 case annot_expr_no_vector_kind:
4215 case annot_expr_vector_kind:
4216 case annot_expr_parallel_kind:
4217 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
4218 if (TREE_CODE (type) != BOOLEAN_TYPE)
4219 TREE_TYPE (expr) = boolean_type_node;
4220 return expr;
4221 default:
4222 gcc_unreachable ();
4225 default:
4226 if (COMPARISON_CLASS_P (expr))
4228 /* There expressions always prduce boolean results. */
4229 if (TREE_CODE (type) != BOOLEAN_TYPE)
4230 TREE_TYPE (expr) = boolean_type_node;
4231 return expr;
4233 /* Other expressions that get here must have boolean values, but
4234 might need to be converted to the appropriate mode. */
4235 if (TREE_CODE (type) == BOOLEAN_TYPE)
4236 return expr;
4237 return fold_convert_loc (loc, boolean_type_node, expr);
4241 /* Given a conditional expression *EXPR_P without side effects, gimplify
4242 its operands. New statements are inserted to PRE_P. */
4244 static enum gimplify_status
4245 gimplify_pure_cond_expr (tree *expr_p, gimple_seq *pre_p)
4247 tree expr = *expr_p, cond;
4248 enum gimplify_status ret, tret;
4249 enum tree_code code;
4251 cond = gimple_boolify (COND_EXPR_COND (expr));
4253 /* We need to handle && and || specially, as their gimplification
4254 creates pure cond_expr, thus leading to an infinite cycle otherwise. */
4255 code = TREE_CODE (cond);
4256 if (code == TRUTH_ANDIF_EXPR)
4257 TREE_SET_CODE (cond, TRUTH_AND_EXPR);
4258 else if (code == TRUTH_ORIF_EXPR)
4259 TREE_SET_CODE (cond, TRUTH_OR_EXPR);
4260 ret = gimplify_expr (&cond, pre_p, NULL, is_gimple_condexpr, fb_rvalue);
4261 COND_EXPR_COND (*expr_p) = cond;
4263 tret = gimplify_expr (&COND_EXPR_THEN (expr), pre_p, NULL,
4264 is_gimple_val, fb_rvalue);
4265 ret = MIN (ret, tret);
4266 tret = gimplify_expr (&COND_EXPR_ELSE (expr), pre_p, NULL,
4267 is_gimple_val, fb_rvalue);
4269 return MIN (ret, tret);
4272 /* Return true if evaluating EXPR could trap.
4273 EXPR is GENERIC, while tree_could_trap_p can be called
4274 only on GIMPLE. */
4276 bool
4277 generic_expr_could_trap_p (tree expr)
4279 unsigned i, n;
4281 if (!expr || is_gimple_val (expr))
4282 return false;
4284 if (!EXPR_P (expr) || tree_could_trap_p (expr))
4285 return true;
4287 n = TREE_OPERAND_LENGTH (expr);
4288 for (i = 0; i < n; i++)
4289 if (generic_expr_could_trap_p (TREE_OPERAND (expr, i)))
4290 return true;
4292 return false;
4295 /* Convert the conditional expression pointed to by EXPR_P '(p) ? a : b;'
4296 into
4298 if (p) if (p)
4299 t1 = a; a;
4300 else or else
4301 t1 = b; b;
4304 The second form is used when *EXPR_P is of type void.
4306 PRE_P points to the list where side effects that must happen before
4307 *EXPR_P should be stored. */
4309 static enum gimplify_status
4310 gimplify_cond_expr (tree *expr_p, gimple_seq *pre_p, fallback_t fallback)
4312 tree expr = *expr_p;
4313 tree type = TREE_TYPE (expr);
4314 location_t loc = EXPR_LOCATION (expr);
4315 tree tmp, arm1, arm2;
4316 enum gimplify_status ret;
4317 tree label_true, label_false, label_cont;
4318 bool have_then_clause_p, have_else_clause_p;
4319 gcond *cond_stmt;
4320 enum tree_code pred_code;
4321 gimple_seq seq = NULL;
4323 /* If this COND_EXPR has a value, copy the values into a temporary within
4324 the arms. */
4325 if (!VOID_TYPE_P (type))
4327 tree then_ = TREE_OPERAND (expr, 1), else_ = TREE_OPERAND (expr, 2);
4328 tree result;
4330 /* If either an rvalue is ok or we do not require an lvalue, create the
4331 temporary. But we cannot do that if the type is addressable. */
4332 if (((fallback & fb_rvalue) || !(fallback & fb_lvalue))
4333 && !TREE_ADDRESSABLE (type))
4335 if (gimplify_ctxp->allow_rhs_cond_expr
4336 /* If either branch has side effects or could trap, it can't be
4337 evaluated unconditionally. */
4338 && !TREE_SIDE_EFFECTS (then_)
4339 && !generic_expr_could_trap_p (then_)
4340 && !TREE_SIDE_EFFECTS (else_)
4341 && !generic_expr_could_trap_p (else_))
4342 return gimplify_pure_cond_expr (expr_p, pre_p);
4344 tmp = create_tmp_var (type, "iftmp");
4345 result = tmp;
4348 /* Otherwise, only create and copy references to the values. */
4349 else
4351 type = build_pointer_type (type);
4353 if (!VOID_TYPE_P (TREE_TYPE (then_)))
4354 then_ = build_fold_addr_expr_loc (loc, then_);
4356 if (!VOID_TYPE_P (TREE_TYPE (else_)))
4357 else_ = build_fold_addr_expr_loc (loc, else_);
4359 expr
4360 = build3 (COND_EXPR, type, TREE_OPERAND (expr, 0), then_, else_);
4362 tmp = create_tmp_var (type, "iftmp");
4363 result = build_simple_mem_ref_loc (loc, tmp);
4366 /* Build the new then clause, `tmp = then_;'. But don't build the
4367 assignment if the value is void; in C++ it can be if it's a throw. */
4368 if (!VOID_TYPE_P (TREE_TYPE (then_)))
4369 TREE_OPERAND (expr, 1) = build2 (INIT_EXPR, type, tmp, then_);
4371 /* Similarly, build the new else clause, `tmp = else_;'. */
4372 if (!VOID_TYPE_P (TREE_TYPE (else_)))
4373 TREE_OPERAND (expr, 2) = build2 (INIT_EXPR, type, tmp, else_);
4375 TREE_TYPE (expr) = void_type_node;
4376 recalculate_side_effects (expr);
4378 /* Move the COND_EXPR to the prequeue. */
4379 gimplify_stmt (&expr, pre_p);
4381 *expr_p = result;
4382 return GS_ALL_DONE;
4385 /* Remove any COMPOUND_EXPR so the following cases will be caught. */
4386 STRIP_TYPE_NOPS (TREE_OPERAND (expr, 0));
4387 if (TREE_CODE (TREE_OPERAND (expr, 0)) == COMPOUND_EXPR)
4388 gimplify_compound_expr (&TREE_OPERAND (expr, 0), pre_p, true);
4390 /* Make sure the condition has BOOLEAN_TYPE. */
4391 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
4393 /* Break apart && and || conditions. */
4394 if (TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ANDIF_EXPR
4395 || TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ORIF_EXPR)
4397 expr = shortcut_cond_expr (expr);
4399 if (expr != *expr_p)
4401 *expr_p = expr;
4403 /* We can't rely on gimplify_expr to re-gimplify the expanded
4404 form properly, as cleanups might cause the target labels to be
4405 wrapped in a TRY_FINALLY_EXPR. To prevent that, we need to
4406 set up a conditional context. */
4407 gimple_push_condition ();
4408 gimplify_stmt (expr_p, &seq);
4409 gimple_pop_condition (pre_p);
4410 gimple_seq_add_seq (pre_p, seq);
4412 return GS_ALL_DONE;
4416 /* Now do the normal gimplification. */
4418 /* Gimplify condition. */
4419 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL,
4420 is_gimple_condexpr_for_cond, fb_rvalue);
4421 if (ret == GS_ERROR)
4422 return GS_ERROR;
4423 gcc_assert (TREE_OPERAND (expr, 0) != NULL_TREE);
4425 gimple_push_condition ();
4427 have_then_clause_p = have_else_clause_p = false;
4428 label_true = find_goto_label (TREE_OPERAND (expr, 1));
4429 if (label_true
4430 && DECL_CONTEXT (GOTO_DESTINATION (label_true)) == current_function_decl
4431 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4432 have different locations, otherwise we end up with incorrect
4433 location information on the branches. */
4434 && (optimize
4435 || !EXPR_HAS_LOCATION (expr)
4436 || !rexpr_has_location (label_true)
4437 || EXPR_LOCATION (expr) == rexpr_location (label_true)))
4439 have_then_clause_p = true;
4440 label_true = GOTO_DESTINATION (label_true);
4442 else
4443 label_true = create_artificial_label (UNKNOWN_LOCATION);
4444 label_false = find_goto_label (TREE_OPERAND (expr, 2));
4445 if (label_false
4446 && DECL_CONTEXT (GOTO_DESTINATION (label_false)) == current_function_decl
4447 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4448 have different locations, otherwise we end up with incorrect
4449 location information on the branches. */
4450 && (optimize
4451 || !EXPR_HAS_LOCATION (expr)
4452 || !rexpr_has_location (label_false)
4453 || EXPR_LOCATION (expr) == rexpr_location (label_false)))
4455 have_else_clause_p = true;
4456 label_false = GOTO_DESTINATION (label_false);
4458 else
4459 label_false = create_artificial_label (UNKNOWN_LOCATION);
4461 gimple_cond_get_ops_from_tree (COND_EXPR_COND (expr), &pred_code, &arm1,
4462 &arm2);
4463 cond_stmt = gimple_build_cond (pred_code, arm1, arm2, label_true,
4464 label_false);
4465 gimple_set_location (cond_stmt, EXPR_LOCATION (expr));
4466 copy_warning (cond_stmt, COND_EXPR_COND (expr));
4467 gimplify_seq_add_stmt (&seq, cond_stmt);
4468 gimple_stmt_iterator gsi = gsi_last (seq);
4469 maybe_fold_stmt (&gsi);
4471 label_cont = NULL_TREE;
4472 if (!have_then_clause_p)
4474 /* For if (...) {} else { code; } put label_true after
4475 the else block. */
4476 if (TREE_OPERAND (expr, 1) == NULL_TREE
4477 && !have_else_clause_p
4478 && TREE_OPERAND (expr, 2) != NULL_TREE)
4480 /* For if (0) {} else { code; } tell -Wimplicit-fallthrough
4481 handling that label_cont == label_true can be only reached
4482 through fallthrough from { code; }. */
4483 if (integer_zerop (COND_EXPR_COND (expr)))
4484 UNUSED_LABEL_P (label_true) = 1;
4485 label_cont = label_true;
4487 else
4489 bool then_side_effects
4490 = (TREE_OPERAND (expr, 1)
4491 && TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)));
4492 gimplify_seq_add_stmt (&seq, gimple_build_label (label_true));
4493 have_then_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 1), &seq);
4494 /* For if (...) { code; } else {} or
4495 if (...) { code; } else goto label; or
4496 if (...) { code; return; } else { ... }
4497 label_cont isn't needed. */
4498 if (!have_else_clause_p
4499 && TREE_OPERAND (expr, 2) != NULL_TREE
4500 && gimple_seq_may_fallthru (seq))
4502 gimple *g;
4503 label_cont = create_artificial_label (UNKNOWN_LOCATION);
4505 /* For if (0) { non-side-effect-code } else { code }
4506 tell -Wimplicit-fallthrough handling that label_cont can
4507 be only reached through fallthrough from { code }. */
4508 if (integer_zerop (COND_EXPR_COND (expr)))
4510 UNUSED_LABEL_P (label_true) = 1;
4511 if (!then_side_effects)
4512 UNUSED_LABEL_P (label_cont) = 1;
4515 g = gimple_build_goto (label_cont);
4517 /* GIMPLE_COND's are very low level; they have embedded
4518 gotos. This particular embedded goto should not be marked
4519 with the location of the original COND_EXPR, as it would
4520 correspond to the COND_EXPR's condition, not the ELSE or the
4521 THEN arms. To avoid marking it with the wrong location, flag
4522 it as "no location". */
4523 gimple_set_do_not_emit_location (g);
4525 gimplify_seq_add_stmt (&seq, g);
4529 if (!have_else_clause_p)
4531 /* For if (1) { code } or if (1) { code } else { non-side-effect-code }
4532 tell -Wimplicit-fallthrough handling that label_false can be only
4533 reached through fallthrough from { code }. */
4534 if (integer_nonzerop (COND_EXPR_COND (expr))
4535 && (TREE_OPERAND (expr, 2) == NULL_TREE
4536 || !TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 2))))
4537 UNUSED_LABEL_P (label_false) = 1;
4538 gimplify_seq_add_stmt (&seq, gimple_build_label (label_false));
4539 have_else_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 2), &seq);
4541 if (label_cont)
4542 gimplify_seq_add_stmt (&seq, gimple_build_label (label_cont));
4544 gimple_pop_condition (pre_p);
4545 gimple_seq_add_seq (pre_p, seq);
4547 if (ret == GS_ERROR)
4548 ; /* Do nothing. */
4549 else if (have_then_clause_p || have_else_clause_p)
4550 ret = GS_ALL_DONE;
4551 else
4553 /* Both arms are empty; replace the COND_EXPR with its predicate. */
4554 expr = TREE_OPERAND (expr, 0);
4555 gimplify_stmt (&expr, pre_p);
4558 *expr_p = NULL;
4559 return ret;
4562 /* Prepare the node pointed to by EXPR_P, an is_gimple_addressable expression,
4563 to be marked addressable.
4565 We cannot rely on such an expression being directly markable if a temporary
4566 has been created by the gimplification. In this case, we create another
4567 temporary and initialize it with a copy, which will become a store after we
4568 mark it addressable. This can happen if the front-end passed us something
4569 that it could not mark addressable yet, like a Fortran pass-by-reference
4570 parameter (int) floatvar. */
4572 static void
4573 prepare_gimple_addressable (tree *expr_p, gimple_seq *seq_p)
4575 while (handled_component_p (*expr_p))
4576 expr_p = &TREE_OPERAND (*expr_p, 0);
4577 if (is_gimple_reg (*expr_p))
4579 /* Do not allow an SSA name as the temporary. */
4580 tree var = get_initialized_tmp_var (*expr_p, seq_p, NULL, false);
4581 DECL_NOT_GIMPLE_REG_P (var) = 1;
4582 *expr_p = var;
4586 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4587 a call to __builtin_memcpy. */
4589 static enum gimplify_status
4590 gimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value,
4591 gimple_seq *seq_p)
4593 tree t, to, to_ptr, from, from_ptr;
4594 gcall *gs;
4595 location_t loc = EXPR_LOCATION (*expr_p);
4597 to = TREE_OPERAND (*expr_p, 0);
4598 from = TREE_OPERAND (*expr_p, 1);
4600 /* Mark the RHS addressable. Beware that it may not be possible to do so
4601 directly if a temporary has been created by the gimplification. */
4602 prepare_gimple_addressable (&from, seq_p);
4604 mark_addressable (from);
4605 from_ptr = build_fold_addr_expr_loc (loc, from);
4606 gimplify_arg (&from_ptr, seq_p, loc);
4608 mark_addressable (to);
4609 to_ptr = build_fold_addr_expr_loc (loc, to);
4610 gimplify_arg (&to_ptr, seq_p, loc);
4612 t = builtin_decl_implicit (BUILT_IN_MEMCPY);
4614 gs = gimple_build_call (t, 3, to_ptr, from_ptr, size);
4615 gimple_call_set_alloca_for_var (gs, true);
4617 if (want_value)
4619 /* tmp = memcpy() */
4620 t = create_tmp_var (TREE_TYPE (to_ptr));
4621 gimple_call_set_lhs (gs, t);
4622 gimplify_seq_add_stmt (seq_p, gs);
4624 *expr_p = build_simple_mem_ref (t);
4625 return GS_ALL_DONE;
4628 gimplify_seq_add_stmt (seq_p, gs);
4629 *expr_p = NULL;
4630 return GS_ALL_DONE;
4633 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4634 a call to __builtin_memset. In this case we know that the RHS is
4635 a CONSTRUCTOR with an empty element list. */
4637 static enum gimplify_status
4638 gimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value,
4639 gimple_seq *seq_p)
4641 tree t, from, to, to_ptr;
4642 gcall *gs;
4643 location_t loc = EXPR_LOCATION (*expr_p);
4645 /* Assert our assumptions, to abort instead of producing wrong code
4646 silently if they are not met. Beware that the RHS CONSTRUCTOR might
4647 not be immediately exposed. */
4648 from = TREE_OPERAND (*expr_p, 1);
4649 if (TREE_CODE (from) == WITH_SIZE_EXPR)
4650 from = TREE_OPERAND (from, 0);
4652 gcc_assert (TREE_CODE (from) == CONSTRUCTOR
4653 && vec_safe_is_empty (CONSTRUCTOR_ELTS (from)));
4655 /* Now proceed. */
4656 to = TREE_OPERAND (*expr_p, 0);
4658 to_ptr = build_fold_addr_expr_loc (loc, to);
4659 gimplify_arg (&to_ptr, seq_p, loc);
4660 t = builtin_decl_implicit (BUILT_IN_MEMSET);
4662 gs = gimple_build_call (t, 3, to_ptr, integer_zero_node, size);
4664 if (want_value)
4666 /* tmp = memset() */
4667 t = create_tmp_var (TREE_TYPE (to_ptr));
4668 gimple_call_set_lhs (gs, t);
4669 gimplify_seq_add_stmt (seq_p, gs);
4671 *expr_p = build1 (INDIRECT_REF, TREE_TYPE (to), t);
4672 return GS_ALL_DONE;
4675 gimplify_seq_add_stmt (seq_p, gs);
4676 *expr_p = NULL;
4677 return GS_ALL_DONE;
4680 /* A subroutine of gimplify_init_ctor_preeval. Called via walk_tree,
4681 determine, cautiously, if a CONSTRUCTOR overlaps the lhs of an
4682 assignment. Return non-null if we detect a potential overlap. */
4684 struct gimplify_init_ctor_preeval_data
4686 /* The base decl of the lhs object. May be NULL, in which case we
4687 have to assume the lhs is indirect. */
4688 tree lhs_base_decl;
4690 /* The alias set of the lhs object. */
4691 alias_set_type lhs_alias_set;
4694 static tree
4695 gimplify_init_ctor_preeval_1 (tree *tp, int *walk_subtrees, void *xdata)
4697 struct gimplify_init_ctor_preeval_data *data
4698 = (struct gimplify_init_ctor_preeval_data *) xdata;
4699 tree t = *tp;
4701 /* If we find the base object, obviously we have overlap. */
4702 if (data->lhs_base_decl == t)
4703 return t;
4705 /* If the constructor component is indirect, determine if we have a
4706 potential overlap with the lhs. The only bits of information we
4707 have to go on at this point are addressability and alias sets. */
4708 if ((INDIRECT_REF_P (t)
4709 || TREE_CODE (t) == MEM_REF)
4710 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
4711 && alias_sets_conflict_p (data->lhs_alias_set, get_alias_set (t)))
4712 return t;
4714 /* If the constructor component is a call, determine if it can hide a
4715 potential overlap with the lhs through an INDIRECT_REF like above.
4716 ??? Ugh - this is completely broken. In fact this whole analysis
4717 doesn't look conservative. */
4718 if (TREE_CODE (t) == CALL_EXPR)
4720 tree type, fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (t)));
4722 for (type = TYPE_ARG_TYPES (fntype); type; type = TREE_CHAIN (type))
4723 if (POINTER_TYPE_P (TREE_VALUE (type))
4724 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
4725 && alias_sets_conflict_p (data->lhs_alias_set,
4726 get_alias_set
4727 (TREE_TYPE (TREE_VALUE (type)))))
4728 return t;
4731 if (IS_TYPE_OR_DECL_P (t))
4732 *walk_subtrees = 0;
4733 return NULL;
4736 /* A subroutine of gimplify_init_constructor. Pre-evaluate EXPR,
4737 force values that overlap with the lhs (as described by *DATA)
4738 into temporaries. */
4740 static void
4741 gimplify_init_ctor_preeval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
4742 struct gimplify_init_ctor_preeval_data *data)
4744 enum gimplify_status one;
4746 /* If the value is constant, then there's nothing to pre-evaluate. */
4747 if (TREE_CONSTANT (*expr_p))
4749 /* Ensure it does not have side effects, it might contain a reference to
4750 the object we're initializing. */
4751 gcc_assert (!TREE_SIDE_EFFECTS (*expr_p));
4752 return;
4755 /* If the type has non-trivial constructors, we can't pre-evaluate. */
4756 if (TREE_ADDRESSABLE (TREE_TYPE (*expr_p)))
4757 return;
4759 /* Recurse for nested constructors. */
4760 if (TREE_CODE (*expr_p) == CONSTRUCTOR)
4762 unsigned HOST_WIDE_INT ix;
4763 constructor_elt *ce;
4764 vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (*expr_p);
4766 FOR_EACH_VEC_SAFE_ELT (v, ix, ce)
4767 gimplify_init_ctor_preeval (&ce->value, pre_p, post_p, data);
4769 return;
4772 /* If this is a variable sized type, we must remember the size. */
4773 maybe_with_size_expr (expr_p);
4775 /* Gimplify the constructor element to something appropriate for the rhs
4776 of a MODIFY_EXPR. Given that we know the LHS is an aggregate, we know
4777 the gimplifier will consider this a store to memory. Doing this
4778 gimplification now means that we won't have to deal with complicated
4779 language-specific trees, nor trees like SAVE_EXPR that can induce
4780 exponential search behavior. */
4781 one = gimplify_expr (expr_p, pre_p, post_p, is_gimple_mem_rhs, fb_rvalue);
4782 if (one == GS_ERROR)
4784 *expr_p = NULL;
4785 return;
4788 /* If we gimplified to a bare decl, we can be sure that it doesn't overlap
4789 with the lhs, since "a = { .x=a }" doesn't make sense. This will
4790 always be true for all scalars, since is_gimple_mem_rhs insists on a
4791 temporary variable for them. */
4792 if (DECL_P (*expr_p))
4793 return;
4795 /* If this is of variable size, we have no choice but to assume it doesn't
4796 overlap since we can't make a temporary for it. */
4797 if (TREE_CODE (TYPE_SIZE (TREE_TYPE (*expr_p))) != INTEGER_CST)
4798 return;
4800 /* Otherwise, we must search for overlap ... */
4801 if (!walk_tree (expr_p, gimplify_init_ctor_preeval_1, data, NULL))
4802 return;
4804 /* ... and if found, force the value into a temporary. */
4805 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
4808 /* A subroutine of gimplify_init_ctor_eval. Create a loop for
4809 a RANGE_EXPR in a CONSTRUCTOR for an array.
4811 var = lower;
4812 loop_entry:
4813 object[var] = value;
4814 if (var == upper)
4815 goto loop_exit;
4816 var = var + 1;
4817 goto loop_entry;
4818 loop_exit:
4820 We increment var _after_ the loop exit check because we might otherwise
4821 fail if upper == TYPE_MAX_VALUE (type for upper).
4823 Note that we never have to deal with SAVE_EXPRs here, because this has
4824 already been taken care of for us, in gimplify_init_ctor_preeval(). */
4826 static void gimplify_init_ctor_eval (tree, vec<constructor_elt, va_gc> *,
4827 gimple_seq *, bool);
4829 static void
4830 gimplify_init_ctor_eval_range (tree object, tree lower, tree upper,
4831 tree value, tree array_elt_type,
4832 gimple_seq *pre_p, bool cleared)
4834 tree loop_entry_label, loop_exit_label, fall_thru_label;
4835 tree var, var_type, cref, tmp;
4837 loop_entry_label = create_artificial_label (UNKNOWN_LOCATION);
4838 loop_exit_label = create_artificial_label (UNKNOWN_LOCATION);
4839 fall_thru_label = create_artificial_label (UNKNOWN_LOCATION);
4841 /* Create and initialize the index variable. */
4842 var_type = TREE_TYPE (upper);
4843 var = create_tmp_var (var_type);
4844 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, lower));
4846 /* Add the loop entry label. */
4847 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_entry_label));
4849 /* Build the reference. */
4850 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
4851 var, NULL_TREE, NULL_TREE);
4853 /* If we are a constructor, just call gimplify_init_ctor_eval to do
4854 the store. Otherwise just assign value to the reference. */
4856 if (TREE_CODE (value) == CONSTRUCTOR)
4857 /* NB we might have to call ourself recursively through
4858 gimplify_init_ctor_eval if the value is a constructor. */
4859 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
4860 pre_p, cleared);
4861 else
4863 if (gimplify_expr (&value, pre_p, NULL, is_gimple_val, fb_rvalue)
4864 != GS_ERROR)
4865 gimplify_seq_add_stmt (pre_p, gimple_build_assign (cref, value));
4868 /* We exit the loop when the index var is equal to the upper bound. */
4869 gimplify_seq_add_stmt (pre_p,
4870 gimple_build_cond (EQ_EXPR, var, upper,
4871 loop_exit_label, fall_thru_label));
4873 gimplify_seq_add_stmt (pre_p, gimple_build_label (fall_thru_label));
4875 /* Otherwise, increment the index var... */
4876 tmp = build2 (PLUS_EXPR, var_type, var,
4877 fold_convert (var_type, integer_one_node));
4878 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, tmp));
4880 /* ...and jump back to the loop entry. */
4881 gimplify_seq_add_stmt (pre_p, gimple_build_goto (loop_entry_label));
4883 /* Add the loop exit label. */
4884 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_exit_label));
4887 /* A subroutine of gimplify_init_constructor. Generate individual
4888 MODIFY_EXPRs for a CONSTRUCTOR. OBJECT is the LHS against which the
4889 assignments should happen. ELTS is the CONSTRUCTOR_ELTS of the
4890 CONSTRUCTOR. CLEARED is true if the entire LHS object has been
4891 zeroed first. */
4893 static void
4894 gimplify_init_ctor_eval (tree object, vec<constructor_elt, va_gc> *elts,
4895 gimple_seq *pre_p, bool cleared)
4897 tree array_elt_type = NULL;
4898 unsigned HOST_WIDE_INT ix;
4899 tree purpose, value;
4901 if (TREE_CODE (TREE_TYPE (object)) == ARRAY_TYPE)
4902 array_elt_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (object)));
4904 FOR_EACH_CONSTRUCTOR_ELT (elts, ix, purpose, value)
4906 tree cref;
4908 /* NULL values are created above for gimplification errors. */
4909 if (value == NULL)
4910 continue;
4912 if (cleared && initializer_zerop (value))
4913 continue;
4915 /* ??? Here's to hoping the front end fills in all of the indices,
4916 so we don't have to figure out what's missing ourselves. */
4917 gcc_assert (purpose);
4919 /* Skip zero-sized fields, unless value has side-effects. This can
4920 happen with calls to functions returning a empty type, which
4921 we shouldn't discard. As a number of downstream passes don't
4922 expect sets of empty type fields, we rely on the gimplification of
4923 the MODIFY_EXPR we make below to drop the assignment statement. */
4924 if (!TREE_SIDE_EFFECTS (value)
4925 && TREE_CODE (purpose) == FIELD_DECL
4926 && is_empty_type (TREE_TYPE (purpose)))
4927 continue;
4929 /* If we have a RANGE_EXPR, we have to build a loop to assign the
4930 whole range. */
4931 if (TREE_CODE (purpose) == RANGE_EXPR)
4933 tree lower = TREE_OPERAND (purpose, 0);
4934 tree upper = TREE_OPERAND (purpose, 1);
4936 /* If the lower bound is equal to upper, just treat it as if
4937 upper was the index. */
4938 if (simple_cst_equal (lower, upper))
4939 purpose = upper;
4940 else
4942 gimplify_init_ctor_eval_range (object, lower, upper, value,
4943 array_elt_type, pre_p, cleared);
4944 continue;
4948 if (array_elt_type)
4950 /* Do not use bitsizetype for ARRAY_REF indices. */
4951 if (TYPE_DOMAIN (TREE_TYPE (object)))
4952 purpose
4953 = fold_convert (TREE_TYPE (TYPE_DOMAIN (TREE_TYPE (object))),
4954 purpose);
4955 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
4956 purpose, NULL_TREE, NULL_TREE);
4958 else
4960 gcc_assert (TREE_CODE (purpose) == FIELD_DECL);
4961 cref = build3 (COMPONENT_REF, TREE_TYPE (purpose),
4962 unshare_expr (object), purpose, NULL_TREE);
4965 if (TREE_CODE (value) == CONSTRUCTOR
4966 && TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE)
4967 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
4968 pre_p, cleared);
4969 else
4971 tree init = build2 (INIT_EXPR, TREE_TYPE (cref), cref, value);
4972 gimplify_and_add (init, pre_p);
4973 ggc_free (init);
4978 /* Return the appropriate RHS predicate for this LHS. */
4980 gimple_predicate
4981 rhs_predicate_for (tree lhs)
4983 if (is_gimple_reg (lhs))
4984 return is_gimple_reg_rhs_or_call;
4985 else
4986 return is_gimple_mem_rhs_or_call;
4989 /* Return the initial guess for an appropriate RHS predicate for this LHS,
4990 before the LHS has been gimplified. */
4992 static gimple_predicate
4993 initial_rhs_predicate_for (tree lhs)
4995 if (is_gimple_reg_type (TREE_TYPE (lhs)))
4996 return is_gimple_reg_rhs_or_call;
4997 else
4998 return is_gimple_mem_rhs_or_call;
5001 /* Gimplify a C99 compound literal expression. This just means adding
5002 the DECL_EXPR before the current statement and using its anonymous
5003 decl instead. */
5005 static enum gimplify_status
5006 gimplify_compound_literal_expr (tree *expr_p, gimple_seq *pre_p,
5007 bool (*gimple_test_f) (tree),
5008 fallback_t fallback)
5010 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (*expr_p);
5011 tree decl = DECL_EXPR_DECL (decl_s);
5012 tree init = DECL_INITIAL (decl);
5013 /* Mark the decl as addressable if the compound literal
5014 expression is addressable now, otherwise it is marked too late
5015 after we gimplify the initialization expression. */
5016 if (TREE_ADDRESSABLE (*expr_p))
5017 TREE_ADDRESSABLE (decl) = 1;
5018 /* Otherwise, if we don't need an lvalue and have a literal directly
5019 substitute it. Check if it matches the gimple predicate, as
5020 otherwise we'd generate a new temporary, and we can as well just
5021 use the decl we already have. */
5022 else if (!TREE_ADDRESSABLE (decl)
5023 && !TREE_THIS_VOLATILE (decl)
5024 && init
5025 && (fallback & fb_lvalue) == 0
5026 && gimple_test_f (init))
5028 *expr_p = init;
5029 return GS_OK;
5032 /* If the decl is not addressable, then it is being used in some
5033 expression or on the right hand side of a statement, and it can
5034 be put into a readonly data section. */
5035 if (!TREE_ADDRESSABLE (decl) && (fallback & fb_lvalue) == 0)
5036 TREE_READONLY (decl) = 1;
5038 /* This decl isn't mentioned in the enclosing block, so add it to the
5039 list of temps. FIXME it seems a bit of a kludge to say that
5040 anonymous artificial vars aren't pushed, but everything else is. */
5041 if (DECL_NAME (decl) == NULL_TREE && !DECL_SEEN_IN_BIND_EXPR_P (decl))
5042 gimple_add_tmp_var (decl);
5044 gimplify_and_add (decl_s, pre_p);
5045 *expr_p = decl;
5046 return GS_OK;
5049 /* Optimize embedded COMPOUND_LITERAL_EXPRs within a CONSTRUCTOR,
5050 return a new CONSTRUCTOR if something changed. */
5052 static tree
5053 optimize_compound_literals_in_ctor (tree orig_ctor)
5055 tree ctor = orig_ctor;
5056 vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ctor);
5057 unsigned int idx, num = vec_safe_length (elts);
5059 for (idx = 0; idx < num; idx++)
5061 tree value = (*elts)[idx].value;
5062 tree newval = value;
5063 if (TREE_CODE (value) == CONSTRUCTOR)
5064 newval = optimize_compound_literals_in_ctor (value);
5065 else if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR)
5067 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (value);
5068 tree decl = DECL_EXPR_DECL (decl_s);
5069 tree init = DECL_INITIAL (decl);
5071 if (!TREE_ADDRESSABLE (value)
5072 && !TREE_ADDRESSABLE (decl)
5073 && init
5074 && TREE_CODE (init) == CONSTRUCTOR)
5075 newval = optimize_compound_literals_in_ctor (init);
5077 if (newval == value)
5078 continue;
5080 if (ctor == orig_ctor)
5082 ctor = copy_node (orig_ctor);
5083 CONSTRUCTOR_ELTS (ctor) = vec_safe_copy (elts);
5084 elts = CONSTRUCTOR_ELTS (ctor);
5086 (*elts)[idx].value = newval;
5088 return ctor;
5091 /* A subroutine of gimplify_modify_expr. Break out elements of a
5092 CONSTRUCTOR used as an initializer into separate MODIFY_EXPRs.
5094 Note that we still need to clear any elements that don't have explicit
5095 initializers, so if not all elements are initialized we keep the
5096 original MODIFY_EXPR, we just remove all of the constructor elements.
5098 If NOTIFY_TEMP_CREATION is true, do not gimplify, just return
5099 GS_ERROR if we would have to create a temporary when gimplifying
5100 this constructor. Otherwise, return GS_OK.
5102 If NOTIFY_TEMP_CREATION is false, just do the gimplification. */
5104 static enum gimplify_status
5105 gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
5106 bool want_value, bool notify_temp_creation)
5108 tree object, ctor, type;
5109 enum gimplify_status ret;
5110 vec<constructor_elt, va_gc> *elts;
5111 bool cleared = false;
5112 bool is_empty_ctor = false;
5113 bool is_init_expr = (TREE_CODE (*expr_p) == INIT_EXPR);
5115 gcc_assert (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == CONSTRUCTOR);
5117 if (!notify_temp_creation)
5119 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
5120 is_gimple_lvalue, fb_lvalue);
5121 if (ret == GS_ERROR)
5122 return ret;
5125 object = TREE_OPERAND (*expr_p, 0);
5126 ctor = TREE_OPERAND (*expr_p, 1)
5127 = optimize_compound_literals_in_ctor (TREE_OPERAND (*expr_p, 1));
5128 type = TREE_TYPE (ctor);
5129 elts = CONSTRUCTOR_ELTS (ctor);
5130 ret = GS_ALL_DONE;
5132 switch (TREE_CODE (type))
5134 case RECORD_TYPE:
5135 case UNION_TYPE:
5136 case QUAL_UNION_TYPE:
5137 case ARRAY_TYPE:
5139 /* Use readonly data for initializers of this or smaller size
5140 regardless of the num_nonzero_elements / num_unique_nonzero_elements
5141 ratio. */
5142 const HOST_WIDE_INT min_unique_size = 64;
5143 /* If num_nonzero_elements / num_unique_nonzero_elements ratio
5144 is smaller than this, use readonly data. */
5145 const int unique_nonzero_ratio = 8;
5146 /* True if a single access of the object must be ensured. This is the
5147 case if the target is volatile, the type is non-addressable and more
5148 than one field need to be assigned. */
5149 const bool ensure_single_access
5150 = TREE_THIS_VOLATILE (object)
5151 && !TREE_ADDRESSABLE (type)
5152 && vec_safe_length (elts) > 1;
5153 struct gimplify_init_ctor_preeval_data preeval_data;
5154 HOST_WIDE_INT num_ctor_elements, num_nonzero_elements;
5155 HOST_WIDE_INT num_unique_nonzero_elements;
5156 bool complete_p, valid_const_initializer;
5158 /* Aggregate types must lower constructors to initialization of
5159 individual elements. The exception is that a CONSTRUCTOR node
5160 with no elements indicates zero-initialization of the whole. */
5161 if (vec_safe_is_empty (elts))
5163 if (notify_temp_creation)
5164 return GS_OK;
5166 /* The var will be initialized and so appear on lhs of
5167 assignment, it can't be TREE_READONLY anymore. */
5168 if (VAR_P (object))
5169 TREE_READONLY (object) = 0;
5171 is_empty_ctor = true;
5172 break;
5175 /* Fetch information about the constructor to direct later processing.
5176 We might want to make static versions of it in various cases, and
5177 can only do so if it known to be a valid constant initializer. */
5178 valid_const_initializer
5179 = categorize_ctor_elements (ctor, &num_nonzero_elements,
5180 &num_unique_nonzero_elements,
5181 &num_ctor_elements, &complete_p);
5183 /* If a const aggregate variable is being initialized, then it
5184 should never be a lose to promote the variable to be static. */
5185 if (valid_const_initializer
5186 && num_nonzero_elements > 1
5187 && TREE_READONLY (object)
5188 && VAR_P (object)
5189 && !DECL_REGISTER (object)
5190 && (flag_merge_constants >= 2 || !TREE_ADDRESSABLE (object))
5191 /* For ctors that have many repeated nonzero elements
5192 represented through RANGE_EXPRs, prefer initializing
5193 those through runtime loops over copies of large amounts
5194 of data from readonly data section. */
5195 && (num_unique_nonzero_elements
5196 > num_nonzero_elements / unique_nonzero_ratio
5197 || ((unsigned HOST_WIDE_INT) int_size_in_bytes (type)
5198 <= (unsigned HOST_WIDE_INT) min_unique_size)))
5200 if (notify_temp_creation)
5201 return GS_ERROR;
5203 DECL_INITIAL (object) = ctor;
5204 TREE_STATIC (object) = 1;
5205 if (!DECL_NAME (object))
5206 DECL_NAME (object) = create_tmp_var_name ("C");
5207 walk_tree (&DECL_INITIAL (object), force_labels_r, NULL, NULL);
5209 /* ??? C++ doesn't automatically append a .<number> to the
5210 assembler name, and even when it does, it looks at FE private
5211 data structures to figure out what that number should be,
5212 which are not set for this variable. I suppose this is
5213 important for local statics for inline functions, which aren't
5214 "local" in the object file sense. So in order to get a unique
5215 TU-local symbol, we must invoke the lhd version now. */
5216 lhd_set_decl_assembler_name (object);
5218 *expr_p = NULL_TREE;
5219 break;
5222 /* The var will be initialized and so appear on lhs of
5223 assignment, it can't be TREE_READONLY anymore. */
5224 if (VAR_P (object) && !notify_temp_creation)
5225 TREE_READONLY (object) = 0;
5227 /* If there are "lots" of initialized elements, even discounting
5228 those that are not address constants (and thus *must* be
5229 computed at runtime), then partition the constructor into
5230 constant and non-constant parts. Block copy the constant
5231 parts in, then generate code for the non-constant parts. */
5232 /* TODO. There's code in cp/typeck.cc to do this. */
5234 if (int_size_in_bytes (TREE_TYPE (ctor)) < 0)
5235 /* store_constructor will ignore the clearing of variable-sized
5236 objects. Initializers for such objects must explicitly set
5237 every field that needs to be set. */
5238 cleared = false;
5239 else if (!complete_p)
5240 /* If the constructor isn't complete, clear the whole object
5241 beforehand, unless CONSTRUCTOR_NO_CLEARING is set on it.
5243 ??? This ought not to be needed. For any element not present
5244 in the initializer, we should simply set them to zero. Except
5245 we'd need to *find* the elements that are not present, and that
5246 requires trickery to avoid quadratic compile-time behavior in
5247 large cases or excessive memory use in small cases. */
5248 cleared = !CONSTRUCTOR_NO_CLEARING (ctor);
5249 else if (num_ctor_elements - num_nonzero_elements
5250 > CLEAR_RATIO (optimize_function_for_speed_p (cfun))
5251 && num_nonzero_elements < num_ctor_elements / 4)
5252 /* If there are "lots" of zeros, it's more efficient to clear
5253 the memory and then set the nonzero elements. */
5254 cleared = true;
5255 else if (ensure_single_access && num_nonzero_elements == 0)
5256 /* If a single access to the target must be ensured and all elements
5257 are zero, then it's optimal to clear whatever their number. */
5258 cleared = true;
5259 else
5260 cleared = false;
5262 /* If there are "lots" of initialized elements, and all of them
5263 are valid address constants, then the entire initializer can
5264 be dropped to memory, and then memcpy'd out. Don't do this
5265 for sparse arrays, though, as it's more efficient to follow
5266 the standard CONSTRUCTOR behavior of memset followed by
5267 individual element initialization. Also don't do this for small
5268 all-zero initializers (which aren't big enough to merit
5269 clearing), and don't try to make bitwise copies of
5270 TREE_ADDRESSABLE types. */
5271 if (valid_const_initializer
5272 && complete_p
5273 && !(cleared || num_nonzero_elements == 0)
5274 && !TREE_ADDRESSABLE (type))
5276 HOST_WIDE_INT size = int_size_in_bytes (type);
5277 unsigned int align;
5279 /* ??? We can still get unbounded array types, at least
5280 from the C++ front end. This seems wrong, but attempt
5281 to work around it for now. */
5282 if (size < 0)
5284 size = int_size_in_bytes (TREE_TYPE (object));
5285 if (size >= 0)
5286 TREE_TYPE (ctor) = type = TREE_TYPE (object);
5289 /* Find the maximum alignment we can assume for the object. */
5290 /* ??? Make use of DECL_OFFSET_ALIGN. */
5291 if (DECL_P (object))
5292 align = DECL_ALIGN (object);
5293 else
5294 align = TYPE_ALIGN (type);
5296 /* Do a block move either if the size is so small as to make
5297 each individual move a sub-unit move on average, or if it
5298 is so large as to make individual moves inefficient. */
5299 if (size > 0
5300 && num_nonzero_elements > 1
5301 /* For ctors that have many repeated nonzero elements
5302 represented through RANGE_EXPRs, prefer initializing
5303 those through runtime loops over copies of large amounts
5304 of data from readonly data section. */
5305 && (num_unique_nonzero_elements
5306 > num_nonzero_elements / unique_nonzero_ratio
5307 || size <= min_unique_size)
5308 && (size < num_nonzero_elements
5309 || !can_move_by_pieces (size, align)))
5311 if (notify_temp_creation)
5312 return GS_ERROR;
5314 walk_tree (&ctor, force_labels_r, NULL, NULL);
5315 ctor = tree_output_constant_def (ctor);
5316 if (!useless_type_conversion_p (type, TREE_TYPE (ctor)))
5317 ctor = build1 (VIEW_CONVERT_EXPR, type, ctor);
5318 TREE_OPERAND (*expr_p, 1) = ctor;
5320 /* This is no longer an assignment of a CONSTRUCTOR, but
5321 we still may have processing to do on the LHS. So
5322 pretend we didn't do anything here to let that happen. */
5323 return GS_UNHANDLED;
5327 /* If a single access to the target must be ensured and there are
5328 nonzero elements or the zero elements are not assigned en masse,
5329 initialize the target from a temporary. */
5330 if (ensure_single_access && (num_nonzero_elements > 0 || !cleared))
5332 if (notify_temp_creation)
5333 return GS_ERROR;
5335 tree temp = create_tmp_var (TYPE_MAIN_VARIANT (type));
5336 TREE_OPERAND (*expr_p, 0) = temp;
5337 *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p),
5338 *expr_p,
5339 build2 (MODIFY_EXPR, void_type_node,
5340 object, temp));
5341 return GS_OK;
5344 if (notify_temp_creation)
5345 return GS_OK;
5347 /* If there are nonzero elements and if needed, pre-evaluate to capture
5348 elements overlapping with the lhs into temporaries. We must do this
5349 before clearing to fetch the values before they are zeroed-out. */
5350 if (num_nonzero_elements > 0 && TREE_CODE (*expr_p) != INIT_EXPR)
5352 preeval_data.lhs_base_decl = get_base_address (object);
5353 if (!DECL_P (preeval_data.lhs_base_decl))
5354 preeval_data.lhs_base_decl = NULL;
5355 preeval_data.lhs_alias_set = get_alias_set (object);
5357 gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p, 1),
5358 pre_p, post_p, &preeval_data);
5361 bool ctor_has_side_effects_p
5362 = TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p, 1));
5364 if (cleared)
5366 /* Zap the CONSTRUCTOR element list, which simplifies this case.
5367 Note that we still have to gimplify, in order to handle the
5368 case of variable sized types. Avoid shared tree structures. */
5369 CONSTRUCTOR_ELTS (ctor) = NULL;
5370 TREE_SIDE_EFFECTS (ctor) = 0;
5371 object = unshare_expr (object);
5372 gimplify_stmt (expr_p, pre_p);
5375 /* If we have not block cleared the object, or if there are nonzero
5376 elements in the constructor, or if the constructor has side effects,
5377 add assignments to the individual scalar fields of the object. */
5378 if (!cleared
5379 || num_nonzero_elements > 0
5380 || ctor_has_side_effects_p)
5381 gimplify_init_ctor_eval (object, elts, pre_p, cleared);
5383 *expr_p = NULL_TREE;
5385 break;
5387 case COMPLEX_TYPE:
5389 tree r, i;
5391 if (notify_temp_creation)
5392 return GS_OK;
5394 /* Extract the real and imaginary parts out of the ctor. */
5395 gcc_assert (elts->length () == 2);
5396 r = (*elts)[0].value;
5397 i = (*elts)[1].value;
5398 if (r == NULL || i == NULL)
5400 tree zero = build_zero_cst (TREE_TYPE (type));
5401 if (r == NULL)
5402 r = zero;
5403 if (i == NULL)
5404 i = zero;
5407 /* Complex types have either COMPLEX_CST or COMPLEX_EXPR to
5408 represent creation of a complex value. */
5409 if (TREE_CONSTANT (r) && TREE_CONSTANT (i))
5411 ctor = build_complex (type, r, i);
5412 TREE_OPERAND (*expr_p, 1) = ctor;
5414 else
5416 ctor = build2 (COMPLEX_EXPR, type, r, i);
5417 TREE_OPERAND (*expr_p, 1) = ctor;
5418 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 1),
5419 pre_p,
5420 post_p,
5421 rhs_predicate_for (TREE_OPERAND (*expr_p, 0)),
5422 fb_rvalue);
5425 break;
5427 case VECTOR_TYPE:
5429 unsigned HOST_WIDE_INT ix;
5430 constructor_elt *ce;
5432 if (notify_temp_creation)
5433 return GS_OK;
5435 /* Vector types use CONSTRUCTOR all the way through gimple
5436 compilation as a general initializer. */
5437 FOR_EACH_VEC_SAFE_ELT (elts, ix, ce)
5439 enum gimplify_status tret;
5440 tret = gimplify_expr (&ce->value, pre_p, post_p, is_gimple_val,
5441 fb_rvalue);
5442 if (tret == GS_ERROR)
5443 ret = GS_ERROR;
5444 else if (TREE_STATIC (ctor)
5445 && !initializer_constant_valid_p (ce->value,
5446 TREE_TYPE (ce->value)))
5447 TREE_STATIC (ctor) = 0;
5449 recompute_constructor_flags (ctor);
5451 /* Go ahead and simplify constant constructors to VECTOR_CST. */
5452 if (TREE_CONSTANT (ctor))
5454 bool constant_p = true;
5455 tree value;
5457 /* Even when ctor is constant, it might contain non-*_CST
5458 elements, such as addresses or trapping values like
5459 1.0/0.0 - 1.0/0.0. Such expressions don't belong
5460 in VECTOR_CST nodes. */
5461 FOR_EACH_CONSTRUCTOR_VALUE (elts, ix, value)
5462 if (!CONSTANT_CLASS_P (value))
5464 constant_p = false;
5465 break;
5468 if (constant_p)
5470 TREE_OPERAND (*expr_p, 1) = build_vector_from_ctor (type, elts);
5471 break;
5475 if (!is_gimple_reg (TREE_OPERAND (*expr_p, 0)))
5476 TREE_OPERAND (*expr_p, 1) = get_formal_tmp_var (ctor, pre_p);
5478 break;
5480 default:
5481 /* So how did we get a CONSTRUCTOR for a scalar type? */
5482 gcc_unreachable ();
5485 if (ret == GS_ERROR)
5486 return GS_ERROR;
5487 /* If we have gimplified both sides of the initializer but have
5488 not emitted an assignment, do so now. */
5489 if (*expr_p)
5491 tree lhs = TREE_OPERAND (*expr_p, 0);
5492 tree rhs = TREE_OPERAND (*expr_p, 1);
5493 if (want_value && object == lhs)
5494 lhs = unshare_expr (lhs);
5495 gassign *init = gimple_build_assign (lhs, rhs);
5496 gimplify_seq_add_stmt (pre_p, init);
5498 if (want_value)
5500 *expr_p = object;
5501 ret = GS_OK;
5503 else
5505 *expr_p = NULL;
5506 ret = GS_ALL_DONE;
5509 /* If the user requests to initialize automatic variables, we
5510 should initialize paddings inside the variable. Add a call to
5511 __builtin_clear_pading (&object, 0, for_auto_init = true) to
5512 initialize paddings of object always to zero regardless of
5513 INIT_TYPE. Note, we will not insert this call if the aggregate
5514 variable has be completely cleared already or it's initialized
5515 with an empty constructor. We cannot insert this call if the
5516 variable is a gimple register since __builtin_clear_padding will take
5517 the address of the variable. As a result, if a long double/_Complex long
5518 double variable will be spilled into stack later, its padding cannot
5519 be cleared with __builtin_clear_padding. We should clear its padding
5520 when it is spilled into memory. */
5521 if (is_init_expr
5522 && !is_gimple_reg (object)
5523 && clear_padding_type_may_have_padding_p (type)
5524 && ((AGGREGATE_TYPE_P (type) && !cleared && !is_empty_ctor)
5525 || !AGGREGATE_TYPE_P (type))
5526 && is_var_need_auto_init (object))
5527 gimple_add_padding_init_for_auto_var (object, false, pre_p);
5529 return ret;
5532 /* Given a pointer value OP0, return a simplified version of an
5533 indirection through OP0, or NULL_TREE if no simplification is
5534 possible. This may only be applied to a rhs of an expression.
5535 Note that the resulting type may be different from the type pointed
5536 to in the sense that it is still compatible from the langhooks
5537 point of view. */
5539 static tree
5540 gimple_fold_indirect_ref_rhs (tree t)
5542 return gimple_fold_indirect_ref (t);
5545 /* Subroutine of gimplify_modify_expr to do simplifications of
5546 MODIFY_EXPRs based on the code of the RHS. We loop for as long as
5547 something changes. */
5549 static enum gimplify_status
5550 gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p,
5551 gimple_seq *pre_p, gimple_seq *post_p,
5552 bool want_value)
5554 enum gimplify_status ret = GS_UNHANDLED;
5555 bool changed;
5559 changed = false;
5560 switch (TREE_CODE (*from_p))
5562 case VAR_DECL:
5563 /* If we're assigning from a read-only variable initialized with
5564 a constructor and not volatile, do the direct assignment from
5565 the constructor, but only if the target is not volatile either
5566 since this latter assignment might end up being done on a per
5567 field basis. However, if the target is volatile and the type
5568 is aggregate and non-addressable, gimplify_init_constructor
5569 knows that it needs to ensure a single access to the target
5570 and it will return GS_OK only in this case. */
5571 if (TREE_READONLY (*from_p)
5572 && DECL_INITIAL (*from_p)
5573 && TREE_CODE (DECL_INITIAL (*from_p)) == CONSTRUCTOR
5574 && !TREE_THIS_VOLATILE (*from_p)
5575 && (!TREE_THIS_VOLATILE (*to_p)
5576 || (AGGREGATE_TYPE_P (TREE_TYPE (*to_p))
5577 && !TREE_ADDRESSABLE (TREE_TYPE (*to_p)))))
5579 tree old_from = *from_p;
5580 enum gimplify_status subret;
5582 /* Move the constructor into the RHS. */
5583 *from_p = unshare_expr (DECL_INITIAL (*from_p));
5585 /* Let's see if gimplify_init_constructor will need to put
5586 it in memory. */
5587 subret = gimplify_init_constructor (expr_p, NULL, NULL,
5588 false, true);
5589 if (subret == GS_ERROR)
5591 /* If so, revert the change. */
5592 *from_p = old_from;
5594 else
5596 ret = GS_OK;
5597 changed = true;
5600 break;
5601 case INDIRECT_REF:
5603 /* If we have code like
5605 *(const A*)(A*)&x
5607 where the type of "x" is a (possibly cv-qualified variant
5608 of "A"), treat the entire expression as identical to "x".
5609 This kind of code arises in C++ when an object is bound
5610 to a const reference, and if "x" is a TARGET_EXPR we want
5611 to take advantage of the optimization below. */
5612 bool volatile_p = TREE_THIS_VOLATILE (*from_p);
5613 tree t = gimple_fold_indirect_ref_rhs (TREE_OPERAND (*from_p, 0));
5614 if (t)
5616 if (TREE_THIS_VOLATILE (t) != volatile_p)
5618 if (DECL_P (t))
5619 t = build_simple_mem_ref_loc (EXPR_LOCATION (*from_p),
5620 build_fold_addr_expr (t));
5621 if (REFERENCE_CLASS_P (t))
5622 TREE_THIS_VOLATILE (t) = volatile_p;
5624 *from_p = t;
5625 ret = GS_OK;
5626 changed = true;
5628 break;
5631 case TARGET_EXPR:
5633 /* If we are initializing something from a TARGET_EXPR, strip the
5634 TARGET_EXPR and initialize it directly, if possible. This can't
5635 be done if the initializer is void, since that implies that the
5636 temporary is set in some non-trivial way.
5638 ??? What about code that pulls out the temp and uses it
5639 elsewhere? I think that such code never uses the TARGET_EXPR as
5640 an initializer. If I'm wrong, we'll die because the temp won't
5641 have any RTL. In that case, I guess we'll need to replace
5642 references somehow. */
5643 tree init = TARGET_EXPR_INITIAL (*from_p);
5645 if (init
5646 && (TREE_CODE (*expr_p) != MODIFY_EXPR
5647 || !TARGET_EXPR_NO_ELIDE (*from_p))
5648 && !VOID_TYPE_P (TREE_TYPE (init)))
5650 *from_p = init;
5651 ret = GS_OK;
5652 changed = true;
5655 break;
5657 case COMPOUND_EXPR:
5658 /* Remove any COMPOUND_EXPR in the RHS so the following cases will be
5659 caught. */
5660 gimplify_compound_expr (from_p, pre_p, true);
5661 ret = GS_OK;
5662 changed = true;
5663 break;
5665 case CONSTRUCTOR:
5666 /* If we already made some changes, let the front end have a
5667 crack at this before we break it down. */
5668 if (ret != GS_UNHANDLED)
5669 break;
5671 /* If we're initializing from a CONSTRUCTOR, break this into
5672 individual MODIFY_EXPRs. */
5673 ret = gimplify_init_constructor (expr_p, pre_p, post_p, want_value,
5674 false);
5675 return ret;
5677 case COND_EXPR:
5678 /* If we're assigning to a non-register type, push the assignment
5679 down into the branches. This is mandatory for ADDRESSABLE types,
5680 since we cannot generate temporaries for such, but it saves a
5681 copy in other cases as well. */
5682 if (!is_gimple_reg_type (TREE_TYPE (*from_p)))
5684 /* This code should mirror the code in gimplify_cond_expr. */
5685 enum tree_code code = TREE_CODE (*expr_p);
5686 tree cond = *from_p;
5687 tree result = *to_p;
5689 ret = gimplify_expr (&result, pre_p, post_p,
5690 is_gimple_lvalue, fb_lvalue);
5691 if (ret != GS_ERROR)
5692 ret = GS_OK;
5694 /* If we are going to write RESULT more than once, clear
5695 TREE_READONLY flag, otherwise we might incorrectly promote
5696 the variable to static const and initialize it at compile
5697 time in one of the branches. */
5698 if (VAR_P (result)
5699 && TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node
5700 && TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
5701 TREE_READONLY (result) = 0;
5702 if (TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node)
5703 TREE_OPERAND (cond, 1)
5704 = build2 (code, void_type_node, result,
5705 TREE_OPERAND (cond, 1));
5706 if (TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
5707 TREE_OPERAND (cond, 2)
5708 = build2 (code, void_type_node, unshare_expr (result),
5709 TREE_OPERAND (cond, 2));
5711 TREE_TYPE (cond) = void_type_node;
5712 recalculate_side_effects (cond);
5714 if (want_value)
5716 gimplify_and_add (cond, pre_p);
5717 *expr_p = unshare_expr (result);
5719 else
5720 *expr_p = cond;
5721 return ret;
5723 break;
5725 case CALL_EXPR:
5726 /* For calls that return in memory, give *to_p as the CALL_EXPR's
5727 return slot so that we don't generate a temporary. */
5728 if (!CALL_EXPR_RETURN_SLOT_OPT (*from_p)
5729 && aggregate_value_p (*from_p, *from_p))
5731 bool use_target;
5733 if (!(rhs_predicate_for (*to_p))(*from_p))
5734 /* If we need a temporary, *to_p isn't accurate. */
5735 use_target = false;
5736 /* It's OK to use the return slot directly unless it's an NRV. */
5737 else if (TREE_CODE (*to_p) == RESULT_DECL
5738 && DECL_NAME (*to_p) == NULL_TREE
5739 && needs_to_live_in_memory (*to_p))
5740 use_target = true;
5741 else if (is_gimple_reg_type (TREE_TYPE (*to_p))
5742 || (DECL_P (*to_p) && DECL_REGISTER (*to_p)))
5743 /* Don't force regs into memory. */
5744 use_target = false;
5745 else if (TREE_CODE (*expr_p) == INIT_EXPR)
5746 /* It's OK to use the target directly if it's being
5747 initialized. */
5748 use_target = true;
5749 else if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p)))
5750 != INTEGER_CST)
5751 /* Always use the target and thus RSO for variable-sized types.
5752 GIMPLE cannot deal with a variable-sized assignment
5753 embedded in a call statement. */
5754 use_target = true;
5755 else if (TREE_CODE (*to_p) != SSA_NAME
5756 && (!is_gimple_variable (*to_p)
5757 || needs_to_live_in_memory (*to_p)))
5758 /* Don't use the original target if it's already addressable;
5759 if its address escapes, and the called function uses the
5760 NRV optimization, a conforming program could see *to_p
5761 change before the called function returns; see c++/19317.
5762 When optimizing, the return_slot pass marks more functions
5763 as safe after we have escape info. */
5764 use_target = false;
5765 else
5766 use_target = true;
5768 if (use_target)
5770 CALL_EXPR_RETURN_SLOT_OPT (*from_p) = 1;
5771 mark_addressable (*to_p);
5774 break;
5776 case WITH_SIZE_EXPR:
5777 /* Likewise for calls that return an aggregate of non-constant size,
5778 since we would not be able to generate a temporary at all. */
5779 if (TREE_CODE (TREE_OPERAND (*from_p, 0)) == CALL_EXPR)
5781 *from_p = TREE_OPERAND (*from_p, 0);
5782 /* We don't change ret in this case because the
5783 WITH_SIZE_EXPR might have been added in
5784 gimplify_modify_expr, so returning GS_OK would lead to an
5785 infinite loop. */
5786 changed = true;
5788 break;
5790 /* If we're initializing from a container, push the initialization
5791 inside it. */
5792 case CLEANUP_POINT_EXPR:
5793 case BIND_EXPR:
5794 case STATEMENT_LIST:
5796 tree wrap = *from_p;
5797 tree t;
5799 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_min_lval,
5800 fb_lvalue);
5801 if (ret != GS_ERROR)
5802 ret = GS_OK;
5804 t = voidify_wrapper_expr (wrap, *expr_p);
5805 gcc_assert (t == *expr_p);
5807 if (want_value)
5809 gimplify_and_add (wrap, pre_p);
5810 *expr_p = unshare_expr (*to_p);
5812 else
5813 *expr_p = wrap;
5814 return GS_OK;
5817 case NOP_EXPR:
5818 /* Pull out compound literal expressions from a NOP_EXPR.
5819 Those are created in the C FE to drop qualifiers during
5820 lvalue conversion. */
5821 if ((TREE_CODE (TREE_OPERAND (*from_p, 0)) == COMPOUND_LITERAL_EXPR)
5822 && tree_ssa_useless_type_conversion (*from_p))
5824 *from_p = TREE_OPERAND (*from_p, 0);
5825 ret = GS_OK;
5826 changed = true;
5828 break;
5830 case COMPOUND_LITERAL_EXPR:
5832 tree complit = TREE_OPERAND (*expr_p, 1);
5833 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (complit);
5834 tree decl = DECL_EXPR_DECL (decl_s);
5835 tree init = DECL_INITIAL (decl);
5837 /* struct T x = (struct T) { 0, 1, 2 } can be optimized
5838 into struct T x = { 0, 1, 2 } if the address of the
5839 compound literal has never been taken. */
5840 if (!TREE_ADDRESSABLE (complit)
5841 && !TREE_ADDRESSABLE (decl)
5842 && init)
5844 *expr_p = copy_node (*expr_p);
5845 TREE_OPERAND (*expr_p, 1) = init;
5846 return GS_OK;
5850 default:
5851 break;
5854 while (changed);
5856 return ret;
5860 /* Return true if T looks like a valid GIMPLE statement. */
5862 static bool
5863 is_gimple_stmt (tree t)
5865 const enum tree_code code = TREE_CODE (t);
5867 switch (code)
5869 case NOP_EXPR:
5870 /* The only valid NOP_EXPR is the empty statement. */
5871 return IS_EMPTY_STMT (t);
5873 case BIND_EXPR:
5874 case COND_EXPR:
5875 /* These are only valid if they're void. */
5876 return TREE_TYPE (t) == NULL || VOID_TYPE_P (TREE_TYPE (t));
5878 case SWITCH_EXPR:
5879 case GOTO_EXPR:
5880 case RETURN_EXPR:
5881 case LABEL_EXPR:
5882 case CASE_LABEL_EXPR:
5883 case TRY_CATCH_EXPR:
5884 case TRY_FINALLY_EXPR:
5885 case EH_FILTER_EXPR:
5886 case CATCH_EXPR:
5887 case ASM_EXPR:
5888 case STATEMENT_LIST:
5889 case OACC_PARALLEL:
5890 case OACC_KERNELS:
5891 case OACC_SERIAL:
5892 case OACC_DATA:
5893 case OACC_HOST_DATA:
5894 case OACC_DECLARE:
5895 case OACC_UPDATE:
5896 case OACC_ENTER_DATA:
5897 case OACC_EXIT_DATA:
5898 case OACC_CACHE:
5899 case OMP_PARALLEL:
5900 case OMP_FOR:
5901 case OMP_SIMD:
5902 case OMP_DISTRIBUTE:
5903 case OMP_LOOP:
5904 case OACC_LOOP:
5905 case OMP_SCAN:
5906 case OMP_SCOPE:
5907 case OMP_SECTIONS:
5908 case OMP_SECTION:
5909 case OMP_SINGLE:
5910 case OMP_MASTER:
5911 case OMP_MASKED:
5912 case OMP_TASKGROUP:
5913 case OMP_ORDERED:
5914 case OMP_CRITICAL:
5915 case OMP_TASK:
5916 case OMP_TARGET:
5917 case OMP_TARGET_DATA:
5918 case OMP_TARGET_UPDATE:
5919 case OMP_TARGET_ENTER_DATA:
5920 case OMP_TARGET_EXIT_DATA:
5921 case OMP_TASKLOOP:
5922 case OMP_TEAMS:
5923 /* These are always void. */
5924 return true;
5926 case CALL_EXPR:
5927 case MODIFY_EXPR:
5928 case PREDICT_EXPR:
5929 /* These are valid regardless of their type. */
5930 return true;
5932 default:
5933 return false;
5938 /* Promote partial stores to COMPLEX variables to total stores. *EXPR_P is
5939 a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a gimple register.
5941 IMPORTANT NOTE: This promotion is performed by introducing a load of the
5942 other, unmodified part of the complex object just before the total store.
5943 As a consequence, if the object is still uninitialized, an undefined value
5944 will be loaded into a register, which may result in a spurious exception
5945 if the register is floating-point and the value happens to be a signaling
5946 NaN for example. Then the fully-fledged complex operations lowering pass
5947 followed by a DCE pass are necessary in order to fix things up. */
5949 static enum gimplify_status
5950 gimplify_modify_expr_complex_part (tree *expr_p, gimple_seq *pre_p,
5951 bool want_value)
5953 enum tree_code code, ocode;
5954 tree lhs, rhs, new_rhs, other, realpart, imagpart;
5956 lhs = TREE_OPERAND (*expr_p, 0);
5957 rhs = TREE_OPERAND (*expr_p, 1);
5958 code = TREE_CODE (lhs);
5959 lhs = TREE_OPERAND (lhs, 0);
5961 ocode = code == REALPART_EXPR ? IMAGPART_EXPR : REALPART_EXPR;
5962 other = build1 (ocode, TREE_TYPE (rhs), lhs);
5963 suppress_warning (other);
5964 other = get_formal_tmp_var (other, pre_p);
5966 realpart = code == REALPART_EXPR ? rhs : other;
5967 imagpart = code == REALPART_EXPR ? other : rhs;
5969 if (TREE_CONSTANT (realpart) && TREE_CONSTANT (imagpart))
5970 new_rhs = build_complex (TREE_TYPE (lhs), realpart, imagpart);
5971 else
5972 new_rhs = build2 (COMPLEX_EXPR, TREE_TYPE (lhs), realpart, imagpart);
5974 gimplify_seq_add_stmt (pre_p, gimple_build_assign (lhs, new_rhs));
5975 *expr_p = (want_value) ? rhs : NULL_TREE;
5977 return GS_ALL_DONE;
5980 /* Gimplify the MODIFY_EXPR node pointed to by EXPR_P.
5982 modify_expr
5983 : varname '=' rhs
5984 | '*' ID '=' rhs
5986 PRE_P points to the list where side effects that must happen before
5987 *EXPR_P should be stored.
5989 POST_P points to the list where side effects that must happen after
5990 *EXPR_P should be stored.
5992 WANT_VALUE is nonzero iff we want to use the value of this expression
5993 in another expression. */
5995 static enum gimplify_status
5996 gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
5997 bool want_value)
5999 tree *from_p = &TREE_OPERAND (*expr_p, 1);
6000 tree *to_p = &TREE_OPERAND (*expr_p, 0);
6001 enum gimplify_status ret = GS_UNHANDLED;
6002 gimple *assign;
6003 location_t loc = EXPR_LOCATION (*expr_p);
6004 gimple_stmt_iterator gsi;
6006 gcc_assert (TREE_CODE (*expr_p) == MODIFY_EXPR
6007 || TREE_CODE (*expr_p) == INIT_EXPR);
6009 /* Trying to simplify a clobber using normal logic doesn't work,
6010 so handle it here. */
6011 if (TREE_CLOBBER_P (*from_p))
6013 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
6014 if (ret == GS_ERROR)
6015 return ret;
6016 gcc_assert (!want_value);
6017 if (!VAR_P (*to_p) && TREE_CODE (*to_p) != MEM_REF)
6019 tree addr = get_initialized_tmp_var (build_fold_addr_expr (*to_p),
6020 pre_p, post_p);
6021 *to_p = build_simple_mem_ref_loc (EXPR_LOCATION (*to_p), addr);
6023 gimplify_seq_add_stmt (pre_p, gimple_build_assign (*to_p, *from_p));
6024 *expr_p = NULL;
6025 return GS_ALL_DONE;
6028 /* Insert pointer conversions required by the middle-end that are not
6029 required by the frontend. This fixes middle-end type checking for
6030 for example gcc.dg/redecl-6.c. */
6031 if (POINTER_TYPE_P (TREE_TYPE (*to_p)))
6033 STRIP_USELESS_TYPE_CONVERSION (*from_p);
6034 if (!useless_type_conversion_p (TREE_TYPE (*to_p), TREE_TYPE (*from_p)))
6035 *from_p = fold_convert_loc (loc, TREE_TYPE (*to_p), *from_p);
6038 /* See if any simplifications can be done based on what the RHS is. */
6039 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
6040 want_value);
6041 if (ret != GS_UNHANDLED)
6042 return ret;
6044 /* For empty types only gimplify the left hand side and right hand
6045 side as statements and throw away the assignment. Do this after
6046 gimplify_modify_expr_rhs so we handle TARGET_EXPRs of addressable
6047 types properly. */
6048 if (is_empty_type (TREE_TYPE (*from_p))
6049 && !want_value
6050 /* Don't do this for calls that return addressable types, expand_call
6051 relies on those having a lhs. */
6052 && !(TREE_ADDRESSABLE (TREE_TYPE (*from_p))
6053 && TREE_CODE (*from_p) == CALL_EXPR))
6055 gimplify_stmt (from_p, pre_p);
6056 gimplify_stmt (to_p, pre_p);
6057 *expr_p = NULL_TREE;
6058 return GS_ALL_DONE;
6061 /* If the value being copied is of variable width, compute the length
6062 of the copy into a WITH_SIZE_EXPR. Note that we need to do this
6063 before gimplifying any of the operands so that we can resolve any
6064 PLACEHOLDER_EXPRs in the size. Also note that the RTL expander uses
6065 the size of the expression to be copied, not of the destination, so
6066 that is what we must do here. */
6067 maybe_with_size_expr (from_p);
6069 /* As a special case, we have to temporarily allow for assignments
6070 with a CALL_EXPR on the RHS. Since in GIMPLE a function call is
6071 a toplevel statement, when gimplifying the GENERIC expression
6072 MODIFY_EXPR <a, CALL_EXPR <foo>>, we cannot create the tuple
6073 GIMPLE_ASSIGN <a, GIMPLE_CALL <foo>>.
6075 Instead, we need to create the tuple GIMPLE_CALL <a, foo>. To
6076 prevent gimplify_expr from trying to create a new temporary for
6077 foo's LHS, we tell it that it should only gimplify until it
6078 reaches the CALL_EXPR. On return from gimplify_expr, the newly
6079 created GIMPLE_CALL <foo> will be the last statement in *PRE_P
6080 and all we need to do here is set 'a' to be its LHS. */
6082 /* Gimplify the RHS first for C++17 and bug 71104. */
6083 gimple_predicate initial_pred = initial_rhs_predicate_for (*to_p);
6084 ret = gimplify_expr (from_p, pre_p, post_p, initial_pred, fb_rvalue);
6085 if (ret == GS_ERROR)
6086 return ret;
6088 /* Then gimplify the LHS. */
6089 /* If we gimplified the RHS to a CALL_EXPR and that call may return
6090 twice we have to make sure to gimplify into non-SSA as otherwise
6091 the abnormal edge added later will make those defs not dominate
6092 their uses.
6093 ??? Technically this applies only to the registers used in the
6094 resulting non-register *TO_P. */
6095 bool saved_into_ssa = gimplify_ctxp->into_ssa;
6096 if (saved_into_ssa
6097 && TREE_CODE (*from_p) == CALL_EXPR
6098 && call_expr_flags (*from_p) & ECF_RETURNS_TWICE)
6099 gimplify_ctxp->into_ssa = false;
6100 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
6101 gimplify_ctxp->into_ssa = saved_into_ssa;
6102 if (ret == GS_ERROR)
6103 return ret;
6105 /* Now that the LHS is gimplified, re-gimplify the RHS if our initial
6106 guess for the predicate was wrong. */
6107 gimple_predicate final_pred = rhs_predicate_for (*to_p);
6108 if (final_pred != initial_pred)
6110 ret = gimplify_expr (from_p, pre_p, post_p, final_pred, fb_rvalue);
6111 if (ret == GS_ERROR)
6112 return ret;
6115 /* In case of va_arg internal fn wrappped in a WITH_SIZE_EXPR, add the type
6116 size as argument to the call. */
6117 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
6119 tree call = TREE_OPERAND (*from_p, 0);
6120 tree vlasize = TREE_OPERAND (*from_p, 1);
6122 if (TREE_CODE (call) == CALL_EXPR
6123 && CALL_EXPR_IFN (call) == IFN_VA_ARG)
6125 int nargs = call_expr_nargs (call);
6126 tree type = TREE_TYPE (call);
6127 tree ap = CALL_EXPR_ARG (call, 0);
6128 tree tag = CALL_EXPR_ARG (call, 1);
6129 tree aptag = CALL_EXPR_ARG (call, 2);
6130 tree newcall = build_call_expr_internal_loc (EXPR_LOCATION (call),
6131 IFN_VA_ARG, type,
6132 nargs + 1, ap, tag,
6133 aptag, vlasize);
6134 TREE_OPERAND (*from_p, 0) = newcall;
6138 /* Now see if the above changed *from_p to something we handle specially. */
6139 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
6140 want_value);
6141 if (ret != GS_UNHANDLED)
6142 return ret;
6144 /* If we've got a variable sized assignment between two lvalues (i.e. does
6145 not involve a call), then we can make things a bit more straightforward
6146 by converting the assignment to memcpy or memset. */
6147 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
6149 tree from = TREE_OPERAND (*from_p, 0);
6150 tree size = TREE_OPERAND (*from_p, 1);
6152 if (TREE_CODE (from) == CONSTRUCTOR)
6153 return gimplify_modify_expr_to_memset (expr_p, size, want_value, pre_p);
6155 if (is_gimple_addressable (from))
6157 *from_p = from;
6158 return gimplify_modify_expr_to_memcpy (expr_p, size, want_value,
6159 pre_p);
6163 /* Transform partial stores to non-addressable complex variables into
6164 total stores. This allows us to use real instead of virtual operands
6165 for these variables, which improves optimization. */
6166 if ((TREE_CODE (*to_p) == REALPART_EXPR
6167 || TREE_CODE (*to_p) == IMAGPART_EXPR)
6168 && is_gimple_reg (TREE_OPERAND (*to_p, 0)))
6169 return gimplify_modify_expr_complex_part (expr_p, pre_p, want_value);
6171 /* Try to alleviate the effects of the gimplification creating artificial
6172 temporaries (see for example is_gimple_reg_rhs) on the debug info, but
6173 make sure not to create DECL_DEBUG_EXPR links across functions. */
6174 if (!gimplify_ctxp->into_ssa
6175 && VAR_P (*from_p)
6176 && DECL_IGNORED_P (*from_p)
6177 && DECL_P (*to_p)
6178 && !DECL_IGNORED_P (*to_p)
6179 && decl_function_context (*to_p) == current_function_decl
6180 && decl_function_context (*from_p) == current_function_decl)
6182 if (!DECL_NAME (*from_p) && DECL_NAME (*to_p))
6183 DECL_NAME (*from_p)
6184 = create_tmp_var_name (IDENTIFIER_POINTER (DECL_NAME (*to_p)));
6185 DECL_HAS_DEBUG_EXPR_P (*from_p) = 1;
6186 SET_DECL_DEBUG_EXPR (*from_p, *to_p);
6189 if (want_value && TREE_THIS_VOLATILE (*to_p))
6190 *from_p = get_initialized_tmp_var (*from_p, pre_p, post_p);
6192 if (TREE_CODE (*from_p) == CALL_EXPR)
6194 /* Since the RHS is a CALL_EXPR, we need to create a GIMPLE_CALL
6195 instead of a GIMPLE_ASSIGN. */
6196 gcall *call_stmt;
6197 if (CALL_EXPR_FN (*from_p) == NULL_TREE)
6199 /* Gimplify internal functions created in the FEs. */
6200 int nargs = call_expr_nargs (*from_p), i;
6201 enum internal_fn ifn = CALL_EXPR_IFN (*from_p);
6202 auto_vec<tree> vargs (nargs);
6204 for (i = 0; i < nargs; i++)
6206 gimplify_arg (&CALL_EXPR_ARG (*from_p, i), pre_p,
6207 EXPR_LOCATION (*from_p));
6208 vargs.quick_push (CALL_EXPR_ARG (*from_p, i));
6210 call_stmt = gimple_build_call_internal_vec (ifn, vargs);
6211 gimple_call_set_nothrow (call_stmt, TREE_NOTHROW (*from_p));
6212 gimple_set_location (call_stmt, EXPR_LOCATION (*expr_p));
6214 else
6216 tree fnptrtype = TREE_TYPE (CALL_EXPR_FN (*from_p));
6217 CALL_EXPR_FN (*from_p) = TREE_OPERAND (CALL_EXPR_FN (*from_p), 0);
6218 STRIP_USELESS_TYPE_CONVERSION (CALL_EXPR_FN (*from_p));
6219 tree fndecl = get_callee_fndecl (*from_p);
6220 if (fndecl
6221 && fndecl_built_in_p (fndecl, BUILT_IN_EXPECT)
6222 && call_expr_nargs (*from_p) == 3)
6223 call_stmt = gimple_build_call_internal (IFN_BUILTIN_EXPECT, 3,
6224 CALL_EXPR_ARG (*from_p, 0),
6225 CALL_EXPR_ARG (*from_p, 1),
6226 CALL_EXPR_ARG (*from_p, 2));
6227 else
6229 call_stmt = gimple_build_call_from_tree (*from_p, fnptrtype);
6232 notice_special_calls (call_stmt);
6233 if (!gimple_call_noreturn_p (call_stmt) || !should_remove_lhs_p (*to_p))
6234 gimple_call_set_lhs (call_stmt, *to_p);
6235 else if (TREE_CODE (*to_p) == SSA_NAME)
6236 /* The above is somewhat premature, avoid ICEing later for a
6237 SSA name w/o a definition. We may have uses in the GIMPLE IL.
6238 ??? This doesn't make it a default-def. */
6239 SSA_NAME_DEF_STMT (*to_p) = gimple_build_nop ();
6241 assign = call_stmt;
6243 else
6245 assign = gimple_build_assign (*to_p, *from_p);
6246 gimple_set_location (assign, EXPR_LOCATION (*expr_p));
6247 if (COMPARISON_CLASS_P (*from_p))
6248 copy_warning (assign, *from_p);
6251 if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p))
6253 /* We should have got an SSA name from the start. */
6254 gcc_assert (TREE_CODE (*to_p) == SSA_NAME
6255 || ! gimple_in_ssa_p (cfun));
6258 gimplify_seq_add_stmt (pre_p, assign);
6259 gsi = gsi_last (*pre_p);
6260 maybe_fold_stmt (&gsi);
6262 if (want_value)
6264 *expr_p = TREE_THIS_VOLATILE (*to_p) ? *from_p : unshare_expr (*to_p);
6265 return GS_OK;
6267 else
6268 *expr_p = NULL;
6270 return GS_ALL_DONE;
6273 /* Gimplify a comparison between two variable-sized objects. Do this
6274 with a call to BUILT_IN_MEMCMP. */
6276 static enum gimplify_status
6277 gimplify_variable_sized_compare (tree *expr_p)
6279 location_t loc = EXPR_LOCATION (*expr_p);
6280 tree op0 = TREE_OPERAND (*expr_p, 0);
6281 tree op1 = TREE_OPERAND (*expr_p, 1);
6282 tree t, arg, dest, src, expr;
6284 arg = TYPE_SIZE_UNIT (TREE_TYPE (op0));
6285 arg = unshare_expr (arg);
6286 arg = SUBSTITUTE_PLACEHOLDER_IN_EXPR (arg, op0);
6287 src = build_fold_addr_expr_loc (loc, op1);
6288 dest = build_fold_addr_expr_loc (loc, op0);
6289 t = builtin_decl_implicit (BUILT_IN_MEMCMP);
6290 t = build_call_expr_loc (loc, t, 3, dest, src, arg);
6292 expr
6293 = build2 (TREE_CODE (*expr_p), TREE_TYPE (*expr_p), t, integer_zero_node);
6294 SET_EXPR_LOCATION (expr, loc);
6295 *expr_p = expr;
6297 return GS_OK;
6300 /* Gimplify a comparison between two aggregate objects of integral scalar
6301 mode as a comparison between the bitwise equivalent scalar values. */
6303 static enum gimplify_status
6304 gimplify_scalar_mode_aggregate_compare (tree *expr_p)
6306 location_t loc = EXPR_LOCATION (*expr_p);
6307 tree op0 = TREE_OPERAND (*expr_p, 0);
6308 tree op1 = TREE_OPERAND (*expr_p, 1);
6310 tree type = TREE_TYPE (op0);
6311 tree scalar_type = lang_hooks.types.type_for_mode (TYPE_MODE (type), 1);
6313 op0 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op0);
6314 op1 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op1);
6316 *expr_p
6317 = fold_build2_loc (loc, TREE_CODE (*expr_p), TREE_TYPE (*expr_p), op0, op1);
6319 return GS_OK;
6322 /* Gimplify an expression sequence. This function gimplifies each
6323 expression and rewrites the original expression with the last
6324 expression of the sequence in GIMPLE form.
6326 PRE_P points to the list where the side effects for all the
6327 expressions in the sequence will be emitted.
6329 WANT_VALUE is true when the result of the last COMPOUND_EXPR is used. */
6331 static enum gimplify_status
6332 gimplify_compound_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
6334 tree t = *expr_p;
6338 tree *sub_p = &TREE_OPERAND (t, 0);
6340 if (TREE_CODE (*sub_p) == COMPOUND_EXPR)
6341 gimplify_compound_expr (sub_p, pre_p, false);
6342 else
6343 gimplify_stmt (sub_p, pre_p);
6345 t = TREE_OPERAND (t, 1);
6347 while (TREE_CODE (t) == COMPOUND_EXPR);
6349 *expr_p = t;
6350 if (want_value)
6351 return GS_OK;
6352 else
6354 gimplify_stmt (expr_p, pre_p);
6355 return GS_ALL_DONE;
6359 /* Gimplify a SAVE_EXPR node. EXPR_P points to the expression to
6360 gimplify. After gimplification, EXPR_P will point to a new temporary
6361 that holds the original value of the SAVE_EXPR node.
6363 PRE_P points to the list where side effects that must happen before
6364 *EXPR_P should be stored. */
6366 static enum gimplify_status
6367 gimplify_save_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6369 enum gimplify_status ret = GS_ALL_DONE;
6370 tree val;
6372 gcc_assert (TREE_CODE (*expr_p) == SAVE_EXPR);
6373 val = TREE_OPERAND (*expr_p, 0);
6375 if (TREE_TYPE (val) == error_mark_node)
6376 return GS_ERROR;
6378 /* If the SAVE_EXPR has not been resolved, then evaluate it once. */
6379 if (!SAVE_EXPR_RESOLVED_P (*expr_p))
6381 /* The operand may be a void-valued expression. It is
6382 being executed only for its side-effects. */
6383 if (TREE_TYPE (val) == void_type_node)
6385 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
6386 is_gimple_stmt, fb_none);
6387 val = NULL;
6389 else
6390 /* The temporary may not be an SSA name as later abnormal and EH
6391 control flow may invalidate use/def domination. When in SSA
6392 form then assume there are no such issues and SAVE_EXPRs only
6393 appear via GENERIC foldings. */
6394 val = get_initialized_tmp_var (val, pre_p, post_p,
6395 gimple_in_ssa_p (cfun));
6397 TREE_OPERAND (*expr_p, 0) = val;
6398 SAVE_EXPR_RESOLVED_P (*expr_p) = 1;
6401 *expr_p = val;
6403 return ret;
6406 /* Rewrite the ADDR_EXPR node pointed to by EXPR_P
6408 unary_expr
6409 : ...
6410 | '&' varname
6413 PRE_P points to the list where side effects that must happen before
6414 *EXPR_P should be stored.
6416 POST_P points to the list where side effects that must happen after
6417 *EXPR_P should be stored. */
6419 static enum gimplify_status
6420 gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6422 tree expr = *expr_p;
6423 tree op0 = TREE_OPERAND (expr, 0);
6424 enum gimplify_status ret;
6425 location_t loc = EXPR_LOCATION (*expr_p);
6427 switch (TREE_CODE (op0))
6429 case INDIRECT_REF:
6430 do_indirect_ref:
6431 /* Check if we are dealing with an expression of the form '&*ptr'.
6432 While the front end folds away '&*ptr' into 'ptr', these
6433 expressions may be generated internally by the compiler (e.g.,
6434 builtins like __builtin_va_end). */
6435 /* Caution: the silent array decomposition semantics we allow for
6436 ADDR_EXPR means we can't always discard the pair. */
6437 /* Gimplification of the ADDR_EXPR operand may drop
6438 cv-qualification conversions, so make sure we add them if
6439 needed. */
6441 tree op00 = TREE_OPERAND (op0, 0);
6442 tree t_expr = TREE_TYPE (expr);
6443 tree t_op00 = TREE_TYPE (op00);
6445 if (!useless_type_conversion_p (t_expr, t_op00))
6446 op00 = fold_convert_loc (loc, TREE_TYPE (expr), op00);
6447 *expr_p = op00;
6448 ret = GS_OK;
6450 break;
6452 case VIEW_CONVERT_EXPR:
6453 /* Take the address of our operand and then convert it to the type of
6454 this ADDR_EXPR.
6456 ??? The interactions of VIEW_CONVERT_EXPR and aliasing is not at
6457 all clear. The impact of this transformation is even less clear. */
6459 /* If the operand is a useless conversion, look through it. Doing so
6460 guarantees that the ADDR_EXPR and its operand will remain of the
6461 same type. */
6462 if (tree_ssa_useless_type_conversion (TREE_OPERAND (op0, 0)))
6463 op0 = TREE_OPERAND (op0, 0);
6465 *expr_p = fold_convert_loc (loc, TREE_TYPE (expr),
6466 build_fold_addr_expr_loc (loc,
6467 TREE_OPERAND (op0, 0)));
6468 ret = GS_OK;
6469 break;
6471 case MEM_REF:
6472 if (integer_zerop (TREE_OPERAND (op0, 1)))
6473 goto do_indirect_ref;
6475 /* fall through */
6477 default:
6478 /* If we see a call to a declared builtin or see its address
6479 being taken (we can unify those cases here) then we can mark
6480 the builtin for implicit generation by GCC. */
6481 if (TREE_CODE (op0) == FUNCTION_DECL
6482 && fndecl_built_in_p (op0, BUILT_IN_NORMAL)
6483 && builtin_decl_declared_p (DECL_FUNCTION_CODE (op0)))
6484 set_builtin_decl_implicit_p (DECL_FUNCTION_CODE (op0), true);
6486 /* We use fb_either here because the C frontend sometimes takes
6487 the address of a call that returns a struct; see
6488 gcc.dg/c99-array-lval-1.c. The gimplifier will correctly make
6489 the implied temporary explicit. */
6491 /* Make the operand addressable. */
6492 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, post_p,
6493 is_gimple_addressable, fb_either);
6494 if (ret == GS_ERROR)
6495 break;
6497 /* Then mark it. Beware that it may not be possible to do so directly
6498 if a temporary has been created by the gimplification. */
6499 prepare_gimple_addressable (&TREE_OPERAND (expr, 0), pre_p);
6501 op0 = TREE_OPERAND (expr, 0);
6503 /* For various reasons, the gimplification of the expression
6504 may have made a new INDIRECT_REF. */
6505 if (TREE_CODE (op0) == INDIRECT_REF
6506 || (TREE_CODE (op0) == MEM_REF
6507 && integer_zerop (TREE_OPERAND (op0, 1))))
6508 goto do_indirect_ref;
6510 mark_addressable (TREE_OPERAND (expr, 0));
6512 /* The FEs may end up building ADDR_EXPRs early on a decl with
6513 an incomplete type. Re-build ADDR_EXPRs in canonical form
6514 here. */
6515 if (!types_compatible_p (TREE_TYPE (op0), TREE_TYPE (TREE_TYPE (expr))))
6516 *expr_p = build_fold_addr_expr (op0);
6518 /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly. */
6519 recompute_tree_invariant_for_addr_expr (*expr_p);
6521 /* If we re-built the ADDR_EXPR add a conversion to the original type
6522 if required. */
6523 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
6524 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
6526 break;
6529 return ret;
6532 /* Gimplify the operands of an ASM_EXPR. Input operands should be a gimple
6533 value; output operands should be a gimple lvalue. */
6535 static enum gimplify_status
6536 gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6538 tree expr;
6539 int noutputs;
6540 const char **oconstraints;
6541 int i;
6542 tree link;
6543 const char *constraint;
6544 bool allows_mem, allows_reg, is_inout;
6545 enum gimplify_status ret, tret;
6546 gasm *stmt;
6547 vec<tree, va_gc> *inputs;
6548 vec<tree, va_gc> *outputs;
6549 vec<tree, va_gc> *clobbers;
6550 vec<tree, va_gc> *labels;
6551 tree link_next;
6553 expr = *expr_p;
6554 noutputs = list_length (ASM_OUTPUTS (expr));
6555 oconstraints = (const char **) alloca ((noutputs) * sizeof (const char *));
6557 inputs = NULL;
6558 outputs = NULL;
6559 clobbers = NULL;
6560 labels = NULL;
6562 ret = GS_ALL_DONE;
6563 link_next = NULL_TREE;
6564 for (i = 0, link = ASM_OUTPUTS (expr); link; ++i, link = link_next)
6566 bool ok;
6567 size_t constraint_len;
6569 link_next = TREE_CHAIN (link);
6571 oconstraints[i]
6572 = constraint
6573 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
6574 constraint_len = strlen (constraint);
6575 if (constraint_len == 0)
6576 continue;
6578 ok = parse_output_constraint (&constraint, i, 0, 0,
6579 &allows_mem, &allows_reg, &is_inout);
6580 if (!ok)
6582 ret = GS_ERROR;
6583 is_inout = false;
6586 /* If we can't make copies, we can only accept memory.
6587 Similarly for VLAs. */
6588 tree outtype = TREE_TYPE (TREE_VALUE (link));
6589 if (outtype != error_mark_node
6590 && (TREE_ADDRESSABLE (outtype)
6591 || !COMPLETE_TYPE_P (outtype)
6592 || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (outtype))))
6594 if (allows_mem)
6595 allows_reg = 0;
6596 else
6598 error ("impossible constraint in %<asm%>");
6599 error ("non-memory output %d must stay in memory", i);
6600 return GS_ERROR;
6604 if (!allows_reg && allows_mem)
6605 mark_addressable (TREE_VALUE (link));
6607 tree orig = TREE_VALUE (link);
6608 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6609 is_inout ? is_gimple_min_lval : is_gimple_lvalue,
6610 fb_lvalue | fb_mayfail);
6611 if (tret == GS_ERROR)
6613 if (orig != error_mark_node)
6614 error ("invalid lvalue in %<asm%> output %d", i);
6615 ret = tret;
6618 /* If the constraint does not allow memory make sure we gimplify
6619 it to a register if it is not already but its base is. This
6620 happens for complex and vector components. */
6621 if (!allows_mem)
6623 tree op = TREE_VALUE (link);
6624 if (! is_gimple_val (op)
6625 && is_gimple_reg_type (TREE_TYPE (op))
6626 && is_gimple_reg (get_base_address (op)))
6628 tree tem = create_tmp_reg (TREE_TYPE (op));
6629 tree ass;
6630 if (is_inout)
6632 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem),
6633 tem, unshare_expr (op));
6634 gimplify_and_add (ass, pre_p);
6636 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem), op, tem);
6637 gimplify_and_add (ass, post_p);
6639 TREE_VALUE (link) = tem;
6640 tret = GS_OK;
6644 vec_safe_push (outputs, link);
6645 TREE_CHAIN (link) = NULL_TREE;
6647 if (is_inout)
6649 /* An input/output operand. To give the optimizers more
6650 flexibility, split it into separate input and output
6651 operands. */
6652 tree input;
6653 /* Buffer big enough to format a 32-bit UINT_MAX into. */
6654 char buf[11];
6656 /* Turn the in/out constraint into an output constraint. */
6657 char *p = xstrdup (constraint);
6658 p[0] = '=';
6659 TREE_VALUE (TREE_PURPOSE (link)) = build_string (constraint_len, p);
6661 /* And add a matching input constraint. */
6662 if (allows_reg)
6664 sprintf (buf, "%u", i);
6666 /* If there are multiple alternatives in the constraint,
6667 handle each of them individually. Those that allow register
6668 will be replaced with operand number, the others will stay
6669 unchanged. */
6670 if (strchr (p, ',') != NULL)
6672 size_t len = 0, buflen = strlen (buf);
6673 char *beg, *end, *str, *dst;
6675 for (beg = p + 1;;)
6677 end = strchr (beg, ',');
6678 if (end == NULL)
6679 end = strchr (beg, '\0');
6680 if ((size_t) (end - beg) < buflen)
6681 len += buflen + 1;
6682 else
6683 len += end - beg + 1;
6684 if (*end)
6685 beg = end + 1;
6686 else
6687 break;
6690 str = (char *) alloca (len);
6691 for (beg = p + 1, dst = str;;)
6693 const char *tem;
6694 bool mem_p, reg_p, inout_p;
6696 end = strchr (beg, ',');
6697 if (end)
6698 *end = '\0';
6699 beg[-1] = '=';
6700 tem = beg - 1;
6701 parse_output_constraint (&tem, i, 0, 0,
6702 &mem_p, &reg_p, &inout_p);
6703 if (dst != str)
6704 *dst++ = ',';
6705 if (reg_p)
6707 memcpy (dst, buf, buflen);
6708 dst += buflen;
6710 else
6712 if (end)
6713 len = end - beg;
6714 else
6715 len = strlen (beg);
6716 memcpy (dst, beg, len);
6717 dst += len;
6719 if (end)
6720 beg = end + 1;
6721 else
6722 break;
6724 *dst = '\0';
6725 input = build_string (dst - str, str);
6727 else
6728 input = build_string (strlen (buf), buf);
6730 else
6731 input = build_string (constraint_len - 1, constraint + 1);
6733 free (p);
6735 input = build_tree_list (build_tree_list (NULL_TREE, input),
6736 unshare_expr (TREE_VALUE (link)));
6737 ASM_INPUTS (expr) = chainon (ASM_INPUTS (expr), input);
6741 link_next = NULL_TREE;
6742 for (link = ASM_INPUTS (expr); link; ++i, link = link_next)
6744 link_next = TREE_CHAIN (link);
6745 constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
6746 parse_input_constraint (&constraint, 0, 0, noutputs, 0,
6747 oconstraints, &allows_mem, &allows_reg);
6749 /* If we can't make copies, we can only accept memory. */
6750 tree intype = TREE_TYPE (TREE_VALUE (link));
6751 if (intype != error_mark_node
6752 && (TREE_ADDRESSABLE (intype)
6753 || !COMPLETE_TYPE_P (intype)
6754 || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (intype))))
6756 if (allows_mem)
6757 allows_reg = 0;
6758 else
6760 error ("impossible constraint in %<asm%>");
6761 error ("non-memory input %d must stay in memory", i);
6762 return GS_ERROR;
6766 /* If the operand is a memory input, it should be an lvalue. */
6767 if (!allows_reg && allows_mem)
6769 tree inputv = TREE_VALUE (link);
6770 STRIP_NOPS (inputv);
6771 if (TREE_CODE (inputv) == PREDECREMENT_EXPR
6772 || TREE_CODE (inputv) == PREINCREMENT_EXPR
6773 || TREE_CODE (inputv) == POSTDECREMENT_EXPR
6774 || TREE_CODE (inputv) == POSTINCREMENT_EXPR
6775 || TREE_CODE (inputv) == MODIFY_EXPR)
6776 TREE_VALUE (link) = error_mark_node;
6777 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6778 is_gimple_lvalue, fb_lvalue | fb_mayfail);
6779 if (tret != GS_ERROR)
6781 /* Unlike output operands, memory inputs are not guaranteed
6782 to be lvalues by the FE, and while the expressions are
6783 marked addressable there, if it is e.g. a statement
6784 expression, temporaries in it might not end up being
6785 addressable. They might be already used in the IL and thus
6786 it is too late to make them addressable now though. */
6787 tree x = TREE_VALUE (link);
6788 while (handled_component_p (x))
6789 x = TREE_OPERAND (x, 0);
6790 if (TREE_CODE (x) == MEM_REF
6791 && TREE_CODE (TREE_OPERAND (x, 0)) == ADDR_EXPR)
6792 x = TREE_OPERAND (TREE_OPERAND (x, 0), 0);
6793 if ((VAR_P (x)
6794 || TREE_CODE (x) == PARM_DECL
6795 || TREE_CODE (x) == RESULT_DECL)
6796 && !TREE_ADDRESSABLE (x)
6797 && is_gimple_reg (x))
6799 warning_at (EXPR_LOC_OR_LOC (TREE_VALUE (link),
6800 input_location), 0,
6801 "memory input %d is not directly addressable",
6803 prepare_gimple_addressable (&TREE_VALUE (link), pre_p);
6806 mark_addressable (TREE_VALUE (link));
6807 if (tret == GS_ERROR)
6809 if (inputv != error_mark_node)
6810 error_at (EXPR_LOC_OR_LOC (TREE_VALUE (link), input_location),
6811 "memory input %d is not directly addressable", i);
6812 ret = tret;
6815 else
6817 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6818 is_gimple_asm_val, fb_rvalue);
6819 if (tret == GS_ERROR)
6820 ret = tret;
6823 TREE_CHAIN (link) = NULL_TREE;
6824 vec_safe_push (inputs, link);
6827 link_next = NULL_TREE;
6828 for (link = ASM_CLOBBERS (expr); link; ++i, link = link_next)
6830 link_next = TREE_CHAIN (link);
6831 TREE_CHAIN (link) = NULL_TREE;
6832 vec_safe_push (clobbers, link);
6835 link_next = NULL_TREE;
6836 for (link = ASM_LABELS (expr); link; ++i, link = link_next)
6838 link_next = TREE_CHAIN (link);
6839 TREE_CHAIN (link) = NULL_TREE;
6840 vec_safe_push (labels, link);
6843 /* Do not add ASMs with errors to the gimple IL stream. */
6844 if (ret != GS_ERROR)
6846 stmt = gimple_build_asm_vec (TREE_STRING_POINTER (ASM_STRING (expr)),
6847 inputs, outputs, clobbers, labels);
6849 gimple_asm_set_volatile (stmt, ASM_VOLATILE_P (expr) || noutputs == 0);
6850 gimple_asm_set_input (stmt, ASM_INPUT_P (expr));
6851 gimple_asm_set_inline (stmt, ASM_INLINE_P (expr));
6853 gimplify_seq_add_stmt (pre_p, stmt);
6856 return ret;
6859 /* Gimplify a CLEANUP_POINT_EXPR. Currently this works by adding
6860 GIMPLE_WITH_CLEANUP_EXPRs to the prequeue as we encounter cleanups while
6861 gimplifying the body, and converting them to TRY_FINALLY_EXPRs when we
6862 return to this function.
6864 FIXME should we complexify the prequeue handling instead? Or use flags
6865 for all the cleanups and let the optimizer tighten them up? The current
6866 code seems pretty fragile; it will break on a cleanup within any
6867 non-conditional nesting. But any such nesting would be broken, anyway;
6868 we can't write a TRY_FINALLY_EXPR that starts inside a nesting construct
6869 and continues out of it. We can do that at the RTL level, though, so
6870 having an optimizer to tighten up try/finally regions would be a Good
6871 Thing. */
6873 static enum gimplify_status
6874 gimplify_cleanup_point_expr (tree *expr_p, gimple_seq *pre_p)
6876 gimple_stmt_iterator iter;
6877 gimple_seq body_sequence = NULL;
6879 tree temp = voidify_wrapper_expr (*expr_p, NULL);
6881 /* We only care about the number of conditions between the innermost
6882 CLEANUP_POINT_EXPR and the cleanup. So save and reset the count and
6883 any cleanups collected outside the CLEANUP_POINT_EXPR. */
6884 int old_conds = gimplify_ctxp->conditions;
6885 gimple_seq old_cleanups = gimplify_ctxp->conditional_cleanups;
6886 bool old_in_cleanup_point_expr = gimplify_ctxp->in_cleanup_point_expr;
6887 gimplify_ctxp->conditions = 0;
6888 gimplify_ctxp->conditional_cleanups = NULL;
6889 gimplify_ctxp->in_cleanup_point_expr = true;
6891 gimplify_stmt (&TREE_OPERAND (*expr_p, 0), &body_sequence);
6893 gimplify_ctxp->conditions = old_conds;
6894 gimplify_ctxp->conditional_cleanups = old_cleanups;
6895 gimplify_ctxp->in_cleanup_point_expr = old_in_cleanup_point_expr;
6897 for (iter = gsi_start (body_sequence); !gsi_end_p (iter); )
6899 gimple *wce = gsi_stmt (iter);
6901 if (gimple_code (wce) == GIMPLE_WITH_CLEANUP_EXPR)
6903 if (gsi_one_before_end_p (iter))
6905 /* Note that gsi_insert_seq_before and gsi_remove do not
6906 scan operands, unlike some other sequence mutators. */
6907 if (!gimple_wce_cleanup_eh_only (wce))
6908 gsi_insert_seq_before_without_update (&iter,
6909 gimple_wce_cleanup (wce),
6910 GSI_SAME_STMT);
6911 gsi_remove (&iter, true);
6912 break;
6914 else
6916 gtry *gtry;
6917 gimple_seq seq;
6918 enum gimple_try_flags kind;
6920 if (gimple_wce_cleanup_eh_only (wce))
6921 kind = GIMPLE_TRY_CATCH;
6922 else
6923 kind = GIMPLE_TRY_FINALLY;
6924 seq = gsi_split_seq_after (iter);
6926 gtry = gimple_build_try (seq, gimple_wce_cleanup (wce), kind);
6927 /* Do not use gsi_replace here, as it may scan operands.
6928 We want to do a simple structural modification only. */
6929 gsi_set_stmt (&iter, gtry);
6930 iter = gsi_start (gtry->eval);
6933 else
6934 gsi_next (&iter);
6937 gimplify_seq_add_seq (pre_p, body_sequence);
6938 if (temp)
6940 *expr_p = temp;
6941 return GS_OK;
6943 else
6945 *expr_p = NULL;
6946 return GS_ALL_DONE;
6950 /* Insert a cleanup marker for gimplify_cleanup_point_expr. CLEANUP
6951 is the cleanup action required. EH_ONLY is true if the cleanup should
6952 only be executed if an exception is thrown, not on normal exit.
6953 If FORCE_UNCOND is true perform the cleanup unconditionally; this is
6954 only valid for clobbers. */
6956 static void
6957 gimple_push_cleanup (tree var, tree cleanup, bool eh_only, gimple_seq *pre_p,
6958 bool force_uncond = false)
6960 gimple *wce;
6961 gimple_seq cleanup_stmts = NULL;
6963 /* Errors can result in improperly nested cleanups. Which results in
6964 confusion when trying to resolve the GIMPLE_WITH_CLEANUP_EXPR. */
6965 if (seen_error ())
6966 return;
6968 if (gimple_conditional_context ())
6970 /* If we're in a conditional context, this is more complex. We only
6971 want to run the cleanup if we actually ran the initialization that
6972 necessitates it, but we want to run it after the end of the
6973 conditional context. So we wrap the try/finally around the
6974 condition and use a flag to determine whether or not to actually
6975 run the destructor. Thus
6977 test ? f(A()) : 0
6979 becomes (approximately)
6981 flag = 0;
6982 try {
6983 if (test) { A::A(temp); flag = 1; val = f(temp); }
6984 else { val = 0; }
6985 } finally {
6986 if (flag) A::~A(temp);
6990 if (force_uncond)
6992 gimplify_stmt (&cleanup, &cleanup_stmts);
6993 wce = gimple_build_wce (cleanup_stmts);
6994 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
6996 else
6998 tree flag = create_tmp_var (boolean_type_node, "cleanup");
6999 gassign *ffalse = gimple_build_assign (flag, boolean_false_node);
7000 gassign *ftrue = gimple_build_assign (flag, boolean_true_node);
7002 cleanup = build3 (COND_EXPR, void_type_node, flag, cleanup, NULL);
7003 gimplify_stmt (&cleanup, &cleanup_stmts);
7004 wce = gimple_build_wce (cleanup_stmts);
7005 gimple_wce_set_cleanup_eh_only (wce, eh_only);
7007 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, ffalse);
7008 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
7009 gimplify_seq_add_stmt (pre_p, ftrue);
7011 /* Because of this manipulation, and the EH edges that jump
7012 threading cannot redirect, the temporary (VAR) will appear
7013 to be used uninitialized. Don't warn. */
7014 suppress_warning (var, OPT_Wuninitialized);
7017 else
7019 gimplify_stmt (&cleanup, &cleanup_stmts);
7020 wce = gimple_build_wce (cleanup_stmts);
7021 gimple_wce_set_cleanup_eh_only (wce, eh_only);
7022 gimplify_seq_add_stmt (pre_p, wce);
7026 /* Gimplify a TARGET_EXPR which doesn't appear on the rhs of an INIT_EXPR. */
7028 static enum gimplify_status
7029 gimplify_target_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
7031 tree targ = *expr_p;
7032 tree temp = TARGET_EXPR_SLOT (targ);
7033 tree init = TARGET_EXPR_INITIAL (targ);
7034 enum gimplify_status ret;
7036 bool unpoison_empty_seq = false;
7037 gimple_stmt_iterator unpoison_it;
7039 if (init)
7041 gimple_seq init_pre_p = NULL;
7043 /* TARGET_EXPR temps aren't part of the enclosing block, so add it
7044 to the temps list. Handle also variable length TARGET_EXPRs. */
7045 if (!poly_int_tree_p (DECL_SIZE (temp)))
7047 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (temp)))
7048 gimplify_type_sizes (TREE_TYPE (temp), &init_pre_p);
7049 /* FIXME: this is correct only when the size of the type does
7050 not depend on expressions evaluated in init. */
7051 gimplify_vla_decl (temp, &init_pre_p);
7053 else
7055 /* Save location where we need to place unpoisoning. It's possible
7056 that a variable will be converted to needs_to_live_in_memory. */
7057 unpoison_it = gsi_last (*pre_p);
7058 unpoison_empty_seq = gsi_end_p (unpoison_it);
7060 gimple_add_tmp_var (temp);
7063 /* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the
7064 expression is supposed to initialize the slot. */
7065 if (VOID_TYPE_P (TREE_TYPE (init)))
7066 ret = gimplify_expr (&init, &init_pre_p, post_p, is_gimple_stmt,
7067 fb_none);
7068 else
7070 tree init_expr = build2 (INIT_EXPR, void_type_node, temp, init);
7071 init = init_expr;
7072 ret = gimplify_expr (&init, &init_pre_p, post_p, is_gimple_stmt,
7073 fb_none);
7074 init = NULL;
7075 ggc_free (init_expr);
7077 if (ret == GS_ERROR)
7079 /* PR c++/28266 Make sure this is expanded only once. */
7080 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
7081 return GS_ERROR;
7084 if (init)
7085 gimplify_and_add (init, &init_pre_p);
7087 /* Add a clobber for the temporary going out of scope, like
7088 gimplify_bind_expr. */
7089 if (gimplify_ctxp->in_cleanup_point_expr
7090 && needs_to_live_in_memory (temp))
7092 if (flag_stack_reuse == SR_ALL)
7094 tree clobber = build_clobber (TREE_TYPE (temp), CLOBBER_EOL);
7095 clobber = build2 (MODIFY_EXPR, TREE_TYPE (temp), temp, clobber);
7096 gimple_push_cleanup (temp, clobber, false, pre_p, true);
7098 if (asan_poisoned_variables
7099 && DECL_ALIGN (temp) <= MAX_SUPPORTED_STACK_ALIGNMENT
7100 && !TREE_STATIC (temp)
7101 && dbg_cnt (asan_use_after_scope)
7102 && !gimplify_omp_ctxp)
7104 tree asan_cleanup = build_asan_poison_call_expr (temp);
7105 if (asan_cleanup)
7107 if (unpoison_empty_seq)
7108 unpoison_it = gsi_start (*pre_p);
7110 asan_poison_variable (temp, false, &unpoison_it,
7111 unpoison_empty_seq);
7112 gimple_push_cleanup (temp, asan_cleanup, false, pre_p);
7117 gimple_seq_add_seq (pre_p, init_pre_p);
7119 /* If needed, push the cleanup for the temp. */
7120 if (TARGET_EXPR_CLEANUP (targ))
7121 gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ),
7122 CLEANUP_EH_ONLY (targ), pre_p);
7124 /* Only expand this once. */
7125 TREE_OPERAND (targ, 3) = init;
7126 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
7128 else
7129 /* We should have expanded this before. */
7130 gcc_assert (DECL_SEEN_IN_BIND_EXPR_P (temp));
7132 *expr_p = temp;
7133 return GS_OK;
7136 /* Gimplification of expression trees. */
7138 /* Gimplify an expression which appears at statement context. The
7139 corresponding GIMPLE statements are added to *SEQ_P. If *SEQ_P is
7140 NULL, a new sequence is allocated.
7142 Return true if we actually added a statement to the queue. */
7144 bool
7145 gimplify_stmt (tree *stmt_p, gimple_seq *seq_p)
7147 gimple_seq_node last;
7149 last = gimple_seq_last (*seq_p);
7150 gimplify_expr (stmt_p, seq_p, NULL, is_gimple_stmt, fb_none);
7151 return last != gimple_seq_last (*seq_p);
7154 /* Add FIRSTPRIVATE entries for DECL in the OpenMP the surrounding parallels
7155 to CTX. If entries already exist, force them to be some flavor of private.
7156 If there is no enclosing parallel, do nothing. */
7158 void
7159 omp_firstprivatize_variable (struct gimplify_omp_ctx *ctx, tree decl)
7161 splay_tree_node n;
7163 if (decl == NULL || !DECL_P (decl) || ctx->region_type == ORT_NONE)
7164 return;
7168 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7169 if (n != NULL)
7171 if (n->value & GOVD_SHARED)
7172 n->value = GOVD_FIRSTPRIVATE | (n->value & GOVD_SEEN);
7173 else if (n->value & GOVD_MAP)
7174 n->value |= GOVD_MAP_TO_ONLY;
7175 else
7176 return;
7178 else if ((ctx->region_type & ORT_TARGET) != 0)
7180 if (ctx->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE)
7181 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
7182 else
7183 omp_add_variable (ctx, decl, GOVD_MAP | GOVD_MAP_TO_ONLY);
7185 else if (ctx->region_type != ORT_WORKSHARE
7186 && ctx->region_type != ORT_TASKGROUP
7187 && ctx->region_type != ORT_SIMD
7188 && ctx->region_type != ORT_ACC
7189 && !(ctx->region_type & ORT_TARGET_DATA))
7190 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
7192 ctx = ctx->outer_context;
7194 while (ctx);
7197 /* Similarly for each of the type sizes of TYPE. */
7199 static void
7200 omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type)
7202 if (type == NULL || type == error_mark_node)
7203 return;
7204 type = TYPE_MAIN_VARIANT (type);
7206 if (ctx->privatized_types->add (type))
7207 return;
7209 switch (TREE_CODE (type))
7211 case INTEGER_TYPE:
7212 case ENUMERAL_TYPE:
7213 case BOOLEAN_TYPE:
7214 case REAL_TYPE:
7215 case FIXED_POINT_TYPE:
7216 omp_firstprivatize_variable (ctx, TYPE_MIN_VALUE (type));
7217 omp_firstprivatize_variable (ctx, TYPE_MAX_VALUE (type));
7218 break;
7220 case ARRAY_TYPE:
7221 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
7222 omp_firstprivatize_type_sizes (ctx, TYPE_DOMAIN (type));
7223 break;
7225 case RECORD_TYPE:
7226 case UNION_TYPE:
7227 case QUAL_UNION_TYPE:
7229 tree field;
7230 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
7231 if (TREE_CODE (field) == FIELD_DECL)
7233 omp_firstprivatize_variable (ctx, DECL_FIELD_OFFSET (field));
7234 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (field));
7237 break;
7239 case POINTER_TYPE:
7240 case REFERENCE_TYPE:
7241 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
7242 break;
7244 default:
7245 break;
7248 omp_firstprivatize_variable (ctx, TYPE_SIZE (type));
7249 omp_firstprivatize_variable (ctx, TYPE_SIZE_UNIT (type));
7250 lang_hooks.types.omp_firstprivatize_type_sizes (ctx, type);
7253 /* Add an entry for DECL in the OMP context CTX with FLAGS. */
7255 static void
7256 omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
7258 splay_tree_node n;
7259 unsigned int nflags;
7260 tree t;
7262 if (error_operand_p (decl) || ctx->region_type == ORT_NONE)
7263 return;
7265 /* Never elide decls whose type has TREE_ADDRESSABLE set. This means
7266 there are constructors involved somewhere. Exception is a shared clause,
7267 there is nothing privatized in that case. */
7268 if ((flags & GOVD_SHARED) == 0
7269 && (TREE_ADDRESSABLE (TREE_TYPE (decl))
7270 || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))))
7271 flags |= GOVD_SEEN;
7273 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7274 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
7276 /* We shouldn't be re-adding the decl with the same data
7277 sharing class. */
7278 gcc_assert ((n->value & GOVD_DATA_SHARE_CLASS & flags) == 0);
7279 nflags = n->value | flags;
7280 /* The only combination of data sharing classes we should see is
7281 FIRSTPRIVATE and LASTPRIVATE. However, OpenACC permits
7282 reduction variables to be used in data sharing clauses. */
7283 gcc_assert ((ctx->region_type & ORT_ACC) != 0
7284 || ((nflags & GOVD_DATA_SHARE_CLASS)
7285 == (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE))
7286 || (flags & GOVD_DATA_SHARE_CLASS) == 0);
7287 n->value = nflags;
7288 return;
7291 /* When adding a variable-sized variable, we have to handle all sorts
7292 of additional bits of data: the pointer replacement variable, and
7293 the parameters of the type. */
7294 if (DECL_SIZE (decl) && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
7296 /* Add the pointer replacement variable as PRIVATE if the variable
7297 replacement is private, else FIRSTPRIVATE since we'll need the
7298 address of the original variable either for SHARED, or for the
7299 copy into or out of the context. */
7300 if (!(flags & GOVD_LOCAL) && ctx->region_type != ORT_TASKGROUP)
7302 if (flags & GOVD_MAP)
7303 nflags = GOVD_MAP | GOVD_MAP_TO_ONLY | GOVD_EXPLICIT;
7304 else if (flags & GOVD_PRIVATE)
7305 nflags = GOVD_PRIVATE;
7306 else if (((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
7307 && (flags & GOVD_FIRSTPRIVATE))
7308 || (ctx->region_type == ORT_TARGET_DATA
7309 && (flags & GOVD_DATA_SHARE_CLASS) == 0))
7310 nflags = GOVD_PRIVATE | GOVD_EXPLICIT;
7311 else
7312 nflags = GOVD_FIRSTPRIVATE;
7313 nflags |= flags & GOVD_SEEN;
7314 t = DECL_VALUE_EXPR (decl);
7315 gcc_assert (TREE_CODE (t) == INDIRECT_REF);
7316 t = TREE_OPERAND (t, 0);
7317 gcc_assert (DECL_P (t));
7318 omp_add_variable (ctx, t, nflags);
7321 /* Add all of the variable and type parameters (which should have
7322 been gimplified to a formal temporary) as FIRSTPRIVATE. */
7323 omp_firstprivatize_variable (ctx, DECL_SIZE_UNIT (decl));
7324 omp_firstprivatize_variable (ctx, DECL_SIZE (decl));
7325 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
7327 /* The variable-sized variable itself is never SHARED, only some form
7328 of PRIVATE. The sharing would take place via the pointer variable
7329 which we remapped above. */
7330 if (flags & GOVD_SHARED)
7331 flags = GOVD_SHARED | GOVD_DEBUG_PRIVATE
7332 | (flags & (GOVD_SEEN | GOVD_EXPLICIT));
7334 /* We're going to make use of the TYPE_SIZE_UNIT at least in the
7335 alloca statement we generate for the variable, so make sure it
7336 is available. This isn't automatically needed for the SHARED
7337 case, since we won't be allocating local storage then.
7338 For local variables TYPE_SIZE_UNIT might not be gimplified yet,
7339 in this case omp_notice_variable will be called later
7340 on when it is gimplified. */
7341 else if (! (flags & (GOVD_LOCAL | GOVD_MAP))
7342 && DECL_P (TYPE_SIZE_UNIT (TREE_TYPE (decl))))
7343 omp_notice_variable (ctx, TYPE_SIZE_UNIT (TREE_TYPE (decl)), true);
7345 else if ((flags & (GOVD_MAP | GOVD_LOCAL)) == 0
7346 && omp_privatize_by_reference (decl))
7348 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
7350 /* Similar to the direct variable sized case above, we'll need the
7351 size of references being privatized. */
7352 if ((flags & GOVD_SHARED) == 0)
7354 t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
7355 if (t && DECL_P (t))
7356 omp_notice_variable (ctx, t, true);
7360 if (n != NULL)
7361 n->value |= flags;
7362 else
7363 splay_tree_insert (ctx->variables, (splay_tree_key)decl, flags);
7365 /* For reductions clauses in OpenACC loop directives, by default create a
7366 copy clause on the enclosing parallel construct for carrying back the
7367 results. */
7368 if (ctx->region_type == ORT_ACC && (flags & GOVD_REDUCTION))
7370 struct gimplify_omp_ctx *outer_ctx = ctx->outer_context;
7371 while (outer_ctx)
7373 n = splay_tree_lookup (outer_ctx->variables, (splay_tree_key)decl);
7374 if (n != NULL)
7376 /* Ignore local variables and explicitly declared clauses. */
7377 if (n->value & (GOVD_LOCAL | GOVD_EXPLICIT))
7378 break;
7379 else if (outer_ctx->region_type == ORT_ACC_KERNELS)
7381 /* According to the OpenACC spec, such a reduction variable
7382 should already have a copy map on a kernels construct,
7383 verify that here. */
7384 gcc_assert (!(n->value & GOVD_FIRSTPRIVATE)
7385 && (n->value & GOVD_MAP));
7387 else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
7389 /* Remove firstprivate and make it a copy map. */
7390 n->value &= ~GOVD_FIRSTPRIVATE;
7391 n->value |= GOVD_MAP;
7394 else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
7396 splay_tree_insert (outer_ctx->variables, (splay_tree_key)decl,
7397 GOVD_MAP | GOVD_SEEN);
7398 break;
7400 outer_ctx = outer_ctx->outer_context;
7405 /* Notice a threadprivate variable DECL used in OMP context CTX.
7406 This just prints out diagnostics about threadprivate variable uses
7407 in untied tasks. If DECL2 is non-NULL, prevent this warning
7408 on that variable. */
7410 static bool
7411 omp_notice_threadprivate_variable (struct gimplify_omp_ctx *ctx, tree decl,
7412 tree decl2)
7414 splay_tree_node n;
7415 struct gimplify_omp_ctx *octx;
7417 for (octx = ctx; octx; octx = octx->outer_context)
7418 if ((octx->region_type & ORT_TARGET) != 0
7419 || octx->order_concurrent)
7421 n = splay_tree_lookup (octx->variables, (splay_tree_key)decl);
7422 if (n == NULL)
7424 if (octx->order_concurrent)
7426 error ("threadprivate variable %qE used in a region with"
7427 " %<order(concurrent)%> clause", DECL_NAME (decl));
7428 inform (octx->location, "enclosing region");
7430 else
7432 error ("threadprivate variable %qE used in target region",
7433 DECL_NAME (decl));
7434 inform (octx->location, "enclosing target region");
7436 splay_tree_insert (octx->variables, (splay_tree_key)decl, 0);
7438 if (decl2)
7439 splay_tree_insert (octx->variables, (splay_tree_key)decl2, 0);
7442 if (ctx->region_type != ORT_UNTIED_TASK)
7443 return false;
7444 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7445 if (n == NULL)
7447 error ("threadprivate variable %qE used in untied task",
7448 DECL_NAME (decl));
7449 inform (ctx->location, "enclosing task");
7450 splay_tree_insert (ctx->variables, (splay_tree_key)decl, 0);
7452 if (decl2)
7453 splay_tree_insert (ctx->variables, (splay_tree_key)decl2, 0);
7454 return false;
7457 /* Return true if global var DECL is device resident. */
7459 static bool
7460 device_resident_p (tree decl)
7462 tree attr = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (decl));
7464 if (!attr)
7465 return false;
7467 for (tree t = TREE_VALUE (attr); t; t = TREE_PURPOSE (t))
7469 tree c = TREE_VALUE (t);
7470 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DEVICE_RESIDENT)
7471 return true;
7474 return false;
7477 /* Return true if DECL has an ACC DECLARE attribute. */
7479 static bool
7480 is_oacc_declared (tree decl)
7482 tree t = TREE_CODE (decl) == MEM_REF ? TREE_OPERAND (decl, 0) : decl;
7483 tree declared = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (t));
7484 return declared != NULL_TREE;
7487 /* Determine outer default flags for DECL mentioned in an OMP region
7488 but not declared in an enclosing clause.
7490 ??? Some compiler-generated variables (like SAVE_EXPRs) could be
7491 remapped firstprivate instead of shared. To some extent this is
7492 addressed in omp_firstprivatize_type_sizes, but not
7493 effectively. */
7495 static unsigned
7496 omp_default_clause (struct gimplify_omp_ctx *ctx, tree decl,
7497 bool in_code, unsigned flags)
7499 enum omp_clause_default_kind default_kind = ctx->default_kind;
7500 enum omp_clause_default_kind kind;
7502 kind = lang_hooks.decls.omp_predetermined_sharing (decl);
7503 if (ctx->region_type & ORT_TASK)
7505 tree detach_clause = omp_find_clause (ctx->clauses, OMP_CLAUSE_DETACH);
7507 /* The event-handle specified by a detach clause should always be firstprivate,
7508 regardless of the current default. */
7509 if (detach_clause && OMP_CLAUSE_DECL (detach_clause) == decl)
7510 kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
7512 if (kind != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
7513 default_kind = kind;
7514 else if (VAR_P (decl) && TREE_STATIC (decl) && DECL_IN_CONSTANT_POOL (decl))
7515 default_kind = OMP_CLAUSE_DEFAULT_SHARED;
7516 /* For C/C++ default({,first}private), variables with static storage duration
7517 declared in a namespace or global scope and referenced in construct
7518 must be explicitly specified, i.e. acts as default(none). */
7519 else if ((default_kind == OMP_CLAUSE_DEFAULT_PRIVATE
7520 || default_kind == OMP_CLAUSE_DEFAULT_FIRSTPRIVATE)
7521 && VAR_P (decl)
7522 && is_global_var (decl)
7523 && (DECL_FILE_SCOPE_P (decl)
7524 || (DECL_CONTEXT (decl)
7525 && TREE_CODE (DECL_CONTEXT (decl)) == NAMESPACE_DECL))
7526 && !lang_GNU_Fortran ())
7527 default_kind = OMP_CLAUSE_DEFAULT_NONE;
7529 switch (default_kind)
7531 case OMP_CLAUSE_DEFAULT_NONE:
7533 const char *rtype;
7535 if (ctx->region_type & ORT_PARALLEL)
7536 rtype = "parallel";
7537 else if ((ctx->region_type & ORT_TASKLOOP) == ORT_TASKLOOP)
7538 rtype = "taskloop";
7539 else if (ctx->region_type & ORT_TASK)
7540 rtype = "task";
7541 else if (ctx->region_type & ORT_TEAMS)
7542 rtype = "teams";
7543 else
7544 gcc_unreachable ();
7546 error ("%qE not specified in enclosing %qs",
7547 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rtype);
7548 inform (ctx->location, "enclosing %qs", rtype);
7550 /* FALLTHRU */
7551 case OMP_CLAUSE_DEFAULT_SHARED:
7552 flags |= GOVD_SHARED;
7553 break;
7554 case OMP_CLAUSE_DEFAULT_PRIVATE:
7555 flags |= GOVD_PRIVATE;
7556 break;
7557 case OMP_CLAUSE_DEFAULT_FIRSTPRIVATE:
7558 flags |= GOVD_FIRSTPRIVATE;
7559 break;
7560 case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
7561 /* decl will be either GOVD_FIRSTPRIVATE or GOVD_SHARED. */
7562 gcc_assert ((ctx->region_type & ORT_TASK) != 0);
7563 if (struct gimplify_omp_ctx *octx = ctx->outer_context)
7565 omp_notice_variable (octx, decl, in_code);
7566 for (; octx; octx = octx->outer_context)
7568 splay_tree_node n2;
7570 n2 = splay_tree_lookup (octx->variables, (splay_tree_key) decl);
7571 if ((octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)) != 0
7572 && (n2 == NULL || (n2->value & GOVD_DATA_SHARE_CLASS) == 0))
7573 continue;
7574 if (n2 && (n2->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED)
7576 flags |= GOVD_FIRSTPRIVATE;
7577 goto found_outer;
7579 if ((octx->region_type & (ORT_PARALLEL | ORT_TEAMS)) != 0)
7581 flags |= GOVD_SHARED;
7582 goto found_outer;
7587 if (TREE_CODE (decl) == PARM_DECL
7588 || (!is_global_var (decl)
7589 && DECL_CONTEXT (decl) == current_function_decl))
7590 flags |= GOVD_FIRSTPRIVATE;
7591 else
7592 flags |= GOVD_SHARED;
7593 found_outer:
7594 break;
7596 default:
7597 gcc_unreachable ();
7600 return flags;
7604 /* Determine outer default flags for DECL mentioned in an OACC region
7605 but not declared in an enclosing clause. */
7607 static unsigned
7608 oacc_default_clause (struct gimplify_omp_ctx *ctx, tree decl, unsigned flags)
7610 const char *rkind;
7611 bool on_device = false;
7612 bool is_private = false;
7613 bool declared = is_oacc_declared (decl);
7614 tree type = TREE_TYPE (decl);
7616 if (omp_privatize_by_reference (decl))
7617 type = TREE_TYPE (type);
7619 /* For Fortran COMMON blocks, only used variables in those blocks are
7620 transfered and remapped. The block itself will have a private clause to
7621 avoid transfering the data twice.
7622 The hook evaluates to false by default. For a variable in Fortran's COMMON
7623 or EQUIVALENCE block, returns 'true' (as we have shared=false) - as only
7624 the variables in such a COMMON/EQUIVALENCE block shall be privatized not
7625 the whole block. For C++ and Fortran, it can also be true under certain
7626 other conditions, if DECL_HAS_VALUE_EXPR. */
7627 if (RECORD_OR_UNION_TYPE_P (type))
7628 is_private = lang_hooks.decls.omp_disregard_value_expr (decl, false);
7630 if ((ctx->region_type & (ORT_ACC_PARALLEL | ORT_ACC_KERNELS)) != 0
7631 && is_global_var (decl)
7632 && device_resident_p (decl)
7633 && !is_private)
7635 on_device = true;
7636 flags |= GOVD_MAP_TO_ONLY;
7639 switch (ctx->region_type)
7641 case ORT_ACC_KERNELS:
7642 rkind = "kernels";
7644 if (is_private)
7645 flags |= GOVD_FIRSTPRIVATE;
7646 else if (AGGREGATE_TYPE_P (type))
7648 /* Aggregates default to 'present_or_copy', or 'present'. */
7649 if (ctx->default_kind != OMP_CLAUSE_DEFAULT_PRESENT)
7650 flags |= GOVD_MAP;
7651 else
7652 flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
7654 else
7655 /* Scalars default to 'copy'. */
7656 flags |= GOVD_MAP | GOVD_MAP_FORCE;
7658 break;
7660 case ORT_ACC_PARALLEL:
7661 case ORT_ACC_SERIAL:
7662 rkind = ctx->region_type == ORT_ACC_PARALLEL ? "parallel" : "serial";
7664 if (is_private)
7665 flags |= GOVD_FIRSTPRIVATE;
7666 else if (on_device || declared)
7667 flags |= GOVD_MAP;
7668 else if (AGGREGATE_TYPE_P (type))
7670 /* Aggregates default to 'present_or_copy', or 'present'. */
7671 if (ctx->default_kind != OMP_CLAUSE_DEFAULT_PRESENT)
7672 flags |= GOVD_MAP;
7673 else
7674 flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
7676 else
7677 /* Scalars default to 'firstprivate'. */
7678 flags |= GOVD_FIRSTPRIVATE;
7680 break;
7682 default:
7683 gcc_unreachable ();
7686 if (DECL_ARTIFICIAL (decl))
7687 ; /* We can get compiler-generated decls, and should not complain
7688 about them. */
7689 else if (ctx->default_kind == OMP_CLAUSE_DEFAULT_NONE)
7691 error ("%qE not specified in enclosing OpenACC %qs construct",
7692 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rkind);
7693 inform (ctx->location, "enclosing OpenACC %qs construct", rkind);
7695 else if (ctx->default_kind == OMP_CLAUSE_DEFAULT_PRESENT)
7696 ; /* Handled above. */
7697 else
7698 gcc_checking_assert (ctx->default_kind == OMP_CLAUSE_DEFAULT_SHARED);
7700 return flags;
7703 /* Record the fact that DECL was used within the OMP context CTX.
7704 IN_CODE is true when real code uses DECL, and false when we should
7705 merely emit default(none) errors. Return true if DECL is going to
7706 be remapped and thus DECL shouldn't be gimplified into its
7707 DECL_VALUE_EXPR (if any). */
7709 static bool
7710 omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
7712 splay_tree_node n;
7713 unsigned flags = in_code ? GOVD_SEEN : 0;
7714 bool ret = false, shared;
7716 if (error_operand_p (decl))
7717 return false;
7719 if (ctx->region_type == ORT_NONE)
7720 return lang_hooks.decls.omp_disregard_value_expr (decl, false);
7722 if (is_global_var (decl))
7724 /* Threadprivate variables are predetermined. */
7725 if (DECL_THREAD_LOCAL_P (decl))
7726 return omp_notice_threadprivate_variable (ctx, decl, NULL_TREE);
7728 if (DECL_HAS_VALUE_EXPR_P (decl))
7730 if (ctx->region_type & ORT_ACC)
7731 /* For OpenACC, defer expansion of value to avoid transfering
7732 privatized common block data instead of im-/explicitly transfered
7733 variables which are in common blocks. */
7735 else
7737 tree value = get_base_address (DECL_VALUE_EXPR (decl));
7739 if (value && DECL_P (value) && DECL_THREAD_LOCAL_P (value))
7740 return omp_notice_threadprivate_variable (ctx, decl, value);
7744 if (gimplify_omp_ctxp->outer_context == NULL
7745 && VAR_P (decl)
7746 && oacc_get_fn_attrib (current_function_decl))
7748 location_t loc = DECL_SOURCE_LOCATION (decl);
7750 if (lookup_attribute ("omp declare target link",
7751 DECL_ATTRIBUTES (decl)))
7753 error_at (loc,
7754 "%qE with %<link%> clause used in %<routine%> function",
7755 DECL_NAME (decl));
7756 return false;
7758 else if (!lookup_attribute ("omp declare target",
7759 DECL_ATTRIBUTES (decl)))
7761 error_at (loc,
7762 "%qE requires a %<declare%> directive for use "
7763 "in a %<routine%> function", DECL_NAME (decl));
7764 return false;
7769 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7770 if ((ctx->region_type & ORT_TARGET) != 0)
7772 if (ctx->region_type & ORT_ACC)
7773 /* For OpenACC, as remarked above, defer expansion. */
7774 shared = false;
7775 else
7776 shared = true;
7778 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7779 if (n == NULL)
7781 unsigned nflags = flags;
7782 if ((ctx->region_type & ORT_ACC) == 0)
7784 bool is_declare_target = false;
7785 if (is_global_var (decl)
7786 && varpool_node::get_create (decl)->offloadable)
7788 struct gimplify_omp_ctx *octx;
7789 for (octx = ctx->outer_context;
7790 octx; octx = octx->outer_context)
7792 n = splay_tree_lookup (octx->variables,
7793 (splay_tree_key)decl);
7794 if (n
7795 && (n->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED
7796 && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
7797 break;
7799 is_declare_target = octx == NULL;
7801 if (!is_declare_target)
7803 int gdmk;
7804 enum omp_clause_defaultmap_kind kind;
7805 if (lang_hooks.decls.omp_allocatable_p (decl))
7806 gdmk = GDMK_ALLOCATABLE;
7807 else if (lang_hooks.decls.omp_scalar_target_p (decl))
7808 gdmk = GDMK_SCALAR_TARGET;
7809 else if (lang_hooks.decls.omp_scalar_p (decl, false))
7810 gdmk = GDMK_SCALAR;
7811 else if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
7812 || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
7813 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
7814 == POINTER_TYPE)))
7815 gdmk = GDMK_POINTER;
7816 else
7817 gdmk = GDMK_AGGREGATE;
7818 kind = lang_hooks.decls.omp_predetermined_mapping (decl);
7819 if (kind != OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
7821 if (kind == OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE)
7822 nflags |= GOVD_FIRSTPRIVATE;
7823 else if (kind == OMP_CLAUSE_DEFAULTMAP_TO)
7824 nflags |= GOVD_MAP | GOVD_MAP_TO_ONLY;
7825 else
7826 gcc_unreachable ();
7828 else if (ctx->defaultmap[gdmk] == 0)
7830 tree d = lang_hooks.decls.omp_report_decl (decl);
7831 error ("%qE not specified in enclosing %<target%>",
7832 DECL_NAME (d));
7833 inform (ctx->location, "enclosing %<target%>");
7835 else if (ctx->defaultmap[gdmk]
7836 & (GOVD_MAP_0LEN_ARRAY | GOVD_FIRSTPRIVATE))
7837 nflags |= ctx->defaultmap[gdmk];
7838 else
7840 gcc_assert (ctx->defaultmap[gdmk] & GOVD_MAP);
7841 nflags |= ctx->defaultmap[gdmk] & ~GOVD_MAP;
7846 struct gimplify_omp_ctx *octx = ctx->outer_context;
7847 if ((ctx->region_type & ORT_ACC) && octx)
7849 /* Look in outer OpenACC contexts, to see if there's a
7850 data attribute for this variable. */
7851 omp_notice_variable (octx, decl, in_code);
7853 for (; octx; octx = octx->outer_context)
7855 if (!(octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)))
7856 break;
7857 splay_tree_node n2
7858 = splay_tree_lookup (octx->variables,
7859 (splay_tree_key) decl);
7860 if (n2)
7862 if (octx->region_type == ORT_ACC_HOST_DATA)
7863 error ("variable %qE declared in enclosing "
7864 "%<host_data%> region", DECL_NAME (decl));
7865 nflags |= GOVD_MAP;
7866 if (octx->region_type == ORT_ACC_DATA
7867 && (n2->value & GOVD_MAP_0LEN_ARRAY))
7868 nflags |= GOVD_MAP_0LEN_ARRAY;
7869 goto found_outer;
7874 if ((nflags & ~(GOVD_MAP_TO_ONLY | GOVD_MAP_FROM_ONLY
7875 | GOVD_MAP_ALLOC_ONLY)) == flags)
7877 tree type = TREE_TYPE (decl);
7879 if (gimplify_omp_ctxp->target_firstprivatize_array_bases
7880 && omp_privatize_by_reference (decl))
7881 type = TREE_TYPE (type);
7882 if (!lang_hooks.types.omp_mappable_type (type))
7884 error ("%qD referenced in target region does not have "
7885 "a mappable type", decl);
7886 nflags |= GOVD_MAP | GOVD_EXPLICIT;
7888 else
7890 if ((ctx->region_type & ORT_ACC) != 0)
7891 nflags = oacc_default_clause (ctx, decl, flags);
7892 else
7893 nflags |= GOVD_MAP;
7896 found_outer:
7897 omp_add_variable (ctx, decl, nflags);
7899 else
7901 /* If nothing changed, there's nothing left to do. */
7902 if ((n->value & flags) == flags)
7903 return ret;
7904 flags |= n->value;
7905 n->value = flags;
7907 goto do_outer;
7910 if (n == NULL)
7912 if (ctx->region_type == ORT_WORKSHARE
7913 || ctx->region_type == ORT_TASKGROUP
7914 || ctx->region_type == ORT_SIMD
7915 || ctx->region_type == ORT_ACC
7916 || (ctx->region_type & ORT_TARGET_DATA) != 0)
7917 goto do_outer;
7919 flags = omp_default_clause (ctx, decl, in_code, flags);
7921 if ((flags & GOVD_PRIVATE)
7922 && lang_hooks.decls.omp_private_outer_ref (decl))
7923 flags |= GOVD_PRIVATE_OUTER_REF;
7925 omp_add_variable (ctx, decl, flags);
7927 shared = (flags & GOVD_SHARED) != 0;
7928 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7929 goto do_outer;
7932 /* Don't mark as GOVD_SEEN addressable temporaries seen only in simd
7933 lb, b or incr expressions, those shouldn't be turned into simd arrays. */
7934 if (ctx->region_type == ORT_SIMD
7935 && ctx->in_for_exprs
7936 && ((n->value & (GOVD_PRIVATE | GOVD_SEEN | GOVD_EXPLICIT))
7937 == GOVD_PRIVATE))
7938 flags &= ~GOVD_SEEN;
7940 if ((n->value & (GOVD_SEEN | GOVD_LOCAL)) == 0
7941 && (flags & (GOVD_SEEN | GOVD_LOCAL)) == GOVD_SEEN
7942 && DECL_SIZE (decl))
7944 if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
7946 splay_tree_node n2;
7947 tree t = DECL_VALUE_EXPR (decl);
7948 gcc_assert (TREE_CODE (t) == INDIRECT_REF);
7949 t = TREE_OPERAND (t, 0);
7950 gcc_assert (DECL_P (t));
7951 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
7952 n2->value |= GOVD_SEEN;
7954 else if (omp_privatize_by_reference (decl)
7955 && TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)))
7956 && (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))))
7957 != INTEGER_CST))
7959 splay_tree_node n2;
7960 tree t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
7961 gcc_assert (DECL_P (t));
7962 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
7963 if (n2)
7964 omp_notice_variable (ctx, t, true);
7968 if (ctx->region_type & ORT_ACC)
7969 /* For OpenACC, as remarked above, defer expansion. */
7970 shared = false;
7971 else
7972 shared = ((flags | n->value) & GOVD_SHARED) != 0;
7973 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7975 /* If nothing changed, there's nothing left to do. */
7976 if ((n->value & flags) == flags)
7977 return ret;
7978 flags |= n->value;
7979 n->value = flags;
7981 do_outer:
7982 /* If the variable is private in the current context, then we don't
7983 need to propagate anything to an outer context. */
7984 if ((flags & GOVD_PRIVATE) && !(flags & GOVD_PRIVATE_OUTER_REF))
7985 return ret;
7986 if ((flags & (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7987 == (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7988 return ret;
7989 if ((flags & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
7990 | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7991 == (GOVD_LASTPRIVATE | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7992 return ret;
7993 if (ctx->outer_context
7994 && omp_notice_variable (ctx->outer_context, decl, in_code))
7995 return true;
7996 return ret;
7999 /* Verify that DECL is private within CTX. If there's specific information
8000 to the contrary in the innermost scope, generate an error. */
8002 static bool
8003 omp_is_private (struct gimplify_omp_ctx *ctx, tree decl, int simd)
8005 splay_tree_node n;
8007 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
8008 if (n != NULL)
8010 if (n->value & GOVD_SHARED)
8012 if (ctx == gimplify_omp_ctxp)
8014 if (simd)
8015 error ("iteration variable %qE is predetermined linear",
8016 DECL_NAME (decl));
8017 else
8018 error ("iteration variable %qE should be private",
8019 DECL_NAME (decl));
8020 n->value = GOVD_PRIVATE;
8021 return true;
8023 else
8024 return false;
8026 else if ((n->value & GOVD_EXPLICIT) != 0
8027 && (ctx == gimplify_omp_ctxp
8028 || (ctx->region_type == ORT_COMBINED_PARALLEL
8029 && gimplify_omp_ctxp->outer_context == ctx)))
8031 if ((n->value & GOVD_FIRSTPRIVATE) != 0)
8032 error ("iteration variable %qE should not be firstprivate",
8033 DECL_NAME (decl));
8034 else if ((n->value & GOVD_REDUCTION) != 0)
8035 error ("iteration variable %qE should not be reduction",
8036 DECL_NAME (decl));
8037 else if (simd != 1 && (n->value & GOVD_LINEAR) != 0)
8038 error ("iteration variable %qE should not be linear",
8039 DECL_NAME (decl));
8041 return (ctx == gimplify_omp_ctxp
8042 || (ctx->region_type == ORT_COMBINED_PARALLEL
8043 && gimplify_omp_ctxp->outer_context == ctx));
8046 if (ctx->region_type != ORT_WORKSHARE
8047 && ctx->region_type != ORT_TASKGROUP
8048 && ctx->region_type != ORT_SIMD
8049 && ctx->region_type != ORT_ACC)
8050 return false;
8051 else if (ctx->outer_context)
8052 return omp_is_private (ctx->outer_context, decl, simd);
8053 return false;
8056 /* Return true if DECL is private within a parallel region
8057 that binds to the current construct's context or in parallel
8058 region's REDUCTION clause. */
8060 static bool
8061 omp_check_private (struct gimplify_omp_ctx *ctx, tree decl, bool copyprivate)
8063 splay_tree_node n;
8067 ctx = ctx->outer_context;
8068 if (ctx == NULL)
8070 if (is_global_var (decl))
8071 return false;
8073 /* References might be private, but might be shared too,
8074 when checking for copyprivate, assume they might be
8075 private, otherwise assume they might be shared. */
8076 if (copyprivate)
8077 return true;
8079 if (omp_privatize_by_reference (decl))
8080 return false;
8082 /* Treat C++ privatized non-static data members outside
8083 of the privatization the same. */
8084 if (omp_member_access_dummy_var (decl))
8085 return false;
8087 return true;
8090 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
8092 if ((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
8093 && (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0))
8095 if ((ctx->region_type & ORT_TARGET_DATA) != 0
8096 || n == NULL
8097 || (n->value & GOVD_MAP) == 0)
8098 continue;
8099 return false;
8102 if (n != NULL)
8104 if ((n->value & GOVD_LOCAL) != 0
8105 && omp_member_access_dummy_var (decl))
8106 return false;
8107 return (n->value & GOVD_SHARED) == 0;
8110 if (ctx->region_type == ORT_WORKSHARE
8111 || ctx->region_type == ORT_TASKGROUP
8112 || ctx->region_type == ORT_SIMD
8113 || ctx->region_type == ORT_ACC)
8114 continue;
8116 break;
8118 while (1);
8119 return false;
8122 /* Callback for walk_tree to find a DECL_EXPR for the given DECL. */
8124 static tree
8125 find_decl_expr (tree *tp, int *walk_subtrees, void *data)
8127 tree t = *tp;
8129 /* If this node has been visited, unmark it and keep looking. */
8130 if (TREE_CODE (t) == DECL_EXPR && DECL_EXPR_DECL (t) == (tree) data)
8131 return t;
8133 if (IS_TYPE_OR_DECL_P (t))
8134 *walk_subtrees = 0;
8135 return NULL_TREE;
8139 /* Gimplify the affinity clause but effectively ignore it.
8140 Generate:
8141 var = begin;
8142 if ((step > 1) ? var <= end : var > end)
8143 locatator_var_expr; */
8145 static void
8146 gimplify_omp_affinity (tree *list_p, gimple_seq *pre_p)
8148 tree last_iter = NULL_TREE;
8149 tree last_bind = NULL_TREE;
8150 tree label = NULL_TREE;
8151 tree *last_body = NULL;
8152 for (tree c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
8153 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY)
8155 tree t = OMP_CLAUSE_DECL (c);
8156 if (TREE_CODE (t) == TREE_LIST
8157 && TREE_PURPOSE (t)
8158 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
8160 if (TREE_VALUE (t) == null_pointer_node)
8161 continue;
8162 if (TREE_PURPOSE (t) != last_iter)
8164 if (last_bind)
8166 append_to_statement_list (label, last_body);
8167 gimplify_and_add (last_bind, pre_p);
8168 last_bind = NULL_TREE;
8170 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8172 if (gimplify_expr (&TREE_VEC_ELT (it, 1), pre_p, NULL,
8173 is_gimple_val, fb_rvalue) == GS_ERROR
8174 || gimplify_expr (&TREE_VEC_ELT (it, 2), pre_p, NULL,
8175 is_gimple_val, fb_rvalue) == GS_ERROR
8176 || gimplify_expr (&TREE_VEC_ELT (it, 3), pre_p, NULL,
8177 is_gimple_val, fb_rvalue) == GS_ERROR
8178 || (gimplify_expr (&TREE_VEC_ELT (it, 4), pre_p, NULL,
8179 is_gimple_val, fb_rvalue)
8180 == GS_ERROR))
8181 return;
8183 last_iter = TREE_PURPOSE (t);
8184 tree block = TREE_VEC_ELT (TREE_PURPOSE (t), 5);
8185 last_bind = build3 (BIND_EXPR, void_type_node, BLOCK_VARS (block),
8186 NULL, block);
8187 last_body = &BIND_EXPR_BODY (last_bind);
8188 tree cond = NULL_TREE;
8189 location_t loc = OMP_CLAUSE_LOCATION (c);
8190 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8192 tree var = TREE_VEC_ELT (it, 0);
8193 tree begin = TREE_VEC_ELT (it, 1);
8194 tree end = TREE_VEC_ELT (it, 2);
8195 tree step = TREE_VEC_ELT (it, 3);
8196 loc = DECL_SOURCE_LOCATION (var);
8197 tree tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
8198 var, begin);
8199 append_to_statement_list_force (tem, last_body);
8201 tree cond1 = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8202 step, build_zero_cst (TREE_TYPE (step)));
8203 tree cond2 = fold_build2_loc (loc, LE_EXPR, boolean_type_node,
8204 var, end);
8205 tree cond3 = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8206 var, end);
8207 cond1 = fold_build3_loc (loc, COND_EXPR, boolean_type_node,
8208 cond1, cond2, cond3);
8209 if (cond)
8210 cond = fold_build2_loc (loc, TRUTH_AND_EXPR,
8211 boolean_type_node, cond, cond1);
8212 else
8213 cond = cond1;
8215 tree cont_label = create_artificial_label (loc);
8216 label = build1 (LABEL_EXPR, void_type_node, cont_label);
8217 tree tem = fold_build3_loc (loc, COND_EXPR, void_type_node, cond,
8218 void_node,
8219 build_and_jump (&cont_label));
8220 append_to_statement_list_force (tem, last_body);
8222 if (TREE_CODE (TREE_VALUE (t)) == COMPOUND_EXPR)
8224 append_to_statement_list (TREE_OPERAND (TREE_VALUE (t), 0),
8225 last_body);
8226 TREE_VALUE (t) = TREE_OPERAND (TREE_VALUE (t), 1);
8228 if (error_operand_p (TREE_VALUE (t)))
8229 return;
8230 append_to_statement_list_force (TREE_VALUE (t), last_body);
8231 TREE_VALUE (t) = null_pointer_node;
8233 else
8235 if (last_bind)
8237 append_to_statement_list (label, last_body);
8238 gimplify_and_add (last_bind, pre_p);
8239 last_bind = NULL_TREE;
8241 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
8243 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
8244 NULL, is_gimple_val, fb_rvalue);
8245 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
8247 if (error_operand_p (OMP_CLAUSE_DECL (c)))
8248 return;
8249 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
8250 is_gimple_lvalue, fb_lvalue) == GS_ERROR)
8251 return;
8252 gimplify_and_add (OMP_CLAUSE_DECL (c), pre_p);
8255 if (last_bind)
8257 append_to_statement_list (label, last_body);
8258 gimplify_and_add (last_bind, pre_p);
8260 return;
8263 /* If *LIST_P contains any OpenMP depend clauses with iterators,
8264 lower all the depend clauses by populating corresponding depend
8265 array. Returns 0 if there are no such depend clauses, or
8266 2 if all depend clauses should be removed, 1 otherwise. */
8268 static int
8269 gimplify_omp_depend (tree *list_p, gimple_seq *pre_p)
8271 tree c;
8272 gimple *g;
8273 size_t n[4] = { 0, 0, 0, 0 };
8274 bool unused[4];
8275 tree counts[4] = { NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE };
8276 tree last_iter = NULL_TREE, last_count = NULL_TREE;
8277 size_t i, j;
8278 location_t first_loc = UNKNOWN_LOCATION;
8280 for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
8281 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
8283 switch (OMP_CLAUSE_DEPEND_KIND (c))
8285 case OMP_CLAUSE_DEPEND_IN:
8286 i = 2;
8287 break;
8288 case OMP_CLAUSE_DEPEND_OUT:
8289 case OMP_CLAUSE_DEPEND_INOUT:
8290 i = 0;
8291 break;
8292 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
8293 i = 1;
8294 break;
8295 case OMP_CLAUSE_DEPEND_DEPOBJ:
8296 i = 3;
8297 break;
8298 case OMP_CLAUSE_DEPEND_SOURCE:
8299 case OMP_CLAUSE_DEPEND_SINK:
8300 continue;
8301 default:
8302 gcc_unreachable ();
8304 tree t = OMP_CLAUSE_DECL (c);
8305 if (first_loc == UNKNOWN_LOCATION)
8306 first_loc = OMP_CLAUSE_LOCATION (c);
8307 if (TREE_CODE (t) == TREE_LIST
8308 && TREE_PURPOSE (t)
8309 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
8311 if (TREE_PURPOSE (t) != last_iter)
8313 tree tcnt = size_one_node;
8314 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8316 if (gimplify_expr (&TREE_VEC_ELT (it, 1), pre_p, NULL,
8317 is_gimple_val, fb_rvalue) == GS_ERROR
8318 || gimplify_expr (&TREE_VEC_ELT (it, 2), pre_p, NULL,
8319 is_gimple_val, fb_rvalue) == GS_ERROR
8320 || gimplify_expr (&TREE_VEC_ELT (it, 3), pre_p, NULL,
8321 is_gimple_val, fb_rvalue) == GS_ERROR
8322 || (gimplify_expr (&TREE_VEC_ELT (it, 4), pre_p, NULL,
8323 is_gimple_val, fb_rvalue)
8324 == GS_ERROR))
8325 return 2;
8326 tree var = TREE_VEC_ELT (it, 0);
8327 tree begin = TREE_VEC_ELT (it, 1);
8328 tree end = TREE_VEC_ELT (it, 2);
8329 tree step = TREE_VEC_ELT (it, 3);
8330 tree orig_step = TREE_VEC_ELT (it, 4);
8331 tree type = TREE_TYPE (var);
8332 tree stype = TREE_TYPE (step);
8333 location_t loc = DECL_SOURCE_LOCATION (var);
8334 tree endmbegin;
8335 /* Compute count for this iterator as
8336 orig_step > 0
8337 ? (begin < end ? (end - begin + (step - 1)) / step : 0)
8338 : (begin > end ? (end - begin + (step + 1)) / step : 0)
8339 and compute product of those for the entire depend
8340 clause. */
8341 if (POINTER_TYPE_P (type))
8342 endmbegin = fold_build2_loc (loc, POINTER_DIFF_EXPR,
8343 stype, end, begin);
8344 else
8345 endmbegin = fold_build2_loc (loc, MINUS_EXPR, type,
8346 end, begin);
8347 tree stepm1 = fold_build2_loc (loc, MINUS_EXPR, stype,
8348 step,
8349 build_int_cst (stype, 1));
8350 tree stepp1 = fold_build2_loc (loc, PLUS_EXPR, stype, step,
8351 build_int_cst (stype, 1));
8352 tree pos = fold_build2_loc (loc, PLUS_EXPR, stype,
8353 unshare_expr (endmbegin),
8354 stepm1);
8355 pos = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype,
8356 pos, step);
8357 tree neg = fold_build2_loc (loc, PLUS_EXPR, stype,
8358 endmbegin, stepp1);
8359 if (TYPE_UNSIGNED (stype))
8361 neg = fold_build1_loc (loc, NEGATE_EXPR, stype, neg);
8362 step = fold_build1_loc (loc, NEGATE_EXPR, stype, step);
8364 neg = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype,
8365 neg, step);
8366 step = NULL_TREE;
8367 tree cond = fold_build2_loc (loc, LT_EXPR,
8368 boolean_type_node,
8369 begin, end);
8370 pos = fold_build3_loc (loc, COND_EXPR, stype, cond, pos,
8371 build_int_cst (stype, 0));
8372 cond = fold_build2_loc (loc, LT_EXPR, boolean_type_node,
8373 end, begin);
8374 neg = fold_build3_loc (loc, COND_EXPR, stype, cond, neg,
8375 build_int_cst (stype, 0));
8376 tree osteptype = TREE_TYPE (orig_step);
8377 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8378 orig_step,
8379 build_int_cst (osteptype, 0));
8380 tree cnt = fold_build3_loc (loc, COND_EXPR, stype,
8381 cond, pos, neg);
8382 cnt = fold_convert_loc (loc, sizetype, cnt);
8383 if (gimplify_expr (&cnt, pre_p, NULL, is_gimple_val,
8384 fb_rvalue) == GS_ERROR)
8385 return 2;
8386 tcnt = size_binop_loc (loc, MULT_EXPR, tcnt, cnt);
8388 if (gimplify_expr (&tcnt, pre_p, NULL, is_gimple_val,
8389 fb_rvalue) == GS_ERROR)
8390 return 2;
8391 last_iter = TREE_PURPOSE (t);
8392 last_count = tcnt;
8394 if (counts[i] == NULL_TREE)
8395 counts[i] = last_count;
8396 else
8397 counts[i] = size_binop_loc (OMP_CLAUSE_LOCATION (c),
8398 PLUS_EXPR, counts[i], last_count);
8400 else
8401 n[i]++;
8403 for (i = 0; i < 4; i++)
8404 if (counts[i])
8405 break;
8406 if (i == 4)
8407 return 0;
8409 tree total = size_zero_node;
8410 for (i = 0; i < 4; i++)
8412 unused[i] = counts[i] == NULL_TREE && n[i] == 0;
8413 if (counts[i] == NULL_TREE)
8414 counts[i] = size_zero_node;
8415 if (n[i])
8416 counts[i] = size_binop (PLUS_EXPR, counts[i], size_int (n[i]));
8417 if (gimplify_expr (&counts[i], pre_p, NULL, is_gimple_val,
8418 fb_rvalue) == GS_ERROR)
8419 return 2;
8420 total = size_binop (PLUS_EXPR, total, counts[i]);
8423 if (gimplify_expr (&total, pre_p, NULL, is_gimple_val, fb_rvalue)
8424 == GS_ERROR)
8425 return 2;
8426 bool is_old = unused[1] && unused[3];
8427 tree totalpx = size_binop (PLUS_EXPR, unshare_expr (total),
8428 size_int (is_old ? 1 : 4));
8429 tree type = build_array_type (ptr_type_node, build_index_type (totalpx));
8430 tree array = create_tmp_var_raw (type);
8431 TREE_ADDRESSABLE (array) = 1;
8432 if (!poly_int_tree_p (totalpx))
8434 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (array)))
8435 gimplify_type_sizes (TREE_TYPE (array), pre_p);
8436 if (gimplify_omp_ctxp)
8438 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
8439 while (ctx
8440 && (ctx->region_type == ORT_WORKSHARE
8441 || ctx->region_type == ORT_TASKGROUP
8442 || ctx->region_type == ORT_SIMD
8443 || ctx->region_type == ORT_ACC))
8444 ctx = ctx->outer_context;
8445 if (ctx)
8446 omp_add_variable (ctx, array, GOVD_LOCAL | GOVD_SEEN);
8448 gimplify_vla_decl (array, pre_p);
8450 else
8451 gimple_add_tmp_var (array);
8452 tree r = build4 (ARRAY_REF, ptr_type_node, array, size_int (0), NULL_TREE,
8453 NULL_TREE);
8454 tree tem;
8455 if (!is_old)
8457 tem = build2 (MODIFY_EXPR, void_type_node, r,
8458 build_int_cst (ptr_type_node, 0));
8459 gimplify_and_add (tem, pre_p);
8460 r = build4 (ARRAY_REF, ptr_type_node, array, size_int (1), NULL_TREE,
8461 NULL_TREE);
8463 tem = build2 (MODIFY_EXPR, void_type_node, r,
8464 fold_convert (ptr_type_node, total));
8465 gimplify_and_add (tem, pre_p);
8466 for (i = 1; i < (is_old ? 2 : 4); i++)
8468 r = build4 (ARRAY_REF, ptr_type_node, array, size_int (i + !is_old),
8469 NULL_TREE, NULL_TREE);
8470 tem = build2 (MODIFY_EXPR, void_type_node, r, counts[i - 1]);
8471 gimplify_and_add (tem, pre_p);
8474 tree cnts[4];
8475 for (j = 4; j; j--)
8476 if (!unused[j - 1])
8477 break;
8478 for (i = 0; i < 4; i++)
8480 if (i && (i >= j || unused[i - 1]))
8482 cnts[i] = cnts[i - 1];
8483 continue;
8485 cnts[i] = create_tmp_var (sizetype);
8486 if (i == 0)
8487 g = gimple_build_assign (cnts[i], size_int (is_old ? 2 : 5));
8488 else
8490 tree t;
8491 if (is_old)
8492 t = size_binop (PLUS_EXPR, counts[0], size_int (2));
8493 else
8494 t = size_binop (PLUS_EXPR, cnts[i - 1], counts[i - 1]);
8495 if (gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue)
8496 == GS_ERROR)
8497 return 2;
8498 g = gimple_build_assign (cnts[i], t);
8500 gimple_seq_add_stmt (pre_p, g);
8503 last_iter = NULL_TREE;
8504 tree last_bind = NULL_TREE;
8505 tree *last_body = NULL;
8506 for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
8507 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
8509 switch (OMP_CLAUSE_DEPEND_KIND (c))
8511 case OMP_CLAUSE_DEPEND_IN:
8512 i = 2;
8513 break;
8514 case OMP_CLAUSE_DEPEND_OUT:
8515 case OMP_CLAUSE_DEPEND_INOUT:
8516 i = 0;
8517 break;
8518 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
8519 i = 1;
8520 break;
8521 case OMP_CLAUSE_DEPEND_DEPOBJ:
8522 i = 3;
8523 break;
8524 case OMP_CLAUSE_DEPEND_SOURCE:
8525 case OMP_CLAUSE_DEPEND_SINK:
8526 continue;
8527 default:
8528 gcc_unreachable ();
8530 tree t = OMP_CLAUSE_DECL (c);
8531 if (TREE_CODE (t) == TREE_LIST
8532 && TREE_PURPOSE (t)
8533 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
8535 if (TREE_PURPOSE (t) != last_iter)
8537 if (last_bind)
8538 gimplify_and_add (last_bind, pre_p);
8539 tree block = TREE_VEC_ELT (TREE_PURPOSE (t), 5);
8540 last_bind = build3 (BIND_EXPR, void_type_node,
8541 BLOCK_VARS (block), NULL, block);
8542 TREE_SIDE_EFFECTS (last_bind) = 1;
8543 SET_EXPR_LOCATION (last_bind, OMP_CLAUSE_LOCATION (c));
8544 tree *p = &BIND_EXPR_BODY (last_bind);
8545 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8547 tree var = TREE_VEC_ELT (it, 0);
8548 tree begin = TREE_VEC_ELT (it, 1);
8549 tree end = TREE_VEC_ELT (it, 2);
8550 tree step = TREE_VEC_ELT (it, 3);
8551 tree orig_step = TREE_VEC_ELT (it, 4);
8552 tree type = TREE_TYPE (var);
8553 location_t loc = DECL_SOURCE_LOCATION (var);
8554 /* Emit:
8555 var = begin;
8556 goto cond_label;
8557 beg_label:
8559 var = var + step;
8560 cond_label:
8561 if (orig_step > 0) {
8562 if (var < end) goto beg_label;
8563 } else {
8564 if (var > end) goto beg_label;
8566 for each iterator, with inner iterators added to
8567 the ... above. */
8568 tree beg_label = create_artificial_label (loc);
8569 tree cond_label = NULL_TREE;
8570 tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
8571 var, begin);
8572 append_to_statement_list_force (tem, p);
8573 tem = build_and_jump (&cond_label);
8574 append_to_statement_list_force (tem, p);
8575 tem = build1 (LABEL_EXPR, void_type_node, beg_label);
8576 append_to_statement_list (tem, p);
8577 tree bind = build3 (BIND_EXPR, void_type_node, NULL_TREE,
8578 NULL_TREE, NULL_TREE);
8579 TREE_SIDE_EFFECTS (bind) = 1;
8580 SET_EXPR_LOCATION (bind, loc);
8581 append_to_statement_list_force (bind, p);
8582 if (POINTER_TYPE_P (type))
8583 tem = build2_loc (loc, POINTER_PLUS_EXPR, type,
8584 var, fold_convert_loc (loc, sizetype,
8585 step));
8586 else
8587 tem = build2_loc (loc, PLUS_EXPR, type, var, step);
8588 tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
8589 var, tem);
8590 append_to_statement_list_force (tem, p);
8591 tem = build1 (LABEL_EXPR, void_type_node, cond_label);
8592 append_to_statement_list (tem, p);
8593 tree cond = fold_build2_loc (loc, LT_EXPR,
8594 boolean_type_node,
8595 var, end);
8596 tree pos
8597 = fold_build3_loc (loc, COND_EXPR, void_type_node,
8598 cond, build_and_jump (&beg_label),
8599 void_node);
8600 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8601 var, end);
8602 tree neg
8603 = fold_build3_loc (loc, COND_EXPR, void_type_node,
8604 cond, build_and_jump (&beg_label),
8605 void_node);
8606 tree osteptype = TREE_TYPE (orig_step);
8607 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8608 orig_step,
8609 build_int_cst (osteptype, 0));
8610 tem = fold_build3_loc (loc, COND_EXPR, void_type_node,
8611 cond, pos, neg);
8612 append_to_statement_list_force (tem, p);
8613 p = &BIND_EXPR_BODY (bind);
8615 last_body = p;
8617 last_iter = TREE_PURPOSE (t);
8618 if (TREE_CODE (TREE_VALUE (t)) == COMPOUND_EXPR)
8620 append_to_statement_list (TREE_OPERAND (TREE_VALUE (t),
8621 0), last_body);
8622 TREE_VALUE (t) = TREE_OPERAND (TREE_VALUE (t), 1);
8624 if (error_operand_p (TREE_VALUE (t)))
8625 return 2;
8626 TREE_VALUE (t) = build_fold_addr_expr (TREE_VALUE (t));
8627 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
8628 NULL_TREE, NULL_TREE);
8629 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
8630 void_type_node, r, TREE_VALUE (t));
8631 append_to_statement_list_force (tem, last_body);
8632 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
8633 void_type_node, cnts[i],
8634 size_binop (PLUS_EXPR, cnts[i], size_int (1)));
8635 append_to_statement_list_force (tem, last_body);
8636 TREE_VALUE (t) = null_pointer_node;
8638 else
8640 if (last_bind)
8642 gimplify_and_add (last_bind, pre_p);
8643 last_bind = NULL_TREE;
8645 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
8647 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
8648 NULL, is_gimple_val, fb_rvalue);
8649 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
8651 if (error_operand_p (OMP_CLAUSE_DECL (c)))
8652 return 2;
8653 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
8654 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
8655 is_gimple_val, fb_rvalue) == GS_ERROR)
8656 return 2;
8657 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
8658 NULL_TREE, NULL_TREE);
8659 tem = build2 (MODIFY_EXPR, void_type_node, r, OMP_CLAUSE_DECL (c));
8660 gimplify_and_add (tem, pre_p);
8661 g = gimple_build_assign (cnts[i], size_binop (PLUS_EXPR, cnts[i],
8662 size_int (1)));
8663 gimple_seq_add_stmt (pre_p, g);
8666 if (last_bind)
8667 gimplify_and_add (last_bind, pre_p);
8668 tree cond = boolean_false_node;
8669 if (is_old)
8671 if (!unused[0])
8672 cond = build2_loc (first_loc, NE_EXPR, boolean_type_node, cnts[0],
8673 size_binop_loc (first_loc, PLUS_EXPR, counts[0],
8674 size_int (2)));
8675 if (!unused[2])
8676 cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond,
8677 build2_loc (first_loc, NE_EXPR, boolean_type_node,
8678 cnts[2],
8679 size_binop_loc (first_loc, PLUS_EXPR,
8680 totalpx,
8681 size_int (1))));
8683 else
8685 tree prev = size_int (5);
8686 for (i = 0; i < 4; i++)
8688 if (unused[i])
8689 continue;
8690 prev = size_binop_loc (first_loc, PLUS_EXPR, counts[i], prev);
8691 cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond,
8692 build2_loc (first_loc, NE_EXPR, boolean_type_node,
8693 cnts[i], unshare_expr (prev)));
8696 tem = build3_loc (first_loc, COND_EXPR, void_type_node, cond,
8697 build_call_expr_loc (first_loc,
8698 builtin_decl_explicit (BUILT_IN_TRAP),
8699 0), void_node);
8700 gimplify_and_add (tem, pre_p);
8701 c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_DEPEND);
8702 OMP_CLAUSE_DEPEND_KIND (c) = OMP_CLAUSE_DEPEND_LAST;
8703 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (array);
8704 OMP_CLAUSE_CHAIN (c) = *list_p;
8705 *list_p = c;
8706 return 1;
8709 /* Insert a GOMP_MAP_ALLOC or GOMP_MAP_RELEASE node following a
8710 GOMP_MAP_STRUCT mapping. C is an always_pointer mapping. STRUCT_NODE is
8711 the struct node to insert the new mapping after (when the struct node is
8712 initially created). PREV_NODE is the first of two or three mappings for a
8713 pointer, and is either:
8714 - the node before C, when a pair of mappings is used, e.g. for a C/C++
8715 array section.
8716 - not the node before C. This is true when we have a reference-to-pointer
8717 type (with a mapping for the reference and for the pointer), or for
8718 Fortran derived-type mappings with a GOMP_MAP_TO_PSET.
8719 If SCP is non-null, the new node is inserted before *SCP.
8720 if SCP is null, the new node is inserted before PREV_NODE.
8721 The return type is:
8722 - PREV_NODE, if SCP is non-null.
8723 - The newly-created ALLOC or RELEASE node, if SCP is null.
8724 - The second newly-created ALLOC or RELEASE node, if we are mapping a
8725 reference to a pointer. */
8727 static tree
8728 insert_struct_comp_map (enum tree_code code, tree c, tree struct_node,
8729 tree prev_node, tree *scp)
8731 enum gomp_map_kind mkind
8732 = (code == OMP_TARGET_EXIT_DATA || code == OACC_EXIT_DATA)
8733 ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
8735 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
8736 tree cl = scp ? prev_node : c2;
8737 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
8738 OMP_CLAUSE_DECL (c2) = unshare_expr (OMP_CLAUSE_DECL (c));
8739 OMP_CLAUSE_CHAIN (c2) = scp ? *scp : prev_node;
8740 if (OMP_CLAUSE_CHAIN (prev_node) != c
8741 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (prev_node)) == OMP_CLAUSE_MAP
8742 && (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node))
8743 == GOMP_MAP_TO_PSET))
8744 OMP_CLAUSE_SIZE (c2) = OMP_CLAUSE_SIZE (OMP_CLAUSE_CHAIN (prev_node));
8745 else
8746 OMP_CLAUSE_SIZE (c2) = TYPE_SIZE_UNIT (ptr_type_node);
8747 if (struct_node)
8748 OMP_CLAUSE_CHAIN (struct_node) = c2;
8750 /* We might need to create an additional mapping if we have a reference to a
8751 pointer (in C++). Don't do this if we have something other than a
8752 GOMP_MAP_ALWAYS_POINTER though, i.e. a GOMP_MAP_TO_PSET. */
8753 if (OMP_CLAUSE_CHAIN (prev_node) != c
8754 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (prev_node)) == OMP_CLAUSE_MAP
8755 && ((OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node))
8756 == GOMP_MAP_ALWAYS_POINTER)
8757 || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node))
8758 == GOMP_MAP_ATTACH_DETACH)))
8760 tree c4 = OMP_CLAUSE_CHAIN (prev_node);
8761 tree c3 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
8762 OMP_CLAUSE_SET_MAP_KIND (c3, mkind);
8763 OMP_CLAUSE_DECL (c3) = unshare_expr (OMP_CLAUSE_DECL (c4));
8764 OMP_CLAUSE_SIZE (c3) = TYPE_SIZE_UNIT (ptr_type_node);
8765 OMP_CLAUSE_CHAIN (c3) = prev_node;
8766 if (!scp)
8767 OMP_CLAUSE_CHAIN (c2) = c3;
8768 else
8769 cl = c3;
8772 if (scp)
8773 *scp = c2;
8775 return cl;
8778 /* Strip ARRAY_REFS or an indirect ref off BASE, find the containing object,
8779 and set *BITPOSP and *POFFSETP to the bit offset of the access.
8780 If BASE_REF is non-NULL and the containing object is a reference, set
8781 *BASE_REF to that reference before dereferencing the object.
8782 If BASE_REF is NULL, check that the containing object is a COMPONENT_REF or
8783 has array type, else return NULL. */
8785 static tree
8786 extract_base_bit_offset (tree base, tree *base_ref, poly_int64 *bitposp,
8787 poly_offset_int *poffsetp, tree *offsetp)
8789 tree offset;
8790 poly_int64 bitsize, bitpos;
8791 machine_mode mode;
8792 int unsignedp, reversep, volatilep = 0;
8793 poly_offset_int poffset;
8795 if (base_ref)
8797 *base_ref = NULL_TREE;
8799 while (TREE_CODE (base) == ARRAY_REF)
8800 base = TREE_OPERAND (base, 0);
8802 if (TREE_CODE (base) == INDIRECT_REF)
8803 base = TREE_OPERAND (base, 0);
8805 else
8807 if (TREE_CODE (base) == ARRAY_REF)
8809 while (TREE_CODE (base) == ARRAY_REF)
8810 base = TREE_OPERAND (base, 0);
8811 if (TREE_CODE (base) != COMPONENT_REF
8812 || TREE_CODE (TREE_TYPE (base)) != ARRAY_TYPE)
8813 return NULL_TREE;
8815 else if (TREE_CODE (base) == INDIRECT_REF
8816 && TREE_CODE (TREE_OPERAND (base, 0)) == COMPONENT_REF
8817 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0)))
8818 == REFERENCE_TYPE))
8819 base = TREE_OPERAND (base, 0);
8822 base = get_inner_reference (base, &bitsize, &bitpos, &offset, &mode,
8823 &unsignedp, &reversep, &volatilep);
8825 tree orig_base = base;
8827 if ((TREE_CODE (base) == INDIRECT_REF
8828 || (TREE_CODE (base) == MEM_REF
8829 && integer_zerop (TREE_OPERAND (base, 1))))
8830 && DECL_P (TREE_OPERAND (base, 0))
8831 && TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0))) == REFERENCE_TYPE)
8832 base = TREE_OPERAND (base, 0);
8834 if (offset && poly_int_tree_p (offset))
8836 poffset = wi::to_poly_offset (offset);
8837 offset = NULL_TREE;
8839 else
8840 poffset = 0;
8842 if (maybe_ne (bitpos, 0))
8843 poffset += bits_to_bytes_round_down (bitpos);
8845 *bitposp = bitpos;
8846 *poffsetp = poffset;
8847 *offsetp = offset;
8849 /* Set *BASE_REF if BASE was a dereferenced reference variable. */
8850 if (base_ref && orig_base != base)
8851 *base_ref = orig_base;
8853 return base;
8856 /* Returns true if EXPR is or contains (as a sub-component) BASE_PTR. */
8858 static bool
8859 is_or_contains_p (tree expr, tree base_ptr)
8861 if ((TREE_CODE (expr) == INDIRECT_REF && TREE_CODE (base_ptr) == MEM_REF)
8862 || (TREE_CODE (expr) == MEM_REF && TREE_CODE (base_ptr) == INDIRECT_REF))
8863 return operand_equal_p (TREE_OPERAND (expr, 0),
8864 TREE_OPERAND (base_ptr, 0));
8865 while (!operand_equal_p (expr, base_ptr))
8867 if (TREE_CODE (base_ptr) == COMPOUND_EXPR)
8868 base_ptr = TREE_OPERAND (base_ptr, 1);
8869 if (TREE_CODE (base_ptr) == COMPONENT_REF
8870 || TREE_CODE (base_ptr) == POINTER_PLUS_EXPR
8871 || TREE_CODE (base_ptr) == SAVE_EXPR)
8872 base_ptr = TREE_OPERAND (base_ptr, 0);
8873 else
8874 break;
8876 return operand_equal_p (expr, base_ptr);
8879 /* Implement OpenMP 5.x map ordering rules for target directives. There are
8880 several rules, and with some level of ambiguity, hopefully we can at least
8881 collect the complexity here in one place. */
8883 static void
8884 omp_target_reorder_clauses (tree *list_p)
8886 /* Collect refs to alloc/release/delete maps. */
8887 auto_vec<tree, 32> ard;
8888 tree *cp = list_p;
8889 while (*cp != NULL_TREE)
8890 if (OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP
8891 && (OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_ALLOC
8892 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_RELEASE
8893 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_DELETE))
8895 /* Unlink cp and push to ard. */
8896 tree c = *cp;
8897 tree nc = OMP_CLAUSE_CHAIN (c);
8898 *cp = nc;
8899 ard.safe_push (c);
8901 /* Any associated pointer type maps should also move along. */
8902 while (*cp != NULL_TREE
8903 && OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP
8904 && (OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
8905 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_FIRSTPRIVATE_POINTER
8906 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_ATTACH_DETACH
8907 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_POINTER
8908 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_ALWAYS_POINTER
8909 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_TO_PSET))
8911 c = *cp;
8912 nc = OMP_CLAUSE_CHAIN (c);
8913 *cp = nc;
8914 ard.safe_push (c);
8917 else
8918 cp = &OMP_CLAUSE_CHAIN (*cp);
8920 /* Link alloc/release/delete maps to the end of list. */
8921 for (unsigned int i = 0; i < ard.length (); i++)
8923 *cp = ard[i];
8924 cp = &OMP_CLAUSE_CHAIN (ard[i]);
8926 *cp = NULL_TREE;
8928 /* OpenMP 5.0 requires that pointer variables are mapped before
8929 its use as a base-pointer. */
8930 auto_vec<tree *, 32> atf;
8931 for (tree *cp = list_p; *cp; cp = &OMP_CLAUSE_CHAIN (*cp))
8932 if (OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP)
8934 /* Collect alloc, to, from, to/from clause tree pointers. */
8935 gomp_map_kind k = OMP_CLAUSE_MAP_KIND (*cp);
8936 if (k == GOMP_MAP_ALLOC
8937 || k == GOMP_MAP_TO
8938 || k == GOMP_MAP_FROM
8939 || k == GOMP_MAP_TOFROM
8940 || k == GOMP_MAP_ALWAYS_TO
8941 || k == GOMP_MAP_ALWAYS_FROM
8942 || k == GOMP_MAP_ALWAYS_TOFROM)
8943 atf.safe_push (cp);
8946 for (unsigned int i = 0; i < atf.length (); i++)
8947 if (atf[i])
8949 tree *cp = atf[i];
8950 tree decl = OMP_CLAUSE_DECL (*cp);
8951 if (TREE_CODE (decl) == INDIRECT_REF || TREE_CODE (decl) == MEM_REF)
8953 tree base_ptr = TREE_OPERAND (decl, 0);
8954 STRIP_TYPE_NOPS (base_ptr);
8955 for (unsigned int j = i + 1; j < atf.length (); j++)
8956 if (atf[j])
8958 tree *cp2 = atf[j];
8959 tree decl2 = OMP_CLAUSE_DECL (*cp2);
8961 decl2 = OMP_CLAUSE_DECL (*cp2);
8962 if (is_or_contains_p (decl2, base_ptr))
8964 /* Move *cp2 to before *cp. */
8965 tree c = *cp2;
8966 *cp2 = OMP_CLAUSE_CHAIN (c);
8967 OMP_CLAUSE_CHAIN (c) = *cp;
8968 *cp = c;
8970 if (*cp2 != NULL_TREE
8971 && OMP_CLAUSE_CODE (*cp2) == OMP_CLAUSE_MAP
8972 && OMP_CLAUSE_MAP_KIND (*cp2) == GOMP_MAP_ALWAYS_POINTER)
8974 tree c2 = *cp2;
8975 *cp2 = OMP_CLAUSE_CHAIN (c2);
8976 OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (c);
8977 OMP_CLAUSE_CHAIN (c) = c2;
8980 atf[j] = NULL;
8986 /* For attach_detach map clauses, if there is another map that maps the
8987 attached/detached pointer, make sure that map is ordered before the
8988 attach_detach. */
8989 atf.truncate (0);
8990 for (tree *cp = list_p; *cp; cp = &OMP_CLAUSE_CHAIN (*cp))
8991 if (OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP)
8993 /* Collect alloc, to, from, to/from clauses, and
8994 always_pointer/attach_detach clauses. */
8995 gomp_map_kind k = OMP_CLAUSE_MAP_KIND (*cp);
8996 if (k == GOMP_MAP_ALLOC
8997 || k == GOMP_MAP_TO
8998 || k == GOMP_MAP_FROM
8999 || k == GOMP_MAP_TOFROM
9000 || k == GOMP_MAP_ALWAYS_TO
9001 || k == GOMP_MAP_ALWAYS_FROM
9002 || k == GOMP_MAP_ALWAYS_TOFROM
9003 || k == GOMP_MAP_ATTACH_DETACH
9004 || k == GOMP_MAP_ALWAYS_POINTER)
9005 atf.safe_push (cp);
9008 for (unsigned int i = 0; i < atf.length (); i++)
9009 if (atf[i])
9011 tree *cp = atf[i];
9012 tree ptr = OMP_CLAUSE_DECL (*cp);
9013 STRIP_TYPE_NOPS (ptr);
9014 if (OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_ATTACH_DETACH)
9015 for (unsigned int j = i + 1; j < atf.length (); j++)
9017 tree *cp2 = atf[j];
9018 tree decl2 = OMP_CLAUSE_DECL (*cp2);
9019 if (OMP_CLAUSE_MAP_KIND (*cp2) != GOMP_MAP_ATTACH_DETACH
9020 && OMP_CLAUSE_MAP_KIND (*cp2) != GOMP_MAP_ALWAYS_POINTER
9021 && is_or_contains_p (decl2, ptr))
9023 /* Move *cp2 to before *cp. */
9024 tree c = *cp2;
9025 *cp2 = OMP_CLAUSE_CHAIN (c);
9026 OMP_CLAUSE_CHAIN (c) = *cp;
9027 *cp = c;
9028 atf[j] = NULL;
9030 /* If decl2 is of the form '*decl2_opnd0', and followed by an
9031 ALWAYS_POINTER or ATTACH_DETACH of 'decl2_opnd0', move the
9032 pointer operation along with *cp2. This can happen for C++
9033 reference sequences. */
9034 if (j + 1 < atf.length ()
9035 && (TREE_CODE (decl2) == INDIRECT_REF
9036 || TREE_CODE (decl2) == MEM_REF))
9038 tree *cp3 = atf[j + 1];
9039 tree decl3 = OMP_CLAUSE_DECL (*cp3);
9040 tree decl2_opnd0 = TREE_OPERAND (decl2, 0);
9041 if ((OMP_CLAUSE_MAP_KIND (*cp3) == GOMP_MAP_ALWAYS_POINTER
9042 || OMP_CLAUSE_MAP_KIND (*cp3) == GOMP_MAP_ATTACH_DETACH)
9043 && operand_equal_p (decl3, decl2_opnd0))
9045 /* Also move *cp3 to before *cp. */
9046 c = *cp3;
9047 *cp2 = OMP_CLAUSE_CHAIN (c);
9048 OMP_CLAUSE_CHAIN (c) = *cp;
9049 *cp = c;
9050 atf[j + 1] = NULL;
9051 j += 1;
9059 /* DECL is supposed to have lastprivate semantics in the outer contexts
9060 of combined/composite constructs, starting with OCTX.
9061 Add needed lastprivate, shared or map clause if no data sharing or
9062 mapping clause are present. IMPLICIT_P is true if it is an implicit
9063 clause (IV on simd), in which case the lastprivate will not be
9064 copied to some constructs. */
9066 static void
9067 omp_lastprivate_for_combined_outer_constructs (struct gimplify_omp_ctx *octx,
9068 tree decl, bool implicit_p)
9070 struct gimplify_omp_ctx *orig_octx = octx;
9071 for (; octx; octx = octx->outer_context)
9073 if ((octx->region_type == ORT_COMBINED_PARALLEL
9074 || (octx->region_type & ORT_COMBINED_TEAMS) == ORT_COMBINED_TEAMS)
9075 && splay_tree_lookup (octx->variables,
9076 (splay_tree_key) decl) == NULL)
9078 omp_add_variable (octx, decl, GOVD_SHARED | GOVD_SEEN);
9079 continue;
9081 if ((octx->region_type & ORT_TASK) != 0
9082 && octx->combined_loop
9083 && splay_tree_lookup (octx->variables,
9084 (splay_tree_key) decl) == NULL)
9086 omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
9087 continue;
9089 if (implicit_p
9090 && octx->region_type == ORT_WORKSHARE
9091 && octx->combined_loop
9092 && splay_tree_lookup (octx->variables,
9093 (splay_tree_key) decl) == NULL
9094 && octx->outer_context
9095 && octx->outer_context->region_type == ORT_COMBINED_PARALLEL
9096 && splay_tree_lookup (octx->outer_context->variables,
9097 (splay_tree_key) decl) == NULL)
9099 octx = octx->outer_context;
9100 omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
9101 continue;
9103 if ((octx->region_type == ORT_WORKSHARE || octx->region_type == ORT_ACC)
9104 && octx->combined_loop
9105 && splay_tree_lookup (octx->variables,
9106 (splay_tree_key) decl) == NULL
9107 && !omp_check_private (octx, decl, false))
9109 omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
9110 continue;
9112 if (octx->region_type == ORT_COMBINED_TARGET)
9114 splay_tree_node n = splay_tree_lookup (octx->variables,
9115 (splay_tree_key) decl);
9116 if (n == NULL)
9118 omp_add_variable (octx, decl, GOVD_MAP | GOVD_SEEN);
9119 octx = octx->outer_context;
9121 else if (!implicit_p
9122 && (n->value & GOVD_FIRSTPRIVATE_IMPLICIT))
9124 n->value &= ~(GOVD_FIRSTPRIVATE
9125 | GOVD_FIRSTPRIVATE_IMPLICIT
9126 | GOVD_EXPLICIT);
9127 omp_add_variable (octx, decl, GOVD_MAP | GOVD_SEEN);
9128 octx = octx->outer_context;
9131 break;
9133 if (octx && (implicit_p || octx != orig_octx))
9134 omp_notice_variable (octx, decl, true);
9137 /* Scan the OMP clauses in *LIST_P, installing mappings into a new
9138 and previous omp contexts. */
9140 static void
9141 gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
9142 enum omp_region_type region_type,
9143 enum tree_code code)
9145 struct gimplify_omp_ctx *ctx, *outer_ctx;
9146 tree c;
9147 hash_map<tree_operand_hash, tree> *struct_map_to_clause = NULL;
9148 hash_map<tree_operand_hash, tree *> *struct_seen_clause = NULL;
9149 hash_set<tree> *struct_deref_set = NULL;
9150 tree *prev_list_p = NULL, *orig_list_p = list_p;
9151 int handled_depend_iterators = -1;
9152 int nowait = -1;
9154 ctx = new_omp_context (region_type);
9155 ctx->code = code;
9156 outer_ctx = ctx->outer_context;
9157 if (code == OMP_TARGET)
9159 if (!lang_GNU_Fortran ())
9160 ctx->defaultmap[GDMK_POINTER] = GOVD_MAP | GOVD_MAP_0LEN_ARRAY;
9161 ctx->defaultmap[GDMK_SCALAR] = GOVD_FIRSTPRIVATE;
9162 ctx->defaultmap[GDMK_SCALAR_TARGET] = (lang_GNU_Fortran ()
9163 ? GOVD_MAP : GOVD_FIRSTPRIVATE);
9165 if (!lang_GNU_Fortran ())
9166 switch (code)
9168 case OMP_TARGET:
9169 case OMP_TARGET_DATA:
9170 case OMP_TARGET_ENTER_DATA:
9171 case OMP_TARGET_EXIT_DATA:
9172 case OACC_DECLARE:
9173 case OACC_HOST_DATA:
9174 case OACC_PARALLEL:
9175 case OACC_KERNELS:
9176 ctx->target_firstprivatize_array_bases = true;
9177 default:
9178 break;
9181 if (code == OMP_TARGET
9182 || code == OMP_TARGET_DATA
9183 || code == OMP_TARGET_ENTER_DATA
9184 || code == OMP_TARGET_EXIT_DATA)
9185 omp_target_reorder_clauses (list_p);
9187 while ((c = *list_p) != NULL)
9189 bool remove = false;
9190 bool notice_outer = true;
9191 const char *check_non_private = NULL;
9192 unsigned int flags;
9193 tree decl;
9195 switch (OMP_CLAUSE_CODE (c))
9197 case OMP_CLAUSE_PRIVATE:
9198 flags = GOVD_PRIVATE | GOVD_EXPLICIT;
9199 if (lang_hooks.decls.omp_private_outer_ref (OMP_CLAUSE_DECL (c)))
9201 flags |= GOVD_PRIVATE_OUTER_REF;
9202 OMP_CLAUSE_PRIVATE_OUTER_REF (c) = 1;
9204 else
9205 notice_outer = false;
9206 goto do_add;
9207 case OMP_CLAUSE_SHARED:
9208 flags = GOVD_SHARED | GOVD_EXPLICIT;
9209 goto do_add;
9210 case OMP_CLAUSE_FIRSTPRIVATE:
9211 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
9212 check_non_private = "firstprivate";
9213 if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c))
9215 gcc_assert (code == OMP_TARGET);
9216 flags |= GOVD_FIRSTPRIVATE_IMPLICIT;
9218 goto do_add;
9219 case OMP_CLAUSE_LASTPRIVATE:
9220 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
9221 switch (code)
9223 case OMP_DISTRIBUTE:
9224 error_at (OMP_CLAUSE_LOCATION (c),
9225 "conditional %<lastprivate%> clause on "
9226 "%qs construct", "distribute");
9227 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
9228 break;
9229 case OMP_TASKLOOP:
9230 error_at (OMP_CLAUSE_LOCATION (c),
9231 "conditional %<lastprivate%> clause on "
9232 "%qs construct", "taskloop");
9233 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
9234 break;
9235 default:
9236 break;
9238 flags = GOVD_LASTPRIVATE | GOVD_SEEN | GOVD_EXPLICIT;
9239 if (code != OMP_LOOP)
9240 check_non_private = "lastprivate";
9241 decl = OMP_CLAUSE_DECL (c);
9242 if (error_operand_p (decl))
9243 goto do_add;
9244 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)
9245 && !lang_hooks.decls.omp_scalar_p (decl, true))
9247 error_at (OMP_CLAUSE_LOCATION (c),
9248 "non-scalar variable %qD in conditional "
9249 "%<lastprivate%> clause", decl);
9250 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
9252 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
9253 flags |= GOVD_LASTPRIVATE_CONDITIONAL;
9254 omp_lastprivate_for_combined_outer_constructs (outer_ctx, decl,
9255 false);
9256 goto do_add;
9257 case OMP_CLAUSE_REDUCTION:
9258 if (OMP_CLAUSE_REDUCTION_TASK (c))
9260 if (region_type == ORT_WORKSHARE || code == OMP_SCOPE)
9262 if (nowait == -1)
9263 nowait = omp_find_clause (*list_p,
9264 OMP_CLAUSE_NOWAIT) != NULL_TREE;
9265 if (nowait
9266 && (outer_ctx == NULL
9267 || outer_ctx->region_type != ORT_COMBINED_PARALLEL))
9269 error_at (OMP_CLAUSE_LOCATION (c),
9270 "%<task%> reduction modifier on a construct "
9271 "with a %<nowait%> clause");
9272 OMP_CLAUSE_REDUCTION_TASK (c) = 0;
9275 else if ((region_type & ORT_PARALLEL) != ORT_PARALLEL)
9277 error_at (OMP_CLAUSE_LOCATION (c),
9278 "invalid %<task%> reduction modifier on construct "
9279 "other than %<parallel%>, %qs, %<sections%> or "
9280 "%<scope%>", lang_GNU_Fortran () ? "do" : "for");
9281 OMP_CLAUSE_REDUCTION_TASK (c) = 0;
9284 if (OMP_CLAUSE_REDUCTION_INSCAN (c))
9285 switch (code)
9287 case OMP_SECTIONS:
9288 error_at (OMP_CLAUSE_LOCATION (c),
9289 "%<inscan%> %<reduction%> clause on "
9290 "%qs construct", "sections");
9291 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
9292 break;
9293 case OMP_PARALLEL:
9294 error_at (OMP_CLAUSE_LOCATION (c),
9295 "%<inscan%> %<reduction%> clause on "
9296 "%qs construct", "parallel");
9297 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
9298 break;
9299 case OMP_TEAMS:
9300 error_at (OMP_CLAUSE_LOCATION (c),
9301 "%<inscan%> %<reduction%> clause on "
9302 "%qs construct", "teams");
9303 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
9304 break;
9305 case OMP_TASKLOOP:
9306 error_at (OMP_CLAUSE_LOCATION (c),
9307 "%<inscan%> %<reduction%> clause on "
9308 "%qs construct", "taskloop");
9309 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
9310 break;
9311 case OMP_SCOPE:
9312 error_at (OMP_CLAUSE_LOCATION (c),
9313 "%<inscan%> %<reduction%> clause on "
9314 "%qs construct", "scope");
9315 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
9316 break;
9317 default:
9318 break;
9320 /* FALLTHRU */
9321 case OMP_CLAUSE_IN_REDUCTION:
9322 case OMP_CLAUSE_TASK_REDUCTION:
9323 flags = GOVD_REDUCTION | GOVD_SEEN | GOVD_EXPLICIT;
9324 /* OpenACC permits reductions on private variables. */
9325 if (!(region_type & ORT_ACC)
9326 /* taskgroup is actually not a worksharing region. */
9327 && code != OMP_TASKGROUP)
9328 check_non_private = omp_clause_code_name[OMP_CLAUSE_CODE (c)];
9329 decl = OMP_CLAUSE_DECL (c);
9330 if (TREE_CODE (decl) == MEM_REF)
9332 tree type = TREE_TYPE (decl);
9333 bool saved_into_ssa = gimplify_ctxp->into_ssa;
9334 gimplify_ctxp->into_ssa = false;
9335 if (gimplify_expr (&TYPE_MAX_VALUE (TYPE_DOMAIN (type)), pre_p,
9336 NULL, is_gimple_val, fb_rvalue, false)
9337 == GS_ERROR)
9339 gimplify_ctxp->into_ssa = saved_into_ssa;
9340 remove = true;
9341 break;
9343 gimplify_ctxp->into_ssa = saved_into_ssa;
9344 tree v = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
9345 if (DECL_P (v))
9347 omp_firstprivatize_variable (ctx, v);
9348 omp_notice_variable (ctx, v, true);
9350 decl = TREE_OPERAND (decl, 0);
9351 if (TREE_CODE (decl) == POINTER_PLUS_EXPR)
9353 gimplify_ctxp->into_ssa = false;
9354 if (gimplify_expr (&TREE_OPERAND (decl, 1), pre_p,
9355 NULL, is_gimple_val, fb_rvalue, false)
9356 == GS_ERROR)
9358 gimplify_ctxp->into_ssa = saved_into_ssa;
9359 remove = true;
9360 break;
9362 gimplify_ctxp->into_ssa = saved_into_ssa;
9363 v = TREE_OPERAND (decl, 1);
9364 if (DECL_P (v))
9366 omp_firstprivatize_variable (ctx, v);
9367 omp_notice_variable (ctx, v, true);
9369 decl = TREE_OPERAND (decl, 0);
9371 if (TREE_CODE (decl) == ADDR_EXPR
9372 || TREE_CODE (decl) == INDIRECT_REF)
9373 decl = TREE_OPERAND (decl, 0);
9375 goto do_add_decl;
9376 case OMP_CLAUSE_LINEAR:
9377 if (gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c), pre_p, NULL,
9378 is_gimple_val, fb_rvalue) == GS_ERROR)
9380 remove = true;
9381 break;
9383 else
9385 if (code == OMP_SIMD
9386 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
9388 struct gimplify_omp_ctx *octx = outer_ctx;
9389 if (octx
9390 && octx->region_type == ORT_WORKSHARE
9391 && octx->combined_loop
9392 && !octx->distribute)
9394 if (octx->outer_context
9395 && (octx->outer_context->region_type
9396 == ORT_COMBINED_PARALLEL))
9397 octx = octx->outer_context->outer_context;
9398 else
9399 octx = octx->outer_context;
9401 if (octx
9402 && octx->region_type == ORT_WORKSHARE
9403 && octx->combined_loop
9404 && octx->distribute)
9406 error_at (OMP_CLAUSE_LOCATION (c),
9407 "%<linear%> clause for variable other than "
9408 "loop iterator specified on construct "
9409 "combined with %<distribute%>");
9410 remove = true;
9411 break;
9414 /* For combined #pragma omp parallel for simd, need to put
9415 lastprivate and perhaps firstprivate too on the
9416 parallel. Similarly for #pragma omp for simd. */
9417 struct gimplify_omp_ctx *octx = outer_ctx;
9418 bool taskloop_seen = false;
9419 decl = NULL_TREE;
9422 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
9423 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
9424 break;
9425 decl = OMP_CLAUSE_DECL (c);
9426 if (error_operand_p (decl))
9428 decl = NULL_TREE;
9429 break;
9431 flags = GOVD_SEEN;
9432 if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c))
9433 flags |= GOVD_FIRSTPRIVATE;
9434 if (!OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
9435 flags |= GOVD_LASTPRIVATE;
9436 if (octx
9437 && octx->region_type == ORT_WORKSHARE
9438 && octx->combined_loop)
9440 if (octx->outer_context
9441 && (octx->outer_context->region_type
9442 == ORT_COMBINED_PARALLEL))
9443 octx = octx->outer_context;
9444 else if (omp_check_private (octx, decl, false))
9445 break;
9447 else if (octx
9448 && (octx->region_type & ORT_TASK) != 0
9449 && octx->combined_loop)
9450 taskloop_seen = true;
9451 else if (octx
9452 && octx->region_type == ORT_COMBINED_PARALLEL
9453 && ((ctx->region_type == ORT_WORKSHARE
9454 && octx == outer_ctx)
9455 || taskloop_seen))
9456 flags = GOVD_SEEN | GOVD_SHARED;
9457 else if (octx
9458 && ((octx->region_type & ORT_COMBINED_TEAMS)
9459 == ORT_COMBINED_TEAMS))
9460 flags = GOVD_SEEN | GOVD_SHARED;
9461 else if (octx
9462 && octx->region_type == ORT_COMBINED_TARGET)
9464 if (flags & GOVD_LASTPRIVATE)
9465 flags = GOVD_SEEN | GOVD_MAP;
9467 else
9468 break;
9469 splay_tree_node on
9470 = splay_tree_lookup (octx->variables,
9471 (splay_tree_key) decl);
9472 if (on && (on->value & GOVD_DATA_SHARE_CLASS) != 0)
9474 octx = NULL;
9475 break;
9477 omp_add_variable (octx, decl, flags);
9478 if (octx->outer_context == NULL)
9479 break;
9480 octx = octx->outer_context;
9482 while (1);
9483 if (octx
9484 && decl
9485 && (!OMP_CLAUSE_LINEAR_NO_COPYIN (c)
9486 || !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
9487 omp_notice_variable (octx, decl, true);
9489 flags = GOVD_LINEAR | GOVD_EXPLICIT;
9490 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
9491 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
9493 notice_outer = false;
9494 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
9496 goto do_add;
9498 case OMP_CLAUSE_MAP:
9499 decl = OMP_CLAUSE_DECL (c);
9500 if (error_operand_p (decl))
9501 remove = true;
9502 switch (code)
9504 case OMP_TARGET:
9505 break;
9506 case OACC_DATA:
9507 if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
9508 break;
9509 /* FALLTHRU */
9510 case OMP_TARGET_DATA:
9511 case OMP_TARGET_ENTER_DATA:
9512 case OMP_TARGET_EXIT_DATA:
9513 case OACC_ENTER_DATA:
9514 case OACC_EXIT_DATA:
9515 case OACC_HOST_DATA:
9516 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
9517 || (OMP_CLAUSE_MAP_KIND (c)
9518 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
9519 /* For target {,enter ,exit }data only the array slice is
9520 mapped, but not the pointer to it. */
9521 remove = true;
9522 break;
9523 default:
9524 break;
9526 /* For Fortran, not only the pointer to the data is mapped but also
9527 the address of the pointer, the array descriptor etc.; for
9528 'exit data' - and in particular for 'delete:' - having an 'alloc:'
9529 does not make sense. Likewise, for 'update' only transferring the
9530 data itself is needed as the rest has been handled in previous
9531 directives. However, for 'exit data', the array descriptor needs
9532 to be delete; hence, we turn the MAP_TO_PSET into a MAP_DELETE.
9534 NOTE: Generally, it is not safe to perform "enter data" operations
9535 on arrays where the data *or the descriptor* may go out of scope
9536 before a corresponding "exit data" operation -- and such a
9537 descriptor may be synthesized temporarily, e.g. to pass an
9538 explicit-shape array to a function expecting an assumed-shape
9539 argument. Performing "enter data" inside the called function
9540 would thus be problematic. */
9541 if (code == OMP_TARGET_EXIT_DATA
9542 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_TO_PSET)
9543 OMP_CLAUSE_SET_MAP_KIND (c, OMP_CLAUSE_MAP_KIND (*prev_list_p)
9544 == GOMP_MAP_DELETE
9545 ? GOMP_MAP_DELETE : GOMP_MAP_RELEASE);
9546 else if ((code == OMP_TARGET_EXIT_DATA || code == OMP_TARGET_UPDATE)
9547 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
9548 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_TO_PSET))
9549 remove = true;
9551 if (remove)
9552 break;
9553 if (DECL_P (decl) && outer_ctx && (region_type & ORT_ACC))
9555 struct gimplify_omp_ctx *octx;
9556 for (octx = outer_ctx; octx; octx = octx->outer_context)
9558 if (octx->region_type != ORT_ACC_HOST_DATA)
9559 break;
9560 splay_tree_node n2
9561 = splay_tree_lookup (octx->variables,
9562 (splay_tree_key) decl);
9563 if (n2)
9564 error_at (OMP_CLAUSE_LOCATION (c), "variable %qE "
9565 "declared in enclosing %<host_data%> region",
9566 DECL_NAME (decl));
9569 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
9570 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
9571 : TYPE_SIZE_UNIT (TREE_TYPE (decl));
9572 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
9573 NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
9575 remove = true;
9576 break;
9578 else if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
9579 || (OMP_CLAUSE_MAP_KIND (c)
9580 == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
9581 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
9582 && TREE_CODE (OMP_CLAUSE_SIZE (c)) != INTEGER_CST)
9584 OMP_CLAUSE_SIZE (c)
9585 = get_initialized_tmp_var (OMP_CLAUSE_SIZE (c), pre_p, NULL,
9586 false);
9587 if ((region_type & ORT_TARGET) != 0)
9588 omp_add_variable (ctx, OMP_CLAUSE_SIZE (c),
9589 GOVD_FIRSTPRIVATE | GOVD_SEEN);
9592 if (TREE_CODE (decl) == TARGET_EXPR)
9594 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
9595 is_gimple_lvalue, fb_lvalue)
9596 == GS_ERROR)
9597 remove = true;
9599 else if (!DECL_P (decl))
9601 tree d = decl, *pd;
9602 if (TREE_CODE (d) == ARRAY_REF)
9604 while (TREE_CODE (d) == ARRAY_REF)
9605 d = TREE_OPERAND (d, 0);
9606 if (TREE_CODE (d) == COMPONENT_REF
9607 && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE)
9608 decl = d;
9610 pd = &OMP_CLAUSE_DECL (c);
9611 if (d == decl
9612 && TREE_CODE (decl) == INDIRECT_REF
9613 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
9614 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
9615 == REFERENCE_TYPE)
9616 && (OMP_CLAUSE_MAP_KIND (c)
9617 != GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION))
9619 pd = &TREE_OPERAND (decl, 0);
9620 decl = TREE_OPERAND (decl, 0);
9622 bool indir_p = false;
9623 bool component_ref_p = false;
9624 tree indir_base = NULL_TREE;
9625 tree orig_decl = decl;
9626 tree decl_ref = NULL_TREE;
9627 if ((region_type & (ORT_ACC | ORT_TARGET | ORT_TARGET_DATA)) != 0
9628 && TREE_CODE (*pd) == COMPONENT_REF
9629 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH
9630 && code != OACC_UPDATE)
9632 while (TREE_CODE (decl) == COMPONENT_REF)
9634 decl = TREE_OPERAND (decl, 0);
9635 component_ref_p = true;
9636 if (((TREE_CODE (decl) == MEM_REF
9637 && integer_zerop (TREE_OPERAND (decl, 1)))
9638 || INDIRECT_REF_P (decl))
9639 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
9640 == POINTER_TYPE))
9642 indir_p = true;
9643 indir_base = decl;
9644 decl = TREE_OPERAND (decl, 0);
9645 STRIP_NOPS (decl);
9647 if (TREE_CODE (decl) == INDIRECT_REF
9648 && DECL_P (TREE_OPERAND (decl, 0))
9649 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
9650 == REFERENCE_TYPE))
9652 decl_ref = decl;
9653 decl = TREE_OPERAND (decl, 0);
9657 else if (TREE_CODE (decl) == COMPONENT_REF
9658 && (OMP_CLAUSE_MAP_KIND (c)
9659 != GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION))
9661 component_ref_p = true;
9662 while (TREE_CODE (decl) == COMPONENT_REF)
9663 decl = TREE_OPERAND (decl, 0);
9664 if (TREE_CODE (decl) == INDIRECT_REF
9665 && DECL_P (TREE_OPERAND (decl, 0))
9666 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
9667 == REFERENCE_TYPE))
9668 decl = TREE_OPERAND (decl, 0);
9670 if (decl != orig_decl && DECL_P (decl) && indir_p
9671 && (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
9672 || (decl_ref
9673 && TREE_CODE (TREE_TYPE (decl_ref)) == POINTER_TYPE)))
9675 gomp_map_kind k
9676 = ((code == OACC_EXIT_DATA || code == OMP_TARGET_EXIT_DATA)
9677 ? GOMP_MAP_DETACH : GOMP_MAP_ATTACH);
9678 /* We have a dereference of a struct member. Make this an
9679 attach/detach operation, and ensure the base pointer is
9680 mapped as a FIRSTPRIVATE_POINTER. */
9681 OMP_CLAUSE_SET_MAP_KIND (c, k);
9682 flags = GOVD_MAP | GOVD_SEEN | GOVD_EXPLICIT;
9683 tree next_clause = OMP_CLAUSE_CHAIN (c);
9684 if (k == GOMP_MAP_ATTACH
9685 && code != OACC_ENTER_DATA
9686 && code != OMP_TARGET_ENTER_DATA
9687 && (!next_clause
9688 || (OMP_CLAUSE_CODE (next_clause) != OMP_CLAUSE_MAP)
9689 || (OMP_CLAUSE_MAP_KIND (next_clause)
9690 != GOMP_MAP_POINTER)
9691 || OMP_CLAUSE_DECL (next_clause) != decl)
9692 && (!struct_deref_set
9693 || !struct_deref_set->contains (decl))
9694 && (!struct_map_to_clause
9695 || !struct_map_to_clause->get (indir_base)))
9697 if (!struct_deref_set)
9698 struct_deref_set = new hash_set<tree> ();
9699 /* As well as the attach, we also need a
9700 FIRSTPRIVATE_POINTER clause to properly map the
9701 pointer to the struct base. */
9702 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9703 OMP_CLAUSE_MAP);
9704 OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_ALLOC);
9705 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (c2)
9706 = 1;
9707 tree charptr_zero
9708 = build_int_cst (build_pointer_type (char_type_node),
9710 OMP_CLAUSE_DECL (c2)
9711 = build2 (MEM_REF, char_type_node,
9712 decl_ref ? decl_ref : decl, charptr_zero);
9713 OMP_CLAUSE_SIZE (c2) = size_zero_node;
9714 tree c3 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9715 OMP_CLAUSE_MAP);
9716 OMP_CLAUSE_SET_MAP_KIND (c3,
9717 GOMP_MAP_FIRSTPRIVATE_POINTER);
9718 OMP_CLAUSE_DECL (c3) = decl;
9719 OMP_CLAUSE_SIZE (c3) = size_zero_node;
9720 tree mapgrp = *prev_list_p;
9721 *prev_list_p = c2;
9722 OMP_CLAUSE_CHAIN (c3) = mapgrp;
9723 OMP_CLAUSE_CHAIN (c2) = c3;
9725 struct_deref_set->add (decl);
9727 goto do_add_decl;
9729 /* An "attach/detach" operation on an update directive should
9730 behave as a GOMP_MAP_ALWAYS_POINTER. Beware that
9731 unlike attach or detach map kinds, GOMP_MAP_ALWAYS_POINTER
9732 depends on the previous mapping. */
9733 if (code == OACC_UPDATE
9734 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
9735 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_ALWAYS_POINTER);
9736 if ((DECL_P (decl)
9737 || (component_ref_p
9738 && (INDIRECT_REF_P (decl)
9739 || TREE_CODE (decl) == MEM_REF
9740 || TREE_CODE (decl) == ARRAY_REF)))
9741 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_TO_PSET
9742 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH
9743 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_DETACH
9744 && code != OACC_UPDATE
9745 && code != OMP_TARGET_UPDATE)
9747 if (error_operand_p (decl))
9749 remove = true;
9750 break;
9753 tree stype = TREE_TYPE (decl);
9754 if (TREE_CODE (stype) == REFERENCE_TYPE)
9755 stype = TREE_TYPE (stype);
9756 if (TYPE_SIZE_UNIT (stype) == NULL
9757 || TREE_CODE (TYPE_SIZE_UNIT (stype)) != INTEGER_CST)
9759 error_at (OMP_CLAUSE_LOCATION (c),
9760 "mapping field %qE of variable length "
9761 "structure", OMP_CLAUSE_DECL (c));
9762 remove = true;
9763 break;
9766 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER
9767 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
9769 /* Error recovery. */
9770 if (prev_list_p == NULL)
9772 remove = true;
9773 break;
9776 /* The below prev_list_p based error recovery code is
9777 currently no longer valid for OpenMP. */
9778 if (code != OMP_TARGET
9779 && code != OMP_TARGET_DATA
9780 && code != OMP_TARGET_UPDATE
9781 && code != OMP_TARGET_ENTER_DATA
9782 && code != OMP_TARGET_EXIT_DATA
9783 && OMP_CLAUSE_CHAIN (*prev_list_p) != c)
9785 tree ch = OMP_CLAUSE_CHAIN (*prev_list_p);
9786 if (ch == NULL_TREE || OMP_CLAUSE_CHAIN (ch) != c)
9788 remove = true;
9789 break;
9794 poly_offset_int offset1;
9795 poly_int64 bitpos1;
9796 tree tree_offset1;
9797 tree base_ref;
9799 tree base
9800 = extract_base_bit_offset (OMP_CLAUSE_DECL (c), &base_ref,
9801 &bitpos1, &offset1,
9802 &tree_offset1);
9804 bool do_map_struct = (base == decl && !tree_offset1);
9806 splay_tree_node n
9807 = (DECL_P (decl)
9808 ? splay_tree_lookup (ctx->variables,
9809 (splay_tree_key) decl)
9810 : NULL);
9811 bool ptr = (OMP_CLAUSE_MAP_KIND (c)
9812 == GOMP_MAP_ALWAYS_POINTER);
9813 bool attach_detach = (OMP_CLAUSE_MAP_KIND (c)
9814 == GOMP_MAP_ATTACH_DETACH);
9815 bool attach = OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
9816 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH;
9817 bool has_attachments = false;
9818 /* For OpenACC, pointers in structs should trigger an
9819 attach action. */
9820 if (attach_detach
9821 && ((region_type & (ORT_ACC | ORT_TARGET | ORT_TARGET_DATA))
9822 || code == OMP_TARGET_ENTER_DATA
9823 || code == OMP_TARGET_EXIT_DATA))
9826 /* Turn a GOMP_MAP_ATTACH_DETACH clause into a
9827 GOMP_MAP_ATTACH or GOMP_MAP_DETACH clause after we
9828 have detected a case that needs a GOMP_MAP_STRUCT
9829 mapping added. */
9830 gomp_map_kind k
9831 = ((code == OACC_EXIT_DATA || code == OMP_TARGET_EXIT_DATA)
9832 ? GOMP_MAP_DETACH : GOMP_MAP_ATTACH);
9833 OMP_CLAUSE_SET_MAP_KIND (c, k);
9834 has_attachments = true;
9837 /* We currently don't handle non-constant offset accesses wrt to
9838 GOMP_MAP_STRUCT elements. */
9839 if (!do_map_struct)
9840 goto skip_map_struct;
9842 /* Nor for attach_detach for OpenMP. */
9843 if ((code == OMP_TARGET
9844 || code == OMP_TARGET_DATA
9845 || code == OMP_TARGET_UPDATE
9846 || code == OMP_TARGET_ENTER_DATA
9847 || code == OMP_TARGET_EXIT_DATA)
9848 && attach_detach)
9850 if (DECL_P (decl))
9852 if (struct_seen_clause == NULL)
9853 struct_seen_clause
9854 = new hash_map<tree_operand_hash, tree *>;
9855 if (!struct_seen_clause->get (decl))
9856 struct_seen_clause->put (decl, list_p);
9859 goto skip_map_struct;
9862 if ((DECL_P (decl)
9863 && (n == NULL || (n->value & GOVD_MAP) == 0))
9864 || (!DECL_P (decl)
9865 && (!struct_map_to_clause
9866 || struct_map_to_clause->get (decl) == NULL)))
9868 tree l = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9869 OMP_CLAUSE_MAP);
9870 gomp_map_kind k = attach ? GOMP_MAP_FORCE_PRESENT
9871 : GOMP_MAP_STRUCT;
9873 OMP_CLAUSE_SET_MAP_KIND (l, k);
9874 if (base_ref)
9875 OMP_CLAUSE_DECL (l) = unshare_expr (base_ref);
9876 else
9878 OMP_CLAUSE_DECL (l) = unshare_expr (decl);
9879 if (!DECL_P (OMP_CLAUSE_DECL (l))
9880 && (gimplify_expr (&OMP_CLAUSE_DECL (l),
9881 pre_p, NULL, is_gimple_lvalue,
9882 fb_lvalue)
9883 == GS_ERROR))
9885 remove = true;
9886 break;
9889 OMP_CLAUSE_SIZE (l)
9890 = (!attach
9891 ? size_int (1)
9892 : DECL_P (OMP_CLAUSE_DECL (l))
9893 ? DECL_SIZE_UNIT (OMP_CLAUSE_DECL (l))
9894 : TYPE_SIZE_UNIT (TREE_TYPE (OMP_CLAUSE_DECL (l))));
9895 if (struct_map_to_clause == NULL)
9896 struct_map_to_clause
9897 = new hash_map<tree_operand_hash, tree>;
9898 struct_map_to_clause->put (decl, l);
9899 if (ptr || attach_detach)
9901 tree **sc = (struct_seen_clause
9902 ? struct_seen_clause->get (decl)
9903 : NULL);
9904 tree *insert_node_pos = sc ? *sc : prev_list_p;
9906 insert_struct_comp_map (code, c, l, *insert_node_pos,
9907 NULL);
9908 *insert_node_pos = l;
9909 prev_list_p = NULL;
9911 else
9913 OMP_CLAUSE_CHAIN (l) = c;
9914 *list_p = l;
9915 list_p = &OMP_CLAUSE_CHAIN (l);
9917 if (base_ref && code == OMP_TARGET)
9919 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9920 OMP_CLAUSE_MAP);
9921 enum gomp_map_kind mkind
9922 = GOMP_MAP_FIRSTPRIVATE_REFERENCE;
9923 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
9924 OMP_CLAUSE_DECL (c2) = decl;
9925 OMP_CLAUSE_SIZE (c2) = size_zero_node;
9926 OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (l);
9927 OMP_CLAUSE_CHAIN (l) = c2;
9929 flags = GOVD_MAP | GOVD_EXPLICIT;
9930 if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c))
9931 || ptr
9932 || attach_detach)
9933 flags |= GOVD_SEEN;
9934 if (has_attachments)
9935 flags |= GOVD_MAP_HAS_ATTACHMENTS;
9937 /* If this is a *pointer-to-struct expression, make sure a
9938 firstprivate map of the base-pointer exists. */
9939 if (component_ref_p
9940 && ((TREE_CODE (decl) == MEM_REF
9941 && integer_zerop (TREE_OPERAND (decl, 1)))
9942 || INDIRECT_REF_P (decl))
9943 && DECL_P (TREE_OPERAND (decl, 0))
9944 && !splay_tree_lookup (ctx->variables,
9945 ((splay_tree_key)
9946 TREE_OPERAND (decl, 0))))
9948 decl = TREE_OPERAND (decl, 0);
9949 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9950 OMP_CLAUSE_MAP);
9951 enum gomp_map_kind mkind
9952 = GOMP_MAP_FIRSTPRIVATE_POINTER;
9953 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
9954 OMP_CLAUSE_DECL (c2) = decl;
9955 OMP_CLAUSE_SIZE (c2) = size_zero_node;
9956 OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (c);
9957 OMP_CLAUSE_CHAIN (c) = c2;
9960 if (DECL_P (decl))
9961 goto do_add_decl;
9963 else if (struct_map_to_clause)
9965 tree *osc = struct_map_to_clause->get (decl);
9966 tree *sc = NULL, *scp = NULL;
9967 if (n != NULL
9968 && (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c))
9969 || ptr
9970 || attach_detach))
9971 n->value |= GOVD_SEEN;
9972 sc = &OMP_CLAUSE_CHAIN (*osc);
9973 if (*sc != c
9974 && (OMP_CLAUSE_MAP_KIND (*sc)
9975 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
9976 sc = &OMP_CLAUSE_CHAIN (*sc);
9977 /* Here "prev_list_p" is the end of the inserted
9978 alloc/release nodes after the struct node, OSC. */
9979 for (; *sc != c; sc = &OMP_CLAUSE_CHAIN (*sc))
9980 if ((ptr || attach_detach) && sc == prev_list_p)
9981 break;
9982 else if (TREE_CODE (OMP_CLAUSE_DECL (*sc))
9983 != COMPONENT_REF
9984 && (TREE_CODE (OMP_CLAUSE_DECL (*sc))
9985 != INDIRECT_REF)
9986 && (TREE_CODE (OMP_CLAUSE_DECL (*sc))
9987 != ARRAY_REF))
9988 break;
9989 else
9991 tree sc_decl = OMP_CLAUSE_DECL (*sc);
9992 poly_offset_int offsetn;
9993 poly_int64 bitposn;
9994 tree tree_offsetn;
9995 tree base
9996 = extract_base_bit_offset (sc_decl, NULL,
9997 &bitposn, &offsetn,
9998 &tree_offsetn);
9999 if (base != decl)
10000 break;
10001 if (scp)
10002 continue;
10003 if ((region_type & ORT_ACC) != 0)
10005 /* This duplicate checking code is currently only
10006 enabled for OpenACC. */
10007 tree d1 = OMP_CLAUSE_DECL (*sc);
10008 tree d2 = OMP_CLAUSE_DECL (c);
10009 while (TREE_CODE (d1) == ARRAY_REF)
10010 d1 = TREE_OPERAND (d1, 0);
10011 while (TREE_CODE (d2) == ARRAY_REF)
10012 d2 = TREE_OPERAND (d2, 0);
10013 if (TREE_CODE (d1) == INDIRECT_REF)
10014 d1 = TREE_OPERAND (d1, 0);
10015 if (TREE_CODE (d2) == INDIRECT_REF)
10016 d2 = TREE_OPERAND (d2, 0);
10017 while (TREE_CODE (d1) == COMPONENT_REF)
10018 if (TREE_CODE (d2) == COMPONENT_REF
10019 && TREE_OPERAND (d1, 1)
10020 == TREE_OPERAND (d2, 1))
10022 d1 = TREE_OPERAND (d1, 0);
10023 d2 = TREE_OPERAND (d2, 0);
10025 else
10026 break;
10027 if (d1 == d2)
10029 error_at (OMP_CLAUSE_LOCATION (c),
10030 "%qE appears more than once in map "
10031 "clauses", OMP_CLAUSE_DECL (c));
10032 remove = true;
10033 break;
10036 if (maybe_lt (offset1, offsetn)
10037 || (known_eq (offset1, offsetn)
10038 && maybe_lt (bitpos1, bitposn)))
10040 if (ptr || attach_detach)
10041 scp = sc;
10042 else
10043 break;
10046 if (remove)
10047 break;
10048 if (!attach)
10049 OMP_CLAUSE_SIZE (*osc)
10050 = size_binop (PLUS_EXPR, OMP_CLAUSE_SIZE (*osc),
10051 size_one_node);
10052 if (ptr || attach_detach)
10054 tree cl = insert_struct_comp_map (code, c, NULL,
10055 *prev_list_p, scp);
10056 if (sc == prev_list_p)
10058 *sc = cl;
10059 prev_list_p = NULL;
10061 else
10063 *prev_list_p = OMP_CLAUSE_CHAIN (c);
10064 list_p = prev_list_p;
10065 prev_list_p = NULL;
10066 OMP_CLAUSE_CHAIN (c) = *sc;
10067 *sc = cl;
10068 continue;
10071 else if (*sc != c)
10073 if (gimplify_expr (pd, pre_p, NULL, is_gimple_lvalue,
10074 fb_lvalue)
10075 == GS_ERROR)
10077 remove = true;
10078 break;
10080 *list_p = OMP_CLAUSE_CHAIN (c);
10081 OMP_CLAUSE_CHAIN (c) = *sc;
10082 *sc = c;
10083 continue;
10086 skip_map_struct:
10089 else if ((code == OACC_ENTER_DATA
10090 || code == OACC_EXIT_DATA
10091 || code == OACC_DATA
10092 || code == OACC_PARALLEL
10093 || code == OACC_KERNELS
10094 || code == OACC_SERIAL
10095 || code == OMP_TARGET_ENTER_DATA
10096 || code == OMP_TARGET_EXIT_DATA)
10097 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
10099 gomp_map_kind k = ((code == OACC_EXIT_DATA
10100 || code == OMP_TARGET_EXIT_DATA)
10101 ? GOMP_MAP_DETACH : GOMP_MAP_ATTACH);
10102 OMP_CLAUSE_SET_MAP_KIND (c, k);
10105 if (code == OMP_TARGET && OMP_CLAUSE_MAP_IN_REDUCTION (c))
10107 /* Don't gimplify *pd fully at this point, as the base
10108 will need to be adjusted during omp lowering. */
10109 auto_vec<tree, 10> expr_stack;
10110 tree *p = pd;
10111 while (handled_component_p (*p)
10112 || TREE_CODE (*p) == INDIRECT_REF
10113 || TREE_CODE (*p) == ADDR_EXPR
10114 || TREE_CODE (*p) == MEM_REF
10115 || TREE_CODE (*p) == NON_LVALUE_EXPR)
10117 expr_stack.safe_push (*p);
10118 p = &TREE_OPERAND (*p, 0);
10120 for (int i = expr_stack.length () - 1; i >= 0; i--)
10122 tree t = expr_stack[i];
10123 if (TREE_CODE (t) == ARRAY_REF
10124 || TREE_CODE (t) == ARRAY_RANGE_REF)
10126 if (TREE_OPERAND (t, 2) == NULL_TREE)
10128 tree low = unshare_expr (array_ref_low_bound (t));
10129 if (!is_gimple_min_invariant (low))
10131 TREE_OPERAND (t, 2) = low;
10132 if (gimplify_expr (&TREE_OPERAND (t, 2),
10133 pre_p, NULL,
10134 is_gimple_reg,
10135 fb_rvalue) == GS_ERROR)
10136 remove = true;
10139 else if (gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
10140 NULL, is_gimple_reg,
10141 fb_rvalue) == GS_ERROR)
10142 remove = true;
10143 if (TREE_OPERAND (t, 3) == NULL_TREE)
10145 tree elmt_size = array_ref_element_size (t);
10146 if (!is_gimple_min_invariant (elmt_size))
10148 elmt_size = unshare_expr (elmt_size);
10149 tree elmt_type
10150 = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t,
10151 0)));
10152 tree factor
10153 = size_int (TYPE_ALIGN_UNIT (elmt_type));
10154 elmt_size
10155 = size_binop (EXACT_DIV_EXPR, elmt_size,
10156 factor);
10157 TREE_OPERAND (t, 3) = elmt_size;
10158 if (gimplify_expr (&TREE_OPERAND (t, 3),
10159 pre_p, NULL,
10160 is_gimple_reg,
10161 fb_rvalue) == GS_ERROR)
10162 remove = true;
10165 else if (gimplify_expr (&TREE_OPERAND (t, 3), pre_p,
10166 NULL, is_gimple_reg,
10167 fb_rvalue) == GS_ERROR)
10168 remove = true;
10170 else if (TREE_CODE (t) == COMPONENT_REF)
10172 if (TREE_OPERAND (t, 2) == NULL_TREE)
10174 tree offset = component_ref_field_offset (t);
10175 if (!is_gimple_min_invariant (offset))
10177 offset = unshare_expr (offset);
10178 tree field = TREE_OPERAND (t, 1);
10179 tree factor
10180 = size_int (DECL_OFFSET_ALIGN (field)
10181 / BITS_PER_UNIT);
10182 offset = size_binop (EXACT_DIV_EXPR, offset,
10183 factor);
10184 TREE_OPERAND (t, 2) = offset;
10185 if (gimplify_expr (&TREE_OPERAND (t, 2),
10186 pre_p, NULL,
10187 is_gimple_reg,
10188 fb_rvalue) == GS_ERROR)
10189 remove = true;
10192 else if (gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
10193 NULL, is_gimple_reg,
10194 fb_rvalue) == GS_ERROR)
10195 remove = true;
10198 for (; expr_stack.length () > 0; )
10200 tree t = expr_stack.pop ();
10202 if (TREE_CODE (t) == ARRAY_REF
10203 || TREE_CODE (t) == ARRAY_RANGE_REF)
10205 if (!is_gimple_min_invariant (TREE_OPERAND (t, 1))
10206 && gimplify_expr (&TREE_OPERAND (t, 1), pre_p,
10207 NULL, is_gimple_val,
10208 fb_rvalue) == GS_ERROR)
10209 remove = true;
10213 else if (gimplify_expr (pd, pre_p, NULL, is_gimple_lvalue,
10214 fb_lvalue) == GS_ERROR)
10216 remove = true;
10217 break;
10220 /* If this was of the form map(*pointer_to_struct), then the
10221 'pointer_to_struct' DECL should be considered deref'ed. */
10222 if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALLOC
10223 || GOMP_MAP_COPY_TO_P (OMP_CLAUSE_MAP_KIND (c))
10224 || GOMP_MAP_COPY_FROM_P (OMP_CLAUSE_MAP_KIND (c)))
10225 && INDIRECT_REF_P (orig_decl)
10226 && DECL_P (TREE_OPERAND (orig_decl, 0))
10227 && TREE_CODE (TREE_TYPE (orig_decl)) == RECORD_TYPE)
10229 tree ptr = TREE_OPERAND (orig_decl, 0);
10230 if (!struct_deref_set || !struct_deref_set->contains (ptr))
10232 if (!struct_deref_set)
10233 struct_deref_set = new hash_set<tree> ();
10234 struct_deref_set->add (ptr);
10238 if (!remove
10239 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_POINTER
10240 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH_DETACH
10241 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_TO_PSET
10242 && OMP_CLAUSE_CHAIN (c)
10243 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (c)) == OMP_CLAUSE_MAP
10244 && ((OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
10245 == GOMP_MAP_ALWAYS_POINTER)
10246 || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
10247 == GOMP_MAP_ATTACH_DETACH)
10248 || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
10249 == GOMP_MAP_TO_PSET)))
10250 prev_list_p = list_p;
10252 break;
10254 else
10256 /* DECL_P (decl) == true */
10257 tree *sc;
10258 if (struct_map_to_clause
10259 && (sc = struct_map_to_clause->get (decl)) != NULL
10260 && OMP_CLAUSE_MAP_KIND (*sc) == GOMP_MAP_STRUCT
10261 && decl == OMP_CLAUSE_DECL (*sc))
10263 /* We have found a map of the whole structure after a
10264 leading GOMP_MAP_STRUCT has been created, so refill the
10265 leading clause into a map of the whole structure
10266 variable, and remove the current one.
10267 TODO: we should be able to remove some maps of the
10268 following structure element maps if they are of
10269 compatible TO/FROM/ALLOC type. */
10270 OMP_CLAUSE_SET_MAP_KIND (*sc, OMP_CLAUSE_MAP_KIND (c));
10271 OMP_CLAUSE_SIZE (*sc) = unshare_expr (OMP_CLAUSE_SIZE (c));
10272 remove = true;
10273 break;
10276 flags = GOVD_MAP | GOVD_EXPLICIT;
10277 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TO
10278 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TOFROM)
10279 flags |= GOVD_MAP_ALWAYS_TO;
10281 if ((code == OMP_TARGET
10282 || code == OMP_TARGET_DATA
10283 || code == OMP_TARGET_ENTER_DATA
10284 || code == OMP_TARGET_EXIT_DATA)
10285 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
10287 for (struct gimplify_omp_ctx *octx = outer_ctx; octx;
10288 octx = octx->outer_context)
10290 splay_tree_node n
10291 = splay_tree_lookup (octx->variables,
10292 (splay_tree_key) OMP_CLAUSE_DECL (c));
10293 /* If this is contained in an outer OpenMP region as a
10294 firstprivate value, remove the attach/detach. */
10295 if (n && (n->value & GOVD_FIRSTPRIVATE))
10297 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FIRSTPRIVATE_POINTER);
10298 goto do_add;
10302 enum gomp_map_kind map_kind = (code == OMP_TARGET_EXIT_DATA
10303 ? GOMP_MAP_DETACH
10304 : GOMP_MAP_ATTACH);
10305 OMP_CLAUSE_SET_MAP_KIND (c, map_kind);
10308 goto do_add;
10310 case OMP_CLAUSE_AFFINITY:
10311 gimplify_omp_affinity (list_p, pre_p);
10312 remove = true;
10313 break;
10314 case OMP_CLAUSE_DEPEND:
10315 if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
10317 tree deps = OMP_CLAUSE_DECL (c);
10318 while (deps && TREE_CODE (deps) == TREE_LIST)
10320 if (TREE_CODE (TREE_PURPOSE (deps)) == TRUNC_DIV_EXPR
10321 && DECL_P (TREE_OPERAND (TREE_PURPOSE (deps), 1)))
10322 gimplify_expr (&TREE_OPERAND (TREE_PURPOSE (deps), 1),
10323 pre_p, NULL, is_gimple_val, fb_rvalue);
10324 deps = TREE_CHAIN (deps);
10326 break;
10328 else if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
10329 break;
10330 if (handled_depend_iterators == -1)
10331 handled_depend_iterators = gimplify_omp_depend (list_p, pre_p);
10332 if (handled_depend_iterators)
10334 if (handled_depend_iterators == 2)
10335 remove = true;
10336 break;
10338 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
10340 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
10341 NULL, is_gimple_val, fb_rvalue);
10342 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
10344 if (error_operand_p (OMP_CLAUSE_DECL (c)))
10346 remove = true;
10347 break;
10349 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
10350 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
10351 is_gimple_val, fb_rvalue) == GS_ERROR)
10353 remove = true;
10354 break;
10356 if (code == OMP_TASK)
10357 ctx->has_depend = true;
10358 break;
10360 case OMP_CLAUSE_TO:
10361 case OMP_CLAUSE_FROM:
10362 case OMP_CLAUSE__CACHE_:
10363 decl = OMP_CLAUSE_DECL (c);
10364 if (error_operand_p (decl))
10366 remove = true;
10367 break;
10369 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
10370 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
10371 : TYPE_SIZE_UNIT (TREE_TYPE (decl));
10372 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
10373 NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
10375 remove = true;
10376 break;
10378 if (!DECL_P (decl))
10380 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p,
10381 NULL, is_gimple_lvalue, fb_lvalue)
10382 == GS_ERROR)
10384 remove = true;
10385 break;
10387 break;
10389 goto do_notice;
10391 case OMP_CLAUSE_USE_DEVICE_PTR:
10392 case OMP_CLAUSE_USE_DEVICE_ADDR:
10393 flags = GOVD_EXPLICIT;
10394 goto do_add;
10396 case OMP_CLAUSE_HAS_DEVICE_ADDR:
10397 decl = OMP_CLAUSE_DECL (c);
10398 while (TREE_CODE (decl) == INDIRECT_REF
10399 || TREE_CODE (decl) == ARRAY_REF)
10400 decl = TREE_OPERAND (decl, 0);
10401 flags = GOVD_EXPLICIT;
10402 goto do_add_decl;
10404 case OMP_CLAUSE_IS_DEVICE_PTR:
10405 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
10406 goto do_add;
10408 do_add:
10409 decl = OMP_CLAUSE_DECL (c);
10410 do_add_decl:
10411 if (error_operand_p (decl))
10413 remove = true;
10414 break;
10416 if (DECL_NAME (decl) == NULL_TREE && (flags & GOVD_SHARED) == 0)
10418 tree t = omp_member_access_dummy_var (decl);
10419 if (t)
10421 tree v = DECL_VALUE_EXPR (decl);
10422 DECL_NAME (decl) = DECL_NAME (TREE_OPERAND (v, 1));
10423 if (outer_ctx)
10424 omp_notice_variable (outer_ctx, t, true);
10427 if (code == OACC_DATA
10428 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
10429 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
10430 flags |= GOVD_MAP_0LEN_ARRAY;
10431 omp_add_variable (ctx, decl, flags);
10432 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10433 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
10434 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
10435 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
10437 struct gimplify_omp_ctx *pctx
10438 = code == OMP_TARGET ? outer_ctx : ctx;
10439 if (pctx)
10440 omp_add_variable (pctx, OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
10441 GOVD_LOCAL | GOVD_SEEN);
10442 if (pctx
10443 && OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
10444 && walk_tree (&OMP_CLAUSE_REDUCTION_INIT (c),
10445 find_decl_expr,
10446 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
10447 NULL) == NULL_TREE)
10448 omp_add_variable (pctx,
10449 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
10450 GOVD_LOCAL | GOVD_SEEN);
10451 gimplify_omp_ctxp = pctx;
10452 push_gimplify_context ();
10454 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
10455 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
10457 gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c),
10458 &OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c));
10459 pop_gimplify_context
10460 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c)));
10461 push_gimplify_context ();
10462 gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c),
10463 &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
10464 pop_gimplify_context
10465 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c)));
10466 OMP_CLAUSE_REDUCTION_INIT (c) = NULL_TREE;
10467 OMP_CLAUSE_REDUCTION_MERGE (c) = NULL_TREE;
10469 gimplify_omp_ctxp = outer_ctx;
10471 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
10472 && OMP_CLAUSE_LASTPRIVATE_STMT (c))
10474 gimplify_omp_ctxp = ctx;
10475 push_gimplify_context ();
10476 if (TREE_CODE (OMP_CLAUSE_LASTPRIVATE_STMT (c)) != BIND_EXPR)
10478 tree bind = build3 (BIND_EXPR, void_type_node, NULL,
10479 NULL, NULL);
10480 TREE_SIDE_EFFECTS (bind) = 1;
10481 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LASTPRIVATE_STMT (c);
10482 OMP_CLAUSE_LASTPRIVATE_STMT (c) = bind;
10484 gimplify_and_add (OMP_CLAUSE_LASTPRIVATE_STMT (c),
10485 &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
10486 pop_gimplify_context
10487 (gimple_seq_first_stmt (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c)));
10488 OMP_CLAUSE_LASTPRIVATE_STMT (c) = NULL_TREE;
10490 gimplify_omp_ctxp = outer_ctx;
10492 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
10493 && OMP_CLAUSE_LINEAR_STMT (c))
10495 gimplify_omp_ctxp = ctx;
10496 push_gimplify_context ();
10497 if (TREE_CODE (OMP_CLAUSE_LINEAR_STMT (c)) != BIND_EXPR)
10499 tree bind = build3 (BIND_EXPR, void_type_node, NULL,
10500 NULL, NULL);
10501 TREE_SIDE_EFFECTS (bind) = 1;
10502 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LINEAR_STMT (c);
10503 OMP_CLAUSE_LINEAR_STMT (c) = bind;
10505 gimplify_and_add (OMP_CLAUSE_LINEAR_STMT (c),
10506 &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c));
10507 pop_gimplify_context
10508 (gimple_seq_first_stmt (OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c)));
10509 OMP_CLAUSE_LINEAR_STMT (c) = NULL_TREE;
10511 gimplify_omp_ctxp = outer_ctx;
10513 if (notice_outer)
10514 goto do_notice;
10515 break;
10517 case OMP_CLAUSE_COPYIN:
10518 case OMP_CLAUSE_COPYPRIVATE:
10519 decl = OMP_CLAUSE_DECL (c);
10520 if (error_operand_p (decl))
10522 remove = true;
10523 break;
10525 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_COPYPRIVATE
10526 && !remove
10527 && !omp_check_private (ctx, decl, true))
10529 remove = true;
10530 if (is_global_var (decl))
10532 if (DECL_THREAD_LOCAL_P (decl))
10533 remove = false;
10534 else if (DECL_HAS_VALUE_EXPR_P (decl))
10536 tree value = get_base_address (DECL_VALUE_EXPR (decl));
10538 if (value
10539 && DECL_P (value)
10540 && DECL_THREAD_LOCAL_P (value))
10541 remove = false;
10544 if (remove)
10545 error_at (OMP_CLAUSE_LOCATION (c),
10546 "copyprivate variable %qE is not threadprivate"
10547 " or private in outer context", DECL_NAME (decl));
10549 do_notice:
10550 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10551 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
10552 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
10553 && outer_ctx
10554 && ((region_type & ORT_TASKLOOP) == ORT_TASKLOOP
10555 || (region_type == ORT_WORKSHARE
10556 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10557 && (OMP_CLAUSE_REDUCTION_INSCAN (c)
10558 || code == OMP_LOOP)))
10559 && (outer_ctx->region_type == ORT_COMBINED_PARALLEL
10560 || (code == OMP_LOOP
10561 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10562 && ((outer_ctx->region_type & ORT_COMBINED_TEAMS)
10563 == ORT_COMBINED_TEAMS))))
10565 splay_tree_node on
10566 = splay_tree_lookup (outer_ctx->variables,
10567 (splay_tree_key)decl);
10568 if (on == NULL || (on->value & GOVD_DATA_SHARE_CLASS) == 0)
10570 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10571 && TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
10572 && (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
10573 || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
10574 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
10575 == POINTER_TYPE))))
10576 omp_firstprivatize_variable (outer_ctx, decl);
10577 else
10579 omp_add_variable (outer_ctx, decl,
10580 GOVD_SEEN | GOVD_SHARED);
10581 if (outer_ctx->outer_context)
10582 omp_notice_variable (outer_ctx->outer_context, decl,
10583 true);
10587 if (outer_ctx)
10588 omp_notice_variable (outer_ctx, decl, true);
10589 if (check_non_private
10590 && (region_type == ORT_WORKSHARE || code == OMP_SCOPE)
10591 && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
10592 || decl == OMP_CLAUSE_DECL (c)
10593 || (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
10594 && (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
10595 == ADDR_EXPR
10596 || (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
10597 == POINTER_PLUS_EXPR
10598 && (TREE_CODE (TREE_OPERAND (TREE_OPERAND
10599 (OMP_CLAUSE_DECL (c), 0), 0))
10600 == ADDR_EXPR)))))
10601 && omp_check_private (ctx, decl, false))
10603 error ("%s variable %qE is private in outer context",
10604 check_non_private, DECL_NAME (decl));
10605 remove = true;
10607 break;
10609 case OMP_CLAUSE_DETACH:
10610 flags = GOVD_FIRSTPRIVATE | GOVD_SEEN;
10611 goto do_add;
10613 case OMP_CLAUSE_IF:
10614 if (OMP_CLAUSE_IF_MODIFIER (c) != ERROR_MARK
10615 && OMP_CLAUSE_IF_MODIFIER (c) != code)
10617 const char *p[2];
10618 for (int i = 0; i < 2; i++)
10619 switch (i ? OMP_CLAUSE_IF_MODIFIER (c) : code)
10621 case VOID_CST: p[i] = "cancel"; break;
10622 case OMP_PARALLEL: p[i] = "parallel"; break;
10623 case OMP_SIMD: p[i] = "simd"; break;
10624 case OMP_TASK: p[i] = "task"; break;
10625 case OMP_TASKLOOP: p[i] = "taskloop"; break;
10626 case OMP_TARGET_DATA: p[i] = "target data"; break;
10627 case OMP_TARGET: p[i] = "target"; break;
10628 case OMP_TARGET_UPDATE: p[i] = "target update"; break;
10629 case OMP_TARGET_ENTER_DATA:
10630 p[i] = "target enter data"; break;
10631 case OMP_TARGET_EXIT_DATA: p[i] = "target exit data"; break;
10632 default: gcc_unreachable ();
10634 error_at (OMP_CLAUSE_LOCATION (c),
10635 "expected %qs %<if%> clause modifier rather than %qs",
10636 p[0], p[1]);
10637 remove = true;
10639 /* Fall through. */
10641 case OMP_CLAUSE_FINAL:
10642 OMP_CLAUSE_OPERAND (c, 0)
10643 = gimple_boolify (OMP_CLAUSE_OPERAND (c, 0));
10644 /* Fall through. */
10646 case OMP_CLAUSE_NUM_TEAMS:
10647 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
10648 && OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
10649 && !is_gimple_min_invariant (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)))
10651 if (error_operand_p (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)))
10653 remove = true;
10654 break;
10656 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
10657 = get_initialized_tmp_var (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c),
10658 pre_p, NULL, true);
10660 /* Fall through. */
10662 case OMP_CLAUSE_SCHEDULE:
10663 case OMP_CLAUSE_NUM_THREADS:
10664 case OMP_CLAUSE_THREAD_LIMIT:
10665 case OMP_CLAUSE_DIST_SCHEDULE:
10666 case OMP_CLAUSE_DEVICE:
10667 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE
10668 && OMP_CLAUSE_DEVICE_ANCESTOR (c))
10670 if (code != OMP_TARGET)
10672 error_at (OMP_CLAUSE_LOCATION (c),
10673 "%<device%> clause with %<ancestor%> is only "
10674 "allowed on %<target%> construct");
10675 remove = true;
10676 break;
10679 tree clauses = *orig_list_p;
10680 for (; clauses ; clauses = OMP_CLAUSE_CHAIN (clauses))
10681 if (OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_DEVICE
10682 && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_FIRSTPRIVATE
10683 && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_PRIVATE
10684 && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_DEFAULTMAP
10685 && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_MAP
10688 error_at (OMP_CLAUSE_LOCATION (c),
10689 "with %<ancestor%>, only the %<device%>, "
10690 "%<firstprivate%>, %<private%>, %<defaultmap%>, "
10691 "and %<map%> clauses may appear on the "
10692 "construct");
10693 remove = true;
10694 break;
10697 /* Fall through. */
10699 case OMP_CLAUSE_PRIORITY:
10700 case OMP_CLAUSE_GRAINSIZE:
10701 case OMP_CLAUSE_NUM_TASKS:
10702 case OMP_CLAUSE_FILTER:
10703 case OMP_CLAUSE_HINT:
10704 case OMP_CLAUSE_ASYNC:
10705 case OMP_CLAUSE_WAIT:
10706 case OMP_CLAUSE_NUM_GANGS:
10707 case OMP_CLAUSE_NUM_WORKERS:
10708 case OMP_CLAUSE_VECTOR_LENGTH:
10709 case OMP_CLAUSE_WORKER:
10710 case OMP_CLAUSE_VECTOR:
10711 if (OMP_CLAUSE_OPERAND (c, 0)
10712 && !is_gimple_min_invariant (OMP_CLAUSE_OPERAND (c, 0)))
10714 if (error_operand_p (OMP_CLAUSE_OPERAND (c, 0)))
10716 remove = true;
10717 break;
10719 /* All these clauses care about value, not a particular decl,
10720 so try to force it into a SSA_NAME or fresh temporary. */
10721 OMP_CLAUSE_OPERAND (c, 0)
10722 = get_initialized_tmp_var (OMP_CLAUSE_OPERAND (c, 0),
10723 pre_p, NULL, true);
10725 break;
10727 case OMP_CLAUSE_GANG:
10728 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
10729 is_gimple_val, fb_rvalue) == GS_ERROR)
10730 remove = true;
10731 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 1), pre_p, NULL,
10732 is_gimple_val, fb_rvalue) == GS_ERROR)
10733 remove = true;
10734 break;
10736 case OMP_CLAUSE_NOWAIT:
10737 nowait = 1;
10738 break;
10740 case OMP_CLAUSE_ORDERED:
10741 case OMP_CLAUSE_UNTIED:
10742 case OMP_CLAUSE_COLLAPSE:
10743 case OMP_CLAUSE_TILE:
10744 case OMP_CLAUSE_AUTO:
10745 case OMP_CLAUSE_SEQ:
10746 case OMP_CLAUSE_INDEPENDENT:
10747 case OMP_CLAUSE_MERGEABLE:
10748 case OMP_CLAUSE_PROC_BIND:
10749 case OMP_CLAUSE_SAFELEN:
10750 case OMP_CLAUSE_SIMDLEN:
10751 case OMP_CLAUSE_NOGROUP:
10752 case OMP_CLAUSE_THREADS:
10753 case OMP_CLAUSE_SIMD:
10754 case OMP_CLAUSE_BIND:
10755 case OMP_CLAUSE_IF_PRESENT:
10756 case OMP_CLAUSE_FINALIZE:
10757 break;
10759 case OMP_CLAUSE_ORDER:
10760 ctx->order_concurrent = true;
10761 break;
10763 case OMP_CLAUSE_DEFAULTMAP:
10764 enum gimplify_defaultmap_kind gdmkmin, gdmkmax;
10765 switch (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c))
10767 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
10768 gdmkmin = GDMK_SCALAR;
10769 gdmkmax = GDMK_POINTER;
10770 break;
10771 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
10772 gdmkmin = GDMK_SCALAR;
10773 gdmkmax = GDMK_SCALAR_TARGET;
10774 break;
10775 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
10776 gdmkmin = gdmkmax = GDMK_AGGREGATE;
10777 break;
10778 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALLOCATABLE:
10779 gdmkmin = gdmkmax = GDMK_ALLOCATABLE;
10780 break;
10781 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
10782 gdmkmin = gdmkmax = GDMK_POINTER;
10783 break;
10784 default:
10785 gcc_unreachable ();
10787 for (int gdmk = gdmkmin; gdmk <= gdmkmax; gdmk++)
10788 switch (OMP_CLAUSE_DEFAULTMAP_BEHAVIOR (c))
10790 case OMP_CLAUSE_DEFAULTMAP_ALLOC:
10791 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_ALLOC_ONLY;
10792 break;
10793 case OMP_CLAUSE_DEFAULTMAP_TO:
10794 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_TO_ONLY;
10795 break;
10796 case OMP_CLAUSE_DEFAULTMAP_FROM:
10797 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_FROM_ONLY;
10798 break;
10799 case OMP_CLAUSE_DEFAULTMAP_TOFROM:
10800 ctx->defaultmap[gdmk] = GOVD_MAP;
10801 break;
10802 case OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE:
10803 ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE;
10804 break;
10805 case OMP_CLAUSE_DEFAULTMAP_NONE:
10806 ctx->defaultmap[gdmk] = 0;
10807 break;
10808 case OMP_CLAUSE_DEFAULTMAP_DEFAULT:
10809 switch (gdmk)
10811 case GDMK_SCALAR:
10812 ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE;
10813 break;
10814 case GDMK_SCALAR_TARGET:
10815 ctx->defaultmap[gdmk] = (lang_GNU_Fortran ()
10816 ? GOVD_MAP : GOVD_FIRSTPRIVATE);
10817 break;
10818 case GDMK_AGGREGATE:
10819 case GDMK_ALLOCATABLE:
10820 ctx->defaultmap[gdmk] = GOVD_MAP;
10821 break;
10822 case GDMK_POINTER:
10823 ctx->defaultmap[gdmk] = GOVD_MAP;
10824 if (!lang_GNU_Fortran ())
10825 ctx->defaultmap[gdmk] |= GOVD_MAP_0LEN_ARRAY;
10826 break;
10827 default:
10828 gcc_unreachable ();
10830 break;
10831 default:
10832 gcc_unreachable ();
10834 break;
10836 case OMP_CLAUSE_ALIGNED:
10837 decl = OMP_CLAUSE_DECL (c);
10838 if (error_operand_p (decl))
10840 remove = true;
10841 break;
10843 if (gimplify_expr (&OMP_CLAUSE_ALIGNED_ALIGNMENT (c), pre_p, NULL,
10844 is_gimple_val, fb_rvalue) == GS_ERROR)
10846 remove = true;
10847 break;
10849 if (!is_global_var (decl)
10850 && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
10851 omp_add_variable (ctx, decl, GOVD_ALIGNED);
10852 break;
10854 case OMP_CLAUSE_NONTEMPORAL:
10855 decl = OMP_CLAUSE_DECL (c);
10856 if (error_operand_p (decl))
10858 remove = true;
10859 break;
10861 omp_add_variable (ctx, decl, GOVD_NONTEMPORAL);
10862 break;
10864 case OMP_CLAUSE_ALLOCATE:
10865 decl = OMP_CLAUSE_DECL (c);
10866 if (error_operand_p (decl))
10868 remove = true;
10869 break;
10871 if (gimplify_expr (&OMP_CLAUSE_ALLOCATE_ALLOCATOR (c), pre_p, NULL,
10872 is_gimple_val, fb_rvalue) == GS_ERROR)
10874 remove = true;
10875 break;
10877 else if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) == NULL_TREE
10878 || (TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c))
10879 == INTEGER_CST))
10881 else if (code == OMP_TASKLOOP
10882 || !DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)))
10883 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
10884 = get_initialized_tmp_var (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
10885 pre_p, NULL, false);
10886 break;
10888 case OMP_CLAUSE_DEFAULT:
10889 ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
10890 break;
10892 case OMP_CLAUSE_INCLUSIVE:
10893 case OMP_CLAUSE_EXCLUSIVE:
10894 decl = OMP_CLAUSE_DECL (c);
10896 splay_tree_node n = splay_tree_lookup (outer_ctx->variables,
10897 (splay_tree_key) decl);
10898 if (n == NULL || (n->value & GOVD_REDUCTION) == 0)
10900 error_at (OMP_CLAUSE_LOCATION (c),
10901 "%qD specified in %qs clause but not in %<inscan%> "
10902 "%<reduction%> clause on the containing construct",
10903 decl, omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
10904 remove = true;
10906 else
10908 n->value |= GOVD_REDUCTION_INSCAN;
10909 if (outer_ctx->region_type == ORT_SIMD
10910 && outer_ctx->outer_context
10911 && outer_ctx->outer_context->region_type == ORT_WORKSHARE)
10913 n = splay_tree_lookup (outer_ctx->outer_context->variables,
10914 (splay_tree_key) decl);
10915 if (n && (n->value & GOVD_REDUCTION) != 0)
10916 n->value |= GOVD_REDUCTION_INSCAN;
10920 break;
10922 case OMP_CLAUSE_NOHOST:
10923 default:
10924 gcc_unreachable ();
10927 if (code == OACC_DATA
10928 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
10929 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
10930 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
10931 remove = true;
10932 if (remove)
10933 *list_p = OMP_CLAUSE_CHAIN (c);
10934 else
10935 list_p = &OMP_CLAUSE_CHAIN (c);
10938 ctx->clauses = *orig_list_p;
10939 gimplify_omp_ctxp = ctx;
10940 if (struct_seen_clause)
10941 delete struct_seen_clause;
10942 if (struct_map_to_clause)
10943 delete struct_map_to_clause;
10944 if (struct_deref_set)
10945 delete struct_deref_set;
10948 /* Return true if DECL is a candidate for shared to firstprivate
10949 optimization. We only consider non-addressable scalars, not
10950 too big, and not references. */
10952 static bool
10953 omp_shared_to_firstprivate_optimizable_decl_p (tree decl)
10955 if (TREE_ADDRESSABLE (decl))
10956 return false;
10957 tree type = TREE_TYPE (decl);
10958 if (!is_gimple_reg_type (type)
10959 || TREE_CODE (type) == REFERENCE_TYPE
10960 || TREE_ADDRESSABLE (type))
10961 return false;
10962 /* Don't optimize too large decls, as each thread/task will have
10963 its own. */
10964 HOST_WIDE_INT len = int_size_in_bytes (type);
10965 if (len == -1 || len > 4 * POINTER_SIZE / BITS_PER_UNIT)
10966 return false;
10967 if (omp_privatize_by_reference (decl))
10968 return false;
10969 return true;
10972 /* Helper function of omp_find_stores_op and gimplify_adjust_omp_clauses*.
10973 For omp_shared_to_firstprivate_optimizable_decl_p decl mark it as
10974 GOVD_WRITTEN in outer contexts. */
10976 static void
10977 omp_mark_stores (struct gimplify_omp_ctx *ctx, tree decl)
10979 for (; ctx; ctx = ctx->outer_context)
10981 splay_tree_node n = splay_tree_lookup (ctx->variables,
10982 (splay_tree_key) decl);
10983 if (n == NULL)
10984 continue;
10985 else if (n->value & GOVD_SHARED)
10987 n->value |= GOVD_WRITTEN;
10988 return;
10990 else if (n->value & GOVD_DATA_SHARE_CLASS)
10991 return;
10995 /* Helper callback for walk_gimple_seq to discover possible stores
10996 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
10997 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
10998 for those. */
11000 static tree
11001 omp_find_stores_op (tree *tp, int *walk_subtrees, void *data)
11003 struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
11005 *walk_subtrees = 0;
11006 if (!wi->is_lhs)
11007 return NULL_TREE;
11009 tree op = *tp;
11012 if (handled_component_p (op))
11013 op = TREE_OPERAND (op, 0);
11014 else if ((TREE_CODE (op) == MEM_REF || TREE_CODE (op) == TARGET_MEM_REF)
11015 && TREE_CODE (TREE_OPERAND (op, 0)) == ADDR_EXPR)
11016 op = TREE_OPERAND (TREE_OPERAND (op, 0), 0);
11017 else
11018 break;
11020 while (1);
11021 if (!DECL_P (op) || !omp_shared_to_firstprivate_optimizable_decl_p (op))
11022 return NULL_TREE;
11024 omp_mark_stores (gimplify_omp_ctxp, op);
11025 return NULL_TREE;
11028 /* Helper callback for walk_gimple_seq to discover possible stores
11029 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
11030 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
11031 for those. */
11033 static tree
11034 omp_find_stores_stmt (gimple_stmt_iterator *gsi_p,
11035 bool *handled_ops_p,
11036 struct walk_stmt_info *wi)
11038 gimple *stmt = gsi_stmt (*gsi_p);
11039 switch (gimple_code (stmt))
11041 /* Don't recurse on OpenMP constructs for which
11042 gimplify_adjust_omp_clauses already handled the bodies,
11043 except handle gimple_omp_for_pre_body. */
11044 case GIMPLE_OMP_FOR:
11045 *handled_ops_p = true;
11046 if (gimple_omp_for_pre_body (stmt))
11047 walk_gimple_seq (gimple_omp_for_pre_body (stmt),
11048 omp_find_stores_stmt, omp_find_stores_op, wi);
11049 break;
11050 case GIMPLE_OMP_PARALLEL:
11051 case GIMPLE_OMP_TASK:
11052 case GIMPLE_OMP_SECTIONS:
11053 case GIMPLE_OMP_SINGLE:
11054 case GIMPLE_OMP_SCOPE:
11055 case GIMPLE_OMP_TARGET:
11056 case GIMPLE_OMP_TEAMS:
11057 case GIMPLE_OMP_CRITICAL:
11058 *handled_ops_p = true;
11059 break;
11060 default:
11061 break;
11063 return NULL_TREE;
11066 struct gimplify_adjust_omp_clauses_data
11068 tree *list_p;
11069 gimple_seq *pre_p;
11072 /* For all variables that were not actually used within the context,
11073 remove PRIVATE, SHARED, and FIRSTPRIVATE clauses. */
11075 static int
11076 gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
11078 tree *list_p = ((struct gimplify_adjust_omp_clauses_data *) data)->list_p;
11079 gimple_seq *pre_p
11080 = ((struct gimplify_adjust_omp_clauses_data *) data)->pre_p;
11081 tree decl = (tree) n->key;
11082 unsigned flags = n->value;
11083 enum omp_clause_code code;
11084 tree clause;
11085 bool private_debug;
11087 if (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
11088 && (flags & GOVD_LASTPRIVATE_CONDITIONAL) != 0)
11089 flags = GOVD_SHARED | GOVD_SEEN | GOVD_WRITTEN;
11090 if (flags & (GOVD_EXPLICIT | GOVD_LOCAL))
11091 return 0;
11092 if ((flags & GOVD_SEEN) == 0)
11093 return 0;
11094 if ((flags & GOVD_MAP_HAS_ATTACHMENTS) != 0)
11095 return 0;
11096 if (flags & GOVD_DEBUG_PRIVATE)
11098 gcc_assert ((flags & GOVD_DATA_SHARE_CLASS) == GOVD_SHARED);
11099 private_debug = true;
11101 else if (flags & GOVD_MAP)
11102 private_debug = false;
11103 else
11104 private_debug
11105 = lang_hooks.decls.omp_private_debug_clause (decl,
11106 !!(flags & GOVD_SHARED));
11107 if (private_debug)
11108 code = OMP_CLAUSE_PRIVATE;
11109 else if (flags & GOVD_MAP)
11111 code = OMP_CLAUSE_MAP;
11112 if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0
11113 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
11115 error ("%<_Atomic%> %qD in implicit %<map%> clause", decl);
11116 return 0;
11118 if (VAR_P (decl)
11119 && DECL_IN_CONSTANT_POOL (decl)
11120 && !lookup_attribute ("omp declare target",
11121 DECL_ATTRIBUTES (decl)))
11123 tree id = get_identifier ("omp declare target");
11124 DECL_ATTRIBUTES (decl)
11125 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
11126 varpool_node *node = varpool_node::get (decl);
11127 if (node)
11129 node->offloadable = 1;
11130 if (ENABLE_OFFLOADING)
11131 g->have_offload = true;
11135 else if (flags & GOVD_SHARED)
11137 if (is_global_var (decl))
11139 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
11140 while (ctx != NULL)
11142 splay_tree_node on
11143 = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11144 if (on && (on->value & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
11145 | GOVD_PRIVATE | GOVD_REDUCTION
11146 | GOVD_LINEAR | GOVD_MAP)) != 0)
11147 break;
11148 ctx = ctx->outer_context;
11150 if (ctx == NULL)
11151 return 0;
11153 code = OMP_CLAUSE_SHARED;
11154 /* Don't optimize shared into firstprivate for read-only vars
11155 on tasks with depend clause, we shouldn't try to copy them
11156 until the dependencies are satisfied. */
11157 if (gimplify_omp_ctxp->has_depend)
11158 flags |= GOVD_WRITTEN;
11160 else if (flags & GOVD_PRIVATE)
11161 code = OMP_CLAUSE_PRIVATE;
11162 else if (flags & GOVD_FIRSTPRIVATE)
11164 code = OMP_CLAUSE_FIRSTPRIVATE;
11165 if ((gimplify_omp_ctxp->region_type & ORT_TARGET)
11166 && (gimplify_omp_ctxp->region_type & ORT_ACC) == 0
11167 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
11169 error ("%<_Atomic%> %qD in implicit %<firstprivate%> clause on "
11170 "%<target%> construct", decl);
11171 return 0;
11174 else if (flags & GOVD_LASTPRIVATE)
11175 code = OMP_CLAUSE_LASTPRIVATE;
11176 else if (flags & (GOVD_ALIGNED | GOVD_NONTEMPORAL))
11177 return 0;
11178 else if (flags & GOVD_CONDTEMP)
11180 code = OMP_CLAUSE__CONDTEMP_;
11181 gimple_add_tmp_var (decl);
11183 else
11184 gcc_unreachable ();
11186 if (((flags & GOVD_LASTPRIVATE)
11187 || (code == OMP_CLAUSE_SHARED && (flags & GOVD_WRITTEN)))
11188 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
11189 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
11191 tree chain = *list_p;
11192 clause = build_omp_clause (input_location, code);
11193 OMP_CLAUSE_DECL (clause) = decl;
11194 OMP_CLAUSE_CHAIN (clause) = chain;
11195 if (private_debug)
11196 OMP_CLAUSE_PRIVATE_DEBUG (clause) = 1;
11197 else if (code == OMP_CLAUSE_PRIVATE && (flags & GOVD_PRIVATE_OUTER_REF))
11198 OMP_CLAUSE_PRIVATE_OUTER_REF (clause) = 1;
11199 else if (code == OMP_CLAUSE_SHARED
11200 && (flags & GOVD_WRITTEN) == 0
11201 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
11202 OMP_CLAUSE_SHARED_READONLY (clause) = 1;
11203 else if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_EXPLICIT) == 0)
11204 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (clause) = 1;
11205 else if (code == OMP_CLAUSE_MAP && (flags & GOVD_MAP_0LEN_ARRAY) != 0)
11207 tree nc = build_omp_clause (input_location, OMP_CLAUSE_MAP);
11208 OMP_CLAUSE_DECL (nc) = decl;
11209 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
11210 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == POINTER_TYPE)
11211 OMP_CLAUSE_DECL (clause)
11212 = build_simple_mem_ref_loc (input_location, decl);
11213 OMP_CLAUSE_DECL (clause)
11214 = build2 (MEM_REF, char_type_node, OMP_CLAUSE_DECL (clause),
11215 build_int_cst (build_pointer_type (char_type_node), 0));
11216 OMP_CLAUSE_SIZE (clause) = size_zero_node;
11217 OMP_CLAUSE_SIZE (nc) = size_zero_node;
11218 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_ALLOC);
11219 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (clause) = 1;
11220 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
11221 OMP_CLAUSE_CHAIN (nc) = chain;
11222 OMP_CLAUSE_CHAIN (clause) = nc;
11223 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
11224 gimplify_omp_ctxp = ctx->outer_context;
11225 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (clause), 0),
11226 pre_p, NULL, is_gimple_val, fb_rvalue);
11227 gimplify_omp_ctxp = ctx;
11229 else if (code == OMP_CLAUSE_MAP)
11231 int kind;
11232 /* Not all combinations of these GOVD_MAP flags are actually valid. */
11233 switch (flags & (GOVD_MAP_TO_ONLY
11234 | GOVD_MAP_FORCE
11235 | GOVD_MAP_FORCE_PRESENT
11236 | GOVD_MAP_ALLOC_ONLY
11237 | GOVD_MAP_FROM_ONLY))
11239 case 0:
11240 kind = GOMP_MAP_TOFROM;
11241 break;
11242 case GOVD_MAP_FORCE:
11243 kind = GOMP_MAP_TOFROM | GOMP_MAP_FLAG_FORCE;
11244 break;
11245 case GOVD_MAP_TO_ONLY:
11246 kind = GOMP_MAP_TO;
11247 break;
11248 case GOVD_MAP_FROM_ONLY:
11249 kind = GOMP_MAP_FROM;
11250 break;
11251 case GOVD_MAP_ALLOC_ONLY:
11252 kind = GOMP_MAP_ALLOC;
11253 break;
11254 case GOVD_MAP_TO_ONLY | GOVD_MAP_FORCE:
11255 kind = GOMP_MAP_TO | GOMP_MAP_FLAG_FORCE;
11256 break;
11257 case GOVD_MAP_FORCE_PRESENT:
11258 kind = GOMP_MAP_FORCE_PRESENT;
11259 break;
11260 default:
11261 gcc_unreachable ();
11263 OMP_CLAUSE_SET_MAP_KIND (clause, kind);
11264 /* Setting of the implicit flag for the runtime is currently disabled for
11265 OpenACC. */
11266 if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0)
11267 OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (clause) = 1;
11268 if (DECL_SIZE (decl)
11269 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
11271 tree decl2 = DECL_VALUE_EXPR (decl);
11272 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
11273 decl2 = TREE_OPERAND (decl2, 0);
11274 gcc_assert (DECL_P (decl2));
11275 tree mem = build_simple_mem_ref (decl2);
11276 OMP_CLAUSE_DECL (clause) = mem;
11277 OMP_CLAUSE_SIZE (clause) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
11278 if (gimplify_omp_ctxp->outer_context)
11280 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
11281 omp_notice_variable (ctx, decl2, true);
11282 omp_notice_variable (ctx, OMP_CLAUSE_SIZE (clause), true);
11284 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
11285 OMP_CLAUSE_MAP);
11286 OMP_CLAUSE_DECL (nc) = decl;
11287 OMP_CLAUSE_SIZE (nc) = size_zero_node;
11288 if (gimplify_omp_ctxp->target_firstprivatize_array_bases)
11289 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
11290 else
11291 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
11292 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
11293 OMP_CLAUSE_CHAIN (clause) = nc;
11295 else if (gimplify_omp_ctxp->target_firstprivatize_array_bases
11296 && omp_privatize_by_reference (decl))
11298 OMP_CLAUSE_DECL (clause) = build_simple_mem_ref (decl);
11299 OMP_CLAUSE_SIZE (clause)
11300 = unshare_expr (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))));
11301 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
11302 gimplify_omp_ctxp = ctx->outer_context;
11303 gimplify_expr (&OMP_CLAUSE_SIZE (clause),
11304 pre_p, NULL, is_gimple_val, fb_rvalue);
11305 gimplify_omp_ctxp = ctx;
11306 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
11307 OMP_CLAUSE_MAP);
11308 OMP_CLAUSE_DECL (nc) = decl;
11309 OMP_CLAUSE_SIZE (nc) = size_zero_node;
11310 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_REFERENCE);
11311 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
11312 OMP_CLAUSE_CHAIN (clause) = nc;
11314 else
11315 OMP_CLAUSE_SIZE (clause) = DECL_SIZE_UNIT (decl);
11317 if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_LASTPRIVATE) != 0)
11319 tree nc = build_omp_clause (input_location, OMP_CLAUSE_LASTPRIVATE);
11320 OMP_CLAUSE_DECL (nc) = decl;
11321 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (nc) = 1;
11322 OMP_CLAUSE_CHAIN (nc) = chain;
11323 OMP_CLAUSE_CHAIN (clause) = nc;
11324 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
11325 gimplify_omp_ctxp = ctx->outer_context;
11326 lang_hooks.decls.omp_finish_clause (nc, pre_p,
11327 (ctx->region_type & ORT_ACC) != 0);
11328 gimplify_omp_ctxp = ctx;
11330 *list_p = clause;
11331 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
11332 gimplify_omp_ctxp = ctx->outer_context;
11333 /* Don't call omp_finish_clause on implicitly added OMP_CLAUSE_PRIVATE
11334 in simd. Those are only added for the local vars inside of simd body
11335 and they don't need to be e.g. default constructible. */
11336 if (code != OMP_CLAUSE_PRIVATE || ctx->region_type != ORT_SIMD)
11337 lang_hooks.decls.omp_finish_clause (clause, pre_p,
11338 (ctx->region_type & ORT_ACC) != 0);
11339 if (gimplify_omp_ctxp)
11340 for (; clause != chain; clause = OMP_CLAUSE_CHAIN (clause))
11341 if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_MAP
11342 && DECL_P (OMP_CLAUSE_SIZE (clause)))
11343 omp_notice_variable (gimplify_omp_ctxp, OMP_CLAUSE_SIZE (clause),
11344 true);
11345 gimplify_omp_ctxp = ctx;
11346 return 0;
11349 static void
11350 gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
11351 enum tree_code code)
11353 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
11354 tree *orig_list_p = list_p;
11355 tree c, decl;
11356 bool has_inscan_reductions = false;
11358 if (body)
11360 struct gimplify_omp_ctx *octx;
11361 for (octx = ctx; octx; octx = octx->outer_context)
11362 if ((octx->region_type & (ORT_PARALLEL | ORT_TASK | ORT_TEAMS)) != 0)
11363 break;
11364 if (octx)
11366 struct walk_stmt_info wi;
11367 memset (&wi, 0, sizeof (wi));
11368 walk_gimple_seq (body, omp_find_stores_stmt,
11369 omp_find_stores_op, &wi);
11373 if (ctx->add_safelen1)
11375 /* If there are VLAs in the body of simd loop, prevent
11376 vectorization. */
11377 gcc_assert (ctx->region_type == ORT_SIMD);
11378 c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_SAFELEN);
11379 OMP_CLAUSE_SAFELEN_EXPR (c) = integer_one_node;
11380 OMP_CLAUSE_CHAIN (c) = *list_p;
11381 *list_p = c;
11382 list_p = &OMP_CLAUSE_CHAIN (c);
11385 if (ctx->region_type == ORT_WORKSHARE
11386 && ctx->outer_context
11387 && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL)
11389 for (c = ctx->outer_context->clauses; c; c = OMP_CLAUSE_CHAIN (c))
11390 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
11391 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
11393 decl = OMP_CLAUSE_DECL (c);
11394 splay_tree_node n
11395 = splay_tree_lookup (ctx->outer_context->variables,
11396 (splay_tree_key) decl);
11397 gcc_checking_assert (!splay_tree_lookup (ctx->variables,
11398 (splay_tree_key) decl));
11399 omp_add_variable (ctx, decl, n->value);
11400 tree c2 = copy_node (c);
11401 OMP_CLAUSE_CHAIN (c2) = *list_p;
11402 *list_p = c2;
11403 if ((n->value & GOVD_FIRSTPRIVATE) == 0)
11404 continue;
11405 c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
11406 OMP_CLAUSE_FIRSTPRIVATE);
11407 OMP_CLAUSE_DECL (c2) = decl;
11408 OMP_CLAUSE_CHAIN (c2) = *list_p;
11409 *list_p = c2;
11412 while ((c = *list_p) != NULL)
11414 splay_tree_node n;
11415 bool remove = false;
11417 switch (OMP_CLAUSE_CODE (c))
11419 case OMP_CLAUSE_FIRSTPRIVATE:
11420 if ((ctx->region_type & ORT_TARGET)
11421 && (ctx->region_type & ORT_ACC) == 0
11422 && TYPE_ATOMIC (strip_array_types
11423 (TREE_TYPE (OMP_CLAUSE_DECL (c)))))
11425 error_at (OMP_CLAUSE_LOCATION (c),
11426 "%<_Atomic%> %qD in %<firstprivate%> clause on "
11427 "%<target%> construct", OMP_CLAUSE_DECL (c));
11428 remove = true;
11429 break;
11431 if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c))
11433 decl = OMP_CLAUSE_DECL (c);
11434 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11435 if ((n->value & GOVD_MAP) != 0)
11437 remove = true;
11438 break;
11440 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT_TARGET (c) = 0;
11441 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c) = 0;
11443 /* FALLTHRU */
11444 case OMP_CLAUSE_PRIVATE:
11445 case OMP_CLAUSE_SHARED:
11446 case OMP_CLAUSE_LINEAR:
11447 decl = OMP_CLAUSE_DECL (c);
11448 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11449 remove = !(n->value & GOVD_SEEN);
11450 if ((n->value & GOVD_LASTPRIVATE_CONDITIONAL) != 0
11451 && code == OMP_PARALLEL
11452 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
11453 remove = true;
11454 if (! remove)
11456 bool shared = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED;
11457 if ((n->value & GOVD_DEBUG_PRIVATE)
11458 || lang_hooks.decls.omp_private_debug_clause (decl, shared))
11460 gcc_assert ((n->value & GOVD_DEBUG_PRIVATE) == 0
11461 || ((n->value & GOVD_DATA_SHARE_CLASS)
11462 == GOVD_SHARED));
11463 OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_PRIVATE);
11464 OMP_CLAUSE_PRIVATE_DEBUG (c) = 1;
11466 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
11467 && ctx->has_depend
11468 && DECL_P (decl))
11469 n->value |= GOVD_WRITTEN;
11470 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
11471 && (n->value & GOVD_WRITTEN) == 0
11472 && DECL_P (decl)
11473 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
11474 OMP_CLAUSE_SHARED_READONLY (c) = 1;
11475 else if (DECL_P (decl)
11476 && ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
11477 && (n->value & GOVD_WRITTEN) != 0)
11478 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
11479 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
11480 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
11481 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
11483 else
11484 n->value &= ~GOVD_EXPLICIT;
11485 break;
11487 case OMP_CLAUSE_LASTPRIVATE:
11488 /* Make sure OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE is set to
11489 accurately reflect the presence of a FIRSTPRIVATE clause. */
11490 decl = OMP_CLAUSE_DECL (c);
11491 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11492 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c)
11493 = (n->value & GOVD_FIRSTPRIVATE) != 0;
11494 if (code == OMP_DISTRIBUTE
11495 && OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
11497 remove = true;
11498 error_at (OMP_CLAUSE_LOCATION (c),
11499 "same variable used in %<firstprivate%> and "
11500 "%<lastprivate%> clauses on %<distribute%> "
11501 "construct");
11503 if (!remove
11504 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
11505 && DECL_P (decl)
11506 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
11507 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
11508 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) && code == OMP_PARALLEL)
11509 remove = true;
11510 break;
11512 case OMP_CLAUSE_ALIGNED:
11513 decl = OMP_CLAUSE_DECL (c);
11514 if (!is_global_var (decl))
11516 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11517 remove = n == NULL || !(n->value & GOVD_SEEN);
11518 if (!remove && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
11520 struct gimplify_omp_ctx *octx;
11521 if (n != NULL
11522 && (n->value & (GOVD_DATA_SHARE_CLASS
11523 & ~GOVD_FIRSTPRIVATE)))
11524 remove = true;
11525 else
11526 for (octx = ctx->outer_context; octx;
11527 octx = octx->outer_context)
11529 n = splay_tree_lookup (octx->variables,
11530 (splay_tree_key) decl);
11531 if (n == NULL)
11532 continue;
11533 if (n->value & GOVD_LOCAL)
11534 break;
11535 /* We have to avoid assigning a shared variable
11536 to itself when trying to add
11537 __builtin_assume_aligned. */
11538 if (n->value & GOVD_SHARED)
11540 remove = true;
11541 break;
11546 else if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
11548 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11549 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
11550 remove = true;
11552 break;
11554 case OMP_CLAUSE_HAS_DEVICE_ADDR:
11555 decl = OMP_CLAUSE_DECL (c);
11556 while (TREE_CODE (decl) == INDIRECT_REF
11557 || TREE_CODE (decl) == ARRAY_REF)
11558 decl = TREE_OPERAND (decl, 0);
11559 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11560 remove = n == NULL || !(n->value & GOVD_SEEN);
11561 break;
11563 case OMP_CLAUSE_IS_DEVICE_PTR:
11564 case OMP_CLAUSE_NONTEMPORAL:
11565 decl = OMP_CLAUSE_DECL (c);
11566 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11567 remove = n == NULL || !(n->value & GOVD_SEEN);
11568 break;
11570 case OMP_CLAUSE_MAP:
11571 if (code == OMP_TARGET_EXIT_DATA
11572 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER)
11574 remove = true;
11575 break;
11577 decl = OMP_CLAUSE_DECL (c);
11578 /* Data clauses associated with reductions must be
11579 compatible with present_or_copy. Warn and adjust the clause
11580 if that is not the case. */
11581 if (ctx->region_type == ORT_ACC_PARALLEL
11582 || ctx->region_type == ORT_ACC_SERIAL)
11584 tree t = DECL_P (decl) ? decl : TREE_OPERAND (decl, 0);
11585 n = NULL;
11587 if (DECL_P (t))
11588 n = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
11590 if (n && (n->value & GOVD_REDUCTION))
11592 enum gomp_map_kind kind = OMP_CLAUSE_MAP_KIND (c);
11594 OMP_CLAUSE_MAP_IN_REDUCTION (c) = 1;
11595 if ((kind & GOMP_MAP_TOFROM) != GOMP_MAP_TOFROM
11596 && kind != GOMP_MAP_FORCE_PRESENT
11597 && kind != GOMP_MAP_POINTER)
11599 warning_at (OMP_CLAUSE_LOCATION (c), 0,
11600 "incompatible data clause with reduction "
11601 "on %qE; promoting to %<present_or_copy%>",
11602 DECL_NAME (t));
11603 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TOFROM);
11607 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT
11608 && (code == OMP_TARGET_EXIT_DATA || code == OACC_EXIT_DATA))
11610 remove = true;
11611 break;
11613 if (!DECL_P (decl))
11615 if ((ctx->region_type & ORT_TARGET) != 0
11616 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
11618 if (TREE_CODE (decl) == INDIRECT_REF
11619 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
11620 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
11621 == REFERENCE_TYPE))
11622 decl = TREE_OPERAND (decl, 0);
11623 if (TREE_CODE (decl) == COMPONENT_REF)
11625 while (TREE_CODE (decl) == COMPONENT_REF)
11626 decl = TREE_OPERAND (decl, 0);
11627 if (DECL_P (decl))
11629 n = splay_tree_lookup (ctx->variables,
11630 (splay_tree_key) decl);
11631 if (!(n->value & GOVD_SEEN))
11632 remove = true;
11636 break;
11638 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11639 if ((ctx->region_type & ORT_TARGET) != 0
11640 && !(n->value & GOVD_SEEN)
11641 && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) == 0
11642 && (!is_global_var (decl)
11643 || !lookup_attribute ("omp declare target link",
11644 DECL_ATTRIBUTES (decl))))
11646 remove = true;
11647 /* For struct element mapping, if struct is never referenced
11648 in target block and none of the mapping has always modifier,
11649 remove all the struct element mappings, which immediately
11650 follow the GOMP_MAP_STRUCT map clause. */
11651 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT)
11653 HOST_WIDE_INT cnt = tree_to_shwi (OMP_CLAUSE_SIZE (c));
11654 while (cnt--)
11655 OMP_CLAUSE_CHAIN (c)
11656 = OMP_CLAUSE_CHAIN (OMP_CLAUSE_CHAIN (c));
11659 else if (DECL_SIZE (decl)
11660 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST
11661 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_POINTER
11662 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_POINTER
11663 && (OMP_CLAUSE_MAP_KIND (c)
11664 != GOMP_MAP_FIRSTPRIVATE_REFERENCE))
11666 /* For GOMP_MAP_FORCE_DEVICEPTR, we'll never enter here, because
11667 for these, TREE_CODE (DECL_SIZE (decl)) will always be
11668 INTEGER_CST. */
11669 gcc_assert (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FORCE_DEVICEPTR);
11671 tree decl2 = DECL_VALUE_EXPR (decl);
11672 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
11673 decl2 = TREE_OPERAND (decl2, 0);
11674 gcc_assert (DECL_P (decl2));
11675 tree mem = build_simple_mem_ref (decl2);
11676 OMP_CLAUSE_DECL (c) = mem;
11677 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
11678 if (ctx->outer_context)
11680 omp_notice_variable (ctx->outer_context, decl2, true);
11681 omp_notice_variable (ctx->outer_context,
11682 OMP_CLAUSE_SIZE (c), true);
11684 if (((ctx->region_type & ORT_TARGET) != 0
11685 || !ctx->target_firstprivatize_array_bases)
11686 && ((n->value & GOVD_SEEN) == 0
11687 || (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) == 0))
11689 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
11690 OMP_CLAUSE_MAP);
11691 OMP_CLAUSE_DECL (nc) = decl;
11692 OMP_CLAUSE_SIZE (nc) = size_zero_node;
11693 if (ctx->target_firstprivatize_array_bases)
11694 OMP_CLAUSE_SET_MAP_KIND (nc,
11695 GOMP_MAP_FIRSTPRIVATE_POINTER);
11696 else
11697 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
11698 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
11699 OMP_CLAUSE_CHAIN (c) = nc;
11700 c = nc;
11703 else
11705 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
11706 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
11707 gcc_assert ((n->value & GOVD_SEEN) == 0
11708 || ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
11709 == 0));
11711 break;
11713 case OMP_CLAUSE_TO:
11714 case OMP_CLAUSE_FROM:
11715 case OMP_CLAUSE__CACHE_:
11716 decl = OMP_CLAUSE_DECL (c);
11717 if (!DECL_P (decl))
11718 break;
11719 if (DECL_SIZE (decl)
11720 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
11722 tree decl2 = DECL_VALUE_EXPR (decl);
11723 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
11724 decl2 = TREE_OPERAND (decl2, 0);
11725 gcc_assert (DECL_P (decl2));
11726 tree mem = build_simple_mem_ref (decl2);
11727 OMP_CLAUSE_DECL (c) = mem;
11728 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
11729 if (ctx->outer_context)
11731 omp_notice_variable (ctx->outer_context, decl2, true);
11732 omp_notice_variable (ctx->outer_context,
11733 OMP_CLAUSE_SIZE (c), true);
11736 else if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
11737 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
11738 break;
11740 case OMP_CLAUSE_REDUCTION:
11741 if (OMP_CLAUSE_REDUCTION_INSCAN (c))
11743 decl = OMP_CLAUSE_DECL (c);
11744 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11745 if ((n->value & GOVD_REDUCTION_INSCAN) == 0)
11747 remove = true;
11748 error_at (OMP_CLAUSE_LOCATION (c),
11749 "%qD specified in %<inscan%> %<reduction%> clause "
11750 "but not in %<scan%> directive clause", decl);
11751 break;
11753 has_inscan_reductions = true;
11755 /* FALLTHRU */
11756 case OMP_CLAUSE_IN_REDUCTION:
11757 case OMP_CLAUSE_TASK_REDUCTION:
11758 decl = OMP_CLAUSE_DECL (c);
11759 /* OpenACC reductions need a present_or_copy data clause.
11760 Add one if necessary. Emit error when the reduction is private. */
11761 if (ctx->region_type == ORT_ACC_PARALLEL
11762 || ctx->region_type == ORT_ACC_SERIAL)
11764 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11765 if (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
11767 remove = true;
11768 error_at (OMP_CLAUSE_LOCATION (c), "invalid private "
11769 "reduction on %qE", DECL_NAME (decl));
11771 else if ((n->value & GOVD_MAP) == 0)
11773 tree next = OMP_CLAUSE_CHAIN (c);
11774 tree nc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_MAP);
11775 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_TOFROM);
11776 OMP_CLAUSE_DECL (nc) = decl;
11777 OMP_CLAUSE_CHAIN (c) = nc;
11778 lang_hooks.decls.omp_finish_clause (nc, pre_p,
11779 (ctx->region_type
11780 & ORT_ACC) != 0);
11781 while (1)
11783 OMP_CLAUSE_MAP_IN_REDUCTION (nc) = 1;
11784 if (OMP_CLAUSE_CHAIN (nc) == NULL)
11785 break;
11786 nc = OMP_CLAUSE_CHAIN (nc);
11788 OMP_CLAUSE_CHAIN (nc) = next;
11789 n->value |= GOVD_MAP;
11792 if (DECL_P (decl)
11793 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
11794 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
11795 break;
11797 case OMP_CLAUSE_ALLOCATE:
11798 decl = OMP_CLAUSE_DECL (c);
11799 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11800 if (n != NULL && !(n->value & GOVD_SEEN))
11802 if ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE | GOVD_LINEAR))
11803 != 0
11804 && (n->value & (GOVD_REDUCTION | GOVD_LASTPRIVATE)) == 0)
11805 remove = true;
11807 if (!remove
11808 && OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
11809 && TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)) != INTEGER_CST
11810 && ((ctx->region_type & (ORT_PARALLEL | ORT_TARGET)) != 0
11811 || (ctx->region_type & ORT_TASKLOOP) == ORT_TASK
11812 || (ctx->region_type & ORT_HOST_TEAMS) == ORT_HOST_TEAMS))
11814 tree allocator = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
11815 n = splay_tree_lookup (ctx->variables, (splay_tree_key) allocator);
11816 if (n == NULL)
11818 enum omp_clause_default_kind default_kind
11819 = ctx->default_kind;
11820 ctx->default_kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
11821 omp_notice_variable (ctx, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
11822 true);
11823 ctx->default_kind = default_kind;
11825 else
11826 omp_notice_variable (ctx, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
11827 true);
11829 break;
11831 case OMP_CLAUSE_COPYIN:
11832 case OMP_CLAUSE_COPYPRIVATE:
11833 case OMP_CLAUSE_IF:
11834 case OMP_CLAUSE_NUM_THREADS:
11835 case OMP_CLAUSE_NUM_TEAMS:
11836 case OMP_CLAUSE_THREAD_LIMIT:
11837 case OMP_CLAUSE_DIST_SCHEDULE:
11838 case OMP_CLAUSE_DEVICE:
11839 case OMP_CLAUSE_SCHEDULE:
11840 case OMP_CLAUSE_NOWAIT:
11841 case OMP_CLAUSE_ORDERED:
11842 case OMP_CLAUSE_DEFAULT:
11843 case OMP_CLAUSE_UNTIED:
11844 case OMP_CLAUSE_COLLAPSE:
11845 case OMP_CLAUSE_FINAL:
11846 case OMP_CLAUSE_MERGEABLE:
11847 case OMP_CLAUSE_PROC_BIND:
11848 case OMP_CLAUSE_SAFELEN:
11849 case OMP_CLAUSE_SIMDLEN:
11850 case OMP_CLAUSE_DEPEND:
11851 case OMP_CLAUSE_PRIORITY:
11852 case OMP_CLAUSE_GRAINSIZE:
11853 case OMP_CLAUSE_NUM_TASKS:
11854 case OMP_CLAUSE_NOGROUP:
11855 case OMP_CLAUSE_THREADS:
11856 case OMP_CLAUSE_SIMD:
11857 case OMP_CLAUSE_FILTER:
11858 case OMP_CLAUSE_HINT:
11859 case OMP_CLAUSE_DEFAULTMAP:
11860 case OMP_CLAUSE_ORDER:
11861 case OMP_CLAUSE_BIND:
11862 case OMP_CLAUSE_DETACH:
11863 case OMP_CLAUSE_USE_DEVICE_PTR:
11864 case OMP_CLAUSE_USE_DEVICE_ADDR:
11865 case OMP_CLAUSE_ASYNC:
11866 case OMP_CLAUSE_WAIT:
11867 case OMP_CLAUSE_INDEPENDENT:
11868 case OMP_CLAUSE_NUM_GANGS:
11869 case OMP_CLAUSE_NUM_WORKERS:
11870 case OMP_CLAUSE_VECTOR_LENGTH:
11871 case OMP_CLAUSE_GANG:
11872 case OMP_CLAUSE_WORKER:
11873 case OMP_CLAUSE_VECTOR:
11874 case OMP_CLAUSE_AUTO:
11875 case OMP_CLAUSE_SEQ:
11876 case OMP_CLAUSE_TILE:
11877 case OMP_CLAUSE_IF_PRESENT:
11878 case OMP_CLAUSE_FINALIZE:
11879 case OMP_CLAUSE_INCLUSIVE:
11880 case OMP_CLAUSE_EXCLUSIVE:
11881 break;
11883 case OMP_CLAUSE_NOHOST:
11884 default:
11885 gcc_unreachable ();
11888 if (remove)
11889 *list_p = OMP_CLAUSE_CHAIN (c);
11890 else
11891 list_p = &OMP_CLAUSE_CHAIN (c);
11894 /* Add in any implicit data sharing. */
11895 struct gimplify_adjust_omp_clauses_data data;
11896 if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0)
11898 /* OpenMP. Implicit clauses are added at the start of the clause list,
11899 but after any non-map clauses. */
11900 tree *implicit_add_list_p = orig_list_p;
11901 while (*implicit_add_list_p
11902 && OMP_CLAUSE_CODE (*implicit_add_list_p) != OMP_CLAUSE_MAP)
11903 implicit_add_list_p = &OMP_CLAUSE_CHAIN (*implicit_add_list_p);
11904 data.list_p = implicit_add_list_p;
11906 else
11907 /* OpenACC. */
11908 data.list_p = list_p;
11909 data.pre_p = pre_p;
11910 splay_tree_foreach (ctx->variables, gimplify_adjust_omp_clauses_1, &data);
11912 if (has_inscan_reductions)
11913 for (c = *orig_list_p; c; c = OMP_CLAUSE_CHAIN (c))
11914 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
11915 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
11917 error_at (OMP_CLAUSE_LOCATION (c),
11918 "%<inscan%> %<reduction%> clause used together with "
11919 "%<linear%> clause for a variable other than loop "
11920 "iterator");
11921 break;
11924 gimplify_omp_ctxp = ctx->outer_context;
11925 delete_omp_context (ctx);
11928 /* Return 0 if CONSTRUCTS selectors don't match the OpenMP context,
11929 -1 if unknown yet (simd is involved, won't be known until vectorization)
11930 and 1 if they do. If SCORES is non-NULL, it should point to an array
11931 of at least 2*NCONSTRUCTS+2 ints, and will be filled with the positions
11932 of the CONSTRUCTS (position -1 if it will never match) followed by
11933 number of constructs in the OpenMP context construct trait. If the
11934 score depends on whether it will be in a declare simd clone or not,
11935 the function returns 2 and there will be two sets of the scores, the first
11936 one for the case that it is not in a declare simd clone, the other
11937 that it is in a declare simd clone. */
11940 omp_construct_selector_matches (enum tree_code *constructs, int nconstructs,
11941 int *scores)
11943 int matched = 0, cnt = 0;
11944 bool simd_seen = false;
11945 bool target_seen = false;
11946 int declare_simd_cnt = -1;
11947 auto_vec<enum tree_code, 16> codes;
11948 for (struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; ctx;)
11950 if (((ctx->region_type & ORT_PARALLEL) && ctx->code == OMP_PARALLEL)
11951 || ((ctx->region_type & (ORT_TARGET | ORT_IMPLICIT_TARGET | ORT_ACC))
11952 == ORT_TARGET && ctx->code == OMP_TARGET)
11953 || ((ctx->region_type & ORT_TEAMS) && ctx->code == OMP_TEAMS)
11954 || (ctx->region_type == ORT_WORKSHARE && ctx->code == OMP_FOR)
11955 || (ctx->region_type == ORT_SIMD
11956 && ctx->code == OMP_SIMD
11957 && !omp_find_clause (ctx->clauses, OMP_CLAUSE_BIND)))
11959 ++cnt;
11960 if (scores)
11961 codes.safe_push (ctx->code);
11962 else if (matched < nconstructs && ctx->code == constructs[matched])
11964 if (ctx->code == OMP_SIMD)
11966 if (matched)
11967 return 0;
11968 simd_seen = true;
11970 ++matched;
11972 if (ctx->code == OMP_TARGET)
11974 if (scores == NULL)
11975 return matched < nconstructs ? 0 : simd_seen ? -1 : 1;
11976 target_seen = true;
11977 break;
11980 else if (ctx->region_type == ORT_WORKSHARE
11981 && ctx->code == OMP_LOOP
11982 && ctx->outer_context
11983 && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL
11984 && ctx->outer_context->outer_context
11985 && ctx->outer_context->outer_context->code == OMP_LOOP
11986 && ctx->outer_context->outer_context->distribute)
11987 ctx = ctx->outer_context->outer_context;
11988 ctx = ctx->outer_context;
11990 if (!target_seen
11991 && lookup_attribute ("omp declare simd",
11992 DECL_ATTRIBUTES (current_function_decl)))
11994 /* Declare simd is a maybe case, it is supposed to be added only to the
11995 omp-simd-clone.cc added clones and not to the base function. */
11996 declare_simd_cnt = cnt++;
11997 if (scores)
11998 codes.safe_push (OMP_SIMD);
11999 else if (cnt == 0
12000 && constructs[0] == OMP_SIMD)
12002 gcc_assert (matched == 0);
12003 simd_seen = true;
12004 if (++matched == nconstructs)
12005 return -1;
12008 if (tree attr = lookup_attribute ("omp declare variant variant",
12009 DECL_ATTRIBUTES (current_function_decl)))
12011 enum tree_code variant_constructs[5];
12012 int variant_nconstructs = 0;
12013 if (!target_seen)
12014 variant_nconstructs
12015 = omp_constructor_traits_to_codes (TREE_VALUE (attr),
12016 variant_constructs);
12017 for (int i = 0; i < variant_nconstructs; i++)
12019 ++cnt;
12020 if (scores)
12021 codes.safe_push (variant_constructs[i]);
12022 else if (matched < nconstructs
12023 && variant_constructs[i] == constructs[matched])
12025 if (variant_constructs[i] == OMP_SIMD)
12027 if (matched)
12028 return 0;
12029 simd_seen = true;
12031 ++matched;
12035 if (!target_seen
12036 && lookup_attribute ("omp declare target block",
12037 DECL_ATTRIBUTES (current_function_decl)))
12039 if (scores)
12040 codes.safe_push (OMP_TARGET);
12041 else if (matched < nconstructs && constructs[matched] == OMP_TARGET)
12042 ++matched;
12044 if (scores)
12046 for (int pass = 0; pass < (declare_simd_cnt == -1 ? 1 : 2); pass++)
12048 int j = codes.length () - 1;
12049 for (int i = nconstructs - 1; i >= 0; i--)
12051 while (j >= 0
12052 && (pass != 0 || declare_simd_cnt != j)
12053 && constructs[i] != codes[j])
12054 --j;
12055 if (pass == 0 && declare_simd_cnt != -1 && j > declare_simd_cnt)
12056 *scores++ = j - 1;
12057 else
12058 *scores++ = j;
12060 *scores++ = ((pass == 0 && declare_simd_cnt != -1)
12061 ? codes.length () - 1 : codes.length ());
12063 return declare_simd_cnt == -1 ? 1 : 2;
12065 if (matched == nconstructs)
12066 return simd_seen ? -1 : 1;
12067 return 0;
12070 /* Gimplify OACC_CACHE. */
12072 static void
12073 gimplify_oacc_cache (tree *expr_p, gimple_seq *pre_p)
12075 tree expr = *expr_p;
12077 gimplify_scan_omp_clauses (&OACC_CACHE_CLAUSES (expr), pre_p, ORT_ACC,
12078 OACC_CACHE);
12079 gimplify_adjust_omp_clauses (pre_p, NULL, &OACC_CACHE_CLAUSES (expr),
12080 OACC_CACHE);
12082 /* TODO: Do something sensible with this information. */
12084 *expr_p = NULL_TREE;
12087 /* Helper function of gimplify_oacc_declare. The helper's purpose is to,
12088 if required, translate 'kind' in CLAUSE into an 'entry' kind and 'exit'
12089 kind. The entry kind will replace the one in CLAUSE, while the exit
12090 kind will be used in a new omp_clause and returned to the caller. */
12092 static tree
12093 gimplify_oacc_declare_1 (tree clause)
12095 HOST_WIDE_INT kind, new_op;
12096 bool ret = false;
12097 tree c = NULL;
12099 kind = OMP_CLAUSE_MAP_KIND (clause);
12101 switch (kind)
12103 case GOMP_MAP_ALLOC:
12104 new_op = GOMP_MAP_RELEASE;
12105 ret = true;
12106 break;
12108 case GOMP_MAP_FROM:
12109 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_FORCE_ALLOC);
12110 new_op = GOMP_MAP_FROM;
12111 ret = true;
12112 break;
12114 case GOMP_MAP_TOFROM:
12115 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_TO);
12116 new_op = GOMP_MAP_FROM;
12117 ret = true;
12118 break;
12120 case GOMP_MAP_DEVICE_RESIDENT:
12121 case GOMP_MAP_FORCE_DEVICEPTR:
12122 case GOMP_MAP_FORCE_PRESENT:
12123 case GOMP_MAP_LINK:
12124 case GOMP_MAP_POINTER:
12125 case GOMP_MAP_TO:
12126 break;
12128 default:
12129 gcc_unreachable ();
12130 break;
12133 if (ret)
12135 c = build_omp_clause (OMP_CLAUSE_LOCATION (clause), OMP_CLAUSE_MAP);
12136 OMP_CLAUSE_SET_MAP_KIND (c, new_op);
12137 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clause);
12140 return c;
12143 /* Gimplify OACC_DECLARE. */
12145 static void
12146 gimplify_oacc_declare (tree *expr_p, gimple_seq *pre_p)
12148 tree expr = *expr_p;
12149 gomp_target *stmt;
12150 tree clauses, t, decl;
12152 clauses = OACC_DECLARE_CLAUSES (expr);
12154 gimplify_scan_omp_clauses (&clauses, pre_p, ORT_TARGET_DATA, OACC_DECLARE);
12155 gimplify_adjust_omp_clauses (pre_p, NULL, &clauses, OACC_DECLARE);
12157 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
12159 decl = OMP_CLAUSE_DECL (t);
12161 if (TREE_CODE (decl) == MEM_REF)
12162 decl = TREE_OPERAND (decl, 0);
12164 if (VAR_P (decl) && !is_oacc_declared (decl))
12166 tree attr = get_identifier ("oacc declare target");
12167 DECL_ATTRIBUTES (decl) = tree_cons (attr, NULL_TREE,
12168 DECL_ATTRIBUTES (decl));
12171 if (VAR_P (decl)
12172 && !is_global_var (decl)
12173 && DECL_CONTEXT (decl) == current_function_decl)
12175 tree c = gimplify_oacc_declare_1 (t);
12176 if (c)
12178 if (oacc_declare_returns == NULL)
12179 oacc_declare_returns = new hash_map<tree, tree>;
12181 oacc_declare_returns->put (decl, c);
12185 if (gimplify_omp_ctxp)
12186 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_SEEN);
12189 stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
12190 clauses);
12192 gimplify_seq_add_stmt (pre_p, stmt);
12194 *expr_p = NULL_TREE;
12197 /* Gimplify the contents of an OMP_PARALLEL statement. This involves
12198 gimplification of the body, as well as scanning the body for used
12199 variables. We need to do this scan now, because variable-sized
12200 decls will be decomposed during gimplification. */
12202 static void
12203 gimplify_omp_parallel (tree *expr_p, gimple_seq *pre_p)
12205 tree expr = *expr_p;
12206 gimple *g;
12207 gimple_seq body = NULL;
12209 gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr), pre_p,
12210 OMP_PARALLEL_COMBINED (expr)
12211 ? ORT_COMBINED_PARALLEL
12212 : ORT_PARALLEL, OMP_PARALLEL);
12214 push_gimplify_context ();
12216 g = gimplify_and_return_first (OMP_PARALLEL_BODY (expr), &body);
12217 if (gimple_code (g) == GIMPLE_BIND)
12218 pop_gimplify_context (g);
12219 else
12220 pop_gimplify_context (NULL);
12222 gimplify_adjust_omp_clauses (pre_p, body, &OMP_PARALLEL_CLAUSES (expr),
12223 OMP_PARALLEL);
12225 g = gimple_build_omp_parallel (body,
12226 OMP_PARALLEL_CLAUSES (expr),
12227 NULL_TREE, NULL_TREE);
12228 if (OMP_PARALLEL_COMBINED (expr))
12229 gimple_omp_set_subcode (g, GF_OMP_PARALLEL_COMBINED);
12230 gimplify_seq_add_stmt (pre_p, g);
12231 *expr_p = NULL_TREE;
12234 /* Gimplify the contents of an OMP_TASK statement. This involves
12235 gimplification of the body, as well as scanning the body for used
12236 variables. We need to do this scan now, because variable-sized
12237 decls will be decomposed during gimplification. */
12239 static void
12240 gimplify_omp_task (tree *expr_p, gimple_seq *pre_p)
12242 tree expr = *expr_p;
12243 gimple *g;
12244 gimple_seq body = NULL;
12246 if (OMP_TASK_BODY (expr) == NULL_TREE)
12247 for (tree c = OMP_TASK_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
12248 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
12249 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_MUTEXINOUTSET)
12251 error_at (OMP_CLAUSE_LOCATION (c),
12252 "%<mutexinoutset%> kind in %<depend%> clause on a "
12253 "%<taskwait%> construct");
12254 break;
12257 gimplify_scan_omp_clauses (&OMP_TASK_CLAUSES (expr), pre_p,
12258 omp_find_clause (OMP_TASK_CLAUSES (expr),
12259 OMP_CLAUSE_UNTIED)
12260 ? ORT_UNTIED_TASK : ORT_TASK, OMP_TASK);
12262 if (OMP_TASK_BODY (expr))
12264 push_gimplify_context ();
12266 g = gimplify_and_return_first (OMP_TASK_BODY (expr), &body);
12267 if (gimple_code (g) == GIMPLE_BIND)
12268 pop_gimplify_context (g);
12269 else
12270 pop_gimplify_context (NULL);
12273 gimplify_adjust_omp_clauses (pre_p, body, &OMP_TASK_CLAUSES (expr),
12274 OMP_TASK);
12276 g = gimple_build_omp_task (body,
12277 OMP_TASK_CLAUSES (expr),
12278 NULL_TREE, NULL_TREE,
12279 NULL_TREE, NULL_TREE, NULL_TREE);
12280 if (OMP_TASK_BODY (expr) == NULL_TREE)
12281 gimple_omp_task_set_taskwait_p (g, true);
12282 gimplify_seq_add_stmt (pre_p, g);
12283 *expr_p = NULL_TREE;
12286 /* Helper function for gimplify_omp_for. If *TP is not a gimple constant,
12287 force it into a temporary initialized in PRE_P and add firstprivate clause
12288 to ORIG_FOR_STMT. */
12290 static void
12291 gimplify_omp_taskloop_expr (tree type, tree *tp, gimple_seq *pre_p,
12292 tree orig_for_stmt)
12294 if (*tp == NULL || is_gimple_constant (*tp))
12295 return;
12297 *tp = get_initialized_tmp_var (*tp, pre_p, NULL, false);
12298 /* Reference to pointer conversion is considered useless,
12299 but is significant for firstprivate clause. Force it
12300 here. */
12301 if (type
12302 && TREE_CODE (type) == POINTER_TYPE
12303 && TREE_CODE (TREE_TYPE (*tp)) == REFERENCE_TYPE)
12305 tree v = create_tmp_var (TYPE_MAIN_VARIANT (type));
12306 tree m = build2 (INIT_EXPR, TREE_TYPE (v), v, *tp);
12307 gimplify_and_add (m, pre_p);
12308 *tp = v;
12311 tree c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
12312 OMP_CLAUSE_DECL (c) = *tp;
12313 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
12314 OMP_FOR_CLAUSES (orig_for_stmt) = c;
12317 /* Gimplify the gross structure of an OMP_FOR statement. */
12319 static enum gimplify_status
12320 gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
12322 tree for_stmt, orig_for_stmt, inner_for_stmt = NULL_TREE, decl, var, t;
12323 enum gimplify_status ret = GS_ALL_DONE;
12324 enum gimplify_status tret;
12325 gomp_for *gfor;
12326 gimple_seq for_body, for_pre_body;
12327 int i;
12328 bitmap has_decl_expr = NULL;
12329 enum omp_region_type ort = ORT_WORKSHARE;
12330 bool openacc = TREE_CODE (*expr_p) == OACC_LOOP;
12332 orig_for_stmt = for_stmt = *expr_p;
12334 bool loop_p = (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_BIND)
12335 != NULL_TREE);
12336 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
12338 tree *data[4] = { NULL, NULL, NULL, NULL };
12339 gcc_assert (TREE_CODE (for_stmt) != OACC_LOOP);
12340 inner_for_stmt = walk_tree (&OMP_FOR_BODY (for_stmt),
12341 find_combined_omp_for, data, NULL);
12342 if (inner_for_stmt == NULL_TREE)
12344 gcc_assert (seen_error ());
12345 *expr_p = NULL_TREE;
12346 return GS_ERROR;
12348 if (data[2] && OMP_FOR_PRE_BODY (*data[2]))
12350 append_to_statement_list_force (OMP_FOR_PRE_BODY (*data[2]),
12351 &OMP_FOR_PRE_BODY (for_stmt));
12352 OMP_FOR_PRE_BODY (*data[2]) = NULL_TREE;
12354 if (OMP_FOR_PRE_BODY (inner_for_stmt))
12356 append_to_statement_list_force (OMP_FOR_PRE_BODY (inner_for_stmt),
12357 &OMP_FOR_PRE_BODY (for_stmt));
12358 OMP_FOR_PRE_BODY (inner_for_stmt) = NULL_TREE;
12361 if (data[0])
12363 /* We have some statements or variable declarations in between
12364 the composite construct directives. Move them around the
12365 inner_for_stmt. */
12366 data[0] = expr_p;
12367 for (i = 0; i < 3; i++)
12368 if (data[i])
12370 tree t = *data[i];
12371 if (i < 2 && data[i + 1] == &OMP_BODY (t))
12372 data[i + 1] = data[i];
12373 *data[i] = OMP_BODY (t);
12374 tree body = build3 (BIND_EXPR, void_type_node, NULL_TREE,
12375 NULL_TREE, make_node (BLOCK));
12376 OMP_BODY (t) = body;
12377 append_to_statement_list_force (inner_for_stmt,
12378 &BIND_EXPR_BODY (body));
12379 *data[3] = t;
12380 data[3] = tsi_stmt_ptr (tsi_start (BIND_EXPR_BODY (body)));
12381 gcc_assert (*data[3] == inner_for_stmt);
12383 return GS_OK;
12386 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
12387 if (!loop_p
12388 && OMP_FOR_ORIG_DECLS (inner_for_stmt)
12389 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
12390 i)) == TREE_LIST
12391 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
12392 i)))
12394 tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
12395 /* Class iterators aren't allowed on OMP_SIMD, so the only
12396 case we need to solve is distribute parallel for. They are
12397 allowed on the loop construct, but that is already handled
12398 in gimplify_omp_loop. */
12399 gcc_assert (TREE_CODE (inner_for_stmt) == OMP_FOR
12400 && TREE_CODE (for_stmt) == OMP_DISTRIBUTE
12401 && data[1]);
12402 tree orig_decl = TREE_PURPOSE (orig);
12403 tree last = TREE_VALUE (orig);
12404 tree *pc;
12405 for (pc = &OMP_FOR_CLAUSES (inner_for_stmt);
12406 *pc; pc = &OMP_CLAUSE_CHAIN (*pc))
12407 if ((OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE
12408 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LASTPRIVATE)
12409 && OMP_CLAUSE_DECL (*pc) == orig_decl)
12410 break;
12411 if (*pc == NULL_TREE)
12413 tree *spc;
12414 for (spc = &OMP_PARALLEL_CLAUSES (*data[1]);
12415 *spc; spc = &OMP_CLAUSE_CHAIN (*spc))
12416 if (OMP_CLAUSE_CODE (*spc) == OMP_CLAUSE_PRIVATE
12417 && OMP_CLAUSE_DECL (*spc) == orig_decl)
12418 break;
12419 if (*spc)
12421 tree c = *spc;
12422 *spc = OMP_CLAUSE_CHAIN (c);
12423 OMP_CLAUSE_CHAIN (c) = NULL_TREE;
12424 *pc = c;
12427 if (*pc == NULL_TREE)
12429 else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE)
12431 /* private clause will appear only on inner_for_stmt.
12432 Change it into firstprivate, and add private clause
12433 on for_stmt. */
12434 tree c = copy_node (*pc);
12435 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
12436 OMP_FOR_CLAUSES (for_stmt) = c;
12437 OMP_CLAUSE_CODE (*pc) = OMP_CLAUSE_FIRSTPRIVATE;
12438 lang_hooks.decls.omp_finish_clause (*pc, pre_p, openacc);
12440 else
12442 /* lastprivate clause will appear on both inner_for_stmt
12443 and for_stmt. Add firstprivate clause to
12444 inner_for_stmt. */
12445 tree c = build_omp_clause (OMP_CLAUSE_LOCATION (*pc),
12446 OMP_CLAUSE_FIRSTPRIVATE);
12447 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (*pc);
12448 OMP_CLAUSE_CHAIN (c) = *pc;
12449 *pc = c;
12450 lang_hooks.decls.omp_finish_clause (*pc, pre_p, openacc);
12452 tree c = build_omp_clause (UNKNOWN_LOCATION,
12453 OMP_CLAUSE_FIRSTPRIVATE);
12454 OMP_CLAUSE_DECL (c) = last;
12455 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
12456 OMP_PARALLEL_CLAUSES (*data[1]) = c;
12457 c = build_omp_clause (UNKNOWN_LOCATION,
12458 *pc ? OMP_CLAUSE_SHARED
12459 : OMP_CLAUSE_FIRSTPRIVATE);
12460 OMP_CLAUSE_DECL (c) = orig_decl;
12461 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
12462 OMP_PARALLEL_CLAUSES (*data[1]) = c;
12464 /* Similarly, take care of C++ range for temporaries, those should
12465 be firstprivate on OMP_PARALLEL if any. */
12466 if (data[1])
12467 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
12468 if (OMP_FOR_ORIG_DECLS (inner_for_stmt)
12469 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
12470 i)) == TREE_LIST
12471 && TREE_CHAIN (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
12472 i)))
12474 tree orig
12475 = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
12476 tree v = TREE_CHAIN (orig);
12477 tree c = build_omp_clause (UNKNOWN_LOCATION,
12478 OMP_CLAUSE_FIRSTPRIVATE);
12479 /* First add firstprivate clause for the __for_end artificial
12480 decl. */
12481 OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 1);
12482 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
12483 == REFERENCE_TYPE)
12484 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
12485 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
12486 OMP_PARALLEL_CLAUSES (*data[1]) = c;
12487 if (TREE_VEC_ELT (v, 0))
12489 /* And now the same for __for_range artificial decl if it
12490 exists. */
12491 c = build_omp_clause (UNKNOWN_LOCATION,
12492 OMP_CLAUSE_FIRSTPRIVATE);
12493 OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 0);
12494 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
12495 == REFERENCE_TYPE)
12496 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
12497 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
12498 OMP_PARALLEL_CLAUSES (*data[1]) = c;
12503 switch (TREE_CODE (for_stmt))
12505 case OMP_FOR:
12506 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt))
12508 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
12509 OMP_CLAUSE_SCHEDULE))
12510 error_at (EXPR_LOCATION (for_stmt),
12511 "%qs clause may not appear on non-rectangular %qs",
12512 "schedule", lang_GNU_Fortran () ? "do" : "for");
12513 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED))
12514 error_at (EXPR_LOCATION (for_stmt),
12515 "%qs clause may not appear on non-rectangular %qs",
12516 "ordered", lang_GNU_Fortran () ? "do" : "for");
12518 break;
12519 case OMP_DISTRIBUTE:
12520 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt)
12521 && omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
12522 OMP_CLAUSE_DIST_SCHEDULE))
12523 error_at (EXPR_LOCATION (for_stmt),
12524 "%qs clause may not appear on non-rectangular %qs",
12525 "dist_schedule", "distribute");
12526 break;
12527 case OACC_LOOP:
12528 ort = ORT_ACC;
12529 break;
12530 case OMP_TASKLOOP:
12531 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt))
12533 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
12534 OMP_CLAUSE_GRAINSIZE))
12535 error_at (EXPR_LOCATION (for_stmt),
12536 "%qs clause may not appear on non-rectangular %qs",
12537 "grainsize", "taskloop");
12538 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
12539 OMP_CLAUSE_NUM_TASKS))
12540 error_at (EXPR_LOCATION (for_stmt),
12541 "%qs clause may not appear on non-rectangular %qs",
12542 "num_tasks", "taskloop");
12544 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_UNTIED))
12545 ort = ORT_UNTIED_TASKLOOP;
12546 else
12547 ort = ORT_TASKLOOP;
12548 break;
12549 case OMP_SIMD:
12550 ort = ORT_SIMD;
12551 break;
12552 default:
12553 gcc_unreachable ();
12556 /* Set OMP_CLAUSE_LINEAR_NO_COPYIN flag on explicit linear
12557 clause for the IV. */
12558 if (ort == ORT_SIMD && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
12560 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), 0);
12561 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
12562 decl = TREE_OPERAND (t, 0);
12563 for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
12564 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
12565 && OMP_CLAUSE_DECL (c) == decl)
12567 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
12568 break;
12572 if (TREE_CODE (for_stmt) != OMP_TASKLOOP)
12573 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p, ort,
12574 loop_p && TREE_CODE (for_stmt) != OMP_SIMD
12575 ? OMP_LOOP : TREE_CODE (for_stmt));
12577 if (TREE_CODE (for_stmt) == OMP_DISTRIBUTE)
12578 gimplify_omp_ctxp->distribute = true;
12580 /* Handle OMP_FOR_INIT. */
12581 for_pre_body = NULL;
12582 if ((ort == ORT_SIMD
12583 || (inner_for_stmt && TREE_CODE (inner_for_stmt) == OMP_SIMD))
12584 && OMP_FOR_PRE_BODY (for_stmt))
12586 has_decl_expr = BITMAP_ALLOC (NULL);
12587 if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == DECL_EXPR
12588 && TREE_CODE (DECL_EXPR_DECL (OMP_FOR_PRE_BODY (for_stmt)))
12589 == VAR_DECL)
12591 t = OMP_FOR_PRE_BODY (for_stmt);
12592 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
12594 else if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == STATEMENT_LIST)
12596 tree_stmt_iterator si;
12597 for (si = tsi_start (OMP_FOR_PRE_BODY (for_stmt)); !tsi_end_p (si);
12598 tsi_next (&si))
12600 t = tsi_stmt (si);
12601 if (TREE_CODE (t) == DECL_EXPR
12602 && TREE_CODE (DECL_EXPR_DECL (t)) == VAR_DECL)
12603 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
12607 if (OMP_FOR_PRE_BODY (for_stmt))
12609 if (TREE_CODE (for_stmt) != OMP_TASKLOOP || gimplify_omp_ctxp)
12610 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
12611 else
12613 struct gimplify_omp_ctx ctx;
12614 memset (&ctx, 0, sizeof (ctx));
12615 ctx.region_type = ORT_NONE;
12616 gimplify_omp_ctxp = &ctx;
12617 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
12618 gimplify_omp_ctxp = NULL;
12621 OMP_FOR_PRE_BODY (for_stmt) = NULL_TREE;
12623 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
12624 for_stmt = inner_for_stmt;
12626 /* For taskloop, need to gimplify the start, end and step before the
12627 taskloop, outside of the taskloop omp context. */
12628 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
12630 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
12632 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
12633 gimple_seq *for_pre_p = (gimple_seq_empty_p (for_pre_body)
12634 ? pre_p : &for_pre_body);
12635 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
12636 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
12638 tree v = TREE_OPERAND (t, 1);
12639 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 1),
12640 for_pre_p, orig_for_stmt);
12641 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 2),
12642 for_pre_p, orig_for_stmt);
12644 else
12645 gimplify_omp_taskloop_expr (type, &TREE_OPERAND (t, 1), for_pre_p,
12646 orig_for_stmt);
12648 /* Handle OMP_FOR_COND. */
12649 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
12650 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
12652 tree v = TREE_OPERAND (t, 1);
12653 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 1),
12654 for_pre_p, orig_for_stmt);
12655 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 2),
12656 for_pre_p, orig_for_stmt);
12658 else
12659 gimplify_omp_taskloop_expr (type, &TREE_OPERAND (t, 1), for_pre_p,
12660 orig_for_stmt);
12662 /* Handle OMP_FOR_INCR. */
12663 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
12664 if (TREE_CODE (t) == MODIFY_EXPR)
12666 decl = TREE_OPERAND (t, 0);
12667 t = TREE_OPERAND (t, 1);
12668 tree *tp = &TREE_OPERAND (t, 1);
12669 if (TREE_CODE (t) == PLUS_EXPR && *tp == decl)
12670 tp = &TREE_OPERAND (t, 0);
12672 gimplify_omp_taskloop_expr (NULL_TREE, tp, for_pre_p,
12673 orig_for_stmt);
12677 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (orig_for_stmt), pre_p, ort,
12678 OMP_TASKLOOP);
12681 if (orig_for_stmt != for_stmt)
12682 gimplify_omp_ctxp->combined_loop = true;
12684 for_body = NULL;
12685 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
12686 == TREE_VEC_LENGTH (OMP_FOR_COND (for_stmt)));
12687 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
12688 == TREE_VEC_LENGTH (OMP_FOR_INCR (for_stmt)));
12690 tree c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED);
12691 bool is_doacross = false;
12692 if (c && OMP_CLAUSE_ORDERED_EXPR (c))
12694 is_doacross = true;
12695 gimplify_omp_ctxp->loop_iter_var.create (TREE_VEC_LENGTH
12696 (OMP_FOR_INIT (for_stmt))
12697 * 2);
12699 int collapse = 1, tile = 0;
12700 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_COLLAPSE);
12701 if (c)
12702 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (c));
12703 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_TILE);
12704 if (c)
12705 tile = list_length (OMP_CLAUSE_TILE_LIST (c));
12706 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ALLOCATE);
12707 hash_set<tree> *allocate_uids = NULL;
12708 if (c)
12710 allocate_uids = new hash_set<tree>;
12711 for (; c; c = OMP_CLAUSE_CHAIN (c))
12712 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ALLOCATE)
12713 allocate_uids->add (OMP_CLAUSE_DECL (c));
12715 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
12717 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
12718 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
12719 decl = TREE_OPERAND (t, 0);
12720 gcc_assert (DECL_P (decl));
12721 gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl))
12722 || POINTER_TYPE_P (TREE_TYPE (decl)));
12723 if (is_doacross)
12725 if (TREE_CODE (for_stmt) == OMP_FOR && OMP_FOR_ORIG_DECLS (for_stmt))
12727 tree orig_decl = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
12728 if (TREE_CODE (orig_decl) == TREE_LIST)
12730 orig_decl = TREE_PURPOSE (orig_decl);
12731 if (!orig_decl)
12732 orig_decl = decl;
12734 gimplify_omp_ctxp->loop_iter_var.quick_push (orig_decl);
12736 else
12737 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
12738 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
12741 if (for_stmt == orig_for_stmt)
12743 tree orig_decl = decl;
12744 if (OMP_FOR_ORIG_DECLS (for_stmt))
12746 tree orig_decl = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
12747 if (TREE_CODE (orig_decl) == TREE_LIST)
12749 orig_decl = TREE_PURPOSE (orig_decl);
12750 if (!orig_decl)
12751 orig_decl = decl;
12754 if (is_global_var (orig_decl) && DECL_THREAD_LOCAL_P (orig_decl))
12755 error_at (EXPR_LOCATION (for_stmt),
12756 "threadprivate iteration variable %qD", orig_decl);
12759 /* Make sure the iteration variable is private. */
12760 tree c = NULL_TREE;
12761 tree c2 = NULL_TREE;
12762 if (orig_for_stmt != for_stmt)
12764 /* Preserve this information until we gimplify the inner simd. */
12765 if (has_decl_expr
12766 && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
12767 TREE_PRIVATE (t) = 1;
12769 else if (ort == ORT_SIMD)
12771 splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
12772 (splay_tree_key) decl);
12773 omp_is_private (gimplify_omp_ctxp, decl,
12774 1 + (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
12775 != 1));
12776 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
12778 omp_notice_variable (gimplify_omp_ctxp, decl, true);
12779 if (n->value & GOVD_LASTPRIVATE_CONDITIONAL)
12780 for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
12781 OMP_CLAUSE_LASTPRIVATE);
12782 c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
12783 OMP_CLAUSE_LASTPRIVATE))
12784 if (OMP_CLAUSE_DECL (c3) == decl)
12786 warning_at (OMP_CLAUSE_LOCATION (c3), 0,
12787 "conditional %<lastprivate%> on loop "
12788 "iterator %qD ignored", decl);
12789 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
12790 n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
12793 else if (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1 && !loop_p)
12795 c = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
12796 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
12797 unsigned int flags = GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN;
12798 if ((has_decl_expr
12799 && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
12800 || TREE_PRIVATE (t))
12802 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
12803 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
12805 struct gimplify_omp_ctx *outer
12806 = gimplify_omp_ctxp->outer_context;
12807 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
12809 if (outer->region_type == ORT_WORKSHARE
12810 && outer->combined_loop)
12812 n = splay_tree_lookup (outer->variables,
12813 (splay_tree_key)decl);
12814 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
12816 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
12817 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
12819 else
12821 struct gimplify_omp_ctx *octx = outer->outer_context;
12822 if (octx
12823 && octx->region_type == ORT_COMBINED_PARALLEL
12824 && octx->outer_context
12825 && (octx->outer_context->region_type
12826 == ORT_WORKSHARE)
12827 && octx->outer_context->combined_loop)
12829 octx = octx->outer_context;
12830 n = splay_tree_lookup (octx->variables,
12831 (splay_tree_key)decl);
12832 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
12834 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
12835 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
12842 OMP_CLAUSE_DECL (c) = decl;
12843 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
12844 OMP_FOR_CLAUSES (for_stmt) = c;
12845 omp_add_variable (gimplify_omp_ctxp, decl, flags);
12846 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
12847 omp_lastprivate_for_combined_outer_constructs (outer, decl,
12848 true);
12850 else
12852 bool lastprivate
12853 = (!has_decl_expr
12854 || !bitmap_bit_p (has_decl_expr, DECL_UID (decl)));
12855 if (TREE_PRIVATE (t))
12856 lastprivate = false;
12857 if (loop_p && OMP_FOR_ORIG_DECLS (for_stmt))
12859 tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
12860 if (TREE_CODE (elt) == TREE_LIST && TREE_PURPOSE (elt))
12861 lastprivate = false;
12864 struct gimplify_omp_ctx *outer
12865 = gimplify_omp_ctxp->outer_context;
12866 if (outer && lastprivate)
12867 omp_lastprivate_for_combined_outer_constructs (outer, decl,
12868 true);
12870 c = build_omp_clause (input_location,
12871 lastprivate ? OMP_CLAUSE_LASTPRIVATE
12872 : OMP_CLAUSE_PRIVATE);
12873 OMP_CLAUSE_DECL (c) = decl;
12874 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
12875 OMP_FOR_CLAUSES (for_stmt) = c;
12876 omp_add_variable (gimplify_omp_ctxp, decl,
12877 (lastprivate ? GOVD_LASTPRIVATE : GOVD_PRIVATE)
12878 | GOVD_EXPLICIT | GOVD_SEEN);
12879 c = NULL_TREE;
12882 else if (omp_is_private (gimplify_omp_ctxp, decl, 0))
12884 omp_notice_variable (gimplify_omp_ctxp, decl, true);
12885 splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
12886 (splay_tree_key) decl);
12887 if (n && (n->value & GOVD_LASTPRIVATE_CONDITIONAL))
12888 for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
12889 OMP_CLAUSE_LASTPRIVATE);
12890 c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
12891 OMP_CLAUSE_LASTPRIVATE))
12892 if (OMP_CLAUSE_DECL (c3) == decl)
12894 warning_at (OMP_CLAUSE_LOCATION (c3), 0,
12895 "conditional %<lastprivate%> on loop "
12896 "iterator %qD ignored", decl);
12897 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
12898 n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
12901 else
12902 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN);
12904 /* If DECL is not a gimple register, create a temporary variable to act
12905 as an iteration counter. This is valid, since DECL cannot be
12906 modified in the body of the loop. Similarly for any iteration vars
12907 in simd with collapse > 1 where the iterator vars must be
12908 lastprivate. And similarly for vars mentioned in allocate clauses. */
12909 if (orig_for_stmt != for_stmt)
12910 var = decl;
12911 else if (!is_gimple_reg (decl)
12912 || (ort == ORT_SIMD
12913 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) > 1)
12914 || (allocate_uids && allocate_uids->contains (decl)))
12916 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
12917 /* Make sure omp_add_variable is not called on it prematurely.
12918 We call it ourselves a few lines later. */
12919 gimplify_omp_ctxp = NULL;
12920 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
12921 gimplify_omp_ctxp = ctx;
12922 TREE_OPERAND (t, 0) = var;
12924 gimplify_seq_add_stmt (&for_body, gimple_build_assign (decl, var));
12926 if (ort == ORT_SIMD
12927 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
12929 c2 = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
12930 OMP_CLAUSE_LINEAR_NO_COPYIN (c2) = 1;
12931 OMP_CLAUSE_LINEAR_NO_COPYOUT (c2) = 1;
12932 OMP_CLAUSE_DECL (c2) = var;
12933 OMP_CLAUSE_CHAIN (c2) = OMP_FOR_CLAUSES (for_stmt);
12934 OMP_FOR_CLAUSES (for_stmt) = c2;
12935 omp_add_variable (gimplify_omp_ctxp, var,
12936 GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN);
12937 if (c == NULL_TREE)
12939 c = c2;
12940 c2 = NULL_TREE;
12943 else
12944 omp_add_variable (gimplify_omp_ctxp, var,
12945 GOVD_PRIVATE | GOVD_SEEN);
12947 else
12948 var = decl;
12950 gimplify_omp_ctxp->in_for_exprs = true;
12951 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
12953 tree lb = TREE_OPERAND (t, 1);
12954 tret = gimplify_expr (&TREE_VEC_ELT (lb, 1), &for_pre_body, NULL,
12955 is_gimple_val, fb_rvalue, false);
12956 ret = MIN (ret, tret);
12957 tret = gimplify_expr (&TREE_VEC_ELT (lb, 2), &for_pre_body, NULL,
12958 is_gimple_val, fb_rvalue, false);
12960 else
12961 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
12962 is_gimple_val, fb_rvalue, false);
12963 gimplify_omp_ctxp->in_for_exprs = false;
12964 ret = MIN (ret, tret);
12965 if (ret == GS_ERROR)
12966 return ret;
12968 /* Handle OMP_FOR_COND. */
12969 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
12970 gcc_assert (COMPARISON_CLASS_P (t));
12971 gcc_assert (TREE_OPERAND (t, 0) == decl);
12973 gimplify_omp_ctxp->in_for_exprs = true;
12974 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
12976 tree ub = TREE_OPERAND (t, 1);
12977 tret = gimplify_expr (&TREE_VEC_ELT (ub, 1), &for_pre_body, NULL,
12978 is_gimple_val, fb_rvalue, false);
12979 ret = MIN (ret, tret);
12980 tret = gimplify_expr (&TREE_VEC_ELT (ub, 2), &for_pre_body, NULL,
12981 is_gimple_val, fb_rvalue, false);
12983 else
12984 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
12985 is_gimple_val, fb_rvalue, false);
12986 gimplify_omp_ctxp->in_for_exprs = false;
12987 ret = MIN (ret, tret);
12989 /* Handle OMP_FOR_INCR. */
12990 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
12991 switch (TREE_CODE (t))
12993 case PREINCREMENT_EXPR:
12994 case POSTINCREMENT_EXPR:
12996 tree decl = TREE_OPERAND (t, 0);
12997 /* c_omp_for_incr_canonicalize_ptr() should have been
12998 called to massage things appropriately. */
12999 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
13001 if (orig_for_stmt != for_stmt)
13002 break;
13003 t = build_int_cst (TREE_TYPE (decl), 1);
13004 if (c)
13005 OMP_CLAUSE_LINEAR_STEP (c) = t;
13006 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
13007 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
13008 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
13009 break;
13012 case PREDECREMENT_EXPR:
13013 case POSTDECREMENT_EXPR:
13014 /* c_omp_for_incr_canonicalize_ptr() should have been
13015 called to massage things appropriately. */
13016 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
13017 if (orig_for_stmt != for_stmt)
13018 break;
13019 t = build_int_cst (TREE_TYPE (decl), -1);
13020 if (c)
13021 OMP_CLAUSE_LINEAR_STEP (c) = t;
13022 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
13023 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
13024 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
13025 break;
13027 case MODIFY_EXPR:
13028 gcc_assert (TREE_OPERAND (t, 0) == decl);
13029 TREE_OPERAND (t, 0) = var;
13031 t = TREE_OPERAND (t, 1);
13032 switch (TREE_CODE (t))
13034 case PLUS_EXPR:
13035 if (TREE_OPERAND (t, 1) == decl)
13037 TREE_OPERAND (t, 1) = TREE_OPERAND (t, 0);
13038 TREE_OPERAND (t, 0) = var;
13039 break;
13042 /* Fallthru. */
13043 case MINUS_EXPR:
13044 case POINTER_PLUS_EXPR:
13045 gcc_assert (TREE_OPERAND (t, 0) == decl);
13046 TREE_OPERAND (t, 0) = var;
13047 break;
13048 default:
13049 gcc_unreachable ();
13052 gimplify_omp_ctxp->in_for_exprs = true;
13053 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
13054 is_gimple_val, fb_rvalue, false);
13055 ret = MIN (ret, tret);
13056 if (c)
13058 tree step = TREE_OPERAND (t, 1);
13059 tree stept = TREE_TYPE (decl);
13060 if (POINTER_TYPE_P (stept))
13061 stept = sizetype;
13062 step = fold_convert (stept, step);
13063 if (TREE_CODE (t) == MINUS_EXPR)
13064 step = fold_build1 (NEGATE_EXPR, stept, step);
13065 OMP_CLAUSE_LINEAR_STEP (c) = step;
13066 if (step != TREE_OPERAND (t, 1))
13068 tret = gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c),
13069 &for_pre_body, NULL,
13070 is_gimple_val, fb_rvalue, false);
13071 ret = MIN (ret, tret);
13074 gimplify_omp_ctxp->in_for_exprs = false;
13075 break;
13077 default:
13078 gcc_unreachable ();
13081 if (c2)
13083 gcc_assert (c);
13084 OMP_CLAUSE_LINEAR_STEP (c2) = OMP_CLAUSE_LINEAR_STEP (c);
13087 if ((var != decl || collapse > 1 || tile) && orig_for_stmt == for_stmt)
13089 for (c = OMP_FOR_CLAUSES (for_stmt); c ; c = OMP_CLAUSE_CHAIN (c))
13090 if (((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
13091 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) == NULL)
13092 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
13093 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)
13094 && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c) == NULL))
13095 && OMP_CLAUSE_DECL (c) == decl)
13097 if (is_doacross && (collapse == 1 || i >= collapse))
13098 t = var;
13099 else
13101 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
13102 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
13103 gcc_assert (TREE_OPERAND (t, 0) == var);
13104 t = TREE_OPERAND (t, 1);
13105 gcc_assert (TREE_CODE (t) == PLUS_EXPR
13106 || TREE_CODE (t) == MINUS_EXPR
13107 || TREE_CODE (t) == POINTER_PLUS_EXPR);
13108 gcc_assert (TREE_OPERAND (t, 0) == var);
13109 t = build2 (TREE_CODE (t), TREE_TYPE (decl),
13110 is_doacross ? var : decl,
13111 TREE_OPERAND (t, 1));
13113 gimple_seq *seq;
13114 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
13115 seq = &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c);
13116 else
13117 seq = &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c);
13118 push_gimplify_context ();
13119 gimplify_assign (decl, t, seq);
13120 gimple *bind = NULL;
13121 if (gimplify_ctxp->temps)
13123 bind = gimple_build_bind (NULL_TREE, *seq, NULL_TREE);
13124 *seq = NULL;
13125 gimplify_seq_add_stmt (seq, bind);
13127 pop_gimplify_context (bind);
13130 if (OMP_FOR_NON_RECTANGULAR (for_stmt) && var != decl)
13131 for (int j = i + 1; j < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); j++)
13133 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), j);
13134 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
13135 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
13136 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
13137 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
13138 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), j);
13139 gcc_assert (COMPARISON_CLASS_P (t));
13140 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
13141 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
13142 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
13146 BITMAP_FREE (has_decl_expr);
13147 delete allocate_uids;
13149 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP
13150 || (loop_p && orig_for_stmt == for_stmt))
13152 push_gimplify_context ();
13153 if (TREE_CODE (OMP_FOR_BODY (orig_for_stmt)) != BIND_EXPR)
13155 OMP_FOR_BODY (orig_for_stmt)
13156 = build3 (BIND_EXPR, void_type_node, NULL,
13157 OMP_FOR_BODY (orig_for_stmt), NULL);
13158 TREE_SIDE_EFFECTS (OMP_FOR_BODY (orig_for_stmt)) = 1;
13162 gimple *g = gimplify_and_return_first (OMP_FOR_BODY (orig_for_stmt),
13163 &for_body);
13165 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP
13166 || (loop_p && orig_for_stmt == for_stmt))
13168 if (gimple_code (g) == GIMPLE_BIND)
13169 pop_gimplify_context (g);
13170 else
13171 pop_gimplify_context (NULL);
13174 if (orig_for_stmt != for_stmt)
13175 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
13177 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
13178 decl = TREE_OPERAND (t, 0);
13179 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
13180 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
13181 gimplify_omp_ctxp = ctx->outer_context;
13182 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
13183 gimplify_omp_ctxp = ctx;
13184 omp_add_variable (gimplify_omp_ctxp, var, GOVD_PRIVATE | GOVD_SEEN);
13185 TREE_OPERAND (t, 0) = var;
13186 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
13187 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
13188 TREE_OPERAND (TREE_OPERAND (t, 1), 0) = var;
13189 if (OMP_FOR_NON_RECTANGULAR (for_stmt))
13190 for (int j = i + 1;
13191 j < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); j++)
13193 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), j);
13194 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
13195 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
13196 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
13198 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
13199 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
13201 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), j);
13202 gcc_assert (COMPARISON_CLASS_P (t));
13203 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
13204 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
13206 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
13207 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
13212 gimplify_adjust_omp_clauses (pre_p, for_body,
13213 &OMP_FOR_CLAUSES (orig_for_stmt),
13214 TREE_CODE (orig_for_stmt));
13216 int kind;
13217 switch (TREE_CODE (orig_for_stmt))
13219 case OMP_FOR: kind = GF_OMP_FOR_KIND_FOR; break;
13220 case OMP_SIMD: kind = GF_OMP_FOR_KIND_SIMD; break;
13221 case OMP_DISTRIBUTE: kind = GF_OMP_FOR_KIND_DISTRIBUTE; break;
13222 case OMP_TASKLOOP: kind = GF_OMP_FOR_KIND_TASKLOOP; break;
13223 case OACC_LOOP: kind = GF_OMP_FOR_KIND_OACC_LOOP; break;
13224 default:
13225 gcc_unreachable ();
13227 if (loop_p && kind == GF_OMP_FOR_KIND_SIMD)
13229 gimplify_seq_add_seq (pre_p, for_pre_body);
13230 for_pre_body = NULL;
13232 gfor = gimple_build_omp_for (for_body, kind, OMP_FOR_CLAUSES (orig_for_stmt),
13233 TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)),
13234 for_pre_body);
13235 if (orig_for_stmt != for_stmt)
13236 gimple_omp_for_set_combined_p (gfor, true);
13237 if (gimplify_omp_ctxp
13238 && (gimplify_omp_ctxp->combined_loop
13239 || (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
13240 && gimplify_omp_ctxp->outer_context
13241 && gimplify_omp_ctxp->outer_context->combined_loop)))
13243 gimple_omp_for_set_combined_into_p (gfor, true);
13244 if (gimplify_omp_ctxp->combined_loop)
13245 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_SIMD);
13246 else
13247 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_FOR);
13250 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
13252 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
13253 gimple_omp_for_set_index (gfor, i, TREE_OPERAND (t, 0));
13254 gimple_omp_for_set_initial (gfor, i, TREE_OPERAND (t, 1));
13255 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
13256 gimple_omp_for_set_cond (gfor, i, TREE_CODE (t));
13257 gimple_omp_for_set_final (gfor, i, TREE_OPERAND (t, 1));
13258 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
13259 gimple_omp_for_set_incr (gfor, i, TREE_OPERAND (t, 1));
13262 /* OMP_TASKLOOP is gimplified as two GIMPLE_OMP_FOR taskloop
13263 constructs with GIMPLE_OMP_TASK sandwiched in between them.
13264 The outer taskloop stands for computing the number of iterations,
13265 counts for collapsed loops and holding taskloop specific clauses.
13266 The task construct stands for the effect of data sharing on the
13267 explicit task it creates and the inner taskloop stands for expansion
13268 of the static loop inside of the explicit task construct. */
13269 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
13271 tree *gfor_clauses_ptr = gimple_omp_for_clauses_ptr (gfor);
13272 tree task_clauses = NULL_TREE;
13273 tree c = *gfor_clauses_ptr;
13274 tree *gtask_clauses_ptr = &task_clauses;
13275 tree outer_for_clauses = NULL_TREE;
13276 tree *gforo_clauses_ptr = &outer_for_clauses;
13277 bitmap lastprivate_uids = NULL;
13278 if (omp_find_clause (c, OMP_CLAUSE_ALLOCATE))
13280 c = omp_find_clause (c, OMP_CLAUSE_LASTPRIVATE);
13281 if (c)
13283 lastprivate_uids = BITMAP_ALLOC (NULL);
13284 for (; c; c = omp_find_clause (OMP_CLAUSE_CHAIN (c),
13285 OMP_CLAUSE_LASTPRIVATE))
13286 bitmap_set_bit (lastprivate_uids,
13287 DECL_UID (OMP_CLAUSE_DECL (c)));
13289 c = *gfor_clauses_ptr;
13291 for (; c; c = OMP_CLAUSE_CHAIN (c))
13292 switch (OMP_CLAUSE_CODE (c))
13294 /* These clauses are allowed on task, move them there. */
13295 case OMP_CLAUSE_SHARED:
13296 case OMP_CLAUSE_FIRSTPRIVATE:
13297 case OMP_CLAUSE_DEFAULT:
13298 case OMP_CLAUSE_IF:
13299 case OMP_CLAUSE_UNTIED:
13300 case OMP_CLAUSE_FINAL:
13301 case OMP_CLAUSE_MERGEABLE:
13302 case OMP_CLAUSE_PRIORITY:
13303 case OMP_CLAUSE_REDUCTION:
13304 case OMP_CLAUSE_IN_REDUCTION:
13305 *gtask_clauses_ptr = c;
13306 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13307 break;
13308 case OMP_CLAUSE_PRIVATE:
13309 if (OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c))
13311 /* We want private on outer for and firstprivate
13312 on task. */
13313 *gtask_clauses_ptr
13314 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
13315 OMP_CLAUSE_FIRSTPRIVATE);
13316 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
13317 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL,
13318 openacc);
13319 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
13320 *gforo_clauses_ptr = c;
13321 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13323 else
13325 *gtask_clauses_ptr = c;
13326 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13328 break;
13329 /* These clauses go into outer taskloop clauses. */
13330 case OMP_CLAUSE_GRAINSIZE:
13331 case OMP_CLAUSE_NUM_TASKS:
13332 case OMP_CLAUSE_NOGROUP:
13333 *gforo_clauses_ptr = c;
13334 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13335 break;
13336 /* Collapse clause we duplicate on both taskloops. */
13337 case OMP_CLAUSE_COLLAPSE:
13338 *gfor_clauses_ptr = c;
13339 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13340 *gforo_clauses_ptr = copy_node (c);
13341 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
13342 break;
13343 /* For lastprivate, keep the clause on inner taskloop, and add
13344 a shared clause on task. If the same decl is also firstprivate,
13345 add also firstprivate clause on the inner taskloop. */
13346 case OMP_CLAUSE_LASTPRIVATE:
13347 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
13349 /* For taskloop C++ lastprivate IVs, we want:
13350 1) private on outer taskloop
13351 2) firstprivate and shared on task
13352 3) lastprivate on inner taskloop */
13353 *gtask_clauses_ptr
13354 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
13355 OMP_CLAUSE_FIRSTPRIVATE);
13356 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
13357 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL,
13358 openacc);
13359 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
13360 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c) = 1;
13361 *gforo_clauses_ptr = build_omp_clause (OMP_CLAUSE_LOCATION (c),
13362 OMP_CLAUSE_PRIVATE);
13363 OMP_CLAUSE_DECL (*gforo_clauses_ptr) = OMP_CLAUSE_DECL (c);
13364 OMP_CLAUSE_PRIVATE_TASKLOOP_IV (*gforo_clauses_ptr) = 1;
13365 TREE_TYPE (*gforo_clauses_ptr) = TREE_TYPE (c);
13366 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
13368 *gfor_clauses_ptr = c;
13369 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13370 *gtask_clauses_ptr
13371 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_SHARED);
13372 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
13373 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
13374 OMP_CLAUSE_SHARED_FIRSTPRIVATE (*gtask_clauses_ptr) = 1;
13375 gtask_clauses_ptr
13376 = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
13377 break;
13378 /* Allocate clause we duplicate on task and inner taskloop
13379 if the decl is lastprivate, otherwise just put on task. */
13380 case OMP_CLAUSE_ALLOCATE:
13381 if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
13382 && DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)))
13384 /* Additionally, put firstprivate clause on task
13385 for the allocator if it is not constant. */
13386 *gtask_clauses_ptr
13387 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
13388 OMP_CLAUSE_FIRSTPRIVATE);
13389 OMP_CLAUSE_DECL (*gtask_clauses_ptr)
13390 = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
13391 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
13393 if (lastprivate_uids
13394 && bitmap_bit_p (lastprivate_uids,
13395 DECL_UID (OMP_CLAUSE_DECL (c))))
13397 *gfor_clauses_ptr = c;
13398 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13399 *gtask_clauses_ptr = copy_node (c);
13400 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
13402 else
13404 *gtask_clauses_ptr = c;
13405 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13407 break;
13408 default:
13409 gcc_unreachable ();
13411 *gfor_clauses_ptr = NULL_TREE;
13412 *gtask_clauses_ptr = NULL_TREE;
13413 *gforo_clauses_ptr = NULL_TREE;
13414 BITMAP_FREE (lastprivate_uids);
13415 gimple_set_location (gfor, input_location);
13416 g = gimple_build_bind (NULL_TREE, gfor, NULL_TREE);
13417 g = gimple_build_omp_task (g, task_clauses, NULL_TREE, NULL_TREE,
13418 NULL_TREE, NULL_TREE, NULL_TREE);
13419 gimple_set_location (g, input_location);
13420 gimple_omp_task_set_taskloop_p (g, true);
13421 g = gimple_build_bind (NULL_TREE, g, NULL_TREE);
13422 gomp_for *gforo
13423 = gimple_build_omp_for (g, GF_OMP_FOR_KIND_TASKLOOP, outer_for_clauses,
13424 gimple_omp_for_collapse (gfor),
13425 gimple_omp_for_pre_body (gfor));
13426 gimple_omp_for_set_pre_body (gfor, NULL);
13427 gimple_omp_for_set_combined_p (gforo, true);
13428 gimple_omp_for_set_combined_into_p (gfor, true);
13429 for (i = 0; i < (int) gimple_omp_for_collapse (gfor); i++)
13431 tree type = TREE_TYPE (gimple_omp_for_index (gfor, i));
13432 tree v = create_tmp_var (type);
13433 gimple_omp_for_set_index (gforo, i, v);
13434 t = unshare_expr (gimple_omp_for_initial (gfor, i));
13435 gimple_omp_for_set_initial (gforo, i, t);
13436 gimple_omp_for_set_cond (gforo, i,
13437 gimple_omp_for_cond (gfor, i));
13438 t = unshare_expr (gimple_omp_for_final (gfor, i));
13439 gimple_omp_for_set_final (gforo, i, t);
13440 t = unshare_expr (gimple_omp_for_incr (gfor, i));
13441 gcc_assert (TREE_OPERAND (t, 0) == gimple_omp_for_index (gfor, i));
13442 TREE_OPERAND (t, 0) = v;
13443 gimple_omp_for_set_incr (gforo, i, t);
13444 t = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
13445 OMP_CLAUSE_DECL (t) = v;
13446 OMP_CLAUSE_CHAIN (t) = gimple_omp_for_clauses (gforo);
13447 gimple_omp_for_set_clauses (gforo, t);
13448 if (OMP_FOR_NON_RECTANGULAR (for_stmt))
13450 tree *p1 = NULL, *p2 = NULL;
13451 t = gimple_omp_for_initial (gforo, i);
13452 if (TREE_CODE (t) == TREE_VEC)
13453 p1 = &TREE_VEC_ELT (t, 0);
13454 t = gimple_omp_for_final (gforo, i);
13455 if (TREE_CODE (t) == TREE_VEC)
13457 if (p1)
13458 p2 = &TREE_VEC_ELT (t, 0);
13459 else
13460 p1 = &TREE_VEC_ELT (t, 0);
13462 if (p1)
13464 int j;
13465 for (j = 0; j < i; j++)
13466 if (*p1 == gimple_omp_for_index (gfor, j))
13468 *p1 = gimple_omp_for_index (gforo, j);
13469 if (p2)
13470 *p2 = *p1;
13471 break;
13473 gcc_assert (j < i);
13477 gimplify_seq_add_stmt (pre_p, gforo);
13479 else
13480 gimplify_seq_add_stmt (pre_p, gfor);
13482 if (TREE_CODE (orig_for_stmt) == OMP_FOR)
13484 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
13485 unsigned lastprivate_conditional = 0;
13486 while (ctx
13487 && (ctx->region_type == ORT_TARGET_DATA
13488 || ctx->region_type == ORT_TASKGROUP))
13489 ctx = ctx->outer_context;
13490 if (ctx && (ctx->region_type & ORT_PARALLEL) != 0)
13491 for (tree c = gimple_omp_for_clauses (gfor);
13492 c; c = OMP_CLAUSE_CHAIN (c))
13493 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
13494 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
13495 ++lastprivate_conditional;
13496 if (lastprivate_conditional)
13498 struct omp_for_data fd;
13499 omp_extract_for_data (gfor, &fd, NULL);
13500 tree type = build_array_type_nelts (unsigned_type_for (fd.iter_type),
13501 lastprivate_conditional);
13502 tree var = create_tmp_var_raw (type);
13503 tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__CONDTEMP_);
13504 OMP_CLAUSE_DECL (c) = var;
13505 OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor);
13506 gimple_omp_for_set_clauses (gfor, c);
13507 omp_add_variable (ctx, var, GOVD_CONDTEMP | GOVD_SEEN);
13510 else if (TREE_CODE (orig_for_stmt) == OMP_SIMD)
13512 unsigned lastprivate_conditional = 0;
13513 for (tree c = gimple_omp_for_clauses (gfor); c; c = OMP_CLAUSE_CHAIN (c))
13514 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
13515 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
13516 ++lastprivate_conditional;
13517 if (lastprivate_conditional)
13519 struct omp_for_data fd;
13520 omp_extract_for_data (gfor, &fd, NULL);
13521 tree type = unsigned_type_for (fd.iter_type);
13522 while (lastprivate_conditional--)
13524 tree c = build_omp_clause (UNKNOWN_LOCATION,
13525 OMP_CLAUSE__CONDTEMP_);
13526 OMP_CLAUSE_DECL (c) = create_tmp_var (type);
13527 OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor);
13528 gimple_omp_for_set_clauses (gfor, c);
13533 if (ret != GS_ALL_DONE)
13534 return GS_ERROR;
13535 *expr_p = NULL_TREE;
13536 return GS_ALL_DONE;
13539 /* Helper for gimplify_omp_loop, called through walk_tree. */
13541 static tree
13542 note_no_context_vars (tree *tp, int *, void *data)
13544 if (VAR_P (*tp)
13545 && DECL_CONTEXT (*tp) == NULL_TREE
13546 && !is_global_var (*tp))
13548 vec<tree> *d = (vec<tree> *) data;
13549 d->safe_push (*tp);
13550 DECL_CONTEXT (*tp) = current_function_decl;
13552 return NULL_TREE;
13555 /* Gimplify the gross structure of an OMP_LOOP statement. */
13557 static enum gimplify_status
13558 gimplify_omp_loop (tree *expr_p, gimple_seq *pre_p)
13560 tree for_stmt = *expr_p;
13561 tree clauses = OMP_FOR_CLAUSES (for_stmt);
13562 struct gimplify_omp_ctx *octx = gimplify_omp_ctxp;
13563 enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
13564 int i;
13566 /* If order is not present, the behavior is as if order(concurrent)
13567 appeared. */
13568 tree order = omp_find_clause (clauses, OMP_CLAUSE_ORDER);
13569 if (order == NULL_TREE)
13571 order = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_ORDER);
13572 OMP_CLAUSE_CHAIN (order) = clauses;
13573 OMP_FOR_CLAUSES (for_stmt) = clauses = order;
13576 tree bind = omp_find_clause (clauses, OMP_CLAUSE_BIND);
13577 if (bind == NULL_TREE)
13579 if (!flag_openmp) /* flag_openmp_simd */
13581 else if (octx && (octx->region_type & ORT_TEAMS) != 0)
13582 kind = OMP_CLAUSE_BIND_TEAMS;
13583 else if (octx && (octx->region_type & ORT_PARALLEL) != 0)
13584 kind = OMP_CLAUSE_BIND_PARALLEL;
13585 else
13587 for (; octx; octx = octx->outer_context)
13589 if ((octx->region_type & ORT_ACC) != 0
13590 || octx->region_type == ORT_NONE
13591 || octx->region_type == ORT_IMPLICIT_TARGET)
13592 continue;
13593 break;
13595 if (octx == NULL && !in_omp_construct)
13596 error_at (EXPR_LOCATION (for_stmt),
13597 "%<bind%> clause not specified on a %<loop%> "
13598 "construct not nested inside another OpenMP construct");
13600 bind = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_BIND);
13601 OMP_CLAUSE_CHAIN (bind) = clauses;
13602 OMP_CLAUSE_BIND_KIND (bind) = kind;
13603 OMP_FOR_CLAUSES (for_stmt) = bind;
13605 else
13606 switch (OMP_CLAUSE_BIND_KIND (bind))
13608 case OMP_CLAUSE_BIND_THREAD:
13609 break;
13610 case OMP_CLAUSE_BIND_PARALLEL:
13611 if (!flag_openmp) /* flag_openmp_simd */
13613 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
13614 break;
13616 for (; octx; octx = octx->outer_context)
13617 if (octx->region_type == ORT_SIMD
13618 && omp_find_clause (octx->clauses, OMP_CLAUSE_BIND) == NULL_TREE)
13620 error_at (EXPR_LOCATION (for_stmt),
13621 "%<bind(parallel)%> on a %<loop%> construct nested "
13622 "inside %<simd%> construct");
13623 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
13624 break;
13626 kind = OMP_CLAUSE_BIND_PARALLEL;
13627 break;
13628 case OMP_CLAUSE_BIND_TEAMS:
13629 if (!flag_openmp) /* flag_openmp_simd */
13631 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
13632 break;
13634 if ((octx
13635 && octx->region_type != ORT_IMPLICIT_TARGET
13636 && octx->region_type != ORT_NONE
13637 && (octx->region_type & ORT_TEAMS) == 0)
13638 || in_omp_construct)
13640 error_at (EXPR_LOCATION (for_stmt),
13641 "%<bind(teams)%> on a %<loop%> region not strictly "
13642 "nested inside of a %<teams%> region");
13643 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
13644 break;
13646 kind = OMP_CLAUSE_BIND_TEAMS;
13647 break;
13648 default:
13649 gcc_unreachable ();
13652 for (tree *pc = &OMP_FOR_CLAUSES (for_stmt); *pc; )
13653 switch (OMP_CLAUSE_CODE (*pc))
13655 case OMP_CLAUSE_REDUCTION:
13656 if (OMP_CLAUSE_REDUCTION_INSCAN (*pc))
13658 error_at (OMP_CLAUSE_LOCATION (*pc),
13659 "%<inscan%> %<reduction%> clause on "
13660 "%qs construct", "loop");
13661 OMP_CLAUSE_REDUCTION_INSCAN (*pc) = 0;
13663 if (OMP_CLAUSE_REDUCTION_TASK (*pc))
13665 error_at (OMP_CLAUSE_LOCATION (*pc),
13666 "invalid %<task%> reduction modifier on construct "
13667 "other than %<parallel%>, %qs or %<sections%>",
13668 lang_GNU_Fortran () ? "do" : "for");
13669 OMP_CLAUSE_REDUCTION_TASK (*pc) = 0;
13671 pc = &OMP_CLAUSE_CHAIN (*pc);
13672 break;
13673 case OMP_CLAUSE_LASTPRIVATE:
13674 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
13676 tree t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
13677 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
13678 if (OMP_CLAUSE_DECL (*pc) == TREE_OPERAND (t, 0))
13679 break;
13680 if (OMP_FOR_ORIG_DECLS (for_stmt)
13681 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt),
13682 i)) == TREE_LIST
13683 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt),
13684 i)))
13686 tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
13687 if (OMP_CLAUSE_DECL (*pc) == TREE_PURPOSE (orig))
13688 break;
13691 if (i == TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)))
13693 error_at (OMP_CLAUSE_LOCATION (*pc),
13694 "%<lastprivate%> clause on a %<loop%> construct refers "
13695 "to a variable %qD which is not the loop iterator",
13696 OMP_CLAUSE_DECL (*pc));
13697 *pc = OMP_CLAUSE_CHAIN (*pc);
13698 break;
13700 pc = &OMP_CLAUSE_CHAIN (*pc);
13701 break;
13702 default:
13703 pc = &OMP_CLAUSE_CHAIN (*pc);
13704 break;
13707 TREE_SET_CODE (for_stmt, OMP_SIMD);
13709 int last;
13710 switch (kind)
13712 case OMP_CLAUSE_BIND_THREAD: last = 0; break;
13713 case OMP_CLAUSE_BIND_PARALLEL: last = 1; break;
13714 case OMP_CLAUSE_BIND_TEAMS: last = 2; break;
13716 for (int pass = 1; pass <= last; pass++)
13718 if (pass == 2)
13720 tree bind = build3 (BIND_EXPR, void_type_node, NULL, NULL,
13721 make_node (BLOCK));
13722 append_to_statement_list (*expr_p, &BIND_EXPR_BODY (bind));
13723 *expr_p = make_node (OMP_PARALLEL);
13724 TREE_TYPE (*expr_p) = void_type_node;
13725 OMP_PARALLEL_BODY (*expr_p) = bind;
13726 OMP_PARALLEL_COMBINED (*expr_p) = 1;
13727 SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (for_stmt));
13728 tree *pc = &OMP_PARALLEL_CLAUSES (*expr_p);
13729 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
13730 if (OMP_FOR_ORIG_DECLS (for_stmt)
13731 && (TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i))
13732 == TREE_LIST))
13734 tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
13735 if (TREE_PURPOSE (elt) && TREE_VALUE (elt))
13737 *pc = build_omp_clause (UNKNOWN_LOCATION,
13738 OMP_CLAUSE_FIRSTPRIVATE);
13739 OMP_CLAUSE_DECL (*pc) = TREE_VALUE (elt);
13740 pc = &OMP_CLAUSE_CHAIN (*pc);
13744 tree t = make_node (pass == 2 ? OMP_DISTRIBUTE : OMP_FOR);
13745 tree *pc = &OMP_FOR_CLAUSES (t);
13746 TREE_TYPE (t) = void_type_node;
13747 OMP_FOR_BODY (t) = *expr_p;
13748 SET_EXPR_LOCATION (t, EXPR_LOCATION (for_stmt));
13749 for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
13750 switch (OMP_CLAUSE_CODE (c))
13752 case OMP_CLAUSE_BIND:
13753 case OMP_CLAUSE_ORDER:
13754 case OMP_CLAUSE_COLLAPSE:
13755 *pc = copy_node (c);
13756 pc = &OMP_CLAUSE_CHAIN (*pc);
13757 break;
13758 case OMP_CLAUSE_PRIVATE:
13759 case OMP_CLAUSE_FIRSTPRIVATE:
13760 /* Only needed on innermost. */
13761 break;
13762 case OMP_CLAUSE_LASTPRIVATE:
13763 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c) && pass != last)
13765 *pc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
13766 OMP_CLAUSE_FIRSTPRIVATE);
13767 OMP_CLAUSE_DECL (*pc) = OMP_CLAUSE_DECL (c);
13768 lang_hooks.decls.omp_finish_clause (*pc, NULL, false);
13769 pc = &OMP_CLAUSE_CHAIN (*pc);
13771 *pc = copy_node (c);
13772 OMP_CLAUSE_LASTPRIVATE_STMT (*pc) = NULL_TREE;
13773 TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
13774 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
13776 if (pass != last)
13777 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (*pc) = 1;
13778 else
13779 lang_hooks.decls.omp_finish_clause (*pc, NULL, false);
13780 OMP_CLAUSE_LASTPRIVATE_LOOP_IV (*pc) = 0;
13782 pc = &OMP_CLAUSE_CHAIN (*pc);
13783 break;
13784 case OMP_CLAUSE_REDUCTION:
13785 *pc = copy_node (c);
13786 OMP_CLAUSE_DECL (*pc) = unshare_expr (OMP_CLAUSE_DECL (c));
13787 TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
13788 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc))
13790 auto_vec<tree> no_context_vars;
13791 int walk_subtrees = 0;
13792 note_no_context_vars (&OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
13793 &walk_subtrees, &no_context_vars);
13794 if (tree p = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c))
13795 note_no_context_vars (&p, &walk_subtrees, &no_context_vars);
13796 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_INIT (c),
13797 note_no_context_vars,
13798 &no_context_vars);
13799 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_MERGE (c),
13800 note_no_context_vars,
13801 &no_context_vars);
13803 OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc)
13804 = copy_node (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c));
13805 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc))
13806 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc)
13807 = copy_node (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c));
13809 hash_map<tree, tree> decl_map;
13810 decl_map.put (OMP_CLAUSE_DECL (c), OMP_CLAUSE_DECL (c));
13811 decl_map.put (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
13812 OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc));
13813 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc))
13814 decl_map.put (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
13815 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc));
13817 copy_body_data id;
13818 memset (&id, 0, sizeof (id));
13819 id.src_fn = current_function_decl;
13820 id.dst_fn = current_function_decl;
13821 id.src_cfun = cfun;
13822 id.decl_map = &decl_map;
13823 id.copy_decl = copy_decl_no_change;
13824 id.transform_call_graph_edges = CB_CGE_DUPLICATE;
13825 id.transform_new_cfg = true;
13826 id.transform_return_to_modify = false;
13827 id.eh_lp_nr = 0;
13828 walk_tree (&OMP_CLAUSE_REDUCTION_INIT (*pc), copy_tree_body_r,
13829 &id, NULL);
13830 walk_tree (&OMP_CLAUSE_REDUCTION_MERGE (*pc), copy_tree_body_r,
13831 &id, NULL);
13833 for (tree d : no_context_vars)
13835 DECL_CONTEXT (d) = NULL_TREE;
13836 DECL_CONTEXT (*decl_map.get (d)) = NULL_TREE;
13839 else
13841 OMP_CLAUSE_REDUCTION_INIT (*pc)
13842 = unshare_expr (OMP_CLAUSE_REDUCTION_INIT (c));
13843 OMP_CLAUSE_REDUCTION_MERGE (*pc)
13844 = unshare_expr (OMP_CLAUSE_REDUCTION_MERGE (c));
13846 pc = &OMP_CLAUSE_CHAIN (*pc);
13847 break;
13848 default:
13849 gcc_unreachable ();
13851 *pc = NULL_TREE;
13852 *expr_p = t;
13854 return gimplify_expr (expr_p, pre_p, NULL, is_gimple_stmt, fb_none);
13858 /* Helper function of optimize_target_teams, find OMP_TEAMS inside
13859 of OMP_TARGET's body. */
13861 static tree
13862 find_omp_teams (tree *tp, int *walk_subtrees, void *)
13864 *walk_subtrees = 0;
13865 switch (TREE_CODE (*tp))
13867 case OMP_TEAMS:
13868 return *tp;
13869 case BIND_EXPR:
13870 case STATEMENT_LIST:
13871 *walk_subtrees = 1;
13872 break;
13873 default:
13874 break;
13876 return NULL_TREE;
13879 /* Helper function of optimize_target_teams, determine if the expression
13880 can be computed safely before the target construct on the host. */
13882 static tree
13883 computable_teams_clause (tree *tp, int *walk_subtrees, void *)
13885 splay_tree_node n;
13887 if (TYPE_P (*tp))
13889 *walk_subtrees = 0;
13890 return NULL_TREE;
13892 switch (TREE_CODE (*tp))
13894 case VAR_DECL:
13895 case PARM_DECL:
13896 case RESULT_DECL:
13897 *walk_subtrees = 0;
13898 if (error_operand_p (*tp)
13899 || !INTEGRAL_TYPE_P (TREE_TYPE (*tp))
13900 || DECL_HAS_VALUE_EXPR_P (*tp)
13901 || DECL_THREAD_LOCAL_P (*tp)
13902 || TREE_SIDE_EFFECTS (*tp)
13903 || TREE_THIS_VOLATILE (*tp))
13904 return *tp;
13905 if (is_global_var (*tp)
13906 && (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (*tp))
13907 || lookup_attribute ("omp declare target link",
13908 DECL_ATTRIBUTES (*tp))))
13909 return *tp;
13910 if (VAR_P (*tp)
13911 && !DECL_SEEN_IN_BIND_EXPR_P (*tp)
13912 && !is_global_var (*tp)
13913 && decl_function_context (*tp) == current_function_decl)
13914 return *tp;
13915 n = splay_tree_lookup (gimplify_omp_ctxp->variables,
13916 (splay_tree_key) *tp);
13917 if (n == NULL)
13919 if (gimplify_omp_ctxp->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE)
13920 return NULL_TREE;
13921 return *tp;
13923 else if (n->value & GOVD_LOCAL)
13924 return *tp;
13925 else if (n->value & GOVD_FIRSTPRIVATE)
13926 return NULL_TREE;
13927 else if ((n->value & (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
13928 == (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
13929 return NULL_TREE;
13930 return *tp;
13931 case INTEGER_CST:
13932 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
13933 return *tp;
13934 return NULL_TREE;
13935 case TARGET_EXPR:
13936 if (TARGET_EXPR_INITIAL (*tp)
13937 || TREE_CODE (TARGET_EXPR_SLOT (*tp)) != VAR_DECL)
13938 return *tp;
13939 return computable_teams_clause (&TARGET_EXPR_SLOT (*tp),
13940 walk_subtrees, NULL);
13941 /* Allow some reasonable subset of integral arithmetics. */
13942 case PLUS_EXPR:
13943 case MINUS_EXPR:
13944 case MULT_EXPR:
13945 case TRUNC_DIV_EXPR:
13946 case CEIL_DIV_EXPR:
13947 case FLOOR_DIV_EXPR:
13948 case ROUND_DIV_EXPR:
13949 case TRUNC_MOD_EXPR:
13950 case CEIL_MOD_EXPR:
13951 case FLOOR_MOD_EXPR:
13952 case ROUND_MOD_EXPR:
13953 case RDIV_EXPR:
13954 case EXACT_DIV_EXPR:
13955 case MIN_EXPR:
13956 case MAX_EXPR:
13957 case LSHIFT_EXPR:
13958 case RSHIFT_EXPR:
13959 case BIT_IOR_EXPR:
13960 case BIT_XOR_EXPR:
13961 case BIT_AND_EXPR:
13962 case NEGATE_EXPR:
13963 case ABS_EXPR:
13964 case BIT_NOT_EXPR:
13965 case NON_LVALUE_EXPR:
13966 CASE_CONVERT:
13967 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
13968 return *tp;
13969 return NULL_TREE;
13970 /* And disallow anything else, except for comparisons. */
13971 default:
13972 if (COMPARISON_CLASS_P (*tp))
13973 return NULL_TREE;
13974 return *tp;
13978 /* Try to determine if the num_teams and/or thread_limit expressions
13979 can have their values determined already before entering the
13980 target construct.
13981 INTEGER_CSTs trivially are,
13982 integral decls that are firstprivate (explicitly or implicitly)
13983 or explicitly map(always, to:) or map(always, tofrom:) on the target
13984 region too, and expressions involving simple arithmetics on those
13985 too, function calls are not ok, dereferencing something neither etc.
13986 Add NUM_TEAMS and THREAD_LIMIT clauses to the OMP_CLAUSES of
13987 EXPR based on what we find:
13988 0 stands for clause not specified at all, use implementation default
13989 -1 stands for value that can't be determined easily before entering
13990 the target construct.
13991 If teams construct is not present at all, use 1 for num_teams
13992 and 0 for thread_limit (only one team is involved, and the thread
13993 limit is implementation defined. */
13995 static void
13996 optimize_target_teams (tree target, gimple_seq *pre_p)
13998 tree body = OMP_BODY (target);
13999 tree teams = walk_tree (&body, find_omp_teams, NULL, NULL);
14000 tree num_teams_lower = NULL_TREE;
14001 tree num_teams_upper = integer_zero_node;
14002 tree thread_limit = integer_zero_node;
14003 location_t num_teams_loc = EXPR_LOCATION (target);
14004 location_t thread_limit_loc = EXPR_LOCATION (target);
14005 tree c, *p, expr;
14006 struct gimplify_omp_ctx *target_ctx = gimplify_omp_ctxp;
14008 if (teams == NULL_TREE)
14009 num_teams_upper = integer_one_node;
14010 else
14011 for (c = OMP_TEAMS_CLAUSES (teams); c; c = OMP_CLAUSE_CHAIN (c))
14013 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS)
14015 p = &num_teams_upper;
14016 num_teams_loc = OMP_CLAUSE_LOCATION (c);
14017 if (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c))
14019 expr = OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c);
14020 if (TREE_CODE (expr) == INTEGER_CST)
14021 num_teams_lower = expr;
14022 else if (walk_tree (&expr, computable_teams_clause,
14023 NULL, NULL))
14024 num_teams_lower = integer_minus_one_node;
14025 else
14027 num_teams_lower = expr;
14028 gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
14029 if (gimplify_expr (&num_teams_lower, pre_p, NULL,
14030 is_gimple_val, fb_rvalue, false)
14031 == GS_ERROR)
14033 gimplify_omp_ctxp = target_ctx;
14034 num_teams_lower = integer_minus_one_node;
14036 else
14038 gimplify_omp_ctxp = target_ctx;
14039 if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR)
14040 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
14041 = num_teams_lower;
14046 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
14048 p = &thread_limit;
14049 thread_limit_loc = OMP_CLAUSE_LOCATION (c);
14051 else
14052 continue;
14053 expr = OMP_CLAUSE_OPERAND (c, 0);
14054 if (TREE_CODE (expr) == INTEGER_CST)
14056 *p = expr;
14057 continue;
14059 if (walk_tree (&expr, computable_teams_clause, NULL, NULL))
14061 *p = integer_minus_one_node;
14062 continue;
14064 *p = expr;
14065 gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
14066 if (gimplify_expr (p, pre_p, NULL, is_gimple_val, fb_rvalue, false)
14067 == GS_ERROR)
14069 gimplify_omp_ctxp = target_ctx;
14070 *p = integer_minus_one_node;
14071 continue;
14073 gimplify_omp_ctxp = target_ctx;
14074 if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR)
14075 OMP_CLAUSE_OPERAND (c, 0) = *p;
14077 if (!omp_find_clause (OMP_TARGET_CLAUSES (target), OMP_CLAUSE_THREAD_LIMIT))
14079 c = build_omp_clause (thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
14080 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = thread_limit;
14081 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
14082 OMP_TARGET_CLAUSES (target) = c;
14084 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
14085 OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c) = num_teams_upper;
14086 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) = num_teams_lower;
14087 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
14088 OMP_TARGET_CLAUSES (target) = c;
14091 /* Gimplify the gross structure of several OMP constructs. */
14093 static void
14094 gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
14096 tree expr = *expr_p;
14097 gimple *stmt;
14098 gimple_seq body = NULL;
14099 enum omp_region_type ort;
14101 switch (TREE_CODE (expr))
14103 case OMP_SECTIONS:
14104 case OMP_SINGLE:
14105 ort = ORT_WORKSHARE;
14106 break;
14107 case OMP_SCOPE:
14108 ort = ORT_TASKGROUP;
14109 break;
14110 case OMP_TARGET:
14111 ort = OMP_TARGET_COMBINED (expr) ? ORT_COMBINED_TARGET : ORT_TARGET;
14112 break;
14113 case OACC_KERNELS:
14114 ort = ORT_ACC_KERNELS;
14115 break;
14116 case OACC_PARALLEL:
14117 ort = ORT_ACC_PARALLEL;
14118 break;
14119 case OACC_SERIAL:
14120 ort = ORT_ACC_SERIAL;
14121 break;
14122 case OACC_DATA:
14123 ort = ORT_ACC_DATA;
14124 break;
14125 case OMP_TARGET_DATA:
14126 ort = ORT_TARGET_DATA;
14127 break;
14128 case OMP_TEAMS:
14129 ort = OMP_TEAMS_COMBINED (expr) ? ORT_COMBINED_TEAMS : ORT_TEAMS;
14130 if (gimplify_omp_ctxp == NULL
14131 || gimplify_omp_ctxp->region_type == ORT_IMPLICIT_TARGET)
14132 ort = (enum omp_region_type) (ort | ORT_HOST_TEAMS);
14133 break;
14134 case OACC_HOST_DATA:
14135 ort = ORT_ACC_HOST_DATA;
14136 break;
14137 default:
14138 gcc_unreachable ();
14141 bool save_in_omp_construct = in_omp_construct;
14142 if ((ort & ORT_ACC) == 0)
14143 in_omp_construct = false;
14144 gimplify_scan_omp_clauses (&OMP_CLAUSES (expr), pre_p, ort,
14145 TREE_CODE (expr));
14146 if (TREE_CODE (expr) == OMP_TARGET)
14147 optimize_target_teams (expr, pre_p);
14148 if ((ort & (ORT_TARGET | ORT_TARGET_DATA)) != 0
14149 || (ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
14151 push_gimplify_context ();
14152 gimple *g = gimplify_and_return_first (OMP_BODY (expr), &body);
14153 if (gimple_code (g) == GIMPLE_BIND)
14154 pop_gimplify_context (g);
14155 else
14156 pop_gimplify_context (NULL);
14157 if ((ort & ORT_TARGET_DATA) != 0)
14159 enum built_in_function end_ix;
14160 switch (TREE_CODE (expr))
14162 case OACC_DATA:
14163 case OACC_HOST_DATA:
14164 end_ix = BUILT_IN_GOACC_DATA_END;
14165 break;
14166 case OMP_TARGET_DATA:
14167 end_ix = BUILT_IN_GOMP_TARGET_END_DATA;
14168 break;
14169 default:
14170 gcc_unreachable ();
14172 tree fn = builtin_decl_explicit (end_ix);
14173 g = gimple_build_call (fn, 0);
14174 gimple_seq cleanup = NULL;
14175 gimple_seq_add_stmt (&cleanup, g);
14176 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
14177 body = NULL;
14178 gimple_seq_add_stmt (&body, g);
14181 else
14182 gimplify_and_add (OMP_BODY (expr), &body);
14183 gimplify_adjust_omp_clauses (pre_p, body, &OMP_CLAUSES (expr),
14184 TREE_CODE (expr));
14185 in_omp_construct = save_in_omp_construct;
14187 switch (TREE_CODE (expr))
14189 case OACC_DATA:
14190 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_DATA,
14191 OMP_CLAUSES (expr));
14192 break;
14193 case OACC_HOST_DATA:
14194 if (omp_find_clause (OMP_CLAUSES (expr), OMP_CLAUSE_IF_PRESENT))
14196 for (tree c = OMP_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
14197 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_PTR)
14198 OMP_CLAUSE_USE_DEVICE_PTR_IF_PRESENT (c) = 1;
14201 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_HOST_DATA,
14202 OMP_CLAUSES (expr));
14203 break;
14204 case OACC_KERNELS:
14205 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_KERNELS,
14206 OMP_CLAUSES (expr));
14207 break;
14208 case OACC_PARALLEL:
14209 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_PARALLEL,
14210 OMP_CLAUSES (expr));
14211 break;
14212 case OACC_SERIAL:
14213 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_SERIAL,
14214 OMP_CLAUSES (expr));
14215 break;
14216 case OMP_SECTIONS:
14217 stmt = gimple_build_omp_sections (body, OMP_CLAUSES (expr));
14218 break;
14219 case OMP_SINGLE:
14220 stmt = gimple_build_omp_single (body, OMP_CLAUSES (expr));
14221 break;
14222 case OMP_SCOPE:
14223 stmt = gimple_build_omp_scope (body, OMP_CLAUSES (expr));
14224 break;
14225 case OMP_TARGET:
14226 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_REGION,
14227 OMP_CLAUSES (expr));
14228 break;
14229 case OMP_TARGET_DATA:
14230 /* Put use_device_{ptr,addr} clauses last, as map clauses are supposed
14231 to be evaluated before the use_device_{ptr,addr} clauses if they
14232 refer to the same variables. */
14234 tree use_device_clauses;
14235 tree *pc, *uc = &use_device_clauses;
14236 for (pc = &OMP_CLAUSES (expr); *pc; )
14237 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
14238 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
14240 *uc = *pc;
14241 *pc = OMP_CLAUSE_CHAIN (*pc);
14242 uc = &OMP_CLAUSE_CHAIN (*uc);
14244 else
14245 pc = &OMP_CLAUSE_CHAIN (*pc);
14246 *uc = NULL_TREE;
14247 *pc = use_device_clauses;
14248 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_DATA,
14249 OMP_CLAUSES (expr));
14251 break;
14252 case OMP_TEAMS:
14253 stmt = gimple_build_omp_teams (body, OMP_CLAUSES (expr));
14254 if ((ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
14255 gimple_omp_teams_set_host (as_a <gomp_teams *> (stmt), true);
14256 break;
14257 default:
14258 gcc_unreachable ();
14261 gimplify_seq_add_stmt (pre_p, stmt);
14262 *expr_p = NULL_TREE;
14265 /* Gimplify the gross structure of OpenACC enter/exit data, update, and OpenMP
14266 target update constructs. */
14268 static void
14269 gimplify_omp_target_update (tree *expr_p, gimple_seq *pre_p)
14271 tree expr = *expr_p;
14272 int kind;
14273 gomp_target *stmt;
14274 enum omp_region_type ort = ORT_WORKSHARE;
14276 switch (TREE_CODE (expr))
14278 case OACC_ENTER_DATA:
14279 kind = GF_OMP_TARGET_KIND_OACC_ENTER_DATA;
14280 ort = ORT_ACC;
14281 break;
14282 case OACC_EXIT_DATA:
14283 kind = GF_OMP_TARGET_KIND_OACC_EXIT_DATA;
14284 ort = ORT_ACC;
14285 break;
14286 case OACC_UPDATE:
14287 kind = GF_OMP_TARGET_KIND_OACC_UPDATE;
14288 ort = ORT_ACC;
14289 break;
14290 case OMP_TARGET_UPDATE:
14291 kind = GF_OMP_TARGET_KIND_UPDATE;
14292 break;
14293 case OMP_TARGET_ENTER_DATA:
14294 kind = GF_OMP_TARGET_KIND_ENTER_DATA;
14295 break;
14296 case OMP_TARGET_EXIT_DATA:
14297 kind = GF_OMP_TARGET_KIND_EXIT_DATA;
14298 break;
14299 default:
14300 gcc_unreachable ();
14302 gimplify_scan_omp_clauses (&OMP_STANDALONE_CLAUSES (expr), pre_p,
14303 ort, TREE_CODE (expr));
14304 gimplify_adjust_omp_clauses (pre_p, NULL, &OMP_STANDALONE_CLAUSES (expr),
14305 TREE_CODE (expr));
14306 if (TREE_CODE (expr) == OACC_UPDATE
14307 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
14308 OMP_CLAUSE_IF_PRESENT))
14310 /* The runtime uses GOMP_MAP_{TO,FROM} to denote the if_present
14311 clause. */
14312 for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
14313 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
14314 switch (OMP_CLAUSE_MAP_KIND (c))
14316 case GOMP_MAP_FORCE_TO:
14317 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TO);
14318 break;
14319 case GOMP_MAP_FORCE_FROM:
14320 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FROM);
14321 break;
14322 default:
14323 break;
14326 else if (TREE_CODE (expr) == OACC_EXIT_DATA
14327 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
14328 OMP_CLAUSE_FINALIZE))
14330 /* Use GOMP_MAP_DELETE/GOMP_MAP_FORCE_FROM to denote "finalize"
14331 semantics. */
14332 bool have_clause = false;
14333 for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
14334 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
14335 switch (OMP_CLAUSE_MAP_KIND (c))
14337 case GOMP_MAP_FROM:
14338 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_FROM);
14339 have_clause = true;
14340 break;
14341 case GOMP_MAP_RELEASE:
14342 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_DELETE);
14343 have_clause = true;
14344 break;
14345 case GOMP_MAP_TO_PSET:
14346 /* Fortran arrays with descriptors must map that descriptor when
14347 doing standalone "attach" operations (in OpenACC). In that
14348 case GOMP_MAP_TO_PSET appears by itself with no preceding
14349 clause (see trans-openmp.cc:gfc_trans_omp_clauses). */
14350 break;
14351 case GOMP_MAP_POINTER:
14352 /* TODO PR92929: we may see these here, but they'll always follow
14353 one of the clauses above, and will be handled by libgomp as
14354 one group, so no handling required here. */
14355 gcc_assert (have_clause);
14356 break;
14357 case GOMP_MAP_DETACH:
14358 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_DETACH);
14359 have_clause = false;
14360 break;
14361 case GOMP_MAP_STRUCT:
14362 have_clause = false;
14363 break;
14364 default:
14365 gcc_unreachable ();
14368 stmt = gimple_build_omp_target (NULL, kind, OMP_STANDALONE_CLAUSES (expr));
14370 gimplify_seq_add_stmt (pre_p, stmt);
14371 *expr_p = NULL_TREE;
14374 /* A subroutine of gimplify_omp_atomic. The front end is supposed to have
14375 stabilized the lhs of the atomic operation as *ADDR. Return true if
14376 EXPR is this stabilized form. */
14378 static bool
14379 goa_lhs_expr_p (tree expr, tree addr)
14381 /* Also include casts to other type variants. The C front end is fond
14382 of adding these for e.g. volatile variables. This is like
14383 STRIP_TYPE_NOPS but includes the main variant lookup. */
14384 STRIP_USELESS_TYPE_CONVERSION (expr);
14386 if (TREE_CODE (expr) == INDIRECT_REF)
14388 expr = TREE_OPERAND (expr, 0);
14389 while (expr != addr
14390 && (CONVERT_EXPR_P (expr)
14391 || TREE_CODE (expr) == NON_LVALUE_EXPR)
14392 && TREE_CODE (expr) == TREE_CODE (addr)
14393 && types_compatible_p (TREE_TYPE (expr), TREE_TYPE (addr)))
14395 expr = TREE_OPERAND (expr, 0);
14396 addr = TREE_OPERAND (addr, 0);
14398 if (expr == addr)
14399 return true;
14400 return (TREE_CODE (addr) == ADDR_EXPR
14401 && TREE_CODE (expr) == ADDR_EXPR
14402 && TREE_OPERAND (addr, 0) == TREE_OPERAND (expr, 0));
14404 if (TREE_CODE (addr) == ADDR_EXPR && expr == TREE_OPERAND (addr, 0))
14405 return true;
14406 return false;
14409 /* Walk *EXPR_P and replace appearances of *LHS_ADDR with LHS_VAR. If an
14410 expression does not involve the lhs, evaluate it into a temporary.
14411 Return 1 if the lhs appeared as a subexpression, 0 if it did not,
14412 or -1 if an error was encountered. */
14414 static int
14415 goa_stabilize_expr (tree *expr_p, gimple_seq *pre_p, tree lhs_addr,
14416 tree lhs_var, tree &target_expr, bool rhs, int depth)
14418 tree expr = *expr_p;
14419 int saw_lhs = 0;
14421 if (goa_lhs_expr_p (expr, lhs_addr))
14423 if (pre_p)
14424 *expr_p = lhs_var;
14425 return 1;
14427 if (is_gimple_val (expr))
14428 return 0;
14430 /* Maximum depth of lhs in expression is for the
14431 __builtin_clear_padding (...), __builtin_clear_padding (...),
14432 __builtin_memcmp (&TARGET_EXPR <lhs, >, ...) == 0 ? ... : lhs; */
14433 if (++depth > 7)
14434 goto finish;
14436 switch (TREE_CODE_CLASS (TREE_CODE (expr)))
14438 case tcc_binary:
14439 case tcc_comparison:
14440 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p, lhs_addr,
14441 lhs_var, target_expr, true, depth);
14442 /* FALLTHRU */
14443 case tcc_unary:
14444 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p, lhs_addr,
14445 lhs_var, target_expr, true, depth);
14446 break;
14447 case tcc_expression:
14448 switch (TREE_CODE (expr))
14450 case TRUTH_ANDIF_EXPR:
14451 case TRUTH_ORIF_EXPR:
14452 case TRUTH_AND_EXPR:
14453 case TRUTH_OR_EXPR:
14454 case TRUTH_XOR_EXPR:
14455 case BIT_INSERT_EXPR:
14456 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
14457 lhs_addr, lhs_var, target_expr, true,
14458 depth);
14459 /* FALLTHRU */
14460 case TRUTH_NOT_EXPR:
14461 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
14462 lhs_addr, lhs_var, target_expr, true,
14463 depth);
14464 break;
14465 case MODIFY_EXPR:
14466 if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr, lhs_var,
14467 target_expr, true, depth))
14468 break;
14469 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
14470 lhs_addr, lhs_var, target_expr, true,
14471 depth);
14472 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
14473 lhs_addr, lhs_var, target_expr, false,
14474 depth);
14475 break;
14476 /* FALLTHRU */
14477 case ADDR_EXPR:
14478 if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr, lhs_var,
14479 target_expr, true, depth))
14480 break;
14481 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
14482 lhs_addr, lhs_var, target_expr, false,
14483 depth);
14484 break;
14485 case COMPOUND_EXPR:
14486 /* Break out any preevaluations from cp_build_modify_expr. */
14487 for (; TREE_CODE (expr) == COMPOUND_EXPR;
14488 expr = TREE_OPERAND (expr, 1))
14490 /* Special-case __builtin_clear_padding call before
14491 __builtin_memcmp. */
14492 if (TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR)
14494 tree fndecl = get_callee_fndecl (TREE_OPERAND (expr, 0));
14495 if (fndecl
14496 && fndecl_built_in_p (fndecl, BUILT_IN_CLEAR_PADDING)
14497 && VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 0)))
14498 && (!pre_p
14499 || goa_stabilize_expr (&TREE_OPERAND (expr, 0), NULL,
14500 lhs_addr, lhs_var,
14501 target_expr, true, depth)))
14503 if (pre_p)
14504 *expr_p = expr;
14505 saw_lhs = goa_stabilize_expr (&TREE_OPERAND (expr, 0),
14506 pre_p, lhs_addr, lhs_var,
14507 target_expr, true, depth);
14508 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1),
14509 pre_p, lhs_addr, lhs_var,
14510 target_expr, rhs, depth);
14511 return saw_lhs;
14515 if (pre_p)
14516 gimplify_stmt (&TREE_OPERAND (expr, 0), pre_p);
14518 if (!pre_p)
14519 return goa_stabilize_expr (&expr, pre_p, lhs_addr, lhs_var,
14520 target_expr, rhs, depth);
14521 *expr_p = expr;
14522 return goa_stabilize_expr (expr_p, pre_p, lhs_addr, lhs_var,
14523 target_expr, rhs, depth);
14524 case COND_EXPR:
14525 if (!goa_stabilize_expr (&TREE_OPERAND (expr, 0), NULL, lhs_addr,
14526 lhs_var, target_expr, true, depth))
14527 break;
14528 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
14529 lhs_addr, lhs_var, target_expr, true,
14530 depth);
14531 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
14532 lhs_addr, lhs_var, target_expr, true,
14533 depth);
14534 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 2), pre_p,
14535 lhs_addr, lhs_var, target_expr, true,
14536 depth);
14537 break;
14538 case TARGET_EXPR:
14539 if (TARGET_EXPR_INITIAL (expr))
14541 if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr,
14542 lhs_var, target_expr, true,
14543 depth))
14544 break;
14545 if (expr == target_expr)
14546 saw_lhs = 1;
14547 else
14549 saw_lhs = goa_stabilize_expr (&TARGET_EXPR_INITIAL (expr),
14550 pre_p, lhs_addr, lhs_var,
14551 target_expr, true, depth);
14552 if (saw_lhs && target_expr == NULL_TREE && pre_p)
14553 target_expr = expr;
14556 break;
14557 default:
14558 break;
14560 break;
14561 case tcc_reference:
14562 if (TREE_CODE (expr) == BIT_FIELD_REF
14563 || TREE_CODE (expr) == VIEW_CONVERT_EXPR)
14564 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
14565 lhs_addr, lhs_var, target_expr, true,
14566 depth);
14567 break;
14568 case tcc_vl_exp:
14569 if (TREE_CODE (expr) == CALL_EXPR)
14571 if (tree fndecl = get_callee_fndecl (expr))
14572 if (fndecl_built_in_p (fndecl, BUILT_IN_CLEAR_PADDING)
14573 || fndecl_built_in_p (fndecl, BUILT_IN_MEMCMP))
14575 int nargs = call_expr_nargs (expr);
14576 for (int i = 0; i < nargs; i++)
14577 saw_lhs |= goa_stabilize_expr (&CALL_EXPR_ARG (expr, i),
14578 pre_p, lhs_addr, lhs_var,
14579 target_expr, true, depth);
14582 break;
14583 default:
14584 break;
14587 finish:
14588 if (saw_lhs == 0 && pre_p)
14590 enum gimplify_status gs;
14591 if (TREE_CODE (expr) == CALL_EXPR && VOID_TYPE_P (TREE_TYPE (expr)))
14593 gimplify_stmt (&expr, pre_p);
14594 return saw_lhs;
14596 else if (rhs)
14597 gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_val, fb_rvalue);
14598 else
14599 gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_lvalue, fb_lvalue);
14600 if (gs != GS_ALL_DONE)
14601 saw_lhs = -1;
14604 return saw_lhs;
14607 /* Gimplify an OMP_ATOMIC statement. */
14609 static enum gimplify_status
14610 gimplify_omp_atomic (tree *expr_p, gimple_seq *pre_p)
14612 tree addr = TREE_OPERAND (*expr_p, 0);
14613 tree rhs = TREE_CODE (*expr_p) == OMP_ATOMIC_READ
14614 ? NULL : TREE_OPERAND (*expr_p, 1);
14615 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
14616 tree tmp_load;
14617 gomp_atomic_load *loadstmt;
14618 gomp_atomic_store *storestmt;
14619 tree target_expr = NULL_TREE;
14621 tmp_load = create_tmp_reg (type);
14622 if (rhs
14623 && goa_stabilize_expr (&rhs, pre_p, addr, tmp_load, target_expr,
14624 true, 0) < 0)
14625 return GS_ERROR;
14627 if (gimplify_expr (&addr, pre_p, NULL, is_gimple_val, fb_rvalue)
14628 != GS_ALL_DONE)
14629 return GS_ERROR;
14631 loadstmt = gimple_build_omp_atomic_load (tmp_load, addr,
14632 OMP_ATOMIC_MEMORY_ORDER (*expr_p));
14633 gimplify_seq_add_stmt (pre_p, loadstmt);
14634 if (rhs)
14636 /* BIT_INSERT_EXPR is not valid for non-integral bitfield
14637 representatives. Use BIT_FIELD_REF on the lhs instead. */
14638 tree rhsarg = rhs;
14639 if (TREE_CODE (rhs) == COND_EXPR)
14640 rhsarg = TREE_OPERAND (rhs, 1);
14641 if (TREE_CODE (rhsarg) == BIT_INSERT_EXPR
14642 && !INTEGRAL_TYPE_P (TREE_TYPE (tmp_load)))
14644 tree bitpos = TREE_OPERAND (rhsarg, 2);
14645 tree op1 = TREE_OPERAND (rhsarg, 1);
14646 tree bitsize;
14647 tree tmp_store = tmp_load;
14648 if (TREE_CODE (*expr_p) == OMP_ATOMIC_CAPTURE_OLD)
14649 tmp_store = get_initialized_tmp_var (tmp_load, pre_p);
14650 if (INTEGRAL_TYPE_P (TREE_TYPE (op1)))
14651 bitsize = bitsize_int (TYPE_PRECISION (TREE_TYPE (op1)));
14652 else
14653 bitsize = TYPE_SIZE (TREE_TYPE (op1));
14654 gcc_assert (TREE_OPERAND (rhsarg, 0) == tmp_load);
14655 tree t = build2_loc (EXPR_LOCATION (rhsarg),
14656 MODIFY_EXPR, void_type_node,
14657 build3_loc (EXPR_LOCATION (rhsarg),
14658 BIT_FIELD_REF, TREE_TYPE (op1),
14659 tmp_store, bitsize, bitpos), op1);
14660 if (TREE_CODE (rhs) == COND_EXPR)
14661 t = build3_loc (EXPR_LOCATION (rhs), COND_EXPR, void_type_node,
14662 TREE_OPERAND (rhs, 0), t, void_node);
14663 gimplify_and_add (t, pre_p);
14664 rhs = tmp_store;
14666 bool save_allow_rhs_cond_expr = gimplify_ctxp->allow_rhs_cond_expr;
14667 if (TREE_CODE (rhs) == COND_EXPR)
14668 gimplify_ctxp->allow_rhs_cond_expr = true;
14669 enum gimplify_status gs = gimplify_expr (&rhs, pre_p, NULL,
14670 is_gimple_val, fb_rvalue);
14671 gimplify_ctxp->allow_rhs_cond_expr = save_allow_rhs_cond_expr;
14672 if (gs != GS_ALL_DONE)
14673 return GS_ERROR;
14676 if (TREE_CODE (*expr_p) == OMP_ATOMIC_READ)
14677 rhs = tmp_load;
14678 storestmt
14679 = gimple_build_omp_atomic_store (rhs, OMP_ATOMIC_MEMORY_ORDER (*expr_p));
14680 if (TREE_CODE (*expr_p) != OMP_ATOMIC_READ && OMP_ATOMIC_WEAK (*expr_p))
14682 gimple_omp_atomic_set_weak (loadstmt);
14683 gimple_omp_atomic_set_weak (storestmt);
14685 gimplify_seq_add_stmt (pre_p, storestmt);
14686 switch (TREE_CODE (*expr_p))
14688 case OMP_ATOMIC_READ:
14689 case OMP_ATOMIC_CAPTURE_OLD:
14690 *expr_p = tmp_load;
14691 gimple_omp_atomic_set_need_value (loadstmt);
14692 break;
14693 case OMP_ATOMIC_CAPTURE_NEW:
14694 *expr_p = rhs;
14695 gimple_omp_atomic_set_need_value (storestmt);
14696 break;
14697 default:
14698 *expr_p = NULL;
14699 break;
14702 return GS_ALL_DONE;
14705 /* Gimplify a TRANSACTION_EXPR. This involves gimplification of the
14706 body, and adding some EH bits. */
14708 static enum gimplify_status
14709 gimplify_transaction (tree *expr_p, gimple_seq *pre_p)
14711 tree expr = *expr_p, temp, tbody = TRANSACTION_EXPR_BODY (expr);
14712 gimple *body_stmt;
14713 gtransaction *trans_stmt;
14714 gimple_seq body = NULL;
14715 int subcode = 0;
14717 /* Wrap the transaction body in a BIND_EXPR so we have a context
14718 where to put decls for OMP. */
14719 if (TREE_CODE (tbody) != BIND_EXPR)
14721 tree bind = build3 (BIND_EXPR, void_type_node, NULL, tbody, NULL);
14722 TREE_SIDE_EFFECTS (bind) = 1;
14723 SET_EXPR_LOCATION (bind, EXPR_LOCATION (tbody));
14724 TRANSACTION_EXPR_BODY (expr) = bind;
14727 push_gimplify_context ();
14728 temp = voidify_wrapper_expr (*expr_p, NULL);
14730 body_stmt = gimplify_and_return_first (TRANSACTION_EXPR_BODY (expr), &body);
14731 pop_gimplify_context (body_stmt);
14733 trans_stmt = gimple_build_transaction (body);
14734 if (TRANSACTION_EXPR_OUTER (expr))
14735 subcode = GTMA_IS_OUTER;
14736 else if (TRANSACTION_EXPR_RELAXED (expr))
14737 subcode = GTMA_IS_RELAXED;
14738 gimple_transaction_set_subcode (trans_stmt, subcode);
14740 gimplify_seq_add_stmt (pre_p, trans_stmt);
14742 if (temp)
14744 *expr_p = temp;
14745 return GS_OK;
14748 *expr_p = NULL_TREE;
14749 return GS_ALL_DONE;
14752 /* Gimplify an OMP_ORDERED construct. EXPR is the tree version. BODY
14753 is the OMP_BODY of the original EXPR (which has already been
14754 gimplified so it's not present in the EXPR).
14756 Return the gimplified GIMPLE_OMP_ORDERED tuple. */
14758 static gimple *
14759 gimplify_omp_ordered (tree expr, gimple_seq body)
14761 tree c, decls;
14762 int failures = 0;
14763 unsigned int i;
14764 tree source_c = NULL_TREE;
14765 tree sink_c = NULL_TREE;
14767 if (gimplify_omp_ctxp)
14769 for (c = OMP_ORDERED_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
14770 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
14771 && gimplify_omp_ctxp->loop_iter_var.is_empty ()
14772 && (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK
14773 || OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE))
14775 error_at (OMP_CLAUSE_LOCATION (c),
14776 "%<ordered%> construct with %<depend%> clause must be "
14777 "closely nested inside a loop with %<ordered%> clause "
14778 "with a parameter");
14779 failures++;
14781 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
14782 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
14784 bool fail = false;
14785 for (decls = OMP_CLAUSE_DECL (c), i = 0;
14786 decls && TREE_CODE (decls) == TREE_LIST;
14787 decls = TREE_CHAIN (decls), ++i)
14788 if (i >= gimplify_omp_ctxp->loop_iter_var.length () / 2)
14789 continue;
14790 else if (TREE_VALUE (decls)
14791 != gimplify_omp_ctxp->loop_iter_var[2 * i])
14793 error_at (OMP_CLAUSE_LOCATION (c),
14794 "variable %qE is not an iteration "
14795 "of outermost loop %d, expected %qE",
14796 TREE_VALUE (decls), i + 1,
14797 gimplify_omp_ctxp->loop_iter_var[2 * i]);
14798 fail = true;
14799 failures++;
14801 else
14802 TREE_VALUE (decls)
14803 = gimplify_omp_ctxp->loop_iter_var[2 * i + 1];
14804 if (!fail && i != gimplify_omp_ctxp->loop_iter_var.length () / 2)
14806 error_at (OMP_CLAUSE_LOCATION (c),
14807 "number of variables in %<depend%> clause with "
14808 "%<sink%> modifier does not match number of "
14809 "iteration variables");
14810 failures++;
14812 sink_c = c;
14814 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
14815 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
14817 if (source_c)
14819 error_at (OMP_CLAUSE_LOCATION (c),
14820 "more than one %<depend%> clause with %<source%> "
14821 "modifier on an %<ordered%> construct");
14822 failures++;
14824 else
14825 source_c = c;
14828 if (source_c && sink_c)
14830 error_at (OMP_CLAUSE_LOCATION (source_c),
14831 "%<depend%> clause with %<source%> modifier specified "
14832 "together with %<depend%> clauses with %<sink%> modifier "
14833 "on the same construct");
14834 failures++;
14837 if (failures)
14838 return gimple_build_nop ();
14839 return gimple_build_omp_ordered (body, OMP_ORDERED_CLAUSES (expr));
14842 /* Convert the GENERIC expression tree *EXPR_P to GIMPLE. If the
14843 expression produces a value to be used as an operand inside a GIMPLE
14844 statement, the value will be stored back in *EXPR_P. This value will
14845 be a tree of class tcc_declaration, tcc_constant, tcc_reference or
14846 an SSA_NAME. The corresponding sequence of GIMPLE statements is
14847 emitted in PRE_P and POST_P.
14849 Additionally, this process may overwrite parts of the input
14850 expression during gimplification. Ideally, it should be
14851 possible to do non-destructive gimplification.
14853 EXPR_P points to the GENERIC expression to convert to GIMPLE. If
14854 the expression needs to evaluate to a value to be used as
14855 an operand in a GIMPLE statement, this value will be stored in
14856 *EXPR_P on exit. This happens when the caller specifies one
14857 of fb_lvalue or fb_rvalue fallback flags.
14859 PRE_P will contain the sequence of GIMPLE statements corresponding
14860 to the evaluation of EXPR and all the side-effects that must
14861 be executed before the main expression. On exit, the last
14862 statement of PRE_P is the core statement being gimplified. For
14863 instance, when gimplifying 'if (++a)' the last statement in
14864 PRE_P will be 'if (t.1)' where t.1 is the result of
14865 pre-incrementing 'a'.
14867 POST_P will contain the sequence of GIMPLE statements corresponding
14868 to the evaluation of all the side-effects that must be executed
14869 after the main expression. If this is NULL, the post
14870 side-effects are stored at the end of PRE_P.
14872 The reason why the output is split in two is to handle post
14873 side-effects explicitly. In some cases, an expression may have
14874 inner and outer post side-effects which need to be emitted in
14875 an order different from the one given by the recursive
14876 traversal. For instance, for the expression (*p--)++ the post
14877 side-effects of '--' must actually occur *after* the post
14878 side-effects of '++'. However, gimplification will first visit
14879 the inner expression, so if a separate POST sequence was not
14880 used, the resulting sequence would be:
14882 1 t.1 = *p
14883 2 p = p - 1
14884 3 t.2 = t.1 + 1
14885 4 *p = t.2
14887 However, the post-decrement operation in line #2 must not be
14888 evaluated until after the store to *p at line #4, so the
14889 correct sequence should be:
14891 1 t.1 = *p
14892 2 t.2 = t.1 + 1
14893 3 *p = t.2
14894 4 p = p - 1
14896 So, by specifying a separate post queue, it is possible
14897 to emit the post side-effects in the correct order.
14898 If POST_P is NULL, an internal queue will be used. Before
14899 returning to the caller, the sequence POST_P is appended to
14900 the main output sequence PRE_P.
14902 GIMPLE_TEST_F points to a function that takes a tree T and
14903 returns nonzero if T is in the GIMPLE form requested by the
14904 caller. The GIMPLE predicates are in gimple.cc.
14906 FALLBACK tells the function what sort of a temporary we want if
14907 gimplification cannot produce an expression that complies with
14908 GIMPLE_TEST_F.
14910 fb_none means that no temporary should be generated
14911 fb_rvalue means that an rvalue is OK to generate
14912 fb_lvalue means that an lvalue is OK to generate
14913 fb_either means that either is OK, but an lvalue is preferable.
14914 fb_mayfail means that gimplification may fail (in which case
14915 GS_ERROR will be returned)
14917 The return value is either GS_ERROR or GS_ALL_DONE, since this
14918 function iterates until EXPR is completely gimplified or an error
14919 occurs. */
14921 enum gimplify_status
14922 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
14923 bool (*gimple_test_f) (tree), fallback_t fallback)
14925 tree tmp;
14926 gimple_seq internal_pre = NULL;
14927 gimple_seq internal_post = NULL;
14928 tree save_expr;
14929 bool is_statement;
14930 location_t saved_location;
14931 enum gimplify_status ret;
14932 gimple_stmt_iterator pre_last_gsi, post_last_gsi;
14933 tree label;
14935 save_expr = *expr_p;
14936 if (save_expr == NULL_TREE)
14937 return GS_ALL_DONE;
14939 /* If we are gimplifying a top-level statement, PRE_P must be valid. */
14940 is_statement = gimple_test_f == is_gimple_stmt;
14941 if (is_statement)
14942 gcc_assert (pre_p);
14944 /* Consistency checks. */
14945 if (gimple_test_f == is_gimple_reg)
14946 gcc_assert (fallback & (fb_rvalue | fb_lvalue));
14947 else if (gimple_test_f == is_gimple_val
14948 || gimple_test_f == is_gimple_call_addr
14949 || gimple_test_f == is_gimple_condexpr
14950 || gimple_test_f == is_gimple_condexpr_for_cond
14951 || gimple_test_f == is_gimple_mem_rhs
14952 || gimple_test_f == is_gimple_mem_rhs_or_call
14953 || gimple_test_f == is_gimple_reg_rhs
14954 || gimple_test_f == is_gimple_reg_rhs_or_call
14955 || gimple_test_f == is_gimple_asm_val
14956 || gimple_test_f == is_gimple_mem_ref_addr)
14957 gcc_assert (fallback & fb_rvalue);
14958 else if (gimple_test_f == is_gimple_min_lval
14959 || gimple_test_f == is_gimple_lvalue)
14960 gcc_assert (fallback & fb_lvalue);
14961 else if (gimple_test_f == is_gimple_addressable)
14962 gcc_assert (fallback & fb_either);
14963 else if (gimple_test_f == is_gimple_stmt)
14964 gcc_assert (fallback == fb_none);
14965 else
14967 /* We should have recognized the GIMPLE_TEST_F predicate to
14968 know what kind of fallback to use in case a temporary is
14969 needed to hold the value or address of *EXPR_P. */
14970 gcc_unreachable ();
14973 /* We used to check the predicate here and return immediately if it
14974 succeeds. This is wrong; the design is for gimplification to be
14975 idempotent, and for the predicates to only test for valid forms, not
14976 whether they are fully simplified. */
14977 if (pre_p == NULL)
14978 pre_p = &internal_pre;
14980 if (post_p == NULL)
14981 post_p = &internal_post;
14983 /* Remember the last statements added to PRE_P and POST_P. Every
14984 new statement added by the gimplification helpers needs to be
14985 annotated with location information. To centralize the
14986 responsibility, we remember the last statement that had been
14987 added to both queues before gimplifying *EXPR_P. If
14988 gimplification produces new statements in PRE_P and POST_P, those
14989 statements will be annotated with the same location information
14990 as *EXPR_P. */
14991 pre_last_gsi = gsi_last (*pre_p);
14992 post_last_gsi = gsi_last (*post_p);
14994 saved_location = input_location;
14995 if (save_expr != error_mark_node
14996 && EXPR_HAS_LOCATION (*expr_p))
14997 input_location = EXPR_LOCATION (*expr_p);
14999 /* Loop over the specific gimplifiers until the toplevel node
15000 remains the same. */
15003 /* Strip away as many useless type conversions as possible
15004 at the toplevel. */
15005 STRIP_USELESS_TYPE_CONVERSION (*expr_p);
15007 /* Remember the expr. */
15008 save_expr = *expr_p;
15010 /* Die, die, die, my darling. */
15011 if (error_operand_p (save_expr))
15013 ret = GS_ERROR;
15014 break;
15017 /* Do any language-specific gimplification. */
15018 ret = ((enum gimplify_status)
15019 lang_hooks.gimplify_expr (expr_p, pre_p, post_p));
15020 if (ret == GS_OK)
15022 if (*expr_p == NULL_TREE)
15023 break;
15024 if (*expr_p != save_expr)
15025 continue;
15027 else if (ret != GS_UNHANDLED)
15028 break;
15030 /* Make sure that all the cases set 'ret' appropriately. */
15031 ret = GS_UNHANDLED;
15032 switch (TREE_CODE (*expr_p))
15034 /* First deal with the special cases. */
15036 case POSTINCREMENT_EXPR:
15037 case POSTDECREMENT_EXPR:
15038 case PREINCREMENT_EXPR:
15039 case PREDECREMENT_EXPR:
15040 ret = gimplify_self_mod_expr (expr_p, pre_p, post_p,
15041 fallback != fb_none,
15042 TREE_TYPE (*expr_p));
15043 break;
15045 case VIEW_CONVERT_EXPR:
15046 if ((fallback & fb_rvalue)
15047 && is_gimple_reg_type (TREE_TYPE (*expr_p))
15048 && is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0))))
15050 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15051 post_p, is_gimple_val, fb_rvalue);
15052 recalculate_side_effects (*expr_p);
15053 break;
15055 /* Fallthru. */
15057 case ARRAY_REF:
15058 case ARRAY_RANGE_REF:
15059 case REALPART_EXPR:
15060 case IMAGPART_EXPR:
15061 case COMPONENT_REF:
15062 ret = gimplify_compound_lval (expr_p, pre_p, post_p,
15063 fallback ? fallback : fb_rvalue);
15064 break;
15066 case COND_EXPR:
15067 ret = gimplify_cond_expr (expr_p, pre_p, fallback);
15069 /* C99 code may assign to an array in a structure value of a
15070 conditional expression, and this has undefined behavior
15071 only on execution, so create a temporary if an lvalue is
15072 required. */
15073 if (fallback == fb_lvalue)
15075 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
15076 mark_addressable (*expr_p);
15077 ret = GS_OK;
15079 break;
15081 case CALL_EXPR:
15082 ret = gimplify_call_expr (expr_p, pre_p, fallback != fb_none);
15084 /* C99 code may assign to an array in a structure returned
15085 from a function, and this has undefined behavior only on
15086 execution, so create a temporary if an lvalue is
15087 required. */
15088 if (fallback == fb_lvalue)
15090 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
15091 mark_addressable (*expr_p);
15092 ret = GS_OK;
15094 break;
15096 case TREE_LIST:
15097 gcc_unreachable ();
15099 case COMPOUND_EXPR:
15100 ret = gimplify_compound_expr (expr_p, pre_p, fallback != fb_none);
15101 break;
15103 case COMPOUND_LITERAL_EXPR:
15104 ret = gimplify_compound_literal_expr (expr_p, pre_p,
15105 gimple_test_f, fallback);
15106 break;
15108 case MODIFY_EXPR:
15109 case INIT_EXPR:
15110 ret = gimplify_modify_expr (expr_p, pre_p, post_p,
15111 fallback != fb_none);
15112 break;
15114 case TRUTH_ANDIF_EXPR:
15115 case TRUTH_ORIF_EXPR:
15117 /* Preserve the original type of the expression and the
15118 source location of the outer expression. */
15119 tree org_type = TREE_TYPE (*expr_p);
15120 *expr_p = gimple_boolify (*expr_p);
15121 *expr_p = build3_loc (input_location, COND_EXPR,
15122 org_type, *expr_p,
15123 fold_convert_loc
15124 (input_location,
15125 org_type, boolean_true_node),
15126 fold_convert_loc
15127 (input_location,
15128 org_type, boolean_false_node));
15129 ret = GS_OK;
15130 break;
15133 case TRUTH_NOT_EXPR:
15135 tree type = TREE_TYPE (*expr_p);
15136 /* The parsers are careful to generate TRUTH_NOT_EXPR
15137 only with operands that are always zero or one.
15138 We do not fold here but handle the only interesting case
15139 manually, as fold may re-introduce the TRUTH_NOT_EXPR. */
15140 *expr_p = gimple_boolify (*expr_p);
15141 if (TYPE_PRECISION (TREE_TYPE (*expr_p)) == 1)
15142 *expr_p = build1_loc (input_location, BIT_NOT_EXPR,
15143 TREE_TYPE (*expr_p),
15144 TREE_OPERAND (*expr_p, 0));
15145 else
15146 *expr_p = build2_loc (input_location, BIT_XOR_EXPR,
15147 TREE_TYPE (*expr_p),
15148 TREE_OPERAND (*expr_p, 0),
15149 build_int_cst (TREE_TYPE (*expr_p), 1));
15150 if (!useless_type_conversion_p (type, TREE_TYPE (*expr_p)))
15151 *expr_p = fold_convert_loc (input_location, type, *expr_p);
15152 ret = GS_OK;
15153 break;
15156 case ADDR_EXPR:
15157 ret = gimplify_addr_expr (expr_p, pre_p, post_p);
15158 break;
15160 case ANNOTATE_EXPR:
15162 tree cond = TREE_OPERAND (*expr_p, 0);
15163 tree kind = TREE_OPERAND (*expr_p, 1);
15164 tree data = TREE_OPERAND (*expr_p, 2);
15165 tree type = TREE_TYPE (cond);
15166 if (!INTEGRAL_TYPE_P (type))
15168 *expr_p = cond;
15169 ret = GS_OK;
15170 break;
15172 tree tmp = create_tmp_var (type);
15173 gimplify_arg (&cond, pre_p, EXPR_LOCATION (*expr_p));
15174 gcall *call
15175 = gimple_build_call_internal (IFN_ANNOTATE, 3, cond, kind, data);
15176 gimple_call_set_lhs (call, tmp);
15177 gimplify_seq_add_stmt (pre_p, call);
15178 *expr_p = tmp;
15179 ret = GS_ALL_DONE;
15180 break;
15183 case VA_ARG_EXPR:
15184 ret = gimplify_va_arg_expr (expr_p, pre_p, post_p);
15185 break;
15187 CASE_CONVERT:
15188 if (IS_EMPTY_STMT (*expr_p))
15190 ret = GS_ALL_DONE;
15191 break;
15194 if (VOID_TYPE_P (TREE_TYPE (*expr_p))
15195 || fallback == fb_none)
15197 /* Just strip a conversion to void (or in void context) and
15198 try again. */
15199 *expr_p = TREE_OPERAND (*expr_p, 0);
15200 ret = GS_OK;
15201 break;
15204 ret = gimplify_conversion (expr_p);
15205 if (ret == GS_ERROR)
15206 break;
15207 if (*expr_p != save_expr)
15208 break;
15209 /* FALLTHRU */
15211 case FIX_TRUNC_EXPR:
15212 /* unary_expr: ... | '(' cast ')' val | ... */
15213 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
15214 is_gimple_val, fb_rvalue);
15215 recalculate_side_effects (*expr_p);
15216 break;
15218 case INDIRECT_REF:
15220 bool volatilep = TREE_THIS_VOLATILE (*expr_p);
15221 bool notrap = TREE_THIS_NOTRAP (*expr_p);
15222 tree saved_ptr_type = TREE_TYPE (TREE_OPERAND (*expr_p, 0));
15224 *expr_p = fold_indirect_ref_loc (input_location, *expr_p);
15225 if (*expr_p != save_expr)
15227 ret = GS_OK;
15228 break;
15231 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
15232 is_gimple_reg, fb_rvalue);
15233 if (ret == GS_ERROR)
15234 break;
15236 recalculate_side_effects (*expr_p);
15237 *expr_p = fold_build2_loc (input_location, MEM_REF,
15238 TREE_TYPE (*expr_p),
15239 TREE_OPERAND (*expr_p, 0),
15240 build_int_cst (saved_ptr_type, 0));
15241 TREE_THIS_VOLATILE (*expr_p) = volatilep;
15242 TREE_THIS_NOTRAP (*expr_p) = notrap;
15243 ret = GS_OK;
15244 break;
15247 /* We arrive here through the various re-gimplifcation paths. */
15248 case MEM_REF:
15249 /* First try re-folding the whole thing. */
15250 tmp = fold_binary (MEM_REF, TREE_TYPE (*expr_p),
15251 TREE_OPERAND (*expr_p, 0),
15252 TREE_OPERAND (*expr_p, 1));
15253 if (tmp)
15255 REF_REVERSE_STORAGE_ORDER (tmp)
15256 = REF_REVERSE_STORAGE_ORDER (*expr_p);
15257 *expr_p = tmp;
15258 recalculate_side_effects (*expr_p);
15259 ret = GS_OK;
15260 break;
15262 /* Avoid re-gimplifying the address operand if it is already
15263 in suitable form. Re-gimplifying would mark the address
15264 operand addressable. Always gimplify when not in SSA form
15265 as we still may have to gimplify decls with value-exprs. */
15266 if (!gimplify_ctxp || !gimple_in_ssa_p (cfun)
15267 || !is_gimple_mem_ref_addr (TREE_OPERAND (*expr_p, 0)))
15269 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
15270 is_gimple_mem_ref_addr, fb_rvalue);
15271 if (ret == GS_ERROR)
15272 break;
15274 recalculate_side_effects (*expr_p);
15275 ret = GS_ALL_DONE;
15276 break;
15278 /* Constants need not be gimplified. */
15279 case INTEGER_CST:
15280 case REAL_CST:
15281 case FIXED_CST:
15282 case STRING_CST:
15283 case COMPLEX_CST:
15284 case VECTOR_CST:
15285 /* Drop the overflow flag on constants, we do not want
15286 that in the GIMPLE IL. */
15287 if (TREE_OVERFLOW_P (*expr_p))
15288 *expr_p = drop_tree_overflow (*expr_p);
15289 ret = GS_ALL_DONE;
15290 break;
15292 case CONST_DECL:
15293 /* If we require an lvalue, such as for ADDR_EXPR, retain the
15294 CONST_DECL node. Otherwise the decl is replaceable by its
15295 value. */
15296 /* ??? Should be == fb_lvalue, but ADDR_EXPR passes fb_either. */
15297 if (fallback & fb_lvalue)
15298 ret = GS_ALL_DONE;
15299 else
15301 *expr_p = DECL_INITIAL (*expr_p);
15302 ret = GS_OK;
15304 break;
15306 case DECL_EXPR:
15307 ret = gimplify_decl_expr (expr_p, pre_p);
15308 break;
15310 case BIND_EXPR:
15311 ret = gimplify_bind_expr (expr_p, pre_p);
15312 break;
15314 case LOOP_EXPR:
15315 ret = gimplify_loop_expr (expr_p, pre_p);
15316 break;
15318 case SWITCH_EXPR:
15319 ret = gimplify_switch_expr (expr_p, pre_p);
15320 break;
15322 case EXIT_EXPR:
15323 ret = gimplify_exit_expr (expr_p);
15324 break;
15326 case GOTO_EXPR:
15327 /* If the target is not LABEL, then it is a computed jump
15328 and the target needs to be gimplified. */
15329 if (TREE_CODE (GOTO_DESTINATION (*expr_p)) != LABEL_DECL)
15331 ret = gimplify_expr (&GOTO_DESTINATION (*expr_p), pre_p,
15332 NULL, is_gimple_val, fb_rvalue);
15333 if (ret == GS_ERROR)
15334 break;
15336 gimplify_seq_add_stmt (pre_p,
15337 gimple_build_goto (GOTO_DESTINATION (*expr_p)));
15338 ret = GS_ALL_DONE;
15339 break;
15341 case PREDICT_EXPR:
15342 gimplify_seq_add_stmt (pre_p,
15343 gimple_build_predict (PREDICT_EXPR_PREDICTOR (*expr_p),
15344 PREDICT_EXPR_OUTCOME (*expr_p)));
15345 ret = GS_ALL_DONE;
15346 break;
15348 case LABEL_EXPR:
15349 ret = gimplify_label_expr (expr_p, pre_p);
15350 label = LABEL_EXPR_LABEL (*expr_p);
15351 gcc_assert (decl_function_context (label) == current_function_decl);
15353 /* If the label is used in a goto statement, or address of the label
15354 is taken, we need to unpoison all variables that were seen so far.
15355 Doing so would prevent us from reporting a false positives. */
15356 if (asan_poisoned_variables
15357 && asan_used_labels != NULL
15358 && asan_used_labels->contains (label)
15359 && !gimplify_omp_ctxp)
15360 asan_poison_variables (asan_poisoned_variables, false, pre_p);
15361 break;
15363 case CASE_LABEL_EXPR:
15364 ret = gimplify_case_label_expr (expr_p, pre_p);
15366 if (gimplify_ctxp->live_switch_vars)
15367 asan_poison_variables (gimplify_ctxp->live_switch_vars, false,
15368 pre_p);
15369 break;
15371 case RETURN_EXPR:
15372 ret = gimplify_return_expr (*expr_p, pre_p);
15373 break;
15375 case CONSTRUCTOR:
15376 /* Don't reduce this in place; let gimplify_init_constructor work its
15377 magic. Buf if we're just elaborating this for side effects, just
15378 gimplify any element that has side-effects. */
15379 if (fallback == fb_none)
15381 unsigned HOST_WIDE_INT ix;
15382 tree val;
15383 tree temp = NULL_TREE;
15384 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (*expr_p), ix, val)
15385 if (TREE_SIDE_EFFECTS (val))
15386 append_to_statement_list (val, &temp);
15388 *expr_p = temp;
15389 ret = temp ? GS_OK : GS_ALL_DONE;
15391 /* C99 code may assign to an array in a constructed
15392 structure or union, and this has undefined behavior only
15393 on execution, so create a temporary if an lvalue is
15394 required. */
15395 else if (fallback == fb_lvalue)
15397 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
15398 mark_addressable (*expr_p);
15399 ret = GS_OK;
15401 else
15402 ret = GS_ALL_DONE;
15403 break;
15405 /* The following are special cases that are not handled by the
15406 original GIMPLE grammar. */
15408 /* SAVE_EXPR nodes are converted into a GIMPLE identifier and
15409 eliminated. */
15410 case SAVE_EXPR:
15411 ret = gimplify_save_expr (expr_p, pre_p, post_p);
15412 break;
15414 case BIT_FIELD_REF:
15415 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15416 post_p, is_gimple_lvalue, fb_either);
15417 recalculate_side_effects (*expr_p);
15418 break;
15420 case TARGET_MEM_REF:
15422 enum gimplify_status r0 = GS_ALL_DONE, r1 = GS_ALL_DONE;
15424 if (TMR_BASE (*expr_p))
15425 r0 = gimplify_expr (&TMR_BASE (*expr_p), pre_p,
15426 post_p, is_gimple_mem_ref_addr, fb_either);
15427 if (TMR_INDEX (*expr_p))
15428 r1 = gimplify_expr (&TMR_INDEX (*expr_p), pre_p,
15429 post_p, is_gimple_val, fb_rvalue);
15430 if (TMR_INDEX2 (*expr_p))
15431 r1 = gimplify_expr (&TMR_INDEX2 (*expr_p), pre_p,
15432 post_p, is_gimple_val, fb_rvalue);
15433 /* TMR_STEP and TMR_OFFSET are always integer constants. */
15434 ret = MIN (r0, r1);
15436 break;
15438 case NON_LVALUE_EXPR:
15439 /* This should have been stripped above. */
15440 gcc_unreachable ();
15442 case ASM_EXPR:
15443 ret = gimplify_asm_expr (expr_p, pre_p, post_p);
15444 break;
15446 case TRY_FINALLY_EXPR:
15447 case TRY_CATCH_EXPR:
15449 gimple_seq eval, cleanup;
15450 gtry *try_;
15452 /* Calls to destructors are generated automatically in FINALLY/CATCH
15453 block. They should have location as UNKNOWN_LOCATION. However,
15454 gimplify_call_expr will reset these call stmts to input_location
15455 if it finds stmt's location is unknown. To prevent resetting for
15456 destructors, we set the input_location to unknown.
15457 Note that this only affects the destructor calls in FINALLY/CATCH
15458 block, and will automatically reset to its original value by the
15459 end of gimplify_expr. */
15460 input_location = UNKNOWN_LOCATION;
15461 eval = cleanup = NULL;
15462 gimplify_and_add (TREE_OPERAND (*expr_p, 0), &eval);
15463 if (TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
15464 && TREE_CODE (TREE_OPERAND (*expr_p, 1)) == EH_ELSE_EXPR)
15466 gimple_seq n = NULL, e = NULL;
15467 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1),
15468 0), &n);
15469 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1),
15470 1), &e);
15471 if (!gimple_seq_empty_p (n) && !gimple_seq_empty_p (e))
15473 geh_else *stmt = gimple_build_eh_else (n, e);
15474 gimple_seq_add_stmt (&cleanup, stmt);
15477 else
15478 gimplify_and_add (TREE_OPERAND (*expr_p, 1), &cleanup);
15479 /* Don't create bogus GIMPLE_TRY with empty cleanup. */
15480 if (gimple_seq_empty_p (cleanup))
15482 gimple_seq_add_seq (pre_p, eval);
15483 ret = GS_ALL_DONE;
15484 break;
15486 try_ = gimple_build_try (eval, cleanup,
15487 TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
15488 ? GIMPLE_TRY_FINALLY
15489 : GIMPLE_TRY_CATCH);
15490 if (EXPR_HAS_LOCATION (save_expr))
15491 gimple_set_location (try_, EXPR_LOCATION (save_expr));
15492 else if (LOCATION_LOCUS (saved_location) != UNKNOWN_LOCATION)
15493 gimple_set_location (try_, saved_location);
15494 if (TREE_CODE (*expr_p) == TRY_CATCH_EXPR)
15495 gimple_try_set_catch_is_cleanup (try_,
15496 TRY_CATCH_IS_CLEANUP (*expr_p));
15497 gimplify_seq_add_stmt (pre_p, try_);
15498 ret = GS_ALL_DONE;
15499 break;
15502 case CLEANUP_POINT_EXPR:
15503 ret = gimplify_cleanup_point_expr (expr_p, pre_p);
15504 break;
15506 case TARGET_EXPR:
15507 ret = gimplify_target_expr (expr_p, pre_p, post_p);
15508 break;
15510 case CATCH_EXPR:
15512 gimple *c;
15513 gimple_seq handler = NULL;
15514 gimplify_and_add (CATCH_BODY (*expr_p), &handler);
15515 c = gimple_build_catch (CATCH_TYPES (*expr_p), handler);
15516 gimplify_seq_add_stmt (pre_p, c);
15517 ret = GS_ALL_DONE;
15518 break;
15521 case EH_FILTER_EXPR:
15523 gimple *ehf;
15524 gimple_seq failure = NULL;
15526 gimplify_and_add (EH_FILTER_FAILURE (*expr_p), &failure);
15527 ehf = gimple_build_eh_filter (EH_FILTER_TYPES (*expr_p), failure);
15528 copy_warning (ehf, *expr_p);
15529 gimplify_seq_add_stmt (pre_p, ehf);
15530 ret = GS_ALL_DONE;
15531 break;
15534 case OBJ_TYPE_REF:
15536 enum gimplify_status r0, r1;
15537 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p,
15538 post_p, is_gimple_val, fb_rvalue);
15539 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p,
15540 post_p, is_gimple_val, fb_rvalue);
15541 TREE_SIDE_EFFECTS (*expr_p) = 0;
15542 ret = MIN (r0, r1);
15544 break;
15546 case LABEL_DECL:
15547 /* We get here when taking the address of a label. We mark
15548 the label as "forced"; meaning it can never be removed and
15549 it is a potential target for any computed goto. */
15550 FORCED_LABEL (*expr_p) = 1;
15551 ret = GS_ALL_DONE;
15552 break;
15554 case STATEMENT_LIST:
15555 ret = gimplify_statement_list (expr_p, pre_p);
15556 break;
15558 case WITH_SIZE_EXPR:
15560 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15561 post_p == &internal_post ? NULL : post_p,
15562 gimple_test_f, fallback);
15563 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
15564 is_gimple_val, fb_rvalue);
15565 ret = GS_ALL_DONE;
15567 break;
15569 case VAR_DECL:
15570 case PARM_DECL:
15571 ret = gimplify_var_or_parm_decl (expr_p);
15572 break;
15574 case RESULT_DECL:
15575 /* When within an OMP context, notice uses of variables. */
15576 if (gimplify_omp_ctxp)
15577 omp_notice_variable (gimplify_omp_ctxp, *expr_p, true);
15578 ret = GS_ALL_DONE;
15579 break;
15581 case DEBUG_EXPR_DECL:
15582 gcc_unreachable ();
15584 case DEBUG_BEGIN_STMT:
15585 gimplify_seq_add_stmt (pre_p,
15586 gimple_build_debug_begin_stmt
15587 (TREE_BLOCK (*expr_p),
15588 EXPR_LOCATION (*expr_p)));
15589 ret = GS_ALL_DONE;
15590 *expr_p = NULL;
15591 break;
15593 case SSA_NAME:
15594 /* Allow callbacks into the gimplifier during optimization. */
15595 ret = GS_ALL_DONE;
15596 break;
15598 case OMP_PARALLEL:
15599 gimplify_omp_parallel (expr_p, pre_p);
15600 ret = GS_ALL_DONE;
15601 break;
15603 case OMP_TASK:
15604 gimplify_omp_task (expr_p, pre_p);
15605 ret = GS_ALL_DONE;
15606 break;
15608 case OMP_SIMD:
15610 /* Temporarily disable into_ssa, as scan_omp_simd
15611 which calls copy_gimple_seq_and_replace_locals can't deal
15612 with SSA_NAMEs defined outside of the body properly. */
15613 bool saved_into_ssa = gimplify_ctxp->into_ssa;
15614 gimplify_ctxp->into_ssa = false;
15615 ret = gimplify_omp_for (expr_p, pre_p);
15616 gimplify_ctxp->into_ssa = saved_into_ssa;
15617 break;
15620 case OMP_FOR:
15621 case OMP_DISTRIBUTE:
15622 case OMP_TASKLOOP:
15623 case OACC_LOOP:
15624 ret = gimplify_omp_for (expr_p, pre_p);
15625 break;
15627 case OMP_LOOP:
15628 ret = gimplify_omp_loop (expr_p, pre_p);
15629 break;
15631 case OACC_CACHE:
15632 gimplify_oacc_cache (expr_p, pre_p);
15633 ret = GS_ALL_DONE;
15634 break;
15636 case OACC_DECLARE:
15637 gimplify_oacc_declare (expr_p, pre_p);
15638 ret = GS_ALL_DONE;
15639 break;
15641 case OACC_HOST_DATA:
15642 case OACC_DATA:
15643 case OACC_KERNELS:
15644 case OACC_PARALLEL:
15645 case OACC_SERIAL:
15646 case OMP_SCOPE:
15647 case OMP_SECTIONS:
15648 case OMP_SINGLE:
15649 case OMP_TARGET:
15650 case OMP_TARGET_DATA:
15651 case OMP_TEAMS:
15652 gimplify_omp_workshare (expr_p, pre_p);
15653 ret = GS_ALL_DONE;
15654 break;
15656 case OACC_ENTER_DATA:
15657 case OACC_EXIT_DATA:
15658 case OACC_UPDATE:
15659 case OMP_TARGET_UPDATE:
15660 case OMP_TARGET_ENTER_DATA:
15661 case OMP_TARGET_EXIT_DATA:
15662 gimplify_omp_target_update (expr_p, pre_p);
15663 ret = GS_ALL_DONE;
15664 break;
15666 case OMP_SECTION:
15667 case OMP_MASTER:
15668 case OMP_MASKED:
15669 case OMP_ORDERED:
15670 case OMP_CRITICAL:
15671 case OMP_SCAN:
15673 gimple_seq body = NULL;
15674 gimple *g;
15675 bool saved_in_omp_construct = in_omp_construct;
15677 in_omp_construct = true;
15678 gimplify_and_add (OMP_BODY (*expr_p), &body);
15679 in_omp_construct = saved_in_omp_construct;
15680 switch (TREE_CODE (*expr_p))
15682 case OMP_SECTION:
15683 g = gimple_build_omp_section (body);
15684 break;
15685 case OMP_MASTER:
15686 g = gimple_build_omp_master (body);
15687 break;
15688 case OMP_ORDERED:
15689 g = gimplify_omp_ordered (*expr_p, body);
15690 break;
15691 case OMP_MASKED:
15692 gimplify_scan_omp_clauses (&OMP_MASKED_CLAUSES (*expr_p),
15693 pre_p, ORT_WORKSHARE, OMP_MASKED);
15694 gimplify_adjust_omp_clauses (pre_p, body,
15695 &OMP_MASKED_CLAUSES (*expr_p),
15696 OMP_MASKED);
15697 g = gimple_build_omp_masked (body,
15698 OMP_MASKED_CLAUSES (*expr_p));
15699 break;
15700 case OMP_CRITICAL:
15701 gimplify_scan_omp_clauses (&OMP_CRITICAL_CLAUSES (*expr_p),
15702 pre_p, ORT_WORKSHARE, OMP_CRITICAL);
15703 gimplify_adjust_omp_clauses (pre_p, body,
15704 &OMP_CRITICAL_CLAUSES (*expr_p),
15705 OMP_CRITICAL);
15706 g = gimple_build_omp_critical (body,
15707 OMP_CRITICAL_NAME (*expr_p),
15708 OMP_CRITICAL_CLAUSES (*expr_p));
15709 break;
15710 case OMP_SCAN:
15711 gimplify_scan_omp_clauses (&OMP_SCAN_CLAUSES (*expr_p),
15712 pre_p, ORT_WORKSHARE, OMP_SCAN);
15713 gimplify_adjust_omp_clauses (pre_p, body,
15714 &OMP_SCAN_CLAUSES (*expr_p),
15715 OMP_SCAN);
15716 g = gimple_build_omp_scan (body, OMP_SCAN_CLAUSES (*expr_p));
15717 break;
15718 default:
15719 gcc_unreachable ();
15721 gimplify_seq_add_stmt (pre_p, g);
15722 ret = GS_ALL_DONE;
15723 break;
15726 case OMP_TASKGROUP:
15728 gimple_seq body = NULL;
15730 tree *pclauses = &OMP_TASKGROUP_CLAUSES (*expr_p);
15731 bool saved_in_omp_construct = in_omp_construct;
15732 gimplify_scan_omp_clauses (pclauses, pre_p, ORT_TASKGROUP,
15733 OMP_TASKGROUP);
15734 gimplify_adjust_omp_clauses (pre_p, NULL, pclauses, OMP_TASKGROUP);
15736 in_omp_construct = true;
15737 gimplify_and_add (OMP_BODY (*expr_p), &body);
15738 in_omp_construct = saved_in_omp_construct;
15739 gimple_seq cleanup = NULL;
15740 tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_END);
15741 gimple *g = gimple_build_call (fn, 0);
15742 gimple_seq_add_stmt (&cleanup, g);
15743 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
15744 body = NULL;
15745 gimple_seq_add_stmt (&body, g);
15746 g = gimple_build_omp_taskgroup (body, *pclauses);
15747 gimplify_seq_add_stmt (pre_p, g);
15748 ret = GS_ALL_DONE;
15749 break;
15752 case OMP_ATOMIC:
15753 case OMP_ATOMIC_READ:
15754 case OMP_ATOMIC_CAPTURE_OLD:
15755 case OMP_ATOMIC_CAPTURE_NEW:
15756 ret = gimplify_omp_atomic (expr_p, pre_p);
15757 break;
15759 case TRANSACTION_EXPR:
15760 ret = gimplify_transaction (expr_p, pre_p);
15761 break;
15763 case TRUTH_AND_EXPR:
15764 case TRUTH_OR_EXPR:
15765 case TRUTH_XOR_EXPR:
15767 tree orig_type = TREE_TYPE (*expr_p);
15768 tree new_type, xop0, xop1;
15769 *expr_p = gimple_boolify (*expr_p);
15770 new_type = TREE_TYPE (*expr_p);
15771 if (!useless_type_conversion_p (orig_type, new_type))
15773 *expr_p = fold_convert_loc (input_location, orig_type, *expr_p);
15774 ret = GS_OK;
15775 break;
15778 /* Boolified binary truth expressions are semantically equivalent
15779 to bitwise binary expressions. Canonicalize them to the
15780 bitwise variant. */
15781 switch (TREE_CODE (*expr_p))
15783 case TRUTH_AND_EXPR:
15784 TREE_SET_CODE (*expr_p, BIT_AND_EXPR);
15785 break;
15786 case TRUTH_OR_EXPR:
15787 TREE_SET_CODE (*expr_p, BIT_IOR_EXPR);
15788 break;
15789 case TRUTH_XOR_EXPR:
15790 TREE_SET_CODE (*expr_p, BIT_XOR_EXPR);
15791 break;
15792 default:
15793 break;
15795 /* Now make sure that operands have compatible type to
15796 expression's new_type. */
15797 xop0 = TREE_OPERAND (*expr_p, 0);
15798 xop1 = TREE_OPERAND (*expr_p, 1);
15799 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop0)))
15800 TREE_OPERAND (*expr_p, 0) = fold_convert_loc (input_location,
15801 new_type,
15802 xop0);
15803 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop1)))
15804 TREE_OPERAND (*expr_p, 1) = fold_convert_loc (input_location,
15805 new_type,
15806 xop1);
15807 /* Continue classified as tcc_binary. */
15808 goto expr_2;
15811 case VEC_COND_EXPR:
15812 goto expr_3;
15814 case VEC_PERM_EXPR:
15815 /* Classified as tcc_expression. */
15816 goto expr_3;
15818 case BIT_INSERT_EXPR:
15819 /* Argument 3 is a constant. */
15820 goto expr_2;
15822 case POINTER_PLUS_EXPR:
15824 enum gimplify_status r0, r1;
15825 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15826 post_p, is_gimple_val, fb_rvalue);
15827 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
15828 post_p, is_gimple_val, fb_rvalue);
15829 recalculate_side_effects (*expr_p);
15830 ret = MIN (r0, r1);
15831 break;
15834 default:
15835 switch (TREE_CODE_CLASS (TREE_CODE (*expr_p)))
15837 case tcc_comparison:
15838 /* Handle comparison of objects of non scalar mode aggregates
15839 with a call to memcmp. It would be nice to only have to do
15840 this for variable-sized objects, but then we'd have to allow
15841 the same nest of reference nodes we allow for MODIFY_EXPR and
15842 that's too complex.
15844 Compare scalar mode aggregates as scalar mode values. Using
15845 memcmp for them would be very inefficient at best, and is
15846 plain wrong if bitfields are involved. */
15848 tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 1));
15850 /* Vector comparisons need no boolification. */
15851 if (TREE_CODE (type) == VECTOR_TYPE)
15852 goto expr_2;
15853 else if (!AGGREGATE_TYPE_P (type))
15855 tree org_type = TREE_TYPE (*expr_p);
15856 *expr_p = gimple_boolify (*expr_p);
15857 if (!useless_type_conversion_p (org_type,
15858 TREE_TYPE (*expr_p)))
15860 *expr_p = fold_convert_loc (input_location,
15861 org_type, *expr_p);
15862 ret = GS_OK;
15864 else
15865 goto expr_2;
15867 else if (TYPE_MODE (type) != BLKmode)
15868 ret = gimplify_scalar_mode_aggregate_compare (expr_p);
15869 else
15870 ret = gimplify_variable_sized_compare (expr_p);
15872 break;
15875 /* If *EXPR_P does not need to be special-cased, handle it
15876 according to its class. */
15877 case tcc_unary:
15878 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15879 post_p, is_gimple_val, fb_rvalue);
15880 break;
15882 case tcc_binary:
15883 expr_2:
15885 enum gimplify_status r0, r1;
15887 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15888 post_p, is_gimple_val, fb_rvalue);
15889 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
15890 post_p, is_gimple_val, fb_rvalue);
15892 ret = MIN (r0, r1);
15893 break;
15896 expr_3:
15898 enum gimplify_status r0, r1, r2;
15900 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15901 post_p, is_gimple_val, fb_rvalue);
15902 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
15903 post_p, is_gimple_val, fb_rvalue);
15904 r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p,
15905 post_p, is_gimple_val, fb_rvalue);
15907 ret = MIN (MIN (r0, r1), r2);
15908 break;
15911 case tcc_declaration:
15912 case tcc_constant:
15913 ret = GS_ALL_DONE;
15914 goto dont_recalculate;
15916 default:
15917 gcc_unreachable ();
15920 recalculate_side_effects (*expr_p);
15922 dont_recalculate:
15923 break;
15926 gcc_assert (*expr_p || ret != GS_OK);
15928 while (ret == GS_OK);
15930 /* If we encountered an error_mark somewhere nested inside, either
15931 stub out the statement or propagate the error back out. */
15932 if (ret == GS_ERROR)
15934 if (is_statement)
15935 *expr_p = NULL;
15936 goto out;
15939 /* This was only valid as a return value from the langhook, which
15940 we handled. Make sure it doesn't escape from any other context. */
15941 gcc_assert (ret != GS_UNHANDLED);
15943 if (fallback == fb_none && *expr_p && !is_gimple_stmt (*expr_p))
15945 /* We aren't looking for a value, and we don't have a valid
15946 statement. If it doesn't have side-effects, throw it away.
15947 We can also get here with code such as "*&&L;", where L is
15948 a LABEL_DECL that is marked as FORCED_LABEL. */
15949 if (TREE_CODE (*expr_p) == LABEL_DECL
15950 || !TREE_SIDE_EFFECTS (*expr_p))
15951 *expr_p = NULL;
15952 else if (!TREE_THIS_VOLATILE (*expr_p))
15954 /* This is probably a _REF that contains something nested that
15955 has side effects. Recurse through the operands to find it. */
15956 enum tree_code code = TREE_CODE (*expr_p);
15958 switch (code)
15960 case COMPONENT_REF:
15961 case REALPART_EXPR:
15962 case IMAGPART_EXPR:
15963 case VIEW_CONVERT_EXPR:
15964 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
15965 gimple_test_f, fallback);
15966 break;
15968 case ARRAY_REF:
15969 case ARRAY_RANGE_REF:
15970 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
15971 gimple_test_f, fallback);
15972 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
15973 gimple_test_f, fallback);
15974 break;
15976 default:
15977 /* Anything else with side-effects must be converted to
15978 a valid statement before we get here. */
15979 gcc_unreachable ();
15982 *expr_p = NULL;
15984 else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p))
15985 && TYPE_MODE (TREE_TYPE (*expr_p)) != BLKmode
15986 && !is_empty_type (TREE_TYPE (*expr_p)))
15988 /* Historically, the compiler has treated a bare reference
15989 to a non-BLKmode volatile lvalue as forcing a load. */
15990 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p));
15992 /* Normally, we do not want to create a temporary for a
15993 TREE_ADDRESSABLE type because such a type should not be
15994 copied by bitwise-assignment. However, we make an
15995 exception here, as all we are doing here is ensuring that
15996 we read the bytes that make up the type. We use
15997 create_tmp_var_raw because create_tmp_var will abort when
15998 given a TREE_ADDRESSABLE type. */
15999 tree tmp = create_tmp_var_raw (type, "vol");
16000 gimple_add_tmp_var (tmp);
16001 gimplify_assign (tmp, *expr_p, pre_p);
16002 *expr_p = NULL;
16004 else
16005 /* We can't do anything useful with a volatile reference to
16006 an incomplete type, so just throw it away. Likewise for
16007 a BLKmode type, since any implicit inner load should
16008 already have been turned into an explicit one by the
16009 gimplification process. */
16010 *expr_p = NULL;
16013 /* If we are gimplifying at the statement level, we're done. Tack
16014 everything together and return. */
16015 if (fallback == fb_none || is_statement)
16017 /* Since *EXPR_P has been converted into a GIMPLE tuple, clear
16018 it out for GC to reclaim it. */
16019 *expr_p = NULL_TREE;
16021 if (!gimple_seq_empty_p (internal_pre)
16022 || !gimple_seq_empty_p (internal_post))
16024 gimplify_seq_add_seq (&internal_pre, internal_post);
16025 gimplify_seq_add_seq (pre_p, internal_pre);
16028 /* The result of gimplifying *EXPR_P is going to be the last few
16029 statements in *PRE_P and *POST_P. Add location information
16030 to all the statements that were added by the gimplification
16031 helpers. */
16032 if (!gimple_seq_empty_p (*pre_p))
16033 annotate_all_with_location_after (*pre_p, pre_last_gsi, input_location);
16035 if (!gimple_seq_empty_p (*post_p))
16036 annotate_all_with_location_after (*post_p, post_last_gsi,
16037 input_location);
16039 goto out;
16042 #ifdef ENABLE_GIMPLE_CHECKING
16043 if (*expr_p)
16045 enum tree_code code = TREE_CODE (*expr_p);
16046 /* These expressions should already be in gimple IR form. */
16047 gcc_assert (code != MODIFY_EXPR
16048 && code != ASM_EXPR
16049 && code != BIND_EXPR
16050 && code != CATCH_EXPR
16051 && (code != COND_EXPR || gimplify_ctxp->allow_rhs_cond_expr)
16052 && code != EH_FILTER_EXPR
16053 && code != GOTO_EXPR
16054 && code != LABEL_EXPR
16055 && code != LOOP_EXPR
16056 && code != SWITCH_EXPR
16057 && code != TRY_FINALLY_EXPR
16058 && code != EH_ELSE_EXPR
16059 && code != OACC_PARALLEL
16060 && code != OACC_KERNELS
16061 && code != OACC_SERIAL
16062 && code != OACC_DATA
16063 && code != OACC_HOST_DATA
16064 && code != OACC_DECLARE
16065 && code != OACC_UPDATE
16066 && code != OACC_ENTER_DATA
16067 && code != OACC_EXIT_DATA
16068 && code != OACC_CACHE
16069 && code != OMP_CRITICAL
16070 && code != OMP_FOR
16071 && code != OACC_LOOP
16072 && code != OMP_MASTER
16073 && code != OMP_MASKED
16074 && code != OMP_TASKGROUP
16075 && code != OMP_ORDERED
16076 && code != OMP_PARALLEL
16077 && code != OMP_SCAN
16078 && code != OMP_SECTIONS
16079 && code != OMP_SECTION
16080 && code != OMP_SINGLE
16081 && code != OMP_SCOPE);
16083 #endif
16085 /* Otherwise we're gimplifying a subexpression, so the resulting
16086 value is interesting. If it's a valid operand that matches
16087 GIMPLE_TEST_F, we're done. Unless we are handling some
16088 post-effects internally; if that's the case, we need to copy into
16089 a temporary before adding the post-effects to POST_P. */
16090 if (gimple_seq_empty_p (internal_post) && (*gimple_test_f) (*expr_p))
16091 goto out;
16093 /* Otherwise, we need to create a new temporary for the gimplified
16094 expression. */
16096 /* We can't return an lvalue if we have an internal postqueue. The
16097 object the lvalue refers to would (probably) be modified by the
16098 postqueue; we need to copy the value out first, which means an
16099 rvalue. */
16100 if ((fallback & fb_lvalue)
16101 && gimple_seq_empty_p (internal_post)
16102 && is_gimple_addressable (*expr_p))
16104 /* An lvalue will do. Take the address of the expression, store it
16105 in a temporary, and replace the expression with an INDIRECT_REF of
16106 that temporary. */
16107 tree ref_alias_type = reference_alias_ptr_type (*expr_p);
16108 unsigned int ref_align = get_object_alignment (*expr_p);
16109 tree ref_type = TREE_TYPE (*expr_p);
16110 tmp = build_fold_addr_expr_loc (input_location, *expr_p);
16111 gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue);
16112 if (TYPE_ALIGN (ref_type) != ref_align)
16113 ref_type = build_aligned_type (ref_type, ref_align);
16114 *expr_p = build2 (MEM_REF, ref_type,
16115 tmp, build_zero_cst (ref_alias_type));
16117 else if ((fallback & fb_rvalue) && is_gimple_reg_rhs_or_call (*expr_p))
16119 /* An rvalue will do. Assign the gimplified expression into a
16120 new temporary TMP and replace the original expression with
16121 TMP. First, make sure that the expression has a type so that
16122 it can be assigned into a temporary. */
16123 gcc_assert (!VOID_TYPE_P (TREE_TYPE (*expr_p)));
16124 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
16126 else
16128 #ifdef ENABLE_GIMPLE_CHECKING
16129 if (!(fallback & fb_mayfail))
16131 fprintf (stderr, "gimplification failed:\n");
16132 print_generic_expr (stderr, *expr_p);
16133 debug_tree (*expr_p);
16134 internal_error ("gimplification failed");
16136 #endif
16137 gcc_assert (fallback & fb_mayfail);
16139 /* If this is an asm statement, and the user asked for the
16140 impossible, don't die. Fail and let gimplify_asm_expr
16141 issue an error. */
16142 ret = GS_ERROR;
16143 goto out;
16146 /* Make sure the temporary matches our predicate. */
16147 gcc_assert ((*gimple_test_f) (*expr_p));
16149 if (!gimple_seq_empty_p (internal_post))
16151 annotate_all_with_location (internal_post, input_location);
16152 gimplify_seq_add_seq (pre_p, internal_post);
16155 out:
16156 input_location = saved_location;
16157 return ret;
16160 /* Like gimplify_expr but make sure the gimplified result is not itself
16161 a SSA name (but a decl if it were). Temporaries required by
16162 evaluating *EXPR_P may be still SSA names. */
16164 static enum gimplify_status
16165 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
16166 bool (*gimple_test_f) (tree), fallback_t fallback,
16167 bool allow_ssa)
16169 enum gimplify_status ret = gimplify_expr (expr_p, pre_p, post_p,
16170 gimple_test_f, fallback);
16171 if (! allow_ssa
16172 && TREE_CODE (*expr_p) == SSA_NAME)
16173 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, NULL, false);
16174 return ret;
16177 /* Look through TYPE for variable-sized objects and gimplify each such
16178 size that we find. Add to LIST_P any statements generated. */
16180 void
16181 gimplify_type_sizes (tree type, gimple_seq *list_p)
16183 if (type == NULL || type == error_mark_node)
16184 return;
16186 const bool ignored_p
16187 = TYPE_NAME (type)
16188 && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
16189 && DECL_IGNORED_P (TYPE_NAME (type));
16190 tree t;
16192 /* We first do the main variant, then copy into any other variants. */
16193 type = TYPE_MAIN_VARIANT (type);
16195 /* Avoid infinite recursion. */
16196 if (TYPE_SIZES_GIMPLIFIED (type))
16197 return;
16199 TYPE_SIZES_GIMPLIFIED (type) = 1;
16201 switch (TREE_CODE (type))
16203 case INTEGER_TYPE:
16204 case ENUMERAL_TYPE:
16205 case BOOLEAN_TYPE:
16206 case REAL_TYPE:
16207 case FIXED_POINT_TYPE:
16208 gimplify_one_sizepos (&TYPE_MIN_VALUE (type), list_p);
16209 gimplify_one_sizepos (&TYPE_MAX_VALUE (type), list_p);
16211 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
16213 TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type);
16214 TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type);
16216 break;
16218 case ARRAY_TYPE:
16219 /* These types may not have declarations, so handle them here. */
16220 gimplify_type_sizes (TREE_TYPE (type), list_p);
16221 gimplify_type_sizes (TYPE_DOMAIN (type), list_p);
16222 /* Ensure VLA bounds aren't removed, for -O0 they should be variables
16223 with assigned stack slots, for -O1+ -g they should be tracked
16224 by VTA. */
16225 if (!ignored_p
16226 && TYPE_DOMAIN (type)
16227 && INTEGRAL_TYPE_P (TYPE_DOMAIN (type)))
16229 t = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
16230 if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
16231 DECL_IGNORED_P (t) = 0;
16232 t = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
16233 if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
16234 DECL_IGNORED_P (t) = 0;
16236 break;
16238 case RECORD_TYPE:
16239 case UNION_TYPE:
16240 case QUAL_UNION_TYPE:
16241 for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
16242 if (TREE_CODE (field) == FIELD_DECL)
16244 gimplify_one_sizepos (&DECL_FIELD_OFFSET (field), list_p);
16245 /* Likewise, ensure variable offsets aren't removed. */
16246 if (!ignored_p
16247 && (t = DECL_FIELD_OFFSET (field))
16248 && VAR_P (t)
16249 && DECL_ARTIFICIAL (t))
16250 DECL_IGNORED_P (t) = 0;
16251 gimplify_one_sizepos (&DECL_SIZE (field), list_p);
16252 gimplify_one_sizepos (&DECL_SIZE_UNIT (field), list_p);
16253 gimplify_type_sizes (TREE_TYPE (field), list_p);
16255 break;
16257 case POINTER_TYPE:
16258 case REFERENCE_TYPE:
16259 /* We used to recurse on the pointed-to type here, which turned out to
16260 be incorrect because its definition might refer to variables not
16261 yet initialized at this point if a forward declaration is involved.
16263 It was actually useful for anonymous pointed-to types to ensure
16264 that the sizes evaluation dominates every possible later use of the
16265 values. Restricting to such types here would be safe since there
16266 is no possible forward declaration around, but would introduce an
16267 undesirable middle-end semantic to anonymity. We then defer to
16268 front-ends the responsibility of ensuring that the sizes are
16269 evaluated both early and late enough, e.g. by attaching artificial
16270 type declarations to the tree. */
16271 break;
16273 default:
16274 break;
16277 gimplify_one_sizepos (&TYPE_SIZE (type), list_p);
16278 gimplify_one_sizepos (&TYPE_SIZE_UNIT (type), list_p);
16280 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
16282 TYPE_SIZE (t) = TYPE_SIZE (type);
16283 TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (type);
16284 TYPE_SIZES_GIMPLIFIED (t) = 1;
16288 /* A subroutine of gimplify_type_sizes to make sure that *EXPR_P,
16289 a size or position, has had all of its SAVE_EXPRs evaluated.
16290 We add any required statements to *STMT_P. */
16292 void
16293 gimplify_one_sizepos (tree *expr_p, gimple_seq *stmt_p)
16295 tree expr = *expr_p;
16297 /* We don't do anything if the value isn't there, is constant, or contains
16298 A PLACEHOLDER_EXPR. We also don't want to do anything if it's already
16299 a VAR_DECL. If it's a VAR_DECL from another function, the gimplifier
16300 will want to replace it with a new variable, but that will cause problems
16301 if this type is from outside the function. It's OK to have that here. */
16302 if (expr == NULL_TREE
16303 || is_gimple_constant (expr)
16304 || TREE_CODE (expr) == VAR_DECL
16305 || CONTAINS_PLACEHOLDER_P (expr))
16306 return;
16308 *expr_p = unshare_expr (expr);
16310 /* SSA names in decl/type fields are a bad idea - they'll get reclaimed
16311 if the def vanishes. */
16312 gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue, false);
16314 /* If expr wasn't already is_gimple_sizepos or is_gimple_constant from the
16315 FE, ensure that it is a VAR_DECL, otherwise we might handle some decls
16316 as gimplify_vla_decl even when they would have all sizes INTEGER_CSTs. */
16317 if (is_gimple_constant (*expr_p))
16318 *expr_p = get_initialized_tmp_var (*expr_p, stmt_p, NULL, false);
16321 /* Gimplify the body of statements of FNDECL and return a GIMPLE_BIND node
16322 containing the sequence of corresponding GIMPLE statements. If DO_PARMS
16323 is true, also gimplify the parameters. */
16325 gbind *
16326 gimplify_body (tree fndecl, bool do_parms)
16328 location_t saved_location = input_location;
16329 gimple_seq parm_stmts, parm_cleanup = NULL, seq;
16330 gimple *outer_stmt;
16331 gbind *outer_bind;
16333 timevar_push (TV_TREE_GIMPLIFY);
16335 init_tree_ssa (cfun);
16337 /* Initialize for optimize_insn_for_s{ize,peed}_p possibly called during
16338 gimplification. */
16339 default_rtl_profile ();
16341 gcc_assert (gimplify_ctxp == NULL);
16342 push_gimplify_context (true);
16344 if (flag_openacc || flag_openmp)
16346 gcc_assert (gimplify_omp_ctxp == NULL);
16347 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (fndecl)))
16348 gimplify_omp_ctxp = new_omp_context (ORT_IMPLICIT_TARGET);
16351 /* Unshare most shared trees in the body and in that of any nested functions.
16352 It would seem we don't have to do this for nested functions because
16353 they are supposed to be output and then the outer function gimplified
16354 first, but the g++ front end doesn't always do it that way. */
16355 unshare_body (fndecl);
16356 unvisit_body (fndecl);
16358 /* Make sure input_location isn't set to something weird. */
16359 input_location = DECL_SOURCE_LOCATION (fndecl);
16361 /* Resolve callee-copies. This has to be done before processing
16362 the body so that DECL_VALUE_EXPR gets processed correctly. */
16363 parm_stmts = do_parms ? gimplify_parameters (&parm_cleanup) : NULL;
16365 /* Gimplify the function's body. */
16366 seq = NULL;
16367 gimplify_stmt (&DECL_SAVED_TREE (fndecl), &seq);
16368 outer_stmt = gimple_seq_first_nondebug_stmt (seq);
16369 if (!outer_stmt)
16371 outer_stmt = gimple_build_nop ();
16372 gimplify_seq_add_stmt (&seq, outer_stmt);
16375 /* The body must contain exactly one statement, a GIMPLE_BIND. If this is
16376 not the case, wrap everything in a GIMPLE_BIND to make it so. */
16377 if (gimple_code (outer_stmt) == GIMPLE_BIND
16378 && (gimple_seq_first_nondebug_stmt (seq)
16379 == gimple_seq_last_nondebug_stmt (seq)))
16381 outer_bind = as_a <gbind *> (outer_stmt);
16382 if (gimple_seq_first_stmt (seq) != outer_stmt
16383 || gimple_seq_last_stmt (seq) != outer_stmt)
16385 /* If there are debug stmts before or after outer_stmt, move them
16386 inside of outer_bind body. */
16387 gimple_stmt_iterator gsi = gsi_for_stmt (outer_stmt, &seq);
16388 gimple_seq second_seq = NULL;
16389 if (gimple_seq_first_stmt (seq) != outer_stmt
16390 && gimple_seq_last_stmt (seq) != outer_stmt)
16392 second_seq = gsi_split_seq_after (gsi);
16393 gsi_remove (&gsi, false);
16395 else if (gimple_seq_first_stmt (seq) != outer_stmt)
16396 gsi_remove (&gsi, false);
16397 else
16399 gsi_remove (&gsi, false);
16400 second_seq = seq;
16401 seq = NULL;
16403 gimple_seq_add_seq_without_update (&seq,
16404 gimple_bind_body (outer_bind));
16405 gimple_seq_add_seq_without_update (&seq, second_seq);
16406 gimple_bind_set_body (outer_bind, seq);
16409 else
16410 outer_bind = gimple_build_bind (NULL_TREE, seq, NULL);
16412 DECL_SAVED_TREE (fndecl) = NULL_TREE;
16414 /* If we had callee-copies statements, insert them at the beginning
16415 of the function and clear DECL_VALUE_EXPR_P on the parameters. */
16416 if (!gimple_seq_empty_p (parm_stmts))
16418 tree parm;
16420 gimplify_seq_add_seq (&parm_stmts, gimple_bind_body (outer_bind));
16421 if (parm_cleanup)
16423 gtry *g = gimple_build_try (parm_stmts, parm_cleanup,
16424 GIMPLE_TRY_FINALLY);
16425 parm_stmts = NULL;
16426 gimple_seq_add_stmt (&parm_stmts, g);
16428 gimple_bind_set_body (outer_bind, parm_stmts);
16430 for (parm = DECL_ARGUMENTS (current_function_decl);
16431 parm; parm = DECL_CHAIN (parm))
16432 if (DECL_HAS_VALUE_EXPR_P (parm))
16434 DECL_HAS_VALUE_EXPR_P (parm) = 0;
16435 DECL_IGNORED_P (parm) = 0;
16439 if ((flag_openacc || flag_openmp || flag_openmp_simd)
16440 && gimplify_omp_ctxp)
16442 delete_omp_context (gimplify_omp_ctxp);
16443 gimplify_omp_ctxp = NULL;
16446 pop_gimplify_context (outer_bind);
16447 gcc_assert (gimplify_ctxp == NULL);
16449 if (flag_checking && !seen_error ())
16450 verify_gimple_in_seq (gimple_bind_body (outer_bind));
16452 timevar_pop (TV_TREE_GIMPLIFY);
16453 input_location = saved_location;
16455 return outer_bind;
16458 typedef char *char_p; /* For DEF_VEC_P. */
16460 /* Return whether we should exclude FNDECL from instrumentation. */
16462 static bool
16463 flag_instrument_functions_exclude_p (tree fndecl)
16465 vec<char_p> *v;
16467 v = (vec<char_p> *) flag_instrument_functions_exclude_functions;
16468 if (v && v->length () > 0)
16470 const char *name;
16471 int i;
16472 char *s;
16474 name = lang_hooks.decl_printable_name (fndecl, 1);
16475 FOR_EACH_VEC_ELT (*v, i, s)
16476 if (strstr (name, s) != NULL)
16477 return true;
16480 v = (vec<char_p> *) flag_instrument_functions_exclude_files;
16481 if (v && v->length () > 0)
16483 const char *name;
16484 int i;
16485 char *s;
16487 name = DECL_SOURCE_FILE (fndecl);
16488 FOR_EACH_VEC_ELT (*v, i, s)
16489 if (strstr (name, s) != NULL)
16490 return true;
16493 return false;
16496 /* Entry point to the gimplification pass. FNDECL is the FUNCTION_DECL
16497 node for the function we want to gimplify.
16499 Return the sequence of GIMPLE statements corresponding to the body
16500 of FNDECL. */
16502 void
16503 gimplify_function_tree (tree fndecl)
16505 gimple_seq seq;
16506 gbind *bind;
16508 gcc_assert (!gimple_body (fndecl));
16510 if (DECL_STRUCT_FUNCTION (fndecl))
16511 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
16512 else
16513 push_struct_function (fndecl);
16515 /* Tentatively set PROP_gimple_lva here, and reset it in gimplify_va_arg_expr
16516 if necessary. */
16517 cfun->curr_properties |= PROP_gimple_lva;
16519 if (asan_sanitize_use_after_scope ())
16520 asan_poisoned_variables = new hash_set<tree> ();
16521 bind = gimplify_body (fndecl, true);
16522 if (asan_poisoned_variables)
16524 delete asan_poisoned_variables;
16525 asan_poisoned_variables = NULL;
16528 /* The tree body of the function is no longer needed, replace it
16529 with the new GIMPLE body. */
16530 seq = NULL;
16531 gimple_seq_add_stmt (&seq, bind);
16532 gimple_set_body (fndecl, seq);
16534 /* If we're instrumenting function entry/exit, then prepend the call to
16535 the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to
16536 catch the exit hook. */
16537 /* ??? Add some way to ignore exceptions for this TFE. */
16538 if (flag_instrument_function_entry_exit
16539 && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl)
16540 /* Do not instrument extern inline functions. */
16541 && !(DECL_DECLARED_INLINE_P (fndecl)
16542 && DECL_EXTERNAL (fndecl)
16543 && DECL_DISREGARD_INLINE_LIMITS (fndecl))
16544 && !flag_instrument_functions_exclude_p (fndecl))
16546 tree x;
16547 gbind *new_bind;
16548 gimple *tf;
16549 gimple_seq cleanup = NULL, body = NULL;
16550 tree tmp_var, this_fn_addr;
16551 gcall *call;
16553 /* The instrumentation hooks aren't going to call the instrumented
16554 function and the address they receive is expected to be matchable
16555 against symbol addresses. Make sure we don't create a trampoline,
16556 in case the current function is nested. */
16557 this_fn_addr = build_fold_addr_expr (current_function_decl);
16558 TREE_NO_TRAMPOLINE (this_fn_addr) = 1;
16560 x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
16561 call = gimple_build_call (x, 1, integer_zero_node);
16562 tmp_var = create_tmp_var (ptr_type_node, "return_addr");
16563 gimple_call_set_lhs (call, tmp_var);
16564 gimplify_seq_add_stmt (&cleanup, call);
16565 x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_EXIT);
16566 call = gimple_build_call (x, 2, this_fn_addr, tmp_var);
16567 gimplify_seq_add_stmt (&cleanup, call);
16568 tf = gimple_build_try (seq, cleanup, GIMPLE_TRY_FINALLY);
16570 x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
16571 call = gimple_build_call (x, 1, integer_zero_node);
16572 tmp_var = create_tmp_var (ptr_type_node, "return_addr");
16573 gimple_call_set_lhs (call, tmp_var);
16574 gimplify_seq_add_stmt (&body, call);
16575 x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_ENTER);
16576 call = gimple_build_call (x, 2, this_fn_addr, tmp_var);
16577 gimplify_seq_add_stmt (&body, call);
16578 gimplify_seq_add_stmt (&body, tf);
16579 new_bind = gimple_build_bind (NULL, body, NULL);
16581 /* Replace the current function body with the body
16582 wrapped in the try/finally TF. */
16583 seq = NULL;
16584 gimple_seq_add_stmt (&seq, new_bind);
16585 gimple_set_body (fndecl, seq);
16586 bind = new_bind;
16589 if (sanitize_flags_p (SANITIZE_THREAD)
16590 && param_tsan_instrument_func_entry_exit)
16592 gcall *call = gimple_build_call_internal (IFN_TSAN_FUNC_EXIT, 0);
16593 gimple *tf = gimple_build_try (seq, call, GIMPLE_TRY_FINALLY);
16594 gbind *new_bind = gimple_build_bind (NULL, tf, NULL);
16595 /* Replace the current function body with the body
16596 wrapped in the try/finally TF. */
16597 seq = NULL;
16598 gimple_seq_add_stmt (&seq, new_bind);
16599 gimple_set_body (fndecl, seq);
16602 DECL_SAVED_TREE (fndecl) = NULL_TREE;
16603 cfun->curr_properties |= PROP_gimple_any;
16605 pop_cfun ();
16607 dump_function (TDI_gimple, fndecl);
16610 /* Return a dummy expression of type TYPE in order to keep going after an
16611 error. */
16613 static tree
16614 dummy_object (tree type)
16616 tree t = build_int_cst (build_pointer_type (type), 0);
16617 return build2 (MEM_REF, type, t, t);
16620 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
16621 builtin function, but a very special sort of operator. */
16623 enum gimplify_status
16624 gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p,
16625 gimple_seq *post_p ATTRIBUTE_UNUSED)
16627 tree promoted_type, have_va_type;
16628 tree valist = TREE_OPERAND (*expr_p, 0);
16629 tree type = TREE_TYPE (*expr_p);
16630 tree t, tag, aptag;
16631 location_t loc = EXPR_LOCATION (*expr_p);
16633 /* Verify that valist is of the proper type. */
16634 have_va_type = TREE_TYPE (valist);
16635 if (have_va_type == error_mark_node)
16636 return GS_ERROR;
16637 have_va_type = targetm.canonical_va_list_type (have_va_type);
16638 if (have_va_type == NULL_TREE
16639 && POINTER_TYPE_P (TREE_TYPE (valist)))
16640 /* Handle 'Case 1: Not an array type' from c-common.cc/build_va_arg. */
16641 have_va_type
16642 = targetm.canonical_va_list_type (TREE_TYPE (TREE_TYPE (valist)));
16643 gcc_assert (have_va_type != NULL_TREE);
16645 /* Generate a diagnostic for requesting data of a type that cannot
16646 be passed through `...' due to type promotion at the call site. */
16647 if ((promoted_type = lang_hooks.types.type_promotes_to (type))
16648 != type)
16650 static bool gave_help;
16651 bool warned;
16652 /* Use the expansion point to handle cases such as passing bool (defined
16653 in a system header) through `...'. */
16654 location_t xloc
16655 = expansion_point_location_if_in_system_header (loc);
16657 /* Unfortunately, this is merely undefined, rather than a constraint
16658 violation, so we cannot make this an error. If this call is never
16659 executed, the program is still strictly conforming. */
16660 auto_diagnostic_group d;
16661 warned = warning_at (xloc, 0,
16662 "%qT is promoted to %qT when passed through %<...%>",
16663 type, promoted_type);
16664 if (!gave_help && warned)
16666 gave_help = true;
16667 inform (xloc, "(so you should pass %qT not %qT to %<va_arg%>)",
16668 promoted_type, type);
16671 /* We can, however, treat "undefined" any way we please.
16672 Call abort to encourage the user to fix the program. */
16673 if (warned)
16674 inform (xloc, "if this code is reached, the program will abort");
16675 /* Before the abort, allow the evaluation of the va_list
16676 expression to exit or longjmp. */
16677 gimplify_and_add (valist, pre_p);
16678 t = build_call_expr_loc (loc,
16679 builtin_decl_implicit (BUILT_IN_TRAP), 0);
16680 gimplify_and_add (t, pre_p);
16682 /* This is dead code, but go ahead and finish so that the
16683 mode of the result comes out right. */
16684 *expr_p = dummy_object (type);
16685 return GS_ALL_DONE;
16688 tag = build_int_cst (build_pointer_type (type), 0);
16689 aptag = build_int_cst (TREE_TYPE (valist), 0);
16691 *expr_p = build_call_expr_internal_loc (loc, IFN_VA_ARG, type, 3,
16692 valist, tag, aptag);
16694 /* Clear the tentatively set PROP_gimple_lva, to indicate that IFN_VA_ARG
16695 needs to be expanded. */
16696 cfun->curr_properties &= ~PROP_gimple_lva;
16698 return GS_OK;
16701 /* Build a new GIMPLE_ASSIGN tuple and append it to the end of *SEQ_P.
16703 DST/SRC are the destination and source respectively. You can pass
16704 ungimplified trees in DST or SRC, in which case they will be
16705 converted to a gimple operand if necessary.
16707 This function returns the newly created GIMPLE_ASSIGN tuple. */
16709 gimple *
16710 gimplify_assign (tree dst, tree src, gimple_seq *seq_p)
16712 tree t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
16713 gimplify_and_add (t, seq_p);
16714 ggc_free (t);
16715 return gimple_seq_last_stmt (*seq_p);
16718 inline hashval_t
16719 gimplify_hasher::hash (const elt_t *p)
16721 tree t = p->val;
16722 return iterative_hash_expr (t, 0);
16725 inline bool
16726 gimplify_hasher::equal (const elt_t *p1, const elt_t *p2)
16728 tree t1 = p1->val;
16729 tree t2 = p2->val;
16730 enum tree_code code = TREE_CODE (t1);
16732 if (TREE_CODE (t2) != code
16733 || TREE_TYPE (t1) != TREE_TYPE (t2))
16734 return false;
16736 if (!operand_equal_p (t1, t2, 0))
16737 return false;
16739 /* Only allow them to compare equal if they also hash equal; otherwise
16740 results are nondeterminate, and we fail bootstrap comparison. */
16741 gcc_checking_assert (hash (p1) == hash (p2));
16743 return true;