testsuite: -mbig/-mlittle only is valid for powerpc-linux.
[official-gcc.git] / gcc / gimplify.cc
blob875b115d02d5b9b560bbe25b22b85bf589115f41
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);
254 /* Shorter alias name for the above function for use in gimplify.cc
255 only. */
257 static inline void
258 gimplify_seq_add_stmt (gimple_seq *seq_p, gimple *gs)
260 gimple_seq_add_stmt_without_update (seq_p, gs);
263 /* Append sequence SRC to the end of sequence *DST_P. If *DST_P is
264 NULL, a new sequence is allocated. This function is
265 similar to gimple_seq_add_seq, but does not scan the operands.
266 During gimplification, we need to manipulate statement sequences
267 before the def/use vectors have been constructed. */
269 static void
270 gimplify_seq_add_seq (gimple_seq *dst_p, gimple_seq src)
272 gimple_stmt_iterator si;
274 if (src == NULL)
275 return;
277 si = gsi_last (*dst_p);
278 gsi_insert_seq_after_without_update (&si, src, GSI_NEW_STMT);
282 /* Pointer to a list of allocated gimplify_ctx structs to be used for pushing
283 and popping gimplify contexts. */
285 static struct gimplify_ctx *ctx_pool = NULL;
287 /* Return a gimplify context struct from the pool. */
289 static inline struct gimplify_ctx *
290 ctx_alloc (void)
292 struct gimplify_ctx * c = ctx_pool;
294 if (c)
295 ctx_pool = c->prev_context;
296 else
297 c = XNEW (struct gimplify_ctx);
299 memset (c, '\0', sizeof (*c));
300 return c;
303 /* Put gimplify context C back into the pool. */
305 static inline void
306 ctx_free (struct gimplify_ctx *c)
308 c->prev_context = ctx_pool;
309 ctx_pool = c;
312 /* Free allocated ctx stack memory. */
314 void
315 free_gimplify_stack (void)
317 struct gimplify_ctx *c;
319 while ((c = ctx_pool))
321 ctx_pool = c->prev_context;
322 free (c);
327 /* Set up a context for the gimplifier. */
329 void
330 push_gimplify_context (bool in_ssa, bool rhs_cond_ok)
332 struct gimplify_ctx *c = ctx_alloc ();
334 c->prev_context = gimplify_ctxp;
335 gimplify_ctxp = c;
336 gimplify_ctxp->into_ssa = in_ssa;
337 gimplify_ctxp->allow_rhs_cond_expr = rhs_cond_ok;
340 /* Tear down a context for the gimplifier. If BODY is non-null, then
341 put the temporaries into the outer BIND_EXPR. Otherwise, put them
342 in the local_decls.
344 BODY is not a sequence, but the first tuple in a sequence. */
346 void
347 pop_gimplify_context (gimple *body)
349 struct gimplify_ctx *c = gimplify_ctxp;
351 gcc_assert (c
352 && (!c->bind_expr_stack.exists ()
353 || c->bind_expr_stack.is_empty ()));
354 c->bind_expr_stack.release ();
355 gimplify_ctxp = c->prev_context;
357 if (body)
358 declare_vars (c->temps, body, false);
359 else
360 record_vars (c->temps);
362 delete c->temp_htab;
363 c->temp_htab = NULL;
364 ctx_free (c);
367 /* Push a GIMPLE_BIND tuple onto the stack of bindings. */
369 static void
370 gimple_push_bind_expr (gbind *bind_stmt)
372 gimplify_ctxp->bind_expr_stack.reserve (8);
373 gimplify_ctxp->bind_expr_stack.safe_push (bind_stmt);
376 /* Pop the first element off the stack of bindings. */
378 static void
379 gimple_pop_bind_expr (void)
381 gimplify_ctxp->bind_expr_stack.pop ();
384 /* Return the first element of the stack of bindings. */
386 gbind *
387 gimple_current_bind_expr (void)
389 return gimplify_ctxp->bind_expr_stack.last ();
392 /* Return the stack of bindings created during gimplification. */
394 vec<gbind *>
395 gimple_bind_expr_stack (void)
397 return gimplify_ctxp->bind_expr_stack;
400 /* Return true iff there is a COND_EXPR between us and the innermost
401 CLEANUP_POINT_EXPR. This info is used by gimple_push_cleanup. */
403 static bool
404 gimple_conditional_context (void)
406 return gimplify_ctxp->conditions > 0;
409 /* Note that we've entered a COND_EXPR. */
411 static void
412 gimple_push_condition (void)
414 #ifdef ENABLE_GIMPLE_CHECKING
415 if (gimplify_ctxp->conditions == 0)
416 gcc_assert (gimple_seq_empty_p (gimplify_ctxp->conditional_cleanups));
417 #endif
418 ++(gimplify_ctxp->conditions);
421 /* Note that we've left a COND_EXPR. If we're back at unconditional scope
422 now, add any conditional cleanups we've seen to the prequeue. */
424 static void
425 gimple_pop_condition (gimple_seq *pre_p)
427 int conds = --(gimplify_ctxp->conditions);
429 gcc_assert (conds >= 0);
430 if (conds == 0)
432 gimplify_seq_add_seq (pre_p, gimplify_ctxp->conditional_cleanups);
433 gimplify_ctxp->conditional_cleanups = NULL;
437 /* A stable comparison routine for use with splay trees and DECLs. */
439 static int
440 splay_tree_compare_decl_uid (splay_tree_key xa, splay_tree_key xb)
442 tree a = (tree) xa;
443 tree b = (tree) xb;
445 return DECL_UID (a) - DECL_UID (b);
448 /* Create a new omp construct that deals with variable remapping. */
450 static struct gimplify_omp_ctx *
451 new_omp_context (enum omp_region_type region_type)
453 struct gimplify_omp_ctx *c;
455 c = XCNEW (struct gimplify_omp_ctx);
456 c->outer_context = gimplify_omp_ctxp;
457 c->variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0);
458 c->privatized_types = new hash_set<tree>;
459 c->location = input_location;
460 c->region_type = region_type;
461 if ((region_type & ORT_TASK) == 0)
462 c->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
463 else
464 c->default_kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
465 c->defaultmap[GDMK_SCALAR] = GOVD_MAP;
466 c->defaultmap[GDMK_SCALAR_TARGET] = GOVD_MAP;
467 c->defaultmap[GDMK_AGGREGATE] = GOVD_MAP;
468 c->defaultmap[GDMK_ALLOCATABLE] = GOVD_MAP;
469 c->defaultmap[GDMK_POINTER] = GOVD_MAP;
471 return c;
474 /* Destroy an omp construct that deals with variable remapping. */
476 static void
477 delete_omp_context (struct gimplify_omp_ctx *c)
479 splay_tree_delete (c->variables);
480 delete c->privatized_types;
481 c->loop_iter_var.release ();
482 XDELETE (c);
485 static void omp_add_variable (struct gimplify_omp_ctx *, tree, unsigned int);
486 static bool omp_notice_variable (struct gimplify_omp_ctx *, tree, bool);
488 /* Both gimplify the statement T and append it to *SEQ_P. This function
489 behaves exactly as gimplify_stmt, but you don't have to pass T as a
490 reference. */
492 void
493 gimplify_and_add (tree t, gimple_seq *seq_p)
495 gimplify_stmt (&t, seq_p);
498 /* Gimplify statement T into sequence *SEQ_P, and return the first
499 tuple in the sequence of generated tuples for this statement.
500 Return NULL if gimplifying T produced no tuples. */
502 static gimple *
503 gimplify_and_return_first (tree t, gimple_seq *seq_p)
505 gimple_stmt_iterator last = gsi_last (*seq_p);
507 gimplify_and_add (t, seq_p);
509 if (!gsi_end_p (last))
511 gsi_next (&last);
512 return gsi_stmt (last);
514 else
515 return gimple_seq_first_stmt (*seq_p);
518 /* Returns true iff T is a valid RHS for an assignment to an un-renamed
519 LHS, or for a call argument. */
521 static bool
522 is_gimple_mem_rhs (tree t)
524 /* If we're dealing with a renamable type, either source or dest must be
525 a renamed variable. */
526 if (is_gimple_reg_type (TREE_TYPE (t)))
527 return is_gimple_val (t);
528 else
529 return is_gimple_val (t) || is_gimple_lvalue (t);
532 /* Return true if T is a CALL_EXPR or an expression that can be
533 assigned to a temporary. Note that this predicate should only be
534 used during gimplification. See the rationale for this in
535 gimplify_modify_expr. */
537 static bool
538 is_gimple_reg_rhs_or_call (tree t)
540 return (get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS
541 || TREE_CODE (t) == CALL_EXPR);
544 /* Return true if T is a valid memory RHS or a CALL_EXPR. Note that
545 this predicate should only be used during gimplification. See the
546 rationale for this in gimplify_modify_expr. */
548 static bool
549 is_gimple_mem_rhs_or_call (tree t)
551 /* If we're dealing with a renamable type, either source or dest must be
552 a renamed variable. */
553 if (is_gimple_reg_type (TREE_TYPE (t)))
554 return is_gimple_val (t);
555 else
556 return (is_gimple_val (t)
557 || is_gimple_lvalue (t)
558 || TREE_CLOBBER_P (t)
559 || TREE_CODE (t) == CALL_EXPR);
562 /* Create a temporary with a name derived from VAL. Subroutine of
563 lookup_tmp_var; nobody else should call this function. */
565 static inline tree
566 create_tmp_from_val (tree val)
568 /* Drop all qualifiers and address-space information from the value type. */
569 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (val));
570 tree var = create_tmp_var (type, get_name (val));
571 return var;
574 /* Create a temporary to hold the value of VAL. If IS_FORMAL, try to reuse
575 an existing expression temporary. */
577 static tree
578 lookup_tmp_var (tree val, bool is_formal)
580 tree ret;
582 /* If not optimizing, never really reuse a temporary. local-alloc
583 won't allocate any variable that is used in more than one basic
584 block, which means it will go into memory, causing much extra
585 work in reload and final and poorer code generation, outweighing
586 the extra memory allocation here. */
587 if (!optimize || !is_formal || TREE_SIDE_EFFECTS (val))
588 ret = create_tmp_from_val (val);
589 else
591 elt_t elt, *elt_p;
592 elt_t **slot;
594 elt.val = val;
595 if (!gimplify_ctxp->temp_htab)
596 gimplify_ctxp->temp_htab = new hash_table<gimplify_hasher> (1000);
597 slot = gimplify_ctxp->temp_htab->find_slot (&elt, INSERT);
598 if (*slot == NULL)
600 elt_p = XNEW (elt_t);
601 elt_p->val = val;
602 elt_p->temp = ret = create_tmp_from_val (val);
603 *slot = elt_p;
605 else
607 elt_p = *slot;
608 ret = elt_p->temp;
612 return ret;
615 /* Helper for get_formal_tmp_var and get_initialized_tmp_var. */
617 static tree
618 internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
619 bool is_formal, bool allow_ssa)
621 tree t, mod;
623 /* Notice that we explicitly allow VAL to be a CALL_EXPR so that we
624 can create an INIT_EXPR and convert it into a GIMPLE_CALL below. */
625 gimplify_expr (&val, pre_p, post_p, is_gimple_reg_rhs_or_call,
626 fb_rvalue);
628 if (allow_ssa
629 && gimplify_ctxp->into_ssa
630 && is_gimple_reg_type (TREE_TYPE (val)))
632 t = make_ssa_name (TYPE_MAIN_VARIANT (TREE_TYPE (val)));
633 if (! gimple_in_ssa_p (cfun))
635 const char *name = get_name (val);
636 if (name)
637 SET_SSA_NAME_VAR_OR_IDENTIFIER (t, create_tmp_var_name (name));
640 else
641 t = lookup_tmp_var (val, is_formal);
643 mod = build2 (INIT_EXPR, TREE_TYPE (t), t, unshare_expr (val));
645 SET_EXPR_LOCATION (mod, EXPR_LOC_OR_LOC (val, input_location));
647 /* gimplify_modify_expr might want to reduce this further. */
648 gimplify_and_add (mod, pre_p);
649 ggc_free (mod);
651 return t;
654 /* Return a formal temporary variable initialized with VAL. PRE_P is as
655 in gimplify_expr. Only use this function if:
657 1) The value of the unfactored expression represented by VAL will not
658 change between the initialization and use of the temporary, and
659 2) The temporary will not be otherwise modified.
661 For instance, #1 means that this is inappropriate for SAVE_EXPR temps,
662 and #2 means it is inappropriate for && temps.
664 For other cases, use get_initialized_tmp_var instead. */
666 tree
667 get_formal_tmp_var (tree val, gimple_seq *pre_p)
669 return internal_get_tmp_var (val, pre_p, NULL, true, true);
672 /* Return a temporary variable initialized with VAL. PRE_P and POST_P
673 are as in gimplify_expr. */
675 tree
676 get_initialized_tmp_var (tree val, gimple_seq *pre_p,
677 gimple_seq *post_p /* = NULL */,
678 bool allow_ssa /* = true */)
680 return internal_get_tmp_var (val, pre_p, post_p, false, allow_ssa);
683 /* Declare all the variables in VARS in SCOPE. If DEBUG_INFO is true,
684 generate debug info for them; otherwise don't. */
686 void
687 declare_vars (tree vars, gimple *gs, bool debug_info)
689 tree last = vars;
690 if (last)
692 tree temps, block;
694 gbind *scope = as_a <gbind *> (gs);
696 temps = nreverse (last);
698 block = gimple_bind_block (scope);
699 gcc_assert (!block || TREE_CODE (block) == BLOCK);
700 if (!block || !debug_info)
702 DECL_CHAIN (last) = gimple_bind_vars (scope);
703 gimple_bind_set_vars (scope, temps);
705 else
707 /* We need to attach the nodes both to the BIND_EXPR and to its
708 associated BLOCK for debugging purposes. The key point here
709 is that the BLOCK_VARS of the BIND_EXPR_BLOCK of a BIND_EXPR
710 is a subchain of the BIND_EXPR_VARS of the BIND_EXPR. */
711 if (BLOCK_VARS (block))
712 BLOCK_VARS (block) = chainon (BLOCK_VARS (block), temps);
713 else
715 gimple_bind_set_vars (scope,
716 chainon (gimple_bind_vars (scope), temps));
717 BLOCK_VARS (block) = temps;
723 /* For VAR a VAR_DECL of variable size, try to find a constant upper bound
724 for the size and adjust DECL_SIZE/DECL_SIZE_UNIT accordingly. Abort if
725 no such upper bound can be obtained. */
727 static void
728 force_constant_size (tree var)
730 /* The only attempt we make is by querying the maximum size of objects
731 of the variable's type. */
733 HOST_WIDE_INT max_size;
735 gcc_assert (VAR_P (var));
737 max_size = max_int_size_in_bytes (TREE_TYPE (var));
739 gcc_assert (max_size >= 0);
741 DECL_SIZE_UNIT (var)
742 = build_int_cst (TREE_TYPE (DECL_SIZE_UNIT (var)), max_size);
743 DECL_SIZE (var)
744 = build_int_cst (TREE_TYPE (DECL_SIZE (var)), max_size * BITS_PER_UNIT);
747 /* Push the temporary variable TMP into the current binding. */
749 void
750 gimple_add_tmp_var_fn (struct function *fn, tree tmp)
752 gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
754 /* Later processing assumes that the object size is constant, which might
755 not be true at this point. Force the use of a constant upper bound in
756 this case. */
757 if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp)))
758 force_constant_size (tmp);
760 DECL_CONTEXT (tmp) = fn->decl;
761 DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
763 record_vars_into (tmp, fn->decl);
766 /* Push the temporary variable TMP into the current binding. */
768 void
769 gimple_add_tmp_var (tree tmp)
771 gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
773 /* Later processing assumes that the object size is constant, which might
774 not be true at this point. Force the use of a constant upper bound in
775 this case. */
776 if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp)))
777 force_constant_size (tmp);
779 DECL_CONTEXT (tmp) = current_function_decl;
780 DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
782 if (gimplify_ctxp)
784 DECL_CHAIN (tmp) = gimplify_ctxp->temps;
785 gimplify_ctxp->temps = tmp;
787 /* Mark temporaries local within the nearest enclosing parallel. */
788 if (gimplify_omp_ctxp)
790 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
791 int flag = GOVD_LOCAL | GOVD_SEEN;
792 while (ctx
793 && (ctx->region_type == ORT_WORKSHARE
794 || ctx->region_type == ORT_TASKGROUP
795 || ctx->region_type == ORT_SIMD
796 || ctx->region_type == ORT_ACC))
798 if (ctx->region_type == ORT_SIMD
799 && TREE_ADDRESSABLE (tmp)
800 && !TREE_STATIC (tmp))
802 if (TREE_CODE (DECL_SIZE_UNIT (tmp)) != INTEGER_CST)
803 ctx->add_safelen1 = true;
804 else if (ctx->in_for_exprs)
805 flag = GOVD_PRIVATE;
806 else
807 flag = GOVD_PRIVATE | GOVD_SEEN;
808 break;
810 ctx = ctx->outer_context;
812 if (ctx)
813 omp_add_variable (ctx, tmp, flag);
816 else if (cfun)
817 record_vars (tmp);
818 else
820 gimple_seq body_seq;
822 /* This case is for nested functions. We need to expose the locals
823 they create. */
824 body_seq = gimple_body (current_function_decl);
825 declare_vars (tmp, gimple_seq_first_stmt (body_seq), false);
831 /* This page contains routines to unshare tree nodes, i.e. to duplicate tree
832 nodes that are referenced more than once in GENERIC functions. This is
833 necessary because gimplification (translation into GIMPLE) is performed
834 by modifying tree nodes in-place, so gimplication of a shared node in a
835 first context could generate an invalid GIMPLE form in a second context.
837 This is achieved with a simple mark/copy/unmark algorithm that walks the
838 GENERIC representation top-down, marks nodes with TREE_VISITED the first
839 time it encounters them, duplicates them if they already have TREE_VISITED
840 set, and finally removes the TREE_VISITED marks it has set.
842 The algorithm works only at the function level, i.e. it generates a GENERIC
843 representation of a function with no nodes shared within the function when
844 passed a GENERIC function (except for nodes that are allowed to be shared).
846 At the global level, it is also necessary to unshare tree nodes that are
847 referenced in more than one function, for the same aforementioned reason.
848 This requires some cooperation from the front-end. There are 2 strategies:
850 1. Manual unsharing. The front-end needs to call unshare_expr on every
851 expression that might end up being shared across functions.
853 2. Deep unsharing. This is an extension of regular unsharing. Instead
854 of calling unshare_expr on expressions that might be shared across
855 functions, the front-end pre-marks them with TREE_VISITED. This will
856 ensure that they are unshared on the first reference within functions
857 when the regular unsharing algorithm runs. The counterpart is that
858 this algorithm must look deeper than for manual unsharing, which is
859 specified by LANG_HOOKS_DEEP_UNSHARING.
861 If there are only few specific cases of node sharing across functions, it is
862 probably easier for a front-end to unshare the expressions manually. On the
863 contrary, if the expressions generated at the global level are as widespread
864 as expressions generated within functions, deep unsharing is very likely the
865 way to go. */
867 /* Similar to copy_tree_r but do not copy SAVE_EXPR or TARGET_EXPR nodes.
868 These nodes model computations that must be done once. If we were to
869 unshare something like SAVE_EXPR(i++), the gimplification process would
870 create wrong code. However, if DATA is non-null, it must hold a pointer
871 set that is used to unshare the subtrees of these nodes. */
873 static tree
874 mostly_copy_tree_r (tree *tp, int *walk_subtrees, void *data)
876 tree t = *tp;
877 enum tree_code code = TREE_CODE (t);
879 /* Do not copy SAVE_EXPR, TARGET_EXPR or BIND_EXPR nodes themselves, but
880 copy their subtrees if we can make sure to do it only once. */
881 if (code == SAVE_EXPR || code == TARGET_EXPR || code == BIND_EXPR)
883 if (data && !((hash_set<tree> *)data)->add (t))
885 else
886 *walk_subtrees = 0;
889 /* Stop at types, decls, constants like copy_tree_r. */
890 else if (TREE_CODE_CLASS (code) == tcc_type
891 || TREE_CODE_CLASS (code) == tcc_declaration
892 || TREE_CODE_CLASS (code) == tcc_constant)
893 *walk_subtrees = 0;
895 /* Cope with the statement expression extension. */
896 else if (code == STATEMENT_LIST)
899 /* Leave the bulk of the work to copy_tree_r itself. */
900 else
901 copy_tree_r (tp, walk_subtrees, NULL);
903 return NULL_TREE;
906 /* Callback for walk_tree to unshare most of the shared trees rooted at *TP.
907 If *TP has been visited already, then *TP is deeply copied by calling
908 mostly_copy_tree_r. DATA is passed to mostly_copy_tree_r unmodified. */
910 static tree
911 copy_if_shared_r (tree *tp, int *walk_subtrees, void *data)
913 tree t = *tp;
914 enum tree_code code = TREE_CODE (t);
916 /* Skip types, decls, and constants. But we do want to look at their
917 types and the bounds of types. Mark them as visited so we properly
918 unmark their subtrees on the unmark pass. If we've already seen them,
919 don't look down further. */
920 if (TREE_CODE_CLASS (code) == tcc_type
921 || TREE_CODE_CLASS (code) == tcc_declaration
922 || TREE_CODE_CLASS (code) == tcc_constant)
924 if (TREE_VISITED (t))
925 *walk_subtrees = 0;
926 else
927 TREE_VISITED (t) = 1;
930 /* If this node has been visited already, unshare it and don't look
931 any deeper. */
932 else if (TREE_VISITED (t))
934 walk_tree (tp, mostly_copy_tree_r, data, NULL);
935 *walk_subtrees = 0;
938 /* Otherwise, mark the node as visited and keep looking. */
939 else
940 TREE_VISITED (t) = 1;
942 return NULL_TREE;
945 /* Unshare most of the shared trees rooted at *TP. DATA is passed to the
946 copy_if_shared_r callback unmodified. */
948 void
949 copy_if_shared (tree *tp, void *data)
951 walk_tree (tp, copy_if_shared_r, data, NULL);
954 /* Unshare all the trees in the body of FNDECL, as well as in the bodies of
955 any nested functions. */
957 static void
958 unshare_body (tree fndecl)
960 struct cgraph_node *cgn = cgraph_node::get (fndecl);
961 /* If the language requires deep unsharing, we need a pointer set to make
962 sure we don't repeatedly unshare subtrees of unshareable nodes. */
963 hash_set<tree> *visited
964 = lang_hooks.deep_unsharing ? new hash_set<tree> : NULL;
966 copy_if_shared (&DECL_SAVED_TREE (fndecl), visited);
967 copy_if_shared (&DECL_SIZE (DECL_RESULT (fndecl)), visited);
968 copy_if_shared (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)), visited);
970 delete visited;
972 if (cgn)
973 for (cgn = first_nested_function (cgn); cgn;
974 cgn = next_nested_function (cgn))
975 unshare_body (cgn->decl);
978 /* Callback for walk_tree to unmark the visited trees rooted at *TP.
979 Subtrees are walked until the first unvisited node is encountered. */
981 static tree
982 unmark_visited_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
984 tree t = *tp;
986 /* If this node has been visited, unmark it and keep looking. */
987 if (TREE_VISITED (t))
988 TREE_VISITED (t) = 0;
990 /* Otherwise, don't look any deeper. */
991 else
992 *walk_subtrees = 0;
994 return NULL_TREE;
997 /* Unmark the visited trees rooted at *TP. */
999 static inline void
1000 unmark_visited (tree *tp)
1002 walk_tree (tp, unmark_visited_r, NULL, NULL);
1005 /* Likewise, but mark all trees as not visited. */
1007 static void
1008 unvisit_body (tree fndecl)
1010 struct cgraph_node *cgn = cgraph_node::get (fndecl);
1012 unmark_visited (&DECL_SAVED_TREE (fndecl));
1013 unmark_visited (&DECL_SIZE (DECL_RESULT (fndecl)));
1014 unmark_visited (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)));
1016 if (cgn)
1017 for (cgn = first_nested_function (cgn);
1018 cgn; cgn = next_nested_function (cgn))
1019 unvisit_body (cgn->decl);
1022 /* Unconditionally make an unshared copy of EXPR. This is used when using
1023 stored expressions which span multiple functions, such as BINFO_VTABLE,
1024 as the normal unsharing process can't tell that they're shared. */
1026 tree
1027 unshare_expr (tree expr)
1029 walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
1030 return expr;
1033 /* Worker for unshare_expr_without_location. */
1035 static tree
1036 prune_expr_location (tree *tp, int *walk_subtrees, void *)
1038 if (EXPR_P (*tp))
1039 SET_EXPR_LOCATION (*tp, UNKNOWN_LOCATION);
1040 else
1041 *walk_subtrees = 0;
1042 return NULL_TREE;
1045 /* Similar to unshare_expr but also prune all expression locations
1046 from EXPR. */
1048 tree
1049 unshare_expr_without_location (tree expr)
1051 walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
1052 if (EXPR_P (expr))
1053 walk_tree (&expr, prune_expr_location, NULL, NULL);
1054 return expr;
1057 /* Return the EXPR_LOCATION of EXPR, if it (maybe recursively) has
1058 one, OR_ELSE otherwise. The location of a STATEMENT_LISTs
1059 comprising at least one DEBUG_BEGIN_STMT followed by exactly one
1060 EXPR is the location of the EXPR. */
1062 static location_t
1063 rexpr_location (tree expr, location_t or_else = UNKNOWN_LOCATION)
1065 if (!expr)
1066 return or_else;
1068 if (EXPR_HAS_LOCATION (expr))
1069 return EXPR_LOCATION (expr);
1071 if (TREE_CODE (expr) != STATEMENT_LIST)
1072 return or_else;
1074 tree_stmt_iterator i = tsi_start (expr);
1076 bool found = false;
1077 while (!tsi_end_p (i) && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT)
1079 found = true;
1080 tsi_next (&i);
1083 if (!found || !tsi_one_before_end_p (i))
1084 return or_else;
1086 return rexpr_location (tsi_stmt (i), or_else);
1089 /* Return TRUE iff EXPR (maybe recursively) has a location; see
1090 rexpr_location for the potential recursion. */
1092 static inline bool
1093 rexpr_has_location (tree expr)
1095 return rexpr_location (expr) != UNKNOWN_LOCATION;
1099 /* WRAPPER is a code such as BIND_EXPR or CLEANUP_POINT_EXPR which can both
1100 contain statements and have a value. Assign its value to a temporary
1101 and give it void_type_node. Return the temporary, or NULL_TREE if
1102 WRAPPER was already void. */
1104 tree
1105 voidify_wrapper_expr (tree wrapper, tree temp)
1107 tree type = TREE_TYPE (wrapper);
1108 if (type && !VOID_TYPE_P (type))
1110 tree *p;
1112 /* Set p to point to the body of the wrapper. Loop until we find
1113 something that isn't a wrapper. */
1114 for (p = &wrapper; p && *p; )
1116 switch (TREE_CODE (*p))
1118 case BIND_EXPR:
1119 TREE_SIDE_EFFECTS (*p) = 1;
1120 TREE_TYPE (*p) = void_type_node;
1121 /* For a BIND_EXPR, the body is operand 1. */
1122 p = &BIND_EXPR_BODY (*p);
1123 break;
1125 case CLEANUP_POINT_EXPR:
1126 case TRY_FINALLY_EXPR:
1127 case TRY_CATCH_EXPR:
1128 TREE_SIDE_EFFECTS (*p) = 1;
1129 TREE_TYPE (*p) = void_type_node;
1130 p = &TREE_OPERAND (*p, 0);
1131 break;
1133 case STATEMENT_LIST:
1135 tree_stmt_iterator i = tsi_last (*p);
1136 TREE_SIDE_EFFECTS (*p) = 1;
1137 TREE_TYPE (*p) = void_type_node;
1138 p = tsi_end_p (i) ? NULL : tsi_stmt_ptr (i);
1140 break;
1142 case COMPOUND_EXPR:
1143 /* Advance to the last statement. Set all container types to
1144 void. */
1145 for (; TREE_CODE (*p) == COMPOUND_EXPR; p = &TREE_OPERAND (*p, 1))
1147 TREE_SIDE_EFFECTS (*p) = 1;
1148 TREE_TYPE (*p) = void_type_node;
1150 break;
1152 case TRANSACTION_EXPR:
1153 TREE_SIDE_EFFECTS (*p) = 1;
1154 TREE_TYPE (*p) = void_type_node;
1155 p = &TRANSACTION_EXPR_BODY (*p);
1156 break;
1158 default:
1159 /* Assume that any tree upon which voidify_wrapper_expr is
1160 directly called is a wrapper, and that its body is op0. */
1161 if (p == &wrapper)
1163 TREE_SIDE_EFFECTS (*p) = 1;
1164 TREE_TYPE (*p) = void_type_node;
1165 p = &TREE_OPERAND (*p, 0);
1166 break;
1168 goto out;
1172 out:
1173 if (p == NULL || IS_EMPTY_STMT (*p))
1174 temp = NULL_TREE;
1175 else if (temp)
1177 /* The wrapper is on the RHS of an assignment that we're pushing
1178 down. */
1179 gcc_assert (TREE_CODE (temp) == INIT_EXPR
1180 || TREE_CODE (temp) == MODIFY_EXPR);
1181 TREE_OPERAND (temp, 1) = *p;
1182 *p = temp;
1184 else
1186 temp = create_tmp_var (type, "retval");
1187 *p = build2 (INIT_EXPR, type, temp, *p);
1190 return temp;
1193 return NULL_TREE;
1196 /* Prepare calls to builtins to SAVE and RESTORE the stack as well as
1197 a temporary through which they communicate. */
1199 static void
1200 build_stack_save_restore (gcall **save, gcall **restore)
1202 tree tmp_var;
1204 *save = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_SAVE), 0);
1205 tmp_var = create_tmp_var (ptr_type_node, "saved_stack");
1206 gimple_call_set_lhs (*save, tmp_var);
1208 *restore
1209 = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_RESTORE),
1210 1, tmp_var);
1213 /* Generate IFN_ASAN_MARK call that poisons shadow of a for DECL variable. */
1215 static tree
1216 build_asan_poison_call_expr (tree decl)
1218 /* Do not poison variables that have size equal to zero. */
1219 tree unit_size = DECL_SIZE_UNIT (decl);
1220 if (zerop (unit_size))
1221 return NULL_TREE;
1223 tree base = build_fold_addr_expr (decl);
1225 return build_call_expr_internal_loc (UNKNOWN_LOCATION, IFN_ASAN_MARK,
1226 void_type_node, 3,
1227 build_int_cst (integer_type_node,
1228 ASAN_MARK_POISON),
1229 base, unit_size);
1232 /* Generate IFN_ASAN_MARK call that would poison or unpoison, depending
1233 on POISON flag, shadow memory of a DECL variable. The call will be
1234 put on location identified by IT iterator, where BEFORE flag drives
1235 position where the stmt will be put. */
1237 static void
1238 asan_poison_variable (tree decl, bool poison, gimple_stmt_iterator *it,
1239 bool before)
1241 tree unit_size = DECL_SIZE_UNIT (decl);
1242 tree base = build_fold_addr_expr (decl);
1244 /* Do not poison variables that have size equal to zero. */
1245 if (zerop (unit_size))
1246 return;
1248 /* It's necessary to have all stack variables aligned to ASAN granularity
1249 bytes. */
1250 gcc_assert (!hwasan_sanitize_p () || hwasan_sanitize_stack_p ());
1251 unsigned shadow_granularity
1252 = hwasan_sanitize_p () ? HWASAN_TAG_GRANULE_SIZE : ASAN_SHADOW_GRANULARITY;
1253 if (DECL_ALIGN_UNIT (decl) <= shadow_granularity)
1254 SET_DECL_ALIGN (decl, BITS_PER_UNIT * shadow_granularity);
1256 HOST_WIDE_INT flags = poison ? ASAN_MARK_POISON : ASAN_MARK_UNPOISON;
1258 gimple *g
1259 = gimple_build_call_internal (IFN_ASAN_MARK, 3,
1260 build_int_cst (integer_type_node, flags),
1261 base, unit_size);
1263 if (before)
1264 gsi_insert_before (it, g, GSI_NEW_STMT);
1265 else
1266 gsi_insert_after (it, g, GSI_NEW_STMT);
1269 /* Generate IFN_ASAN_MARK internal call that depending on POISON flag
1270 either poisons or unpoisons a DECL. Created statement is appended
1271 to SEQ_P gimple sequence. */
1273 static void
1274 asan_poison_variable (tree decl, bool poison, gimple_seq *seq_p)
1276 gimple_stmt_iterator it = gsi_last (*seq_p);
1277 bool before = false;
1279 if (gsi_end_p (it))
1280 before = true;
1282 asan_poison_variable (decl, poison, &it, before);
1285 /* Sort pair of VAR_DECLs A and B by DECL_UID. */
1287 static int
1288 sort_by_decl_uid (const void *a, const void *b)
1290 const tree *t1 = (const tree *)a;
1291 const tree *t2 = (const tree *)b;
1293 int uid1 = DECL_UID (*t1);
1294 int uid2 = DECL_UID (*t2);
1296 if (uid1 < uid2)
1297 return -1;
1298 else if (uid1 > uid2)
1299 return 1;
1300 else
1301 return 0;
1304 /* Generate IFN_ASAN_MARK internal call for all VARIABLES
1305 depending on POISON flag. Created statement is appended
1306 to SEQ_P gimple sequence. */
1308 static void
1309 asan_poison_variables (hash_set<tree> *variables, bool poison, gimple_seq *seq_p)
1311 unsigned c = variables->elements ();
1312 if (c == 0)
1313 return;
1315 auto_vec<tree> sorted_variables (c);
1317 for (hash_set<tree>::iterator it = variables->begin ();
1318 it != variables->end (); ++it)
1319 sorted_variables.safe_push (*it);
1321 sorted_variables.qsort (sort_by_decl_uid);
1323 unsigned i;
1324 tree var;
1325 FOR_EACH_VEC_ELT (sorted_variables, i, var)
1327 asan_poison_variable (var, poison, seq_p);
1329 /* Add use_after_scope_memory attribute for the variable in order
1330 to prevent re-written into SSA. */
1331 if (!lookup_attribute (ASAN_USE_AFTER_SCOPE_ATTRIBUTE,
1332 DECL_ATTRIBUTES (var)))
1333 DECL_ATTRIBUTES (var)
1334 = tree_cons (get_identifier (ASAN_USE_AFTER_SCOPE_ATTRIBUTE),
1335 integer_one_node,
1336 DECL_ATTRIBUTES (var));
1340 /* Gimplify a BIND_EXPR. Just voidify and recurse. */
1342 static enum gimplify_status
1343 gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p)
1345 tree bind_expr = *expr_p;
1346 bool old_keep_stack = gimplify_ctxp->keep_stack;
1347 bool old_save_stack = gimplify_ctxp->save_stack;
1348 tree t;
1349 gbind *bind_stmt;
1350 gimple_seq body, cleanup;
1351 gcall *stack_save;
1352 location_t start_locus = 0, end_locus = 0;
1353 tree ret_clauses = NULL;
1355 tree temp = voidify_wrapper_expr (bind_expr, NULL);
1357 /* Mark variables seen in this bind expr. */
1358 for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t))
1360 if (VAR_P (t))
1362 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
1364 /* Mark variable as local. */
1365 if (ctx && ctx->region_type != ORT_NONE && !DECL_EXTERNAL (t))
1367 if (! DECL_SEEN_IN_BIND_EXPR_P (t)
1368 || splay_tree_lookup (ctx->variables,
1369 (splay_tree_key) t) == NULL)
1371 int flag = GOVD_LOCAL;
1372 if (ctx->region_type == ORT_SIMD
1373 && TREE_ADDRESSABLE (t)
1374 && !TREE_STATIC (t))
1376 if (TREE_CODE (DECL_SIZE_UNIT (t)) != INTEGER_CST)
1377 ctx->add_safelen1 = true;
1378 else
1379 flag = GOVD_PRIVATE;
1381 omp_add_variable (ctx, t, flag | GOVD_SEEN);
1383 /* Static locals inside of target construct or offloaded
1384 routines need to be "omp declare target". */
1385 if (TREE_STATIC (t))
1386 for (; ctx; ctx = ctx->outer_context)
1387 if ((ctx->region_type & ORT_TARGET) != 0)
1389 if (!lookup_attribute ("omp declare target",
1390 DECL_ATTRIBUTES (t)))
1392 tree id = get_identifier ("omp declare target");
1393 DECL_ATTRIBUTES (t)
1394 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
1395 varpool_node *node = varpool_node::get (t);
1396 if (node)
1398 node->offloadable = 1;
1399 if (ENABLE_OFFLOADING && !DECL_EXTERNAL (t))
1401 g->have_offload = true;
1402 if (!in_lto_p)
1403 vec_safe_push (offload_vars, t);
1407 break;
1411 DECL_SEEN_IN_BIND_EXPR_P (t) = 1;
1413 if (DECL_HARD_REGISTER (t) && !is_global_var (t) && cfun)
1414 cfun->has_local_explicit_reg_vars = true;
1418 bind_stmt = gimple_build_bind (BIND_EXPR_VARS (bind_expr), NULL,
1419 BIND_EXPR_BLOCK (bind_expr));
1420 gimple_push_bind_expr (bind_stmt);
1422 gimplify_ctxp->keep_stack = false;
1423 gimplify_ctxp->save_stack = false;
1425 /* Gimplify the body into the GIMPLE_BIND tuple's body. */
1426 body = NULL;
1427 gimplify_stmt (&BIND_EXPR_BODY (bind_expr), &body);
1428 gimple_bind_set_body (bind_stmt, body);
1430 /* Source location wise, the cleanup code (stack_restore and clobbers)
1431 belongs to the end of the block, so propagate what we have. The
1432 stack_save operation belongs to the beginning of block, which we can
1433 infer from the bind_expr directly if the block has no explicit
1434 assignment. */
1435 if (BIND_EXPR_BLOCK (bind_expr))
1437 end_locus = BLOCK_SOURCE_END_LOCATION (BIND_EXPR_BLOCK (bind_expr));
1438 start_locus = BLOCK_SOURCE_LOCATION (BIND_EXPR_BLOCK (bind_expr));
1440 if (start_locus == 0)
1441 start_locus = EXPR_LOCATION (bind_expr);
1443 cleanup = NULL;
1444 stack_save = NULL;
1446 /* If the code both contains VLAs and calls alloca, then we cannot reclaim
1447 the stack space allocated to the VLAs. */
1448 if (gimplify_ctxp->save_stack && !gimplify_ctxp->keep_stack)
1450 gcall *stack_restore;
1452 /* Save stack on entry and restore it on exit. Add a try_finally
1453 block to achieve this. */
1454 build_stack_save_restore (&stack_save, &stack_restore);
1456 gimple_set_location (stack_save, start_locus);
1457 gimple_set_location (stack_restore, end_locus);
1459 gimplify_seq_add_stmt (&cleanup, stack_restore);
1462 /* Add clobbers for all variables that go out of scope. */
1463 for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t))
1465 if (VAR_P (t)
1466 && !is_global_var (t)
1467 && DECL_CONTEXT (t) == current_function_decl)
1469 if (!DECL_HARD_REGISTER (t)
1470 && !TREE_THIS_VOLATILE (t)
1471 && !DECL_HAS_VALUE_EXPR_P (t)
1472 /* Only care for variables that have to be in memory. Others
1473 will be rewritten into SSA names, hence moved to the
1474 top-level. */
1475 && !is_gimple_reg (t)
1476 && flag_stack_reuse != SR_NONE)
1478 tree clobber = build_clobber (TREE_TYPE (t), CLOBBER_EOL);
1479 gimple *clobber_stmt;
1480 clobber_stmt = gimple_build_assign (t, clobber);
1481 gimple_set_location (clobber_stmt, end_locus);
1482 gimplify_seq_add_stmt (&cleanup, clobber_stmt);
1485 if (flag_openacc && oacc_declare_returns != NULL)
1487 tree key = t;
1488 if (DECL_HAS_VALUE_EXPR_P (key))
1490 key = DECL_VALUE_EXPR (key);
1491 if (TREE_CODE (key) == INDIRECT_REF)
1492 key = TREE_OPERAND (key, 0);
1494 tree *c = oacc_declare_returns->get (key);
1495 if (c != NULL)
1497 if (ret_clauses)
1498 OMP_CLAUSE_CHAIN (*c) = ret_clauses;
1500 ret_clauses = unshare_expr (*c);
1502 oacc_declare_returns->remove (key);
1504 if (oacc_declare_returns->is_empty ())
1506 delete oacc_declare_returns;
1507 oacc_declare_returns = NULL;
1513 if (asan_poisoned_variables != NULL
1514 && asan_poisoned_variables->contains (t))
1516 asan_poisoned_variables->remove (t);
1517 asan_poison_variable (t, true, &cleanup);
1520 if (gimplify_ctxp->live_switch_vars != NULL
1521 && gimplify_ctxp->live_switch_vars->contains (t))
1522 gimplify_ctxp->live_switch_vars->remove (t);
1525 if (ret_clauses)
1527 gomp_target *stmt;
1528 gimple_stmt_iterator si = gsi_start (cleanup);
1530 stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
1531 ret_clauses);
1532 gsi_insert_seq_before_without_update (&si, stmt, GSI_NEW_STMT);
1535 if (cleanup)
1537 gtry *gs;
1538 gimple_seq new_body;
1540 new_body = NULL;
1541 gs = gimple_build_try (gimple_bind_body (bind_stmt), cleanup,
1542 GIMPLE_TRY_FINALLY);
1544 if (stack_save)
1545 gimplify_seq_add_stmt (&new_body, stack_save);
1546 gimplify_seq_add_stmt (&new_body, gs);
1547 gimple_bind_set_body (bind_stmt, new_body);
1550 /* keep_stack propagates all the way up to the outermost BIND_EXPR. */
1551 if (!gimplify_ctxp->keep_stack)
1552 gimplify_ctxp->keep_stack = old_keep_stack;
1553 gimplify_ctxp->save_stack = old_save_stack;
1555 gimple_pop_bind_expr ();
1557 gimplify_seq_add_stmt (pre_p, bind_stmt);
1559 if (temp)
1561 *expr_p = temp;
1562 return GS_OK;
1565 *expr_p = NULL_TREE;
1566 return GS_ALL_DONE;
1569 /* Maybe add early return predict statement to PRE_P sequence. */
1571 static void
1572 maybe_add_early_return_predict_stmt (gimple_seq *pre_p)
1574 /* If we are not in a conditional context, add PREDICT statement. */
1575 if (gimple_conditional_context ())
1577 gimple *predict = gimple_build_predict (PRED_TREE_EARLY_RETURN,
1578 NOT_TAKEN);
1579 gimplify_seq_add_stmt (pre_p, predict);
1583 /* Gimplify a RETURN_EXPR. If the expression to be returned is not a
1584 GIMPLE value, it is assigned to a new temporary and the statement is
1585 re-written to return the temporary.
1587 PRE_P points to the sequence where side effects that must happen before
1588 STMT should be stored. */
1590 static enum gimplify_status
1591 gimplify_return_expr (tree stmt, gimple_seq *pre_p)
1593 greturn *ret;
1594 tree ret_expr = TREE_OPERAND (stmt, 0);
1595 tree result_decl, result;
1597 if (ret_expr == error_mark_node)
1598 return GS_ERROR;
1600 if (!ret_expr
1601 || TREE_CODE (ret_expr) == RESULT_DECL)
1603 maybe_add_early_return_predict_stmt (pre_p);
1604 greturn *ret = gimple_build_return (ret_expr);
1605 copy_warning (ret, stmt);
1606 gimplify_seq_add_stmt (pre_p, ret);
1607 return GS_ALL_DONE;
1610 if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))))
1611 result_decl = NULL_TREE;
1612 else if (TREE_CODE (ret_expr) == COMPOUND_EXPR)
1614 /* Used in C++ for handling EH cleanup of the return value if a local
1615 cleanup throws. Assume the front-end knows what it's doing. */
1616 result_decl = DECL_RESULT (current_function_decl);
1617 /* But crash if we end up trying to modify ret_expr below. */
1618 ret_expr = NULL_TREE;
1620 else
1622 result_decl = TREE_OPERAND (ret_expr, 0);
1624 /* See through a return by reference. */
1625 if (TREE_CODE (result_decl) == INDIRECT_REF)
1626 result_decl = TREE_OPERAND (result_decl, 0);
1628 gcc_assert ((TREE_CODE (ret_expr) == MODIFY_EXPR
1629 || TREE_CODE (ret_expr) == INIT_EXPR)
1630 && TREE_CODE (result_decl) == RESULT_DECL);
1633 /* If aggregate_value_p is true, then we can return the bare RESULT_DECL.
1634 Recall that aggregate_value_p is FALSE for any aggregate type that is
1635 returned in registers. If we're returning values in registers, then
1636 we don't want to extend the lifetime of the RESULT_DECL, particularly
1637 across another call. In addition, for those aggregates for which
1638 hard_function_value generates a PARALLEL, we'll die during normal
1639 expansion of structure assignments; there's special code in expand_return
1640 to handle this case that does not exist in expand_expr. */
1641 if (!result_decl)
1642 result = NULL_TREE;
1643 else if (aggregate_value_p (result_decl, TREE_TYPE (current_function_decl)))
1645 if (!poly_int_tree_p (DECL_SIZE (result_decl)))
1647 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (result_decl)))
1648 gimplify_type_sizes (TREE_TYPE (result_decl), pre_p);
1649 /* Note that we don't use gimplify_vla_decl because the RESULT_DECL
1650 should be effectively allocated by the caller, i.e. all calls to
1651 this function must be subject to the Return Slot Optimization. */
1652 gimplify_one_sizepos (&DECL_SIZE (result_decl), pre_p);
1653 gimplify_one_sizepos (&DECL_SIZE_UNIT (result_decl), pre_p);
1655 result = result_decl;
1657 else if (gimplify_ctxp->return_temp)
1658 result = gimplify_ctxp->return_temp;
1659 else
1661 result = create_tmp_reg (TREE_TYPE (result_decl));
1663 /* ??? With complex control flow (usually involving abnormal edges),
1664 we can wind up warning about an uninitialized value for this. Due
1665 to how this variable is constructed and initialized, this is never
1666 true. Give up and never warn. */
1667 suppress_warning (result, OPT_Wuninitialized);
1669 gimplify_ctxp->return_temp = result;
1672 /* Smash the lhs of the MODIFY_EXPR to the temporary we plan to use.
1673 Then gimplify the whole thing. */
1674 if (result != result_decl)
1675 TREE_OPERAND (ret_expr, 0) = result;
1677 gimplify_and_add (TREE_OPERAND (stmt, 0), pre_p);
1679 maybe_add_early_return_predict_stmt (pre_p);
1680 ret = gimple_build_return (result);
1681 copy_warning (ret, stmt);
1682 gimplify_seq_add_stmt (pre_p, ret);
1684 return GS_ALL_DONE;
1687 /* Gimplify a variable-length array DECL. */
1689 static void
1690 gimplify_vla_decl (tree decl, gimple_seq *seq_p)
1692 /* This is a variable-sized decl. Simplify its size and mark it
1693 for deferred expansion. */
1694 tree t, addr, ptr_type;
1696 gimplify_one_sizepos (&DECL_SIZE (decl), seq_p);
1697 gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), seq_p);
1699 /* Don't mess with a DECL_VALUE_EXPR set by the front-end. */
1700 if (DECL_HAS_VALUE_EXPR_P (decl))
1701 return;
1703 /* All occurrences of this decl in final gimplified code will be
1704 replaced by indirection. Setting DECL_VALUE_EXPR does two
1705 things: First, it lets the rest of the gimplifier know what
1706 replacement to use. Second, it lets the debug info know
1707 where to find the value. */
1708 ptr_type = build_pointer_type (TREE_TYPE (decl));
1709 addr = create_tmp_var (ptr_type, get_name (decl));
1710 DECL_IGNORED_P (addr) = 0;
1711 t = build_fold_indirect_ref (addr);
1712 TREE_THIS_NOTRAP (t) = 1;
1713 SET_DECL_VALUE_EXPR (decl, t);
1714 DECL_HAS_VALUE_EXPR_P (decl) = 1;
1716 t = build_alloca_call_expr (DECL_SIZE_UNIT (decl), DECL_ALIGN (decl),
1717 max_int_size_in_bytes (TREE_TYPE (decl)));
1718 /* The call has been built for a variable-sized object. */
1719 CALL_ALLOCA_FOR_VAR_P (t) = 1;
1720 t = fold_convert (ptr_type, t);
1721 t = build2 (MODIFY_EXPR, TREE_TYPE (addr), addr, t);
1723 gimplify_and_add (t, seq_p);
1725 /* Record the dynamic allocation associated with DECL if requested. */
1726 if (flag_callgraph_info & CALLGRAPH_INFO_DYNAMIC_ALLOC)
1727 record_dynamic_alloc (decl);
1730 /* A helper function to be called via walk_tree. Mark all labels under *TP
1731 as being forced. To be called for DECL_INITIAL of static variables. */
1733 static tree
1734 force_labels_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
1736 if (TYPE_P (*tp))
1737 *walk_subtrees = 0;
1738 if (TREE_CODE (*tp) == LABEL_DECL)
1740 FORCED_LABEL (*tp) = 1;
1741 cfun->has_forced_label_in_static = 1;
1744 return NULL_TREE;
1747 /* Generate an initialization to automatic variable DECL based on INIT_TYPE.
1748 Build a call to internal const function DEFERRED_INIT:
1749 1st argument: SIZE of the DECL;
1750 2nd argument: INIT_TYPE;
1751 3rd argument: NAME of the DECL;
1753 as LHS = DEFERRED_INIT (SIZE of the DECL, INIT_TYPE, NAME of the DECL). */
1755 static void
1756 gimple_add_init_for_auto_var (tree decl,
1757 enum auto_init_type init_type,
1758 gimple_seq *seq_p)
1760 gcc_assert (auto_var_p (decl));
1761 gcc_assert (init_type > AUTO_INIT_UNINITIALIZED);
1762 location_t loc = EXPR_LOCATION (decl);
1763 tree decl_size = TYPE_SIZE_UNIT (TREE_TYPE (decl));
1765 tree init_type_node
1766 = build_int_cst (integer_type_node, (int) init_type);
1768 tree decl_name = NULL_TREE;
1769 if (DECL_NAME (decl))
1771 decl_name = build_string_literal (IDENTIFIER_LENGTH (DECL_NAME (decl)) + 1,
1772 IDENTIFIER_POINTER (DECL_NAME (decl)));
1774 else
1776 char *decl_name_anonymous = xasprintf ("D.%u", DECL_UID (decl));
1777 decl_name = build_string_literal (strlen (decl_name_anonymous) + 1,
1778 decl_name_anonymous);
1779 free (decl_name_anonymous);
1782 tree call = build_call_expr_internal_loc (loc, IFN_DEFERRED_INIT,
1783 TREE_TYPE (decl), 3,
1784 decl_size, init_type_node,
1785 decl_name);
1787 gimplify_assign (decl, call, seq_p);
1790 /* Generate padding initialization for automatic vairable DECL.
1791 C guarantees that brace-init with fewer initializers than members
1792 aggregate will initialize the rest of the aggregate as-if it were
1793 static initialization. In turn static initialization guarantees
1794 that padding is initialized to zero. So, we always initialize paddings
1795 to zeroes regardless INIT_TYPE.
1796 To do the padding initialization, we insert a call to
1797 __builtin_clear_padding (&decl, 0, for_auto_init = true).
1798 Note, we add an additional dummy argument for __builtin_clear_padding,
1799 'for_auto_init' to distinguish whether this call is for automatic
1800 variable initialization or not.
1802 static void
1803 gimple_add_padding_init_for_auto_var (tree decl, bool is_vla,
1804 gimple_seq *seq_p)
1806 tree addr_of_decl = NULL_TREE;
1807 bool for_auto_init = true;
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,
1825 3, addr_of_decl,
1826 build_zero_cst (TREE_TYPE (addr_of_decl)),
1827 build_int_cst (integer_type_node,
1828 (int) for_auto_init));
1829 gimplify_seq_add_stmt (seq_p, call);
1832 /* Return true if the DECL need to be automaticly initialized by the
1833 compiler. */
1834 static bool
1835 is_var_need_auto_init (tree decl)
1837 if (auto_var_p (decl)
1838 && (TREE_CODE (decl) != VAR_DECL
1839 || !DECL_HARD_REGISTER (decl))
1840 && (flag_auto_var_init > AUTO_INIT_UNINITIALIZED)
1841 && (!lookup_attribute ("uninitialized", DECL_ATTRIBUTES (decl)))
1842 && !OPAQUE_TYPE_P (TREE_TYPE (decl))
1843 && !is_empty_type (TREE_TYPE (decl)))
1844 return true;
1845 return false;
1848 /* Gimplify a DECL_EXPR node *STMT_P by making any necessary allocation
1849 and initialization explicit. */
1851 static enum gimplify_status
1852 gimplify_decl_expr (tree *stmt_p, gimple_seq *seq_p)
1854 tree stmt = *stmt_p;
1855 tree decl = DECL_EXPR_DECL (stmt);
1857 *stmt_p = NULL_TREE;
1859 if (TREE_TYPE (decl) == error_mark_node)
1860 return GS_ERROR;
1862 if ((TREE_CODE (decl) == TYPE_DECL
1863 || VAR_P (decl))
1864 && !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl)))
1866 gimplify_type_sizes (TREE_TYPE (decl), seq_p);
1867 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
1868 gimplify_type_sizes (TREE_TYPE (TREE_TYPE (decl)), seq_p);
1871 /* ??? DECL_ORIGINAL_TYPE is streamed for LTO so it needs to be gimplified
1872 in case its size expressions contain problematic nodes like CALL_EXPR. */
1873 if (TREE_CODE (decl) == TYPE_DECL
1874 && DECL_ORIGINAL_TYPE (decl)
1875 && !TYPE_SIZES_GIMPLIFIED (DECL_ORIGINAL_TYPE (decl)))
1877 gimplify_type_sizes (DECL_ORIGINAL_TYPE (decl), seq_p);
1878 if (TREE_CODE (DECL_ORIGINAL_TYPE (decl)) == REFERENCE_TYPE)
1879 gimplify_type_sizes (TREE_TYPE (DECL_ORIGINAL_TYPE (decl)), seq_p);
1882 if (VAR_P (decl) && !DECL_EXTERNAL (decl))
1884 tree init = DECL_INITIAL (decl);
1885 bool is_vla = false;
1886 /* Check whether a decl has FE created VALUE_EXPR here BEFORE
1887 gimplify_vla_decl creates VALUE_EXPR for a vla decl.
1888 If the decl has VALUE_EXPR that was created by FE (usually
1889 C++FE), it's a proxy varaible, and FE already initialized
1890 the VALUE_EXPR of it, we should not initialize it anymore. */
1891 bool decl_had_value_expr_p = DECL_HAS_VALUE_EXPR_P (decl);
1893 poly_uint64 size;
1894 if (!poly_int_tree_p (DECL_SIZE_UNIT (decl), &size)
1895 || (!TREE_STATIC (decl)
1896 && flag_stack_check == GENERIC_STACK_CHECK
1897 && maybe_gt (size,
1898 (unsigned HOST_WIDE_INT) STACK_CHECK_MAX_VAR_SIZE)))
1900 gimplify_vla_decl (decl, seq_p);
1901 is_vla = true;
1904 if (asan_poisoned_variables
1905 && !is_vla
1906 && TREE_ADDRESSABLE (decl)
1907 && !TREE_STATIC (decl)
1908 && !DECL_HAS_VALUE_EXPR_P (decl)
1909 && DECL_ALIGN (decl) <= MAX_SUPPORTED_STACK_ALIGNMENT
1910 && dbg_cnt (asan_use_after_scope)
1911 && !gimplify_omp_ctxp
1912 /* GNAT introduces temporaries to hold return values of calls in
1913 initializers of variables defined in other units, so the
1914 declaration of the variable is discarded completely. We do not
1915 want to issue poison calls for such dropped variables. */
1916 && (DECL_SEEN_IN_BIND_EXPR_P (decl)
1917 || (DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)))
1919 asan_poisoned_variables->add (decl);
1920 asan_poison_variable (decl, false, seq_p);
1921 if (!DECL_ARTIFICIAL (decl) && gimplify_ctxp->live_switch_vars)
1922 gimplify_ctxp->live_switch_vars->add (decl);
1925 /* Some front ends do not explicitly declare all anonymous
1926 artificial variables. We compensate here by declaring the
1927 variables, though it would be better if the front ends would
1928 explicitly declare them. */
1929 if (!DECL_SEEN_IN_BIND_EXPR_P (decl)
1930 && DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
1931 gimple_add_tmp_var (decl);
1933 if (init && init != error_mark_node)
1935 if (!TREE_STATIC (decl))
1937 DECL_INITIAL (decl) = NULL_TREE;
1938 init = build2 (INIT_EXPR, void_type_node, decl, init);
1939 gimplify_and_add (init, seq_p);
1940 ggc_free (init);
1941 /* Clear TREE_READONLY if we really have an initialization. */
1942 if (!DECL_INITIAL (decl)
1943 && !omp_privatize_by_reference (decl))
1944 TREE_READONLY (decl) = 0;
1946 else
1947 /* We must still examine initializers for static variables
1948 as they may contain a label address. */
1949 walk_tree (&init, force_labels_r, NULL, NULL);
1951 /* When there is no explicit initializer, if the user requested,
1952 We should insert an artifical initializer for this automatic
1953 variable. */
1954 else if (is_var_need_auto_init (decl)
1955 && !decl_had_value_expr_p)
1957 gimple_add_init_for_auto_var (decl,
1958 flag_auto_var_init,
1959 seq_p);
1960 /* The expanding of a call to the above .DEFERRED_INIT will apply
1961 block initialization to the whole space covered by this variable.
1962 As a result, all the paddings will be initialized to zeroes
1963 for zero initialization and 0xFE byte-repeatable patterns for
1964 pattern initialization.
1965 In order to make the paddings as zeroes for pattern init, We
1966 should add a call to __builtin_clear_padding to clear the
1967 paddings to zero in compatiple with CLANG.
1968 We cannot insert this call if the variable is a gimple register
1969 since __builtin_clear_padding will take the address of the
1970 variable. As a result, if a long double/_Complex long double
1971 variable will spilled into stack later, its padding is 0XFE. */
1972 if (flag_auto_var_init == AUTO_INIT_PATTERN
1973 && !is_gimple_reg (decl)
1974 && clear_padding_type_may_have_padding_p (TREE_TYPE (decl)))
1975 gimple_add_padding_init_for_auto_var (decl, is_vla, seq_p);
1979 return GS_ALL_DONE;
1982 /* Gimplify a LOOP_EXPR. Normally this just involves gimplifying the body
1983 and replacing the LOOP_EXPR with goto, but if the loop contains an
1984 EXIT_EXPR, we need to append a label for it to jump to. */
1986 static enum gimplify_status
1987 gimplify_loop_expr (tree *expr_p, gimple_seq *pre_p)
1989 tree saved_label = gimplify_ctxp->exit_label;
1990 tree start_label = create_artificial_label (UNKNOWN_LOCATION);
1992 gimplify_seq_add_stmt (pre_p, gimple_build_label (start_label));
1994 gimplify_ctxp->exit_label = NULL_TREE;
1996 gimplify_and_add (LOOP_EXPR_BODY (*expr_p), pre_p);
1998 gimplify_seq_add_stmt (pre_p, gimple_build_goto (start_label));
2000 if (gimplify_ctxp->exit_label)
2001 gimplify_seq_add_stmt (pre_p,
2002 gimple_build_label (gimplify_ctxp->exit_label));
2004 gimplify_ctxp->exit_label = saved_label;
2006 *expr_p = NULL;
2007 return GS_ALL_DONE;
2010 /* Gimplify a statement list onto a sequence. These may be created either
2011 by an enlightened front-end, or by shortcut_cond_expr. */
2013 static enum gimplify_status
2014 gimplify_statement_list (tree *expr_p, gimple_seq *pre_p)
2016 tree temp = voidify_wrapper_expr (*expr_p, NULL);
2018 tree_stmt_iterator i = tsi_start (*expr_p);
2020 while (!tsi_end_p (i))
2022 gimplify_stmt (tsi_stmt_ptr (i), pre_p);
2023 tsi_delink (&i);
2026 if (temp)
2028 *expr_p = temp;
2029 return GS_OK;
2032 return GS_ALL_DONE;
2035 /* Callback for walk_gimple_seq. */
2037 static tree
2038 warn_switch_unreachable_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
2039 struct walk_stmt_info *wi)
2041 gimple *stmt = gsi_stmt (*gsi_p);
2043 *handled_ops_p = true;
2044 switch (gimple_code (stmt))
2046 case GIMPLE_TRY:
2047 /* A compiler-generated cleanup or a user-written try block.
2048 If it's empty, don't dive into it--that would result in
2049 worse location info. */
2050 if (gimple_try_eval (stmt) == NULL)
2052 wi->info = stmt;
2053 return integer_zero_node;
2055 /* Fall through. */
2056 case GIMPLE_BIND:
2057 case GIMPLE_CATCH:
2058 case GIMPLE_EH_FILTER:
2059 case GIMPLE_TRANSACTION:
2060 /* Walk the sub-statements. */
2061 *handled_ops_p = false;
2062 break;
2064 case GIMPLE_DEBUG:
2065 /* Ignore these. We may generate them before declarations that
2066 are never executed. If there's something to warn about,
2067 there will be non-debug stmts too, and we'll catch those. */
2068 break;
2070 case GIMPLE_CALL:
2071 if (gimple_call_internal_p (stmt, IFN_ASAN_MARK))
2073 *handled_ops_p = false;
2074 break;
2076 /* Fall through. */
2077 default:
2078 /* Save the first "real" statement (not a decl/lexical scope/...). */
2079 wi->info = stmt;
2080 return integer_zero_node;
2082 return NULL_TREE;
2085 /* Possibly warn about unreachable statements between switch's controlling
2086 expression and the first case. SEQ is the body of a switch expression. */
2088 static void
2089 maybe_warn_switch_unreachable (gimple_seq seq)
2091 if (!warn_switch_unreachable
2092 /* This warning doesn't play well with Fortran when optimizations
2093 are on. */
2094 || lang_GNU_Fortran ()
2095 || seq == NULL)
2096 return;
2098 struct walk_stmt_info wi;
2099 memset (&wi, 0, sizeof (wi));
2100 walk_gimple_seq (seq, warn_switch_unreachable_r, NULL, &wi);
2101 gimple *stmt = (gimple *) wi.info;
2103 if (stmt && gimple_code (stmt) != GIMPLE_LABEL)
2105 if (gimple_code (stmt) == GIMPLE_GOTO
2106 && TREE_CODE (gimple_goto_dest (stmt)) == LABEL_DECL
2107 && DECL_ARTIFICIAL (gimple_goto_dest (stmt)))
2108 /* Don't warn for compiler-generated gotos. These occur
2109 in Duff's devices, for example. */;
2110 else
2111 warning_at (gimple_location (stmt), OPT_Wswitch_unreachable,
2112 "statement will never be executed");
2117 /* A label entry that pairs label and a location. */
2118 struct label_entry
2120 tree label;
2121 location_t loc;
2124 /* Find LABEL in vector of label entries VEC. */
2126 static struct label_entry *
2127 find_label_entry (const auto_vec<struct label_entry> *vec, tree label)
2129 unsigned int i;
2130 struct label_entry *l;
2132 FOR_EACH_VEC_ELT (*vec, i, l)
2133 if (l->label == label)
2134 return l;
2135 return NULL;
2138 /* Return true if LABEL, a LABEL_DECL, represents a case label
2139 in a vector of labels CASES. */
2141 static bool
2142 case_label_p (const vec<tree> *cases, tree label)
2144 unsigned int i;
2145 tree l;
2147 FOR_EACH_VEC_ELT (*cases, i, l)
2148 if (CASE_LABEL (l) == label)
2149 return true;
2150 return false;
2153 /* Find the last nondebug statement in a scope STMT. */
2155 static gimple *
2156 last_stmt_in_scope (gimple *stmt)
2158 if (!stmt)
2159 return NULL;
2161 switch (gimple_code (stmt))
2163 case GIMPLE_BIND:
2165 gbind *bind = as_a <gbind *> (stmt);
2166 stmt = gimple_seq_last_nondebug_stmt (gimple_bind_body (bind));
2167 return last_stmt_in_scope (stmt);
2170 case GIMPLE_TRY:
2172 gtry *try_stmt = as_a <gtry *> (stmt);
2173 stmt = gimple_seq_last_nondebug_stmt (gimple_try_eval (try_stmt));
2174 gimple *last_eval = last_stmt_in_scope (stmt);
2175 if (gimple_stmt_may_fallthru (last_eval)
2176 && (last_eval == NULL
2177 || !gimple_call_internal_p (last_eval, IFN_FALLTHROUGH))
2178 && gimple_try_kind (try_stmt) == GIMPLE_TRY_FINALLY)
2180 stmt = gimple_seq_last_nondebug_stmt (gimple_try_cleanup (try_stmt));
2181 return last_stmt_in_scope (stmt);
2183 else
2184 return last_eval;
2187 case GIMPLE_DEBUG:
2188 gcc_unreachable ();
2190 default:
2191 return stmt;
2195 /* Collect interesting labels in LABELS and return the statement preceding
2196 another case label, or a user-defined label. Store a location useful
2197 to give warnings at *PREVLOC (usually the location of the returned
2198 statement or of its surrounding scope). */
2200 static gimple *
2201 collect_fallthrough_labels (gimple_stmt_iterator *gsi_p,
2202 auto_vec <struct label_entry> *labels,
2203 location_t *prevloc)
2205 gimple *prev = NULL;
2207 *prevloc = UNKNOWN_LOCATION;
2210 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND)
2212 /* Recognize the special GIMPLE_BIND added by gimplify_switch_expr,
2213 which starts on a GIMPLE_SWITCH and ends with a break label.
2214 Handle that as a single statement that can fall through. */
2215 gbind *bind = as_a <gbind *> (gsi_stmt (*gsi_p));
2216 gimple *first = gimple_seq_first_stmt (gimple_bind_body (bind));
2217 gimple *last = gimple_seq_last_stmt (gimple_bind_body (bind));
2218 if (last
2219 && gimple_code (first) == GIMPLE_SWITCH
2220 && gimple_code (last) == GIMPLE_LABEL)
2222 tree label = gimple_label_label (as_a <glabel *> (last));
2223 if (SWITCH_BREAK_LABEL_P (label))
2225 prev = bind;
2226 gsi_next (gsi_p);
2227 continue;
2231 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND
2232 || gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_TRY)
2234 /* Nested scope. Only look at the last statement of
2235 the innermost scope. */
2236 location_t bind_loc = gimple_location (gsi_stmt (*gsi_p));
2237 gimple *last = last_stmt_in_scope (gsi_stmt (*gsi_p));
2238 if (last)
2240 prev = last;
2241 /* It might be a label without a location. Use the
2242 location of the scope then. */
2243 if (!gimple_has_location (prev))
2244 *prevloc = bind_loc;
2246 gsi_next (gsi_p);
2247 continue;
2250 /* Ifs are tricky. */
2251 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_COND)
2253 gcond *cond_stmt = as_a <gcond *> (gsi_stmt (*gsi_p));
2254 tree false_lab = gimple_cond_false_label (cond_stmt);
2255 location_t if_loc = gimple_location (cond_stmt);
2257 /* If we have e.g.
2258 if (i > 1) goto <D.2259>; else goto D;
2259 we can't do much with the else-branch. */
2260 if (!DECL_ARTIFICIAL (false_lab))
2261 break;
2263 /* Go on until the false label, then one step back. */
2264 for (; !gsi_end_p (*gsi_p); gsi_next (gsi_p))
2266 gimple *stmt = gsi_stmt (*gsi_p);
2267 if (gimple_code (stmt) == GIMPLE_LABEL
2268 && gimple_label_label (as_a <glabel *> (stmt)) == false_lab)
2269 break;
2272 /* Not found? Oops. */
2273 if (gsi_end_p (*gsi_p))
2274 break;
2276 struct label_entry l = { false_lab, if_loc };
2277 labels->safe_push (l);
2279 /* Go to the last statement of the then branch. */
2280 gsi_prev (gsi_p);
2282 /* if (i != 0) goto <D.1759>; else goto <D.1760>;
2283 <D.1759>:
2284 <stmt>;
2285 goto <D.1761>;
2286 <D.1760>:
2288 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_GOTO
2289 && !gimple_has_location (gsi_stmt (*gsi_p)))
2291 /* Look at the statement before, it might be
2292 attribute fallthrough, in which case don't warn. */
2293 gsi_prev (gsi_p);
2294 bool fallthru_before_dest
2295 = gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_FALLTHROUGH);
2296 gsi_next (gsi_p);
2297 tree goto_dest = gimple_goto_dest (gsi_stmt (*gsi_p));
2298 if (!fallthru_before_dest)
2300 struct label_entry l = { goto_dest, if_loc };
2301 labels->safe_push (l);
2304 /* And move back. */
2305 gsi_next (gsi_p);
2308 /* Remember the last statement. Skip labels that are of no interest
2309 to us. */
2310 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
2312 tree label = gimple_label_label (as_a <glabel *> (gsi_stmt (*gsi_p)));
2313 if (find_label_entry (labels, label))
2314 prev = gsi_stmt (*gsi_p);
2316 else if (gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_ASAN_MARK))
2318 else if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_PREDICT)
2320 else if (!is_gimple_debug (gsi_stmt (*gsi_p)))
2321 prev = gsi_stmt (*gsi_p);
2322 gsi_next (gsi_p);
2324 while (!gsi_end_p (*gsi_p)
2325 /* Stop if we find a case or a user-defined label. */
2326 && (gimple_code (gsi_stmt (*gsi_p)) != GIMPLE_LABEL
2327 || !gimple_has_location (gsi_stmt (*gsi_p))));
2329 if (prev && gimple_has_location (prev))
2330 *prevloc = gimple_location (prev);
2331 return prev;
2334 /* Return true if the switch fallthough warning should occur. LABEL is
2335 the label statement that we're falling through to. */
2337 static bool
2338 should_warn_for_implicit_fallthrough (gimple_stmt_iterator *gsi_p, tree label)
2340 gimple_stmt_iterator gsi = *gsi_p;
2342 /* Don't warn if the label is marked with a "falls through" comment. */
2343 if (FALLTHROUGH_LABEL_P (label))
2344 return false;
2346 /* Don't warn for non-case labels followed by a statement:
2347 case 0:
2348 foo ();
2349 label:
2350 bar ();
2351 as these are likely intentional. */
2352 if (!case_label_p (&gimplify_ctxp->case_labels, label))
2354 tree l;
2355 while (!gsi_end_p (gsi)
2356 && gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
2357 && (l = gimple_label_label (as_a <glabel *> (gsi_stmt (gsi))))
2358 && !case_label_p (&gimplify_ctxp->case_labels, l))
2359 gsi_next_nondebug (&gsi);
2360 if (gsi_end_p (gsi) || gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL)
2361 return false;
2364 /* Don't warn for terminated branches, i.e. when the subsequent case labels
2365 immediately breaks. */
2366 gsi = *gsi_p;
2368 /* Skip all immediately following labels. */
2369 while (!gsi_end_p (gsi)
2370 && (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
2371 || gimple_code (gsi_stmt (gsi)) == GIMPLE_PREDICT))
2372 gsi_next_nondebug (&gsi);
2374 /* { ... something; default:; } */
2375 if (gsi_end_p (gsi)
2376 /* { ... something; default: break; } or
2377 { ... something; default: goto L; } */
2378 || gimple_code (gsi_stmt (gsi)) == GIMPLE_GOTO
2379 /* { ... something; default: return; } */
2380 || gimple_code (gsi_stmt (gsi)) == GIMPLE_RETURN)
2381 return false;
2383 return true;
2386 /* Callback for walk_gimple_seq. */
2388 static tree
2389 warn_implicit_fallthrough_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
2390 struct walk_stmt_info *)
2392 gimple *stmt = gsi_stmt (*gsi_p);
2394 *handled_ops_p = true;
2395 switch (gimple_code (stmt))
2397 case GIMPLE_TRY:
2398 case GIMPLE_BIND:
2399 case GIMPLE_CATCH:
2400 case GIMPLE_EH_FILTER:
2401 case GIMPLE_TRANSACTION:
2402 /* Walk the sub-statements. */
2403 *handled_ops_p = false;
2404 break;
2406 /* Find a sequence of form:
2408 GIMPLE_LABEL
2409 [...]
2410 <may fallthru stmt>
2411 GIMPLE_LABEL
2413 and possibly warn. */
2414 case GIMPLE_LABEL:
2416 /* Found a label. Skip all immediately following labels. */
2417 while (!gsi_end_p (*gsi_p)
2418 && gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
2419 gsi_next_nondebug (gsi_p);
2421 /* There might be no more statements. */
2422 if (gsi_end_p (*gsi_p))
2423 return integer_zero_node;
2425 /* Vector of labels that fall through. */
2426 auto_vec <struct label_entry> labels;
2427 location_t prevloc;
2428 gimple *prev = collect_fallthrough_labels (gsi_p, &labels, &prevloc);
2430 /* There might be no more statements. */
2431 if (gsi_end_p (*gsi_p))
2432 return integer_zero_node;
2434 gimple *next = gsi_stmt (*gsi_p);
2435 tree label;
2436 /* If what follows is a label, then we may have a fallthrough. */
2437 if (gimple_code (next) == GIMPLE_LABEL
2438 && gimple_has_location (next)
2439 && (label = gimple_label_label (as_a <glabel *> (next)))
2440 && prev != NULL)
2442 struct label_entry *l;
2443 bool warned_p = false;
2444 auto_diagnostic_group d;
2445 if (!should_warn_for_implicit_fallthrough (gsi_p, label))
2446 /* Quiet. */;
2447 else if (gimple_code (prev) == GIMPLE_LABEL
2448 && (label = gimple_label_label (as_a <glabel *> (prev)))
2449 && (l = find_label_entry (&labels, label)))
2450 warned_p = warning_at (l->loc, OPT_Wimplicit_fallthrough_,
2451 "this statement may fall through");
2452 else if (!gimple_call_internal_p (prev, IFN_FALLTHROUGH)
2453 /* Try to be clever and don't warn when the statement
2454 can't actually fall through. */
2455 && gimple_stmt_may_fallthru (prev)
2456 && prevloc != UNKNOWN_LOCATION)
2457 warned_p = warning_at (prevloc,
2458 OPT_Wimplicit_fallthrough_,
2459 "this statement may fall through");
2460 if (warned_p)
2461 inform (gimple_location (next), "here");
2463 /* Mark this label as processed so as to prevent multiple
2464 warnings in nested switches. */
2465 FALLTHROUGH_LABEL_P (label) = true;
2467 /* So that next warn_implicit_fallthrough_r will start looking for
2468 a new sequence starting with this label. */
2469 gsi_prev (gsi_p);
2472 break;
2473 default:
2474 break;
2476 return NULL_TREE;
2479 /* Warn when a switch case falls through. */
2481 static void
2482 maybe_warn_implicit_fallthrough (gimple_seq seq)
2484 if (!warn_implicit_fallthrough)
2485 return;
2487 /* This warning is meant for C/C++/ObjC/ObjC++ only. */
2488 if (!(lang_GNU_C ()
2489 || lang_GNU_CXX ()
2490 || lang_GNU_OBJC ()))
2491 return;
2493 struct walk_stmt_info wi;
2494 memset (&wi, 0, sizeof (wi));
2495 walk_gimple_seq (seq, warn_implicit_fallthrough_r, NULL, &wi);
2498 /* Callback for walk_gimple_seq. */
2500 static tree
2501 expand_FALLTHROUGH_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
2502 struct walk_stmt_info *wi)
2504 gimple *stmt = gsi_stmt (*gsi_p);
2506 *handled_ops_p = true;
2507 switch (gimple_code (stmt))
2509 case GIMPLE_TRY:
2510 case GIMPLE_BIND:
2511 case GIMPLE_CATCH:
2512 case GIMPLE_EH_FILTER:
2513 case GIMPLE_TRANSACTION:
2514 /* Walk the sub-statements. */
2515 *handled_ops_p = false;
2516 break;
2517 case GIMPLE_CALL:
2518 if (gimple_call_internal_p (stmt, IFN_FALLTHROUGH))
2520 gsi_remove (gsi_p, true);
2521 if (gsi_end_p (*gsi_p))
2523 *static_cast<location_t *>(wi->info) = gimple_location (stmt);
2524 return integer_zero_node;
2527 bool found = false;
2528 location_t loc = gimple_location (stmt);
2530 gimple_stmt_iterator gsi2 = *gsi_p;
2531 stmt = gsi_stmt (gsi2);
2532 if (gimple_code (stmt) == GIMPLE_GOTO && !gimple_has_location (stmt))
2534 /* Go on until the artificial label. */
2535 tree goto_dest = gimple_goto_dest (stmt);
2536 for (; !gsi_end_p (gsi2); gsi_next (&gsi2))
2538 if (gimple_code (gsi_stmt (gsi2)) == GIMPLE_LABEL
2539 && gimple_label_label (as_a <glabel *> (gsi_stmt (gsi2)))
2540 == goto_dest)
2541 break;
2544 /* Not found? Stop. */
2545 if (gsi_end_p (gsi2))
2546 break;
2548 /* Look one past it. */
2549 gsi_next (&gsi2);
2552 /* We're looking for a case label or default label here. */
2553 while (!gsi_end_p (gsi2))
2555 stmt = gsi_stmt (gsi2);
2556 if (gimple_code (stmt) == GIMPLE_LABEL)
2558 tree label = gimple_label_label (as_a <glabel *> (stmt));
2559 if (gimple_has_location (stmt) && DECL_ARTIFICIAL (label))
2561 found = true;
2562 break;
2565 else if (gimple_call_internal_p (stmt, IFN_ASAN_MARK))
2567 else if (!is_gimple_debug (stmt))
2568 /* Anything else is not expected. */
2569 break;
2570 gsi_next (&gsi2);
2572 if (!found)
2573 pedwarn (loc, 0, "attribute %<fallthrough%> not preceding "
2574 "a case label or default label");
2576 break;
2577 default:
2578 break;
2580 return NULL_TREE;
2583 /* Expand all FALLTHROUGH () calls in SEQ. */
2585 static void
2586 expand_FALLTHROUGH (gimple_seq *seq_p)
2588 struct walk_stmt_info wi;
2589 location_t loc;
2590 memset (&wi, 0, sizeof (wi));
2591 wi.info = (void *) &loc;
2592 walk_gimple_seq_mod (seq_p, expand_FALLTHROUGH_r, NULL, &wi);
2593 if (wi.callback_result == integer_zero_node)
2594 /* We've found [[fallthrough]]; at the end of a switch, which the C++
2595 standard says is ill-formed; see [dcl.attr.fallthrough]. */
2596 pedwarn (loc, 0, "attribute %<fallthrough%> not preceding "
2597 "a case label or default label");
2601 /* Gimplify a SWITCH_EXPR, and collect the vector of labels it can
2602 branch to. */
2604 static enum gimplify_status
2605 gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p)
2607 tree switch_expr = *expr_p;
2608 gimple_seq switch_body_seq = NULL;
2609 enum gimplify_status ret;
2610 tree index_type = TREE_TYPE (switch_expr);
2611 if (index_type == NULL_TREE)
2612 index_type = TREE_TYPE (SWITCH_COND (switch_expr));
2614 ret = gimplify_expr (&SWITCH_COND (switch_expr), pre_p, NULL, is_gimple_val,
2615 fb_rvalue);
2616 if (ret == GS_ERROR || ret == GS_UNHANDLED)
2617 return ret;
2619 if (SWITCH_BODY (switch_expr))
2621 vec<tree> labels;
2622 vec<tree> saved_labels;
2623 hash_set<tree> *saved_live_switch_vars = NULL;
2624 tree default_case = NULL_TREE;
2625 gswitch *switch_stmt;
2627 /* Save old labels, get new ones from body, then restore the old
2628 labels. Save all the things from the switch body to append after. */
2629 saved_labels = gimplify_ctxp->case_labels;
2630 gimplify_ctxp->case_labels.create (8);
2632 /* Do not create live_switch_vars if SWITCH_BODY is not a BIND_EXPR. */
2633 saved_live_switch_vars = gimplify_ctxp->live_switch_vars;
2634 tree_code body_type = TREE_CODE (SWITCH_BODY (switch_expr));
2635 if (body_type == BIND_EXPR || body_type == STATEMENT_LIST)
2636 gimplify_ctxp->live_switch_vars = new hash_set<tree> (4);
2637 else
2638 gimplify_ctxp->live_switch_vars = NULL;
2640 bool old_in_switch_expr = gimplify_ctxp->in_switch_expr;
2641 gimplify_ctxp->in_switch_expr = true;
2643 gimplify_stmt (&SWITCH_BODY (switch_expr), &switch_body_seq);
2645 gimplify_ctxp->in_switch_expr = old_in_switch_expr;
2646 maybe_warn_switch_unreachable (switch_body_seq);
2647 maybe_warn_implicit_fallthrough (switch_body_seq);
2648 /* Only do this for the outermost GIMPLE_SWITCH. */
2649 if (!gimplify_ctxp->in_switch_expr)
2650 expand_FALLTHROUGH (&switch_body_seq);
2652 labels = gimplify_ctxp->case_labels;
2653 gimplify_ctxp->case_labels = saved_labels;
2655 if (gimplify_ctxp->live_switch_vars)
2657 gcc_assert (gimplify_ctxp->live_switch_vars->is_empty ());
2658 delete gimplify_ctxp->live_switch_vars;
2660 gimplify_ctxp->live_switch_vars = saved_live_switch_vars;
2662 preprocess_case_label_vec_for_gimple (labels, index_type,
2663 &default_case);
2665 bool add_bind = false;
2666 if (!default_case)
2668 glabel *new_default;
2670 default_case
2671 = build_case_label (NULL_TREE, NULL_TREE,
2672 create_artificial_label (UNKNOWN_LOCATION));
2673 if (old_in_switch_expr)
2675 SWITCH_BREAK_LABEL_P (CASE_LABEL (default_case)) = 1;
2676 add_bind = true;
2678 new_default = gimple_build_label (CASE_LABEL (default_case));
2679 gimplify_seq_add_stmt (&switch_body_seq, new_default);
2681 else if (old_in_switch_expr)
2683 gimple *last = gimple_seq_last_stmt (switch_body_seq);
2684 if (last && gimple_code (last) == GIMPLE_LABEL)
2686 tree label = gimple_label_label (as_a <glabel *> (last));
2687 if (SWITCH_BREAK_LABEL_P (label))
2688 add_bind = true;
2692 switch_stmt = gimple_build_switch (SWITCH_COND (switch_expr),
2693 default_case, labels);
2694 /* For the benefit of -Wimplicit-fallthrough, if switch_body_seq
2695 ends with a GIMPLE_LABEL holding SWITCH_BREAK_LABEL_P LABEL_DECL,
2696 wrap the GIMPLE_SWITCH up to that GIMPLE_LABEL into a GIMPLE_BIND,
2697 so that we can easily find the start and end of the switch
2698 statement. */
2699 if (add_bind)
2701 gimple_seq bind_body = NULL;
2702 gimplify_seq_add_stmt (&bind_body, switch_stmt);
2703 gimple_seq_add_seq (&bind_body, switch_body_seq);
2704 gbind *bind = gimple_build_bind (NULL_TREE, bind_body, NULL_TREE);
2705 gimple_set_location (bind, EXPR_LOCATION (switch_expr));
2706 gimplify_seq_add_stmt (pre_p, bind);
2708 else
2710 gimplify_seq_add_stmt (pre_p, switch_stmt);
2711 gimplify_seq_add_seq (pre_p, switch_body_seq);
2713 labels.release ();
2715 else
2716 gcc_unreachable ();
2718 return GS_ALL_DONE;
2721 /* Gimplify the LABEL_EXPR pointed to by EXPR_P. */
2723 static enum gimplify_status
2724 gimplify_label_expr (tree *expr_p, gimple_seq *pre_p)
2726 gcc_assert (decl_function_context (LABEL_EXPR_LABEL (*expr_p))
2727 == current_function_decl);
2729 tree label = LABEL_EXPR_LABEL (*expr_p);
2730 glabel *label_stmt = gimple_build_label (label);
2731 gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
2732 gimplify_seq_add_stmt (pre_p, label_stmt);
2734 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label)))
2735 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_COLD_LABEL,
2736 NOT_TAKEN));
2737 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label)))
2738 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_HOT_LABEL,
2739 TAKEN));
2741 return GS_ALL_DONE;
2744 /* Gimplify the CASE_LABEL_EXPR pointed to by EXPR_P. */
2746 static enum gimplify_status
2747 gimplify_case_label_expr (tree *expr_p, gimple_seq *pre_p)
2749 struct gimplify_ctx *ctxp;
2750 glabel *label_stmt;
2752 /* Invalid programs can play Duff's Device type games with, for example,
2753 #pragma omp parallel. At least in the C front end, we don't
2754 detect such invalid branches until after gimplification, in the
2755 diagnose_omp_blocks pass. */
2756 for (ctxp = gimplify_ctxp; ; ctxp = ctxp->prev_context)
2757 if (ctxp->case_labels.exists ())
2758 break;
2760 tree label = CASE_LABEL (*expr_p);
2761 label_stmt = gimple_build_label (label);
2762 gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
2763 ctxp->case_labels.safe_push (*expr_p);
2764 gimplify_seq_add_stmt (pre_p, label_stmt);
2766 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label)))
2767 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_COLD_LABEL,
2768 NOT_TAKEN));
2769 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label)))
2770 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_HOT_LABEL,
2771 TAKEN));
2773 return GS_ALL_DONE;
2776 /* Build a GOTO to the LABEL_DECL pointed to by LABEL_P, building it first
2777 if necessary. */
2779 tree
2780 build_and_jump (tree *label_p)
2782 if (label_p == NULL)
2783 /* If there's nowhere to jump, just fall through. */
2784 return NULL_TREE;
2786 if (*label_p == NULL_TREE)
2788 tree label = create_artificial_label (UNKNOWN_LOCATION);
2789 *label_p = label;
2792 return build1 (GOTO_EXPR, void_type_node, *label_p);
2795 /* Gimplify an EXIT_EXPR by converting to a GOTO_EXPR inside a COND_EXPR.
2796 This also involves building a label to jump to and communicating it to
2797 gimplify_loop_expr through gimplify_ctxp->exit_label. */
2799 static enum gimplify_status
2800 gimplify_exit_expr (tree *expr_p)
2802 tree cond = TREE_OPERAND (*expr_p, 0);
2803 tree expr;
2805 expr = build_and_jump (&gimplify_ctxp->exit_label);
2806 expr = build3 (COND_EXPR, void_type_node, cond, expr, NULL_TREE);
2807 *expr_p = expr;
2809 return GS_OK;
2812 /* *EXPR_P is a COMPONENT_REF being used as an rvalue. If its type is
2813 different from its canonical type, wrap the whole thing inside a
2814 NOP_EXPR and force the type of the COMPONENT_REF to be the canonical
2815 type.
2817 The canonical type of a COMPONENT_REF is the type of the field being
2818 referenced--unless the field is a bit-field which can be read directly
2819 in a smaller mode, in which case the canonical type is the
2820 sign-appropriate type corresponding to that mode. */
2822 static void
2823 canonicalize_component_ref (tree *expr_p)
2825 tree expr = *expr_p;
2826 tree type;
2828 gcc_assert (TREE_CODE (expr) == COMPONENT_REF);
2830 if (INTEGRAL_TYPE_P (TREE_TYPE (expr)))
2831 type = TREE_TYPE (get_unwidened (expr, NULL_TREE));
2832 else
2833 type = TREE_TYPE (TREE_OPERAND (expr, 1));
2835 /* One could argue that all the stuff below is not necessary for
2836 the non-bitfield case and declare it a FE error if type
2837 adjustment would be needed. */
2838 if (TREE_TYPE (expr) != type)
2840 #ifdef ENABLE_TYPES_CHECKING
2841 tree old_type = TREE_TYPE (expr);
2842 #endif
2843 int type_quals;
2845 /* We need to preserve qualifiers and propagate them from
2846 operand 0. */
2847 type_quals = TYPE_QUALS (type)
2848 | TYPE_QUALS (TREE_TYPE (TREE_OPERAND (expr, 0)));
2849 if (TYPE_QUALS (type) != type_quals)
2850 type = build_qualified_type (TYPE_MAIN_VARIANT (type), type_quals);
2852 /* Set the type of the COMPONENT_REF to the underlying type. */
2853 TREE_TYPE (expr) = type;
2855 #ifdef ENABLE_TYPES_CHECKING
2856 /* It is now a FE error, if the conversion from the canonical
2857 type to the original expression type is not useless. */
2858 gcc_assert (useless_type_conversion_p (old_type, type));
2859 #endif
2863 /* If a NOP conversion is changing a pointer to array of foo to a pointer
2864 to foo, embed that change in the ADDR_EXPR by converting
2865 T array[U];
2866 (T *)&array
2868 &array[L]
2869 where L is the lower bound. For simplicity, only do this for constant
2870 lower bound.
2871 The constraint is that the type of &array[L] is trivially convertible
2872 to T *. */
2874 static void
2875 canonicalize_addr_expr (tree *expr_p)
2877 tree expr = *expr_p;
2878 tree addr_expr = TREE_OPERAND (expr, 0);
2879 tree datype, ddatype, pddatype;
2881 /* We simplify only conversions from an ADDR_EXPR to a pointer type. */
2882 if (!POINTER_TYPE_P (TREE_TYPE (expr))
2883 || TREE_CODE (addr_expr) != ADDR_EXPR)
2884 return;
2886 /* The addr_expr type should be a pointer to an array. */
2887 datype = TREE_TYPE (TREE_TYPE (addr_expr));
2888 if (TREE_CODE (datype) != ARRAY_TYPE)
2889 return;
2891 /* The pointer to element type shall be trivially convertible to
2892 the expression pointer type. */
2893 ddatype = TREE_TYPE (datype);
2894 pddatype = build_pointer_type (ddatype);
2895 if (!useless_type_conversion_p (TYPE_MAIN_VARIANT (TREE_TYPE (expr)),
2896 pddatype))
2897 return;
2899 /* The lower bound and element sizes must be constant. */
2900 if (!TYPE_SIZE_UNIT (ddatype)
2901 || TREE_CODE (TYPE_SIZE_UNIT (ddatype)) != INTEGER_CST
2902 || !TYPE_DOMAIN (datype) || !TYPE_MIN_VALUE (TYPE_DOMAIN (datype))
2903 || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (datype))) != INTEGER_CST)
2904 return;
2906 /* All checks succeeded. Build a new node to merge the cast. */
2907 *expr_p = build4 (ARRAY_REF, ddatype, TREE_OPERAND (addr_expr, 0),
2908 TYPE_MIN_VALUE (TYPE_DOMAIN (datype)),
2909 NULL_TREE, NULL_TREE);
2910 *expr_p = build1 (ADDR_EXPR, pddatype, *expr_p);
2912 /* We can have stripped a required restrict qualifier above. */
2913 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
2914 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
2917 /* *EXPR_P is a NOP_EXPR or CONVERT_EXPR. Remove it and/or other conversions
2918 underneath as appropriate. */
2920 static enum gimplify_status
2921 gimplify_conversion (tree *expr_p)
2923 location_t loc = EXPR_LOCATION (*expr_p);
2924 gcc_assert (CONVERT_EXPR_P (*expr_p));
2926 /* Then strip away all but the outermost conversion. */
2927 STRIP_SIGN_NOPS (TREE_OPERAND (*expr_p, 0));
2929 /* And remove the outermost conversion if it's useless. */
2930 if (tree_ssa_useless_type_conversion (*expr_p))
2931 *expr_p = TREE_OPERAND (*expr_p, 0);
2933 /* If we still have a conversion at the toplevel,
2934 then canonicalize some constructs. */
2935 if (CONVERT_EXPR_P (*expr_p))
2937 tree sub = TREE_OPERAND (*expr_p, 0);
2939 /* If a NOP conversion is changing the type of a COMPONENT_REF
2940 expression, then canonicalize its type now in order to expose more
2941 redundant conversions. */
2942 if (TREE_CODE (sub) == COMPONENT_REF)
2943 canonicalize_component_ref (&TREE_OPERAND (*expr_p, 0));
2945 /* If a NOP conversion is changing a pointer to array of foo
2946 to a pointer to foo, embed that change in the ADDR_EXPR. */
2947 else if (TREE_CODE (sub) == ADDR_EXPR)
2948 canonicalize_addr_expr (expr_p);
2951 /* If we have a conversion to a non-register type force the
2952 use of a VIEW_CONVERT_EXPR instead. */
2953 if (CONVERT_EXPR_P (*expr_p) && !is_gimple_reg_type (TREE_TYPE (*expr_p)))
2954 *expr_p = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (*expr_p),
2955 TREE_OPERAND (*expr_p, 0));
2957 /* Canonicalize CONVERT_EXPR to NOP_EXPR. */
2958 if (TREE_CODE (*expr_p) == CONVERT_EXPR)
2959 TREE_SET_CODE (*expr_p, NOP_EXPR);
2961 return GS_OK;
2964 /* Gimplify a VAR_DECL or PARM_DECL. Return GS_OK if we expanded a
2965 DECL_VALUE_EXPR, and it's worth re-examining things. */
2967 static enum gimplify_status
2968 gimplify_var_or_parm_decl (tree *expr_p)
2970 tree decl = *expr_p;
2972 /* ??? If this is a local variable, and it has not been seen in any
2973 outer BIND_EXPR, then it's probably the result of a duplicate
2974 declaration, for which we've already issued an error. It would
2975 be really nice if the front end wouldn't leak these at all.
2976 Currently the only known culprit is C++ destructors, as seen
2977 in g++.old-deja/g++.jason/binding.C.
2978 Another possible culpit are size expressions for variably modified
2979 types which are lost in the FE or not gimplified correctly. */
2980 if (VAR_P (decl)
2981 && !DECL_SEEN_IN_BIND_EXPR_P (decl)
2982 && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl)
2983 && decl_function_context (decl) == current_function_decl)
2985 gcc_assert (seen_error ());
2986 return GS_ERROR;
2989 /* When within an OMP context, notice uses of variables. */
2990 if (gimplify_omp_ctxp && omp_notice_variable (gimplify_omp_ctxp, decl, true))
2991 return GS_ALL_DONE;
2993 /* If the decl is an alias for another expression, substitute it now. */
2994 if (DECL_HAS_VALUE_EXPR_P (decl))
2996 *expr_p = unshare_expr (DECL_VALUE_EXPR (decl));
2997 return GS_OK;
3000 return GS_ALL_DONE;
3003 /* Recalculate the value of the TREE_SIDE_EFFECTS flag for T. */
3005 static void
3006 recalculate_side_effects (tree t)
3008 enum tree_code code = TREE_CODE (t);
3009 int len = TREE_OPERAND_LENGTH (t);
3010 int i;
3012 switch (TREE_CODE_CLASS (code))
3014 case tcc_expression:
3015 switch (code)
3017 case INIT_EXPR:
3018 case MODIFY_EXPR:
3019 case VA_ARG_EXPR:
3020 case PREDECREMENT_EXPR:
3021 case PREINCREMENT_EXPR:
3022 case POSTDECREMENT_EXPR:
3023 case POSTINCREMENT_EXPR:
3024 /* All of these have side-effects, no matter what their
3025 operands are. */
3026 return;
3028 default:
3029 break;
3031 /* Fall through. */
3033 case tcc_comparison: /* a comparison expression */
3034 case tcc_unary: /* a unary arithmetic expression */
3035 case tcc_binary: /* a binary arithmetic expression */
3036 case tcc_reference: /* a reference */
3037 case tcc_vl_exp: /* a function call */
3038 TREE_SIDE_EFFECTS (t) = TREE_THIS_VOLATILE (t);
3039 for (i = 0; i < len; ++i)
3041 tree op = TREE_OPERAND (t, i);
3042 if (op && TREE_SIDE_EFFECTS (op))
3043 TREE_SIDE_EFFECTS (t) = 1;
3045 break;
3047 case tcc_constant:
3048 /* No side-effects. */
3049 return;
3051 default:
3052 gcc_unreachable ();
3056 /* Gimplify the COMPONENT_REF, ARRAY_REF, REALPART_EXPR or IMAGPART_EXPR
3057 node *EXPR_P.
3059 compound_lval
3060 : min_lval '[' val ']'
3061 | min_lval '.' ID
3062 | compound_lval '[' val ']'
3063 | compound_lval '.' ID
3065 This is not part of the original SIMPLE definition, which separates
3066 array and member references, but it seems reasonable to handle them
3067 together. Also, this way we don't run into problems with union
3068 aliasing; gcc requires that for accesses through a union to alias, the
3069 union reference must be explicit, which was not always the case when we
3070 were splitting up array and member refs.
3072 PRE_P points to the sequence where side effects that must happen before
3073 *EXPR_P should be stored.
3075 POST_P points to the sequence where side effects that must happen after
3076 *EXPR_P should be stored. */
3078 static enum gimplify_status
3079 gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
3080 fallback_t fallback)
3082 tree *p;
3083 enum gimplify_status ret = GS_ALL_DONE, tret;
3084 int i;
3085 location_t loc = EXPR_LOCATION (*expr_p);
3086 tree expr = *expr_p;
3088 /* Create a stack of the subexpressions so later we can walk them in
3089 order from inner to outer. */
3090 auto_vec<tree, 10> expr_stack;
3092 /* We can handle anything that get_inner_reference can deal with. */
3093 for (p = expr_p; ; p = &TREE_OPERAND (*p, 0))
3095 restart:
3096 /* Fold INDIRECT_REFs now to turn them into ARRAY_REFs. */
3097 if (TREE_CODE (*p) == INDIRECT_REF)
3098 *p = fold_indirect_ref_loc (loc, *p);
3100 if (handled_component_p (*p))
3102 /* Expand DECL_VALUE_EXPR now. In some cases that may expose
3103 additional COMPONENT_REFs. */
3104 else if ((VAR_P (*p) || TREE_CODE (*p) == PARM_DECL)
3105 && gimplify_var_or_parm_decl (p) == GS_OK)
3106 goto restart;
3107 else
3108 break;
3110 expr_stack.safe_push (*p);
3113 gcc_assert (expr_stack.length ());
3115 /* Now EXPR_STACK is a stack of pointers to all the refs we've
3116 walked through and P points to the innermost expression.
3118 Java requires that we elaborated nodes in source order. That
3119 means we must gimplify the inner expression followed by each of
3120 the indices, in order. But we can't gimplify the inner
3121 expression until we deal with any variable bounds, sizes, or
3122 positions in order to deal with PLACEHOLDER_EXPRs.
3124 The base expression may contain a statement expression that
3125 has declarations used in size expressions, so has to be
3126 gimplified before gimplifying the size expressions.
3128 So we do this in three steps. First we deal with variable
3129 bounds, sizes, and positions, then we gimplify the base,
3130 then we deal with the annotations for any variables in the
3131 components and any indices, from left to right. */
3133 for (i = expr_stack.length () - 1; i >= 0; i--)
3135 tree t = expr_stack[i];
3137 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
3139 /* Deal with the low bound and element type size and put them into
3140 the ARRAY_REF. If these values are set, they have already been
3141 gimplified. */
3142 if (TREE_OPERAND (t, 2) == NULL_TREE)
3144 tree low = unshare_expr (array_ref_low_bound (t));
3145 if (!is_gimple_min_invariant (low))
3147 TREE_OPERAND (t, 2) = low;
3151 if (TREE_OPERAND (t, 3) == NULL_TREE)
3153 tree elmt_size = array_ref_element_size (t);
3154 if (!is_gimple_min_invariant (elmt_size))
3156 elmt_size = unshare_expr (elmt_size);
3157 tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0)));
3158 tree factor = size_int (TYPE_ALIGN_UNIT (elmt_type));
3160 /* Divide the element size by the alignment of the element
3161 type (above). */
3162 elmt_size = size_binop_loc (loc, EXACT_DIV_EXPR,
3163 elmt_size, factor);
3165 TREE_OPERAND (t, 3) = elmt_size;
3169 else if (TREE_CODE (t) == COMPONENT_REF)
3171 /* Set the field offset into T and gimplify it. */
3172 if (TREE_OPERAND (t, 2) == NULL_TREE)
3174 tree offset = component_ref_field_offset (t);
3175 if (!is_gimple_min_invariant (offset))
3177 offset = unshare_expr (offset);
3178 tree field = TREE_OPERAND (t, 1);
3179 tree factor
3180 = size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT);
3182 /* Divide the offset by its alignment. */
3183 offset = size_binop_loc (loc, EXACT_DIV_EXPR,
3184 offset, factor);
3186 TREE_OPERAND (t, 2) = offset;
3192 /* Step 2 is to gimplify the base expression. Make sure lvalue is set
3193 so as to match the min_lval predicate. Failure to do so may result
3194 in the creation of large aggregate temporaries. */
3195 tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval,
3196 fallback | fb_lvalue);
3197 ret = MIN (ret, tret);
3199 /* Step 3: gimplify size expressions and the indices and operands of
3200 ARRAY_REF. During this loop we also remove any useless conversions. */
3202 for (; expr_stack.length () > 0; )
3204 tree t = expr_stack.pop ();
3206 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
3208 /* Gimplify the low bound and element type size. */
3209 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
3210 is_gimple_reg, fb_rvalue);
3211 ret = MIN (ret, tret);
3213 tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p, post_p,
3214 is_gimple_reg, fb_rvalue);
3215 ret = MIN (ret, tret);
3217 /* Gimplify the dimension. */
3218 tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
3219 is_gimple_val, fb_rvalue);
3220 ret = MIN (ret, tret);
3222 else if (TREE_CODE (t) == COMPONENT_REF)
3224 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
3225 is_gimple_reg, fb_rvalue);
3226 ret = MIN (ret, tret);
3229 STRIP_USELESS_TYPE_CONVERSION (TREE_OPERAND (t, 0));
3231 /* The innermost expression P may have originally had
3232 TREE_SIDE_EFFECTS set which would have caused all the outer
3233 expressions in *EXPR_P leading to P to also have had
3234 TREE_SIDE_EFFECTS set. */
3235 recalculate_side_effects (t);
3238 /* If the outermost expression is a COMPONENT_REF, canonicalize its type. */
3239 if ((fallback & fb_rvalue) && TREE_CODE (*expr_p) == COMPONENT_REF)
3241 canonicalize_component_ref (expr_p);
3244 expr_stack.release ();
3246 gcc_assert (*expr_p == expr || ret != GS_ALL_DONE);
3248 return ret;
3251 /* Gimplify the self modifying expression pointed to by EXPR_P
3252 (++, --, +=, -=).
3254 PRE_P points to the list where side effects that must happen before
3255 *EXPR_P should be stored.
3257 POST_P points to the list where side effects that must happen after
3258 *EXPR_P should be stored.
3260 WANT_VALUE is nonzero iff we want to use the value of this expression
3261 in another expression.
3263 ARITH_TYPE is the type the computation should be performed in. */
3265 enum gimplify_status
3266 gimplify_self_mod_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
3267 bool want_value, tree arith_type)
3269 enum tree_code code;
3270 tree lhs, lvalue, rhs, t1;
3271 gimple_seq post = NULL, *orig_post_p = post_p;
3272 bool postfix;
3273 enum tree_code arith_code;
3274 enum gimplify_status ret;
3275 location_t loc = EXPR_LOCATION (*expr_p);
3277 code = TREE_CODE (*expr_p);
3279 gcc_assert (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR
3280 || code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR);
3282 /* Prefix or postfix? */
3283 if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
3284 /* Faster to treat as prefix if result is not used. */
3285 postfix = want_value;
3286 else
3287 postfix = false;
3289 /* For postfix, make sure the inner expression's post side effects
3290 are executed after side effects from this expression. */
3291 if (postfix)
3292 post_p = &post;
3294 /* Add or subtract? */
3295 if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
3296 arith_code = PLUS_EXPR;
3297 else
3298 arith_code = MINUS_EXPR;
3300 /* Gimplify the LHS into a GIMPLE lvalue. */
3301 lvalue = TREE_OPERAND (*expr_p, 0);
3302 ret = gimplify_expr (&lvalue, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
3303 if (ret == GS_ERROR)
3304 return ret;
3306 /* Extract the operands to the arithmetic operation. */
3307 lhs = lvalue;
3308 rhs = TREE_OPERAND (*expr_p, 1);
3310 /* For postfix operator, we evaluate the LHS to an rvalue and then use
3311 that as the result value and in the postqueue operation. */
3312 if (postfix)
3314 ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue);
3315 if (ret == GS_ERROR)
3316 return ret;
3318 lhs = get_initialized_tmp_var (lhs, pre_p);
3321 /* For POINTERs increment, use POINTER_PLUS_EXPR. */
3322 if (POINTER_TYPE_P (TREE_TYPE (lhs)))
3324 rhs = convert_to_ptrofftype_loc (loc, rhs);
3325 if (arith_code == MINUS_EXPR)
3326 rhs = fold_build1_loc (loc, NEGATE_EXPR, TREE_TYPE (rhs), rhs);
3327 t1 = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (*expr_p), lhs, rhs);
3329 else
3330 t1 = fold_convert (TREE_TYPE (*expr_p),
3331 fold_build2 (arith_code, arith_type,
3332 fold_convert (arith_type, lhs),
3333 fold_convert (arith_type, rhs)));
3335 if (postfix)
3337 gimplify_assign (lvalue, t1, pre_p);
3338 gimplify_seq_add_seq (orig_post_p, post);
3339 *expr_p = lhs;
3340 return GS_ALL_DONE;
3342 else
3344 *expr_p = build2 (MODIFY_EXPR, TREE_TYPE (lvalue), lvalue, t1);
3345 return GS_OK;
3349 /* If *EXPR_P has a variable sized type, wrap it in a WITH_SIZE_EXPR. */
3351 static void
3352 maybe_with_size_expr (tree *expr_p)
3354 tree expr = *expr_p;
3355 tree type = TREE_TYPE (expr);
3356 tree size;
3358 /* If we've already wrapped this or the type is error_mark_node, we can't do
3359 anything. */
3360 if (TREE_CODE (expr) == WITH_SIZE_EXPR
3361 || type == error_mark_node)
3362 return;
3364 /* If the size isn't known or is a constant, we have nothing to do. */
3365 size = TYPE_SIZE_UNIT (type);
3366 if (!size || poly_int_tree_p (size))
3367 return;
3369 /* Otherwise, make a WITH_SIZE_EXPR. */
3370 size = unshare_expr (size);
3371 size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, expr);
3372 *expr_p = build2 (WITH_SIZE_EXPR, type, expr, size);
3375 /* Helper for gimplify_call_expr. Gimplify a single argument *ARG_P
3376 Store any side-effects in PRE_P. CALL_LOCATION is the location of
3377 the CALL_EXPR. If ALLOW_SSA is set the actual parameter may be
3378 gimplified to an SSA name. */
3380 enum gimplify_status
3381 gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location,
3382 bool allow_ssa)
3384 bool (*test) (tree);
3385 fallback_t fb;
3387 /* In general, we allow lvalues for function arguments to avoid
3388 extra overhead of copying large aggregates out of even larger
3389 aggregates into temporaries only to copy the temporaries to
3390 the argument list. Make optimizers happy by pulling out to
3391 temporaries those types that fit in registers. */
3392 if (is_gimple_reg_type (TREE_TYPE (*arg_p)))
3393 test = is_gimple_val, fb = fb_rvalue;
3394 else
3396 test = is_gimple_lvalue, fb = fb_either;
3397 /* Also strip a TARGET_EXPR that would force an extra copy. */
3398 if (TREE_CODE (*arg_p) == TARGET_EXPR)
3400 tree init = TARGET_EXPR_INITIAL (*arg_p);
3401 if (init
3402 && !VOID_TYPE_P (TREE_TYPE (init)))
3403 *arg_p = init;
3407 /* If this is a variable sized type, we must remember the size. */
3408 maybe_with_size_expr (arg_p);
3410 /* FIXME diagnostics: This will mess up gcc.dg/Warray-bounds.c. */
3411 /* Make sure arguments have the same location as the function call
3412 itself. */
3413 protected_set_expr_location (*arg_p, call_location);
3415 /* There is a sequence point before a function call. Side effects in
3416 the argument list must occur before the actual call. So, when
3417 gimplifying arguments, force gimplify_expr to use an internal
3418 post queue which is then appended to the end of PRE_P. */
3419 return gimplify_expr (arg_p, pre_p, NULL, test, fb, allow_ssa);
3422 /* Don't fold inside offloading or taskreg regions: it can break code by
3423 adding decl references that weren't in the source. We'll do it during
3424 omplower pass instead. */
3426 static bool
3427 maybe_fold_stmt (gimple_stmt_iterator *gsi)
3429 struct gimplify_omp_ctx *ctx;
3430 for (ctx = gimplify_omp_ctxp; ctx; ctx = ctx->outer_context)
3431 if ((ctx->region_type & (ORT_TARGET | ORT_PARALLEL | ORT_TASK)) != 0)
3432 return false;
3433 else if ((ctx->region_type & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
3434 return false;
3435 /* Delay folding of builtins until the IL is in consistent state
3436 so the diagnostic machinery can do a better job. */
3437 if (gimple_call_builtin_p (gsi_stmt (*gsi)))
3438 return false;
3439 return fold_stmt (gsi);
3442 /* Gimplify the CALL_EXPR node *EXPR_P into the GIMPLE sequence PRE_P.
3443 WANT_VALUE is true if the result of the call is desired. */
3445 static enum gimplify_status
3446 gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
3448 tree fndecl, parms, p, fnptrtype;
3449 enum gimplify_status ret;
3450 int i, nargs;
3451 gcall *call;
3452 bool builtin_va_start_p = false;
3453 location_t loc = EXPR_LOCATION (*expr_p);
3455 gcc_assert (TREE_CODE (*expr_p) == CALL_EXPR);
3457 /* For reliable diagnostics during inlining, it is necessary that
3458 every call_expr be annotated with file and line. */
3459 if (! EXPR_HAS_LOCATION (*expr_p))
3460 SET_EXPR_LOCATION (*expr_p, input_location);
3462 /* Gimplify internal functions created in the FEs. */
3463 if (CALL_EXPR_FN (*expr_p) == NULL_TREE)
3465 if (want_value)
3466 return GS_ALL_DONE;
3468 nargs = call_expr_nargs (*expr_p);
3469 enum internal_fn ifn = CALL_EXPR_IFN (*expr_p);
3470 auto_vec<tree> vargs (nargs);
3472 for (i = 0; i < nargs; i++)
3474 gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
3475 EXPR_LOCATION (*expr_p));
3476 vargs.quick_push (CALL_EXPR_ARG (*expr_p, i));
3479 gcall *call = gimple_build_call_internal_vec (ifn, vargs);
3480 gimple_call_set_nothrow (call, TREE_NOTHROW (*expr_p));
3481 gimplify_seq_add_stmt (pre_p, call);
3482 return GS_ALL_DONE;
3485 /* This may be a call to a builtin function.
3487 Builtin function calls may be transformed into different
3488 (and more efficient) builtin function calls under certain
3489 circumstances. Unfortunately, gimplification can muck things
3490 up enough that the builtin expanders are not aware that certain
3491 transformations are still valid.
3493 So we attempt transformation/gimplification of the call before
3494 we gimplify the CALL_EXPR. At this time we do not manage to
3495 transform all calls in the same manner as the expanders do, but
3496 we do transform most of them. */
3497 fndecl = get_callee_fndecl (*expr_p);
3498 if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
3499 switch (DECL_FUNCTION_CODE (fndecl))
3501 CASE_BUILT_IN_ALLOCA:
3502 /* If the call has been built for a variable-sized object, then we
3503 want to restore the stack level when the enclosing BIND_EXPR is
3504 exited to reclaim the allocated space; otherwise, we precisely
3505 need to do the opposite and preserve the latest stack level. */
3506 if (CALL_ALLOCA_FOR_VAR_P (*expr_p))
3507 gimplify_ctxp->save_stack = true;
3508 else
3509 gimplify_ctxp->keep_stack = true;
3510 break;
3512 case BUILT_IN_VA_START:
3514 builtin_va_start_p = TRUE;
3515 if (call_expr_nargs (*expr_p) < 2)
3517 error ("too few arguments to function %<va_start%>");
3518 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
3519 return GS_OK;
3522 if (fold_builtin_next_arg (*expr_p, true))
3524 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
3525 return GS_OK;
3527 break;
3530 case BUILT_IN_EH_RETURN:
3531 cfun->calls_eh_return = true;
3532 break;
3534 case BUILT_IN_CLEAR_PADDING:
3535 if (call_expr_nargs (*expr_p) == 1)
3537 /* Remember the original type of the argument in an internal
3538 dummy second argument, as in GIMPLE pointer conversions are
3539 useless. also mark this call as not for automatic initialization
3540 in the internal dummy third argument. */
3541 p = CALL_EXPR_ARG (*expr_p, 0);
3542 bool for_auto_init = false;
3543 *expr_p
3544 = build_call_expr_loc (EXPR_LOCATION (*expr_p), fndecl, 3, p,
3545 build_zero_cst (TREE_TYPE (p)),
3546 build_int_cst (integer_type_node,
3547 (int) for_auto_init));
3548 return GS_OK;
3550 break;
3552 default:
3555 if (fndecl && fndecl_built_in_p (fndecl))
3557 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
3558 if (new_tree && new_tree != *expr_p)
3560 /* There was a transformation of this call which computes the
3561 same value, but in a more efficient way. Return and try
3562 again. */
3563 *expr_p = new_tree;
3564 return GS_OK;
3568 /* Remember the original function pointer type. */
3569 fnptrtype = TREE_TYPE (CALL_EXPR_FN (*expr_p));
3571 if (flag_openmp
3572 && fndecl
3573 && cfun
3574 && (cfun->curr_properties & PROP_gimple_any) == 0)
3576 tree variant = omp_resolve_declare_variant (fndecl);
3577 if (variant != fndecl)
3578 CALL_EXPR_FN (*expr_p) = build1 (ADDR_EXPR, fnptrtype, variant);
3581 /* There is a sequence point before the call, so any side effects in
3582 the calling expression must occur before the actual call. Force
3583 gimplify_expr to use an internal post queue. */
3584 ret = gimplify_expr (&CALL_EXPR_FN (*expr_p), pre_p, NULL,
3585 is_gimple_call_addr, fb_rvalue);
3587 nargs = call_expr_nargs (*expr_p);
3589 /* Get argument types for verification. */
3590 fndecl = get_callee_fndecl (*expr_p);
3591 parms = NULL_TREE;
3592 if (fndecl)
3593 parms = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
3594 else
3595 parms = TYPE_ARG_TYPES (TREE_TYPE (fnptrtype));
3597 if (fndecl && DECL_ARGUMENTS (fndecl))
3598 p = DECL_ARGUMENTS (fndecl);
3599 else if (parms)
3600 p = parms;
3601 else
3602 p = NULL_TREE;
3603 for (i = 0; i < nargs && p; i++, p = TREE_CHAIN (p))
3606 /* If the last argument is __builtin_va_arg_pack () and it is not
3607 passed as a named argument, decrease the number of CALL_EXPR
3608 arguments and set instead the CALL_EXPR_VA_ARG_PACK flag. */
3609 if (!p
3610 && i < nargs
3611 && TREE_CODE (CALL_EXPR_ARG (*expr_p, nargs - 1)) == CALL_EXPR)
3613 tree last_arg = CALL_EXPR_ARG (*expr_p, nargs - 1);
3614 tree last_arg_fndecl = get_callee_fndecl (last_arg);
3616 if (last_arg_fndecl
3617 && fndecl_built_in_p (last_arg_fndecl, BUILT_IN_VA_ARG_PACK))
3619 tree call = *expr_p;
3621 --nargs;
3622 *expr_p = build_call_array_loc (loc, TREE_TYPE (call),
3623 CALL_EXPR_FN (call),
3624 nargs, CALL_EXPR_ARGP (call));
3626 /* Copy all CALL_EXPR flags, location and block, except
3627 CALL_EXPR_VA_ARG_PACK flag. */
3628 CALL_EXPR_STATIC_CHAIN (*expr_p) = CALL_EXPR_STATIC_CHAIN (call);
3629 CALL_EXPR_TAILCALL (*expr_p) = CALL_EXPR_TAILCALL (call);
3630 CALL_EXPR_RETURN_SLOT_OPT (*expr_p)
3631 = CALL_EXPR_RETURN_SLOT_OPT (call);
3632 CALL_FROM_THUNK_P (*expr_p) = CALL_FROM_THUNK_P (call);
3633 SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (call));
3635 /* Set CALL_EXPR_VA_ARG_PACK. */
3636 CALL_EXPR_VA_ARG_PACK (*expr_p) = 1;
3640 /* If the call returns twice then after building the CFG the call
3641 argument computations will no longer dominate the call because
3642 we add an abnormal incoming edge to the call. So do not use SSA
3643 vars there. */
3644 bool returns_twice = call_expr_flags (*expr_p) & ECF_RETURNS_TWICE;
3646 /* Gimplify the function arguments. */
3647 if (nargs > 0)
3649 for (i = (PUSH_ARGS_REVERSED ? nargs - 1 : 0);
3650 PUSH_ARGS_REVERSED ? i >= 0 : i < nargs;
3651 PUSH_ARGS_REVERSED ? i-- : i++)
3653 enum gimplify_status t;
3655 /* Avoid gimplifying the second argument to va_start, which needs to
3656 be the plain PARM_DECL. */
3657 if ((i != 1) || !builtin_va_start_p)
3659 t = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
3660 EXPR_LOCATION (*expr_p), ! returns_twice);
3662 if (t == GS_ERROR)
3663 ret = GS_ERROR;
3668 /* Gimplify the static chain. */
3669 if (CALL_EXPR_STATIC_CHAIN (*expr_p))
3671 if (fndecl && !DECL_STATIC_CHAIN (fndecl))
3672 CALL_EXPR_STATIC_CHAIN (*expr_p) = NULL;
3673 else
3675 enum gimplify_status t;
3676 t = gimplify_arg (&CALL_EXPR_STATIC_CHAIN (*expr_p), pre_p,
3677 EXPR_LOCATION (*expr_p), ! returns_twice);
3678 if (t == GS_ERROR)
3679 ret = GS_ERROR;
3683 /* Verify the function result. */
3684 if (want_value && fndecl
3685 && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fnptrtype))))
3687 error_at (loc, "using result of function returning %<void%>");
3688 ret = GS_ERROR;
3691 /* Try this again in case gimplification exposed something. */
3692 if (ret != GS_ERROR)
3694 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
3696 if (new_tree && new_tree != *expr_p)
3698 /* There was a transformation of this call which computes the
3699 same value, but in a more efficient way. Return and try
3700 again. */
3701 *expr_p = new_tree;
3702 return GS_OK;
3705 else
3707 *expr_p = error_mark_node;
3708 return GS_ERROR;
3711 /* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its
3712 decl. This allows us to eliminate redundant or useless
3713 calls to "const" functions. */
3714 if (TREE_CODE (*expr_p) == CALL_EXPR)
3716 int flags = call_expr_flags (*expr_p);
3717 if (flags & (ECF_CONST | ECF_PURE)
3718 /* An infinite loop is considered a side effect. */
3719 && !(flags & (ECF_LOOPING_CONST_OR_PURE)))
3720 TREE_SIDE_EFFECTS (*expr_p) = 0;
3723 /* If the value is not needed by the caller, emit a new GIMPLE_CALL
3724 and clear *EXPR_P. Otherwise, leave *EXPR_P in its gimplified
3725 form and delegate the creation of a GIMPLE_CALL to
3726 gimplify_modify_expr. This is always possible because when
3727 WANT_VALUE is true, the caller wants the result of this call into
3728 a temporary, which means that we will emit an INIT_EXPR in
3729 internal_get_tmp_var which will then be handled by
3730 gimplify_modify_expr. */
3731 if (!want_value)
3733 /* The CALL_EXPR in *EXPR_P is already in GIMPLE form, so all we
3734 have to do is replicate it as a GIMPLE_CALL tuple. */
3735 gimple_stmt_iterator gsi;
3736 call = gimple_build_call_from_tree (*expr_p, fnptrtype);
3737 notice_special_calls (call);
3738 gimplify_seq_add_stmt (pre_p, call);
3739 gsi = gsi_last (*pre_p);
3740 maybe_fold_stmt (&gsi);
3741 *expr_p = NULL_TREE;
3743 else
3744 /* Remember the original function type. */
3745 CALL_EXPR_FN (*expr_p) = build1 (NOP_EXPR, fnptrtype,
3746 CALL_EXPR_FN (*expr_p));
3748 return ret;
3751 /* Handle shortcut semantics in the predicate operand of a COND_EXPR by
3752 rewriting it into multiple COND_EXPRs, and possibly GOTO_EXPRs.
3754 TRUE_LABEL_P and FALSE_LABEL_P point to the labels to jump to if the
3755 condition is true or false, respectively. If null, we should generate
3756 our own to skip over the evaluation of this specific expression.
3758 LOCUS is the source location of the COND_EXPR.
3760 This function is the tree equivalent of do_jump.
3762 shortcut_cond_r should only be called by shortcut_cond_expr. */
3764 static tree
3765 shortcut_cond_r (tree pred, tree *true_label_p, tree *false_label_p,
3766 location_t locus)
3768 tree local_label = NULL_TREE;
3769 tree t, expr = NULL;
3771 /* OK, it's not a simple case; we need to pull apart the COND_EXPR to
3772 retain the shortcut semantics. Just insert the gotos here;
3773 shortcut_cond_expr will append the real blocks later. */
3774 if (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
3776 location_t new_locus;
3778 /* Turn if (a && b) into
3780 if (a); else goto no;
3781 if (b) goto yes; else goto no;
3782 (no:) */
3784 if (false_label_p == NULL)
3785 false_label_p = &local_label;
3787 /* Keep the original source location on the first 'if'. */
3788 t = shortcut_cond_r (TREE_OPERAND (pred, 0), NULL, false_label_p, locus);
3789 append_to_statement_list (t, &expr);
3791 /* Set the source location of the && on the second 'if'. */
3792 new_locus = rexpr_location (pred, locus);
3793 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
3794 new_locus);
3795 append_to_statement_list (t, &expr);
3797 else if (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
3799 location_t new_locus;
3801 /* Turn if (a || b) into
3803 if (a) goto yes;
3804 if (b) goto yes; else goto no;
3805 (yes:) */
3807 if (true_label_p == NULL)
3808 true_label_p = &local_label;
3810 /* Keep the original source location on the first 'if'. */
3811 t = shortcut_cond_r (TREE_OPERAND (pred, 0), true_label_p, NULL, locus);
3812 append_to_statement_list (t, &expr);
3814 /* Set the source location of the || on the second 'if'. */
3815 new_locus = rexpr_location (pred, locus);
3816 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
3817 new_locus);
3818 append_to_statement_list (t, &expr);
3820 else if (TREE_CODE (pred) == COND_EXPR
3821 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 1)))
3822 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 2))))
3824 location_t new_locus;
3826 /* As long as we're messing with gotos, turn if (a ? b : c) into
3827 if (a)
3828 if (b) goto yes; else goto no;
3829 else
3830 if (c) goto yes; else goto no;
3832 Don't do this if one of the arms has void type, which can happen
3833 in C++ when the arm is throw. */
3835 /* Keep the original source location on the first 'if'. Set the source
3836 location of the ? on the second 'if'. */
3837 new_locus = rexpr_location (pred, locus);
3838 expr = build3 (COND_EXPR, void_type_node, TREE_OPERAND (pred, 0),
3839 shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p,
3840 false_label_p, locus),
3841 shortcut_cond_r (TREE_OPERAND (pred, 2), true_label_p,
3842 false_label_p, new_locus));
3844 else
3846 expr = build3 (COND_EXPR, void_type_node, pred,
3847 build_and_jump (true_label_p),
3848 build_and_jump (false_label_p));
3849 SET_EXPR_LOCATION (expr, locus);
3852 if (local_label)
3854 t = build1 (LABEL_EXPR, void_type_node, local_label);
3855 append_to_statement_list (t, &expr);
3858 return expr;
3861 /* If EXPR is a GOTO_EXPR, return it. If it is a STATEMENT_LIST, skip
3862 any of its leading DEBUG_BEGIN_STMTS and recurse on the subsequent
3863 statement, if it is the last one. Otherwise, return NULL. */
3865 static tree
3866 find_goto (tree expr)
3868 if (!expr)
3869 return NULL_TREE;
3871 if (TREE_CODE (expr) == GOTO_EXPR)
3872 return expr;
3874 if (TREE_CODE (expr) != STATEMENT_LIST)
3875 return NULL_TREE;
3877 tree_stmt_iterator i = tsi_start (expr);
3879 while (!tsi_end_p (i) && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT)
3880 tsi_next (&i);
3882 if (!tsi_one_before_end_p (i))
3883 return NULL_TREE;
3885 return find_goto (tsi_stmt (i));
3888 /* Same as find_goto, except that it returns NULL if the destination
3889 is not a LABEL_DECL. */
3891 static inline tree
3892 find_goto_label (tree expr)
3894 tree dest = find_goto (expr);
3895 if (dest && TREE_CODE (GOTO_DESTINATION (dest)) == LABEL_DECL)
3896 return dest;
3897 return NULL_TREE;
3900 /* Given a conditional expression EXPR with short-circuit boolean
3901 predicates using TRUTH_ANDIF_EXPR or TRUTH_ORIF_EXPR, break the
3902 predicate apart into the equivalent sequence of conditionals. */
3904 static tree
3905 shortcut_cond_expr (tree expr)
3907 tree pred = TREE_OPERAND (expr, 0);
3908 tree then_ = TREE_OPERAND (expr, 1);
3909 tree else_ = TREE_OPERAND (expr, 2);
3910 tree true_label, false_label, end_label, t;
3911 tree *true_label_p;
3912 tree *false_label_p;
3913 bool emit_end, emit_false, jump_over_else;
3914 bool then_se = then_ && TREE_SIDE_EFFECTS (then_);
3915 bool else_se = else_ && TREE_SIDE_EFFECTS (else_);
3917 /* First do simple transformations. */
3918 if (!else_se)
3920 /* If there is no 'else', turn
3921 if (a && b) then c
3922 into
3923 if (a) if (b) then c. */
3924 while (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
3926 /* Keep the original source location on the first 'if'. */
3927 location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
3928 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
3929 /* Set the source location of the && on the second 'if'. */
3930 if (rexpr_has_location (pred))
3931 SET_EXPR_LOCATION (expr, rexpr_location (pred));
3932 then_ = shortcut_cond_expr (expr);
3933 then_se = then_ && TREE_SIDE_EFFECTS (then_);
3934 pred = TREE_OPERAND (pred, 0);
3935 expr = build3 (COND_EXPR, void_type_node, pred, then_, NULL_TREE);
3936 SET_EXPR_LOCATION (expr, locus);
3940 if (!then_se)
3942 /* If there is no 'then', turn
3943 if (a || b); else d
3944 into
3945 if (a); else if (b); else d. */
3946 while (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
3948 /* Keep the original source location on the first 'if'. */
3949 location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
3950 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
3951 /* Set the source location of the || on the second 'if'. */
3952 if (rexpr_has_location (pred))
3953 SET_EXPR_LOCATION (expr, rexpr_location (pred));
3954 else_ = shortcut_cond_expr (expr);
3955 else_se = else_ && TREE_SIDE_EFFECTS (else_);
3956 pred = TREE_OPERAND (pred, 0);
3957 expr = build3 (COND_EXPR, void_type_node, pred, NULL_TREE, else_);
3958 SET_EXPR_LOCATION (expr, locus);
3962 /* If we're done, great. */
3963 if (TREE_CODE (pred) != TRUTH_ANDIF_EXPR
3964 && TREE_CODE (pred) != TRUTH_ORIF_EXPR)
3965 return expr;
3967 /* Otherwise we need to mess with gotos. Change
3968 if (a) c; else d;
3970 if (a); else goto no;
3971 c; goto end;
3972 no: d; end:
3973 and recursively gimplify the condition. */
3975 true_label = false_label = end_label = NULL_TREE;
3977 /* If our arms just jump somewhere, hijack those labels so we don't
3978 generate jumps to jumps. */
3980 if (tree then_goto = find_goto_label (then_))
3982 true_label = GOTO_DESTINATION (then_goto);
3983 then_ = NULL;
3984 then_se = false;
3987 if (tree else_goto = find_goto_label (else_))
3989 false_label = GOTO_DESTINATION (else_goto);
3990 else_ = NULL;
3991 else_se = false;
3994 /* If we aren't hijacking a label for the 'then' branch, it falls through. */
3995 if (true_label)
3996 true_label_p = &true_label;
3997 else
3998 true_label_p = NULL;
4000 /* The 'else' branch also needs a label if it contains interesting code. */
4001 if (false_label || else_se)
4002 false_label_p = &false_label;
4003 else
4004 false_label_p = NULL;
4006 /* If there was nothing else in our arms, just forward the label(s). */
4007 if (!then_se && !else_se)
4008 return shortcut_cond_r (pred, true_label_p, false_label_p,
4009 EXPR_LOC_OR_LOC (expr, input_location));
4011 /* If our last subexpression already has a terminal label, reuse it. */
4012 if (else_se)
4013 t = expr_last (else_);
4014 else if (then_se)
4015 t = expr_last (then_);
4016 else
4017 t = NULL;
4018 if (t && TREE_CODE (t) == LABEL_EXPR)
4019 end_label = LABEL_EXPR_LABEL (t);
4021 /* If we don't care about jumping to the 'else' branch, jump to the end
4022 if the condition is false. */
4023 if (!false_label_p)
4024 false_label_p = &end_label;
4026 /* We only want to emit these labels if we aren't hijacking them. */
4027 emit_end = (end_label == NULL_TREE);
4028 emit_false = (false_label == NULL_TREE);
4030 /* We only emit the jump over the else clause if we have to--if the
4031 then clause may fall through. Otherwise we can wind up with a
4032 useless jump and a useless label at the end of gimplified code,
4033 which will cause us to think that this conditional as a whole
4034 falls through even if it doesn't. If we then inline a function
4035 which ends with such a condition, that can cause us to issue an
4036 inappropriate warning about control reaching the end of a
4037 non-void function. */
4038 jump_over_else = block_may_fallthru (then_);
4040 pred = shortcut_cond_r (pred, true_label_p, false_label_p,
4041 EXPR_LOC_OR_LOC (expr, input_location));
4043 expr = NULL;
4044 append_to_statement_list (pred, &expr);
4046 append_to_statement_list (then_, &expr);
4047 if (else_se)
4049 if (jump_over_else)
4051 tree last = expr_last (expr);
4052 t = build_and_jump (&end_label);
4053 if (rexpr_has_location (last))
4054 SET_EXPR_LOCATION (t, rexpr_location (last));
4055 append_to_statement_list (t, &expr);
4057 if (emit_false)
4059 t = build1 (LABEL_EXPR, void_type_node, false_label);
4060 append_to_statement_list (t, &expr);
4062 append_to_statement_list (else_, &expr);
4064 if (emit_end && end_label)
4066 t = build1 (LABEL_EXPR, void_type_node, end_label);
4067 append_to_statement_list (t, &expr);
4070 return expr;
4073 /* EXPR is used in a boolean context; make sure it has BOOLEAN_TYPE. */
4075 tree
4076 gimple_boolify (tree expr)
4078 tree type = TREE_TYPE (expr);
4079 location_t loc = EXPR_LOCATION (expr);
4081 if (TREE_CODE (expr) == NE_EXPR
4082 && TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR
4083 && integer_zerop (TREE_OPERAND (expr, 1)))
4085 tree call = TREE_OPERAND (expr, 0);
4086 tree fn = get_callee_fndecl (call);
4088 /* For __builtin_expect ((long) (x), y) recurse into x as well
4089 if x is truth_value_p. */
4090 if (fn
4091 && fndecl_built_in_p (fn, BUILT_IN_EXPECT)
4092 && call_expr_nargs (call) == 2)
4094 tree arg = CALL_EXPR_ARG (call, 0);
4095 if (arg)
4097 if (TREE_CODE (arg) == NOP_EXPR
4098 && TREE_TYPE (arg) == TREE_TYPE (call))
4099 arg = TREE_OPERAND (arg, 0);
4100 if (truth_value_p (TREE_CODE (arg)))
4102 arg = gimple_boolify (arg);
4103 CALL_EXPR_ARG (call, 0)
4104 = fold_convert_loc (loc, TREE_TYPE (call), arg);
4110 switch (TREE_CODE (expr))
4112 case TRUTH_AND_EXPR:
4113 case TRUTH_OR_EXPR:
4114 case TRUTH_XOR_EXPR:
4115 case TRUTH_ANDIF_EXPR:
4116 case TRUTH_ORIF_EXPR:
4117 /* Also boolify the arguments of truth exprs. */
4118 TREE_OPERAND (expr, 1) = gimple_boolify (TREE_OPERAND (expr, 1));
4119 /* FALLTHRU */
4121 case TRUTH_NOT_EXPR:
4122 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
4124 /* These expressions always produce boolean results. */
4125 if (TREE_CODE (type) != BOOLEAN_TYPE)
4126 TREE_TYPE (expr) = boolean_type_node;
4127 return expr;
4129 case ANNOTATE_EXPR:
4130 switch ((enum annot_expr_kind) TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)))
4132 case annot_expr_ivdep_kind:
4133 case annot_expr_unroll_kind:
4134 case annot_expr_no_vector_kind:
4135 case annot_expr_vector_kind:
4136 case annot_expr_parallel_kind:
4137 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
4138 if (TREE_CODE (type) != BOOLEAN_TYPE)
4139 TREE_TYPE (expr) = boolean_type_node;
4140 return expr;
4141 default:
4142 gcc_unreachable ();
4145 default:
4146 if (COMPARISON_CLASS_P (expr))
4148 /* There expressions always prduce boolean results. */
4149 if (TREE_CODE (type) != BOOLEAN_TYPE)
4150 TREE_TYPE (expr) = boolean_type_node;
4151 return expr;
4153 /* Other expressions that get here must have boolean values, but
4154 might need to be converted to the appropriate mode. */
4155 if (TREE_CODE (type) == BOOLEAN_TYPE)
4156 return expr;
4157 return fold_convert_loc (loc, boolean_type_node, expr);
4161 /* Given a conditional expression *EXPR_P without side effects, gimplify
4162 its operands. New statements are inserted to PRE_P. */
4164 static enum gimplify_status
4165 gimplify_pure_cond_expr (tree *expr_p, gimple_seq *pre_p)
4167 tree expr = *expr_p, cond;
4168 enum gimplify_status ret, tret;
4169 enum tree_code code;
4171 cond = gimple_boolify (COND_EXPR_COND (expr));
4173 /* We need to handle && and || specially, as their gimplification
4174 creates pure cond_expr, thus leading to an infinite cycle otherwise. */
4175 code = TREE_CODE (cond);
4176 if (code == TRUTH_ANDIF_EXPR)
4177 TREE_SET_CODE (cond, TRUTH_AND_EXPR);
4178 else if (code == TRUTH_ORIF_EXPR)
4179 TREE_SET_CODE (cond, TRUTH_OR_EXPR);
4180 ret = gimplify_expr (&cond, pre_p, NULL, is_gimple_condexpr, fb_rvalue);
4181 COND_EXPR_COND (*expr_p) = cond;
4183 tret = gimplify_expr (&COND_EXPR_THEN (expr), pre_p, NULL,
4184 is_gimple_val, fb_rvalue);
4185 ret = MIN (ret, tret);
4186 tret = gimplify_expr (&COND_EXPR_ELSE (expr), pre_p, NULL,
4187 is_gimple_val, fb_rvalue);
4189 return MIN (ret, tret);
4192 /* Return true if evaluating EXPR could trap.
4193 EXPR is GENERIC, while tree_could_trap_p can be called
4194 only on GIMPLE. */
4196 bool
4197 generic_expr_could_trap_p (tree expr)
4199 unsigned i, n;
4201 if (!expr || is_gimple_val (expr))
4202 return false;
4204 if (!EXPR_P (expr) || tree_could_trap_p (expr))
4205 return true;
4207 n = TREE_OPERAND_LENGTH (expr);
4208 for (i = 0; i < n; i++)
4209 if (generic_expr_could_trap_p (TREE_OPERAND (expr, i)))
4210 return true;
4212 return false;
4215 /* Convert the conditional expression pointed to by EXPR_P '(p) ? a : b;'
4216 into
4218 if (p) if (p)
4219 t1 = a; a;
4220 else or else
4221 t1 = b; b;
4224 The second form is used when *EXPR_P is of type void.
4226 PRE_P points to the list where side effects that must happen before
4227 *EXPR_P should be stored. */
4229 static enum gimplify_status
4230 gimplify_cond_expr (tree *expr_p, gimple_seq *pre_p, fallback_t fallback)
4232 tree expr = *expr_p;
4233 tree type = TREE_TYPE (expr);
4234 location_t loc = EXPR_LOCATION (expr);
4235 tree tmp, arm1, arm2;
4236 enum gimplify_status ret;
4237 tree label_true, label_false, label_cont;
4238 bool have_then_clause_p, have_else_clause_p;
4239 gcond *cond_stmt;
4240 enum tree_code pred_code;
4241 gimple_seq seq = NULL;
4243 /* If this COND_EXPR has a value, copy the values into a temporary within
4244 the arms. */
4245 if (!VOID_TYPE_P (type))
4247 tree then_ = TREE_OPERAND (expr, 1), else_ = TREE_OPERAND (expr, 2);
4248 tree result;
4250 /* If either an rvalue is ok or we do not require an lvalue, create the
4251 temporary. But we cannot do that if the type is addressable. */
4252 if (((fallback & fb_rvalue) || !(fallback & fb_lvalue))
4253 && !TREE_ADDRESSABLE (type))
4255 if (gimplify_ctxp->allow_rhs_cond_expr
4256 /* If either branch has side effects or could trap, it can't be
4257 evaluated unconditionally. */
4258 && !TREE_SIDE_EFFECTS (then_)
4259 && !generic_expr_could_trap_p (then_)
4260 && !TREE_SIDE_EFFECTS (else_)
4261 && !generic_expr_could_trap_p (else_))
4262 return gimplify_pure_cond_expr (expr_p, pre_p);
4264 tmp = create_tmp_var (type, "iftmp");
4265 result = tmp;
4268 /* Otherwise, only create and copy references to the values. */
4269 else
4271 type = build_pointer_type (type);
4273 if (!VOID_TYPE_P (TREE_TYPE (then_)))
4274 then_ = build_fold_addr_expr_loc (loc, then_);
4276 if (!VOID_TYPE_P (TREE_TYPE (else_)))
4277 else_ = build_fold_addr_expr_loc (loc, else_);
4279 expr
4280 = build3 (COND_EXPR, type, TREE_OPERAND (expr, 0), then_, else_);
4282 tmp = create_tmp_var (type, "iftmp");
4283 result = build_simple_mem_ref_loc (loc, tmp);
4286 /* Build the new then clause, `tmp = then_;'. But don't build the
4287 assignment if the value is void; in C++ it can be if it's a throw. */
4288 if (!VOID_TYPE_P (TREE_TYPE (then_)))
4289 TREE_OPERAND (expr, 1) = build2 (INIT_EXPR, type, tmp, then_);
4291 /* Similarly, build the new else clause, `tmp = else_;'. */
4292 if (!VOID_TYPE_P (TREE_TYPE (else_)))
4293 TREE_OPERAND (expr, 2) = build2 (INIT_EXPR, type, tmp, else_);
4295 TREE_TYPE (expr) = void_type_node;
4296 recalculate_side_effects (expr);
4298 /* Move the COND_EXPR to the prequeue. */
4299 gimplify_stmt (&expr, pre_p);
4301 *expr_p = result;
4302 return GS_ALL_DONE;
4305 /* Remove any COMPOUND_EXPR so the following cases will be caught. */
4306 STRIP_TYPE_NOPS (TREE_OPERAND (expr, 0));
4307 if (TREE_CODE (TREE_OPERAND (expr, 0)) == COMPOUND_EXPR)
4308 gimplify_compound_expr (&TREE_OPERAND (expr, 0), pre_p, true);
4310 /* Make sure the condition has BOOLEAN_TYPE. */
4311 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
4313 /* Break apart && and || conditions. */
4314 if (TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ANDIF_EXPR
4315 || TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ORIF_EXPR)
4317 expr = shortcut_cond_expr (expr);
4319 if (expr != *expr_p)
4321 *expr_p = expr;
4323 /* We can't rely on gimplify_expr to re-gimplify the expanded
4324 form properly, as cleanups might cause the target labels to be
4325 wrapped in a TRY_FINALLY_EXPR. To prevent that, we need to
4326 set up a conditional context. */
4327 gimple_push_condition ();
4328 gimplify_stmt (expr_p, &seq);
4329 gimple_pop_condition (pre_p);
4330 gimple_seq_add_seq (pre_p, seq);
4332 return GS_ALL_DONE;
4336 /* Now do the normal gimplification. */
4338 /* Gimplify condition. */
4339 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL,
4340 is_gimple_condexpr_for_cond, fb_rvalue);
4341 if (ret == GS_ERROR)
4342 return GS_ERROR;
4343 gcc_assert (TREE_OPERAND (expr, 0) != NULL_TREE);
4345 gimple_push_condition ();
4347 have_then_clause_p = have_else_clause_p = false;
4348 label_true = find_goto_label (TREE_OPERAND (expr, 1));
4349 if (label_true
4350 && DECL_CONTEXT (GOTO_DESTINATION (label_true)) == current_function_decl
4351 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4352 have different locations, otherwise we end up with incorrect
4353 location information on the branches. */
4354 && (optimize
4355 || !EXPR_HAS_LOCATION (expr)
4356 || !rexpr_has_location (label_true)
4357 || EXPR_LOCATION (expr) == rexpr_location (label_true)))
4359 have_then_clause_p = true;
4360 label_true = GOTO_DESTINATION (label_true);
4362 else
4363 label_true = create_artificial_label (UNKNOWN_LOCATION);
4364 label_false = find_goto_label (TREE_OPERAND (expr, 2));
4365 if (label_false
4366 && DECL_CONTEXT (GOTO_DESTINATION (label_false)) == current_function_decl
4367 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4368 have different locations, otherwise we end up with incorrect
4369 location information on the branches. */
4370 && (optimize
4371 || !EXPR_HAS_LOCATION (expr)
4372 || !rexpr_has_location (label_false)
4373 || EXPR_LOCATION (expr) == rexpr_location (label_false)))
4375 have_else_clause_p = true;
4376 label_false = GOTO_DESTINATION (label_false);
4378 else
4379 label_false = create_artificial_label (UNKNOWN_LOCATION);
4381 gimple_cond_get_ops_from_tree (COND_EXPR_COND (expr), &pred_code, &arm1,
4382 &arm2);
4383 cond_stmt = gimple_build_cond (pred_code, arm1, arm2, label_true,
4384 label_false);
4385 gimple_set_location (cond_stmt, EXPR_LOCATION (expr));
4386 copy_warning (cond_stmt, COND_EXPR_COND (expr));
4387 gimplify_seq_add_stmt (&seq, cond_stmt);
4388 gimple_stmt_iterator gsi = gsi_last (seq);
4389 maybe_fold_stmt (&gsi);
4391 label_cont = NULL_TREE;
4392 if (!have_then_clause_p)
4394 /* For if (...) {} else { code; } put label_true after
4395 the else block. */
4396 if (TREE_OPERAND (expr, 1) == NULL_TREE
4397 && !have_else_clause_p
4398 && TREE_OPERAND (expr, 2) != NULL_TREE)
4399 label_cont = label_true;
4400 else
4402 gimplify_seq_add_stmt (&seq, gimple_build_label (label_true));
4403 have_then_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 1), &seq);
4404 /* For if (...) { code; } else {} or
4405 if (...) { code; } else goto label; or
4406 if (...) { code; return; } else { ... }
4407 label_cont isn't needed. */
4408 if (!have_else_clause_p
4409 && TREE_OPERAND (expr, 2) != NULL_TREE
4410 && gimple_seq_may_fallthru (seq))
4412 gimple *g;
4413 label_cont = create_artificial_label (UNKNOWN_LOCATION);
4415 g = gimple_build_goto (label_cont);
4417 /* GIMPLE_COND's are very low level; they have embedded
4418 gotos. This particular embedded goto should not be marked
4419 with the location of the original COND_EXPR, as it would
4420 correspond to the COND_EXPR's condition, not the ELSE or the
4421 THEN arms. To avoid marking it with the wrong location, flag
4422 it as "no location". */
4423 gimple_set_do_not_emit_location (g);
4425 gimplify_seq_add_stmt (&seq, g);
4429 if (!have_else_clause_p)
4431 gimplify_seq_add_stmt (&seq, gimple_build_label (label_false));
4432 have_else_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 2), &seq);
4434 if (label_cont)
4435 gimplify_seq_add_stmt (&seq, gimple_build_label (label_cont));
4437 gimple_pop_condition (pre_p);
4438 gimple_seq_add_seq (pre_p, seq);
4440 if (ret == GS_ERROR)
4441 ; /* Do nothing. */
4442 else if (have_then_clause_p || have_else_clause_p)
4443 ret = GS_ALL_DONE;
4444 else
4446 /* Both arms are empty; replace the COND_EXPR with its predicate. */
4447 expr = TREE_OPERAND (expr, 0);
4448 gimplify_stmt (&expr, pre_p);
4451 *expr_p = NULL;
4452 return ret;
4455 /* Prepare the node pointed to by EXPR_P, an is_gimple_addressable expression,
4456 to be marked addressable.
4458 We cannot rely on such an expression being directly markable if a temporary
4459 has been created by the gimplification. In this case, we create another
4460 temporary and initialize it with a copy, which will become a store after we
4461 mark it addressable. This can happen if the front-end passed us something
4462 that it could not mark addressable yet, like a Fortran pass-by-reference
4463 parameter (int) floatvar. */
4465 static void
4466 prepare_gimple_addressable (tree *expr_p, gimple_seq *seq_p)
4468 while (handled_component_p (*expr_p))
4469 expr_p = &TREE_OPERAND (*expr_p, 0);
4470 if (is_gimple_reg (*expr_p))
4472 /* Do not allow an SSA name as the temporary. */
4473 tree var = get_initialized_tmp_var (*expr_p, seq_p, NULL, false);
4474 DECL_NOT_GIMPLE_REG_P (var) = 1;
4475 *expr_p = var;
4479 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4480 a call to __builtin_memcpy. */
4482 static enum gimplify_status
4483 gimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value,
4484 gimple_seq *seq_p)
4486 tree t, to, to_ptr, from, from_ptr;
4487 gcall *gs;
4488 location_t loc = EXPR_LOCATION (*expr_p);
4490 to = TREE_OPERAND (*expr_p, 0);
4491 from = TREE_OPERAND (*expr_p, 1);
4493 /* Mark the RHS addressable. Beware that it may not be possible to do so
4494 directly if a temporary has been created by the gimplification. */
4495 prepare_gimple_addressable (&from, seq_p);
4497 mark_addressable (from);
4498 from_ptr = build_fold_addr_expr_loc (loc, from);
4499 gimplify_arg (&from_ptr, seq_p, loc);
4501 mark_addressable (to);
4502 to_ptr = build_fold_addr_expr_loc (loc, to);
4503 gimplify_arg (&to_ptr, seq_p, loc);
4505 t = builtin_decl_implicit (BUILT_IN_MEMCPY);
4507 gs = gimple_build_call (t, 3, to_ptr, from_ptr, size);
4508 gimple_call_set_alloca_for_var (gs, true);
4510 if (want_value)
4512 /* tmp = memcpy() */
4513 t = create_tmp_var (TREE_TYPE (to_ptr));
4514 gimple_call_set_lhs (gs, t);
4515 gimplify_seq_add_stmt (seq_p, gs);
4517 *expr_p = build_simple_mem_ref (t);
4518 return GS_ALL_DONE;
4521 gimplify_seq_add_stmt (seq_p, gs);
4522 *expr_p = NULL;
4523 return GS_ALL_DONE;
4526 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4527 a call to __builtin_memset. In this case we know that the RHS is
4528 a CONSTRUCTOR with an empty element list. */
4530 static enum gimplify_status
4531 gimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value,
4532 gimple_seq *seq_p)
4534 tree t, from, to, to_ptr;
4535 gcall *gs;
4536 location_t loc = EXPR_LOCATION (*expr_p);
4538 /* Assert our assumptions, to abort instead of producing wrong code
4539 silently if they are not met. Beware that the RHS CONSTRUCTOR might
4540 not be immediately exposed. */
4541 from = TREE_OPERAND (*expr_p, 1);
4542 if (TREE_CODE (from) == WITH_SIZE_EXPR)
4543 from = TREE_OPERAND (from, 0);
4545 gcc_assert (TREE_CODE (from) == CONSTRUCTOR
4546 && vec_safe_is_empty (CONSTRUCTOR_ELTS (from)));
4548 /* Now proceed. */
4549 to = TREE_OPERAND (*expr_p, 0);
4551 to_ptr = build_fold_addr_expr_loc (loc, to);
4552 gimplify_arg (&to_ptr, seq_p, loc);
4553 t = builtin_decl_implicit (BUILT_IN_MEMSET);
4555 gs = gimple_build_call (t, 3, to_ptr, integer_zero_node, size);
4557 if (want_value)
4559 /* tmp = memset() */
4560 t = create_tmp_var (TREE_TYPE (to_ptr));
4561 gimple_call_set_lhs (gs, t);
4562 gimplify_seq_add_stmt (seq_p, gs);
4564 *expr_p = build1 (INDIRECT_REF, TREE_TYPE (to), t);
4565 return GS_ALL_DONE;
4568 gimplify_seq_add_stmt (seq_p, gs);
4569 *expr_p = NULL;
4570 return GS_ALL_DONE;
4573 /* A subroutine of gimplify_init_ctor_preeval. Called via walk_tree,
4574 determine, cautiously, if a CONSTRUCTOR overlaps the lhs of an
4575 assignment. Return non-null if we detect a potential overlap. */
4577 struct gimplify_init_ctor_preeval_data
4579 /* The base decl of the lhs object. May be NULL, in which case we
4580 have to assume the lhs is indirect. */
4581 tree lhs_base_decl;
4583 /* The alias set of the lhs object. */
4584 alias_set_type lhs_alias_set;
4587 static tree
4588 gimplify_init_ctor_preeval_1 (tree *tp, int *walk_subtrees, void *xdata)
4590 struct gimplify_init_ctor_preeval_data *data
4591 = (struct gimplify_init_ctor_preeval_data *) xdata;
4592 tree t = *tp;
4594 /* If we find the base object, obviously we have overlap. */
4595 if (data->lhs_base_decl == t)
4596 return t;
4598 /* If the constructor component is indirect, determine if we have a
4599 potential overlap with the lhs. The only bits of information we
4600 have to go on at this point are addressability and alias sets. */
4601 if ((INDIRECT_REF_P (t)
4602 || TREE_CODE (t) == MEM_REF)
4603 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
4604 && alias_sets_conflict_p (data->lhs_alias_set, get_alias_set (t)))
4605 return t;
4607 /* If the constructor component is a call, determine if it can hide a
4608 potential overlap with the lhs through an INDIRECT_REF like above.
4609 ??? Ugh - this is completely broken. In fact this whole analysis
4610 doesn't look conservative. */
4611 if (TREE_CODE (t) == CALL_EXPR)
4613 tree type, fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (t)));
4615 for (type = TYPE_ARG_TYPES (fntype); type; type = TREE_CHAIN (type))
4616 if (POINTER_TYPE_P (TREE_VALUE (type))
4617 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
4618 && alias_sets_conflict_p (data->lhs_alias_set,
4619 get_alias_set
4620 (TREE_TYPE (TREE_VALUE (type)))))
4621 return t;
4624 if (IS_TYPE_OR_DECL_P (t))
4625 *walk_subtrees = 0;
4626 return NULL;
4629 /* A subroutine of gimplify_init_constructor. Pre-evaluate EXPR,
4630 force values that overlap with the lhs (as described by *DATA)
4631 into temporaries. */
4633 static void
4634 gimplify_init_ctor_preeval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
4635 struct gimplify_init_ctor_preeval_data *data)
4637 enum gimplify_status one;
4639 /* If the value is constant, then there's nothing to pre-evaluate. */
4640 if (TREE_CONSTANT (*expr_p))
4642 /* Ensure it does not have side effects, it might contain a reference to
4643 the object we're initializing. */
4644 gcc_assert (!TREE_SIDE_EFFECTS (*expr_p));
4645 return;
4648 /* If the type has non-trivial constructors, we can't pre-evaluate. */
4649 if (TREE_ADDRESSABLE (TREE_TYPE (*expr_p)))
4650 return;
4652 /* Recurse for nested constructors. */
4653 if (TREE_CODE (*expr_p) == CONSTRUCTOR)
4655 unsigned HOST_WIDE_INT ix;
4656 constructor_elt *ce;
4657 vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (*expr_p);
4659 FOR_EACH_VEC_SAFE_ELT (v, ix, ce)
4660 gimplify_init_ctor_preeval (&ce->value, pre_p, post_p, data);
4662 return;
4665 /* If this is a variable sized type, we must remember the size. */
4666 maybe_with_size_expr (expr_p);
4668 /* Gimplify the constructor element to something appropriate for the rhs
4669 of a MODIFY_EXPR. Given that we know the LHS is an aggregate, we know
4670 the gimplifier will consider this a store to memory. Doing this
4671 gimplification now means that we won't have to deal with complicated
4672 language-specific trees, nor trees like SAVE_EXPR that can induce
4673 exponential search behavior. */
4674 one = gimplify_expr (expr_p, pre_p, post_p, is_gimple_mem_rhs, fb_rvalue);
4675 if (one == GS_ERROR)
4677 *expr_p = NULL;
4678 return;
4681 /* If we gimplified to a bare decl, we can be sure that it doesn't overlap
4682 with the lhs, since "a = { .x=a }" doesn't make sense. This will
4683 always be true for all scalars, since is_gimple_mem_rhs insists on a
4684 temporary variable for them. */
4685 if (DECL_P (*expr_p))
4686 return;
4688 /* If this is of variable size, we have no choice but to assume it doesn't
4689 overlap since we can't make a temporary for it. */
4690 if (TREE_CODE (TYPE_SIZE (TREE_TYPE (*expr_p))) != INTEGER_CST)
4691 return;
4693 /* Otherwise, we must search for overlap ... */
4694 if (!walk_tree (expr_p, gimplify_init_ctor_preeval_1, data, NULL))
4695 return;
4697 /* ... and if found, force the value into a temporary. */
4698 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
4701 /* A subroutine of gimplify_init_ctor_eval. Create a loop for
4702 a RANGE_EXPR in a CONSTRUCTOR for an array.
4704 var = lower;
4705 loop_entry:
4706 object[var] = value;
4707 if (var == upper)
4708 goto loop_exit;
4709 var = var + 1;
4710 goto loop_entry;
4711 loop_exit:
4713 We increment var _after_ the loop exit check because we might otherwise
4714 fail if upper == TYPE_MAX_VALUE (type for upper).
4716 Note that we never have to deal with SAVE_EXPRs here, because this has
4717 already been taken care of for us, in gimplify_init_ctor_preeval(). */
4719 static void gimplify_init_ctor_eval (tree, vec<constructor_elt, va_gc> *,
4720 gimple_seq *, bool);
4722 static void
4723 gimplify_init_ctor_eval_range (tree object, tree lower, tree upper,
4724 tree value, tree array_elt_type,
4725 gimple_seq *pre_p, bool cleared)
4727 tree loop_entry_label, loop_exit_label, fall_thru_label;
4728 tree var, var_type, cref, tmp;
4730 loop_entry_label = create_artificial_label (UNKNOWN_LOCATION);
4731 loop_exit_label = create_artificial_label (UNKNOWN_LOCATION);
4732 fall_thru_label = create_artificial_label (UNKNOWN_LOCATION);
4734 /* Create and initialize the index variable. */
4735 var_type = TREE_TYPE (upper);
4736 var = create_tmp_var (var_type);
4737 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, lower));
4739 /* Add the loop entry label. */
4740 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_entry_label));
4742 /* Build the reference. */
4743 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
4744 var, NULL_TREE, NULL_TREE);
4746 /* If we are a constructor, just call gimplify_init_ctor_eval to do
4747 the store. Otherwise just assign value to the reference. */
4749 if (TREE_CODE (value) == CONSTRUCTOR)
4750 /* NB we might have to call ourself recursively through
4751 gimplify_init_ctor_eval if the value is a constructor. */
4752 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
4753 pre_p, cleared);
4754 else
4756 if (gimplify_expr (&value, pre_p, NULL, is_gimple_val, fb_rvalue)
4757 != GS_ERROR)
4758 gimplify_seq_add_stmt (pre_p, gimple_build_assign (cref, value));
4761 /* We exit the loop when the index var is equal to the upper bound. */
4762 gimplify_seq_add_stmt (pre_p,
4763 gimple_build_cond (EQ_EXPR, var, upper,
4764 loop_exit_label, fall_thru_label));
4766 gimplify_seq_add_stmt (pre_p, gimple_build_label (fall_thru_label));
4768 /* Otherwise, increment the index var... */
4769 tmp = build2 (PLUS_EXPR, var_type, var,
4770 fold_convert (var_type, integer_one_node));
4771 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, tmp));
4773 /* ...and jump back to the loop entry. */
4774 gimplify_seq_add_stmt (pre_p, gimple_build_goto (loop_entry_label));
4776 /* Add the loop exit label. */
4777 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_exit_label));
4780 /* A subroutine of gimplify_init_constructor. Generate individual
4781 MODIFY_EXPRs for a CONSTRUCTOR. OBJECT is the LHS against which the
4782 assignments should happen. ELTS is the CONSTRUCTOR_ELTS of the
4783 CONSTRUCTOR. CLEARED is true if the entire LHS object has been
4784 zeroed first. */
4786 static void
4787 gimplify_init_ctor_eval (tree object, vec<constructor_elt, va_gc> *elts,
4788 gimple_seq *pre_p, bool cleared)
4790 tree array_elt_type = NULL;
4791 unsigned HOST_WIDE_INT ix;
4792 tree purpose, value;
4794 if (TREE_CODE (TREE_TYPE (object)) == ARRAY_TYPE)
4795 array_elt_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (object)));
4797 FOR_EACH_CONSTRUCTOR_ELT (elts, ix, purpose, value)
4799 tree cref;
4801 /* NULL values are created above for gimplification errors. */
4802 if (value == NULL)
4803 continue;
4805 if (cleared && initializer_zerop (value))
4806 continue;
4808 /* ??? Here's to hoping the front end fills in all of the indices,
4809 so we don't have to figure out what's missing ourselves. */
4810 gcc_assert (purpose);
4812 /* Skip zero-sized fields, unless value has side-effects. This can
4813 happen with calls to functions returning a empty type, which
4814 we shouldn't discard. As a number of downstream passes don't
4815 expect sets of empty type fields, we rely on the gimplification of
4816 the MODIFY_EXPR we make below to drop the assignment statement. */
4817 if (!TREE_SIDE_EFFECTS (value)
4818 && TREE_CODE (purpose) == FIELD_DECL
4819 && is_empty_type (TREE_TYPE (purpose)))
4820 continue;
4822 /* If we have a RANGE_EXPR, we have to build a loop to assign the
4823 whole range. */
4824 if (TREE_CODE (purpose) == RANGE_EXPR)
4826 tree lower = TREE_OPERAND (purpose, 0);
4827 tree upper = TREE_OPERAND (purpose, 1);
4829 /* If the lower bound is equal to upper, just treat it as if
4830 upper was the index. */
4831 if (simple_cst_equal (lower, upper))
4832 purpose = upper;
4833 else
4835 gimplify_init_ctor_eval_range (object, lower, upper, value,
4836 array_elt_type, pre_p, cleared);
4837 continue;
4841 if (array_elt_type)
4843 /* Do not use bitsizetype for ARRAY_REF indices. */
4844 if (TYPE_DOMAIN (TREE_TYPE (object)))
4845 purpose
4846 = fold_convert (TREE_TYPE (TYPE_DOMAIN (TREE_TYPE (object))),
4847 purpose);
4848 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
4849 purpose, NULL_TREE, NULL_TREE);
4851 else
4853 gcc_assert (TREE_CODE (purpose) == FIELD_DECL);
4854 cref = build3 (COMPONENT_REF, TREE_TYPE (purpose),
4855 unshare_expr (object), purpose, NULL_TREE);
4858 if (TREE_CODE (value) == CONSTRUCTOR
4859 && TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE)
4860 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
4861 pre_p, cleared);
4862 else
4864 tree init = build2 (INIT_EXPR, TREE_TYPE (cref), cref, value);
4865 gimplify_and_add (init, pre_p);
4866 ggc_free (init);
4871 /* Return the appropriate RHS predicate for this LHS. */
4873 gimple_predicate
4874 rhs_predicate_for (tree lhs)
4876 if (is_gimple_reg (lhs))
4877 return is_gimple_reg_rhs_or_call;
4878 else
4879 return is_gimple_mem_rhs_or_call;
4882 /* Return the initial guess for an appropriate RHS predicate for this LHS,
4883 before the LHS has been gimplified. */
4885 static gimple_predicate
4886 initial_rhs_predicate_for (tree lhs)
4888 if (is_gimple_reg_type (TREE_TYPE (lhs)))
4889 return is_gimple_reg_rhs_or_call;
4890 else
4891 return is_gimple_mem_rhs_or_call;
4894 /* Gimplify a C99 compound literal expression. This just means adding
4895 the DECL_EXPR before the current statement and using its anonymous
4896 decl instead. */
4898 static enum gimplify_status
4899 gimplify_compound_literal_expr (tree *expr_p, gimple_seq *pre_p,
4900 bool (*gimple_test_f) (tree),
4901 fallback_t fallback)
4903 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (*expr_p);
4904 tree decl = DECL_EXPR_DECL (decl_s);
4905 tree init = DECL_INITIAL (decl);
4906 /* Mark the decl as addressable if the compound literal
4907 expression is addressable now, otherwise it is marked too late
4908 after we gimplify the initialization expression. */
4909 if (TREE_ADDRESSABLE (*expr_p))
4910 TREE_ADDRESSABLE (decl) = 1;
4911 /* Otherwise, if we don't need an lvalue and have a literal directly
4912 substitute it. Check if it matches the gimple predicate, as
4913 otherwise we'd generate a new temporary, and we can as well just
4914 use the decl we already have. */
4915 else if (!TREE_ADDRESSABLE (decl)
4916 && !TREE_THIS_VOLATILE (decl)
4917 && init
4918 && (fallback & fb_lvalue) == 0
4919 && gimple_test_f (init))
4921 *expr_p = init;
4922 return GS_OK;
4925 /* If the decl is not addressable, then it is being used in some
4926 expression or on the right hand side of a statement, and it can
4927 be put into a readonly data section. */
4928 if (!TREE_ADDRESSABLE (decl) && (fallback & fb_lvalue) == 0)
4929 TREE_READONLY (decl) = 1;
4931 /* This decl isn't mentioned in the enclosing block, so add it to the
4932 list of temps. FIXME it seems a bit of a kludge to say that
4933 anonymous artificial vars aren't pushed, but everything else is. */
4934 if (DECL_NAME (decl) == NULL_TREE && !DECL_SEEN_IN_BIND_EXPR_P (decl))
4935 gimple_add_tmp_var (decl);
4937 gimplify_and_add (decl_s, pre_p);
4938 *expr_p = decl;
4939 return GS_OK;
4942 /* Optimize embedded COMPOUND_LITERAL_EXPRs within a CONSTRUCTOR,
4943 return a new CONSTRUCTOR if something changed. */
4945 static tree
4946 optimize_compound_literals_in_ctor (tree orig_ctor)
4948 tree ctor = orig_ctor;
4949 vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ctor);
4950 unsigned int idx, num = vec_safe_length (elts);
4952 for (idx = 0; idx < num; idx++)
4954 tree value = (*elts)[idx].value;
4955 tree newval = value;
4956 if (TREE_CODE (value) == CONSTRUCTOR)
4957 newval = optimize_compound_literals_in_ctor (value);
4958 else if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR)
4960 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (value);
4961 tree decl = DECL_EXPR_DECL (decl_s);
4962 tree init = DECL_INITIAL (decl);
4964 if (!TREE_ADDRESSABLE (value)
4965 && !TREE_ADDRESSABLE (decl)
4966 && init
4967 && TREE_CODE (init) == CONSTRUCTOR)
4968 newval = optimize_compound_literals_in_ctor (init);
4970 if (newval == value)
4971 continue;
4973 if (ctor == orig_ctor)
4975 ctor = copy_node (orig_ctor);
4976 CONSTRUCTOR_ELTS (ctor) = vec_safe_copy (elts);
4977 elts = CONSTRUCTOR_ELTS (ctor);
4979 (*elts)[idx].value = newval;
4981 return ctor;
4984 /* A subroutine of gimplify_modify_expr. Break out elements of a
4985 CONSTRUCTOR used as an initializer into separate MODIFY_EXPRs.
4987 Note that we still need to clear any elements that don't have explicit
4988 initializers, so if not all elements are initialized we keep the
4989 original MODIFY_EXPR, we just remove all of the constructor elements.
4991 If NOTIFY_TEMP_CREATION is true, do not gimplify, just return
4992 GS_ERROR if we would have to create a temporary when gimplifying
4993 this constructor. Otherwise, return GS_OK.
4995 If NOTIFY_TEMP_CREATION is false, just do the gimplification. */
4997 static enum gimplify_status
4998 gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
4999 bool want_value, bool notify_temp_creation)
5001 tree object, ctor, type;
5002 enum gimplify_status ret;
5003 vec<constructor_elt, va_gc> *elts;
5004 bool cleared = false;
5005 bool is_empty_ctor = false;
5006 bool is_init_expr = (TREE_CODE (*expr_p) == INIT_EXPR);
5008 gcc_assert (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == CONSTRUCTOR);
5010 if (!notify_temp_creation)
5012 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
5013 is_gimple_lvalue, fb_lvalue);
5014 if (ret == GS_ERROR)
5015 return ret;
5018 object = TREE_OPERAND (*expr_p, 0);
5019 ctor = TREE_OPERAND (*expr_p, 1)
5020 = optimize_compound_literals_in_ctor (TREE_OPERAND (*expr_p, 1));
5021 type = TREE_TYPE (ctor);
5022 elts = CONSTRUCTOR_ELTS (ctor);
5023 ret = GS_ALL_DONE;
5025 switch (TREE_CODE (type))
5027 case RECORD_TYPE:
5028 case UNION_TYPE:
5029 case QUAL_UNION_TYPE:
5030 case ARRAY_TYPE:
5032 /* Use readonly data for initializers of this or smaller size
5033 regardless of the num_nonzero_elements / num_unique_nonzero_elements
5034 ratio. */
5035 const HOST_WIDE_INT min_unique_size = 64;
5036 /* If num_nonzero_elements / num_unique_nonzero_elements ratio
5037 is smaller than this, use readonly data. */
5038 const int unique_nonzero_ratio = 8;
5039 /* True if a single access of the object must be ensured. This is the
5040 case if the target is volatile, the type is non-addressable and more
5041 than one field need to be assigned. */
5042 const bool ensure_single_access
5043 = TREE_THIS_VOLATILE (object)
5044 && !TREE_ADDRESSABLE (type)
5045 && vec_safe_length (elts) > 1;
5046 struct gimplify_init_ctor_preeval_data preeval_data;
5047 HOST_WIDE_INT num_ctor_elements, num_nonzero_elements;
5048 HOST_WIDE_INT num_unique_nonzero_elements;
5049 bool complete_p, valid_const_initializer;
5051 /* Aggregate types must lower constructors to initialization of
5052 individual elements. The exception is that a CONSTRUCTOR node
5053 with no elements indicates zero-initialization of the whole. */
5054 if (vec_safe_is_empty (elts))
5056 if (notify_temp_creation)
5057 return GS_OK;
5058 is_empty_ctor = true;
5059 break;
5062 /* Fetch information about the constructor to direct later processing.
5063 We might want to make static versions of it in various cases, and
5064 can only do so if it known to be a valid constant initializer. */
5065 valid_const_initializer
5066 = categorize_ctor_elements (ctor, &num_nonzero_elements,
5067 &num_unique_nonzero_elements,
5068 &num_ctor_elements, &complete_p);
5070 /* If a const aggregate variable is being initialized, then it
5071 should never be a lose to promote the variable to be static. */
5072 if (valid_const_initializer
5073 && num_nonzero_elements > 1
5074 && TREE_READONLY (object)
5075 && VAR_P (object)
5076 && !DECL_REGISTER (object)
5077 && (flag_merge_constants >= 2 || !TREE_ADDRESSABLE (object))
5078 /* For ctors that have many repeated nonzero elements
5079 represented through RANGE_EXPRs, prefer initializing
5080 those through runtime loops over copies of large amounts
5081 of data from readonly data section. */
5082 && (num_unique_nonzero_elements
5083 > num_nonzero_elements / unique_nonzero_ratio
5084 || ((unsigned HOST_WIDE_INT) int_size_in_bytes (type)
5085 <= (unsigned HOST_WIDE_INT) min_unique_size)))
5087 if (notify_temp_creation)
5088 return GS_ERROR;
5090 DECL_INITIAL (object) = ctor;
5091 TREE_STATIC (object) = 1;
5092 if (!DECL_NAME (object))
5093 DECL_NAME (object) = create_tmp_var_name ("C");
5094 walk_tree (&DECL_INITIAL (object), force_labels_r, NULL, NULL);
5096 /* ??? C++ doesn't automatically append a .<number> to the
5097 assembler name, and even when it does, it looks at FE private
5098 data structures to figure out what that number should be,
5099 which are not set for this variable. I suppose this is
5100 important for local statics for inline functions, which aren't
5101 "local" in the object file sense. So in order to get a unique
5102 TU-local symbol, we must invoke the lhd version now. */
5103 lhd_set_decl_assembler_name (object);
5105 *expr_p = NULL_TREE;
5106 break;
5109 /* If there are "lots" of initialized elements, even discounting
5110 those that are not address constants (and thus *must* be
5111 computed at runtime), then partition the constructor into
5112 constant and non-constant parts. Block copy the constant
5113 parts in, then generate code for the non-constant parts. */
5114 /* TODO. There's code in cp/typeck.cc to do this. */
5116 if (int_size_in_bytes (TREE_TYPE (ctor)) < 0)
5117 /* store_constructor will ignore the clearing of variable-sized
5118 objects. Initializers for such objects must explicitly set
5119 every field that needs to be set. */
5120 cleared = false;
5121 else if (!complete_p)
5122 /* If the constructor isn't complete, clear the whole object
5123 beforehand, unless CONSTRUCTOR_NO_CLEARING is set on it.
5125 ??? This ought not to be needed. For any element not present
5126 in the initializer, we should simply set them to zero. Except
5127 we'd need to *find* the elements that are not present, and that
5128 requires trickery to avoid quadratic compile-time behavior in
5129 large cases or excessive memory use in small cases. */
5130 cleared = !CONSTRUCTOR_NO_CLEARING (ctor);
5131 else if (num_ctor_elements - num_nonzero_elements
5132 > CLEAR_RATIO (optimize_function_for_speed_p (cfun))
5133 && num_nonzero_elements < num_ctor_elements / 4)
5134 /* If there are "lots" of zeros, it's more efficient to clear
5135 the memory and then set the nonzero elements. */
5136 cleared = true;
5137 else if (ensure_single_access && num_nonzero_elements == 0)
5138 /* If a single access to the target must be ensured and all elements
5139 are zero, then it's optimal to clear whatever their number. */
5140 cleared = true;
5141 else
5142 cleared = false;
5144 /* If there are "lots" of initialized elements, and all of them
5145 are valid address constants, then the entire initializer can
5146 be dropped to memory, and then memcpy'd out. Don't do this
5147 for sparse arrays, though, as it's more efficient to follow
5148 the standard CONSTRUCTOR behavior of memset followed by
5149 individual element initialization. Also don't do this for small
5150 all-zero initializers (which aren't big enough to merit
5151 clearing), and don't try to make bitwise copies of
5152 TREE_ADDRESSABLE types. */
5153 if (valid_const_initializer
5154 && complete_p
5155 && !(cleared || num_nonzero_elements == 0)
5156 && !TREE_ADDRESSABLE (type))
5158 HOST_WIDE_INT size = int_size_in_bytes (type);
5159 unsigned int align;
5161 /* ??? We can still get unbounded array types, at least
5162 from the C++ front end. This seems wrong, but attempt
5163 to work around it for now. */
5164 if (size < 0)
5166 size = int_size_in_bytes (TREE_TYPE (object));
5167 if (size >= 0)
5168 TREE_TYPE (ctor) = type = TREE_TYPE (object);
5171 /* Find the maximum alignment we can assume for the object. */
5172 /* ??? Make use of DECL_OFFSET_ALIGN. */
5173 if (DECL_P (object))
5174 align = DECL_ALIGN (object);
5175 else
5176 align = TYPE_ALIGN (type);
5178 /* Do a block move either if the size is so small as to make
5179 each individual move a sub-unit move on average, or if it
5180 is so large as to make individual moves inefficient. */
5181 if (size > 0
5182 && num_nonzero_elements > 1
5183 /* For ctors that have many repeated nonzero elements
5184 represented through RANGE_EXPRs, prefer initializing
5185 those through runtime loops over copies of large amounts
5186 of data from readonly data section. */
5187 && (num_unique_nonzero_elements
5188 > num_nonzero_elements / unique_nonzero_ratio
5189 || size <= min_unique_size)
5190 && (size < num_nonzero_elements
5191 || !can_move_by_pieces (size, align)))
5193 if (notify_temp_creation)
5194 return GS_ERROR;
5196 walk_tree (&ctor, force_labels_r, NULL, NULL);
5197 ctor = tree_output_constant_def (ctor);
5198 if (!useless_type_conversion_p (type, TREE_TYPE (ctor)))
5199 ctor = build1 (VIEW_CONVERT_EXPR, type, ctor);
5200 TREE_OPERAND (*expr_p, 1) = ctor;
5202 /* This is no longer an assignment of a CONSTRUCTOR, but
5203 we still may have processing to do on the LHS. So
5204 pretend we didn't do anything here to let that happen. */
5205 return GS_UNHANDLED;
5209 /* If a single access to the target must be ensured and there are
5210 nonzero elements or the zero elements are not assigned en masse,
5211 initialize the target from a temporary. */
5212 if (ensure_single_access && (num_nonzero_elements > 0 || !cleared))
5214 if (notify_temp_creation)
5215 return GS_ERROR;
5217 tree temp = create_tmp_var (TYPE_MAIN_VARIANT (type));
5218 TREE_OPERAND (*expr_p, 0) = temp;
5219 *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p),
5220 *expr_p,
5221 build2 (MODIFY_EXPR, void_type_node,
5222 object, temp));
5223 return GS_OK;
5226 if (notify_temp_creation)
5227 return GS_OK;
5229 /* If there are nonzero elements and if needed, pre-evaluate to capture
5230 elements overlapping with the lhs into temporaries. We must do this
5231 before clearing to fetch the values before they are zeroed-out. */
5232 if (num_nonzero_elements > 0 && TREE_CODE (*expr_p) != INIT_EXPR)
5234 preeval_data.lhs_base_decl = get_base_address (object);
5235 if (!DECL_P (preeval_data.lhs_base_decl))
5236 preeval_data.lhs_base_decl = NULL;
5237 preeval_data.lhs_alias_set = get_alias_set (object);
5239 gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p, 1),
5240 pre_p, post_p, &preeval_data);
5243 bool ctor_has_side_effects_p
5244 = TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p, 1));
5246 if (cleared)
5248 /* Zap the CONSTRUCTOR element list, which simplifies this case.
5249 Note that we still have to gimplify, in order to handle the
5250 case of variable sized types. Avoid shared tree structures. */
5251 CONSTRUCTOR_ELTS (ctor) = NULL;
5252 TREE_SIDE_EFFECTS (ctor) = 0;
5253 object = unshare_expr (object);
5254 gimplify_stmt (expr_p, pre_p);
5257 /* If we have not block cleared the object, or if there are nonzero
5258 elements in the constructor, or if the constructor has side effects,
5259 add assignments to the individual scalar fields of the object. */
5260 if (!cleared
5261 || num_nonzero_elements > 0
5262 || ctor_has_side_effects_p)
5263 gimplify_init_ctor_eval (object, elts, pre_p, cleared);
5265 *expr_p = NULL_TREE;
5267 break;
5269 case COMPLEX_TYPE:
5271 tree r, i;
5273 if (notify_temp_creation)
5274 return GS_OK;
5276 /* Extract the real and imaginary parts out of the ctor. */
5277 gcc_assert (elts->length () == 2);
5278 r = (*elts)[0].value;
5279 i = (*elts)[1].value;
5280 if (r == NULL || i == NULL)
5282 tree zero = build_zero_cst (TREE_TYPE (type));
5283 if (r == NULL)
5284 r = zero;
5285 if (i == NULL)
5286 i = zero;
5289 /* Complex types have either COMPLEX_CST or COMPLEX_EXPR to
5290 represent creation of a complex value. */
5291 if (TREE_CONSTANT (r) && TREE_CONSTANT (i))
5293 ctor = build_complex (type, r, i);
5294 TREE_OPERAND (*expr_p, 1) = ctor;
5296 else
5298 ctor = build2 (COMPLEX_EXPR, type, r, i);
5299 TREE_OPERAND (*expr_p, 1) = ctor;
5300 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 1),
5301 pre_p,
5302 post_p,
5303 rhs_predicate_for (TREE_OPERAND (*expr_p, 0)),
5304 fb_rvalue);
5307 break;
5309 case VECTOR_TYPE:
5311 unsigned HOST_WIDE_INT ix;
5312 constructor_elt *ce;
5314 if (notify_temp_creation)
5315 return GS_OK;
5317 /* Go ahead and simplify constant constructors to VECTOR_CST. */
5318 if (TREE_CONSTANT (ctor))
5320 bool constant_p = true;
5321 tree value;
5323 /* Even when ctor is constant, it might contain non-*_CST
5324 elements, such as addresses or trapping values like
5325 1.0/0.0 - 1.0/0.0. Such expressions don't belong
5326 in VECTOR_CST nodes. */
5327 FOR_EACH_CONSTRUCTOR_VALUE (elts, ix, value)
5328 if (!CONSTANT_CLASS_P (value))
5330 constant_p = false;
5331 break;
5334 if (constant_p)
5336 TREE_OPERAND (*expr_p, 1) = build_vector_from_ctor (type, elts);
5337 break;
5340 TREE_CONSTANT (ctor) = 0;
5343 /* Vector types use CONSTRUCTOR all the way through gimple
5344 compilation as a general initializer. */
5345 FOR_EACH_VEC_SAFE_ELT (elts, ix, ce)
5347 enum gimplify_status tret;
5348 tret = gimplify_expr (&ce->value, pre_p, post_p, is_gimple_val,
5349 fb_rvalue);
5350 if (tret == GS_ERROR)
5351 ret = GS_ERROR;
5352 else if (TREE_STATIC (ctor)
5353 && !initializer_constant_valid_p (ce->value,
5354 TREE_TYPE (ce->value)))
5355 TREE_STATIC (ctor) = 0;
5357 recompute_constructor_flags (ctor);
5358 if (!is_gimple_reg (TREE_OPERAND (*expr_p, 0)))
5359 TREE_OPERAND (*expr_p, 1) = get_formal_tmp_var (ctor, pre_p);
5361 break;
5363 default:
5364 /* So how did we get a CONSTRUCTOR for a scalar type? */
5365 gcc_unreachable ();
5368 if (ret == GS_ERROR)
5369 return GS_ERROR;
5370 /* If we have gimplified both sides of the initializer but have
5371 not emitted an assignment, do so now. */
5372 if (*expr_p)
5374 tree lhs = TREE_OPERAND (*expr_p, 0);
5375 tree rhs = TREE_OPERAND (*expr_p, 1);
5376 if (want_value && object == lhs)
5377 lhs = unshare_expr (lhs);
5378 gassign *init = gimple_build_assign (lhs, rhs);
5379 gimplify_seq_add_stmt (pre_p, init);
5381 if (want_value)
5383 *expr_p = object;
5384 ret = GS_OK;
5386 else
5388 *expr_p = NULL;
5389 ret = GS_ALL_DONE;
5392 /* If the user requests to initialize automatic variables, we
5393 should initialize paddings inside the variable. Add a call to
5394 __builtin_clear_pading (&object, 0, for_auto_init = true) to
5395 initialize paddings of object always to zero regardless of
5396 INIT_TYPE. Note, we will not insert this call if the aggregate
5397 variable has be completely cleared already or it's initialized
5398 with an empty constructor. We cannot insert this call if the
5399 variable is a gimple register since __builtin_clear_padding will take
5400 the address of the variable. As a result, if a long double/_Complex long
5401 double variable will be spilled into stack later, its padding cannot
5402 be cleared with __builtin_clear_padding. We should clear its padding
5403 when it is spilled into memory. */
5404 if (is_init_expr
5405 && !is_gimple_reg (object)
5406 && clear_padding_type_may_have_padding_p (type)
5407 && ((AGGREGATE_TYPE_P (type) && !cleared && !is_empty_ctor)
5408 || !AGGREGATE_TYPE_P (type))
5409 && is_var_need_auto_init (object))
5410 gimple_add_padding_init_for_auto_var (object, false, pre_p);
5412 return ret;
5415 /* Given a pointer value OP0, return a simplified version of an
5416 indirection through OP0, or NULL_TREE if no simplification is
5417 possible. This may only be applied to a rhs of an expression.
5418 Note that the resulting type may be different from the type pointed
5419 to in the sense that it is still compatible from the langhooks
5420 point of view. */
5422 static tree
5423 gimple_fold_indirect_ref_rhs (tree t)
5425 return gimple_fold_indirect_ref (t);
5428 /* Subroutine of gimplify_modify_expr to do simplifications of
5429 MODIFY_EXPRs based on the code of the RHS. We loop for as long as
5430 something changes. */
5432 static enum gimplify_status
5433 gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p,
5434 gimple_seq *pre_p, gimple_seq *post_p,
5435 bool want_value)
5437 enum gimplify_status ret = GS_UNHANDLED;
5438 bool changed;
5442 changed = false;
5443 switch (TREE_CODE (*from_p))
5445 case VAR_DECL:
5446 /* If we're assigning from a read-only variable initialized with
5447 a constructor and not volatile, do the direct assignment from
5448 the constructor, but only if the target is not volatile either
5449 since this latter assignment might end up being done on a per
5450 field basis. However, if the target is volatile and the type
5451 is aggregate and non-addressable, gimplify_init_constructor
5452 knows that it needs to ensure a single access to the target
5453 and it will return GS_OK only in this case. */
5454 if (TREE_READONLY (*from_p)
5455 && DECL_INITIAL (*from_p)
5456 && TREE_CODE (DECL_INITIAL (*from_p)) == CONSTRUCTOR
5457 && !TREE_THIS_VOLATILE (*from_p)
5458 && (!TREE_THIS_VOLATILE (*to_p)
5459 || (AGGREGATE_TYPE_P (TREE_TYPE (*to_p))
5460 && !TREE_ADDRESSABLE (TREE_TYPE (*to_p)))))
5462 tree old_from = *from_p;
5463 enum gimplify_status subret;
5465 /* Move the constructor into the RHS. */
5466 *from_p = unshare_expr (DECL_INITIAL (*from_p));
5468 /* Let's see if gimplify_init_constructor will need to put
5469 it in memory. */
5470 subret = gimplify_init_constructor (expr_p, NULL, NULL,
5471 false, true);
5472 if (subret == GS_ERROR)
5474 /* If so, revert the change. */
5475 *from_p = old_from;
5477 else
5479 ret = GS_OK;
5480 changed = true;
5483 break;
5484 case INDIRECT_REF:
5486 /* If we have code like
5488 *(const A*)(A*)&x
5490 where the type of "x" is a (possibly cv-qualified variant
5491 of "A"), treat the entire expression as identical to "x".
5492 This kind of code arises in C++ when an object is bound
5493 to a const reference, and if "x" is a TARGET_EXPR we want
5494 to take advantage of the optimization below. */
5495 bool volatile_p = TREE_THIS_VOLATILE (*from_p);
5496 tree t = gimple_fold_indirect_ref_rhs (TREE_OPERAND (*from_p, 0));
5497 if (t)
5499 if (TREE_THIS_VOLATILE (t) != volatile_p)
5501 if (DECL_P (t))
5502 t = build_simple_mem_ref_loc (EXPR_LOCATION (*from_p),
5503 build_fold_addr_expr (t));
5504 if (REFERENCE_CLASS_P (t))
5505 TREE_THIS_VOLATILE (t) = volatile_p;
5507 *from_p = t;
5508 ret = GS_OK;
5509 changed = true;
5511 break;
5514 case TARGET_EXPR:
5516 /* If we are initializing something from a TARGET_EXPR, strip the
5517 TARGET_EXPR and initialize it directly, if possible. This can't
5518 be done if the initializer is void, since that implies that the
5519 temporary is set in some non-trivial way.
5521 ??? What about code that pulls out the temp and uses it
5522 elsewhere? I think that such code never uses the TARGET_EXPR as
5523 an initializer. If I'm wrong, we'll die because the temp won't
5524 have any RTL. In that case, I guess we'll need to replace
5525 references somehow. */
5526 tree init = TARGET_EXPR_INITIAL (*from_p);
5528 if (init
5529 && (TREE_CODE (*expr_p) != MODIFY_EXPR
5530 || !TARGET_EXPR_NO_ELIDE (*from_p))
5531 && !VOID_TYPE_P (TREE_TYPE (init)))
5533 *from_p = init;
5534 ret = GS_OK;
5535 changed = true;
5538 break;
5540 case COMPOUND_EXPR:
5541 /* Remove any COMPOUND_EXPR in the RHS so the following cases will be
5542 caught. */
5543 gimplify_compound_expr (from_p, pre_p, true);
5544 ret = GS_OK;
5545 changed = true;
5546 break;
5548 case CONSTRUCTOR:
5549 /* If we already made some changes, let the front end have a
5550 crack at this before we break it down. */
5551 if (ret != GS_UNHANDLED)
5552 break;
5554 /* If we're initializing from a CONSTRUCTOR, break this into
5555 individual MODIFY_EXPRs. */
5556 ret = gimplify_init_constructor (expr_p, pre_p, post_p, want_value,
5557 false);
5558 return ret;
5560 case COND_EXPR:
5561 /* If we're assigning to a non-register type, push the assignment
5562 down into the branches. This is mandatory for ADDRESSABLE types,
5563 since we cannot generate temporaries for such, but it saves a
5564 copy in other cases as well. */
5565 if (!is_gimple_reg_type (TREE_TYPE (*from_p)))
5567 /* This code should mirror the code in gimplify_cond_expr. */
5568 enum tree_code code = TREE_CODE (*expr_p);
5569 tree cond = *from_p;
5570 tree result = *to_p;
5572 ret = gimplify_expr (&result, pre_p, post_p,
5573 is_gimple_lvalue, fb_lvalue);
5574 if (ret != GS_ERROR)
5575 ret = GS_OK;
5577 /* If we are going to write RESULT more than once, clear
5578 TREE_READONLY flag, otherwise we might incorrectly promote
5579 the variable to static const and initialize it at compile
5580 time in one of the branches. */
5581 if (VAR_P (result)
5582 && TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node
5583 && TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
5584 TREE_READONLY (result) = 0;
5585 if (TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node)
5586 TREE_OPERAND (cond, 1)
5587 = build2 (code, void_type_node, result,
5588 TREE_OPERAND (cond, 1));
5589 if (TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
5590 TREE_OPERAND (cond, 2)
5591 = build2 (code, void_type_node, unshare_expr (result),
5592 TREE_OPERAND (cond, 2));
5594 TREE_TYPE (cond) = void_type_node;
5595 recalculate_side_effects (cond);
5597 if (want_value)
5599 gimplify_and_add (cond, pre_p);
5600 *expr_p = unshare_expr (result);
5602 else
5603 *expr_p = cond;
5604 return ret;
5606 break;
5608 case CALL_EXPR:
5609 /* For calls that return in memory, give *to_p as the CALL_EXPR's
5610 return slot so that we don't generate a temporary. */
5611 if (!CALL_EXPR_RETURN_SLOT_OPT (*from_p)
5612 && aggregate_value_p (*from_p, *from_p))
5614 bool use_target;
5616 if (!(rhs_predicate_for (*to_p))(*from_p))
5617 /* If we need a temporary, *to_p isn't accurate. */
5618 use_target = false;
5619 /* It's OK to use the return slot directly unless it's an NRV. */
5620 else if (TREE_CODE (*to_p) == RESULT_DECL
5621 && DECL_NAME (*to_p) == NULL_TREE
5622 && needs_to_live_in_memory (*to_p))
5623 use_target = true;
5624 else if (is_gimple_reg_type (TREE_TYPE (*to_p))
5625 || (DECL_P (*to_p) && DECL_REGISTER (*to_p)))
5626 /* Don't force regs into memory. */
5627 use_target = false;
5628 else if (TREE_CODE (*expr_p) == INIT_EXPR)
5629 /* It's OK to use the target directly if it's being
5630 initialized. */
5631 use_target = true;
5632 else if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p)))
5633 != INTEGER_CST)
5634 /* Always use the target and thus RSO for variable-sized types.
5635 GIMPLE cannot deal with a variable-sized assignment
5636 embedded in a call statement. */
5637 use_target = true;
5638 else if (TREE_CODE (*to_p) != SSA_NAME
5639 && (!is_gimple_variable (*to_p)
5640 || needs_to_live_in_memory (*to_p)))
5641 /* Don't use the original target if it's already addressable;
5642 if its address escapes, and the called function uses the
5643 NRV optimization, a conforming program could see *to_p
5644 change before the called function returns; see c++/19317.
5645 When optimizing, the return_slot pass marks more functions
5646 as safe after we have escape info. */
5647 use_target = false;
5648 else
5649 use_target = true;
5651 if (use_target)
5653 CALL_EXPR_RETURN_SLOT_OPT (*from_p) = 1;
5654 mark_addressable (*to_p);
5657 break;
5659 case WITH_SIZE_EXPR:
5660 /* Likewise for calls that return an aggregate of non-constant size,
5661 since we would not be able to generate a temporary at all. */
5662 if (TREE_CODE (TREE_OPERAND (*from_p, 0)) == CALL_EXPR)
5664 *from_p = TREE_OPERAND (*from_p, 0);
5665 /* We don't change ret in this case because the
5666 WITH_SIZE_EXPR might have been added in
5667 gimplify_modify_expr, so returning GS_OK would lead to an
5668 infinite loop. */
5669 changed = true;
5671 break;
5673 /* If we're initializing from a container, push the initialization
5674 inside it. */
5675 case CLEANUP_POINT_EXPR:
5676 case BIND_EXPR:
5677 case STATEMENT_LIST:
5679 tree wrap = *from_p;
5680 tree t;
5682 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_min_lval,
5683 fb_lvalue);
5684 if (ret != GS_ERROR)
5685 ret = GS_OK;
5687 t = voidify_wrapper_expr (wrap, *expr_p);
5688 gcc_assert (t == *expr_p);
5690 if (want_value)
5692 gimplify_and_add (wrap, pre_p);
5693 *expr_p = unshare_expr (*to_p);
5695 else
5696 *expr_p = wrap;
5697 return GS_OK;
5700 case NOP_EXPR:
5701 /* Pull out compound literal expressions from a NOP_EXPR.
5702 Those are created in the C FE to drop qualifiers during
5703 lvalue conversion. */
5704 if ((TREE_CODE (TREE_OPERAND (*from_p, 0)) == COMPOUND_LITERAL_EXPR)
5705 && tree_ssa_useless_type_conversion (*from_p))
5707 *from_p = TREE_OPERAND (*from_p, 0);
5708 ret = GS_OK;
5709 changed = true;
5711 break;
5713 case COMPOUND_LITERAL_EXPR:
5715 tree complit = TREE_OPERAND (*expr_p, 1);
5716 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (complit);
5717 tree decl = DECL_EXPR_DECL (decl_s);
5718 tree init = DECL_INITIAL (decl);
5720 /* struct T x = (struct T) { 0, 1, 2 } can be optimized
5721 into struct T x = { 0, 1, 2 } if the address of the
5722 compound literal has never been taken. */
5723 if (!TREE_ADDRESSABLE (complit)
5724 && !TREE_ADDRESSABLE (decl)
5725 && init)
5727 *expr_p = copy_node (*expr_p);
5728 TREE_OPERAND (*expr_p, 1) = init;
5729 return GS_OK;
5733 default:
5734 break;
5737 while (changed);
5739 return ret;
5743 /* Return true if T looks like a valid GIMPLE statement. */
5745 static bool
5746 is_gimple_stmt (tree t)
5748 const enum tree_code code = TREE_CODE (t);
5750 switch (code)
5752 case NOP_EXPR:
5753 /* The only valid NOP_EXPR is the empty statement. */
5754 return IS_EMPTY_STMT (t);
5756 case BIND_EXPR:
5757 case COND_EXPR:
5758 /* These are only valid if they're void. */
5759 return TREE_TYPE (t) == NULL || VOID_TYPE_P (TREE_TYPE (t));
5761 case SWITCH_EXPR:
5762 case GOTO_EXPR:
5763 case RETURN_EXPR:
5764 case LABEL_EXPR:
5765 case CASE_LABEL_EXPR:
5766 case TRY_CATCH_EXPR:
5767 case TRY_FINALLY_EXPR:
5768 case EH_FILTER_EXPR:
5769 case CATCH_EXPR:
5770 case ASM_EXPR:
5771 case STATEMENT_LIST:
5772 case OACC_PARALLEL:
5773 case OACC_KERNELS:
5774 case OACC_SERIAL:
5775 case OACC_DATA:
5776 case OACC_HOST_DATA:
5777 case OACC_DECLARE:
5778 case OACC_UPDATE:
5779 case OACC_ENTER_DATA:
5780 case OACC_EXIT_DATA:
5781 case OACC_CACHE:
5782 case OMP_PARALLEL:
5783 case OMP_FOR:
5784 case OMP_SIMD:
5785 case OMP_DISTRIBUTE:
5786 case OMP_LOOP:
5787 case OACC_LOOP:
5788 case OMP_SCAN:
5789 case OMP_SCOPE:
5790 case OMP_SECTIONS:
5791 case OMP_SECTION:
5792 case OMP_SINGLE:
5793 case OMP_MASTER:
5794 case OMP_MASKED:
5795 case OMP_TASKGROUP:
5796 case OMP_ORDERED:
5797 case OMP_CRITICAL:
5798 case OMP_TASK:
5799 case OMP_TARGET:
5800 case OMP_TARGET_DATA:
5801 case OMP_TARGET_UPDATE:
5802 case OMP_TARGET_ENTER_DATA:
5803 case OMP_TARGET_EXIT_DATA:
5804 case OMP_TASKLOOP:
5805 case OMP_TEAMS:
5806 /* These are always void. */
5807 return true;
5809 case CALL_EXPR:
5810 case MODIFY_EXPR:
5811 case PREDICT_EXPR:
5812 /* These are valid regardless of their type. */
5813 return true;
5815 default:
5816 return false;
5821 /* Promote partial stores to COMPLEX variables to total stores. *EXPR_P is
5822 a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a gimple register.
5824 IMPORTANT NOTE: This promotion is performed by introducing a load of the
5825 other, unmodified part of the complex object just before the total store.
5826 As a consequence, if the object is still uninitialized, an undefined value
5827 will be loaded into a register, which may result in a spurious exception
5828 if the register is floating-point and the value happens to be a signaling
5829 NaN for example. Then the fully-fledged complex operations lowering pass
5830 followed by a DCE pass are necessary in order to fix things up. */
5832 static enum gimplify_status
5833 gimplify_modify_expr_complex_part (tree *expr_p, gimple_seq *pre_p,
5834 bool want_value)
5836 enum tree_code code, ocode;
5837 tree lhs, rhs, new_rhs, other, realpart, imagpart;
5839 lhs = TREE_OPERAND (*expr_p, 0);
5840 rhs = TREE_OPERAND (*expr_p, 1);
5841 code = TREE_CODE (lhs);
5842 lhs = TREE_OPERAND (lhs, 0);
5844 ocode = code == REALPART_EXPR ? IMAGPART_EXPR : REALPART_EXPR;
5845 other = build1 (ocode, TREE_TYPE (rhs), lhs);
5846 suppress_warning (other);
5847 other = get_formal_tmp_var (other, pre_p);
5849 realpart = code == REALPART_EXPR ? rhs : other;
5850 imagpart = code == REALPART_EXPR ? other : rhs;
5852 if (TREE_CONSTANT (realpart) && TREE_CONSTANT (imagpart))
5853 new_rhs = build_complex (TREE_TYPE (lhs), realpart, imagpart);
5854 else
5855 new_rhs = build2 (COMPLEX_EXPR, TREE_TYPE (lhs), realpart, imagpart);
5857 gimplify_seq_add_stmt (pre_p, gimple_build_assign (lhs, new_rhs));
5858 *expr_p = (want_value) ? rhs : NULL_TREE;
5860 return GS_ALL_DONE;
5863 /* Gimplify the MODIFY_EXPR node pointed to by EXPR_P.
5865 modify_expr
5866 : varname '=' rhs
5867 | '*' ID '=' rhs
5869 PRE_P points to the list where side effects that must happen before
5870 *EXPR_P should be stored.
5872 POST_P points to the list where side effects that must happen after
5873 *EXPR_P should be stored.
5875 WANT_VALUE is nonzero iff we want to use the value of this expression
5876 in another expression. */
5878 static enum gimplify_status
5879 gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
5880 bool want_value)
5882 tree *from_p = &TREE_OPERAND (*expr_p, 1);
5883 tree *to_p = &TREE_OPERAND (*expr_p, 0);
5884 enum gimplify_status ret = GS_UNHANDLED;
5885 gimple *assign;
5886 location_t loc = EXPR_LOCATION (*expr_p);
5887 gimple_stmt_iterator gsi;
5889 gcc_assert (TREE_CODE (*expr_p) == MODIFY_EXPR
5890 || TREE_CODE (*expr_p) == INIT_EXPR);
5892 /* Trying to simplify a clobber using normal logic doesn't work,
5893 so handle it here. */
5894 if (TREE_CLOBBER_P (*from_p))
5896 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
5897 if (ret == GS_ERROR)
5898 return ret;
5899 gcc_assert (!want_value);
5900 if (!VAR_P (*to_p) && TREE_CODE (*to_p) != MEM_REF)
5902 tree addr = get_initialized_tmp_var (build_fold_addr_expr (*to_p),
5903 pre_p, post_p);
5904 *to_p = build_simple_mem_ref_loc (EXPR_LOCATION (*to_p), addr);
5906 gimplify_seq_add_stmt (pre_p, gimple_build_assign (*to_p, *from_p));
5907 *expr_p = NULL;
5908 return GS_ALL_DONE;
5911 /* Insert pointer conversions required by the middle-end that are not
5912 required by the frontend. This fixes middle-end type checking for
5913 for example gcc.dg/redecl-6.c. */
5914 if (POINTER_TYPE_P (TREE_TYPE (*to_p)))
5916 STRIP_USELESS_TYPE_CONVERSION (*from_p);
5917 if (!useless_type_conversion_p (TREE_TYPE (*to_p), TREE_TYPE (*from_p)))
5918 *from_p = fold_convert_loc (loc, TREE_TYPE (*to_p), *from_p);
5921 /* See if any simplifications can be done based on what the RHS is. */
5922 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
5923 want_value);
5924 if (ret != GS_UNHANDLED)
5925 return ret;
5927 /* For empty types only gimplify the left hand side and right hand
5928 side as statements and throw away the assignment. Do this after
5929 gimplify_modify_expr_rhs so we handle TARGET_EXPRs of addressable
5930 types properly. */
5931 if (is_empty_type (TREE_TYPE (*from_p))
5932 && !want_value
5933 /* Don't do this for calls that return addressable types, expand_call
5934 relies on those having a lhs. */
5935 && !(TREE_ADDRESSABLE (TREE_TYPE (*from_p))
5936 && TREE_CODE (*from_p) == CALL_EXPR))
5938 gimplify_stmt (from_p, pre_p);
5939 gimplify_stmt (to_p, pre_p);
5940 *expr_p = NULL_TREE;
5941 return GS_ALL_DONE;
5944 /* If the value being copied is of variable width, compute the length
5945 of the copy into a WITH_SIZE_EXPR. Note that we need to do this
5946 before gimplifying any of the operands so that we can resolve any
5947 PLACEHOLDER_EXPRs in the size. Also note that the RTL expander uses
5948 the size of the expression to be copied, not of the destination, so
5949 that is what we must do here. */
5950 maybe_with_size_expr (from_p);
5952 /* As a special case, we have to temporarily allow for assignments
5953 with a CALL_EXPR on the RHS. Since in GIMPLE a function call is
5954 a toplevel statement, when gimplifying the GENERIC expression
5955 MODIFY_EXPR <a, CALL_EXPR <foo>>, we cannot create the tuple
5956 GIMPLE_ASSIGN <a, GIMPLE_CALL <foo>>.
5958 Instead, we need to create the tuple GIMPLE_CALL <a, foo>. To
5959 prevent gimplify_expr from trying to create a new temporary for
5960 foo's LHS, we tell it that it should only gimplify until it
5961 reaches the CALL_EXPR. On return from gimplify_expr, the newly
5962 created GIMPLE_CALL <foo> will be the last statement in *PRE_P
5963 and all we need to do here is set 'a' to be its LHS. */
5965 /* Gimplify the RHS first for C++17 and bug 71104. */
5966 gimple_predicate initial_pred = initial_rhs_predicate_for (*to_p);
5967 ret = gimplify_expr (from_p, pre_p, post_p, initial_pred, fb_rvalue);
5968 if (ret == GS_ERROR)
5969 return ret;
5971 /* Then gimplify the LHS. */
5972 /* If we gimplified the RHS to a CALL_EXPR and that call may return
5973 twice we have to make sure to gimplify into non-SSA as otherwise
5974 the abnormal edge added later will make those defs not dominate
5975 their uses.
5976 ??? Technically this applies only to the registers used in the
5977 resulting non-register *TO_P. */
5978 bool saved_into_ssa = gimplify_ctxp->into_ssa;
5979 if (saved_into_ssa
5980 && TREE_CODE (*from_p) == CALL_EXPR
5981 && call_expr_flags (*from_p) & ECF_RETURNS_TWICE)
5982 gimplify_ctxp->into_ssa = false;
5983 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
5984 gimplify_ctxp->into_ssa = saved_into_ssa;
5985 if (ret == GS_ERROR)
5986 return ret;
5988 /* Now that the LHS is gimplified, re-gimplify the RHS if our initial
5989 guess for the predicate was wrong. */
5990 gimple_predicate final_pred = rhs_predicate_for (*to_p);
5991 if (final_pred != initial_pred)
5993 ret = gimplify_expr (from_p, pre_p, post_p, final_pred, fb_rvalue);
5994 if (ret == GS_ERROR)
5995 return ret;
5998 /* In case of va_arg internal fn wrappped in a WITH_SIZE_EXPR, add the type
5999 size as argument to the call. */
6000 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
6002 tree call = TREE_OPERAND (*from_p, 0);
6003 tree vlasize = TREE_OPERAND (*from_p, 1);
6005 if (TREE_CODE (call) == CALL_EXPR
6006 && CALL_EXPR_IFN (call) == IFN_VA_ARG)
6008 int nargs = call_expr_nargs (call);
6009 tree type = TREE_TYPE (call);
6010 tree ap = CALL_EXPR_ARG (call, 0);
6011 tree tag = CALL_EXPR_ARG (call, 1);
6012 tree aptag = CALL_EXPR_ARG (call, 2);
6013 tree newcall = build_call_expr_internal_loc (EXPR_LOCATION (call),
6014 IFN_VA_ARG, type,
6015 nargs + 1, ap, tag,
6016 aptag, vlasize);
6017 TREE_OPERAND (*from_p, 0) = newcall;
6021 /* Now see if the above changed *from_p to something we handle specially. */
6022 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
6023 want_value);
6024 if (ret != GS_UNHANDLED)
6025 return ret;
6027 /* If we've got a variable sized assignment between two lvalues (i.e. does
6028 not involve a call), then we can make things a bit more straightforward
6029 by converting the assignment to memcpy or memset. */
6030 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
6032 tree from = TREE_OPERAND (*from_p, 0);
6033 tree size = TREE_OPERAND (*from_p, 1);
6035 if (TREE_CODE (from) == CONSTRUCTOR)
6036 return gimplify_modify_expr_to_memset (expr_p, size, want_value, pre_p);
6038 if (is_gimple_addressable (from))
6040 *from_p = from;
6041 return gimplify_modify_expr_to_memcpy (expr_p, size, want_value,
6042 pre_p);
6046 /* Transform partial stores to non-addressable complex variables into
6047 total stores. This allows us to use real instead of virtual operands
6048 for these variables, which improves optimization. */
6049 if ((TREE_CODE (*to_p) == REALPART_EXPR
6050 || TREE_CODE (*to_p) == IMAGPART_EXPR)
6051 && is_gimple_reg (TREE_OPERAND (*to_p, 0)))
6052 return gimplify_modify_expr_complex_part (expr_p, pre_p, want_value);
6054 /* Try to alleviate the effects of the gimplification creating artificial
6055 temporaries (see for example is_gimple_reg_rhs) on the debug info, but
6056 make sure not to create DECL_DEBUG_EXPR links across functions. */
6057 if (!gimplify_ctxp->into_ssa
6058 && VAR_P (*from_p)
6059 && DECL_IGNORED_P (*from_p)
6060 && DECL_P (*to_p)
6061 && !DECL_IGNORED_P (*to_p)
6062 && decl_function_context (*to_p) == current_function_decl
6063 && decl_function_context (*from_p) == current_function_decl)
6065 if (!DECL_NAME (*from_p) && DECL_NAME (*to_p))
6066 DECL_NAME (*from_p)
6067 = create_tmp_var_name (IDENTIFIER_POINTER (DECL_NAME (*to_p)));
6068 DECL_HAS_DEBUG_EXPR_P (*from_p) = 1;
6069 SET_DECL_DEBUG_EXPR (*from_p, *to_p);
6072 if (want_value && TREE_THIS_VOLATILE (*to_p))
6073 *from_p = get_initialized_tmp_var (*from_p, pre_p, post_p);
6075 if (TREE_CODE (*from_p) == CALL_EXPR)
6077 /* Since the RHS is a CALL_EXPR, we need to create a GIMPLE_CALL
6078 instead of a GIMPLE_ASSIGN. */
6079 gcall *call_stmt;
6080 if (CALL_EXPR_FN (*from_p) == NULL_TREE)
6082 /* Gimplify internal functions created in the FEs. */
6083 int nargs = call_expr_nargs (*from_p), i;
6084 enum internal_fn ifn = CALL_EXPR_IFN (*from_p);
6085 auto_vec<tree> vargs (nargs);
6087 for (i = 0; i < nargs; i++)
6089 gimplify_arg (&CALL_EXPR_ARG (*from_p, i), pre_p,
6090 EXPR_LOCATION (*from_p));
6091 vargs.quick_push (CALL_EXPR_ARG (*from_p, i));
6093 call_stmt = gimple_build_call_internal_vec (ifn, vargs);
6094 gimple_call_set_nothrow (call_stmt, TREE_NOTHROW (*from_p));
6095 gimple_set_location (call_stmt, EXPR_LOCATION (*expr_p));
6097 else
6099 tree fnptrtype = TREE_TYPE (CALL_EXPR_FN (*from_p));
6100 CALL_EXPR_FN (*from_p) = TREE_OPERAND (CALL_EXPR_FN (*from_p), 0);
6101 STRIP_USELESS_TYPE_CONVERSION (CALL_EXPR_FN (*from_p));
6102 tree fndecl = get_callee_fndecl (*from_p);
6103 if (fndecl
6104 && fndecl_built_in_p (fndecl, BUILT_IN_EXPECT)
6105 && call_expr_nargs (*from_p) == 3)
6106 call_stmt = gimple_build_call_internal (IFN_BUILTIN_EXPECT, 3,
6107 CALL_EXPR_ARG (*from_p, 0),
6108 CALL_EXPR_ARG (*from_p, 1),
6109 CALL_EXPR_ARG (*from_p, 2));
6110 else
6112 call_stmt = gimple_build_call_from_tree (*from_p, fnptrtype);
6115 notice_special_calls (call_stmt);
6116 if (!gimple_call_noreturn_p (call_stmt) || !should_remove_lhs_p (*to_p))
6117 gimple_call_set_lhs (call_stmt, *to_p);
6118 else if (TREE_CODE (*to_p) == SSA_NAME)
6119 /* The above is somewhat premature, avoid ICEing later for a
6120 SSA name w/o a definition. We may have uses in the GIMPLE IL.
6121 ??? This doesn't make it a default-def. */
6122 SSA_NAME_DEF_STMT (*to_p) = gimple_build_nop ();
6124 assign = call_stmt;
6126 else
6128 assign = gimple_build_assign (*to_p, *from_p);
6129 gimple_set_location (assign, EXPR_LOCATION (*expr_p));
6130 if (COMPARISON_CLASS_P (*from_p))
6131 copy_warning (assign, *from_p);
6134 if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p))
6136 /* We should have got an SSA name from the start. */
6137 gcc_assert (TREE_CODE (*to_p) == SSA_NAME
6138 || ! gimple_in_ssa_p (cfun));
6141 gimplify_seq_add_stmt (pre_p, assign);
6142 gsi = gsi_last (*pre_p);
6143 maybe_fold_stmt (&gsi);
6145 if (want_value)
6147 *expr_p = TREE_THIS_VOLATILE (*to_p) ? *from_p : unshare_expr (*to_p);
6148 return GS_OK;
6150 else
6151 *expr_p = NULL;
6153 return GS_ALL_DONE;
6156 /* Gimplify a comparison between two variable-sized objects. Do this
6157 with a call to BUILT_IN_MEMCMP. */
6159 static enum gimplify_status
6160 gimplify_variable_sized_compare (tree *expr_p)
6162 location_t loc = EXPR_LOCATION (*expr_p);
6163 tree op0 = TREE_OPERAND (*expr_p, 0);
6164 tree op1 = TREE_OPERAND (*expr_p, 1);
6165 tree t, arg, dest, src, expr;
6167 arg = TYPE_SIZE_UNIT (TREE_TYPE (op0));
6168 arg = unshare_expr (arg);
6169 arg = SUBSTITUTE_PLACEHOLDER_IN_EXPR (arg, op0);
6170 src = build_fold_addr_expr_loc (loc, op1);
6171 dest = build_fold_addr_expr_loc (loc, op0);
6172 t = builtin_decl_implicit (BUILT_IN_MEMCMP);
6173 t = build_call_expr_loc (loc, t, 3, dest, src, arg);
6175 expr
6176 = build2 (TREE_CODE (*expr_p), TREE_TYPE (*expr_p), t, integer_zero_node);
6177 SET_EXPR_LOCATION (expr, loc);
6178 *expr_p = expr;
6180 return GS_OK;
6183 /* Gimplify a comparison between two aggregate objects of integral scalar
6184 mode as a comparison between the bitwise equivalent scalar values. */
6186 static enum gimplify_status
6187 gimplify_scalar_mode_aggregate_compare (tree *expr_p)
6189 location_t loc = EXPR_LOCATION (*expr_p);
6190 tree op0 = TREE_OPERAND (*expr_p, 0);
6191 tree op1 = TREE_OPERAND (*expr_p, 1);
6193 tree type = TREE_TYPE (op0);
6194 tree scalar_type = lang_hooks.types.type_for_mode (TYPE_MODE (type), 1);
6196 op0 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op0);
6197 op1 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op1);
6199 *expr_p
6200 = fold_build2_loc (loc, TREE_CODE (*expr_p), TREE_TYPE (*expr_p), op0, op1);
6202 return GS_OK;
6205 /* Gimplify an expression sequence. This function gimplifies each
6206 expression and rewrites the original expression with the last
6207 expression of the sequence in GIMPLE form.
6209 PRE_P points to the list where the side effects for all the
6210 expressions in the sequence will be emitted.
6212 WANT_VALUE is true when the result of the last COMPOUND_EXPR is used. */
6214 static enum gimplify_status
6215 gimplify_compound_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
6217 tree t = *expr_p;
6221 tree *sub_p = &TREE_OPERAND (t, 0);
6223 if (TREE_CODE (*sub_p) == COMPOUND_EXPR)
6224 gimplify_compound_expr (sub_p, pre_p, false);
6225 else
6226 gimplify_stmt (sub_p, pre_p);
6228 t = TREE_OPERAND (t, 1);
6230 while (TREE_CODE (t) == COMPOUND_EXPR);
6232 *expr_p = t;
6233 if (want_value)
6234 return GS_OK;
6235 else
6237 gimplify_stmt (expr_p, pre_p);
6238 return GS_ALL_DONE;
6242 /* Gimplify a SAVE_EXPR node. EXPR_P points to the expression to
6243 gimplify. After gimplification, EXPR_P will point to a new temporary
6244 that holds the original value of the SAVE_EXPR node.
6246 PRE_P points to the list where side effects that must happen before
6247 *EXPR_P should be stored. */
6249 static enum gimplify_status
6250 gimplify_save_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6252 enum gimplify_status ret = GS_ALL_DONE;
6253 tree val;
6255 gcc_assert (TREE_CODE (*expr_p) == SAVE_EXPR);
6256 val = TREE_OPERAND (*expr_p, 0);
6258 if (TREE_TYPE (val) == error_mark_node)
6259 return GS_ERROR;
6261 /* If the SAVE_EXPR has not been resolved, then evaluate it once. */
6262 if (!SAVE_EXPR_RESOLVED_P (*expr_p))
6264 /* The operand may be a void-valued expression. It is
6265 being executed only for its side-effects. */
6266 if (TREE_TYPE (val) == void_type_node)
6268 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
6269 is_gimple_stmt, fb_none);
6270 val = NULL;
6272 else
6273 /* The temporary may not be an SSA name as later abnormal and EH
6274 control flow may invalidate use/def domination. When in SSA
6275 form then assume there are no such issues and SAVE_EXPRs only
6276 appear via GENERIC foldings. */
6277 val = get_initialized_tmp_var (val, pre_p, post_p,
6278 gimple_in_ssa_p (cfun));
6280 TREE_OPERAND (*expr_p, 0) = val;
6281 SAVE_EXPR_RESOLVED_P (*expr_p) = 1;
6284 *expr_p = val;
6286 return ret;
6289 /* Rewrite the ADDR_EXPR node pointed to by EXPR_P
6291 unary_expr
6292 : ...
6293 | '&' varname
6296 PRE_P points to the list where side effects that must happen before
6297 *EXPR_P should be stored.
6299 POST_P points to the list where side effects that must happen after
6300 *EXPR_P should be stored. */
6302 static enum gimplify_status
6303 gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6305 tree expr = *expr_p;
6306 tree op0 = TREE_OPERAND (expr, 0);
6307 enum gimplify_status ret;
6308 location_t loc = EXPR_LOCATION (*expr_p);
6310 switch (TREE_CODE (op0))
6312 case INDIRECT_REF:
6313 do_indirect_ref:
6314 /* Check if we are dealing with an expression of the form '&*ptr'.
6315 While the front end folds away '&*ptr' into 'ptr', these
6316 expressions may be generated internally by the compiler (e.g.,
6317 builtins like __builtin_va_end). */
6318 /* Caution: the silent array decomposition semantics we allow for
6319 ADDR_EXPR means we can't always discard the pair. */
6320 /* Gimplification of the ADDR_EXPR operand may drop
6321 cv-qualification conversions, so make sure we add them if
6322 needed. */
6324 tree op00 = TREE_OPERAND (op0, 0);
6325 tree t_expr = TREE_TYPE (expr);
6326 tree t_op00 = TREE_TYPE (op00);
6328 if (!useless_type_conversion_p (t_expr, t_op00))
6329 op00 = fold_convert_loc (loc, TREE_TYPE (expr), op00);
6330 *expr_p = op00;
6331 ret = GS_OK;
6333 break;
6335 case VIEW_CONVERT_EXPR:
6336 /* Take the address of our operand and then convert it to the type of
6337 this ADDR_EXPR.
6339 ??? The interactions of VIEW_CONVERT_EXPR and aliasing is not at
6340 all clear. The impact of this transformation is even less clear. */
6342 /* If the operand is a useless conversion, look through it. Doing so
6343 guarantees that the ADDR_EXPR and its operand will remain of the
6344 same type. */
6345 if (tree_ssa_useless_type_conversion (TREE_OPERAND (op0, 0)))
6346 op0 = TREE_OPERAND (op0, 0);
6348 *expr_p = fold_convert_loc (loc, TREE_TYPE (expr),
6349 build_fold_addr_expr_loc (loc,
6350 TREE_OPERAND (op0, 0)));
6351 ret = GS_OK;
6352 break;
6354 case MEM_REF:
6355 if (integer_zerop (TREE_OPERAND (op0, 1)))
6356 goto do_indirect_ref;
6358 /* fall through */
6360 default:
6361 /* If we see a call to a declared builtin or see its address
6362 being taken (we can unify those cases here) then we can mark
6363 the builtin for implicit generation by GCC. */
6364 if (TREE_CODE (op0) == FUNCTION_DECL
6365 && fndecl_built_in_p (op0, BUILT_IN_NORMAL)
6366 && builtin_decl_declared_p (DECL_FUNCTION_CODE (op0)))
6367 set_builtin_decl_implicit_p (DECL_FUNCTION_CODE (op0), true);
6369 /* We use fb_either here because the C frontend sometimes takes
6370 the address of a call that returns a struct; see
6371 gcc.dg/c99-array-lval-1.c. The gimplifier will correctly make
6372 the implied temporary explicit. */
6374 /* Make the operand addressable. */
6375 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, post_p,
6376 is_gimple_addressable, fb_either);
6377 if (ret == GS_ERROR)
6378 break;
6380 /* Then mark it. Beware that it may not be possible to do so directly
6381 if a temporary has been created by the gimplification. */
6382 prepare_gimple_addressable (&TREE_OPERAND (expr, 0), pre_p);
6384 op0 = TREE_OPERAND (expr, 0);
6386 /* For various reasons, the gimplification of the expression
6387 may have made a new INDIRECT_REF. */
6388 if (TREE_CODE (op0) == INDIRECT_REF
6389 || (TREE_CODE (op0) == MEM_REF
6390 && integer_zerop (TREE_OPERAND (op0, 1))))
6391 goto do_indirect_ref;
6393 mark_addressable (TREE_OPERAND (expr, 0));
6395 /* The FEs may end up building ADDR_EXPRs early on a decl with
6396 an incomplete type. Re-build ADDR_EXPRs in canonical form
6397 here. */
6398 if (!types_compatible_p (TREE_TYPE (op0), TREE_TYPE (TREE_TYPE (expr))))
6399 *expr_p = build_fold_addr_expr (op0);
6401 /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly. */
6402 recompute_tree_invariant_for_addr_expr (*expr_p);
6404 /* If we re-built the ADDR_EXPR add a conversion to the original type
6405 if required. */
6406 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
6407 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
6409 break;
6412 return ret;
6415 /* Gimplify the operands of an ASM_EXPR. Input operands should be a gimple
6416 value; output operands should be a gimple lvalue. */
6418 static enum gimplify_status
6419 gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6421 tree expr;
6422 int noutputs;
6423 const char **oconstraints;
6424 int i;
6425 tree link;
6426 const char *constraint;
6427 bool allows_mem, allows_reg, is_inout;
6428 enum gimplify_status ret, tret;
6429 gasm *stmt;
6430 vec<tree, va_gc> *inputs;
6431 vec<tree, va_gc> *outputs;
6432 vec<tree, va_gc> *clobbers;
6433 vec<tree, va_gc> *labels;
6434 tree link_next;
6436 expr = *expr_p;
6437 noutputs = list_length (ASM_OUTPUTS (expr));
6438 oconstraints = (const char **) alloca ((noutputs) * sizeof (const char *));
6440 inputs = NULL;
6441 outputs = NULL;
6442 clobbers = NULL;
6443 labels = NULL;
6445 ret = GS_ALL_DONE;
6446 link_next = NULL_TREE;
6447 for (i = 0, link = ASM_OUTPUTS (expr); link; ++i, link = link_next)
6449 bool ok;
6450 size_t constraint_len;
6452 link_next = TREE_CHAIN (link);
6454 oconstraints[i]
6455 = constraint
6456 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
6457 constraint_len = strlen (constraint);
6458 if (constraint_len == 0)
6459 continue;
6461 ok = parse_output_constraint (&constraint, i, 0, 0,
6462 &allows_mem, &allows_reg, &is_inout);
6463 if (!ok)
6465 ret = GS_ERROR;
6466 is_inout = false;
6469 /* If we can't make copies, we can only accept memory.
6470 Similarly for VLAs. */
6471 tree outtype = TREE_TYPE (TREE_VALUE (link));
6472 if (outtype != error_mark_node
6473 && (TREE_ADDRESSABLE (outtype)
6474 || !COMPLETE_TYPE_P (outtype)
6475 || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (outtype))))
6477 if (allows_mem)
6478 allows_reg = 0;
6479 else
6481 error ("impossible constraint in %<asm%>");
6482 error ("non-memory output %d must stay in memory", i);
6483 return GS_ERROR;
6487 if (!allows_reg && allows_mem)
6488 mark_addressable (TREE_VALUE (link));
6490 tree orig = TREE_VALUE (link);
6491 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6492 is_inout ? is_gimple_min_lval : is_gimple_lvalue,
6493 fb_lvalue | fb_mayfail);
6494 if (tret == GS_ERROR)
6496 if (orig != error_mark_node)
6497 error ("invalid lvalue in %<asm%> output %d", i);
6498 ret = tret;
6501 /* If the constraint does not allow memory make sure we gimplify
6502 it to a register if it is not already but its base is. This
6503 happens for complex and vector components. */
6504 if (!allows_mem)
6506 tree op = TREE_VALUE (link);
6507 if (! is_gimple_val (op)
6508 && is_gimple_reg_type (TREE_TYPE (op))
6509 && is_gimple_reg (get_base_address (op)))
6511 tree tem = create_tmp_reg (TREE_TYPE (op));
6512 tree ass;
6513 if (is_inout)
6515 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem),
6516 tem, unshare_expr (op));
6517 gimplify_and_add (ass, pre_p);
6519 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem), op, tem);
6520 gimplify_and_add (ass, post_p);
6522 TREE_VALUE (link) = tem;
6523 tret = GS_OK;
6527 vec_safe_push (outputs, link);
6528 TREE_CHAIN (link) = NULL_TREE;
6530 if (is_inout)
6532 /* An input/output operand. To give the optimizers more
6533 flexibility, split it into separate input and output
6534 operands. */
6535 tree input;
6536 /* Buffer big enough to format a 32-bit UINT_MAX into. */
6537 char buf[11];
6539 /* Turn the in/out constraint into an output constraint. */
6540 char *p = xstrdup (constraint);
6541 p[0] = '=';
6542 TREE_VALUE (TREE_PURPOSE (link)) = build_string (constraint_len, p);
6544 /* And add a matching input constraint. */
6545 if (allows_reg)
6547 sprintf (buf, "%u", i);
6549 /* If there are multiple alternatives in the constraint,
6550 handle each of them individually. Those that allow register
6551 will be replaced with operand number, the others will stay
6552 unchanged. */
6553 if (strchr (p, ',') != NULL)
6555 size_t len = 0, buflen = strlen (buf);
6556 char *beg, *end, *str, *dst;
6558 for (beg = p + 1;;)
6560 end = strchr (beg, ',');
6561 if (end == NULL)
6562 end = strchr (beg, '\0');
6563 if ((size_t) (end - beg) < buflen)
6564 len += buflen + 1;
6565 else
6566 len += end - beg + 1;
6567 if (*end)
6568 beg = end + 1;
6569 else
6570 break;
6573 str = (char *) alloca (len);
6574 for (beg = p + 1, dst = str;;)
6576 const char *tem;
6577 bool mem_p, reg_p, inout_p;
6579 end = strchr (beg, ',');
6580 if (end)
6581 *end = '\0';
6582 beg[-1] = '=';
6583 tem = beg - 1;
6584 parse_output_constraint (&tem, i, 0, 0,
6585 &mem_p, &reg_p, &inout_p);
6586 if (dst != str)
6587 *dst++ = ',';
6588 if (reg_p)
6590 memcpy (dst, buf, buflen);
6591 dst += buflen;
6593 else
6595 if (end)
6596 len = end - beg;
6597 else
6598 len = strlen (beg);
6599 memcpy (dst, beg, len);
6600 dst += len;
6602 if (end)
6603 beg = end + 1;
6604 else
6605 break;
6607 *dst = '\0';
6608 input = build_string (dst - str, str);
6610 else
6611 input = build_string (strlen (buf), buf);
6613 else
6614 input = build_string (constraint_len - 1, constraint + 1);
6616 free (p);
6618 input = build_tree_list (build_tree_list (NULL_TREE, input),
6619 unshare_expr (TREE_VALUE (link)));
6620 ASM_INPUTS (expr) = chainon (ASM_INPUTS (expr), input);
6624 link_next = NULL_TREE;
6625 for (link = ASM_INPUTS (expr); link; ++i, link = link_next)
6627 link_next = TREE_CHAIN (link);
6628 constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
6629 parse_input_constraint (&constraint, 0, 0, noutputs, 0,
6630 oconstraints, &allows_mem, &allows_reg);
6632 /* If we can't make copies, we can only accept memory. */
6633 tree intype = TREE_TYPE (TREE_VALUE (link));
6634 if (intype != error_mark_node
6635 && (TREE_ADDRESSABLE (intype)
6636 || !COMPLETE_TYPE_P (intype)
6637 || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (intype))))
6639 if (allows_mem)
6640 allows_reg = 0;
6641 else
6643 error ("impossible constraint in %<asm%>");
6644 error ("non-memory input %d must stay in memory", i);
6645 return GS_ERROR;
6649 /* If the operand is a memory input, it should be an lvalue. */
6650 if (!allows_reg && allows_mem)
6652 tree inputv = TREE_VALUE (link);
6653 STRIP_NOPS (inputv);
6654 if (TREE_CODE (inputv) == PREDECREMENT_EXPR
6655 || TREE_CODE (inputv) == PREINCREMENT_EXPR
6656 || TREE_CODE (inputv) == POSTDECREMENT_EXPR
6657 || TREE_CODE (inputv) == POSTINCREMENT_EXPR
6658 || TREE_CODE (inputv) == MODIFY_EXPR)
6659 TREE_VALUE (link) = error_mark_node;
6660 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6661 is_gimple_lvalue, fb_lvalue | fb_mayfail);
6662 if (tret != GS_ERROR)
6664 /* Unlike output operands, memory inputs are not guaranteed
6665 to be lvalues by the FE, and while the expressions are
6666 marked addressable there, if it is e.g. a statement
6667 expression, temporaries in it might not end up being
6668 addressable. They might be already used in the IL and thus
6669 it is too late to make them addressable now though. */
6670 tree x = TREE_VALUE (link);
6671 while (handled_component_p (x))
6672 x = TREE_OPERAND (x, 0);
6673 if (TREE_CODE (x) == MEM_REF
6674 && TREE_CODE (TREE_OPERAND (x, 0)) == ADDR_EXPR)
6675 x = TREE_OPERAND (TREE_OPERAND (x, 0), 0);
6676 if ((VAR_P (x)
6677 || TREE_CODE (x) == PARM_DECL
6678 || TREE_CODE (x) == RESULT_DECL)
6679 && !TREE_ADDRESSABLE (x)
6680 && is_gimple_reg (x))
6682 warning_at (EXPR_LOC_OR_LOC (TREE_VALUE (link),
6683 input_location), 0,
6684 "memory input %d is not directly addressable",
6686 prepare_gimple_addressable (&TREE_VALUE (link), pre_p);
6689 mark_addressable (TREE_VALUE (link));
6690 if (tret == GS_ERROR)
6692 if (inputv != error_mark_node)
6693 error_at (EXPR_LOC_OR_LOC (TREE_VALUE (link), input_location),
6694 "memory input %d is not directly addressable", i);
6695 ret = tret;
6698 else
6700 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6701 is_gimple_asm_val, fb_rvalue);
6702 if (tret == GS_ERROR)
6703 ret = tret;
6706 TREE_CHAIN (link) = NULL_TREE;
6707 vec_safe_push (inputs, link);
6710 link_next = NULL_TREE;
6711 for (link = ASM_CLOBBERS (expr); link; ++i, link = link_next)
6713 link_next = TREE_CHAIN (link);
6714 TREE_CHAIN (link) = NULL_TREE;
6715 vec_safe_push (clobbers, link);
6718 link_next = NULL_TREE;
6719 for (link = ASM_LABELS (expr); link; ++i, link = link_next)
6721 link_next = TREE_CHAIN (link);
6722 TREE_CHAIN (link) = NULL_TREE;
6723 vec_safe_push (labels, link);
6726 /* Do not add ASMs with errors to the gimple IL stream. */
6727 if (ret != GS_ERROR)
6729 stmt = gimple_build_asm_vec (TREE_STRING_POINTER (ASM_STRING (expr)),
6730 inputs, outputs, clobbers, labels);
6732 gimple_asm_set_volatile (stmt, ASM_VOLATILE_P (expr) || noutputs == 0);
6733 gimple_asm_set_input (stmt, ASM_INPUT_P (expr));
6734 gimple_asm_set_inline (stmt, ASM_INLINE_P (expr));
6736 gimplify_seq_add_stmt (pre_p, stmt);
6739 return ret;
6742 /* Gimplify a CLEANUP_POINT_EXPR. Currently this works by adding
6743 GIMPLE_WITH_CLEANUP_EXPRs to the prequeue as we encounter cleanups while
6744 gimplifying the body, and converting them to TRY_FINALLY_EXPRs when we
6745 return to this function.
6747 FIXME should we complexify the prequeue handling instead? Or use flags
6748 for all the cleanups and let the optimizer tighten them up? The current
6749 code seems pretty fragile; it will break on a cleanup within any
6750 non-conditional nesting. But any such nesting would be broken, anyway;
6751 we can't write a TRY_FINALLY_EXPR that starts inside a nesting construct
6752 and continues out of it. We can do that at the RTL level, though, so
6753 having an optimizer to tighten up try/finally regions would be a Good
6754 Thing. */
6756 static enum gimplify_status
6757 gimplify_cleanup_point_expr (tree *expr_p, gimple_seq *pre_p)
6759 gimple_stmt_iterator iter;
6760 gimple_seq body_sequence = NULL;
6762 tree temp = voidify_wrapper_expr (*expr_p, NULL);
6764 /* We only care about the number of conditions between the innermost
6765 CLEANUP_POINT_EXPR and the cleanup. So save and reset the count and
6766 any cleanups collected outside the CLEANUP_POINT_EXPR. */
6767 int old_conds = gimplify_ctxp->conditions;
6768 gimple_seq old_cleanups = gimplify_ctxp->conditional_cleanups;
6769 bool old_in_cleanup_point_expr = gimplify_ctxp->in_cleanup_point_expr;
6770 gimplify_ctxp->conditions = 0;
6771 gimplify_ctxp->conditional_cleanups = NULL;
6772 gimplify_ctxp->in_cleanup_point_expr = true;
6774 gimplify_stmt (&TREE_OPERAND (*expr_p, 0), &body_sequence);
6776 gimplify_ctxp->conditions = old_conds;
6777 gimplify_ctxp->conditional_cleanups = old_cleanups;
6778 gimplify_ctxp->in_cleanup_point_expr = old_in_cleanup_point_expr;
6780 for (iter = gsi_start (body_sequence); !gsi_end_p (iter); )
6782 gimple *wce = gsi_stmt (iter);
6784 if (gimple_code (wce) == GIMPLE_WITH_CLEANUP_EXPR)
6786 if (gsi_one_before_end_p (iter))
6788 /* Note that gsi_insert_seq_before and gsi_remove do not
6789 scan operands, unlike some other sequence mutators. */
6790 if (!gimple_wce_cleanup_eh_only (wce))
6791 gsi_insert_seq_before_without_update (&iter,
6792 gimple_wce_cleanup (wce),
6793 GSI_SAME_STMT);
6794 gsi_remove (&iter, true);
6795 break;
6797 else
6799 gtry *gtry;
6800 gimple_seq seq;
6801 enum gimple_try_flags kind;
6803 if (gimple_wce_cleanup_eh_only (wce))
6804 kind = GIMPLE_TRY_CATCH;
6805 else
6806 kind = GIMPLE_TRY_FINALLY;
6807 seq = gsi_split_seq_after (iter);
6809 gtry = gimple_build_try (seq, gimple_wce_cleanup (wce), kind);
6810 /* Do not use gsi_replace here, as it may scan operands.
6811 We want to do a simple structural modification only. */
6812 gsi_set_stmt (&iter, gtry);
6813 iter = gsi_start (gtry->eval);
6816 else
6817 gsi_next (&iter);
6820 gimplify_seq_add_seq (pre_p, body_sequence);
6821 if (temp)
6823 *expr_p = temp;
6824 return GS_OK;
6826 else
6828 *expr_p = NULL;
6829 return GS_ALL_DONE;
6833 /* Insert a cleanup marker for gimplify_cleanup_point_expr. CLEANUP
6834 is the cleanup action required. EH_ONLY is true if the cleanup should
6835 only be executed if an exception is thrown, not on normal exit.
6836 If FORCE_UNCOND is true perform the cleanup unconditionally; this is
6837 only valid for clobbers. */
6839 static void
6840 gimple_push_cleanup (tree var, tree cleanup, bool eh_only, gimple_seq *pre_p,
6841 bool force_uncond = false)
6843 gimple *wce;
6844 gimple_seq cleanup_stmts = NULL;
6846 /* Errors can result in improperly nested cleanups. Which results in
6847 confusion when trying to resolve the GIMPLE_WITH_CLEANUP_EXPR. */
6848 if (seen_error ())
6849 return;
6851 if (gimple_conditional_context ())
6853 /* If we're in a conditional context, this is more complex. We only
6854 want to run the cleanup if we actually ran the initialization that
6855 necessitates it, but we want to run it after the end of the
6856 conditional context. So we wrap the try/finally around the
6857 condition and use a flag to determine whether or not to actually
6858 run the destructor. Thus
6860 test ? f(A()) : 0
6862 becomes (approximately)
6864 flag = 0;
6865 try {
6866 if (test) { A::A(temp); flag = 1; val = f(temp); }
6867 else { val = 0; }
6868 } finally {
6869 if (flag) A::~A(temp);
6873 if (force_uncond)
6875 gimplify_stmt (&cleanup, &cleanup_stmts);
6876 wce = gimple_build_wce (cleanup_stmts);
6877 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
6879 else
6881 tree flag = create_tmp_var (boolean_type_node, "cleanup");
6882 gassign *ffalse = gimple_build_assign (flag, boolean_false_node);
6883 gassign *ftrue = gimple_build_assign (flag, boolean_true_node);
6885 cleanup = build3 (COND_EXPR, void_type_node, flag, cleanup, NULL);
6886 gimplify_stmt (&cleanup, &cleanup_stmts);
6887 wce = gimple_build_wce (cleanup_stmts);
6888 gimple_wce_set_cleanup_eh_only (wce, eh_only);
6890 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, ffalse);
6891 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
6892 gimplify_seq_add_stmt (pre_p, ftrue);
6894 /* Because of this manipulation, and the EH edges that jump
6895 threading cannot redirect, the temporary (VAR) will appear
6896 to be used uninitialized. Don't warn. */
6897 suppress_warning (var, OPT_Wuninitialized);
6900 else
6902 gimplify_stmt (&cleanup, &cleanup_stmts);
6903 wce = gimple_build_wce (cleanup_stmts);
6904 gimple_wce_set_cleanup_eh_only (wce, eh_only);
6905 gimplify_seq_add_stmt (pre_p, wce);
6909 /* Gimplify a TARGET_EXPR which doesn't appear on the rhs of an INIT_EXPR. */
6911 static enum gimplify_status
6912 gimplify_target_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6914 tree targ = *expr_p;
6915 tree temp = TARGET_EXPR_SLOT (targ);
6916 tree init = TARGET_EXPR_INITIAL (targ);
6917 enum gimplify_status ret;
6919 bool unpoison_empty_seq = false;
6920 gimple_stmt_iterator unpoison_it;
6922 if (init)
6924 tree cleanup = NULL_TREE;
6926 /* TARGET_EXPR temps aren't part of the enclosing block, so add it
6927 to the temps list. Handle also variable length TARGET_EXPRs. */
6928 if (!poly_int_tree_p (DECL_SIZE (temp)))
6930 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (temp)))
6931 gimplify_type_sizes (TREE_TYPE (temp), pre_p);
6932 /* FIXME: this is correct only when the size of the type does
6933 not depend on expressions evaluated in init. */
6934 gimplify_vla_decl (temp, pre_p);
6936 else
6938 /* Save location where we need to place unpoisoning. It's possible
6939 that a variable will be converted to needs_to_live_in_memory. */
6940 unpoison_it = gsi_last (*pre_p);
6941 unpoison_empty_seq = gsi_end_p (unpoison_it);
6943 gimple_add_tmp_var (temp);
6946 /* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the
6947 expression is supposed to initialize the slot. */
6948 if (VOID_TYPE_P (TREE_TYPE (init)))
6949 ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
6950 else
6952 tree init_expr = build2 (INIT_EXPR, void_type_node, temp, init);
6953 init = init_expr;
6954 ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
6955 init = NULL;
6956 ggc_free (init_expr);
6958 if (ret == GS_ERROR)
6960 /* PR c++/28266 Make sure this is expanded only once. */
6961 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
6962 return GS_ERROR;
6964 if (init)
6965 gimplify_and_add (init, pre_p);
6967 /* If needed, push the cleanup for the temp. */
6968 if (TARGET_EXPR_CLEANUP (targ))
6970 if (CLEANUP_EH_ONLY (targ))
6971 gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ),
6972 CLEANUP_EH_ONLY (targ), pre_p);
6973 else
6974 cleanup = TARGET_EXPR_CLEANUP (targ);
6977 /* Add a clobber for the temporary going out of scope, like
6978 gimplify_bind_expr. */
6979 if (gimplify_ctxp->in_cleanup_point_expr
6980 && needs_to_live_in_memory (temp))
6982 if (flag_stack_reuse == SR_ALL)
6984 tree clobber = build_clobber (TREE_TYPE (temp), CLOBBER_EOL);
6985 clobber = build2 (MODIFY_EXPR, TREE_TYPE (temp), temp, clobber);
6986 gimple_push_cleanup (temp, clobber, false, pre_p, true);
6988 if (asan_poisoned_variables
6989 && DECL_ALIGN (temp) <= MAX_SUPPORTED_STACK_ALIGNMENT
6990 && !TREE_STATIC (temp)
6991 && dbg_cnt (asan_use_after_scope)
6992 && !gimplify_omp_ctxp)
6994 tree asan_cleanup = build_asan_poison_call_expr (temp);
6995 if (asan_cleanup)
6997 if (unpoison_empty_seq)
6998 unpoison_it = gsi_start (*pre_p);
7000 asan_poison_variable (temp, false, &unpoison_it,
7001 unpoison_empty_seq);
7002 gimple_push_cleanup (temp, asan_cleanup, false, pre_p);
7006 if (cleanup)
7007 gimple_push_cleanup (temp, cleanup, false, pre_p);
7009 /* Only expand this once. */
7010 TREE_OPERAND (targ, 3) = init;
7011 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
7013 else
7014 /* We should have expanded this before. */
7015 gcc_assert (DECL_SEEN_IN_BIND_EXPR_P (temp));
7017 *expr_p = temp;
7018 return GS_OK;
7021 /* Gimplification of expression trees. */
7023 /* Gimplify an expression which appears at statement context. The
7024 corresponding GIMPLE statements are added to *SEQ_P. If *SEQ_P is
7025 NULL, a new sequence is allocated.
7027 Return true if we actually added a statement to the queue. */
7029 bool
7030 gimplify_stmt (tree *stmt_p, gimple_seq *seq_p)
7032 gimple_seq_node last;
7034 last = gimple_seq_last (*seq_p);
7035 gimplify_expr (stmt_p, seq_p, NULL, is_gimple_stmt, fb_none);
7036 return last != gimple_seq_last (*seq_p);
7039 /* Add FIRSTPRIVATE entries for DECL in the OpenMP the surrounding parallels
7040 to CTX. If entries already exist, force them to be some flavor of private.
7041 If there is no enclosing parallel, do nothing. */
7043 void
7044 omp_firstprivatize_variable (struct gimplify_omp_ctx *ctx, tree decl)
7046 splay_tree_node n;
7048 if (decl == NULL || !DECL_P (decl) || ctx->region_type == ORT_NONE)
7049 return;
7053 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7054 if (n != NULL)
7056 if (n->value & GOVD_SHARED)
7057 n->value = GOVD_FIRSTPRIVATE | (n->value & GOVD_SEEN);
7058 else if (n->value & GOVD_MAP)
7059 n->value |= GOVD_MAP_TO_ONLY;
7060 else
7061 return;
7063 else if ((ctx->region_type & ORT_TARGET) != 0)
7065 if (ctx->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE)
7066 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
7067 else
7068 omp_add_variable (ctx, decl, GOVD_MAP | GOVD_MAP_TO_ONLY);
7070 else if (ctx->region_type != ORT_WORKSHARE
7071 && ctx->region_type != ORT_TASKGROUP
7072 && ctx->region_type != ORT_SIMD
7073 && ctx->region_type != ORT_ACC
7074 && !(ctx->region_type & ORT_TARGET_DATA))
7075 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
7077 ctx = ctx->outer_context;
7079 while (ctx);
7082 /* Similarly for each of the type sizes of TYPE. */
7084 static void
7085 omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type)
7087 if (type == NULL || type == error_mark_node)
7088 return;
7089 type = TYPE_MAIN_VARIANT (type);
7091 if (ctx->privatized_types->add (type))
7092 return;
7094 switch (TREE_CODE (type))
7096 case INTEGER_TYPE:
7097 case ENUMERAL_TYPE:
7098 case BOOLEAN_TYPE:
7099 case REAL_TYPE:
7100 case FIXED_POINT_TYPE:
7101 omp_firstprivatize_variable (ctx, TYPE_MIN_VALUE (type));
7102 omp_firstprivatize_variable (ctx, TYPE_MAX_VALUE (type));
7103 break;
7105 case ARRAY_TYPE:
7106 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
7107 omp_firstprivatize_type_sizes (ctx, TYPE_DOMAIN (type));
7108 break;
7110 case RECORD_TYPE:
7111 case UNION_TYPE:
7112 case QUAL_UNION_TYPE:
7114 tree field;
7115 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
7116 if (TREE_CODE (field) == FIELD_DECL)
7118 omp_firstprivatize_variable (ctx, DECL_FIELD_OFFSET (field));
7119 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (field));
7122 break;
7124 case POINTER_TYPE:
7125 case REFERENCE_TYPE:
7126 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
7127 break;
7129 default:
7130 break;
7133 omp_firstprivatize_variable (ctx, TYPE_SIZE (type));
7134 omp_firstprivatize_variable (ctx, TYPE_SIZE_UNIT (type));
7135 lang_hooks.types.omp_firstprivatize_type_sizes (ctx, type);
7138 /* Add an entry for DECL in the OMP context CTX with FLAGS. */
7140 static void
7141 omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
7143 splay_tree_node n;
7144 unsigned int nflags;
7145 tree t;
7147 if (error_operand_p (decl) || ctx->region_type == ORT_NONE)
7148 return;
7150 /* Never elide decls whose type has TREE_ADDRESSABLE set. This means
7151 there are constructors involved somewhere. Exception is a shared clause,
7152 there is nothing privatized in that case. */
7153 if ((flags & GOVD_SHARED) == 0
7154 && (TREE_ADDRESSABLE (TREE_TYPE (decl))
7155 || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))))
7156 flags |= GOVD_SEEN;
7158 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7159 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
7161 /* We shouldn't be re-adding the decl with the same data
7162 sharing class. */
7163 gcc_assert ((n->value & GOVD_DATA_SHARE_CLASS & flags) == 0);
7164 nflags = n->value | flags;
7165 /* The only combination of data sharing classes we should see is
7166 FIRSTPRIVATE and LASTPRIVATE. However, OpenACC permits
7167 reduction variables to be used in data sharing clauses. */
7168 gcc_assert ((ctx->region_type & ORT_ACC) != 0
7169 || ((nflags & GOVD_DATA_SHARE_CLASS)
7170 == (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE))
7171 || (flags & GOVD_DATA_SHARE_CLASS) == 0);
7172 n->value = nflags;
7173 return;
7176 /* When adding a variable-sized variable, we have to handle all sorts
7177 of additional bits of data: the pointer replacement variable, and
7178 the parameters of the type. */
7179 if (DECL_SIZE (decl) && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
7181 /* Add the pointer replacement variable as PRIVATE if the variable
7182 replacement is private, else FIRSTPRIVATE since we'll need the
7183 address of the original variable either for SHARED, or for the
7184 copy into or out of the context. */
7185 if (!(flags & GOVD_LOCAL) && ctx->region_type != ORT_TASKGROUP)
7187 if (flags & GOVD_MAP)
7188 nflags = GOVD_MAP | GOVD_MAP_TO_ONLY | GOVD_EXPLICIT;
7189 else if (flags & GOVD_PRIVATE)
7190 nflags = GOVD_PRIVATE;
7191 else if (((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
7192 && (flags & GOVD_FIRSTPRIVATE))
7193 || (ctx->region_type == ORT_TARGET_DATA
7194 && (flags & GOVD_DATA_SHARE_CLASS) == 0))
7195 nflags = GOVD_PRIVATE | GOVD_EXPLICIT;
7196 else
7197 nflags = GOVD_FIRSTPRIVATE;
7198 nflags |= flags & GOVD_SEEN;
7199 t = DECL_VALUE_EXPR (decl);
7200 gcc_assert (TREE_CODE (t) == INDIRECT_REF);
7201 t = TREE_OPERAND (t, 0);
7202 gcc_assert (DECL_P (t));
7203 omp_add_variable (ctx, t, nflags);
7206 /* Add all of the variable and type parameters (which should have
7207 been gimplified to a formal temporary) as FIRSTPRIVATE. */
7208 omp_firstprivatize_variable (ctx, DECL_SIZE_UNIT (decl));
7209 omp_firstprivatize_variable (ctx, DECL_SIZE (decl));
7210 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
7212 /* The variable-sized variable itself is never SHARED, only some form
7213 of PRIVATE. The sharing would take place via the pointer variable
7214 which we remapped above. */
7215 if (flags & GOVD_SHARED)
7216 flags = GOVD_SHARED | GOVD_DEBUG_PRIVATE
7217 | (flags & (GOVD_SEEN | GOVD_EXPLICIT));
7219 /* We're going to make use of the TYPE_SIZE_UNIT at least in the
7220 alloca statement we generate for the variable, so make sure it
7221 is available. This isn't automatically needed for the SHARED
7222 case, since we won't be allocating local storage then.
7223 For local variables TYPE_SIZE_UNIT might not be gimplified yet,
7224 in this case omp_notice_variable will be called later
7225 on when it is gimplified. */
7226 else if (! (flags & (GOVD_LOCAL | GOVD_MAP))
7227 && DECL_P (TYPE_SIZE_UNIT (TREE_TYPE (decl))))
7228 omp_notice_variable (ctx, TYPE_SIZE_UNIT (TREE_TYPE (decl)), true);
7230 else if ((flags & (GOVD_MAP | GOVD_LOCAL)) == 0
7231 && omp_privatize_by_reference (decl))
7233 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
7235 /* Similar to the direct variable sized case above, we'll need the
7236 size of references being privatized. */
7237 if ((flags & GOVD_SHARED) == 0)
7239 t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
7240 if (t && DECL_P (t))
7241 omp_notice_variable (ctx, t, true);
7245 if (n != NULL)
7246 n->value |= flags;
7247 else
7248 splay_tree_insert (ctx->variables, (splay_tree_key)decl, flags);
7250 /* For reductions clauses in OpenACC loop directives, by default create a
7251 copy clause on the enclosing parallel construct for carrying back the
7252 results. */
7253 if (ctx->region_type == ORT_ACC && (flags & GOVD_REDUCTION))
7255 struct gimplify_omp_ctx *outer_ctx = ctx->outer_context;
7256 while (outer_ctx)
7258 n = splay_tree_lookup (outer_ctx->variables, (splay_tree_key)decl);
7259 if (n != NULL)
7261 /* Ignore local variables and explicitly declared clauses. */
7262 if (n->value & (GOVD_LOCAL | GOVD_EXPLICIT))
7263 break;
7264 else if (outer_ctx->region_type == ORT_ACC_KERNELS)
7266 /* According to the OpenACC spec, such a reduction variable
7267 should already have a copy map on a kernels construct,
7268 verify that here. */
7269 gcc_assert (!(n->value & GOVD_FIRSTPRIVATE)
7270 && (n->value & GOVD_MAP));
7272 else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
7274 /* Remove firstprivate and make it a copy map. */
7275 n->value &= ~GOVD_FIRSTPRIVATE;
7276 n->value |= GOVD_MAP;
7279 else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
7281 splay_tree_insert (outer_ctx->variables, (splay_tree_key)decl,
7282 GOVD_MAP | GOVD_SEEN);
7283 break;
7285 outer_ctx = outer_ctx->outer_context;
7290 /* Notice a threadprivate variable DECL used in OMP context CTX.
7291 This just prints out diagnostics about threadprivate variable uses
7292 in untied tasks. If DECL2 is non-NULL, prevent this warning
7293 on that variable. */
7295 static bool
7296 omp_notice_threadprivate_variable (struct gimplify_omp_ctx *ctx, tree decl,
7297 tree decl2)
7299 splay_tree_node n;
7300 struct gimplify_omp_ctx *octx;
7302 for (octx = ctx; octx; octx = octx->outer_context)
7303 if ((octx->region_type & ORT_TARGET) != 0
7304 || octx->order_concurrent)
7306 n = splay_tree_lookup (octx->variables, (splay_tree_key)decl);
7307 if (n == NULL)
7309 if (octx->order_concurrent)
7311 error ("threadprivate variable %qE used in a region with"
7312 " %<order(concurrent)%> clause", DECL_NAME (decl));
7313 inform (octx->location, "enclosing region");
7315 else
7317 error ("threadprivate variable %qE used in target region",
7318 DECL_NAME (decl));
7319 inform (octx->location, "enclosing target region");
7321 splay_tree_insert (octx->variables, (splay_tree_key)decl, 0);
7323 if (decl2)
7324 splay_tree_insert (octx->variables, (splay_tree_key)decl2, 0);
7327 if (ctx->region_type != ORT_UNTIED_TASK)
7328 return false;
7329 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7330 if (n == NULL)
7332 error ("threadprivate variable %qE used in untied task",
7333 DECL_NAME (decl));
7334 inform (ctx->location, "enclosing task");
7335 splay_tree_insert (ctx->variables, (splay_tree_key)decl, 0);
7337 if (decl2)
7338 splay_tree_insert (ctx->variables, (splay_tree_key)decl2, 0);
7339 return false;
7342 /* Return true if global var DECL is device resident. */
7344 static bool
7345 device_resident_p (tree decl)
7347 tree attr = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (decl));
7349 if (!attr)
7350 return false;
7352 for (tree t = TREE_VALUE (attr); t; t = TREE_PURPOSE (t))
7354 tree c = TREE_VALUE (t);
7355 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DEVICE_RESIDENT)
7356 return true;
7359 return false;
7362 /* Return true if DECL has an ACC DECLARE attribute. */
7364 static bool
7365 is_oacc_declared (tree decl)
7367 tree t = TREE_CODE (decl) == MEM_REF ? TREE_OPERAND (decl, 0) : decl;
7368 tree declared = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (t));
7369 return declared != NULL_TREE;
7372 /* Determine outer default flags for DECL mentioned in an OMP region
7373 but not declared in an enclosing clause.
7375 ??? Some compiler-generated variables (like SAVE_EXPRs) could be
7376 remapped firstprivate instead of shared. To some extent this is
7377 addressed in omp_firstprivatize_type_sizes, but not
7378 effectively. */
7380 static unsigned
7381 omp_default_clause (struct gimplify_omp_ctx *ctx, tree decl,
7382 bool in_code, unsigned flags)
7384 enum omp_clause_default_kind default_kind = ctx->default_kind;
7385 enum omp_clause_default_kind kind;
7387 kind = lang_hooks.decls.omp_predetermined_sharing (decl);
7388 if (ctx->region_type & ORT_TASK)
7390 tree detach_clause = omp_find_clause (ctx->clauses, OMP_CLAUSE_DETACH);
7392 /* The event-handle specified by a detach clause should always be firstprivate,
7393 regardless of the current default. */
7394 if (detach_clause && OMP_CLAUSE_DECL (detach_clause) == decl)
7395 kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
7397 if (kind != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
7398 default_kind = kind;
7399 else if (VAR_P (decl) && TREE_STATIC (decl) && DECL_IN_CONSTANT_POOL (decl))
7400 default_kind = OMP_CLAUSE_DEFAULT_SHARED;
7401 /* For C/C++ default({,first}private), variables with static storage duration
7402 declared in a namespace or global scope and referenced in construct
7403 must be explicitly specified, i.e. acts as default(none). */
7404 else if ((default_kind == OMP_CLAUSE_DEFAULT_PRIVATE
7405 || default_kind == OMP_CLAUSE_DEFAULT_FIRSTPRIVATE)
7406 && VAR_P (decl)
7407 && is_global_var (decl)
7408 && (DECL_FILE_SCOPE_P (decl)
7409 || (DECL_CONTEXT (decl)
7410 && TREE_CODE (DECL_CONTEXT (decl)) == NAMESPACE_DECL))
7411 && !lang_GNU_Fortran ())
7412 default_kind = OMP_CLAUSE_DEFAULT_NONE;
7414 switch (default_kind)
7416 case OMP_CLAUSE_DEFAULT_NONE:
7418 const char *rtype;
7420 if (ctx->region_type & ORT_PARALLEL)
7421 rtype = "parallel";
7422 else if ((ctx->region_type & ORT_TASKLOOP) == ORT_TASKLOOP)
7423 rtype = "taskloop";
7424 else if (ctx->region_type & ORT_TASK)
7425 rtype = "task";
7426 else if (ctx->region_type & ORT_TEAMS)
7427 rtype = "teams";
7428 else
7429 gcc_unreachable ();
7431 error ("%qE not specified in enclosing %qs",
7432 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rtype);
7433 inform (ctx->location, "enclosing %qs", rtype);
7435 /* FALLTHRU */
7436 case OMP_CLAUSE_DEFAULT_SHARED:
7437 flags |= GOVD_SHARED;
7438 break;
7439 case OMP_CLAUSE_DEFAULT_PRIVATE:
7440 flags |= GOVD_PRIVATE;
7441 break;
7442 case OMP_CLAUSE_DEFAULT_FIRSTPRIVATE:
7443 flags |= GOVD_FIRSTPRIVATE;
7444 break;
7445 case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
7446 /* decl will be either GOVD_FIRSTPRIVATE or GOVD_SHARED. */
7447 gcc_assert ((ctx->region_type & ORT_TASK) != 0);
7448 if (struct gimplify_omp_ctx *octx = ctx->outer_context)
7450 omp_notice_variable (octx, decl, in_code);
7451 for (; octx; octx = octx->outer_context)
7453 splay_tree_node n2;
7455 n2 = splay_tree_lookup (octx->variables, (splay_tree_key) decl);
7456 if ((octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)) != 0
7457 && (n2 == NULL || (n2->value & GOVD_DATA_SHARE_CLASS) == 0))
7458 continue;
7459 if (n2 && (n2->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED)
7461 flags |= GOVD_FIRSTPRIVATE;
7462 goto found_outer;
7464 if ((octx->region_type & (ORT_PARALLEL | ORT_TEAMS)) != 0)
7466 flags |= GOVD_SHARED;
7467 goto found_outer;
7472 if (TREE_CODE (decl) == PARM_DECL
7473 || (!is_global_var (decl)
7474 && DECL_CONTEXT (decl) == current_function_decl))
7475 flags |= GOVD_FIRSTPRIVATE;
7476 else
7477 flags |= GOVD_SHARED;
7478 found_outer:
7479 break;
7481 default:
7482 gcc_unreachable ();
7485 return flags;
7489 /* Determine outer default flags for DECL mentioned in an OACC region
7490 but not declared in an enclosing clause. */
7492 static unsigned
7493 oacc_default_clause (struct gimplify_omp_ctx *ctx, tree decl, unsigned flags)
7495 const char *rkind;
7496 bool on_device = false;
7497 bool is_private = false;
7498 bool declared = is_oacc_declared (decl);
7499 tree type = TREE_TYPE (decl);
7501 if (omp_privatize_by_reference (decl))
7502 type = TREE_TYPE (type);
7504 /* For Fortran COMMON blocks, only used variables in those blocks are
7505 transfered and remapped. The block itself will have a private clause to
7506 avoid transfering the data twice.
7507 The hook evaluates to false by default. For a variable in Fortran's COMMON
7508 or EQUIVALENCE block, returns 'true' (as we have shared=false) - as only
7509 the variables in such a COMMON/EQUIVALENCE block shall be privatized not
7510 the whole block. For C++ and Fortran, it can also be true under certain
7511 other conditions, if DECL_HAS_VALUE_EXPR. */
7512 if (RECORD_OR_UNION_TYPE_P (type))
7513 is_private = lang_hooks.decls.omp_disregard_value_expr (decl, false);
7515 if ((ctx->region_type & (ORT_ACC_PARALLEL | ORT_ACC_KERNELS)) != 0
7516 && is_global_var (decl)
7517 && device_resident_p (decl)
7518 && !is_private)
7520 on_device = true;
7521 flags |= GOVD_MAP_TO_ONLY;
7524 switch (ctx->region_type)
7526 case ORT_ACC_KERNELS:
7527 rkind = "kernels";
7529 if (is_private)
7530 flags |= GOVD_FIRSTPRIVATE;
7531 else if (AGGREGATE_TYPE_P (type))
7533 /* Aggregates default to 'present_or_copy', or 'present'. */
7534 if (ctx->default_kind != OMP_CLAUSE_DEFAULT_PRESENT)
7535 flags |= GOVD_MAP;
7536 else
7537 flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
7539 else
7540 /* Scalars default to 'copy'. */
7541 flags |= GOVD_MAP | GOVD_MAP_FORCE;
7543 break;
7545 case ORT_ACC_PARALLEL:
7546 case ORT_ACC_SERIAL:
7547 rkind = ctx->region_type == ORT_ACC_PARALLEL ? "parallel" : "serial";
7549 if (is_private)
7550 flags |= GOVD_FIRSTPRIVATE;
7551 else if (on_device || declared)
7552 flags |= GOVD_MAP;
7553 else if (AGGREGATE_TYPE_P (type))
7555 /* Aggregates default to 'present_or_copy', or 'present'. */
7556 if (ctx->default_kind != OMP_CLAUSE_DEFAULT_PRESENT)
7557 flags |= GOVD_MAP;
7558 else
7559 flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
7561 else
7562 /* Scalars default to 'firstprivate'. */
7563 flags |= GOVD_FIRSTPRIVATE;
7565 break;
7567 default:
7568 gcc_unreachable ();
7571 if (DECL_ARTIFICIAL (decl))
7572 ; /* We can get compiler-generated decls, and should not complain
7573 about them. */
7574 else if (ctx->default_kind == OMP_CLAUSE_DEFAULT_NONE)
7576 error ("%qE not specified in enclosing OpenACC %qs construct",
7577 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rkind);
7578 inform (ctx->location, "enclosing OpenACC %qs construct", rkind);
7580 else if (ctx->default_kind == OMP_CLAUSE_DEFAULT_PRESENT)
7581 ; /* Handled above. */
7582 else
7583 gcc_checking_assert (ctx->default_kind == OMP_CLAUSE_DEFAULT_SHARED);
7585 return flags;
7588 /* Record the fact that DECL was used within the OMP context CTX.
7589 IN_CODE is true when real code uses DECL, and false when we should
7590 merely emit default(none) errors. Return true if DECL is going to
7591 be remapped and thus DECL shouldn't be gimplified into its
7592 DECL_VALUE_EXPR (if any). */
7594 static bool
7595 omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
7597 splay_tree_node n;
7598 unsigned flags = in_code ? GOVD_SEEN : 0;
7599 bool ret = false, shared;
7601 if (error_operand_p (decl))
7602 return false;
7604 if (ctx->region_type == ORT_NONE)
7605 return lang_hooks.decls.omp_disregard_value_expr (decl, false);
7607 if (is_global_var (decl))
7609 /* Threadprivate variables are predetermined. */
7610 if (DECL_THREAD_LOCAL_P (decl))
7611 return omp_notice_threadprivate_variable (ctx, decl, NULL_TREE);
7613 if (DECL_HAS_VALUE_EXPR_P (decl))
7615 if (ctx->region_type & ORT_ACC)
7616 /* For OpenACC, defer expansion of value to avoid transfering
7617 privatized common block data instead of im-/explicitly transfered
7618 variables which are in common blocks. */
7620 else
7622 tree value = get_base_address (DECL_VALUE_EXPR (decl));
7624 if (value && DECL_P (value) && DECL_THREAD_LOCAL_P (value))
7625 return omp_notice_threadprivate_variable (ctx, decl, value);
7629 if (gimplify_omp_ctxp->outer_context == NULL
7630 && VAR_P (decl)
7631 && oacc_get_fn_attrib (current_function_decl))
7633 location_t loc = DECL_SOURCE_LOCATION (decl);
7635 if (lookup_attribute ("omp declare target link",
7636 DECL_ATTRIBUTES (decl)))
7638 error_at (loc,
7639 "%qE with %<link%> clause used in %<routine%> function",
7640 DECL_NAME (decl));
7641 return false;
7643 else if (!lookup_attribute ("omp declare target",
7644 DECL_ATTRIBUTES (decl)))
7646 error_at (loc,
7647 "%qE requires a %<declare%> directive for use "
7648 "in a %<routine%> function", DECL_NAME (decl));
7649 return false;
7654 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7655 if ((ctx->region_type & ORT_TARGET) != 0)
7657 if (ctx->region_type & ORT_ACC)
7658 /* For OpenACC, as remarked above, defer expansion. */
7659 shared = false;
7660 else
7661 shared = true;
7663 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7664 if (n == NULL)
7666 unsigned nflags = flags;
7667 if ((ctx->region_type & ORT_ACC) == 0)
7669 bool is_declare_target = false;
7670 if (is_global_var (decl)
7671 && varpool_node::get_create (decl)->offloadable)
7673 struct gimplify_omp_ctx *octx;
7674 for (octx = ctx->outer_context;
7675 octx; octx = octx->outer_context)
7677 n = splay_tree_lookup (octx->variables,
7678 (splay_tree_key)decl);
7679 if (n
7680 && (n->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED
7681 && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
7682 break;
7684 is_declare_target = octx == NULL;
7686 if (!is_declare_target)
7688 int gdmk;
7689 enum omp_clause_defaultmap_kind kind;
7690 if (lang_hooks.decls.omp_allocatable_p (decl))
7691 gdmk = GDMK_ALLOCATABLE;
7692 else if (lang_hooks.decls.omp_scalar_target_p (decl))
7693 gdmk = GDMK_SCALAR_TARGET;
7694 else if (lang_hooks.decls.omp_scalar_p (decl, false))
7695 gdmk = GDMK_SCALAR;
7696 else if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
7697 || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
7698 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
7699 == POINTER_TYPE)))
7700 gdmk = GDMK_POINTER;
7701 else
7702 gdmk = GDMK_AGGREGATE;
7703 kind = lang_hooks.decls.omp_predetermined_mapping (decl);
7704 if (kind != OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
7706 if (kind == OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE)
7707 nflags |= GOVD_FIRSTPRIVATE;
7708 else if (kind == OMP_CLAUSE_DEFAULTMAP_TO)
7709 nflags |= GOVD_MAP | GOVD_MAP_TO_ONLY;
7710 else
7711 gcc_unreachable ();
7713 else if (ctx->defaultmap[gdmk] == 0)
7715 tree d = lang_hooks.decls.omp_report_decl (decl);
7716 error ("%qE not specified in enclosing %<target%>",
7717 DECL_NAME (d));
7718 inform (ctx->location, "enclosing %<target%>");
7720 else if (ctx->defaultmap[gdmk]
7721 & (GOVD_MAP_0LEN_ARRAY | GOVD_FIRSTPRIVATE))
7722 nflags |= ctx->defaultmap[gdmk];
7723 else
7725 gcc_assert (ctx->defaultmap[gdmk] & GOVD_MAP);
7726 nflags |= ctx->defaultmap[gdmk] & ~GOVD_MAP;
7731 struct gimplify_omp_ctx *octx = ctx->outer_context;
7732 if ((ctx->region_type & ORT_ACC) && octx)
7734 /* Look in outer OpenACC contexts, to see if there's a
7735 data attribute for this variable. */
7736 omp_notice_variable (octx, decl, in_code);
7738 for (; octx; octx = octx->outer_context)
7740 if (!(octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)))
7741 break;
7742 splay_tree_node n2
7743 = splay_tree_lookup (octx->variables,
7744 (splay_tree_key) decl);
7745 if (n2)
7747 if (octx->region_type == ORT_ACC_HOST_DATA)
7748 error ("variable %qE declared in enclosing "
7749 "%<host_data%> region", DECL_NAME (decl));
7750 nflags |= GOVD_MAP;
7751 if (octx->region_type == ORT_ACC_DATA
7752 && (n2->value & GOVD_MAP_0LEN_ARRAY))
7753 nflags |= GOVD_MAP_0LEN_ARRAY;
7754 goto found_outer;
7759 if ((nflags & ~(GOVD_MAP_TO_ONLY | GOVD_MAP_FROM_ONLY
7760 | GOVD_MAP_ALLOC_ONLY)) == flags)
7762 tree type = TREE_TYPE (decl);
7764 if (gimplify_omp_ctxp->target_firstprivatize_array_bases
7765 && omp_privatize_by_reference (decl))
7766 type = TREE_TYPE (type);
7767 if (!lang_hooks.types.omp_mappable_type (type))
7769 error ("%qD referenced in target region does not have "
7770 "a mappable type", decl);
7771 nflags |= GOVD_MAP | GOVD_EXPLICIT;
7773 else
7775 if ((ctx->region_type & ORT_ACC) != 0)
7776 nflags = oacc_default_clause (ctx, decl, flags);
7777 else
7778 nflags |= GOVD_MAP;
7781 found_outer:
7782 omp_add_variable (ctx, decl, nflags);
7784 else
7786 /* If nothing changed, there's nothing left to do. */
7787 if ((n->value & flags) == flags)
7788 return ret;
7789 flags |= n->value;
7790 n->value = flags;
7792 goto do_outer;
7795 if (n == NULL)
7797 if (ctx->region_type == ORT_WORKSHARE
7798 || ctx->region_type == ORT_TASKGROUP
7799 || ctx->region_type == ORT_SIMD
7800 || ctx->region_type == ORT_ACC
7801 || (ctx->region_type & ORT_TARGET_DATA) != 0)
7802 goto do_outer;
7804 flags = omp_default_clause (ctx, decl, in_code, flags);
7806 if ((flags & GOVD_PRIVATE)
7807 && lang_hooks.decls.omp_private_outer_ref (decl))
7808 flags |= GOVD_PRIVATE_OUTER_REF;
7810 omp_add_variable (ctx, decl, flags);
7812 shared = (flags & GOVD_SHARED) != 0;
7813 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7814 goto do_outer;
7817 /* Don't mark as GOVD_SEEN addressable temporaries seen only in simd
7818 lb, b or incr expressions, those shouldn't be turned into simd arrays. */
7819 if (ctx->region_type == ORT_SIMD
7820 && ctx->in_for_exprs
7821 && ((n->value & (GOVD_PRIVATE | GOVD_SEEN | GOVD_EXPLICIT))
7822 == GOVD_PRIVATE))
7823 flags &= ~GOVD_SEEN;
7825 if ((n->value & (GOVD_SEEN | GOVD_LOCAL)) == 0
7826 && (flags & (GOVD_SEEN | GOVD_LOCAL)) == GOVD_SEEN
7827 && DECL_SIZE (decl))
7829 if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
7831 splay_tree_node n2;
7832 tree t = DECL_VALUE_EXPR (decl);
7833 gcc_assert (TREE_CODE (t) == INDIRECT_REF);
7834 t = TREE_OPERAND (t, 0);
7835 gcc_assert (DECL_P (t));
7836 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
7837 n2->value |= GOVD_SEEN;
7839 else if (omp_privatize_by_reference (decl)
7840 && TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)))
7841 && (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))))
7842 != INTEGER_CST))
7844 splay_tree_node n2;
7845 tree t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
7846 gcc_assert (DECL_P (t));
7847 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
7848 if (n2)
7849 omp_notice_variable (ctx, t, true);
7853 if (ctx->region_type & ORT_ACC)
7854 /* For OpenACC, as remarked above, defer expansion. */
7855 shared = false;
7856 else
7857 shared = ((flags | n->value) & GOVD_SHARED) != 0;
7858 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7860 /* If nothing changed, there's nothing left to do. */
7861 if ((n->value & flags) == flags)
7862 return ret;
7863 flags |= n->value;
7864 n->value = flags;
7866 do_outer:
7867 /* If the variable is private in the current context, then we don't
7868 need to propagate anything to an outer context. */
7869 if ((flags & GOVD_PRIVATE) && !(flags & GOVD_PRIVATE_OUTER_REF))
7870 return ret;
7871 if ((flags & (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7872 == (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7873 return ret;
7874 if ((flags & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
7875 | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7876 == (GOVD_LASTPRIVATE | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7877 return ret;
7878 if (ctx->outer_context
7879 && omp_notice_variable (ctx->outer_context, decl, in_code))
7880 return true;
7881 return ret;
7884 /* Verify that DECL is private within CTX. If there's specific information
7885 to the contrary in the innermost scope, generate an error. */
7887 static bool
7888 omp_is_private (struct gimplify_omp_ctx *ctx, tree decl, int simd)
7890 splay_tree_node n;
7892 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7893 if (n != NULL)
7895 if (n->value & GOVD_SHARED)
7897 if (ctx == gimplify_omp_ctxp)
7899 if (simd)
7900 error ("iteration variable %qE is predetermined linear",
7901 DECL_NAME (decl));
7902 else
7903 error ("iteration variable %qE should be private",
7904 DECL_NAME (decl));
7905 n->value = GOVD_PRIVATE;
7906 return true;
7908 else
7909 return false;
7911 else if ((n->value & GOVD_EXPLICIT) != 0
7912 && (ctx == gimplify_omp_ctxp
7913 || (ctx->region_type == ORT_COMBINED_PARALLEL
7914 && gimplify_omp_ctxp->outer_context == ctx)))
7916 if ((n->value & GOVD_FIRSTPRIVATE) != 0)
7917 error ("iteration variable %qE should not be firstprivate",
7918 DECL_NAME (decl));
7919 else if ((n->value & GOVD_REDUCTION) != 0)
7920 error ("iteration variable %qE should not be reduction",
7921 DECL_NAME (decl));
7922 else if (simd != 1 && (n->value & GOVD_LINEAR) != 0)
7923 error ("iteration variable %qE should not be linear",
7924 DECL_NAME (decl));
7926 return (ctx == gimplify_omp_ctxp
7927 || (ctx->region_type == ORT_COMBINED_PARALLEL
7928 && gimplify_omp_ctxp->outer_context == ctx));
7931 if (ctx->region_type != ORT_WORKSHARE
7932 && ctx->region_type != ORT_TASKGROUP
7933 && ctx->region_type != ORT_SIMD
7934 && ctx->region_type != ORT_ACC)
7935 return false;
7936 else if (ctx->outer_context)
7937 return omp_is_private (ctx->outer_context, decl, simd);
7938 return false;
7941 /* Return true if DECL is private within a parallel region
7942 that binds to the current construct's context or in parallel
7943 region's REDUCTION clause. */
7945 static bool
7946 omp_check_private (struct gimplify_omp_ctx *ctx, tree decl, bool copyprivate)
7948 splay_tree_node n;
7952 ctx = ctx->outer_context;
7953 if (ctx == NULL)
7955 if (is_global_var (decl))
7956 return false;
7958 /* References might be private, but might be shared too,
7959 when checking for copyprivate, assume they might be
7960 private, otherwise assume they might be shared. */
7961 if (copyprivate)
7962 return true;
7964 if (omp_privatize_by_reference (decl))
7965 return false;
7967 /* Treat C++ privatized non-static data members outside
7968 of the privatization the same. */
7969 if (omp_member_access_dummy_var (decl))
7970 return false;
7972 return true;
7975 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
7977 if ((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
7978 && (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0))
7980 if ((ctx->region_type & ORT_TARGET_DATA) != 0
7981 || n == NULL
7982 || (n->value & GOVD_MAP) == 0)
7983 continue;
7984 return false;
7987 if (n != NULL)
7989 if ((n->value & GOVD_LOCAL) != 0
7990 && omp_member_access_dummy_var (decl))
7991 return false;
7992 return (n->value & GOVD_SHARED) == 0;
7995 if (ctx->region_type == ORT_WORKSHARE
7996 || ctx->region_type == ORT_TASKGROUP
7997 || ctx->region_type == ORT_SIMD
7998 || ctx->region_type == ORT_ACC)
7999 continue;
8001 break;
8003 while (1);
8004 return false;
8007 /* Callback for walk_tree to find a DECL_EXPR for the given DECL. */
8009 static tree
8010 find_decl_expr (tree *tp, int *walk_subtrees, void *data)
8012 tree t = *tp;
8014 /* If this node has been visited, unmark it and keep looking. */
8015 if (TREE_CODE (t) == DECL_EXPR && DECL_EXPR_DECL (t) == (tree) data)
8016 return t;
8018 if (IS_TYPE_OR_DECL_P (t))
8019 *walk_subtrees = 0;
8020 return NULL_TREE;
8024 /* Gimplify the affinity clause but effectively ignore it.
8025 Generate:
8026 var = begin;
8027 if ((step > 1) ? var <= end : var > end)
8028 locatator_var_expr; */
8030 static void
8031 gimplify_omp_affinity (tree *list_p, gimple_seq *pre_p)
8033 tree last_iter = NULL_TREE;
8034 tree last_bind = NULL_TREE;
8035 tree label = NULL_TREE;
8036 tree *last_body = NULL;
8037 for (tree c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
8038 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY)
8040 tree t = OMP_CLAUSE_DECL (c);
8041 if (TREE_CODE (t) == TREE_LIST
8042 && TREE_PURPOSE (t)
8043 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
8045 if (TREE_VALUE (t) == null_pointer_node)
8046 continue;
8047 if (TREE_PURPOSE (t) != last_iter)
8049 if (last_bind)
8051 append_to_statement_list (label, last_body);
8052 gimplify_and_add (last_bind, pre_p);
8053 last_bind = NULL_TREE;
8055 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8057 if (gimplify_expr (&TREE_VEC_ELT (it, 1), pre_p, NULL,
8058 is_gimple_val, fb_rvalue) == GS_ERROR
8059 || gimplify_expr (&TREE_VEC_ELT (it, 2), pre_p, NULL,
8060 is_gimple_val, fb_rvalue) == GS_ERROR
8061 || gimplify_expr (&TREE_VEC_ELT (it, 3), pre_p, NULL,
8062 is_gimple_val, fb_rvalue) == GS_ERROR
8063 || (gimplify_expr (&TREE_VEC_ELT (it, 4), pre_p, NULL,
8064 is_gimple_val, fb_rvalue)
8065 == GS_ERROR))
8066 return;
8068 last_iter = TREE_PURPOSE (t);
8069 tree block = TREE_VEC_ELT (TREE_PURPOSE (t), 5);
8070 last_bind = build3 (BIND_EXPR, void_type_node, BLOCK_VARS (block),
8071 NULL, block);
8072 last_body = &BIND_EXPR_BODY (last_bind);
8073 tree cond = NULL_TREE;
8074 location_t loc = OMP_CLAUSE_LOCATION (c);
8075 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8077 tree var = TREE_VEC_ELT (it, 0);
8078 tree begin = TREE_VEC_ELT (it, 1);
8079 tree end = TREE_VEC_ELT (it, 2);
8080 tree step = TREE_VEC_ELT (it, 3);
8081 loc = DECL_SOURCE_LOCATION (var);
8082 tree tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
8083 var, begin);
8084 append_to_statement_list_force (tem, last_body);
8086 tree cond1 = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8087 step, build_zero_cst (TREE_TYPE (step)));
8088 tree cond2 = fold_build2_loc (loc, LE_EXPR, boolean_type_node,
8089 var, end);
8090 tree cond3 = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8091 var, end);
8092 cond1 = fold_build3_loc (loc, COND_EXPR, boolean_type_node,
8093 cond1, cond2, cond3);
8094 if (cond)
8095 cond = fold_build2_loc (loc, TRUTH_AND_EXPR,
8096 boolean_type_node, cond, cond1);
8097 else
8098 cond = cond1;
8100 tree cont_label = create_artificial_label (loc);
8101 label = build1 (LABEL_EXPR, void_type_node, cont_label);
8102 tree tem = fold_build3_loc (loc, COND_EXPR, void_type_node, cond,
8103 void_node,
8104 build_and_jump (&cont_label));
8105 append_to_statement_list_force (tem, last_body);
8107 if (TREE_CODE (TREE_VALUE (t)) == COMPOUND_EXPR)
8109 append_to_statement_list (TREE_OPERAND (TREE_VALUE (t), 0),
8110 last_body);
8111 TREE_VALUE (t) = TREE_OPERAND (TREE_VALUE (t), 1);
8113 if (error_operand_p (TREE_VALUE (t)))
8114 return;
8115 append_to_statement_list_force (TREE_VALUE (t), last_body);
8116 TREE_VALUE (t) = null_pointer_node;
8118 else
8120 if (last_bind)
8122 append_to_statement_list (label, last_body);
8123 gimplify_and_add (last_bind, pre_p);
8124 last_bind = NULL_TREE;
8126 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
8128 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
8129 NULL, is_gimple_val, fb_rvalue);
8130 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
8132 if (error_operand_p (OMP_CLAUSE_DECL (c)))
8133 return;
8134 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
8135 is_gimple_lvalue, fb_lvalue) == GS_ERROR)
8136 return;
8137 gimplify_and_add (OMP_CLAUSE_DECL (c), pre_p);
8140 if (last_bind)
8142 append_to_statement_list (label, last_body);
8143 gimplify_and_add (last_bind, pre_p);
8145 return;
8148 /* If *LIST_P contains any OpenMP depend clauses with iterators,
8149 lower all the depend clauses by populating corresponding depend
8150 array. Returns 0 if there are no such depend clauses, or
8151 2 if all depend clauses should be removed, 1 otherwise. */
8153 static int
8154 gimplify_omp_depend (tree *list_p, gimple_seq *pre_p)
8156 tree c;
8157 gimple *g;
8158 size_t n[4] = { 0, 0, 0, 0 };
8159 bool unused[4];
8160 tree counts[4] = { NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE };
8161 tree last_iter = NULL_TREE, last_count = NULL_TREE;
8162 size_t i, j;
8163 location_t first_loc = UNKNOWN_LOCATION;
8165 for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
8166 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
8168 switch (OMP_CLAUSE_DEPEND_KIND (c))
8170 case OMP_CLAUSE_DEPEND_IN:
8171 i = 2;
8172 break;
8173 case OMP_CLAUSE_DEPEND_OUT:
8174 case OMP_CLAUSE_DEPEND_INOUT:
8175 i = 0;
8176 break;
8177 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
8178 i = 1;
8179 break;
8180 case OMP_CLAUSE_DEPEND_DEPOBJ:
8181 i = 3;
8182 break;
8183 case OMP_CLAUSE_DEPEND_SOURCE:
8184 case OMP_CLAUSE_DEPEND_SINK:
8185 continue;
8186 default:
8187 gcc_unreachable ();
8189 tree t = OMP_CLAUSE_DECL (c);
8190 if (first_loc == UNKNOWN_LOCATION)
8191 first_loc = OMP_CLAUSE_LOCATION (c);
8192 if (TREE_CODE (t) == TREE_LIST
8193 && TREE_PURPOSE (t)
8194 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
8196 if (TREE_PURPOSE (t) != last_iter)
8198 tree tcnt = size_one_node;
8199 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8201 if (gimplify_expr (&TREE_VEC_ELT (it, 1), pre_p, NULL,
8202 is_gimple_val, fb_rvalue) == GS_ERROR
8203 || gimplify_expr (&TREE_VEC_ELT (it, 2), pre_p, NULL,
8204 is_gimple_val, fb_rvalue) == GS_ERROR
8205 || gimplify_expr (&TREE_VEC_ELT (it, 3), pre_p, NULL,
8206 is_gimple_val, fb_rvalue) == GS_ERROR
8207 || (gimplify_expr (&TREE_VEC_ELT (it, 4), pre_p, NULL,
8208 is_gimple_val, fb_rvalue)
8209 == GS_ERROR))
8210 return 2;
8211 tree var = TREE_VEC_ELT (it, 0);
8212 tree begin = TREE_VEC_ELT (it, 1);
8213 tree end = TREE_VEC_ELT (it, 2);
8214 tree step = TREE_VEC_ELT (it, 3);
8215 tree orig_step = TREE_VEC_ELT (it, 4);
8216 tree type = TREE_TYPE (var);
8217 tree stype = TREE_TYPE (step);
8218 location_t loc = DECL_SOURCE_LOCATION (var);
8219 tree endmbegin;
8220 /* Compute count for this iterator as
8221 orig_step > 0
8222 ? (begin < end ? (end - begin + (step - 1)) / step : 0)
8223 : (begin > end ? (end - begin + (step + 1)) / step : 0)
8224 and compute product of those for the entire depend
8225 clause. */
8226 if (POINTER_TYPE_P (type))
8227 endmbegin = fold_build2_loc (loc, POINTER_DIFF_EXPR,
8228 stype, end, begin);
8229 else
8230 endmbegin = fold_build2_loc (loc, MINUS_EXPR, type,
8231 end, begin);
8232 tree stepm1 = fold_build2_loc (loc, MINUS_EXPR, stype,
8233 step,
8234 build_int_cst (stype, 1));
8235 tree stepp1 = fold_build2_loc (loc, PLUS_EXPR, stype, step,
8236 build_int_cst (stype, 1));
8237 tree pos = fold_build2_loc (loc, PLUS_EXPR, stype,
8238 unshare_expr (endmbegin),
8239 stepm1);
8240 pos = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype,
8241 pos, step);
8242 tree neg = fold_build2_loc (loc, PLUS_EXPR, stype,
8243 endmbegin, stepp1);
8244 if (TYPE_UNSIGNED (stype))
8246 neg = fold_build1_loc (loc, NEGATE_EXPR, stype, neg);
8247 step = fold_build1_loc (loc, NEGATE_EXPR, stype, step);
8249 neg = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype,
8250 neg, step);
8251 step = NULL_TREE;
8252 tree cond = fold_build2_loc (loc, LT_EXPR,
8253 boolean_type_node,
8254 begin, end);
8255 pos = fold_build3_loc (loc, COND_EXPR, stype, cond, pos,
8256 build_int_cst (stype, 0));
8257 cond = fold_build2_loc (loc, LT_EXPR, boolean_type_node,
8258 end, begin);
8259 neg = fold_build3_loc (loc, COND_EXPR, stype, cond, neg,
8260 build_int_cst (stype, 0));
8261 tree osteptype = TREE_TYPE (orig_step);
8262 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8263 orig_step,
8264 build_int_cst (osteptype, 0));
8265 tree cnt = fold_build3_loc (loc, COND_EXPR, stype,
8266 cond, pos, neg);
8267 cnt = fold_convert_loc (loc, sizetype, cnt);
8268 if (gimplify_expr (&cnt, pre_p, NULL, is_gimple_val,
8269 fb_rvalue) == GS_ERROR)
8270 return 2;
8271 tcnt = size_binop_loc (loc, MULT_EXPR, tcnt, cnt);
8273 if (gimplify_expr (&tcnt, pre_p, NULL, is_gimple_val,
8274 fb_rvalue) == GS_ERROR)
8275 return 2;
8276 last_iter = TREE_PURPOSE (t);
8277 last_count = tcnt;
8279 if (counts[i] == NULL_TREE)
8280 counts[i] = last_count;
8281 else
8282 counts[i] = size_binop_loc (OMP_CLAUSE_LOCATION (c),
8283 PLUS_EXPR, counts[i], last_count);
8285 else
8286 n[i]++;
8288 for (i = 0; i < 4; i++)
8289 if (counts[i])
8290 break;
8291 if (i == 4)
8292 return 0;
8294 tree total = size_zero_node;
8295 for (i = 0; i < 4; i++)
8297 unused[i] = counts[i] == NULL_TREE && n[i] == 0;
8298 if (counts[i] == NULL_TREE)
8299 counts[i] = size_zero_node;
8300 if (n[i])
8301 counts[i] = size_binop (PLUS_EXPR, counts[i], size_int (n[i]));
8302 if (gimplify_expr (&counts[i], pre_p, NULL, is_gimple_val,
8303 fb_rvalue) == GS_ERROR)
8304 return 2;
8305 total = size_binop (PLUS_EXPR, total, counts[i]);
8308 if (gimplify_expr (&total, pre_p, NULL, is_gimple_val, fb_rvalue)
8309 == GS_ERROR)
8310 return 2;
8311 bool is_old = unused[1] && unused[3];
8312 tree totalpx = size_binop (PLUS_EXPR, unshare_expr (total),
8313 size_int (is_old ? 1 : 4));
8314 tree type = build_array_type (ptr_type_node, build_index_type (totalpx));
8315 tree array = create_tmp_var_raw (type);
8316 TREE_ADDRESSABLE (array) = 1;
8317 if (!poly_int_tree_p (totalpx))
8319 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (array)))
8320 gimplify_type_sizes (TREE_TYPE (array), pre_p);
8321 if (gimplify_omp_ctxp)
8323 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
8324 while (ctx
8325 && (ctx->region_type == ORT_WORKSHARE
8326 || ctx->region_type == ORT_TASKGROUP
8327 || ctx->region_type == ORT_SIMD
8328 || ctx->region_type == ORT_ACC))
8329 ctx = ctx->outer_context;
8330 if (ctx)
8331 omp_add_variable (ctx, array, GOVD_LOCAL | GOVD_SEEN);
8333 gimplify_vla_decl (array, pre_p);
8335 else
8336 gimple_add_tmp_var (array);
8337 tree r = build4 (ARRAY_REF, ptr_type_node, array, size_int (0), NULL_TREE,
8338 NULL_TREE);
8339 tree tem;
8340 if (!is_old)
8342 tem = build2 (MODIFY_EXPR, void_type_node, r,
8343 build_int_cst (ptr_type_node, 0));
8344 gimplify_and_add (tem, pre_p);
8345 r = build4 (ARRAY_REF, ptr_type_node, array, size_int (1), NULL_TREE,
8346 NULL_TREE);
8348 tem = build2 (MODIFY_EXPR, void_type_node, r,
8349 fold_convert (ptr_type_node, total));
8350 gimplify_and_add (tem, pre_p);
8351 for (i = 1; i < (is_old ? 2 : 4); i++)
8353 r = build4 (ARRAY_REF, ptr_type_node, array, size_int (i + !is_old),
8354 NULL_TREE, NULL_TREE);
8355 tem = build2 (MODIFY_EXPR, void_type_node, r, counts[i - 1]);
8356 gimplify_and_add (tem, pre_p);
8359 tree cnts[4];
8360 for (j = 4; j; j--)
8361 if (!unused[j - 1])
8362 break;
8363 for (i = 0; i < 4; i++)
8365 if (i && (i >= j || unused[i - 1]))
8367 cnts[i] = cnts[i - 1];
8368 continue;
8370 cnts[i] = create_tmp_var (sizetype);
8371 if (i == 0)
8372 g = gimple_build_assign (cnts[i], size_int (is_old ? 2 : 5));
8373 else
8375 tree t;
8376 if (is_old)
8377 t = size_binop (PLUS_EXPR, counts[0], size_int (2));
8378 else
8379 t = size_binop (PLUS_EXPR, cnts[i - 1], counts[i - 1]);
8380 if (gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue)
8381 == GS_ERROR)
8382 return 2;
8383 g = gimple_build_assign (cnts[i], t);
8385 gimple_seq_add_stmt (pre_p, g);
8388 last_iter = NULL_TREE;
8389 tree last_bind = NULL_TREE;
8390 tree *last_body = NULL;
8391 for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
8392 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
8394 switch (OMP_CLAUSE_DEPEND_KIND (c))
8396 case OMP_CLAUSE_DEPEND_IN:
8397 i = 2;
8398 break;
8399 case OMP_CLAUSE_DEPEND_OUT:
8400 case OMP_CLAUSE_DEPEND_INOUT:
8401 i = 0;
8402 break;
8403 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
8404 i = 1;
8405 break;
8406 case OMP_CLAUSE_DEPEND_DEPOBJ:
8407 i = 3;
8408 break;
8409 case OMP_CLAUSE_DEPEND_SOURCE:
8410 case OMP_CLAUSE_DEPEND_SINK:
8411 continue;
8412 default:
8413 gcc_unreachable ();
8415 tree t = OMP_CLAUSE_DECL (c);
8416 if (TREE_CODE (t) == TREE_LIST
8417 && TREE_PURPOSE (t)
8418 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
8420 if (TREE_PURPOSE (t) != last_iter)
8422 if (last_bind)
8423 gimplify_and_add (last_bind, pre_p);
8424 tree block = TREE_VEC_ELT (TREE_PURPOSE (t), 5);
8425 last_bind = build3 (BIND_EXPR, void_type_node,
8426 BLOCK_VARS (block), NULL, block);
8427 TREE_SIDE_EFFECTS (last_bind) = 1;
8428 SET_EXPR_LOCATION (last_bind, OMP_CLAUSE_LOCATION (c));
8429 tree *p = &BIND_EXPR_BODY (last_bind);
8430 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8432 tree var = TREE_VEC_ELT (it, 0);
8433 tree begin = TREE_VEC_ELT (it, 1);
8434 tree end = TREE_VEC_ELT (it, 2);
8435 tree step = TREE_VEC_ELT (it, 3);
8436 tree orig_step = TREE_VEC_ELT (it, 4);
8437 tree type = TREE_TYPE (var);
8438 location_t loc = DECL_SOURCE_LOCATION (var);
8439 /* Emit:
8440 var = begin;
8441 goto cond_label;
8442 beg_label:
8444 var = var + step;
8445 cond_label:
8446 if (orig_step > 0) {
8447 if (var < end) goto beg_label;
8448 } else {
8449 if (var > end) goto beg_label;
8451 for each iterator, with inner iterators added to
8452 the ... above. */
8453 tree beg_label = create_artificial_label (loc);
8454 tree cond_label = NULL_TREE;
8455 tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
8456 var, begin);
8457 append_to_statement_list_force (tem, p);
8458 tem = build_and_jump (&cond_label);
8459 append_to_statement_list_force (tem, p);
8460 tem = build1 (LABEL_EXPR, void_type_node, beg_label);
8461 append_to_statement_list (tem, p);
8462 tree bind = build3 (BIND_EXPR, void_type_node, NULL_TREE,
8463 NULL_TREE, NULL_TREE);
8464 TREE_SIDE_EFFECTS (bind) = 1;
8465 SET_EXPR_LOCATION (bind, loc);
8466 append_to_statement_list_force (bind, p);
8467 if (POINTER_TYPE_P (type))
8468 tem = build2_loc (loc, POINTER_PLUS_EXPR, type,
8469 var, fold_convert_loc (loc, sizetype,
8470 step));
8471 else
8472 tem = build2_loc (loc, PLUS_EXPR, type, var, step);
8473 tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
8474 var, tem);
8475 append_to_statement_list_force (tem, p);
8476 tem = build1 (LABEL_EXPR, void_type_node, cond_label);
8477 append_to_statement_list (tem, p);
8478 tree cond = fold_build2_loc (loc, LT_EXPR,
8479 boolean_type_node,
8480 var, end);
8481 tree pos
8482 = fold_build3_loc (loc, COND_EXPR, void_type_node,
8483 cond, build_and_jump (&beg_label),
8484 void_node);
8485 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8486 var, end);
8487 tree neg
8488 = fold_build3_loc (loc, COND_EXPR, void_type_node,
8489 cond, build_and_jump (&beg_label),
8490 void_node);
8491 tree osteptype = TREE_TYPE (orig_step);
8492 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8493 orig_step,
8494 build_int_cst (osteptype, 0));
8495 tem = fold_build3_loc (loc, COND_EXPR, void_type_node,
8496 cond, pos, neg);
8497 append_to_statement_list_force (tem, p);
8498 p = &BIND_EXPR_BODY (bind);
8500 last_body = p;
8502 last_iter = TREE_PURPOSE (t);
8503 if (TREE_CODE (TREE_VALUE (t)) == COMPOUND_EXPR)
8505 append_to_statement_list (TREE_OPERAND (TREE_VALUE (t),
8506 0), last_body);
8507 TREE_VALUE (t) = TREE_OPERAND (TREE_VALUE (t), 1);
8509 if (error_operand_p (TREE_VALUE (t)))
8510 return 2;
8511 TREE_VALUE (t) = build_fold_addr_expr (TREE_VALUE (t));
8512 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
8513 NULL_TREE, NULL_TREE);
8514 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
8515 void_type_node, r, TREE_VALUE (t));
8516 append_to_statement_list_force (tem, last_body);
8517 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
8518 void_type_node, cnts[i],
8519 size_binop (PLUS_EXPR, cnts[i], size_int (1)));
8520 append_to_statement_list_force (tem, last_body);
8521 TREE_VALUE (t) = null_pointer_node;
8523 else
8525 if (last_bind)
8527 gimplify_and_add (last_bind, pre_p);
8528 last_bind = NULL_TREE;
8530 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
8532 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
8533 NULL, is_gimple_val, fb_rvalue);
8534 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
8536 if (error_operand_p (OMP_CLAUSE_DECL (c)))
8537 return 2;
8538 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
8539 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
8540 is_gimple_val, fb_rvalue) == GS_ERROR)
8541 return 2;
8542 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
8543 NULL_TREE, NULL_TREE);
8544 tem = build2 (MODIFY_EXPR, void_type_node, r, OMP_CLAUSE_DECL (c));
8545 gimplify_and_add (tem, pre_p);
8546 g = gimple_build_assign (cnts[i], size_binop (PLUS_EXPR, cnts[i],
8547 size_int (1)));
8548 gimple_seq_add_stmt (pre_p, g);
8551 if (last_bind)
8552 gimplify_and_add (last_bind, pre_p);
8553 tree cond = boolean_false_node;
8554 if (is_old)
8556 if (!unused[0])
8557 cond = build2_loc (first_loc, NE_EXPR, boolean_type_node, cnts[0],
8558 size_binop_loc (first_loc, PLUS_EXPR, counts[0],
8559 size_int (2)));
8560 if (!unused[2])
8561 cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond,
8562 build2_loc (first_loc, NE_EXPR, boolean_type_node,
8563 cnts[2],
8564 size_binop_loc (first_loc, PLUS_EXPR,
8565 totalpx,
8566 size_int (1))));
8568 else
8570 tree prev = size_int (5);
8571 for (i = 0; i < 4; i++)
8573 if (unused[i])
8574 continue;
8575 prev = size_binop_loc (first_loc, PLUS_EXPR, counts[i], prev);
8576 cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond,
8577 build2_loc (first_loc, NE_EXPR, boolean_type_node,
8578 cnts[i], unshare_expr (prev)));
8581 tem = build3_loc (first_loc, COND_EXPR, void_type_node, cond,
8582 build_call_expr_loc (first_loc,
8583 builtin_decl_explicit (BUILT_IN_TRAP),
8584 0), void_node);
8585 gimplify_and_add (tem, pre_p);
8586 c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_DEPEND);
8587 OMP_CLAUSE_DEPEND_KIND (c) = OMP_CLAUSE_DEPEND_LAST;
8588 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (array);
8589 OMP_CLAUSE_CHAIN (c) = *list_p;
8590 *list_p = c;
8591 return 1;
8594 /* Insert a GOMP_MAP_ALLOC or GOMP_MAP_RELEASE node following a
8595 GOMP_MAP_STRUCT mapping. C is an always_pointer mapping. STRUCT_NODE is
8596 the struct node to insert the new mapping after (when the struct node is
8597 initially created). PREV_NODE is the first of two or three mappings for a
8598 pointer, and is either:
8599 - the node before C, when a pair of mappings is used, e.g. for a C/C++
8600 array section.
8601 - not the node before C. This is true when we have a reference-to-pointer
8602 type (with a mapping for the reference and for the pointer), or for
8603 Fortran derived-type mappings with a GOMP_MAP_TO_PSET.
8604 If SCP is non-null, the new node is inserted before *SCP.
8605 if SCP is null, the new node is inserted before PREV_NODE.
8606 The return type is:
8607 - PREV_NODE, if SCP is non-null.
8608 - The newly-created ALLOC or RELEASE node, if SCP is null.
8609 - The second newly-created ALLOC or RELEASE node, if we are mapping a
8610 reference to a pointer. */
8612 static tree
8613 insert_struct_comp_map (enum tree_code code, tree c, tree struct_node,
8614 tree prev_node, tree *scp)
8616 enum gomp_map_kind mkind
8617 = (code == OMP_TARGET_EXIT_DATA || code == OACC_EXIT_DATA)
8618 ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
8620 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
8621 tree cl = scp ? prev_node : c2;
8622 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
8623 OMP_CLAUSE_DECL (c2) = unshare_expr (OMP_CLAUSE_DECL (c));
8624 OMP_CLAUSE_CHAIN (c2) = scp ? *scp : prev_node;
8625 if (OMP_CLAUSE_CHAIN (prev_node) != c
8626 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (prev_node)) == OMP_CLAUSE_MAP
8627 && (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node))
8628 == GOMP_MAP_TO_PSET))
8629 OMP_CLAUSE_SIZE (c2) = OMP_CLAUSE_SIZE (OMP_CLAUSE_CHAIN (prev_node));
8630 else
8631 OMP_CLAUSE_SIZE (c2) = TYPE_SIZE_UNIT (ptr_type_node);
8632 if (struct_node)
8633 OMP_CLAUSE_CHAIN (struct_node) = c2;
8635 /* We might need to create an additional mapping if we have a reference to a
8636 pointer (in C++). Don't do this if we have something other than a
8637 GOMP_MAP_ALWAYS_POINTER though, i.e. a GOMP_MAP_TO_PSET. */
8638 if (OMP_CLAUSE_CHAIN (prev_node) != c
8639 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (prev_node)) == OMP_CLAUSE_MAP
8640 && ((OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node))
8641 == GOMP_MAP_ALWAYS_POINTER)
8642 || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node))
8643 == GOMP_MAP_ATTACH_DETACH)))
8645 tree c4 = OMP_CLAUSE_CHAIN (prev_node);
8646 tree c3 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
8647 OMP_CLAUSE_SET_MAP_KIND (c3, mkind);
8648 OMP_CLAUSE_DECL (c3) = unshare_expr (OMP_CLAUSE_DECL (c4));
8649 OMP_CLAUSE_SIZE (c3) = TYPE_SIZE_UNIT (ptr_type_node);
8650 OMP_CLAUSE_CHAIN (c3) = prev_node;
8651 if (!scp)
8652 OMP_CLAUSE_CHAIN (c2) = c3;
8653 else
8654 cl = c3;
8657 if (scp)
8658 *scp = c2;
8660 return cl;
8663 /* Strip ARRAY_REFS or an indirect ref off BASE, find the containing object,
8664 and set *BITPOSP and *POFFSETP to the bit offset of the access.
8665 If BASE_REF is non-NULL and the containing object is a reference, set
8666 *BASE_REF to that reference before dereferencing the object.
8667 If BASE_REF is NULL, check that the containing object is a COMPONENT_REF or
8668 has array type, else return NULL. */
8670 static tree
8671 extract_base_bit_offset (tree base, tree *base_ref, poly_int64 *bitposp,
8672 poly_offset_int *poffsetp, tree *offsetp)
8674 tree offset;
8675 poly_int64 bitsize, bitpos;
8676 machine_mode mode;
8677 int unsignedp, reversep, volatilep = 0;
8678 poly_offset_int poffset;
8680 if (base_ref)
8682 *base_ref = NULL_TREE;
8684 while (TREE_CODE (base) == ARRAY_REF)
8685 base = TREE_OPERAND (base, 0);
8687 if (TREE_CODE (base) == INDIRECT_REF)
8688 base = TREE_OPERAND (base, 0);
8690 else
8692 if (TREE_CODE (base) == ARRAY_REF)
8694 while (TREE_CODE (base) == ARRAY_REF)
8695 base = TREE_OPERAND (base, 0);
8696 if (TREE_CODE (base) != COMPONENT_REF
8697 || TREE_CODE (TREE_TYPE (base)) != ARRAY_TYPE)
8698 return NULL_TREE;
8700 else if (TREE_CODE (base) == INDIRECT_REF
8701 && TREE_CODE (TREE_OPERAND (base, 0)) == COMPONENT_REF
8702 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0)))
8703 == REFERENCE_TYPE))
8704 base = TREE_OPERAND (base, 0);
8707 base = get_inner_reference (base, &bitsize, &bitpos, &offset, &mode,
8708 &unsignedp, &reversep, &volatilep);
8710 tree orig_base = base;
8712 if ((TREE_CODE (base) == INDIRECT_REF
8713 || (TREE_CODE (base) == MEM_REF
8714 && integer_zerop (TREE_OPERAND (base, 1))))
8715 && DECL_P (TREE_OPERAND (base, 0))
8716 && TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0))) == REFERENCE_TYPE)
8717 base = TREE_OPERAND (base, 0);
8719 if (offset && poly_int_tree_p (offset))
8721 poffset = wi::to_poly_offset (offset);
8722 offset = NULL_TREE;
8724 else
8725 poffset = 0;
8727 if (maybe_ne (bitpos, 0))
8728 poffset += bits_to_bytes_round_down (bitpos);
8730 *bitposp = bitpos;
8731 *poffsetp = poffset;
8732 *offsetp = offset;
8734 /* Set *BASE_REF if BASE was a dereferenced reference variable. */
8735 if (base_ref && orig_base != base)
8736 *base_ref = orig_base;
8738 return base;
8741 /* Returns true if EXPR is or contains (as a sub-component) BASE_PTR. */
8743 static bool
8744 is_or_contains_p (tree expr, tree base_ptr)
8746 if ((TREE_CODE (expr) == INDIRECT_REF && TREE_CODE (base_ptr) == MEM_REF)
8747 || (TREE_CODE (expr) == MEM_REF && TREE_CODE (base_ptr) == INDIRECT_REF))
8748 return operand_equal_p (TREE_OPERAND (expr, 0),
8749 TREE_OPERAND (base_ptr, 0));
8750 while (!operand_equal_p (expr, base_ptr))
8752 if (TREE_CODE (base_ptr) == COMPOUND_EXPR)
8753 base_ptr = TREE_OPERAND (base_ptr, 1);
8754 if (TREE_CODE (base_ptr) == COMPONENT_REF
8755 || TREE_CODE (base_ptr) == POINTER_PLUS_EXPR
8756 || TREE_CODE (base_ptr) == SAVE_EXPR)
8757 base_ptr = TREE_OPERAND (base_ptr, 0);
8758 else
8759 break;
8761 return operand_equal_p (expr, base_ptr);
8764 /* Implement OpenMP 5.x map ordering rules for target directives. There are
8765 several rules, and with some level of ambiguity, hopefully we can at least
8766 collect the complexity here in one place. */
8768 static void
8769 omp_target_reorder_clauses (tree *list_p)
8771 /* Collect refs to alloc/release/delete maps. */
8772 auto_vec<tree, 32> ard;
8773 tree *cp = list_p;
8774 while (*cp != NULL_TREE)
8775 if (OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP
8776 && (OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_ALLOC
8777 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_RELEASE
8778 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_DELETE))
8780 /* Unlink cp and push to ard. */
8781 tree c = *cp;
8782 tree nc = OMP_CLAUSE_CHAIN (c);
8783 *cp = nc;
8784 ard.safe_push (c);
8786 /* Any associated pointer type maps should also move along. */
8787 while (*cp != NULL_TREE
8788 && OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP
8789 && (OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
8790 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_FIRSTPRIVATE_POINTER
8791 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_ATTACH_DETACH
8792 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_POINTER
8793 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_ALWAYS_POINTER
8794 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_TO_PSET))
8796 c = *cp;
8797 nc = OMP_CLAUSE_CHAIN (c);
8798 *cp = nc;
8799 ard.safe_push (c);
8802 else
8803 cp = &OMP_CLAUSE_CHAIN (*cp);
8805 /* Link alloc/release/delete maps to the end of list. */
8806 for (unsigned int i = 0; i < ard.length (); i++)
8808 *cp = ard[i];
8809 cp = &OMP_CLAUSE_CHAIN (ard[i]);
8811 *cp = NULL_TREE;
8813 /* OpenMP 5.0 requires that pointer variables are mapped before
8814 its use as a base-pointer. */
8815 auto_vec<tree *, 32> atf;
8816 for (tree *cp = list_p; *cp; cp = &OMP_CLAUSE_CHAIN (*cp))
8817 if (OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP)
8819 /* Collect alloc, to, from, to/from clause tree pointers. */
8820 gomp_map_kind k = OMP_CLAUSE_MAP_KIND (*cp);
8821 if (k == GOMP_MAP_ALLOC
8822 || k == GOMP_MAP_TO
8823 || k == GOMP_MAP_FROM
8824 || k == GOMP_MAP_TOFROM
8825 || k == GOMP_MAP_ALWAYS_TO
8826 || k == GOMP_MAP_ALWAYS_FROM
8827 || k == GOMP_MAP_ALWAYS_TOFROM)
8828 atf.safe_push (cp);
8831 for (unsigned int i = 0; i < atf.length (); i++)
8832 if (atf[i])
8834 tree *cp = atf[i];
8835 tree decl = OMP_CLAUSE_DECL (*cp);
8836 if (TREE_CODE (decl) == INDIRECT_REF || TREE_CODE (decl) == MEM_REF)
8838 tree base_ptr = TREE_OPERAND (decl, 0);
8839 STRIP_TYPE_NOPS (base_ptr);
8840 for (unsigned int j = i + 1; j < atf.length (); j++)
8841 if (atf[j])
8843 tree *cp2 = atf[j];
8844 tree decl2 = OMP_CLAUSE_DECL (*cp2);
8846 decl2 = OMP_CLAUSE_DECL (*cp2);
8847 if (is_or_contains_p (decl2, base_ptr))
8849 /* Move *cp2 to before *cp. */
8850 tree c = *cp2;
8851 *cp2 = OMP_CLAUSE_CHAIN (c);
8852 OMP_CLAUSE_CHAIN (c) = *cp;
8853 *cp = c;
8855 if (*cp2 != NULL_TREE
8856 && OMP_CLAUSE_CODE (*cp2) == OMP_CLAUSE_MAP
8857 && OMP_CLAUSE_MAP_KIND (*cp2) == GOMP_MAP_ALWAYS_POINTER)
8859 tree c2 = *cp2;
8860 *cp2 = OMP_CLAUSE_CHAIN (c2);
8861 OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (c);
8862 OMP_CLAUSE_CHAIN (c) = c2;
8865 atf[j] = NULL;
8871 /* For attach_detach map clauses, if there is another map that maps the
8872 attached/detached pointer, make sure that map is ordered before the
8873 attach_detach. */
8874 atf.truncate (0);
8875 for (tree *cp = list_p; *cp; cp = &OMP_CLAUSE_CHAIN (*cp))
8876 if (OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP)
8878 /* Collect alloc, to, from, to/from clauses, and
8879 always_pointer/attach_detach clauses. */
8880 gomp_map_kind k = OMP_CLAUSE_MAP_KIND (*cp);
8881 if (k == GOMP_MAP_ALLOC
8882 || k == GOMP_MAP_TO
8883 || k == GOMP_MAP_FROM
8884 || k == GOMP_MAP_TOFROM
8885 || k == GOMP_MAP_ALWAYS_TO
8886 || k == GOMP_MAP_ALWAYS_FROM
8887 || k == GOMP_MAP_ALWAYS_TOFROM
8888 || k == GOMP_MAP_ATTACH_DETACH
8889 || k == GOMP_MAP_ALWAYS_POINTER)
8890 atf.safe_push (cp);
8893 for (unsigned int i = 0; i < atf.length (); i++)
8894 if (atf[i])
8896 tree *cp = atf[i];
8897 tree ptr = OMP_CLAUSE_DECL (*cp);
8898 STRIP_TYPE_NOPS (ptr);
8899 if (OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_ATTACH_DETACH)
8900 for (unsigned int j = i + 1; j < atf.length (); j++)
8902 tree *cp2 = atf[j];
8903 tree decl2 = OMP_CLAUSE_DECL (*cp2);
8904 if (OMP_CLAUSE_MAP_KIND (*cp2) != GOMP_MAP_ATTACH_DETACH
8905 && OMP_CLAUSE_MAP_KIND (*cp2) != GOMP_MAP_ALWAYS_POINTER
8906 && is_or_contains_p (decl2, ptr))
8908 /* Move *cp2 to before *cp. */
8909 tree c = *cp2;
8910 *cp2 = OMP_CLAUSE_CHAIN (c);
8911 OMP_CLAUSE_CHAIN (c) = *cp;
8912 *cp = c;
8913 atf[j] = NULL;
8915 /* If decl2 is of the form '*decl2_opnd0', and followed by an
8916 ALWAYS_POINTER or ATTACH_DETACH of 'decl2_opnd0', move the
8917 pointer operation along with *cp2. This can happen for C++
8918 reference sequences. */
8919 if (j + 1 < atf.length ()
8920 && (TREE_CODE (decl2) == INDIRECT_REF
8921 || TREE_CODE (decl2) == MEM_REF))
8923 tree *cp3 = atf[j + 1];
8924 tree decl3 = OMP_CLAUSE_DECL (*cp3);
8925 tree decl2_opnd0 = TREE_OPERAND (decl2, 0);
8926 if ((OMP_CLAUSE_MAP_KIND (*cp3) == GOMP_MAP_ALWAYS_POINTER
8927 || OMP_CLAUSE_MAP_KIND (*cp3) == GOMP_MAP_ATTACH_DETACH)
8928 && operand_equal_p (decl3, decl2_opnd0))
8930 /* Also move *cp3 to before *cp. */
8931 c = *cp3;
8932 *cp2 = OMP_CLAUSE_CHAIN (c);
8933 OMP_CLAUSE_CHAIN (c) = *cp;
8934 *cp = c;
8935 atf[j + 1] = NULL;
8936 j += 1;
8944 /* DECL is supposed to have lastprivate semantics in the outer contexts
8945 of combined/composite constructs, starting with OCTX.
8946 Add needed lastprivate, shared or map clause if no data sharing or
8947 mapping clause are present. IMPLICIT_P is true if it is an implicit
8948 clause (IV on simd), in which case the lastprivate will not be
8949 copied to some constructs. */
8951 static void
8952 omp_lastprivate_for_combined_outer_constructs (struct gimplify_omp_ctx *octx,
8953 tree decl, bool implicit_p)
8955 struct gimplify_omp_ctx *orig_octx = octx;
8956 for (; octx; octx = octx->outer_context)
8958 if ((octx->region_type == ORT_COMBINED_PARALLEL
8959 || (octx->region_type & ORT_COMBINED_TEAMS) == ORT_COMBINED_TEAMS)
8960 && splay_tree_lookup (octx->variables,
8961 (splay_tree_key) decl) == NULL)
8963 omp_add_variable (octx, decl, GOVD_SHARED | GOVD_SEEN);
8964 continue;
8966 if ((octx->region_type & ORT_TASK) != 0
8967 && octx->combined_loop
8968 && splay_tree_lookup (octx->variables,
8969 (splay_tree_key) decl) == NULL)
8971 omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
8972 continue;
8974 if (implicit_p
8975 && octx->region_type == ORT_WORKSHARE
8976 && octx->combined_loop
8977 && splay_tree_lookup (octx->variables,
8978 (splay_tree_key) decl) == NULL
8979 && octx->outer_context
8980 && octx->outer_context->region_type == ORT_COMBINED_PARALLEL
8981 && splay_tree_lookup (octx->outer_context->variables,
8982 (splay_tree_key) decl) == NULL)
8984 octx = octx->outer_context;
8985 omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
8986 continue;
8988 if ((octx->region_type == ORT_WORKSHARE || octx->region_type == ORT_ACC)
8989 && octx->combined_loop
8990 && splay_tree_lookup (octx->variables,
8991 (splay_tree_key) decl) == NULL
8992 && !omp_check_private (octx, decl, false))
8994 omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
8995 continue;
8997 if (octx->region_type == ORT_COMBINED_TARGET)
8999 splay_tree_node n = splay_tree_lookup (octx->variables,
9000 (splay_tree_key) decl);
9001 if (n == NULL)
9003 omp_add_variable (octx, decl, GOVD_MAP | GOVD_SEEN);
9004 octx = octx->outer_context;
9006 else if (!implicit_p
9007 && (n->value & GOVD_FIRSTPRIVATE_IMPLICIT))
9009 n->value &= ~(GOVD_FIRSTPRIVATE
9010 | GOVD_FIRSTPRIVATE_IMPLICIT
9011 | GOVD_EXPLICIT);
9012 omp_add_variable (octx, decl, GOVD_MAP | GOVD_SEEN);
9013 octx = octx->outer_context;
9016 break;
9018 if (octx && (implicit_p || octx != orig_octx))
9019 omp_notice_variable (octx, decl, true);
9022 /* Scan the OMP clauses in *LIST_P, installing mappings into a new
9023 and previous omp contexts. */
9025 static void
9026 gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
9027 enum omp_region_type region_type,
9028 enum tree_code code)
9030 struct gimplify_omp_ctx *ctx, *outer_ctx;
9031 tree c;
9032 hash_map<tree_operand_hash, tree> *struct_map_to_clause = NULL;
9033 hash_map<tree_operand_hash, tree *> *struct_seen_clause = NULL;
9034 hash_set<tree> *struct_deref_set = NULL;
9035 tree *prev_list_p = NULL, *orig_list_p = list_p;
9036 int handled_depend_iterators = -1;
9037 int nowait = -1;
9039 ctx = new_omp_context (region_type);
9040 ctx->code = code;
9041 outer_ctx = ctx->outer_context;
9042 if (code == OMP_TARGET)
9044 if (!lang_GNU_Fortran ())
9045 ctx->defaultmap[GDMK_POINTER] = GOVD_MAP | GOVD_MAP_0LEN_ARRAY;
9046 ctx->defaultmap[GDMK_SCALAR] = GOVD_FIRSTPRIVATE;
9047 ctx->defaultmap[GDMK_SCALAR_TARGET] = (lang_GNU_Fortran ()
9048 ? GOVD_MAP : GOVD_FIRSTPRIVATE);
9050 if (!lang_GNU_Fortran ())
9051 switch (code)
9053 case OMP_TARGET:
9054 case OMP_TARGET_DATA:
9055 case OMP_TARGET_ENTER_DATA:
9056 case OMP_TARGET_EXIT_DATA:
9057 case OACC_DECLARE:
9058 case OACC_HOST_DATA:
9059 case OACC_PARALLEL:
9060 case OACC_KERNELS:
9061 ctx->target_firstprivatize_array_bases = true;
9062 default:
9063 break;
9066 if (code == OMP_TARGET
9067 || code == OMP_TARGET_DATA
9068 || code == OMP_TARGET_ENTER_DATA
9069 || code == OMP_TARGET_EXIT_DATA)
9070 omp_target_reorder_clauses (list_p);
9072 while ((c = *list_p) != NULL)
9074 bool remove = false;
9075 bool notice_outer = true;
9076 const char *check_non_private = NULL;
9077 unsigned int flags;
9078 tree decl;
9080 switch (OMP_CLAUSE_CODE (c))
9082 case OMP_CLAUSE_PRIVATE:
9083 flags = GOVD_PRIVATE | GOVD_EXPLICIT;
9084 if (lang_hooks.decls.omp_private_outer_ref (OMP_CLAUSE_DECL (c)))
9086 flags |= GOVD_PRIVATE_OUTER_REF;
9087 OMP_CLAUSE_PRIVATE_OUTER_REF (c) = 1;
9089 else
9090 notice_outer = false;
9091 goto do_add;
9092 case OMP_CLAUSE_SHARED:
9093 flags = GOVD_SHARED | GOVD_EXPLICIT;
9094 goto do_add;
9095 case OMP_CLAUSE_FIRSTPRIVATE:
9096 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
9097 check_non_private = "firstprivate";
9098 if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c))
9100 gcc_assert (code == OMP_TARGET);
9101 flags |= GOVD_FIRSTPRIVATE_IMPLICIT;
9103 goto do_add;
9104 case OMP_CLAUSE_LASTPRIVATE:
9105 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
9106 switch (code)
9108 case OMP_DISTRIBUTE:
9109 error_at (OMP_CLAUSE_LOCATION (c),
9110 "conditional %<lastprivate%> clause on "
9111 "%qs construct", "distribute");
9112 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
9113 break;
9114 case OMP_TASKLOOP:
9115 error_at (OMP_CLAUSE_LOCATION (c),
9116 "conditional %<lastprivate%> clause on "
9117 "%qs construct", "taskloop");
9118 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
9119 break;
9120 default:
9121 break;
9123 flags = GOVD_LASTPRIVATE | GOVD_SEEN | GOVD_EXPLICIT;
9124 if (code != OMP_LOOP)
9125 check_non_private = "lastprivate";
9126 decl = OMP_CLAUSE_DECL (c);
9127 if (error_operand_p (decl))
9128 goto do_add;
9129 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)
9130 && !lang_hooks.decls.omp_scalar_p (decl, true))
9132 error_at (OMP_CLAUSE_LOCATION (c),
9133 "non-scalar variable %qD in conditional "
9134 "%<lastprivate%> clause", decl);
9135 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
9137 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
9138 flags |= GOVD_LASTPRIVATE_CONDITIONAL;
9139 omp_lastprivate_for_combined_outer_constructs (outer_ctx, decl,
9140 false);
9141 goto do_add;
9142 case OMP_CLAUSE_REDUCTION:
9143 if (OMP_CLAUSE_REDUCTION_TASK (c))
9145 if (region_type == ORT_WORKSHARE || code == OMP_SCOPE)
9147 if (nowait == -1)
9148 nowait = omp_find_clause (*list_p,
9149 OMP_CLAUSE_NOWAIT) != NULL_TREE;
9150 if (nowait
9151 && (outer_ctx == NULL
9152 || outer_ctx->region_type != ORT_COMBINED_PARALLEL))
9154 error_at (OMP_CLAUSE_LOCATION (c),
9155 "%<task%> reduction modifier on a construct "
9156 "with a %<nowait%> clause");
9157 OMP_CLAUSE_REDUCTION_TASK (c) = 0;
9160 else if ((region_type & ORT_PARALLEL) != ORT_PARALLEL)
9162 error_at (OMP_CLAUSE_LOCATION (c),
9163 "invalid %<task%> reduction modifier on construct "
9164 "other than %<parallel%>, %qs, %<sections%> or "
9165 "%<scope%>", lang_GNU_Fortran () ? "do" : "for");
9166 OMP_CLAUSE_REDUCTION_TASK (c) = 0;
9169 if (OMP_CLAUSE_REDUCTION_INSCAN (c))
9170 switch (code)
9172 case OMP_SECTIONS:
9173 error_at (OMP_CLAUSE_LOCATION (c),
9174 "%<inscan%> %<reduction%> clause on "
9175 "%qs construct", "sections");
9176 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
9177 break;
9178 case OMP_PARALLEL:
9179 error_at (OMP_CLAUSE_LOCATION (c),
9180 "%<inscan%> %<reduction%> clause on "
9181 "%qs construct", "parallel");
9182 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
9183 break;
9184 case OMP_TEAMS:
9185 error_at (OMP_CLAUSE_LOCATION (c),
9186 "%<inscan%> %<reduction%> clause on "
9187 "%qs construct", "teams");
9188 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
9189 break;
9190 case OMP_TASKLOOP:
9191 error_at (OMP_CLAUSE_LOCATION (c),
9192 "%<inscan%> %<reduction%> clause on "
9193 "%qs construct", "taskloop");
9194 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
9195 break;
9196 case OMP_SCOPE:
9197 error_at (OMP_CLAUSE_LOCATION (c),
9198 "%<inscan%> %<reduction%> clause on "
9199 "%qs construct", "scope");
9200 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
9201 break;
9202 default:
9203 break;
9205 /* FALLTHRU */
9206 case OMP_CLAUSE_IN_REDUCTION:
9207 case OMP_CLAUSE_TASK_REDUCTION:
9208 flags = GOVD_REDUCTION | GOVD_SEEN | GOVD_EXPLICIT;
9209 /* OpenACC permits reductions on private variables. */
9210 if (!(region_type & ORT_ACC)
9211 /* taskgroup is actually not a worksharing region. */
9212 && code != OMP_TASKGROUP)
9213 check_non_private = omp_clause_code_name[OMP_CLAUSE_CODE (c)];
9214 decl = OMP_CLAUSE_DECL (c);
9215 if (TREE_CODE (decl) == MEM_REF)
9217 tree type = TREE_TYPE (decl);
9218 bool saved_into_ssa = gimplify_ctxp->into_ssa;
9219 gimplify_ctxp->into_ssa = false;
9220 if (gimplify_expr (&TYPE_MAX_VALUE (TYPE_DOMAIN (type)), pre_p,
9221 NULL, is_gimple_val, fb_rvalue, false)
9222 == GS_ERROR)
9224 gimplify_ctxp->into_ssa = saved_into_ssa;
9225 remove = true;
9226 break;
9228 gimplify_ctxp->into_ssa = saved_into_ssa;
9229 tree v = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
9230 if (DECL_P (v))
9232 omp_firstprivatize_variable (ctx, v);
9233 omp_notice_variable (ctx, v, true);
9235 decl = TREE_OPERAND (decl, 0);
9236 if (TREE_CODE (decl) == POINTER_PLUS_EXPR)
9238 gimplify_ctxp->into_ssa = false;
9239 if (gimplify_expr (&TREE_OPERAND (decl, 1), pre_p,
9240 NULL, is_gimple_val, fb_rvalue, false)
9241 == GS_ERROR)
9243 gimplify_ctxp->into_ssa = saved_into_ssa;
9244 remove = true;
9245 break;
9247 gimplify_ctxp->into_ssa = saved_into_ssa;
9248 v = TREE_OPERAND (decl, 1);
9249 if (DECL_P (v))
9251 omp_firstprivatize_variable (ctx, v);
9252 omp_notice_variable (ctx, v, true);
9254 decl = TREE_OPERAND (decl, 0);
9256 if (TREE_CODE (decl) == ADDR_EXPR
9257 || TREE_CODE (decl) == INDIRECT_REF)
9258 decl = TREE_OPERAND (decl, 0);
9260 goto do_add_decl;
9261 case OMP_CLAUSE_LINEAR:
9262 if (gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c), pre_p, NULL,
9263 is_gimple_val, fb_rvalue) == GS_ERROR)
9265 remove = true;
9266 break;
9268 else
9270 if (code == OMP_SIMD
9271 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
9273 struct gimplify_omp_ctx *octx = outer_ctx;
9274 if (octx
9275 && octx->region_type == ORT_WORKSHARE
9276 && octx->combined_loop
9277 && !octx->distribute)
9279 if (octx->outer_context
9280 && (octx->outer_context->region_type
9281 == ORT_COMBINED_PARALLEL))
9282 octx = octx->outer_context->outer_context;
9283 else
9284 octx = octx->outer_context;
9286 if (octx
9287 && octx->region_type == ORT_WORKSHARE
9288 && octx->combined_loop
9289 && octx->distribute)
9291 error_at (OMP_CLAUSE_LOCATION (c),
9292 "%<linear%> clause for variable other than "
9293 "loop iterator specified on construct "
9294 "combined with %<distribute%>");
9295 remove = true;
9296 break;
9299 /* For combined #pragma omp parallel for simd, need to put
9300 lastprivate and perhaps firstprivate too on the
9301 parallel. Similarly for #pragma omp for simd. */
9302 struct gimplify_omp_ctx *octx = outer_ctx;
9303 bool taskloop_seen = false;
9304 decl = NULL_TREE;
9307 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
9308 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
9309 break;
9310 decl = OMP_CLAUSE_DECL (c);
9311 if (error_operand_p (decl))
9313 decl = NULL_TREE;
9314 break;
9316 flags = GOVD_SEEN;
9317 if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c))
9318 flags |= GOVD_FIRSTPRIVATE;
9319 if (!OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
9320 flags |= GOVD_LASTPRIVATE;
9321 if (octx
9322 && octx->region_type == ORT_WORKSHARE
9323 && octx->combined_loop)
9325 if (octx->outer_context
9326 && (octx->outer_context->region_type
9327 == ORT_COMBINED_PARALLEL))
9328 octx = octx->outer_context;
9329 else if (omp_check_private (octx, decl, false))
9330 break;
9332 else if (octx
9333 && (octx->region_type & ORT_TASK) != 0
9334 && octx->combined_loop)
9335 taskloop_seen = true;
9336 else if (octx
9337 && octx->region_type == ORT_COMBINED_PARALLEL
9338 && ((ctx->region_type == ORT_WORKSHARE
9339 && octx == outer_ctx)
9340 || taskloop_seen))
9341 flags = GOVD_SEEN | GOVD_SHARED;
9342 else if (octx
9343 && ((octx->region_type & ORT_COMBINED_TEAMS)
9344 == ORT_COMBINED_TEAMS))
9345 flags = GOVD_SEEN | GOVD_SHARED;
9346 else if (octx
9347 && octx->region_type == ORT_COMBINED_TARGET)
9349 if (flags & GOVD_LASTPRIVATE)
9350 flags = GOVD_SEEN | GOVD_MAP;
9352 else
9353 break;
9354 splay_tree_node on
9355 = splay_tree_lookup (octx->variables,
9356 (splay_tree_key) decl);
9357 if (on && (on->value & GOVD_DATA_SHARE_CLASS) != 0)
9359 octx = NULL;
9360 break;
9362 omp_add_variable (octx, decl, flags);
9363 if (octx->outer_context == NULL)
9364 break;
9365 octx = octx->outer_context;
9367 while (1);
9368 if (octx
9369 && decl
9370 && (!OMP_CLAUSE_LINEAR_NO_COPYIN (c)
9371 || !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
9372 omp_notice_variable (octx, decl, true);
9374 flags = GOVD_LINEAR | GOVD_EXPLICIT;
9375 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
9376 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
9378 notice_outer = false;
9379 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
9381 goto do_add;
9383 case OMP_CLAUSE_MAP:
9384 decl = OMP_CLAUSE_DECL (c);
9385 if (error_operand_p (decl))
9386 remove = true;
9387 switch (code)
9389 case OMP_TARGET:
9390 break;
9391 case OACC_DATA:
9392 if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
9393 break;
9394 /* FALLTHRU */
9395 case OMP_TARGET_DATA:
9396 case OMP_TARGET_ENTER_DATA:
9397 case OMP_TARGET_EXIT_DATA:
9398 case OACC_ENTER_DATA:
9399 case OACC_EXIT_DATA:
9400 case OACC_HOST_DATA:
9401 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
9402 || (OMP_CLAUSE_MAP_KIND (c)
9403 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
9404 /* For target {,enter ,exit }data only the array slice is
9405 mapped, but not the pointer to it. */
9406 remove = true;
9407 break;
9408 default:
9409 break;
9411 /* For Fortran, not only the pointer to the data is mapped but also
9412 the address of the pointer, the array descriptor etc.; for
9413 'exit data' - and in particular for 'delete:' - having an 'alloc:'
9414 does not make sense. Likewise, for 'update' only transferring the
9415 data itself is needed as the rest has been handled in previous
9416 directives. However, for 'exit data', the array descriptor needs
9417 to be delete; hence, we turn the MAP_TO_PSET into a MAP_DELETE.
9419 NOTE: Generally, it is not safe to perform "enter data" operations
9420 on arrays where the data *or the descriptor* may go out of scope
9421 before a corresponding "exit data" operation -- and such a
9422 descriptor may be synthesized temporarily, e.g. to pass an
9423 explicit-shape array to a function expecting an assumed-shape
9424 argument. Performing "enter data" inside the called function
9425 would thus be problematic. */
9426 if (code == OMP_TARGET_EXIT_DATA
9427 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_TO_PSET)
9428 OMP_CLAUSE_SET_MAP_KIND (c, OMP_CLAUSE_MAP_KIND (*prev_list_p)
9429 == GOMP_MAP_DELETE
9430 ? GOMP_MAP_DELETE : GOMP_MAP_RELEASE);
9431 else if ((code == OMP_TARGET_EXIT_DATA || code == OMP_TARGET_UPDATE)
9432 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
9433 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_TO_PSET))
9434 remove = true;
9436 if (remove)
9437 break;
9438 if (DECL_P (decl) && outer_ctx && (region_type & ORT_ACC))
9440 struct gimplify_omp_ctx *octx;
9441 for (octx = outer_ctx; octx; octx = octx->outer_context)
9443 if (octx->region_type != ORT_ACC_HOST_DATA)
9444 break;
9445 splay_tree_node n2
9446 = splay_tree_lookup (octx->variables,
9447 (splay_tree_key) decl);
9448 if (n2)
9449 error_at (OMP_CLAUSE_LOCATION (c), "variable %qE "
9450 "declared in enclosing %<host_data%> region",
9451 DECL_NAME (decl));
9454 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
9455 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
9456 : TYPE_SIZE_UNIT (TREE_TYPE (decl));
9457 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
9458 NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
9460 remove = true;
9461 break;
9463 else if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
9464 || (OMP_CLAUSE_MAP_KIND (c)
9465 == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
9466 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
9467 && TREE_CODE (OMP_CLAUSE_SIZE (c)) != INTEGER_CST)
9469 OMP_CLAUSE_SIZE (c)
9470 = get_initialized_tmp_var (OMP_CLAUSE_SIZE (c), pre_p, NULL,
9471 false);
9472 if ((region_type & ORT_TARGET) != 0)
9473 omp_add_variable (ctx, OMP_CLAUSE_SIZE (c),
9474 GOVD_FIRSTPRIVATE | GOVD_SEEN);
9477 if (TREE_CODE (decl) == TARGET_EXPR)
9479 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
9480 is_gimple_lvalue, fb_lvalue)
9481 == GS_ERROR)
9482 remove = true;
9484 else if (!DECL_P (decl))
9486 tree d = decl, *pd;
9487 if (TREE_CODE (d) == ARRAY_REF)
9489 while (TREE_CODE (d) == ARRAY_REF)
9490 d = TREE_OPERAND (d, 0);
9491 if (TREE_CODE (d) == COMPONENT_REF
9492 && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE)
9493 decl = d;
9495 pd = &OMP_CLAUSE_DECL (c);
9496 if (d == decl
9497 && TREE_CODE (decl) == INDIRECT_REF
9498 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
9499 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
9500 == REFERENCE_TYPE)
9501 && (OMP_CLAUSE_MAP_KIND (c)
9502 != GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION))
9504 pd = &TREE_OPERAND (decl, 0);
9505 decl = TREE_OPERAND (decl, 0);
9507 bool indir_p = false;
9508 bool component_ref_p = false;
9509 tree indir_base = NULL_TREE;
9510 tree orig_decl = decl;
9511 tree decl_ref = NULL_TREE;
9512 if ((region_type & (ORT_ACC | ORT_TARGET | ORT_TARGET_DATA)) != 0
9513 && TREE_CODE (*pd) == COMPONENT_REF
9514 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH
9515 && code != OACC_UPDATE)
9517 while (TREE_CODE (decl) == COMPONENT_REF)
9519 decl = TREE_OPERAND (decl, 0);
9520 component_ref_p = true;
9521 if (((TREE_CODE (decl) == MEM_REF
9522 && integer_zerop (TREE_OPERAND (decl, 1)))
9523 || INDIRECT_REF_P (decl))
9524 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
9525 == POINTER_TYPE))
9527 indir_p = true;
9528 indir_base = decl;
9529 decl = TREE_OPERAND (decl, 0);
9530 STRIP_NOPS (decl);
9532 if (TREE_CODE (decl) == INDIRECT_REF
9533 && DECL_P (TREE_OPERAND (decl, 0))
9534 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
9535 == REFERENCE_TYPE))
9537 decl_ref = decl;
9538 decl = TREE_OPERAND (decl, 0);
9542 else if (TREE_CODE (decl) == COMPONENT_REF
9543 && (OMP_CLAUSE_MAP_KIND (c)
9544 != GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION))
9546 component_ref_p = true;
9547 while (TREE_CODE (decl) == COMPONENT_REF)
9548 decl = TREE_OPERAND (decl, 0);
9549 if (TREE_CODE (decl) == INDIRECT_REF
9550 && DECL_P (TREE_OPERAND (decl, 0))
9551 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
9552 == REFERENCE_TYPE))
9553 decl = TREE_OPERAND (decl, 0);
9555 if (decl != orig_decl && DECL_P (decl) && indir_p
9556 && (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
9557 || (decl_ref
9558 && TREE_CODE (TREE_TYPE (decl_ref)) == POINTER_TYPE)))
9560 gomp_map_kind k
9561 = ((code == OACC_EXIT_DATA || code == OMP_TARGET_EXIT_DATA)
9562 ? GOMP_MAP_DETACH : GOMP_MAP_ATTACH);
9563 /* We have a dereference of a struct member. Make this an
9564 attach/detach operation, and ensure the base pointer is
9565 mapped as a FIRSTPRIVATE_POINTER. */
9566 OMP_CLAUSE_SET_MAP_KIND (c, k);
9567 flags = GOVD_MAP | GOVD_SEEN | GOVD_EXPLICIT;
9568 tree next_clause = OMP_CLAUSE_CHAIN (c);
9569 if (k == GOMP_MAP_ATTACH
9570 && code != OACC_ENTER_DATA
9571 && code != OMP_TARGET_ENTER_DATA
9572 && (!next_clause
9573 || (OMP_CLAUSE_CODE (next_clause) != OMP_CLAUSE_MAP)
9574 || (OMP_CLAUSE_MAP_KIND (next_clause)
9575 != GOMP_MAP_POINTER)
9576 || OMP_CLAUSE_DECL (next_clause) != decl)
9577 && (!struct_deref_set
9578 || !struct_deref_set->contains (decl))
9579 && (!struct_map_to_clause
9580 || !struct_map_to_clause->get (indir_base)))
9582 if (!struct_deref_set)
9583 struct_deref_set = new hash_set<tree> ();
9584 /* As well as the attach, we also need a
9585 FIRSTPRIVATE_POINTER clause to properly map the
9586 pointer to the struct base. */
9587 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9588 OMP_CLAUSE_MAP);
9589 OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_ALLOC);
9590 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (c2)
9591 = 1;
9592 tree charptr_zero
9593 = build_int_cst (build_pointer_type (char_type_node),
9595 OMP_CLAUSE_DECL (c2)
9596 = build2 (MEM_REF, char_type_node,
9597 decl_ref ? decl_ref : decl, charptr_zero);
9598 OMP_CLAUSE_SIZE (c2) = size_zero_node;
9599 tree c3 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9600 OMP_CLAUSE_MAP);
9601 OMP_CLAUSE_SET_MAP_KIND (c3,
9602 GOMP_MAP_FIRSTPRIVATE_POINTER);
9603 OMP_CLAUSE_DECL (c3) = decl;
9604 OMP_CLAUSE_SIZE (c3) = size_zero_node;
9605 tree mapgrp = *prev_list_p;
9606 *prev_list_p = c2;
9607 OMP_CLAUSE_CHAIN (c3) = mapgrp;
9608 OMP_CLAUSE_CHAIN (c2) = c3;
9610 struct_deref_set->add (decl);
9612 goto do_add_decl;
9614 /* An "attach/detach" operation on an update directive should
9615 behave as a GOMP_MAP_ALWAYS_POINTER. Beware that
9616 unlike attach or detach map kinds, GOMP_MAP_ALWAYS_POINTER
9617 depends on the previous mapping. */
9618 if (code == OACC_UPDATE
9619 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
9620 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_ALWAYS_POINTER);
9621 if ((DECL_P (decl)
9622 || (component_ref_p
9623 && (INDIRECT_REF_P (decl)
9624 || TREE_CODE (decl) == MEM_REF
9625 || TREE_CODE (decl) == ARRAY_REF)))
9626 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_TO_PSET
9627 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH
9628 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_DETACH
9629 && code != OACC_UPDATE
9630 && code != OMP_TARGET_UPDATE)
9632 if (error_operand_p (decl))
9634 remove = true;
9635 break;
9638 tree stype = TREE_TYPE (decl);
9639 if (TREE_CODE (stype) == REFERENCE_TYPE)
9640 stype = TREE_TYPE (stype);
9641 if (TYPE_SIZE_UNIT (stype) == NULL
9642 || TREE_CODE (TYPE_SIZE_UNIT (stype)) != INTEGER_CST)
9644 error_at (OMP_CLAUSE_LOCATION (c),
9645 "mapping field %qE of variable length "
9646 "structure", OMP_CLAUSE_DECL (c));
9647 remove = true;
9648 break;
9651 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER
9652 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
9654 /* Error recovery. */
9655 if (prev_list_p == NULL)
9657 remove = true;
9658 break;
9661 /* The below prev_list_p based error recovery code is
9662 currently no longer valid for OpenMP. */
9663 if (code != OMP_TARGET
9664 && code != OMP_TARGET_DATA
9665 && code != OMP_TARGET_UPDATE
9666 && code != OMP_TARGET_ENTER_DATA
9667 && code != OMP_TARGET_EXIT_DATA
9668 && OMP_CLAUSE_CHAIN (*prev_list_p) != c)
9670 tree ch = OMP_CLAUSE_CHAIN (*prev_list_p);
9671 if (ch == NULL_TREE || OMP_CLAUSE_CHAIN (ch) != c)
9673 remove = true;
9674 break;
9679 poly_offset_int offset1;
9680 poly_int64 bitpos1;
9681 tree tree_offset1;
9682 tree base_ref;
9684 tree base
9685 = extract_base_bit_offset (OMP_CLAUSE_DECL (c), &base_ref,
9686 &bitpos1, &offset1,
9687 &tree_offset1);
9689 bool do_map_struct = (base == decl && !tree_offset1);
9691 splay_tree_node n
9692 = (DECL_P (decl)
9693 ? splay_tree_lookup (ctx->variables,
9694 (splay_tree_key) decl)
9695 : NULL);
9696 bool ptr = (OMP_CLAUSE_MAP_KIND (c)
9697 == GOMP_MAP_ALWAYS_POINTER);
9698 bool attach_detach = (OMP_CLAUSE_MAP_KIND (c)
9699 == GOMP_MAP_ATTACH_DETACH);
9700 bool attach = OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
9701 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH;
9702 bool has_attachments = false;
9703 /* For OpenACC, pointers in structs should trigger an
9704 attach action. */
9705 if (attach_detach
9706 && ((region_type & (ORT_ACC | ORT_TARGET | ORT_TARGET_DATA))
9707 || code == OMP_TARGET_ENTER_DATA
9708 || code == OMP_TARGET_EXIT_DATA))
9711 /* Turn a GOMP_MAP_ATTACH_DETACH clause into a
9712 GOMP_MAP_ATTACH or GOMP_MAP_DETACH clause after we
9713 have detected a case that needs a GOMP_MAP_STRUCT
9714 mapping added. */
9715 gomp_map_kind k
9716 = ((code == OACC_EXIT_DATA || code == OMP_TARGET_EXIT_DATA)
9717 ? GOMP_MAP_DETACH : GOMP_MAP_ATTACH);
9718 OMP_CLAUSE_SET_MAP_KIND (c, k);
9719 has_attachments = true;
9722 /* We currently don't handle non-constant offset accesses wrt to
9723 GOMP_MAP_STRUCT elements. */
9724 if (!do_map_struct)
9725 goto skip_map_struct;
9727 /* Nor for attach_detach for OpenMP. */
9728 if ((code == OMP_TARGET
9729 || code == OMP_TARGET_DATA
9730 || code == OMP_TARGET_UPDATE
9731 || code == OMP_TARGET_ENTER_DATA
9732 || code == OMP_TARGET_EXIT_DATA)
9733 && attach_detach)
9735 if (DECL_P (decl))
9737 if (struct_seen_clause == NULL)
9738 struct_seen_clause
9739 = new hash_map<tree_operand_hash, tree *>;
9740 if (!struct_seen_clause->get (decl))
9741 struct_seen_clause->put (decl, list_p);
9744 goto skip_map_struct;
9747 if ((DECL_P (decl)
9748 && (n == NULL || (n->value & GOVD_MAP) == 0))
9749 || (!DECL_P (decl)
9750 && (!struct_map_to_clause
9751 || struct_map_to_clause->get (decl) == NULL)))
9753 tree l = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9754 OMP_CLAUSE_MAP);
9755 gomp_map_kind k = attach ? GOMP_MAP_FORCE_PRESENT
9756 : GOMP_MAP_STRUCT;
9758 OMP_CLAUSE_SET_MAP_KIND (l, k);
9759 if (base_ref)
9760 OMP_CLAUSE_DECL (l) = unshare_expr (base_ref);
9761 else
9763 OMP_CLAUSE_DECL (l) = unshare_expr (decl);
9764 if (!DECL_P (OMP_CLAUSE_DECL (l))
9765 && (gimplify_expr (&OMP_CLAUSE_DECL (l),
9766 pre_p, NULL, is_gimple_lvalue,
9767 fb_lvalue)
9768 == GS_ERROR))
9770 remove = true;
9771 break;
9774 OMP_CLAUSE_SIZE (l)
9775 = (!attach
9776 ? size_int (1)
9777 : DECL_P (OMP_CLAUSE_DECL (l))
9778 ? DECL_SIZE_UNIT (OMP_CLAUSE_DECL (l))
9779 : TYPE_SIZE_UNIT (TREE_TYPE (OMP_CLAUSE_DECL (l))));
9780 if (struct_map_to_clause == NULL)
9781 struct_map_to_clause
9782 = new hash_map<tree_operand_hash, tree>;
9783 struct_map_to_clause->put (decl, l);
9784 if (ptr || attach_detach)
9786 tree **sc = (struct_seen_clause
9787 ? struct_seen_clause->get (decl)
9788 : NULL);
9789 tree *insert_node_pos = sc ? *sc : prev_list_p;
9791 insert_struct_comp_map (code, c, l, *insert_node_pos,
9792 NULL);
9793 *insert_node_pos = l;
9794 prev_list_p = NULL;
9796 else
9798 OMP_CLAUSE_CHAIN (l) = c;
9799 *list_p = l;
9800 list_p = &OMP_CLAUSE_CHAIN (l);
9802 if (base_ref && code == OMP_TARGET)
9804 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9805 OMP_CLAUSE_MAP);
9806 enum gomp_map_kind mkind
9807 = GOMP_MAP_FIRSTPRIVATE_REFERENCE;
9808 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
9809 OMP_CLAUSE_DECL (c2) = decl;
9810 OMP_CLAUSE_SIZE (c2) = size_zero_node;
9811 OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (l);
9812 OMP_CLAUSE_CHAIN (l) = c2;
9814 flags = GOVD_MAP | GOVD_EXPLICIT;
9815 if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c))
9816 || ptr
9817 || attach_detach)
9818 flags |= GOVD_SEEN;
9819 if (has_attachments)
9820 flags |= GOVD_MAP_HAS_ATTACHMENTS;
9822 /* If this is a *pointer-to-struct expression, make sure a
9823 firstprivate map of the base-pointer exists. */
9824 if (component_ref_p
9825 && ((TREE_CODE (decl) == MEM_REF
9826 && integer_zerop (TREE_OPERAND (decl, 1)))
9827 || INDIRECT_REF_P (decl))
9828 && DECL_P (TREE_OPERAND (decl, 0))
9829 && !splay_tree_lookup (ctx->variables,
9830 ((splay_tree_key)
9831 TREE_OPERAND (decl, 0))))
9833 decl = TREE_OPERAND (decl, 0);
9834 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9835 OMP_CLAUSE_MAP);
9836 enum gomp_map_kind mkind
9837 = GOMP_MAP_FIRSTPRIVATE_POINTER;
9838 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
9839 OMP_CLAUSE_DECL (c2) = decl;
9840 OMP_CLAUSE_SIZE (c2) = size_zero_node;
9841 OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (c);
9842 OMP_CLAUSE_CHAIN (c) = c2;
9845 if (DECL_P (decl))
9846 goto do_add_decl;
9848 else if (struct_map_to_clause)
9850 tree *osc = struct_map_to_clause->get (decl);
9851 tree *sc = NULL, *scp = NULL;
9852 if (n != NULL
9853 && (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c))
9854 || ptr
9855 || attach_detach))
9856 n->value |= GOVD_SEEN;
9857 sc = &OMP_CLAUSE_CHAIN (*osc);
9858 if (*sc != c
9859 && (OMP_CLAUSE_MAP_KIND (*sc)
9860 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
9861 sc = &OMP_CLAUSE_CHAIN (*sc);
9862 /* Here "prev_list_p" is the end of the inserted
9863 alloc/release nodes after the struct node, OSC. */
9864 for (; *sc != c; sc = &OMP_CLAUSE_CHAIN (*sc))
9865 if ((ptr || attach_detach) && sc == prev_list_p)
9866 break;
9867 else if (TREE_CODE (OMP_CLAUSE_DECL (*sc))
9868 != COMPONENT_REF
9869 && (TREE_CODE (OMP_CLAUSE_DECL (*sc))
9870 != INDIRECT_REF)
9871 && (TREE_CODE (OMP_CLAUSE_DECL (*sc))
9872 != ARRAY_REF))
9873 break;
9874 else
9876 tree sc_decl = OMP_CLAUSE_DECL (*sc);
9877 poly_offset_int offsetn;
9878 poly_int64 bitposn;
9879 tree tree_offsetn;
9880 tree base
9881 = extract_base_bit_offset (sc_decl, NULL,
9882 &bitposn, &offsetn,
9883 &tree_offsetn);
9884 if (base != decl)
9885 break;
9886 if (scp)
9887 continue;
9888 if ((region_type & ORT_ACC) != 0)
9890 /* This duplicate checking code is currently only
9891 enabled for OpenACC. */
9892 tree d1 = OMP_CLAUSE_DECL (*sc);
9893 tree d2 = OMP_CLAUSE_DECL (c);
9894 while (TREE_CODE (d1) == ARRAY_REF)
9895 d1 = TREE_OPERAND (d1, 0);
9896 while (TREE_CODE (d2) == ARRAY_REF)
9897 d2 = TREE_OPERAND (d2, 0);
9898 if (TREE_CODE (d1) == INDIRECT_REF)
9899 d1 = TREE_OPERAND (d1, 0);
9900 if (TREE_CODE (d2) == INDIRECT_REF)
9901 d2 = TREE_OPERAND (d2, 0);
9902 while (TREE_CODE (d1) == COMPONENT_REF)
9903 if (TREE_CODE (d2) == COMPONENT_REF
9904 && TREE_OPERAND (d1, 1)
9905 == TREE_OPERAND (d2, 1))
9907 d1 = TREE_OPERAND (d1, 0);
9908 d2 = TREE_OPERAND (d2, 0);
9910 else
9911 break;
9912 if (d1 == d2)
9914 error_at (OMP_CLAUSE_LOCATION (c),
9915 "%qE appears more than once in map "
9916 "clauses", OMP_CLAUSE_DECL (c));
9917 remove = true;
9918 break;
9921 if (maybe_lt (offset1, offsetn)
9922 || (known_eq (offset1, offsetn)
9923 && maybe_lt (bitpos1, bitposn)))
9925 if (ptr || attach_detach)
9926 scp = sc;
9927 else
9928 break;
9931 if (remove)
9932 break;
9933 if (!attach)
9934 OMP_CLAUSE_SIZE (*osc)
9935 = size_binop (PLUS_EXPR, OMP_CLAUSE_SIZE (*osc),
9936 size_one_node);
9937 if (ptr || attach_detach)
9939 tree cl = insert_struct_comp_map (code, c, NULL,
9940 *prev_list_p, scp);
9941 if (sc == prev_list_p)
9943 *sc = cl;
9944 prev_list_p = NULL;
9946 else
9948 *prev_list_p = OMP_CLAUSE_CHAIN (c);
9949 list_p = prev_list_p;
9950 prev_list_p = NULL;
9951 OMP_CLAUSE_CHAIN (c) = *sc;
9952 *sc = cl;
9953 continue;
9956 else if (*sc != c)
9958 if (gimplify_expr (pd, pre_p, NULL, is_gimple_lvalue,
9959 fb_lvalue)
9960 == GS_ERROR)
9962 remove = true;
9963 break;
9965 *list_p = OMP_CLAUSE_CHAIN (c);
9966 OMP_CLAUSE_CHAIN (c) = *sc;
9967 *sc = c;
9968 continue;
9971 skip_map_struct:
9974 else if ((code == OACC_ENTER_DATA
9975 || code == OACC_EXIT_DATA
9976 || code == OACC_DATA
9977 || code == OACC_PARALLEL
9978 || code == OACC_KERNELS
9979 || code == OACC_SERIAL
9980 || code == OMP_TARGET_ENTER_DATA
9981 || code == OMP_TARGET_EXIT_DATA)
9982 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
9984 gomp_map_kind k = ((code == OACC_EXIT_DATA
9985 || code == OMP_TARGET_EXIT_DATA)
9986 ? GOMP_MAP_DETACH : GOMP_MAP_ATTACH);
9987 OMP_CLAUSE_SET_MAP_KIND (c, k);
9990 if (code == OMP_TARGET && OMP_CLAUSE_MAP_IN_REDUCTION (c))
9992 /* Don't gimplify *pd fully at this point, as the base
9993 will need to be adjusted during omp lowering. */
9994 auto_vec<tree, 10> expr_stack;
9995 tree *p = pd;
9996 while (handled_component_p (*p)
9997 || TREE_CODE (*p) == INDIRECT_REF
9998 || TREE_CODE (*p) == ADDR_EXPR
9999 || TREE_CODE (*p) == MEM_REF
10000 || TREE_CODE (*p) == NON_LVALUE_EXPR)
10002 expr_stack.safe_push (*p);
10003 p = &TREE_OPERAND (*p, 0);
10005 for (int i = expr_stack.length () - 1; i >= 0; i--)
10007 tree t = expr_stack[i];
10008 if (TREE_CODE (t) == ARRAY_REF
10009 || TREE_CODE (t) == ARRAY_RANGE_REF)
10011 if (TREE_OPERAND (t, 2) == NULL_TREE)
10013 tree low = unshare_expr (array_ref_low_bound (t));
10014 if (!is_gimple_min_invariant (low))
10016 TREE_OPERAND (t, 2) = low;
10017 if (gimplify_expr (&TREE_OPERAND (t, 2),
10018 pre_p, NULL,
10019 is_gimple_reg,
10020 fb_rvalue) == GS_ERROR)
10021 remove = true;
10024 else if (gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
10025 NULL, is_gimple_reg,
10026 fb_rvalue) == GS_ERROR)
10027 remove = true;
10028 if (TREE_OPERAND (t, 3) == NULL_TREE)
10030 tree elmt_size = array_ref_element_size (t);
10031 if (!is_gimple_min_invariant (elmt_size))
10033 elmt_size = unshare_expr (elmt_size);
10034 tree elmt_type
10035 = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t,
10036 0)));
10037 tree factor
10038 = size_int (TYPE_ALIGN_UNIT (elmt_type));
10039 elmt_size
10040 = size_binop (EXACT_DIV_EXPR, elmt_size,
10041 factor);
10042 TREE_OPERAND (t, 3) = elmt_size;
10043 if (gimplify_expr (&TREE_OPERAND (t, 3),
10044 pre_p, NULL,
10045 is_gimple_reg,
10046 fb_rvalue) == GS_ERROR)
10047 remove = true;
10050 else if (gimplify_expr (&TREE_OPERAND (t, 3), pre_p,
10051 NULL, is_gimple_reg,
10052 fb_rvalue) == GS_ERROR)
10053 remove = true;
10055 else if (TREE_CODE (t) == COMPONENT_REF)
10057 if (TREE_OPERAND (t, 2) == NULL_TREE)
10059 tree offset = component_ref_field_offset (t);
10060 if (!is_gimple_min_invariant (offset))
10062 offset = unshare_expr (offset);
10063 tree field = TREE_OPERAND (t, 1);
10064 tree factor
10065 = size_int (DECL_OFFSET_ALIGN (field)
10066 / BITS_PER_UNIT);
10067 offset = size_binop (EXACT_DIV_EXPR, offset,
10068 factor);
10069 TREE_OPERAND (t, 2) = offset;
10070 if (gimplify_expr (&TREE_OPERAND (t, 2),
10071 pre_p, NULL,
10072 is_gimple_reg,
10073 fb_rvalue) == GS_ERROR)
10074 remove = true;
10077 else if (gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
10078 NULL, is_gimple_reg,
10079 fb_rvalue) == GS_ERROR)
10080 remove = true;
10083 for (; expr_stack.length () > 0; )
10085 tree t = expr_stack.pop ();
10087 if (TREE_CODE (t) == ARRAY_REF
10088 || TREE_CODE (t) == ARRAY_RANGE_REF)
10090 if (!is_gimple_min_invariant (TREE_OPERAND (t, 1))
10091 && gimplify_expr (&TREE_OPERAND (t, 1), pre_p,
10092 NULL, is_gimple_val,
10093 fb_rvalue) == GS_ERROR)
10094 remove = true;
10098 else if (gimplify_expr (pd, pre_p, NULL, is_gimple_lvalue,
10099 fb_lvalue) == GS_ERROR)
10101 remove = true;
10102 break;
10105 /* If this was of the form map(*pointer_to_struct), then the
10106 'pointer_to_struct' DECL should be considered deref'ed. */
10107 if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALLOC
10108 || GOMP_MAP_COPY_TO_P (OMP_CLAUSE_MAP_KIND (c))
10109 || GOMP_MAP_COPY_FROM_P (OMP_CLAUSE_MAP_KIND (c)))
10110 && INDIRECT_REF_P (orig_decl)
10111 && DECL_P (TREE_OPERAND (orig_decl, 0))
10112 && TREE_CODE (TREE_TYPE (orig_decl)) == RECORD_TYPE)
10114 tree ptr = TREE_OPERAND (orig_decl, 0);
10115 if (!struct_deref_set || !struct_deref_set->contains (ptr))
10117 if (!struct_deref_set)
10118 struct_deref_set = new hash_set<tree> ();
10119 struct_deref_set->add (ptr);
10123 if (!remove
10124 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_POINTER
10125 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH_DETACH
10126 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_TO_PSET
10127 && OMP_CLAUSE_CHAIN (c)
10128 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (c)) == OMP_CLAUSE_MAP
10129 && ((OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
10130 == GOMP_MAP_ALWAYS_POINTER)
10131 || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
10132 == GOMP_MAP_ATTACH_DETACH)
10133 || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
10134 == GOMP_MAP_TO_PSET)))
10135 prev_list_p = list_p;
10137 break;
10139 else
10141 /* DECL_P (decl) == true */
10142 tree *sc;
10143 if (struct_map_to_clause
10144 && (sc = struct_map_to_clause->get (decl)) != NULL
10145 && OMP_CLAUSE_MAP_KIND (*sc) == GOMP_MAP_STRUCT
10146 && decl == OMP_CLAUSE_DECL (*sc))
10148 /* We have found a map of the whole structure after a
10149 leading GOMP_MAP_STRUCT has been created, so refill the
10150 leading clause into a map of the whole structure
10151 variable, and remove the current one.
10152 TODO: we should be able to remove some maps of the
10153 following structure element maps if they are of
10154 compatible TO/FROM/ALLOC type. */
10155 OMP_CLAUSE_SET_MAP_KIND (*sc, OMP_CLAUSE_MAP_KIND (c));
10156 OMP_CLAUSE_SIZE (*sc) = unshare_expr (OMP_CLAUSE_SIZE (c));
10157 remove = true;
10158 break;
10161 flags = GOVD_MAP | GOVD_EXPLICIT;
10162 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TO
10163 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TOFROM)
10164 flags |= GOVD_MAP_ALWAYS_TO;
10166 if ((code == OMP_TARGET
10167 || code == OMP_TARGET_DATA
10168 || code == OMP_TARGET_ENTER_DATA
10169 || code == OMP_TARGET_EXIT_DATA)
10170 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
10172 for (struct gimplify_omp_ctx *octx = outer_ctx; octx;
10173 octx = octx->outer_context)
10175 splay_tree_node n
10176 = splay_tree_lookup (octx->variables,
10177 (splay_tree_key) OMP_CLAUSE_DECL (c));
10178 /* If this is contained in an outer OpenMP region as a
10179 firstprivate value, remove the attach/detach. */
10180 if (n && (n->value & GOVD_FIRSTPRIVATE))
10182 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FIRSTPRIVATE_POINTER);
10183 goto do_add;
10187 enum gomp_map_kind map_kind = (code == OMP_TARGET_EXIT_DATA
10188 ? GOMP_MAP_DETACH
10189 : GOMP_MAP_ATTACH);
10190 OMP_CLAUSE_SET_MAP_KIND (c, map_kind);
10193 goto do_add;
10195 case OMP_CLAUSE_AFFINITY:
10196 gimplify_omp_affinity (list_p, pre_p);
10197 remove = true;
10198 break;
10199 case OMP_CLAUSE_DEPEND:
10200 if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
10202 tree deps = OMP_CLAUSE_DECL (c);
10203 while (deps && TREE_CODE (deps) == TREE_LIST)
10205 if (TREE_CODE (TREE_PURPOSE (deps)) == TRUNC_DIV_EXPR
10206 && DECL_P (TREE_OPERAND (TREE_PURPOSE (deps), 1)))
10207 gimplify_expr (&TREE_OPERAND (TREE_PURPOSE (deps), 1),
10208 pre_p, NULL, is_gimple_val, fb_rvalue);
10209 deps = TREE_CHAIN (deps);
10211 break;
10213 else if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
10214 break;
10215 if (handled_depend_iterators == -1)
10216 handled_depend_iterators = gimplify_omp_depend (list_p, pre_p);
10217 if (handled_depend_iterators)
10219 if (handled_depend_iterators == 2)
10220 remove = true;
10221 break;
10223 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
10225 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
10226 NULL, is_gimple_val, fb_rvalue);
10227 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
10229 if (error_operand_p (OMP_CLAUSE_DECL (c)))
10231 remove = true;
10232 break;
10234 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
10235 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
10236 is_gimple_val, fb_rvalue) == GS_ERROR)
10238 remove = true;
10239 break;
10241 if (code == OMP_TASK)
10242 ctx->has_depend = true;
10243 break;
10245 case OMP_CLAUSE_TO:
10246 case OMP_CLAUSE_FROM:
10247 case OMP_CLAUSE__CACHE_:
10248 decl = OMP_CLAUSE_DECL (c);
10249 if (error_operand_p (decl))
10251 remove = true;
10252 break;
10254 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
10255 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
10256 : TYPE_SIZE_UNIT (TREE_TYPE (decl));
10257 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
10258 NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
10260 remove = true;
10261 break;
10263 if (!DECL_P (decl))
10265 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p,
10266 NULL, is_gimple_lvalue, fb_lvalue)
10267 == GS_ERROR)
10269 remove = true;
10270 break;
10272 break;
10274 goto do_notice;
10276 case OMP_CLAUSE_USE_DEVICE_PTR:
10277 case OMP_CLAUSE_USE_DEVICE_ADDR:
10278 flags = GOVD_EXPLICIT;
10279 goto do_add;
10281 case OMP_CLAUSE_IS_DEVICE_PTR:
10282 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
10283 goto do_add;
10285 do_add:
10286 decl = OMP_CLAUSE_DECL (c);
10287 do_add_decl:
10288 if (error_operand_p (decl))
10290 remove = true;
10291 break;
10293 if (DECL_NAME (decl) == NULL_TREE && (flags & GOVD_SHARED) == 0)
10295 tree t = omp_member_access_dummy_var (decl);
10296 if (t)
10298 tree v = DECL_VALUE_EXPR (decl);
10299 DECL_NAME (decl) = DECL_NAME (TREE_OPERAND (v, 1));
10300 if (outer_ctx)
10301 omp_notice_variable (outer_ctx, t, true);
10304 if (code == OACC_DATA
10305 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
10306 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
10307 flags |= GOVD_MAP_0LEN_ARRAY;
10308 omp_add_variable (ctx, decl, flags);
10309 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10310 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
10311 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
10312 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
10314 struct gimplify_omp_ctx *pctx
10315 = code == OMP_TARGET ? outer_ctx : ctx;
10316 if (pctx)
10317 omp_add_variable (pctx, OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
10318 GOVD_LOCAL | GOVD_SEEN);
10319 if (pctx
10320 && OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
10321 && walk_tree (&OMP_CLAUSE_REDUCTION_INIT (c),
10322 find_decl_expr,
10323 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
10324 NULL) == NULL_TREE)
10325 omp_add_variable (pctx,
10326 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
10327 GOVD_LOCAL | GOVD_SEEN);
10328 gimplify_omp_ctxp = pctx;
10329 push_gimplify_context ();
10331 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
10332 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
10334 gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c),
10335 &OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c));
10336 pop_gimplify_context
10337 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c)));
10338 push_gimplify_context ();
10339 gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c),
10340 &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
10341 pop_gimplify_context
10342 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c)));
10343 OMP_CLAUSE_REDUCTION_INIT (c) = NULL_TREE;
10344 OMP_CLAUSE_REDUCTION_MERGE (c) = NULL_TREE;
10346 gimplify_omp_ctxp = outer_ctx;
10348 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
10349 && OMP_CLAUSE_LASTPRIVATE_STMT (c))
10351 gimplify_omp_ctxp = ctx;
10352 push_gimplify_context ();
10353 if (TREE_CODE (OMP_CLAUSE_LASTPRIVATE_STMT (c)) != BIND_EXPR)
10355 tree bind = build3 (BIND_EXPR, void_type_node, NULL,
10356 NULL, NULL);
10357 TREE_SIDE_EFFECTS (bind) = 1;
10358 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LASTPRIVATE_STMT (c);
10359 OMP_CLAUSE_LASTPRIVATE_STMT (c) = bind;
10361 gimplify_and_add (OMP_CLAUSE_LASTPRIVATE_STMT (c),
10362 &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
10363 pop_gimplify_context
10364 (gimple_seq_first_stmt (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c)));
10365 OMP_CLAUSE_LASTPRIVATE_STMT (c) = NULL_TREE;
10367 gimplify_omp_ctxp = outer_ctx;
10369 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
10370 && OMP_CLAUSE_LINEAR_STMT (c))
10372 gimplify_omp_ctxp = ctx;
10373 push_gimplify_context ();
10374 if (TREE_CODE (OMP_CLAUSE_LINEAR_STMT (c)) != BIND_EXPR)
10376 tree bind = build3 (BIND_EXPR, void_type_node, NULL,
10377 NULL, NULL);
10378 TREE_SIDE_EFFECTS (bind) = 1;
10379 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LINEAR_STMT (c);
10380 OMP_CLAUSE_LINEAR_STMT (c) = bind;
10382 gimplify_and_add (OMP_CLAUSE_LINEAR_STMT (c),
10383 &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c));
10384 pop_gimplify_context
10385 (gimple_seq_first_stmt (OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c)));
10386 OMP_CLAUSE_LINEAR_STMT (c) = NULL_TREE;
10388 gimplify_omp_ctxp = outer_ctx;
10390 if (notice_outer)
10391 goto do_notice;
10392 break;
10394 case OMP_CLAUSE_COPYIN:
10395 case OMP_CLAUSE_COPYPRIVATE:
10396 decl = OMP_CLAUSE_DECL (c);
10397 if (error_operand_p (decl))
10399 remove = true;
10400 break;
10402 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_COPYPRIVATE
10403 && !remove
10404 && !omp_check_private (ctx, decl, true))
10406 remove = true;
10407 if (is_global_var (decl))
10409 if (DECL_THREAD_LOCAL_P (decl))
10410 remove = false;
10411 else if (DECL_HAS_VALUE_EXPR_P (decl))
10413 tree value = get_base_address (DECL_VALUE_EXPR (decl));
10415 if (value
10416 && DECL_P (value)
10417 && DECL_THREAD_LOCAL_P (value))
10418 remove = false;
10421 if (remove)
10422 error_at (OMP_CLAUSE_LOCATION (c),
10423 "copyprivate variable %qE is not threadprivate"
10424 " or private in outer context", DECL_NAME (decl));
10426 do_notice:
10427 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10428 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
10429 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
10430 && outer_ctx
10431 && ((region_type & ORT_TASKLOOP) == ORT_TASKLOOP
10432 || (region_type == ORT_WORKSHARE
10433 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10434 && (OMP_CLAUSE_REDUCTION_INSCAN (c)
10435 || code == OMP_LOOP)))
10436 && (outer_ctx->region_type == ORT_COMBINED_PARALLEL
10437 || (code == OMP_LOOP
10438 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10439 && ((outer_ctx->region_type & ORT_COMBINED_TEAMS)
10440 == ORT_COMBINED_TEAMS))))
10442 splay_tree_node on
10443 = splay_tree_lookup (outer_ctx->variables,
10444 (splay_tree_key)decl);
10445 if (on == NULL || (on->value & GOVD_DATA_SHARE_CLASS) == 0)
10447 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10448 && TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
10449 && (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
10450 || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
10451 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
10452 == POINTER_TYPE))))
10453 omp_firstprivatize_variable (outer_ctx, decl);
10454 else
10456 omp_add_variable (outer_ctx, decl,
10457 GOVD_SEEN | GOVD_SHARED);
10458 if (outer_ctx->outer_context)
10459 omp_notice_variable (outer_ctx->outer_context, decl,
10460 true);
10464 if (outer_ctx)
10465 omp_notice_variable (outer_ctx, decl, true);
10466 if (check_non_private
10467 && (region_type == ORT_WORKSHARE || code == OMP_SCOPE)
10468 && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
10469 || decl == OMP_CLAUSE_DECL (c)
10470 || (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
10471 && (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
10472 == ADDR_EXPR
10473 || (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
10474 == POINTER_PLUS_EXPR
10475 && (TREE_CODE (TREE_OPERAND (TREE_OPERAND
10476 (OMP_CLAUSE_DECL (c), 0), 0))
10477 == ADDR_EXPR)))))
10478 && omp_check_private (ctx, decl, false))
10480 error ("%s variable %qE is private in outer context",
10481 check_non_private, DECL_NAME (decl));
10482 remove = true;
10484 break;
10486 case OMP_CLAUSE_DETACH:
10487 flags = GOVD_FIRSTPRIVATE | GOVD_SEEN;
10488 goto do_add;
10490 case OMP_CLAUSE_IF:
10491 if (OMP_CLAUSE_IF_MODIFIER (c) != ERROR_MARK
10492 && OMP_CLAUSE_IF_MODIFIER (c) != code)
10494 const char *p[2];
10495 for (int i = 0; i < 2; i++)
10496 switch (i ? OMP_CLAUSE_IF_MODIFIER (c) : code)
10498 case VOID_CST: p[i] = "cancel"; break;
10499 case OMP_PARALLEL: p[i] = "parallel"; break;
10500 case OMP_SIMD: p[i] = "simd"; break;
10501 case OMP_TASK: p[i] = "task"; break;
10502 case OMP_TASKLOOP: p[i] = "taskloop"; break;
10503 case OMP_TARGET_DATA: p[i] = "target data"; break;
10504 case OMP_TARGET: p[i] = "target"; break;
10505 case OMP_TARGET_UPDATE: p[i] = "target update"; break;
10506 case OMP_TARGET_ENTER_DATA:
10507 p[i] = "target enter data"; break;
10508 case OMP_TARGET_EXIT_DATA: p[i] = "target exit data"; break;
10509 default: gcc_unreachable ();
10511 error_at (OMP_CLAUSE_LOCATION (c),
10512 "expected %qs %<if%> clause modifier rather than %qs",
10513 p[0], p[1]);
10514 remove = true;
10516 /* Fall through. */
10518 case OMP_CLAUSE_FINAL:
10519 OMP_CLAUSE_OPERAND (c, 0)
10520 = gimple_boolify (OMP_CLAUSE_OPERAND (c, 0));
10521 /* Fall through. */
10523 case OMP_CLAUSE_NUM_TEAMS:
10524 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
10525 && OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
10526 && !is_gimple_min_invariant (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)))
10528 if (error_operand_p (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)))
10530 remove = true;
10531 break;
10533 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
10534 = get_initialized_tmp_var (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c),
10535 pre_p, NULL, true);
10537 /* Fall through. */
10539 case OMP_CLAUSE_SCHEDULE:
10540 case OMP_CLAUSE_NUM_THREADS:
10541 case OMP_CLAUSE_THREAD_LIMIT:
10542 case OMP_CLAUSE_DIST_SCHEDULE:
10543 case OMP_CLAUSE_DEVICE:
10544 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE
10545 && OMP_CLAUSE_DEVICE_ANCESTOR (c))
10547 if (code != OMP_TARGET)
10549 error_at (OMP_CLAUSE_LOCATION (c),
10550 "%<device%> clause with %<ancestor%> is only "
10551 "allowed on %<target%> construct");
10552 remove = true;
10553 break;
10556 tree clauses = *orig_list_p;
10557 for (; clauses ; clauses = OMP_CLAUSE_CHAIN (clauses))
10558 if (OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_DEVICE
10559 && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_FIRSTPRIVATE
10560 && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_PRIVATE
10561 && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_DEFAULTMAP
10562 && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_MAP
10565 error_at (OMP_CLAUSE_LOCATION (c),
10566 "with %<ancestor%>, only the %<device%>, "
10567 "%<firstprivate%>, %<private%>, %<defaultmap%>, "
10568 "and %<map%> clauses may appear on the "
10569 "construct");
10570 remove = true;
10571 break;
10574 /* Fall through. */
10576 case OMP_CLAUSE_PRIORITY:
10577 case OMP_CLAUSE_GRAINSIZE:
10578 case OMP_CLAUSE_NUM_TASKS:
10579 case OMP_CLAUSE_FILTER:
10580 case OMP_CLAUSE_HINT:
10581 case OMP_CLAUSE_ASYNC:
10582 case OMP_CLAUSE_WAIT:
10583 case OMP_CLAUSE_NUM_GANGS:
10584 case OMP_CLAUSE_NUM_WORKERS:
10585 case OMP_CLAUSE_VECTOR_LENGTH:
10586 case OMP_CLAUSE_WORKER:
10587 case OMP_CLAUSE_VECTOR:
10588 if (OMP_CLAUSE_OPERAND (c, 0)
10589 && !is_gimple_min_invariant (OMP_CLAUSE_OPERAND (c, 0)))
10591 if (error_operand_p (OMP_CLAUSE_OPERAND (c, 0)))
10593 remove = true;
10594 break;
10596 /* All these clauses care about value, not a particular decl,
10597 so try to force it into a SSA_NAME or fresh temporary. */
10598 OMP_CLAUSE_OPERAND (c, 0)
10599 = get_initialized_tmp_var (OMP_CLAUSE_OPERAND (c, 0),
10600 pre_p, NULL, true);
10602 break;
10604 case OMP_CLAUSE_GANG:
10605 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
10606 is_gimple_val, fb_rvalue) == GS_ERROR)
10607 remove = true;
10608 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 1), pre_p, NULL,
10609 is_gimple_val, fb_rvalue) == GS_ERROR)
10610 remove = true;
10611 break;
10613 case OMP_CLAUSE_NOWAIT:
10614 nowait = 1;
10615 break;
10617 case OMP_CLAUSE_ORDERED:
10618 case OMP_CLAUSE_UNTIED:
10619 case OMP_CLAUSE_COLLAPSE:
10620 case OMP_CLAUSE_TILE:
10621 case OMP_CLAUSE_AUTO:
10622 case OMP_CLAUSE_SEQ:
10623 case OMP_CLAUSE_INDEPENDENT:
10624 case OMP_CLAUSE_MERGEABLE:
10625 case OMP_CLAUSE_PROC_BIND:
10626 case OMP_CLAUSE_SAFELEN:
10627 case OMP_CLAUSE_SIMDLEN:
10628 case OMP_CLAUSE_NOGROUP:
10629 case OMP_CLAUSE_THREADS:
10630 case OMP_CLAUSE_SIMD:
10631 case OMP_CLAUSE_BIND:
10632 case OMP_CLAUSE_IF_PRESENT:
10633 case OMP_CLAUSE_FINALIZE:
10634 break;
10636 case OMP_CLAUSE_ORDER:
10637 ctx->order_concurrent = true;
10638 break;
10640 case OMP_CLAUSE_DEFAULTMAP:
10641 enum gimplify_defaultmap_kind gdmkmin, gdmkmax;
10642 switch (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c))
10644 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
10645 gdmkmin = GDMK_SCALAR;
10646 gdmkmax = GDMK_POINTER;
10647 break;
10648 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
10649 gdmkmin = GDMK_SCALAR;
10650 gdmkmax = GDMK_SCALAR_TARGET;
10651 break;
10652 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
10653 gdmkmin = gdmkmax = GDMK_AGGREGATE;
10654 break;
10655 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALLOCATABLE:
10656 gdmkmin = gdmkmax = GDMK_ALLOCATABLE;
10657 break;
10658 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
10659 gdmkmin = gdmkmax = GDMK_POINTER;
10660 break;
10661 default:
10662 gcc_unreachable ();
10664 for (int gdmk = gdmkmin; gdmk <= gdmkmax; gdmk++)
10665 switch (OMP_CLAUSE_DEFAULTMAP_BEHAVIOR (c))
10667 case OMP_CLAUSE_DEFAULTMAP_ALLOC:
10668 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_ALLOC_ONLY;
10669 break;
10670 case OMP_CLAUSE_DEFAULTMAP_TO:
10671 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_TO_ONLY;
10672 break;
10673 case OMP_CLAUSE_DEFAULTMAP_FROM:
10674 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_FROM_ONLY;
10675 break;
10676 case OMP_CLAUSE_DEFAULTMAP_TOFROM:
10677 ctx->defaultmap[gdmk] = GOVD_MAP;
10678 break;
10679 case OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE:
10680 ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE;
10681 break;
10682 case OMP_CLAUSE_DEFAULTMAP_NONE:
10683 ctx->defaultmap[gdmk] = 0;
10684 break;
10685 case OMP_CLAUSE_DEFAULTMAP_DEFAULT:
10686 switch (gdmk)
10688 case GDMK_SCALAR:
10689 ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE;
10690 break;
10691 case GDMK_SCALAR_TARGET:
10692 ctx->defaultmap[gdmk] = (lang_GNU_Fortran ()
10693 ? GOVD_MAP : GOVD_FIRSTPRIVATE);
10694 break;
10695 case GDMK_AGGREGATE:
10696 case GDMK_ALLOCATABLE:
10697 ctx->defaultmap[gdmk] = GOVD_MAP;
10698 break;
10699 case GDMK_POINTER:
10700 ctx->defaultmap[gdmk] = GOVD_MAP;
10701 if (!lang_GNU_Fortran ())
10702 ctx->defaultmap[gdmk] |= GOVD_MAP_0LEN_ARRAY;
10703 break;
10704 default:
10705 gcc_unreachable ();
10707 break;
10708 default:
10709 gcc_unreachable ();
10711 break;
10713 case OMP_CLAUSE_ALIGNED:
10714 decl = OMP_CLAUSE_DECL (c);
10715 if (error_operand_p (decl))
10717 remove = true;
10718 break;
10720 if (gimplify_expr (&OMP_CLAUSE_ALIGNED_ALIGNMENT (c), pre_p, NULL,
10721 is_gimple_val, fb_rvalue) == GS_ERROR)
10723 remove = true;
10724 break;
10726 if (!is_global_var (decl)
10727 && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
10728 omp_add_variable (ctx, decl, GOVD_ALIGNED);
10729 break;
10731 case OMP_CLAUSE_NONTEMPORAL:
10732 decl = OMP_CLAUSE_DECL (c);
10733 if (error_operand_p (decl))
10735 remove = true;
10736 break;
10738 omp_add_variable (ctx, decl, GOVD_NONTEMPORAL);
10739 break;
10741 case OMP_CLAUSE_ALLOCATE:
10742 decl = OMP_CLAUSE_DECL (c);
10743 if (error_operand_p (decl))
10745 remove = true;
10746 break;
10748 if (gimplify_expr (&OMP_CLAUSE_ALLOCATE_ALLOCATOR (c), pre_p, NULL,
10749 is_gimple_val, fb_rvalue) == GS_ERROR)
10751 remove = true;
10752 break;
10754 else if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) == NULL_TREE
10755 || (TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c))
10756 == INTEGER_CST))
10758 else if (code == OMP_TASKLOOP
10759 || !DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)))
10760 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
10761 = get_initialized_tmp_var (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
10762 pre_p, NULL, false);
10763 break;
10765 case OMP_CLAUSE_DEFAULT:
10766 ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
10767 break;
10769 case OMP_CLAUSE_INCLUSIVE:
10770 case OMP_CLAUSE_EXCLUSIVE:
10771 decl = OMP_CLAUSE_DECL (c);
10773 splay_tree_node n = splay_tree_lookup (outer_ctx->variables,
10774 (splay_tree_key) decl);
10775 if (n == NULL || (n->value & GOVD_REDUCTION) == 0)
10777 error_at (OMP_CLAUSE_LOCATION (c),
10778 "%qD specified in %qs clause but not in %<inscan%> "
10779 "%<reduction%> clause on the containing construct",
10780 decl, omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
10781 remove = true;
10783 else
10785 n->value |= GOVD_REDUCTION_INSCAN;
10786 if (outer_ctx->region_type == ORT_SIMD
10787 && outer_ctx->outer_context
10788 && outer_ctx->outer_context->region_type == ORT_WORKSHARE)
10790 n = splay_tree_lookup (outer_ctx->outer_context->variables,
10791 (splay_tree_key) decl);
10792 if (n && (n->value & GOVD_REDUCTION) != 0)
10793 n->value |= GOVD_REDUCTION_INSCAN;
10797 break;
10799 case OMP_CLAUSE_NOHOST:
10800 default:
10801 gcc_unreachable ();
10804 if (code == OACC_DATA
10805 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
10806 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
10807 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
10808 remove = true;
10809 if (remove)
10810 *list_p = OMP_CLAUSE_CHAIN (c);
10811 else
10812 list_p = &OMP_CLAUSE_CHAIN (c);
10815 ctx->clauses = *orig_list_p;
10816 gimplify_omp_ctxp = ctx;
10817 if (struct_seen_clause)
10818 delete struct_seen_clause;
10819 if (struct_map_to_clause)
10820 delete struct_map_to_clause;
10821 if (struct_deref_set)
10822 delete struct_deref_set;
10825 /* Return true if DECL is a candidate for shared to firstprivate
10826 optimization. We only consider non-addressable scalars, not
10827 too big, and not references. */
10829 static bool
10830 omp_shared_to_firstprivate_optimizable_decl_p (tree decl)
10832 if (TREE_ADDRESSABLE (decl))
10833 return false;
10834 tree type = TREE_TYPE (decl);
10835 if (!is_gimple_reg_type (type)
10836 || TREE_CODE (type) == REFERENCE_TYPE
10837 || TREE_ADDRESSABLE (type))
10838 return false;
10839 /* Don't optimize too large decls, as each thread/task will have
10840 its own. */
10841 HOST_WIDE_INT len = int_size_in_bytes (type);
10842 if (len == -1 || len > 4 * POINTER_SIZE / BITS_PER_UNIT)
10843 return false;
10844 if (omp_privatize_by_reference (decl))
10845 return false;
10846 return true;
10849 /* Helper function of omp_find_stores_op and gimplify_adjust_omp_clauses*.
10850 For omp_shared_to_firstprivate_optimizable_decl_p decl mark it as
10851 GOVD_WRITTEN in outer contexts. */
10853 static void
10854 omp_mark_stores (struct gimplify_omp_ctx *ctx, tree decl)
10856 for (; ctx; ctx = ctx->outer_context)
10858 splay_tree_node n = splay_tree_lookup (ctx->variables,
10859 (splay_tree_key) decl);
10860 if (n == NULL)
10861 continue;
10862 else if (n->value & GOVD_SHARED)
10864 n->value |= GOVD_WRITTEN;
10865 return;
10867 else if (n->value & GOVD_DATA_SHARE_CLASS)
10868 return;
10872 /* Helper callback for walk_gimple_seq to discover possible stores
10873 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
10874 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
10875 for those. */
10877 static tree
10878 omp_find_stores_op (tree *tp, int *walk_subtrees, void *data)
10880 struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
10882 *walk_subtrees = 0;
10883 if (!wi->is_lhs)
10884 return NULL_TREE;
10886 tree op = *tp;
10889 if (handled_component_p (op))
10890 op = TREE_OPERAND (op, 0);
10891 else if ((TREE_CODE (op) == MEM_REF || TREE_CODE (op) == TARGET_MEM_REF)
10892 && TREE_CODE (TREE_OPERAND (op, 0)) == ADDR_EXPR)
10893 op = TREE_OPERAND (TREE_OPERAND (op, 0), 0);
10894 else
10895 break;
10897 while (1);
10898 if (!DECL_P (op) || !omp_shared_to_firstprivate_optimizable_decl_p (op))
10899 return NULL_TREE;
10901 omp_mark_stores (gimplify_omp_ctxp, op);
10902 return NULL_TREE;
10905 /* Helper callback for walk_gimple_seq to discover possible stores
10906 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
10907 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
10908 for those. */
10910 static tree
10911 omp_find_stores_stmt (gimple_stmt_iterator *gsi_p,
10912 bool *handled_ops_p,
10913 struct walk_stmt_info *wi)
10915 gimple *stmt = gsi_stmt (*gsi_p);
10916 switch (gimple_code (stmt))
10918 /* Don't recurse on OpenMP constructs for which
10919 gimplify_adjust_omp_clauses already handled the bodies,
10920 except handle gimple_omp_for_pre_body. */
10921 case GIMPLE_OMP_FOR:
10922 *handled_ops_p = true;
10923 if (gimple_omp_for_pre_body (stmt))
10924 walk_gimple_seq (gimple_omp_for_pre_body (stmt),
10925 omp_find_stores_stmt, omp_find_stores_op, wi);
10926 break;
10927 case GIMPLE_OMP_PARALLEL:
10928 case GIMPLE_OMP_TASK:
10929 case GIMPLE_OMP_SECTIONS:
10930 case GIMPLE_OMP_SINGLE:
10931 case GIMPLE_OMP_SCOPE:
10932 case GIMPLE_OMP_TARGET:
10933 case GIMPLE_OMP_TEAMS:
10934 case GIMPLE_OMP_CRITICAL:
10935 *handled_ops_p = true;
10936 break;
10937 default:
10938 break;
10940 return NULL_TREE;
10943 struct gimplify_adjust_omp_clauses_data
10945 tree *list_p;
10946 gimple_seq *pre_p;
10949 /* For all variables that were not actually used within the context,
10950 remove PRIVATE, SHARED, and FIRSTPRIVATE clauses. */
10952 static int
10953 gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
10955 tree *list_p = ((struct gimplify_adjust_omp_clauses_data *) data)->list_p;
10956 gimple_seq *pre_p
10957 = ((struct gimplify_adjust_omp_clauses_data *) data)->pre_p;
10958 tree decl = (tree) n->key;
10959 unsigned flags = n->value;
10960 enum omp_clause_code code;
10961 tree clause;
10962 bool private_debug;
10964 if (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
10965 && (flags & GOVD_LASTPRIVATE_CONDITIONAL) != 0)
10966 flags = GOVD_SHARED | GOVD_SEEN | GOVD_WRITTEN;
10967 if (flags & (GOVD_EXPLICIT | GOVD_LOCAL))
10968 return 0;
10969 if ((flags & GOVD_SEEN) == 0)
10970 return 0;
10971 if ((flags & GOVD_MAP_HAS_ATTACHMENTS) != 0)
10972 return 0;
10973 if (flags & GOVD_DEBUG_PRIVATE)
10975 gcc_assert ((flags & GOVD_DATA_SHARE_CLASS) == GOVD_SHARED);
10976 private_debug = true;
10978 else if (flags & GOVD_MAP)
10979 private_debug = false;
10980 else
10981 private_debug
10982 = lang_hooks.decls.omp_private_debug_clause (decl,
10983 !!(flags & GOVD_SHARED));
10984 if (private_debug)
10985 code = OMP_CLAUSE_PRIVATE;
10986 else if (flags & GOVD_MAP)
10988 code = OMP_CLAUSE_MAP;
10989 if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0
10990 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
10992 error ("%<_Atomic%> %qD in implicit %<map%> clause", decl);
10993 return 0;
10995 if (VAR_P (decl)
10996 && DECL_IN_CONSTANT_POOL (decl)
10997 && !lookup_attribute ("omp declare target",
10998 DECL_ATTRIBUTES (decl)))
11000 tree id = get_identifier ("omp declare target");
11001 DECL_ATTRIBUTES (decl)
11002 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
11003 varpool_node *node = varpool_node::get (decl);
11004 if (node)
11006 node->offloadable = 1;
11007 if (ENABLE_OFFLOADING)
11008 g->have_offload = true;
11012 else if (flags & GOVD_SHARED)
11014 if (is_global_var (decl))
11016 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
11017 while (ctx != NULL)
11019 splay_tree_node on
11020 = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11021 if (on && (on->value & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
11022 | GOVD_PRIVATE | GOVD_REDUCTION
11023 | GOVD_LINEAR | GOVD_MAP)) != 0)
11024 break;
11025 ctx = ctx->outer_context;
11027 if (ctx == NULL)
11028 return 0;
11030 code = OMP_CLAUSE_SHARED;
11031 /* Don't optimize shared into firstprivate for read-only vars
11032 on tasks with depend clause, we shouldn't try to copy them
11033 until the dependencies are satisfied. */
11034 if (gimplify_omp_ctxp->has_depend)
11035 flags |= GOVD_WRITTEN;
11037 else if (flags & GOVD_PRIVATE)
11038 code = OMP_CLAUSE_PRIVATE;
11039 else if (flags & GOVD_FIRSTPRIVATE)
11041 code = OMP_CLAUSE_FIRSTPRIVATE;
11042 if ((gimplify_omp_ctxp->region_type & ORT_TARGET)
11043 && (gimplify_omp_ctxp->region_type & ORT_ACC) == 0
11044 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
11046 error ("%<_Atomic%> %qD in implicit %<firstprivate%> clause on "
11047 "%<target%> construct", decl);
11048 return 0;
11051 else if (flags & GOVD_LASTPRIVATE)
11052 code = OMP_CLAUSE_LASTPRIVATE;
11053 else if (flags & (GOVD_ALIGNED | GOVD_NONTEMPORAL))
11054 return 0;
11055 else if (flags & GOVD_CONDTEMP)
11057 code = OMP_CLAUSE__CONDTEMP_;
11058 gimple_add_tmp_var (decl);
11060 else
11061 gcc_unreachable ();
11063 if (((flags & GOVD_LASTPRIVATE)
11064 || (code == OMP_CLAUSE_SHARED && (flags & GOVD_WRITTEN)))
11065 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
11066 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
11068 tree chain = *list_p;
11069 clause = build_omp_clause (input_location, code);
11070 OMP_CLAUSE_DECL (clause) = decl;
11071 OMP_CLAUSE_CHAIN (clause) = chain;
11072 if (private_debug)
11073 OMP_CLAUSE_PRIVATE_DEBUG (clause) = 1;
11074 else if (code == OMP_CLAUSE_PRIVATE && (flags & GOVD_PRIVATE_OUTER_REF))
11075 OMP_CLAUSE_PRIVATE_OUTER_REF (clause) = 1;
11076 else if (code == OMP_CLAUSE_SHARED
11077 && (flags & GOVD_WRITTEN) == 0
11078 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
11079 OMP_CLAUSE_SHARED_READONLY (clause) = 1;
11080 else if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_EXPLICIT) == 0)
11081 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (clause) = 1;
11082 else if (code == OMP_CLAUSE_MAP && (flags & GOVD_MAP_0LEN_ARRAY) != 0)
11084 tree nc = build_omp_clause (input_location, OMP_CLAUSE_MAP);
11085 OMP_CLAUSE_DECL (nc) = decl;
11086 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
11087 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == POINTER_TYPE)
11088 OMP_CLAUSE_DECL (clause)
11089 = build_simple_mem_ref_loc (input_location, decl);
11090 OMP_CLAUSE_DECL (clause)
11091 = build2 (MEM_REF, char_type_node, OMP_CLAUSE_DECL (clause),
11092 build_int_cst (build_pointer_type (char_type_node), 0));
11093 OMP_CLAUSE_SIZE (clause) = size_zero_node;
11094 OMP_CLAUSE_SIZE (nc) = size_zero_node;
11095 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_ALLOC);
11096 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (clause) = 1;
11097 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
11098 OMP_CLAUSE_CHAIN (nc) = chain;
11099 OMP_CLAUSE_CHAIN (clause) = nc;
11100 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
11101 gimplify_omp_ctxp = ctx->outer_context;
11102 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (clause), 0),
11103 pre_p, NULL, is_gimple_val, fb_rvalue);
11104 gimplify_omp_ctxp = ctx;
11106 else if (code == OMP_CLAUSE_MAP)
11108 int kind;
11109 /* Not all combinations of these GOVD_MAP flags are actually valid. */
11110 switch (flags & (GOVD_MAP_TO_ONLY
11111 | GOVD_MAP_FORCE
11112 | GOVD_MAP_FORCE_PRESENT
11113 | GOVD_MAP_ALLOC_ONLY
11114 | GOVD_MAP_FROM_ONLY))
11116 case 0:
11117 kind = GOMP_MAP_TOFROM;
11118 break;
11119 case GOVD_MAP_FORCE:
11120 kind = GOMP_MAP_TOFROM | GOMP_MAP_FLAG_FORCE;
11121 break;
11122 case GOVD_MAP_TO_ONLY:
11123 kind = GOMP_MAP_TO;
11124 break;
11125 case GOVD_MAP_FROM_ONLY:
11126 kind = GOMP_MAP_FROM;
11127 break;
11128 case GOVD_MAP_ALLOC_ONLY:
11129 kind = GOMP_MAP_ALLOC;
11130 break;
11131 case GOVD_MAP_TO_ONLY | GOVD_MAP_FORCE:
11132 kind = GOMP_MAP_TO | GOMP_MAP_FLAG_FORCE;
11133 break;
11134 case GOVD_MAP_FORCE_PRESENT:
11135 kind = GOMP_MAP_FORCE_PRESENT;
11136 break;
11137 default:
11138 gcc_unreachable ();
11140 OMP_CLAUSE_SET_MAP_KIND (clause, kind);
11141 /* Setting of the implicit flag for the runtime is currently disabled for
11142 OpenACC. */
11143 if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0)
11144 OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (clause) = 1;
11145 if (DECL_SIZE (decl)
11146 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
11148 tree decl2 = DECL_VALUE_EXPR (decl);
11149 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
11150 decl2 = TREE_OPERAND (decl2, 0);
11151 gcc_assert (DECL_P (decl2));
11152 tree mem = build_simple_mem_ref (decl2);
11153 OMP_CLAUSE_DECL (clause) = mem;
11154 OMP_CLAUSE_SIZE (clause) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
11155 if (gimplify_omp_ctxp->outer_context)
11157 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
11158 omp_notice_variable (ctx, decl2, true);
11159 omp_notice_variable (ctx, OMP_CLAUSE_SIZE (clause), true);
11161 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
11162 OMP_CLAUSE_MAP);
11163 OMP_CLAUSE_DECL (nc) = decl;
11164 OMP_CLAUSE_SIZE (nc) = size_zero_node;
11165 if (gimplify_omp_ctxp->target_firstprivatize_array_bases)
11166 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
11167 else
11168 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
11169 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
11170 OMP_CLAUSE_CHAIN (clause) = nc;
11172 else if (gimplify_omp_ctxp->target_firstprivatize_array_bases
11173 && omp_privatize_by_reference (decl))
11175 OMP_CLAUSE_DECL (clause) = build_simple_mem_ref (decl);
11176 OMP_CLAUSE_SIZE (clause)
11177 = unshare_expr (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))));
11178 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
11179 gimplify_omp_ctxp = ctx->outer_context;
11180 gimplify_expr (&OMP_CLAUSE_SIZE (clause),
11181 pre_p, NULL, is_gimple_val, fb_rvalue);
11182 gimplify_omp_ctxp = ctx;
11183 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
11184 OMP_CLAUSE_MAP);
11185 OMP_CLAUSE_DECL (nc) = decl;
11186 OMP_CLAUSE_SIZE (nc) = size_zero_node;
11187 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_REFERENCE);
11188 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
11189 OMP_CLAUSE_CHAIN (clause) = nc;
11191 else
11192 OMP_CLAUSE_SIZE (clause) = DECL_SIZE_UNIT (decl);
11194 if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_LASTPRIVATE) != 0)
11196 tree nc = build_omp_clause (input_location, OMP_CLAUSE_LASTPRIVATE);
11197 OMP_CLAUSE_DECL (nc) = decl;
11198 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (nc) = 1;
11199 OMP_CLAUSE_CHAIN (nc) = chain;
11200 OMP_CLAUSE_CHAIN (clause) = nc;
11201 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
11202 gimplify_omp_ctxp = ctx->outer_context;
11203 lang_hooks.decls.omp_finish_clause (nc, pre_p,
11204 (ctx->region_type & ORT_ACC) != 0);
11205 gimplify_omp_ctxp = ctx;
11207 *list_p = clause;
11208 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
11209 gimplify_omp_ctxp = ctx->outer_context;
11210 /* Don't call omp_finish_clause on implicitly added OMP_CLAUSE_PRIVATE
11211 in simd. Those are only added for the local vars inside of simd body
11212 and they don't need to be e.g. default constructible. */
11213 if (code != OMP_CLAUSE_PRIVATE || ctx->region_type != ORT_SIMD)
11214 lang_hooks.decls.omp_finish_clause (clause, pre_p,
11215 (ctx->region_type & ORT_ACC) != 0);
11216 if (gimplify_omp_ctxp)
11217 for (; clause != chain; clause = OMP_CLAUSE_CHAIN (clause))
11218 if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_MAP
11219 && DECL_P (OMP_CLAUSE_SIZE (clause)))
11220 omp_notice_variable (gimplify_omp_ctxp, OMP_CLAUSE_SIZE (clause),
11221 true);
11222 gimplify_omp_ctxp = ctx;
11223 return 0;
11226 static void
11227 gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
11228 enum tree_code code)
11230 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
11231 tree *orig_list_p = list_p;
11232 tree c, decl;
11233 bool has_inscan_reductions = false;
11235 if (body)
11237 struct gimplify_omp_ctx *octx;
11238 for (octx = ctx; octx; octx = octx->outer_context)
11239 if ((octx->region_type & (ORT_PARALLEL | ORT_TASK | ORT_TEAMS)) != 0)
11240 break;
11241 if (octx)
11243 struct walk_stmt_info wi;
11244 memset (&wi, 0, sizeof (wi));
11245 walk_gimple_seq (body, omp_find_stores_stmt,
11246 omp_find_stores_op, &wi);
11250 if (ctx->add_safelen1)
11252 /* If there are VLAs in the body of simd loop, prevent
11253 vectorization. */
11254 gcc_assert (ctx->region_type == ORT_SIMD);
11255 c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_SAFELEN);
11256 OMP_CLAUSE_SAFELEN_EXPR (c) = integer_one_node;
11257 OMP_CLAUSE_CHAIN (c) = *list_p;
11258 *list_p = c;
11259 list_p = &OMP_CLAUSE_CHAIN (c);
11262 if (ctx->region_type == ORT_WORKSHARE
11263 && ctx->outer_context
11264 && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL)
11266 for (c = ctx->outer_context->clauses; c; c = OMP_CLAUSE_CHAIN (c))
11267 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
11268 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
11270 decl = OMP_CLAUSE_DECL (c);
11271 splay_tree_node n
11272 = splay_tree_lookup (ctx->outer_context->variables,
11273 (splay_tree_key) decl);
11274 gcc_checking_assert (!splay_tree_lookup (ctx->variables,
11275 (splay_tree_key) decl));
11276 omp_add_variable (ctx, decl, n->value);
11277 tree c2 = copy_node (c);
11278 OMP_CLAUSE_CHAIN (c2) = *list_p;
11279 *list_p = c2;
11280 if ((n->value & GOVD_FIRSTPRIVATE) == 0)
11281 continue;
11282 c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
11283 OMP_CLAUSE_FIRSTPRIVATE);
11284 OMP_CLAUSE_DECL (c2) = decl;
11285 OMP_CLAUSE_CHAIN (c2) = *list_p;
11286 *list_p = c2;
11289 while ((c = *list_p) != NULL)
11291 splay_tree_node n;
11292 bool remove = false;
11294 switch (OMP_CLAUSE_CODE (c))
11296 case OMP_CLAUSE_FIRSTPRIVATE:
11297 if ((ctx->region_type & ORT_TARGET)
11298 && (ctx->region_type & ORT_ACC) == 0
11299 && TYPE_ATOMIC (strip_array_types
11300 (TREE_TYPE (OMP_CLAUSE_DECL (c)))))
11302 error_at (OMP_CLAUSE_LOCATION (c),
11303 "%<_Atomic%> %qD in %<firstprivate%> clause on "
11304 "%<target%> construct", OMP_CLAUSE_DECL (c));
11305 remove = true;
11306 break;
11308 if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c))
11310 decl = OMP_CLAUSE_DECL (c);
11311 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11312 if ((n->value & GOVD_MAP) != 0)
11314 remove = true;
11315 break;
11317 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT_TARGET (c) = 0;
11318 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c) = 0;
11320 /* FALLTHRU */
11321 case OMP_CLAUSE_PRIVATE:
11322 case OMP_CLAUSE_SHARED:
11323 case OMP_CLAUSE_LINEAR:
11324 decl = OMP_CLAUSE_DECL (c);
11325 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11326 remove = !(n->value & GOVD_SEEN);
11327 if ((n->value & GOVD_LASTPRIVATE_CONDITIONAL) != 0
11328 && code == OMP_PARALLEL
11329 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
11330 remove = true;
11331 if (! remove)
11333 bool shared = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED;
11334 if ((n->value & GOVD_DEBUG_PRIVATE)
11335 || lang_hooks.decls.omp_private_debug_clause (decl, shared))
11337 gcc_assert ((n->value & GOVD_DEBUG_PRIVATE) == 0
11338 || ((n->value & GOVD_DATA_SHARE_CLASS)
11339 == GOVD_SHARED));
11340 OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_PRIVATE);
11341 OMP_CLAUSE_PRIVATE_DEBUG (c) = 1;
11343 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
11344 && ctx->has_depend
11345 && DECL_P (decl))
11346 n->value |= GOVD_WRITTEN;
11347 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
11348 && (n->value & GOVD_WRITTEN) == 0
11349 && DECL_P (decl)
11350 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
11351 OMP_CLAUSE_SHARED_READONLY (c) = 1;
11352 else if (DECL_P (decl)
11353 && ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
11354 && (n->value & GOVD_WRITTEN) != 0)
11355 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
11356 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
11357 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
11358 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
11360 else
11361 n->value &= ~GOVD_EXPLICIT;
11362 break;
11364 case OMP_CLAUSE_LASTPRIVATE:
11365 /* Make sure OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE is set to
11366 accurately reflect the presence of a FIRSTPRIVATE clause. */
11367 decl = OMP_CLAUSE_DECL (c);
11368 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11369 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c)
11370 = (n->value & GOVD_FIRSTPRIVATE) != 0;
11371 if (code == OMP_DISTRIBUTE
11372 && OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
11374 remove = true;
11375 error_at (OMP_CLAUSE_LOCATION (c),
11376 "same variable used in %<firstprivate%> and "
11377 "%<lastprivate%> clauses on %<distribute%> "
11378 "construct");
11380 if (!remove
11381 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
11382 && DECL_P (decl)
11383 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
11384 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
11385 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) && code == OMP_PARALLEL)
11386 remove = true;
11387 break;
11389 case OMP_CLAUSE_ALIGNED:
11390 decl = OMP_CLAUSE_DECL (c);
11391 if (!is_global_var (decl))
11393 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11394 remove = n == NULL || !(n->value & GOVD_SEEN);
11395 if (!remove && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
11397 struct gimplify_omp_ctx *octx;
11398 if (n != NULL
11399 && (n->value & (GOVD_DATA_SHARE_CLASS
11400 & ~GOVD_FIRSTPRIVATE)))
11401 remove = true;
11402 else
11403 for (octx = ctx->outer_context; octx;
11404 octx = octx->outer_context)
11406 n = splay_tree_lookup (octx->variables,
11407 (splay_tree_key) decl);
11408 if (n == NULL)
11409 continue;
11410 if (n->value & GOVD_LOCAL)
11411 break;
11412 /* We have to avoid assigning a shared variable
11413 to itself when trying to add
11414 __builtin_assume_aligned. */
11415 if (n->value & GOVD_SHARED)
11417 remove = true;
11418 break;
11423 else if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
11425 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11426 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
11427 remove = true;
11429 break;
11431 case OMP_CLAUSE_NONTEMPORAL:
11432 decl = OMP_CLAUSE_DECL (c);
11433 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11434 remove = n == NULL || !(n->value & GOVD_SEEN);
11435 break;
11437 case OMP_CLAUSE_MAP:
11438 if (code == OMP_TARGET_EXIT_DATA
11439 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER)
11441 remove = true;
11442 break;
11444 decl = OMP_CLAUSE_DECL (c);
11445 /* Data clauses associated with reductions must be
11446 compatible with present_or_copy. Warn and adjust the clause
11447 if that is not the case. */
11448 if (ctx->region_type == ORT_ACC_PARALLEL
11449 || ctx->region_type == ORT_ACC_SERIAL)
11451 tree t = DECL_P (decl) ? decl : TREE_OPERAND (decl, 0);
11452 n = NULL;
11454 if (DECL_P (t))
11455 n = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
11457 if (n && (n->value & GOVD_REDUCTION))
11459 enum gomp_map_kind kind = OMP_CLAUSE_MAP_KIND (c);
11461 OMP_CLAUSE_MAP_IN_REDUCTION (c) = 1;
11462 if ((kind & GOMP_MAP_TOFROM) != GOMP_MAP_TOFROM
11463 && kind != GOMP_MAP_FORCE_PRESENT
11464 && kind != GOMP_MAP_POINTER)
11466 warning_at (OMP_CLAUSE_LOCATION (c), 0,
11467 "incompatible data clause with reduction "
11468 "on %qE; promoting to %<present_or_copy%>",
11469 DECL_NAME (t));
11470 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TOFROM);
11474 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT
11475 && (code == OMP_TARGET_EXIT_DATA || code == OACC_EXIT_DATA))
11477 remove = true;
11478 break;
11480 if (!DECL_P (decl))
11482 if ((ctx->region_type & ORT_TARGET) != 0
11483 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
11485 if (TREE_CODE (decl) == INDIRECT_REF
11486 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
11487 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
11488 == REFERENCE_TYPE))
11489 decl = TREE_OPERAND (decl, 0);
11490 if (TREE_CODE (decl) == COMPONENT_REF)
11492 while (TREE_CODE (decl) == COMPONENT_REF)
11493 decl = TREE_OPERAND (decl, 0);
11494 if (DECL_P (decl))
11496 n = splay_tree_lookup (ctx->variables,
11497 (splay_tree_key) decl);
11498 if (!(n->value & GOVD_SEEN))
11499 remove = true;
11503 break;
11505 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11506 if ((ctx->region_type & ORT_TARGET) != 0
11507 && !(n->value & GOVD_SEEN)
11508 && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) == 0
11509 && (!is_global_var (decl)
11510 || !lookup_attribute ("omp declare target link",
11511 DECL_ATTRIBUTES (decl))))
11513 remove = true;
11514 /* For struct element mapping, if struct is never referenced
11515 in target block and none of the mapping has always modifier,
11516 remove all the struct element mappings, which immediately
11517 follow the GOMP_MAP_STRUCT map clause. */
11518 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT)
11520 HOST_WIDE_INT cnt = tree_to_shwi (OMP_CLAUSE_SIZE (c));
11521 while (cnt--)
11522 OMP_CLAUSE_CHAIN (c)
11523 = OMP_CLAUSE_CHAIN (OMP_CLAUSE_CHAIN (c));
11526 else if (DECL_SIZE (decl)
11527 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST
11528 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_POINTER
11529 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_POINTER
11530 && (OMP_CLAUSE_MAP_KIND (c)
11531 != GOMP_MAP_FIRSTPRIVATE_REFERENCE))
11533 /* For GOMP_MAP_FORCE_DEVICEPTR, we'll never enter here, because
11534 for these, TREE_CODE (DECL_SIZE (decl)) will always be
11535 INTEGER_CST. */
11536 gcc_assert (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FORCE_DEVICEPTR);
11538 tree decl2 = DECL_VALUE_EXPR (decl);
11539 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
11540 decl2 = TREE_OPERAND (decl2, 0);
11541 gcc_assert (DECL_P (decl2));
11542 tree mem = build_simple_mem_ref (decl2);
11543 OMP_CLAUSE_DECL (c) = mem;
11544 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
11545 if (ctx->outer_context)
11547 omp_notice_variable (ctx->outer_context, decl2, true);
11548 omp_notice_variable (ctx->outer_context,
11549 OMP_CLAUSE_SIZE (c), true);
11551 if (((ctx->region_type & ORT_TARGET) != 0
11552 || !ctx->target_firstprivatize_array_bases)
11553 && ((n->value & GOVD_SEEN) == 0
11554 || (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) == 0))
11556 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
11557 OMP_CLAUSE_MAP);
11558 OMP_CLAUSE_DECL (nc) = decl;
11559 OMP_CLAUSE_SIZE (nc) = size_zero_node;
11560 if (ctx->target_firstprivatize_array_bases)
11561 OMP_CLAUSE_SET_MAP_KIND (nc,
11562 GOMP_MAP_FIRSTPRIVATE_POINTER);
11563 else
11564 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
11565 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
11566 OMP_CLAUSE_CHAIN (c) = nc;
11567 c = nc;
11570 else
11572 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
11573 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
11574 gcc_assert ((n->value & GOVD_SEEN) == 0
11575 || ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
11576 == 0));
11578 break;
11580 case OMP_CLAUSE_TO:
11581 case OMP_CLAUSE_FROM:
11582 case OMP_CLAUSE__CACHE_:
11583 decl = OMP_CLAUSE_DECL (c);
11584 if (!DECL_P (decl))
11585 break;
11586 if (DECL_SIZE (decl)
11587 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
11589 tree decl2 = DECL_VALUE_EXPR (decl);
11590 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
11591 decl2 = TREE_OPERAND (decl2, 0);
11592 gcc_assert (DECL_P (decl2));
11593 tree mem = build_simple_mem_ref (decl2);
11594 OMP_CLAUSE_DECL (c) = mem;
11595 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
11596 if (ctx->outer_context)
11598 omp_notice_variable (ctx->outer_context, decl2, true);
11599 omp_notice_variable (ctx->outer_context,
11600 OMP_CLAUSE_SIZE (c), true);
11603 else if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
11604 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
11605 break;
11607 case OMP_CLAUSE_REDUCTION:
11608 if (OMP_CLAUSE_REDUCTION_INSCAN (c))
11610 decl = OMP_CLAUSE_DECL (c);
11611 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11612 if ((n->value & GOVD_REDUCTION_INSCAN) == 0)
11614 remove = true;
11615 error_at (OMP_CLAUSE_LOCATION (c),
11616 "%qD specified in %<inscan%> %<reduction%> clause "
11617 "but not in %<scan%> directive clause", decl);
11618 break;
11620 has_inscan_reductions = true;
11622 /* FALLTHRU */
11623 case OMP_CLAUSE_IN_REDUCTION:
11624 case OMP_CLAUSE_TASK_REDUCTION:
11625 decl = OMP_CLAUSE_DECL (c);
11626 /* OpenACC reductions need a present_or_copy data clause.
11627 Add one if necessary. Emit error when the reduction is private. */
11628 if (ctx->region_type == ORT_ACC_PARALLEL
11629 || ctx->region_type == ORT_ACC_SERIAL)
11631 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11632 if (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
11634 remove = true;
11635 error_at (OMP_CLAUSE_LOCATION (c), "invalid private "
11636 "reduction on %qE", DECL_NAME (decl));
11638 else if ((n->value & GOVD_MAP) == 0)
11640 tree next = OMP_CLAUSE_CHAIN (c);
11641 tree nc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_MAP);
11642 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_TOFROM);
11643 OMP_CLAUSE_DECL (nc) = decl;
11644 OMP_CLAUSE_CHAIN (c) = nc;
11645 lang_hooks.decls.omp_finish_clause (nc, pre_p,
11646 (ctx->region_type
11647 & ORT_ACC) != 0);
11648 while (1)
11650 OMP_CLAUSE_MAP_IN_REDUCTION (nc) = 1;
11651 if (OMP_CLAUSE_CHAIN (nc) == NULL)
11652 break;
11653 nc = OMP_CLAUSE_CHAIN (nc);
11655 OMP_CLAUSE_CHAIN (nc) = next;
11656 n->value |= GOVD_MAP;
11659 if (DECL_P (decl)
11660 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
11661 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
11662 break;
11664 case OMP_CLAUSE_ALLOCATE:
11665 decl = OMP_CLAUSE_DECL (c);
11666 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11667 if (n != NULL && !(n->value & GOVD_SEEN))
11669 if ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE | GOVD_LINEAR))
11670 != 0
11671 && (n->value & (GOVD_REDUCTION | GOVD_LASTPRIVATE)) == 0)
11672 remove = true;
11674 if (!remove
11675 && OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
11676 && TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)) != INTEGER_CST
11677 && ((ctx->region_type & (ORT_PARALLEL | ORT_TARGET)) != 0
11678 || (ctx->region_type & ORT_TASKLOOP) == ORT_TASK
11679 || (ctx->region_type & ORT_HOST_TEAMS) == ORT_HOST_TEAMS))
11681 tree allocator = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
11682 n = splay_tree_lookup (ctx->variables, (splay_tree_key) allocator);
11683 if (n == NULL)
11685 enum omp_clause_default_kind default_kind
11686 = ctx->default_kind;
11687 ctx->default_kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
11688 omp_notice_variable (ctx, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
11689 true);
11690 ctx->default_kind = default_kind;
11692 else
11693 omp_notice_variable (ctx, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
11694 true);
11696 break;
11698 case OMP_CLAUSE_COPYIN:
11699 case OMP_CLAUSE_COPYPRIVATE:
11700 case OMP_CLAUSE_IF:
11701 case OMP_CLAUSE_NUM_THREADS:
11702 case OMP_CLAUSE_NUM_TEAMS:
11703 case OMP_CLAUSE_THREAD_LIMIT:
11704 case OMP_CLAUSE_DIST_SCHEDULE:
11705 case OMP_CLAUSE_DEVICE:
11706 case OMP_CLAUSE_SCHEDULE:
11707 case OMP_CLAUSE_NOWAIT:
11708 case OMP_CLAUSE_ORDERED:
11709 case OMP_CLAUSE_DEFAULT:
11710 case OMP_CLAUSE_UNTIED:
11711 case OMP_CLAUSE_COLLAPSE:
11712 case OMP_CLAUSE_FINAL:
11713 case OMP_CLAUSE_MERGEABLE:
11714 case OMP_CLAUSE_PROC_BIND:
11715 case OMP_CLAUSE_SAFELEN:
11716 case OMP_CLAUSE_SIMDLEN:
11717 case OMP_CLAUSE_DEPEND:
11718 case OMP_CLAUSE_PRIORITY:
11719 case OMP_CLAUSE_GRAINSIZE:
11720 case OMP_CLAUSE_NUM_TASKS:
11721 case OMP_CLAUSE_NOGROUP:
11722 case OMP_CLAUSE_THREADS:
11723 case OMP_CLAUSE_SIMD:
11724 case OMP_CLAUSE_FILTER:
11725 case OMP_CLAUSE_HINT:
11726 case OMP_CLAUSE_DEFAULTMAP:
11727 case OMP_CLAUSE_ORDER:
11728 case OMP_CLAUSE_BIND:
11729 case OMP_CLAUSE_DETACH:
11730 case OMP_CLAUSE_USE_DEVICE_PTR:
11731 case OMP_CLAUSE_USE_DEVICE_ADDR:
11732 case OMP_CLAUSE_IS_DEVICE_PTR:
11733 case OMP_CLAUSE_ASYNC:
11734 case OMP_CLAUSE_WAIT:
11735 case OMP_CLAUSE_INDEPENDENT:
11736 case OMP_CLAUSE_NUM_GANGS:
11737 case OMP_CLAUSE_NUM_WORKERS:
11738 case OMP_CLAUSE_VECTOR_LENGTH:
11739 case OMP_CLAUSE_GANG:
11740 case OMP_CLAUSE_WORKER:
11741 case OMP_CLAUSE_VECTOR:
11742 case OMP_CLAUSE_AUTO:
11743 case OMP_CLAUSE_SEQ:
11744 case OMP_CLAUSE_TILE:
11745 case OMP_CLAUSE_IF_PRESENT:
11746 case OMP_CLAUSE_FINALIZE:
11747 case OMP_CLAUSE_INCLUSIVE:
11748 case OMP_CLAUSE_EXCLUSIVE:
11749 break;
11751 case OMP_CLAUSE_NOHOST:
11752 default:
11753 gcc_unreachable ();
11756 if (remove)
11757 *list_p = OMP_CLAUSE_CHAIN (c);
11758 else
11759 list_p = &OMP_CLAUSE_CHAIN (c);
11762 /* Add in any implicit data sharing. */
11763 struct gimplify_adjust_omp_clauses_data data;
11764 if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0)
11766 /* OpenMP. Implicit clauses are added at the start of the clause list,
11767 but after any non-map clauses. */
11768 tree *implicit_add_list_p = orig_list_p;
11769 while (*implicit_add_list_p
11770 && OMP_CLAUSE_CODE (*implicit_add_list_p) != OMP_CLAUSE_MAP)
11771 implicit_add_list_p = &OMP_CLAUSE_CHAIN (*implicit_add_list_p);
11772 data.list_p = implicit_add_list_p;
11774 else
11775 /* OpenACC. */
11776 data.list_p = list_p;
11777 data.pre_p = pre_p;
11778 splay_tree_foreach (ctx->variables, gimplify_adjust_omp_clauses_1, &data);
11780 if (has_inscan_reductions)
11781 for (c = *orig_list_p; c; c = OMP_CLAUSE_CHAIN (c))
11782 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
11783 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
11785 error_at (OMP_CLAUSE_LOCATION (c),
11786 "%<inscan%> %<reduction%> clause used together with "
11787 "%<linear%> clause for a variable other than loop "
11788 "iterator");
11789 break;
11792 gimplify_omp_ctxp = ctx->outer_context;
11793 delete_omp_context (ctx);
11796 /* Return 0 if CONSTRUCTS selectors don't match the OpenMP context,
11797 -1 if unknown yet (simd is involved, won't be known until vectorization)
11798 and 1 if they do. If SCORES is non-NULL, it should point to an array
11799 of at least 2*NCONSTRUCTS+2 ints, and will be filled with the positions
11800 of the CONSTRUCTS (position -1 if it will never match) followed by
11801 number of constructs in the OpenMP context construct trait. If the
11802 score depends on whether it will be in a declare simd clone or not,
11803 the function returns 2 and there will be two sets of the scores, the first
11804 one for the case that it is not in a declare simd clone, the other
11805 that it is in a declare simd clone. */
11808 omp_construct_selector_matches (enum tree_code *constructs, int nconstructs,
11809 int *scores)
11811 int matched = 0, cnt = 0;
11812 bool simd_seen = false;
11813 bool target_seen = false;
11814 int declare_simd_cnt = -1;
11815 auto_vec<enum tree_code, 16> codes;
11816 for (struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; ctx;)
11818 if (((ctx->region_type & ORT_PARALLEL) && ctx->code == OMP_PARALLEL)
11819 || ((ctx->region_type & (ORT_TARGET | ORT_IMPLICIT_TARGET | ORT_ACC))
11820 == ORT_TARGET && ctx->code == OMP_TARGET)
11821 || ((ctx->region_type & ORT_TEAMS) && ctx->code == OMP_TEAMS)
11822 || (ctx->region_type == ORT_WORKSHARE && ctx->code == OMP_FOR)
11823 || (ctx->region_type == ORT_SIMD
11824 && ctx->code == OMP_SIMD
11825 && !omp_find_clause (ctx->clauses, OMP_CLAUSE_BIND)))
11827 ++cnt;
11828 if (scores)
11829 codes.safe_push (ctx->code);
11830 else if (matched < nconstructs && ctx->code == constructs[matched])
11832 if (ctx->code == OMP_SIMD)
11834 if (matched)
11835 return 0;
11836 simd_seen = true;
11838 ++matched;
11840 if (ctx->code == OMP_TARGET)
11842 if (scores == NULL)
11843 return matched < nconstructs ? 0 : simd_seen ? -1 : 1;
11844 target_seen = true;
11845 break;
11848 else if (ctx->region_type == ORT_WORKSHARE
11849 && ctx->code == OMP_LOOP
11850 && ctx->outer_context
11851 && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL
11852 && ctx->outer_context->outer_context
11853 && ctx->outer_context->outer_context->code == OMP_LOOP
11854 && ctx->outer_context->outer_context->distribute)
11855 ctx = ctx->outer_context->outer_context;
11856 ctx = ctx->outer_context;
11858 if (!target_seen
11859 && lookup_attribute ("omp declare simd",
11860 DECL_ATTRIBUTES (current_function_decl)))
11862 /* Declare simd is a maybe case, it is supposed to be added only to the
11863 omp-simd-clone.cc added clones and not to the base function. */
11864 declare_simd_cnt = cnt++;
11865 if (scores)
11866 codes.safe_push (OMP_SIMD);
11867 else if (cnt == 0
11868 && constructs[0] == OMP_SIMD)
11870 gcc_assert (matched == 0);
11871 simd_seen = true;
11872 if (++matched == nconstructs)
11873 return -1;
11876 if (tree attr = lookup_attribute ("omp declare variant variant",
11877 DECL_ATTRIBUTES (current_function_decl)))
11879 enum tree_code variant_constructs[5];
11880 int variant_nconstructs = 0;
11881 if (!target_seen)
11882 variant_nconstructs
11883 = omp_constructor_traits_to_codes (TREE_VALUE (attr),
11884 variant_constructs);
11885 for (int i = 0; i < variant_nconstructs; i++)
11887 ++cnt;
11888 if (scores)
11889 codes.safe_push (variant_constructs[i]);
11890 else if (matched < nconstructs
11891 && variant_constructs[i] == constructs[matched])
11893 if (variant_constructs[i] == OMP_SIMD)
11895 if (matched)
11896 return 0;
11897 simd_seen = true;
11899 ++matched;
11903 if (!target_seen
11904 && lookup_attribute ("omp declare target block",
11905 DECL_ATTRIBUTES (current_function_decl)))
11907 if (scores)
11908 codes.safe_push (OMP_TARGET);
11909 else if (matched < nconstructs && constructs[matched] == OMP_TARGET)
11910 ++matched;
11912 if (scores)
11914 for (int pass = 0; pass < (declare_simd_cnt == -1 ? 1 : 2); pass++)
11916 int j = codes.length () - 1;
11917 for (int i = nconstructs - 1; i >= 0; i--)
11919 while (j >= 0
11920 && (pass != 0 || declare_simd_cnt != j)
11921 && constructs[i] != codes[j])
11922 --j;
11923 if (pass == 0 && declare_simd_cnt != -1 && j > declare_simd_cnt)
11924 *scores++ = j - 1;
11925 else
11926 *scores++ = j;
11928 *scores++ = ((pass == 0 && declare_simd_cnt != -1)
11929 ? codes.length () - 1 : codes.length ());
11931 return declare_simd_cnt == -1 ? 1 : 2;
11933 if (matched == nconstructs)
11934 return simd_seen ? -1 : 1;
11935 return 0;
11938 /* Gimplify OACC_CACHE. */
11940 static void
11941 gimplify_oacc_cache (tree *expr_p, gimple_seq *pre_p)
11943 tree expr = *expr_p;
11945 gimplify_scan_omp_clauses (&OACC_CACHE_CLAUSES (expr), pre_p, ORT_ACC,
11946 OACC_CACHE);
11947 gimplify_adjust_omp_clauses (pre_p, NULL, &OACC_CACHE_CLAUSES (expr),
11948 OACC_CACHE);
11950 /* TODO: Do something sensible with this information. */
11952 *expr_p = NULL_TREE;
11955 /* Helper function of gimplify_oacc_declare. The helper's purpose is to,
11956 if required, translate 'kind' in CLAUSE into an 'entry' kind and 'exit'
11957 kind. The entry kind will replace the one in CLAUSE, while the exit
11958 kind will be used in a new omp_clause and returned to the caller. */
11960 static tree
11961 gimplify_oacc_declare_1 (tree clause)
11963 HOST_WIDE_INT kind, new_op;
11964 bool ret = false;
11965 tree c = NULL;
11967 kind = OMP_CLAUSE_MAP_KIND (clause);
11969 switch (kind)
11971 case GOMP_MAP_ALLOC:
11972 new_op = GOMP_MAP_RELEASE;
11973 ret = true;
11974 break;
11976 case GOMP_MAP_FROM:
11977 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_FORCE_ALLOC);
11978 new_op = GOMP_MAP_FROM;
11979 ret = true;
11980 break;
11982 case GOMP_MAP_TOFROM:
11983 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_TO);
11984 new_op = GOMP_MAP_FROM;
11985 ret = true;
11986 break;
11988 case GOMP_MAP_DEVICE_RESIDENT:
11989 case GOMP_MAP_FORCE_DEVICEPTR:
11990 case GOMP_MAP_FORCE_PRESENT:
11991 case GOMP_MAP_LINK:
11992 case GOMP_MAP_POINTER:
11993 case GOMP_MAP_TO:
11994 break;
11996 default:
11997 gcc_unreachable ();
11998 break;
12001 if (ret)
12003 c = build_omp_clause (OMP_CLAUSE_LOCATION (clause), OMP_CLAUSE_MAP);
12004 OMP_CLAUSE_SET_MAP_KIND (c, new_op);
12005 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clause);
12008 return c;
12011 /* Gimplify OACC_DECLARE. */
12013 static void
12014 gimplify_oacc_declare (tree *expr_p, gimple_seq *pre_p)
12016 tree expr = *expr_p;
12017 gomp_target *stmt;
12018 tree clauses, t, decl;
12020 clauses = OACC_DECLARE_CLAUSES (expr);
12022 gimplify_scan_omp_clauses (&clauses, pre_p, ORT_TARGET_DATA, OACC_DECLARE);
12023 gimplify_adjust_omp_clauses (pre_p, NULL, &clauses, OACC_DECLARE);
12025 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
12027 decl = OMP_CLAUSE_DECL (t);
12029 if (TREE_CODE (decl) == MEM_REF)
12030 decl = TREE_OPERAND (decl, 0);
12032 if (VAR_P (decl) && !is_oacc_declared (decl))
12034 tree attr = get_identifier ("oacc declare target");
12035 DECL_ATTRIBUTES (decl) = tree_cons (attr, NULL_TREE,
12036 DECL_ATTRIBUTES (decl));
12039 if (VAR_P (decl)
12040 && !is_global_var (decl)
12041 && DECL_CONTEXT (decl) == current_function_decl)
12043 tree c = gimplify_oacc_declare_1 (t);
12044 if (c)
12046 if (oacc_declare_returns == NULL)
12047 oacc_declare_returns = new hash_map<tree, tree>;
12049 oacc_declare_returns->put (decl, c);
12053 if (gimplify_omp_ctxp)
12054 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_SEEN);
12057 stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
12058 clauses);
12060 gimplify_seq_add_stmt (pre_p, stmt);
12062 *expr_p = NULL_TREE;
12065 /* Gimplify the contents of an OMP_PARALLEL statement. This involves
12066 gimplification of the body, as well as scanning the body for used
12067 variables. We need to do this scan now, because variable-sized
12068 decls will be decomposed during gimplification. */
12070 static void
12071 gimplify_omp_parallel (tree *expr_p, gimple_seq *pre_p)
12073 tree expr = *expr_p;
12074 gimple *g;
12075 gimple_seq body = NULL;
12077 gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr), pre_p,
12078 OMP_PARALLEL_COMBINED (expr)
12079 ? ORT_COMBINED_PARALLEL
12080 : ORT_PARALLEL, OMP_PARALLEL);
12082 push_gimplify_context ();
12084 g = gimplify_and_return_first (OMP_PARALLEL_BODY (expr), &body);
12085 if (gimple_code (g) == GIMPLE_BIND)
12086 pop_gimplify_context (g);
12087 else
12088 pop_gimplify_context (NULL);
12090 gimplify_adjust_omp_clauses (pre_p, body, &OMP_PARALLEL_CLAUSES (expr),
12091 OMP_PARALLEL);
12093 g = gimple_build_omp_parallel (body,
12094 OMP_PARALLEL_CLAUSES (expr),
12095 NULL_TREE, NULL_TREE);
12096 if (OMP_PARALLEL_COMBINED (expr))
12097 gimple_omp_set_subcode (g, GF_OMP_PARALLEL_COMBINED);
12098 gimplify_seq_add_stmt (pre_p, g);
12099 *expr_p = NULL_TREE;
12102 /* Gimplify the contents of an OMP_TASK statement. This involves
12103 gimplification of the body, as well as scanning the body for used
12104 variables. We need to do this scan now, because variable-sized
12105 decls will be decomposed during gimplification. */
12107 static void
12108 gimplify_omp_task (tree *expr_p, gimple_seq *pre_p)
12110 tree expr = *expr_p;
12111 gimple *g;
12112 gimple_seq body = NULL;
12114 if (OMP_TASK_BODY (expr) == NULL_TREE)
12115 for (tree c = OMP_TASK_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
12116 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
12117 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_MUTEXINOUTSET)
12119 error_at (OMP_CLAUSE_LOCATION (c),
12120 "%<mutexinoutset%> kind in %<depend%> clause on a "
12121 "%<taskwait%> construct");
12122 break;
12125 gimplify_scan_omp_clauses (&OMP_TASK_CLAUSES (expr), pre_p,
12126 omp_find_clause (OMP_TASK_CLAUSES (expr),
12127 OMP_CLAUSE_UNTIED)
12128 ? ORT_UNTIED_TASK : ORT_TASK, OMP_TASK);
12130 if (OMP_TASK_BODY (expr))
12132 push_gimplify_context ();
12134 g = gimplify_and_return_first (OMP_TASK_BODY (expr), &body);
12135 if (gimple_code (g) == GIMPLE_BIND)
12136 pop_gimplify_context (g);
12137 else
12138 pop_gimplify_context (NULL);
12141 gimplify_adjust_omp_clauses (pre_p, body, &OMP_TASK_CLAUSES (expr),
12142 OMP_TASK);
12144 g = gimple_build_omp_task (body,
12145 OMP_TASK_CLAUSES (expr),
12146 NULL_TREE, NULL_TREE,
12147 NULL_TREE, NULL_TREE, NULL_TREE);
12148 if (OMP_TASK_BODY (expr) == NULL_TREE)
12149 gimple_omp_task_set_taskwait_p (g, true);
12150 gimplify_seq_add_stmt (pre_p, g);
12151 *expr_p = NULL_TREE;
12154 /* Helper function for gimplify_omp_for. If *TP is not a gimple constant,
12155 force it into a temporary initialized in PRE_P and add firstprivate clause
12156 to ORIG_FOR_STMT. */
12158 static void
12159 gimplify_omp_taskloop_expr (tree type, tree *tp, gimple_seq *pre_p,
12160 tree orig_for_stmt)
12162 if (*tp == NULL || is_gimple_constant (*tp))
12163 return;
12165 *tp = get_initialized_tmp_var (*tp, pre_p, NULL, false);
12166 /* Reference to pointer conversion is considered useless,
12167 but is significant for firstprivate clause. Force it
12168 here. */
12169 if (type
12170 && TREE_CODE (type) == POINTER_TYPE
12171 && TREE_CODE (TREE_TYPE (*tp)) == REFERENCE_TYPE)
12173 tree v = create_tmp_var (TYPE_MAIN_VARIANT (type));
12174 tree m = build2 (INIT_EXPR, TREE_TYPE (v), v, *tp);
12175 gimplify_and_add (m, pre_p);
12176 *tp = v;
12179 tree c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
12180 OMP_CLAUSE_DECL (c) = *tp;
12181 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
12182 OMP_FOR_CLAUSES (orig_for_stmt) = c;
12185 /* Gimplify the gross structure of an OMP_FOR statement. */
12187 static enum gimplify_status
12188 gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
12190 tree for_stmt, orig_for_stmt, inner_for_stmt = NULL_TREE, decl, var, t;
12191 enum gimplify_status ret = GS_ALL_DONE;
12192 enum gimplify_status tret;
12193 gomp_for *gfor;
12194 gimple_seq for_body, for_pre_body;
12195 int i;
12196 bitmap has_decl_expr = NULL;
12197 enum omp_region_type ort = ORT_WORKSHARE;
12198 bool openacc = TREE_CODE (*expr_p) == OACC_LOOP;
12200 orig_for_stmt = for_stmt = *expr_p;
12202 bool loop_p = (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_BIND)
12203 != NULL_TREE);
12204 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
12206 tree *data[4] = { NULL, NULL, NULL, NULL };
12207 gcc_assert (TREE_CODE (for_stmt) != OACC_LOOP);
12208 inner_for_stmt = walk_tree (&OMP_FOR_BODY (for_stmt),
12209 find_combined_omp_for, data, NULL);
12210 if (inner_for_stmt == NULL_TREE)
12212 gcc_assert (seen_error ());
12213 *expr_p = NULL_TREE;
12214 return GS_ERROR;
12216 if (data[2] && OMP_FOR_PRE_BODY (*data[2]))
12218 append_to_statement_list_force (OMP_FOR_PRE_BODY (*data[2]),
12219 &OMP_FOR_PRE_BODY (for_stmt));
12220 OMP_FOR_PRE_BODY (*data[2]) = NULL_TREE;
12222 if (OMP_FOR_PRE_BODY (inner_for_stmt))
12224 append_to_statement_list_force (OMP_FOR_PRE_BODY (inner_for_stmt),
12225 &OMP_FOR_PRE_BODY (for_stmt));
12226 OMP_FOR_PRE_BODY (inner_for_stmt) = NULL_TREE;
12229 if (data[0])
12231 /* We have some statements or variable declarations in between
12232 the composite construct directives. Move them around the
12233 inner_for_stmt. */
12234 data[0] = expr_p;
12235 for (i = 0; i < 3; i++)
12236 if (data[i])
12238 tree t = *data[i];
12239 if (i < 2 && data[i + 1] == &OMP_BODY (t))
12240 data[i + 1] = data[i];
12241 *data[i] = OMP_BODY (t);
12242 tree body = build3 (BIND_EXPR, void_type_node, NULL_TREE,
12243 NULL_TREE, make_node (BLOCK));
12244 OMP_BODY (t) = body;
12245 append_to_statement_list_force (inner_for_stmt,
12246 &BIND_EXPR_BODY (body));
12247 *data[3] = t;
12248 data[3] = tsi_stmt_ptr (tsi_start (BIND_EXPR_BODY (body)));
12249 gcc_assert (*data[3] == inner_for_stmt);
12251 return GS_OK;
12254 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
12255 if (!loop_p
12256 && OMP_FOR_ORIG_DECLS (inner_for_stmt)
12257 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
12258 i)) == TREE_LIST
12259 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
12260 i)))
12262 tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
12263 /* Class iterators aren't allowed on OMP_SIMD, so the only
12264 case we need to solve is distribute parallel for. They are
12265 allowed on the loop construct, but that is already handled
12266 in gimplify_omp_loop. */
12267 gcc_assert (TREE_CODE (inner_for_stmt) == OMP_FOR
12268 && TREE_CODE (for_stmt) == OMP_DISTRIBUTE
12269 && data[1]);
12270 tree orig_decl = TREE_PURPOSE (orig);
12271 tree last = TREE_VALUE (orig);
12272 tree *pc;
12273 for (pc = &OMP_FOR_CLAUSES (inner_for_stmt);
12274 *pc; pc = &OMP_CLAUSE_CHAIN (*pc))
12275 if ((OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE
12276 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LASTPRIVATE)
12277 && OMP_CLAUSE_DECL (*pc) == orig_decl)
12278 break;
12279 if (*pc == NULL_TREE)
12281 tree *spc;
12282 for (spc = &OMP_PARALLEL_CLAUSES (*data[1]);
12283 *spc; spc = &OMP_CLAUSE_CHAIN (*spc))
12284 if (OMP_CLAUSE_CODE (*spc) == OMP_CLAUSE_PRIVATE
12285 && OMP_CLAUSE_DECL (*spc) == orig_decl)
12286 break;
12287 if (*spc)
12289 tree c = *spc;
12290 *spc = OMP_CLAUSE_CHAIN (c);
12291 OMP_CLAUSE_CHAIN (c) = NULL_TREE;
12292 *pc = c;
12295 if (*pc == NULL_TREE)
12297 else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE)
12299 /* private clause will appear only on inner_for_stmt.
12300 Change it into firstprivate, and add private clause
12301 on for_stmt. */
12302 tree c = copy_node (*pc);
12303 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
12304 OMP_FOR_CLAUSES (for_stmt) = c;
12305 OMP_CLAUSE_CODE (*pc) = OMP_CLAUSE_FIRSTPRIVATE;
12306 lang_hooks.decls.omp_finish_clause (*pc, pre_p, openacc);
12308 else
12310 /* lastprivate clause will appear on both inner_for_stmt
12311 and for_stmt. Add firstprivate clause to
12312 inner_for_stmt. */
12313 tree c = build_omp_clause (OMP_CLAUSE_LOCATION (*pc),
12314 OMP_CLAUSE_FIRSTPRIVATE);
12315 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (*pc);
12316 OMP_CLAUSE_CHAIN (c) = *pc;
12317 *pc = c;
12318 lang_hooks.decls.omp_finish_clause (*pc, pre_p, openacc);
12320 tree c = build_omp_clause (UNKNOWN_LOCATION,
12321 OMP_CLAUSE_FIRSTPRIVATE);
12322 OMP_CLAUSE_DECL (c) = last;
12323 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
12324 OMP_PARALLEL_CLAUSES (*data[1]) = c;
12325 c = build_omp_clause (UNKNOWN_LOCATION,
12326 *pc ? OMP_CLAUSE_SHARED
12327 : OMP_CLAUSE_FIRSTPRIVATE);
12328 OMP_CLAUSE_DECL (c) = orig_decl;
12329 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
12330 OMP_PARALLEL_CLAUSES (*data[1]) = c;
12332 /* Similarly, take care of C++ range for temporaries, those should
12333 be firstprivate on OMP_PARALLEL if any. */
12334 if (data[1])
12335 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
12336 if (OMP_FOR_ORIG_DECLS (inner_for_stmt)
12337 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
12338 i)) == TREE_LIST
12339 && TREE_CHAIN (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
12340 i)))
12342 tree orig
12343 = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
12344 tree v = TREE_CHAIN (orig);
12345 tree c = build_omp_clause (UNKNOWN_LOCATION,
12346 OMP_CLAUSE_FIRSTPRIVATE);
12347 /* First add firstprivate clause for the __for_end artificial
12348 decl. */
12349 OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 1);
12350 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
12351 == REFERENCE_TYPE)
12352 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
12353 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
12354 OMP_PARALLEL_CLAUSES (*data[1]) = c;
12355 if (TREE_VEC_ELT (v, 0))
12357 /* And now the same for __for_range artificial decl if it
12358 exists. */
12359 c = build_omp_clause (UNKNOWN_LOCATION,
12360 OMP_CLAUSE_FIRSTPRIVATE);
12361 OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 0);
12362 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
12363 == REFERENCE_TYPE)
12364 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
12365 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
12366 OMP_PARALLEL_CLAUSES (*data[1]) = c;
12371 switch (TREE_CODE (for_stmt))
12373 case OMP_FOR:
12374 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt))
12376 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
12377 OMP_CLAUSE_SCHEDULE))
12378 error_at (EXPR_LOCATION (for_stmt),
12379 "%qs clause may not appear on non-rectangular %qs",
12380 "schedule", "for");
12381 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED))
12382 error_at (EXPR_LOCATION (for_stmt),
12383 "%qs clause may not appear on non-rectangular %qs",
12384 "ordered", "for");
12386 break;
12387 case OMP_DISTRIBUTE:
12388 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt)
12389 && omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
12390 OMP_CLAUSE_DIST_SCHEDULE))
12391 error_at (EXPR_LOCATION (for_stmt),
12392 "%qs clause may not appear on non-rectangular %qs",
12393 "dist_schedule", "distribute");
12394 break;
12395 case OACC_LOOP:
12396 ort = ORT_ACC;
12397 break;
12398 case OMP_TASKLOOP:
12399 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_UNTIED))
12400 ort = ORT_UNTIED_TASKLOOP;
12401 else
12402 ort = ORT_TASKLOOP;
12403 break;
12404 case OMP_SIMD:
12405 ort = ORT_SIMD;
12406 break;
12407 default:
12408 gcc_unreachable ();
12411 /* Set OMP_CLAUSE_LINEAR_NO_COPYIN flag on explicit linear
12412 clause for the IV. */
12413 if (ort == ORT_SIMD && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
12415 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), 0);
12416 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
12417 decl = TREE_OPERAND (t, 0);
12418 for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
12419 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
12420 && OMP_CLAUSE_DECL (c) == decl)
12422 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
12423 break;
12427 if (TREE_CODE (for_stmt) != OMP_TASKLOOP)
12428 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p, ort,
12429 loop_p && TREE_CODE (for_stmt) != OMP_SIMD
12430 ? OMP_LOOP : TREE_CODE (for_stmt));
12432 if (TREE_CODE (for_stmt) == OMP_DISTRIBUTE)
12433 gimplify_omp_ctxp->distribute = true;
12435 /* Handle OMP_FOR_INIT. */
12436 for_pre_body = NULL;
12437 if ((ort == ORT_SIMD
12438 || (inner_for_stmt && TREE_CODE (inner_for_stmt) == OMP_SIMD))
12439 && OMP_FOR_PRE_BODY (for_stmt))
12441 has_decl_expr = BITMAP_ALLOC (NULL);
12442 if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == DECL_EXPR
12443 && TREE_CODE (DECL_EXPR_DECL (OMP_FOR_PRE_BODY (for_stmt)))
12444 == VAR_DECL)
12446 t = OMP_FOR_PRE_BODY (for_stmt);
12447 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
12449 else if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == STATEMENT_LIST)
12451 tree_stmt_iterator si;
12452 for (si = tsi_start (OMP_FOR_PRE_BODY (for_stmt)); !tsi_end_p (si);
12453 tsi_next (&si))
12455 t = tsi_stmt (si);
12456 if (TREE_CODE (t) == DECL_EXPR
12457 && TREE_CODE (DECL_EXPR_DECL (t)) == VAR_DECL)
12458 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
12462 if (OMP_FOR_PRE_BODY (for_stmt))
12464 if (TREE_CODE (for_stmt) != OMP_TASKLOOP || gimplify_omp_ctxp)
12465 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
12466 else
12468 struct gimplify_omp_ctx ctx;
12469 memset (&ctx, 0, sizeof (ctx));
12470 ctx.region_type = ORT_NONE;
12471 gimplify_omp_ctxp = &ctx;
12472 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
12473 gimplify_omp_ctxp = NULL;
12476 OMP_FOR_PRE_BODY (for_stmt) = NULL_TREE;
12478 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
12479 for_stmt = inner_for_stmt;
12481 /* For taskloop, need to gimplify the start, end and step before the
12482 taskloop, outside of the taskloop omp context. */
12483 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
12485 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
12487 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
12488 gimple_seq *for_pre_p = (gimple_seq_empty_p (for_pre_body)
12489 ? pre_p : &for_pre_body);
12490 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
12491 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
12493 tree v = TREE_OPERAND (t, 1);
12494 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 1),
12495 for_pre_p, orig_for_stmt);
12496 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 2),
12497 for_pre_p, orig_for_stmt);
12499 else
12500 gimplify_omp_taskloop_expr (type, &TREE_OPERAND (t, 1), for_pre_p,
12501 orig_for_stmt);
12503 /* Handle OMP_FOR_COND. */
12504 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
12505 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
12507 tree v = TREE_OPERAND (t, 1);
12508 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 1),
12509 for_pre_p, orig_for_stmt);
12510 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 2),
12511 for_pre_p, orig_for_stmt);
12513 else
12514 gimplify_omp_taskloop_expr (type, &TREE_OPERAND (t, 1), for_pre_p,
12515 orig_for_stmt);
12517 /* Handle OMP_FOR_INCR. */
12518 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
12519 if (TREE_CODE (t) == MODIFY_EXPR)
12521 decl = TREE_OPERAND (t, 0);
12522 t = TREE_OPERAND (t, 1);
12523 tree *tp = &TREE_OPERAND (t, 1);
12524 if (TREE_CODE (t) == PLUS_EXPR && *tp == decl)
12525 tp = &TREE_OPERAND (t, 0);
12527 gimplify_omp_taskloop_expr (NULL_TREE, tp, for_pre_p,
12528 orig_for_stmt);
12532 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (orig_for_stmt), pre_p, ort,
12533 OMP_TASKLOOP);
12536 if (orig_for_stmt != for_stmt)
12537 gimplify_omp_ctxp->combined_loop = true;
12539 for_body = NULL;
12540 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
12541 == TREE_VEC_LENGTH (OMP_FOR_COND (for_stmt)));
12542 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
12543 == TREE_VEC_LENGTH (OMP_FOR_INCR (for_stmt)));
12545 tree c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED);
12546 bool is_doacross = false;
12547 if (c && OMP_CLAUSE_ORDERED_EXPR (c))
12549 is_doacross = true;
12550 gimplify_omp_ctxp->loop_iter_var.create (TREE_VEC_LENGTH
12551 (OMP_FOR_INIT (for_stmt))
12552 * 2);
12554 int collapse = 1, tile = 0;
12555 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_COLLAPSE);
12556 if (c)
12557 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (c));
12558 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_TILE);
12559 if (c)
12560 tile = list_length (OMP_CLAUSE_TILE_LIST (c));
12561 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ALLOCATE);
12562 hash_set<tree> *allocate_uids = NULL;
12563 if (c)
12565 allocate_uids = new hash_set<tree>;
12566 for (; c; c = OMP_CLAUSE_CHAIN (c))
12567 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ALLOCATE)
12568 allocate_uids->add (OMP_CLAUSE_DECL (c));
12570 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
12572 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
12573 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
12574 decl = TREE_OPERAND (t, 0);
12575 gcc_assert (DECL_P (decl));
12576 gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl))
12577 || POINTER_TYPE_P (TREE_TYPE (decl)));
12578 if (is_doacross)
12580 if (TREE_CODE (for_stmt) == OMP_FOR && OMP_FOR_ORIG_DECLS (for_stmt))
12582 tree orig_decl = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
12583 if (TREE_CODE (orig_decl) == TREE_LIST)
12585 orig_decl = TREE_PURPOSE (orig_decl);
12586 if (!orig_decl)
12587 orig_decl = decl;
12589 gimplify_omp_ctxp->loop_iter_var.quick_push (orig_decl);
12591 else
12592 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
12593 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
12596 if (for_stmt == orig_for_stmt)
12598 tree orig_decl = decl;
12599 if (OMP_FOR_ORIG_DECLS (for_stmt))
12601 tree orig_decl = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
12602 if (TREE_CODE (orig_decl) == TREE_LIST)
12604 orig_decl = TREE_PURPOSE (orig_decl);
12605 if (!orig_decl)
12606 orig_decl = decl;
12609 if (is_global_var (orig_decl) && DECL_THREAD_LOCAL_P (orig_decl))
12610 error_at (EXPR_LOCATION (for_stmt),
12611 "threadprivate iteration variable %qD", orig_decl);
12614 /* Make sure the iteration variable is private. */
12615 tree c = NULL_TREE;
12616 tree c2 = NULL_TREE;
12617 if (orig_for_stmt != for_stmt)
12619 /* Preserve this information until we gimplify the inner simd. */
12620 if (has_decl_expr
12621 && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
12622 TREE_PRIVATE (t) = 1;
12624 else if (ort == ORT_SIMD)
12626 splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
12627 (splay_tree_key) decl);
12628 omp_is_private (gimplify_omp_ctxp, decl,
12629 1 + (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
12630 != 1));
12631 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
12633 omp_notice_variable (gimplify_omp_ctxp, decl, true);
12634 if (n->value & GOVD_LASTPRIVATE_CONDITIONAL)
12635 for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
12636 OMP_CLAUSE_LASTPRIVATE);
12637 c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
12638 OMP_CLAUSE_LASTPRIVATE))
12639 if (OMP_CLAUSE_DECL (c3) == decl)
12641 warning_at (OMP_CLAUSE_LOCATION (c3), 0,
12642 "conditional %<lastprivate%> on loop "
12643 "iterator %qD ignored", decl);
12644 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
12645 n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
12648 else if (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1 && !loop_p)
12650 c = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
12651 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
12652 unsigned int flags = GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN;
12653 if ((has_decl_expr
12654 && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
12655 || TREE_PRIVATE (t))
12657 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
12658 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
12660 struct gimplify_omp_ctx *outer
12661 = gimplify_omp_ctxp->outer_context;
12662 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
12664 if (outer->region_type == ORT_WORKSHARE
12665 && outer->combined_loop)
12667 n = splay_tree_lookup (outer->variables,
12668 (splay_tree_key)decl);
12669 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
12671 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
12672 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
12674 else
12676 struct gimplify_omp_ctx *octx = outer->outer_context;
12677 if (octx
12678 && octx->region_type == ORT_COMBINED_PARALLEL
12679 && octx->outer_context
12680 && (octx->outer_context->region_type
12681 == ORT_WORKSHARE)
12682 && octx->outer_context->combined_loop)
12684 octx = octx->outer_context;
12685 n = splay_tree_lookup (octx->variables,
12686 (splay_tree_key)decl);
12687 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
12689 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
12690 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
12697 OMP_CLAUSE_DECL (c) = decl;
12698 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
12699 OMP_FOR_CLAUSES (for_stmt) = c;
12700 omp_add_variable (gimplify_omp_ctxp, decl, flags);
12701 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
12702 omp_lastprivate_for_combined_outer_constructs (outer, decl,
12703 true);
12705 else
12707 bool lastprivate
12708 = (!has_decl_expr
12709 || !bitmap_bit_p (has_decl_expr, DECL_UID (decl)));
12710 if (TREE_PRIVATE (t))
12711 lastprivate = false;
12712 if (loop_p && OMP_FOR_ORIG_DECLS (for_stmt))
12714 tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
12715 if (TREE_CODE (elt) == TREE_LIST && TREE_PURPOSE (elt))
12716 lastprivate = false;
12719 struct gimplify_omp_ctx *outer
12720 = gimplify_omp_ctxp->outer_context;
12721 if (outer && lastprivate)
12722 omp_lastprivate_for_combined_outer_constructs (outer, decl,
12723 true);
12725 c = build_omp_clause (input_location,
12726 lastprivate ? OMP_CLAUSE_LASTPRIVATE
12727 : OMP_CLAUSE_PRIVATE);
12728 OMP_CLAUSE_DECL (c) = decl;
12729 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
12730 OMP_FOR_CLAUSES (for_stmt) = c;
12731 omp_add_variable (gimplify_omp_ctxp, decl,
12732 (lastprivate ? GOVD_LASTPRIVATE : GOVD_PRIVATE)
12733 | GOVD_EXPLICIT | GOVD_SEEN);
12734 c = NULL_TREE;
12737 else if (omp_is_private (gimplify_omp_ctxp, decl, 0))
12739 omp_notice_variable (gimplify_omp_ctxp, decl, true);
12740 splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
12741 (splay_tree_key) decl);
12742 if (n && (n->value & GOVD_LASTPRIVATE_CONDITIONAL))
12743 for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
12744 OMP_CLAUSE_LASTPRIVATE);
12745 c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
12746 OMP_CLAUSE_LASTPRIVATE))
12747 if (OMP_CLAUSE_DECL (c3) == decl)
12749 warning_at (OMP_CLAUSE_LOCATION (c3), 0,
12750 "conditional %<lastprivate%> on loop "
12751 "iterator %qD ignored", decl);
12752 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
12753 n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
12756 else
12757 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN);
12759 /* If DECL is not a gimple register, create a temporary variable to act
12760 as an iteration counter. This is valid, since DECL cannot be
12761 modified in the body of the loop. Similarly for any iteration vars
12762 in simd with collapse > 1 where the iterator vars must be
12763 lastprivate. And similarly for vars mentioned in allocate clauses. */
12764 if (orig_for_stmt != for_stmt)
12765 var = decl;
12766 else if (!is_gimple_reg (decl)
12767 || (ort == ORT_SIMD
12768 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) > 1)
12769 || (allocate_uids && allocate_uids->contains (decl)))
12771 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
12772 /* Make sure omp_add_variable is not called on it prematurely.
12773 We call it ourselves a few lines later. */
12774 gimplify_omp_ctxp = NULL;
12775 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
12776 gimplify_omp_ctxp = ctx;
12777 TREE_OPERAND (t, 0) = var;
12779 gimplify_seq_add_stmt (&for_body, gimple_build_assign (decl, var));
12781 if (ort == ORT_SIMD
12782 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
12784 c2 = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
12785 OMP_CLAUSE_LINEAR_NO_COPYIN (c2) = 1;
12786 OMP_CLAUSE_LINEAR_NO_COPYOUT (c2) = 1;
12787 OMP_CLAUSE_DECL (c2) = var;
12788 OMP_CLAUSE_CHAIN (c2) = OMP_FOR_CLAUSES (for_stmt);
12789 OMP_FOR_CLAUSES (for_stmt) = c2;
12790 omp_add_variable (gimplify_omp_ctxp, var,
12791 GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN);
12792 if (c == NULL_TREE)
12794 c = c2;
12795 c2 = NULL_TREE;
12798 else
12799 omp_add_variable (gimplify_omp_ctxp, var,
12800 GOVD_PRIVATE | GOVD_SEEN);
12802 else
12803 var = decl;
12805 gimplify_omp_ctxp->in_for_exprs = true;
12806 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
12808 tree lb = TREE_OPERAND (t, 1);
12809 tret = gimplify_expr (&TREE_VEC_ELT (lb, 1), &for_pre_body, NULL,
12810 is_gimple_val, fb_rvalue, false);
12811 ret = MIN (ret, tret);
12812 tret = gimplify_expr (&TREE_VEC_ELT (lb, 2), &for_pre_body, NULL,
12813 is_gimple_val, fb_rvalue, false);
12815 else
12816 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
12817 is_gimple_val, fb_rvalue, false);
12818 gimplify_omp_ctxp->in_for_exprs = false;
12819 ret = MIN (ret, tret);
12820 if (ret == GS_ERROR)
12821 return ret;
12823 /* Handle OMP_FOR_COND. */
12824 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
12825 gcc_assert (COMPARISON_CLASS_P (t));
12826 gcc_assert (TREE_OPERAND (t, 0) == decl);
12828 gimplify_omp_ctxp->in_for_exprs = true;
12829 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
12831 tree ub = TREE_OPERAND (t, 1);
12832 tret = gimplify_expr (&TREE_VEC_ELT (ub, 1), &for_pre_body, NULL,
12833 is_gimple_val, fb_rvalue, false);
12834 ret = MIN (ret, tret);
12835 tret = gimplify_expr (&TREE_VEC_ELT (ub, 2), &for_pre_body, NULL,
12836 is_gimple_val, fb_rvalue, false);
12838 else
12839 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
12840 is_gimple_val, fb_rvalue, false);
12841 gimplify_omp_ctxp->in_for_exprs = false;
12842 ret = MIN (ret, tret);
12844 /* Handle OMP_FOR_INCR. */
12845 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
12846 switch (TREE_CODE (t))
12848 case PREINCREMENT_EXPR:
12849 case POSTINCREMENT_EXPR:
12851 tree decl = TREE_OPERAND (t, 0);
12852 /* c_omp_for_incr_canonicalize_ptr() should have been
12853 called to massage things appropriately. */
12854 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
12856 if (orig_for_stmt != for_stmt)
12857 break;
12858 t = build_int_cst (TREE_TYPE (decl), 1);
12859 if (c)
12860 OMP_CLAUSE_LINEAR_STEP (c) = t;
12861 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
12862 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
12863 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
12864 break;
12867 case PREDECREMENT_EXPR:
12868 case POSTDECREMENT_EXPR:
12869 /* c_omp_for_incr_canonicalize_ptr() should have been
12870 called to massage things appropriately. */
12871 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
12872 if (orig_for_stmt != for_stmt)
12873 break;
12874 t = build_int_cst (TREE_TYPE (decl), -1);
12875 if (c)
12876 OMP_CLAUSE_LINEAR_STEP (c) = t;
12877 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
12878 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
12879 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
12880 break;
12882 case MODIFY_EXPR:
12883 gcc_assert (TREE_OPERAND (t, 0) == decl);
12884 TREE_OPERAND (t, 0) = var;
12886 t = TREE_OPERAND (t, 1);
12887 switch (TREE_CODE (t))
12889 case PLUS_EXPR:
12890 if (TREE_OPERAND (t, 1) == decl)
12892 TREE_OPERAND (t, 1) = TREE_OPERAND (t, 0);
12893 TREE_OPERAND (t, 0) = var;
12894 break;
12897 /* Fallthru. */
12898 case MINUS_EXPR:
12899 case POINTER_PLUS_EXPR:
12900 gcc_assert (TREE_OPERAND (t, 0) == decl);
12901 TREE_OPERAND (t, 0) = var;
12902 break;
12903 default:
12904 gcc_unreachable ();
12907 gimplify_omp_ctxp->in_for_exprs = true;
12908 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
12909 is_gimple_val, fb_rvalue, false);
12910 ret = MIN (ret, tret);
12911 if (c)
12913 tree step = TREE_OPERAND (t, 1);
12914 tree stept = TREE_TYPE (decl);
12915 if (POINTER_TYPE_P (stept))
12916 stept = sizetype;
12917 step = fold_convert (stept, step);
12918 if (TREE_CODE (t) == MINUS_EXPR)
12919 step = fold_build1 (NEGATE_EXPR, stept, step);
12920 OMP_CLAUSE_LINEAR_STEP (c) = step;
12921 if (step != TREE_OPERAND (t, 1))
12923 tret = gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c),
12924 &for_pre_body, NULL,
12925 is_gimple_val, fb_rvalue, false);
12926 ret = MIN (ret, tret);
12929 gimplify_omp_ctxp->in_for_exprs = false;
12930 break;
12932 default:
12933 gcc_unreachable ();
12936 if (c2)
12938 gcc_assert (c);
12939 OMP_CLAUSE_LINEAR_STEP (c2) = OMP_CLAUSE_LINEAR_STEP (c);
12942 if ((var != decl || collapse > 1 || tile) && orig_for_stmt == for_stmt)
12944 for (c = OMP_FOR_CLAUSES (for_stmt); c ; c = OMP_CLAUSE_CHAIN (c))
12945 if (((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
12946 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) == NULL)
12947 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
12948 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)
12949 && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c) == NULL))
12950 && OMP_CLAUSE_DECL (c) == decl)
12952 if (is_doacross && (collapse == 1 || i >= collapse))
12953 t = var;
12954 else
12956 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
12957 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
12958 gcc_assert (TREE_OPERAND (t, 0) == var);
12959 t = TREE_OPERAND (t, 1);
12960 gcc_assert (TREE_CODE (t) == PLUS_EXPR
12961 || TREE_CODE (t) == MINUS_EXPR
12962 || TREE_CODE (t) == POINTER_PLUS_EXPR);
12963 gcc_assert (TREE_OPERAND (t, 0) == var);
12964 t = build2 (TREE_CODE (t), TREE_TYPE (decl),
12965 is_doacross ? var : decl,
12966 TREE_OPERAND (t, 1));
12968 gimple_seq *seq;
12969 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
12970 seq = &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c);
12971 else
12972 seq = &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c);
12973 push_gimplify_context ();
12974 gimplify_assign (decl, t, seq);
12975 gimple *bind = NULL;
12976 if (gimplify_ctxp->temps)
12978 bind = gimple_build_bind (NULL_TREE, *seq, NULL_TREE);
12979 *seq = NULL;
12980 gimplify_seq_add_stmt (seq, bind);
12982 pop_gimplify_context (bind);
12985 if (OMP_FOR_NON_RECTANGULAR (for_stmt) && var != decl)
12986 for (int j = i + 1; j < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); j++)
12988 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), j);
12989 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
12990 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
12991 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
12992 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
12993 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), j);
12994 gcc_assert (COMPARISON_CLASS_P (t));
12995 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
12996 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
12997 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
13001 BITMAP_FREE (has_decl_expr);
13002 delete allocate_uids;
13004 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP
13005 || (loop_p && orig_for_stmt == for_stmt))
13007 push_gimplify_context ();
13008 if (TREE_CODE (OMP_FOR_BODY (orig_for_stmt)) != BIND_EXPR)
13010 OMP_FOR_BODY (orig_for_stmt)
13011 = build3 (BIND_EXPR, void_type_node, NULL,
13012 OMP_FOR_BODY (orig_for_stmt), NULL);
13013 TREE_SIDE_EFFECTS (OMP_FOR_BODY (orig_for_stmt)) = 1;
13017 gimple *g = gimplify_and_return_first (OMP_FOR_BODY (orig_for_stmt),
13018 &for_body);
13020 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP
13021 || (loop_p && orig_for_stmt == for_stmt))
13023 if (gimple_code (g) == GIMPLE_BIND)
13024 pop_gimplify_context (g);
13025 else
13026 pop_gimplify_context (NULL);
13029 if (orig_for_stmt != for_stmt)
13030 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
13032 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
13033 decl = TREE_OPERAND (t, 0);
13034 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
13035 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
13036 gimplify_omp_ctxp = ctx->outer_context;
13037 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
13038 gimplify_omp_ctxp = ctx;
13039 omp_add_variable (gimplify_omp_ctxp, var, GOVD_PRIVATE | GOVD_SEEN);
13040 TREE_OPERAND (t, 0) = var;
13041 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
13042 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
13043 TREE_OPERAND (TREE_OPERAND (t, 1), 0) = var;
13044 if (OMP_FOR_NON_RECTANGULAR (for_stmt))
13045 for (int j = i + 1;
13046 j < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); j++)
13048 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), j);
13049 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
13050 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
13051 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
13053 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
13054 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
13056 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), j);
13057 gcc_assert (COMPARISON_CLASS_P (t));
13058 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
13059 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
13061 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
13062 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
13067 gimplify_adjust_omp_clauses (pre_p, for_body,
13068 &OMP_FOR_CLAUSES (orig_for_stmt),
13069 TREE_CODE (orig_for_stmt));
13071 int kind;
13072 switch (TREE_CODE (orig_for_stmt))
13074 case OMP_FOR: kind = GF_OMP_FOR_KIND_FOR; break;
13075 case OMP_SIMD: kind = GF_OMP_FOR_KIND_SIMD; break;
13076 case OMP_DISTRIBUTE: kind = GF_OMP_FOR_KIND_DISTRIBUTE; break;
13077 case OMP_TASKLOOP: kind = GF_OMP_FOR_KIND_TASKLOOP; break;
13078 case OACC_LOOP: kind = GF_OMP_FOR_KIND_OACC_LOOP; break;
13079 default:
13080 gcc_unreachable ();
13082 if (loop_p && kind == GF_OMP_FOR_KIND_SIMD)
13084 gimplify_seq_add_seq (pre_p, for_pre_body);
13085 for_pre_body = NULL;
13087 gfor = gimple_build_omp_for (for_body, kind, OMP_FOR_CLAUSES (orig_for_stmt),
13088 TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)),
13089 for_pre_body);
13090 if (orig_for_stmt != for_stmt)
13091 gimple_omp_for_set_combined_p (gfor, true);
13092 if (gimplify_omp_ctxp
13093 && (gimplify_omp_ctxp->combined_loop
13094 || (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
13095 && gimplify_omp_ctxp->outer_context
13096 && gimplify_omp_ctxp->outer_context->combined_loop)))
13098 gimple_omp_for_set_combined_into_p (gfor, true);
13099 if (gimplify_omp_ctxp->combined_loop)
13100 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_SIMD);
13101 else
13102 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_FOR);
13105 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
13107 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
13108 gimple_omp_for_set_index (gfor, i, TREE_OPERAND (t, 0));
13109 gimple_omp_for_set_initial (gfor, i, TREE_OPERAND (t, 1));
13110 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
13111 gimple_omp_for_set_cond (gfor, i, TREE_CODE (t));
13112 gimple_omp_for_set_final (gfor, i, TREE_OPERAND (t, 1));
13113 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
13114 gimple_omp_for_set_incr (gfor, i, TREE_OPERAND (t, 1));
13117 /* OMP_TASKLOOP is gimplified as two GIMPLE_OMP_FOR taskloop
13118 constructs with GIMPLE_OMP_TASK sandwiched in between them.
13119 The outer taskloop stands for computing the number of iterations,
13120 counts for collapsed loops and holding taskloop specific clauses.
13121 The task construct stands for the effect of data sharing on the
13122 explicit task it creates and the inner taskloop stands for expansion
13123 of the static loop inside of the explicit task construct. */
13124 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
13126 tree *gfor_clauses_ptr = gimple_omp_for_clauses_ptr (gfor);
13127 tree task_clauses = NULL_TREE;
13128 tree c = *gfor_clauses_ptr;
13129 tree *gtask_clauses_ptr = &task_clauses;
13130 tree outer_for_clauses = NULL_TREE;
13131 tree *gforo_clauses_ptr = &outer_for_clauses;
13132 bitmap lastprivate_uids = NULL;
13133 if (omp_find_clause (c, OMP_CLAUSE_ALLOCATE))
13135 c = omp_find_clause (c, OMP_CLAUSE_LASTPRIVATE);
13136 if (c)
13138 lastprivate_uids = BITMAP_ALLOC (NULL);
13139 for (; c; c = omp_find_clause (OMP_CLAUSE_CHAIN (c),
13140 OMP_CLAUSE_LASTPRIVATE))
13141 bitmap_set_bit (lastprivate_uids,
13142 DECL_UID (OMP_CLAUSE_DECL (c)));
13144 c = *gfor_clauses_ptr;
13146 for (; c; c = OMP_CLAUSE_CHAIN (c))
13147 switch (OMP_CLAUSE_CODE (c))
13149 /* These clauses are allowed on task, move them there. */
13150 case OMP_CLAUSE_SHARED:
13151 case OMP_CLAUSE_FIRSTPRIVATE:
13152 case OMP_CLAUSE_DEFAULT:
13153 case OMP_CLAUSE_IF:
13154 case OMP_CLAUSE_UNTIED:
13155 case OMP_CLAUSE_FINAL:
13156 case OMP_CLAUSE_MERGEABLE:
13157 case OMP_CLAUSE_PRIORITY:
13158 case OMP_CLAUSE_REDUCTION:
13159 case OMP_CLAUSE_IN_REDUCTION:
13160 *gtask_clauses_ptr = c;
13161 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13162 break;
13163 case OMP_CLAUSE_PRIVATE:
13164 if (OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c))
13166 /* We want private on outer for and firstprivate
13167 on task. */
13168 *gtask_clauses_ptr
13169 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
13170 OMP_CLAUSE_FIRSTPRIVATE);
13171 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
13172 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL,
13173 openacc);
13174 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
13175 *gforo_clauses_ptr = c;
13176 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13178 else
13180 *gtask_clauses_ptr = c;
13181 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13183 break;
13184 /* These clauses go into outer taskloop clauses. */
13185 case OMP_CLAUSE_GRAINSIZE:
13186 case OMP_CLAUSE_NUM_TASKS:
13187 case OMP_CLAUSE_NOGROUP:
13188 *gforo_clauses_ptr = c;
13189 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13190 break;
13191 /* Collapse clause we duplicate on both taskloops. */
13192 case OMP_CLAUSE_COLLAPSE:
13193 *gfor_clauses_ptr = c;
13194 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13195 *gforo_clauses_ptr = copy_node (c);
13196 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
13197 break;
13198 /* For lastprivate, keep the clause on inner taskloop, and add
13199 a shared clause on task. If the same decl is also firstprivate,
13200 add also firstprivate clause on the inner taskloop. */
13201 case OMP_CLAUSE_LASTPRIVATE:
13202 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
13204 /* For taskloop C++ lastprivate IVs, we want:
13205 1) private on outer taskloop
13206 2) firstprivate and shared on task
13207 3) lastprivate on inner taskloop */
13208 *gtask_clauses_ptr
13209 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
13210 OMP_CLAUSE_FIRSTPRIVATE);
13211 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
13212 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL,
13213 openacc);
13214 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
13215 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c) = 1;
13216 *gforo_clauses_ptr = build_omp_clause (OMP_CLAUSE_LOCATION (c),
13217 OMP_CLAUSE_PRIVATE);
13218 OMP_CLAUSE_DECL (*gforo_clauses_ptr) = OMP_CLAUSE_DECL (c);
13219 OMP_CLAUSE_PRIVATE_TASKLOOP_IV (*gforo_clauses_ptr) = 1;
13220 TREE_TYPE (*gforo_clauses_ptr) = TREE_TYPE (c);
13221 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
13223 *gfor_clauses_ptr = c;
13224 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13225 *gtask_clauses_ptr
13226 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_SHARED);
13227 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
13228 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
13229 OMP_CLAUSE_SHARED_FIRSTPRIVATE (*gtask_clauses_ptr) = 1;
13230 gtask_clauses_ptr
13231 = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
13232 break;
13233 /* Allocate clause we duplicate on task and inner taskloop
13234 if the decl is lastprivate, otherwise just put on task. */
13235 case OMP_CLAUSE_ALLOCATE:
13236 if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
13237 && DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)))
13239 /* Additionally, put firstprivate clause on task
13240 for the allocator if it is not constant. */
13241 *gtask_clauses_ptr
13242 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
13243 OMP_CLAUSE_FIRSTPRIVATE);
13244 OMP_CLAUSE_DECL (*gtask_clauses_ptr)
13245 = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
13246 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
13248 if (lastprivate_uids
13249 && bitmap_bit_p (lastprivate_uids,
13250 DECL_UID (OMP_CLAUSE_DECL (c))))
13252 *gfor_clauses_ptr = c;
13253 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13254 *gtask_clauses_ptr = copy_node (c);
13255 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
13257 else
13259 *gtask_clauses_ptr = c;
13260 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13262 break;
13263 default:
13264 gcc_unreachable ();
13266 *gfor_clauses_ptr = NULL_TREE;
13267 *gtask_clauses_ptr = NULL_TREE;
13268 *gforo_clauses_ptr = NULL_TREE;
13269 BITMAP_FREE (lastprivate_uids);
13270 g = gimple_build_bind (NULL_TREE, gfor, NULL_TREE);
13271 g = gimple_build_omp_task (g, task_clauses, NULL_TREE, NULL_TREE,
13272 NULL_TREE, NULL_TREE, NULL_TREE);
13273 gimple_omp_task_set_taskloop_p (g, true);
13274 g = gimple_build_bind (NULL_TREE, g, NULL_TREE);
13275 gomp_for *gforo
13276 = gimple_build_omp_for (g, GF_OMP_FOR_KIND_TASKLOOP, outer_for_clauses,
13277 gimple_omp_for_collapse (gfor),
13278 gimple_omp_for_pre_body (gfor));
13279 gimple_omp_for_set_pre_body (gfor, NULL);
13280 gimple_omp_for_set_combined_p (gforo, true);
13281 gimple_omp_for_set_combined_into_p (gfor, true);
13282 for (i = 0; i < (int) gimple_omp_for_collapse (gfor); i++)
13284 tree type = TREE_TYPE (gimple_omp_for_index (gfor, i));
13285 tree v = create_tmp_var (type);
13286 gimple_omp_for_set_index (gforo, i, v);
13287 t = unshare_expr (gimple_omp_for_initial (gfor, i));
13288 gimple_omp_for_set_initial (gforo, i, t);
13289 gimple_omp_for_set_cond (gforo, i,
13290 gimple_omp_for_cond (gfor, i));
13291 t = unshare_expr (gimple_omp_for_final (gfor, i));
13292 gimple_omp_for_set_final (gforo, i, t);
13293 t = unshare_expr (gimple_omp_for_incr (gfor, i));
13294 gcc_assert (TREE_OPERAND (t, 0) == gimple_omp_for_index (gfor, i));
13295 TREE_OPERAND (t, 0) = v;
13296 gimple_omp_for_set_incr (gforo, i, t);
13297 t = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
13298 OMP_CLAUSE_DECL (t) = v;
13299 OMP_CLAUSE_CHAIN (t) = gimple_omp_for_clauses (gforo);
13300 gimple_omp_for_set_clauses (gforo, t);
13301 if (OMP_FOR_NON_RECTANGULAR (for_stmt))
13303 tree *p1 = NULL, *p2 = NULL;
13304 t = gimple_omp_for_initial (gforo, i);
13305 if (TREE_CODE (t) == TREE_VEC)
13306 p1 = &TREE_VEC_ELT (t, 0);
13307 t = gimple_omp_for_final (gforo, i);
13308 if (TREE_CODE (t) == TREE_VEC)
13310 if (p1)
13311 p2 = &TREE_VEC_ELT (t, 0);
13312 else
13313 p1 = &TREE_VEC_ELT (t, 0);
13315 if (p1)
13317 int j;
13318 for (j = 0; j < i; j++)
13319 if (*p1 == gimple_omp_for_index (gfor, j))
13321 *p1 = gimple_omp_for_index (gforo, j);
13322 if (p2)
13323 *p2 = *p1;
13324 break;
13326 gcc_assert (j < i);
13330 gimplify_seq_add_stmt (pre_p, gforo);
13332 else
13333 gimplify_seq_add_stmt (pre_p, gfor);
13335 if (TREE_CODE (orig_for_stmt) == OMP_FOR)
13337 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
13338 unsigned lastprivate_conditional = 0;
13339 while (ctx
13340 && (ctx->region_type == ORT_TARGET_DATA
13341 || ctx->region_type == ORT_TASKGROUP))
13342 ctx = ctx->outer_context;
13343 if (ctx && (ctx->region_type & ORT_PARALLEL) != 0)
13344 for (tree c = gimple_omp_for_clauses (gfor);
13345 c; c = OMP_CLAUSE_CHAIN (c))
13346 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
13347 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
13348 ++lastprivate_conditional;
13349 if (lastprivate_conditional)
13351 struct omp_for_data fd;
13352 omp_extract_for_data (gfor, &fd, NULL);
13353 tree type = build_array_type_nelts (unsigned_type_for (fd.iter_type),
13354 lastprivate_conditional);
13355 tree var = create_tmp_var_raw (type);
13356 tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__CONDTEMP_);
13357 OMP_CLAUSE_DECL (c) = var;
13358 OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor);
13359 gimple_omp_for_set_clauses (gfor, c);
13360 omp_add_variable (ctx, var, GOVD_CONDTEMP | GOVD_SEEN);
13363 else if (TREE_CODE (orig_for_stmt) == OMP_SIMD)
13365 unsigned lastprivate_conditional = 0;
13366 for (tree c = gimple_omp_for_clauses (gfor); c; c = OMP_CLAUSE_CHAIN (c))
13367 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
13368 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
13369 ++lastprivate_conditional;
13370 if (lastprivate_conditional)
13372 struct omp_for_data fd;
13373 omp_extract_for_data (gfor, &fd, NULL);
13374 tree type = unsigned_type_for (fd.iter_type);
13375 while (lastprivate_conditional--)
13377 tree c = build_omp_clause (UNKNOWN_LOCATION,
13378 OMP_CLAUSE__CONDTEMP_);
13379 OMP_CLAUSE_DECL (c) = create_tmp_var (type);
13380 OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor);
13381 gimple_omp_for_set_clauses (gfor, c);
13386 if (ret != GS_ALL_DONE)
13387 return GS_ERROR;
13388 *expr_p = NULL_TREE;
13389 return GS_ALL_DONE;
13392 /* Helper for gimplify_omp_loop, called through walk_tree. */
13394 static tree
13395 note_no_context_vars (tree *tp, int *, void *data)
13397 if (VAR_P (*tp)
13398 && DECL_CONTEXT (*tp) == NULL_TREE
13399 && !is_global_var (*tp))
13401 vec<tree> *d = (vec<tree> *) data;
13402 d->safe_push (*tp);
13403 DECL_CONTEXT (*tp) = current_function_decl;
13405 return NULL_TREE;
13408 /* Gimplify the gross structure of an OMP_LOOP statement. */
13410 static enum gimplify_status
13411 gimplify_omp_loop (tree *expr_p, gimple_seq *pre_p)
13413 tree for_stmt = *expr_p;
13414 tree clauses = OMP_FOR_CLAUSES (for_stmt);
13415 struct gimplify_omp_ctx *octx = gimplify_omp_ctxp;
13416 enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
13417 int i;
13419 /* If order is not present, the behavior is as if order(concurrent)
13420 appeared. */
13421 tree order = omp_find_clause (clauses, OMP_CLAUSE_ORDER);
13422 if (order == NULL_TREE)
13424 order = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_ORDER);
13425 OMP_CLAUSE_CHAIN (order) = clauses;
13426 OMP_FOR_CLAUSES (for_stmt) = clauses = order;
13429 tree bind = omp_find_clause (clauses, OMP_CLAUSE_BIND);
13430 if (bind == NULL_TREE)
13432 if (!flag_openmp) /* flag_openmp_simd */
13434 else if (octx && (octx->region_type & ORT_TEAMS) != 0)
13435 kind = OMP_CLAUSE_BIND_TEAMS;
13436 else if (octx && (octx->region_type & ORT_PARALLEL) != 0)
13437 kind = OMP_CLAUSE_BIND_PARALLEL;
13438 else
13440 for (; octx; octx = octx->outer_context)
13442 if ((octx->region_type & ORT_ACC) != 0
13443 || octx->region_type == ORT_NONE
13444 || octx->region_type == ORT_IMPLICIT_TARGET)
13445 continue;
13446 break;
13448 if (octx == NULL && !in_omp_construct)
13449 error_at (EXPR_LOCATION (for_stmt),
13450 "%<bind%> clause not specified on a %<loop%> "
13451 "construct not nested inside another OpenMP construct");
13453 bind = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_BIND);
13454 OMP_CLAUSE_CHAIN (bind) = clauses;
13455 OMP_CLAUSE_BIND_KIND (bind) = kind;
13456 OMP_FOR_CLAUSES (for_stmt) = bind;
13458 else
13459 switch (OMP_CLAUSE_BIND_KIND (bind))
13461 case OMP_CLAUSE_BIND_THREAD:
13462 break;
13463 case OMP_CLAUSE_BIND_PARALLEL:
13464 if (!flag_openmp) /* flag_openmp_simd */
13466 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
13467 break;
13469 for (; octx; octx = octx->outer_context)
13470 if (octx->region_type == ORT_SIMD
13471 && omp_find_clause (octx->clauses, OMP_CLAUSE_BIND) == NULL_TREE)
13473 error_at (EXPR_LOCATION (for_stmt),
13474 "%<bind(parallel)%> on a %<loop%> construct nested "
13475 "inside %<simd%> construct");
13476 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
13477 break;
13479 kind = OMP_CLAUSE_BIND_PARALLEL;
13480 break;
13481 case OMP_CLAUSE_BIND_TEAMS:
13482 if (!flag_openmp) /* flag_openmp_simd */
13484 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
13485 break;
13487 if ((octx
13488 && octx->region_type != ORT_IMPLICIT_TARGET
13489 && octx->region_type != ORT_NONE
13490 && (octx->region_type & ORT_TEAMS) == 0)
13491 || in_omp_construct)
13493 error_at (EXPR_LOCATION (for_stmt),
13494 "%<bind(teams)%> on a %<loop%> region not strictly "
13495 "nested inside of a %<teams%> region");
13496 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
13497 break;
13499 kind = OMP_CLAUSE_BIND_TEAMS;
13500 break;
13501 default:
13502 gcc_unreachable ();
13505 for (tree *pc = &OMP_FOR_CLAUSES (for_stmt); *pc; )
13506 switch (OMP_CLAUSE_CODE (*pc))
13508 case OMP_CLAUSE_REDUCTION:
13509 if (OMP_CLAUSE_REDUCTION_INSCAN (*pc))
13511 error_at (OMP_CLAUSE_LOCATION (*pc),
13512 "%<inscan%> %<reduction%> clause on "
13513 "%qs construct", "loop");
13514 OMP_CLAUSE_REDUCTION_INSCAN (*pc) = 0;
13516 if (OMP_CLAUSE_REDUCTION_TASK (*pc))
13518 error_at (OMP_CLAUSE_LOCATION (*pc),
13519 "invalid %<task%> reduction modifier on construct "
13520 "other than %<parallel%>, %qs or %<sections%>",
13521 lang_GNU_Fortran () ? "do" : "for");
13522 OMP_CLAUSE_REDUCTION_TASK (*pc) = 0;
13524 pc = &OMP_CLAUSE_CHAIN (*pc);
13525 break;
13526 case OMP_CLAUSE_LASTPRIVATE:
13527 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
13529 tree t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
13530 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
13531 if (OMP_CLAUSE_DECL (*pc) == TREE_OPERAND (t, 0))
13532 break;
13533 if (OMP_FOR_ORIG_DECLS (for_stmt)
13534 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt),
13535 i)) == TREE_LIST
13536 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt),
13537 i)))
13539 tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
13540 if (OMP_CLAUSE_DECL (*pc) == TREE_PURPOSE (orig))
13541 break;
13544 if (i == TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)))
13546 error_at (OMP_CLAUSE_LOCATION (*pc),
13547 "%<lastprivate%> clause on a %<loop%> construct refers "
13548 "to a variable %qD which is not the loop iterator",
13549 OMP_CLAUSE_DECL (*pc));
13550 *pc = OMP_CLAUSE_CHAIN (*pc);
13551 break;
13553 pc = &OMP_CLAUSE_CHAIN (*pc);
13554 break;
13555 default:
13556 pc = &OMP_CLAUSE_CHAIN (*pc);
13557 break;
13560 TREE_SET_CODE (for_stmt, OMP_SIMD);
13562 int last;
13563 switch (kind)
13565 case OMP_CLAUSE_BIND_THREAD: last = 0; break;
13566 case OMP_CLAUSE_BIND_PARALLEL: last = 1; break;
13567 case OMP_CLAUSE_BIND_TEAMS: last = 2; break;
13569 for (int pass = 1; pass <= last; pass++)
13571 if (pass == 2)
13573 tree bind = build3 (BIND_EXPR, void_type_node, NULL, NULL,
13574 make_node (BLOCK));
13575 append_to_statement_list (*expr_p, &BIND_EXPR_BODY (bind));
13576 *expr_p = make_node (OMP_PARALLEL);
13577 TREE_TYPE (*expr_p) = void_type_node;
13578 OMP_PARALLEL_BODY (*expr_p) = bind;
13579 OMP_PARALLEL_COMBINED (*expr_p) = 1;
13580 SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (for_stmt));
13581 tree *pc = &OMP_PARALLEL_CLAUSES (*expr_p);
13582 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
13583 if (OMP_FOR_ORIG_DECLS (for_stmt)
13584 && (TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i))
13585 == TREE_LIST))
13587 tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
13588 if (TREE_PURPOSE (elt) && TREE_VALUE (elt))
13590 *pc = build_omp_clause (UNKNOWN_LOCATION,
13591 OMP_CLAUSE_FIRSTPRIVATE);
13592 OMP_CLAUSE_DECL (*pc) = TREE_VALUE (elt);
13593 pc = &OMP_CLAUSE_CHAIN (*pc);
13597 tree t = make_node (pass == 2 ? OMP_DISTRIBUTE : OMP_FOR);
13598 tree *pc = &OMP_FOR_CLAUSES (t);
13599 TREE_TYPE (t) = void_type_node;
13600 OMP_FOR_BODY (t) = *expr_p;
13601 SET_EXPR_LOCATION (t, EXPR_LOCATION (for_stmt));
13602 for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
13603 switch (OMP_CLAUSE_CODE (c))
13605 case OMP_CLAUSE_BIND:
13606 case OMP_CLAUSE_ORDER:
13607 case OMP_CLAUSE_COLLAPSE:
13608 *pc = copy_node (c);
13609 pc = &OMP_CLAUSE_CHAIN (*pc);
13610 break;
13611 case OMP_CLAUSE_PRIVATE:
13612 case OMP_CLAUSE_FIRSTPRIVATE:
13613 /* Only needed on innermost. */
13614 break;
13615 case OMP_CLAUSE_LASTPRIVATE:
13616 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c) && pass != last)
13618 *pc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
13619 OMP_CLAUSE_FIRSTPRIVATE);
13620 OMP_CLAUSE_DECL (*pc) = OMP_CLAUSE_DECL (c);
13621 lang_hooks.decls.omp_finish_clause (*pc, NULL, false);
13622 pc = &OMP_CLAUSE_CHAIN (*pc);
13624 *pc = copy_node (c);
13625 OMP_CLAUSE_LASTPRIVATE_STMT (*pc) = NULL_TREE;
13626 TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
13627 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
13629 if (pass != last)
13630 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (*pc) = 1;
13631 else
13632 lang_hooks.decls.omp_finish_clause (*pc, NULL, false);
13633 OMP_CLAUSE_LASTPRIVATE_LOOP_IV (*pc) = 0;
13635 pc = &OMP_CLAUSE_CHAIN (*pc);
13636 break;
13637 case OMP_CLAUSE_REDUCTION:
13638 *pc = copy_node (c);
13639 OMP_CLAUSE_DECL (*pc) = unshare_expr (OMP_CLAUSE_DECL (c));
13640 TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
13641 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc))
13643 auto_vec<tree> no_context_vars;
13644 int walk_subtrees = 0;
13645 note_no_context_vars (&OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
13646 &walk_subtrees, &no_context_vars);
13647 if (tree p = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c))
13648 note_no_context_vars (&p, &walk_subtrees, &no_context_vars);
13649 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_INIT (c),
13650 note_no_context_vars,
13651 &no_context_vars);
13652 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_MERGE (c),
13653 note_no_context_vars,
13654 &no_context_vars);
13656 OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc)
13657 = copy_node (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c));
13658 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc))
13659 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc)
13660 = copy_node (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c));
13662 hash_map<tree, tree> decl_map;
13663 decl_map.put (OMP_CLAUSE_DECL (c), OMP_CLAUSE_DECL (c));
13664 decl_map.put (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
13665 OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc));
13666 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc))
13667 decl_map.put (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
13668 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc));
13670 copy_body_data id;
13671 memset (&id, 0, sizeof (id));
13672 id.src_fn = current_function_decl;
13673 id.dst_fn = current_function_decl;
13674 id.src_cfun = cfun;
13675 id.decl_map = &decl_map;
13676 id.copy_decl = copy_decl_no_change;
13677 id.transform_call_graph_edges = CB_CGE_DUPLICATE;
13678 id.transform_new_cfg = true;
13679 id.transform_return_to_modify = false;
13680 id.eh_lp_nr = 0;
13681 walk_tree (&OMP_CLAUSE_REDUCTION_INIT (*pc), copy_tree_body_r,
13682 &id, NULL);
13683 walk_tree (&OMP_CLAUSE_REDUCTION_MERGE (*pc), copy_tree_body_r,
13684 &id, NULL);
13686 for (tree d : no_context_vars)
13688 DECL_CONTEXT (d) = NULL_TREE;
13689 DECL_CONTEXT (*decl_map.get (d)) = NULL_TREE;
13692 else
13694 OMP_CLAUSE_REDUCTION_INIT (*pc)
13695 = unshare_expr (OMP_CLAUSE_REDUCTION_INIT (c));
13696 OMP_CLAUSE_REDUCTION_MERGE (*pc)
13697 = unshare_expr (OMP_CLAUSE_REDUCTION_MERGE (c));
13699 pc = &OMP_CLAUSE_CHAIN (*pc);
13700 break;
13701 default:
13702 gcc_unreachable ();
13704 *pc = NULL_TREE;
13705 *expr_p = t;
13707 return gimplify_omp_for (expr_p, pre_p);
13711 /* Helper function of optimize_target_teams, find OMP_TEAMS inside
13712 of OMP_TARGET's body. */
13714 static tree
13715 find_omp_teams (tree *tp, int *walk_subtrees, void *)
13717 *walk_subtrees = 0;
13718 switch (TREE_CODE (*tp))
13720 case OMP_TEAMS:
13721 return *tp;
13722 case BIND_EXPR:
13723 case STATEMENT_LIST:
13724 *walk_subtrees = 1;
13725 break;
13726 default:
13727 break;
13729 return NULL_TREE;
13732 /* Helper function of optimize_target_teams, determine if the expression
13733 can be computed safely before the target construct on the host. */
13735 static tree
13736 computable_teams_clause (tree *tp, int *walk_subtrees, void *)
13738 splay_tree_node n;
13740 if (TYPE_P (*tp))
13742 *walk_subtrees = 0;
13743 return NULL_TREE;
13745 switch (TREE_CODE (*tp))
13747 case VAR_DECL:
13748 case PARM_DECL:
13749 case RESULT_DECL:
13750 *walk_subtrees = 0;
13751 if (error_operand_p (*tp)
13752 || !INTEGRAL_TYPE_P (TREE_TYPE (*tp))
13753 || DECL_HAS_VALUE_EXPR_P (*tp)
13754 || DECL_THREAD_LOCAL_P (*tp)
13755 || TREE_SIDE_EFFECTS (*tp)
13756 || TREE_THIS_VOLATILE (*tp))
13757 return *tp;
13758 if (is_global_var (*tp)
13759 && (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (*tp))
13760 || lookup_attribute ("omp declare target link",
13761 DECL_ATTRIBUTES (*tp))))
13762 return *tp;
13763 if (VAR_P (*tp)
13764 && !DECL_SEEN_IN_BIND_EXPR_P (*tp)
13765 && !is_global_var (*tp)
13766 && decl_function_context (*tp) == current_function_decl)
13767 return *tp;
13768 n = splay_tree_lookup (gimplify_omp_ctxp->variables,
13769 (splay_tree_key) *tp);
13770 if (n == NULL)
13772 if (gimplify_omp_ctxp->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE)
13773 return NULL_TREE;
13774 return *tp;
13776 else if (n->value & GOVD_LOCAL)
13777 return *tp;
13778 else if (n->value & GOVD_FIRSTPRIVATE)
13779 return NULL_TREE;
13780 else if ((n->value & (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
13781 == (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
13782 return NULL_TREE;
13783 return *tp;
13784 case INTEGER_CST:
13785 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
13786 return *tp;
13787 return NULL_TREE;
13788 case TARGET_EXPR:
13789 if (TARGET_EXPR_INITIAL (*tp)
13790 || TREE_CODE (TARGET_EXPR_SLOT (*tp)) != VAR_DECL)
13791 return *tp;
13792 return computable_teams_clause (&TARGET_EXPR_SLOT (*tp),
13793 walk_subtrees, NULL);
13794 /* Allow some reasonable subset of integral arithmetics. */
13795 case PLUS_EXPR:
13796 case MINUS_EXPR:
13797 case MULT_EXPR:
13798 case TRUNC_DIV_EXPR:
13799 case CEIL_DIV_EXPR:
13800 case FLOOR_DIV_EXPR:
13801 case ROUND_DIV_EXPR:
13802 case TRUNC_MOD_EXPR:
13803 case CEIL_MOD_EXPR:
13804 case FLOOR_MOD_EXPR:
13805 case ROUND_MOD_EXPR:
13806 case RDIV_EXPR:
13807 case EXACT_DIV_EXPR:
13808 case MIN_EXPR:
13809 case MAX_EXPR:
13810 case LSHIFT_EXPR:
13811 case RSHIFT_EXPR:
13812 case BIT_IOR_EXPR:
13813 case BIT_XOR_EXPR:
13814 case BIT_AND_EXPR:
13815 case NEGATE_EXPR:
13816 case ABS_EXPR:
13817 case BIT_NOT_EXPR:
13818 case NON_LVALUE_EXPR:
13819 CASE_CONVERT:
13820 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
13821 return *tp;
13822 return NULL_TREE;
13823 /* And disallow anything else, except for comparisons. */
13824 default:
13825 if (COMPARISON_CLASS_P (*tp))
13826 return NULL_TREE;
13827 return *tp;
13831 /* Try to determine if the num_teams and/or thread_limit expressions
13832 can have their values determined already before entering the
13833 target construct.
13834 INTEGER_CSTs trivially are,
13835 integral decls that are firstprivate (explicitly or implicitly)
13836 or explicitly map(always, to:) or map(always, tofrom:) on the target
13837 region too, and expressions involving simple arithmetics on those
13838 too, function calls are not ok, dereferencing something neither etc.
13839 Add NUM_TEAMS and THREAD_LIMIT clauses to the OMP_CLAUSES of
13840 EXPR based on what we find:
13841 0 stands for clause not specified at all, use implementation default
13842 -1 stands for value that can't be determined easily before entering
13843 the target construct.
13844 If teams construct is not present at all, use 1 for num_teams
13845 and 0 for thread_limit (only one team is involved, and the thread
13846 limit is implementation defined. */
13848 static void
13849 optimize_target_teams (tree target, gimple_seq *pre_p)
13851 tree body = OMP_BODY (target);
13852 tree teams = walk_tree (&body, find_omp_teams, NULL, NULL);
13853 tree num_teams_lower = NULL_TREE;
13854 tree num_teams_upper = integer_zero_node;
13855 tree thread_limit = integer_zero_node;
13856 location_t num_teams_loc = EXPR_LOCATION (target);
13857 location_t thread_limit_loc = EXPR_LOCATION (target);
13858 tree c, *p, expr;
13859 struct gimplify_omp_ctx *target_ctx = gimplify_omp_ctxp;
13861 if (teams == NULL_TREE)
13862 num_teams_upper = integer_one_node;
13863 else
13864 for (c = OMP_TEAMS_CLAUSES (teams); c; c = OMP_CLAUSE_CHAIN (c))
13866 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS)
13868 p = &num_teams_upper;
13869 num_teams_loc = OMP_CLAUSE_LOCATION (c);
13870 if (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c))
13872 expr = OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c);
13873 if (TREE_CODE (expr) == INTEGER_CST)
13874 num_teams_lower = expr;
13875 else if (walk_tree (&expr, computable_teams_clause,
13876 NULL, NULL))
13877 num_teams_lower = integer_minus_one_node;
13878 else
13880 num_teams_lower = expr;
13881 gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
13882 if (gimplify_expr (&num_teams_lower, pre_p, NULL,
13883 is_gimple_val, fb_rvalue, false)
13884 == GS_ERROR)
13886 gimplify_omp_ctxp = target_ctx;
13887 num_teams_lower = integer_minus_one_node;
13889 else
13891 gimplify_omp_ctxp = target_ctx;
13892 if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR)
13893 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
13894 = num_teams_lower;
13899 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
13901 p = &thread_limit;
13902 thread_limit_loc = OMP_CLAUSE_LOCATION (c);
13904 else
13905 continue;
13906 expr = OMP_CLAUSE_OPERAND (c, 0);
13907 if (TREE_CODE (expr) == INTEGER_CST)
13909 *p = expr;
13910 continue;
13912 if (walk_tree (&expr, computable_teams_clause, NULL, NULL))
13914 *p = integer_minus_one_node;
13915 continue;
13917 *p = expr;
13918 gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
13919 if (gimplify_expr (p, pre_p, NULL, is_gimple_val, fb_rvalue, false)
13920 == GS_ERROR)
13922 gimplify_omp_ctxp = target_ctx;
13923 *p = integer_minus_one_node;
13924 continue;
13926 gimplify_omp_ctxp = target_ctx;
13927 if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR)
13928 OMP_CLAUSE_OPERAND (c, 0) = *p;
13930 if (!omp_find_clause (OMP_TARGET_CLAUSES (target), OMP_CLAUSE_THREAD_LIMIT))
13932 c = build_omp_clause (thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
13933 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = thread_limit;
13934 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
13935 OMP_TARGET_CLAUSES (target) = c;
13937 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
13938 OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c) = num_teams_upper;
13939 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) = num_teams_lower;
13940 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
13941 OMP_TARGET_CLAUSES (target) = c;
13944 /* Gimplify the gross structure of several OMP constructs. */
13946 static void
13947 gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
13949 tree expr = *expr_p;
13950 gimple *stmt;
13951 gimple_seq body = NULL;
13952 enum omp_region_type ort;
13954 switch (TREE_CODE (expr))
13956 case OMP_SECTIONS:
13957 case OMP_SINGLE:
13958 ort = ORT_WORKSHARE;
13959 break;
13960 case OMP_SCOPE:
13961 ort = ORT_TASKGROUP;
13962 break;
13963 case OMP_TARGET:
13964 ort = OMP_TARGET_COMBINED (expr) ? ORT_COMBINED_TARGET : ORT_TARGET;
13965 break;
13966 case OACC_KERNELS:
13967 ort = ORT_ACC_KERNELS;
13968 break;
13969 case OACC_PARALLEL:
13970 ort = ORT_ACC_PARALLEL;
13971 break;
13972 case OACC_SERIAL:
13973 ort = ORT_ACC_SERIAL;
13974 break;
13975 case OACC_DATA:
13976 ort = ORT_ACC_DATA;
13977 break;
13978 case OMP_TARGET_DATA:
13979 ort = ORT_TARGET_DATA;
13980 break;
13981 case OMP_TEAMS:
13982 ort = OMP_TEAMS_COMBINED (expr) ? ORT_COMBINED_TEAMS : ORT_TEAMS;
13983 if (gimplify_omp_ctxp == NULL
13984 || gimplify_omp_ctxp->region_type == ORT_IMPLICIT_TARGET)
13985 ort = (enum omp_region_type) (ort | ORT_HOST_TEAMS);
13986 break;
13987 case OACC_HOST_DATA:
13988 ort = ORT_ACC_HOST_DATA;
13989 break;
13990 default:
13991 gcc_unreachable ();
13994 bool save_in_omp_construct = in_omp_construct;
13995 if ((ort & ORT_ACC) == 0)
13996 in_omp_construct = false;
13997 gimplify_scan_omp_clauses (&OMP_CLAUSES (expr), pre_p, ort,
13998 TREE_CODE (expr));
13999 if (TREE_CODE (expr) == OMP_TARGET)
14000 optimize_target_teams (expr, pre_p);
14001 if ((ort & (ORT_TARGET | ORT_TARGET_DATA)) != 0
14002 || (ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
14004 push_gimplify_context ();
14005 gimple *g = gimplify_and_return_first (OMP_BODY (expr), &body);
14006 if (gimple_code (g) == GIMPLE_BIND)
14007 pop_gimplify_context (g);
14008 else
14009 pop_gimplify_context (NULL);
14010 if ((ort & ORT_TARGET_DATA) != 0)
14012 enum built_in_function end_ix;
14013 switch (TREE_CODE (expr))
14015 case OACC_DATA:
14016 case OACC_HOST_DATA:
14017 end_ix = BUILT_IN_GOACC_DATA_END;
14018 break;
14019 case OMP_TARGET_DATA:
14020 end_ix = BUILT_IN_GOMP_TARGET_END_DATA;
14021 break;
14022 default:
14023 gcc_unreachable ();
14025 tree fn = builtin_decl_explicit (end_ix);
14026 g = gimple_build_call (fn, 0);
14027 gimple_seq cleanup = NULL;
14028 gimple_seq_add_stmt (&cleanup, g);
14029 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
14030 body = NULL;
14031 gimple_seq_add_stmt (&body, g);
14034 else
14035 gimplify_and_add (OMP_BODY (expr), &body);
14036 gimplify_adjust_omp_clauses (pre_p, body, &OMP_CLAUSES (expr),
14037 TREE_CODE (expr));
14038 in_omp_construct = save_in_omp_construct;
14040 switch (TREE_CODE (expr))
14042 case OACC_DATA:
14043 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_DATA,
14044 OMP_CLAUSES (expr));
14045 break;
14046 case OACC_HOST_DATA:
14047 if (omp_find_clause (OMP_CLAUSES (expr), OMP_CLAUSE_IF_PRESENT))
14049 for (tree c = OMP_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
14050 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_PTR)
14051 OMP_CLAUSE_USE_DEVICE_PTR_IF_PRESENT (c) = 1;
14054 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_HOST_DATA,
14055 OMP_CLAUSES (expr));
14056 break;
14057 case OACC_KERNELS:
14058 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_KERNELS,
14059 OMP_CLAUSES (expr));
14060 break;
14061 case OACC_PARALLEL:
14062 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_PARALLEL,
14063 OMP_CLAUSES (expr));
14064 break;
14065 case OACC_SERIAL:
14066 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_SERIAL,
14067 OMP_CLAUSES (expr));
14068 break;
14069 case OMP_SECTIONS:
14070 stmt = gimple_build_omp_sections (body, OMP_CLAUSES (expr));
14071 break;
14072 case OMP_SINGLE:
14073 stmt = gimple_build_omp_single (body, OMP_CLAUSES (expr));
14074 break;
14075 case OMP_SCOPE:
14076 stmt = gimple_build_omp_scope (body, OMP_CLAUSES (expr));
14077 break;
14078 case OMP_TARGET:
14079 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_REGION,
14080 OMP_CLAUSES (expr));
14081 break;
14082 case OMP_TARGET_DATA:
14083 /* Put use_device_{ptr,addr} clauses last, as map clauses are supposed
14084 to be evaluated before the use_device_{ptr,addr} clauses if they
14085 refer to the same variables. */
14087 tree use_device_clauses;
14088 tree *pc, *uc = &use_device_clauses;
14089 for (pc = &OMP_CLAUSES (expr); *pc; )
14090 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
14091 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
14093 *uc = *pc;
14094 *pc = OMP_CLAUSE_CHAIN (*pc);
14095 uc = &OMP_CLAUSE_CHAIN (*uc);
14097 else
14098 pc = &OMP_CLAUSE_CHAIN (*pc);
14099 *uc = NULL_TREE;
14100 *pc = use_device_clauses;
14101 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_DATA,
14102 OMP_CLAUSES (expr));
14104 break;
14105 case OMP_TEAMS:
14106 stmt = gimple_build_omp_teams (body, OMP_CLAUSES (expr));
14107 if ((ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
14108 gimple_omp_teams_set_host (as_a <gomp_teams *> (stmt), true);
14109 break;
14110 default:
14111 gcc_unreachable ();
14114 gimplify_seq_add_stmt (pre_p, stmt);
14115 *expr_p = NULL_TREE;
14118 /* Gimplify the gross structure of OpenACC enter/exit data, update, and OpenMP
14119 target update constructs. */
14121 static void
14122 gimplify_omp_target_update (tree *expr_p, gimple_seq *pre_p)
14124 tree expr = *expr_p;
14125 int kind;
14126 gomp_target *stmt;
14127 enum omp_region_type ort = ORT_WORKSHARE;
14129 switch (TREE_CODE (expr))
14131 case OACC_ENTER_DATA:
14132 kind = GF_OMP_TARGET_KIND_OACC_ENTER_DATA;
14133 ort = ORT_ACC;
14134 break;
14135 case OACC_EXIT_DATA:
14136 kind = GF_OMP_TARGET_KIND_OACC_EXIT_DATA;
14137 ort = ORT_ACC;
14138 break;
14139 case OACC_UPDATE:
14140 kind = GF_OMP_TARGET_KIND_OACC_UPDATE;
14141 ort = ORT_ACC;
14142 break;
14143 case OMP_TARGET_UPDATE:
14144 kind = GF_OMP_TARGET_KIND_UPDATE;
14145 break;
14146 case OMP_TARGET_ENTER_DATA:
14147 kind = GF_OMP_TARGET_KIND_ENTER_DATA;
14148 break;
14149 case OMP_TARGET_EXIT_DATA:
14150 kind = GF_OMP_TARGET_KIND_EXIT_DATA;
14151 break;
14152 default:
14153 gcc_unreachable ();
14155 gimplify_scan_omp_clauses (&OMP_STANDALONE_CLAUSES (expr), pre_p,
14156 ort, TREE_CODE (expr));
14157 gimplify_adjust_omp_clauses (pre_p, NULL, &OMP_STANDALONE_CLAUSES (expr),
14158 TREE_CODE (expr));
14159 if (TREE_CODE (expr) == OACC_UPDATE
14160 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
14161 OMP_CLAUSE_IF_PRESENT))
14163 /* The runtime uses GOMP_MAP_{TO,FROM} to denote the if_present
14164 clause. */
14165 for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
14166 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
14167 switch (OMP_CLAUSE_MAP_KIND (c))
14169 case GOMP_MAP_FORCE_TO:
14170 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TO);
14171 break;
14172 case GOMP_MAP_FORCE_FROM:
14173 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FROM);
14174 break;
14175 default:
14176 break;
14179 else if (TREE_CODE (expr) == OACC_EXIT_DATA
14180 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
14181 OMP_CLAUSE_FINALIZE))
14183 /* Use GOMP_MAP_DELETE/GOMP_MAP_FORCE_FROM to denote "finalize"
14184 semantics. */
14185 bool have_clause = false;
14186 for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
14187 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
14188 switch (OMP_CLAUSE_MAP_KIND (c))
14190 case GOMP_MAP_FROM:
14191 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_FROM);
14192 have_clause = true;
14193 break;
14194 case GOMP_MAP_RELEASE:
14195 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_DELETE);
14196 have_clause = true;
14197 break;
14198 case GOMP_MAP_TO_PSET:
14199 /* Fortran arrays with descriptors must map that descriptor when
14200 doing standalone "attach" operations (in OpenACC). In that
14201 case GOMP_MAP_TO_PSET appears by itself with no preceding
14202 clause (see trans-openmp.cc:gfc_trans_omp_clauses). */
14203 break;
14204 case GOMP_MAP_POINTER:
14205 /* TODO PR92929: we may see these here, but they'll always follow
14206 one of the clauses above, and will be handled by libgomp as
14207 one group, so no handling required here. */
14208 gcc_assert (have_clause);
14209 break;
14210 case GOMP_MAP_DETACH:
14211 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_DETACH);
14212 have_clause = false;
14213 break;
14214 case GOMP_MAP_STRUCT:
14215 have_clause = false;
14216 break;
14217 default:
14218 gcc_unreachable ();
14221 stmt = gimple_build_omp_target (NULL, kind, OMP_STANDALONE_CLAUSES (expr));
14223 gimplify_seq_add_stmt (pre_p, stmt);
14224 *expr_p = NULL_TREE;
14227 /* A subroutine of gimplify_omp_atomic. The front end is supposed to have
14228 stabilized the lhs of the atomic operation as *ADDR. Return true if
14229 EXPR is this stabilized form. */
14231 static bool
14232 goa_lhs_expr_p (tree expr, tree addr)
14234 /* Also include casts to other type variants. The C front end is fond
14235 of adding these for e.g. volatile variables. This is like
14236 STRIP_TYPE_NOPS but includes the main variant lookup. */
14237 STRIP_USELESS_TYPE_CONVERSION (expr);
14239 if (TREE_CODE (expr) == INDIRECT_REF)
14241 expr = TREE_OPERAND (expr, 0);
14242 while (expr != addr
14243 && (CONVERT_EXPR_P (expr)
14244 || TREE_CODE (expr) == NON_LVALUE_EXPR)
14245 && TREE_CODE (expr) == TREE_CODE (addr)
14246 && types_compatible_p (TREE_TYPE (expr), TREE_TYPE (addr)))
14248 expr = TREE_OPERAND (expr, 0);
14249 addr = TREE_OPERAND (addr, 0);
14251 if (expr == addr)
14252 return true;
14253 return (TREE_CODE (addr) == ADDR_EXPR
14254 && TREE_CODE (expr) == ADDR_EXPR
14255 && TREE_OPERAND (addr, 0) == TREE_OPERAND (expr, 0));
14257 if (TREE_CODE (addr) == ADDR_EXPR && expr == TREE_OPERAND (addr, 0))
14258 return true;
14259 return false;
14262 /* Walk *EXPR_P and replace appearances of *LHS_ADDR with LHS_VAR. If an
14263 expression does not involve the lhs, evaluate it into a temporary.
14264 Return 1 if the lhs appeared as a subexpression, 0 if it did not,
14265 or -1 if an error was encountered. */
14267 static int
14268 goa_stabilize_expr (tree *expr_p, gimple_seq *pre_p, tree lhs_addr,
14269 tree lhs_var, tree &target_expr, bool rhs, int depth)
14271 tree expr = *expr_p;
14272 int saw_lhs = 0;
14274 if (goa_lhs_expr_p (expr, lhs_addr))
14276 if (pre_p)
14277 *expr_p = lhs_var;
14278 return 1;
14280 if (is_gimple_val (expr))
14281 return 0;
14283 /* Maximum depth of lhs in expression is for the
14284 __builtin_clear_padding (...), __builtin_clear_padding (...),
14285 __builtin_memcmp (&TARGET_EXPR <lhs, >, ...) == 0 ? ... : lhs; */
14286 if (++depth > 7)
14287 goto finish;
14289 switch (TREE_CODE_CLASS (TREE_CODE (expr)))
14291 case tcc_binary:
14292 case tcc_comparison:
14293 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p, lhs_addr,
14294 lhs_var, target_expr, true, depth);
14295 /* FALLTHRU */
14296 case tcc_unary:
14297 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p, lhs_addr,
14298 lhs_var, target_expr, true, depth);
14299 break;
14300 case tcc_expression:
14301 switch (TREE_CODE (expr))
14303 case TRUTH_ANDIF_EXPR:
14304 case TRUTH_ORIF_EXPR:
14305 case TRUTH_AND_EXPR:
14306 case TRUTH_OR_EXPR:
14307 case TRUTH_XOR_EXPR:
14308 case BIT_INSERT_EXPR:
14309 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
14310 lhs_addr, lhs_var, target_expr, true,
14311 depth);
14312 /* FALLTHRU */
14313 case TRUTH_NOT_EXPR:
14314 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
14315 lhs_addr, lhs_var, target_expr, true,
14316 depth);
14317 break;
14318 case MODIFY_EXPR:
14319 if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr, lhs_var,
14320 target_expr, true, depth))
14321 break;
14322 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
14323 lhs_addr, lhs_var, target_expr, true,
14324 depth);
14325 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
14326 lhs_addr, lhs_var, target_expr, false,
14327 depth);
14328 break;
14329 /* FALLTHRU */
14330 case ADDR_EXPR:
14331 if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr, lhs_var,
14332 target_expr, true, depth))
14333 break;
14334 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
14335 lhs_addr, lhs_var, target_expr, false,
14336 depth);
14337 break;
14338 case COMPOUND_EXPR:
14339 /* Break out any preevaluations from cp_build_modify_expr. */
14340 for (; TREE_CODE (expr) == COMPOUND_EXPR;
14341 expr = TREE_OPERAND (expr, 1))
14343 /* Special-case __builtin_clear_padding call before
14344 __builtin_memcmp. */
14345 if (TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR)
14347 tree fndecl = get_callee_fndecl (TREE_OPERAND (expr, 0));
14348 if (fndecl
14349 && fndecl_built_in_p (fndecl, BUILT_IN_CLEAR_PADDING)
14350 && VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 0)))
14351 && (!pre_p
14352 || goa_stabilize_expr (&TREE_OPERAND (expr, 0), NULL,
14353 lhs_addr, lhs_var,
14354 target_expr, true, depth)))
14356 if (pre_p)
14357 *expr_p = expr;
14358 saw_lhs = goa_stabilize_expr (&TREE_OPERAND (expr, 0),
14359 pre_p, lhs_addr, lhs_var,
14360 target_expr, true, depth);
14361 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1),
14362 pre_p, lhs_addr, lhs_var,
14363 target_expr, rhs, depth);
14364 return saw_lhs;
14368 if (pre_p)
14369 gimplify_stmt (&TREE_OPERAND (expr, 0), pre_p);
14371 if (!pre_p)
14372 return goa_stabilize_expr (&expr, pre_p, lhs_addr, lhs_var,
14373 target_expr, rhs, depth);
14374 *expr_p = expr;
14375 return goa_stabilize_expr (expr_p, pre_p, lhs_addr, lhs_var,
14376 target_expr, rhs, depth);
14377 case COND_EXPR:
14378 if (!goa_stabilize_expr (&TREE_OPERAND (expr, 0), NULL, lhs_addr,
14379 lhs_var, target_expr, true, depth))
14380 break;
14381 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
14382 lhs_addr, lhs_var, target_expr, true,
14383 depth);
14384 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
14385 lhs_addr, lhs_var, target_expr, true,
14386 depth);
14387 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 2), pre_p,
14388 lhs_addr, lhs_var, target_expr, true,
14389 depth);
14390 break;
14391 case TARGET_EXPR:
14392 if (TARGET_EXPR_INITIAL (expr))
14394 if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr,
14395 lhs_var, target_expr, true,
14396 depth))
14397 break;
14398 if (expr == target_expr)
14399 saw_lhs = 1;
14400 else
14402 saw_lhs = goa_stabilize_expr (&TARGET_EXPR_INITIAL (expr),
14403 pre_p, lhs_addr, lhs_var,
14404 target_expr, true, depth);
14405 if (saw_lhs && target_expr == NULL_TREE && pre_p)
14406 target_expr = expr;
14409 break;
14410 default:
14411 break;
14413 break;
14414 case tcc_reference:
14415 if (TREE_CODE (expr) == BIT_FIELD_REF
14416 || TREE_CODE (expr) == VIEW_CONVERT_EXPR)
14417 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
14418 lhs_addr, lhs_var, target_expr, true,
14419 depth);
14420 break;
14421 case tcc_vl_exp:
14422 if (TREE_CODE (expr) == CALL_EXPR)
14424 if (tree fndecl = get_callee_fndecl (expr))
14425 if (fndecl_built_in_p (fndecl, BUILT_IN_CLEAR_PADDING)
14426 || fndecl_built_in_p (fndecl, BUILT_IN_MEMCMP))
14428 int nargs = call_expr_nargs (expr);
14429 for (int i = 0; i < nargs; i++)
14430 saw_lhs |= goa_stabilize_expr (&CALL_EXPR_ARG (expr, i),
14431 pre_p, lhs_addr, lhs_var,
14432 target_expr, true, depth);
14435 break;
14436 default:
14437 break;
14440 finish:
14441 if (saw_lhs == 0 && pre_p)
14443 enum gimplify_status gs;
14444 if (TREE_CODE (expr) == CALL_EXPR && VOID_TYPE_P (TREE_TYPE (expr)))
14446 gimplify_stmt (&expr, pre_p);
14447 return saw_lhs;
14449 else if (rhs)
14450 gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_val, fb_rvalue);
14451 else
14452 gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_lvalue, fb_lvalue);
14453 if (gs != GS_ALL_DONE)
14454 saw_lhs = -1;
14457 return saw_lhs;
14460 /* Gimplify an OMP_ATOMIC statement. */
14462 static enum gimplify_status
14463 gimplify_omp_atomic (tree *expr_p, gimple_seq *pre_p)
14465 tree addr = TREE_OPERAND (*expr_p, 0);
14466 tree rhs = TREE_CODE (*expr_p) == OMP_ATOMIC_READ
14467 ? NULL : TREE_OPERAND (*expr_p, 1);
14468 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
14469 tree tmp_load;
14470 gomp_atomic_load *loadstmt;
14471 gomp_atomic_store *storestmt;
14472 tree target_expr = NULL_TREE;
14474 tmp_load = create_tmp_reg (type);
14475 if (rhs
14476 && goa_stabilize_expr (&rhs, pre_p, addr, tmp_load, target_expr,
14477 true, 0) < 0)
14478 return GS_ERROR;
14480 if (gimplify_expr (&addr, pre_p, NULL, is_gimple_val, fb_rvalue)
14481 != GS_ALL_DONE)
14482 return GS_ERROR;
14484 loadstmt = gimple_build_omp_atomic_load (tmp_load, addr,
14485 OMP_ATOMIC_MEMORY_ORDER (*expr_p));
14486 gimplify_seq_add_stmt (pre_p, loadstmt);
14487 if (rhs)
14489 /* BIT_INSERT_EXPR is not valid for non-integral bitfield
14490 representatives. Use BIT_FIELD_REF on the lhs instead. */
14491 tree rhsarg = rhs;
14492 if (TREE_CODE (rhs) == COND_EXPR)
14493 rhsarg = TREE_OPERAND (rhs, 1);
14494 if (TREE_CODE (rhsarg) == BIT_INSERT_EXPR
14495 && !INTEGRAL_TYPE_P (TREE_TYPE (tmp_load)))
14497 tree bitpos = TREE_OPERAND (rhsarg, 2);
14498 tree op1 = TREE_OPERAND (rhsarg, 1);
14499 tree bitsize;
14500 tree tmp_store = tmp_load;
14501 if (TREE_CODE (*expr_p) == OMP_ATOMIC_CAPTURE_OLD)
14502 tmp_store = get_initialized_tmp_var (tmp_load, pre_p);
14503 if (INTEGRAL_TYPE_P (TREE_TYPE (op1)))
14504 bitsize = bitsize_int (TYPE_PRECISION (TREE_TYPE (op1)));
14505 else
14506 bitsize = TYPE_SIZE (TREE_TYPE (op1));
14507 gcc_assert (TREE_OPERAND (rhsarg, 0) == tmp_load);
14508 tree t = build2_loc (EXPR_LOCATION (rhsarg),
14509 MODIFY_EXPR, void_type_node,
14510 build3_loc (EXPR_LOCATION (rhsarg),
14511 BIT_FIELD_REF, TREE_TYPE (op1),
14512 tmp_store, bitsize, bitpos), op1);
14513 if (TREE_CODE (rhs) == COND_EXPR)
14514 t = build3_loc (EXPR_LOCATION (rhs), COND_EXPR, void_type_node,
14515 TREE_OPERAND (rhs, 0), t, void_node);
14516 gimplify_and_add (t, pre_p);
14517 rhs = tmp_store;
14519 bool save_allow_rhs_cond_expr = gimplify_ctxp->allow_rhs_cond_expr;
14520 if (TREE_CODE (rhs) == COND_EXPR)
14521 gimplify_ctxp->allow_rhs_cond_expr = true;
14522 enum gimplify_status gs = gimplify_expr (&rhs, pre_p, NULL,
14523 is_gimple_val, fb_rvalue);
14524 gimplify_ctxp->allow_rhs_cond_expr = save_allow_rhs_cond_expr;
14525 if (gs != GS_ALL_DONE)
14526 return GS_ERROR;
14529 if (TREE_CODE (*expr_p) == OMP_ATOMIC_READ)
14530 rhs = tmp_load;
14531 storestmt
14532 = gimple_build_omp_atomic_store (rhs, OMP_ATOMIC_MEMORY_ORDER (*expr_p));
14533 if (TREE_CODE (*expr_p) != OMP_ATOMIC_READ && OMP_ATOMIC_WEAK (*expr_p))
14535 gimple_omp_atomic_set_weak (loadstmt);
14536 gimple_omp_atomic_set_weak (storestmt);
14538 gimplify_seq_add_stmt (pre_p, storestmt);
14539 switch (TREE_CODE (*expr_p))
14541 case OMP_ATOMIC_READ:
14542 case OMP_ATOMIC_CAPTURE_OLD:
14543 *expr_p = tmp_load;
14544 gimple_omp_atomic_set_need_value (loadstmt);
14545 break;
14546 case OMP_ATOMIC_CAPTURE_NEW:
14547 *expr_p = rhs;
14548 gimple_omp_atomic_set_need_value (storestmt);
14549 break;
14550 default:
14551 *expr_p = NULL;
14552 break;
14555 return GS_ALL_DONE;
14558 /* Gimplify a TRANSACTION_EXPR. This involves gimplification of the
14559 body, and adding some EH bits. */
14561 static enum gimplify_status
14562 gimplify_transaction (tree *expr_p, gimple_seq *pre_p)
14564 tree expr = *expr_p, temp, tbody = TRANSACTION_EXPR_BODY (expr);
14565 gimple *body_stmt;
14566 gtransaction *trans_stmt;
14567 gimple_seq body = NULL;
14568 int subcode = 0;
14570 /* Wrap the transaction body in a BIND_EXPR so we have a context
14571 where to put decls for OMP. */
14572 if (TREE_CODE (tbody) != BIND_EXPR)
14574 tree bind = build3 (BIND_EXPR, void_type_node, NULL, tbody, NULL);
14575 TREE_SIDE_EFFECTS (bind) = 1;
14576 SET_EXPR_LOCATION (bind, EXPR_LOCATION (tbody));
14577 TRANSACTION_EXPR_BODY (expr) = bind;
14580 push_gimplify_context ();
14581 temp = voidify_wrapper_expr (*expr_p, NULL);
14583 body_stmt = gimplify_and_return_first (TRANSACTION_EXPR_BODY (expr), &body);
14584 pop_gimplify_context (body_stmt);
14586 trans_stmt = gimple_build_transaction (body);
14587 if (TRANSACTION_EXPR_OUTER (expr))
14588 subcode = GTMA_IS_OUTER;
14589 else if (TRANSACTION_EXPR_RELAXED (expr))
14590 subcode = GTMA_IS_RELAXED;
14591 gimple_transaction_set_subcode (trans_stmt, subcode);
14593 gimplify_seq_add_stmt (pre_p, trans_stmt);
14595 if (temp)
14597 *expr_p = temp;
14598 return GS_OK;
14601 *expr_p = NULL_TREE;
14602 return GS_ALL_DONE;
14605 /* Gimplify an OMP_ORDERED construct. EXPR is the tree version. BODY
14606 is the OMP_BODY of the original EXPR (which has already been
14607 gimplified so it's not present in the EXPR).
14609 Return the gimplified GIMPLE_OMP_ORDERED tuple. */
14611 static gimple *
14612 gimplify_omp_ordered (tree expr, gimple_seq body)
14614 tree c, decls;
14615 int failures = 0;
14616 unsigned int i;
14617 tree source_c = NULL_TREE;
14618 tree sink_c = NULL_TREE;
14620 if (gimplify_omp_ctxp)
14622 for (c = OMP_ORDERED_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
14623 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
14624 && gimplify_omp_ctxp->loop_iter_var.is_empty ()
14625 && (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK
14626 || OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE))
14628 error_at (OMP_CLAUSE_LOCATION (c),
14629 "%<ordered%> construct with %<depend%> clause must be "
14630 "closely nested inside a loop with %<ordered%> clause "
14631 "with a parameter");
14632 failures++;
14634 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
14635 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
14637 bool fail = false;
14638 for (decls = OMP_CLAUSE_DECL (c), i = 0;
14639 decls && TREE_CODE (decls) == TREE_LIST;
14640 decls = TREE_CHAIN (decls), ++i)
14641 if (i >= gimplify_omp_ctxp->loop_iter_var.length () / 2)
14642 continue;
14643 else if (TREE_VALUE (decls)
14644 != gimplify_omp_ctxp->loop_iter_var[2 * i])
14646 error_at (OMP_CLAUSE_LOCATION (c),
14647 "variable %qE is not an iteration "
14648 "of outermost loop %d, expected %qE",
14649 TREE_VALUE (decls), i + 1,
14650 gimplify_omp_ctxp->loop_iter_var[2 * i]);
14651 fail = true;
14652 failures++;
14654 else
14655 TREE_VALUE (decls)
14656 = gimplify_omp_ctxp->loop_iter_var[2 * i + 1];
14657 if (!fail && i != gimplify_omp_ctxp->loop_iter_var.length () / 2)
14659 error_at (OMP_CLAUSE_LOCATION (c),
14660 "number of variables in %<depend%> clause with "
14661 "%<sink%> modifier does not match number of "
14662 "iteration variables");
14663 failures++;
14665 sink_c = c;
14667 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
14668 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
14670 if (source_c)
14672 error_at (OMP_CLAUSE_LOCATION (c),
14673 "more than one %<depend%> clause with %<source%> "
14674 "modifier on an %<ordered%> construct");
14675 failures++;
14677 else
14678 source_c = c;
14681 if (source_c && sink_c)
14683 error_at (OMP_CLAUSE_LOCATION (source_c),
14684 "%<depend%> clause with %<source%> modifier specified "
14685 "together with %<depend%> clauses with %<sink%> modifier "
14686 "on the same construct");
14687 failures++;
14690 if (failures)
14691 return gimple_build_nop ();
14692 return gimple_build_omp_ordered (body, OMP_ORDERED_CLAUSES (expr));
14695 /* Convert the GENERIC expression tree *EXPR_P to GIMPLE. If the
14696 expression produces a value to be used as an operand inside a GIMPLE
14697 statement, the value will be stored back in *EXPR_P. This value will
14698 be a tree of class tcc_declaration, tcc_constant, tcc_reference or
14699 an SSA_NAME. The corresponding sequence of GIMPLE statements is
14700 emitted in PRE_P and POST_P.
14702 Additionally, this process may overwrite parts of the input
14703 expression during gimplification. Ideally, it should be
14704 possible to do non-destructive gimplification.
14706 EXPR_P points to the GENERIC expression to convert to GIMPLE. If
14707 the expression needs to evaluate to a value to be used as
14708 an operand in a GIMPLE statement, this value will be stored in
14709 *EXPR_P on exit. This happens when the caller specifies one
14710 of fb_lvalue or fb_rvalue fallback flags.
14712 PRE_P will contain the sequence of GIMPLE statements corresponding
14713 to the evaluation of EXPR and all the side-effects that must
14714 be executed before the main expression. On exit, the last
14715 statement of PRE_P is the core statement being gimplified. For
14716 instance, when gimplifying 'if (++a)' the last statement in
14717 PRE_P will be 'if (t.1)' where t.1 is the result of
14718 pre-incrementing 'a'.
14720 POST_P will contain the sequence of GIMPLE statements corresponding
14721 to the evaluation of all the side-effects that must be executed
14722 after the main expression. If this is NULL, the post
14723 side-effects are stored at the end of PRE_P.
14725 The reason why the output is split in two is to handle post
14726 side-effects explicitly. In some cases, an expression may have
14727 inner and outer post side-effects which need to be emitted in
14728 an order different from the one given by the recursive
14729 traversal. For instance, for the expression (*p--)++ the post
14730 side-effects of '--' must actually occur *after* the post
14731 side-effects of '++'. However, gimplification will first visit
14732 the inner expression, so if a separate POST sequence was not
14733 used, the resulting sequence would be:
14735 1 t.1 = *p
14736 2 p = p - 1
14737 3 t.2 = t.1 + 1
14738 4 *p = t.2
14740 However, the post-decrement operation in line #2 must not be
14741 evaluated until after the store to *p at line #4, so the
14742 correct sequence should be:
14744 1 t.1 = *p
14745 2 t.2 = t.1 + 1
14746 3 *p = t.2
14747 4 p = p - 1
14749 So, by specifying a separate post queue, it is possible
14750 to emit the post side-effects in the correct order.
14751 If POST_P is NULL, an internal queue will be used. Before
14752 returning to the caller, the sequence POST_P is appended to
14753 the main output sequence PRE_P.
14755 GIMPLE_TEST_F points to a function that takes a tree T and
14756 returns nonzero if T is in the GIMPLE form requested by the
14757 caller. The GIMPLE predicates are in gimple.cc.
14759 FALLBACK tells the function what sort of a temporary we want if
14760 gimplification cannot produce an expression that complies with
14761 GIMPLE_TEST_F.
14763 fb_none means that no temporary should be generated
14764 fb_rvalue means that an rvalue is OK to generate
14765 fb_lvalue means that an lvalue is OK to generate
14766 fb_either means that either is OK, but an lvalue is preferable.
14767 fb_mayfail means that gimplification may fail (in which case
14768 GS_ERROR will be returned)
14770 The return value is either GS_ERROR or GS_ALL_DONE, since this
14771 function iterates until EXPR is completely gimplified or an error
14772 occurs. */
14774 enum gimplify_status
14775 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
14776 bool (*gimple_test_f) (tree), fallback_t fallback)
14778 tree tmp;
14779 gimple_seq internal_pre = NULL;
14780 gimple_seq internal_post = NULL;
14781 tree save_expr;
14782 bool is_statement;
14783 location_t saved_location;
14784 enum gimplify_status ret;
14785 gimple_stmt_iterator pre_last_gsi, post_last_gsi;
14786 tree label;
14788 save_expr = *expr_p;
14789 if (save_expr == NULL_TREE)
14790 return GS_ALL_DONE;
14792 /* If we are gimplifying a top-level statement, PRE_P must be valid. */
14793 is_statement = gimple_test_f == is_gimple_stmt;
14794 if (is_statement)
14795 gcc_assert (pre_p);
14797 /* Consistency checks. */
14798 if (gimple_test_f == is_gimple_reg)
14799 gcc_assert (fallback & (fb_rvalue | fb_lvalue));
14800 else if (gimple_test_f == is_gimple_val
14801 || gimple_test_f == is_gimple_call_addr
14802 || gimple_test_f == is_gimple_condexpr
14803 || gimple_test_f == is_gimple_condexpr_for_cond
14804 || gimple_test_f == is_gimple_mem_rhs
14805 || gimple_test_f == is_gimple_mem_rhs_or_call
14806 || gimple_test_f == is_gimple_reg_rhs
14807 || gimple_test_f == is_gimple_reg_rhs_or_call
14808 || gimple_test_f == is_gimple_asm_val
14809 || gimple_test_f == is_gimple_mem_ref_addr)
14810 gcc_assert (fallback & fb_rvalue);
14811 else if (gimple_test_f == is_gimple_min_lval
14812 || gimple_test_f == is_gimple_lvalue)
14813 gcc_assert (fallback & fb_lvalue);
14814 else if (gimple_test_f == is_gimple_addressable)
14815 gcc_assert (fallback & fb_either);
14816 else if (gimple_test_f == is_gimple_stmt)
14817 gcc_assert (fallback == fb_none);
14818 else
14820 /* We should have recognized the GIMPLE_TEST_F predicate to
14821 know what kind of fallback to use in case a temporary is
14822 needed to hold the value or address of *EXPR_P. */
14823 gcc_unreachable ();
14826 /* We used to check the predicate here and return immediately if it
14827 succeeds. This is wrong; the design is for gimplification to be
14828 idempotent, and for the predicates to only test for valid forms, not
14829 whether they are fully simplified. */
14830 if (pre_p == NULL)
14831 pre_p = &internal_pre;
14833 if (post_p == NULL)
14834 post_p = &internal_post;
14836 /* Remember the last statements added to PRE_P and POST_P. Every
14837 new statement added by the gimplification helpers needs to be
14838 annotated with location information. To centralize the
14839 responsibility, we remember the last statement that had been
14840 added to both queues before gimplifying *EXPR_P. If
14841 gimplification produces new statements in PRE_P and POST_P, those
14842 statements will be annotated with the same location information
14843 as *EXPR_P. */
14844 pre_last_gsi = gsi_last (*pre_p);
14845 post_last_gsi = gsi_last (*post_p);
14847 saved_location = input_location;
14848 if (save_expr != error_mark_node
14849 && EXPR_HAS_LOCATION (*expr_p))
14850 input_location = EXPR_LOCATION (*expr_p);
14852 /* Loop over the specific gimplifiers until the toplevel node
14853 remains the same. */
14856 /* Strip away as many useless type conversions as possible
14857 at the toplevel. */
14858 STRIP_USELESS_TYPE_CONVERSION (*expr_p);
14860 /* Remember the expr. */
14861 save_expr = *expr_p;
14863 /* Die, die, die, my darling. */
14864 if (error_operand_p (save_expr))
14866 ret = GS_ERROR;
14867 break;
14870 /* Do any language-specific gimplification. */
14871 ret = ((enum gimplify_status)
14872 lang_hooks.gimplify_expr (expr_p, pre_p, post_p));
14873 if (ret == GS_OK)
14875 if (*expr_p == NULL_TREE)
14876 break;
14877 if (*expr_p != save_expr)
14878 continue;
14880 else if (ret != GS_UNHANDLED)
14881 break;
14883 /* Make sure that all the cases set 'ret' appropriately. */
14884 ret = GS_UNHANDLED;
14885 switch (TREE_CODE (*expr_p))
14887 /* First deal with the special cases. */
14889 case POSTINCREMENT_EXPR:
14890 case POSTDECREMENT_EXPR:
14891 case PREINCREMENT_EXPR:
14892 case PREDECREMENT_EXPR:
14893 ret = gimplify_self_mod_expr (expr_p, pre_p, post_p,
14894 fallback != fb_none,
14895 TREE_TYPE (*expr_p));
14896 break;
14898 case VIEW_CONVERT_EXPR:
14899 if ((fallback & fb_rvalue)
14900 && is_gimple_reg_type (TREE_TYPE (*expr_p))
14901 && is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0))))
14903 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
14904 post_p, is_gimple_val, fb_rvalue);
14905 recalculate_side_effects (*expr_p);
14906 break;
14908 /* Fallthru. */
14910 case ARRAY_REF:
14911 case ARRAY_RANGE_REF:
14912 case REALPART_EXPR:
14913 case IMAGPART_EXPR:
14914 case COMPONENT_REF:
14915 ret = gimplify_compound_lval (expr_p, pre_p, post_p,
14916 fallback ? fallback : fb_rvalue);
14917 break;
14919 case COND_EXPR:
14920 ret = gimplify_cond_expr (expr_p, pre_p, fallback);
14922 /* C99 code may assign to an array in a structure value of a
14923 conditional expression, and this has undefined behavior
14924 only on execution, so create a temporary if an lvalue is
14925 required. */
14926 if (fallback == fb_lvalue)
14928 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
14929 mark_addressable (*expr_p);
14930 ret = GS_OK;
14932 break;
14934 case CALL_EXPR:
14935 ret = gimplify_call_expr (expr_p, pre_p, fallback != fb_none);
14937 /* C99 code may assign to an array in a structure returned
14938 from a function, and this has undefined behavior only on
14939 execution, so create a temporary if an lvalue is
14940 required. */
14941 if (fallback == fb_lvalue)
14943 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
14944 mark_addressable (*expr_p);
14945 ret = GS_OK;
14947 break;
14949 case TREE_LIST:
14950 gcc_unreachable ();
14952 case COMPOUND_EXPR:
14953 ret = gimplify_compound_expr (expr_p, pre_p, fallback != fb_none);
14954 break;
14956 case COMPOUND_LITERAL_EXPR:
14957 ret = gimplify_compound_literal_expr (expr_p, pre_p,
14958 gimple_test_f, fallback);
14959 break;
14961 case MODIFY_EXPR:
14962 case INIT_EXPR:
14963 ret = gimplify_modify_expr (expr_p, pre_p, post_p,
14964 fallback != fb_none);
14965 break;
14967 case TRUTH_ANDIF_EXPR:
14968 case TRUTH_ORIF_EXPR:
14970 /* Preserve the original type of the expression and the
14971 source location of the outer expression. */
14972 tree org_type = TREE_TYPE (*expr_p);
14973 *expr_p = gimple_boolify (*expr_p);
14974 *expr_p = build3_loc (input_location, COND_EXPR,
14975 org_type, *expr_p,
14976 fold_convert_loc
14977 (input_location,
14978 org_type, boolean_true_node),
14979 fold_convert_loc
14980 (input_location,
14981 org_type, boolean_false_node));
14982 ret = GS_OK;
14983 break;
14986 case TRUTH_NOT_EXPR:
14988 tree type = TREE_TYPE (*expr_p);
14989 /* The parsers are careful to generate TRUTH_NOT_EXPR
14990 only with operands that are always zero or one.
14991 We do not fold here but handle the only interesting case
14992 manually, as fold may re-introduce the TRUTH_NOT_EXPR. */
14993 *expr_p = gimple_boolify (*expr_p);
14994 if (TYPE_PRECISION (TREE_TYPE (*expr_p)) == 1)
14995 *expr_p = build1_loc (input_location, BIT_NOT_EXPR,
14996 TREE_TYPE (*expr_p),
14997 TREE_OPERAND (*expr_p, 0));
14998 else
14999 *expr_p = build2_loc (input_location, BIT_XOR_EXPR,
15000 TREE_TYPE (*expr_p),
15001 TREE_OPERAND (*expr_p, 0),
15002 build_int_cst (TREE_TYPE (*expr_p), 1));
15003 if (!useless_type_conversion_p (type, TREE_TYPE (*expr_p)))
15004 *expr_p = fold_convert_loc (input_location, type, *expr_p);
15005 ret = GS_OK;
15006 break;
15009 case ADDR_EXPR:
15010 ret = gimplify_addr_expr (expr_p, pre_p, post_p);
15011 break;
15013 case ANNOTATE_EXPR:
15015 tree cond = TREE_OPERAND (*expr_p, 0);
15016 tree kind = TREE_OPERAND (*expr_p, 1);
15017 tree data = TREE_OPERAND (*expr_p, 2);
15018 tree type = TREE_TYPE (cond);
15019 if (!INTEGRAL_TYPE_P (type))
15021 *expr_p = cond;
15022 ret = GS_OK;
15023 break;
15025 tree tmp = create_tmp_var (type);
15026 gimplify_arg (&cond, pre_p, EXPR_LOCATION (*expr_p));
15027 gcall *call
15028 = gimple_build_call_internal (IFN_ANNOTATE, 3, cond, kind, data);
15029 gimple_call_set_lhs (call, tmp);
15030 gimplify_seq_add_stmt (pre_p, call);
15031 *expr_p = tmp;
15032 ret = GS_ALL_DONE;
15033 break;
15036 case VA_ARG_EXPR:
15037 ret = gimplify_va_arg_expr (expr_p, pre_p, post_p);
15038 break;
15040 CASE_CONVERT:
15041 if (IS_EMPTY_STMT (*expr_p))
15043 ret = GS_ALL_DONE;
15044 break;
15047 if (VOID_TYPE_P (TREE_TYPE (*expr_p))
15048 || fallback == fb_none)
15050 /* Just strip a conversion to void (or in void context) and
15051 try again. */
15052 *expr_p = TREE_OPERAND (*expr_p, 0);
15053 ret = GS_OK;
15054 break;
15057 ret = gimplify_conversion (expr_p);
15058 if (ret == GS_ERROR)
15059 break;
15060 if (*expr_p != save_expr)
15061 break;
15062 /* FALLTHRU */
15064 case FIX_TRUNC_EXPR:
15065 /* unary_expr: ... | '(' cast ')' val | ... */
15066 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
15067 is_gimple_val, fb_rvalue);
15068 recalculate_side_effects (*expr_p);
15069 break;
15071 case INDIRECT_REF:
15073 bool volatilep = TREE_THIS_VOLATILE (*expr_p);
15074 bool notrap = TREE_THIS_NOTRAP (*expr_p);
15075 tree saved_ptr_type = TREE_TYPE (TREE_OPERAND (*expr_p, 0));
15077 *expr_p = fold_indirect_ref_loc (input_location, *expr_p);
15078 if (*expr_p != save_expr)
15080 ret = GS_OK;
15081 break;
15084 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
15085 is_gimple_reg, fb_rvalue);
15086 if (ret == GS_ERROR)
15087 break;
15089 recalculate_side_effects (*expr_p);
15090 *expr_p = fold_build2_loc (input_location, MEM_REF,
15091 TREE_TYPE (*expr_p),
15092 TREE_OPERAND (*expr_p, 0),
15093 build_int_cst (saved_ptr_type, 0));
15094 TREE_THIS_VOLATILE (*expr_p) = volatilep;
15095 TREE_THIS_NOTRAP (*expr_p) = notrap;
15096 ret = GS_OK;
15097 break;
15100 /* We arrive here through the various re-gimplifcation paths. */
15101 case MEM_REF:
15102 /* First try re-folding the whole thing. */
15103 tmp = fold_binary (MEM_REF, TREE_TYPE (*expr_p),
15104 TREE_OPERAND (*expr_p, 0),
15105 TREE_OPERAND (*expr_p, 1));
15106 if (tmp)
15108 REF_REVERSE_STORAGE_ORDER (tmp)
15109 = REF_REVERSE_STORAGE_ORDER (*expr_p);
15110 *expr_p = tmp;
15111 recalculate_side_effects (*expr_p);
15112 ret = GS_OK;
15113 break;
15115 /* Avoid re-gimplifying the address operand if it is already
15116 in suitable form. Re-gimplifying would mark the address
15117 operand addressable. Always gimplify when not in SSA form
15118 as we still may have to gimplify decls with value-exprs. */
15119 if (!gimplify_ctxp || !gimple_in_ssa_p (cfun)
15120 || !is_gimple_mem_ref_addr (TREE_OPERAND (*expr_p, 0)))
15122 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
15123 is_gimple_mem_ref_addr, fb_rvalue);
15124 if (ret == GS_ERROR)
15125 break;
15127 recalculate_side_effects (*expr_p);
15128 ret = GS_ALL_DONE;
15129 break;
15131 /* Constants need not be gimplified. */
15132 case INTEGER_CST:
15133 case REAL_CST:
15134 case FIXED_CST:
15135 case STRING_CST:
15136 case COMPLEX_CST:
15137 case VECTOR_CST:
15138 /* Drop the overflow flag on constants, we do not want
15139 that in the GIMPLE IL. */
15140 if (TREE_OVERFLOW_P (*expr_p))
15141 *expr_p = drop_tree_overflow (*expr_p);
15142 ret = GS_ALL_DONE;
15143 break;
15145 case CONST_DECL:
15146 /* If we require an lvalue, such as for ADDR_EXPR, retain the
15147 CONST_DECL node. Otherwise the decl is replaceable by its
15148 value. */
15149 /* ??? Should be == fb_lvalue, but ADDR_EXPR passes fb_either. */
15150 if (fallback & fb_lvalue)
15151 ret = GS_ALL_DONE;
15152 else
15154 *expr_p = DECL_INITIAL (*expr_p);
15155 ret = GS_OK;
15157 break;
15159 case DECL_EXPR:
15160 ret = gimplify_decl_expr (expr_p, pre_p);
15161 break;
15163 case BIND_EXPR:
15164 ret = gimplify_bind_expr (expr_p, pre_p);
15165 break;
15167 case LOOP_EXPR:
15168 ret = gimplify_loop_expr (expr_p, pre_p);
15169 break;
15171 case SWITCH_EXPR:
15172 ret = gimplify_switch_expr (expr_p, pre_p);
15173 break;
15175 case EXIT_EXPR:
15176 ret = gimplify_exit_expr (expr_p);
15177 break;
15179 case GOTO_EXPR:
15180 /* If the target is not LABEL, then it is a computed jump
15181 and the target needs to be gimplified. */
15182 if (TREE_CODE (GOTO_DESTINATION (*expr_p)) != LABEL_DECL)
15184 ret = gimplify_expr (&GOTO_DESTINATION (*expr_p), pre_p,
15185 NULL, is_gimple_val, fb_rvalue);
15186 if (ret == GS_ERROR)
15187 break;
15189 gimplify_seq_add_stmt (pre_p,
15190 gimple_build_goto (GOTO_DESTINATION (*expr_p)));
15191 ret = GS_ALL_DONE;
15192 break;
15194 case PREDICT_EXPR:
15195 gimplify_seq_add_stmt (pre_p,
15196 gimple_build_predict (PREDICT_EXPR_PREDICTOR (*expr_p),
15197 PREDICT_EXPR_OUTCOME (*expr_p)));
15198 ret = GS_ALL_DONE;
15199 break;
15201 case LABEL_EXPR:
15202 ret = gimplify_label_expr (expr_p, pre_p);
15203 label = LABEL_EXPR_LABEL (*expr_p);
15204 gcc_assert (decl_function_context (label) == current_function_decl);
15206 /* If the label is used in a goto statement, or address of the label
15207 is taken, we need to unpoison all variables that were seen so far.
15208 Doing so would prevent us from reporting a false positives. */
15209 if (asan_poisoned_variables
15210 && asan_used_labels != NULL
15211 && asan_used_labels->contains (label)
15212 && !gimplify_omp_ctxp)
15213 asan_poison_variables (asan_poisoned_variables, false, pre_p);
15214 break;
15216 case CASE_LABEL_EXPR:
15217 ret = gimplify_case_label_expr (expr_p, pre_p);
15219 if (gimplify_ctxp->live_switch_vars)
15220 asan_poison_variables (gimplify_ctxp->live_switch_vars, false,
15221 pre_p);
15222 break;
15224 case RETURN_EXPR:
15225 ret = gimplify_return_expr (*expr_p, pre_p);
15226 break;
15228 case CONSTRUCTOR:
15229 /* Don't reduce this in place; let gimplify_init_constructor work its
15230 magic. Buf if we're just elaborating this for side effects, just
15231 gimplify any element that has side-effects. */
15232 if (fallback == fb_none)
15234 unsigned HOST_WIDE_INT ix;
15235 tree val;
15236 tree temp = NULL_TREE;
15237 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (*expr_p), ix, val)
15238 if (TREE_SIDE_EFFECTS (val))
15239 append_to_statement_list (val, &temp);
15241 *expr_p = temp;
15242 ret = temp ? GS_OK : GS_ALL_DONE;
15244 /* C99 code may assign to an array in a constructed
15245 structure or union, and this has undefined behavior only
15246 on execution, so create a temporary if an lvalue is
15247 required. */
15248 else if (fallback == fb_lvalue)
15250 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
15251 mark_addressable (*expr_p);
15252 ret = GS_OK;
15254 else
15255 ret = GS_ALL_DONE;
15256 break;
15258 /* The following are special cases that are not handled by the
15259 original GIMPLE grammar. */
15261 /* SAVE_EXPR nodes are converted into a GIMPLE identifier and
15262 eliminated. */
15263 case SAVE_EXPR:
15264 ret = gimplify_save_expr (expr_p, pre_p, post_p);
15265 break;
15267 case BIT_FIELD_REF:
15268 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15269 post_p, is_gimple_lvalue, fb_either);
15270 recalculate_side_effects (*expr_p);
15271 break;
15273 case TARGET_MEM_REF:
15275 enum gimplify_status r0 = GS_ALL_DONE, r1 = GS_ALL_DONE;
15277 if (TMR_BASE (*expr_p))
15278 r0 = gimplify_expr (&TMR_BASE (*expr_p), pre_p,
15279 post_p, is_gimple_mem_ref_addr, fb_either);
15280 if (TMR_INDEX (*expr_p))
15281 r1 = gimplify_expr (&TMR_INDEX (*expr_p), pre_p,
15282 post_p, is_gimple_val, fb_rvalue);
15283 if (TMR_INDEX2 (*expr_p))
15284 r1 = gimplify_expr (&TMR_INDEX2 (*expr_p), pre_p,
15285 post_p, is_gimple_val, fb_rvalue);
15286 /* TMR_STEP and TMR_OFFSET are always integer constants. */
15287 ret = MIN (r0, r1);
15289 break;
15291 case NON_LVALUE_EXPR:
15292 /* This should have been stripped above. */
15293 gcc_unreachable ();
15295 case ASM_EXPR:
15296 ret = gimplify_asm_expr (expr_p, pre_p, post_p);
15297 break;
15299 case TRY_FINALLY_EXPR:
15300 case TRY_CATCH_EXPR:
15302 gimple_seq eval, cleanup;
15303 gtry *try_;
15305 /* Calls to destructors are generated automatically in FINALLY/CATCH
15306 block. They should have location as UNKNOWN_LOCATION. However,
15307 gimplify_call_expr will reset these call stmts to input_location
15308 if it finds stmt's location is unknown. To prevent resetting for
15309 destructors, we set the input_location to unknown.
15310 Note that this only affects the destructor calls in FINALLY/CATCH
15311 block, and will automatically reset to its original value by the
15312 end of gimplify_expr. */
15313 input_location = UNKNOWN_LOCATION;
15314 eval = cleanup = NULL;
15315 gimplify_and_add (TREE_OPERAND (*expr_p, 0), &eval);
15316 if (TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
15317 && TREE_CODE (TREE_OPERAND (*expr_p, 1)) == EH_ELSE_EXPR)
15319 gimple_seq n = NULL, e = NULL;
15320 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1),
15321 0), &n);
15322 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1),
15323 1), &e);
15324 if (!gimple_seq_empty_p (n) && !gimple_seq_empty_p (e))
15326 geh_else *stmt = gimple_build_eh_else (n, e);
15327 gimple_seq_add_stmt (&cleanup, stmt);
15330 else
15331 gimplify_and_add (TREE_OPERAND (*expr_p, 1), &cleanup);
15332 /* Don't create bogus GIMPLE_TRY with empty cleanup. */
15333 if (gimple_seq_empty_p (cleanup))
15335 gimple_seq_add_seq (pre_p, eval);
15336 ret = GS_ALL_DONE;
15337 break;
15339 try_ = gimple_build_try (eval, cleanup,
15340 TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
15341 ? GIMPLE_TRY_FINALLY
15342 : GIMPLE_TRY_CATCH);
15343 if (EXPR_HAS_LOCATION (save_expr))
15344 gimple_set_location (try_, EXPR_LOCATION (save_expr));
15345 else if (LOCATION_LOCUS (saved_location) != UNKNOWN_LOCATION)
15346 gimple_set_location (try_, saved_location);
15347 if (TREE_CODE (*expr_p) == TRY_CATCH_EXPR)
15348 gimple_try_set_catch_is_cleanup (try_,
15349 TRY_CATCH_IS_CLEANUP (*expr_p));
15350 gimplify_seq_add_stmt (pre_p, try_);
15351 ret = GS_ALL_DONE;
15352 break;
15355 case CLEANUP_POINT_EXPR:
15356 ret = gimplify_cleanup_point_expr (expr_p, pre_p);
15357 break;
15359 case TARGET_EXPR:
15360 ret = gimplify_target_expr (expr_p, pre_p, post_p);
15361 break;
15363 case CATCH_EXPR:
15365 gimple *c;
15366 gimple_seq handler = NULL;
15367 gimplify_and_add (CATCH_BODY (*expr_p), &handler);
15368 c = gimple_build_catch (CATCH_TYPES (*expr_p), handler);
15369 gimplify_seq_add_stmt (pre_p, c);
15370 ret = GS_ALL_DONE;
15371 break;
15374 case EH_FILTER_EXPR:
15376 gimple *ehf;
15377 gimple_seq failure = NULL;
15379 gimplify_and_add (EH_FILTER_FAILURE (*expr_p), &failure);
15380 ehf = gimple_build_eh_filter (EH_FILTER_TYPES (*expr_p), failure);
15381 copy_warning (ehf, *expr_p);
15382 gimplify_seq_add_stmt (pre_p, ehf);
15383 ret = GS_ALL_DONE;
15384 break;
15387 case OBJ_TYPE_REF:
15389 enum gimplify_status r0, r1;
15390 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p,
15391 post_p, is_gimple_val, fb_rvalue);
15392 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p,
15393 post_p, is_gimple_val, fb_rvalue);
15394 TREE_SIDE_EFFECTS (*expr_p) = 0;
15395 ret = MIN (r0, r1);
15397 break;
15399 case LABEL_DECL:
15400 /* We get here when taking the address of a label. We mark
15401 the label as "forced"; meaning it can never be removed and
15402 it is a potential target for any computed goto. */
15403 FORCED_LABEL (*expr_p) = 1;
15404 ret = GS_ALL_DONE;
15405 break;
15407 case STATEMENT_LIST:
15408 ret = gimplify_statement_list (expr_p, pre_p);
15409 break;
15411 case WITH_SIZE_EXPR:
15413 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15414 post_p == &internal_post ? NULL : post_p,
15415 gimple_test_f, fallback);
15416 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
15417 is_gimple_val, fb_rvalue);
15418 ret = GS_ALL_DONE;
15420 break;
15422 case VAR_DECL:
15423 case PARM_DECL:
15424 ret = gimplify_var_or_parm_decl (expr_p);
15425 break;
15427 case RESULT_DECL:
15428 /* When within an OMP context, notice uses of variables. */
15429 if (gimplify_omp_ctxp)
15430 omp_notice_variable (gimplify_omp_ctxp, *expr_p, true);
15431 ret = GS_ALL_DONE;
15432 break;
15434 case DEBUG_EXPR_DECL:
15435 gcc_unreachable ();
15437 case DEBUG_BEGIN_STMT:
15438 gimplify_seq_add_stmt (pre_p,
15439 gimple_build_debug_begin_stmt
15440 (TREE_BLOCK (*expr_p),
15441 EXPR_LOCATION (*expr_p)));
15442 ret = GS_ALL_DONE;
15443 *expr_p = NULL;
15444 break;
15446 case SSA_NAME:
15447 /* Allow callbacks into the gimplifier during optimization. */
15448 ret = GS_ALL_DONE;
15449 break;
15451 case OMP_PARALLEL:
15452 gimplify_omp_parallel (expr_p, pre_p);
15453 ret = GS_ALL_DONE;
15454 break;
15456 case OMP_TASK:
15457 gimplify_omp_task (expr_p, pre_p);
15458 ret = GS_ALL_DONE;
15459 break;
15461 case OMP_FOR:
15462 case OMP_SIMD:
15463 case OMP_DISTRIBUTE:
15464 case OMP_TASKLOOP:
15465 case OACC_LOOP:
15466 ret = gimplify_omp_for (expr_p, pre_p);
15467 break;
15469 case OMP_LOOP:
15470 ret = gimplify_omp_loop (expr_p, pre_p);
15471 break;
15473 case OACC_CACHE:
15474 gimplify_oacc_cache (expr_p, pre_p);
15475 ret = GS_ALL_DONE;
15476 break;
15478 case OACC_DECLARE:
15479 gimplify_oacc_declare (expr_p, pre_p);
15480 ret = GS_ALL_DONE;
15481 break;
15483 case OACC_HOST_DATA:
15484 case OACC_DATA:
15485 case OACC_KERNELS:
15486 case OACC_PARALLEL:
15487 case OACC_SERIAL:
15488 case OMP_SCOPE:
15489 case OMP_SECTIONS:
15490 case OMP_SINGLE:
15491 case OMP_TARGET:
15492 case OMP_TARGET_DATA:
15493 case OMP_TEAMS:
15494 gimplify_omp_workshare (expr_p, pre_p);
15495 ret = GS_ALL_DONE;
15496 break;
15498 case OACC_ENTER_DATA:
15499 case OACC_EXIT_DATA:
15500 case OACC_UPDATE:
15501 case OMP_TARGET_UPDATE:
15502 case OMP_TARGET_ENTER_DATA:
15503 case OMP_TARGET_EXIT_DATA:
15504 gimplify_omp_target_update (expr_p, pre_p);
15505 ret = GS_ALL_DONE;
15506 break;
15508 case OMP_SECTION:
15509 case OMP_MASTER:
15510 case OMP_MASKED:
15511 case OMP_ORDERED:
15512 case OMP_CRITICAL:
15513 case OMP_SCAN:
15515 gimple_seq body = NULL;
15516 gimple *g;
15517 bool saved_in_omp_construct = in_omp_construct;
15519 in_omp_construct = true;
15520 gimplify_and_add (OMP_BODY (*expr_p), &body);
15521 in_omp_construct = saved_in_omp_construct;
15522 switch (TREE_CODE (*expr_p))
15524 case OMP_SECTION:
15525 g = gimple_build_omp_section (body);
15526 break;
15527 case OMP_MASTER:
15528 g = gimple_build_omp_master (body);
15529 break;
15530 case OMP_ORDERED:
15531 g = gimplify_omp_ordered (*expr_p, body);
15532 break;
15533 case OMP_MASKED:
15534 gimplify_scan_omp_clauses (&OMP_MASKED_CLAUSES (*expr_p),
15535 pre_p, ORT_WORKSHARE, OMP_MASKED);
15536 gimplify_adjust_omp_clauses (pre_p, body,
15537 &OMP_MASKED_CLAUSES (*expr_p),
15538 OMP_MASKED);
15539 g = gimple_build_omp_masked (body,
15540 OMP_MASKED_CLAUSES (*expr_p));
15541 break;
15542 case OMP_CRITICAL:
15543 gimplify_scan_omp_clauses (&OMP_CRITICAL_CLAUSES (*expr_p),
15544 pre_p, ORT_WORKSHARE, OMP_CRITICAL);
15545 gimplify_adjust_omp_clauses (pre_p, body,
15546 &OMP_CRITICAL_CLAUSES (*expr_p),
15547 OMP_CRITICAL);
15548 g = gimple_build_omp_critical (body,
15549 OMP_CRITICAL_NAME (*expr_p),
15550 OMP_CRITICAL_CLAUSES (*expr_p));
15551 break;
15552 case OMP_SCAN:
15553 gimplify_scan_omp_clauses (&OMP_SCAN_CLAUSES (*expr_p),
15554 pre_p, ORT_WORKSHARE, OMP_SCAN);
15555 gimplify_adjust_omp_clauses (pre_p, body,
15556 &OMP_SCAN_CLAUSES (*expr_p),
15557 OMP_SCAN);
15558 g = gimple_build_omp_scan (body, OMP_SCAN_CLAUSES (*expr_p));
15559 break;
15560 default:
15561 gcc_unreachable ();
15563 gimplify_seq_add_stmt (pre_p, g);
15564 ret = GS_ALL_DONE;
15565 break;
15568 case OMP_TASKGROUP:
15570 gimple_seq body = NULL;
15572 tree *pclauses = &OMP_TASKGROUP_CLAUSES (*expr_p);
15573 bool saved_in_omp_construct = in_omp_construct;
15574 gimplify_scan_omp_clauses (pclauses, pre_p, ORT_TASKGROUP,
15575 OMP_TASKGROUP);
15576 gimplify_adjust_omp_clauses (pre_p, NULL, pclauses, OMP_TASKGROUP);
15578 in_omp_construct = true;
15579 gimplify_and_add (OMP_BODY (*expr_p), &body);
15580 in_omp_construct = saved_in_omp_construct;
15581 gimple_seq cleanup = NULL;
15582 tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_END);
15583 gimple *g = gimple_build_call (fn, 0);
15584 gimple_seq_add_stmt (&cleanup, g);
15585 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
15586 body = NULL;
15587 gimple_seq_add_stmt (&body, g);
15588 g = gimple_build_omp_taskgroup (body, *pclauses);
15589 gimplify_seq_add_stmt (pre_p, g);
15590 ret = GS_ALL_DONE;
15591 break;
15594 case OMP_ATOMIC:
15595 case OMP_ATOMIC_READ:
15596 case OMP_ATOMIC_CAPTURE_OLD:
15597 case OMP_ATOMIC_CAPTURE_NEW:
15598 ret = gimplify_omp_atomic (expr_p, pre_p);
15599 break;
15601 case TRANSACTION_EXPR:
15602 ret = gimplify_transaction (expr_p, pre_p);
15603 break;
15605 case TRUTH_AND_EXPR:
15606 case TRUTH_OR_EXPR:
15607 case TRUTH_XOR_EXPR:
15609 tree orig_type = TREE_TYPE (*expr_p);
15610 tree new_type, xop0, xop1;
15611 *expr_p = gimple_boolify (*expr_p);
15612 new_type = TREE_TYPE (*expr_p);
15613 if (!useless_type_conversion_p (orig_type, new_type))
15615 *expr_p = fold_convert_loc (input_location, orig_type, *expr_p);
15616 ret = GS_OK;
15617 break;
15620 /* Boolified binary truth expressions are semantically equivalent
15621 to bitwise binary expressions. Canonicalize them to the
15622 bitwise variant. */
15623 switch (TREE_CODE (*expr_p))
15625 case TRUTH_AND_EXPR:
15626 TREE_SET_CODE (*expr_p, BIT_AND_EXPR);
15627 break;
15628 case TRUTH_OR_EXPR:
15629 TREE_SET_CODE (*expr_p, BIT_IOR_EXPR);
15630 break;
15631 case TRUTH_XOR_EXPR:
15632 TREE_SET_CODE (*expr_p, BIT_XOR_EXPR);
15633 break;
15634 default:
15635 break;
15637 /* Now make sure that operands have compatible type to
15638 expression's new_type. */
15639 xop0 = TREE_OPERAND (*expr_p, 0);
15640 xop1 = TREE_OPERAND (*expr_p, 1);
15641 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop0)))
15642 TREE_OPERAND (*expr_p, 0) = fold_convert_loc (input_location,
15643 new_type,
15644 xop0);
15645 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop1)))
15646 TREE_OPERAND (*expr_p, 1) = fold_convert_loc (input_location,
15647 new_type,
15648 xop1);
15649 /* Continue classified as tcc_binary. */
15650 goto expr_2;
15653 case VEC_COND_EXPR:
15654 goto expr_3;
15656 case VEC_PERM_EXPR:
15657 /* Classified as tcc_expression. */
15658 goto expr_3;
15660 case BIT_INSERT_EXPR:
15661 /* Argument 3 is a constant. */
15662 goto expr_2;
15664 case POINTER_PLUS_EXPR:
15666 enum gimplify_status r0, r1;
15667 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15668 post_p, is_gimple_val, fb_rvalue);
15669 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
15670 post_p, is_gimple_val, fb_rvalue);
15671 recalculate_side_effects (*expr_p);
15672 ret = MIN (r0, r1);
15673 break;
15676 default:
15677 switch (TREE_CODE_CLASS (TREE_CODE (*expr_p)))
15679 case tcc_comparison:
15680 /* Handle comparison of objects of non scalar mode aggregates
15681 with a call to memcmp. It would be nice to only have to do
15682 this for variable-sized objects, but then we'd have to allow
15683 the same nest of reference nodes we allow for MODIFY_EXPR and
15684 that's too complex.
15686 Compare scalar mode aggregates as scalar mode values. Using
15687 memcmp for them would be very inefficient at best, and is
15688 plain wrong if bitfields are involved. */
15690 tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 1));
15692 /* Vector comparisons need no boolification. */
15693 if (TREE_CODE (type) == VECTOR_TYPE)
15694 goto expr_2;
15695 else if (!AGGREGATE_TYPE_P (type))
15697 tree org_type = TREE_TYPE (*expr_p);
15698 *expr_p = gimple_boolify (*expr_p);
15699 if (!useless_type_conversion_p (org_type,
15700 TREE_TYPE (*expr_p)))
15702 *expr_p = fold_convert_loc (input_location,
15703 org_type, *expr_p);
15704 ret = GS_OK;
15706 else
15707 goto expr_2;
15709 else if (TYPE_MODE (type) != BLKmode)
15710 ret = gimplify_scalar_mode_aggregate_compare (expr_p);
15711 else
15712 ret = gimplify_variable_sized_compare (expr_p);
15714 break;
15717 /* If *EXPR_P does not need to be special-cased, handle it
15718 according to its class. */
15719 case tcc_unary:
15720 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15721 post_p, is_gimple_val, fb_rvalue);
15722 break;
15724 case tcc_binary:
15725 expr_2:
15727 enum gimplify_status r0, r1;
15729 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15730 post_p, is_gimple_val, fb_rvalue);
15731 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
15732 post_p, is_gimple_val, fb_rvalue);
15734 ret = MIN (r0, r1);
15735 break;
15738 expr_3:
15740 enum gimplify_status r0, r1, r2;
15742 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15743 post_p, is_gimple_val, fb_rvalue);
15744 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
15745 post_p, is_gimple_val, fb_rvalue);
15746 r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p,
15747 post_p, is_gimple_val, fb_rvalue);
15749 ret = MIN (MIN (r0, r1), r2);
15750 break;
15753 case tcc_declaration:
15754 case tcc_constant:
15755 ret = GS_ALL_DONE;
15756 goto dont_recalculate;
15758 default:
15759 gcc_unreachable ();
15762 recalculate_side_effects (*expr_p);
15764 dont_recalculate:
15765 break;
15768 gcc_assert (*expr_p || ret != GS_OK);
15770 while (ret == GS_OK);
15772 /* If we encountered an error_mark somewhere nested inside, either
15773 stub out the statement or propagate the error back out. */
15774 if (ret == GS_ERROR)
15776 if (is_statement)
15777 *expr_p = NULL;
15778 goto out;
15781 /* This was only valid as a return value from the langhook, which
15782 we handled. Make sure it doesn't escape from any other context. */
15783 gcc_assert (ret != GS_UNHANDLED);
15785 if (fallback == fb_none && *expr_p && !is_gimple_stmt (*expr_p))
15787 /* We aren't looking for a value, and we don't have a valid
15788 statement. If it doesn't have side-effects, throw it away.
15789 We can also get here with code such as "*&&L;", where L is
15790 a LABEL_DECL that is marked as FORCED_LABEL. */
15791 if (TREE_CODE (*expr_p) == LABEL_DECL
15792 || !TREE_SIDE_EFFECTS (*expr_p))
15793 *expr_p = NULL;
15794 else if (!TREE_THIS_VOLATILE (*expr_p))
15796 /* This is probably a _REF that contains something nested that
15797 has side effects. Recurse through the operands to find it. */
15798 enum tree_code code = TREE_CODE (*expr_p);
15800 switch (code)
15802 case COMPONENT_REF:
15803 case REALPART_EXPR:
15804 case IMAGPART_EXPR:
15805 case VIEW_CONVERT_EXPR:
15806 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
15807 gimple_test_f, fallback);
15808 break;
15810 case ARRAY_REF:
15811 case ARRAY_RANGE_REF:
15812 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
15813 gimple_test_f, fallback);
15814 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
15815 gimple_test_f, fallback);
15816 break;
15818 default:
15819 /* Anything else with side-effects must be converted to
15820 a valid statement before we get here. */
15821 gcc_unreachable ();
15824 *expr_p = NULL;
15826 else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p))
15827 && TYPE_MODE (TREE_TYPE (*expr_p)) != BLKmode
15828 && !is_empty_type (TREE_TYPE (*expr_p)))
15830 /* Historically, the compiler has treated a bare reference
15831 to a non-BLKmode volatile lvalue as forcing a load. */
15832 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p));
15834 /* Normally, we do not want to create a temporary for a
15835 TREE_ADDRESSABLE type because such a type should not be
15836 copied by bitwise-assignment. However, we make an
15837 exception here, as all we are doing here is ensuring that
15838 we read the bytes that make up the type. We use
15839 create_tmp_var_raw because create_tmp_var will abort when
15840 given a TREE_ADDRESSABLE type. */
15841 tree tmp = create_tmp_var_raw (type, "vol");
15842 gimple_add_tmp_var (tmp);
15843 gimplify_assign (tmp, *expr_p, pre_p);
15844 *expr_p = NULL;
15846 else
15847 /* We can't do anything useful with a volatile reference to
15848 an incomplete type, so just throw it away. Likewise for
15849 a BLKmode type, since any implicit inner load should
15850 already have been turned into an explicit one by the
15851 gimplification process. */
15852 *expr_p = NULL;
15855 /* If we are gimplifying at the statement level, we're done. Tack
15856 everything together and return. */
15857 if (fallback == fb_none || is_statement)
15859 /* Since *EXPR_P has been converted into a GIMPLE tuple, clear
15860 it out for GC to reclaim it. */
15861 *expr_p = NULL_TREE;
15863 if (!gimple_seq_empty_p (internal_pre)
15864 || !gimple_seq_empty_p (internal_post))
15866 gimplify_seq_add_seq (&internal_pre, internal_post);
15867 gimplify_seq_add_seq (pre_p, internal_pre);
15870 /* The result of gimplifying *EXPR_P is going to be the last few
15871 statements in *PRE_P and *POST_P. Add location information
15872 to all the statements that were added by the gimplification
15873 helpers. */
15874 if (!gimple_seq_empty_p (*pre_p))
15875 annotate_all_with_location_after (*pre_p, pre_last_gsi, input_location);
15877 if (!gimple_seq_empty_p (*post_p))
15878 annotate_all_with_location_after (*post_p, post_last_gsi,
15879 input_location);
15881 goto out;
15884 #ifdef ENABLE_GIMPLE_CHECKING
15885 if (*expr_p)
15887 enum tree_code code = TREE_CODE (*expr_p);
15888 /* These expressions should already be in gimple IR form. */
15889 gcc_assert (code != MODIFY_EXPR
15890 && code != ASM_EXPR
15891 && code != BIND_EXPR
15892 && code != CATCH_EXPR
15893 && (code != COND_EXPR || gimplify_ctxp->allow_rhs_cond_expr)
15894 && code != EH_FILTER_EXPR
15895 && code != GOTO_EXPR
15896 && code != LABEL_EXPR
15897 && code != LOOP_EXPR
15898 && code != SWITCH_EXPR
15899 && code != TRY_FINALLY_EXPR
15900 && code != EH_ELSE_EXPR
15901 && code != OACC_PARALLEL
15902 && code != OACC_KERNELS
15903 && code != OACC_SERIAL
15904 && code != OACC_DATA
15905 && code != OACC_HOST_DATA
15906 && code != OACC_DECLARE
15907 && code != OACC_UPDATE
15908 && code != OACC_ENTER_DATA
15909 && code != OACC_EXIT_DATA
15910 && code != OACC_CACHE
15911 && code != OMP_CRITICAL
15912 && code != OMP_FOR
15913 && code != OACC_LOOP
15914 && code != OMP_MASTER
15915 && code != OMP_MASKED
15916 && code != OMP_TASKGROUP
15917 && code != OMP_ORDERED
15918 && code != OMP_PARALLEL
15919 && code != OMP_SCAN
15920 && code != OMP_SECTIONS
15921 && code != OMP_SECTION
15922 && code != OMP_SINGLE
15923 && code != OMP_SCOPE);
15925 #endif
15927 /* Otherwise we're gimplifying a subexpression, so the resulting
15928 value is interesting. If it's a valid operand that matches
15929 GIMPLE_TEST_F, we're done. Unless we are handling some
15930 post-effects internally; if that's the case, we need to copy into
15931 a temporary before adding the post-effects to POST_P. */
15932 if (gimple_seq_empty_p (internal_post) && (*gimple_test_f) (*expr_p))
15933 goto out;
15935 /* Otherwise, we need to create a new temporary for the gimplified
15936 expression. */
15938 /* We can't return an lvalue if we have an internal postqueue. The
15939 object the lvalue refers to would (probably) be modified by the
15940 postqueue; we need to copy the value out first, which means an
15941 rvalue. */
15942 if ((fallback & fb_lvalue)
15943 && gimple_seq_empty_p (internal_post)
15944 && is_gimple_addressable (*expr_p))
15946 /* An lvalue will do. Take the address of the expression, store it
15947 in a temporary, and replace the expression with an INDIRECT_REF of
15948 that temporary. */
15949 tree ref_alias_type = reference_alias_ptr_type (*expr_p);
15950 unsigned int ref_align = get_object_alignment (*expr_p);
15951 tree ref_type = TREE_TYPE (*expr_p);
15952 tmp = build_fold_addr_expr_loc (input_location, *expr_p);
15953 gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue);
15954 if (TYPE_ALIGN (ref_type) != ref_align)
15955 ref_type = build_aligned_type (ref_type, ref_align);
15956 *expr_p = build2 (MEM_REF, ref_type,
15957 tmp, build_zero_cst (ref_alias_type));
15959 else if ((fallback & fb_rvalue) && is_gimple_reg_rhs_or_call (*expr_p))
15961 /* An rvalue will do. Assign the gimplified expression into a
15962 new temporary TMP and replace the original expression with
15963 TMP. First, make sure that the expression has a type so that
15964 it can be assigned into a temporary. */
15965 gcc_assert (!VOID_TYPE_P (TREE_TYPE (*expr_p)));
15966 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
15968 else
15970 #ifdef ENABLE_GIMPLE_CHECKING
15971 if (!(fallback & fb_mayfail))
15973 fprintf (stderr, "gimplification failed:\n");
15974 print_generic_expr (stderr, *expr_p);
15975 debug_tree (*expr_p);
15976 internal_error ("gimplification failed");
15978 #endif
15979 gcc_assert (fallback & fb_mayfail);
15981 /* If this is an asm statement, and the user asked for the
15982 impossible, don't die. Fail and let gimplify_asm_expr
15983 issue an error. */
15984 ret = GS_ERROR;
15985 goto out;
15988 /* Make sure the temporary matches our predicate. */
15989 gcc_assert ((*gimple_test_f) (*expr_p));
15991 if (!gimple_seq_empty_p (internal_post))
15993 annotate_all_with_location (internal_post, input_location);
15994 gimplify_seq_add_seq (pre_p, internal_post);
15997 out:
15998 input_location = saved_location;
15999 return ret;
16002 /* Like gimplify_expr but make sure the gimplified result is not itself
16003 a SSA name (but a decl if it were). Temporaries required by
16004 evaluating *EXPR_P may be still SSA names. */
16006 static enum gimplify_status
16007 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
16008 bool (*gimple_test_f) (tree), fallback_t fallback,
16009 bool allow_ssa)
16011 enum gimplify_status ret = gimplify_expr (expr_p, pre_p, post_p,
16012 gimple_test_f, fallback);
16013 if (! allow_ssa
16014 && TREE_CODE (*expr_p) == SSA_NAME)
16015 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, NULL, false);
16016 return ret;
16019 /* Look through TYPE for variable-sized objects and gimplify each such
16020 size that we find. Add to LIST_P any statements generated. */
16022 void
16023 gimplify_type_sizes (tree type, gimple_seq *list_p)
16025 if (type == NULL || type == error_mark_node)
16026 return;
16028 const bool ignored_p
16029 = TYPE_NAME (type)
16030 && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
16031 && DECL_IGNORED_P (TYPE_NAME (type));
16032 tree t;
16034 /* We first do the main variant, then copy into any other variants. */
16035 type = TYPE_MAIN_VARIANT (type);
16037 /* Avoid infinite recursion. */
16038 if (TYPE_SIZES_GIMPLIFIED (type))
16039 return;
16041 TYPE_SIZES_GIMPLIFIED (type) = 1;
16043 switch (TREE_CODE (type))
16045 case INTEGER_TYPE:
16046 case ENUMERAL_TYPE:
16047 case BOOLEAN_TYPE:
16048 case REAL_TYPE:
16049 case FIXED_POINT_TYPE:
16050 gimplify_one_sizepos (&TYPE_MIN_VALUE (type), list_p);
16051 gimplify_one_sizepos (&TYPE_MAX_VALUE (type), list_p);
16053 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
16055 TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type);
16056 TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type);
16058 break;
16060 case ARRAY_TYPE:
16061 /* These types may not have declarations, so handle them here. */
16062 gimplify_type_sizes (TREE_TYPE (type), list_p);
16063 gimplify_type_sizes (TYPE_DOMAIN (type), list_p);
16064 /* Ensure VLA bounds aren't removed, for -O0 they should be variables
16065 with assigned stack slots, for -O1+ -g they should be tracked
16066 by VTA. */
16067 if (!ignored_p
16068 && TYPE_DOMAIN (type)
16069 && INTEGRAL_TYPE_P (TYPE_DOMAIN (type)))
16071 t = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
16072 if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
16073 DECL_IGNORED_P (t) = 0;
16074 t = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
16075 if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
16076 DECL_IGNORED_P (t) = 0;
16078 break;
16080 case RECORD_TYPE:
16081 case UNION_TYPE:
16082 case QUAL_UNION_TYPE:
16083 for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
16084 if (TREE_CODE (field) == FIELD_DECL)
16086 gimplify_one_sizepos (&DECL_FIELD_OFFSET (field), list_p);
16087 /* Likewise, ensure variable offsets aren't removed. */
16088 if (!ignored_p
16089 && (t = DECL_FIELD_OFFSET (field))
16090 && VAR_P (t)
16091 && DECL_ARTIFICIAL (t))
16092 DECL_IGNORED_P (t) = 0;
16093 gimplify_one_sizepos (&DECL_SIZE (field), list_p);
16094 gimplify_one_sizepos (&DECL_SIZE_UNIT (field), list_p);
16095 gimplify_type_sizes (TREE_TYPE (field), list_p);
16097 break;
16099 case POINTER_TYPE:
16100 case REFERENCE_TYPE:
16101 /* We used to recurse on the pointed-to type here, which turned out to
16102 be incorrect because its definition might refer to variables not
16103 yet initialized at this point if a forward declaration is involved.
16105 It was actually useful for anonymous pointed-to types to ensure
16106 that the sizes evaluation dominates every possible later use of the
16107 values. Restricting to such types here would be safe since there
16108 is no possible forward declaration around, but would introduce an
16109 undesirable middle-end semantic to anonymity. We then defer to
16110 front-ends the responsibility of ensuring that the sizes are
16111 evaluated both early and late enough, e.g. by attaching artificial
16112 type declarations to the tree. */
16113 break;
16115 default:
16116 break;
16119 gimplify_one_sizepos (&TYPE_SIZE (type), list_p);
16120 gimplify_one_sizepos (&TYPE_SIZE_UNIT (type), list_p);
16122 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
16124 TYPE_SIZE (t) = TYPE_SIZE (type);
16125 TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (type);
16126 TYPE_SIZES_GIMPLIFIED (t) = 1;
16130 /* A subroutine of gimplify_type_sizes to make sure that *EXPR_P,
16131 a size or position, has had all of its SAVE_EXPRs evaluated.
16132 We add any required statements to *STMT_P. */
16134 void
16135 gimplify_one_sizepos (tree *expr_p, gimple_seq *stmt_p)
16137 tree expr = *expr_p;
16139 /* We don't do anything if the value isn't there, is constant, or contains
16140 A PLACEHOLDER_EXPR. We also don't want to do anything if it's already
16141 a VAR_DECL. If it's a VAR_DECL from another function, the gimplifier
16142 will want to replace it with a new variable, but that will cause problems
16143 if this type is from outside the function. It's OK to have that here. */
16144 if (expr == NULL_TREE
16145 || is_gimple_constant (expr)
16146 || TREE_CODE (expr) == VAR_DECL
16147 || CONTAINS_PLACEHOLDER_P (expr))
16148 return;
16150 *expr_p = unshare_expr (expr);
16152 /* SSA names in decl/type fields are a bad idea - they'll get reclaimed
16153 if the def vanishes. */
16154 gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue, false);
16156 /* If expr wasn't already is_gimple_sizepos or is_gimple_constant from the
16157 FE, ensure that it is a VAR_DECL, otherwise we might handle some decls
16158 as gimplify_vla_decl even when they would have all sizes INTEGER_CSTs. */
16159 if (is_gimple_constant (*expr_p))
16160 *expr_p = get_initialized_tmp_var (*expr_p, stmt_p, NULL, false);
16163 /* Gimplify the body of statements of FNDECL and return a GIMPLE_BIND node
16164 containing the sequence of corresponding GIMPLE statements. If DO_PARMS
16165 is true, also gimplify the parameters. */
16167 gbind *
16168 gimplify_body (tree fndecl, bool do_parms)
16170 location_t saved_location = input_location;
16171 gimple_seq parm_stmts, parm_cleanup = NULL, seq;
16172 gimple *outer_stmt;
16173 gbind *outer_bind;
16175 timevar_push (TV_TREE_GIMPLIFY);
16177 init_tree_ssa (cfun);
16179 /* Initialize for optimize_insn_for_s{ize,peed}_p possibly called during
16180 gimplification. */
16181 default_rtl_profile ();
16183 gcc_assert (gimplify_ctxp == NULL);
16184 push_gimplify_context (true);
16186 if (flag_openacc || flag_openmp)
16188 gcc_assert (gimplify_omp_ctxp == NULL);
16189 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (fndecl)))
16190 gimplify_omp_ctxp = new_omp_context (ORT_IMPLICIT_TARGET);
16193 /* Unshare most shared trees in the body and in that of any nested functions.
16194 It would seem we don't have to do this for nested functions because
16195 they are supposed to be output and then the outer function gimplified
16196 first, but the g++ front end doesn't always do it that way. */
16197 unshare_body (fndecl);
16198 unvisit_body (fndecl);
16200 /* Make sure input_location isn't set to something weird. */
16201 input_location = DECL_SOURCE_LOCATION (fndecl);
16203 /* Resolve callee-copies. This has to be done before processing
16204 the body so that DECL_VALUE_EXPR gets processed correctly. */
16205 parm_stmts = do_parms ? gimplify_parameters (&parm_cleanup) : NULL;
16207 /* Gimplify the function's body. */
16208 seq = NULL;
16209 gimplify_stmt (&DECL_SAVED_TREE (fndecl), &seq);
16210 outer_stmt = gimple_seq_first_nondebug_stmt (seq);
16211 if (!outer_stmt)
16213 outer_stmt = gimple_build_nop ();
16214 gimplify_seq_add_stmt (&seq, outer_stmt);
16217 /* The body must contain exactly one statement, a GIMPLE_BIND. If this is
16218 not the case, wrap everything in a GIMPLE_BIND to make it so. */
16219 if (gimple_code (outer_stmt) == GIMPLE_BIND
16220 && (gimple_seq_first_nondebug_stmt (seq)
16221 == gimple_seq_last_nondebug_stmt (seq)))
16223 outer_bind = as_a <gbind *> (outer_stmt);
16224 if (gimple_seq_first_stmt (seq) != outer_stmt
16225 || gimple_seq_last_stmt (seq) != outer_stmt)
16227 /* If there are debug stmts before or after outer_stmt, move them
16228 inside of outer_bind body. */
16229 gimple_stmt_iterator gsi = gsi_for_stmt (outer_stmt, &seq);
16230 gimple_seq second_seq = NULL;
16231 if (gimple_seq_first_stmt (seq) != outer_stmt
16232 && gimple_seq_last_stmt (seq) != outer_stmt)
16234 second_seq = gsi_split_seq_after (gsi);
16235 gsi_remove (&gsi, false);
16237 else if (gimple_seq_first_stmt (seq) != outer_stmt)
16238 gsi_remove (&gsi, false);
16239 else
16241 gsi_remove (&gsi, false);
16242 second_seq = seq;
16243 seq = NULL;
16245 gimple_seq_add_seq_without_update (&seq,
16246 gimple_bind_body (outer_bind));
16247 gimple_seq_add_seq_without_update (&seq, second_seq);
16248 gimple_bind_set_body (outer_bind, seq);
16251 else
16252 outer_bind = gimple_build_bind (NULL_TREE, seq, NULL);
16254 DECL_SAVED_TREE (fndecl) = NULL_TREE;
16256 /* If we had callee-copies statements, insert them at the beginning
16257 of the function and clear DECL_VALUE_EXPR_P on the parameters. */
16258 if (!gimple_seq_empty_p (parm_stmts))
16260 tree parm;
16262 gimplify_seq_add_seq (&parm_stmts, gimple_bind_body (outer_bind));
16263 if (parm_cleanup)
16265 gtry *g = gimple_build_try (parm_stmts, parm_cleanup,
16266 GIMPLE_TRY_FINALLY);
16267 parm_stmts = NULL;
16268 gimple_seq_add_stmt (&parm_stmts, g);
16270 gimple_bind_set_body (outer_bind, parm_stmts);
16272 for (parm = DECL_ARGUMENTS (current_function_decl);
16273 parm; parm = DECL_CHAIN (parm))
16274 if (DECL_HAS_VALUE_EXPR_P (parm))
16276 DECL_HAS_VALUE_EXPR_P (parm) = 0;
16277 DECL_IGNORED_P (parm) = 0;
16281 if ((flag_openacc || flag_openmp || flag_openmp_simd)
16282 && gimplify_omp_ctxp)
16284 delete_omp_context (gimplify_omp_ctxp);
16285 gimplify_omp_ctxp = NULL;
16288 pop_gimplify_context (outer_bind);
16289 gcc_assert (gimplify_ctxp == NULL);
16291 if (flag_checking && !seen_error ())
16292 verify_gimple_in_seq (gimple_bind_body (outer_bind));
16294 timevar_pop (TV_TREE_GIMPLIFY);
16295 input_location = saved_location;
16297 return outer_bind;
16300 typedef char *char_p; /* For DEF_VEC_P. */
16302 /* Return whether we should exclude FNDECL from instrumentation. */
16304 static bool
16305 flag_instrument_functions_exclude_p (tree fndecl)
16307 vec<char_p> *v;
16309 v = (vec<char_p> *) flag_instrument_functions_exclude_functions;
16310 if (v && v->length () > 0)
16312 const char *name;
16313 int i;
16314 char *s;
16316 name = lang_hooks.decl_printable_name (fndecl, 1);
16317 FOR_EACH_VEC_ELT (*v, i, s)
16318 if (strstr (name, s) != NULL)
16319 return true;
16322 v = (vec<char_p> *) flag_instrument_functions_exclude_files;
16323 if (v && v->length () > 0)
16325 const char *name;
16326 int i;
16327 char *s;
16329 name = DECL_SOURCE_FILE (fndecl);
16330 FOR_EACH_VEC_ELT (*v, i, s)
16331 if (strstr (name, s) != NULL)
16332 return true;
16335 return false;
16338 /* Entry point to the gimplification pass. FNDECL is the FUNCTION_DECL
16339 node for the function we want to gimplify.
16341 Return the sequence of GIMPLE statements corresponding to the body
16342 of FNDECL. */
16344 void
16345 gimplify_function_tree (tree fndecl)
16347 gimple_seq seq;
16348 gbind *bind;
16350 gcc_assert (!gimple_body (fndecl));
16352 if (DECL_STRUCT_FUNCTION (fndecl))
16353 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
16354 else
16355 push_struct_function (fndecl);
16357 /* Tentatively set PROP_gimple_lva here, and reset it in gimplify_va_arg_expr
16358 if necessary. */
16359 cfun->curr_properties |= PROP_gimple_lva;
16361 if (asan_sanitize_use_after_scope ())
16362 asan_poisoned_variables = new hash_set<tree> ();
16363 bind = gimplify_body (fndecl, true);
16364 if (asan_poisoned_variables)
16366 delete asan_poisoned_variables;
16367 asan_poisoned_variables = NULL;
16370 /* The tree body of the function is no longer needed, replace it
16371 with the new GIMPLE body. */
16372 seq = NULL;
16373 gimple_seq_add_stmt (&seq, bind);
16374 gimple_set_body (fndecl, seq);
16376 /* If we're instrumenting function entry/exit, then prepend the call to
16377 the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to
16378 catch the exit hook. */
16379 /* ??? Add some way to ignore exceptions for this TFE. */
16380 if (flag_instrument_function_entry_exit
16381 && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl)
16382 /* Do not instrument extern inline functions. */
16383 && !(DECL_DECLARED_INLINE_P (fndecl)
16384 && DECL_EXTERNAL (fndecl)
16385 && DECL_DISREGARD_INLINE_LIMITS (fndecl))
16386 && !flag_instrument_functions_exclude_p (fndecl))
16388 tree x;
16389 gbind *new_bind;
16390 gimple *tf;
16391 gimple_seq cleanup = NULL, body = NULL;
16392 tree tmp_var, this_fn_addr;
16393 gcall *call;
16395 /* The instrumentation hooks aren't going to call the instrumented
16396 function and the address they receive is expected to be matchable
16397 against symbol addresses. Make sure we don't create a trampoline,
16398 in case the current function is nested. */
16399 this_fn_addr = build_fold_addr_expr (current_function_decl);
16400 TREE_NO_TRAMPOLINE (this_fn_addr) = 1;
16402 x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
16403 call = gimple_build_call (x, 1, integer_zero_node);
16404 tmp_var = create_tmp_var (ptr_type_node, "return_addr");
16405 gimple_call_set_lhs (call, tmp_var);
16406 gimplify_seq_add_stmt (&cleanup, call);
16407 x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_EXIT);
16408 call = gimple_build_call (x, 2, this_fn_addr, tmp_var);
16409 gimplify_seq_add_stmt (&cleanup, call);
16410 tf = gimple_build_try (seq, cleanup, GIMPLE_TRY_FINALLY);
16412 x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
16413 call = gimple_build_call (x, 1, integer_zero_node);
16414 tmp_var = create_tmp_var (ptr_type_node, "return_addr");
16415 gimple_call_set_lhs (call, tmp_var);
16416 gimplify_seq_add_stmt (&body, call);
16417 x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_ENTER);
16418 call = gimple_build_call (x, 2, this_fn_addr, tmp_var);
16419 gimplify_seq_add_stmt (&body, call);
16420 gimplify_seq_add_stmt (&body, tf);
16421 new_bind = gimple_build_bind (NULL, body, NULL);
16423 /* Replace the current function body with the body
16424 wrapped in the try/finally TF. */
16425 seq = NULL;
16426 gimple_seq_add_stmt (&seq, new_bind);
16427 gimple_set_body (fndecl, seq);
16428 bind = new_bind;
16431 if (sanitize_flags_p (SANITIZE_THREAD)
16432 && param_tsan_instrument_func_entry_exit)
16434 gcall *call = gimple_build_call_internal (IFN_TSAN_FUNC_EXIT, 0);
16435 gimple *tf = gimple_build_try (seq, call, GIMPLE_TRY_FINALLY);
16436 gbind *new_bind = gimple_build_bind (NULL, tf, NULL);
16437 /* Replace the current function body with the body
16438 wrapped in the try/finally TF. */
16439 seq = NULL;
16440 gimple_seq_add_stmt (&seq, new_bind);
16441 gimple_set_body (fndecl, seq);
16444 DECL_SAVED_TREE (fndecl) = NULL_TREE;
16445 cfun->curr_properties |= PROP_gimple_any;
16447 pop_cfun ();
16449 dump_function (TDI_gimple, fndecl);
16452 /* Return a dummy expression of type TYPE in order to keep going after an
16453 error. */
16455 static tree
16456 dummy_object (tree type)
16458 tree t = build_int_cst (build_pointer_type (type), 0);
16459 return build2 (MEM_REF, type, t, t);
16462 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
16463 builtin function, but a very special sort of operator. */
16465 enum gimplify_status
16466 gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p,
16467 gimple_seq *post_p ATTRIBUTE_UNUSED)
16469 tree promoted_type, have_va_type;
16470 tree valist = TREE_OPERAND (*expr_p, 0);
16471 tree type = TREE_TYPE (*expr_p);
16472 tree t, tag, aptag;
16473 location_t loc = EXPR_LOCATION (*expr_p);
16475 /* Verify that valist is of the proper type. */
16476 have_va_type = TREE_TYPE (valist);
16477 if (have_va_type == error_mark_node)
16478 return GS_ERROR;
16479 have_va_type = targetm.canonical_va_list_type (have_va_type);
16480 if (have_va_type == NULL_TREE
16481 && POINTER_TYPE_P (TREE_TYPE (valist)))
16482 /* Handle 'Case 1: Not an array type' from c-common.cc/build_va_arg. */
16483 have_va_type
16484 = targetm.canonical_va_list_type (TREE_TYPE (TREE_TYPE (valist)));
16485 gcc_assert (have_va_type != NULL_TREE);
16487 /* Generate a diagnostic for requesting data of a type that cannot
16488 be passed through `...' due to type promotion at the call site. */
16489 if ((promoted_type = lang_hooks.types.type_promotes_to (type))
16490 != type)
16492 static bool gave_help;
16493 bool warned;
16494 /* Use the expansion point to handle cases such as passing bool (defined
16495 in a system header) through `...'. */
16496 location_t xloc
16497 = expansion_point_location_if_in_system_header (loc);
16499 /* Unfortunately, this is merely undefined, rather than a constraint
16500 violation, so we cannot make this an error. If this call is never
16501 executed, the program is still strictly conforming. */
16502 auto_diagnostic_group d;
16503 warned = warning_at (xloc, 0,
16504 "%qT is promoted to %qT when passed through %<...%>",
16505 type, promoted_type);
16506 if (!gave_help && warned)
16508 gave_help = true;
16509 inform (xloc, "(so you should pass %qT not %qT to %<va_arg%>)",
16510 promoted_type, type);
16513 /* We can, however, treat "undefined" any way we please.
16514 Call abort to encourage the user to fix the program. */
16515 if (warned)
16516 inform (xloc, "if this code is reached, the program will abort");
16517 /* Before the abort, allow the evaluation of the va_list
16518 expression to exit or longjmp. */
16519 gimplify_and_add (valist, pre_p);
16520 t = build_call_expr_loc (loc,
16521 builtin_decl_implicit (BUILT_IN_TRAP), 0);
16522 gimplify_and_add (t, pre_p);
16524 /* This is dead code, but go ahead and finish so that the
16525 mode of the result comes out right. */
16526 *expr_p = dummy_object (type);
16527 return GS_ALL_DONE;
16530 tag = build_int_cst (build_pointer_type (type), 0);
16531 aptag = build_int_cst (TREE_TYPE (valist), 0);
16533 *expr_p = build_call_expr_internal_loc (loc, IFN_VA_ARG, type, 3,
16534 valist, tag, aptag);
16536 /* Clear the tentatively set PROP_gimple_lva, to indicate that IFN_VA_ARG
16537 needs to be expanded. */
16538 cfun->curr_properties &= ~PROP_gimple_lva;
16540 return GS_OK;
16543 /* Build a new GIMPLE_ASSIGN tuple and append it to the end of *SEQ_P.
16545 DST/SRC are the destination and source respectively. You can pass
16546 ungimplified trees in DST or SRC, in which case they will be
16547 converted to a gimple operand if necessary.
16549 This function returns the newly created GIMPLE_ASSIGN tuple. */
16551 gimple *
16552 gimplify_assign (tree dst, tree src, gimple_seq *seq_p)
16554 tree t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
16555 gimplify_and_add (t, seq_p);
16556 ggc_free (t);
16557 return gimple_seq_last_stmt (*seq_p);
16560 inline hashval_t
16561 gimplify_hasher::hash (const elt_t *p)
16563 tree t = p->val;
16564 return iterative_hash_expr (t, 0);
16567 inline bool
16568 gimplify_hasher::equal (const elt_t *p1, const elt_t *p2)
16570 tree t1 = p1->val;
16571 tree t2 = p2->val;
16572 enum tree_code code = TREE_CODE (t1);
16574 if (TREE_CODE (t2) != code
16575 || TREE_TYPE (t1) != TREE_TYPE (t2))
16576 return false;
16578 if (!operand_equal_p (t1, t2, 0))
16579 return false;
16581 /* Only allow them to compare equal if they also hash equal; otherwise
16582 results are nondeterminate, and we fail bootstrap comparison. */
16583 gcc_checking_assert (hash (p1) == hash (p2));
16585 return true;