ada: Fix infinite loop with multiple limited with clauses
[official-gcc.git] / gcc / gimplify.cc
blob9f4722f7458cb1866ab3df067982c9d20a28a8b1
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 tree tmp = build_pointer_type (TREE_TYPE (t));
1409 tree v = create_tmp_var (tmp, get_name (t));
1410 DECL_IGNORED_P (v) = 0;
1411 tmp = remove_attribute ("omp allocate", DECL_ATTRIBUTES (t));
1412 DECL_ATTRIBUTES (v)
1413 = tree_cons (get_identifier ("omp allocate var"),
1414 build_tree_list (NULL_TREE, t), tmp);
1415 tmp = build_fold_indirect_ref (v);
1416 TREE_THIS_NOTRAP (tmp) = 1;
1417 SET_DECL_VALUE_EXPR (t, tmp);
1418 DECL_HAS_VALUE_EXPR_P (t) = 1;
1419 tree sz = TYPE_SIZE_UNIT (TREE_TYPE (t));
1420 if (alloc == NULL_TREE)
1421 alloc = build_zero_cst (ptr_type_node);
1422 if (align == NULL_TREE)
1423 align = build_int_cst (size_type_node, DECL_ALIGN_UNIT (t));
1424 else
1425 align = build_int_cst (size_type_node,
1426 MAX (tree_to_uhwi (align),
1427 DECL_ALIGN_UNIT (t)));
1428 tmp = builtin_decl_explicit (BUILT_IN_GOMP_ALLOC);
1429 tmp = build_call_expr_loc (DECL_SOURCE_LOCATION (t), tmp,
1430 3, align, sz, alloc);
1431 tmp = fold_build2_loc (DECL_SOURCE_LOCATION (t), MODIFY_EXPR,
1432 TREE_TYPE (v), v,
1433 fold_convert (TREE_TYPE (v), tmp));
1434 gcc_assert (BIND_EXPR_BODY (bind_expr) != NULL_TREE
1435 && (TREE_CODE (BIND_EXPR_BODY (bind_expr))
1436 == STATEMENT_LIST));
1437 tree_stmt_iterator e = tsi_start (BIND_EXPR_BODY (bind_expr));
1438 while (!tsi_end_p (e))
1440 if ((TREE_CODE (*e) == DECL_EXPR
1441 && TREE_OPERAND (*e, 0) == t)
1442 || (TREE_CODE (*e) == CLEANUP_POINT_EXPR
1443 && TREE_CODE (TREE_OPERAND (*e, 0)) == DECL_EXPR
1444 && TREE_OPERAND (TREE_OPERAND (*e, 0), 0) == t))
1445 break;
1446 ++e;
1448 gcc_assert (!tsi_end_p (e));
1449 tsi_link_before (&e, tmp, TSI_SAME_STMT);
1453 /* Mark variable as local. */
1454 if (ctx && ctx->region_type != ORT_NONE && !DECL_EXTERNAL (t))
1456 if (! DECL_SEEN_IN_BIND_EXPR_P (t)
1457 || splay_tree_lookup (ctx->variables,
1458 (splay_tree_key) t) == NULL)
1460 int flag = GOVD_LOCAL;
1461 if (ctx->region_type == ORT_SIMD
1462 && TREE_ADDRESSABLE (t)
1463 && !TREE_STATIC (t))
1465 if (TREE_CODE (DECL_SIZE_UNIT (t)) != INTEGER_CST)
1466 ctx->add_safelen1 = true;
1467 else
1468 flag = GOVD_PRIVATE;
1470 omp_add_variable (ctx, t, flag | GOVD_SEEN);
1472 /* Static locals inside of target construct or offloaded
1473 routines need to be "omp declare target". */
1474 if (TREE_STATIC (t))
1475 for (; ctx; ctx = ctx->outer_context)
1476 if ((ctx->region_type & ORT_TARGET) != 0)
1478 if (!lookup_attribute ("omp declare target",
1479 DECL_ATTRIBUTES (t)))
1481 tree id = get_identifier ("omp declare target");
1482 DECL_ATTRIBUTES (t)
1483 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
1484 varpool_node *node = varpool_node::get (t);
1485 if (node)
1487 node->offloadable = 1;
1488 if (ENABLE_OFFLOADING && !DECL_EXTERNAL (t))
1490 g->have_offload = true;
1491 if (!in_lto_p)
1492 vec_safe_push (offload_vars, t);
1496 break;
1500 DECL_SEEN_IN_BIND_EXPR_P (t) = 1;
1502 if (DECL_HARD_REGISTER (t) && !is_global_var (t) && cfun)
1503 cfun->has_local_explicit_reg_vars = true;
1507 bind_stmt = gimple_build_bind (BIND_EXPR_VARS (bind_expr), NULL,
1508 BIND_EXPR_BLOCK (bind_expr));
1509 gimple_push_bind_expr (bind_stmt);
1511 gimplify_ctxp->keep_stack = false;
1512 gimplify_ctxp->save_stack = false;
1514 /* Gimplify the body into the GIMPLE_BIND tuple's body. */
1515 body = NULL;
1516 gimplify_stmt (&BIND_EXPR_BODY (bind_expr), &body);
1517 gimple_bind_set_body (bind_stmt, body);
1519 /* Source location wise, the cleanup code (stack_restore and clobbers)
1520 belongs to the end of the block, so propagate what we have. The
1521 stack_save operation belongs to the beginning of block, which we can
1522 infer from the bind_expr directly if the block has no explicit
1523 assignment. */
1524 if (BIND_EXPR_BLOCK (bind_expr))
1526 end_locus = BLOCK_SOURCE_END_LOCATION (BIND_EXPR_BLOCK (bind_expr));
1527 start_locus = BLOCK_SOURCE_LOCATION (BIND_EXPR_BLOCK (bind_expr));
1529 if (start_locus == 0)
1530 start_locus = EXPR_LOCATION (bind_expr);
1532 cleanup = NULL;
1533 stack_save = NULL;
1535 /* Add clobbers for all variables that go out of scope. */
1536 for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t))
1538 if (VAR_P (t)
1539 && !is_global_var (t)
1540 && DECL_CONTEXT (t) == current_function_decl)
1542 if (flag_openmp
1543 && DECL_HAS_VALUE_EXPR_P (t)
1544 && TREE_USED (t)
1545 && lookup_attribute ("omp allocate", DECL_ATTRIBUTES (t)))
1547 tree tmp = builtin_decl_explicit (BUILT_IN_GOMP_FREE);
1548 tmp = build_call_expr_loc (end_locus, tmp, 2,
1549 TREE_OPERAND (DECL_VALUE_EXPR (t), 0),
1550 build_zero_cst (ptr_type_node));
1551 gimplify_and_add (tmp, &cleanup);
1553 if (!DECL_HARD_REGISTER (t)
1554 && !TREE_THIS_VOLATILE (t)
1555 && !DECL_HAS_VALUE_EXPR_P (t)
1556 /* Only care for variables that have to be in memory. Others
1557 will be rewritten into SSA names, hence moved to the
1558 top-level. */
1559 && !is_gimple_reg (t)
1560 && flag_stack_reuse != SR_NONE)
1562 tree clobber = build_clobber (TREE_TYPE (t), CLOBBER_EOL);
1563 gimple *clobber_stmt;
1564 clobber_stmt = gimple_build_assign (t, clobber);
1565 gimple_set_location (clobber_stmt, end_locus);
1566 gimplify_seq_add_stmt (&cleanup, clobber_stmt);
1569 if (flag_openacc && oacc_declare_returns != NULL)
1571 tree key = t;
1572 if (DECL_HAS_VALUE_EXPR_P (key))
1574 key = DECL_VALUE_EXPR (key);
1575 if (INDIRECT_REF_P (key))
1576 key = TREE_OPERAND (key, 0);
1578 tree *c = oacc_declare_returns->get (key);
1579 if (c != NULL)
1581 if (ret_clauses)
1582 OMP_CLAUSE_CHAIN (*c) = ret_clauses;
1584 ret_clauses = unshare_expr (*c);
1586 oacc_declare_returns->remove (key);
1588 if (oacc_declare_returns->is_empty ())
1590 delete oacc_declare_returns;
1591 oacc_declare_returns = NULL;
1597 if (asan_poisoned_variables != NULL
1598 && asan_poisoned_variables->contains (t))
1600 asan_poisoned_variables->remove (t);
1601 asan_poison_variable (t, true, &cleanup);
1604 if (gimplify_ctxp->live_switch_vars != NULL
1605 && gimplify_ctxp->live_switch_vars->contains (t))
1606 gimplify_ctxp->live_switch_vars->remove (t);
1609 /* If the code both contains VLAs and calls alloca, then we cannot reclaim
1610 the stack space allocated to the VLAs. */
1611 if (gimplify_ctxp->save_stack && !gimplify_ctxp->keep_stack)
1613 gcall *stack_restore;
1615 /* Save stack on entry and restore it on exit. Add a try_finally
1616 block to achieve this. */
1617 build_stack_save_restore (&stack_save, &stack_restore);
1619 gimple_set_location (stack_save, start_locus);
1620 gimple_set_location (stack_restore, end_locus);
1622 gimplify_seq_add_stmt (&cleanup, stack_restore);
1625 if (ret_clauses)
1627 gomp_target *stmt;
1628 gimple_stmt_iterator si = gsi_start (cleanup);
1630 stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
1631 ret_clauses);
1632 gsi_insert_seq_before_without_update (&si, stmt, GSI_NEW_STMT);
1635 if (cleanup)
1637 gtry *gs;
1638 gimple_seq new_body;
1640 new_body = NULL;
1641 gs = gimple_build_try (gimple_bind_body (bind_stmt), cleanup,
1642 GIMPLE_TRY_FINALLY);
1644 if (stack_save)
1645 gimplify_seq_add_stmt (&new_body, stack_save);
1646 gimplify_seq_add_stmt (&new_body, gs);
1647 gimple_bind_set_body (bind_stmt, new_body);
1650 /* keep_stack propagates all the way up to the outermost BIND_EXPR. */
1651 if (!gimplify_ctxp->keep_stack)
1652 gimplify_ctxp->keep_stack = old_keep_stack;
1653 gimplify_ctxp->save_stack = old_save_stack;
1655 gimple_pop_bind_expr ();
1657 gimplify_seq_add_stmt (pre_p, bind_stmt);
1659 if (temp)
1661 *expr_p = temp;
1662 return GS_OK;
1665 *expr_p = NULL_TREE;
1666 return GS_ALL_DONE;
1669 /* Maybe add early return predict statement to PRE_P sequence. */
1671 static void
1672 maybe_add_early_return_predict_stmt (gimple_seq *pre_p)
1674 /* If we are not in a conditional context, add PREDICT statement. */
1675 if (gimple_conditional_context ())
1677 gimple *predict = gimple_build_predict (PRED_TREE_EARLY_RETURN,
1678 NOT_TAKEN);
1679 gimplify_seq_add_stmt (pre_p, predict);
1683 /* Gimplify a RETURN_EXPR. If the expression to be returned is not a
1684 GIMPLE value, it is assigned to a new temporary and the statement is
1685 re-written to return the temporary.
1687 PRE_P points to the sequence where side effects that must happen before
1688 STMT should be stored. */
1690 static enum gimplify_status
1691 gimplify_return_expr (tree stmt, gimple_seq *pre_p)
1693 greturn *ret;
1694 tree ret_expr = TREE_OPERAND (stmt, 0);
1695 tree result_decl, result;
1697 if (ret_expr == error_mark_node)
1698 return GS_ERROR;
1700 if (!ret_expr
1701 || TREE_CODE (ret_expr) == RESULT_DECL)
1703 maybe_add_early_return_predict_stmt (pre_p);
1704 greturn *ret = gimple_build_return (ret_expr);
1705 copy_warning (ret, stmt);
1706 gimplify_seq_add_stmt (pre_p, ret);
1707 return GS_ALL_DONE;
1710 if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))))
1711 result_decl = NULL_TREE;
1712 else if (TREE_CODE (ret_expr) == COMPOUND_EXPR)
1714 /* Used in C++ for handling EH cleanup of the return value if a local
1715 cleanup throws. Assume the front-end knows what it's doing. */
1716 result_decl = DECL_RESULT (current_function_decl);
1717 /* But crash if we end up trying to modify ret_expr below. */
1718 ret_expr = NULL_TREE;
1720 else
1722 result_decl = TREE_OPERAND (ret_expr, 0);
1724 /* See through a return by reference. */
1725 if (INDIRECT_REF_P (result_decl))
1726 result_decl = TREE_OPERAND (result_decl, 0);
1728 gcc_assert ((TREE_CODE (ret_expr) == MODIFY_EXPR
1729 || TREE_CODE (ret_expr) == INIT_EXPR)
1730 && TREE_CODE (result_decl) == RESULT_DECL);
1733 /* If aggregate_value_p is true, then we can return the bare RESULT_DECL.
1734 Recall that aggregate_value_p is FALSE for any aggregate type that is
1735 returned in registers. If we're returning values in registers, then
1736 we don't want to extend the lifetime of the RESULT_DECL, particularly
1737 across another call. In addition, for those aggregates for which
1738 hard_function_value generates a PARALLEL, we'll die during normal
1739 expansion of structure assignments; there's special code in expand_return
1740 to handle this case that does not exist in expand_expr. */
1741 if (!result_decl)
1742 result = NULL_TREE;
1743 else if (aggregate_value_p (result_decl, TREE_TYPE (current_function_decl)))
1745 if (!poly_int_tree_p (DECL_SIZE (result_decl)))
1747 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (result_decl)))
1748 gimplify_type_sizes (TREE_TYPE (result_decl), pre_p);
1749 /* Note that we don't use gimplify_vla_decl because the RESULT_DECL
1750 should be effectively allocated by the caller, i.e. all calls to
1751 this function must be subject to the Return Slot Optimization. */
1752 gimplify_one_sizepos (&DECL_SIZE (result_decl), pre_p);
1753 gimplify_one_sizepos (&DECL_SIZE_UNIT (result_decl), pre_p);
1755 result = result_decl;
1757 else if (gimplify_ctxp->return_temp)
1758 result = gimplify_ctxp->return_temp;
1759 else
1761 result = create_tmp_reg (TREE_TYPE (result_decl));
1763 /* ??? With complex control flow (usually involving abnormal edges),
1764 we can wind up warning about an uninitialized value for this. Due
1765 to how this variable is constructed and initialized, this is never
1766 true. Give up and never warn. */
1767 suppress_warning (result, OPT_Wuninitialized);
1769 gimplify_ctxp->return_temp = result;
1772 /* Smash the lhs of the MODIFY_EXPR to the temporary we plan to use.
1773 Then gimplify the whole thing. */
1774 if (result != result_decl)
1775 TREE_OPERAND (ret_expr, 0) = result;
1777 gimplify_and_add (TREE_OPERAND (stmt, 0), pre_p);
1779 maybe_add_early_return_predict_stmt (pre_p);
1780 ret = gimple_build_return (result);
1781 copy_warning (ret, stmt);
1782 gimplify_seq_add_stmt (pre_p, ret);
1784 return GS_ALL_DONE;
1787 /* Gimplify a variable-length array DECL. */
1789 static void
1790 gimplify_vla_decl (tree decl, gimple_seq *seq_p)
1792 /* This is a variable-sized decl. Simplify its size and mark it
1793 for deferred expansion. */
1794 tree t, addr, ptr_type;
1796 gimplify_one_sizepos (&DECL_SIZE (decl), seq_p);
1797 gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), seq_p);
1799 /* Don't mess with a DECL_VALUE_EXPR set by the front-end. */
1800 if (DECL_HAS_VALUE_EXPR_P (decl))
1801 return;
1803 /* All occurrences of this decl in final gimplified code will be
1804 replaced by indirection. Setting DECL_VALUE_EXPR does two
1805 things: First, it lets the rest of the gimplifier know what
1806 replacement to use. Second, it lets the debug info know
1807 where to find the value. */
1808 ptr_type = build_pointer_type (TREE_TYPE (decl));
1809 addr = create_tmp_var (ptr_type, get_name (decl));
1810 DECL_IGNORED_P (addr) = 0;
1811 t = build_fold_indirect_ref (addr);
1812 TREE_THIS_NOTRAP (t) = 1;
1813 SET_DECL_VALUE_EXPR (decl, t);
1814 DECL_HAS_VALUE_EXPR_P (decl) = 1;
1816 t = build_alloca_call_expr (DECL_SIZE_UNIT (decl), DECL_ALIGN (decl),
1817 max_int_size_in_bytes (TREE_TYPE (decl)));
1818 /* The call has been built for a variable-sized object. */
1819 CALL_ALLOCA_FOR_VAR_P (t) = 1;
1820 t = fold_convert (ptr_type, t);
1821 t = build2 (MODIFY_EXPR, TREE_TYPE (addr), addr, t);
1823 gimplify_and_add (t, seq_p);
1825 /* Record the dynamic allocation associated with DECL if requested. */
1826 if (flag_callgraph_info & CALLGRAPH_INFO_DYNAMIC_ALLOC)
1827 record_dynamic_alloc (decl);
1830 /* A helper function to be called via walk_tree. Mark all labels under *TP
1831 as being forced. To be called for DECL_INITIAL of static variables. */
1833 static tree
1834 force_labels_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
1836 if (TYPE_P (*tp))
1837 *walk_subtrees = 0;
1838 if (TREE_CODE (*tp) == LABEL_DECL)
1840 FORCED_LABEL (*tp) = 1;
1841 cfun->has_forced_label_in_static = 1;
1844 return NULL_TREE;
1847 /* Generate an initialization to automatic variable DECL based on INIT_TYPE.
1848 Build a call to internal const function DEFERRED_INIT:
1849 1st argument: SIZE of the DECL;
1850 2nd argument: INIT_TYPE;
1851 3rd argument: NAME of the DECL;
1853 as LHS = DEFERRED_INIT (SIZE of the DECL, INIT_TYPE, NAME of the DECL). */
1855 static void
1856 gimple_add_init_for_auto_var (tree decl,
1857 enum auto_init_type init_type,
1858 gimple_seq *seq_p)
1860 gcc_assert (auto_var_p (decl));
1861 gcc_assert (init_type > AUTO_INIT_UNINITIALIZED);
1862 location_t loc = EXPR_LOCATION (decl);
1863 tree decl_size = TYPE_SIZE_UNIT (TREE_TYPE (decl));
1865 tree init_type_node
1866 = build_int_cst (integer_type_node, (int) init_type);
1868 tree decl_name = NULL_TREE;
1869 if (DECL_NAME (decl))
1871 decl_name = build_string_literal (DECL_NAME (decl));
1873 else
1875 char decl_name_anonymous[3 + (HOST_BITS_PER_INT + 2) / 3];
1876 sprintf (decl_name_anonymous, "D.%u", DECL_UID (decl));
1877 decl_name = build_string_literal (decl_name_anonymous);
1880 tree call = build_call_expr_internal_loc (loc, IFN_DEFERRED_INIT,
1881 TREE_TYPE (decl), 3,
1882 decl_size, init_type_node,
1883 decl_name);
1885 gimplify_assign (decl, call, seq_p);
1888 /* Generate padding initialization for automatic vairable DECL.
1889 C guarantees that brace-init with fewer initializers than members
1890 aggregate will initialize the rest of the aggregate as-if it were
1891 static initialization. In turn static initialization guarantees
1892 that padding is initialized to zero. So, we always initialize paddings
1893 to zeroes regardless INIT_TYPE.
1894 To do the padding initialization, we insert a call to
1895 __builtin_clear_padding (&decl, 0, for_auto_init = true).
1896 Note, we add an additional dummy argument for __builtin_clear_padding,
1897 'for_auto_init' to distinguish whether this call is for automatic
1898 variable initialization or not.
1900 static void
1901 gimple_add_padding_init_for_auto_var (tree decl, bool is_vla,
1902 gimple_seq *seq_p)
1904 tree addr_of_decl = NULL_TREE;
1905 tree fn = builtin_decl_explicit (BUILT_IN_CLEAR_PADDING);
1907 if (is_vla)
1909 /* The temporary address variable for this vla should be
1910 created in gimplify_vla_decl. */
1911 gcc_assert (DECL_HAS_VALUE_EXPR_P (decl));
1912 gcc_assert (INDIRECT_REF_P (DECL_VALUE_EXPR (decl)));
1913 addr_of_decl = TREE_OPERAND (DECL_VALUE_EXPR (decl), 0);
1915 else
1917 mark_addressable (decl);
1918 addr_of_decl = build_fold_addr_expr (decl);
1921 gimple *call = gimple_build_call (fn, 2, addr_of_decl,
1922 build_one_cst (TREE_TYPE (addr_of_decl)));
1923 gimplify_seq_add_stmt (seq_p, call);
1926 /* Return true if the DECL need to be automaticly initialized by the
1927 compiler. */
1928 static bool
1929 is_var_need_auto_init (tree decl)
1931 if (auto_var_p (decl)
1932 && (TREE_CODE (decl) != VAR_DECL
1933 || !DECL_HARD_REGISTER (decl))
1934 && (flag_auto_var_init > AUTO_INIT_UNINITIALIZED)
1935 && (!lookup_attribute ("uninitialized", DECL_ATTRIBUTES (decl)))
1936 && !OPAQUE_TYPE_P (TREE_TYPE (decl))
1937 && !is_empty_type (TREE_TYPE (decl)))
1938 return true;
1939 return false;
1942 /* Gimplify a DECL_EXPR node *STMT_P by making any necessary allocation
1943 and initialization explicit. */
1945 static enum gimplify_status
1946 gimplify_decl_expr (tree *stmt_p, gimple_seq *seq_p)
1948 tree stmt = *stmt_p;
1949 tree decl = DECL_EXPR_DECL (stmt);
1951 *stmt_p = NULL_TREE;
1953 if (TREE_TYPE (decl) == error_mark_node)
1954 return GS_ERROR;
1956 if ((TREE_CODE (decl) == TYPE_DECL
1957 || VAR_P (decl))
1958 && !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl)))
1960 gimplify_type_sizes (TREE_TYPE (decl), seq_p);
1961 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
1962 gimplify_type_sizes (TREE_TYPE (TREE_TYPE (decl)), seq_p);
1965 /* ??? DECL_ORIGINAL_TYPE is streamed for LTO so it needs to be gimplified
1966 in case its size expressions contain problematic nodes like CALL_EXPR. */
1967 if (TREE_CODE (decl) == TYPE_DECL
1968 && DECL_ORIGINAL_TYPE (decl)
1969 && !TYPE_SIZES_GIMPLIFIED (DECL_ORIGINAL_TYPE (decl)))
1971 gimplify_type_sizes (DECL_ORIGINAL_TYPE (decl), seq_p);
1972 if (TREE_CODE (DECL_ORIGINAL_TYPE (decl)) == REFERENCE_TYPE)
1973 gimplify_type_sizes (TREE_TYPE (DECL_ORIGINAL_TYPE (decl)), seq_p);
1976 if (VAR_P (decl) && !DECL_EXTERNAL (decl))
1978 tree init = DECL_INITIAL (decl);
1979 bool is_vla = false;
1980 /* Check whether a decl has FE created VALUE_EXPR here BEFORE
1981 gimplify_vla_decl creates VALUE_EXPR for a vla decl.
1982 If the decl has VALUE_EXPR that was created by FE (usually
1983 C++FE), it's a proxy varaible, and FE already initialized
1984 the VALUE_EXPR of it, we should not initialize it anymore. */
1985 bool decl_had_value_expr_p = DECL_HAS_VALUE_EXPR_P (decl);
1987 poly_uint64 size;
1988 if (!poly_int_tree_p (DECL_SIZE_UNIT (decl), &size)
1989 || (!TREE_STATIC (decl)
1990 && flag_stack_check == GENERIC_STACK_CHECK
1991 && maybe_gt (size,
1992 (unsigned HOST_WIDE_INT) STACK_CHECK_MAX_VAR_SIZE)))
1994 gimplify_vla_decl (decl, seq_p);
1995 is_vla = true;
1998 if (asan_poisoned_variables
1999 && !is_vla
2000 && TREE_ADDRESSABLE (decl)
2001 && !TREE_STATIC (decl)
2002 && !DECL_HAS_VALUE_EXPR_P (decl)
2003 && DECL_ALIGN (decl) <= MAX_SUPPORTED_STACK_ALIGNMENT
2004 && dbg_cnt (asan_use_after_scope)
2005 && !gimplify_omp_ctxp
2006 /* GNAT introduces temporaries to hold return values of calls in
2007 initializers of variables defined in other units, so the
2008 declaration of the variable is discarded completely. We do not
2009 want to issue poison calls for such dropped variables. */
2010 && (DECL_SEEN_IN_BIND_EXPR_P (decl)
2011 || (DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)))
2013 asan_poisoned_variables->add (decl);
2014 asan_poison_variable (decl, false, seq_p);
2015 if (!DECL_ARTIFICIAL (decl) && gimplify_ctxp->live_switch_vars)
2016 gimplify_ctxp->live_switch_vars->add (decl);
2019 /* Some front ends do not explicitly declare all anonymous
2020 artificial variables. We compensate here by declaring the
2021 variables, though it would be better if the front ends would
2022 explicitly declare them. */
2023 if (!DECL_SEEN_IN_BIND_EXPR_P (decl)
2024 && DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
2025 gimple_add_tmp_var (decl);
2027 if (init && init != error_mark_node)
2029 if (!TREE_STATIC (decl))
2031 DECL_INITIAL (decl) = NULL_TREE;
2032 init = build2 (INIT_EXPR, void_type_node, decl, init);
2033 gimplify_and_add (init, seq_p);
2034 ggc_free (init);
2035 /* Clear TREE_READONLY if we really have an initialization. */
2036 if (!DECL_INITIAL (decl)
2037 && !omp_privatize_by_reference (decl))
2038 TREE_READONLY (decl) = 0;
2040 else
2041 /* We must still examine initializers for static variables
2042 as they may contain a label address. */
2043 walk_tree (&init, force_labels_r, NULL, NULL);
2045 /* When there is no explicit initializer, if the user requested,
2046 We should insert an artifical initializer for this automatic
2047 variable. */
2048 else if (is_var_need_auto_init (decl)
2049 && !decl_had_value_expr_p)
2051 gimple_add_init_for_auto_var (decl,
2052 flag_auto_var_init,
2053 seq_p);
2054 /* The expanding of a call to the above .DEFERRED_INIT will apply
2055 block initialization to the whole space covered by this variable.
2056 As a result, all the paddings will be initialized to zeroes
2057 for zero initialization and 0xFE byte-repeatable patterns for
2058 pattern initialization.
2059 In order to make the paddings as zeroes for pattern init, We
2060 should add a call to __builtin_clear_padding to clear the
2061 paddings to zero in compatiple with CLANG.
2062 We cannot insert this call if the variable is a gimple register
2063 since __builtin_clear_padding will take the address of the
2064 variable. As a result, if a long double/_Complex long double
2065 variable will spilled into stack later, its padding is 0XFE. */
2066 if (flag_auto_var_init == AUTO_INIT_PATTERN
2067 && !is_gimple_reg (decl)
2068 && clear_padding_type_may_have_padding_p (TREE_TYPE (decl)))
2069 gimple_add_padding_init_for_auto_var (decl, is_vla, seq_p);
2073 return GS_ALL_DONE;
2076 /* Gimplify a LOOP_EXPR. Normally this just involves gimplifying the body
2077 and replacing the LOOP_EXPR with goto, but if the loop contains an
2078 EXIT_EXPR, we need to append a label for it to jump to. */
2080 static enum gimplify_status
2081 gimplify_loop_expr (tree *expr_p, gimple_seq *pre_p)
2083 tree saved_label = gimplify_ctxp->exit_label;
2084 tree start_label = create_artificial_label (UNKNOWN_LOCATION);
2086 gimplify_seq_add_stmt (pre_p, gimple_build_label (start_label));
2088 gimplify_ctxp->exit_label = NULL_TREE;
2090 gimplify_and_add (LOOP_EXPR_BODY (*expr_p), pre_p);
2092 gimplify_seq_add_stmt (pre_p, gimple_build_goto (start_label));
2094 if (gimplify_ctxp->exit_label)
2095 gimplify_seq_add_stmt (pre_p,
2096 gimple_build_label (gimplify_ctxp->exit_label));
2098 gimplify_ctxp->exit_label = saved_label;
2100 *expr_p = NULL;
2101 return GS_ALL_DONE;
2104 /* Gimplify a statement list onto a sequence. These may be created either
2105 by an enlightened front-end, or by shortcut_cond_expr. */
2107 static enum gimplify_status
2108 gimplify_statement_list (tree *expr_p, gimple_seq *pre_p)
2110 tree temp = voidify_wrapper_expr (*expr_p, NULL);
2112 tree_stmt_iterator i = tsi_start (*expr_p);
2114 while (!tsi_end_p (i))
2116 gimplify_stmt (tsi_stmt_ptr (i), pre_p);
2117 tsi_delink (&i);
2120 if (temp)
2122 *expr_p = temp;
2123 return GS_OK;
2126 return GS_ALL_DONE;
2130 /* Emit warning for the unreachable statment STMT if needed.
2131 Return the gimple itself when the warning is emitted, otherwise
2132 return NULL. */
2133 static gimple *
2134 emit_warn_switch_unreachable (gimple *stmt)
2136 if (gimple_code (stmt) == GIMPLE_GOTO
2137 && TREE_CODE (gimple_goto_dest (stmt)) == LABEL_DECL
2138 && DECL_ARTIFICIAL (gimple_goto_dest (stmt)))
2139 /* Don't warn for compiler-generated gotos. These occur
2140 in Duff's devices, for example. */
2141 return NULL;
2142 else if ((flag_auto_var_init > AUTO_INIT_UNINITIALIZED)
2143 && ((gimple_call_internal_p (stmt, IFN_DEFERRED_INIT))
2144 || (gimple_call_builtin_p (stmt, BUILT_IN_CLEAR_PADDING)
2145 && (bool) TREE_INT_CST_LOW (gimple_call_arg (stmt, 1)))
2146 || (is_gimple_assign (stmt)
2147 && gimple_assign_single_p (stmt)
2148 && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
2149 && gimple_call_internal_p (
2150 SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt)),
2151 IFN_DEFERRED_INIT))))
2152 /* Don't warn for compiler-generated initializations for
2153 -ftrivial-auto-var-init.
2154 There are 3 cases:
2155 case 1: a call to .DEFERRED_INIT;
2156 case 2: a call to __builtin_clear_padding with the 2nd argument is
2157 present and non-zero;
2158 case 3: a gimple assign store right after the call to .DEFERRED_INIT
2159 that has the LHS of .DEFERRED_INIT as the RHS as following:
2160 _1 = .DEFERRED_INIT (4, 2, &"i1"[0]);
2161 i1 = _1. */
2162 return NULL;
2163 else
2164 warning_at (gimple_location (stmt), OPT_Wswitch_unreachable,
2165 "statement will never be executed");
2166 return stmt;
2169 /* Callback for walk_gimple_seq. */
2171 static tree
2172 warn_switch_unreachable_and_auto_init_r (gimple_stmt_iterator *gsi_p,
2173 bool *handled_ops_p,
2174 struct walk_stmt_info *wi)
2176 gimple *stmt = gsi_stmt (*gsi_p);
2177 bool unreachable_issued = wi->info != NULL;
2179 *handled_ops_p = true;
2180 switch (gimple_code (stmt))
2182 case GIMPLE_TRY:
2183 /* A compiler-generated cleanup or a user-written try block.
2184 If it's empty, don't dive into it--that would result in
2185 worse location info. */
2186 if (gimple_try_eval (stmt) == NULL)
2188 if (warn_switch_unreachable && !unreachable_issued)
2189 wi->info = emit_warn_switch_unreachable (stmt);
2191 /* Stop when auto var init warning is not on. */
2192 if (!warn_trivial_auto_var_init)
2193 return integer_zero_node;
2195 /* Fall through. */
2196 case GIMPLE_BIND:
2197 case GIMPLE_CATCH:
2198 case GIMPLE_EH_FILTER:
2199 case GIMPLE_TRANSACTION:
2200 /* Walk the sub-statements. */
2201 *handled_ops_p = false;
2202 break;
2204 case GIMPLE_DEBUG:
2205 /* Ignore these. We may generate them before declarations that
2206 are never executed. If there's something to warn about,
2207 there will be non-debug stmts too, and we'll catch those. */
2208 break;
2210 case GIMPLE_LABEL:
2211 /* Stop till the first Label. */
2212 return integer_zero_node;
2213 case GIMPLE_CALL:
2214 if (gimple_call_internal_p (stmt, IFN_ASAN_MARK))
2216 *handled_ops_p = false;
2217 break;
2219 if (warn_trivial_auto_var_init
2220 && flag_auto_var_init > AUTO_INIT_UNINITIALIZED
2221 && gimple_call_internal_p (stmt, IFN_DEFERRED_INIT))
2223 /* Get the variable name from the 3rd argument of call. */
2224 tree var_name = gimple_call_arg (stmt, 2);
2225 var_name = TREE_OPERAND (TREE_OPERAND (var_name, 0), 0);
2226 const char *var_name_str = TREE_STRING_POINTER (var_name);
2228 warning_at (gimple_location (stmt), OPT_Wtrivial_auto_var_init,
2229 "%qs cannot be initialized with"
2230 "%<-ftrivial-auto-var_init%>",
2231 var_name_str);
2232 break;
2235 /* Fall through. */
2236 default:
2237 /* check the first "real" statement (not a decl/lexical scope/...), issue
2238 warning if needed. */
2239 if (warn_switch_unreachable && !unreachable_issued)
2240 wi->info = emit_warn_switch_unreachable (stmt);
2241 /* Stop when auto var init warning is not on. */
2242 if (!warn_trivial_auto_var_init)
2243 return integer_zero_node;
2244 break;
2246 return NULL_TREE;
2250 /* Possibly warn about unreachable statements between switch's controlling
2251 expression and the first case. Also warn about -ftrivial-auto-var-init
2252 cannot initialize the auto variable under such situation.
2253 SEQ is the body of a switch expression. */
2255 static void
2256 maybe_warn_switch_unreachable_and_auto_init (gimple_seq seq)
2258 if ((!warn_switch_unreachable && !warn_trivial_auto_var_init)
2259 /* This warning doesn't play well with Fortran when optimizations
2260 are on. */
2261 || lang_GNU_Fortran ()
2262 || seq == NULL)
2263 return;
2265 struct walk_stmt_info wi;
2267 memset (&wi, 0, sizeof (wi));
2268 walk_gimple_seq (seq, warn_switch_unreachable_and_auto_init_r, NULL, &wi);
2272 /* A label entry that pairs label and a location. */
2273 struct label_entry
2275 tree label;
2276 location_t loc;
2279 /* Find LABEL in vector of label entries VEC. */
2281 static struct label_entry *
2282 find_label_entry (const auto_vec<struct label_entry> *vec, tree label)
2284 unsigned int i;
2285 struct label_entry *l;
2287 FOR_EACH_VEC_ELT (*vec, i, l)
2288 if (l->label == label)
2289 return l;
2290 return NULL;
2293 /* Return true if LABEL, a LABEL_DECL, represents a case label
2294 in a vector of labels CASES. */
2296 static bool
2297 case_label_p (const vec<tree> *cases, tree label)
2299 unsigned int i;
2300 tree l;
2302 FOR_EACH_VEC_ELT (*cases, i, l)
2303 if (CASE_LABEL (l) == label)
2304 return true;
2305 return false;
2308 /* Find the last nondebug statement in a scope STMT. */
2310 static gimple *
2311 last_stmt_in_scope (gimple *stmt)
2313 if (!stmt)
2314 return NULL;
2316 switch (gimple_code (stmt))
2318 case GIMPLE_BIND:
2320 gbind *bind = as_a <gbind *> (stmt);
2321 stmt = gimple_seq_last_nondebug_stmt (gimple_bind_body (bind));
2322 return last_stmt_in_scope (stmt);
2325 case GIMPLE_TRY:
2327 gtry *try_stmt = as_a <gtry *> (stmt);
2328 stmt = gimple_seq_last_nondebug_stmt (gimple_try_eval (try_stmt));
2329 gimple *last_eval = last_stmt_in_scope (stmt);
2330 if (gimple_stmt_may_fallthru (last_eval)
2331 && (last_eval == NULL
2332 || !gimple_call_internal_p (last_eval, IFN_FALLTHROUGH))
2333 && gimple_try_kind (try_stmt) == GIMPLE_TRY_FINALLY)
2335 stmt = gimple_seq_last_nondebug_stmt (gimple_try_cleanup (try_stmt));
2336 return last_stmt_in_scope (stmt);
2338 else
2339 return last_eval;
2342 case GIMPLE_DEBUG:
2343 gcc_unreachable ();
2345 default:
2346 return stmt;
2350 /* Collect labels that may fall through into LABELS and return the statement
2351 preceding another case label, or a user-defined label. Store a location
2352 useful to give warnings at *PREVLOC (usually the location of the returned
2353 statement or of its surrounding scope). */
2355 static gimple *
2356 collect_fallthrough_labels (gimple_stmt_iterator *gsi_p,
2357 auto_vec <struct label_entry> *labels,
2358 location_t *prevloc)
2360 gimple *prev = NULL;
2362 *prevloc = UNKNOWN_LOCATION;
2365 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND)
2367 /* Recognize the special GIMPLE_BIND added by gimplify_switch_expr,
2368 which starts on a GIMPLE_SWITCH and ends with a break label.
2369 Handle that as a single statement that can fall through. */
2370 gbind *bind = as_a <gbind *> (gsi_stmt (*gsi_p));
2371 gimple *first = gimple_seq_first_stmt (gimple_bind_body (bind));
2372 gimple *last = gimple_seq_last_stmt (gimple_bind_body (bind));
2373 if (last
2374 && gimple_code (first) == GIMPLE_SWITCH
2375 && gimple_code (last) == GIMPLE_LABEL)
2377 tree label = gimple_label_label (as_a <glabel *> (last));
2378 if (SWITCH_BREAK_LABEL_P (label))
2380 prev = bind;
2381 gsi_next (gsi_p);
2382 continue;
2386 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND
2387 || gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_TRY)
2389 /* Nested scope. Only look at the last statement of
2390 the innermost scope. */
2391 location_t bind_loc = gimple_location (gsi_stmt (*gsi_p));
2392 gimple *last = last_stmt_in_scope (gsi_stmt (*gsi_p));
2393 if (last)
2395 prev = last;
2396 /* It might be a label without a location. Use the
2397 location of the scope then. */
2398 if (!gimple_has_location (prev))
2399 *prevloc = bind_loc;
2401 gsi_next (gsi_p);
2402 continue;
2405 /* Ifs are tricky. */
2406 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_COND)
2408 gcond *cond_stmt = as_a <gcond *> (gsi_stmt (*gsi_p));
2409 tree false_lab = gimple_cond_false_label (cond_stmt);
2410 location_t if_loc = gimple_location (cond_stmt);
2412 /* If we have e.g.
2413 if (i > 1) goto <D.2259>; else goto D;
2414 we can't do much with the else-branch. */
2415 if (!DECL_ARTIFICIAL (false_lab))
2416 break;
2418 /* Go on until the false label, then one step back. */
2419 for (; !gsi_end_p (*gsi_p); gsi_next (gsi_p))
2421 gimple *stmt = gsi_stmt (*gsi_p);
2422 if (gimple_code (stmt) == GIMPLE_LABEL
2423 && gimple_label_label (as_a <glabel *> (stmt)) == false_lab)
2424 break;
2427 /* Not found? Oops. */
2428 if (gsi_end_p (*gsi_p))
2429 break;
2431 /* A dead label can't fall through. */
2432 if (!UNUSED_LABEL_P (false_lab))
2434 struct label_entry l = { false_lab, if_loc };
2435 labels->safe_push (l);
2438 /* Go to the last statement of the then branch. */
2439 gsi_prev (gsi_p);
2441 /* if (i != 0) goto <D.1759>; else goto <D.1760>;
2442 <D.1759>:
2443 <stmt>;
2444 goto <D.1761>;
2445 <D.1760>:
2447 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_GOTO
2448 && !gimple_has_location (gsi_stmt (*gsi_p)))
2450 /* Look at the statement before, it might be
2451 attribute fallthrough, in which case don't warn. */
2452 gsi_prev (gsi_p);
2453 bool fallthru_before_dest
2454 = gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_FALLTHROUGH);
2455 gsi_next (gsi_p);
2456 tree goto_dest = gimple_goto_dest (gsi_stmt (*gsi_p));
2457 if (!fallthru_before_dest)
2459 struct label_entry l = { goto_dest, if_loc };
2460 labels->safe_push (l);
2463 /* This case is about
2464 if (1 != 0) goto <D.2022>; else goto <D.2023>;
2465 <D.2022>:
2466 n = n + 1; // #1
2467 <D.2023>: // #2
2468 <D.1988>: // #3
2469 where #2 is UNUSED_LABEL_P and we want to warn about #1 falling
2470 through to #3. So set PREV to #1. */
2471 else if (UNUSED_LABEL_P (false_lab))
2472 prev = gsi_stmt (*gsi_p);
2474 /* And move back. */
2475 gsi_next (gsi_p);
2478 /* Remember the last statement. Skip labels that are of no interest
2479 to us. */
2480 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
2482 tree label = gimple_label_label (as_a <glabel *> (gsi_stmt (*gsi_p)));
2483 if (find_label_entry (labels, label))
2484 prev = gsi_stmt (*gsi_p);
2486 else if (gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_ASAN_MARK))
2488 else if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_PREDICT)
2490 else if (!is_gimple_debug (gsi_stmt (*gsi_p)))
2491 prev = gsi_stmt (*gsi_p);
2492 gsi_next (gsi_p);
2494 while (!gsi_end_p (*gsi_p)
2495 /* Stop if we find a case or a user-defined label. */
2496 && (gimple_code (gsi_stmt (*gsi_p)) != GIMPLE_LABEL
2497 || !gimple_has_location (gsi_stmt (*gsi_p))));
2499 if (prev && gimple_has_location (prev))
2500 *prevloc = gimple_location (prev);
2501 return prev;
2504 /* Return true if the switch fallthough warning should occur. LABEL is
2505 the label statement that we're falling through to. */
2507 static bool
2508 should_warn_for_implicit_fallthrough (gimple_stmt_iterator *gsi_p, tree label)
2510 gimple_stmt_iterator gsi = *gsi_p;
2512 /* Don't warn if the label is marked with a "falls through" comment. */
2513 if (FALLTHROUGH_LABEL_P (label))
2514 return false;
2516 /* Don't warn for non-case labels followed by a statement:
2517 case 0:
2518 foo ();
2519 label:
2520 bar ();
2521 as these are likely intentional. */
2522 if (!case_label_p (&gimplify_ctxp->case_labels, label))
2524 tree l;
2525 while (!gsi_end_p (gsi)
2526 && gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
2527 && (l = gimple_label_label (as_a <glabel *> (gsi_stmt (gsi))))
2528 && !case_label_p (&gimplify_ctxp->case_labels, l))
2529 gsi_next_nondebug (&gsi);
2530 if (gsi_end_p (gsi) || gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL)
2531 return false;
2534 /* Don't warn for terminated branches, i.e. when the subsequent case labels
2535 immediately breaks. */
2536 gsi = *gsi_p;
2538 /* Skip all immediately following labels. */
2539 while (!gsi_end_p (gsi)
2540 && (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
2541 || gimple_code (gsi_stmt (gsi)) == GIMPLE_PREDICT))
2542 gsi_next_nondebug (&gsi);
2544 /* { ... something; default:; } */
2545 if (gsi_end_p (gsi)
2546 /* { ... something; default: break; } or
2547 { ... something; default: goto L; } */
2548 || gimple_code (gsi_stmt (gsi)) == GIMPLE_GOTO
2549 /* { ... something; default: return; } */
2550 || gimple_code (gsi_stmt (gsi)) == GIMPLE_RETURN)
2551 return false;
2553 return true;
2556 /* Callback for walk_gimple_seq. */
2558 static tree
2559 warn_implicit_fallthrough_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
2560 struct walk_stmt_info *)
2562 gimple *stmt = gsi_stmt (*gsi_p);
2564 *handled_ops_p = true;
2565 switch (gimple_code (stmt))
2567 case GIMPLE_TRY:
2568 case GIMPLE_BIND:
2569 case GIMPLE_CATCH:
2570 case GIMPLE_EH_FILTER:
2571 case GIMPLE_TRANSACTION:
2572 /* Walk the sub-statements. */
2573 *handled_ops_p = false;
2574 break;
2576 /* Find a sequence of form:
2578 GIMPLE_LABEL
2579 [...]
2580 <may fallthru stmt>
2581 GIMPLE_LABEL
2583 and possibly warn. */
2584 case GIMPLE_LABEL:
2586 /* Found a label. Skip all immediately following labels. */
2587 while (!gsi_end_p (*gsi_p)
2588 && gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
2589 gsi_next_nondebug (gsi_p);
2591 /* There might be no more statements. */
2592 if (gsi_end_p (*gsi_p))
2593 return integer_zero_node;
2595 /* Vector of labels that fall through. */
2596 auto_vec <struct label_entry> labels;
2597 location_t prevloc;
2598 gimple *prev = collect_fallthrough_labels (gsi_p, &labels, &prevloc);
2600 /* There might be no more statements. */
2601 if (gsi_end_p (*gsi_p))
2602 return integer_zero_node;
2604 gimple *next = gsi_stmt (*gsi_p);
2605 tree label;
2606 /* If what follows is a label, then we may have a fallthrough. */
2607 if (gimple_code (next) == GIMPLE_LABEL
2608 && gimple_has_location (next)
2609 && (label = gimple_label_label (as_a <glabel *> (next)))
2610 && prev != NULL)
2612 struct label_entry *l;
2613 bool warned_p = false;
2614 auto_diagnostic_group d;
2615 if (!should_warn_for_implicit_fallthrough (gsi_p, label))
2616 /* Quiet. */;
2617 else if (gimple_code (prev) == GIMPLE_LABEL
2618 && (label = gimple_label_label (as_a <glabel *> (prev)))
2619 && (l = find_label_entry (&labels, label)))
2620 warned_p = warning_at (l->loc, OPT_Wimplicit_fallthrough_,
2621 "this statement may fall through");
2622 else if (!gimple_call_internal_p (prev, IFN_FALLTHROUGH)
2623 /* Try to be clever and don't warn when the statement
2624 can't actually fall through. */
2625 && gimple_stmt_may_fallthru (prev)
2626 && prevloc != UNKNOWN_LOCATION)
2627 warned_p = warning_at (prevloc,
2628 OPT_Wimplicit_fallthrough_,
2629 "this statement may fall through");
2630 if (warned_p)
2631 inform (gimple_location (next), "here");
2633 /* Mark this label as processed so as to prevent multiple
2634 warnings in nested switches. */
2635 FALLTHROUGH_LABEL_P (label) = true;
2637 /* So that next warn_implicit_fallthrough_r will start looking for
2638 a new sequence starting with this label. */
2639 gsi_prev (gsi_p);
2642 break;
2643 default:
2644 break;
2646 return NULL_TREE;
2649 /* Warn when a switch case falls through. */
2651 static void
2652 maybe_warn_implicit_fallthrough (gimple_seq seq)
2654 if (!warn_implicit_fallthrough)
2655 return;
2657 /* This warning is meant for C/C++/ObjC/ObjC++ only. */
2658 if (!(lang_GNU_C ()
2659 || lang_GNU_CXX ()
2660 || lang_GNU_OBJC ()))
2661 return;
2663 struct walk_stmt_info wi;
2664 memset (&wi, 0, sizeof (wi));
2665 walk_gimple_seq (seq, warn_implicit_fallthrough_r, NULL, &wi);
2668 /* Callback for walk_gimple_seq. */
2670 static tree
2671 expand_FALLTHROUGH_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
2672 struct walk_stmt_info *wi)
2674 gimple *stmt = gsi_stmt (*gsi_p);
2676 *handled_ops_p = true;
2677 switch (gimple_code (stmt))
2679 case GIMPLE_TRY:
2680 case GIMPLE_BIND:
2681 case GIMPLE_CATCH:
2682 case GIMPLE_EH_FILTER:
2683 case GIMPLE_TRANSACTION:
2684 /* Walk the sub-statements. */
2685 *handled_ops_p = false;
2686 break;
2687 case GIMPLE_CALL:
2688 if (gimple_call_internal_p (stmt, IFN_FALLTHROUGH))
2690 gsi_remove (gsi_p, true);
2691 if (gsi_end_p (*gsi_p))
2693 *static_cast<location_t *>(wi->info) = gimple_location (stmt);
2694 return integer_zero_node;
2697 bool found = false;
2698 location_t loc = gimple_location (stmt);
2700 gimple_stmt_iterator gsi2 = *gsi_p;
2701 stmt = gsi_stmt (gsi2);
2702 if (gimple_code (stmt) == GIMPLE_GOTO && !gimple_has_location (stmt))
2704 /* Go on until the artificial label. */
2705 tree goto_dest = gimple_goto_dest (stmt);
2706 for (; !gsi_end_p (gsi2); gsi_next (&gsi2))
2708 if (gimple_code (gsi_stmt (gsi2)) == GIMPLE_LABEL
2709 && gimple_label_label (as_a <glabel *> (gsi_stmt (gsi2)))
2710 == goto_dest)
2711 break;
2714 /* Not found? Stop. */
2715 if (gsi_end_p (gsi2))
2716 break;
2718 /* Look one past it. */
2719 gsi_next (&gsi2);
2722 /* We're looking for a case label or default label here. */
2723 while (!gsi_end_p (gsi2))
2725 stmt = gsi_stmt (gsi2);
2726 if (gimple_code (stmt) == GIMPLE_LABEL)
2728 tree label = gimple_label_label (as_a <glabel *> (stmt));
2729 if (gimple_has_location (stmt) && DECL_ARTIFICIAL (label))
2731 found = true;
2732 break;
2735 else if (gimple_call_internal_p (stmt, IFN_ASAN_MARK))
2737 else if (!is_gimple_debug (stmt))
2738 /* Anything else is not expected. */
2739 break;
2740 gsi_next (&gsi2);
2742 if (!found)
2743 pedwarn (loc, 0, "attribute %<fallthrough%> not preceding "
2744 "a case label or default label");
2746 break;
2747 default:
2748 break;
2750 return NULL_TREE;
2753 /* Expand all FALLTHROUGH () calls in SEQ. */
2755 static void
2756 expand_FALLTHROUGH (gimple_seq *seq_p)
2758 struct walk_stmt_info wi;
2759 location_t loc;
2760 memset (&wi, 0, sizeof (wi));
2761 wi.info = (void *) &loc;
2762 walk_gimple_seq_mod (seq_p, expand_FALLTHROUGH_r, NULL, &wi);
2763 if (wi.callback_result == integer_zero_node)
2764 /* We've found [[fallthrough]]; at the end of a switch, which the C++
2765 standard says is ill-formed; see [dcl.attr.fallthrough]. */
2766 pedwarn (loc, 0, "attribute %<fallthrough%> not preceding "
2767 "a case label or default label");
2771 /* Gimplify a SWITCH_EXPR, and collect the vector of labels it can
2772 branch to. */
2774 static enum gimplify_status
2775 gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p)
2777 tree switch_expr = *expr_p;
2778 gimple_seq switch_body_seq = NULL;
2779 enum gimplify_status ret;
2780 tree index_type = TREE_TYPE (switch_expr);
2781 if (index_type == NULL_TREE)
2782 index_type = TREE_TYPE (SWITCH_COND (switch_expr));
2784 ret = gimplify_expr (&SWITCH_COND (switch_expr), pre_p, NULL, is_gimple_val,
2785 fb_rvalue);
2786 if (ret == GS_ERROR || ret == GS_UNHANDLED)
2787 return ret;
2789 if (SWITCH_BODY (switch_expr))
2791 vec<tree> labels;
2792 vec<tree> saved_labels;
2793 hash_set<tree> *saved_live_switch_vars = NULL;
2794 tree default_case = NULL_TREE;
2795 gswitch *switch_stmt;
2797 /* Save old labels, get new ones from body, then restore the old
2798 labels. Save all the things from the switch body to append after. */
2799 saved_labels = gimplify_ctxp->case_labels;
2800 gimplify_ctxp->case_labels.create (8);
2802 /* Do not create live_switch_vars if SWITCH_BODY is not a BIND_EXPR. */
2803 saved_live_switch_vars = gimplify_ctxp->live_switch_vars;
2804 tree_code body_type = TREE_CODE (SWITCH_BODY (switch_expr));
2805 if (body_type == BIND_EXPR || body_type == STATEMENT_LIST)
2806 gimplify_ctxp->live_switch_vars = new hash_set<tree> (4);
2807 else
2808 gimplify_ctxp->live_switch_vars = NULL;
2810 bool old_in_switch_expr = gimplify_ctxp->in_switch_expr;
2811 gimplify_ctxp->in_switch_expr = true;
2813 gimplify_stmt (&SWITCH_BODY (switch_expr), &switch_body_seq);
2815 gimplify_ctxp->in_switch_expr = old_in_switch_expr;
2816 maybe_warn_switch_unreachable_and_auto_init (switch_body_seq);
2817 maybe_warn_implicit_fallthrough (switch_body_seq);
2818 /* Only do this for the outermost GIMPLE_SWITCH. */
2819 if (!gimplify_ctxp->in_switch_expr)
2820 expand_FALLTHROUGH (&switch_body_seq);
2822 labels = gimplify_ctxp->case_labels;
2823 gimplify_ctxp->case_labels = saved_labels;
2825 if (gimplify_ctxp->live_switch_vars)
2827 gcc_assert (gimplify_ctxp->live_switch_vars->is_empty ());
2828 delete gimplify_ctxp->live_switch_vars;
2830 gimplify_ctxp->live_switch_vars = saved_live_switch_vars;
2832 preprocess_case_label_vec_for_gimple (labels, index_type,
2833 &default_case);
2835 bool add_bind = false;
2836 if (!default_case)
2838 glabel *new_default;
2840 default_case
2841 = build_case_label (NULL_TREE, NULL_TREE,
2842 create_artificial_label (UNKNOWN_LOCATION));
2843 if (old_in_switch_expr)
2845 SWITCH_BREAK_LABEL_P (CASE_LABEL (default_case)) = 1;
2846 add_bind = true;
2848 new_default = gimple_build_label (CASE_LABEL (default_case));
2849 gimplify_seq_add_stmt (&switch_body_seq, new_default);
2851 else if (old_in_switch_expr)
2853 gimple *last = gimple_seq_last_stmt (switch_body_seq);
2854 if (last && gimple_code (last) == GIMPLE_LABEL)
2856 tree label = gimple_label_label (as_a <glabel *> (last));
2857 if (SWITCH_BREAK_LABEL_P (label))
2858 add_bind = true;
2862 switch_stmt = gimple_build_switch (SWITCH_COND (switch_expr),
2863 default_case, labels);
2864 /* For the benefit of -Wimplicit-fallthrough, if switch_body_seq
2865 ends with a GIMPLE_LABEL holding SWITCH_BREAK_LABEL_P LABEL_DECL,
2866 wrap the GIMPLE_SWITCH up to that GIMPLE_LABEL into a GIMPLE_BIND,
2867 so that we can easily find the start and end of the switch
2868 statement. */
2869 if (add_bind)
2871 gimple_seq bind_body = NULL;
2872 gimplify_seq_add_stmt (&bind_body, switch_stmt);
2873 gimple_seq_add_seq (&bind_body, switch_body_seq);
2874 gbind *bind = gimple_build_bind (NULL_TREE, bind_body, NULL_TREE);
2875 gimple_set_location (bind, EXPR_LOCATION (switch_expr));
2876 gimplify_seq_add_stmt (pre_p, bind);
2878 else
2880 gimplify_seq_add_stmt (pre_p, switch_stmt);
2881 gimplify_seq_add_seq (pre_p, switch_body_seq);
2883 labels.release ();
2885 else
2886 gcc_unreachable ();
2888 return GS_ALL_DONE;
2891 /* Gimplify the LABEL_EXPR pointed to by EXPR_P. */
2893 static enum gimplify_status
2894 gimplify_label_expr (tree *expr_p, gimple_seq *pre_p)
2896 gcc_assert (decl_function_context (LABEL_EXPR_LABEL (*expr_p))
2897 == current_function_decl);
2899 tree label = LABEL_EXPR_LABEL (*expr_p);
2900 glabel *label_stmt = gimple_build_label (label);
2901 gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
2902 gimplify_seq_add_stmt (pre_p, label_stmt);
2904 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label)))
2905 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_COLD_LABEL,
2906 NOT_TAKEN));
2907 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label)))
2908 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_HOT_LABEL,
2909 TAKEN));
2911 return GS_ALL_DONE;
2914 /* Gimplify the CASE_LABEL_EXPR pointed to by EXPR_P. */
2916 static enum gimplify_status
2917 gimplify_case_label_expr (tree *expr_p, gimple_seq *pre_p)
2919 struct gimplify_ctx *ctxp;
2920 glabel *label_stmt;
2922 /* Invalid programs can play Duff's Device type games with, for example,
2923 #pragma omp parallel. At least in the C front end, we don't
2924 detect such invalid branches until after gimplification, in the
2925 diagnose_omp_blocks pass. */
2926 for (ctxp = gimplify_ctxp; ; ctxp = ctxp->prev_context)
2927 if (ctxp->case_labels.exists ())
2928 break;
2930 tree label = CASE_LABEL (*expr_p);
2931 label_stmt = gimple_build_label (label);
2932 gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
2933 ctxp->case_labels.safe_push (*expr_p);
2934 gimplify_seq_add_stmt (pre_p, label_stmt);
2936 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label)))
2937 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_COLD_LABEL,
2938 NOT_TAKEN));
2939 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label)))
2940 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_HOT_LABEL,
2941 TAKEN));
2943 return GS_ALL_DONE;
2946 /* Build a GOTO to the LABEL_DECL pointed to by LABEL_P, building it first
2947 if necessary. */
2949 tree
2950 build_and_jump (tree *label_p)
2952 if (label_p == NULL)
2953 /* If there's nowhere to jump, just fall through. */
2954 return NULL_TREE;
2956 if (*label_p == NULL_TREE)
2958 tree label = create_artificial_label (UNKNOWN_LOCATION);
2959 *label_p = label;
2962 return build1 (GOTO_EXPR, void_type_node, *label_p);
2965 /* Gimplify an EXIT_EXPR by converting to a GOTO_EXPR inside a COND_EXPR.
2966 This also involves building a label to jump to and communicating it to
2967 gimplify_loop_expr through gimplify_ctxp->exit_label. */
2969 static enum gimplify_status
2970 gimplify_exit_expr (tree *expr_p)
2972 tree cond = TREE_OPERAND (*expr_p, 0);
2973 tree expr;
2975 expr = build_and_jump (&gimplify_ctxp->exit_label);
2976 expr = build3 (COND_EXPR, void_type_node, cond, expr, NULL_TREE);
2977 *expr_p = expr;
2979 return GS_OK;
2982 /* *EXPR_P is a COMPONENT_REF being used as an rvalue. If its type is
2983 different from its canonical type, wrap the whole thing inside a
2984 NOP_EXPR and force the type of the COMPONENT_REF to be the canonical
2985 type.
2987 The canonical type of a COMPONENT_REF is the type of the field being
2988 referenced--unless the field is a bit-field which can be read directly
2989 in a smaller mode, in which case the canonical type is the
2990 sign-appropriate type corresponding to that mode. */
2992 static void
2993 canonicalize_component_ref (tree *expr_p)
2995 tree expr = *expr_p;
2996 tree type;
2998 gcc_assert (TREE_CODE (expr) == COMPONENT_REF);
3000 if (INTEGRAL_TYPE_P (TREE_TYPE (expr)))
3001 type = TREE_TYPE (get_unwidened (expr, NULL_TREE));
3002 else
3003 type = TREE_TYPE (TREE_OPERAND (expr, 1));
3005 /* One could argue that all the stuff below is not necessary for
3006 the non-bitfield case and declare it a FE error if type
3007 adjustment would be needed. */
3008 if (TREE_TYPE (expr) != type)
3010 #ifdef ENABLE_TYPES_CHECKING
3011 tree old_type = TREE_TYPE (expr);
3012 #endif
3013 int type_quals;
3015 /* We need to preserve qualifiers and propagate them from
3016 operand 0. */
3017 type_quals = TYPE_QUALS (type)
3018 | TYPE_QUALS (TREE_TYPE (TREE_OPERAND (expr, 0)));
3019 if (TYPE_QUALS (type) != type_quals)
3020 type = build_qualified_type (TYPE_MAIN_VARIANT (type), type_quals);
3022 /* Set the type of the COMPONENT_REF to the underlying type. */
3023 TREE_TYPE (expr) = type;
3025 #ifdef ENABLE_TYPES_CHECKING
3026 /* It is now a FE error, if the conversion from the canonical
3027 type to the original expression type is not useless. */
3028 gcc_assert (useless_type_conversion_p (old_type, type));
3029 #endif
3033 /* If a NOP conversion is changing a pointer to array of foo to a pointer
3034 to foo, embed that change in the ADDR_EXPR by converting
3035 T array[U];
3036 (T *)&array
3038 &array[L]
3039 where L is the lower bound. For simplicity, only do this for constant
3040 lower bound.
3041 The constraint is that the type of &array[L] is trivially convertible
3042 to T *. */
3044 static void
3045 canonicalize_addr_expr (tree *expr_p)
3047 tree expr = *expr_p;
3048 tree addr_expr = TREE_OPERAND (expr, 0);
3049 tree datype, ddatype, pddatype;
3051 /* We simplify only conversions from an ADDR_EXPR to a pointer type. */
3052 if (!POINTER_TYPE_P (TREE_TYPE (expr))
3053 || TREE_CODE (addr_expr) != ADDR_EXPR)
3054 return;
3056 /* The addr_expr type should be a pointer to an array. */
3057 datype = TREE_TYPE (TREE_TYPE (addr_expr));
3058 if (TREE_CODE (datype) != ARRAY_TYPE)
3059 return;
3061 /* The pointer to element type shall be trivially convertible to
3062 the expression pointer type. */
3063 ddatype = TREE_TYPE (datype);
3064 pddatype = build_pointer_type (ddatype);
3065 if (!useless_type_conversion_p (TYPE_MAIN_VARIANT (TREE_TYPE (expr)),
3066 pddatype))
3067 return;
3069 /* The lower bound and element sizes must be constant. */
3070 if (!TYPE_SIZE_UNIT (ddatype)
3071 || TREE_CODE (TYPE_SIZE_UNIT (ddatype)) != INTEGER_CST
3072 || !TYPE_DOMAIN (datype) || !TYPE_MIN_VALUE (TYPE_DOMAIN (datype))
3073 || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (datype))) != INTEGER_CST)
3074 return;
3076 /* All checks succeeded. Build a new node to merge the cast. */
3077 *expr_p = build4 (ARRAY_REF, ddatype, TREE_OPERAND (addr_expr, 0),
3078 TYPE_MIN_VALUE (TYPE_DOMAIN (datype)),
3079 NULL_TREE, NULL_TREE);
3080 *expr_p = build1 (ADDR_EXPR, pddatype, *expr_p);
3082 /* We can have stripped a required restrict qualifier above. */
3083 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
3084 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
3087 /* *EXPR_P is a NOP_EXPR or CONVERT_EXPR. Remove it and/or other conversions
3088 underneath as appropriate. */
3090 static enum gimplify_status
3091 gimplify_conversion (tree *expr_p)
3093 location_t loc = EXPR_LOCATION (*expr_p);
3094 gcc_assert (CONVERT_EXPR_P (*expr_p));
3096 /* Then strip away all but the outermost conversion. */
3097 STRIP_SIGN_NOPS (TREE_OPERAND (*expr_p, 0));
3099 /* And remove the outermost conversion if it's useless. */
3100 if (tree_ssa_useless_type_conversion (*expr_p))
3101 *expr_p = TREE_OPERAND (*expr_p, 0);
3103 /* If we still have a conversion at the toplevel,
3104 then canonicalize some constructs. */
3105 if (CONVERT_EXPR_P (*expr_p))
3107 tree sub = TREE_OPERAND (*expr_p, 0);
3109 /* If a NOP conversion is changing the type of a COMPONENT_REF
3110 expression, then canonicalize its type now in order to expose more
3111 redundant conversions. */
3112 if (TREE_CODE (sub) == COMPONENT_REF)
3113 canonicalize_component_ref (&TREE_OPERAND (*expr_p, 0));
3115 /* If a NOP conversion is changing a pointer to array of foo
3116 to a pointer to foo, embed that change in the ADDR_EXPR. */
3117 else if (TREE_CODE (sub) == ADDR_EXPR)
3118 canonicalize_addr_expr (expr_p);
3121 /* If we have a conversion to a non-register type force the
3122 use of a VIEW_CONVERT_EXPR instead. */
3123 if (CONVERT_EXPR_P (*expr_p) && !is_gimple_reg_type (TREE_TYPE (*expr_p)))
3124 *expr_p = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (*expr_p),
3125 TREE_OPERAND (*expr_p, 0));
3127 /* Canonicalize CONVERT_EXPR to NOP_EXPR. */
3128 if (TREE_CODE (*expr_p) == CONVERT_EXPR)
3129 TREE_SET_CODE (*expr_p, NOP_EXPR);
3131 return GS_OK;
3134 /* Gimplify a VAR_DECL or PARM_DECL. Return GS_OK if we expanded a
3135 DECL_VALUE_EXPR, and it's worth re-examining things. */
3137 static enum gimplify_status
3138 gimplify_var_or_parm_decl (tree *expr_p)
3140 tree decl = *expr_p;
3142 /* ??? If this is a local variable, and it has not been seen in any
3143 outer BIND_EXPR, then it's probably the result of a duplicate
3144 declaration, for which we've already issued an error. It would
3145 be really nice if the front end wouldn't leak these at all.
3146 Currently the only known culprit is C++ destructors, as seen
3147 in g++.old-deja/g++.jason/binding.C.
3148 Another possible culpit are size expressions for variably modified
3149 types which are lost in the FE or not gimplified correctly. */
3150 if (VAR_P (decl)
3151 && !DECL_SEEN_IN_BIND_EXPR_P (decl)
3152 && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl)
3153 && decl_function_context (decl) == current_function_decl)
3155 gcc_assert (seen_error ());
3156 return GS_ERROR;
3159 /* When within an OMP context, notice uses of variables. */
3160 if (gimplify_omp_ctxp && omp_notice_variable (gimplify_omp_ctxp, decl, true))
3161 return GS_ALL_DONE;
3163 /* If the decl is an alias for another expression, substitute it now. */
3164 if (DECL_HAS_VALUE_EXPR_P (decl))
3166 *expr_p = unshare_expr (DECL_VALUE_EXPR (decl));
3167 return GS_OK;
3170 return GS_ALL_DONE;
3173 /* Recalculate the value of the TREE_SIDE_EFFECTS flag for T. */
3175 static void
3176 recalculate_side_effects (tree t)
3178 enum tree_code code = TREE_CODE (t);
3179 int len = TREE_OPERAND_LENGTH (t);
3180 int i;
3182 switch (TREE_CODE_CLASS (code))
3184 case tcc_expression:
3185 switch (code)
3187 case INIT_EXPR:
3188 case MODIFY_EXPR:
3189 case VA_ARG_EXPR:
3190 case PREDECREMENT_EXPR:
3191 case PREINCREMENT_EXPR:
3192 case POSTDECREMENT_EXPR:
3193 case POSTINCREMENT_EXPR:
3194 /* All of these have side-effects, no matter what their
3195 operands are. */
3196 return;
3198 default:
3199 break;
3201 /* Fall through. */
3203 case tcc_comparison: /* a comparison expression */
3204 case tcc_unary: /* a unary arithmetic expression */
3205 case tcc_binary: /* a binary arithmetic expression */
3206 case tcc_reference: /* a reference */
3207 case tcc_vl_exp: /* a function call */
3208 TREE_SIDE_EFFECTS (t) = TREE_THIS_VOLATILE (t);
3209 for (i = 0; i < len; ++i)
3211 tree op = TREE_OPERAND (t, i);
3212 if (op && TREE_SIDE_EFFECTS (op))
3213 TREE_SIDE_EFFECTS (t) = 1;
3215 break;
3217 case tcc_constant:
3218 /* No side-effects. */
3219 return;
3221 default:
3222 gcc_unreachable ();
3226 /* Gimplify the COMPONENT_REF, ARRAY_REF, REALPART_EXPR or IMAGPART_EXPR
3227 node *EXPR_P.
3229 compound_lval
3230 : min_lval '[' val ']'
3231 | min_lval '.' ID
3232 | compound_lval '[' val ']'
3233 | compound_lval '.' ID
3235 This is not part of the original SIMPLE definition, which separates
3236 array and member references, but it seems reasonable to handle them
3237 together. Also, this way we don't run into problems with union
3238 aliasing; gcc requires that for accesses through a union to alias, the
3239 union reference must be explicit, which was not always the case when we
3240 were splitting up array and member refs.
3242 PRE_P points to the sequence where side effects that must happen before
3243 *EXPR_P should be stored.
3245 POST_P points to the sequence where side effects that must happen after
3246 *EXPR_P should be stored. */
3248 static enum gimplify_status
3249 gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
3250 fallback_t fallback)
3252 tree *p;
3253 enum gimplify_status ret = GS_ALL_DONE, tret;
3254 int i;
3255 location_t loc = EXPR_LOCATION (*expr_p);
3256 tree expr = *expr_p;
3258 /* Create a stack of the subexpressions so later we can walk them in
3259 order from inner to outer. */
3260 auto_vec<tree, 10> expr_stack;
3262 /* We can handle anything that get_inner_reference can deal with. */
3263 for (p = expr_p; ; p = &TREE_OPERAND (*p, 0))
3265 restart:
3266 /* Fold INDIRECT_REFs now to turn them into ARRAY_REFs. */
3267 if (TREE_CODE (*p) == INDIRECT_REF)
3268 *p = fold_indirect_ref_loc (loc, *p);
3270 if (handled_component_p (*p))
3272 /* Expand DECL_VALUE_EXPR now. In some cases that may expose
3273 additional COMPONENT_REFs. */
3274 else if ((VAR_P (*p) || TREE_CODE (*p) == PARM_DECL)
3275 && gimplify_var_or_parm_decl (p) == GS_OK)
3276 goto restart;
3277 else
3278 break;
3280 expr_stack.safe_push (*p);
3283 gcc_assert (expr_stack.length ());
3285 /* Now EXPR_STACK is a stack of pointers to all the refs we've
3286 walked through and P points to the innermost expression.
3288 Java requires that we elaborated nodes in source order. That
3289 means we must gimplify the inner expression followed by each of
3290 the indices, in order. But we can't gimplify the inner
3291 expression until we deal with any variable bounds, sizes, or
3292 positions in order to deal with PLACEHOLDER_EXPRs.
3294 The base expression may contain a statement expression that
3295 has declarations used in size expressions, so has to be
3296 gimplified before gimplifying the size expressions.
3298 So we do this in three steps. First we deal with variable
3299 bounds, sizes, and positions, then we gimplify the base and
3300 ensure it is memory if needed, then we deal with the annotations
3301 for any variables in the components and any indices, from left
3302 to right. */
3304 bool need_non_reg = false;
3305 for (i = expr_stack.length () - 1; i >= 0; i--)
3307 tree t = expr_stack[i];
3309 if (error_operand_p (TREE_OPERAND (t, 0)))
3310 return GS_ERROR;
3312 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
3314 /* Deal with the low bound and element type size and put them into
3315 the ARRAY_REF. If these values are set, they have already been
3316 gimplified. */
3317 if (TREE_OPERAND (t, 2) == NULL_TREE)
3319 tree low = unshare_expr (array_ref_low_bound (t));
3320 if (!is_gimple_min_invariant (low))
3322 TREE_OPERAND (t, 2) = low;
3326 if (TREE_OPERAND (t, 3) == NULL_TREE)
3328 tree elmt_size = array_ref_element_size (t);
3329 if (!is_gimple_min_invariant (elmt_size))
3331 elmt_size = unshare_expr (elmt_size);
3332 tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0)));
3333 tree factor = size_int (TYPE_ALIGN_UNIT (elmt_type));
3335 /* Divide the element size by the alignment of the element
3336 type (above). */
3337 elmt_size = size_binop_loc (loc, EXACT_DIV_EXPR,
3338 elmt_size, factor);
3340 TREE_OPERAND (t, 3) = elmt_size;
3343 need_non_reg = true;
3345 else if (TREE_CODE (t) == COMPONENT_REF)
3347 /* Set the field offset into T and gimplify it. */
3348 if (TREE_OPERAND (t, 2) == NULL_TREE)
3350 tree offset = component_ref_field_offset (t);
3351 if (!is_gimple_min_invariant (offset))
3353 offset = unshare_expr (offset);
3354 tree field = TREE_OPERAND (t, 1);
3355 tree factor
3356 = size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT);
3358 /* Divide the offset by its alignment. */
3359 offset = size_binop_loc (loc, EXACT_DIV_EXPR,
3360 offset, factor);
3362 TREE_OPERAND (t, 2) = offset;
3365 need_non_reg = true;
3367 else if (!is_gimple_reg_type (TREE_TYPE (t)))
3368 /* When the result of an operation, in particular a VIEW_CONVERT_EXPR
3369 is a non-register type then require the base object to be a
3370 non-register as well. */
3371 need_non_reg = true;
3374 /* Step 2 is to gimplify the base expression. Make sure lvalue is set
3375 so as to match the min_lval predicate. Failure to do so may result
3376 in the creation of large aggregate temporaries. */
3377 tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval,
3378 fallback | fb_lvalue);
3379 ret = MIN (ret, tret);
3380 if (ret == GS_ERROR)
3381 return GS_ERROR;
3383 /* Step 2a: if we have component references we do not support on
3384 registers then make sure the base isn't a register. Of course
3385 we can only do so if an rvalue is OK. */
3386 if (need_non_reg && (fallback & fb_rvalue))
3387 prepare_gimple_addressable (p, pre_p);
3390 /* Step 3: gimplify size expressions and the indices and operands of
3391 ARRAY_REF. During this loop we also remove any useless conversions.
3392 If we operate on a register also make sure to properly gimplify
3393 to individual operations. */
3395 bool reg_operations = is_gimple_reg (*p);
3396 for (; expr_stack.length () > 0; )
3398 tree t = expr_stack.pop ();
3400 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
3402 gcc_assert (!reg_operations);
3404 /* Gimplify the low bound and element type size. */
3405 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
3406 is_gimple_reg, fb_rvalue);
3407 ret = MIN (ret, tret);
3409 tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p, post_p,
3410 is_gimple_reg, fb_rvalue);
3411 ret = MIN (ret, tret);
3413 /* Gimplify the dimension. */
3414 tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
3415 is_gimple_val, fb_rvalue);
3416 ret = MIN (ret, tret);
3418 else if (TREE_CODE (t) == COMPONENT_REF)
3420 gcc_assert (!reg_operations);
3422 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
3423 is_gimple_reg, fb_rvalue);
3424 ret = MIN (ret, tret);
3426 else if (reg_operations)
3428 tret = gimplify_expr (&TREE_OPERAND (t, 0), pre_p, post_p,
3429 is_gimple_val, fb_rvalue);
3430 ret = MIN (ret, tret);
3433 STRIP_USELESS_TYPE_CONVERSION (TREE_OPERAND (t, 0));
3435 /* The innermost expression P may have originally had
3436 TREE_SIDE_EFFECTS set which would have caused all the outer
3437 expressions in *EXPR_P leading to P to also have had
3438 TREE_SIDE_EFFECTS set. */
3439 recalculate_side_effects (t);
3442 /* If the outermost expression is a COMPONENT_REF, canonicalize its type. */
3443 if ((fallback & fb_rvalue) && TREE_CODE (*expr_p) == COMPONENT_REF)
3445 canonicalize_component_ref (expr_p);
3448 expr_stack.release ();
3450 gcc_assert (*expr_p == expr || ret != GS_ALL_DONE);
3452 return ret;
3455 /* Gimplify the self modifying expression pointed to by EXPR_P
3456 (++, --, +=, -=).
3458 PRE_P points to the list where side effects that must happen before
3459 *EXPR_P should be stored.
3461 POST_P points to the list where side effects that must happen after
3462 *EXPR_P should be stored.
3464 WANT_VALUE is nonzero iff we want to use the value of this expression
3465 in another expression.
3467 ARITH_TYPE is the type the computation should be performed in. */
3469 enum gimplify_status
3470 gimplify_self_mod_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
3471 bool want_value, tree arith_type)
3473 enum tree_code code;
3474 tree lhs, lvalue, rhs, t1;
3475 gimple_seq post = NULL, *orig_post_p = post_p;
3476 bool postfix;
3477 enum tree_code arith_code;
3478 enum gimplify_status ret;
3479 location_t loc = EXPR_LOCATION (*expr_p);
3481 code = TREE_CODE (*expr_p);
3483 gcc_assert (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR
3484 || code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR);
3486 /* Prefix or postfix? */
3487 if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
3488 /* Faster to treat as prefix if result is not used. */
3489 postfix = want_value;
3490 else
3491 postfix = false;
3493 /* For postfix, make sure the inner expression's post side effects
3494 are executed after side effects from this expression. */
3495 if (postfix)
3496 post_p = &post;
3498 /* Add or subtract? */
3499 if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
3500 arith_code = PLUS_EXPR;
3501 else
3502 arith_code = MINUS_EXPR;
3504 /* Gimplify the LHS into a GIMPLE lvalue. */
3505 lvalue = TREE_OPERAND (*expr_p, 0);
3506 ret = gimplify_expr (&lvalue, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
3507 if (ret == GS_ERROR)
3508 return ret;
3510 /* Extract the operands to the arithmetic operation. */
3511 lhs = lvalue;
3512 rhs = TREE_OPERAND (*expr_p, 1);
3514 /* For postfix operator, we evaluate the LHS to an rvalue and then use
3515 that as the result value and in the postqueue operation. */
3516 if (postfix)
3518 ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue);
3519 if (ret == GS_ERROR)
3520 return ret;
3522 lhs = get_initialized_tmp_var (lhs, pre_p);
3525 /* For POINTERs increment, use POINTER_PLUS_EXPR. */
3526 if (POINTER_TYPE_P (TREE_TYPE (lhs)))
3528 rhs = convert_to_ptrofftype_loc (loc, rhs);
3529 if (arith_code == MINUS_EXPR)
3530 rhs = fold_build1_loc (loc, NEGATE_EXPR, TREE_TYPE (rhs), rhs);
3531 t1 = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (*expr_p), lhs, rhs);
3533 else
3534 t1 = fold_convert (TREE_TYPE (*expr_p),
3535 fold_build2 (arith_code, arith_type,
3536 fold_convert (arith_type, lhs),
3537 fold_convert (arith_type, rhs)));
3539 if (postfix)
3541 gimplify_assign (lvalue, t1, pre_p);
3542 gimplify_seq_add_seq (orig_post_p, post);
3543 *expr_p = lhs;
3544 return GS_ALL_DONE;
3546 else
3548 *expr_p = build2 (MODIFY_EXPR, TREE_TYPE (lvalue), lvalue, t1);
3549 return GS_OK;
3553 /* If *EXPR_P has a variable sized type, wrap it in a WITH_SIZE_EXPR. */
3555 static void
3556 maybe_with_size_expr (tree *expr_p)
3558 tree expr = *expr_p;
3559 tree type = TREE_TYPE (expr);
3560 tree size;
3562 /* If we've already wrapped this or the type is error_mark_node, we can't do
3563 anything. */
3564 if (TREE_CODE (expr) == WITH_SIZE_EXPR
3565 || type == error_mark_node)
3566 return;
3568 /* If the size isn't known or is a constant, we have nothing to do. */
3569 size = TYPE_SIZE_UNIT (type);
3570 if (!size || poly_int_tree_p (size))
3571 return;
3573 /* Otherwise, make a WITH_SIZE_EXPR. */
3574 size = unshare_expr (size);
3575 size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, expr);
3576 *expr_p = build2 (WITH_SIZE_EXPR, type, expr, size);
3579 /* Helper for gimplify_call_expr. Gimplify a single argument *ARG_P
3580 Store any side-effects in PRE_P. CALL_LOCATION is the location of
3581 the CALL_EXPR. If ALLOW_SSA is set the actual parameter may be
3582 gimplified to an SSA name. */
3584 enum gimplify_status
3585 gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location,
3586 bool allow_ssa)
3588 bool (*test) (tree);
3589 fallback_t fb;
3591 /* In general, we allow lvalues for function arguments to avoid
3592 extra overhead of copying large aggregates out of even larger
3593 aggregates into temporaries only to copy the temporaries to
3594 the argument list. Make optimizers happy by pulling out to
3595 temporaries those types that fit in registers. */
3596 if (is_gimple_reg_type (TREE_TYPE (*arg_p)))
3597 test = is_gimple_val, fb = fb_rvalue;
3598 else
3600 test = is_gimple_lvalue, fb = fb_either;
3601 /* Also strip a TARGET_EXPR that would force an extra copy. */
3602 if (TREE_CODE (*arg_p) == TARGET_EXPR)
3604 tree init = TARGET_EXPR_INITIAL (*arg_p);
3605 if (init
3606 && !VOID_TYPE_P (TREE_TYPE (init)))
3607 *arg_p = init;
3611 /* If this is a variable sized type, we must remember the size. */
3612 maybe_with_size_expr (arg_p);
3614 /* FIXME diagnostics: This will mess up gcc.dg/Warray-bounds.c. */
3615 /* Make sure arguments have the same location as the function call
3616 itself. */
3617 protected_set_expr_location (*arg_p, call_location);
3619 /* There is a sequence point before a function call. Side effects in
3620 the argument list must occur before the actual call. So, when
3621 gimplifying arguments, force gimplify_expr to use an internal
3622 post queue which is then appended to the end of PRE_P. */
3623 return gimplify_expr (arg_p, pre_p, NULL, test, fb, allow_ssa);
3626 /* Don't fold inside offloading or taskreg regions: it can break code by
3627 adding decl references that weren't in the source. We'll do it during
3628 omplower pass instead. */
3630 static bool
3631 maybe_fold_stmt (gimple_stmt_iterator *gsi)
3633 struct gimplify_omp_ctx *ctx;
3634 for (ctx = gimplify_omp_ctxp; ctx; ctx = ctx->outer_context)
3635 if ((ctx->region_type & (ORT_TARGET | ORT_PARALLEL | ORT_TASK)) != 0)
3636 return false;
3637 else if ((ctx->region_type & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
3638 return false;
3639 /* Delay folding of builtins until the IL is in consistent state
3640 so the diagnostic machinery can do a better job. */
3641 if (gimple_call_builtin_p (gsi_stmt (*gsi)))
3642 return false;
3643 return fold_stmt (gsi);
3646 /* Gimplify the CALL_EXPR node *EXPR_P into the GIMPLE sequence PRE_P.
3647 WANT_VALUE is true if the result of the call is desired. */
3649 static enum gimplify_status
3650 gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
3652 tree fndecl, parms, p, fnptrtype;
3653 enum gimplify_status ret;
3654 int i, nargs;
3655 gcall *call;
3656 bool builtin_va_start_p = false;
3657 location_t loc = EXPR_LOCATION (*expr_p);
3659 gcc_assert (TREE_CODE (*expr_p) == CALL_EXPR);
3661 /* For reliable diagnostics during inlining, it is necessary that
3662 every call_expr be annotated with file and line. */
3663 if (! EXPR_HAS_LOCATION (*expr_p))
3664 SET_EXPR_LOCATION (*expr_p, input_location);
3666 /* Gimplify internal functions created in the FEs. */
3667 if (CALL_EXPR_FN (*expr_p) == NULL_TREE)
3669 if (want_value)
3670 return GS_ALL_DONE;
3672 nargs = call_expr_nargs (*expr_p);
3673 enum internal_fn ifn = CALL_EXPR_IFN (*expr_p);
3674 auto_vec<tree> vargs (nargs);
3676 if (ifn == IFN_ASSUME)
3678 if (simple_condition_p (CALL_EXPR_ARG (*expr_p, 0)))
3680 /* If the [[assume (cond)]]; condition is simple
3681 enough and can be evaluated unconditionally
3682 without side-effects, expand it as
3683 if (!cond) __builtin_unreachable (); */
3684 tree fndecl = builtin_decl_explicit (BUILT_IN_UNREACHABLE);
3685 *expr_p = build3 (COND_EXPR, void_type_node,
3686 CALL_EXPR_ARG (*expr_p, 0), void_node,
3687 build_call_expr_loc (EXPR_LOCATION (*expr_p),
3688 fndecl, 0));
3689 return GS_OK;
3691 /* If not optimizing, ignore the assumptions. */
3692 if (!optimize || seen_error ())
3694 *expr_p = NULL_TREE;
3695 return GS_ALL_DONE;
3697 /* Temporarily, until gimple lowering, transform
3698 .ASSUME (cond);
3699 into:
3700 [[assume (guard)]]
3702 guard = cond;
3704 such that gimple lowering can outline the condition into
3705 a separate function easily. */
3706 tree guard = create_tmp_var (boolean_type_node);
3707 *expr_p = build2 (MODIFY_EXPR, void_type_node, guard,
3708 gimple_boolify (CALL_EXPR_ARG (*expr_p, 0)));
3709 *expr_p = build3 (BIND_EXPR, void_type_node, NULL, *expr_p, NULL);
3710 push_gimplify_context ();
3711 gimple_seq body = NULL;
3712 gimple *g = gimplify_and_return_first (*expr_p, &body);
3713 pop_gimplify_context (g);
3714 g = gimple_build_assume (guard, body);
3715 gimple_set_location (g, loc);
3716 gimplify_seq_add_stmt (pre_p, g);
3717 *expr_p = NULL_TREE;
3718 return GS_ALL_DONE;
3721 for (i = 0; i < nargs; i++)
3723 gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
3724 EXPR_LOCATION (*expr_p));
3725 vargs.quick_push (CALL_EXPR_ARG (*expr_p, i));
3728 gcall *call = gimple_build_call_internal_vec (ifn, vargs);
3729 gimple_call_set_nothrow (call, TREE_NOTHROW (*expr_p));
3730 gimplify_seq_add_stmt (pre_p, call);
3731 return GS_ALL_DONE;
3734 /* This may be a call to a builtin function.
3736 Builtin function calls may be transformed into different
3737 (and more efficient) builtin function calls under certain
3738 circumstances. Unfortunately, gimplification can muck things
3739 up enough that the builtin expanders are not aware that certain
3740 transformations are still valid.
3742 So we attempt transformation/gimplification of the call before
3743 we gimplify the CALL_EXPR. At this time we do not manage to
3744 transform all calls in the same manner as the expanders do, but
3745 we do transform most of them. */
3746 fndecl = get_callee_fndecl (*expr_p);
3747 if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
3748 switch (DECL_FUNCTION_CODE (fndecl))
3750 CASE_BUILT_IN_ALLOCA:
3751 /* If the call has been built for a variable-sized object, then we
3752 want to restore the stack level when the enclosing BIND_EXPR is
3753 exited to reclaim the allocated space; otherwise, we precisely
3754 need to do the opposite and preserve the latest stack level. */
3755 if (CALL_ALLOCA_FOR_VAR_P (*expr_p))
3756 gimplify_ctxp->save_stack = true;
3757 else
3758 gimplify_ctxp->keep_stack = true;
3759 break;
3761 case BUILT_IN_VA_START:
3763 builtin_va_start_p = true;
3764 if (call_expr_nargs (*expr_p) < 2)
3766 error ("too few arguments to function %<va_start%>");
3767 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
3768 return GS_OK;
3771 if (fold_builtin_next_arg (*expr_p, true))
3773 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
3774 return GS_OK;
3776 break;
3779 case BUILT_IN_EH_RETURN:
3780 cfun->calls_eh_return = true;
3781 break;
3783 case BUILT_IN_CLEAR_PADDING:
3784 if (call_expr_nargs (*expr_p) == 1)
3786 /* Remember the original type of the argument in an internal
3787 dummy second argument, as in GIMPLE pointer conversions are
3788 useless. Also mark this call as not for automatic
3789 initialization in the internal dummy third argument. */
3790 p = CALL_EXPR_ARG (*expr_p, 0);
3791 *expr_p
3792 = build_call_expr_loc (EXPR_LOCATION (*expr_p), fndecl, 2, p,
3793 build_zero_cst (TREE_TYPE (p)));
3794 return GS_OK;
3796 break;
3798 default:
3801 if (fndecl && fndecl_built_in_p (fndecl))
3803 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
3804 if (new_tree && new_tree != *expr_p)
3806 /* There was a transformation of this call which computes the
3807 same value, but in a more efficient way. Return and try
3808 again. */
3809 *expr_p = new_tree;
3810 return GS_OK;
3814 /* Remember the original function pointer type. */
3815 fnptrtype = TREE_TYPE (CALL_EXPR_FN (*expr_p));
3817 if (flag_openmp
3818 && fndecl
3819 && cfun
3820 && (cfun->curr_properties & PROP_gimple_any) == 0)
3822 tree variant = omp_resolve_declare_variant (fndecl);
3823 if (variant != fndecl)
3824 CALL_EXPR_FN (*expr_p) = build1 (ADDR_EXPR, fnptrtype, variant);
3827 /* There is a sequence point before the call, so any side effects in
3828 the calling expression must occur before the actual call. Force
3829 gimplify_expr to use an internal post queue. */
3830 ret = gimplify_expr (&CALL_EXPR_FN (*expr_p), pre_p, NULL,
3831 is_gimple_call_addr, fb_rvalue);
3833 if (ret == GS_ERROR)
3834 return GS_ERROR;
3836 nargs = call_expr_nargs (*expr_p);
3838 /* Get argument types for verification. */
3839 fndecl = get_callee_fndecl (*expr_p);
3840 parms = NULL_TREE;
3841 if (fndecl)
3842 parms = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
3843 else
3844 parms = TYPE_ARG_TYPES (TREE_TYPE (fnptrtype));
3846 if (fndecl && DECL_ARGUMENTS (fndecl))
3847 p = DECL_ARGUMENTS (fndecl);
3848 else if (parms)
3849 p = parms;
3850 else
3851 p = NULL_TREE;
3852 for (i = 0; i < nargs && p; i++, p = TREE_CHAIN (p))
3855 /* If the last argument is __builtin_va_arg_pack () and it is not
3856 passed as a named argument, decrease the number of CALL_EXPR
3857 arguments and set instead the CALL_EXPR_VA_ARG_PACK flag. */
3858 if (!p
3859 && i < nargs
3860 && TREE_CODE (CALL_EXPR_ARG (*expr_p, nargs - 1)) == CALL_EXPR)
3862 tree last_arg = CALL_EXPR_ARG (*expr_p, nargs - 1);
3863 tree last_arg_fndecl = get_callee_fndecl (last_arg);
3865 if (last_arg_fndecl
3866 && fndecl_built_in_p (last_arg_fndecl, BUILT_IN_VA_ARG_PACK))
3868 tree call = *expr_p;
3870 --nargs;
3871 *expr_p = build_call_array_loc (loc, TREE_TYPE (call),
3872 CALL_EXPR_FN (call),
3873 nargs, CALL_EXPR_ARGP (call));
3875 /* Copy all CALL_EXPR flags, location and block, except
3876 CALL_EXPR_VA_ARG_PACK flag. */
3877 CALL_EXPR_STATIC_CHAIN (*expr_p) = CALL_EXPR_STATIC_CHAIN (call);
3878 CALL_EXPR_TAILCALL (*expr_p) = CALL_EXPR_TAILCALL (call);
3879 CALL_EXPR_RETURN_SLOT_OPT (*expr_p)
3880 = CALL_EXPR_RETURN_SLOT_OPT (call);
3881 CALL_FROM_THUNK_P (*expr_p) = CALL_FROM_THUNK_P (call);
3882 SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (call));
3884 /* Set CALL_EXPR_VA_ARG_PACK. */
3885 CALL_EXPR_VA_ARG_PACK (*expr_p) = 1;
3889 /* If the call returns twice then after building the CFG the call
3890 argument computations will no longer dominate the call because
3891 we add an abnormal incoming edge to the call. So do not use SSA
3892 vars there. */
3893 bool returns_twice = call_expr_flags (*expr_p) & ECF_RETURNS_TWICE;
3895 /* Gimplify the function arguments. */
3896 if (nargs > 0)
3898 for (i = (PUSH_ARGS_REVERSED ? nargs - 1 : 0);
3899 PUSH_ARGS_REVERSED ? i >= 0 : i < nargs;
3900 PUSH_ARGS_REVERSED ? i-- : i++)
3902 enum gimplify_status t;
3904 /* Avoid gimplifying the second argument to va_start, which needs to
3905 be the plain PARM_DECL. */
3906 if ((i != 1) || !builtin_va_start_p)
3908 t = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
3909 EXPR_LOCATION (*expr_p), ! returns_twice);
3911 if (t == GS_ERROR)
3912 ret = GS_ERROR;
3917 /* Gimplify the static chain. */
3918 if (CALL_EXPR_STATIC_CHAIN (*expr_p))
3920 if (fndecl && !DECL_STATIC_CHAIN (fndecl))
3921 CALL_EXPR_STATIC_CHAIN (*expr_p) = NULL;
3922 else
3924 enum gimplify_status t;
3925 t = gimplify_arg (&CALL_EXPR_STATIC_CHAIN (*expr_p), pre_p,
3926 EXPR_LOCATION (*expr_p), ! returns_twice);
3927 if (t == GS_ERROR)
3928 ret = GS_ERROR;
3932 /* Verify the function result. */
3933 if (want_value && fndecl
3934 && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fnptrtype))))
3936 error_at (loc, "using result of function returning %<void%>");
3937 ret = GS_ERROR;
3940 /* Try this again in case gimplification exposed something. */
3941 if (ret != GS_ERROR)
3943 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
3945 if (new_tree && new_tree != *expr_p)
3947 /* There was a transformation of this call which computes the
3948 same value, but in a more efficient way. Return and try
3949 again. */
3950 *expr_p = new_tree;
3951 return GS_OK;
3954 else
3956 *expr_p = error_mark_node;
3957 return GS_ERROR;
3960 /* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its
3961 decl. This allows us to eliminate redundant or useless
3962 calls to "const" functions. */
3963 if (TREE_CODE (*expr_p) == CALL_EXPR)
3965 int flags = call_expr_flags (*expr_p);
3966 if (flags & (ECF_CONST | ECF_PURE)
3967 /* An infinite loop is considered a side effect. */
3968 && !(flags & (ECF_LOOPING_CONST_OR_PURE)))
3969 TREE_SIDE_EFFECTS (*expr_p) = 0;
3972 /* If the value is not needed by the caller, emit a new GIMPLE_CALL
3973 and clear *EXPR_P. Otherwise, leave *EXPR_P in its gimplified
3974 form and delegate the creation of a GIMPLE_CALL to
3975 gimplify_modify_expr. This is always possible because when
3976 WANT_VALUE is true, the caller wants the result of this call into
3977 a temporary, which means that we will emit an INIT_EXPR in
3978 internal_get_tmp_var which will then be handled by
3979 gimplify_modify_expr. */
3980 if (!want_value)
3982 /* The CALL_EXPR in *EXPR_P is already in GIMPLE form, so all we
3983 have to do is replicate it as a GIMPLE_CALL tuple. */
3984 gimple_stmt_iterator gsi;
3985 call = gimple_build_call_from_tree (*expr_p, fnptrtype);
3986 notice_special_calls (call);
3987 gimplify_seq_add_stmt (pre_p, call);
3988 gsi = gsi_last (*pre_p);
3989 maybe_fold_stmt (&gsi);
3990 *expr_p = NULL_TREE;
3992 else
3993 /* Remember the original function type. */
3994 CALL_EXPR_FN (*expr_p) = build1 (NOP_EXPR, fnptrtype,
3995 CALL_EXPR_FN (*expr_p));
3997 return ret;
4000 /* Handle shortcut semantics in the predicate operand of a COND_EXPR by
4001 rewriting it into multiple COND_EXPRs, and possibly GOTO_EXPRs.
4003 TRUE_LABEL_P and FALSE_LABEL_P point to the labels to jump to if the
4004 condition is true or false, respectively. If null, we should generate
4005 our own to skip over the evaluation of this specific expression.
4007 LOCUS is the source location of the COND_EXPR.
4009 This function is the tree equivalent of do_jump.
4011 shortcut_cond_r should only be called by shortcut_cond_expr. */
4013 static tree
4014 shortcut_cond_r (tree pred, tree *true_label_p, tree *false_label_p,
4015 location_t locus)
4017 tree local_label = NULL_TREE;
4018 tree t, expr = NULL;
4020 /* OK, it's not a simple case; we need to pull apart the COND_EXPR to
4021 retain the shortcut semantics. Just insert the gotos here;
4022 shortcut_cond_expr will append the real blocks later. */
4023 if (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
4025 location_t new_locus;
4027 /* Turn if (a && b) into
4029 if (a); else goto no;
4030 if (b) goto yes; else goto no;
4031 (no:) */
4033 if (false_label_p == NULL)
4034 false_label_p = &local_label;
4036 /* Keep the original source location on the first 'if'. */
4037 t = shortcut_cond_r (TREE_OPERAND (pred, 0), NULL, false_label_p, locus);
4038 append_to_statement_list (t, &expr);
4040 /* Set the source location of the && on the second 'if'. */
4041 new_locus = rexpr_location (pred, locus);
4042 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
4043 new_locus);
4044 append_to_statement_list (t, &expr);
4046 else if (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
4048 location_t new_locus;
4050 /* Turn if (a || b) into
4052 if (a) goto yes;
4053 if (b) goto yes; else goto no;
4054 (yes:) */
4056 if (true_label_p == NULL)
4057 true_label_p = &local_label;
4059 /* Keep the original source location on the first 'if'. */
4060 t = shortcut_cond_r (TREE_OPERAND (pred, 0), true_label_p, NULL, locus);
4061 append_to_statement_list (t, &expr);
4063 /* Set the source location of the || on the second 'if'. */
4064 new_locus = rexpr_location (pred, locus);
4065 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
4066 new_locus);
4067 append_to_statement_list (t, &expr);
4069 else if (TREE_CODE (pred) == COND_EXPR
4070 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 1)))
4071 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 2))))
4073 location_t new_locus;
4075 /* As long as we're messing with gotos, turn if (a ? b : c) into
4076 if (a)
4077 if (b) goto yes; else goto no;
4078 else
4079 if (c) goto yes; else goto no;
4081 Don't do this if one of the arms has void type, which can happen
4082 in C++ when the arm is throw. */
4084 /* Keep the original source location on the first 'if'. Set the source
4085 location of the ? on the second 'if'. */
4086 new_locus = rexpr_location (pred, locus);
4087 expr = build3 (COND_EXPR, void_type_node, TREE_OPERAND (pred, 0),
4088 shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p,
4089 false_label_p, locus),
4090 shortcut_cond_r (TREE_OPERAND (pred, 2), true_label_p,
4091 false_label_p, new_locus));
4093 else
4095 expr = build3 (COND_EXPR, void_type_node, pred,
4096 build_and_jump (true_label_p),
4097 build_and_jump (false_label_p));
4098 SET_EXPR_LOCATION (expr, locus);
4101 if (local_label)
4103 t = build1 (LABEL_EXPR, void_type_node, local_label);
4104 append_to_statement_list (t, &expr);
4107 return expr;
4110 /* If EXPR is a GOTO_EXPR, return it. If it is a STATEMENT_LIST, skip
4111 any of its leading DEBUG_BEGIN_STMTS and recurse on the subsequent
4112 statement, if it is the last one. Otherwise, return NULL. */
4114 static tree
4115 find_goto (tree expr)
4117 if (!expr)
4118 return NULL_TREE;
4120 if (TREE_CODE (expr) == GOTO_EXPR)
4121 return expr;
4123 if (TREE_CODE (expr) != STATEMENT_LIST)
4124 return NULL_TREE;
4126 tree_stmt_iterator i = tsi_start (expr);
4128 while (!tsi_end_p (i) && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT)
4129 tsi_next (&i);
4131 if (!tsi_one_before_end_p (i))
4132 return NULL_TREE;
4134 return find_goto (tsi_stmt (i));
4137 /* Same as find_goto, except that it returns NULL if the destination
4138 is not a LABEL_DECL. */
4140 static inline tree
4141 find_goto_label (tree expr)
4143 tree dest = find_goto (expr);
4144 if (dest && TREE_CODE (GOTO_DESTINATION (dest)) == LABEL_DECL)
4145 return dest;
4146 return NULL_TREE;
4149 /* Given a conditional expression EXPR with short-circuit boolean
4150 predicates using TRUTH_ANDIF_EXPR or TRUTH_ORIF_EXPR, break the
4151 predicate apart into the equivalent sequence of conditionals. */
4153 static tree
4154 shortcut_cond_expr (tree expr)
4156 tree pred = TREE_OPERAND (expr, 0);
4157 tree then_ = TREE_OPERAND (expr, 1);
4158 tree else_ = TREE_OPERAND (expr, 2);
4159 tree true_label, false_label, end_label, t;
4160 tree *true_label_p;
4161 tree *false_label_p;
4162 bool emit_end, emit_false, jump_over_else;
4163 bool then_se = then_ && TREE_SIDE_EFFECTS (then_);
4164 bool else_se = else_ && TREE_SIDE_EFFECTS (else_);
4166 /* First do simple transformations. */
4167 if (!else_se)
4169 /* If there is no 'else', turn
4170 if (a && b) then c
4171 into
4172 if (a) if (b) then c. */
4173 while (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
4175 /* Keep the original source location on the first 'if'. */
4176 location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
4177 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
4178 /* Set the source location of the && on the second 'if'. */
4179 if (rexpr_has_location (pred))
4180 SET_EXPR_LOCATION (expr, rexpr_location (pred));
4181 then_ = shortcut_cond_expr (expr);
4182 then_se = then_ && TREE_SIDE_EFFECTS (then_);
4183 pred = TREE_OPERAND (pred, 0);
4184 expr = build3 (COND_EXPR, void_type_node, pred, then_, NULL_TREE);
4185 SET_EXPR_LOCATION (expr, locus);
4189 if (!then_se)
4191 /* If there is no 'then', turn
4192 if (a || b); else d
4193 into
4194 if (a); else if (b); else d. */
4195 while (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
4197 /* Keep the original source location on the first 'if'. */
4198 location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
4199 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
4200 /* Set the source location of the || on the second 'if'. */
4201 if (rexpr_has_location (pred))
4202 SET_EXPR_LOCATION (expr, rexpr_location (pred));
4203 else_ = shortcut_cond_expr (expr);
4204 else_se = else_ && TREE_SIDE_EFFECTS (else_);
4205 pred = TREE_OPERAND (pred, 0);
4206 expr = build3 (COND_EXPR, void_type_node, pred, NULL_TREE, else_);
4207 SET_EXPR_LOCATION (expr, locus);
4211 /* If we're done, great. */
4212 if (TREE_CODE (pred) != TRUTH_ANDIF_EXPR
4213 && TREE_CODE (pred) != TRUTH_ORIF_EXPR)
4214 return expr;
4216 /* Otherwise we need to mess with gotos. Change
4217 if (a) c; else d;
4219 if (a); else goto no;
4220 c; goto end;
4221 no: d; end:
4222 and recursively gimplify the condition. */
4224 true_label = false_label = end_label = NULL_TREE;
4226 /* If our arms just jump somewhere, hijack those labels so we don't
4227 generate jumps to jumps. */
4229 if (tree then_goto = find_goto_label (then_))
4231 true_label = GOTO_DESTINATION (then_goto);
4232 then_ = NULL;
4233 then_se = false;
4236 if (tree else_goto = find_goto_label (else_))
4238 false_label = GOTO_DESTINATION (else_goto);
4239 else_ = NULL;
4240 else_se = false;
4243 /* If we aren't hijacking a label for the 'then' branch, it falls through. */
4244 if (true_label)
4245 true_label_p = &true_label;
4246 else
4247 true_label_p = NULL;
4249 /* The 'else' branch also needs a label if it contains interesting code. */
4250 if (false_label || else_se)
4251 false_label_p = &false_label;
4252 else
4253 false_label_p = NULL;
4255 /* If there was nothing else in our arms, just forward the label(s). */
4256 if (!then_se && !else_se)
4257 return shortcut_cond_r (pred, true_label_p, false_label_p,
4258 EXPR_LOC_OR_LOC (expr, input_location));
4260 /* If our last subexpression already has a terminal label, reuse it. */
4261 if (else_se)
4262 t = expr_last (else_);
4263 else if (then_se)
4264 t = expr_last (then_);
4265 else
4266 t = NULL;
4267 if (t && TREE_CODE (t) == LABEL_EXPR)
4268 end_label = LABEL_EXPR_LABEL (t);
4270 /* If we don't care about jumping to the 'else' branch, jump to the end
4271 if the condition is false. */
4272 if (!false_label_p)
4273 false_label_p = &end_label;
4275 /* We only want to emit these labels if we aren't hijacking them. */
4276 emit_end = (end_label == NULL_TREE);
4277 emit_false = (false_label == NULL_TREE);
4279 /* We only emit the jump over the else clause if we have to--if the
4280 then clause may fall through. Otherwise we can wind up with a
4281 useless jump and a useless label at the end of gimplified code,
4282 which will cause us to think that this conditional as a whole
4283 falls through even if it doesn't. If we then inline a function
4284 which ends with such a condition, that can cause us to issue an
4285 inappropriate warning about control reaching the end of a
4286 non-void function. */
4287 jump_over_else = block_may_fallthru (then_);
4289 pred = shortcut_cond_r (pred, true_label_p, false_label_p,
4290 EXPR_LOC_OR_LOC (expr, input_location));
4292 expr = NULL;
4293 append_to_statement_list (pred, &expr);
4295 append_to_statement_list (then_, &expr);
4296 if (else_se)
4298 if (jump_over_else)
4300 tree last = expr_last (expr);
4301 t = build_and_jump (&end_label);
4302 if (rexpr_has_location (last))
4303 SET_EXPR_LOCATION (t, rexpr_location (last));
4304 append_to_statement_list (t, &expr);
4306 if (emit_false)
4308 t = build1 (LABEL_EXPR, void_type_node, false_label);
4309 append_to_statement_list (t, &expr);
4311 append_to_statement_list (else_, &expr);
4313 if (emit_end && end_label)
4315 t = build1 (LABEL_EXPR, void_type_node, end_label);
4316 append_to_statement_list (t, &expr);
4319 return expr;
4322 /* EXPR is used in a boolean context; make sure it has BOOLEAN_TYPE. */
4324 tree
4325 gimple_boolify (tree expr)
4327 tree type = TREE_TYPE (expr);
4328 location_t loc = EXPR_LOCATION (expr);
4330 if (TREE_CODE (expr) == NE_EXPR
4331 && TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR
4332 && integer_zerop (TREE_OPERAND (expr, 1)))
4334 tree call = TREE_OPERAND (expr, 0);
4335 tree fn = get_callee_fndecl (call);
4337 /* For __builtin_expect ((long) (x), y) recurse into x as well
4338 if x is truth_value_p. */
4339 if (fn
4340 && fndecl_built_in_p (fn, BUILT_IN_EXPECT)
4341 && call_expr_nargs (call) == 2)
4343 tree arg = CALL_EXPR_ARG (call, 0);
4344 if (arg)
4346 if (TREE_CODE (arg) == NOP_EXPR
4347 && TREE_TYPE (arg) == TREE_TYPE (call))
4348 arg = TREE_OPERAND (arg, 0);
4349 if (truth_value_p (TREE_CODE (arg)))
4351 arg = gimple_boolify (arg);
4352 CALL_EXPR_ARG (call, 0)
4353 = fold_convert_loc (loc, TREE_TYPE (call), arg);
4359 switch (TREE_CODE (expr))
4361 case TRUTH_AND_EXPR:
4362 case TRUTH_OR_EXPR:
4363 case TRUTH_XOR_EXPR:
4364 case TRUTH_ANDIF_EXPR:
4365 case TRUTH_ORIF_EXPR:
4366 /* Also boolify the arguments of truth exprs. */
4367 TREE_OPERAND (expr, 1) = gimple_boolify (TREE_OPERAND (expr, 1));
4368 /* FALLTHRU */
4370 case TRUTH_NOT_EXPR:
4371 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
4373 /* These expressions always produce boolean results. */
4374 if (TREE_CODE (type) != BOOLEAN_TYPE)
4375 TREE_TYPE (expr) = boolean_type_node;
4376 return expr;
4378 case ANNOTATE_EXPR:
4379 switch ((enum annot_expr_kind) TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)))
4381 case annot_expr_ivdep_kind:
4382 case annot_expr_unroll_kind:
4383 case annot_expr_no_vector_kind:
4384 case annot_expr_vector_kind:
4385 case annot_expr_parallel_kind:
4386 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
4387 if (TREE_CODE (type) != BOOLEAN_TYPE)
4388 TREE_TYPE (expr) = boolean_type_node;
4389 return expr;
4390 default:
4391 gcc_unreachable ();
4394 default:
4395 if (COMPARISON_CLASS_P (expr))
4397 /* These expressions always produce boolean results. */
4398 if (TREE_CODE (type) != BOOLEAN_TYPE)
4399 TREE_TYPE (expr) = boolean_type_node;
4400 return expr;
4402 /* Other expressions that get here must have boolean values, but
4403 might need to be converted to the appropriate mode. */
4404 if (TREE_CODE (type) == BOOLEAN_TYPE)
4405 return expr;
4406 return fold_convert_loc (loc, boolean_type_node, expr);
4410 /* Given a conditional expression *EXPR_P without side effects, gimplify
4411 its operands. New statements are inserted to PRE_P. */
4413 static enum gimplify_status
4414 gimplify_pure_cond_expr (tree *expr_p, gimple_seq *pre_p)
4416 tree expr = *expr_p, cond;
4417 enum gimplify_status ret, tret;
4418 enum tree_code code;
4420 cond = gimple_boolify (COND_EXPR_COND (expr));
4422 /* We need to handle && and || specially, as their gimplification
4423 creates pure cond_expr, thus leading to an infinite cycle otherwise. */
4424 code = TREE_CODE (cond);
4425 if (code == TRUTH_ANDIF_EXPR)
4426 TREE_SET_CODE (cond, TRUTH_AND_EXPR);
4427 else if (code == TRUTH_ORIF_EXPR)
4428 TREE_SET_CODE (cond, TRUTH_OR_EXPR);
4429 ret = gimplify_expr (&cond, pre_p, NULL, is_gimple_val, fb_rvalue);
4430 COND_EXPR_COND (*expr_p) = cond;
4432 tret = gimplify_expr (&COND_EXPR_THEN (expr), pre_p, NULL,
4433 is_gimple_val, fb_rvalue);
4434 ret = MIN (ret, tret);
4435 tret = gimplify_expr (&COND_EXPR_ELSE (expr), pre_p, NULL,
4436 is_gimple_val, fb_rvalue);
4438 return MIN (ret, tret);
4441 /* Return true if evaluating EXPR could trap.
4442 EXPR is GENERIC, while tree_could_trap_p can be called
4443 only on GIMPLE. */
4445 bool
4446 generic_expr_could_trap_p (tree expr)
4448 unsigned i, n;
4450 if (!expr || is_gimple_val (expr))
4451 return false;
4453 if (!EXPR_P (expr) || tree_could_trap_p (expr))
4454 return true;
4456 n = TREE_OPERAND_LENGTH (expr);
4457 for (i = 0; i < n; i++)
4458 if (generic_expr_could_trap_p (TREE_OPERAND (expr, i)))
4459 return true;
4461 return false;
4464 /* Convert the conditional expression pointed to by EXPR_P '(p) ? a : b;'
4465 into
4467 if (p) if (p)
4468 t1 = a; a;
4469 else or else
4470 t1 = b; b;
4473 The second form is used when *EXPR_P is of type void.
4475 PRE_P points to the list where side effects that must happen before
4476 *EXPR_P should be stored. */
4478 static enum gimplify_status
4479 gimplify_cond_expr (tree *expr_p, gimple_seq *pre_p, fallback_t fallback)
4481 tree expr = *expr_p;
4482 tree type = TREE_TYPE (expr);
4483 location_t loc = EXPR_LOCATION (expr);
4484 tree tmp, arm1, arm2;
4485 enum gimplify_status ret;
4486 tree label_true, label_false, label_cont;
4487 bool have_then_clause_p, have_else_clause_p;
4488 gcond *cond_stmt;
4489 enum tree_code pred_code;
4490 gimple_seq seq = NULL;
4492 /* If this COND_EXPR has a value, copy the values into a temporary within
4493 the arms. */
4494 if (!VOID_TYPE_P (type))
4496 tree then_ = TREE_OPERAND (expr, 1), else_ = TREE_OPERAND (expr, 2);
4497 tree result;
4499 /* If either an rvalue is ok or we do not require an lvalue, create the
4500 temporary. But we cannot do that if the type is addressable. */
4501 if (((fallback & fb_rvalue) || !(fallback & fb_lvalue))
4502 && !TREE_ADDRESSABLE (type))
4504 if (gimplify_ctxp->allow_rhs_cond_expr
4505 /* If either branch has side effects or could trap, it can't be
4506 evaluated unconditionally. */
4507 && !TREE_SIDE_EFFECTS (then_)
4508 && !generic_expr_could_trap_p (then_)
4509 && !TREE_SIDE_EFFECTS (else_)
4510 && !generic_expr_could_trap_p (else_))
4511 return gimplify_pure_cond_expr (expr_p, pre_p);
4513 tmp = create_tmp_var (type, "iftmp");
4514 result = tmp;
4517 /* Otherwise, only create and copy references to the values. */
4518 else
4520 type = build_pointer_type (type);
4522 if (!VOID_TYPE_P (TREE_TYPE (then_)))
4523 then_ = build_fold_addr_expr_loc (loc, then_);
4525 if (!VOID_TYPE_P (TREE_TYPE (else_)))
4526 else_ = build_fold_addr_expr_loc (loc, else_);
4528 expr
4529 = build3 (COND_EXPR, type, TREE_OPERAND (expr, 0), then_, else_);
4531 tmp = create_tmp_var (type, "iftmp");
4532 result = build_simple_mem_ref_loc (loc, tmp);
4535 /* Build the new then clause, `tmp = then_;'. But don't build the
4536 assignment if the value is void; in C++ it can be if it's a throw. */
4537 if (!VOID_TYPE_P (TREE_TYPE (then_)))
4538 TREE_OPERAND (expr, 1) = build2 (INIT_EXPR, type, tmp, then_);
4540 /* Similarly, build the new else clause, `tmp = else_;'. */
4541 if (!VOID_TYPE_P (TREE_TYPE (else_)))
4542 TREE_OPERAND (expr, 2) = build2 (INIT_EXPR, type, tmp, else_);
4544 TREE_TYPE (expr) = void_type_node;
4545 recalculate_side_effects (expr);
4547 /* Move the COND_EXPR to the prequeue. */
4548 gimplify_stmt (&expr, pre_p);
4550 *expr_p = result;
4551 return GS_ALL_DONE;
4554 /* Remove any COMPOUND_EXPR so the following cases will be caught. */
4555 STRIP_TYPE_NOPS (TREE_OPERAND (expr, 0));
4556 if (TREE_CODE (TREE_OPERAND (expr, 0)) == COMPOUND_EXPR)
4557 gimplify_compound_expr (&TREE_OPERAND (expr, 0), pre_p, true);
4559 /* Make sure the condition has BOOLEAN_TYPE. */
4560 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
4562 /* Break apart && and || conditions. */
4563 if (TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ANDIF_EXPR
4564 || TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ORIF_EXPR)
4566 expr = shortcut_cond_expr (expr);
4568 if (expr != *expr_p)
4570 *expr_p = expr;
4572 /* We can't rely on gimplify_expr to re-gimplify the expanded
4573 form properly, as cleanups might cause the target labels to be
4574 wrapped in a TRY_FINALLY_EXPR. To prevent that, we need to
4575 set up a conditional context. */
4576 gimple_push_condition ();
4577 gimplify_stmt (expr_p, &seq);
4578 gimple_pop_condition (pre_p);
4579 gimple_seq_add_seq (pre_p, seq);
4581 return GS_ALL_DONE;
4585 /* Now do the normal gimplification. */
4587 /* Gimplify condition. */
4588 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL,
4589 is_gimple_condexpr_for_cond, fb_rvalue);
4590 if (ret == GS_ERROR)
4591 return GS_ERROR;
4592 gcc_assert (TREE_OPERAND (expr, 0) != NULL_TREE);
4594 gimple_push_condition ();
4596 have_then_clause_p = have_else_clause_p = false;
4597 label_true = find_goto_label (TREE_OPERAND (expr, 1));
4598 if (label_true
4599 && DECL_CONTEXT (GOTO_DESTINATION (label_true)) == current_function_decl
4600 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4601 have different locations, otherwise we end up with incorrect
4602 location information on the branches. */
4603 && (optimize
4604 || !EXPR_HAS_LOCATION (expr)
4605 || !rexpr_has_location (label_true)
4606 || EXPR_LOCATION (expr) == rexpr_location (label_true)))
4608 have_then_clause_p = true;
4609 label_true = GOTO_DESTINATION (label_true);
4611 else
4612 label_true = create_artificial_label (UNKNOWN_LOCATION);
4613 label_false = find_goto_label (TREE_OPERAND (expr, 2));
4614 if (label_false
4615 && DECL_CONTEXT (GOTO_DESTINATION (label_false)) == current_function_decl
4616 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4617 have different locations, otherwise we end up with incorrect
4618 location information on the branches. */
4619 && (optimize
4620 || !EXPR_HAS_LOCATION (expr)
4621 || !rexpr_has_location (label_false)
4622 || EXPR_LOCATION (expr) == rexpr_location (label_false)))
4624 have_else_clause_p = true;
4625 label_false = GOTO_DESTINATION (label_false);
4627 else
4628 label_false = create_artificial_label (UNKNOWN_LOCATION);
4630 gimple_cond_get_ops_from_tree (COND_EXPR_COND (expr), &pred_code, &arm1,
4631 &arm2);
4632 cond_stmt = gimple_build_cond (pred_code, arm1, arm2, label_true,
4633 label_false);
4634 gimple_set_location (cond_stmt, EXPR_LOCATION (expr));
4635 copy_warning (cond_stmt, COND_EXPR_COND (expr));
4636 gimplify_seq_add_stmt (&seq, cond_stmt);
4637 gimple_stmt_iterator gsi = gsi_last (seq);
4638 maybe_fold_stmt (&gsi);
4640 label_cont = NULL_TREE;
4641 if (!have_then_clause_p)
4643 /* For if (...) {} else { code; } put label_true after
4644 the else block. */
4645 if (TREE_OPERAND (expr, 1) == NULL_TREE
4646 && !have_else_clause_p
4647 && TREE_OPERAND (expr, 2) != NULL_TREE)
4649 /* For if (0) {} else { code; } tell -Wimplicit-fallthrough
4650 handling that label_cont == label_true can be only reached
4651 through fallthrough from { code; }. */
4652 if (integer_zerop (COND_EXPR_COND (expr)))
4653 UNUSED_LABEL_P (label_true) = 1;
4654 label_cont = label_true;
4656 else
4658 bool then_side_effects
4659 = (TREE_OPERAND (expr, 1)
4660 && TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)));
4661 gimplify_seq_add_stmt (&seq, gimple_build_label (label_true));
4662 have_then_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 1), &seq);
4663 /* For if (...) { code; } else {} or
4664 if (...) { code; } else goto label; or
4665 if (...) { code; return; } else { ... }
4666 label_cont isn't needed. */
4667 if (!have_else_clause_p
4668 && TREE_OPERAND (expr, 2) != NULL_TREE
4669 && gimple_seq_may_fallthru (seq))
4671 gimple *g;
4672 label_cont = create_artificial_label (UNKNOWN_LOCATION);
4674 /* For if (0) { non-side-effect-code } else { code }
4675 tell -Wimplicit-fallthrough handling that label_cont can
4676 be only reached through fallthrough from { code }. */
4677 if (integer_zerop (COND_EXPR_COND (expr)))
4679 UNUSED_LABEL_P (label_true) = 1;
4680 if (!then_side_effects)
4681 UNUSED_LABEL_P (label_cont) = 1;
4684 g = gimple_build_goto (label_cont);
4686 /* GIMPLE_COND's are very low level; they have embedded
4687 gotos. This particular embedded goto should not be marked
4688 with the location of the original COND_EXPR, as it would
4689 correspond to the COND_EXPR's condition, not the ELSE or the
4690 THEN arms. To avoid marking it with the wrong location, flag
4691 it as "no location". */
4692 gimple_set_do_not_emit_location (g);
4694 gimplify_seq_add_stmt (&seq, g);
4698 if (!have_else_clause_p)
4700 /* For if (1) { code } or if (1) { code } else { non-side-effect-code }
4701 tell -Wimplicit-fallthrough handling that label_false can be only
4702 reached through fallthrough from { code }. */
4703 if (integer_nonzerop (COND_EXPR_COND (expr))
4704 && (TREE_OPERAND (expr, 2) == NULL_TREE
4705 || !TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 2))))
4706 UNUSED_LABEL_P (label_false) = 1;
4707 gimplify_seq_add_stmt (&seq, gimple_build_label (label_false));
4708 have_else_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 2), &seq);
4710 if (label_cont)
4711 gimplify_seq_add_stmt (&seq, gimple_build_label (label_cont));
4713 gimple_pop_condition (pre_p);
4714 gimple_seq_add_seq (pre_p, seq);
4716 if (ret == GS_ERROR)
4717 ; /* Do nothing. */
4718 else if (have_then_clause_p || have_else_clause_p)
4719 ret = GS_ALL_DONE;
4720 else
4722 /* Both arms are empty; replace the COND_EXPR with its predicate. */
4723 expr = TREE_OPERAND (expr, 0);
4724 gimplify_stmt (&expr, pre_p);
4727 *expr_p = NULL;
4728 return ret;
4731 /* Prepare the node pointed to by EXPR_P, an is_gimple_addressable expression,
4732 to be marked addressable.
4734 We cannot rely on such an expression being directly markable if a temporary
4735 has been created by the gimplification. In this case, we create another
4736 temporary and initialize it with a copy, which will become a store after we
4737 mark it addressable. This can happen if the front-end passed us something
4738 that it could not mark addressable yet, like a Fortran pass-by-reference
4739 parameter (int) floatvar. */
4741 static void
4742 prepare_gimple_addressable (tree *expr_p, gimple_seq *seq_p)
4744 while (handled_component_p (*expr_p))
4745 expr_p = &TREE_OPERAND (*expr_p, 0);
4747 /* Do not allow an SSA name as the temporary. */
4748 if (is_gimple_reg (*expr_p))
4749 *expr_p = internal_get_tmp_var (*expr_p, seq_p, NULL, false, false, true);
4752 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4753 a call to __builtin_memcpy. */
4755 static enum gimplify_status
4756 gimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value,
4757 gimple_seq *seq_p)
4759 tree t, to, to_ptr, from, from_ptr;
4760 gcall *gs;
4761 location_t loc = EXPR_LOCATION (*expr_p);
4763 to = TREE_OPERAND (*expr_p, 0);
4764 from = TREE_OPERAND (*expr_p, 1);
4766 /* Mark the RHS addressable. Beware that it may not be possible to do so
4767 directly if a temporary has been created by the gimplification. */
4768 prepare_gimple_addressable (&from, seq_p);
4770 mark_addressable (from);
4771 from_ptr = build_fold_addr_expr_loc (loc, from);
4772 gimplify_arg (&from_ptr, seq_p, loc);
4774 mark_addressable (to);
4775 to_ptr = build_fold_addr_expr_loc (loc, to);
4776 gimplify_arg (&to_ptr, seq_p, loc);
4778 t = builtin_decl_implicit (BUILT_IN_MEMCPY);
4780 gs = gimple_build_call (t, 3, to_ptr, from_ptr, size);
4781 gimple_call_set_alloca_for_var (gs, true);
4783 if (want_value)
4785 /* tmp = memcpy() */
4786 t = create_tmp_var (TREE_TYPE (to_ptr));
4787 gimple_call_set_lhs (gs, t);
4788 gimplify_seq_add_stmt (seq_p, gs);
4790 *expr_p = build_simple_mem_ref (t);
4791 return GS_ALL_DONE;
4794 gimplify_seq_add_stmt (seq_p, gs);
4795 *expr_p = NULL;
4796 return GS_ALL_DONE;
4799 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4800 a call to __builtin_memset. In this case we know that the RHS is
4801 a CONSTRUCTOR with an empty element list. */
4803 static enum gimplify_status
4804 gimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value,
4805 gimple_seq *seq_p)
4807 tree t, from, to, to_ptr;
4808 gcall *gs;
4809 location_t loc = EXPR_LOCATION (*expr_p);
4811 /* Assert our assumptions, to abort instead of producing wrong code
4812 silently if they are not met. Beware that the RHS CONSTRUCTOR might
4813 not be immediately exposed. */
4814 from = TREE_OPERAND (*expr_p, 1);
4815 if (TREE_CODE (from) == WITH_SIZE_EXPR)
4816 from = TREE_OPERAND (from, 0);
4818 gcc_assert (TREE_CODE (from) == CONSTRUCTOR
4819 && vec_safe_is_empty (CONSTRUCTOR_ELTS (from)));
4821 /* Now proceed. */
4822 to = TREE_OPERAND (*expr_p, 0);
4824 to_ptr = build_fold_addr_expr_loc (loc, to);
4825 gimplify_arg (&to_ptr, seq_p, loc);
4826 t = builtin_decl_implicit (BUILT_IN_MEMSET);
4828 gs = gimple_build_call (t, 3, to_ptr, integer_zero_node, size);
4830 if (want_value)
4832 /* tmp = memset() */
4833 t = create_tmp_var (TREE_TYPE (to_ptr));
4834 gimple_call_set_lhs (gs, t);
4835 gimplify_seq_add_stmt (seq_p, gs);
4837 *expr_p = build1 (INDIRECT_REF, TREE_TYPE (to), t);
4838 return GS_ALL_DONE;
4841 gimplify_seq_add_stmt (seq_p, gs);
4842 *expr_p = NULL;
4843 return GS_ALL_DONE;
4846 /* A subroutine of gimplify_init_ctor_preeval. Called via walk_tree,
4847 determine, cautiously, if a CONSTRUCTOR overlaps the lhs of an
4848 assignment. Return non-null if we detect a potential overlap. */
4850 struct gimplify_init_ctor_preeval_data
4852 /* The base decl of the lhs object. May be NULL, in which case we
4853 have to assume the lhs is indirect. */
4854 tree lhs_base_decl;
4856 /* The alias set of the lhs object. */
4857 alias_set_type lhs_alias_set;
4860 static tree
4861 gimplify_init_ctor_preeval_1 (tree *tp, int *walk_subtrees, void *xdata)
4863 struct gimplify_init_ctor_preeval_data *data
4864 = (struct gimplify_init_ctor_preeval_data *) xdata;
4865 tree t = *tp;
4867 /* If we find the base object, obviously we have overlap. */
4868 if (data->lhs_base_decl == t)
4869 return t;
4871 /* If the constructor component is indirect, determine if we have a
4872 potential overlap with the lhs. The only bits of information we
4873 have to go on at this point are addressability and alias sets. */
4874 if ((INDIRECT_REF_P (t)
4875 || TREE_CODE (t) == MEM_REF)
4876 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
4877 && alias_sets_conflict_p (data->lhs_alias_set, get_alias_set (t)))
4878 return t;
4880 /* If the constructor component is a call, determine if it can hide a
4881 potential overlap with the lhs through an INDIRECT_REF like above.
4882 ??? Ugh - this is completely broken. In fact this whole analysis
4883 doesn't look conservative. */
4884 if (TREE_CODE (t) == CALL_EXPR)
4886 tree type, fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (t)));
4888 for (type = TYPE_ARG_TYPES (fntype); type; type = TREE_CHAIN (type))
4889 if (POINTER_TYPE_P (TREE_VALUE (type))
4890 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
4891 && alias_sets_conflict_p (data->lhs_alias_set,
4892 get_alias_set
4893 (TREE_TYPE (TREE_VALUE (type)))))
4894 return t;
4897 if (IS_TYPE_OR_DECL_P (t))
4898 *walk_subtrees = 0;
4899 return NULL;
4902 /* A subroutine of gimplify_init_constructor. Pre-evaluate EXPR,
4903 force values that overlap with the lhs (as described by *DATA)
4904 into temporaries. */
4906 static void
4907 gimplify_init_ctor_preeval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
4908 struct gimplify_init_ctor_preeval_data *data)
4910 enum gimplify_status one;
4912 /* If the value is constant, then there's nothing to pre-evaluate. */
4913 if (TREE_CONSTANT (*expr_p))
4915 /* Ensure it does not have side effects, it might contain a reference to
4916 the object we're initializing. */
4917 gcc_assert (!TREE_SIDE_EFFECTS (*expr_p));
4918 return;
4921 /* If the type has non-trivial constructors, we can't pre-evaluate. */
4922 if (TREE_ADDRESSABLE (TREE_TYPE (*expr_p)))
4923 return;
4925 /* Recurse for nested constructors. */
4926 if (TREE_CODE (*expr_p) == CONSTRUCTOR)
4928 unsigned HOST_WIDE_INT ix;
4929 constructor_elt *ce;
4930 vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (*expr_p);
4932 FOR_EACH_VEC_SAFE_ELT (v, ix, ce)
4933 gimplify_init_ctor_preeval (&ce->value, pre_p, post_p, data);
4935 return;
4938 /* If this is a variable sized type, we must remember the size. */
4939 maybe_with_size_expr (expr_p);
4941 /* Gimplify the constructor element to something appropriate for the rhs
4942 of a MODIFY_EXPR. Given that we know the LHS is an aggregate, we know
4943 the gimplifier will consider this a store to memory. Doing this
4944 gimplification now means that we won't have to deal with complicated
4945 language-specific trees, nor trees like SAVE_EXPR that can induce
4946 exponential search behavior. */
4947 one = gimplify_expr (expr_p, pre_p, post_p, is_gimple_mem_rhs, fb_rvalue);
4948 if (one == GS_ERROR)
4950 *expr_p = NULL;
4951 return;
4954 /* If we gimplified to a bare decl, we can be sure that it doesn't overlap
4955 with the lhs, since "a = { .x=a }" doesn't make sense. This will
4956 always be true for all scalars, since is_gimple_mem_rhs insists on a
4957 temporary variable for them. */
4958 if (DECL_P (*expr_p))
4959 return;
4961 /* If this is of variable size, we have no choice but to assume it doesn't
4962 overlap since we can't make a temporary for it. */
4963 if (TREE_CODE (TYPE_SIZE (TREE_TYPE (*expr_p))) != INTEGER_CST)
4964 return;
4966 /* Otherwise, we must search for overlap ... */
4967 if (!walk_tree (expr_p, gimplify_init_ctor_preeval_1, data, NULL))
4968 return;
4970 /* ... and if found, force the value into a temporary. */
4971 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
4974 /* A subroutine of gimplify_init_ctor_eval. Create a loop for
4975 a RANGE_EXPR in a CONSTRUCTOR for an array.
4977 var = lower;
4978 loop_entry:
4979 object[var] = value;
4980 if (var == upper)
4981 goto loop_exit;
4982 var = var + 1;
4983 goto loop_entry;
4984 loop_exit:
4986 We increment var _after_ the loop exit check because we might otherwise
4987 fail if upper == TYPE_MAX_VALUE (type for upper).
4989 Note that we never have to deal with SAVE_EXPRs here, because this has
4990 already been taken care of for us, in gimplify_init_ctor_preeval(). */
4992 static void gimplify_init_ctor_eval (tree, vec<constructor_elt, va_gc> *,
4993 gimple_seq *, bool);
4995 static void
4996 gimplify_init_ctor_eval_range (tree object, tree lower, tree upper,
4997 tree value, tree array_elt_type,
4998 gimple_seq *pre_p, bool cleared)
5000 tree loop_entry_label, loop_exit_label, fall_thru_label;
5001 tree var, var_type, cref, tmp;
5003 loop_entry_label = create_artificial_label (UNKNOWN_LOCATION);
5004 loop_exit_label = create_artificial_label (UNKNOWN_LOCATION);
5005 fall_thru_label = create_artificial_label (UNKNOWN_LOCATION);
5007 /* Create and initialize the index variable. */
5008 var_type = TREE_TYPE (upper);
5009 var = create_tmp_var (var_type);
5010 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, lower));
5012 /* Add the loop entry label. */
5013 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_entry_label));
5015 /* Build the reference. */
5016 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
5017 var, NULL_TREE, NULL_TREE);
5019 /* If we are a constructor, just call gimplify_init_ctor_eval to do
5020 the store. Otherwise just assign value to the reference. */
5022 if (TREE_CODE (value) == CONSTRUCTOR)
5023 /* NB we might have to call ourself recursively through
5024 gimplify_init_ctor_eval if the value is a constructor. */
5025 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
5026 pre_p, cleared);
5027 else
5029 if (gimplify_expr (&value, pre_p, NULL, is_gimple_val, fb_rvalue)
5030 != GS_ERROR)
5031 gimplify_seq_add_stmt (pre_p, gimple_build_assign (cref, value));
5034 /* We exit the loop when the index var is equal to the upper bound. */
5035 gimplify_seq_add_stmt (pre_p,
5036 gimple_build_cond (EQ_EXPR, var, upper,
5037 loop_exit_label, fall_thru_label));
5039 gimplify_seq_add_stmt (pre_p, gimple_build_label (fall_thru_label));
5041 /* Otherwise, increment the index var... */
5042 tmp = build2 (PLUS_EXPR, var_type, var,
5043 fold_convert (var_type, integer_one_node));
5044 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, tmp));
5046 /* ...and jump back to the loop entry. */
5047 gimplify_seq_add_stmt (pre_p, gimple_build_goto (loop_entry_label));
5049 /* Add the loop exit label. */
5050 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_exit_label));
5053 /* A subroutine of gimplify_init_constructor. Generate individual
5054 MODIFY_EXPRs for a CONSTRUCTOR. OBJECT is the LHS against which the
5055 assignments should happen. ELTS is the CONSTRUCTOR_ELTS of the
5056 CONSTRUCTOR. CLEARED is true if the entire LHS object has been
5057 zeroed first. */
5059 static void
5060 gimplify_init_ctor_eval (tree object, vec<constructor_elt, va_gc> *elts,
5061 gimple_seq *pre_p, bool cleared)
5063 tree array_elt_type = NULL;
5064 unsigned HOST_WIDE_INT ix;
5065 tree purpose, value;
5067 if (TREE_CODE (TREE_TYPE (object)) == ARRAY_TYPE)
5068 array_elt_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (object)));
5070 FOR_EACH_CONSTRUCTOR_ELT (elts, ix, purpose, value)
5072 tree cref;
5074 /* NULL values are created above for gimplification errors. */
5075 if (value == NULL)
5076 continue;
5078 if (cleared && initializer_zerop (value))
5079 continue;
5081 /* ??? Here's to hoping the front end fills in all of the indices,
5082 so we don't have to figure out what's missing ourselves. */
5083 gcc_assert (purpose);
5085 /* Skip zero-sized fields, unless value has side-effects. This can
5086 happen with calls to functions returning a empty type, which
5087 we shouldn't discard. As a number of downstream passes don't
5088 expect sets of empty type fields, we rely on the gimplification of
5089 the MODIFY_EXPR we make below to drop the assignment statement. */
5090 if (!TREE_SIDE_EFFECTS (value)
5091 && TREE_CODE (purpose) == FIELD_DECL
5092 && is_empty_type (TREE_TYPE (purpose)))
5093 continue;
5095 /* If we have a RANGE_EXPR, we have to build a loop to assign the
5096 whole range. */
5097 if (TREE_CODE (purpose) == RANGE_EXPR)
5099 tree lower = TREE_OPERAND (purpose, 0);
5100 tree upper = TREE_OPERAND (purpose, 1);
5102 /* If the lower bound is equal to upper, just treat it as if
5103 upper was the index. */
5104 if (simple_cst_equal (lower, upper))
5105 purpose = upper;
5106 else
5108 gimplify_init_ctor_eval_range (object, lower, upper, value,
5109 array_elt_type, pre_p, cleared);
5110 continue;
5114 if (array_elt_type)
5116 /* Do not use bitsizetype for ARRAY_REF indices. */
5117 if (TYPE_DOMAIN (TREE_TYPE (object)))
5118 purpose
5119 = fold_convert (TREE_TYPE (TYPE_DOMAIN (TREE_TYPE (object))),
5120 purpose);
5121 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
5122 purpose, NULL_TREE, NULL_TREE);
5124 else
5126 gcc_assert (TREE_CODE (purpose) == FIELD_DECL);
5127 cref = build3 (COMPONENT_REF, TREE_TYPE (purpose),
5128 unshare_expr (object), purpose, NULL_TREE);
5131 if (TREE_CODE (value) == CONSTRUCTOR
5132 && TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE)
5133 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
5134 pre_p, cleared);
5135 else
5137 tree init = build2 (INIT_EXPR, TREE_TYPE (cref), cref, value);
5138 gimplify_and_add (init, pre_p);
5139 ggc_free (init);
5144 /* Return the appropriate RHS predicate for this LHS. */
5146 gimple_predicate
5147 rhs_predicate_for (tree lhs)
5149 if (is_gimple_reg (lhs))
5150 return is_gimple_reg_rhs_or_call;
5151 else
5152 return is_gimple_mem_rhs_or_call;
5155 /* Return the initial guess for an appropriate RHS predicate for this LHS,
5156 before the LHS has been gimplified. */
5158 static gimple_predicate
5159 initial_rhs_predicate_for (tree lhs)
5161 if (is_gimple_reg_type (TREE_TYPE (lhs)))
5162 return is_gimple_reg_rhs_or_call;
5163 else
5164 return is_gimple_mem_rhs_or_call;
5167 /* Gimplify a C99 compound literal expression. This just means adding
5168 the DECL_EXPR before the current statement and using its anonymous
5169 decl instead. */
5171 static enum gimplify_status
5172 gimplify_compound_literal_expr (tree *expr_p, gimple_seq *pre_p,
5173 bool (*gimple_test_f) (tree),
5174 fallback_t fallback)
5176 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (*expr_p);
5177 tree decl = DECL_EXPR_DECL (decl_s);
5178 tree init = DECL_INITIAL (decl);
5179 /* Mark the decl as addressable if the compound literal
5180 expression is addressable now, otherwise it is marked too late
5181 after we gimplify the initialization expression. */
5182 if (TREE_ADDRESSABLE (*expr_p))
5183 TREE_ADDRESSABLE (decl) = 1;
5184 /* Otherwise, if we don't need an lvalue and have a literal directly
5185 substitute it. Check if it matches the gimple predicate, as
5186 otherwise we'd generate a new temporary, and we can as well just
5187 use the decl we already have. */
5188 else if (!TREE_ADDRESSABLE (decl)
5189 && !TREE_THIS_VOLATILE (decl)
5190 && init
5191 && (fallback & fb_lvalue) == 0
5192 && gimple_test_f (init))
5194 *expr_p = init;
5195 return GS_OK;
5198 /* If the decl is not addressable, then it is being used in some
5199 expression or on the right hand side of a statement, and it can
5200 be put into a readonly data section. */
5201 if (!TREE_ADDRESSABLE (decl) && (fallback & fb_lvalue) == 0)
5202 TREE_READONLY (decl) = 1;
5204 /* This decl isn't mentioned in the enclosing block, so add it to the
5205 list of temps. FIXME it seems a bit of a kludge to say that
5206 anonymous artificial vars aren't pushed, but everything else is. */
5207 if (DECL_NAME (decl) == NULL_TREE && !DECL_SEEN_IN_BIND_EXPR_P (decl))
5208 gimple_add_tmp_var (decl);
5210 gimplify_and_add (decl_s, pre_p);
5211 *expr_p = decl;
5212 return GS_OK;
5215 /* Optimize embedded COMPOUND_LITERAL_EXPRs within a CONSTRUCTOR,
5216 return a new CONSTRUCTOR if something changed. */
5218 static tree
5219 optimize_compound_literals_in_ctor (tree orig_ctor)
5221 tree ctor = orig_ctor;
5222 vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ctor);
5223 unsigned int idx, num = vec_safe_length (elts);
5225 for (idx = 0; idx < num; idx++)
5227 tree value = (*elts)[idx].value;
5228 tree newval = value;
5229 if (TREE_CODE (value) == CONSTRUCTOR)
5230 newval = optimize_compound_literals_in_ctor (value);
5231 else if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR)
5233 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (value);
5234 tree decl = DECL_EXPR_DECL (decl_s);
5235 tree init = DECL_INITIAL (decl);
5237 if (!TREE_ADDRESSABLE (value)
5238 && !TREE_ADDRESSABLE (decl)
5239 && init
5240 && TREE_CODE (init) == CONSTRUCTOR)
5241 newval = optimize_compound_literals_in_ctor (init);
5243 if (newval == value)
5244 continue;
5246 if (ctor == orig_ctor)
5248 ctor = copy_node (orig_ctor);
5249 CONSTRUCTOR_ELTS (ctor) = vec_safe_copy (elts);
5250 elts = CONSTRUCTOR_ELTS (ctor);
5252 (*elts)[idx].value = newval;
5254 return ctor;
5257 /* A subroutine of gimplify_modify_expr. Break out elements of a
5258 CONSTRUCTOR used as an initializer into separate MODIFY_EXPRs.
5260 Note that we still need to clear any elements that don't have explicit
5261 initializers, so if not all elements are initialized we keep the
5262 original MODIFY_EXPR, we just remove all of the constructor elements.
5264 If NOTIFY_TEMP_CREATION is true, do not gimplify, just return
5265 GS_ERROR if we would have to create a temporary when gimplifying
5266 this constructor. Otherwise, return GS_OK.
5268 If NOTIFY_TEMP_CREATION is false, just do the gimplification. */
5270 static enum gimplify_status
5271 gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
5272 bool want_value, bool notify_temp_creation)
5274 tree object, ctor, type;
5275 enum gimplify_status ret;
5276 vec<constructor_elt, va_gc> *elts;
5277 bool cleared = false;
5278 bool is_empty_ctor = false;
5279 bool is_init_expr = (TREE_CODE (*expr_p) == INIT_EXPR);
5281 gcc_assert (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == CONSTRUCTOR);
5283 if (!notify_temp_creation)
5285 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
5286 is_gimple_lvalue, fb_lvalue);
5287 if (ret == GS_ERROR)
5288 return ret;
5291 object = TREE_OPERAND (*expr_p, 0);
5292 ctor = TREE_OPERAND (*expr_p, 1)
5293 = optimize_compound_literals_in_ctor (TREE_OPERAND (*expr_p, 1));
5294 type = TREE_TYPE (ctor);
5295 elts = CONSTRUCTOR_ELTS (ctor);
5296 ret = GS_ALL_DONE;
5298 switch (TREE_CODE (type))
5300 case RECORD_TYPE:
5301 case UNION_TYPE:
5302 case QUAL_UNION_TYPE:
5303 case ARRAY_TYPE:
5305 /* Use readonly data for initializers of this or smaller size
5306 regardless of the num_nonzero_elements / num_unique_nonzero_elements
5307 ratio. */
5308 const HOST_WIDE_INT min_unique_size = 64;
5309 /* If num_nonzero_elements / num_unique_nonzero_elements ratio
5310 is smaller than this, use readonly data. */
5311 const int unique_nonzero_ratio = 8;
5312 /* True if a single access of the object must be ensured. This is the
5313 case if the target is volatile, the type is non-addressable and more
5314 than one field need to be assigned. */
5315 const bool ensure_single_access
5316 = TREE_THIS_VOLATILE (object)
5317 && !TREE_ADDRESSABLE (type)
5318 && vec_safe_length (elts) > 1;
5319 struct gimplify_init_ctor_preeval_data preeval_data;
5320 HOST_WIDE_INT num_ctor_elements, num_nonzero_elements;
5321 HOST_WIDE_INT num_unique_nonzero_elements;
5322 bool complete_p, valid_const_initializer;
5324 /* Aggregate types must lower constructors to initialization of
5325 individual elements. The exception is that a CONSTRUCTOR node
5326 with no elements indicates zero-initialization of the whole. */
5327 if (vec_safe_is_empty (elts))
5329 if (notify_temp_creation)
5330 return GS_OK;
5332 /* The var will be initialized and so appear on lhs of
5333 assignment, it can't be TREE_READONLY anymore. */
5334 if (VAR_P (object))
5335 TREE_READONLY (object) = 0;
5337 is_empty_ctor = true;
5338 break;
5341 /* Fetch information about the constructor to direct later processing.
5342 We might want to make static versions of it in various cases, and
5343 can only do so if it known to be a valid constant initializer. */
5344 valid_const_initializer
5345 = categorize_ctor_elements (ctor, &num_nonzero_elements,
5346 &num_unique_nonzero_elements,
5347 &num_ctor_elements, &complete_p);
5349 /* If a const aggregate variable is being initialized, then it
5350 should never be a lose to promote the variable to be static. */
5351 if (valid_const_initializer
5352 && num_nonzero_elements > 1
5353 && TREE_READONLY (object)
5354 && VAR_P (object)
5355 && !DECL_REGISTER (object)
5356 && (flag_merge_constants >= 2 || !TREE_ADDRESSABLE (object)
5357 || DECL_MERGEABLE (object))
5358 /* For ctors that have many repeated nonzero elements
5359 represented through RANGE_EXPRs, prefer initializing
5360 those through runtime loops over copies of large amounts
5361 of data from readonly data section. */
5362 && (num_unique_nonzero_elements
5363 > num_nonzero_elements / unique_nonzero_ratio
5364 || ((unsigned HOST_WIDE_INT) int_size_in_bytes (type)
5365 <= (unsigned HOST_WIDE_INT) min_unique_size)))
5367 if (notify_temp_creation)
5368 return GS_ERROR;
5370 DECL_INITIAL (object) = ctor;
5371 TREE_STATIC (object) = 1;
5372 if (!DECL_NAME (object))
5373 DECL_NAME (object) = create_tmp_var_name ("C");
5374 walk_tree (&DECL_INITIAL (object), force_labels_r, NULL, NULL);
5376 /* ??? C++ doesn't automatically append a .<number> to the
5377 assembler name, and even when it does, it looks at FE private
5378 data structures to figure out what that number should be,
5379 which are not set for this variable. I suppose this is
5380 important for local statics for inline functions, which aren't
5381 "local" in the object file sense. So in order to get a unique
5382 TU-local symbol, we must invoke the lhd version now. */
5383 lhd_set_decl_assembler_name (object);
5385 *expr_p = NULL_TREE;
5386 break;
5389 /* The var will be initialized and so appear on lhs of
5390 assignment, it can't be TREE_READONLY anymore. */
5391 if (VAR_P (object) && !notify_temp_creation)
5392 TREE_READONLY (object) = 0;
5394 /* If there are "lots" of initialized elements, even discounting
5395 those that are not address constants (and thus *must* be
5396 computed at runtime), then partition the constructor into
5397 constant and non-constant parts. Block copy the constant
5398 parts in, then generate code for the non-constant parts. */
5399 /* TODO. There's code in cp/typeck.cc to do this. */
5401 if (int_size_in_bytes (TREE_TYPE (ctor)) < 0)
5402 /* store_constructor will ignore the clearing of variable-sized
5403 objects. Initializers for such objects must explicitly set
5404 every field that needs to be set. */
5405 cleared = false;
5406 else if (!complete_p)
5407 /* If the constructor isn't complete, clear the whole object
5408 beforehand, unless CONSTRUCTOR_NO_CLEARING is set on it.
5410 ??? This ought not to be needed. For any element not present
5411 in the initializer, we should simply set them to zero. Except
5412 we'd need to *find* the elements that are not present, and that
5413 requires trickery to avoid quadratic compile-time behavior in
5414 large cases or excessive memory use in small cases. */
5415 cleared = !CONSTRUCTOR_NO_CLEARING (ctor);
5416 else if (num_ctor_elements - num_nonzero_elements
5417 > CLEAR_RATIO (optimize_function_for_speed_p (cfun))
5418 && num_nonzero_elements < num_ctor_elements / 4)
5419 /* If there are "lots" of zeros, it's more efficient to clear
5420 the memory and then set the nonzero elements. */
5421 cleared = true;
5422 else if (ensure_single_access && num_nonzero_elements == 0)
5423 /* If a single access to the target must be ensured and all elements
5424 are zero, then it's optimal to clear whatever their number. */
5425 cleared = true;
5426 else
5427 cleared = false;
5429 /* If there are "lots" of initialized elements, and all of them
5430 are valid address constants, then the entire initializer can
5431 be dropped to memory, and then memcpy'd out. Don't do this
5432 for sparse arrays, though, as it's more efficient to follow
5433 the standard CONSTRUCTOR behavior of memset followed by
5434 individual element initialization. Also don't do this for small
5435 all-zero initializers (which aren't big enough to merit
5436 clearing), and don't try to make bitwise copies of
5437 TREE_ADDRESSABLE types. */
5438 if (valid_const_initializer
5439 && complete_p
5440 && !(cleared || num_nonzero_elements == 0)
5441 && !TREE_ADDRESSABLE (type))
5443 HOST_WIDE_INT size = int_size_in_bytes (type);
5444 unsigned int align;
5446 /* ??? We can still get unbounded array types, at least
5447 from the C++ front end. This seems wrong, but attempt
5448 to work around it for now. */
5449 if (size < 0)
5451 size = int_size_in_bytes (TREE_TYPE (object));
5452 if (size >= 0)
5453 TREE_TYPE (ctor) = type = TREE_TYPE (object);
5456 /* Find the maximum alignment we can assume for the object. */
5457 /* ??? Make use of DECL_OFFSET_ALIGN. */
5458 if (DECL_P (object))
5459 align = DECL_ALIGN (object);
5460 else
5461 align = TYPE_ALIGN (type);
5463 /* Do a block move either if the size is so small as to make
5464 each individual move a sub-unit move on average, or if it
5465 is so large as to make individual moves inefficient. */
5466 if (size > 0
5467 && num_nonzero_elements > 1
5468 /* For ctors that have many repeated nonzero elements
5469 represented through RANGE_EXPRs, prefer initializing
5470 those through runtime loops over copies of large amounts
5471 of data from readonly data section. */
5472 && (num_unique_nonzero_elements
5473 > num_nonzero_elements / unique_nonzero_ratio
5474 || size <= min_unique_size)
5475 && (size < num_nonzero_elements
5476 || !can_move_by_pieces (size, align)))
5478 if (notify_temp_creation)
5479 return GS_ERROR;
5481 walk_tree (&ctor, force_labels_r, NULL, NULL);
5482 ctor = tree_output_constant_def (ctor);
5483 if (!useless_type_conversion_p (type, TREE_TYPE (ctor)))
5484 ctor = build1 (VIEW_CONVERT_EXPR, type, ctor);
5485 TREE_OPERAND (*expr_p, 1) = ctor;
5487 /* This is no longer an assignment of a CONSTRUCTOR, but
5488 we still may have processing to do on the LHS. So
5489 pretend we didn't do anything here to let that happen. */
5490 return GS_UNHANDLED;
5494 /* If a single access to the target must be ensured and there are
5495 nonzero elements or the zero elements are not assigned en masse,
5496 initialize the target from a temporary. */
5497 if (ensure_single_access && (num_nonzero_elements > 0 || !cleared))
5499 if (notify_temp_creation)
5500 return GS_ERROR;
5502 tree temp = create_tmp_var (TYPE_MAIN_VARIANT (type));
5503 TREE_OPERAND (*expr_p, 0) = temp;
5504 *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p),
5505 *expr_p,
5506 build2 (MODIFY_EXPR, void_type_node,
5507 object, temp));
5508 return GS_OK;
5511 if (notify_temp_creation)
5512 return GS_OK;
5514 /* If there are nonzero elements and if needed, pre-evaluate to capture
5515 elements overlapping with the lhs into temporaries. We must do this
5516 before clearing to fetch the values before they are zeroed-out. */
5517 if (num_nonzero_elements > 0 && TREE_CODE (*expr_p) != INIT_EXPR)
5519 preeval_data.lhs_base_decl = get_base_address (object);
5520 if (!DECL_P (preeval_data.lhs_base_decl))
5521 preeval_data.lhs_base_decl = NULL;
5522 preeval_data.lhs_alias_set = get_alias_set (object);
5524 gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p, 1),
5525 pre_p, post_p, &preeval_data);
5528 bool ctor_has_side_effects_p
5529 = TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p, 1));
5531 if (cleared)
5533 /* Zap the CONSTRUCTOR element list, which simplifies this case.
5534 Note that we still have to gimplify, in order to handle the
5535 case of variable sized types. Avoid shared tree structures. */
5536 CONSTRUCTOR_ELTS (ctor) = NULL;
5537 TREE_SIDE_EFFECTS (ctor) = 0;
5538 object = unshare_expr (object);
5539 gimplify_stmt (expr_p, pre_p);
5542 /* If we have not block cleared the object, or if there are nonzero
5543 elements in the constructor, or if the constructor has side effects,
5544 add assignments to the individual scalar fields of the object. */
5545 if (!cleared
5546 || num_nonzero_elements > 0
5547 || ctor_has_side_effects_p)
5548 gimplify_init_ctor_eval (object, elts, pre_p, cleared);
5550 *expr_p = NULL_TREE;
5552 break;
5554 case COMPLEX_TYPE:
5556 tree r, i;
5558 if (notify_temp_creation)
5559 return GS_OK;
5561 /* Extract the real and imaginary parts out of the ctor. */
5562 gcc_assert (elts->length () == 2);
5563 r = (*elts)[0].value;
5564 i = (*elts)[1].value;
5565 if (r == NULL || i == NULL)
5567 tree zero = build_zero_cst (TREE_TYPE (type));
5568 if (r == NULL)
5569 r = zero;
5570 if (i == NULL)
5571 i = zero;
5574 /* Complex types have either COMPLEX_CST or COMPLEX_EXPR to
5575 represent creation of a complex value. */
5576 if (TREE_CONSTANT (r) && TREE_CONSTANT (i))
5578 ctor = build_complex (type, r, i);
5579 TREE_OPERAND (*expr_p, 1) = ctor;
5581 else
5583 ctor = build2 (COMPLEX_EXPR, type, r, i);
5584 TREE_OPERAND (*expr_p, 1) = ctor;
5585 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 1),
5586 pre_p,
5587 post_p,
5588 rhs_predicate_for (TREE_OPERAND (*expr_p, 0)),
5589 fb_rvalue);
5592 break;
5594 case VECTOR_TYPE:
5596 unsigned HOST_WIDE_INT ix;
5597 constructor_elt *ce;
5599 if (notify_temp_creation)
5600 return GS_OK;
5602 /* Vector types use CONSTRUCTOR all the way through gimple
5603 compilation as a general initializer. */
5604 FOR_EACH_VEC_SAFE_ELT (elts, ix, ce)
5606 enum gimplify_status tret;
5607 tret = gimplify_expr (&ce->value, pre_p, post_p, is_gimple_val,
5608 fb_rvalue);
5609 if (tret == GS_ERROR)
5610 ret = GS_ERROR;
5611 else if (TREE_STATIC (ctor)
5612 && !initializer_constant_valid_p (ce->value,
5613 TREE_TYPE (ce->value)))
5614 TREE_STATIC (ctor) = 0;
5616 recompute_constructor_flags (ctor);
5618 /* Go ahead and simplify constant constructors to VECTOR_CST. */
5619 if (TREE_CONSTANT (ctor))
5621 bool constant_p = true;
5622 tree value;
5624 /* Even when ctor is constant, it might contain non-*_CST
5625 elements, such as addresses or trapping values like
5626 1.0/0.0 - 1.0/0.0. Such expressions don't belong
5627 in VECTOR_CST nodes. */
5628 FOR_EACH_CONSTRUCTOR_VALUE (elts, ix, value)
5629 if (!CONSTANT_CLASS_P (value))
5631 constant_p = false;
5632 break;
5635 if (constant_p)
5637 TREE_OPERAND (*expr_p, 1) = build_vector_from_ctor (type, elts);
5638 break;
5642 if (!is_gimple_reg (TREE_OPERAND (*expr_p, 0)))
5643 TREE_OPERAND (*expr_p, 1) = get_formal_tmp_var (ctor, pre_p);
5645 break;
5647 default:
5648 /* So how did we get a CONSTRUCTOR for a scalar type? */
5649 gcc_unreachable ();
5652 if (ret == GS_ERROR)
5653 return GS_ERROR;
5654 /* If we have gimplified both sides of the initializer but have
5655 not emitted an assignment, do so now. */
5656 if (*expr_p
5657 /* If the type is an empty type, we don't need to emit the
5658 assignment. */
5659 && !is_empty_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0))))
5661 tree lhs = TREE_OPERAND (*expr_p, 0);
5662 tree rhs = TREE_OPERAND (*expr_p, 1);
5663 if (want_value && object == lhs)
5664 lhs = unshare_expr (lhs);
5665 gassign *init = gimple_build_assign (lhs, rhs);
5666 gimplify_seq_add_stmt (pre_p, init);
5668 if (want_value)
5670 *expr_p = object;
5671 ret = GS_OK;
5673 else
5675 *expr_p = NULL;
5676 ret = GS_ALL_DONE;
5679 /* If the user requests to initialize automatic variables, we
5680 should initialize paddings inside the variable. Add a call to
5681 __builtin_clear_pading (&object, 0, for_auto_init = true) to
5682 initialize paddings of object always to zero regardless of
5683 INIT_TYPE. Note, we will not insert this call if the aggregate
5684 variable has be completely cleared already or it's initialized
5685 with an empty constructor. We cannot insert this call if the
5686 variable is a gimple register since __builtin_clear_padding will take
5687 the address of the variable. As a result, if a long double/_Complex long
5688 double variable will be spilled into stack later, its padding cannot
5689 be cleared with __builtin_clear_padding. We should clear its padding
5690 when it is spilled into memory. */
5691 if (is_init_expr
5692 && !is_gimple_reg (object)
5693 && clear_padding_type_may_have_padding_p (type)
5694 && ((AGGREGATE_TYPE_P (type) && !cleared && !is_empty_ctor)
5695 || !AGGREGATE_TYPE_P (type))
5696 && is_var_need_auto_init (object))
5697 gimple_add_padding_init_for_auto_var (object, false, pre_p);
5699 return ret;
5702 /* Given a pointer value OP0, return a simplified version of an
5703 indirection through OP0, or NULL_TREE if no simplification is
5704 possible. This may only be applied to a rhs of an expression.
5705 Note that the resulting type may be different from the type pointed
5706 to in the sense that it is still compatible from the langhooks
5707 point of view. */
5709 static tree
5710 gimple_fold_indirect_ref_rhs (tree t)
5712 return gimple_fold_indirect_ref (t);
5715 /* Subroutine of gimplify_modify_expr to do simplifications of
5716 MODIFY_EXPRs based on the code of the RHS. We loop for as long as
5717 something changes. */
5719 static enum gimplify_status
5720 gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p,
5721 gimple_seq *pre_p, gimple_seq *post_p,
5722 bool want_value)
5724 enum gimplify_status ret = GS_UNHANDLED;
5725 bool changed;
5729 changed = false;
5730 switch (TREE_CODE (*from_p))
5732 case VAR_DECL:
5733 /* If we're assigning from a read-only variable initialized with
5734 a constructor and not volatile, do the direct assignment from
5735 the constructor, but only if the target is not volatile either
5736 since this latter assignment might end up being done on a per
5737 field basis. However, if the target is volatile and the type
5738 is aggregate and non-addressable, gimplify_init_constructor
5739 knows that it needs to ensure a single access to the target
5740 and it will return GS_OK only in this case. */
5741 if (TREE_READONLY (*from_p)
5742 && DECL_INITIAL (*from_p)
5743 && TREE_CODE (DECL_INITIAL (*from_p)) == CONSTRUCTOR
5744 && !TREE_THIS_VOLATILE (*from_p)
5745 && (!TREE_THIS_VOLATILE (*to_p)
5746 || (AGGREGATE_TYPE_P (TREE_TYPE (*to_p))
5747 && !TREE_ADDRESSABLE (TREE_TYPE (*to_p)))))
5749 tree old_from = *from_p;
5750 enum gimplify_status subret;
5752 /* Move the constructor into the RHS. */
5753 *from_p = unshare_expr (DECL_INITIAL (*from_p));
5755 /* Let's see if gimplify_init_constructor will need to put
5756 it in memory. */
5757 subret = gimplify_init_constructor (expr_p, NULL, NULL,
5758 false, true);
5759 if (subret == GS_ERROR)
5761 /* If so, revert the change. */
5762 *from_p = old_from;
5764 else
5766 ret = GS_OK;
5767 changed = true;
5770 break;
5771 case INDIRECT_REF:
5772 if (!TREE_ADDRESSABLE (TREE_TYPE (*from_p)))
5773 /* If we have code like
5775 *(const A*)(A*)&x
5777 where the type of "x" is a (possibly cv-qualified variant
5778 of "A"), treat the entire expression as identical to "x".
5779 This kind of code arises in C++ when an object is bound
5780 to a const reference, and if "x" is a TARGET_EXPR we want
5781 to take advantage of the optimization below. But not if
5782 the type is TREE_ADDRESSABLE; then C++17 says that the
5783 TARGET_EXPR needs to be a temporary. */
5784 if (tree t
5785 = gimple_fold_indirect_ref_rhs (TREE_OPERAND (*from_p, 0)))
5787 bool volatile_p = TREE_THIS_VOLATILE (*from_p);
5788 if (TREE_THIS_VOLATILE (t) != volatile_p)
5790 if (DECL_P (t))
5791 t = build_simple_mem_ref_loc (EXPR_LOCATION (*from_p),
5792 build_fold_addr_expr (t));
5793 if (REFERENCE_CLASS_P (t))
5794 TREE_THIS_VOLATILE (t) = volatile_p;
5796 *from_p = t;
5797 ret = GS_OK;
5798 changed = true;
5800 break;
5802 case TARGET_EXPR:
5804 /* If we are initializing something from a TARGET_EXPR, strip the
5805 TARGET_EXPR and initialize it directly, if possible. This can't
5806 be done if the initializer is void, since that implies that the
5807 temporary is set in some non-trivial way.
5809 ??? What about code that pulls out the temp and uses it
5810 elsewhere? I think that such code never uses the TARGET_EXPR as
5811 an initializer. If I'm wrong, we'll die because the temp won't
5812 have any RTL. In that case, I guess we'll need to replace
5813 references somehow. */
5814 tree init = TARGET_EXPR_INITIAL (*from_p);
5816 if (init
5817 && (TREE_CODE (*expr_p) != MODIFY_EXPR
5818 || !TARGET_EXPR_NO_ELIDE (*from_p))
5819 && !VOID_TYPE_P (TREE_TYPE (init)))
5821 *from_p = init;
5822 ret = GS_OK;
5823 changed = true;
5826 break;
5828 case COMPOUND_EXPR:
5829 /* Remove any COMPOUND_EXPR in the RHS so the following cases will be
5830 caught. */
5831 gimplify_compound_expr (from_p, pre_p, true);
5832 ret = GS_OK;
5833 changed = true;
5834 break;
5836 case CONSTRUCTOR:
5837 /* If we already made some changes, let the front end have a
5838 crack at this before we break it down. */
5839 if (ret != GS_UNHANDLED)
5840 break;
5842 /* If we're initializing from a CONSTRUCTOR, break this into
5843 individual MODIFY_EXPRs. */
5844 ret = gimplify_init_constructor (expr_p, pre_p, post_p, want_value,
5845 false);
5846 return ret;
5848 case COND_EXPR:
5849 /* If we're assigning to a non-register type, push the assignment
5850 down into the branches. This is mandatory for ADDRESSABLE types,
5851 since we cannot generate temporaries for such, but it saves a
5852 copy in other cases as well. */
5853 if (!is_gimple_reg_type (TREE_TYPE (*from_p)))
5855 /* This code should mirror the code in gimplify_cond_expr. */
5856 enum tree_code code = TREE_CODE (*expr_p);
5857 tree cond = *from_p;
5858 tree result = *to_p;
5860 ret = gimplify_expr (&result, pre_p, post_p,
5861 is_gimple_lvalue, fb_lvalue);
5862 if (ret != GS_ERROR)
5863 ret = GS_OK;
5865 /* If we are going to write RESULT more than once, clear
5866 TREE_READONLY flag, otherwise we might incorrectly promote
5867 the variable to static const and initialize it at compile
5868 time in one of the branches. */
5869 if (VAR_P (result)
5870 && TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node
5871 && TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
5872 TREE_READONLY (result) = 0;
5873 if (TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node)
5874 TREE_OPERAND (cond, 1)
5875 = build2 (code, void_type_node, result,
5876 TREE_OPERAND (cond, 1));
5877 if (TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
5878 TREE_OPERAND (cond, 2)
5879 = build2 (code, void_type_node, unshare_expr (result),
5880 TREE_OPERAND (cond, 2));
5882 TREE_TYPE (cond) = void_type_node;
5883 recalculate_side_effects (cond);
5885 if (want_value)
5887 gimplify_and_add (cond, pre_p);
5888 *expr_p = unshare_expr (result);
5890 else
5891 *expr_p = cond;
5892 return ret;
5894 break;
5896 case CALL_EXPR:
5897 /* For calls that return in memory, give *to_p as the CALL_EXPR's
5898 return slot so that we don't generate a temporary. */
5899 if (!CALL_EXPR_RETURN_SLOT_OPT (*from_p)
5900 && aggregate_value_p (*from_p, *from_p))
5902 bool use_target;
5904 if (!(rhs_predicate_for (*to_p))(*from_p))
5905 /* If we need a temporary, *to_p isn't accurate. */
5906 use_target = false;
5907 /* It's OK to use the return slot directly unless it's an NRV. */
5908 else if (TREE_CODE (*to_p) == RESULT_DECL
5909 && DECL_NAME (*to_p) == NULL_TREE
5910 && needs_to_live_in_memory (*to_p))
5911 use_target = true;
5912 else if (is_gimple_reg_type (TREE_TYPE (*to_p))
5913 || (DECL_P (*to_p) && DECL_REGISTER (*to_p)))
5914 /* Don't force regs into memory. */
5915 use_target = false;
5916 else if (TREE_CODE (*expr_p) == INIT_EXPR)
5917 /* It's OK to use the target directly if it's being
5918 initialized. */
5919 use_target = true;
5920 else if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p)))
5921 != INTEGER_CST)
5922 /* Always use the target and thus RSO for variable-sized types.
5923 GIMPLE cannot deal with a variable-sized assignment
5924 embedded in a call statement. */
5925 use_target = true;
5926 else if (TREE_CODE (*to_p) != SSA_NAME
5927 && (!is_gimple_variable (*to_p)
5928 || needs_to_live_in_memory (*to_p)))
5929 /* Don't use the original target if it's already addressable;
5930 if its address escapes, and the called function uses the
5931 NRV optimization, a conforming program could see *to_p
5932 change before the called function returns; see c++/19317.
5933 When optimizing, the return_slot pass marks more functions
5934 as safe after we have escape info. */
5935 use_target = false;
5936 else
5937 use_target = true;
5939 if (use_target)
5941 CALL_EXPR_RETURN_SLOT_OPT (*from_p) = 1;
5942 mark_addressable (*to_p);
5945 break;
5947 case WITH_SIZE_EXPR:
5948 /* Likewise for calls that return an aggregate of non-constant size,
5949 since we would not be able to generate a temporary at all. */
5950 if (TREE_CODE (TREE_OPERAND (*from_p, 0)) == CALL_EXPR)
5952 *from_p = TREE_OPERAND (*from_p, 0);
5953 /* We don't change ret in this case because the
5954 WITH_SIZE_EXPR might have been added in
5955 gimplify_modify_expr, so returning GS_OK would lead to an
5956 infinite loop. */
5957 changed = true;
5959 break;
5961 /* If we're initializing from a container, push the initialization
5962 inside it. */
5963 case CLEANUP_POINT_EXPR:
5964 case BIND_EXPR:
5965 case STATEMENT_LIST:
5967 tree wrap = *from_p;
5968 tree t;
5970 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_min_lval,
5971 fb_lvalue);
5972 if (ret != GS_ERROR)
5973 ret = GS_OK;
5975 t = voidify_wrapper_expr (wrap, *expr_p);
5976 gcc_assert (t == *expr_p);
5978 if (want_value)
5980 gimplify_and_add (wrap, pre_p);
5981 *expr_p = unshare_expr (*to_p);
5983 else
5984 *expr_p = wrap;
5985 return GS_OK;
5988 case NOP_EXPR:
5989 /* Pull out compound literal expressions from a NOP_EXPR.
5990 Those are created in the C FE to drop qualifiers during
5991 lvalue conversion. */
5992 if ((TREE_CODE (TREE_OPERAND (*from_p, 0)) == COMPOUND_LITERAL_EXPR)
5993 && tree_ssa_useless_type_conversion (*from_p))
5995 *from_p = TREE_OPERAND (*from_p, 0);
5996 ret = GS_OK;
5997 changed = true;
5999 break;
6001 case COMPOUND_LITERAL_EXPR:
6003 tree complit = TREE_OPERAND (*expr_p, 1);
6004 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (complit);
6005 tree decl = DECL_EXPR_DECL (decl_s);
6006 tree init = DECL_INITIAL (decl);
6008 /* struct T x = (struct T) { 0, 1, 2 } can be optimized
6009 into struct T x = { 0, 1, 2 } if the address of the
6010 compound literal has never been taken. */
6011 if (!TREE_ADDRESSABLE (complit)
6012 && !TREE_ADDRESSABLE (decl)
6013 && init)
6015 *expr_p = copy_node (*expr_p);
6016 TREE_OPERAND (*expr_p, 1) = init;
6017 return GS_OK;
6021 default:
6022 break;
6025 while (changed);
6027 return ret;
6031 /* Return true if T looks like a valid GIMPLE statement. */
6033 static bool
6034 is_gimple_stmt (tree t)
6036 const enum tree_code code = TREE_CODE (t);
6038 switch (code)
6040 case NOP_EXPR:
6041 /* The only valid NOP_EXPR is the empty statement. */
6042 return IS_EMPTY_STMT (t);
6044 case BIND_EXPR:
6045 case COND_EXPR:
6046 /* These are only valid if they're void. */
6047 return TREE_TYPE (t) == NULL || VOID_TYPE_P (TREE_TYPE (t));
6049 case SWITCH_EXPR:
6050 case GOTO_EXPR:
6051 case RETURN_EXPR:
6052 case LABEL_EXPR:
6053 case CASE_LABEL_EXPR:
6054 case TRY_CATCH_EXPR:
6055 case TRY_FINALLY_EXPR:
6056 case EH_FILTER_EXPR:
6057 case CATCH_EXPR:
6058 case ASM_EXPR:
6059 case STATEMENT_LIST:
6060 case OACC_PARALLEL:
6061 case OACC_KERNELS:
6062 case OACC_SERIAL:
6063 case OACC_DATA:
6064 case OACC_HOST_DATA:
6065 case OACC_DECLARE:
6066 case OACC_UPDATE:
6067 case OACC_ENTER_DATA:
6068 case OACC_EXIT_DATA:
6069 case OACC_CACHE:
6070 case OMP_PARALLEL:
6071 case OMP_FOR:
6072 case OMP_SIMD:
6073 case OMP_DISTRIBUTE:
6074 case OMP_LOOP:
6075 case OACC_LOOP:
6076 case OMP_SCAN:
6077 case OMP_SCOPE:
6078 case OMP_SECTIONS:
6079 case OMP_SECTION:
6080 case OMP_STRUCTURED_BLOCK:
6081 case OMP_SINGLE:
6082 case OMP_MASTER:
6083 case OMP_MASKED:
6084 case OMP_TASKGROUP:
6085 case OMP_ORDERED:
6086 case OMP_CRITICAL:
6087 case OMP_TASK:
6088 case OMP_TARGET:
6089 case OMP_TARGET_DATA:
6090 case OMP_TARGET_UPDATE:
6091 case OMP_TARGET_ENTER_DATA:
6092 case OMP_TARGET_EXIT_DATA:
6093 case OMP_TASKLOOP:
6094 case OMP_TEAMS:
6095 /* These are always void. */
6096 return true;
6098 case CALL_EXPR:
6099 case MODIFY_EXPR:
6100 case PREDICT_EXPR:
6101 /* These are valid regardless of their type. */
6102 return true;
6104 default:
6105 return false;
6110 /* Promote partial stores to COMPLEX variables to total stores. *EXPR_P is
6111 a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a gimple register.
6113 IMPORTANT NOTE: This promotion is performed by introducing a load of the
6114 other, unmodified part of the complex object just before the total store.
6115 As a consequence, if the object is still uninitialized, an undefined value
6116 will be loaded into a register, which may result in a spurious exception
6117 if the register is floating-point and the value happens to be a signaling
6118 NaN for example. Then the fully-fledged complex operations lowering pass
6119 followed by a DCE pass are necessary in order to fix things up. */
6121 static enum gimplify_status
6122 gimplify_modify_expr_complex_part (tree *expr_p, gimple_seq *pre_p,
6123 bool want_value)
6125 enum tree_code code, ocode;
6126 tree lhs, rhs, new_rhs, other, realpart, imagpart;
6128 lhs = TREE_OPERAND (*expr_p, 0);
6129 rhs = TREE_OPERAND (*expr_p, 1);
6130 code = TREE_CODE (lhs);
6131 lhs = TREE_OPERAND (lhs, 0);
6133 ocode = code == REALPART_EXPR ? IMAGPART_EXPR : REALPART_EXPR;
6134 other = build1 (ocode, TREE_TYPE (rhs), lhs);
6135 suppress_warning (other);
6136 other = get_formal_tmp_var (other, pre_p);
6138 realpart = code == REALPART_EXPR ? rhs : other;
6139 imagpart = code == REALPART_EXPR ? other : rhs;
6141 if (TREE_CONSTANT (realpart) && TREE_CONSTANT (imagpart))
6142 new_rhs = build_complex (TREE_TYPE (lhs), realpart, imagpart);
6143 else
6144 new_rhs = build2 (COMPLEX_EXPR, TREE_TYPE (lhs), realpart, imagpart);
6146 gimplify_seq_add_stmt (pre_p, gimple_build_assign (lhs, new_rhs));
6147 *expr_p = (want_value) ? rhs : NULL_TREE;
6149 return GS_ALL_DONE;
6152 /* Gimplify the MODIFY_EXPR node pointed to by EXPR_P.
6154 modify_expr
6155 : varname '=' rhs
6156 | '*' ID '=' rhs
6158 PRE_P points to the list where side effects that must happen before
6159 *EXPR_P should be stored.
6161 POST_P points to the list where side effects that must happen after
6162 *EXPR_P should be stored.
6164 WANT_VALUE is nonzero iff we want to use the value of this expression
6165 in another expression. */
6167 static enum gimplify_status
6168 gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
6169 bool want_value)
6171 tree *from_p = &TREE_OPERAND (*expr_p, 1);
6172 tree *to_p = &TREE_OPERAND (*expr_p, 0);
6173 enum gimplify_status ret = GS_UNHANDLED;
6174 gimple *assign;
6175 location_t loc = EXPR_LOCATION (*expr_p);
6176 gimple_stmt_iterator gsi;
6178 if (error_operand_p (*from_p) || error_operand_p (*to_p))
6179 return GS_ERROR;
6181 gcc_assert (TREE_CODE (*expr_p) == MODIFY_EXPR
6182 || TREE_CODE (*expr_p) == INIT_EXPR);
6184 /* Trying to simplify a clobber using normal logic doesn't work,
6185 so handle it here. */
6186 if (TREE_CLOBBER_P (*from_p))
6188 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
6189 if (ret == GS_ERROR)
6190 return ret;
6191 gcc_assert (!want_value);
6192 if (!VAR_P (*to_p) && TREE_CODE (*to_p) != MEM_REF)
6194 tree addr = get_initialized_tmp_var (build_fold_addr_expr (*to_p),
6195 pre_p, post_p);
6196 *to_p = build_simple_mem_ref_loc (EXPR_LOCATION (*to_p), addr);
6198 gimplify_seq_add_stmt (pre_p, gimple_build_assign (*to_p, *from_p));
6199 *expr_p = NULL;
6200 return GS_ALL_DONE;
6203 /* Convert initialization from an empty variable-size CONSTRUCTOR to
6204 memset. */
6205 if (TREE_TYPE (*from_p) != error_mark_node
6206 && TYPE_SIZE_UNIT (TREE_TYPE (*from_p))
6207 && !poly_int_tree_p (TYPE_SIZE_UNIT (TREE_TYPE (*from_p)))
6208 && TREE_CODE (*from_p) == CONSTRUCTOR
6209 && CONSTRUCTOR_NELTS (*from_p) == 0)
6211 maybe_with_size_expr (from_p);
6212 gcc_assert (TREE_CODE (*from_p) == WITH_SIZE_EXPR);
6213 return gimplify_modify_expr_to_memset (expr_p,
6214 TREE_OPERAND (*from_p, 1),
6215 want_value, pre_p);
6218 /* Insert pointer conversions required by the middle-end that are not
6219 required by the frontend. This fixes middle-end type checking for
6220 for example gcc.dg/redecl-6.c. */
6221 if (POINTER_TYPE_P (TREE_TYPE (*to_p)))
6223 STRIP_USELESS_TYPE_CONVERSION (*from_p);
6224 if (!useless_type_conversion_p (TREE_TYPE (*to_p), TREE_TYPE (*from_p)))
6225 *from_p = fold_convert_loc (loc, TREE_TYPE (*to_p), *from_p);
6228 /* See if any simplifications can be done based on what the RHS is. */
6229 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
6230 want_value);
6231 if (ret != GS_UNHANDLED)
6232 return ret;
6234 /* For empty types only gimplify the left hand side and right hand
6235 side as statements and throw away the assignment. Do this after
6236 gimplify_modify_expr_rhs so we handle TARGET_EXPRs of addressable
6237 types properly. */
6238 if (is_empty_type (TREE_TYPE (*from_p))
6239 && !want_value
6240 /* Don't do this for calls that return addressable types, expand_call
6241 relies on those having a lhs. */
6242 && !(TREE_ADDRESSABLE (TREE_TYPE (*from_p))
6243 && TREE_CODE (*from_p) == CALL_EXPR))
6245 gimplify_stmt (from_p, pre_p);
6246 gimplify_stmt (to_p, pre_p);
6247 *expr_p = NULL_TREE;
6248 return GS_ALL_DONE;
6251 /* If the value being copied is of variable width, compute the length
6252 of the copy into a WITH_SIZE_EXPR. Note that we need to do this
6253 before gimplifying any of the operands so that we can resolve any
6254 PLACEHOLDER_EXPRs in the size. Also note that the RTL expander uses
6255 the size of the expression to be copied, not of the destination, so
6256 that is what we must do here. */
6257 maybe_with_size_expr (from_p);
6259 /* As a special case, we have to temporarily allow for assignments
6260 with a CALL_EXPR on the RHS. Since in GIMPLE a function call is
6261 a toplevel statement, when gimplifying the GENERIC expression
6262 MODIFY_EXPR <a, CALL_EXPR <foo>>, we cannot create the tuple
6263 GIMPLE_ASSIGN <a, GIMPLE_CALL <foo>>.
6265 Instead, we need to create the tuple GIMPLE_CALL <a, foo>. To
6266 prevent gimplify_expr from trying to create a new temporary for
6267 foo's LHS, we tell it that it should only gimplify until it
6268 reaches the CALL_EXPR. On return from gimplify_expr, the newly
6269 created GIMPLE_CALL <foo> will be the last statement in *PRE_P
6270 and all we need to do here is set 'a' to be its LHS. */
6272 /* Gimplify the RHS first for C++17 and bug 71104. */
6273 gimple_predicate initial_pred = initial_rhs_predicate_for (*to_p);
6274 ret = gimplify_expr (from_p, pre_p, post_p, initial_pred, fb_rvalue);
6275 if (ret == GS_ERROR)
6276 return ret;
6278 /* Then gimplify the LHS. */
6279 /* If we gimplified the RHS to a CALL_EXPR and that call may return
6280 twice we have to make sure to gimplify into non-SSA as otherwise
6281 the abnormal edge added later will make those defs not dominate
6282 their uses.
6283 ??? Technically this applies only to the registers used in the
6284 resulting non-register *TO_P. */
6285 bool saved_into_ssa = gimplify_ctxp->into_ssa;
6286 if (saved_into_ssa
6287 && TREE_CODE (*from_p) == CALL_EXPR
6288 && call_expr_flags (*from_p) & ECF_RETURNS_TWICE)
6289 gimplify_ctxp->into_ssa = false;
6290 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
6291 gimplify_ctxp->into_ssa = saved_into_ssa;
6292 if (ret == GS_ERROR)
6293 return ret;
6295 /* Now that the LHS is gimplified, re-gimplify the RHS if our initial
6296 guess for the predicate was wrong. */
6297 gimple_predicate final_pred = rhs_predicate_for (*to_p);
6298 if (final_pred != initial_pred)
6300 ret = gimplify_expr (from_p, pre_p, post_p, final_pred, fb_rvalue);
6301 if (ret == GS_ERROR)
6302 return ret;
6305 /* In case of va_arg internal fn wrappped in a WITH_SIZE_EXPR, add the type
6306 size as argument to the call. */
6307 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
6309 tree call = TREE_OPERAND (*from_p, 0);
6310 tree vlasize = TREE_OPERAND (*from_p, 1);
6312 if (TREE_CODE (call) == CALL_EXPR
6313 && CALL_EXPR_IFN (call) == IFN_VA_ARG)
6315 int nargs = call_expr_nargs (call);
6316 tree type = TREE_TYPE (call);
6317 tree ap = CALL_EXPR_ARG (call, 0);
6318 tree tag = CALL_EXPR_ARG (call, 1);
6319 tree aptag = CALL_EXPR_ARG (call, 2);
6320 tree newcall = build_call_expr_internal_loc (EXPR_LOCATION (call),
6321 IFN_VA_ARG, type,
6322 nargs + 1, ap, tag,
6323 aptag, vlasize);
6324 TREE_OPERAND (*from_p, 0) = newcall;
6328 /* Now see if the above changed *from_p to something we handle specially. */
6329 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
6330 want_value);
6331 if (ret != GS_UNHANDLED)
6332 return ret;
6334 /* If we've got a variable sized assignment between two lvalues (i.e. does
6335 not involve a call), then we can make things a bit more straightforward
6336 by converting the assignment to memcpy or memset. */
6337 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
6339 tree from = TREE_OPERAND (*from_p, 0);
6340 tree size = TREE_OPERAND (*from_p, 1);
6342 if (TREE_CODE (from) == CONSTRUCTOR)
6343 return gimplify_modify_expr_to_memset (expr_p, size, want_value, pre_p);
6345 if (is_gimple_addressable (from))
6347 *from_p = from;
6348 return gimplify_modify_expr_to_memcpy (expr_p, size, want_value,
6349 pre_p);
6353 /* Transform partial stores to non-addressable complex variables into
6354 total stores. This allows us to use real instead of virtual operands
6355 for these variables, which improves optimization. */
6356 if ((TREE_CODE (*to_p) == REALPART_EXPR
6357 || TREE_CODE (*to_p) == IMAGPART_EXPR)
6358 && is_gimple_reg (TREE_OPERAND (*to_p, 0)))
6359 return gimplify_modify_expr_complex_part (expr_p, pre_p, want_value);
6361 /* Try to alleviate the effects of the gimplification creating artificial
6362 temporaries (see for example is_gimple_reg_rhs) on the debug info, but
6363 make sure not to create DECL_DEBUG_EXPR links across functions. */
6364 if (!gimplify_ctxp->into_ssa
6365 && VAR_P (*from_p)
6366 && DECL_IGNORED_P (*from_p)
6367 && DECL_P (*to_p)
6368 && !DECL_IGNORED_P (*to_p)
6369 && decl_function_context (*to_p) == current_function_decl
6370 && decl_function_context (*from_p) == current_function_decl)
6372 if (!DECL_NAME (*from_p) && DECL_NAME (*to_p))
6373 DECL_NAME (*from_p)
6374 = create_tmp_var_name (IDENTIFIER_POINTER (DECL_NAME (*to_p)));
6375 DECL_HAS_DEBUG_EXPR_P (*from_p) = 1;
6376 SET_DECL_DEBUG_EXPR (*from_p, *to_p);
6379 if (want_value && TREE_THIS_VOLATILE (*to_p))
6380 *from_p = get_initialized_tmp_var (*from_p, pre_p, post_p);
6382 if (TREE_CODE (*from_p) == CALL_EXPR)
6384 /* Since the RHS is a CALL_EXPR, we need to create a GIMPLE_CALL
6385 instead of a GIMPLE_ASSIGN. */
6386 gcall *call_stmt;
6387 if (CALL_EXPR_FN (*from_p) == NULL_TREE)
6389 /* Gimplify internal functions created in the FEs. */
6390 int nargs = call_expr_nargs (*from_p), i;
6391 enum internal_fn ifn = CALL_EXPR_IFN (*from_p);
6392 auto_vec<tree> vargs (nargs);
6394 for (i = 0; i < nargs; i++)
6396 gimplify_arg (&CALL_EXPR_ARG (*from_p, i), pre_p,
6397 EXPR_LOCATION (*from_p));
6398 vargs.quick_push (CALL_EXPR_ARG (*from_p, i));
6400 call_stmt = gimple_build_call_internal_vec (ifn, vargs);
6401 gimple_call_set_nothrow (call_stmt, TREE_NOTHROW (*from_p));
6402 gimple_set_location (call_stmt, EXPR_LOCATION (*expr_p));
6404 else
6406 tree fnptrtype = TREE_TYPE (CALL_EXPR_FN (*from_p));
6407 CALL_EXPR_FN (*from_p) = TREE_OPERAND (CALL_EXPR_FN (*from_p), 0);
6408 STRIP_USELESS_TYPE_CONVERSION (CALL_EXPR_FN (*from_p));
6409 tree fndecl = get_callee_fndecl (*from_p);
6410 if (fndecl
6411 && fndecl_built_in_p (fndecl, BUILT_IN_EXPECT)
6412 && call_expr_nargs (*from_p) == 3)
6413 call_stmt = gimple_build_call_internal (IFN_BUILTIN_EXPECT, 3,
6414 CALL_EXPR_ARG (*from_p, 0),
6415 CALL_EXPR_ARG (*from_p, 1),
6416 CALL_EXPR_ARG (*from_p, 2));
6417 else
6419 call_stmt = gimple_build_call_from_tree (*from_p, fnptrtype);
6422 notice_special_calls (call_stmt);
6423 if (!gimple_call_noreturn_p (call_stmt) || !should_remove_lhs_p (*to_p))
6424 gimple_call_set_lhs (call_stmt, *to_p);
6425 else if (TREE_CODE (*to_p) == SSA_NAME)
6426 /* The above is somewhat premature, avoid ICEing later for a
6427 SSA name w/o a definition. We may have uses in the GIMPLE IL.
6428 ??? This doesn't make it a default-def. */
6429 SSA_NAME_DEF_STMT (*to_p) = gimple_build_nop ();
6431 assign = call_stmt;
6433 else
6435 assign = gimple_build_assign (*to_p, *from_p);
6436 gimple_set_location (assign, EXPR_LOCATION (*expr_p));
6437 if (COMPARISON_CLASS_P (*from_p))
6438 copy_warning (assign, *from_p);
6441 if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p))
6443 /* We should have got an SSA name from the start. */
6444 gcc_assert (TREE_CODE (*to_p) == SSA_NAME
6445 || ! gimple_in_ssa_p (cfun));
6448 gimplify_seq_add_stmt (pre_p, assign);
6449 gsi = gsi_last (*pre_p);
6450 maybe_fold_stmt (&gsi);
6452 if (want_value)
6454 *expr_p = TREE_THIS_VOLATILE (*to_p) ? *from_p : unshare_expr (*to_p);
6455 return GS_OK;
6457 else
6458 *expr_p = NULL;
6460 return GS_ALL_DONE;
6463 /* Gimplify a comparison between two variable-sized objects. Do this
6464 with a call to BUILT_IN_MEMCMP. */
6466 static enum gimplify_status
6467 gimplify_variable_sized_compare (tree *expr_p)
6469 location_t loc = EXPR_LOCATION (*expr_p);
6470 tree op0 = TREE_OPERAND (*expr_p, 0);
6471 tree op1 = TREE_OPERAND (*expr_p, 1);
6472 tree t, arg, dest, src, expr;
6474 arg = TYPE_SIZE_UNIT (TREE_TYPE (op0));
6475 arg = unshare_expr (arg);
6476 arg = SUBSTITUTE_PLACEHOLDER_IN_EXPR (arg, op0);
6477 src = build_fold_addr_expr_loc (loc, op1);
6478 dest = build_fold_addr_expr_loc (loc, op0);
6479 t = builtin_decl_implicit (BUILT_IN_MEMCMP);
6480 t = build_call_expr_loc (loc, t, 3, dest, src, arg);
6482 expr
6483 = build2 (TREE_CODE (*expr_p), TREE_TYPE (*expr_p), t, integer_zero_node);
6484 SET_EXPR_LOCATION (expr, loc);
6485 *expr_p = expr;
6487 return GS_OK;
6490 /* Gimplify a comparison between two aggregate objects of integral scalar
6491 mode as a comparison between the bitwise equivalent scalar values. */
6493 static enum gimplify_status
6494 gimplify_scalar_mode_aggregate_compare (tree *expr_p)
6496 location_t loc = EXPR_LOCATION (*expr_p);
6497 tree op0 = TREE_OPERAND (*expr_p, 0);
6498 tree op1 = TREE_OPERAND (*expr_p, 1);
6500 tree type = TREE_TYPE (op0);
6501 tree scalar_type = lang_hooks.types.type_for_mode (TYPE_MODE (type), 1);
6503 op0 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op0);
6504 op1 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op1);
6506 *expr_p
6507 = fold_build2_loc (loc, TREE_CODE (*expr_p), TREE_TYPE (*expr_p), op0, op1);
6509 return GS_OK;
6512 /* Gimplify an expression sequence. This function gimplifies each
6513 expression and rewrites the original expression with the last
6514 expression of the sequence in GIMPLE form.
6516 PRE_P points to the list where the side effects for all the
6517 expressions in the sequence will be emitted.
6519 WANT_VALUE is true when the result of the last COMPOUND_EXPR is used. */
6521 static enum gimplify_status
6522 gimplify_compound_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
6524 tree t = *expr_p;
6528 tree *sub_p = &TREE_OPERAND (t, 0);
6530 if (TREE_CODE (*sub_p) == COMPOUND_EXPR)
6531 gimplify_compound_expr (sub_p, pre_p, false);
6532 else
6533 gimplify_stmt (sub_p, pre_p);
6535 t = TREE_OPERAND (t, 1);
6537 while (TREE_CODE (t) == COMPOUND_EXPR);
6539 *expr_p = t;
6540 if (want_value)
6541 return GS_OK;
6542 else
6544 gimplify_stmt (expr_p, pre_p);
6545 return GS_ALL_DONE;
6549 /* Gimplify a SAVE_EXPR node. EXPR_P points to the expression to
6550 gimplify. After gimplification, EXPR_P will point to a new temporary
6551 that holds the original value of the SAVE_EXPR node.
6553 PRE_P points to the list where side effects that must happen before
6554 *EXPR_P should be stored. */
6556 static enum gimplify_status
6557 gimplify_save_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6559 enum gimplify_status ret = GS_ALL_DONE;
6560 tree val;
6562 gcc_assert (TREE_CODE (*expr_p) == SAVE_EXPR);
6563 val = TREE_OPERAND (*expr_p, 0);
6565 if (val && TREE_TYPE (val) == error_mark_node)
6566 return GS_ERROR;
6568 /* If the SAVE_EXPR has not been resolved, then evaluate it once. */
6569 if (!SAVE_EXPR_RESOLVED_P (*expr_p))
6571 /* The operand may be a void-valued expression. It is
6572 being executed only for its side-effects. */
6573 if (TREE_TYPE (val) == void_type_node)
6575 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
6576 is_gimple_stmt, fb_none);
6577 val = NULL;
6579 else
6580 /* The temporary may not be an SSA name as later abnormal and EH
6581 control flow may invalidate use/def domination. When in SSA
6582 form then assume there are no such issues and SAVE_EXPRs only
6583 appear via GENERIC foldings. */
6584 val = get_initialized_tmp_var (val, pre_p, post_p,
6585 gimple_in_ssa_p (cfun));
6587 TREE_OPERAND (*expr_p, 0) = val;
6588 SAVE_EXPR_RESOLVED_P (*expr_p) = 1;
6591 *expr_p = val;
6593 return ret;
6596 /* Rewrite the ADDR_EXPR node pointed to by EXPR_P
6598 unary_expr
6599 : ...
6600 | '&' varname
6603 PRE_P points to the list where side effects that must happen before
6604 *EXPR_P should be stored.
6606 POST_P points to the list where side effects that must happen after
6607 *EXPR_P should be stored. */
6609 static enum gimplify_status
6610 gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6612 tree expr = *expr_p;
6613 tree op0 = TREE_OPERAND (expr, 0);
6614 enum gimplify_status ret;
6615 location_t loc = EXPR_LOCATION (*expr_p);
6617 switch (TREE_CODE (op0))
6619 case INDIRECT_REF:
6620 do_indirect_ref:
6621 /* Check if we are dealing with an expression of the form '&*ptr'.
6622 While the front end folds away '&*ptr' into 'ptr', these
6623 expressions may be generated internally by the compiler (e.g.,
6624 builtins like __builtin_va_end). */
6625 /* Caution: the silent array decomposition semantics we allow for
6626 ADDR_EXPR means we can't always discard the pair. */
6627 /* Gimplification of the ADDR_EXPR operand may drop
6628 cv-qualification conversions, so make sure we add them if
6629 needed. */
6631 tree op00 = TREE_OPERAND (op0, 0);
6632 tree t_expr = TREE_TYPE (expr);
6633 tree t_op00 = TREE_TYPE (op00);
6635 if (!useless_type_conversion_p (t_expr, t_op00))
6636 op00 = fold_convert_loc (loc, TREE_TYPE (expr), op00);
6637 *expr_p = op00;
6638 ret = GS_OK;
6640 break;
6642 case VIEW_CONVERT_EXPR:
6643 /* Take the address of our operand and then convert it to the type of
6644 this ADDR_EXPR.
6646 ??? The interactions of VIEW_CONVERT_EXPR and aliasing is not at
6647 all clear. The impact of this transformation is even less clear. */
6649 /* If the operand is a useless conversion, look through it. Doing so
6650 guarantees that the ADDR_EXPR and its operand will remain of the
6651 same type. */
6652 if (tree_ssa_useless_type_conversion (TREE_OPERAND (op0, 0)))
6653 op0 = TREE_OPERAND (op0, 0);
6655 *expr_p = fold_convert_loc (loc, TREE_TYPE (expr),
6656 build_fold_addr_expr_loc (loc,
6657 TREE_OPERAND (op0, 0)));
6658 ret = GS_OK;
6659 break;
6661 case MEM_REF:
6662 if (integer_zerop (TREE_OPERAND (op0, 1)))
6663 goto do_indirect_ref;
6665 /* fall through */
6667 default:
6668 /* If we see a call to a declared builtin or see its address
6669 being taken (we can unify those cases here) then we can mark
6670 the builtin for implicit generation by GCC. */
6671 if (TREE_CODE (op0) == FUNCTION_DECL
6672 && fndecl_built_in_p (op0, BUILT_IN_NORMAL)
6673 && builtin_decl_declared_p (DECL_FUNCTION_CODE (op0)))
6674 set_builtin_decl_implicit_p (DECL_FUNCTION_CODE (op0), true);
6676 /* We use fb_either here because the C frontend sometimes takes
6677 the address of a call that returns a struct; see
6678 gcc.dg/c99-array-lval-1.c. The gimplifier will correctly make
6679 the implied temporary explicit. */
6681 /* Make the operand addressable. */
6682 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, post_p,
6683 is_gimple_addressable, fb_either);
6684 if (ret == GS_ERROR)
6685 break;
6687 /* Then mark it. Beware that it may not be possible to do so directly
6688 if a temporary has been created by the gimplification. */
6689 prepare_gimple_addressable (&TREE_OPERAND (expr, 0), pre_p);
6691 op0 = TREE_OPERAND (expr, 0);
6693 /* For various reasons, the gimplification of the expression
6694 may have made a new INDIRECT_REF. */
6695 if (INDIRECT_REF_P (op0)
6696 || (TREE_CODE (op0) == MEM_REF
6697 && integer_zerop (TREE_OPERAND (op0, 1))))
6698 goto do_indirect_ref;
6700 mark_addressable (TREE_OPERAND (expr, 0));
6702 /* The FEs may end up building ADDR_EXPRs early on a decl with
6703 an incomplete type. Re-build ADDR_EXPRs in canonical form
6704 here. */
6705 if (!types_compatible_p (TREE_TYPE (op0), TREE_TYPE (TREE_TYPE (expr))))
6706 *expr_p = build_fold_addr_expr (op0);
6708 /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly. */
6709 recompute_tree_invariant_for_addr_expr (*expr_p);
6711 /* If we re-built the ADDR_EXPR add a conversion to the original type
6712 if required. */
6713 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
6714 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
6716 break;
6719 return ret;
6722 /* Gimplify the operands of an ASM_EXPR. Input operands should be a gimple
6723 value; output operands should be a gimple lvalue. */
6725 static enum gimplify_status
6726 gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6728 tree expr;
6729 int noutputs;
6730 const char **oconstraints;
6731 int i;
6732 tree link;
6733 const char *constraint;
6734 bool allows_mem, allows_reg, is_inout;
6735 enum gimplify_status ret, tret;
6736 gasm *stmt;
6737 vec<tree, va_gc> *inputs;
6738 vec<tree, va_gc> *outputs;
6739 vec<tree, va_gc> *clobbers;
6740 vec<tree, va_gc> *labels;
6741 tree link_next;
6743 expr = *expr_p;
6744 noutputs = list_length (ASM_OUTPUTS (expr));
6745 oconstraints = (const char **) alloca ((noutputs) * sizeof (const char *));
6747 inputs = NULL;
6748 outputs = NULL;
6749 clobbers = NULL;
6750 labels = NULL;
6752 ret = GS_ALL_DONE;
6753 link_next = NULL_TREE;
6754 for (i = 0, link = ASM_OUTPUTS (expr); link; ++i, link = link_next)
6756 bool ok;
6757 size_t constraint_len;
6759 link_next = TREE_CHAIN (link);
6761 oconstraints[i]
6762 = constraint
6763 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
6764 constraint_len = strlen (constraint);
6765 if (constraint_len == 0)
6766 continue;
6768 ok = parse_output_constraint (&constraint, i, 0, 0,
6769 &allows_mem, &allows_reg, &is_inout);
6770 if (!ok)
6772 ret = GS_ERROR;
6773 is_inout = false;
6776 /* If we can't make copies, we can only accept memory.
6777 Similarly for VLAs. */
6778 tree outtype = TREE_TYPE (TREE_VALUE (link));
6779 if (outtype != error_mark_node
6780 && (TREE_ADDRESSABLE (outtype)
6781 || !COMPLETE_TYPE_P (outtype)
6782 || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (outtype))))
6784 if (allows_mem)
6785 allows_reg = 0;
6786 else
6788 error ("impossible constraint in %<asm%>");
6789 error ("non-memory output %d must stay in memory", i);
6790 return GS_ERROR;
6794 if (!allows_reg && allows_mem)
6795 mark_addressable (TREE_VALUE (link));
6797 tree orig = TREE_VALUE (link);
6798 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6799 is_inout ? is_gimple_min_lval : is_gimple_lvalue,
6800 fb_lvalue | fb_mayfail);
6801 if (tret == GS_ERROR)
6803 if (orig != error_mark_node)
6804 error ("invalid lvalue in %<asm%> output %d", i);
6805 ret = tret;
6808 /* If the constraint does not allow memory make sure we gimplify
6809 it to a register if it is not already but its base is. This
6810 happens for complex and vector components. */
6811 if (!allows_mem)
6813 tree op = TREE_VALUE (link);
6814 if (! is_gimple_val (op)
6815 && is_gimple_reg_type (TREE_TYPE (op))
6816 && is_gimple_reg (get_base_address (op)))
6818 tree tem = create_tmp_reg (TREE_TYPE (op));
6819 tree ass;
6820 if (is_inout)
6822 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem),
6823 tem, unshare_expr (op));
6824 gimplify_and_add (ass, pre_p);
6826 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem), op, tem);
6827 gimplify_and_add (ass, post_p);
6829 TREE_VALUE (link) = tem;
6830 tret = GS_OK;
6834 vec_safe_push (outputs, link);
6835 TREE_CHAIN (link) = NULL_TREE;
6837 if (is_inout)
6839 /* An input/output operand. To give the optimizers more
6840 flexibility, split it into separate input and output
6841 operands. */
6842 tree input;
6843 /* Buffer big enough to format a 32-bit UINT_MAX into. */
6844 char buf[11];
6846 /* Turn the in/out constraint into an output constraint. */
6847 char *p = xstrdup (constraint);
6848 p[0] = '=';
6849 TREE_VALUE (TREE_PURPOSE (link)) = build_string (constraint_len, p);
6851 /* And add a matching input constraint. */
6852 if (allows_reg)
6854 sprintf (buf, "%u", i);
6856 /* If there are multiple alternatives in the constraint,
6857 handle each of them individually. Those that allow register
6858 will be replaced with operand number, the others will stay
6859 unchanged. */
6860 if (strchr (p, ',') != NULL)
6862 size_t len = 0, buflen = strlen (buf);
6863 char *beg, *end, *str, *dst;
6865 for (beg = p + 1;;)
6867 end = strchr (beg, ',');
6868 if (end == NULL)
6869 end = strchr (beg, '\0');
6870 if ((size_t) (end - beg) < buflen)
6871 len += buflen + 1;
6872 else
6873 len += end - beg + 1;
6874 if (*end)
6875 beg = end + 1;
6876 else
6877 break;
6880 str = (char *) alloca (len);
6881 for (beg = p + 1, dst = str;;)
6883 const char *tem;
6884 bool mem_p, reg_p, inout_p;
6886 end = strchr (beg, ',');
6887 if (end)
6888 *end = '\0';
6889 beg[-1] = '=';
6890 tem = beg - 1;
6891 parse_output_constraint (&tem, i, 0, 0,
6892 &mem_p, &reg_p, &inout_p);
6893 if (dst != str)
6894 *dst++ = ',';
6895 if (reg_p)
6897 memcpy (dst, buf, buflen);
6898 dst += buflen;
6900 else
6902 if (end)
6903 len = end - beg;
6904 else
6905 len = strlen (beg);
6906 memcpy (dst, beg, len);
6907 dst += len;
6909 if (end)
6910 beg = end + 1;
6911 else
6912 break;
6914 *dst = '\0';
6915 input = build_string (dst - str, str);
6917 else
6918 input = build_string (strlen (buf), buf);
6920 else
6921 input = build_string (constraint_len - 1, constraint + 1);
6923 free (p);
6925 input = build_tree_list (build_tree_list (NULL_TREE, input),
6926 unshare_expr (TREE_VALUE (link)));
6927 ASM_INPUTS (expr) = chainon (ASM_INPUTS (expr), input);
6931 link_next = NULL_TREE;
6932 for (link = ASM_INPUTS (expr); link; ++i, link = link_next)
6934 link_next = TREE_CHAIN (link);
6935 constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
6936 parse_input_constraint (&constraint, 0, 0, noutputs, 0,
6937 oconstraints, &allows_mem, &allows_reg);
6939 /* If we can't make copies, we can only accept memory. */
6940 tree intype = TREE_TYPE (TREE_VALUE (link));
6941 if (intype != error_mark_node
6942 && (TREE_ADDRESSABLE (intype)
6943 || !COMPLETE_TYPE_P (intype)
6944 || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (intype))))
6946 if (allows_mem)
6947 allows_reg = 0;
6948 else
6950 error ("impossible constraint in %<asm%>");
6951 error ("non-memory input %d must stay in memory", i);
6952 return GS_ERROR;
6956 /* If the operand is a memory input, it should be an lvalue. */
6957 if (!allows_reg && allows_mem)
6959 tree inputv = TREE_VALUE (link);
6960 STRIP_NOPS (inputv);
6961 if (TREE_CODE (inputv) == PREDECREMENT_EXPR
6962 || TREE_CODE (inputv) == PREINCREMENT_EXPR
6963 || TREE_CODE (inputv) == POSTDECREMENT_EXPR
6964 || TREE_CODE (inputv) == POSTINCREMENT_EXPR
6965 || TREE_CODE (inputv) == MODIFY_EXPR)
6966 TREE_VALUE (link) = error_mark_node;
6967 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6968 is_gimple_lvalue, fb_lvalue | fb_mayfail);
6969 if (tret != GS_ERROR)
6971 /* Unlike output operands, memory inputs are not guaranteed
6972 to be lvalues by the FE, and while the expressions are
6973 marked addressable there, if it is e.g. a statement
6974 expression, temporaries in it might not end up being
6975 addressable. They might be already used in the IL and thus
6976 it is too late to make them addressable now though. */
6977 tree x = TREE_VALUE (link);
6978 while (handled_component_p (x))
6979 x = TREE_OPERAND (x, 0);
6980 if (TREE_CODE (x) == MEM_REF
6981 && TREE_CODE (TREE_OPERAND (x, 0)) == ADDR_EXPR)
6982 x = TREE_OPERAND (TREE_OPERAND (x, 0), 0);
6983 if ((VAR_P (x)
6984 || TREE_CODE (x) == PARM_DECL
6985 || TREE_CODE (x) == RESULT_DECL)
6986 && !TREE_ADDRESSABLE (x)
6987 && is_gimple_reg (x))
6989 warning_at (EXPR_LOC_OR_LOC (TREE_VALUE (link),
6990 input_location), 0,
6991 "memory input %d is not directly addressable",
6993 prepare_gimple_addressable (&TREE_VALUE (link), pre_p);
6996 mark_addressable (TREE_VALUE (link));
6997 if (tret == GS_ERROR)
6999 if (inputv != error_mark_node)
7000 error_at (EXPR_LOC_OR_LOC (TREE_VALUE (link), input_location),
7001 "memory input %d is not directly addressable", i);
7002 ret = tret;
7005 else
7007 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
7008 is_gimple_asm_val, fb_rvalue);
7009 if (tret == GS_ERROR)
7010 ret = tret;
7013 TREE_CHAIN (link) = NULL_TREE;
7014 vec_safe_push (inputs, link);
7017 link_next = NULL_TREE;
7018 for (link = ASM_CLOBBERS (expr); link; ++i, link = link_next)
7020 link_next = TREE_CHAIN (link);
7021 TREE_CHAIN (link) = NULL_TREE;
7022 vec_safe_push (clobbers, link);
7025 link_next = NULL_TREE;
7026 for (link = ASM_LABELS (expr); link; ++i, link = link_next)
7028 link_next = TREE_CHAIN (link);
7029 TREE_CHAIN (link) = NULL_TREE;
7030 vec_safe_push (labels, link);
7033 /* Do not add ASMs with errors to the gimple IL stream. */
7034 if (ret != GS_ERROR)
7036 stmt = gimple_build_asm_vec (TREE_STRING_POINTER (ASM_STRING (expr)),
7037 inputs, outputs, clobbers, labels);
7039 /* asm is volatile if it was marked by the user as volatile or
7040 there are no outputs or this is an asm goto. */
7041 gimple_asm_set_volatile (stmt,
7042 ASM_VOLATILE_P (expr)
7043 || noutputs == 0
7044 || labels);
7045 gimple_asm_set_input (stmt, ASM_INPUT_P (expr));
7046 gimple_asm_set_inline (stmt, ASM_INLINE_P (expr));
7048 gimplify_seq_add_stmt (pre_p, stmt);
7051 return ret;
7054 /* Gimplify a CLEANUP_POINT_EXPR. Currently this works by adding
7055 GIMPLE_WITH_CLEANUP_EXPRs to the prequeue as we encounter cleanups while
7056 gimplifying the body, and converting them to TRY_FINALLY_EXPRs when we
7057 return to this function.
7059 FIXME should we complexify the prequeue handling instead? Or use flags
7060 for all the cleanups and let the optimizer tighten them up? The current
7061 code seems pretty fragile; it will break on a cleanup within any
7062 non-conditional nesting. But any such nesting would be broken, anyway;
7063 we can't write a TRY_FINALLY_EXPR that starts inside a nesting construct
7064 and continues out of it. We can do that at the RTL level, though, so
7065 having an optimizer to tighten up try/finally regions would be a Good
7066 Thing. */
7068 static enum gimplify_status
7069 gimplify_cleanup_point_expr (tree *expr_p, gimple_seq *pre_p)
7071 gimple_stmt_iterator iter;
7072 gimple_seq body_sequence = NULL;
7074 tree temp = voidify_wrapper_expr (*expr_p, NULL);
7076 /* We only care about the number of conditions between the innermost
7077 CLEANUP_POINT_EXPR and the cleanup. So save and reset the count and
7078 any cleanups collected outside the CLEANUP_POINT_EXPR. */
7079 int old_conds = gimplify_ctxp->conditions;
7080 gimple_seq old_cleanups = gimplify_ctxp->conditional_cleanups;
7081 bool old_in_cleanup_point_expr = gimplify_ctxp->in_cleanup_point_expr;
7082 gimplify_ctxp->conditions = 0;
7083 gimplify_ctxp->conditional_cleanups = NULL;
7084 gimplify_ctxp->in_cleanup_point_expr = true;
7086 gimplify_stmt (&TREE_OPERAND (*expr_p, 0), &body_sequence);
7088 gimplify_ctxp->conditions = old_conds;
7089 gimplify_ctxp->conditional_cleanups = old_cleanups;
7090 gimplify_ctxp->in_cleanup_point_expr = old_in_cleanup_point_expr;
7092 for (iter = gsi_start (body_sequence); !gsi_end_p (iter); )
7094 gimple *wce = gsi_stmt (iter);
7096 if (gimple_code (wce) == GIMPLE_WITH_CLEANUP_EXPR)
7098 if (gsi_one_before_end_p (iter))
7100 /* Note that gsi_insert_seq_before and gsi_remove do not
7101 scan operands, unlike some other sequence mutators. */
7102 if (!gimple_wce_cleanup_eh_only (wce))
7103 gsi_insert_seq_before_without_update (&iter,
7104 gimple_wce_cleanup (wce),
7105 GSI_SAME_STMT);
7106 gsi_remove (&iter, true);
7107 break;
7109 else
7111 gtry *gtry;
7112 gimple_seq seq;
7113 enum gimple_try_flags kind;
7115 if (gimple_wce_cleanup_eh_only (wce))
7116 kind = GIMPLE_TRY_CATCH;
7117 else
7118 kind = GIMPLE_TRY_FINALLY;
7119 seq = gsi_split_seq_after (iter);
7121 gtry = gimple_build_try (seq, gimple_wce_cleanup (wce), kind);
7122 /* Do not use gsi_replace here, as it may scan operands.
7123 We want to do a simple structural modification only. */
7124 gsi_set_stmt (&iter, gtry);
7125 iter = gsi_start (gtry->eval);
7128 else
7129 gsi_next (&iter);
7132 gimplify_seq_add_seq (pre_p, body_sequence);
7133 if (temp)
7135 *expr_p = temp;
7136 return GS_OK;
7138 else
7140 *expr_p = NULL;
7141 return GS_ALL_DONE;
7145 /* Insert a cleanup marker for gimplify_cleanup_point_expr. CLEANUP
7146 is the cleanup action required. EH_ONLY is true if the cleanup should
7147 only be executed if an exception is thrown, not on normal exit.
7148 If FORCE_UNCOND is true perform the cleanup unconditionally; this is
7149 only valid for clobbers. */
7151 static void
7152 gimple_push_cleanup (tree var, tree cleanup, bool eh_only, gimple_seq *pre_p,
7153 bool force_uncond = false)
7155 gimple *wce;
7156 gimple_seq cleanup_stmts = NULL;
7158 /* Errors can result in improperly nested cleanups. Which results in
7159 confusion when trying to resolve the GIMPLE_WITH_CLEANUP_EXPR. */
7160 if (seen_error ())
7161 return;
7163 if (gimple_conditional_context ())
7165 /* If we're in a conditional context, this is more complex. We only
7166 want to run the cleanup if we actually ran the initialization that
7167 necessitates it, but we want to run it after the end of the
7168 conditional context. So we wrap the try/finally around the
7169 condition and use a flag to determine whether or not to actually
7170 run the destructor. Thus
7172 test ? f(A()) : 0
7174 becomes (approximately)
7176 flag = 0;
7177 try {
7178 if (test) { A::A(temp); flag = 1; val = f(temp); }
7179 else { val = 0; }
7180 } finally {
7181 if (flag) A::~A(temp);
7185 if (force_uncond)
7187 gimplify_stmt (&cleanup, &cleanup_stmts);
7188 wce = gimple_build_wce (cleanup_stmts);
7189 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
7191 else
7193 tree flag = create_tmp_var (boolean_type_node, "cleanup");
7194 gassign *ffalse = gimple_build_assign (flag, boolean_false_node);
7195 gassign *ftrue = gimple_build_assign (flag, boolean_true_node);
7197 cleanup = build3 (COND_EXPR, void_type_node, flag, cleanup, NULL);
7198 gimplify_stmt (&cleanup, &cleanup_stmts);
7199 wce = gimple_build_wce (cleanup_stmts);
7200 gimple_wce_set_cleanup_eh_only (wce, eh_only);
7202 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, ffalse);
7203 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
7204 gimplify_seq_add_stmt (pre_p, ftrue);
7206 /* Because of this manipulation, and the EH edges that jump
7207 threading cannot redirect, the temporary (VAR) will appear
7208 to be used uninitialized. Don't warn. */
7209 suppress_warning (var, OPT_Wuninitialized);
7212 else
7214 gimplify_stmt (&cleanup, &cleanup_stmts);
7215 wce = gimple_build_wce (cleanup_stmts);
7216 gimple_wce_set_cleanup_eh_only (wce, eh_only);
7217 gimplify_seq_add_stmt (pre_p, wce);
7221 /* Gimplify a TARGET_EXPR which doesn't appear on the rhs of an INIT_EXPR. */
7223 static enum gimplify_status
7224 gimplify_target_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
7226 tree targ = *expr_p;
7227 tree temp = TARGET_EXPR_SLOT (targ);
7228 tree init = TARGET_EXPR_INITIAL (targ);
7229 enum gimplify_status ret;
7231 bool unpoison_empty_seq = false;
7232 gimple_stmt_iterator unpoison_it;
7234 if (init)
7236 gimple_seq init_pre_p = NULL;
7238 /* TARGET_EXPR temps aren't part of the enclosing block, so add it
7239 to the temps list. Handle also variable length TARGET_EXPRs. */
7240 if (!poly_int_tree_p (DECL_SIZE (temp)))
7242 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (temp)))
7243 gimplify_type_sizes (TREE_TYPE (temp), &init_pre_p);
7244 /* FIXME: this is correct only when the size of the type does
7245 not depend on expressions evaluated in init. */
7246 gimplify_vla_decl (temp, &init_pre_p);
7248 else
7250 /* Save location where we need to place unpoisoning. It's possible
7251 that a variable will be converted to needs_to_live_in_memory. */
7252 unpoison_it = gsi_last (*pre_p);
7253 unpoison_empty_seq = gsi_end_p (unpoison_it);
7255 gimple_add_tmp_var (temp);
7258 /* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the
7259 expression is supposed to initialize the slot. */
7260 if (VOID_TYPE_P (TREE_TYPE (init)))
7261 ret = gimplify_expr (&init, &init_pre_p, post_p, is_gimple_stmt,
7262 fb_none);
7263 else
7265 tree init_expr = build2 (INIT_EXPR, void_type_node, temp, init);
7266 init = init_expr;
7267 ret = gimplify_expr (&init, &init_pre_p, post_p, is_gimple_stmt,
7268 fb_none);
7269 init = NULL;
7270 ggc_free (init_expr);
7272 if (ret == GS_ERROR)
7274 /* PR c++/28266 Make sure this is expanded only once. */
7275 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
7276 return GS_ERROR;
7279 if (init)
7280 gimplify_and_add (init, &init_pre_p);
7282 /* Add a clobber for the temporary going out of scope, like
7283 gimplify_bind_expr. But only if we did not promote the
7284 temporary to static storage. */
7285 if (gimplify_ctxp->in_cleanup_point_expr
7286 && !TREE_STATIC (temp)
7287 && needs_to_live_in_memory (temp))
7289 if (flag_stack_reuse == SR_ALL)
7291 tree clobber = build_clobber (TREE_TYPE (temp), CLOBBER_EOL);
7292 clobber = build2 (MODIFY_EXPR, TREE_TYPE (temp), temp, clobber);
7293 gimple_push_cleanup (temp, clobber, false, pre_p, true);
7295 if (asan_poisoned_variables
7296 && DECL_ALIGN (temp) <= MAX_SUPPORTED_STACK_ALIGNMENT
7297 && !TREE_STATIC (temp)
7298 && dbg_cnt (asan_use_after_scope)
7299 && !gimplify_omp_ctxp)
7301 tree asan_cleanup = build_asan_poison_call_expr (temp);
7302 if (asan_cleanup)
7304 if (unpoison_empty_seq)
7305 unpoison_it = gsi_start (*pre_p);
7307 asan_poison_variable (temp, false, &unpoison_it,
7308 unpoison_empty_seq);
7309 gimple_push_cleanup (temp, asan_cleanup, false, pre_p);
7314 gimple_seq_add_seq (pre_p, init_pre_p);
7316 /* If needed, push the cleanup for the temp. */
7317 if (TARGET_EXPR_CLEANUP (targ))
7318 gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ),
7319 CLEANUP_EH_ONLY (targ), pre_p);
7321 /* Only expand this once. */
7322 TREE_OPERAND (targ, 3) = init;
7323 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
7325 else
7326 /* We should have expanded this before. */
7327 gcc_assert (DECL_SEEN_IN_BIND_EXPR_P (temp));
7329 *expr_p = temp;
7330 return GS_OK;
7333 /* Gimplification of expression trees. */
7335 /* Gimplify an expression which appears at statement context. The
7336 corresponding GIMPLE statements are added to *SEQ_P. If *SEQ_P is
7337 NULL, a new sequence is allocated.
7339 Return true if we actually added a statement to the queue. */
7341 bool
7342 gimplify_stmt (tree *stmt_p, gimple_seq *seq_p)
7344 gimple_seq_node last;
7346 last = gimple_seq_last (*seq_p);
7347 gimplify_expr (stmt_p, seq_p, NULL, is_gimple_stmt, fb_none);
7348 return last != gimple_seq_last (*seq_p);
7351 /* Add FIRSTPRIVATE entries for DECL in the OpenMP the surrounding parallels
7352 to CTX. If entries already exist, force them to be some flavor of private.
7353 If there is no enclosing parallel, do nothing. */
7355 void
7356 omp_firstprivatize_variable (struct gimplify_omp_ctx *ctx, tree decl)
7358 splay_tree_node n;
7360 if (decl == NULL || !DECL_P (decl) || ctx->region_type == ORT_NONE)
7361 return;
7365 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7366 if (n != NULL)
7368 if (n->value & GOVD_SHARED)
7369 n->value = GOVD_FIRSTPRIVATE | (n->value & GOVD_SEEN);
7370 else if (n->value & GOVD_MAP)
7371 n->value |= GOVD_MAP_TO_ONLY;
7372 else
7373 return;
7375 else if ((ctx->region_type & ORT_TARGET) != 0)
7377 if (ctx->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE)
7378 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
7379 else
7380 omp_add_variable (ctx, decl, GOVD_MAP | GOVD_MAP_TO_ONLY);
7382 else if (ctx->region_type != ORT_WORKSHARE
7383 && ctx->region_type != ORT_TASKGROUP
7384 && ctx->region_type != ORT_SIMD
7385 && ctx->region_type != ORT_ACC
7386 && !(ctx->region_type & ORT_TARGET_DATA))
7387 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
7389 ctx = ctx->outer_context;
7391 while (ctx);
7394 /* Similarly for each of the type sizes of TYPE. */
7396 static void
7397 omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type)
7399 if (type == NULL || type == error_mark_node)
7400 return;
7401 type = TYPE_MAIN_VARIANT (type);
7403 if (ctx->privatized_types->add (type))
7404 return;
7406 switch (TREE_CODE (type))
7408 case INTEGER_TYPE:
7409 case ENUMERAL_TYPE:
7410 case BOOLEAN_TYPE:
7411 case REAL_TYPE:
7412 case FIXED_POINT_TYPE:
7413 omp_firstprivatize_variable (ctx, TYPE_MIN_VALUE (type));
7414 omp_firstprivatize_variable (ctx, TYPE_MAX_VALUE (type));
7415 break;
7417 case ARRAY_TYPE:
7418 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
7419 omp_firstprivatize_type_sizes (ctx, TYPE_DOMAIN (type));
7420 break;
7422 case RECORD_TYPE:
7423 case UNION_TYPE:
7424 case QUAL_UNION_TYPE:
7426 tree field;
7427 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
7428 if (TREE_CODE (field) == FIELD_DECL)
7430 omp_firstprivatize_variable (ctx, DECL_FIELD_OFFSET (field));
7431 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (field));
7434 break;
7436 case POINTER_TYPE:
7437 case REFERENCE_TYPE:
7438 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
7439 break;
7441 default:
7442 break;
7445 omp_firstprivatize_variable (ctx, TYPE_SIZE (type));
7446 omp_firstprivatize_variable (ctx, TYPE_SIZE_UNIT (type));
7447 lang_hooks.types.omp_firstprivatize_type_sizes (ctx, type);
7450 /* Add an entry for DECL in the OMP context CTX with FLAGS. */
7452 static void
7453 omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
7455 splay_tree_node n;
7456 unsigned int nflags;
7457 tree t;
7459 if (error_operand_p (decl) || ctx->region_type == ORT_NONE)
7460 return;
7462 /* Never elide decls whose type has TREE_ADDRESSABLE set. This means
7463 there are constructors involved somewhere. Exception is a shared clause,
7464 there is nothing privatized in that case. */
7465 if ((flags & GOVD_SHARED) == 0
7466 && (TREE_ADDRESSABLE (TREE_TYPE (decl))
7467 || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))))
7468 flags |= GOVD_SEEN;
7470 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7471 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
7473 /* We shouldn't be re-adding the decl with the same data
7474 sharing class. */
7475 gcc_assert ((n->value & GOVD_DATA_SHARE_CLASS & flags) == 0);
7476 nflags = n->value | flags;
7477 /* The only combination of data sharing classes we should see is
7478 FIRSTPRIVATE and LASTPRIVATE. However, OpenACC permits
7479 reduction variables to be used in data sharing clauses. */
7480 gcc_assert ((ctx->region_type & ORT_ACC) != 0
7481 || ((nflags & GOVD_DATA_SHARE_CLASS)
7482 == (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE))
7483 || (flags & GOVD_DATA_SHARE_CLASS) == 0);
7484 n->value = nflags;
7485 return;
7488 /* When adding a variable-sized variable, we have to handle all sorts
7489 of additional bits of data: the pointer replacement variable, and
7490 the parameters of the type. */
7491 if (DECL_SIZE (decl) && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
7493 /* Add the pointer replacement variable as PRIVATE if the variable
7494 replacement is private, else FIRSTPRIVATE since we'll need the
7495 address of the original variable either for SHARED, or for the
7496 copy into or out of the context. */
7497 if (!(flags & GOVD_LOCAL) && ctx->region_type != ORT_TASKGROUP)
7499 if (flags & GOVD_MAP)
7500 nflags = GOVD_MAP | GOVD_MAP_TO_ONLY | GOVD_EXPLICIT;
7501 else if (flags & GOVD_PRIVATE)
7502 nflags = GOVD_PRIVATE;
7503 else if (((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
7504 && (flags & GOVD_FIRSTPRIVATE))
7505 || (ctx->region_type == ORT_TARGET_DATA
7506 && (flags & GOVD_DATA_SHARE_CLASS) == 0))
7507 nflags = GOVD_PRIVATE | GOVD_EXPLICIT;
7508 else
7509 nflags = GOVD_FIRSTPRIVATE;
7510 nflags |= flags & GOVD_SEEN;
7511 t = DECL_VALUE_EXPR (decl);
7512 gcc_assert (INDIRECT_REF_P (t));
7513 t = TREE_OPERAND (t, 0);
7514 gcc_assert (DECL_P (t));
7515 omp_add_variable (ctx, t, nflags);
7518 /* Add all of the variable and type parameters (which should have
7519 been gimplified to a formal temporary) as FIRSTPRIVATE. */
7520 omp_firstprivatize_variable (ctx, DECL_SIZE_UNIT (decl));
7521 omp_firstprivatize_variable (ctx, DECL_SIZE (decl));
7522 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
7524 /* The variable-sized variable itself is never SHARED, only some form
7525 of PRIVATE. The sharing would take place via the pointer variable
7526 which we remapped above. */
7527 if (flags & GOVD_SHARED)
7528 flags = GOVD_SHARED | GOVD_DEBUG_PRIVATE
7529 | (flags & (GOVD_SEEN | GOVD_EXPLICIT));
7531 /* We're going to make use of the TYPE_SIZE_UNIT at least in the
7532 alloca statement we generate for the variable, so make sure it
7533 is available. This isn't automatically needed for the SHARED
7534 case, since we won't be allocating local storage then.
7535 For local variables TYPE_SIZE_UNIT might not be gimplified yet,
7536 in this case omp_notice_variable will be called later
7537 on when it is gimplified. */
7538 else if (! (flags & (GOVD_LOCAL | GOVD_MAP))
7539 && DECL_P (TYPE_SIZE_UNIT (TREE_TYPE (decl))))
7540 omp_notice_variable (ctx, TYPE_SIZE_UNIT (TREE_TYPE (decl)), true);
7542 else if ((flags & (GOVD_MAP | GOVD_LOCAL)) == 0
7543 && omp_privatize_by_reference (decl))
7545 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
7547 /* Similar to the direct variable sized case above, we'll need the
7548 size of references being privatized. */
7549 if ((flags & GOVD_SHARED) == 0)
7551 t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
7552 if (t && DECL_P (t))
7553 omp_notice_variable (ctx, t, true);
7557 if (n != NULL)
7558 n->value |= flags;
7559 else
7560 splay_tree_insert (ctx->variables, (splay_tree_key)decl, flags);
7562 /* For reductions clauses in OpenACC loop directives, by default create a
7563 copy clause on the enclosing parallel construct for carrying back the
7564 results. */
7565 if (ctx->region_type == ORT_ACC && (flags & GOVD_REDUCTION))
7567 struct gimplify_omp_ctx *outer_ctx = ctx->outer_context;
7568 while (outer_ctx)
7570 n = splay_tree_lookup (outer_ctx->variables, (splay_tree_key)decl);
7571 if (n != NULL)
7573 /* Ignore local variables and explicitly declared clauses. */
7574 if (n->value & (GOVD_LOCAL | GOVD_EXPLICIT))
7575 break;
7576 else if (outer_ctx->region_type == ORT_ACC_KERNELS)
7578 /* According to the OpenACC spec, such a reduction variable
7579 should already have a copy map on a kernels construct,
7580 verify that here. */
7581 gcc_assert (!(n->value & GOVD_FIRSTPRIVATE)
7582 && (n->value & GOVD_MAP));
7584 else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
7586 /* Remove firstprivate and make it a copy map. */
7587 n->value &= ~GOVD_FIRSTPRIVATE;
7588 n->value |= GOVD_MAP;
7591 else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
7593 splay_tree_insert (outer_ctx->variables, (splay_tree_key)decl,
7594 GOVD_MAP | GOVD_SEEN);
7595 break;
7597 outer_ctx = outer_ctx->outer_context;
7602 /* Notice a threadprivate variable DECL used in OMP context CTX.
7603 This just prints out diagnostics about threadprivate variable uses
7604 in untied tasks. If DECL2 is non-NULL, prevent this warning
7605 on that variable. */
7607 static bool
7608 omp_notice_threadprivate_variable (struct gimplify_omp_ctx *ctx, tree decl,
7609 tree decl2)
7611 splay_tree_node n;
7612 struct gimplify_omp_ctx *octx;
7614 for (octx = ctx; octx; octx = octx->outer_context)
7615 if ((octx->region_type & ORT_TARGET) != 0
7616 || octx->order_concurrent)
7618 n = splay_tree_lookup (octx->variables, (splay_tree_key)decl);
7619 if (n == NULL)
7621 if (octx->order_concurrent)
7623 error ("threadprivate variable %qE used in a region with"
7624 " %<order(concurrent)%> clause", DECL_NAME (decl));
7625 inform (octx->location, "enclosing region");
7627 else
7629 error ("threadprivate variable %qE used in target region",
7630 DECL_NAME (decl));
7631 inform (octx->location, "enclosing target region");
7633 splay_tree_insert (octx->variables, (splay_tree_key)decl, 0);
7635 if (decl2)
7636 splay_tree_insert (octx->variables, (splay_tree_key)decl2, 0);
7639 if (ctx->region_type != ORT_UNTIED_TASK)
7640 return false;
7641 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7642 if (n == NULL)
7644 error ("threadprivate variable %qE used in untied task",
7645 DECL_NAME (decl));
7646 inform (ctx->location, "enclosing task");
7647 splay_tree_insert (ctx->variables, (splay_tree_key)decl, 0);
7649 if (decl2)
7650 splay_tree_insert (ctx->variables, (splay_tree_key)decl2, 0);
7651 return false;
7654 /* Return true if global var DECL is device resident. */
7656 static bool
7657 device_resident_p (tree decl)
7659 tree attr = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (decl));
7661 if (!attr)
7662 return false;
7664 for (tree t = TREE_VALUE (attr); t; t = TREE_PURPOSE (t))
7666 tree c = TREE_VALUE (t);
7667 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DEVICE_RESIDENT)
7668 return true;
7671 return false;
7674 /* Return true if DECL has an ACC DECLARE attribute. */
7676 static bool
7677 is_oacc_declared (tree decl)
7679 tree t = TREE_CODE (decl) == MEM_REF ? TREE_OPERAND (decl, 0) : decl;
7680 tree declared = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (t));
7681 return declared != NULL_TREE;
7684 /* Determine outer default flags for DECL mentioned in an OMP region
7685 but not declared in an enclosing clause.
7687 ??? Some compiler-generated variables (like SAVE_EXPRs) could be
7688 remapped firstprivate instead of shared. To some extent this is
7689 addressed in omp_firstprivatize_type_sizes, but not
7690 effectively. */
7692 static unsigned
7693 omp_default_clause (struct gimplify_omp_ctx *ctx, tree decl,
7694 bool in_code, unsigned flags)
7696 enum omp_clause_default_kind default_kind = ctx->default_kind;
7697 enum omp_clause_default_kind kind;
7699 kind = lang_hooks.decls.omp_predetermined_sharing (decl);
7700 if (ctx->region_type & ORT_TASK)
7702 tree detach_clause = omp_find_clause (ctx->clauses, OMP_CLAUSE_DETACH);
7704 /* The event-handle specified by a detach clause should always be firstprivate,
7705 regardless of the current default. */
7706 if (detach_clause && OMP_CLAUSE_DECL (detach_clause) == decl)
7707 kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
7709 if (kind != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
7710 default_kind = kind;
7711 else if (VAR_P (decl) && TREE_STATIC (decl) && DECL_IN_CONSTANT_POOL (decl))
7712 default_kind = OMP_CLAUSE_DEFAULT_SHARED;
7713 /* For C/C++ default({,first}private), variables with static storage duration
7714 declared in a namespace or global scope and referenced in construct
7715 must be explicitly specified, i.e. acts as default(none). */
7716 else if ((default_kind == OMP_CLAUSE_DEFAULT_PRIVATE
7717 || default_kind == OMP_CLAUSE_DEFAULT_FIRSTPRIVATE)
7718 && VAR_P (decl)
7719 && is_global_var (decl)
7720 && (DECL_FILE_SCOPE_P (decl)
7721 || (DECL_CONTEXT (decl)
7722 && TREE_CODE (DECL_CONTEXT (decl)) == NAMESPACE_DECL))
7723 && !lang_GNU_Fortran ())
7724 default_kind = OMP_CLAUSE_DEFAULT_NONE;
7726 switch (default_kind)
7728 case OMP_CLAUSE_DEFAULT_NONE:
7730 const char *rtype;
7732 if (ctx->region_type & ORT_PARALLEL)
7733 rtype = "parallel";
7734 else if ((ctx->region_type & ORT_TASKLOOP) == ORT_TASKLOOP)
7735 rtype = "taskloop";
7736 else if (ctx->region_type & ORT_TASK)
7737 rtype = "task";
7738 else if (ctx->region_type & ORT_TEAMS)
7739 rtype = "teams";
7740 else
7741 gcc_unreachable ();
7743 error ("%qE not specified in enclosing %qs",
7744 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rtype);
7745 inform (ctx->location, "enclosing %qs", rtype);
7747 /* FALLTHRU */
7748 case OMP_CLAUSE_DEFAULT_SHARED:
7749 flags |= GOVD_SHARED;
7750 break;
7751 case OMP_CLAUSE_DEFAULT_PRIVATE:
7752 flags |= GOVD_PRIVATE;
7753 break;
7754 case OMP_CLAUSE_DEFAULT_FIRSTPRIVATE:
7755 flags |= GOVD_FIRSTPRIVATE;
7756 break;
7757 case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
7758 /* decl will be either GOVD_FIRSTPRIVATE or GOVD_SHARED. */
7759 gcc_assert ((ctx->region_type & ORT_TASK) != 0);
7760 if (struct gimplify_omp_ctx *octx = ctx->outer_context)
7762 omp_notice_variable (octx, decl, in_code);
7763 for (; octx; octx = octx->outer_context)
7765 splay_tree_node n2;
7767 n2 = splay_tree_lookup (octx->variables, (splay_tree_key) decl);
7768 if ((octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)) != 0
7769 && (n2 == NULL || (n2->value & GOVD_DATA_SHARE_CLASS) == 0))
7770 continue;
7771 if (n2 && (n2->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED)
7773 flags |= GOVD_FIRSTPRIVATE;
7774 goto found_outer;
7776 if ((octx->region_type & (ORT_PARALLEL | ORT_TEAMS)) != 0)
7778 flags |= GOVD_SHARED;
7779 goto found_outer;
7784 if (TREE_CODE (decl) == PARM_DECL
7785 || (!is_global_var (decl)
7786 && DECL_CONTEXT (decl) == current_function_decl))
7787 flags |= GOVD_FIRSTPRIVATE;
7788 else
7789 flags |= GOVD_SHARED;
7790 found_outer:
7791 break;
7793 default:
7794 gcc_unreachable ();
7797 return flags;
7800 /* Return string name for types of OpenACC constructs from ORT_* values. */
7802 static const char *
7803 oacc_region_type_name (enum omp_region_type region_type)
7805 switch (region_type)
7807 case ORT_ACC_DATA:
7808 return "data";
7809 case ORT_ACC_PARALLEL:
7810 return "parallel";
7811 case ORT_ACC_KERNELS:
7812 return "kernels";
7813 case ORT_ACC_SERIAL:
7814 return "serial";
7815 default:
7816 gcc_unreachable ();
7820 /* Determine outer default flags for DECL mentioned in an OACC region
7821 but not declared in an enclosing clause. */
7823 static unsigned
7824 oacc_default_clause (struct gimplify_omp_ctx *ctx, tree decl, unsigned flags)
7826 struct gimplify_omp_ctx *ctx_default = ctx;
7827 /* If no 'default' clause appears on this compute construct... */
7828 if (ctx_default->default_kind == OMP_CLAUSE_DEFAULT_SHARED)
7830 /* ..., see if one appears on a lexically containing 'data'
7831 construct. */
7832 while ((ctx_default = ctx_default->outer_context))
7834 if (ctx_default->region_type == ORT_ACC_DATA
7835 && ctx_default->default_kind != OMP_CLAUSE_DEFAULT_SHARED)
7836 break;
7838 /* If not, reset. */
7839 if (!ctx_default)
7840 ctx_default = ctx;
7843 bool on_device = false;
7844 bool is_private = false;
7845 bool declared = is_oacc_declared (decl);
7846 tree type = TREE_TYPE (decl);
7848 if (omp_privatize_by_reference (decl))
7849 type = TREE_TYPE (type);
7851 /* For Fortran COMMON blocks, only used variables in those blocks are
7852 transfered and remapped. The block itself will have a private clause to
7853 avoid transfering the data twice.
7854 The hook evaluates to false by default. For a variable in Fortran's COMMON
7855 or EQUIVALENCE block, returns 'true' (as we have shared=false) - as only
7856 the variables in such a COMMON/EQUIVALENCE block shall be privatized not
7857 the whole block. For C++ and Fortran, it can also be true under certain
7858 other conditions, if DECL_HAS_VALUE_EXPR. */
7859 if (RECORD_OR_UNION_TYPE_P (type))
7860 is_private = lang_hooks.decls.omp_disregard_value_expr (decl, false);
7862 if ((ctx->region_type & (ORT_ACC_PARALLEL | ORT_ACC_KERNELS)) != 0
7863 && is_global_var (decl)
7864 && device_resident_p (decl)
7865 && !is_private)
7867 on_device = true;
7868 flags |= GOVD_MAP_TO_ONLY;
7871 switch (ctx->region_type)
7873 case ORT_ACC_KERNELS:
7874 if (is_private)
7875 flags |= GOVD_FIRSTPRIVATE;
7876 else if (AGGREGATE_TYPE_P (type))
7878 /* Aggregates default to 'present_or_copy', or 'present'. */
7879 if (ctx_default->default_kind != OMP_CLAUSE_DEFAULT_PRESENT)
7880 flags |= GOVD_MAP;
7881 else
7882 flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
7884 else
7885 /* Scalars default to 'copy'. */
7886 flags |= GOVD_MAP | GOVD_MAP_FORCE;
7888 break;
7890 case ORT_ACC_PARALLEL:
7891 case ORT_ACC_SERIAL:
7892 if (is_private)
7893 flags |= GOVD_FIRSTPRIVATE;
7894 else if (on_device || declared)
7895 flags |= GOVD_MAP;
7896 else if (AGGREGATE_TYPE_P (type))
7898 /* Aggregates default to 'present_or_copy', or 'present'. */
7899 if (ctx_default->default_kind != OMP_CLAUSE_DEFAULT_PRESENT)
7900 flags |= GOVD_MAP;
7901 else
7902 flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
7904 else
7905 /* Scalars default to 'firstprivate'. */
7906 flags |= GOVD_FIRSTPRIVATE;
7908 break;
7910 default:
7911 gcc_unreachable ();
7914 if (DECL_ARTIFICIAL (decl))
7915 ; /* We can get compiler-generated decls, and should not complain
7916 about them. */
7917 else if (ctx_default->default_kind == OMP_CLAUSE_DEFAULT_NONE)
7919 error ("%qE not specified in enclosing OpenACC %qs construct",
7920 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)),
7921 oacc_region_type_name (ctx->region_type));
7922 if (ctx_default != ctx)
7923 inform (ctx->location, "enclosing OpenACC %qs construct and",
7924 oacc_region_type_name (ctx->region_type));
7925 inform (ctx_default->location,
7926 "enclosing OpenACC %qs construct with %qs clause",
7927 oacc_region_type_name (ctx_default->region_type),
7928 "default(none)");
7930 else if (ctx_default->default_kind == OMP_CLAUSE_DEFAULT_PRESENT)
7931 ; /* Handled above. */
7932 else
7933 gcc_checking_assert (ctx_default->default_kind == OMP_CLAUSE_DEFAULT_SHARED);
7935 return flags;
7938 /* Record the fact that DECL was used within the OMP context CTX.
7939 IN_CODE is true when real code uses DECL, and false when we should
7940 merely emit default(none) errors. Return true if DECL is going to
7941 be remapped and thus DECL shouldn't be gimplified into its
7942 DECL_VALUE_EXPR (if any). */
7944 static bool
7945 omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
7947 splay_tree_node n;
7948 unsigned flags = in_code ? GOVD_SEEN : 0;
7949 bool ret = false, shared;
7951 if (error_operand_p (decl))
7952 return false;
7954 if (DECL_ARTIFICIAL (decl))
7956 tree attr = lookup_attribute ("omp allocate var", DECL_ATTRIBUTES (decl));
7957 if (attr)
7958 decl = TREE_VALUE (TREE_VALUE (attr));
7961 if (ctx->region_type == ORT_NONE)
7962 return lang_hooks.decls.omp_disregard_value_expr (decl, false);
7964 if (is_global_var (decl))
7966 /* Threadprivate variables are predetermined. */
7967 if (DECL_THREAD_LOCAL_P (decl))
7968 return omp_notice_threadprivate_variable (ctx, decl, NULL_TREE);
7970 if (DECL_HAS_VALUE_EXPR_P (decl))
7972 if (ctx->region_type & ORT_ACC)
7973 /* For OpenACC, defer expansion of value to avoid transfering
7974 privatized common block data instead of im-/explicitly transfered
7975 variables which are in common blocks. */
7977 else
7979 tree value = get_base_address (DECL_VALUE_EXPR (decl));
7981 if (value && DECL_P (value) && DECL_THREAD_LOCAL_P (value))
7982 return omp_notice_threadprivate_variable (ctx, decl, value);
7986 if (gimplify_omp_ctxp->outer_context == NULL
7987 && VAR_P (decl)
7988 && oacc_get_fn_attrib (current_function_decl))
7990 location_t loc = DECL_SOURCE_LOCATION (decl);
7992 if (lookup_attribute ("omp declare target link",
7993 DECL_ATTRIBUTES (decl)))
7995 error_at (loc,
7996 "%qE with %<link%> clause used in %<routine%> function",
7997 DECL_NAME (decl));
7998 return false;
8000 else if (!lookup_attribute ("omp declare target",
8001 DECL_ATTRIBUTES (decl)))
8003 error_at (loc,
8004 "%qE requires a %<declare%> directive for use "
8005 "in a %<routine%> function", DECL_NAME (decl));
8006 return false;
8011 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
8012 if ((ctx->region_type & ORT_TARGET) != 0)
8014 if (ctx->region_type & ORT_ACC)
8015 /* For OpenACC, as remarked above, defer expansion. */
8016 shared = false;
8017 else
8018 shared = true;
8020 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
8021 if (n == NULL)
8023 unsigned nflags = flags;
8024 if ((ctx->region_type & ORT_ACC) == 0)
8026 bool is_declare_target = false;
8027 if (is_global_var (decl)
8028 && varpool_node::get_create (decl)->offloadable)
8030 struct gimplify_omp_ctx *octx;
8031 for (octx = ctx->outer_context;
8032 octx; octx = octx->outer_context)
8034 n = splay_tree_lookup (octx->variables,
8035 (splay_tree_key)decl);
8036 if (n
8037 && (n->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED
8038 && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
8039 break;
8041 is_declare_target = octx == NULL;
8043 if (!is_declare_target)
8045 int gdmk;
8046 enum omp_clause_defaultmap_kind kind;
8047 if (lang_hooks.decls.omp_allocatable_p (decl))
8048 gdmk = GDMK_ALLOCATABLE;
8049 else if (lang_hooks.decls.omp_scalar_target_p (decl))
8050 gdmk = GDMK_SCALAR_TARGET;
8051 else if (lang_hooks.decls.omp_scalar_p (decl, false))
8052 gdmk = GDMK_SCALAR;
8053 else if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
8054 || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
8055 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
8056 == POINTER_TYPE)))
8057 gdmk = GDMK_POINTER;
8058 else
8059 gdmk = GDMK_AGGREGATE;
8060 kind = lang_hooks.decls.omp_predetermined_mapping (decl);
8061 if (kind != OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
8063 if (kind == OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE)
8064 nflags |= GOVD_FIRSTPRIVATE;
8065 else if (kind == OMP_CLAUSE_DEFAULTMAP_TO)
8066 nflags |= GOVD_MAP | GOVD_MAP_TO_ONLY;
8067 else
8068 gcc_unreachable ();
8070 else if (ctx->defaultmap[gdmk] == 0)
8072 tree d = lang_hooks.decls.omp_report_decl (decl);
8073 error ("%qE not specified in enclosing %<target%>",
8074 DECL_NAME (d));
8075 inform (ctx->location, "enclosing %<target%>");
8077 else if (ctx->defaultmap[gdmk]
8078 & (GOVD_MAP_0LEN_ARRAY | GOVD_FIRSTPRIVATE))
8079 nflags |= ctx->defaultmap[gdmk];
8080 else if (ctx->defaultmap[gdmk] & GOVD_MAP_FORCE_PRESENT)
8082 gcc_assert (ctx->defaultmap[gdmk] & GOVD_MAP);
8083 nflags |= ctx->defaultmap[gdmk] | GOVD_MAP_ALLOC_ONLY;
8085 else
8087 gcc_assert (ctx->defaultmap[gdmk] & GOVD_MAP);
8088 nflags |= ctx->defaultmap[gdmk] & ~GOVD_MAP;
8093 struct gimplify_omp_ctx *octx = ctx->outer_context;
8094 if ((ctx->region_type & ORT_ACC) && octx)
8096 /* Look in outer OpenACC contexts, to see if there's a
8097 data attribute for this variable. */
8098 omp_notice_variable (octx, decl, in_code);
8100 for (; octx; octx = octx->outer_context)
8102 if (!(octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)))
8103 break;
8104 splay_tree_node n2
8105 = splay_tree_lookup (octx->variables,
8106 (splay_tree_key) decl);
8107 if (n2)
8109 if (octx->region_type == ORT_ACC_HOST_DATA)
8110 error ("variable %qE declared in enclosing "
8111 "%<host_data%> region", DECL_NAME (decl));
8112 nflags |= GOVD_MAP;
8113 if (octx->region_type == ORT_ACC_DATA
8114 && (n2->value & GOVD_MAP_0LEN_ARRAY))
8115 nflags |= GOVD_MAP_0LEN_ARRAY;
8116 goto found_outer;
8121 if ((nflags & ~(GOVD_MAP_TO_ONLY | GOVD_MAP_FROM_ONLY
8122 | GOVD_MAP_ALLOC_ONLY)) == flags)
8124 tree type = TREE_TYPE (decl);
8126 if (gimplify_omp_ctxp->target_firstprivatize_array_bases
8127 && omp_privatize_by_reference (decl))
8128 type = TREE_TYPE (type);
8129 if (!omp_mappable_type (type))
8131 error ("%qD referenced in target region does not have "
8132 "a mappable type", decl);
8133 nflags |= GOVD_MAP | GOVD_EXPLICIT;
8135 else
8137 if ((ctx->region_type & ORT_ACC) != 0)
8138 nflags = oacc_default_clause (ctx, decl, flags);
8139 else
8140 nflags |= GOVD_MAP;
8143 found_outer:
8144 omp_add_variable (ctx, decl, nflags);
8146 else
8148 /* If nothing changed, there's nothing left to do. */
8149 if ((n->value & flags) == flags)
8150 return ret;
8151 flags |= n->value;
8152 n->value = flags;
8154 goto do_outer;
8157 if (n == NULL)
8159 if (ctx->region_type == ORT_WORKSHARE
8160 || ctx->region_type == ORT_TASKGROUP
8161 || ctx->region_type == ORT_SIMD
8162 || ctx->region_type == ORT_ACC
8163 || (ctx->region_type & ORT_TARGET_DATA) != 0)
8164 goto do_outer;
8166 flags = omp_default_clause (ctx, decl, in_code, flags);
8168 if ((flags & GOVD_PRIVATE)
8169 && lang_hooks.decls.omp_private_outer_ref (decl))
8170 flags |= GOVD_PRIVATE_OUTER_REF;
8172 omp_add_variable (ctx, decl, flags);
8174 shared = (flags & GOVD_SHARED) != 0;
8175 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
8176 goto do_outer;
8179 /* Don't mark as GOVD_SEEN addressable temporaries seen only in simd
8180 lb, b or incr expressions, those shouldn't be turned into simd arrays. */
8181 if (ctx->region_type == ORT_SIMD
8182 && ctx->in_for_exprs
8183 && ((n->value & (GOVD_PRIVATE | GOVD_SEEN | GOVD_EXPLICIT))
8184 == GOVD_PRIVATE))
8185 flags &= ~GOVD_SEEN;
8187 if ((n->value & (GOVD_SEEN | GOVD_LOCAL)) == 0
8188 && (flags & (GOVD_SEEN | GOVD_LOCAL)) == GOVD_SEEN
8189 && DECL_SIZE (decl))
8191 if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
8193 splay_tree_node n2;
8194 tree t = DECL_VALUE_EXPR (decl);
8195 gcc_assert (INDIRECT_REF_P (t));
8196 t = TREE_OPERAND (t, 0);
8197 gcc_assert (DECL_P (t));
8198 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
8199 n2->value |= GOVD_SEEN;
8201 else if (omp_privatize_by_reference (decl)
8202 && TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)))
8203 && (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))))
8204 != INTEGER_CST))
8206 splay_tree_node n2;
8207 tree t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
8208 gcc_assert (DECL_P (t));
8209 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
8210 if (n2)
8211 omp_notice_variable (ctx, t, true);
8215 if (ctx->region_type & ORT_ACC)
8216 /* For OpenACC, as remarked above, defer expansion. */
8217 shared = false;
8218 else
8219 shared = ((flags | n->value) & GOVD_SHARED) != 0;
8220 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
8222 /* If nothing changed, there's nothing left to do. */
8223 if ((n->value & flags) == flags)
8224 return ret;
8225 flags |= n->value;
8226 n->value = flags;
8228 do_outer:
8229 /* If the variable is private in the current context, then we don't
8230 need to propagate anything to an outer context. */
8231 if ((flags & GOVD_PRIVATE) && !(flags & GOVD_PRIVATE_OUTER_REF))
8232 return ret;
8233 if ((flags & (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
8234 == (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
8235 return ret;
8236 if ((flags & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
8237 | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
8238 == (GOVD_LASTPRIVATE | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
8239 return ret;
8240 if (ctx->outer_context
8241 && omp_notice_variable (ctx->outer_context, decl, in_code))
8242 return true;
8243 return ret;
8246 /* Verify that DECL is private within CTX. If there's specific information
8247 to the contrary in the innermost scope, generate an error. */
8249 static bool
8250 omp_is_private (struct gimplify_omp_ctx *ctx, tree decl, int simd)
8252 splay_tree_node n;
8254 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
8255 if (n != NULL)
8257 if (n->value & GOVD_SHARED)
8259 if (ctx == gimplify_omp_ctxp)
8261 if (simd)
8262 error ("iteration variable %qE is predetermined linear",
8263 DECL_NAME (decl));
8264 else
8265 error ("iteration variable %qE should be private",
8266 DECL_NAME (decl));
8267 n->value = GOVD_PRIVATE;
8268 return true;
8270 else
8271 return false;
8273 else if ((n->value & GOVD_EXPLICIT) != 0
8274 && (ctx == gimplify_omp_ctxp
8275 || (ctx->region_type == ORT_COMBINED_PARALLEL
8276 && gimplify_omp_ctxp->outer_context == ctx)))
8278 if ((n->value & GOVD_FIRSTPRIVATE) != 0)
8279 error ("iteration variable %qE should not be firstprivate",
8280 DECL_NAME (decl));
8281 else if ((n->value & GOVD_REDUCTION) != 0)
8282 error ("iteration variable %qE should not be reduction",
8283 DECL_NAME (decl));
8284 else if (simd != 1 && (n->value & GOVD_LINEAR) != 0)
8285 error ("iteration variable %qE should not be linear",
8286 DECL_NAME (decl));
8288 return (ctx == gimplify_omp_ctxp
8289 || (ctx->region_type == ORT_COMBINED_PARALLEL
8290 && gimplify_omp_ctxp->outer_context == ctx));
8293 if (ctx->region_type != ORT_WORKSHARE
8294 && ctx->region_type != ORT_TASKGROUP
8295 && ctx->region_type != ORT_SIMD
8296 && ctx->region_type != ORT_ACC)
8297 return false;
8298 else if (ctx->outer_context)
8299 return omp_is_private (ctx->outer_context, decl, simd);
8300 return false;
8303 /* Return true if DECL is private within a parallel region
8304 that binds to the current construct's context or in parallel
8305 region's REDUCTION clause. */
8307 static bool
8308 omp_check_private (struct gimplify_omp_ctx *ctx, tree decl, bool copyprivate)
8310 splay_tree_node n;
8314 ctx = ctx->outer_context;
8315 if (ctx == NULL)
8317 if (is_global_var (decl))
8318 return false;
8320 /* References might be private, but might be shared too,
8321 when checking for copyprivate, assume they might be
8322 private, otherwise assume they might be shared. */
8323 if (copyprivate)
8324 return true;
8326 if (omp_privatize_by_reference (decl))
8327 return false;
8329 /* Treat C++ privatized non-static data members outside
8330 of the privatization the same. */
8331 if (omp_member_access_dummy_var (decl))
8332 return false;
8334 return true;
8337 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
8339 if ((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
8340 && (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0))
8342 if ((ctx->region_type & ORT_TARGET_DATA) != 0
8343 || n == NULL
8344 || (n->value & GOVD_MAP) == 0)
8345 continue;
8346 return false;
8349 if (n != NULL)
8351 if ((n->value & GOVD_LOCAL) != 0
8352 && omp_member_access_dummy_var (decl))
8353 return false;
8354 return (n->value & GOVD_SHARED) == 0;
8357 if (ctx->region_type == ORT_WORKSHARE
8358 || ctx->region_type == ORT_TASKGROUP
8359 || ctx->region_type == ORT_SIMD
8360 || ctx->region_type == ORT_ACC)
8361 continue;
8363 break;
8365 while (1);
8366 return false;
8369 /* Callback for walk_tree to find a DECL_EXPR for the given DECL. */
8371 static tree
8372 find_decl_expr (tree *tp, int *walk_subtrees, void *data)
8374 tree t = *tp;
8376 /* If this node has been visited, unmark it and keep looking. */
8377 if (TREE_CODE (t) == DECL_EXPR && DECL_EXPR_DECL (t) == (tree) data)
8378 return t;
8380 if (IS_TYPE_OR_DECL_P (t))
8381 *walk_subtrees = 0;
8382 return NULL_TREE;
8386 /* Gimplify the affinity clause but effectively ignore it.
8387 Generate:
8388 var = begin;
8389 if ((step > 1) ? var <= end : var > end)
8390 locatator_var_expr; */
8392 static void
8393 gimplify_omp_affinity (tree *list_p, gimple_seq *pre_p)
8395 tree last_iter = NULL_TREE;
8396 tree last_bind = NULL_TREE;
8397 tree label = NULL_TREE;
8398 tree *last_body = NULL;
8399 for (tree c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
8400 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY)
8402 tree t = OMP_CLAUSE_DECL (c);
8403 if (TREE_CODE (t) == TREE_LIST
8404 && TREE_PURPOSE (t)
8405 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
8407 if (TREE_VALUE (t) == null_pointer_node)
8408 continue;
8409 if (TREE_PURPOSE (t) != last_iter)
8411 if (last_bind)
8413 append_to_statement_list (label, last_body);
8414 gimplify_and_add (last_bind, pre_p);
8415 last_bind = NULL_TREE;
8417 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8419 if (gimplify_expr (&TREE_VEC_ELT (it, 1), pre_p, NULL,
8420 is_gimple_val, fb_rvalue) == GS_ERROR
8421 || gimplify_expr (&TREE_VEC_ELT (it, 2), pre_p, NULL,
8422 is_gimple_val, fb_rvalue) == GS_ERROR
8423 || gimplify_expr (&TREE_VEC_ELT (it, 3), pre_p, NULL,
8424 is_gimple_val, fb_rvalue) == GS_ERROR
8425 || (gimplify_expr (&TREE_VEC_ELT (it, 4), pre_p, NULL,
8426 is_gimple_val, fb_rvalue)
8427 == GS_ERROR))
8428 return;
8430 last_iter = TREE_PURPOSE (t);
8431 tree block = TREE_VEC_ELT (TREE_PURPOSE (t), 5);
8432 last_bind = build3 (BIND_EXPR, void_type_node, BLOCK_VARS (block),
8433 NULL, block);
8434 last_body = &BIND_EXPR_BODY (last_bind);
8435 tree cond = NULL_TREE;
8436 location_t loc = OMP_CLAUSE_LOCATION (c);
8437 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8439 tree var = TREE_VEC_ELT (it, 0);
8440 tree begin = TREE_VEC_ELT (it, 1);
8441 tree end = TREE_VEC_ELT (it, 2);
8442 tree step = TREE_VEC_ELT (it, 3);
8443 loc = DECL_SOURCE_LOCATION (var);
8444 tree tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
8445 var, begin);
8446 append_to_statement_list_force (tem, last_body);
8448 tree cond1 = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8449 step, build_zero_cst (TREE_TYPE (step)));
8450 tree cond2 = fold_build2_loc (loc, LE_EXPR, boolean_type_node,
8451 var, end);
8452 tree cond3 = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8453 var, end);
8454 cond1 = fold_build3_loc (loc, COND_EXPR, boolean_type_node,
8455 cond1, cond2, cond3);
8456 if (cond)
8457 cond = fold_build2_loc (loc, TRUTH_AND_EXPR,
8458 boolean_type_node, cond, cond1);
8459 else
8460 cond = cond1;
8462 tree cont_label = create_artificial_label (loc);
8463 label = build1 (LABEL_EXPR, void_type_node, cont_label);
8464 tree tem = fold_build3_loc (loc, COND_EXPR, void_type_node, cond,
8465 void_node,
8466 build_and_jump (&cont_label));
8467 append_to_statement_list_force (tem, last_body);
8469 if (TREE_CODE (TREE_VALUE (t)) == COMPOUND_EXPR)
8471 append_to_statement_list (TREE_OPERAND (TREE_VALUE (t), 0),
8472 last_body);
8473 TREE_VALUE (t) = TREE_OPERAND (TREE_VALUE (t), 1);
8475 if (error_operand_p (TREE_VALUE (t)))
8476 return;
8477 append_to_statement_list_force (TREE_VALUE (t), last_body);
8478 TREE_VALUE (t) = null_pointer_node;
8480 else
8482 if (last_bind)
8484 append_to_statement_list (label, last_body);
8485 gimplify_and_add (last_bind, pre_p);
8486 last_bind = NULL_TREE;
8488 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
8490 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
8491 NULL, is_gimple_val, fb_rvalue);
8492 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
8494 if (error_operand_p (OMP_CLAUSE_DECL (c)))
8495 return;
8496 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
8497 is_gimple_lvalue, fb_lvalue) == GS_ERROR)
8498 return;
8499 gimplify_and_add (OMP_CLAUSE_DECL (c), pre_p);
8502 if (last_bind)
8504 append_to_statement_list (label, last_body);
8505 gimplify_and_add (last_bind, pre_p);
8507 return;
8510 /* If *LIST_P contains any OpenMP depend clauses with iterators,
8511 lower all the depend clauses by populating corresponding depend
8512 array. Returns 0 if there are no such depend clauses, or
8513 2 if all depend clauses should be removed, 1 otherwise. */
8515 static int
8516 gimplify_omp_depend (tree *list_p, gimple_seq *pre_p)
8518 tree c;
8519 gimple *g;
8520 size_t n[5] = { 0, 0, 0, 0, 0 };
8521 bool unused[5];
8522 tree counts[5] = { NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE };
8523 tree last_iter = NULL_TREE, last_count = NULL_TREE;
8524 size_t i, j;
8525 location_t first_loc = UNKNOWN_LOCATION;
8527 for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
8528 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
8530 switch (OMP_CLAUSE_DEPEND_KIND (c))
8532 case OMP_CLAUSE_DEPEND_IN:
8533 i = 2;
8534 break;
8535 case OMP_CLAUSE_DEPEND_OUT:
8536 case OMP_CLAUSE_DEPEND_INOUT:
8537 i = 0;
8538 break;
8539 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
8540 i = 1;
8541 break;
8542 case OMP_CLAUSE_DEPEND_DEPOBJ:
8543 i = 3;
8544 break;
8545 case OMP_CLAUSE_DEPEND_INOUTSET:
8546 i = 4;
8547 break;
8548 default:
8549 gcc_unreachable ();
8551 tree t = OMP_CLAUSE_DECL (c);
8552 if (first_loc == UNKNOWN_LOCATION)
8553 first_loc = OMP_CLAUSE_LOCATION (c);
8554 if (TREE_CODE (t) == TREE_LIST
8555 && TREE_PURPOSE (t)
8556 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
8558 if (TREE_PURPOSE (t) != last_iter)
8560 tree tcnt = size_one_node;
8561 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8563 if (gimplify_expr (&TREE_VEC_ELT (it, 1), pre_p, NULL,
8564 is_gimple_val, fb_rvalue) == GS_ERROR
8565 || gimplify_expr (&TREE_VEC_ELT (it, 2), pre_p, NULL,
8566 is_gimple_val, fb_rvalue) == GS_ERROR
8567 || gimplify_expr (&TREE_VEC_ELT (it, 3), pre_p, NULL,
8568 is_gimple_val, fb_rvalue) == GS_ERROR
8569 || (gimplify_expr (&TREE_VEC_ELT (it, 4), pre_p, NULL,
8570 is_gimple_val, fb_rvalue)
8571 == GS_ERROR))
8572 return 2;
8573 tree var = TREE_VEC_ELT (it, 0);
8574 tree begin = TREE_VEC_ELT (it, 1);
8575 tree end = TREE_VEC_ELT (it, 2);
8576 tree step = TREE_VEC_ELT (it, 3);
8577 tree orig_step = TREE_VEC_ELT (it, 4);
8578 tree type = TREE_TYPE (var);
8579 tree stype = TREE_TYPE (step);
8580 location_t loc = DECL_SOURCE_LOCATION (var);
8581 tree endmbegin;
8582 /* Compute count for this iterator as
8583 orig_step > 0
8584 ? (begin < end ? (end - begin + (step - 1)) / step : 0)
8585 : (begin > end ? (end - begin + (step + 1)) / step : 0)
8586 and compute product of those for the entire depend
8587 clause. */
8588 if (POINTER_TYPE_P (type))
8589 endmbegin = fold_build2_loc (loc, POINTER_DIFF_EXPR,
8590 stype, end, begin);
8591 else
8592 endmbegin = fold_build2_loc (loc, MINUS_EXPR, type,
8593 end, begin);
8594 tree stepm1 = fold_build2_loc (loc, MINUS_EXPR, stype,
8595 step,
8596 build_int_cst (stype, 1));
8597 tree stepp1 = fold_build2_loc (loc, PLUS_EXPR, stype, step,
8598 build_int_cst (stype, 1));
8599 tree pos = fold_build2_loc (loc, PLUS_EXPR, stype,
8600 unshare_expr (endmbegin),
8601 stepm1);
8602 pos = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype,
8603 pos, step);
8604 tree neg = fold_build2_loc (loc, PLUS_EXPR, stype,
8605 endmbegin, stepp1);
8606 if (TYPE_UNSIGNED (stype))
8608 neg = fold_build1_loc (loc, NEGATE_EXPR, stype, neg);
8609 step = fold_build1_loc (loc, NEGATE_EXPR, stype, step);
8611 neg = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype,
8612 neg, step);
8613 step = NULL_TREE;
8614 tree cond = fold_build2_loc (loc, LT_EXPR,
8615 boolean_type_node,
8616 begin, end);
8617 pos = fold_build3_loc (loc, COND_EXPR, stype, cond, pos,
8618 build_int_cst (stype, 0));
8619 cond = fold_build2_loc (loc, LT_EXPR, boolean_type_node,
8620 end, begin);
8621 neg = fold_build3_loc (loc, COND_EXPR, stype, cond, neg,
8622 build_int_cst (stype, 0));
8623 tree osteptype = TREE_TYPE (orig_step);
8624 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8625 orig_step,
8626 build_int_cst (osteptype, 0));
8627 tree cnt = fold_build3_loc (loc, COND_EXPR, stype,
8628 cond, pos, neg);
8629 cnt = fold_convert_loc (loc, sizetype, cnt);
8630 if (gimplify_expr (&cnt, pre_p, NULL, is_gimple_val,
8631 fb_rvalue) == GS_ERROR)
8632 return 2;
8633 tcnt = size_binop_loc (loc, MULT_EXPR, tcnt, cnt);
8635 if (gimplify_expr (&tcnt, pre_p, NULL, is_gimple_val,
8636 fb_rvalue) == GS_ERROR)
8637 return 2;
8638 last_iter = TREE_PURPOSE (t);
8639 last_count = tcnt;
8641 if (counts[i] == NULL_TREE)
8642 counts[i] = last_count;
8643 else
8644 counts[i] = size_binop_loc (OMP_CLAUSE_LOCATION (c),
8645 PLUS_EXPR, counts[i], last_count);
8647 else
8648 n[i]++;
8650 for (i = 0; i < 5; i++)
8651 if (counts[i])
8652 break;
8653 if (i == 5)
8654 return 0;
8656 tree total = size_zero_node;
8657 for (i = 0; i < 5; i++)
8659 unused[i] = counts[i] == NULL_TREE && n[i] == 0;
8660 if (counts[i] == NULL_TREE)
8661 counts[i] = size_zero_node;
8662 if (n[i])
8663 counts[i] = size_binop (PLUS_EXPR, counts[i], size_int (n[i]));
8664 if (gimplify_expr (&counts[i], pre_p, NULL, is_gimple_val,
8665 fb_rvalue) == GS_ERROR)
8666 return 2;
8667 total = size_binop (PLUS_EXPR, total, counts[i]);
8670 if (gimplify_expr (&total, pre_p, NULL, is_gimple_val, fb_rvalue)
8671 == GS_ERROR)
8672 return 2;
8673 bool is_old = unused[1] && unused[3] && unused[4];
8674 tree totalpx = size_binop (PLUS_EXPR, unshare_expr (total),
8675 size_int (is_old ? 1 : 4));
8676 if (!unused[4])
8677 totalpx = size_binop (PLUS_EXPR, totalpx,
8678 size_binop (MULT_EXPR, counts[4], size_int (2)));
8679 tree type = build_array_type (ptr_type_node, build_index_type (totalpx));
8680 tree array = create_tmp_var_raw (type);
8681 TREE_ADDRESSABLE (array) = 1;
8682 if (!poly_int_tree_p (totalpx))
8684 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (array)))
8685 gimplify_type_sizes (TREE_TYPE (array), pre_p);
8686 if (gimplify_omp_ctxp)
8688 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
8689 while (ctx
8690 && (ctx->region_type == ORT_WORKSHARE
8691 || ctx->region_type == ORT_TASKGROUP
8692 || ctx->region_type == ORT_SIMD
8693 || ctx->region_type == ORT_ACC))
8694 ctx = ctx->outer_context;
8695 if (ctx)
8696 omp_add_variable (ctx, array, GOVD_LOCAL | GOVD_SEEN);
8698 gimplify_vla_decl (array, pre_p);
8700 else
8701 gimple_add_tmp_var (array);
8702 tree r = build4 (ARRAY_REF, ptr_type_node, array, size_int (0), NULL_TREE,
8703 NULL_TREE);
8704 tree tem;
8705 if (!is_old)
8707 tem = build2 (MODIFY_EXPR, void_type_node, r,
8708 build_int_cst (ptr_type_node, 0));
8709 gimplify_and_add (tem, pre_p);
8710 r = build4 (ARRAY_REF, ptr_type_node, array, size_int (1), NULL_TREE,
8711 NULL_TREE);
8713 tem = build2 (MODIFY_EXPR, void_type_node, r,
8714 fold_convert (ptr_type_node, total));
8715 gimplify_and_add (tem, pre_p);
8716 for (i = 1; i < (is_old ? 2 : 4); i++)
8718 r = build4 (ARRAY_REF, ptr_type_node, array, size_int (i + !is_old),
8719 NULL_TREE, NULL_TREE);
8720 tem = build2 (MODIFY_EXPR, void_type_node, r, counts[i - 1]);
8721 gimplify_and_add (tem, pre_p);
8724 tree cnts[6];
8725 for (j = 5; j; j--)
8726 if (!unused[j - 1])
8727 break;
8728 for (i = 0; i < 5; i++)
8730 if (i && (i >= j || unused[i - 1]))
8732 cnts[i] = cnts[i - 1];
8733 continue;
8735 cnts[i] = create_tmp_var (sizetype);
8736 if (i == 0)
8737 g = gimple_build_assign (cnts[i], size_int (is_old ? 2 : 5));
8738 else
8740 tree t;
8741 if (is_old)
8742 t = size_binop (PLUS_EXPR, counts[0], size_int (2));
8743 else
8744 t = size_binop (PLUS_EXPR, cnts[i - 1], counts[i - 1]);
8745 if (gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue)
8746 == GS_ERROR)
8747 return 2;
8748 g = gimple_build_assign (cnts[i], t);
8750 gimple_seq_add_stmt (pre_p, g);
8752 if (unused[4])
8753 cnts[5] = NULL_TREE;
8754 else
8756 tree t = size_binop (PLUS_EXPR, total, size_int (5));
8757 cnts[5] = create_tmp_var (sizetype);
8758 g = gimple_build_assign (cnts[i], t);
8759 gimple_seq_add_stmt (pre_p, g);
8762 last_iter = NULL_TREE;
8763 tree last_bind = NULL_TREE;
8764 tree *last_body = NULL;
8765 for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
8766 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
8768 switch (OMP_CLAUSE_DEPEND_KIND (c))
8770 case OMP_CLAUSE_DEPEND_IN:
8771 i = 2;
8772 break;
8773 case OMP_CLAUSE_DEPEND_OUT:
8774 case OMP_CLAUSE_DEPEND_INOUT:
8775 i = 0;
8776 break;
8777 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
8778 i = 1;
8779 break;
8780 case OMP_CLAUSE_DEPEND_DEPOBJ:
8781 i = 3;
8782 break;
8783 case OMP_CLAUSE_DEPEND_INOUTSET:
8784 i = 4;
8785 break;
8786 default:
8787 gcc_unreachable ();
8789 tree t = OMP_CLAUSE_DECL (c);
8790 if (TREE_CODE (t) == TREE_LIST
8791 && TREE_PURPOSE (t)
8792 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
8794 if (TREE_PURPOSE (t) != last_iter)
8796 if (last_bind)
8797 gimplify_and_add (last_bind, pre_p);
8798 tree block = TREE_VEC_ELT (TREE_PURPOSE (t), 5);
8799 last_bind = build3 (BIND_EXPR, void_type_node,
8800 BLOCK_VARS (block), NULL, block);
8801 TREE_SIDE_EFFECTS (last_bind) = 1;
8802 SET_EXPR_LOCATION (last_bind, OMP_CLAUSE_LOCATION (c));
8803 tree *p = &BIND_EXPR_BODY (last_bind);
8804 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8806 tree var = TREE_VEC_ELT (it, 0);
8807 tree begin = TREE_VEC_ELT (it, 1);
8808 tree end = TREE_VEC_ELT (it, 2);
8809 tree step = TREE_VEC_ELT (it, 3);
8810 tree orig_step = TREE_VEC_ELT (it, 4);
8811 tree type = TREE_TYPE (var);
8812 location_t loc = DECL_SOURCE_LOCATION (var);
8813 /* Emit:
8814 var = begin;
8815 goto cond_label;
8816 beg_label:
8818 var = var + step;
8819 cond_label:
8820 if (orig_step > 0) {
8821 if (var < end) goto beg_label;
8822 } else {
8823 if (var > end) goto beg_label;
8825 for each iterator, with inner iterators added to
8826 the ... above. */
8827 tree beg_label = create_artificial_label (loc);
8828 tree cond_label = NULL_TREE;
8829 tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
8830 var, begin);
8831 append_to_statement_list_force (tem, p);
8832 tem = build_and_jump (&cond_label);
8833 append_to_statement_list_force (tem, p);
8834 tem = build1 (LABEL_EXPR, void_type_node, beg_label);
8835 append_to_statement_list (tem, p);
8836 tree bind = build3 (BIND_EXPR, void_type_node, NULL_TREE,
8837 NULL_TREE, NULL_TREE);
8838 TREE_SIDE_EFFECTS (bind) = 1;
8839 SET_EXPR_LOCATION (bind, loc);
8840 append_to_statement_list_force (bind, p);
8841 if (POINTER_TYPE_P (type))
8842 tem = build2_loc (loc, POINTER_PLUS_EXPR, type,
8843 var, fold_convert_loc (loc, sizetype,
8844 step));
8845 else
8846 tem = build2_loc (loc, PLUS_EXPR, type, var, step);
8847 tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
8848 var, tem);
8849 append_to_statement_list_force (tem, p);
8850 tem = build1 (LABEL_EXPR, void_type_node, cond_label);
8851 append_to_statement_list (tem, p);
8852 tree cond = fold_build2_loc (loc, LT_EXPR,
8853 boolean_type_node,
8854 var, end);
8855 tree pos
8856 = fold_build3_loc (loc, COND_EXPR, void_type_node,
8857 cond, build_and_jump (&beg_label),
8858 void_node);
8859 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8860 var, end);
8861 tree neg
8862 = fold_build3_loc (loc, COND_EXPR, void_type_node,
8863 cond, build_and_jump (&beg_label),
8864 void_node);
8865 tree osteptype = TREE_TYPE (orig_step);
8866 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8867 orig_step,
8868 build_int_cst (osteptype, 0));
8869 tem = fold_build3_loc (loc, COND_EXPR, void_type_node,
8870 cond, pos, neg);
8871 append_to_statement_list_force (tem, p);
8872 p = &BIND_EXPR_BODY (bind);
8874 last_body = p;
8876 last_iter = TREE_PURPOSE (t);
8877 if (TREE_CODE (TREE_VALUE (t)) == COMPOUND_EXPR)
8879 append_to_statement_list (TREE_OPERAND (TREE_VALUE (t),
8880 0), last_body);
8881 TREE_VALUE (t) = TREE_OPERAND (TREE_VALUE (t), 1);
8883 if (error_operand_p (TREE_VALUE (t)))
8884 return 2;
8885 if (TREE_VALUE (t) != null_pointer_node)
8886 TREE_VALUE (t) = build_fold_addr_expr (TREE_VALUE (t));
8887 if (i == 4)
8889 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
8890 NULL_TREE, NULL_TREE);
8891 tree r2 = build4 (ARRAY_REF, ptr_type_node, array, cnts[5],
8892 NULL_TREE, NULL_TREE);
8893 r2 = build_fold_addr_expr_with_type (r2, ptr_type_node);
8894 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
8895 void_type_node, r, r2);
8896 append_to_statement_list_force (tem, last_body);
8897 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
8898 void_type_node, cnts[i],
8899 size_binop (PLUS_EXPR, cnts[i],
8900 size_int (1)));
8901 append_to_statement_list_force (tem, last_body);
8902 i = 5;
8904 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
8905 NULL_TREE, NULL_TREE);
8906 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
8907 void_type_node, r, TREE_VALUE (t));
8908 append_to_statement_list_force (tem, last_body);
8909 if (i == 5)
8911 r = build4 (ARRAY_REF, ptr_type_node, array,
8912 size_binop (PLUS_EXPR, cnts[i], size_int (1)),
8913 NULL_TREE, NULL_TREE);
8914 tem = build_int_cst (ptr_type_node, GOMP_DEPEND_INOUTSET);
8915 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
8916 void_type_node, r, tem);
8917 append_to_statement_list_force (tem, last_body);
8919 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
8920 void_type_node, cnts[i],
8921 size_binop (PLUS_EXPR, cnts[i],
8922 size_int (1 + (i == 5))));
8923 append_to_statement_list_force (tem, last_body);
8924 TREE_VALUE (t) = null_pointer_node;
8926 else
8928 if (last_bind)
8930 gimplify_and_add (last_bind, pre_p);
8931 last_bind = NULL_TREE;
8933 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
8935 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
8936 NULL, is_gimple_val, fb_rvalue);
8937 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
8939 if (error_operand_p (OMP_CLAUSE_DECL (c)))
8940 return 2;
8941 if (OMP_CLAUSE_DECL (c) != null_pointer_node)
8942 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
8943 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
8944 is_gimple_val, fb_rvalue) == GS_ERROR)
8945 return 2;
8946 if (i == 4)
8948 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
8949 NULL_TREE, NULL_TREE);
8950 tree r2 = build4 (ARRAY_REF, ptr_type_node, array, cnts[5],
8951 NULL_TREE, NULL_TREE);
8952 r2 = build_fold_addr_expr_with_type (r2, ptr_type_node);
8953 tem = build2 (MODIFY_EXPR, void_type_node, r, r2);
8954 gimplify_and_add (tem, pre_p);
8955 g = gimple_build_assign (cnts[i], size_binop (PLUS_EXPR,
8956 cnts[i],
8957 size_int (1)));
8958 gimple_seq_add_stmt (pre_p, g);
8959 i = 5;
8961 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
8962 NULL_TREE, NULL_TREE);
8963 tem = build2 (MODIFY_EXPR, void_type_node, r, OMP_CLAUSE_DECL (c));
8964 gimplify_and_add (tem, pre_p);
8965 if (i == 5)
8967 r = build4 (ARRAY_REF, ptr_type_node, array,
8968 size_binop (PLUS_EXPR, cnts[i], size_int (1)),
8969 NULL_TREE, NULL_TREE);
8970 tem = build_int_cst (ptr_type_node, GOMP_DEPEND_INOUTSET);
8971 tem = build2 (MODIFY_EXPR, void_type_node, r, tem);
8972 append_to_statement_list_force (tem, last_body);
8973 gimplify_and_add (tem, pre_p);
8975 g = gimple_build_assign (cnts[i],
8976 size_binop (PLUS_EXPR, cnts[i],
8977 size_int (1 + (i == 5))));
8978 gimple_seq_add_stmt (pre_p, g);
8981 if (last_bind)
8982 gimplify_and_add (last_bind, pre_p);
8983 tree cond = boolean_false_node;
8984 if (is_old)
8986 if (!unused[0])
8987 cond = build2_loc (first_loc, NE_EXPR, boolean_type_node, cnts[0],
8988 size_binop_loc (first_loc, PLUS_EXPR, counts[0],
8989 size_int (2)));
8990 if (!unused[2])
8991 cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond,
8992 build2_loc (first_loc, NE_EXPR, boolean_type_node,
8993 cnts[2],
8994 size_binop_loc (first_loc, PLUS_EXPR,
8995 totalpx,
8996 size_int (1))));
8998 else
9000 tree prev = size_int (5);
9001 for (i = 0; i < 5; i++)
9003 if (unused[i])
9004 continue;
9005 prev = size_binop_loc (first_loc, PLUS_EXPR, counts[i], prev);
9006 cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond,
9007 build2_loc (first_loc, NE_EXPR, boolean_type_node,
9008 cnts[i], unshare_expr (prev)));
9011 tem = build3_loc (first_loc, COND_EXPR, void_type_node, cond,
9012 build_call_expr_loc (first_loc,
9013 builtin_decl_explicit (BUILT_IN_TRAP),
9014 0), void_node);
9015 gimplify_and_add (tem, pre_p);
9016 c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_DEPEND);
9017 OMP_CLAUSE_DEPEND_KIND (c) = OMP_CLAUSE_DEPEND_LAST;
9018 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (array);
9019 OMP_CLAUSE_CHAIN (c) = *list_p;
9020 *list_p = c;
9021 return 1;
9024 /* For a set of mappings describing an array section pointed to by a struct
9025 (or derived type, etc.) component, create an "alloc" or "release" node to
9026 insert into a list following a GOMP_MAP_STRUCT node. For some types of
9027 mapping (e.g. Fortran arrays with descriptors), an additional mapping may
9028 be created that is inserted into the list of mapping nodes attached to the
9029 directive being processed -- not part of the sorted list of nodes after
9030 GOMP_MAP_STRUCT.
9032 CODE is the code of the directive being processed. GRP_START and GRP_END
9033 are the first and last of two or three nodes representing this array section
9034 mapping (e.g. a data movement node like GOMP_MAP_{TO,FROM}, optionally a
9035 GOMP_MAP_TO_PSET, and finally a GOMP_MAP_ALWAYS_POINTER). EXTRA_NODE is
9036 filled with the additional node described above, if needed.
9038 This function does not add the new nodes to any lists itself. It is the
9039 responsibility of the caller to do that. */
9041 static tree
9042 build_omp_struct_comp_nodes (enum tree_code code, tree grp_start, tree grp_end,
9043 tree *extra_node)
9045 enum gomp_map_kind mkind
9046 = (code == OMP_TARGET_EXIT_DATA || code == OACC_EXIT_DATA)
9047 ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
9049 gcc_assert (grp_start != grp_end);
9051 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end), OMP_CLAUSE_MAP);
9052 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
9053 OMP_CLAUSE_DECL (c2) = unshare_expr (OMP_CLAUSE_DECL (grp_end));
9054 OMP_CLAUSE_CHAIN (c2) = NULL_TREE;
9055 tree grp_mid = NULL_TREE;
9056 if (OMP_CLAUSE_CHAIN (grp_start) != grp_end)
9057 grp_mid = OMP_CLAUSE_CHAIN (grp_start);
9059 if (grp_mid
9060 && OMP_CLAUSE_CODE (grp_mid) == OMP_CLAUSE_MAP
9061 && OMP_CLAUSE_MAP_KIND (grp_mid) == GOMP_MAP_TO_PSET)
9062 OMP_CLAUSE_SIZE (c2) = OMP_CLAUSE_SIZE (grp_mid);
9063 else
9064 OMP_CLAUSE_SIZE (c2) = TYPE_SIZE_UNIT (ptr_type_node);
9066 if (grp_mid
9067 && OMP_CLAUSE_CODE (grp_mid) == OMP_CLAUSE_MAP
9068 && (OMP_CLAUSE_MAP_KIND (grp_mid) == GOMP_MAP_ALWAYS_POINTER
9069 || OMP_CLAUSE_MAP_KIND (grp_mid) == GOMP_MAP_ATTACH_DETACH))
9071 tree c3
9072 = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end), OMP_CLAUSE_MAP);
9073 OMP_CLAUSE_SET_MAP_KIND (c3, mkind);
9074 OMP_CLAUSE_DECL (c3) = unshare_expr (OMP_CLAUSE_DECL (grp_mid));
9075 OMP_CLAUSE_SIZE (c3) = TYPE_SIZE_UNIT (ptr_type_node);
9076 OMP_CLAUSE_CHAIN (c3) = NULL_TREE;
9078 *extra_node = c3;
9080 else
9081 *extra_node = NULL_TREE;
9083 return c2;
9086 /* Strip ARRAY_REFS or an indirect ref off BASE, find the containing object,
9087 and set *BITPOSP and *POFFSETP to the bit offset of the access.
9088 If BASE_REF is non-NULL and the containing object is a reference, set
9089 *BASE_REF to that reference before dereferencing the object.
9090 If BASE_REF is NULL, check that the containing object is a COMPONENT_REF or
9091 has array type, else return NULL. */
9093 static tree
9094 extract_base_bit_offset (tree base, poly_int64 *bitposp,
9095 poly_offset_int *poffsetp)
9097 tree offset;
9098 poly_int64 bitsize, bitpos;
9099 machine_mode mode;
9100 int unsignedp, reversep, volatilep = 0;
9101 poly_offset_int poffset;
9103 STRIP_NOPS (base);
9105 base = get_inner_reference (base, &bitsize, &bitpos, &offset, &mode,
9106 &unsignedp, &reversep, &volatilep);
9108 STRIP_NOPS (base);
9110 if (offset && poly_int_tree_p (offset))
9112 poffset = wi::to_poly_offset (offset);
9113 offset = NULL_TREE;
9115 else
9116 poffset = 0;
9118 if (maybe_ne (bitpos, 0))
9119 poffset += bits_to_bytes_round_down (bitpos);
9121 *bitposp = bitpos;
9122 *poffsetp = poffset;
9124 return base;
9127 /* Used for topological sorting of mapping groups. UNVISITED means we haven't
9128 started processing the group yet. The TEMPORARY mark is used when we first
9129 encounter a group on a depth-first traversal, and the PERMANENT mark is used
9130 when we have processed all the group's children (i.e. all the base pointers
9131 referred to by the group's mapping nodes, recursively). */
9133 enum omp_tsort_mark {
9134 UNVISITED,
9135 TEMPORARY,
9136 PERMANENT
9139 /* Hash for trees based on operand_equal_p. Like tree_operand_hash
9140 but ignores side effects in the equality comparisons. */
9142 struct tree_operand_hash_no_se : tree_operand_hash
9144 static inline bool equal (const value_type &,
9145 const compare_type &);
9148 inline bool
9149 tree_operand_hash_no_se::equal (const value_type &t1,
9150 const compare_type &t2)
9152 return operand_equal_p (t1, t2, OEP_MATCH_SIDE_EFFECTS);
9155 /* A group of OMP_CLAUSE_MAP nodes that correspond to a single "map"
9156 clause. */
9158 struct omp_mapping_group {
9159 tree *grp_start;
9160 tree grp_end;
9161 omp_tsort_mark mark;
9162 /* If we've removed the group but need to reindex, mark the group as
9163 deleted. */
9164 bool deleted;
9165 struct omp_mapping_group *sibling;
9166 struct omp_mapping_group *next;
9169 DEBUG_FUNCTION void
9170 debug_mapping_group (omp_mapping_group *grp)
9172 tree tmp = OMP_CLAUSE_CHAIN (grp->grp_end);
9173 OMP_CLAUSE_CHAIN (grp->grp_end) = NULL;
9174 debug_generic_expr (*grp->grp_start);
9175 OMP_CLAUSE_CHAIN (grp->grp_end) = tmp;
9178 /* Return the OpenMP "base pointer" of an expression EXPR, or NULL if there
9179 isn't one. */
9181 static tree
9182 omp_get_base_pointer (tree expr)
9184 while (TREE_CODE (expr) == ARRAY_REF
9185 || TREE_CODE (expr) == COMPONENT_REF)
9186 expr = TREE_OPERAND (expr, 0);
9188 if (INDIRECT_REF_P (expr)
9189 || (TREE_CODE (expr) == MEM_REF
9190 && integer_zerop (TREE_OPERAND (expr, 1))))
9192 expr = TREE_OPERAND (expr, 0);
9193 while (TREE_CODE (expr) == COMPOUND_EXPR)
9194 expr = TREE_OPERAND (expr, 1);
9195 if (TREE_CODE (expr) == POINTER_PLUS_EXPR)
9196 expr = TREE_OPERAND (expr, 0);
9197 if (TREE_CODE (expr) == SAVE_EXPR)
9198 expr = TREE_OPERAND (expr, 0);
9199 STRIP_NOPS (expr);
9200 return expr;
9203 return NULL_TREE;
9206 /* Remove COMPONENT_REFS and indirections from EXPR. */
9208 static tree
9209 omp_strip_components_and_deref (tree expr)
9211 while (TREE_CODE (expr) == COMPONENT_REF
9212 || INDIRECT_REF_P (expr)
9213 || (TREE_CODE (expr) == MEM_REF
9214 && integer_zerop (TREE_OPERAND (expr, 1)))
9215 || TREE_CODE (expr) == POINTER_PLUS_EXPR
9216 || TREE_CODE (expr) == COMPOUND_EXPR)
9217 if (TREE_CODE (expr) == COMPOUND_EXPR)
9218 expr = TREE_OPERAND (expr, 1);
9219 else
9220 expr = TREE_OPERAND (expr, 0);
9222 STRIP_NOPS (expr);
9224 return expr;
9227 static tree
9228 omp_strip_indirections (tree expr)
9230 while (INDIRECT_REF_P (expr)
9231 || (TREE_CODE (expr) == MEM_REF
9232 && integer_zerop (TREE_OPERAND (expr, 1))))
9233 expr = TREE_OPERAND (expr, 0);
9235 return expr;
9238 /* An attach or detach operation depends directly on the address being
9239 attached/detached. Return that address, or none if there are no
9240 attachments/detachments. */
9242 static tree
9243 omp_get_attachment (omp_mapping_group *grp)
9245 tree node = *grp->grp_start;
9247 switch (OMP_CLAUSE_MAP_KIND (node))
9249 case GOMP_MAP_TO:
9250 case GOMP_MAP_FROM:
9251 case GOMP_MAP_TOFROM:
9252 case GOMP_MAP_ALWAYS_FROM:
9253 case GOMP_MAP_ALWAYS_TO:
9254 case GOMP_MAP_ALWAYS_TOFROM:
9255 case GOMP_MAP_FORCE_FROM:
9256 case GOMP_MAP_FORCE_TO:
9257 case GOMP_MAP_FORCE_TOFROM:
9258 case GOMP_MAP_FORCE_PRESENT:
9259 case GOMP_MAP_PRESENT_ALLOC:
9260 case GOMP_MAP_PRESENT_FROM:
9261 case GOMP_MAP_PRESENT_TO:
9262 case GOMP_MAP_PRESENT_TOFROM:
9263 case GOMP_MAP_ALWAYS_PRESENT_FROM:
9264 case GOMP_MAP_ALWAYS_PRESENT_TO:
9265 case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
9266 case GOMP_MAP_ALLOC:
9267 case GOMP_MAP_RELEASE:
9268 case GOMP_MAP_DELETE:
9269 case GOMP_MAP_FORCE_ALLOC:
9270 if (node == grp->grp_end)
9271 return NULL_TREE;
9273 node = OMP_CLAUSE_CHAIN (node);
9274 if (node && OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_TO_PSET)
9276 gcc_assert (node != grp->grp_end);
9277 node = OMP_CLAUSE_CHAIN (node);
9279 if (node)
9280 switch (OMP_CLAUSE_MAP_KIND (node))
9282 case GOMP_MAP_POINTER:
9283 case GOMP_MAP_ALWAYS_POINTER:
9284 case GOMP_MAP_FIRSTPRIVATE_POINTER:
9285 case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
9286 case GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION:
9287 return NULL_TREE;
9289 case GOMP_MAP_ATTACH_DETACH:
9290 case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION:
9291 return OMP_CLAUSE_DECL (node);
9293 default:
9294 internal_error ("unexpected mapping node");
9296 return error_mark_node;
9298 case GOMP_MAP_TO_PSET:
9299 gcc_assert (node != grp->grp_end);
9300 node = OMP_CLAUSE_CHAIN (node);
9301 if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_ATTACH
9302 || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_DETACH)
9303 return OMP_CLAUSE_DECL (node);
9304 else
9305 internal_error ("unexpected mapping node");
9306 return error_mark_node;
9308 case GOMP_MAP_ATTACH:
9309 case GOMP_MAP_DETACH:
9310 node = OMP_CLAUSE_CHAIN (node);
9311 if (!node || *grp->grp_start == grp->grp_end)
9312 return OMP_CLAUSE_DECL (*grp->grp_start);
9313 if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_POINTER
9314 || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
9315 return OMP_CLAUSE_DECL (*grp->grp_start);
9316 else
9317 internal_error ("unexpected mapping node");
9318 return error_mark_node;
9320 case GOMP_MAP_STRUCT:
9321 case GOMP_MAP_FORCE_DEVICEPTR:
9322 case GOMP_MAP_DEVICE_RESIDENT:
9323 case GOMP_MAP_LINK:
9324 case GOMP_MAP_IF_PRESENT:
9325 case GOMP_MAP_FIRSTPRIVATE:
9326 case GOMP_MAP_FIRSTPRIVATE_INT:
9327 case GOMP_MAP_USE_DEVICE_PTR:
9328 case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION:
9329 return NULL_TREE;
9331 default:
9332 internal_error ("unexpected mapping node");
9335 return error_mark_node;
9338 /* Given a pointer START_P to the start of a group of related (e.g. pointer)
9339 mappings, return the chain pointer to the end of that group in the list. */
9341 static tree *
9342 omp_group_last (tree *start_p)
9344 tree c = *start_p, nc, *grp_last_p = start_p;
9346 gcc_assert (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP);
9348 nc = OMP_CLAUSE_CHAIN (c);
9350 if (!nc || OMP_CLAUSE_CODE (nc) != OMP_CLAUSE_MAP)
9351 return grp_last_p;
9353 switch (OMP_CLAUSE_MAP_KIND (c))
9355 default:
9356 while (nc
9357 && OMP_CLAUSE_CODE (nc) == OMP_CLAUSE_MAP
9358 && (OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
9359 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_POINTER
9360 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_ATTACH_DETACH
9361 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_POINTER
9362 || (OMP_CLAUSE_MAP_KIND (nc)
9363 == GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION)
9364 || (OMP_CLAUSE_MAP_KIND (nc)
9365 == GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION)
9366 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_ALWAYS_POINTER
9367 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_TO_PSET))
9369 grp_last_p = &OMP_CLAUSE_CHAIN (c);
9370 c = nc;
9371 tree nc2 = OMP_CLAUSE_CHAIN (nc);
9372 if (nc2
9373 && OMP_CLAUSE_CODE (nc2) == OMP_CLAUSE_MAP
9374 && (OMP_CLAUSE_MAP_KIND (nc)
9375 == GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION)
9376 && OMP_CLAUSE_MAP_KIND (nc2) == GOMP_MAP_ATTACH)
9378 grp_last_p = &OMP_CLAUSE_CHAIN (nc);
9379 c = nc2;
9380 nc2 = OMP_CLAUSE_CHAIN (nc2);
9382 nc = nc2;
9384 break;
9386 case GOMP_MAP_ATTACH:
9387 case GOMP_MAP_DETACH:
9388 /* This is a weird artifact of how directives are parsed: bare attach or
9389 detach clauses get a subsequent (meaningless) FIRSTPRIVATE_POINTER or
9390 FIRSTPRIVATE_REFERENCE node. FIXME. */
9391 if (nc
9392 && OMP_CLAUSE_CODE (nc) == OMP_CLAUSE_MAP
9393 && (OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
9394 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_POINTER))
9395 grp_last_p = &OMP_CLAUSE_CHAIN (c);
9396 break;
9398 case GOMP_MAP_TO_PSET:
9399 if (OMP_CLAUSE_CODE (nc) == OMP_CLAUSE_MAP
9400 && (OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_ATTACH
9401 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_DETACH))
9402 grp_last_p = &OMP_CLAUSE_CHAIN (c);
9403 break;
9405 case GOMP_MAP_STRUCT:
9407 unsigned HOST_WIDE_INT num_mappings
9408 = tree_to_uhwi (OMP_CLAUSE_SIZE (c));
9409 if (OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_POINTER
9410 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
9411 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_ATTACH_DETACH)
9412 grp_last_p = &OMP_CLAUSE_CHAIN (*grp_last_p);
9413 for (unsigned i = 0; i < num_mappings; i++)
9414 grp_last_p = &OMP_CLAUSE_CHAIN (*grp_last_p);
9416 break;
9419 return grp_last_p;
9422 /* Walk through LIST_P, and return a list of groups of mappings found (e.g.
9423 OMP_CLAUSE_MAP with GOMP_MAP_{TO/FROM/TOFROM} followed by one or two
9424 associated GOMP_MAP_POINTER mappings). Return a vector of omp_mapping_group
9425 if we have more than one such group, else return NULL. */
9427 static void
9428 omp_gather_mapping_groups_1 (tree *list_p, vec<omp_mapping_group> *groups,
9429 tree gather_sentinel)
9431 for (tree *cp = list_p;
9432 *cp && *cp != gather_sentinel;
9433 cp = &OMP_CLAUSE_CHAIN (*cp))
9435 if (OMP_CLAUSE_CODE (*cp) != OMP_CLAUSE_MAP)
9436 continue;
9438 tree *grp_last_p = omp_group_last (cp);
9439 omp_mapping_group grp;
9441 grp.grp_start = cp;
9442 grp.grp_end = *grp_last_p;
9443 grp.mark = UNVISITED;
9444 grp.sibling = NULL;
9445 grp.deleted = false;
9446 grp.next = NULL;
9447 groups->safe_push (grp);
9449 cp = grp_last_p;
9453 static vec<omp_mapping_group> *
9454 omp_gather_mapping_groups (tree *list_p)
9456 vec<omp_mapping_group> *groups = new vec<omp_mapping_group> ();
9458 omp_gather_mapping_groups_1 (list_p, groups, NULL_TREE);
9460 if (groups->length () > 0)
9461 return groups;
9462 else
9464 delete groups;
9465 return NULL;
9469 /* A pointer mapping group GRP may define a block of memory starting at some
9470 base address, and maybe also define a firstprivate pointer or firstprivate
9471 reference that points to that block. The return value is a node containing
9472 the former, and the *FIRSTPRIVATE pointer is set if we have the latter.
9473 If we define several base pointers, i.e. for a GOMP_MAP_STRUCT mapping,
9474 return the number of consecutive chained nodes in CHAINED. */
9476 static tree
9477 omp_group_base (omp_mapping_group *grp, unsigned int *chained,
9478 tree *firstprivate)
9480 tree node = *grp->grp_start;
9482 *firstprivate = NULL_TREE;
9483 *chained = 1;
9485 switch (OMP_CLAUSE_MAP_KIND (node))
9487 case GOMP_MAP_TO:
9488 case GOMP_MAP_FROM:
9489 case GOMP_MAP_TOFROM:
9490 case GOMP_MAP_ALWAYS_FROM:
9491 case GOMP_MAP_ALWAYS_TO:
9492 case GOMP_MAP_ALWAYS_TOFROM:
9493 case GOMP_MAP_FORCE_FROM:
9494 case GOMP_MAP_FORCE_TO:
9495 case GOMP_MAP_FORCE_TOFROM:
9496 case GOMP_MAP_FORCE_PRESENT:
9497 case GOMP_MAP_PRESENT_ALLOC:
9498 case GOMP_MAP_PRESENT_FROM:
9499 case GOMP_MAP_PRESENT_TO:
9500 case GOMP_MAP_PRESENT_TOFROM:
9501 case GOMP_MAP_ALWAYS_PRESENT_FROM:
9502 case GOMP_MAP_ALWAYS_PRESENT_TO:
9503 case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
9504 case GOMP_MAP_ALLOC:
9505 case GOMP_MAP_RELEASE:
9506 case GOMP_MAP_DELETE:
9507 case GOMP_MAP_FORCE_ALLOC:
9508 case GOMP_MAP_IF_PRESENT:
9509 if (node == grp->grp_end)
9510 return node;
9512 node = OMP_CLAUSE_CHAIN (node);
9513 if (node && OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_TO_PSET)
9515 if (node == grp->grp_end)
9516 return *grp->grp_start;
9517 node = OMP_CLAUSE_CHAIN (node);
9519 if (node)
9520 switch (OMP_CLAUSE_MAP_KIND (node))
9522 case GOMP_MAP_POINTER:
9523 case GOMP_MAP_FIRSTPRIVATE_POINTER:
9524 case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
9525 case GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION:
9526 *firstprivate = OMP_CLAUSE_DECL (node);
9527 return *grp->grp_start;
9529 case GOMP_MAP_ALWAYS_POINTER:
9530 case GOMP_MAP_ATTACH_DETACH:
9531 case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION:
9532 return *grp->grp_start;
9534 default:
9535 internal_error ("unexpected mapping node");
9537 else
9538 internal_error ("unexpected mapping node");
9539 return error_mark_node;
9541 case GOMP_MAP_TO_PSET:
9542 gcc_assert (node != grp->grp_end);
9543 node = OMP_CLAUSE_CHAIN (node);
9544 if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_ATTACH
9545 || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_DETACH)
9546 return NULL_TREE;
9547 else
9548 internal_error ("unexpected mapping node");
9549 return error_mark_node;
9551 case GOMP_MAP_ATTACH:
9552 case GOMP_MAP_DETACH:
9553 node = OMP_CLAUSE_CHAIN (node);
9554 if (!node || *grp->grp_start == grp->grp_end)
9555 return NULL_TREE;
9556 if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_POINTER
9557 || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
9559 /* We're mapping the base pointer itself in a bare attach or detach
9560 node. This is a side effect of how parsing works, and the mapping
9561 will be removed anyway (at least for enter/exit data directives).
9562 We should ignore the mapping here. FIXME. */
9563 return NULL_TREE;
9565 else
9566 internal_error ("unexpected mapping node");
9567 return error_mark_node;
9569 case GOMP_MAP_STRUCT:
9571 unsigned HOST_WIDE_INT num_mappings
9572 = tree_to_uhwi (OMP_CLAUSE_SIZE (node));
9573 node = OMP_CLAUSE_CHAIN (node);
9574 if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_POINTER
9575 || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
9577 *firstprivate = OMP_CLAUSE_DECL (node);
9578 node = OMP_CLAUSE_CHAIN (node);
9580 *chained = num_mappings;
9581 return node;
9584 case GOMP_MAP_FORCE_DEVICEPTR:
9585 case GOMP_MAP_DEVICE_RESIDENT:
9586 case GOMP_MAP_LINK:
9587 case GOMP_MAP_FIRSTPRIVATE:
9588 case GOMP_MAP_FIRSTPRIVATE_INT:
9589 case GOMP_MAP_USE_DEVICE_PTR:
9590 case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION:
9591 return NULL_TREE;
9593 case GOMP_MAP_FIRSTPRIVATE_POINTER:
9594 case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
9595 case GOMP_MAP_POINTER:
9596 case GOMP_MAP_ALWAYS_POINTER:
9597 case GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION:
9598 /* These shouldn't appear by themselves. */
9599 if (!seen_error ())
9600 internal_error ("unexpected pointer mapping node");
9601 return error_mark_node;
9603 default:
9604 gcc_unreachable ();
9607 return error_mark_node;
9610 /* Given a vector of omp_mapping_groups, build a hash table so we can look up
9611 nodes by tree_operand_hash_no_se. */
9613 static void
9614 omp_index_mapping_groups_1 (hash_map<tree_operand_hash_no_se,
9615 omp_mapping_group *> *grpmap,
9616 vec<omp_mapping_group> *groups,
9617 tree reindex_sentinel)
9619 omp_mapping_group *grp;
9620 unsigned int i;
9621 bool reindexing = reindex_sentinel != NULL_TREE, above_hwm = false;
9623 FOR_EACH_VEC_ELT (*groups, i, grp)
9625 if (reindexing && *grp->grp_start == reindex_sentinel)
9626 above_hwm = true;
9628 if (reindexing && !above_hwm)
9629 continue;
9631 tree fpp;
9632 unsigned int chained;
9633 tree node = omp_group_base (grp, &chained, &fpp);
9635 if (node == error_mark_node || (!node && !fpp))
9636 continue;
9638 for (unsigned j = 0;
9639 node && j < chained;
9640 node = OMP_CLAUSE_CHAIN (node), j++)
9642 tree decl = OMP_CLAUSE_DECL (node);
9643 /* Sometimes we see zero-offset MEM_REF instead of INDIRECT_REF,
9644 meaning node-hash lookups don't work. This is a workaround for
9645 that, but ideally we should just create the INDIRECT_REF at
9646 source instead. FIXME. */
9647 if (TREE_CODE (decl) == MEM_REF
9648 && integer_zerop (TREE_OPERAND (decl, 1)))
9649 decl = build_fold_indirect_ref (TREE_OPERAND (decl, 0));
9651 omp_mapping_group **prev = grpmap->get (decl);
9653 if (prev && *prev == grp)
9654 /* Empty. */;
9655 else if (prev)
9657 /* Mapping the same thing twice is normally diagnosed as an error,
9658 but can happen under some circumstances, e.g. in pr99928-16.c,
9659 the directive:
9661 #pragma omp target simd reduction(+:a[:3]) \
9662 map(always, tofrom: a[:6])
9665 will result in two "a[0]" mappings (of different sizes). */
9667 grp->sibling = (*prev)->sibling;
9668 (*prev)->sibling = grp;
9670 else
9671 grpmap->put (decl, grp);
9674 if (!fpp)
9675 continue;
9677 omp_mapping_group **prev = grpmap->get (fpp);
9678 if (prev && *prev != grp)
9680 grp->sibling = (*prev)->sibling;
9681 (*prev)->sibling = grp;
9683 else
9684 grpmap->put (fpp, grp);
9688 static hash_map<tree_operand_hash_no_se, omp_mapping_group *> *
9689 omp_index_mapping_groups (vec<omp_mapping_group> *groups)
9691 hash_map<tree_operand_hash_no_se, omp_mapping_group *> *grpmap
9692 = new hash_map<tree_operand_hash_no_se, omp_mapping_group *>;
9694 omp_index_mapping_groups_1 (grpmap, groups, NULL_TREE);
9696 return grpmap;
9699 /* Rebuild group map from partially-processed clause list (during
9700 omp_build_struct_sibling_lists). We have already processed nodes up until
9701 a high-water mark (HWM). This is a bit tricky because the list is being
9702 reordered as it is scanned, but we know:
9704 1. The list after HWM has not been touched yet, so we can reindex it safely.
9706 2. The list before and including HWM has been altered, but remains
9707 well-formed throughout the sibling-list building operation.
9709 so, we can do the reindex operation in two parts, on the processed and
9710 then the unprocessed halves of the list. */
9712 static hash_map<tree_operand_hash_no_se, omp_mapping_group *> *
9713 omp_reindex_mapping_groups (tree *list_p,
9714 vec<omp_mapping_group> *groups,
9715 vec<omp_mapping_group> *processed_groups,
9716 tree sentinel)
9718 hash_map<tree_operand_hash_no_se, omp_mapping_group *> *grpmap
9719 = new hash_map<tree_operand_hash_no_se, omp_mapping_group *>;
9721 processed_groups->truncate (0);
9723 omp_gather_mapping_groups_1 (list_p, processed_groups, sentinel);
9724 omp_index_mapping_groups_1 (grpmap, processed_groups, NULL_TREE);
9725 if (sentinel)
9726 omp_index_mapping_groups_1 (grpmap, groups, sentinel);
9728 return grpmap;
9731 /* Find the immediately-containing struct for a component ref (etc.)
9732 expression EXPR. */
9734 static tree
9735 omp_containing_struct (tree expr)
9737 tree expr0 = expr;
9739 STRIP_NOPS (expr);
9741 /* Note: don't strip NOPs unless we're also stripping off array refs or a
9742 component ref. */
9743 if (TREE_CODE (expr) != ARRAY_REF && TREE_CODE (expr) != COMPONENT_REF)
9744 return expr0;
9746 while (TREE_CODE (expr) == ARRAY_REF)
9747 expr = TREE_OPERAND (expr, 0);
9749 if (TREE_CODE (expr) == COMPONENT_REF)
9750 expr = TREE_OPERAND (expr, 0);
9752 return expr;
9755 /* Return TRUE if DECL describes a component that is part of a whole structure
9756 that is mapped elsewhere in GRPMAP. *MAPPED_BY_GROUP is set to the group
9757 that maps that structure, if present. */
9759 static bool
9760 omp_mapped_by_containing_struct (hash_map<tree_operand_hash_no_se,
9761 omp_mapping_group *> *grpmap,
9762 tree decl,
9763 omp_mapping_group **mapped_by_group)
9765 tree wsdecl = NULL_TREE;
9767 *mapped_by_group = NULL;
9769 while (true)
9771 wsdecl = omp_containing_struct (decl);
9772 if (wsdecl == decl)
9773 break;
9774 omp_mapping_group **wholestruct = grpmap->get (wsdecl);
9775 if (!wholestruct
9776 && TREE_CODE (wsdecl) == MEM_REF
9777 && integer_zerop (TREE_OPERAND (wsdecl, 1)))
9779 tree deref = TREE_OPERAND (wsdecl, 0);
9780 deref = build_fold_indirect_ref (deref);
9781 wholestruct = grpmap->get (deref);
9783 if (wholestruct)
9785 *mapped_by_group = *wholestruct;
9786 return true;
9788 decl = wsdecl;
9791 return false;
9794 /* Helper function for omp_tsort_mapping_groups. Returns TRUE on success, or
9795 FALSE on error. */
9797 static bool
9798 omp_tsort_mapping_groups_1 (omp_mapping_group ***outlist,
9799 vec<omp_mapping_group> *groups,
9800 hash_map<tree_operand_hash_no_se,
9801 omp_mapping_group *> *grpmap,
9802 omp_mapping_group *grp)
9804 if (grp->mark == PERMANENT)
9805 return true;
9806 if (grp->mark == TEMPORARY)
9808 fprintf (stderr, "when processing group:\n");
9809 debug_mapping_group (grp);
9810 internal_error ("base pointer cycle detected");
9811 return false;
9813 grp->mark = TEMPORARY;
9815 tree attaches_to = omp_get_attachment (grp);
9817 if (attaches_to)
9819 omp_mapping_group **basep = grpmap->get (attaches_to);
9821 if (basep && *basep != grp)
9823 for (omp_mapping_group *w = *basep; w; w = w->sibling)
9824 if (!omp_tsort_mapping_groups_1 (outlist, groups, grpmap, w))
9825 return false;
9829 tree decl = OMP_CLAUSE_DECL (*grp->grp_start);
9831 while (decl)
9833 tree base = omp_get_base_pointer (decl);
9835 if (!base)
9836 break;
9838 omp_mapping_group **innerp = grpmap->get (base);
9839 omp_mapping_group *wholestruct;
9841 /* We should treat whole-structure mappings as if all (pointer, in this
9842 case) members are mapped as individual list items. Check if we have
9843 such a whole-structure mapping, if we don't have an explicit reference
9844 to the pointer member itself. */
9845 if (!innerp
9846 && TREE_CODE (base) == COMPONENT_REF
9847 && omp_mapped_by_containing_struct (grpmap, base, &wholestruct))
9848 innerp = &wholestruct;
9850 if (innerp && *innerp != grp)
9852 for (omp_mapping_group *w = *innerp; w; w = w->sibling)
9853 if (!omp_tsort_mapping_groups_1 (outlist, groups, grpmap, w))
9854 return false;
9855 break;
9858 decl = base;
9861 grp->mark = PERMANENT;
9863 /* Emit grp to output list. */
9865 **outlist = grp;
9866 *outlist = &grp->next;
9868 return true;
9871 /* Topologically sort GROUPS, so that OMP 5.0-defined base pointers come
9872 before mappings that use those pointers. This is an implementation of the
9873 depth-first search algorithm, described e.g. at:
9875 https://en.wikipedia.org/wiki/Topological_sorting
9878 static omp_mapping_group *
9879 omp_tsort_mapping_groups (vec<omp_mapping_group> *groups,
9880 hash_map<tree_operand_hash_no_se, omp_mapping_group *>
9881 *grpmap)
9883 omp_mapping_group *grp, *outlist = NULL, **cursor;
9884 unsigned int i;
9886 cursor = &outlist;
9888 FOR_EACH_VEC_ELT (*groups, i, grp)
9890 if (grp->mark != PERMANENT)
9891 if (!omp_tsort_mapping_groups_1 (&cursor, groups, grpmap, grp))
9892 return NULL;
9895 return outlist;
9898 /* Split INLIST into two parts, moving groups corresponding to
9899 ALLOC/RELEASE/DELETE mappings to one list, and other mappings to another.
9900 The former list is then appended to the latter. Each sub-list retains the
9901 order of the original list.
9902 Note that ATTACH nodes are later moved to the end of the list in
9903 gimplify_adjust_omp_clauses, for target regions. */
9905 static omp_mapping_group *
9906 omp_segregate_mapping_groups (omp_mapping_group *inlist)
9908 omp_mapping_group *ard_groups = NULL, *tf_groups = NULL;
9909 omp_mapping_group **ard_tail = &ard_groups, **tf_tail = &tf_groups;
9911 for (omp_mapping_group *w = inlist; w;)
9913 tree c = *w->grp_start;
9914 omp_mapping_group *next = w->next;
9916 gcc_assert (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP);
9918 switch (OMP_CLAUSE_MAP_KIND (c))
9920 case GOMP_MAP_ALLOC:
9921 case GOMP_MAP_RELEASE:
9922 case GOMP_MAP_DELETE:
9923 *ard_tail = w;
9924 w->next = NULL;
9925 ard_tail = &w->next;
9926 break;
9928 default:
9929 *tf_tail = w;
9930 w->next = NULL;
9931 tf_tail = &w->next;
9934 w = next;
9937 /* Now splice the lists together... */
9938 *tf_tail = ard_groups;
9940 return tf_groups;
9943 /* Given a list LIST_P containing groups of mappings given by GROUPS, reorder
9944 those groups based on the output list of omp_tsort_mapping_groups --
9945 singly-linked, threaded through each element's NEXT pointer starting at
9946 HEAD. Each list element appears exactly once in that linked list.
9948 Each element of GROUPS may correspond to one or several mapping nodes.
9949 Node groups are kept together, and in the reordered list, the positions of
9950 the original groups are reused for the positions of the reordered list.
9951 Hence if we have e.g.
9953 {to ptr ptr} firstprivate {tofrom ptr} ...
9954 ^ ^ ^
9955 first group non-"map" second group
9957 and say the second group contains a base pointer for the first so must be
9958 moved before it, the resulting list will contain:
9960 {tofrom ptr} firstprivate {to ptr ptr} ...
9961 ^ prev. second group ^ prev. first group
9964 static tree *
9965 omp_reorder_mapping_groups (vec<omp_mapping_group> *groups,
9966 omp_mapping_group *head,
9967 tree *list_p)
9969 omp_mapping_group *grp;
9970 unsigned int i;
9971 unsigned numgroups = groups->length ();
9972 auto_vec<tree> old_heads (numgroups);
9973 auto_vec<tree *> old_headps (numgroups);
9974 auto_vec<tree> new_heads (numgroups);
9975 auto_vec<tree> old_succs (numgroups);
9976 bool map_at_start = (list_p == (*groups)[0].grp_start);
9978 tree *new_grp_tail = NULL;
9980 /* Stash the start & end nodes of each mapping group before we start
9981 modifying the list. */
9982 FOR_EACH_VEC_ELT (*groups, i, grp)
9984 old_headps.quick_push (grp->grp_start);
9985 old_heads.quick_push (*grp->grp_start);
9986 old_succs.quick_push (OMP_CLAUSE_CHAIN (grp->grp_end));
9989 /* And similarly, the heads of the groups in the order we want to rearrange
9990 the list to. */
9991 for (omp_mapping_group *w = head; w; w = w->next)
9992 new_heads.quick_push (*w->grp_start);
9994 FOR_EACH_VEC_ELT (*groups, i, grp)
9996 gcc_assert (head);
9998 if (new_grp_tail && old_succs[i - 1] == old_heads[i])
10000 /* a {b c d} {e f g} h i j (original)
10002 a {k l m} {e f g} h i j (inserted new group on last iter)
10004 a {k l m} {n o p} h i j (this time, chain last group to new one)
10005 ^new_grp_tail
10007 *new_grp_tail = new_heads[i];
10009 else if (new_grp_tail)
10011 /* a {b c d} e {f g h} i j k (original)
10013 a {l m n} e {f g h} i j k (gap after last iter's group)
10015 a {l m n} e {o p q} h i j (chain last group to old successor)
10016 ^new_grp_tail
10018 *new_grp_tail = old_succs[i - 1];
10019 *old_headps[i] = new_heads[i];
10021 else
10023 /* The first inserted group -- point to new group, and leave end
10024 open.
10025 a {b c d} e f
10027 a {g h i...
10029 *grp->grp_start = new_heads[i];
10032 new_grp_tail = &OMP_CLAUSE_CHAIN (head->grp_end);
10034 head = head->next;
10037 if (new_grp_tail)
10038 *new_grp_tail = old_succs[numgroups - 1];
10040 gcc_assert (!head);
10042 return map_at_start ? (*groups)[0].grp_start : list_p;
10045 /* DECL is supposed to have lastprivate semantics in the outer contexts
10046 of combined/composite constructs, starting with OCTX.
10047 Add needed lastprivate, shared or map clause if no data sharing or
10048 mapping clause are present. IMPLICIT_P is true if it is an implicit
10049 clause (IV on simd), in which case the lastprivate will not be
10050 copied to some constructs. */
10052 static void
10053 omp_lastprivate_for_combined_outer_constructs (struct gimplify_omp_ctx *octx,
10054 tree decl, bool implicit_p)
10056 struct gimplify_omp_ctx *orig_octx = octx;
10057 for (; octx; octx = octx->outer_context)
10059 if ((octx->region_type == ORT_COMBINED_PARALLEL
10060 || (octx->region_type & ORT_COMBINED_TEAMS) == ORT_COMBINED_TEAMS)
10061 && splay_tree_lookup (octx->variables,
10062 (splay_tree_key) decl) == NULL)
10064 omp_add_variable (octx, decl, GOVD_SHARED | GOVD_SEEN);
10065 continue;
10067 if ((octx->region_type & ORT_TASK) != 0
10068 && octx->combined_loop
10069 && splay_tree_lookup (octx->variables,
10070 (splay_tree_key) decl) == NULL)
10072 omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
10073 continue;
10075 if (implicit_p
10076 && octx->region_type == ORT_WORKSHARE
10077 && octx->combined_loop
10078 && splay_tree_lookup (octx->variables,
10079 (splay_tree_key) decl) == NULL
10080 && octx->outer_context
10081 && octx->outer_context->region_type == ORT_COMBINED_PARALLEL
10082 && splay_tree_lookup (octx->outer_context->variables,
10083 (splay_tree_key) decl) == NULL)
10085 octx = octx->outer_context;
10086 omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
10087 continue;
10089 if ((octx->region_type == ORT_WORKSHARE || octx->region_type == ORT_ACC)
10090 && octx->combined_loop
10091 && splay_tree_lookup (octx->variables,
10092 (splay_tree_key) decl) == NULL
10093 && !omp_check_private (octx, decl, false))
10095 omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
10096 continue;
10098 if (octx->region_type == ORT_COMBINED_TARGET)
10100 splay_tree_node n = splay_tree_lookup (octx->variables,
10101 (splay_tree_key) decl);
10102 if (n == NULL)
10104 omp_add_variable (octx, decl, GOVD_MAP | GOVD_SEEN);
10105 octx = octx->outer_context;
10107 else if (!implicit_p
10108 && (n->value & GOVD_FIRSTPRIVATE_IMPLICIT))
10110 n->value &= ~(GOVD_FIRSTPRIVATE
10111 | GOVD_FIRSTPRIVATE_IMPLICIT
10112 | GOVD_EXPLICIT);
10113 omp_add_variable (octx, decl, GOVD_MAP | GOVD_SEEN);
10114 octx = octx->outer_context;
10117 break;
10119 if (octx && (implicit_p || octx != orig_octx))
10120 omp_notice_variable (octx, decl, true);
10123 /* If we have mappings INNER and OUTER, where INNER is a component access and
10124 OUTER is a mapping of the whole containing struct, check that the mappings
10125 are compatible. We'll be deleting the inner mapping, so we need to make
10126 sure the outer mapping does (at least) the same transfers to/from the device
10127 as the inner mapping. */
10129 bool
10130 omp_check_mapping_compatibility (location_t loc,
10131 omp_mapping_group *outer,
10132 omp_mapping_group *inner)
10134 tree first_outer = *outer->grp_start, first_inner = *inner->grp_start;
10136 gcc_assert (OMP_CLAUSE_CODE (first_outer) == OMP_CLAUSE_MAP);
10137 gcc_assert (OMP_CLAUSE_CODE (first_inner) == OMP_CLAUSE_MAP);
10139 enum gomp_map_kind outer_kind = OMP_CLAUSE_MAP_KIND (first_outer);
10140 enum gomp_map_kind inner_kind = OMP_CLAUSE_MAP_KIND (first_inner);
10142 if (outer_kind == inner_kind)
10143 return true;
10145 switch (outer_kind)
10147 case GOMP_MAP_ALWAYS_TO:
10148 if (inner_kind == GOMP_MAP_FORCE_PRESENT
10149 || inner_kind == GOMP_MAP_ALLOC
10150 || inner_kind == GOMP_MAP_TO)
10151 return true;
10152 break;
10154 case GOMP_MAP_ALWAYS_FROM:
10155 if (inner_kind == GOMP_MAP_FORCE_PRESENT
10156 || inner_kind == GOMP_MAP_ALLOC
10157 || inner_kind == GOMP_MAP_FROM)
10158 return true;
10159 break;
10161 case GOMP_MAP_TO:
10162 case GOMP_MAP_FROM:
10163 if (inner_kind == GOMP_MAP_FORCE_PRESENT
10164 || inner_kind == GOMP_MAP_ALLOC)
10165 return true;
10166 break;
10168 case GOMP_MAP_ALWAYS_TOFROM:
10169 case GOMP_MAP_TOFROM:
10170 if (inner_kind == GOMP_MAP_FORCE_PRESENT
10171 || inner_kind == GOMP_MAP_ALLOC
10172 || inner_kind == GOMP_MAP_TO
10173 || inner_kind == GOMP_MAP_FROM
10174 || inner_kind == GOMP_MAP_TOFROM)
10175 return true;
10176 break;
10178 default:
10182 error_at (loc, "data movement for component %qE is not compatible with "
10183 "movement for struct %qE", OMP_CLAUSE_DECL (first_inner),
10184 OMP_CLAUSE_DECL (first_outer));
10186 return false;
10189 /* Similar to omp_resolve_clause_dependencies, but for OpenACC. The only
10190 clause dependencies we handle for now are struct element mappings and
10191 whole-struct mappings on the same directive, and duplicate clause
10192 detection. */
10194 void
10195 oacc_resolve_clause_dependencies (vec<omp_mapping_group> *groups,
10196 hash_map<tree_operand_hash_no_se,
10197 omp_mapping_group *> *grpmap)
10199 int i;
10200 omp_mapping_group *grp;
10201 hash_set<tree_operand_hash> *seen_components = NULL;
10202 hash_set<tree_operand_hash> *shown_error = NULL;
10204 FOR_EACH_VEC_ELT (*groups, i, grp)
10206 tree grp_end = grp->grp_end;
10207 tree decl = OMP_CLAUSE_DECL (grp_end);
10209 gcc_assert (OMP_CLAUSE_CODE (grp_end) == OMP_CLAUSE_MAP);
10211 if (DECL_P (grp_end))
10212 continue;
10214 tree c = OMP_CLAUSE_DECL (*grp->grp_start);
10215 while (TREE_CODE (c) == ARRAY_REF)
10216 c = TREE_OPERAND (c, 0);
10217 if (TREE_CODE (c) != COMPONENT_REF)
10218 continue;
10219 if (!seen_components)
10220 seen_components = new hash_set<tree_operand_hash> ();
10221 if (!shown_error)
10222 shown_error = new hash_set<tree_operand_hash> ();
10223 if (seen_components->contains (c)
10224 && !shown_error->contains (c))
10226 error_at (OMP_CLAUSE_LOCATION (grp_end),
10227 "%qE appears more than once in map clauses",
10228 OMP_CLAUSE_DECL (grp_end));
10229 shown_error->add (c);
10231 else
10232 seen_components->add (c);
10234 omp_mapping_group *struct_group;
10235 if (omp_mapped_by_containing_struct (grpmap, decl, &struct_group)
10236 && *grp->grp_start == grp_end)
10238 omp_check_mapping_compatibility (OMP_CLAUSE_LOCATION (grp_end),
10239 struct_group, grp);
10240 /* Remove the whole of this mapping -- redundant. */
10241 grp->deleted = true;
10245 if (seen_components)
10246 delete seen_components;
10247 if (shown_error)
10248 delete shown_error;
10251 /* Link node NEWNODE so it is pointed to by chain INSERT_AT. NEWNODE's chain
10252 is linked to the previous node pointed to by INSERT_AT. */
10254 static tree *
10255 omp_siblist_insert_node_after (tree newnode, tree *insert_at)
10257 OMP_CLAUSE_CHAIN (newnode) = *insert_at;
10258 *insert_at = newnode;
10259 return &OMP_CLAUSE_CHAIN (newnode);
10262 /* Move NODE (which is currently pointed to by the chain OLD_POS) so it is
10263 pointed to by chain MOVE_AFTER instead. */
10265 static void
10266 omp_siblist_move_node_after (tree node, tree *old_pos, tree *move_after)
10268 gcc_assert (node == *old_pos);
10269 *old_pos = OMP_CLAUSE_CHAIN (node);
10270 OMP_CLAUSE_CHAIN (node) = *move_after;
10271 *move_after = node;
10274 /* Move nodes from FIRST_PTR (pointed to by previous node's chain) to
10275 LAST_NODE to after MOVE_AFTER chain. Similar to below function, but no
10276 new nodes are prepended to the list before splicing into the new position.
10277 Return the position we should continue scanning the list at, or NULL to
10278 stay where we were. */
10280 static tree *
10281 omp_siblist_move_nodes_after (tree *first_ptr, tree last_node,
10282 tree *move_after)
10284 if (first_ptr == move_after)
10285 return NULL;
10287 tree tmp = *first_ptr;
10288 *first_ptr = OMP_CLAUSE_CHAIN (last_node);
10289 OMP_CLAUSE_CHAIN (last_node) = *move_after;
10290 *move_after = tmp;
10292 return first_ptr;
10295 /* Concatenate two lists described by [FIRST_NEW, LAST_NEW_TAIL] and
10296 [FIRST_PTR, LAST_NODE], and insert them in the OMP clause list after chain
10297 pointer MOVE_AFTER.
10299 The latter list was previously part of the OMP clause list, and the former
10300 (prepended) part is comprised of new nodes.
10302 We start with a list of nodes starting with a struct mapping node. We
10303 rearrange the list so that new nodes starting from FIRST_NEW and whose last
10304 node's chain is LAST_NEW_TAIL comes directly after MOVE_AFTER, followed by
10305 the group of mapping nodes we are currently processing (from the chain
10306 FIRST_PTR to LAST_NODE). The return value is the pointer to the next chain
10307 we should continue processing from, or NULL to stay where we were.
10309 The transformation (in the case where MOVE_AFTER and FIRST_PTR are
10310 different) is worked through below. Here we are processing LAST_NODE, and
10311 FIRST_PTR points at the preceding mapping clause:
10313 #. mapping node chain
10314 ---------------------------------------------------
10315 A. struct_node [->B]
10316 B. comp_1 [->C]
10317 C. comp_2 [->D (move_after)]
10318 D. map_to_3 [->E]
10319 E. attach_3 [->F (first_ptr)]
10320 F. map_to_4 [->G (continue_at)]
10321 G. attach_4 (last_node) [->H]
10322 H. ...
10324 *last_new_tail = *first_ptr;
10326 I. new_node (first_new) [->F (last_new_tail)]
10328 *first_ptr = OMP_CLAUSE_CHAIN (last_node)
10330 #. mapping node chain
10331 ----------------------------------------------------
10332 A. struct_node [->B]
10333 B. comp_1 [->C]
10334 C. comp_2 [->D (move_after)]
10335 D. map_to_3 [->E]
10336 E. attach_3 [->H (first_ptr)]
10337 F. map_to_4 [->G (continue_at)]
10338 G. attach_4 (last_node) [->H]
10339 H. ...
10341 I. new_node (first_new) [->F (last_new_tail)]
10343 OMP_CLAUSE_CHAIN (last_node) = *move_after;
10345 #. mapping node chain
10346 ---------------------------------------------------
10347 A. struct_node [->B]
10348 B. comp_1 [->C]
10349 C. comp_2 [->D (move_after)]
10350 D. map_to_3 [->E]
10351 E. attach_3 [->H (continue_at)]
10352 F. map_to_4 [->G]
10353 G. attach_4 (last_node) [->D]
10354 H. ...
10356 I. new_node (first_new) [->F (last_new_tail)]
10358 *move_after = first_new;
10360 #. mapping node chain
10361 ---------------------------------------------------
10362 A. struct_node [->B]
10363 B. comp_1 [->C]
10364 C. comp_2 [->I (move_after)]
10365 D. map_to_3 [->E]
10366 E. attach_3 [->H (continue_at)]
10367 F. map_to_4 [->G]
10368 G. attach_4 (last_node) [->D]
10369 H. ...
10370 I. new_node (first_new) [->F (last_new_tail)]
10372 or, in order:
10374 #. mapping node chain
10375 ---------------------------------------------------
10376 A. struct_node [->B]
10377 B. comp_1 [->C]
10378 C. comp_2 [->I (move_after)]
10379 I. new_node (first_new) [->F (last_new_tail)]
10380 F. map_to_4 [->G]
10381 G. attach_4 (last_node) [->D]
10382 D. map_to_3 [->E]
10383 E. attach_3 [->H (continue_at)]
10384 H. ...
10387 static tree *
10388 omp_siblist_move_concat_nodes_after (tree first_new, tree *last_new_tail,
10389 tree *first_ptr, tree last_node,
10390 tree *move_after)
10392 tree *continue_at = NULL;
10393 *last_new_tail = *first_ptr;
10394 if (first_ptr == move_after)
10395 *move_after = first_new;
10396 else
10398 *first_ptr = OMP_CLAUSE_CHAIN (last_node);
10399 continue_at = first_ptr;
10400 OMP_CLAUSE_CHAIN (last_node) = *move_after;
10401 *move_after = first_new;
10403 return continue_at;
10406 /* Mapping struct members causes an additional set of nodes to be created,
10407 starting with GOMP_MAP_STRUCT followed by a number of mappings equal to the
10408 number of members being mapped, in order of ascending position (address or
10409 bitwise).
10411 We scan through the list of mapping clauses, calling this function for each
10412 struct member mapping we find, and build up the list of mappings after the
10413 initial GOMP_MAP_STRUCT node. For pointer members, these will be
10414 newly-created ALLOC nodes. For non-pointer members, the existing mapping is
10415 moved into place in the sorted list.
10417 struct {
10418 int *a;
10419 int *b;
10420 int c;
10421 int *d;
10424 #pragma (acc|omp directive) copy(struct.a[0:n], struct.b[0:n], struct.c,
10425 struct.d[0:n])
10427 GOMP_MAP_STRUCT (4)
10428 [GOMP_MAP_FIRSTPRIVATE_REFERENCE -- for refs to structs]
10429 GOMP_MAP_ALLOC (struct.a)
10430 GOMP_MAP_ALLOC (struct.b)
10431 GOMP_MAP_TO (struct.c)
10432 GOMP_MAP_ALLOC (struct.d)
10435 In the case where we are mapping references to pointers, or in Fortran if
10436 we are mapping an array with a descriptor, additional nodes may be created
10437 after the struct node list also.
10439 The return code is either a pointer to the next node to process (if the
10440 list has been rearranged), else NULL to continue with the next node in the
10441 original list. */
10443 static tree *
10444 omp_accumulate_sibling_list (enum omp_region_type region_type,
10445 enum tree_code code,
10446 hash_map<tree_operand_hash, tree>
10447 *&struct_map_to_clause, tree *grp_start_p,
10448 tree grp_end, tree *inner)
10450 poly_offset_int coffset;
10451 poly_int64 cbitpos;
10452 tree ocd = OMP_CLAUSE_DECL (grp_end);
10453 bool openmp = !(region_type & ORT_ACC);
10454 tree *continue_at = NULL;
10456 while (TREE_CODE (ocd) == ARRAY_REF)
10457 ocd = TREE_OPERAND (ocd, 0);
10459 if (INDIRECT_REF_P (ocd))
10460 ocd = TREE_OPERAND (ocd, 0);
10462 tree base = extract_base_bit_offset (ocd, &cbitpos, &coffset);
10464 bool ptr = (OMP_CLAUSE_MAP_KIND (grp_end) == GOMP_MAP_ALWAYS_POINTER);
10465 bool attach_detach = ((OMP_CLAUSE_MAP_KIND (grp_end)
10466 == GOMP_MAP_ATTACH_DETACH)
10467 || (OMP_CLAUSE_MAP_KIND (grp_end)
10468 == GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION));
10469 bool attach = (OMP_CLAUSE_MAP_KIND (grp_end) == GOMP_MAP_ATTACH
10470 || OMP_CLAUSE_MAP_KIND (grp_end) == GOMP_MAP_DETACH);
10472 /* FIXME: If we're not mapping the base pointer in some other clause on this
10473 directive, I think we want to create ALLOC/RELEASE here -- i.e. not
10474 early-exit. */
10475 if (openmp && attach_detach)
10476 return NULL;
10478 if (!struct_map_to_clause || struct_map_to_clause->get (base) == NULL)
10480 tree l = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end), OMP_CLAUSE_MAP);
10481 gomp_map_kind k = attach ? GOMP_MAP_FORCE_PRESENT : GOMP_MAP_STRUCT;
10483 OMP_CLAUSE_SET_MAP_KIND (l, k);
10485 OMP_CLAUSE_DECL (l) = unshare_expr (base);
10487 OMP_CLAUSE_SIZE (l)
10488 = (!attach ? size_int (1)
10489 : (DECL_P (OMP_CLAUSE_DECL (l))
10490 ? DECL_SIZE_UNIT (OMP_CLAUSE_DECL (l))
10491 : TYPE_SIZE_UNIT (TREE_TYPE (OMP_CLAUSE_DECL (l)))));
10492 if (struct_map_to_clause == NULL)
10493 struct_map_to_clause = new hash_map<tree_operand_hash, tree>;
10494 struct_map_to_clause->put (base, l);
10496 if (ptr || attach_detach)
10498 tree extra_node;
10499 tree alloc_node
10500 = build_omp_struct_comp_nodes (code, *grp_start_p, grp_end,
10501 &extra_node);
10502 OMP_CLAUSE_CHAIN (l) = alloc_node;
10504 tree *insert_node_pos = grp_start_p;
10506 if (extra_node)
10508 OMP_CLAUSE_CHAIN (extra_node) = *insert_node_pos;
10509 OMP_CLAUSE_CHAIN (alloc_node) = extra_node;
10511 else
10512 OMP_CLAUSE_CHAIN (alloc_node) = *insert_node_pos;
10514 *insert_node_pos = l;
10516 else
10518 gcc_assert (*grp_start_p == grp_end);
10519 grp_start_p = omp_siblist_insert_node_after (l, grp_start_p);
10522 tree noind = omp_strip_indirections (base);
10524 if (!openmp
10525 && (region_type & ORT_TARGET)
10526 && TREE_CODE (noind) == COMPONENT_REF)
10528 /* The base for this component access is a struct component access
10529 itself. Insert a node to be processed on the next iteration of
10530 our caller's loop, which will subsequently be turned into a new,
10531 inner GOMP_MAP_STRUCT mapping.
10533 We need to do this else the non-DECL_P base won't be
10534 rewritten correctly in the offloaded region. */
10535 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end),
10536 OMP_CLAUSE_MAP);
10537 OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_FORCE_PRESENT);
10538 OMP_CLAUSE_DECL (c2) = unshare_expr (noind);
10539 OMP_CLAUSE_SIZE (c2) = TYPE_SIZE_UNIT (TREE_TYPE (noind));
10540 *inner = c2;
10541 return NULL;
10544 tree sdecl = omp_strip_components_and_deref (base);
10546 if (POINTER_TYPE_P (TREE_TYPE (sdecl)) && (region_type & ORT_TARGET))
10548 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end),
10549 OMP_CLAUSE_MAP);
10550 bool base_ref
10551 = (INDIRECT_REF_P (base)
10552 && ((TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0)))
10553 == REFERENCE_TYPE)
10554 || (INDIRECT_REF_P (TREE_OPERAND (base, 0))
10555 && (TREE_CODE (TREE_TYPE (TREE_OPERAND
10556 (TREE_OPERAND (base, 0), 0)))
10557 == REFERENCE_TYPE))));
10558 enum gomp_map_kind mkind = base_ref ? GOMP_MAP_FIRSTPRIVATE_REFERENCE
10559 : GOMP_MAP_FIRSTPRIVATE_POINTER;
10560 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
10561 OMP_CLAUSE_DECL (c2) = sdecl;
10562 tree baddr = build_fold_addr_expr (base);
10563 baddr = fold_convert_loc (OMP_CLAUSE_LOCATION (grp_end),
10564 ptrdiff_type_node, baddr);
10565 /* This isn't going to be good enough when we add support for more
10566 complicated lvalue expressions. FIXME. */
10567 if (TREE_CODE (TREE_TYPE (sdecl)) == REFERENCE_TYPE
10568 && TREE_CODE (TREE_TYPE (TREE_TYPE (sdecl))) == POINTER_TYPE)
10569 sdecl = build_simple_mem_ref (sdecl);
10570 tree decladdr = fold_convert_loc (OMP_CLAUSE_LOCATION (grp_end),
10571 ptrdiff_type_node, sdecl);
10572 OMP_CLAUSE_SIZE (c2)
10573 = fold_build2_loc (OMP_CLAUSE_LOCATION (grp_end), MINUS_EXPR,
10574 ptrdiff_type_node, baddr, decladdr);
10575 /* Insert after struct node. */
10576 OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (l);
10577 OMP_CLAUSE_CHAIN (l) = c2;
10580 return NULL;
10582 else if (struct_map_to_clause)
10584 tree *osc = struct_map_to_clause->get (base);
10585 tree *sc = NULL, *scp = NULL;
10586 sc = &OMP_CLAUSE_CHAIN (*osc);
10587 /* The struct mapping might be immediately followed by a
10588 FIRSTPRIVATE_POINTER and/or FIRSTPRIVATE_REFERENCE -- if it's an
10589 indirect access or a reference, or both. (This added node is removed
10590 in omp-low.c after it has been processed there.) */
10591 if (*sc != grp_end
10592 && (OMP_CLAUSE_MAP_KIND (*sc) == GOMP_MAP_FIRSTPRIVATE_POINTER
10593 || OMP_CLAUSE_MAP_KIND (*sc) == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
10594 sc = &OMP_CLAUSE_CHAIN (*sc);
10595 for (; *sc != grp_end; sc = &OMP_CLAUSE_CHAIN (*sc))
10596 if ((ptr || attach_detach) && sc == grp_start_p)
10597 break;
10598 else if (TREE_CODE (OMP_CLAUSE_DECL (*sc)) != COMPONENT_REF
10599 && TREE_CODE (OMP_CLAUSE_DECL (*sc)) != INDIRECT_REF
10600 && TREE_CODE (OMP_CLAUSE_DECL (*sc)) != ARRAY_REF)
10601 break;
10602 else
10604 tree sc_decl = OMP_CLAUSE_DECL (*sc);
10605 poly_offset_int offset;
10606 poly_int64 bitpos;
10608 if (TREE_CODE (sc_decl) == ARRAY_REF)
10610 while (TREE_CODE (sc_decl) == ARRAY_REF)
10611 sc_decl = TREE_OPERAND (sc_decl, 0);
10612 if (TREE_CODE (sc_decl) != COMPONENT_REF
10613 || TREE_CODE (TREE_TYPE (sc_decl)) != ARRAY_TYPE)
10614 break;
10616 else if (INDIRECT_REF_P (sc_decl)
10617 && TREE_CODE (TREE_OPERAND (sc_decl, 0)) == COMPONENT_REF
10618 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (sc_decl, 0)))
10619 == REFERENCE_TYPE))
10620 sc_decl = TREE_OPERAND (sc_decl, 0);
10622 tree base2 = extract_base_bit_offset (sc_decl, &bitpos, &offset);
10623 if (!base2 || !operand_equal_p (base2, base, 0))
10624 break;
10625 if (scp)
10626 continue;
10627 if (maybe_lt (coffset, offset)
10628 || (known_eq (coffset, offset)
10629 && maybe_lt (cbitpos, bitpos)))
10631 if (ptr || attach_detach)
10632 scp = sc;
10633 else
10634 break;
10638 if (!attach)
10639 OMP_CLAUSE_SIZE (*osc)
10640 = size_binop (PLUS_EXPR, OMP_CLAUSE_SIZE (*osc), size_one_node);
10641 if (ptr || attach_detach)
10643 tree cl = NULL_TREE, extra_node;
10644 tree alloc_node = build_omp_struct_comp_nodes (code, *grp_start_p,
10645 grp_end, &extra_node);
10646 tree *tail_chain = NULL;
10648 /* Here, we have:
10650 grp_end : the last (or only) node in this group.
10651 grp_start_p : pointer to the first node in a pointer mapping group
10652 up to and including GRP_END.
10653 sc : pointer to the chain for the end of the struct component
10654 list.
10655 scp : pointer to the chain for the sorted position at which we
10656 should insert in the middle of the struct component list
10657 (else NULL to insert at end).
10658 alloc_node : the "alloc" node for the structure (pointer-type)
10659 component. We insert at SCP (if present), else SC
10660 (the end of the struct component list).
10661 extra_node : a newly-synthesized node for an additional indirect
10662 pointer mapping or a Fortran pointer set, if needed.
10663 cl : first node to prepend before grp_start_p.
10664 tail_chain : pointer to chain of last prepended node.
10666 The general idea is we move the nodes for this struct mapping
10667 together: the alloc node goes into the sorted list directly after
10668 the struct mapping, and any extra nodes (together with the nodes
10669 mapping arrays pointed to by struct components) get moved after
10670 that list. When SCP is NULL, we insert the nodes at SC, i.e. at
10671 the end of the struct component mapping list. It's important that
10672 the alloc_node comes first in that case because it's part of the
10673 sorted component mapping list (but subsequent nodes are not!). */
10675 if (scp)
10676 omp_siblist_insert_node_after (alloc_node, scp);
10678 /* Make [cl,tail_chain] a list of the alloc node (if we haven't
10679 already inserted it) and the extra_node (if it is present). The
10680 list can be empty if we added alloc_node above and there is no
10681 extra node. */
10682 if (scp && extra_node)
10684 cl = extra_node;
10685 tail_chain = &OMP_CLAUSE_CHAIN (extra_node);
10687 else if (extra_node)
10689 OMP_CLAUSE_CHAIN (alloc_node) = extra_node;
10690 cl = alloc_node;
10691 tail_chain = &OMP_CLAUSE_CHAIN (extra_node);
10693 else if (!scp)
10695 cl = alloc_node;
10696 tail_chain = &OMP_CLAUSE_CHAIN (alloc_node);
10699 continue_at
10700 = cl ? omp_siblist_move_concat_nodes_after (cl, tail_chain,
10701 grp_start_p, grp_end,
10703 : omp_siblist_move_nodes_after (grp_start_p, grp_end, sc);
10705 else if (*sc != grp_end)
10707 gcc_assert (*grp_start_p == grp_end);
10709 /* We are moving the current node back to a previous struct node:
10710 the node that used to point to the current node will now point to
10711 the next node. */
10712 continue_at = grp_start_p;
10713 /* In the non-pointer case, the mapping clause itself is moved into
10714 the correct position in the struct component list, which in this
10715 case is just SC. */
10716 omp_siblist_move_node_after (*grp_start_p, grp_start_p, sc);
10719 return continue_at;
10722 /* Scan through GROUPS, and create sorted structure sibling lists without
10723 gimplifying. */
10725 static bool
10726 omp_build_struct_sibling_lists (enum tree_code code,
10727 enum omp_region_type region_type,
10728 vec<omp_mapping_group> *groups,
10729 hash_map<tree_operand_hash_no_se,
10730 omp_mapping_group *> **grpmap,
10731 tree *list_p)
10733 unsigned i;
10734 omp_mapping_group *grp;
10735 hash_map<tree_operand_hash, tree> *struct_map_to_clause = NULL;
10736 bool success = true;
10737 tree *new_next = NULL;
10738 tree *tail = &OMP_CLAUSE_CHAIN ((*groups)[groups->length () - 1].grp_end);
10739 auto_vec<omp_mapping_group> pre_hwm_groups;
10741 FOR_EACH_VEC_ELT (*groups, i, grp)
10743 tree c = grp->grp_end;
10744 tree decl = OMP_CLAUSE_DECL (c);
10745 tree grp_end = grp->grp_end;
10746 tree sentinel = OMP_CLAUSE_CHAIN (grp_end);
10748 if (new_next)
10749 grp->grp_start = new_next;
10751 new_next = NULL;
10753 tree *grp_start_p = grp->grp_start;
10755 if (DECL_P (decl))
10756 continue;
10758 /* Skip groups we marked for deletion in
10759 oacc_resolve_clause_dependencies. */
10760 if (grp->deleted)
10761 continue;
10763 if (OMP_CLAUSE_CHAIN (*grp_start_p)
10764 && OMP_CLAUSE_CHAIN (*grp_start_p) != grp_end)
10766 /* Don't process an array descriptor that isn't inside a derived type
10767 as a struct (the GOMP_MAP_POINTER following will have the form
10768 "var.data", but such mappings are handled specially). */
10769 tree grpmid = OMP_CLAUSE_CHAIN (*grp_start_p);
10770 if (OMP_CLAUSE_CODE (grpmid) == OMP_CLAUSE_MAP
10771 && OMP_CLAUSE_MAP_KIND (grpmid) == GOMP_MAP_TO_PSET
10772 && DECL_P (OMP_CLAUSE_DECL (grpmid)))
10773 continue;
10776 tree d = decl;
10777 if (TREE_CODE (d) == ARRAY_REF)
10779 while (TREE_CODE (d) == ARRAY_REF)
10780 d = TREE_OPERAND (d, 0);
10781 if (TREE_CODE (d) == COMPONENT_REF
10782 && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE)
10783 decl = d;
10785 if (d == decl
10786 && INDIRECT_REF_P (decl)
10787 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
10788 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
10789 == REFERENCE_TYPE)
10790 && (OMP_CLAUSE_MAP_KIND (c)
10791 != GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION))
10792 decl = TREE_OPERAND (decl, 0);
10794 STRIP_NOPS (decl);
10796 if (TREE_CODE (decl) != COMPONENT_REF)
10797 continue;
10799 /* If we're mapping the whole struct in another node, skip adding this
10800 node to a sibling list. */
10801 omp_mapping_group *wholestruct;
10802 if (omp_mapped_by_containing_struct (*grpmap, OMP_CLAUSE_DECL (c),
10803 &wholestruct))
10805 if (!(region_type & ORT_ACC)
10806 && *grp_start_p == grp_end)
10807 /* Remove the whole of this mapping -- redundant. */
10808 grp->deleted = true;
10810 continue;
10813 if (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_TO_PSET
10814 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH
10815 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_DETACH
10816 && code != OACC_UPDATE
10817 && code != OMP_TARGET_UPDATE)
10819 if (error_operand_p (decl))
10821 success = false;
10822 goto error_out;
10825 tree stype = TREE_TYPE (decl);
10826 if (TREE_CODE (stype) == REFERENCE_TYPE)
10827 stype = TREE_TYPE (stype);
10828 if (TYPE_SIZE_UNIT (stype) == NULL
10829 || TREE_CODE (TYPE_SIZE_UNIT (stype)) != INTEGER_CST)
10831 error_at (OMP_CLAUSE_LOCATION (c),
10832 "mapping field %qE of variable length "
10833 "structure", OMP_CLAUSE_DECL (c));
10834 success = false;
10835 goto error_out;
10838 tree inner = NULL_TREE;
10840 new_next
10841 = omp_accumulate_sibling_list (region_type, code,
10842 struct_map_to_clause, grp_start_p,
10843 grp_end, &inner);
10845 if (inner)
10847 if (new_next && *new_next == NULL_TREE)
10848 *new_next = inner;
10849 else
10850 *tail = inner;
10852 OMP_CLAUSE_CHAIN (inner) = NULL_TREE;
10853 omp_mapping_group newgrp;
10854 newgrp.grp_start = new_next ? new_next : tail;
10855 newgrp.grp_end = inner;
10856 newgrp.mark = UNVISITED;
10857 newgrp.sibling = NULL;
10858 newgrp.deleted = false;
10859 newgrp.next = NULL;
10860 groups->safe_push (newgrp);
10862 /* !!! Growing GROUPS might invalidate the pointers in the group
10863 map. Rebuild it here. This is a bit inefficient, but
10864 shouldn't happen very often. */
10865 delete (*grpmap);
10866 *grpmap
10867 = omp_reindex_mapping_groups (list_p, groups, &pre_hwm_groups,
10868 sentinel);
10870 tail = &OMP_CLAUSE_CHAIN (inner);
10875 /* Delete groups marked for deletion above. At this point the order of the
10876 groups may no longer correspond to the order of the underlying list,
10877 which complicates this a little. First clear out OMP_CLAUSE_DECL for
10878 deleted nodes... */
10880 FOR_EACH_VEC_ELT (*groups, i, grp)
10881 if (grp->deleted)
10882 for (tree d = *grp->grp_start;
10883 d != OMP_CLAUSE_CHAIN (grp->grp_end);
10884 d = OMP_CLAUSE_CHAIN (d))
10885 OMP_CLAUSE_DECL (d) = NULL_TREE;
10887 /* ...then sweep through the list removing the now-empty nodes. */
10889 tail = list_p;
10890 while (*tail)
10892 if (OMP_CLAUSE_CODE (*tail) == OMP_CLAUSE_MAP
10893 && OMP_CLAUSE_DECL (*tail) == NULL_TREE)
10894 *tail = OMP_CLAUSE_CHAIN (*tail);
10895 else
10896 tail = &OMP_CLAUSE_CHAIN (*tail);
10899 error_out:
10900 if (struct_map_to_clause)
10901 delete struct_map_to_clause;
10903 return success;
10906 /* Scan the OMP clauses in *LIST_P, installing mappings into a new
10907 and previous omp contexts. */
10909 static void
10910 gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
10911 enum omp_region_type region_type,
10912 enum tree_code code)
10914 struct gimplify_omp_ctx *ctx, *outer_ctx;
10915 tree c;
10916 tree *orig_list_p = list_p;
10917 int handled_depend_iterators = -1;
10918 int nowait = -1;
10920 ctx = new_omp_context (region_type);
10921 ctx->code = code;
10922 outer_ctx = ctx->outer_context;
10923 if (code == OMP_TARGET)
10925 if (!lang_GNU_Fortran ())
10926 ctx->defaultmap[GDMK_POINTER] = GOVD_MAP | GOVD_MAP_0LEN_ARRAY;
10927 ctx->defaultmap[GDMK_SCALAR] = GOVD_FIRSTPRIVATE;
10928 ctx->defaultmap[GDMK_SCALAR_TARGET] = (lang_GNU_Fortran ()
10929 ? GOVD_MAP : GOVD_FIRSTPRIVATE);
10931 if (!lang_GNU_Fortran ())
10932 switch (code)
10934 case OMP_TARGET:
10935 case OMP_TARGET_DATA:
10936 case OMP_TARGET_ENTER_DATA:
10937 case OMP_TARGET_EXIT_DATA:
10938 case OACC_DECLARE:
10939 case OACC_HOST_DATA:
10940 case OACC_PARALLEL:
10941 case OACC_KERNELS:
10942 ctx->target_firstprivatize_array_bases = true;
10943 default:
10944 break;
10947 if (code == OMP_TARGET
10948 || code == OMP_TARGET_DATA
10949 || code == OMP_TARGET_ENTER_DATA
10950 || code == OMP_TARGET_EXIT_DATA)
10952 vec<omp_mapping_group> *groups;
10953 groups = omp_gather_mapping_groups (list_p);
10954 if (groups)
10956 hash_map<tree_operand_hash_no_se, omp_mapping_group *> *grpmap;
10957 grpmap = omp_index_mapping_groups (groups);
10959 omp_build_struct_sibling_lists (code, region_type, groups, &grpmap,
10960 list_p);
10962 omp_mapping_group *outlist = NULL;
10964 /* Topological sorting may fail if we have duplicate nodes, which
10965 we should have detected and shown an error for already. Skip
10966 sorting in that case. */
10967 if (seen_error ())
10968 goto failure;
10970 delete grpmap;
10971 delete groups;
10973 /* Rebuild now we have struct sibling lists. */
10974 groups = omp_gather_mapping_groups (list_p);
10975 grpmap = omp_index_mapping_groups (groups);
10977 outlist = omp_tsort_mapping_groups (groups, grpmap);
10978 outlist = omp_segregate_mapping_groups (outlist);
10979 list_p = omp_reorder_mapping_groups (groups, outlist, list_p);
10981 failure:
10982 delete grpmap;
10983 delete groups;
10986 /* OpenMP map clauses with 'present' need to go in front of those
10987 without. */
10988 tree present_map_head = NULL;
10989 tree *present_map_tail_p = &present_map_head;
10990 tree *first_map_clause_p = NULL;
10992 for (tree *c_p = list_p; *c_p; )
10994 tree c = *c_p;
10995 tree *next_c_p = &OMP_CLAUSE_CHAIN (c);
10997 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
10999 if (!first_map_clause_p)
11000 first_map_clause_p = c_p;
11001 switch (OMP_CLAUSE_MAP_KIND (c))
11003 case GOMP_MAP_PRESENT_ALLOC:
11004 case GOMP_MAP_PRESENT_FROM:
11005 case GOMP_MAP_PRESENT_TO:
11006 case GOMP_MAP_PRESENT_TOFROM:
11007 next_c_p = c_p;
11008 *c_p = OMP_CLAUSE_CHAIN (c);
11010 OMP_CLAUSE_CHAIN (c) = NULL;
11011 *present_map_tail_p = c;
11012 present_map_tail_p = &OMP_CLAUSE_CHAIN (c);
11014 break;
11016 default:
11017 break;
11021 c_p = next_c_p;
11023 if (first_map_clause_p && present_map_head)
11025 tree next = *first_map_clause_p;
11026 *first_map_clause_p = present_map_head;
11027 *present_map_tail_p = next;
11030 else if (region_type & ORT_ACC)
11032 vec<omp_mapping_group> *groups;
11033 groups = omp_gather_mapping_groups (list_p);
11034 if (groups)
11036 hash_map<tree_operand_hash_no_se, omp_mapping_group *> *grpmap;
11037 grpmap = omp_index_mapping_groups (groups);
11039 oacc_resolve_clause_dependencies (groups, grpmap);
11040 omp_build_struct_sibling_lists (code, region_type, groups, &grpmap,
11041 list_p);
11043 delete groups;
11044 delete grpmap;
11048 while ((c = *list_p) != NULL)
11050 bool remove = false;
11051 bool notice_outer = true;
11052 const char *check_non_private = NULL;
11053 unsigned int flags;
11054 tree decl;
11056 switch (OMP_CLAUSE_CODE (c))
11058 case OMP_CLAUSE_PRIVATE:
11059 flags = GOVD_PRIVATE | GOVD_EXPLICIT;
11060 if (lang_hooks.decls.omp_private_outer_ref (OMP_CLAUSE_DECL (c)))
11062 flags |= GOVD_PRIVATE_OUTER_REF;
11063 OMP_CLAUSE_PRIVATE_OUTER_REF (c) = 1;
11065 else
11066 notice_outer = false;
11067 goto do_add;
11068 case OMP_CLAUSE_SHARED:
11069 flags = GOVD_SHARED | GOVD_EXPLICIT;
11070 goto do_add;
11071 case OMP_CLAUSE_FIRSTPRIVATE:
11072 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
11073 check_non_private = "firstprivate";
11074 if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c))
11076 gcc_assert (code == OMP_TARGET);
11077 flags |= GOVD_FIRSTPRIVATE_IMPLICIT;
11079 goto do_add;
11080 case OMP_CLAUSE_LASTPRIVATE:
11081 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
11082 switch (code)
11084 case OMP_DISTRIBUTE:
11085 error_at (OMP_CLAUSE_LOCATION (c),
11086 "conditional %<lastprivate%> clause on "
11087 "%qs construct", "distribute");
11088 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
11089 break;
11090 case OMP_TASKLOOP:
11091 error_at (OMP_CLAUSE_LOCATION (c),
11092 "conditional %<lastprivate%> clause on "
11093 "%qs construct", "taskloop");
11094 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
11095 break;
11096 default:
11097 break;
11099 flags = GOVD_LASTPRIVATE | GOVD_SEEN | GOVD_EXPLICIT;
11100 if (code != OMP_LOOP)
11101 check_non_private = "lastprivate";
11102 decl = OMP_CLAUSE_DECL (c);
11103 if (error_operand_p (decl))
11104 goto do_add;
11105 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)
11106 && !lang_hooks.decls.omp_scalar_p (decl, true))
11108 error_at (OMP_CLAUSE_LOCATION (c),
11109 "non-scalar variable %qD in conditional "
11110 "%<lastprivate%> clause", decl);
11111 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
11113 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
11114 flags |= GOVD_LASTPRIVATE_CONDITIONAL;
11115 omp_lastprivate_for_combined_outer_constructs (outer_ctx, decl,
11116 false);
11117 goto do_add;
11118 case OMP_CLAUSE_REDUCTION:
11119 if (OMP_CLAUSE_REDUCTION_TASK (c))
11121 if (region_type == ORT_WORKSHARE || code == OMP_SCOPE)
11123 if (nowait == -1)
11124 nowait = omp_find_clause (*list_p,
11125 OMP_CLAUSE_NOWAIT) != NULL_TREE;
11126 if (nowait
11127 && (outer_ctx == NULL
11128 || outer_ctx->region_type != ORT_COMBINED_PARALLEL))
11130 error_at (OMP_CLAUSE_LOCATION (c),
11131 "%<task%> reduction modifier on a construct "
11132 "with a %<nowait%> clause");
11133 OMP_CLAUSE_REDUCTION_TASK (c) = 0;
11136 else if ((region_type & ORT_PARALLEL) != ORT_PARALLEL)
11138 error_at (OMP_CLAUSE_LOCATION (c),
11139 "invalid %<task%> reduction modifier on construct "
11140 "other than %<parallel%>, %qs, %<sections%> or "
11141 "%<scope%>", lang_GNU_Fortran () ? "do" : "for");
11142 OMP_CLAUSE_REDUCTION_TASK (c) = 0;
11145 if (OMP_CLAUSE_REDUCTION_INSCAN (c))
11146 switch (code)
11148 case OMP_SECTIONS:
11149 error_at (OMP_CLAUSE_LOCATION (c),
11150 "%<inscan%> %<reduction%> clause on "
11151 "%qs construct", "sections");
11152 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
11153 break;
11154 case OMP_PARALLEL:
11155 error_at (OMP_CLAUSE_LOCATION (c),
11156 "%<inscan%> %<reduction%> clause on "
11157 "%qs construct", "parallel");
11158 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
11159 break;
11160 case OMP_TEAMS:
11161 error_at (OMP_CLAUSE_LOCATION (c),
11162 "%<inscan%> %<reduction%> clause on "
11163 "%qs construct", "teams");
11164 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
11165 break;
11166 case OMP_TASKLOOP:
11167 error_at (OMP_CLAUSE_LOCATION (c),
11168 "%<inscan%> %<reduction%> clause on "
11169 "%qs construct", "taskloop");
11170 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
11171 break;
11172 case OMP_SCOPE:
11173 error_at (OMP_CLAUSE_LOCATION (c),
11174 "%<inscan%> %<reduction%> clause on "
11175 "%qs construct", "scope");
11176 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
11177 break;
11178 default:
11179 break;
11181 /* FALLTHRU */
11182 case OMP_CLAUSE_IN_REDUCTION:
11183 case OMP_CLAUSE_TASK_REDUCTION:
11184 flags = GOVD_REDUCTION | GOVD_SEEN | GOVD_EXPLICIT;
11185 /* OpenACC permits reductions on private variables. */
11186 if (!(region_type & ORT_ACC)
11187 /* taskgroup is actually not a worksharing region. */
11188 && code != OMP_TASKGROUP)
11189 check_non_private = omp_clause_code_name[OMP_CLAUSE_CODE (c)];
11190 decl = OMP_CLAUSE_DECL (c);
11191 if (TREE_CODE (decl) == MEM_REF)
11193 tree type = TREE_TYPE (decl);
11194 bool saved_into_ssa = gimplify_ctxp->into_ssa;
11195 gimplify_ctxp->into_ssa = false;
11196 if (gimplify_expr (&TYPE_MAX_VALUE (TYPE_DOMAIN (type)), pre_p,
11197 NULL, is_gimple_val, fb_rvalue, false)
11198 == GS_ERROR)
11200 gimplify_ctxp->into_ssa = saved_into_ssa;
11201 remove = true;
11202 break;
11204 gimplify_ctxp->into_ssa = saved_into_ssa;
11205 tree v = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
11206 if (DECL_P (v))
11208 omp_firstprivatize_variable (ctx, v);
11209 omp_notice_variable (ctx, v, true);
11211 decl = TREE_OPERAND (decl, 0);
11212 if (TREE_CODE (decl) == POINTER_PLUS_EXPR)
11214 gimplify_ctxp->into_ssa = false;
11215 if (gimplify_expr (&TREE_OPERAND (decl, 1), pre_p,
11216 NULL, is_gimple_val, fb_rvalue, false)
11217 == GS_ERROR)
11219 gimplify_ctxp->into_ssa = saved_into_ssa;
11220 remove = true;
11221 break;
11223 gimplify_ctxp->into_ssa = saved_into_ssa;
11224 v = TREE_OPERAND (decl, 1);
11225 if (DECL_P (v))
11227 omp_firstprivatize_variable (ctx, v);
11228 omp_notice_variable (ctx, v, true);
11230 decl = TREE_OPERAND (decl, 0);
11232 if (TREE_CODE (decl) == ADDR_EXPR
11233 || TREE_CODE (decl) == INDIRECT_REF)
11234 decl = TREE_OPERAND (decl, 0);
11236 goto do_add_decl;
11237 case OMP_CLAUSE_LINEAR:
11238 if (gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c), pre_p, NULL,
11239 is_gimple_val, fb_rvalue) == GS_ERROR)
11241 remove = true;
11242 break;
11244 else
11246 if (code == OMP_SIMD
11247 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
11249 struct gimplify_omp_ctx *octx = outer_ctx;
11250 if (octx
11251 && octx->region_type == ORT_WORKSHARE
11252 && octx->combined_loop
11253 && !octx->distribute)
11255 if (octx->outer_context
11256 && (octx->outer_context->region_type
11257 == ORT_COMBINED_PARALLEL))
11258 octx = octx->outer_context->outer_context;
11259 else
11260 octx = octx->outer_context;
11262 if (octx
11263 && octx->region_type == ORT_WORKSHARE
11264 && octx->combined_loop
11265 && octx->distribute)
11267 error_at (OMP_CLAUSE_LOCATION (c),
11268 "%<linear%> clause for variable other than "
11269 "loop iterator specified on construct "
11270 "combined with %<distribute%>");
11271 remove = true;
11272 break;
11275 /* For combined #pragma omp parallel for simd, need to put
11276 lastprivate and perhaps firstprivate too on the
11277 parallel. Similarly for #pragma omp for simd. */
11278 struct gimplify_omp_ctx *octx = outer_ctx;
11279 bool taskloop_seen = false;
11280 decl = NULL_TREE;
11283 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
11284 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
11285 break;
11286 decl = OMP_CLAUSE_DECL (c);
11287 if (error_operand_p (decl))
11289 decl = NULL_TREE;
11290 break;
11292 flags = GOVD_SEEN;
11293 if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c))
11294 flags |= GOVD_FIRSTPRIVATE;
11295 if (!OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
11296 flags |= GOVD_LASTPRIVATE;
11297 if (octx
11298 && octx->region_type == ORT_WORKSHARE
11299 && octx->combined_loop)
11301 if (octx->outer_context
11302 && (octx->outer_context->region_type
11303 == ORT_COMBINED_PARALLEL))
11304 octx = octx->outer_context;
11305 else if (omp_check_private (octx, decl, false))
11306 break;
11308 else if (octx
11309 && (octx->region_type & ORT_TASK) != 0
11310 && octx->combined_loop)
11311 taskloop_seen = true;
11312 else if (octx
11313 && octx->region_type == ORT_COMBINED_PARALLEL
11314 && ((ctx->region_type == ORT_WORKSHARE
11315 && octx == outer_ctx)
11316 || taskloop_seen))
11317 flags = GOVD_SEEN | GOVD_SHARED;
11318 else if (octx
11319 && ((octx->region_type & ORT_COMBINED_TEAMS)
11320 == ORT_COMBINED_TEAMS))
11321 flags = GOVD_SEEN | GOVD_SHARED;
11322 else if (octx
11323 && octx->region_type == ORT_COMBINED_TARGET)
11325 if (flags & GOVD_LASTPRIVATE)
11326 flags = GOVD_SEEN | GOVD_MAP;
11328 else
11329 break;
11330 splay_tree_node on
11331 = splay_tree_lookup (octx->variables,
11332 (splay_tree_key) decl);
11333 if (on && (on->value & GOVD_DATA_SHARE_CLASS) != 0)
11335 octx = NULL;
11336 break;
11338 omp_add_variable (octx, decl, flags);
11339 if (octx->outer_context == NULL)
11340 break;
11341 octx = octx->outer_context;
11343 while (1);
11344 if (octx
11345 && decl
11346 && (!OMP_CLAUSE_LINEAR_NO_COPYIN (c)
11347 || !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
11348 omp_notice_variable (octx, decl, true);
11350 flags = GOVD_LINEAR | GOVD_EXPLICIT;
11351 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
11352 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
11354 notice_outer = false;
11355 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
11357 goto do_add;
11359 case OMP_CLAUSE_MAP:
11360 decl = OMP_CLAUSE_DECL (c);
11361 if (error_operand_p (decl))
11362 remove = true;
11363 switch (code)
11365 case OMP_TARGET:
11366 break;
11367 case OACC_DATA:
11368 if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
11369 break;
11370 /* FALLTHRU */
11371 case OMP_TARGET_DATA:
11372 case OMP_TARGET_ENTER_DATA:
11373 case OMP_TARGET_EXIT_DATA:
11374 case OACC_ENTER_DATA:
11375 case OACC_EXIT_DATA:
11376 case OACC_HOST_DATA:
11377 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
11378 || (OMP_CLAUSE_MAP_KIND (c)
11379 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
11380 /* For target {,enter ,exit }data only the array slice is
11381 mapped, but not the pointer to it. */
11382 remove = true;
11383 break;
11384 default:
11385 break;
11387 if (remove)
11388 break;
11389 if (DECL_P (decl) && outer_ctx && (region_type & ORT_ACC))
11391 struct gimplify_omp_ctx *octx;
11392 for (octx = outer_ctx; octx; octx = octx->outer_context)
11394 if (octx->region_type != ORT_ACC_HOST_DATA)
11395 break;
11396 splay_tree_node n2
11397 = splay_tree_lookup (octx->variables,
11398 (splay_tree_key) decl);
11399 if (n2)
11400 error_at (OMP_CLAUSE_LOCATION (c), "variable %qE "
11401 "declared in enclosing %<host_data%> region",
11402 DECL_NAME (decl));
11405 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
11406 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
11407 : TYPE_SIZE_UNIT (TREE_TYPE (decl));
11408 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
11409 NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
11411 remove = true;
11412 break;
11414 else if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
11415 || (OMP_CLAUSE_MAP_KIND (c)
11416 == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
11417 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
11418 && TREE_CODE (OMP_CLAUSE_SIZE (c)) != INTEGER_CST)
11420 OMP_CLAUSE_SIZE (c)
11421 = get_initialized_tmp_var (OMP_CLAUSE_SIZE (c), pre_p, NULL,
11422 false);
11423 if ((region_type & ORT_TARGET) != 0)
11424 omp_add_variable (ctx, OMP_CLAUSE_SIZE (c),
11425 GOVD_FIRSTPRIVATE | GOVD_SEEN);
11428 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT)
11430 tree base = omp_strip_components_and_deref (decl);
11431 if (DECL_P (base))
11433 decl = base;
11434 splay_tree_node n
11435 = splay_tree_lookup (ctx->variables,
11436 (splay_tree_key) decl);
11437 if (seen_error ()
11438 && n
11439 && (n->value & (GOVD_MAP | GOVD_FIRSTPRIVATE)) != 0)
11441 remove = true;
11442 break;
11444 flags = GOVD_MAP | GOVD_EXPLICIT;
11446 goto do_add_decl;
11450 if (TREE_CODE (decl) == TARGET_EXPR)
11452 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
11453 is_gimple_lvalue, fb_lvalue)
11454 == GS_ERROR)
11455 remove = true;
11457 else if (!DECL_P (decl))
11459 tree d = decl, *pd;
11460 if (TREE_CODE (d) == ARRAY_REF)
11462 while (TREE_CODE (d) == ARRAY_REF)
11463 d = TREE_OPERAND (d, 0);
11464 if (TREE_CODE (d) == COMPONENT_REF
11465 && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE)
11466 decl = d;
11468 pd = &OMP_CLAUSE_DECL (c);
11469 if (d == decl
11470 && TREE_CODE (decl) == INDIRECT_REF
11471 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
11472 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
11473 == REFERENCE_TYPE)
11474 && (OMP_CLAUSE_MAP_KIND (c)
11475 != GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION))
11477 pd = &TREE_OPERAND (decl, 0);
11478 decl = TREE_OPERAND (decl, 0);
11480 /* An "attach/detach" operation on an update directive should
11481 behave as a GOMP_MAP_ALWAYS_POINTER. Beware that
11482 unlike attach or detach map kinds, GOMP_MAP_ALWAYS_POINTER
11483 depends on the previous mapping. */
11484 if (code == OACC_UPDATE
11485 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
11486 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_ALWAYS_POINTER);
11488 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
11490 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
11491 == ARRAY_TYPE)
11492 remove = true;
11493 else
11495 gomp_map_kind k = ((code == OACC_EXIT_DATA
11496 || code == OMP_TARGET_EXIT_DATA)
11497 ? GOMP_MAP_DETACH : GOMP_MAP_ATTACH);
11498 OMP_CLAUSE_SET_MAP_KIND (c, k);
11502 tree cref = decl;
11504 while (TREE_CODE (cref) == ARRAY_REF)
11505 cref = TREE_OPERAND (cref, 0);
11507 if (TREE_CODE (cref) == INDIRECT_REF)
11508 cref = TREE_OPERAND (cref, 0);
11510 if (TREE_CODE (cref) == COMPONENT_REF)
11512 tree base = cref;
11513 while (base && !DECL_P (base))
11515 tree innerbase = omp_get_base_pointer (base);
11516 if (!innerbase)
11517 break;
11518 base = innerbase;
11520 if (base
11521 && DECL_P (base)
11522 && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c))
11523 && POINTER_TYPE_P (TREE_TYPE (base)))
11525 splay_tree_node n
11526 = splay_tree_lookup (ctx->variables,
11527 (splay_tree_key) base);
11528 n->value |= GOVD_SEEN;
11532 if (code == OMP_TARGET && OMP_CLAUSE_MAP_IN_REDUCTION (c))
11534 /* Don't gimplify *pd fully at this point, as the base
11535 will need to be adjusted during omp lowering. */
11536 auto_vec<tree, 10> expr_stack;
11537 tree *p = pd;
11538 while (handled_component_p (*p)
11539 || TREE_CODE (*p) == INDIRECT_REF
11540 || TREE_CODE (*p) == ADDR_EXPR
11541 || TREE_CODE (*p) == MEM_REF
11542 || TREE_CODE (*p) == NON_LVALUE_EXPR)
11544 expr_stack.safe_push (*p);
11545 p = &TREE_OPERAND (*p, 0);
11547 for (int i = expr_stack.length () - 1; i >= 0; i--)
11549 tree t = expr_stack[i];
11550 if (TREE_CODE (t) == ARRAY_REF
11551 || TREE_CODE (t) == ARRAY_RANGE_REF)
11553 if (TREE_OPERAND (t, 2) == NULL_TREE)
11555 tree low = unshare_expr (array_ref_low_bound (t));
11556 if (!is_gimple_min_invariant (low))
11558 TREE_OPERAND (t, 2) = low;
11559 if (gimplify_expr (&TREE_OPERAND (t, 2),
11560 pre_p, NULL,
11561 is_gimple_reg,
11562 fb_rvalue) == GS_ERROR)
11563 remove = true;
11566 else if (gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
11567 NULL, is_gimple_reg,
11568 fb_rvalue) == GS_ERROR)
11569 remove = true;
11570 if (TREE_OPERAND (t, 3) == NULL_TREE)
11572 tree elmt_size = array_ref_element_size (t);
11573 if (!is_gimple_min_invariant (elmt_size))
11575 elmt_size = unshare_expr (elmt_size);
11576 tree elmt_type
11577 = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t,
11578 0)));
11579 tree factor
11580 = size_int (TYPE_ALIGN_UNIT (elmt_type));
11581 elmt_size
11582 = size_binop (EXACT_DIV_EXPR, elmt_size,
11583 factor);
11584 TREE_OPERAND (t, 3) = elmt_size;
11585 if (gimplify_expr (&TREE_OPERAND (t, 3),
11586 pre_p, NULL,
11587 is_gimple_reg,
11588 fb_rvalue) == GS_ERROR)
11589 remove = true;
11592 else if (gimplify_expr (&TREE_OPERAND (t, 3), pre_p,
11593 NULL, is_gimple_reg,
11594 fb_rvalue) == GS_ERROR)
11595 remove = true;
11597 else if (TREE_CODE (t) == COMPONENT_REF)
11599 if (TREE_OPERAND (t, 2) == NULL_TREE)
11601 tree offset = component_ref_field_offset (t);
11602 if (!is_gimple_min_invariant (offset))
11604 offset = unshare_expr (offset);
11605 tree field = TREE_OPERAND (t, 1);
11606 tree factor
11607 = size_int (DECL_OFFSET_ALIGN (field)
11608 / BITS_PER_UNIT);
11609 offset = size_binop (EXACT_DIV_EXPR, offset,
11610 factor);
11611 TREE_OPERAND (t, 2) = offset;
11612 if (gimplify_expr (&TREE_OPERAND (t, 2),
11613 pre_p, NULL,
11614 is_gimple_reg,
11615 fb_rvalue) == GS_ERROR)
11616 remove = true;
11619 else if (gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
11620 NULL, is_gimple_reg,
11621 fb_rvalue) == GS_ERROR)
11622 remove = true;
11625 for (; expr_stack.length () > 0; )
11627 tree t = expr_stack.pop ();
11629 if (TREE_CODE (t) == ARRAY_REF
11630 || TREE_CODE (t) == ARRAY_RANGE_REF)
11632 if (!is_gimple_min_invariant (TREE_OPERAND (t, 1))
11633 && gimplify_expr (&TREE_OPERAND (t, 1), pre_p,
11634 NULL, is_gimple_val,
11635 fb_rvalue) == GS_ERROR)
11636 remove = true;
11640 else if (gimplify_expr (pd, pre_p, NULL, is_gimple_lvalue,
11641 fb_lvalue) == GS_ERROR)
11643 remove = true;
11644 break;
11646 break;
11648 flags = GOVD_MAP | GOVD_EXPLICIT;
11649 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TO
11650 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TOFROM)
11651 flags |= GOVD_MAP_ALWAYS_TO;
11653 if ((code == OMP_TARGET
11654 || code == OMP_TARGET_DATA
11655 || code == OMP_TARGET_ENTER_DATA
11656 || code == OMP_TARGET_EXIT_DATA)
11657 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
11659 for (struct gimplify_omp_ctx *octx = outer_ctx; octx;
11660 octx = octx->outer_context)
11662 splay_tree_node n
11663 = splay_tree_lookup (octx->variables,
11664 (splay_tree_key) OMP_CLAUSE_DECL (c));
11665 /* If this is contained in an outer OpenMP region as a
11666 firstprivate value, remove the attach/detach. */
11667 if (n && (n->value & GOVD_FIRSTPRIVATE))
11669 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FIRSTPRIVATE_POINTER);
11670 goto do_add;
11674 enum gomp_map_kind map_kind = (code == OMP_TARGET_EXIT_DATA
11675 ? GOMP_MAP_DETACH
11676 : GOMP_MAP_ATTACH);
11677 OMP_CLAUSE_SET_MAP_KIND (c, map_kind);
11680 goto do_add;
11682 case OMP_CLAUSE_AFFINITY:
11683 gimplify_omp_affinity (list_p, pre_p);
11684 remove = true;
11685 break;
11686 case OMP_CLAUSE_DOACROSS:
11687 if (OMP_CLAUSE_DOACROSS_KIND (c) == OMP_CLAUSE_DOACROSS_SINK)
11689 tree deps = OMP_CLAUSE_DECL (c);
11690 while (deps && TREE_CODE (deps) == TREE_LIST)
11692 if (TREE_CODE (TREE_PURPOSE (deps)) == TRUNC_DIV_EXPR
11693 && DECL_P (TREE_OPERAND (TREE_PURPOSE (deps), 1)))
11694 gimplify_expr (&TREE_OPERAND (TREE_PURPOSE (deps), 1),
11695 pre_p, NULL, is_gimple_val, fb_rvalue);
11696 deps = TREE_CHAIN (deps);
11699 else
11700 gcc_assert (OMP_CLAUSE_DOACROSS_KIND (c)
11701 == OMP_CLAUSE_DOACROSS_SOURCE);
11702 break;
11703 case OMP_CLAUSE_DEPEND:
11704 if (handled_depend_iterators == -1)
11705 handled_depend_iterators = gimplify_omp_depend (list_p, pre_p);
11706 if (handled_depend_iterators)
11708 if (handled_depend_iterators == 2)
11709 remove = true;
11710 break;
11712 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
11714 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
11715 NULL, is_gimple_val, fb_rvalue);
11716 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
11718 if (error_operand_p (OMP_CLAUSE_DECL (c)))
11720 remove = true;
11721 break;
11723 if (OMP_CLAUSE_DECL (c) != null_pointer_node)
11725 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
11726 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
11727 is_gimple_val, fb_rvalue) == GS_ERROR)
11729 remove = true;
11730 break;
11733 if (code == OMP_TASK)
11734 ctx->has_depend = true;
11735 break;
11737 case OMP_CLAUSE_TO:
11738 case OMP_CLAUSE_FROM:
11739 case OMP_CLAUSE__CACHE_:
11740 decl = OMP_CLAUSE_DECL (c);
11741 if (error_operand_p (decl))
11743 remove = true;
11744 break;
11746 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
11747 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
11748 : TYPE_SIZE_UNIT (TREE_TYPE (decl));
11749 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
11750 NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
11752 remove = true;
11753 break;
11755 if (!DECL_P (decl))
11757 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p,
11758 NULL, is_gimple_lvalue, fb_lvalue)
11759 == GS_ERROR)
11761 remove = true;
11762 break;
11764 break;
11766 goto do_notice;
11768 case OMP_CLAUSE_USE_DEVICE_PTR:
11769 case OMP_CLAUSE_USE_DEVICE_ADDR:
11770 flags = GOVD_EXPLICIT;
11771 goto do_add;
11773 case OMP_CLAUSE_HAS_DEVICE_ADDR:
11774 decl = OMP_CLAUSE_DECL (c);
11775 while (TREE_CODE (decl) == INDIRECT_REF
11776 || TREE_CODE (decl) == ARRAY_REF)
11777 decl = TREE_OPERAND (decl, 0);
11778 flags = GOVD_EXPLICIT;
11779 goto do_add_decl;
11781 case OMP_CLAUSE_IS_DEVICE_PTR:
11782 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
11783 goto do_add;
11785 do_add:
11786 decl = OMP_CLAUSE_DECL (c);
11787 do_add_decl:
11788 if (error_operand_p (decl))
11790 remove = true;
11791 break;
11793 if (DECL_NAME (decl) == NULL_TREE && (flags & GOVD_SHARED) == 0)
11795 tree t = omp_member_access_dummy_var (decl);
11796 if (t)
11798 tree v = DECL_VALUE_EXPR (decl);
11799 DECL_NAME (decl) = DECL_NAME (TREE_OPERAND (v, 1));
11800 if (outer_ctx)
11801 omp_notice_variable (outer_ctx, t, true);
11804 if (code == OACC_DATA
11805 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
11806 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
11807 flags |= GOVD_MAP_0LEN_ARRAY;
11808 omp_add_variable (ctx, decl, flags);
11809 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
11810 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
11811 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
11812 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
11814 struct gimplify_omp_ctx *pctx
11815 = code == OMP_TARGET ? outer_ctx : ctx;
11816 if (pctx)
11817 omp_add_variable (pctx, OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
11818 GOVD_LOCAL | GOVD_SEEN);
11819 if (pctx
11820 && OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
11821 && walk_tree (&OMP_CLAUSE_REDUCTION_INIT (c),
11822 find_decl_expr,
11823 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
11824 NULL) == NULL_TREE)
11825 omp_add_variable (pctx,
11826 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
11827 GOVD_LOCAL | GOVD_SEEN);
11828 gimplify_omp_ctxp = pctx;
11829 push_gimplify_context ();
11831 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
11832 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
11834 gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c),
11835 &OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c));
11836 pop_gimplify_context
11837 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c)));
11838 push_gimplify_context ();
11839 gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c),
11840 &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
11841 pop_gimplify_context
11842 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c)));
11843 OMP_CLAUSE_REDUCTION_INIT (c) = NULL_TREE;
11844 OMP_CLAUSE_REDUCTION_MERGE (c) = NULL_TREE;
11846 gimplify_omp_ctxp = outer_ctx;
11848 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
11849 && OMP_CLAUSE_LASTPRIVATE_STMT (c))
11851 gimplify_omp_ctxp = ctx;
11852 push_gimplify_context ();
11853 if (TREE_CODE (OMP_CLAUSE_LASTPRIVATE_STMT (c)) != BIND_EXPR)
11855 tree bind = build3 (BIND_EXPR, void_type_node, NULL,
11856 NULL, NULL);
11857 TREE_SIDE_EFFECTS (bind) = 1;
11858 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LASTPRIVATE_STMT (c);
11859 OMP_CLAUSE_LASTPRIVATE_STMT (c) = bind;
11861 gimplify_and_add (OMP_CLAUSE_LASTPRIVATE_STMT (c),
11862 &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
11863 pop_gimplify_context
11864 (gimple_seq_first_stmt (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c)));
11865 OMP_CLAUSE_LASTPRIVATE_STMT (c) = NULL_TREE;
11867 gimplify_omp_ctxp = outer_ctx;
11869 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
11870 && OMP_CLAUSE_LINEAR_STMT (c))
11872 gimplify_omp_ctxp = ctx;
11873 push_gimplify_context ();
11874 if (TREE_CODE (OMP_CLAUSE_LINEAR_STMT (c)) != BIND_EXPR)
11876 tree bind = build3 (BIND_EXPR, void_type_node, NULL,
11877 NULL, NULL);
11878 TREE_SIDE_EFFECTS (bind) = 1;
11879 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LINEAR_STMT (c);
11880 OMP_CLAUSE_LINEAR_STMT (c) = bind;
11882 gimplify_and_add (OMP_CLAUSE_LINEAR_STMT (c),
11883 &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c));
11884 pop_gimplify_context
11885 (gimple_seq_first_stmt (OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c)));
11886 OMP_CLAUSE_LINEAR_STMT (c) = NULL_TREE;
11888 gimplify_omp_ctxp = outer_ctx;
11890 if (notice_outer)
11891 goto do_notice;
11892 break;
11894 case OMP_CLAUSE_COPYIN:
11895 case OMP_CLAUSE_COPYPRIVATE:
11896 decl = OMP_CLAUSE_DECL (c);
11897 if (error_operand_p (decl))
11899 remove = true;
11900 break;
11902 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_COPYPRIVATE
11903 && !remove
11904 && !omp_check_private (ctx, decl, true))
11906 remove = true;
11907 if (is_global_var (decl))
11909 if (DECL_THREAD_LOCAL_P (decl))
11910 remove = false;
11911 else if (DECL_HAS_VALUE_EXPR_P (decl))
11913 tree value = get_base_address (DECL_VALUE_EXPR (decl));
11915 if (value
11916 && DECL_P (value)
11917 && DECL_THREAD_LOCAL_P (value))
11918 remove = false;
11921 if (remove)
11922 error_at (OMP_CLAUSE_LOCATION (c),
11923 "copyprivate variable %qE is not threadprivate"
11924 " or private in outer context", DECL_NAME (decl));
11926 do_notice:
11927 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
11928 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
11929 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
11930 && outer_ctx
11931 && ((region_type & ORT_TASKLOOP) == ORT_TASKLOOP
11932 || (region_type == ORT_WORKSHARE
11933 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
11934 && (OMP_CLAUSE_REDUCTION_INSCAN (c)
11935 || code == OMP_LOOP)))
11936 && (outer_ctx->region_type == ORT_COMBINED_PARALLEL
11937 || (code == OMP_LOOP
11938 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
11939 && ((outer_ctx->region_type & ORT_COMBINED_TEAMS)
11940 == ORT_COMBINED_TEAMS))))
11942 splay_tree_node on
11943 = splay_tree_lookup (outer_ctx->variables,
11944 (splay_tree_key)decl);
11945 if (on == NULL || (on->value & GOVD_DATA_SHARE_CLASS) == 0)
11947 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
11948 && TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
11949 && (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
11950 || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
11951 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
11952 == POINTER_TYPE))))
11953 omp_firstprivatize_variable (outer_ctx, decl);
11954 else
11956 omp_add_variable (outer_ctx, decl,
11957 GOVD_SEEN | GOVD_SHARED);
11958 if (outer_ctx->outer_context)
11959 omp_notice_variable (outer_ctx->outer_context, decl,
11960 true);
11964 if (outer_ctx)
11965 omp_notice_variable (outer_ctx, decl, true);
11966 if (check_non_private
11967 && (region_type == ORT_WORKSHARE || code == OMP_SCOPE)
11968 && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
11969 || decl == OMP_CLAUSE_DECL (c)
11970 || (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
11971 && (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
11972 == ADDR_EXPR
11973 || (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
11974 == POINTER_PLUS_EXPR
11975 && (TREE_CODE (TREE_OPERAND (TREE_OPERAND
11976 (OMP_CLAUSE_DECL (c), 0), 0))
11977 == ADDR_EXPR)))))
11978 && omp_check_private (ctx, decl, false))
11980 error ("%s variable %qE is private in outer context",
11981 check_non_private, DECL_NAME (decl));
11982 remove = true;
11984 break;
11986 case OMP_CLAUSE_DETACH:
11987 flags = GOVD_FIRSTPRIVATE | GOVD_SEEN;
11988 goto do_add;
11990 case OMP_CLAUSE_IF:
11991 if (OMP_CLAUSE_IF_MODIFIER (c) != ERROR_MARK
11992 && OMP_CLAUSE_IF_MODIFIER (c) != code)
11994 const char *p[2];
11995 for (int i = 0; i < 2; i++)
11996 switch (i ? OMP_CLAUSE_IF_MODIFIER (c) : code)
11998 case VOID_CST: p[i] = "cancel"; break;
11999 case OMP_PARALLEL: p[i] = "parallel"; break;
12000 case OMP_SIMD: p[i] = "simd"; break;
12001 case OMP_TASK: p[i] = "task"; break;
12002 case OMP_TASKLOOP: p[i] = "taskloop"; break;
12003 case OMP_TARGET_DATA: p[i] = "target data"; break;
12004 case OMP_TARGET: p[i] = "target"; break;
12005 case OMP_TARGET_UPDATE: p[i] = "target update"; break;
12006 case OMP_TARGET_ENTER_DATA:
12007 p[i] = "target enter data"; break;
12008 case OMP_TARGET_EXIT_DATA: p[i] = "target exit data"; break;
12009 default: gcc_unreachable ();
12011 error_at (OMP_CLAUSE_LOCATION (c),
12012 "expected %qs %<if%> clause modifier rather than %qs",
12013 p[0], p[1]);
12014 remove = true;
12016 /* Fall through. */
12018 case OMP_CLAUSE_FINAL:
12019 OMP_CLAUSE_OPERAND (c, 0)
12020 = gimple_boolify (OMP_CLAUSE_OPERAND (c, 0));
12021 /* Fall through. */
12023 case OMP_CLAUSE_NUM_TEAMS:
12024 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
12025 && OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
12026 && !is_gimple_min_invariant (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)))
12028 if (error_operand_p (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)))
12030 remove = true;
12031 break;
12033 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
12034 = get_initialized_tmp_var (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c),
12035 pre_p, NULL, true);
12037 /* Fall through. */
12039 case OMP_CLAUSE_SCHEDULE:
12040 case OMP_CLAUSE_NUM_THREADS:
12041 case OMP_CLAUSE_THREAD_LIMIT:
12042 case OMP_CLAUSE_DIST_SCHEDULE:
12043 case OMP_CLAUSE_DEVICE:
12044 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE
12045 && OMP_CLAUSE_DEVICE_ANCESTOR (c))
12047 if (code != OMP_TARGET)
12049 error_at (OMP_CLAUSE_LOCATION (c),
12050 "%<device%> clause with %<ancestor%> is only "
12051 "allowed on %<target%> construct");
12052 remove = true;
12053 break;
12056 tree clauses = *orig_list_p;
12057 for (; clauses ; clauses = OMP_CLAUSE_CHAIN (clauses))
12058 if (OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_DEVICE
12059 && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_FIRSTPRIVATE
12060 && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_PRIVATE
12061 && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_DEFAULTMAP
12062 && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_MAP
12065 error_at (OMP_CLAUSE_LOCATION (c),
12066 "with %<ancestor%>, only the %<device%>, "
12067 "%<firstprivate%>, %<private%>, %<defaultmap%>, "
12068 "and %<map%> clauses may appear on the "
12069 "construct");
12070 remove = true;
12071 break;
12074 /* Fall through. */
12076 case OMP_CLAUSE_PRIORITY:
12077 case OMP_CLAUSE_GRAINSIZE:
12078 case OMP_CLAUSE_NUM_TASKS:
12079 case OMP_CLAUSE_FILTER:
12080 case OMP_CLAUSE_HINT:
12081 case OMP_CLAUSE_ASYNC:
12082 case OMP_CLAUSE_WAIT:
12083 case OMP_CLAUSE_NUM_GANGS:
12084 case OMP_CLAUSE_NUM_WORKERS:
12085 case OMP_CLAUSE_VECTOR_LENGTH:
12086 case OMP_CLAUSE_WORKER:
12087 case OMP_CLAUSE_VECTOR:
12088 if (OMP_CLAUSE_OPERAND (c, 0)
12089 && !is_gimple_min_invariant (OMP_CLAUSE_OPERAND (c, 0)))
12091 if (error_operand_p (OMP_CLAUSE_OPERAND (c, 0)))
12093 remove = true;
12094 break;
12096 /* All these clauses care about value, not a particular decl,
12097 so try to force it into a SSA_NAME or fresh temporary. */
12098 OMP_CLAUSE_OPERAND (c, 0)
12099 = get_initialized_tmp_var (OMP_CLAUSE_OPERAND (c, 0),
12100 pre_p, NULL, true);
12102 break;
12104 case OMP_CLAUSE_GANG:
12105 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
12106 is_gimple_val, fb_rvalue) == GS_ERROR)
12107 remove = true;
12108 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 1), pre_p, NULL,
12109 is_gimple_val, fb_rvalue) == GS_ERROR)
12110 remove = true;
12111 break;
12113 case OMP_CLAUSE_NOWAIT:
12114 nowait = 1;
12115 break;
12117 case OMP_CLAUSE_ORDERED:
12118 case OMP_CLAUSE_UNTIED:
12119 case OMP_CLAUSE_COLLAPSE:
12120 case OMP_CLAUSE_TILE:
12121 case OMP_CLAUSE_AUTO:
12122 case OMP_CLAUSE_SEQ:
12123 case OMP_CLAUSE_INDEPENDENT:
12124 case OMP_CLAUSE_MERGEABLE:
12125 case OMP_CLAUSE_PROC_BIND:
12126 case OMP_CLAUSE_SAFELEN:
12127 case OMP_CLAUSE_SIMDLEN:
12128 case OMP_CLAUSE_NOGROUP:
12129 case OMP_CLAUSE_THREADS:
12130 case OMP_CLAUSE_SIMD:
12131 case OMP_CLAUSE_BIND:
12132 case OMP_CLAUSE_IF_PRESENT:
12133 case OMP_CLAUSE_FINALIZE:
12134 break;
12136 case OMP_CLAUSE_ORDER:
12137 ctx->order_concurrent = true;
12138 break;
12140 case OMP_CLAUSE_DEFAULTMAP:
12141 enum gimplify_defaultmap_kind gdmkmin, gdmkmax;
12142 switch (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c))
12144 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
12145 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL:
12146 gdmkmin = GDMK_SCALAR;
12147 gdmkmax = GDMK_POINTER;
12148 break;
12149 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
12150 gdmkmin = GDMK_SCALAR;
12151 gdmkmax = GDMK_SCALAR_TARGET;
12152 break;
12153 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
12154 gdmkmin = gdmkmax = GDMK_AGGREGATE;
12155 break;
12156 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALLOCATABLE:
12157 gdmkmin = gdmkmax = GDMK_ALLOCATABLE;
12158 break;
12159 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
12160 gdmkmin = gdmkmax = GDMK_POINTER;
12161 break;
12162 default:
12163 gcc_unreachable ();
12165 for (int gdmk = gdmkmin; gdmk <= gdmkmax; gdmk++)
12166 switch (OMP_CLAUSE_DEFAULTMAP_BEHAVIOR (c))
12168 case OMP_CLAUSE_DEFAULTMAP_ALLOC:
12169 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_ALLOC_ONLY;
12170 break;
12171 case OMP_CLAUSE_DEFAULTMAP_TO:
12172 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_TO_ONLY;
12173 break;
12174 case OMP_CLAUSE_DEFAULTMAP_FROM:
12175 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_FROM_ONLY;
12176 break;
12177 case OMP_CLAUSE_DEFAULTMAP_TOFROM:
12178 ctx->defaultmap[gdmk] = GOVD_MAP;
12179 break;
12180 case OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE:
12181 ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE;
12182 break;
12183 case OMP_CLAUSE_DEFAULTMAP_NONE:
12184 ctx->defaultmap[gdmk] = 0;
12185 break;
12186 case OMP_CLAUSE_DEFAULTMAP_PRESENT:
12187 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
12188 break;
12189 case OMP_CLAUSE_DEFAULTMAP_DEFAULT:
12190 switch (gdmk)
12192 case GDMK_SCALAR:
12193 ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE;
12194 break;
12195 case GDMK_SCALAR_TARGET:
12196 ctx->defaultmap[gdmk] = (lang_GNU_Fortran ()
12197 ? GOVD_MAP : GOVD_FIRSTPRIVATE);
12198 break;
12199 case GDMK_AGGREGATE:
12200 case GDMK_ALLOCATABLE:
12201 ctx->defaultmap[gdmk] = GOVD_MAP;
12202 break;
12203 case GDMK_POINTER:
12204 ctx->defaultmap[gdmk] = GOVD_MAP;
12205 if (!lang_GNU_Fortran ())
12206 ctx->defaultmap[gdmk] |= GOVD_MAP_0LEN_ARRAY;
12207 break;
12208 default:
12209 gcc_unreachable ();
12211 break;
12212 default:
12213 gcc_unreachable ();
12215 break;
12217 case OMP_CLAUSE_ALIGNED:
12218 decl = OMP_CLAUSE_DECL (c);
12219 if (error_operand_p (decl))
12221 remove = true;
12222 break;
12224 if (gimplify_expr (&OMP_CLAUSE_ALIGNED_ALIGNMENT (c), pre_p, NULL,
12225 is_gimple_val, fb_rvalue) == GS_ERROR)
12227 remove = true;
12228 break;
12230 if (!is_global_var (decl)
12231 && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
12232 omp_add_variable (ctx, decl, GOVD_ALIGNED);
12233 break;
12235 case OMP_CLAUSE_NONTEMPORAL:
12236 decl = OMP_CLAUSE_DECL (c);
12237 if (error_operand_p (decl))
12239 remove = true;
12240 break;
12242 omp_add_variable (ctx, decl, GOVD_NONTEMPORAL);
12243 break;
12245 case OMP_CLAUSE_ALLOCATE:
12246 decl = OMP_CLAUSE_DECL (c);
12247 if (error_operand_p (decl))
12249 remove = true;
12250 break;
12252 if (gimplify_expr (&OMP_CLAUSE_ALLOCATE_ALLOCATOR (c), pre_p, NULL,
12253 is_gimple_val, fb_rvalue) == GS_ERROR)
12255 remove = true;
12256 break;
12258 else if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) == NULL_TREE
12259 || (TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c))
12260 == INTEGER_CST))
12262 else if (code == OMP_TASKLOOP
12263 || !DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)))
12264 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
12265 = get_initialized_tmp_var (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
12266 pre_p, NULL, false);
12267 break;
12269 case OMP_CLAUSE_DEFAULT:
12270 ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
12271 break;
12273 case OMP_CLAUSE_INCLUSIVE:
12274 case OMP_CLAUSE_EXCLUSIVE:
12275 decl = OMP_CLAUSE_DECL (c);
12277 splay_tree_node n = splay_tree_lookup (outer_ctx->variables,
12278 (splay_tree_key) decl);
12279 if (n == NULL || (n->value & GOVD_REDUCTION) == 0)
12281 error_at (OMP_CLAUSE_LOCATION (c),
12282 "%qD specified in %qs clause but not in %<inscan%> "
12283 "%<reduction%> clause on the containing construct",
12284 decl, omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
12285 remove = true;
12287 else
12289 n->value |= GOVD_REDUCTION_INSCAN;
12290 if (outer_ctx->region_type == ORT_SIMD
12291 && outer_ctx->outer_context
12292 && outer_ctx->outer_context->region_type == ORT_WORKSHARE)
12294 n = splay_tree_lookup (outer_ctx->outer_context->variables,
12295 (splay_tree_key) decl);
12296 if (n && (n->value & GOVD_REDUCTION) != 0)
12297 n->value |= GOVD_REDUCTION_INSCAN;
12301 break;
12303 case OMP_CLAUSE_NOHOST:
12304 default:
12305 gcc_unreachable ();
12308 if (code == OACC_DATA
12309 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
12310 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
12311 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
12312 remove = true;
12313 if (remove)
12314 *list_p = OMP_CLAUSE_CHAIN (c);
12315 else
12316 list_p = &OMP_CLAUSE_CHAIN (c);
12319 ctx->clauses = *orig_list_p;
12320 gimplify_omp_ctxp = ctx;
12323 /* Return true if DECL is a candidate for shared to firstprivate
12324 optimization. We only consider non-addressable scalars, not
12325 too big, and not references. */
12327 static bool
12328 omp_shared_to_firstprivate_optimizable_decl_p (tree decl)
12330 if (TREE_ADDRESSABLE (decl))
12331 return false;
12332 tree type = TREE_TYPE (decl);
12333 if (!is_gimple_reg_type (type)
12334 || TREE_CODE (type) == REFERENCE_TYPE
12335 || TREE_ADDRESSABLE (type))
12336 return false;
12337 /* Don't optimize too large decls, as each thread/task will have
12338 its own. */
12339 HOST_WIDE_INT len = int_size_in_bytes (type);
12340 if (len == -1 || len > 4 * POINTER_SIZE / BITS_PER_UNIT)
12341 return false;
12342 if (omp_privatize_by_reference (decl))
12343 return false;
12344 return true;
12347 /* Helper function of omp_find_stores_op and gimplify_adjust_omp_clauses*.
12348 For omp_shared_to_firstprivate_optimizable_decl_p decl mark it as
12349 GOVD_WRITTEN in outer contexts. */
12351 static void
12352 omp_mark_stores (struct gimplify_omp_ctx *ctx, tree decl)
12354 for (; ctx; ctx = ctx->outer_context)
12356 splay_tree_node n = splay_tree_lookup (ctx->variables,
12357 (splay_tree_key) decl);
12358 if (n == NULL)
12359 continue;
12360 else if (n->value & GOVD_SHARED)
12362 n->value |= GOVD_WRITTEN;
12363 return;
12365 else if (n->value & GOVD_DATA_SHARE_CLASS)
12366 return;
12370 /* Helper callback for walk_gimple_seq to discover possible stores
12371 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
12372 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
12373 for those. */
12375 static tree
12376 omp_find_stores_op (tree *tp, int *walk_subtrees, void *data)
12378 struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
12380 *walk_subtrees = 0;
12381 if (!wi->is_lhs)
12382 return NULL_TREE;
12384 tree op = *tp;
12387 if (handled_component_p (op))
12388 op = TREE_OPERAND (op, 0);
12389 else if ((TREE_CODE (op) == MEM_REF || TREE_CODE (op) == TARGET_MEM_REF)
12390 && TREE_CODE (TREE_OPERAND (op, 0)) == ADDR_EXPR)
12391 op = TREE_OPERAND (TREE_OPERAND (op, 0), 0);
12392 else
12393 break;
12395 while (1);
12396 if (!DECL_P (op) || !omp_shared_to_firstprivate_optimizable_decl_p (op))
12397 return NULL_TREE;
12399 omp_mark_stores (gimplify_omp_ctxp, op);
12400 return NULL_TREE;
12403 /* Helper callback for walk_gimple_seq to discover possible stores
12404 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
12405 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
12406 for those. */
12408 static tree
12409 omp_find_stores_stmt (gimple_stmt_iterator *gsi_p,
12410 bool *handled_ops_p,
12411 struct walk_stmt_info *wi)
12413 gimple *stmt = gsi_stmt (*gsi_p);
12414 switch (gimple_code (stmt))
12416 /* Don't recurse on OpenMP constructs for which
12417 gimplify_adjust_omp_clauses already handled the bodies,
12418 except handle gimple_omp_for_pre_body. */
12419 case GIMPLE_OMP_FOR:
12420 *handled_ops_p = true;
12421 if (gimple_omp_for_pre_body (stmt))
12422 walk_gimple_seq (gimple_omp_for_pre_body (stmt),
12423 omp_find_stores_stmt, omp_find_stores_op, wi);
12424 break;
12425 case GIMPLE_OMP_PARALLEL:
12426 case GIMPLE_OMP_TASK:
12427 case GIMPLE_OMP_SECTIONS:
12428 case GIMPLE_OMP_SINGLE:
12429 case GIMPLE_OMP_SCOPE:
12430 case GIMPLE_OMP_TARGET:
12431 case GIMPLE_OMP_TEAMS:
12432 case GIMPLE_OMP_CRITICAL:
12433 *handled_ops_p = true;
12434 break;
12435 default:
12436 break;
12438 return NULL_TREE;
12441 struct gimplify_adjust_omp_clauses_data
12443 tree *list_p;
12444 gimple_seq *pre_p;
12447 /* For all variables that were not actually used within the context,
12448 remove PRIVATE, SHARED, and FIRSTPRIVATE clauses. */
12450 static int
12451 gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
12453 tree *list_p = ((struct gimplify_adjust_omp_clauses_data *) data)->list_p;
12454 gimple_seq *pre_p
12455 = ((struct gimplify_adjust_omp_clauses_data *) data)->pre_p;
12456 tree decl = (tree) n->key;
12457 unsigned flags = n->value;
12458 enum omp_clause_code code;
12459 tree clause;
12460 bool private_debug;
12462 if (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
12463 && (flags & GOVD_LASTPRIVATE_CONDITIONAL) != 0)
12464 flags = GOVD_SHARED | GOVD_SEEN | GOVD_WRITTEN;
12465 if (flags & (GOVD_EXPLICIT | GOVD_LOCAL))
12466 return 0;
12467 if ((flags & GOVD_SEEN) == 0)
12468 return 0;
12469 if (flags & GOVD_DEBUG_PRIVATE)
12471 gcc_assert ((flags & GOVD_DATA_SHARE_CLASS) == GOVD_SHARED);
12472 private_debug = true;
12474 else if (flags & GOVD_MAP)
12475 private_debug = false;
12476 else
12477 private_debug
12478 = lang_hooks.decls.omp_private_debug_clause (decl,
12479 !!(flags & GOVD_SHARED));
12480 if (private_debug)
12481 code = OMP_CLAUSE_PRIVATE;
12482 else if (flags & GOVD_MAP)
12484 code = OMP_CLAUSE_MAP;
12485 if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0
12486 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
12488 error ("%<_Atomic%> %qD in implicit %<map%> clause", decl);
12489 return 0;
12491 if (VAR_P (decl)
12492 && DECL_IN_CONSTANT_POOL (decl)
12493 && !lookup_attribute ("omp declare target",
12494 DECL_ATTRIBUTES (decl)))
12496 tree id = get_identifier ("omp declare target");
12497 DECL_ATTRIBUTES (decl)
12498 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
12499 varpool_node *node = varpool_node::get (decl);
12500 if (node)
12502 node->offloadable = 1;
12503 if (ENABLE_OFFLOADING)
12504 g->have_offload = true;
12508 else if (flags & GOVD_SHARED)
12510 if (is_global_var (decl))
12512 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
12513 while (ctx != NULL)
12515 splay_tree_node on
12516 = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
12517 if (on && (on->value & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
12518 | GOVD_PRIVATE | GOVD_REDUCTION
12519 | GOVD_LINEAR | GOVD_MAP)) != 0)
12520 break;
12521 ctx = ctx->outer_context;
12523 if (ctx == NULL)
12524 return 0;
12526 code = OMP_CLAUSE_SHARED;
12527 /* Don't optimize shared into firstprivate for read-only vars
12528 on tasks with depend clause, we shouldn't try to copy them
12529 until the dependencies are satisfied. */
12530 if (gimplify_omp_ctxp->has_depend)
12531 flags |= GOVD_WRITTEN;
12533 else if (flags & GOVD_PRIVATE)
12534 code = OMP_CLAUSE_PRIVATE;
12535 else if (flags & GOVD_FIRSTPRIVATE)
12537 code = OMP_CLAUSE_FIRSTPRIVATE;
12538 if ((gimplify_omp_ctxp->region_type & ORT_TARGET)
12539 && (gimplify_omp_ctxp->region_type & ORT_ACC) == 0
12540 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
12542 error ("%<_Atomic%> %qD in implicit %<firstprivate%> clause on "
12543 "%<target%> construct", decl);
12544 return 0;
12547 else if (flags & GOVD_LASTPRIVATE)
12548 code = OMP_CLAUSE_LASTPRIVATE;
12549 else if (flags & (GOVD_ALIGNED | GOVD_NONTEMPORAL))
12550 return 0;
12551 else if (flags & GOVD_CONDTEMP)
12553 code = OMP_CLAUSE__CONDTEMP_;
12554 gimple_add_tmp_var (decl);
12556 else
12557 gcc_unreachable ();
12559 if (((flags & GOVD_LASTPRIVATE)
12560 || (code == OMP_CLAUSE_SHARED && (flags & GOVD_WRITTEN)))
12561 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
12562 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
12564 tree chain = *list_p;
12565 clause = build_omp_clause (input_location, code);
12566 OMP_CLAUSE_DECL (clause) = decl;
12567 OMP_CLAUSE_CHAIN (clause) = chain;
12568 if (private_debug)
12569 OMP_CLAUSE_PRIVATE_DEBUG (clause) = 1;
12570 else if (code == OMP_CLAUSE_PRIVATE && (flags & GOVD_PRIVATE_OUTER_REF))
12571 OMP_CLAUSE_PRIVATE_OUTER_REF (clause) = 1;
12572 else if (code == OMP_CLAUSE_SHARED
12573 && (flags & GOVD_WRITTEN) == 0
12574 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
12575 OMP_CLAUSE_SHARED_READONLY (clause) = 1;
12576 else if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_EXPLICIT) == 0)
12577 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (clause) = 1;
12578 else if (code == OMP_CLAUSE_MAP && (flags & GOVD_MAP_0LEN_ARRAY) != 0)
12580 tree nc = build_omp_clause (input_location, OMP_CLAUSE_MAP);
12581 OMP_CLAUSE_DECL (nc) = decl;
12582 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
12583 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == POINTER_TYPE)
12584 OMP_CLAUSE_DECL (clause)
12585 = build_simple_mem_ref_loc (input_location, decl);
12586 OMP_CLAUSE_DECL (clause)
12587 = build2 (MEM_REF, char_type_node, OMP_CLAUSE_DECL (clause),
12588 build_int_cst (build_pointer_type (char_type_node), 0));
12589 OMP_CLAUSE_SIZE (clause) = size_zero_node;
12590 OMP_CLAUSE_SIZE (nc) = size_zero_node;
12591 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_ALLOC);
12592 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (clause) = 1;
12593 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
12594 OMP_CLAUSE_CHAIN (nc) = chain;
12595 OMP_CLAUSE_CHAIN (clause) = nc;
12596 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
12597 gimplify_omp_ctxp = ctx->outer_context;
12598 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (clause), 0),
12599 pre_p, NULL, is_gimple_val, fb_rvalue);
12600 gimplify_omp_ctxp = ctx;
12602 else if (code == OMP_CLAUSE_MAP)
12604 int kind;
12605 /* Not all combinations of these GOVD_MAP flags are actually valid. */
12606 switch (flags & (GOVD_MAP_TO_ONLY
12607 | GOVD_MAP_FORCE
12608 | GOVD_MAP_FORCE_PRESENT
12609 | GOVD_MAP_ALLOC_ONLY
12610 | GOVD_MAP_FROM_ONLY))
12612 case 0:
12613 kind = GOMP_MAP_TOFROM;
12614 break;
12615 case GOVD_MAP_FORCE:
12616 kind = GOMP_MAP_TOFROM | GOMP_MAP_FLAG_FORCE;
12617 break;
12618 case GOVD_MAP_TO_ONLY:
12619 kind = GOMP_MAP_TO;
12620 break;
12621 case GOVD_MAP_FROM_ONLY:
12622 kind = GOMP_MAP_FROM;
12623 break;
12624 case GOVD_MAP_ALLOC_ONLY:
12625 kind = GOMP_MAP_ALLOC;
12626 break;
12627 case GOVD_MAP_TO_ONLY | GOVD_MAP_FORCE:
12628 kind = GOMP_MAP_TO | GOMP_MAP_FLAG_FORCE;
12629 break;
12630 case GOVD_MAP_FORCE_PRESENT:
12631 kind = GOMP_MAP_FORCE_PRESENT;
12632 break;
12633 case GOVD_MAP_FORCE_PRESENT | GOVD_MAP_ALLOC_ONLY:
12634 kind = GOMP_MAP_FORCE_PRESENT;
12635 break;
12636 default:
12637 gcc_unreachable ();
12639 OMP_CLAUSE_SET_MAP_KIND (clause, kind);
12640 /* Setting of the implicit flag for the runtime is currently disabled for
12641 OpenACC. */
12642 if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0)
12643 OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (clause) = 1;
12644 if (DECL_SIZE (decl)
12645 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
12647 tree decl2 = DECL_VALUE_EXPR (decl);
12648 gcc_assert (INDIRECT_REF_P (decl2));
12649 decl2 = TREE_OPERAND (decl2, 0);
12650 gcc_assert (DECL_P (decl2));
12651 tree mem = build_simple_mem_ref (decl2);
12652 OMP_CLAUSE_DECL (clause) = mem;
12653 OMP_CLAUSE_SIZE (clause) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
12654 if (gimplify_omp_ctxp->outer_context)
12656 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
12657 omp_notice_variable (ctx, decl2, true);
12658 omp_notice_variable (ctx, OMP_CLAUSE_SIZE (clause), true);
12660 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
12661 OMP_CLAUSE_MAP);
12662 OMP_CLAUSE_DECL (nc) = decl;
12663 OMP_CLAUSE_SIZE (nc) = size_zero_node;
12664 if (gimplify_omp_ctxp->target_firstprivatize_array_bases)
12665 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
12666 else
12667 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
12668 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
12669 OMP_CLAUSE_CHAIN (clause) = nc;
12671 else if (gimplify_omp_ctxp->target_firstprivatize_array_bases
12672 && omp_privatize_by_reference (decl))
12674 OMP_CLAUSE_DECL (clause) = build_simple_mem_ref (decl);
12675 OMP_CLAUSE_SIZE (clause)
12676 = unshare_expr (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))));
12677 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
12678 gimplify_omp_ctxp = ctx->outer_context;
12679 gimplify_expr (&OMP_CLAUSE_SIZE (clause),
12680 pre_p, NULL, is_gimple_val, fb_rvalue);
12681 gimplify_omp_ctxp = ctx;
12682 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
12683 OMP_CLAUSE_MAP);
12684 OMP_CLAUSE_DECL (nc) = decl;
12685 OMP_CLAUSE_SIZE (nc) = size_zero_node;
12686 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_REFERENCE);
12687 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
12688 OMP_CLAUSE_CHAIN (clause) = nc;
12690 else
12691 OMP_CLAUSE_SIZE (clause) = DECL_SIZE_UNIT (decl);
12693 if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_LASTPRIVATE) != 0)
12695 tree nc = build_omp_clause (input_location, OMP_CLAUSE_LASTPRIVATE);
12696 OMP_CLAUSE_DECL (nc) = decl;
12697 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (nc) = 1;
12698 OMP_CLAUSE_CHAIN (nc) = chain;
12699 OMP_CLAUSE_CHAIN (clause) = nc;
12700 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
12701 gimplify_omp_ctxp = ctx->outer_context;
12702 lang_hooks.decls.omp_finish_clause (nc, pre_p,
12703 (ctx->region_type & ORT_ACC) != 0);
12704 gimplify_omp_ctxp = ctx;
12706 *list_p = clause;
12707 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
12708 gimplify_omp_ctxp = ctx->outer_context;
12709 /* Don't call omp_finish_clause on implicitly added OMP_CLAUSE_PRIVATE
12710 in simd. Those are only added for the local vars inside of simd body
12711 and they don't need to be e.g. default constructible. */
12712 if (code != OMP_CLAUSE_PRIVATE || ctx->region_type != ORT_SIMD)
12713 lang_hooks.decls.omp_finish_clause (clause, pre_p,
12714 (ctx->region_type & ORT_ACC) != 0);
12715 if (gimplify_omp_ctxp)
12716 for (; clause != chain; clause = OMP_CLAUSE_CHAIN (clause))
12717 if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_MAP
12718 && DECL_P (OMP_CLAUSE_SIZE (clause)))
12719 omp_notice_variable (gimplify_omp_ctxp, OMP_CLAUSE_SIZE (clause),
12720 true);
12721 gimplify_omp_ctxp = ctx;
12722 return 0;
12725 static void
12726 gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
12727 enum tree_code code)
12729 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
12730 tree *orig_list_p = list_p;
12731 tree c, decl;
12732 bool has_inscan_reductions = false;
12734 if (body)
12736 struct gimplify_omp_ctx *octx;
12737 for (octx = ctx; octx; octx = octx->outer_context)
12738 if ((octx->region_type & (ORT_PARALLEL | ORT_TASK | ORT_TEAMS)) != 0)
12739 break;
12740 if (octx)
12742 struct walk_stmt_info wi;
12743 memset (&wi, 0, sizeof (wi));
12744 walk_gimple_seq (body, omp_find_stores_stmt,
12745 omp_find_stores_op, &wi);
12749 if (ctx->add_safelen1)
12751 /* If there are VLAs in the body of simd loop, prevent
12752 vectorization. */
12753 gcc_assert (ctx->region_type == ORT_SIMD);
12754 c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_SAFELEN);
12755 OMP_CLAUSE_SAFELEN_EXPR (c) = integer_one_node;
12756 OMP_CLAUSE_CHAIN (c) = *list_p;
12757 *list_p = c;
12758 list_p = &OMP_CLAUSE_CHAIN (c);
12761 if (ctx->region_type == ORT_WORKSHARE
12762 && ctx->outer_context
12763 && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL)
12765 for (c = ctx->outer_context->clauses; c; c = OMP_CLAUSE_CHAIN (c))
12766 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
12767 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
12769 decl = OMP_CLAUSE_DECL (c);
12770 splay_tree_node n
12771 = splay_tree_lookup (ctx->outer_context->variables,
12772 (splay_tree_key) decl);
12773 gcc_checking_assert (!splay_tree_lookup (ctx->variables,
12774 (splay_tree_key) decl));
12775 omp_add_variable (ctx, decl, n->value);
12776 tree c2 = copy_node (c);
12777 OMP_CLAUSE_CHAIN (c2) = *list_p;
12778 *list_p = c2;
12779 if ((n->value & GOVD_FIRSTPRIVATE) == 0)
12780 continue;
12781 c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
12782 OMP_CLAUSE_FIRSTPRIVATE);
12783 OMP_CLAUSE_DECL (c2) = decl;
12784 OMP_CLAUSE_CHAIN (c2) = *list_p;
12785 *list_p = c2;
12789 tree attach_list = NULL_TREE;
12790 tree *attach_tail = &attach_list;
12792 while ((c = *list_p) != NULL)
12794 splay_tree_node n;
12795 bool remove = false;
12796 bool move_attach = false;
12798 switch (OMP_CLAUSE_CODE (c))
12800 case OMP_CLAUSE_FIRSTPRIVATE:
12801 if ((ctx->region_type & ORT_TARGET)
12802 && (ctx->region_type & ORT_ACC) == 0
12803 && TYPE_ATOMIC (strip_array_types
12804 (TREE_TYPE (OMP_CLAUSE_DECL (c)))))
12806 error_at (OMP_CLAUSE_LOCATION (c),
12807 "%<_Atomic%> %qD in %<firstprivate%> clause on "
12808 "%<target%> construct", OMP_CLAUSE_DECL (c));
12809 remove = true;
12810 break;
12812 if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c))
12814 decl = OMP_CLAUSE_DECL (c);
12815 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
12816 if ((n->value & GOVD_MAP) != 0)
12818 remove = true;
12819 break;
12821 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT_TARGET (c) = 0;
12822 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c) = 0;
12824 /* FALLTHRU */
12825 case OMP_CLAUSE_PRIVATE:
12826 case OMP_CLAUSE_SHARED:
12827 case OMP_CLAUSE_LINEAR:
12828 decl = OMP_CLAUSE_DECL (c);
12829 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
12830 remove = !(n->value & GOVD_SEEN);
12831 if ((n->value & GOVD_LASTPRIVATE_CONDITIONAL) != 0
12832 && code == OMP_PARALLEL
12833 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
12834 remove = true;
12835 if (! remove)
12837 bool shared = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED;
12838 if ((n->value & GOVD_DEBUG_PRIVATE)
12839 || lang_hooks.decls.omp_private_debug_clause (decl, shared))
12841 gcc_assert ((n->value & GOVD_DEBUG_PRIVATE) == 0
12842 || ((n->value & GOVD_DATA_SHARE_CLASS)
12843 == GOVD_SHARED));
12844 OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_PRIVATE);
12845 OMP_CLAUSE_PRIVATE_DEBUG (c) = 1;
12847 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
12848 && ctx->has_depend
12849 && DECL_P (decl))
12850 n->value |= GOVD_WRITTEN;
12851 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
12852 && (n->value & GOVD_WRITTEN) == 0
12853 && DECL_P (decl)
12854 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
12855 OMP_CLAUSE_SHARED_READONLY (c) = 1;
12856 else if (DECL_P (decl)
12857 && ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
12858 && (n->value & GOVD_WRITTEN) != 0)
12859 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
12860 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
12861 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
12862 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
12864 else
12865 n->value &= ~GOVD_EXPLICIT;
12866 break;
12868 case OMP_CLAUSE_LASTPRIVATE:
12869 /* Make sure OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE is set to
12870 accurately reflect the presence of a FIRSTPRIVATE clause. */
12871 decl = OMP_CLAUSE_DECL (c);
12872 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
12873 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c)
12874 = (n->value & GOVD_FIRSTPRIVATE) != 0;
12875 if (code == OMP_DISTRIBUTE
12876 && OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
12878 remove = true;
12879 error_at (OMP_CLAUSE_LOCATION (c),
12880 "same variable used in %<firstprivate%> and "
12881 "%<lastprivate%> clauses on %<distribute%> "
12882 "construct");
12884 if (!remove
12885 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
12886 && DECL_P (decl)
12887 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
12888 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
12889 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) && code == OMP_PARALLEL)
12890 remove = true;
12891 break;
12893 case OMP_CLAUSE_ALIGNED:
12894 decl = OMP_CLAUSE_DECL (c);
12895 if (!is_global_var (decl))
12897 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
12898 remove = n == NULL || !(n->value & GOVD_SEEN);
12899 if (!remove && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
12901 struct gimplify_omp_ctx *octx;
12902 if (n != NULL
12903 && (n->value & (GOVD_DATA_SHARE_CLASS
12904 & ~GOVD_FIRSTPRIVATE)))
12905 remove = true;
12906 else
12907 for (octx = ctx->outer_context; octx;
12908 octx = octx->outer_context)
12910 n = splay_tree_lookup (octx->variables,
12911 (splay_tree_key) decl);
12912 if (n == NULL)
12913 continue;
12914 if (n->value & GOVD_LOCAL)
12915 break;
12916 /* We have to avoid assigning a shared variable
12917 to itself when trying to add
12918 __builtin_assume_aligned. */
12919 if (n->value & GOVD_SHARED)
12921 remove = true;
12922 break;
12927 else if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
12929 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
12930 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
12931 remove = true;
12933 break;
12935 case OMP_CLAUSE_HAS_DEVICE_ADDR:
12936 decl = OMP_CLAUSE_DECL (c);
12937 while (INDIRECT_REF_P (decl)
12938 || TREE_CODE (decl) == ARRAY_REF)
12939 decl = TREE_OPERAND (decl, 0);
12940 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
12941 remove = n == NULL || !(n->value & GOVD_SEEN);
12942 break;
12944 case OMP_CLAUSE_IS_DEVICE_PTR:
12945 case OMP_CLAUSE_NONTEMPORAL:
12946 decl = OMP_CLAUSE_DECL (c);
12947 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
12948 remove = n == NULL || !(n->value & GOVD_SEEN);
12949 break;
12951 case OMP_CLAUSE_MAP:
12952 switch (OMP_CLAUSE_MAP_KIND (c))
12954 case GOMP_MAP_PRESENT_ALLOC:
12955 case GOMP_MAP_PRESENT_TO:
12956 case GOMP_MAP_PRESENT_FROM:
12957 case GOMP_MAP_PRESENT_TOFROM:
12958 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_PRESENT);
12959 break;
12960 default:
12961 break;
12963 if (code == OMP_TARGET_EXIT_DATA
12964 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER)
12966 remove = true;
12967 break;
12969 /* If we have a target region, we can push all the attaches to the
12970 end of the list (we may have standalone "attach" operations
12971 synthesized for GOMP_MAP_STRUCT nodes that must be processed after
12972 the attachment point AND the pointed-to block have been mapped).
12973 If we have something else, e.g. "enter data", we need to keep
12974 "attach" nodes together with the previous node they attach to so
12975 that separate "exit data" operations work properly (see
12976 libgomp/target.c). */
12977 if ((ctx->region_type & ORT_TARGET) != 0
12978 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
12979 || (OMP_CLAUSE_MAP_KIND (c)
12980 == GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION)))
12981 move_attach = true;
12982 decl = OMP_CLAUSE_DECL (c);
12983 /* Data clauses associated with reductions must be
12984 compatible with present_or_copy. Warn and adjust the clause
12985 if that is not the case. */
12986 if (ctx->region_type == ORT_ACC_PARALLEL
12987 || ctx->region_type == ORT_ACC_SERIAL)
12989 tree t = DECL_P (decl) ? decl : TREE_OPERAND (decl, 0);
12990 n = NULL;
12992 if (DECL_P (t))
12993 n = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
12995 if (n && (n->value & GOVD_REDUCTION))
12997 enum gomp_map_kind kind = OMP_CLAUSE_MAP_KIND (c);
12999 OMP_CLAUSE_MAP_IN_REDUCTION (c) = 1;
13000 if ((kind & GOMP_MAP_TOFROM) != GOMP_MAP_TOFROM
13001 && kind != GOMP_MAP_FORCE_PRESENT
13002 && kind != GOMP_MAP_POINTER)
13004 warning_at (OMP_CLAUSE_LOCATION (c), 0,
13005 "incompatible data clause with reduction "
13006 "on %qE; promoting to %<present_or_copy%>",
13007 DECL_NAME (t));
13008 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TOFROM);
13012 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT
13013 && (code == OMP_TARGET_EXIT_DATA || code == OACC_EXIT_DATA))
13015 remove = true;
13016 break;
13018 if (!DECL_P (decl))
13020 if ((ctx->region_type & ORT_TARGET) != 0
13021 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
13023 if (INDIRECT_REF_P (decl)
13024 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
13025 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
13026 == REFERENCE_TYPE))
13027 decl = TREE_OPERAND (decl, 0);
13028 if (TREE_CODE (decl) == COMPONENT_REF)
13030 while (TREE_CODE (decl) == COMPONENT_REF)
13031 decl = TREE_OPERAND (decl, 0);
13032 if (DECL_P (decl))
13034 n = splay_tree_lookup (ctx->variables,
13035 (splay_tree_key) decl);
13036 if (!(n->value & GOVD_SEEN))
13037 remove = true;
13041 break;
13043 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
13044 if ((ctx->region_type & ORT_TARGET) != 0
13045 && !(n->value & GOVD_SEEN)
13046 && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) == 0
13047 && (!is_global_var (decl)
13048 || !lookup_attribute ("omp declare target link",
13049 DECL_ATTRIBUTES (decl))))
13051 remove = true;
13052 /* For struct element mapping, if struct is never referenced
13053 in target block and none of the mapping has always modifier,
13054 remove all the struct element mappings, which immediately
13055 follow the GOMP_MAP_STRUCT map clause. */
13056 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT)
13058 HOST_WIDE_INT cnt = tree_to_shwi (OMP_CLAUSE_SIZE (c));
13059 while (cnt--)
13060 OMP_CLAUSE_CHAIN (c)
13061 = OMP_CLAUSE_CHAIN (OMP_CLAUSE_CHAIN (c));
13064 else if (DECL_SIZE (decl)
13065 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST
13066 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_POINTER
13067 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_POINTER
13068 && (OMP_CLAUSE_MAP_KIND (c)
13069 != GOMP_MAP_FIRSTPRIVATE_REFERENCE))
13071 /* For GOMP_MAP_FORCE_DEVICEPTR, we'll never enter here, because
13072 for these, TREE_CODE (DECL_SIZE (decl)) will always be
13073 INTEGER_CST. */
13074 gcc_assert (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FORCE_DEVICEPTR);
13076 tree decl2 = DECL_VALUE_EXPR (decl);
13077 gcc_assert (INDIRECT_REF_P (decl2));
13078 decl2 = TREE_OPERAND (decl2, 0);
13079 gcc_assert (DECL_P (decl2));
13080 tree mem = build_simple_mem_ref (decl2);
13081 OMP_CLAUSE_DECL (c) = mem;
13082 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
13083 if (ctx->outer_context)
13085 omp_notice_variable (ctx->outer_context, decl2, true);
13086 omp_notice_variable (ctx->outer_context,
13087 OMP_CLAUSE_SIZE (c), true);
13089 if (((ctx->region_type & ORT_TARGET) != 0
13090 || !ctx->target_firstprivatize_array_bases)
13091 && ((n->value & GOVD_SEEN) == 0
13092 || (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) == 0))
13094 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
13095 OMP_CLAUSE_MAP);
13096 OMP_CLAUSE_DECL (nc) = decl;
13097 OMP_CLAUSE_SIZE (nc) = size_zero_node;
13098 if (ctx->target_firstprivatize_array_bases)
13099 OMP_CLAUSE_SET_MAP_KIND (nc,
13100 GOMP_MAP_FIRSTPRIVATE_POINTER);
13101 else
13102 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
13103 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
13104 OMP_CLAUSE_CHAIN (c) = nc;
13105 c = nc;
13108 else
13110 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
13111 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
13112 gcc_assert ((n->value & GOVD_SEEN) == 0
13113 || ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
13114 == 0));
13116 break;
13118 case OMP_CLAUSE_TO:
13119 case OMP_CLAUSE_FROM:
13120 case OMP_CLAUSE__CACHE_:
13121 decl = OMP_CLAUSE_DECL (c);
13122 if (!DECL_P (decl))
13123 break;
13124 if (DECL_SIZE (decl)
13125 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
13127 tree decl2 = DECL_VALUE_EXPR (decl);
13128 gcc_assert (INDIRECT_REF_P (decl2));
13129 decl2 = TREE_OPERAND (decl2, 0);
13130 gcc_assert (DECL_P (decl2));
13131 tree mem = build_simple_mem_ref (decl2);
13132 OMP_CLAUSE_DECL (c) = mem;
13133 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
13134 if (ctx->outer_context)
13136 omp_notice_variable (ctx->outer_context, decl2, true);
13137 omp_notice_variable (ctx->outer_context,
13138 OMP_CLAUSE_SIZE (c), true);
13141 else if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
13142 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
13143 break;
13145 case OMP_CLAUSE_REDUCTION:
13146 if (OMP_CLAUSE_REDUCTION_INSCAN (c))
13148 decl = OMP_CLAUSE_DECL (c);
13149 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
13150 if ((n->value & GOVD_REDUCTION_INSCAN) == 0)
13152 remove = true;
13153 error_at (OMP_CLAUSE_LOCATION (c),
13154 "%qD specified in %<inscan%> %<reduction%> clause "
13155 "but not in %<scan%> directive clause", decl);
13156 break;
13158 has_inscan_reductions = true;
13160 /* FALLTHRU */
13161 case OMP_CLAUSE_IN_REDUCTION:
13162 case OMP_CLAUSE_TASK_REDUCTION:
13163 decl = OMP_CLAUSE_DECL (c);
13164 /* OpenACC reductions need a present_or_copy data clause.
13165 Add one if necessary. Emit error when the reduction is private. */
13166 if (ctx->region_type == ORT_ACC_PARALLEL
13167 || ctx->region_type == ORT_ACC_SERIAL)
13169 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
13170 if (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
13172 remove = true;
13173 error_at (OMP_CLAUSE_LOCATION (c), "invalid private "
13174 "reduction on %qE", DECL_NAME (decl));
13176 else if ((n->value & GOVD_MAP) == 0)
13178 tree next = OMP_CLAUSE_CHAIN (c);
13179 tree nc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_MAP);
13180 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_TOFROM);
13181 OMP_CLAUSE_DECL (nc) = decl;
13182 OMP_CLAUSE_CHAIN (c) = nc;
13183 lang_hooks.decls.omp_finish_clause (nc, pre_p,
13184 (ctx->region_type
13185 & ORT_ACC) != 0);
13186 while (1)
13188 OMP_CLAUSE_MAP_IN_REDUCTION (nc) = 1;
13189 if (OMP_CLAUSE_CHAIN (nc) == NULL)
13190 break;
13191 nc = OMP_CLAUSE_CHAIN (nc);
13193 OMP_CLAUSE_CHAIN (nc) = next;
13194 n->value |= GOVD_MAP;
13197 if (DECL_P (decl)
13198 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
13199 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
13200 break;
13202 case OMP_CLAUSE_ALLOCATE:
13203 decl = OMP_CLAUSE_DECL (c);
13204 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
13205 if (n != NULL && !(n->value & GOVD_SEEN))
13207 if ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE | GOVD_LINEAR))
13208 != 0
13209 && (n->value & (GOVD_REDUCTION | GOVD_LASTPRIVATE)) == 0)
13210 remove = true;
13212 if (!remove
13213 && OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
13214 && TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)) != INTEGER_CST
13215 && ((ctx->region_type & (ORT_PARALLEL | ORT_TARGET)) != 0
13216 || (ctx->region_type & ORT_TASKLOOP) == ORT_TASK
13217 || (ctx->region_type & ORT_HOST_TEAMS) == ORT_HOST_TEAMS))
13219 tree allocator = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
13220 n = splay_tree_lookup (ctx->variables, (splay_tree_key) allocator);
13221 if (n == NULL)
13223 enum omp_clause_default_kind default_kind
13224 = ctx->default_kind;
13225 ctx->default_kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
13226 omp_notice_variable (ctx, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
13227 true);
13228 ctx->default_kind = default_kind;
13230 else
13231 omp_notice_variable (ctx, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
13232 true);
13234 break;
13236 case OMP_CLAUSE_COPYIN:
13237 case OMP_CLAUSE_COPYPRIVATE:
13238 case OMP_CLAUSE_IF:
13239 case OMP_CLAUSE_NUM_THREADS:
13240 case OMP_CLAUSE_NUM_TEAMS:
13241 case OMP_CLAUSE_THREAD_LIMIT:
13242 case OMP_CLAUSE_DIST_SCHEDULE:
13243 case OMP_CLAUSE_DEVICE:
13244 case OMP_CLAUSE_SCHEDULE:
13245 case OMP_CLAUSE_NOWAIT:
13246 case OMP_CLAUSE_ORDERED:
13247 case OMP_CLAUSE_DEFAULT:
13248 case OMP_CLAUSE_UNTIED:
13249 case OMP_CLAUSE_COLLAPSE:
13250 case OMP_CLAUSE_FINAL:
13251 case OMP_CLAUSE_MERGEABLE:
13252 case OMP_CLAUSE_PROC_BIND:
13253 case OMP_CLAUSE_SAFELEN:
13254 case OMP_CLAUSE_SIMDLEN:
13255 case OMP_CLAUSE_DEPEND:
13256 case OMP_CLAUSE_DOACROSS:
13257 case OMP_CLAUSE_PRIORITY:
13258 case OMP_CLAUSE_GRAINSIZE:
13259 case OMP_CLAUSE_NUM_TASKS:
13260 case OMP_CLAUSE_NOGROUP:
13261 case OMP_CLAUSE_THREADS:
13262 case OMP_CLAUSE_SIMD:
13263 case OMP_CLAUSE_FILTER:
13264 case OMP_CLAUSE_HINT:
13265 case OMP_CLAUSE_DEFAULTMAP:
13266 case OMP_CLAUSE_ORDER:
13267 case OMP_CLAUSE_BIND:
13268 case OMP_CLAUSE_DETACH:
13269 case OMP_CLAUSE_USE_DEVICE_PTR:
13270 case OMP_CLAUSE_USE_DEVICE_ADDR:
13271 case OMP_CLAUSE_ASYNC:
13272 case OMP_CLAUSE_WAIT:
13273 case OMP_CLAUSE_INDEPENDENT:
13274 case OMP_CLAUSE_NUM_GANGS:
13275 case OMP_CLAUSE_NUM_WORKERS:
13276 case OMP_CLAUSE_VECTOR_LENGTH:
13277 case OMP_CLAUSE_GANG:
13278 case OMP_CLAUSE_WORKER:
13279 case OMP_CLAUSE_VECTOR:
13280 case OMP_CLAUSE_AUTO:
13281 case OMP_CLAUSE_SEQ:
13282 case OMP_CLAUSE_TILE:
13283 case OMP_CLAUSE_IF_PRESENT:
13284 case OMP_CLAUSE_FINALIZE:
13285 case OMP_CLAUSE_INCLUSIVE:
13286 case OMP_CLAUSE_EXCLUSIVE:
13287 break;
13289 case OMP_CLAUSE_NOHOST:
13290 default:
13291 gcc_unreachable ();
13294 if (remove)
13295 *list_p = OMP_CLAUSE_CHAIN (c);
13296 else if (move_attach)
13298 /* Remove attach node from here, separate out into its own list. */
13299 *attach_tail = c;
13300 *list_p = OMP_CLAUSE_CHAIN (c);
13301 OMP_CLAUSE_CHAIN (c) = NULL_TREE;
13302 attach_tail = &OMP_CLAUSE_CHAIN (c);
13304 else
13305 list_p = &OMP_CLAUSE_CHAIN (c);
13308 /* Splice attach nodes at the end of the list. */
13309 if (attach_list)
13311 *list_p = attach_list;
13312 list_p = attach_tail;
13315 /* Add in any implicit data sharing. */
13316 struct gimplify_adjust_omp_clauses_data data;
13317 if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0)
13319 /* OpenMP. Implicit clauses are added at the start of the clause list,
13320 but after any non-map clauses. */
13321 tree *implicit_add_list_p = orig_list_p;
13322 while (*implicit_add_list_p
13323 && OMP_CLAUSE_CODE (*implicit_add_list_p) != OMP_CLAUSE_MAP)
13324 implicit_add_list_p = &OMP_CLAUSE_CHAIN (*implicit_add_list_p);
13325 data.list_p = implicit_add_list_p;
13327 else
13328 /* OpenACC. */
13329 data.list_p = list_p;
13330 data.pre_p = pre_p;
13331 splay_tree_foreach (ctx->variables, gimplify_adjust_omp_clauses_1, &data);
13333 if (has_inscan_reductions)
13334 for (c = *orig_list_p; c; c = OMP_CLAUSE_CHAIN (c))
13335 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
13336 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
13338 error_at (OMP_CLAUSE_LOCATION (c),
13339 "%<inscan%> %<reduction%> clause used together with "
13340 "%<linear%> clause for a variable other than loop "
13341 "iterator");
13342 break;
13345 gimplify_omp_ctxp = ctx->outer_context;
13346 delete_omp_context (ctx);
13349 /* Return 0 if CONSTRUCTS selectors don't match the OpenMP context,
13350 -1 if unknown yet (simd is involved, won't be known until vectorization)
13351 and 1 if they do. If SCORES is non-NULL, it should point to an array
13352 of at least 2*NCONSTRUCTS+2 ints, and will be filled with the positions
13353 of the CONSTRUCTS (position -1 if it will never match) followed by
13354 number of constructs in the OpenMP context construct trait. If the
13355 score depends on whether it will be in a declare simd clone or not,
13356 the function returns 2 and there will be two sets of the scores, the first
13357 one for the case that it is not in a declare simd clone, the other
13358 that it is in a declare simd clone. */
13361 omp_construct_selector_matches (enum tree_code *constructs, int nconstructs,
13362 int *scores)
13364 int matched = 0, cnt = 0;
13365 bool simd_seen = false;
13366 bool target_seen = false;
13367 int declare_simd_cnt = -1;
13368 auto_vec<enum tree_code, 16> codes;
13369 for (struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; ctx;)
13371 if (((ctx->region_type & ORT_PARALLEL) && ctx->code == OMP_PARALLEL)
13372 || ((ctx->region_type & (ORT_TARGET | ORT_IMPLICIT_TARGET | ORT_ACC))
13373 == ORT_TARGET && ctx->code == OMP_TARGET)
13374 || ((ctx->region_type & ORT_TEAMS) && ctx->code == OMP_TEAMS)
13375 || (ctx->region_type == ORT_WORKSHARE && ctx->code == OMP_FOR)
13376 || (ctx->region_type == ORT_SIMD
13377 && ctx->code == OMP_SIMD
13378 && !omp_find_clause (ctx->clauses, OMP_CLAUSE_BIND)))
13380 ++cnt;
13381 if (scores)
13382 codes.safe_push (ctx->code);
13383 else if (matched < nconstructs && ctx->code == constructs[matched])
13385 if (ctx->code == OMP_SIMD)
13387 if (matched)
13388 return 0;
13389 simd_seen = true;
13391 ++matched;
13393 if (ctx->code == OMP_TARGET)
13395 if (scores == NULL)
13396 return matched < nconstructs ? 0 : simd_seen ? -1 : 1;
13397 target_seen = true;
13398 break;
13401 else if (ctx->region_type == ORT_WORKSHARE
13402 && ctx->code == OMP_LOOP
13403 && ctx->outer_context
13404 && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL
13405 && ctx->outer_context->outer_context
13406 && ctx->outer_context->outer_context->code == OMP_LOOP
13407 && ctx->outer_context->outer_context->distribute)
13408 ctx = ctx->outer_context->outer_context;
13409 ctx = ctx->outer_context;
13411 if (!target_seen
13412 && lookup_attribute ("omp declare simd",
13413 DECL_ATTRIBUTES (current_function_decl)))
13415 /* Declare simd is a maybe case, it is supposed to be added only to the
13416 omp-simd-clone.cc added clones and not to the base function. */
13417 declare_simd_cnt = cnt++;
13418 if (scores)
13419 codes.safe_push (OMP_SIMD);
13420 else if (cnt == 0
13421 && constructs[0] == OMP_SIMD)
13423 gcc_assert (matched == 0);
13424 simd_seen = true;
13425 if (++matched == nconstructs)
13426 return -1;
13429 if (tree attr = lookup_attribute ("omp declare variant variant",
13430 DECL_ATTRIBUTES (current_function_decl)))
13432 enum tree_code variant_constructs[5];
13433 int variant_nconstructs = 0;
13434 if (!target_seen)
13435 variant_nconstructs
13436 = omp_constructor_traits_to_codes (TREE_VALUE (attr),
13437 variant_constructs);
13438 for (int i = 0; i < variant_nconstructs; i++)
13440 ++cnt;
13441 if (scores)
13442 codes.safe_push (variant_constructs[i]);
13443 else if (matched < nconstructs
13444 && variant_constructs[i] == constructs[matched])
13446 if (variant_constructs[i] == OMP_SIMD)
13448 if (matched)
13449 return 0;
13450 simd_seen = true;
13452 ++matched;
13456 if (!target_seen
13457 && lookup_attribute ("omp declare target block",
13458 DECL_ATTRIBUTES (current_function_decl)))
13460 if (scores)
13461 codes.safe_push (OMP_TARGET);
13462 else if (matched < nconstructs && constructs[matched] == OMP_TARGET)
13463 ++matched;
13465 if (scores)
13467 for (int pass = 0; pass < (declare_simd_cnt == -1 ? 1 : 2); pass++)
13469 int j = codes.length () - 1;
13470 for (int i = nconstructs - 1; i >= 0; i--)
13472 while (j >= 0
13473 && (pass != 0 || declare_simd_cnt != j)
13474 && constructs[i] != codes[j])
13475 --j;
13476 if (pass == 0 && declare_simd_cnt != -1 && j > declare_simd_cnt)
13477 *scores++ = j - 1;
13478 else
13479 *scores++ = j;
13481 *scores++ = ((pass == 0 && declare_simd_cnt != -1)
13482 ? codes.length () - 1 : codes.length ());
13484 return declare_simd_cnt == -1 ? 1 : 2;
13486 if (matched == nconstructs)
13487 return simd_seen ? -1 : 1;
13488 return 0;
13491 /* Gimplify OACC_CACHE. */
13493 static void
13494 gimplify_oacc_cache (tree *expr_p, gimple_seq *pre_p)
13496 tree expr = *expr_p;
13498 gimplify_scan_omp_clauses (&OACC_CACHE_CLAUSES (expr), pre_p, ORT_ACC,
13499 OACC_CACHE);
13500 gimplify_adjust_omp_clauses (pre_p, NULL, &OACC_CACHE_CLAUSES (expr),
13501 OACC_CACHE);
13503 /* TODO: Do something sensible with this information. */
13505 *expr_p = NULL_TREE;
13508 /* Helper function of gimplify_oacc_declare. The helper's purpose is to,
13509 if required, translate 'kind' in CLAUSE into an 'entry' kind and 'exit'
13510 kind. The entry kind will replace the one in CLAUSE, while the exit
13511 kind will be used in a new omp_clause and returned to the caller. */
13513 static tree
13514 gimplify_oacc_declare_1 (tree clause)
13516 HOST_WIDE_INT kind, new_op;
13517 bool ret = false;
13518 tree c = NULL;
13520 kind = OMP_CLAUSE_MAP_KIND (clause);
13522 switch (kind)
13524 case GOMP_MAP_ALLOC:
13525 new_op = GOMP_MAP_RELEASE;
13526 ret = true;
13527 break;
13529 case GOMP_MAP_FROM:
13530 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_FORCE_ALLOC);
13531 new_op = GOMP_MAP_FROM;
13532 ret = true;
13533 break;
13535 case GOMP_MAP_TOFROM:
13536 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_TO);
13537 new_op = GOMP_MAP_FROM;
13538 ret = true;
13539 break;
13541 case GOMP_MAP_DEVICE_RESIDENT:
13542 case GOMP_MAP_FORCE_DEVICEPTR:
13543 case GOMP_MAP_FORCE_PRESENT:
13544 case GOMP_MAP_LINK:
13545 case GOMP_MAP_POINTER:
13546 case GOMP_MAP_TO:
13547 break;
13549 default:
13550 gcc_unreachable ();
13551 break;
13554 if (ret)
13556 c = build_omp_clause (OMP_CLAUSE_LOCATION (clause), OMP_CLAUSE_MAP);
13557 OMP_CLAUSE_SET_MAP_KIND (c, new_op);
13558 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clause);
13561 return c;
13564 /* Gimplify OACC_DECLARE. */
13566 static void
13567 gimplify_oacc_declare (tree *expr_p, gimple_seq *pre_p)
13569 tree expr = *expr_p;
13570 gomp_target *stmt;
13571 tree clauses, t, decl;
13573 clauses = OACC_DECLARE_CLAUSES (expr);
13575 gimplify_scan_omp_clauses (&clauses, pre_p, ORT_TARGET_DATA, OACC_DECLARE);
13576 gimplify_adjust_omp_clauses (pre_p, NULL, &clauses, OACC_DECLARE);
13578 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
13580 decl = OMP_CLAUSE_DECL (t);
13582 if (TREE_CODE (decl) == MEM_REF)
13583 decl = TREE_OPERAND (decl, 0);
13585 if (VAR_P (decl) && !is_oacc_declared (decl))
13587 tree attr = get_identifier ("oacc declare target");
13588 DECL_ATTRIBUTES (decl) = tree_cons (attr, NULL_TREE,
13589 DECL_ATTRIBUTES (decl));
13592 if (VAR_P (decl)
13593 && !is_global_var (decl)
13594 && DECL_CONTEXT (decl) == current_function_decl)
13596 tree c = gimplify_oacc_declare_1 (t);
13597 if (c)
13599 if (oacc_declare_returns == NULL)
13600 oacc_declare_returns = new hash_map<tree, tree>;
13602 oacc_declare_returns->put (decl, c);
13606 if (gimplify_omp_ctxp)
13607 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_SEEN);
13610 stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
13611 clauses);
13613 gimplify_seq_add_stmt (pre_p, stmt);
13615 *expr_p = NULL_TREE;
13618 /* Gimplify the contents of an OMP_PARALLEL statement. This involves
13619 gimplification of the body, as well as scanning the body for used
13620 variables. We need to do this scan now, because variable-sized
13621 decls will be decomposed during gimplification. */
13623 static void
13624 gimplify_omp_parallel (tree *expr_p, gimple_seq *pre_p)
13626 tree expr = *expr_p;
13627 gimple *g;
13628 gimple_seq body = NULL;
13630 gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr), pre_p,
13631 OMP_PARALLEL_COMBINED (expr)
13632 ? ORT_COMBINED_PARALLEL
13633 : ORT_PARALLEL, OMP_PARALLEL);
13635 push_gimplify_context ();
13637 g = gimplify_and_return_first (OMP_PARALLEL_BODY (expr), &body);
13638 if (gimple_code (g) == GIMPLE_BIND)
13639 pop_gimplify_context (g);
13640 else
13641 pop_gimplify_context (NULL);
13643 gimplify_adjust_omp_clauses (pre_p, body, &OMP_PARALLEL_CLAUSES (expr),
13644 OMP_PARALLEL);
13646 g = gimple_build_omp_parallel (body,
13647 OMP_PARALLEL_CLAUSES (expr),
13648 NULL_TREE, NULL_TREE);
13649 if (OMP_PARALLEL_COMBINED (expr))
13650 gimple_omp_set_subcode (g, GF_OMP_PARALLEL_COMBINED);
13651 gimplify_seq_add_stmt (pre_p, g);
13652 *expr_p = NULL_TREE;
13655 /* Gimplify the contents of an OMP_TASK statement. This involves
13656 gimplification of the body, as well as scanning the body for used
13657 variables. We need to do this scan now, because variable-sized
13658 decls will be decomposed during gimplification. */
13660 static void
13661 gimplify_omp_task (tree *expr_p, gimple_seq *pre_p)
13663 tree expr = *expr_p;
13664 gimple *g;
13665 gimple_seq body = NULL;
13666 bool nowait = false;
13667 bool has_depend = false;
13669 if (OMP_TASK_BODY (expr) == NULL_TREE)
13671 for (tree c = OMP_TASK_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
13672 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
13674 has_depend = true;
13675 if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_MUTEXINOUTSET)
13677 error_at (OMP_CLAUSE_LOCATION (c),
13678 "%<mutexinoutset%> kind in %<depend%> clause on a "
13679 "%<taskwait%> construct");
13680 break;
13683 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NOWAIT)
13684 nowait = true;
13685 if (nowait && !has_depend)
13687 error_at (EXPR_LOCATION (expr),
13688 "%<taskwait%> construct with %<nowait%> clause but no "
13689 "%<depend%> clauses");
13690 *expr_p = NULL_TREE;
13691 return;
13695 gimplify_scan_omp_clauses (&OMP_TASK_CLAUSES (expr), pre_p,
13696 omp_find_clause (OMP_TASK_CLAUSES (expr),
13697 OMP_CLAUSE_UNTIED)
13698 ? ORT_UNTIED_TASK : ORT_TASK, OMP_TASK);
13700 if (OMP_TASK_BODY (expr))
13702 push_gimplify_context ();
13704 g = gimplify_and_return_first (OMP_TASK_BODY (expr), &body);
13705 if (gimple_code (g) == GIMPLE_BIND)
13706 pop_gimplify_context (g);
13707 else
13708 pop_gimplify_context (NULL);
13711 gimplify_adjust_omp_clauses (pre_p, body, &OMP_TASK_CLAUSES (expr),
13712 OMP_TASK);
13714 g = gimple_build_omp_task (body,
13715 OMP_TASK_CLAUSES (expr),
13716 NULL_TREE, NULL_TREE,
13717 NULL_TREE, NULL_TREE, NULL_TREE);
13718 if (OMP_TASK_BODY (expr) == NULL_TREE)
13719 gimple_omp_task_set_taskwait_p (g, true);
13720 gimplify_seq_add_stmt (pre_p, g);
13721 *expr_p = NULL_TREE;
13724 /* Helper function for gimplify_omp_for. If *TP is not a gimple constant,
13725 force it into a temporary initialized in PRE_P and add firstprivate clause
13726 to ORIG_FOR_STMT. */
13728 static void
13729 gimplify_omp_taskloop_expr (tree type, tree *tp, gimple_seq *pre_p,
13730 tree orig_for_stmt)
13732 if (*tp == NULL || is_gimple_constant (*tp))
13733 return;
13735 *tp = get_initialized_tmp_var (*tp, pre_p, NULL, false);
13736 /* Reference to pointer conversion is considered useless,
13737 but is significant for firstprivate clause. Force it
13738 here. */
13739 if (type
13740 && TREE_CODE (type) == POINTER_TYPE
13741 && TREE_CODE (TREE_TYPE (*tp)) == REFERENCE_TYPE)
13743 tree v = create_tmp_var (TYPE_MAIN_VARIANT (type));
13744 tree m = build2 (INIT_EXPR, TREE_TYPE (v), v, *tp);
13745 gimplify_and_add (m, pre_p);
13746 *tp = v;
13749 tree c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
13750 OMP_CLAUSE_DECL (c) = *tp;
13751 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
13752 OMP_FOR_CLAUSES (orig_for_stmt) = c;
13755 /* Helper function of gimplify_omp_for, find OMP_ORDERED with
13756 null OMP_ORDERED_BODY inside of OMP_FOR's body. */
13758 static tree
13759 find_standalone_omp_ordered (tree *tp, int *walk_subtrees, void *)
13761 switch (TREE_CODE (*tp))
13763 case OMP_ORDERED:
13764 if (OMP_ORDERED_BODY (*tp) == NULL_TREE)
13765 return *tp;
13766 break;
13767 case OMP_SIMD:
13768 case OMP_PARALLEL:
13769 case OMP_TARGET:
13770 *walk_subtrees = 0;
13771 break;
13772 default:
13773 break;
13775 return NULL_TREE;
13778 /* Gimplify the gross structure of an OMP_FOR statement. */
13780 static enum gimplify_status
13781 gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
13783 tree for_stmt, orig_for_stmt, inner_for_stmt = NULL_TREE, decl, var, t;
13784 enum gimplify_status ret = GS_ALL_DONE;
13785 enum gimplify_status tret;
13786 gomp_for *gfor;
13787 gimple_seq for_body, for_pre_body;
13788 int i;
13789 bitmap has_decl_expr = NULL;
13790 enum omp_region_type ort = ORT_WORKSHARE;
13791 bool openacc = TREE_CODE (*expr_p) == OACC_LOOP;
13793 orig_for_stmt = for_stmt = *expr_p;
13795 bool loop_p = (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_BIND)
13796 != NULL_TREE);
13797 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
13799 tree *data[4] = { NULL, NULL, NULL, NULL };
13800 gcc_assert (TREE_CODE (for_stmt) != OACC_LOOP);
13801 inner_for_stmt = walk_tree (&OMP_FOR_BODY (for_stmt),
13802 find_combined_omp_for, data, NULL);
13803 if (inner_for_stmt == NULL_TREE)
13805 gcc_assert (seen_error ());
13806 *expr_p = NULL_TREE;
13807 return GS_ERROR;
13809 if (data[2] && OMP_FOR_PRE_BODY (*data[2]))
13811 append_to_statement_list_force (OMP_FOR_PRE_BODY (*data[2]),
13812 &OMP_FOR_PRE_BODY (for_stmt));
13813 OMP_FOR_PRE_BODY (*data[2]) = NULL_TREE;
13815 if (OMP_FOR_PRE_BODY (inner_for_stmt))
13817 append_to_statement_list_force (OMP_FOR_PRE_BODY (inner_for_stmt),
13818 &OMP_FOR_PRE_BODY (for_stmt));
13819 OMP_FOR_PRE_BODY (inner_for_stmt) = NULL_TREE;
13822 if (data[0])
13824 /* We have some statements or variable declarations in between
13825 the composite construct directives. Move them around the
13826 inner_for_stmt. */
13827 data[0] = expr_p;
13828 for (i = 0; i < 3; i++)
13829 if (data[i])
13831 tree t = *data[i];
13832 if (i < 2 && data[i + 1] == &OMP_BODY (t))
13833 data[i + 1] = data[i];
13834 *data[i] = OMP_BODY (t);
13835 tree body = build3 (BIND_EXPR, void_type_node, NULL_TREE,
13836 NULL_TREE, make_node (BLOCK));
13837 OMP_BODY (t) = body;
13838 append_to_statement_list_force (inner_for_stmt,
13839 &BIND_EXPR_BODY (body));
13840 *data[3] = t;
13841 data[3] = tsi_stmt_ptr (tsi_start (BIND_EXPR_BODY (body)));
13842 gcc_assert (*data[3] == inner_for_stmt);
13844 return GS_OK;
13847 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
13848 if (!loop_p
13849 && OMP_FOR_ORIG_DECLS (inner_for_stmt)
13850 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
13851 i)) == TREE_LIST
13852 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
13853 i)))
13855 tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
13856 /* Class iterators aren't allowed on OMP_SIMD, so the only
13857 case we need to solve is distribute parallel for. They are
13858 allowed on the loop construct, but that is already handled
13859 in gimplify_omp_loop. */
13860 gcc_assert (TREE_CODE (inner_for_stmt) == OMP_FOR
13861 && TREE_CODE (for_stmt) == OMP_DISTRIBUTE
13862 && data[1]);
13863 tree orig_decl = TREE_PURPOSE (orig);
13864 tree last = TREE_VALUE (orig);
13865 tree *pc;
13866 for (pc = &OMP_FOR_CLAUSES (inner_for_stmt);
13867 *pc; pc = &OMP_CLAUSE_CHAIN (*pc))
13868 if ((OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE
13869 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LASTPRIVATE)
13870 && OMP_CLAUSE_DECL (*pc) == orig_decl)
13871 break;
13872 if (*pc == NULL_TREE)
13874 tree *spc;
13875 for (spc = &OMP_PARALLEL_CLAUSES (*data[1]);
13876 *spc; spc = &OMP_CLAUSE_CHAIN (*spc))
13877 if (OMP_CLAUSE_CODE (*spc) == OMP_CLAUSE_PRIVATE
13878 && OMP_CLAUSE_DECL (*spc) == orig_decl)
13879 break;
13880 if (*spc)
13882 tree c = *spc;
13883 *spc = OMP_CLAUSE_CHAIN (c);
13884 OMP_CLAUSE_CHAIN (c) = NULL_TREE;
13885 *pc = c;
13888 if (*pc == NULL_TREE)
13890 else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE)
13892 /* private clause will appear only on inner_for_stmt.
13893 Change it into firstprivate, and add private clause
13894 on for_stmt. */
13895 tree c = copy_node (*pc);
13896 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
13897 OMP_FOR_CLAUSES (for_stmt) = c;
13898 OMP_CLAUSE_CODE (*pc) = OMP_CLAUSE_FIRSTPRIVATE;
13899 lang_hooks.decls.omp_finish_clause (*pc, pre_p, openacc);
13901 else
13903 /* lastprivate clause will appear on both inner_for_stmt
13904 and for_stmt. Add firstprivate clause to
13905 inner_for_stmt. */
13906 tree c = build_omp_clause (OMP_CLAUSE_LOCATION (*pc),
13907 OMP_CLAUSE_FIRSTPRIVATE);
13908 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (*pc);
13909 OMP_CLAUSE_CHAIN (c) = *pc;
13910 *pc = c;
13911 lang_hooks.decls.omp_finish_clause (*pc, pre_p, openacc);
13913 tree c = build_omp_clause (UNKNOWN_LOCATION,
13914 OMP_CLAUSE_FIRSTPRIVATE);
13915 OMP_CLAUSE_DECL (c) = last;
13916 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
13917 OMP_PARALLEL_CLAUSES (*data[1]) = c;
13918 c = build_omp_clause (UNKNOWN_LOCATION,
13919 *pc ? OMP_CLAUSE_SHARED
13920 : OMP_CLAUSE_FIRSTPRIVATE);
13921 OMP_CLAUSE_DECL (c) = orig_decl;
13922 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
13923 OMP_PARALLEL_CLAUSES (*data[1]) = c;
13925 /* Similarly, take care of C++ range for temporaries, those should
13926 be firstprivate on OMP_PARALLEL if any. */
13927 if (data[1])
13928 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
13929 if (OMP_FOR_ORIG_DECLS (inner_for_stmt)
13930 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
13931 i)) == TREE_LIST
13932 && TREE_CHAIN (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
13933 i)))
13935 tree orig
13936 = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
13937 tree v = TREE_CHAIN (orig);
13938 tree c = build_omp_clause (UNKNOWN_LOCATION,
13939 OMP_CLAUSE_FIRSTPRIVATE);
13940 /* First add firstprivate clause for the __for_end artificial
13941 decl. */
13942 OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 1);
13943 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
13944 == REFERENCE_TYPE)
13945 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
13946 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
13947 OMP_PARALLEL_CLAUSES (*data[1]) = c;
13948 if (TREE_VEC_ELT (v, 0))
13950 /* And now the same for __for_range artificial decl if it
13951 exists. */
13952 c = build_omp_clause (UNKNOWN_LOCATION,
13953 OMP_CLAUSE_FIRSTPRIVATE);
13954 OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 0);
13955 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
13956 == REFERENCE_TYPE)
13957 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
13958 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
13959 OMP_PARALLEL_CLAUSES (*data[1]) = c;
13964 switch (TREE_CODE (for_stmt))
13966 case OMP_FOR:
13967 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt))
13969 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
13970 OMP_CLAUSE_SCHEDULE))
13971 error_at (EXPR_LOCATION (for_stmt),
13972 "%qs clause may not appear on non-rectangular %qs",
13973 "schedule", lang_GNU_Fortran () ? "do" : "for");
13974 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED))
13975 error_at (EXPR_LOCATION (for_stmt),
13976 "%qs clause may not appear on non-rectangular %qs",
13977 "ordered", lang_GNU_Fortran () ? "do" : "for");
13979 break;
13980 case OMP_DISTRIBUTE:
13981 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt)
13982 && omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
13983 OMP_CLAUSE_DIST_SCHEDULE))
13984 error_at (EXPR_LOCATION (for_stmt),
13985 "%qs clause may not appear on non-rectangular %qs",
13986 "dist_schedule", "distribute");
13987 break;
13988 case OACC_LOOP:
13989 ort = ORT_ACC;
13990 break;
13991 case OMP_TASKLOOP:
13992 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt))
13994 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
13995 OMP_CLAUSE_GRAINSIZE))
13996 error_at (EXPR_LOCATION (for_stmt),
13997 "%qs clause may not appear on non-rectangular %qs",
13998 "grainsize", "taskloop");
13999 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
14000 OMP_CLAUSE_NUM_TASKS))
14001 error_at (EXPR_LOCATION (for_stmt),
14002 "%qs clause may not appear on non-rectangular %qs",
14003 "num_tasks", "taskloop");
14005 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_UNTIED))
14006 ort = ORT_UNTIED_TASKLOOP;
14007 else
14008 ort = ORT_TASKLOOP;
14009 break;
14010 case OMP_SIMD:
14011 ort = ORT_SIMD;
14012 break;
14013 default:
14014 gcc_unreachable ();
14017 /* Set OMP_CLAUSE_LINEAR_NO_COPYIN flag on explicit linear
14018 clause for the IV. */
14019 if (ort == ORT_SIMD && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
14021 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), 0);
14022 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
14023 decl = TREE_OPERAND (t, 0);
14024 for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
14025 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
14026 && OMP_CLAUSE_DECL (c) == decl)
14028 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
14029 break;
14033 if (TREE_CODE (for_stmt) != OMP_TASKLOOP)
14034 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p, ort,
14035 loop_p && TREE_CODE (for_stmt) != OMP_SIMD
14036 ? OMP_LOOP : TREE_CODE (for_stmt));
14038 if (TREE_CODE (for_stmt) == OMP_DISTRIBUTE)
14039 gimplify_omp_ctxp->distribute = true;
14041 /* Handle OMP_FOR_INIT. */
14042 for_pre_body = NULL;
14043 if ((ort == ORT_SIMD
14044 || (inner_for_stmt && TREE_CODE (inner_for_stmt) == OMP_SIMD))
14045 && OMP_FOR_PRE_BODY (for_stmt))
14047 has_decl_expr = BITMAP_ALLOC (NULL);
14048 if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == DECL_EXPR
14049 && VAR_P (DECL_EXPR_DECL (OMP_FOR_PRE_BODY (for_stmt))))
14051 t = OMP_FOR_PRE_BODY (for_stmt);
14052 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
14054 else if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == STATEMENT_LIST)
14056 tree_stmt_iterator si;
14057 for (si = tsi_start (OMP_FOR_PRE_BODY (for_stmt)); !tsi_end_p (si);
14058 tsi_next (&si))
14060 t = tsi_stmt (si);
14061 if (TREE_CODE (t) == DECL_EXPR
14062 && VAR_P (DECL_EXPR_DECL (t)))
14063 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
14067 if (OMP_FOR_PRE_BODY (for_stmt))
14069 if (TREE_CODE (for_stmt) != OMP_TASKLOOP || gimplify_omp_ctxp)
14070 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
14071 else
14073 struct gimplify_omp_ctx ctx;
14074 memset (&ctx, 0, sizeof (ctx));
14075 ctx.region_type = ORT_NONE;
14076 gimplify_omp_ctxp = &ctx;
14077 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
14078 gimplify_omp_ctxp = NULL;
14081 OMP_FOR_PRE_BODY (for_stmt) = NULL_TREE;
14083 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
14084 for_stmt = inner_for_stmt;
14086 /* For taskloop, need to gimplify the start, end and step before the
14087 taskloop, outside of the taskloop omp context. */
14088 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
14090 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
14092 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
14093 gimple_seq *for_pre_p = (gimple_seq_empty_p (for_pre_body)
14094 ? pre_p : &for_pre_body);
14095 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
14096 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
14098 tree v = TREE_OPERAND (t, 1);
14099 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 1),
14100 for_pre_p, orig_for_stmt);
14101 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 2),
14102 for_pre_p, orig_for_stmt);
14104 else
14105 gimplify_omp_taskloop_expr (type, &TREE_OPERAND (t, 1), for_pre_p,
14106 orig_for_stmt);
14108 /* Handle OMP_FOR_COND. */
14109 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
14110 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
14112 tree v = TREE_OPERAND (t, 1);
14113 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 1),
14114 for_pre_p, orig_for_stmt);
14115 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 2),
14116 for_pre_p, orig_for_stmt);
14118 else
14119 gimplify_omp_taskloop_expr (type, &TREE_OPERAND (t, 1), for_pre_p,
14120 orig_for_stmt);
14122 /* Handle OMP_FOR_INCR. */
14123 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
14124 if (TREE_CODE (t) == MODIFY_EXPR)
14126 decl = TREE_OPERAND (t, 0);
14127 t = TREE_OPERAND (t, 1);
14128 tree *tp = &TREE_OPERAND (t, 1);
14129 if (TREE_CODE (t) == PLUS_EXPR && *tp == decl)
14130 tp = &TREE_OPERAND (t, 0);
14132 gimplify_omp_taskloop_expr (NULL_TREE, tp, for_pre_p,
14133 orig_for_stmt);
14137 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (orig_for_stmt), pre_p, ort,
14138 OMP_TASKLOOP);
14141 if (orig_for_stmt != for_stmt)
14142 gimplify_omp_ctxp->combined_loop = true;
14144 for_body = NULL;
14145 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
14146 == TREE_VEC_LENGTH (OMP_FOR_COND (for_stmt)));
14147 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
14148 == TREE_VEC_LENGTH (OMP_FOR_INCR (for_stmt)));
14150 tree c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED);
14151 bool is_doacross = false;
14152 if (c && walk_tree_without_duplicates (&OMP_FOR_BODY (for_stmt),
14153 find_standalone_omp_ordered, NULL))
14155 OMP_CLAUSE_ORDERED_DOACROSS (c) = 1;
14156 is_doacross = true;
14157 int len = TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt));
14158 gimplify_omp_ctxp->loop_iter_var.create (len * 2);
14159 for (tree *pc = &OMP_FOR_CLAUSES (for_stmt); *pc; )
14160 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LINEAR)
14162 error_at (OMP_CLAUSE_LOCATION (*pc),
14163 "%<linear%> clause may not be specified together "
14164 "with %<ordered%> clause if stand-alone %<ordered%> "
14165 "construct is nested in it");
14166 *pc = OMP_CLAUSE_CHAIN (*pc);
14168 else
14169 pc = &OMP_CLAUSE_CHAIN (*pc);
14171 int collapse = 1, tile = 0;
14172 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_COLLAPSE);
14173 if (c)
14174 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (c));
14175 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_TILE);
14176 if (c)
14177 tile = list_length (OMP_CLAUSE_TILE_LIST (c));
14178 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ALLOCATE);
14179 hash_set<tree> *allocate_uids = NULL;
14180 if (c)
14182 allocate_uids = new hash_set<tree>;
14183 for (; c; c = OMP_CLAUSE_CHAIN (c))
14184 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ALLOCATE)
14185 allocate_uids->add (OMP_CLAUSE_DECL (c));
14187 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
14189 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
14190 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
14191 decl = TREE_OPERAND (t, 0);
14192 gcc_assert (DECL_P (decl));
14193 gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl))
14194 || POINTER_TYPE_P (TREE_TYPE (decl)));
14195 if (is_doacross)
14197 if (TREE_CODE (for_stmt) == OMP_FOR && OMP_FOR_ORIG_DECLS (for_stmt))
14199 tree orig_decl = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
14200 if (TREE_CODE (orig_decl) == TREE_LIST)
14202 orig_decl = TREE_PURPOSE (orig_decl);
14203 if (!orig_decl)
14204 orig_decl = decl;
14206 gimplify_omp_ctxp->loop_iter_var.quick_push (orig_decl);
14208 else
14209 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
14210 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
14213 if (for_stmt == orig_for_stmt)
14215 tree orig_decl = decl;
14216 if (OMP_FOR_ORIG_DECLS (for_stmt))
14218 tree orig_decl = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
14219 if (TREE_CODE (orig_decl) == TREE_LIST)
14221 orig_decl = TREE_PURPOSE (orig_decl);
14222 if (!orig_decl)
14223 orig_decl = decl;
14226 if (is_global_var (orig_decl) && DECL_THREAD_LOCAL_P (orig_decl))
14227 error_at (EXPR_LOCATION (for_stmt),
14228 "threadprivate iteration variable %qD", orig_decl);
14231 /* Make sure the iteration variable is private. */
14232 tree c = NULL_TREE;
14233 tree c2 = NULL_TREE;
14234 if (orig_for_stmt != for_stmt)
14236 /* Preserve this information until we gimplify the inner simd. */
14237 if (has_decl_expr
14238 && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
14239 TREE_PRIVATE (t) = 1;
14241 else if (ort == ORT_SIMD)
14243 splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
14244 (splay_tree_key) decl);
14245 omp_is_private (gimplify_omp_ctxp, decl,
14246 1 + (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
14247 != 1));
14248 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
14250 omp_notice_variable (gimplify_omp_ctxp, decl, true);
14251 if (n->value & GOVD_LASTPRIVATE_CONDITIONAL)
14252 for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
14253 OMP_CLAUSE_LASTPRIVATE);
14254 c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
14255 OMP_CLAUSE_LASTPRIVATE))
14256 if (OMP_CLAUSE_DECL (c3) == decl)
14258 warning_at (OMP_CLAUSE_LOCATION (c3), 0,
14259 "conditional %<lastprivate%> on loop "
14260 "iterator %qD ignored", decl);
14261 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
14262 n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
14265 else if (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1 && !loop_p)
14267 c = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
14268 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
14269 unsigned int flags = GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN;
14270 if ((has_decl_expr
14271 && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
14272 || TREE_PRIVATE (t))
14274 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
14275 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
14277 struct gimplify_omp_ctx *outer
14278 = gimplify_omp_ctxp->outer_context;
14279 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
14281 if (outer->region_type == ORT_WORKSHARE
14282 && outer->combined_loop)
14284 n = splay_tree_lookup (outer->variables,
14285 (splay_tree_key)decl);
14286 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
14288 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
14289 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
14291 else
14293 struct gimplify_omp_ctx *octx = outer->outer_context;
14294 if (octx
14295 && octx->region_type == ORT_COMBINED_PARALLEL
14296 && octx->outer_context
14297 && (octx->outer_context->region_type
14298 == ORT_WORKSHARE)
14299 && octx->outer_context->combined_loop)
14301 octx = octx->outer_context;
14302 n = splay_tree_lookup (octx->variables,
14303 (splay_tree_key)decl);
14304 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
14306 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
14307 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
14314 OMP_CLAUSE_DECL (c) = decl;
14315 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
14316 OMP_FOR_CLAUSES (for_stmt) = c;
14317 omp_add_variable (gimplify_omp_ctxp, decl, flags);
14318 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
14319 omp_lastprivate_for_combined_outer_constructs (outer, decl,
14320 true);
14322 else
14324 bool lastprivate
14325 = (!has_decl_expr
14326 || !bitmap_bit_p (has_decl_expr, DECL_UID (decl)));
14327 if (TREE_PRIVATE (t))
14328 lastprivate = false;
14329 if (loop_p && OMP_FOR_ORIG_DECLS (for_stmt))
14331 tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
14332 if (TREE_CODE (elt) == TREE_LIST && TREE_PURPOSE (elt))
14333 lastprivate = false;
14336 struct gimplify_omp_ctx *outer
14337 = gimplify_omp_ctxp->outer_context;
14338 if (outer && lastprivate)
14339 omp_lastprivate_for_combined_outer_constructs (outer, decl,
14340 true);
14342 c = build_omp_clause (input_location,
14343 lastprivate ? OMP_CLAUSE_LASTPRIVATE
14344 : OMP_CLAUSE_PRIVATE);
14345 OMP_CLAUSE_DECL (c) = decl;
14346 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
14347 OMP_FOR_CLAUSES (for_stmt) = c;
14348 omp_add_variable (gimplify_omp_ctxp, decl,
14349 (lastprivate ? GOVD_LASTPRIVATE : GOVD_PRIVATE)
14350 | GOVD_EXPLICIT | GOVD_SEEN);
14351 c = NULL_TREE;
14354 else if (omp_is_private (gimplify_omp_ctxp, decl, 0))
14356 omp_notice_variable (gimplify_omp_ctxp, decl, true);
14357 splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
14358 (splay_tree_key) decl);
14359 if (n && (n->value & GOVD_LASTPRIVATE_CONDITIONAL))
14360 for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
14361 OMP_CLAUSE_LASTPRIVATE);
14362 c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
14363 OMP_CLAUSE_LASTPRIVATE))
14364 if (OMP_CLAUSE_DECL (c3) == decl)
14366 warning_at (OMP_CLAUSE_LOCATION (c3), 0,
14367 "conditional %<lastprivate%> on loop "
14368 "iterator %qD ignored", decl);
14369 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
14370 n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
14373 else
14374 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN);
14376 /* If DECL is not a gimple register, create a temporary variable to act
14377 as an iteration counter. This is valid, since DECL cannot be
14378 modified in the body of the loop. Similarly for any iteration vars
14379 in simd with collapse > 1 where the iterator vars must be
14380 lastprivate. And similarly for vars mentioned in allocate clauses. */
14381 if (orig_for_stmt != for_stmt)
14382 var = decl;
14383 else if (!is_gimple_reg (decl)
14384 || (ort == ORT_SIMD
14385 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) > 1)
14386 || (allocate_uids && allocate_uids->contains (decl)))
14388 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
14389 /* Make sure omp_add_variable is not called on it prematurely.
14390 We call it ourselves a few lines later. */
14391 gimplify_omp_ctxp = NULL;
14392 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
14393 gimplify_omp_ctxp = ctx;
14394 TREE_OPERAND (t, 0) = var;
14396 gimplify_seq_add_stmt (&for_body, gimple_build_assign (decl, var));
14398 if (ort == ORT_SIMD
14399 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
14401 c2 = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
14402 OMP_CLAUSE_LINEAR_NO_COPYIN (c2) = 1;
14403 OMP_CLAUSE_LINEAR_NO_COPYOUT (c2) = 1;
14404 OMP_CLAUSE_DECL (c2) = var;
14405 OMP_CLAUSE_CHAIN (c2) = OMP_FOR_CLAUSES (for_stmt);
14406 OMP_FOR_CLAUSES (for_stmt) = c2;
14407 omp_add_variable (gimplify_omp_ctxp, var,
14408 GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN);
14409 if (c == NULL_TREE)
14411 c = c2;
14412 c2 = NULL_TREE;
14415 else
14416 omp_add_variable (gimplify_omp_ctxp, var,
14417 GOVD_PRIVATE | GOVD_SEEN);
14419 else
14420 var = decl;
14422 gimplify_omp_ctxp->in_for_exprs = true;
14423 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
14425 tree lb = TREE_OPERAND (t, 1);
14426 tret = gimplify_expr (&TREE_VEC_ELT (lb, 1), &for_pre_body, NULL,
14427 is_gimple_val, fb_rvalue, false);
14428 ret = MIN (ret, tret);
14429 tret = gimplify_expr (&TREE_VEC_ELT (lb, 2), &for_pre_body, NULL,
14430 is_gimple_val, fb_rvalue, false);
14432 else
14433 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
14434 is_gimple_val, fb_rvalue, false);
14435 gimplify_omp_ctxp->in_for_exprs = false;
14436 ret = MIN (ret, tret);
14437 if (ret == GS_ERROR)
14438 return ret;
14440 /* Handle OMP_FOR_COND. */
14441 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
14442 gcc_assert (COMPARISON_CLASS_P (t));
14443 gcc_assert (TREE_OPERAND (t, 0) == decl);
14445 gimplify_omp_ctxp->in_for_exprs = true;
14446 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
14448 tree ub = TREE_OPERAND (t, 1);
14449 tret = gimplify_expr (&TREE_VEC_ELT (ub, 1), &for_pre_body, NULL,
14450 is_gimple_val, fb_rvalue, false);
14451 ret = MIN (ret, tret);
14452 tret = gimplify_expr (&TREE_VEC_ELT (ub, 2), &for_pre_body, NULL,
14453 is_gimple_val, fb_rvalue, false);
14455 else
14456 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
14457 is_gimple_val, fb_rvalue, false);
14458 gimplify_omp_ctxp->in_for_exprs = false;
14459 ret = MIN (ret, tret);
14461 /* Handle OMP_FOR_INCR. */
14462 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
14463 switch (TREE_CODE (t))
14465 case PREINCREMENT_EXPR:
14466 case POSTINCREMENT_EXPR:
14468 tree decl = TREE_OPERAND (t, 0);
14469 /* c_omp_for_incr_canonicalize_ptr() should have been
14470 called to massage things appropriately. */
14471 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
14473 if (orig_for_stmt != for_stmt)
14474 break;
14475 t = build_int_cst (TREE_TYPE (decl), 1);
14476 if (c)
14477 OMP_CLAUSE_LINEAR_STEP (c) = t;
14478 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
14479 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
14480 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
14481 break;
14484 case PREDECREMENT_EXPR:
14485 case POSTDECREMENT_EXPR:
14486 /* c_omp_for_incr_canonicalize_ptr() should have been
14487 called to massage things appropriately. */
14488 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
14489 if (orig_for_stmt != for_stmt)
14490 break;
14491 t = build_int_cst (TREE_TYPE (decl), -1);
14492 if (c)
14493 OMP_CLAUSE_LINEAR_STEP (c) = t;
14494 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
14495 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
14496 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
14497 break;
14499 case MODIFY_EXPR:
14500 gcc_assert (TREE_OPERAND (t, 0) == decl);
14501 TREE_OPERAND (t, 0) = var;
14503 t = TREE_OPERAND (t, 1);
14504 switch (TREE_CODE (t))
14506 case PLUS_EXPR:
14507 if (TREE_OPERAND (t, 1) == decl)
14509 TREE_OPERAND (t, 1) = TREE_OPERAND (t, 0);
14510 TREE_OPERAND (t, 0) = var;
14511 break;
14514 /* Fallthru. */
14515 case MINUS_EXPR:
14516 case POINTER_PLUS_EXPR:
14517 gcc_assert (TREE_OPERAND (t, 0) == decl);
14518 TREE_OPERAND (t, 0) = var;
14519 break;
14520 default:
14521 gcc_unreachable ();
14524 gimplify_omp_ctxp->in_for_exprs = true;
14525 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
14526 is_gimple_val, fb_rvalue, false);
14527 ret = MIN (ret, tret);
14528 if (c)
14530 tree step = TREE_OPERAND (t, 1);
14531 tree stept = TREE_TYPE (decl);
14532 if (POINTER_TYPE_P (stept))
14533 stept = sizetype;
14534 step = fold_convert (stept, step);
14535 if (TREE_CODE (t) == MINUS_EXPR)
14536 step = fold_build1 (NEGATE_EXPR, stept, step);
14537 OMP_CLAUSE_LINEAR_STEP (c) = step;
14538 if (step != TREE_OPERAND (t, 1))
14540 tret = gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c),
14541 &for_pre_body, NULL,
14542 is_gimple_val, fb_rvalue, false);
14543 ret = MIN (ret, tret);
14546 gimplify_omp_ctxp->in_for_exprs = false;
14547 break;
14549 default:
14550 gcc_unreachable ();
14553 if (c2)
14555 gcc_assert (c);
14556 OMP_CLAUSE_LINEAR_STEP (c2) = OMP_CLAUSE_LINEAR_STEP (c);
14559 if ((var != decl || collapse > 1 || tile) && orig_for_stmt == for_stmt)
14561 for (c = OMP_FOR_CLAUSES (for_stmt); c ; c = OMP_CLAUSE_CHAIN (c))
14562 if (((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
14563 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) == NULL)
14564 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
14565 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)
14566 && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c) == NULL))
14567 && OMP_CLAUSE_DECL (c) == decl)
14569 if (is_doacross && (collapse == 1 || i >= collapse))
14570 t = var;
14571 else
14573 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
14574 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
14575 gcc_assert (TREE_OPERAND (t, 0) == var);
14576 t = TREE_OPERAND (t, 1);
14577 gcc_assert (TREE_CODE (t) == PLUS_EXPR
14578 || TREE_CODE (t) == MINUS_EXPR
14579 || TREE_CODE (t) == POINTER_PLUS_EXPR);
14580 gcc_assert (TREE_OPERAND (t, 0) == var);
14581 t = build2 (TREE_CODE (t), TREE_TYPE (decl),
14582 is_doacross ? var : decl,
14583 TREE_OPERAND (t, 1));
14585 gimple_seq *seq;
14586 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
14587 seq = &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c);
14588 else
14589 seq = &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c);
14590 push_gimplify_context ();
14591 gimplify_assign (decl, t, seq);
14592 gimple *bind = NULL;
14593 if (gimplify_ctxp->temps)
14595 bind = gimple_build_bind (NULL_TREE, *seq, NULL_TREE);
14596 *seq = NULL;
14597 gimplify_seq_add_stmt (seq, bind);
14599 pop_gimplify_context (bind);
14602 if (OMP_FOR_NON_RECTANGULAR (for_stmt) && var != decl)
14603 for (int j = i + 1; j < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); j++)
14605 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), j);
14606 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
14607 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
14608 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
14609 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
14610 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), j);
14611 gcc_assert (COMPARISON_CLASS_P (t));
14612 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
14613 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
14614 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
14618 BITMAP_FREE (has_decl_expr);
14619 delete allocate_uids;
14621 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP
14622 || (loop_p && orig_for_stmt == for_stmt))
14624 push_gimplify_context ();
14625 if (TREE_CODE (OMP_FOR_BODY (orig_for_stmt)) != BIND_EXPR)
14627 OMP_FOR_BODY (orig_for_stmt)
14628 = build3 (BIND_EXPR, void_type_node, NULL,
14629 OMP_FOR_BODY (orig_for_stmt), NULL);
14630 TREE_SIDE_EFFECTS (OMP_FOR_BODY (orig_for_stmt)) = 1;
14634 gimple *g = gimplify_and_return_first (OMP_FOR_BODY (orig_for_stmt),
14635 &for_body);
14637 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP
14638 || (loop_p && orig_for_stmt == for_stmt))
14640 if (gimple_code (g) == GIMPLE_BIND)
14641 pop_gimplify_context (g);
14642 else
14643 pop_gimplify_context (NULL);
14646 if (orig_for_stmt != for_stmt)
14647 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
14649 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
14650 decl = TREE_OPERAND (t, 0);
14651 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
14652 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
14653 gimplify_omp_ctxp = ctx->outer_context;
14654 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
14655 gimplify_omp_ctxp = ctx;
14656 omp_add_variable (gimplify_omp_ctxp, var, GOVD_PRIVATE | GOVD_SEEN);
14657 TREE_OPERAND (t, 0) = var;
14658 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
14659 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
14660 TREE_OPERAND (TREE_OPERAND (t, 1), 0) = var;
14661 if (OMP_FOR_NON_RECTANGULAR (for_stmt))
14662 for (int j = i + 1;
14663 j < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); j++)
14665 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), j);
14666 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
14667 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
14668 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
14670 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
14671 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
14673 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), j);
14674 gcc_assert (COMPARISON_CLASS_P (t));
14675 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
14676 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
14678 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
14679 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
14684 gimplify_adjust_omp_clauses (pre_p, for_body,
14685 &OMP_FOR_CLAUSES (orig_for_stmt),
14686 TREE_CODE (orig_for_stmt));
14688 int kind;
14689 switch (TREE_CODE (orig_for_stmt))
14691 case OMP_FOR: kind = GF_OMP_FOR_KIND_FOR; break;
14692 case OMP_SIMD: kind = GF_OMP_FOR_KIND_SIMD; break;
14693 case OMP_DISTRIBUTE: kind = GF_OMP_FOR_KIND_DISTRIBUTE; break;
14694 case OMP_TASKLOOP: kind = GF_OMP_FOR_KIND_TASKLOOP; break;
14695 case OACC_LOOP: kind = GF_OMP_FOR_KIND_OACC_LOOP; break;
14696 default:
14697 gcc_unreachable ();
14699 if (loop_p && kind == GF_OMP_FOR_KIND_SIMD)
14701 gimplify_seq_add_seq (pre_p, for_pre_body);
14702 for_pre_body = NULL;
14704 gfor = gimple_build_omp_for (for_body, kind, OMP_FOR_CLAUSES (orig_for_stmt),
14705 TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)),
14706 for_pre_body);
14707 if (orig_for_stmt != for_stmt)
14708 gimple_omp_for_set_combined_p (gfor, true);
14709 if (gimplify_omp_ctxp
14710 && (gimplify_omp_ctxp->combined_loop
14711 || (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
14712 && gimplify_omp_ctxp->outer_context
14713 && gimplify_omp_ctxp->outer_context->combined_loop)))
14715 gimple_omp_for_set_combined_into_p (gfor, true);
14716 if (gimplify_omp_ctxp->combined_loop)
14717 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_SIMD);
14718 else
14719 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_FOR);
14722 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
14724 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
14725 gimple_omp_for_set_index (gfor, i, TREE_OPERAND (t, 0));
14726 gimple_omp_for_set_initial (gfor, i, TREE_OPERAND (t, 1));
14727 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
14728 gimple_omp_for_set_cond (gfor, i, TREE_CODE (t));
14729 gimple_omp_for_set_final (gfor, i, TREE_OPERAND (t, 1));
14730 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
14731 gimple_omp_for_set_incr (gfor, i, TREE_OPERAND (t, 1));
14734 /* OMP_TASKLOOP is gimplified as two GIMPLE_OMP_FOR taskloop
14735 constructs with GIMPLE_OMP_TASK sandwiched in between them.
14736 The outer taskloop stands for computing the number of iterations,
14737 counts for collapsed loops and holding taskloop specific clauses.
14738 The task construct stands for the effect of data sharing on the
14739 explicit task it creates and the inner taskloop stands for expansion
14740 of the static loop inside of the explicit task construct. */
14741 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
14743 tree *gfor_clauses_ptr = gimple_omp_for_clauses_ptr (gfor);
14744 tree task_clauses = NULL_TREE;
14745 tree c = *gfor_clauses_ptr;
14746 tree *gtask_clauses_ptr = &task_clauses;
14747 tree outer_for_clauses = NULL_TREE;
14748 tree *gforo_clauses_ptr = &outer_for_clauses;
14749 bitmap lastprivate_uids = NULL;
14750 if (omp_find_clause (c, OMP_CLAUSE_ALLOCATE))
14752 c = omp_find_clause (c, OMP_CLAUSE_LASTPRIVATE);
14753 if (c)
14755 lastprivate_uids = BITMAP_ALLOC (NULL);
14756 for (; c; c = omp_find_clause (OMP_CLAUSE_CHAIN (c),
14757 OMP_CLAUSE_LASTPRIVATE))
14758 bitmap_set_bit (lastprivate_uids,
14759 DECL_UID (OMP_CLAUSE_DECL (c)));
14761 c = *gfor_clauses_ptr;
14763 for (; c; c = OMP_CLAUSE_CHAIN (c))
14764 switch (OMP_CLAUSE_CODE (c))
14766 /* These clauses are allowed on task, move them there. */
14767 case OMP_CLAUSE_SHARED:
14768 case OMP_CLAUSE_FIRSTPRIVATE:
14769 case OMP_CLAUSE_DEFAULT:
14770 case OMP_CLAUSE_IF:
14771 case OMP_CLAUSE_UNTIED:
14772 case OMP_CLAUSE_FINAL:
14773 case OMP_CLAUSE_MERGEABLE:
14774 case OMP_CLAUSE_PRIORITY:
14775 case OMP_CLAUSE_REDUCTION:
14776 case OMP_CLAUSE_IN_REDUCTION:
14777 *gtask_clauses_ptr = c;
14778 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
14779 break;
14780 case OMP_CLAUSE_PRIVATE:
14781 if (OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c))
14783 /* We want private on outer for and firstprivate
14784 on task. */
14785 *gtask_clauses_ptr
14786 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
14787 OMP_CLAUSE_FIRSTPRIVATE);
14788 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
14789 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL,
14790 openacc);
14791 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
14792 *gforo_clauses_ptr = c;
14793 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
14795 else
14797 *gtask_clauses_ptr = c;
14798 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
14800 break;
14801 /* These clauses go into outer taskloop clauses. */
14802 case OMP_CLAUSE_GRAINSIZE:
14803 case OMP_CLAUSE_NUM_TASKS:
14804 case OMP_CLAUSE_NOGROUP:
14805 *gforo_clauses_ptr = c;
14806 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
14807 break;
14808 /* Collapse clause we duplicate on both taskloops. */
14809 case OMP_CLAUSE_COLLAPSE:
14810 *gfor_clauses_ptr = c;
14811 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
14812 *gforo_clauses_ptr = copy_node (c);
14813 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
14814 break;
14815 /* For lastprivate, keep the clause on inner taskloop, and add
14816 a shared clause on task. If the same decl is also firstprivate,
14817 add also firstprivate clause on the inner taskloop. */
14818 case OMP_CLAUSE_LASTPRIVATE:
14819 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
14821 /* For taskloop C++ lastprivate IVs, we want:
14822 1) private on outer taskloop
14823 2) firstprivate and shared on task
14824 3) lastprivate on inner taskloop */
14825 *gtask_clauses_ptr
14826 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
14827 OMP_CLAUSE_FIRSTPRIVATE);
14828 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
14829 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL,
14830 openacc);
14831 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
14832 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c) = 1;
14833 *gforo_clauses_ptr = build_omp_clause (OMP_CLAUSE_LOCATION (c),
14834 OMP_CLAUSE_PRIVATE);
14835 OMP_CLAUSE_DECL (*gforo_clauses_ptr) = OMP_CLAUSE_DECL (c);
14836 OMP_CLAUSE_PRIVATE_TASKLOOP_IV (*gforo_clauses_ptr) = 1;
14837 TREE_TYPE (*gforo_clauses_ptr) = TREE_TYPE (c);
14838 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
14840 *gfor_clauses_ptr = c;
14841 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
14842 *gtask_clauses_ptr
14843 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_SHARED);
14844 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
14845 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
14846 OMP_CLAUSE_SHARED_FIRSTPRIVATE (*gtask_clauses_ptr) = 1;
14847 gtask_clauses_ptr
14848 = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
14849 break;
14850 /* Allocate clause we duplicate on task and inner taskloop
14851 if the decl is lastprivate, otherwise just put on task. */
14852 case OMP_CLAUSE_ALLOCATE:
14853 if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
14854 && DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)))
14856 /* Additionally, put firstprivate clause on task
14857 for the allocator if it is not constant. */
14858 *gtask_clauses_ptr
14859 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
14860 OMP_CLAUSE_FIRSTPRIVATE);
14861 OMP_CLAUSE_DECL (*gtask_clauses_ptr)
14862 = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
14863 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
14865 if (lastprivate_uids
14866 && bitmap_bit_p (lastprivate_uids,
14867 DECL_UID (OMP_CLAUSE_DECL (c))))
14869 *gfor_clauses_ptr = c;
14870 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
14871 *gtask_clauses_ptr = copy_node (c);
14872 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
14874 else
14876 *gtask_clauses_ptr = c;
14877 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
14879 break;
14880 default:
14881 gcc_unreachable ();
14883 *gfor_clauses_ptr = NULL_TREE;
14884 *gtask_clauses_ptr = NULL_TREE;
14885 *gforo_clauses_ptr = NULL_TREE;
14886 BITMAP_FREE (lastprivate_uids);
14887 gimple_set_location (gfor, input_location);
14888 g = gimple_build_bind (NULL_TREE, gfor, NULL_TREE);
14889 g = gimple_build_omp_task (g, task_clauses, NULL_TREE, NULL_TREE,
14890 NULL_TREE, NULL_TREE, NULL_TREE);
14891 gimple_set_location (g, input_location);
14892 gimple_omp_task_set_taskloop_p (g, true);
14893 g = gimple_build_bind (NULL_TREE, g, NULL_TREE);
14894 gomp_for *gforo
14895 = gimple_build_omp_for (g, GF_OMP_FOR_KIND_TASKLOOP, outer_for_clauses,
14896 gimple_omp_for_collapse (gfor),
14897 gimple_omp_for_pre_body (gfor));
14898 gimple_omp_for_set_pre_body (gfor, NULL);
14899 gimple_omp_for_set_combined_p (gforo, true);
14900 gimple_omp_for_set_combined_into_p (gfor, true);
14901 for (i = 0; i < (int) gimple_omp_for_collapse (gfor); i++)
14903 tree type = TREE_TYPE (gimple_omp_for_index (gfor, i));
14904 tree v = create_tmp_var (type);
14905 gimple_omp_for_set_index (gforo, i, v);
14906 t = unshare_expr (gimple_omp_for_initial (gfor, i));
14907 gimple_omp_for_set_initial (gforo, i, t);
14908 gimple_omp_for_set_cond (gforo, i,
14909 gimple_omp_for_cond (gfor, i));
14910 t = unshare_expr (gimple_omp_for_final (gfor, i));
14911 gimple_omp_for_set_final (gforo, i, t);
14912 t = unshare_expr (gimple_omp_for_incr (gfor, i));
14913 gcc_assert (TREE_OPERAND (t, 0) == gimple_omp_for_index (gfor, i));
14914 TREE_OPERAND (t, 0) = v;
14915 gimple_omp_for_set_incr (gforo, i, t);
14916 t = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
14917 OMP_CLAUSE_DECL (t) = v;
14918 OMP_CLAUSE_CHAIN (t) = gimple_omp_for_clauses (gforo);
14919 gimple_omp_for_set_clauses (gforo, t);
14920 if (OMP_FOR_NON_RECTANGULAR (for_stmt))
14922 tree *p1 = NULL, *p2 = NULL;
14923 t = gimple_omp_for_initial (gforo, i);
14924 if (TREE_CODE (t) == TREE_VEC)
14925 p1 = &TREE_VEC_ELT (t, 0);
14926 t = gimple_omp_for_final (gforo, i);
14927 if (TREE_CODE (t) == TREE_VEC)
14929 if (p1)
14930 p2 = &TREE_VEC_ELT (t, 0);
14931 else
14932 p1 = &TREE_VEC_ELT (t, 0);
14934 if (p1)
14936 int j;
14937 for (j = 0; j < i; j++)
14938 if (*p1 == gimple_omp_for_index (gfor, j))
14940 *p1 = gimple_omp_for_index (gforo, j);
14941 if (p2)
14942 *p2 = *p1;
14943 break;
14945 gcc_assert (j < i);
14949 gimplify_seq_add_stmt (pre_p, gforo);
14951 else
14952 gimplify_seq_add_stmt (pre_p, gfor);
14954 if (TREE_CODE (orig_for_stmt) == OMP_FOR)
14956 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
14957 unsigned lastprivate_conditional = 0;
14958 while (ctx
14959 && (ctx->region_type == ORT_TARGET_DATA
14960 || ctx->region_type == ORT_TASKGROUP))
14961 ctx = ctx->outer_context;
14962 if (ctx && (ctx->region_type & ORT_PARALLEL) != 0)
14963 for (tree c = gimple_omp_for_clauses (gfor);
14964 c; c = OMP_CLAUSE_CHAIN (c))
14965 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
14966 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
14967 ++lastprivate_conditional;
14968 if (lastprivate_conditional)
14970 struct omp_for_data fd;
14971 omp_extract_for_data (gfor, &fd, NULL);
14972 tree type = build_array_type_nelts (unsigned_type_for (fd.iter_type),
14973 lastprivate_conditional);
14974 tree var = create_tmp_var_raw (type);
14975 tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__CONDTEMP_);
14976 OMP_CLAUSE_DECL (c) = var;
14977 OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor);
14978 gimple_omp_for_set_clauses (gfor, c);
14979 omp_add_variable (ctx, var, GOVD_CONDTEMP | GOVD_SEEN);
14982 else if (TREE_CODE (orig_for_stmt) == OMP_SIMD)
14984 unsigned lastprivate_conditional = 0;
14985 for (tree c = gimple_omp_for_clauses (gfor); c; c = OMP_CLAUSE_CHAIN (c))
14986 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
14987 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
14988 ++lastprivate_conditional;
14989 if (lastprivate_conditional)
14991 struct omp_for_data fd;
14992 omp_extract_for_data (gfor, &fd, NULL);
14993 tree type = unsigned_type_for (fd.iter_type);
14994 while (lastprivate_conditional--)
14996 tree c = build_omp_clause (UNKNOWN_LOCATION,
14997 OMP_CLAUSE__CONDTEMP_);
14998 OMP_CLAUSE_DECL (c) = create_tmp_var (type);
14999 OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor);
15000 gimple_omp_for_set_clauses (gfor, c);
15005 if (ret != GS_ALL_DONE)
15006 return GS_ERROR;
15007 *expr_p = NULL_TREE;
15008 return GS_ALL_DONE;
15011 /* Helper for gimplify_omp_loop, called through walk_tree. */
15013 static tree
15014 note_no_context_vars (tree *tp, int *, void *data)
15016 if (VAR_P (*tp)
15017 && DECL_CONTEXT (*tp) == NULL_TREE
15018 && !is_global_var (*tp))
15020 vec<tree> *d = (vec<tree> *) data;
15021 d->safe_push (*tp);
15022 DECL_CONTEXT (*tp) = current_function_decl;
15024 return NULL_TREE;
15027 /* Gimplify the gross structure of an OMP_LOOP statement. */
15029 static enum gimplify_status
15030 gimplify_omp_loop (tree *expr_p, gimple_seq *pre_p)
15032 tree for_stmt = *expr_p;
15033 tree clauses = OMP_FOR_CLAUSES (for_stmt);
15034 struct gimplify_omp_ctx *octx = gimplify_omp_ctxp;
15035 enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
15036 int i;
15038 /* If order is not present, the behavior is as if order(concurrent)
15039 appeared. */
15040 tree order = omp_find_clause (clauses, OMP_CLAUSE_ORDER);
15041 if (order == NULL_TREE)
15043 order = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_ORDER);
15044 OMP_CLAUSE_CHAIN (order) = clauses;
15045 OMP_FOR_CLAUSES (for_stmt) = clauses = order;
15048 tree bind = omp_find_clause (clauses, OMP_CLAUSE_BIND);
15049 if (bind == NULL_TREE)
15051 if (!flag_openmp) /* flag_openmp_simd */
15053 else if (octx && (octx->region_type & ORT_TEAMS) != 0)
15054 kind = OMP_CLAUSE_BIND_TEAMS;
15055 else if (octx && (octx->region_type & ORT_PARALLEL) != 0)
15056 kind = OMP_CLAUSE_BIND_PARALLEL;
15057 else
15059 for (; octx; octx = octx->outer_context)
15061 if ((octx->region_type & ORT_ACC) != 0
15062 || octx->region_type == ORT_NONE
15063 || octx->region_type == ORT_IMPLICIT_TARGET)
15064 continue;
15065 break;
15067 if (octx == NULL && !in_omp_construct)
15068 error_at (EXPR_LOCATION (for_stmt),
15069 "%<bind%> clause not specified on a %<loop%> "
15070 "construct not nested inside another OpenMP construct");
15072 bind = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_BIND);
15073 OMP_CLAUSE_CHAIN (bind) = clauses;
15074 OMP_CLAUSE_BIND_KIND (bind) = kind;
15075 OMP_FOR_CLAUSES (for_stmt) = bind;
15077 else
15078 switch (OMP_CLAUSE_BIND_KIND (bind))
15080 case OMP_CLAUSE_BIND_THREAD:
15081 break;
15082 case OMP_CLAUSE_BIND_PARALLEL:
15083 if (!flag_openmp) /* flag_openmp_simd */
15085 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
15086 break;
15088 for (; octx; octx = octx->outer_context)
15089 if (octx->region_type == ORT_SIMD
15090 && omp_find_clause (octx->clauses, OMP_CLAUSE_BIND) == NULL_TREE)
15092 error_at (EXPR_LOCATION (for_stmt),
15093 "%<bind(parallel)%> on a %<loop%> construct nested "
15094 "inside %<simd%> construct");
15095 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
15096 break;
15098 kind = OMP_CLAUSE_BIND_PARALLEL;
15099 break;
15100 case OMP_CLAUSE_BIND_TEAMS:
15101 if (!flag_openmp) /* flag_openmp_simd */
15103 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
15104 break;
15106 if ((octx
15107 && octx->region_type != ORT_IMPLICIT_TARGET
15108 && octx->region_type != ORT_NONE
15109 && (octx->region_type & ORT_TEAMS) == 0)
15110 || in_omp_construct)
15112 error_at (EXPR_LOCATION (for_stmt),
15113 "%<bind(teams)%> on a %<loop%> region not strictly "
15114 "nested inside of a %<teams%> region");
15115 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
15116 break;
15118 kind = OMP_CLAUSE_BIND_TEAMS;
15119 break;
15120 default:
15121 gcc_unreachable ();
15124 for (tree *pc = &OMP_FOR_CLAUSES (for_stmt); *pc; )
15125 switch (OMP_CLAUSE_CODE (*pc))
15127 case OMP_CLAUSE_REDUCTION:
15128 if (OMP_CLAUSE_REDUCTION_INSCAN (*pc))
15130 error_at (OMP_CLAUSE_LOCATION (*pc),
15131 "%<inscan%> %<reduction%> clause on "
15132 "%qs construct", "loop");
15133 OMP_CLAUSE_REDUCTION_INSCAN (*pc) = 0;
15135 if (OMP_CLAUSE_REDUCTION_TASK (*pc))
15137 error_at (OMP_CLAUSE_LOCATION (*pc),
15138 "invalid %<task%> reduction modifier on construct "
15139 "other than %<parallel%>, %qs or %<sections%>",
15140 lang_GNU_Fortran () ? "do" : "for");
15141 OMP_CLAUSE_REDUCTION_TASK (*pc) = 0;
15143 pc = &OMP_CLAUSE_CHAIN (*pc);
15144 break;
15145 case OMP_CLAUSE_LASTPRIVATE:
15146 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
15148 tree t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
15149 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
15150 if (OMP_CLAUSE_DECL (*pc) == TREE_OPERAND (t, 0))
15151 break;
15152 if (OMP_FOR_ORIG_DECLS (for_stmt)
15153 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt),
15154 i)) == TREE_LIST
15155 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt),
15156 i)))
15158 tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
15159 if (OMP_CLAUSE_DECL (*pc) == TREE_PURPOSE (orig))
15160 break;
15163 if (i == TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)))
15165 error_at (OMP_CLAUSE_LOCATION (*pc),
15166 "%<lastprivate%> clause on a %<loop%> construct refers "
15167 "to a variable %qD which is not the loop iterator",
15168 OMP_CLAUSE_DECL (*pc));
15169 *pc = OMP_CLAUSE_CHAIN (*pc);
15170 break;
15172 pc = &OMP_CLAUSE_CHAIN (*pc);
15173 break;
15174 default:
15175 pc = &OMP_CLAUSE_CHAIN (*pc);
15176 break;
15179 TREE_SET_CODE (for_stmt, OMP_SIMD);
15181 int last;
15182 switch (kind)
15184 case OMP_CLAUSE_BIND_THREAD: last = 0; break;
15185 case OMP_CLAUSE_BIND_PARALLEL: last = 1; break;
15186 case OMP_CLAUSE_BIND_TEAMS: last = 2; break;
15188 for (int pass = 1; pass <= last; pass++)
15190 if (pass == 2)
15192 tree bind = build3 (BIND_EXPR, void_type_node, NULL, NULL,
15193 make_node (BLOCK));
15194 append_to_statement_list (*expr_p, &BIND_EXPR_BODY (bind));
15195 *expr_p = make_node (OMP_PARALLEL);
15196 TREE_TYPE (*expr_p) = void_type_node;
15197 OMP_PARALLEL_BODY (*expr_p) = bind;
15198 OMP_PARALLEL_COMBINED (*expr_p) = 1;
15199 SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (for_stmt));
15200 tree *pc = &OMP_PARALLEL_CLAUSES (*expr_p);
15201 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
15202 if (OMP_FOR_ORIG_DECLS (for_stmt)
15203 && (TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i))
15204 == TREE_LIST))
15206 tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
15207 if (TREE_PURPOSE (elt) && TREE_VALUE (elt))
15209 *pc = build_omp_clause (UNKNOWN_LOCATION,
15210 OMP_CLAUSE_FIRSTPRIVATE);
15211 OMP_CLAUSE_DECL (*pc) = TREE_VALUE (elt);
15212 pc = &OMP_CLAUSE_CHAIN (*pc);
15216 tree t = make_node (pass == 2 ? OMP_DISTRIBUTE : OMP_FOR);
15217 tree *pc = &OMP_FOR_CLAUSES (t);
15218 TREE_TYPE (t) = void_type_node;
15219 OMP_FOR_BODY (t) = *expr_p;
15220 SET_EXPR_LOCATION (t, EXPR_LOCATION (for_stmt));
15221 for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
15222 switch (OMP_CLAUSE_CODE (c))
15224 case OMP_CLAUSE_BIND:
15225 case OMP_CLAUSE_ORDER:
15226 case OMP_CLAUSE_COLLAPSE:
15227 *pc = copy_node (c);
15228 pc = &OMP_CLAUSE_CHAIN (*pc);
15229 break;
15230 case OMP_CLAUSE_PRIVATE:
15231 case OMP_CLAUSE_FIRSTPRIVATE:
15232 /* Only needed on innermost. */
15233 break;
15234 case OMP_CLAUSE_LASTPRIVATE:
15235 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c) && pass != last)
15237 *pc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
15238 OMP_CLAUSE_FIRSTPRIVATE);
15239 OMP_CLAUSE_DECL (*pc) = OMP_CLAUSE_DECL (c);
15240 lang_hooks.decls.omp_finish_clause (*pc, NULL, false);
15241 pc = &OMP_CLAUSE_CHAIN (*pc);
15243 *pc = copy_node (c);
15244 OMP_CLAUSE_LASTPRIVATE_STMT (*pc) = NULL_TREE;
15245 TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
15246 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
15248 if (pass != last)
15249 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (*pc) = 1;
15250 else
15251 lang_hooks.decls.omp_finish_clause (*pc, NULL, false);
15252 OMP_CLAUSE_LASTPRIVATE_LOOP_IV (*pc) = 0;
15254 pc = &OMP_CLAUSE_CHAIN (*pc);
15255 break;
15256 case OMP_CLAUSE_REDUCTION:
15257 *pc = copy_node (c);
15258 OMP_CLAUSE_DECL (*pc) = unshare_expr (OMP_CLAUSE_DECL (c));
15259 TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
15260 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc))
15262 auto_vec<tree> no_context_vars;
15263 int walk_subtrees = 0;
15264 note_no_context_vars (&OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
15265 &walk_subtrees, &no_context_vars);
15266 if (tree p = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c))
15267 note_no_context_vars (&p, &walk_subtrees, &no_context_vars);
15268 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_INIT (c),
15269 note_no_context_vars,
15270 &no_context_vars);
15271 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_MERGE (c),
15272 note_no_context_vars,
15273 &no_context_vars);
15275 OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc)
15276 = copy_node (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c));
15277 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc))
15278 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc)
15279 = copy_node (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c));
15281 hash_map<tree, tree> decl_map;
15282 decl_map.put (OMP_CLAUSE_DECL (c), OMP_CLAUSE_DECL (c));
15283 decl_map.put (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
15284 OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc));
15285 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc))
15286 decl_map.put (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
15287 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc));
15289 copy_body_data id;
15290 memset (&id, 0, sizeof (id));
15291 id.src_fn = current_function_decl;
15292 id.dst_fn = current_function_decl;
15293 id.src_cfun = cfun;
15294 id.decl_map = &decl_map;
15295 id.copy_decl = copy_decl_no_change;
15296 id.transform_call_graph_edges = CB_CGE_DUPLICATE;
15297 id.transform_new_cfg = true;
15298 id.transform_return_to_modify = false;
15299 id.eh_lp_nr = 0;
15300 walk_tree (&OMP_CLAUSE_REDUCTION_INIT (*pc), copy_tree_body_r,
15301 &id, NULL);
15302 walk_tree (&OMP_CLAUSE_REDUCTION_MERGE (*pc), copy_tree_body_r,
15303 &id, NULL);
15305 for (tree d : no_context_vars)
15307 DECL_CONTEXT (d) = NULL_TREE;
15308 DECL_CONTEXT (*decl_map.get (d)) = NULL_TREE;
15311 else
15313 OMP_CLAUSE_REDUCTION_INIT (*pc)
15314 = unshare_expr (OMP_CLAUSE_REDUCTION_INIT (c));
15315 OMP_CLAUSE_REDUCTION_MERGE (*pc)
15316 = unshare_expr (OMP_CLAUSE_REDUCTION_MERGE (c));
15318 pc = &OMP_CLAUSE_CHAIN (*pc);
15319 break;
15320 default:
15321 gcc_unreachable ();
15323 *pc = NULL_TREE;
15324 *expr_p = t;
15326 return gimplify_expr (expr_p, pre_p, NULL, is_gimple_stmt, fb_none);
15330 /* Helper function of optimize_target_teams, find OMP_TEAMS inside
15331 of OMP_TARGET's body. */
15333 static tree
15334 find_omp_teams (tree *tp, int *walk_subtrees, void *)
15336 *walk_subtrees = 0;
15337 switch (TREE_CODE (*tp))
15339 case OMP_TEAMS:
15340 return *tp;
15341 case BIND_EXPR:
15342 case STATEMENT_LIST:
15343 *walk_subtrees = 1;
15344 break;
15345 default:
15346 break;
15348 return NULL_TREE;
15351 /* Helper function of optimize_target_teams, determine if the expression
15352 can be computed safely before the target construct on the host. */
15354 static tree
15355 computable_teams_clause (tree *tp, int *walk_subtrees, void *)
15357 splay_tree_node n;
15359 if (TYPE_P (*tp))
15361 *walk_subtrees = 0;
15362 return NULL_TREE;
15364 switch (TREE_CODE (*tp))
15366 case VAR_DECL:
15367 case PARM_DECL:
15368 case RESULT_DECL:
15369 *walk_subtrees = 0;
15370 if (error_operand_p (*tp)
15371 || !INTEGRAL_TYPE_P (TREE_TYPE (*tp))
15372 || DECL_HAS_VALUE_EXPR_P (*tp)
15373 || DECL_THREAD_LOCAL_P (*tp)
15374 || TREE_SIDE_EFFECTS (*tp)
15375 || TREE_THIS_VOLATILE (*tp))
15376 return *tp;
15377 if (is_global_var (*tp)
15378 && (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (*tp))
15379 || lookup_attribute ("omp declare target link",
15380 DECL_ATTRIBUTES (*tp))))
15381 return *tp;
15382 if (VAR_P (*tp)
15383 && !DECL_SEEN_IN_BIND_EXPR_P (*tp)
15384 && !is_global_var (*tp)
15385 && decl_function_context (*tp) == current_function_decl)
15386 return *tp;
15387 n = splay_tree_lookup (gimplify_omp_ctxp->variables,
15388 (splay_tree_key) *tp);
15389 if (n == NULL)
15391 if (gimplify_omp_ctxp->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE)
15392 return NULL_TREE;
15393 return *tp;
15395 else if (n->value & GOVD_LOCAL)
15396 return *tp;
15397 else if (n->value & GOVD_FIRSTPRIVATE)
15398 return NULL_TREE;
15399 else if ((n->value & (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
15400 == (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
15401 return NULL_TREE;
15402 return *tp;
15403 case INTEGER_CST:
15404 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
15405 return *tp;
15406 return NULL_TREE;
15407 case TARGET_EXPR:
15408 if (TARGET_EXPR_INITIAL (*tp)
15409 || TREE_CODE (TARGET_EXPR_SLOT (*tp)) != VAR_DECL)
15410 return *tp;
15411 return computable_teams_clause (&TARGET_EXPR_SLOT (*tp),
15412 walk_subtrees, NULL);
15413 /* Allow some reasonable subset of integral arithmetics. */
15414 case PLUS_EXPR:
15415 case MINUS_EXPR:
15416 case MULT_EXPR:
15417 case TRUNC_DIV_EXPR:
15418 case CEIL_DIV_EXPR:
15419 case FLOOR_DIV_EXPR:
15420 case ROUND_DIV_EXPR:
15421 case TRUNC_MOD_EXPR:
15422 case CEIL_MOD_EXPR:
15423 case FLOOR_MOD_EXPR:
15424 case ROUND_MOD_EXPR:
15425 case RDIV_EXPR:
15426 case EXACT_DIV_EXPR:
15427 case MIN_EXPR:
15428 case MAX_EXPR:
15429 case LSHIFT_EXPR:
15430 case RSHIFT_EXPR:
15431 case BIT_IOR_EXPR:
15432 case BIT_XOR_EXPR:
15433 case BIT_AND_EXPR:
15434 case NEGATE_EXPR:
15435 case ABS_EXPR:
15436 case BIT_NOT_EXPR:
15437 case NON_LVALUE_EXPR:
15438 CASE_CONVERT:
15439 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
15440 return *tp;
15441 return NULL_TREE;
15442 /* And disallow anything else, except for comparisons. */
15443 default:
15444 if (COMPARISON_CLASS_P (*tp))
15445 return NULL_TREE;
15446 return *tp;
15450 /* Try to determine if the num_teams and/or thread_limit expressions
15451 can have their values determined already before entering the
15452 target construct.
15453 INTEGER_CSTs trivially are,
15454 integral decls that are firstprivate (explicitly or implicitly)
15455 or explicitly map(always, to:) or map(always, tofrom:) on the target
15456 region too, and expressions involving simple arithmetics on those
15457 too, function calls are not ok, dereferencing something neither etc.
15458 Add NUM_TEAMS and THREAD_LIMIT clauses to the OMP_CLAUSES of
15459 EXPR based on what we find:
15460 0 stands for clause not specified at all, use implementation default
15461 -1 stands for value that can't be determined easily before entering
15462 the target construct.
15463 -2 means that no explicit teams construct was specified
15464 If teams construct is not present at all, use 1 for num_teams
15465 and 0 for thread_limit (only one team is involved, and the thread
15466 limit is implementation defined. */
15468 static void
15469 optimize_target_teams (tree target, gimple_seq *pre_p)
15471 tree body = OMP_BODY (target);
15472 tree teams = walk_tree (&body, find_omp_teams, NULL, NULL);
15473 tree num_teams_lower = NULL_TREE;
15474 tree num_teams_upper = integer_zero_node;
15475 tree thread_limit = integer_zero_node;
15476 location_t num_teams_loc = EXPR_LOCATION (target);
15477 location_t thread_limit_loc = EXPR_LOCATION (target);
15478 tree c, *p, expr;
15479 struct gimplify_omp_ctx *target_ctx = gimplify_omp_ctxp;
15481 if (teams == NULL_TREE)
15482 num_teams_upper = build_int_cst (integer_type_node, -2);
15483 else
15484 for (c = OMP_TEAMS_CLAUSES (teams); c; c = OMP_CLAUSE_CHAIN (c))
15486 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS)
15488 p = &num_teams_upper;
15489 num_teams_loc = OMP_CLAUSE_LOCATION (c);
15490 if (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c))
15492 expr = OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c);
15493 if (TREE_CODE (expr) == INTEGER_CST)
15494 num_teams_lower = expr;
15495 else if (walk_tree (&expr, computable_teams_clause,
15496 NULL, NULL))
15497 num_teams_lower = integer_minus_one_node;
15498 else
15500 num_teams_lower = expr;
15501 gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
15502 if (gimplify_expr (&num_teams_lower, pre_p, NULL,
15503 is_gimple_val, fb_rvalue, false)
15504 == GS_ERROR)
15506 gimplify_omp_ctxp = target_ctx;
15507 num_teams_lower = integer_minus_one_node;
15509 else
15511 gimplify_omp_ctxp = target_ctx;
15512 if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR)
15513 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
15514 = num_teams_lower;
15519 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
15521 p = &thread_limit;
15522 thread_limit_loc = OMP_CLAUSE_LOCATION (c);
15524 else
15525 continue;
15526 expr = OMP_CLAUSE_OPERAND (c, 0);
15527 if (TREE_CODE (expr) == INTEGER_CST)
15529 *p = expr;
15530 continue;
15532 if (walk_tree (&expr, computable_teams_clause, NULL, NULL))
15534 *p = integer_minus_one_node;
15535 continue;
15537 *p = expr;
15538 gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
15539 if (gimplify_expr (p, pre_p, NULL, is_gimple_val, fb_rvalue, false)
15540 == GS_ERROR)
15542 gimplify_omp_ctxp = target_ctx;
15543 *p = integer_minus_one_node;
15544 continue;
15546 gimplify_omp_ctxp = target_ctx;
15547 if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR)
15548 OMP_CLAUSE_OPERAND (c, 0) = *p;
15550 if (!omp_find_clause (OMP_TARGET_CLAUSES (target), OMP_CLAUSE_THREAD_LIMIT))
15552 c = build_omp_clause (thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
15553 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = thread_limit;
15554 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
15555 OMP_TARGET_CLAUSES (target) = c;
15557 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
15558 OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c) = num_teams_upper;
15559 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) = num_teams_lower;
15560 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
15561 OMP_TARGET_CLAUSES (target) = c;
15564 /* Gimplify the gross structure of several OMP constructs. */
15566 static void
15567 gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
15569 tree expr = *expr_p;
15570 gimple *stmt;
15571 gimple_seq body = NULL;
15572 enum omp_region_type ort;
15574 switch (TREE_CODE (expr))
15576 case OMP_SECTIONS:
15577 case OMP_SINGLE:
15578 ort = ORT_WORKSHARE;
15579 break;
15580 case OMP_SCOPE:
15581 ort = ORT_TASKGROUP;
15582 break;
15583 case OMP_TARGET:
15584 ort = OMP_TARGET_COMBINED (expr) ? ORT_COMBINED_TARGET : ORT_TARGET;
15585 break;
15586 case OACC_KERNELS:
15587 ort = ORT_ACC_KERNELS;
15588 break;
15589 case OACC_PARALLEL:
15590 ort = ORT_ACC_PARALLEL;
15591 break;
15592 case OACC_SERIAL:
15593 ort = ORT_ACC_SERIAL;
15594 break;
15595 case OACC_DATA:
15596 ort = ORT_ACC_DATA;
15597 break;
15598 case OMP_TARGET_DATA:
15599 ort = ORT_TARGET_DATA;
15600 break;
15601 case OMP_TEAMS:
15602 ort = OMP_TEAMS_COMBINED (expr) ? ORT_COMBINED_TEAMS : ORT_TEAMS;
15603 if (gimplify_omp_ctxp == NULL
15604 || gimplify_omp_ctxp->region_type == ORT_IMPLICIT_TARGET)
15605 ort = (enum omp_region_type) (ort | ORT_HOST_TEAMS);
15606 break;
15607 case OACC_HOST_DATA:
15608 ort = ORT_ACC_HOST_DATA;
15609 break;
15610 default:
15611 gcc_unreachable ();
15614 bool save_in_omp_construct = in_omp_construct;
15615 if ((ort & ORT_ACC) == 0)
15616 in_omp_construct = false;
15617 gimplify_scan_omp_clauses (&OMP_CLAUSES (expr), pre_p, ort,
15618 TREE_CODE (expr));
15619 if (TREE_CODE (expr) == OMP_TARGET)
15620 optimize_target_teams (expr, pre_p);
15621 if ((ort & (ORT_TARGET | ORT_TARGET_DATA)) != 0
15622 || (ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
15624 push_gimplify_context ();
15625 gimple *g = gimplify_and_return_first (OMP_BODY (expr), &body);
15626 if (gimple_code (g) == GIMPLE_BIND)
15627 pop_gimplify_context (g);
15628 else
15629 pop_gimplify_context (NULL);
15630 if ((ort & ORT_TARGET_DATA) != 0)
15632 enum built_in_function end_ix;
15633 switch (TREE_CODE (expr))
15635 case OACC_DATA:
15636 case OACC_HOST_DATA:
15637 end_ix = BUILT_IN_GOACC_DATA_END;
15638 break;
15639 case OMP_TARGET_DATA:
15640 end_ix = BUILT_IN_GOMP_TARGET_END_DATA;
15641 break;
15642 default:
15643 gcc_unreachable ();
15645 tree fn = builtin_decl_explicit (end_ix);
15646 g = gimple_build_call (fn, 0);
15647 gimple_seq cleanup = NULL;
15648 gimple_seq_add_stmt (&cleanup, g);
15649 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
15650 body = NULL;
15651 gimple_seq_add_stmt (&body, g);
15654 else
15655 gimplify_and_add (OMP_BODY (expr), &body);
15656 gimplify_adjust_omp_clauses (pre_p, body, &OMP_CLAUSES (expr),
15657 TREE_CODE (expr));
15658 in_omp_construct = save_in_omp_construct;
15660 switch (TREE_CODE (expr))
15662 case OACC_DATA:
15663 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_DATA,
15664 OMP_CLAUSES (expr));
15665 break;
15666 case OACC_HOST_DATA:
15667 if (omp_find_clause (OMP_CLAUSES (expr), OMP_CLAUSE_IF_PRESENT))
15669 for (tree c = OMP_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
15670 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_PTR)
15671 OMP_CLAUSE_USE_DEVICE_PTR_IF_PRESENT (c) = 1;
15674 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_HOST_DATA,
15675 OMP_CLAUSES (expr));
15676 break;
15677 case OACC_KERNELS:
15678 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_KERNELS,
15679 OMP_CLAUSES (expr));
15680 break;
15681 case OACC_PARALLEL:
15682 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_PARALLEL,
15683 OMP_CLAUSES (expr));
15684 break;
15685 case OACC_SERIAL:
15686 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_SERIAL,
15687 OMP_CLAUSES (expr));
15688 break;
15689 case OMP_SECTIONS:
15690 stmt = gimple_build_omp_sections (body, OMP_CLAUSES (expr));
15691 break;
15692 case OMP_SINGLE:
15693 stmt = gimple_build_omp_single (body, OMP_CLAUSES (expr));
15694 break;
15695 case OMP_SCOPE:
15696 stmt = gimple_build_omp_scope (body, OMP_CLAUSES (expr));
15697 break;
15698 case OMP_TARGET:
15699 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_REGION,
15700 OMP_CLAUSES (expr));
15701 break;
15702 case OMP_TARGET_DATA:
15703 /* Put use_device_{ptr,addr} clauses last, as map clauses are supposed
15704 to be evaluated before the use_device_{ptr,addr} clauses if they
15705 refer to the same variables. */
15707 tree use_device_clauses;
15708 tree *pc, *uc = &use_device_clauses;
15709 for (pc = &OMP_CLAUSES (expr); *pc; )
15710 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
15711 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
15713 *uc = *pc;
15714 *pc = OMP_CLAUSE_CHAIN (*pc);
15715 uc = &OMP_CLAUSE_CHAIN (*uc);
15717 else
15718 pc = &OMP_CLAUSE_CHAIN (*pc);
15719 *uc = NULL_TREE;
15720 *pc = use_device_clauses;
15721 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_DATA,
15722 OMP_CLAUSES (expr));
15724 break;
15725 case OMP_TEAMS:
15726 stmt = gimple_build_omp_teams (body, OMP_CLAUSES (expr));
15727 if ((ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
15728 gimple_omp_teams_set_host (as_a <gomp_teams *> (stmt), true);
15729 break;
15730 default:
15731 gcc_unreachable ();
15734 gimplify_seq_add_stmt (pre_p, stmt);
15735 *expr_p = NULL_TREE;
15738 /* Gimplify the gross structure of OpenACC enter/exit data, update, and OpenMP
15739 target update constructs. */
15741 static void
15742 gimplify_omp_target_update (tree *expr_p, gimple_seq *pre_p)
15744 tree expr = *expr_p;
15745 int kind;
15746 gomp_target *stmt;
15747 enum omp_region_type ort = ORT_WORKSHARE;
15749 switch (TREE_CODE (expr))
15751 case OACC_ENTER_DATA:
15752 kind = GF_OMP_TARGET_KIND_OACC_ENTER_DATA;
15753 ort = ORT_ACC;
15754 break;
15755 case OACC_EXIT_DATA:
15756 kind = GF_OMP_TARGET_KIND_OACC_EXIT_DATA;
15757 ort = ORT_ACC;
15758 break;
15759 case OACC_UPDATE:
15760 kind = GF_OMP_TARGET_KIND_OACC_UPDATE;
15761 ort = ORT_ACC;
15762 break;
15763 case OMP_TARGET_UPDATE:
15764 kind = GF_OMP_TARGET_KIND_UPDATE;
15765 break;
15766 case OMP_TARGET_ENTER_DATA:
15767 kind = GF_OMP_TARGET_KIND_ENTER_DATA;
15768 break;
15769 case OMP_TARGET_EXIT_DATA:
15770 kind = GF_OMP_TARGET_KIND_EXIT_DATA;
15771 break;
15772 default:
15773 gcc_unreachable ();
15775 gimplify_scan_omp_clauses (&OMP_STANDALONE_CLAUSES (expr), pre_p,
15776 ort, TREE_CODE (expr));
15777 gimplify_adjust_omp_clauses (pre_p, NULL, &OMP_STANDALONE_CLAUSES (expr),
15778 TREE_CODE (expr));
15779 if (TREE_CODE (expr) == OACC_UPDATE
15780 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
15781 OMP_CLAUSE_IF_PRESENT))
15783 /* The runtime uses GOMP_MAP_{TO,FROM} to denote the if_present
15784 clause. */
15785 for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
15786 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
15787 switch (OMP_CLAUSE_MAP_KIND (c))
15789 case GOMP_MAP_FORCE_TO:
15790 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TO);
15791 break;
15792 case GOMP_MAP_FORCE_FROM:
15793 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FROM);
15794 break;
15795 default:
15796 break;
15799 else if (TREE_CODE (expr) == OACC_EXIT_DATA
15800 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
15801 OMP_CLAUSE_FINALIZE))
15803 /* Use GOMP_MAP_DELETE/GOMP_MAP_FORCE_FROM to denote "finalize"
15804 semantics. */
15805 bool have_clause = false;
15806 for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
15807 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
15808 switch (OMP_CLAUSE_MAP_KIND (c))
15810 case GOMP_MAP_FROM:
15811 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_FROM);
15812 have_clause = true;
15813 break;
15814 case GOMP_MAP_RELEASE:
15815 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_DELETE);
15816 have_clause = true;
15817 break;
15818 case GOMP_MAP_TO_PSET:
15819 /* Fortran arrays with descriptors must map that descriptor when
15820 doing standalone "attach" operations (in OpenACC). In that
15821 case GOMP_MAP_TO_PSET appears by itself with no preceding
15822 clause (see trans-openmp.cc:gfc_trans_omp_clauses). */
15823 break;
15824 case GOMP_MAP_POINTER:
15825 /* TODO PR92929: we may see these here, but they'll always follow
15826 one of the clauses above, and will be handled by libgomp as
15827 one group, so no handling required here. */
15828 gcc_assert (have_clause);
15829 break;
15830 case GOMP_MAP_DETACH:
15831 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_DETACH);
15832 have_clause = false;
15833 break;
15834 case GOMP_MAP_STRUCT:
15835 have_clause = false;
15836 break;
15837 default:
15838 gcc_unreachable ();
15841 stmt = gimple_build_omp_target (NULL, kind, OMP_STANDALONE_CLAUSES (expr));
15843 gimplify_seq_add_stmt (pre_p, stmt);
15844 *expr_p = NULL_TREE;
15847 /* A subroutine of gimplify_omp_atomic. The front end is supposed to have
15848 stabilized the lhs of the atomic operation as *ADDR. Return true if
15849 EXPR is this stabilized form. */
15851 static bool
15852 goa_lhs_expr_p (tree expr, tree addr)
15854 /* Also include casts to other type variants. The C front end is fond
15855 of adding these for e.g. volatile variables. This is like
15856 STRIP_TYPE_NOPS but includes the main variant lookup. */
15857 STRIP_USELESS_TYPE_CONVERSION (expr);
15859 if (INDIRECT_REF_P (expr))
15861 expr = TREE_OPERAND (expr, 0);
15862 while (expr != addr
15863 && (CONVERT_EXPR_P (expr)
15864 || TREE_CODE (expr) == NON_LVALUE_EXPR)
15865 && TREE_CODE (expr) == TREE_CODE (addr)
15866 && types_compatible_p (TREE_TYPE (expr), TREE_TYPE (addr)))
15868 expr = TREE_OPERAND (expr, 0);
15869 addr = TREE_OPERAND (addr, 0);
15871 if (expr == addr)
15872 return true;
15873 return (TREE_CODE (addr) == ADDR_EXPR
15874 && TREE_CODE (expr) == ADDR_EXPR
15875 && TREE_OPERAND (addr, 0) == TREE_OPERAND (expr, 0));
15877 if (TREE_CODE (addr) == ADDR_EXPR && expr == TREE_OPERAND (addr, 0))
15878 return true;
15879 return false;
15882 /* Walk *EXPR_P and replace appearances of *LHS_ADDR with LHS_VAR. If an
15883 expression does not involve the lhs, evaluate it into a temporary.
15884 Return 1 if the lhs appeared as a subexpression, 0 if it did not,
15885 or -1 if an error was encountered. */
15887 static int
15888 goa_stabilize_expr (tree *expr_p, gimple_seq *pre_p, tree lhs_addr,
15889 tree lhs_var, tree &target_expr, bool rhs, int depth)
15891 tree expr = *expr_p;
15892 int saw_lhs = 0;
15894 if (goa_lhs_expr_p (expr, lhs_addr))
15896 if (pre_p)
15897 *expr_p = lhs_var;
15898 return 1;
15900 if (is_gimple_val (expr))
15901 return 0;
15903 /* Maximum depth of lhs in expression is for the
15904 __builtin_clear_padding (...), __builtin_clear_padding (...),
15905 __builtin_memcmp (&TARGET_EXPR <lhs, >, ...) == 0 ? ... : lhs; */
15906 if (++depth > 7)
15907 goto finish;
15909 switch (TREE_CODE_CLASS (TREE_CODE (expr)))
15911 case tcc_binary:
15912 case tcc_comparison:
15913 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p, lhs_addr,
15914 lhs_var, target_expr, true, depth);
15915 /* FALLTHRU */
15916 case tcc_unary:
15917 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p, lhs_addr,
15918 lhs_var, target_expr, true, depth);
15919 break;
15920 case tcc_expression:
15921 switch (TREE_CODE (expr))
15923 case TRUTH_ANDIF_EXPR:
15924 case TRUTH_ORIF_EXPR:
15925 case TRUTH_AND_EXPR:
15926 case TRUTH_OR_EXPR:
15927 case TRUTH_XOR_EXPR:
15928 case BIT_INSERT_EXPR:
15929 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
15930 lhs_addr, lhs_var, target_expr, true,
15931 depth);
15932 /* FALLTHRU */
15933 case TRUTH_NOT_EXPR:
15934 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
15935 lhs_addr, lhs_var, target_expr, true,
15936 depth);
15937 break;
15938 case MODIFY_EXPR:
15939 if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr, lhs_var,
15940 target_expr, true, depth))
15941 break;
15942 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
15943 lhs_addr, lhs_var, target_expr, true,
15944 depth);
15945 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
15946 lhs_addr, lhs_var, target_expr, false,
15947 depth);
15948 break;
15949 /* FALLTHRU */
15950 case ADDR_EXPR:
15951 if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr, lhs_var,
15952 target_expr, true, depth))
15953 break;
15954 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
15955 lhs_addr, lhs_var, target_expr, false,
15956 depth);
15957 break;
15958 case COMPOUND_EXPR:
15959 /* Break out any preevaluations from cp_build_modify_expr. */
15960 for (; TREE_CODE (expr) == COMPOUND_EXPR;
15961 expr = TREE_OPERAND (expr, 1))
15963 /* Special-case __builtin_clear_padding call before
15964 __builtin_memcmp. */
15965 if (TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR)
15967 tree fndecl = get_callee_fndecl (TREE_OPERAND (expr, 0));
15968 if (fndecl
15969 && fndecl_built_in_p (fndecl, BUILT_IN_CLEAR_PADDING)
15970 && VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 0)))
15971 && (!pre_p
15972 || goa_stabilize_expr (&TREE_OPERAND (expr, 0), NULL,
15973 lhs_addr, lhs_var,
15974 target_expr, true, depth)))
15976 if (pre_p)
15977 *expr_p = expr;
15978 saw_lhs = goa_stabilize_expr (&TREE_OPERAND (expr, 0),
15979 pre_p, lhs_addr, lhs_var,
15980 target_expr, true, depth);
15981 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1),
15982 pre_p, lhs_addr, lhs_var,
15983 target_expr, rhs, depth);
15984 return saw_lhs;
15988 if (pre_p)
15989 gimplify_stmt (&TREE_OPERAND (expr, 0), pre_p);
15991 if (!pre_p)
15992 return goa_stabilize_expr (&expr, pre_p, lhs_addr, lhs_var,
15993 target_expr, rhs, depth);
15994 *expr_p = expr;
15995 return goa_stabilize_expr (expr_p, pre_p, lhs_addr, lhs_var,
15996 target_expr, rhs, depth);
15997 case COND_EXPR:
15998 if (!goa_stabilize_expr (&TREE_OPERAND (expr, 0), NULL, lhs_addr,
15999 lhs_var, target_expr, true, depth))
16000 break;
16001 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
16002 lhs_addr, lhs_var, target_expr, true,
16003 depth);
16004 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
16005 lhs_addr, lhs_var, target_expr, true,
16006 depth);
16007 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 2), pre_p,
16008 lhs_addr, lhs_var, target_expr, true,
16009 depth);
16010 break;
16011 case TARGET_EXPR:
16012 if (TARGET_EXPR_INITIAL (expr))
16014 if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr,
16015 lhs_var, target_expr, true,
16016 depth))
16017 break;
16018 if (expr == target_expr)
16019 saw_lhs = 1;
16020 else
16022 saw_lhs = goa_stabilize_expr (&TARGET_EXPR_INITIAL (expr),
16023 pre_p, lhs_addr, lhs_var,
16024 target_expr, true, depth);
16025 if (saw_lhs && target_expr == NULL_TREE && pre_p)
16026 target_expr = expr;
16029 break;
16030 default:
16031 break;
16033 break;
16034 case tcc_reference:
16035 if (TREE_CODE (expr) == BIT_FIELD_REF
16036 || TREE_CODE (expr) == VIEW_CONVERT_EXPR)
16037 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
16038 lhs_addr, lhs_var, target_expr, true,
16039 depth);
16040 break;
16041 case tcc_vl_exp:
16042 if (TREE_CODE (expr) == CALL_EXPR)
16044 if (tree fndecl = get_callee_fndecl (expr))
16045 if (fndecl_built_in_p (fndecl, BUILT_IN_CLEAR_PADDING,
16046 BUILT_IN_MEMCMP))
16048 int nargs = call_expr_nargs (expr);
16049 for (int i = 0; i < nargs; i++)
16050 saw_lhs |= goa_stabilize_expr (&CALL_EXPR_ARG (expr, i),
16051 pre_p, lhs_addr, lhs_var,
16052 target_expr, true, depth);
16055 break;
16056 default:
16057 break;
16060 finish:
16061 if (saw_lhs == 0 && pre_p)
16063 enum gimplify_status gs;
16064 if (TREE_CODE (expr) == CALL_EXPR && VOID_TYPE_P (TREE_TYPE (expr)))
16066 gimplify_stmt (&expr, pre_p);
16067 return saw_lhs;
16069 else if (rhs)
16070 gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_val, fb_rvalue);
16071 else
16072 gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_lvalue, fb_lvalue);
16073 if (gs != GS_ALL_DONE)
16074 saw_lhs = -1;
16077 return saw_lhs;
16080 /* Gimplify an OMP_ATOMIC statement. */
16082 static enum gimplify_status
16083 gimplify_omp_atomic (tree *expr_p, gimple_seq *pre_p)
16085 tree addr = TREE_OPERAND (*expr_p, 0);
16086 tree rhs = TREE_CODE (*expr_p) == OMP_ATOMIC_READ
16087 ? NULL : TREE_OPERAND (*expr_p, 1);
16088 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
16089 tree tmp_load;
16090 gomp_atomic_load *loadstmt;
16091 gomp_atomic_store *storestmt;
16092 tree target_expr = NULL_TREE;
16094 tmp_load = create_tmp_reg (type);
16095 if (rhs
16096 && goa_stabilize_expr (&rhs, pre_p, addr, tmp_load, target_expr,
16097 true, 0) < 0)
16098 return GS_ERROR;
16100 if (gimplify_expr (&addr, pre_p, NULL, is_gimple_val, fb_rvalue)
16101 != GS_ALL_DONE)
16102 return GS_ERROR;
16104 loadstmt = gimple_build_omp_atomic_load (tmp_load, addr,
16105 OMP_ATOMIC_MEMORY_ORDER (*expr_p));
16106 gimplify_seq_add_stmt (pre_p, loadstmt);
16107 if (rhs)
16109 /* BIT_INSERT_EXPR is not valid for non-integral bitfield
16110 representatives. Use BIT_FIELD_REF on the lhs instead. */
16111 tree rhsarg = rhs;
16112 if (TREE_CODE (rhs) == COND_EXPR)
16113 rhsarg = TREE_OPERAND (rhs, 1);
16114 if (TREE_CODE (rhsarg) == BIT_INSERT_EXPR
16115 && !INTEGRAL_TYPE_P (TREE_TYPE (tmp_load)))
16117 tree bitpos = TREE_OPERAND (rhsarg, 2);
16118 tree op1 = TREE_OPERAND (rhsarg, 1);
16119 tree bitsize;
16120 tree tmp_store = tmp_load;
16121 if (TREE_CODE (*expr_p) == OMP_ATOMIC_CAPTURE_OLD)
16122 tmp_store = get_initialized_tmp_var (tmp_load, pre_p);
16123 if (INTEGRAL_TYPE_P (TREE_TYPE (op1)))
16124 bitsize = bitsize_int (TYPE_PRECISION (TREE_TYPE (op1)));
16125 else
16126 bitsize = TYPE_SIZE (TREE_TYPE (op1));
16127 gcc_assert (TREE_OPERAND (rhsarg, 0) == tmp_load);
16128 tree t = build2_loc (EXPR_LOCATION (rhsarg),
16129 MODIFY_EXPR, void_type_node,
16130 build3_loc (EXPR_LOCATION (rhsarg),
16131 BIT_FIELD_REF, TREE_TYPE (op1),
16132 tmp_store, bitsize, bitpos), op1);
16133 if (TREE_CODE (rhs) == COND_EXPR)
16134 t = build3_loc (EXPR_LOCATION (rhs), COND_EXPR, void_type_node,
16135 TREE_OPERAND (rhs, 0), t, void_node);
16136 gimplify_and_add (t, pre_p);
16137 rhs = tmp_store;
16139 bool save_allow_rhs_cond_expr = gimplify_ctxp->allow_rhs_cond_expr;
16140 if (TREE_CODE (rhs) == COND_EXPR)
16141 gimplify_ctxp->allow_rhs_cond_expr = true;
16142 enum gimplify_status gs = gimplify_expr (&rhs, pre_p, NULL,
16143 is_gimple_val, fb_rvalue);
16144 gimplify_ctxp->allow_rhs_cond_expr = save_allow_rhs_cond_expr;
16145 if (gs != GS_ALL_DONE)
16146 return GS_ERROR;
16149 if (TREE_CODE (*expr_p) == OMP_ATOMIC_READ)
16150 rhs = tmp_load;
16151 storestmt
16152 = gimple_build_omp_atomic_store (rhs, OMP_ATOMIC_MEMORY_ORDER (*expr_p));
16153 if (TREE_CODE (*expr_p) != OMP_ATOMIC_READ && OMP_ATOMIC_WEAK (*expr_p))
16155 gimple_omp_atomic_set_weak (loadstmt);
16156 gimple_omp_atomic_set_weak (storestmt);
16158 gimplify_seq_add_stmt (pre_p, storestmt);
16159 switch (TREE_CODE (*expr_p))
16161 case OMP_ATOMIC_READ:
16162 case OMP_ATOMIC_CAPTURE_OLD:
16163 *expr_p = tmp_load;
16164 gimple_omp_atomic_set_need_value (loadstmt);
16165 break;
16166 case OMP_ATOMIC_CAPTURE_NEW:
16167 *expr_p = rhs;
16168 gimple_omp_atomic_set_need_value (storestmt);
16169 break;
16170 default:
16171 *expr_p = NULL;
16172 break;
16175 return GS_ALL_DONE;
16178 /* Gimplify a TRANSACTION_EXPR. This involves gimplification of the
16179 body, and adding some EH bits. */
16181 static enum gimplify_status
16182 gimplify_transaction (tree *expr_p, gimple_seq *pre_p)
16184 tree expr = *expr_p, temp, tbody = TRANSACTION_EXPR_BODY (expr);
16185 gimple *body_stmt;
16186 gtransaction *trans_stmt;
16187 gimple_seq body = NULL;
16188 int subcode = 0;
16190 /* Wrap the transaction body in a BIND_EXPR so we have a context
16191 where to put decls for OMP. */
16192 if (TREE_CODE (tbody) != BIND_EXPR)
16194 tree bind = build3 (BIND_EXPR, void_type_node, NULL, tbody, NULL);
16195 TREE_SIDE_EFFECTS (bind) = 1;
16196 SET_EXPR_LOCATION (bind, EXPR_LOCATION (tbody));
16197 TRANSACTION_EXPR_BODY (expr) = bind;
16200 push_gimplify_context ();
16201 temp = voidify_wrapper_expr (*expr_p, NULL);
16203 body_stmt = gimplify_and_return_first (TRANSACTION_EXPR_BODY (expr), &body);
16204 pop_gimplify_context (body_stmt);
16206 trans_stmt = gimple_build_transaction (body);
16207 if (TRANSACTION_EXPR_OUTER (expr))
16208 subcode = GTMA_IS_OUTER;
16209 else if (TRANSACTION_EXPR_RELAXED (expr))
16210 subcode = GTMA_IS_RELAXED;
16211 gimple_transaction_set_subcode (trans_stmt, subcode);
16213 gimplify_seq_add_stmt (pre_p, trans_stmt);
16215 if (temp)
16217 *expr_p = temp;
16218 return GS_OK;
16221 *expr_p = NULL_TREE;
16222 return GS_ALL_DONE;
16225 /* Gimplify an OMP_ORDERED construct. EXPR is the tree version. BODY
16226 is the OMP_BODY of the original EXPR (which has already been
16227 gimplified so it's not present in the EXPR).
16229 Return the gimplified GIMPLE_OMP_ORDERED tuple. */
16231 static gimple *
16232 gimplify_omp_ordered (tree expr, gimple_seq body)
16234 tree c, decls;
16235 int failures = 0;
16236 unsigned int i;
16237 tree source_c = NULL_TREE;
16238 tree sink_c = NULL_TREE;
16240 if (gimplify_omp_ctxp)
16242 for (c = OMP_ORDERED_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
16243 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DOACROSS
16244 && gimplify_omp_ctxp->loop_iter_var.is_empty ())
16246 error_at (OMP_CLAUSE_LOCATION (c),
16247 "%<ordered%> construct with %qs clause must be "
16248 "closely nested inside a loop with %<ordered%> clause",
16249 OMP_CLAUSE_DOACROSS_DEPEND (c) ? "depend" : "doacross");
16250 failures++;
16252 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DOACROSS
16253 && OMP_CLAUSE_DOACROSS_KIND (c) == OMP_CLAUSE_DOACROSS_SINK)
16255 bool fail = false;
16256 sink_c = c;
16257 if (OMP_CLAUSE_DECL (c) == NULL_TREE)
16258 continue; /* omp_cur_iteration - 1 */
16259 for (decls = OMP_CLAUSE_DECL (c), i = 0;
16260 decls && TREE_CODE (decls) == TREE_LIST;
16261 decls = TREE_CHAIN (decls), ++i)
16262 if (i >= gimplify_omp_ctxp->loop_iter_var.length () / 2)
16263 continue;
16264 else if (TREE_VALUE (decls)
16265 != gimplify_omp_ctxp->loop_iter_var[2 * i])
16267 error_at (OMP_CLAUSE_LOCATION (c),
16268 "variable %qE is not an iteration "
16269 "of outermost loop %d, expected %qE",
16270 TREE_VALUE (decls), i + 1,
16271 gimplify_omp_ctxp->loop_iter_var[2 * i]);
16272 fail = true;
16273 failures++;
16275 else
16276 TREE_VALUE (decls)
16277 = gimplify_omp_ctxp->loop_iter_var[2 * i + 1];
16278 if (!fail && i != gimplify_omp_ctxp->loop_iter_var.length () / 2)
16280 error_at (OMP_CLAUSE_LOCATION (c),
16281 "number of variables in %qs clause with "
16282 "%<sink%> modifier does not match number of "
16283 "iteration variables",
16284 OMP_CLAUSE_DOACROSS_DEPEND (c)
16285 ? "depend" : "doacross");
16286 failures++;
16289 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DOACROSS
16290 && OMP_CLAUSE_DOACROSS_KIND (c) == OMP_CLAUSE_DOACROSS_SOURCE)
16292 if (source_c)
16294 error_at (OMP_CLAUSE_LOCATION (c),
16295 "more than one %qs clause with %<source%> "
16296 "modifier on an %<ordered%> construct",
16297 OMP_CLAUSE_DOACROSS_DEPEND (source_c)
16298 ? "depend" : "doacross");
16299 failures++;
16301 else
16302 source_c = c;
16305 if (source_c && sink_c)
16307 error_at (OMP_CLAUSE_LOCATION (source_c),
16308 "%qs clause with %<source%> modifier specified "
16309 "together with %qs clauses with %<sink%> modifier "
16310 "on the same construct",
16311 OMP_CLAUSE_DOACROSS_DEPEND (source_c) ? "depend" : "doacross",
16312 OMP_CLAUSE_DOACROSS_DEPEND (sink_c) ? "depend" : "doacross");
16313 failures++;
16316 if (failures)
16317 return gimple_build_nop ();
16318 return gimple_build_omp_ordered (body, OMP_ORDERED_CLAUSES (expr));
16321 /* Convert the GENERIC expression tree *EXPR_P to GIMPLE. If the
16322 expression produces a value to be used as an operand inside a GIMPLE
16323 statement, the value will be stored back in *EXPR_P. This value will
16324 be a tree of class tcc_declaration, tcc_constant, tcc_reference or
16325 an SSA_NAME. The corresponding sequence of GIMPLE statements is
16326 emitted in PRE_P and POST_P.
16328 Additionally, this process may overwrite parts of the input
16329 expression during gimplification. Ideally, it should be
16330 possible to do non-destructive gimplification.
16332 EXPR_P points to the GENERIC expression to convert to GIMPLE. If
16333 the expression needs to evaluate to a value to be used as
16334 an operand in a GIMPLE statement, this value will be stored in
16335 *EXPR_P on exit. This happens when the caller specifies one
16336 of fb_lvalue or fb_rvalue fallback flags.
16338 PRE_P will contain the sequence of GIMPLE statements corresponding
16339 to the evaluation of EXPR and all the side-effects that must
16340 be executed before the main expression. On exit, the last
16341 statement of PRE_P is the core statement being gimplified. For
16342 instance, when gimplifying 'if (++a)' the last statement in
16343 PRE_P will be 'if (t.1)' where t.1 is the result of
16344 pre-incrementing 'a'.
16346 POST_P will contain the sequence of GIMPLE statements corresponding
16347 to the evaluation of all the side-effects that must be executed
16348 after the main expression. If this is NULL, the post
16349 side-effects are stored at the end of PRE_P.
16351 The reason why the output is split in two is to handle post
16352 side-effects explicitly. In some cases, an expression may have
16353 inner and outer post side-effects which need to be emitted in
16354 an order different from the one given by the recursive
16355 traversal. For instance, for the expression (*p--)++ the post
16356 side-effects of '--' must actually occur *after* the post
16357 side-effects of '++'. However, gimplification will first visit
16358 the inner expression, so if a separate POST sequence was not
16359 used, the resulting sequence would be:
16361 1 t.1 = *p
16362 2 p = p - 1
16363 3 t.2 = t.1 + 1
16364 4 *p = t.2
16366 However, the post-decrement operation in line #2 must not be
16367 evaluated until after the store to *p at line #4, so the
16368 correct sequence should be:
16370 1 t.1 = *p
16371 2 t.2 = t.1 + 1
16372 3 *p = t.2
16373 4 p = p - 1
16375 So, by specifying a separate post queue, it is possible
16376 to emit the post side-effects in the correct order.
16377 If POST_P is NULL, an internal queue will be used. Before
16378 returning to the caller, the sequence POST_P is appended to
16379 the main output sequence PRE_P.
16381 GIMPLE_TEST_F points to a function that takes a tree T and
16382 returns nonzero if T is in the GIMPLE form requested by the
16383 caller. The GIMPLE predicates are in gimple.cc.
16385 FALLBACK tells the function what sort of a temporary we want if
16386 gimplification cannot produce an expression that complies with
16387 GIMPLE_TEST_F.
16389 fb_none means that no temporary should be generated
16390 fb_rvalue means that an rvalue is OK to generate
16391 fb_lvalue means that an lvalue is OK to generate
16392 fb_either means that either is OK, but an lvalue is preferable.
16393 fb_mayfail means that gimplification may fail (in which case
16394 GS_ERROR will be returned)
16396 The return value is either GS_ERROR or GS_ALL_DONE, since this
16397 function iterates until EXPR is completely gimplified or an error
16398 occurs. */
16400 enum gimplify_status
16401 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
16402 bool (*gimple_test_f) (tree), fallback_t fallback)
16404 tree tmp;
16405 gimple_seq internal_pre = NULL;
16406 gimple_seq internal_post = NULL;
16407 tree save_expr;
16408 bool is_statement;
16409 location_t saved_location;
16410 enum gimplify_status ret;
16411 gimple_stmt_iterator pre_last_gsi, post_last_gsi;
16412 tree label;
16414 save_expr = *expr_p;
16415 if (save_expr == NULL_TREE)
16416 return GS_ALL_DONE;
16418 /* If we are gimplifying a top-level statement, PRE_P must be valid. */
16419 is_statement = gimple_test_f == is_gimple_stmt;
16420 if (is_statement)
16421 gcc_assert (pre_p);
16423 /* Consistency checks. */
16424 if (gimple_test_f == is_gimple_reg)
16425 gcc_assert (fallback & (fb_rvalue | fb_lvalue));
16426 else if (gimple_test_f == is_gimple_val
16427 || gimple_test_f == is_gimple_call_addr
16428 || gimple_test_f == is_gimple_condexpr_for_cond
16429 || gimple_test_f == is_gimple_mem_rhs
16430 || gimple_test_f == is_gimple_mem_rhs_or_call
16431 || gimple_test_f == is_gimple_reg_rhs
16432 || gimple_test_f == is_gimple_reg_rhs_or_call
16433 || gimple_test_f == is_gimple_asm_val
16434 || gimple_test_f == is_gimple_mem_ref_addr)
16435 gcc_assert (fallback & fb_rvalue);
16436 else if (gimple_test_f == is_gimple_min_lval
16437 || gimple_test_f == is_gimple_lvalue)
16438 gcc_assert (fallback & fb_lvalue);
16439 else if (gimple_test_f == is_gimple_addressable)
16440 gcc_assert (fallback & fb_either);
16441 else if (gimple_test_f == is_gimple_stmt)
16442 gcc_assert (fallback == fb_none);
16443 else
16445 /* We should have recognized the GIMPLE_TEST_F predicate to
16446 know what kind of fallback to use in case a temporary is
16447 needed to hold the value or address of *EXPR_P. */
16448 gcc_unreachable ();
16451 /* We used to check the predicate here and return immediately if it
16452 succeeds. This is wrong; the design is for gimplification to be
16453 idempotent, and for the predicates to only test for valid forms, not
16454 whether they are fully simplified. */
16455 if (pre_p == NULL)
16456 pre_p = &internal_pre;
16458 if (post_p == NULL)
16459 post_p = &internal_post;
16461 /* Remember the last statements added to PRE_P and POST_P. Every
16462 new statement added by the gimplification helpers needs to be
16463 annotated with location information. To centralize the
16464 responsibility, we remember the last statement that had been
16465 added to both queues before gimplifying *EXPR_P. If
16466 gimplification produces new statements in PRE_P and POST_P, those
16467 statements will be annotated with the same location information
16468 as *EXPR_P. */
16469 pre_last_gsi = gsi_last (*pre_p);
16470 post_last_gsi = gsi_last (*post_p);
16472 saved_location = input_location;
16473 if (save_expr != error_mark_node
16474 && EXPR_HAS_LOCATION (*expr_p))
16475 input_location = EXPR_LOCATION (*expr_p);
16477 /* Loop over the specific gimplifiers until the toplevel node
16478 remains the same. */
16481 /* Strip away as many useless type conversions as possible
16482 at the toplevel. */
16483 STRIP_USELESS_TYPE_CONVERSION (*expr_p);
16485 /* Remember the expr. */
16486 save_expr = *expr_p;
16488 /* Die, die, die, my darling. */
16489 if (error_operand_p (save_expr))
16491 ret = GS_ERROR;
16492 break;
16495 /* Do any language-specific gimplification. */
16496 ret = ((enum gimplify_status)
16497 lang_hooks.gimplify_expr (expr_p, pre_p, post_p));
16498 if (ret == GS_OK)
16500 if (*expr_p == NULL_TREE)
16501 break;
16502 if (*expr_p != save_expr)
16503 continue;
16505 else if (ret != GS_UNHANDLED)
16506 break;
16508 /* Make sure that all the cases set 'ret' appropriately. */
16509 ret = GS_UNHANDLED;
16510 switch (TREE_CODE (*expr_p))
16512 /* First deal with the special cases. */
16514 case POSTINCREMENT_EXPR:
16515 case POSTDECREMENT_EXPR:
16516 case PREINCREMENT_EXPR:
16517 case PREDECREMENT_EXPR:
16518 ret = gimplify_self_mod_expr (expr_p, pre_p, post_p,
16519 fallback != fb_none,
16520 TREE_TYPE (*expr_p));
16521 break;
16523 case VIEW_CONVERT_EXPR:
16524 if ((fallback & fb_rvalue)
16525 && is_gimple_reg_type (TREE_TYPE (*expr_p))
16526 && is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0))))
16528 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
16529 post_p, is_gimple_val, fb_rvalue);
16530 recalculate_side_effects (*expr_p);
16531 break;
16533 /* Fallthru. */
16535 case ARRAY_REF:
16536 case ARRAY_RANGE_REF:
16537 case REALPART_EXPR:
16538 case IMAGPART_EXPR:
16539 case COMPONENT_REF:
16540 ret = gimplify_compound_lval (expr_p, pre_p, post_p,
16541 fallback ? fallback : fb_rvalue);
16542 break;
16544 case COND_EXPR:
16545 ret = gimplify_cond_expr (expr_p, pre_p, fallback);
16547 /* C99 code may assign to an array in a structure value of a
16548 conditional expression, and this has undefined behavior
16549 only on execution, so create a temporary if an lvalue is
16550 required. */
16551 if (fallback == fb_lvalue)
16553 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
16554 mark_addressable (*expr_p);
16555 ret = GS_OK;
16557 break;
16559 case CALL_EXPR:
16560 ret = gimplify_call_expr (expr_p, pre_p, fallback != fb_none);
16562 /* C99 code may assign to an array in a structure returned
16563 from a function, and this has undefined behavior only on
16564 execution, so create a temporary if an lvalue is
16565 required. */
16566 if (fallback == fb_lvalue)
16568 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
16569 mark_addressable (*expr_p);
16570 ret = GS_OK;
16572 break;
16574 case TREE_LIST:
16575 gcc_unreachable ();
16577 case COMPOUND_EXPR:
16578 ret = gimplify_compound_expr (expr_p, pre_p, fallback != fb_none);
16579 break;
16581 case COMPOUND_LITERAL_EXPR:
16582 ret = gimplify_compound_literal_expr (expr_p, pre_p,
16583 gimple_test_f, fallback);
16584 break;
16586 case MODIFY_EXPR:
16587 case INIT_EXPR:
16588 ret = gimplify_modify_expr (expr_p, pre_p, post_p,
16589 fallback != fb_none);
16590 break;
16592 case TRUTH_ANDIF_EXPR:
16593 case TRUTH_ORIF_EXPR:
16595 /* Preserve the original type of the expression and the
16596 source location of the outer expression. */
16597 tree org_type = TREE_TYPE (*expr_p);
16598 *expr_p = gimple_boolify (*expr_p);
16599 *expr_p = build3_loc (input_location, COND_EXPR,
16600 org_type, *expr_p,
16601 fold_convert_loc
16602 (input_location,
16603 org_type, boolean_true_node),
16604 fold_convert_loc
16605 (input_location,
16606 org_type, boolean_false_node));
16607 ret = GS_OK;
16608 break;
16611 case TRUTH_NOT_EXPR:
16613 tree type = TREE_TYPE (*expr_p);
16614 /* The parsers are careful to generate TRUTH_NOT_EXPR
16615 only with operands that are always zero or one.
16616 We do not fold here but handle the only interesting case
16617 manually, as fold may re-introduce the TRUTH_NOT_EXPR. */
16618 *expr_p = gimple_boolify (*expr_p);
16619 if (TYPE_PRECISION (TREE_TYPE (*expr_p)) == 1)
16620 *expr_p = build1_loc (input_location, BIT_NOT_EXPR,
16621 TREE_TYPE (*expr_p),
16622 TREE_OPERAND (*expr_p, 0));
16623 else
16624 *expr_p = build2_loc (input_location, BIT_XOR_EXPR,
16625 TREE_TYPE (*expr_p),
16626 TREE_OPERAND (*expr_p, 0),
16627 build_int_cst (TREE_TYPE (*expr_p), 1));
16628 if (!useless_type_conversion_p (type, TREE_TYPE (*expr_p)))
16629 *expr_p = fold_convert_loc (input_location, type, *expr_p);
16630 ret = GS_OK;
16631 break;
16634 case ADDR_EXPR:
16635 ret = gimplify_addr_expr (expr_p, pre_p, post_p);
16636 break;
16638 case ANNOTATE_EXPR:
16640 tree cond = TREE_OPERAND (*expr_p, 0);
16641 tree kind = TREE_OPERAND (*expr_p, 1);
16642 tree data = TREE_OPERAND (*expr_p, 2);
16643 tree type = TREE_TYPE (cond);
16644 if (!INTEGRAL_TYPE_P (type))
16646 *expr_p = cond;
16647 ret = GS_OK;
16648 break;
16650 tree tmp = create_tmp_var (type);
16651 gimplify_arg (&cond, pre_p, EXPR_LOCATION (*expr_p));
16652 gcall *call
16653 = gimple_build_call_internal (IFN_ANNOTATE, 3, cond, kind, data);
16654 gimple_call_set_lhs (call, tmp);
16655 gimplify_seq_add_stmt (pre_p, call);
16656 *expr_p = tmp;
16657 ret = GS_ALL_DONE;
16658 break;
16661 case VA_ARG_EXPR:
16662 ret = gimplify_va_arg_expr (expr_p, pre_p, post_p);
16663 break;
16665 CASE_CONVERT:
16666 if (IS_EMPTY_STMT (*expr_p))
16668 ret = GS_ALL_DONE;
16669 break;
16672 if (VOID_TYPE_P (TREE_TYPE (*expr_p))
16673 || fallback == fb_none)
16675 /* Just strip a conversion to void (or in void context) and
16676 try again. */
16677 *expr_p = TREE_OPERAND (*expr_p, 0);
16678 ret = GS_OK;
16679 break;
16682 ret = gimplify_conversion (expr_p);
16683 if (ret == GS_ERROR)
16684 break;
16685 if (*expr_p != save_expr)
16686 break;
16687 /* FALLTHRU */
16689 case FIX_TRUNC_EXPR:
16690 /* unary_expr: ... | '(' cast ')' val | ... */
16691 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
16692 is_gimple_val, fb_rvalue);
16693 recalculate_side_effects (*expr_p);
16694 break;
16696 case INDIRECT_REF:
16698 bool volatilep = TREE_THIS_VOLATILE (*expr_p);
16699 bool notrap = TREE_THIS_NOTRAP (*expr_p);
16700 tree saved_ptr_type = TREE_TYPE (TREE_OPERAND (*expr_p, 0));
16702 *expr_p = fold_indirect_ref_loc (input_location, *expr_p);
16703 if (*expr_p != save_expr)
16705 ret = GS_OK;
16706 break;
16709 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
16710 is_gimple_reg, fb_rvalue);
16711 if (ret == GS_ERROR)
16712 break;
16714 recalculate_side_effects (*expr_p);
16715 *expr_p = fold_build2_loc (input_location, MEM_REF,
16716 TREE_TYPE (*expr_p),
16717 TREE_OPERAND (*expr_p, 0),
16718 build_int_cst (saved_ptr_type, 0));
16719 TREE_THIS_VOLATILE (*expr_p) = volatilep;
16720 TREE_THIS_NOTRAP (*expr_p) = notrap;
16721 ret = GS_OK;
16722 break;
16725 /* We arrive here through the various re-gimplifcation paths. */
16726 case MEM_REF:
16727 /* First try re-folding the whole thing. */
16728 tmp = fold_binary (MEM_REF, TREE_TYPE (*expr_p),
16729 TREE_OPERAND (*expr_p, 0),
16730 TREE_OPERAND (*expr_p, 1));
16731 if (tmp)
16733 REF_REVERSE_STORAGE_ORDER (tmp)
16734 = REF_REVERSE_STORAGE_ORDER (*expr_p);
16735 *expr_p = tmp;
16736 recalculate_side_effects (*expr_p);
16737 ret = GS_OK;
16738 break;
16740 /* Avoid re-gimplifying the address operand if it is already
16741 in suitable form. Re-gimplifying would mark the address
16742 operand addressable. Always gimplify when not in SSA form
16743 as we still may have to gimplify decls with value-exprs. */
16744 if (!gimplify_ctxp || !gimple_in_ssa_p (cfun)
16745 || !is_gimple_mem_ref_addr (TREE_OPERAND (*expr_p, 0)))
16747 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
16748 is_gimple_mem_ref_addr, fb_rvalue);
16749 if (ret == GS_ERROR)
16750 break;
16752 recalculate_side_effects (*expr_p);
16753 ret = GS_ALL_DONE;
16754 break;
16756 /* Constants need not be gimplified. */
16757 case INTEGER_CST:
16758 case REAL_CST:
16759 case FIXED_CST:
16760 case STRING_CST:
16761 case COMPLEX_CST:
16762 case VECTOR_CST:
16763 /* Drop the overflow flag on constants, we do not want
16764 that in the GIMPLE IL. */
16765 if (TREE_OVERFLOW_P (*expr_p))
16766 *expr_p = drop_tree_overflow (*expr_p);
16767 ret = GS_ALL_DONE;
16768 break;
16770 case CONST_DECL:
16771 /* If we require an lvalue, such as for ADDR_EXPR, retain the
16772 CONST_DECL node. Otherwise the decl is replaceable by its
16773 value. */
16774 /* ??? Should be == fb_lvalue, but ADDR_EXPR passes fb_either. */
16775 if (fallback & fb_lvalue)
16776 ret = GS_ALL_DONE;
16777 else
16779 *expr_p = DECL_INITIAL (*expr_p);
16780 ret = GS_OK;
16782 break;
16784 case DECL_EXPR:
16785 ret = gimplify_decl_expr (expr_p, pre_p);
16786 break;
16788 case BIND_EXPR:
16789 ret = gimplify_bind_expr (expr_p, pre_p);
16790 break;
16792 case LOOP_EXPR:
16793 ret = gimplify_loop_expr (expr_p, pre_p);
16794 break;
16796 case SWITCH_EXPR:
16797 ret = gimplify_switch_expr (expr_p, pre_p);
16798 break;
16800 case EXIT_EXPR:
16801 ret = gimplify_exit_expr (expr_p);
16802 break;
16804 case GOTO_EXPR:
16805 /* If the target is not LABEL, then it is a computed jump
16806 and the target needs to be gimplified. */
16807 if (TREE_CODE (GOTO_DESTINATION (*expr_p)) != LABEL_DECL)
16809 ret = gimplify_expr (&GOTO_DESTINATION (*expr_p), pre_p,
16810 NULL, is_gimple_val, fb_rvalue);
16811 if (ret == GS_ERROR)
16812 break;
16814 gimplify_seq_add_stmt (pre_p,
16815 gimple_build_goto (GOTO_DESTINATION (*expr_p)));
16816 ret = GS_ALL_DONE;
16817 break;
16819 case PREDICT_EXPR:
16820 gimplify_seq_add_stmt (pre_p,
16821 gimple_build_predict (PREDICT_EXPR_PREDICTOR (*expr_p),
16822 PREDICT_EXPR_OUTCOME (*expr_p)));
16823 ret = GS_ALL_DONE;
16824 break;
16826 case LABEL_EXPR:
16827 ret = gimplify_label_expr (expr_p, pre_p);
16828 label = LABEL_EXPR_LABEL (*expr_p);
16829 gcc_assert (decl_function_context (label) == current_function_decl);
16831 /* If the label is used in a goto statement, or address of the label
16832 is taken, we need to unpoison all variables that were seen so far.
16833 Doing so would prevent us from reporting a false positives. */
16834 if (asan_poisoned_variables
16835 && asan_used_labels != NULL
16836 && asan_used_labels->contains (label)
16837 && !gimplify_omp_ctxp)
16838 asan_poison_variables (asan_poisoned_variables, false, pre_p);
16839 break;
16841 case CASE_LABEL_EXPR:
16842 ret = gimplify_case_label_expr (expr_p, pre_p);
16844 if (gimplify_ctxp->live_switch_vars)
16845 asan_poison_variables (gimplify_ctxp->live_switch_vars, false,
16846 pre_p);
16847 break;
16849 case RETURN_EXPR:
16850 ret = gimplify_return_expr (*expr_p, pre_p);
16851 break;
16853 case CONSTRUCTOR:
16854 /* Don't reduce this in place; let gimplify_init_constructor work its
16855 magic. Buf if we're just elaborating this for side effects, just
16856 gimplify any element that has side-effects. */
16857 if (fallback == fb_none)
16859 unsigned HOST_WIDE_INT ix;
16860 tree val;
16861 tree temp = NULL_TREE;
16862 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (*expr_p), ix, val)
16863 if (TREE_SIDE_EFFECTS (val))
16864 append_to_statement_list (val, &temp);
16866 *expr_p = temp;
16867 ret = temp ? GS_OK : GS_ALL_DONE;
16869 /* C99 code may assign to an array in a constructed
16870 structure or union, and this has undefined behavior only
16871 on execution, so create a temporary if an lvalue is
16872 required. */
16873 else if (fallback == fb_lvalue)
16875 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
16876 mark_addressable (*expr_p);
16877 ret = GS_OK;
16879 else
16880 ret = GS_ALL_DONE;
16881 break;
16883 /* The following are special cases that are not handled by the
16884 original GIMPLE grammar. */
16886 /* SAVE_EXPR nodes are converted into a GIMPLE identifier and
16887 eliminated. */
16888 case SAVE_EXPR:
16889 ret = gimplify_save_expr (expr_p, pre_p, post_p);
16890 break;
16892 case BIT_FIELD_REF:
16893 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
16894 post_p, is_gimple_lvalue, fb_either);
16895 recalculate_side_effects (*expr_p);
16896 break;
16898 case TARGET_MEM_REF:
16900 enum gimplify_status r0 = GS_ALL_DONE, r1 = GS_ALL_DONE;
16902 if (TMR_BASE (*expr_p))
16903 r0 = gimplify_expr (&TMR_BASE (*expr_p), pre_p,
16904 post_p, is_gimple_mem_ref_addr, fb_either);
16905 if (TMR_INDEX (*expr_p))
16906 r1 = gimplify_expr (&TMR_INDEX (*expr_p), pre_p,
16907 post_p, is_gimple_val, fb_rvalue);
16908 if (TMR_INDEX2 (*expr_p))
16909 r1 = gimplify_expr (&TMR_INDEX2 (*expr_p), pre_p,
16910 post_p, is_gimple_val, fb_rvalue);
16911 /* TMR_STEP and TMR_OFFSET are always integer constants. */
16912 ret = MIN (r0, r1);
16914 break;
16916 case NON_LVALUE_EXPR:
16917 /* This should have been stripped above. */
16918 gcc_unreachable ();
16920 case ASM_EXPR:
16921 ret = gimplify_asm_expr (expr_p, pre_p, post_p);
16922 break;
16924 case TRY_FINALLY_EXPR:
16925 case TRY_CATCH_EXPR:
16927 gimple_seq eval, cleanup;
16928 gtry *try_;
16930 /* Calls to destructors are generated automatically in FINALLY/CATCH
16931 block. They should have location as UNKNOWN_LOCATION. However,
16932 gimplify_call_expr will reset these call stmts to input_location
16933 if it finds stmt's location is unknown. To prevent resetting for
16934 destructors, we set the input_location to unknown.
16935 Note that this only affects the destructor calls in FINALLY/CATCH
16936 block, and will automatically reset to its original value by the
16937 end of gimplify_expr. */
16938 input_location = UNKNOWN_LOCATION;
16939 eval = cleanup = NULL;
16940 gimplify_and_add (TREE_OPERAND (*expr_p, 0), &eval);
16941 if (TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
16942 && TREE_CODE (TREE_OPERAND (*expr_p, 1)) == EH_ELSE_EXPR)
16944 gimple_seq n = NULL, e = NULL;
16945 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1),
16946 0), &n);
16947 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1),
16948 1), &e);
16949 if (!gimple_seq_empty_p (n) && !gimple_seq_empty_p (e))
16951 geh_else *stmt = gimple_build_eh_else (n, e);
16952 gimple_seq_add_stmt (&cleanup, stmt);
16955 else
16956 gimplify_and_add (TREE_OPERAND (*expr_p, 1), &cleanup);
16957 /* Don't create bogus GIMPLE_TRY with empty cleanup. */
16958 if (gimple_seq_empty_p (cleanup))
16960 gimple_seq_add_seq (pre_p, eval);
16961 ret = GS_ALL_DONE;
16962 break;
16964 try_ = gimple_build_try (eval, cleanup,
16965 TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
16966 ? GIMPLE_TRY_FINALLY
16967 : GIMPLE_TRY_CATCH);
16968 if (EXPR_HAS_LOCATION (save_expr))
16969 gimple_set_location (try_, EXPR_LOCATION (save_expr));
16970 else if (LOCATION_LOCUS (saved_location) != UNKNOWN_LOCATION)
16971 gimple_set_location (try_, saved_location);
16972 if (TREE_CODE (*expr_p) == TRY_CATCH_EXPR)
16973 gimple_try_set_catch_is_cleanup (try_,
16974 TRY_CATCH_IS_CLEANUP (*expr_p));
16975 gimplify_seq_add_stmt (pre_p, try_);
16976 ret = GS_ALL_DONE;
16977 break;
16980 case CLEANUP_POINT_EXPR:
16981 ret = gimplify_cleanup_point_expr (expr_p, pre_p);
16982 break;
16984 case TARGET_EXPR:
16985 ret = gimplify_target_expr (expr_p, pre_p, post_p);
16986 break;
16988 case CATCH_EXPR:
16990 gimple *c;
16991 gimple_seq handler = NULL;
16992 gimplify_and_add (CATCH_BODY (*expr_p), &handler);
16993 c = gimple_build_catch (CATCH_TYPES (*expr_p), handler);
16994 gimplify_seq_add_stmt (pre_p, c);
16995 ret = GS_ALL_DONE;
16996 break;
16999 case EH_FILTER_EXPR:
17001 gimple *ehf;
17002 gimple_seq failure = NULL;
17004 gimplify_and_add (EH_FILTER_FAILURE (*expr_p), &failure);
17005 ehf = gimple_build_eh_filter (EH_FILTER_TYPES (*expr_p), failure);
17006 copy_warning (ehf, *expr_p);
17007 gimplify_seq_add_stmt (pre_p, ehf);
17008 ret = GS_ALL_DONE;
17009 break;
17012 case OBJ_TYPE_REF:
17014 enum gimplify_status r0, r1;
17015 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p,
17016 post_p, is_gimple_val, fb_rvalue);
17017 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p,
17018 post_p, is_gimple_val, fb_rvalue);
17019 TREE_SIDE_EFFECTS (*expr_p) = 0;
17020 ret = MIN (r0, r1);
17022 break;
17024 case LABEL_DECL:
17025 /* We get here when taking the address of a label. We mark
17026 the label as "forced"; meaning it can never be removed and
17027 it is a potential target for any computed goto. */
17028 FORCED_LABEL (*expr_p) = 1;
17029 ret = GS_ALL_DONE;
17030 break;
17032 case STATEMENT_LIST:
17033 ret = gimplify_statement_list (expr_p, pre_p);
17034 break;
17036 case WITH_SIZE_EXPR:
17038 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
17039 post_p == &internal_post ? NULL : post_p,
17040 gimple_test_f, fallback);
17041 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
17042 is_gimple_val, fb_rvalue);
17043 ret = GS_ALL_DONE;
17045 break;
17047 case VAR_DECL:
17048 case PARM_DECL:
17049 ret = gimplify_var_or_parm_decl (expr_p);
17050 break;
17052 case RESULT_DECL:
17053 /* When within an OMP context, notice uses of variables. */
17054 if (gimplify_omp_ctxp)
17055 omp_notice_variable (gimplify_omp_ctxp, *expr_p, true);
17056 ret = GS_ALL_DONE;
17057 break;
17059 case DEBUG_EXPR_DECL:
17060 gcc_unreachable ();
17062 case DEBUG_BEGIN_STMT:
17063 gimplify_seq_add_stmt (pre_p,
17064 gimple_build_debug_begin_stmt
17065 (TREE_BLOCK (*expr_p),
17066 EXPR_LOCATION (*expr_p)));
17067 ret = GS_ALL_DONE;
17068 *expr_p = NULL;
17069 break;
17071 case SSA_NAME:
17072 /* Allow callbacks into the gimplifier during optimization. */
17073 ret = GS_ALL_DONE;
17074 break;
17076 case OMP_PARALLEL:
17077 gimplify_omp_parallel (expr_p, pre_p);
17078 ret = GS_ALL_DONE;
17079 break;
17081 case OMP_TASK:
17082 gimplify_omp_task (expr_p, pre_p);
17083 ret = GS_ALL_DONE;
17084 break;
17086 case OMP_SIMD:
17088 /* Temporarily disable into_ssa, as scan_omp_simd
17089 which calls copy_gimple_seq_and_replace_locals can't deal
17090 with SSA_NAMEs defined outside of the body properly. */
17091 bool saved_into_ssa = gimplify_ctxp->into_ssa;
17092 gimplify_ctxp->into_ssa = false;
17093 ret = gimplify_omp_for (expr_p, pre_p);
17094 gimplify_ctxp->into_ssa = saved_into_ssa;
17095 break;
17098 case OMP_FOR:
17099 case OMP_DISTRIBUTE:
17100 case OMP_TASKLOOP:
17101 case OACC_LOOP:
17102 ret = gimplify_omp_for (expr_p, pre_p);
17103 break;
17105 case OMP_LOOP:
17106 ret = gimplify_omp_loop (expr_p, pre_p);
17107 break;
17109 case OACC_CACHE:
17110 gimplify_oacc_cache (expr_p, pre_p);
17111 ret = GS_ALL_DONE;
17112 break;
17114 case OACC_DECLARE:
17115 gimplify_oacc_declare (expr_p, pre_p);
17116 ret = GS_ALL_DONE;
17117 break;
17119 case OACC_HOST_DATA:
17120 case OACC_DATA:
17121 case OACC_KERNELS:
17122 case OACC_PARALLEL:
17123 case OACC_SERIAL:
17124 case OMP_SCOPE:
17125 case OMP_SECTIONS:
17126 case OMP_SINGLE:
17127 case OMP_TARGET:
17128 case OMP_TARGET_DATA:
17129 case OMP_TEAMS:
17130 gimplify_omp_workshare (expr_p, pre_p);
17131 ret = GS_ALL_DONE;
17132 break;
17134 case OACC_ENTER_DATA:
17135 case OACC_EXIT_DATA:
17136 case OACC_UPDATE:
17137 case OMP_TARGET_UPDATE:
17138 case OMP_TARGET_ENTER_DATA:
17139 case OMP_TARGET_EXIT_DATA:
17140 gimplify_omp_target_update (expr_p, pre_p);
17141 ret = GS_ALL_DONE;
17142 break;
17144 case OMP_SECTION:
17145 case OMP_STRUCTURED_BLOCK:
17146 case OMP_MASTER:
17147 case OMP_MASKED:
17148 case OMP_ORDERED:
17149 case OMP_CRITICAL:
17150 case OMP_SCAN:
17152 gimple_seq body = NULL;
17153 gimple *g;
17154 bool saved_in_omp_construct = in_omp_construct;
17156 in_omp_construct = true;
17157 gimplify_and_add (OMP_BODY (*expr_p), &body);
17158 in_omp_construct = saved_in_omp_construct;
17159 switch (TREE_CODE (*expr_p))
17161 case OMP_SECTION:
17162 g = gimple_build_omp_section (body);
17163 break;
17164 case OMP_STRUCTURED_BLOCK:
17165 g = gimple_build_omp_structured_block (body);
17166 break;
17167 case OMP_MASTER:
17168 g = gimple_build_omp_master (body);
17169 break;
17170 case OMP_ORDERED:
17171 g = gimplify_omp_ordered (*expr_p, body);
17172 if (OMP_BODY (*expr_p) == NULL_TREE
17173 && gimple_code (g) == GIMPLE_OMP_ORDERED)
17174 gimple_omp_ordered_standalone (g);
17175 break;
17176 case OMP_MASKED:
17177 gimplify_scan_omp_clauses (&OMP_MASKED_CLAUSES (*expr_p),
17178 pre_p, ORT_WORKSHARE, OMP_MASKED);
17179 gimplify_adjust_omp_clauses (pre_p, body,
17180 &OMP_MASKED_CLAUSES (*expr_p),
17181 OMP_MASKED);
17182 g = gimple_build_omp_masked (body,
17183 OMP_MASKED_CLAUSES (*expr_p));
17184 break;
17185 case OMP_CRITICAL:
17186 gimplify_scan_omp_clauses (&OMP_CRITICAL_CLAUSES (*expr_p),
17187 pre_p, ORT_WORKSHARE, OMP_CRITICAL);
17188 gimplify_adjust_omp_clauses (pre_p, body,
17189 &OMP_CRITICAL_CLAUSES (*expr_p),
17190 OMP_CRITICAL);
17191 g = gimple_build_omp_critical (body,
17192 OMP_CRITICAL_NAME (*expr_p),
17193 OMP_CRITICAL_CLAUSES (*expr_p));
17194 break;
17195 case OMP_SCAN:
17196 gimplify_scan_omp_clauses (&OMP_SCAN_CLAUSES (*expr_p),
17197 pre_p, ORT_WORKSHARE, OMP_SCAN);
17198 gimplify_adjust_omp_clauses (pre_p, body,
17199 &OMP_SCAN_CLAUSES (*expr_p),
17200 OMP_SCAN);
17201 g = gimple_build_omp_scan (body, OMP_SCAN_CLAUSES (*expr_p));
17202 break;
17203 default:
17204 gcc_unreachable ();
17206 gimplify_seq_add_stmt (pre_p, g);
17207 ret = GS_ALL_DONE;
17208 break;
17211 case OMP_TASKGROUP:
17213 gimple_seq body = NULL;
17215 tree *pclauses = &OMP_TASKGROUP_CLAUSES (*expr_p);
17216 bool saved_in_omp_construct = in_omp_construct;
17217 gimplify_scan_omp_clauses (pclauses, pre_p, ORT_TASKGROUP,
17218 OMP_TASKGROUP);
17219 gimplify_adjust_omp_clauses (pre_p, NULL, pclauses, OMP_TASKGROUP);
17221 in_omp_construct = true;
17222 gimplify_and_add (OMP_BODY (*expr_p), &body);
17223 in_omp_construct = saved_in_omp_construct;
17224 gimple_seq cleanup = NULL;
17225 tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_END);
17226 gimple *g = gimple_build_call (fn, 0);
17227 gimple_seq_add_stmt (&cleanup, g);
17228 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
17229 body = NULL;
17230 gimple_seq_add_stmt (&body, g);
17231 g = gimple_build_omp_taskgroup (body, *pclauses);
17232 gimplify_seq_add_stmt (pre_p, g);
17233 ret = GS_ALL_DONE;
17234 break;
17237 case OMP_ATOMIC:
17238 case OMP_ATOMIC_READ:
17239 case OMP_ATOMIC_CAPTURE_OLD:
17240 case OMP_ATOMIC_CAPTURE_NEW:
17241 ret = gimplify_omp_atomic (expr_p, pre_p);
17242 break;
17244 case TRANSACTION_EXPR:
17245 ret = gimplify_transaction (expr_p, pre_p);
17246 break;
17248 case TRUTH_AND_EXPR:
17249 case TRUTH_OR_EXPR:
17250 case TRUTH_XOR_EXPR:
17252 tree orig_type = TREE_TYPE (*expr_p);
17253 tree new_type, xop0, xop1;
17254 *expr_p = gimple_boolify (*expr_p);
17255 new_type = TREE_TYPE (*expr_p);
17256 if (!useless_type_conversion_p (orig_type, new_type))
17258 *expr_p = fold_convert_loc (input_location, orig_type, *expr_p);
17259 ret = GS_OK;
17260 break;
17263 /* Boolified binary truth expressions are semantically equivalent
17264 to bitwise binary expressions. Canonicalize them to the
17265 bitwise variant. */
17266 switch (TREE_CODE (*expr_p))
17268 case TRUTH_AND_EXPR:
17269 TREE_SET_CODE (*expr_p, BIT_AND_EXPR);
17270 break;
17271 case TRUTH_OR_EXPR:
17272 TREE_SET_CODE (*expr_p, BIT_IOR_EXPR);
17273 break;
17274 case TRUTH_XOR_EXPR:
17275 TREE_SET_CODE (*expr_p, BIT_XOR_EXPR);
17276 break;
17277 default:
17278 break;
17280 /* Now make sure that operands have compatible type to
17281 expression's new_type. */
17282 xop0 = TREE_OPERAND (*expr_p, 0);
17283 xop1 = TREE_OPERAND (*expr_p, 1);
17284 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop0)))
17285 TREE_OPERAND (*expr_p, 0) = fold_convert_loc (input_location,
17286 new_type,
17287 xop0);
17288 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop1)))
17289 TREE_OPERAND (*expr_p, 1) = fold_convert_loc (input_location,
17290 new_type,
17291 xop1);
17292 /* Continue classified as tcc_binary. */
17293 goto expr_2;
17296 case VEC_COND_EXPR:
17297 goto expr_3;
17299 case VEC_PERM_EXPR:
17300 /* Classified as tcc_expression. */
17301 goto expr_3;
17303 case BIT_INSERT_EXPR:
17304 /* Argument 3 is a constant. */
17305 goto expr_2;
17307 case POINTER_PLUS_EXPR:
17309 enum gimplify_status r0, r1;
17310 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
17311 post_p, is_gimple_val, fb_rvalue);
17312 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
17313 post_p, is_gimple_val, fb_rvalue);
17314 recalculate_side_effects (*expr_p);
17315 ret = MIN (r0, r1);
17316 break;
17319 default:
17320 switch (TREE_CODE_CLASS (TREE_CODE (*expr_p)))
17322 case tcc_comparison:
17323 /* Handle comparison of objects of non scalar mode aggregates
17324 with a call to memcmp. It would be nice to only have to do
17325 this for variable-sized objects, but then we'd have to allow
17326 the same nest of reference nodes we allow for MODIFY_EXPR and
17327 that's too complex.
17329 Compare scalar mode aggregates as scalar mode values. Using
17330 memcmp for them would be very inefficient at best, and is
17331 plain wrong if bitfields are involved. */
17332 if (error_operand_p (TREE_OPERAND (*expr_p, 1)))
17333 ret = GS_ERROR;
17334 else
17336 tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 1));
17338 /* Vector comparisons need no boolification. */
17339 if (TREE_CODE (type) == VECTOR_TYPE)
17340 goto expr_2;
17341 else if (!AGGREGATE_TYPE_P (type))
17343 tree org_type = TREE_TYPE (*expr_p);
17344 *expr_p = gimple_boolify (*expr_p);
17345 if (!useless_type_conversion_p (org_type,
17346 TREE_TYPE (*expr_p)))
17348 *expr_p = fold_convert_loc (input_location,
17349 org_type, *expr_p);
17350 ret = GS_OK;
17352 else
17353 goto expr_2;
17355 else if (TYPE_MODE (type) != BLKmode)
17356 ret = gimplify_scalar_mode_aggregate_compare (expr_p);
17357 else
17358 ret = gimplify_variable_sized_compare (expr_p);
17360 break;
17362 /* If *EXPR_P does not need to be special-cased, handle it
17363 according to its class. */
17364 case tcc_unary:
17365 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
17366 post_p, is_gimple_val, fb_rvalue);
17367 break;
17369 case tcc_binary:
17370 expr_2:
17372 enum gimplify_status r0, r1;
17374 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
17375 post_p, is_gimple_val, fb_rvalue);
17376 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
17377 post_p, is_gimple_val, fb_rvalue);
17379 ret = MIN (r0, r1);
17380 break;
17383 expr_3:
17385 enum gimplify_status r0, r1, r2;
17387 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
17388 post_p, is_gimple_val, fb_rvalue);
17389 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
17390 post_p, is_gimple_val, fb_rvalue);
17391 r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p,
17392 post_p, is_gimple_val, fb_rvalue);
17394 ret = MIN (MIN (r0, r1), r2);
17395 break;
17398 case tcc_declaration:
17399 case tcc_constant:
17400 ret = GS_ALL_DONE;
17401 goto dont_recalculate;
17403 default:
17404 gcc_unreachable ();
17407 recalculate_side_effects (*expr_p);
17409 dont_recalculate:
17410 break;
17413 gcc_assert (*expr_p || ret != GS_OK);
17415 while (ret == GS_OK);
17417 /* If we encountered an error_mark somewhere nested inside, either
17418 stub out the statement or propagate the error back out. */
17419 if (ret == GS_ERROR)
17421 if (is_statement)
17422 *expr_p = NULL;
17423 goto out;
17426 /* This was only valid as a return value from the langhook, which
17427 we handled. Make sure it doesn't escape from any other context. */
17428 gcc_assert (ret != GS_UNHANDLED);
17430 if (fallback == fb_none && *expr_p && !is_gimple_stmt (*expr_p))
17432 /* We aren't looking for a value, and we don't have a valid
17433 statement. If it doesn't have side-effects, throw it away.
17434 We can also get here with code such as "*&&L;", where L is
17435 a LABEL_DECL that is marked as FORCED_LABEL. */
17436 if (TREE_CODE (*expr_p) == LABEL_DECL
17437 || !TREE_SIDE_EFFECTS (*expr_p))
17438 *expr_p = NULL;
17439 else if (!TREE_THIS_VOLATILE (*expr_p))
17441 /* This is probably a _REF that contains something nested that
17442 has side effects. Recurse through the operands to find it. */
17443 enum tree_code code = TREE_CODE (*expr_p);
17445 switch (code)
17447 case COMPONENT_REF:
17448 case REALPART_EXPR:
17449 case IMAGPART_EXPR:
17450 case VIEW_CONVERT_EXPR:
17451 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
17452 gimple_test_f, fallback);
17453 break;
17455 case ARRAY_REF:
17456 case ARRAY_RANGE_REF:
17457 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
17458 gimple_test_f, fallback);
17459 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
17460 gimple_test_f, fallback);
17461 break;
17463 default:
17464 /* Anything else with side-effects must be converted to
17465 a valid statement before we get here. */
17466 gcc_unreachable ();
17469 *expr_p = NULL;
17471 else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p))
17472 && TYPE_MODE (TREE_TYPE (*expr_p)) != BLKmode
17473 && !is_empty_type (TREE_TYPE (*expr_p)))
17475 /* Historically, the compiler has treated a bare reference
17476 to a non-BLKmode volatile lvalue as forcing a load. */
17477 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p));
17479 /* Normally, we do not want to create a temporary for a
17480 TREE_ADDRESSABLE type because such a type should not be
17481 copied by bitwise-assignment. However, we make an
17482 exception here, as all we are doing here is ensuring that
17483 we read the bytes that make up the type. We use
17484 create_tmp_var_raw because create_tmp_var will abort when
17485 given a TREE_ADDRESSABLE type. */
17486 tree tmp = create_tmp_var_raw (type, "vol");
17487 gimple_add_tmp_var (tmp);
17488 gimplify_assign (tmp, *expr_p, pre_p);
17489 *expr_p = NULL;
17491 else
17492 /* We can't do anything useful with a volatile reference to
17493 an incomplete type, so just throw it away. Likewise for
17494 a BLKmode type, since any implicit inner load should
17495 already have been turned into an explicit one by the
17496 gimplification process. */
17497 *expr_p = NULL;
17500 /* If we are gimplifying at the statement level, we're done. Tack
17501 everything together and return. */
17502 if (fallback == fb_none || is_statement)
17504 /* Since *EXPR_P has been converted into a GIMPLE tuple, clear
17505 it out for GC to reclaim it. */
17506 *expr_p = NULL_TREE;
17508 if (!gimple_seq_empty_p (internal_pre)
17509 || !gimple_seq_empty_p (internal_post))
17511 gimplify_seq_add_seq (&internal_pre, internal_post);
17512 gimplify_seq_add_seq (pre_p, internal_pre);
17515 /* The result of gimplifying *EXPR_P is going to be the last few
17516 statements in *PRE_P and *POST_P. Add location information
17517 to all the statements that were added by the gimplification
17518 helpers. */
17519 if (!gimple_seq_empty_p (*pre_p))
17520 annotate_all_with_location_after (*pre_p, pre_last_gsi, input_location);
17522 if (!gimple_seq_empty_p (*post_p))
17523 annotate_all_with_location_after (*post_p, post_last_gsi,
17524 input_location);
17526 goto out;
17529 #ifdef ENABLE_GIMPLE_CHECKING
17530 if (*expr_p)
17532 enum tree_code code = TREE_CODE (*expr_p);
17533 /* These expressions should already be in gimple IR form. */
17534 gcc_assert (code != MODIFY_EXPR
17535 && code != ASM_EXPR
17536 && code != BIND_EXPR
17537 && code != CATCH_EXPR
17538 && (code != COND_EXPR || gimplify_ctxp->allow_rhs_cond_expr)
17539 && code != EH_FILTER_EXPR
17540 && code != GOTO_EXPR
17541 && code != LABEL_EXPR
17542 && code != LOOP_EXPR
17543 && code != SWITCH_EXPR
17544 && code != TRY_FINALLY_EXPR
17545 && code != EH_ELSE_EXPR
17546 && code != OACC_PARALLEL
17547 && code != OACC_KERNELS
17548 && code != OACC_SERIAL
17549 && code != OACC_DATA
17550 && code != OACC_HOST_DATA
17551 && code != OACC_DECLARE
17552 && code != OACC_UPDATE
17553 && code != OACC_ENTER_DATA
17554 && code != OACC_EXIT_DATA
17555 && code != OACC_CACHE
17556 && code != OMP_CRITICAL
17557 && code != OMP_FOR
17558 && code != OACC_LOOP
17559 && code != OMP_MASTER
17560 && code != OMP_MASKED
17561 && code != OMP_TASKGROUP
17562 && code != OMP_ORDERED
17563 && code != OMP_PARALLEL
17564 && code != OMP_SCAN
17565 && code != OMP_SECTIONS
17566 && code != OMP_SECTION
17567 && code != OMP_STRUCTURED_BLOCK
17568 && code != OMP_SINGLE
17569 && code != OMP_SCOPE);
17571 #endif
17573 /* Otherwise we're gimplifying a subexpression, so the resulting
17574 value is interesting. If it's a valid operand that matches
17575 GIMPLE_TEST_F, we're done. Unless we are handling some
17576 post-effects internally; if that's the case, we need to copy into
17577 a temporary before adding the post-effects to POST_P. */
17578 if (gimple_seq_empty_p (internal_post) && (*gimple_test_f) (*expr_p))
17579 goto out;
17581 /* Otherwise, we need to create a new temporary for the gimplified
17582 expression. */
17584 /* We can't return an lvalue if we have an internal postqueue. The
17585 object the lvalue refers to would (probably) be modified by the
17586 postqueue; we need to copy the value out first, which means an
17587 rvalue. */
17588 if ((fallback & fb_lvalue)
17589 && gimple_seq_empty_p (internal_post)
17590 && is_gimple_addressable (*expr_p))
17592 /* An lvalue will do. Take the address of the expression, store it
17593 in a temporary, and replace the expression with an INDIRECT_REF of
17594 that temporary. */
17595 tree ref_alias_type = reference_alias_ptr_type (*expr_p);
17596 unsigned int ref_align = get_object_alignment (*expr_p);
17597 tree ref_type = TREE_TYPE (*expr_p);
17598 tmp = build_fold_addr_expr_loc (input_location, *expr_p);
17599 gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue);
17600 if (TYPE_ALIGN (ref_type) != ref_align)
17601 ref_type = build_aligned_type (ref_type, ref_align);
17602 *expr_p = build2 (MEM_REF, ref_type,
17603 tmp, build_zero_cst (ref_alias_type));
17605 else if ((fallback & fb_rvalue) && is_gimple_reg_rhs_or_call (*expr_p))
17607 /* An rvalue will do. Assign the gimplified expression into a
17608 new temporary TMP and replace the original expression with
17609 TMP. First, make sure that the expression has a type so that
17610 it can be assigned into a temporary. */
17611 gcc_assert (!VOID_TYPE_P (TREE_TYPE (*expr_p)));
17612 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
17614 else
17616 #ifdef ENABLE_GIMPLE_CHECKING
17617 if (!(fallback & fb_mayfail))
17619 fprintf (stderr, "gimplification failed:\n");
17620 print_generic_expr (stderr, *expr_p);
17621 debug_tree (*expr_p);
17622 internal_error ("gimplification failed");
17624 #endif
17625 gcc_assert (fallback & fb_mayfail);
17627 /* If this is an asm statement, and the user asked for the
17628 impossible, don't die. Fail and let gimplify_asm_expr
17629 issue an error. */
17630 ret = GS_ERROR;
17631 goto out;
17634 /* Make sure the temporary matches our predicate. */
17635 gcc_assert ((*gimple_test_f) (*expr_p));
17637 if (!gimple_seq_empty_p (internal_post))
17639 annotate_all_with_location (internal_post, input_location);
17640 gimplify_seq_add_seq (pre_p, internal_post);
17643 out:
17644 input_location = saved_location;
17645 return ret;
17648 /* Like gimplify_expr but make sure the gimplified result is not itself
17649 a SSA name (but a decl if it were). Temporaries required by
17650 evaluating *EXPR_P may be still SSA names. */
17652 static enum gimplify_status
17653 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
17654 bool (*gimple_test_f) (tree), fallback_t fallback,
17655 bool allow_ssa)
17657 enum gimplify_status ret = gimplify_expr (expr_p, pre_p, post_p,
17658 gimple_test_f, fallback);
17659 if (! allow_ssa
17660 && TREE_CODE (*expr_p) == SSA_NAME)
17661 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, NULL, false);
17662 return ret;
17665 /* Look through TYPE for variable-sized objects and gimplify each such
17666 size that we find. Add to LIST_P any statements generated. */
17668 void
17669 gimplify_type_sizes (tree type, gimple_seq *list_p)
17671 if (type == NULL || type == error_mark_node)
17672 return;
17674 const bool ignored_p
17675 = TYPE_NAME (type)
17676 && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
17677 && DECL_IGNORED_P (TYPE_NAME (type));
17678 tree t;
17680 /* We first do the main variant, then copy into any other variants. */
17681 type = TYPE_MAIN_VARIANT (type);
17683 /* Avoid infinite recursion. */
17684 if (TYPE_SIZES_GIMPLIFIED (type))
17685 return;
17687 TYPE_SIZES_GIMPLIFIED (type) = 1;
17689 switch (TREE_CODE (type))
17691 case INTEGER_TYPE:
17692 case ENUMERAL_TYPE:
17693 case BOOLEAN_TYPE:
17694 case REAL_TYPE:
17695 case FIXED_POINT_TYPE:
17696 gimplify_one_sizepos (&TYPE_MIN_VALUE (type), list_p);
17697 gimplify_one_sizepos (&TYPE_MAX_VALUE (type), list_p);
17699 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
17701 TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type);
17702 TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type);
17704 break;
17706 case ARRAY_TYPE:
17707 /* These types may not have declarations, so handle them here. */
17708 gimplify_type_sizes (TREE_TYPE (type), list_p);
17709 gimplify_type_sizes (TYPE_DOMAIN (type), list_p);
17710 /* Ensure VLA bounds aren't removed, for -O0 they should be variables
17711 with assigned stack slots, for -O1+ -g they should be tracked
17712 by VTA. */
17713 if (!ignored_p
17714 && TYPE_DOMAIN (type)
17715 && INTEGRAL_TYPE_P (TYPE_DOMAIN (type)))
17717 t = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
17718 if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
17719 DECL_IGNORED_P (t) = 0;
17720 t = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
17721 if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
17722 DECL_IGNORED_P (t) = 0;
17724 break;
17726 case RECORD_TYPE:
17727 case UNION_TYPE:
17728 case QUAL_UNION_TYPE:
17729 for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
17730 if (TREE_CODE (field) == FIELD_DECL)
17732 gimplify_one_sizepos (&DECL_FIELD_OFFSET (field), list_p);
17733 /* Likewise, ensure variable offsets aren't removed. */
17734 if (!ignored_p
17735 && (t = DECL_FIELD_OFFSET (field))
17736 && VAR_P (t)
17737 && DECL_ARTIFICIAL (t))
17738 DECL_IGNORED_P (t) = 0;
17739 gimplify_one_sizepos (&DECL_SIZE (field), list_p);
17740 gimplify_one_sizepos (&DECL_SIZE_UNIT (field), list_p);
17741 gimplify_type_sizes (TREE_TYPE (field), list_p);
17743 break;
17745 case POINTER_TYPE:
17746 case REFERENCE_TYPE:
17747 /* We used to recurse on the pointed-to type here, which turned out to
17748 be incorrect because its definition might refer to variables not
17749 yet initialized at this point if a forward declaration is involved.
17751 It was actually useful for anonymous pointed-to types to ensure
17752 that the sizes evaluation dominates every possible later use of the
17753 values. Restricting to such types here would be safe since there
17754 is no possible forward declaration around, but would introduce an
17755 undesirable middle-end semantic to anonymity. We then defer to
17756 front-ends the responsibility of ensuring that the sizes are
17757 evaluated both early and late enough, e.g. by attaching artificial
17758 type declarations to the tree. */
17759 break;
17761 default:
17762 break;
17765 gimplify_one_sizepos (&TYPE_SIZE (type), list_p);
17766 gimplify_one_sizepos (&TYPE_SIZE_UNIT (type), list_p);
17768 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
17770 TYPE_SIZE (t) = TYPE_SIZE (type);
17771 TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (type);
17772 TYPE_SIZES_GIMPLIFIED (t) = 1;
17776 /* A subroutine of gimplify_type_sizes to make sure that *EXPR_P,
17777 a size or position, has had all of its SAVE_EXPRs evaluated.
17778 We add any required statements to *STMT_P. */
17780 void
17781 gimplify_one_sizepos (tree *expr_p, gimple_seq *stmt_p)
17783 tree expr = *expr_p;
17785 /* We don't do anything if the value isn't there, is constant, or contains
17786 A PLACEHOLDER_EXPR. We also don't want to do anything if it's already
17787 a VAR_DECL. If it's a VAR_DECL from another function, the gimplifier
17788 will want to replace it with a new variable, but that will cause problems
17789 if this type is from outside the function. It's OK to have that here. */
17790 if (expr == NULL_TREE
17791 || is_gimple_constant (expr)
17792 || VAR_P (expr)
17793 || CONTAINS_PLACEHOLDER_P (expr))
17794 return;
17796 *expr_p = unshare_expr (expr);
17798 /* SSA names in decl/type fields are a bad idea - they'll get reclaimed
17799 if the def vanishes. */
17800 gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue, false);
17802 /* If expr wasn't already is_gimple_sizepos or is_gimple_constant from the
17803 FE, ensure that it is a VAR_DECL, otherwise we might handle some decls
17804 as gimplify_vla_decl even when they would have all sizes INTEGER_CSTs. */
17805 if (is_gimple_constant (*expr_p))
17806 *expr_p = get_initialized_tmp_var (*expr_p, stmt_p, NULL, false);
17809 /* Gimplify the body of statements of FNDECL and return a GIMPLE_BIND node
17810 containing the sequence of corresponding GIMPLE statements. If DO_PARMS
17811 is true, also gimplify the parameters. */
17813 gbind *
17814 gimplify_body (tree fndecl, bool do_parms)
17816 location_t saved_location = input_location;
17817 gimple_seq parm_stmts, parm_cleanup = NULL, seq;
17818 gimple *outer_stmt;
17819 gbind *outer_bind;
17821 timevar_push (TV_TREE_GIMPLIFY);
17823 init_tree_ssa (cfun);
17825 /* Initialize for optimize_insn_for_s{ize,peed}_p possibly called during
17826 gimplification. */
17827 default_rtl_profile ();
17829 gcc_assert (gimplify_ctxp == NULL);
17830 push_gimplify_context (true);
17832 if (flag_openacc || flag_openmp)
17834 gcc_assert (gimplify_omp_ctxp == NULL);
17835 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (fndecl)))
17836 gimplify_omp_ctxp = new_omp_context (ORT_IMPLICIT_TARGET);
17839 /* Unshare most shared trees in the body and in that of any nested functions.
17840 It would seem we don't have to do this for nested functions because
17841 they are supposed to be output and then the outer function gimplified
17842 first, but the g++ front end doesn't always do it that way. */
17843 unshare_body (fndecl);
17844 unvisit_body (fndecl);
17846 /* Make sure input_location isn't set to something weird. */
17847 input_location = DECL_SOURCE_LOCATION (fndecl);
17849 /* Resolve callee-copies. This has to be done before processing
17850 the body so that DECL_VALUE_EXPR gets processed correctly. */
17851 parm_stmts = do_parms ? gimplify_parameters (&parm_cleanup) : NULL;
17853 /* Gimplify the function's body. */
17854 seq = NULL;
17855 gimplify_stmt (&DECL_SAVED_TREE (fndecl), &seq);
17856 outer_stmt = gimple_seq_first_nondebug_stmt (seq);
17857 if (!outer_stmt)
17859 outer_stmt = gimple_build_nop ();
17860 gimplify_seq_add_stmt (&seq, outer_stmt);
17863 /* The body must contain exactly one statement, a GIMPLE_BIND. If this is
17864 not the case, wrap everything in a GIMPLE_BIND to make it so. */
17865 if (gimple_code (outer_stmt) == GIMPLE_BIND
17866 && (gimple_seq_first_nondebug_stmt (seq)
17867 == gimple_seq_last_nondebug_stmt (seq)))
17869 outer_bind = as_a <gbind *> (outer_stmt);
17870 if (gimple_seq_first_stmt (seq) != outer_stmt
17871 || gimple_seq_last_stmt (seq) != outer_stmt)
17873 /* If there are debug stmts before or after outer_stmt, move them
17874 inside of outer_bind body. */
17875 gimple_stmt_iterator gsi = gsi_for_stmt (outer_stmt, &seq);
17876 gimple_seq second_seq = NULL;
17877 if (gimple_seq_first_stmt (seq) != outer_stmt
17878 && gimple_seq_last_stmt (seq) != outer_stmt)
17880 second_seq = gsi_split_seq_after (gsi);
17881 gsi_remove (&gsi, false);
17883 else if (gimple_seq_first_stmt (seq) != outer_stmt)
17884 gsi_remove (&gsi, false);
17885 else
17887 gsi_remove (&gsi, false);
17888 second_seq = seq;
17889 seq = NULL;
17891 gimple_seq_add_seq_without_update (&seq,
17892 gimple_bind_body (outer_bind));
17893 gimple_seq_add_seq_without_update (&seq, second_seq);
17894 gimple_bind_set_body (outer_bind, seq);
17897 else
17898 outer_bind = gimple_build_bind (NULL_TREE, seq, NULL);
17900 DECL_SAVED_TREE (fndecl) = NULL_TREE;
17902 /* If we had callee-copies statements, insert them at the beginning
17903 of the function and clear DECL_VALUE_EXPR_P on the parameters. */
17904 if (!gimple_seq_empty_p (parm_stmts))
17906 tree parm;
17908 gimplify_seq_add_seq (&parm_stmts, gimple_bind_body (outer_bind));
17909 if (parm_cleanup)
17911 gtry *g = gimple_build_try (parm_stmts, parm_cleanup,
17912 GIMPLE_TRY_FINALLY);
17913 parm_stmts = NULL;
17914 gimple_seq_add_stmt (&parm_stmts, g);
17916 gimple_bind_set_body (outer_bind, parm_stmts);
17918 for (parm = DECL_ARGUMENTS (current_function_decl);
17919 parm; parm = DECL_CHAIN (parm))
17920 if (DECL_HAS_VALUE_EXPR_P (parm))
17922 DECL_HAS_VALUE_EXPR_P (parm) = 0;
17923 DECL_IGNORED_P (parm) = 0;
17927 if ((flag_openacc || flag_openmp || flag_openmp_simd)
17928 && gimplify_omp_ctxp)
17930 delete_omp_context (gimplify_omp_ctxp);
17931 gimplify_omp_ctxp = NULL;
17934 pop_gimplify_context (outer_bind);
17935 gcc_assert (gimplify_ctxp == NULL);
17937 if (flag_checking && !seen_error ())
17938 verify_gimple_in_seq (gimple_bind_body (outer_bind));
17940 timevar_pop (TV_TREE_GIMPLIFY);
17941 input_location = saved_location;
17943 return outer_bind;
17946 typedef char *char_p; /* For DEF_VEC_P. */
17948 /* Return whether we should exclude FNDECL from instrumentation. */
17950 static bool
17951 flag_instrument_functions_exclude_p (tree fndecl)
17953 vec<char_p> *v;
17955 v = (vec<char_p> *) flag_instrument_functions_exclude_functions;
17956 if (v && v->length () > 0)
17958 const char *name;
17959 int i;
17960 char *s;
17962 name = lang_hooks.decl_printable_name (fndecl, 1);
17963 FOR_EACH_VEC_ELT (*v, i, s)
17964 if (strstr (name, s) != NULL)
17965 return true;
17968 v = (vec<char_p> *) flag_instrument_functions_exclude_files;
17969 if (v && v->length () > 0)
17971 const char *name;
17972 int i;
17973 char *s;
17975 name = DECL_SOURCE_FILE (fndecl);
17976 FOR_EACH_VEC_ELT (*v, i, s)
17977 if (strstr (name, s) != NULL)
17978 return true;
17981 return false;
17984 /* Build a call to the instrumentation function FNCODE and add it to SEQ.
17985 If COND_VAR is not NULL, it is a boolean variable guarding the call to
17986 the instrumentation function. IF STMT is not NULL, it is a statement
17987 to be executed just before the call to the instrumentation function. */
17989 static void
17990 build_instrumentation_call (gimple_seq *seq, enum built_in_function fncode,
17991 tree cond_var, gimple *stmt)
17993 /* The instrumentation hooks aren't going to call the instrumented
17994 function and the address they receive is expected to be matchable
17995 against symbol addresses. Make sure we don't create a trampoline,
17996 in case the current function is nested. */
17997 tree this_fn_addr = build_fold_addr_expr (current_function_decl);
17998 TREE_NO_TRAMPOLINE (this_fn_addr) = 1;
18000 tree label_true, label_false;
18001 if (cond_var)
18003 label_true = create_artificial_label (UNKNOWN_LOCATION);
18004 label_false = create_artificial_label (UNKNOWN_LOCATION);
18005 gcond *cond = gimple_build_cond (EQ_EXPR, cond_var, boolean_false_node,
18006 label_true, label_false);
18007 gimplify_seq_add_stmt (seq, cond);
18008 gimplify_seq_add_stmt (seq, gimple_build_label (label_true));
18009 gimplify_seq_add_stmt (seq, gimple_build_predict (PRED_COLD_LABEL,
18010 NOT_TAKEN));
18013 if (stmt)
18014 gimplify_seq_add_stmt (seq, stmt);
18016 tree x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
18017 gcall *call = gimple_build_call (x, 1, integer_zero_node);
18018 tree tmp_var = create_tmp_var (ptr_type_node, "return_addr");
18019 gimple_call_set_lhs (call, tmp_var);
18020 gimplify_seq_add_stmt (seq, call);
18021 x = builtin_decl_implicit (fncode);
18022 call = gimple_build_call (x, 2, this_fn_addr, tmp_var);
18023 gimplify_seq_add_stmt (seq, call);
18025 if (cond_var)
18026 gimplify_seq_add_stmt (seq, gimple_build_label (label_false));
18029 /* Entry point to the gimplification pass. FNDECL is the FUNCTION_DECL
18030 node for the function we want to gimplify.
18032 Return the sequence of GIMPLE statements corresponding to the body
18033 of FNDECL. */
18035 void
18036 gimplify_function_tree (tree fndecl)
18038 gimple_seq seq;
18039 gbind *bind;
18041 gcc_assert (!gimple_body (fndecl));
18043 if (DECL_STRUCT_FUNCTION (fndecl))
18044 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
18045 else
18046 push_struct_function (fndecl);
18048 /* Tentatively set PROP_gimple_lva here, and reset it in gimplify_va_arg_expr
18049 if necessary. */
18050 cfun->curr_properties |= PROP_gimple_lva;
18052 if (asan_sanitize_use_after_scope ())
18053 asan_poisoned_variables = new hash_set<tree> ();
18054 bind = gimplify_body (fndecl, true);
18055 if (asan_poisoned_variables)
18057 delete asan_poisoned_variables;
18058 asan_poisoned_variables = NULL;
18061 /* The tree body of the function is no longer needed, replace it
18062 with the new GIMPLE body. */
18063 seq = NULL;
18064 gimple_seq_add_stmt (&seq, bind);
18065 gimple_set_body (fndecl, seq);
18067 /* If we're instrumenting function entry/exit, then prepend the call to
18068 the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to
18069 catch the exit hook. */
18070 /* ??? Add some way to ignore exceptions for this TFE. */
18071 if (flag_instrument_function_entry_exit
18072 && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl)
18073 /* Do not instrument extern inline functions. */
18074 && !(DECL_DECLARED_INLINE_P (fndecl)
18075 && DECL_EXTERNAL (fndecl)
18076 && DECL_DISREGARD_INLINE_LIMITS (fndecl))
18077 && !flag_instrument_functions_exclude_p (fndecl))
18079 gimple_seq body = NULL, cleanup = NULL;
18080 gassign *assign;
18081 tree cond_var;
18083 /* If -finstrument-functions-once is specified, generate:
18085 static volatile bool C.0 = false;
18086 bool tmp_called;
18088 tmp_called = C.0;
18089 if (!tmp_called)
18091 C.0 = true;
18092 [call profiling enter function]
18095 without specific protection for data races. */
18096 if (flag_instrument_function_entry_exit > 1)
18098 tree first_var
18099 = build_decl (DECL_SOURCE_LOCATION (current_function_decl),
18100 VAR_DECL,
18101 create_tmp_var_name ("C"),
18102 boolean_type_node);
18103 DECL_ARTIFICIAL (first_var) = 1;
18104 DECL_IGNORED_P (first_var) = 1;
18105 TREE_STATIC (first_var) = 1;
18106 TREE_THIS_VOLATILE (first_var) = 1;
18107 TREE_USED (first_var) = 1;
18108 DECL_INITIAL (first_var) = boolean_false_node;
18109 varpool_node::add (first_var);
18111 cond_var = create_tmp_var (boolean_type_node, "tmp_called");
18112 assign = gimple_build_assign (cond_var, first_var);
18113 gimplify_seq_add_stmt (&body, assign);
18115 assign = gimple_build_assign (first_var, boolean_true_node);
18118 else
18120 cond_var = NULL_TREE;
18121 assign = NULL;
18124 build_instrumentation_call (&body, BUILT_IN_PROFILE_FUNC_ENTER,
18125 cond_var, assign);
18127 /* If -finstrument-functions-once is specified, generate:
18129 if (!tmp_called)
18130 [call profiling exit function]
18132 without specific protection for data races. */
18133 build_instrumentation_call (&cleanup, BUILT_IN_PROFILE_FUNC_EXIT,
18134 cond_var, NULL);
18136 gimple *tf = gimple_build_try (seq, cleanup, GIMPLE_TRY_FINALLY);
18137 gimplify_seq_add_stmt (&body, tf);
18138 gbind *new_bind = gimple_build_bind (NULL, body, NULL);
18140 /* Replace the current function body with the body
18141 wrapped in the try/finally TF. */
18142 seq = NULL;
18143 gimple_seq_add_stmt (&seq, new_bind);
18144 gimple_set_body (fndecl, seq);
18145 bind = new_bind;
18148 if (sanitize_flags_p (SANITIZE_THREAD)
18149 && param_tsan_instrument_func_entry_exit)
18151 gcall *call = gimple_build_call_internal (IFN_TSAN_FUNC_EXIT, 0);
18152 gimple *tf = gimple_build_try (seq, call, GIMPLE_TRY_FINALLY);
18153 gbind *new_bind = gimple_build_bind (NULL, tf, NULL);
18154 /* Replace the current function body with the body
18155 wrapped in the try/finally TF. */
18156 seq = NULL;
18157 gimple_seq_add_stmt (&seq, new_bind);
18158 gimple_set_body (fndecl, seq);
18161 DECL_SAVED_TREE (fndecl) = NULL_TREE;
18162 cfun->curr_properties |= PROP_gimple_any;
18164 pop_cfun ();
18166 dump_function (TDI_gimple, fndecl);
18169 /* Return a dummy expression of type TYPE in order to keep going after an
18170 error. */
18172 static tree
18173 dummy_object (tree type)
18175 tree t = build_int_cst (build_pointer_type (type), 0);
18176 return build2 (MEM_REF, type, t, t);
18179 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
18180 builtin function, but a very special sort of operator. */
18182 enum gimplify_status
18183 gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p,
18184 gimple_seq *post_p ATTRIBUTE_UNUSED)
18186 tree promoted_type, have_va_type;
18187 tree valist = TREE_OPERAND (*expr_p, 0);
18188 tree type = TREE_TYPE (*expr_p);
18189 tree t, tag, aptag;
18190 location_t loc = EXPR_LOCATION (*expr_p);
18192 /* Verify that valist is of the proper type. */
18193 have_va_type = TREE_TYPE (valist);
18194 if (have_va_type == error_mark_node)
18195 return GS_ERROR;
18196 have_va_type = targetm.canonical_va_list_type (have_va_type);
18197 if (have_va_type == NULL_TREE
18198 && POINTER_TYPE_P (TREE_TYPE (valist)))
18199 /* Handle 'Case 1: Not an array type' from c-common.cc/build_va_arg. */
18200 have_va_type
18201 = targetm.canonical_va_list_type (TREE_TYPE (TREE_TYPE (valist)));
18202 gcc_assert (have_va_type != NULL_TREE);
18204 /* Generate a diagnostic for requesting data of a type that cannot
18205 be passed through `...' due to type promotion at the call site. */
18206 if ((promoted_type = lang_hooks.types.type_promotes_to (type))
18207 != type)
18209 static bool gave_help;
18210 bool warned;
18211 /* Use the expansion point to handle cases such as passing bool (defined
18212 in a system header) through `...'. */
18213 location_t xloc
18214 = expansion_point_location_if_in_system_header (loc);
18216 /* Unfortunately, this is merely undefined, rather than a constraint
18217 violation, so we cannot make this an error. If this call is never
18218 executed, the program is still strictly conforming. */
18219 auto_diagnostic_group d;
18220 warned = warning_at (xloc, 0,
18221 "%qT is promoted to %qT when passed through %<...%>",
18222 type, promoted_type);
18223 if (!gave_help && warned)
18225 gave_help = true;
18226 inform (xloc, "(so you should pass %qT not %qT to %<va_arg%>)",
18227 promoted_type, type);
18230 /* We can, however, treat "undefined" any way we please.
18231 Call abort to encourage the user to fix the program. */
18232 if (warned)
18233 inform (xloc, "if this code is reached, the program will abort");
18234 /* Before the abort, allow the evaluation of the va_list
18235 expression to exit or longjmp. */
18236 gimplify_and_add (valist, pre_p);
18237 t = build_call_expr_loc (loc,
18238 builtin_decl_implicit (BUILT_IN_TRAP), 0);
18239 gimplify_and_add (t, pre_p);
18241 /* This is dead code, but go ahead and finish so that the
18242 mode of the result comes out right. */
18243 *expr_p = dummy_object (type);
18244 return GS_ALL_DONE;
18247 tag = build_int_cst (build_pointer_type (type), 0);
18248 aptag = build_int_cst (TREE_TYPE (valist), 0);
18250 *expr_p = build_call_expr_internal_loc (loc, IFN_VA_ARG, type, 3,
18251 valist, tag, aptag);
18253 /* Clear the tentatively set PROP_gimple_lva, to indicate that IFN_VA_ARG
18254 needs to be expanded. */
18255 cfun->curr_properties &= ~PROP_gimple_lva;
18257 return GS_OK;
18260 /* Build a new GIMPLE_ASSIGN tuple and append it to the end of *SEQ_P.
18262 DST/SRC are the destination and source respectively. You can pass
18263 ungimplified trees in DST or SRC, in which case they will be
18264 converted to a gimple operand if necessary.
18266 This function returns the newly created GIMPLE_ASSIGN tuple. */
18268 gimple *
18269 gimplify_assign (tree dst, tree src, gimple_seq *seq_p)
18271 tree t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
18272 gimplify_and_add (t, seq_p);
18273 ggc_free (t);
18274 return gimple_seq_last_stmt (*seq_p);
18277 inline hashval_t
18278 gimplify_hasher::hash (const elt_t *p)
18280 tree t = p->val;
18281 return iterative_hash_expr (t, 0);
18284 inline bool
18285 gimplify_hasher::equal (const elt_t *p1, const elt_t *p2)
18287 tree t1 = p1->val;
18288 tree t2 = p2->val;
18289 enum tree_code code = TREE_CODE (t1);
18291 if (TREE_CODE (t2) != code
18292 || TREE_TYPE (t1) != TREE_TYPE (t2))
18293 return false;
18295 if (!operand_equal_p (t1, t2, 0))
18296 return false;
18298 /* Only allow them to compare equal if they also hash equal; otherwise
18299 results are nondeterminate, and we fail bootstrap comparison. */
18300 gcc_checking_assert (hash (p1) == hash (p2));
18302 return true;