RISC-V: Make dynamic LMUL cost model more accurate for conversion codes
[official-gcc.git] / gcc / gimplify.cc
blobf71abedcb30c45b7774fa861388c3bbce96e4aea
1 /* Tree lowering pass. This pass converts the GENERIC functions-as-trees
2 tree representation into the GIMPLE form.
3 Copyright (C) 2002-2023 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 "diagnostic.h" /* For errorcount. */
40 #include "alias.h"
41 #include "fold-const.h"
42 #include "calls.h"
43 #include "varasm.h"
44 #include "stmt.h"
45 #include "expr.h"
46 #include "gimple-iterator.h"
47 #include "gimple-fold.h"
48 #include "tree-eh.h"
49 #include "gimplify.h"
50 #include "stor-layout.h"
51 #include "print-tree.h"
52 #include "tree-iterator.h"
53 #include "tree-inline.h"
54 #include "langhooks.h"
55 #include "tree-cfg.h"
56 #include "tree-ssa.h"
57 #include "tree-hash-traits.h"
58 #include "omp-general.h"
59 #include "omp-low.h"
60 #include "gimple-low.h"
61 #include "gomp-constants.h"
62 #include "splay-tree.h"
63 #include "gimple-walk.h"
64 #include "langhooks-def.h" /* FIXME: for lhd_set_decl_assembler_name */
65 #include "builtins.h"
66 #include "stringpool.h"
67 #include "attribs.h"
68 #include "asan.h"
69 #include "dbgcnt.h"
70 #include "omp-offload.h"
71 #include "context.h"
72 #include "tree-nested.h"
74 /* Hash set of poisoned variables in a bind expr. */
75 static hash_set<tree> *asan_poisoned_variables = NULL;
77 enum gimplify_omp_var_data
79 GOVD_SEEN = 0x000001,
80 GOVD_EXPLICIT = 0x000002,
81 GOVD_SHARED = 0x000004,
82 GOVD_PRIVATE = 0x000008,
83 GOVD_FIRSTPRIVATE = 0x000010,
84 GOVD_LASTPRIVATE = 0x000020,
85 GOVD_REDUCTION = 0x000040,
86 GOVD_LOCAL = 0x00080,
87 GOVD_MAP = 0x000100,
88 GOVD_DEBUG_PRIVATE = 0x000200,
89 GOVD_PRIVATE_OUTER_REF = 0x000400,
90 GOVD_LINEAR = 0x000800,
91 GOVD_ALIGNED = 0x001000,
93 /* Flag for GOVD_MAP: don't copy back. */
94 GOVD_MAP_TO_ONLY = 0x002000,
96 /* Flag for GOVD_LINEAR or GOVD_LASTPRIVATE: no outer reference. */
97 GOVD_LINEAR_LASTPRIVATE_NO_OUTER = 0x004000,
99 GOVD_MAP_0LEN_ARRAY = 0x008000,
101 /* Flag for GOVD_MAP, if it is always, to or always, tofrom mapping. */
102 GOVD_MAP_ALWAYS_TO = 0x010000,
104 /* Flag for shared vars that are or might be stored to in the region. */
105 GOVD_WRITTEN = 0x020000,
107 /* Flag for GOVD_MAP, if it is a forced mapping. */
108 GOVD_MAP_FORCE = 0x040000,
110 /* Flag for GOVD_MAP: must be present already. */
111 GOVD_MAP_FORCE_PRESENT = 0x080000,
113 /* Flag for GOVD_MAP: only allocate. */
114 GOVD_MAP_ALLOC_ONLY = 0x100000,
116 /* Flag for GOVD_MAP: only copy back. */
117 GOVD_MAP_FROM_ONLY = 0x200000,
119 GOVD_NONTEMPORAL = 0x400000,
121 /* Flag for GOVD_LASTPRIVATE: conditional modifier. */
122 GOVD_LASTPRIVATE_CONDITIONAL = 0x800000,
124 GOVD_CONDTEMP = 0x1000000,
126 /* Flag for GOVD_REDUCTION: inscan seen in {in,ex}clusive clause. */
127 GOVD_REDUCTION_INSCAN = 0x2000000,
129 /* Flag for GOVD_FIRSTPRIVATE: OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT. */
130 GOVD_FIRSTPRIVATE_IMPLICIT = 0x4000000,
132 GOVD_DATA_SHARE_CLASS = (GOVD_SHARED | GOVD_PRIVATE | GOVD_FIRSTPRIVATE
133 | GOVD_LASTPRIVATE | GOVD_REDUCTION | GOVD_LINEAR
134 | GOVD_LOCAL)
138 enum omp_region_type
140 ORT_WORKSHARE = 0x00,
141 ORT_TASKGROUP = 0x01,
142 ORT_SIMD = 0x04,
144 ORT_PARALLEL = 0x08,
145 ORT_COMBINED_PARALLEL = ORT_PARALLEL | 1,
147 ORT_TASK = 0x10,
148 ORT_UNTIED_TASK = ORT_TASK | 1,
149 ORT_TASKLOOP = ORT_TASK | 2,
150 ORT_UNTIED_TASKLOOP = ORT_UNTIED_TASK | 2,
152 ORT_TEAMS = 0x20,
153 ORT_COMBINED_TEAMS = ORT_TEAMS | 1,
154 ORT_HOST_TEAMS = ORT_TEAMS | 2,
155 ORT_COMBINED_HOST_TEAMS = ORT_COMBINED_TEAMS | 2,
157 /* Data region. */
158 ORT_TARGET_DATA = 0x40,
160 /* Data region with offloading. */
161 ORT_TARGET = 0x80,
162 ORT_COMBINED_TARGET = ORT_TARGET | 1,
163 ORT_IMPLICIT_TARGET = ORT_TARGET | 2,
165 /* OpenACC variants. */
166 ORT_ACC = 0x100, /* A generic OpenACC region. */
167 ORT_ACC_DATA = ORT_ACC | ORT_TARGET_DATA, /* Data construct. */
168 ORT_ACC_PARALLEL = ORT_ACC | ORT_TARGET, /* Parallel construct */
169 ORT_ACC_KERNELS = ORT_ACC | ORT_TARGET | 2, /* Kernels construct. */
170 ORT_ACC_SERIAL = ORT_ACC | ORT_TARGET | 4, /* Serial construct. */
171 ORT_ACC_HOST_DATA = ORT_ACC | ORT_TARGET_DATA | 2, /* Host data. */
173 /* Dummy OpenMP region, used to disable expansion of
174 DECL_VALUE_EXPRs in taskloop pre body. */
175 ORT_NONE = 0x200
178 /* Gimplify hashtable helper. */
180 struct gimplify_hasher : free_ptr_hash <elt_t>
182 static inline hashval_t hash (const elt_t *);
183 static inline bool equal (const elt_t *, const elt_t *);
186 struct gimplify_ctx
188 struct gimplify_ctx *prev_context;
190 vec<gbind *> bind_expr_stack;
191 tree temps;
192 gimple_seq conditional_cleanups;
193 tree exit_label;
194 tree return_temp;
196 vec<tree> case_labels;
197 hash_set<tree> *live_switch_vars;
198 /* The formal temporary table. Should this be persistent? */
199 hash_table<gimplify_hasher> *temp_htab;
201 int conditions;
202 unsigned into_ssa : 1;
203 unsigned allow_rhs_cond_expr : 1;
204 unsigned in_cleanup_point_expr : 1;
205 unsigned keep_stack : 1;
206 unsigned save_stack : 1;
207 unsigned in_switch_expr : 1;
210 enum gimplify_defaultmap_kind
212 GDMK_SCALAR,
213 GDMK_SCALAR_TARGET, /* w/ Fortran's target attr, implicit mapping, only. */
214 GDMK_AGGREGATE,
215 GDMK_ALLOCATABLE,
216 GDMK_POINTER
219 struct gimplify_omp_ctx
221 struct gimplify_omp_ctx *outer_context;
222 splay_tree variables;
223 hash_set<tree> *privatized_types;
224 tree clauses;
225 /* Iteration variables in an OMP_FOR. */
226 vec<tree> loop_iter_var;
227 location_t location;
228 enum omp_clause_default_kind default_kind;
229 enum omp_region_type region_type;
230 enum tree_code code;
231 bool combined_loop;
232 bool distribute;
233 bool target_firstprivatize_array_bases;
234 bool add_safelen1;
235 bool order_concurrent;
236 bool has_depend;
237 bool in_for_exprs;
238 int defaultmap[5];
241 static struct gimplify_ctx *gimplify_ctxp;
242 static struct gimplify_omp_ctx *gimplify_omp_ctxp;
243 static bool in_omp_construct;
245 /* Forward declaration. */
246 static enum gimplify_status gimplify_compound_expr (tree *, gimple_seq *, bool);
247 static hash_map<tree, tree> *oacc_declare_returns;
248 static enum gimplify_status gimplify_expr (tree *, gimple_seq *, gimple_seq *,
249 bool (*) (tree), fallback_t, bool);
250 static void prepare_gimple_addressable (tree *, gimple_seq *);
252 /* Shorter alias name for the above function for use in gimplify.cc
253 only. */
255 static inline void
256 gimplify_seq_add_stmt (gimple_seq *seq_p, gimple *gs)
258 gimple_seq_add_stmt_without_update (seq_p, gs);
261 /* Append sequence SRC to the end of sequence *DST_P. If *DST_P is
262 NULL, a new sequence is allocated. This function is
263 similar to gimple_seq_add_seq, but does not scan the operands.
264 During gimplification, we need to manipulate statement sequences
265 before the def/use vectors have been constructed. */
267 static void
268 gimplify_seq_add_seq (gimple_seq *dst_p, gimple_seq src)
270 gimple_stmt_iterator si;
272 if (src == NULL)
273 return;
275 si = gsi_last (*dst_p);
276 gsi_insert_seq_after_without_update (&si, src, GSI_NEW_STMT);
280 /* Pointer to a list of allocated gimplify_ctx structs to be used for pushing
281 and popping gimplify contexts. */
283 static struct gimplify_ctx *ctx_pool = NULL;
285 /* Return a gimplify context struct from the pool. */
287 static inline struct gimplify_ctx *
288 ctx_alloc (void)
290 struct gimplify_ctx * c = ctx_pool;
292 if (c)
293 ctx_pool = c->prev_context;
294 else
295 c = XNEW (struct gimplify_ctx);
297 memset (c, '\0', sizeof (*c));
298 return c;
301 /* Put gimplify context C back into the pool. */
303 static inline void
304 ctx_free (struct gimplify_ctx *c)
306 c->prev_context = ctx_pool;
307 ctx_pool = c;
310 /* Free allocated ctx stack memory. */
312 void
313 free_gimplify_stack (void)
315 struct gimplify_ctx *c;
317 while ((c = ctx_pool))
319 ctx_pool = c->prev_context;
320 free (c);
325 /* Set up a context for the gimplifier. */
327 void
328 push_gimplify_context (bool in_ssa, bool rhs_cond_ok)
330 struct gimplify_ctx *c = ctx_alloc ();
332 c->prev_context = gimplify_ctxp;
333 gimplify_ctxp = c;
334 gimplify_ctxp->into_ssa = in_ssa;
335 gimplify_ctxp->allow_rhs_cond_expr = rhs_cond_ok;
338 /* Tear down a context for the gimplifier. If BODY is non-null, then
339 put the temporaries into the outer BIND_EXPR. Otherwise, put them
340 in the local_decls.
342 BODY is not a sequence, but the first tuple in a sequence. */
344 void
345 pop_gimplify_context (gimple *body)
347 struct gimplify_ctx *c = gimplify_ctxp;
349 gcc_assert (c
350 && (!c->bind_expr_stack.exists ()
351 || c->bind_expr_stack.is_empty ()));
352 c->bind_expr_stack.release ();
353 gimplify_ctxp = c->prev_context;
355 if (body)
356 declare_vars (c->temps, body, false);
357 else
358 record_vars (c->temps);
360 delete c->temp_htab;
361 c->temp_htab = NULL;
362 ctx_free (c);
365 /* Push a GIMPLE_BIND tuple onto the stack of bindings. */
367 static void
368 gimple_push_bind_expr (gbind *bind_stmt)
370 gimplify_ctxp->bind_expr_stack.reserve (8);
371 gimplify_ctxp->bind_expr_stack.safe_push (bind_stmt);
374 /* Pop the first element off the stack of bindings. */
376 static void
377 gimple_pop_bind_expr (void)
379 gimplify_ctxp->bind_expr_stack.pop ();
382 /* Return the first element of the stack of bindings. */
384 gbind *
385 gimple_current_bind_expr (void)
387 return gimplify_ctxp->bind_expr_stack.last ();
390 /* Return the stack of bindings created during gimplification. */
392 vec<gbind *>
393 gimple_bind_expr_stack (void)
395 return gimplify_ctxp->bind_expr_stack;
398 /* Return true iff there is a COND_EXPR between us and the innermost
399 CLEANUP_POINT_EXPR. This info is used by gimple_push_cleanup. */
401 static bool
402 gimple_conditional_context (void)
404 return gimplify_ctxp->conditions > 0;
407 /* Note that we've entered a COND_EXPR. */
409 static void
410 gimple_push_condition (void)
412 #ifdef ENABLE_GIMPLE_CHECKING
413 if (gimplify_ctxp->conditions == 0)
414 gcc_assert (gimple_seq_empty_p (gimplify_ctxp->conditional_cleanups));
415 #endif
416 ++(gimplify_ctxp->conditions);
419 /* Note that we've left a COND_EXPR. If we're back at unconditional scope
420 now, add any conditional cleanups we've seen to the prequeue. */
422 static void
423 gimple_pop_condition (gimple_seq *pre_p)
425 int conds = --(gimplify_ctxp->conditions);
427 gcc_assert (conds >= 0);
428 if (conds == 0)
430 gimplify_seq_add_seq (pre_p, gimplify_ctxp->conditional_cleanups);
431 gimplify_ctxp->conditional_cleanups = NULL;
435 /* A stable comparison routine for use with splay trees and DECLs. */
437 static int
438 splay_tree_compare_decl_uid (splay_tree_key xa, splay_tree_key xb)
440 tree a = (tree) xa;
441 tree b = (tree) xb;
443 return DECL_UID (a) - DECL_UID (b);
446 /* Create a new omp construct that deals with variable remapping. */
448 static struct gimplify_omp_ctx *
449 new_omp_context (enum omp_region_type region_type)
451 struct gimplify_omp_ctx *c;
453 c = XCNEW (struct gimplify_omp_ctx);
454 c->outer_context = gimplify_omp_ctxp;
455 c->variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0);
456 c->privatized_types = new hash_set<tree>;
457 c->location = input_location;
458 c->region_type = region_type;
459 if ((region_type & ORT_TASK) == 0)
460 c->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
461 else
462 c->default_kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
463 c->defaultmap[GDMK_SCALAR] = GOVD_MAP;
464 c->defaultmap[GDMK_SCALAR_TARGET] = GOVD_MAP;
465 c->defaultmap[GDMK_AGGREGATE] = GOVD_MAP;
466 c->defaultmap[GDMK_ALLOCATABLE] = GOVD_MAP;
467 c->defaultmap[GDMK_POINTER] = GOVD_MAP;
469 return c;
472 /* Destroy an omp construct that deals with variable remapping. */
474 static void
475 delete_omp_context (struct gimplify_omp_ctx *c)
477 splay_tree_delete (c->variables);
478 delete c->privatized_types;
479 c->loop_iter_var.release ();
480 XDELETE (c);
483 static void omp_add_variable (struct gimplify_omp_ctx *, tree, unsigned int);
484 static bool omp_notice_variable (struct gimplify_omp_ctx *, tree, bool);
486 /* Both gimplify the statement T and append it to *SEQ_P. This function
487 behaves exactly as gimplify_stmt, but you don't have to pass T as a
488 reference. */
490 void
491 gimplify_and_add (tree t, gimple_seq *seq_p)
493 gimplify_stmt (&t, seq_p);
496 /* Gimplify statement T into sequence *SEQ_P, and return the first
497 tuple in the sequence of generated tuples for this statement.
498 Return NULL if gimplifying T produced no tuples. */
500 static gimple *
501 gimplify_and_return_first (tree t, gimple_seq *seq_p)
503 gimple_stmt_iterator last = gsi_last (*seq_p);
505 gimplify_and_add (t, seq_p);
507 if (!gsi_end_p (last))
509 gsi_next (&last);
510 return gsi_stmt (last);
512 else
513 return gimple_seq_first_stmt (*seq_p);
516 /* Returns true iff T is a valid RHS for an assignment to an un-renamed
517 LHS, or for a call argument. */
519 static bool
520 is_gimple_mem_rhs (tree t)
522 /* If we're dealing with a renamable type, either source or dest must be
523 a renamed variable. */
524 if (is_gimple_reg_type (TREE_TYPE (t)))
525 return is_gimple_val (t);
526 else
527 return is_gimple_val (t) || is_gimple_lvalue (t);
530 /* Return true if T is a CALL_EXPR or an expression that can be
531 assigned to a temporary. Note that this predicate should only be
532 used during gimplification. See the rationale for this in
533 gimplify_modify_expr. */
535 static bool
536 is_gimple_reg_rhs_or_call (tree t)
538 return (get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS
539 || TREE_CODE (t) == CALL_EXPR);
542 /* Return true if T is a valid memory RHS or a CALL_EXPR. Note that
543 this predicate should only be used during gimplification. See the
544 rationale for this in gimplify_modify_expr. */
546 static bool
547 is_gimple_mem_rhs_or_call (tree t)
549 /* If we're dealing with a renamable type, either source or dest must be
550 a renamed variable. */
551 if (is_gimple_reg_type (TREE_TYPE (t)))
552 return is_gimple_val (t);
553 else
554 return (is_gimple_val (t)
555 || is_gimple_lvalue (t)
556 || TREE_CLOBBER_P (t)
557 || TREE_CODE (t) == CALL_EXPR);
560 /* Create a temporary with a name derived from VAL. Subroutine of
561 lookup_tmp_var; nobody else should call this function. */
563 static inline tree
564 create_tmp_from_val (tree val)
566 /* Drop all qualifiers and address-space information from the value type. */
567 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (val));
568 tree var = create_tmp_var (type, get_name (val));
569 return var;
572 /* Create a temporary to hold the value of VAL. If IS_FORMAL, try to reuse
573 an existing expression temporary. If NOT_GIMPLE_REG, mark it as such. */
575 static tree
576 lookup_tmp_var (tree val, bool is_formal, bool not_gimple_reg)
578 tree ret;
580 /* We cannot mark a formal temporary with DECL_NOT_GIMPLE_REG_P. */
581 gcc_assert (!is_formal || !not_gimple_reg);
583 /* If not optimizing, never really reuse a temporary. local-alloc
584 won't allocate any variable that is used in more than one basic
585 block, which means it will go into memory, causing much extra
586 work in reload and final and poorer code generation, outweighing
587 the extra memory allocation here. */
588 if (!optimize || !is_formal || TREE_SIDE_EFFECTS (val))
590 ret = create_tmp_from_val (val);
591 DECL_NOT_GIMPLE_REG_P (ret) = not_gimple_reg;
593 else
595 elt_t elt, *elt_p;
596 elt_t **slot;
598 elt.val = val;
599 if (!gimplify_ctxp->temp_htab)
600 gimplify_ctxp->temp_htab = new hash_table<gimplify_hasher> (1000);
601 slot = gimplify_ctxp->temp_htab->find_slot (&elt, INSERT);
602 if (*slot == NULL)
604 elt_p = XNEW (elt_t);
605 elt_p->val = val;
606 elt_p->temp = ret = create_tmp_from_val (val);
607 *slot = elt_p;
609 else
611 elt_p = *slot;
612 ret = elt_p->temp;
616 return ret;
619 /* Helper for get_formal_tmp_var and get_initialized_tmp_var. */
621 static tree
622 internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
623 bool is_formal, bool allow_ssa, bool not_gimple_reg)
625 tree t, mod;
627 /* Notice that we explicitly allow VAL to be a CALL_EXPR so that we
628 can create an INIT_EXPR and convert it into a GIMPLE_CALL below. */
629 gimplify_expr (&val, pre_p, post_p, is_gimple_reg_rhs_or_call,
630 fb_rvalue);
632 if (allow_ssa
633 && gimplify_ctxp->into_ssa
634 && is_gimple_reg_type (TREE_TYPE (val)))
636 t = make_ssa_name (TYPE_MAIN_VARIANT (TREE_TYPE (val)));
637 if (! gimple_in_ssa_p (cfun))
639 const char *name = get_name (val);
640 if (name)
641 SET_SSA_NAME_VAR_OR_IDENTIFIER (t, create_tmp_var_name (name));
644 else
645 t = lookup_tmp_var (val, is_formal, not_gimple_reg);
647 mod = build2 (INIT_EXPR, TREE_TYPE (t), t, unshare_expr (val));
649 SET_EXPR_LOCATION (mod, EXPR_LOC_OR_LOC (val, input_location));
651 /* gimplify_modify_expr might want to reduce this further. */
652 gimplify_and_add (mod, pre_p);
653 ggc_free (mod);
655 return t;
658 /* Return a formal temporary variable initialized with VAL. PRE_P is as
659 in gimplify_expr. Only use this function if:
661 1) The value of the unfactored expression represented by VAL will not
662 change between the initialization and use of the temporary, and
663 2) The temporary will not be otherwise modified.
665 For instance, #1 means that this is inappropriate for SAVE_EXPR temps,
666 and #2 means it is inappropriate for && temps.
668 For other cases, use get_initialized_tmp_var instead. */
670 tree
671 get_formal_tmp_var (tree val, gimple_seq *pre_p)
673 return internal_get_tmp_var (val, pre_p, NULL, true, true, false);
676 /* Return a temporary variable initialized with VAL. PRE_P and POST_P
677 are as in gimplify_expr. */
679 tree
680 get_initialized_tmp_var (tree val, gimple_seq *pre_p,
681 gimple_seq *post_p /* = NULL */,
682 bool allow_ssa /* = true */)
684 return internal_get_tmp_var (val, pre_p, post_p, false, allow_ssa, false);
687 /* Declare all the variables in VARS in SCOPE. If DEBUG_INFO is true,
688 generate debug info for them; otherwise don't. */
690 void
691 declare_vars (tree vars, gimple *gs, bool debug_info)
693 tree last = vars;
694 if (last)
696 tree temps, block;
698 gbind *scope = as_a <gbind *> (gs);
700 temps = nreverse (last);
702 block = gimple_bind_block (scope);
703 gcc_assert (!block || TREE_CODE (block) == BLOCK);
704 if (!block || !debug_info)
706 DECL_CHAIN (last) = gimple_bind_vars (scope);
707 gimple_bind_set_vars (scope, temps);
709 else
711 /* We need to attach the nodes both to the BIND_EXPR and to its
712 associated BLOCK for debugging purposes. The key point here
713 is that the BLOCK_VARS of the BIND_EXPR_BLOCK of a BIND_EXPR
714 is a subchain of the BIND_EXPR_VARS of the BIND_EXPR. */
715 if (BLOCK_VARS (block))
716 BLOCK_VARS (block) = chainon (BLOCK_VARS (block), temps);
717 else
719 gimple_bind_set_vars (scope,
720 chainon (gimple_bind_vars (scope), temps));
721 BLOCK_VARS (block) = temps;
727 /* For VAR a VAR_DECL of variable size, try to find a constant upper bound
728 for the size and adjust DECL_SIZE/DECL_SIZE_UNIT accordingly. Abort if
729 no such upper bound can be obtained. */
731 static void
732 force_constant_size (tree var)
734 /* The only attempt we make is by querying the maximum size of objects
735 of the variable's type. */
737 HOST_WIDE_INT max_size;
739 gcc_assert (VAR_P (var));
741 max_size = max_int_size_in_bytes (TREE_TYPE (var));
743 gcc_assert (max_size >= 0);
745 DECL_SIZE_UNIT (var)
746 = build_int_cst (TREE_TYPE (DECL_SIZE_UNIT (var)), max_size);
747 DECL_SIZE (var)
748 = build_int_cst (TREE_TYPE (DECL_SIZE (var)), max_size * BITS_PER_UNIT);
751 /* Push the temporary variable TMP into the current binding. */
753 void
754 gimple_add_tmp_var_fn (struct function *fn, tree tmp)
756 gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
758 /* Later processing assumes that the object size is constant, which might
759 not be true at this point. Force the use of a constant upper bound in
760 this case. */
761 if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp)))
762 force_constant_size (tmp);
764 DECL_CONTEXT (tmp) = fn->decl;
765 DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
767 record_vars_into (tmp, fn->decl);
770 /* Push the temporary variable TMP into the current binding. */
772 void
773 gimple_add_tmp_var (tree tmp)
775 gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
777 /* Later processing assumes that the object size is constant, which might
778 not be true at this point. Force the use of a constant upper bound in
779 this case. */
780 if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp)))
781 force_constant_size (tmp);
783 DECL_CONTEXT (tmp) = current_function_decl;
784 DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
786 if (gimplify_ctxp)
788 DECL_CHAIN (tmp) = gimplify_ctxp->temps;
789 gimplify_ctxp->temps = tmp;
791 /* Mark temporaries local within the nearest enclosing parallel. */
792 if (gimplify_omp_ctxp)
794 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
795 int flag = GOVD_LOCAL | GOVD_SEEN;
796 while (ctx
797 && (ctx->region_type == ORT_WORKSHARE
798 || ctx->region_type == ORT_TASKGROUP
799 || ctx->region_type == ORT_SIMD
800 || ctx->region_type == ORT_ACC))
802 if (ctx->region_type == ORT_SIMD
803 && TREE_ADDRESSABLE (tmp)
804 && !TREE_STATIC (tmp))
806 if (TREE_CODE (DECL_SIZE_UNIT (tmp)) != INTEGER_CST)
807 ctx->add_safelen1 = true;
808 else if (ctx->in_for_exprs)
809 flag = GOVD_PRIVATE;
810 else
811 flag = GOVD_PRIVATE | GOVD_SEEN;
812 break;
814 ctx = ctx->outer_context;
816 if (ctx)
817 omp_add_variable (ctx, tmp, flag);
820 else if (cfun)
821 record_vars (tmp);
822 else
824 gimple_seq body_seq;
826 /* This case is for nested functions. We need to expose the locals
827 they create. */
828 body_seq = gimple_body (current_function_decl);
829 declare_vars (tmp, gimple_seq_first_stmt (body_seq), false);
835 /* This page contains routines to unshare tree nodes, i.e. to duplicate tree
836 nodes that are referenced more than once in GENERIC functions. This is
837 necessary because gimplification (translation into GIMPLE) is performed
838 by modifying tree nodes in-place, so gimplication of a shared node in a
839 first context could generate an invalid GIMPLE form in a second context.
841 This is achieved with a simple mark/copy/unmark algorithm that walks the
842 GENERIC representation top-down, marks nodes with TREE_VISITED the first
843 time it encounters them, duplicates them if they already have TREE_VISITED
844 set, and finally removes the TREE_VISITED marks it has set.
846 The algorithm works only at the function level, i.e. it generates a GENERIC
847 representation of a function with no nodes shared within the function when
848 passed a GENERIC function (except for nodes that are allowed to be shared).
850 At the global level, it is also necessary to unshare tree nodes that are
851 referenced in more than one function, for the same aforementioned reason.
852 This requires some cooperation from the front-end. There are 2 strategies:
854 1. Manual unsharing. The front-end needs to call unshare_expr on every
855 expression that might end up being shared across functions.
857 2. Deep unsharing. This is an extension of regular unsharing. Instead
858 of calling unshare_expr on expressions that might be shared across
859 functions, the front-end pre-marks them with TREE_VISITED. This will
860 ensure that they are unshared on the first reference within functions
861 when the regular unsharing algorithm runs. The counterpart is that
862 this algorithm must look deeper than for manual unsharing, which is
863 specified by LANG_HOOKS_DEEP_UNSHARING.
865 If there are only few specific cases of node sharing across functions, it is
866 probably easier for a front-end to unshare the expressions manually. On the
867 contrary, if the expressions generated at the global level are as widespread
868 as expressions generated within functions, deep unsharing is very likely the
869 way to go. */
871 /* Similar to copy_tree_r but do not copy SAVE_EXPR or TARGET_EXPR nodes.
872 These nodes model computations that must be done once. If we were to
873 unshare something like SAVE_EXPR(i++), the gimplification process would
874 create wrong code. However, if DATA is non-null, it must hold a pointer
875 set that is used to unshare the subtrees of these nodes. */
877 static tree
878 mostly_copy_tree_r (tree *tp, int *walk_subtrees, void *data)
880 tree t = *tp;
881 enum tree_code code = TREE_CODE (t);
883 /* Do not copy SAVE_EXPR, TARGET_EXPR or BIND_EXPR nodes themselves, but
884 copy their subtrees if we can make sure to do it only once. */
885 if (code == SAVE_EXPR || code == TARGET_EXPR || code == BIND_EXPR)
887 if (data && !((hash_set<tree> *)data)->add (t))
889 else
890 *walk_subtrees = 0;
893 /* Stop at types, decls, constants like copy_tree_r. */
894 else if (TREE_CODE_CLASS (code) == tcc_type
895 || TREE_CODE_CLASS (code) == tcc_declaration
896 || TREE_CODE_CLASS (code) == tcc_constant)
897 *walk_subtrees = 0;
899 /* Cope with the statement expression extension. */
900 else if (code == STATEMENT_LIST)
903 /* Leave the bulk of the work to copy_tree_r itself. */
904 else
905 copy_tree_r (tp, walk_subtrees, NULL);
907 return NULL_TREE;
910 /* Callback for walk_tree to unshare most of the shared trees rooted at *TP.
911 If *TP has been visited already, then *TP is deeply copied by calling
912 mostly_copy_tree_r. DATA is passed to mostly_copy_tree_r unmodified. */
914 static tree
915 copy_if_shared_r (tree *tp, int *walk_subtrees, void *data)
917 tree t = *tp;
918 enum tree_code code = TREE_CODE (t);
920 /* Skip types, decls, and constants. But we do want to look at their
921 types and the bounds of types. Mark them as visited so we properly
922 unmark their subtrees on the unmark pass. If we've already seen them,
923 don't look down further. */
924 if (TREE_CODE_CLASS (code) == tcc_type
925 || TREE_CODE_CLASS (code) == tcc_declaration
926 || TREE_CODE_CLASS (code) == tcc_constant)
928 if (TREE_VISITED (t))
929 *walk_subtrees = 0;
930 else
931 TREE_VISITED (t) = 1;
934 /* If this node has been visited already, unshare it and don't look
935 any deeper. */
936 else if (TREE_VISITED (t))
938 walk_tree (tp, mostly_copy_tree_r, data, NULL);
939 *walk_subtrees = 0;
942 /* Otherwise, mark the node as visited and keep looking. */
943 else
944 TREE_VISITED (t) = 1;
946 return NULL_TREE;
949 /* Unshare most of the shared trees rooted at *TP. DATA is passed to the
950 copy_if_shared_r callback unmodified. */
952 void
953 copy_if_shared (tree *tp, void *data)
955 walk_tree (tp, copy_if_shared_r, data, NULL);
958 /* Unshare all the trees in the body of FNDECL, as well as in the bodies of
959 any nested functions. */
961 static void
962 unshare_body (tree fndecl)
964 struct cgraph_node *cgn = cgraph_node::get (fndecl);
965 /* If the language requires deep unsharing, we need a pointer set to make
966 sure we don't repeatedly unshare subtrees of unshareable nodes. */
967 hash_set<tree> *visited
968 = lang_hooks.deep_unsharing ? new hash_set<tree> : NULL;
970 copy_if_shared (&DECL_SAVED_TREE (fndecl), visited);
971 copy_if_shared (&DECL_SIZE (DECL_RESULT (fndecl)), visited);
972 copy_if_shared (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)), visited);
974 delete visited;
976 if (cgn)
977 for (cgn = first_nested_function (cgn); cgn;
978 cgn = next_nested_function (cgn))
979 unshare_body (cgn->decl);
982 /* Callback for walk_tree to unmark the visited trees rooted at *TP.
983 Subtrees are walked until the first unvisited node is encountered. */
985 static tree
986 unmark_visited_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
988 tree t = *tp;
990 /* If this node has been visited, unmark it and keep looking. */
991 if (TREE_VISITED (t))
992 TREE_VISITED (t) = 0;
994 /* Otherwise, don't look any deeper. */
995 else
996 *walk_subtrees = 0;
998 return NULL_TREE;
1001 /* Unmark the visited trees rooted at *TP. */
1003 static inline void
1004 unmark_visited (tree *tp)
1006 walk_tree (tp, unmark_visited_r, NULL, NULL);
1009 /* Likewise, but mark all trees as not visited. */
1011 static void
1012 unvisit_body (tree fndecl)
1014 struct cgraph_node *cgn = cgraph_node::get (fndecl);
1016 unmark_visited (&DECL_SAVED_TREE (fndecl));
1017 unmark_visited (&DECL_SIZE (DECL_RESULT (fndecl)));
1018 unmark_visited (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)));
1020 if (cgn)
1021 for (cgn = first_nested_function (cgn);
1022 cgn; cgn = next_nested_function (cgn))
1023 unvisit_body (cgn->decl);
1026 /* Unconditionally make an unshared copy of EXPR. This is used when using
1027 stored expressions which span multiple functions, such as BINFO_VTABLE,
1028 as the normal unsharing process can't tell that they're shared. */
1030 tree
1031 unshare_expr (tree expr)
1033 walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
1034 return expr;
1037 /* Worker for unshare_expr_without_location. */
1039 static tree
1040 prune_expr_location (tree *tp, int *walk_subtrees, void *)
1042 if (EXPR_P (*tp))
1043 SET_EXPR_LOCATION (*tp, UNKNOWN_LOCATION);
1044 else
1045 *walk_subtrees = 0;
1046 return NULL_TREE;
1049 /* Similar to unshare_expr but also prune all expression locations
1050 from EXPR. */
1052 tree
1053 unshare_expr_without_location (tree expr)
1055 walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
1056 if (EXPR_P (expr))
1057 walk_tree (&expr, prune_expr_location, NULL, NULL);
1058 return expr;
1061 /* Return the EXPR_LOCATION of EXPR, if it (maybe recursively) has
1062 one, OR_ELSE otherwise. The location of a STATEMENT_LISTs
1063 comprising at least one DEBUG_BEGIN_STMT followed by exactly one
1064 EXPR is the location of the EXPR. */
1066 static location_t
1067 rexpr_location (tree expr, location_t or_else = UNKNOWN_LOCATION)
1069 if (!expr)
1070 return or_else;
1072 if (EXPR_HAS_LOCATION (expr))
1073 return EXPR_LOCATION (expr);
1075 if (TREE_CODE (expr) != STATEMENT_LIST)
1076 return or_else;
1078 tree_stmt_iterator i = tsi_start (expr);
1080 bool found = false;
1081 while (!tsi_end_p (i) && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT)
1083 found = true;
1084 tsi_next (&i);
1087 if (!found || !tsi_one_before_end_p (i))
1088 return or_else;
1090 return rexpr_location (tsi_stmt (i), or_else);
1093 /* Return TRUE iff EXPR (maybe recursively) has a location; see
1094 rexpr_location for the potential recursion. */
1096 static inline bool
1097 rexpr_has_location (tree expr)
1099 return rexpr_location (expr) != UNKNOWN_LOCATION;
1103 /* WRAPPER is a code such as BIND_EXPR or CLEANUP_POINT_EXPR which can both
1104 contain statements and have a value. Assign its value to a temporary
1105 and give it void_type_node. Return the temporary, or NULL_TREE if
1106 WRAPPER was already void. */
1108 tree
1109 voidify_wrapper_expr (tree wrapper, tree temp)
1111 tree type = TREE_TYPE (wrapper);
1112 if (type && !VOID_TYPE_P (type))
1114 tree *p;
1116 /* Set p to point to the body of the wrapper. Loop until we find
1117 something that isn't a wrapper. */
1118 for (p = &wrapper; p && *p; )
1120 switch (TREE_CODE (*p))
1122 case BIND_EXPR:
1123 TREE_SIDE_EFFECTS (*p) = 1;
1124 TREE_TYPE (*p) = void_type_node;
1125 /* For a BIND_EXPR, the body is operand 1. */
1126 p = &BIND_EXPR_BODY (*p);
1127 break;
1129 case CLEANUP_POINT_EXPR:
1130 case TRY_FINALLY_EXPR:
1131 case TRY_CATCH_EXPR:
1132 TREE_SIDE_EFFECTS (*p) = 1;
1133 TREE_TYPE (*p) = void_type_node;
1134 p = &TREE_OPERAND (*p, 0);
1135 break;
1137 case STATEMENT_LIST:
1139 tree_stmt_iterator i = tsi_last (*p);
1140 TREE_SIDE_EFFECTS (*p) = 1;
1141 TREE_TYPE (*p) = void_type_node;
1142 p = tsi_end_p (i) ? NULL : tsi_stmt_ptr (i);
1144 break;
1146 case COMPOUND_EXPR:
1147 /* Advance to the last statement. Set all container types to
1148 void. */
1149 for (; TREE_CODE (*p) == COMPOUND_EXPR; p = &TREE_OPERAND (*p, 1))
1151 TREE_SIDE_EFFECTS (*p) = 1;
1152 TREE_TYPE (*p) = void_type_node;
1154 break;
1156 case TRANSACTION_EXPR:
1157 TREE_SIDE_EFFECTS (*p) = 1;
1158 TREE_TYPE (*p) = void_type_node;
1159 p = &TRANSACTION_EXPR_BODY (*p);
1160 break;
1162 default:
1163 /* Assume that any tree upon which voidify_wrapper_expr is
1164 directly called is a wrapper, and that its body is op0. */
1165 if (p == &wrapper)
1167 TREE_SIDE_EFFECTS (*p) = 1;
1168 TREE_TYPE (*p) = void_type_node;
1169 p = &TREE_OPERAND (*p, 0);
1170 break;
1172 goto out;
1176 out:
1177 if (p == NULL || IS_EMPTY_STMT (*p))
1178 temp = NULL_TREE;
1179 else if (temp)
1181 /* The wrapper is on the RHS of an assignment that we're pushing
1182 down. */
1183 gcc_assert (TREE_CODE (temp) == INIT_EXPR
1184 || TREE_CODE (temp) == MODIFY_EXPR);
1185 TREE_OPERAND (temp, 1) = *p;
1186 *p = temp;
1188 else
1190 temp = create_tmp_var (type, "retval");
1191 *p = build2 (INIT_EXPR, type, temp, *p);
1194 return temp;
1197 return NULL_TREE;
1200 /* Prepare calls to builtins to SAVE and RESTORE the stack as well as
1201 a temporary through which they communicate. */
1203 static void
1204 build_stack_save_restore (gcall **save, gcall **restore)
1206 tree tmp_var;
1208 *save = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_SAVE), 0);
1209 tmp_var = create_tmp_var (ptr_type_node, "saved_stack");
1210 gimple_call_set_lhs (*save, tmp_var);
1212 *restore
1213 = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_RESTORE),
1214 1, tmp_var);
1217 /* Generate IFN_ASAN_MARK call that poisons shadow of a for DECL variable. */
1219 static tree
1220 build_asan_poison_call_expr (tree decl)
1222 /* Do not poison variables that have size equal to zero. */
1223 tree unit_size = DECL_SIZE_UNIT (decl);
1224 if (zerop (unit_size))
1225 return NULL_TREE;
1227 tree base = build_fold_addr_expr (decl);
1229 return build_call_expr_internal_loc (UNKNOWN_LOCATION, IFN_ASAN_MARK,
1230 void_type_node, 3,
1231 build_int_cst (integer_type_node,
1232 ASAN_MARK_POISON),
1233 base, unit_size);
1236 /* Generate IFN_ASAN_MARK call that would poison or unpoison, depending
1237 on POISON flag, shadow memory of a DECL variable. The call will be
1238 put on location identified by IT iterator, where BEFORE flag drives
1239 position where the stmt will be put. */
1241 static void
1242 asan_poison_variable (tree decl, bool poison, gimple_stmt_iterator *it,
1243 bool before)
1245 tree unit_size = DECL_SIZE_UNIT (decl);
1246 tree base = build_fold_addr_expr (decl);
1248 /* Do not poison variables that have size equal to zero. */
1249 if (zerop (unit_size))
1250 return;
1252 /* It's necessary to have all stack variables aligned to ASAN granularity
1253 bytes. */
1254 gcc_assert (!hwasan_sanitize_p () || hwasan_sanitize_stack_p ());
1255 unsigned shadow_granularity
1256 = hwasan_sanitize_p () ? HWASAN_TAG_GRANULE_SIZE : ASAN_SHADOW_GRANULARITY;
1257 if (DECL_ALIGN_UNIT (decl) <= shadow_granularity)
1258 SET_DECL_ALIGN (decl, BITS_PER_UNIT * shadow_granularity);
1260 HOST_WIDE_INT flags = poison ? ASAN_MARK_POISON : ASAN_MARK_UNPOISON;
1262 gimple *g
1263 = gimple_build_call_internal (IFN_ASAN_MARK, 3,
1264 build_int_cst (integer_type_node, flags),
1265 base, unit_size);
1267 if (before)
1268 gsi_insert_before (it, g, GSI_NEW_STMT);
1269 else
1270 gsi_insert_after (it, g, GSI_NEW_STMT);
1273 /* Generate IFN_ASAN_MARK internal call that depending on POISON flag
1274 either poisons or unpoisons a DECL. Created statement is appended
1275 to SEQ_P gimple sequence. */
1277 static void
1278 asan_poison_variable (tree decl, bool poison, gimple_seq *seq_p)
1280 gimple_stmt_iterator it = gsi_last (*seq_p);
1281 bool before = false;
1283 if (gsi_end_p (it))
1284 before = true;
1286 asan_poison_variable (decl, poison, &it, before);
1289 /* Sort pair of VAR_DECLs A and B by DECL_UID. */
1291 static int
1292 sort_by_decl_uid (const void *a, const void *b)
1294 const tree *t1 = (const tree *)a;
1295 const tree *t2 = (const tree *)b;
1297 int uid1 = DECL_UID (*t1);
1298 int uid2 = DECL_UID (*t2);
1300 if (uid1 < uid2)
1301 return -1;
1302 else if (uid1 > uid2)
1303 return 1;
1304 else
1305 return 0;
1308 /* Generate IFN_ASAN_MARK internal call for all VARIABLES
1309 depending on POISON flag. Created statement is appended
1310 to SEQ_P gimple sequence. */
1312 static void
1313 asan_poison_variables (hash_set<tree> *variables, bool poison, gimple_seq *seq_p)
1315 unsigned c = variables->elements ();
1316 if (c == 0)
1317 return;
1319 auto_vec<tree> sorted_variables (c);
1321 for (hash_set<tree>::iterator it = variables->begin ();
1322 it != variables->end (); ++it)
1323 sorted_variables.safe_push (*it);
1325 sorted_variables.qsort (sort_by_decl_uid);
1327 unsigned i;
1328 tree var;
1329 FOR_EACH_VEC_ELT (sorted_variables, i, var)
1331 asan_poison_variable (var, poison, seq_p);
1333 /* Add use_after_scope_memory attribute for the variable in order
1334 to prevent re-written into SSA. */
1335 if (!lookup_attribute (ASAN_USE_AFTER_SCOPE_ATTRIBUTE,
1336 DECL_ATTRIBUTES (var)))
1337 DECL_ATTRIBUTES (var)
1338 = tree_cons (get_identifier (ASAN_USE_AFTER_SCOPE_ATTRIBUTE),
1339 integer_one_node,
1340 DECL_ATTRIBUTES (var));
1344 /* Gimplify a BIND_EXPR. Just voidify and recurse. */
1346 static enum gimplify_status
1347 gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p)
1349 tree bind_expr = *expr_p;
1350 bool old_keep_stack = gimplify_ctxp->keep_stack;
1351 bool old_save_stack = gimplify_ctxp->save_stack;
1352 tree t;
1353 gbind *bind_stmt;
1354 gimple_seq body, cleanup;
1355 gcall *stack_save;
1356 location_t start_locus = 0, end_locus = 0;
1357 tree ret_clauses = NULL;
1359 tree temp = voidify_wrapper_expr (bind_expr, NULL);
1361 /* Mark variables seen in this bind expr. */
1362 for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t))
1364 if (VAR_P (t))
1366 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
1367 tree attr;
1369 if (flag_openmp
1370 && !is_global_var (t)
1371 && DECL_CONTEXT (t) == current_function_decl
1372 && TREE_USED (t)
1373 && (attr = lookup_attribute ("omp allocate", DECL_ATTRIBUTES (t)))
1374 != NULL_TREE)
1376 gcc_assert (!DECL_HAS_VALUE_EXPR_P (t));
1377 tree alloc = TREE_PURPOSE (TREE_VALUE (attr));
1378 tree align = TREE_VALUE (TREE_VALUE (attr));
1379 /* Allocate directives that appear in a target region must specify
1380 an allocator clause unless a requires directive with the
1381 dynamic_allocators clause is present in the same compilation
1382 unit. */
1383 bool missing_dyn_alloc = false;
1384 if (alloc == NULL_TREE
1385 && ((omp_requires_mask & OMP_REQUIRES_DYNAMIC_ALLOCATORS)
1386 == 0))
1388 /* This comes too early for omp_discover_declare_target...,
1389 but should at least catch the most common cases. */
1390 missing_dyn_alloc
1391 = cgraph_node::get (current_function_decl)->offloadable;
1392 for (struct gimplify_omp_ctx *ctx2 = ctx;
1393 ctx2 && !missing_dyn_alloc; ctx2 = ctx2->outer_context)
1394 if (ctx2->code == OMP_TARGET)
1395 missing_dyn_alloc = true;
1397 if (missing_dyn_alloc)
1398 error_at (DECL_SOURCE_LOCATION (t),
1399 "%<allocate%> directive for %qD inside a target "
1400 "region must specify an %<allocator%> clause", t);
1401 /* Skip for omp_default_mem_alloc (= 1),
1402 unless align is present. */
1403 else if (!errorcount
1404 && (align != NULL_TREE
1405 || alloc == NULL_TREE
1406 || !integer_onep (alloc)))
1408 /* Fortran might already use a pointer type internally;
1409 use that pointer except for type(C_ptr) and type(C_funptr);
1410 note that normal proc pointers are rejected. */
1411 tree type = TREE_TYPE (t);
1412 tree tmp, v;
1413 if (lang_GNU_Fortran ()
1414 && POINTER_TYPE_P (type)
1415 && TREE_TYPE (type) != void_type_node
1416 && TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE)
1418 type = TREE_TYPE (type);
1419 v = t;
1421 else
1423 tmp = build_pointer_type (type);
1424 v = create_tmp_var (tmp, get_name (t));
1425 DECL_IGNORED_P (v) = 0;
1426 DECL_ATTRIBUTES (v)
1427 = tree_cons (get_identifier ("omp allocate var"),
1428 build_tree_list (NULL_TREE, t),
1429 remove_attribute ("omp allocate",
1430 DECL_ATTRIBUTES (t)));
1431 tmp = build_fold_indirect_ref (v);
1432 TREE_THIS_NOTRAP (tmp) = 1;
1433 SET_DECL_VALUE_EXPR (t, tmp);
1434 DECL_HAS_VALUE_EXPR_P (t) = 1;
1436 tree sz = TYPE_SIZE_UNIT (type);
1437 /* The size to use in Fortran might not match TYPE_SIZE_UNIT;
1438 hence, for some decls, a size variable is saved in the
1439 attributes; use it, if available. */
1440 if (TREE_CHAIN (TREE_VALUE (attr))
1441 && TREE_CHAIN (TREE_CHAIN (TREE_VALUE (attr)))
1442 && TREE_PURPOSE (
1443 TREE_CHAIN (TREE_CHAIN (TREE_VALUE (attr)))))
1445 sz = TREE_CHAIN (TREE_CHAIN (TREE_VALUE (attr)));
1446 sz = TREE_PURPOSE (sz);
1448 if (alloc == NULL_TREE)
1449 alloc = build_zero_cst (ptr_type_node);
1450 if (align == NULL_TREE)
1451 align = build_int_cst (size_type_node, DECL_ALIGN_UNIT (t));
1452 else
1453 align = build_int_cst (size_type_node,
1454 MAX (tree_to_uhwi (align),
1455 DECL_ALIGN_UNIT (t)));
1456 location_t loc = DECL_SOURCE_LOCATION (t);
1457 tmp = builtin_decl_explicit (BUILT_IN_GOMP_ALLOC);
1458 tmp = build_call_expr_loc (loc, tmp, 3, align, sz, alloc);
1459 tmp = fold_build2_loc (loc, MODIFY_EXPR, TREE_TYPE (v), v,
1460 fold_convert (TREE_TYPE (v), tmp));
1461 gcc_assert (BIND_EXPR_BODY (bind_expr) != NULL_TREE);
1462 /* Ensure that either TREE_CHAIN (TREE_VALUE (attr) is set
1463 and GOMP_FREE added here or that DECL_HAS_VALUE_EXPR_P (t)
1464 is set, using in a condition much further below. */
1465 gcc_assert (DECL_HAS_VALUE_EXPR_P (t)
1466 || TREE_CHAIN (TREE_VALUE (attr)));
1467 if (TREE_CHAIN (TREE_VALUE (attr)))
1469 /* Fortran is special as it does not have properly nest
1470 declarations in blocks. And as there is no
1471 initializer, there is also no expression to look for.
1472 Hence, the FE makes the statement list of the
1473 try-finally block available. We can put the GOMP_alloc
1474 at the top, unless an allocator or size expression
1475 requires to put it afterward; note that the size is
1476 always later in generated code; for strings, no
1477 size expr but still an expr might be available.
1478 As LTO does not handle a statement list, 'sl' has
1479 to be removed; done so by removing the attribute. */
1480 DECL_ATTRIBUTES (t)
1481 = remove_attribute ("omp allocate",
1482 DECL_ATTRIBUTES (t));
1483 tree sl = TREE_PURPOSE (TREE_CHAIN (TREE_VALUE (attr)));
1484 tree_stmt_iterator e = tsi_start (sl);
1485 tree needle = NULL_TREE;
1486 if (TREE_CHAIN (TREE_CHAIN (TREE_VALUE (attr))))
1488 needle = TREE_CHAIN (TREE_CHAIN (TREE_VALUE (attr)));
1489 needle = (TREE_VALUE (needle) ? TREE_VALUE (needle)
1490 : sz);
1492 else if (TREE_CHAIN (TREE_CHAIN (TREE_VALUE (attr))))
1493 needle = sz;
1494 else if (DECL_P (alloc) && DECL_ARTIFICIAL (alloc))
1495 needle = alloc;
1497 if (needle != NULL_TREE)
1499 while (!tsi_end_p (e))
1501 if (*e == needle
1502 || (TREE_CODE (*e) == MODIFY_EXPR
1503 && TREE_OPERAND (*e, 0) == needle))
1504 break;
1505 ++e;
1507 gcc_assert (!tsi_end_p (e));
1509 tsi_link_after (&e, tmp, TSI_SAME_STMT);
1511 /* As the cleanup is in BIND_EXPR_BODY, GOMP_free is added
1512 here; for C/C++ it will be added in the 'cleanup'
1513 section after gimplification. But Fortran already has
1514 a try-finally block. */
1515 sl = TREE_VALUE (TREE_CHAIN (TREE_VALUE (attr)));
1516 e = tsi_last (sl);
1517 tmp = builtin_decl_explicit (BUILT_IN_GOMP_FREE);
1518 tmp = build_call_expr_loc (EXPR_LOCATION (*e), tmp, 2, v,
1519 build_zero_cst (ptr_type_node));
1520 tsi_link_after (&e, tmp, TSI_SAME_STMT);
1521 tmp = build_clobber (TREE_TYPE (v), CLOBBER_STORAGE_END);
1522 tmp = fold_build2_loc (loc, MODIFY_EXPR, TREE_TYPE (v), v,
1523 fold_convert (TREE_TYPE (v), tmp));
1524 ++e;
1525 tsi_link_after (&e, tmp, TSI_SAME_STMT);
1527 else
1529 gcc_assert (TREE_CODE (BIND_EXPR_BODY (bind_expr))
1530 == STATEMENT_LIST);
1531 tree_stmt_iterator e;
1532 e = tsi_start (BIND_EXPR_BODY (bind_expr));
1533 while (!tsi_end_p (e))
1535 if ((TREE_CODE (*e) == DECL_EXPR
1536 && TREE_OPERAND (*e, 0) == t)
1537 || (TREE_CODE (*e) == CLEANUP_POINT_EXPR
1538 && (TREE_CODE (TREE_OPERAND (*e, 0))
1539 == DECL_EXPR)
1540 && (TREE_OPERAND (TREE_OPERAND (*e, 0), 0)
1541 == t)))
1542 break;
1543 ++e;
1545 gcc_assert (!tsi_end_p (e));
1546 tsi_link_before (&e, tmp, TSI_SAME_STMT);
1551 /* Mark variable as local. */
1552 if (ctx && ctx->region_type != ORT_NONE && !DECL_EXTERNAL (t))
1554 if (! DECL_SEEN_IN_BIND_EXPR_P (t)
1555 || splay_tree_lookup (ctx->variables,
1556 (splay_tree_key) t) == NULL)
1558 int flag = GOVD_LOCAL;
1559 if (ctx->region_type == ORT_SIMD
1560 && TREE_ADDRESSABLE (t)
1561 && !TREE_STATIC (t))
1563 if (TREE_CODE (DECL_SIZE_UNIT (t)) != INTEGER_CST)
1564 ctx->add_safelen1 = true;
1565 else
1566 flag = GOVD_PRIVATE;
1568 omp_add_variable (ctx, t, flag | GOVD_SEEN);
1570 /* Static locals inside of target construct or offloaded
1571 routines need to be "omp declare target". */
1572 if (TREE_STATIC (t))
1573 for (; ctx; ctx = ctx->outer_context)
1574 if ((ctx->region_type & ORT_TARGET) != 0)
1576 if (!lookup_attribute ("omp declare target",
1577 DECL_ATTRIBUTES (t)))
1579 tree id = get_identifier ("omp declare target");
1580 DECL_ATTRIBUTES (t)
1581 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
1582 varpool_node *node = varpool_node::get (t);
1583 if (node)
1585 node->offloadable = 1;
1586 if (ENABLE_OFFLOADING && !DECL_EXTERNAL (t))
1588 g->have_offload = true;
1589 if (!in_lto_p)
1590 vec_safe_push (offload_vars, t);
1594 break;
1598 DECL_SEEN_IN_BIND_EXPR_P (t) = 1;
1600 if (DECL_HARD_REGISTER (t) && !is_global_var (t) && cfun)
1601 cfun->has_local_explicit_reg_vars = true;
1605 bind_stmt = gimple_build_bind (BIND_EXPR_VARS (bind_expr), NULL,
1606 BIND_EXPR_BLOCK (bind_expr));
1607 gimple_push_bind_expr (bind_stmt);
1609 gimplify_ctxp->keep_stack = false;
1610 gimplify_ctxp->save_stack = false;
1612 /* Gimplify the body into the GIMPLE_BIND tuple's body. */
1613 body = NULL;
1614 gimplify_stmt (&BIND_EXPR_BODY (bind_expr), &body);
1615 gimple_bind_set_body (bind_stmt, body);
1617 /* Source location wise, the cleanup code (stack_restore and clobbers)
1618 belongs to the end of the block, so propagate what we have. The
1619 stack_save operation belongs to the beginning of block, which we can
1620 infer from the bind_expr directly if the block has no explicit
1621 assignment. */
1622 if (BIND_EXPR_BLOCK (bind_expr))
1624 end_locus = BLOCK_SOURCE_END_LOCATION (BIND_EXPR_BLOCK (bind_expr));
1625 start_locus = BLOCK_SOURCE_LOCATION (BIND_EXPR_BLOCK (bind_expr));
1627 if (start_locus == 0)
1628 start_locus = EXPR_LOCATION (bind_expr);
1630 cleanup = NULL;
1631 stack_save = NULL;
1633 /* Add clobbers for all variables that go out of scope. */
1634 for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t))
1636 if (VAR_P (t)
1637 && !is_global_var (t)
1638 && DECL_CONTEXT (t) == current_function_decl)
1640 if (flag_openmp
1641 && DECL_HAS_VALUE_EXPR_P (t)
1642 && TREE_USED (t)
1643 && lookup_attribute ("omp allocate", DECL_ATTRIBUTES (t)))
1645 /* For Fortran, TREE_CHAIN (TREE_VALUE (attr)) is set, which
1646 causes that the GOMP_free call is already added above;
1647 and "omp allocate" is removed from DECL_ATTRIBUTES. */
1648 tree v = TREE_OPERAND (DECL_VALUE_EXPR (t), 0);
1649 tree tmp = builtin_decl_explicit (BUILT_IN_GOMP_FREE);
1650 tmp = build_call_expr_loc (end_locus, tmp, 2, v,
1651 build_zero_cst (ptr_type_node));
1652 gimplify_and_add (tmp, &cleanup);
1653 gimple *clobber_stmt;
1654 tmp = build_clobber (TREE_TYPE (v), CLOBBER_STORAGE_END);
1655 clobber_stmt = gimple_build_assign (v, tmp);
1656 gimple_set_location (clobber_stmt, end_locus);
1657 gimplify_seq_add_stmt (&cleanup, clobber_stmt);
1659 if (!DECL_HARD_REGISTER (t)
1660 && !TREE_THIS_VOLATILE (t)
1661 && !DECL_HAS_VALUE_EXPR_P (t)
1662 /* Only care for variables that have to be in memory. Others
1663 will be rewritten into SSA names, hence moved to the
1664 top-level. */
1665 && !is_gimple_reg (t)
1666 && flag_stack_reuse != SR_NONE)
1668 tree clobber = build_clobber (TREE_TYPE (t), CLOBBER_STORAGE_END);
1669 gimple *clobber_stmt;
1670 clobber_stmt = gimple_build_assign (t, clobber);
1671 gimple_set_location (clobber_stmt, end_locus);
1672 gimplify_seq_add_stmt (&cleanup, clobber_stmt);
1675 if (flag_openacc && oacc_declare_returns != NULL)
1677 tree key = t;
1678 if (DECL_HAS_VALUE_EXPR_P (key))
1680 key = DECL_VALUE_EXPR (key);
1681 if (INDIRECT_REF_P (key))
1682 key = TREE_OPERAND (key, 0);
1684 tree *c = oacc_declare_returns->get (key);
1685 if (c != NULL)
1687 if (ret_clauses)
1688 OMP_CLAUSE_CHAIN (*c) = ret_clauses;
1690 ret_clauses = unshare_expr (*c);
1692 oacc_declare_returns->remove (key);
1694 if (oacc_declare_returns->is_empty ())
1696 delete oacc_declare_returns;
1697 oacc_declare_returns = NULL;
1703 if (asan_poisoned_variables != NULL
1704 && asan_poisoned_variables->contains (t))
1706 asan_poisoned_variables->remove (t);
1707 asan_poison_variable (t, true, &cleanup);
1710 if (gimplify_ctxp->live_switch_vars != NULL
1711 && gimplify_ctxp->live_switch_vars->contains (t))
1712 gimplify_ctxp->live_switch_vars->remove (t);
1715 /* If the code both contains VLAs and calls alloca, then we cannot reclaim
1716 the stack space allocated to the VLAs. */
1717 if (gimplify_ctxp->save_stack && !gimplify_ctxp->keep_stack)
1719 gcall *stack_restore;
1721 /* Save stack on entry and restore it on exit. Add a try_finally
1722 block to achieve this. */
1723 build_stack_save_restore (&stack_save, &stack_restore);
1725 gimple_set_location (stack_save, start_locus);
1726 gimple_set_location (stack_restore, end_locus);
1728 gimplify_seq_add_stmt (&cleanup, stack_restore);
1731 if (ret_clauses)
1733 gomp_target *stmt;
1734 gimple_stmt_iterator si = gsi_start (cleanup);
1736 stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
1737 ret_clauses);
1738 gsi_insert_seq_before_without_update (&si, stmt, GSI_NEW_STMT);
1741 if (cleanup)
1743 gtry *gs;
1744 gimple_seq new_body;
1746 new_body = NULL;
1747 gs = gimple_build_try (gimple_bind_body (bind_stmt), cleanup,
1748 GIMPLE_TRY_FINALLY);
1750 if (stack_save)
1751 gimplify_seq_add_stmt (&new_body, stack_save);
1752 gimplify_seq_add_stmt (&new_body, gs);
1753 gimple_bind_set_body (bind_stmt, new_body);
1756 /* keep_stack propagates all the way up to the outermost BIND_EXPR. */
1757 if (!gimplify_ctxp->keep_stack)
1758 gimplify_ctxp->keep_stack = old_keep_stack;
1759 gimplify_ctxp->save_stack = old_save_stack;
1761 gimple_pop_bind_expr ();
1763 gimplify_seq_add_stmt (pre_p, bind_stmt);
1765 if (temp)
1767 *expr_p = temp;
1768 return GS_OK;
1771 *expr_p = NULL_TREE;
1772 return GS_ALL_DONE;
1775 /* Maybe add early return predict statement to PRE_P sequence. */
1777 static void
1778 maybe_add_early_return_predict_stmt (gimple_seq *pre_p)
1780 /* If we are not in a conditional context, add PREDICT statement. */
1781 if (gimple_conditional_context ())
1783 gimple *predict = gimple_build_predict (PRED_TREE_EARLY_RETURN,
1784 NOT_TAKEN);
1785 gimplify_seq_add_stmt (pre_p, predict);
1789 /* Gimplify a RETURN_EXPR. If the expression to be returned is not a
1790 GIMPLE value, it is assigned to a new temporary and the statement is
1791 re-written to return the temporary.
1793 PRE_P points to the sequence where side effects that must happen before
1794 STMT should be stored. */
1796 static enum gimplify_status
1797 gimplify_return_expr (tree stmt, gimple_seq *pre_p)
1799 greturn *ret;
1800 tree ret_expr = TREE_OPERAND (stmt, 0);
1801 tree result_decl, result;
1803 if (ret_expr == error_mark_node)
1804 return GS_ERROR;
1806 if (!ret_expr
1807 || TREE_CODE (ret_expr) == RESULT_DECL)
1809 maybe_add_early_return_predict_stmt (pre_p);
1810 greturn *ret = gimple_build_return (ret_expr);
1811 copy_warning (ret, stmt);
1812 gimplify_seq_add_stmt (pre_p, ret);
1813 return GS_ALL_DONE;
1816 if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))))
1817 result_decl = NULL_TREE;
1818 else if (TREE_CODE (ret_expr) == COMPOUND_EXPR)
1820 /* Used in C++ for handling EH cleanup of the return value if a local
1821 cleanup throws. Assume the front-end knows what it's doing. */
1822 result_decl = DECL_RESULT (current_function_decl);
1823 /* But crash if we end up trying to modify ret_expr below. */
1824 ret_expr = NULL_TREE;
1826 else
1828 result_decl = TREE_OPERAND (ret_expr, 0);
1830 /* See through a return by reference. */
1831 if (INDIRECT_REF_P (result_decl))
1832 result_decl = TREE_OPERAND (result_decl, 0);
1834 gcc_assert ((TREE_CODE (ret_expr) == MODIFY_EXPR
1835 || TREE_CODE (ret_expr) == INIT_EXPR)
1836 && TREE_CODE (result_decl) == RESULT_DECL);
1839 /* If aggregate_value_p is true, then we can return the bare RESULT_DECL.
1840 Recall that aggregate_value_p is FALSE for any aggregate type that is
1841 returned in registers. If we're returning values in registers, then
1842 we don't want to extend the lifetime of the RESULT_DECL, particularly
1843 across another call. In addition, for those aggregates for which
1844 hard_function_value generates a PARALLEL, we'll die during normal
1845 expansion of structure assignments; there's special code in expand_return
1846 to handle this case that does not exist in expand_expr. */
1847 if (!result_decl)
1848 result = NULL_TREE;
1849 else if (aggregate_value_p (result_decl, TREE_TYPE (current_function_decl)))
1851 if (!poly_int_tree_p (DECL_SIZE (result_decl)))
1853 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (result_decl)))
1854 gimplify_type_sizes (TREE_TYPE (result_decl), pre_p);
1855 /* Note that we don't use gimplify_vla_decl because the RESULT_DECL
1856 should be effectively allocated by the caller, i.e. all calls to
1857 this function must be subject to the Return Slot Optimization. */
1858 gimplify_one_sizepos (&DECL_SIZE (result_decl), pre_p);
1859 gimplify_one_sizepos (&DECL_SIZE_UNIT (result_decl), pre_p);
1861 result = result_decl;
1863 else if (gimplify_ctxp->return_temp)
1864 result = gimplify_ctxp->return_temp;
1865 else
1867 result = create_tmp_reg (TREE_TYPE (result_decl));
1869 /* ??? With complex control flow (usually involving abnormal edges),
1870 we can wind up warning about an uninitialized value for this. Due
1871 to how this variable is constructed and initialized, this is never
1872 true. Give up and never warn. */
1873 suppress_warning (result, OPT_Wuninitialized);
1875 gimplify_ctxp->return_temp = result;
1878 /* Smash the lhs of the MODIFY_EXPR to the temporary we plan to use.
1879 Then gimplify the whole thing. */
1880 if (result != result_decl)
1881 TREE_OPERAND (ret_expr, 0) = result;
1883 gimplify_and_add (TREE_OPERAND (stmt, 0), pre_p);
1885 maybe_add_early_return_predict_stmt (pre_p);
1886 ret = gimple_build_return (result);
1887 copy_warning (ret, stmt);
1888 gimplify_seq_add_stmt (pre_p, ret);
1890 return GS_ALL_DONE;
1893 /* Gimplify a variable-length array DECL. */
1895 static void
1896 gimplify_vla_decl (tree decl, gimple_seq *seq_p)
1898 /* This is a variable-sized decl. Simplify its size and mark it
1899 for deferred expansion. */
1900 tree t, addr, ptr_type;
1902 gimplify_one_sizepos (&DECL_SIZE (decl), seq_p);
1903 gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), seq_p);
1905 /* Don't mess with a DECL_VALUE_EXPR set by the front-end. */
1906 if (DECL_HAS_VALUE_EXPR_P (decl))
1907 return;
1909 /* All occurrences of this decl in final gimplified code will be
1910 replaced by indirection. Setting DECL_VALUE_EXPR does two
1911 things: First, it lets the rest of the gimplifier know what
1912 replacement to use. Second, it lets the debug info know
1913 where to find the value. */
1914 ptr_type = build_pointer_type (TREE_TYPE (decl));
1915 addr = create_tmp_var (ptr_type, get_name (decl));
1916 DECL_IGNORED_P (addr) = 0;
1917 t = build_fold_indirect_ref (addr);
1918 TREE_THIS_NOTRAP (t) = 1;
1919 SET_DECL_VALUE_EXPR (decl, t);
1920 DECL_HAS_VALUE_EXPR_P (decl) = 1;
1922 t = build_alloca_call_expr (DECL_SIZE_UNIT (decl), DECL_ALIGN (decl),
1923 max_int_size_in_bytes (TREE_TYPE (decl)));
1924 /* The call has been built for a variable-sized object. */
1925 CALL_ALLOCA_FOR_VAR_P (t) = 1;
1926 t = fold_convert (ptr_type, t);
1927 t = build2 (MODIFY_EXPR, TREE_TYPE (addr), addr, t);
1929 gimplify_and_add (t, seq_p);
1931 /* Record the dynamic allocation associated with DECL if requested. */
1932 if (flag_callgraph_info & CALLGRAPH_INFO_DYNAMIC_ALLOC)
1933 record_dynamic_alloc (decl);
1936 /* A helper function to be called via walk_tree. Mark all labels under *TP
1937 as being forced. To be called for DECL_INITIAL of static variables. */
1939 static tree
1940 force_labels_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
1942 if (TYPE_P (*tp))
1943 *walk_subtrees = 0;
1944 if (TREE_CODE (*tp) == LABEL_DECL)
1946 FORCED_LABEL (*tp) = 1;
1947 cfun->has_forced_label_in_static = 1;
1950 return NULL_TREE;
1953 /* Generate an initialization to automatic variable DECL based on INIT_TYPE.
1954 Build a call to internal const function DEFERRED_INIT:
1955 1st argument: SIZE of the DECL;
1956 2nd argument: INIT_TYPE;
1957 3rd argument: NAME of the DECL;
1959 as LHS = DEFERRED_INIT (SIZE of the DECL, INIT_TYPE, NAME of the DECL). */
1961 static void
1962 gimple_add_init_for_auto_var (tree decl,
1963 enum auto_init_type init_type,
1964 gimple_seq *seq_p)
1966 gcc_assert (auto_var_p (decl));
1967 gcc_assert (init_type > AUTO_INIT_UNINITIALIZED);
1968 location_t loc = EXPR_LOCATION (decl);
1969 tree decl_size = TYPE_SIZE_UNIT (TREE_TYPE (decl));
1971 tree init_type_node
1972 = build_int_cst (integer_type_node, (int) init_type);
1974 tree decl_name = NULL_TREE;
1975 if (DECL_NAME (decl))
1977 decl_name = build_string_literal (DECL_NAME (decl));
1979 else
1981 char decl_name_anonymous[3 + (HOST_BITS_PER_INT + 2) / 3];
1982 sprintf (decl_name_anonymous, "D.%u", DECL_UID (decl));
1983 decl_name = build_string_literal (decl_name_anonymous);
1986 tree call = build_call_expr_internal_loc (loc, IFN_DEFERRED_INIT,
1987 TREE_TYPE (decl), 3,
1988 decl_size, init_type_node,
1989 decl_name);
1991 gimplify_assign (decl, call, seq_p);
1994 /* Generate padding initialization for automatic vairable DECL.
1995 C guarantees that brace-init with fewer initializers than members
1996 aggregate will initialize the rest of the aggregate as-if it were
1997 static initialization. In turn static initialization guarantees
1998 that padding is initialized to zero. So, we always initialize paddings
1999 to zeroes regardless INIT_TYPE.
2000 To do the padding initialization, we insert a call to
2001 __builtin_clear_padding (&decl, 0, for_auto_init = true).
2002 Note, we add an additional dummy argument for __builtin_clear_padding,
2003 'for_auto_init' to distinguish whether this call is for automatic
2004 variable initialization or not.
2006 static void
2007 gimple_add_padding_init_for_auto_var (tree decl, bool is_vla,
2008 gimple_seq *seq_p)
2010 tree addr_of_decl = NULL_TREE;
2011 tree fn = builtin_decl_explicit (BUILT_IN_CLEAR_PADDING);
2013 if (is_vla)
2015 /* The temporary address variable for this vla should be
2016 created in gimplify_vla_decl. */
2017 gcc_assert (DECL_HAS_VALUE_EXPR_P (decl));
2018 gcc_assert (INDIRECT_REF_P (DECL_VALUE_EXPR (decl)));
2019 addr_of_decl = TREE_OPERAND (DECL_VALUE_EXPR (decl), 0);
2021 else
2023 mark_addressable (decl);
2024 addr_of_decl = build_fold_addr_expr (decl);
2027 gimple *call = gimple_build_call (fn, 2, addr_of_decl,
2028 build_one_cst (TREE_TYPE (addr_of_decl)));
2029 gimplify_seq_add_stmt (seq_p, call);
2032 /* Return true if the DECL need to be automaticly initialized by the
2033 compiler. */
2034 static bool
2035 is_var_need_auto_init (tree decl)
2037 if (auto_var_p (decl)
2038 && (TREE_CODE (decl) != VAR_DECL
2039 || !DECL_HARD_REGISTER (decl))
2040 && (flag_auto_var_init > AUTO_INIT_UNINITIALIZED)
2041 && (!lookup_attribute ("uninitialized", DECL_ATTRIBUTES (decl)))
2042 && !OPAQUE_TYPE_P (TREE_TYPE (decl))
2043 && !is_empty_type (TREE_TYPE (decl)))
2044 return true;
2045 return false;
2048 /* Gimplify a DECL_EXPR node *STMT_P by making any necessary allocation
2049 and initialization explicit. */
2051 static enum gimplify_status
2052 gimplify_decl_expr (tree *stmt_p, gimple_seq *seq_p)
2054 tree stmt = *stmt_p;
2055 tree decl = DECL_EXPR_DECL (stmt);
2057 *stmt_p = NULL_TREE;
2059 if (TREE_TYPE (decl) == error_mark_node)
2060 return GS_ERROR;
2062 if ((TREE_CODE (decl) == TYPE_DECL
2063 || VAR_P (decl))
2064 && !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl)))
2066 gimplify_type_sizes (TREE_TYPE (decl), seq_p);
2067 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
2068 gimplify_type_sizes (TREE_TYPE (TREE_TYPE (decl)), seq_p);
2071 /* ??? DECL_ORIGINAL_TYPE is streamed for LTO so it needs to be gimplified
2072 in case its size expressions contain problematic nodes like CALL_EXPR. */
2073 if (TREE_CODE (decl) == TYPE_DECL
2074 && DECL_ORIGINAL_TYPE (decl)
2075 && !TYPE_SIZES_GIMPLIFIED (DECL_ORIGINAL_TYPE (decl)))
2077 gimplify_type_sizes (DECL_ORIGINAL_TYPE (decl), seq_p);
2078 if (TREE_CODE (DECL_ORIGINAL_TYPE (decl)) == REFERENCE_TYPE)
2079 gimplify_type_sizes (TREE_TYPE (DECL_ORIGINAL_TYPE (decl)), seq_p);
2082 if (VAR_P (decl) && !DECL_EXTERNAL (decl))
2084 tree init = DECL_INITIAL (decl);
2085 bool is_vla = false;
2086 /* Check whether a decl has FE created VALUE_EXPR here BEFORE
2087 gimplify_vla_decl creates VALUE_EXPR for a vla decl.
2088 If the decl has VALUE_EXPR that was created by FE (usually
2089 C++FE), it's a proxy varaible, and FE already initialized
2090 the VALUE_EXPR of it, we should not initialize it anymore. */
2091 bool decl_had_value_expr_p = DECL_HAS_VALUE_EXPR_P (decl);
2093 poly_uint64 size;
2094 if (!poly_int_tree_p (DECL_SIZE_UNIT (decl), &size)
2095 || (!TREE_STATIC (decl)
2096 && flag_stack_check == GENERIC_STACK_CHECK
2097 && maybe_gt (size,
2098 (unsigned HOST_WIDE_INT) STACK_CHECK_MAX_VAR_SIZE)))
2100 gimplify_vla_decl (decl, seq_p);
2101 is_vla = true;
2104 if (asan_poisoned_variables
2105 && !is_vla
2106 && TREE_ADDRESSABLE (decl)
2107 && !TREE_STATIC (decl)
2108 && !DECL_HAS_VALUE_EXPR_P (decl)
2109 && DECL_ALIGN (decl) <= MAX_SUPPORTED_STACK_ALIGNMENT
2110 && dbg_cnt (asan_use_after_scope)
2111 && !gimplify_omp_ctxp
2112 /* GNAT introduces temporaries to hold return values of calls in
2113 initializers of variables defined in other units, so the
2114 declaration of the variable is discarded completely. We do not
2115 want to issue poison calls for such dropped variables. */
2116 && (DECL_SEEN_IN_BIND_EXPR_P (decl)
2117 || (DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)))
2119 asan_poisoned_variables->add (decl);
2120 asan_poison_variable (decl, false, seq_p);
2121 if (!DECL_ARTIFICIAL (decl) && gimplify_ctxp->live_switch_vars)
2122 gimplify_ctxp->live_switch_vars->add (decl);
2125 /* Some front ends do not explicitly declare all anonymous
2126 artificial variables. We compensate here by declaring the
2127 variables, though it would be better if the front ends would
2128 explicitly declare them. */
2129 if (!DECL_SEEN_IN_BIND_EXPR_P (decl)
2130 && DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
2131 gimple_add_tmp_var (decl);
2133 if (init && init != error_mark_node)
2135 if (!TREE_STATIC (decl))
2137 DECL_INITIAL (decl) = NULL_TREE;
2138 init = build2 (INIT_EXPR, void_type_node, decl, init);
2139 gimplify_and_add (init, seq_p);
2140 ggc_free (init);
2141 /* Clear TREE_READONLY if we really have an initialization. */
2142 if (!DECL_INITIAL (decl)
2143 && !omp_privatize_by_reference (decl))
2144 TREE_READONLY (decl) = 0;
2146 else
2147 /* We must still examine initializers for static variables
2148 as they may contain a label address. */
2149 walk_tree (&init, force_labels_r, NULL, NULL);
2151 /* When there is no explicit initializer, if the user requested,
2152 We should insert an artifical initializer for this automatic
2153 variable. */
2154 else if (is_var_need_auto_init (decl)
2155 && !decl_had_value_expr_p)
2157 gimple_add_init_for_auto_var (decl,
2158 flag_auto_var_init,
2159 seq_p);
2160 /* The expanding of a call to the above .DEFERRED_INIT will apply
2161 block initialization to the whole space covered by this variable.
2162 As a result, all the paddings will be initialized to zeroes
2163 for zero initialization and 0xFE byte-repeatable patterns for
2164 pattern initialization.
2165 In order to make the paddings as zeroes for pattern init, We
2166 should add a call to __builtin_clear_padding to clear the
2167 paddings to zero in compatiple with CLANG.
2168 We cannot insert this call if the variable is a gimple register
2169 since __builtin_clear_padding will take the address of the
2170 variable. As a result, if a long double/_Complex long double
2171 variable will spilled into stack later, its padding is 0XFE. */
2172 if (flag_auto_var_init == AUTO_INIT_PATTERN
2173 && !is_gimple_reg (decl)
2174 && clear_padding_type_may_have_padding_p (TREE_TYPE (decl)))
2175 gimple_add_padding_init_for_auto_var (decl, is_vla, seq_p);
2179 return GS_ALL_DONE;
2182 /* Gimplify a LOOP_EXPR. Normally this just involves gimplifying the body
2183 and replacing the LOOP_EXPR with goto, but if the loop contains an
2184 EXIT_EXPR, we need to append a label for it to jump to. */
2186 static enum gimplify_status
2187 gimplify_loop_expr (tree *expr_p, gimple_seq *pre_p)
2189 tree saved_label = gimplify_ctxp->exit_label;
2190 tree start_label = create_artificial_label (UNKNOWN_LOCATION);
2192 gimplify_seq_add_stmt (pre_p, gimple_build_label (start_label));
2194 gimplify_ctxp->exit_label = NULL_TREE;
2196 gimplify_and_add (LOOP_EXPR_BODY (*expr_p), pre_p);
2198 gimplify_seq_add_stmt (pre_p, gimple_build_goto (start_label));
2200 if (gimplify_ctxp->exit_label)
2201 gimplify_seq_add_stmt (pre_p,
2202 gimple_build_label (gimplify_ctxp->exit_label));
2204 gimplify_ctxp->exit_label = saved_label;
2206 *expr_p = NULL;
2207 return GS_ALL_DONE;
2210 /* Gimplify a statement list onto a sequence. These may be created either
2211 by an enlightened front-end, or by shortcut_cond_expr. */
2213 static enum gimplify_status
2214 gimplify_statement_list (tree *expr_p, gimple_seq *pre_p)
2216 tree temp = voidify_wrapper_expr (*expr_p, NULL);
2218 tree_stmt_iterator i = tsi_start (*expr_p);
2220 while (!tsi_end_p (i))
2222 gimplify_stmt (tsi_stmt_ptr (i), pre_p);
2223 tsi_delink (&i);
2226 if (temp)
2228 *expr_p = temp;
2229 return GS_OK;
2232 return GS_ALL_DONE;
2236 /* Emit warning for the unreachable statment STMT if needed.
2237 Return the gimple itself when the warning is emitted, otherwise
2238 return NULL. */
2239 static gimple *
2240 emit_warn_switch_unreachable (gimple *stmt)
2242 if (gimple_code (stmt) == GIMPLE_GOTO
2243 && TREE_CODE (gimple_goto_dest (stmt)) == LABEL_DECL
2244 && DECL_ARTIFICIAL (gimple_goto_dest (stmt)))
2245 /* Don't warn for compiler-generated gotos. These occur
2246 in Duff's devices, for example. */
2247 return NULL;
2248 else if ((flag_auto_var_init > AUTO_INIT_UNINITIALIZED)
2249 && ((gimple_call_internal_p (stmt, IFN_DEFERRED_INIT))
2250 || (gimple_call_builtin_p (stmt, BUILT_IN_CLEAR_PADDING)
2251 && (bool) TREE_INT_CST_LOW (gimple_call_arg (stmt, 1)))
2252 || (is_gimple_assign (stmt)
2253 && gimple_assign_single_p (stmt)
2254 && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
2255 && gimple_call_internal_p (
2256 SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt)),
2257 IFN_DEFERRED_INIT))))
2258 /* Don't warn for compiler-generated initializations for
2259 -ftrivial-auto-var-init.
2260 There are 3 cases:
2261 case 1: a call to .DEFERRED_INIT;
2262 case 2: a call to __builtin_clear_padding with the 2nd argument is
2263 present and non-zero;
2264 case 3: a gimple assign store right after the call to .DEFERRED_INIT
2265 that has the LHS of .DEFERRED_INIT as the RHS as following:
2266 _1 = .DEFERRED_INIT (4, 2, &"i1"[0]);
2267 i1 = _1. */
2268 return NULL;
2269 else
2270 warning_at (gimple_location (stmt), OPT_Wswitch_unreachable,
2271 "statement will never be executed");
2272 return stmt;
2275 /* Callback for walk_gimple_seq. */
2277 static tree
2278 warn_switch_unreachable_and_auto_init_r (gimple_stmt_iterator *gsi_p,
2279 bool *handled_ops_p,
2280 struct walk_stmt_info *wi)
2282 gimple *stmt = gsi_stmt (*gsi_p);
2283 bool unreachable_issued = wi->info != NULL;
2285 *handled_ops_p = true;
2286 switch (gimple_code (stmt))
2288 case GIMPLE_TRY:
2289 /* A compiler-generated cleanup or a user-written try block.
2290 If it's empty, don't dive into it--that would result in
2291 worse location info. */
2292 if (gimple_try_eval (stmt) == NULL)
2294 if (warn_switch_unreachable && !unreachable_issued)
2295 wi->info = emit_warn_switch_unreachable (stmt);
2297 /* Stop when auto var init warning is not on. */
2298 if (!warn_trivial_auto_var_init)
2299 return integer_zero_node;
2301 /* Fall through. */
2302 case GIMPLE_BIND:
2303 case GIMPLE_CATCH:
2304 case GIMPLE_EH_FILTER:
2305 case GIMPLE_TRANSACTION:
2306 /* Walk the sub-statements. */
2307 *handled_ops_p = false;
2308 break;
2310 case GIMPLE_DEBUG:
2311 /* Ignore these. We may generate them before declarations that
2312 are never executed. If there's something to warn about,
2313 there will be non-debug stmts too, and we'll catch those. */
2314 break;
2316 case GIMPLE_LABEL:
2317 /* Stop till the first Label. */
2318 return integer_zero_node;
2319 case GIMPLE_CALL:
2320 if (gimple_call_internal_p (stmt, IFN_ASAN_MARK))
2322 *handled_ops_p = false;
2323 break;
2325 if (warn_trivial_auto_var_init
2326 && flag_auto_var_init > AUTO_INIT_UNINITIALIZED
2327 && gimple_call_internal_p (stmt, IFN_DEFERRED_INIT))
2329 /* Get the variable name from the 3rd argument of call. */
2330 tree var_name = gimple_call_arg (stmt, 2);
2331 var_name = TREE_OPERAND (TREE_OPERAND (var_name, 0), 0);
2332 const char *var_name_str = TREE_STRING_POINTER (var_name);
2334 warning_at (gimple_location (stmt), OPT_Wtrivial_auto_var_init,
2335 "%qs cannot be initialized with"
2336 "%<-ftrivial-auto-var_init%>",
2337 var_name_str);
2338 break;
2341 /* Fall through. */
2342 default:
2343 /* check the first "real" statement (not a decl/lexical scope/...), issue
2344 warning if needed. */
2345 if (warn_switch_unreachable && !unreachable_issued)
2346 wi->info = emit_warn_switch_unreachable (stmt);
2347 /* Stop when auto var init warning is not on. */
2348 if (!warn_trivial_auto_var_init)
2349 return integer_zero_node;
2350 break;
2352 return NULL_TREE;
2356 /* Possibly warn about unreachable statements between switch's controlling
2357 expression and the first case. Also warn about -ftrivial-auto-var-init
2358 cannot initialize the auto variable under such situation.
2359 SEQ is the body of a switch expression. */
2361 static void
2362 maybe_warn_switch_unreachable_and_auto_init (gimple_seq seq)
2364 if ((!warn_switch_unreachable && !warn_trivial_auto_var_init)
2365 /* This warning doesn't play well with Fortran when optimizations
2366 are on. */
2367 || lang_GNU_Fortran ()
2368 || seq == NULL)
2369 return;
2371 struct walk_stmt_info wi;
2373 memset (&wi, 0, sizeof (wi));
2374 walk_gimple_seq (seq, warn_switch_unreachable_and_auto_init_r, NULL, &wi);
2378 /* A label entry that pairs label and a location. */
2379 struct label_entry
2381 tree label;
2382 location_t loc;
2385 /* Find LABEL in vector of label entries VEC. */
2387 static struct label_entry *
2388 find_label_entry (const auto_vec<struct label_entry> *vec, tree label)
2390 unsigned int i;
2391 struct label_entry *l;
2393 FOR_EACH_VEC_ELT (*vec, i, l)
2394 if (l->label == label)
2395 return l;
2396 return NULL;
2399 /* Return true if LABEL, a LABEL_DECL, represents a case label
2400 in a vector of labels CASES. */
2402 static bool
2403 case_label_p (const vec<tree> *cases, tree label)
2405 unsigned int i;
2406 tree l;
2408 FOR_EACH_VEC_ELT (*cases, i, l)
2409 if (CASE_LABEL (l) == label)
2410 return true;
2411 return false;
2414 /* Find the last nondebug statement in a scope STMT. */
2416 static gimple *
2417 last_stmt_in_scope (gimple *stmt)
2419 if (!stmt)
2420 return NULL;
2422 switch (gimple_code (stmt))
2424 case GIMPLE_BIND:
2426 gbind *bind = as_a <gbind *> (stmt);
2427 stmt = gimple_seq_last_nondebug_stmt (gimple_bind_body (bind));
2428 return last_stmt_in_scope (stmt);
2431 case GIMPLE_TRY:
2433 gtry *try_stmt = as_a <gtry *> (stmt);
2434 stmt = gimple_seq_last_nondebug_stmt (gimple_try_eval (try_stmt));
2435 gimple *last_eval = last_stmt_in_scope (stmt);
2436 if (gimple_stmt_may_fallthru (last_eval)
2437 && (last_eval == NULL
2438 || !gimple_call_internal_p (last_eval, IFN_FALLTHROUGH))
2439 && gimple_try_kind (try_stmt) == GIMPLE_TRY_FINALLY)
2441 stmt = gimple_seq_last_nondebug_stmt (gimple_try_cleanup (try_stmt));
2442 return last_stmt_in_scope (stmt);
2444 else
2445 return last_eval;
2448 case GIMPLE_DEBUG:
2449 gcc_unreachable ();
2451 default:
2452 return stmt;
2456 /* Collect labels that may fall through into LABELS and return the statement
2457 preceding another case label, or a user-defined label. Store a location
2458 useful to give warnings at *PREVLOC (usually the location of the returned
2459 statement or of its surrounding scope). */
2461 static gimple *
2462 collect_fallthrough_labels (gimple_stmt_iterator *gsi_p,
2463 auto_vec <struct label_entry> *labels,
2464 location_t *prevloc)
2466 gimple *prev = NULL;
2468 *prevloc = UNKNOWN_LOCATION;
2471 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND)
2473 /* Recognize the special GIMPLE_BIND added by gimplify_switch_expr,
2474 which starts on a GIMPLE_SWITCH and ends with a break label.
2475 Handle that as a single statement that can fall through. */
2476 gbind *bind = as_a <gbind *> (gsi_stmt (*gsi_p));
2477 gimple *first = gimple_seq_first_stmt (gimple_bind_body (bind));
2478 gimple *last = gimple_seq_last_stmt (gimple_bind_body (bind));
2479 if (last
2480 && gimple_code (first) == GIMPLE_SWITCH
2481 && gimple_code (last) == GIMPLE_LABEL)
2483 tree label = gimple_label_label (as_a <glabel *> (last));
2484 if (SWITCH_BREAK_LABEL_P (label))
2486 prev = bind;
2487 gsi_next (gsi_p);
2488 continue;
2492 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND
2493 || gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_TRY)
2495 /* Nested scope. Only look at the last statement of
2496 the innermost scope. */
2497 location_t bind_loc = gimple_location (gsi_stmt (*gsi_p));
2498 gimple *last = last_stmt_in_scope (gsi_stmt (*gsi_p));
2499 if (last)
2501 prev = last;
2502 /* It might be a label without a location. Use the
2503 location of the scope then. */
2504 if (!gimple_has_location (prev))
2505 *prevloc = bind_loc;
2507 gsi_next (gsi_p);
2508 continue;
2511 /* Ifs are tricky. */
2512 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_COND)
2514 gcond *cond_stmt = as_a <gcond *> (gsi_stmt (*gsi_p));
2515 tree false_lab = gimple_cond_false_label (cond_stmt);
2516 location_t if_loc = gimple_location (cond_stmt);
2518 /* If we have e.g.
2519 if (i > 1) goto <D.2259>; else goto D;
2520 we can't do much with the else-branch. */
2521 if (!DECL_ARTIFICIAL (false_lab))
2522 break;
2524 /* Go on until the false label, then one step back. */
2525 for (; !gsi_end_p (*gsi_p); gsi_next (gsi_p))
2527 gimple *stmt = gsi_stmt (*gsi_p);
2528 if (gimple_code (stmt) == GIMPLE_LABEL
2529 && gimple_label_label (as_a <glabel *> (stmt)) == false_lab)
2530 break;
2533 /* Not found? Oops. */
2534 if (gsi_end_p (*gsi_p))
2535 break;
2537 /* A dead label can't fall through. */
2538 if (!UNUSED_LABEL_P (false_lab))
2540 struct label_entry l = { false_lab, if_loc };
2541 labels->safe_push (l);
2544 /* Go to the last statement of the then branch. */
2545 gsi_prev (gsi_p);
2547 /* if (i != 0) goto <D.1759>; else goto <D.1760>;
2548 <D.1759>:
2549 <stmt>;
2550 goto <D.1761>;
2551 <D.1760>:
2553 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_GOTO
2554 && !gimple_has_location (gsi_stmt (*gsi_p)))
2556 /* Look at the statement before, it might be
2557 attribute fallthrough, in which case don't warn. */
2558 gsi_prev (gsi_p);
2559 bool fallthru_before_dest
2560 = gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_FALLTHROUGH);
2561 gsi_next (gsi_p);
2562 tree goto_dest = gimple_goto_dest (gsi_stmt (*gsi_p));
2563 if (!fallthru_before_dest)
2565 struct label_entry l = { goto_dest, if_loc };
2566 labels->safe_push (l);
2569 /* This case is about
2570 if (1 != 0) goto <D.2022>; else goto <D.2023>;
2571 <D.2022>:
2572 n = n + 1; // #1
2573 <D.2023>: // #2
2574 <D.1988>: // #3
2575 where #2 is UNUSED_LABEL_P and we want to warn about #1 falling
2576 through to #3. So set PREV to #1. */
2577 else if (UNUSED_LABEL_P (false_lab))
2578 prev = gsi_stmt (*gsi_p);
2580 /* And move back. */
2581 gsi_next (gsi_p);
2584 /* Remember the last statement. Skip labels that are of no interest
2585 to us. */
2586 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
2588 tree label = gimple_label_label (as_a <glabel *> (gsi_stmt (*gsi_p)));
2589 if (find_label_entry (labels, label))
2590 prev = gsi_stmt (*gsi_p);
2592 else if (gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_ASAN_MARK))
2594 else if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_PREDICT)
2596 else if (!is_gimple_debug (gsi_stmt (*gsi_p)))
2597 prev = gsi_stmt (*gsi_p);
2598 gsi_next (gsi_p);
2600 while (!gsi_end_p (*gsi_p)
2601 /* Stop if we find a case or a user-defined label. */
2602 && (gimple_code (gsi_stmt (*gsi_p)) != GIMPLE_LABEL
2603 || !gimple_has_location (gsi_stmt (*gsi_p))));
2605 if (prev && gimple_has_location (prev))
2606 *prevloc = gimple_location (prev);
2607 return prev;
2610 /* Return true if the switch fallthough warning should occur. LABEL is
2611 the label statement that we're falling through to. */
2613 static bool
2614 should_warn_for_implicit_fallthrough (gimple_stmt_iterator *gsi_p, tree label)
2616 gimple_stmt_iterator gsi = *gsi_p;
2618 /* Don't warn if the label is marked with a "falls through" comment. */
2619 if (FALLTHROUGH_LABEL_P (label))
2620 return false;
2622 /* Don't warn for non-case labels followed by a statement:
2623 case 0:
2624 foo ();
2625 label:
2626 bar ();
2627 as these are likely intentional. */
2628 if (!case_label_p (&gimplify_ctxp->case_labels, label))
2630 tree l;
2631 while (!gsi_end_p (gsi)
2632 && gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
2633 && (l = gimple_label_label (as_a <glabel *> (gsi_stmt (gsi))))
2634 && !case_label_p (&gimplify_ctxp->case_labels, l))
2635 gsi_next_nondebug (&gsi);
2636 if (gsi_end_p (gsi) || gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL)
2637 return false;
2640 /* Don't warn for terminated branches, i.e. when the subsequent case labels
2641 immediately breaks. */
2642 gsi = *gsi_p;
2644 /* Skip all immediately following labels. */
2645 while (!gsi_end_p (gsi)
2646 && (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
2647 || gimple_code (gsi_stmt (gsi)) == GIMPLE_PREDICT))
2648 gsi_next_nondebug (&gsi);
2650 /* { ... something; default:; } */
2651 if (gsi_end_p (gsi)
2652 /* { ... something; default: break; } or
2653 { ... something; default: goto L; } */
2654 || gimple_code (gsi_stmt (gsi)) == GIMPLE_GOTO
2655 /* { ... something; default: return; } */
2656 || gimple_code (gsi_stmt (gsi)) == GIMPLE_RETURN)
2657 return false;
2659 return true;
2662 /* Callback for walk_gimple_seq. */
2664 static tree
2665 warn_implicit_fallthrough_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
2666 struct walk_stmt_info *)
2668 gimple *stmt = gsi_stmt (*gsi_p);
2670 *handled_ops_p = true;
2671 switch (gimple_code (stmt))
2673 case GIMPLE_TRY:
2674 case GIMPLE_BIND:
2675 case GIMPLE_CATCH:
2676 case GIMPLE_EH_FILTER:
2677 case GIMPLE_TRANSACTION:
2678 /* Walk the sub-statements. */
2679 *handled_ops_p = false;
2680 break;
2682 /* Find a sequence of form:
2684 GIMPLE_LABEL
2685 [...]
2686 <may fallthru stmt>
2687 GIMPLE_LABEL
2689 and possibly warn. */
2690 case GIMPLE_LABEL:
2692 /* Found a label. Skip all immediately following labels. */
2693 while (!gsi_end_p (*gsi_p)
2694 && gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
2695 gsi_next_nondebug (gsi_p);
2697 /* There might be no more statements. */
2698 if (gsi_end_p (*gsi_p))
2699 return integer_zero_node;
2701 /* Vector of labels that fall through. */
2702 auto_vec <struct label_entry> labels;
2703 location_t prevloc;
2704 gimple *prev = collect_fallthrough_labels (gsi_p, &labels, &prevloc);
2706 /* There might be no more statements. */
2707 if (gsi_end_p (*gsi_p))
2708 return integer_zero_node;
2710 gimple *next = gsi_stmt (*gsi_p);
2711 tree label;
2712 /* If what follows is a label, then we may have a fallthrough. */
2713 if (gimple_code (next) == GIMPLE_LABEL
2714 && gimple_has_location (next)
2715 && (label = gimple_label_label (as_a <glabel *> (next)))
2716 && prev != NULL)
2718 struct label_entry *l;
2719 bool warned_p = false;
2720 auto_diagnostic_group d;
2721 if (!should_warn_for_implicit_fallthrough (gsi_p, label))
2722 /* Quiet. */;
2723 else if (gimple_code (prev) == GIMPLE_LABEL
2724 && (label = gimple_label_label (as_a <glabel *> (prev)))
2725 && (l = find_label_entry (&labels, label)))
2726 warned_p = warning_at (l->loc, OPT_Wimplicit_fallthrough_,
2727 "this statement may fall through");
2728 else if (!gimple_call_internal_p (prev, IFN_FALLTHROUGH)
2729 /* Try to be clever and don't warn when the statement
2730 can't actually fall through. */
2731 && gimple_stmt_may_fallthru (prev)
2732 && prevloc != UNKNOWN_LOCATION)
2733 warned_p = warning_at (prevloc,
2734 OPT_Wimplicit_fallthrough_,
2735 "this statement may fall through");
2736 if (warned_p)
2737 inform (gimple_location (next), "here");
2739 /* Mark this label as processed so as to prevent multiple
2740 warnings in nested switches. */
2741 FALLTHROUGH_LABEL_P (label) = true;
2743 /* So that next warn_implicit_fallthrough_r will start looking for
2744 a new sequence starting with this label. */
2745 gsi_prev (gsi_p);
2748 break;
2749 default:
2750 break;
2752 return NULL_TREE;
2755 /* Warn when a switch case falls through. */
2757 static void
2758 maybe_warn_implicit_fallthrough (gimple_seq seq)
2760 if (!warn_implicit_fallthrough)
2761 return;
2763 /* This warning is meant for C/C++/ObjC/ObjC++ only. */
2764 if (!(lang_GNU_C ()
2765 || lang_GNU_CXX ()
2766 || lang_GNU_OBJC ()))
2767 return;
2769 struct walk_stmt_info wi;
2770 memset (&wi, 0, sizeof (wi));
2771 walk_gimple_seq (seq, warn_implicit_fallthrough_r, NULL, &wi);
2774 /* Callback for walk_gimple_seq. */
2776 static tree
2777 expand_FALLTHROUGH_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
2778 struct walk_stmt_info *wi)
2780 gimple *stmt = gsi_stmt (*gsi_p);
2782 *handled_ops_p = true;
2783 switch (gimple_code (stmt))
2785 case GIMPLE_TRY:
2786 case GIMPLE_BIND:
2787 case GIMPLE_CATCH:
2788 case GIMPLE_EH_FILTER:
2789 case GIMPLE_TRANSACTION:
2790 /* Walk the sub-statements. */
2791 *handled_ops_p = false;
2792 break;
2793 case GIMPLE_CALL:
2794 static_cast<location_t *>(wi->info)[0] = UNKNOWN_LOCATION;
2795 if (gimple_call_internal_p (stmt, IFN_FALLTHROUGH))
2797 location_t loc = gimple_location (stmt);
2798 gsi_remove (gsi_p, true);
2799 wi->removed_stmt = true;
2801 /* nothrow flag is added by genericize_c_loop to mark fallthrough
2802 statement at the end of some loop's body. Those should be
2803 always diagnosed, either because they indeed don't precede
2804 a case label or default label, or because the next statement
2805 is not within the same iteration statement. */
2806 if ((stmt->subcode & GF_CALL_NOTHROW) != 0)
2808 pedwarn (loc, 0, "attribute %<fallthrough%> not preceding "
2809 "a case label or default label");
2810 break;
2813 if (gsi_end_p (*gsi_p))
2815 static_cast<location_t *>(wi->info)[0] = BUILTINS_LOCATION;
2816 static_cast<location_t *>(wi->info)[1] = loc;
2817 break;
2820 bool found = false;
2822 gimple_stmt_iterator gsi2 = *gsi_p;
2823 stmt = gsi_stmt (gsi2);
2824 if (gimple_code (stmt) == GIMPLE_GOTO && !gimple_has_location (stmt))
2826 /* Go on until the artificial label. */
2827 tree goto_dest = gimple_goto_dest (stmt);
2828 for (; !gsi_end_p (gsi2); gsi_next (&gsi2))
2830 if (gimple_code (gsi_stmt (gsi2)) == GIMPLE_LABEL
2831 && gimple_label_label (as_a <glabel *> (gsi_stmt (gsi2)))
2832 == goto_dest)
2833 break;
2836 /* Not found? Stop. */
2837 if (gsi_end_p (gsi2))
2838 break;
2840 /* Look one past it. */
2841 gsi_next (&gsi2);
2844 /* We're looking for a case label or default label here. */
2845 while (!gsi_end_p (gsi2))
2847 stmt = gsi_stmt (gsi2);
2848 if (gimple_code (stmt) == GIMPLE_LABEL)
2850 tree label = gimple_label_label (as_a <glabel *> (stmt));
2851 if (gimple_has_location (stmt) && DECL_ARTIFICIAL (label))
2853 found = true;
2854 break;
2857 else if (gimple_call_internal_p (stmt, IFN_ASAN_MARK))
2859 else if (!is_gimple_debug (stmt))
2860 /* Anything else is not expected. */
2861 break;
2862 gsi_next (&gsi2);
2864 if (!found)
2865 pedwarn (loc, 0, "attribute %<fallthrough%> not preceding "
2866 "a case label or default label");
2868 break;
2869 default:
2870 static_cast<location_t *>(wi->info)[0] = UNKNOWN_LOCATION;
2871 break;
2873 return NULL_TREE;
2876 /* Expand all FALLTHROUGH () calls in SEQ. */
2878 static void
2879 expand_FALLTHROUGH (gimple_seq *seq_p)
2881 struct walk_stmt_info wi;
2882 location_t loc[2];
2883 memset (&wi, 0, sizeof (wi));
2884 loc[0] = UNKNOWN_LOCATION;
2885 loc[1] = UNKNOWN_LOCATION;
2886 wi.info = (void *) &loc[0];
2887 walk_gimple_seq_mod (seq_p, expand_FALLTHROUGH_r, NULL, &wi);
2888 if (loc[0] != UNKNOWN_LOCATION)
2889 /* We've found [[fallthrough]]; at the end of a switch, which the C++
2890 standard says is ill-formed; see [dcl.attr.fallthrough]. */
2891 pedwarn (loc[1], 0, "attribute %<fallthrough%> not preceding "
2892 "a case label or default label");
2896 /* Gimplify a SWITCH_EXPR, and collect the vector of labels it can
2897 branch to. */
2899 static enum gimplify_status
2900 gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p)
2902 tree switch_expr = *expr_p;
2903 gimple_seq switch_body_seq = NULL;
2904 enum gimplify_status ret;
2905 tree index_type = TREE_TYPE (switch_expr);
2906 if (index_type == NULL_TREE)
2907 index_type = TREE_TYPE (SWITCH_COND (switch_expr));
2909 ret = gimplify_expr (&SWITCH_COND (switch_expr), pre_p, NULL, is_gimple_val,
2910 fb_rvalue);
2911 if (ret == GS_ERROR || ret == GS_UNHANDLED)
2912 return ret;
2914 if (SWITCH_BODY (switch_expr))
2916 vec<tree> labels;
2917 vec<tree> saved_labels;
2918 hash_set<tree> *saved_live_switch_vars = NULL;
2919 tree default_case = NULL_TREE;
2920 gswitch *switch_stmt;
2922 /* Save old labels, get new ones from body, then restore the old
2923 labels. Save all the things from the switch body to append after. */
2924 saved_labels = gimplify_ctxp->case_labels;
2925 gimplify_ctxp->case_labels.create (8);
2927 /* Do not create live_switch_vars if SWITCH_BODY is not a BIND_EXPR. */
2928 saved_live_switch_vars = gimplify_ctxp->live_switch_vars;
2929 tree_code body_type = TREE_CODE (SWITCH_BODY (switch_expr));
2930 if (body_type == BIND_EXPR || body_type == STATEMENT_LIST)
2931 gimplify_ctxp->live_switch_vars = new hash_set<tree> (4);
2932 else
2933 gimplify_ctxp->live_switch_vars = NULL;
2935 bool old_in_switch_expr = gimplify_ctxp->in_switch_expr;
2936 gimplify_ctxp->in_switch_expr = true;
2938 gimplify_stmt (&SWITCH_BODY (switch_expr), &switch_body_seq);
2940 gimplify_ctxp->in_switch_expr = old_in_switch_expr;
2941 maybe_warn_switch_unreachable_and_auto_init (switch_body_seq);
2942 maybe_warn_implicit_fallthrough (switch_body_seq);
2943 /* Only do this for the outermost GIMPLE_SWITCH. */
2944 if (!gimplify_ctxp->in_switch_expr)
2945 expand_FALLTHROUGH (&switch_body_seq);
2947 labels = gimplify_ctxp->case_labels;
2948 gimplify_ctxp->case_labels = saved_labels;
2950 if (gimplify_ctxp->live_switch_vars)
2952 gcc_assert (gimplify_ctxp->live_switch_vars->is_empty ());
2953 delete gimplify_ctxp->live_switch_vars;
2955 gimplify_ctxp->live_switch_vars = saved_live_switch_vars;
2957 preprocess_case_label_vec_for_gimple (labels, index_type,
2958 &default_case);
2960 bool add_bind = false;
2961 if (!default_case)
2963 glabel *new_default;
2965 default_case
2966 = build_case_label (NULL_TREE, NULL_TREE,
2967 create_artificial_label (UNKNOWN_LOCATION));
2968 if (old_in_switch_expr)
2970 SWITCH_BREAK_LABEL_P (CASE_LABEL (default_case)) = 1;
2971 add_bind = true;
2973 new_default = gimple_build_label (CASE_LABEL (default_case));
2974 gimplify_seq_add_stmt (&switch_body_seq, new_default);
2976 else if (old_in_switch_expr)
2978 gimple *last = gimple_seq_last_stmt (switch_body_seq);
2979 if (last && gimple_code (last) == GIMPLE_LABEL)
2981 tree label = gimple_label_label (as_a <glabel *> (last));
2982 if (SWITCH_BREAK_LABEL_P (label))
2983 add_bind = true;
2987 switch_stmt = gimple_build_switch (SWITCH_COND (switch_expr),
2988 default_case, labels);
2989 /* For the benefit of -Wimplicit-fallthrough, if switch_body_seq
2990 ends with a GIMPLE_LABEL holding SWITCH_BREAK_LABEL_P LABEL_DECL,
2991 wrap the GIMPLE_SWITCH up to that GIMPLE_LABEL into a GIMPLE_BIND,
2992 so that we can easily find the start and end of the switch
2993 statement. */
2994 if (add_bind)
2996 gimple_seq bind_body = NULL;
2997 gimplify_seq_add_stmt (&bind_body, switch_stmt);
2998 gimple_seq_add_seq (&bind_body, switch_body_seq);
2999 gbind *bind = gimple_build_bind (NULL_TREE, bind_body, NULL_TREE);
3000 gimple_set_location (bind, EXPR_LOCATION (switch_expr));
3001 gimplify_seq_add_stmt (pre_p, bind);
3003 else
3005 gimplify_seq_add_stmt (pre_p, switch_stmt);
3006 gimplify_seq_add_seq (pre_p, switch_body_seq);
3008 labels.release ();
3010 else
3011 gcc_unreachable ();
3013 return GS_ALL_DONE;
3016 /* Gimplify the LABEL_EXPR pointed to by EXPR_P. */
3018 static enum gimplify_status
3019 gimplify_label_expr (tree *expr_p, gimple_seq *pre_p)
3021 gcc_assert (decl_function_context (LABEL_EXPR_LABEL (*expr_p))
3022 == current_function_decl);
3024 tree label = LABEL_EXPR_LABEL (*expr_p);
3025 glabel *label_stmt = gimple_build_label (label);
3026 gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
3027 gimplify_seq_add_stmt (pre_p, label_stmt);
3029 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label)))
3030 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_COLD_LABEL,
3031 NOT_TAKEN));
3032 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label)))
3033 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_HOT_LABEL,
3034 TAKEN));
3036 return GS_ALL_DONE;
3039 /* Gimplify the CASE_LABEL_EXPR pointed to by EXPR_P. */
3041 static enum gimplify_status
3042 gimplify_case_label_expr (tree *expr_p, gimple_seq *pre_p)
3044 struct gimplify_ctx *ctxp;
3045 glabel *label_stmt;
3047 /* Invalid programs can play Duff's Device type games with, for example,
3048 #pragma omp parallel. At least in the C front end, we don't
3049 detect such invalid branches until after gimplification, in the
3050 diagnose_omp_blocks pass. */
3051 for (ctxp = gimplify_ctxp; ; ctxp = ctxp->prev_context)
3052 if (ctxp->case_labels.exists ())
3053 break;
3055 tree label = CASE_LABEL (*expr_p);
3056 label_stmt = gimple_build_label (label);
3057 gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
3058 ctxp->case_labels.safe_push (*expr_p);
3059 gimplify_seq_add_stmt (pre_p, label_stmt);
3061 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label)))
3062 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_COLD_LABEL,
3063 NOT_TAKEN));
3064 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label)))
3065 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_HOT_LABEL,
3066 TAKEN));
3068 return GS_ALL_DONE;
3071 /* Build a GOTO to the LABEL_DECL pointed to by LABEL_P, building it first
3072 if necessary. */
3074 tree
3075 build_and_jump (tree *label_p)
3077 if (label_p == NULL)
3078 /* If there's nowhere to jump, just fall through. */
3079 return NULL_TREE;
3081 if (*label_p == NULL_TREE)
3083 tree label = create_artificial_label (UNKNOWN_LOCATION);
3084 *label_p = label;
3087 return build1 (GOTO_EXPR, void_type_node, *label_p);
3090 /* Gimplify an EXIT_EXPR by converting to a GOTO_EXPR inside a COND_EXPR.
3091 This also involves building a label to jump to and communicating it to
3092 gimplify_loop_expr through gimplify_ctxp->exit_label. */
3094 static enum gimplify_status
3095 gimplify_exit_expr (tree *expr_p)
3097 tree cond = TREE_OPERAND (*expr_p, 0);
3098 tree expr;
3100 expr = build_and_jump (&gimplify_ctxp->exit_label);
3101 expr = build3 (COND_EXPR, void_type_node, cond, expr, NULL_TREE);
3102 *expr_p = expr;
3104 return GS_OK;
3107 /* *EXPR_P is a COMPONENT_REF being used as an rvalue. If its type is
3108 different from its canonical type, wrap the whole thing inside a
3109 NOP_EXPR and force the type of the COMPONENT_REF to be the canonical
3110 type.
3112 The canonical type of a COMPONENT_REF is the type of the field being
3113 referenced--unless the field is a bit-field which can be read directly
3114 in a smaller mode, in which case the canonical type is the
3115 sign-appropriate type corresponding to that mode. */
3117 static void
3118 canonicalize_component_ref (tree *expr_p)
3120 tree expr = *expr_p;
3121 tree type;
3123 gcc_assert (TREE_CODE (expr) == COMPONENT_REF);
3125 if (INTEGRAL_TYPE_P (TREE_TYPE (expr)))
3126 type = TREE_TYPE (get_unwidened (expr, NULL_TREE));
3127 else
3128 type = TREE_TYPE (TREE_OPERAND (expr, 1));
3130 /* One could argue that all the stuff below is not necessary for
3131 the non-bitfield case and declare it a FE error if type
3132 adjustment would be needed. */
3133 if (TREE_TYPE (expr) != type)
3135 #ifdef ENABLE_TYPES_CHECKING
3136 tree old_type = TREE_TYPE (expr);
3137 #endif
3138 int type_quals;
3140 /* We need to preserve qualifiers and propagate them from
3141 operand 0. */
3142 type_quals = TYPE_QUALS (type)
3143 | TYPE_QUALS (TREE_TYPE (TREE_OPERAND (expr, 0)));
3144 if (TYPE_QUALS (type) != type_quals)
3145 type = build_qualified_type (TYPE_MAIN_VARIANT (type), type_quals);
3147 /* Set the type of the COMPONENT_REF to the underlying type. */
3148 TREE_TYPE (expr) = type;
3150 #ifdef ENABLE_TYPES_CHECKING
3151 /* It is now a FE error, if the conversion from the canonical
3152 type to the original expression type is not useless. */
3153 gcc_assert (useless_type_conversion_p (old_type, type));
3154 #endif
3158 /* If a NOP conversion is changing a pointer to array of foo to a pointer
3159 to foo, embed that change in the ADDR_EXPR by converting
3160 T array[U];
3161 (T *)&array
3163 &array[L]
3164 where L is the lower bound. For simplicity, only do this for constant
3165 lower bound.
3166 The constraint is that the type of &array[L] is trivially convertible
3167 to T *. */
3169 static void
3170 canonicalize_addr_expr (tree *expr_p)
3172 tree expr = *expr_p;
3173 tree addr_expr = TREE_OPERAND (expr, 0);
3174 tree datype, ddatype, pddatype;
3176 /* We simplify only conversions from an ADDR_EXPR to a pointer type. */
3177 if (!POINTER_TYPE_P (TREE_TYPE (expr))
3178 || TREE_CODE (addr_expr) != ADDR_EXPR)
3179 return;
3181 /* The addr_expr type should be a pointer to an array. */
3182 datype = TREE_TYPE (TREE_TYPE (addr_expr));
3183 if (TREE_CODE (datype) != ARRAY_TYPE)
3184 return;
3186 /* The pointer to element type shall be trivially convertible to
3187 the expression pointer type. */
3188 ddatype = TREE_TYPE (datype);
3189 pddatype = build_pointer_type (ddatype);
3190 if (!useless_type_conversion_p (TYPE_MAIN_VARIANT (TREE_TYPE (expr)),
3191 pddatype))
3192 return;
3194 /* The lower bound and element sizes must be constant. */
3195 if (!TYPE_SIZE_UNIT (ddatype)
3196 || TREE_CODE (TYPE_SIZE_UNIT (ddatype)) != INTEGER_CST
3197 || !TYPE_DOMAIN (datype) || !TYPE_MIN_VALUE (TYPE_DOMAIN (datype))
3198 || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (datype))) != INTEGER_CST)
3199 return;
3201 /* All checks succeeded. Build a new node to merge the cast. */
3202 *expr_p = build4 (ARRAY_REF, ddatype, TREE_OPERAND (addr_expr, 0),
3203 TYPE_MIN_VALUE (TYPE_DOMAIN (datype)),
3204 NULL_TREE, NULL_TREE);
3205 *expr_p = build1 (ADDR_EXPR, pddatype, *expr_p);
3207 /* We can have stripped a required restrict qualifier above. */
3208 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
3209 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
3212 /* *EXPR_P is a NOP_EXPR or CONVERT_EXPR. Remove it and/or other conversions
3213 underneath as appropriate. */
3215 static enum gimplify_status
3216 gimplify_conversion (tree *expr_p)
3218 location_t loc = EXPR_LOCATION (*expr_p);
3219 gcc_assert (CONVERT_EXPR_P (*expr_p));
3221 /* Then strip away all but the outermost conversion. */
3222 STRIP_SIGN_NOPS (TREE_OPERAND (*expr_p, 0));
3224 /* And remove the outermost conversion if it's useless. */
3225 if (tree_ssa_useless_type_conversion (*expr_p))
3226 *expr_p = TREE_OPERAND (*expr_p, 0);
3228 /* If we still have a conversion at the toplevel,
3229 then canonicalize some constructs. */
3230 if (CONVERT_EXPR_P (*expr_p))
3232 tree sub = TREE_OPERAND (*expr_p, 0);
3234 /* If a NOP conversion is changing the type of a COMPONENT_REF
3235 expression, then canonicalize its type now in order to expose more
3236 redundant conversions. */
3237 if (TREE_CODE (sub) == COMPONENT_REF)
3238 canonicalize_component_ref (&TREE_OPERAND (*expr_p, 0));
3240 /* If a NOP conversion is changing a pointer to array of foo
3241 to a pointer to foo, embed that change in the ADDR_EXPR. */
3242 else if (TREE_CODE (sub) == ADDR_EXPR)
3243 canonicalize_addr_expr (expr_p);
3246 /* If we have a conversion to a non-register type force the
3247 use of a VIEW_CONVERT_EXPR instead. */
3248 if (CONVERT_EXPR_P (*expr_p) && !is_gimple_reg_type (TREE_TYPE (*expr_p)))
3249 *expr_p = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (*expr_p),
3250 TREE_OPERAND (*expr_p, 0));
3252 /* Canonicalize CONVERT_EXPR to NOP_EXPR. */
3253 if (TREE_CODE (*expr_p) == CONVERT_EXPR)
3254 TREE_SET_CODE (*expr_p, NOP_EXPR);
3256 return GS_OK;
3259 /* Gimplify a VAR_DECL or PARM_DECL. Return GS_OK if we expanded a
3260 DECL_VALUE_EXPR, and it's worth re-examining things. */
3262 static enum gimplify_status
3263 gimplify_var_or_parm_decl (tree *expr_p)
3265 tree decl = *expr_p;
3267 /* ??? If this is a local variable, and it has not been seen in any
3268 outer BIND_EXPR, then it's probably the result of a duplicate
3269 declaration, for which we've already issued an error. It would
3270 be really nice if the front end wouldn't leak these at all.
3271 Currently the only known culprit is C++ destructors, as seen
3272 in g++.old-deja/g++.jason/binding.C.
3273 Another possible culpit are size expressions for variably modified
3274 types which are lost in the FE or not gimplified correctly. */
3275 if (VAR_P (decl)
3276 && !DECL_SEEN_IN_BIND_EXPR_P (decl)
3277 && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl)
3278 && decl_function_context (decl) == current_function_decl)
3280 gcc_assert (seen_error ());
3281 return GS_ERROR;
3284 /* When within an OMP context, notice uses of variables. */
3285 if (gimplify_omp_ctxp && omp_notice_variable (gimplify_omp_ctxp, decl, true))
3286 return GS_ALL_DONE;
3288 /* If the decl is an alias for another expression, substitute it now. */
3289 if (DECL_HAS_VALUE_EXPR_P (decl))
3291 *expr_p = unshare_expr (DECL_VALUE_EXPR (decl));
3292 return GS_OK;
3295 return GS_ALL_DONE;
3298 /* Recalculate the value of the TREE_SIDE_EFFECTS flag for T. */
3300 static void
3301 recalculate_side_effects (tree t)
3303 enum tree_code code = TREE_CODE (t);
3304 int len = TREE_OPERAND_LENGTH (t);
3305 int i;
3307 switch (TREE_CODE_CLASS (code))
3309 case tcc_expression:
3310 switch (code)
3312 case INIT_EXPR:
3313 case MODIFY_EXPR:
3314 case VA_ARG_EXPR:
3315 case PREDECREMENT_EXPR:
3316 case PREINCREMENT_EXPR:
3317 case POSTDECREMENT_EXPR:
3318 case POSTINCREMENT_EXPR:
3319 /* All of these have side-effects, no matter what their
3320 operands are. */
3321 return;
3323 default:
3324 break;
3326 /* Fall through. */
3328 case tcc_comparison: /* a comparison expression */
3329 case tcc_unary: /* a unary arithmetic expression */
3330 case tcc_binary: /* a binary arithmetic expression */
3331 case tcc_reference: /* a reference */
3332 case tcc_vl_exp: /* a function call */
3333 TREE_SIDE_EFFECTS (t) = TREE_THIS_VOLATILE (t);
3334 for (i = 0; i < len; ++i)
3336 tree op = TREE_OPERAND (t, i);
3337 if (op && TREE_SIDE_EFFECTS (op))
3338 TREE_SIDE_EFFECTS (t) = 1;
3340 break;
3342 case tcc_constant:
3343 /* No side-effects. */
3344 return;
3346 default:
3347 gcc_unreachable ();
3351 /* Gimplify the COMPONENT_REF, ARRAY_REF, REALPART_EXPR or IMAGPART_EXPR
3352 node *EXPR_P.
3354 compound_lval
3355 : min_lval '[' val ']'
3356 | min_lval '.' ID
3357 | compound_lval '[' val ']'
3358 | compound_lval '.' ID
3360 This is not part of the original SIMPLE definition, which separates
3361 array and member references, but it seems reasonable to handle them
3362 together. Also, this way we don't run into problems with union
3363 aliasing; gcc requires that for accesses through a union to alias, the
3364 union reference must be explicit, which was not always the case when we
3365 were splitting up array and member refs.
3367 PRE_P points to the sequence where side effects that must happen before
3368 *EXPR_P should be stored.
3370 POST_P points to the sequence where side effects that must happen after
3371 *EXPR_P should be stored. */
3373 static enum gimplify_status
3374 gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
3375 fallback_t fallback)
3377 tree *p;
3378 enum gimplify_status ret = GS_ALL_DONE, tret;
3379 int i;
3380 location_t loc = EXPR_LOCATION (*expr_p);
3381 tree expr = *expr_p;
3383 /* Create a stack of the subexpressions so later we can walk them in
3384 order from inner to outer. */
3385 auto_vec<tree, 10> expr_stack;
3387 /* We can handle anything that get_inner_reference can deal with. */
3388 for (p = expr_p; ; p = &TREE_OPERAND (*p, 0))
3390 restart:
3391 /* Fold INDIRECT_REFs now to turn them into ARRAY_REFs. */
3392 if (TREE_CODE (*p) == INDIRECT_REF)
3393 *p = fold_indirect_ref_loc (loc, *p);
3395 if (handled_component_p (*p))
3397 /* Expand DECL_VALUE_EXPR now. In some cases that may expose
3398 additional COMPONENT_REFs. */
3399 else if ((VAR_P (*p) || TREE_CODE (*p) == PARM_DECL)
3400 && gimplify_var_or_parm_decl (p) == GS_OK)
3401 goto restart;
3402 else
3403 break;
3405 expr_stack.safe_push (*p);
3408 gcc_assert (expr_stack.length ());
3410 /* Now EXPR_STACK is a stack of pointers to all the refs we've
3411 walked through and P points to the innermost expression.
3413 Java requires that we elaborated nodes in source order. That
3414 means we must gimplify the inner expression followed by each of
3415 the indices, in order. But we can't gimplify the inner
3416 expression until we deal with any variable bounds, sizes, or
3417 positions in order to deal with PLACEHOLDER_EXPRs.
3419 The base expression may contain a statement expression that
3420 has declarations used in size expressions, so has to be
3421 gimplified before gimplifying the size expressions.
3423 So we do this in three steps. First we deal with variable
3424 bounds, sizes, and positions, then we gimplify the base and
3425 ensure it is memory if needed, then we deal with the annotations
3426 for any variables in the components and any indices, from left
3427 to right. */
3429 bool need_non_reg = false;
3430 for (i = expr_stack.length () - 1; i >= 0; i--)
3432 tree t = expr_stack[i];
3434 if (error_operand_p (TREE_OPERAND (t, 0)))
3435 return GS_ERROR;
3437 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
3439 /* Deal with the low bound and element type size and put them into
3440 the ARRAY_REF. If these values are set, they have already been
3441 gimplified. */
3442 if (TREE_OPERAND (t, 2) == NULL_TREE)
3444 tree low = unshare_expr (array_ref_low_bound (t));
3445 if (!is_gimple_min_invariant (low))
3447 TREE_OPERAND (t, 2) = low;
3451 if (TREE_OPERAND (t, 3) == NULL_TREE)
3453 tree elmt_size = array_ref_element_size (t);
3454 if (!is_gimple_min_invariant (elmt_size))
3456 elmt_size = unshare_expr (elmt_size);
3457 tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0)));
3458 tree factor = size_int (TYPE_ALIGN_UNIT (elmt_type));
3460 /* Divide the element size by the alignment of the element
3461 type (above). */
3462 elmt_size = size_binop_loc (loc, EXACT_DIV_EXPR,
3463 elmt_size, factor);
3465 TREE_OPERAND (t, 3) = elmt_size;
3468 need_non_reg = true;
3470 else if (TREE_CODE (t) == COMPONENT_REF)
3472 /* Set the field offset into T and gimplify it. */
3473 if (TREE_OPERAND (t, 2) == NULL_TREE)
3475 tree offset = component_ref_field_offset (t);
3476 if (!is_gimple_min_invariant (offset))
3478 offset = unshare_expr (offset);
3479 tree field = TREE_OPERAND (t, 1);
3480 tree factor
3481 = size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT);
3483 /* Divide the offset by its alignment. */
3484 offset = size_binop_loc (loc, EXACT_DIV_EXPR,
3485 offset, factor);
3487 TREE_OPERAND (t, 2) = offset;
3490 need_non_reg = true;
3492 else if (!is_gimple_reg_type (TREE_TYPE (t)))
3493 /* When the result of an operation, in particular a VIEW_CONVERT_EXPR
3494 is a non-register type then require the base object to be a
3495 non-register as well. */
3496 need_non_reg = true;
3499 /* Step 2 is to gimplify the base expression. Make sure lvalue is set
3500 so as to match the min_lval predicate. Failure to do so may result
3501 in the creation of large aggregate temporaries. */
3502 tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval,
3503 fallback | fb_lvalue);
3504 ret = MIN (ret, tret);
3505 if (ret == GS_ERROR)
3506 return GS_ERROR;
3508 /* Step 2a: if we have component references we do not support on
3509 registers then make sure the base isn't a register. Of course
3510 we can only do so if an rvalue is OK. */
3511 if (need_non_reg && (fallback & fb_rvalue))
3512 prepare_gimple_addressable (p, pre_p);
3515 /* Step 3: gimplify size expressions and the indices and operands of
3516 ARRAY_REF. During this loop we also remove any useless conversions.
3517 If we operate on a register also make sure to properly gimplify
3518 to individual operations. */
3520 bool reg_operations = is_gimple_reg (*p);
3521 for (; expr_stack.length () > 0; )
3523 tree t = expr_stack.pop ();
3525 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
3527 gcc_assert (!reg_operations);
3529 /* Gimplify the low bound and element type size. */
3530 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
3531 is_gimple_reg, fb_rvalue);
3532 ret = MIN (ret, tret);
3534 tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p, post_p,
3535 is_gimple_reg, fb_rvalue);
3536 ret = MIN (ret, tret);
3538 /* Gimplify the dimension. */
3539 tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
3540 is_gimple_val, fb_rvalue);
3541 ret = MIN (ret, tret);
3543 else if (TREE_CODE (t) == COMPONENT_REF)
3545 gcc_assert (!reg_operations);
3547 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
3548 is_gimple_reg, fb_rvalue);
3549 ret = MIN (ret, tret);
3551 else if (reg_operations)
3553 tret = gimplify_expr (&TREE_OPERAND (t, 0), pre_p, post_p,
3554 is_gimple_val, fb_rvalue);
3555 ret = MIN (ret, tret);
3558 STRIP_USELESS_TYPE_CONVERSION (TREE_OPERAND (t, 0));
3560 /* The innermost expression P may have originally had
3561 TREE_SIDE_EFFECTS set which would have caused all the outer
3562 expressions in *EXPR_P leading to P to also have had
3563 TREE_SIDE_EFFECTS set. */
3564 recalculate_side_effects (t);
3567 /* If the outermost expression is a COMPONENT_REF, canonicalize its type. */
3568 if ((fallback & fb_rvalue) && TREE_CODE (*expr_p) == COMPONENT_REF)
3570 canonicalize_component_ref (expr_p);
3573 expr_stack.release ();
3575 gcc_assert (*expr_p == expr || ret != GS_ALL_DONE);
3577 return ret;
3580 /* Gimplify the self modifying expression pointed to by EXPR_P
3581 (++, --, +=, -=).
3583 PRE_P points to the list where side effects that must happen before
3584 *EXPR_P should be stored.
3586 POST_P points to the list where side effects that must happen after
3587 *EXPR_P should be stored.
3589 WANT_VALUE is nonzero iff we want to use the value of this expression
3590 in another expression.
3592 ARITH_TYPE is the type the computation should be performed in. */
3594 enum gimplify_status
3595 gimplify_self_mod_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
3596 bool want_value, tree arith_type)
3598 enum tree_code code;
3599 tree lhs, lvalue, rhs, t1;
3600 gimple_seq post = NULL, *orig_post_p = post_p;
3601 bool postfix;
3602 enum tree_code arith_code;
3603 enum gimplify_status ret;
3604 location_t loc = EXPR_LOCATION (*expr_p);
3606 code = TREE_CODE (*expr_p);
3608 gcc_assert (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR
3609 || code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR);
3611 /* Prefix or postfix? */
3612 if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
3613 /* Faster to treat as prefix if result is not used. */
3614 postfix = want_value;
3615 else
3616 postfix = false;
3618 /* For postfix, make sure the inner expression's post side effects
3619 are executed after side effects from this expression. */
3620 if (postfix)
3621 post_p = &post;
3623 /* Add or subtract? */
3624 if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
3625 arith_code = PLUS_EXPR;
3626 else
3627 arith_code = MINUS_EXPR;
3629 /* Gimplify the LHS into a GIMPLE lvalue. */
3630 lvalue = TREE_OPERAND (*expr_p, 0);
3631 ret = gimplify_expr (&lvalue, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
3632 if (ret == GS_ERROR)
3633 return ret;
3635 /* Extract the operands to the arithmetic operation. */
3636 lhs = lvalue;
3637 rhs = TREE_OPERAND (*expr_p, 1);
3639 /* For postfix operator, we evaluate the LHS to an rvalue and then use
3640 that as the result value and in the postqueue operation. */
3641 if (postfix)
3643 ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue);
3644 if (ret == GS_ERROR)
3645 return ret;
3647 lhs = get_initialized_tmp_var (lhs, pre_p);
3650 /* For POINTERs increment, use POINTER_PLUS_EXPR. */
3651 if (POINTER_TYPE_P (TREE_TYPE (lhs)))
3653 rhs = convert_to_ptrofftype_loc (loc, rhs);
3654 if (arith_code == MINUS_EXPR)
3655 rhs = fold_build1_loc (loc, NEGATE_EXPR, TREE_TYPE (rhs), rhs);
3656 t1 = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (*expr_p), lhs, rhs);
3658 else
3659 t1 = fold_convert (TREE_TYPE (*expr_p),
3660 fold_build2 (arith_code, arith_type,
3661 fold_convert (arith_type, lhs),
3662 fold_convert (arith_type, rhs)));
3664 if (postfix)
3666 gimplify_assign (lvalue, t1, pre_p);
3667 gimplify_seq_add_seq (orig_post_p, post);
3668 *expr_p = lhs;
3669 return GS_ALL_DONE;
3671 else
3673 *expr_p = build2 (MODIFY_EXPR, TREE_TYPE (lvalue), lvalue, t1);
3674 return GS_OK;
3678 /* If *EXPR_P has a variable sized type, wrap it in a WITH_SIZE_EXPR. */
3680 static void
3681 maybe_with_size_expr (tree *expr_p)
3683 tree expr = *expr_p;
3684 tree type = TREE_TYPE (expr);
3685 tree size;
3687 /* If we've already wrapped this or the type is error_mark_node, we can't do
3688 anything. */
3689 if (TREE_CODE (expr) == WITH_SIZE_EXPR
3690 || type == error_mark_node)
3691 return;
3693 /* If the size isn't known or is a constant, we have nothing to do. */
3694 size = TYPE_SIZE_UNIT (type);
3695 if (!size || poly_int_tree_p (size))
3696 return;
3698 /* Otherwise, make a WITH_SIZE_EXPR. */
3699 size = unshare_expr (size);
3700 size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, expr);
3701 *expr_p = build2 (WITH_SIZE_EXPR, type, expr, size);
3704 /* Helper for gimplify_call_expr. Gimplify a single argument *ARG_P
3705 Store any side-effects in PRE_P. CALL_LOCATION is the location of
3706 the CALL_EXPR. If ALLOW_SSA is set the actual parameter may be
3707 gimplified to an SSA name. */
3709 enum gimplify_status
3710 gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location,
3711 bool allow_ssa)
3713 bool (*test) (tree);
3714 fallback_t fb;
3716 /* In general, we allow lvalues for function arguments to avoid
3717 extra overhead of copying large aggregates out of even larger
3718 aggregates into temporaries only to copy the temporaries to
3719 the argument list. Make optimizers happy by pulling out to
3720 temporaries those types that fit in registers. */
3721 if (is_gimple_reg_type (TREE_TYPE (*arg_p)))
3722 test = is_gimple_val, fb = fb_rvalue;
3723 else
3725 test = is_gimple_lvalue, fb = fb_either;
3726 /* Also strip a TARGET_EXPR that would force an extra copy. */
3727 if (TREE_CODE (*arg_p) == TARGET_EXPR)
3729 tree init = TARGET_EXPR_INITIAL (*arg_p);
3730 if (init
3731 && !VOID_TYPE_P (TREE_TYPE (init)))
3732 *arg_p = init;
3736 /* If this is a variable sized type, we must remember the size. */
3737 maybe_with_size_expr (arg_p);
3739 /* FIXME diagnostics: This will mess up gcc.dg/Warray-bounds.c. */
3740 /* Make sure arguments have the same location as the function call
3741 itself. */
3742 protected_set_expr_location (*arg_p, call_location);
3744 /* There is a sequence point before a function call. Side effects in
3745 the argument list must occur before the actual call. So, when
3746 gimplifying arguments, force gimplify_expr to use an internal
3747 post queue which is then appended to the end of PRE_P. */
3748 return gimplify_expr (arg_p, pre_p, NULL, test, fb, allow_ssa);
3751 /* Don't fold inside offloading or taskreg regions: it can break code by
3752 adding decl references that weren't in the source. We'll do it during
3753 omplower pass instead. */
3755 static bool
3756 maybe_fold_stmt (gimple_stmt_iterator *gsi)
3758 struct gimplify_omp_ctx *ctx;
3759 for (ctx = gimplify_omp_ctxp; ctx; ctx = ctx->outer_context)
3760 if ((ctx->region_type & (ORT_TARGET | ORT_PARALLEL | ORT_TASK)) != 0)
3761 return false;
3762 else if ((ctx->region_type & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
3763 return false;
3764 /* Delay folding of builtins until the IL is in consistent state
3765 so the diagnostic machinery can do a better job. */
3766 if (gimple_call_builtin_p (gsi_stmt (*gsi)))
3767 return false;
3768 return fold_stmt (gsi);
3771 /* Gimplify the CALL_EXPR node *EXPR_P into the GIMPLE sequence PRE_P.
3772 WANT_VALUE is true if the result of the call is desired. */
3774 static enum gimplify_status
3775 gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
3777 tree fndecl, parms, p, fnptrtype;
3778 enum gimplify_status ret;
3779 int i, nargs;
3780 gcall *call;
3781 bool builtin_va_start_p = false;
3782 location_t loc = EXPR_LOCATION (*expr_p);
3784 gcc_assert (TREE_CODE (*expr_p) == CALL_EXPR);
3786 /* For reliable diagnostics during inlining, it is necessary that
3787 every call_expr be annotated with file and line. */
3788 if (! EXPR_HAS_LOCATION (*expr_p))
3789 SET_EXPR_LOCATION (*expr_p, input_location);
3791 /* Gimplify internal functions created in the FEs. */
3792 if (CALL_EXPR_FN (*expr_p) == NULL_TREE)
3794 if (want_value)
3795 return GS_ALL_DONE;
3797 nargs = call_expr_nargs (*expr_p);
3798 enum internal_fn ifn = CALL_EXPR_IFN (*expr_p);
3799 auto_vec<tree> vargs (nargs);
3801 if (ifn == IFN_ASSUME)
3803 if (simple_condition_p (CALL_EXPR_ARG (*expr_p, 0)))
3805 /* If the [[assume (cond)]]; condition is simple
3806 enough and can be evaluated unconditionally
3807 without side-effects, expand it as
3808 if (!cond) __builtin_unreachable (); */
3809 tree fndecl = builtin_decl_explicit (BUILT_IN_UNREACHABLE);
3810 *expr_p = build3 (COND_EXPR, void_type_node,
3811 CALL_EXPR_ARG (*expr_p, 0), void_node,
3812 build_call_expr_loc (EXPR_LOCATION (*expr_p),
3813 fndecl, 0));
3814 return GS_OK;
3816 /* If not optimizing, ignore the assumptions. */
3817 if (!optimize || seen_error ())
3819 *expr_p = NULL_TREE;
3820 return GS_ALL_DONE;
3822 /* Temporarily, until gimple lowering, transform
3823 .ASSUME (cond);
3824 into:
3825 [[assume (guard)]]
3827 guard = cond;
3829 such that gimple lowering can outline the condition into
3830 a separate function easily. */
3831 tree guard = create_tmp_var (boolean_type_node);
3832 *expr_p = build2 (MODIFY_EXPR, void_type_node, guard,
3833 gimple_boolify (CALL_EXPR_ARG (*expr_p, 0)));
3834 *expr_p = build3 (BIND_EXPR, void_type_node, NULL, *expr_p, NULL);
3835 push_gimplify_context ();
3836 gimple_seq body = NULL;
3837 gimple *g = gimplify_and_return_first (*expr_p, &body);
3838 pop_gimplify_context (g);
3839 g = gimple_build_assume (guard, body);
3840 gimple_set_location (g, loc);
3841 gimplify_seq_add_stmt (pre_p, g);
3842 *expr_p = NULL_TREE;
3843 return GS_ALL_DONE;
3846 for (i = 0; i < nargs; i++)
3848 gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
3849 EXPR_LOCATION (*expr_p));
3850 vargs.quick_push (CALL_EXPR_ARG (*expr_p, i));
3853 gcall *call = gimple_build_call_internal_vec (ifn, vargs);
3854 gimple_call_set_nothrow (call, TREE_NOTHROW (*expr_p));
3855 gimplify_seq_add_stmt (pre_p, call);
3856 return GS_ALL_DONE;
3859 /* This may be a call to a builtin function.
3861 Builtin function calls may be transformed into different
3862 (and more efficient) builtin function calls under certain
3863 circumstances. Unfortunately, gimplification can muck things
3864 up enough that the builtin expanders are not aware that certain
3865 transformations are still valid.
3867 So we attempt transformation/gimplification of the call before
3868 we gimplify the CALL_EXPR. At this time we do not manage to
3869 transform all calls in the same manner as the expanders do, but
3870 we do transform most of them. */
3871 fndecl = get_callee_fndecl (*expr_p);
3872 if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
3873 switch (DECL_FUNCTION_CODE (fndecl))
3875 CASE_BUILT_IN_ALLOCA:
3876 /* If the call has been built for a variable-sized object, then we
3877 want to restore the stack level when the enclosing BIND_EXPR is
3878 exited to reclaim the allocated space; otherwise, we precisely
3879 need to do the opposite and preserve the latest stack level. */
3880 if (CALL_ALLOCA_FOR_VAR_P (*expr_p))
3881 gimplify_ctxp->save_stack = true;
3882 else
3883 gimplify_ctxp->keep_stack = true;
3884 break;
3886 case BUILT_IN_VA_START:
3888 builtin_va_start_p = true;
3889 if (call_expr_nargs (*expr_p) < 2)
3891 error ("too few arguments to function %<va_start%>");
3892 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
3893 return GS_OK;
3896 if (fold_builtin_next_arg (*expr_p, true))
3898 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
3899 return GS_OK;
3901 break;
3904 case BUILT_IN_EH_RETURN:
3905 cfun->calls_eh_return = true;
3906 break;
3908 case BUILT_IN_CLEAR_PADDING:
3909 if (call_expr_nargs (*expr_p) == 1)
3911 /* Remember the original type of the argument in an internal
3912 dummy second argument, as in GIMPLE pointer conversions are
3913 useless. Also mark this call as not for automatic
3914 initialization in the internal dummy third argument. */
3915 p = CALL_EXPR_ARG (*expr_p, 0);
3916 *expr_p
3917 = build_call_expr_loc (EXPR_LOCATION (*expr_p), fndecl, 2, p,
3918 build_zero_cst (TREE_TYPE (p)));
3919 return GS_OK;
3921 break;
3923 default:
3926 if (fndecl && fndecl_built_in_p (fndecl))
3928 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
3929 if (new_tree && new_tree != *expr_p)
3931 /* There was a transformation of this call which computes the
3932 same value, but in a more efficient way. Return and try
3933 again. */
3934 *expr_p = new_tree;
3935 return GS_OK;
3939 /* Remember the original function pointer type. */
3940 fnptrtype = TREE_TYPE (CALL_EXPR_FN (*expr_p));
3942 if (flag_openmp
3943 && fndecl
3944 && cfun
3945 && (cfun->curr_properties & PROP_gimple_any) == 0)
3947 tree variant = omp_resolve_declare_variant (fndecl);
3948 if (variant != fndecl)
3949 CALL_EXPR_FN (*expr_p) = build1 (ADDR_EXPR, fnptrtype, variant);
3952 /* There is a sequence point before the call, so any side effects in
3953 the calling expression must occur before the actual call. Force
3954 gimplify_expr to use an internal post queue. */
3955 ret = gimplify_expr (&CALL_EXPR_FN (*expr_p), pre_p, NULL,
3956 is_gimple_call_addr, fb_rvalue);
3958 if (ret == GS_ERROR)
3959 return GS_ERROR;
3961 nargs = call_expr_nargs (*expr_p);
3963 /* Get argument types for verification. */
3964 fndecl = get_callee_fndecl (*expr_p);
3965 parms = NULL_TREE;
3966 if (fndecl)
3967 parms = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
3968 else
3969 parms = TYPE_ARG_TYPES (TREE_TYPE (fnptrtype));
3971 if (fndecl && DECL_ARGUMENTS (fndecl))
3972 p = DECL_ARGUMENTS (fndecl);
3973 else if (parms)
3974 p = parms;
3975 else
3976 p = NULL_TREE;
3977 for (i = 0; i < nargs && p; i++, p = TREE_CHAIN (p))
3980 /* If the last argument is __builtin_va_arg_pack () and it is not
3981 passed as a named argument, decrease the number of CALL_EXPR
3982 arguments and set instead the CALL_EXPR_VA_ARG_PACK flag. */
3983 if (!p
3984 && i < nargs
3985 && TREE_CODE (CALL_EXPR_ARG (*expr_p, nargs - 1)) == CALL_EXPR)
3987 tree last_arg = CALL_EXPR_ARG (*expr_p, nargs - 1);
3988 tree last_arg_fndecl = get_callee_fndecl (last_arg);
3990 if (last_arg_fndecl
3991 && fndecl_built_in_p (last_arg_fndecl, BUILT_IN_VA_ARG_PACK))
3993 tree call = *expr_p;
3995 --nargs;
3996 *expr_p = build_call_array_loc (loc, TREE_TYPE (call),
3997 CALL_EXPR_FN (call),
3998 nargs, CALL_EXPR_ARGP (call));
4000 /* Copy all CALL_EXPR flags, location and block, except
4001 CALL_EXPR_VA_ARG_PACK flag. */
4002 CALL_EXPR_STATIC_CHAIN (*expr_p) = CALL_EXPR_STATIC_CHAIN (call);
4003 CALL_EXPR_TAILCALL (*expr_p) = CALL_EXPR_TAILCALL (call);
4004 CALL_EXPR_RETURN_SLOT_OPT (*expr_p)
4005 = CALL_EXPR_RETURN_SLOT_OPT (call);
4006 CALL_FROM_THUNK_P (*expr_p) = CALL_FROM_THUNK_P (call);
4007 SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (call));
4009 /* Set CALL_EXPR_VA_ARG_PACK. */
4010 CALL_EXPR_VA_ARG_PACK (*expr_p) = 1;
4014 /* If the call returns twice then after building the CFG the call
4015 argument computations will no longer dominate the call because
4016 we add an abnormal incoming edge to the call. So do not use SSA
4017 vars there. */
4018 bool returns_twice = call_expr_flags (*expr_p) & ECF_RETURNS_TWICE;
4020 /* Gimplify the function arguments. */
4021 if (nargs > 0)
4023 for (i = (PUSH_ARGS_REVERSED ? nargs - 1 : 0);
4024 PUSH_ARGS_REVERSED ? i >= 0 : i < nargs;
4025 PUSH_ARGS_REVERSED ? i-- : i++)
4027 enum gimplify_status t;
4029 /* Avoid gimplifying the second argument to va_start, which needs to
4030 be the plain PARM_DECL. */
4031 if ((i != 1) || !builtin_va_start_p)
4033 t = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
4034 EXPR_LOCATION (*expr_p), ! returns_twice);
4036 if (t == GS_ERROR)
4037 ret = GS_ERROR;
4042 /* Gimplify the static chain. */
4043 if (CALL_EXPR_STATIC_CHAIN (*expr_p))
4045 if (fndecl && !DECL_STATIC_CHAIN (fndecl))
4046 CALL_EXPR_STATIC_CHAIN (*expr_p) = NULL;
4047 else
4049 enum gimplify_status t;
4050 t = gimplify_arg (&CALL_EXPR_STATIC_CHAIN (*expr_p), pre_p,
4051 EXPR_LOCATION (*expr_p), ! returns_twice);
4052 if (t == GS_ERROR)
4053 ret = GS_ERROR;
4057 /* Verify the function result. */
4058 if (want_value && fndecl
4059 && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fnptrtype))))
4061 error_at (loc, "using result of function returning %<void%>");
4062 ret = GS_ERROR;
4065 /* Try this again in case gimplification exposed something. */
4066 if (ret != GS_ERROR)
4068 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
4070 if (new_tree && new_tree != *expr_p)
4072 /* There was a transformation of this call which computes the
4073 same value, but in a more efficient way. Return and try
4074 again. */
4075 *expr_p = new_tree;
4076 return GS_OK;
4079 else
4081 *expr_p = error_mark_node;
4082 return GS_ERROR;
4085 /* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its
4086 decl. This allows us to eliminate redundant or useless
4087 calls to "const" functions. */
4088 if (TREE_CODE (*expr_p) == CALL_EXPR)
4090 int flags = call_expr_flags (*expr_p);
4091 if (flags & (ECF_CONST | ECF_PURE)
4092 /* An infinite loop is considered a side effect. */
4093 && !(flags & (ECF_LOOPING_CONST_OR_PURE)))
4094 TREE_SIDE_EFFECTS (*expr_p) = 0;
4097 /* If the value is not needed by the caller, emit a new GIMPLE_CALL
4098 and clear *EXPR_P. Otherwise, leave *EXPR_P in its gimplified
4099 form and delegate the creation of a GIMPLE_CALL to
4100 gimplify_modify_expr. This is always possible because when
4101 WANT_VALUE is true, the caller wants the result of this call into
4102 a temporary, which means that we will emit an INIT_EXPR in
4103 internal_get_tmp_var which will then be handled by
4104 gimplify_modify_expr. */
4105 if (!want_value)
4107 /* The CALL_EXPR in *EXPR_P is already in GIMPLE form, so all we
4108 have to do is replicate it as a GIMPLE_CALL tuple. */
4109 gimple_stmt_iterator gsi;
4110 call = gimple_build_call_from_tree (*expr_p, fnptrtype);
4111 notice_special_calls (call);
4112 gimplify_seq_add_stmt (pre_p, call);
4113 gsi = gsi_last (*pre_p);
4114 maybe_fold_stmt (&gsi);
4115 *expr_p = NULL_TREE;
4117 else
4118 /* Remember the original function type. */
4119 CALL_EXPR_FN (*expr_p) = build1 (NOP_EXPR, fnptrtype,
4120 CALL_EXPR_FN (*expr_p));
4122 return ret;
4125 /* Handle shortcut semantics in the predicate operand of a COND_EXPR by
4126 rewriting it into multiple COND_EXPRs, and possibly GOTO_EXPRs.
4128 TRUE_LABEL_P and FALSE_LABEL_P point to the labels to jump to if the
4129 condition is true or false, respectively. If null, we should generate
4130 our own to skip over the evaluation of this specific expression.
4132 LOCUS is the source location of the COND_EXPR.
4134 This function is the tree equivalent of do_jump.
4136 shortcut_cond_r should only be called by shortcut_cond_expr. */
4138 static tree
4139 shortcut_cond_r (tree pred, tree *true_label_p, tree *false_label_p,
4140 location_t locus)
4142 tree local_label = NULL_TREE;
4143 tree t, expr = NULL;
4145 /* OK, it's not a simple case; we need to pull apart the COND_EXPR to
4146 retain the shortcut semantics. Just insert the gotos here;
4147 shortcut_cond_expr will append the real blocks later. */
4148 if (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
4150 location_t new_locus;
4152 /* Turn if (a && b) into
4154 if (a); else goto no;
4155 if (b) goto yes; else goto no;
4156 (no:) */
4158 if (false_label_p == NULL)
4159 false_label_p = &local_label;
4161 /* Keep the original source location on the first 'if'. */
4162 t = shortcut_cond_r (TREE_OPERAND (pred, 0), NULL, false_label_p, locus);
4163 append_to_statement_list (t, &expr);
4165 /* Set the source location of the && on the second 'if'. */
4166 new_locus = rexpr_location (pred, locus);
4167 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
4168 new_locus);
4169 append_to_statement_list (t, &expr);
4171 else if (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
4173 location_t new_locus;
4175 /* Turn if (a || b) into
4177 if (a) goto yes;
4178 if (b) goto yes; else goto no;
4179 (yes:) */
4181 if (true_label_p == NULL)
4182 true_label_p = &local_label;
4184 /* Keep the original source location on the first 'if'. */
4185 t = shortcut_cond_r (TREE_OPERAND (pred, 0), true_label_p, NULL, locus);
4186 append_to_statement_list (t, &expr);
4188 /* Set the source location of the || on the second 'if'. */
4189 new_locus = rexpr_location (pred, locus);
4190 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
4191 new_locus);
4192 append_to_statement_list (t, &expr);
4194 else if (TREE_CODE (pred) == COND_EXPR
4195 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 1)))
4196 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 2))))
4198 location_t new_locus;
4200 /* As long as we're messing with gotos, turn if (a ? b : c) into
4201 if (a)
4202 if (b) goto yes; else goto no;
4203 else
4204 if (c) goto yes; else goto no;
4206 Don't do this if one of the arms has void type, which can happen
4207 in C++ when the arm is throw. */
4209 /* Keep the original source location on the first 'if'. Set the source
4210 location of the ? on the second 'if'. */
4211 new_locus = rexpr_location (pred, locus);
4212 expr = build3 (COND_EXPR, void_type_node, TREE_OPERAND (pred, 0),
4213 shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p,
4214 false_label_p, locus),
4215 shortcut_cond_r (TREE_OPERAND (pred, 2), true_label_p,
4216 false_label_p, new_locus));
4218 else
4220 expr = build3 (COND_EXPR, void_type_node, pred,
4221 build_and_jump (true_label_p),
4222 build_and_jump (false_label_p));
4223 SET_EXPR_LOCATION (expr, locus);
4226 if (local_label)
4228 t = build1 (LABEL_EXPR, void_type_node, local_label);
4229 append_to_statement_list (t, &expr);
4232 return expr;
4235 /* If EXPR is a GOTO_EXPR, return it. If it is a STATEMENT_LIST, skip
4236 any of its leading DEBUG_BEGIN_STMTS and recurse on the subsequent
4237 statement, if it is the last one. Otherwise, return NULL. */
4239 static tree
4240 find_goto (tree expr)
4242 if (!expr)
4243 return NULL_TREE;
4245 if (TREE_CODE (expr) == GOTO_EXPR)
4246 return expr;
4248 if (TREE_CODE (expr) != STATEMENT_LIST)
4249 return NULL_TREE;
4251 tree_stmt_iterator i = tsi_start (expr);
4253 while (!tsi_end_p (i) && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT)
4254 tsi_next (&i);
4256 if (!tsi_one_before_end_p (i))
4257 return NULL_TREE;
4259 return find_goto (tsi_stmt (i));
4262 /* Same as find_goto, except that it returns NULL if the destination
4263 is not a LABEL_DECL. */
4265 static inline tree
4266 find_goto_label (tree expr)
4268 tree dest = find_goto (expr);
4269 if (dest && TREE_CODE (GOTO_DESTINATION (dest)) == LABEL_DECL)
4270 return dest;
4271 return NULL_TREE;
4274 /* Given a conditional expression EXPR with short-circuit boolean
4275 predicates using TRUTH_ANDIF_EXPR or TRUTH_ORIF_EXPR, break the
4276 predicate apart into the equivalent sequence of conditionals. */
4278 static tree
4279 shortcut_cond_expr (tree expr)
4281 tree pred = TREE_OPERAND (expr, 0);
4282 tree then_ = TREE_OPERAND (expr, 1);
4283 tree else_ = TREE_OPERAND (expr, 2);
4284 tree true_label, false_label, end_label, t;
4285 tree *true_label_p;
4286 tree *false_label_p;
4287 bool emit_end, emit_false, jump_over_else;
4288 bool then_se = then_ && TREE_SIDE_EFFECTS (then_);
4289 bool else_se = else_ && TREE_SIDE_EFFECTS (else_);
4291 /* First do simple transformations. */
4292 if (!else_se)
4294 /* If there is no 'else', turn
4295 if (a && b) then c
4296 into
4297 if (a) if (b) then c. */
4298 while (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
4300 /* Keep the original source location on the first 'if'. */
4301 location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
4302 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
4303 /* Set the source location of the && on the second 'if'. */
4304 if (rexpr_has_location (pred))
4305 SET_EXPR_LOCATION (expr, rexpr_location (pred));
4306 then_ = shortcut_cond_expr (expr);
4307 then_se = then_ && TREE_SIDE_EFFECTS (then_);
4308 pred = TREE_OPERAND (pred, 0);
4309 expr = build3 (COND_EXPR, void_type_node, pred, then_, NULL_TREE);
4310 SET_EXPR_LOCATION (expr, locus);
4314 if (!then_se)
4316 /* If there is no 'then', turn
4317 if (a || b); else d
4318 into
4319 if (a); else if (b); else d. */
4320 while (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
4322 /* Keep the original source location on the first 'if'. */
4323 location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
4324 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
4325 /* Set the source location of the || on the second 'if'. */
4326 if (rexpr_has_location (pred))
4327 SET_EXPR_LOCATION (expr, rexpr_location (pred));
4328 else_ = shortcut_cond_expr (expr);
4329 else_se = else_ && TREE_SIDE_EFFECTS (else_);
4330 pred = TREE_OPERAND (pred, 0);
4331 expr = build3 (COND_EXPR, void_type_node, pred, NULL_TREE, else_);
4332 SET_EXPR_LOCATION (expr, locus);
4336 /* If we're done, great. */
4337 if (TREE_CODE (pred) != TRUTH_ANDIF_EXPR
4338 && TREE_CODE (pred) != TRUTH_ORIF_EXPR)
4339 return expr;
4341 /* Otherwise we need to mess with gotos. Change
4342 if (a) c; else d;
4344 if (a); else goto no;
4345 c; goto end;
4346 no: d; end:
4347 and recursively gimplify the condition. */
4349 true_label = false_label = end_label = NULL_TREE;
4351 /* If our arms just jump somewhere, hijack those labels so we don't
4352 generate jumps to jumps. */
4354 if (tree then_goto = find_goto_label (then_))
4356 true_label = GOTO_DESTINATION (then_goto);
4357 then_ = NULL;
4358 then_se = false;
4361 if (tree else_goto = find_goto_label (else_))
4363 false_label = GOTO_DESTINATION (else_goto);
4364 else_ = NULL;
4365 else_se = false;
4368 /* If we aren't hijacking a label for the 'then' branch, it falls through. */
4369 if (true_label)
4370 true_label_p = &true_label;
4371 else
4372 true_label_p = NULL;
4374 /* The 'else' branch also needs a label if it contains interesting code. */
4375 if (false_label || else_se)
4376 false_label_p = &false_label;
4377 else
4378 false_label_p = NULL;
4380 /* If there was nothing else in our arms, just forward the label(s). */
4381 if (!then_se && !else_se)
4382 return shortcut_cond_r (pred, true_label_p, false_label_p,
4383 EXPR_LOC_OR_LOC (expr, input_location));
4385 /* If our last subexpression already has a terminal label, reuse it. */
4386 if (else_se)
4387 t = expr_last (else_);
4388 else if (then_se)
4389 t = expr_last (then_);
4390 else
4391 t = NULL;
4392 if (t && TREE_CODE (t) == LABEL_EXPR)
4393 end_label = LABEL_EXPR_LABEL (t);
4395 /* If we don't care about jumping to the 'else' branch, jump to the end
4396 if the condition is false. */
4397 if (!false_label_p)
4398 false_label_p = &end_label;
4400 /* We only want to emit these labels if we aren't hijacking them. */
4401 emit_end = (end_label == NULL_TREE);
4402 emit_false = (false_label == NULL_TREE);
4404 /* We only emit the jump over the else clause if we have to--if the
4405 then clause may fall through. Otherwise we can wind up with a
4406 useless jump and a useless label at the end of gimplified code,
4407 which will cause us to think that this conditional as a whole
4408 falls through even if it doesn't. If we then inline a function
4409 which ends with such a condition, that can cause us to issue an
4410 inappropriate warning about control reaching the end of a
4411 non-void function. */
4412 jump_over_else = block_may_fallthru (then_);
4414 pred = shortcut_cond_r (pred, true_label_p, false_label_p,
4415 EXPR_LOC_OR_LOC (expr, input_location));
4417 expr = NULL;
4418 append_to_statement_list (pred, &expr);
4420 append_to_statement_list (then_, &expr);
4421 if (else_se)
4423 if (jump_over_else)
4425 tree last = expr_last (expr);
4426 t = build_and_jump (&end_label);
4427 if (rexpr_has_location (last))
4428 SET_EXPR_LOCATION (t, rexpr_location (last));
4429 append_to_statement_list (t, &expr);
4431 if (emit_false)
4433 t = build1 (LABEL_EXPR, void_type_node, false_label);
4434 append_to_statement_list (t, &expr);
4436 append_to_statement_list (else_, &expr);
4438 if (emit_end && end_label)
4440 t = build1 (LABEL_EXPR, void_type_node, end_label);
4441 append_to_statement_list (t, &expr);
4444 return expr;
4447 /* EXPR is used in a boolean context; make sure it has BOOLEAN_TYPE. */
4449 tree
4450 gimple_boolify (tree expr)
4452 tree type = TREE_TYPE (expr);
4453 location_t loc = EXPR_LOCATION (expr);
4455 if (TREE_CODE (expr) == NE_EXPR
4456 && TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR
4457 && integer_zerop (TREE_OPERAND (expr, 1)))
4459 tree call = TREE_OPERAND (expr, 0);
4460 tree fn = get_callee_fndecl (call);
4462 /* For __builtin_expect ((long) (x), y) recurse into x as well
4463 if x is truth_value_p. */
4464 if (fn
4465 && fndecl_built_in_p (fn, BUILT_IN_EXPECT)
4466 && call_expr_nargs (call) == 2)
4468 tree arg = CALL_EXPR_ARG (call, 0);
4469 if (arg)
4471 if (TREE_CODE (arg) == NOP_EXPR
4472 && TREE_TYPE (arg) == TREE_TYPE (call))
4473 arg = TREE_OPERAND (arg, 0);
4474 if (truth_value_p (TREE_CODE (arg)))
4476 arg = gimple_boolify (arg);
4477 CALL_EXPR_ARG (call, 0)
4478 = fold_convert_loc (loc, TREE_TYPE (call), arg);
4484 switch (TREE_CODE (expr))
4486 case TRUTH_AND_EXPR:
4487 case TRUTH_OR_EXPR:
4488 case TRUTH_XOR_EXPR:
4489 case TRUTH_ANDIF_EXPR:
4490 case TRUTH_ORIF_EXPR:
4491 /* Also boolify the arguments of truth exprs. */
4492 TREE_OPERAND (expr, 1) = gimple_boolify (TREE_OPERAND (expr, 1));
4493 /* FALLTHRU */
4495 case TRUTH_NOT_EXPR:
4496 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
4498 /* These expressions always produce boolean results. */
4499 if (TREE_CODE (type) != BOOLEAN_TYPE)
4500 TREE_TYPE (expr) = boolean_type_node;
4501 return expr;
4503 case ANNOTATE_EXPR:
4504 switch ((enum annot_expr_kind) TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)))
4506 case annot_expr_ivdep_kind:
4507 case annot_expr_unroll_kind:
4508 case annot_expr_no_vector_kind:
4509 case annot_expr_vector_kind:
4510 case annot_expr_parallel_kind:
4511 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
4512 if (TREE_CODE (type) != BOOLEAN_TYPE)
4513 TREE_TYPE (expr) = boolean_type_node;
4514 return expr;
4515 default:
4516 gcc_unreachable ();
4519 default:
4520 if (COMPARISON_CLASS_P (expr))
4522 /* These expressions always produce boolean results. */
4523 if (TREE_CODE (type) != BOOLEAN_TYPE)
4524 TREE_TYPE (expr) = boolean_type_node;
4525 return expr;
4527 /* Other expressions that get here must have boolean values, but
4528 might need to be converted to the appropriate mode. */
4529 if (TREE_CODE (type) == BOOLEAN_TYPE)
4530 return expr;
4531 return fold_convert_loc (loc, boolean_type_node, expr);
4535 /* Given a conditional expression *EXPR_P without side effects, gimplify
4536 its operands. New statements are inserted to PRE_P. */
4538 static enum gimplify_status
4539 gimplify_pure_cond_expr (tree *expr_p, gimple_seq *pre_p)
4541 tree expr = *expr_p, cond;
4542 enum gimplify_status ret, tret;
4543 enum tree_code code;
4545 cond = gimple_boolify (COND_EXPR_COND (expr));
4547 /* We need to handle && and || specially, as their gimplification
4548 creates pure cond_expr, thus leading to an infinite cycle otherwise. */
4549 code = TREE_CODE (cond);
4550 if (code == TRUTH_ANDIF_EXPR)
4551 TREE_SET_CODE (cond, TRUTH_AND_EXPR);
4552 else if (code == TRUTH_ORIF_EXPR)
4553 TREE_SET_CODE (cond, TRUTH_OR_EXPR);
4554 ret = gimplify_expr (&cond, pre_p, NULL, is_gimple_val, fb_rvalue);
4555 COND_EXPR_COND (*expr_p) = cond;
4557 tret = gimplify_expr (&COND_EXPR_THEN (expr), pre_p, NULL,
4558 is_gimple_val, fb_rvalue);
4559 ret = MIN (ret, tret);
4560 tret = gimplify_expr (&COND_EXPR_ELSE (expr), pre_p, NULL,
4561 is_gimple_val, fb_rvalue);
4563 return MIN (ret, tret);
4566 /* Return true if evaluating EXPR could trap.
4567 EXPR is GENERIC, while tree_could_trap_p can be called
4568 only on GIMPLE. */
4570 bool
4571 generic_expr_could_trap_p (tree expr)
4573 unsigned i, n;
4575 if (!expr || is_gimple_val (expr))
4576 return false;
4578 if (!EXPR_P (expr) || tree_could_trap_p (expr))
4579 return true;
4581 n = TREE_OPERAND_LENGTH (expr);
4582 for (i = 0; i < n; i++)
4583 if (generic_expr_could_trap_p (TREE_OPERAND (expr, i)))
4584 return true;
4586 return false;
4589 /* Convert the conditional expression pointed to by EXPR_P '(p) ? a : b;'
4590 into
4592 if (p) if (p)
4593 t1 = a; a;
4594 else or else
4595 t1 = b; b;
4598 The second form is used when *EXPR_P is of type void.
4600 PRE_P points to the list where side effects that must happen before
4601 *EXPR_P should be stored. */
4603 static enum gimplify_status
4604 gimplify_cond_expr (tree *expr_p, gimple_seq *pre_p, fallback_t fallback)
4606 tree expr = *expr_p;
4607 tree type = TREE_TYPE (expr);
4608 location_t loc = EXPR_LOCATION (expr);
4609 tree tmp, arm1, arm2;
4610 enum gimplify_status ret;
4611 tree label_true, label_false, label_cont;
4612 bool have_then_clause_p, have_else_clause_p;
4613 gcond *cond_stmt;
4614 enum tree_code pred_code;
4615 gimple_seq seq = NULL;
4617 /* If this COND_EXPR has a value, copy the values into a temporary within
4618 the arms. */
4619 if (!VOID_TYPE_P (type))
4621 tree then_ = TREE_OPERAND (expr, 1), else_ = TREE_OPERAND (expr, 2);
4622 tree result;
4624 /* If either an rvalue is ok or we do not require an lvalue, create the
4625 temporary. But we cannot do that if the type is addressable. */
4626 if (((fallback & fb_rvalue) || !(fallback & fb_lvalue))
4627 && !TREE_ADDRESSABLE (type))
4629 if (gimplify_ctxp->allow_rhs_cond_expr
4630 /* If either branch has side effects or could trap, it can't be
4631 evaluated unconditionally. */
4632 && !TREE_SIDE_EFFECTS (then_)
4633 && !generic_expr_could_trap_p (then_)
4634 && !TREE_SIDE_EFFECTS (else_)
4635 && !generic_expr_could_trap_p (else_))
4636 return gimplify_pure_cond_expr (expr_p, pre_p);
4638 tmp = create_tmp_var (type, "iftmp");
4639 result = tmp;
4642 /* Otherwise, only create and copy references to the values. */
4643 else
4645 type = build_pointer_type (type);
4647 if (!VOID_TYPE_P (TREE_TYPE (then_)))
4648 then_ = build_fold_addr_expr_loc (loc, then_);
4650 if (!VOID_TYPE_P (TREE_TYPE (else_)))
4651 else_ = build_fold_addr_expr_loc (loc, else_);
4653 expr
4654 = build3 (COND_EXPR, type, TREE_OPERAND (expr, 0), then_, else_);
4656 tmp = create_tmp_var (type, "iftmp");
4657 result = build_simple_mem_ref_loc (loc, tmp);
4660 /* Build the new then clause, `tmp = then_;'. But don't build the
4661 assignment if the value is void; in C++ it can be if it's a throw. */
4662 if (!VOID_TYPE_P (TREE_TYPE (then_)))
4663 TREE_OPERAND (expr, 1) = build2 (INIT_EXPR, type, tmp, then_);
4665 /* Similarly, build the new else clause, `tmp = else_;'. */
4666 if (!VOID_TYPE_P (TREE_TYPE (else_)))
4667 TREE_OPERAND (expr, 2) = build2 (INIT_EXPR, type, tmp, else_);
4669 TREE_TYPE (expr) = void_type_node;
4670 recalculate_side_effects (expr);
4672 /* Move the COND_EXPR to the prequeue. */
4673 gimplify_stmt (&expr, pre_p);
4675 *expr_p = result;
4676 return GS_ALL_DONE;
4679 /* Remove any COMPOUND_EXPR so the following cases will be caught. */
4680 STRIP_TYPE_NOPS (TREE_OPERAND (expr, 0));
4681 if (TREE_CODE (TREE_OPERAND (expr, 0)) == COMPOUND_EXPR)
4682 gimplify_compound_expr (&TREE_OPERAND (expr, 0), pre_p, true);
4684 /* Make sure the condition has BOOLEAN_TYPE. */
4685 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
4687 /* Break apart && and || conditions. */
4688 if (TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ANDIF_EXPR
4689 || TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ORIF_EXPR)
4691 expr = shortcut_cond_expr (expr);
4693 if (expr != *expr_p)
4695 *expr_p = expr;
4697 /* We can't rely on gimplify_expr to re-gimplify the expanded
4698 form properly, as cleanups might cause the target labels to be
4699 wrapped in a TRY_FINALLY_EXPR. To prevent that, we need to
4700 set up a conditional context. */
4701 gimple_push_condition ();
4702 gimplify_stmt (expr_p, &seq);
4703 gimple_pop_condition (pre_p);
4704 gimple_seq_add_seq (pre_p, seq);
4706 return GS_ALL_DONE;
4710 /* Now do the normal gimplification. */
4712 /* Gimplify condition. */
4713 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL,
4714 is_gimple_condexpr_for_cond, fb_rvalue);
4715 if (ret == GS_ERROR)
4716 return GS_ERROR;
4717 gcc_assert (TREE_OPERAND (expr, 0) != NULL_TREE);
4719 gimple_push_condition ();
4721 have_then_clause_p = have_else_clause_p = false;
4722 label_true = find_goto_label (TREE_OPERAND (expr, 1));
4723 if (label_true
4724 && DECL_CONTEXT (GOTO_DESTINATION (label_true)) == current_function_decl
4725 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4726 have different locations, otherwise we end up with incorrect
4727 location information on the branches. */
4728 && (optimize
4729 || !EXPR_HAS_LOCATION (expr)
4730 || !rexpr_has_location (label_true)
4731 || EXPR_LOCATION (expr) == rexpr_location (label_true)))
4733 have_then_clause_p = true;
4734 label_true = GOTO_DESTINATION (label_true);
4736 else
4737 label_true = create_artificial_label (UNKNOWN_LOCATION);
4738 label_false = find_goto_label (TREE_OPERAND (expr, 2));
4739 if (label_false
4740 && DECL_CONTEXT (GOTO_DESTINATION (label_false)) == current_function_decl
4741 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4742 have different locations, otherwise we end up with incorrect
4743 location information on the branches. */
4744 && (optimize
4745 || !EXPR_HAS_LOCATION (expr)
4746 || !rexpr_has_location (label_false)
4747 || EXPR_LOCATION (expr) == rexpr_location (label_false)))
4749 have_else_clause_p = true;
4750 label_false = GOTO_DESTINATION (label_false);
4752 else
4753 label_false = create_artificial_label (UNKNOWN_LOCATION);
4755 gimple_cond_get_ops_from_tree (COND_EXPR_COND (expr), &pred_code, &arm1,
4756 &arm2);
4757 cond_stmt = gimple_build_cond (pred_code, arm1, arm2, label_true,
4758 label_false);
4759 gimple_set_location (cond_stmt, EXPR_LOCATION (expr));
4760 copy_warning (cond_stmt, COND_EXPR_COND (expr));
4761 gimplify_seq_add_stmt (&seq, cond_stmt);
4762 gimple_stmt_iterator gsi = gsi_last (seq);
4763 maybe_fold_stmt (&gsi);
4765 label_cont = NULL_TREE;
4766 if (!have_then_clause_p)
4768 /* For if (...) {} else { code; } put label_true after
4769 the else block. */
4770 if (TREE_OPERAND (expr, 1) == NULL_TREE
4771 && !have_else_clause_p
4772 && TREE_OPERAND (expr, 2) != NULL_TREE)
4774 /* For if (0) {} else { code; } tell -Wimplicit-fallthrough
4775 handling that label_cont == label_true can be only reached
4776 through fallthrough from { code; }. */
4777 if (integer_zerop (COND_EXPR_COND (expr)))
4778 UNUSED_LABEL_P (label_true) = 1;
4779 label_cont = label_true;
4781 else
4783 bool then_side_effects
4784 = (TREE_OPERAND (expr, 1)
4785 && TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)));
4786 gimplify_seq_add_stmt (&seq, gimple_build_label (label_true));
4787 have_then_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 1), &seq);
4788 /* For if (...) { code; } else {} or
4789 if (...) { code; } else goto label; or
4790 if (...) { code; return; } else { ... }
4791 label_cont isn't needed. */
4792 if (!have_else_clause_p
4793 && TREE_OPERAND (expr, 2) != NULL_TREE
4794 && gimple_seq_may_fallthru (seq))
4796 gimple *g;
4797 label_cont = create_artificial_label (UNKNOWN_LOCATION);
4799 /* For if (0) { non-side-effect-code } else { code }
4800 tell -Wimplicit-fallthrough handling that label_cont can
4801 be only reached through fallthrough from { code }. */
4802 if (integer_zerop (COND_EXPR_COND (expr)))
4804 UNUSED_LABEL_P (label_true) = 1;
4805 if (!then_side_effects)
4806 UNUSED_LABEL_P (label_cont) = 1;
4809 g = gimple_build_goto (label_cont);
4811 /* GIMPLE_COND's are very low level; they have embedded
4812 gotos. This particular embedded goto should not be marked
4813 with the location of the original COND_EXPR, as it would
4814 correspond to the COND_EXPR's condition, not the ELSE or the
4815 THEN arms. To avoid marking it with the wrong location, flag
4816 it as "no location". */
4817 gimple_set_do_not_emit_location (g);
4819 gimplify_seq_add_stmt (&seq, g);
4823 if (!have_else_clause_p)
4825 /* For if (1) { code } or if (1) { code } else { non-side-effect-code }
4826 tell -Wimplicit-fallthrough handling that label_false can be only
4827 reached through fallthrough from { code }. */
4828 if (integer_nonzerop (COND_EXPR_COND (expr))
4829 && (TREE_OPERAND (expr, 2) == NULL_TREE
4830 || !TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 2))))
4831 UNUSED_LABEL_P (label_false) = 1;
4832 gimplify_seq_add_stmt (&seq, gimple_build_label (label_false));
4833 have_else_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 2), &seq);
4835 if (label_cont)
4836 gimplify_seq_add_stmt (&seq, gimple_build_label (label_cont));
4838 gimple_pop_condition (pre_p);
4839 gimple_seq_add_seq (pre_p, seq);
4841 if (ret == GS_ERROR)
4842 ; /* Do nothing. */
4843 else if (have_then_clause_p || have_else_clause_p)
4844 ret = GS_ALL_DONE;
4845 else
4847 /* Both arms are empty; replace the COND_EXPR with its predicate. */
4848 expr = TREE_OPERAND (expr, 0);
4849 gimplify_stmt (&expr, pre_p);
4852 *expr_p = NULL;
4853 return ret;
4856 /* Prepare the node pointed to by EXPR_P, an is_gimple_addressable expression,
4857 to be marked addressable.
4859 We cannot rely on such an expression being directly markable if a temporary
4860 has been created by the gimplification. In this case, we create another
4861 temporary and initialize it with a copy, which will become a store after we
4862 mark it addressable. This can happen if the front-end passed us something
4863 that it could not mark addressable yet, like a Fortran pass-by-reference
4864 parameter (int) floatvar. */
4866 static void
4867 prepare_gimple_addressable (tree *expr_p, gimple_seq *seq_p)
4869 while (handled_component_p (*expr_p))
4870 expr_p = &TREE_OPERAND (*expr_p, 0);
4872 /* Do not allow an SSA name as the temporary. */
4873 if (is_gimple_reg (*expr_p))
4874 *expr_p = internal_get_tmp_var (*expr_p, seq_p, NULL, false, false, true);
4877 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4878 a call to __builtin_memcpy. */
4880 static enum gimplify_status
4881 gimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value,
4882 gimple_seq *seq_p)
4884 tree t, to, to_ptr, from, from_ptr;
4885 gcall *gs;
4886 location_t loc = EXPR_LOCATION (*expr_p);
4888 to = TREE_OPERAND (*expr_p, 0);
4889 from = TREE_OPERAND (*expr_p, 1);
4890 gcc_assert (ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (to)))
4891 && ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (from))));
4893 /* Mark the RHS addressable. Beware that it may not be possible to do so
4894 directly if a temporary has been created by the gimplification. */
4895 prepare_gimple_addressable (&from, seq_p);
4897 mark_addressable (from);
4898 from_ptr = build_fold_addr_expr_loc (loc, from);
4899 gimplify_arg (&from_ptr, seq_p, loc);
4901 mark_addressable (to);
4902 to_ptr = build_fold_addr_expr_loc (loc, to);
4903 gimplify_arg (&to_ptr, seq_p, loc);
4905 t = builtin_decl_implicit (BUILT_IN_MEMCPY);
4907 gs = gimple_build_call (t, 3, to_ptr, from_ptr, size);
4908 gimple_call_set_alloca_for_var (gs, true);
4910 if (want_value)
4912 /* tmp = memcpy() */
4913 t = create_tmp_var (TREE_TYPE (to_ptr));
4914 gimple_call_set_lhs (gs, t);
4915 gimplify_seq_add_stmt (seq_p, gs);
4917 *expr_p = build_simple_mem_ref (t);
4918 return GS_ALL_DONE;
4921 gimplify_seq_add_stmt (seq_p, gs);
4922 *expr_p = NULL;
4923 return GS_ALL_DONE;
4926 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4927 a call to __builtin_memset. In this case we know that the RHS is
4928 a CONSTRUCTOR with an empty element list. */
4930 static enum gimplify_status
4931 gimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value,
4932 gimple_seq *seq_p)
4934 tree t, from, to, to_ptr;
4935 gcall *gs;
4936 location_t loc = EXPR_LOCATION (*expr_p);
4938 /* Assert our assumptions, to abort instead of producing wrong code
4939 silently if they are not met. Beware that the RHS CONSTRUCTOR might
4940 not be immediately exposed. */
4941 from = TREE_OPERAND (*expr_p, 1);
4942 if (TREE_CODE (from) == WITH_SIZE_EXPR)
4943 from = TREE_OPERAND (from, 0);
4945 gcc_assert (TREE_CODE (from) == CONSTRUCTOR
4946 && vec_safe_is_empty (CONSTRUCTOR_ELTS (from)));
4948 /* Now proceed. */
4949 to = TREE_OPERAND (*expr_p, 0);
4950 gcc_assert (ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (to))));
4952 to_ptr = build_fold_addr_expr_loc (loc, to);
4953 gimplify_arg (&to_ptr, seq_p, loc);
4954 t = builtin_decl_implicit (BUILT_IN_MEMSET);
4956 gs = gimple_build_call (t, 3, to_ptr, integer_zero_node, size);
4958 if (want_value)
4960 /* tmp = memset() */
4961 t = create_tmp_var (TREE_TYPE (to_ptr));
4962 gimple_call_set_lhs (gs, t);
4963 gimplify_seq_add_stmt (seq_p, gs);
4965 *expr_p = build1 (INDIRECT_REF, TREE_TYPE (to), t);
4966 return GS_ALL_DONE;
4969 gimplify_seq_add_stmt (seq_p, gs);
4970 *expr_p = NULL;
4971 return GS_ALL_DONE;
4974 /* A subroutine of gimplify_init_ctor_preeval. Called via walk_tree,
4975 determine, cautiously, if a CONSTRUCTOR overlaps the lhs of an
4976 assignment. Return non-null if we detect a potential overlap. */
4978 struct gimplify_init_ctor_preeval_data
4980 /* The base decl of the lhs object. May be NULL, in which case we
4981 have to assume the lhs is indirect. */
4982 tree lhs_base_decl;
4984 /* The alias set of the lhs object. */
4985 alias_set_type lhs_alias_set;
4988 static tree
4989 gimplify_init_ctor_preeval_1 (tree *tp, int *walk_subtrees, void *xdata)
4991 struct gimplify_init_ctor_preeval_data *data
4992 = (struct gimplify_init_ctor_preeval_data *) xdata;
4993 tree t = *tp;
4995 /* If we find the base object, obviously we have overlap. */
4996 if (data->lhs_base_decl == t)
4997 return t;
4999 /* If the constructor component is indirect, determine if we have a
5000 potential overlap with the lhs. The only bits of information we
5001 have to go on at this point are addressability and alias sets. */
5002 if ((INDIRECT_REF_P (t)
5003 || TREE_CODE (t) == MEM_REF)
5004 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
5005 && alias_sets_conflict_p (data->lhs_alias_set, get_alias_set (t)))
5006 return t;
5008 /* If the constructor component is a call, determine if it can hide a
5009 potential overlap with the lhs through an INDIRECT_REF like above.
5010 ??? Ugh - this is completely broken. In fact this whole analysis
5011 doesn't look conservative. */
5012 if (TREE_CODE (t) == CALL_EXPR)
5014 tree type, fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (t)));
5016 for (type = TYPE_ARG_TYPES (fntype); type; type = TREE_CHAIN (type))
5017 if (POINTER_TYPE_P (TREE_VALUE (type))
5018 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
5019 && alias_sets_conflict_p (data->lhs_alias_set,
5020 get_alias_set
5021 (TREE_TYPE (TREE_VALUE (type)))))
5022 return t;
5025 if (IS_TYPE_OR_DECL_P (t))
5026 *walk_subtrees = 0;
5027 return NULL;
5030 /* A subroutine of gimplify_init_constructor. Pre-evaluate EXPR,
5031 force values that overlap with the lhs (as described by *DATA)
5032 into temporaries. */
5034 static void
5035 gimplify_init_ctor_preeval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
5036 struct gimplify_init_ctor_preeval_data *data)
5038 enum gimplify_status one;
5040 /* If the value is constant, then there's nothing to pre-evaluate. */
5041 if (TREE_CONSTANT (*expr_p))
5043 /* Ensure it does not have side effects, it might contain a reference to
5044 the object we're initializing. */
5045 gcc_assert (!TREE_SIDE_EFFECTS (*expr_p));
5046 return;
5049 /* If the type has non-trivial constructors, we can't pre-evaluate. */
5050 if (TREE_ADDRESSABLE (TREE_TYPE (*expr_p)))
5051 return;
5053 /* Recurse for nested constructors. */
5054 if (TREE_CODE (*expr_p) == CONSTRUCTOR)
5056 unsigned HOST_WIDE_INT ix;
5057 constructor_elt *ce;
5058 vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (*expr_p);
5060 FOR_EACH_VEC_SAFE_ELT (v, ix, ce)
5061 gimplify_init_ctor_preeval (&ce->value, pre_p, post_p, data);
5063 return;
5066 /* If this is a variable sized type, we must remember the size. */
5067 maybe_with_size_expr (expr_p);
5069 /* Gimplify the constructor element to something appropriate for the rhs
5070 of a MODIFY_EXPR. Given that we know the LHS is an aggregate, we know
5071 the gimplifier will consider this a store to memory. Doing this
5072 gimplification now means that we won't have to deal with complicated
5073 language-specific trees, nor trees like SAVE_EXPR that can induce
5074 exponential search behavior. */
5075 one = gimplify_expr (expr_p, pre_p, post_p, is_gimple_mem_rhs, fb_rvalue);
5076 if (one == GS_ERROR)
5078 *expr_p = NULL;
5079 return;
5082 /* If we gimplified to a bare decl, we can be sure that it doesn't overlap
5083 with the lhs, since "a = { .x=a }" doesn't make sense. This will
5084 always be true for all scalars, since is_gimple_mem_rhs insists on a
5085 temporary variable for them. */
5086 if (DECL_P (*expr_p))
5087 return;
5089 /* If this is of variable size, we have no choice but to assume it doesn't
5090 overlap since we can't make a temporary for it. */
5091 if (TREE_CODE (TYPE_SIZE (TREE_TYPE (*expr_p))) != INTEGER_CST)
5092 return;
5094 /* Otherwise, we must search for overlap ... */
5095 if (!walk_tree (expr_p, gimplify_init_ctor_preeval_1, data, NULL))
5096 return;
5098 /* ... and if found, force the value into a temporary. */
5099 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
5102 /* A subroutine of gimplify_init_ctor_eval. Create a loop for
5103 a RANGE_EXPR in a CONSTRUCTOR for an array.
5105 var = lower;
5106 loop_entry:
5107 object[var] = value;
5108 if (var == upper)
5109 goto loop_exit;
5110 var = var + 1;
5111 goto loop_entry;
5112 loop_exit:
5114 We increment var _after_ the loop exit check because we might otherwise
5115 fail if upper == TYPE_MAX_VALUE (type for upper).
5117 Note that we never have to deal with SAVE_EXPRs here, because this has
5118 already been taken care of for us, in gimplify_init_ctor_preeval(). */
5120 static void gimplify_init_ctor_eval (tree, vec<constructor_elt, va_gc> *,
5121 gimple_seq *, bool);
5123 static void
5124 gimplify_init_ctor_eval_range (tree object, tree lower, tree upper,
5125 tree value, tree array_elt_type,
5126 gimple_seq *pre_p, bool cleared)
5128 tree loop_entry_label, loop_exit_label, fall_thru_label;
5129 tree var, var_type, cref, tmp;
5131 loop_entry_label = create_artificial_label (UNKNOWN_LOCATION);
5132 loop_exit_label = create_artificial_label (UNKNOWN_LOCATION);
5133 fall_thru_label = create_artificial_label (UNKNOWN_LOCATION);
5135 /* Create and initialize the index variable. */
5136 var_type = TREE_TYPE (upper);
5137 var = create_tmp_var (var_type);
5138 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, lower));
5140 /* Add the loop entry label. */
5141 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_entry_label));
5143 /* Build the reference. */
5144 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
5145 var, NULL_TREE, NULL_TREE);
5147 /* If we are a constructor, just call gimplify_init_ctor_eval to do
5148 the store. Otherwise just assign value to the reference. */
5150 if (TREE_CODE (value) == CONSTRUCTOR)
5151 /* NB we might have to call ourself recursively through
5152 gimplify_init_ctor_eval if the value is a constructor. */
5153 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
5154 pre_p, cleared);
5155 else
5157 if (gimplify_expr (&value, pre_p, NULL, is_gimple_val, fb_rvalue)
5158 != GS_ERROR)
5159 gimplify_seq_add_stmt (pre_p, gimple_build_assign (cref, value));
5162 /* We exit the loop when the index var is equal to the upper bound. */
5163 gimplify_seq_add_stmt (pre_p,
5164 gimple_build_cond (EQ_EXPR, var, upper,
5165 loop_exit_label, fall_thru_label));
5167 gimplify_seq_add_stmt (pre_p, gimple_build_label (fall_thru_label));
5169 /* Otherwise, increment the index var... */
5170 tmp = build2 (PLUS_EXPR, var_type, var,
5171 fold_convert (var_type, integer_one_node));
5172 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, tmp));
5174 /* ...and jump back to the loop entry. */
5175 gimplify_seq_add_stmt (pre_p, gimple_build_goto (loop_entry_label));
5177 /* Add the loop exit label. */
5178 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_exit_label));
5181 /* A subroutine of gimplify_init_constructor. Generate individual
5182 MODIFY_EXPRs for a CONSTRUCTOR. OBJECT is the LHS against which the
5183 assignments should happen. ELTS is the CONSTRUCTOR_ELTS of the
5184 CONSTRUCTOR. CLEARED is true if the entire LHS object has been
5185 zeroed first. */
5187 static void
5188 gimplify_init_ctor_eval (tree object, vec<constructor_elt, va_gc> *elts,
5189 gimple_seq *pre_p, bool cleared)
5191 tree array_elt_type = NULL;
5192 unsigned HOST_WIDE_INT ix;
5193 tree purpose, value;
5195 if (TREE_CODE (TREE_TYPE (object)) == ARRAY_TYPE)
5196 array_elt_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (object)));
5198 FOR_EACH_CONSTRUCTOR_ELT (elts, ix, purpose, value)
5200 tree cref;
5202 /* NULL values are created above for gimplification errors. */
5203 if (value == NULL)
5204 continue;
5206 if (cleared && initializer_zerop (value))
5207 continue;
5209 /* ??? Here's to hoping the front end fills in all of the indices,
5210 so we don't have to figure out what's missing ourselves. */
5211 gcc_assert (purpose);
5213 /* Skip zero-sized fields, unless value has side-effects. This can
5214 happen with calls to functions returning a empty type, which
5215 we shouldn't discard. As a number of downstream passes don't
5216 expect sets of empty type fields, we rely on the gimplification of
5217 the MODIFY_EXPR we make below to drop the assignment statement. */
5218 if (!TREE_SIDE_EFFECTS (value)
5219 && TREE_CODE (purpose) == FIELD_DECL
5220 && is_empty_type (TREE_TYPE (purpose)))
5221 continue;
5223 /* If we have a RANGE_EXPR, we have to build a loop to assign the
5224 whole range. */
5225 if (TREE_CODE (purpose) == RANGE_EXPR)
5227 tree lower = TREE_OPERAND (purpose, 0);
5228 tree upper = TREE_OPERAND (purpose, 1);
5230 /* If the lower bound is equal to upper, just treat it as if
5231 upper was the index. */
5232 if (simple_cst_equal (lower, upper))
5233 purpose = upper;
5234 else
5236 gimplify_init_ctor_eval_range (object, lower, upper, value,
5237 array_elt_type, pre_p, cleared);
5238 continue;
5242 if (array_elt_type)
5244 /* Do not use bitsizetype for ARRAY_REF indices. */
5245 if (TYPE_DOMAIN (TREE_TYPE (object)))
5246 purpose
5247 = fold_convert (TREE_TYPE (TYPE_DOMAIN (TREE_TYPE (object))),
5248 purpose);
5249 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
5250 purpose, NULL_TREE, NULL_TREE);
5252 else
5254 gcc_assert (TREE_CODE (purpose) == FIELD_DECL);
5255 cref = build3 (COMPONENT_REF, TREE_TYPE (purpose),
5256 unshare_expr (object), purpose, NULL_TREE);
5259 if (TREE_CODE (value) == CONSTRUCTOR
5260 && TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE)
5261 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
5262 pre_p, cleared);
5263 else
5265 tree init = build2 (INIT_EXPR, TREE_TYPE (cref), cref, value);
5266 gimplify_and_add (init, pre_p);
5267 ggc_free (init);
5272 /* Return the appropriate RHS predicate for this LHS. */
5274 gimple_predicate
5275 rhs_predicate_for (tree lhs)
5277 if (is_gimple_reg (lhs))
5278 return is_gimple_reg_rhs_or_call;
5279 else
5280 return is_gimple_mem_rhs_or_call;
5283 /* Return the initial guess for an appropriate RHS predicate for this LHS,
5284 before the LHS has been gimplified. */
5286 static gimple_predicate
5287 initial_rhs_predicate_for (tree lhs)
5289 if (is_gimple_reg_type (TREE_TYPE (lhs)))
5290 return is_gimple_reg_rhs_or_call;
5291 else
5292 return is_gimple_mem_rhs_or_call;
5295 /* Gimplify a C99 compound literal expression. This just means adding
5296 the DECL_EXPR before the current statement and using its anonymous
5297 decl instead. */
5299 static enum gimplify_status
5300 gimplify_compound_literal_expr (tree *expr_p, gimple_seq *pre_p,
5301 bool (*gimple_test_f) (tree),
5302 fallback_t fallback)
5304 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (*expr_p);
5305 tree decl = DECL_EXPR_DECL (decl_s);
5306 tree init = DECL_INITIAL (decl);
5307 /* Mark the decl as addressable if the compound literal
5308 expression is addressable now, otherwise it is marked too late
5309 after we gimplify the initialization expression. */
5310 if (TREE_ADDRESSABLE (*expr_p))
5311 TREE_ADDRESSABLE (decl) = 1;
5312 /* Otherwise, if we don't need an lvalue and have a literal directly
5313 substitute it. Check if it matches the gimple predicate, as
5314 otherwise we'd generate a new temporary, and we can as well just
5315 use the decl we already have. */
5316 else if (!TREE_ADDRESSABLE (decl)
5317 && !TREE_THIS_VOLATILE (decl)
5318 && init
5319 && (fallback & fb_lvalue) == 0
5320 && gimple_test_f (init))
5322 *expr_p = init;
5323 return GS_OK;
5326 /* If the decl is not addressable, then it is being used in some
5327 expression or on the right hand side of a statement, and it can
5328 be put into a readonly data section. */
5329 if (!TREE_ADDRESSABLE (decl) && (fallback & fb_lvalue) == 0)
5330 TREE_READONLY (decl) = 1;
5332 /* This decl isn't mentioned in the enclosing block, so add it to the
5333 list of temps. FIXME it seems a bit of a kludge to say that
5334 anonymous artificial vars aren't pushed, but everything else is. */
5335 if (DECL_NAME (decl) == NULL_TREE && !DECL_SEEN_IN_BIND_EXPR_P (decl))
5336 gimple_add_tmp_var (decl);
5338 gimplify_and_add (decl_s, pre_p);
5339 *expr_p = decl;
5340 return GS_OK;
5343 /* Optimize embedded COMPOUND_LITERAL_EXPRs within a CONSTRUCTOR,
5344 return a new CONSTRUCTOR if something changed. */
5346 static tree
5347 optimize_compound_literals_in_ctor (tree orig_ctor)
5349 tree ctor = orig_ctor;
5350 vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ctor);
5351 unsigned int idx, num = vec_safe_length (elts);
5353 for (idx = 0; idx < num; idx++)
5355 tree value = (*elts)[idx].value;
5356 tree newval = value;
5357 if (TREE_CODE (value) == CONSTRUCTOR)
5358 newval = optimize_compound_literals_in_ctor (value);
5359 else if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR)
5361 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (value);
5362 tree decl = DECL_EXPR_DECL (decl_s);
5363 tree init = DECL_INITIAL (decl);
5365 if (!TREE_ADDRESSABLE (value)
5366 && !TREE_ADDRESSABLE (decl)
5367 && init
5368 && TREE_CODE (init) == CONSTRUCTOR)
5369 newval = optimize_compound_literals_in_ctor (init);
5371 if (newval == value)
5372 continue;
5374 if (ctor == orig_ctor)
5376 ctor = copy_node (orig_ctor);
5377 CONSTRUCTOR_ELTS (ctor) = vec_safe_copy (elts);
5378 elts = CONSTRUCTOR_ELTS (ctor);
5380 (*elts)[idx].value = newval;
5382 return ctor;
5385 /* A subroutine of gimplify_modify_expr. Break out elements of a
5386 CONSTRUCTOR used as an initializer into separate MODIFY_EXPRs.
5388 Note that we still need to clear any elements that don't have explicit
5389 initializers, so if not all elements are initialized we keep the
5390 original MODIFY_EXPR, we just remove all of the constructor elements.
5392 If NOTIFY_TEMP_CREATION is true, do not gimplify, just return
5393 GS_ERROR if we would have to create a temporary when gimplifying
5394 this constructor. Otherwise, return GS_OK.
5396 If NOTIFY_TEMP_CREATION is false, just do the gimplification. */
5398 static enum gimplify_status
5399 gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
5400 bool want_value, bool notify_temp_creation)
5402 tree object, ctor, type;
5403 enum gimplify_status ret;
5404 vec<constructor_elt, va_gc> *elts;
5405 bool cleared = false;
5406 bool is_empty_ctor = false;
5407 bool is_init_expr = (TREE_CODE (*expr_p) == INIT_EXPR);
5409 gcc_assert (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == CONSTRUCTOR);
5411 if (!notify_temp_creation)
5413 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
5414 is_gimple_lvalue, fb_lvalue);
5415 if (ret == GS_ERROR)
5416 return ret;
5419 object = TREE_OPERAND (*expr_p, 0);
5420 ctor = TREE_OPERAND (*expr_p, 1)
5421 = optimize_compound_literals_in_ctor (TREE_OPERAND (*expr_p, 1));
5422 type = TREE_TYPE (ctor);
5423 elts = CONSTRUCTOR_ELTS (ctor);
5424 ret = GS_ALL_DONE;
5426 switch (TREE_CODE (type))
5428 case RECORD_TYPE:
5429 case UNION_TYPE:
5430 case QUAL_UNION_TYPE:
5431 case ARRAY_TYPE:
5433 /* Use readonly data for initializers of this or smaller size
5434 regardless of the num_nonzero_elements / num_unique_nonzero_elements
5435 ratio. */
5436 const HOST_WIDE_INT min_unique_size = 64;
5437 /* If num_nonzero_elements / num_unique_nonzero_elements ratio
5438 is smaller than this, use readonly data. */
5439 const int unique_nonzero_ratio = 8;
5440 /* True if a single access of the object must be ensured. This is the
5441 case if the target is volatile, the type is non-addressable and more
5442 than one field need to be assigned. */
5443 const bool ensure_single_access
5444 = TREE_THIS_VOLATILE (object)
5445 && !TREE_ADDRESSABLE (type)
5446 && vec_safe_length (elts) > 1;
5447 struct gimplify_init_ctor_preeval_data preeval_data;
5448 HOST_WIDE_INT num_ctor_elements, num_nonzero_elements;
5449 HOST_WIDE_INT num_unique_nonzero_elements;
5450 bool complete_p, valid_const_initializer;
5452 /* Aggregate types must lower constructors to initialization of
5453 individual elements. The exception is that a CONSTRUCTOR node
5454 with no elements indicates zero-initialization of the whole. */
5455 if (vec_safe_is_empty (elts))
5457 if (notify_temp_creation)
5458 return GS_OK;
5460 /* The var will be initialized and so appear on lhs of
5461 assignment, it can't be TREE_READONLY anymore. */
5462 if (VAR_P (object))
5463 TREE_READONLY (object) = 0;
5465 is_empty_ctor = true;
5466 break;
5469 /* Fetch information about the constructor to direct later processing.
5470 We might want to make static versions of it in various cases, and
5471 can only do so if it known to be a valid constant initializer. */
5472 valid_const_initializer
5473 = categorize_ctor_elements (ctor, &num_nonzero_elements,
5474 &num_unique_nonzero_elements,
5475 &num_ctor_elements, &complete_p);
5477 /* If a const aggregate variable is being initialized, then it
5478 should never be a lose to promote the variable to be static. */
5479 if (valid_const_initializer
5480 && num_nonzero_elements > 1
5481 && TREE_READONLY (object)
5482 && VAR_P (object)
5483 && !DECL_REGISTER (object)
5484 && (flag_merge_constants >= 2 || !TREE_ADDRESSABLE (object)
5485 || DECL_MERGEABLE (object))
5486 /* For ctors that have many repeated nonzero elements
5487 represented through RANGE_EXPRs, prefer initializing
5488 those through runtime loops over copies of large amounts
5489 of data from readonly data section. */
5490 && (num_unique_nonzero_elements
5491 > num_nonzero_elements / unique_nonzero_ratio
5492 || ((unsigned HOST_WIDE_INT) int_size_in_bytes (type)
5493 <= (unsigned HOST_WIDE_INT) min_unique_size)))
5495 if (notify_temp_creation)
5496 return GS_ERROR;
5498 DECL_INITIAL (object) = ctor;
5499 TREE_STATIC (object) = 1;
5500 if (!DECL_NAME (object))
5501 DECL_NAME (object) = create_tmp_var_name ("C");
5502 walk_tree (&DECL_INITIAL (object), force_labels_r, NULL, NULL);
5504 /* ??? C++ doesn't automatically append a .<number> to the
5505 assembler name, and even when it does, it looks at FE private
5506 data structures to figure out what that number should be,
5507 which are not set for this variable. I suppose this is
5508 important for local statics for inline functions, which aren't
5509 "local" in the object file sense. So in order to get a unique
5510 TU-local symbol, we must invoke the lhd version now. */
5511 lhd_set_decl_assembler_name (object);
5513 *expr_p = NULL_TREE;
5514 break;
5517 /* The var will be initialized and so appear on lhs of
5518 assignment, it can't be TREE_READONLY anymore. */
5519 if (VAR_P (object) && !notify_temp_creation)
5520 TREE_READONLY (object) = 0;
5522 /* If there are "lots" of initialized elements, even discounting
5523 those that are not address constants (and thus *must* be
5524 computed at runtime), then partition the constructor into
5525 constant and non-constant parts. Block copy the constant
5526 parts in, then generate code for the non-constant parts. */
5527 /* TODO. There's code in cp/typeck.cc to do this. */
5529 if (int_size_in_bytes (TREE_TYPE (ctor)) < 0)
5530 /* store_constructor will ignore the clearing of variable-sized
5531 objects. Initializers for such objects must explicitly set
5532 every field that needs to be set. */
5533 cleared = false;
5534 else if (!complete_p)
5535 /* If the constructor isn't complete, clear the whole object
5536 beforehand, unless CONSTRUCTOR_NO_CLEARING is set on it.
5538 ??? This ought not to be needed. For any element not present
5539 in the initializer, we should simply set them to zero. Except
5540 we'd need to *find* the elements that are not present, and that
5541 requires trickery to avoid quadratic compile-time behavior in
5542 large cases or excessive memory use in small cases. */
5543 cleared = !CONSTRUCTOR_NO_CLEARING (ctor);
5544 else if (num_ctor_elements - num_nonzero_elements
5545 > CLEAR_RATIO (optimize_function_for_speed_p (cfun))
5546 && num_nonzero_elements < num_ctor_elements / 4)
5547 /* If there are "lots" of zeros, it's more efficient to clear
5548 the memory and then set the nonzero elements. */
5549 cleared = true;
5550 else if (ensure_single_access && num_nonzero_elements == 0)
5551 /* If a single access to the target must be ensured and all elements
5552 are zero, then it's optimal to clear whatever their number. */
5553 cleared = true;
5554 else
5555 cleared = false;
5557 /* If there are "lots" of initialized elements, and all of them
5558 are valid address constants, then the entire initializer can
5559 be dropped to memory, and then memcpy'd out. Don't do this
5560 for sparse arrays, though, as it's more efficient to follow
5561 the standard CONSTRUCTOR behavior of memset followed by
5562 individual element initialization. Also don't do this for small
5563 all-zero initializers (which aren't big enough to merit
5564 clearing), and don't try to make bitwise copies of
5565 TREE_ADDRESSABLE types. */
5566 if (valid_const_initializer
5567 && complete_p
5568 && !(cleared || num_nonzero_elements == 0)
5569 && !TREE_ADDRESSABLE (type))
5571 HOST_WIDE_INT size = int_size_in_bytes (type);
5572 unsigned int align;
5574 /* ??? We can still get unbounded array types, at least
5575 from the C++ front end. This seems wrong, but attempt
5576 to work around it for now. */
5577 if (size < 0)
5579 size = int_size_in_bytes (TREE_TYPE (object));
5580 if (size >= 0)
5581 TREE_TYPE (ctor) = type = TREE_TYPE (object);
5584 /* Find the maximum alignment we can assume for the object. */
5585 /* ??? Make use of DECL_OFFSET_ALIGN. */
5586 if (DECL_P (object))
5587 align = DECL_ALIGN (object);
5588 else
5589 align = TYPE_ALIGN (type);
5591 /* Do a block move either if the size is so small as to make
5592 each individual move a sub-unit move on average, or if it
5593 is so large as to make individual moves inefficient. */
5594 if (size > 0
5595 && num_nonzero_elements > 1
5596 /* For ctors that have many repeated nonzero elements
5597 represented through RANGE_EXPRs, prefer initializing
5598 those through runtime loops over copies of large amounts
5599 of data from readonly data section. */
5600 && (num_unique_nonzero_elements
5601 > num_nonzero_elements / unique_nonzero_ratio
5602 || size <= min_unique_size)
5603 && (size < num_nonzero_elements
5604 || !can_move_by_pieces (size, align)))
5606 if (notify_temp_creation)
5607 return GS_ERROR;
5609 walk_tree (&ctor, force_labels_r, NULL, NULL);
5610 ctor = tree_output_constant_def (ctor);
5611 if (!useless_type_conversion_p (type, TREE_TYPE (ctor)))
5612 ctor = build1 (VIEW_CONVERT_EXPR, type, ctor);
5613 TREE_OPERAND (*expr_p, 1) = ctor;
5615 /* This is no longer an assignment of a CONSTRUCTOR, but
5616 we still may have processing to do on the LHS. So
5617 pretend we didn't do anything here to let that happen. */
5618 return GS_UNHANDLED;
5622 /* If a single access to the target must be ensured and there are
5623 nonzero elements or the zero elements are not assigned en masse,
5624 initialize the target from a temporary. */
5625 if (ensure_single_access && (num_nonzero_elements > 0 || !cleared))
5627 if (notify_temp_creation)
5628 return GS_ERROR;
5630 tree temp = create_tmp_var (TYPE_MAIN_VARIANT (type));
5631 TREE_OPERAND (*expr_p, 0) = temp;
5632 *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p),
5633 *expr_p,
5634 build2 (MODIFY_EXPR, void_type_node,
5635 object, temp));
5636 return GS_OK;
5639 if (notify_temp_creation)
5640 return GS_OK;
5642 /* If there are nonzero elements and if needed, pre-evaluate to capture
5643 elements overlapping with the lhs into temporaries. We must do this
5644 before clearing to fetch the values before they are zeroed-out. */
5645 if (num_nonzero_elements > 0 && TREE_CODE (*expr_p) != INIT_EXPR)
5647 preeval_data.lhs_base_decl = get_base_address (object);
5648 if (!DECL_P (preeval_data.lhs_base_decl))
5649 preeval_data.lhs_base_decl = NULL;
5650 preeval_data.lhs_alias_set = get_alias_set (object);
5652 gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p, 1),
5653 pre_p, post_p, &preeval_data);
5656 bool ctor_has_side_effects_p
5657 = TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p, 1));
5659 if (cleared)
5661 /* Zap the CONSTRUCTOR element list, which simplifies this case.
5662 Note that we still have to gimplify, in order to handle the
5663 case of variable sized types. Avoid shared tree structures. */
5664 CONSTRUCTOR_ELTS (ctor) = NULL;
5665 TREE_SIDE_EFFECTS (ctor) = 0;
5666 object = unshare_expr (object);
5667 gimplify_stmt (expr_p, pre_p);
5670 /* If we have not block cleared the object, or if there are nonzero
5671 elements in the constructor, or if the constructor has side effects,
5672 add assignments to the individual scalar fields of the object. */
5673 if (!cleared
5674 || num_nonzero_elements > 0
5675 || ctor_has_side_effects_p)
5676 gimplify_init_ctor_eval (object, elts, pre_p, cleared);
5678 *expr_p = NULL_TREE;
5680 break;
5682 case COMPLEX_TYPE:
5684 tree r, i;
5686 if (notify_temp_creation)
5687 return GS_OK;
5689 /* Extract the real and imaginary parts out of the ctor. */
5690 gcc_assert (elts->length () == 2);
5691 r = (*elts)[0].value;
5692 i = (*elts)[1].value;
5693 if (r == NULL || i == NULL)
5695 tree zero = build_zero_cst (TREE_TYPE (type));
5696 if (r == NULL)
5697 r = zero;
5698 if (i == NULL)
5699 i = zero;
5702 /* Complex types have either COMPLEX_CST or COMPLEX_EXPR to
5703 represent creation of a complex value. */
5704 if (TREE_CONSTANT (r) && TREE_CONSTANT (i))
5706 ctor = build_complex (type, r, i);
5707 TREE_OPERAND (*expr_p, 1) = ctor;
5709 else
5711 ctor = build2 (COMPLEX_EXPR, type, r, i);
5712 TREE_OPERAND (*expr_p, 1) = ctor;
5713 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 1),
5714 pre_p,
5715 post_p,
5716 rhs_predicate_for (TREE_OPERAND (*expr_p, 0)),
5717 fb_rvalue);
5720 break;
5722 case VECTOR_TYPE:
5724 unsigned HOST_WIDE_INT ix;
5725 constructor_elt *ce;
5727 if (notify_temp_creation)
5728 return GS_OK;
5730 /* Vector types use CONSTRUCTOR all the way through gimple
5731 compilation as a general initializer. */
5732 FOR_EACH_VEC_SAFE_ELT (elts, ix, ce)
5734 enum gimplify_status tret;
5735 tret = gimplify_expr (&ce->value, pre_p, post_p, is_gimple_val,
5736 fb_rvalue);
5737 if (tret == GS_ERROR)
5738 ret = GS_ERROR;
5739 else if (TREE_STATIC (ctor)
5740 && !initializer_constant_valid_p (ce->value,
5741 TREE_TYPE (ce->value)))
5742 TREE_STATIC (ctor) = 0;
5744 recompute_constructor_flags (ctor);
5746 /* Go ahead and simplify constant constructors to VECTOR_CST. */
5747 if (TREE_CONSTANT (ctor))
5749 bool constant_p = true;
5750 tree value;
5752 /* Even when ctor is constant, it might contain non-*_CST
5753 elements, such as addresses or trapping values like
5754 1.0/0.0 - 1.0/0.0. Such expressions don't belong
5755 in VECTOR_CST nodes. */
5756 FOR_EACH_CONSTRUCTOR_VALUE (elts, ix, value)
5757 if (!CONSTANT_CLASS_P (value))
5759 constant_p = false;
5760 break;
5763 if (constant_p)
5765 TREE_OPERAND (*expr_p, 1) = build_vector_from_ctor (type, elts);
5766 break;
5770 if (!is_gimple_reg (TREE_OPERAND (*expr_p, 0)))
5771 TREE_OPERAND (*expr_p, 1) = get_formal_tmp_var (ctor, pre_p);
5773 break;
5775 default:
5776 /* So how did we get a CONSTRUCTOR for a scalar type? */
5777 gcc_unreachable ();
5780 if (ret == GS_ERROR)
5781 return GS_ERROR;
5782 /* If we have gimplified both sides of the initializer but have
5783 not emitted an assignment, do so now. */
5784 if (*expr_p
5785 /* If the type is an empty type, we don't need to emit the
5786 assignment. */
5787 && !is_empty_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0))))
5789 tree lhs = TREE_OPERAND (*expr_p, 0);
5790 tree rhs = TREE_OPERAND (*expr_p, 1);
5791 if (want_value && object == lhs)
5792 lhs = unshare_expr (lhs);
5793 gassign *init = gimple_build_assign (lhs, rhs);
5794 gimplify_seq_add_stmt (pre_p, init);
5796 if (want_value)
5798 *expr_p = object;
5799 ret = GS_OK;
5801 else
5803 *expr_p = NULL;
5804 ret = GS_ALL_DONE;
5807 /* If the user requests to initialize automatic variables, we
5808 should initialize paddings inside the variable. Add a call to
5809 __builtin_clear_pading (&object, 0, for_auto_init = true) to
5810 initialize paddings of object always to zero regardless of
5811 INIT_TYPE. Note, we will not insert this call if the aggregate
5812 variable has be completely cleared already or it's initialized
5813 with an empty constructor. We cannot insert this call if the
5814 variable is a gimple register since __builtin_clear_padding will take
5815 the address of the variable. As a result, if a long double/_Complex long
5816 double variable will be spilled into stack later, its padding cannot
5817 be cleared with __builtin_clear_padding. We should clear its padding
5818 when it is spilled into memory. */
5819 if (is_init_expr
5820 && !is_gimple_reg (object)
5821 && clear_padding_type_may_have_padding_p (type)
5822 && ((AGGREGATE_TYPE_P (type) && !cleared && !is_empty_ctor)
5823 || !AGGREGATE_TYPE_P (type))
5824 && is_var_need_auto_init (object))
5825 gimple_add_padding_init_for_auto_var (object, false, pre_p);
5827 return ret;
5830 /* Given a pointer value OP0, return a simplified version of an
5831 indirection through OP0, or NULL_TREE if no simplification is
5832 possible. This may only be applied to a rhs of an expression.
5833 Note that the resulting type may be different from the type pointed
5834 to in the sense that it is still compatible from the langhooks
5835 point of view. */
5837 static tree
5838 gimple_fold_indirect_ref_rhs (tree t)
5840 return gimple_fold_indirect_ref (t);
5843 /* Subroutine of gimplify_modify_expr to do simplifications of
5844 MODIFY_EXPRs based on the code of the RHS. We loop for as long as
5845 something changes. */
5847 static enum gimplify_status
5848 gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p,
5849 gimple_seq *pre_p, gimple_seq *post_p,
5850 bool want_value)
5852 enum gimplify_status ret = GS_UNHANDLED;
5853 bool changed;
5857 changed = false;
5858 switch (TREE_CODE (*from_p))
5860 case VAR_DECL:
5861 /* If we're assigning from a read-only variable initialized with
5862 a constructor and not volatile, do the direct assignment from
5863 the constructor, but only if the target is not volatile either
5864 since this latter assignment might end up being done on a per
5865 field basis. However, if the target is volatile and the type
5866 is aggregate and non-addressable, gimplify_init_constructor
5867 knows that it needs to ensure a single access to the target
5868 and it will return GS_OK only in this case. */
5869 if (TREE_READONLY (*from_p)
5870 && DECL_INITIAL (*from_p)
5871 && TREE_CODE (DECL_INITIAL (*from_p)) == CONSTRUCTOR
5872 && !TREE_THIS_VOLATILE (*from_p)
5873 && (!TREE_THIS_VOLATILE (*to_p)
5874 || (AGGREGATE_TYPE_P (TREE_TYPE (*to_p))
5875 && !TREE_ADDRESSABLE (TREE_TYPE (*to_p)))))
5877 tree old_from = *from_p;
5878 enum gimplify_status subret;
5880 /* Move the constructor into the RHS. */
5881 *from_p = unshare_expr (DECL_INITIAL (*from_p));
5883 /* Let's see if gimplify_init_constructor will need to put
5884 it in memory. */
5885 subret = gimplify_init_constructor (expr_p, NULL, NULL,
5886 false, true);
5887 if (subret == GS_ERROR)
5889 /* If so, revert the change. */
5890 *from_p = old_from;
5892 else
5894 ret = GS_OK;
5895 changed = true;
5898 break;
5899 case INDIRECT_REF:
5900 if (!TREE_ADDRESSABLE (TREE_TYPE (*from_p)))
5901 /* If we have code like
5903 *(const A*)(A*)&x
5905 where the type of "x" is a (possibly cv-qualified variant
5906 of "A"), treat the entire expression as identical to "x".
5907 This kind of code arises in C++ when an object is bound
5908 to a const reference, and if "x" is a TARGET_EXPR we want
5909 to take advantage of the optimization below. But not if
5910 the type is TREE_ADDRESSABLE; then C++17 says that the
5911 TARGET_EXPR needs to be a temporary. */
5912 if (tree t
5913 = gimple_fold_indirect_ref_rhs (TREE_OPERAND (*from_p, 0)))
5915 bool volatile_p = TREE_THIS_VOLATILE (*from_p);
5916 if (TREE_THIS_VOLATILE (t) != volatile_p)
5918 if (DECL_P (t))
5919 t = build_simple_mem_ref_loc (EXPR_LOCATION (*from_p),
5920 build_fold_addr_expr (t));
5921 if (REFERENCE_CLASS_P (t))
5922 TREE_THIS_VOLATILE (t) = volatile_p;
5924 *from_p = t;
5925 ret = GS_OK;
5926 changed = true;
5928 break;
5930 case TARGET_EXPR:
5932 /* If we are initializing something from a TARGET_EXPR, strip the
5933 TARGET_EXPR and initialize it directly, if possible. This can't
5934 be done if the initializer is void, since that implies that the
5935 temporary is set in some non-trivial way.
5937 ??? What about code that pulls out the temp and uses it
5938 elsewhere? I think that such code never uses the TARGET_EXPR as
5939 an initializer. If I'm wrong, we'll die because the temp won't
5940 have any RTL. In that case, I guess we'll need to replace
5941 references somehow. */
5942 tree init = TARGET_EXPR_INITIAL (*from_p);
5944 if (init
5945 && (TREE_CODE (*expr_p) != MODIFY_EXPR
5946 || !TARGET_EXPR_NO_ELIDE (*from_p))
5947 && !VOID_TYPE_P (TREE_TYPE (init)))
5949 *from_p = init;
5950 ret = GS_OK;
5951 changed = true;
5954 break;
5956 case COMPOUND_EXPR:
5957 /* Remove any COMPOUND_EXPR in the RHS so the following cases will be
5958 caught. */
5959 gimplify_compound_expr (from_p, pre_p, true);
5960 ret = GS_OK;
5961 changed = true;
5962 break;
5964 case CONSTRUCTOR:
5965 /* If we already made some changes, let the front end have a
5966 crack at this before we break it down. */
5967 if (ret != GS_UNHANDLED)
5968 break;
5970 /* If we're initializing from a CONSTRUCTOR, break this into
5971 individual MODIFY_EXPRs. */
5972 ret = gimplify_init_constructor (expr_p, pre_p, post_p, want_value,
5973 false);
5974 return ret;
5976 case COND_EXPR:
5977 /* If we're assigning to a non-register type, push the assignment
5978 down into the branches. This is mandatory for ADDRESSABLE types,
5979 since we cannot generate temporaries for such, but it saves a
5980 copy in other cases as well. */
5981 if (!is_gimple_reg_type (TREE_TYPE (*from_p)))
5983 /* This code should mirror the code in gimplify_cond_expr. */
5984 enum tree_code code = TREE_CODE (*expr_p);
5985 tree cond = *from_p;
5986 tree result = *to_p;
5988 ret = gimplify_expr (&result, pre_p, post_p,
5989 is_gimple_lvalue, fb_lvalue);
5990 if (ret != GS_ERROR)
5991 ret = GS_OK;
5993 /* If we are going to write RESULT more than once, clear
5994 TREE_READONLY flag, otherwise we might incorrectly promote
5995 the variable to static const and initialize it at compile
5996 time in one of the branches. */
5997 if (VAR_P (result)
5998 && TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node
5999 && TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
6000 TREE_READONLY (result) = 0;
6001 if (TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node)
6002 TREE_OPERAND (cond, 1)
6003 = build2 (code, void_type_node, result,
6004 TREE_OPERAND (cond, 1));
6005 if (TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
6006 TREE_OPERAND (cond, 2)
6007 = build2 (code, void_type_node, unshare_expr (result),
6008 TREE_OPERAND (cond, 2));
6010 TREE_TYPE (cond) = void_type_node;
6011 recalculate_side_effects (cond);
6013 if (want_value)
6015 gimplify_and_add (cond, pre_p);
6016 *expr_p = unshare_expr (result);
6018 else
6019 *expr_p = cond;
6020 return ret;
6022 break;
6024 case CALL_EXPR:
6025 /* For calls that return in memory, give *to_p as the CALL_EXPR's
6026 return slot so that we don't generate a temporary. */
6027 if (!CALL_EXPR_RETURN_SLOT_OPT (*from_p)
6028 && aggregate_value_p (*from_p, *from_p))
6030 bool use_target;
6032 if (!(rhs_predicate_for (*to_p))(*from_p))
6033 /* If we need a temporary, *to_p isn't accurate. */
6034 use_target = false;
6035 /* It's OK to use the return slot directly unless it's an NRV. */
6036 else if (TREE_CODE (*to_p) == RESULT_DECL
6037 && DECL_NAME (*to_p) == NULL_TREE
6038 && needs_to_live_in_memory (*to_p))
6039 use_target = true;
6040 else if (is_gimple_reg_type (TREE_TYPE (*to_p))
6041 || (DECL_P (*to_p) && DECL_REGISTER (*to_p)))
6042 /* Don't force regs into memory. */
6043 use_target = false;
6044 else if (TREE_CODE (*expr_p) == INIT_EXPR)
6045 /* It's OK to use the target directly if it's being
6046 initialized. */
6047 use_target = true;
6048 else if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p)))
6049 != INTEGER_CST)
6050 /* Always use the target and thus RSO for variable-sized types.
6051 GIMPLE cannot deal with a variable-sized assignment
6052 embedded in a call statement. */
6053 use_target = true;
6054 else if (TREE_CODE (*to_p) != SSA_NAME
6055 && (!is_gimple_variable (*to_p)
6056 || needs_to_live_in_memory (*to_p)))
6057 /* Don't use the original target if it's already addressable;
6058 if its address escapes, and the called function uses the
6059 NRV optimization, a conforming program could see *to_p
6060 change before the called function returns; see c++/19317.
6061 When optimizing, the return_slot pass marks more functions
6062 as safe after we have escape info. */
6063 use_target = false;
6064 else
6065 use_target = true;
6067 if (use_target)
6069 CALL_EXPR_RETURN_SLOT_OPT (*from_p) = 1;
6070 mark_addressable (*to_p);
6073 break;
6075 case WITH_SIZE_EXPR:
6076 /* Likewise for calls that return an aggregate of non-constant size,
6077 since we would not be able to generate a temporary at all. */
6078 if (TREE_CODE (TREE_OPERAND (*from_p, 0)) == CALL_EXPR)
6080 *from_p = TREE_OPERAND (*from_p, 0);
6081 /* We don't change ret in this case because the
6082 WITH_SIZE_EXPR might have been added in
6083 gimplify_modify_expr, so returning GS_OK would lead to an
6084 infinite loop. */
6085 changed = true;
6087 break;
6089 /* If we're initializing from a container, push the initialization
6090 inside it. */
6091 case CLEANUP_POINT_EXPR:
6092 case BIND_EXPR:
6093 case STATEMENT_LIST:
6095 tree wrap = *from_p;
6096 tree t;
6098 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_min_lval,
6099 fb_lvalue);
6100 if (ret != GS_ERROR)
6101 ret = GS_OK;
6103 t = voidify_wrapper_expr (wrap, *expr_p);
6104 gcc_assert (t == *expr_p);
6106 if (want_value)
6108 gimplify_and_add (wrap, pre_p);
6109 *expr_p = unshare_expr (*to_p);
6111 else
6112 *expr_p = wrap;
6113 return GS_OK;
6116 case NOP_EXPR:
6117 /* Pull out compound literal expressions from a NOP_EXPR.
6118 Those are created in the C FE to drop qualifiers during
6119 lvalue conversion. */
6120 if ((TREE_CODE (TREE_OPERAND (*from_p, 0)) == COMPOUND_LITERAL_EXPR)
6121 && tree_ssa_useless_type_conversion (*from_p))
6123 *from_p = TREE_OPERAND (*from_p, 0);
6124 ret = GS_OK;
6125 changed = true;
6127 break;
6129 case COMPOUND_LITERAL_EXPR:
6131 tree complit = TREE_OPERAND (*expr_p, 1);
6132 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (complit);
6133 tree decl = DECL_EXPR_DECL (decl_s);
6134 tree init = DECL_INITIAL (decl);
6136 /* struct T x = (struct T) { 0, 1, 2 } can be optimized
6137 into struct T x = { 0, 1, 2 } if the address of the
6138 compound literal has never been taken. */
6139 if (!TREE_ADDRESSABLE (complit)
6140 && !TREE_ADDRESSABLE (decl)
6141 && init)
6143 *expr_p = copy_node (*expr_p);
6144 TREE_OPERAND (*expr_p, 1) = init;
6145 return GS_OK;
6149 default:
6150 break;
6153 while (changed);
6155 return ret;
6159 /* Return true if T looks like a valid GIMPLE statement. */
6161 static bool
6162 is_gimple_stmt (tree t)
6164 const enum tree_code code = TREE_CODE (t);
6166 switch (code)
6168 case NOP_EXPR:
6169 /* The only valid NOP_EXPR is the empty statement. */
6170 return IS_EMPTY_STMT (t);
6172 case BIND_EXPR:
6173 case COND_EXPR:
6174 /* These are only valid if they're void. */
6175 return TREE_TYPE (t) == NULL || VOID_TYPE_P (TREE_TYPE (t));
6177 case SWITCH_EXPR:
6178 case GOTO_EXPR:
6179 case RETURN_EXPR:
6180 case LABEL_EXPR:
6181 case CASE_LABEL_EXPR:
6182 case TRY_CATCH_EXPR:
6183 case TRY_FINALLY_EXPR:
6184 case EH_FILTER_EXPR:
6185 case CATCH_EXPR:
6186 case ASM_EXPR:
6187 case STATEMENT_LIST:
6188 case OACC_PARALLEL:
6189 case OACC_KERNELS:
6190 case OACC_SERIAL:
6191 case OACC_DATA:
6192 case OACC_HOST_DATA:
6193 case OACC_DECLARE:
6194 case OACC_UPDATE:
6195 case OACC_ENTER_DATA:
6196 case OACC_EXIT_DATA:
6197 case OACC_CACHE:
6198 case OMP_PARALLEL:
6199 case OMP_FOR:
6200 case OMP_SIMD:
6201 case OMP_DISTRIBUTE:
6202 case OMP_LOOP:
6203 case OACC_LOOP:
6204 case OMP_SCAN:
6205 case OMP_SCOPE:
6206 case OMP_SECTIONS:
6207 case OMP_SECTION:
6208 case OMP_STRUCTURED_BLOCK:
6209 case OMP_SINGLE:
6210 case OMP_MASTER:
6211 case OMP_MASKED:
6212 case OMP_TASKGROUP:
6213 case OMP_ORDERED:
6214 case OMP_CRITICAL:
6215 case OMP_TASK:
6216 case OMP_TARGET:
6217 case OMP_TARGET_DATA:
6218 case OMP_TARGET_UPDATE:
6219 case OMP_TARGET_ENTER_DATA:
6220 case OMP_TARGET_EXIT_DATA:
6221 case OMP_TASKLOOP:
6222 case OMP_TEAMS:
6223 /* These are always void. */
6224 return true;
6226 case CALL_EXPR:
6227 case MODIFY_EXPR:
6228 case PREDICT_EXPR:
6229 /* These are valid regardless of their type. */
6230 return true;
6232 default:
6233 return false;
6238 /* Promote partial stores to COMPLEX variables to total stores. *EXPR_P is
6239 a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a gimple register.
6241 IMPORTANT NOTE: This promotion is performed by introducing a load of the
6242 other, unmodified part of the complex object just before the total store.
6243 As a consequence, if the object is still uninitialized, an undefined value
6244 will be loaded into a register, which may result in a spurious exception
6245 if the register is floating-point and the value happens to be a signaling
6246 NaN for example. Then the fully-fledged complex operations lowering pass
6247 followed by a DCE pass are necessary in order to fix things up. */
6249 static enum gimplify_status
6250 gimplify_modify_expr_complex_part (tree *expr_p, gimple_seq *pre_p,
6251 bool want_value)
6253 enum tree_code code, ocode;
6254 tree lhs, rhs, new_rhs, other, realpart, imagpart;
6256 lhs = TREE_OPERAND (*expr_p, 0);
6257 rhs = TREE_OPERAND (*expr_p, 1);
6258 code = TREE_CODE (lhs);
6259 lhs = TREE_OPERAND (lhs, 0);
6261 ocode = code == REALPART_EXPR ? IMAGPART_EXPR : REALPART_EXPR;
6262 other = build1 (ocode, TREE_TYPE (rhs), lhs);
6263 suppress_warning (other);
6264 other = get_formal_tmp_var (other, pre_p);
6266 realpart = code == REALPART_EXPR ? rhs : other;
6267 imagpart = code == REALPART_EXPR ? other : rhs;
6269 if (TREE_CONSTANT (realpart) && TREE_CONSTANT (imagpart))
6270 new_rhs = build_complex (TREE_TYPE (lhs), realpart, imagpart);
6271 else
6272 new_rhs = build2 (COMPLEX_EXPR, TREE_TYPE (lhs), realpart, imagpart);
6274 gimplify_seq_add_stmt (pre_p, gimple_build_assign (lhs, new_rhs));
6275 *expr_p = (want_value) ? rhs : NULL_TREE;
6277 return GS_ALL_DONE;
6280 /* Gimplify the MODIFY_EXPR node pointed to by EXPR_P.
6282 modify_expr
6283 : varname '=' rhs
6284 | '*' ID '=' rhs
6286 PRE_P points to the list where side effects that must happen before
6287 *EXPR_P should be stored.
6289 POST_P points to the list where side effects that must happen after
6290 *EXPR_P should be stored.
6292 WANT_VALUE is nonzero iff we want to use the value of this expression
6293 in another expression. */
6295 static enum gimplify_status
6296 gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
6297 bool want_value)
6299 tree *from_p = &TREE_OPERAND (*expr_p, 1);
6300 tree *to_p = &TREE_OPERAND (*expr_p, 0);
6301 enum gimplify_status ret = GS_UNHANDLED;
6302 gimple *assign;
6303 location_t loc = EXPR_LOCATION (*expr_p);
6304 gimple_stmt_iterator gsi;
6306 if (error_operand_p (*from_p) || error_operand_p (*to_p))
6307 return GS_ERROR;
6309 gcc_assert (TREE_CODE (*expr_p) == MODIFY_EXPR
6310 || TREE_CODE (*expr_p) == INIT_EXPR);
6312 /* Trying to simplify a clobber using normal logic doesn't work,
6313 so handle it here. */
6314 if (TREE_CLOBBER_P (*from_p))
6316 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
6317 if (ret == GS_ERROR)
6318 return ret;
6319 gcc_assert (!want_value);
6320 if (!VAR_P (*to_p) && TREE_CODE (*to_p) != MEM_REF)
6322 tree addr = get_initialized_tmp_var (build_fold_addr_expr (*to_p),
6323 pre_p, post_p);
6324 *to_p = build_simple_mem_ref_loc (EXPR_LOCATION (*to_p), addr);
6326 gimplify_seq_add_stmt (pre_p, gimple_build_assign (*to_p, *from_p));
6327 *expr_p = NULL;
6328 return GS_ALL_DONE;
6331 /* Convert initialization from an empty variable-size CONSTRUCTOR to
6332 memset. */
6333 if (TREE_TYPE (*from_p) != error_mark_node
6334 && TYPE_SIZE_UNIT (TREE_TYPE (*from_p))
6335 && !poly_int_tree_p (TYPE_SIZE_UNIT (TREE_TYPE (*from_p)))
6336 && TREE_CODE (*from_p) == CONSTRUCTOR
6337 && CONSTRUCTOR_NELTS (*from_p) == 0)
6339 maybe_with_size_expr (from_p);
6340 gcc_assert (TREE_CODE (*from_p) == WITH_SIZE_EXPR);
6341 return gimplify_modify_expr_to_memset (expr_p,
6342 TREE_OPERAND (*from_p, 1),
6343 want_value, pre_p);
6346 /* Insert pointer conversions required by the middle-end that are not
6347 required by the frontend. This fixes middle-end type checking for
6348 for example gcc.dg/redecl-6.c. */
6349 if (POINTER_TYPE_P (TREE_TYPE (*to_p)))
6351 STRIP_USELESS_TYPE_CONVERSION (*from_p);
6352 if (!useless_type_conversion_p (TREE_TYPE (*to_p), TREE_TYPE (*from_p)))
6353 *from_p = fold_convert_loc (loc, TREE_TYPE (*to_p), *from_p);
6356 /* See if any simplifications can be done based on what the RHS is. */
6357 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
6358 want_value);
6359 if (ret != GS_UNHANDLED)
6360 return ret;
6362 /* For empty types only gimplify the left hand side and right hand
6363 side as statements and throw away the assignment. Do this after
6364 gimplify_modify_expr_rhs so we handle TARGET_EXPRs of addressable
6365 types properly. */
6366 if (is_empty_type (TREE_TYPE (*from_p))
6367 && !want_value
6368 /* Don't do this for calls that return addressable types, expand_call
6369 relies on those having a lhs. */
6370 && !(TREE_ADDRESSABLE (TREE_TYPE (*from_p))
6371 && TREE_CODE (*from_p) == CALL_EXPR))
6373 gimplify_stmt (from_p, pre_p);
6374 gimplify_stmt (to_p, pre_p);
6375 *expr_p = NULL_TREE;
6376 return GS_ALL_DONE;
6379 /* If the value being copied is of variable width, compute the length
6380 of the copy into a WITH_SIZE_EXPR. Note that we need to do this
6381 before gimplifying any of the operands so that we can resolve any
6382 PLACEHOLDER_EXPRs in the size. Also note that the RTL expander uses
6383 the size of the expression to be copied, not of the destination, so
6384 that is what we must do here. */
6385 maybe_with_size_expr (from_p);
6387 /* As a special case, we have to temporarily allow for assignments
6388 with a CALL_EXPR on the RHS. Since in GIMPLE a function call is
6389 a toplevel statement, when gimplifying the GENERIC expression
6390 MODIFY_EXPR <a, CALL_EXPR <foo>>, we cannot create the tuple
6391 GIMPLE_ASSIGN <a, GIMPLE_CALL <foo>>.
6393 Instead, we need to create the tuple GIMPLE_CALL <a, foo>. To
6394 prevent gimplify_expr from trying to create a new temporary for
6395 foo's LHS, we tell it that it should only gimplify until it
6396 reaches the CALL_EXPR. On return from gimplify_expr, the newly
6397 created GIMPLE_CALL <foo> will be the last statement in *PRE_P
6398 and all we need to do here is set 'a' to be its LHS. */
6400 /* Gimplify the RHS first for C++17 and bug 71104. */
6401 gimple_predicate initial_pred = initial_rhs_predicate_for (*to_p);
6402 ret = gimplify_expr (from_p, pre_p, post_p, initial_pred, fb_rvalue);
6403 if (ret == GS_ERROR)
6404 return ret;
6406 /* Then gimplify the LHS. */
6407 /* If we gimplified the RHS to a CALL_EXPR and that call may return
6408 twice we have to make sure to gimplify into non-SSA as otherwise
6409 the abnormal edge added later will make those defs not dominate
6410 their uses.
6411 ??? Technically this applies only to the registers used in the
6412 resulting non-register *TO_P. */
6413 bool saved_into_ssa = gimplify_ctxp->into_ssa;
6414 if (saved_into_ssa
6415 && TREE_CODE (*from_p) == CALL_EXPR
6416 && call_expr_flags (*from_p) & ECF_RETURNS_TWICE)
6417 gimplify_ctxp->into_ssa = false;
6418 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
6419 gimplify_ctxp->into_ssa = saved_into_ssa;
6420 if (ret == GS_ERROR)
6421 return ret;
6423 /* Now that the LHS is gimplified, re-gimplify the RHS if our initial
6424 guess for the predicate was wrong. */
6425 gimple_predicate final_pred = rhs_predicate_for (*to_p);
6426 if (final_pred != initial_pred)
6428 ret = gimplify_expr (from_p, pre_p, post_p, final_pred, fb_rvalue);
6429 if (ret == GS_ERROR)
6430 return ret;
6433 /* In case of va_arg internal fn wrappped in a WITH_SIZE_EXPR, add the type
6434 size as argument to the call. */
6435 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
6437 tree call = TREE_OPERAND (*from_p, 0);
6438 tree vlasize = TREE_OPERAND (*from_p, 1);
6440 if (TREE_CODE (call) == CALL_EXPR
6441 && CALL_EXPR_IFN (call) == IFN_VA_ARG)
6443 int nargs = call_expr_nargs (call);
6444 tree type = TREE_TYPE (call);
6445 tree ap = CALL_EXPR_ARG (call, 0);
6446 tree tag = CALL_EXPR_ARG (call, 1);
6447 tree aptag = CALL_EXPR_ARG (call, 2);
6448 tree newcall = build_call_expr_internal_loc (EXPR_LOCATION (call),
6449 IFN_VA_ARG, type,
6450 nargs + 1, ap, tag,
6451 aptag, vlasize);
6452 TREE_OPERAND (*from_p, 0) = newcall;
6456 /* Now see if the above changed *from_p to something we handle specially. */
6457 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
6458 want_value);
6459 if (ret != GS_UNHANDLED)
6460 return ret;
6462 /* If we've got a variable sized assignment between two lvalues (i.e. does
6463 not involve a call), then we can make things a bit more straightforward
6464 by converting the assignment to memcpy or memset. */
6465 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
6467 tree from = TREE_OPERAND (*from_p, 0);
6468 tree size = TREE_OPERAND (*from_p, 1);
6470 if (TREE_CODE (from) == CONSTRUCTOR)
6471 return gimplify_modify_expr_to_memset (expr_p, size, want_value, pre_p);
6472 else if (is_gimple_addressable (from)
6473 && ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (*to_p)))
6474 && ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (from))))
6476 *from_p = from;
6477 return gimplify_modify_expr_to_memcpy (expr_p, size, want_value,
6478 pre_p);
6482 /* Transform partial stores to non-addressable complex variables into
6483 total stores. This allows us to use real instead of virtual operands
6484 for these variables, which improves optimization. */
6485 if ((TREE_CODE (*to_p) == REALPART_EXPR
6486 || TREE_CODE (*to_p) == IMAGPART_EXPR)
6487 && is_gimple_reg (TREE_OPERAND (*to_p, 0)))
6488 return gimplify_modify_expr_complex_part (expr_p, pre_p, want_value);
6490 /* Try to alleviate the effects of the gimplification creating artificial
6491 temporaries (see for example is_gimple_reg_rhs) on the debug info, but
6492 make sure not to create DECL_DEBUG_EXPR links across functions. */
6493 if (!gimplify_ctxp->into_ssa
6494 && VAR_P (*from_p)
6495 && DECL_IGNORED_P (*from_p)
6496 && DECL_P (*to_p)
6497 && !DECL_IGNORED_P (*to_p)
6498 && decl_function_context (*to_p) == current_function_decl
6499 && decl_function_context (*from_p) == current_function_decl)
6501 if (!DECL_NAME (*from_p) && DECL_NAME (*to_p))
6502 DECL_NAME (*from_p)
6503 = create_tmp_var_name (IDENTIFIER_POINTER (DECL_NAME (*to_p)));
6504 DECL_HAS_DEBUG_EXPR_P (*from_p) = 1;
6505 SET_DECL_DEBUG_EXPR (*from_p, *to_p);
6508 if (want_value && TREE_THIS_VOLATILE (*to_p))
6509 *from_p = get_initialized_tmp_var (*from_p, pre_p, post_p);
6511 if (TREE_CODE (*from_p) == CALL_EXPR)
6513 /* Since the RHS is a CALL_EXPR, we need to create a GIMPLE_CALL
6514 instead of a GIMPLE_ASSIGN. */
6515 gcall *call_stmt;
6516 if (CALL_EXPR_FN (*from_p) == NULL_TREE)
6518 /* Gimplify internal functions created in the FEs. */
6519 int nargs = call_expr_nargs (*from_p), i;
6520 enum internal_fn ifn = CALL_EXPR_IFN (*from_p);
6521 auto_vec<tree> vargs (nargs);
6523 for (i = 0; i < nargs; i++)
6525 gimplify_arg (&CALL_EXPR_ARG (*from_p, i), pre_p,
6526 EXPR_LOCATION (*from_p));
6527 vargs.quick_push (CALL_EXPR_ARG (*from_p, i));
6529 call_stmt = gimple_build_call_internal_vec (ifn, vargs);
6530 gimple_call_set_nothrow (call_stmt, TREE_NOTHROW (*from_p));
6531 gimple_set_location (call_stmt, EXPR_LOCATION (*expr_p));
6533 else
6535 tree fnptrtype = TREE_TYPE (CALL_EXPR_FN (*from_p));
6536 CALL_EXPR_FN (*from_p) = TREE_OPERAND (CALL_EXPR_FN (*from_p), 0);
6537 STRIP_USELESS_TYPE_CONVERSION (CALL_EXPR_FN (*from_p));
6538 tree fndecl = get_callee_fndecl (*from_p);
6539 if (fndecl
6540 && fndecl_built_in_p (fndecl, BUILT_IN_EXPECT)
6541 && call_expr_nargs (*from_p) == 3)
6542 call_stmt = gimple_build_call_internal (IFN_BUILTIN_EXPECT, 3,
6543 CALL_EXPR_ARG (*from_p, 0),
6544 CALL_EXPR_ARG (*from_p, 1),
6545 CALL_EXPR_ARG (*from_p, 2));
6546 else
6548 call_stmt = gimple_build_call_from_tree (*from_p, fnptrtype);
6551 notice_special_calls (call_stmt);
6552 if (!gimple_call_noreturn_p (call_stmt) || !should_remove_lhs_p (*to_p))
6553 gimple_call_set_lhs (call_stmt, *to_p);
6554 else if (TREE_CODE (*to_p) == SSA_NAME)
6555 /* The above is somewhat premature, avoid ICEing later for a
6556 SSA name w/o a definition. We may have uses in the GIMPLE IL.
6557 ??? This doesn't make it a default-def. */
6558 SSA_NAME_DEF_STMT (*to_p) = gimple_build_nop ();
6560 assign = call_stmt;
6562 else
6564 assign = gimple_build_assign (*to_p, *from_p);
6565 gimple_set_location (assign, EXPR_LOCATION (*expr_p));
6566 if (COMPARISON_CLASS_P (*from_p))
6567 copy_warning (assign, *from_p);
6570 if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p))
6572 /* We should have got an SSA name from the start. */
6573 gcc_assert (TREE_CODE (*to_p) == SSA_NAME
6574 || ! gimple_in_ssa_p (cfun));
6577 gimplify_seq_add_stmt (pre_p, assign);
6578 gsi = gsi_last (*pre_p);
6579 maybe_fold_stmt (&gsi);
6581 if (want_value)
6583 *expr_p = TREE_THIS_VOLATILE (*to_p) ? *from_p : unshare_expr (*to_p);
6584 return GS_OK;
6586 else
6587 *expr_p = NULL;
6589 return GS_ALL_DONE;
6592 /* Gimplify a comparison between two variable-sized objects. Do this
6593 with a call to BUILT_IN_MEMCMP. */
6595 static enum gimplify_status
6596 gimplify_variable_sized_compare (tree *expr_p)
6598 location_t loc = EXPR_LOCATION (*expr_p);
6599 tree op0 = TREE_OPERAND (*expr_p, 0);
6600 tree op1 = TREE_OPERAND (*expr_p, 1);
6601 tree t, arg, dest, src, expr;
6603 arg = TYPE_SIZE_UNIT (TREE_TYPE (op0));
6604 arg = unshare_expr (arg);
6605 arg = SUBSTITUTE_PLACEHOLDER_IN_EXPR (arg, op0);
6606 src = build_fold_addr_expr_loc (loc, op1);
6607 dest = build_fold_addr_expr_loc (loc, op0);
6608 t = builtin_decl_implicit (BUILT_IN_MEMCMP);
6609 t = build_call_expr_loc (loc, t, 3, dest, src, arg);
6611 expr
6612 = build2 (TREE_CODE (*expr_p), TREE_TYPE (*expr_p), t, integer_zero_node);
6613 SET_EXPR_LOCATION (expr, loc);
6614 *expr_p = expr;
6616 return GS_OK;
6619 /* Gimplify a comparison between two aggregate objects of integral scalar
6620 mode as a comparison between the bitwise equivalent scalar values. */
6622 static enum gimplify_status
6623 gimplify_scalar_mode_aggregate_compare (tree *expr_p)
6625 location_t loc = EXPR_LOCATION (*expr_p);
6626 tree op0 = TREE_OPERAND (*expr_p, 0);
6627 tree op1 = TREE_OPERAND (*expr_p, 1);
6629 tree type = TREE_TYPE (op0);
6630 tree scalar_type = lang_hooks.types.type_for_mode (TYPE_MODE (type), 1);
6632 op0 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op0);
6633 op1 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op1);
6635 *expr_p
6636 = fold_build2_loc (loc, TREE_CODE (*expr_p), TREE_TYPE (*expr_p), op0, op1);
6638 return GS_OK;
6641 /* Gimplify an expression sequence. This function gimplifies each
6642 expression and rewrites the original expression with the last
6643 expression of the sequence in GIMPLE form.
6645 PRE_P points to the list where the side effects for all the
6646 expressions in the sequence will be emitted.
6648 WANT_VALUE is true when the result of the last COMPOUND_EXPR is used. */
6650 static enum gimplify_status
6651 gimplify_compound_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
6653 tree t = *expr_p;
6657 tree *sub_p = &TREE_OPERAND (t, 0);
6659 if (TREE_CODE (*sub_p) == COMPOUND_EXPR)
6660 gimplify_compound_expr (sub_p, pre_p, false);
6661 else
6662 gimplify_stmt (sub_p, pre_p);
6664 t = TREE_OPERAND (t, 1);
6666 while (TREE_CODE (t) == COMPOUND_EXPR);
6668 *expr_p = t;
6669 if (want_value)
6670 return GS_OK;
6671 else
6673 gimplify_stmt (expr_p, pre_p);
6674 return GS_ALL_DONE;
6678 /* Gimplify a SAVE_EXPR node. EXPR_P points to the expression to
6679 gimplify. After gimplification, EXPR_P will point to a new temporary
6680 that holds the original value of the SAVE_EXPR node.
6682 PRE_P points to the list where side effects that must happen before
6683 *EXPR_P should be stored. */
6685 static enum gimplify_status
6686 gimplify_save_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6688 enum gimplify_status ret = GS_ALL_DONE;
6689 tree val;
6691 gcc_assert (TREE_CODE (*expr_p) == SAVE_EXPR);
6692 val = TREE_OPERAND (*expr_p, 0);
6694 if (val && TREE_TYPE (val) == error_mark_node)
6695 return GS_ERROR;
6697 /* If the SAVE_EXPR has not been resolved, then evaluate it once. */
6698 if (!SAVE_EXPR_RESOLVED_P (*expr_p))
6700 /* The operand may be a void-valued expression. It is
6701 being executed only for its side-effects. */
6702 if (TREE_TYPE (val) == void_type_node)
6704 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
6705 is_gimple_stmt, fb_none);
6706 val = NULL;
6708 else
6709 /* The temporary may not be an SSA name as later abnormal and EH
6710 control flow may invalidate use/def domination. When in SSA
6711 form then assume there are no such issues and SAVE_EXPRs only
6712 appear via GENERIC foldings. */
6713 val = get_initialized_tmp_var (val, pre_p, post_p,
6714 gimple_in_ssa_p (cfun));
6716 TREE_OPERAND (*expr_p, 0) = val;
6717 SAVE_EXPR_RESOLVED_P (*expr_p) = 1;
6720 *expr_p = val;
6722 return ret;
6725 /* Rewrite the ADDR_EXPR node pointed to by EXPR_P
6727 unary_expr
6728 : ...
6729 | '&' varname
6732 PRE_P points to the list where side effects that must happen before
6733 *EXPR_P should be stored.
6735 POST_P points to the list where side effects that must happen after
6736 *EXPR_P should be stored. */
6738 static enum gimplify_status
6739 gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6741 tree expr = *expr_p;
6742 tree op0 = TREE_OPERAND (expr, 0);
6743 enum gimplify_status ret;
6744 location_t loc = EXPR_LOCATION (*expr_p);
6746 switch (TREE_CODE (op0))
6748 case INDIRECT_REF:
6749 do_indirect_ref:
6750 /* Check if we are dealing with an expression of the form '&*ptr'.
6751 While the front end folds away '&*ptr' into 'ptr', these
6752 expressions may be generated internally by the compiler (e.g.,
6753 builtins like __builtin_va_end). */
6754 /* Caution: the silent array decomposition semantics we allow for
6755 ADDR_EXPR means we can't always discard the pair. */
6756 /* Gimplification of the ADDR_EXPR operand may drop
6757 cv-qualification conversions, so make sure we add them if
6758 needed. */
6760 tree op00 = TREE_OPERAND (op0, 0);
6761 tree t_expr = TREE_TYPE (expr);
6762 tree t_op00 = TREE_TYPE (op00);
6764 if (!useless_type_conversion_p (t_expr, t_op00))
6765 op00 = fold_convert_loc (loc, TREE_TYPE (expr), op00);
6766 *expr_p = op00;
6767 ret = GS_OK;
6769 break;
6771 case VIEW_CONVERT_EXPR:
6772 /* Take the address of our operand and then convert it to the type of
6773 this ADDR_EXPR.
6775 ??? The interactions of VIEW_CONVERT_EXPR and aliasing is not at
6776 all clear. The impact of this transformation is even less clear. */
6778 /* If the operand is a useless conversion, look through it. Doing so
6779 guarantees that the ADDR_EXPR and its operand will remain of the
6780 same type. */
6781 if (tree_ssa_useless_type_conversion (TREE_OPERAND (op0, 0)))
6782 op0 = TREE_OPERAND (op0, 0);
6784 *expr_p = fold_convert_loc (loc, TREE_TYPE (expr),
6785 build_fold_addr_expr_loc (loc,
6786 TREE_OPERAND (op0, 0)));
6787 ret = GS_OK;
6788 break;
6790 case MEM_REF:
6791 if (integer_zerop (TREE_OPERAND (op0, 1)))
6792 goto do_indirect_ref;
6794 /* fall through */
6796 default:
6797 /* If we see a call to a declared builtin or see its address
6798 being taken (we can unify those cases here) then we can mark
6799 the builtin for implicit generation by GCC. */
6800 if (TREE_CODE (op0) == FUNCTION_DECL
6801 && fndecl_built_in_p (op0, BUILT_IN_NORMAL)
6802 && builtin_decl_declared_p (DECL_FUNCTION_CODE (op0)))
6803 set_builtin_decl_implicit_p (DECL_FUNCTION_CODE (op0), true);
6805 /* We use fb_either here because the C frontend sometimes takes
6806 the address of a call that returns a struct; see
6807 gcc.dg/c99-array-lval-1.c. The gimplifier will correctly make
6808 the implied temporary explicit. */
6810 /* Make the operand addressable. */
6811 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, post_p,
6812 is_gimple_addressable, fb_either);
6813 if (ret == GS_ERROR)
6814 break;
6816 /* Then mark it. Beware that it may not be possible to do so directly
6817 if a temporary has been created by the gimplification. */
6818 prepare_gimple_addressable (&TREE_OPERAND (expr, 0), pre_p);
6820 op0 = TREE_OPERAND (expr, 0);
6822 /* For various reasons, the gimplification of the expression
6823 may have made a new INDIRECT_REF. */
6824 if (INDIRECT_REF_P (op0)
6825 || (TREE_CODE (op0) == MEM_REF
6826 && integer_zerop (TREE_OPERAND (op0, 1))))
6827 goto do_indirect_ref;
6829 mark_addressable (TREE_OPERAND (expr, 0));
6831 /* The FEs may end up building ADDR_EXPRs early on a decl with
6832 an incomplete type. Re-build ADDR_EXPRs in canonical form
6833 here. */
6834 if (!types_compatible_p (TREE_TYPE (op0), TREE_TYPE (TREE_TYPE (expr))))
6835 *expr_p = build_fold_addr_expr (op0);
6837 /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly. */
6838 recompute_tree_invariant_for_addr_expr (*expr_p);
6840 /* If we re-built the ADDR_EXPR add a conversion to the original type
6841 if required. */
6842 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
6843 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
6845 break;
6848 return ret;
6851 /* Gimplify the operands of an ASM_EXPR. Input operands should be a gimple
6852 value; output operands should be a gimple lvalue. */
6854 static enum gimplify_status
6855 gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6857 tree expr;
6858 int noutputs;
6859 const char **oconstraints;
6860 int i;
6861 tree link;
6862 const char *constraint;
6863 bool allows_mem, allows_reg, is_inout;
6864 enum gimplify_status ret, tret;
6865 gasm *stmt;
6866 vec<tree, va_gc> *inputs;
6867 vec<tree, va_gc> *outputs;
6868 vec<tree, va_gc> *clobbers;
6869 vec<tree, va_gc> *labels;
6870 tree link_next;
6872 expr = *expr_p;
6873 noutputs = list_length (ASM_OUTPUTS (expr));
6874 oconstraints = (const char **) alloca ((noutputs) * sizeof (const char *));
6876 inputs = NULL;
6877 outputs = NULL;
6878 clobbers = NULL;
6879 labels = NULL;
6881 ret = GS_ALL_DONE;
6882 link_next = NULL_TREE;
6883 for (i = 0, link = ASM_OUTPUTS (expr); link; ++i, link = link_next)
6885 bool ok;
6886 size_t constraint_len;
6888 link_next = TREE_CHAIN (link);
6890 oconstraints[i]
6891 = constraint
6892 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
6893 constraint_len = strlen (constraint);
6894 if (constraint_len == 0)
6895 continue;
6897 ok = parse_output_constraint (&constraint, i, 0, 0,
6898 &allows_mem, &allows_reg, &is_inout);
6899 if (!ok)
6901 ret = GS_ERROR;
6902 is_inout = false;
6905 /* If we can't make copies, we can only accept memory.
6906 Similarly for VLAs. */
6907 tree outtype = TREE_TYPE (TREE_VALUE (link));
6908 if (outtype != error_mark_node
6909 && (TREE_ADDRESSABLE (outtype)
6910 || !COMPLETE_TYPE_P (outtype)
6911 || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (outtype))))
6913 if (allows_mem)
6914 allows_reg = 0;
6915 else
6917 error ("impossible constraint in %<asm%>");
6918 error ("non-memory output %d must stay in memory", i);
6919 return GS_ERROR;
6923 if (!allows_reg && allows_mem)
6924 mark_addressable (TREE_VALUE (link));
6926 tree orig = TREE_VALUE (link);
6927 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6928 is_inout ? is_gimple_min_lval : is_gimple_lvalue,
6929 fb_lvalue | fb_mayfail);
6930 if (tret == GS_ERROR)
6932 if (orig != error_mark_node)
6933 error ("invalid lvalue in %<asm%> output %d", i);
6934 ret = tret;
6937 /* If the constraint does not allow memory make sure we gimplify
6938 it to a register if it is not already but its base is. This
6939 happens for complex and vector components. */
6940 if (!allows_mem)
6942 tree op = TREE_VALUE (link);
6943 if (! is_gimple_val (op)
6944 && is_gimple_reg_type (TREE_TYPE (op))
6945 && is_gimple_reg (get_base_address (op)))
6947 tree tem = create_tmp_reg (TREE_TYPE (op));
6948 tree ass;
6949 if (is_inout)
6951 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem),
6952 tem, unshare_expr (op));
6953 gimplify_and_add (ass, pre_p);
6955 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem), op, tem);
6956 gimplify_and_add (ass, post_p);
6958 TREE_VALUE (link) = tem;
6959 tret = GS_OK;
6963 vec_safe_push (outputs, link);
6964 TREE_CHAIN (link) = NULL_TREE;
6966 if (is_inout)
6968 /* An input/output operand. To give the optimizers more
6969 flexibility, split it into separate input and output
6970 operands. */
6971 tree input;
6972 /* Buffer big enough to format a 32-bit UINT_MAX into. */
6973 char buf[11];
6975 /* Turn the in/out constraint into an output constraint. */
6976 char *p = xstrdup (constraint);
6977 p[0] = '=';
6978 TREE_VALUE (TREE_PURPOSE (link)) = build_string (constraint_len, p);
6980 /* And add a matching input constraint. */
6981 if (allows_reg)
6983 sprintf (buf, "%u", i);
6985 /* If there are multiple alternatives in the constraint,
6986 handle each of them individually. Those that allow register
6987 will be replaced with operand number, the others will stay
6988 unchanged. */
6989 if (strchr (p, ',') != NULL)
6991 size_t len = 0, buflen = strlen (buf);
6992 char *beg, *end, *str, *dst;
6994 for (beg = p + 1;;)
6996 end = strchr (beg, ',');
6997 if (end == NULL)
6998 end = strchr (beg, '\0');
6999 if ((size_t) (end - beg) < buflen)
7000 len += buflen + 1;
7001 else
7002 len += end - beg + 1;
7003 if (*end)
7004 beg = end + 1;
7005 else
7006 break;
7009 str = (char *) alloca (len);
7010 for (beg = p + 1, dst = str;;)
7012 const char *tem;
7013 bool mem_p, reg_p, inout_p;
7015 end = strchr (beg, ',');
7016 if (end)
7017 *end = '\0';
7018 beg[-1] = '=';
7019 tem = beg - 1;
7020 parse_output_constraint (&tem, i, 0, 0,
7021 &mem_p, &reg_p, &inout_p);
7022 if (dst != str)
7023 *dst++ = ',';
7024 if (reg_p)
7026 memcpy (dst, buf, buflen);
7027 dst += buflen;
7029 else
7031 if (end)
7032 len = end - beg;
7033 else
7034 len = strlen (beg);
7035 memcpy (dst, beg, len);
7036 dst += len;
7038 if (end)
7039 beg = end + 1;
7040 else
7041 break;
7043 *dst = '\0';
7044 input = build_string (dst - str, str);
7046 else
7047 input = build_string (strlen (buf), buf);
7049 else
7050 input = build_string (constraint_len - 1, constraint + 1);
7052 free (p);
7054 input = build_tree_list (build_tree_list (NULL_TREE, input),
7055 unshare_expr (TREE_VALUE (link)));
7056 ASM_INPUTS (expr) = chainon (ASM_INPUTS (expr), input);
7060 link_next = NULL_TREE;
7061 for (link = ASM_INPUTS (expr); link; ++i, link = link_next)
7063 link_next = TREE_CHAIN (link);
7064 constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
7065 parse_input_constraint (&constraint, 0, 0, noutputs, 0,
7066 oconstraints, &allows_mem, &allows_reg);
7068 /* If we can't make copies, we can only accept memory. */
7069 tree intype = TREE_TYPE (TREE_VALUE (link));
7070 if (intype != error_mark_node
7071 && (TREE_ADDRESSABLE (intype)
7072 || !COMPLETE_TYPE_P (intype)
7073 || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (intype))))
7075 if (allows_mem)
7076 allows_reg = 0;
7077 else
7079 error ("impossible constraint in %<asm%>");
7080 error ("non-memory input %d must stay in memory", i);
7081 return GS_ERROR;
7085 /* If the operand is a memory input, it should be an lvalue. */
7086 if (!allows_reg && allows_mem)
7088 tree inputv = TREE_VALUE (link);
7089 STRIP_NOPS (inputv);
7090 if (TREE_CODE (inputv) == PREDECREMENT_EXPR
7091 || TREE_CODE (inputv) == PREINCREMENT_EXPR
7092 || TREE_CODE (inputv) == POSTDECREMENT_EXPR
7093 || TREE_CODE (inputv) == POSTINCREMENT_EXPR
7094 || TREE_CODE (inputv) == MODIFY_EXPR)
7095 TREE_VALUE (link) = error_mark_node;
7096 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
7097 is_gimple_lvalue, fb_lvalue | fb_mayfail);
7098 if (tret != GS_ERROR)
7100 /* Unlike output operands, memory inputs are not guaranteed
7101 to be lvalues by the FE, and while the expressions are
7102 marked addressable there, if it is e.g. a statement
7103 expression, temporaries in it might not end up being
7104 addressable. They might be already used in the IL and thus
7105 it is too late to make them addressable now though. */
7106 tree x = TREE_VALUE (link);
7107 while (handled_component_p (x))
7108 x = TREE_OPERAND (x, 0);
7109 if (TREE_CODE (x) == MEM_REF
7110 && TREE_CODE (TREE_OPERAND (x, 0)) == ADDR_EXPR)
7111 x = TREE_OPERAND (TREE_OPERAND (x, 0), 0);
7112 if ((VAR_P (x)
7113 || TREE_CODE (x) == PARM_DECL
7114 || TREE_CODE (x) == RESULT_DECL)
7115 && !TREE_ADDRESSABLE (x)
7116 && is_gimple_reg (x))
7118 warning_at (EXPR_LOC_OR_LOC (TREE_VALUE (link),
7119 input_location), 0,
7120 "memory input %d is not directly addressable",
7122 prepare_gimple_addressable (&TREE_VALUE (link), pre_p);
7125 mark_addressable (TREE_VALUE (link));
7126 if (tret == GS_ERROR)
7128 if (inputv != error_mark_node)
7129 error_at (EXPR_LOC_OR_LOC (TREE_VALUE (link), input_location),
7130 "memory input %d is not directly addressable", i);
7131 ret = tret;
7134 else
7136 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
7137 is_gimple_asm_val, fb_rvalue);
7138 if (tret == GS_ERROR)
7139 ret = tret;
7142 TREE_CHAIN (link) = NULL_TREE;
7143 vec_safe_push (inputs, link);
7146 link_next = NULL_TREE;
7147 for (link = ASM_CLOBBERS (expr); link; ++i, link = link_next)
7149 link_next = TREE_CHAIN (link);
7150 TREE_CHAIN (link) = NULL_TREE;
7151 vec_safe_push (clobbers, link);
7154 link_next = NULL_TREE;
7155 for (link = ASM_LABELS (expr); link; ++i, link = link_next)
7157 link_next = TREE_CHAIN (link);
7158 TREE_CHAIN (link) = NULL_TREE;
7159 vec_safe_push (labels, link);
7162 /* Do not add ASMs with errors to the gimple IL stream. */
7163 if (ret != GS_ERROR)
7165 stmt = gimple_build_asm_vec (TREE_STRING_POINTER (ASM_STRING (expr)),
7166 inputs, outputs, clobbers, labels);
7168 /* asm is volatile if it was marked by the user as volatile or
7169 there are no outputs or this is an asm goto. */
7170 gimple_asm_set_volatile (stmt,
7171 ASM_VOLATILE_P (expr)
7172 || noutputs == 0
7173 || labels);
7174 gimple_asm_set_input (stmt, ASM_INPUT_P (expr));
7175 gimple_asm_set_inline (stmt, ASM_INLINE_P (expr));
7177 gimplify_seq_add_stmt (pre_p, stmt);
7180 return ret;
7183 /* Gimplify a CLEANUP_POINT_EXPR. Currently this works by adding
7184 GIMPLE_WITH_CLEANUP_EXPRs to the prequeue as we encounter cleanups while
7185 gimplifying the body, and converting them to TRY_FINALLY_EXPRs when we
7186 return to this function.
7188 FIXME should we complexify the prequeue handling instead? Or use flags
7189 for all the cleanups and let the optimizer tighten them up? The current
7190 code seems pretty fragile; it will break on a cleanup within any
7191 non-conditional nesting. But any such nesting would be broken, anyway;
7192 we can't write a TRY_FINALLY_EXPR that starts inside a nesting construct
7193 and continues out of it. We can do that at the RTL level, though, so
7194 having an optimizer to tighten up try/finally regions would be a Good
7195 Thing. */
7197 static enum gimplify_status
7198 gimplify_cleanup_point_expr (tree *expr_p, gimple_seq *pre_p)
7200 gimple_stmt_iterator iter;
7201 gimple_seq body_sequence = NULL;
7203 tree temp = voidify_wrapper_expr (*expr_p, NULL);
7205 /* We only care about the number of conditions between the innermost
7206 CLEANUP_POINT_EXPR and the cleanup. So save and reset the count and
7207 any cleanups collected outside the CLEANUP_POINT_EXPR. */
7208 int old_conds = gimplify_ctxp->conditions;
7209 gimple_seq old_cleanups = gimplify_ctxp->conditional_cleanups;
7210 bool old_in_cleanup_point_expr = gimplify_ctxp->in_cleanup_point_expr;
7211 gimplify_ctxp->conditions = 0;
7212 gimplify_ctxp->conditional_cleanups = NULL;
7213 gimplify_ctxp->in_cleanup_point_expr = true;
7215 gimplify_stmt (&TREE_OPERAND (*expr_p, 0), &body_sequence);
7217 gimplify_ctxp->conditions = old_conds;
7218 gimplify_ctxp->conditional_cleanups = old_cleanups;
7219 gimplify_ctxp->in_cleanup_point_expr = old_in_cleanup_point_expr;
7221 for (iter = gsi_start (body_sequence); !gsi_end_p (iter); )
7223 gimple *wce = gsi_stmt (iter);
7225 if (gimple_code (wce) == GIMPLE_WITH_CLEANUP_EXPR)
7227 if (gsi_one_before_end_p (iter))
7229 /* Note that gsi_insert_seq_before and gsi_remove do not
7230 scan operands, unlike some other sequence mutators. */
7231 if (!gimple_wce_cleanup_eh_only (wce))
7232 gsi_insert_seq_before_without_update (&iter,
7233 gimple_wce_cleanup (wce),
7234 GSI_SAME_STMT);
7235 gsi_remove (&iter, true);
7236 break;
7238 else
7240 gtry *gtry;
7241 gimple_seq seq;
7242 enum gimple_try_flags kind;
7244 if (gimple_wce_cleanup_eh_only (wce))
7245 kind = GIMPLE_TRY_CATCH;
7246 else
7247 kind = GIMPLE_TRY_FINALLY;
7248 seq = gsi_split_seq_after (iter);
7250 gtry = gimple_build_try (seq, gimple_wce_cleanup (wce), kind);
7251 /* Do not use gsi_replace here, as it may scan operands.
7252 We want to do a simple structural modification only. */
7253 gsi_set_stmt (&iter, gtry);
7254 iter = gsi_start (gtry->eval);
7257 else
7258 gsi_next (&iter);
7261 gimplify_seq_add_seq (pre_p, body_sequence);
7262 if (temp)
7264 *expr_p = temp;
7265 return GS_OK;
7267 else
7269 *expr_p = NULL;
7270 return GS_ALL_DONE;
7274 /* Insert a cleanup marker for gimplify_cleanup_point_expr. CLEANUP
7275 is the cleanup action required. EH_ONLY is true if the cleanup should
7276 only be executed if an exception is thrown, not on normal exit.
7277 If FORCE_UNCOND is true perform the cleanup unconditionally; this is
7278 only valid for clobbers. */
7280 static void
7281 gimple_push_cleanup (tree var, tree cleanup, bool eh_only, gimple_seq *pre_p,
7282 bool force_uncond = false)
7284 gimple *wce;
7285 gimple_seq cleanup_stmts = NULL;
7287 /* Errors can result in improperly nested cleanups. Which results in
7288 confusion when trying to resolve the GIMPLE_WITH_CLEANUP_EXPR. */
7289 if (seen_error ())
7290 return;
7292 if (gimple_conditional_context ())
7294 /* If we're in a conditional context, this is more complex. We only
7295 want to run the cleanup if we actually ran the initialization that
7296 necessitates it, but we want to run it after the end of the
7297 conditional context. So we wrap the try/finally around the
7298 condition and use a flag to determine whether or not to actually
7299 run the destructor. Thus
7301 test ? f(A()) : 0
7303 becomes (approximately)
7305 flag = 0;
7306 try {
7307 if (test) { A::A(temp); flag = 1; val = f(temp); }
7308 else { val = 0; }
7309 } finally {
7310 if (flag) A::~A(temp);
7314 if (force_uncond)
7316 gimplify_stmt (&cleanup, &cleanup_stmts);
7317 wce = gimple_build_wce (cleanup_stmts);
7318 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
7320 else
7322 tree flag = create_tmp_var (boolean_type_node, "cleanup");
7323 gassign *ffalse = gimple_build_assign (flag, boolean_false_node);
7324 gassign *ftrue = gimple_build_assign (flag, boolean_true_node);
7326 cleanup = build3 (COND_EXPR, void_type_node, flag, cleanup, NULL);
7327 gimplify_stmt (&cleanup, &cleanup_stmts);
7328 wce = gimple_build_wce (cleanup_stmts);
7329 gimple_wce_set_cleanup_eh_only (wce, eh_only);
7331 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, ffalse);
7332 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
7333 gimplify_seq_add_stmt (pre_p, ftrue);
7335 /* Because of this manipulation, and the EH edges that jump
7336 threading cannot redirect, the temporary (VAR) will appear
7337 to be used uninitialized. Don't warn. */
7338 suppress_warning (var, OPT_Wuninitialized);
7341 else
7343 gimplify_stmt (&cleanup, &cleanup_stmts);
7344 wce = gimple_build_wce (cleanup_stmts);
7345 gimple_wce_set_cleanup_eh_only (wce, eh_only);
7346 gimplify_seq_add_stmt (pre_p, wce);
7350 /* Gimplify a TARGET_EXPR which doesn't appear on the rhs of an INIT_EXPR. */
7352 static enum gimplify_status
7353 gimplify_target_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
7355 tree targ = *expr_p;
7356 tree temp = TARGET_EXPR_SLOT (targ);
7357 tree init = TARGET_EXPR_INITIAL (targ);
7358 enum gimplify_status ret;
7360 bool unpoison_empty_seq = false;
7361 gimple_stmt_iterator unpoison_it;
7363 if (init)
7365 gimple_seq init_pre_p = NULL;
7367 /* TARGET_EXPR temps aren't part of the enclosing block, so add it
7368 to the temps list. Handle also variable length TARGET_EXPRs. */
7369 if (!poly_int_tree_p (DECL_SIZE (temp)))
7371 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (temp)))
7372 gimplify_type_sizes (TREE_TYPE (temp), &init_pre_p);
7373 /* FIXME: this is correct only when the size of the type does
7374 not depend on expressions evaluated in init. */
7375 gimplify_vla_decl (temp, &init_pre_p);
7377 else
7379 /* Save location where we need to place unpoisoning. It's possible
7380 that a variable will be converted to needs_to_live_in_memory. */
7381 unpoison_it = gsi_last (*pre_p);
7382 unpoison_empty_seq = gsi_end_p (unpoison_it);
7384 gimple_add_tmp_var (temp);
7387 /* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the
7388 expression is supposed to initialize the slot. */
7389 if (VOID_TYPE_P (TREE_TYPE (init)))
7390 ret = gimplify_expr (&init, &init_pre_p, post_p, is_gimple_stmt,
7391 fb_none);
7392 else
7394 tree init_expr = build2 (INIT_EXPR, void_type_node, temp, init);
7395 init = init_expr;
7396 ret = gimplify_expr (&init, &init_pre_p, post_p, is_gimple_stmt,
7397 fb_none);
7398 init = NULL;
7399 ggc_free (init_expr);
7401 if (ret == GS_ERROR)
7403 /* PR c++/28266 Make sure this is expanded only once. */
7404 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
7405 return GS_ERROR;
7408 if (init)
7409 gimplify_and_add (init, &init_pre_p);
7411 /* Add a clobber for the temporary going out of scope, like
7412 gimplify_bind_expr. But only if we did not promote the
7413 temporary to static storage. */
7414 if (gimplify_ctxp->in_cleanup_point_expr
7415 && !TREE_STATIC (temp)
7416 && needs_to_live_in_memory (temp))
7418 if (flag_stack_reuse == SR_ALL)
7420 tree clobber = build_clobber (TREE_TYPE (temp),
7421 CLOBBER_STORAGE_END);
7422 clobber = build2 (MODIFY_EXPR, TREE_TYPE (temp), temp, clobber);
7423 gimple_push_cleanup (temp, clobber, false, pre_p, true);
7425 if (asan_poisoned_variables
7426 && DECL_ALIGN (temp) <= MAX_SUPPORTED_STACK_ALIGNMENT
7427 && !TREE_STATIC (temp)
7428 && dbg_cnt (asan_use_after_scope)
7429 && !gimplify_omp_ctxp)
7431 tree asan_cleanup = build_asan_poison_call_expr (temp);
7432 if (asan_cleanup)
7434 if (unpoison_empty_seq)
7435 unpoison_it = gsi_start (*pre_p);
7437 asan_poison_variable (temp, false, &unpoison_it,
7438 unpoison_empty_seq);
7439 gimple_push_cleanup (temp, asan_cleanup, false, pre_p);
7444 gimple_seq_add_seq (pre_p, init_pre_p);
7446 /* If needed, push the cleanup for the temp. */
7447 if (TARGET_EXPR_CLEANUP (targ))
7448 gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ),
7449 CLEANUP_EH_ONLY (targ), pre_p);
7451 /* Only expand this once. */
7452 TREE_OPERAND (targ, 3) = init;
7453 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
7455 else
7456 /* We should have expanded this before. */
7457 gcc_assert (DECL_SEEN_IN_BIND_EXPR_P (temp));
7459 *expr_p = temp;
7460 return GS_OK;
7463 /* Gimplification of expression trees. */
7465 /* Gimplify an expression which appears at statement context. The
7466 corresponding GIMPLE statements are added to *SEQ_P. If *SEQ_P is
7467 NULL, a new sequence is allocated.
7469 Return true if we actually added a statement to the queue. */
7471 bool
7472 gimplify_stmt (tree *stmt_p, gimple_seq *seq_p)
7474 gimple_seq_node last;
7476 last = gimple_seq_last (*seq_p);
7477 gimplify_expr (stmt_p, seq_p, NULL, is_gimple_stmt, fb_none);
7478 return last != gimple_seq_last (*seq_p);
7481 /* Add FIRSTPRIVATE entries for DECL in the OpenMP the surrounding parallels
7482 to CTX. If entries already exist, force them to be some flavor of private.
7483 If there is no enclosing parallel, do nothing. */
7485 void
7486 omp_firstprivatize_variable (struct gimplify_omp_ctx *ctx, tree decl)
7488 splay_tree_node n;
7490 if (decl == NULL || !DECL_P (decl) || ctx->region_type == ORT_NONE)
7491 return;
7495 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7496 if (n != NULL)
7498 if (n->value & GOVD_SHARED)
7499 n->value = GOVD_FIRSTPRIVATE | (n->value & GOVD_SEEN);
7500 else if (n->value & GOVD_MAP)
7501 n->value |= GOVD_MAP_TO_ONLY;
7502 else
7503 return;
7505 else if ((ctx->region_type & ORT_TARGET) != 0)
7507 if (ctx->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE)
7508 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
7509 else
7510 omp_add_variable (ctx, decl, GOVD_MAP | GOVD_MAP_TO_ONLY);
7512 else if (ctx->region_type != ORT_WORKSHARE
7513 && ctx->region_type != ORT_TASKGROUP
7514 && ctx->region_type != ORT_SIMD
7515 && ctx->region_type != ORT_ACC
7516 && !(ctx->region_type & ORT_TARGET_DATA))
7517 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
7519 ctx = ctx->outer_context;
7521 while (ctx);
7524 /* Similarly for each of the type sizes of TYPE. */
7526 static void
7527 omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type)
7529 if (type == NULL || type == error_mark_node)
7530 return;
7531 type = TYPE_MAIN_VARIANT (type);
7533 if (ctx->privatized_types->add (type))
7534 return;
7536 switch (TREE_CODE (type))
7538 case INTEGER_TYPE:
7539 case ENUMERAL_TYPE:
7540 case BOOLEAN_TYPE:
7541 case REAL_TYPE:
7542 case FIXED_POINT_TYPE:
7543 omp_firstprivatize_variable (ctx, TYPE_MIN_VALUE (type));
7544 omp_firstprivatize_variable (ctx, TYPE_MAX_VALUE (type));
7545 break;
7547 case ARRAY_TYPE:
7548 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
7549 omp_firstprivatize_type_sizes (ctx, TYPE_DOMAIN (type));
7550 break;
7552 case RECORD_TYPE:
7553 case UNION_TYPE:
7554 case QUAL_UNION_TYPE:
7556 tree field;
7557 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
7558 if (TREE_CODE (field) == FIELD_DECL)
7560 omp_firstprivatize_variable (ctx, DECL_FIELD_OFFSET (field));
7561 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (field));
7564 break;
7566 case POINTER_TYPE:
7567 case REFERENCE_TYPE:
7568 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
7569 break;
7571 default:
7572 break;
7575 omp_firstprivatize_variable (ctx, TYPE_SIZE (type));
7576 omp_firstprivatize_variable (ctx, TYPE_SIZE_UNIT (type));
7577 lang_hooks.types.omp_firstprivatize_type_sizes (ctx, type);
7580 /* Add an entry for DECL in the OMP context CTX with FLAGS. */
7582 static void
7583 omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
7585 splay_tree_node n;
7586 unsigned int nflags;
7587 tree t;
7589 if (error_operand_p (decl) || ctx->region_type == ORT_NONE)
7590 return;
7592 /* Never elide decls whose type has TREE_ADDRESSABLE set. This means
7593 there are constructors involved somewhere. Exception is a shared clause,
7594 there is nothing privatized in that case. */
7595 if ((flags & GOVD_SHARED) == 0
7596 && (TREE_ADDRESSABLE (TREE_TYPE (decl))
7597 || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))))
7598 flags |= GOVD_SEEN;
7600 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7601 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
7603 /* We shouldn't be re-adding the decl with the same data
7604 sharing class. */
7605 gcc_assert ((n->value & GOVD_DATA_SHARE_CLASS & flags) == 0);
7606 nflags = n->value | flags;
7607 /* The only combination of data sharing classes we should see is
7608 FIRSTPRIVATE and LASTPRIVATE. However, OpenACC permits
7609 reduction variables to be used in data sharing clauses. */
7610 gcc_assert ((ctx->region_type & ORT_ACC) != 0
7611 || ((nflags & GOVD_DATA_SHARE_CLASS)
7612 == (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE))
7613 || (flags & GOVD_DATA_SHARE_CLASS) == 0);
7614 n->value = nflags;
7615 return;
7618 /* When adding a variable-sized variable, we have to handle all sorts
7619 of additional bits of data: the pointer replacement variable, and
7620 the parameters of the type. */
7621 if (DECL_SIZE (decl) && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
7623 /* Add the pointer replacement variable as PRIVATE if the variable
7624 replacement is private, else FIRSTPRIVATE since we'll need the
7625 address of the original variable either for SHARED, or for the
7626 copy into or out of the context. */
7627 if (!(flags & GOVD_LOCAL) && ctx->region_type != ORT_TASKGROUP)
7629 if (flags & GOVD_MAP)
7630 nflags = GOVD_MAP | GOVD_MAP_TO_ONLY | GOVD_EXPLICIT;
7631 else if (flags & GOVD_PRIVATE)
7632 nflags = GOVD_PRIVATE;
7633 else if (((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
7634 && (flags & GOVD_FIRSTPRIVATE))
7635 || (ctx->region_type == ORT_TARGET_DATA
7636 && (flags & GOVD_DATA_SHARE_CLASS) == 0))
7637 nflags = GOVD_PRIVATE | GOVD_EXPLICIT;
7638 else
7639 nflags = GOVD_FIRSTPRIVATE;
7640 nflags |= flags & GOVD_SEEN;
7641 t = DECL_VALUE_EXPR (decl);
7642 gcc_assert (INDIRECT_REF_P (t));
7643 t = TREE_OPERAND (t, 0);
7644 gcc_assert (DECL_P (t));
7645 omp_add_variable (ctx, t, nflags);
7648 /* Add all of the variable and type parameters (which should have
7649 been gimplified to a formal temporary) as FIRSTPRIVATE. */
7650 omp_firstprivatize_variable (ctx, DECL_SIZE_UNIT (decl));
7651 omp_firstprivatize_variable (ctx, DECL_SIZE (decl));
7652 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
7654 /* The variable-sized variable itself is never SHARED, only some form
7655 of PRIVATE. The sharing would take place via the pointer variable
7656 which we remapped above. */
7657 if (flags & GOVD_SHARED)
7658 flags = GOVD_SHARED | GOVD_DEBUG_PRIVATE
7659 | (flags & (GOVD_SEEN | GOVD_EXPLICIT));
7661 /* We're going to make use of the TYPE_SIZE_UNIT at least in the
7662 alloca statement we generate for the variable, so make sure it
7663 is available. This isn't automatically needed for the SHARED
7664 case, since we won't be allocating local storage then.
7665 For local variables TYPE_SIZE_UNIT might not be gimplified yet,
7666 in this case omp_notice_variable will be called later
7667 on when it is gimplified. */
7668 else if (! (flags & (GOVD_LOCAL | GOVD_MAP))
7669 && DECL_P (TYPE_SIZE_UNIT (TREE_TYPE (decl))))
7670 omp_notice_variable (ctx, TYPE_SIZE_UNIT (TREE_TYPE (decl)), true);
7672 else if ((flags & (GOVD_MAP | GOVD_LOCAL)) == 0
7673 && omp_privatize_by_reference (decl))
7675 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
7677 /* Similar to the direct variable sized case above, we'll need the
7678 size of references being privatized. */
7679 if ((flags & GOVD_SHARED) == 0)
7681 t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
7682 if (t && DECL_P (t))
7683 omp_notice_variable (ctx, t, true);
7687 if (n != NULL)
7688 n->value |= flags;
7689 else
7690 splay_tree_insert (ctx->variables, (splay_tree_key)decl, flags);
7692 /* For reductions clauses in OpenACC loop directives, by default create a
7693 copy clause on the enclosing parallel construct for carrying back the
7694 results. */
7695 if (ctx->region_type == ORT_ACC && (flags & GOVD_REDUCTION))
7697 struct gimplify_omp_ctx *outer_ctx = ctx->outer_context;
7698 while (outer_ctx)
7700 n = splay_tree_lookup (outer_ctx->variables, (splay_tree_key)decl);
7701 if (n != NULL)
7703 /* Ignore local variables and explicitly declared clauses. */
7704 if (n->value & (GOVD_LOCAL | GOVD_EXPLICIT))
7705 break;
7706 else if (outer_ctx->region_type == ORT_ACC_KERNELS)
7708 /* According to the OpenACC spec, such a reduction variable
7709 should already have a copy map on a kernels construct,
7710 verify that here. */
7711 gcc_assert (!(n->value & GOVD_FIRSTPRIVATE)
7712 && (n->value & GOVD_MAP));
7714 else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
7716 /* Remove firstprivate and make it a copy map. */
7717 n->value &= ~GOVD_FIRSTPRIVATE;
7718 n->value |= GOVD_MAP;
7721 else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
7723 splay_tree_insert (outer_ctx->variables, (splay_tree_key)decl,
7724 GOVD_MAP | GOVD_SEEN);
7725 break;
7727 outer_ctx = outer_ctx->outer_context;
7732 /* Notice a threadprivate variable DECL used in OMP context CTX.
7733 This just prints out diagnostics about threadprivate variable uses
7734 in untied tasks. If DECL2 is non-NULL, prevent this warning
7735 on that variable. */
7737 static bool
7738 omp_notice_threadprivate_variable (struct gimplify_omp_ctx *ctx, tree decl,
7739 tree decl2)
7741 splay_tree_node n;
7742 struct gimplify_omp_ctx *octx;
7744 for (octx = ctx; octx; octx = octx->outer_context)
7745 if ((octx->region_type & ORT_TARGET) != 0
7746 || octx->order_concurrent)
7748 n = splay_tree_lookup (octx->variables, (splay_tree_key)decl);
7749 if (n == NULL)
7751 if (octx->order_concurrent)
7753 error ("threadprivate variable %qE used in a region with"
7754 " %<order(concurrent)%> clause", DECL_NAME (decl));
7755 inform (octx->location, "enclosing region");
7757 else
7759 error ("threadprivate variable %qE used in target region",
7760 DECL_NAME (decl));
7761 inform (octx->location, "enclosing target region");
7763 splay_tree_insert (octx->variables, (splay_tree_key)decl, 0);
7765 if (decl2)
7766 splay_tree_insert (octx->variables, (splay_tree_key)decl2, 0);
7769 if (ctx->region_type != ORT_UNTIED_TASK)
7770 return false;
7771 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7772 if (n == NULL)
7774 error ("threadprivate variable %qE used in untied task",
7775 DECL_NAME (decl));
7776 inform (ctx->location, "enclosing task");
7777 splay_tree_insert (ctx->variables, (splay_tree_key)decl, 0);
7779 if (decl2)
7780 splay_tree_insert (ctx->variables, (splay_tree_key)decl2, 0);
7781 return false;
7784 /* Return true if global var DECL is device resident. */
7786 static bool
7787 device_resident_p (tree decl)
7789 tree attr = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (decl));
7791 if (!attr)
7792 return false;
7794 for (tree t = TREE_VALUE (attr); t; t = TREE_PURPOSE (t))
7796 tree c = TREE_VALUE (t);
7797 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DEVICE_RESIDENT)
7798 return true;
7801 return false;
7804 /* Return true if DECL has an ACC DECLARE attribute. */
7806 static bool
7807 is_oacc_declared (tree decl)
7809 tree t = TREE_CODE (decl) == MEM_REF ? TREE_OPERAND (decl, 0) : decl;
7810 tree declared = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (t));
7811 return declared != NULL_TREE;
7814 /* Determine outer default flags for DECL mentioned in an OMP region
7815 but not declared in an enclosing clause.
7817 ??? Some compiler-generated variables (like SAVE_EXPRs) could be
7818 remapped firstprivate instead of shared. To some extent this is
7819 addressed in omp_firstprivatize_type_sizes, but not
7820 effectively. */
7822 static unsigned
7823 omp_default_clause (struct gimplify_omp_ctx *ctx, tree decl,
7824 bool in_code, unsigned flags)
7826 enum omp_clause_default_kind default_kind = ctx->default_kind;
7827 enum omp_clause_default_kind kind;
7829 kind = lang_hooks.decls.omp_predetermined_sharing (decl);
7830 if (ctx->region_type & ORT_TASK)
7832 tree detach_clause = omp_find_clause (ctx->clauses, OMP_CLAUSE_DETACH);
7834 /* The event-handle specified by a detach clause should always be firstprivate,
7835 regardless of the current default. */
7836 if (detach_clause && OMP_CLAUSE_DECL (detach_clause) == decl)
7837 kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
7839 if (kind != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
7840 default_kind = kind;
7841 else if (VAR_P (decl) && TREE_STATIC (decl) && DECL_IN_CONSTANT_POOL (decl))
7842 default_kind = OMP_CLAUSE_DEFAULT_SHARED;
7843 /* For C/C++ default({,first}private), variables with static storage duration
7844 declared in a namespace or global scope and referenced in construct
7845 must be explicitly specified, i.e. acts as default(none). */
7846 else if ((default_kind == OMP_CLAUSE_DEFAULT_PRIVATE
7847 || default_kind == OMP_CLAUSE_DEFAULT_FIRSTPRIVATE)
7848 && VAR_P (decl)
7849 && is_global_var (decl)
7850 && (DECL_FILE_SCOPE_P (decl)
7851 || (DECL_CONTEXT (decl)
7852 && TREE_CODE (DECL_CONTEXT (decl)) == NAMESPACE_DECL))
7853 && !lang_GNU_Fortran ())
7854 default_kind = OMP_CLAUSE_DEFAULT_NONE;
7856 switch (default_kind)
7858 case OMP_CLAUSE_DEFAULT_NONE:
7860 const char *rtype;
7862 if (ctx->region_type & ORT_PARALLEL)
7863 rtype = "parallel";
7864 else if ((ctx->region_type & ORT_TASKLOOP) == ORT_TASKLOOP)
7865 rtype = "taskloop";
7866 else if (ctx->region_type & ORT_TASK)
7867 rtype = "task";
7868 else if (ctx->region_type & ORT_TEAMS)
7869 rtype = "teams";
7870 else
7871 gcc_unreachable ();
7873 error ("%qE not specified in enclosing %qs",
7874 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rtype);
7875 inform (ctx->location, "enclosing %qs", rtype);
7877 /* FALLTHRU */
7878 case OMP_CLAUSE_DEFAULT_SHARED:
7879 flags |= GOVD_SHARED;
7880 break;
7881 case OMP_CLAUSE_DEFAULT_PRIVATE:
7882 flags |= GOVD_PRIVATE;
7883 break;
7884 case OMP_CLAUSE_DEFAULT_FIRSTPRIVATE:
7885 flags |= GOVD_FIRSTPRIVATE;
7886 break;
7887 case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
7888 /* decl will be either GOVD_FIRSTPRIVATE or GOVD_SHARED. */
7889 gcc_assert ((ctx->region_type & ORT_TASK) != 0);
7890 if (struct gimplify_omp_ctx *octx = ctx->outer_context)
7892 omp_notice_variable (octx, decl, in_code);
7893 for (; octx; octx = octx->outer_context)
7895 splay_tree_node n2;
7897 n2 = splay_tree_lookup (octx->variables, (splay_tree_key) decl);
7898 if ((octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)) != 0
7899 && (n2 == NULL || (n2->value & GOVD_DATA_SHARE_CLASS) == 0))
7900 continue;
7901 if (n2 && (n2->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED)
7903 flags |= GOVD_FIRSTPRIVATE;
7904 goto found_outer;
7906 if ((octx->region_type & (ORT_PARALLEL | ORT_TEAMS)) != 0)
7908 flags |= GOVD_SHARED;
7909 goto found_outer;
7914 if (TREE_CODE (decl) == PARM_DECL
7915 || (!is_global_var (decl)
7916 && DECL_CONTEXT (decl) == current_function_decl))
7917 flags |= GOVD_FIRSTPRIVATE;
7918 else
7919 flags |= GOVD_SHARED;
7920 found_outer:
7921 break;
7923 default:
7924 gcc_unreachable ();
7927 return flags;
7930 /* Return string name for types of OpenACC constructs from ORT_* values. */
7932 static const char *
7933 oacc_region_type_name (enum omp_region_type region_type)
7935 switch (region_type)
7937 case ORT_ACC_DATA:
7938 return "data";
7939 case ORT_ACC_PARALLEL:
7940 return "parallel";
7941 case ORT_ACC_KERNELS:
7942 return "kernels";
7943 case ORT_ACC_SERIAL:
7944 return "serial";
7945 default:
7946 gcc_unreachable ();
7950 /* Determine outer default flags for DECL mentioned in an OACC region
7951 but not declared in an enclosing clause. */
7953 static unsigned
7954 oacc_default_clause (struct gimplify_omp_ctx *ctx, tree decl, unsigned flags)
7956 struct gimplify_omp_ctx *ctx_default = ctx;
7957 /* If no 'default' clause appears on this compute construct... */
7958 if (ctx_default->default_kind == OMP_CLAUSE_DEFAULT_SHARED)
7960 /* ..., see if one appears on a lexically containing 'data'
7961 construct. */
7962 while ((ctx_default = ctx_default->outer_context))
7964 if (ctx_default->region_type == ORT_ACC_DATA
7965 && ctx_default->default_kind != OMP_CLAUSE_DEFAULT_SHARED)
7966 break;
7968 /* If not, reset. */
7969 if (!ctx_default)
7970 ctx_default = ctx;
7973 bool on_device = false;
7974 bool is_private = false;
7975 bool declared = is_oacc_declared (decl);
7976 tree type = TREE_TYPE (decl);
7978 if (omp_privatize_by_reference (decl))
7979 type = TREE_TYPE (type);
7981 /* For Fortran COMMON blocks, only used variables in those blocks are
7982 transfered and remapped. The block itself will have a private clause to
7983 avoid transfering the data twice.
7984 The hook evaluates to false by default. For a variable in Fortran's COMMON
7985 or EQUIVALENCE block, returns 'true' (as we have shared=false) - as only
7986 the variables in such a COMMON/EQUIVALENCE block shall be privatized not
7987 the whole block. For C++ and Fortran, it can also be true under certain
7988 other conditions, if DECL_HAS_VALUE_EXPR. */
7989 if (RECORD_OR_UNION_TYPE_P (type))
7990 is_private = lang_hooks.decls.omp_disregard_value_expr (decl, false);
7992 if ((ctx->region_type & (ORT_ACC_PARALLEL | ORT_ACC_KERNELS)) != 0
7993 && is_global_var (decl)
7994 && device_resident_p (decl)
7995 && !is_private)
7997 on_device = true;
7998 flags |= GOVD_MAP_TO_ONLY;
8001 switch (ctx->region_type)
8003 case ORT_ACC_KERNELS:
8004 if (is_private)
8005 flags |= GOVD_FIRSTPRIVATE;
8006 else if (AGGREGATE_TYPE_P (type))
8008 /* Aggregates default to 'present_or_copy', or 'present'. */
8009 if (ctx_default->default_kind != OMP_CLAUSE_DEFAULT_PRESENT)
8010 flags |= GOVD_MAP;
8011 else
8012 flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
8014 else
8015 /* Scalars default to 'copy'. */
8016 flags |= GOVD_MAP | GOVD_MAP_FORCE;
8018 break;
8020 case ORT_ACC_PARALLEL:
8021 case ORT_ACC_SERIAL:
8022 if (is_private)
8023 flags |= GOVD_FIRSTPRIVATE;
8024 else if (on_device || declared)
8025 flags |= GOVD_MAP;
8026 else if (AGGREGATE_TYPE_P (type))
8028 /* Aggregates default to 'present_or_copy', or 'present'. */
8029 if (ctx_default->default_kind != OMP_CLAUSE_DEFAULT_PRESENT)
8030 flags |= GOVD_MAP;
8031 else
8032 flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
8034 else
8035 /* Scalars default to 'firstprivate'. */
8036 flags |= GOVD_FIRSTPRIVATE;
8038 break;
8040 default:
8041 gcc_unreachable ();
8044 if (DECL_ARTIFICIAL (decl))
8045 ; /* We can get compiler-generated decls, and should not complain
8046 about them. */
8047 else if (ctx_default->default_kind == OMP_CLAUSE_DEFAULT_NONE)
8049 error ("%qE not specified in enclosing OpenACC %qs construct",
8050 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)),
8051 oacc_region_type_name (ctx->region_type));
8052 if (ctx_default != ctx)
8053 inform (ctx->location, "enclosing OpenACC %qs construct and",
8054 oacc_region_type_name (ctx->region_type));
8055 inform (ctx_default->location,
8056 "enclosing OpenACC %qs construct with %qs clause",
8057 oacc_region_type_name (ctx_default->region_type),
8058 "default(none)");
8060 else if (ctx_default->default_kind == OMP_CLAUSE_DEFAULT_PRESENT)
8061 ; /* Handled above. */
8062 else
8063 gcc_checking_assert (ctx_default->default_kind == OMP_CLAUSE_DEFAULT_SHARED);
8065 return flags;
8068 /* Record the fact that DECL was used within the OMP context CTX.
8069 IN_CODE is true when real code uses DECL, and false when we should
8070 merely emit default(none) errors. Return true if DECL is going to
8071 be remapped and thus DECL shouldn't be gimplified into its
8072 DECL_VALUE_EXPR (if any). */
8074 static bool
8075 omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
8077 splay_tree_node n;
8078 unsigned flags = in_code ? GOVD_SEEN : 0;
8079 bool ret = false, shared;
8081 if (error_operand_p (decl))
8082 return false;
8084 if (DECL_ARTIFICIAL (decl))
8086 tree attr = lookup_attribute ("omp allocate var", DECL_ATTRIBUTES (decl));
8087 if (attr)
8088 decl = TREE_VALUE (TREE_VALUE (attr));
8091 if (ctx->region_type == ORT_NONE)
8092 return lang_hooks.decls.omp_disregard_value_expr (decl, false);
8094 if (is_global_var (decl))
8096 /* Threadprivate variables are predetermined. */
8097 if (DECL_THREAD_LOCAL_P (decl))
8098 return omp_notice_threadprivate_variable (ctx, decl, NULL_TREE);
8100 if (DECL_HAS_VALUE_EXPR_P (decl))
8102 if (ctx->region_type & ORT_ACC)
8103 /* For OpenACC, defer expansion of value to avoid transfering
8104 privatized common block data instead of im-/explicitly transfered
8105 variables which are in common blocks. */
8107 else
8109 tree value = get_base_address (DECL_VALUE_EXPR (decl));
8111 if (value && DECL_P (value) && DECL_THREAD_LOCAL_P (value))
8112 return omp_notice_threadprivate_variable (ctx, decl, value);
8116 if (gimplify_omp_ctxp->outer_context == NULL
8117 && VAR_P (decl)
8118 && oacc_get_fn_attrib (current_function_decl))
8120 location_t loc = DECL_SOURCE_LOCATION (decl);
8122 if (lookup_attribute ("omp declare target link",
8123 DECL_ATTRIBUTES (decl)))
8125 error_at (loc,
8126 "%qE with %<link%> clause used in %<routine%> function",
8127 DECL_NAME (decl));
8128 return false;
8130 else if (!lookup_attribute ("omp declare target",
8131 DECL_ATTRIBUTES (decl)))
8133 error_at (loc,
8134 "%qE requires a %<declare%> directive for use "
8135 "in a %<routine%> function", DECL_NAME (decl));
8136 return false;
8141 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
8142 if ((ctx->region_type & ORT_TARGET) != 0)
8144 if (ctx->region_type & ORT_ACC)
8145 /* For OpenACC, as remarked above, defer expansion. */
8146 shared = false;
8147 else
8148 shared = true;
8150 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
8151 if (n == NULL)
8153 unsigned nflags = flags;
8154 if ((ctx->region_type & ORT_ACC) == 0)
8156 bool is_declare_target = false;
8157 if (is_global_var (decl)
8158 && varpool_node::get_create (decl)->offloadable)
8160 struct gimplify_omp_ctx *octx;
8161 for (octx = ctx->outer_context;
8162 octx; octx = octx->outer_context)
8164 n = splay_tree_lookup (octx->variables,
8165 (splay_tree_key)decl);
8166 if (n
8167 && (n->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED
8168 && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
8169 break;
8171 is_declare_target = octx == NULL;
8173 if (!is_declare_target)
8175 int gdmk;
8176 enum omp_clause_defaultmap_kind kind;
8177 if (lang_hooks.decls.omp_allocatable_p (decl))
8178 gdmk = GDMK_ALLOCATABLE;
8179 else if (lang_hooks.decls.omp_scalar_target_p (decl))
8180 gdmk = GDMK_SCALAR_TARGET;
8181 else if (lang_hooks.decls.omp_scalar_p (decl, false))
8182 gdmk = GDMK_SCALAR;
8183 else if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
8184 || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
8185 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
8186 == POINTER_TYPE)))
8187 gdmk = GDMK_POINTER;
8188 else
8189 gdmk = GDMK_AGGREGATE;
8190 kind = lang_hooks.decls.omp_predetermined_mapping (decl);
8191 if (kind != OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
8193 if (kind == OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE)
8194 nflags |= GOVD_FIRSTPRIVATE;
8195 else if (kind == OMP_CLAUSE_DEFAULTMAP_TO)
8196 nflags |= GOVD_MAP | GOVD_MAP_TO_ONLY;
8197 else
8198 gcc_unreachable ();
8200 else if (ctx->defaultmap[gdmk] == 0)
8202 tree d = lang_hooks.decls.omp_report_decl (decl);
8203 error ("%qE not specified in enclosing %<target%>",
8204 DECL_NAME (d));
8205 inform (ctx->location, "enclosing %<target%>");
8207 else if (ctx->defaultmap[gdmk]
8208 & (GOVD_MAP_0LEN_ARRAY | GOVD_FIRSTPRIVATE))
8209 nflags |= ctx->defaultmap[gdmk];
8210 else if (ctx->defaultmap[gdmk] & GOVD_MAP_FORCE_PRESENT)
8212 gcc_assert (ctx->defaultmap[gdmk] & GOVD_MAP);
8213 nflags |= ctx->defaultmap[gdmk] | GOVD_MAP_ALLOC_ONLY;
8215 else
8217 gcc_assert (ctx->defaultmap[gdmk] & GOVD_MAP);
8218 nflags |= ctx->defaultmap[gdmk] & ~GOVD_MAP;
8223 struct gimplify_omp_ctx *octx = ctx->outer_context;
8224 if ((ctx->region_type & ORT_ACC) && octx)
8226 /* Look in outer OpenACC contexts, to see if there's a
8227 data attribute for this variable. */
8228 omp_notice_variable (octx, decl, in_code);
8230 for (; octx; octx = octx->outer_context)
8232 if (!(octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)))
8233 break;
8234 splay_tree_node n2
8235 = splay_tree_lookup (octx->variables,
8236 (splay_tree_key) decl);
8237 if (n2)
8239 if (octx->region_type == ORT_ACC_HOST_DATA)
8240 error ("variable %qE declared in enclosing "
8241 "%<host_data%> region", DECL_NAME (decl));
8242 nflags |= GOVD_MAP;
8243 if (octx->region_type == ORT_ACC_DATA
8244 && (n2->value & GOVD_MAP_0LEN_ARRAY))
8245 nflags |= GOVD_MAP_0LEN_ARRAY;
8246 goto found_outer;
8251 if ((nflags & ~(GOVD_MAP_TO_ONLY | GOVD_MAP_FROM_ONLY
8252 | GOVD_MAP_ALLOC_ONLY)) == flags)
8254 tree type = TREE_TYPE (decl);
8256 if (gimplify_omp_ctxp->target_firstprivatize_array_bases
8257 && omp_privatize_by_reference (decl))
8258 type = TREE_TYPE (type);
8259 if (!omp_mappable_type (type))
8261 error ("%qD referenced in target region does not have "
8262 "a mappable type", decl);
8263 nflags |= GOVD_MAP | GOVD_EXPLICIT;
8265 else
8267 if ((ctx->region_type & ORT_ACC) != 0)
8268 nflags = oacc_default_clause (ctx, decl, flags);
8269 else
8270 nflags |= GOVD_MAP;
8273 found_outer:
8274 omp_add_variable (ctx, decl, nflags);
8276 else
8278 /* If nothing changed, there's nothing left to do. */
8279 if ((n->value & flags) == flags)
8280 return ret;
8281 flags |= n->value;
8282 n->value = flags;
8284 goto do_outer;
8287 if (n == NULL)
8289 if (ctx->region_type == ORT_WORKSHARE
8290 || ctx->region_type == ORT_TASKGROUP
8291 || ctx->region_type == ORT_SIMD
8292 || ctx->region_type == ORT_ACC
8293 || (ctx->region_type & ORT_TARGET_DATA) != 0)
8294 goto do_outer;
8296 flags = omp_default_clause (ctx, decl, in_code, flags);
8298 if ((flags & GOVD_PRIVATE)
8299 && lang_hooks.decls.omp_private_outer_ref (decl))
8300 flags |= GOVD_PRIVATE_OUTER_REF;
8302 omp_add_variable (ctx, decl, flags);
8304 shared = (flags & GOVD_SHARED) != 0;
8305 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
8306 goto do_outer;
8309 /* Don't mark as GOVD_SEEN addressable temporaries seen only in simd
8310 lb, b or incr expressions, those shouldn't be turned into simd arrays. */
8311 if (ctx->region_type == ORT_SIMD
8312 && ctx->in_for_exprs
8313 && ((n->value & (GOVD_PRIVATE | GOVD_SEEN | GOVD_EXPLICIT))
8314 == GOVD_PRIVATE))
8315 flags &= ~GOVD_SEEN;
8317 if ((n->value & (GOVD_SEEN | GOVD_LOCAL)) == 0
8318 && (flags & (GOVD_SEEN | GOVD_LOCAL)) == GOVD_SEEN
8319 && DECL_SIZE (decl))
8321 if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
8323 splay_tree_node n2;
8324 tree t = DECL_VALUE_EXPR (decl);
8325 gcc_assert (INDIRECT_REF_P (t));
8326 t = TREE_OPERAND (t, 0);
8327 gcc_assert (DECL_P (t));
8328 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
8329 n2->value |= GOVD_SEEN;
8331 else if (omp_privatize_by_reference (decl)
8332 && TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)))
8333 && (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))))
8334 != INTEGER_CST))
8336 splay_tree_node n2;
8337 tree t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
8338 gcc_assert (DECL_P (t));
8339 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
8340 if (n2)
8341 omp_notice_variable (ctx, t, true);
8345 if (ctx->region_type & ORT_ACC)
8346 /* For OpenACC, as remarked above, defer expansion. */
8347 shared = false;
8348 else
8349 shared = ((flags | n->value) & GOVD_SHARED) != 0;
8350 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
8352 /* If nothing changed, there's nothing left to do. */
8353 if ((n->value & flags) == flags)
8354 return ret;
8355 flags |= n->value;
8356 n->value = flags;
8358 do_outer:
8359 /* If the variable is private in the current context, then we don't
8360 need to propagate anything to an outer context. */
8361 if ((flags & GOVD_PRIVATE) && !(flags & GOVD_PRIVATE_OUTER_REF))
8362 return ret;
8363 if ((flags & (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
8364 == (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
8365 return ret;
8366 if ((flags & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
8367 | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
8368 == (GOVD_LASTPRIVATE | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
8369 return ret;
8370 if (ctx->outer_context
8371 && omp_notice_variable (ctx->outer_context, decl, in_code))
8372 return true;
8373 return ret;
8376 /* Verify that DECL is private within CTX. If there's specific information
8377 to the contrary in the innermost scope, generate an error. */
8379 static bool
8380 omp_is_private (struct gimplify_omp_ctx *ctx, tree decl, int simd)
8382 splay_tree_node n;
8384 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
8385 if (n != NULL)
8387 if (n->value & GOVD_SHARED)
8389 if (ctx == gimplify_omp_ctxp)
8391 if (simd)
8392 error ("iteration variable %qE is predetermined linear",
8393 DECL_NAME (decl));
8394 else
8395 error ("iteration variable %qE should be private",
8396 DECL_NAME (decl));
8397 n->value = GOVD_PRIVATE;
8398 return true;
8400 else
8401 return false;
8403 else if ((n->value & GOVD_EXPLICIT) != 0
8404 && (ctx == gimplify_omp_ctxp
8405 || (ctx->region_type == ORT_COMBINED_PARALLEL
8406 && gimplify_omp_ctxp->outer_context == ctx)))
8408 if ((n->value & GOVD_FIRSTPRIVATE) != 0)
8409 error ("iteration variable %qE should not be firstprivate",
8410 DECL_NAME (decl));
8411 else if ((n->value & GOVD_REDUCTION) != 0)
8412 error ("iteration variable %qE should not be reduction",
8413 DECL_NAME (decl));
8414 else if (simd != 1 && (n->value & GOVD_LINEAR) != 0)
8415 error ("iteration variable %qE should not be linear",
8416 DECL_NAME (decl));
8418 return (ctx == gimplify_omp_ctxp
8419 || (ctx->region_type == ORT_COMBINED_PARALLEL
8420 && gimplify_omp_ctxp->outer_context == ctx));
8423 if (ctx->region_type != ORT_WORKSHARE
8424 && ctx->region_type != ORT_TASKGROUP
8425 && ctx->region_type != ORT_SIMD
8426 && ctx->region_type != ORT_ACC)
8427 return false;
8428 else if (ctx->outer_context)
8429 return omp_is_private (ctx->outer_context, decl, simd);
8430 return false;
8433 /* Return true if DECL is private within a parallel region
8434 that binds to the current construct's context or in parallel
8435 region's REDUCTION clause. */
8437 static bool
8438 omp_check_private (struct gimplify_omp_ctx *ctx, tree decl, bool copyprivate)
8440 splay_tree_node n;
8444 ctx = ctx->outer_context;
8445 if (ctx == NULL)
8447 if (is_global_var (decl))
8448 return false;
8450 /* References might be private, but might be shared too,
8451 when checking for copyprivate, assume they might be
8452 private, otherwise assume they might be shared. */
8453 if (copyprivate)
8454 return true;
8456 if (omp_privatize_by_reference (decl))
8457 return false;
8459 /* Treat C++ privatized non-static data members outside
8460 of the privatization the same. */
8461 if (omp_member_access_dummy_var (decl))
8462 return false;
8464 return true;
8467 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
8469 if ((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
8470 && (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0))
8472 if ((ctx->region_type & ORT_TARGET_DATA) != 0
8473 || n == NULL
8474 || (n->value & GOVD_MAP) == 0)
8475 continue;
8476 return false;
8479 if (n != NULL)
8481 if ((n->value & GOVD_LOCAL) != 0
8482 && omp_member_access_dummy_var (decl))
8483 return false;
8484 return (n->value & GOVD_SHARED) == 0;
8487 if (ctx->region_type == ORT_WORKSHARE
8488 || ctx->region_type == ORT_TASKGROUP
8489 || ctx->region_type == ORT_SIMD
8490 || ctx->region_type == ORT_ACC)
8491 continue;
8493 break;
8495 while (1);
8496 return false;
8499 /* Callback for walk_tree to find a DECL_EXPR for the given DECL. */
8501 static tree
8502 find_decl_expr (tree *tp, int *walk_subtrees, void *data)
8504 tree t = *tp;
8506 /* If this node has been visited, unmark it and keep looking. */
8507 if (TREE_CODE (t) == DECL_EXPR && DECL_EXPR_DECL (t) == (tree) data)
8508 return t;
8510 if (IS_TYPE_OR_DECL_P (t))
8511 *walk_subtrees = 0;
8512 return NULL_TREE;
8516 /* Gimplify the affinity clause but effectively ignore it.
8517 Generate:
8518 var = begin;
8519 if ((step > 1) ? var <= end : var > end)
8520 locatator_var_expr; */
8522 static void
8523 gimplify_omp_affinity (tree *list_p, gimple_seq *pre_p)
8525 tree last_iter = NULL_TREE;
8526 tree last_bind = NULL_TREE;
8527 tree label = NULL_TREE;
8528 tree *last_body = NULL;
8529 for (tree c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
8530 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY)
8532 tree t = OMP_CLAUSE_DECL (c);
8533 if (TREE_CODE (t) == TREE_LIST
8534 && TREE_PURPOSE (t)
8535 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
8537 if (TREE_VALUE (t) == null_pointer_node)
8538 continue;
8539 if (TREE_PURPOSE (t) != last_iter)
8541 if (last_bind)
8543 append_to_statement_list (label, last_body);
8544 gimplify_and_add (last_bind, pre_p);
8545 last_bind = NULL_TREE;
8547 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8549 if (gimplify_expr (&TREE_VEC_ELT (it, 1), pre_p, NULL,
8550 is_gimple_val, fb_rvalue) == GS_ERROR
8551 || gimplify_expr (&TREE_VEC_ELT (it, 2), pre_p, NULL,
8552 is_gimple_val, fb_rvalue) == GS_ERROR
8553 || gimplify_expr (&TREE_VEC_ELT (it, 3), pre_p, NULL,
8554 is_gimple_val, fb_rvalue) == GS_ERROR
8555 || (gimplify_expr (&TREE_VEC_ELT (it, 4), pre_p, NULL,
8556 is_gimple_val, fb_rvalue)
8557 == GS_ERROR))
8558 return;
8560 last_iter = TREE_PURPOSE (t);
8561 tree block = TREE_VEC_ELT (TREE_PURPOSE (t), 5);
8562 last_bind = build3 (BIND_EXPR, void_type_node, BLOCK_VARS (block),
8563 NULL, block);
8564 last_body = &BIND_EXPR_BODY (last_bind);
8565 tree cond = NULL_TREE;
8566 location_t loc = OMP_CLAUSE_LOCATION (c);
8567 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8569 tree var = TREE_VEC_ELT (it, 0);
8570 tree begin = TREE_VEC_ELT (it, 1);
8571 tree end = TREE_VEC_ELT (it, 2);
8572 tree step = TREE_VEC_ELT (it, 3);
8573 loc = DECL_SOURCE_LOCATION (var);
8574 tree tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
8575 var, begin);
8576 append_to_statement_list_force (tem, last_body);
8578 tree cond1 = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8579 step, build_zero_cst (TREE_TYPE (step)));
8580 tree cond2 = fold_build2_loc (loc, LE_EXPR, boolean_type_node,
8581 var, end);
8582 tree cond3 = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8583 var, end);
8584 cond1 = fold_build3_loc (loc, COND_EXPR, boolean_type_node,
8585 cond1, cond2, cond3);
8586 if (cond)
8587 cond = fold_build2_loc (loc, TRUTH_AND_EXPR,
8588 boolean_type_node, cond, cond1);
8589 else
8590 cond = cond1;
8592 tree cont_label = create_artificial_label (loc);
8593 label = build1 (LABEL_EXPR, void_type_node, cont_label);
8594 tree tem = fold_build3_loc (loc, COND_EXPR, void_type_node, cond,
8595 void_node,
8596 build_and_jump (&cont_label));
8597 append_to_statement_list_force (tem, last_body);
8599 if (TREE_CODE (TREE_VALUE (t)) == COMPOUND_EXPR)
8601 append_to_statement_list (TREE_OPERAND (TREE_VALUE (t), 0),
8602 last_body);
8603 TREE_VALUE (t) = TREE_OPERAND (TREE_VALUE (t), 1);
8605 if (error_operand_p (TREE_VALUE (t)))
8606 return;
8607 append_to_statement_list_force (TREE_VALUE (t), last_body);
8608 TREE_VALUE (t) = null_pointer_node;
8610 else
8612 if (last_bind)
8614 append_to_statement_list (label, last_body);
8615 gimplify_and_add (last_bind, pre_p);
8616 last_bind = NULL_TREE;
8618 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
8620 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
8621 NULL, is_gimple_val, fb_rvalue);
8622 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
8624 if (error_operand_p (OMP_CLAUSE_DECL (c)))
8625 return;
8626 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
8627 is_gimple_lvalue, fb_lvalue) == GS_ERROR)
8628 return;
8629 gimplify_and_add (OMP_CLAUSE_DECL (c), pre_p);
8632 if (last_bind)
8634 append_to_statement_list (label, last_body);
8635 gimplify_and_add (last_bind, pre_p);
8637 return;
8640 /* If *LIST_P contains any OpenMP depend clauses with iterators,
8641 lower all the depend clauses by populating corresponding depend
8642 array. Returns 0 if there are no such depend clauses, or
8643 2 if all depend clauses should be removed, 1 otherwise. */
8645 static int
8646 gimplify_omp_depend (tree *list_p, gimple_seq *pre_p)
8648 tree c;
8649 gimple *g;
8650 size_t n[5] = { 0, 0, 0, 0, 0 };
8651 bool unused[5];
8652 tree counts[5] = { NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE };
8653 tree last_iter = NULL_TREE, last_count = NULL_TREE;
8654 size_t i, j;
8655 location_t first_loc = UNKNOWN_LOCATION;
8657 for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
8658 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
8660 switch (OMP_CLAUSE_DEPEND_KIND (c))
8662 case OMP_CLAUSE_DEPEND_IN:
8663 i = 2;
8664 break;
8665 case OMP_CLAUSE_DEPEND_OUT:
8666 case OMP_CLAUSE_DEPEND_INOUT:
8667 i = 0;
8668 break;
8669 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
8670 i = 1;
8671 break;
8672 case OMP_CLAUSE_DEPEND_DEPOBJ:
8673 i = 3;
8674 break;
8675 case OMP_CLAUSE_DEPEND_INOUTSET:
8676 i = 4;
8677 break;
8678 default:
8679 gcc_unreachable ();
8681 tree t = OMP_CLAUSE_DECL (c);
8682 if (first_loc == UNKNOWN_LOCATION)
8683 first_loc = OMP_CLAUSE_LOCATION (c);
8684 if (TREE_CODE (t) == TREE_LIST
8685 && TREE_PURPOSE (t)
8686 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
8688 if (TREE_PURPOSE (t) != last_iter)
8690 tree tcnt = size_one_node;
8691 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8693 if (gimplify_expr (&TREE_VEC_ELT (it, 1), pre_p, NULL,
8694 is_gimple_val, fb_rvalue) == GS_ERROR
8695 || gimplify_expr (&TREE_VEC_ELT (it, 2), pre_p, NULL,
8696 is_gimple_val, fb_rvalue) == GS_ERROR
8697 || gimplify_expr (&TREE_VEC_ELT (it, 3), pre_p, NULL,
8698 is_gimple_val, fb_rvalue) == GS_ERROR
8699 || (gimplify_expr (&TREE_VEC_ELT (it, 4), pre_p, NULL,
8700 is_gimple_val, fb_rvalue)
8701 == GS_ERROR))
8702 return 2;
8703 tree var = TREE_VEC_ELT (it, 0);
8704 tree begin = TREE_VEC_ELT (it, 1);
8705 tree end = TREE_VEC_ELT (it, 2);
8706 tree step = TREE_VEC_ELT (it, 3);
8707 tree orig_step = TREE_VEC_ELT (it, 4);
8708 tree type = TREE_TYPE (var);
8709 tree stype = TREE_TYPE (step);
8710 location_t loc = DECL_SOURCE_LOCATION (var);
8711 tree endmbegin;
8712 /* Compute count for this iterator as
8713 orig_step > 0
8714 ? (begin < end ? (end - begin + (step - 1)) / step : 0)
8715 : (begin > end ? (end - begin + (step + 1)) / step : 0)
8716 and compute product of those for the entire depend
8717 clause. */
8718 if (POINTER_TYPE_P (type))
8719 endmbegin = fold_build2_loc (loc, POINTER_DIFF_EXPR,
8720 stype, end, begin);
8721 else
8722 endmbegin = fold_build2_loc (loc, MINUS_EXPR, type,
8723 end, begin);
8724 tree stepm1 = fold_build2_loc (loc, MINUS_EXPR, stype,
8725 step,
8726 build_int_cst (stype, 1));
8727 tree stepp1 = fold_build2_loc (loc, PLUS_EXPR, stype, step,
8728 build_int_cst (stype, 1));
8729 tree pos = fold_build2_loc (loc, PLUS_EXPR, stype,
8730 unshare_expr (endmbegin),
8731 stepm1);
8732 pos = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype,
8733 pos, step);
8734 tree neg = fold_build2_loc (loc, PLUS_EXPR, stype,
8735 endmbegin, stepp1);
8736 if (TYPE_UNSIGNED (stype))
8738 neg = fold_build1_loc (loc, NEGATE_EXPR, stype, neg);
8739 step = fold_build1_loc (loc, NEGATE_EXPR, stype, step);
8741 neg = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype,
8742 neg, step);
8743 step = NULL_TREE;
8744 tree cond = fold_build2_loc (loc, LT_EXPR,
8745 boolean_type_node,
8746 begin, end);
8747 pos = fold_build3_loc (loc, COND_EXPR, stype, cond, pos,
8748 build_int_cst (stype, 0));
8749 cond = fold_build2_loc (loc, LT_EXPR, boolean_type_node,
8750 end, begin);
8751 neg = fold_build3_loc (loc, COND_EXPR, stype, cond, neg,
8752 build_int_cst (stype, 0));
8753 tree osteptype = TREE_TYPE (orig_step);
8754 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8755 orig_step,
8756 build_int_cst (osteptype, 0));
8757 tree cnt = fold_build3_loc (loc, COND_EXPR, stype,
8758 cond, pos, neg);
8759 cnt = fold_convert_loc (loc, sizetype, cnt);
8760 if (gimplify_expr (&cnt, pre_p, NULL, is_gimple_val,
8761 fb_rvalue) == GS_ERROR)
8762 return 2;
8763 tcnt = size_binop_loc (loc, MULT_EXPR, tcnt, cnt);
8765 if (gimplify_expr (&tcnt, pre_p, NULL, is_gimple_val,
8766 fb_rvalue) == GS_ERROR)
8767 return 2;
8768 last_iter = TREE_PURPOSE (t);
8769 last_count = tcnt;
8771 if (counts[i] == NULL_TREE)
8772 counts[i] = last_count;
8773 else
8774 counts[i] = size_binop_loc (OMP_CLAUSE_LOCATION (c),
8775 PLUS_EXPR, counts[i], last_count);
8777 else
8778 n[i]++;
8780 for (i = 0; i < 5; i++)
8781 if (counts[i])
8782 break;
8783 if (i == 5)
8784 return 0;
8786 tree total = size_zero_node;
8787 for (i = 0; i < 5; i++)
8789 unused[i] = counts[i] == NULL_TREE && n[i] == 0;
8790 if (counts[i] == NULL_TREE)
8791 counts[i] = size_zero_node;
8792 if (n[i])
8793 counts[i] = size_binop (PLUS_EXPR, counts[i], size_int (n[i]));
8794 if (gimplify_expr (&counts[i], pre_p, NULL, is_gimple_val,
8795 fb_rvalue) == GS_ERROR)
8796 return 2;
8797 total = size_binop (PLUS_EXPR, total, counts[i]);
8800 if (gimplify_expr (&total, pre_p, NULL, is_gimple_val, fb_rvalue)
8801 == GS_ERROR)
8802 return 2;
8803 bool is_old = unused[1] && unused[3] && unused[4];
8804 tree totalpx = size_binop (PLUS_EXPR, unshare_expr (total),
8805 size_int (is_old ? 1 : 4));
8806 if (!unused[4])
8807 totalpx = size_binop (PLUS_EXPR, totalpx,
8808 size_binop (MULT_EXPR, counts[4], size_int (2)));
8809 tree type = build_array_type (ptr_type_node, build_index_type (totalpx));
8810 tree array = create_tmp_var_raw (type);
8811 TREE_ADDRESSABLE (array) = 1;
8812 if (!poly_int_tree_p (totalpx))
8814 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (array)))
8815 gimplify_type_sizes (TREE_TYPE (array), pre_p);
8816 if (gimplify_omp_ctxp)
8818 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
8819 while (ctx
8820 && (ctx->region_type == ORT_WORKSHARE
8821 || ctx->region_type == ORT_TASKGROUP
8822 || ctx->region_type == ORT_SIMD
8823 || ctx->region_type == ORT_ACC))
8824 ctx = ctx->outer_context;
8825 if (ctx)
8826 omp_add_variable (ctx, array, GOVD_LOCAL | GOVD_SEEN);
8828 gimplify_vla_decl (array, pre_p);
8830 else
8831 gimple_add_tmp_var (array);
8832 tree r = build4 (ARRAY_REF, ptr_type_node, array, size_int (0), NULL_TREE,
8833 NULL_TREE);
8834 tree tem;
8835 if (!is_old)
8837 tem = build2 (MODIFY_EXPR, void_type_node, r,
8838 build_int_cst (ptr_type_node, 0));
8839 gimplify_and_add (tem, pre_p);
8840 r = build4 (ARRAY_REF, ptr_type_node, array, size_int (1), NULL_TREE,
8841 NULL_TREE);
8843 tem = build2 (MODIFY_EXPR, void_type_node, r,
8844 fold_convert (ptr_type_node, total));
8845 gimplify_and_add (tem, pre_p);
8846 for (i = 1; i < (is_old ? 2 : 4); i++)
8848 r = build4 (ARRAY_REF, ptr_type_node, array, size_int (i + !is_old),
8849 NULL_TREE, NULL_TREE);
8850 tem = build2 (MODIFY_EXPR, void_type_node, r, counts[i - 1]);
8851 gimplify_and_add (tem, pre_p);
8854 tree cnts[6];
8855 for (j = 5; j; j--)
8856 if (!unused[j - 1])
8857 break;
8858 for (i = 0; i < 5; i++)
8860 if (i && (i >= j || unused[i - 1]))
8862 cnts[i] = cnts[i - 1];
8863 continue;
8865 cnts[i] = create_tmp_var (sizetype);
8866 if (i == 0)
8867 g = gimple_build_assign (cnts[i], size_int (is_old ? 2 : 5));
8868 else
8870 tree t;
8871 if (is_old)
8872 t = size_binop (PLUS_EXPR, counts[0], size_int (2));
8873 else
8874 t = size_binop (PLUS_EXPR, cnts[i - 1], counts[i - 1]);
8875 if (gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue)
8876 == GS_ERROR)
8877 return 2;
8878 g = gimple_build_assign (cnts[i], t);
8880 gimple_seq_add_stmt (pre_p, g);
8882 if (unused[4])
8883 cnts[5] = NULL_TREE;
8884 else
8886 tree t = size_binop (PLUS_EXPR, total, size_int (5));
8887 cnts[5] = create_tmp_var (sizetype);
8888 g = gimple_build_assign (cnts[i], t);
8889 gimple_seq_add_stmt (pre_p, g);
8892 last_iter = NULL_TREE;
8893 tree last_bind = NULL_TREE;
8894 tree *last_body = NULL;
8895 for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
8896 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
8898 switch (OMP_CLAUSE_DEPEND_KIND (c))
8900 case OMP_CLAUSE_DEPEND_IN:
8901 i = 2;
8902 break;
8903 case OMP_CLAUSE_DEPEND_OUT:
8904 case OMP_CLAUSE_DEPEND_INOUT:
8905 i = 0;
8906 break;
8907 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
8908 i = 1;
8909 break;
8910 case OMP_CLAUSE_DEPEND_DEPOBJ:
8911 i = 3;
8912 break;
8913 case OMP_CLAUSE_DEPEND_INOUTSET:
8914 i = 4;
8915 break;
8916 default:
8917 gcc_unreachable ();
8919 tree t = OMP_CLAUSE_DECL (c);
8920 if (TREE_CODE (t) == TREE_LIST
8921 && TREE_PURPOSE (t)
8922 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
8924 if (TREE_PURPOSE (t) != last_iter)
8926 if (last_bind)
8927 gimplify_and_add (last_bind, pre_p);
8928 tree block = TREE_VEC_ELT (TREE_PURPOSE (t), 5);
8929 last_bind = build3 (BIND_EXPR, void_type_node,
8930 BLOCK_VARS (block), NULL, block);
8931 TREE_SIDE_EFFECTS (last_bind) = 1;
8932 SET_EXPR_LOCATION (last_bind, OMP_CLAUSE_LOCATION (c));
8933 tree *p = &BIND_EXPR_BODY (last_bind);
8934 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8936 tree var = TREE_VEC_ELT (it, 0);
8937 tree begin = TREE_VEC_ELT (it, 1);
8938 tree end = TREE_VEC_ELT (it, 2);
8939 tree step = TREE_VEC_ELT (it, 3);
8940 tree orig_step = TREE_VEC_ELT (it, 4);
8941 tree type = TREE_TYPE (var);
8942 location_t loc = DECL_SOURCE_LOCATION (var);
8943 /* Emit:
8944 var = begin;
8945 goto cond_label;
8946 beg_label:
8948 var = var + step;
8949 cond_label:
8950 if (orig_step > 0) {
8951 if (var < end) goto beg_label;
8952 } else {
8953 if (var > end) goto beg_label;
8955 for each iterator, with inner iterators added to
8956 the ... above. */
8957 tree beg_label = create_artificial_label (loc);
8958 tree cond_label = NULL_TREE;
8959 tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
8960 var, begin);
8961 append_to_statement_list_force (tem, p);
8962 tem = build_and_jump (&cond_label);
8963 append_to_statement_list_force (tem, p);
8964 tem = build1 (LABEL_EXPR, void_type_node, beg_label);
8965 append_to_statement_list (tem, p);
8966 tree bind = build3 (BIND_EXPR, void_type_node, NULL_TREE,
8967 NULL_TREE, NULL_TREE);
8968 TREE_SIDE_EFFECTS (bind) = 1;
8969 SET_EXPR_LOCATION (bind, loc);
8970 append_to_statement_list_force (bind, p);
8971 if (POINTER_TYPE_P (type))
8972 tem = build2_loc (loc, POINTER_PLUS_EXPR, type,
8973 var, fold_convert_loc (loc, sizetype,
8974 step));
8975 else
8976 tem = build2_loc (loc, PLUS_EXPR, type, var, step);
8977 tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
8978 var, tem);
8979 append_to_statement_list_force (tem, p);
8980 tem = build1 (LABEL_EXPR, void_type_node, cond_label);
8981 append_to_statement_list (tem, p);
8982 tree cond = fold_build2_loc (loc, LT_EXPR,
8983 boolean_type_node,
8984 var, end);
8985 tree pos
8986 = fold_build3_loc (loc, COND_EXPR, void_type_node,
8987 cond, build_and_jump (&beg_label),
8988 void_node);
8989 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8990 var, end);
8991 tree neg
8992 = fold_build3_loc (loc, COND_EXPR, void_type_node,
8993 cond, build_and_jump (&beg_label),
8994 void_node);
8995 tree osteptype = TREE_TYPE (orig_step);
8996 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8997 orig_step,
8998 build_int_cst (osteptype, 0));
8999 tem = fold_build3_loc (loc, COND_EXPR, void_type_node,
9000 cond, pos, neg);
9001 append_to_statement_list_force (tem, p);
9002 p = &BIND_EXPR_BODY (bind);
9004 last_body = p;
9006 last_iter = TREE_PURPOSE (t);
9007 if (TREE_CODE (TREE_VALUE (t)) == COMPOUND_EXPR)
9009 append_to_statement_list (TREE_OPERAND (TREE_VALUE (t),
9010 0), last_body);
9011 TREE_VALUE (t) = TREE_OPERAND (TREE_VALUE (t), 1);
9013 if (error_operand_p (TREE_VALUE (t)))
9014 return 2;
9015 if (TREE_VALUE (t) != null_pointer_node)
9016 TREE_VALUE (t) = build_fold_addr_expr (TREE_VALUE (t));
9017 if (i == 4)
9019 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
9020 NULL_TREE, NULL_TREE);
9021 tree r2 = build4 (ARRAY_REF, ptr_type_node, array, cnts[5],
9022 NULL_TREE, NULL_TREE);
9023 r2 = build_fold_addr_expr_with_type (r2, ptr_type_node);
9024 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
9025 void_type_node, r, r2);
9026 append_to_statement_list_force (tem, last_body);
9027 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
9028 void_type_node, cnts[i],
9029 size_binop (PLUS_EXPR, cnts[i],
9030 size_int (1)));
9031 append_to_statement_list_force (tem, last_body);
9032 i = 5;
9034 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
9035 NULL_TREE, NULL_TREE);
9036 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
9037 void_type_node, r, TREE_VALUE (t));
9038 append_to_statement_list_force (tem, last_body);
9039 if (i == 5)
9041 r = build4 (ARRAY_REF, ptr_type_node, array,
9042 size_binop (PLUS_EXPR, cnts[i], size_int (1)),
9043 NULL_TREE, NULL_TREE);
9044 tem = build_int_cst (ptr_type_node, GOMP_DEPEND_INOUTSET);
9045 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
9046 void_type_node, r, tem);
9047 append_to_statement_list_force (tem, last_body);
9049 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
9050 void_type_node, cnts[i],
9051 size_binop (PLUS_EXPR, cnts[i],
9052 size_int (1 + (i == 5))));
9053 append_to_statement_list_force (tem, last_body);
9054 TREE_VALUE (t) = null_pointer_node;
9056 else
9058 if (last_bind)
9060 gimplify_and_add (last_bind, pre_p);
9061 last_bind = NULL_TREE;
9063 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
9065 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
9066 NULL, is_gimple_val, fb_rvalue);
9067 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
9069 if (error_operand_p (OMP_CLAUSE_DECL (c)))
9070 return 2;
9071 if (OMP_CLAUSE_DECL (c) != null_pointer_node)
9072 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
9073 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
9074 is_gimple_val, fb_rvalue) == GS_ERROR)
9075 return 2;
9076 if (i == 4)
9078 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
9079 NULL_TREE, NULL_TREE);
9080 tree r2 = build4 (ARRAY_REF, ptr_type_node, array, cnts[5],
9081 NULL_TREE, NULL_TREE);
9082 r2 = build_fold_addr_expr_with_type (r2, ptr_type_node);
9083 tem = build2 (MODIFY_EXPR, void_type_node, r, r2);
9084 gimplify_and_add (tem, pre_p);
9085 g = gimple_build_assign (cnts[i], size_binop (PLUS_EXPR,
9086 cnts[i],
9087 size_int (1)));
9088 gimple_seq_add_stmt (pre_p, g);
9089 i = 5;
9091 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
9092 NULL_TREE, NULL_TREE);
9093 tem = build2 (MODIFY_EXPR, void_type_node, r, OMP_CLAUSE_DECL (c));
9094 gimplify_and_add (tem, pre_p);
9095 if (i == 5)
9097 r = build4 (ARRAY_REF, ptr_type_node, array,
9098 size_binop (PLUS_EXPR, cnts[i], size_int (1)),
9099 NULL_TREE, NULL_TREE);
9100 tem = build_int_cst (ptr_type_node, GOMP_DEPEND_INOUTSET);
9101 tem = build2 (MODIFY_EXPR, void_type_node, r, tem);
9102 append_to_statement_list_force (tem, last_body);
9103 gimplify_and_add (tem, pre_p);
9105 g = gimple_build_assign (cnts[i],
9106 size_binop (PLUS_EXPR, cnts[i],
9107 size_int (1 + (i == 5))));
9108 gimple_seq_add_stmt (pre_p, g);
9111 if (last_bind)
9112 gimplify_and_add (last_bind, pre_p);
9113 tree cond = boolean_false_node;
9114 if (is_old)
9116 if (!unused[0])
9117 cond = build2_loc (first_loc, NE_EXPR, boolean_type_node, cnts[0],
9118 size_binop_loc (first_loc, PLUS_EXPR, counts[0],
9119 size_int (2)));
9120 if (!unused[2])
9121 cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond,
9122 build2_loc (first_loc, NE_EXPR, boolean_type_node,
9123 cnts[2],
9124 size_binop_loc (first_loc, PLUS_EXPR,
9125 totalpx,
9126 size_int (1))));
9128 else
9130 tree prev = size_int (5);
9131 for (i = 0; i < 5; i++)
9133 if (unused[i])
9134 continue;
9135 prev = size_binop_loc (first_loc, PLUS_EXPR, counts[i], prev);
9136 cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond,
9137 build2_loc (first_loc, NE_EXPR, boolean_type_node,
9138 cnts[i], unshare_expr (prev)));
9141 tem = build3_loc (first_loc, COND_EXPR, void_type_node, cond,
9142 build_call_expr_loc (first_loc,
9143 builtin_decl_explicit (BUILT_IN_TRAP),
9144 0), void_node);
9145 gimplify_and_add (tem, pre_p);
9146 c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_DEPEND);
9147 OMP_CLAUSE_DEPEND_KIND (c) = OMP_CLAUSE_DEPEND_LAST;
9148 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (array);
9149 OMP_CLAUSE_CHAIN (c) = *list_p;
9150 *list_p = c;
9151 return 1;
9154 /* True if mapping node C maps, or unmaps, a (Fortran) array descriptor. */
9156 static bool
9157 omp_map_clause_descriptor_p (tree c)
9159 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP)
9160 return false;
9162 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_TO_PSET)
9163 return true;
9165 if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_RELEASE
9166 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DELETE)
9167 && OMP_CLAUSE_RELEASE_DESCRIPTOR (c))
9168 return true;
9170 return false;
9173 /* For a set of mappings describing an array section pointed to by a struct
9174 (or derived type, etc.) component, create an "alloc" or "release" node to
9175 insert into a list following a GOMP_MAP_STRUCT node. For some types of
9176 mapping (e.g. Fortran arrays with descriptors), an additional mapping may
9177 be created that is inserted into the list of mapping nodes attached to the
9178 directive being processed -- not part of the sorted list of nodes after
9179 GOMP_MAP_STRUCT.
9181 CODE is the code of the directive being processed. GRP_START and GRP_END
9182 are the first and last of two or three nodes representing this array section
9183 mapping (e.g. a data movement node like GOMP_MAP_{TO,FROM}, optionally a
9184 GOMP_MAP_TO_PSET, and finally a GOMP_MAP_ALWAYS_POINTER). EXTRA_NODE is
9185 filled with the additional node described above, if needed.
9187 This function does not add the new nodes to any lists itself. It is the
9188 responsibility of the caller to do that. */
9190 static tree
9191 build_omp_struct_comp_nodes (enum tree_code code, tree grp_start, tree grp_end,
9192 tree *extra_node)
9194 enum gomp_map_kind mkind
9195 = (code == OMP_TARGET_EXIT_DATA || code == OACC_EXIT_DATA)
9196 ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
9198 gcc_assert (grp_start != grp_end);
9200 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end), OMP_CLAUSE_MAP);
9201 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
9202 OMP_CLAUSE_DECL (c2) = unshare_expr (OMP_CLAUSE_DECL (grp_end));
9203 OMP_CLAUSE_CHAIN (c2) = NULL_TREE;
9204 tree grp_mid = NULL_TREE;
9205 if (OMP_CLAUSE_CHAIN (grp_start) != grp_end)
9206 grp_mid = OMP_CLAUSE_CHAIN (grp_start);
9208 if (grp_mid && omp_map_clause_descriptor_p (grp_mid))
9209 OMP_CLAUSE_SIZE (c2) = OMP_CLAUSE_SIZE (grp_mid);
9210 else
9211 OMP_CLAUSE_SIZE (c2) = TYPE_SIZE_UNIT (ptr_type_node);
9213 if (grp_mid
9214 && OMP_CLAUSE_CODE (grp_mid) == OMP_CLAUSE_MAP
9215 && OMP_CLAUSE_MAP_KIND (grp_mid) == GOMP_MAP_ALWAYS_POINTER)
9217 tree c3
9218 = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end), OMP_CLAUSE_MAP);
9219 OMP_CLAUSE_SET_MAP_KIND (c3, mkind);
9220 OMP_CLAUSE_DECL (c3) = unshare_expr (OMP_CLAUSE_DECL (grp_mid));
9221 OMP_CLAUSE_SIZE (c3) = TYPE_SIZE_UNIT (ptr_type_node);
9222 OMP_CLAUSE_CHAIN (c3) = NULL_TREE;
9224 *extra_node = c3;
9226 else
9227 *extra_node = NULL_TREE;
9229 return c2;
9232 /* Strip ARRAY_REFS or an indirect ref off BASE, find the containing object,
9233 and set *BITPOSP and *POFFSETP to the bit offset of the access.
9234 If BASE_REF is non-NULL and the containing object is a reference, set
9235 *BASE_REF to that reference before dereferencing the object.
9236 If BASE_REF is NULL, check that the containing object is a COMPONENT_REF or
9237 has array type, else return NULL. */
9239 static tree
9240 extract_base_bit_offset (tree base, poly_int64 *bitposp,
9241 poly_offset_int *poffsetp,
9242 bool *variable_offset)
9244 tree offset;
9245 poly_int64 bitsize, bitpos;
9246 machine_mode mode;
9247 int unsignedp, reversep, volatilep = 0;
9248 poly_offset_int poffset;
9250 STRIP_NOPS (base);
9252 base = get_inner_reference (base, &bitsize, &bitpos, &offset, &mode,
9253 &unsignedp, &reversep, &volatilep);
9255 STRIP_NOPS (base);
9257 if (offset && poly_int_tree_p (offset))
9259 poffset = wi::to_poly_offset (offset);
9260 *variable_offset = false;
9262 else
9264 poffset = 0;
9265 *variable_offset = (offset != NULL_TREE);
9268 if (maybe_ne (bitpos, 0))
9269 poffset += bits_to_bytes_round_down (bitpos);
9271 *bitposp = bitpos;
9272 *poffsetp = poffset;
9274 return base;
9277 /* Used for topological sorting of mapping groups. UNVISITED means we haven't
9278 started processing the group yet. The TEMPORARY mark is used when we first
9279 encounter a group on a depth-first traversal, and the PERMANENT mark is used
9280 when we have processed all the group's children (i.e. all the base pointers
9281 referred to by the group's mapping nodes, recursively). */
9283 enum omp_tsort_mark {
9284 UNVISITED,
9285 TEMPORARY,
9286 PERMANENT
9289 /* Hash for trees based on operand_equal_p. Like tree_operand_hash
9290 but ignores side effects in the equality comparisons. */
9292 struct tree_operand_hash_no_se : tree_operand_hash
9294 static inline bool equal (const value_type &,
9295 const compare_type &);
9298 inline bool
9299 tree_operand_hash_no_se::equal (const value_type &t1,
9300 const compare_type &t2)
9302 return operand_equal_p (t1, t2, OEP_MATCH_SIDE_EFFECTS);
9305 /* A group of OMP_CLAUSE_MAP nodes that correspond to a single "map"
9306 clause. */
9308 struct omp_mapping_group {
9309 tree *grp_start;
9310 tree grp_end;
9311 omp_tsort_mark mark;
9312 /* If we've removed the group but need to reindex, mark the group as
9313 deleted. */
9314 bool deleted;
9315 /* The group points to an already-created "GOMP_MAP_STRUCT
9316 GOMP_MAP_ATTACH_DETACH" pair. */
9317 bool reprocess_struct;
9318 /* The group should use "zero-length" allocations for pointers that are not
9319 mapped "to" on the same directive. */
9320 bool fragile;
9321 struct omp_mapping_group *sibling;
9322 struct omp_mapping_group *next;
9325 DEBUG_FUNCTION void
9326 debug_mapping_group (omp_mapping_group *grp)
9328 tree tmp = OMP_CLAUSE_CHAIN (grp->grp_end);
9329 OMP_CLAUSE_CHAIN (grp->grp_end) = NULL;
9330 debug_generic_expr (*grp->grp_start);
9331 OMP_CLAUSE_CHAIN (grp->grp_end) = tmp;
9334 /* Return the OpenMP "base pointer" of an expression EXPR, or NULL if there
9335 isn't one. */
9337 static tree
9338 omp_get_base_pointer (tree expr)
9340 while (TREE_CODE (expr) == ARRAY_REF
9341 || TREE_CODE (expr) == COMPONENT_REF)
9342 expr = TREE_OPERAND (expr, 0);
9344 if (INDIRECT_REF_P (expr)
9345 || (TREE_CODE (expr) == MEM_REF
9346 && integer_zerop (TREE_OPERAND (expr, 1))))
9348 expr = TREE_OPERAND (expr, 0);
9349 while (TREE_CODE (expr) == COMPOUND_EXPR)
9350 expr = TREE_OPERAND (expr, 1);
9351 if (TREE_CODE (expr) == POINTER_PLUS_EXPR)
9352 expr = TREE_OPERAND (expr, 0);
9353 if (TREE_CODE (expr) == SAVE_EXPR)
9354 expr = TREE_OPERAND (expr, 0);
9355 STRIP_NOPS (expr);
9356 return expr;
9359 return NULL_TREE;
9362 /* An attach or detach operation depends directly on the address being
9363 attached/detached. Return that address, or none if there are no
9364 attachments/detachments. */
9366 static tree
9367 omp_get_attachment (omp_mapping_group *grp)
9369 tree node = *grp->grp_start;
9371 switch (OMP_CLAUSE_MAP_KIND (node))
9373 case GOMP_MAP_TO:
9374 case GOMP_MAP_FROM:
9375 case GOMP_MAP_TOFROM:
9376 case GOMP_MAP_ALWAYS_FROM:
9377 case GOMP_MAP_ALWAYS_TO:
9378 case GOMP_MAP_ALWAYS_TOFROM:
9379 case GOMP_MAP_FORCE_FROM:
9380 case GOMP_MAP_FORCE_TO:
9381 case GOMP_MAP_FORCE_TOFROM:
9382 case GOMP_MAP_FORCE_PRESENT:
9383 case GOMP_MAP_PRESENT_ALLOC:
9384 case GOMP_MAP_PRESENT_FROM:
9385 case GOMP_MAP_PRESENT_TO:
9386 case GOMP_MAP_PRESENT_TOFROM:
9387 case GOMP_MAP_ALWAYS_PRESENT_FROM:
9388 case GOMP_MAP_ALWAYS_PRESENT_TO:
9389 case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
9390 case GOMP_MAP_ALLOC:
9391 case GOMP_MAP_RELEASE:
9392 case GOMP_MAP_DELETE:
9393 case GOMP_MAP_FORCE_ALLOC:
9394 if (node == grp->grp_end)
9395 return NULL_TREE;
9397 node = OMP_CLAUSE_CHAIN (node);
9398 if (node && omp_map_clause_descriptor_p (node))
9400 gcc_assert (node != grp->grp_end);
9401 node = OMP_CLAUSE_CHAIN (node);
9403 if (node)
9404 switch (OMP_CLAUSE_MAP_KIND (node))
9406 case GOMP_MAP_POINTER:
9407 case GOMP_MAP_ALWAYS_POINTER:
9408 case GOMP_MAP_FIRSTPRIVATE_POINTER:
9409 case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
9410 case GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION:
9411 return NULL_TREE;
9413 case GOMP_MAP_ATTACH_DETACH:
9414 case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION:
9415 case GOMP_MAP_DETACH:
9416 return OMP_CLAUSE_DECL (node);
9418 default:
9419 internal_error ("unexpected mapping node");
9421 return error_mark_node;
9423 case GOMP_MAP_TO_PSET:
9424 gcc_assert (node != grp->grp_end);
9425 node = OMP_CLAUSE_CHAIN (node);
9426 if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_ATTACH
9427 || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_DETACH)
9428 return OMP_CLAUSE_DECL (node);
9429 else
9430 internal_error ("unexpected mapping node");
9431 return error_mark_node;
9433 case GOMP_MAP_ATTACH:
9434 case GOMP_MAP_DETACH:
9435 node = OMP_CLAUSE_CHAIN (node);
9436 if (!node || *grp->grp_start == grp->grp_end)
9437 return OMP_CLAUSE_DECL (*grp->grp_start);
9438 if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_POINTER
9439 || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
9440 return OMP_CLAUSE_DECL (*grp->grp_start);
9441 else
9442 internal_error ("unexpected mapping node");
9443 return error_mark_node;
9445 case GOMP_MAP_STRUCT:
9446 case GOMP_MAP_STRUCT_UNORD:
9447 case GOMP_MAP_FORCE_DEVICEPTR:
9448 case GOMP_MAP_DEVICE_RESIDENT:
9449 case GOMP_MAP_LINK:
9450 case GOMP_MAP_IF_PRESENT:
9451 case GOMP_MAP_FIRSTPRIVATE:
9452 case GOMP_MAP_FIRSTPRIVATE_INT:
9453 case GOMP_MAP_USE_DEVICE_PTR:
9454 case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION:
9455 return NULL_TREE;
9457 default:
9458 internal_error ("unexpected mapping node");
9461 return error_mark_node;
9464 /* Given a pointer START_P to the start of a group of related (e.g. pointer)
9465 mappings, return the chain pointer to the end of that group in the list. */
9467 static tree *
9468 omp_group_last (tree *start_p)
9470 tree c = *start_p, nc, *grp_last_p = start_p;
9472 gcc_assert (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP);
9474 nc = OMP_CLAUSE_CHAIN (c);
9476 if (!nc || OMP_CLAUSE_CODE (nc) != OMP_CLAUSE_MAP)
9477 return grp_last_p;
9479 switch (OMP_CLAUSE_MAP_KIND (c))
9481 default:
9482 while (nc
9483 && OMP_CLAUSE_CODE (nc) == OMP_CLAUSE_MAP
9484 && (OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
9485 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_POINTER
9486 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_ATTACH_DETACH
9487 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_POINTER
9488 || (OMP_CLAUSE_MAP_KIND (nc)
9489 == GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION)
9490 || (OMP_CLAUSE_MAP_KIND (nc)
9491 == GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION)
9492 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_DETACH
9493 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_ALWAYS_POINTER
9494 || omp_map_clause_descriptor_p (nc)))
9496 tree nc2 = OMP_CLAUSE_CHAIN (nc);
9497 if (OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_DETACH)
9499 /* In the specific case we're doing "exit data" on an array
9500 slice of a reference-to-pointer struct component, we will see
9501 DETACH followed by ATTACH_DETACH here. We want to treat that
9502 as a single group. In other cases DETACH might represent a
9503 stand-alone "detach" clause, so we don't want to consider
9504 that part of the group. */
9505 if (nc2
9506 && OMP_CLAUSE_CODE (nc2) == OMP_CLAUSE_MAP
9507 && OMP_CLAUSE_MAP_KIND (nc2) == GOMP_MAP_ATTACH_DETACH)
9508 goto consume_two_nodes;
9509 else
9510 break;
9512 if (nc2
9513 && OMP_CLAUSE_CODE (nc2) == OMP_CLAUSE_MAP
9514 && (OMP_CLAUSE_MAP_KIND (nc)
9515 == GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION)
9516 && OMP_CLAUSE_MAP_KIND (nc2) == GOMP_MAP_ATTACH)
9518 consume_two_nodes:
9519 grp_last_p = &OMP_CLAUSE_CHAIN (nc);
9520 c = nc2;
9521 nc = OMP_CLAUSE_CHAIN (nc2);
9523 else
9525 grp_last_p = &OMP_CLAUSE_CHAIN (c);
9526 c = nc;
9527 nc = nc2;
9530 break;
9532 case GOMP_MAP_ATTACH:
9533 case GOMP_MAP_DETACH:
9534 /* This is a weird artifact of how directives are parsed: bare attach or
9535 detach clauses get a subsequent (meaningless) FIRSTPRIVATE_POINTER or
9536 FIRSTPRIVATE_REFERENCE node. FIXME. */
9537 if (nc
9538 && OMP_CLAUSE_CODE (nc) == OMP_CLAUSE_MAP
9539 && (OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
9540 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_POINTER))
9541 grp_last_p = &OMP_CLAUSE_CHAIN (c);
9542 break;
9544 case GOMP_MAP_TO_PSET:
9545 if (OMP_CLAUSE_CODE (nc) == OMP_CLAUSE_MAP
9546 && (OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_ATTACH
9547 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_DETACH))
9548 grp_last_p = &OMP_CLAUSE_CHAIN (c);
9549 break;
9551 case GOMP_MAP_STRUCT:
9552 case GOMP_MAP_STRUCT_UNORD:
9554 unsigned HOST_WIDE_INT num_mappings
9555 = tree_to_uhwi (OMP_CLAUSE_SIZE (c));
9556 if (OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_POINTER
9557 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
9558 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_ATTACH_DETACH)
9559 grp_last_p = &OMP_CLAUSE_CHAIN (*grp_last_p);
9560 for (unsigned i = 0; i < num_mappings; i++)
9561 grp_last_p = &OMP_CLAUSE_CHAIN (*grp_last_p);
9563 break;
9566 return grp_last_p;
9569 /* Walk through LIST_P, and return a list of groups of mappings found (e.g.
9570 OMP_CLAUSE_MAP with GOMP_MAP_{TO/FROM/TOFROM} followed by one or two
9571 associated GOMP_MAP_POINTER mappings). Return a vector of omp_mapping_group
9572 if we have more than one such group, else return NULL. */
9574 static void
9575 omp_gather_mapping_groups_1 (tree *list_p, vec<omp_mapping_group> *groups,
9576 tree gather_sentinel)
9578 for (tree *cp = list_p;
9579 *cp && *cp != gather_sentinel;
9580 cp = &OMP_CLAUSE_CHAIN (*cp))
9582 if (OMP_CLAUSE_CODE (*cp) != OMP_CLAUSE_MAP)
9583 continue;
9585 tree *grp_last_p = omp_group_last (cp);
9586 omp_mapping_group grp;
9588 grp.grp_start = cp;
9589 grp.grp_end = *grp_last_p;
9590 grp.mark = UNVISITED;
9591 grp.sibling = NULL;
9592 grp.deleted = false;
9593 grp.reprocess_struct = false;
9594 grp.fragile = false;
9595 grp.next = NULL;
9596 groups->safe_push (grp);
9598 cp = grp_last_p;
9602 static vec<omp_mapping_group> *
9603 omp_gather_mapping_groups (tree *list_p)
9605 vec<omp_mapping_group> *groups = new vec<omp_mapping_group> ();
9607 omp_gather_mapping_groups_1 (list_p, groups, NULL_TREE);
9609 if (groups->length () > 0)
9610 return groups;
9611 else
9613 delete groups;
9614 return NULL;
9618 /* A pointer mapping group GRP may define a block of memory starting at some
9619 base address, and maybe also define a firstprivate pointer or firstprivate
9620 reference that points to that block. The return value is a node containing
9621 the former, and the *FIRSTPRIVATE pointer is set if we have the latter.
9622 If we define several base pointers, i.e. for a GOMP_MAP_STRUCT mapping,
9623 return the number of consecutive chained nodes in CHAINED. */
9625 static tree
9626 omp_group_base (omp_mapping_group *grp, unsigned int *chained,
9627 tree *firstprivate)
9629 tree node = *grp->grp_start;
9631 *firstprivate = NULL_TREE;
9632 *chained = 1;
9634 switch (OMP_CLAUSE_MAP_KIND (node))
9636 case GOMP_MAP_TO:
9637 case GOMP_MAP_FROM:
9638 case GOMP_MAP_TOFROM:
9639 case GOMP_MAP_ALWAYS_FROM:
9640 case GOMP_MAP_ALWAYS_TO:
9641 case GOMP_MAP_ALWAYS_TOFROM:
9642 case GOMP_MAP_FORCE_FROM:
9643 case GOMP_MAP_FORCE_TO:
9644 case GOMP_MAP_FORCE_TOFROM:
9645 case GOMP_MAP_FORCE_PRESENT:
9646 case GOMP_MAP_PRESENT_ALLOC:
9647 case GOMP_MAP_PRESENT_FROM:
9648 case GOMP_MAP_PRESENT_TO:
9649 case GOMP_MAP_PRESENT_TOFROM:
9650 case GOMP_MAP_ALWAYS_PRESENT_FROM:
9651 case GOMP_MAP_ALWAYS_PRESENT_TO:
9652 case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
9653 case GOMP_MAP_ALLOC:
9654 case GOMP_MAP_RELEASE:
9655 case GOMP_MAP_DELETE:
9656 case GOMP_MAP_FORCE_ALLOC:
9657 case GOMP_MAP_IF_PRESENT:
9658 if (node == grp->grp_end)
9659 return node;
9661 node = OMP_CLAUSE_CHAIN (node);
9662 if (!node)
9663 internal_error ("unexpected mapping node");
9664 if (omp_map_clause_descriptor_p (node))
9666 if (node == grp->grp_end)
9667 return *grp->grp_start;
9668 node = OMP_CLAUSE_CHAIN (node);
9670 switch (OMP_CLAUSE_MAP_KIND (node))
9672 case GOMP_MAP_POINTER:
9673 case GOMP_MAP_FIRSTPRIVATE_POINTER:
9674 case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
9675 case GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION:
9676 *firstprivate = OMP_CLAUSE_DECL (node);
9677 return *grp->grp_start;
9679 case GOMP_MAP_ALWAYS_POINTER:
9680 case GOMP_MAP_ATTACH_DETACH:
9681 case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION:
9682 case GOMP_MAP_DETACH:
9683 return *grp->grp_start;
9685 default:
9686 internal_error ("unexpected mapping node");
9688 return error_mark_node;
9690 case GOMP_MAP_TO_PSET:
9691 gcc_assert (node != grp->grp_end);
9692 node = OMP_CLAUSE_CHAIN (node);
9693 if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_ATTACH
9694 || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_DETACH)
9695 return NULL_TREE;
9696 else
9697 internal_error ("unexpected mapping node");
9698 return error_mark_node;
9700 case GOMP_MAP_ATTACH:
9701 case GOMP_MAP_DETACH:
9702 node = OMP_CLAUSE_CHAIN (node);
9703 if (!node || *grp->grp_start == grp->grp_end)
9704 return NULL_TREE;
9705 if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_POINTER
9706 || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
9708 /* We're mapping the base pointer itself in a bare attach or detach
9709 node. This is a side effect of how parsing works, and the mapping
9710 will be removed anyway (at least for enter/exit data directives).
9711 We should ignore the mapping here. FIXME. */
9712 return NULL_TREE;
9714 else
9715 internal_error ("unexpected mapping node");
9716 return error_mark_node;
9718 case GOMP_MAP_STRUCT:
9719 case GOMP_MAP_STRUCT_UNORD:
9721 unsigned HOST_WIDE_INT num_mappings
9722 = tree_to_uhwi (OMP_CLAUSE_SIZE (node));
9723 node = OMP_CLAUSE_CHAIN (node);
9724 if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_POINTER
9725 || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
9727 *firstprivate = OMP_CLAUSE_DECL (node);
9728 node = OMP_CLAUSE_CHAIN (node);
9730 else if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_ATTACH_DETACH)
9731 node = OMP_CLAUSE_CHAIN (node);
9732 *chained = num_mappings;
9733 return node;
9736 case GOMP_MAP_FORCE_DEVICEPTR:
9737 case GOMP_MAP_DEVICE_RESIDENT:
9738 case GOMP_MAP_LINK:
9739 case GOMP_MAP_FIRSTPRIVATE:
9740 case GOMP_MAP_FIRSTPRIVATE_INT:
9741 case GOMP_MAP_USE_DEVICE_PTR:
9742 case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION:
9743 return NULL_TREE;
9745 case GOMP_MAP_FIRSTPRIVATE_POINTER:
9746 case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
9747 case GOMP_MAP_POINTER:
9748 case GOMP_MAP_ALWAYS_POINTER:
9749 case GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION:
9750 /* These shouldn't appear by themselves. */
9751 if (!seen_error ())
9752 internal_error ("unexpected pointer mapping node");
9753 return error_mark_node;
9755 default:
9756 gcc_unreachable ();
9759 return error_mark_node;
9762 /* Given a vector of omp_mapping_groups, build a hash table so we can look up
9763 nodes by tree_operand_hash_no_se. */
9765 static void
9766 omp_index_mapping_groups_1 (hash_map<tree_operand_hash_no_se,
9767 omp_mapping_group *> *grpmap,
9768 vec<omp_mapping_group> *groups,
9769 tree reindex_sentinel)
9771 omp_mapping_group *grp;
9772 unsigned int i;
9773 bool reindexing = reindex_sentinel != NULL_TREE, above_hwm = false;
9775 FOR_EACH_VEC_ELT (*groups, i, grp)
9777 if (reindexing && *grp->grp_start == reindex_sentinel)
9778 above_hwm = true;
9780 if (reindexing && !above_hwm)
9781 continue;
9783 if (grp->reprocess_struct)
9784 continue;
9786 tree fpp;
9787 unsigned int chained;
9788 tree node = omp_group_base (grp, &chained, &fpp);
9790 if (node == error_mark_node || (!node && !fpp))
9791 continue;
9793 for (unsigned j = 0;
9794 node && j < chained;
9795 node = OMP_CLAUSE_CHAIN (node), j++)
9797 tree decl = OMP_CLAUSE_DECL (node);
9798 /* Sometimes we see zero-offset MEM_REF instead of INDIRECT_REF,
9799 meaning node-hash lookups don't work. This is a workaround for
9800 that, but ideally we should just create the INDIRECT_REF at
9801 source instead. FIXME. */
9802 if (TREE_CODE (decl) == MEM_REF
9803 && integer_zerop (TREE_OPERAND (decl, 1)))
9804 decl = build_fold_indirect_ref (TREE_OPERAND (decl, 0));
9806 omp_mapping_group **prev = grpmap->get (decl);
9808 if (prev && *prev == grp)
9809 /* Empty. */;
9810 else if (prev)
9812 /* Mapping the same thing twice is normally diagnosed as an error,
9813 but can happen under some circumstances, e.g. in pr99928-16.c,
9814 the directive:
9816 #pragma omp target simd reduction(+:a[:3]) \
9817 map(always, tofrom: a[:6])
9820 will result in two "a[0]" mappings (of different sizes). */
9822 grp->sibling = (*prev)->sibling;
9823 (*prev)->sibling = grp;
9825 else
9826 grpmap->put (decl, grp);
9829 if (!fpp)
9830 continue;
9832 omp_mapping_group **prev = grpmap->get (fpp);
9833 if (prev && *prev != grp)
9835 grp->sibling = (*prev)->sibling;
9836 (*prev)->sibling = grp;
9838 else
9839 grpmap->put (fpp, grp);
9843 static hash_map<tree_operand_hash_no_se, omp_mapping_group *> *
9844 omp_index_mapping_groups (vec<omp_mapping_group> *groups)
9846 hash_map<tree_operand_hash_no_se, omp_mapping_group *> *grpmap
9847 = new hash_map<tree_operand_hash_no_se, omp_mapping_group *>;
9849 omp_index_mapping_groups_1 (grpmap, groups, NULL_TREE);
9851 return grpmap;
9854 /* Rebuild group map from partially-processed clause list (during
9855 omp_build_struct_sibling_lists). We have already processed nodes up until
9856 a high-water mark (HWM). This is a bit tricky because the list is being
9857 reordered as it is scanned, but we know:
9859 1. The list after HWM has not been touched yet, so we can reindex it safely.
9861 2. The list before and including HWM has been altered, but remains
9862 well-formed throughout the sibling-list building operation.
9864 so, we can do the reindex operation in two parts, on the processed and
9865 then the unprocessed halves of the list. */
9867 static hash_map<tree_operand_hash_no_se, omp_mapping_group *> *
9868 omp_reindex_mapping_groups (tree *list_p,
9869 vec<omp_mapping_group> *groups,
9870 vec<omp_mapping_group> *processed_groups,
9871 tree sentinel)
9873 hash_map<tree_operand_hash_no_se, omp_mapping_group *> *grpmap
9874 = new hash_map<tree_operand_hash_no_se, omp_mapping_group *>;
9876 processed_groups->truncate (0);
9878 omp_gather_mapping_groups_1 (list_p, processed_groups, sentinel);
9879 omp_index_mapping_groups_1 (grpmap, processed_groups, NULL_TREE);
9880 if (sentinel)
9881 omp_index_mapping_groups_1 (grpmap, groups, sentinel);
9883 return grpmap;
9886 /* Find the immediately-containing struct for a component ref (etc.)
9887 expression EXPR. */
9889 static tree
9890 omp_containing_struct (tree expr)
9892 tree expr0 = expr;
9894 STRIP_NOPS (expr);
9896 /* Note: don't strip NOPs unless we're also stripping off array refs or a
9897 component ref. */
9898 if (TREE_CODE (expr) != ARRAY_REF && TREE_CODE (expr) != COMPONENT_REF)
9899 return expr0;
9901 while (TREE_CODE (expr) == ARRAY_REF)
9902 expr = TREE_OPERAND (expr, 0);
9904 if (TREE_CODE (expr) == COMPONENT_REF)
9905 expr = TREE_OPERAND (expr, 0);
9907 return expr;
9910 /* Return TRUE if DECL describes a component that is part of a whole structure
9911 that is mapped elsewhere in GRPMAP. *MAPPED_BY_GROUP is set to the group
9912 that maps that structure, if present. */
9914 static bool
9915 omp_mapped_by_containing_struct (hash_map<tree_operand_hash_no_se,
9916 omp_mapping_group *> *grpmap,
9917 tree decl,
9918 omp_mapping_group **mapped_by_group)
9920 tree wsdecl = NULL_TREE;
9922 *mapped_by_group = NULL;
9924 while (true)
9926 wsdecl = omp_containing_struct (decl);
9927 if (wsdecl == decl)
9928 break;
9929 omp_mapping_group **wholestruct = grpmap->get (wsdecl);
9930 if (!wholestruct
9931 && TREE_CODE (wsdecl) == MEM_REF
9932 && integer_zerop (TREE_OPERAND (wsdecl, 1)))
9934 tree deref = TREE_OPERAND (wsdecl, 0);
9935 deref = build_fold_indirect_ref (deref);
9936 wholestruct = grpmap->get (deref);
9938 if (wholestruct)
9940 *mapped_by_group = *wholestruct;
9941 return true;
9943 decl = wsdecl;
9946 return false;
9949 /* Helper function for omp_tsort_mapping_groups. Returns TRUE on success, or
9950 FALSE on error. */
9952 static bool
9953 omp_tsort_mapping_groups_1 (omp_mapping_group ***outlist,
9954 vec<omp_mapping_group> *groups,
9955 hash_map<tree_operand_hash_no_se,
9956 omp_mapping_group *> *grpmap,
9957 omp_mapping_group *grp)
9959 if (grp->mark == PERMANENT)
9960 return true;
9961 if (grp->mark == TEMPORARY)
9963 fprintf (stderr, "when processing group:\n");
9964 debug_mapping_group (grp);
9965 internal_error ("base pointer cycle detected");
9966 return false;
9968 grp->mark = TEMPORARY;
9970 tree attaches_to = omp_get_attachment (grp);
9972 if (attaches_to)
9974 omp_mapping_group **basep = grpmap->get (attaches_to);
9976 if (basep && *basep != grp)
9978 for (omp_mapping_group *w = *basep; w; w = w->sibling)
9979 if (!omp_tsort_mapping_groups_1 (outlist, groups, grpmap, w))
9980 return false;
9984 tree decl = OMP_CLAUSE_DECL (*grp->grp_start);
9986 while (decl)
9988 tree base = omp_get_base_pointer (decl);
9990 if (!base)
9991 break;
9993 omp_mapping_group **innerp = grpmap->get (base);
9994 omp_mapping_group *wholestruct;
9996 /* We should treat whole-structure mappings as if all (pointer, in this
9997 case) members are mapped as individual list items. Check if we have
9998 such a whole-structure mapping, if we don't have an explicit reference
9999 to the pointer member itself. */
10000 if (!innerp
10001 && TREE_CODE (base) == COMPONENT_REF
10002 && omp_mapped_by_containing_struct (grpmap, base, &wholestruct))
10003 innerp = &wholestruct;
10005 if (innerp && *innerp != grp)
10007 for (omp_mapping_group *w = *innerp; w; w = w->sibling)
10008 if (!omp_tsort_mapping_groups_1 (outlist, groups, grpmap, w))
10009 return false;
10010 break;
10013 decl = base;
10016 grp->mark = PERMANENT;
10018 /* Emit grp to output list. */
10020 **outlist = grp;
10021 *outlist = &grp->next;
10023 return true;
10026 /* Topologically sort GROUPS, so that OMP 5.0-defined base pointers come
10027 before mappings that use those pointers. This is an implementation of the
10028 depth-first search algorithm, described e.g. at:
10030 https://en.wikipedia.org/wiki/Topological_sorting
10033 static omp_mapping_group *
10034 omp_tsort_mapping_groups (vec<omp_mapping_group> *groups,
10035 hash_map<tree_operand_hash_no_se, omp_mapping_group *>
10036 *grpmap,
10037 bool enter_exit_data)
10039 omp_mapping_group *grp, *outlist = NULL, **cursor;
10040 unsigned int i;
10041 bool saw_runtime_implicit = false;
10043 cursor = &outlist;
10045 FOR_EACH_VEC_ELT (*groups, i, grp)
10047 if (grp->mark != PERMANENT)
10049 if (OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (*grp->grp_start))
10051 saw_runtime_implicit = true;
10052 continue;
10054 if (!omp_tsort_mapping_groups_1 (&cursor, groups, grpmap, grp))
10055 return NULL;
10059 if (!saw_runtime_implicit)
10060 return outlist;
10062 FOR_EACH_VEC_ELT (*groups, i, grp)
10064 if (grp->mark != PERMANENT
10065 && OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (*grp->grp_start))
10067 /* Clear the flag for enter/exit data because it is currently
10068 meaningless for those operations in libgomp. */
10069 if (enter_exit_data)
10070 OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (*grp->grp_start) = 0;
10072 if (!omp_tsort_mapping_groups_1 (&cursor, groups, grpmap, grp))
10073 return NULL;
10077 return outlist;
10080 /* Split INLIST into three parts:
10082 - "present" alloc/to/from groups
10083 - other to/from groups
10084 - other alloc/release/delete groups
10086 These sub-lists are then concatenated together to form the final list.
10087 Each sub-list retains the order of the original list.
10088 Note that ATTACH nodes are later moved to the end of the list in
10089 gimplify_adjust_omp_clauses, for target regions. */
10091 static omp_mapping_group *
10092 omp_segregate_mapping_groups (omp_mapping_group *inlist)
10094 omp_mapping_group *ard_groups = NULL, *tf_groups = NULL;
10095 omp_mapping_group *p_groups = NULL;
10096 omp_mapping_group **ard_tail = &ard_groups, **tf_tail = &tf_groups;
10097 omp_mapping_group **p_tail = &p_groups;
10099 for (omp_mapping_group *w = inlist; w;)
10101 tree c = *w->grp_start;
10102 omp_mapping_group *next = w->next;
10104 gcc_assert (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP);
10106 switch (OMP_CLAUSE_MAP_KIND (c))
10108 case GOMP_MAP_ALLOC:
10109 case GOMP_MAP_RELEASE:
10110 case GOMP_MAP_DELETE:
10111 *ard_tail = w;
10112 w->next = NULL;
10113 ard_tail = &w->next;
10114 break;
10116 /* These map types are all semantically identical, so are moved into a
10117 single group. They will each be changed into GOMP_MAP_FORCE_PRESENT
10118 in gimplify_adjust_omp_clauses. */
10119 case GOMP_MAP_PRESENT_ALLOC:
10120 case GOMP_MAP_PRESENT_FROM:
10121 case GOMP_MAP_PRESENT_TO:
10122 case GOMP_MAP_PRESENT_TOFROM:
10123 *p_tail = w;
10124 w->next = NULL;
10125 p_tail = &w->next;
10126 break;
10128 default:
10129 *tf_tail = w;
10130 w->next = NULL;
10131 tf_tail = &w->next;
10134 w = next;
10137 /* Now splice the lists together... */
10138 *tf_tail = ard_groups;
10139 *p_tail = tf_groups;
10141 return p_groups;
10144 /* Given a list LIST_P containing groups of mappings given by GROUPS, reorder
10145 those groups based on the output list of omp_tsort_mapping_groups --
10146 singly-linked, threaded through each element's NEXT pointer starting at
10147 HEAD. Each list element appears exactly once in that linked list.
10149 Each element of GROUPS may correspond to one or several mapping nodes.
10150 Node groups are kept together, and in the reordered list, the positions of
10151 the original groups are reused for the positions of the reordered list.
10152 Hence if we have e.g.
10154 {to ptr ptr} firstprivate {tofrom ptr} ...
10155 ^ ^ ^
10156 first group non-"map" second group
10158 and say the second group contains a base pointer for the first so must be
10159 moved before it, the resulting list will contain:
10161 {tofrom ptr} firstprivate {to ptr ptr} ...
10162 ^ prev. second group ^ prev. first group
10165 static tree *
10166 omp_reorder_mapping_groups (vec<omp_mapping_group> *groups,
10167 omp_mapping_group *head,
10168 tree *list_p)
10170 omp_mapping_group *grp;
10171 unsigned int i;
10172 unsigned numgroups = groups->length ();
10173 auto_vec<tree> old_heads (numgroups);
10174 auto_vec<tree *> old_headps (numgroups);
10175 auto_vec<tree> new_heads (numgroups);
10176 auto_vec<tree> old_succs (numgroups);
10177 bool map_at_start = (list_p == (*groups)[0].grp_start);
10179 tree *new_grp_tail = NULL;
10181 /* Stash the start & end nodes of each mapping group before we start
10182 modifying the list. */
10183 FOR_EACH_VEC_ELT (*groups, i, grp)
10185 old_headps.quick_push (grp->grp_start);
10186 old_heads.quick_push (*grp->grp_start);
10187 old_succs.quick_push (OMP_CLAUSE_CHAIN (grp->grp_end));
10190 /* And similarly, the heads of the groups in the order we want to rearrange
10191 the list to. */
10192 for (omp_mapping_group *w = head; w; w = w->next)
10193 new_heads.quick_push (*w->grp_start);
10195 FOR_EACH_VEC_ELT (*groups, i, grp)
10197 gcc_assert (head);
10199 if (new_grp_tail && old_succs[i - 1] == old_heads[i])
10201 /* a {b c d} {e f g} h i j (original)
10203 a {k l m} {e f g} h i j (inserted new group on last iter)
10205 a {k l m} {n o p} h i j (this time, chain last group to new one)
10206 ^new_grp_tail
10208 *new_grp_tail = new_heads[i];
10210 else if (new_grp_tail)
10212 /* a {b c d} e {f g h} i j k (original)
10214 a {l m n} e {f g h} i j k (gap after last iter's group)
10216 a {l m n} e {o p q} h i j (chain last group to old successor)
10217 ^new_grp_tail
10219 *new_grp_tail = old_succs[i - 1];
10220 *old_headps[i] = new_heads[i];
10222 else
10224 /* The first inserted group -- point to new group, and leave end
10225 open.
10226 a {b c d} e f
10228 a {g h i...
10230 *grp->grp_start = new_heads[i];
10233 new_grp_tail = &OMP_CLAUSE_CHAIN (head->grp_end);
10235 head = head->next;
10238 if (new_grp_tail)
10239 *new_grp_tail = old_succs[numgroups - 1];
10241 gcc_assert (!head);
10243 return map_at_start ? (*groups)[0].grp_start : list_p;
10246 /* DECL is supposed to have lastprivate semantics in the outer contexts
10247 of combined/composite constructs, starting with OCTX.
10248 Add needed lastprivate, shared or map clause if no data sharing or
10249 mapping clause are present. IMPLICIT_P is true if it is an implicit
10250 clause (IV on simd), in which case the lastprivate will not be
10251 copied to some constructs. */
10253 static void
10254 omp_lastprivate_for_combined_outer_constructs (struct gimplify_omp_ctx *octx,
10255 tree decl, bool implicit_p)
10257 struct gimplify_omp_ctx *orig_octx = octx;
10258 for (; octx; octx = octx->outer_context)
10260 if ((octx->region_type == ORT_COMBINED_PARALLEL
10261 || (octx->region_type & ORT_COMBINED_TEAMS) == ORT_COMBINED_TEAMS)
10262 && splay_tree_lookup (octx->variables,
10263 (splay_tree_key) decl) == NULL)
10265 omp_add_variable (octx, decl, GOVD_SHARED | GOVD_SEEN);
10266 continue;
10268 if ((octx->region_type & ORT_TASK) != 0
10269 && octx->combined_loop
10270 && splay_tree_lookup (octx->variables,
10271 (splay_tree_key) decl) == NULL)
10273 omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
10274 continue;
10276 if (implicit_p
10277 && octx->region_type == ORT_WORKSHARE
10278 && octx->combined_loop
10279 && splay_tree_lookup (octx->variables,
10280 (splay_tree_key) decl) == NULL
10281 && octx->outer_context
10282 && octx->outer_context->region_type == ORT_COMBINED_PARALLEL
10283 && splay_tree_lookup (octx->outer_context->variables,
10284 (splay_tree_key) decl) == NULL)
10286 octx = octx->outer_context;
10287 omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
10288 continue;
10290 if ((octx->region_type == ORT_WORKSHARE || octx->region_type == ORT_ACC)
10291 && octx->combined_loop
10292 && splay_tree_lookup (octx->variables,
10293 (splay_tree_key) decl) == NULL
10294 && !omp_check_private (octx, decl, false))
10296 omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
10297 continue;
10299 if (octx->region_type == ORT_COMBINED_TARGET)
10301 splay_tree_node n = splay_tree_lookup (octx->variables,
10302 (splay_tree_key) decl);
10303 if (n == NULL)
10305 omp_add_variable (octx, decl, GOVD_MAP | GOVD_SEEN);
10306 octx = octx->outer_context;
10308 else if (!implicit_p
10309 && (n->value & GOVD_FIRSTPRIVATE_IMPLICIT))
10311 n->value &= ~(GOVD_FIRSTPRIVATE
10312 | GOVD_FIRSTPRIVATE_IMPLICIT
10313 | GOVD_EXPLICIT);
10314 omp_add_variable (octx, decl, GOVD_MAP | GOVD_SEEN);
10315 octx = octx->outer_context;
10318 break;
10320 if (octx && (implicit_p || octx != orig_octx))
10321 omp_notice_variable (octx, decl, true);
10324 /* We might have indexed several groups for DECL, e.g. a "TO" mapping and also
10325 a "FIRSTPRIVATE" mapping. Return the one that isn't firstprivate, etc. */
10327 static omp_mapping_group *
10328 omp_get_nonfirstprivate_group (hash_map<tree_operand_hash_no_se,
10329 omp_mapping_group *> *grpmap,
10330 tree decl, bool allow_deleted = false)
10332 omp_mapping_group **to_group_p = grpmap->get (decl);
10334 if (!to_group_p)
10335 return NULL;
10337 omp_mapping_group *to_group = *to_group_p;
10339 for (; to_group; to_group = to_group->sibling)
10341 tree grp_end = to_group->grp_end;
10342 switch (OMP_CLAUSE_MAP_KIND (grp_end))
10344 case GOMP_MAP_FIRSTPRIVATE_POINTER:
10345 case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
10346 break;
10348 default:
10349 if (allow_deleted || !to_group->deleted)
10350 return to_group;
10354 return NULL;
10357 /* Return TRUE if the directive (whose clauses are described by the hash table
10358 of mapping groups, GRPMAP) maps DECL explicitly. If TO_SPECIFICALLY is
10359 true, only count TO mappings. If ALLOW_DELETED is true, ignore the
10360 "deleted" flag for groups. If CONTAINED_IN_STRUCT is true, also return
10361 TRUE if DECL is mapped as a member of a whole-struct mapping. */
10363 static bool
10364 omp_directive_maps_explicitly (hash_map<tree_operand_hash_no_se,
10365 omp_mapping_group *> *grpmap,
10366 tree decl, omp_mapping_group **base_group,
10367 bool to_specifically, bool allow_deleted,
10368 bool contained_in_struct)
10370 omp_mapping_group *decl_group
10371 = omp_get_nonfirstprivate_group (grpmap, decl, allow_deleted);
10373 *base_group = NULL;
10375 if (decl_group)
10377 tree grp_first = *decl_group->grp_start;
10378 /* We might be called during omp_build_struct_sibling_lists, when
10379 GOMP_MAP_STRUCT might have been inserted at the start of the group.
10380 Skip over that, and also possibly the node after it. */
10381 if (OMP_CLAUSE_MAP_KIND (grp_first) == GOMP_MAP_STRUCT
10382 || OMP_CLAUSE_MAP_KIND (grp_first) == GOMP_MAP_STRUCT_UNORD)
10384 grp_first = OMP_CLAUSE_CHAIN (grp_first);
10385 if (OMP_CLAUSE_MAP_KIND (grp_first) == GOMP_MAP_FIRSTPRIVATE_POINTER
10386 || (OMP_CLAUSE_MAP_KIND (grp_first)
10387 == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
10388 || OMP_CLAUSE_MAP_KIND (grp_first) == GOMP_MAP_ATTACH_DETACH)
10389 grp_first = OMP_CLAUSE_CHAIN (grp_first);
10391 enum gomp_map_kind first_kind = OMP_CLAUSE_MAP_KIND (grp_first);
10392 if (!to_specifically
10393 || GOMP_MAP_COPY_TO_P (first_kind)
10394 || first_kind == GOMP_MAP_ALLOC)
10396 *base_group = decl_group;
10397 return true;
10401 if (contained_in_struct
10402 && omp_mapped_by_containing_struct (grpmap, decl, base_group))
10403 return true;
10405 return false;
10408 /* If we have mappings INNER and OUTER, where INNER is a component access and
10409 OUTER is a mapping of the whole containing struct, check that the mappings
10410 are compatible. We'll be deleting the inner mapping, so we need to make
10411 sure the outer mapping does (at least) the same transfers to/from the device
10412 as the inner mapping. */
10414 bool
10415 omp_check_mapping_compatibility (location_t loc,
10416 omp_mapping_group *outer,
10417 omp_mapping_group *inner)
10419 tree first_outer = *outer->grp_start, first_inner = *inner->grp_start;
10421 gcc_assert (OMP_CLAUSE_CODE (first_outer) == OMP_CLAUSE_MAP);
10422 gcc_assert (OMP_CLAUSE_CODE (first_inner) == OMP_CLAUSE_MAP);
10424 enum gomp_map_kind outer_kind = OMP_CLAUSE_MAP_KIND (first_outer);
10425 enum gomp_map_kind inner_kind = OMP_CLAUSE_MAP_KIND (first_inner);
10427 if (outer_kind == inner_kind)
10428 return true;
10430 switch (outer_kind)
10432 case GOMP_MAP_ALWAYS_TO:
10433 if (inner_kind == GOMP_MAP_FORCE_PRESENT
10434 || inner_kind == GOMP_MAP_ALLOC
10435 || inner_kind == GOMP_MAP_TO)
10436 return true;
10437 break;
10439 case GOMP_MAP_ALWAYS_FROM:
10440 if (inner_kind == GOMP_MAP_FORCE_PRESENT
10441 || inner_kind == GOMP_MAP_RELEASE
10442 || inner_kind == GOMP_MAP_FROM)
10443 return true;
10444 break;
10446 case GOMP_MAP_TO:
10447 if (inner_kind == GOMP_MAP_FORCE_PRESENT
10448 || inner_kind == GOMP_MAP_ALLOC)
10449 return true;
10450 break;
10452 case GOMP_MAP_FROM:
10453 if (inner_kind == GOMP_MAP_RELEASE
10454 || inner_kind == GOMP_MAP_FORCE_PRESENT)
10455 return true;
10456 break;
10458 case GOMP_MAP_ALWAYS_TOFROM:
10459 case GOMP_MAP_TOFROM:
10460 if (inner_kind == GOMP_MAP_FORCE_PRESENT
10461 || inner_kind == GOMP_MAP_ALLOC
10462 || inner_kind == GOMP_MAP_TO
10463 || inner_kind == GOMP_MAP_FROM
10464 || inner_kind == GOMP_MAP_TOFROM)
10465 return true;
10466 break;
10468 default:
10472 error_at (loc, "data movement for component %qE is not compatible with "
10473 "movement for struct %qE", OMP_CLAUSE_DECL (first_inner),
10474 OMP_CLAUSE_DECL (first_outer));
10476 return false;
10479 /* This function handles several cases where clauses on a mapping directive
10480 can interact with each other.
10482 If we have a FIRSTPRIVATE_POINTER node and we're also mapping the pointer
10483 on the same directive, change the mapping of the first node to
10484 ATTACH_DETACH. We should have detected that this will happen already in
10485 c-omp.cc:c_omp_adjust_map_clauses and marked the appropriate decl
10486 as addressable. (If we didn't, bail out.)
10488 If we have a FIRSTPRIVATE_REFERENCE (for a reference to pointer) and we're
10489 mapping the base pointer also, we may need to change the mapping type to
10490 ATTACH_DETACH and synthesize an alloc node for the reference itself.
10492 If we have an ATTACH_DETACH node, this is an array section with a pointer
10493 base. If we're mapping the base on the same directive too, we can drop its
10494 mapping. However, if we have a reference to pointer, make other appropriate
10495 adjustments to the mapping nodes instead.
10497 If we have an ATTACH_DETACH node with a Fortran pointer-set (array
10498 descriptor) mapping for a derived-type component, and we're also mapping the
10499 whole of the derived-type variable on another clause, the pointer-set
10500 mapping is removed.
10502 If we have a component access but we're also mapping the whole of the
10503 containing struct, drop the former access.
10505 If the expression is a component access, and we're also mapping a base
10506 pointer used in that component access in the same expression, change the
10507 mapping type of the latter to ALLOC (ready for processing by
10508 omp_build_struct_sibling_lists). */
10510 void
10511 omp_resolve_clause_dependencies (enum tree_code code,
10512 vec<omp_mapping_group> *groups,
10513 hash_map<tree_operand_hash_no_se,
10514 omp_mapping_group *> *grpmap)
10516 int i;
10517 omp_mapping_group *grp;
10518 bool repair_chain = false;
10520 FOR_EACH_VEC_ELT (*groups, i, grp)
10522 tree grp_end = grp->grp_end;
10523 tree decl = OMP_CLAUSE_DECL (grp_end);
10525 gcc_assert (OMP_CLAUSE_CODE (grp_end) == OMP_CLAUSE_MAP);
10527 switch (OMP_CLAUSE_MAP_KIND (grp_end))
10529 case GOMP_MAP_FIRSTPRIVATE_POINTER:
10531 omp_mapping_group *to_group
10532 = omp_get_nonfirstprivate_group (grpmap, decl);
10534 if (!to_group || to_group == grp)
10535 continue;
10537 tree grp_first = *to_group->grp_start;
10538 enum gomp_map_kind first_kind = OMP_CLAUSE_MAP_KIND (grp_first);
10540 if ((GOMP_MAP_COPY_TO_P (first_kind)
10541 || first_kind == GOMP_MAP_ALLOC)
10542 && (OMP_CLAUSE_MAP_KIND (to_group->grp_end)
10543 != GOMP_MAP_FIRSTPRIVATE_POINTER))
10545 gcc_assert (TREE_ADDRESSABLE (OMP_CLAUSE_DECL (grp_end)));
10546 OMP_CLAUSE_SET_MAP_KIND (grp_end, GOMP_MAP_ATTACH_DETACH);
10549 break;
10551 case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
10553 tree ptr = build_fold_indirect_ref (decl);
10555 omp_mapping_group *to_group
10556 = omp_get_nonfirstprivate_group (grpmap, ptr);
10558 if (!to_group || to_group == grp)
10559 continue;
10561 tree grp_first = *to_group->grp_start;
10562 enum gomp_map_kind first_kind = OMP_CLAUSE_MAP_KIND (grp_first);
10564 if (GOMP_MAP_COPY_TO_P (first_kind)
10565 || first_kind == GOMP_MAP_ALLOC)
10567 OMP_CLAUSE_SET_MAP_KIND (grp_end, GOMP_MAP_ATTACH_DETACH);
10568 OMP_CLAUSE_DECL (grp_end) = ptr;
10569 if ((OMP_CLAUSE_CHAIN (*to_group->grp_start)
10570 == to_group->grp_end)
10571 && (OMP_CLAUSE_MAP_KIND (to_group->grp_end)
10572 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
10574 gcc_assert (TREE_ADDRESSABLE
10575 (OMP_CLAUSE_DECL (to_group->grp_end)));
10576 OMP_CLAUSE_SET_MAP_KIND (to_group->grp_end,
10577 GOMP_MAP_ATTACH_DETACH);
10579 location_t loc = OMP_CLAUSE_LOCATION (to_group->grp_end);
10580 tree alloc
10581 = build_omp_clause (loc, OMP_CLAUSE_MAP);
10582 OMP_CLAUSE_SET_MAP_KIND (alloc, GOMP_MAP_ALLOC);
10583 tree tmp = build_fold_addr_expr (OMP_CLAUSE_DECL
10584 (to_group->grp_end));
10585 tree char_ptr_type = build_pointer_type (char_type_node);
10586 OMP_CLAUSE_DECL (alloc)
10587 = build2 (MEM_REF, char_type_node,
10588 tmp,
10589 build_int_cst (char_ptr_type, 0));
10590 OMP_CLAUSE_SIZE (alloc) = TYPE_SIZE_UNIT (TREE_TYPE (tmp));
10592 OMP_CLAUSE_CHAIN (alloc)
10593 = OMP_CLAUSE_CHAIN (*to_group->grp_start);
10594 OMP_CLAUSE_CHAIN (*to_group->grp_start) = alloc;
10598 break;
10600 case GOMP_MAP_ATTACH_DETACH:
10601 case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION:
10603 tree base_ptr, referenced_ptr_node = NULL_TREE;
10605 while (TREE_CODE (decl) == ARRAY_REF)
10606 decl = TREE_OPERAND (decl, 0);
10608 if (TREE_CODE (decl) == INDIRECT_REF)
10609 decl = TREE_OPERAND (decl, 0);
10611 /* Only component accesses. */
10612 if (DECL_P (decl))
10613 continue;
10615 /* We want the pointer itself when checking if the base pointer is
10616 mapped elsewhere in the same directive -- if we have a
10617 reference to the pointer, don't use that. */
10619 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
10620 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == POINTER_TYPE)
10622 referenced_ptr_node = OMP_CLAUSE_CHAIN (*grp->grp_start);
10623 base_ptr = OMP_CLAUSE_DECL (referenced_ptr_node);
10625 else
10626 base_ptr = decl;
10628 gomp_map_kind zlas_kind
10629 = (code == OACC_EXIT_DATA || code == OMP_TARGET_EXIT_DATA)
10630 ? GOMP_MAP_DETACH : GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION;
10632 if (TREE_CODE (TREE_TYPE (base_ptr)) == POINTER_TYPE)
10634 /* If we map the base TO, and we're doing an attachment, we can
10635 skip the TO mapping altogether and create an ALLOC mapping
10636 instead, since the attachment will overwrite the device
10637 pointer in that location immediately anyway. Otherwise,
10638 change our mapping to
10639 GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION in case the
10640 attachment target has not been copied to the device already
10641 by some earlier directive. */
10643 bool base_mapped_to = false;
10645 omp_mapping_group *base_group;
10647 if (omp_directive_maps_explicitly (grpmap, base_ptr,
10648 &base_group, false, true,
10649 false))
10651 if (referenced_ptr_node)
10653 base_mapped_to = true;
10654 if ((OMP_CLAUSE_MAP_KIND (base_group->grp_end)
10655 == GOMP_MAP_ATTACH_DETACH)
10656 && (OMP_CLAUSE_CHAIN (*base_group->grp_start)
10657 == base_group->grp_end))
10659 OMP_CLAUSE_CHAIN (*base_group->grp_start)
10660 = OMP_CLAUSE_CHAIN (base_group->grp_end);
10661 base_group->grp_end = *base_group->grp_start;
10662 repair_chain = true;
10665 else
10667 base_group->deleted = true;
10668 OMP_CLAUSE_ATTACHMENT_MAPPING_ERASED (grp_end) = 1;
10672 /* We're dealing with a reference to a pointer, and we are
10673 attaching both the reference and the pointer. We know the
10674 reference itself is on the target, because we are going to
10675 create an ALLOC node for it in accumulate_sibling_list. The
10676 pointer might be on the target already or it might not, but
10677 if it isn't then it's not an error, so use
10678 GOMP_MAP_ATTACH_ZLAS for it. */
10679 if (!base_mapped_to && referenced_ptr_node)
10680 OMP_CLAUSE_SET_MAP_KIND (referenced_ptr_node, zlas_kind);
10682 omp_mapping_group *struct_group;
10683 tree desc;
10684 if ((desc = OMP_CLAUSE_CHAIN (*grp->grp_start))
10685 && omp_map_clause_descriptor_p (desc)
10686 && omp_mapped_by_containing_struct (grpmap, decl,
10687 &struct_group))
10688 /* If we have a pointer set but we're mapping (or unmapping)
10689 the whole of the containing struct, we can remove the
10690 pointer set mapping. */
10691 OMP_CLAUSE_CHAIN (*grp->grp_start) = OMP_CLAUSE_CHAIN (desc);
10693 else if (TREE_CODE (TREE_TYPE (base_ptr)) == REFERENCE_TYPE
10694 && (TREE_CODE (TREE_TYPE (TREE_TYPE (base_ptr)))
10695 == ARRAY_TYPE)
10696 && OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION
10697 (*grp->grp_start))
10698 OMP_CLAUSE_SET_MAP_KIND (grp->grp_end, zlas_kind);
10700 break;
10702 case GOMP_MAP_ATTACH:
10703 /* Ignore standalone attach here. */
10704 break;
10706 default:
10708 omp_mapping_group *struct_group;
10709 if (omp_mapped_by_containing_struct (grpmap, decl, &struct_group)
10710 && *grp->grp_start == grp_end)
10712 omp_check_mapping_compatibility (OMP_CLAUSE_LOCATION (grp_end),
10713 struct_group, grp);
10714 /* Remove the whole of this mapping -- redundant. */
10715 grp->deleted = true;
10718 tree base = decl;
10719 while ((base = omp_get_base_pointer (base)))
10721 omp_mapping_group *base_group;
10723 if (omp_directive_maps_explicitly (grpmap, base, &base_group,
10724 true, true, false))
10726 tree grp_first = *base_group->grp_start;
10727 OMP_CLAUSE_SET_MAP_KIND (grp_first, GOMP_MAP_ALLOC);
10734 if (repair_chain)
10736 /* Group start pointers may have become detached from the
10737 OMP_CLAUSE_CHAIN of previous groups if elements were removed from the
10738 end of those groups. Fix that now. */
10739 tree *new_next = NULL;
10740 FOR_EACH_VEC_ELT (*groups, i, grp)
10742 if (new_next)
10743 grp->grp_start = new_next;
10745 new_next = &OMP_CLAUSE_CHAIN (grp->grp_end);
10750 /* Similar to omp_resolve_clause_dependencies, but for OpenACC. The only
10751 clause dependencies we handle for now are struct element mappings and
10752 whole-struct mappings on the same directive, and duplicate clause
10753 detection. */
10755 void
10756 oacc_resolve_clause_dependencies (vec<omp_mapping_group> *groups,
10757 hash_map<tree_operand_hash_no_se,
10758 omp_mapping_group *> *grpmap)
10760 int i;
10761 omp_mapping_group *grp;
10762 hash_set<tree_operand_hash> *seen_components = NULL;
10763 hash_set<tree_operand_hash> *shown_error = NULL;
10765 FOR_EACH_VEC_ELT (*groups, i, grp)
10767 tree grp_end = grp->grp_end;
10768 tree decl = OMP_CLAUSE_DECL (grp_end);
10770 gcc_assert (OMP_CLAUSE_CODE (grp_end) == OMP_CLAUSE_MAP);
10772 if (DECL_P (grp_end))
10773 continue;
10775 tree c = OMP_CLAUSE_DECL (*grp->grp_start);
10776 while (TREE_CODE (c) == ARRAY_REF)
10777 c = TREE_OPERAND (c, 0);
10778 if (TREE_CODE (c) != COMPONENT_REF)
10779 continue;
10780 if (!seen_components)
10781 seen_components = new hash_set<tree_operand_hash> ();
10782 if (!shown_error)
10783 shown_error = new hash_set<tree_operand_hash> ();
10784 if (seen_components->contains (c)
10785 && !shown_error->contains (c))
10787 error_at (OMP_CLAUSE_LOCATION (grp_end),
10788 "%qE appears more than once in map clauses",
10789 OMP_CLAUSE_DECL (grp_end));
10790 shown_error->add (c);
10792 else
10793 seen_components->add (c);
10795 omp_mapping_group *struct_group;
10796 if (omp_mapped_by_containing_struct (grpmap, decl, &struct_group)
10797 && *grp->grp_start == grp_end)
10799 omp_check_mapping_compatibility (OMP_CLAUSE_LOCATION (grp_end),
10800 struct_group, grp);
10801 /* Remove the whole of this mapping -- redundant. */
10802 grp->deleted = true;
10806 if (seen_components)
10807 delete seen_components;
10808 if (shown_error)
10809 delete shown_error;
10812 /* Link node NEWNODE so it is pointed to by chain INSERT_AT. NEWNODE's chain
10813 is linked to the previous node pointed to by INSERT_AT. */
10815 static tree *
10816 omp_siblist_insert_node_after (tree newnode, tree *insert_at)
10818 OMP_CLAUSE_CHAIN (newnode) = *insert_at;
10819 *insert_at = newnode;
10820 return &OMP_CLAUSE_CHAIN (newnode);
10823 /* Move NODE (which is currently pointed to by the chain OLD_POS) so it is
10824 pointed to by chain MOVE_AFTER instead. */
10826 static void
10827 omp_siblist_move_node_after (tree node, tree *old_pos, tree *move_after)
10829 gcc_assert (node == *old_pos);
10830 *old_pos = OMP_CLAUSE_CHAIN (node);
10831 OMP_CLAUSE_CHAIN (node) = *move_after;
10832 *move_after = node;
10835 /* Move nodes from FIRST_PTR (pointed to by previous node's chain) to
10836 LAST_NODE to after MOVE_AFTER chain. Similar to below function, but no
10837 new nodes are prepended to the list before splicing into the new position.
10838 Return the position we should continue scanning the list at, or NULL to
10839 stay where we were. */
10841 static tree *
10842 omp_siblist_move_nodes_after (tree *first_ptr, tree last_node,
10843 tree *move_after)
10845 if (first_ptr == move_after)
10846 return NULL;
10848 tree tmp = *first_ptr;
10849 *first_ptr = OMP_CLAUSE_CHAIN (last_node);
10850 OMP_CLAUSE_CHAIN (last_node) = *move_after;
10851 *move_after = tmp;
10853 return first_ptr;
10856 /* Concatenate two lists described by [FIRST_NEW, LAST_NEW_TAIL] and
10857 [FIRST_PTR, LAST_NODE], and insert them in the OMP clause list after chain
10858 pointer MOVE_AFTER.
10860 The latter list was previously part of the OMP clause list, and the former
10861 (prepended) part is comprised of new nodes.
10863 We start with a list of nodes starting with a struct mapping node. We
10864 rearrange the list so that new nodes starting from FIRST_NEW and whose last
10865 node's chain is LAST_NEW_TAIL comes directly after MOVE_AFTER, followed by
10866 the group of mapping nodes we are currently processing (from the chain
10867 FIRST_PTR to LAST_NODE). The return value is the pointer to the next chain
10868 we should continue processing from, or NULL to stay where we were.
10870 The transformation (in the case where MOVE_AFTER and FIRST_PTR are
10871 different) is worked through below. Here we are processing LAST_NODE, and
10872 FIRST_PTR points at the preceding mapping clause:
10874 #. mapping node chain
10875 ---------------------------------------------------
10876 A. struct_node [->B]
10877 B. comp_1 [->C]
10878 C. comp_2 [->D (move_after)]
10879 D. map_to_3 [->E]
10880 E. attach_3 [->F (first_ptr)]
10881 F. map_to_4 [->G (continue_at)]
10882 G. attach_4 (last_node) [->H]
10883 H. ...
10885 *last_new_tail = *first_ptr;
10887 I. new_node (first_new) [->F (last_new_tail)]
10889 *first_ptr = OMP_CLAUSE_CHAIN (last_node)
10891 #. mapping node chain
10892 ----------------------------------------------------
10893 A. struct_node [->B]
10894 B. comp_1 [->C]
10895 C. comp_2 [->D (move_after)]
10896 D. map_to_3 [->E]
10897 E. attach_3 [->H (first_ptr)]
10898 F. map_to_4 [->G (continue_at)]
10899 G. attach_4 (last_node) [->H]
10900 H. ...
10902 I. new_node (first_new) [->F (last_new_tail)]
10904 OMP_CLAUSE_CHAIN (last_node) = *move_after;
10906 #. mapping node chain
10907 ---------------------------------------------------
10908 A. struct_node [->B]
10909 B. comp_1 [->C]
10910 C. comp_2 [->D (move_after)]
10911 D. map_to_3 [->E]
10912 E. attach_3 [->H (continue_at)]
10913 F. map_to_4 [->G]
10914 G. attach_4 (last_node) [->D]
10915 H. ...
10917 I. new_node (first_new) [->F (last_new_tail)]
10919 *move_after = first_new;
10921 #. mapping node chain
10922 ---------------------------------------------------
10923 A. struct_node [->B]
10924 B. comp_1 [->C]
10925 C. comp_2 [->I (move_after)]
10926 D. map_to_3 [->E]
10927 E. attach_3 [->H (continue_at)]
10928 F. map_to_4 [->G]
10929 G. attach_4 (last_node) [->D]
10930 H. ...
10931 I. new_node (first_new) [->F (last_new_tail)]
10933 or, in order:
10935 #. mapping node chain
10936 ---------------------------------------------------
10937 A. struct_node [->B]
10938 B. comp_1 [->C]
10939 C. comp_2 [->I (move_after)]
10940 I. new_node (first_new) [->F (last_new_tail)]
10941 F. map_to_4 [->G]
10942 G. attach_4 (last_node) [->D]
10943 D. map_to_3 [->E]
10944 E. attach_3 [->H (continue_at)]
10945 H. ...
10948 static tree *
10949 omp_siblist_move_concat_nodes_after (tree first_new, tree *last_new_tail,
10950 tree *first_ptr, tree last_node,
10951 tree *move_after)
10953 tree *continue_at = NULL;
10954 *last_new_tail = *first_ptr;
10955 if (first_ptr == move_after)
10956 *move_after = first_new;
10957 else
10959 *first_ptr = OMP_CLAUSE_CHAIN (last_node);
10960 continue_at = first_ptr;
10961 OMP_CLAUSE_CHAIN (last_node) = *move_after;
10962 *move_after = first_new;
10964 return continue_at;
10967 static omp_addr_token *
10968 omp_first_chained_access_token (vec<omp_addr_token *> &addr_tokens)
10970 using namespace omp_addr_tokenizer;
10971 int idx = addr_tokens.length () - 1;
10972 gcc_assert (idx >= 0);
10973 if (addr_tokens[idx]->type != ACCESS_METHOD)
10974 return addr_tokens[idx];
10975 while (idx > 0 && addr_tokens[idx - 1]->type == ACCESS_METHOD)
10976 idx--;
10977 return addr_tokens[idx];
10980 /* Mapping struct members causes an additional set of nodes to be created,
10981 starting with GOMP_MAP_STRUCT followed by a number of mappings equal to the
10982 number of members being mapped, in order of ascending position (address or
10983 bitwise).
10985 We scan through the list of mapping clauses, calling this function for each
10986 struct member mapping we find, and build up the list of mappings after the
10987 initial GOMP_MAP_STRUCT node. For pointer members, these will be
10988 newly-created ALLOC nodes. For non-pointer members, the existing mapping is
10989 moved into place in the sorted list.
10991 struct {
10992 int *a;
10993 int *b;
10994 int c;
10995 int *d;
10998 #pragma (acc|omp directive) copy(struct.a[0:n], struct.b[0:n], struct.c,
10999 struct.d[0:n])
11001 GOMP_MAP_STRUCT (4)
11002 [GOMP_MAP_FIRSTPRIVATE_REFERENCE -- for refs to structs]
11003 GOMP_MAP_ALLOC (struct.a)
11004 GOMP_MAP_ALLOC (struct.b)
11005 GOMP_MAP_TO (struct.c)
11006 GOMP_MAP_ALLOC (struct.d)
11009 In the case where we are mapping references to pointers, or in Fortran if
11010 we are mapping an array with a descriptor, additional nodes may be created
11011 after the struct node list also.
11013 The return code is either a pointer to the next node to process (if the
11014 list has been rearranged), else NULL to continue with the next node in the
11015 original list. */
11017 static tree *
11018 omp_accumulate_sibling_list (enum omp_region_type region_type,
11019 enum tree_code code,
11020 hash_map<tree_operand_hash, tree>
11021 *&struct_map_to_clause,
11022 hash_map<tree_operand_hash_no_se,
11023 omp_mapping_group *> *group_map,
11024 tree *grp_start_p, tree grp_end,
11025 vec<omp_addr_token *> &addr_tokens, tree **inner,
11026 bool *fragile_p, bool reprocessing_struct,
11027 tree **added_tail)
11029 using namespace omp_addr_tokenizer;
11030 poly_offset_int coffset;
11031 poly_int64 cbitpos;
11032 tree ocd = OMP_CLAUSE_DECL (grp_end);
11033 bool openmp = !(region_type & ORT_ACC);
11034 bool target = (region_type & ORT_TARGET) != 0;
11035 tree *continue_at = NULL;
11037 while (TREE_CODE (ocd) == ARRAY_REF)
11038 ocd = TREE_OPERAND (ocd, 0);
11040 if (*fragile_p)
11042 omp_mapping_group *to_group
11043 = omp_get_nonfirstprivate_group (group_map, ocd, true);
11045 if (to_group)
11046 return NULL;
11049 omp_addr_token *last_token = omp_first_chained_access_token (addr_tokens);
11050 if (last_token->type == ACCESS_METHOD)
11052 switch (last_token->u.access_kind)
11054 case ACCESS_REF:
11055 case ACCESS_REF_TO_POINTER:
11056 case ACCESS_REF_TO_POINTER_OFFSET:
11057 case ACCESS_INDEXED_REF_TO_ARRAY:
11058 /* We may see either a bare reference or a dereferenced
11059 "convert_from_reference"-like one here. Handle either way. */
11060 if (TREE_CODE (ocd) == INDIRECT_REF)
11061 ocd = TREE_OPERAND (ocd, 0);
11062 gcc_assert (TREE_CODE (TREE_TYPE (ocd)) == REFERENCE_TYPE);
11063 break;
11065 default:
11070 bool variable_offset;
11071 tree base
11072 = extract_base_bit_offset (ocd, &cbitpos, &coffset, &variable_offset);
11074 int base_token;
11075 for (base_token = addr_tokens.length () - 1; base_token >= 0; base_token--)
11077 if (addr_tokens[base_token]->type == ARRAY_BASE
11078 || addr_tokens[base_token]->type == STRUCTURE_BASE)
11079 break;
11082 /* The two expressions in the assertion below aren't quite the same: if we
11083 have 'struct_base_decl access_indexed_array' for something like
11084 "myvar[2].x" then base will be "myvar" and addr_tokens[base_token]->expr
11085 will be "myvar[2]" -- the actual base of the structure.
11086 The former interpretation leads to a strange situation where we get
11087 struct(myvar) alloc(myvar[2].ptr1)
11088 That is, the array of structures is kind of treated as one big structure
11089 for the purposes of gathering sibling lists, etc. */
11090 /* gcc_assert (base == addr_tokens[base_token]->expr); */
11092 bool attach_detach = ((OMP_CLAUSE_MAP_KIND (grp_end)
11093 == GOMP_MAP_ATTACH_DETACH)
11094 || (OMP_CLAUSE_MAP_KIND (grp_end)
11095 == GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION));
11096 bool has_descriptor = false;
11097 if (OMP_CLAUSE_CHAIN (*grp_start_p) != grp_end)
11099 tree grp_mid = OMP_CLAUSE_CHAIN (*grp_start_p);
11100 if (grp_mid && omp_map_clause_descriptor_p (grp_mid))
11101 has_descriptor = true;
11104 if (!struct_map_to_clause || struct_map_to_clause->get (base) == NULL)
11106 enum gomp_map_kind str_kind = GOMP_MAP_STRUCT;
11108 if (struct_map_to_clause == NULL)
11109 struct_map_to_clause = new hash_map<tree_operand_hash, tree>;
11111 if (variable_offset)
11112 str_kind = GOMP_MAP_STRUCT_UNORD;
11114 tree l = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end), OMP_CLAUSE_MAP);
11116 OMP_CLAUSE_SET_MAP_KIND (l, str_kind);
11117 OMP_CLAUSE_DECL (l) = unshare_expr (base);
11118 OMP_CLAUSE_SIZE (l) = size_int (1);
11120 struct_map_to_clause->put (base, l);
11122 /* On first iterating through the clause list, we insert the struct node
11123 just before the component access node that triggers the initial
11124 omp_accumulate_sibling_list call for a particular sibling list (and
11125 it then forms the first entry in that list). When reprocessing
11126 struct bases that are themselves component accesses, we insert the
11127 struct node on an off-side list to avoid inserting the new
11128 GOMP_MAP_STRUCT into the middle of the old one. */
11129 tree *insert_node_pos = reprocessing_struct ? *added_tail : grp_start_p;
11131 if (has_descriptor)
11133 tree desc = OMP_CLAUSE_CHAIN (*grp_start_p);
11134 if (code == OMP_TARGET_EXIT_DATA || code == OACC_EXIT_DATA)
11135 OMP_CLAUSE_SET_MAP_KIND (desc, GOMP_MAP_RELEASE);
11136 tree sc = *insert_node_pos;
11137 OMP_CLAUSE_CHAIN (l) = desc;
11138 OMP_CLAUSE_CHAIN (*grp_start_p) = OMP_CLAUSE_CHAIN (desc);
11139 OMP_CLAUSE_CHAIN (desc) = sc;
11140 *insert_node_pos = l;
11142 else if (attach_detach)
11144 tree extra_node;
11145 tree alloc_node
11146 = build_omp_struct_comp_nodes (code, *grp_start_p, grp_end,
11147 &extra_node);
11148 tree *tail;
11149 OMP_CLAUSE_CHAIN (l) = alloc_node;
11151 if (extra_node)
11153 OMP_CLAUSE_CHAIN (extra_node) = *insert_node_pos;
11154 OMP_CLAUSE_CHAIN (alloc_node) = extra_node;
11155 tail = &OMP_CLAUSE_CHAIN (extra_node);
11157 else
11159 OMP_CLAUSE_CHAIN (alloc_node) = *insert_node_pos;
11160 tail = &OMP_CLAUSE_CHAIN (alloc_node);
11163 /* For OpenMP semantics, we don't want to implicitly allocate
11164 space for the pointer here for non-compute regions (e.g. "enter
11165 data"). A FRAGILE_P node is only being created so that
11166 omp-low.cc is able to rewrite the struct properly.
11167 For references (to pointers), we want to actually allocate the
11168 space for the reference itself in the sorted list following the
11169 struct node.
11170 For pointers, we want to allocate space if we had an explicit
11171 mapping of the attachment point, but not otherwise. */
11172 if (*fragile_p
11173 || (openmp
11174 && !target
11175 && attach_detach
11176 && TREE_CODE (TREE_TYPE (ocd)) == POINTER_TYPE
11177 && !OMP_CLAUSE_ATTACHMENT_MAPPING_ERASED (grp_end)))
11179 if (!lang_GNU_Fortran ())
11180 /* In Fortran, pointers are dereferenced automatically, but may
11181 be unassociated. So we still want to allocate space for the
11182 pointer (as the base for an attach operation that should be
11183 present in the same directive's clause list also). */
11184 OMP_CLAUSE_SIZE (alloc_node) = size_zero_node;
11185 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (alloc_node) = 1;
11188 *insert_node_pos = l;
11190 if (reprocessing_struct)
11192 /* When reprocessing a struct node group used as the base of a
11193 subcomponent access, if we have a reference-to-pointer base,
11194 we will see:
11195 struct(**ptr) attach(*ptr)
11196 whereas for a non-reprocess-struct group, we see, e.g.:
11197 tofrom(**ptr) attach(*ptr) attach(ptr)
11198 and we create the "alloc" for the second "attach", i.e.
11199 for the reference itself. When reprocessing a struct group we
11200 thus change the pointer attachment into a reference attachment
11201 by stripping the indirection. (The attachment of the
11202 referenced pointer must happen elsewhere, either on the same
11203 directive, or otherwise.) */
11204 tree adecl = OMP_CLAUSE_DECL (alloc_node);
11206 if ((TREE_CODE (adecl) == INDIRECT_REF
11207 || (TREE_CODE (adecl) == MEM_REF
11208 && integer_zerop (TREE_OPERAND (adecl, 1))))
11209 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (adecl, 0)))
11210 == REFERENCE_TYPE)
11211 && (TREE_CODE (TREE_TYPE (TREE_TYPE
11212 (TREE_OPERAND (adecl, 0)))) == POINTER_TYPE))
11213 OMP_CLAUSE_DECL (alloc_node) = TREE_OPERAND (adecl, 0);
11215 *added_tail = tail;
11218 else
11220 gcc_assert (*grp_start_p == grp_end);
11221 if (reprocessing_struct)
11223 /* If we don't have an attach/detach node, this is a
11224 "target data" directive or similar, not an offload region.
11225 Synthesize an "alloc" node using just the initiating
11226 GOMP_MAP_STRUCT decl. */
11227 gomp_map_kind k = (code == OMP_TARGET_EXIT_DATA
11228 || code == OACC_EXIT_DATA)
11229 ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
11230 tree alloc_node
11231 = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end),
11232 OMP_CLAUSE_MAP);
11233 OMP_CLAUSE_SET_MAP_KIND (alloc_node, k);
11234 OMP_CLAUSE_DECL (alloc_node) = unshare_expr (last_token->expr);
11235 OMP_CLAUSE_SIZE (alloc_node)
11236 = TYPE_SIZE_UNIT (TREE_TYPE (OMP_CLAUSE_DECL (alloc_node)));
11238 OMP_CLAUSE_CHAIN (alloc_node) = OMP_CLAUSE_CHAIN (l);
11239 OMP_CLAUSE_CHAIN (l) = alloc_node;
11240 *insert_node_pos = l;
11241 *added_tail = &OMP_CLAUSE_CHAIN (alloc_node);
11243 else
11244 grp_start_p = omp_siblist_insert_node_after (l, insert_node_pos);
11247 unsigned last_access = base_token + 1;
11249 while (last_access + 1 < addr_tokens.length ()
11250 && addr_tokens[last_access + 1]->type == ACCESS_METHOD)
11251 last_access++;
11253 if ((region_type & ORT_TARGET)
11254 && addr_tokens[base_token + 1]->type == ACCESS_METHOD)
11256 bool base_ref = false;
11257 access_method_kinds access_kind
11258 = addr_tokens[last_access]->u.access_kind;
11260 switch (access_kind)
11262 case ACCESS_DIRECT:
11263 case ACCESS_INDEXED_ARRAY:
11264 return NULL;
11266 case ACCESS_REF:
11267 case ACCESS_REF_TO_POINTER:
11268 case ACCESS_REF_TO_POINTER_OFFSET:
11269 case ACCESS_INDEXED_REF_TO_ARRAY:
11270 base_ref = true;
11271 break;
11273 default:
11276 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end),
11277 OMP_CLAUSE_MAP);
11278 enum gomp_map_kind mkind;
11279 omp_mapping_group *decl_group;
11280 tree use_base;
11281 switch (access_kind)
11283 case ACCESS_POINTER:
11284 case ACCESS_POINTER_OFFSET:
11285 use_base = addr_tokens[last_access]->expr;
11286 break;
11287 case ACCESS_REF_TO_POINTER:
11288 case ACCESS_REF_TO_POINTER_OFFSET:
11289 use_base
11290 = build_fold_indirect_ref (addr_tokens[last_access]->expr);
11291 break;
11292 default:
11293 use_base = addr_tokens[base_token]->expr;
11295 bool mapped_to_p
11296 = omp_directive_maps_explicitly (group_map, use_base, &decl_group,
11297 true, false, true);
11298 if (addr_tokens[base_token]->type == STRUCTURE_BASE
11299 && DECL_P (addr_tokens[last_access]->expr)
11300 && !mapped_to_p)
11301 mkind = base_ref ? GOMP_MAP_FIRSTPRIVATE_REFERENCE
11302 : GOMP_MAP_FIRSTPRIVATE_POINTER;
11303 else
11304 mkind = GOMP_MAP_ATTACH_DETACH;
11306 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
11307 /* If we have a reference to pointer base, we want to attach the
11308 pointer here, not the reference. The reference attachment happens
11309 elsewhere. */
11310 bool ref_to_ptr
11311 = (access_kind == ACCESS_REF_TO_POINTER
11312 || access_kind == ACCESS_REF_TO_POINTER_OFFSET);
11313 tree sdecl = addr_tokens[last_access]->expr;
11314 tree sdecl_ptr = ref_to_ptr ? build_fold_indirect_ref (sdecl)
11315 : sdecl;
11316 /* For the FIRSTPRIVATE_REFERENCE after the struct node, we
11317 want to use the reference itself for the decl, but we
11318 still want to use the pointer to calculate the bias. */
11319 OMP_CLAUSE_DECL (c2) = (mkind == GOMP_MAP_ATTACH_DETACH)
11320 ? sdecl_ptr : sdecl;
11321 sdecl = sdecl_ptr;
11322 tree baddr = build_fold_addr_expr (base);
11323 baddr = fold_convert_loc (OMP_CLAUSE_LOCATION (grp_end),
11324 ptrdiff_type_node, baddr);
11325 tree decladdr = fold_convert_loc (OMP_CLAUSE_LOCATION (grp_end),
11326 ptrdiff_type_node, sdecl);
11327 OMP_CLAUSE_SIZE (c2)
11328 = fold_build2_loc (OMP_CLAUSE_LOCATION (grp_end), MINUS_EXPR,
11329 ptrdiff_type_node, baddr, decladdr);
11330 /* Insert after struct node. */
11331 OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (l);
11332 OMP_CLAUSE_CHAIN (l) = c2;
11334 if (addr_tokens[base_token]->type == STRUCTURE_BASE
11335 && (addr_tokens[base_token]->u.structure_base_kind
11336 == BASE_COMPONENT_EXPR)
11337 && mkind == GOMP_MAP_ATTACH_DETACH
11338 && addr_tokens[last_access]->u.access_kind != ACCESS_REF)
11340 *inner = insert_node_pos;
11341 if (openmp)
11342 *fragile_p = true;
11343 return NULL;
11347 if (addr_tokens[base_token]->type == STRUCTURE_BASE
11348 && (addr_tokens[base_token]->u.structure_base_kind
11349 == BASE_COMPONENT_EXPR)
11350 && addr_tokens[last_access]->u.access_kind == ACCESS_REF)
11351 *inner = insert_node_pos;
11353 return NULL;
11355 else if (struct_map_to_clause)
11357 tree *osc = struct_map_to_clause->get (base);
11358 tree *sc = NULL, *scp = NULL;
11359 bool unordered = false;
11361 if (osc && OMP_CLAUSE_MAP_KIND (*osc) == GOMP_MAP_STRUCT_UNORD)
11362 unordered = true;
11364 unsigned HOST_WIDE_INT i, elems = tree_to_uhwi (OMP_CLAUSE_SIZE (*osc));
11365 sc = &OMP_CLAUSE_CHAIN (*osc);
11366 /* The struct mapping might be immediately followed by a
11367 FIRSTPRIVATE_POINTER, FIRSTPRIVATE_REFERENCE or an ATTACH_DETACH --
11368 if it's an indirect access or a reference, or if the structure base
11369 is not a decl. The FIRSTPRIVATE_* nodes are removed in omp-low.cc
11370 after they have been processed there, and ATTACH_DETACH nodes are
11371 recomputed and moved out of the GOMP_MAP_STRUCT construct once
11372 sibling list building is complete. */
11373 if (OMP_CLAUSE_MAP_KIND (*sc) == GOMP_MAP_FIRSTPRIVATE_POINTER
11374 || OMP_CLAUSE_MAP_KIND (*sc) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
11375 || OMP_CLAUSE_MAP_KIND (*sc) == GOMP_MAP_ATTACH_DETACH)
11376 sc = &OMP_CLAUSE_CHAIN (*sc);
11377 for (i = 0; i < elems; i++, sc = &OMP_CLAUSE_CHAIN (*sc))
11378 if (attach_detach && sc == grp_start_p)
11379 break;
11380 else if (TREE_CODE (OMP_CLAUSE_DECL (*sc)) != COMPONENT_REF
11381 && TREE_CODE (OMP_CLAUSE_DECL (*sc)) != INDIRECT_REF
11382 && TREE_CODE (OMP_CLAUSE_DECL (*sc)) != ARRAY_REF)
11383 break;
11384 else
11386 tree sc_decl = OMP_CLAUSE_DECL (*sc);
11387 poly_offset_int offset;
11388 poly_int64 bitpos;
11390 if (TREE_CODE (sc_decl) == ARRAY_REF)
11392 while (TREE_CODE (sc_decl) == ARRAY_REF)
11393 sc_decl = TREE_OPERAND (sc_decl, 0);
11394 if (TREE_CODE (sc_decl) != COMPONENT_REF
11395 || TREE_CODE (TREE_TYPE (sc_decl)) != ARRAY_TYPE)
11396 break;
11398 else if (INDIRECT_REF_P (sc_decl)
11399 && TREE_CODE (TREE_OPERAND (sc_decl, 0)) == COMPONENT_REF
11400 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (sc_decl, 0)))
11401 == REFERENCE_TYPE))
11402 sc_decl = TREE_OPERAND (sc_decl, 0);
11404 bool variable_offset2;
11405 tree base2 = extract_base_bit_offset (sc_decl, &bitpos, &offset,
11406 &variable_offset2);
11407 if (!base2 || !operand_equal_p (base2, base, 0))
11408 break;
11409 if (scp)
11410 continue;
11411 if (variable_offset2)
11413 OMP_CLAUSE_SET_MAP_KIND (*osc, GOMP_MAP_STRUCT_UNORD);
11414 unordered = true;
11415 break;
11417 else if ((region_type & ORT_ACC) != 0)
11419 /* For OpenACC, allow (ignore) duplicate struct accesses in
11420 the middle of a mapping clause, e.g. "mystruct->foo" in:
11421 copy(mystruct->foo->bar) copy(mystruct->foo->qux). */
11422 if (reprocessing_struct
11423 && known_eq (coffset, offset)
11424 && known_eq (cbitpos, bitpos))
11425 return NULL;
11427 else if (known_eq (coffset, offset)
11428 && known_eq (cbitpos, bitpos))
11430 /* Having two struct members at the same offset doesn't work,
11431 so make sure we don't. (We're allowed to ignore this.
11432 Should we report the error?) */
11433 /*error_at (OMP_CLAUSE_LOCATION (grp_end),
11434 "duplicate struct member %qE in map clauses",
11435 OMP_CLAUSE_DECL (grp_end));*/
11436 return NULL;
11438 if (maybe_lt (coffset, offset)
11439 || (known_eq (coffset, offset)
11440 && maybe_lt (cbitpos, bitpos)))
11442 if (attach_detach)
11443 scp = sc;
11444 else
11445 break;
11449 /* If this is an unordered struct, just insert the new element at the
11450 end of the list. */
11451 if (unordered)
11453 for (; i < elems; i++)
11454 sc = &OMP_CLAUSE_CHAIN (*sc);
11455 scp = NULL;
11458 OMP_CLAUSE_SIZE (*osc)
11459 = size_binop (PLUS_EXPR, OMP_CLAUSE_SIZE (*osc), size_one_node);
11461 if (reprocessing_struct)
11463 /* If we're reprocessing a struct node, we don't want to do most of
11464 the list manipulation below. We only need to handle the (pointer
11465 or reference) attach/detach case. */
11466 tree extra_node, alloc_node;
11467 if (has_descriptor)
11468 gcc_unreachable ();
11469 else if (attach_detach)
11470 alloc_node = build_omp_struct_comp_nodes (code, *grp_start_p,
11471 grp_end, &extra_node);
11472 else
11474 /* If we don't have an attach/detach node, this is a
11475 "target data" directive or similar, not an offload region.
11476 Synthesize an "alloc" node using just the initiating
11477 GOMP_MAP_STRUCT decl. */
11478 gomp_map_kind k = (code == OMP_TARGET_EXIT_DATA
11479 || code == OACC_EXIT_DATA)
11480 ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
11481 alloc_node
11482 = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end),
11483 OMP_CLAUSE_MAP);
11484 OMP_CLAUSE_SET_MAP_KIND (alloc_node, k);
11485 OMP_CLAUSE_DECL (alloc_node) = unshare_expr (last_token->expr);
11486 OMP_CLAUSE_SIZE (alloc_node)
11487 = TYPE_SIZE_UNIT (TREE_TYPE (OMP_CLAUSE_DECL (alloc_node)));
11490 if (scp)
11491 omp_siblist_insert_node_after (alloc_node, scp);
11492 else
11494 tree *new_end = omp_siblist_insert_node_after (alloc_node, sc);
11495 if (sc == *added_tail)
11496 *added_tail = new_end;
11499 return NULL;
11502 if (has_descriptor)
11504 tree desc = OMP_CLAUSE_CHAIN (*grp_start_p);
11505 if (code == OMP_TARGET_EXIT_DATA
11506 || code == OACC_EXIT_DATA)
11507 OMP_CLAUSE_SET_MAP_KIND (desc, GOMP_MAP_RELEASE);
11508 omp_siblist_move_node_after (desc,
11509 &OMP_CLAUSE_CHAIN (*grp_start_p),
11510 scp ? scp : sc);
11512 else if (attach_detach)
11514 tree cl = NULL_TREE, extra_node;
11515 tree alloc_node = build_omp_struct_comp_nodes (code, *grp_start_p,
11516 grp_end, &extra_node);
11517 tree *tail_chain = NULL;
11519 if (*fragile_p
11520 || (openmp
11521 && !target
11522 && attach_detach
11523 && TREE_CODE (TREE_TYPE (ocd)) == POINTER_TYPE
11524 && !OMP_CLAUSE_ATTACHMENT_MAPPING_ERASED (grp_end)))
11526 if (!lang_GNU_Fortran ())
11527 OMP_CLAUSE_SIZE (alloc_node) = size_zero_node;
11528 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (alloc_node) = 1;
11531 /* Here, we have:
11533 grp_end : the last (or only) node in this group.
11534 grp_start_p : pointer to the first node in a pointer mapping group
11535 up to and including GRP_END.
11536 sc : pointer to the chain for the end of the struct component
11537 list.
11538 scp : pointer to the chain for the sorted position at which we
11539 should insert in the middle of the struct component list
11540 (else NULL to insert at end).
11541 alloc_node : the "alloc" node for the structure (pointer-type)
11542 component. We insert at SCP (if present), else SC
11543 (the end of the struct component list).
11544 extra_node : a newly-synthesized node for an additional indirect
11545 pointer mapping or a Fortran pointer set, if needed.
11546 cl : first node to prepend before grp_start_p.
11547 tail_chain : pointer to chain of last prepended node.
11549 The general idea is we move the nodes for this struct mapping
11550 together: the alloc node goes into the sorted list directly after
11551 the struct mapping, and any extra nodes (together with the nodes
11552 mapping arrays pointed to by struct components) get moved after
11553 that list. When SCP is NULL, we insert the nodes at SC, i.e. at
11554 the end of the struct component mapping list. It's important that
11555 the alloc_node comes first in that case because it's part of the
11556 sorted component mapping list (but subsequent nodes are not!). */
11558 if (scp)
11559 omp_siblist_insert_node_after (alloc_node, scp);
11561 /* Make [cl,tail_chain] a list of the alloc node (if we haven't
11562 already inserted it) and the extra_node (if it is present). The
11563 list can be empty if we added alloc_node above and there is no
11564 extra node. */
11565 if (scp && extra_node)
11567 cl = extra_node;
11568 tail_chain = &OMP_CLAUSE_CHAIN (extra_node);
11570 else if (extra_node)
11572 OMP_CLAUSE_CHAIN (alloc_node) = extra_node;
11573 cl = alloc_node;
11574 tail_chain = &OMP_CLAUSE_CHAIN (extra_node);
11576 else if (!scp)
11578 cl = alloc_node;
11579 tail_chain = &OMP_CLAUSE_CHAIN (alloc_node);
11582 continue_at
11583 = cl ? omp_siblist_move_concat_nodes_after (cl, tail_chain,
11584 grp_start_p, grp_end,
11586 : omp_siblist_move_nodes_after (grp_start_p, grp_end, sc);
11588 else if (*sc != grp_end)
11590 gcc_assert (*grp_start_p == grp_end);
11592 /* We are moving the current node back to a previous struct node:
11593 the node that used to point to the current node will now point to
11594 the next node. */
11595 continue_at = grp_start_p;
11596 /* In the non-pointer case, the mapping clause itself is moved into
11597 the correct position in the struct component list, which in this
11598 case is just SC. */
11599 omp_siblist_move_node_after (*grp_start_p, grp_start_p, sc);
11602 return continue_at;
11605 /* Scan through GROUPS, and create sorted structure sibling lists without
11606 gimplifying. */
11608 static bool
11609 omp_build_struct_sibling_lists (enum tree_code code,
11610 enum omp_region_type region_type,
11611 vec<omp_mapping_group> *groups,
11612 hash_map<tree_operand_hash_no_se,
11613 omp_mapping_group *> **grpmap,
11614 tree *list_p)
11616 using namespace omp_addr_tokenizer;
11617 unsigned i;
11618 omp_mapping_group *grp;
11619 hash_map<tree_operand_hash, tree> *struct_map_to_clause = NULL;
11620 bool success = true;
11621 tree *new_next = NULL;
11622 tree *tail = &OMP_CLAUSE_CHAIN ((*groups)[groups->length () - 1].grp_end);
11623 tree added_nodes = NULL_TREE;
11624 tree *added_tail = &added_nodes;
11625 auto_vec<omp_mapping_group> pre_hwm_groups;
11627 FOR_EACH_VEC_ELT (*groups, i, grp)
11629 tree c = grp->grp_end;
11630 tree decl = OMP_CLAUSE_DECL (c);
11631 tree grp_end = grp->grp_end;
11632 auto_vec<omp_addr_token *> addr_tokens;
11633 tree sentinel = OMP_CLAUSE_CHAIN (grp_end);
11635 if (new_next && !grp->reprocess_struct)
11636 grp->grp_start = new_next;
11638 new_next = NULL;
11640 tree *grp_start_p = grp->grp_start;
11642 if (DECL_P (decl))
11643 continue;
11645 /* Skip groups we marked for deletion in
11646 {omp,oacc}_resolve_clause_dependencies. */
11647 if (grp->deleted)
11648 continue;
11650 if (OMP_CLAUSE_CHAIN (*grp_start_p)
11651 && OMP_CLAUSE_CHAIN (*grp_start_p) != grp_end)
11653 /* Don't process an array descriptor that isn't inside a derived type
11654 as a struct (the GOMP_MAP_POINTER following will have the form
11655 "var.data", but such mappings are handled specially). */
11656 tree grpmid = OMP_CLAUSE_CHAIN (*grp_start_p);
11657 if (omp_map_clause_descriptor_p (grpmid)
11658 && DECL_P (OMP_CLAUSE_DECL (grpmid)))
11659 continue;
11662 tree expr = decl;
11664 while (TREE_CODE (expr) == ARRAY_REF)
11665 expr = TREE_OPERAND (expr, 0);
11667 if (!omp_parse_expr (addr_tokens, expr))
11668 continue;
11670 omp_addr_token *last_token
11671 = omp_first_chained_access_token (addr_tokens);
11673 /* A mapping of a reference to a pointer member that doesn't specify an
11674 array section, etc., like this:
11675 *mystruct.ref_to_ptr
11676 should not be processed by the struct sibling-list handling code --
11677 it just transfers the referenced pointer.
11679 In contrast, the quite similar-looking construct:
11680 *mystruct.ptr
11681 which is equivalent to e.g.
11682 mystruct.ptr[0]
11683 *does* trigger sibling-list processing.
11685 An exception for the former case is for "fragile" groups where the
11686 reference itself is not handled otherwise; this is subject to special
11687 handling in omp_accumulate_sibling_list also. */
11689 if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
11690 && last_token->type == ACCESS_METHOD
11691 && last_token->u.access_kind == ACCESS_REF
11692 && !grp->fragile)
11693 continue;
11695 tree d = decl;
11696 if (TREE_CODE (d) == ARRAY_REF)
11698 while (TREE_CODE (d) == ARRAY_REF)
11699 d = TREE_OPERAND (d, 0);
11700 if (TREE_CODE (d) == COMPONENT_REF
11701 && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE)
11702 decl = d;
11704 if (d == decl
11705 && INDIRECT_REF_P (decl)
11706 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
11707 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
11708 == REFERENCE_TYPE)
11709 && (OMP_CLAUSE_MAP_KIND (c)
11710 != GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION))
11711 decl = TREE_OPERAND (decl, 0);
11713 STRIP_NOPS (decl);
11715 if (TREE_CODE (decl) != COMPONENT_REF)
11716 continue;
11718 /* If we're mapping the whole struct in another node, skip adding this
11719 node to a sibling list. */
11720 omp_mapping_group *wholestruct;
11721 if (omp_mapped_by_containing_struct (*grpmap, OMP_CLAUSE_DECL (c),
11722 &wholestruct))
11723 continue;
11725 if (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_TO_PSET
11726 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH
11727 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_DETACH
11728 && code != OACC_UPDATE
11729 && code != OMP_TARGET_UPDATE)
11731 if (error_operand_p (decl))
11733 success = false;
11734 goto error_out;
11737 tree stype = TREE_TYPE (decl);
11738 if (TREE_CODE (stype) == REFERENCE_TYPE)
11739 stype = TREE_TYPE (stype);
11740 if (TYPE_SIZE_UNIT (stype) == NULL
11741 || TREE_CODE (TYPE_SIZE_UNIT (stype)) != INTEGER_CST)
11743 error_at (OMP_CLAUSE_LOCATION (c),
11744 "mapping field %qE of variable length "
11745 "structure", OMP_CLAUSE_DECL (c));
11746 success = false;
11747 goto error_out;
11750 tree *inner = NULL;
11751 bool fragile_p = grp->fragile;
11753 new_next
11754 = omp_accumulate_sibling_list (region_type, code,
11755 struct_map_to_clause, *grpmap,
11756 grp_start_p, grp_end, addr_tokens,
11757 &inner, &fragile_p,
11758 grp->reprocess_struct, &added_tail);
11760 if (inner)
11762 omp_mapping_group newgrp;
11763 newgrp.grp_start = inner;
11764 if (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (*inner))
11765 == GOMP_MAP_ATTACH_DETACH)
11766 newgrp.grp_end = OMP_CLAUSE_CHAIN (*inner);
11767 else
11768 newgrp.grp_end = *inner;
11769 newgrp.mark = UNVISITED;
11770 newgrp.sibling = NULL;
11771 newgrp.deleted = false;
11772 newgrp.reprocess_struct = true;
11773 newgrp.fragile = fragile_p;
11774 newgrp.next = NULL;
11775 groups->safe_push (newgrp);
11777 /* !!! Growing GROUPS might invalidate the pointers in the group
11778 map. Rebuild it here. This is a bit inefficient, but
11779 shouldn't happen very often. */
11780 delete (*grpmap);
11781 *grpmap
11782 = omp_reindex_mapping_groups (list_p, groups, &pre_hwm_groups,
11783 sentinel);
11788 /* Delete groups marked for deletion above. At this point the order of the
11789 groups may no longer correspond to the order of the underlying list,
11790 which complicates this a little. First clear out OMP_CLAUSE_DECL for
11791 deleted nodes... */
11793 FOR_EACH_VEC_ELT (*groups, i, grp)
11794 if (grp->deleted)
11795 for (tree d = *grp->grp_start;
11796 d != OMP_CLAUSE_CHAIN (grp->grp_end);
11797 d = OMP_CLAUSE_CHAIN (d))
11798 OMP_CLAUSE_DECL (d) = NULL_TREE;
11800 /* ...then sweep through the list removing the now-empty nodes. */
11802 tail = list_p;
11803 while (*tail)
11805 if (OMP_CLAUSE_CODE (*tail) == OMP_CLAUSE_MAP
11806 && OMP_CLAUSE_DECL (*tail) == NULL_TREE)
11807 *tail = OMP_CLAUSE_CHAIN (*tail);
11808 else
11809 tail = &OMP_CLAUSE_CHAIN (*tail);
11812 /* Tack on the struct nodes added during nested struct reprocessing. */
11813 if (added_nodes)
11815 *tail = added_nodes;
11816 tail = added_tail;
11819 /* Now we have finished building the struct sibling lists, reprocess
11820 newly-added "attach" nodes: we need the address of the first
11821 mapped element of each struct sibling list for the bias of the attach
11822 operation -- not necessarily the base address of the whole struct. */
11823 if (struct_map_to_clause)
11824 for (hash_map<tree_operand_hash, tree>::iterator iter
11825 = struct_map_to_clause->begin ();
11826 iter != struct_map_to_clause->end ();
11827 ++iter)
11829 tree struct_node = (*iter).second;
11830 gcc_assert (OMP_CLAUSE_CODE (struct_node) == OMP_CLAUSE_MAP);
11831 tree attach = OMP_CLAUSE_CHAIN (struct_node);
11833 if (OMP_CLAUSE_CODE (attach) != OMP_CLAUSE_MAP
11834 || OMP_CLAUSE_MAP_KIND (attach) != GOMP_MAP_ATTACH_DETACH)
11835 continue;
11837 OMP_CLAUSE_SET_MAP_KIND (attach, GOMP_MAP_ATTACH);
11839 /* Sanity check: the standalone attach node will not work if we have
11840 an "enter data" operation (because for those, variables need to be
11841 mapped separately and attach nodes must be grouped together with the
11842 base they attach to). We should only have created the
11843 ATTACH_DETACH node after GOMP_MAP_STRUCT for a target region, so
11844 this should never be true. */
11845 gcc_assert ((region_type & ORT_TARGET) != 0);
11847 /* This is the first sorted node in the struct sibling list. Use it
11848 to recalculate the correct bias to use.
11849 (&first_node - attach_decl).
11850 For GOMP_MAP_STRUCT_UNORD, we need e.g. the
11851 min(min(min(first,second),third),fourth) element, because the
11852 elements aren't in any particular order. */
11853 tree lowest_addr;
11854 if (OMP_CLAUSE_MAP_KIND (struct_node) == GOMP_MAP_STRUCT_UNORD)
11856 tree first_node = OMP_CLAUSE_CHAIN (attach);
11857 unsigned HOST_WIDE_INT num_mappings
11858 = tree_to_uhwi (OMP_CLAUSE_SIZE (struct_node));
11859 lowest_addr = OMP_CLAUSE_DECL (first_node);
11860 lowest_addr = build_fold_addr_expr (lowest_addr);
11861 lowest_addr = fold_convert (pointer_sized_int_node, lowest_addr);
11862 tree next_node = OMP_CLAUSE_CHAIN (first_node);
11863 while (num_mappings > 1)
11865 tree tmp = OMP_CLAUSE_DECL (next_node);
11866 tmp = build_fold_addr_expr (tmp);
11867 tmp = fold_convert (pointer_sized_int_node, tmp);
11868 lowest_addr = fold_build2 (MIN_EXPR, pointer_sized_int_node,
11869 lowest_addr, tmp);
11870 next_node = OMP_CLAUSE_CHAIN (next_node);
11871 num_mappings--;
11873 lowest_addr = fold_convert (ptrdiff_type_node, lowest_addr);
11875 else
11877 tree first_node = OMP_CLAUSE_DECL (OMP_CLAUSE_CHAIN (attach));
11878 first_node = build_fold_addr_expr (first_node);
11879 lowest_addr = fold_convert (ptrdiff_type_node, first_node);
11881 tree attach_decl = OMP_CLAUSE_DECL (attach);
11882 attach_decl = fold_convert (ptrdiff_type_node, attach_decl);
11883 OMP_CLAUSE_SIZE (attach)
11884 = fold_build2 (MINUS_EXPR, ptrdiff_type_node, lowest_addr,
11885 attach_decl);
11887 /* Remove GOMP_MAP_ATTACH node from after struct node. */
11888 OMP_CLAUSE_CHAIN (struct_node) = OMP_CLAUSE_CHAIN (attach);
11889 /* ...and re-insert it at the end of our clause list. */
11890 *tail = attach;
11891 OMP_CLAUSE_CHAIN (attach) = NULL_TREE;
11892 tail = &OMP_CLAUSE_CHAIN (attach);
11895 error_out:
11896 if (struct_map_to_clause)
11897 delete struct_map_to_clause;
11899 return success;
11902 /* Scan the OMP clauses in *LIST_P, installing mappings into a new
11903 and previous omp contexts. */
11905 static void
11906 gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
11907 enum omp_region_type region_type,
11908 enum tree_code code)
11910 using namespace omp_addr_tokenizer;
11911 struct gimplify_omp_ctx *ctx, *outer_ctx;
11912 tree c;
11913 tree *orig_list_p = list_p;
11914 int handled_depend_iterators = -1;
11915 int nowait = -1;
11917 ctx = new_omp_context (region_type);
11918 ctx->code = code;
11919 outer_ctx = ctx->outer_context;
11920 if (code == OMP_TARGET)
11922 if (!lang_GNU_Fortran ())
11923 ctx->defaultmap[GDMK_POINTER] = GOVD_MAP | GOVD_MAP_0LEN_ARRAY;
11924 ctx->defaultmap[GDMK_SCALAR] = GOVD_FIRSTPRIVATE;
11925 ctx->defaultmap[GDMK_SCALAR_TARGET] = (lang_GNU_Fortran ()
11926 ? GOVD_MAP : GOVD_FIRSTPRIVATE);
11928 if (!lang_GNU_Fortran ())
11929 switch (code)
11931 case OMP_TARGET:
11932 case OMP_TARGET_DATA:
11933 case OMP_TARGET_ENTER_DATA:
11934 case OMP_TARGET_EXIT_DATA:
11935 case OACC_DECLARE:
11936 case OACC_HOST_DATA:
11937 case OACC_PARALLEL:
11938 case OACC_KERNELS:
11939 ctx->target_firstprivatize_array_bases = true;
11940 default:
11941 break;
11944 vec<omp_mapping_group> *groups = NULL;
11945 hash_map<tree_operand_hash_no_se, omp_mapping_group *> *grpmap = NULL;
11946 unsigned grpnum = 0;
11947 tree *grp_start_p = NULL, grp_end = NULL_TREE;
11949 if (code == OMP_TARGET
11950 || code == OMP_TARGET_DATA
11951 || code == OMP_TARGET_ENTER_DATA
11952 || code == OMP_TARGET_EXIT_DATA
11953 || code == OACC_DATA
11954 || code == OACC_KERNELS
11955 || code == OACC_PARALLEL
11956 || code == OACC_SERIAL
11957 || code == OACC_ENTER_DATA
11958 || code == OACC_EXIT_DATA
11959 || code == OACC_UPDATE
11960 || code == OACC_DECLARE)
11962 groups = omp_gather_mapping_groups (list_p);
11964 if (groups)
11965 grpmap = omp_index_mapping_groups (groups);
11968 while ((c = *list_p) != NULL)
11970 bool remove = false;
11971 bool notice_outer = true;
11972 bool map_descriptor;
11973 const char *check_non_private = NULL;
11974 unsigned int flags;
11975 tree decl;
11976 auto_vec<omp_addr_token *, 10> addr_tokens;
11978 if (grp_end && c == OMP_CLAUSE_CHAIN (grp_end))
11980 grp_start_p = NULL;
11981 grp_end = NULL_TREE;
11984 switch (OMP_CLAUSE_CODE (c))
11986 case OMP_CLAUSE_PRIVATE:
11987 flags = GOVD_PRIVATE | GOVD_EXPLICIT;
11988 if (lang_hooks.decls.omp_private_outer_ref (OMP_CLAUSE_DECL (c)))
11990 flags |= GOVD_PRIVATE_OUTER_REF;
11991 OMP_CLAUSE_PRIVATE_OUTER_REF (c) = 1;
11993 else
11994 notice_outer = false;
11995 goto do_add;
11996 case OMP_CLAUSE_SHARED:
11997 flags = GOVD_SHARED | GOVD_EXPLICIT;
11998 goto do_add;
11999 case OMP_CLAUSE_FIRSTPRIVATE:
12000 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
12001 check_non_private = "firstprivate";
12002 if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c))
12004 gcc_assert (code == OMP_TARGET);
12005 flags |= GOVD_FIRSTPRIVATE_IMPLICIT;
12007 goto do_add;
12008 case OMP_CLAUSE_LASTPRIVATE:
12009 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
12010 switch (code)
12012 case OMP_DISTRIBUTE:
12013 error_at (OMP_CLAUSE_LOCATION (c),
12014 "conditional %<lastprivate%> clause on "
12015 "%qs construct", "distribute");
12016 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
12017 break;
12018 case OMP_TASKLOOP:
12019 error_at (OMP_CLAUSE_LOCATION (c),
12020 "conditional %<lastprivate%> clause on "
12021 "%qs construct", "taskloop");
12022 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
12023 break;
12024 default:
12025 break;
12027 flags = GOVD_LASTPRIVATE | GOVD_SEEN | GOVD_EXPLICIT;
12028 if (code != OMP_LOOP)
12029 check_non_private = "lastprivate";
12030 decl = OMP_CLAUSE_DECL (c);
12031 if (error_operand_p (decl))
12032 goto do_add;
12033 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)
12034 && !lang_hooks.decls.omp_scalar_p (decl, true))
12036 error_at (OMP_CLAUSE_LOCATION (c),
12037 "non-scalar variable %qD in conditional "
12038 "%<lastprivate%> clause", decl);
12039 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
12041 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
12042 flags |= GOVD_LASTPRIVATE_CONDITIONAL;
12043 omp_lastprivate_for_combined_outer_constructs (outer_ctx, decl,
12044 false);
12045 goto do_add;
12046 case OMP_CLAUSE_REDUCTION:
12047 if (OMP_CLAUSE_REDUCTION_TASK (c))
12049 if (region_type == ORT_WORKSHARE || code == OMP_SCOPE)
12051 if (nowait == -1)
12052 nowait = omp_find_clause (*list_p,
12053 OMP_CLAUSE_NOWAIT) != NULL_TREE;
12054 if (nowait
12055 && (outer_ctx == NULL
12056 || outer_ctx->region_type != ORT_COMBINED_PARALLEL))
12058 error_at (OMP_CLAUSE_LOCATION (c),
12059 "%<task%> reduction modifier on a construct "
12060 "with a %<nowait%> clause");
12061 OMP_CLAUSE_REDUCTION_TASK (c) = 0;
12064 else if ((region_type & ORT_PARALLEL) != ORT_PARALLEL)
12066 error_at (OMP_CLAUSE_LOCATION (c),
12067 "invalid %<task%> reduction modifier on construct "
12068 "other than %<parallel%>, %qs, %<sections%> or "
12069 "%<scope%>", lang_GNU_Fortran () ? "do" : "for");
12070 OMP_CLAUSE_REDUCTION_TASK (c) = 0;
12073 if (OMP_CLAUSE_REDUCTION_INSCAN (c))
12074 switch (code)
12076 case OMP_SECTIONS:
12077 error_at (OMP_CLAUSE_LOCATION (c),
12078 "%<inscan%> %<reduction%> clause on "
12079 "%qs construct", "sections");
12080 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
12081 break;
12082 case OMP_PARALLEL:
12083 error_at (OMP_CLAUSE_LOCATION (c),
12084 "%<inscan%> %<reduction%> clause on "
12085 "%qs construct", "parallel");
12086 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
12087 break;
12088 case OMP_TEAMS:
12089 error_at (OMP_CLAUSE_LOCATION (c),
12090 "%<inscan%> %<reduction%> clause on "
12091 "%qs construct", "teams");
12092 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
12093 break;
12094 case OMP_TASKLOOP:
12095 error_at (OMP_CLAUSE_LOCATION (c),
12096 "%<inscan%> %<reduction%> clause on "
12097 "%qs construct", "taskloop");
12098 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
12099 break;
12100 case OMP_SCOPE:
12101 error_at (OMP_CLAUSE_LOCATION (c),
12102 "%<inscan%> %<reduction%> clause on "
12103 "%qs construct", "scope");
12104 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
12105 break;
12106 default:
12107 break;
12109 /* FALLTHRU */
12110 case OMP_CLAUSE_IN_REDUCTION:
12111 case OMP_CLAUSE_TASK_REDUCTION:
12112 flags = GOVD_REDUCTION | GOVD_SEEN | GOVD_EXPLICIT;
12113 /* OpenACC permits reductions on private variables. */
12114 if (!(region_type & ORT_ACC)
12115 /* taskgroup is actually not a worksharing region. */
12116 && code != OMP_TASKGROUP)
12117 check_non_private = omp_clause_code_name[OMP_CLAUSE_CODE (c)];
12118 decl = OMP_CLAUSE_DECL (c);
12119 if (TREE_CODE (decl) == MEM_REF)
12121 tree type = TREE_TYPE (decl);
12122 bool saved_into_ssa = gimplify_ctxp->into_ssa;
12123 gimplify_ctxp->into_ssa = false;
12124 if (gimplify_expr (&TYPE_MAX_VALUE (TYPE_DOMAIN (type)), pre_p,
12125 NULL, is_gimple_val, fb_rvalue, false)
12126 == GS_ERROR)
12128 gimplify_ctxp->into_ssa = saved_into_ssa;
12129 remove = true;
12130 break;
12132 gimplify_ctxp->into_ssa = saved_into_ssa;
12133 tree v = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
12134 if (DECL_P (v))
12136 omp_firstprivatize_variable (ctx, v);
12137 omp_notice_variable (ctx, v, true);
12139 decl = TREE_OPERAND (decl, 0);
12140 if (TREE_CODE (decl) == POINTER_PLUS_EXPR)
12142 gimplify_ctxp->into_ssa = false;
12143 if (gimplify_expr (&TREE_OPERAND (decl, 1), pre_p,
12144 NULL, is_gimple_val, fb_rvalue, false)
12145 == GS_ERROR)
12147 gimplify_ctxp->into_ssa = saved_into_ssa;
12148 remove = true;
12149 break;
12151 gimplify_ctxp->into_ssa = saved_into_ssa;
12152 v = TREE_OPERAND (decl, 1);
12153 if (DECL_P (v))
12155 omp_firstprivatize_variable (ctx, v);
12156 omp_notice_variable (ctx, v, true);
12158 decl = TREE_OPERAND (decl, 0);
12160 if (TREE_CODE (decl) == ADDR_EXPR
12161 || TREE_CODE (decl) == INDIRECT_REF)
12162 decl = TREE_OPERAND (decl, 0);
12164 goto do_add_decl;
12165 case OMP_CLAUSE_LINEAR:
12166 if (gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c), pre_p, NULL,
12167 is_gimple_val, fb_rvalue) == GS_ERROR)
12169 remove = true;
12170 break;
12172 else
12174 if (code == OMP_SIMD
12175 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
12177 struct gimplify_omp_ctx *octx = outer_ctx;
12178 if (octx
12179 && octx->region_type == ORT_WORKSHARE
12180 && octx->combined_loop
12181 && !octx->distribute)
12183 if (octx->outer_context
12184 && (octx->outer_context->region_type
12185 == ORT_COMBINED_PARALLEL))
12186 octx = octx->outer_context->outer_context;
12187 else
12188 octx = octx->outer_context;
12190 if (octx
12191 && octx->region_type == ORT_WORKSHARE
12192 && octx->combined_loop
12193 && octx->distribute)
12195 error_at (OMP_CLAUSE_LOCATION (c),
12196 "%<linear%> clause for variable other than "
12197 "loop iterator specified on construct "
12198 "combined with %<distribute%>");
12199 remove = true;
12200 break;
12203 /* For combined #pragma omp parallel for simd, need to put
12204 lastprivate and perhaps firstprivate too on the
12205 parallel. Similarly for #pragma omp for simd. */
12206 struct gimplify_omp_ctx *octx = outer_ctx;
12207 bool taskloop_seen = false;
12208 decl = NULL_TREE;
12211 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
12212 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
12213 break;
12214 decl = OMP_CLAUSE_DECL (c);
12215 if (error_operand_p (decl))
12217 decl = NULL_TREE;
12218 break;
12220 flags = GOVD_SEEN;
12221 if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c))
12222 flags |= GOVD_FIRSTPRIVATE;
12223 if (!OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
12224 flags |= GOVD_LASTPRIVATE;
12225 if (octx
12226 && octx->region_type == ORT_WORKSHARE
12227 && octx->combined_loop)
12229 if (octx->outer_context
12230 && (octx->outer_context->region_type
12231 == ORT_COMBINED_PARALLEL))
12232 octx = octx->outer_context;
12233 else if (omp_check_private (octx, decl, false))
12234 break;
12236 else if (octx
12237 && (octx->region_type & ORT_TASK) != 0
12238 && octx->combined_loop)
12239 taskloop_seen = true;
12240 else if (octx
12241 && octx->region_type == ORT_COMBINED_PARALLEL
12242 && ((ctx->region_type == ORT_WORKSHARE
12243 && octx == outer_ctx)
12244 || taskloop_seen))
12245 flags = GOVD_SEEN | GOVD_SHARED;
12246 else if (octx
12247 && ((octx->region_type & ORT_COMBINED_TEAMS)
12248 == ORT_COMBINED_TEAMS))
12249 flags = GOVD_SEEN | GOVD_SHARED;
12250 else if (octx
12251 && octx->region_type == ORT_COMBINED_TARGET)
12253 if (flags & GOVD_LASTPRIVATE)
12254 flags = GOVD_SEEN | GOVD_MAP;
12256 else
12257 break;
12258 splay_tree_node on
12259 = splay_tree_lookup (octx->variables,
12260 (splay_tree_key) decl);
12261 if (on && (on->value & GOVD_DATA_SHARE_CLASS) != 0)
12263 octx = NULL;
12264 break;
12266 omp_add_variable (octx, decl, flags);
12267 if (octx->outer_context == NULL)
12268 break;
12269 octx = octx->outer_context;
12271 while (1);
12272 if (octx
12273 && decl
12274 && (!OMP_CLAUSE_LINEAR_NO_COPYIN (c)
12275 || !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
12276 omp_notice_variable (octx, decl, true);
12278 flags = GOVD_LINEAR | GOVD_EXPLICIT;
12279 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
12280 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
12282 notice_outer = false;
12283 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
12285 goto do_add;
12287 case OMP_CLAUSE_MAP:
12288 if (!grp_start_p)
12290 grp_start_p = list_p;
12291 grp_end = (*groups)[grpnum].grp_end;
12292 grpnum++;
12294 decl = OMP_CLAUSE_DECL (c);
12296 if (error_operand_p (decl))
12298 remove = true;
12299 break;
12302 if (!omp_parse_expr (addr_tokens, decl))
12304 remove = true;
12305 break;
12308 if (remove)
12309 break;
12310 if (DECL_P (decl) && outer_ctx && (region_type & ORT_ACC))
12312 struct gimplify_omp_ctx *octx;
12313 for (octx = outer_ctx; octx; octx = octx->outer_context)
12315 if (octx->region_type != ORT_ACC_HOST_DATA)
12316 break;
12317 splay_tree_node n2
12318 = splay_tree_lookup (octx->variables,
12319 (splay_tree_key) decl);
12320 if (n2)
12321 error_at (OMP_CLAUSE_LOCATION (c), "variable %qE "
12322 "declared in enclosing %<host_data%> region",
12323 DECL_NAME (decl));
12327 map_descriptor = false;
12329 /* This condition checks if we're mapping an array descriptor that
12330 isn't inside a derived type -- these have special handling, and
12331 are not handled as structs in omp_build_struct_sibling_lists.
12332 See that function for further details. */
12333 if (*grp_start_p != grp_end
12334 && OMP_CLAUSE_CHAIN (*grp_start_p)
12335 && OMP_CLAUSE_CHAIN (*grp_start_p) != grp_end)
12337 tree grp_mid = OMP_CLAUSE_CHAIN (*grp_start_p);
12338 if (omp_map_clause_descriptor_p (grp_mid)
12339 && DECL_P (OMP_CLAUSE_DECL (grp_mid)))
12340 map_descriptor = true;
12342 else if (OMP_CLAUSE_CODE (grp_end) == OMP_CLAUSE_MAP
12343 && (OMP_CLAUSE_MAP_KIND (grp_end) == GOMP_MAP_RELEASE
12344 || OMP_CLAUSE_MAP_KIND (grp_end) == GOMP_MAP_DELETE)
12345 && OMP_CLAUSE_RELEASE_DESCRIPTOR (grp_end))
12346 map_descriptor = true;
12348 /* Adding the decl for a struct access: we haven't created
12349 GOMP_MAP_STRUCT nodes yet, so this statement needs to predict
12350 whether they will be created in gimplify_adjust_omp_clauses.
12351 NOTE: Technically we should probably look through DECL_VALUE_EXPR
12352 here because something that looks like a DECL_P may actually be a
12353 struct access, e.g. variables in a lambda closure
12354 (__closure->__foo) or class members (this->foo). Currently in both
12355 those cases we map the whole of the containing object (directly in
12356 the C++ FE) though, so struct nodes are not created. */
12357 if (c == grp_end
12358 && addr_tokens[0]->type == STRUCTURE_BASE
12359 && addr_tokens[0]->u.structure_base_kind == BASE_DECL
12360 && !map_descriptor)
12362 gcc_assert (addr_tokens[1]->type == ACCESS_METHOD);
12363 /* If we got to this struct via a chain of pointers, maybe we
12364 want to map it implicitly instead. */
12365 if (omp_access_chain_p (addr_tokens, 1))
12366 break;
12367 omp_mapping_group *wholestruct;
12368 if (!(region_type & ORT_ACC)
12369 && omp_mapped_by_containing_struct (grpmap,
12370 OMP_CLAUSE_DECL (c),
12371 &wholestruct))
12372 break;
12373 decl = addr_tokens[1]->expr;
12374 if (splay_tree_lookup (ctx->variables, (splay_tree_key) decl))
12375 break;
12376 /* Standalone attach or detach clauses for a struct element
12377 should not inhibit implicit mapping of the whole struct. */
12378 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
12379 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH)
12380 break;
12381 flags = GOVD_MAP | GOVD_EXPLICIT;
12383 gcc_assert (addr_tokens[1]->u.access_kind != ACCESS_DIRECT
12384 || TREE_ADDRESSABLE (decl));
12385 goto do_add_decl;
12388 if (!DECL_P (decl))
12390 tree d = decl, *pd;
12391 if (TREE_CODE (d) == ARRAY_REF)
12393 while (TREE_CODE (d) == ARRAY_REF)
12394 d = TREE_OPERAND (d, 0);
12395 if (TREE_CODE (d) == COMPONENT_REF
12396 && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE)
12397 decl = d;
12399 pd = &OMP_CLAUSE_DECL (c);
12400 if (d == decl
12401 && TREE_CODE (decl) == INDIRECT_REF
12402 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
12403 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
12404 == REFERENCE_TYPE)
12405 && (OMP_CLAUSE_MAP_KIND (c)
12406 != GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION))
12408 pd = &TREE_OPERAND (decl, 0);
12409 decl = TREE_OPERAND (decl, 0);
12412 if (addr_tokens[0]->type == STRUCTURE_BASE
12413 && addr_tokens[0]->u.structure_base_kind == BASE_DECL
12414 && addr_tokens[1]->type == ACCESS_METHOD
12415 && (addr_tokens[1]->u.access_kind == ACCESS_POINTER
12416 || (addr_tokens[1]->u.access_kind
12417 == ACCESS_POINTER_OFFSET))
12418 && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)))
12420 tree base = addr_tokens[1]->expr;
12421 splay_tree_node n
12422 = splay_tree_lookup (ctx->variables,
12423 (splay_tree_key) base);
12424 n->value |= GOVD_SEEN;
12427 if (code == OMP_TARGET && OMP_CLAUSE_MAP_IN_REDUCTION (c))
12429 /* Don't gimplify *pd fully at this point, as the base
12430 will need to be adjusted during omp lowering. */
12431 auto_vec<tree, 10> expr_stack;
12432 tree *p = pd;
12433 while (handled_component_p (*p)
12434 || TREE_CODE (*p) == INDIRECT_REF
12435 || TREE_CODE (*p) == ADDR_EXPR
12436 || TREE_CODE (*p) == MEM_REF
12437 || TREE_CODE (*p) == NON_LVALUE_EXPR)
12439 expr_stack.safe_push (*p);
12440 p = &TREE_OPERAND (*p, 0);
12442 for (int i = expr_stack.length () - 1; i >= 0; i--)
12444 tree t = expr_stack[i];
12445 if (TREE_CODE (t) == ARRAY_REF
12446 || TREE_CODE (t) == ARRAY_RANGE_REF)
12448 if (TREE_OPERAND (t, 2) == NULL_TREE)
12450 tree low = unshare_expr (array_ref_low_bound (t));
12451 if (!is_gimple_min_invariant (low))
12453 TREE_OPERAND (t, 2) = low;
12454 if (gimplify_expr (&TREE_OPERAND (t, 2),
12455 pre_p, NULL,
12456 is_gimple_reg,
12457 fb_rvalue) == GS_ERROR)
12458 remove = true;
12461 else if (gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
12462 NULL, is_gimple_reg,
12463 fb_rvalue) == GS_ERROR)
12464 remove = true;
12465 if (TREE_OPERAND (t, 3) == NULL_TREE)
12467 tree elmt_size = array_ref_element_size (t);
12468 if (!is_gimple_min_invariant (elmt_size))
12470 elmt_size = unshare_expr (elmt_size);
12471 tree elmt_type
12472 = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t,
12473 0)));
12474 tree factor
12475 = size_int (TYPE_ALIGN_UNIT (elmt_type));
12476 elmt_size
12477 = size_binop (EXACT_DIV_EXPR, elmt_size,
12478 factor);
12479 TREE_OPERAND (t, 3) = elmt_size;
12480 if (gimplify_expr (&TREE_OPERAND (t, 3),
12481 pre_p, NULL,
12482 is_gimple_reg,
12483 fb_rvalue) == GS_ERROR)
12484 remove = true;
12487 else if (gimplify_expr (&TREE_OPERAND (t, 3), pre_p,
12488 NULL, is_gimple_reg,
12489 fb_rvalue) == GS_ERROR)
12490 remove = true;
12492 else if (TREE_CODE (t) == COMPONENT_REF)
12494 if (TREE_OPERAND (t, 2) == NULL_TREE)
12496 tree offset = component_ref_field_offset (t);
12497 if (!is_gimple_min_invariant (offset))
12499 offset = unshare_expr (offset);
12500 tree field = TREE_OPERAND (t, 1);
12501 tree factor
12502 = size_int (DECL_OFFSET_ALIGN (field)
12503 / BITS_PER_UNIT);
12504 offset = size_binop (EXACT_DIV_EXPR, offset,
12505 factor);
12506 TREE_OPERAND (t, 2) = offset;
12507 if (gimplify_expr (&TREE_OPERAND (t, 2),
12508 pre_p, NULL,
12509 is_gimple_reg,
12510 fb_rvalue) == GS_ERROR)
12511 remove = true;
12514 else if (gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
12515 NULL, is_gimple_reg,
12516 fb_rvalue) == GS_ERROR)
12517 remove = true;
12520 for (; expr_stack.length () > 0; )
12522 tree t = expr_stack.pop ();
12524 if (TREE_CODE (t) == ARRAY_REF
12525 || TREE_CODE (t) == ARRAY_RANGE_REF)
12527 if (!is_gimple_min_invariant (TREE_OPERAND (t, 1))
12528 && gimplify_expr (&TREE_OPERAND (t, 1), pre_p,
12529 NULL, is_gimple_val,
12530 fb_rvalue) == GS_ERROR)
12531 remove = true;
12535 break;
12538 if ((code == OMP_TARGET
12539 || code == OMP_TARGET_DATA
12540 || code == OMP_TARGET_ENTER_DATA
12541 || code == OMP_TARGET_EXIT_DATA)
12542 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
12544 /* If we have attach/detach but the decl we have is a pointer to
12545 pointer, we're probably mapping the "base level" array
12546 implicitly. Make sure we don't add the decl as if we mapped
12547 it explicitly. That is,
12549 int **arr;
12550 [...]
12551 #pragma omp target map(arr[a][b:c])
12553 should *not* map "arr" explicitly. That way we get a
12554 zero-length "alloc" mapping for it, and assuming it's been
12555 mapped by some previous directive, etc., things work as they
12556 should. */
12558 tree basetype = TREE_TYPE (addr_tokens[0]->expr);
12560 if (TREE_CODE (basetype) == REFERENCE_TYPE)
12561 basetype = TREE_TYPE (basetype);
12563 if (code == OMP_TARGET
12564 && addr_tokens[0]->type == ARRAY_BASE
12565 && addr_tokens[0]->u.structure_base_kind == BASE_DECL
12566 && TREE_CODE (basetype) == POINTER_TYPE
12567 && TREE_CODE (TREE_TYPE (basetype)) == POINTER_TYPE)
12568 break;
12571 flags = GOVD_MAP | GOVD_EXPLICIT;
12572 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TO
12573 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TOFROM
12574 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_PRESENT_TO
12575 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_PRESENT_TOFROM)
12576 flags |= GOVD_MAP_ALWAYS_TO;
12578 goto do_add;
12580 case OMP_CLAUSE_AFFINITY:
12581 gimplify_omp_affinity (list_p, pre_p);
12582 remove = true;
12583 break;
12584 case OMP_CLAUSE_DOACROSS:
12585 if (OMP_CLAUSE_DOACROSS_KIND (c) == OMP_CLAUSE_DOACROSS_SINK)
12587 tree deps = OMP_CLAUSE_DECL (c);
12588 while (deps && TREE_CODE (deps) == TREE_LIST)
12590 if (TREE_CODE (TREE_PURPOSE (deps)) == TRUNC_DIV_EXPR
12591 && DECL_P (TREE_OPERAND (TREE_PURPOSE (deps), 1)))
12592 gimplify_expr (&TREE_OPERAND (TREE_PURPOSE (deps), 1),
12593 pre_p, NULL, is_gimple_val, fb_rvalue);
12594 deps = TREE_CHAIN (deps);
12597 else
12598 gcc_assert (OMP_CLAUSE_DOACROSS_KIND (c)
12599 == OMP_CLAUSE_DOACROSS_SOURCE);
12600 break;
12601 case OMP_CLAUSE_DEPEND:
12602 if (handled_depend_iterators == -1)
12603 handled_depend_iterators = gimplify_omp_depend (list_p, pre_p);
12604 if (handled_depend_iterators)
12606 if (handled_depend_iterators == 2)
12607 remove = true;
12608 break;
12610 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
12612 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
12613 NULL, is_gimple_val, fb_rvalue);
12614 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
12616 if (error_operand_p (OMP_CLAUSE_DECL (c)))
12618 remove = true;
12619 break;
12621 if (OMP_CLAUSE_DECL (c) != null_pointer_node)
12623 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
12624 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
12625 is_gimple_val, fb_rvalue) == GS_ERROR)
12627 remove = true;
12628 break;
12631 if (code == OMP_TASK)
12632 ctx->has_depend = true;
12633 break;
12635 case OMP_CLAUSE_TO:
12636 case OMP_CLAUSE_FROM:
12637 case OMP_CLAUSE__CACHE_:
12638 decl = OMP_CLAUSE_DECL (c);
12639 if (error_operand_p (decl))
12641 remove = true;
12642 break;
12644 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
12645 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
12646 : TYPE_SIZE_UNIT (TREE_TYPE (decl));
12647 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
12648 NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
12650 remove = true;
12651 break;
12653 if (!DECL_P (decl))
12655 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p,
12656 NULL, is_gimple_lvalue, fb_lvalue)
12657 == GS_ERROR)
12659 remove = true;
12660 break;
12662 break;
12664 goto do_notice;
12666 case OMP_CLAUSE_USE_DEVICE_PTR:
12667 case OMP_CLAUSE_USE_DEVICE_ADDR:
12668 flags = GOVD_EXPLICIT;
12669 goto do_add;
12671 case OMP_CLAUSE_HAS_DEVICE_ADDR:
12672 decl = OMP_CLAUSE_DECL (c);
12673 while (TREE_CODE (decl) == INDIRECT_REF
12674 || TREE_CODE (decl) == ARRAY_REF)
12675 decl = TREE_OPERAND (decl, 0);
12676 flags = GOVD_EXPLICIT;
12677 goto do_add_decl;
12679 case OMP_CLAUSE_IS_DEVICE_PTR:
12680 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
12681 goto do_add;
12683 do_add:
12684 decl = OMP_CLAUSE_DECL (c);
12685 do_add_decl:
12686 if (error_operand_p (decl))
12688 remove = true;
12689 break;
12691 if (DECL_NAME (decl) == NULL_TREE && (flags & GOVD_SHARED) == 0)
12693 tree t = omp_member_access_dummy_var (decl);
12694 if (t)
12696 tree v = DECL_VALUE_EXPR (decl);
12697 DECL_NAME (decl) = DECL_NAME (TREE_OPERAND (v, 1));
12698 if (outer_ctx)
12699 omp_notice_variable (outer_ctx, t, true);
12702 if (code == OACC_DATA
12703 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
12704 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
12705 flags |= GOVD_MAP_0LEN_ARRAY;
12706 omp_add_variable (ctx, decl, flags);
12707 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
12708 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
12709 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
12710 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
12712 struct gimplify_omp_ctx *pctx
12713 = code == OMP_TARGET ? outer_ctx : ctx;
12714 if (pctx)
12715 omp_add_variable (pctx, OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
12716 GOVD_LOCAL | GOVD_SEEN);
12717 if (pctx
12718 && OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
12719 && walk_tree (&OMP_CLAUSE_REDUCTION_INIT (c),
12720 find_decl_expr,
12721 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
12722 NULL) == NULL_TREE)
12723 omp_add_variable (pctx,
12724 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
12725 GOVD_LOCAL | GOVD_SEEN);
12726 gimplify_omp_ctxp = pctx;
12727 push_gimplify_context ();
12729 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
12730 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
12732 gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c),
12733 &OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c));
12734 pop_gimplify_context
12735 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c)));
12736 push_gimplify_context ();
12737 gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c),
12738 &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
12739 pop_gimplify_context
12740 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c)));
12741 OMP_CLAUSE_REDUCTION_INIT (c) = NULL_TREE;
12742 OMP_CLAUSE_REDUCTION_MERGE (c) = NULL_TREE;
12744 gimplify_omp_ctxp = outer_ctx;
12746 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
12747 && OMP_CLAUSE_LASTPRIVATE_STMT (c))
12749 gimplify_omp_ctxp = ctx;
12750 push_gimplify_context ();
12751 if (TREE_CODE (OMP_CLAUSE_LASTPRIVATE_STMT (c)) != BIND_EXPR)
12753 tree bind = build3 (BIND_EXPR, void_type_node, NULL,
12754 NULL, NULL);
12755 TREE_SIDE_EFFECTS (bind) = 1;
12756 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LASTPRIVATE_STMT (c);
12757 OMP_CLAUSE_LASTPRIVATE_STMT (c) = bind;
12759 gimplify_and_add (OMP_CLAUSE_LASTPRIVATE_STMT (c),
12760 &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
12761 pop_gimplify_context
12762 (gimple_seq_first_stmt (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c)));
12763 OMP_CLAUSE_LASTPRIVATE_STMT (c) = NULL_TREE;
12765 gimplify_omp_ctxp = outer_ctx;
12767 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
12768 && OMP_CLAUSE_LINEAR_STMT (c))
12770 gimplify_omp_ctxp = ctx;
12771 push_gimplify_context ();
12772 if (TREE_CODE (OMP_CLAUSE_LINEAR_STMT (c)) != BIND_EXPR)
12774 tree bind = build3 (BIND_EXPR, void_type_node, NULL,
12775 NULL, NULL);
12776 TREE_SIDE_EFFECTS (bind) = 1;
12777 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LINEAR_STMT (c);
12778 OMP_CLAUSE_LINEAR_STMT (c) = bind;
12780 gimplify_and_add (OMP_CLAUSE_LINEAR_STMT (c),
12781 &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c));
12782 pop_gimplify_context
12783 (gimple_seq_first_stmt (OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c)));
12784 OMP_CLAUSE_LINEAR_STMT (c) = NULL_TREE;
12786 gimplify_omp_ctxp = outer_ctx;
12788 if (notice_outer)
12789 goto do_notice;
12790 break;
12792 case OMP_CLAUSE_COPYIN:
12793 case OMP_CLAUSE_COPYPRIVATE:
12794 decl = OMP_CLAUSE_DECL (c);
12795 if (error_operand_p (decl))
12797 remove = true;
12798 break;
12800 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_COPYPRIVATE
12801 && !remove
12802 && !omp_check_private (ctx, decl, true))
12804 remove = true;
12805 if (is_global_var (decl))
12807 if (DECL_THREAD_LOCAL_P (decl))
12808 remove = false;
12809 else if (DECL_HAS_VALUE_EXPR_P (decl))
12811 tree value = get_base_address (DECL_VALUE_EXPR (decl));
12813 if (value
12814 && DECL_P (value)
12815 && DECL_THREAD_LOCAL_P (value))
12816 remove = false;
12819 if (remove)
12820 error_at (OMP_CLAUSE_LOCATION (c),
12821 "copyprivate variable %qE is not threadprivate"
12822 " or private in outer context", DECL_NAME (decl));
12824 do_notice:
12825 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
12826 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
12827 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
12828 && outer_ctx
12829 && ((region_type & ORT_TASKLOOP) == ORT_TASKLOOP
12830 || (region_type == ORT_WORKSHARE
12831 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
12832 && (OMP_CLAUSE_REDUCTION_INSCAN (c)
12833 || code == OMP_LOOP)))
12834 && (outer_ctx->region_type == ORT_COMBINED_PARALLEL
12835 || (code == OMP_LOOP
12836 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
12837 && ((outer_ctx->region_type & ORT_COMBINED_TEAMS)
12838 == ORT_COMBINED_TEAMS))))
12840 splay_tree_node on
12841 = splay_tree_lookup (outer_ctx->variables,
12842 (splay_tree_key)decl);
12843 if (on == NULL || (on->value & GOVD_DATA_SHARE_CLASS) == 0)
12845 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
12846 && TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
12847 && (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
12848 || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
12849 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
12850 == POINTER_TYPE))))
12851 omp_firstprivatize_variable (outer_ctx, decl);
12852 else
12854 omp_add_variable (outer_ctx, decl,
12855 GOVD_SEEN | GOVD_SHARED);
12856 if (outer_ctx->outer_context)
12857 omp_notice_variable (outer_ctx->outer_context, decl,
12858 true);
12862 if (outer_ctx)
12863 omp_notice_variable (outer_ctx, decl, true);
12864 if (check_non_private
12865 && (region_type == ORT_WORKSHARE || code == OMP_SCOPE)
12866 && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
12867 || decl == OMP_CLAUSE_DECL (c)
12868 || (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
12869 && (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
12870 == ADDR_EXPR
12871 || (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
12872 == POINTER_PLUS_EXPR
12873 && (TREE_CODE (TREE_OPERAND (TREE_OPERAND
12874 (OMP_CLAUSE_DECL (c), 0), 0))
12875 == ADDR_EXPR)))))
12876 && omp_check_private (ctx, decl, false))
12878 error ("%s variable %qE is private in outer context",
12879 check_non_private, DECL_NAME (decl));
12880 remove = true;
12882 break;
12884 case OMP_CLAUSE_DETACH:
12885 flags = GOVD_FIRSTPRIVATE | GOVD_SEEN;
12886 goto do_add;
12888 case OMP_CLAUSE_IF:
12889 if (OMP_CLAUSE_IF_MODIFIER (c) != ERROR_MARK
12890 && OMP_CLAUSE_IF_MODIFIER (c) != code)
12892 const char *p[2];
12893 for (int i = 0; i < 2; i++)
12894 switch (i ? OMP_CLAUSE_IF_MODIFIER (c) : code)
12896 case VOID_CST: p[i] = "cancel"; break;
12897 case OMP_PARALLEL: p[i] = "parallel"; break;
12898 case OMP_SIMD: p[i] = "simd"; break;
12899 case OMP_TASK: p[i] = "task"; break;
12900 case OMP_TASKLOOP: p[i] = "taskloop"; break;
12901 case OMP_TARGET_DATA: p[i] = "target data"; break;
12902 case OMP_TARGET: p[i] = "target"; break;
12903 case OMP_TARGET_UPDATE: p[i] = "target update"; break;
12904 case OMP_TARGET_ENTER_DATA:
12905 p[i] = "target enter data"; break;
12906 case OMP_TARGET_EXIT_DATA: p[i] = "target exit data"; break;
12907 default: gcc_unreachable ();
12909 error_at (OMP_CLAUSE_LOCATION (c),
12910 "expected %qs %<if%> clause modifier rather than %qs",
12911 p[0], p[1]);
12912 remove = true;
12914 /* Fall through. */
12916 case OMP_CLAUSE_SELF:
12917 case OMP_CLAUSE_FINAL:
12918 OMP_CLAUSE_OPERAND (c, 0)
12919 = gimple_boolify (OMP_CLAUSE_OPERAND (c, 0));
12920 /* Fall through. */
12922 case OMP_CLAUSE_NUM_TEAMS:
12923 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
12924 && OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
12925 && !is_gimple_min_invariant (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)))
12927 if (error_operand_p (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)))
12929 remove = true;
12930 break;
12932 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
12933 = get_initialized_tmp_var (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c),
12934 pre_p, NULL, true);
12936 /* Fall through. */
12938 case OMP_CLAUSE_SCHEDULE:
12939 case OMP_CLAUSE_NUM_THREADS:
12940 case OMP_CLAUSE_THREAD_LIMIT:
12941 case OMP_CLAUSE_DIST_SCHEDULE:
12942 case OMP_CLAUSE_DEVICE:
12943 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE
12944 && OMP_CLAUSE_DEVICE_ANCESTOR (c))
12946 if (code != OMP_TARGET)
12948 error_at (OMP_CLAUSE_LOCATION (c),
12949 "%<device%> clause with %<ancestor%> is only "
12950 "allowed on %<target%> construct");
12951 remove = true;
12952 break;
12955 tree clauses = *orig_list_p;
12956 for (; clauses ; clauses = OMP_CLAUSE_CHAIN (clauses))
12957 if (OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_DEVICE
12958 && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_FIRSTPRIVATE
12959 && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_PRIVATE
12960 && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_DEFAULTMAP
12961 && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_MAP
12964 error_at (OMP_CLAUSE_LOCATION (c),
12965 "with %<ancestor%>, only the %<device%>, "
12966 "%<firstprivate%>, %<private%>, %<defaultmap%>, "
12967 "and %<map%> clauses may appear on the "
12968 "construct");
12969 remove = true;
12970 break;
12973 /* Fall through. */
12975 case OMP_CLAUSE_PRIORITY:
12976 case OMP_CLAUSE_GRAINSIZE:
12977 case OMP_CLAUSE_NUM_TASKS:
12978 case OMP_CLAUSE_FILTER:
12979 case OMP_CLAUSE_HINT:
12980 case OMP_CLAUSE_ASYNC:
12981 case OMP_CLAUSE_WAIT:
12982 case OMP_CLAUSE_NUM_GANGS:
12983 case OMP_CLAUSE_NUM_WORKERS:
12984 case OMP_CLAUSE_VECTOR_LENGTH:
12985 case OMP_CLAUSE_WORKER:
12986 case OMP_CLAUSE_VECTOR:
12987 if (OMP_CLAUSE_OPERAND (c, 0)
12988 && !is_gimple_min_invariant (OMP_CLAUSE_OPERAND (c, 0)))
12990 if (error_operand_p (OMP_CLAUSE_OPERAND (c, 0)))
12992 remove = true;
12993 break;
12995 /* All these clauses care about value, not a particular decl,
12996 so try to force it into a SSA_NAME or fresh temporary. */
12997 OMP_CLAUSE_OPERAND (c, 0)
12998 = get_initialized_tmp_var (OMP_CLAUSE_OPERAND (c, 0),
12999 pre_p, NULL, true);
13001 break;
13003 case OMP_CLAUSE_GANG:
13004 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
13005 is_gimple_val, fb_rvalue) == GS_ERROR)
13006 remove = true;
13007 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 1), pre_p, NULL,
13008 is_gimple_val, fb_rvalue) == GS_ERROR)
13009 remove = true;
13010 break;
13012 case OMP_CLAUSE_NOWAIT:
13013 nowait = 1;
13014 break;
13016 case OMP_CLAUSE_ORDERED:
13017 case OMP_CLAUSE_UNTIED:
13018 case OMP_CLAUSE_COLLAPSE:
13019 case OMP_CLAUSE_TILE:
13020 case OMP_CLAUSE_AUTO:
13021 case OMP_CLAUSE_SEQ:
13022 case OMP_CLAUSE_INDEPENDENT:
13023 case OMP_CLAUSE_MERGEABLE:
13024 case OMP_CLAUSE_PROC_BIND:
13025 case OMP_CLAUSE_SAFELEN:
13026 case OMP_CLAUSE_SIMDLEN:
13027 case OMP_CLAUSE_NOGROUP:
13028 case OMP_CLAUSE_THREADS:
13029 case OMP_CLAUSE_SIMD:
13030 case OMP_CLAUSE_BIND:
13031 case OMP_CLAUSE_IF_PRESENT:
13032 case OMP_CLAUSE_FINALIZE:
13033 break;
13035 case OMP_CLAUSE_ORDER:
13036 ctx->order_concurrent = true;
13037 break;
13039 case OMP_CLAUSE_DEFAULTMAP:
13040 enum gimplify_defaultmap_kind gdmkmin, gdmkmax;
13041 switch (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c))
13043 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
13044 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL:
13045 gdmkmin = GDMK_SCALAR;
13046 gdmkmax = GDMK_POINTER;
13047 break;
13048 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
13049 gdmkmin = GDMK_SCALAR;
13050 gdmkmax = GDMK_SCALAR_TARGET;
13051 break;
13052 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
13053 gdmkmin = gdmkmax = GDMK_AGGREGATE;
13054 break;
13055 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALLOCATABLE:
13056 gdmkmin = gdmkmax = GDMK_ALLOCATABLE;
13057 break;
13058 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
13059 gdmkmin = gdmkmax = GDMK_POINTER;
13060 break;
13061 default:
13062 gcc_unreachable ();
13064 for (int gdmk = gdmkmin; gdmk <= gdmkmax; gdmk++)
13065 switch (OMP_CLAUSE_DEFAULTMAP_BEHAVIOR (c))
13067 case OMP_CLAUSE_DEFAULTMAP_ALLOC:
13068 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_ALLOC_ONLY;
13069 break;
13070 case OMP_CLAUSE_DEFAULTMAP_TO:
13071 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_TO_ONLY;
13072 break;
13073 case OMP_CLAUSE_DEFAULTMAP_FROM:
13074 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_FROM_ONLY;
13075 break;
13076 case OMP_CLAUSE_DEFAULTMAP_TOFROM:
13077 ctx->defaultmap[gdmk] = GOVD_MAP;
13078 break;
13079 case OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE:
13080 ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE;
13081 break;
13082 case OMP_CLAUSE_DEFAULTMAP_NONE:
13083 ctx->defaultmap[gdmk] = 0;
13084 break;
13085 case OMP_CLAUSE_DEFAULTMAP_PRESENT:
13086 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
13087 break;
13088 case OMP_CLAUSE_DEFAULTMAP_DEFAULT:
13089 switch (gdmk)
13091 case GDMK_SCALAR:
13092 ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE;
13093 break;
13094 case GDMK_SCALAR_TARGET:
13095 ctx->defaultmap[gdmk] = (lang_GNU_Fortran ()
13096 ? GOVD_MAP : GOVD_FIRSTPRIVATE);
13097 break;
13098 case GDMK_AGGREGATE:
13099 case GDMK_ALLOCATABLE:
13100 ctx->defaultmap[gdmk] = GOVD_MAP;
13101 break;
13102 case GDMK_POINTER:
13103 ctx->defaultmap[gdmk] = GOVD_MAP;
13104 if (!lang_GNU_Fortran ())
13105 ctx->defaultmap[gdmk] |= GOVD_MAP_0LEN_ARRAY;
13106 break;
13107 default:
13108 gcc_unreachable ();
13110 break;
13111 default:
13112 gcc_unreachable ();
13114 break;
13116 case OMP_CLAUSE_ALIGNED:
13117 decl = OMP_CLAUSE_DECL (c);
13118 if (error_operand_p (decl))
13120 remove = true;
13121 break;
13123 if (gimplify_expr (&OMP_CLAUSE_ALIGNED_ALIGNMENT (c), pre_p, NULL,
13124 is_gimple_val, fb_rvalue) == GS_ERROR)
13126 remove = true;
13127 break;
13129 if (!is_global_var (decl)
13130 && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
13131 omp_add_variable (ctx, decl, GOVD_ALIGNED);
13132 break;
13134 case OMP_CLAUSE_NONTEMPORAL:
13135 decl = OMP_CLAUSE_DECL (c);
13136 if (error_operand_p (decl))
13138 remove = true;
13139 break;
13141 omp_add_variable (ctx, decl, GOVD_NONTEMPORAL);
13142 break;
13144 case OMP_CLAUSE_ALLOCATE:
13145 decl = OMP_CLAUSE_DECL (c);
13146 if (error_operand_p (decl))
13148 remove = true;
13149 break;
13151 if (gimplify_expr (&OMP_CLAUSE_ALLOCATE_ALLOCATOR (c), pre_p, NULL,
13152 is_gimple_val, fb_rvalue) == GS_ERROR)
13154 remove = true;
13155 break;
13157 else if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) == NULL_TREE
13158 || (TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c))
13159 == INTEGER_CST))
13161 else if (code == OMP_TASKLOOP
13162 || !DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)))
13163 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
13164 = get_initialized_tmp_var (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
13165 pre_p, NULL, false);
13166 break;
13168 case OMP_CLAUSE_DEFAULT:
13169 ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
13170 break;
13172 case OMP_CLAUSE_INCLUSIVE:
13173 case OMP_CLAUSE_EXCLUSIVE:
13174 decl = OMP_CLAUSE_DECL (c);
13176 splay_tree_node n = splay_tree_lookup (outer_ctx->variables,
13177 (splay_tree_key) decl);
13178 if (n == NULL || (n->value & GOVD_REDUCTION) == 0)
13180 error_at (OMP_CLAUSE_LOCATION (c),
13181 "%qD specified in %qs clause but not in %<inscan%> "
13182 "%<reduction%> clause on the containing construct",
13183 decl, omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
13184 remove = true;
13186 else
13188 n->value |= GOVD_REDUCTION_INSCAN;
13189 if (outer_ctx->region_type == ORT_SIMD
13190 && outer_ctx->outer_context
13191 && outer_ctx->outer_context->region_type == ORT_WORKSHARE)
13193 n = splay_tree_lookup (outer_ctx->outer_context->variables,
13194 (splay_tree_key) decl);
13195 if (n && (n->value & GOVD_REDUCTION) != 0)
13196 n->value |= GOVD_REDUCTION_INSCAN;
13200 break;
13202 case OMP_CLAUSE_NOHOST:
13203 default:
13204 gcc_unreachable ();
13207 if (code == OACC_DATA
13208 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
13209 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
13210 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
13211 remove = true;
13212 if (remove)
13213 *list_p = OMP_CLAUSE_CHAIN (c);
13214 else
13215 list_p = &OMP_CLAUSE_CHAIN (c);
13218 if (groups)
13220 delete grpmap;
13221 delete groups;
13224 ctx->clauses = *orig_list_p;
13225 gimplify_omp_ctxp = ctx;
13228 /* Return true if DECL is a candidate for shared to firstprivate
13229 optimization. We only consider non-addressable scalars, not
13230 too big, and not references. */
13232 static bool
13233 omp_shared_to_firstprivate_optimizable_decl_p (tree decl)
13235 if (TREE_ADDRESSABLE (decl))
13236 return false;
13237 tree type = TREE_TYPE (decl);
13238 if (!is_gimple_reg_type (type)
13239 || TREE_CODE (type) == REFERENCE_TYPE
13240 || TREE_ADDRESSABLE (type))
13241 return false;
13242 /* Don't optimize too large decls, as each thread/task will have
13243 its own. */
13244 HOST_WIDE_INT len = int_size_in_bytes (type);
13245 if (len == -1 || len > 4 * POINTER_SIZE / BITS_PER_UNIT)
13246 return false;
13247 if (omp_privatize_by_reference (decl))
13248 return false;
13249 return true;
13252 /* Helper function of omp_find_stores_op and gimplify_adjust_omp_clauses*.
13253 For omp_shared_to_firstprivate_optimizable_decl_p decl mark it as
13254 GOVD_WRITTEN in outer contexts. */
13256 static void
13257 omp_mark_stores (struct gimplify_omp_ctx *ctx, tree decl)
13259 for (; ctx; ctx = ctx->outer_context)
13261 splay_tree_node n = splay_tree_lookup (ctx->variables,
13262 (splay_tree_key) decl);
13263 if (n == NULL)
13264 continue;
13265 else if (n->value & GOVD_SHARED)
13267 n->value |= GOVD_WRITTEN;
13268 return;
13270 else if (n->value & GOVD_DATA_SHARE_CLASS)
13271 return;
13275 /* Helper callback for walk_gimple_seq to discover possible stores
13276 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
13277 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
13278 for those. */
13280 static tree
13281 omp_find_stores_op (tree *tp, int *walk_subtrees, void *data)
13283 struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
13285 *walk_subtrees = 0;
13286 if (!wi->is_lhs)
13287 return NULL_TREE;
13289 tree op = *tp;
13292 if (handled_component_p (op))
13293 op = TREE_OPERAND (op, 0);
13294 else if ((TREE_CODE (op) == MEM_REF || TREE_CODE (op) == TARGET_MEM_REF)
13295 && TREE_CODE (TREE_OPERAND (op, 0)) == ADDR_EXPR)
13296 op = TREE_OPERAND (TREE_OPERAND (op, 0), 0);
13297 else
13298 break;
13300 while (1);
13301 if (!DECL_P (op) || !omp_shared_to_firstprivate_optimizable_decl_p (op))
13302 return NULL_TREE;
13304 omp_mark_stores (gimplify_omp_ctxp, op);
13305 return NULL_TREE;
13308 /* Helper callback for walk_gimple_seq to discover possible stores
13309 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
13310 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
13311 for those. */
13313 static tree
13314 omp_find_stores_stmt (gimple_stmt_iterator *gsi_p,
13315 bool *handled_ops_p,
13316 struct walk_stmt_info *wi)
13318 gimple *stmt = gsi_stmt (*gsi_p);
13319 switch (gimple_code (stmt))
13321 /* Don't recurse on OpenMP constructs for which
13322 gimplify_adjust_omp_clauses already handled the bodies,
13323 except handle gimple_omp_for_pre_body. */
13324 case GIMPLE_OMP_FOR:
13325 *handled_ops_p = true;
13326 if (gimple_omp_for_pre_body (stmt))
13327 walk_gimple_seq (gimple_omp_for_pre_body (stmt),
13328 omp_find_stores_stmt, omp_find_stores_op, wi);
13329 break;
13330 case GIMPLE_OMP_PARALLEL:
13331 case GIMPLE_OMP_TASK:
13332 case GIMPLE_OMP_SECTIONS:
13333 case GIMPLE_OMP_SINGLE:
13334 case GIMPLE_OMP_SCOPE:
13335 case GIMPLE_OMP_TARGET:
13336 case GIMPLE_OMP_TEAMS:
13337 case GIMPLE_OMP_CRITICAL:
13338 *handled_ops_p = true;
13339 break;
13340 default:
13341 break;
13343 return NULL_TREE;
13346 struct gimplify_adjust_omp_clauses_data
13348 tree *list_p;
13349 gimple_seq *pre_p;
13352 /* For all variables that were not actually used within the context,
13353 remove PRIVATE, SHARED, and FIRSTPRIVATE clauses. */
13355 static int
13356 gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
13358 tree *list_p = ((struct gimplify_adjust_omp_clauses_data *) data)->list_p;
13359 gimple_seq *pre_p
13360 = ((struct gimplify_adjust_omp_clauses_data *) data)->pre_p;
13361 tree decl = (tree) n->key;
13362 unsigned flags = n->value;
13363 enum omp_clause_code code;
13364 tree clause;
13365 bool private_debug;
13367 if (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
13368 && (flags & GOVD_LASTPRIVATE_CONDITIONAL) != 0)
13369 flags = GOVD_SHARED | GOVD_SEEN | GOVD_WRITTEN;
13370 if (flags & (GOVD_EXPLICIT | GOVD_LOCAL))
13371 return 0;
13372 if ((flags & GOVD_SEEN) == 0)
13373 return 0;
13374 if (flags & GOVD_DEBUG_PRIVATE)
13376 gcc_assert ((flags & GOVD_DATA_SHARE_CLASS) == GOVD_SHARED);
13377 private_debug = true;
13379 else if (flags & GOVD_MAP)
13380 private_debug = false;
13381 else
13382 private_debug
13383 = lang_hooks.decls.omp_private_debug_clause (decl,
13384 !!(flags & GOVD_SHARED));
13385 if (private_debug)
13386 code = OMP_CLAUSE_PRIVATE;
13387 else if (flags & GOVD_MAP)
13389 code = OMP_CLAUSE_MAP;
13390 if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0
13391 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
13393 error ("%<_Atomic%> %qD in implicit %<map%> clause", decl);
13394 return 0;
13396 if (VAR_P (decl)
13397 && DECL_IN_CONSTANT_POOL (decl)
13398 && !lookup_attribute ("omp declare target",
13399 DECL_ATTRIBUTES (decl)))
13401 tree id = get_identifier ("omp declare target");
13402 DECL_ATTRIBUTES (decl)
13403 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
13404 varpool_node *node = varpool_node::get (decl);
13405 if (node)
13407 node->offloadable = 1;
13408 if (ENABLE_OFFLOADING)
13409 g->have_offload = true;
13413 else if (flags & GOVD_SHARED)
13415 if (is_global_var (decl))
13417 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
13418 while (ctx != NULL)
13420 splay_tree_node on
13421 = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
13422 if (on && (on->value & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
13423 | GOVD_PRIVATE | GOVD_REDUCTION
13424 | GOVD_LINEAR | GOVD_MAP)) != 0)
13425 break;
13426 ctx = ctx->outer_context;
13428 if (ctx == NULL)
13429 return 0;
13431 code = OMP_CLAUSE_SHARED;
13432 /* Don't optimize shared into firstprivate for read-only vars
13433 on tasks with depend clause, we shouldn't try to copy them
13434 until the dependencies are satisfied. */
13435 if (gimplify_omp_ctxp->has_depend)
13436 flags |= GOVD_WRITTEN;
13438 else if (flags & GOVD_PRIVATE)
13439 code = OMP_CLAUSE_PRIVATE;
13440 else if (flags & GOVD_FIRSTPRIVATE)
13442 code = OMP_CLAUSE_FIRSTPRIVATE;
13443 if ((gimplify_omp_ctxp->region_type & ORT_TARGET)
13444 && (gimplify_omp_ctxp->region_type & ORT_ACC) == 0
13445 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
13447 error ("%<_Atomic%> %qD in implicit %<firstprivate%> clause on "
13448 "%<target%> construct", decl);
13449 return 0;
13452 else if (flags & GOVD_LASTPRIVATE)
13453 code = OMP_CLAUSE_LASTPRIVATE;
13454 else if (flags & (GOVD_ALIGNED | GOVD_NONTEMPORAL))
13455 return 0;
13456 else if (flags & GOVD_CONDTEMP)
13458 code = OMP_CLAUSE__CONDTEMP_;
13459 gimple_add_tmp_var (decl);
13461 else
13462 gcc_unreachable ();
13464 if (((flags & GOVD_LASTPRIVATE)
13465 || (code == OMP_CLAUSE_SHARED && (flags & GOVD_WRITTEN)))
13466 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
13467 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
13469 tree chain = *list_p;
13470 clause = build_omp_clause (input_location, code);
13471 OMP_CLAUSE_DECL (clause) = decl;
13472 OMP_CLAUSE_CHAIN (clause) = chain;
13473 if (private_debug)
13474 OMP_CLAUSE_PRIVATE_DEBUG (clause) = 1;
13475 else if (code == OMP_CLAUSE_PRIVATE && (flags & GOVD_PRIVATE_OUTER_REF))
13476 OMP_CLAUSE_PRIVATE_OUTER_REF (clause) = 1;
13477 else if (code == OMP_CLAUSE_SHARED
13478 && (flags & GOVD_WRITTEN) == 0
13479 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
13480 OMP_CLAUSE_SHARED_READONLY (clause) = 1;
13481 else if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_EXPLICIT) == 0)
13482 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (clause) = 1;
13483 else if (code == OMP_CLAUSE_MAP && (flags & GOVD_MAP_0LEN_ARRAY) != 0)
13485 tree nc = build_omp_clause (input_location, OMP_CLAUSE_MAP);
13486 OMP_CLAUSE_DECL (nc) = decl;
13487 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
13488 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == POINTER_TYPE)
13489 OMP_CLAUSE_DECL (clause)
13490 = build_fold_indirect_ref_loc (input_location, decl);
13491 OMP_CLAUSE_DECL (clause)
13492 = build2 (MEM_REF, char_type_node, OMP_CLAUSE_DECL (clause),
13493 build_int_cst (build_pointer_type (char_type_node), 0));
13494 OMP_CLAUSE_SIZE (clause) = size_zero_node;
13495 OMP_CLAUSE_SIZE (nc) = size_zero_node;
13496 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_ALLOC);
13497 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (clause) = 1;
13498 tree dtype = TREE_TYPE (decl);
13499 if (TREE_CODE (dtype) == REFERENCE_TYPE)
13500 dtype = TREE_TYPE (dtype);
13501 /* FIRSTPRIVATE_POINTER doesn't work well if we have a
13502 multiply-indirected pointer. */
13503 if (TREE_CODE (dtype) == POINTER_TYPE
13504 && TREE_CODE (TREE_TYPE (dtype)) == POINTER_TYPE)
13505 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
13506 else
13507 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
13508 OMP_CLAUSE_CHAIN (nc) = chain;
13509 OMP_CLAUSE_CHAIN (clause) = nc;
13510 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
13511 gimplify_omp_ctxp = ctx->outer_context;
13512 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (clause), 0),
13513 pre_p, NULL, is_gimple_val, fb_rvalue);
13514 gimplify_omp_ctxp = ctx;
13516 else if (code == OMP_CLAUSE_MAP)
13518 int kind;
13519 /* Not all combinations of these GOVD_MAP flags are actually valid. */
13520 switch (flags & (GOVD_MAP_TO_ONLY
13521 | GOVD_MAP_FORCE
13522 | GOVD_MAP_FORCE_PRESENT
13523 | GOVD_MAP_ALLOC_ONLY
13524 | GOVD_MAP_FROM_ONLY))
13526 case 0:
13527 kind = GOMP_MAP_TOFROM;
13528 break;
13529 case GOVD_MAP_FORCE:
13530 kind = GOMP_MAP_TOFROM | GOMP_MAP_FLAG_FORCE;
13531 break;
13532 case GOVD_MAP_TO_ONLY:
13533 kind = GOMP_MAP_TO;
13534 break;
13535 case GOVD_MAP_FROM_ONLY:
13536 kind = GOMP_MAP_FROM;
13537 break;
13538 case GOVD_MAP_ALLOC_ONLY:
13539 kind = GOMP_MAP_ALLOC;
13540 break;
13541 case GOVD_MAP_TO_ONLY | GOVD_MAP_FORCE:
13542 kind = GOMP_MAP_TO | GOMP_MAP_FLAG_FORCE;
13543 break;
13544 case GOVD_MAP_FORCE_PRESENT:
13545 kind = GOMP_MAP_FORCE_PRESENT;
13546 break;
13547 case GOVD_MAP_FORCE_PRESENT | GOVD_MAP_ALLOC_ONLY:
13548 kind = GOMP_MAP_FORCE_PRESENT;
13549 break;
13550 default:
13551 gcc_unreachable ();
13553 OMP_CLAUSE_SET_MAP_KIND (clause, kind);
13554 /* Setting of the implicit flag for the runtime is currently disabled for
13555 OpenACC. */
13556 if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0)
13557 OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (clause) = 1;
13558 if (DECL_SIZE (decl)
13559 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
13561 tree decl2 = DECL_VALUE_EXPR (decl);
13562 gcc_assert (INDIRECT_REF_P (decl2));
13563 decl2 = TREE_OPERAND (decl2, 0);
13564 gcc_assert (DECL_P (decl2));
13565 tree mem = build_simple_mem_ref (decl2);
13566 OMP_CLAUSE_DECL (clause) = mem;
13567 OMP_CLAUSE_SIZE (clause) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
13568 if (gimplify_omp_ctxp->outer_context)
13570 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
13571 omp_notice_variable (ctx, decl2, true);
13572 omp_notice_variable (ctx, OMP_CLAUSE_SIZE (clause), true);
13574 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
13575 OMP_CLAUSE_MAP);
13576 OMP_CLAUSE_DECL (nc) = decl;
13577 OMP_CLAUSE_SIZE (nc) = size_zero_node;
13578 if (gimplify_omp_ctxp->target_firstprivatize_array_bases)
13579 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
13580 else
13581 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
13582 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
13583 OMP_CLAUSE_CHAIN (clause) = nc;
13585 else if (gimplify_omp_ctxp->target_firstprivatize_array_bases
13586 && omp_privatize_by_reference (decl))
13588 OMP_CLAUSE_DECL (clause) = build_simple_mem_ref (decl);
13589 OMP_CLAUSE_SIZE (clause)
13590 = unshare_expr (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))));
13591 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
13592 gimplify_omp_ctxp = ctx->outer_context;
13593 gimplify_expr (&OMP_CLAUSE_SIZE (clause),
13594 pre_p, NULL, is_gimple_val, fb_rvalue);
13595 gimplify_omp_ctxp = ctx;
13596 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
13597 OMP_CLAUSE_MAP);
13598 OMP_CLAUSE_DECL (nc) = decl;
13599 OMP_CLAUSE_SIZE (nc) = size_zero_node;
13600 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_REFERENCE);
13601 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
13602 OMP_CLAUSE_CHAIN (clause) = nc;
13604 else
13605 OMP_CLAUSE_SIZE (clause) = DECL_SIZE_UNIT (decl);
13607 if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_LASTPRIVATE) != 0)
13609 tree nc = build_omp_clause (input_location, OMP_CLAUSE_LASTPRIVATE);
13610 OMP_CLAUSE_DECL (nc) = decl;
13611 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (nc) = 1;
13612 OMP_CLAUSE_CHAIN (nc) = chain;
13613 OMP_CLAUSE_CHAIN (clause) = nc;
13614 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
13615 gimplify_omp_ctxp = ctx->outer_context;
13616 lang_hooks.decls.omp_finish_clause (nc, pre_p,
13617 (ctx->region_type & ORT_ACC) != 0);
13618 gimplify_omp_ctxp = ctx;
13620 *list_p = clause;
13621 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
13622 gimplify_omp_ctxp = ctx->outer_context;
13623 /* Don't call omp_finish_clause on implicitly added OMP_CLAUSE_PRIVATE
13624 in simd. Those are only added for the local vars inside of simd body
13625 and they don't need to be e.g. default constructible. */
13626 if (code != OMP_CLAUSE_PRIVATE || ctx->region_type != ORT_SIMD)
13627 lang_hooks.decls.omp_finish_clause (clause, pre_p,
13628 (ctx->region_type & ORT_ACC) != 0);
13629 if (gimplify_omp_ctxp)
13630 for (; clause != chain; clause = OMP_CLAUSE_CHAIN (clause))
13631 if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_MAP
13632 && DECL_P (OMP_CLAUSE_SIZE (clause)))
13633 omp_notice_variable (gimplify_omp_ctxp, OMP_CLAUSE_SIZE (clause),
13634 true);
13635 gimplify_omp_ctxp = ctx;
13636 return 0;
13639 static void
13640 gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
13641 enum tree_code code)
13643 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
13644 tree *orig_list_p = list_p;
13645 tree c, decl;
13646 bool has_inscan_reductions = false;
13648 if (body)
13650 struct gimplify_omp_ctx *octx;
13651 for (octx = ctx; octx; octx = octx->outer_context)
13652 if ((octx->region_type & (ORT_PARALLEL | ORT_TASK | ORT_TEAMS)) != 0)
13653 break;
13654 if (octx)
13656 struct walk_stmt_info wi;
13657 memset (&wi, 0, sizeof (wi));
13658 walk_gimple_seq (body, omp_find_stores_stmt,
13659 omp_find_stores_op, &wi);
13663 if (ctx->add_safelen1)
13665 /* If there are VLAs in the body of simd loop, prevent
13666 vectorization. */
13667 gcc_assert (ctx->region_type == ORT_SIMD);
13668 c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_SAFELEN);
13669 OMP_CLAUSE_SAFELEN_EXPR (c) = integer_one_node;
13670 OMP_CLAUSE_CHAIN (c) = *list_p;
13671 *list_p = c;
13672 list_p = &OMP_CLAUSE_CHAIN (c);
13675 if (ctx->region_type == ORT_WORKSHARE
13676 && ctx->outer_context
13677 && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL)
13679 for (c = ctx->outer_context->clauses; c; c = OMP_CLAUSE_CHAIN (c))
13680 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
13681 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
13683 decl = OMP_CLAUSE_DECL (c);
13684 splay_tree_node n
13685 = splay_tree_lookup (ctx->outer_context->variables,
13686 (splay_tree_key) decl);
13687 gcc_checking_assert (!splay_tree_lookup (ctx->variables,
13688 (splay_tree_key) decl));
13689 omp_add_variable (ctx, decl, n->value);
13690 tree c2 = copy_node (c);
13691 OMP_CLAUSE_CHAIN (c2) = *list_p;
13692 *list_p = c2;
13693 if ((n->value & GOVD_FIRSTPRIVATE) == 0)
13694 continue;
13695 c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
13696 OMP_CLAUSE_FIRSTPRIVATE);
13697 OMP_CLAUSE_DECL (c2) = decl;
13698 OMP_CLAUSE_CHAIN (c2) = *list_p;
13699 *list_p = c2;
13703 if (code == OMP_TARGET
13704 || code == OMP_TARGET_DATA
13705 || code == OMP_TARGET_ENTER_DATA
13706 || code == OMP_TARGET_EXIT_DATA)
13708 vec<omp_mapping_group> *groups;
13709 groups = omp_gather_mapping_groups (list_p);
13710 hash_map<tree_operand_hash_no_se, omp_mapping_group *> *grpmap = NULL;
13712 if (groups)
13714 grpmap = omp_index_mapping_groups (groups);
13716 omp_resolve_clause_dependencies (code, groups, grpmap);
13717 omp_build_struct_sibling_lists (code, ctx->region_type, groups,
13718 &grpmap, list_p);
13720 omp_mapping_group *outlist = NULL;
13722 delete grpmap;
13723 delete groups;
13725 /* Rebuild now we have struct sibling lists. */
13726 groups = omp_gather_mapping_groups (list_p);
13727 grpmap = omp_index_mapping_groups (groups);
13729 bool enter_exit = (code == OMP_TARGET_ENTER_DATA
13730 || code == OMP_TARGET_EXIT_DATA);
13732 outlist = omp_tsort_mapping_groups (groups, grpmap, enter_exit);
13733 outlist = omp_segregate_mapping_groups (outlist);
13734 list_p = omp_reorder_mapping_groups (groups, outlist, list_p);
13736 delete grpmap;
13737 delete groups;
13740 else if (ctx->region_type & ORT_ACC)
13742 vec<omp_mapping_group> *groups;
13743 groups = omp_gather_mapping_groups (list_p);
13744 if (groups)
13746 hash_map<tree_operand_hash_no_se, omp_mapping_group *> *grpmap;
13747 grpmap = omp_index_mapping_groups (groups);
13749 oacc_resolve_clause_dependencies (groups, grpmap);
13750 omp_build_struct_sibling_lists (code, ctx->region_type, groups,
13751 &grpmap, list_p);
13753 delete groups;
13754 delete grpmap;
13758 tree attach_list = NULL_TREE;
13759 tree *attach_tail = &attach_list;
13761 tree *grp_start_p = NULL, grp_end = NULL_TREE;
13763 while ((c = *list_p) != NULL)
13765 splay_tree_node n;
13766 bool remove = false;
13767 bool move_attach = false;
13769 if (grp_end && c == OMP_CLAUSE_CHAIN (grp_end))
13770 grp_end = NULL_TREE;
13772 switch (OMP_CLAUSE_CODE (c))
13774 case OMP_CLAUSE_FIRSTPRIVATE:
13775 if ((ctx->region_type & ORT_TARGET)
13776 && (ctx->region_type & ORT_ACC) == 0
13777 && TYPE_ATOMIC (strip_array_types
13778 (TREE_TYPE (OMP_CLAUSE_DECL (c)))))
13780 error_at (OMP_CLAUSE_LOCATION (c),
13781 "%<_Atomic%> %qD in %<firstprivate%> clause on "
13782 "%<target%> construct", OMP_CLAUSE_DECL (c));
13783 remove = true;
13784 break;
13786 if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c))
13788 decl = OMP_CLAUSE_DECL (c);
13789 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
13790 if ((n->value & GOVD_MAP) != 0)
13792 remove = true;
13793 break;
13795 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT_TARGET (c) = 0;
13796 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c) = 0;
13798 /* FALLTHRU */
13799 case OMP_CLAUSE_PRIVATE:
13800 case OMP_CLAUSE_SHARED:
13801 case OMP_CLAUSE_LINEAR:
13802 decl = OMP_CLAUSE_DECL (c);
13803 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
13804 remove = !(n->value & GOVD_SEEN);
13805 if ((n->value & GOVD_LASTPRIVATE_CONDITIONAL) != 0
13806 && code == OMP_PARALLEL
13807 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
13808 remove = true;
13809 if (! remove)
13811 bool shared = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED;
13812 if ((n->value & GOVD_DEBUG_PRIVATE)
13813 || lang_hooks.decls.omp_private_debug_clause (decl, shared))
13815 gcc_assert ((n->value & GOVD_DEBUG_PRIVATE) == 0
13816 || ((n->value & GOVD_DATA_SHARE_CLASS)
13817 == GOVD_SHARED));
13818 OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_PRIVATE);
13819 OMP_CLAUSE_PRIVATE_DEBUG (c) = 1;
13821 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
13822 && ctx->has_depend
13823 && DECL_P (decl))
13824 n->value |= GOVD_WRITTEN;
13825 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
13826 && (n->value & GOVD_WRITTEN) == 0
13827 && DECL_P (decl)
13828 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
13829 OMP_CLAUSE_SHARED_READONLY (c) = 1;
13830 else if (DECL_P (decl)
13831 && ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
13832 && (n->value & GOVD_WRITTEN) != 0)
13833 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
13834 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
13835 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
13836 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
13838 else
13839 n->value &= ~GOVD_EXPLICIT;
13840 break;
13842 case OMP_CLAUSE_LASTPRIVATE:
13843 /* Make sure OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE is set to
13844 accurately reflect the presence of a FIRSTPRIVATE clause. */
13845 decl = OMP_CLAUSE_DECL (c);
13846 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
13847 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c)
13848 = (n->value & GOVD_FIRSTPRIVATE) != 0;
13849 if (code == OMP_DISTRIBUTE
13850 && OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
13852 remove = true;
13853 error_at (OMP_CLAUSE_LOCATION (c),
13854 "same variable used in %<firstprivate%> and "
13855 "%<lastprivate%> clauses on %<distribute%> "
13856 "construct");
13858 if (!remove
13859 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
13860 && DECL_P (decl)
13861 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
13862 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
13863 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) && code == OMP_PARALLEL)
13864 remove = true;
13865 break;
13867 case OMP_CLAUSE_ALIGNED:
13868 decl = OMP_CLAUSE_DECL (c);
13869 if (!is_global_var (decl))
13871 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
13872 remove = n == NULL || !(n->value & GOVD_SEEN);
13873 if (!remove && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
13875 struct gimplify_omp_ctx *octx;
13876 if (n != NULL
13877 && (n->value & (GOVD_DATA_SHARE_CLASS
13878 & ~GOVD_FIRSTPRIVATE)))
13879 remove = true;
13880 else
13881 for (octx = ctx->outer_context; octx;
13882 octx = octx->outer_context)
13884 n = splay_tree_lookup (octx->variables,
13885 (splay_tree_key) decl);
13886 if (n == NULL)
13887 continue;
13888 if (n->value & GOVD_LOCAL)
13889 break;
13890 /* We have to avoid assigning a shared variable
13891 to itself when trying to add
13892 __builtin_assume_aligned. */
13893 if (n->value & GOVD_SHARED)
13895 remove = true;
13896 break;
13901 else if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
13903 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
13904 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
13905 remove = true;
13907 break;
13909 case OMP_CLAUSE_HAS_DEVICE_ADDR:
13910 decl = OMP_CLAUSE_DECL (c);
13911 while (INDIRECT_REF_P (decl)
13912 || TREE_CODE (decl) == ARRAY_REF)
13913 decl = TREE_OPERAND (decl, 0);
13914 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
13915 remove = n == NULL || !(n->value & GOVD_SEEN);
13916 break;
13918 case OMP_CLAUSE_IS_DEVICE_PTR:
13919 case OMP_CLAUSE_NONTEMPORAL:
13920 decl = OMP_CLAUSE_DECL (c);
13921 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
13922 remove = n == NULL || !(n->value & GOVD_SEEN);
13923 break;
13925 case OMP_CLAUSE_MAP:
13926 decl = OMP_CLAUSE_DECL (c);
13927 if (!grp_end)
13929 grp_start_p = list_p;
13930 grp_end = *omp_group_last (grp_start_p);
13932 switch (OMP_CLAUSE_MAP_KIND (c))
13934 case GOMP_MAP_PRESENT_ALLOC:
13935 case GOMP_MAP_PRESENT_TO:
13936 case GOMP_MAP_PRESENT_FROM:
13937 case GOMP_MAP_PRESENT_TOFROM:
13938 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_PRESENT);
13939 break;
13940 default:
13941 break;
13943 switch (code)
13945 case OACC_DATA:
13946 if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
13947 break;
13948 /* Fallthrough. */
13949 case OACC_HOST_DATA:
13950 case OACC_ENTER_DATA:
13951 case OACC_EXIT_DATA:
13952 case OMP_TARGET_DATA:
13953 case OMP_TARGET_ENTER_DATA:
13954 case OMP_TARGET_EXIT_DATA:
13955 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
13956 || (OMP_CLAUSE_MAP_KIND (c)
13957 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
13958 /* For target {,enter ,exit }data only the array slice is
13959 mapped, but not the pointer to it. */
13960 remove = true;
13961 if (code == OMP_TARGET_EXIT_DATA
13962 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER
13963 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER))
13964 remove = true;
13965 break;
13966 case OMP_TARGET:
13967 break;
13968 default:
13969 break;
13971 if (remove)
13972 break;
13973 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
13975 /* Sanity check: attach/detach map kinds use the size as a bias,
13976 and it's never right to use the decl size for such
13977 mappings. */
13978 gcc_assert (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH
13979 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_DETACH
13980 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FORCE_DETACH
13981 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH_DETACH
13982 && (OMP_CLAUSE_MAP_KIND (c)
13983 != GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION));
13984 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
13985 : TYPE_SIZE_UNIT (TREE_TYPE (decl));
13987 gimplify_omp_ctxp = ctx->outer_context;
13988 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p, NULL,
13989 is_gimple_val, fb_rvalue) == GS_ERROR)
13991 gimplify_omp_ctxp = ctx;
13992 remove = true;
13993 break;
13995 else if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
13996 || (OMP_CLAUSE_MAP_KIND (c)
13997 == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
13998 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
13999 && TREE_CODE (OMP_CLAUSE_SIZE (c)) != INTEGER_CST)
14001 OMP_CLAUSE_SIZE (c)
14002 = get_initialized_tmp_var (OMP_CLAUSE_SIZE (c), pre_p, NULL,
14003 false);
14004 if ((ctx->region_type & ORT_TARGET) != 0)
14005 omp_add_variable (ctx, OMP_CLAUSE_SIZE (c),
14006 GOVD_FIRSTPRIVATE | GOVD_SEEN);
14008 gimplify_omp_ctxp = ctx;
14009 /* Data clauses associated with reductions must be
14010 compatible with present_or_copy. Warn and adjust the clause
14011 if that is not the case. */
14012 if (ctx->region_type == ORT_ACC_PARALLEL
14013 || ctx->region_type == ORT_ACC_SERIAL)
14015 tree t = DECL_P (decl) ? decl : TREE_OPERAND (decl, 0);
14016 n = NULL;
14018 if (DECL_P (t))
14019 n = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
14021 if (n && (n->value & GOVD_REDUCTION))
14023 enum gomp_map_kind kind = OMP_CLAUSE_MAP_KIND (c);
14025 OMP_CLAUSE_MAP_IN_REDUCTION (c) = 1;
14026 if ((kind & GOMP_MAP_TOFROM) != GOMP_MAP_TOFROM
14027 && kind != GOMP_MAP_FORCE_PRESENT
14028 && kind != GOMP_MAP_POINTER)
14030 warning_at (OMP_CLAUSE_LOCATION (c), 0,
14031 "incompatible data clause with reduction "
14032 "on %qE; promoting to %<present_or_copy%>",
14033 DECL_NAME (t));
14034 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TOFROM);
14038 if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT
14039 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT_UNORD)
14040 && (code == OMP_TARGET_EXIT_DATA || code == OACC_EXIT_DATA))
14042 remove = true;
14043 break;
14045 /* If we have a DECL_VALUE_EXPR (e.g. this is a class member and/or
14046 a variable captured in a lambda closure), look through that now
14047 before the DECL_P check below. (A code other than COMPONENT_REF,
14048 i.e. INDIRECT_REF, will be a VLA/variable-length array
14049 section. A global var may be a variable in a common block. We
14050 don't want to do this here for either of those.) */
14051 if ((ctx->region_type & ORT_ACC) == 0
14052 && DECL_P (decl)
14053 && !is_global_var (decl)
14054 && DECL_HAS_VALUE_EXPR_P (decl)
14055 && TREE_CODE (DECL_VALUE_EXPR (decl)) == COMPONENT_REF)
14056 decl = OMP_CLAUSE_DECL (c) = DECL_VALUE_EXPR (decl);
14057 if (TREE_CODE (decl) == TARGET_EXPR)
14059 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
14060 is_gimple_lvalue, fb_lvalue) == GS_ERROR)
14061 remove = true;
14063 else if (!DECL_P (decl))
14065 if ((ctx->region_type & ORT_TARGET) != 0
14066 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
14068 if (INDIRECT_REF_P (decl)
14069 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
14070 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
14071 == REFERENCE_TYPE))
14072 decl = TREE_OPERAND (decl, 0);
14073 if (TREE_CODE (decl) == COMPONENT_REF)
14075 while (TREE_CODE (decl) == COMPONENT_REF)
14076 decl = TREE_OPERAND (decl, 0);
14077 if (DECL_P (decl))
14079 n = splay_tree_lookup (ctx->variables,
14080 (splay_tree_key) decl);
14081 if (!(n->value & GOVD_SEEN))
14082 remove = true;
14087 tree d = decl, *pd;
14088 if (TREE_CODE (d) == ARRAY_REF)
14090 while (TREE_CODE (d) == ARRAY_REF)
14091 d = TREE_OPERAND (d, 0);
14092 if (TREE_CODE (d) == COMPONENT_REF
14093 && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE)
14094 decl = d;
14096 pd = &OMP_CLAUSE_DECL (c);
14097 if (d == decl
14098 && TREE_CODE (decl) == INDIRECT_REF
14099 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
14100 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
14101 == REFERENCE_TYPE)
14102 && (OMP_CLAUSE_MAP_KIND (c)
14103 != GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION))
14105 pd = &TREE_OPERAND (decl, 0);
14106 decl = TREE_OPERAND (decl, 0);
14109 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
14110 switch (code)
14112 case OACC_ENTER_DATA:
14113 case OACC_EXIT_DATA:
14114 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
14115 == ARRAY_TYPE)
14116 remove = true;
14117 else if (code == OACC_ENTER_DATA)
14118 goto change_to_attach;
14119 /* Fallthrough. */
14120 case OMP_TARGET_EXIT_DATA:
14121 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_DETACH);
14122 break;
14123 case OACC_UPDATE:
14124 /* An "attach/detach" operation on an update directive
14125 should behave as a GOMP_MAP_ALWAYS_POINTER. Note that
14126 both GOMP_MAP_ATTACH_DETACH and GOMP_MAP_ALWAYS_POINTER
14127 kinds depend on the previous mapping (for non-TARGET
14128 regions). */
14129 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_ALWAYS_POINTER);
14130 break;
14131 default:
14132 change_to_attach:
14133 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_ATTACH);
14134 if ((ctx->region_type & ORT_TARGET) != 0)
14135 move_attach = true;
14137 else if ((ctx->region_type & ORT_TARGET) != 0
14138 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
14139 || (OMP_CLAUSE_MAP_KIND (c)
14140 == GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION)))
14141 move_attach = true;
14143 /* If we have e.g. map(struct: *var), don't gimplify the
14144 argument since omp-low.cc wants to see the decl itself. */
14145 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT)
14146 break;
14148 /* We've already partly gimplified this in
14149 gimplify_scan_omp_clauses. Don't do any more. */
14150 if (code == OMP_TARGET && OMP_CLAUSE_MAP_IN_REDUCTION (c))
14151 break;
14153 gimplify_omp_ctxp = ctx->outer_context;
14154 if (gimplify_expr (pd, pre_p, NULL, is_gimple_lvalue,
14155 fb_lvalue) == GS_ERROR)
14156 remove = true;
14157 gimplify_omp_ctxp = ctx;
14158 break;
14161 if ((code == OMP_TARGET
14162 || code == OMP_TARGET_DATA
14163 || code == OMP_TARGET_ENTER_DATA
14164 || code == OMP_TARGET_EXIT_DATA)
14165 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
14167 bool firstprivatize = false;
14169 for (struct gimplify_omp_ctx *octx = ctx->outer_context; octx;
14170 octx = octx->outer_context)
14172 splay_tree_node n
14173 = splay_tree_lookup (octx->variables,
14174 (splay_tree_key) OMP_CLAUSE_DECL (c));
14175 /* If this is contained in an outer OpenMP region as a
14176 firstprivate value, remove the attach/detach. */
14177 if (n && (n->value & GOVD_FIRSTPRIVATE))
14179 firstprivatize = true;
14180 break;
14184 enum gomp_map_kind map_kind;
14185 if (firstprivatize)
14186 map_kind = GOMP_MAP_FIRSTPRIVATE_POINTER;
14187 else if (code == OMP_TARGET_EXIT_DATA)
14188 map_kind = GOMP_MAP_DETACH;
14189 else
14190 map_kind = GOMP_MAP_ATTACH;
14191 OMP_CLAUSE_SET_MAP_KIND (c, map_kind);
14193 else if ((ctx->region_type & ORT_ACC) != 0
14194 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
14196 enum gomp_map_kind map_kind = (code == OACC_EXIT_DATA
14197 ? GOMP_MAP_DETACH
14198 : GOMP_MAP_ATTACH);
14199 OMP_CLAUSE_SET_MAP_KIND (c, map_kind);
14202 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
14203 if ((ctx->region_type & ORT_TARGET) != 0
14204 && !(n->value & GOVD_SEEN)
14205 && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) == 0
14206 && (!is_global_var (decl)
14207 || !lookup_attribute ("omp declare target link",
14208 DECL_ATTRIBUTES (decl))))
14210 remove = true;
14211 /* For struct element mapping, if struct is never referenced
14212 in target block and none of the mapping has always modifier,
14213 remove all the struct element mappings, which immediately
14214 follow the GOMP_MAP_STRUCT map clause. */
14215 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT
14216 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT_UNORD)
14218 HOST_WIDE_INT cnt = tree_to_shwi (OMP_CLAUSE_SIZE (c));
14219 while (cnt--)
14220 OMP_CLAUSE_CHAIN (c)
14221 = OMP_CLAUSE_CHAIN (OMP_CLAUSE_CHAIN (c));
14224 else if (DECL_SIZE (decl)
14225 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST
14226 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_POINTER
14227 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_POINTER
14228 && (OMP_CLAUSE_MAP_KIND (c)
14229 != GOMP_MAP_FIRSTPRIVATE_REFERENCE))
14231 /* For GOMP_MAP_FORCE_DEVICEPTR, we'll never enter here, because
14232 for these, TREE_CODE (DECL_SIZE (decl)) will always be
14233 INTEGER_CST. */
14234 gcc_assert (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FORCE_DEVICEPTR);
14236 tree decl2 = DECL_VALUE_EXPR (decl);
14237 gcc_assert (INDIRECT_REF_P (decl2));
14238 decl2 = TREE_OPERAND (decl2, 0);
14239 gcc_assert (DECL_P (decl2));
14240 tree mem = build_simple_mem_ref (decl2);
14241 OMP_CLAUSE_DECL (c) = mem;
14242 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
14243 if (ctx->outer_context)
14245 omp_notice_variable (ctx->outer_context, decl2, true);
14246 omp_notice_variable (ctx->outer_context,
14247 OMP_CLAUSE_SIZE (c), true);
14249 if (((ctx->region_type & ORT_TARGET) != 0
14250 || !ctx->target_firstprivatize_array_bases)
14251 && ((n->value & GOVD_SEEN) == 0
14252 || (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) == 0))
14254 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
14255 OMP_CLAUSE_MAP);
14256 OMP_CLAUSE_DECL (nc) = decl;
14257 OMP_CLAUSE_SIZE (nc) = size_zero_node;
14258 if (ctx->target_firstprivatize_array_bases)
14259 OMP_CLAUSE_SET_MAP_KIND (nc,
14260 GOMP_MAP_FIRSTPRIVATE_POINTER);
14261 else
14262 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
14263 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
14264 OMP_CLAUSE_CHAIN (c) = nc;
14265 c = nc;
14268 else
14270 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
14271 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
14272 gcc_assert ((n->value & GOVD_SEEN) == 0
14273 || ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
14274 == 0));
14277 /* If we have a target region, we can push all the attaches to the
14278 end of the list (we may have standalone "attach" operations
14279 synthesized for GOMP_MAP_STRUCT nodes that must be processed after
14280 the attachment point AND the pointed-to block have been mapped).
14281 If we have something else, e.g. "enter data", we need to keep
14282 "attach" nodes together with the previous node they attach to so
14283 that separate "exit data" operations work properly (see
14284 libgomp/target.c). */
14285 if ((ctx->region_type & ORT_TARGET) != 0
14286 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
14287 || (OMP_CLAUSE_MAP_KIND (c)
14288 == GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION)))
14289 move_attach = true;
14291 break;
14293 case OMP_CLAUSE_TO:
14294 case OMP_CLAUSE_FROM:
14295 case OMP_CLAUSE__CACHE_:
14296 decl = OMP_CLAUSE_DECL (c);
14297 if (!DECL_P (decl))
14298 break;
14299 if (DECL_SIZE (decl)
14300 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
14302 tree decl2 = DECL_VALUE_EXPR (decl);
14303 gcc_assert (INDIRECT_REF_P (decl2));
14304 decl2 = TREE_OPERAND (decl2, 0);
14305 gcc_assert (DECL_P (decl2));
14306 tree mem = build_simple_mem_ref (decl2);
14307 OMP_CLAUSE_DECL (c) = mem;
14308 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
14309 if (ctx->outer_context)
14311 omp_notice_variable (ctx->outer_context, decl2, true);
14312 omp_notice_variable (ctx->outer_context,
14313 OMP_CLAUSE_SIZE (c), true);
14316 else if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
14317 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
14318 break;
14320 case OMP_CLAUSE_REDUCTION:
14321 if (OMP_CLAUSE_REDUCTION_INSCAN (c))
14323 decl = OMP_CLAUSE_DECL (c);
14324 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
14325 if ((n->value & GOVD_REDUCTION_INSCAN) == 0)
14327 remove = true;
14328 error_at (OMP_CLAUSE_LOCATION (c),
14329 "%qD specified in %<inscan%> %<reduction%> clause "
14330 "but not in %<scan%> directive clause", decl);
14331 break;
14333 has_inscan_reductions = true;
14335 /* FALLTHRU */
14336 case OMP_CLAUSE_IN_REDUCTION:
14337 case OMP_CLAUSE_TASK_REDUCTION:
14338 decl = OMP_CLAUSE_DECL (c);
14339 /* OpenACC reductions need a present_or_copy data clause.
14340 Add one if necessary. Emit error when the reduction is private. */
14341 if (ctx->region_type == ORT_ACC_PARALLEL
14342 || ctx->region_type == ORT_ACC_SERIAL)
14344 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
14345 if (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
14347 remove = true;
14348 error_at (OMP_CLAUSE_LOCATION (c), "invalid private "
14349 "reduction on %qE", DECL_NAME (decl));
14351 else if ((n->value & GOVD_MAP) == 0)
14353 tree next = OMP_CLAUSE_CHAIN (c);
14354 tree nc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_MAP);
14355 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_TOFROM);
14356 OMP_CLAUSE_DECL (nc) = decl;
14357 OMP_CLAUSE_CHAIN (c) = nc;
14358 lang_hooks.decls.omp_finish_clause (nc, pre_p,
14359 (ctx->region_type
14360 & ORT_ACC) != 0);
14361 while (1)
14363 OMP_CLAUSE_MAP_IN_REDUCTION (nc) = 1;
14364 if (OMP_CLAUSE_CHAIN (nc) == NULL)
14365 break;
14366 nc = OMP_CLAUSE_CHAIN (nc);
14368 OMP_CLAUSE_CHAIN (nc) = next;
14369 n->value |= GOVD_MAP;
14372 if (DECL_P (decl)
14373 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
14374 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
14375 break;
14377 case OMP_CLAUSE_ALLOCATE:
14378 decl = OMP_CLAUSE_DECL (c);
14379 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
14380 if (n != NULL && !(n->value & GOVD_SEEN))
14382 if ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE | GOVD_LINEAR))
14383 != 0
14384 && (n->value & (GOVD_REDUCTION | GOVD_LASTPRIVATE)) == 0)
14385 remove = true;
14387 if (!remove
14388 && OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
14389 && TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)) != INTEGER_CST
14390 && ((ctx->region_type & (ORT_PARALLEL | ORT_TARGET)) != 0
14391 || (ctx->region_type & ORT_TASKLOOP) == ORT_TASK
14392 || (ctx->region_type & ORT_HOST_TEAMS) == ORT_HOST_TEAMS))
14394 tree allocator = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
14395 n = splay_tree_lookup (ctx->variables, (splay_tree_key) allocator);
14396 if (n == NULL)
14398 enum omp_clause_default_kind default_kind
14399 = ctx->default_kind;
14400 ctx->default_kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
14401 omp_notice_variable (ctx, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
14402 true);
14403 ctx->default_kind = default_kind;
14405 else
14406 omp_notice_variable (ctx, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
14407 true);
14409 break;
14411 case OMP_CLAUSE_COPYIN:
14412 case OMP_CLAUSE_COPYPRIVATE:
14413 case OMP_CLAUSE_IF:
14414 case OMP_CLAUSE_SELF:
14415 case OMP_CLAUSE_NUM_THREADS:
14416 case OMP_CLAUSE_NUM_TEAMS:
14417 case OMP_CLAUSE_THREAD_LIMIT:
14418 case OMP_CLAUSE_DIST_SCHEDULE:
14419 case OMP_CLAUSE_DEVICE:
14420 case OMP_CLAUSE_SCHEDULE:
14421 case OMP_CLAUSE_NOWAIT:
14422 case OMP_CLAUSE_ORDERED:
14423 case OMP_CLAUSE_DEFAULT:
14424 case OMP_CLAUSE_UNTIED:
14425 case OMP_CLAUSE_COLLAPSE:
14426 case OMP_CLAUSE_FINAL:
14427 case OMP_CLAUSE_MERGEABLE:
14428 case OMP_CLAUSE_PROC_BIND:
14429 case OMP_CLAUSE_SAFELEN:
14430 case OMP_CLAUSE_SIMDLEN:
14431 case OMP_CLAUSE_DEPEND:
14432 case OMP_CLAUSE_DOACROSS:
14433 case OMP_CLAUSE_PRIORITY:
14434 case OMP_CLAUSE_GRAINSIZE:
14435 case OMP_CLAUSE_NUM_TASKS:
14436 case OMP_CLAUSE_NOGROUP:
14437 case OMP_CLAUSE_THREADS:
14438 case OMP_CLAUSE_SIMD:
14439 case OMP_CLAUSE_FILTER:
14440 case OMP_CLAUSE_HINT:
14441 case OMP_CLAUSE_DEFAULTMAP:
14442 case OMP_CLAUSE_ORDER:
14443 case OMP_CLAUSE_BIND:
14444 case OMP_CLAUSE_DETACH:
14445 case OMP_CLAUSE_USE_DEVICE_PTR:
14446 case OMP_CLAUSE_USE_DEVICE_ADDR:
14447 case OMP_CLAUSE_ASYNC:
14448 case OMP_CLAUSE_WAIT:
14449 case OMP_CLAUSE_INDEPENDENT:
14450 case OMP_CLAUSE_NUM_GANGS:
14451 case OMP_CLAUSE_NUM_WORKERS:
14452 case OMP_CLAUSE_VECTOR_LENGTH:
14453 case OMP_CLAUSE_GANG:
14454 case OMP_CLAUSE_WORKER:
14455 case OMP_CLAUSE_VECTOR:
14456 case OMP_CLAUSE_AUTO:
14457 case OMP_CLAUSE_SEQ:
14458 case OMP_CLAUSE_TILE:
14459 case OMP_CLAUSE_IF_PRESENT:
14460 case OMP_CLAUSE_FINALIZE:
14461 case OMP_CLAUSE_INCLUSIVE:
14462 case OMP_CLAUSE_EXCLUSIVE:
14463 break;
14465 case OMP_CLAUSE_NOHOST:
14466 default:
14467 gcc_unreachable ();
14470 if (remove)
14471 *list_p = OMP_CLAUSE_CHAIN (c);
14472 else if (move_attach)
14474 /* Remove attach node from here, separate out into its own list. */
14475 *attach_tail = c;
14476 *list_p = OMP_CLAUSE_CHAIN (c);
14477 OMP_CLAUSE_CHAIN (c) = NULL_TREE;
14478 attach_tail = &OMP_CLAUSE_CHAIN (c);
14480 else
14481 list_p = &OMP_CLAUSE_CHAIN (c);
14484 /* Splice attach nodes at the end of the list. */
14485 if (attach_list)
14487 *list_p = attach_list;
14488 list_p = attach_tail;
14491 /* Add in any implicit data sharing. */
14492 struct gimplify_adjust_omp_clauses_data data;
14493 if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0)
14495 /* OpenMP. Implicit clauses are added at the start of the clause list,
14496 but after any non-map clauses. */
14497 tree *implicit_add_list_p = orig_list_p;
14498 while (*implicit_add_list_p
14499 && OMP_CLAUSE_CODE (*implicit_add_list_p) != OMP_CLAUSE_MAP)
14500 implicit_add_list_p = &OMP_CLAUSE_CHAIN (*implicit_add_list_p);
14501 data.list_p = implicit_add_list_p;
14503 else
14504 /* OpenACC. */
14505 data.list_p = list_p;
14506 data.pre_p = pre_p;
14507 splay_tree_foreach (ctx->variables, gimplify_adjust_omp_clauses_1, &data);
14509 if (has_inscan_reductions)
14510 for (c = *orig_list_p; c; c = OMP_CLAUSE_CHAIN (c))
14511 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
14512 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
14514 error_at (OMP_CLAUSE_LOCATION (c),
14515 "%<inscan%> %<reduction%> clause used together with "
14516 "%<linear%> clause for a variable other than loop "
14517 "iterator");
14518 break;
14521 gimplify_omp_ctxp = ctx->outer_context;
14522 delete_omp_context (ctx);
14525 /* Return 0 if CONSTRUCTS selectors don't match the OpenMP context,
14526 -1 if unknown yet (simd is involved, won't be known until vectorization)
14527 and 1 if they do. If SCORES is non-NULL, it should point to an array
14528 of at least 2*NCONSTRUCTS+2 ints, and will be filled with the positions
14529 of the CONSTRUCTS (position -1 if it will never match) followed by
14530 number of constructs in the OpenMP context construct trait. If the
14531 score depends on whether it will be in a declare simd clone or not,
14532 the function returns 2 and there will be two sets of the scores, the first
14533 one for the case that it is not in a declare simd clone, the other
14534 that it is in a declare simd clone. */
14537 omp_construct_selector_matches (enum tree_code *constructs, int nconstructs,
14538 int *scores)
14540 int matched = 0, cnt = 0;
14541 bool simd_seen = false;
14542 bool target_seen = false;
14543 int declare_simd_cnt = -1;
14544 auto_vec<enum tree_code, 16> codes;
14545 for (struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; ctx;)
14547 if (((ctx->region_type & ORT_PARALLEL) && ctx->code == OMP_PARALLEL)
14548 || ((ctx->region_type & (ORT_TARGET | ORT_IMPLICIT_TARGET | ORT_ACC))
14549 == ORT_TARGET && ctx->code == OMP_TARGET)
14550 || ((ctx->region_type & ORT_TEAMS) && ctx->code == OMP_TEAMS)
14551 || (ctx->region_type == ORT_WORKSHARE && ctx->code == OMP_FOR)
14552 || (ctx->region_type == ORT_SIMD
14553 && ctx->code == OMP_SIMD
14554 && !omp_find_clause (ctx->clauses, OMP_CLAUSE_BIND)))
14556 ++cnt;
14557 if (scores)
14558 codes.safe_push (ctx->code);
14559 else if (matched < nconstructs && ctx->code == constructs[matched])
14561 if (ctx->code == OMP_SIMD)
14563 if (matched)
14564 return 0;
14565 simd_seen = true;
14567 ++matched;
14569 if (ctx->code == OMP_TARGET)
14571 if (scores == NULL)
14572 return matched < nconstructs ? 0 : simd_seen ? -1 : 1;
14573 target_seen = true;
14574 break;
14577 else if (ctx->region_type == ORT_WORKSHARE
14578 && ctx->code == OMP_LOOP
14579 && ctx->outer_context
14580 && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL
14581 && ctx->outer_context->outer_context
14582 && ctx->outer_context->outer_context->code == OMP_LOOP
14583 && ctx->outer_context->outer_context->distribute)
14584 ctx = ctx->outer_context->outer_context;
14585 ctx = ctx->outer_context;
14587 if (!target_seen
14588 && lookup_attribute ("omp declare simd",
14589 DECL_ATTRIBUTES (current_function_decl)))
14591 /* Declare simd is a maybe case, it is supposed to be added only to the
14592 omp-simd-clone.cc added clones and not to the base function. */
14593 declare_simd_cnt = cnt++;
14594 if (scores)
14595 codes.safe_push (OMP_SIMD);
14596 else if (cnt == 0
14597 && constructs[0] == OMP_SIMD)
14599 gcc_assert (matched == 0);
14600 simd_seen = true;
14601 if (++matched == nconstructs)
14602 return -1;
14605 if (tree attr = lookup_attribute ("omp declare variant variant",
14606 DECL_ATTRIBUTES (current_function_decl)))
14608 tree selectors = TREE_VALUE (attr);
14609 int variant_nconstructs = list_length (selectors);
14610 enum tree_code *variant_constructs = NULL;
14611 if (!target_seen && variant_nconstructs)
14613 variant_constructs
14614 = (enum tree_code *) alloca (variant_nconstructs
14615 * sizeof (enum tree_code));
14616 omp_construct_traits_to_codes (selectors, variant_nconstructs,
14617 variant_constructs);
14619 for (int i = 0; i < variant_nconstructs; i++)
14621 ++cnt;
14622 if (scores)
14623 codes.safe_push (variant_constructs[i]);
14624 else if (matched < nconstructs
14625 && variant_constructs[i] == constructs[matched])
14627 if (variant_constructs[i] == OMP_SIMD)
14629 if (matched)
14630 return 0;
14631 simd_seen = true;
14633 ++matched;
14637 if (!target_seen
14638 && lookup_attribute ("omp declare target block",
14639 DECL_ATTRIBUTES (current_function_decl)))
14641 if (scores)
14642 codes.safe_push (OMP_TARGET);
14643 else if (matched < nconstructs && constructs[matched] == OMP_TARGET)
14644 ++matched;
14646 if (scores)
14648 for (int pass = 0; pass < (declare_simd_cnt == -1 ? 1 : 2); pass++)
14650 int j = codes.length () - 1;
14651 for (int i = nconstructs - 1; i >= 0; i--)
14653 while (j >= 0
14654 && (pass != 0 || declare_simd_cnt != j)
14655 && constructs[i] != codes[j])
14656 --j;
14657 if (pass == 0 && declare_simd_cnt != -1 && j > declare_simd_cnt)
14658 *scores++ = j - 1;
14659 else
14660 *scores++ = j;
14662 *scores++ = ((pass == 0 && declare_simd_cnt != -1)
14663 ? codes.length () - 1 : codes.length ());
14665 return declare_simd_cnt == -1 ? 1 : 2;
14667 if (matched == nconstructs)
14668 return simd_seen ? -1 : 1;
14669 return 0;
14672 /* Gimplify OACC_CACHE. */
14674 static void
14675 gimplify_oacc_cache (tree *expr_p, gimple_seq *pre_p)
14677 tree expr = *expr_p;
14679 gimplify_scan_omp_clauses (&OACC_CACHE_CLAUSES (expr), pre_p, ORT_ACC,
14680 OACC_CACHE);
14681 gimplify_adjust_omp_clauses (pre_p, NULL, &OACC_CACHE_CLAUSES (expr),
14682 OACC_CACHE);
14684 /* TODO: Do something sensible with this information. */
14686 *expr_p = NULL_TREE;
14689 /* Helper function of gimplify_oacc_declare. The helper's purpose is to,
14690 if required, translate 'kind' in CLAUSE into an 'entry' kind and 'exit'
14691 kind. The entry kind will replace the one in CLAUSE, while the exit
14692 kind will be used in a new omp_clause and returned to the caller. */
14694 static tree
14695 gimplify_oacc_declare_1 (tree clause)
14697 HOST_WIDE_INT kind, new_op;
14698 bool ret = false;
14699 tree c = NULL;
14701 kind = OMP_CLAUSE_MAP_KIND (clause);
14703 switch (kind)
14705 case GOMP_MAP_ALLOC:
14706 new_op = GOMP_MAP_RELEASE;
14707 ret = true;
14708 break;
14710 case GOMP_MAP_FROM:
14711 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_FORCE_ALLOC);
14712 new_op = GOMP_MAP_FROM;
14713 ret = true;
14714 break;
14716 case GOMP_MAP_TOFROM:
14717 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_TO);
14718 new_op = GOMP_MAP_FROM;
14719 ret = true;
14720 break;
14722 case GOMP_MAP_DEVICE_RESIDENT:
14723 case GOMP_MAP_FORCE_DEVICEPTR:
14724 case GOMP_MAP_FORCE_PRESENT:
14725 case GOMP_MAP_LINK:
14726 case GOMP_MAP_POINTER:
14727 case GOMP_MAP_TO:
14728 break;
14730 default:
14731 gcc_unreachable ();
14732 break;
14735 if (ret)
14737 c = build_omp_clause (OMP_CLAUSE_LOCATION (clause), OMP_CLAUSE_MAP);
14738 OMP_CLAUSE_SET_MAP_KIND (c, new_op);
14739 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clause);
14742 return c;
14745 /* Gimplify OACC_DECLARE. */
14747 static void
14748 gimplify_oacc_declare (tree *expr_p, gimple_seq *pre_p)
14750 tree expr = *expr_p;
14751 gomp_target *stmt;
14752 tree clauses, t, decl;
14754 clauses = OACC_DECLARE_CLAUSES (expr);
14756 gimplify_scan_omp_clauses (&clauses, pre_p, ORT_TARGET_DATA, OACC_DECLARE);
14757 gimplify_adjust_omp_clauses (pre_p, NULL, &clauses, OACC_DECLARE);
14759 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
14761 decl = OMP_CLAUSE_DECL (t);
14763 if (TREE_CODE (decl) == MEM_REF)
14764 decl = TREE_OPERAND (decl, 0);
14766 if (VAR_P (decl) && !is_oacc_declared (decl))
14768 tree attr = get_identifier ("oacc declare target");
14769 DECL_ATTRIBUTES (decl) = tree_cons (attr, NULL_TREE,
14770 DECL_ATTRIBUTES (decl));
14773 if (VAR_P (decl)
14774 && !is_global_var (decl)
14775 && DECL_CONTEXT (decl) == current_function_decl)
14777 tree c = gimplify_oacc_declare_1 (t);
14778 if (c)
14780 if (oacc_declare_returns == NULL)
14781 oacc_declare_returns = new hash_map<tree, tree>;
14783 oacc_declare_returns->put (decl, c);
14787 if (gimplify_omp_ctxp)
14788 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_SEEN);
14791 stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
14792 clauses);
14794 gimplify_seq_add_stmt (pre_p, stmt);
14796 *expr_p = NULL_TREE;
14799 /* Gimplify the contents of an OMP_PARALLEL statement. This involves
14800 gimplification of the body, as well as scanning the body for used
14801 variables. We need to do this scan now, because variable-sized
14802 decls will be decomposed during gimplification. */
14804 static void
14805 gimplify_omp_parallel (tree *expr_p, gimple_seq *pre_p)
14807 tree expr = *expr_p;
14808 gimple *g;
14809 gimple_seq body = NULL;
14811 gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr), pre_p,
14812 OMP_PARALLEL_COMBINED (expr)
14813 ? ORT_COMBINED_PARALLEL
14814 : ORT_PARALLEL, OMP_PARALLEL);
14816 push_gimplify_context ();
14818 g = gimplify_and_return_first (OMP_PARALLEL_BODY (expr), &body);
14819 if (gimple_code (g) == GIMPLE_BIND)
14820 pop_gimplify_context (g);
14821 else
14822 pop_gimplify_context (NULL);
14824 gimplify_adjust_omp_clauses (pre_p, body, &OMP_PARALLEL_CLAUSES (expr),
14825 OMP_PARALLEL);
14827 g = gimple_build_omp_parallel (body,
14828 OMP_PARALLEL_CLAUSES (expr),
14829 NULL_TREE, NULL_TREE);
14830 if (OMP_PARALLEL_COMBINED (expr))
14831 gimple_omp_set_subcode (g, GF_OMP_PARALLEL_COMBINED);
14832 gimplify_seq_add_stmt (pre_p, g);
14833 *expr_p = NULL_TREE;
14836 /* Gimplify the contents of an OMP_TASK statement. This involves
14837 gimplification of the body, as well as scanning the body for used
14838 variables. We need to do this scan now, because variable-sized
14839 decls will be decomposed during gimplification. */
14841 static void
14842 gimplify_omp_task (tree *expr_p, gimple_seq *pre_p)
14844 tree expr = *expr_p;
14845 gimple *g;
14846 gimple_seq body = NULL;
14847 bool nowait = false;
14848 bool has_depend = false;
14850 if (OMP_TASK_BODY (expr) == NULL_TREE)
14852 for (tree c = OMP_TASK_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
14853 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
14855 has_depend = true;
14856 if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_MUTEXINOUTSET)
14858 error_at (OMP_CLAUSE_LOCATION (c),
14859 "%<mutexinoutset%> kind in %<depend%> clause on a "
14860 "%<taskwait%> construct");
14861 break;
14864 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NOWAIT)
14865 nowait = true;
14866 if (nowait && !has_depend)
14868 error_at (EXPR_LOCATION (expr),
14869 "%<taskwait%> construct with %<nowait%> clause but no "
14870 "%<depend%> clauses");
14871 *expr_p = NULL_TREE;
14872 return;
14876 gimplify_scan_omp_clauses (&OMP_TASK_CLAUSES (expr), pre_p,
14877 omp_find_clause (OMP_TASK_CLAUSES (expr),
14878 OMP_CLAUSE_UNTIED)
14879 ? ORT_UNTIED_TASK : ORT_TASK, OMP_TASK);
14881 if (OMP_TASK_BODY (expr))
14883 push_gimplify_context ();
14885 g = gimplify_and_return_first (OMP_TASK_BODY (expr), &body);
14886 if (gimple_code (g) == GIMPLE_BIND)
14887 pop_gimplify_context (g);
14888 else
14889 pop_gimplify_context (NULL);
14892 gimplify_adjust_omp_clauses (pre_p, body, &OMP_TASK_CLAUSES (expr),
14893 OMP_TASK);
14895 g = gimple_build_omp_task (body,
14896 OMP_TASK_CLAUSES (expr),
14897 NULL_TREE, NULL_TREE,
14898 NULL_TREE, NULL_TREE, NULL_TREE);
14899 if (OMP_TASK_BODY (expr) == NULL_TREE)
14900 gimple_omp_task_set_taskwait_p (g, true);
14901 gimplify_seq_add_stmt (pre_p, g);
14902 *expr_p = NULL_TREE;
14905 /* Helper function for gimplify_omp_for. If *TP is not a gimple constant,
14906 force it into a temporary initialized in PRE_P and add firstprivate clause
14907 to ORIG_FOR_STMT. */
14909 static void
14910 gimplify_omp_taskloop_expr (tree type, tree *tp, gimple_seq *pre_p,
14911 tree orig_for_stmt)
14913 if (*tp == NULL || is_gimple_constant (*tp))
14914 return;
14916 *tp = get_initialized_tmp_var (*tp, pre_p, NULL, false);
14917 /* Reference to pointer conversion is considered useless,
14918 but is significant for firstprivate clause. Force it
14919 here. */
14920 if (type
14921 && TREE_CODE (type) == POINTER_TYPE
14922 && TREE_CODE (TREE_TYPE (*tp)) == REFERENCE_TYPE)
14924 tree v = create_tmp_var (TYPE_MAIN_VARIANT (type));
14925 tree m = build2 (INIT_EXPR, TREE_TYPE (v), v, *tp);
14926 gimplify_and_add (m, pre_p);
14927 *tp = v;
14930 tree c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
14931 OMP_CLAUSE_DECL (c) = *tp;
14932 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
14933 OMP_FOR_CLAUSES (orig_for_stmt) = c;
14936 /* Helper function of gimplify_omp_for, find OMP_ORDERED with
14937 null OMP_ORDERED_BODY inside of OMP_FOR's body. */
14939 static tree
14940 find_standalone_omp_ordered (tree *tp, int *walk_subtrees, void *)
14942 switch (TREE_CODE (*tp))
14944 case OMP_ORDERED:
14945 if (OMP_ORDERED_BODY (*tp) == NULL_TREE)
14946 return *tp;
14947 break;
14948 case OMP_SIMD:
14949 case OMP_PARALLEL:
14950 case OMP_TARGET:
14951 *walk_subtrees = 0;
14952 break;
14953 default:
14954 break;
14956 return NULL_TREE;
14959 /* Gimplify the gross structure of an OMP_FOR statement. */
14961 static enum gimplify_status
14962 gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
14964 tree for_stmt, orig_for_stmt, inner_for_stmt = NULL_TREE, decl, var, t;
14965 enum gimplify_status ret = GS_ALL_DONE;
14966 enum gimplify_status tret;
14967 gomp_for *gfor;
14968 gimple_seq for_body, for_pre_body;
14969 int i;
14970 bitmap has_decl_expr = NULL;
14971 enum omp_region_type ort = ORT_WORKSHARE;
14972 bool openacc = TREE_CODE (*expr_p) == OACC_LOOP;
14974 orig_for_stmt = for_stmt = *expr_p;
14976 bool loop_p = (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_BIND)
14977 != NULL_TREE);
14978 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
14980 tree *data[4] = { NULL, NULL, NULL, NULL };
14981 gcc_assert (TREE_CODE (for_stmt) != OACC_LOOP);
14982 inner_for_stmt = walk_tree (&OMP_FOR_BODY (for_stmt),
14983 find_combined_omp_for, data, NULL);
14984 if (inner_for_stmt == NULL_TREE)
14986 gcc_assert (seen_error ());
14987 *expr_p = NULL_TREE;
14988 return GS_ERROR;
14990 if (data[2] && OMP_FOR_PRE_BODY (*data[2]))
14992 append_to_statement_list_force (OMP_FOR_PRE_BODY (*data[2]),
14993 &OMP_FOR_PRE_BODY (for_stmt));
14994 OMP_FOR_PRE_BODY (*data[2]) = NULL_TREE;
14996 if (OMP_FOR_PRE_BODY (inner_for_stmt))
14998 append_to_statement_list_force (OMP_FOR_PRE_BODY (inner_for_stmt),
14999 &OMP_FOR_PRE_BODY (for_stmt));
15000 OMP_FOR_PRE_BODY (inner_for_stmt) = NULL_TREE;
15003 if (data[0])
15005 /* We have some statements or variable declarations in between
15006 the composite construct directives. Move them around the
15007 inner_for_stmt. */
15008 data[0] = expr_p;
15009 for (i = 0; i < 3; i++)
15010 if (data[i])
15012 tree t = *data[i];
15013 if (i < 2 && data[i + 1] == &OMP_BODY (t))
15014 data[i + 1] = data[i];
15015 *data[i] = OMP_BODY (t);
15016 tree body = build3 (BIND_EXPR, void_type_node, NULL_TREE,
15017 NULL_TREE, make_node (BLOCK));
15018 OMP_BODY (t) = body;
15019 append_to_statement_list_force (inner_for_stmt,
15020 &BIND_EXPR_BODY (body));
15021 *data[3] = t;
15022 data[3] = tsi_stmt_ptr (tsi_start (BIND_EXPR_BODY (body)));
15023 gcc_assert (*data[3] == inner_for_stmt);
15025 return GS_OK;
15028 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
15029 if (!loop_p
15030 && OMP_FOR_ORIG_DECLS (inner_for_stmt)
15031 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
15032 i)) == TREE_LIST
15033 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
15034 i)))
15036 tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
15037 /* Class iterators aren't allowed on OMP_SIMD, so the only
15038 case we need to solve is distribute parallel for. They are
15039 allowed on the loop construct, but that is already handled
15040 in gimplify_omp_loop. */
15041 gcc_assert (TREE_CODE (inner_for_stmt) == OMP_FOR
15042 && TREE_CODE (for_stmt) == OMP_DISTRIBUTE
15043 && data[1]);
15044 tree orig_decl = TREE_PURPOSE (orig);
15045 tree last = TREE_VALUE (orig);
15046 tree *pc;
15047 for (pc = &OMP_FOR_CLAUSES (inner_for_stmt);
15048 *pc; pc = &OMP_CLAUSE_CHAIN (*pc))
15049 if ((OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE
15050 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LASTPRIVATE)
15051 && OMP_CLAUSE_DECL (*pc) == orig_decl)
15052 break;
15053 if (*pc == NULL_TREE)
15055 tree *spc;
15056 for (spc = &OMP_PARALLEL_CLAUSES (*data[1]);
15057 *spc; spc = &OMP_CLAUSE_CHAIN (*spc))
15058 if (OMP_CLAUSE_CODE (*spc) == OMP_CLAUSE_PRIVATE
15059 && OMP_CLAUSE_DECL (*spc) == orig_decl)
15060 break;
15061 if (*spc)
15063 tree c = *spc;
15064 *spc = OMP_CLAUSE_CHAIN (c);
15065 OMP_CLAUSE_CHAIN (c) = NULL_TREE;
15066 *pc = c;
15069 if (*pc == NULL_TREE)
15071 else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE)
15073 /* private clause will appear only on inner_for_stmt.
15074 Change it into firstprivate, and add private clause
15075 on for_stmt. */
15076 tree c = copy_node (*pc);
15077 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
15078 OMP_FOR_CLAUSES (for_stmt) = c;
15079 OMP_CLAUSE_CODE (*pc) = OMP_CLAUSE_FIRSTPRIVATE;
15080 lang_hooks.decls.omp_finish_clause (*pc, pre_p, openacc);
15082 else
15084 /* lastprivate clause will appear on both inner_for_stmt
15085 and for_stmt. Add firstprivate clause to
15086 inner_for_stmt. */
15087 tree c = build_omp_clause (OMP_CLAUSE_LOCATION (*pc),
15088 OMP_CLAUSE_FIRSTPRIVATE);
15089 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (*pc);
15090 OMP_CLAUSE_CHAIN (c) = *pc;
15091 *pc = c;
15092 lang_hooks.decls.omp_finish_clause (*pc, pre_p, openacc);
15094 tree c = build_omp_clause (UNKNOWN_LOCATION,
15095 OMP_CLAUSE_FIRSTPRIVATE);
15096 OMP_CLAUSE_DECL (c) = last;
15097 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
15098 OMP_PARALLEL_CLAUSES (*data[1]) = c;
15099 c = build_omp_clause (UNKNOWN_LOCATION,
15100 *pc ? OMP_CLAUSE_SHARED
15101 : OMP_CLAUSE_FIRSTPRIVATE);
15102 OMP_CLAUSE_DECL (c) = orig_decl;
15103 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
15104 OMP_PARALLEL_CLAUSES (*data[1]) = c;
15106 /* Similarly, take care of C++ range for temporaries, those should
15107 be firstprivate on OMP_PARALLEL if any. */
15108 if (data[1])
15109 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
15110 if (OMP_FOR_ORIG_DECLS (inner_for_stmt)
15111 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
15112 i)) == TREE_LIST
15113 && TREE_CHAIN (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
15114 i)))
15116 tree orig
15117 = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
15118 tree v = TREE_CHAIN (orig);
15119 tree c = build_omp_clause (UNKNOWN_LOCATION,
15120 OMP_CLAUSE_FIRSTPRIVATE);
15121 /* First add firstprivate clause for the __for_end artificial
15122 decl. */
15123 OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 1);
15124 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
15125 == REFERENCE_TYPE)
15126 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
15127 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
15128 OMP_PARALLEL_CLAUSES (*data[1]) = c;
15129 if (TREE_VEC_ELT (v, 0))
15131 /* And now the same for __for_range artificial decl if it
15132 exists. */
15133 c = build_omp_clause (UNKNOWN_LOCATION,
15134 OMP_CLAUSE_FIRSTPRIVATE);
15135 OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 0);
15136 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
15137 == REFERENCE_TYPE)
15138 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
15139 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
15140 OMP_PARALLEL_CLAUSES (*data[1]) = c;
15145 switch (TREE_CODE (for_stmt))
15147 case OMP_FOR:
15148 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt))
15150 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
15151 OMP_CLAUSE_SCHEDULE))
15152 error_at (EXPR_LOCATION (for_stmt),
15153 "%qs clause may not appear on non-rectangular %qs",
15154 "schedule", lang_GNU_Fortran () ? "do" : "for");
15155 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED))
15156 error_at (EXPR_LOCATION (for_stmt),
15157 "%qs clause may not appear on non-rectangular %qs",
15158 "ordered", lang_GNU_Fortran () ? "do" : "for");
15160 break;
15161 case OMP_DISTRIBUTE:
15162 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt)
15163 && omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
15164 OMP_CLAUSE_DIST_SCHEDULE))
15165 error_at (EXPR_LOCATION (for_stmt),
15166 "%qs clause may not appear on non-rectangular %qs",
15167 "dist_schedule", "distribute");
15168 break;
15169 case OACC_LOOP:
15170 ort = ORT_ACC;
15171 break;
15172 case OMP_TASKLOOP:
15173 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt))
15175 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
15176 OMP_CLAUSE_GRAINSIZE))
15177 error_at (EXPR_LOCATION (for_stmt),
15178 "%qs clause may not appear on non-rectangular %qs",
15179 "grainsize", "taskloop");
15180 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
15181 OMP_CLAUSE_NUM_TASKS))
15182 error_at (EXPR_LOCATION (for_stmt),
15183 "%qs clause may not appear on non-rectangular %qs",
15184 "num_tasks", "taskloop");
15186 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_UNTIED))
15187 ort = ORT_UNTIED_TASKLOOP;
15188 else
15189 ort = ORT_TASKLOOP;
15190 break;
15191 case OMP_SIMD:
15192 ort = ORT_SIMD;
15193 break;
15194 default:
15195 gcc_unreachable ();
15198 /* Set OMP_CLAUSE_LINEAR_NO_COPYIN flag on explicit linear
15199 clause for the IV. */
15200 if (ort == ORT_SIMD && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
15202 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), 0);
15203 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
15204 decl = TREE_OPERAND (t, 0);
15205 for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
15206 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
15207 && OMP_CLAUSE_DECL (c) == decl)
15209 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
15210 break;
15214 if (TREE_CODE (for_stmt) != OMP_TASKLOOP)
15215 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p, ort,
15216 loop_p && TREE_CODE (for_stmt) != OMP_SIMD
15217 ? OMP_LOOP : TREE_CODE (for_stmt));
15219 if (TREE_CODE (for_stmt) == OMP_DISTRIBUTE)
15220 gimplify_omp_ctxp->distribute = true;
15222 /* Handle OMP_FOR_INIT. */
15223 for_pre_body = NULL;
15224 if ((ort == ORT_SIMD
15225 || (inner_for_stmt && TREE_CODE (inner_for_stmt) == OMP_SIMD))
15226 && OMP_FOR_PRE_BODY (for_stmt))
15228 has_decl_expr = BITMAP_ALLOC (NULL);
15229 if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == DECL_EXPR
15230 && VAR_P (DECL_EXPR_DECL (OMP_FOR_PRE_BODY (for_stmt))))
15232 t = OMP_FOR_PRE_BODY (for_stmt);
15233 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
15235 else if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == STATEMENT_LIST)
15237 tree_stmt_iterator si;
15238 for (si = tsi_start (OMP_FOR_PRE_BODY (for_stmt)); !tsi_end_p (si);
15239 tsi_next (&si))
15241 t = tsi_stmt (si);
15242 if (TREE_CODE (t) == DECL_EXPR
15243 && VAR_P (DECL_EXPR_DECL (t)))
15244 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
15248 if (OMP_FOR_PRE_BODY (for_stmt))
15250 if (TREE_CODE (for_stmt) != OMP_TASKLOOP || gimplify_omp_ctxp)
15251 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
15252 else
15254 struct gimplify_omp_ctx ctx;
15255 memset (&ctx, 0, sizeof (ctx));
15256 ctx.region_type = ORT_NONE;
15257 gimplify_omp_ctxp = &ctx;
15258 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
15259 gimplify_omp_ctxp = NULL;
15262 OMP_FOR_PRE_BODY (for_stmt) = NULL_TREE;
15264 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
15265 for_stmt = inner_for_stmt;
15267 /* For taskloop, need to gimplify the start, end and step before the
15268 taskloop, outside of the taskloop omp context. */
15269 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
15271 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
15273 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
15274 gimple_seq *for_pre_p = (gimple_seq_empty_p (for_pre_body)
15275 ? pre_p : &for_pre_body);
15276 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
15277 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
15279 tree v = TREE_OPERAND (t, 1);
15280 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 1),
15281 for_pre_p, orig_for_stmt);
15282 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 2),
15283 for_pre_p, orig_for_stmt);
15285 else
15286 gimplify_omp_taskloop_expr (type, &TREE_OPERAND (t, 1), for_pre_p,
15287 orig_for_stmt);
15289 /* Handle OMP_FOR_COND. */
15290 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
15291 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
15293 tree v = TREE_OPERAND (t, 1);
15294 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 1),
15295 for_pre_p, orig_for_stmt);
15296 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 2),
15297 for_pre_p, orig_for_stmt);
15299 else
15300 gimplify_omp_taskloop_expr (type, &TREE_OPERAND (t, 1), for_pre_p,
15301 orig_for_stmt);
15303 /* Handle OMP_FOR_INCR. */
15304 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
15305 if (TREE_CODE (t) == MODIFY_EXPR)
15307 decl = TREE_OPERAND (t, 0);
15308 t = TREE_OPERAND (t, 1);
15309 tree *tp = &TREE_OPERAND (t, 1);
15310 if (TREE_CODE (t) == PLUS_EXPR && *tp == decl)
15311 tp = &TREE_OPERAND (t, 0);
15313 gimplify_omp_taskloop_expr (NULL_TREE, tp, for_pre_p,
15314 orig_for_stmt);
15318 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (orig_for_stmt), pre_p, ort,
15319 OMP_TASKLOOP);
15322 if (orig_for_stmt != for_stmt)
15323 gimplify_omp_ctxp->combined_loop = true;
15325 for_body = NULL;
15326 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
15327 == TREE_VEC_LENGTH (OMP_FOR_COND (for_stmt)));
15328 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
15329 == TREE_VEC_LENGTH (OMP_FOR_INCR (for_stmt)));
15331 tree c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED);
15332 bool is_doacross = false;
15333 if (c && walk_tree_without_duplicates (&OMP_FOR_BODY (for_stmt),
15334 find_standalone_omp_ordered, NULL))
15336 OMP_CLAUSE_ORDERED_DOACROSS (c) = 1;
15337 is_doacross = true;
15338 int len = TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt));
15339 gimplify_omp_ctxp->loop_iter_var.create (len * 2);
15340 for (tree *pc = &OMP_FOR_CLAUSES (for_stmt); *pc; )
15341 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LINEAR)
15343 error_at (OMP_CLAUSE_LOCATION (*pc),
15344 "%<linear%> clause may not be specified together "
15345 "with %<ordered%> clause if stand-alone %<ordered%> "
15346 "construct is nested in it");
15347 *pc = OMP_CLAUSE_CHAIN (*pc);
15349 else
15350 pc = &OMP_CLAUSE_CHAIN (*pc);
15352 int collapse = 1, tile = 0;
15353 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_COLLAPSE);
15354 if (c)
15355 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (c));
15356 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_TILE);
15357 if (c)
15358 tile = list_length (OMP_CLAUSE_TILE_LIST (c));
15359 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ALLOCATE);
15360 hash_set<tree> *allocate_uids = NULL;
15361 if (c)
15363 allocate_uids = new hash_set<tree>;
15364 for (; c; c = OMP_CLAUSE_CHAIN (c))
15365 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ALLOCATE)
15366 allocate_uids->add (OMP_CLAUSE_DECL (c));
15368 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
15370 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
15371 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
15372 decl = TREE_OPERAND (t, 0);
15373 gcc_assert (DECL_P (decl));
15374 gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl))
15375 || POINTER_TYPE_P (TREE_TYPE (decl)));
15376 if (is_doacross)
15378 if (TREE_CODE (for_stmt) == OMP_FOR && OMP_FOR_ORIG_DECLS (for_stmt))
15380 tree orig_decl = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
15381 if (TREE_CODE (orig_decl) == TREE_LIST)
15383 orig_decl = TREE_PURPOSE (orig_decl);
15384 if (!orig_decl)
15385 orig_decl = decl;
15387 gimplify_omp_ctxp->loop_iter_var.quick_push (orig_decl);
15389 else
15390 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
15391 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
15394 if (for_stmt == orig_for_stmt)
15396 tree orig_decl = decl;
15397 if (OMP_FOR_ORIG_DECLS (for_stmt))
15399 tree orig_decl = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
15400 if (TREE_CODE (orig_decl) == TREE_LIST)
15402 orig_decl = TREE_PURPOSE (orig_decl);
15403 if (!orig_decl)
15404 orig_decl = decl;
15407 if (is_global_var (orig_decl) && DECL_THREAD_LOCAL_P (orig_decl))
15408 error_at (EXPR_LOCATION (for_stmt),
15409 "threadprivate iteration variable %qD", orig_decl);
15412 /* Make sure the iteration variable is private. */
15413 tree c = NULL_TREE;
15414 tree c2 = NULL_TREE;
15415 if (orig_for_stmt != for_stmt)
15417 /* Preserve this information until we gimplify the inner simd. */
15418 if (has_decl_expr
15419 && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
15420 TREE_PRIVATE (t) = 1;
15422 else if (ort == ORT_SIMD)
15424 splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
15425 (splay_tree_key) decl);
15426 omp_is_private (gimplify_omp_ctxp, decl,
15427 1 + (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
15428 != 1));
15429 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
15431 omp_notice_variable (gimplify_omp_ctxp, decl, true);
15432 if (n->value & GOVD_LASTPRIVATE_CONDITIONAL)
15433 for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
15434 OMP_CLAUSE_LASTPRIVATE);
15435 c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
15436 OMP_CLAUSE_LASTPRIVATE))
15437 if (OMP_CLAUSE_DECL (c3) == decl)
15439 warning_at (OMP_CLAUSE_LOCATION (c3), OPT_Wopenmp,
15440 "conditional %<lastprivate%> on loop "
15441 "iterator %qD ignored", decl);
15442 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
15443 n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
15446 else if (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1 && !loop_p)
15448 c = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
15449 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
15450 unsigned int flags = GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN;
15451 if ((has_decl_expr
15452 && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
15453 || TREE_PRIVATE (t))
15455 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
15456 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
15458 struct gimplify_omp_ctx *outer
15459 = gimplify_omp_ctxp->outer_context;
15460 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
15462 if (outer->region_type == ORT_WORKSHARE
15463 && outer->combined_loop)
15465 n = splay_tree_lookup (outer->variables,
15466 (splay_tree_key)decl);
15467 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
15469 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
15470 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
15472 else
15474 struct gimplify_omp_ctx *octx = outer->outer_context;
15475 if (octx
15476 && octx->region_type == ORT_COMBINED_PARALLEL
15477 && octx->outer_context
15478 && (octx->outer_context->region_type
15479 == ORT_WORKSHARE)
15480 && octx->outer_context->combined_loop)
15482 octx = octx->outer_context;
15483 n = splay_tree_lookup (octx->variables,
15484 (splay_tree_key)decl);
15485 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
15487 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
15488 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
15495 OMP_CLAUSE_DECL (c) = decl;
15496 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
15497 OMP_FOR_CLAUSES (for_stmt) = c;
15498 omp_add_variable (gimplify_omp_ctxp, decl, flags);
15499 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
15500 omp_lastprivate_for_combined_outer_constructs (outer, decl,
15501 true);
15503 else
15505 bool lastprivate
15506 = (!has_decl_expr
15507 || !bitmap_bit_p (has_decl_expr, DECL_UID (decl)));
15508 if (TREE_PRIVATE (t))
15509 lastprivate = false;
15510 if (loop_p && OMP_FOR_ORIG_DECLS (for_stmt))
15512 tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
15513 if (TREE_CODE (elt) == TREE_LIST && TREE_PURPOSE (elt))
15514 lastprivate = false;
15517 struct gimplify_omp_ctx *outer
15518 = gimplify_omp_ctxp->outer_context;
15519 if (outer && lastprivate)
15520 omp_lastprivate_for_combined_outer_constructs (outer, decl,
15521 true);
15523 c = build_omp_clause (input_location,
15524 lastprivate ? OMP_CLAUSE_LASTPRIVATE
15525 : OMP_CLAUSE_PRIVATE);
15526 OMP_CLAUSE_DECL (c) = decl;
15527 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
15528 OMP_FOR_CLAUSES (for_stmt) = c;
15529 omp_add_variable (gimplify_omp_ctxp, decl,
15530 (lastprivate ? GOVD_LASTPRIVATE : GOVD_PRIVATE)
15531 | GOVD_EXPLICIT | GOVD_SEEN);
15532 c = NULL_TREE;
15535 else if (omp_is_private (gimplify_omp_ctxp, decl, 0))
15537 omp_notice_variable (gimplify_omp_ctxp, decl, true);
15538 splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
15539 (splay_tree_key) decl);
15540 if (n && (n->value & GOVD_LASTPRIVATE_CONDITIONAL))
15541 for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
15542 OMP_CLAUSE_LASTPRIVATE);
15543 c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
15544 OMP_CLAUSE_LASTPRIVATE))
15545 if (OMP_CLAUSE_DECL (c3) == decl)
15547 warning_at (OMP_CLAUSE_LOCATION (c3), OPT_Wopenmp,
15548 "conditional %<lastprivate%> on loop "
15549 "iterator %qD ignored", decl);
15550 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
15551 n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
15554 else
15555 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN);
15557 /* If DECL is not a gimple register, create a temporary variable to act
15558 as an iteration counter. This is valid, since DECL cannot be
15559 modified in the body of the loop. Similarly for any iteration vars
15560 in simd with collapse > 1 where the iterator vars must be
15561 lastprivate. And similarly for vars mentioned in allocate clauses. */
15562 if (orig_for_stmt != for_stmt)
15563 var = decl;
15564 else if (!is_gimple_reg (decl)
15565 || (ort == ORT_SIMD
15566 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) > 1)
15567 || (allocate_uids && allocate_uids->contains (decl)))
15569 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
15570 /* Make sure omp_add_variable is not called on it prematurely.
15571 We call it ourselves a few lines later. */
15572 gimplify_omp_ctxp = NULL;
15573 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
15574 gimplify_omp_ctxp = ctx;
15575 TREE_OPERAND (t, 0) = var;
15577 gimplify_seq_add_stmt (&for_body, gimple_build_assign (decl, var));
15579 if (ort == ORT_SIMD
15580 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
15582 c2 = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
15583 OMP_CLAUSE_LINEAR_NO_COPYIN (c2) = 1;
15584 OMP_CLAUSE_LINEAR_NO_COPYOUT (c2) = 1;
15585 OMP_CLAUSE_DECL (c2) = var;
15586 OMP_CLAUSE_CHAIN (c2) = OMP_FOR_CLAUSES (for_stmt);
15587 OMP_FOR_CLAUSES (for_stmt) = c2;
15588 omp_add_variable (gimplify_omp_ctxp, var,
15589 GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN);
15590 if (c == NULL_TREE)
15592 c = c2;
15593 c2 = NULL_TREE;
15596 else
15597 omp_add_variable (gimplify_omp_ctxp, var,
15598 GOVD_PRIVATE | GOVD_SEEN);
15600 else
15601 var = decl;
15603 gimplify_omp_ctxp->in_for_exprs = true;
15604 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
15606 tree lb = TREE_OPERAND (t, 1);
15607 tret = gimplify_expr (&TREE_VEC_ELT (lb, 1), &for_pre_body, NULL,
15608 is_gimple_val, fb_rvalue, false);
15609 ret = MIN (ret, tret);
15610 tret = gimplify_expr (&TREE_VEC_ELT (lb, 2), &for_pre_body, NULL,
15611 is_gimple_val, fb_rvalue, false);
15613 else
15614 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
15615 is_gimple_val, fb_rvalue, false);
15616 gimplify_omp_ctxp->in_for_exprs = false;
15617 ret = MIN (ret, tret);
15618 if (ret == GS_ERROR)
15619 return ret;
15621 /* Handle OMP_FOR_COND. */
15622 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
15623 gcc_assert (COMPARISON_CLASS_P (t));
15624 gcc_assert (TREE_OPERAND (t, 0) == decl);
15626 gimplify_omp_ctxp->in_for_exprs = true;
15627 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
15629 tree ub = TREE_OPERAND (t, 1);
15630 tret = gimplify_expr (&TREE_VEC_ELT (ub, 1), &for_pre_body, NULL,
15631 is_gimple_val, fb_rvalue, false);
15632 ret = MIN (ret, tret);
15633 tret = gimplify_expr (&TREE_VEC_ELT (ub, 2), &for_pre_body, NULL,
15634 is_gimple_val, fb_rvalue, false);
15636 else
15637 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
15638 is_gimple_val, fb_rvalue, false);
15639 gimplify_omp_ctxp->in_for_exprs = false;
15640 ret = MIN (ret, tret);
15642 /* Handle OMP_FOR_INCR. */
15643 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
15644 switch (TREE_CODE (t))
15646 case PREINCREMENT_EXPR:
15647 case POSTINCREMENT_EXPR:
15649 tree decl = TREE_OPERAND (t, 0);
15650 /* c_omp_for_incr_canonicalize_ptr() should have been
15651 called to massage things appropriately. */
15652 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
15654 if (orig_for_stmt != for_stmt)
15655 break;
15656 t = build_int_cst (TREE_TYPE (decl), 1);
15657 if (c)
15658 OMP_CLAUSE_LINEAR_STEP (c) = t;
15659 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
15660 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
15661 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
15662 break;
15665 case PREDECREMENT_EXPR:
15666 case POSTDECREMENT_EXPR:
15667 /* c_omp_for_incr_canonicalize_ptr() should have been
15668 called to massage things appropriately. */
15669 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
15670 if (orig_for_stmt != for_stmt)
15671 break;
15672 t = build_int_cst (TREE_TYPE (decl), -1);
15673 if (c)
15674 OMP_CLAUSE_LINEAR_STEP (c) = t;
15675 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
15676 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
15677 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
15678 break;
15680 case MODIFY_EXPR:
15681 gcc_assert (TREE_OPERAND (t, 0) == decl);
15682 TREE_OPERAND (t, 0) = var;
15684 t = TREE_OPERAND (t, 1);
15685 switch (TREE_CODE (t))
15687 case PLUS_EXPR:
15688 if (TREE_OPERAND (t, 1) == decl)
15690 TREE_OPERAND (t, 1) = TREE_OPERAND (t, 0);
15691 TREE_OPERAND (t, 0) = var;
15692 break;
15695 /* Fallthru. */
15696 case MINUS_EXPR:
15697 case POINTER_PLUS_EXPR:
15698 gcc_assert (TREE_OPERAND (t, 0) == decl);
15699 TREE_OPERAND (t, 0) = var;
15700 break;
15701 default:
15702 gcc_unreachable ();
15705 gimplify_omp_ctxp->in_for_exprs = true;
15706 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
15707 is_gimple_val, fb_rvalue, false);
15708 ret = MIN (ret, tret);
15709 if (c)
15711 tree step = TREE_OPERAND (t, 1);
15712 tree stept = TREE_TYPE (decl);
15713 if (POINTER_TYPE_P (stept))
15714 stept = sizetype;
15715 step = fold_convert (stept, step);
15716 if (TREE_CODE (t) == MINUS_EXPR)
15717 step = fold_build1 (NEGATE_EXPR, stept, step);
15718 OMP_CLAUSE_LINEAR_STEP (c) = step;
15719 if (step != TREE_OPERAND (t, 1))
15721 tret = gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c),
15722 &for_pre_body, NULL,
15723 is_gimple_val, fb_rvalue, false);
15724 ret = MIN (ret, tret);
15727 gimplify_omp_ctxp->in_for_exprs = false;
15728 break;
15730 default:
15731 gcc_unreachable ();
15734 if (c2)
15736 gcc_assert (c);
15737 OMP_CLAUSE_LINEAR_STEP (c2) = OMP_CLAUSE_LINEAR_STEP (c);
15740 if ((var != decl || collapse > 1 || tile) && orig_for_stmt == for_stmt)
15742 for (c = OMP_FOR_CLAUSES (for_stmt); c ; c = OMP_CLAUSE_CHAIN (c))
15743 if (((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
15744 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) == NULL)
15745 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
15746 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)
15747 && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c) == NULL))
15748 && OMP_CLAUSE_DECL (c) == decl)
15750 if (is_doacross && (collapse == 1 || i >= collapse))
15751 t = var;
15752 else
15754 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
15755 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
15756 gcc_assert (TREE_OPERAND (t, 0) == var);
15757 t = TREE_OPERAND (t, 1);
15758 gcc_assert (TREE_CODE (t) == PLUS_EXPR
15759 || TREE_CODE (t) == MINUS_EXPR
15760 || TREE_CODE (t) == POINTER_PLUS_EXPR);
15761 gcc_assert (TREE_OPERAND (t, 0) == var);
15762 t = build2 (TREE_CODE (t), TREE_TYPE (decl),
15763 is_doacross ? var : decl,
15764 TREE_OPERAND (t, 1));
15766 gimple_seq *seq;
15767 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
15768 seq = &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c);
15769 else
15770 seq = &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c);
15771 push_gimplify_context ();
15772 gimplify_assign (decl, t, seq);
15773 gimple *bind = NULL;
15774 if (gimplify_ctxp->temps)
15776 bind = gimple_build_bind (NULL_TREE, *seq, NULL_TREE);
15777 *seq = NULL;
15778 gimplify_seq_add_stmt (seq, bind);
15780 pop_gimplify_context (bind);
15783 if (OMP_FOR_NON_RECTANGULAR (for_stmt) && var != decl)
15784 for (int j = i + 1; j < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); j++)
15786 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), j);
15787 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
15788 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
15789 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
15790 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
15791 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), j);
15792 gcc_assert (COMPARISON_CLASS_P (t));
15793 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
15794 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
15795 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
15799 BITMAP_FREE (has_decl_expr);
15800 delete allocate_uids;
15802 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP
15803 || (loop_p && orig_for_stmt == for_stmt))
15805 push_gimplify_context ();
15806 if (TREE_CODE (OMP_FOR_BODY (orig_for_stmt)) != BIND_EXPR)
15808 OMP_FOR_BODY (orig_for_stmt)
15809 = build3 (BIND_EXPR, void_type_node, NULL,
15810 OMP_FOR_BODY (orig_for_stmt), NULL);
15811 TREE_SIDE_EFFECTS (OMP_FOR_BODY (orig_for_stmt)) = 1;
15815 gimple *g = gimplify_and_return_first (OMP_FOR_BODY (orig_for_stmt),
15816 &for_body);
15818 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP
15819 || (loop_p && orig_for_stmt == for_stmt))
15821 if (gimple_code (g) == GIMPLE_BIND)
15822 pop_gimplify_context (g);
15823 else
15824 pop_gimplify_context (NULL);
15827 if (orig_for_stmt != for_stmt)
15828 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
15830 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
15831 decl = TREE_OPERAND (t, 0);
15832 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
15833 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
15834 gimplify_omp_ctxp = ctx->outer_context;
15835 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
15836 gimplify_omp_ctxp = ctx;
15837 omp_add_variable (gimplify_omp_ctxp, var, GOVD_PRIVATE | GOVD_SEEN);
15838 TREE_OPERAND (t, 0) = var;
15839 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
15840 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
15841 TREE_OPERAND (TREE_OPERAND (t, 1), 0) = var;
15842 if (OMP_FOR_NON_RECTANGULAR (for_stmt))
15843 for (int j = i + 1;
15844 j < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); j++)
15846 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), j);
15847 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
15848 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
15849 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
15851 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
15852 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
15854 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), j);
15855 gcc_assert (COMPARISON_CLASS_P (t));
15856 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
15857 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
15859 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
15860 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
15865 gimplify_adjust_omp_clauses (pre_p, for_body,
15866 &OMP_FOR_CLAUSES (orig_for_stmt),
15867 TREE_CODE (orig_for_stmt));
15869 int kind;
15870 switch (TREE_CODE (orig_for_stmt))
15872 case OMP_FOR: kind = GF_OMP_FOR_KIND_FOR; break;
15873 case OMP_SIMD: kind = GF_OMP_FOR_KIND_SIMD; break;
15874 case OMP_DISTRIBUTE: kind = GF_OMP_FOR_KIND_DISTRIBUTE; break;
15875 case OMP_TASKLOOP: kind = GF_OMP_FOR_KIND_TASKLOOP; break;
15876 case OACC_LOOP: kind = GF_OMP_FOR_KIND_OACC_LOOP; break;
15877 default:
15878 gcc_unreachable ();
15880 if (loop_p && kind == GF_OMP_FOR_KIND_SIMD)
15882 gimplify_seq_add_seq (pre_p, for_pre_body);
15883 for_pre_body = NULL;
15885 gfor = gimple_build_omp_for (for_body, kind, OMP_FOR_CLAUSES (orig_for_stmt),
15886 TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)),
15887 for_pre_body);
15888 if (orig_for_stmt != for_stmt)
15889 gimple_omp_for_set_combined_p (gfor, true);
15890 if (gimplify_omp_ctxp
15891 && (gimplify_omp_ctxp->combined_loop
15892 || (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
15893 && gimplify_omp_ctxp->outer_context
15894 && gimplify_omp_ctxp->outer_context->combined_loop)))
15896 gimple_omp_for_set_combined_into_p (gfor, true);
15897 if (gimplify_omp_ctxp->combined_loop)
15898 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_SIMD);
15899 else
15900 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_FOR);
15903 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
15905 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
15906 gimple_omp_for_set_index (gfor, i, TREE_OPERAND (t, 0));
15907 gimple_omp_for_set_initial (gfor, i, TREE_OPERAND (t, 1));
15908 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
15909 gimple_omp_for_set_cond (gfor, i, TREE_CODE (t));
15910 gimple_omp_for_set_final (gfor, i, TREE_OPERAND (t, 1));
15911 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
15912 gimple_omp_for_set_incr (gfor, i, TREE_OPERAND (t, 1));
15915 /* OMP_TASKLOOP is gimplified as two GIMPLE_OMP_FOR taskloop
15916 constructs with GIMPLE_OMP_TASK sandwiched in between them.
15917 The outer taskloop stands for computing the number of iterations,
15918 counts for collapsed loops and holding taskloop specific clauses.
15919 The task construct stands for the effect of data sharing on the
15920 explicit task it creates and the inner taskloop stands for expansion
15921 of the static loop inside of the explicit task construct. */
15922 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
15924 tree *gfor_clauses_ptr = gimple_omp_for_clauses_ptr (gfor);
15925 tree task_clauses = NULL_TREE;
15926 tree c = *gfor_clauses_ptr;
15927 tree *gtask_clauses_ptr = &task_clauses;
15928 tree outer_for_clauses = NULL_TREE;
15929 tree *gforo_clauses_ptr = &outer_for_clauses;
15930 bitmap lastprivate_uids = NULL;
15931 if (omp_find_clause (c, OMP_CLAUSE_ALLOCATE))
15933 c = omp_find_clause (c, OMP_CLAUSE_LASTPRIVATE);
15934 if (c)
15936 lastprivate_uids = BITMAP_ALLOC (NULL);
15937 for (; c; c = omp_find_clause (OMP_CLAUSE_CHAIN (c),
15938 OMP_CLAUSE_LASTPRIVATE))
15939 bitmap_set_bit (lastprivate_uids,
15940 DECL_UID (OMP_CLAUSE_DECL (c)));
15942 c = *gfor_clauses_ptr;
15944 for (; c; c = OMP_CLAUSE_CHAIN (c))
15945 switch (OMP_CLAUSE_CODE (c))
15947 /* These clauses are allowed on task, move them there. */
15948 case OMP_CLAUSE_SHARED:
15949 case OMP_CLAUSE_FIRSTPRIVATE:
15950 case OMP_CLAUSE_DEFAULT:
15951 case OMP_CLAUSE_IF:
15952 case OMP_CLAUSE_UNTIED:
15953 case OMP_CLAUSE_FINAL:
15954 case OMP_CLAUSE_MERGEABLE:
15955 case OMP_CLAUSE_PRIORITY:
15956 case OMP_CLAUSE_REDUCTION:
15957 case OMP_CLAUSE_IN_REDUCTION:
15958 *gtask_clauses_ptr = c;
15959 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
15960 break;
15961 case OMP_CLAUSE_PRIVATE:
15962 if (OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c))
15964 /* We want private on outer for and firstprivate
15965 on task. */
15966 *gtask_clauses_ptr
15967 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
15968 OMP_CLAUSE_FIRSTPRIVATE);
15969 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
15970 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL,
15971 openacc);
15972 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
15973 *gforo_clauses_ptr = c;
15974 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
15976 else
15978 *gtask_clauses_ptr = c;
15979 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
15981 break;
15982 /* These clauses go into outer taskloop clauses. */
15983 case OMP_CLAUSE_GRAINSIZE:
15984 case OMP_CLAUSE_NUM_TASKS:
15985 case OMP_CLAUSE_NOGROUP:
15986 *gforo_clauses_ptr = c;
15987 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
15988 break;
15989 /* Collapse clause we duplicate on both taskloops. */
15990 case OMP_CLAUSE_COLLAPSE:
15991 *gfor_clauses_ptr = c;
15992 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
15993 *gforo_clauses_ptr = copy_node (c);
15994 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
15995 break;
15996 /* For lastprivate, keep the clause on inner taskloop, and add
15997 a shared clause on task. If the same decl is also firstprivate,
15998 add also firstprivate clause on the inner taskloop. */
15999 case OMP_CLAUSE_LASTPRIVATE:
16000 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
16002 /* For taskloop C++ lastprivate IVs, we want:
16003 1) private on outer taskloop
16004 2) firstprivate and shared on task
16005 3) lastprivate on inner taskloop */
16006 *gtask_clauses_ptr
16007 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
16008 OMP_CLAUSE_FIRSTPRIVATE);
16009 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
16010 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL,
16011 openacc);
16012 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
16013 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c) = 1;
16014 *gforo_clauses_ptr = build_omp_clause (OMP_CLAUSE_LOCATION (c),
16015 OMP_CLAUSE_PRIVATE);
16016 OMP_CLAUSE_DECL (*gforo_clauses_ptr) = OMP_CLAUSE_DECL (c);
16017 OMP_CLAUSE_PRIVATE_TASKLOOP_IV (*gforo_clauses_ptr) = 1;
16018 TREE_TYPE (*gforo_clauses_ptr) = TREE_TYPE (c);
16019 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
16021 *gfor_clauses_ptr = c;
16022 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
16023 *gtask_clauses_ptr
16024 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_SHARED);
16025 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
16026 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
16027 OMP_CLAUSE_SHARED_FIRSTPRIVATE (*gtask_clauses_ptr) = 1;
16028 gtask_clauses_ptr
16029 = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
16030 break;
16031 /* Allocate clause we duplicate on task and inner taskloop
16032 if the decl is lastprivate, otherwise just put on task. */
16033 case OMP_CLAUSE_ALLOCATE:
16034 if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
16035 && DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)))
16037 /* Additionally, put firstprivate clause on task
16038 for the allocator if it is not constant. */
16039 *gtask_clauses_ptr
16040 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
16041 OMP_CLAUSE_FIRSTPRIVATE);
16042 OMP_CLAUSE_DECL (*gtask_clauses_ptr)
16043 = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
16044 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
16046 if (lastprivate_uids
16047 && bitmap_bit_p (lastprivate_uids,
16048 DECL_UID (OMP_CLAUSE_DECL (c))))
16050 *gfor_clauses_ptr = c;
16051 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
16052 *gtask_clauses_ptr = copy_node (c);
16053 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
16055 else
16057 *gtask_clauses_ptr = c;
16058 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
16060 break;
16061 default:
16062 gcc_unreachable ();
16064 *gfor_clauses_ptr = NULL_TREE;
16065 *gtask_clauses_ptr = NULL_TREE;
16066 *gforo_clauses_ptr = NULL_TREE;
16067 BITMAP_FREE (lastprivate_uids);
16068 gimple_set_location (gfor, input_location);
16069 g = gimple_build_bind (NULL_TREE, gfor, NULL_TREE);
16070 g = gimple_build_omp_task (g, task_clauses, NULL_TREE, NULL_TREE,
16071 NULL_TREE, NULL_TREE, NULL_TREE);
16072 gimple_set_location (g, input_location);
16073 gimple_omp_task_set_taskloop_p (g, true);
16074 g = gimple_build_bind (NULL_TREE, g, NULL_TREE);
16075 gomp_for *gforo
16076 = gimple_build_omp_for (g, GF_OMP_FOR_KIND_TASKLOOP, outer_for_clauses,
16077 gimple_omp_for_collapse (gfor),
16078 gimple_omp_for_pre_body (gfor));
16079 gimple_omp_for_set_pre_body (gfor, NULL);
16080 gimple_omp_for_set_combined_p (gforo, true);
16081 gimple_omp_for_set_combined_into_p (gfor, true);
16082 for (i = 0; i < (int) gimple_omp_for_collapse (gfor); i++)
16084 tree type = TREE_TYPE (gimple_omp_for_index (gfor, i));
16085 tree v = create_tmp_var (type);
16086 gimple_omp_for_set_index (gforo, i, v);
16087 t = unshare_expr (gimple_omp_for_initial (gfor, i));
16088 gimple_omp_for_set_initial (gforo, i, t);
16089 gimple_omp_for_set_cond (gforo, i,
16090 gimple_omp_for_cond (gfor, i));
16091 t = unshare_expr (gimple_omp_for_final (gfor, i));
16092 gimple_omp_for_set_final (gforo, i, t);
16093 t = unshare_expr (gimple_omp_for_incr (gfor, i));
16094 gcc_assert (TREE_OPERAND (t, 0) == gimple_omp_for_index (gfor, i));
16095 TREE_OPERAND (t, 0) = v;
16096 gimple_omp_for_set_incr (gforo, i, t);
16097 t = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
16098 OMP_CLAUSE_DECL (t) = v;
16099 OMP_CLAUSE_CHAIN (t) = gimple_omp_for_clauses (gforo);
16100 gimple_omp_for_set_clauses (gforo, t);
16101 if (OMP_FOR_NON_RECTANGULAR (for_stmt))
16103 tree *p1 = NULL, *p2 = NULL;
16104 t = gimple_omp_for_initial (gforo, i);
16105 if (TREE_CODE (t) == TREE_VEC)
16106 p1 = &TREE_VEC_ELT (t, 0);
16107 t = gimple_omp_for_final (gforo, i);
16108 if (TREE_CODE (t) == TREE_VEC)
16110 if (p1)
16111 p2 = &TREE_VEC_ELT (t, 0);
16112 else
16113 p1 = &TREE_VEC_ELT (t, 0);
16115 if (p1)
16117 int j;
16118 for (j = 0; j < i; j++)
16119 if (*p1 == gimple_omp_for_index (gfor, j))
16121 *p1 = gimple_omp_for_index (gforo, j);
16122 if (p2)
16123 *p2 = *p1;
16124 break;
16126 gcc_assert (j < i);
16130 gimplify_seq_add_stmt (pre_p, gforo);
16132 else
16133 gimplify_seq_add_stmt (pre_p, gfor);
16135 if (TREE_CODE (orig_for_stmt) == OMP_FOR)
16137 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
16138 unsigned lastprivate_conditional = 0;
16139 while (ctx
16140 && (ctx->region_type == ORT_TARGET_DATA
16141 || ctx->region_type == ORT_TASKGROUP))
16142 ctx = ctx->outer_context;
16143 if (ctx && (ctx->region_type & ORT_PARALLEL) != 0)
16144 for (tree c = gimple_omp_for_clauses (gfor);
16145 c; c = OMP_CLAUSE_CHAIN (c))
16146 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
16147 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
16148 ++lastprivate_conditional;
16149 if (lastprivate_conditional)
16151 struct omp_for_data fd;
16152 omp_extract_for_data (gfor, &fd, NULL);
16153 tree type = build_array_type_nelts (unsigned_type_for (fd.iter_type),
16154 lastprivate_conditional);
16155 tree var = create_tmp_var_raw (type);
16156 tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__CONDTEMP_);
16157 OMP_CLAUSE_DECL (c) = var;
16158 OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor);
16159 gimple_omp_for_set_clauses (gfor, c);
16160 omp_add_variable (ctx, var, GOVD_CONDTEMP | GOVD_SEEN);
16163 else if (TREE_CODE (orig_for_stmt) == OMP_SIMD)
16165 unsigned lastprivate_conditional = 0;
16166 for (tree c = gimple_omp_for_clauses (gfor); c; c = OMP_CLAUSE_CHAIN (c))
16167 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
16168 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
16169 ++lastprivate_conditional;
16170 if (lastprivate_conditional)
16172 struct omp_for_data fd;
16173 omp_extract_for_data (gfor, &fd, NULL);
16174 tree type = unsigned_type_for (fd.iter_type);
16175 while (lastprivate_conditional--)
16177 tree c = build_omp_clause (UNKNOWN_LOCATION,
16178 OMP_CLAUSE__CONDTEMP_);
16179 OMP_CLAUSE_DECL (c) = create_tmp_var (type);
16180 OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor);
16181 gimple_omp_for_set_clauses (gfor, c);
16186 if (ret != GS_ALL_DONE)
16187 return GS_ERROR;
16188 *expr_p = NULL_TREE;
16189 return GS_ALL_DONE;
16192 /* Helper for gimplify_omp_loop, called through walk_tree. */
16194 static tree
16195 note_no_context_vars (tree *tp, int *, void *data)
16197 if (VAR_P (*tp)
16198 && DECL_CONTEXT (*tp) == NULL_TREE
16199 && !is_global_var (*tp))
16201 vec<tree> *d = (vec<tree> *) data;
16202 d->safe_push (*tp);
16203 DECL_CONTEXT (*tp) = current_function_decl;
16205 return NULL_TREE;
16208 /* Gimplify the gross structure of an OMP_LOOP statement. */
16210 static enum gimplify_status
16211 gimplify_omp_loop (tree *expr_p, gimple_seq *pre_p)
16213 tree for_stmt = *expr_p;
16214 tree clauses = OMP_FOR_CLAUSES (for_stmt);
16215 struct gimplify_omp_ctx *octx = gimplify_omp_ctxp;
16216 enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
16217 int i;
16219 /* If order is not present, the behavior is as if order(concurrent)
16220 appeared. */
16221 tree order = omp_find_clause (clauses, OMP_CLAUSE_ORDER);
16222 if (order == NULL_TREE)
16224 order = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_ORDER);
16225 OMP_CLAUSE_CHAIN (order) = clauses;
16226 OMP_FOR_CLAUSES (for_stmt) = clauses = order;
16229 tree bind = omp_find_clause (clauses, OMP_CLAUSE_BIND);
16230 if (bind == NULL_TREE)
16232 if (!flag_openmp) /* flag_openmp_simd */
16234 else if (octx && (octx->region_type & ORT_TEAMS) != 0)
16235 kind = OMP_CLAUSE_BIND_TEAMS;
16236 else if (octx && (octx->region_type & ORT_PARALLEL) != 0)
16237 kind = OMP_CLAUSE_BIND_PARALLEL;
16238 else
16240 for (; octx; octx = octx->outer_context)
16242 if ((octx->region_type & ORT_ACC) != 0
16243 || octx->region_type == ORT_NONE
16244 || octx->region_type == ORT_IMPLICIT_TARGET)
16245 continue;
16246 break;
16248 if (octx == NULL && !in_omp_construct)
16249 error_at (EXPR_LOCATION (for_stmt),
16250 "%<bind%> clause not specified on a %<loop%> "
16251 "construct not nested inside another OpenMP construct");
16253 bind = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_BIND);
16254 OMP_CLAUSE_CHAIN (bind) = clauses;
16255 OMP_CLAUSE_BIND_KIND (bind) = kind;
16256 OMP_FOR_CLAUSES (for_stmt) = bind;
16258 else
16259 switch (OMP_CLAUSE_BIND_KIND (bind))
16261 case OMP_CLAUSE_BIND_THREAD:
16262 break;
16263 case OMP_CLAUSE_BIND_PARALLEL:
16264 if (!flag_openmp) /* flag_openmp_simd */
16266 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
16267 break;
16269 for (; octx; octx = octx->outer_context)
16270 if (octx->region_type == ORT_SIMD
16271 && omp_find_clause (octx->clauses, OMP_CLAUSE_BIND) == NULL_TREE)
16273 error_at (EXPR_LOCATION (for_stmt),
16274 "%<bind(parallel)%> on a %<loop%> construct nested "
16275 "inside %<simd%> construct");
16276 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
16277 break;
16279 kind = OMP_CLAUSE_BIND_PARALLEL;
16280 break;
16281 case OMP_CLAUSE_BIND_TEAMS:
16282 if (!flag_openmp) /* flag_openmp_simd */
16284 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
16285 break;
16287 if ((octx
16288 && octx->region_type != ORT_IMPLICIT_TARGET
16289 && octx->region_type != ORT_NONE
16290 && (octx->region_type & ORT_TEAMS) == 0)
16291 || in_omp_construct)
16293 error_at (EXPR_LOCATION (for_stmt),
16294 "%<bind(teams)%> on a %<loop%> region not strictly "
16295 "nested inside of a %<teams%> region");
16296 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
16297 break;
16299 kind = OMP_CLAUSE_BIND_TEAMS;
16300 break;
16301 default:
16302 gcc_unreachable ();
16305 for (tree *pc = &OMP_FOR_CLAUSES (for_stmt); *pc; )
16306 switch (OMP_CLAUSE_CODE (*pc))
16308 case OMP_CLAUSE_REDUCTION:
16309 if (OMP_CLAUSE_REDUCTION_INSCAN (*pc))
16311 error_at (OMP_CLAUSE_LOCATION (*pc),
16312 "%<inscan%> %<reduction%> clause on "
16313 "%qs construct", "loop");
16314 OMP_CLAUSE_REDUCTION_INSCAN (*pc) = 0;
16316 if (OMP_CLAUSE_REDUCTION_TASK (*pc))
16318 error_at (OMP_CLAUSE_LOCATION (*pc),
16319 "invalid %<task%> reduction modifier on construct "
16320 "other than %<parallel%>, %qs or %<sections%>",
16321 lang_GNU_Fortran () ? "do" : "for");
16322 OMP_CLAUSE_REDUCTION_TASK (*pc) = 0;
16324 pc = &OMP_CLAUSE_CHAIN (*pc);
16325 break;
16326 case OMP_CLAUSE_LASTPRIVATE:
16327 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
16329 tree t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
16330 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
16331 if (OMP_CLAUSE_DECL (*pc) == TREE_OPERAND (t, 0))
16332 break;
16333 if (OMP_FOR_ORIG_DECLS (for_stmt)
16334 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt),
16335 i)) == TREE_LIST
16336 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt),
16337 i)))
16339 tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
16340 if (OMP_CLAUSE_DECL (*pc) == TREE_PURPOSE (orig))
16341 break;
16344 if (i == TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)))
16346 error_at (OMP_CLAUSE_LOCATION (*pc),
16347 "%<lastprivate%> clause on a %<loop%> construct refers "
16348 "to a variable %qD which is not the loop iterator",
16349 OMP_CLAUSE_DECL (*pc));
16350 *pc = OMP_CLAUSE_CHAIN (*pc);
16351 break;
16353 pc = &OMP_CLAUSE_CHAIN (*pc);
16354 break;
16355 default:
16356 pc = &OMP_CLAUSE_CHAIN (*pc);
16357 break;
16360 TREE_SET_CODE (for_stmt, OMP_SIMD);
16362 int last;
16363 switch (kind)
16365 case OMP_CLAUSE_BIND_THREAD: last = 0; break;
16366 case OMP_CLAUSE_BIND_PARALLEL: last = 1; break;
16367 case OMP_CLAUSE_BIND_TEAMS: last = 2; break;
16369 for (int pass = 1; pass <= last; pass++)
16371 if (pass == 2)
16373 tree bind = build3 (BIND_EXPR, void_type_node, NULL, NULL,
16374 make_node (BLOCK));
16375 append_to_statement_list (*expr_p, &BIND_EXPR_BODY (bind));
16376 *expr_p = make_node (OMP_PARALLEL);
16377 TREE_TYPE (*expr_p) = void_type_node;
16378 OMP_PARALLEL_BODY (*expr_p) = bind;
16379 OMP_PARALLEL_COMBINED (*expr_p) = 1;
16380 SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (for_stmt));
16381 tree *pc = &OMP_PARALLEL_CLAUSES (*expr_p);
16382 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
16383 if (OMP_FOR_ORIG_DECLS (for_stmt)
16384 && (TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i))
16385 == TREE_LIST))
16387 tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
16388 if (TREE_PURPOSE (elt) && TREE_VALUE (elt))
16390 *pc = build_omp_clause (UNKNOWN_LOCATION,
16391 OMP_CLAUSE_FIRSTPRIVATE);
16392 OMP_CLAUSE_DECL (*pc) = TREE_VALUE (elt);
16393 pc = &OMP_CLAUSE_CHAIN (*pc);
16397 tree t = make_node (pass == 2 ? OMP_DISTRIBUTE : OMP_FOR);
16398 tree *pc = &OMP_FOR_CLAUSES (t);
16399 TREE_TYPE (t) = void_type_node;
16400 OMP_FOR_BODY (t) = *expr_p;
16401 SET_EXPR_LOCATION (t, EXPR_LOCATION (for_stmt));
16402 for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
16403 switch (OMP_CLAUSE_CODE (c))
16405 case OMP_CLAUSE_BIND:
16406 case OMP_CLAUSE_ORDER:
16407 case OMP_CLAUSE_COLLAPSE:
16408 *pc = copy_node (c);
16409 pc = &OMP_CLAUSE_CHAIN (*pc);
16410 break;
16411 case OMP_CLAUSE_PRIVATE:
16412 case OMP_CLAUSE_FIRSTPRIVATE:
16413 /* Only needed on innermost. */
16414 break;
16415 case OMP_CLAUSE_LASTPRIVATE:
16416 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c) && pass != last)
16418 *pc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
16419 OMP_CLAUSE_FIRSTPRIVATE);
16420 OMP_CLAUSE_DECL (*pc) = OMP_CLAUSE_DECL (c);
16421 lang_hooks.decls.omp_finish_clause (*pc, NULL, false);
16422 pc = &OMP_CLAUSE_CHAIN (*pc);
16424 *pc = copy_node (c);
16425 OMP_CLAUSE_LASTPRIVATE_STMT (*pc) = NULL_TREE;
16426 TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
16427 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
16429 if (pass != last)
16430 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (*pc) = 1;
16431 else
16432 lang_hooks.decls.omp_finish_clause (*pc, NULL, false);
16433 OMP_CLAUSE_LASTPRIVATE_LOOP_IV (*pc) = 0;
16435 pc = &OMP_CLAUSE_CHAIN (*pc);
16436 break;
16437 case OMP_CLAUSE_REDUCTION:
16438 *pc = copy_node (c);
16439 OMP_CLAUSE_DECL (*pc) = unshare_expr (OMP_CLAUSE_DECL (c));
16440 TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
16441 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc))
16443 auto_vec<tree> no_context_vars;
16444 int walk_subtrees = 0;
16445 note_no_context_vars (&OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
16446 &walk_subtrees, &no_context_vars);
16447 if (tree p = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c))
16448 note_no_context_vars (&p, &walk_subtrees, &no_context_vars);
16449 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_INIT (c),
16450 note_no_context_vars,
16451 &no_context_vars);
16452 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_MERGE (c),
16453 note_no_context_vars,
16454 &no_context_vars);
16456 OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc)
16457 = copy_node (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c));
16458 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc))
16459 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc)
16460 = copy_node (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c));
16462 hash_map<tree, tree> decl_map;
16463 decl_map.put (OMP_CLAUSE_DECL (c), OMP_CLAUSE_DECL (c));
16464 decl_map.put (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
16465 OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc));
16466 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc))
16467 decl_map.put (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
16468 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc));
16470 copy_body_data id;
16471 memset (&id, 0, sizeof (id));
16472 id.src_fn = current_function_decl;
16473 id.dst_fn = current_function_decl;
16474 id.src_cfun = cfun;
16475 id.decl_map = &decl_map;
16476 id.copy_decl = copy_decl_no_change;
16477 id.transform_call_graph_edges = CB_CGE_DUPLICATE;
16478 id.transform_new_cfg = true;
16479 id.transform_return_to_modify = false;
16480 id.eh_lp_nr = 0;
16481 walk_tree (&OMP_CLAUSE_REDUCTION_INIT (*pc), copy_tree_body_r,
16482 &id, NULL);
16483 walk_tree (&OMP_CLAUSE_REDUCTION_MERGE (*pc), copy_tree_body_r,
16484 &id, NULL);
16486 for (tree d : no_context_vars)
16488 DECL_CONTEXT (d) = NULL_TREE;
16489 DECL_CONTEXT (*decl_map.get (d)) = NULL_TREE;
16492 else
16494 OMP_CLAUSE_REDUCTION_INIT (*pc)
16495 = unshare_expr (OMP_CLAUSE_REDUCTION_INIT (c));
16496 OMP_CLAUSE_REDUCTION_MERGE (*pc)
16497 = unshare_expr (OMP_CLAUSE_REDUCTION_MERGE (c));
16499 pc = &OMP_CLAUSE_CHAIN (*pc);
16500 break;
16501 default:
16502 gcc_unreachable ();
16504 *pc = NULL_TREE;
16505 *expr_p = t;
16507 return gimplify_expr (expr_p, pre_p, NULL, is_gimple_stmt, fb_none);
16511 /* Helper function of optimize_target_teams, find OMP_TEAMS inside
16512 of OMP_TARGET's body. */
16514 static tree
16515 find_omp_teams (tree *tp, int *walk_subtrees, void *)
16517 *walk_subtrees = 0;
16518 switch (TREE_CODE (*tp))
16520 case OMP_TEAMS:
16521 return *tp;
16522 case BIND_EXPR:
16523 case STATEMENT_LIST:
16524 *walk_subtrees = 1;
16525 break;
16526 default:
16527 break;
16529 return NULL_TREE;
16532 /* Helper function of optimize_target_teams, determine if the expression
16533 can be computed safely before the target construct on the host. */
16535 static tree
16536 computable_teams_clause (tree *tp, int *walk_subtrees, void *)
16538 splay_tree_node n;
16540 if (TYPE_P (*tp))
16542 *walk_subtrees = 0;
16543 return NULL_TREE;
16545 switch (TREE_CODE (*tp))
16547 case VAR_DECL:
16548 case PARM_DECL:
16549 case RESULT_DECL:
16550 *walk_subtrees = 0;
16551 if (error_operand_p (*tp)
16552 || !INTEGRAL_TYPE_P (TREE_TYPE (*tp))
16553 || DECL_HAS_VALUE_EXPR_P (*tp)
16554 || DECL_THREAD_LOCAL_P (*tp)
16555 || TREE_SIDE_EFFECTS (*tp)
16556 || TREE_THIS_VOLATILE (*tp))
16557 return *tp;
16558 if (is_global_var (*tp)
16559 && (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (*tp))
16560 || lookup_attribute ("omp declare target link",
16561 DECL_ATTRIBUTES (*tp))))
16562 return *tp;
16563 if (VAR_P (*tp)
16564 && !DECL_SEEN_IN_BIND_EXPR_P (*tp)
16565 && !is_global_var (*tp)
16566 && decl_function_context (*tp) == current_function_decl)
16567 return *tp;
16568 n = splay_tree_lookup (gimplify_omp_ctxp->variables,
16569 (splay_tree_key) *tp);
16570 if (n == NULL)
16572 if (gimplify_omp_ctxp->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE)
16573 return NULL_TREE;
16574 return *tp;
16576 else if (n->value & GOVD_LOCAL)
16577 return *tp;
16578 else if (n->value & GOVD_FIRSTPRIVATE)
16579 return NULL_TREE;
16580 else if ((n->value & (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
16581 == (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
16582 return NULL_TREE;
16583 return *tp;
16584 case INTEGER_CST:
16585 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
16586 return *tp;
16587 return NULL_TREE;
16588 case TARGET_EXPR:
16589 if (TARGET_EXPR_INITIAL (*tp)
16590 || TREE_CODE (TARGET_EXPR_SLOT (*tp)) != VAR_DECL)
16591 return *tp;
16592 return computable_teams_clause (&TARGET_EXPR_SLOT (*tp),
16593 walk_subtrees, NULL);
16594 /* Allow some reasonable subset of integral arithmetics. */
16595 case PLUS_EXPR:
16596 case MINUS_EXPR:
16597 case MULT_EXPR:
16598 case TRUNC_DIV_EXPR:
16599 case CEIL_DIV_EXPR:
16600 case FLOOR_DIV_EXPR:
16601 case ROUND_DIV_EXPR:
16602 case TRUNC_MOD_EXPR:
16603 case CEIL_MOD_EXPR:
16604 case FLOOR_MOD_EXPR:
16605 case ROUND_MOD_EXPR:
16606 case RDIV_EXPR:
16607 case EXACT_DIV_EXPR:
16608 case MIN_EXPR:
16609 case MAX_EXPR:
16610 case LSHIFT_EXPR:
16611 case RSHIFT_EXPR:
16612 case BIT_IOR_EXPR:
16613 case BIT_XOR_EXPR:
16614 case BIT_AND_EXPR:
16615 case NEGATE_EXPR:
16616 case ABS_EXPR:
16617 case BIT_NOT_EXPR:
16618 case NON_LVALUE_EXPR:
16619 CASE_CONVERT:
16620 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
16621 return *tp;
16622 return NULL_TREE;
16623 /* And disallow anything else, except for comparisons. */
16624 default:
16625 if (COMPARISON_CLASS_P (*tp))
16626 return NULL_TREE;
16627 return *tp;
16631 /* Try to determine if the num_teams and/or thread_limit expressions
16632 can have their values determined already before entering the
16633 target construct.
16634 INTEGER_CSTs trivially are,
16635 integral decls that are firstprivate (explicitly or implicitly)
16636 or explicitly map(always, to:) or map(always, tofrom:) on the target
16637 region too, and expressions involving simple arithmetics on those
16638 too, function calls are not ok, dereferencing something neither etc.
16639 Add NUM_TEAMS and THREAD_LIMIT clauses to the OMP_CLAUSES of
16640 EXPR based on what we find:
16641 0 stands for clause not specified at all, use implementation default
16642 -1 stands for value that can't be determined easily before entering
16643 the target construct.
16644 -2 means that no explicit teams construct was specified
16645 If teams construct is not present at all, use 1 for num_teams
16646 and 0 for thread_limit (only one team is involved, and the thread
16647 limit is implementation defined. */
16649 static void
16650 optimize_target_teams (tree target, gimple_seq *pre_p)
16652 tree body = OMP_BODY (target);
16653 tree teams = walk_tree (&body, find_omp_teams, NULL, NULL);
16654 tree num_teams_lower = NULL_TREE;
16655 tree num_teams_upper = integer_zero_node;
16656 tree thread_limit = integer_zero_node;
16657 location_t num_teams_loc = EXPR_LOCATION (target);
16658 location_t thread_limit_loc = EXPR_LOCATION (target);
16659 tree c, *p, expr;
16660 struct gimplify_omp_ctx *target_ctx = gimplify_omp_ctxp;
16662 if (teams == NULL_TREE)
16663 num_teams_upper = build_int_cst (integer_type_node, -2);
16664 else
16665 for (c = OMP_TEAMS_CLAUSES (teams); c; c = OMP_CLAUSE_CHAIN (c))
16667 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS)
16669 p = &num_teams_upper;
16670 num_teams_loc = OMP_CLAUSE_LOCATION (c);
16671 if (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c))
16673 expr = OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c);
16674 if (TREE_CODE (expr) == INTEGER_CST)
16675 num_teams_lower = expr;
16676 else if (walk_tree (&expr, computable_teams_clause,
16677 NULL, NULL))
16678 num_teams_lower = integer_minus_one_node;
16679 else
16681 num_teams_lower = expr;
16682 gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
16683 if (gimplify_expr (&num_teams_lower, pre_p, NULL,
16684 is_gimple_val, fb_rvalue, false)
16685 == GS_ERROR)
16687 gimplify_omp_ctxp = target_ctx;
16688 num_teams_lower = integer_minus_one_node;
16690 else
16692 gimplify_omp_ctxp = target_ctx;
16693 if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR)
16694 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
16695 = num_teams_lower;
16700 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
16702 p = &thread_limit;
16703 thread_limit_loc = OMP_CLAUSE_LOCATION (c);
16705 else
16706 continue;
16707 expr = OMP_CLAUSE_OPERAND (c, 0);
16708 if (TREE_CODE (expr) == INTEGER_CST)
16710 *p = expr;
16711 continue;
16713 if (walk_tree (&expr, computable_teams_clause, NULL, NULL))
16715 *p = integer_minus_one_node;
16716 continue;
16718 *p = expr;
16719 gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
16720 if (gimplify_expr (p, pre_p, NULL, is_gimple_val, fb_rvalue, false)
16721 == GS_ERROR)
16723 gimplify_omp_ctxp = target_ctx;
16724 *p = integer_minus_one_node;
16725 continue;
16727 gimplify_omp_ctxp = target_ctx;
16728 if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR)
16729 OMP_CLAUSE_OPERAND (c, 0) = *p;
16731 if (!omp_find_clause (OMP_TARGET_CLAUSES (target), OMP_CLAUSE_THREAD_LIMIT))
16733 c = build_omp_clause (thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
16734 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = thread_limit;
16735 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
16736 OMP_TARGET_CLAUSES (target) = c;
16738 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
16739 OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c) = num_teams_upper;
16740 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) = num_teams_lower;
16741 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
16742 OMP_TARGET_CLAUSES (target) = c;
16745 /* Gimplify the gross structure of several OMP constructs. */
16747 static void
16748 gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
16750 tree expr = *expr_p;
16751 gimple *stmt;
16752 gimple_seq body = NULL;
16753 enum omp_region_type ort;
16755 switch (TREE_CODE (expr))
16757 case OMP_SECTIONS:
16758 case OMP_SINGLE:
16759 ort = ORT_WORKSHARE;
16760 break;
16761 case OMP_SCOPE:
16762 ort = ORT_TASKGROUP;
16763 break;
16764 case OMP_TARGET:
16765 ort = OMP_TARGET_COMBINED (expr) ? ORT_COMBINED_TARGET : ORT_TARGET;
16766 break;
16767 case OACC_KERNELS:
16768 ort = ORT_ACC_KERNELS;
16769 break;
16770 case OACC_PARALLEL:
16771 ort = ORT_ACC_PARALLEL;
16772 break;
16773 case OACC_SERIAL:
16774 ort = ORT_ACC_SERIAL;
16775 break;
16776 case OACC_DATA:
16777 ort = ORT_ACC_DATA;
16778 break;
16779 case OMP_TARGET_DATA:
16780 ort = ORT_TARGET_DATA;
16781 break;
16782 case OMP_TEAMS:
16783 ort = OMP_TEAMS_COMBINED (expr) ? ORT_COMBINED_TEAMS : ORT_TEAMS;
16784 if (gimplify_omp_ctxp == NULL
16785 || gimplify_omp_ctxp->region_type == ORT_IMPLICIT_TARGET)
16786 ort = (enum omp_region_type) (ort | ORT_HOST_TEAMS);
16787 break;
16788 case OACC_HOST_DATA:
16789 ort = ORT_ACC_HOST_DATA;
16790 break;
16791 default:
16792 gcc_unreachable ();
16795 bool save_in_omp_construct = in_omp_construct;
16796 if ((ort & ORT_ACC) == 0)
16797 in_omp_construct = false;
16798 gimplify_scan_omp_clauses (&OMP_CLAUSES (expr), pre_p, ort,
16799 TREE_CODE (expr));
16800 if (TREE_CODE (expr) == OMP_TARGET)
16801 optimize_target_teams (expr, pre_p);
16802 if ((ort & (ORT_TARGET | ORT_TARGET_DATA)) != 0
16803 || (ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
16805 push_gimplify_context ();
16806 gimple *g = gimplify_and_return_first (OMP_BODY (expr), &body);
16807 if (gimple_code (g) == GIMPLE_BIND)
16808 pop_gimplify_context (g);
16809 else
16810 pop_gimplify_context (NULL);
16811 if ((ort & ORT_TARGET_DATA) != 0)
16813 enum built_in_function end_ix;
16814 switch (TREE_CODE (expr))
16816 case OACC_DATA:
16817 case OACC_HOST_DATA:
16818 end_ix = BUILT_IN_GOACC_DATA_END;
16819 break;
16820 case OMP_TARGET_DATA:
16821 end_ix = BUILT_IN_GOMP_TARGET_END_DATA;
16822 break;
16823 default:
16824 gcc_unreachable ();
16826 tree fn = builtin_decl_explicit (end_ix);
16827 g = gimple_build_call (fn, 0);
16828 gimple_seq cleanup = NULL;
16829 gimple_seq_add_stmt (&cleanup, g);
16830 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
16831 body = NULL;
16832 gimple_seq_add_stmt (&body, g);
16835 else
16836 gimplify_and_add (OMP_BODY (expr), &body);
16837 gimplify_adjust_omp_clauses (pre_p, body, &OMP_CLAUSES (expr),
16838 TREE_CODE (expr));
16839 in_omp_construct = save_in_omp_construct;
16841 switch (TREE_CODE (expr))
16843 case OACC_DATA:
16844 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_DATA,
16845 OMP_CLAUSES (expr));
16846 break;
16847 case OACC_HOST_DATA:
16848 if (omp_find_clause (OMP_CLAUSES (expr), OMP_CLAUSE_IF_PRESENT))
16850 for (tree c = OMP_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
16851 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_PTR)
16852 OMP_CLAUSE_USE_DEVICE_PTR_IF_PRESENT (c) = 1;
16855 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_HOST_DATA,
16856 OMP_CLAUSES (expr));
16857 break;
16858 case OACC_KERNELS:
16859 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_KERNELS,
16860 OMP_CLAUSES (expr));
16861 break;
16862 case OACC_PARALLEL:
16863 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_PARALLEL,
16864 OMP_CLAUSES (expr));
16865 break;
16866 case OACC_SERIAL:
16867 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_SERIAL,
16868 OMP_CLAUSES (expr));
16869 break;
16870 case OMP_SECTIONS:
16871 stmt = gimple_build_omp_sections (body, OMP_CLAUSES (expr));
16872 break;
16873 case OMP_SINGLE:
16874 stmt = gimple_build_omp_single (body, OMP_CLAUSES (expr));
16875 break;
16876 case OMP_SCOPE:
16877 stmt = gimple_build_omp_scope (body, OMP_CLAUSES (expr));
16878 break;
16879 case OMP_TARGET:
16880 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_REGION,
16881 OMP_CLAUSES (expr));
16882 break;
16883 case OMP_TARGET_DATA:
16884 /* Put use_device_{ptr,addr} clauses last, as map clauses are supposed
16885 to be evaluated before the use_device_{ptr,addr} clauses if they
16886 refer to the same variables. */
16888 tree use_device_clauses;
16889 tree *pc, *uc = &use_device_clauses;
16890 for (pc = &OMP_CLAUSES (expr); *pc; )
16891 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
16892 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
16894 *uc = *pc;
16895 *pc = OMP_CLAUSE_CHAIN (*pc);
16896 uc = &OMP_CLAUSE_CHAIN (*uc);
16898 else
16899 pc = &OMP_CLAUSE_CHAIN (*pc);
16900 *uc = NULL_TREE;
16901 *pc = use_device_clauses;
16902 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_DATA,
16903 OMP_CLAUSES (expr));
16905 break;
16906 case OMP_TEAMS:
16907 stmt = gimple_build_omp_teams (body, OMP_CLAUSES (expr));
16908 if ((ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
16909 gimple_omp_teams_set_host (as_a <gomp_teams *> (stmt), true);
16910 break;
16911 default:
16912 gcc_unreachable ();
16915 gimplify_seq_add_stmt (pre_p, stmt);
16916 *expr_p = NULL_TREE;
16919 /* Gimplify the gross structure of OpenACC enter/exit data, update, and OpenMP
16920 target update constructs. */
16922 static void
16923 gimplify_omp_target_update (tree *expr_p, gimple_seq *pre_p)
16925 tree expr = *expr_p;
16926 int kind;
16927 gomp_target *stmt;
16928 enum omp_region_type ort = ORT_WORKSHARE;
16930 switch (TREE_CODE (expr))
16932 case OACC_ENTER_DATA:
16933 kind = GF_OMP_TARGET_KIND_OACC_ENTER_DATA;
16934 ort = ORT_ACC;
16935 break;
16936 case OACC_EXIT_DATA:
16937 kind = GF_OMP_TARGET_KIND_OACC_EXIT_DATA;
16938 ort = ORT_ACC;
16939 break;
16940 case OACC_UPDATE:
16941 kind = GF_OMP_TARGET_KIND_OACC_UPDATE;
16942 ort = ORT_ACC;
16943 break;
16944 case OMP_TARGET_UPDATE:
16945 kind = GF_OMP_TARGET_KIND_UPDATE;
16946 break;
16947 case OMP_TARGET_ENTER_DATA:
16948 kind = GF_OMP_TARGET_KIND_ENTER_DATA;
16949 break;
16950 case OMP_TARGET_EXIT_DATA:
16951 kind = GF_OMP_TARGET_KIND_EXIT_DATA;
16952 break;
16953 default:
16954 gcc_unreachable ();
16956 gimplify_scan_omp_clauses (&OMP_STANDALONE_CLAUSES (expr), pre_p,
16957 ort, TREE_CODE (expr));
16958 gimplify_adjust_omp_clauses (pre_p, NULL, &OMP_STANDALONE_CLAUSES (expr),
16959 TREE_CODE (expr));
16960 if (TREE_CODE (expr) == OACC_UPDATE
16961 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
16962 OMP_CLAUSE_IF_PRESENT))
16964 /* The runtime uses GOMP_MAP_{TO,FROM} to denote the if_present
16965 clause. */
16966 for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
16967 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
16968 switch (OMP_CLAUSE_MAP_KIND (c))
16970 case GOMP_MAP_FORCE_TO:
16971 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TO);
16972 break;
16973 case GOMP_MAP_FORCE_FROM:
16974 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FROM);
16975 break;
16976 default:
16977 break;
16980 else if (TREE_CODE (expr) == OACC_EXIT_DATA
16981 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
16982 OMP_CLAUSE_FINALIZE))
16984 /* Use GOMP_MAP_DELETE/GOMP_MAP_FORCE_FROM to denote "finalize"
16985 semantics. */
16986 bool have_clause = false;
16987 for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
16988 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
16989 switch (OMP_CLAUSE_MAP_KIND (c))
16991 case GOMP_MAP_FROM:
16992 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_FROM);
16993 have_clause = true;
16994 break;
16995 case GOMP_MAP_RELEASE:
16996 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_DELETE);
16997 have_clause = true;
16998 break;
16999 case GOMP_MAP_TO_PSET:
17000 /* Fortran arrays with descriptors must map that descriptor when
17001 doing standalone "attach" operations (in OpenACC). In that
17002 case GOMP_MAP_TO_PSET appears by itself with no preceding
17003 clause (see trans-openmp.cc:gfc_trans_omp_clauses). */
17004 break;
17005 case GOMP_MAP_POINTER:
17006 /* TODO PR92929: we may see these here, but they'll always follow
17007 one of the clauses above, and will be handled by libgomp as
17008 one group, so no handling required here. */
17009 gcc_assert (have_clause);
17010 break;
17011 case GOMP_MAP_DETACH:
17012 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_DETACH);
17013 have_clause = false;
17014 break;
17015 case GOMP_MAP_STRUCT:
17016 case GOMP_MAP_STRUCT_UNORD:
17017 have_clause = false;
17018 break;
17019 default:
17020 gcc_unreachable ();
17023 stmt = gimple_build_omp_target (NULL, kind, OMP_STANDALONE_CLAUSES (expr));
17025 gimplify_seq_add_stmt (pre_p, stmt);
17026 *expr_p = NULL_TREE;
17029 /* A subroutine of gimplify_omp_atomic. The front end is supposed to have
17030 stabilized the lhs of the atomic operation as *ADDR. Return true if
17031 EXPR is this stabilized form. */
17033 static bool
17034 goa_lhs_expr_p (tree expr, tree addr)
17036 /* Also include casts to other type variants. The C front end is fond
17037 of adding these for e.g. volatile variables. This is like
17038 STRIP_TYPE_NOPS but includes the main variant lookup. */
17039 STRIP_USELESS_TYPE_CONVERSION (expr);
17041 if (INDIRECT_REF_P (expr))
17043 expr = TREE_OPERAND (expr, 0);
17044 while (expr != addr
17045 && (CONVERT_EXPR_P (expr)
17046 || TREE_CODE (expr) == NON_LVALUE_EXPR)
17047 && TREE_CODE (expr) == TREE_CODE (addr)
17048 && types_compatible_p (TREE_TYPE (expr), TREE_TYPE (addr)))
17050 expr = TREE_OPERAND (expr, 0);
17051 addr = TREE_OPERAND (addr, 0);
17053 if (expr == addr)
17054 return true;
17055 return (TREE_CODE (addr) == ADDR_EXPR
17056 && TREE_CODE (expr) == ADDR_EXPR
17057 && TREE_OPERAND (addr, 0) == TREE_OPERAND (expr, 0));
17059 if (TREE_CODE (addr) == ADDR_EXPR && expr == TREE_OPERAND (addr, 0))
17060 return true;
17061 return false;
17064 /* Walk *EXPR_P and replace appearances of *LHS_ADDR with LHS_VAR. If an
17065 expression does not involve the lhs, evaluate it into a temporary.
17066 Return 1 if the lhs appeared as a subexpression, 0 if it did not,
17067 or -1 if an error was encountered. */
17069 static int
17070 goa_stabilize_expr (tree *expr_p, gimple_seq *pre_p, tree lhs_addr,
17071 tree lhs_var, tree &target_expr, bool rhs, int depth)
17073 tree expr = *expr_p;
17074 int saw_lhs = 0;
17076 if (goa_lhs_expr_p (expr, lhs_addr))
17078 if (pre_p)
17079 *expr_p = lhs_var;
17080 return 1;
17082 if (is_gimple_val (expr))
17083 return 0;
17085 /* Maximum depth of lhs in expression is for the
17086 __builtin_clear_padding (...), __builtin_clear_padding (...),
17087 __builtin_memcmp (&TARGET_EXPR <lhs, >, ...) == 0 ? ... : lhs; */
17088 if (++depth > 7)
17089 goto finish;
17091 switch (TREE_CODE_CLASS (TREE_CODE (expr)))
17093 case tcc_binary:
17094 case tcc_comparison:
17095 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p, lhs_addr,
17096 lhs_var, target_expr, true, depth);
17097 /* FALLTHRU */
17098 case tcc_unary:
17099 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p, lhs_addr,
17100 lhs_var, target_expr, true, depth);
17101 break;
17102 case tcc_expression:
17103 switch (TREE_CODE (expr))
17105 case TRUTH_ANDIF_EXPR:
17106 case TRUTH_ORIF_EXPR:
17107 case TRUTH_AND_EXPR:
17108 case TRUTH_OR_EXPR:
17109 case TRUTH_XOR_EXPR:
17110 case BIT_INSERT_EXPR:
17111 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
17112 lhs_addr, lhs_var, target_expr, true,
17113 depth);
17114 /* FALLTHRU */
17115 case TRUTH_NOT_EXPR:
17116 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
17117 lhs_addr, lhs_var, target_expr, true,
17118 depth);
17119 break;
17120 case MODIFY_EXPR:
17121 if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr, lhs_var,
17122 target_expr, true, depth))
17123 break;
17124 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
17125 lhs_addr, lhs_var, target_expr, true,
17126 depth);
17127 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
17128 lhs_addr, lhs_var, target_expr, false,
17129 depth);
17130 break;
17131 /* FALLTHRU */
17132 case ADDR_EXPR:
17133 if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr, lhs_var,
17134 target_expr, true, depth))
17135 break;
17136 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
17137 lhs_addr, lhs_var, target_expr, false,
17138 depth);
17139 break;
17140 case COMPOUND_EXPR:
17141 /* Break out any preevaluations from cp_build_modify_expr. */
17142 for (; TREE_CODE (expr) == COMPOUND_EXPR;
17143 expr = TREE_OPERAND (expr, 1))
17145 /* Special-case __builtin_clear_padding call before
17146 __builtin_memcmp. */
17147 if (TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR)
17149 tree fndecl = get_callee_fndecl (TREE_OPERAND (expr, 0));
17150 if (fndecl
17151 && fndecl_built_in_p (fndecl, BUILT_IN_CLEAR_PADDING)
17152 && VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 0)))
17153 && (!pre_p
17154 || goa_stabilize_expr (&TREE_OPERAND (expr, 0), NULL,
17155 lhs_addr, lhs_var,
17156 target_expr, true, depth)))
17158 if (pre_p)
17159 *expr_p = expr;
17160 saw_lhs = goa_stabilize_expr (&TREE_OPERAND (expr, 0),
17161 pre_p, lhs_addr, lhs_var,
17162 target_expr, true, depth);
17163 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1),
17164 pre_p, lhs_addr, lhs_var,
17165 target_expr, rhs, depth);
17166 return saw_lhs;
17170 if (pre_p)
17171 gimplify_stmt (&TREE_OPERAND (expr, 0), pre_p);
17173 if (!pre_p)
17174 return goa_stabilize_expr (&expr, pre_p, lhs_addr, lhs_var,
17175 target_expr, rhs, depth);
17176 *expr_p = expr;
17177 return goa_stabilize_expr (expr_p, pre_p, lhs_addr, lhs_var,
17178 target_expr, rhs, depth);
17179 case COND_EXPR:
17180 if (!goa_stabilize_expr (&TREE_OPERAND (expr, 0), NULL, lhs_addr,
17181 lhs_var, target_expr, true, depth))
17182 break;
17183 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
17184 lhs_addr, lhs_var, target_expr, true,
17185 depth);
17186 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
17187 lhs_addr, lhs_var, target_expr, true,
17188 depth);
17189 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 2), pre_p,
17190 lhs_addr, lhs_var, target_expr, true,
17191 depth);
17192 break;
17193 case TARGET_EXPR:
17194 if (TARGET_EXPR_INITIAL (expr))
17196 if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr,
17197 lhs_var, target_expr, true,
17198 depth))
17199 break;
17200 if (expr == target_expr)
17201 saw_lhs = 1;
17202 else
17204 saw_lhs = goa_stabilize_expr (&TARGET_EXPR_INITIAL (expr),
17205 pre_p, lhs_addr, lhs_var,
17206 target_expr, true, depth);
17207 if (saw_lhs && target_expr == NULL_TREE && pre_p)
17208 target_expr = expr;
17211 break;
17212 default:
17213 break;
17215 break;
17216 case tcc_reference:
17217 if (TREE_CODE (expr) == BIT_FIELD_REF
17218 || TREE_CODE (expr) == VIEW_CONVERT_EXPR)
17219 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
17220 lhs_addr, lhs_var, target_expr, true,
17221 depth);
17222 break;
17223 case tcc_vl_exp:
17224 if (TREE_CODE (expr) == CALL_EXPR)
17226 if (tree fndecl = get_callee_fndecl (expr))
17227 if (fndecl_built_in_p (fndecl, BUILT_IN_CLEAR_PADDING,
17228 BUILT_IN_MEMCMP))
17230 int nargs = call_expr_nargs (expr);
17231 for (int i = 0; i < nargs; i++)
17232 saw_lhs |= goa_stabilize_expr (&CALL_EXPR_ARG (expr, i),
17233 pre_p, lhs_addr, lhs_var,
17234 target_expr, true, depth);
17237 break;
17238 default:
17239 break;
17242 finish:
17243 if (saw_lhs == 0 && pre_p)
17245 enum gimplify_status gs;
17246 if (TREE_CODE (expr) == CALL_EXPR && VOID_TYPE_P (TREE_TYPE (expr)))
17248 gimplify_stmt (&expr, pre_p);
17249 return saw_lhs;
17251 else if (rhs)
17252 gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_val, fb_rvalue);
17253 else
17254 gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_lvalue, fb_lvalue);
17255 if (gs != GS_ALL_DONE)
17256 saw_lhs = -1;
17259 return saw_lhs;
17262 /* Gimplify an OMP_ATOMIC statement. */
17264 static enum gimplify_status
17265 gimplify_omp_atomic (tree *expr_p, gimple_seq *pre_p)
17267 tree addr = TREE_OPERAND (*expr_p, 0);
17268 tree rhs = TREE_CODE (*expr_p) == OMP_ATOMIC_READ
17269 ? NULL : TREE_OPERAND (*expr_p, 1);
17270 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
17271 tree tmp_load;
17272 gomp_atomic_load *loadstmt;
17273 gomp_atomic_store *storestmt;
17274 tree target_expr = NULL_TREE;
17276 tmp_load = create_tmp_reg (type);
17277 if (rhs
17278 && goa_stabilize_expr (&rhs, pre_p, addr, tmp_load, target_expr,
17279 true, 0) < 0)
17280 return GS_ERROR;
17282 if (gimplify_expr (&addr, pre_p, NULL, is_gimple_val, fb_rvalue)
17283 != GS_ALL_DONE)
17284 return GS_ERROR;
17286 loadstmt = gimple_build_omp_atomic_load (tmp_load, addr,
17287 OMP_ATOMIC_MEMORY_ORDER (*expr_p));
17288 gimplify_seq_add_stmt (pre_p, loadstmt);
17289 if (rhs)
17291 /* BIT_INSERT_EXPR is not valid for non-integral bitfield
17292 representatives. Use BIT_FIELD_REF on the lhs instead. */
17293 tree rhsarg = rhs;
17294 if (TREE_CODE (rhs) == COND_EXPR)
17295 rhsarg = TREE_OPERAND (rhs, 1);
17296 if (TREE_CODE (rhsarg) == BIT_INSERT_EXPR
17297 && !INTEGRAL_TYPE_P (TREE_TYPE (tmp_load)))
17299 tree bitpos = TREE_OPERAND (rhsarg, 2);
17300 tree op1 = TREE_OPERAND (rhsarg, 1);
17301 tree bitsize;
17302 tree tmp_store = tmp_load;
17303 if (TREE_CODE (*expr_p) == OMP_ATOMIC_CAPTURE_OLD)
17304 tmp_store = get_initialized_tmp_var (tmp_load, pre_p);
17305 if (INTEGRAL_TYPE_P (TREE_TYPE (op1)))
17306 bitsize = bitsize_int (TYPE_PRECISION (TREE_TYPE (op1)));
17307 else
17308 bitsize = TYPE_SIZE (TREE_TYPE (op1));
17309 gcc_assert (TREE_OPERAND (rhsarg, 0) == tmp_load);
17310 tree t = build2_loc (EXPR_LOCATION (rhsarg),
17311 MODIFY_EXPR, void_type_node,
17312 build3_loc (EXPR_LOCATION (rhsarg),
17313 BIT_FIELD_REF, TREE_TYPE (op1),
17314 tmp_store, bitsize, bitpos), op1);
17315 if (TREE_CODE (rhs) == COND_EXPR)
17316 t = build3_loc (EXPR_LOCATION (rhs), COND_EXPR, void_type_node,
17317 TREE_OPERAND (rhs, 0), t, void_node);
17318 gimplify_and_add (t, pre_p);
17319 rhs = tmp_store;
17321 bool save_allow_rhs_cond_expr = gimplify_ctxp->allow_rhs_cond_expr;
17322 if (TREE_CODE (rhs) == COND_EXPR)
17323 gimplify_ctxp->allow_rhs_cond_expr = true;
17324 enum gimplify_status gs = gimplify_expr (&rhs, pre_p, NULL,
17325 is_gimple_val, fb_rvalue);
17326 gimplify_ctxp->allow_rhs_cond_expr = save_allow_rhs_cond_expr;
17327 if (gs != GS_ALL_DONE)
17328 return GS_ERROR;
17331 if (TREE_CODE (*expr_p) == OMP_ATOMIC_READ)
17332 rhs = tmp_load;
17333 storestmt
17334 = gimple_build_omp_atomic_store (rhs, OMP_ATOMIC_MEMORY_ORDER (*expr_p));
17335 if (TREE_CODE (*expr_p) != OMP_ATOMIC_READ && OMP_ATOMIC_WEAK (*expr_p))
17337 gimple_omp_atomic_set_weak (loadstmt);
17338 gimple_omp_atomic_set_weak (storestmt);
17340 gimplify_seq_add_stmt (pre_p, storestmt);
17341 switch (TREE_CODE (*expr_p))
17343 case OMP_ATOMIC_READ:
17344 case OMP_ATOMIC_CAPTURE_OLD:
17345 *expr_p = tmp_load;
17346 gimple_omp_atomic_set_need_value (loadstmt);
17347 break;
17348 case OMP_ATOMIC_CAPTURE_NEW:
17349 *expr_p = rhs;
17350 gimple_omp_atomic_set_need_value (storestmt);
17351 break;
17352 default:
17353 *expr_p = NULL;
17354 break;
17357 return GS_ALL_DONE;
17360 /* Gimplify a TRANSACTION_EXPR. This involves gimplification of the
17361 body, and adding some EH bits. */
17363 static enum gimplify_status
17364 gimplify_transaction (tree *expr_p, gimple_seq *pre_p)
17366 tree expr = *expr_p, temp, tbody = TRANSACTION_EXPR_BODY (expr);
17367 gimple *body_stmt;
17368 gtransaction *trans_stmt;
17369 gimple_seq body = NULL;
17370 int subcode = 0;
17372 /* Wrap the transaction body in a BIND_EXPR so we have a context
17373 where to put decls for OMP. */
17374 if (TREE_CODE (tbody) != BIND_EXPR)
17376 tree bind = build3 (BIND_EXPR, void_type_node, NULL, tbody, NULL);
17377 TREE_SIDE_EFFECTS (bind) = 1;
17378 SET_EXPR_LOCATION (bind, EXPR_LOCATION (tbody));
17379 TRANSACTION_EXPR_BODY (expr) = bind;
17382 push_gimplify_context ();
17383 temp = voidify_wrapper_expr (*expr_p, NULL);
17385 body_stmt = gimplify_and_return_first (TRANSACTION_EXPR_BODY (expr), &body);
17386 pop_gimplify_context (body_stmt);
17388 trans_stmt = gimple_build_transaction (body);
17389 if (TRANSACTION_EXPR_OUTER (expr))
17390 subcode = GTMA_IS_OUTER;
17391 else if (TRANSACTION_EXPR_RELAXED (expr))
17392 subcode = GTMA_IS_RELAXED;
17393 gimple_transaction_set_subcode (trans_stmt, subcode);
17395 gimplify_seq_add_stmt (pre_p, trans_stmt);
17397 if (temp)
17399 *expr_p = temp;
17400 return GS_OK;
17403 *expr_p = NULL_TREE;
17404 return GS_ALL_DONE;
17407 /* Gimplify an OMP_ORDERED construct. EXPR is the tree version. BODY
17408 is the OMP_BODY of the original EXPR (which has already been
17409 gimplified so it's not present in the EXPR).
17411 Return the gimplified GIMPLE_OMP_ORDERED tuple. */
17413 static gimple *
17414 gimplify_omp_ordered (tree expr, gimple_seq body)
17416 tree c, decls;
17417 int failures = 0;
17418 unsigned int i;
17419 tree source_c = NULL_TREE;
17420 tree sink_c = NULL_TREE;
17422 if (gimplify_omp_ctxp)
17424 for (c = OMP_ORDERED_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
17425 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DOACROSS
17426 && gimplify_omp_ctxp->loop_iter_var.is_empty ())
17428 error_at (OMP_CLAUSE_LOCATION (c),
17429 "%<ordered%> construct with %qs clause must be "
17430 "closely nested inside a loop with %<ordered%> clause",
17431 OMP_CLAUSE_DOACROSS_DEPEND (c) ? "depend" : "doacross");
17432 failures++;
17434 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DOACROSS
17435 && OMP_CLAUSE_DOACROSS_KIND (c) == OMP_CLAUSE_DOACROSS_SINK)
17437 bool fail = false;
17438 sink_c = c;
17439 if (OMP_CLAUSE_DECL (c) == NULL_TREE)
17440 continue; /* omp_cur_iteration - 1 */
17441 for (decls = OMP_CLAUSE_DECL (c), i = 0;
17442 decls && TREE_CODE (decls) == TREE_LIST;
17443 decls = TREE_CHAIN (decls), ++i)
17444 if (i >= gimplify_omp_ctxp->loop_iter_var.length () / 2)
17445 continue;
17446 else if (TREE_VALUE (decls)
17447 != gimplify_omp_ctxp->loop_iter_var[2 * i])
17449 error_at (OMP_CLAUSE_LOCATION (c),
17450 "variable %qE is not an iteration "
17451 "of outermost loop %d, expected %qE",
17452 TREE_VALUE (decls), i + 1,
17453 gimplify_omp_ctxp->loop_iter_var[2 * i]);
17454 fail = true;
17455 failures++;
17457 else
17458 TREE_VALUE (decls)
17459 = gimplify_omp_ctxp->loop_iter_var[2 * i + 1];
17460 if (!fail && i != gimplify_omp_ctxp->loop_iter_var.length () / 2)
17462 error_at (OMP_CLAUSE_LOCATION (c),
17463 "number of variables in %qs clause with "
17464 "%<sink%> modifier does not match number of "
17465 "iteration variables",
17466 OMP_CLAUSE_DOACROSS_DEPEND (c)
17467 ? "depend" : "doacross");
17468 failures++;
17471 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DOACROSS
17472 && OMP_CLAUSE_DOACROSS_KIND (c) == OMP_CLAUSE_DOACROSS_SOURCE)
17474 if (source_c)
17476 error_at (OMP_CLAUSE_LOCATION (c),
17477 "more than one %qs clause with %<source%> "
17478 "modifier on an %<ordered%> construct",
17479 OMP_CLAUSE_DOACROSS_DEPEND (source_c)
17480 ? "depend" : "doacross");
17481 failures++;
17483 else
17484 source_c = c;
17487 if (source_c && sink_c)
17489 error_at (OMP_CLAUSE_LOCATION (source_c),
17490 "%qs clause with %<source%> modifier specified "
17491 "together with %qs clauses with %<sink%> modifier "
17492 "on the same construct",
17493 OMP_CLAUSE_DOACROSS_DEPEND (source_c) ? "depend" : "doacross",
17494 OMP_CLAUSE_DOACROSS_DEPEND (sink_c) ? "depend" : "doacross");
17495 failures++;
17498 if (failures)
17499 return gimple_build_nop ();
17500 return gimple_build_omp_ordered (body, OMP_ORDERED_CLAUSES (expr));
17503 /* Convert the GENERIC expression tree *EXPR_P to GIMPLE. If the
17504 expression produces a value to be used as an operand inside a GIMPLE
17505 statement, the value will be stored back in *EXPR_P. This value will
17506 be a tree of class tcc_declaration, tcc_constant, tcc_reference or
17507 an SSA_NAME. The corresponding sequence of GIMPLE statements is
17508 emitted in PRE_P and POST_P.
17510 Additionally, this process may overwrite parts of the input
17511 expression during gimplification. Ideally, it should be
17512 possible to do non-destructive gimplification.
17514 EXPR_P points to the GENERIC expression to convert to GIMPLE. If
17515 the expression needs to evaluate to a value to be used as
17516 an operand in a GIMPLE statement, this value will be stored in
17517 *EXPR_P on exit. This happens when the caller specifies one
17518 of fb_lvalue or fb_rvalue fallback flags.
17520 PRE_P will contain the sequence of GIMPLE statements corresponding
17521 to the evaluation of EXPR and all the side-effects that must
17522 be executed before the main expression. On exit, the last
17523 statement of PRE_P is the core statement being gimplified. For
17524 instance, when gimplifying 'if (++a)' the last statement in
17525 PRE_P will be 'if (t.1)' where t.1 is the result of
17526 pre-incrementing 'a'.
17528 POST_P will contain the sequence of GIMPLE statements corresponding
17529 to the evaluation of all the side-effects that must be executed
17530 after the main expression. If this is NULL, the post
17531 side-effects are stored at the end of PRE_P.
17533 The reason why the output is split in two is to handle post
17534 side-effects explicitly. In some cases, an expression may have
17535 inner and outer post side-effects which need to be emitted in
17536 an order different from the one given by the recursive
17537 traversal. For instance, for the expression (*p--)++ the post
17538 side-effects of '--' must actually occur *after* the post
17539 side-effects of '++'. However, gimplification will first visit
17540 the inner expression, so if a separate POST sequence was not
17541 used, the resulting sequence would be:
17543 1 t.1 = *p
17544 2 p = p - 1
17545 3 t.2 = t.1 + 1
17546 4 *p = t.2
17548 However, the post-decrement operation in line #2 must not be
17549 evaluated until after the store to *p at line #4, so the
17550 correct sequence should be:
17552 1 t.1 = *p
17553 2 t.2 = t.1 + 1
17554 3 *p = t.2
17555 4 p = p - 1
17557 So, by specifying a separate post queue, it is possible
17558 to emit the post side-effects in the correct order.
17559 If POST_P is NULL, an internal queue will be used. Before
17560 returning to the caller, the sequence POST_P is appended to
17561 the main output sequence PRE_P.
17563 GIMPLE_TEST_F points to a function that takes a tree T and
17564 returns nonzero if T is in the GIMPLE form requested by the
17565 caller. The GIMPLE predicates are in gimple.cc.
17567 FALLBACK tells the function what sort of a temporary we want if
17568 gimplification cannot produce an expression that complies with
17569 GIMPLE_TEST_F.
17571 fb_none means that no temporary should be generated
17572 fb_rvalue means that an rvalue is OK to generate
17573 fb_lvalue means that an lvalue is OK to generate
17574 fb_either means that either is OK, but an lvalue is preferable.
17575 fb_mayfail means that gimplification may fail (in which case
17576 GS_ERROR will be returned)
17578 The return value is either GS_ERROR or GS_ALL_DONE, since this
17579 function iterates until EXPR is completely gimplified or an error
17580 occurs. */
17582 enum gimplify_status
17583 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
17584 bool (*gimple_test_f) (tree), fallback_t fallback)
17586 tree tmp;
17587 gimple_seq internal_pre = NULL;
17588 gimple_seq internal_post = NULL;
17589 tree save_expr;
17590 bool is_statement;
17591 location_t saved_location;
17592 enum gimplify_status ret;
17593 gimple_stmt_iterator pre_last_gsi, post_last_gsi;
17594 tree label;
17596 save_expr = *expr_p;
17597 if (save_expr == NULL_TREE)
17598 return GS_ALL_DONE;
17600 /* If we are gimplifying a top-level statement, PRE_P must be valid. */
17601 is_statement = gimple_test_f == is_gimple_stmt;
17602 if (is_statement)
17603 gcc_assert (pre_p);
17605 /* Consistency checks. */
17606 if (gimple_test_f == is_gimple_reg)
17607 gcc_assert (fallback & (fb_rvalue | fb_lvalue));
17608 else if (gimple_test_f == is_gimple_val
17609 || gimple_test_f == is_gimple_call_addr
17610 || gimple_test_f == is_gimple_condexpr_for_cond
17611 || gimple_test_f == is_gimple_mem_rhs
17612 || gimple_test_f == is_gimple_mem_rhs_or_call
17613 || gimple_test_f == is_gimple_reg_rhs
17614 || gimple_test_f == is_gimple_reg_rhs_or_call
17615 || gimple_test_f == is_gimple_asm_val
17616 || gimple_test_f == is_gimple_mem_ref_addr)
17617 gcc_assert (fallback & fb_rvalue);
17618 else if (gimple_test_f == is_gimple_min_lval
17619 || gimple_test_f == is_gimple_lvalue)
17620 gcc_assert (fallback & fb_lvalue);
17621 else if (gimple_test_f == is_gimple_addressable)
17622 gcc_assert (fallback & fb_either);
17623 else if (gimple_test_f == is_gimple_stmt)
17624 gcc_assert (fallback == fb_none);
17625 else
17627 /* We should have recognized the GIMPLE_TEST_F predicate to
17628 know what kind of fallback to use in case a temporary is
17629 needed to hold the value or address of *EXPR_P. */
17630 gcc_unreachable ();
17633 /* We used to check the predicate here and return immediately if it
17634 succeeds. This is wrong; the design is for gimplification to be
17635 idempotent, and for the predicates to only test for valid forms, not
17636 whether they are fully simplified. */
17637 if (pre_p == NULL)
17638 pre_p = &internal_pre;
17640 if (post_p == NULL)
17641 post_p = &internal_post;
17643 /* Remember the last statements added to PRE_P and POST_P. Every
17644 new statement added by the gimplification helpers needs to be
17645 annotated with location information. To centralize the
17646 responsibility, we remember the last statement that had been
17647 added to both queues before gimplifying *EXPR_P. If
17648 gimplification produces new statements in PRE_P and POST_P, those
17649 statements will be annotated with the same location information
17650 as *EXPR_P. */
17651 pre_last_gsi = gsi_last (*pre_p);
17652 post_last_gsi = gsi_last (*post_p);
17654 saved_location = input_location;
17655 if (save_expr != error_mark_node
17656 && EXPR_HAS_LOCATION (*expr_p))
17657 input_location = EXPR_LOCATION (*expr_p);
17659 /* Loop over the specific gimplifiers until the toplevel node
17660 remains the same. */
17663 /* Strip away as many useless type conversions as possible
17664 at the toplevel. */
17665 STRIP_USELESS_TYPE_CONVERSION (*expr_p);
17667 /* Remember the expr. */
17668 save_expr = *expr_p;
17670 /* Die, die, die, my darling. */
17671 if (error_operand_p (save_expr))
17673 ret = GS_ERROR;
17674 break;
17677 /* Do any language-specific gimplification. */
17678 ret = ((enum gimplify_status)
17679 lang_hooks.gimplify_expr (expr_p, pre_p, post_p));
17680 if (ret == GS_OK)
17682 if (*expr_p == NULL_TREE)
17683 break;
17684 if (*expr_p != save_expr)
17685 continue;
17687 else if (ret != GS_UNHANDLED)
17688 break;
17690 /* Make sure that all the cases set 'ret' appropriately. */
17691 ret = GS_UNHANDLED;
17692 switch (TREE_CODE (*expr_p))
17694 /* First deal with the special cases. */
17696 case POSTINCREMENT_EXPR:
17697 case POSTDECREMENT_EXPR:
17698 case PREINCREMENT_EXPR:
17699 case PREDECREMENT_EXPR:
17700 ret = gimplify_self_mod_expr (expr_p, pre_p, post_p,
17701 fallback != fb_none,
17702 TREE_TYPE (*expr_p));
17703 break;
17705 case VIEW_CONVERT_EXPR:
17706 if ((fallback & fb_rvalue)
17707 && is_gimple_reg_type (TREE_TYPE (*expr_p))
17708 && is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0))))
17710 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
17711 post_p, is_gimple_val, fb_rvalue);
17712 recalculate_side_effects (*expr_p);
17713 break;
17715 /* Fallthru. */
17717 case ARRAY_REF:
17718 case ARRAY_RANGE_REF:
17719 case REALPART_EXPR:
17720 case IMAGPART_EXPR:
17721 case COMPONENT_REF:
17722 ret = gimplify_compound_lval (expr_p, pre_p, post_p,
17723 fallback ? fallback : fb_rvalue);
17724 break;
17726 case COND_EXPR:
17727 ret = gimplify_cond_expr (expr_p, pre_p, fallback);
17729 /* C99 code may assign to an array in a structure value of a
17730 conditional expression, and this has undefined behavior
17731 only on execution, so create a temporary if an lvalue is
17732 required. */
17733 if (fallback == fb_lvalue)
17735 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
17736 mark_addressable (*expr_p);
17737 ret = GS_OK;
17739 break;
17741 case CALL_EXPR:
17742 ret = gimplify_call_expr (expr_p, pre_p, fallback != fb_none);
17744 /* C99 code may assign to an array in a structure returned
17745 from a function, and this has undefined behavior only on
17746 execution, so create a temporary if an lvalue is
17747 required. */
17748 if (fallback == fb_lvalue)
17750 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
17751 mark_addressable (*expr_p);
17752 ret = GS_OK;
17754 break;
17756 case TREE_LIST:
17757 gcc_unreachable ();
17759 case COMPOUND_EXPR:
17760 ret = gimplify_compound_expr (expr_p, pre_p, fallback != fb_none);
17761 break;
17763 case COMPOUND_LITERAL_EXPR:
17764 ret = gimplify_compound_literal_expr (expr_p, pre_p,
17765 gimple_test_f, fallback);
17766 break;
17768 case MODIFY_EXPR:
17769 case INIT_EXPR:
17770 ret = gimplify_modify_expr (expr_p, pre_p, post_p,
17771 fallback != fb_none);
17772 break;
17774 case TRUTH_ANDIF_EXPR:
17775 case TRUTH_ORIF_EXPR:
17777 /* Preserve the original type of the expression and the
17778 source location of the outer expression. */
17779 tree org_type = TREE_TYPE (*expr_p);
17780 *expr_p = gimple_boolify (*expr_p);
17781 *expr_p = build3_loc (input_location, COND_EXPR,
17782 org_type, *expr_p,
17783 fold_convert_loc
17784 (input_location,
17785 org_type, boolean_true_node),
17786 fold_convert_loc
17787 (input_location,
17788 org_type, boolean_false_node));
17789 ret = GS_OK;
17790 break;
17793 case TRUTH_NOT_EXPR:
17795 tree type = TREE_TYPE (*expr_p);
17796 /* The parsers are careful to generate TRUTH_NOT_EXPR
17797 only with operands that are always zero or one.
17798 We do not fold here but handle the only interesting case
17799 manually, as fold may re-introduce the TRUTH_NOT_EXPR. */
17800 *expr_p = gimple_boolify (*expr_p);
17801 if (TYPE_PRECISION (TREE_TYPE (*expr_p)) == 1)
17802 *expr_p = build1_loc (input_location, BIT_NOT_EXPR,
17803 TREE_TYPE (*expr_p),
17804 TREE_OPERAND (*expr_p, 0));
17805 else
17806 *expr_p = build2_loc (input_location, BIT_XOR_EXPR,
17807 TREE_TYPE (*expr_p),
17808 TREE_OPERAND (*expr_p, 0),
17809 build_int_cst (TREE_TYPE (*expr_p), 1));
17810 if (!useless_type_conversion_p (type, TREE_TYPE (*expr_p)))
17811 *expr_p = fold_convert_loc (input_location, type, *expr_p);
17812 ret = GS_OK;
17813 break;
17816 case ADDR_EXPR:
17817 ret = gimplify_addr_expr (expr_p, pre_p, post_p);
17818 break;
17820 case ANNOTATE_EXPR:
17822 tree cond = TREE_OPERAND (*expr_p, 0);
17823 tree kind = TREE_OPERAND (*expr_p, 1);
17824 tree data = TREE_OPERAND (*expr_p, 2);
17825 tree type = TREE_TYPE (cond);
17826 if (!INTEGRAL_TYPE_P (type))
17828 *expr_p = cond;
17829 ret = GS_OK;
17830 break;
17832 tree tmp = create_tmp_var (type);
17833 gimplify_arg (&cond, pre_p, EXPR_LOCATION (*expr_p));
17834 gcall *call
17835 = gimple_build_call_internal (IFN_ANNOTATE, 3, cond, kind, data);
17836 gimple_call_set_lhs (call, tmp);
17837 gimplify_seq_add_stmt (pre_p, call);
17838 *expr_p = tmp;
17839 ret = GS_ALL_DONE;
17840 break;
17843 case VA_ARG_EXPR:
17844 ret = gimplify_va_arg_expr (expr_p, pre_p, post_p);
17845 break;
17847 CASE_CONVERT:
17848 if (IS_EMPTY_STMT (*expr_p))
17850 ret = GS_ALL_DONE;
17851 break;
17854 if (VOID_TYPE_P (TREE_TYPE (*expr_p))
17855 || fallback == fb_none)
17857 /* Just strip a conversion to void (or in void context) and
17858 try again. */
17859 *expr_p = TREE_OPERAND (*expr_p, 0);
17860 ret = GS_OK;
17861 break;
17864 ret = gimplify_conversion (expr_p);
17865 if (ret == GS_ERROR)
17866 break;
17867 if (*expr_p != save_expr)
17868 break;
17869 /* FALLTHRU */
17871 case FIX_TRUNC_EXPR:
17872 /* unary_expr: ... | '(' cast ')' val | ... */
17873 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
17874 is_gimple_val, fb_rvalue);
17875 recalculate_side_effects (*expr_p);
17876 break;
17878 case INDIRECT_REF:
17880 bool volatilep = TREE_THIS_VOLATILE (*expr_p);
17881 bool notrap = TREE_THIS_NOTRAP (*expr_p);
17882 tree saved_ptr_type = TREE_TYPE (TREE_OPERAND (*expr_p, 0));
17884 *expr_p = fold_indirect_ref_loc (input_location, *expr_p);
17885 if (*expr_p != save_expr)
17887 ret = GS_OK;
17888 break;
17891 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
17892 is_gimple_reg, fb_rvalue);
17893 if (ret == GS_ERROR)
17894 break;
17896 recalculate_side_effects (*expr_p);
17897 *expr_p = fold_build2_loc (input_location, MEM_REF,
17898 TREE_TYPE (*expr_p),
17899 TREE_OPERAND (*expr_p, 0),
17900 build_int_cst (saved_ptr_type, 0));
17901 TREE_THIS_VOLATILE (*expr_p) = volatilep;
17902 TREE_THIS_NOTRAP (*expr_p) = notrap;
17903 ret = GS_OK;
17904 break;
17907 /* We arrive here through the various re-gimplifcation paths. */
17908 case MEM_REF:
17909 /* First try re-folding the whole thing. */
17910 tmp = fold_binary (MEM_REF, TREE_TYPE (*expr_p),
17911 TREE_OPERAND (*expr_p, 0),
17912 TREE_OPERAND (*expr_p, 1));
17913 if (tmp)
17915 REF_REVERSE_STORAGE_ORDER (tmp)
17916 = REF_REVERSE_STORAGE_ORDER (*expr_p);
17917 *expr_p = tmp;
17918 recalculate_side_effects (*expr_p);
17919 ret = GS_OK;
17920 break;
17922 /* Avoid re-gimplifying the address operand if it is already
17923 in suitable form. Re-gimplifying would mark the address
17924 operand addressable. Always gimplify when not in SSA form
17925 as we still may have to gimplify decls with value-exprs. */
17926 if (!gimplify_ctxp || !gimple_in_ssa_p (cfun)
17927 || !is_gimple_mem_ref_addr (TREE_OPERAND (*expr_p, 0)))
17929 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
17930 is_gimple_mem_ref_addr, fb_rvalue);
17931 if (ret == GS_ERROR)
17932 break;
17934 recalculate_side_effects (*expr_p);
17935 ret = GS_ALL_DONE;
17936 break;
17938 /* Constants need not be gimplified. */
17939 case INTEGER_CST:
17940 case REAL_CST:
17941 case FIXED_CST:
17942 case STRING_CST:
17943 case COMPLEX_CST:
17944 case VECTOR_CST:
17945 /* Drop the overflow flag on constants, we do not want
17946 that in the GIMPLE IL. */
17947 if (TREE_OVERFLOW_P (*expr_p))
17948 *expr_p = drop_tree_overflow (*expr_p);
17949 ret = GS_ALL_DONE;
17950 break;
17952 case CONST_DECL:
17953 /* If we require an lvalue, such as for ADDR_EXPR, retain the
17954 CONST_DECL node. Otherwise the decl is replaceable by its
17955 value. */
17956 /* ??? Should be == fb_lvalue, but ADDR_EXPR passes fb_either. */
17957 if (fallback & fb_lvalue)
17958 ret = GS_ALL_DONE;
17959 else
17961 *expr_p = DECL_INITIAL (*expr_p);
17962 ret = GS_OK;
17964 break;
17966 case DECL_EXPR:
17967 ret = gimplify_decl_expr (expr_p, pre_p);
17968 break;
17970 case BIND_EXPR:
17971 ret = gimplify_bind_expr (expr_p, pre_p);
17972 break;
17974 case LOOP_EXPR:
17975 ret = gimplify_loop_expr (expr_p, pre_p);
17976 break;
17978 case SWITCH_EXPR:
17979 ret = gimplify_switch_expr (expr_p, pre_p);
17980 break;
17982 case EXIT_EXPR:
17983 ret = gimplify_exit_expr (expr_p);
17984 break;
17986 case GOTO_EXPR:
17987 /* If the target is not LABEL, then it is a computed jump
17988 and the target needs to be gimplified. */
17989 if (TREE_CODE (GOTO_DESTINATION (*expr_p)) != LABEL_DECL)
17991 ret = gimplify_expr (&GOTO_DESTINATION (*expr_p), pre_p,
17992 NULL, is_gimple_val, fb_rvalue);
17993 if (ret == GS_ERROR)
17994 break;
17996 gimplify_seq_add_stmt (pre_p,
17997 gimple_build_goto (GOTO_DESTINATION (*expr_p)));
17998 ret = GS_ALL_DONE;
17999 break;
18001 case PREDICT_EXPR:
18002 gimplify_seq_add_stmt (pre_p,
18003 gimple_build_predict (PREDICT_EXPR_PREDICTOR (*expr_p),
18004 PREDICT_EXPR_OUTCOME (*expr_p)));
18005 ret = GS_ALL_DONE;
18006 break;
18008 case LABEL_EXPR:
18009 ret = gimplify_label_expr (expr_p, pre_p);
18010 label = LABEL_EXPR_LABEL (*expr_p);
18011 gcc_assert (decl_function_context (label) == current_function_decl);
18013 /* If the label is used in a goto statement, or address of the label
18014 is taken, we need to unpoison all variables that were seen so far.
18015 Doing so would prevent us from reporting a false positives. */
18016 if (asan_poisoned_variables
18017 && asan_used_labels != NULL
18018 && asan_used_labels->contains (label)
18019 && !gimplify_omp_ctxp)
18020 asan_poison_variables (asan_poisoned_variables, false, pre_p);
18021 break;
18023 case CASE_LABEL_EXPR:
18024 ret = gimplify_case_label_expr (expr_p, pre_p);
18026 if (gimplify_ctxp->live_switch_vars)
18027 asan_poison_variables (gimplify_ctxp->live_switch_vars, false,
18028 pre_p);
18029 break;
18031 case RETURN_EXPR:
18032 ret = gimplify_return_expr (*expr_p, pre_p);
18033 break;
18035 case CONSTRUCTOR:
18036 /* Don't reduce this in place; let gimplify_init_constructor work its
18037 magic. Buf if we're just elaborating this for side effects, just
18038 gimplify any element that has side-effects. */
18039 if (fallback == fb_none)
18041 unsigned HOST_WIDE_INT ix;
18042 tree val;
18043 tree temp = NULL_TREE;
18044 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (*expr_p), ix, val)
18045 if (TREE_SIDE_EFFECTS (val))
18046 append_to_statement_list (val, &temp);
18048 *expr_p = temp;
18049 ret = temp ? GS_OK : GS_ALL_DONE;
18051 /* C99 code may assign to an array in a constructed
18052 structure or union, and this has undefined behavior only
18053 on execution, so create a temporary if an lvalue is
18054 required. */
18055 else if (fallback == fb_lvalue)
18057 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
18058 mark_addressable (*expr_p);
18059 ret = GS_OK;
18061 else
18062 ret = GS_ALL_DONE;
18063 break;
18065 /* The following are special cases that are not handled by the
18066 original GIMPLE grammar. */
18068 /* SAVE_EXPR nodes are converted into a GIMPLE identifier and
18069 eliminated. */
18070 case SAVE_EXPR:
18071 ret = gimplify_save_expr (expr_p, pre_p, post_p);
18072 break;
18074 case BIT_FIELD_REF:
18075 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
18076 post_p, is_gimple_lvalue, fb_either);
18077 recalculate_side_effects (*expr_p);
18078 break;
18080 case TARGET_MEM_REF:
18082 enum gimplify_status r0 = GS_ALL_DONE, r1 = GS_ALL_DONE;
18084 if (TMR_BASE (*expr_p))
18085 r0 = gimplify_expr (&TMR_BASE (*expr_p), pre_p,
18086 post_p, is_gimple_mem_ref_addr, fb_either);
18087 if (TMR_INDEX (*expr_p))
18088 r1 = gimplify_expr (&TMR_INDEX (*expr_p), pre_p,
18089 post_p, is_gimple_val, fb_rvalue);
18090 if (TMR_INDEX2 (*expr_p))
18091 r1 = gimplify_expr (&TMR_INDEX2 (*expr_p), pre_p,
18092 post_p, is_gimple_val, fb_rvalue);
18093 /* TMR_STEP and TMR_OFFSET are always integer constants. */
18094 ret = MIN (r0, r1);
18096 break;
18098 case NON_LVALUE_EXPR:
18099 /* This should have been stripped above. */
18100 gcc_unreachable ();
18102 case ASM_EXPR:
18103 ret = gimplify_asm_expr (expr_p, pre_p, post_p);
18104 break;
18106 case TRY_FINALLY_EXPR:
18107 case TRY_CATCH_EXPR:
18109 gimple_seq eval, cleanup;
18110 gtry *try_;
18112 /* Calls to destructors are generated automatically in FINALLY/CATCH
18113 block. They should have location as UNKNOWN_LOCATION. However,
18114 gimplify_call_expr will reset these call stmts to input_location
18115 if it finds stmt's location is unknown. To prevent resetting for
18116 destructors, we set the input_location to unknown.
18117 Note that this only affects the destructor calls in FINALLY/CATCH
18118 block, and will automatically reset to its original value by the
18119 end of gimplify_expr. */
18120 input_location = UNKNOWN_LOCATION;
18121 eval = cleanup = NULL;
18122 gimplify_and_add (TREE_OPERAND (*expr_p, 0), &eval);
18123 if (TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
18124 && TREE_CODE (TREE_OPERAND (*expr_p, 1)) == EH_ELSE_EXPR)
18126 gimple_seq n = NULL, e = NULL;
18127 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1),
18128 0), &n);
18129 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1),
18130 1), &e);
18131 if (!gimple_seq_empty_p (n) && !gimple_seq_empty_p (e))
18133 geh_else *stmt = gimple_build_eh_else (n, e);
18134 gimple_seq_add_stmt (&cleanup, stmt);
18137 else
18138 gimplify_and_add (TREE_OPERAND (*expr_p, 1), &cleanup);
18139 /* Don't create bogus GIMPLE_TRY with empty cleanup. */
18140 if (gimple_seq_empty_p (cleanup))
18142 gimple_seq_add_seq (pre_p, eval);
18143 ret = GS_ALL_DONE;
18144 break;
18146 try_ = gimple_build_try (eval, cleanup,
18147 TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
18148 ? GIMPLE_TRY_FINALLY
18149 : GIMPLE_TRY_CATCH);
18150 if (EXPR_HAS_LOCATION (save_expr))
18151 gimple_set_location (try_, EXPR_LOCATION (save_expr));
18152 else if (LOCATION_LOCUS (saved_location) != UNKNOWN_LOCATION)
18153 gimple_set_location (try_, saved_location);
18154 if (TREE_CODE (*expr_p) == TRY_CATCH_EXPR)
18155 gimple_try_set_catch_is_cleanup (try_,
18156 TRY_CATCH_IS_CLEANUP (*expr_p));
18157 gimplify_seq_add_stmt (pre_p, try_);
18158 ret = GS_ALL_DONE;
18159 break;
18162 case CLEANUP_POINT_EXPR:
18163 ret = gimplify_cleanup_point_expr (expr_p, pre_p);
18164 break;
18166 case TARGET_EXPR:
18167 ret = gimplify_target_expr (expr_p, pre_p, post_p);
18168 break;
18170 case CATCH_EXPR:
18172 gimple *c;
18173 gimple_seq handler = NULL;
18174 gimplify_and_add (CATCH_BODY (*expr_p), &handler);
18175 c = gimple_build_catch (CATCH_TYPES (*expr_p), handler);
18176 gimplify_seq_add_stmt (pre_p, c);
18177 ret = GS_ALL_DONE;
18178 break;
18181 case EH_FILTER_EXPR:
18183 gimple *ehf;
18184 gimple_seq failure = NULL;
18186 gimplify_and_add (EH_FILTER_FAILURE (*expr_p), &failure);
18187 ehf = gimple_build_eh_filter (EH_FILTER_TYPES (*expr_p), failure);
18188 copy_warning (ehf, *expr_p);
18189 gimplify_seq_add_stmt (pre_p, ehf);
18190 ret = GS_ALL_DONE;
18191 break;
18194 case OBJ_TYPE_REF:
18196 enum gimplify_status r0, r1;
18197 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p,
18198 post_p, is_gimple_val, fb_rvalue);
18199 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p,
18200 post_p, is_gimple_val, fb_rvalue);
18201 TREE_SIDE_EFFECTS (*expr_p) = 0;
18202 ret = MIN (r0, r1);
18204 break;
18206 case LABEL_DECL:
18207 /* We get here when taking the address of a label. We mark
18208 the label as "forced"; meaning it can never be removed and
18209 it is a potential target for any computed goto. */
18210 FORCED_LABEL (*expr_p) = 1;
18211 ret = GS_ALL_DONE;
18212 break;
18214 case STATEMENT_LIST:
18215 ret = gimplify_statement_list (expr_p, pre_p);
18216 break;
18218 case WITH_SIZE_EXPR:
18220 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
18221 post_p == &internal_post ? NULL : post_p,
18222 gimple_test_f, fallback);
18223 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
18224 is_gimple_val, fb_rvalue);
18225 ret = GS_ALL_DONE;
18227 break;
18229 case VAR_DECL:
18230 case PARM_DECL:
18231 ret = gimplify_var_or_parm_decl (expr_p);
18232 break;
18234 case RESULT_DECL:
18235 /* When within an OMP context, notice uses of variables. */
18236 if (gimplify_omp_ctxp)
18237 omp_notice_variable (gimplify_omp_ctxp, *expr_p, true);
18238 ret = GS_ALL_DONE;
18239 break;
18241 case DEBUG_EXPR_DECL:
18242 gcc_unreachable ();
18244 case DEBUG_BEGIN_STMT:
18245 gimplify_seq_add_stmt (pre_p,
18246 gimple_build_debug_begin_stmt
18247 (TREE_BLOCK (*expr_p),
18248 EXPR_LOCATION (*expr_p)));
18249 ret = GS_ALL_DONE;
18250 *expr_p = NULL;
18251 break;
18253 case SSA_NAME:
18254 /* Allow callbacks into the gimplifier during optimization. */
18255 ret = GS_ALL_DONE;
18256 break;
18258 case OMP_PARALLEL:
18259 gimplify_omp_parallel (expr_p, pre_p);
18260 ret = GS_ALL_DONE;
18261 break;
18263 case OMP_TASK:
18264 gimplify_omp_task (expr_p, pre_p);
18265 ret = GS_ALL_DONE;
18266 break;
18268 case OMP_SIMD:
18270 /* Temporarily disable into_ssa, as scan_omp_simd
18271 which calls copy_gimple_seq_and_replace_locals can't deal
18272 with SSA_NAMEs defined outside of the body properly. */
18273 bool saved_into_ssa = gimplify_ctxp->into_ssa;
18274 gimplify_ctxp->into_ssa = false;
18275 ret = gimplify_omp_for (expr_p, pre_p);
18276 gimplify_ctxp->into_ssa = saved_into_ssa;
18277 break;
18280 case OMP_FOR:
18281 case OMP_DISTRIBUTE:
18282 case OMP_TASKLOOP:
18283 case OACC_LOOP:
18284 ret = gimplify_omp_for (expr_p, pre_p);
18285 break;
18287 case OMP_LOOP:
18288 ret = gimplify_omp_loop (expr_p, pre_p);
18289 break;
18291 case OACC_CACHE:
18292 gimplify_oacc_cache (expr_p, pre_p);
18293 ret = GS_ALL_DONE;
18294 break;
18296 case OACC_DECLARE:
18297 gimplify_oacc_declare (expr_p, pre_p);
18298 ret = GS_ALL_DONE;
18299 break;
18301 case OACC_HOST_DATA:
18302 case OACC_DATA:
18303 case OACC_KERNELS:
18304 case OACC_PARALLEL:
18305 case OACC_SERIAL:
18306 case OMP_SCOPE:
18307 case OMP_SECTIONS:
18308 case OMP_SINGLE:
18309 case OMP_TARGET:
18310 case OMP_TARGET_DATA:
18311 case OMP_TEAMS:
18312 gimplify_omp_workshare (expr_p, pre_p);
18313 ret = GS_ALL_DONE;
18314 break;
18316 case OACC_ENTER_DATA:
18317 case OACC_EXIT_DATA:
18318 case OACC_UPDATE:
18319 case OMP_TARGET_UPDATE:
18320 case OMP_TARGET_ENTER_DATA:
18321 case OMP_TARGET_EXIT_DATA:
18322 gimplify_omp_target_update (expr_p, pre_p);
18323 ret = GS_ALL_DONE;
18324 break;
18326 case OMP_SECTION:
18327 case OMP_STRUCTURED_BLOCK:
18328 case OMP_MASTER:
18329 case OMP_MASKED:
18330 case OMP_ORDERED:
18331 case OMP_CRITICAL:
18332 case OMP_SCAN:
18334 gimple_seq body = NULL;
18335 gimple *g;
18336 bool saved_in_omp_construct = in_omp_construct;
18338 in_omp_construct = true;
18339 gimplify_and_add (OMP_BODY (*expr_p), &body);
18340 in_omp_construct = saved_in_omp_construct;
18341 switch (TREE_CODE (*expr_p))
18343 case OMP_SECTION:
18344 g = gimple_build_omp_section (body);
18345 break;
18346 case OMP_STRUCTURED_BLOCK:
18347 g = gimple_build_omp_structured_block (body);
18348 break;
18349 case OMP_MASTER:
18350 g = gimple_build_omp_master (body);
18351 break;
18352 case OMP_ORDERED:
18353 g = gimplify_omp_ordered (*expr_p, body);
18354 if (OMP_BODY (*expr_p) == NULL_TREE
18355 && gimple_code (g) == GIMPLE_OMP_ORDERED)
18356 gimple_omp_ordered_standalone (g);
18357 break;
18358 case OMP_MASKED:
18359 gimplify_scan_omp_clauses (&OMP_MASKED_CLAUSES (*expr_p),
18360 pre_p, ORT_WORKSHARE, OMP_MASKED);
18361 gimplify_adjust_omp_clauses (pre_p, body,
18362 &OMP_MASKED_CLAUSES (*expr_p),
18363 OMP_MASKED);
18364 g = gimple_build_omp_masked (body,
18365 OMP_MASKED_CLAUSES (*expr_p));
18366 break;
18367 case OMP_CRITICAL:
18368 gimplify_scan_omp_clauses (&OMP_CRITICAL_CLAUSES (*expr_p),
18369 pre_p, ORT_WORKSHARE, OMP_CRITICAL);
18370 gimplify_adjust_omp_clauses (pre_p, body,
18371 &OMP_CRITICAL_CLAUSES (*expr_p),
18372 OMP_CRITICAL);
18373 g = gimple_build_omp_critical (body,
18374 OMP_CRITICAL_NAME (*expr_p),
18375 OMP_CRITICAL_CLAUSES (*expr_p));
18376 break;
18377 case OMP_SCAN:
18378 gimplify_scan_omp_clauses (&OMP_SCAN_CLAUSES (*expr_p),
18379 pre_p, ORT_WORKSHARE, OMP_SCAN);
18380 gimplify_adjust_omp_clauses (pre_p, body,
18381 &OMP_SCAN_CLAUSES (*expr_p),
18382 OMP_SCAN);
18383 g = gimple_build_omp_scan (body, OMP_SCAN_CLAUSES (*expr_p));
18384 break;
18385 default:
18386 gcc_unreachable ();
18388 gimplify_seq_add_stmt (pre_p, g);
18389 ret = GS_ALL_DONE;
18390 break;
18393 case OMP_TASKGROUP:
18395 gimple_seq body = NULL;
18397 tree *pclauses = &OMP_TASKGROUP_CLAUSES (*expr_p);
18398 bool saved_in_omp_construct = in_omp_construct;
18399 gimplify_scan_omp_clauses (pclauses, pre_p, ORT_TASKGROUP,
18400 OMP_TASKGROUP);
18401 gimplify_adjust_omp_clauses (pre_p, NULL, pclauses, OMP_TASKGROUP);
18403 in_omp_construct = true;
18404 gimplify_and_add (OMP_BODY (*expr_p), &body);
18405 in_omp_construct = saved_in_omp_construct;
18406 gimple_seq cleanup = NULL;
18407 tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_END);
18408 gimple *g = gimple_build_call (fn, 0);
18409 gimple_seq_add_stmt (&cleanup, g);
18410 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
18411 body = NULL;
18412 gimple_seq_add_stmt (&body, g);
18413 g = gimple_build_omp_taskgroup (body, *pclauses);
18414 gimplify_seq_add_stmt (pre_p, g);
18415 ret = GS_ALL_DONE;
18416 break;
18419 case OMP_ATOMIC:
18420 case OMP_ATOMIC_READ:
18421 case OMP_ATOMIC_CAPTURE_OLD:
18422 case OMP_ATOMIC_CAPTURE_NEW:
18423 ret = gimplify_omp_atomic (expr_p, pre_p);
18424 break;
18426 case TRANSACTION_EXPR:
18427 ret = gimplify_transaction (expr_p, pre_p);
18428 break;
18430 case TRUTH_AND_EXPR:
18431 case TRUTH_OR_EXPR:
18432 case TRUTH_XOR_EXPR:
18434 tree orig_type = TREE_TYPE (*expr_p);
18435 tree new_type, xop0, xop1;
18436 *expr_p = gimple_boolify (*expr_p);
18437 new_type = TREE_TYPE (*expr_p);
18438 if (!useless_type_conversion_p (orig_type, new_type))
18440 *expr_p = fold_convert_loc (input_location, orig_type, *expr_p);
18441 ret = GS_OK;
18442 break;
18445 /* Boolified binary truth expressions are semantically equivalent
18446 to bitwise binary expressions. Canonicalize them to the
18447 bitwise variant. */
18448 switch (TREE_CODE (*expr_p))
18450 case TRUTH_AND_EXPR:
18451 TREE_SET_CODE (*expr_p, BIT_AND_EXPR);
18452 break;
18453 case TRUTH_OR_EXPR:
18454 TREE_SET_CODE (*expr_p, BIT_IOR_EXPR);
18455 break;
18456 case TRUTH_XOR_EXPR:
18457 TREE_SET_CODE (*expr_p, BIT_XOR_EXPR);
18458 break;
18459 default:
18460 break;
18462 /* Now make sure that operands have compatible type to
18463 expression's new_type. */
18464 xop0 = TREE_OPERAND (*expr_p, 0);
18465 xop1 = TREE_OPERAND (*expr_p, 1);
18466 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop0)))
18467 TREE_OPERAND (*expr_p, 0) = fold_convert_loc (input_location,
18468 new_type,
18469 xop0);
18470 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop1)))
18471 TREE_OPERAND (*expr_p, 1) = fold_convert_loc (input_location,
18472 new_type,
18473 xop1);
18474 /* Continue classified as tcc_binary. */
18475 goto expr_2;
18478 case VEC_COND_EXPR:
18479 goto expr_3;
18481 case VEC_PERM_EXPR:
18482 /* Classified as tcc_expression. */
18483 goto expr_3;
18485 case BIT_INSERT_EXPR:
18486 /* Argument 3 is a constant. */
18487 goto expr_2;
18489 case POINTER_PLUS_EXPR:
18491 enum gimplify_status r0, r1;
18492 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
18493 post_p, is_gimple_val, fb_rvalue);
18494 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
18495 post_p, is_gimple_val, fb_rvalue);
18496 recalculate_side_effects (*expr_p);
18497 ret = MIN (r0, r1);
18498 break;
18501 default:
18502 switch (TREE_CODE_CLASS (TREE_CODE (*expr_p)))
18504 case tcc_comparison:
18505 /* Handle comparison of objects of non scalar mode aggregates
18506 with a call to memcmp. It would be nice to only have to do
18507 this for variable-sized objects, but then we'd have to allow
18508 the same nest of reference nodes we allow for MODIFY_EXPR and
18509 that's too complex.
18511 Compare scalar mode aggregates as scalar mode values. Using
18512 memcmp for them would be very inefficient at best, and is
18513 plain wrong if bitfields are involved. */
18514 if (error_operand_p (TREE_OPERAND (*expr_p, 1)))
18515 ret = GS_ERROR;
18516 else
18518 tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 1));
18520 /* Vector comparisons need no boolification. */
18521 if (TREE_CODE (type) == VECTOR_TYPE)
18522 goto expr_2;
18523 else if (!AGGREGATE_TYPE_P (type))
18525 tree org_type = TREE_TYPE (*expr_p);
18526 *expr_p = gimple_boolify (*expr_p);
18527 if (!useless_type_conversion_p (org_type,
18528 TREE_TYPE (*expr_p)))
18530 *expr_p = fold_convert_loc (input_location,
18531 org_type, *expr_p);
18532 ret = GS_OK;
18534 else
18535 goto expr_2;
18537 else if (TYPE_MODE (type) != BLKmode)
18538 ret = gimplify_scalar_mode_aggregate_compare (expr_p);
18539 else
18540 ret = gimplify_variable_sized_compare (expr_p);
18542 break;
18544 /* If *EXPR_P does not need to be special-cased, handle it
18545 according to its class. */
18546 case tcc_unary:
18547 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
18548 post_p, is_gimple_val, fb_rvalue);
18549 break;
18551 case tcc_binary:
18552 expr_2:
18554 enum gimplify_status r0, r1;
18556 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
18557 post_p, is_gimple_val, fb_rvalue);
18558 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
18559 post_p, is_gimple_val, fb_rvalue);
18561 ret = MIN (r0, r1);
18562 break;
18565 expr_3:
18567 enum gimplify_status r0, r1, r2;
18569 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
18570 post_p, is_gimple_val, fb_rvalue);
18571 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
18572 post_p, is_gimple_val, fb_rvalue);
18573 r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p,
18574 post_p, is_gimple_val, fb_rvalue);
18576 ret = MIN (MIN (r0, r1), r2);
18577 break;
18580 case tcc_declaration:
18581 case tcc_constant:
18582 ret = GS_ALL_DONE;
18583 goto dont_recalculate;
18585 default:
18586 gcc_unreachable ();
18589 recalculate_side_effects (*expr_p);
18591 dont_recalculate:
18592 break;
18595 gcc_assert (*expr_p || ret != GS_OK);
18597 while (ret == GS_OK);
18599 /* If we encountered an error_mark somewhere nested inside, either
18600 stub out the statement or propagate the error back out. */
18601 if (ret == GS_ERROR)
18603 if (is_statement)
18604 *expr_p = NULL;
18605 goto out;
18608 /* This was only valid as a return value from the langhook, which
18609 we handled. Make sure it doesn't escape from any other context. */
18610 gcc_assert (ret != GS_UNHANDLED);
18612 if (fallback == fb_none && *expr_p && !is_gimple_stmt (*expr_p))
18614 /* We aren't looking for a value, and we don't have a valid
18615 statement. If it doesn't have side-effects, throw it away.
18616 We can also get here with code such as "*&&L;", where L is
18617 a LABEL_DECL that is marked as FORCED_LABEL. */
18618 if (TREE_CODE (*expr_p) == LABEL_DECL
18619 || !TREE_SIDE_EFFECTS (*expr_p))
18620 *expr_p = NULL;
18621 else if (!TREE_THIS_VOLATILE (*expr_p))
18623 /* This is probably a _REF that contains something nested that
18624 has side effects. Recurse through the operands to find it. */
18625 enum tree_code code = TREE_CODE (*expr_p);
18627 switch (code)
18629 case COMPONENT_REF:
18630 case REALPART_EXPR:
18631 case IMAGPART_EXPR:
18632 case VIEW_CONVERT_EXPR:
18633 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
18634 gimple_test_f, fallback);
18635 break;
18637 case ARRAY_REF:
18638 case ARRAY_RANGE_REF:
18639 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
18640 gimple_test_f, fallback);
18641 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
18642 gimple_test_f, fallback);
18643 break;
18645 default:
18646 /* Anything else with side-effects must be converted to
18647 a valid statement before we get here. */
18648 gcc_unreachable ();
18651 *expr_p = NULL;
18653 else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p))
18654 && TYPE_MODE (TREE_TYPE (*expr_p)) != BLKmode
18655 && !is_empty_type (TREE_TYPE (*expr_p)))
18657 /* Historically, the compiler has treated a bare reference
18658 to a non-BLKmode volatile lvalue as forcing a load. */
18659 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p));
18661 /* Normally, we do not want to create a temporary for a
18662 TREE_ADDRESSABLE type because such a type should not be
18663 copied by bitwise-assignment. However, we make an
18664 exception here, as all we are doing here is ensuring that
18665 we read the bytes that make up the type. We use
18666 create_tmp_var_raw because create_tmp_var will abort when
18667 given a TREE_ADDRESSABLE type. */
18668 tree tmp = create_tmp_var_raw (type, "vol");
18669 gimple_add_tmp_var (tmp);
18670 gimplify_assign (tmp, *expr_p, pre_p);
18671 *expr_p = NULL;
18673 else
18674 /* We can't do anything useful with a volatile reference to
18675 an incomplete type, so just throw it away. Likewise for
18676 a BLKmode type, since any implicit inner load should
18677 already have been turned into an explicit one by the
18678 gimplification process. */
18679 *expr_p = NULL;
18682 /* If we are gimplifying at the statement level, we're done. Tack
18683 everything together and return. */
18684 if (fallback == fb_none || is_statement)
18686 /* Since *EXPR_P has been converted into a GIMPLE tuple, clear
18687 it out for GC to reclaim it. */
18688 *expr_p = NULL_TREE;
18690 if (!gimple_seq_empty_p (internal_pre)
18691 || !gimple_seq_empty_p (internal_post))
18693 gimplify_seq_add_seq (&internal_pre, internal_post);
18694 gimplify_seq_add_seq (pre_p, internal_pre);
18697 /* The result of gimplifying *EXPR_P is going to be the last few
18698 statements in *PRE_P and *POST_P. Add location information
18699 to all the statements that were added by the gimplification
18700 helpers. */
18701 if (!gimple_seq_empty_p (*pre_p))
18702 annotate_all_with_location_after (*pre_p, pre_last_gsi, input_location);
18704 if (!gimple_seq_empty_p (*post_p))
18705 annotate_all_with_location_after (*post_p, post_last_gsi,
18706 input_location);
18708 goto out;
18711 #ifdef ENABLE_GIMPLE_CHECKING
18712 if (*expr_p)
18714 enum tree_code code = TREE_CODE (*expr_p);
18715 /* These expressions should already be in gimple IR form. */
18716 gcc_assert (code != MODIFY_EXPR
18717 && code != ASM_EXPR
18718 && code != BIND_EXPR
18719 && code != CATCH_EXPR
18720 && (code != COND_EXPR || gimplify_ctxp->allow_rhs_cond_expr)
18721 && code != EH_FILTER_EXPR
18722 && code != GOTO_EXPR
18723 && code != LABEL_EXPR
18724 && code != LOOP_EXPR
18725 && code != SWITCH_EXPR
18726 && code != TRY_FINALLY_EXPR
18727 && code != EH_ELSE_EXPR
18728 && code != OACC_PARALLEL
18729 && code != OACC_KERNELS
18730 && code != OACC_SERIAL
18731 && code != OACC_DATA
18732 && code != OACC_HOST_DATA
18733 && code != OACC_DECLARE
18734 && code != OACC_UPDATE
18735 && code != OACC_ENTER_DATA
18736 && code != OACC_EXIT_DATA
18737 && code != OACC_CACHE
18738 && code != OMP_CRITICAL
18739 && code != OMP_FOR
18740 && code != OACC_LOOP
18741 && code != OMP_MASTER
18742 && code != OMP_MASKED
18743 && code != OMP_TASKGROUP
18744 && code != OMP_ORDERED
18745 && code != OMP_PARALLEL
18746 && code != OMP_SCAN
18747 && code != OMP_SECTIONS
18748 && code != OMP_SECTION
18749 && code != OMP_STRUCTURED_BLOCK
18750 && code != OMP_SINGLE
18751 && code != OMP_SCOPE);
18753 #endif
18755 /* Otherwise we're gimplifying a subexpression, so the resulting
18756 value is interesting. If it's a valid operand that matches
18757 GIMPLE_TEST_F, we're done. Unless we are handling some
18758 post-effects internally; if that's the case, we need to copy into
18759 a temporary before adding the post-effects to POST_P. */
18760 if (gimple_seq_empty_p (internal_post) && (*gimple_test_f) (*expr_p))
18761 goto out;
18763 /* Otherwise, we need to create a new temporary for the gimplified
18764 expression. */
18766 /* We can't return an lvalue if we have an internal postqueue. The
18767 object the lvalue refers to would (probably) be modified by the
18768 postqueue; we need to copy the value out first, which means an
18769 rvalue. */
18770 if ((fallback & fb_lvalue)
18771 && gimple_seq_empty_p (internal_post)
18772 && is_gimple_addressable (*expr_p))
18774 /* An lvalue will do. Take the address of the expression, store it
18775 in a temporary, and replace the expression with an INDIRECT_REF of
18776 that temporary. */
18777 tree ref_alias_type = reference_alias_ptr_type (*expr_p);
18778 unsigned int ref_align = get_object_alignment (*expr_p);
18779 tree ref_type = TREE_TYPE (*expr_p);
18780 tmp = build_fold_addr_expr_loc (input_location, *expr_p);
18781 gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue);
18782 if (TYPE_ALIGN (ref_type) != ref_align)
18783 ref_type = build_aligned_type (ref_type, ref_align);
18784 *expr_p = build2 (MEM_REF, ref_type,
18785 tmp, build_zero_cst (ref_alias_type));
18787 else if ((fallback & fb_rvalue) && is_gimple_reg_rhs_or_call (*expr_p))
18789 /* An rvalue will do. Assign the gimplified expression into a
18790 new temporary TMP and replace the original expression with
18791 TMP. First, make sure that the expression has a type so that
18792 it can be assigned into a temporary. */
18793 gcc_assert (!VOID_TYPE_P (TREE_TYPE (*expr_p)));
18794 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
18796 else
18798 #ifdef ENABLE_GIMPLE_CHECKING
18799 if (!(fallback & fb_mayfail))
18801 fprintf (stderr, "gimplification failed:\n");
18802 print_generic_expr (stderr, *expr_p);
18803 debug_tree (*expr_p);
18804 internal_error ("gimplification failed");
18806 #endif
18807 gcc_assert (fallback & fb_mayfail);
18809 /* If this is an asm statement, and the user asked for the
18810 impossible, don't die. Fail and let gimplify_asm_expr
18811 issue an error. */
18812 ret = GS_ERROR;
18813 goto out;
18816 /* Make sure the temporary matches our predicate. */
18817 gcc_assert ((*gimple_test_f) (*expr_p));
18819 if (!gimple_seq_empty_p (internal_post))
18821 annotate_all_with_location (internal_post, input_location);
18822 gimplify_seq_add_seq (pre_p, internal_post);
18825 out:
18826 input_location = saved_location;
18827 return ret;
18830 /* Like gimplify_expr but make sure the gimplified result is not itself
18831 a SSA name (but a decl if it were). Temporaries required by
18832 evaluating *EXPR_P may be still SSA names. */
18834 static enum gimplify_status
18835 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
18836 bool (*gimple_test_f) (tree), fallback_t fallback,
18837 bool allow_ssa)
18839 enum gimplify_status ret = gimplify_expr (expr_p, pre_p, post_p,
18840 gimple_test_f, fallback);
18841 if (! allow_ssa
18842 && TREE_CODE (*expr_p) == SSA_NAME)
18843 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, NULL, false);
18844 return ret;
18847 /* Look through TYPE for variable-sized objects and gimplify each such
18848 size that we find. Add to LIST_P any statements generated. */
18850 void
18851 gimplify_type_sizes (tree type, gimple_seq *list_p)
18853 if (type == NULL || type == error_mark_node)
18854 return;
18856 const bool ignored_p
18857 = TYPE_NAME (type)
18858 && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
18859 && DECL_IGNORED_P (TYPE_NAME (type));
18860 tree t;
18862 /* We first do the main variant, then copy into any other variants. */
18863 type = TYPE_MAIN_VARIANT (type);
18865 /* Avoid infinite recursion. */
18866 if (TYPE_SIZES_GIMPLIFIED (type))
18867 return;
18869 TYPE_SIZES_GIMPLIFIED (type) = 1;
18871 switch (TREE_CODE (type))
18873 case INTEGER_TYPE:
18874 case ENUMERAL_TYPE:
18875 case BOOLEAN_TYPE:
18876 case REAL_TYPE:
18877 case FIXED_POINT_TYPE:
18878 gimplify_one_sizepos (&TYPE_MIN_VALUE (type), list_p);
18879 gimplify_one_sizepos (&TYPE_MAX_VALUE (type), list_p);
18881 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
18883 TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type);
18884 TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type);
18886 break;
18888 case ARRAY_TYPE:
18889 /* These types may not have declarations, so handle them here. */
18890 gimplify_type_sizes (TREE_TYPE (type), list_p);
18891 gimplify_type_sizes (TYPE_DOMAIN (type), list_p);
18892 /* Ensure VLA bounds aren't removed, for -O0 they should be variables
18893 with assigned stack slots, for -O1+ -g they should be tracked
18894 by VTA. */
18895 if (!ignored_p
18896 && TYPE_DOMAIN (type)
18897 && INTEGRAL_TYPE_P (TYPE_DOMAIN (type)))
18899 t = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
18900 if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
18901 DECL_IGNORED_P (t) = 0;
18902 t = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
18903 if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
18904 DECL_IGNORED_P (t) = 0;
18906 break;
18908 case RECORD_TYPE:
18909 case UNION_TYPE:
18910 case QUAL_UNION_TYPE:
18911 for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
18912 if (TREE_CODE (field) == FIELD_DECL)
18914 gimplify_one_sizepos (&DECL_FIELD_OFFSET (field), list_p);
18915 /* Likewise, ensure variable offsets aren't removed. */
18916 if (!ignored_p
18917 && (t = DECL_FIELD_OFFSET (field))
18918 && VAR_P (t)
18919 && DECL_ARTIFICIAL (t))
18920 DECL_IGNORED_P (t) = 0;
18921 gimplify_one_sizepos (&DECL_SIZE (field), list_p);
18922 gimplify_one_sizepos (&DECL_SIZE_UNIT (field), list_p);
18923 gimplify_type_sizes (TREE_TYPE (field), list_p);
18925 break;
18927 case POINTER_TYPE:
18928 case REFERENCE_TYPE:
18929 /* We used to recurse on the pointed-to type here, which turned out to
18930 be incorrect because its definition might refer to variables not
18931 yet initialized at this point if a forward declaration is involved.
18933 It was actually useful for anonymous pointed-to types to ensure
18934 that the sizes evaluation dominates every possible later use of the
18935 values. Restricting to such types here would be safe since there
18936 is no possible forward declaration around, but would introduce an
18937 undesirable middle-end semantic to anonymity. We then defer to
18938 front-ends the responsibility of ensuring that the sizes are
18939 evaluated both early and late enough, e.g. by attaching artificial
18940 type declarations to the tree. */
18941 break;
18943 default:
18944 break;
18947 gimplify_one_sizepos (&TYPE_SIZE (type), list_p);
18948 gimplify_one_sizepos (&TYPE_SIZE_UNIT (type), list_p);
18950 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
18952 TYPE_SIZE (t) = TYPE_SIZE (type);
18953 TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (type);
18954 TYPE_SIZES_GIMPLIFIED (t) = 1;
18958 /* A subroutine of gimplify_type_sizes to make sure that *EXPR_P,
18959 a size or position, has had all of its SAVE_EXPRs evaluated.
18960 We add any required statements to *STMT_P. */
18962 void
18963 gimplify_one_sizepos (tree *expr_p, gimple_seq *stmt_p)
18965 tree expr = *expr_p;
18967 /* We don't do anything if the value isn't there, is constant, or contains
18968 A PLACEHOLDER_EXPR. We also don't want to do anything if it's already
18969 a VAR_DECL. If it's a VAR_DECL from another function, the gimplifier
18970 will want to replace it with a new variable, but that will cause problems
18971 if this type is from outside the function. It's OK to have that here. */
18972 if (expr == NULL_TREE
18973 || is_gimple_constant (expr)
18974 || VAR_P (expr)
18975 || CONTAINS_PLACEHOLDER_P (expr))
18976 return;
18978 *expr_p = unshare_expr (expr);
18980 /* SSA names in decl/type fields are a bad idea - they'll get reclaimed
18981 if the def vanishes. */
18982 gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue, false);
18984 /* If expr wasn't already is_gimple_sizepos or is_gimple_constant from the
18985 FE, ensure that it is a VAR_DECL, otherwise we might handle some decls
18986 as gimplify_vla_decl even when they would have all sizes INTEGER_CSTs. */
18987 if (is_gimple_constant (*expr_p))
18988 *expr_p = get_initialized_tmp_var (*expr_p, stmt_p, NULL, false);
18991 /* Gimplify the body of statements of FNDECL and return a GIMPLE_BIND node
18992 containing the sequence of corresponding GIMPLE statements. If DO_PARMS
18993 is true, also gimplify the parameters. */
18995 gbind *
18996 gimplify_body (tree fndecl, bool do_parms)
18998 location_t saved_location = input_location;
18999 gimple_seq parm_stmts, parm_cleanup = NULL, seq;
19000 gimple *outer_stmt;
19001 gbind *outer_bind;
19003 timevar_push (TV_TREE_GIMPLIFY);
19005 init_tree_ssa (cfun);
19007 /* Initialize for optimize_insn_for_s{ize,peed}_p possibly called during
19008 gimplification. */
19009 default_rtl_profile ();
19011 gcc_assert (gimplify_ctxp == NULL);
19012 push_gimplify_context (true);
19014 if (flag_openacc || flag_openmp)
19016 gcc_assert (gimplify_omp_ctxp == NULL);
19017 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (fndecl)))
19018 gimplify_omp_ctxp = new_omp_context (ORT_IMPLICIT_TARGET);
19021 /* Unshare most shared trees in the body and in that of any nested functions.
19022 It would seem we don't have to do this for nested functions because
19023 they are supposed to be output and then the outer function gimplified
19024 first, but the g++ front end doesn't always do it that way. */
19025 unshare_body (fndecl);
19026 unvisit_body (fndecl);
19028 /* Make sure input_location isn't set to something weird. */
19029 input_location = DECL_SOURCE_LOCATION (fndecl);
19031 /* Resolve callee-copies. This has to be done before processing
19032 the body so that DECL_VALUE_EXPR gets processed correctly. */
19033 parm_stmts = do_parms ? gimplify_parameters (&parm_cleanup) : NULL;
19035 /* Gimplify the function's body. */
19036 seq = NULL;
19037 gimplify_stmt (&DECL_SAVED_TREE (fndecl), &seq);
19038 outer_stmt = gimple_seq_first_nondebug_stmt (seq);
19039 if (!outer_stmt)
19041 outer_stmt = gimple_build_nop ();
19042 gimplify_seq_add_stmt (&seq, outer_stmt);
19045 /* The body must contain exactly one statement, a GIMPLE_BIND. If this is
19046 not the case, wrap everything in a GIMPLE_BIND to make it so. */
19047 if (gimple_code (outer_stmt) == GIMPLE_BIND
19048 && (gimple_seq_first_nondebug_stmt (seq)
19049 == gimple_seq_last_nondebug_stmt (seq)))
19051 outer_bind = as_a <gbind *> (outer_stmt);
19052 if (gimple_seq_first_stmt (seq) != outer_stmt
19053 || gimple_seq_last_stmt (seq) != outer_stmt)
19055 /* If there are debug stmts before or after outer_stmt, move them
19056 inside of outer_bind body. */
19057 gimple_stmt_iterator gsi = gsi_for_stmt (outer_stmt, &seq);
19058 gimple_seq second_seq = NULL;
19059 if (gimple_seq_first_stmt (seq) != outer_stmt
19060 && gimple_seq_last_stmt (seq) != outer_stmt)
19062 second_seq = gsi_split_seq_after (gsi);
19063 gsi_remove (&gsi, false);
19065 else if (gimple_seq_first_stmt (seq) != outer_stmt)
19066 gsi_remove (&gsi, false);
19067 else
19069 gsi_remove (&gsi, false);
19070 second_seq = seq;
19071 seq = NULL;
19073 gimple_seq_add_seq_without_update (&seq,
19074 gimple_bind_body (outer_bind));
19075 gimple_seq_add_seq_without_update (&seq, second_seq);
19076 gimple_bind_set_body (outer_bind, seq);
19079 else
19080 outer_bind = gimple_build_bind (NULL_TREE, seq, NULL);
19082 DECL_SAVED_TREE (fndecl) = NULL_TREE;
19084 /* If we had callee-copies statements, insert them at the beginning
19085 of the function and clear DECL_VALUE_EXPR_P on the parameters. */
19086 if (!gimple_seq_empty_p (parm_stmts))
19088 tree parm;
19090 gimplify_seq_add_seq (&parm_stmts, gimple_bind_body (outer_bind));
19091 if (parm_cleanup)
19093 gtry *g = gimple_build_try (parm_stmts, parm_cleanup,
19094 GIMPLE_TRY_FINALLY);
19095 parm_stmts = NULL;
19096 gimple_seq_add_stmt (&parm_stmts, g);
19098 gimple_bind_set_body (outer_bind, parm_stmts);
19100 for (parm = DECL_ARGUMENTS (current_function_decl);
19101 parm; parm = DECL_CHAIN (parm))
19102 if (DECL_HAS_VALUE_EXPR_P (parm))
19104 DECL_HAS_VALUE_EXPR_P (parm) = 0;
19105 DECL_IGNORED_P (parm) = 0;
19109 if ((flag_openacc || flag_openmp || flag_openmp_simd)
19110 && gimplify_omp_ctxp)
19112 delete_omp_context (gimplify_omp_ctxp);
19113 gimplify_omp_ctxp = NULL;
19116 pop_gimplify_context (outer_bind);
19117 gcc_assert (gimplify_ctxp == NULL);
19119 if (flag_checking && !seen_error ())
19120 verify_gimple_in_seq (gimple_bind_body (outer_bind));
19122 timevar_pop (TV_TREE_GIMPLIFY);
19123 input_location = saved_location;
19125 return outer_bind;
19128 typedef char *char_p; /* For DEF_VEC_P. */
19130 /* Return whether we should exclude FNDECL from instrumentation. */
19132 static bool
19133 flag_instrument_functions_exclude_p (tree fndecl)
19135 vec<char_p> *v;
19137 v = (vec<char_p> *) flag_instrument_functions_exclude_functions;
19138 if (v && v->length () > 0)
19140 const char *name;
19141 int i;
19142 char *s;
19144 name = lang_hooks.decl_printable_name (fndecl, 1);
19145 FOR_EACH_VEC_ELT (*v, i, s)
19146 if (strstr (name, s) != NULL)
19147 return true;
19150 v = (vec<char_p> *) flag_instrument_functions_exclude_files;
19151 if (v && v->length () > 0)
19153 const char *name;
19154 int i;
19155 char *s;
19157 name = DECL_SOURCE_FILE (fndecl);
19158 FOR_EACH_VEC_ELT (*v, i, s)
19159 if (strstr (name, s) != NULL)
19160 return true;
19163 return false;
19166 /* Build a call to the instrumentation function FNCODE and add it to SEQ.
19167 If COND_VAR is not NULL, it is a boolean variable guarding the call to
19168 the instrumentation function. IF STMT is not NULL, it is a statement
19169 to be executed just before the call to the instrumentation function. */
19171 static void
19172 build_instrumentation_call (gimple_seq *seq, enum built_in_function fncode,
19173 tree cond_var, gimple *stmt)
19175 /* The instrumentation hooks aren't going to call the instrumented
19176 function and the address they receive is expected to be matchable
19177 against symbol addresses. Make sure we don't create a trampoline,
19178 in case the current function is nested. */
19179 tree this_fn_addr = build_fold_addr_expr (current_function_decl);
19180 TREE_NO_TRAMPOLINE (this_fn_addr) = 1;
19182 tree label_true, label_false;
19183 if (cond_var)
19185 label_true = create_artificial_label (UNKNOWN_LOCATION);
19186 label_false = create_artificial_label (UNKNOWN_LOCATION);
19187 gcond *cond = gimple_build_cond (EQ_EXPR, cond_var, boolean_false_node,
19188 label_true, label_false);
19189 gimplify_seq_add_stmt (seq, cond);
19190 gimplify_seq_add_stmt (seq, gimple_build_label (label_true));
19191 gimplify_seq_add_stmt (seq, gimple_build_predict (PRED_COLD_LABEL,
19192 NOT_TAKEN));
19195 if (stmt)
19196 gimplify_seq_add_stmt (seq, stmt);
19198 tree x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
19199 gcall *call = gimple_build_call (x, 1, integer_zero_node);
19200 tree tmp_var = create_tmp_var (ptr_type_node, "return_addr");
19201 gimple_call_set_lhs (call, tmp_var);
19202 gimplify_seq_add_stmt (seq, call);
19203 x = builtin_decl_implicit (fncode);
19204 call = gimple_build_call (x, 2, this_fn_addr, tmp_var);
19205 gimplify_seq_add_stmt (seq, call);
19207 if (cond_var)
19208 gimplify_seq_add_stmt (seq, gimple_build_label (label_false));
19211 /* Entry point to the gimplification pass. FNDECL is the FUNCTION_DECL
19212 node for the function we want to gimplify.
19214 Return the sequence of GIMPLE statements corresponding to the body
19215 of FNDECL. */
19217 void
19218 gimplify_function_tree (tree fndecl)
19220 gimple_seq seq;
19221 gbind *bind;
19223 gcc_assert (!gimple_body (fndecl));
19225 if (DECL_STRUCT_FUNCTION (fndecl))
19226 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
19227 else
19228 push_struct_function (fndecl);
19230 /* Tentatively set PROP_gimple_lva here, and reset it in gimplify_va_arg_expr
19231 if necessary. */
19232 cfun->curr_properties |= PROP_gimple_lva;
19234 if (asan_sanitize_use_after_scope ())
19235 asan_poisoned_variables = new hash_set<tree> ();
19236 bind = gimplify_body (fndecl, true);
19237 if (asan_poisoned_variables)
19239 delete asan_poisoned_variables;
19240 asan_poisoned_variables = NULL;
19243 /* The tree body of the function is no longer needed, replace it
19244 with the new GIMPLE body. */
19245 seq = NULL;
19246 gimple_seq_add_stmt (&seq, bind);
19247 gimple_set_body (fndecl, seq);
19249 /* If we're instrumenting function entry/exit, then prepend the call to
19250 the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to
19251 catch the exit hook. */
19252 /* ??? Add some way to ignore exceptions for this TFE. */
19253 if (flag_instrument_function_entry_exit
19254 && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl)
19255 /* Do not instrument extern inline functions. */
19256 && !(DECL_DECLARED_INLINE_P (fndecl)
19257 && DECL_EXTERNAL (fndecl)
19258 && DECL_DISREGARD_INLINE_LIMITS (fndecl))
19259 && !flag_instrument_functions_exclude_p (fndecl))
19261 gimple_seq body = NULL, cleanup = NULL;
19262 gassign *assign;
19263 tree cond_var;
19265 /* If -finstrument-functions-once is specified, generate:
19267 static volatile bool C.0 = false;
19268 bool tmp_called;
19270 tmp_called = C.0;
19271 if (!tmp_called)
19273 C.0 = true;
19274 [call profiling enter function]
19277 without specific protection for data races. */
19278 if (flag_instrument_function_entry_exit > 1)
19280 tree first_var
19281 = build_decl (DECL_SOURCE_LOCATION (current_function_decl),
19282 VAR_DECL,
19283 create_tmp_var_name ("C"),
19284 boolean_type_node);
19285 DECL_ARTIFICIAL (first_var) = 1;
19286 DECL_IGNORED_P (first_var) = 1;
19287 TREE_STATIC (first_var) = 1;
19288 TREE_THIS_VOLATILE (first_var) = 1;
19289 TREE_USED (first_var) = 1;
19290 DECL_INITIAL (first_var) = boolean_false_node;
19291 varpool_node::add (first_var);
19293 cond_var = create_tmp_var (boolean_type_node, "tmp_called");
19294 assign = gimple_build_assign (cond_var, first_var);
19295 gimplify_seq_add_stmt (&body, assign);
19297 assign = gimple_build_assign (first_var, boolean_true_node);
19300 else
19302 cond_var = NULL_TREE;
19303 assign = NULL;
19306 build_instrumentation_call (&body, BUILT_IN_PROFILE_FUNC_ENTER,
19307 cond_var, assign);
19309 /* If -finstrument-functions-once is specified, generate:
19311 if (!tmp_called)
19312 [call profiling exit function]
19314 without specific protection for data races. */
19315 build_instrumentation_call (&cleanup, BUILT_IN_PROFILE_FUNC_EXIT,
19316 cond_var, NULL);
19318 gimple *tf = gimple_build_try (seq, cleanup, GIMPLE_TRY_FINALLY);
19319 gimplify_seq_add_stmt (&body, tf);
19320 gbind *new_bind = gimple_build_bind (NULL, body, NULL);
19322 /* Replace the current function body with the body
19323 wrapped in the try/finally TF. */
19324 seq = NULL;
19325 gimple_seq_add_stmt (&seq, new_bind);
19326 gimple_set_body (fndecl, seq);
19327 bind = new_bind;
19330 if (sanitize_flags_p (SANITIZE_THREAD)
19331 && param_tsan_instrument_func_entry_exit)
19333 gcall *call = gimple_build_call_internal (IFN_TSAN_FUNC_EXIT, 0);
19334 gimple *tf = gimple_build_try (seq, call, GIMPLE_TRY_FINALLY);
19335 gbind *new_bind = gimple_build_bind (NULL, tf, NULL);
19336 /* Replace the current function body with the body
19337 wrapped in the try/finally TF. */
19338 seq = NULL;
19339 gimple_seq_add_stmt (&seq, new_bind);
19340 gimple_set_body (fndecl, seq);
19343 DECL_SAVED_TREE (fndecl) = NULL_TREE;
19344 cfun->curr_properties |= PROP_gimple_any;
19346 pop_cfun ();
19348 dump_function (TDI_gimple, fndecl);
19351 /* Return a dummy expression of type TYPE in order to keep going after an
19352 error. */
19354 static tree
19355 dummy_object (tree type)
19357 tree t = build_int_cst (build_pointer_type (type), 0);
19358 return build2 (MEM_REF, type, t, t);
19361 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
19362 builtin function, but a very special sort of operator. */
19364 enum gimplify_status
19365 gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p,
19366 gimple_seq *post_p ATTRIBUTE_UNUSED)
19368 tree promoted_type, have_va_type;
19369 tree valist = TREE_OPERAND (*expr_p, 0);
19370 tree type = TREE_TYPE (*expr_p);
19371 tree t, tag, aptag;
19372 location_t loc = EXPR_LOCATION (*expr_p);
19374 /* Verify that valist is of the proper type. */
19375 have_va_type = TREE_TYPE (valist);
19376 if (have_va_type == error_mark_node)
19377 return GS_ERROR;
19378 have_va_type = targetm.canonical_va_list_type (have_va_type);
19379 if (have_va_type == NULL_TREE
19380 && POINTER_TYPE_P (TREE_TYPE (valist)))
19381 /* Handle 'Case 1: Not an array type' from c-common.cc/build_va_arg. */
19382 have_va_type
19383 = targetm.canonical_va_list_type (TREE_TYPE (TREE_TYPE (valist)));
19384 gcc_assert (have_va_type != NULL_TREE);
19386 /* Generate a diagnostic for requesting data of a type that cannot
19387 be passed through `...' due to type promotion at the call site. */
19388 if ((promoted_type = lang_hooks.types.type_promotes_to (type))
19389 != type)
19391 static bool gave_help;
19392 bool warned;
19393 /* Use the expansion point to handle cases such as passing bool (defined
19394 in a system header) through `...'. */
19395 location_t xloc
19396 = expansion_point_location_if_in_system_header (loc);
19398 /* Unfortunately, this is merely undefined, rather than a constraint
19399 violation, so we cannot make this an error. If this call is never
19400 executed, the program is still strictly conforming. */
19401 auto_diagnostic_group d;
19402 warned = warning_at (xloc, 0,
19403 "%qT is promoted to %qT when passed through %<...%>",
19404 type, promoted_type);
19405 if (!gave_help && warned)
19407 gave_help = true;
19408 inform (xloc, "(so you should pass %qT not %qT to %<va_arg%>)",
19409 promoted_type, type);
19412 /* We can, however, treat "undefined" any way we please.
19413 Call abort to encourage the user to fix the program. */
19414 if (warned)
19415 inform (xloc, "if this code is reached, the program will abort");
19416 /* Before the abort, allow the evaluation of the va_list
19417 expression to exit or longjmp. */
19418 gimplify_and_add (valist, pre_p);
19419 t = build_call_expr_loc (loc,
19420 builtin_decl_implicit (BUILT_IN_TRAP), 0);
19421 gimplify_and_add (t, pre_p);
19423 /* This is dead code, but go ahead and finish so that the
19424 mode of the result comes out right. */
19425 *expr_p = dummy_object (type);
19426 return GS_ALL_DONE;
19429 tag = build_int_cst (build_pointer_type (type), 0);
19430 aptag = build_int_cst (TREE_TYPE (valist), 0);
19432 *expr_p = build_call_expr_internal_loc (loc, IFN_VA_ARG, type, 3,
19433 valist, tag, aptag);
19435 /* Clear the tentatively set PROP_gimple_lva, to indicate that IFN_VA_ARG
19436 needs to be expanded. */
19437 cfun->curr_properties &= ~PROP_gimple_lva;
19439 return GS_OK;
19442 /* Build a new GIMPLE_ASSIGN tuple and append it to the end of *SEQ_P.
19444 DST/SRC are the destination and source respectively. You can pass
19445 ungimplified trees in DST or SRC, in which case they will be
19446 converted to a gimple operand if necessary.
19448 This function returns the newly created GIMPLE_ASSIGN tuple. */
19450 gimple *
19451 gimplify_assign (tree dst, tree src, gimple_seq *seq_p)
19453 tree t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
19454 gimplify_and_add (t, seq_p);
19455 ggc_free (t);
19456 return gimple_seq_last_stmt (*seq_p);
19459 inline hashval_t
19460 gimplify_hasher::hash (const elt_t *p)
19462 tree t = p->val;
19463 return iterative_hash_expr (t, 0);
19466 inline bool
19467 gimplify_hasher::equal (const elt_t *p1, const elt_t *p2)
19469 tree t1 = p1->val;
19470 tree t2 = p2->val;
19471 enum tree_code code = TREE_CODE (t1);
19473 if (TREE_CODE (t2) != code
19474 || TREE_TYPE (t1) != TREE_TYPE (t2))
19475 return false;
19477 if (!operand_equal_p (t1, t2, 0))
19478 return false;
19480 /* Only allow them to compare equal if they also hash equal; otherwise
19481 results are nondeterminate, and we fail bootstrap comparison. */
19482 gcc_checking_assert (hash (p1) == hash (p2));
19484 return true;