rs6000: Skip DWARF5 and -fcompare-debug testcases on AIX.
[official-gcc.git] / gcc / gimplify.c
blob2f2c51b2d894e8070e4e62e014acf438e4be12cb
1 /* Tree lowering pass. This pass converts the GENERIC functions-as-trees
2 tree representation into the GIMPLE form.
3 Copyright (C) 2002-2020 Free Software Foundation, Inc.
4 Major work done by Sebastian Pop <s.pop@laposte.net>,
5 Diego Novillo <dnovillo@redhat.com> and Jason Merrill <jason@redhat.com>.
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
12 version.
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "backend.h"
27 #include "target.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "memmodel.h"
31 #include "tm_p.h"
32 #include "gimple.h"
33 #include "gimple-predict.h"
34 #include "tree-pass.h" /* FIXME: only for PROP_gimple_any */
35 #include "ssa.h"
36 #include "cgraph.h"
37 #include "tree-pretty-print.h"
38 #include "diagnostic-core.h"
39 #include "alias.h"
40 #include "fold-const.h"
41 #include "calls.h"
42 #include "varasm.h"
43 #include "stmt.h"
44 #include "expr.h"
45 #include "gimple-fold.h"
46 #include "tree-eh.h"
47 #include "gimplify.h"
48 #include "gimple-iterator.h"
49 #include "stor-layout.h"
50 #include "print-tree.h"
51 #include "tree-iterator.h"
52 #include "tree-inline.h"
53 #include "langhooks.h"
54 #include "tree-cfg.h"
55 #include "tree-ssa.h"
56 #include "omp-general.h"
57 #include "omp-low.h"
58 #include "gimple-low.h"
59 #include "gomp-constants.h"
60 #include "splay-tree.h"
61 #include "gimple-walk.h"
62 #include "langhooks-def.h" /* FIXME: for lhd_set_decl_assembler_name */
63 #include "builtins.h"
64 #include "stringpool.h"
65 #include "attribs.h"
66 #include "asan.h"
67 #include "dbgcnt.h"
68 #include "omp-offload.h"
69 #include "context.h"
71 /* Hash set of poisoned variables in a bind expr. */
72 static hash_set<tree> *asan_poisoned_variables = NULL;
74 enum gimplify_omp_var_data
76 GOVD_SEEN = 0x000001,
77 GOVD_EXPLICIT = 0x000002,
78 GOVD_SHARED = 0x000004,
79 GOVD_PRIVATE = 0x000008,
80 GOVD_FIRSTPRIVATE = 0x000010,
81 GOVD_LASTPRIVATE = 0x000020,
82 GOVD_REDUCTION = 0x000040,
83 GOVD_LOCAL = 0x00080,
84 GOVD_MAP = 0x000100,
85 GOVD_DEBUG_PRIVATE = 0x000200,
86 GOVD_PRIVATE_OUTER_REF = 0x000400,
87 GOVD_LINEAR = 0x000800,
88 GOVD_ALIGNED = 0x001000,
90 /* Flag for GOVD_MAP: don't copy back. */
91 GOVD_MAP_TO_ONLY = 0x002000,
93 /* Flag for GOVD_LINEAR or GOVD_LASTPRIVATE: no outer reference. */
94 GOVD_LINEAR_LASTPRIVATE_NO_OUTER = 0x004000,
96 GOVD_MAP_0LEN_ARRAY = 0x008000,
98 /* Flag for GOVD_MAP, if it is always, to or always, tofrom mapping. */
99 GOVD_MAP_ALWAYS_TO = 0x010000,
101 /* Flag for shared vars that are or might be stored to in the region. */
102 GOVD_WRITTEN = 0x020000,
104 /* Flag for GOVD_MAP, if it is a forced mapping. */
105 GOVD_MAP_FORCE = 0x040000,
107 /* Flag for GOVD_MAP: must be present already. */
108 GOVD_MAP_FORCE_PRESENT = 0x080000,
110 /* Flag for GOVD_MAP: only allocate. */
111 GOVD_MAP_ALLOC_ONLY = 0x100000,
113 /* Flag for GOVD_MAP: only copy back. */
114 GOVD_MAP_FROM_ONLY = 0x200000,
116 GOVD_NONTEMPORAL = 0x400000,
118 /* Flag for GOVD_LASTPRIVATE: conditional modifier. */
119 GOVD_LASTPRIVATE_CONDITIONAL = 0x800000,
121 GOVD_CONDTEMP = 0x1000000,
123 /* Flag for GOVD_REDUCTION: inscan seen in {in,ex}clusive clause. */
124 GOVD_REDUCTION_INSCAN = 0x2000000,
126 /* Flag for GOVD_MAP: (struct) vars that have pointer attachments for
127 fields. */
128 GOVD_MAP_HAS_ATTACHMENTS = 8388608,
130 GOVD_DATA_SHARE_CLASS = (GOVD_SHARED | GOVD_PRIVATE | GOVD_FIRSTPRIVATE
131 | GOVD_LASTPRIVATE | GOVD_REDUCTION | GOVD_LINEAR
132 | GOVD_LOCAL)
136 enum omp_region_type
138 ORT_WORKSHARE = 0x00,
139 ORT_TASKGROUP = 0x01,
140 ORT_SIMD = 0x04,
142 ORT_PARALLEL = 0x08,
143 ORT_COMBINED_PARALLEL = ORT_PARALLEL | 1,
145 ORT_TASK = 0x10,
146 ORT_UNTIED_TASK = ORT_TASK | 1,
147 ORT_TASKLOOP = ORT_TASK | 2,
148 ORT_UNTIED_TASKLOOP = ORT_UNTIED_TASK | 2,
150 ORT_TEAMS = 0x20,
151 ORT_COMBINED_TEAMS = ORT_TEAMS | 1,
152 ORT_HOST_TEAMS = ORT_TEAMS | 2,
153 ORT_COMBINED_HOST_TEAMS = ORT_COMBINED_TEAMS | 2,
155 /* Data region. */
156 ORT_TARGET_DATA = 0x40,
158 /* Data region with offloading. */
159 ORT_TARGET = 0x80,
160 ORT_COMBINED_TARGET = ORT_TARGET | 1,
161 ORT_IMPLICIT_TARGET = ORT_TARGET | 2,
163 /* OpenACC variants. */
164 ORT_ACC = 0x100, /* A generic OpenACC region. */
165 ORT_ACC_DATA = ORT_ACC | ORT_TARGET_DATA, /* Data construct. */
166 ORT_ACC_PARALLEL = ORT_ACC | ORT_TARGET, /* Parallel construct */
167 ORT_ACC_KERNELS = ORT_ACC | ORT_TARGET | 2, /* Kernels construct. */
168 ORT_ACC_SERIAL = ORT_ACC | ORT_TARGET | 4, /* Serial construct. */
169 ORT_ACC_HOST_DATA = ORT_ACC | ORT_TARGET_DATA | 2, /* Host data. */
171 /* Dummy OpenMP region, used to disable expansion of
172 DECL_VALUE_EXPRs in taskloop pre body. */
173 ORT_NONE = 0x200
176 /* Gimplify hashtable helper. */
178 struct gimplify_hasher : free_ptr_hash <elt_t>
180 static inline hashval_t hash (const elt_t *);
181 static inline bool equal (const elt_t *, const elt_t *);
184 struct gimplify_ctx
186 struct gimplify_ctx *prev_context;
188 vec<gbind *> bind_expr_stack;
189 tree temps;
190 gimple_seq conditional_cleanups;
191 tree exit_label;
192 tree return_temp;
194 vec<tree> case_labels;
195 hash_set<tree> *live_switch_vars;
196 /* The formal temporary table. Should this be persistent? */
197 hash_table<gimplify_hasher> *temp_htab;
199 int conditions;
200 unsigned into_ssa : 1;
201 unsigned allow_rhs_cond_expr : 1;
202 unsigned in_cleanup_point_expr : 1;
203 unsigned keep_stack : 1;
204 unsigned save_stack : 1;
205 unsigned in_switch_expr : 1;
208 enum gimplify_defaultmap_kind
210 GDMK_SCALAR,
211 GDMK_AGGREGATE,
212 GDMK_ALLOCATABLE,
213 GDMK_POINTER
216 struct gimplify_omp_ctx
218 struct gimplify_omp_ctx *outer_context;
219 splay_tree variables;
220 hash_set<tree> *privatized_types;
221 tree clauses;
222 /* Iteration variables in an OMP_FOR. */
223 vec<tree> loop_iter_var;
224 location_t location;
225 enum omp_clause_default_kind default_kind;
226 enum omp_region_type region_type;
227 enum tree_code code;
228 bool combined_loop;
229 bool distribute;
230 bool target_firstprivatize_array_bases;
231 bool add_safelen1;
232 bool order_concurrent;
233 int defaultmap[4];
236 static struct gimplify_ctx *gimplify_ctxp;
237 static struct gimplify_omp_ctx *gimplify_omp_ctxp;
238 static bool in_omp_construct;
240 /* Forward declaration. */
241 static enum gimplify_status gimplify_compound_expr (tree *, gimple_seq *, bool);
242 static hash_map<tree, tree> *oacc_declare_returns;
243 static enum gimplify_status gimplify_expr (tree *, gimple_seq *, gimple_seq *,
244 bool (*) (tree), fallback_t, bool);
246 /* Shorter alias name for the above function for use in gimplify.c
247 only. */
249 static inline void
250 gimplify_seq_add_stmt (gimple_seq *seq_p, gimple *gs)
252 gimple_seq_add_stmt_without_update (seq_p, gs);
255 /* Append sequence SRC to the end of sequence *DST_P. If *DST_P is
256 NULL, a new sequence is allocated. This function is
257 similar to gimple_seq_add_seq, but does not scan the operands.
258 During gimplification, we need to manipulate statement sequences
259 before the def/use vectors have been constructed. */
261 static void
262 gimplify_seq_add_seq (gimple_seq *dst_p, gimple_seq src)
264 gimple_stmt_iterator si;
266 if (src == NULL)
267 return;
269 si = gsi_last (*dst_p);
270 gsi_insert_seq_after_without_update (&si, src, GSI_NEW_STMT);
274 /* Pointer to a list of allocated gimplify_ctx structs to be used for pushing
275 and popping gimplify contexts. */
277 static struct gimplify_ctx *ctx_pool = NULL;
279 /* Return a gimplify context struct from the pool. */
281 static inline struct gimplify_ctx *
282 ctx_alloc (void)
284 struct gimplify_ctx * c = ctx_pool;
286 if (c)
287 ctx_pool = c->prev_context;
288 else
289 c = XNEW (struct gimplify_ctx);
291 memset (c, '\0', sizeof (*c));
292 return c;
295 /* Put gimplify context C back into the pool. */
297 static inline void
298 ctx_free (struct gimplify_ctx *c)
300 c->prev_context = ctx_pool;
301 ctx_pool = c;
304 /* Free allocated ctx stack memory. */
306 void
307 free_gimplify_stack (void)
309 struct gimplify_ctx *c;
311 while ((c = ctx_pool))
313 ctx_pool = c->prev_context;
314 free (c);
319 /* Set up a context for the gimplifier. */
321 void
322 push_gimplify_context (bool in_ssa, bool rhs_cond_ok)
324 struct gimplify_ctx *c = ctx_alloc ();
326 c->prev_context = gimplify_ctxp;
327 gimplify_ctxp = c;
328 gimplify_ctxp->into_ssa = in_ssa;
329 gimplify_ctxp->allow_rhs_cond_expr = rhs_cond_ok;
332 /* Tear down a context for the gimplifier. If BODY is non-null, then
333 put the temporaries into the outer BIND_EXPR. Otherwise, put them
334 in the local_decls.
336 BODY is not a sequence, but the first tuple in a sequence. */
338 void
339 pop_gimplify_context (gimple *body)
341 struct gimplify_ctx *c = gimplify_ctxp;
343 gcc_assert (c
344 && (!c->bind_expr_stack.exists ()
345 || c->bind_expr_stack.is_empty ()));
346 c->bind_expr_stack.release ();
347 gimplify_ctxp = c->prev_context;
349 if (body)
350 declare_vars (c->temps, body, false);
351 else
352 record_vars (c->temps);
354 delete c->temp_htab;
355 c->temp_htab = NULL;
356 ctx_free (c);
359 /* Push a GIMPLE_BIND tuple onto the stack of bindings. */
361 static void
362 gimple_push_bind_expr (gbind *bind_stmt)
364 gimplify_ctxp->bind_expr_stack.reserve (8);
365 gimplify_ctxp->bind_expr_stack.safe_push (bind_stmt);
368 /* Pop the first element off the stack of bindings. */
370 static void
371 gimple_pop_bind_expr (void)
373 gimplify_ctxp->bind_expr_stack.pop ();
376 /* Return the first element of the stack of bindings. */
378 gbind *
379 gimple_current_bind_expr (void)
381 return gimplify_ctxp->bind_expr_stack.last ();
384 /* Return the stack of bindings created during gimplification. */
386 vec<gbind *>
387 gimple_bind_expr_stack (void)
389 return gimplify_ctxp->bind_expr_stack;
392 /* Return true iff there is a COND_EXPR between us and the innermost
393 CLEANUP_POINT_EXPR. This info is used by gimple_push_cleanup. */
395 static bool
396 gimple_conditional_context (void)
398 return gimplify_ctxp->conditions > 0;
401 /* Note that we've entered a COND_EXPR. */
403 static void
404 gimple_push_condition (void)
406 #ifdef ENABLE_GIMPLE_CHECKING
407 if (gimplify_ctxp->conditions == 0)
408 gcc_assert (gimple_seq_empty_p (gimplify_ctxp->conditional_cleanups));
409 #endif
410 ++(gimplify_ctxp->conditions);
413 /* Note that we've left a COND_EXPR. If we're back at unconditional scope
414 now, add any conditional cleanups we've seen to the prequeue. */
416 static void
417 gimple_pop_condition (gimple_seq *pre_p)
419 int conds = --(gimplify_ctxp->conditions);
421 gcc_assert (conds >= 0);
422 if (conds == 0)
424 gimplify_seq_add_seq (pre_p, gimplify_ctxp->conditional_cleanups);
425 gimplify_ctxp->conditional_cleanups = NULL;
429 /* A stable comparison routine for use with splay trees and DECLs. */
431 static int
432 splay_tree_compare_decl_uid (splay_tree_key xa, splay_tree_key xb)
434 tree a = (tree) xa;
435 tree b = (tree) xb;
437 return DECL_UID (a) - DECL_UID (b);
440 /* Create a new omp construct that deals with variable remapping. */
442 static struct gimplify_omp_ctx *
443 new_omp_context (enum omp_region_type region_type)
445 struct gimplify_omp_ctx *c;
447 c = XCNEW (struct gimplify_omp_ctx);
448 c->outer_context = gimplify_omp_ctxp;
449 c->variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0);
450 c->privatized_types = new hash_set<tree>;
451 c->location = input_location;
452 c->region_type = region_type;
453 if ((region_type & ORT_TASK) == 0)
454 c->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
455 else
456 c->default_kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
457 c->defaultmap[GDMK_SCALAR] = GOVD_MAP;
458 c->defaultmap[GDMK_AGGREGATE] = GOVD_MAP;
459 c->defaultmap[GDMK_ALLOCATABLE] = GOVD_MAP;
460 c->defaultmap[GDMK_POINTER] = GOVD_MAP;
462 return c;
465 /* Destroy an omp construct that deals with variable remapping. */
467 static void
468 delete_omp_context (struct gimplify_omp_ctx *c)
470 splay_tree_delete (c->variables);
471 delete c->privatized_types;
472 c->loop_iter_var.release ();
473 XDELETE (c);
476 static void omp_add_variable (struct gimplify_omp_ctx *, tree, unsigned int);
477 static bool omp_notice_variable (struct gimplify_omp_ctx *, tree, bool);
479 /* Both gimplify the statement T and append it to *SEQ_P. This function
480 behaves exactly as gimplify_stmt, but you don't have to pass T as a
481 reference. */
483 void
484 gimplify_and_add (tree t, gimple_seq *seq_p)
486 gimplify_stmt (&t, seq_p);
489 /* Gimplify statement T into sequence *SEQ_P, and return the first
490 tuple in the sequence of generated tuples for this statement.
491 Return NULL if gimplifying T produced no tuples. */
493 static gimple *
494 gimplify_and_return_first (tree t, gimple_seq *seq_p)
496 gimple_stmt_iterator last = gsi_last (*seq_p);
498 gimplify_and_add (t, seq_p);
500 if (!gsi_end_p (last))
502 gsi_next (&last);
503 return gsi_stmt (last);
505 else
506 return gimple_seq_first_stmt (*seq_p);
509 /* Returns true iff T is a valid RHS for an assignment to an un-renamed
510 LHS, or for a call argument. */
512 static bool
513 is_gimple_mem_rhs (tree t)
515 /* If we're dealing with a renamable type, either source or dest must be
516 a renamed variable. */
517 if (is_gimple_reg_type (TREE_TYPE (t)))
518 return is_gimple_val (t);
519 else
520 return is_gimple_val (t) || is_gimple_lvalue (t);
523 /* Return true if T is a CALL_EXPR or an expression that can be
524 assigned to a temporary. Note that this predicate should only be
525 used during gimplification. See the rationale for this in
526 gimplify_modify_expr. */
528 static bool
529 is_gimple_reg_rhs_or_call (tree t)
531 return (get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS
532 || TREE_CODE (t) == CALL_EXPR);
535 /* Return true if T is a valid memory RHS or a CALL_EXPR. Note that
536 this predicate should only be used during gimplification. See the
537 rationale for this in gimplify_modify_expr. */
539 static bool
540 is_gimple_mem_rhs_or_call (tree t)
542 /* If we're dealing with a renamable type, either source or dest must be
543 a renamed variable. */
544 if (is_gimple_reg_type (TREE_TYPE (t)))
545 return is_gimple_val (t);
546 else
547 return (is_gimple_val (t)
548 || is_gimple_lvalue (t)
549 || TREE_CLOBBER_P (t)
550 || TREE_CODE (t) == CALL_EXPR);
553 /* Create a temporary with a name derived from VAL. Subroutine of
554 lookup_tmp_var; nobody else should call this function. */
556 static inline tree
557 create_tmp_from_val (tree val)
559 /* Drop all qualifiers and address-space information from the value type. */
560 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (val));
561 tree var = create_tmp_var (type, get_name (val));
562 if (TREE_CODE (TREE_TYPE (var)) == COMPLEX_TYPE
563 || TREE_CODE (TREE_TYPE (var)) == VECTOR_TYPE)
564 DECL_GIMPLE_REG_P (var) = 1;
565 return var;
568 /* Create a temporary to hold the value of VAL. If IS_FORMAL, try to reuse
569 an existing expression temporary. */
571 static tree
572 lookup_tmp_var (tree val, bool is_formal)
574 tree ret;
576 /* If not optimizing, never really reuse a temporary. local-alloc
577 won't allocate any variable that is used in more than one basic
578 block, which means it will go into memory, causing much extra
579 work in reload and final and poorer code generation, outweighing
580 the extra memory allocation here. */
581 if (!optimize || !is_formal || TREE_SIDE_EFFECTS (val))
582 ret = create_tmp_from_val (val);
583 else
585 elt_t elt, *elt_p;
586 elt_t **slot;
588 elt.val = val;
589 if (!gimplify_ctxp->temp_htab)
590 gimplify_ctxp->temp_htab = new hash_table<gimplify_hasher> (1000);
591 slot = gimplify_ctxp->temp_htab->find_slot (&elt, INSERT);
592 if (*slot == NULL)
594 elt_p = XNEW (elt_t);
595 elt_p->val = val;
596 elt_p->temp = ret = create_tmp_from_val (val);
597 *slot = elt_p;
599 else
601 elt_p = *slot;
602 ret = elt_p->temp;
606 return ret;
609 /* Helper for get_formal_tmp_var and get_initialized_tmp_var. */
611 static tree
612 internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
613 bool is_formal, bool allow_ssa)
615 tree t, mod;
617 /* Notice that we explicitly allow VAL to be a CALL_EXPR so that we
618 can create an INIT_EXPR and convert it into a GIMPLE_CALL below. */
619 gimplify_expr (&val, pre_p, post_p, is_gimple_reg_rhs_or_call,
620 fb_rvalue);
622 if (allow_ssa
623 && gimplify_ctxp->into_ssa
624 && is_gimple_reg_type (TREE_TYPE (val)))
626 t = make_ssa_name (TYPE_MAIN_VARIANT (TREE_TYPE (val)));
627 if (! gimple_in_ssa_p (cfun))
629 const char *name = get_name (val);
630 if (name)
631 SET_SSA_NAME_VAR_OR_IDENTIFIER (t, create_tmp_var_name (name));
634 else
635 t = lookup_tmp_var (val, is_formal);
637 mod = build2 (INIT_EXPR, TREE_TYPE (t), t, unshare_expr (val));
639 SET_EXPR_LOCATION (mod, EXPR_LOC_OR_LOC (val, input_location));
641 /* gimplify_modify_expr might want to reduce this further. */
642 gimplify_and_add (mod, pre_p);
643 ggc_free (mod);
645 return t;
648 /* Return a formal temporary variable initialized with VAL. PRE_P is as
649 in gimplify_expr. Only use this function if:
651 1) The value of the unfactored expression represented by VAL will not
652 change between the initialization and use of the temporary, and
653 2) The temporary will not be otherwise modified.
655 For instance, #1 means that this is inappropriate for SAVE_EXPR temps,
656 and #2 means it is inappropriate for && temps.
658 For other cases, use get_initialized_tmp_var instead. */
660 tree
661 get_formal_tmp_var (tree val, gimple_seq *pre_p)
663 return internal_get_tmp_var (val, pre_p, NULL, true, true);
666 /* Return a temporary variable initialized with VAL. PRE_P and POST_P
667 are as in gimplify_expr. */
669 tree
670 get_initialized_tmp_var (tree val, gimple_seq *pre_p,
671 gimple_seq *post_p /* = NULL */,
672 bool allow_ssa /* = true */)
674 return internal_get_tmp_var (val, pre_p, post_p, false, allow_ssa);
677 /* Declare all the variables in VARS in SCOPE. If DEBUG_INFO is true,
678 generate debug info for them; otherwise don't. */
680 void
681 declare_vars (tree vars, gimple *gs, bool debug_info)
683 tree last = vars;
684 if (last)
686 tree temps, block;
688 gbind *scope = as_a <gbind *> (gs);
690 temps = nreverse (last);
692 block = gimple_bind_block (scope);
693 gcc_assert (!block || TREE_CODE (block) == BLOCK);
694 if (!block || !debug_info)
696 DECL_CHAIN (last) = gimple_bind_vars (scope);
697 gimple_bind_set_vars (scope, temps);
699 else
701 /* We need to attach the nodes both to the BIND_EXPR and to its
702 associated BLOCK for debugging purposes. The key point here
703 is that the BLOCK_VARS of the BIND_EXPR_BLOCK of a BIND_EXPR
704 is a subchain of the BIND_EXPR_VARS of the BIND_EXPR. */
705 if (BLOCK_VARS (block))
706 BLOCK_VARS (block) = chainon (BLOCK_VARS (block), temps);
707 else
709 gimple_bind_set_vars (scope,
710 chainon (gimple_bind_vars (scope), temps));
711 BLOCK_VARS (block) = temps;
717 /* For VAR a VAR_DECL of variable size, try to find a constant upper bound
718 for the size and adjust DECL_SIZE/DECL_SIZE_UNIT accordingly. Abort if
719 no such upper bound can be obtained. */
721 static void
722 force_constant_size (tree var)
724 /* The only attempt we make is by querying the maximum size of objects
725 of the variable's type. */
727 HOST_WIDE_INT max_size;
729 gcc_assert (VAR_P (var));
731 max_size = max_int_size_in_bytes (TREE_TYPE (var));
733 gcc_assert (max_size >= 0);
735 DECL_SIZE_UNIT (var)
736 = build_int_cst (TREE_TYPE (DECL_SIZE_UNIT (var)), max_size);
737 DECL_SIZE (var)
738 = build_int_cst (TREE_TYPE (DECL_SIZE (var)), max_size * BITS_PER_UNIT);
741 /* Push the temporary variable TMP into the current binding. */
743 void
744 gimple_add_tmp_var_fn (struct function *fn, tree tmp)
746 gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
748 /* Later processing assumes that the object size is constant, which might
749 not be true at this point. Force the use of a constant upper bound in
750 this case. */
751 if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp)))
752 force_constant_size (tmp);
754 DECL_CONTEXT (tmp) = fn->decl;
755 DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
757 record_vars_into (tmp, fn->decl);
760 /* Push the temporary variable TMP into the current binding. */
762 void
763 gimple_add_tmp_var (tree tmp)
765 gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
767 /* Later processing assumes that the object size is constant, which might
768 not be true at this point. Force the use of a constant upper bound in
769 this case. */
770 if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp)))
771 force_constant_size (tmp);
773 DECL_CONTEXT (tmp) = current_function_decl;
774 DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
776 if (gimplify_ctxp)
778 DECL_CHAIN (tmp) = gimplify_ctxp->temps;
779 gimplify_ctxp->temps = tmp;
781 /* Mark temporaries local within the nearest enclosing parallel. */
782 if (gimplify_omp_ctxp)
784 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
785 int flag = GOVD_LOCAL;
786 while (ctx
787 && (ctx->region_type == ORT_WORKSHARE
788 || ctx->region_type == ORT_TASKGROUP
789 || ctx->region_type == ORT_SIMD
790 || ctx->region_type == ORT_ACC))
792 if (ctx->region_type == ORT_SIMD
793 && TREE_ADDRESSABLE (tmp)
794 && !TREE_STATIC (tmp))
796 if (TREE_CODE (DECL_SIZE_UNIT (tmp)) != INTEGER_CST)
797 ctx->add_safelen1 = true;
798 else
799 flag = GOVD_PRIVATE;
800 break;
802 ctx = ctx->outer_context;
804 if (ctx)
805 omp_add_variable (ctx, tmp, flag | GOVD_SEEN);
808 else if (cfun)
809 record_vars (tmp);
810 else
812 gimple_seq body_seq;
814 /* This case is for nested functions. We need to expose the locals
815 they create. */
816 body_seq = gimple_body (current_function_decl);
817 declare_vars (tmp, gimple_seq_first_stmt (body_seq), false);
823 /* This page contains routines to unshare tree nodes, i.e. to duplicate tree
824 nodes that are referenced more than once in GENERIC functions. This is
825 necessary because gimplification (translation into GIMPLE) is performed
826 by modifying tree nodes in-place, so gimplication of a shared node in a
827 first context could generate an invalid GIMPLE form in a second context.
829 This is achieved with a simple mark/copy/unmark algorithm that walks the
830 GENERIC representation top-down, marks nodes with TREE_VISITED the first
831 time it encounters them, duplicates them if they already have TREE_VISITED
832 set, and finally removes the TREE_VISITED marks it has set.
834 The algorithm works only at the function level, i.e. it generates a GENERIC
835 representation of a function with no nodes shared within the function when
836 passed a GENERIC function (except for nodes that are allowed to be shared).
838 At the global level, it is also necessary to unshare tree nodes that are
839 referenced in more than one function, for the same aforementioned reason.
840 This requires some cooperation from the front-end. There are 2 strategies:
842 1. Manual unsharing. The front-end needs to call unshare_expr on every
843 expression that might end up being shared across functions.
845 2. Deep unsharing. This is an extension of regular unsharing. Instead
846 of calling unshare_expr on expressions that might be shared across
847 functions, the front-end pre-marks them with TREE_VISITED. This will
848 ensure that they are unshared on the first reference within functions
849 when the regular unsharing algorithm runs. The counterpart is that
850 this algorithm must look deeper than for manual unsharing, which is
851 specified by LANG_HOOKS_DEEP_UNSHARING.
853 If there are only few specific cases of node sharing across functions, it is
854 probably easier for a front-end to unshare the expressions manually. On the
855 contrary, if the expressions generated at the global level are as widespread
856 as expressions generated within functions, deep unsharing is very likely the
857 way to go. */
859 /* Similar to copy_tree_r but do not copy SAVE_EXPR or TARGET_EXPR nodes.
860 These nodes model computations that must be done once. If we were to
861 unshare something like SAVE_EXPR(i++), the gimplification process would
862 create wrong code. However, if DATA is non-null, it must hold a pointer
863 set that is used to unshare the subtrees of these nodes. */
865 static tree
866 mostly_copy_tree_r (tree *tp, int *walk_subtrees, void *data)
868 tree t = *tp;
869 enum tree_code code = TREE_CODE (t);
871 /* Do not copy SAVE_EXPR, TARGET_EXPR or BIND_EXPR nodes themselves, but
872 copy their subtrees if we can make sure to do it only once. */
873 if (code == SAVE_EXPR || code == TARGET_EXPR || code == BIND_EXPR)
875 if (data && !((hash_set<tree> *)data)->add (t))
877 else
878 *walk_subtrees = 0;
881 /* Stop at types, decls, constants like copy_tree_r. */
882 else if (TREE_CODE_CLASS (code) == tcc_type
883 || TREE_CODE_CLASS (code) == tcc_declaration
884 || TREE_CODE_CLASS (code) == tcc_constant)
885 *walk_subtrees = 0;
887 /* Cope with the statement expression extension. */
888 else if (code == STATEMENT_LIST)
891 /* Leave the bulk of the work to copy_tree_r itself. */
892 else
893 copy_tree_r (tp, walk_subtrees, NULL);
895 return NULL_TREE;
898 /* Callback for walk_tree to unshare most of the shared trees rooted at *TP.
899 If *TP has been visited already, then *TP is deeply copied by calling
900 mostly_copy_tree_r. DATA is passed to mostly_copy_tree_r unmodified. */
902 static tree
903 copy_if_shared_r (tree *tp, int *walk_subtrees, void *data)
905 tree t = *tp;
906 enum tree_code code = TREE_CODE (t);
908 /* Skip types, decls, and constants. But we do want to look at their
909 types and the bounds of types. Mark them as visited so we properly
910 unmark their subtrees on the unmark pass. If we've already seen them,
911 don't look down further. */
912 if (TREE_CODE_CLASS (code) == tcc_type
913 || TREE_CODE_CLASS (code) == tcc_declaration
914 || TREE_CODE_CLASS (code) == tcc_constant)
916 if (TREE_VISITED (t))
917 *walk_subtrees = 0;
918 else
919 TREE_VISITED (t) = 1;
922 /* If this node has been visited already, unshare it and don't look
923 any deeper. */
924 else if (TREE_VISITED (t))
926 walk_tree (tp, mostly_copy_tree_r, data, NULL);
927 *walk_subtrees = 0;
930 /* Otherwise, mark the node as visited and keep looking. */
931 else
932 TREE_VISITED (t) = 1;
934 return NULL_TREE;
937 /* Unshare most of the shared trees rooted at *TP. DATA is passed to the
938 copy_if_shared_r callback unmodified. */
940 void
941 copy_if_shared (tree *tp, void *data)
943 walk_tree (tp, copy_if_shared_r, data, NULL);
946 /* Unshare all the trees in the body of FNDECL, as well as in the bodies of
947 any nested functions. */
949 static void
950 unshare_body (tree fndecl)
952 struct cgraph_node *cgn = cgraph_node::get (fndecl);
953 /* If the language requires deep unsharing, we need a pointer set to make
954 sure we don't repeatedly unshare subtrees of unshareable nodes. */
955 hash_set<tree> *visited
956 = lang_hooks.deep_unsharing ? new hash_set<tree> : NULL;
958 copy_if_shared (&DECL_SAVED_TREE (fndecl), visited);
959 copy_if_shared (&DECL_SIZE (DECL_RESULT (fndecl)), visited);
960 copy_if_shared (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)), visited);
962 delete visited;
964 if (cgn)
965 for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
966 unshare_body (cgn->decl);
969 /* Callback for walk_tree to unmark the visited trees rooted at *TP.
970 Subtrees are walked until the first unvisited node is encountered. */
972 static tree
973 unmark_visited_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
975 tree t = *tp;
977 /* If this node has been visited, unmark it and keep looking. */
978 if (TREE_VISITED (t))
979 TREE_VISITED (t) = 0;
981 /* Otherwise, don't look any deeper. */
982 else
983 *walk_subtrees = 0;
985 return NULL_TREE;
988 /* Unmark the visited trees rooted at *TP. */
990 static inline void
991 unmark_visited (tree *tp)
993 walk_tree (tp, unmark_visited_r, NULL, NULL);
996 /* Likewise, but mark all trees as not visited. */
998 static void
999 unvisit_body (tree fndecl)
1001 struct cgraph_node *cgn = cgraph_node::get (fndecl);
1003 unmark_visited (&DECL_SAVED_TREE (fndecl));
1004 unmark_visited (&DECL_SIZE (DECL_RESULT (fndecl)));
1005 unmark_visited (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)));
1007 if (cgn)
1008 for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
1009 unvisit_body (cgn->decl);
1012 /* Unconditionally make an unshared copy of EXPR. This is used when using
1013 stored expressions which span multiple functions, such as BINFO_VTABLE,
1014 as the normal unsharing process can't tell that they're shared. */
1016 tree
1017 unshare_expr (tree expr)
1019 walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
1020 return expr;
1023 /* Worker for unshare_expr_without_location. */
1025 static tree
1026 prune_expr_location (tree *tp, int *walk_subtrees, void *)
1028 if (EXPR_P (*tp))
1029 SET_EXPR_LOCATION (*tp, UNKNOWN_LOCATION);
1030 else
1031 *walk_subtrees = 0;
1032 return NULL_TREE;
1035 /* Similar to unshare_expr but also prune all expression locations
1036 from EXPR. */
1038 tree
1039 unshare_expr_without_location (tree expr)
1041 walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
1042 if (EXPR_P (expr))
1043 walk_tree (&expr, prune_expr_location, NULL, NULL);
1044 return expr;
1047 /* Return the EXPR_LOCATION of EXPR, if it (maybe recursively) has
1048 one, OR_ELSE otherwise. The location of a STATEMENT_LISTs
1049 comprising at least one DEBUG_BEGIN_STMT followed by exactly one
1050 EXPR is the location of the EXPR. */
1052 static location_t
1053 rexpr_location (tree expr, location_t or_else = UNKNOWN_LOCATION)
1055 if (!expr)
1056 return or_else;
1058 if (EXPR_HAS_LOCATION (expr))
1059 return EXPR_LOCATION (expr);
1061 if (TREE_CODE (expr) != STATEMENT_LIST)
1062 return or_else;
1064 tree_stmt_iterator i = tsi_start (expr);
1066 bool found = false;
1067 while (!tsi_end_p (i) && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT)
1069 found = true;
1070 tsi_next (&i);
1073 if (!found || !tsi_one_before_end_p (i))
1074 return or_else;
1076 return rexpr_location (tsi_stmt (i), or_else);
1079 /* Return TRUE iff EXPR (maybe recursively) has a location; see
1080 rexpr_location for the potential recursion. */
1082 static inline bool
1083 rexpr_has_location (tree expr)
1085 return rexpr_location (expr) != UNKNOWN_LOCATION;
1089 /* WRAPPER is a code such as BIND_EXPR or CLEANUP_POINT_EXPR which can both
1090 contain statements and have a value. Assign its value to a temporary
1091 and give it void_type_node. Return the temporary, or NULL_TREE if
1092 WRAPPER was already void. */
1094 tree
1095 voidify_wrapper_expr (tree wrapper, tree temp)
1097 tree type = TREE_TYPE (wrapper);
1098 if (type && !VOID_TYPE_P (type))
1100 tree *p;
1102 /* Set p to point to the body of the wrapper. Loop until we find
1103 something that isn't a wrapper. */
1104 for (p = &wrapper; p && *p; )
1106 switch (TREE_CODE (*p))
1108 case BIND_EXPR:
1109 TREE_SIDE_EFFECTS (*p) = 1;
1110 TREE_TYPE (*p) = void_type_node;
1111 /* For a BIND_EXPR, the body is operand 1. */
1112 p = &BIND_EXPR_BODY (*p);
1113 break;
1115 case CLEANUP_POINT_EXPR:
1116 case TRY_FINALLY_EXPR:
1117 case TRY_CATCH_EXPR:
1118 TREE_SIDE_EFFECTS (*p) = 1;
1119 TREE_TYPE (*p) = void_type_node;
1120 p = &TREE_OPERAND (*p, 0);
1121 break;
1123 case STATEMENT_LIST:
1125 tree_stmt_iterator i = tsi_last (*p);
1126 TREE_SIDE_EFFECTS (*p) = 1;
1127 TREE_TYPE (*p) = void_type_node;
1128 p = tsi_end_p (i) ? NULL : tsi_stmt_ptr (i);
1130 break;
1132 case COMPOUND_EXPR:
1133 /* Advance to the last statement. Set all container types to
1134 void. */
1135 for (; TREE_CODE (*p) == COMPOUND_EXPR; p = &TREE_OPERAND (*p, 1))
1137 TREE_SIDE_EFFECTS (*p) = 1;
1138 TREE_TYPE (*p) = void_type_node;
1140 break;
1142 case TRANSACTION_EXPR:
1143 TREE_SIDE_EFFECTS (*p) = 1;
1144 TREE_TYPE (*p) = void_type_node;
1145 p = &TRANSACTION_EXPR_BODY (*p);
1146 break;
1148 default:
1149 /* Assume that any tree upon which voidify_wrapper_expr is
1150 directly called is a wrapper, and that its body is op0. */
1151 if (p == &wrapper)
1153 TREE_SIDE_EFFECTS (*p) = 1;
1154 TREE_TYPE (*p) = void_type_node;
1155 p = &TREE_OPERAND (*p, 0);
1156 break;
1158 goto out;
1162 out:
1163 if (p == NULL || IS_EMPTY_STMT (*p))
1164 temp = NULL_TREE;
1165 else if (temp)
1167 /* The wrapper is on the RHS of an assignment that we're pushing
1168 down. */
1169 gcc_assert (TREE_CODE (temp) == INIT_EXPR
1170 || TREE_CODE (temp) == MODIFY_EXPR);
1171 TREE_OPERAND (temp, 1) = *p;
1172 *p = temp;
1174 else
1176 temp = create_tmp_var (type, "retval");
1177 *p = build2 (INIT_EXPR, type, temp, *p);
1180 return temp;
1183 return NULL_TREE;
1186 /* Prepare calls to builtins to SAVE and RESTORE the stack as well as
1187 a temporary through which they communicate. */
1189 static void
1190 build_stack_save_restore (gcall **save, gcall **restore)
1192 tree tmp_var;
1194 *save = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_SAVE), 0);
1195 tmp_var = create_tmp_var (ptr_type_node, "saved_stack");
1196 gimple_call_set_lhs (*save, tmp_var);
1198 *restore
1199 = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_RESTORE),
1200 1, tmp_var);
1203 /* Generate IFN_ASAN_MARK call that poisons shadow of a for DECL variable. */
1205 static tree
1206 build_asan_poison_call_expr (tree decl)
1208 /* Do not poison variables that have size equal to zero. */
1209 tree unit_size = DECL_SIZE_UNIT (decl);
1210 if (zerop (unit_size))
1211 return NULL_TREE;
1213 tree base = build_fold_addr_expr (decl);
1215 return build_call_expr_internal_loc (UNKNOWN_LOCATION, IFN_ASAN_MARK,
1216 void_type_node, 3,
1217 build_int_cst (integer_type_node,
1218 ASAN_MARK_POISON),
1219 base, unit_size);
1222 /* Generate IFN_ASAN_MARK call that would poison or unpoison, depending
1223 on POISON flag, shadow memory of a DECL variable. The call will be
1224 put on location identified by IT iterator, where BEFORE flag drives
1225 position where the stmt will be put. */
1227 static void
1228 asan_poison_variable (tree decl, bool poison, gimple_stmt_iterator *it,
1229 bool before)
1231 tree unit_size = DECL_SIZE_UNIT (decl);
1232 tree base = build_fold_addr_expr (decl);
1234 /* Do not poison variables that have size equal to zero. */
1235 if (zerop (unit_size))
1236 return;
1238 /* It's necessary to have all stack variables aligned to ASAN granularity
1239 bytes. */
1240 if (DECL_ALIGN_UNIT (decl) <= ASAN_SHADOW_GRANULARITY)
1241 SET_DECL_ALIGN (decl, BITS_PER_UNIT * ASAN_SHADOW_GRANULARITY);
1243 HOST_WIDE_INT flags = poison ? ASAN_MARK_POISON : ASAN_MARK_UNPOISON;
1245 gimple *g
1246 = gimple_build_call_internal (IFN_ASAN_MARK, 3,
1247 build_int_cst (integer_type_node, flags),
1248 base, unit_size);
1250 if (before)
1251 gsi_insert_before (it, g, GSI_NEW_STMT);
1252 else
1253 gsi_insert_after (it, g, GSI_NEW_STMT);
1256 /* Generate IFN_ASAN_MARK internal call that depending on POISON flag
1257 either poisons or unpoisons a DECL. Created statement is appended
1258 to SEQ_P gimple sequence. */
1260 static void
1261 asan_poison_variable (tree decl, bool poison, gimple_seq *seq_p)
1263 gimple_stmt_iterator it = gsi_last (*seq_p);
1264 bool before = false;
1266 if (gsi_end_p (it))
1267 before = true;
1269 asan_poison_variable (decl, poison, &it, before);
1272 /* Sort pair of VAR_DECLs A and B by DECL_UID. */
1274 static int
1275 sort_by_decl_uid (const void *a, const void *b)
1277 const tree *t1 = (const tree *)a;
1278 const tree *t2 = (const tree *)b;
1280 int uid1 = DECL_UID (*t1);
1281 int uid2 = DECL_UID (*t2);
1283 if (uid1 < uid2)
1284 return -1;
1285 else if (uid1 > uid2)
1286 return 1;
1287 else
1288 return 0;
1291 /* Generate IFN_ASAN_MARK internal call for all VARIABLES
1292 depending on POISON flag. Created statement is appended
1293 to SEQ_P gimple sequence. */
1295 static void
1296 asan_poison_variables (hash_set<tree> *variables, bool poison, gimple_seq *seq_p)
1298 unsigned c = variables->elements ();
1299 if (c == 0)
1300 return;
1302 auto_vec<tree> sorted_variables (c);
1304 for (hash_set<tree>::iterator it = variables->begin ();
1305 it != variables->end (); ++it)
1306 sorted_variables.safe_push (*it);
1308 sorted_variables.qsort (sort_by_decl_uid);
1310 unsigned i;
1311 tree var;
1312 FOR_EACH_VEC_ELT (sorted_variables, i, var)
1314 asan_poison_variable (var, poison, seq_p);
1316 /* Add use_after_scope_memory attribute for the variable in order
1317 to prevent re-written into SSA. */
1318 if (!lookup_attribute (ASAN_USE_AFTER_SCOPE_ATTRIBUTE,
1319 DECL_ATTRIBUTES (var)))
1320 DECL_ATTRIBUTES (var)
1321 = tree_cons (get_identifier (ASAN_USE_AFTER_SCOPE_ATTRIBUTE),
1322 integer_one_node,
1323 DECL_ATTRIBUTES (var));
1327 /* Gimplify a BIND_EXPR. Just voidify and recurse. */
1329 static enum gimplify_status
1330 gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p)
1332 tree bind_expr = *expr_p;
1333 bool old_keep_stack = gimplify_ctxp->keep_stack;
1334 bool old_save_stack = gimplify_ctxp->save_stack;
1335 tree t;
1336 gbind *bind_stmt;
1337 gimple_seq body, cleanup;
1338 gcall *stack_save;
1339 location_t start_locus = 0, end_locus = 0;
1340 tree ret_clauses = NULL;
1342 tree temp = voidify_wrapper_expr (bind_expr, NULL);
1344 /* Mark variables seen in this bind expr. */
1345 for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t))
1347 if (VAR_P (t))
1349 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
1351 /* Mark variable as local. */
1352 if (ctx && ctx->region_type != ORT_NONE && !DECL_EXTERNAL (t))
1354 if (! DECL_SEEN_IN_BIND_EXPR_P (t)
1355 || splay_tree_lookup (ctx->variables,
1356 (splay_tree_key) t) == NULL)
1358 int flag = GOVD_LOCAL;
1359 if (ctx->region_type == ORT_SIMD
1360 && TREE_ADDRESSABLE (t)
1361 && !TREE_STATIC (t))
1363 if (TREE_CODE (DECL_SIZE_UNIT (t)) != INTEGER_CST)
1364 ctx->add_safelen1 = true;
1365 else
1366 flag = GOVD_PRIVATE;
1368 omp_add_variable (ctx, t, flag | GOVD_SEEN);
1370 /* Static locals inside of target construct or offloaded
1371 routines need to be "omp declare target". */
1372 if (TREE_STATIC (t))
1373 for (; ctx; ctx = ctx->outer_context)
1374 if ((ctx->region_type & ORT_TARGET) != 0)
1376 if (!lookup_attribute ("omp declare target",
1377 DECL_ATTRIBUTES (t)))
1379 tree id = get_identifier ("omp declare target");
1380 DECL_ATTRIBUTES (t)
1381 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
1382 varpool_node *node = varpool_node::get (t);
1383 if (node)
1385 node->offloadable = 1;
1386 if (ENABLE_OFFLOADING && !DECL_EXTERNAL (t))
1388 g->have_offload = true;
1389 if (!in_lto_p)
1390 vec_safe_push (offload_vars, t);
1394 break;
1398 DECL_SEEN_IN_BIND_EXPR_P (t) = 1;
1400 if (DECL_HARD_REGISTER (t) && !is_global_var (t) && cfun)
1401 cfun->has_local_explicit_reg_vars = true;
1404 /* Preliminarily mark non-addressed complex variables as eligible
1405 for promotion to gimple registers. We'll transform their uses
1406 as we find them. */
1407 if ((TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE
1408 || TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
1409 && !TREE_THIS_VOLATILE (t)
1410 && (VAR_P (t) && !DECL_HARD_REGISTER (t))
1411 && !needs_to_live_in_memory (t))
1412 DECL_GIMPLE_REG_P (t) = 1;
1415 bind_stmt = gimple_build_bind (BIND_EXPR_VARS (bind_expr), NULL,
1416 BIND_EXPR_BLOCK (bind_expr));
1417 gimple_push_bind_expr (bind_stmt);
1419 gimplify_ctxp->keep_stack = false;
1420 gimplify_ctxp->save_stack = false;
1422 /* Gimplify the body into the GIMPLE_BIND tuple's body. */
1423 body = NULL;
1424 gimplify_stmt (&BIND_EXPR_BODY (bind_expr), &body);
1425 gimple_bind_set_body (bind_stmt, body);
1427 /* Source location wise, the cleanup code (stack_restore and clobbers)
1428 belongs to the end of the block, so propagate what we have. The
1429 stack_save operation belongs to the beginning of block, which we can
1430 infer from the bind_expr directly if the block has no explicit
1431 assignment. */
1432 if (BIND_EXPR_BLOCK (bind_expr))
1434 end_locus = BLOCK_SOURCE_END_LOCATION (BIND_EXPR_BLOCK (bind_expr));
1435 start_locus = BLOCK_SOURCE_LOCATION (BIND_EXPR_BLOCK (bind_expr));
1437 if (start_locus == 0)
1438 start_locus = EXPR_LOCATION (bind_expr);
1440 cleanup = NULL;
1441 stack_save = NULL;
1443 /* If the code both contains VLAs and calls alloca, then we cannot reclaim
1444 the stack space allocated to the VLAs. */
1445 if (gimplify_ctxp->save_stack && !gimplify_ctxp->keep_stack)
1447 gcall *stack_restore;
1449 /* Save stack on entry and restore it on exit. Add a try_finally
1450 block to achieve this. */
1451 build_stack_save_restore (&stack_save, &stack_restore);
1453 gimple_set_location (stack_save, start_locus);
1454 gimple_set_location (stack_restore, end_locus);
1456 gimplify_seq_add_stmt (&cleanup, stack_restore);
1459 /* Add clobbers for all variables that go out of scope. */
1460 for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t))
1462 if (VAR_P (t)
1463 && !is_global_var (t)
1464 && DECL_CONTEXT (t) == current_function_decl)
1466 if (!DECL_HARD_REGISTER (t)
1467 && !TREE_THIS_VOLATILE (t)
1468 && !DECL_HAS_VALUE_EXPR_P (t)
1469 /* Only care for variables that have to be in memory. Others
1470 will be rewritten into SSA names, hence moved to the
1471 top-level. */
1472 && !is_gimple_reg (t)
1473 && flag_stack_reuse != SR_NONE)
1475 tree clobber = build_clobber (TREE_TYPE (t));
1476 gimple *clobber_stmt;
1477 clobber_stmt = gimple_build_assign (t, clobber);
1478 gimple_set_location (clobber_stmt, end_locus);
1479 gimplify_seq_add_stmt (&cleanup, clobber_stmt);
1482 if (flag_openacc && oacc_declare_returns != NULL)
1484 tree *c = oacc_declare_returns->get (t);
1485 if (c != NULL)
1487 if (ret_clauses)
1488 OMP_CLAUSE_CHAIN (*c) = ret_clauses;
1490 ret_clauses = *c;
1492 oacc_declare_returns->remove (t);
1494 if (oacc_declare_returns->is_empty ())
1496 delete oacc_declare_returns;
1497 oacc_declare_returns = NULL;
1503 if (asan_poisoned_variables != NULL
1504 && asan_poisoned_variables->contains (t))
1506 asan_poisoned_variables->remove (t);
1507 asan_poison_variable (t, true, &cleanup);
1510 if (gimplify_ctxp->live_switch_vars != NULL
1511 && gimplify_ctxp->live_switch_vars->contains (t))
1512 gimplify_ctxp->live_switch_vars->remove (t);
1515 if (ret_clauses)
1517 gomp_target *stmt;
1518 gimple_stmt_iterator si = gsi_start (cleanup);
1520 stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
1521 ret_clauses);
1522 gsi_insert_seq_before_without_update (&si, stmt, GSI_NEW_STMT);
1525 if (cleanup)
1527 gtry *gs;
1528 gimple_seq new_body;
1530 new_body = NULL;
1531 gs = gimple_build_try (gimple_bind_body (bind_stmt), cleanup,
1532 GIMPLE_TRY_FINALLY);
1534 if (stack_save)
1535 gimplify_seq_add_stmt (&new_body, stack_save);
1536 gimplify_seq_add_stmt (&new_body, gs);
1537 gimple_bind_set_body (bind_stmt, new_body);
1540 /* keep_stack propagates all the way up to the outermost BIND_EXPR. */
1541 if (!gimplify_ctxp->keep_stack)
1542 gimplify_ctxp->keep_stack = old_keep_stack;
1543 gimplify_ctxp->save_stack = old_save_stack;
1545 gimple_pop_bind_expr ();
1547 gimplify_seq_add_stmt (pre_p, bind_stmt);
1549 if (temp)
1551 *expr_p = temp;
1552 return GS_OK;
1555 *expr_p = NULL_TREE;
1556 return GS_ALL_DONE;
1559 /* Maybe add early return predict statement to PRE_P sequence. */
1561 static void
1562 maybe_add_early_return_predict_stmt (gimple_seq *pre_p)
1564 /* If we are not in a conditional context, add PREDICT statement. */
1565 if (gimple_conditional_context ())
1567 gimple *predict = gimple_build_predict (PRED_TREE_EARLY_RETURN,
1568 NOT_TAKEN);
1569 gimplify_seq_add_stmt (pre_p, predict);
1573 /* Gimplify a RETURN_EXPR. If the expression to be returned is not a
1574 GIMPLE value, it is assigned to a new temporary and the statement is
1575 re-written to return the temporary.
1577 PRE_P points to the sequence where side effects that must happen before
1578 STMT should be stored. */
1580 static enum gimplify_status
1581 gimplify_return_expr (tree stmt, gimple_seq *pre_p)
1583 greturn *ret;
1584 tree ret_expr = TREE_OPERAND (stmt, 0);
1585 tree result_decl, result;
1587 if (ret_expr == error_mark_node)
1588 return GS_ERROR;
1590 if (!ret_expr
1591 || TREE_CODE (ret_expr) == RESULT_DECL)
1593 maybe_add_early_return_predict_stmt (pre_p);
1594 greturn *ret = gimple_build_return (ret_expr);
1595 gimple_set_no_warning (ret, TREE_NO_WARNING (stmt));
1596 gimplify_seq_add_stmt (pre_p, ret);
1597 return GS_ALL_DONE;
1600 if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))))
1601 result_decl = NULL_TREE;
1602 else if (TREE_CODE (ret_expr) == COMPOUND_EXPR)
1604 /* Used in C++ for handling EH cleanup of the return value if a local
1605 cleanup throws. Assume the front-end knows what it's doing. */
1606 result_decl = DECL_RESULT (current_function_decl);
1607 /* But crash if we end up trying to modify ret_expr below. */
1608 ret_expr = NULL_TREE;
1610 else
1612 result_decl = TREE_OPERAND (ret_expr, 0);
1614 /* See through a return by reference. */
1615 if (TREE_CODE (result_decl) == INDIRECT_REF)
1616 result_decl = TREE_OPERAND (result_decl, 0);
1618 gcc_assert ((TREE_CODE (ret_expr) == MODIFY_EXPR
1619 || TREE_CODE (ret_expr) == INIT_EXPR)
1620 && TREE_CODE (result_decl) == RESULT_DECL);
1623 /* If aggregate_value_p is true, then we can return the bare RESULT_DECL.
1624 Recall that aggregate_value_p is FALSE for any aggregate type that is
1625 returned in registers. If we're returning values in registers, then
1626 we don't want to extend the lifetime of the RESULT_DECL, particularly
1627 across another call. In addition, for those aggregates for which
1628 hard_function_value generates a PARALLEL, we'll die during normal
1629 expansion of structure assignments; there's special code in expand_return
1630 to handle this case that does not exist in expand_expr. */
1631 if (!result_decl)
1632 result = NULL_TREE;
1633 else if (aggregate_value_p (result_decl, TREE_TYPE (current_function_decl)))
1635 if (!poly_int_tree_p (DECL_SIZE (result_decl)))
1637 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (result_decl)))
1638 gimplify_type_sizes (TREE_TYPE (result_decl), pre_p);
1639 /* Note that we don't use gimplify_vla_decl because the RESULT_DECL
1640 should be effectively allocated by the caller, i.e. all calls to
1641 this function must be subject to the Return Slot Optimization. */
1642 gimplify_one_sizepos (&DECL_SIZE (result_decl), pre_p);
1643 gimplify_one_sizepos (&DECL_SIZE_UNIT (result_decl), pre_p);
1645 result = result_decl;
1647 else if (gimplify_ctxp->return_temp)
1648 result = gimplify_ctxp->return_temp;
1649 else
1651 result = create_tmp_reg (TREE_TYPE (result_decl));
1653 /* ??? With complex control flow (usually involving abnormal edges),
1654 we can wind up warning about an uninitialized value for this. Due
1655 to how this variable is constructed and initialized, this is never
1656 true. Give up and never warn. */
1657 TREE_NO_WARNING (result) = 1;
1659 gimplify_ctxp->return_temp = result;
1662 /* Smash the lhs of the MODIFY_EXPR to the temporary we plan to use.
1663 Then gimplify the whole thing. */
1664 if (result != result_decl)
1665 TREE_OPERAND (ret_expr, 0) = result;
1667 gimplify_and_add (TREE_OPERAND (stmt, 0), pre_p);
1669 maybe_add_early_return_predict_stmt (pre_p);
1670 ret = gimple_build_return (result);
1671 gimple_set_no_warning (ret, TREE_NO_WARNING (stmt));
1672 gimplify_seq_add_stmt (pre_p, ret);
1674 return GS_ALL_DONE;
1677 /* Gimplify a variable-length array DECL. */
1679 static void
1680 gimplify_vla_decl (tree decl, gimple_seq *seq_p)
1682 /* This is a variable-sized decl. Simplify its size and mark it
1683 for deferred expansion. */
1684 tree t, addr, ptr_type;
1686 gimplify_one_sizepos (&DECL_SIZE (decl), seq_p);
1687 gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), seq_p);
1689 /* Don't mess with a DECL_VALUE_EXPR set by the front-end. */
1690 if (DECL_HAS_VALUE_EXPR_P (decl))
1691 return;
1693 /* All occurrences of this decl in final gimplified code will be
1694 replaced by indirection. Setting DECL_VALUE_EXPR does two
1695 things: First, it lets the rest of the gimplifier know what
1696 replacement to use. Second, it lets the debug info know
1697 where to find the value. */
1698 ptr_type = build_pointer_type (TREE_TYPE (decl));
1699 addr = create_tmp_var (ptr_type, get_name (decl));
1700 DECL_IGNORED_P (addr) = 0;
1701 t = build_fold_indirect_ref (addr);
1702 TREE_THIS_NOTRAP (t) = 1;
1703 SET_DECL_VALUE_EXPR (decl, t);
1704 DECL_HAS_VALUE_EXPR_P (decl) = 1;
1706 t = build_alloca_call_expr (DECL_SIZE_UNIT (decl), DECL_ALIGN (decl),
1707 max_int_size_in_bytes (TREE_TYPE (decl)));
1708 /* The call has been built for a variable-sized object. */
1709 CALL_ALLOCA_FOR_VAR_P (t) = 1;
1710 t = fold_convert (ptr_type, t);
1711 t = build2 (MODIFY_EXPR, TREE_TYPE (addr), addr, t);
1713 gimplify_and_add (t, seq_p);
1715 /* Record the dynamic allocation associated with DECL if requested. */
1716 if (flag_callgraph_info & CALLGRAPH_INFO_DYNAMIC_ALLOC)
1717 record_dynamic_alloc (decl);
1720 /* A helper function to be called via walk_tree. Mark all labels under *TP
1721 as being forced. To be called for DECL_INITIAL of static variables. */
1723 static tree
1724 force_labels_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
1726 if (TYPE_P (*tp))
1727 *walk_subtrees = 0;
1728 if (TREE_CODE (*tp) == LABEL_DECL)
1730 FORCED_LABEL (*tp) = 1;
1731 cfun->has_forced_label_in_static = 1;
1734 return NULL_TREE;
1737 /* Gimplify a DECL_EXPR node *STMT_P by making any necessary allocation
1738 and initialization explicit. */
1740 static enum gimplify_status
1741 gimplify_decl_expr (tree *stmt_p, gimple_seq *seq_p)
1743 tree stmt = *stmt_p;
1744 tree decl = DECL_EXPR_DECL (stmt);
1746 *stmt_p = NULL_TREE;
1748 if (TREE_TYPE (decl) == error_mark_node)
1749 return GS_ERROR;
1751 if ((TREE_CODE (decl) == TYPE_DECL
1752 || VAR_P (decl))
1753 && !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl)))
1755 gimplify_type_sizes (TREE_TYPE (decl), seq_p);
1756 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
1757 gimplify_type_sizes (TREE_TYPE (TREE_TYPE (decl)), seq_p);
1760 /* ??? DECL_ORIGINAL_TYPE is streamed for LTO so it needs to be gimplified
1761 in case its size expressions contain problematic nodes like CALL_EXPR. */
1762 if (TREE_CODE (decl) == TYPE_DECL
1763 && DECL_ORIGINAL_TYPE (decl)
1764 && !TYPE_SIZES_GIMPLIFIED (DECL_ORIGINAL_TYPE (decl)))
1766 gimplify_type_sizes (DECL_ORIGINAL_TYPE (decl), seq_p);
1767 if (TREE_CODE (DECL_ORIGINAL_TYPE (decl)) == REFERENCE_TYPE)
1768 gimplify_type_sizes (TREE_TYPE (DECL_ORIGINAL_TYPE (decl)), seq_p);
1771 if (VAR_P (decl) && !DECL_EXTERNAL (decl))
1773 tree init = DECL_INITIAL (decl);
1774 bool is_vla = false;
1776 poly_uint64 size;
1777 if (!poly_int_tree_p (DECL_SIZE_UNIT (decl), &size)
1778 || (!TREE_STATIC (decl)
1779 && flag_stack_check == GENERIC_STACK_CHECK
1780 && maybe_gt (size,
1781 (unsigned HOST_WIDE_INT) STACK_CHECK_MAX_VAR_SIZE)))
1783 gimplify_vla_decl (decl, seq_p);
1784 is_vla = true;
1787 if (asan_poisoned_variables
1788 && !is_vla
1789 && TREE_ADDRESSABLE (decl)
1790 && !TREE_STATIC (decl)
1791 && !DECL_HAS_VALUE_EXPR_P (decl)
1792 && DECL_ALIGN (decl) <= MAX_SUPPORTED_STACK_ALIGNMENT
1793 && dbg_cnt (asan_use_after_scope)
1794 && !gimplify_omp_ctxp)
1796 asan_poisoned_variables->add (decl);
1797 asan_poison_variable (decl, false, seq_p);
1798 if (!DECL_ARTIFICIAL (decl) && gimplify_ctxp->live_switch_vars)
1799 gimplify_ctxp->live_switch_vars->add (decl);
1802 /* Some front ends do not explicitly declare all anonymous
1803 artificial variables. We compensate here by declaring the
1804 variables, though it would be better if the front ends would
1805 explicitly declare them. */
1806 if (!DECL_SEEN_IN_BIND_EXPR_P (decl)
1807 && DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
1808 gimple_add_tmp_var (decl);
1810 if (init && init != error_mark_node)
1812 if (!TREE_STATIC (decl))
1814 DECL_INITIAL (decl) = NULL_TREE;
1815 init = build2 (INIT_EXPR, void_type_node, decl, init);
1816 gimplify_and_add (init, seq_p);
1817 ggc_free (init);
1819 else
1820 /* We must still examine initializers for static variables
1821 as they may contain a label address. */
1822 walk_tree (&init, force_labels_r, NULL, NULL);
1826 return GS_ALL_DONE;
1829 /* Gimplify a LOOP_EXPR. Normally this just involves gimplifying the body
1830 and replacing the LOOP_EXPR with goto, but if the loop contains an
1831 EXIT_EXPR, we need to append a label for it to jump to. */
1833 static enum gimplify_status
1834 gimplify_loop_expr (tree *expr_p, gimple_seq *pre_p)
1836 tree saved_label = gimplify_ctxp->exit_label;
1837 tree start_label = create_artificial_label (UNKNOWN_LOCATION);
1839 gimplify_seq_add_stmt (pre_p, gimple_build_label (start_label));
1841 gimplify_ctxp->exit_label = NULL_TREE;
1843 gimplify_and_add (LOOP_EXPR_BODY (*expr_p), pre_p);
1845 gimplify_seq_add_stmt (pre_p, gimple_build_goto (start_label));
1847 if (gimplify_ctxp->exit_label)
1848 gimplify_seq_add_stmt (pre_p,
1849 gimple_build_label (gimplify_ctxp->exit_label));
1851 gimplify_ctxp->exit_label = saved_label;
1853 *expr_p = NULL;
1854 return GS_ALL_DONE;
1857 /* Gimplify a statement list onto a sequence. These may be created either
1858 by an enlightened front-end, or by shortcut_cond_expr. */
1860 static enum gimplify_status
1861 gimplify_statement_list (tree *expr_p, gimple_seq *pre_p)
1863 tree temp = voidify_wrapper_expr (*expr_p, NULL);
1865 tree_stmt_iterator i = tsi_start (*expr_p);
1867 while (!tsi_end_p (i))
1869 gimplify_stmt (tsi_stmt_ptr (i), pre_p);
1870 tsi_delink (&i);
1873 if (temp)
1875 *expr_p = temp;
1876 return GS_OK;
1879 return GS_ALL_DONE;
1882 /* Callback for walk_gimple_seq. */
1884 static tree
1885 warn_switch_unreachable_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
1886 struct walk_stmt_info *wi)
1888 gimple *stmt = gsi_stmt (*gsi_p);
1890 *handled_ops_p = true;
1891 switch (gimple_code (stmt))
1893 case GIMPLE_TRY:
1894 /* A compiler-generated cleanup or a user-written try block.
1895 If it's empty, don't dive into it--that would result in
1896 worse location info. */
1897 if (gimple_try_eval (stmt) == NULL)
1899 wi->info = stmt;
1900 return integer_zero_node;
1902 /* Fall through. */
1903 case GIMPLE_BIND:
1904 case GIMPLE_CATCH:
1905 case GIMPLE_EH_FILTER:
1906 case GIMPLE_TRANSACTION:
1907 /* Walk the sub-statements. */
1908 *handled_ops_p = false;
1909 break;
1911 case GIMPLE_DEBUG:
1912 /* Ignore these. We may generate them before declarations that
1913 are never executed. If there's something to warn about,
1914 there will be non-debug stmts too, and we'll catch those. */
1915 break;
1917 case GIMPLE_CALL:
1918 if (gimple_call_internal_p (stmt, IFN_ASAN_MARK))
1920 *handled_ops_p = false;
1921 break;
1923 /* Fall through. */
1924 default:
1925 /* Save the first "real" statement (not a decl/lexical scope/...). */
1926 wi->info = stmt;
1927 return integer_zero_node;
1929 return NULL_TREE;
1932 /* Possibly warn about unreachable statements between switch's controlling
1933 expression and the first case. SEQ is the body of a switch expression. */
1935 static void
1936 maybe_warn_switch_unreachable (gimple_seq seq)
1938 if (!warn_switch_unreachable
1939 /* This warning doesn't play well with Fortran when optimizations
1940 are on. */
1941 || lang_GNU_Fortran ()
1942 || seq == NULL)
1943 return;
1945 struct walk_stmt_info wi;
1946 memset (&wi, 0, sizeof (wi));
1947 walk_gimple_seq (seq, warn_switch_unreachable_r, NULL, &wi);
1948 gimple *stmt = (gimple *) wi.info;
1950 if (stmt && gimple_code (stmt) != GIMPLE_LABEL)
1952 if (gimple_code (stmt) == GIMPLE_GOTO
1953 && TREE_CODE (gimple_goto_dest (stmt)) == LABEL_DECL
1954 && DECL_ARTIFICIAL (gimple_goto_dest (stmt)))
1955 /* Don't warn for compiler-generated gotos. These occur
1956 in Duff's devices, for example. */;
1957 else
1958 warning_at (gimple_location (stmt), OPT_Wswitch_unreachable,
1959 "statement will never be executed");
1964 /* A label entry that pairs label and a location. */
1965 struct label_entry
1967 tree label;
1968 location_t loc;
1971 /* Find LABEL in vector of label entries VEC. */
1973 static struct label_entry *
1974 find_label_entry (const auto_vec<struct label_entry> *vec, tree label)
1976 unsigned int i;
1977 struct label_entry *l;
1979 FOR_EACH_VEC_ELT (*vec, i, l)
1980 if (l->label == label)
1981 return l;
1982 return NULL;
1985 /* Return true if LABEL, a LABEL_DECL, represents a case label
1986 in a vector of labels CASES. */
1988 static bool
1989 case_label_p (const vec<tree> *cases, tree label)
1991 unsigned int i;
1992 tree l;
1994 FOR_EACH_VEC_ELT (*cases, i, l)
1995 if (CASE_LABEL (l) == label)
1996 return true;
1997 return false;
2000 /* Find the last nondebug statement in a scope STMT. */
2002 static gimple *
2003 last_stmt_in_scope (gimple *stmt)
2005 if (!stmt)
2006 return NULL;
2008 switch (gimple_code (stmt))
2010 case GIMPLE_BIND:
2012 gbind *bind = as_a <gbind *> (stmt);
2013 stmt = gimple_seq_last_nondebug_stmt (gimple_bind_body (bind));
2014 return last_stmt_in_scope (stmt);
2017 case GIMPLE_TRY:
2019 gtry *try_stmt = as_a <gtry *> (stmt);
2020 stmt = gimple_seq_last_nondebug_stmt (gimple_try_eval (try_stmt));
2021 gimple *last_eval = last_stmt_in_scope (stmt);
2022 if (gimple_stmt_may_fallthru (last_eval)
2023 && (last_eval == NULL
2024 || !gimple_call_internal_p (last_eval, IFN_FALLTHROUGH))
2025 && gimple_try_kind (try_stmt) == GIMPLE_TRY_FINALLY)
2027 stmt = gimple_seq_last_nondebug_stmt (gimple_try_cleanup (try_stmt));
2028 return last_stmt_in_scope (stmt);
2030 else
2031 return last_eval;
2034 case GIMPLE_DEBUG:
2035 gcc_unreachable ();
2037 default:
2038 return stmt;
2042 /* Collect interesting labels in LABELS and return the statement preceding
2043 another case label, or a user-defined label. Store a location useful
2044 to give warnings at *PREVLOC (usually the location of the returned
2045 statement or of its surrounding scope). */
2047 static gimple *
2048 collect_fallthrough_labels (gimple_stmt_iterator *gsi_p,
2049 auto_vec <struct label_entry> *labels,
2050 location_t *prevloc)
2052 gimple *prev = NULL;
2054 *prevloc = UNKNOWN_LOCATION;
2057 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND)
2059 /* Recognize the special GIMPLE_BIND added by gimplify_switch_expr,
2060 which starts on a GIMPLE_SWITCH and ends with a break label.
2061 Handle that as a single statement that can fall through. */
2062 gbind *bind = as_a <gbind *> (gsi_stmt (*gsi_p));
2063 gimple *first = gimple_seq_first_stmt (gimple_bind_body (bind));
2064 gimple *last = gimple_seq_last_stmt (gimple_bind_body (bind));
2065 if (last
2066 && gimple_code (first) == GIMPLE_SWITCH
2067 && gimple_code (last) == GIMPLE_LABEL)
2069 tree label = gimple_label_label (as_a <glabel *> (last));
2070 if (SWITCH_BREAK_LABEL_P (label))
2072 prev = bind;
2073 gsi_next (gsi_p);
2074 continue;
2078 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND
2079 || gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_TRY)
2081 /* Nested scope. Only look at the last statement of
2082 the innermost scope. */
2083 location_t bind_loc = gimple_location (gsi_stmt (*gsi_p));
2084 gimple *last = last_stmt_in_scope (gsi_stmt (*gsi_p));
2085 if (last)
2087 prev = last;
2088 /* It might be a label without a location. Use the
2089 location of the scope then. */
2090 if (!gimple_has_location (prev))
2091 *prevloc = bind_loc;
2093 gsi_next (gsi_p);
2094 continue;
2097 /* Ifs are tricky. */
2098 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_COND)
2100 gcond *cond_stmt = as_a <gcond *> (gsi_stmt (*gsi_p));
2101 tree false_lab = gimple_cond_false_label (cond_stmt);
2102 location_t if_loc = gimple_location (cond_stmt);
2104 /* If we have e.g.
2105 if (i > 1) goto <D.2259>; else goto D;
2106 we can't do much with the else-branch. */
2107 if (!DECL_ARTIFICIAL (false_lab))
2108 break;
2110 /* Go on until the false label, then one step back. */
2111 for (; !gsi_end_p (*gsi_p); gsi_next (gsi_p))
2113 gimple *stmt = gsi_stmt (*gsi_p);
2114 if (gimple_code (stmt) == GIMPLE_LABEL
2115 && gimple_label_label (as_a <glabel *> (stmt)) == false_lab)
2116 break;
2119 /* Not found? Oops. */
2120 if (gsi_end_p (*gsi_p))
2121 break;
2123 struct label_entry l = { false_lab, if_loc };
2124 labels->safe_push (l);
2126 /* Go to the last statement of the then branch. */
2127 gsi_prev (gsi_p);
2129 /* if (i != 0) goto <D.1759>; else goto <D.1760>;
2130 <D.1759>:
2131 <stmt>;
2132 goto <D.1761>;
2133 <D.1760>:
2135 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_GOTO
2136 && !gimple_has_location (gsi_stmt (*gsi_p)))
2138 /* Look at the statement before, it might be
2139 attribute fallthrough, in which case don't warn. */
2140 gsi_prev (gsi_p);
2141 bool fallthru_before_dest
2142 = gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_FALLTHROUGH);
2143 gsi_next (gsi_p);
2144 tree goto_dest = gimple_goto_dest (gsi_stmt (*gsi_p));
2145 if (!fallthru_before_dest)
2147 struct label_entry l = { goto_dest, if_loc };
2148 labels->safe_push (l);
2151 /* And move back. */
2152 gsi_next (gsi_p);
2155 /* Remember the last statement. Skip labels that are of no interest
2156 to us. */
2157 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
2159 tree label = gimple_label_label (as_a <glabel *> (gsi_stmt (*gsi_p)));
2160 if (find_label_entry (labels, label))
2161 prev = gsi_stmt (*gsi_p);
2163 else if (gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_ASAN_MARK))
2165 else if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_PREDICT)
2167 else if (!is_gimple_debug (gsi_stmt (*gsi_p)))
2168 prev = gsi_stmt (*gsi_p);
2169 gsi_next (gsi_p);
2171 while (!gsi_end_p (*gsi_p)
2172 /* Stop if we find a case or a user-defined label. */
2173 && (gimple_code (gsi_stmt (*gsi_p)) != GIMPLE_LABEL
2174 || !gimple_has_location (gsi_stmt (*gsi_p))));
2176 if (prev && gimple_has_location (prev))
2177 *prevloc = gimple_location (prev);
2178 return prev;
2181 /* Return true if the switch fallthough warning should occur. LABEL is
2182 the label statement that we're falling through to. */
2184 static bool
2185 should_warn_for_implicit_fallthrough (gimple_stmt_iterator *gsi_p, tree label)
2187 gimple_stmt_iterator gsi = *gsi_p;
2189 /* Don't warn if the label is marked with a "falls through" comment. */
2190 if (FALLTHROUGH_LABEL_P (label))
2191 return false;
2193 /* Don't warn for non-case labels followed by a statement:
2194 case 0:
2195 foo ();
2196 label:
2197 bar ();
2198 as these are likely intentional. */
2199 if (!case_label_p (&gimplify_ctxp->case_labels, label))
2201 tree l;
2202 while (!gsi_end_p (gsi)
2203 && gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
2204 && (l = gimple_label_label (as_a <glabel *> (gsi_stmt (gsi))))
2205 && !case_label_p (&gimplify_ctxp->case_labels, l))
2206 gsi_next_nondebug (&gsi);
2207 if (gsi_end_p (gsi) || gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL)
2208 return false;
2211 /* Don't warn for terminated branches, i.e. when the subsequent case labels
2212 immediately breaks. */
2213 gsi = *gsi_p;
2215 /* Skip all immediately following labels. */
2216 while (!gsi_end_p (gsi)
2217 && (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
2218 || gimple_code (gsi_stmt (gsi)) == GIMPLE_PREDICT))
2219 gsi_next_nondebug (&gsi);
2221 /* { ... something; default:; } */
2222 if (gsi_end_p (gsi)
2223 /* { ... something; default: break; } or
2224 { ... something; default: goto L; } */
2225 || gimple_code (gsi_stmt (gsi)) == GIMPLE_GOTO
2226 /* { ... something; default: return; } */
2227 || gimple_code (gsi_stmt (gsi)) == GIMPLE_RETURN)
2228 return false;
2230 return true;
2233 /* Callback for walk_gimple_seq. */
2235 static tree
2236 warn_implicit_fallthrough_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
2237 struct walk_stmt_info *)
2239 gimple *stmt = gsi_stmt (*gsi_p);
2241 *handled_ops_p = true;
2242 switch (gimple_code (stmt))
2244 case GIMPLE_TRY:
2245 case GIMPLE_BIND:
2246 case GIMPLE_CATCH:
2247 case GIMPLE_EH_FILTER:
2248 case GIMPLE_TRANSACTION:
2249 /* Walk the sub-statements. */
2250 *handled_ops_p = false;
2251 break;
2253 /* Find a sequence of form:
2255 GIMPLE_LABEL
2256 [...]
2257 <may fallthru stmt>
2258 GIMPLE_LABEL
2260 and possibly warn. */
2261 case GIMPLE_LABEL:
2263 /* Found a label. Skip all immediately following labels. */
2264 while (!gsi_end_p (*gsi_p)
2265 && gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
2266 gsi_next_nondebug (gsi_p);
2268 /* There might be no more statements. */
2269 if (gsi_end_p (*gsi_p))
2270 return integer_zero_node;
2272 /* Vector of labels that fall through. */
2273 auto_vec <struct label_entry> labels;
2274 location_t prevloc;
2275 gimple *prev = collect_fallthrough_labels (gsi_p, &labels, &prevloc);
2277 /* There might be no more statements. */
2278 if (gsi_end_p (*gsi_p))
2279 return integer_zero_node;
2281 gimple *next = gsi_stmt (*gsi_p);
2282 tree label;
2283 /* If what follows is a label, then we may have a fallthrough. */
2284 if (gimple_code (next) == GIMPLE_LABEL
2285 && gimple_has_location (next)
2286 && (label = gimple_label_label (as_a <glabel *> (next)))
2287 && prev != NULL)
2289 struct label_entry *l;
2290 bool warned_p = false;
2291 auto_diagnostic_group d;
2292 if (!should_warn_for_implicit_fallthrough (gsi_p, label))
2293 /* Quiet. */;
2294 else if (gimple_code (prev) == GIMPLE_LABEL
2295 && (label = gimple_label_label (as_a <glabel *> (prev)))
2296 && (l = find_label_entry (&labels, label)))
2297 warned_p = warning_at (l->loc, OPT_Wimplicit_fallthrough_,
2298 "this statement may fall through");
2299 else if (!gimple_call_internal_p (prev, IFN_FALLTHROUGH)
2300 /* Try to be clever and don't warn when the statement
2301 can't actually fall through. */
2302 && gimple_stmt_may_fallthru (prev)
2303 && prevloc != UNKNOWN_LOCATION)
2304 warned_p = warning_at (prevloc,
2305 OPT_Wimplicit_fallthrough_,
2306 "this statement may fall through");
2307 if (warned_p)
2308 inform (gimple_location (next), "here");
2310 /* Mark this label as processed so as to prevent multiple
2311 warnings in nested switches. */
2312 FALLTHROUGH_LABEL_P (label) = true;
2314 /* So that next warn_implicit_fallthrough_r will start looking for
2315 a new sequence starting with this label. */
2316 gsi_prev (gsi_p);
2319 break;
2320 default:
2321 break;
2323 return NULL_TREE;
2326 /* Warn when a switch case falls through. */
2328 static void
2329 maybe_warn_implicit_fallthrough (gimple_seq seq)
2331 if (!warn_implicit_fallthrough)
2332 return;
2334 /* This warning is meant for C/C++/ObjC/ObjC++ only. */
2335 if (!(lang_GNU_C ()
2336 || lang_GNU_CXX ()
2337 || lang_GNU_OBJC ()))
2338 return;
2340 struct walk_stmt_info wi;
2341 memset (&wi, 0, sizeof (wi));
2342 walk_gimple_seq (seq, warn_implicit_fallthrough_r, NULL, &wi);
2345 /* Callback for walk_gimple_seq. */
2347 static tree
2348 expand_FALLTHROUGH_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
2349 struct walk_stmt_info *wi)
2351 gimple *stmt = gsi_stmt (*gsi_p);
2353 *handled_ops_p = true;
2354 switch (gimple_code (stmt))
2356 case GIMPLE_TRY:
2357 case GIMPLE_BIND:
2358 case GIMPLE_CATCH:
2359 case GIMPLE_EH_FILTER:
2360 case GIMPLE_TRANSACTION:
2361 /* Walk the sub-statements. */
2362 *handled_ops_p = false;
2363 break;
2364 case GIMPLE_CALL:
2365 if (gimple_call_internal_p (stmt, IFN_FALLTHROUGH))
2367 gsi_remove (gsi_p, true);
2368 if (gsi_end_p (*gsi_p))
2370 *static_cast<location_t *>(wi->info) = gimple_location (stmt);
2371 return integer_zero_node;
2374 bool found = false;
2375 location_t loc = gimple_location (stmt);
2377 gimple_stmt_iterator gsi2 = *gsi_p;
2378 stmt = gsi_stmt (gsi2);
2379 if (gimple_code (stmt) == GIMPLE_GOTO && !gimple_has_location (stmt))
2381 /* Go on until the artificial label. */
2382 tree goto_dest = gimple_goto_dest (stmt);
2383 for (; !gsi_end_p (gsi2); gsi_next (&gsi2))
2385 if (gimple_code (gsi_stmt (gsi2)) == GIMPLE_LABEL
2386 && gimple_label_label (as_a <glabel *> (gsi_stmt (gsi2)))
2387 == goto_dest)
2388 break;
2391 /* Not found? Stop. */
2392 if (gsi_end_p (gsi2))
2393 break;
2395 /* Look one past it. */
2396 gsi_next (&gsi2);
2399 /* We're looking for a case label or default label here. */
2400 while (!gsi_end_p (gsi2))
2402 stmt = gsi_stmt (gsi2);
2403 if (gimple_code (stmt) == GIMPLE_LABEL)
2405 tree label = gimple_label_label (as_a <glabel *> (stmt));
2406 if (gimple_has_location (stmt) && DECL_ARTIFICIAL (label))
2408 found = true;
2409 break;
2412 else if (gimple_call_internal_p (stmt, IFN_ASAN_MARK))
2414 else if (!is_gimple_debug (stmt))
2415 /* Anything else is not expected. */
2416 break;
2417 gsi_next (&gsi2);
2419 if (!found)
2420 pedwarn (loc, 0, "attribute %<fallthrough%> not preceding "
2421 "a case label or default label");
2423 break;
2424 default:
2425 break;
2427 return NULL_TREE;
2430 /* Expand all FALLTHROUGH () calls in SEQ. */
2432 static void
2433 expand_FALLTHROUGH (gimple_seq *seq_p)
2435 struct walk_stmt_info wi;
2436 location_t loc;
2437 memset (&wi, 0, sizeof (wi));
2438 wi.info = (void *) &loc;
2439 walk_gimple_seq_mod (seq_p, expand_FALLTHROUGH_r, NULL, &wi);
2440 if (wi.callback_result == integer_zero_node)
2441 /* We've found [[fallthrough]]; at the end of a switch, which the C++
2442 standard says is ill-formed; see [dcl.attr.fallthrough]. */
2443 pedwarn (loc, 0, "attribute %<fallthrough%> not preceding "
2444 "a case label or default label");
2448 /* Gimplify a SWITCH_EXPR, and collect the vector of labels it can
2449 branch to. */
2451 static enum gimplify_status
2452 gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p)
2454 tree switch_expr = *expr_p;
2455 gimple_seq switch_body_seq = NULL;
2456 enum gimplify_status ret;
2457 tree index_type = TREE_TYPE (switch_expr);
2458 if (index_type == NULL_TREE)
2459 index_type = TREE_TYPE (SWITCH_COND (switch_expr));
2461 ret = gimplify_expr (&SWITCH_COND (switch_expr), pre_p, NULL, is_gimple_val,
2462 fb_rvalue);
2463 if (ret == GS_ERROR || ret == GS_UNHANDLED)
2464 return ret;
2466 if (SWITCH_BODY (switch_expr))
2468 vec<tree> labels;
2469 vec<tree> saved_labels;
2470 hash_set<tree> *saved_live_switch_vars = NULL;
2471 tree default_case = NULL_TREE;
2472 gswitch *switch_stmt;
2474 /* Save old labels, get new ones from body, then restore the old
2475 labels. Save all the things from the switch body to append after. */
2476 saved_labels = gimplify_ctxp->case_labels;
2477 gimplify_ctxp->case_labels.create (8);
2479 /* Do not create live_switch_vars if SWITCH_BODY is not a BIND_EXPR. */
2480 saved_live_switch_vars = gimplify_ctxp->live_switch_vars;
2481 tree_code body_type = TREE_CODE (SWITCH_BODY (switch_expr));
2482 if (body_type == BIND_EXPR || body_type == STATEMENT_LIST)
2483 gimplify_ctxp->live_switch_vars = new hash_set<tree> (4);
2484 else
2485 gimplify_ctxp->live_switch_vars = NULL;
2487 bool old_in_switch_expr = gimplify_ctxp->in_switch_expr;
2488 gimplify_ctxp->in_switch_expr = true;
2490 gimplify_stmt (&SWITCH_BODY (switch_expr), &switch_body_seq);
2492 gimplify_ctxp->in_switch_expr = old_in_switch_expr;
2493 maybe_warn_switch_unreachable (switch_body_seq);
2494 maybe_warn_implicit_fallthrough (switch_body_seq);
2495 /* Only do this for the outermost GIMPLE_SWITCH. */
2496 if (!gimplify_ctxp->in_switch_expr)
2497 expand_FALLTHROUGH (&switch_body_seq);
2499 labels = gimplify_ctxp->case_labels;
2500 gimplify_ctxp->case_labels = saved_labels;
2502 if (gimplify_ctxp->live_switch_vars)
2504 gcc_assert (gimplify_ctxp->live_switch_vars->is_empty ());
2505 delete gimplify_ctxp->live_switch_vars;
2507 gimplify_ctxp->live_switch_vars = saved_live_switch_vars;
2509 preprocess_case_label_vec_for_gimple (labels, index_type,
2510 &default_case);
2512 bool add_bind = false;
2513 if (!default_case)
2515 glabel *new_default;
2517 default_case
2518 = build_case_label (NULL_TREE, NULL_TREE,
2519 create_artificial_label (UNKNOWN_LOCATION));
2520 if (old_in_switch_expr)
2522 SWITCH_BREAK_LABEL_P (CASE_LABEL (default_case)) = 1;
2523 add_bind = true;
2525 new_default = gimple_build_label (CASE_LABEL (default_case));
2526 gimplify_seq_add_stmt (&switch_body_seq, new_default);
2528 else if (old_in_switch_expr)
2530 gimple *last = gimple_seq_last_stmt (switch_body_seq);
2531 if (last && gimple_code (last) == GIMPLE_LABEL)
2533 tree label = gimple_label_label (as_a <glabel *> (last));
2534 if (SWITCH_BREAK_LABEL_P (label))
2535 add_bind = true;
2539 switch_stmt = gimple_build_switch (SWITCH_COND (switch_expr),
2540 default_case, labels);
2541 /* For the benefit of -Wimplicit-fallthrough, if switch_body_seq
2542 ends with a GIMPLE_LABEL holding SWITCH_BREAK_LABEL_P LABEL_DECL,
2543 wrap the GIMPLE_SWITCH up to that GIMPLE_LABEL into a GIMPLE_BIND,
2544 so that we can easily find the start and end of the switch
2545 statement. */
2546 if (add_bind)
2548 gimple_seq bind_body = NULL;
2549 gimplify_seq_add_stmt (&bind_body, switch_stmt);
2550 gimple_seq_add_seq (&bind_body, switch_body_seq);
2551 gbind *bind = gimple_build_bind (NULL_TREE, bind_body, NULL_TREE);
2552 gimple_set_location (bind, EXPR_LOCATION (switch_expr));
2553 gimplify_seq_add_stmt (pre_p, bind);
2555 else
2557 gimplify_seq_add_stmt (pre_p, switch_stmt);
2558 gimplify_seq_add_seq (pre_p, switch_body_seq);
2560 labels.release ();
2562 else
2563 gcc_unreachable ();
2565 return GS_ALL_DONE;
2568 /* Gimplify the LABEL_EXPR pointed to by EXPR_P. */
2570 static enum gimplify_status
2571 gimplify_label_expr (tree *expr_p, gimple_seq *pre_p)
2573 gcc_assert (decl_function_context (LABEL_EXPR_LABEL (*expr_p))
2574 == current_function_decl);
2576 tree label = LABEL_EXPR_LABEL (*expr_p);
2577 glabel *label_stmt = gimple_build_label (label);
2578 gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
2579 gimplify_seq_add_stmt (pre_p, label_stmt);
2581 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label)))
2582 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_COLD_LABEL,
2583 NOT_TAKEN));
2584 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label)))
2585 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_HOT_LABEL,
2586 TAKEN));
2588 return GS_ALL_DONE;
2591 /* Gimplify the CASE_LABEL_EXPR pointed to by EXPR_P. */
2593 static enum gimplify_status
2594 gimplify_case_label_expr (tree *expr_p, gimple_seq *pre_p)
2596 struct gimplify_ctx *ctxp;
2597 glabel *label_stmt;
2599 /* Invalid programs can play Duff's Device type games with, for example,
2600 #pragma omp parallel. At least in the C front end, we don't
2601 detect such invalid branches until after gimplification, in the
2602 diagnose_omp_blocks pass. */
2603 for (ctxp = gimplify_ctxp; ; ctxp = ctxp->prev_context)
2604 if (ctxp->case_labels.exists ())
2605 break;
2607 tree label = CASE_LABEL (*expr_p);
2608 label_stmt = gimple_build_label (label);
2609 gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
2610 ctxp->case_labels.safe_push (*expr_p);
2611 gimplify_seq_add_stmt (pre_p, label_stmt);
2613 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label)))
2614 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_COLD_LABEL,
2615 NOT_TAKEN));
2616 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label)))
2617 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_HOT_LABEL,
2618 TAKEN));
2620 return GS_ALL_DONE;
2623 /* Build a GOTO to the LABEL_DECL pointed to by LABEL_P, building it first
2624 if necessary. */
2626 tree
2627 build_and_jump (tree *label_p)
2629 if (label_p == NULL)
2630 /* If there's nowhere to jump, just fall through. */
2631 return NULL_TREE;
2633 if (*label_p == NULL_TREE)
2635 tree label = create_artificial_label (UNKNOWN_LOCATION);
2636 *label_p = label;
2639 return build1 (GOTO_EXPR, void_type_node, *label_p);
2642 /* Gimplify an EXIT_EXPR by converting to a GOTO_EXPR inside a COND_EXPR.
2643 This also involves building a label to jump to and communicating it to
2644 gimplify_loop_expr through gimplify_ctxp->exit_label. */
2646 static enum gimplify_status
2647 gimplify_exit_expr (tree *expr_p)
2649 tree cond = TREE_OPERAND (*expr_p, 0);
2650 tree expr;
2652 expr = build_and_jump (&gimplify_ctxp->exit_label);
2653 expr = build3 (COND_EXPR, void_type_node, cond, expr, NULL_TREE);
2654 *expr_p = expr;
2656 return GS_OK;
2659 /* *EXPR_P is a COMPONENT_REF being used as an rvalue. If its type is
2660 different from its canonical type, wrap the whole thing inside a
2661 NOP_EXPR and force the type of the COMPONENT_REF to be the canonical
2662 type.
2664 The canonical type of a COMPONENT_REF is the type of the field being
2665 referenced--unless the field is a bit-field which can be read directly
2666 in a smaller mode, in which case the canonical type is the
2667 sign-appropriate type corresponding to that mode. */
2669 static void
2670 canonicalize_component_ref (tree *expr_p)
2672 tree expr = *expr_p;
2673 tree type;
2675 gcc_assert (TREE_CODE (expr) == COMPONENT_REF);
2677 if (INTEGRAL_TYPE_P (TREE_TYPE (expr)))
2678 type = TREE_TYPE (get_unwidened (expr, NULL_TREE));
2679 else
2680 type = TREE_TYPE (TREE_OPERAND (expr, 1));
2682 /* One could argue that all the stuff below is not necessary for
2683 the non-bitfield case and declare it a FE error if type
2684 adjustment would be needed. */
2685 if (TREE_TYPE (expr) != type)
2687 #ifdef ENABLE_TYPES_CHECKING
2688 tree old_type = TREE_TYPE (expr);
2689 #endif
2690 int type_quals;
2692 /* We need to preserve qualifiers and propagate them from
2693 operand 0. */
2694 type_quals = TYPE_QUALS (type)
2695 | TYPE_QUALS (TREE_TYPE (TREE_OPERAND (expr, 0)));
2696 if (TYPE_QUALS (type) != type_quals)
2697 type = build_qualified_type (TYPE_MAIN_VARIANT (type), type_quals);
2699 /* Set the type of the COMPONENT_REF to the underlying type. */
2700 TREE_TYPE (expr) = type;
2702 #ifdef ENABLE_TYPES_CHECKING
2703 /* It is now a FE error, if the conversion from the canonical
2704 type to the original expression type is not useless. */
2705 gcc_assert (useless_type_conversion_p (old_type, type));
2706 #endif
2710 /* If a NOP conversion is changing a pointer to array of foo to a pointer
2711 to foo, embed that change in the ADDR_EXPR by converting
2712 T array[U];
2713 (T *)&array
2715 &array[L]
2716 where L is the lower bound. For simplicity, only do this for constant
2717 lower bound.
2718 The constraint is that the type of &array[L] is trivially convertible
2719 to T *. */
2721 static void
2722 canonicalize_addr_expr (tree *expr_p)
2724 tree expr = *expr_p;
2725 tree addr_expr = TREE_OPERAND (expr, 0);
2726 tree datype, ddatype, pddatype;
2728 /* We simplify only conversions from an ADDR_EXPR to a pointer type. */
2729 if (!POINTER_TYPE_P (TREE_TYPE (expr))
2730 || TREE_CODE (addr_expr) != ADDR_EXPR)
2731 return;
2733 /* The addr_expr type should be a pointer to an array. */
2734 datype = TREE_TYPE (TREE_TYPE (addr_expr));
2735 if (TREE_CODE (datype) != ARRAY_TYPE)
2736 return;
2738 /* The pointer to element type shall be trivially convertible to
2739 the expression pointer type. */
2740 ddatype = TREE_TYPE (datype);
2741 pddatype = build_pointer_type (ddatype);
2742 if (!useless_type_conversion_p (TYPE_MAIN_VARIANT (TREE_TYPE (expr)),
2743 pddatype))
2744 return;
2746 /* The lower bound and element sizes must be constant. */
2747 if (!TYPE_SIZE_UNIT (ddatype)
2748 || TREE_CODE (TYPE_SIZE_UNIT (ddatype)) != INTEGER_CST
2749 || !TYPE_DOMAIN (datype) || !TYPE_MIN_VALUE (TYPE_DOMAIN (datype))
2750 || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (datype))) != INTEGER_CST)
2751 return;
2753 /* All checks succeeded. Build a new node to merge the cast. */
2754 *expr_p = build4 (ARRAY_REF, ddatype, TREE_OPERAND (addr_expr, 0),
2755 TYPE_MIN_VALUE (TYPE_DOMAIN (datype)),
2756 NULL_TREE, NULL_TREE);
2757 *expr_p = build1 (ADDR_EXPR, pddatype, *expr_p);
2759 /* We can have stripped a required restrict qualifier above. */
2760 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
2761 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
2764 /* *EXPR_P is a NOP_EXPR or CONVERT_EXPR. Remove it and/or other conversions
2765 underneath as appropriate. */
2767 static enum gimplify_status
2768 gimplify_conversion (tree *expr_p)
2770 location_t loc = EXPR_LOCATION (*expr_p);
2771 gcc_assert (CONVERT_EXPR_P (*expr_p));
2773 /* Then strip away all but the outermost conversion. */
2774 STRIP_SIGN_NOPS (TREE_OPERAND (*expr_p, 0));
2776 /* And remove the outermost conversion if it's useless. */
2777 if (tree_ssa_useless_type_conversion (*expr_p))
2778 *expr_p = TREE_OPERAND (*expr_p, 0);
2780 /* If we still have a conversion at the toplevel,
2781 then canonicalize some constructs. */
2782 if (CONVERT_EXPR_P (*expr_p))
2784 tree sub = TREE_OPERAND (*expr_p, 0);
2786 /* If a NOP conversion is changing the type of a COMPONENT_REF
2787 expression, then canonicalize its type now in order to expose more
2788 redundant conversions. */
2789 if (TREE_CODE (sub) == COMPONENT_REF)
2790 canonicalize_component_ref (&TREE_OPERAND (*expr_p, 0));
2792 /* If a NOP conversion is changing a pointer to array of foo
2793 to a pointer to foo, embed that change in the ADDR_EXPR. */
2794 else if (TREE_CODE (sub) == ADDR_EXPR)
2795 canonicalize_addr_expr (expr_p);
2798 /* If we have a conversion to a non-register type force the
2799 use of a VIEW_CONVERT_EXPR instead. */
2800 if (CONVERT_EXPR_P (*expr_p) && !is_gimple_reg_type (TREE_TYPE (*expr_p)))
2801 *expr_p = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (*expr_p),
2802 TREE_OPERAND (*expr_p, 0));
2804 /* Canonicalize CONVERT_EXPR to NOP_EXPR. */
2805 if (TREE_CODE (*expr_p) == CONVERT_EXPR)
2806 TREE_SET_CODE (*expr_p, NOP_EXPR);
2808 return GS_OK;
2811 /* Gimplify a VAR_DECL or PARM_DECL. Return GS_OK if we expanded a
2812 DECL_VALUE_EXPR, and it's worth re-examining things. */
2814 static enum gimplify_status
2815 gimplify_var_or_parm_decl (tree *expr_p)
2817 tree decl = *expr_p;
2819 /* ??? If this is a local variable, and it has not been seen in any
2820 outer BIND_EXPR, then it's probably the result of a duplicate
2821 declaration, for which we've already issued an error. It would
2822 be really nice if the front end wouldn't leak these at all.
2823 Currently the only known culprit is C++ destructors, as seen
2824 in g++.old-deja/g++.jason/binding.C. */
2825 if (VAR_P (decl)
2826 && !DECL_SEEN_IN_BIND_EXPR_P (decl)
2827 && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl)
2828 && decl_function_context (decl) == current_function_decl)
2830 gcc_assert (seen_error ());
2831 return GS_ERROR;
2834 /* When within an OMP context, notice uses of variables. */
2835 if (gimplify_omp_ctxp && omp_notice_variable (gimplify_omp_ctxp, decl, true))
2836 return GS_ALL_DONE;
2838 /* If the decl is an alias for another expression, substitute it now. */
2839 if (DECL_HAS_VALUE_EXPR_P (decl))
2841 *expr_p = unshare_expr (DECL_VALUE_EXPR (decl));
2842 return GS_OK;
2845 return GS_ALL_DONE;
2848 /* Recalculate the value of the TREE_SIDE_EFFECTS flag for T. */
2850 static void
2851 recalculate_side_effects (tree t)
2853 enum tree_code code = TREE_CODE (t);
2854 int len = TREE_OPERAND_LENGTH (t);
2855 int i;
2857 switch (TREE_CODE_CLASS (code))
2859 case tcc_expression:
2860 switch (code)
2862 case INIT_EXPR:
2863 case MODIFY_EXPR:
2864 case VA_ARG_EXPR:
2865 case PREDECREMENT_EXPR:
2866 case PREINCREMENT_EXPR:
2867 case POSTDECREMENT_EXPR:
2868 case POSTINCREMENT_EXPR:
2869 /* All of these have side-effects, no matter what their
2870 operands are. */
2871 return;
2873 default:
2874 break;
2876 /* Fall through. */
2878 case tcc_comparison: /* a comparison expression */
2879 case tcc_unary: /* a unary arithmetic expression */
2880 case tcc_binary: /* a binary arithmetic expression */
2881 case tcc_reference: /* a reference */
2882 case tcc_vl_exp: /* a function call */
2883 TREE_SIDE_EFFECTS (t) = TREE_THIS_VOLATILE (t);
2884 for (i = 0; i < len; ++i)
2886 tree op = TREE_OPERAND (t, i);
2887 if (op && TREE_SIDE_EFFECTS (op))
2888 TREE_SIDE_EFFECTS (t) = 1;
2890 break;
2892 case tcc_constant:
2893 /* No side-effects. */
2894 return;
2896 default:
2897 gcc_unreachable ();
2901 /* Gimplify the COMPONENT_REF, ARRAY_REF, REALPART_EXPR or IMAGPART_EXPR
2902 node *EXPR_P.
2904 compound_lval
2905 : min_lval '[' val ']'
2906 | min_lval '.' ID
2907 | compound_lval '[' val ']'
2908 | compound_lval '.' ID
2910 This is not part of the original SIMPLE definition, which separates
2911 array and member references, but it seems reasonable to handle them
2912 together. Also, this way we don't run into problems with union
2913 aliasing; gcc requires that for accesses through a union to alias, the
2914 union reference must be explicit, which was not always the case when we
2915 were splitting up array and member refs.
2917 PRE_P points to the sequence where side effects that must happen before
2918 *EXPR_P should be stored.
2920 POST_P points to the sequence where side effects that must happen after
2921 *EXPR_P should be stored. */
2923 static enum gimplify_status
2924 gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
2925 fallback_t fallback)
2927 tree *p;
2928 enum gimplify_status ret = GS_ALL_DONE, tret;
2929 int i;
2930 location_t loc = EXPR_LOCATION (*expr_p);
2931 tree expr = *expr_p;
2933 /* Create a stack of the subexpressions so later we can walk them in
2934 order from inner to outer. */
2935 auto_vec<tree, 10> expr_stack;
2937 /* We can handle anything that get_inner_reference can deal with. */
2938 for (p = expr_p; ; p = &TREE_OPERAND (*p, 0))
2940 restart:
2941 /* Fold INDIRECT_REFs now to turn them into ARRAY_REFs. */
2942 if (TREE_CODE (*p) == INDIRECT_REF)
2943 *p = fold_indirect_ref_loc (loc, *p);
2945 if (handled_component_p (*p))
2947 /* Expand DECL_VALUE_EXPR now. In some cases that may expose
2948 additional COMPONENT_REFs. */
2949 else if ((VAR_P (*p) || TREE_CODE (*p) == PARM_DECL)
2950 && gimplify_var_or_parm_decl (p) == GS_OK)
2951 goto restart;
2952 else
2953 break;
2955 expr_stack.safe_push (*p);
2958 gcc_assert (expr_stack.length ());
2960 /* Now EXPR_STACK is a stack of pointers to all the refs we've
2961 walked through and P points to the innermost expression.
2963 Java requires that we elaborated nodes in source order. That
2964 means we must gimplify the inner expression followed by each of
2965 the indices, in order. But we can't gimplify the inner
2966 expression until we deal with any variable bounds, sizes, or
2967 positions in order to deal with PLACEHOLDER_EXPRs.
2969 So we do this in three steps. First we deal with the annotations
2970 for any variables in the components, then we gimplify the base,
2971 then we gimplify any indices, from left to right. */
2972 for (i = expr_stack.length () - 1; i >= 0; i--)
2974 tree t = expr_stack[i];
2976 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
2978 /* Gimplify the low bound and element type size and put them into
2979 the ARRAY_REF. If these values are set, they have already been
2980 gimplified. */
2981 if (TREE_OPERAND (t, 2) == NULL_TREE)
2983 tree low = unshare_expr (array_ref_low_bound (t));
2984 if (!is_gimple_min_invariant (low))
2986 TREE_OPERAND (t, 2) = low;
2987 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
2988 post_p, is_gimple_reg,
2989 fb_rvalue);
2990 ret = MIN (ret, tret);
2993 else
2995 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
2996 is_gimple_reg, fb_rvalue);
2997 ret = MIN (ret, tret);
3000 if (TREE_OPERAND (t, 3) == NULL_TREE)
3002 tree elmt_size = array_ref_element_size (t);
3003 if (!is_gimple_min_invariant (elmt_size))
3005 elmt_size = unshare_expr (elmt_size);
3006 tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0)));
3007 tree factor = size_int (TYPE_ALIGN_UNIT (elmt_type));
3009 /* Divide the element size by the alignment of the element
3010 type (above). */
3011 elmt_size = size_binop_loc (loc, EXACT_DIV_EXPR,
3012 elmt_size, factor);
3014 TREE_OPERAND (t, 3) = elmt_size;
3015 tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p,
3016 post_p, is_gimple_reg,
3017 fb_rvalue);
3018 ret = MIN (ret, tret);
3021 else
3023 tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p, post_p,
3024 is_gimple_reg, fb_rvalue);
3025 ret = MIN (ret, tret);
3028 else if (TREE_CODE (t) == COMPONENT_REF)
3030 /* Set the field offset into T and gimplify it. */
3031 if (TREE_OPERAND (t, 2) == NULL_TREE)
3033 tree offset = component_ref_field_offset (t);
3034 if (!is_gimple_min_invariant (offset))
3036 offset = unshare_expr (offset);
3037 tree field = TREE_OPERAND (t, 1);
3038 tree factor
3039 = size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT);
3041 /* Divide the offset by its alignment. */
3042 offset = size_binop_loc (loc, EXACT_DIV_EXPR,
3043 offset, factor);
3045 TREE_OPERAND (t, 2) = offset;
3046 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
3047 post_p, is_gimple_reg,
3048 fb_rvalue);
3049 ret = MIN (ret, tret);
3052 else
3054 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
3055 is_gimple_reg, fb_rvalue);
3056 ret = MIN (ret, tret);
3061 /* Step 2 is to gimplify the base expression. Make sure lvalue is set
3062 so as to match the min_lval predicate. Failure to do so may result
3063 in the creation of large aggregate temporaries. */
3064 tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval,
3065 fallback | fb_lvalue);
3066 ret = MIN (ret, tret);
3068 /* And finally, the indices and operands of ARRAY_REF. During this
3069 loop we also remove any useless conversions. */
3070 for (; expr_stack.length () > 0; )
3072 tree t = expr_stack.pop ();
3074 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
3076 /* Gimplify the dimension. */
3077 if (!is_gimple_min_invariant (TREE_OPERAND (t, 1)))
3079 tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
3080 is_gimple_val, fb_rvalue);
3081 ret = MIN (ret, tret);
3085 STRIP_USELESS_TYPE_CONVERSION (TREE_OPERAND (t, 0));
3087 /* The innermost expression P may have originally had
3088 TREE_SIDE_EFFECTS set which would have caused all the outer
3089 expressions in *EXPR_P leading to P to also have had
3090 TREE_SIDE_EFFECTS set. */
3091 recalculate_side_effects (t);
3094 /* If the outermost expression is a COMPONENT_REF, canonicalize its type. */
3095 if ((fallback & fb_rvalue) && TREE_CODE (*expr_p) == COMPONENT_REF)
3097 canonicalize_component_ref (expr_p);
3100 expr_stack.release ();
3102 gcc_assert (*expr_p == expr || ret != GS_ALL_DONE);
3104 return ret;
3107 /* Gimplify the self modifying expression pointed to by EXPR_P
3108 (++, --, +=, -=).
3110 PRE_P points to the list where side effects that must happen before
3111 *EXPR_P should be stored.
3113 POST_P points to the list where side effects that must happen after
3114 *EXPR_P should be stored.
3116 WANT_VALUE is nonzero iff we want to use the value of this expression
3117 in another expression.
3119 ARITH_TYPE is the type the computation should be performed in. */
3121 enum gimplify_status
3122 gimplify_self_mod_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
3123 bool want_value, tree arith_type)
3125 enum tree_code code;
3126 tree lhs, lvalue, rhs, t1;
3127 gimple_seq post = NULL, *orig_post_p = post_p;
3128 bool postfix;
3129 enum tree_code arith_code;
3130 enum gimplify_status ret;
3131 location_t loc = EXPR_LOCATION (*expr_p);
3133 code = TREE_CODE (*expr_p);
3135 gcc_assert (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR
3136 || code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR);
3138 /* Prefix or postfix? */
3139 if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
3140 /* Faster to treat as prefix if result is not used. */
3141 postfix = want_value;
3142 else
3143 postfix = false;
3145 /* For postfix, make sure the inner expression's post side effects
3146 are executed after side effects from this expression. */
3147 if (postfix)
3148 post_p = &post;
3150 /* Add or subtract? */
3151 if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
3152 arith_code = PLUS_EXPR;
3153 else
3154 arith_code = MINUS_EXPR;
3156 /* Gimplify the LHS into a GIMPLE lvalue. */
3157 lvalue = TREE_OPERAND (*expr_p, 0);
3158 ret = gimplify_expr (&lvalue, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
3159 if (ret == GS_ERROR)
3160 return ret;
3162 /* Extract the operands to the arithmetic operation. */
3163 lhs = lvalue;
3164 rhs = TREE_OPERAND (*expr_p, 1);
3166 /* For postfix operator, we evaluate the LHS to an rvalue and then use
3167 that as the result value and in the postqueue operation. */
3168 if (postfix)
3170 ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue);
3171 if (ret == GS_ERROR)
3172 return ret;
3174 lhs = get_initialized_tmp_var (lhs, pre_p);
3177 /* For POINTERs increment, use POINTER_PLUS_EXPR. */
3178 if (POINTER_TYPE_P (TREE_TYPE (lhs)))
3180 rhs = convert_to_ptrofftype_loc (loc, rhs);
3181 if (arith_code == MINUS_EXPR)
3182 rhs = fold_build1_loc (loc, NEGATE_EXPR, TREE_TYPE (rhs), rhs);
3183 t1 = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (*expr_p), lhs, rhs);
3185 else
3186 t1 = fold_convert (TREE_TYPE (*expr_p),
3187 fold_build2 (arith_code, arith_type,
3188 fold_convert (arith_type, lhs),
3189 fold_convert (arith_type, rhs)));
3191 if (postfix)
3193 gimplify_assign (lvalue, t1, pre_p);
3194 gimplify_seq_add_seq (orig_post_p, post);
3195 *expr_p = lhs;
3196 return GS_ALL_DONE;
3198 else
3200 *expr_p = build2 (MODIFY_EXPR, TREE_TYPE (lvalue), lvalue, t1);
3201 return GS_OK;
3205 /* If *EXPR_P has a variable sized type, wrap it in a WITH_SIZE_EXPR. */
3207 static void
3208 maybe_with_size_expr (tree *expr_p)
3210 tree expr = *expr_p;
3211 tree type = TREE_TYPE (expr);
3212 tree size;
3214 /* If we've already wrapped this or the type is error_mark_node, we can't do
3215 anything. */
3216 if (TREE_CODE (expr) == WITH_SIZE_EXPR
3217 || type == error_mark_node)
3218 return;
3220 /* If the size isn't known or is a constant, we have nothing to do. */
3221 size = TYPE_SIZE_UNIT (type);
3222 if (!size || poly_int_tree_p (size))
3223 return;
3225 /* Otherwise, make a WITH_SIZE_EXPR. */
3226 size = unshare_expr (size);
3227 size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, expr);
3228 *expr_p = build2 (WITH_SIZE_EXPR, type, expr, size);
3231 /* Helper for gimplify_call_expr. Gimplify a single argument *ARG_P
3232 Store any side-effects in PRE_P. CALL_LOCATION is the location of
3233 the CALL_EXPR. If ALLOW_SSA is set the actual parameter may be
3234 gimplified to an SSA name. */
3236 enum gimplify_status
3237 gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location,
3238 bool allow_ssa)
3240 bool (*test) (tree);
3241 fallback_t fb;
3243 /* In general, we allow lvalues for function arguments to avoid
3244 extra overhead of copying large aggregates out of even larger
3245 aggregates into temporaries only to copy the temporaries to
3246 the argument list. Make optimizers happy by pulling out to
3247 temporaries those types that fit in registers. */
3248 if (is_gimple_reg_type (TREE_TYPE (*arg_p)))
3249 test = is_gimple_val, fb = fb_rvalue;
3250 else
3252 test = is_gimple_lvalue, fb = fb_either;
3253 /* Also strip a TARGET_EXPR that would force an extra copy. */
3254 if (TREE_CODE (*arg_p) == TARGET_EXPR)
3256 tree init = TARGET_EXPR_INITIAL (*arg_p);
3257 if (init
3258 && !VOID_TYPE_P (TREE_TYPE (init)))
3259 *arg_p = init;
3263 /* If this is a variable sized type, we must remember the size. */
3264 maybe_with_size_expr (arg_p);
3266 /* FIXME diagnostics: This will mess up gcc.dg/Warray-bounds.c. */
3267 /* Make sure arguments have the same location as the function call
3268 itself. */
3269 protected_set_expr_location (*arg_p, call_location);
3271 /* There is a sequence point before a function call. Side effects in
3272 the argument list must occur before the actual call. So, when
3273 gimplifying arguments, force gimplify_expr to use an internal
3274 post queue which is then appended to the end of PRE_P. */
3275 return gimplify_expr (arg_p, pre_p, NULL, test, fb, allow_ssa);
3278 /* Don't fold inside offloading or taskreg regions: it can break code by
3279 adding decl references that weren't in the source. We'll do it during
3280 omplower pass instead. */
3282 static bool
3283 maybe_fold_stmt (gimple_stmt_iterator *gsi)
3285 struct gimplify_omp_ctx *ctx;
3286 for (ctx = gimplify_omp_ctxp; ctx; ctx = ctx->outer_context)
3287 if ((ctx->region_type & (ORT_TARGET | ORT_PARALLEL | ORT_TASK)) != 0)
3288 return false;
3289 else if ((ctx->region_type & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
3290 return false;
3291 /* Delay folding of builtins until the IL is in consistent state
3292 so the diagnostic machinery can do a better job. */
3293 if (gimple_call_builtin_p (gsi_stmt (*gsi)))
3294 return false;
3295 return fold_stmt (gsi);
3298 /* Gimplify the CALL_EXPR node *EXPR_P into the GIMPLE sequence PRE_P.
3299 WANT_VALUE is true if the result of the call is desired. */
3301 static enum gimplify_status
3302 gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
3304 tree fndecl, parms, p, fnptrtype;
3305 enum gimplify_status ret;
3306 int i, nargs;
3307 gcall *call;
3308 bool builtin_va_start_p = false;
3309 location_t loc = EXPR_LOCATION (*expr_p);
3311 gcc_assert (TREE_CODE (*expr_p) == CALL_EXPR);
3313 /* For reliable diagnostics during inlining, it is necessary that
3314 every call_expr be annotated with file and line. */
3315 if (! EXPR_HAS_LOCATION (*expr_p))
3316 SET_EXPR_LOCATION (*expr_p, input_location);
3318 /* Gimplify internal functions created in the FEs. */
3319 if (CALL_EXPR_FN (*expr_p) == NULL_TREE)
3321 if (want_value)
3322 return GS_ALL_DONE;
3324 nargs = call_expr_nargs (*expr_p);
3325 enum internal_fn ifn = CALL_EXPR_IFN (*expr_p);
3326 auto_vec<tree> vargs (nargs);
3328 for (i = 0; i < nargs; i++)
3330 gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
3331 EXPR_LOCATION (*expr_p));
3332 vargs.quick_push (CALL_EXPR_ARG (*expr_p, i));
3335 gcall *call = gimple_build_call_internal_vec (ifn, vargs);
3336 gimple_call_set_nothrow (call, TREE_NOTHROW (*expr_p));
3337 gimplify_seq_add_stmt (pre_p, call);
3338 return GS_ALL_DONE;
3341 /* This may be a call to a builtin function.
3343 Builtin function calls may be transformed into different
3344 (and more efficient) builtin function calls under certain
3345 circumstances. Unfortunately, gimplification can muck things
3346 up enough that the builtin expanders are not aware that certain
3347 transformations are still valid.
3349 So we attempt transformation/gimplification of the call before
3350 we gimplify the CALL_EXPR. At this time we do not manage to
3351 transform all calls in the same manner as the expanders do, but
3352 we do transform most of them. */
3353 fndecl = get_callee_fndecl (*expr_p);
3354 if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
3355 switch (DECL_FUNCTION_CODE (fndecl))
3357 CASE_BUILT_IN_ALLOCA:
3358 /* If the call has been built for a variable-sized object, then we
3359 want to restore the stack level when the enclosing BIND_EXPR is
3360 exited to reclaim the allocated space; otherwise, we precisely
3361 need to do the opposite and preserve the latest stack level. */
3362 if (CALL_ALLOCA_FOR_VAR_P (*expr_p))
3363 gimplify_ctxp->save_stack = true;
3364 else
3365 gimplify_ctxp->keep_stack = true;
3366 break;
3368 case BUILT_IN_VA_START:
3370 builtin_va_start_p = TRUE;
3371 if (call_expr_nargs (*expr_p) < 2)
3373 error ("too few arguments to function %<va_start%>");
3374 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
3375 return GS_OK;
3378 if (fold_builtin_next_arg (*expr_p, true))
3380 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
3381 return GS_OK;
3383 break;
3386 case BUILT_IN_EH_RETURN:
3387 cfun->calls_eh_return = true;
3388 break;
3390 default:
3393 if (fndecl && fndecl_built_in_p (fndecl))
3395 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
3396 if (new_tree && new_tree != *expr_p)
3398 /* There was a transformation of this call which computes the
3399 same value, but in a more efficient way. Return and try
3400 again. */
3401 *expr_p = new_tree;
3402 return GS_OK;
3406 /* Remember the original function pointer type. */
3407 fnptrtype = TREE_TYPE (CALL_EXPR_FN (*expr_p));
3409 if (flag_openmp
3410 && fndecl
3411 && cfun
3412 && (cfun->curr_properties & PROP_gimple_any) == 0)
3414 tree variant = omp_resolve_declare_variant (fndecl);
3415 if (variant != fndecl)
3416 CALL_EXPR_FN (*expr_p) = build1 (ADDR_EXPR, fnptrtype, variant);
3419 /* There is a sequence point before the call, so any side effects in
3420 the calling expression must occur before the actual call. Force
3421 gimplify_expr to use an internal post queue. */
3422 ret = gimplify_expr (&CALL_EXPR_FN (*expr_p), pre_p, NULL,
3423 is_gimple_call_addr, fb_rvalue);
3425 nargs = call_expr_nargs (*expr_p);
3427 /* Get argument types for verification. */
3428 fndecl = get_callee_fndecl (*expr_p);
3429 parms = NULL_TREE;
3430 if (fndecl)
3431 parms = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
3432 else
3433 parms = TYPE_ARG_TYPES (TREE_TYPE (fnptrtype));
3435 if (fndecl && DECL_ARGUMENTS (fndecl))
3436 p = DECL_ARGUMENTS (fndecl);
3437 else if (parms)
3438 p = parms;
3439 else
3440 p = NULL_TREE;
3441 for (i = 0; i < nargs && p; i++, p = TREE_CHAIN (p))
3444 /* If the last argument is __builtin_va_arg_pack () and it is not
3445 passed as a named argument, decrease the number of CALL_EXPR
3446 arguments and set instead the CALL_EXPR_VA_ARG_PACK flag. */
3447 if (!p
3448 && i < nargs
3449 && TREE_CODE (CALL_EXPR_ARG (*expr_p, nargs - 1)) == CALL_EXPR)
3451 tree last_arg = CALL_EXPR_ARG (*expr_p, nargs - 1);
3452 tree last_arg_fndecl = get_callee_fndecl (last_arg);
3454 if (last_arg_fndecl
3455 && fndecl_built_in_p (last_arg_fndecl, BUILT_IN_VA_ARG_PACK))
3457 tree call = *expr_p;
3459 --nargs;
3460 *expr_p = build_call_array_loc (loc, TREE_TYPE (call),
3461 CALL_EXPR_FN (call),
3462 nargs, CALL_EXPR_ARGP (call));
3464 /* Copy all CALL_EXPR flags, location and block, except
3465 CALL_EXPR_VA_ARG_PACK flag. */
3466 CALL_EXPR_STATIC_CHAIN (*expr_p) = CALL_EXPR_STATIC_CHAIN (call);
3467 CALL_EXPR_TAILCALL (*expr_p) = CALL_EXPR_TAILCALL (call);
3468 CALL_EXPR_RETURN_SLOT_OPT (*expr_p)
3469 = CALL_EXPR_RETURN_SLOT_OPT (call);
3470 CALL_FROM_THUNK_P (*expr_p) = CALL_FROM_THUNK_P (call);
3471 SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (call));
3473 /* Set CALL_EXPR_VA_ARG_PACK. */
3474 CALL_EXPR_VA_ARG_PACK (*expr_p) = 1;
3478 /* If the call returns twice then after building the CFG the call
3479 argument computations will no longer dominate the call because
3480 we add an abnormal incoming edge to the call. So do not use SSA
3481 vars there. */
3482 bool returns_twice = call_expr_flags (*expr_p) & ECF_RETURNS_TWICE;
3484 /* Gimplify the function arguments. */
3485 if (nargs > 0)
3487 for (i = (PUSH_ARGS_REVERSED ? nargs - 1 : 0);
3488 PUSH_ARGS_REVERSED ? i >= 0 : i < nargs;
3489 PUSH_ARGS_REVERSED ? i-- : i++)
3491 enum gimplify_status t;
3493 /* Avoid gimplifying the second argument to va_start, which needs to
3494 be the plain PARM_DECL. */
3495 if ((i != 1) || !builtin_va_start_p)
3497 t = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
3498 EXPR_LOCATION (*expr_p), ! returns_twice);
3500 if (t == GS_ERROR)
3501 ret = GS_ERROR;
3506 /* Gimplify the static chain. */
3507 if (CALL_EXPR_STATIC_CHAIN (*expr_p))
3509 if (fndecl && !DECL_STATIC_CHAIN (fndecl))
3510 CALL_EXPR_STATIC_CHAIN (*expr_p) = NULL;
3511 else
3513 enum gimplify_status t;
3514 t = gimplify_arg (&CALL_EXPR_STATIC_CHAIN (*expr_p), pre_p,
3515 EXPR_LOCATION (*expr_p), ! returns_twice);
3516 if (t == GS_ERROR)
3517 ret = GS_ERROR;
3521 /* Verify the function result. */
3522 if (want_value && fndecl
3523 && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fnptrtype))))
3525 error_at (loc, "using result of function returning %<void%>");
3526 ret = GS_ERROR;
3529 /* Try this again in case gimplification exposed something. */
3530 if (ret != GS_ERROR)
3532 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
3534 if (new_tree && new_tree != *expr_p)
3536 /* There was a transformation of this call which computes the
3537 same value, but in a more efficient way. Return and try
3538 again. */
3539 *expr_p = new_tree;
3540 return GS_OK;
3543 else
3545 *expr_p = error_mark_node;
3546 return GS_ERROR;
3549 /* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its
3550 decl. This allows us to eliminate redundant or useless
3551 calls to "const" functions. */
3552 if (TREE_CODE (*expr_p) == CALL_EXPR)
3554 int flags = call_expr_flags (*expr_p);
3555 if (flags & (ECF_CONST | ECF_PURE)
3556 /* An infinite loop is considered a side effect. */
3557 && !(flags & (ECF_LOOPING_CONST_OR_PURE)))
3558 TREE_SIDE_EFFECTS (*expr_p) = 0;
3561 /* If the value is not needed by the caller, emit a new GIMPLE_CALL
3562 and clear *EXPR_P. Otherwise, leave *EXPR_P in its gimplified
3563 form and delegate the creation of a GIMPLE_CALL to
3564 gimplify_modify_expr. This is always possible because when
3565 WANT_VALUE is true, the caller wants the result of this call into
3566 a temporary, which means that we will emit an INIT_EXPR in
3567 internal_get_tmp_var which will then be handled by
3568 gimplify_modify_expr. */
3569 if (!want_value)
3571 /* The CALL_EXPR in *EXPR_P is already in GIMPLE form, so all we
3572 have to do is replicate it as a GIMPLE_CALL tuple. */
3573 gimple_stmt_iterator gsi;
3574 call = gimple_build_call_from_tree (*expr_p, fnptrtype);
3575 notice_special_calls (call);
3576 gimplify_seq_add_stmt (pre_p, call);
3577 gsi = gsi_last (*pre_p);
3578 maybe_fold_stmt (&gsi);
3579 *expr_p = NULL_TREE;
3581 else
3582 /* Remember the original function type. */
3583 CALL_EXPR_FN (*expr_p) = build1 (NOP_EXPR, fnptrtype,
3584 CALL_EXPR_FN (*expr_p));
3586 return ret;
3589 /* Handle shortcut semantics in the predicate operand of a COND_EXPR by
3590 rewriting it into multiple COND_EXPRs, and possibly GOTO_EXPRs.
3592 TRUE_LABEL_P and FALSE_LABEL_P point to the labels to jump to if the
3593 condition is true or false, respectively. If null, we should generate
3594 our own to skip over the evaluation of this specific expression.
3596 LOCUS is the source location of the COND_EXPR.
3598 This function is the tree equivalent of do_jump.
3600 shortcut_cond_r should only be called by shortcut_cond_expr. */
3602 static tree
3603 shortcut_cond_r (tree pred, tree *true_label_p, tree *false_label_p,
3604 location_t locus)
3606 tree local_label = NULL_TREE;
3607 tree t, expr = NULL;
3609 /* OK, it's not a simple case; we need to pull apart the COND_EXPR to
3610 retain the shortcut semantics. Just insert the gotos here;
3611 shortcut_cond_expr will append the real blocks later. */
3612 if (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
3614 location_t new_locus;
3616 /* Turn if (a && b) into
3618 if (a); else goto no;
3619 if (b) goto yes; else goto no;
3620 (no:) */
3622 if (false_label_p == NULL)
3623 false_label_p = &local_label;
3625 /* Keep the original source location on the first 'if'. */
3626 t = shortcut_cond_r (TREE_OPERAND (pred, 0), NULL, false_label_p, locus);
3627 append_to_statement_list (t, &expr);
3629 /* Set the source location of the && on the second 'if'. */
3630 new_locus = rexpr_location (pred, locus);
3631 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
3632 new_locus);
3633 append_to_statement_list (t, &expr);
3635 else if (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
3637 location_t new_locus;
3639 /* Turn if (a || b) into
3641 if (a) goto yes;
3642 if (b) goto yes; else goto no;
3643 (yes:) */
3645 if (true_label_p == NULL)
3646 true_label_p = &local_label;
3648 /* Keep the original source location on the first 'if'. */
3649 t = shortcut_cond_r (TREE_OPERAND (pred, 0), true_label_p, NULL, locus);
3650 append_to_statement_list (t, &expr);
3652 /* Set the source location of the || on the second 'if'. */
3653 new_locus = rexpr_location (pred, locus);
3654 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
3655 new_locus);
3656 append_to_statement_list (t, &expr);
3658 else if (TREE_CODE (pred) == COND_EXPR
3659 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 1)))
3660 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 2))))
3662 location_t new_locus;
3664 /* As long as we're messing with gotos, turn if (a ? b : c) into
3665 if (a)
3666 if (b) goto yes; else goto no;
3667 else
3668 if (c) goto yes; else goto no;
3670 Don't do this if one of the arms has void type, which can happen
3671 in C++ when the arm is throw. */
3673 /* Keep the original source location on the first 'if'. Set the source
3674 location of the ? on the second 'if'. */
3675 new_locus = rexpr_location (pred, locus);
3676 expr = build3 (COND_EXPR, void_type_node, TREE_OPERAND (pred, 0),
3677 shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p,
3678 false_label_p, locus),
3679 shortcut_cond_r (TREE_OPERAND (pred, 2), true_label_p,
3680 false_label_p, new_locus));
3682 else
3684 expr = build3 (COND_EXPR, void_type_node, pred,
3685 build_and_jump (true_label_p),
3686 build_and_jump (false_label_p));
3687 SET_EXPR_LOCATION (expr, locus);
3690 if (local_label)
3692 t = build1 (LABEL_EXPR, void_type_node, local_label);
3693 append_to_statement_list (t, &expr);
3696 return expr;
3699 /* If EXPR is a GOTO_EXPR, return it. If it is a STATEMENT_LIST, skip
3700 any of its leading DEBUG_BEGIN_STMTS and recurse on the subsequent
3701 statement, if it is the last one. Otherwise, return NULL. */
3703 static tree
3704 find_goto (tree expr)
3706 if (!expr)
3707 return NULL_TREE;
3709 if (TREE_CODE (expr) == GOTO_EXPR)
3710 return expr;
3712 if (TREE_CODE (expr) != STATEMENT_LIST)
3713 return NULL_TREE;
3715 tree_stmt_iterator i = tsi_start (expr);
3717 while (!tsi_end_p (i) && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT)
3718 tsi_next (&i);
3720 if (!tsi_one_before_end_p (i))
3721 return NULL_TREE;
3723 return find_goto (tsi_stmt (i));
3726 /* Same as find_goto, except that it returns NULL if the destination
3727 is not a LABEL_DECL. */
3729 static inline tree
3730 find_goto_label (tree expr)
3732 tree dest = find_goto (expr);
3733 if (dest && TREE_CODE (GOTO_DESTINATION (dest)) == LABEL_DECL)
3734 return dest;
3735 return NULL_TREE;
3738 /* Given a conditional expression EXPR with short-circuit boolean
3739 predicates using TRUTH_ANDIF_EXPR or TRUTH_ORIF_EXPR, break the
3740 predicate apart into the equivalent sequence of conditionals. */
3742 static tree
3743 shortcut_cond_expr (tree expr)
3745 tree pred = TREE_OPERAND (expr, 0);
3746 tree then_ = TREE_OPERAND (expr, 1);
3747 tree else_ = TREE_OPERAND (expr, 2);
3748 tree true_label, false_label, end_label, t;
3749 tree *true_label_p;
3750 tree *false_label_p;
3751 bool emit_end, emit_false, jump_over_else;
3752 bool then_se = then_ && TREE_SIDE_EFFECTS (then_);
3753 bool else_se = else_ && TREE_SIDE_EFFECTS (else_);
3755 /* First do simple transformations. */
3756 if (!else_se)
3758 /* If there is no 'else', turn
3759 if (a && b) then c
3760 into
3761 if (a) if (b) then c. */
3762 while (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
3764 /* Keep the original source location on the first 'if'. */
3765 location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
3766 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
3767 /* Set the source location of the && on the second 'if'. */
3768 if (rexpr_has_location (pred))
3769 SET_EXPR_LOCATION (expr, rexpr_location (pred));
3770 then_ = shortcut_cond_expr (expr);
3771 then_se = then_ && TREE_SIDE_EFFECTS (then_);
3772 pred = TREE_OPERAND (pred, 0);
3773 expr = build3 (COND_EXPR, void_type_node, pred, then_, NULL_TREE);
3774 SET_EXPR_LOCATION (expr, locus);
3778 if (!then_se)
3780 /* If there is no 'then', turn
3781 if (a || b); else d
3782 into
3783 if (a); else if (b); else d. */
3784 while (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
3786 /* Keep the original source location on the first 'if'. */
3787 location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
3788 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
3789 /* Set the source location of the || on the second 'if'. */
3790 if (rexpr_has_location (pred))
3791 SET_EXPR_LOCATION (expr, rexpr_location (pred));
3792 else_ = shortcut_cond_expr (expr);
3793 else_se = else_ && TREE_SIDE_EFFECTS (else_);
3794 pred = TREE_OPERAND (pred, 0);
3795 expr = build3 (COND_EXPR, void_type_node, pred, NULL_TREE, else_);
3796 SET_EXPR_LOCATION (expr, locus);
3800 /* If we're done, great. */
3801 if (TREE_CODE (pred) != TRUTH_ANDIF_EXPR
3802 && TREE_CODE (pred) != TRUTH_ORIF_EXPR)
3803 return expr;
3805 /* Otherwise we need to mess with gotos. Change
3806 if (a) c; else d;
3808 if (a); else goto no;
3809 c; goto end;
3810 no: d; end:
3811 and recursively gimplify the condition. */
3813 true_label = false_label = end_label = NULL_TREE;
3815 /* If our arms just jump somewhere, hijack those labels so we don't
3816 generate jumps to jumps. */
3818 if (tree then_goto = find_goto_label (then_))
3820 true_label = GOTO_DESTINATION (then_goto);
3821 then_ = NULL;
3822 then_se = false;
3825 if (tree else_goto = find_goto_label (else_))
3827 false_label = GOTO_DESTINATION (else_goto);
3828 else_ = NULL;
3829 else_se = false;
3832 /* If we aren't hijacking a label for the 'then' branch, it falls through. */
3833 if (true_label)
3834 true_label_p = &true_label;
3835 else
3836 true_label_p = NULL;
3838 /* The 'else' branch also needs a label if it contains interesting code. */
3839 if (false_label || else_se)
3840 false_label_p = &false_label;
3841 else
3842 false_label_p = NULL;
3844 /* If there was nothing else in our arms, just forward the label(s). */
3845 if (!then_se && !else_se)
3846 return shortcut_cond_r (pred, true_label_p, false_label_p,
3847 EXPR_LOC_OR_LOC (expr, input_location));
3849 /* If our last subexpression already has a terminal label, reuse it. */
3850 if (else_se)
3851 t = expr_last (else_);
3852 else if (then_se)
3853 t = expr_last (then_);
3854 else
3855 t = NULL;
3856 if (t && TREE_CODE (t) == LABEL_EXPR)
3857 end_label = LABEL_EXPR_LABEL (t);
3859 /* If we don't care about jumping to the 'else' branch, jump to the end
3860 if the condition is false. */
3861 if (!false_label_p)
3862 false_label_p = &end_label;
3864 /* We only want to emit these labels if we aren't hijacking them. */
3865 emit_end = (end_label == NULL_TREE);
3866 emit_false = (false_label == NULL_TREE);
3868 /* We only emit the jump over the else clause if we have to--if the
3869 then clause may fall through. Otherwise we can wind up with a
3870 useless jump and a useless label at the end of gimplified code,
3871 which will cause us to think that this conditional as a whole
3872 falls through even if it doesn't. If we then inline a function
3873 which ends with such a condition, that can cause us to issue an
3874 inappropriate warning about control reaching the end of a
3875 non-void function. */
3876 jump_over_else = block_may_fallthru (then_);
3878 pred = shortcut_cond_r (pred, true_label_p, false_label_p,
3879 EXPR_LOC_OR_LOC (expr, input_location));
3881 expr = NULL;
3882 append_to_statement_list (pred, &expr);
3884 append_to_statement_list (then_, &expr);
3885 if (else_se)
3887 if (jump_over_else)
3889 tree last = expr_last (expr);
3890 t = build_and_jump (&end_label);
3891 if (rexpr_has_location (last))
3892 SET_EXPR_LOCATION (t, rexpr_location (last));
3893 append_to_statement_list (t, &expr);
3895 if (emit_false)
3897 t = build1 (LABEL_EXPR, void_type_node, false_label);
3898 append_to_statement_list (t, &expr);
3900 append_to_statement_list (else_, &expr);
3902 if (emit_end && end_label)
3904 t = build1 (LABEL_EXPR, void_type_node, end_label);
3905 append_to_statement_list (t, &expr);
3908 return expr;
3911 /* EXPR is used in a boolean context; make sure it has BOOLEAN_TYPE. */
3913 tree
3914 gimple_boolify (tree expr)
3916 tree type = TREE_TYPE (expr);
3917 location_t loc = EXPR_LOCATION (expr);
3919 if (TREE_CODE (expr) == NE_EXPR
3920 && TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR
3921 && integer_zerop (TREE_OPERAND (expr, 1)))
3923 tree call = TREE_OPERAND (expr, 0);
3924 tree fn = get_callee_fndecl (call);
3926 /* For __builtin_expect ((long) (x), y) recurse into x as well
3927 if x is truth_value_p. */
3928 if (fn
3929 && fndecl_built_in_p (fn, BUILT_IN_EXPECT)
3930 && call_expr_nargs (call) == 2)
3932 tree arg = CALL_EXPR_ARG (call, 0);
3933 if (arg)
3935 if (TREE_CODE (arg) == NOP_EXPR
3936 && TREE_TYPE (arg) == TREE_TYPE (call))
3937 arg = TREE_OPERAND (arg, 0);
3938 if (truth_value_p (TREE_CODE (arg)))
3940 arg = gimple_boolify (arg);
3941 CALL_EXPR_ARG (call, 0)
3942 = fold_convert_loc (loc, TREE_TYPE (call), arg);
3948 switch (TREE_CODE (expr))
3950 case TRUTH_AND_EXPR:
3951 case TRUTH_OR_EXPR:
3952 case TRUTH_XOR_EXPR:
3953 case TRUTH_ANDIF_EXPR:
3954 case TRUTH_ORIF_EXPR:
3955 /* Also boolify the arguments of truth exprs. */
3956 TREE_OPERAND (expr, 1) = gimple_boolify (TREE_OPERAND (expr, 1));
3957 /* FALLTHRU */
3959 case TRUTH_NOT_EXPR:
3960 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
3962 /* These expressions always produce boolean results. */
3963 if (TREE_CODE (type) != BOOLEAN_TYPE)
3964 TREE_TYPE (expr) = boolean_type_node;
3965 return expr;
3967 case ANNOTATE_EXPR:
3968 switch ((enum annot_expr_kind) TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)))
3970 case annot_expr_ivdep_kind:
3971 case annot_expr_unroll_kind:
3972 case annot_expr_no_vector_kind:
3973 case annot_expr_vector_kind:
3974 case annot_expr_parallel_kind:
3975 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
3976 if (TREE_CODE (type) != BOOLEAN_TYPE)
3977 TREE_TYPE (expr) = boolean_type_node;
3978 return expr;
3979 default:
3980 gcc_unreachable ();
3983 default:
3984 if (COMPARISON_CLASS_P (expr))
3986 /* There expressions always prduce boolean results. */
3987 if (TREE_CODE (type) != BOOLEAN_TYPE)
3988 TREE_TYPE (expr) = boolean_type_node;
3989 return expr;
3991 /* Other expressions that get here must have boolean values, but
3992 might need to be converted to the appropriate mode. */
3993 if (TREE_CODE (type) == BOOLEAN_TYPE)
3994 return expr;
3995 return fold_convert_loc (loc, boolean_type_node, expr);
3999 /* Given a conditional expression *EXPR_P without side effects, gimplify
4000 its operands. New statements are inserted to PRE_P. */
4002 static enum gimplify_status
4003 gimplify_pure_cond_expr (tree *expr_p, gimple_seq *pre_p)
4005 tree expr = *expr_p, cond;
4006 enum gimplify_status ret, tret;
4007 enum tree_code code;
4009 cond = gimple_boolify (COND_EXPR_COND (expr));
4011 /* We need to handle && and || specially, as their gimplification
4012 creates pure cond_expr, thus leading to an infinite cycle otherwise. */
4013 code = TREE_CODE (cond);
4014 if (code == TRUTH_ANDIF_EXPR)
4015 TREE_SET_CODE (cond, TRUTH_AND_EXPR);
4016 else if (code == TRUTH_ORIF_EXPR)
4017 TREE_SET_CODE (cond, TRUTH_OR_EXPR);
4018 ret = gimplify_expr (&cond, pre_p, NULL, is_gimple_condexpr, fb_rvalue);
4019 COND_EXPR_COND (*expr_p) = cond;
4021 tret = gimplify_expr (&COND_EXPR_THEN (expr), pre_p, NULL,
4022 is_gimple_val, fb_rvalue);
4023 ret = MIN (ret, tret);
4024 tret = gimplify_expr (&COND_EXPR_ELSE (expr), pre_p, NULL,
4025 is_gimple_val, fb_rvalue);
4027 return MIN (ret, tret);
4030 /* Return true if evaluating EXPR could trap.
4031 EXPR is GENERIC, while tree_could_trap_p can be called
4032 only on GIMPLE. */
4034 bool
4035 generic_expr_could_trap_p (tree expr)
4037 unsigned i, n;
4039 if (!expr || is_gimple_val (expr))
4040 return false;
4042 if (!EXPR_P (expr) || tree_could_trap_p (expr))
4043 return true;
4045 n = TREE_OPERAND_LENGTH (expr);
4046 for (i = 0; i < n; i++)
4047 if (generic_expr_could_trap_p (TREE_OPERAND (expr, i)))
4048 return true;
4050 return false;
4053 /* Convert the conditional expression pointed to by EXPR_P '(p) ? a : b;'
4054 into
4056 if (p) if (p)
4057 t1 = a; a;
4058 else or else
4059 t1 = b; b;
4062 The second form is used when *EXPR_P is of type void.
4064 PRE_P points to the list where side effects that must happen before
4065 *EXPR_P should be stored. */
4067 static enum gimplify_status
4068 gimplify_cond_expr (tree *expr_p, gimple_seq *pre_p, fallback_t fallback)
4070 tree expr = *expr_p;
4071 tree type = TREE_TYPE (expr);
4072 location_t loc = EXPR_LOCATION (expr);
4073 tree tmp, arm1, arm2;
4074 enum gimplify_status ret;
4075 tree label_true, label_false, label_cont;
4076 bool have_then_clause_p, have_else_clause_p;
4077 gcond *cond_stmt;
4078 enum tree_code pred_code;
4079 gimple_seq seq = NULL;
4081 /* If this COND_EXPR has a value, copy the values into a temporary within
4082 the arms. */
4083 if (!VOID_TYPE_P (type))
4085 tree then_ = TREE_OPERAND (expr, 1), else_ = TREE_OPERAND (expr, 2);
4086 tree result;
4088 /* If either an rvalue is ok or we do not require an lvalue, create the
4089 temporary. But we cannot do that if the type is addressable. */
4090 if (((fallback & fb_rvalue) || !(fallback & fb_lvalue))
4091 && !TREE_ADDRESSABLE (type))
4093 if (gimplify_ctxp->allow_rhs_cond_expr
4094 /* If either branch has side effects or could trap, it can't be
4095 evaluated unconditionally. */
4096 && !TREE_SIDE_EFFECTS (then_)
4097 && !generic_expr_could_trap_p (then_)
4098 && !TREE_SIDE_EFFECTS (else_)
4099 && !generic_expr_could_trap_p (else_))
4100 return gimplify_pure_cond_expr (expr_p, pre_p);
4102 tmp = create_tmp_var (type, "iftmp");
4103 result = tmp;
4106 /* Otherwise, only create and copy references to the values. */
4107 else
4109 type = build_pointer_type (type);
4111 if (!VOID_TYPE_P (TREE_TYPE (then_)))
4112 then_ = build_fold_addr_expr_loc (loc, then_);
4114 if (!VOID_TYPE_P (TREE_TYPE (else_)))
4115 else_ = build_fold_addr_expr_loc (loc, else_);
4117 expr
4118 = build3 (COND_EXPR, type, TREE_OPERAND (expr, 0), then_, else_);
4120 tmp = create_tmp_var (type, "iftmp");
4121 result = build_simple_mem_ref_loc (loc, tmp);
4124 /* Build the new then clause, `tmp = then_;'. But don't build the
4125 assignment if the value is void; in C++ it can be if it's a throw. */
4126 if (!VOID_TYPE_P (TREE_TYPE (then_)))
4127 TREE_OPERAND (expr, 1) = build2 (INIT_EXPR, type, tmp, then_);
4129 /* Similarly, build the new else clause, `tmp = else_;'. */
4130 if (!VOID_TYPE_P (TREE_TYPE (else_)))
4131 TREE_OPERAND (expr, 2) = build2 (INIT_EXPR, type, tmp, else_);
4133 TREE_TYPE (expr) = void_type_node;
4134 recalculate_side_effects (expr);
4136 /* Move the COND_EXPR to the prequeue. */
4137 gimplify_stmt (&expr, pre_p);
4139 *expr_p = result;
4140 return GS_ALL_DONE;
4143 /* Remove any COMPOUND_EXPR so the following cases will be caught. */
4144 STRIP_TYPE_NOPS (TREE_OPERAND (expr, 0));
4145 if (TREE_CODE (TREE_OPERAND (expr, 0)) == COMPOUND_EXPR)
4146 gimplify_compound_expr (&TREE_OPERAND (expr, 0), pre_p, true);
4148 /* Make sure the condition has BOOLEAN_TYPE. */
4149 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
4151 /* Break apart && and || conditions. */
4152 if (TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ANDIF_EXPR
4153 || TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ORIF_EXPR)
4155 expr = shortcut_cond_expr (expr);
4157 if (expr != *expr_p)
4159 *expr_p = expr;
4161 /* We can't rely on gimplify_expr to re-gimplify the expanded
4162 form properly, as cleanups might cause the target labels to be
4163 wrapped in a TRY_FINALLY_EXPR. To prevent that, we need to
4164 set up a conditional context. */
4165 gimple_push_condition ();
4166 gimplify_stmt (expr_p, &seq);
4167 gimple_pop_condition (pre_p);
4168 gimple_seq_add_seq (pre_p, seq);
4170 return GS_ALL_DONE;
4174 /* Now do the normal gimplification. */
4176 /* Gimplify condition. */
4177 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL,
4178 is_gimple_condexpr_for_cond, fb_rvalue);
4179 if (ret == GS_ERROR)
4180 return GS_ERROR;
4181 gcc_assert (TREE_OPERAND (expr, 0) != NULL_TREE);
4183 gimple_push_condition ();
4185 have_then_clause_p = have_else_clause_p = false;
4186 label_true = find_goto_label (TREE_OPERAND (expr, 1));
4187 if (label_true
4188 && DECL_CONTEXT (GOTO_DESTINATION (label_true)) == current_function_decl
4189 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4190 have different locations, otherwise we end up with incorrect
4191 location information on the branches. */
4192 && (optimize
4193 || !EXPR_HAS_LOCATION (expr)
4194 || !rexpr_has_location (label_true)
4195 || EXPR_LOCATION (expr) == rexpr_location (label_true)))
4197 have_then_clause_p = true;
4198 label_true = GOTO_DESTINATION (label_true);
4200 else
4201 label_true = create_artificial_label (UNKNOWN_LOCATION);
4202 label_false = find_goto_label (TREE_OPERAND (expr, 2));
4203 if (label_false
4204 && DECL_CONTEXT (GOTO_DESTINATION (label_false)) == current_function_decl
4205 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4206 have different locations, otherwise we end up with incorrect
4207 location information on the branches. */
4208 && (optimize
4209 || !EXPR_HAS_LOCATION (expr)
4210 || !rexpr_has_location (label_false)
4211 || EXPR_LOCATION (expr) == rexpr_location (label_false)))
4213 have_else_clause_p = true;
4214 label_false = GOTO_DESTINATION (label_false);
4216 else
4217 label_false = create_artificial_label (UNKNOWN_LOCATION);
4219 gimple_cond_get_ops_from_tree (COND_EXPR_COND (expr), &pred_code, &arm1,
4220 &arm2);
4221 cond_stmt = gimple_build_cond (pred_code, arm1, arm2, label_true,
4222 label_false);
4223 gimple_set_no_warning (cond_stmt, TREE_NO_WARNING (COND_EXPR_COND (expr)));
4224 gimplify_seq_add_stmt (&seq, cond_stmt);
4225 gimple_stmt_iterator gsi = gsi_last (seq);
4226 maybe_fold_stmt (&gsi);
4228 label_cont = NULL_TREE;
4229 if (!have_then_clause_p)
4231 /* For if (...) {} else { code; } put label_true after
4232 the else block. */
4233 if (TREE_OPERAND (expr, 1) == NULL_TREE
4234 && !have_else_clause_p
4235 && TREE_OPERAND (expr, 2) != NULL_TREE)
4236 label_cont = label_true;
4237 else
4239 gimplify_seq_add_stmt (&seq, gimple_build_label (label_true));
4240 have_then_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 1), &seq);
4241 /* For if (...) { code; } else {} or
4242 if (...) { code; } else goto label; or
4243 if (...) { code; return; } else { ... }
4244 label_cont isn't needed. */
4245 if (!have_else_clause_p
4246 && TREE_OPERAND (expr, 2) != NULL_TREE
4247 && gimple_seq_may_fallthru (seq))
4249 gimple *g;
4250 label_cont = create_artificial_label (UNKNOWN_LOCATION);
4252 g = gimple_build_goto (label_cont);
4254 /* GIMPLE_COND's are very low level; they have embedded
4255 gotos. This particular embedded goto should not be marked
4256 with the location of the original COND_EXPR, as it would
4257 correspond to the COND_EXPR's condition, not the ELSE or the
4258 THEN arms. To avoid marking it with the wrong location, flag
4259 it as "no location". */
4260 gimple_set_do_not_emit_location (g);
4262 gimplify_seq_add_stmt (&seq, g);
4266 if (!have_else_clause_p)
4268 gimplify_seq_add_stmt (&seq, gimple_build_label (label_false));
4269 have_else_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 2), &seq);
4271 if (label_cont)
4272 gimplify_seq_add_stmt (&seq, gimple_build_label (label_cont));
4274 gimple_pop_condition (pre_p);
4275 gimple_seq_add_seq (pre_p, seq);
4277 if (ret == GS_ERROR)
4278 ; /* Do nothing. */
4279 else if (have_then_clause_p || have_else_clause_p)
4280 ret = GS_ALL_DONE;
4281 else
4283 /* Both arms are empty; replace the COND_EXPR with its predicate. */
4284 expr = TREE_OPERAND (expr, 0);
4285 gimplify_stmt (&expr, pre_p);
4288 *expr_p = NULL;
4289 return ret;
4292 /* Prepare the node pointed to by EXPR_P, an is_gimple_addressable expression,
4293 to be marked addressable.
4295 We cannot rely on such an expression being directly markable if a temporary
4296 has been created by the gimplification. In this case, we create another
4297 temporary and initialize it with a copy, which will become a store after we
4298 mark it addressable. This can happen if the front-end passed us something
4299 that it could not mark addressable yet, like a Fortran pass-by-reference
4300 parameter (int) floatvar. */
4302 static void
4303 prepare_gimple_addressable (tree *expr_p, gimple_seq *seq_p)
4305 while (handled_component_p (*expr_p))
4306 expr_p = &TREE_OPERAND (*expr_p, 0);
4307 if (is_gimple_reg (*expr_p))
4309 /* Do not allow an SSA name as the temporary. */
4310 tree var = get_initialized_tmp_var (*expr_p, seq_p, NULL, false);
4311 DECL_GIMPLE_REG_P (var) = 0;
4312 *expr_p = var;
4316 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4317 a call to __builtin_memcpy. */
4319 static enum gimplify_status
4320 gimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value,
4321 gimple_seq *seq_p)
4323 tree t, to, to_ptr, from, from_ptr;
4324 gcall *gs;
4325 location_t loc = EXPR_LOCATION (*expr_p);
4327 to = TREE_OPERAND (*expr_p, 0);
4328 from = TREE_OPERAND (*expr_p, 1);
4330 /* Mark the RHS addressable. Beware that it may not be possible to do so
4331 directly if a temporary has been created by the gimplification. */
4332 prepare_gimple_addressable (&from, seq_p);
4334 mark_addressable (from);
4335 from_ptr = build_fold_addr_expr_loc (loc, from);
4336 gimplify_arg (&from_ptr, seq_p, loc);
4338 mark_addressable (to);
4339 to_ptr = build_fold_addr_expr_loc (loc, to);
4340 gimplify_arg (&to_ptr, seq_p, loc);
4342 t = builtin_decl_implicit (BUILT_IN_MEMCPY);
4344 gs = gimple_build_call (t, 3, to_ptr, from_ptr, size);
4346 if (want_value)
4348 /* tmp = memcpy() */
4349 t = create_tmp_var (TREE_TYPE (to_ptr));
4350 gimple_call_set_lhs (gs, t);
4351 gimplify_seq_add_stmt (seq_p, gs);
4353 *expr_p = build_simple_mem_ref (t);
4354 return GS_ALL_DONE;
4357 gimplify_seq_add_stmt (seq_p, gs);
4358 *expr_p = NULL;
4359 return GS_ALL_DONE;
4362 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4363 a call to __builtin_memset. In this case we know that the RHS is
4364 a CONSTRUCTOR with an empty element list. */
4366 static enum gimplify_status
4367 gimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value,
4368 gimple_seq *seq_p)
4370 tree t, from, to, to_ptr;
4371 gcall *gs;
4372 location_t loc = EXPR_LOCATION (*expr_p);
4374 /* Assert our assumptions, to abort instead of producing wrong code
4375 silently if they are not met. Beware that the RHS CONSTRUCTOR might
4376 not be immediately exposed. */
4377 from = TREE_OPERAND (*expr_p, 1);
4378 if (TREE_CODE (from) == WITH_SIZE_EXPR)
4379 from = TREE_OPERAND (from, 0);
4381 gcc_assert (TREE_CODE (from) == CONSTRUCTOR
4382 && vec_safe_is_empty (CONSTRUCTOR_ELTS (from)));
4384 /* Now proceed. */
4385 to = TREE_OPERAND (*expr_p, 0);
4387 to_ptr = build_fold_addr_expr_loc (loc, to);
4388 gimplify_arg (&to_ptr, seq_p, loc);
4389 t = builtin_decl_implicit (BUILT_IN_MEMSET);
4391 gs = gimple_build_call (t, 3, to_ptr, integer_zero_node, size);
4393 if (want_value)
4395 /* tmp = memset() */
4396 t = create_tmp_var (TREE_TYPE (to_ptr));
4397 gimple_call_set_lhs (gs, t);
4398 gimplify_seq_add_stmt (seq_p, gs);
4400 *expr_p = build1 (INDIRECT_REF, TREE_TYPE (to), t);
4401 return GS_ALL_DONE;
4404 gimplify_seq_add_stmt (seq_p, gs);
4405 *expr_p = NULL;
4406 return GS_ALL_DONE;
4409 /* A subroutine of gimplify_init_ctor_preeval. Called via walk_tree,
4410 determine, cautiously, if a CONSTRUCTOR overlaps the lhs of an
4411 assignment. Return non-null if we detect a potential overlap. */
4413 struct gimplify_init_ctor_preeval_data
4415 /* The base decl of the lhs object. May be NULL, in which case we
4416 have to assume the lhs is indirect. */
4417 tree lhs_base_decl;
4419 /* The alias set of the lhs object. */
4420 alias_set_type lhs_alias_set;
4423 static tree
4424 gimplify_init_ctor_preeval_1 (tree *tp, int *walk_subtrees, void *xdata)
4426 struct gimplify_init_ctor_preeval_data *data
4427 = (struct gimplify_init_ctor_preeval_data *) xdata;
4428 tree t = *tp;
4430 /* If we find the base object, obviously we have overlap. */
4431 if (data->lhs_base_decl == t)
4432 return t;
4434 /* If the constructor component is indirect, determine if we have a
4435 potential overlap with the lhs. The only bits of information we
4436 have to go on at this point are addressability and alias sets. */
4437 if ((INDIRECT_REF_P (t)
4438 || TREE_CODE (t) == MEM_REF)
4439 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
4440 && alias_sets_conflict_p (data->lhs_alias_set, get_alias_set (t)))
4441 return t;
4443 /* If the constructor component is a call, determine if it can hide a
4444 potential overlap with the lhs through an INDIRECT_REF like above.
4445 ??? Ugh - this is completely broken. In fact this whole analysis
4446 doesn't look conservative. */
4447 if (TREE_CODE (t) == CALL_EXPR)
4449 tree type, fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (t)));
4451 for (type = TYPE_ARG_TYPES (fntype); type; type = TREE_CHAIN (type))
4452 if (POINTER_TYPE_P (TREE_VALUE (type))
4453 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
4454 && alias_sets_conflict_p (data->lhs_alias_set,
4455 get_alias_set
4456 (TREE_TYPE (TREE_VALUE (type)))))
4457 return t;
4460 if (IS_TYPE_OR_DECL_P (t))
4461 *walk_subtrees = 0;
4462 return NULL;
4465 /* A subroutine of gimplify_init_constructor. Pre-evaluate EXPR,
4466 force values that overlap with the lhs (as described by *DATA)
4467 into temporaries. */
4469 static void
4470 gimplify_init_ctor_preeval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
4471 struct gimplify_init_ctor_preeval_data *data)
4473 enum gimplify_status one;
4475 /* If the value is constant, then there's nothing to pre-evaluate. */
4476 if (TREE_CONSTANT (*expr_p))
4478 /* Ensure it does not have side effects, it might contain a reference to
4479 the object we're initializing. */
4480 gcc_assert (!TREE_SIDE_EFFECTS (*expr_p));
4481 return;
4484 /* If the type has non-trivial constructors, we can't pre-evaluate. */
4485 if (TREE_ADDRESSABLE (TREE_TYPE (*expr_p)))
4486 return;
4488 /* Recurse for nested constructors. */
4489 if (TREE_CODE (*expr_p) == CONSTRUCTOR)
4491 unsigned HOST_WIDE_INT ix;
4492 constructor_elt *ce;
4493 vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (*expr_p);
4495 FOR_EACH_VEC_SAFE_ELT (v, ix, ce)
4496 gimplify_init_ctor_preeval (&ce->value, pre_p, post_p, data);
4498 return;
4501 /* If this is a variable sized type, we must remember the size. */
4502 maybe_with_size_expr (expr_p);
4504 /* Gimplify the constructor element to something appropriate for the rhs
4505 of a MODIFY_EXPR. Given that we know the LHS is an aggregate, we know
4506 the gimplifier will consider this a store to memory. Doing this
4507 gimplification now means that we won't have to deal with complicated
4508 language-specific trees, nor trees like SAVE_EXPR that can induce
4509 exponential search behavior. */
4510 one = gimplify_expr (expr_p, pre_p, post_p, is_gimple_mem_rhs, fb_rvalue);
4511 if (one == GS_ERROR)
4513 *expr_p = NULL;
4514 return;
4517 /* If we gimplified to a bare decl, we can be sure that it doesn't overlap
4518 with the lhs, since "a = { .x=a }" doesn't make sense. This will
4519 always be true for all scalars, since is_gimple_mem_rhs insists on a
4520 temporary variable for them. */
4521 if (DECL_P (*expr_p))
4522 return;
4524 /* If this is of variable size, we have no choice but to assume it doesn't
4525 overlap since we can't make a temporary for it. */
4526 if (TREE_CODE (TYPE_SIZE (TREE_TYPE (*expr_p))) != INTEGER_CST)
4527 return;
4529 /* Otherwise, we must search for overlap ... */
4530 if (!walk_tree (expr_p, gimplify_init_ctor_preeval_1, data, NULL))
4531 return;
4533 /* ... and if found, force the value into a temporary. */
4534 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
4537 /* A subroutine of gimplify_init_ctor_eval. Create a loop for
4538 a RANGE_EXPR in a CONSTRUCTOR for an array.
4540 var = lower;
4541 loop_entry:
4542 object[var] = value;
4543 if (var == upper)
4544 goto loop_exit;
4545 var = var + 1;
4546 goto loop_entry;
4547 loop_exit:
4549 We increment var _after_ the loop exit check because we might otherwise
4550 fail if upper == TYPE_MAX_VALUE (type for upper).
4552 Note that we never have to deal with SAVE_EXPRs here, because this has
4553 already been taken care of for us, in gimplify_init_ctor_preeval(). */
4555 static void gimplify_init_ctor_eval (tree, vec<constructor_elt, va_gc> *,
4556 gimple_seq *, bool);
4558 static void
4559 gimplify_init_ctor_eval_range (tree object, tree lower, tree upper,
4560 tree value, tree array_elt_type,
4561 gimple_seq *pre_p, bool cleared)
4563 tree loop_entry_label, loop_exit_label, fall_thru_label;
4564 tree var, var_type, cref, tmp;
4566 loop_entry_label = create_artificial_label (UNKNOWN_LOCATION);
4567 loop_exit_label = create_artificial_label (UNKNOWN_LOCATION);
4568 fall_thru_label = create_artificial_label (UNKNOWN_LOCATION);
4570 /* Create and initialize the index variable. */
4571 var_type = TREE_TYPE (upper);
4572 var = create_tmp_var (var_type);
4573 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, lower));
4575 /* Add the loop entry label. */
4576 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_entry_label));
4578 /* Build the reference. */
4579 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
4580 var, NULL_TREE, NULL_TREE);
4582 /* If we are a constructor, just call gimplify_init_ctor_eval to do
4583 the store. Otherwise just assign value to the reference. */
4585 if (TREE_CODE (value) == CONSTRUCTOR)
4586 /* NB we might have to call ourself recursively through
4587 gimplify_init_ctor_eval if the value is a constructor. */
4588 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
4589 pre_p, cleared);
4590 else
4591 gimplify_seq_add_stmt (pre_p, gimple_build_assign (cref, value));
4593 /* We exit the loop when the index var is equal to the upper bound. */
4594 gimplify_seq_add_stmt (pre_p,
4595 gimple_build_cond (EQ_EXPR, var, upper,
4596 loop_exit_label, fall_thru_label));
4598 gimplify_seq_add_stmt (pre_p, gimple_build_label (fall_thru_label));
4600 /* Otherwise, increment the index var... */
4601 tmp = build2 (PLUS_EXPR, var_type, var,
4602 fold_convert (var_type, integer_one_node));
4603 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, tmp));
4605 /* ...and jump back to the loop entry. */
4606 gimplify_seq_add_stmt (pre_p, gimple_build_goto (loop_entry_label));
4608 /* Add the loop exit label. */
4609 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_exit_label));
4612 /* Return true if FDECL is accessing a field that is zero sized. */
4614 static bool
4615 zero_sized_field_decl (const_tree fdecl)
4617 if (TREE_CODE (fdecl) == FIELD_DECL && DECL_SIZE (fdecl)
4618 && integer_zerop (DECL_SIZE (fdecl)))
4619 return true;
4620 return false;
4623 /* Return true if TYPE is zero sized. */
4625 static bool
4626 zero_sized_type (const_tree type)
4628 if (AGGREGATE_TYPE_P (type) && TYPE_SIZE (type)
4629 && integer_zerop (TYPE_SIZE (type)))
4630 return true;
4631 return false;
4634 /* A subroutine of gimplify_init_constructor. Generate individual
4635 MODIFY_EXPRs for a CONSTRUCTOR. OBJECT is the LHS against which the
4636 assignments should happen. ELTS is the CONSTRUCTOR_ELTS of the
4637 CONSTRUCTOR. CLEARED is true if the entire LHS object has been
4638 zeroed first. */
4640 static void
4641 gimplify_init_ctor_eval (tree object, vec<constructor_elt, va_gc> *elts,
4642 gimple_seq *pre_p, bool cleared)
4644 tree array_elt_type = NULL;
4645 unsigned HOST_WIDE_INT ix;
4646 tree purpose, value;
4648 if (TREE_CODE (TREE_TYPE (object)) == ARRAY_TYPE)
4649 array_elt_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (object)));
4651 FOR_EACH_CONSTRUCTOR_ELT (elts, ix, purpose, value)
4653 tree cref;
4655 /* NULL values are created above for gimplification errors. */
4656 if (value == NULL)
4657 continue;
4659 if (cleared && initializer_zerop (value))
4660 continue;
4662 /* ??? Here's to hoping the front end fills in all of the indices,
4663 so we don't have to figure out what's missing ourselves. */
4664 gcc_assert (purpose);
4666 /* Skip zero-sized fields, unless value has side-effects. This can
4667 happen with calls to functions returning a zero-sized type, which
4668 we shouldn't discard. As a number of downstream passes don't
4669 expect sets of zero-sized fields, we rely on the gimplification of
4670 the MODIFY_EXPR we make below to drop the assignment statement. */
4671 if (! TREE_SIDE_EFFECTS (value) && zero_sized_field_decl (purpose))
4672 continue;
4674 /* If we have a RANGE_EXPR, we have to build a loop to assign the
4675 whole range. */
4676 if (TREE_CODE (purpose) == RANGE_EXPR)
4678 tree lower = TREE_OPERAND (purpose, 0);
4679 tree upper = TREE_OPERAND (purpose, 1);
4681 /* If the lower bound is equal to upper, just treat it as if
4682 upper was the index. */
4683 if (simple_cst_equal (lower, upper))
4684 purpose = upper;
4685 else
4687 gimplify_init_ctor_eval_range (object, lower, upper, value,
4688 array_elt_type, pre_p, cleared);
4689 continue;
4693 if (array_elt_type)
4695 /* Do not use bitsizetype for ARRAY_REF indices. */
4696 if (TYPE_DOMAIN (TREE_TYPE (object)))
4697 purpose
4698 = fold_convert (TREE_TYPE (TYPE_DOMAIN (TREE_TYPE (object))),
4699 purpose);
4700 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
4701 purpose, NULL_TREE, NULL_TREE);
4703 else
4705 gcc_assert (TREE_CODE (purpose) == FIELD_DECL);
4706 cref = build3 (COMPONENT_REF, TREE_TYPE (purpose),
4707 unshare_expr (object), purpose, NULL_TREE);
4710 if (TREE_CODE (value) == CONSTRUCTOR
4711 && TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE)
4712 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
4713 pre_p, cleared);
4714 else
4716 tree init = build2 (INIT_EXPR, TREE_TYPE (cref), cref, value);
4717 gimplify_and_add (init, pre_p);
4718 ggc_free (init);
4723 /* Return the appropriate RHS predicate for this LHS. */
4725 gimple_predicate
4726 rhs_predicate_for (tree lhs)
4728 if (is_gimple_reg (lhs))
4729 return is_gimple_reg_rhs_or_call;
4730 else
4731 return is_gimple_mem_rhs_or_call;
4734 /* Return the initial guess for an appropriate RHS predicate for this LHS,
4735 before the LHS has been gimplified. */
4737 static gimple_predicate
4738 initial_rhs_predicate_for (tree lhs)
4740 if (is_gimple_reg_type (TREE_TYPE (lhs)))
4741 return is_gimple_reg_rhs_or_call;
4742 else
4743 return is_gimple_mem_rhs_or_call;
4746 /* Gimplify a C99 compound literal expression. This just means adding
4747 the DECL_EXPR before the current statement and using its anonymous
4748 decl instead. */
4750 static enum gimplify_status
4751 gimplify_compound_literal_expr (tree *expr_p, gimple_seq *pre_p,
4752 bool (*gimple_test_f) (tree),
4753 fallback_t fallback)
4755 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (*expr_p);
4756 tree decl = DECL_EXPR_DECL (decl_s);
4757 tree init = DECL_INITIAL (decl);
4758 /* Mark the decl as addressable if the compound literal
4759 expression is addressable now, otherwise it is marked too late
4760 after we gimplify the initialization expression. */
4761 if (TREE_ADDRESSABLE (*expr_p))
4762 TREE_ADDRESSABLE (decl) = 1;
4763 /* Otherwise, if we don't need an lvalue and have a literal directly
4764 substitute it. Check if it matches the gimple predicate, as
4765 otherwise we'd generate a new temporary, and we can as well just
4766 use the decl we already have. */
4767 else if (!TREE_ADDRESSABLE (decl)
4768 && !TREE_THIS_VOLATILE (decl)
4769 && init
4770 && (fallback & fb_lvalue) == 0
4771 && gimple_test_f (init))
4773 *expr_p = init;
4774 return GS_OK;
4777 /* Preliminarily mark non-addressed complex variables as eligible
4778 for promotion to gimple registers. We'll transform their uses
4779 as we find them. */
4780 if ((TREE_CODE (TREE_TYPE (decl)) == COMPLEX_TYPE
4781 || TREE_CODE (TREE_TYPE (decl)) == VECTOR_TYPE)
4782 && !TREE_THIS_VOLATILE (decl)
4783 && !needs_to_live_in_memory (decl))
4784 DECL_GIMPLE_REG_P (decl) = 1;
4786 /* If the decl is not addressable, then it is being used in some
4787 expression or on the right hand side of a statement, and it can
4788 be put into a readonly data section. */
4789 if (!TREE_ADDRESSABLE (decl) && (fallback & fb_lvalue) == 0)
4790 TREE_READONLY (decl) = 1;
4792 /* This decl isn't mentioned in the enclosing block, so add it to the
4793 list of temps. FIXME it seems a bit of a kludge to say that
4794 anonymous artificial vars aren't pushed, but everything else is. */
4795 if (DECL_NAME (decl) == NULL_TREE && !DECL_SEEN_IN_BIND_EXPR_P (decl))
4796 gimple_add_tmp_var (decl);
4798 gimplify_and_add (decl_s, pre_p);
4799 *expr_p = decl;
4800 return GS_OK;
4803 /* Optimize embedded COMPOUND_LITERAL_EXPRs within a CONSTRUCTOR,
4804 return a new CONSTRUCTOR if something changed. */
4806 static tree
4807 optimize_compound_literals_in_ctor (tree orig_ctor)
4809 tree ctor = orig_ctor;
4810 vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ctor);
4811 unsigned int idx, num = vec_safe_length (elts);
4813 for (idx = 0; idx < num; idx++)
4815 tree value = (*elts)[idx].value;
4816 tree newval = value;
4817 if (TREE_CODE (value) == CONSTRUCTOR)
4818 newval = optimize_compound_literals_in_ctor (value);
4819 else if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR)
4821 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (value);
4822 tree decl = DECL_EXPR_DECL (decl_s);
4823 tree init = DECL_INITIAL (decl);
4825 if (!TREE_ADDRESSABLE (value)
4826 && !TREE_ADDRESSABLE (decl)
4827 && init
4828 && TREE_CODE (init) == CONSTRUCTOR)
4829 newval = optimize_compound_literals_in_ctor (init);
4831 if (newval == value)
4832 continue;
4834 if (ctor == orig_ctor)
4836 ctor = copy_node (orig_ctor);
4837 CONSTRUCTOR_ELTS (ctor) = vec_safe_copy (elts);
4838 elts = CONSTRUCTOR_ELTS (ctor);
4840 (*elts)[idx].value = newval;
4842 return ctor;
4845 /* A subroutine of gimplify_modify_expr. Break out elements of a
4846 CONSTRUCTOR used as an initializer into separate MODIFY_EXPRs.
4848 Note that we still need to clear any elements that don't have explicit
4849 initializers, so if not all elements are initialized we keep the
4850 original MODIFY_EXPR, we just remove all of the constructor elements.
4852 If NOTIFY_TEMP_CREATION is true, do not gimplify, just return
4853 GS_ERROR if we would have to create a temporary when gimplifying
4854 this constructor. Otherwise, return GS_OK.
4856 If NOTIFY_TEMP_CREATION is false, just do the gimplification. */
4858 static enum gimplify_status
4859 gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
4860 bool want_value, bool notify_temp_creation)
4862 tree object, ctor, type;
4863 enum gimplify_status ret;
4864 vec<constructor_elt, va_gc> *elts;
4866 gcc_assert (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == CONSTRUCTOR);
4868 if (!notify_temp_creation)
4870 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
4871 is_gimple_lvalue, fb_lvalue);
4872 if (ret == GS_ERROR)
4873 return ret;
4876 object = TREE_OPERAND (*expr_p, 0);
4877 ctor = TREE_OPERAND (*expr_p, 1)
4878 = optimize_compound_literals_in_ctor (TREE_OPERAND (*expr_p, 1));
4879 type = TREE_TYPE (ctor);
4880 elts = CONSTRUCTOR_ELTS (ctor);
4881 ret = GS_ALL_DONE;
4883 switch (TREE_CODE (type))
4885 case RECORD_TYPE:
4886 case UNION_TYPE:
4887 case QUAL_UNION_TYPE:
4888 case ARRAY_TYPE:
4890 struct gimplify_init_ctor_preeval_data preeval_data;
4891 HOST_WIDE_INT num_ctor_elements, num_nonzero_elements;
4892 HOST_WIDE_INT num_unique_nonzero_elements;
4893 bool cleared, complete_p, valid_const_initializer;
4894 /* Use readonly data for initializers of this or smaller size
4895 regardless of the num_nonzero_elements / num_unique_nonzero_elements
4896 ratio. */
4897 const HOST_WIDE_INT min_unique_size = 64;
4898 /* If num_nonzero_elements / num_unique_nonzero_elements ratio
4899 is smaller than this, use readonly data. */
4900 const int unique_nonzero_ratio = 8;
4902 /* Aggregate types must lower constructors to initialization of
4903 individual elements. The exception is that a CONSTRUCTOR node
4904 with no elements indicates zero-initialization of the whole. */
4905 if (vec_safe_is_empty (elts))
4907 if (notify_temp_creation)
4908 return GS_OK;
4909 break;
4912 /* Fetch information about the constructor to direct later processing.
4913 We might want to make static versions of it in various cases, and
4914 can only do so if it known to be a valid constant initializer. */
4915 valid_const_initializer
4916 = categorize_ctor_elements (ctor, &num_nonzero_elements,
4917 &num_unique_nonzero_elements,
4918 &num_ctor_elements, &complete_p);
4920 /* If a const aggregate variable is being initialized, then it
4921 should never be a lose to promote the variable to be static. */
4922 if (valid_const_initializer
4923 && num_nonzero_elements > 1
4924 && TREE_READONLY (object)
4925 && VAR_P (object)
4926 && !DECL_REGISTER (object)
4927 && (flag_merge_constants >= 2 || !TREE_ADDRESSABLE (object))
4928 /* For ctors that have many repeated nonzero elements
4929 represented through RANGE_EXPRs, prefer initializing
4930 those through runtime loops over copies of large amounts
4931 of data from readonly data section. */
4932 && (num_unique_nonzero_elements
4933 > num_nonzero_elements / unique_nonzero_ratio
4934 || ((unsigned HOST_WIDE_INT) int_size_in_bytes (type)
4935 <= (unsigned HOST_WIDE_INT) min_unique_size)))
4937 if (notify_temp_creation)
4938 return GS_ERROR;
4939 DECL_INITIAL (object) = ctor;
4940 TREE_STATIC (object) = 1;
4941 if (!DECL_NAME (object))
4942 DECL_NAME (object) = create_tmp_var_name ("C");
4943 walk_tree (&DECL_INITIAL (object), force_labels_r, NULL, NULL);
4945 /* ??? C++ doesn't automatically append a .<number> to the
4946 assembler name, and even when it does, it looks at FE private
4947 data structures to figure out what that number should be,
4948 which are not set for this variable. I suppose this is
4949 important for local statics for inline functions, which aren't
4950 "local" in the object file sense. So in order to get a unique
4951 TU-local symbol, we must invoke the lhd version now. */
4952 lhd_set_decl_assembler_name (object);
4954 *expr_p = NULL_TREE;
4955 break;
4958 /* If there are "lots" of initialized elements, even discounting
4959 those that are not address constants (and thus *must* be
4960 computed at runtime), then partition the constructor into
4961 constant and non-constant parts. Block copy the constant
4962 parts in, then generate code for the non-constant parts. */
4963 /* TODO. There's code in cp/typeck.c to do this. */
4965 if (int_size_in_bytes (TREE_TYPE (ctor)) < 0)
4966 /* store_constructor will ignore the clearing of variable-sized
4967 objects. Initializers for such objects must explicitly set
4968 every field that needs to be set. */
4969 cleared = false;
4970 else if (!complete_p)
4971 /* If the constructor isn't complete, clear the whole object
4972 beforehand, unless CONSTRUCTOR_NO_CLEARING is set on it.
4974 ??? This ought not to be needed. For any element not present
4975 in the initializer, we should simply set them to zero. Except
4976 we'd need to *find* the elements that are not present, and that
4977 requires trickery to avoid quadratic compile-time behavior in
4978 large cases or excessive memory use in small cases. */
4979 cleared = !CONSTRUCTOR_NO_CLEARING (ctor);
4980 else if (num_ctor_elements - num_nonzero_elements
4981 > CLEAR_RATIO (optimize_function_for_speed_p (cfun))
4982 && num_nonzero_elements < num_ctor_elements / 4)
4983 /* If there are "lots" of zeros, it's more efficient to clear
4984 the memory and then set the nonzero elements. */
4985 cleared = true;
4986 else
4987 cleared = false;
4989 /* If there are "lots" of initialized elements, and all of them
4990 are valid address constants, then the entire initializer can
4991 be dropped to memory, and then memcpy'd out. Don't do this
4992 for sparse arrays, though, as it's more efficient to follow
4993 the standard CONSTRUCTOR behavior of memset followed by
4994 individual element initialization. Also don't do this for small
4995 all-zero initializers (which aren't big enough to merit
4996 clearing), and don't try to make bitwise copies of
4997 TREE_ADDRESSABLE types. */
4999 if (valid_const_initializer
5000 && !(cleared || num_nonzero_elements == 0)
5001 && !TREE_ADDRESSABLE (type))
5003 HOST_WIDE_INT size = int_size_in_bytes (type);
5004 unsigned int align;
5006 /* ??? We can still get unbounded array types, at least
5007 from the C++ front end. This seems wrong, but attempt
5008 to work around it for now. */
5009 if (size < 0)
5011 size = int_size_in_bytes (TREE_TYPE (object));
5012 if (size >= 0)
5013 TREE_TYPE (ctor) = type = TREE_TYPE (object);
5016 /* Find the maximum alignment we can assume for the object. */
5017 /* ??? Make use of DECL_OFFSET_ALIGN. */
5018 if (DECL_P (object))
5019 align = DECL_ALIGN (object);
5020 else
5021 align = TYPE_ALIGN (type);
5023 /* Do a block move either if the size is so small as to make
5024 each individual move a sub-unit move on average, or if it
5025 is so large as to make individual moves inefficient. */
5026 if (size > 0
5027 && num_nonzero_elements > 1
5028 /* For ctors that have many repeated nonzero elements
5029 represented through RANGE_EXPRs, prefer initializing
5030 those through runtime loops over copies of large amounts
5031 of data from readonly data section. */
5032 && (num_unique_nonzero_elements
5033 > num_nonzero_elements / unique_nonzero_ratio
5034 || size <= min_unique_size)
5035 && (size < num_nonzero_elements
5036 || !can_move_by_pieces (size, align)))
5038 if (notify_temp_creation)
5039 return GS_ERROR;
5041 walk_tree (&ctor, force_labels_r, NULL, NULL);
5042 ctor = tree_output_constant_def (ctor);
5043 if (!useless_type_conversion_p (type, TREE_TYPE (ctor)))
5044 ctor = build1 (VIEW_CONVERT_EXPR, type, ctor);
5045 TREE_OPERAND (*expr_p, 1) = ctor;
5047 /* This is no longer an assignment of a CONSTRUCTOR, but
5048 we still may have processing to do on the LHS. So
5049 pretend we didn't do anything here to let that happen. */
5050 return GS_UNHANDLED;
5054 /* If the target is volatile, we have non-zero elements and more than
5055 one field to assign, initialize the target from a temporary. */
5056 if (TREE_THIS_VOLATILE (object)
5057 && !TREE_ADDRESSABLE (type)
5058 && (num_nonzero_elements > 0 || !cleared)
5059 && vec_safe_length (elts) > 1)
5061 tree temp = create_tmp_var (TYPE_MAIN_VARIANT (type));
5062 TREE_OPERAND (*expr_p, 0) = temp;
5063 *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p),
5064 *expr_p,
5065 build2 (MODIFY_EXPR, void_type_node,
5066 object, temp));
5067 return GS_OK;
5070 if (notify_temp_creation)
5071 return GS_OK;
5073 /* If there are nonzero elements and if needed, pre-evaluate to capture
5074 elements overlapping with the lhs into temporaries. We must do this
5075 before clearing to fetch the values before they are zeroed-out. */
5076 if (num_nonzero_elements > 0 && TREE_CODE (*expr_p) != INIT_EXPR)
5078 preeval_data.lhs_base_decl = get_base_address (object);
5079 if (!DECL_P (preeval_data.lhs_base_decl))
5080 preeval_data.lhs_base_decl = NULL;
5081 preeval_data.lhs_alias_set = get_alias_set (object);
5083 gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p, 1),
5084 pre_p, post_p, &preeval_data);
5087 bool ctor_has_side_effects_p
5088 = TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p, 1));
5090 if (cleared)
5092 /* Zap the CONSTRUCTOR element list, which simplifies this case.
5093 Note that we still have to gimplify, in order to handle the
5094 case of variable sized types. Avoid shared tree structures. */
5095 CONSTRUCTOR_ELTS (ctor) = NULL;
5096 TREE_SIDE_EFFECTS (ctor) = 0;
5097 object = unshare_expr (object);
5098 gimplify_stmt (expr_p, pre_p);
5101 /* If we have not block cleared the object, or if there are nonzero
5102 elements in the constructor, or if the constructor has side effects,
5103 add assignments to the individual scalar fields of the object. */
5104 if (!cleared
5105 || num_nonzero_elements > 0
5106 || ctor_has_side_effects_p)
5107 gimplify_init_ctor_eval (object, elts, pre_p, cleared);
5109 *expr_p = NULL_TREE;
5111 break;
5113 case COMPLEX_TYPE:
5115 tree r, i;
5117 if (notify_temp_creation)
5118 return GS_OK;
5120 /* Extract the real and imaginary parts out of the ctor. */
5121 gcc_assert (elts->length () == 2);
5122 r = (*elts)[0].value;
5123 i = (*elts)[1].value;
5124 if (r == NULL || i == NULL)
5126 tree zero = build_zero_cst (TREE_TYPE (type));
5127 if (r == NULL)
5128 r = zero;
5129 if (i == NULL)
5130 i = zero;
5133 /* Complex types have either COMPLEX_CST or COMPLEX_EXPR to
5134 represent creation of a complex value. */
5135 if (TREE_CONSTANT (r) && TREE_CONSTANT (i))
5137 ctor = build_complex (type, r, i);
5138 TREE_OPERAND (*expr_p, 1) = ctor;
5140 else
5142 ctor = build2 (COMPLEX_EXPR, type, r, i);
5143 TREE_OPERAND (*expr_p, 1) = ctor;
5144 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 1),
5145 pre_p,
5146 post_p,
5147 rhs_predicate_for (TREE_OPERAND (*expr_p, 0)),
5148 fb_rvalue);
5151 break;
5153 case VECTOR_TYPE:
5155 unsigned HOST_WIDE_INT ix;
5156 constructor_elt *ce;
5158 if (notify_temp_creation)
5159 return GS_OK;
5161 /* Go ahead and simplify constant constructors to VECTOR_CST. */
5162 if (TREE_CONSTANT (ctor))
5164 bool constant_p = true;
5165 tree value;
5167 /* Even when ctor is constant, it might contain non-*_CST
5168 elements, such as addresses or trapping values like
5169 1.0/0.0 - 1.0/0.0. Such expressions don't belong
5170 in VECTOR_CST nodes. */
5171 FOR_EACH_CONSTRUCTOR_VALUE (elts, ix, value)
5172 if (!CONSTANT_CLASS_P (value))
5174 constant_p = false;
5175 break;
5178 if (constant_p)
5180 TREE_OPERAND (*expr_p, 1) = build_vector_from_ctor (type, elts);
5181 break;
5184 TREE_CONSTANT (ctor) = 0;
5187 /* Vector types use CONSTRUCTOR all the way through gimple
5188 compilation as a general initializer. */
5189 FOR_EACH_VEC_SAFE_ELT (elts, ix, ce)
5191 enum gimplify_status tret;
5192 tret = gimplify_expr (&ce->value, pre_p, post_p, is_gimple_val,
5193 fb_rvalue);
5194 if (tret == GS_ERROR)
5195 ret = GS_ERROR;
5196 else if (TREE_STATIC (ctor)
5197 && !initializer_constant_valid_p (ce->value,
5198 TREE_TYPE (ce->value)))
5199 TREE_STATIC (ctor) = 0;
5201 if (!is_gimple_reg (TREE_OPERAND (*expr_p, 0)))
5202 TREE_OPERAND (*expr_p, 1) = get_formal_tmp_var (ctor, pre_p);
5204 break;
5206 default:
5207 /* So how did we get a CONSTRUCTOR for a scalar type? */
5208 gcc_unreachable ();
5211 if (ret == GS_ERROR)
5212 return GS_ERROR;
5213 /* If we have gimplified both sides of the initializer but have
5214 not emitted an assignment, do so now. */
5215 if (*expr_p)
5217 tree lhs = TREE_OPERAND (*expr_p, 0);
5218 tree rhs = TREE_OPERAND (*expr_p, 1);
5219 if (want_value && object == lhs)
5220 lhs = unshare_expr (lhs);
5221 gassign *init = gimple_build_assign (lhs, rhs);
5222 gimplify_seq_add_stmt (pre_p, init);
5224 if (want_value)
5226 *expr_p = object;
5227 return GS_OK;
5229 else
5231 *expr_p = NULL;
5232 return GS_ALL_DONE;
5236 /* Given a pointer value OP0, return a simplified version of an
5237 indirection through OP0, or NULL_TREE if no simplification is
5238 possible. This may only be applied to a rhs of an expression.
5239 Note that the resulting type may be different from the type pointed
5240 to in the sense that it is still compatible from the langhooks
5241 point of view. */
5243 static tree
5244 gimple_fold_indirect_ref_rhs (tree t)
5246 return gimple_fold_indirect_ref (t);
5249 /* Subroutine of gimplify_modify_expr to do simplifications of
5250 MODIFY_EXPRs based on the code of the RHS. We loop for as long as
5251 something changes. */
5253 static enum gimplify_status
5254 gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p,
5255 gimple_seq *pre_p, gimple_seq *post_p,
5256 bool want_value)
5258 enum gimplify_status ret = GS_UNHANDLED;
5259 bool changed;
5263 changed = false;
5264 switch (TREE_CODE (*from_p))
5266 case VAR_DECL:
5267 /* If we're assigning from a read-only variable initialized with
5268 a constructor, do the direct assignment from the constructor,
5269 but only if neither source nor target are volatile since this
5270 latter assignment might end up being done on a per-field basis. */
5271 if (DECL_INITIAL (*from_p)
5272 && TREE_READONLY (*from_p)
5273 && !TREE_THIS_VOLATILE (*from_p)
5274 && !TREE_THIS_VOLATILE (*to_p)
5275 && TREE_CODE (DECL_INITIAL (*from_p)) == CONSTRUCTOR)
5277 tree old_from = *from_p;
5278 enum gimplify_status subret;
5280 /* Move the constructor into the RHS. */
5281 *from_p = unshare_expr (DECL_INITIAL (*from_p));
5283 /* Let's see if gimplify_init_constructor will need to put
5284 it in memory. */
5285 subret = gimplify_init_constructor (expr_p, NULL, NULL,
5286 false, true);
5287 if (subret == GS_ERROR)
5289 /* If so, revert the change. */
5290 *from_p = old_from;
5292 else
5294 ret = GS_OK;
5295 changed = true;
5298 break;
5299 case INDIRECT_REF:
5301 /* If we have code like
5303 *(const A*)(A*)&x
5305 where the type of "x" is a (possibly cv-qualified variant
5306 of "A"), treat the entire expression as identical to "x".
5307 This kind of code arises in C++ when an object is bound
5308 to a const reference, and if "x" is a TARGET_EXPR we want
5309 to take advantage of the optimization below. */
5310 bool volatile_p = TREE_THIS_VOLATILE (*from_p);
5311 tree t = gimple_fold_indirect_ref_rhs (TREE_OPERAND (*from_p, 0));
5312 if (t)
5314 if (TREE_THIS_VOLATILE (t) != volatile_p)
5316 if (DECL_P (t))
5317 t = build_simple_mem_ref_loc (EXPR_LOCATION (*from_p),
5318 build_fold_addr_expr (t));
5319 if (REFERENCE_CLASS_P (t))
5320 TREE_THIS_VOLATILE (t) = volatile_p;
5322 *from_p = t;
5323 ret = GS_OK;
5324 changed = true;
5326 break;
5329 case TARGET_EXPR:
5331 /* If we are initializing something from a TARGET_EXPR, strip the
5332 TARGET_EXPR and initialize it directly, if possible. This can't
5333 be done if the initializer is void, since that implies that the
5334 temporary is set in some non-trivial way.
5336 ??? What about code that pulls out the temp and uses it
5337 elsewhere? I think that such code never uses the TARGET_EXPR as
5338 an initializer. If I'm wrong, we'll die because the temp won't
5339 have any RTL. In that case, I guess we'll need to replace
5340 references somehow. */
5341 tree init = TARGET_EXPR_INITIAL (*from_p);
5343 if (init
5344 && (TREE_CODE (*expr_p) != MODIFY_EXPR
5345 || !TARGET_EXPR_NO_ELIDE (*from_p))
5346 && !VOID_TYPE_P (TREE_TYPE (init)))
5348 *from_p = init;
5349 ret = GS_OK;
5350 changed = true;
5353 break;
5355 case COMPOUND_EXPR:
5356 /* Remove any COMPOUND_EXPR in the RHS so the following cases will be
5357 caught. */
5358 gimplify_compound_expr (from_p, pre_p, true);
5359 ret = GS_OK;
5360 changed = true;
5361 break;
5363 case CONSTRUCTOR:
5364 /* If we already made some changes, let the front end have a
5365 crack at this before we break it down. */
5366 if (ret != GS_UNHANDLED)
5367 break;
5368 /* If we're initializing from a CONSTRUCTOR, break this into
5369 individual MODIFY_EXPRs. */
5370 return gimplify_init_constructor (expr_p, pre_p, post_p, want_value,
5371 false);
5373 case COND_EXPR:
5374 /* If we're assigning to a non-register type, push the assignment
5375 down into the branches. This is mandatory for ADDRESSABLE types,
5376 since we cannot generate temporaries for such, but it saves a
5377 copy in other cases as well. */
5378 if (!is_gimple_reg_type (TREE_TYPE (*from_p)))
5380 /* This code should mirror the code in gimplify_cond_expr. */
5381 enum tree_code code = TREE_CODE (*expr_p);
5382 tree cond = *from_p;
5383 tree result = *to_p;
5385 ret = gimplify_expr (&result, pre_p, post_p,
5386 is_gimple_lvalue, fb_lvalue);
5387 if (ret != GS_ERROR)
5388 ret = GS_OK;
5390 /* If we are going to write RESULT more than once, clear
5391 TREE_READONLY flag, otherwise we might incorrectly promote
5392 the variable to static const and initialize it at compile
5393 time in one of the branches. */
5394 if (VAR_P (result)
5395 && TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node
5396 && TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
5397 TREE_READONLY (result) = 0;
5398 if (TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node)
5399 TREE_OPERAND (cond, 1)
5400 = build2 (code, void_type_node, result,
5401 TREE_OPERAND (cond, 1));
5402 if (TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
5403 TREE_OPERAND (cond, 2)
5404 = build2 (code, void_type_node, unshare_expr (result),
5405 TREE_OPERAND (cond, 2));
5407 TREE_TYPE (cond) = void_type_node;
5408 recalculate_side_effects (cond);
5410 if (want_value)
5412 gimplify_and_add (cond, pre_p);
5413 *expr_p = unshare_expr (result);
5415 else
5416 *expr_p = cond;
5417 return ret;
5419 break;
5421 case CALL_EXPR:
5422 /* For calls that return in memory, give *to_p as the CALL_EXPR's
5423 return slot so that we don't generate a temporary. */
5424 if (!CALL_EXPR_RETURN_SLOT_OPT (*from_p)
5425 && aggregate_value_p (*from_p, *from_p))
5427 bool use_target;
5429 if (!(rhs_predicate_for (*to_p))(*from_p))
5430 /* If we need a temporary, *to_p isn't accurate. */
5431 use_target = false;
5432 /* It's OK to use the return slot directly unless it's an NRV. */
5433 else if (TREE_CODE (*to_p) == RESULT_DECL
5434 && DECL_NAME (*to_p) == NULL_TREE
5435 && needs_to_live_in_memory (*to_p))
5436 use_target = true;
5437 else if (is_gimple_reg_type (TREE_TYPE (*to_p))
5438 || (DECL_P (*to_p) && DECL_REGISTER (*to_p)))
5439 /* Don't force regs into memory. */
5440 use_target = false;
5441 else if (TREE_CODE (*expr_p) == INIT_EXPR)
5442 /* It's OK to use the target directly if it's being
5443 initialized. */
5444 use_target = true;
5445 else if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p)))
5446 != INTEGER_CST)
5447 /* Always use the target and thus RSO for variable-sized types.
5448 GIMPLE cannot deal with a variable-sized assignment
5449 embedded in a call statement. */
5450 use_target = true;
5451 else if (TREE_CODE (*to_p) != SSA_NAME
5452 && (!is_gimple_variable (*to_p)
5453 || needs_to_live_in_memory (*to_p)))
5454 /* Don't use the original target if it's already addressable;
5455 if its address escapes, and the called function uses the
5456 NRV optimization, a conforming program could see *to_p
5457 change before the called function returns; see c++/19317.
5458 When optimizing, the return_slot pass marks more functions
5459 as safe after we have escape info. */
5460 use_target = false;
5461 else
5462 use_target = true;
5464 if (use_target)
5466 CALL_EXPR_RETURN_SLOT_OPT (*from_p) = 1;
5467 mark_addressable (*to_p);
5470 break;
5472 case WITH_SIZE_EXPR:
5473 /* Likewise for calls that return an aggregate of non-constant size,
5474 since we would not be able to generate a temporary at all. */
5475 if (TREE_CODE (TREE_OPERAND (*from_p, 0)) == CALL_EXPR)
5477 *from_p = TREE_OPERAND (*from_p, 0);
5478 /* We don't change ret in this case because the
5479 WITH_SIZE_EXPR might have been added in
5480 gimplify_modify_expr, so returning GS_OK would lead to an
5481 infinite loop. */
5482 changed = true;
5484 break;
5486 /* If we're initializing from a container, push the initialization
5487 inside it. */
5488 case CLEANUP_POINT_EXPR:
5489 case BIND_EXPR:
5490 case STATEMENT_LIST:
5492 tree wrap = *from_p;
5493 tree t;
5495 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_min_lval,
5496 fb_lvalue);
5497 if (ret != GS_ERROR)
5498 ret = GS_OK;
5500 t = voidify_wrapper_expr (wrap, *expr_p);
5501 gcc_assert (t == *expr_p);
5503 if (want_value)
5505 gimplify_and_add (wrap, pre_p);
5506 *expr_p = unshare_expr (*to_p);
5508 else
5509 *expr_p = wrap;
5510 return GS_OK;
5513 case COMPOUND_LITERAL_EXPR:
5515 tree complit = TREE_OPERAND (*expr_p, 1);
5516 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (complit);
5517 tree decl = DECL_EXPR_DECL (decl_s);
5518 tree init = DECL_INITIAL (decl);
5520 /* struct T x = (struct T) { 0, 1, 2 } can be optimized
5521 into struct T x = { 0, 1, 2 } if the address of the
5522 compound literal has never been taken. */
5523 if (!TREE_ADDRESSABLE (complit)
5524 && !TREE_ADDRESSABLE (decl)
5525 && init)
5527 *expr_p = copy_node (*expr_p);
5528 TREE_OPERAND (*expr_p, 1) = init;
5529 return GS_OK;
5533 default:
5534 break;
5537 while (changed);
5539 return ret;
5543 /* Return true if T looks like a valid GIMPLE statement. */
5545 static bool
5546 is_gimple_stmt (tree t)
5548 const enum tree_code code = TREE_CODE (t);
5550 switch (code)
5552 case NOP_EXPR:
5553 /* The only valid NOP_EXPR is the empty statement. */
5554 return IS_EMPTY_STMT (t);
5556 case BIND_EXPR:
5557 case COND_EXPR:
5558 /* These are only valid if they're void. */
5559 return TREE_TYPE (t) == NULL || VOID_TYPE_P (TREE_TYPE (t));
5561 case SWITCH_EXPR:
5562 case GOTO_EXPR:
5563 case RETURN_EXPR:
5564 case LABEL_EXPR:
5565 case CASE_LABEL_EXPR:
5566 case TRY_CATCH_EXPR:
5567 case TRY_FINALLY_EXPR:
5568 case EH_FILTER_EXPR:
5569 case CATCH_EXPR:
5570 case ASM_EXPR:
5571 case STATEMENT_LIST:
5572 case OACC_PARALLEL:
5573 case OACC_KERNELS:
5574 case OACC_SERIAL:
5575 case OACC_DATA:
5576 case OACC_HOST_DATA:
5577 case OACC_DECLARE:
5578 case OACC_UPDATE:
5579 case OACC_ENTER_DATA:
5580 case OACC_EXIT_DATA:
5581 case OACC_CACHE:
5582 case OMP_PARALLEL:
5583 case OMP_FOR:
5584 case OMP_SIMD:
5585 case OMP_DISTRIBUTE:
5586 case OMP_LOOP:
5587 case OACC_LOOP:
5588 case OMP_SCAN:
5589 case OMP_SECTIONS:
5590 case OMP_SECTION:
5591 case OMP_SINGLE:
5592 case OMP_MASTER:
5593 case OMP_TASKGROUP:
5594 case OMP_ORDERED:
5595 case OMP_CRITICAL:
5596 case OMP_TASK:
5597 case OMP_TARGET:
5598 case OMP_TARGET_DATA:
5599 case OMP_TARGET_UPDATE:
5600 case OMP_TARGET_ENTER_DATA:
5601 case OMP_TARGET_EXIT_DATA:
5602 case OMP_TASKLOOP:
5603 case OMP_TEAMS:
5604 /* These are always void. */
5605 return true;
5607 case CALL_EXPR:
5608 case MODIFY_EXPR:
5609 case PREDICT_EXPR:
5610 /* These are valid regardless of their type. */
5611 return true;
5613 default:
5614 return false;
5619 /* Promote partial stores to COMPLEX variables to total stores. *EXPR_P is
5620 a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a variable with
5621 DECL_GIMPLE_REG_P set.
5623 IMPORTANT NOTE: This promotion is performed by introducing a load of the
5624 other, unmodified part of the complex object just before the total store.
5625 As a consequence, if the object is still uninitialized, an undefined value
5626 will be loaded into a register, which may result in a spurious exception
5627 if the register is floating-point and the value happens to be a signaling
5628 NaN for example. Then the fully-fledged complex operations lowering pass
5629 followed by a DCE pass are necessary in order to fix things up. */
5631 static enum gimplify_status
5632 gimplify_modify_expr_complex_part (tree *expr_p, gimple_seq *pre_p,
5633 bool want_value)
5635 enum tree_code code, ocode;
5636 tree lhs, rhs, new_rhs, other, realpart, imagpart;
5638 lhs = TREE_OPERAND (*expr_p, 0);
5639 rhs = TREE_OPERAND (*expr_p, 1);
5640 code = TREE_CODE (lhs);
5641 lhs = TREE_OPERAND (lhs, 0);
5643 ocode = code == REALPART_EXPR ? IMAGPART_EXPR : REALPART_EXPR;
5644 other = build1 (ocode, TREE_TYPE (rhs), lhs);
5645 TREE_NO_WARNING (other) = 1;
5646 other = get_formal_tmp_var (other, pre_p);
5648 realpart = code == REALPART_EXPR ? rhs : other;
5649 imagpart = code == REALPART_EXPR ? other : rhs;
5651 if (TREE_CONSTANT (realpart) && TREE_CONSTANT (imagpart))
5652 new_rhs = build_complex (TREE_TYPE (lhs), realpart, imagpart);
5653 else
5654 new_rhs = build2 (COMPLEX_EXPR, TREE_TYPE (lhs), realpart, imagpart);
5656 gimplify_seq_add_stmt (pre_p, gimple_build_assign (lhs, new_rhs));
5657 *expr_p = (want_value) ? rhs : NULL_TREE;
5659 return GS_ALL_DONE;
5662 /* Gimplify the MODIFY_EXPR node pointed to by EXPR_P.
5664 modify_expr
5665 : varname '=' rhs
5666 | '*' ID '=' rhs
5668 PRE_P points to the list where side effects that must happen before
5669 *EXPR_P should be stored.
5671 POST_P points to the list where side effects that must happen after
5672 *EXPR_P should be stored.
5674 WANT_VALUE is nonzero iff we want to use the value of this expression
5675 in another expression. */
5677 static enum gimplify_status
5678 gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
5679 bool want_value)
5681 tree *from_p = &TREE_OPERAND (*expr_p, 1);
5682 tree *to_p = &TREE_OPERAND (*expr_p, 0);
5683 enum gimplify_status ret = GS_UNHANDLED;
5684 gimple *assign;
5685 location_t loc = EXPR_LOCATION (*expr_p);
5686 gimple_stmt_iterator gsi;
5688 gcc_assert (TREE_CODE (*expr_p) == MODIFY_EXPR
5689 || TREE_CODE (*expr_p) == INIT_EXPR);
5691 /* Trying to simplify a clobber using normal logic doesn't work,
5692 so handle it here. */
5693 if (TREE_CLOBBER_P (*from_p))
5695 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
5696 if (ret == GS_ERROR)
5697 return ret;
5698 gcc_assert (!want_value);
5699 if (!VAR_P (*to_p) && TREE_CODE (*to_p) != MEM_REF)
5701 tree addr = get_initialized_tmp_var (build_fold_addr_expr (*to_p),
5702 pre_p, post_p);
5703 *to_p = build_simple_mem_ref_loc (EXPR_LOCATION (*to_p), addr);
5705 gimplify_seq_add_stmt (pre_p, gimple_build_assign (*to_p, *from_p));
5706 *expr_p = NULL;
5707 return GS_ALL_DONE;
5710 /* Insert pointer conversions required by the middle-end that are not
5711 required by the frontend. This fixes middle-end type checking for
5712 for example gcc.dg/redecl-6.c. */
5713 if (POINTER_TYPE_P (TREE_TYPE (*to_p)))
5715 STRIP_USELESS_TYPE_CONVERSION (*from_p);
5716 if (!useless_type_conversion_p (TREE_TYPE (*to_p), TREE_TYPE (*from_p)))
5717 *from_p = fold_convert_loc (loc, TREE_TYPE (*to_p), *from_p);
5720 /* See if any simplifications can be done based on what the RHS is. */
5721 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
5722 want_value);
5723 if (ret != GS_UNHANDLED)
5724 return ret;
5726 /* For zero sized types only gimplify the left hand side and right hand
5727 side as statements and throw away the assignment. Do this after
5728 gimplify_modify_expr_rhs so we handle TARGET_EXPRs of addressable
5729 types properly. */
5730 if (zero_sized_type (TREE_TYPE (*from_p))
5731 && !want_value
5732 /* Don't do this for calls that return addressable types, expand_call
5733 relies on those having a lhs. */
5734 && !(TREE_ADDRESSABLE (TREE_TYPE (*from_p))
5735 && TREE_CODE (*from_p) == CALL_EXPR))
5737 gimplify_stmt (from_p, pre_p);
5738 gimplify_stmt (to_p, pre_p);
5739 *expr_p = NULL_TREE;
5740 return GS_ALL_DONE;
5743 /* If the value being copied is of variable width, compute the length
5744 of the copy into a WITH_SIZE_EXPR. Note that we need to do this
5745 before gimplifying any of the operands so that we can resolve any
5746 PLACEHOLDER_EXPRs in the size. Also note that the RTL expander uses
5747 the size of the expression to be copied, not of the destination, so
5748 that is what we must do here. */
5749 maybe_with_size_expr (from_p);
5751 /* As a special case, we have to temporarily allow for assignments
5752 with a CALL_EXPR on the RHS. Since in GIMPLE a function call is
5753 a toplevel statement, when gimplifying the GENERIC expression
5754 MODIFY_EXPR <a, CALL_EXPR <foo>>, we cannot create the tuple
5755 GIMPLE_ASSIGN <a, GIMPLE_CALL <foo>>.
5757 Instead, we need to create the tuple GIMPLE_CALL <a, foo>. To
5758 prevent gimplify_expr from trying to create a new temporary for
5759 foo's LHS, we tell it that it should only gimplify until it
5760 reaches the CALL_EXPR. On return from gimplify_expr, the newly
5761 created GIMPLE_CALL <foo> will be the last statement in *PRE_P
5762 and all we need to do here is set 'a' to be its LHS. */
5764 /* Gimplify the RHS first for C++17 and bug 71104. */
5765 gimple_predicate initial_pred = initial_rhs_predicate_for (*to_p);
5766 ret = gimplify_expr (from_p, pre_p, post_p, initial_pred, fb_rvalue);
5767 if (ret == GS_ERROR)
5768 return ret;
5770 /* Then gimplify the LHS. */
5771 /* If we gimplified the RHS to a CALL_EXPR and that call may return
5772 twice we have to make sure to gimplify into non-SSA as otherwise
5773 the abnormal edge added later will make those defs not dominate
5774 their uses.
5775 ??? Technically this applies only to the registers used in the
5776 resulting non-register *TO_P. */
5777 bool saved_into_ssa = gimplify_ctxp->into_ssa;
5778 if (saved_into_ssa
5779 && TREE_CODE (*from_p) == CALL_EXPR
5780 && call_expr_flags (*from_p) & ECF_RETURNS_TWICE)
5781 gimplify_ctxp->into_ssa = false;
5782 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
5783 gimplify_ctxp->into_ssa = saved_into_ssa;
5784 if (ret == GS_ERROR)
5785 return ret;
5787 /* Now that the LHS is gimplified, re-gimplify the RHS if our initial
5788 guess for the predicate was wrong. */
5789 gimple_predicate final_pred = rhs_predicate_for (*to_p);
5790 if (final_pred != initial_pred)
5792 ret = gimplify_expr (from_p, pre_p, post_p, final_pred, fb_rvalue);
5793 if (ret == GS_ERROR)
5794 return ret;
5797 /* In case of va_arg internal fn wrappped in a WITH_SIZE_EXPR, add the type
5798 size as argument to the call. */
5799 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
5801 tree call = TREE_OPERAND (*from_p, 0);
5802 tree vlasize = TREE_OPERAND (*from_p, 1);
5804 if (TREE_CODE (call) == CALL_EXPR
5805 && CALL_EXPR_IFN (call) == IFN_VA_ARG)
5807 int nargs = call_expr_nargs (call);
5808 tree type = TREE_TYPE (call);
5809 tree ap = CALL_EXPR_ARG (call, 0);
5810 tree tag = CALL_EXPR_ARG (call, 1);
5811 tree aptag = CALL_EXPR_ARG (call, 2);
5812 tree newcall = build_call_expr_internal_loc (EXPR_LOCATION (call),
5813 IFN_VA_ARG, type,
5814 nargs + 1, ap, tag,
5815 aptag, vlasize);
5816 TREE_OPERAND (*from_p, 0) = newcall;
5820 /* Now see if the above changed *from_p to something we handle specially. */
5821 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
5822 want_value);
5823 if (ret != GS_UNHANDLED)
5824 return ret;
5826 /* If we've got a variable sized assignment between two lvalues (i.e. does
5827 not involve a call), then we can make things a bit more straightforward
5828 by converting the assignment to memcpy or memset. */
5829 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
5831 tree from = TREE_OPERAND (*from_p, 0);
5832 tree size = TREE_OPERAND (*from_p, 1);
5834 if (TREE_CODE (from) == CONSTRUCTOR)
5835 return gimplify_modify_expr_to_memset (expr_p, size, want_value, pre_p);
5837 if (is_gimple_addressable (from))
5839 *from_p = from;
5840 return gimplify_modify_expr_to_memcpy (expr_p, size, want_value,
5841 pre_p);
5845 /* Transform partial stores to non-addressable complex variables into
5846 total stores. This allows us to use real instead of virtual operands
5847 for these variables, which improves optimization. */
5848 if ((TREE_CODE (*to_p) == REALPART_EXPR
5849 || TREE_CODE (*to_p) == IMAGPART_EXPR)
5850 && is_gimple_reg (TREE_OPERAND (*to_p, 0)))
5851 return gimplify_modify_expr_complex_part (expr_p, pre_p, want_value);
5853 /* Try to alleviate the effects of the gimplification creating artificial
5854 temporaries (see for example is_gimple_reg_rhs) on the debug info, but
5855 make sure not to create DECL_DEBUG_EXPR links across functions. */
5856 if (!gimplify_ctxp->into_ssa
5857 && VAR_P (*from_p)
5858 && DECL_IGNORED_P (*from_p)
5859 && DECL_P (*to_p)
5860 && !DECL_IGNORED_P (*to_p)
5861 && decl_function_context (*to_p) == current_function_decl
5862 && decl_function_context (*from_p) == current_function_decl)
5864 if (!DECL_NAME (*from_p) && DECL_NAME (*to_p))
5865 DECL_NAME (*from_p)
5866 = create_tmp_var_name (IDENTIFIER_POINTER (DECL_NAME (*to_p)));
5867 DECL_HAS_DEBUG_EXPR_P (*from_p) = 1;
5868 SET_DECL_DEBUG_EXPR (*from_p, *to_p);
5871 if (want_value && TREE_THIS_VOLATILE (*to_p))
5872 *from_p = get_initialized_tmp_var (*from_p, pre_p, post_p);
5874 if (TREE_CODE (*from_p) == CALL_EXPR)
5876 /* Since the RHS is a CALL_EXPR, we need to create a GIMPLE_CALL
5877 instead of a GIMPLE_ASSIGN. */
5878 gcall *call_stmt;
5879 if (CALL_EXPR_FN (*from_p) == NULL_TREE)
5881 /* Gimplify internal functions created in the FEs. */
5882 int nargs = call_expr_nargs (*from_p), i;
5883 enum internal_fn ifn = CALL_EXPR_IFN (*from_p);
5884 auto_vec<tree> vargs (nargs);
5886 for (i = 0; i < nargs; i++)
5888 gimplify_arg (&CALL_EXPR_ARG (*from_p, i), pre_p,
5889 EXPR_LOCATION (*from_p));
5890 vargs.quick_push (CALL_EXPR_ARG (*from_p, i));
5892 call_stmt = gimple_build_call_internal_vec (ifn, vargs);
5893 gimple_call_set_nothrow (call_stmt, TREE_NOTHROW (*from_p));
5894 gimple_set_location (call_stmt, EXPR_LOCATION (*expr_p));
5896 else
5898 tree fnptrtype = TREE_TYPE (CALL_EXPR_FN (*from_p));
5899 CALL_EXPR_FN (*from_p) = TREE_OPERAND (CALL_EXPR_FN (*from_p), 0);
5900 STRIP_USELESS_TYPE_CONVERSION (CALL_EXPR_FN (*from_p));
5901 tree fndecl = get_callee_fndecl (*from_p);
5902 if (fndecl
5903 && fndecl_built_in_p (fndecl, BUILT_IN_EXPECT)
5904 && call_expr_nargs (*from_p) == 3)
5905 call_stmt = gimple_build_call_internal (IFN_BUILTIN_EXPECT, 3,
5906 CALL_EXPR_ARG (*from_p, 0),
5907 CALL_EXPR_ARG (*from_p, 1),
5908 CALL_EXPR_ARG (*from_p, 2));
5909 else
5911 call_stmt = gimple_build_call_from_tree (*from_p, fnptrtype);
5914 notice_special_calls (call_stmt);
5915 if (!gimple_call_noreturn_p (call_stmt) || !should_remove_lhs_p (*to_p))
5916 gimple_call_set_lhs (call_stmt, *to_p);
5917 else if (TREE_CODE (*to_p) == SSA_NAME)
5918 /* The above is somewhat premature, avoid ICEing later for a
5919 SSA name w/o a definition. We may have uses in the GIMPLE IL.
5920 ??? This doesn't make it a default-def. */
5921 SSA_NAME_DEF_STMT (*to_p) = gimple_build_nop ();
5923 assign = call_stmt;
5925 else
5927 assign = gimple_build_assign (*to_p, *from_p);
5928 gimple_set_location (assign, EXPR_LOCATION (*expr_p));
5929 if (COMPARISON_CLASS_P (*from_p))
5930 gimple_set_no_warning (assign, TREE_NO_WARNING (*from_p));
5933 if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p))
5935 /* We should have got an SSA name from the start. */
5936 gcc_assert (TREE_CODE (*to_p) == SSA_NAME
5937 || ! gimple_in_ssa_p (cfun));
5940 gimplify_seq_add_stmt (pre_p, assign);
5941 gsi = gsi_last (*pre_p);
5942 maybe_fold_stmt (&gsi);
5944 if (want_value)
5946 *expr_p = TREE_THIS_VOLATILE (*to_p) ? *from_p : unshare_expr (*to_p);
5947 return GS_OK;
5949 else
5950 *expr_p = NULL;
5952 return GS_ALL_DONE;
5955 /* Gimplify a comparison between two variable-sized objects. Do this
5956 with a call to BUILT_IN_MEMCMP. */
5958 static enum gimplify_status
5959 gimplify_variable_sized_compare (tree *expr_p)
5961 location_t loc = EXPR_LOCATION (*expr_p);
5962 tree op0 = TREE_OPERAND (*expr_p, 0);
5963 tree op1 = TREE_OPERAND (*expr_p, 1);
5964 tree t, arg, dest, src, expr;
5966 arg = TYPE_SIZE_UNIT (TREE_TYPE (op0));
5967 arg = unshare_expr (arg);
5968 arg = SUBSTITUTE_PLACEHOLDER_IN_EXPR (arg, op0);
5969 src = build_fold_addr_expr_loc (loc, op1);
5970 dest = build_fold_addr_expr_loc (loc, op0);
5971 t = builtin_decl_implicit (BUILT_IN_MEMCMP);
5972 t = build_call_expr_loc (loc, t, 3, dest, src, arg);
5974 expr
5975 = build2 (TREE_CODE (*expr_p), TREE_TYPE (*expr_p), t, integer_zero_node);
5976 SET_EXPR_LOCATION (expr, loc);
5977 *expr_p = expr;
5979 return GS_OK;
5982 /* Gimplify a comparison between two aggregate objects of integral scalar
5983 mode as a comparison between the bitwise equivalent scalar values. */
5985 static enum gimplify_status
5986 gimplify_scalar_mode_aggregate_compare (tree *expr_p)
5988 location_t loc = EXPR_LOCATION (*expr_p);
5989 tree op0 = TREE_OPERAND (*expr_p, 0);
5990 tree op1 = TREE_OPERAND (*expr_p, 1);
5992 tree type = TREE_TYPE (op0);
5993 tree scalar_type = lang_hooks.types.type_for_mode (TYPE_MODE (type), 1);
5995 op0 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op0);
5996 op1 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op1);
5998 *expr_p
5999 = fold_build2_loc (loc, TREE_CODE (*expr_p), TREE_TYPE (*expr_p), op0, op1);
6001 return GS_OK;
6004 /* Gimplify an expression sequence. This function gimplifies each
6005 expression and rewrites the original expression with the last
6006 expression of the sequence in GIMPLE form.
6008 PRE_P points to the list where the side effects for all the
6009 expressions in the sequence will be emitted.
6011 WANT_VALUE is true when the result of the last COMPOUND_EXPR is used. */
6013 static enum gimplify_status
6014 gimplify_compound_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
6016 tree t = *expr_p;
6020 tree *sub_p = &TREE_OPERAND (t, 0);
6022 if (TREE_CODE (*sub_p) == COMPOUND_EXPR)
6023 gimplify_compound_expr (sub_p, pre_p, false);
6024 else
6025 gimplify_stmt (sub_p, pre_p);
6027 t = TREE_OPERAND (t, 1);
6029 while (TREE_CODE (t) == COMPOUND_EXPR);
6031 *expr_p = t;
6032 if (want_value)
6033 return GS_OK;
6034 else
6036 gimplify_stmt (expr_p, pre_p);
6037 return GS_ALL_DONE;
6041 /* Gimplify a SAVE_EXPR node. EXPR_P points to the expression to
6042 gimplify. After gimplification, EXPR_P will point to a new temporary
6043 that holds the original value of the SAVE_EXPR node.
6045 PRE_P points to the list where side effects that must happen before
6046 *EXPR_P should be stored. */
6048 static enum gimplify_status
6049 gimplify_save_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6051 enum gimplify_status ret = GS_ALL_DONE;
6052 tree val;
6054 gcc_assert (TREE_CODE (*expr_p) == SAVE_EXPR);
6055 val = TREE_OPERAND (*expr_p, 0);
6057 /* If the SAVE_EXPR has not been resolved, then evaluate it once. */
6058 if (!SAVE_EXPR_RESOLVED_P (*expr_p))
6060 /* The operand may be a void-valued expression. It is
6061 being executed only for its side-effects. */
6062 if (TREE_TYPE (val) == void_type_node)
6064 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
6065 is_gimple_stmt, fb_none);
6066 val = NULL;
6068 else
6069 /* The temporary may not be an SSA name as later abnormal and EH
6070 control flow may invalidate use/def domination. When in SSA
6071 form then assume there are no such issues and SAVE_EXPRs only
6072 appear via GENERIC foldings. */
6073 val = get_initialized_tmp_var (val, pre_p, post_p,
6074 gimple_in_ssa_p (cfun));
6076 TREE_OPERAND (*expr_p, 0) = val;
6077 SAVE_EXPR_RESOLVED_P (*expr_p) = 1;
6080 *expr_p = val;
6082 return ret;
6085 /* Rewrite the ADDR_EXPR node pointed to by EXPR_P
6087 unary_expr
6088 : ...
6089 | '&' varname
6092 PRE_P points to the list where side effects that must happen before
6093 *EXPR_P should be stored.
6095 POST_P points to the list where side effects that must happen after
6096 *EXPR_P should be stored. */
6098 static enum gimplify_status
6099 gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6101 tree expr = *expr_p;
6102 tree op0 = TREE_OPERAND (expr, 0);
6103 enum gimplify_status ret;
6104 location_t loc = EXPR_LOCATION (*expr_p);
6106 switch (TREE_CODE (op0))
6108 case INDIRECT_REF:
6109 do_indirect_ref:
6110 /* Check if we are dealing with an expression of the form '&*ptr'.
6111 While the front end folds away '&*ptr' into 'ptr', these
6112 expressions may be generated internally by the compiler (e.g.,
6113 builtins like __builtin_va_end). */
6114 /* Caution: the silent array decomposition semantics we allow for
6115 ADDR_EXPR means we can't always discard the pair. */
6116 /* Gimplification of the ADDR_EXPR operand may drop
6117 cv-qualification conversions, so make sure we add them if
6118 needed. */
6120 tree op00 = TREE_OPERAND (op0, 0);
6121 tree t_expr = TREE_TYPE (expr);
6122 tree t_op00 = TREE_TYPE (op00);
6124 if (!useless_type_conversion_p (t_expr, t_op00))
6125 op00 = fold_convert_loc (loc, TREE_TYPE (expr), op00);
6126 *expr_p = op00;
6127 ret = GS_OK;
6129 break;
6131 case VIEW_CONVERT_EXPR:
6132 /* Take the address of our operand and then convert it to the type of
6133 this ADDR_EXPR.
6135 ??? The interactions of VIEW_CONVERT_EXPR and aliasing is not at
6136 all clear. The impact of this transformation is even less clear. */
6138 /* If the operand is a useless conversion, look through it. Doing so
6139 guarantees that the ADDR_EXPR and its operand will remain of the
6140 same type. */
6141 if (tree_ssa_useless_type_conversion (TREE_OPERAND (op0, 0)))
6142 op0 = TREE_OPERAND (op0, 0);
6144 *expr_p = fold_convert_loc (loc, TREE_TYPE (expr),
6145 build_fold_addr_expr_loc (loc,
6146 TREE_OPERAND (op0, 0)));
6147 ret = GS_OK;
6148 break;
6150 case MEM_REF:
6151 if (integer_zerop (TREE_OPERAND (op0, 1)))
6152 goto do_indirect_ref;
6154 /* fall through */
6156 default:
6157 /* If we see a call to a declared builtin or see its address
6158 being taken (we can unify those cases here) then we can mark
6159 the builtin for implicit generation by GCC. */
6160 if (TREE_CODE (op0) == FUNCTION_DECL
6161 && fndecl_built_in_p (op0, BUILT_IN_NORMAL)
6162 && builtin_decl_declared_p (DECL_FUNCTION_CODE (op0)))
6163 set_builtin_decl_implicit_p (DECL_FUNCTION_CODE (op0), true);
6165 /* We use fb_either here because the C frontend sometimes takes
6166 the address of a call that returns a struct; see
6167 gcc.dg/c99-array-lval-1.c. The gimplifier will correctly make
6168 the implied temporary explicit. */
6170 /* Make the operand addressable. */
6171 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, post_p,
6172 is_gimple_addressable, fb_either);
6173 if (ret == GS_ERROR)
6174 break;
6176 /* Then mark it. Beware that it may not be possible to do so directly
6177 if a temporary has been created by the gimplification. */
6178 prepare_gimple_addressable (&TREE_OPERAND (expr, 0), pre_p);
6180 op0 = TREE_OPERAND (expr, 0);
6182 /* For various reasons, the gimplification of the expression
6183 may have made a new INDIRECT_REF. */
6184 if (TREE_CODE (op0) == INDIRECT_REF
6185 || (TREE_CODE (op0) == MEM_REF
6186 && integer_zerop (TREE_OPERAND (op0, 1))))
6187 goto do_indirect_ref;
6189 mark_addressable (TREE_OPERAND (expr, 0));
6191 /* The FEs may end up building ADDR_EXPRs early on a decl with
6192 an incomplete type. Re-build ADDR_EXPRs in canonical form
6193 here. */
6194 if (!types_compatible_p (TREE_TYPE (op0), TREE_TYPE (TREE_TYPE (expr))))
6195 *expr_p = build_fold_addr_expr (op0);
6197 /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly. */
6198 recompute_tree_invariant_for_addr_expr (*expr_p);
6200 /* If we re-built the ADDR_EXPR add a conversion to the original type
6201 if required. */
6202 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
6203 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
6205 break;
6208 return ret;
6211 /* Gimplify the operands of an ASM_EXPR. Input operands should be a gimple
6212 value; output operands should be a gimple lvalue. */
6214 static enum gimplify_status
6215 gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6217 tree expr;
6218 int noutputs;
6219 const char **oconstraints;
6220 int i;
6221 tree link;
6222 const char *constraint;
6223 bool allows_mem, allows_reg, is_inout;
6224 enum gimplify_status ret, tret;
6225 gasm *stmt;
6226 vec<tree, va_gc> *inputs;
6227 vec<tree, va_gc> *outputs;
6228 vec<tree, va_gc> *clobbers;
6229 vec<tree, va_gc> *labels;
6230 tree link_next;
6232 expr = *expr_p;
6233 noutputs = list_length (ASM_OUTPUTS (expr));
6234 oconstraints = (const char **) alloca ((noutputs) * sizeof (const char *));
6236 inputs = NULL;
6237 outputs = NULL;
6238 clobbers = NULL;
6239 labels = NULL;
6241 ret = GS_ALL_DONE;
6242 link_next = NULL_TREE;
6243 for (i = 0, link = ASM_OUTPUTS (expr); link; ++i, link = link_next)
6245 bool ok;
6246 size_t constraint_len;
6248 link_next = TREE_CHAIN (link);
6250 oconstraints[i]
6251 = constraint
6252 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
6253 constraint_len = strlen (constraint);
6254 if (constraint_len == 0)
6255 continue;
6257 ok = parse_output_constraint (&constraint, i, 0, 0,
6258 &allows_mem, &allows_reg, &is_inout);
6259 if (!ok)
6261 ret = GS_ERROR;
6262 is_inout = false;
6265 /* If we can't make copies, we can only accept memory.
6266 Similarly for VLAs. */
6267 tree outtype = TREE_TYPE (TREE_VALUE (link));
6268 if (outtype != error_mark_node
6269 && (TREE_ADDRESSABLE (outtype)
6270 || !COMPLETE_TYPE_P (outtype)
6271 || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (outtype))))
6273 if (allows_mem)
6274 allows_reg = 0;
6275 else
6277 error ("impossible constraint in %<asm%>");
6278 error ("non-memory output %d must stay in memory", i);
6279 return GS_ERROR;
6283 if (!allows_reg && allows_mem)
6284 mark_addressable (TREE_VALUE (link));
6286 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6287 is_inout ? is_gimple_min_lval : is_gimple_lvalue,
6288 fb_lvalue | fb_mayfail);
6289 if (tret == GS_ERROR)
6291 error ("invalid lvalue in %<asm%> output %d", i);
6292 ret = tret;
6295 /* If the constraint does not allow memory make sure we gimplify
6296 it to a register if it is not already but its base is. This
6297 happens for complex and vector components. */
6298 if (!allows_mem)
6300 tree op = TREE_VALUE (link);
6301 if (! is_gimple_val (op)
6302 && is_gimple_reg_type (TREE_TYPE (op))
6303 && is_gimple_reg (get_base_address (op)))
6305 tree tem = create_tmp_reg (TREE_TYPE (op));
6306 tree ass;
6307 if (is_inout)
6309 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem),
6310 tem, unshare_expr (op));
6311 gimplify_and_add (ass, pre_p);
6313 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem), op, tem);
6314 gimplify_and_add (ass, post_p);
6316 TREE_VALUE (link) = tem;
6317 tret = GS_OK;
6321 vec_safe_push (outputs, link);
6322 TREE_CHAIN (link) = NULL_TREE;
6324 if (is_inout)
6326 /* An input/output operand. To give the optimizers more
6327 flexibility, split it into separate input and output
6328 operands. */
6329 tree input;
6330 /* Buffer big enough to format a 32-bit UINT_MAX into. */
6331 char buf[11];
6333 /* Turn the in/out constraint into an output constraint. */
6334 char *p = xstrdup (constraint);
6335 p[0] = '=';
6336 TREE_VALUE (TREE_PURPOSE (link)) = build_string (constraint_len, p);
6338 /* And add a matching input constraint. */
6339 if (allows_reg)
6341 sprintf (buf, "%u", i);
6343 /* If there are multiple alternatives in the constraint,
6344 handle each of them individually. Those that allow register
6345 will be replaced with operand number, the others will stay
6346 unchanged. */
6347 if (strchr (p, ',') != NULL)
6349 size_t len = 0, buflen = strlen (buf);
6350 char *beg, *end, *str, *dst;
6352 for (beg = p + 1;;)
6354 end = strchr (beg, ',');
6355 if (end == NULL)
6356 end = strchr (beg, '\0');
6357 if ((size_t) (end - beg) < buflen)
6358 len += buflen + 1;
6359 else
6360 len += end - beg + 1;
6361 if (*end)
6362 beg = end + 1;
6363 else
6364 break;
6367 str = (char *) alloca (len);
6368 for (beg = p + 1, dst = str;;)
6370 const char *tem;
6371 bool mem_p, reg_p, inout_p;
6373 end = strchr (beg, ',');
6374 if (end)
6375 *end = '\0';
6376 beg[-1] = '=';
6377 tem = beg - 1;
6378 parse_output_constraint (&tem, i, 0, 0,
6379 &mem_p, &reg_p, &inout_p);
6380 if (dst != str)
6381 *dst++ = ',';
6382 if (reg_p)
6384 memcpy (dst, buf, buflen);
6385 dst += buflen;
6387 else
6389 if (end)
6390 len = end - beg;
6391 else
6392 len = strlen (beg);
6393 memcpy (dst, beg, len);
6394 dst += len;
6396 if (end)
6397 beg = end + 1;
6398 else
6399 break;
6401 *dst = '\0';
6402 input = build_string (dst - str, str);
6404 else
6405 input = build_string (strlen (buf), buf);
6407 else
6408 input = build_string (constraint_len - 1, constraint + 1);
6410 free (p);
6412 input = build_tree_list (build_tree_list (NULL_TREE, input),
6413 unshare_expr (TREE_VALUE (link)));
6414 ASM_INPUTS (expr) = chainon (ASM_INPUTS (expr), input);
6418 link_next = NULL_TREE;
6419 for (link = ASM_INPUTS (expr); link; ++i, link = link_next)
6421 link_next = TREE_CHAIN (link);
6422 constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
6423 parse_input_constraint (&constraint, 0, 0, noutputs, 0,
6424 oconstraints, &allows_mem, &allows_reg);
6426 /* If we can't make copies, we can only accept memory. */
6427 tree intype = TREE_TYPE (TREE_VALUE (link));
6428 if (intype != error_mark_node
6429 && (TREE_ADDRESSABLE (intype)
6430 || !COMPLETE_TYPE_P (intype)
6431 || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (intype))))
6433 if (allows_mem)
6434 allows_reg = 0;
6435 else
6437 error ("impossible constraint in %<asm%>");
6438 error ("non-memory input %d must stay in memory", i);
6439 return GS_ERROR;
6443 /* If the operand is a memory input, it should be an lvalue. */
6444 if (!allows_reg && allows_mem)
6446 tree inputv = TREE_VALUE (link);
6447 STRIP_NOPS (inputv);
6448 if (TREE_CODE (inputv) == PREDECREMENT_EXPR
6449 || TREE_CODE (inputv) == PREINCREMENT_EXPR
6450 || TREE_CODE (inputv) == POSTDECREMENT_EXPR
6451 || TREE_CODE (inputv) == POSTINCREMENT_EXPR
6452 || TREE_CODE (inputv) == MODIFY_EXPR)
6453 TREE_VALUE (link) = error_mark_node;
6454 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6455 is_gimple_lvalue, fb_lvalue | fb_mayfail);
6456 if (tret != GS_ERROR)
6458 /* Unlike output operands, memory inputs are not guaranteed
6459 to be lvalues by the FE, and while the expressions are
6460 marked addressable there, if it is e.g. a statement
6461 expression, temporaries in it might not end up being
6462 addressable. They might be already used in the IL and thus
6463 it is too late to make them addressable now though. */
6464 tree x = TREE_VALUE (link);
6465 while (handled_component_p (x))
6466 x = TREE_OPERAND (x, 0);
6467 if (TREE_CODE (x) == MEM_REF
6468 && TREE_CODE (TREE_OPERAND (x, 0)) == ADDR_EXPR)
6469 x = TREE_OPERAND (TREE_OPERAND (x, 0), 0);
6470 if ((VAR_P (x)
6471 || TREE_CODE (x) == PARM_DECL
6472 || TREE_CODE (x) == RESULT_DECL)
6473 && !TREE_ADDRESSABLE (x)
6474 && is_gimple_reg (x))
6476 warning_at (EXPR_LOC_OR_LOC (TREE_VALUE (link),
6477 input_location), 0,
6478 "memory input %d is not directly addressable",
6480 prepare_gimple_addressable (&TREE_VALUE (link), pre_p);
6483 mark_addressable (TREE_VALUE (link));
6484 if (tret == GS_ERROR)
6486 error_at (EXPR_LOC_OR_LOC (TREE_VALUE (link), input_location),
6487 "memory input %d is not directly addressable", i);
6488 ret = tret;
6491 else
6493 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6494 is_gimple_asm_val, fb_rvalue);
6495 if (tret == GS_ERROR)
6496 ret = tret;
6499 TREE_CHAIN (link) = NULL_TREE;
6500 vec_safe_push (inputs, link);
6503 link_next = NULL_TREE;
6504 for (link = ASM_CLOBBERS (expr); link; ++i, link = link_next)
6506 link_next = TREE_CHAIN (link);
6507 TREE_CHAIN (link) = NULL_TREE;
6508 vec_safe_push (clobbers, link);
6511 link_next = NULL_TREE;
6512 for (link = ASM_LABELS (expr); link; ++i, link = link_next)
6514 link_next = TREE_CHAIN (link);
6515 TREE_CHAIN (link) = NULL_TREE;
6516 vec_safe_push (labels, link);
6519 /* Do not add ASMs with errors to the gimple IL stream. */
6520 if (ret != GS_ERROR)
6522 stmt = gimple_build_asm_vec (TREE_STRING_POINTER (ASM_STRING (expr)),
6523 inputs, outputs, clobbers, labels);
6525 gimple_asm_set_volatile (stmt, ASM_VOLATILE_P (expr) || noutputs == 0);
6526 gimple_asm_set_input (stmt, ASM_INPUT_P (expr));
6527 gimple_asm_set_inline (stmt, ASM_INLINE_P (expr));
6529 gimplify_seq_add_stmt (pre_p, stmt);
6532 return ret;
6535 /* Gimplify a CLEANUP_POINT_EXPR. Currently this works by adding
6536 GIMPLE_WITH_CLEANUP_EXPRs to the prequeue as we encounter cleanups while
6537 gimplifying the body, and converting them to TRY_FINALLY_EXPRs when we
6538 return to this function.
6540 FIXME should we complexify the prequeue handling instead? Or use flags
6541 for all the cleanups and let the optimizer tighten them up? The current
6542 code seems pretty fragile; it will break on a cleanup within any
6543 non-conditional nesting. But any such nesting would be broken, anyway;
6544 we can't write a TRY_FINALLY_EXPR that starts inside a nesting construct
6545 and continues out of it. We can do that at the RTL level, though, so
6546 having an optimizer to tighten up try/finally regions would be a Good
6547 Thing. */
6549 static enum gimplify_status
6550 gimplify_cleanup_point_expr (tree *expr_p, gimple_seq *pre_p)
6552 gimple_stmt_iterator iter;
6553 gimple_seq body_sequence = NULL;
6555 tree temp = voidify_wrapper_expr (*expr_p, NULL);
6557 /* We only care about the number of conditions between the innermost
6558 CLEANUP_POINT_EXPR and the cleanup. So save and reset the count and
6559 any cleanups collected outside the CLEANUP_POINT_EXPR. */
6560 int old_conds = gimplify_ctxp->conditions;
6561 gimple_seq old_cleanups = gimplify_ctxp->conditional_cleanups;
6562 bool old_in_cleanup_point_expr = gimplify_ctxp->in_cleanup_point_expr;
6563 gimplify_ctxp->conditions = 0;
6564 gimplify_ctxp->conditional_cleanups = NULL;
6565 gimplify_ctxp->in_cleanup_point_expr = true;
6567 gimplify_stmt (&TREE_OPERAND (*expr_p, 0), &body_sequence);
6569 gimplify_ctxp->conditions = old_conds;
6570 gimplify_ctxp->conditional_cleanups = old_cleanups;
6571 gimplify_ctxp->in_cleanup_point_expr = old_in_cleanup_point_expr;
6573 for (iter = gsi_start (body_sequence); !gsi_end_p (iter); )
6575 gimple *wce = gsi_stmt (iter);
6577 if (gimple_code (wce) == GIMPLE_WITH_CLEANUP_EXPR)
6579 if (gsi_one_before_end_p (iter))
6581 /* Note that gsi_insert_seq_before and gsi_remove do not
6582 scan operands, unlike some other sequence mutators. */
6583 if (!gimple_wce_cleanup_eh_only (wce))
6584 gsi_insert_seq_before_without_update (&iter,
6585 gimple_wce_cleanup (wce),
6586 GSI_SAME_STMT);
6587 gsi_remove (&iter, true);
6588 break;
6590 else
6592 gtry *gtry;
6593 gimple_seq seq;
6594 enum gimple_try_flags kind;
6596 if (gimple_wce_cleanup_eh_only (wce))
6597 kind = GIMPLE_TRY_CATCH;
6598 else
6599 kind = GIMPLE_TRY_FINALLY;
6600 seq = gsi_split_seq_after (iter);
6602 gtry = gimple_build_try (seq, gimple_wce_cleanup (wce), kind);
6603 /* Do not use gsi_replace here, as it may scan operands.
6604 We want to do a simple structural modification only. */
6605 gsi_set_stmt (&iter, gtry);
6606 iter = gsi_start (gtry->eval);
6609 else
6610 gsi_next (&iter);
6613 gimplify_seq_add_seq (pre_p, body_sequence);
6614 if (temp)
6616 *expr_p = temp;
6617 return GS_OK;
6619 else
6621 *expr_p = NULL;
6622 return GS_ALL_DONE;
6626 /* Insert a cleanup marker for gimplify_cleanup_point_expr. CLEANUP
6627 is the cleanup action required. EH_ONLY is true if the cleanup should
6628 only be executed if an exception is thrown, not on normal exit.
6629 If FORCE_UNCOND is true perform the cleanup unconditionally; this is
6630 only valid for clobbers. */
6632 static void
6633 gimple_push_cleanup (tree var, tree cleanup, bool eh_only, gimple_seq *pre_p,
6634 bool force_uncond = false)
6636 gimple *wce;
6637 gimple_seq cleanup_stmts = NULL;
6639 /* Errors can result in improperly nested cleanups. Which results in
6640 confusion when trying to resolve the GIMPLE_WITH_CLEANUP_EXPR. */
6641 if (seen_error ())
6642 return;
6644 if (gimple_conditional_context ())
6646 /* If we're in a conditional context, this is more complex. We only
6647 want to run the cleanup if we actually ran the initialization that
6648 necessitates it, but we want to run it after the end of the
6649 conditional context. So we wrap the try/finally around the
6650 condition and use a flag to determine whether or not to actually
6651 run the destructor. Thus
6653 test ? f(A()) : 0
6655 becomes (approximately)
6657 flag = 0;
6658 try {
6659 if (test) { A::A(temp); flag = 1; val = f(temp); }
6660 else { val = 0; }
6661 } finally {
6662 if (flag) A::~A(temp);
6666 if (force_uncond)
6668 gimplify_stmt (&cleanup, &cleanup_stmts);
6669 wce = gimple_build_wce (cleanup_stmts);
6670 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
6672 else
6674 tree flag = create_tmp_var (boolean_type_node, "cleanup");
6675 gassign *ffalse = gimple_build_assign (flag, boolean_false_node);
6676 gassign *ftrue = gimple_build_assign (flag, boolean_true_node);
6678 cleanup = build3 (COND_EXPR, void_type_node, flag, cleanup, NULL);
6679 gimplify_stmt (&cleanup, &cleanup_stmts);
6680 wce = gimple_build_wce (cleanup_stmts);
6682 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, ffalse);
6683 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
6684 gimplify_seq_add_stmt (pre_p, ftrue);
6686 /* Because of this manipulation, and the EH edges that jump
6687 threading cannot redirect, the temporary (VAR) will appear
6688 to be used uninitialized. Don't warn. */
6689 TREE_NO_WARNING (var) = 1;
6692 else
6694 gimplify_stmt (&cleanup, &cleanup_stmts);
6695 wce = gimple_build_wce (cleanup_stmts);
6696 gimple_wce_set_cleanup_eh_only (wce, eh_only);
6697 gimplify_seq_add_stmt (pre_p, wce);
6701 /* Gimplify a TARGET_EXPR which doesn't appear on the rhs of an INIT_EXPR. */
6703 static enum gimplify_status
6704 gimplify_target_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6706 tree targ = *expr_p;
6707 tree temp = TARGET_EXPR_SLOT (targ);
6708 tree init = TARGET_EXPR_INITIAL (targ);
6709 enum gimplify_status ret;
6711 bool unpoison_empty_seq = false;
6712 gimple_stmt_iterator unpoison_it;
6714 if (init)
6716 tree cleanup = NULL_TREE;
6718 /* TARGET_EXPR temps aren't part of the enclosing block, so add it
6719 to the temps list. Handle also variable length TARGET_EXPRs. */
6720 if (!poly_int_tree_p (DECL_SIZE (temp)))
6722 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (temp)))
6723 gimplify_type_sizes (TREE_TYPE (temp), pre_p);
6724 gimplify_vla_decl (temp, pre_p);
6726 else
6728 /* Save location where we need to place unpoisoning. It's possible
6729 that a variable will be converted to needs_to_live_in_memory. */
6730 unpoison_it = gsi_last (*pre_p);
6731 unpoison_empty_seq = gsi_end_p (unpoison_it);
6733 gimple_add_tmp_var (temp);
6736 /* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the
6737 expression is supposed to initialize the slot. */
6738 if (VOID_TYPE_P (TREE_TYPE (init)))
6739 ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
6740 else
6742 tree init_expr = build2 (INIT_EXPR, void_type_node, temp, init);
6743 init = init_expr;
6744 ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
6745 init = NULL;
6746 ggc_free (init_expr);
6748 if (ret == GS_ERROR)
6750 /* PR c++/28266 Make sure this is expanded only once. */
6751 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
6752 return GS_ERROR;
6754 if (init)
6755 gimplify_and_add (init, pre_p);
6757 /* If needed, push the cleanup for the temp. */
6758 if (TARGET_EXPR_CLEANUP (targ))
6760 if (CLEANUP_EH_ONLY (targ))
6761 gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ),
6762 CLEANUP_EH_ONLY (targ), pre_p);
6763 else
6764 cleanup = TARGET_EXPR_CLEANUP (targ);
6767 /* Add a clobber for the temporary going out of scope, like
6768 gimplify_bind_expr. */
6769 if (gimplify_ctxp->in_cleanup_point_expr
6770 && needs_to_live_in_memory (temp))
6772 if (flag_stack_reuse == SR_ALL)
6774 tree clobber = build_clobber (TREE_TYPE (temp));
6775 clobber = build2 (MODIFY_EXPR, TREE_TYPE (temp), temp, clobber);
6776 gimple_push_cleanup (temp, clobber, false, pre_p, true);
6778 if (asan_poisoned_variables
6779 && DECL_ALIGN (temp) <= MAX_SUPPORTED_STACK_ALIGNMENT
6780 && !TREE_STATIC (temp)
6781 && dbg_cnt (asan_use_after_scope)
6782 && !gimplify_omp_ctxp)
6784 tree asan_cleanup = build_asan_poison_call_expr (temp);
6785 if (asan_cleanup)
6787 if (unpoison_empty_seq)
6788 unpoison_it = gsi_start (*pre_p);
6790 asan_poison_variable (temp, false, &unpoison_it,
6791 unpoison_empty_seq);
6792 gimple_push_cleanup (temp, asan_cleanup, false, pre_p);
6796 if (cleanup)
6797 gimple_push_cleanup (temp, cleanup, false, pre_p);
6799 /* Only expand this once. */
6800 TREE_OPERAND (targ, 3) = init;
6801 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
6803 else
6804 /* We should have expanded this before. */
6805 gcc_assert (DECL_SEEN_IN_BIND_EXPR_P (temp));
6807 *expr_p = temp;
6808 return GS_OK;
6811 /* Gimplification of expression trees. */
6813 /* Gimplify an expression which appears at statement context. The
6814 corresponding GIMPLE statements are added to *SEQ_P. If *SEQ_P is
6815 NULL, a new sequence is allocated.
6817 Return true if we actually added a statement to the queue. */
6819 bool
6820 gimplify_stmt (tree *stmt_p, gimple_seq *seq_p)
6822 gimple_seq_node last;
6824 last = gimple_seq_last (*seq_p);
6825 gimplify_expr (stmt_p, seq_p, NULL, is_gimple_stmt, fb_none);
6826 return last != gimple_seq_last (*seq_p);
6829 /* Add FIRSTPRIVATE entries for DECL in the OpenMP the surrounding parallels
6830 to CTX. If entries already exist, force them to be some flavor of private.
6831 If there is no enclosing parallel, do nothing. */
6833 void
6834 omp_firstprivatize_variable (struct gimplify_omp_ctx *ctx, tree decl)
6836 splay_tree_node n;
6838 if (decl == NULL || !DECL_P (decl) || ctx->region_type == ORT_NONE)
6839 return;
6843 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
6844 if (n != NULL)
6846 if (n->value & GOVD_SHARED)
6847 n->value = GOVD_FIRSTPRIVATE | (n->value & GOVD_SEEN);
6848 else if (n->value & GOVD_MAP)
6849 n->value |= GOVD_MAP_TO_ONLY;
6850 else
6851 return;
6853 else if ((ctx->region_type & ORT_TARGET) != 0)
6855 if (ctx->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE)
6856 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
6857 else
6858 omp_add_variable (ctx, decl, GOVD_MAP | GOVD_MAP_TO_ONLY);
6860 else if (ctx->region_type != ORT_WORKSHARE
6861 && ctx->region_type != ORT_TASKGROUP
6862 && ctx->region_type != ORT_SIMD
6863 && ctx->region_type != ORT_ACC
6864 && !(ctx->region_type & ORT_TARGET_DATA))
6865 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
6867 ctx = ctx->outer_context;
6869 while (ctx);
6872 /* Similarly for each of the type sizes of TYPE. */
6874 static void
6875 omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type)
6877 if (type == NULL || type == error_mark_node)
6878 return;
6879 type = TYPE_MAIN_VARIANT (type);
6881 if (ctx->privatized_types->add (type))
6882 return;
6884 switch (TREE_CODE (type))
6886 case INTEGER_TYPE:
6887 case ENUMERAL_TYPE:
6888 case BOOLEAN_TYPE:
6889 case REAL_TYPE:
6890 case FIXED_POINT_TYPE:
6891 omp_firstprivatize_variable (ctx, TYPE_MIN_VALUE (type));
6892 omp_firstprivatize_variable (ctx, TYPE_MAX_VALUE (type));
6893 break;
6895 case ARRAY_TYPE:
6896 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
6897 omp_firstprivatize_type_sizes (ctx, TYPE_DOMAIN (type));
6898 break;
6900 case RECORD_TYPE:
6901 case UNION_TYPE:
6902 case QUAL_UNION_TYPE:
6904 tree field;
6905 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
6906 if (TREE_CODE (field) == FIELD_DECL)
6908 omp_firstprivatize_variable (ctx, DECL_FIELD_OFFSET (field));
6909 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (field));
6912 break;
6914 case POINTER_TYPE:
6915 case REFERENCE_TYPE:
6916 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
6917 break;
6919 default:
6920 break;
6923 omp_firstprivatize_variable (ctx, TYPE_SIZE (type));
6924 omp_firstprivatize_variable (ctx, TYPE_SIZE_UNIT (type));
6925 lang_hooks.types.omp_firstprivatize_type_sizes (ctx, type);
6928 /* Add an entry for DECL in the OMP context CTX with FLAGS. */
6930 static void
6931 omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
6933 splay_tree_node n;
6934 unsigned int nflags;
6935 tree t;
6937 if (error_operand_p (decl) || ctx->region_type == ORT_NONE)
6938 return;
6940 /* Never elide decls whose type has TREE_ADDRESSABLE set. This means
6941 there are constructors involved somewhere. Exception is a shared clause,
6942 there is nothing privatized in that case. */
6943 if ((flags & GOVD_SHARED) == 0
6944 && (TREE_ADDRESSABLE (TREE_TYPE (decl))
6945 || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))))
6946 flags |= GOVD_SEEN;
6948 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
6949 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
6951 /* We shouldn't be re-adding the decl with the same data
6952 sharing class. */
6953 gcc_assert ((n->value & GOVD_DATA_SHARE_CLASS & flags) == 0);
6954 nflags = n->value | flags;
6955 /* The only combination of data sharing classes we should see is
6956 FIRSTPRIVATE and LASTPRIVATE. However, OpenACC permits
6957 reduction variables to be used in data sharing clauses. */
6958 gcc_assert ((ctx->region_type & ORT_ACC) != 0
6959 || ((nflags & GOVD_DATA_SHARE_CLASS)
6960 == (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE))
6961 || (flags & GOVD_DATA_SHARE_CLASS) == 0);
6962 n->value = nflags;
6963 return;
6966 /* When adding a variable-sized variable, we have to handle all sorts
6967 of additional bits of data: the pointer replacement variable, and
6968 the parameters of the type. */
6969 if (DECL_SIZE (decl) && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
6971 /* Add the pointer replacement variable as PRIVATE if the variable
6972 replacement is private, else FIRSTPRIVATE since we'll need the
6973 address of the original variable either for SHARED, or for the
6974 copy into or out of the context. */
6975 if (!(flags & GOVD_LOCAL) && ctx->region_type != ORT_TASKGROUP)
6977 if (flags & GOVD_MAP)
6978 nflags = GOVD_MAP | GOVD_MAP_TO_ONLY | GOVD_EXPLICIT;
6979 else if (flags & GOVD_PRIVATE)
6980 nflags = GOVD_PRIVATE;
6981 else if (((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
6982 && (flags & GOVD_FIRSTPRIVATE))
6983 || (ctx->region_type == ORT_TARGET_DATA
6984 && (flags & GOVD_DATA_SHARE_CLASS) == 0))
6985 nflags = GOVD_PRIVATE | GOVD_EXPLICIT;
6986 else
6987 nflags = GOVD_FIRSTPRIVATE;
6988 nflags |= flags & GOVD_SEEN;
6989 t = DECL_VALUE_EXPR (decl);
6990 gcc_assert (TREE_CODE (t) == INDIRECT_REF);
6991 t = TREE_OPERAND (t, 0);
6992 gcc_assert (DECL_P (t));
6993 omp_add_variable (ctx, t, nflags);
6996 /* Add all of the variable and type parameters (which should have
6997 been gimplified to a formal temporary) as FIRSTPRIVATE. */
6998 omp_firstprivatize_variable (ctx, DECL_SIZE_UNIT (decl));
6999 omp_firstprivatize_variable (ctx, DECL_SIZE (decl));
7000 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
7002 /* The variable-sized variable itself is never SHARED, only some form
7003 of PRIVATE. The sharing would take place via the pointer variable
7004 which we remapped above. */
7005 if (flags & GOVD_SHARED)
7006 flags = GOVD_SHARED | GOVD_DEBUG_PRIVATE
7007 | (flags & (GOVD_SEEN | GOVD_EXPLICIT));
7009 /* We're going to make use of the TYPE_SIZE_UNIT at least in the
7010 alloca statement we generate for the variable, so make sure it
7011 is available. This isn't automatically needed for the SHARED
7012 case, since we won't be allocating local storage then.
7013 For local variables TYPE_SIZE_UNIT might not be gimplified yet,
7014 in this case omp_notice_variable will be called later
7015 on when it is gimplified. */
7016 else if (! (flags & (GOVD_LOCAL | GOVD_MAP))
7017 && DECL_P (TYPE_SIZE_UNIT (TREE_TYPE (decl))))
7018 omp_notice_variable (ctx, TYPE_SIZE_UNIT (TREE_TYPE (decl)), true);
7020 else if ((flags & (GOVD_MAP | GOVD_LOCAL)) == 0
7021 && lang_hooks.decls.omp_privatize_by_reference (decl))
7023 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
7025 /* Similar to the direct variable sized case above, we'll need the
7026 size of references being privatized. */
7027 if ((flags & GOVD_SHARED) == 0)
7029 t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
7030 if (DECL_P (t))
7031 omp_notice_variable (ctx, t, true);
7035 if (n != NULL)
7036 n->value |= flags;
7037 else
7038 splay_tree_insert (ctx->variables, (splay_tree_key)decl, flags);
7040 /* For reductions clauses in OpenACC loop directives, by default create a
7041 copy clause on the enclosing parallel construct for carrying back the
7042 results. */
7043 if (ctx->region_type == ORT_ACC && (flags & GOVD_REDUCTION))
7045 struct gimplify_omp_ctx *outer_ctx = ctx->outer_context;
7046 while (outer_ctx)
7048 n = splay_tree_lookup (outer_ctx->variables, (splay_tree_key)decl);
7049 if (n != NULL)
7051 /* Ignore local variables and explicitly declared clauses. */
7052 if (n->value & (GOVD_LOCAL | GOVD_EXPLICIT))
7053 break;
7054 else if (outer_ctx->region_type == ORT_ACC_KERNELS)
7056 /* According to the OpenACC spec, such a reduction variable
7057 should already have a copy map on a kernels construct,
7058 verify that here. */
7059 gcc_assert (!(n->value & GOVD_FIRSTPRIVATE)
7060 && (n->value & GOVD_MAP));
7062 else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
7064 /* Remove firstprivate and make it a copy map. */
7065 n->value &= ~GOVD_FIRSTPRIVATE;
7066 n->value |= GOVD_MAP;
7069 else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
7071 splay_tree_insert (outer_ctx->variables, (splay_tree_key)decl,
7072 GOVD_MAP | GOVD_SEEN);
7073 break;
7075 outer_ctx = outer_ctx->outer_context;
7080 /* Notice a threadprivate variable DECL used in OMP context CTX.
7081 This just prints out diagnostics about threadprivate variable uses
7082 in untied tasks. If DECL2 is non-NULL, prevent this warning
7083 on that variable. */
7085 static bool
7086 omp_notice_threadprivate_variable (struct gimplify_omp_ctx *ctx, tree decl,
7087 tree decl2)
7089 splay_tree_node n;
7090 struct gimplify_omp_ctx *octx;
7092 for (octx = ctx; octx; octx = octx->outer_context)
7093 if ((octx->region_type & ORT_TARGET) != 0
7094 || octx->order_concurrent)
7096 n = splay_tree_lookup (octx->variables, (splay_tree_key)decl);
7097 if (n == NULL)
7099 if (octx->order_concurrent)
7101 error ("threadprivate variable %qE used in a region with"
7102 " %<order(concurrent)%> clause", DECL_NAME (decl));
7103 error_at (octx->location, "enclosing region");
7105 else
7107 error ("threadprivate variable %qE used in target region",
7108 DECL_NAME (decl));
7109 error_at (octx->location, "enclosing target region");
7111 splay_tree_insert (octx->variables, (splay_tree_key)decl, 0);
7113 if (decl2)
7114 splay_tree_insert (octx->variables, (splay_tree_key)decl2, 0);
7117 if (ctx->region_type != ORT_UNTIED_TASK)
7118 return false;
7119 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7120 if (n == NULL)
7122 error ("threadprivate variable %qE used in untied task",
7123 DECL_NAME (decl));
7124 error_at (ctx->location, "enclosing task");
7125 splay_tree_insert (ctx->variables, (splay_tree_key)decl, 0);
7127 if (decl2)
7128 splay_tree_insert (ctx->variables, (splay_tree_key)decl2, 0);
7129 return false;
7132 /* Return true if global var DECL is device resident. */
7134 static bool
7135 device_resident_p (tree decl)
7137 tree attr = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (decl));
7139 if (!attr)
7140 return false;
7142 for (tree t = TREE_VALUE (attr); t; t = TREE_PURPOSE (t))
7144 tree c = TREE_VALUE (t);
7145 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DEVICE_RESIDENT)
7146 return true;
7149 return false;
7152 /* Return true if DECL has an ACC DECLARE attribute. */
7154 static bool
7155 is_oacc_declared (tree decl)
7157 tree t = TREE_CODE (decl) == MEM_REF ? TREE_OPERAND (decl, 0) : decl;
7158 tree declared = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (t));
7159 return declared != NULL_TREE;
7162 /* Determine outer default flags for DECL mentioned in an OMP region
7163 but not declared in an enclosing clause.
7165 ??? Some compiler-generated variables (like SAVE_EXPRs) could be
7166 remapped firstprivate instead of shared. To some extent this is
7167 addressed in omp_firstprivatize_type_sizes, but not
7168 effectively. */
7170 static unsigned
7171 omp_default_clause (struct gimplify_omp_ctx *ctx, tree decl,
7172 bool in_code, unsigned flags)
7174 enum omp_clause_default_kind default_kind = ctx->default_kind;
7175 enum omp_clause_default_kind kind;
7177 kind = lang_hooks.decls.omp_predetermined_sharing (decl);
7178 if (kind != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
7179 default_kind = kind;
7180 else if (VAR_P (decl) && TREE_STATIC (decl) && DECL_IN_CONSTANT_POOL (decl))
7181 default_kind = OMP_CLAUSE_DEFAULT_SHARED;
7183 switch (default_kind)
7185 case OMP_CLAUSE_DEFAULT_NONE:
7187 const char *rtype;
7189 if (ctx->region_type & ORT_PARALLEL)
7190 rtype = "parallel";
7191 else if ((ctx->region_type & ORT_TASKLOOP) == ORT_TASKLOOP)
7192 rtype = "taskloop";
7193 else if (ctx->region_type & ORT_TASK)
7194 rtype = "task";
7195 else if (ctx->region_type & ORT_TEAMS)
7196 rtype = "teams";
7197 else
7198 gcc_unreachable ();
7200 error ("%qE not specified in enclosing %qs",
7201 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rtype);
7202 error_at (ctx->location, "enclosing %qs", rtype);
7204 /* FALLTHRU */
7205 case OMP_CLAUSE_DEFAULT_SHARED:
7206 flags |= GOVD_SHARED;
7207 break;
7208 case OMP_CLAUSE_DEFAULT_PRIVATE:
7209 flags |= GOVD_PRIVATE;
7210 break;
7211 case OMP_CLAUSE_DEFAULT_FIRSTPRIVATE:
7212 flags |= GOVD_FIRSTPRIVATE;
7213 break;
7214 case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
7215 /* decl will be either GOVD_FIRSTPRIVATE or GOVD_SHARED. */
7216 gcc_assert ((ctx->region_type & ORT_TASK) != 0);
7217 if (struct gimplify_omp_ctx *octx = ctx->outer_context)
7219 omp_notice_variable (octx, decl, in_code);
7220 for (; octx; octx = octx->outer_context)
7222 splay_tree_node n2;
7224 n2 = splay_tree_lookup (octx->variables, (splay_tree_key) decl);
7225 if ((octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)) != 0
7226 && (n2 == NULL || (n2->value & GOVD_DATA_SHARE_CLASS) == 0))
7227 continue;
7228 if (n2 && (n2->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED)
7230 flags |= GOVD_FIRSTPRIVATE;
7231 goto found_outer;
7233 if ((octx->region_type & (ORT_PARALLEL | ORT_TEAMS)) != 0)
7235 flags |= GOVD_SHARED;
7236 goto found_outer;
7241 if (TREE_CODE (decl) == PARM_DECL
7242 || (!is_global_var (decl)
7243 && DECL_CONTEXT (decl) == current_function_decl))
7244 flags |= GOVD_FIRSTPRIVATE;
7245 else
7246 flags |= GOVD_SHARED;
7247 found_outer:
7248 break;
7250 default:
7251 gcc_unreachable ();
7254 return flags;
7258 /* Determine outer default flags for DECL mentioned in an OACC region
7259 but not declared in an enclosing clause. */
7261 static unsigned
7262 oacc_default_clause (struct gimplify_omp_ctx *ctx, tree decl, unsigned flags)
7264 const char *rkind;
7265 bool on_device = false;
7266 bool is_private = false;
7267 bool declared = is_oacc_declared (decl);
7268 tree type = TREE_TYPE (decl);
7270 if (lang_hooks.decls.omp_privatize_by_reference (decl))
7271 type = TREE_TYPE (type);
7273 /* For Fortran COMMON blocks, only used variables in those blocks are
7274 transfered and remapped. The block itself will have a private clause to
7275 avoid transfering the data twice.
7276 The hook evaluates to false by default. For a variable in Fortran's COMMON
7277 or EQUIVALENCE block, returns 'true' (as we have shared=false) - as only
7278 the variables in such a COMMON/EQUIVALENCE block shall be privatized not
7279 the whole block. For C++ and Fortran, it can also be true under certain
7280 other conditions, if DECL_HAS_VALUE_EXPR. */
7281 if (RECORD_OR_UNION_TYPE_P (type))
7282 is_private = lang_hooks.decls.omp_disregard_value_expr (decl, false);
7284 if ((ctx->region_type & (ORT_ACC_PARALLEL | ORT_ACC_KERNELS)) != 0
7285 && is_global_var (decl)
7286 && device_resident_p (decl)
7287 && !is_private)
7289 on_device = true;
7290 flags |= GOVD_MAP_TO_ONLY;
7293 switch (ctx->region_type)
7295 case ORT_ACC_KERNELS:
7296 rkind = "kernels";
7298 if (is_private)
7299 flags |= GOVD_FIRSTPRIVATE;
7300 else if (AGGREGATE_TYPE_P (type))
7302 /* Aggregates default to 'present_or_copy', or 'present'. */
7303 if (ctx->default_kind != OMP_CLAUSE_DEFAULT_PRESENT)
7304 flags |= GOVD_MAP;
7305 else
7306 flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
7308 else
7309 /* Scalars default to 'copy'. */
7310 flags |= GOVD_MAP | GOVD_MAP_FORCE;
7312 break;
7314 case ORT_ACC_PARALLEL:
7315 case ORT_ACC_SERIAL:
7316 rkind = ctx->region_type == ORT_ACC_PARALLEL ? "parallel" : "serial";
7318 if (is_private)
7319 flags |= GOVD_FIRSTPRIVATE;
7320 else if (on_device || declared)
7321 flags |= GOVD_MAP;
7322 else if (AGGREGATE_TYPE_P (type))
7324 /* Aggregates default to 'present_or_copy', or 'present'. */
7325 if (ctx->default_kind != OMP_CLAUSE_DEFAULT_PRESENT)
7326 flags |= GOVD_MAP;
7327 else
7328 flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
7330 else
7331 /* Scalars default to 'firstprivate'. */
7332 flags |= GOVD_FIRSTPRIVATE;
7334 break;
7336 default:
7337 gcc_unreachable ();
7340 if (DECL_ARTIFICIAL (decl))
7341 ; /* We can get compiler-generated decls, and should not complain
7342 about them. */
7343 else if (ctx->default_kind == OMP_CLAUSE_DEFAULT_NONE)
7345 error ("%qE not specified in enclosing OpenACC %qs construct",
7346 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rkind);
7347 inform (ctx->location, "enclosing OpenACC %qs construct", rkind);
7349 else if (ctx->default_kind == OMP_CLAUSE_DEFAULT_PRESENT)
7350 ; /* Handled above. */
7351 else
7352 gcc_checking_assert (ctx->default_kind == OMP_CLAUSE_DEFAULT_SHARED);
7354 return flags;
7357 /* Record the fact that DECL was used within the OMP context CTX.
7358 IN_CODE is true when real code uses DECL, and false when we should
7359 merely emit default(none) errors. Return true if DECL is going to
7360 be remapped and thus DECL shouldn't be gimplified into its
7361 DECL_VALUE_EXPR (if any). */
7363 static bool
7364 omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
7366 splay_tree_node n;
7367 unsigned flags = in_code ? GOVD_SEEN : 0;
7368 bool ret = false, shared;
7370 if (error_operand_p (decl))
7371 return false;
7373 if (ctx->region_type == ORT_NONE)
7374 return lang_hooks.decls.omp_disregard_value_expr (decl, false);
7376 if (is_global_var (decl))
7378 /* Threadprivate variables are predetermined. */
7379 if (DECL_THREAD_LOCAL_P (decl))
7380 return omp_notice_threadprivate_variable (ctx, decl, NULL_TREE);
7382 if (DECL_HAS_VALUE_EXPR_P (decl))
7384 if (ctx->region_type & ORT_ACC)
7385 /* For OpenACC, defer expansion of value to avoid transfering
7386 privatized common block data instead of im-/explicitly transfered
7387 variables which are in common blocks. */
7389 else
7391 tree value = get_base_address (DECL_VALUE_EXPR (decl));
7393 if (value && DECL_P (value) && DECL_THREAD_LOCAL_P (value))
7394 return omp_notice_threadprivate_variable (ctx, decl, value);
7398 if (gimplify_omp_ctxp->outer_context == NULL
7399 && VAR_P (decl)
7400 && oacc_get_fn_attrib (current_function_decl))
7402 location_t loc = DECL_SOURCE_LOCATION (decl);
7404 if (lookup_attribute ("omp declare target link",
7405 DECL_ATTRIBUTES (decl)))
7407 error_at (loc,
7408 "%qE with %<link%> clause used in %<routine%> function",
7409 DECL_NAME (decl));
7410 return false;
7412 else if (!lookup_attribute ("omp declare target",
7413 DECL_ATTRIBUTES (decl)))
7415 error_at (loc,
7416 "%qE requires a %<declare%> directive for use "
7417 "in a %<routine%> function", DECL_NAME (decl));
7418 return false;
7423 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7424 if ((ctx->region_type & ORT_TARGET) != 0)
7426 if (ctx->region_type & ORT_ACC)
7427 /* For OpenACC, as remarked above, defer expansion. */
7428 shared = false;
7429 else
7430 shared = true;
7432 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7433 if (n == NULL)
7435 unsigned nflags = flags;
7436 if ((ctx->region_type & ORT_ACC) == 0)
7438 bool is_declare_target = false;
7439 if (is_global_var (decl)
7440 && varpool_node::get_create (decl)->offloadable)
7442 struct gimplify_omp_ctx *octx;
7443 for (octx = ctx->outer_context;
7444 octx; octx = octx->outer_context)
7446 n = splay_tree_lookup (octx->variables,
7447 (splay_tree_key)decl);
7448 if (n
7449 && (n->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED
7450 && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
7451 break;
7453 is_declare_target = octx == NULL;
7455 if (!is_declare_target)
7457 int gdmk;
7458 if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
7459 || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
7460 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
7461 == POINTER_TYPE)))
7462 gdmk = GDMK_POINTER;
7463 else if (lang_hooks.decls.omp_scalar_p (decl))
7464 gdmk = GDMK_SCALAR;
7465 else
7466 gdmk = GDMK_AGGREGATE;
7467 if (ctx->defaultmap[gdmk] == 0)
7469 tree d = lang_hooks.decls.omp_report_decl (decl);
7470 error ("%qE not specified in enclosing %<target%>",
7471 DECL_NAME (d));
7472 error_at (ctx->location, "enclosing %<target%>");
7474 else if (ctx->defaultmap[gdmk]
7475 & (GOVD_MAP_0LEN_ARRAY | GOVD_FIRSTPRIVATE))
7476 nflags |= ctx->defaultmap[gdmk];
7477 else
7479 gcc_assert (ctx->defaultmap[gdmk] & GOVD_MAP);
7480 nflags |= ctx->defaultmap[gdmk] & ~GOVD_MAP;
7485 struct gimplify_omp_ctx *octx = ctx->outer_context;
7486 if ((ctx->region_type & ORT_ACC) && octx)
7488 /* Look in outer OpenACC contexts, to see if there's a
7489 data attribute for this variable. */
7490 omp_notice_variable (octx, decl, in_code);
7492 for (; octx; octx = octx->outer_context)
7494 if (!(octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)))
7495 break;
7496 splay_tree_node n2
7497 = splay_tree_lookup (octx->variables,
7498 (splay_tree_key) decl);
7499 if (n2)
7501 if (octx->region_type == ORT_ACC_HOST_DATA)
7502 error ("variable %qE declared in enclosing "
7503 "%<host_data%> region", DECL_NAME (decl));
7504 nflags |= GOVD_MAP;
7505 if (octx->region_type == ORT_ACC_DATA
7506 && (n2->value & GOVD_MAP_0LEN_ARRAY))
7507 nflags |= GOVD_MAP_0LEN_ARRAY;
7508 goto found_outer;
7513 if ((nflags & ~(GOVD_MAP_TO_ONLY | GOVD_MAP_FROM_ONLY
7514 | GOVD_MAP_ALLOC_ONLY)) == flags)
7516 tree type = TREE_TYPE (decl);
7518 if (gimplify_omp_ctxp->target_firstprivatize_array_bases
7519 && lang_hooks.decls.omp_privatize_by_reference (decl))
7520 type = TREE_TYPE (type);
7521 if (!lang_hooks.types.omp_mappable_type (type))
7523 error ("%qD referenced in target region does not have "
7524 "a mappable type", decl);
7525 nflags |= GOVD_MAP | GOVD_EXPLICIT;
7527 else
7529 if ((ctx->region_type & ORT_ACC) != 0)
7530 nflags = oacc_default_clause (ctx, decl, flags);
7531 else
7532 nflags |= GOVD_MAP;
7535 found_outer:
7536 omp_add_variable (ctx, decl, nflags);
7538 else
7540 /* If nothing changed, there's nothing left to do. */
7541 if ((n->value & flags) == flags)
7542 return ret;
7543 flags |= n->value;
7544 n->value = flags;
7546 goto do_outer;
7549 if (n == NULL)
7551 if (ctx->region_type == ORT_WORKSHARE
7552 || ctx->region_type == ORT_TASKGROUP
7553 || ctx->region_type == ORT_SIMD
7554 || ctx->region_type == ORT_ACC
7555 || (ctx->region_type & ORT_TARGET_DATA) != 0)
7556 goto do_outer;
7558 flags = omp_default_clause (ctx, decl, in_code, flags);
7560 if ((flags & GOVD_PRIVATE)
7561 && lang_hooks.decls.omp_private_outer_ref (decl))
7562 flags |= GOVD_PRIVATE_OUTER_REF;
7564 omp_add_variable (ctx, decl, flags);
7566 shared = (flags & GOVD_SHARED) != 0;
7567 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7568 goto do_outer;
7571 if ((n->value & (GOVD_SEEN | GOVD_LOCAL)) == 0
7572 && (flags & (GOVD_SEEN | GOVD_LOCAL)) == GOVD_SEEN
7573 && DECL_SIZE (decl))
7575 if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
7577 splay_tree_node n2;
7578 tree t = DECL_VALUE_EXPR (decl);
7579 gcc_assert (TREE_CODE (t) == INDIRECT_REF);
7580 t = TREE_OPERAND (t, 0);
7581 gcc_assert (DECL_P (t));
7582 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
7583 n2->value |= GOVD_SEEN;
7585 else if (lang_hooks.decls.omp_privatize_by_reference (decl)
7586 && TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)))
7587 && (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))))
7588 != INTEGER_CST))
7590 splay_tree_node n2;
7591 tree t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
7592 gcc_assert (DECL_P (t));
7593 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
7594 if (n2)
7595 omp_notice_variable (ctx, t, true);
7599 if (ctx->region_type & ORT_ACC)
7600 /* For OpenACC, as remarked above, defer expansion. */
7601 shared = false;
7602 else
7603 shared = ((flags | n->value) & GOVD_SHARED) != 0;
7604 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7606 /* If nothing changed, there's nothing left to do. */
7607 if ((n->value & flags) == flags)
7608 return ret;
7609 flags |= n->value;
7610 n->value = flags;
7612 do_outer:
7613 /* If the variable is private in the current context, then we don't
7614 need to propagate anything to an outer context. */
7615 if ((flags & GOVD_PRIVATE) && !(flags & GOVD_PRIVATE_OUTER_REF))
7616 return ret;
7617 if ((flags & (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7618 == (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7619 return ret;
7620 if ((flags & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
7621 | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7622 == (GOVD_LASTPRIVATE | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7623 return ret;
7624 if (ctx->outer_context
7625 && omp_notice_variable (ctx->outer_context, decl, in_code))
7626 return true;
7627 return ret;
7630 /* Verify that DECL is private within CTX. If there's specific information
7631 to the contrary in the innermost scope, generate an error. */
7633 static bool
7634 omp_is_private (struct gimplify_omp_ctx *ctx, tree decl, int simd)
7636 splay_tree_node n;
7638 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7639 if (n != NULL)
7641 if (n->value & GOVD_SHARED)
7643 if (ctx == gimplify_omp_ctxp)
7645 if (simd)
7646 error ("iteration variable %qE is predetermined linear",
7647 DECL_NAME (decl));
7648 else
7649 error ("iteration variable %qE should be private",
7650 DECL_NAME (decl));
7651 n->value = GOVD_PRIVATE;
7652 return true;
7654 else
7655 return false;
7657 else if ((n->value & GOVD_EXPLICIT) != 0
7658 && (ctx == gimplify_omp_ctxp
7659 || (ctx->region_type == ORT_COMBINED_PARALLEL
7660 && gimplify_omp_ctxp->outer_context == ctx)))
7662 if ((n->value & GOVD_FIRSTPRIVATE) != 0)
7663 error ("iteration variable %qE should not be firstprivate",
7664 DECL_NAME (decl));
7665 else if ((n->value & GOVD_REDUCTION) != 0)
7666 error ("iteration variable %qE should not be reduction",
7667 DECL_NAME (decl));
7668 else if (simd != 1 && (n->value & GOVD_LINEAR) != 0)
7669 error ("iteration variable %qE should not be linear",
7670 DECL_NAME (decl));
7672 return (ctx == gimplify_omp_ctxp
7673 || (ctx->region_type == ORT_COMBINED_PARALLEL
7674 && gimplify_omp_ctxp->outer_context == ctx));
7677 if (ctx->region_type != ORT_WORKSHARE
7678 && ctx->region_type != ORT_TASKGROUP
7679 && ctx->region_type != ORT_SIMD
7680 && ctx->region_type != ORT_ACC)
7681 return false;
7682 else if (ctx->outer_context)
7683 return omp_is_private (ctx->outer_context, decl, simd);
7684 return false;
7687 /* Return true if DECL is private within a parallel region
7688 that binds to the current construct's context or in parallel
7689 region's REDUCTION clause. */
7691 static bool
7692 omp_check_private (struct gimplify_omp_ctx *ctx, tree decl, bool copyprivate)
7694 splay_tree_node n;
7698 ctx = ctx->outer_context;
7699 if (ctx == NULL)
7701 if (is_global_var (decl))
7702 return false;
7704 /* References might be private, but might be shared too,
7705 when checking for copyprivate, assume they might be
7706 private, otherwise assume they might be shared. */
7707 if (copyprivate)
7708 return true;
7710 if (lang_hooks.decls.omp_privatize_by_reference (decl))
7711 return false;
7713 /* Treat C++ privatized non-static data members outside
7714 of the privatization the same. */
7715 if (omp_member_access_dummy_var (decl))
7716 return false;
7718 return true;
7721 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
7723 if ((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
7724 && (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0))
7725 continue;
7727 if (n != NULL)
7729 if ((n->value & GOVD_LOCAL) != 0
7730 && omp_member_access_dummy_var (decl))
7731 return false;
7732 return (n->value & GOVD_SHARED) == 0;
7735 while (ctx->region_type == ORT_WORKSHARE
7736 || ctx->region_type == ORT_TASKGROUP
7737 || ctx->region_type == ORT_SIMD
7738 || ctx->region_type == ORT_ACC);
7739 return false;
7742 /* Callback for walk_tree to find a DECL_EXPR for the given DECL. */
7744 static tree
7745 find_decl_expr (tree *tp, int *walk_subtrees, void *data)
7747 tree t = *tp;
7749 /* If this node has been visited, unmark it and keep looking. */
7750 if (TREE_CODE (t) == DECL_EXPR && DECL_EXPR_DECL (t) == (tree) data)
7751 return t;
7753 if (IS_TYPE_OR_DECL_P (t))
7754 *walk_subtrees = 0;
7755 return NULL_TREE;
7758 /* If *LIST_P contains any OpenMP depend clauses with iterators,
7759 lower all the depend clauses by populating corresponding depend
7760 array. Returns 0 if there are no such depend clauses, or
7761 2 if all depend clauses should be removed, 1 otherwise. */
7763 static int
7764 gimplify_omp_depend (tree *list_p, gimple_seq *pre_p)
7766 tree c;
7767 gimple *g;
7768 size_t n[4] = { 0, 0, 0, 0 };
7769 bool unused[4];
7770 tree counts[4] = { NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE };
7771 tree last_iter = NULL_TREE, last_count = NULL_TREE;
7772 size_t i, j;
7773 location_t first_loc = UNKNOWN_LOCATION;
7775 for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
7776 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
7778 switch (OMP_CLAUSE_DEPEND_KIND (c))
7780 case OMP_CLAUSE_DEPEND_IN:
7781 i = 2;
7782 break;
7783 case OMP_CLAUSE_DEPEND_OUT:
7784 case OMP_CLAUSE_DEPEND_INOUT:
7785 i = 0;
7786 break;
7787 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
7788 i = 1;
7789 break;
7790 case OMP_CLAUSE_DEPEND_DEPOBJ:
7791 i = 3;
7792 break;
7793 case OMP_CLAUSE_DEPEND_SOURCE:
7794 case OMP_CLAUSE_DEPEND_SINK:
7795 continue;
7796 default:
7797 gcc_unreachable ();
7799 tree t = OMP_CLAUSE_DECL (c);
7800 if (first_loc == UNKNOWN_LOCATION)
7801 first_loc = OMP_CLAUSE_LOCATION (c);
7802 if (TREE_CODE (t) == TREE_LIST
7803 && TREE_PURPOSE (t)
7804 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
7806 if (TREE_PURPOSE (t) != last_iter)
7808 tree tcnt = size_one_node;
7809 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
7811 if (gimplify_expr (&TREE_VEC_ELT (it, 1), pre_p, NULL,
7812 is_gimple_val, fb_rvalue) == GS_ERROR
7813 || gimplify_expr (&TREE_VEC_ELT (it, 2), pre_p, NULL,
7814 is_gimple_val, fb_rvalue) == GS_ERROR
7815 || gimplify_expr (&TREE_VEC_ELT (it, 3), pre_p, NULL,
7816 is_gimple_val, fb_rvalue) == GS_ERROR
7817 || (gimplify_expr (&TREE_VEC_ELT (it, 4), pre_p, NULL,
7818 is_gimple_val, fb_rvalue)
7819 == GS_ERROR))
7820 return 2;
7821 tree var = TREE_VEC_ELT (it, 0);
7822 tree begin = TREE_VEC_ELT (it, 1);
7823 tree end = TREE_VEC_ELT (it, 2);
7824 tree step = TREE_VEC_ELT (it, 3);
7825 tree orig_step = TREE_VEC_ELT (it, 4);
7826 tree type = TREE_TYPE (var);
7827 tree stype = TREE_TYPE (step);
7828 location_t loc = DECL_SOURCE_LOCATION (var);
7829 tree endmbegin;
7830 /* Compute count for this iterator as
7831 orig_step > 0
7832 ? (begin < end ? (end - begin + (step - 1)) / step : 0)
7833 : (begin > end ? (end - begin + (step + 1)) / step : 0)
7834 and compute product of those for the entire depend
7835 clause. */
7836 if (POINTER_TYPE_P (type))
7837 endmbegin = fold_build2_loc (loc, POINTER_DIFF_EXPR,
7838 stype, end, begin);
7839 else
7840 endmbegin = fold_build2_loc (loc, MINUS_EXPR, type,
7841 end, begin);
7842 tree stepm1 = fold_build2_loc (loc, MINUS_EXPR, stype,
7843 step,
7844 build_int_cst (stype, 1));
7845 tree stepp1 = fold_build2_loc (loc, PLUS_EXPR, stype, step,
7846 build_int_cst (stype, 1));
7847 tree pos = fold_build2_loc (loc, PLUS_EXPR, stype,
7848 unshare_expr (endmbegin),
7849 stepm1);
7850 pos = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype,
7851 pos, step);
7852 tree neg = fold_build2_loc (loc, PLUS_EXPR, stype,
7853 endmbegin, stepp1);
7854 if (TYPE_UNSIGNED (stype))
7856 neg = fold_build1_loc (loc, NEGATE_EXPR, stype, neg);
7857 step = fold_build1_loc (loc, NEGATE_EXPR, stype, step);
7859 neg = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype,
7860 neg, step);
7861 step = NULL_TREE;
7862 tree cond = fold_build2_loc (loc, LT_EXPR,
7863 boolean_type_node,
7864 begin, end);
7865 pos = fold_build3_loc (loc, COND_EXPR, stype, cond, pos,
7866 build_int_cst (stype, 0));
7867 cond = fold_build2_loc (loc, LT_EXPR, boolean_type_node,
7868 end, begin);
7869 neg = fold_build3_loc (loc, COND_EXPR, stype, cond, neg,
7870 build_int_cst (stype, 0));
7871 tree osteptype = TREE_TYPE (orig_step);
7872 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
7873 orig_step,
7874 build_int_cst (osteptype, 0));
7875 tree cnt = fold_build3_loc (loc, COND_EXPR, stype,
7876 cond, pos, neg);
7877 cnt = fold_convert_loc (loc, sizetype, cnt);
7878 if (gimplify_expr (&cnt, pre_p, NULL, is_gimple_val,
7879 fb_rvalue) == GS_ERROR)
7880 return 2;
7881 tcnt = size_binop_loc (loc, MULT_EXPR, tcnt, cnt);
7883 if (gimplify_expr (&tcnt, pre_p, NULL, is_gimple_val,
7884 fb_rvalue) == GS_ERROR)
7885 return 2;
7886 last_iter = TREE_PURPOSE (t);
7887 last_count = tcnt;
7889 if (counts[i] == NULL_TREE)
7890 counts[i] = last_count;
7891 else
7892 counts[i] = size_binop_loc (OMP_CLAUSE_LOCATION (c),
7893 PLUS_EXPR, counts[i], last_count);
7895 else
7896 n[i]++;
7898 for (i = 0; i < 4; i++)
7899 if (counts[i])
7900 break;
7901 if (i == 4)
7902 return 0;
7904 tree total = size_zero_node;
7905 for (i = 0; i < 4; i++)
7907 unused[i] = counts[i] == NULL_TREE && n[i] == 0;
7908 if (counts[i] == NULL_TREE)
7909 counts[i] = size_zero_node;
7910 if (n[i])
7911 counts[i] = size_binop (PLUS_EXPR, counts[i], size_int (n[i]));
7912 if (gimplify_expr (&counts[i], pre_p, NULL, is_gimple_val,
7913 fb_rvalue) == GS_ERROR)
7914 return 2;
7915 total = size_binop (PLUS_EXPR, total, counts[i]);
7918 if (gimplify_expr (&total, pre_p, NULL, is_gimple_val, fb_rvalue)
7919 == GS_ERROR)
7920 return 2;
7921 bool is_old = unused[1] && unused[3];
7922 tree totalpx = size_binop (PLUS_EXPR, unshare_expr (total),
7923 size_int (is_old ? 1 : 4));
7924 tree type = build_array_type (ptr_type_node, build_index_type (totalpx));
7925 tree array = create_tmp_var_raw (type);
7926 TREE_ADDRESSABLE (array) = 1;
7927 if (!poly_int_tree_p (totalpx))
7929 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (array)))
7930 gimplify_type_sizes (TREE_TYPE (array), pre_p);
7931 if (gimplify_omp_ctxp)
7933 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
7934 while (ctx
7935 && (ctx->region_type == ORT_WORKSHARE
7936 || ctx->region_type == ORT_TASKGROUP
7937 || ctx->region_type == ORT_SIMD
7938 || ctx->region_type == ORT_ACC))
7939 ctx = ctx->outer_context;
7940 if (ctx)
7941 omp_add_variable (ctx, array, GOVD_LOCAL | GOVD_SEEN);
7943 gimplify_vla_decl (array, pre_p);
7945 else
7946 gimple_add_tmp_var (array);
7947 tree r = build4 (ARRAY_REF, ptr_type_node, array, size_int (0), NULL_TREE,
7948 NULL_TREE);
7949 tree tem;
7950 if (!is_old)
7952 tem = build2 (MODIFY_EXPR, void_type_node, r,
7953 build_int_cst (ptr_type_node, 0));
7954 gimplify_and_add (tem, pre_p);
7955 r = build4 (ARRAY_REF, ptr_type_node, array, size_int (1), NULL_TREE,
7956 NULL_TREE);
7958 tem = build2 (MODIFY_EXPR, void_type_node, r,
7959 fold_convert (ptr_type_node, total));
7960 gimplify_and_add (tem, pre_p);
7961 for (i = 1; i < (is_old ? 2 : 4); i++)
7963 r = build4 (ARRAY_REF, ptr_type_node, array, size_int (i + !is_old),
7964 NULL_TREE, NULL_TREE);
7965 tem = build2 (MODIFY_EXPR, void_type_node, r, counts[i - 1]);
7966 gimplify_and_add (tem, pre_p);
7969 tree cnts[4];
7970 for (j = 4; j; j--)
7971 if (!unused[j - 1])
7972 break;
7973 for (i = 0; i < 4; i++)
7975 if (i && (i >= j || unused[i - 1]))
7977 cnts[i] = cnts[i - 1];
7978 continue;
7980 cnts[i] = create_tmp_var (sizetype);
7981 if (i == 0)
7982 g = gimple_build_assign (cnts[i], size_int (is_old ? 2 : 5));
7983 else
7985 tree t;
7986 if (is_old)
7987 t = size_binop (PLUS_EXPR, counts[0], size_int (2));
7988 else
7989 t = size_binop (PLUS_EXPR, cnts[i - 1], counts[i - 1]);
7990 if (gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue)
7991 == GS_ERROR)
7992 return 2;
7993 g = gimple_build_assign (cnts[i], t);
7995 gimple_seq_add_stmt (pre_p, g);
7998 last_iter = NULL_TREE;
7999 tree last_bind = NULL_TREE;
8000 tree *last_body = NULL;
8001 for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
8002 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
8004 switch (OMP_CLAUSE_DEPEND_KIND (c))
8006 case OMP_CLAUSE_DEPEND_IN:
8007 i = 2;
8008 break;
8009 case OMP_CLAUSE_DEPEND_OUT:
8010 case OMP_CLAUSE_DEPEND_INOUT:
8011 i = 0;
8012 break;
8013 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
8014 i = 1;
8015 break;
8016 case OMP_CLAUSE_DEPEND_DEPOBJ:
8017 i = 3;
8018 break;
8019 case OMP_CLAUSE_DEPEND_SOURCE:
8020 case OMP_CLAUSE_DEPEND_SINK:
8021 continue;
8022 default:
8023 gcc_unreachable ();
8025 tree t = OMP_CLAUSE_DECL (c);
8026 if (TREE_CODE (t) == TREE_LIST
8027 && TREE_PURPOSE (t)
8028 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
8030 if (TREE_PURPOSE (t) != last_iter)
8032 if (last_bind)
8033 gimplify_and_add (last_bind, pre_p);
8034 tree block = TREE_VEC_ELT (TREE_PURPOSE (t), 5);
8035 last_bind = build3 (BIND_EXPR, void_type_node,
8036 BLOCK_VARS (block), NULL, block);
8037 TREE_SIDE_EFFECTS (last_bind) = 1;
8038 SET_EXPR_LOCATION (last_bind, OMP_CLAUSE_LOCATION (c));
8039 tree *p = &BIND_EXPR_BODY (last_bind);
8040 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8042 tree var = TREE_VEC_ELT (it, 0);
8043 tree begin = TREE_VEC_ELT (it, 1);
8044 tree end = TREE_VEC_ELT (it, 2);
8045 tree step = TREE_VEC_ELT (it, 3);
8046 tree orig_step = TREE_VEC_ELT (it, 4);
8047 tree type = TREE_TYPE (var);
8048 location_t loc = DECL_SOURCE_LOCATION (var);
8049 /* Emit:
8050 var = begin;
8051 goto cond_label;
8052 beg_label:
8054 var = var + step;
8055 cond_label:
8056 if (orig_step > 0) {
8057 if (var < end) goto beg_label;
8058 } else {
8059 if (var > end) goto beg_label;
8061 for each iterator, with inner iterators added to
8062 the ... above. */
8063 tree beg_label = create_artificial_label (loc);
8064 tree cond_label = NULL_TREE;
8065 tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
8066 var, begin);
8067 append_to_statement_list_force (tem, p);
8068 tem = build_and_jump (&cond_label);
8069 append_to_statement_list_force (tem, p);
8070 tem = build1 (LABEL_EXPR, void_type_node, beg_label);
8071 append_to_statement_list (tem, p);
8072 tree bind = build3 (BIND_EXPR, void_type_node, NULL_TREE,
8073 NULL_TREE, NULL_TREE);
8074 TREE_SIDE_EFFECTS (bind) = 1;
8075 SET_EXPR_LOCATION (bind, loc);
8076 append_to_statement_list_force (bind, p);
8077 if (POINTER_TYPE_P (type))
8078 tem = build2_loc (loc, POINTER_PLUS_EXPR, type,
8079 var, fold_convert_loc (loc, sizetype,
8080 step));
8081 else
8082 tem = build2_loc (loc, PLUS_EXPR, type, var, step);
8083 tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
8084 var, tem);
8085 append_to_statement_list_force (tem, p);
8086 tem = build1 (LABEL_EXPR, void_type_node, cond_label);
8087 append_to_statement_list (tem, p);
8088 tree cond = fold_build2_loc (loc, LT_EXPR,
8089 boolean_type_node,
8090 var, end);
8091 tree pos
8092 = fold_build3_loc (loc, COND_EXPR, void_type_node,
8093 cond, build_and_jump (&beg_label),
8094 void_node);
8095 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8096 var, end);
8097 tree neg
8098 = fold_build3_loc (loc, COND_EXPR, void_type_node,
8099 cond, build_and_jump (&beg_label),
8100 void_node);
8101 tree osteptype = TREE_TYPE (orig_step);
8102 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8103 orig_step,
8104 build_int_cst (osteptype, 0));
8105 tem = fold_build3_loc (loc, COND_EXPR, void_type_node,
8106 cond, pos, neg);
8107 append_to_statement_list_force (tem, p);
8108 p = &BIND_EXPR_BODY (bind);
8110 last_body = p;
8112 last_iter = TREE_PURPOSE (t);
8113 if (TREE_CODE (TREE_VALUE (t)) == COMPOUND_EXPR)
8115 append_to_statement_list (TREE_OPERAND (TREE_VALUE (t),
8116 0), last_body);
8117 TREE_VALUE (t) = TREE_OPERAND (TREE_VALUE (t), 1);
8119 if (error_operand_p (TREE_VALUE (t)))
8120 return 2;
8121 TREE_VALUE (t) = build_fold_addr_expr (TREE_VALUE (t));
8122 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
8123 NULL_TREE, NULL_TREE);
8124 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
8125 void_type_node, r, TREE_VALUE (t));
8126 append_to_statement_list_force (tem, last_body);
8127 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
8128 void_type_node, cnts[i],
8129 size_binop (PLUS_EXPR, cnts[i], size_int (1)));
8130 append_to_statement_list_force (tem, last_body);
8131 TREE_VALUE (t) = null_pointer_node;
8133 else
8135 if (last_bind)
8137 gimplify_and_add (last_bind, pre_p);
8138 last_bind = NULL_TREE;
8140 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
8142 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
8143 NULL, is_gimple_val, fb_rvalue);
8144 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
8146 if (error_operand_p (OMP_CLAUSE_DECL (c)))
8147 return 2;
8148 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
8149 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
8150 is_gimple_val, fb_rvalue) == GS_ERROR)
8151 return 2;
8152 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
8153 NULL_TREE, NULL_TREE);
8154 tem = build2 (MODIFY_EXPR, void_type_node, r, OMP_CLAUSE_DECL (c));
8155 gimplify_and_add (tem, pre_p);
8156 g = gimple_build_assign (cnts[i], size_binop (PLUS_EXPR, cnts[i],
8157 size_int (1)));
8158 gimple_seq_add_stmt (pre_p, g);
8161 if (last_bind)
8162 gimplify_and_add (last_bind, pre_p);
8163 tree cond = boolean_false_node;
8164 if (is_old)
8166 if (!unused[0])
8167 cond = build2_loc (first_loc, NE_EXPR, boolean_type_node, cnts[0],
8168 size_binop_loc (first_loc, PLUS_EXPR, counts[0],
8169 size_int (2)));
8170 if (!unused[2])
8171 cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond,
8172 build2_loc (first_loc, NE_EXPR, boolean_type_node,
8173 cnts[2],
8174 size_binop_loc (first_loc, PLUS_EXPR,
8175 totalpx,
8176 size_int (1))));
8178 else
8180 tree prev = size_int (5);
8181 for (i = 0; i < 4; i++)
8183 if (unused[i])
8184 continue;
8185 prev = size_binop_loc (first_loc, PLUS_EXPR, counts[i], prev);
8186 cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond,
8187 build2_loc (first_loc, NE_EXPR, boolean_type_node,
8188 cnts[i], unshare_expr (prev)));
8191 tem = build3_loc (first_loc, COND_EXPR, void_type_node, cond,
8192 build_call_expr_loc (first_loc,
8193 builtin_decl_explicit (BUILT_IN_TRAP),
8194 0), void_node);
8195 gimplify_and_add (tem, pre_p);
8196 c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_DEPEND);
8197 OMP_CLAUSE_DEPEND_KIND (c) = OMP_CLAUSE_DEPEND_LAST;
8198 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (array);
8199 OMP_CLAUSE_CHAIN (c) = *list_p;
8200 *list_p = c;
8201 return 1;
8204 /* Insert a GOMP_MAP_ALLOC or GOMP_MAP_RELEASE node following a
8205 GOMP_MAP_STRUCT mapping. C is an always_pointer mapping. STRUCT_NODE is
8206 the struct node to insert the new mapping after (when the struct node is
8207 initially created). PREV_NODE is the first of two or three mappings for a
8208 pointer, and is either:
8209 - the node before C, when a pair of mappings is used, e.g. for a C/C++
8210 array section.
8211 - not the node before C. This is true when we have a reference-to-pointer
8212 type (with a mapping for the reference and for the pointer), or for
8213 Fortran derived-type mappings with a GOMP_MAP_TO_PSET.
8214 If SCP is non-null, the new node is inserted before *SCP.
8215 if SCP is null, the new node is inserted before PREV_NODE.
8216 The return type is:
8217 - PREV_NODE, if SCP is non-null.
8218 - The newly-created ALLOC or RELEASE node, if SCP is null.
8219 - The second newly-created ALLOC or RELEASE node, if we are mapping a
8220 reference to a pointer. */
8222 static tree
8223 insert_struct_comp_map (enum tree_code code, tree c, tree struct_node,
8224 tree prev_node, tree *scp)
8226 enum gomp_map_kind mkind
8227 = (code == OMP_TARGET_EXIT_DATA || code == OACC_EXIT_DATA)
8228 ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
8230 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
8231 tree cl = scp ? prev_node : c2;
8232 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
8233 OMP_CLAUSE_DECL (c2) = unshare_expr (OMP_CLAUSE_DECL (c));
8234 OMP_CLAUSE_CHAIN (c2) = scp ? *scp : prev_node;
8235 if (OMP_CLAUSE_CHAIN (prev_node) != c
8236 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (prev_node)) == OMP_CLAUSE_MAP
8237 && (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node))
8238 == GOMP_MAP_TO_PSET))
8239 OMP_CLAUSE_SIZE (c2) = OMP_CLAUSE_SIZE (OMP_CLAUSE_CHAIN (prev_node));
8240 else
8241 OMP_CLAUSE_SIZE (c2) = TYPE_SIZE_UNIT (ptr_type_node);
8242 if (struct_node)
8243 OMP_CLAUSE_CHAIN (struct_node) = c2;
8245 /* We might need to create an additional mapping if we have a reference to a
8246 pointer (in C++). Don't do this if we have something other than a
8247 GOMP_MAP_ALWAYS_POINTER though, i.e. a GOMP_MAP_TO_PSET. */
8248 if (OMP_CLAUSE_CHAIN (prev_node) != c
8249 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (prev_node)) == OMP_CLAUSE_MAP
8250 && ((OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node))
8251 == GOMP_MAP_ALWAYS_POINTER)
8252 || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node))
8253 == GOMP_MAP_ATTACH_DETACH)))
8255 tree c4 = OMP_CLAUSE_CHAIN (prev_node);
8256 tree c3 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
8257 OMP_CLAUSE_SET_MAP_KIND (c3, mkind);
8258 OMP_CLAUSE_DECL (c3) = unshare_expr (OMP_CLAUSE_DECL (c4));
8259 OMP_CLAUSE_SIZE (c3) = TYPE_SIZE_UNIT (ptr_type_node);
8260 OMP_CLAUSE_CHAIN (c3) = prev_node;
8261 if (!scp)
8262 OMP_CLAUSE_CHAIN (c2) = c3;
8263 else
8264 cl = c3;
8267 if (scp)
8268 *scp = c2;
8270 return cl;
8273 /* Strip ARRAY_REFS or an indirect ref off BASE, find the containing object,
8274 and set *BITPOSP and *POFFSETP to the bit offset of the access.
8275 If BASE_REF is non-NULL and the containing object is a reference, set
8276 *BASE_REF to that reference before dereferencing the object.
8277 If BASE_REF is NULL, check that the containing object is a COMPONENT_REF or
8278 has array type, else return NULL. */
8280 static tree
8281 extract_base_bit_offset (tree base, tree *base_ref, poly_int64 *bitposp,
8282 poly_offset_int *poffsetp)
8284 tree offset;
8285 poly_int64 bitsize, bitpos;
8286 machine_mode mode;
8287 int unsignedp, reversep, volatilep = 0;
8288 poly_offset_int poffset;
8290 if (base_ref)
8292 *base_ref = NULL_TREE;
8294 while (TREE_CODE (base) == ARRAY_REF)
8295 base = TREE_OPERAND (base, 0);
8297 if (TREE_CODE (base) == INDIRECT_REF)
8298 base = TREE_OPERAND (base, 0);
8300 else
8302 if (TREE_CODE (base) == ARRAY_REF)
8304 while (TREE_CODE (base) == ARRAY_REF)
8305 base = TREE_OPERAND (base, 0);
8306 if (TREE_CODE (base) != COMPONENT_REF
8307 || TREE_CODE (TREE_TYPE (base)) != ARRAY_TYPE)
8308 return NULL_TREE;
8310 else if (TREE_CODE (base) == INDIRECT_REF
8311 && TREE_CODE (TREE_OPERAND (base, 0)) == COMPONENT_REF
8312 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0)))
8313 == REFERENCE_TYPE))
8314 base = TREE_OPERAND (base, 0);
8317 base = get_inner_reference (base, &bitsize, &bitpos, &offset, &mode,
8318 &unsignedp, &reversep, &volatilep);
8320 tree orig_base = base;
8322 if ((TREE_CODE (base) == INDIRECT_REF
8323 || (TREE_CODE (base) == MEM_REF
8324 && integer_zerop (TREE_OPERAND (base, 1))))
8325 && DECL_P (TREE_OPERAND (base, 0))
8326 && TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0))) == REFERENCE_TYPE)
8327 base = TREE_OPERAND (base, 0);
8329 gcc_assert (offset == NULL_TREE || poly_int_tree_p (offset));
8331 if (offset)
8332 poffset = wi::to_poly_offset (offset);
8333 else
8334 poffset = 0;
8336 if (maybe_ne (bitpos, 0))
8337 poffset += bits_to_bytes_round_down (bitpos);
8339 *bitposp = bitpos;
8340 *poffsetp = poffset;
8342 /* Set *BASE_REF if BASE was a dereferenced reference variable. */
8343 if (base_ref && orig_base != base)
8344 *base_ref = orig_base;
8346 return base;
8349 /* Scan the OMP clauses in *LIST_P, installing mappings into a new
8350 and previous omp contexts. */
8352 static void
8353 gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
8354 enum omp_region_type region_type,
8355 enum tree_code code)
8357 struct gimplify_omp_ctx *ctx, *outer_ctx;
8358 tree c;
8359 hash_map<tree, tree> *struct_map_to_clause = NULL;
8360 hash_set<tree> *struct_deref_set = NULL;
8361 tree *prev_list_p = NULL, *orig_list_p = list_p;
8362 int handled_depend_iterators = -1;
8363 int nowait = -1;
8365 ctx = new_omp_context (region_type);
8366 ctx->code = code;
8367 outer_ctx = ctx->outer_context;
8368 if (code == OMP_TARGET)
8370 if (!lang_GNU_Fortran ())
8371 ctx->defaultmap[GDMK_POINTER] = GOVD_MAP | GOVD_MAP_0LEN_ARRAY;
8372 ctx->defaultmap[GDMK_SCALAR] = GOVD_FIRSTPRIVATE;
8374 if (!lang_GNU_Fortran ())
8375 switch (code)
8377 case OMP_TARGET:
8378 case OMP_TARGET_DATA:
8379 case OMP_TARGET_ENTER_DATA:
8380 case OMP_TARGET_EXIT_DATA:
8381 case OACC_DECLARE:
8382 case OACC_HOST_DATA:
8383 case OACC_PARALLEL:
8384 case OACC_KERNELS:
8385 ctx->target_firstprivatize_array_bases = true;
8386 default:
8387 break;
8390 while ((c = *list_p) != NULL)
8392 bool remove = false;
8393 bool notice_outer = true;
8394 const char *check_non_private = NULL;
8395 unsigned int flags;
8396 tree decl;
8398 switch (OMP_CLAUSE_CODE (c))
8400 case OMP_CLAUSE_PRIVATE:
8401 flags = GOVD_PRIVATE | GOVD_EXPLICIT;
8402 if (lang_hooks.decls.omp_private_outer_ref (OMP_CLAUSE_DECL (c)))
8404 flags |= GOVD_PRIVATE_OUTER_REF;
8405 OMP_CLAUSE_PRIVATE_OUTER_REF (c) = 1;
8407 else
8408 notice_outer = false;
8409 goto do_add;
8410 case OMP_CLAUSE_SHARED:
8411 flags = GOVD_SHARED | GOVD_EXPLICIT;
8412 goto do_add;
8413 case OMP_CLAUSE_FIRSTPRIVATE:
8414 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
8415 check_non_private = "firstprivate";
8416 goto do_add;
8417 case OMP_CLAUSE_LASTPRIVATE:
8418 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
8419 switch (code)
8421 case OMP_DISTRIBUTE:
8422 error_at (OMP_CLAUSE_LOCATION (c),
8423 "conditional %<lastprivate%> clause on "
8424 "%qs construct", "distribute");
8425 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
8426 break;
8427 case OMP_TASKLOOP:
8428 error_at (OMP_CLAUSE_LOCATION (c),
8429 "conditional %<lastprivate%> clause on "
8430 "%qs construct", "taskloop");
8431 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
8432 break;
8433 default:
8434 break;
8436 flags = GOVD_LASTPRIVATE | GOVD_SEEN | GOVD_EXPLICIT;
8437 if (code != OMP_LOOP)
8438 check_non_private = "lastprivate";
8439 decl = OMP_CLAUSE_DECL (c);
8440 if (error_operand_p (decl))
8441 goto do_add;
8442 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)
8443 && !lang_hooks.decls.omp_scalar_p (decl))
8445 error_at (OMP_CLAUSE_LOCATION (c),
8446 "non-scalar variable %qD in conditional "
8447 "%<lastprivate%> clause", decl);
8448 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
8450 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
8451 flags |= GOVD_LASTPRIVATE_CONDITIONAL;
8452 if (outer_ctx
8453 && (outer_ctx->region_type == ORT_COMBINED_PARALLEL
8454 || ((outer_ctx->region_type & ORT_COMBINED_TEAMS)
8455 == ORT_COMBINED_TEAMS))
8456 && splay_tree_lookup (outer_ctx->variables,
8457 (splay_tree_key) decl) == NULL)
8459 omp_add_variable (outer_ctx, decl, GOVD_SHARED | GOVD_SEEN);
8460 if (outer_ctx->outer_context)
8461 omp_notice_variable (outer_ctx->outer_context, decl, true);
8463 else if (outer_ctx
8464 && (outer_ctx->region_type & ORT_TASK) != 0
8465 && outer_ctx->combined_loop
8466 && splay_tree_lookup (outer_ctx->variables,
8467 (splay_tree_key) decl) == NULL)
8469 omp_add_variable (outer_ctx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
8470 if (outer_ctx->outer_context)
8471 omp_notice_variable (outer_ctx->outer_context, decl, true);
8473 else if (outer_ctx
8474 && (outer_ctx->region_type == ORT_WORKSHARE
8475 || outer_ctx->region_type == ORT_ACC)
8476 && outer_ctx->combined_loop
8477 && splay_tree_lookup (outer_ctx->variables,
8478 (splay_tree_key) decl) == NULL
8479 && !omp_check_private (outer_ctx, decl, false))
8481 omp_add_variable (outer_ctx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
8482 if (outer_ctx->outer_context
8483 && (outer_ctx->outer_context->region_type
8484 == ORT_COMBINED_PARALLEL)
8485 && splay_tree_lookup (outer_ctx->outer_context->variables,
8486 (splay_tree_key) decl) == NULL)
8488 struct gimplify_omp_ctx *octx = outer_ctx->outer_context;
8489 omp_add_variable (octx, decl, GOVD_SHARED | GOVD_SEEN);
8490 if (octx->outer_context)
8492 octx = octx->outer_context;
8493 if (octx->region_type == ORT_WORKSHARE
8494 && octx->combined_loop
8495 && splay_tree_lookup (octx->variables,
8496 (splay_tree_key) decl) == NULL
8497 && !omp_check_private (octx, decl, false))
8499 omp_add_variable (octx, decl,
8500 GOVD_LASTPRIVATE | GOVD_SEEN);
8501 octx = octx->outer_context;
8502 if (octx
8503 && ((octx->region_type & ORT_COMBINED_TEAMS)
8504 == ORT_COMBINED_TEAMS)
8505 && (splay_tree_lookup (octx->variables,
8506 (splay_tree_key) decl)
8507 == NULL))
8509 omp_add_variable (octx, decl,
8510 GOVD_SHARED | GOVD_SEEN);
8511 octx = octx->outer_context;
8514 if (octx)
8515 omp_notice_variable (octx, decl, true);
8518 else if (outer_ctx->outer_context)
8519 omp_notice_variable (outer_ctx->outer_context, decl, true);
8521 goto do_add;
8522 case OMP_CLAUSE_REDUCTION:
8523 if (OMP_CLAUSE_REDUCTION_TASK (c))
8525 if (region_type == ORT_WORKSHARE)
8527 if (nowait == -1)
8528 nowait = omp_find_clause (*list_p,
8529 OMP_CLAUSE_NOWAIT) != NULL_TREE;
8530 if (nowait
8531 && (outer_ctx == NULL
8532 || outer_ctx->region_type != ORT_COMBINED_PARALLEL))
8534 error_at (OMP_CLAUSE_LOCATION (c),
8535 "%<task%> reduction modifier on a construct "
8536 "with a %<nowait%> clause");
8537 OMP_CLAUSE_REDUCTION_TASK (c) = 0;
8540 else if ((region_type & ORT_PARALLEL) != ORT_PARALLEL)
8542 error_at (OMP_CLAUSE_LOCATION (c),
8543 "invalid %<task%> reduction modifier on construct "
8544 "other than %<parallel%>, %<for%> or %<sections%>");
8545 OMP_CLAUSE_REDUCTION_TASK (c) = 0;
8548 if (OMP_CLAUSE_REDUCTION_INSCAN (c))
8549 switch (code)
8551 case OMP_SECTIONS:
8552 error_at (OMP_CLAUSE_LOCATION (c),
8553 "%<inscan%> %<reduction%> clause on "
8554 "%qs construct", "sections");
8555 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
8556 break;
8557 case OMP_PARALLEL:
8558 error_at (OMP_CLAUSE_LOCATION (c),
8559 "%<inscan%> %<reduction%> clause on "
8560 "%qs construct", "parallel");
8561 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
8562 break;
8563 case OMP_TEAMS:
8564 error_at (OMP_CLAUSE_LOCATION (c),
8565 "%<inscan%> %<reduction%> clause on "
8566 "%qs construct", "teams");
8567 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
8568 break;
8569 case OMP_TASKLOOP:
8570 error_at (OMP_CLAUSE_LOCATION (c),
8571 "%<inscan%> %<reduction%> clause on "
8572 "%qs construct", "taskloop");
8573 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
8574 break;
8575 default:
8576 break;
8578 /* FALLTHRU */
8579 case OMP_CLAUSE_IN_REDUCTION:
8580 case OMP_CLAUSE_TASK_REDUCTION:
8581 flags = GOVD_REDUCTION | GOVD_SEEN | GOVD_EXPLICIT;
8582 /* OpenACC permits reductions on private variables. */
8583 if (!(region_type & ORT_ACC)
8584 /* taskgroup is actually not a worksharing region. */
8585 && code != OMP_TASKGROUP)
8586 check_non_private = omp_clause_code_name[OMP_CLAUSE_CODE (c)];
8587 decl = OMP_CLAUSE_DECL (c);
8588 if (TREE_CODE (decl) == MEM_REF)
8590 tree type = TREE_TYPE (decl);
8591 if (gimplify_expr (&TYPE_MAX_VALUE (TYPE_DOMAIN (type)), pre_p,
8592 NULL, is_gimple_val, fb_rvalue, false)
8593 == GS_ERROR)
8595 remove = true;
8596 break;
8598 tree v = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
8599 if (DECL_P (v))
8601 omp_firstprivatize_variable (ctx, v);
8602 omp_notice_variable (ctx, v, true);
8604 decl = TREE_OPERAND (decl, 0);
8605 if (TREE_CODE (decl) == POINTER_PLUS_EXPR)
8607 if (gimplify_expr (&TREE_OPERAND (decl, 1), pre_p,
8608 NULL, is_gimple_val, fb_rvalue, false)
8609 == GS_ERROR)
8611 remove = true;
8612 break;
8614 v = TREE_OPERAND (decl, 1);
8615 if (DECL_P (v))
8617 omp_firstprivatize_variable (ctx, v);
8618 omp_notice_variable (ctx, v, true);
8620 decl = TREE_OPERAND (decl, 0);
8622 if (TREE_CODE (decl) == ADDR_EXPR
8623 || TREE_CODE (decl) == INDIRECT_REF)
8624 decl = TREE_OPERAND (decl, 0);
8626 goto do_add_decl;
8627 case OMP_CLAUSE_LINEAR:
8628 if (gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c), pre_p, NULL,
8629 is_gimple_val, fb_rvalue) == GS_ERROR)
8631 remove = true;
8632 break;
8634 else
8636 if (code == OMP_SIMD
8637 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
8639 struct gimplify_omp_ctx *octx = outer_ctx;
8640 if (octx
8641 && octx->region_type == ORT_WORKSHARE
8642 && octx->combined_loop
8643 && !octx->distribute)
8645 if (octx->outer_context
8646 && (octx->outer_context->region_type
8647 == ORT_COMBINED_PARALLEL))
8648 octx = octx->outer_context->outer_context;
8649 else
8650 octx = octx->outer_context;
8652 if (octx
8653 && octx->region_type == ORT_WORKSHARE
8654 && octx->combined_loop
8655 && octx->distribute)
8657 error_at (OMP_CLAUSE_LOCATION (c),
8658 "%<linear%> clause for variable other than "
8659 "loop iterator specified on construct "
8660 "combined with %<distribute%>");
8661 remove = true;
8662 break;
8665 /* For combined #pragma omp parallel for simd, need to put
8666 lastprivate and perhaps firstprivate too on the
8667 parallel. Similarly for #pragma omp for simd. */
8668 struct gimplify_omp_ctx *octx = outer_ctx;
8669 decl = NULL_TREE;
8672 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
8673 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
8674 break;
8675 decl = OMP_CLAUSE_DECL (c);
8676 if (error_operand_p (decl))
8678 decl = NULL_TREE;
8679 break;
8681 flags = GOVD_SEEN;
8682 if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c))
8683 flags |= GOVD_FIRSTPRIVATE;
8684 if (!OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
8685 flags |= GOVD_LASTPRIVATE;
8686 if (octx
8687 && octx->region_type == ORT_WORKSHARE
8688 && octx->combined_loop)
8690 if (octx->outer_context
8691 && (octx->outer_context->region_type
8692 == ORT_COMBINED_PARALLEL))
8693 octx = octx->outer_context;
8694 else if (omp_check_private (octx, decl, false))
8695 break;
8697 else if (octx
8698 && (octx->region_type & ORT_TASK) != 0
8699 && octx->combined_loop)
8701 else if (octx
8702 && octx->region_type == ORT_COMBINED_PARALLEL
8703 && ctx->region_type == ORT_WORKSHARE
8704 && octx == outer_ctx)
8705 flags = GOVD_SEEN | GOVD_SHARED;
8706 else if (octx
8707 && ((octx->region_type & ORT_COMBINED_TEAMS)
8708 == ORT_COMBINED_TEAMS))
8709 flags = GOVD_SEEN | GOVD_SHARED;
8710 else if (octx
8711 && octx->region_type == ORT_COMBINED_TARGET)
8713 flags &= ~GOVD_LASTPRIVATE;
8714 if (flags == GOVD_SEEN)
8715 break;
8717 else
8718 break;
8719 splay_tree_node on
8720 = splay_tree_lookup (octx->variables,
8721 (splay_tree_key) decl);
8722 if (on && (on->value & GOVD_DATA_SHARE_CLASS) != 0)
8724 octx = NULL;
8725 break;
8727 omp_add_variable (octx, decl, flags);
8728 if (octx->outer_context == NULL)
8729 break;
8730 octx = octx->outer_context;
8732 while (1);
8733 if (octx
8734 && decl
8735 && (!OMP_CLAUSE_LINEAR_NO_COPYIN (c)
8736 || !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
8737 omp_notice_variable (octx, decl, true);
8739 flags = GOVD_LINEAR | GOVD_EXPLICIT;
8740 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
8741 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
8743 notice_outer = false;
8744 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
8746 goto do_add;
8748 case OMP_CLAUSE_MAP:
8749 decl = OMP_CLAUSE_DECL (c);
8750 if (error_operand_p (decl))
8751 remove = true;
8752 switch (code)
8754 case OMP_TARGET:
8755 break;
8756 case OACC_DATA:
8757 if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
8758 break;
8759 /* FALLTHRU */
8760 case OMP_TARGET_DATA:
8761 case OMP_TARGET_ENTER_DATA:
8762 case OMP_TARGET_EXIT_DATA:
8763 case OACC_HOST_DATA:
8764 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
8765 || (OMP_CLAUSE_MAP_KIND (c)
8766 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
8767 /* For target {,enter ,exit }data only the array slice is
8768 mapped, but not the pointer to it. */
8769 remove = true;
8770 break;
8771 case OACC_ENTER_DATA:
8772 case OACC_EXIT_DATA:
8773 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
8774 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_TO_PSET
8775 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
8776 || (OMP_CLAUSE_MAP_KIND (c)
8777 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
8778 remove = true;
8779 break;
8780 default:
8781 break;
8783 /* For Fortran, not only the pointer to the data is mapped but also
8784 the address of the pointer, the array descriptor etc.; for
8785 'exit data' - and in particular for 'delete:' - having an 'alloc:'
8786 does not make sense. Likewise, for 'update' only transferring the
8787 data itself is needed as the rest has been handled in previous
8788 directives. However, for 'exit data', the array descriptor needs
8789 to be delete; hence, we turn the MAP_TO_PSET into a MAP_DELETE. */
8790 if (code == OMP_TARGET_EXIT_DATA
8791 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_TO_PSET)
8792 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_DELETE);
8793 else if ((code == OMP_TARGET_EXIT_DATA || code == OMP_TARGET_UPDATE)
8794 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
8795 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_TO_PSET))
8796 remove = true;
8798 if (remove)
8799 break;
8800 if (DECL_P (decl) && outer_ctx && (region_type & ORT_ACC))
8802 struct gimplify_omp_ctx *octx;
8803 for (octx = outer_ctx; octx; octx = octx->outer_context)
8805 if (octx->region_type != ORT_ACC_HOST_DATA)
8806 break;
8807 splay_tree_node n2
8808 = splay_tree_lookup (octx->variables,
8809 (splay_tree_key) decl);
8810 if (n2)
8811 error_at (OMP_CLAUSE_LOCATION (c), "variable %qE "
8812 "declared in enclosing %<host_data%> region",
8813 DECL_NAME (decl));
8816 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
8817 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
8818 : TYPE_SIZE_UNIT (TREE_TYPE (decl));
8819 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
8820 NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
8822 remove = true;
8823 break;
8825 else if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
8826 || (OMP_CLAUSE_MAP_KIND (c)
8827 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
8828 && TREE_CODE (OMP_CLAUSE_SIZE (c)) != INTEGER_CST)
8830 OMP_CLAUSE_SIZE (c)
8831 = get_initialized_tmp_var (OMP_CLAUSE_SIZE (c), pre_p, NULL,
8832 false);
8833 omp_add_variable (ctx, OMP_CLAUSE_SIZE (c),
8834 GOVD_FIRSTPRIVATE | GOVD_SEEN);
8836 if (!DECL_P (decl))
8838 tree d = decl, *pd;
8839 if (TREE_CODE (d) == ARRAY_REF)
8841 while (TREE_CODE (d) == ARRAY_REF)
8842 d = TREE_OPERAND (d, 0);
8843 if (TREE_CODE (d) == COMPONENT_REF
8844 && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE)
8845 decl = d;
8847 pd = &OMP_CLAUSE_DECL (c);
8848 if (d == decl
8849 && TREE_CODE (decl) == INDIRECT_REF
8850 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
8851 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
8852 == REFERENCE_TYPE))
8854 pd = &TREE_OPERAND (decl, 0);
8855 decl = TREE_OPERAND (decl, 0);
8857 bool indir_p = false;
8858 tree orig_decl = decl;
8859 tree decl_ref = NULL_TREE;
8860 if ((region_type & ORT_ACC) != 0
8861 && TREE_CODE (*pd) == COMPONENT_REF
8862 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH
8863 && code != OACC_UPDATE)
8865 while (TREE_CODE (decl) == COMPONENT_REF)
8867 decl = TREE_OPERAND (decl, 0);
8868 if ((TREE_CODE (decl) == MEM_REF
8869 && integer_zerop (TREE_OPERAND (decl, 1)))
8870 || INDIRECT_REF_P (decl))
8872 indir_p = true;
8873 decl = TREE_OPERAND (decl, 0);
8875 if (TREE_CODE (decl) == INDIRECT_REF
8876 && DECL_P (TREE_OPERAND (decl, 0))
8877 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
8878 == REFERENCE_TYPE))
8880 decl_ref = decl;
8881 decl = TREE_OPERAND (decl, 0);
8885 else if (TREE_CODE (decl) == COMPONENT_REF)
8887 while (TREE_CODE (decl) == COMPONENT_REF)
8888 decl = TREE_OPERAND (decl, 0);
8889 if (TREE_CODE (decl) == INDIRECT_REF
8890 && DECL_P (TREE_OPERAND (decl, 0))
8891 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
8892 == REFERENCE_TYPE))
8893 decl = TREE_OPERAND (decl, 0);
8895 if (decl != orig_decl && DECL_P (decl) && indir_p)
8897 gomp_map_kind k = (code == OACC_EXIT_DATA) ? GOMP_MAP_DETACH
8898 : GOMP_MAP_ATTACH;
8899 /* We have a dereference of a struct member. Make this an
8900 attach/detach operation, and ensure the base pointer is
8901 mapped as a FIRSTPRIVATE_POINTER. */
8902 OMP_CLAUSE_SET_MAP_KIND (c, k);
8903 flags = GOVD_MAP | GOVD_SEEN | GOVD_EXPLICIT;
8904 tree next_clause = OMP_CLAUSE_CHAIN (c);
8905 if (k == GOMP_MAP_ATTACH
8906 && code != OACC_ENTER_DATA
8907 && (!next_clause
8908 || (OMP_CLAUSE_CODE (next_clause) != OMP_CLAUSE_MAP)
8909 || (OMP_CLAUSE_MAP_KIND (next_clause)
8910 != GOMP_MAP_POINTER)
8911 || OMP_CLAUSE_DECL (next_clause) != decl)
8912 && (!struct_deref_set
8913 || !struct_deref_set->contains (decl)))
8915 if (!struct_deref_set)
8916 struct_deref_set = new hash_set<tree> ();
8917 /* As well as the attach, we also need a
8918 FIRSTPRIVATE_POINTER clause to properly map the
8919 pointer to the struct base. */
8920 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
8921 OMP_CLAUSE_MAP);
8922 OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_ALLOC);
8923 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (c2)
8924 = 1;
8925 tree charptr_zero
8926 = build_int_cst (build_pointer_type (char_type_node),
8928 OMP_CLAUSE_DECL (c2)
8929 = build2 (MEM_REF, char_type_node,
8930 decl_ref ? decl_ref : decl, charptr_zero);
8931 OMP_CLAUSE_SIZE (c2) = size_zero_node;
8932 tree c3 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
8933 OMP_CLAUSE_MAP);
8934 OMP_CLAUSE_SET_MAP_KIND (c3,
8935 GOMP_MAP_FIRSTPRIVATE_POINTER);
8936 OMP_CLAUSE_DECL (c3) = decl;
8937 OMP_CLAUSE_SIZE (c3) = size_zero_node;
8938 tree mapgrp = *prev_list_p;
8939 *prev_list_p = c2;
8940 OMP_CLAUSE_CHAIN (c3) = mapgrp;
8941 OMP_CLAUSE_CHAIN (c2) = c3;
8943 struct_deref_set->add (decl);
8945 goto do_add_decl;
8947 /* An "attach/detach" operation on an update directive should
8948 behave as a GOMP_MAP_ALWAYS_POINTER. Beware that
8949 unlike attach or detach map kinds, GOMP_MAP_ALWAYS_POINTER
8950 depends on the previous mapping. */
8951 if (code == OACC_UPDATE
8952 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
8953 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_ALWAYS_POINTER);
8954 if (gimplify_expr (pd, pre_p, NULL, is_gimple_lvalue, fb_lvalue)
8955 == GS_ERROR)
8957 remove = true;
8958 break;
8960 if (DECL_P (decl)
8961 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_TO_PSET
8962 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH
8963 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_DETACH
8964 && code != OACC_UPDATE)
8966 if (error_operand_p (decl))
8968 remove = true;
8969 break;
8972 tree stype = TREE_TYPE (decl);
8973 if (TREE_CODE (stype) == REFERENCE_TYPE)
8974 stype = TREE_TYPE (stype);
8975 if (TYPE_SIZE_UNIT (stype) == NULL
8976 || TREE_CODE (TYPE_SIZE_UNIT (stype)) != INTEGER_CST)
8978 error_at (OMP_CLAUSE_LOCATION (c),
8979 "mapping field %qE of variable length "
8980 "structure", OMP_CLAUSE_DECL (c));
8981 remove = true;
8982 break;
8985 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER
8986 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
8988 /* Error recovery. */
8989 if (prev_list_p == NULL)
8991 remove = true;
8992 break;
8994 if (OMP_CLAUSE_CHAIN (*prev_list_p) != c)
8996 tree ch = OMP_CLAUSE_CHAIN (*prev_list_p);
8997 if (ch == NULL_TREE || OMP_CLAUSE_CHAIN (ch) != c)
8999 remove = true;
9000 break;
9005 poly_offset_int offset1;
9006 poly_int64 bitpos1;
9007 tree base_ref;
9009 tree base
9010 = extract_base_bit_offset (OMP_CLAUSE_DECL (c), &base_ref,
9011 &bitpos1, &offset1);
9013 gcc_assert (base == decl);
9015 splay_tree_node n
9016 = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
9017 bool ptr = (OMP_CLAUSE_MAP_KIND (c)
9018 == GOMP_MAP_ALWAYS_POINTER);
9019 bool attach_detach = (OMP_CLAUSE_MAP_KIND (c)
9020 == GOMP_MAP_ATTACH_DETACH);
9021 bool attach = OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
9022 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH;
9023 bool has_attachments = false;
9024 /* For OpenACC, pointers in structs should trigger an
9025 attach action. */
9026 if (attach_detach && (region_type & ORT_ACC) != 0)
9028 /* Turn a GOMP_MAP_ATTACH_DETACH clause into a
9029 GOMP_MAP_ATTACH or GOMP_MAP_DETACH clause after we
9030 have detected a case that needs a GOMP_MAP_STRUCT
9031 mapping added. */
9032 gomp_map_kind k
9033 = (code == OACC_EXIT_DATA) ? GOMP_MAP_DETACH
9034 : GOMP_MAP_ATTACH;
9035 OMP_CLAUSE_SET_MAP_KIND (c, k);
9036 has_attachments = true;
9038 if (n == NULL || (n->value & GOVD_MAP) == 0)
9040 tree l = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9041 OMP_CLAUSE_MAP);
9042 gomp_map_kind k = attach ? GOMP_MAP_FORCE_PRESENT
9043 : GOMP_MAP_STRUCT;
9045 OMP_CLAUSE_SET_MAP_KIND (l, k);
9046 if (base_ref)
9047 OMP_CLAUSE_DECL (l) = unshare_expr (base_ref);
9048 else
9049 OMP_CLAUSE_DECL (l) = decl;
9050 OMP_CLAUSE_SIZE (l)
9051 = (!attach
9052 ? size_int (1)
9053 : DECL_P (OMP_CLAUSE_DECL (l))
9054 ? DECL_SIZE_UNIT (OMP_CLAUSE_DECL (l))
9055 : TYPE_SIZE_UNIT (TREE_TYPE (OMP_CLAUSE_DECL (l))));
9056 if (struct_map_to_clause == NULL)
9057 struct_map_to_clause = new hash_map<tree, tree>;
9058 struct_map_to_clause->put (decl, l);
9059 if (ptr || attach_detach)
9061 insert_struct_comp_map (code, c, l, *prev_list_p,
9062 NULL);
9063 *prev_list_p = l;
9064 prev_list_p = NULL;
9066 else
9068 OMP_CLAUSE_CHAIN (l) = c;
9069 *list_p = l;
9070 list_p = &OMP_CLAUSE_CHAIN (l);
9072 if (base_ref && code == OMP_TARGET)
9074 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9075 OMP_CLAUSE_MAP);
9076 enum gomp_map_kind mkind
9077 = GOMP_MAP_FIRSTPRIVATE_REFERENCE;
9078 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
9079 OMP_CLAUSE_DECL (c2) = decl;
9080 OMP_CLAUSE_SIZE (c2) = size_zero_node;
9081 OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (l);
9082 OMP_CLAUSE_CHAIN (l) = c2;
9084 flags = GOVD_MAP | GOVD_EXPLICIT;
9085 if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c))
9086 || ptr
9087 || attach_detach)
9088 flags |= GOVD_SEEN;
9089 if (has_attachments)
9090 flags |= GOVD_MAP_HAS_ATTACHMENTS;
9091 goto do_add_decl;
9093 else if (struct_map_to_clause)
9095 tree *osc = struct_map_to_clause->get (decl);
9096 tree *sc = NULL, *scp = NULL;
9097 if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c))
9098 || ptr
9099 || attach_detach)
9100 n->value |= GOVD_SEEN;
9101 sc = &OMP_CLAUSE_CHAIN (*osc);
9102 if (*sc != c
9103 && (OMP_CLAUSE_MAP_KIND (*sc)
9104 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
9105 sc = &OMP_CLAUSE_CHAIN (*sc);
9106 /* Here "prev_list_p" is the end of the inserted
9107 alloc/release nodes after the struct node, OSC. */
9108 for (; *sc != c; sc = &OMP_CLAUSE_CHAIN (*sc))
9109 if ((ptr || attach_detach) && sc == prev_list_p)
9110 break;
9111 else if (TREE_CODE (OMP_CLAUSE_DECL (*sc))
9112 != COMPONENT_REF
9113 && (TREE_CODE (OMP_CLAUSE_DECL (*sc))
9114 != INDIRECT_REF)
9115 && (TREE_CODE (OMP_CLAUSE_DECL (*sc))
9116 != ARRAY_REF))
9117 break;
9118 else
9120 tree sc_decl = OMP_CLAUSE_DECL (*sc);
9121 poly_offset_int offsetn;
9122 poly_int64 bitposn;
9123 tree base
9124 = extract_base_bit_offset (sc_decl, NULL,
9125 &bitposn, &offsetn);
9126 if (base != decl)
9127 break;
9128 if (scp)
9129 continue;
9130 tree d1 = OMP_CLAUSE_DECL (*sc);
9131 tree d2 = OMP_CLAUSE_DECL (c);
9132 while (TREE_CODE (d1) == ARRAY_REF)
9133 d1 = TREE_OPERAND (d1, 0);
9134 while (TREE_CODE (d2) == ARRAY_REF)
9135 d2 = TREE_OPERAND (d2, 0);
9136 if (TREE_CODE (d1) == INDIRECT_REF)
9137 d1 = TREE_OPERAND (d1, 0);
9138 if (TREE_CODE (d2) == INDIRECT_REF)
9139 d2 = TREE_OPERAND (d2, 0);
9140 while (TREE_CODE (d1) == COMPONENT_REF)
9141 if (TREE_CODE (d2) == COMPONENT_REF
9142 && TREE_OPERAND (d1, 1)
9143 == TREE_OPERAND (d2, 1))
9145 d1 = TREE_OPERAND (d1, 0);
9146 d2 = TREE_OPERAND (d2, 0);
9148 else
9149 break;
9150 if (d1 == d2)
9152 error_at (OMP_CLAUSE_LOCATION (c),
9153 "%qE appears more than once in map "
9154 "clauses", OMP_CLAUSE_DECL (c));
9155 remove = true;
9156 break;
9158 if (maybe_lt (offset1, offsetn)
9159 || (known_eq (offset1, offsetn)
9160 && maybe_lt (bitpos1, bitposn)))
9162 if (ptr || attach_detach)
9163 scp = sc;
9164 else
9165 break;
9168 if (remove)
9169 break;
9170 if (!attach)
9171 OMP_CLAUSE_SIZE (*osc)
9172 = size_binop (PLUS_EXPR, OMP_CLAUSE_SIZE (*osc),
9173 size_one_node);
9174 if (ptr || attach_detach)
9176 tree cl = insert_struct_comp_map (code, c, NULL,
9177 *prev_list_p, scp);
9178 if (sc == prev_list_p)
9180 *sc = cl;
9181 prev_list_p = NULL;
9183 else
9185 *prev_list_p = OMP_CLAUSE_CHAIN (c);
9186 list_p = prev_list_p;
9187 prev_list_p = NULL;
9188 OMP_CLAUSE_CHAIN (c) = *sc;
9189 *sc = cl;
9190 continue;
9193 else if (*sc != c)
9195 *list_p = OMP_CLAUSE_CHAIN (c);
9196 OMP_CLAUSE_CHAIN (c) = *sc;
9197 *sc = c;
9198 continue;
9202 if (!remove
9203 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_POINTER
9204 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH_DETACH
9205 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_TO_PSET
9206 && OMP_CLAUSE_CHAIN (c)
9207 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (c)) == OMP_CLAUSE_MAP
9208 && ((OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
9209 == GOMP_MAP_ALWAYS_POINTER)
9210 || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
9211 == GOMP_MAP_ATTACH_DETACH)
9212 || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
9213 == GOMP_MAP_TO_PSET)))
9214 prev_list_p = list_p;
9216 break;
9218 flags = GOVD_MAP | GOVD_EXPLICIT;
9219 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TO
9220 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TOFROM)
9221 flags |= GOVD_MAP_ALWAYS_TO;
9222 goto do_add;
9224 case OMP_CLAUSE_DEPEND:
9225 if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
9227 tree deps = OMP_CLAUSE_DECL (c);
9228 while (deps && TREE_CODE (deps) == TREE_LIST)
9230 if (TREE_CODE (TREE_PURPOSE (deps)) == TRUNC_DIV_EXPR
9231 && DECL_P (TREE_OPERAND (TREE_PURPOSE (deps), 1)))
9232 gimplify_expr (&TREE_OPERAND (TREE_PURPOSE (deps), 1),
9233 pre_p, NULL, is_gimple_val, fb_rvalue);
9234 deps = TREE_CHAIN (deps);
9236 break;
9238 else if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
9239 break;
9240 if (handled_depend_iterators == -1)
9241 handled_depend_iterators = gimplify_omp_depend (list_p, pre_p);
9242 if (handled_depend_iterators)
9244 if (handled_depend_iterators == 2)
9245 remove = true;
9246 break;
9248 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
9250 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
9251 NULL, is_gimple_val, fb_rvalue);
9252 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
9254 if (error_operand_p (OMP_CLAUSE_DECL (c)))
9256 remove = true;
9257 break;
9259 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
9260 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
9261 is_gimple_val, fb_rvalue) == GS_ERROR)
9263 remove = true;
9264 break;
9266 break;
9268 case OMP_CLAUSE_TO:
9269 case OMP_CLAUSE_FROM:
9270 case OMP_CLAUSE__CACHE_:
9271 decl = OMP_CLAUSE_DECL (c);
9272 if (error_operand_p (decl))
9274 remove = true;
9275 break;
9277 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
9278 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
9279 : TYPE_SIZE_UNIT (TREE_TYPE (decl));
9280 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
9281 NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
9283 remove = true;
9284 break;
9286 if (!DECL_P (decl))
9288 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p,
9289 NULL, is_gimple_lvalue, fb_lvalue)
9290 == GS_ERROR)
9292 remove = true;
9293 break;
9295 break;
9297 goto do_notice;
9299 case OMP_CLAUSE_USE_DEVICE_PTR:
9300 case OMP_CLAUSE_USE_DEVICE_ADDR:
9301 flags = GOVD_EXPLICIT;
9302 goto do_add;
9304 case OMP_CLAUSE_IS_DEVICE_PTR:
9305 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
9306 goto do_add;
9308 do_add:
9309 decl = OMP_CLAUSE_DECL (c);
9310 do_add_decl:
9311 if (error_operand_p (decl))
9313 remove = true;
9314 break;
9316 if (DECL_NAME (decl) == NULL_TREE && (flags & GOVD_SHARED) == 0)
9318 tree t = omp_member_access_dummy_var (decl);
9319 if (t)
9321 tree v = DECL_VALUE_EXPR (decl);
9322 DECL_NAME (decl) = DECL_NAME (TREE_OPERAND (v, 1));
9323 if (outer_ctx)
9324 omp_notice_variable (outer_ctx, t, true);
9327 if (code == OACC_DATA
9328 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9329 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
9330 flags |= GOVD_MAP_0LEN_ARRAY;
9331 omp_add_variable (ctx, decl, flags);
9332 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
9333 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
9334 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
9335 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
9337 omp_add_variable (ctx, OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
9338 GOVD_LOCAL | GOVD_SEEN);
9339 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
9340 && walk_tree (&OMP_CLAUSE_REDUCTION_INIT (c),
9341 find_decl_expr,
9342 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
9343 NULL) == NULL_TREE)
9344 omp_add_variable (ctx,
9345 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
9346 GOVD_LOCAL | GOVD_SEEN);
9347 gimplify_omp_ctxp = ctx;
9348 push_gimplify_context ();
9350 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
9351 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
9353 gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c),
9354 &OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c));
9355 pop_gimplify_context
9356 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c)));
9357 push_gimplify_context ();
9358 gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c),
9359 &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
9360 pop_gimplify_context
9361 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c)));
9362 OMP_CLAUSE_REDUCTION_INIT (c) = NULL_TREE;
9363 OMP_CLAUSE_REDUCTION_MERGE (c) = NULL_TREE;
9365 gimplify_omp_ctxp = outer_ctx;
9367 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
9368 && OMP_CLAUSE_LASTPRIVATE_STMT (c))
9370 gimplify_omp_ctxp = ctx;
9371 push_gimplify_context ();
9372 if (TREE_CODE (OMP_CLAUSE_LASTPRIVATE_STMT (c)) != BIND_EXPR)
9374 tree bind = build3 (BIND_EXPR, void_type_node, NULL,
9375 NULL, NULL);
9376 TREE_SIDE_EFFECTS (bind) = 1;
9377 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LASTPRIVATE_STMT (c);
9378 OMP_CLAUSE_LASTPRIVATE_STMT (c) = bind;
9380 gimplify_and_add (OMP_CLAUSE_LASTPRIVATE_STMT (c),
9381 &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
9382 pop_gimplify_context
9383 (gimple_seq_first_stmt (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c)));
9384 OMP_CLAUSE_LASTPRIVATE_STMT (c) = NULL_TREE;
9386 gimplify_omp_ctxp = outer_ctx;
9388 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
9389 && OMP_CLAUSE_LINEAR_STMT (c))
9391 gimplify_omp_ctxp = ctx;
9392 push_gimplify_context ();
9393 if (TREE_CODE (OMP_CLAUSE_LINEAR_STMT (c)) != BIND_EXPR)
9395 tree bind = build3 (BIND_EXPR, void_type_node, NULL,
9396 NULL, NULL);
9397 TREE_SIDE_EFFECTS (bind) = 1;
9398 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LINEAR_STMT (c);
9399 OMP_CLAUSE_LINEAR_STMT (c) = bind;
9401 gimplify_and_add (OMP_CLAUSE_LINEAR_STMT (c),
9402 &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c));
9403 pop_gimplify_context
9404 (gimple_seq_first_stmt (OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c)));
9405 OMP_CLAUSE_LINEAR_STMT (c) = NULL_TREE;
9407 gimplify_omp_ctxp = outer_ctx;
9409 if (notice_outer)
9410 goto do_notice;
9411 break;
9413 case OMP_CLAUSE_COPYIN:
9414 case OMP_CLAUSE_COPYPRIVATE:
9415 decl = OMP_CLAUSE_DECL (c);
9416 if (error_operand_p (decl))
9418 remove = true;
9419 break;
9421 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_COPYPRIVATE
9422 && !remove
9423 && !omp_check_private (ctx, decl, true))
9425 remove = true;
9426 if (is_global_var (decl))
9428 if (DECL_THREAD_LOCAL_P (decl))
9429 remove = false;
9430 else if (DECL_HAS_VALUE_EXPR_P (decl))
9432 tree value = get_base_address (DECL_VALUE_EXPR (decl));
9434 if (value
9435 && DECL_P (value)
9436 && DECL_THREAD_LOCAL_P (value))
9437 remove = false;
9440 if (remove)
9441 error_at (OMP_CLAUSE_LOCATION (c),
9442 "copyprivate variable %qE is not threadprivate"
9443 " or private in outer context", DECL_NAME (decl));
9445 do_notice:
9446 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
9447 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
9448 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
9449 && outer_ctx
9450 && ((region_type & ORT_TASKLOOP) == ORT_TASKLOOP
9451 || (region_type == ORT_WORKSHARE
9452 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
9453 && (OMP_CLAUSE_REDUCTION_INSCAN (c)
9454 || code == OMP_LOOP)))
9455 && (outer_ctx->region_type == ORT_COMBINED_PARALLEL
9456 || (code == OMP_LOOP
9457 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
9458 && ((outer_ctx->region_type & ORT_COMBINED_TEAMS)
9459 == ORT_COMBINED_TEAMS))))
9461 splay_tree_node on
9462 = splay_tree_lookup (outer_ctx->variables,
9463 (splay_tree_key)decl);
9464 if (on == NULL || (on->value & GOVD_DATA_SHARE_CLASS) == 0)
9466 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
9467 && TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
9468 && (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
9469 || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
9470 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
9471 == POINTER_TYPE))))
9472 omp_firstprivatize_variable (outer_ctx, decl);
9473 else
9475 omp_add_variable (outer_ctx, decl,
9476 GOVD_SEEN | GOVD_SHARED);
9477 if (outer_ctx->outer_context)
9478 omp_notice_variable (outer_ctx->outer_context, decl,
9479 true);
9483 if (outer_ctx)
9484 omp_notice_variable (outer_ctx, decl, true);
9485 if (check_non_private
9486 && region_type == ORT_WORKSHARE
9487 && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
9488 || decl == OMP_CLAUSE_DECL (c)
9489 || (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
9490 && (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
9491 == ADDR_EXPR
9492 || (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
9493 == POINTER_PLUS_EXPR
9494 && (TREE_CODE (TREE_OPERAND (TREE_OPERAND
9495 (OMP_CLAUSE_DECL (c), 0), 0))
9496 == ADDR_EXPR)))))
9497 && omp_check_private (ctx, decl, false))
9499 error ("%s variable %qE is private in outer context",
9500 check_non_private, DECL_NAME (decl));
9501 remove = true;
9503 break;
9505 case OMP_CLAUSE_IF:
9506 if (OMP_CLAUSE_IF_MODIFIER (c) != ERROR_MARK
9507 && OMP_CLAUSE_IF_MODIFIER (c) != code)
9509 const char *p[2];
9510 for (int i = 0; i < 2; i++)
9511 switch (i ? OMP_CLAUSE_IF_MODIFIER (c) : code)
9513 case VOID_CST: p[i] = "cancel"; break;
9514 case OMP_PARALLEL: p[i] = "parallel"; break;
9515 case OMP_SIMD: p[i] = "simd"; break;
9516 case OMP_TASK: p[i] = "task"; break;
9517 case OMP_TASKLOOP: p[i] = "taskloop"; break;
9518 case OMP_TARGET_DATA: p[i] = "target data"; break;
9519 case OMP_TARGET: p[i] = "target"; break;
9520 case OMP_TARGET_UPDATE: p[i] = "target update"; break;
9521 case OMP_TARGET_ENTER_DATA:
9522 p[i] = "target enter data"; break;
9523 case OMP_TARGET_EXIT_DATA: p[i] = "target exit data"; break;
9524 default: gcc_unreachable ();
9526 error_at (OMP_CLAUSE_LOCATION (c),
9527 "expected %qs %<if%> clause modifier rather than %qs",
9528 p[0], p[1]);
9529 remove = true;
9531 /* Fall through. */
9533 case OMP_CLAUSE_FINAL:
9534 OMP_CLAUSE_OPERAND (c, 0)
9535 = gimple_boolify (OMP_CLAUSE_OPERAND (c, 0));
9536 /* Fall through. */
9538 case OMP_CLAUSE_SCHEDULE:
9539 case OMP_CLAUSE_NUM_THREADS:
9540 case OMP_CLAUSE_NUM_TEAMS:
9541 case OMP_CLAUSE_THREAD_LIMIT:
9542 case OMP_CLAUSE_DIST_SCHEDULE:
9543 case OMP_CLAUSE_DEVICE:
9544 case OMP_CLAUSE_PRIORITY:
9545 case OMP_CLAUSE_GRAINSIZE:
9546 case OMP_CLAUSE_NUM_TASKS:
9547 case OMP_CLAUSE_HINT:
9548 case OMP_CLAUSE_ASYNC:
9549 case OMP_CLAUSE_WAIT:
9550 case OMP_CLAUSE_NUM_GANGS:
9551 case OMP_CLAUSE_NUM_WORKERS:
9552 case OMP_CLAUSE_VECTOR_LENGTH:
9553 case OMP_CLAUSE_WORKER:
9554 case OMP_CLAUSE_VECTOR:
9555 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
9556 is_gimple_val, fb_rvalue) == GS_ERROR)
9557 remove = true;
9558 break;
9560 case OMP_CLAUSE_GANG:
9561 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
9562 is_gimple_val, fb_rvalue) == GS_ERROR)
9563 remove = true;
9564 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 1), pre_p, NULL,
9565 is_gimple_val, fb_rvalue) == GS_ERROR)
9566 remove = true;
9567 break;
9569 case OMP_CLAUSE_NOWAIT:
9570 nowait = 1;
9571 break;
9573 case OMP_CLAUSE_ORDERED:
9574 case OMP_CLAUSE_UNTIED:
9575 case OMP_CLAUSE_COLLAPSE:
9576 case OMP_CLAUSE_TILE:
9577 case OMP_CLAUSE_AUTO:
9578 case OMP_CLAUSE_SEQ:
9579 case OMP_CLAUSE_INDEPENDENT:
9580 case OMP_CLAUSE_MERGEABLE:
9581 case OMP_CLAUSE_PROC_BIND:
9582 case OMP_CLAUSE_SAFELEN:
9583 case OMP_CLAUSE_SIMDLEN:
9584 case OMP_CLAUSE_NOGROUP:
9585 case OMP_CLAUSE_THREADS:
9586 case OMP_CLAUSE_SIMD:
9587 case OMP_CLAUSE_BIND:
9588 case OMP_CLAUSE_IF_PRESENT:
9589 case OMP_CLAUSE_FINALIZE:
9590 break;
9592 case OMP_CLAUSE_ORDER:
9593 ctx->order_concurrent = true;
9594 break;
9596 case OMP_CLAUSE_DEFAULTMAP:
9597 enum gimplify_defaultmap_kind gdmkmin, gdmkmax;
9598 switch (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c))
9600 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
9601 gdmkmin = GDMK_SCALAR;
9602 gdmkmax = GDMK_POINTER;
9603 break;
9604 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
9605 gdmkmin = gdmkmax = GDMK_SCALAR;
9606 break;
9607 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
9608 gdmkmin = gdmkmax = GDMK_AGGREGATE;
9609 break;
9610 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALLOCATABLE:
9611 gdmkmin = gdmkmax = GDMK_ALLOCATABLE;
9612 break;
9613 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
9614 gdmkmin = gdmkmax = GDMK_POINTER;
9615 break;
9616 default:
9617 gcc_unreachable ();
9619 for (int gdmk = gdmkmin; gdmk <= gdmkmax; gdmk++)
9620 switch (OMP_CLAUSE_DEFAULTMAP_BEHAVIOR (c))
9622 case OMP_CLAUSE_DEFAULTMAP_ALLOC:
9623 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_ALLOC_ONLY;
9624 break;
9625 case OMP_CLAUSE_DEFAULTMAP_TO:
9626 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_TO_ONLY;
9627 break;
9628 case OMP_CLAUSE_DEFAULTMAP_FROM:
9629 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_FROM_ONLY;
9630 break;
9631 case OMP_CLAUSE_DEFAULTMAP_TOFROM:
9632 ctx->defaultmap[gdmk] = GOVD_MAP;
9633 break;
9634 case OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE:
9635 ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE;
9636 break;
9637 case OMP_CLAUSE_DEFAULTMAP_NONE:
9638 ctx->defaultmap[gdmk] = 0;
9639 break;
9640 case OMP_CLAUSE_DEFAULTMAP_DEFAULT:
9641 switch (gdmk)
9643 case GDMK_SCALAR:
9644 ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE;
9645 break;
9646 case GDMK_AGGREGATE:
9647 case GDMK_ALLOCATABLE:
9648 ctx->defaultmap[gdmk] = GOVD_MAP;
9649 break;
9650 case GDMK_POINTER:
9651 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_0LEN_ARRAY;
9652 break;
9653 default:
9654 gcc_unreachable ();
9656 break;
9657 default:
9658 gcc_unreachable ();
9660 break;
9662 case OMP_CLAUSE_ALIGNED:
9663 decl = OMP_CLAUSE_DECL (c);
9664 if (error_operand_p (decl))
9666 remove = true;
9667 break;
9669 if (gimplify_expr (&OMP_CLAUSE_ALIGNED_ALIGNMENT (c), pre_p, NULL,
9670 is_gimple_val, fb_rvalue) == GS_ERROR)
9672 remove = true;
9673 break;
9675 if (!is_global_var (decl)
9676 && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
9677 omp_add_variable (ctx, decl, GOVD_ALIGNED);
9678 break;
9680 case OMP_CLAUSE_NONTEMPORAL:
9681 decl = OMP_CLAUSE_DECL (c);
9682 if (error_operand_p (decl))
9684 remove = true;
9685 break;
9687 omp_add_variable (ctx, decl, GOVD_NONTEMPORAL);
9688 break;
9690 case OMP_CLAUSE_DEFAULT:
9691 ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
9692 break;
9694 case OMP_CLAUSE_INCLUSIVE:
9695 case OMP_CLAUSE_EXCLUSIVE:
9696 decl = OMP_CLAUSE_DECL (c);
9698 splay_tree_node n = splay_tree_lookup (outer_ctx->variables,
9699 (splay_tree_key) decl);
9700 if (n == NULL || (n->value & GOVD_REDUCTION) == 0)
9702 error_at (OMP_CLAUSE_LOCATION (c),
9703 "%qD specified in %qs clause but not in %<inscan%> "
9704 "%<reduction%> clause on the containing construct",
9705 decl, omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
9706 remove = true;
9708 else
9710 n->value |= GOVD_REDUCTION_INSCAN;
9711 if (outer_ctx->region_type == ORT_SIMD
9712 && outer_ctx->outer_context
9713 && outer_ctx->outer_context->region_type == ORT_WORKSHARE)
9715 n = splay_tree_lookup (outer_ctx->outer_context->variables,
9716 (splay_tree_key) decl);
9717 if (n && (n->value & GOVD_REDUCTION) != 0)
9718 n->value |= GOVD_REDUCTION_INSCAN;
9722 break;
9724 default:
9725 gcc_unreachable ();
9728 if (code == OACC_DATA
9729 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9730 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
9731 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
9732 remove = true;
9733 if (remove)
9734 *list_p = OMP_CLAUSE_CHAIN (c);
9735 else
9736 list_p = &OMP_CLAUSE_CHAIN (c);
9739 ctx->clauses = *orig_list_p;
9740 gimplify_omp_ctxp = ctx;
9741 if (struct_map_to_clause)
9742 delete struct_map_to_clause;
9743 if (struct_deref_set)
9744 delete struct_deref_set;
9747 /* Return true if DECL is a candidate for shared to firstprivate
9748 optimization. We only consider non-addressable scalars, not
9749 too big, and not references. */
9751 static bool
9752 omp_shared_to_firstprivate_optimizable_decl_p (tree decl)
9754 if (TREE_ADDRESSABLE (decl))
9755 return false;
9756 tree type = TREE_TYPE (decl);
9757 if (!is_gimple_reg_type (type)
9758 || TREE_CODE (type) == REFERENCE_TYPE
9759 || TREE_ADDRESSABLE (type))
9760 return false;
9761 /* Don't optimize too large decls, as each thread/task will have
9762 its own. */
9763 HOST_WIDE_INT len = int_size_in_bytes (type);
9764 if (len == -1 || len > 4 * POINTER_SIZE / BITS_PER_UNIT)
9765 return false;
9766 if (lang_hooks.decls.omp_privatize_by_reference (decl))
9767 return false;
9768 return true;
9771 /* Helper function of omp_find_stores_op and gimplify_adjust_omp_clauses*.
9772 For omp_shared_to_firstprivate_optimizable_decl_p decl mark it as
9773 GOVD_WRITTEN in outer contexts. */
9775 static void
9776 omp_mark_stores (struct gimplify_omp_ctx *ctx, tree decl)
9778 for (; ctx; ctx = ctx->outer_context)
9780 splay_tree_node n = splay_tree_lookup (ctx->variables,
9781 (splay_tree_key) decl);
9782 if (n == NULL)
9783 continue;
9784 else if (n->value & GOVD_SHARED)
9786 n->value |= GOVD_WRITTEN;
9787 return;
9789 else if (n->value & GOVD_DATA_SHARE_CLASS)
9790 return;
9794 /* Helper callback for walk_gimple_seq to discover possible stores
9795 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
9796 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
9797 for those. */
9799 static tree
9800 omp_find_stores_op (tree *tp, int *walk_subtrees, void *data)
9802 struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
9804 *walk_subtrees = 0;
9805 if (!wi->is_lhs)
9806 return NULL_TREE;
9808 tree op = *tp;
9811 if (handled_component_p (op))
9812 op = TREE_OPERAND (op, 0);
9813 else if ((TREE_CODE (op) == MEM_REF || TREE_CODE (op) == TARGET_MEM_REF)
9814 && TREE_CODE (TREE_OPERAND (op, 0)) == ADDR_EXPR)
9815 op = TREE_OPERAND (TREE_OPERAND (op, 0), 0);
9816 else
9817 break;
9819 while (1);
9820 if (!DECL_P (op) || !omp_shared_to_firstprivate_optimizable_decl_p (op))
9821 return NULL_TREE;
9823 omp_mark_stores (gimplify_omp_ctxp, op);
9824 return NULL_TREE;
9827 /* Helper callback for walk_gimple_seq to discover possible stores
9828 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
9829 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
9830 for those. */
9832 static tree
9833 omp_find_stores_stmt (gimple_stmt_iterator *gsi_p,
9834 bool *handled_ops_p,
9835 struct walk_stmt_info *wi)
9837 gimple *stmt = gsi_stmt (*gsi_p);
9838 switch (gimple_code (stmt))
9840 /* Don't recurse on OpenMP constructs for which
9841 gimplify_adjust_omp_clauses already handled the bodies,
9842 except handle gimple_omp_for_pre_body. */
9843 case GIMPLE_OMP_FOR:
9844 *handled_ops_p = true;
9845 if (gimple_omp_for_pre_body (stmt))
9846 walk_gimple_seq (gimple_omp_for_pre_body (stmt),
9847 omp_find_stores_stmt, omp_find_stores_op, wi);
9848 break;
9849 case GIMPLE_OMP_PARALLEL:
9850 case GIMPLE_OMP_TASK:
9851 case GIMPLE_OMP_SECTIONS:
9852 case GIMPLE_OMP_SINGLE:
9853 case GIMPLE_OMP_TARGET:
9854 case GIMPLE_OMP_TEAMS:
9855 case GIMPLE_OMP_CRITICAL:
9856 *handled_ops_p = true;
9857 break;
9858 default:
9859 break;
9861 return NULL_TREE;
9864 struct gimplify_adjust_omp_clauses_data
9866 tree *list_p;
9867 gimple_seq *pre_p;
9870 /* For all variables that were not actually used within the context,
9871 remove PRIVATE, SHARED, and FIRSTPRIVATE clauses. */
9873 static int
9874 gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
9876 tree *list_p = ((struct gimplify_adjust_omp_clauses_data *) data)->list_p;
9877 gimple_seq *pre_p
9878 = ((struct gimplify_adjust_omp_clauses_data *) data)->pre_p;
9879 tree decl = (tree) n->key;
9880 unsigned flags = n->value;
9881 enum omp_clause_code code;
9882 tree clause;
9883 bool private_debug;
9885 if (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
9886 && (flags & GOVD_LASTPRIVATE_CONDITIONAL) != 0)
9887 flags = GOVD_SHARED | GOVD_SEEN | GOVD_WRITTEN;
9888 if (flags & (GOVD_EXPLICIT | GOVD_LOCAL))
9889 return 0;
9890 if ((flags & GOVD_SEEN) == 0)
9891 return 0;
9892 if ((flags & GOVD_MAP_HAS_ATTACHMENTS) != 0)
9893 return 0;
9894 if (flags & GOVD_DEBUG_PRIVATE)
9896 gcc_assert ((flags & GOVD_DATA_SHARE_CLASS) == GOVD_SHARED);
9897 private_debug = true;
9899 else if (flags & GOVD_MAP)
9900 private_debug = false;
9901 else
9902 private_debug
9903 = lang_hooks.decls.omp_private_debug_clause (decl,
9904 !!(flags & GOVD_SHARED));
9905 if (private_debug)
9906 code = OMP_CLAUSE_PRIVATE;
9907 else if (flags & GOVD_MAP)
9909 code = OMP_CLAUSE_MAP;
9910 if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0
9911 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
9913 error ("%<_Atomic%> %qD in implicit %<map%> clause", decl);
9914 return 0;
9916 if (VAR_P (decl)
9917 && DECL_IN_CONSTANT_POOL (decl)
9918 && !lookup_attribute ("omp declare target",
9919 DECL_ATTRIBUTES (decl)))
9921 tree id = get_identifier ("omp declare target");
9922 DECL_ATTRIBUTES (decl)
9923 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
9924 varpool_node *node = varpool_node::get (decl);
9925 if (node)
9927 node->offloadable = 1;
9928 if (ENABLE_OFFLOADING)
9929 g->have_offload = true;
9933 else if (flags & GOVD_SHARED)
9935 if (is_global_var (decl))
9937 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
9938 while (ctx != NULL)
9940 splay_tree_node on
9941 = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
9942 if (on && (on->value & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
9943 | GOVD_PRIVATE | GOVD_REDUCTION
9944 | GOVD_LINEAR | GOVD_MAP)) != 0)
9945 break;
9946 ctx = ctx->outer_context;
9948 if (ctx == NULL)
9949 return 0;
9951 code = OMP_CLAUSE_SHARED;
9953 else if (flags & GOVD_PRIVATE)
9954 code = OMP_CLAUSE_PRIVATE;
9955 else if (flags & GOVD_FIRSTPRIVATE)
9957 code = OMP_CLAUSE_FIRSTPRIVATE;
9958 if ((gimplify_omp_ctxp->region_type & ORT_TARGET)
9959 && (gimplify_omp_ctxp->region_type & ORT_ACC) == 0
9960 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
9962 error ("%<_Atomic%> %qD in implicit %<firstprivate%> clause on "
9963 "%<target%> construct", decl);
9964 return 0;
9967 else if (flags & GOVD_LASTPRIVATE)
9968 code = OMP_CLAUSE_LASTPRIVATE;
9969 else if (flags & (GOVD_ALIGNED | GOVD_NONTEMPORAL))
9970 return 0;
9971 else if (flags & GOVD_CONDTEMP)
9973 code = OMP_CLAUSE__CONDTEMP_;
9974 gimple_add_tmp_var (decl);
9976 else
9977 gcc_unreachable ();
9979 if (((flags & GOVD_LASTPRIVATE)
9980 || (code == OMP_CLAUSE_SHARED && (flags & GOVD_WRITTEN)))
9981 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
9982 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
9984 tree chain = *list_p;
9985 clause = build_omp_clause (input_location, code);
9986 OMP_CLAUSE_DECL (clause) = decl;
9987 OMP_CLAUSE_CHAIN (clause) = chain;
9988 if (private_debug)
9989 OMP_CLAUSE_PRIVATE_DEBUG (clause) = 1;
9990 else if (code == OMP_CLAUSE_PRIVATE && (flags & GOVD_PRIVATE_OUTER_REF))
9991 OMP_CLAUSE_PRIVATE_OUTER_REF (clause) = 1;
9992 else if (code == OMP_CLAUSE_SHARED
9993 && (flags & GOVD_WRITTEN) == 0
9994 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
9995 OMP_CLAUSE_SHARED_READONLY (clause) = 1;
9996 else if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_EXPLICIT) == 0)
9997 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (clause) = 1;
9998 else if (code == OMP_CLAUSE_MAP && (flags & GOVD_MAP_0LEN_ARRAY) != 0)
10000 tree nc = build_omp_clause (input_location, OMP_CLAUSE_MAP);
10001 OMP_CLAUSE_DECL (nc) = decl;
10002 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
10003 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == POINTER_TYPE)
10004 OMP_CLAUSE_DECL (clause)
10005 = build_simple_mem_ref_loc (input_location, decl);
10006 OMP_CLAUSE_DECL (clause)
10007 = build2 (MEM_REF, char_type_node, OMP_CLAUSE_DECL (clause),
10008 build_int_cst (build_pointer_type (char_type_node), 0));
10009 OMP_CLAUSE_SIZE (clause) = size_zero_node;
10010 OMP_CLAUSE_SIZE (nc) = size_zero_node;
10011 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_ALLOC);
10012 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (clause) = 1;
10013 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
10014 OMP_CLAUSE_CHAIN (nc) = chain;
10015 OMP_CLAUSE_CHAIN (clause) = nc;
10016 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
10017 gimplify_omp_ctxp = ctx->outer_context;
10018 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (clause), 0),
10019 pre_p, NULL, is_gimple_val, fb_rvalue);
10020 gimplify_omp_ctxp = ctx;
10022 else if (code == OMP_CLAUSE_MAP)
10024 int kind;
10025 /* Not all combinations of these GOVD_MAP flags are actually valid. */
10026 switch (flags & (GOVD_MAP_TO_ONLY
10027 | GOVD_MAP_FORCE
10028 | GOVD_MAP_FORCE_PRESENT
10029 | GOVD_MAP_ALLOC_ONLY
10030 | GOVD_MAP_FROM_ONLY))
10032 case 0:
10033 kind = GOMP_MAP_TOFROM;
10034 break;
10035 case GOVD_MAP_FORCE:
10036 kind = GOMP_MAP_TOFROM | GOMP_MAP_FLAG_FORCE;
10037 break;
10038 case GOVD_MAP_TO_ONLY:
10039 kind = GOMP_MAP_TO;
10040 break;
10041 case GOVD_MAP_FROM_ONLY:
10042 kind = GOMP_MAP_FROM;
10043 break;
10044 case GOVD_MAP_ALLOC_ONLY:
10045 kind = GOMP_MAP_ALLOC;
10046 break;
10047 case GOVD_MAP_TO_ONLY | GOVD_MAP_FORCE:
10048 kind = GOMP_MAP_TO | GOMP_MAP_FLAG_FORCE;
10049 break;
10050 case GOVD_MAP_FORCE_PRESENT:
10051 kind = GOMP_MAP_FORCE_PRESENT;
10052 break;
10053 default:
10054 gcc_unreachable ();
10056 OMP_CLAUSE_SET_MAP_KIND (clause, kind);
10057 if (DECL_SIZE (decl)
10058 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
10060 tree decl2 = DECL_VALUE_EXPR (decl);
10061 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
10062 decl2 = TREE_OPERAND (decl2, 0);
10063 gcc_assert (DECL_P (decl2));
10064 tree mem = build_simple_mem_ref (decl2);
10065 OMP_CLAUSE_DECL (clause) = mem;
10066 OMP_CLAUSE_SIZE (clause) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
10067 if (gimplify_omp_ctxp->outer_context)
10069 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
10070 omp_notice_variable (ctx, decl2, true);
10071 omp_notice_variable (ctx, OMP_CLAUSE_SIZE (clause), true);
10073 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
10074 OMP_CLAUSE_MAP);
10075 OMP_CLAUSE_DECL (nc) = decl;
10076 OMP_CLAUSE_SIZE (nc) = size_zero_node;
10077 if (gimplify_omp_ctxp->target_firstprivatize_array_bases)
10078 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
10079 else
10080 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
10081 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
10082 OMP_CLAUSE_CHAIN (clause) = nc;
10084 else if (gimplify_omp_ctxp->target_firstprivatize_array_bases
10085 && lang_hooks.decls.omp_privatize_by_reference (decl))
10087 OMP_CLAUSE_DECL (clause) = build_simple_mem_ref (decl);
10088 OMP_CLAUSE_SIZE (clause)
10089 = unshare_expr (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))));
10090 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
10091 gimplify_omp_ctxp = ctx->outer_context;
10092 gimplify_expr (&OMP_CLAUSE_SIZE (clause),
10093 pre_p, NULL, is_gimple_val, fb_rvalue);
10094 gimplify_omp_ctxp = ctx;
10095 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
10096 OMP_CLAUSE_MAP);
10097 OMP_CLAUSE_DECL (nc) = decl;
10098 OMP_CLAUSE_SIZE (nc) = size_zero_node;
10099 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_REFERENCE);
10100 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
10101 OMP_CLAUSE_CHAIN (clause) = nc;
10103 else
10104 OMP_CLAUSE_SIZE (clause) = DECL_SIZE_UNIT (decl);
10106 if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_LASTPRIVATE) != 0)
10108 tree nc = build_omp_clause (input_location, OMP_CLAUSE_LASTPRIVATE);
10109 OMP_CLAUSE_DECL (nc) = decl;
10110 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (nc) = 1;
10111 OMP_CLAUSE_CHAIN (nc) = chain;
10112 OMP_CLAUSE_CHAIN (clause) = nc;
10113 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
10114 gimplify_omp_ctxp = ctx->outer_context;
10115 lang_hooks.decls.omp_finish_clause (nc, pre_p);
10116 gimplify_omp_ctxp = ctx;
10118 *list_p = clause;
10119 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
10120 gimplify_omp_ctxp = ctx->outer_context;
10121 lang_hooks.decls.omp_finish_clause (clause, pre_p);
10122 if (gimplify_omp_ctxp)
10123 for (; clause != chain; clause = OMP_CLAUSE_CHAIN (clause))
10124 if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_MAP
10125 && DECL_P (OMP_CLAUSE_SIZE (clause)))
10126 omp_notice_variable (gimplify_omp_ctxp, OMP_CLAUSE_SIZE (clause),
10127 true);
10128 gimplify_omp_ctxp = ctx;
10129 return 0;
10132 static void
10133 gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
10134 enum tree_code code)
10136 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
10137 tree *orig_list_p = list_p;
10138 tree c, decl;
10139 bool has_inscan_reductions = false;
10141 if (body)
10143 struct gimplify_omp_ctx *octx;
10144 for (octx = ctx; octx; octx = octx->outer_context)
10145 if ((octx->region_type & (ORT_PARALLEL | ORT_TASK | ORT_TEAMS)) != 0)
10146 break;
10147 if (octx)
10149 struct walk_stmt_info wi;
10150 memset (&wi, 0, sizeof (wi));
10151 walk_gimple_seq (body, omp_find_stores_stmt,
10152 omp_find_stores_op, &wi);
10156 if (ctx->add_safelen1)
10158 /* If there are VLAs in the body of simd loop, prevent
10159 vectorization. */
10160 gcc_assert (ctx->region_type == ORT_SIMD);
10161 c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_SAFELEN);
10162 OMP_CLAUSE_SAFELEN_EXPR (c) = integer_one_node;
10163 OMP_CLAUSE_CHAIN (c) = *list_p;
10164 *list_p = c;
10165 list_p = &OMP_CLAUSE_CHAIN (c);
10168 if (ctx->region_type == ORT_WORKSHARE
10169 && ctx->outer_context
10170 && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL)
10172 for (c = ctx->outer_context->clauses; c; c = OMP_CLAUSE_CHAIN (c))
10173 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
10174 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
10176 decl = OMP_CLAUSE_DECL (c);
10177 splay_tree_node n
10178 = splay_tree_lookup (ctx->outer_context->variables,
10179 (splay_tree_key) decl);
10180 gcc_checking_assert (!splay_tree_lookup (ctx->variables,
10181 (splay_tree_key) decl));
10182 omp_add_variable (ctx, decl, n->value);
10183 tree c2 = copy_node (c);
10184 OMP_CLAUSE_CHAIN (c2) = *list_p;
10185 *list_p = c2;
10186 if ((n->value & GOVD_FIRSTPRIVATE) == 0)
10187 continue;
10188 c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
10189 OMP_CLAUSE_FIRSTPRIVATE);
10190 OMP_CLAUSE_DECL (c2) = decl;
10191 OMP_CLAUSE_CHAIN (c2) = *list_p;
10192 *list_p = c2;
10195 while ((c = *list_p) != NULL)
10197 splay_tree_node n;
10198 bool remove = false;
10200 switch (OMP_CLAUSE_CODE (c))
10202 case OMP_CLAUSE_FIRSTPRIVATE:
10203 if ((ctx->region_type & ORT_TARGET)
10204 && (ctx->region_type & ORT_ACC) == 0
10205 && TYPE_ATOMIC (strip_array_types
10206 (TREE_TYPE (OMP_CLAUSE_DECL (c)))))
10208 error_at (OMP_CLAUSE_LOCATION (c),
10209 "%<_Atomic%> %qD in %<firstprivate%> clause on "
10210 "%<target%> construct", OMP_CLAUSE_DECL (c));
10211 remove = true;
10212 break;
10214 /* FALLTHRU */
10215 case OMP_CLAUSE_PRIVATE:
10216 case OMP_CLAUSE_SHARED:
10217 case OMP_CLAUSE_LINEAR:
10218 decl = OMP_CLAUSE_DECL (c);
10219 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10220 remove = !(n->value & GOVD_SEEN);
10221 if ((n->value & GOVD_LASTPRIVATE_CONDITIONAL) != 0
10222 && code == OMP_PARALLEL
10223 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
10224 remove = true;
10225 if (! remove)
10227 bool shared = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED;
10228 if ((n->value & GOVD_DEBUG_PRIVATE)
10229 || lang_hooks.decls.omp_private_debug_clause (decl, shared))
10231 gcc_assert ((n->value & GOVD_DEBUG_PRIVATE) == 0
10232 || ((n->value & GOVD_DATA_SHARE_CLASS)
10233 == GOVD_SHARED));
10234 OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_PRIVATE);
10235 OMP_CLAUSE_PRIVATE_DEBUG (c) = 1;
10237 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
10238 && (n->value & GOVD_WRITTEN) == 0
10239 && DECL_P (decl)
10240 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
10241 OMP_CLAUSE_SHARED_READONLY (c) = 1;
10242 else if (DECL_P (decl)
10243 && ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
10244 && (n->value & GOVD_WRITTEN) != 0)
10245 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
10246 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
10247 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
10248 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
10250 break;
10252 case OMP_CLAUSE_LASTPRIVATE:
10253 /* Make sure OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE is set to
10254 accurately reflect the presence of a FIRSTPRIVATE clause. */
10255 decl = OMP_CLAUSE_DECL (c);
10256 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10257 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c)
10258 = (n->value & GOVD_FIRSTPRIVATE) != 0;
10259 if (code == OMP_DISTRIBUTE
10260 && OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
10262 remove = true;
10263 error_at (OMP_CLAUSE_LOCATION (c),
10264 "same variable used in %<firstprivate%> and "
10265 "%<lastprivate%> clauses on %<distribute%> "
10266 "construct");
10268 if (!remove
10269 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
10270 && DECL_P (decl)
10271 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
10272 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
10273 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) && code == OMP_PARALLEL)
10274 remove = true;
10275 break;
10277 case OMP_CLAUSE_ALIGNED:
10278 decl = OMP_CLAUSE_DECL (c);
10279 if (!is_global_var (decl))
10281 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10282 remove = n == NULL || !(n->value & GOVD_SEEN);
10283 if (!remove && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
10285 struct gimplify_omp_ctx *octx;
10286 if (n != NULL
10287 && (n->value & (GOVD_DATA_SHARE_CLASS
10288 & ~GOVD_FIRSTPRIVATE)))
10289 remove = true;
10290 else
10291 for (octx = ctx->outer_context; octx;
10292 octx = octx->outer_context)
10294 n = splay_tree_lookup (octx->variables,
10295 (splay_tree_key) decl);
10296 if (n == NULL)
10297 continue;
10298 if (n->value & GOVD_LOCAL)
10299 break;
10300 /* We have to avoid assigning a shared variable
10301 to itself when trying to add
10302 __builtin_assume_aligned. */
10303 if (n->value & GOVD_SHARED)
10305 remove = true;
10306 break;
10311 else if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
10313 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10314 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
10315 remove = true;
10317 break;
10319 case OMP_CLAUSE_NONTEMPORAL:
10320 decl = OMP_CLAUSE_DECL (c);
10321 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10322 remove = n == NULL || !(n->value & GOVD_SEEN);
10323 break;
10325 case OMP_CLAUSE_MAP:
10326 if (code == OMP_TARGET_EXIT_DATA
10327 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER)
10329 remove = true;
10330 break;
10332 decl = OMP_CLAUSE_DECL (c);
10333 /* Data clauses associated with reductions must be
10334 compatible with present_or_copy. Warn and adjust the clause
10335 if that is not the case. */
10336 if (ctx->region_type == ORT_ACC_PARALLEL
10337 || ctx->region_type == ORT_ACC_SERIAL)
10339 tree t = DECL_P (decl) ? decl : TREE_OPERAND (decl, 0);
10340 n = NULL;
10342 if (DECL_P (t))
10343 n = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
10345 if (n && (n->value & GOVD_REDUCTION))
10347 enum gomp_map_kind kind = OMP_CLAUSE_MAP_KIND (c);
10349 OMP_CLAUSE_MAP_IN_REDUCTION (c) = 1;
10350 if ((kind & GOMP_MAP_TOFROM) != GOMP_MAP_TOFROM
10351 && kind != GOMP_MAP_FORCE_PRESENT
10352 && kind != GOMP_MAP_POINTER)
10354 warning_at (OMP_CLAUSE_LOCATION (c), 0,
10355 "incompatible data clause with reduction "
10356 "on %qE; promoting to %<present_or_copy%>",
10357 DECL_NAME (t));
10358 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TOFROM);
10362 if (!DECL_P (decl))
10364 if ((ctx->region_type & ORT_TARGET) != 0
10365 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
10367 if (TREE_CODE (decl) == INDIRECT_REF
10368 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
10369 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
10370 == REFERENCE_TYPE))
10371 decl = TREE_OPERAND (decl, 0);
10372 if (TREE_CODE (decl) == COMPONENT_REF)
10374 while (TREE_CODE (decl) == COMPONENT_REF)
10375 decl = TREE_OPERAND (decl, 0);
10376 if (DECL_P (decl))
10378 n = splay_tree_lookup (ctx->variables,
10379 (splay_tree_key) decl);
10380 if (!(n->value & GOVD_SEEN))
10381 remove = true;
10385 break;
10387 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10388 if ((ctx->region_type & ORT_TARGET) != 0
10389 && !(n->value & GOVD_SEEN)
10390 && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) == 0
10391 && (!is_global_var (decl)
10392 || !lookup_attribute ("omp declare target link",
10393 DECL_ATTRIBUTES (decl))))
10395 remove = true;
10396 /* For struct element mapping, if struct is never referenced
10397 in target block and none of the mapping has always modifier,
10398 remove all the struct element mappings, which immediately
10399 follow the GOMP_MAP_STRUCT map clause. */
10400 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT)
10402 HOST_WIDE_INT cnt = tree_to_shwi (OMP_CLAUSE_SIZE (c));
10403 while (cnt--)
10404 OMP_CLAUSE_CHAIN (c)
10405 = OMP_CLAUSE_CHAIN (OMP_CLAUSE_CHAIN (c));
10408 else if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT
10409 && code == OMP_TARGET_EXIT_DATA)
10410 remove = true;
10411 else if (DECL_SIZE (decl)
10412 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST
10413 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_POINTER
10414 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_POINTER
10415 && (OMP_CLAUSE_MAP_KIND (c)
10416 != GOMP_MAP_FIRSTPRIVATE_REFERENCE))
10418 /* For GOMP_MAP_FORCE_DEVICEPTR, we'll never enter here, because
10419 for these, TREE_CODE (DECL_SIZE (decl)) will always be
10420 INTEGER_CST. */
10421 gcc_assert (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FORCE_DEVICEPTR);
10423 tree decl2 = DECL_VALUE_EXPR (decl);
10424 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
10425 decl2 = TREE_OPERAND (decl2, 0);
10426 gcc_assert (DECL_P (decl2));
10427 tree mem = build_simple_mem_ref (decl2);
10428 OMP_CLAUSE_DECL (c) = mem;
10429 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
10430 if (ctx->outer_context)
10432 omp_notice_variable (ctx->outer_context, decl2, true);
10433 omp_notice_variable (ctx->outer_context,
10434 OMP_CLAUSE_SIZE (c), true);
10436 if (((ctx->region_type & ORT_TARGET) != 0
10437 || !ctx->target_firstprivatize_array_bases)
10438 && ((n->value & GOVD_SEEN) == 0
10439 || (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) == 0))
10441 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
10442 OMP_CLAUSE_MAP);
10443 OMP_CLAUSE_DECL (nc) = decl;
10444 OMP_CLAUSE_SIZE (nc) = size_zero_node;
10445 if (ctx->target_firstprivatize_array_bases)
10446 OMP_CLAUSE_SET_MAP_KIND (nc,
10447 GOMP_MAP_FIRSTPRIVATE_POINTER);
10448 else
10449 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
10450 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
10451 OMP_CLAUSE_CHAIN (c) = nc;
10452 c = nc;
10455 else
10457 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
10458 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
10459 gcc_assert ((n->value & GOVD_SEEN) == 0
10460 || ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
10461 == 0));
10463 break;
10465 case OMP_CLAUSE_TO:
10466 case OMP_CLAUSE_FROM:
10467 case OMP_CLAUSE__CACHE_:
10468 decl = OMP_CLAUSE_DECL (c);
10469 if (!DECL_P (decl))
10470 break;
10471 if (DECL_SIZE (decl)
10472 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
10474 tree decl2 = DECL_VALUE_EXPR (decl);
10475 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
10476 decl2 = TREE_OPERAND (decl2, 0);
10477 gcc_assert (DECL_P (decl2));
10478 tree mem = build_simple_mem_ref (decl2);
10479 OMP_CLAUSE_DECL (c) = mem;
10480 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
10481 if (ctx->outer_context)
10483 omp_notice_variable (ctx->outer_context, decl2, true);
10484 omp_notice_variable (ctx->outer_context,
10485 OMP_CLAUSE_SIZE (c), true);
10488 else if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
10489 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
10490 break;
10492 case OMP_CLAUSE_REDUCTION:
10493 if (OMP_CLAUSE_REDUCTION_INSCAN (c))
10495 decl = OMP_CLAUSE_DECL (c);
10496 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10497 if ((n->value & GOVD_REDUCTION_INSCAN) == 0)
10499 remove = true;
10500 error_at (OMP_CLAUSE_LOCATION (c),
10501 "%qD specified in %<inscan%> %<reduction%> clause "
10502 "but not in %<scan%> directive clause", decl);
10503 break;
10505 has_inscan_reductions = true;
10507 /* FALLTHRU */
10508 case OMP_CLAUSE_IN_REDUCTION:
10509 case OMP_CLAUSE_TASK_REDUCTION:
10510 decl = OMP_CLAUSE_DECL (c);
10511 /* OpenACC reductions need a present_or_copy data clause.
10512 Add one if necessary. Emit error when the reduction is private. */
10513 if (ctx->region_type == ORT_ACC_PARALLEL
10514 || ctx->region_type == ORT_ACC_SERIAL)
10516 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10517 if (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
10519 remove = true;
10520 error_at (OMP_CLAUSE_LOCATION (c), "invalid private "
10521 "reduction on %qE", DECL_NAME (decl));
10523 else if ((n->value & GOVD_MAP) == 0)
10525 tree next = OMP_CLAUSE_CHAIN (c);
10526 tree nc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_MAP);
10527 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_TOFROM);
10528 OMP_CLAUSE_DECL (nc) = decl;
10529 OMP_CLAUSE_CHAIN (c) = nc;
10530 lang_hooks.decls.omp_finish_clause (nc, pre_p);
10531 while (1)
10533 OMP_CLAUSE_MAP_IN_REDUCTION (nc) = 1;
10534 if (OMP_CLAUSE_CHAIN (nc) == NULL)
10535 break;
10536 nc = OMP_CLAUSE_CHAIN (nc);
10538 OMP_CLAUSE_CHAIN (nc) = next;
10539 n->value |= GOVD_MAP;
10542 if (DECL_P (decl)
10543 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
10544 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
10545 break;
10546 case OMP_CLAUSE_COPYIN:
10547 case OMP_CLAUSE_COPYPRIVATE:
10548 case OMP_CLAUSE_IF:
10549 case OMP_CLAUSE_NUM_THREADS:
10550 case OMP_CLAUSE_NUM_TEAMS:
10551 case OMP_CLAUSE_THREAD_LIMIT:
10552 case OMP_CLAUSE_DIST_SCHEDULE:
10553 case OMP_CLAUSE_DEVICE:
10554 case OMP_CLAUSE_SCHEDULE:
10555 case OMP_CLAUSE_NOWAIT:
10556 case OMP_CLAUSE_ORDERED:
10557 case OMP_CLAUSE_DEFAULT:
10558 case OMP_CLAUSE_UNTIED:
10559 case OMP_CLAUSE_COLLAPSE:
10560 case OMP_CLAUSE_FINAL:
10561 case OMP_CLAUSE_MERGEABLE:
10562 case OMP_CLAUSE_PROC_BIND:
10563 case OMP_CLAUSE_SAFELEN:
10564 case OMP_CLAUSE_SIMDLEN:
10565 case OMP_CLAUSE_DEPEND:
10566 case OMP_CLAUSE_PRIORITY:
10567 case OMP_CLAUSE_GRAINSIZE:
10568 case OMP_CLAUSE_NUM_TASKS:
10569 case OMP_CLAUSE_NOGROUP:
10570 case OMP_CLAUSE_THREADS:
10571 case OMP_CLAUSE_SIMD:
10572 case OMP_CLAUSE_HINT:
10573 case OMP_CLAUSE_DEFAULTMAP:
10574 case OMP_CLAUSE_ORDER:
10575 case OMP_CLAUSE_BIND:
10576 case OMP_CLAUSE_USE_DEVICE_PTR:
10577 case OMP_CLAUSE_USE_DEVICE_ADDR:
10578 case OMP_CLAUSE_IS_DEVICE_PTR:
10579 case OMP_CLAUSE_ASYNC:
10580 case OMP_CLAUSE_WAIT:
10581 case OMP_CLAUSE_INDEPENDENT:
10582 case OMP_CLAUSE_NUM_GANGS:
10583 case OMP_CLAUSE_NUM_WORKERS:
10584 case OMP_CLAUSE_VECTOR_LENGTH:
10585 case OMP_CLAUSE_GANG:
10586 case OMP_CLAUSE_WORKER:
10587 case OMP_CLAUSE_VECTOR:
10588 case OMP_CLAUSE_AUTO:
10589 case OMP_CLAUSE_SEQ:
10590 case OMP_CLAUSE_TILE:
10591 case OMP_CLAUSE_IF_PRESENT:
10592 case OMP_CLAUSE_FINALIZE:
10593 case OMP_CLAUSE_INCLUSIVE:
10594 case OMP_CLAUSE_EXCLUSIVE:
10595 break;
10597 default:
10598 gcc_unreachable ();
10601 if (remove)
10602 *list_p = OMP_CLAUSE_CHAIN (c);
10603 else
10604 list_p = &OMP_CLAUSE_CHAIN (c);
10607 /* Add in any implicit data sharing. */
10608 struct gimplify_adjust_omp_clauses_data data;
10609 data.list_p = list_p;
10610 data.pre_p = pre_p;
10611 splay_tree_foreach (ctx->variables, gimplify_adjust_omp_clauses_1, &data);
10613 if (has_inscan_reductions)
10614 for (c = *orig_list_p; c; c = OMP_CLAUSE_CHAIN (c))
10615 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
10616 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
10618 error_at (OMP_CLAUSE_LOCATION (c),
10619 "%<inscan%> %<reduction%> clause used together with "
10620 "%<linear%> clause for a variable other than loop "
10621 "iterator");
10622 break;
10625 gimplify_omp_ctxp = ctx->outer_context;
10626 delete_omp_context (ctx);
10629 /* Return 0 if CONSTRUCTS selectors don't match the OpenMP context,
10630 -1 if unknown yet (simd is involved, won't be known until vectorization)
10631 and 1 if they do. If SCORES is non-NULL, it should point to an array
10632 of at least 2*NCONSTRUCTS+2 ints, and will be filled with the positions
10633 of the CONSTRUCTS (position -1 if it will never match) followed by
10634 number of constructs in the OpenMP context construct trait. If the
10635 score depends on whether it will be in a declare simd clone or not,
10636 the function returns 2 and there will be two sets of the scores, the first
10637 one for the case that it is not in a declare simd clone, the other
10638 that it is in a declare simd clone. */
10641 omp_construct_selector_matches (enum tree_code *constructs, int nconstructs,
10642 int *scores)
10644 int matched = 0, cnt = 0;
10645 bool simd_seen = false;
10646 bool target_seen = false;
10647 int declare_simd_cnt = -1;
10648 auto_vec<enum tree_code, 16> codes;
10649 for (struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; ctx;)
10651 if (((ctx->region_type & ORT_PARALLEL) && ctx->code == OMP_PARALLEL)
10652 || ((ctx->region_type & (ORT_TARGET | ORT_IMPLICIT_TARGET | ORT_ACC))
10653 == ORT_TARGET && ctx->code == OMP_TARGET)
10654 || ((ctx->region_type & ORT_TEAMS) && ctx->code == OMP_TEAMS)
10655 || (ctx->region_type == ORT_WORKSHARE && ctx->code == OMP_FOR)
10656 || (ctx->region_type == ORT_SIMD
10657 && ctx->code == OMP_SIMD
10658 && !omp_find_clause (ctx->clauses, OMP_CLAUSE_BIND)))
10660 ++cnt;
10661 if (scores)
10662 codes.safe_push (ctx->code);
10663 else if (matched < nconstructs && ctx->code == constructs[matched])
10665 if (ctx->code == OMP_SIMD)
10667 if (matched)
10668 return 0;
10669 simd_seen = true;
10671 ++matched;
10673 if (ctx->code == OMP_TARGET)
10675 if (scores == NULL)
10676 return matched < nconstructs ? 0 : simd_seen ? -1 : 1;
10677 target_seen = true;
10678 break;
10681 else if (ctx->region_type == ORT_WORKSHARE
10682 && ctx->code == OMP_LOOP
10683 && ctx->outer_context
10684 && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL
10685 && ctx->outer_context->outer_context
10686 && ctx->outer_context->outer_context->code == OMP_LOOP
10687 && ctx->outer_context->outer_context->distribute)
10688 ctx = ctx->outer_context->outer_context;
10689 ctx = ctx->outer_context;
10691 if (!target_seen
10692 && lookup_attribute ("omp declare simd",
10693 DECL_ATTRIBUTES (current_function_decl)))
10695 /* Declare simd is a maybe case, it is supposed to be added only to the
10696 omp-simd-clone.c added clones and not to the base function. */
10697 declare_simd_cnt = cnt++;
10698 if (scores)
10699 codes.safe_push (OMP_SIMD);
10700 else if (cnt == 0
10701 && constructs[0] == OMP_SIMD)
10703 gcc_assert (matched == 0);
10704 simd_seen = true;
10705 if (++matched == nconstructs)
10706 return -1;
10709 if (tree attr = lookup_attribute ("omp declare variant variant",
10710 DECL_ATTRIBUTES (current_function_decl)))
10712 enum tree_code variant_constructs[5];
10713 int variant_nconstructs = 0;
10714 if (!target_seen)
10715 variant_nconstructs
10716 = omp_constructor_traits_to_codes (TREE_VALUE (attr),
10717 variant_constructs);
10718 for (int i = 0; i < variant_nconstructs; i++)
10720 ++cnt;
10721 if (scores)
10722 codes.safe_push (variant_constructs[i]);
10723 else if (matched < nconstructs
10724 && variant_constructs[i] == constructs[matched])
10726 if (variant_constructs[i] == OMP_SIMD)
10728 if (matched)
10729 return 0;
10730 simd_seen = true;
10732 ++matched;
10736 if (!target_seen
10737 && lookup_attribute ("omp declare target block",
10738 DECL_ATTRIBUTES (current_function_decl)))
10740 if (scores)
10741 codes.safe_push (OMP_TARGET);
10742 else if (matched < nconstructs && constructs[matched] == OMP_TARGET)
10743 ++matched;
10745 if (scores)
10747 for (int pass = 0; pass < (declare_simd_cnt == -1 ? 1 : 2); pass++)
10749 int j = codes.length () - 1;
10750 for (int i = nconstructs - 1; i >= 0; i--)
10752 while (j >= 0
10753 && (pass != 0 || declare_simd_cnt != j)
10754 && constructs[i] != codes[j])
10755 --j;
10756 if (pass == 0 && declare_simd_cnt != -1 && j > declare_simd_cnt)
10757 *scores++ = j - 1;
10758 else
10759 *scores++ = j;
10761 *scores++ = ((pass == 0 && declare_simd_cnt != -1)
10762 ? codes.length () - 1 : codes.length ());
10764 return declare_simd_cnt == -1 ? 1 : 2;
10766 if (matched == nconstructs)
10767 return simd_seen ? -1 : 1;
10768 return 0;
10771 /* Gimplify OACC_CACHE. */
10773 static void
10774 gimplify_oacc_cache (tree *expr_p, gimple_seq *pre_p)
10776 tree expr = *expr_p;
10778 gimplify_scan_omp_clauses (&OACC_CACHE_CLAUSES (expr), pre_p, ORT_ACC,
10779 OACC_CACHE);
10780 gimplify_adjust_omp_clauses (pre_p, NULL, &OACC_CACHE_CLAUSES (expr),
10781 OACC_CACHE);
10783 /* TODO: Do something sensible with this information. */
10785 *expr_p = NULL_TREE;
10788 /* Helper function of gimplify_oacc_declare. The helper's purpose is to,
10789 if required, translate 'kind' in CLAUSE into an 'entry' kind and 'exit'
10790 kind. The entry kind will replace the one in CLAUSE, while the exit
10791 kind will be used in a new omp_clause and returned to the caller. */
10793 static tree
10794 gimplify_oacc_declare_1 (tree clause)
10796 HOST_WIDE_INT kind, new_op;
10797 bool ret = false;
10798 tree c = NULL;
10800 kind = OMP_CLAUSE_MAP_KIND (clause);
10802 switch (kind)
10804 case GOMP_MAP_ALLOC:
10805 new_op = GOMP_MAP_RELEASE;
10806 ret = true;
10807 break;
10809 case GOMP_MAP_FROM:
10810 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_FORCE_ALLOC);
10811 new_op = GOMP_MAP_FROM;
10812 ret = true;
10813 break;
10815 case GOMP_MAP_TOFROM:
10816 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_TO);
10817 new_op = GOMP_MAP_FROM;
10818 ret = true;
10819 break;
10821 case GOMP_MAP_DEVICE_RESIDENT:
10822 case GOMP_MAP_FORCE_DEVICEPTR:
10823 case GOMP_MAP_FORCE_PRESENT:
10824 case GOMP_MAP_LINK:
10825 case GOMP_MAP_POINTER:
10826 case GOMP_MAP_TO:
10827 break;
10829 default:
10830 gcc_unreachable ();
10831 break;
10834 if (ret)
10836 c = build_omp_clause (OMP_CLAUSE_LOCATION (clause), OMP_CLAUSE_MAP);
10837 OMP_CLAUSE_SET_MAP_KIND (c, new_op);
10838 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clause);
10841 return c;
10844 /* Gimplify OACC_DECLARE. */
10846 static void
10847 gimplify_oacc_declare (tree *expr_p, gimple_seq *pre_p)
10849 tree expr = *expr_p;
10850 gomp_target *stmt;
10851 tree clauses, t, decl;
10853 clauses = OACC_DECLARE_CLAUSES (expr);
10855 gimplify_scan_omp_clauses (&clauses, pre_p, ORT_TARGET_DATA, OACC_DECLARE);
10856 gimplify_adjust_omp_clauses (pre_p, NULL, &clauses, OACC_DECLARE);
10858 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
10860 decl = OMP_CLAUSE_DECL (t);
10862 if (TREE_CODE (decl) == MEM_REF)
10863 decl = TREE_OPERAND (decl, 0);
10865 if (VAR_P (decl) && !is_oacc_declared (decl))
10867 tree attr = get_identifier ("oacc declare target");
10868 DECL_ATTRIBUTES (decl) = tree_cons (attr, NULL_TREE,
10869 DECL_ATTRIBUTES (decl));
10872 if (VAR_P (decl)
10873 && !is_global_var (decl)
10874 && DECL_CONTEXT (decl) == current_function_decl)
10876 tree c = gimplify_oacc_declare_1 (t);
10877 if (c)
10879 if (oacc_declare_returns == NULL)
10880 oacc_declare_returns = new hash_map<tree, tree>;
10882 oacc_declare_returns->put (decl, c);
10886 if (gimplify_omp_ctxp)
10887 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_SEEN);
10890 stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
10891 clauses);
10893 gimplify_seq_add_stmt (pre_p, stmt);
10895 *expr_p = NULL_TREE;
10898 /* Gimplify the contents of an OMP_PARALLEL statement. This involves
10899 gimplification of the body, as well as scanning the body for used
10900 variables. We need to do this scan now, because variable-sized
10901 decls will be decomposed during gimplification. */
10903 static void
10904 gimplify_omp_parallel (tree *expr_p, gimple_seq *pre_p)
10906 tree expr = *expr_p;
10907 gimple *g;
10908 gimple_seq body = NULL;
10910 gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr), pre_p,
10911 OMP_PARALLEL_COMBINED (expr)
10912 ? ORT_COMBINED_PARALLEL
10913 : ORT_PARALLEL, OMP_PARALLEL);
10915 push_gimplify_context ();
10917 g = gimplify_and_return_first (OMP_PARALLEL_BODY (expr), &body);
10918 if (gimple_code (g) == GIMPLE_BIND)
10919 pop_gimplify_context (g);
10920 else
10921 pop_gimplify_context (NULL);
10923 gimplify_adjust_omp_clauses (pre_p, body, &OMP_PARALLEL_CLAUSES (expr),
10924 OMP_PARALLEL);
10926 g = gimple_build_omp_parallel (body,
10927 OMP_PARALLEL_CLAUSES (expr),
10928 NULL_TREE, NULL_TREE);
10929 if (OMP_PARALLEL_COMBINED (expr))
10930 gimple_omp_set_subcode (g, GF_OMP_PARALLEL_COMBINED);
10931 gimplify_seq_add_stmt (pre_p, g);
10932 *expr_p = NULL_TREE;
10935 /* Gimplify the contents of an OMP_TASK statement. This involves
10936 gimplification of the body, as well as scanning the body for used
10937 variables. We need to do this scan now, because variable-sized
10938 decls will be decomposed during gimplification. */
10940 static void
10941 gimplify_omp_task (tree *expr_p, gimple_seq *pre_p)
10943 tree expr = *expr_p;
10944 gimple *g;
10945 gimple_seq body = NULL;
10947 if (OMP_TASK_BODY (expr) == NULL_TREE)
10948 for (tree c = OMP_TASK_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
10949 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
10950 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_MUTEXINOUTSET)
10952 error_at (OMP_CLAUSE_LOCATION (c),
10953 "%<mutexinoutset%> kind in %<depend%> clause on a "
10954 "%<taskwait%> construct");
10955 break;
10958 gimplify_scan_omp_clauses (&OMP_TASK_CLAUSES (expr), pre_p,
10959 omp_find_clause (OMP_TASK_CLAUSES (expr),
10960 OMP_CLAUSE_UNTIED)
10961 ? ORT_UNTIED_TASK : ORT_TASK, OMP_TASK);
10963 if (OMP_TASK_BODY (expr))
10965 push_gimplify_context ();
10967 g = gimplify_and_return_first (OMP_TASK_BODY (expr), &body);
10968 if (gimple_code (g) == GIMPLE_BIND)
10969 pop_gimplify_context (g);
10970 else
10971 pop_gimplify_context (NULL);
10974 gimplify_adjust_omp_clauses (pre_p, body, &OMP_TASK_CLAUSES (expr),
10975 OMP_TASK);
10977 g = gimple_build_omp_task (body,
10978 OMP_TASK_CLAUSES (expr),
10979 NULL_TREE, NULL_TREE,
10980 NULL_TREE, NULL_TREE, NULL_TREE);
10981 if (OMP_TASK_BODY (expr) == NULL_TREE)
10982 gimple_omp_task_set_taskwait_p (g, true);
10983 gimplify_seq_add_stmt (pre_p, g);
10984 *expr_p = NULL_TREE;
10987 /* Helper function of gimplify_omp_for, find OMP_FOR resp. OMP_SIMD
10988 with non-NULL OMP_FOR_INIT. Also, fill in pdata array,
10989 pdata[0] non-NULL if there is anything non-trivial in between, pdata[1]
10990 is address of OMP_PARALLEL in between if any, pdata[2] is address of
10991 OMP_FOR in between if any and pdata[3] is address of the inner
10992 OMP_FOR/OMP_SIMD. */
10994 static tree
10995 find_combined_omp_for (tree *tp, int *walk_subtrees, void *data)
10997 tree **pdata = (tree **) data;
10998 *walk_subtrees = 0;
10999 switch (TREE_CODE (*tp))
11001 case OMP_FOR:
11002 if (OMP_FOR_INIT (*tp) != NULL_TREE)
11004 pdata[3] = tp;
11005 return *tp;
11007 pdata[2] = tp;
11008 *walk_subtrees = 1;
11009 break;
11010 case OMP_SIMD:
11011 if (OMP_FOR_INIT (*tp) != NULL_TREE)
11013 pdata[3] = tp;
11014 return *tp;
11016 break;
11017 case BIND_EXPR:
11018 if (BIND_EXPR_VARS (*tp)
11019 || (BIND_EXPR_BLOCK (*tp)
11020 && BLOCK_VARS (BIND_EXPR_BLOCK (*tp))))
11021 pdata[0] = tp;
11022 *walk_subtrees = 1;
11023 break;
11024 case STATEMENT_LIST:
11025 if (!tsi_one_before_end_p (tsi_start (*tp)))
11026 pdata[0] = tp;
11027 *walk_subtrees = 1;
11028 break;
11029 case TRY_FINALLY_EXPR:
11030 pdata[0] = tp;
11031 *walk_subtrees = 1;
11032 break;
11033 case OMP_PARALLEL:
11034 pdata[1] = tp;
11035 *walk_subtrees = 1;
11036 break;
11037 default:
11038 break;
11040 return NULL_TREE;
11043 /* Gimplify the gross structure of an OMP_FOR statement. */
11045 static enum gimplify_status
11046 gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
11048 tree for_stmt, orig_for_stmt, inner_for_stmt = NULL_TREE, decl, var, t;
11049 enum gimplify_status ret = GS_ALL_DONE;
11050 enum gimplify_status tret;
11051 gomp_for *gfor;
11052 gimple_seq for_body, for_pre_body;
11053 int i;
11054 bitmap has_decl_expr = NULL;
11055 enum omp_region_type ort = ORT_WORKSHARE;
11057 orig_for_stmt = for_stmt = *expr_p;
11059 bool loop_p = (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_BIND)
11060 != NULL_TREE);
11061 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
11063 tree *data[4] = { NULL, NULL, NULL, NULL };
11064 gcc_assert (TREE_CODE (for_stmt) != OACC_LOOP);
11065 inner_for_stmt = walk_tree (&OMP_FOR_BODY (for_stmt),
11066 find_combined_omp_for, data, NULL);
11067 if (inner_for_stmt == NULL_TREE)
11069 gcc_assert (seen_error ());
11070 *expr_p = NULL_TREE;
11071 return GS_ERROR;
11073 if (data[2] && OMP_FOR_PRE_BODY (*data[2]))
11075 append_to_statement_list_force (OMP_FOR_PRE_BODY (*data[2]),
11076 &OMP_FOR_PRE_BODY (for_stmt));
11077 OMP_FOR_PRE_BODY (*data[2]) = NULL_TREE;
11079 if (OMP_FOR_PRE_BODY (inner_for_stmt))
11081 append_to_statement_list_force (OMP_FOR_PRE_BODY (inner_for_stmt),
11082 &OMP_FOR_PRE_BODY (for_stmt));
11083 OMP_FOR_PRE_BODY (inner_for_stmt) = NULL_TREE;
11086 if (data[0])
11088 /* We have some statements or variable declarations in between
11089 the composite construct directives. Move them around the
11090 inner_for_stmt. */
11091 data[0] = expr_p;
11092 for (i = 0; i < 3; i++)
11093 if (data[i])
11095 tree t = *data[i];
11096 if (i < 2 && data[i + 1] == &OMP_BODY (t))
11097 data[i + 1] = data[i];
11098 *data[i] = OMP_BODY (t);
11099 tree body = build3 (BIND_EXPR, void_type_node, NULL_TREE,
11100 NULL_TREE, make_node (BLOCK));
11101 OMP_BODY (t) = body;
11102 append_to_statement_list_force (inner_for_stmt,
11103 &BIND_EXPR_BODY (body));
11104 *data[3] = t;
11105 data[3] = tsi_stmt_ptr (tsi_start (BIND_EXPR_BODY (body)));
11106 gcc_assert (*data[3] == inner_for_stmt);
11108 return GS_OK;
11111 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
11112 if (!loop_p
11113 && OMP_FOR_ORIG_DECLS (inner_for_stmt)
11114 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
11115 i)) == TREE_LIST
11116 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
11117 i)))
11119 tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
11120 /* Class iterators aren't allowed on OMP_SIMD, so the only
11121 case we need to solve is distribute parallel for. They are
11122 allowed on the loop construct, but that is already handled
11123 in gimplify_omp_loop. */
11124 gcc_assert (TREE_CODE (inner_for_stmt) == OMP_FOR
11125 && TREE_CODE (for_stmt) == OMP_DISTRIBUTE
11126 && data[1]);
11127 tree orig_decl = TREE_PURPOSE (orig);
11128 tree last = TREE_VALUE (orig);
11129 tree *pc;
11130 for (pc = &OMP_FOR_CLAUSES (inner_for_stmt);
11131 *pc; pc = &OMP_CLAUSE_CHAIN (*pc))
11132 if ((OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE
11133 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LASTPRIVATE)
11134 && OMP_CLAUSE_DECL (*pc) == orig_decl)
11135 break;
11136 if (*pc == NULL_TREE)
11138 tree *spc;
11139 for (spc = &OMP_PARALLEL_CLAUSES (*data[1]);
11140 *spc; spc = &OMP_CLAUSE_CHAIN (*spc))
11141 if (OMP_CLAUSE_CODE (*spc) == OMP_CLAUSE_PRIVATE
11142 && OMP_CLAUSE_DECL (*spc) == orig_decl)
11143 break;
11144 if (*spc)
11146 tree c = *spc;
11147 *spc = OMP_CLAUSE_CHAIN (c);
11148 OMP_CLAUSE_CHAIN (c) = NULL_TREE;
11149 *pc = c;
11152 if (*pc == NULL_TREE)
11154 else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE)
11156 /* private clause will appear only on inner_for_stmt.
11157 Change it into firstprivate, and add private clause
11158 on for_stmt. */
11159 tree c = copy_node (*pc);
11160 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
11161 OMP_FOR_CLAUSES (for_stmt) = c;
11162 OMP_CLAUSE_CODE (*pc) = OMP_CLAUSE_FIRSTPRIVATE;
11163 lang_hooks.decls.omp_finish_clause (*pc, pre_p);
11165 else
11167 /* lastprivate clause will appear on both inner_for_stmt
11168 and for_stmt. Add firstprivate clause to
11169 inner_for_stmt. */
11170 tree c = build_omp_clause (OMP_CLAUSE_LOCATION (*pc),
11171 OMP_CLAUSE_FIRSTPRIVATE);
11172 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (*pc);
11173 OMP_CLAUSE_CHAIN (c) = *pc;
11174 *pc = c;
11175 lang_hooks.decls.omp_finish_clause (*pc, pre_p);
11177 tree c = build_omp_clause (UNKNOWN_LOCATION,
11178 OMP_CLAUSE_FIRSTPRIVATE);
11179 OMP_CLAUSE_DECL (c) = last;
11180 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
11181 OMP_PARALLEL_CLAUSES (*data[1]) = c;
11182 c = build_omp_clause (UNKNOWN_LOCATION,
11183 *pc ? OMP_CLAUSE_SHARED
11184 : OMP_CLAUSE_FIRSTPRIVATE);
11185 OMP_CLAUSE_DECL (c) = orig_decl;
11186 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
11187 OMP_PARALLEL_CLAUSES (*data[1]) = c;
11189 /* Similarly, take care of C++ range for temporaries, those should
11190 be firstprivate on OMP_PARALLEL if any. */
11191 if (data[1])
11192 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
11193 if (OMP_FOR_ORIG_DECLS (inner_for_stmt)
11194 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
11195 i)) == TREE_LIST
11196 && TREE_CHAIN (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
11197 i)))
11199 tree orig
11200 = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
11201 tree v = TREE_CHAIN (orig);
11202 tree c = build_omp_clause (UNKNOWN_LOCATION,
11203 OMP_CLAUSE_FIRSTPRIVATE);
11204 /* First add firstprivate clause for the __for_end artificial
11205 decl. */
11206 OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 1);
11207 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
11208 == REFERENCE_TYPE)
11209 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
11210 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
11211 OMP_PARALLEL_CLAUSES (*data[1]) = c;
11212 if (TREE_VEC_ELT (v, 0))
11214 /* And now the same for __for_range artificial decl if it
11215 exists. */
11216 c = build_omp_clause (UNKNOWN_LOCATION,
11217 OMP_CLAUSE_FIRSTPRIVATE);
11218 OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 0);
11219 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
11220 == REFERENCE_TYPE)
11221 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
11222 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
11223 OMP_PARALLEL_CLAUSES (*data[1]) = c;
11228 switch (TREE_CODE (for_stmt))
11230 case OMP_FOR:
11231 case OMP_DISTRIBUTE:
11232 break;
11233 case OACC_LOOP:
11234 ort = ORT_ACC;
11235 break;
11236 case OMP_TASKLOOP:
11237 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_UNTIED))
11238 ort = ORT_UNTIED_TASKLOOP;
11239 else
11240 ort = ORT_TASKLOOP;
11241 break;
11242 case OMP_SIMD:
11243 ort = ORT_SIMD;
11244 break;
11245 default:
11246 gcc_unreachable ();
11249 /* Set OMP_CLAUSE_LINEAR_NO_COPYIN flag on explicit linear
11250 clause for the IV. */
11251 if (ort == ORT_SIMD && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
11253 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), 0);
11254 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
11255 decl = TREE_OPERAND (t, 0);
11256 for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
11257 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
11258 && OMP_CLAUSE_DECL (c) == decl)
11260 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
11261 break;
11265 if (TREE_CODE (for_stmt) != OMP_TASKLOOP)
11266 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p, ort,
11267 loop_p && TREE_CODE (for_stmt) != OMP_SIMD
11268 ? OMP_LOOP : TREE_CODE (for_stmt));
11270 if (TREE_CODE (for_stmt) == OMP_DISTRIBUTE)
11271 gimplify_omp_ctxp->distribute = true;
11273 /* Handle OMP_FOR_INIT. */
11274 for_pre_body = NULL;
11275 if ((ort == ORT_SIMD
11276 || (inner_for_stmt && TREE_CODE (inner_for_stmt) == OMP_SIMD))
11277 && OMP_FOR_PRE_BODY (for_stmt))
11279 has_decl_expr = BITMAP_ALLOC (NULL);
11280 if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == DECL_EXPR
11281 && TREE_CODE (DECL_EXPR_DECL (OMP_FOR_PRE_BODY (for_stmt)))
11282 == VAR_DECL)
11284 t = OMP_FOR_PRE_BODY (for_stmt);
11285 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
11287 else if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == STATEMENT_LIST)
11289 tree_stmt_iterator si;
11290 for (si = tsi_start (OMP_FOR_PRE_BODY (for_stmt)); !tsi_end_p (si);
11291 tsi_next (&si))
11293 t = tsi_stmt (si);
11294 if (TREE_CODE (t) == DECL_EXPR
11295 && TREE_CODE (DECL_EXPR_DECL (t)) == VAR_DECL)
11296 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
11300 if (OMP_FOR_PRE_BODY (for_stmt))
11302 if (TREE_CODE (for_stmt) != OMP_TASKLOOP || gimplify_omp_ctxp)
11303 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
11304 else
11306 struct gimplify_omp_ctx ctx;
11307 memset (&ctx, 0, sizeof (ctx));
11308 ctx.region_type = ORT_NONE;
11309 gimplify_omp_ctxp = &ctx;
11310 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
11311 gimplify_omp_ctxp = NULL;
11314 OMP_FOR_PRE_BODY (for_stmt) = NULL_TREE;
11316 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
11317 for_stmt = inner_for_stmt;
11319 /* For taskloop, need to gimplify the start, end and step before the
11320 taskloop, outside of the taskloop omp context. */
11321 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
11323 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
11325 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
11326 if (!is_gimple_constant (TREE_OPERAND (t, 1)))
11328 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
11329 TREE_OPERAND (t, 1)
11330 = get_initialized_tmp_var (TREE_OPERAND (t, 1),
11331 gimple_seq_empty_p (for_pre_body)
11332 ? pre_p : &for_pre_body, NULL,
11333 false);
11334 /* Reference to pointer conversion is considered useless,
11335 but is significant for firstprivate clause. Force it
11336 here. */
11337 if (TREE_CODE (type) == POINTER_TYPE
11338 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 1)))
11339 == REFERENCE_TYPE))
11341 tree v = create_tmp_var (TYPE_MAIN_VARIANT (type));
11342 tree m = build2 (INIT_EXPR, TREE_TYPE (v), v,
11343 TREE_OPERAND (t, 1));
11344 gimplify_and_add (m, gimple_seq_empty_p (for_pre_body)
11345 ? pre_p : &for_pre_body);
11346 TREE_OPERAND (t, 1) = v;
11348 tree c = build_omp_clause (input_location,
11349 OMP_CLAUSE_FIRSTPRIVATE);
11350 OMP_CLAUSE_DECL (c) = TREE_OPERAND (t, 1);
11351 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
11352 OMP_FOR_CLAUSES (orig_for_stmt) = c;
11355 /* Handle OMP_FOR_COND. */
11356 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
11357 if (!is_gimple_constant (TREE_OPERAND (t, 1)))
11359 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
11360 TREE_OPERAND (t, 1)
11361 = get_initialized_tmp_var (TREE_OPERAND (t, 1),
11362 gimple_seq_empty_p (for_pre_body)
11363 ? pre_p : &for_pre_body, NULL,
11364 false);
11365 /* Reference to pointer conversion is considered useless,
11366 but is significant for firstprivate clause. Force it
11367 here. */
11368 if (TREE_CODE (type) == POINTER_TYPE
11369 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 1)))
11370 == REFERENCE_TYPE))
11372 tree v = create_tmp_var (TYPE_MAIN_VARIANT (type));
11373 tree m = build2 (INIT_EXPR, TREE_TYPE (v), v,
11374 TREE_OPERAND (t, 1));
11375 gimplify_and_add (m, gimple_seq_empty_p (for_pre_body)
11376 ? pre_p : &for_pre_body);
11377 TREE_OPERAND (t, 1) = v;
11379 tree c = build_omp_clause (input_location,
11380 OMP_CLAUSE_FIRSTPRIVATE);
11381 OMP_CLAUSE_DECL (c) = TREE_OPERAND (t, 1);
11382 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
11383 OMP_FOR_CLAUSES (orig_for_stmt) = c;
11386 /* Handle OMP_FOR_INCR. */
11387 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
11388 if (TREE_CODE (t) == MODIFY_EXPR)
11390 decl = TREE_OPERAND (t, 0);
11391 t = TREE_OPERAND (t, 1);
11392 tree *tp = &TREE_OPERAND (t, 1);
11393 if (TREE_CODE (t) == PLUS_EXPR && *tp == decl)
11394 tp = &TREE_OPERAND (t, 0);
11396 if (!is_gimple_constant (*tp))
11398 gimple_seq *seq = gimple_seq_empty_p (for_pre_body)
11399 ? pre_p : &for_pre_body;
11400 *tp = get_initialized_tmp_var (*tp, seq, NULL, false);
11401 tree c = build_omp_clause (input_location,
11402 OMP_CLAUSE_FIRSTPRIVATE);
11403 OMP_CLAUSE_DECL (c) = *tp;
11404 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
11405 OMP_FOR_CLAUSES (orig_for_stmt) = c;
11410 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (orig_for_stmt), pre_p, ort,
11411 OMP_TASKLOOP);
11414 if (orig_for_stmt != for_stmt)
11415 gimplify_omp_ctxp->combined_loop = true;
11417 for_body = NULL;
11418 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
11419 == TREE_VEC_LENGTH (OMP_FOR_COND (for_stmt)));
11420 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
11421 == TREE_VEC_LENGTH (OMP_FOR_INCR (for_stmt)));
11423 tree c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED);
11424 bool is_doacross = false;
11425 if (c && OMP_CLAUSE_ORDERED_EXPR (c))
11427 is_doacross = true;
11428 gimplify_omp_ctxp->loop_iter_var.create (TREE_VEC_LENGTH
11429 (OMP_FOR_INIT (for_stmt))
11430 * 2);
11432 int collapse = 1, tile = 0;
11433 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_COLLAPSE);
11434 if (c)
11435 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (c));
11436 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_TILE);
11437 if (c)
11438 tile = list_length (OMP_CLAUSE_TILE_LIST (c));
11439 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
11441 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
11442 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
11443 decl = TREE_OPERAND (t, 0);
11444 gcc_assert (DECL_P (decl));
11445 gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl))
11446 || POINTER_TYPE_P (TREE_TYPE (decl)));
11447 if (is_doacross)
11449 if (TREE_CODE (for_stmt) == OMP_FOR && OMP_FOR_ORIG_DECLS (for_stmt))
11451 tree orig_decl = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
11452 if (TREE_CODE (orig_decl) == TREE_LIST)
11454 orig_decl = TREE_PURPOSE (orig_decl);
11455 if (!orig_decl)
11456 orig_decl = decl;
11458 gimplify_omp_ctxp->loop_iter_var.quick_push (orig_decl);
11460 else
11461 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
11462 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
11465 /* Make sure the iteration variable is private. */
11466 tree c = NULL_TREE;
11467 tree c2 = NULL_TREE;
11468 if (orig_for_stmt != for_stmt)
11470 /* Preserve this information until we gimplify the inner simd. */
11471 if (has_decl_expr
11472 && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
11473 TREE_PRIVATE (t) = 1;
11475 else if (ort == ORT_SIMD)
11477 splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
11478 (splay_tree_key) decl);
11479 omp_is_private (gimplify_omp_ctxp, decl,
11480 1 + (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
11481 != 1));
11482 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
11484 omp_notice_variable (gimplify_omp_ctxp, decl, true);
11485 if (n->value & GOVD_LASTPRIVATE_CONDITIONAL)
11486 for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
11487 OMP_CLAUSE_LASTPRIVATE);
11488 c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
11489 OMP_CLAUSE_LASTPRIVATE))
11490 if (OMP_CLAUSE_DECL (c3) == decl)
11492 warning_at (OMP_CLAUSE_LOCATION (c3), 0,
11493 "conditional %<lastprivate%> on loop "
11494 "iterator %qD ignored", decl);
11495 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
11496 n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
11499 else if (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1 && !loop_p)
11501 c = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
11502 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
11503 unsigned int flags = GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN;
11504 if ((has_decl_expr
11505 && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
11506 || TREE_PRIVATE (t))
11508 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
11509 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
11511 struct gimplify_omp_ctx *outer
11512 = gimplify_omp_ctxp->outer_context;
11513 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
11515 if (outer->region_type == ORT_WORKSHARE
11516 && outer->combined_loop)
11518 n = splay_tree_lookup (outer->variables,
11519 (splay_tree_key)decl);
11520 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
11522 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
11523 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
11525 else
11527 struct gimplify_omp_ctx *octx = outer->outer_context;
11528 if (octx
11529 && octx->region_type == ORT_COMBINED_PARALLEL
11530 && octx->outer_context
11531 && (octx->outer_context->region_type
11532 == ORT_WORKSHARE)
11533 && octx->outer_context->combined_loop)
11535 octx = octx->outer_context;
11536 n = splay_tree_lookup (octx->variables,
11537 (splay_tree_key)decl);
11538 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
11540 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
11541 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
11548 OMP_CLAUSE_DECL (c) = decl;
11549 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
11550 OMP_FOR_CLAUSES (for_stmt) = c;
11551 omp_add_variable (gimplify_omp_ctxp, decl, flags);
11552 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
11554 if (outer->region_type == ORT_WORKSHARE
11555 && outer->combined_loop)
11557 if (outer->outer_context
11558 && (outer->outer_context->region_type
11559 == ORT_COMBINED_PARALLEL))
11560 outer = outer->outer_context;
11561 else if (omp_check_private (outer, decl, false))
11562 outer = NULL;
11564 else if (((outer->region_type & ORT_TASKLOOP)
11565 == ORT_TASKLOOP)
11566 && outer->combined_loop
11567 && !omp_check_private (gimplify_omp_ctxp,
11568 decl, false))
11570 else if (outer->region_type != ORT_COMBINED_PARALLEL)
11572 omp_notice_variable (outer, decl, true);
11573 outer = NULL;
11575 if (outer)
11577 n = splay_tree_lookup (outer->variables,
11578 (splay_tree_key)decl);
11579 if (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
11581 omp_add_variable (outer, decl,
11582 GOVD_LASTPRIVATE | GOVD_SEEN);
11583 if (outer->region_type == ORT_COMBINED_PARALLEL
11584 && outer->outer_context
11585 && (outer->outer_context->region_type
11586 == ORT_WORKSHARE)
11587 && outer->outer_context->combined_loop)
11589 outer = outer->outer_context;
11590 n = splay_tree_lookup (outer->variables,
11591 (splay_tree_key)decl);
11592 if (omp_check_private (outer, decl, false))
11593 outer = NULL;
11594 else if (n == NULL
11595 || ((n->value & GOVD_DATA_SHARE_CLASS)
11596 == 0))
11597 omp_add_variable (outer, decl,
11598 GOVD_LASTPRIVATE
11599 | GOVD_SEEN);
11600 else
11601 outer = NULL;
11603 if (outer && outer->outer_context
11604 && ((outer->outer_context->region_type
11605 & ORT_COMBINED_TEAMS) == ORT_COMBINED_TEAMS
11606 || (((outer->region_type & ORT_TASKLOOP)
11607 == ORT_TASKLOOP)
11608 && (outer->outer_context->region_type
11609 == ORT_COMBINED_PARALLEL))))
11611 outer = outer->outer_context;
11612 n = splay_tree_lookup (outer->variables,
11613 (splay_tree_key)decl);
11614 if (n == NULL
11615 || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
11616 omp_add_variable (outer, decl,
11617 GOVD_SHARED | GOVD_SEEN);
11618 else
11619 outer = NULL;
11621 if (outer && outer->outer_context)
11622 omp_notice_variable (outer->outer_context, decl,
11623 true);
11628 else
11630 bool lastprivate
11631 = (!has_decl_expr
11632 || !bitmap_bit_p (has_decl_expr, DECL_UID (decl)));
11633 if (TREE_PRIVATE (t))
11634 lastprivate = false;
11635 if (loop_p && OMP_FOR_ORIG_DECLS (for_stmt))
11637 tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
11638 if (TREE_CODE (elt) == TREE_LIST && TREE_PURPOSE (elt))
11639 lastprivate = false;
11642 struct gimplify_omp_ctx *outer
11643 = gimplify_omp_ctxp->outer_context;
11644 if (outer && lastprivate)
11646 if (outer->region_type == ORT_WORKSHARE
11647 && outer->combined_loop)
11649 n = splay_tree_lookup (outer->variables,
11650 (splay_tree_key)decl);
11651 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
11653 lastprivate = false;
11654 outer = NULL;
11656 else if (outer->outer_context
11657 && (outer->outer_context->region_type
11658 == ORT_COMBINED_PARALLEL))
11659 outer = outer->outer_context;
11660 else if (omp_check_private (outer, decl, false))
11661 outer = NULL;
11663 else if (((outer->region_type & ORT_TASKLOOP)
11664 == ORT_TASKLOOP)
11665 && outer->combined_loop
11666 && !omp_check_private (gimplify_omp_ctxp,
11667 decl, false))
11669 else if (outer->region_type != ORT_COMBINED_PARALLEL)
11671 omp_notice_variable (outer, decl, true);
11672 outer = NULL;
11674 if (outer)
11676 n = splay_tree_lookup (outer->variables,
11677 (splay_tree_key)decl);
11678 if (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
11680 omp_add_variable (outer, decl,
11681 GOVD_LASTPRIVATE | GOVD_SEEN);
11682 if (outer->region_type == ORT_COMBINED_PARALLEL
11683 && outer->outer_context
11684 && (outer->outer_context->region_type
11685 == ORT_WORKSHARE)
11686 && outer->outer_context->combined_loop)
11688 outer = outer->outer_context;
11689 n = splay_tree_lookup (outer->variables,
11690 (splay_tree_key)decl);
11691 if (omp_check_private (outer, decl, false))
11692 outer = NULL;
11693 else if (n == NULL
11694 || ((n->value & GOVD_DATA_SHARE_CLASS)
11695 == 0))
11696 omp_add_variable (outer, decl,
11697 GOVD_LASTPRIVATE
11698 | GOVD_SEEN);
11699 else
11700 outer = NULL;
11702 if (outer && outer->outer_context
11703 && ((outer->outer_context->region_type
11704 & ORT_COMBINED_TEAMS) == ORT_COMBINED_TEAMS
11705 || (((outer->region_type & ORT_TASKLOOP)
11706 == ORT_TASKLOOP)
11707 && (outer->outer_context->region_type
11708 == ORT_COMBINED_PARALLEL))))
11710 outer = outer->outer_context;
11711 n = splay_tree_lookup (outer->variables,
11712 (splay_tree_key)decl);
11713 if (n == NULL
11714 || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
11715 omp_add_variable (outer, decl,
11716 GOVD_SHARED | GOVD_SEEN);
11717 else
11718 outer = NULL;
11720 if (outer && outer->outer_context)
11721 omp_notice_variable (outer->outer_context, decl,
11722 true);
11727 c = build_omp_clause (input_location,
11728 lastprivate ? OMP_CLAUSE_LASTPRIVATE
11729 : OMP_CLAUSE_PRIVATE);
11730 OMP_CLAUSE_DECL (c) = decl;
11731 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
11732 OMP_FOR_CLAUSES (for_stmt) = c;
11733 omp_add_variable (gimplify_omp_ctxp, decl,
11734 (lastprivate ? GOVD_LASTPRIVATE : GOVD_PRIVATE)
11735 | GOVD_EXPLICIT | GOVD_SEEN);
11736 c = NULL_TREE;
11739 else if (omp_is_private (gimplify_omp_ctxp, decl, 0))
11741 omp_notice_variable (gimplify_omp_ctxp, decl, true);
11742 splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
11743 (splay_tree_key) decl);
11744 if (n && (n->value & GOVD_LASTPRIVATE_CONDITIONAL))
11745 for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
11746 OMP_CLAUSE_LASTPRIVATE);
11747 c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
11748 OMP_CLAUSE_LASTPRIVATE))
11749 if (OMP_CLAUSE_DECL (c3) == decl)
11751 warning_at (OMP_CLAUSE_LOCATION (c3), 0,
11752 "conditional %<lastprivate%> on loop "
11753 "iterator %qD ignored", decl);
11754 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
11755 n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
11758 else
11759 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN);
11761 /* If DECL is not a gimple register, create a temporary variable to act
11762 as an iteration counter. This is valid, since DECL cannot be
11763 modified in the body of the loop. Similarly for any iteration vars
11764 in simd with collapse > 1 where the iterator vars must be
11765 lastprivate. */
11766 if (orig_for_stmt != for_stmt)
11767 var = decl;
11768 else if (!is_gimple_reg (decl)
11769 || (ort == ORT_SIMD
11770 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) > 1))
11772 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
11773 /* Make sure omp_add_variable is not called on it prematurely.
11774 We call it ourselves a few lines later. */
11775 gimplify_omp_ctxp = NULL;
11776 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
11777 gimplify_omp_ctxp = ctx;
11778 TREE_OPERAND (t, 0) = var;
11780 gimplify_seq_add_stmt (&for_body, gimple_build_assign (decl, var));
11782 if (ort == ORT_SIMD
11783 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
11785 c2 = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
11786 OMP_CLAUSE_LINEAR_NO_COPYIN (c2) = 1;
11787 OMP_CLAUSE_LINEAR_NO_COPYOUT (c2) = 1;
11788 OMP_CLAUSE_DECL (c2) = var;
11789 OMP_CLAUSE_CHAIN (c2) = OMP_FOR_CLAUSES (for_stmt);
11790 OMP_FOR_CLAUSES (for_stmt) = c2;
11791 omp_add_variable (gimplify_omp_ctxp, var,
11792 GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN);
11793 if (c == NULL_TREE)
11795 c = c2;
11796 c2 = NULL_TREE;
11799 else
11800 omp_add_variable (gimplify_omp_ctxp, var,
11801 GOVD_PRIVATE | GOVD_SEEN);
11803 else
11804 var = decl;
11806 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
11807 is_gimple_val, fb_rvalue, false);
11808 ret = MIN (ret, tret);
11809 if (ret == GS_ERROR)
11810 return ret;
11812 /* Handle OMP_FOR_COND. */
11813 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
11814 gcc_assert (COMPARISON_CLASS_P (t));
11815 gcc_assert (TREE_OPERAND (t, 0) == decl);
11817 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
11818 is_gimple_val, fb_rvalue, false);
11819 ret = MIN (ret, tret);
11821 /* Handle OMP_FOR_INCR. */
11822 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
11823 switch (TREE_CODE (t))
11825 case PREINCREMENT_EXPR:
11826 case POSTINCREMENT_EXPR:
11828 tree decl = TREE_OPERAND (t, 0);
11829 /* c_omp_for_incr_canonicalize_ptr() should have been
11830 called to massage things appropriately. */
11831 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
11833 if (orig_for_stmt != for_stmt)
11834 break;
11835 t = build_int_cst (TREE_TYPE (decl), 1);
11836 if (c)
11837 OMP_CLAUSE_LINEAR_STEP (c) = t;
11838 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
11839 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
11840 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
11841 break;
11844 case PREDECREMENT_EXPR:
11845 case POSTDECREMENT_EXPR:
11846 /* c_omp_for_incr_canonicalize_ptr() should have been
11847 called to massage things appropriately. */
11848 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
11849 if (orig_for_stmt != for_stmt)
11850 break;
11851 t = build_int_cst (TREE_TYPE (decl), -1);
11852 if (c)
11853 OMP_CLAUSE_LINEAR_STEP (c) = t;
11854 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
11855 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
11856 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
11857 break;
11859 case MODIFY_EXPR:
11860 gcc_assert (TREE_OPERAND (t, 0) == decl);
11861 TREE_OPERAND (t, 0) = var;
11863 t = TREE_OPERAND (t, 1);
11864 switch (TREE_CODE (t))
11866 case PLUS_EXPR:
11867 if (TREE_OPERAND (t, 1) == decl)
11869 TREE_OPERAND (t, 1) = TREE_OPERAND (t, 0);
11870 TREE_OPERAND (t, 0) = var;
11871 break;
11874 /* Fallthru. */
11875 case MINUS_EXPR:
11876 case POINTER_PLUS_EXPR:
11877 gcc_assert (TREE_OPERAND (t, 0) == decl);
11878 TREE_OPERAND (t, 0) = var;
11879 break;
11880 default:
11881 gcc_unreachable ();
11884 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
11885 is_gimple_val, fb_rvalue, false);
11886 ret = MIN (ret, tret);
11887 if (c)
11889 tree step = TREE_OPERAND (t, 1);
11890 tree stept = TREE_TYPE (decl);
11891 if (POINTER_TYPE_P (stept))
11892 stept = sizetype;
11893 step = fold_convert (stept, step);
11894 if (TREE_CODE (t) == MINUS_EXPR)
11895 step = fold_build1 (NEGATE_EXPR, stept, step);
11896 OMP_CLAUSE_LINEAR_STEP (c) = step;
11897 if (step != TREE_OPERAND (t, 1))
11899 tret = gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c),
11900 &for_pre_body, NULL,
11901 is_gimple_val, fb_rvalue, false);
11902 ret = MIN (ret, tret);
11905 break;
11907 default:
11908 gcc_unreachable ();
11911 if (c2)
11913 gcc_assert (c);
11914 OMP_CLAUSE_LINEAR_STEP (c2) = OMP_CLAUSE_LINEAR_STEP (c);
11917 if ((var != decl || collapse > 1 || tile) && orig_for_stmt == for_stmt)
11919 for (c = OMP_FOR_CLAUSES (for_stmt); c ; c = OMP_CLAUSE_CHAIN (c))
11920 if (((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
11921 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) == NULL)
11922 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
11923 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)
11924 && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c) == NULL))
11925 && OMP_CLAUSE_DECL (c) == decl)
11927 if (is_doacross && (collapse == 1 || i >= collapse))
11928 t = var;
11929 else
11931 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
11932 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
11933 gcc_assert (TREE_OPERAND (t, 0) == var);
11934 t = TREE_OPERAND (t, 1);
11935 gcc_assert (TREE_CODE (t) == PLUS_EXPR
11936 || TREE_CODE (t) == MINUS_EXPR
11937 || TREE_CODE (t) == POINTER_PLUS_EXPR);
11938 gcc_assert (TREE_OPERAND (t, 0) == var);
11939 t = build2 (TREE_CODE (t), TREE_TYPE (decl),
11940 is_doacross ? var : decl,
11941 TREE_OPERAND (t, 1));
11943 gimple_seq *seq;
11944 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
11945 seq = &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c);
11946 else
11947 seq = &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c);
11948 push_gimplify_context ();
11949 gimplify_assign (decl, t, seq);
11950 gimple *bind = NULL;
11951 if (gimplify_ctxp->temps)
11953 bind = gimple_build_bind (NULL_TREE, *seq, NULL_TREE);
11954 *seq = NULL;
11955 gimplify_seq_add_stmt (seq, bind);
11957 pop_gimplify_context (bind);
11962 BITMAP_FREE (has_decl_expr);
11964 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP
11965 || (loop_p && orig_for_stmt == for_stmt))
11967 push_gimplify_context ();
11968 if (TREE_CODE (OMP_FOR_BODY (orig_for_stmt)) != BIND_EXPR)
11970 OMP_FOR_BODY (orig_for_stmt)
11971 = build3 (BIND_EXPR, void_type_node, NULL,
11972 OMP_FOR_BODY (orig_for_stmt), NULL);
11973 TREE_SIDE_EFFECTS (OMP_FOR_BODY (orig_for_stmt)) = 1;
11977 gimple *g = gimplify_and_return_first (OMP_FOR_BODY (orig_for_stmt),
11978 &for_body);
11980 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP
11981 || (loop_p && orig_for_stmt == for_stmt))
11983 if (gimple_code (g) == GIMPLE_BIND)
11984 pop_gimplify_context (g);
11985 else
11986 pop_gimplify_context (NULL);
11989 if (orig_for_stmt != for_stmt)
11990 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
11992 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
11993 decl = TREE_OPERAND (t, 0);
11994 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
11995 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
11996 gimplify_omp_ctxp = ctx->outer_context;
11997 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
11998 gimplify_omp_ctxp = ctx;
11999 omp_add_variable (gimplify_omp_ctxp, var, GOVD_PRIVATE | GOVD_SEEN);
12000 TREE_OPERAND (t, 0) = var;
12001 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
12002 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
12003 TREE_OPERAND (TREE_OPERAND (t, 1), 0) = var;
12006 gimplify_adjust_omp_clauses (pre_p, for_body,
12007 &OMP_FOR_CLAUSES (orig_for_stmt),
12008 TREE_CODE (orig_for_stmt));
12010 int kind;
12011 switch (TREE_CODE (orig_for_stmt))
12013 case OMP_FOR: kind = GF_OMP_FOR_KIND_FOR; break;
12014 case OMP_SIMD: kind = GF_OMP_FOR_KIND_SIMD; break;
12015 case OMP_DISTRIBUTE: kind = GF_OMP_FOR_KIND_DISTRIBUTE; break;
12016 case OMP_TASKLOOP: kind = GF_OMP_FOR_KIND_TASKLOOP; break;
12017 case OACC_LOOP: kind = GF_OMP_FOR_KIND_OACC_LOOP; break;
12018 default:
12019 gcc_unreachable ();
12021 if (loop_p && kind == GF_OMP_FOR_KIND_SIMD)
12023 gimplify_seq_add_seq (pre_p, for_pre_body);
12024 for_pre_body = NULL;
12026 gfor = gimple_build_omp_for (for_body, kind, OMP_FOR_CLAUSES (orig_for_stmt),
12027 TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)),
12028 for_pre_body);
12029 if (orig_for_stmt != for_stmt)
12030 gimple_omp_for_set_combined_p (gfor, true);
12031 if (gimplify_omp_ctxp
12032 && (gimplify_omp_ctxp->combined_loop
12033 || (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
12034 && gimplify_omp_ctxp->outer_context
12035 && gimplify_omp_ctxp->outer_context->combined_loop)))
12037 gimple_omp_for_set_combined_into_p (gfor, true);
12038 if (gimplify_omp_ctxp->combined_loop)
12039 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_SIMD);
12040 else
12041 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_FOR);
12044 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
12046 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
12047 gimple_omp_for_set_index (gfor, i, TREE_OPERAND (t, 0));
12048 gimple_omp_for_set_initial (gfor, i, TREE_OPERAND (t, 1));
12049 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
12050 gimple_omp_for_set_cond (gfor, i, TREE_CODE (t));
12051 gimple_omp_for_set_final (gfor, i, TREE_OPERAND (t, 1));
12052 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
12053 gimple_omp_for_set_incr (gfor, i, TREE_OPERAND (t, 1));
12056 /* OMP_TASKLOOP is gimplified as two GIMPLE_OMP_FOR taskloop
12057 constructs with GIMPLE_OMP_TASK sandwiched in between them.
12058 The outer taskloop stands for computing the number of iterations,
12059 counts for collapsed loops and holding taskloop specific clauses.
12060 The task construct stands for the effect of data sharing on the
12061 explicit task it creates and the inner taskloop stands for expansion
12062 of the static loop inside of the explicit task construct. */
12063 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
12065 tree *gfor_clauses_ptr = gimple_omp_for_clauses_ptr (gfor);
12066 tree task_clauses = NULL_TREE;
12067 tree c = *gfor_clauses_ptr;
12068 tree *gtask_clauses_ptr = &task_clauses;
12069 tree outer_for_clauses = NULL_TREE;
12070 tree *gforo_clauses_ptr = &outer_for_clauses;
12071 for (; c; c = OMP_CLAUSE_CHAIN (c))
12072 switch (OMP_CLAUSE_CODE (c))
12074 /* These clauses are allowed on task, move them there. */
12075 case OMP_CLAUSE_SHARED:
12076 case OMP_CLAUSE_FIRSTPRIVATE:
12077 case OMP_CLAUSE_DEFAULT:
12078 case OMP_CLAUSE_IF:
12079 case OMP_CLAUSE_UNTIED:
12080 case OMP_CLAUSE_FINAL:
12081 case OMP_CLAUSE_MERGEABLE:
12082 case OMP_CLAUSE_PRIORITY:
12083 case OMP_CLAUSE_REDUCTION:
12084 case OMP_CLAUSE_IN_REDUCTION:
12085 *gtask_clauses_ptr = c;
12086 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12087 break;
12088 case OMP_CLAUSE_PRIVATE:
12089 if (OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c))
12091 /* We want private on outer for and firstprivate
12092 on task. */
12093 *gtask_clauses_ptr
12094 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
12095 OMP_CLAUSE_FIRSTPRIVATE);
12096 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
12097 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL);
12098 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
12099 *gforo_clauses_ptr = c;
12100 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12102 else
12104 *gtask_clauses_ptr = c;
12105 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12107 break;
12108 /* These clauses go into outer taskloop clauses. */
12109 case OMP_CLAUSE_GRAINSIZE:
12110 case OMP_CLAUSE_NUM_TASKS:
12111 case OMP_CLAUSE_NOGROUP:
12112 *gforo_clauses_ptr = c;
12113 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12114 break;
12115 /* Taskloop clause we duplicate on both taskloops. */
12116 case OMP_CLAUSE_COLLAPSE:
12117 *gfor_clauses_ptr = c;
12118 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12119 *gforo_clauses_ptr = copy_node (c);
12120 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
12121 break;
12122 /* For lastprivate, keep the clause on inner taskloop, and add
12123 a shared clause on task. If the same decl is also firstprivate,
12124 add also firstprivate clause on the inner taskloop. */
12125 case OMP_CLAUSE_LASTPRIVATE:
12126 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
12128 /* For taskloop C++ lastprivate IVs, we want:
12129 1) private on outer taskloop
12130 2) firstprivate and shared on task
12131 3) lastprivate on inner taskloop */
12132 *gtask_clauses_ptr
12133 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
12134 OMP_CLAUSE_FIRSTPRIVATE);
12135 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
12136 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL);
12137 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
12138 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c) = 1;
12139 *gforo_clauses_ptr = build_omp_clause (OMP_CLAUSE_LOCATION (c),
12140 OMP_CLAUSE_PRIVATE);
12141 OMP_CLAUSE_DECL (*gforo_clauses_ptr) = OMP_CLAUSE_DECL (c);
12142 OMP_CLAUSE_PRIVATE_TASKLOOP_IV (*gforo_clauses_ptr) = 1;
12143 TREE_TYPE (*gforo_clauses_ptr) = TREE_TYPE (c);
12144 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
12146 *gfor_clauses_ptr = c;
12147 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12148 *gtask_clauses_ptr
12149 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_SHARED);
12150 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
12151 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
12152 OMP_CLAUSE_SHARED_FIRSTPRIVATE (*gtask_clauses_ptr) = 1;
12153 gtask_clauses_ptr
12154 = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
12155 break;
12156 default:
12157 gcc_unreachable ();
12159 *gfor_clauses_ptr = NULL_TREE;
12160 *gtask_clauses_ptr = NULL_TREE;
12161 *gforo_clauses_ptr = NULL_TREE;
12162 g = gimple_build_bind (NULL_TREE, gfor, NULL_TREE);
12163 g = gimple_build_omp_task (g, task_clauses, NULL_TREE, NULL_TREE,
12164 NULL_TREE, NULL_TREE, NULL_TREE);
12165 gimple_omp_task_set_taskloop_p (g, true);
12166 g = gimple_build_bind (NULL_TREE, g, NULL_TREE);
12167 gomp_for *gforo
12168 = gimple_build_omp_for (g, GF_OMP_FOR_KIND_TASKLOOP, outer_for_clauses,
12169 gimple_omp_for_collapse (gfor),
12170 gimple_omp_for_pre_body (gfor));
12171 gimple_omp_for_set_pre_body (gfor, NULL);
12172 gimple_omp_for_set_combined_p (gforo, true);
12173 gimple_omp_for_set_combined_into_p (gfor, true);
12174 for (i = 0; i < (int) gimple_omp_for_collapse (gfor); i++)
12176 tree type = TREE_TYPE (gimple_omp_for_index (gfor, i));
12177 tree v = create_tmp_var (type);
12178 gimple_omp_for_set_index (gforo, i, v);
12179 t = unshare_expr (gimple_omp_for_initial (gfor, i));
12180 gimple_omp_for_set_initial (gforo, i, t);
12181 gimple_omp_for_set_cond (gforo, i,
12182 gimple_omp_for_cond (gfor, i));
12183 t = unshare_expr (gimple_omp_for_final (gfor, i));
12184 gimple_omp_for_set_final (gforo, i, t);
12185 t = unshare_expr (gimple_omp_for_incr (gfor, i));
12186 gcc_assert (TREE_OPERAND (t, 0) == gimple_omp_for_index (gfor, i));
12187 TREE_OPERAND (t, 0) = v;
12188 gimple_omp_for_set_incr (gforo, i, t);
12189 t = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
12190 OMP_CLAUSE_DECL (t) = v;
12191 OMP_CLAUSE_CHAIN (t) = gimple_omp_for_clauses (gforo);
12192 gimple_omp_for_set_clauses (gforo, t);
12194 gimplify_seq_add_stmt (pre_p, gforo);
12196 else
12197 gimplify_seq_add_stmt (pre_p, gfor);
12199 if (TREE_CODE (orig_for_stmt) == OMP_FOR)
12201 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
12202 unsigned lastprivate_conditional = 0;
12203 while (ctx
12204 && (ctx->region_type == ORT_TARGET_DATA
12205 || ctx->region_type == ORT_TASKGROUP))
12206 ctx = ctx->outer_context;
12207 if (ctx && (ctx->region_type & ORT_PARALLEL) != 0)
12208 for (tree c = gimple_omp_for_clauses (gfor);
12209 c; c = OMP_CLAUSE_CHAIN (c))
12210 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
12211 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
12212 ++lastprivate_conditional;
12213 if (lastprivate_conditional)
12215 struct omp_for_data fd;
12216 omp_extract_for_data (gfor, &fd, NULL);
12217 tree type = build_array_type_nelts (unsigned_type_for (fd.iter_type),
12218 lastprivate_conditional);
12219 tree var = create_tmp_var_raw (type);
12220 tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__CONDTEMP_);
12221 OMP_CLAUSE_DECL (c) = var;
12222 OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor);
12223 gimple_omp_for_set_clauses (gfor, c);
12224 omp_add_variable (ctx, var, GOVD_CONDTEMP | GOVD_SEEN);
12227 else if (TREE_CODE (orig_for_stmt) == OMP_SIMD)
12229 unsigned lastprivate_conditional = 0;
12230 for (tree c = gimple_omp_for_clauses (gfor); c; c = OMP_CLAUSE_CHAIN (c))
12231 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
12232 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
12233 ++lastprivate_conditional;
12234 if (lastprivate_conditional)
12236 struct omp_for_data fd;
12237 omp_extract_for_data (gfor, &fd, NULL);
12238 tree type = unsigned_type_for (fd.iter_type);
12239 while (lastprivate_conditional--)
12241 tree c = build_omp_clause (UNKNOWN_LOCATION,
12242 OMP_CLAUSE__CONDTEMP_);
12243 OMP_CLAUSE_DECL (c) = create_tmp_var (type);
12244 OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor);
12245 gimple_omp_for_set_clauses (gfor, c);
12250 if (ret != GS_ALL_DONE)
12251 return GS_ERROR;
12252 *expr_p = NULL_TREE;
12253 return GS_ALL_DONE;
12256 /* Helper for gimplify_omp_loop, called through walk_tree. */
12258 static tree
12259 replace_reduction_placeholders (tree *tp, int *walk_subtrees, void *data)
12261 if (DECL_P (*tp))
12263 tree *d = (tree *) data;
12264 if (*tp == OMP_CLAUSE_REDUCTION_PLACEHOLDER (d[0]))
12266 *tp = OMP_CLAUSE_REDUCTION_PLACEHOLDER (d[1]);
12267 *walk_subtrees = 0;
12269 else if (*tp == OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (d[0]))
12271 *tp = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (d[1]);
12272 *walk_subtrees = 0;
12275 return NULL_TREE;
12278 /* Gimplify the gross structure of an OMP_LOOP statement. */
12280 static enum gimplify_status
12281 gimplify_omp_loop (tree *expr_p, gimple_seq *pre_p)
12283 tree for_stmt = *expr_p;
12284 tree clauses = OMP_FOR_CLAUSES (for_stmt);
12285 struct gimplify_omp_ctx *octx = gimplify_omp_ctxp;
12286 enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
12287 int i;
12289 /* If order is not present, the behavior is as if order(concurrent)
12290 appeared. */
12291 tree order = omp_find_clause (clauses, OMP_CLAUSE_ORDER);
12292 if (order == NULL_TREE)
12294 order = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_ORDER);
12295 OMP_CLAUSE_CHAIN (order) = clauses;
12296 OMP_FOR_CLAUSES (for_stmt) = clauses = order;
12299 tree bind = omp_find_clause (clauses, OMP_CLAUSE_BIND);
12300 if (bind == NULL_TREE)
12302 if (!flag_openmp) /* flag_openmp_simd */
12304 else if (octx && (octx->region_type & ORT_TEAMS) != 0)
12305 kind = OMP_CLAUSE_BIND_TEAMS;
12306 else if (octx && (octx->region_type & ORT_PARALLEL) != 0)
12307 kind = OMP_CLAUSE_BIND_PARALLEL;
12308 else
12310 for (; octx; octx = octx->outer_context)
12312 if ((octx->region_type & ORT_ACC) != 0
12313 || octx->region_type == ORT_NONE
12314 || octx->region_type == ORT_IMPLICIT_TARGET)
12315 continue;
12316 break;
12318 if (octx == NULL && !in_omp_construct)
12319 error_at (EXPR_LOCATION (for_stmt),
12320 "%<bind%> clause not specified on a %<loop%> "
12321 "construct not nested inside another OpenMP construct");
12323 bind = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_BIND);
12324 OMP_CLAUSE_CHAIN (bind) = clauses;
12325 OMP_CLAUSE_BIND_KIND (bind) = kind;
12326 OMP_FOR_CLAUSES (for_stmt) = bind;
12328 else
12329 switch (OMP_CLAUSE_BIND_KIND (bind))
12331 case OMP_CLAUSE_BIND_THREAD:
12332 break;
12333 case OMP_CLAUSE_BIND_PARALLEL:
12334 if (!flag_openmp) /* flag_openmp_simd */
12336 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
12337 break;
12339 for (; octx; octx = octx->outer_context)
12340 if (octx->region_type == ORT_SIMD
12341 && omp_find_clause (octx->clauses, OMP_CLAUSE_BIND) == NULL_TREE)
12343 error_at (EXPR_LOCATION (for_stmt),
12344 "%<bind(parallel)%> on a %<loop%> construct nested "
12345 "inside %<simd%> construct");
12346 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
12347 break;
12349 kind = OMP_CLAUSE_BIND_PARALLEL;
12350 break;
12351 case OMP_CLAUSE_BIND_TEAMS:
12352 if (!flag_openmp) /* flag_openmp_simd */
12354 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
12355 break;
12357 if ((octx
12358 && octx->region_type != ORT_IMPLICIT_TARGET
12359 && octx->region_type != ORT_NONE
12360 && (octx->region_type & ORT_TEAMS) == 0)
12361 || in_omp_construct)
12363 error_at (EXPR_LOCATION (for_stmt),
12364 "%<bind(teams)%> on a %<loop%> region not strictly "
12365 "nested inside of a %<teams%> region");
12366 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
12367 break;
12369 kind = OMP_CLAUSE_BIND_TEAMS;
12370 break;
12371 default:
12372 gcc_unreachable ();
12375 for (tree *pc = &OMP_FOR_CLAUSES (for_stmt); *pc; )
12376 switch (OMP_CLAUSE_CODE (*pc))
12378 case OMP_CLAUSE_REDUCTION:
12379 if (OMP_CLAUSE_REDUCTION_INSCAN (*pc))
12381 error_at (OMP_CLAUSE_LOCATION (*pc),
12382 "%<inscan%> %<reduction%> clause on "
12383 "%qs construct", "loop");
12384 OMP_CLAUSE_REDUCTION_INSCAN (*pc) = 0;
12386 if (OMP_CLAUSE_REDUCTION_TASK (*pc))
12388 error_at (OMP_CLAUSE_LOCATION (*pc),
12389 "invalid %<task%> reduction modifier on construct "
12390 "other than %<parallel%>, %<for%> or %<sections%>");
12391 OMP_CLAUSE_REDUCTION_TASK (*pc) = 0;
12393 pc = &OMP_CLAUSE_CHAIN (*pc);
12394 break;
12395 case OMP_CLAUSE_LASTPRIVATE:
12396 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
12398 tree t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
12399 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
12400 if (OMP_CLAUSE_DECL (*pc) == TREE_OPERAND (t, 0))
12401 break;
12402 if (OMP_FOR_ORIG_DECLS (for_stmt)
12403 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt),
12404 i)) == TREE_LIST
12405 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt),
12406 i)))
12408 tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
12409 if (OMP_CLAUSE_DECL (*pc) == TREE_PURPOSE (orig))
12410 break;
12413 if (i == TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)))
12415 error_at (OMP_CLAUSE_LOCATION (*pc),
12416 "%<lastprivate%> clause on a %<loop%> construct refers "
12417 "to a variable %qD which is not the loop iterator",
12418 OMP_CLAUSE_DECL (*pc));
12419 *pc = OMP_CLAUSE_CHAIN (*pc);
12420 break;
12422 pc = &OMP_CLAUSE_CHAIN (*pc);
12423 break;
12424 default:
12425 pc = &OMP_CLAUSE_CHAIN (*pc);
12426 break;
12429 TREE_SET_CODE (for_stmt, OMP_SIMD);
12431 int last;
12432 switch (kind)
12434 case OMP_CLAUSE_BIND_THREAD: last = 0; break;
12435 case OMP_CLAUSE_BIND_PARALLEL: last = 1; break;
12436 case OMP_CLAUSE_BIND_TEAMS: last = 2; break;
12438 for (int pass = 1; pass <= last; pass++)
12440 if (pass == 2)
12442 tree bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
12443 append_to_statement_list (*expr_p, &BIND_EXPR_BODY (bind));
12444 *expr_p = make_node (OMP_PARALLEL);
12445 TREE_TYPE (*expr_p) = void_type_node;
12446 OMP_PARALLEL_BODY (*expr_p) = bind;
12447 OMP_PARALLEL_COMBINED (*expr_p) = 1;
12448 SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (for_stmt));
12449 tree *pc = &OMP_PARALLEL_CLAUSES (*expr_p);
12450 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
12451 if (OMP_FOR_ORIG_DECLS (for_stmt)
12452 && (TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i))
12453 == TREE_LIST))
12455 tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
12456 if (TREE_PURPOSE (elt) && TREE_VALUE (elt))
12458 *pc = build_omp_clause (UNKNOWN_LOCATION,
12459 OMP_CLAUSE_FIRSTPRIVATE);
12460 OMP_CLAUSE_DECL (*pc) = TREE_VALUE (elt);
12461 pc = &OMP_CLAUSE_CHAIN (*pc);
12465 tree t = make_node (pass == 2 ? OMP_DISTRIBUTE : OMP_FOR);
12466 tree *pc = &OMP_FOR_CLAUSES (t);
12467 TREE_TYPE (t) = void_type_node;
12468 OMP_FOR_BODY (t) = *expr_p;
12469 SET_EXPR_LOCATION (t, EXPR_LOCATION (for_stmt));
12470 for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
12471 switch (OMP_CLAUSE_CODE (c))
12473 case OMP_CLAUSE_BIND:
12474 case OMP_CLAUSE_ORDER:
12475 case OMP_CLAUSE_COLLAPSE:
12476 *pc = copy_node (c);
12477 pc = &OMP_CLAUSE_CHAIN (*pc);
12478 break;
12479 case OMP_CLAUSE_PRIVATE:
12480 case OMP_CLAUSE_FIRSTPRIVATE:
12481 /* Only needed on innermost. */
12482 break;
12483 case OMP_CLAUSE_LASTPRIVATE:
12484 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c) && pass != last)
12486 *pc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
12487 OMP_CLAUSE_FIRSTPRIVATE);
12488 OMP_CLAUSE_DECL (*pc) = OMP_CLAUSE_DECL (c);
12489 lang_hooks.decls.omp_finish_clause (*pc, NULL);
12490 pc = &OMP_CLAUSE_CHAIN (*pc);
12492 *pc = copy_node (c);
12493 OMP_CLAUSE_LASTPRIVATE_STMT (*pc) = NULL_TREE;
12494 TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
12495 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
12497 if (pass != last)
12498 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (*pc) = 1;
12499 else
12500 lang_hooks.decls.omp_finish_clause (*pc, NULL);
12501 OMP_CLAUSE_LASTPRIVATE_LOOP_IV (*pc) = 0;
12503 pc = &OMP_CLAUSE_CHAIN (*pc);
12504 break;
12505 case OMP_CLAUSE_REDUCTION:
12506 *pc = copy_node (c);
12507 OMP_CLAUSE_DECL (*pc) = unshare_expr (OMP_CLAUSE_DECL (c));
12508 TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
12509 OMP_CLAUSE_REDUCTION_INIT (*pc)
12510 = unshare_expr (OMP_CLAUSE_REDUCTION_INIT (c));
12511 OMP_CLAUSE_REDUCTION_MERGE (*pc)
12512 = unshare_expr (OMP_CLAUSE_REDUCTION_MERGE (c));
12513 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc))
12515 OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc)
12516 = copy_node (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c));
12517 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc))
12518 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc)
12519 = copy_node (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c));
12520 tree nc = *pc;
12521 tree data[2] = { c, nc };
12522 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_INIT (nc),
12523 replace_reduction_placeholders,
12524 data);
12525 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_MERGE (nc),
12526 replace_reduction_placeholders,
12527 data);
12529 pc = &OMP_CLAUSE_CHAIN (*pc);
12530 break;
12531 default:
12532 gcc_unreachable ();
12534 *pc = NULL_TREE;
12535 *expr_p = t;
12537 return gimplify_omp_for (expr_p, pre_p);
12541 /* Helper function of optimize_target_teams, find OMP_TEAMS inside
12542 of OMP_TARGET's body. */
12544 static tree
12545 find_omp_teams (tree *tp, int *walk_subtrees, void *)
12547 *walk_subtrees = 0;
12548 switch (TREE_CODE (*tp))
12550 case OMP_TEAMS:
12551 return *tp;
12552 case BIND_EXPR:
12553 case STATEMENT_LIST:
12554 *walk_subtrees = 1;
12555 break;
12556 default:
12557 break;
12559 return NULL_TREE;
12562 /* Helper function of optimize_target_teams, determine if the expression
12563 can be computed safely before the target construct on the host. */
12565 static tree
12566 computable_teams_clause (tree *tp, int *walk_subtrees, void *)
12568 splay_tree_node n;
12570 if (TYPE_P (*tp))
12572 *walk_subtrees = 0;
12573 return NULL_TREE;
12575 switch (TREE_CODE (*tp))
12577 case VAR_DECL:
12578 case PARM_DECL:
12579 case RESULT_DECL:
12580 *walk_subtrees = 0;
12581 if (error_operand_p (*tp)
12582 || !INTEGRAL_TYPE_P (TREE_TYPE (*tp))
12583 || DECL_HAS_VALUE_EXPR_P (*tp)
12584 || DECL_THREAD_LOCAL_P (*tp)
12585 || TREE_SIDE_EFFECTS (*tp)
12586 || TREE_THIS_VOLATILE (*tp))
12587 return *tp;
12588 if (is_global_var (*tp)
12589 && (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (*tp))
12590 || lookup_attribute ("omp declare target link",
12591 DECL_ATTRIBUTES (*tp))))
12592 return *tp;
12593 if (VAR_P (*tp)
12594 && !DECL_SEEN_IN_BIND_EXPR_P (*tp)
12595 && !is_global_var (*tp)
12596 && decl_function_context (*tp) == current_function_decl)
12597 return *tp;
12598 n = splay_tree_lookup (gimplify_omp_ctxp->variables,
12599 (splay_tree_key) *tp);
12600 if (n == NULL)
12602 if (gimplify_omp_ctxp->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE)
12603 return NULL_TREE;
12604 return *tp;
12606 else if (n->value & GOVD_LOCAL)
12607 return *tp;
12608 else if (n->value & GOVD_FIRSTPRIVATE)
12609 return NULL_TREE;
12610 else if ((n->value & (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
12611 == (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
12612 return NULL_TREE;
12613 return *tp;
12614 case INTEGER_CST:
12615 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
12616 return *tp;
12617 return NULL_TREE;
12618 case TARGET_EXPR:
12619 if (TARGET_EXPR_INITIAL (*tp)
12620 || TREE_CODE (TARGET_EXPR_SLOT (*tp)) != VAR_DECL)
12621 return *tp;
12622 return computable_teams_clause (&TARGET_EXPR_SLOT (*tp),
12623 walk_subtrees, NULL);
12624 /* Allow some reasonable subset of integral arithmetics. */
12625 case PLUS_EXPR:
12626 case MINUS_EXPR:
12627 case MULT_EXPR:
12628 case TRUNC_DIV_EXPR:
12629 case CEIL_DIV_EXPR:
12630 case FLOOR_DIV_EXPR:
12631 case ROUND_DIV_EXPR:
12632 case TRUNC_MOD_EXPR:
12633 case CEIL_MOD_EXPR:
12634 case FLOOR_MOD_EXPR:
12635 case ROUND_MOD_EXPR:
12636 case RDIV_EXPR:
12637 case EXACT_DIV_EXPR:
12638 case MIN_EXPR:
12639 case MAX_EXPR:
12640 case LSHIFT_EXPR:
12641 case RSHIFT_EXPR:
12642 case BIT_IOR_EXPR:
12643 case BIT_XOR_EXPR:
12644 case BIT_AND_EXPR:
12645 case NEGATE_EXPR:
12646 case ABS_EXPR:
12647 case BIT_NOT_EXPR:
12648 case NON_LVALUE_EXPR:
12649 CASE_CONVERT:
12650 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
12651 return *tp;
12652 return NULL_TREE;
12653 /* And disallow anything else, except for comparisons. */
12654 default:
12655 if (COMPARISON_CLASS_P (*tp))
12656 return NULL_TREE;
12657 return *tp;
12661 /* Try to determine if the num_teams and/or thread_limit expressions
12662 can have their values determined already before entering the
12663 target construct.
12664 INTEGER_CSTs trivially are,
12665 integral decls that are firstprivate (explicitly or implicitly)
12666 or explicitly map(always, to:) or map(always, tofrom:) on the target
12667 region too, and expressions involving simple arithmetics on those
12668 too, function calls are not ok, dereferencing something neither etc.
12669 Add NUM_TEAMS and THREAD_LIMIT clauses to the OMP_CLAUSES of
12670 EXPR based on what we find:
12671 0 stands for clause not specified at all, use implementation default
12672 -1 stands for value that can't be determined easily before entering
12673 the target construct.
12674 If teams construct is not present at all, use 1 for num_teams
12675 and 0 for thread_limit (only one team is involved, and the thread
12676 limit is implementation defined. */
12678 static void
12679 optimize_target_teams (tree target, gimple_seq *pre_p)
12681 tree body = OMP_BODY (target);
12682 tree teams = walk_tree (&body, find_omp_teams, NULL, NULL);
12683 tree num_teams = integer_zero_node;
12684 tree thread_limit = integer_zero_node;
12685 location_t num_teams_loc = EXPR_LOCATION (target);
12686 location_t thread_limit_loc = EXPR_LOCATION (target);
12687 tree c, *p, expr;
12688 struct gimplify_omp_ctx *target_ctx = gimplify_omp_ctxp;
12690 if (teams == NULL_TREE)
12691 num_teams = integer_one_node;
12692 else
12693 for (c = OMP_TEAMS_CLAUSES (teams); c; c = OMP_CLAUSE_CHAIN (c))
12695 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS)
12697 p = &num_teams;
12698 num_teams_loc = OMP_CLAUSE_LOCATION (c);
12700 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
12702 p = &thread_limit;
12703 thread_limit_loc = OMP_CLAUSE_LOCATION (c);
12705 else
12706 continue;
12707 expr = OMP_CLAUSE_OPERAND (c, 0);
12708 if (TREE_CODE (expr) == INTEGER_CST)
12710 *p = expr;
12711 continue;
12713 if (walk_tree (&expr, computable_teams_clause, NULL, NULL))
12715 *p = integer_minus_one_node;
12716 continue;
12718 *p = expr;
12719 gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
12720 if (gimplify_expr (p, pre_p, NULL, is_gimple_val, fb_rvalue, false)
12721 == GS_ERROR)
12723 gimplify_omp_ctxp = target_ctx;
12724 *p = integer_minus_one_node;
12725 continue;
12727 gimplify_omp_ctxp = target_ctx;
12728 if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR)
12729 OMP_CLAUSE_OPERAND (c, 0) = *p;
12731 c = build_omp_clause (thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
12732 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = thread_limit;
12733 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
12734 OMP_TARGET_CLAUSES (target) = c;
12735 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
12736 OMP_CLAUSE_NUM_TEAMS_EXPR (c) = num_teams;
12737 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
12738 OMP_TARGET_CLAUSES (target) = c;
12741 /* Gimplify the gross structure of several OMP constructs. */
12743 static void
12744 gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
12746 tree expr = *expr_p;
12747 gimple *stmt;
12748 gimple_seq body = NULL;
12749 enum omp_region_type ort;
12751 switch (TREE_CODE (expr))
12753 case OMP_SECTIONS:
12754 case OMP_SINGLE:
12755 ort = ORT_WORKSHARE;
12756 break;
12757 case OMP_TARGET:
12758 ort = OMP_TARGET_COMBINED (expr) ? ORT_COMBINED_TARGET : ORT_TARGET;
12759 break;
12760 case OACC_KERNELS:
12761 ort = ORT_ACC_KERNELS;
12762 break;
12763 case OACC_PARALLEL:
12764 ort = ORT_ACC_PARALLEL;
12765 break;
12766 case OACC_SERIAL:
12767 ort = ORT_ACC_SERIAL;
12768 break;
12769 case OACC_DATA:
12770 ort = ORT_ACC_DATA;
12771 break;
12772 case OMP_TARGET_DATA:
12773 ort = ORT_TARGET_DATA;
12774 break;
12775 case OMP_TEAMS:
12776 ort = OMP_TEAMS_COMBINED (expr) ? ORT_COMBINED_TEAMS : ORT_TEAMS;
12777 if (gimplify_omp_ctxp == NULL
12778 || gimplify_omp_ctxp->region_type == ORT_IMPLICIT_TARGET)
12779 ort = (enum omp_region_type) (ort | ORT_HOST_TEAMS);
12780 break;
12781 case OACC_HOST_DATA:
12782 ort = ORT_ACC_HOST_DATA;
12783 break;
12784 default:
12785 gcc_unreachable ();
12788 bool save_in_omp_construct = in_omp_construct;
12789 if ((ort & ORT_ACC) == 0)
12790 in_omp_construct = false;
12791 gimplify_scan_omp_clauses (&OMP_CLAUSES (expr), pre_p, ort,
12792 TREE_CODE (expr));
12793 if (TREE_CODE (expr) == OMP_TARGET)
12794 optimize_target_teams (expr, pre_p);
12795 if ((ort & (ORT_TARGET | ORT_TARGET_DATA)) != 0
12796 || (ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
12798 push_gimplify_context ();
12799 gimple *g = gimplify_and_return_first (OMP_BODY (expr), &body);
12800 if (gimple_code (g) == GIMPLE_BIND)
12801 pop_gimplify_context (g);
12802 else
12803 pop_gimplify_context (NULL);
12804 if ((ort & ORT_TARGET_DATA) != 0)
12806 enum built_in_function end_ix;
12807 switch (TREE_CODE (expr))
12809 case OACC_DATA:
12810 case OACC_HOST_DATA:
12811 end_ix = BUILT_IN_GOACC_DATA_END;
12812 break;
12813 case OMP_TARGET_DATA:
12814 end_ix = BUILT_IN_GOMP_TARGET_END_DATA;
12815 break;
12816 default:
12817 gcc_unreachable ();
12819 tree fn = builtin_decl_explicit (end_ix);
12820 g = gimple_build_call (fn, 0);
12821 gimple_seq cleanup = NULL;
12822 gimple_seq_add_stmt (&cleanup, g);
12823 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
12824 body = NULL;
12825 gimple_seq_add_stmt (&body, g);
12828 else
12829 gimplify_and_add (OMP_BODY (expr), &body);
12830 gimplify_adjust_omp_clauses (pre_p, body, &OMP_CLAUSES (expr),
12831 TREE_CODE (expr));
12832 in_omp_construct = save_in_omp_construct;
12834 switch (TREE_CODE (expr))
12836 case OACC_DATA:
12837 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_DATA,
12838 OMP_CLAUSES (expr));
12839 break;
12840 case OACC_HOST_DATA:
12841 if (omp_find_clause (OMP_CLAUSES (expr), OMP_CLAUSE_IF_PRESENT))
12843 for (tree c = OMP_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
12844 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_PTR)
12845 OMP_CLAUSE_USE_DEVICE_PTR_IF_PRESENT (c) = 1;
12848 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_HOST_DATA,
12849 OMP_CLAUSES (expr));
12850 break;
12851 case OACC_KERNELS:
12852 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_KERNELS,
12853 OMP_CLAUSES (expr));
12854 break;
12855 case OACC_PARALLEL:
12856 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_PARALLEL,
12857 OMP_CLAUSES (expr));
12858 break;
12859 case OACC_SERIAL:
12860 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_SERIAL,
12861 OMP_CLAUSES (expr));
12862 break;
12863 case OMP_SECTIONS:
12864 stmt = gimple_build_omp_sections (body, OMP_CLAUSES (expr));
12865 break;
12866 case OMP_SINGLE:
12867 stmt = gimple_build_omp_single (body, OMP_CLAUSES (expr));
12868 break;
12869 case OMP_TARGET:
12870 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_REGION,
12871 OMP_CLAUSES (expr));
12872 break;
12873 case OMP_TARGET_DATA:
12874 /* Put use_device_{ptr,addr} clauses last, as map clauses are supposed
12875 to be evaluated before the use_device_{ptr,addr} clauses if they
12876 refer to the same variables. */
12878 tree use_device_clauses;
12879 tree *pc, *uc = &use_device_clauses;
12880 for (pc = &OMP_CLAUSES (expr); *pc; )
12881 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
12882 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
12884 *uc = *pc;
12885 *pc = OMP_CLAUSE_CHAIN (*pc);
12886 uc = &OMP_CLAUSE_CHAIN (*uc);
12888 else
12889 pc = &OMP_CLAUSE_CHAIN (*pc);
12890 *uc = NULL_TREE;
12891 *pc = use_device_clauses;
12892 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_DATA,
12893 OMP_CLAUSES (expr));
12895 break;
12896 case OMP_TEAMS:
12897 stmt = gimple_build_omp_teams (body, OMP_CLAUSES (expr));
12898 if ((ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
12899 gimple_omp_teams_set_host (as_a <gomp_teams *> (stmt), true);
12900 break;
12901 default:
12902 gcc_unreachable ();
12905 gimplify_seq_add_stmt (pre_p, stmt);
12906 *expr_p = NULL_TREE;
12909 /* Gimplify the gross structure of OpenACC enter/exit data, update, and OpenMP
12910 target update constructs. */
12912 static void
12913 gimplify_omp_target_update (tree *expr_p, gimple_seq *pre_p)
12915 tree expr = *expr_p;
12916 int kind;
12917 gomp_target *stmt;
12918 enum omp_region_type ort = ORT_WORKSHARE;
12920 switch (TREE_CODE (expr))
12922 case OACC_ENTER_DATA:
12923 case OACC_EXIT_DATA:
12924 kind = GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA;
12925 ort = ORT_ACC;
12926 break;
12927 case OACC_UPDATE:
12928 kind = GF_OMP_TARGET_KIND_OACC_UPDATE;
12929 ort = ORT_ACC;
12930 break;
12931 case OMP_TARGET_UPDATE:
12932 kind = GF_OMP_TARGET_KIND_UPDATE;
12933 break;
12934 case OMP_TARGET_ENTER_DATA:
12935 kind = GF_OMP_TARGET_KIND_ENTER_DATA;
12936 break;
12937 case OMP_TARGET_EXIT_DATA:
12938 kind = GF_OMP_TARGET_KIND_EXIT_DATA;
12939 break;
12940 default:
12941 gcc_unreachable ();
12943 gimplify_scan_omp_clauses (&OMP_STANDALONE_CLAUSES (expr), pre_p,
12944 ort, TREE_CODE (expr));
12945 gimplify_adjust_omp_clauses (pre_p, NULL, &OMP_STANDALONE_CLAUSES (expr),
12946 TREE_CODE (expr));
12947 if (TREE_CODE (expr) == OACC_UPDATE
12948 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
12949 OMP_CLAUSE_IF_PRESENT))
12951 /* The runtime uses GOMP_MAP_{TO,FROM} to denote the if_present
12952 clause. */
12953 for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
12954 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
12955 switch (OMP_CLAUSE_MAP_KIND (c))
12957 case GOMP_MAP_FORCE_TO:
12958 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TO);
12959 break;
12960 case GOMP_MAP_FORCE_FROM:
12961 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FROM);
12962 break;
12963 default:
12964 break;
12967 else if (TREE_CODE (expr) == OACC_EXIT_DATA
12968 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
12969 OMP_CLAUSE_FINALIZE))
12971 /* Use GOMP_MAP_DELETE/GOMP_MAP_FORCE_FROM to denote "finalize"
12972 semantics. */
12973 bool have_clause = false;
12974 for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
12975 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
12976 switch (OMP_CLAUSE_MAP_KIND (c))
12978 case GOMP_MAP_FROM:
12979 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_FROM);
12980 have_clause = true;
12981 break;
12982 case GOMP_MAP_RELEASE:
12983 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_DELETE);
12984 have_clause = true;
12985 break;
12986 case GOMP_MAP_POINTER:
12987 case GOMP_MAP_TO_PSET:
12988 /* TODO PR92929: we may see these here, but they'll always follow
12989 one of the clauses above, and will be handled by libgomp as
12990 one group, so no handling required here. */
12991 gcc_assert (have_clause);
12992 break;
12993 case GOMP_MAP_DETACH:
12994 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_DETACH);
12995 have_clause = false;
12996 break;
12997 case GOMP_MAP_STRUCT:
12998 have_clause = false;
12999 break;
13000 default:
13001 gcc_unreachable ();
13004 stmt = gimple_build_omp_target (NULL, kind, OMP_STANDALONE_CLAUSES (expr));
13006 gimplify_seq_add_stmt (pre_p, stmt);
13007 *expr_p = NULL_TREE;
13010 /* A subroutine of gimplify_omp_atomic. The front end is supposed to have
13011 stabilized the lhs of the atomic operation as *ADDR. Return true if
13012 EXPR is this stabilized form. */
13014 static bool
13015 goa_lhs_expr_p (tree expr, tree addr)
13017 /* Also include casts to other type variants. The C front end is fond
13018 of adding these for e.g. volatile variables. This is like
13019 STRIP_TYPE_NOPS but includes the main variant lookup. */
13020 STRIP_USELESS_TYPE_CONVERSION (expr);
13022 if (TREE_CODE (expr) == INDIRECT_REF)
13024 expr = TREE_OPERAND (expr, 0);
13025 while (expr != addr
13026 && (CONVERT_EXPR_P (expr)
13027 || TREE_CODE (expr) == NON_LVALUE_EXPR)
13028 && TREE_CODE (expr) == TREE_CODE (addr)
13029 && types_compatible_p (TREE_TYPE (expr), TREE_TYPE (addr)))
13031 expr = TREE_OPERAND (expr, 0);
13032 addr = TREE_OPERAND (addr, 0);
13034 if (expr == addr)
13035 return true;
13036 return (TREE_CODE (addr) == ADDR_EXPR
13037 && TREE_CODE (expr) == ADDR_EXPR
13038 && TREE_OPERAND (addr, 0) == TREE_OPERAND (expr, 0));
13040 if (TREE_CODE (addr) == ADDR_EXPR && expr == TREE_OPERAND (addr, 0))
13041 return true;
13042 return false;
13045 /* Walk *EXPR_P and replace appearances of *LHS_ADDR with LHS_VAR. If an
13046 expression does not involve the lhs, evaluate it into a temporary.
13047 Return 1 if the lhs appeared as a subexpression, 0 if it did not,
13048 or -1 if an error was encountered. */
13050 static int
13051 goa_stabilize_expr (tree *expr_p, gimple_seq *pre_p, tree lhs_addr,
13052 tree lhs_var)
13054 tree expr = *expr_p;
13055 int saw_lhs;
13057 if (goa_lhs_expr_p (expr, lhs_addr))
13059 *expr_p = lhs_var;
13060 return 1;
13062 if (is_gimple_val (expr))
13063 return 0;
13065 saw_lhs = 0;
13066 switch (TREE_CODE_CLASS (TREE_CODE (expr)))
13068 case tcc_binary:
13069 case tcc_comparison:
13070 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p, lhs_addr,
13071 lhs_var);
13072 /* FALLTHRU */
13073 case tcc_unary:
13074 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p, lhs_addr,
13075 lhs_var);
13076 break;
13077 case tcc_expression:
13078 switch (TREE_CODE (expr))
13080 case TRUTH_ANDIF_EXPR:
13081 case TRUTH_ORIF_EXPR:
13082 case TRUTH_AND_EXPR:
13083 case TRUTH_OR_EXPR:
13084 case TRUTH_XOR_EXPR:
13085 case BIT_INSERT_EXPR:
13086 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
13087 lhs_addr, lhs_var);
13088 /* FALLTHRU */
13089 case TRUTH_NOT_EXPR:
13090 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
13091 lhs_addr, lhs_var);
13092 break;
13093 case COMPOUND_EXPR:
13094 /* Break out any preevaluations from cp_build_modify_expr. */
13095 for (; TREE_CODE (expr) == COMPOUND_EXPR;
13096 expr = TREE_OPERAND (expr, 1))
13097 gimplify_stmt (&TREE_OPERAND (expr, 0), pre_p);
13098 *expr_p = expr;
13099 return goa_stabilize_expr (expr_p, pre_p, lhs_addr, lhs_var);
13100 default:
13101 break;
13103 break;
13104 case tcc_reference:
13105 if (TREE_CODE (expr) == BIT_FIELD_REF)
13106 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
13107 lhs_addr, lhs_var);
13108 break;
13109 default:
13110 break;
13113 if (saw_lhs == 0)
13115 enum gimplify_status gs;
13116 gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_val, fb_rvalue);
13117 if (gs != GS_ALL_DONE)
13118 saw_lhs = -1;
13121 return saw_lhs;
13124 /* Gimplify an OMP_ATOMIC statement. */
13126 static enum gimplify_status
13127 gimplify_omp_atomic (tree *expr_p, gimple_seq *pre_p)
13129 tree addr = TREE_OPERAND (*expr_p, 0);
13130 tree rhs = TREE_CODE (*expr_p) == OMP_ATOMIC_READ
13131 ? NULL : TREE_OPERAND (*expr_p, 1);
13132 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
13133 tree tmp_load;
13134 gomp_atomic_load *loadstmt;
13135 gomp_atomic_store *storestmt;
13137 tmp_load = create_tmp_reg (type);
13138 if (rhs && goa_stabilize_expr (&rhs, pre_p, addr, tmp_load) < 0)
13139 return GS_ERROR;
13141 if (gimplify_expr (&addr, pre_p, NULL, is_gimple_val, fb_rvalue)
13142 != GS_ALL_DONE)
13143 return GS_ERROR;
13145 loadstmt = gimple_build_omp_atomic_load (tmp_load, addr,
13146 OMP_ATOMIC_MEMORY_ORDER (*expr_p));
13147 gimplify_seq_add_stmt (pre_p, loadstmt);
13148 if (rhs)
13150 /* BIT_INSERT_EXPR is not valid for non-integral bitfield
13151 representatives. Use BIT_FIELD_REF on the lhs instead. */
13152 if (TREE_CODE (rhs) == BIT_INSERT_EXPR
13153 && !INTEGRAL_TYPE_P (TREE_TYPE (tmp_load)))
13155 tree bitpos = TREE_OPERAND (rhs, 2);
13156 tree op1 = TREE_OPERAND (rhs, 1);
13157 tree bitsize;
13158 tree tmp_store = tmp_load;
13159 if (TREE_CODE (*expr_p) == OMP_ATOMIC_CAPTURE_OLD)
13160 tmp_store = get_initialized_tmp_var (tmp_load, pre_p);
13161 if (INTEGRAL_TYPE_P (TREE_TYPE (op1)))
13162 bitsize = bitsize_int (TYPE_PRECISION (TREE_TYPE (op1)));
13163 else
13164 bitsize = TYPE_SIZE (TREE_TYPE (op1));
13165 gcc_assert (TREE_OPERAND (rhs, 0) == tmp_load);
13166 tree t = build2_loc (EXPR_LOCATION (rhs),
13167 MODIFY_EXPR, void_type_node,
13168 build3_loc (EXPR_LOCATION (rhs), BIT_FIELD_REF,
13169 TREE_TYPE (op1), tmp_store, bitsize,
13170 bitpos), op1);
13171 gimplify_and_add (t, pre_p);
13172 rhs = tmp_store;
13174 if (gimplify_expr (&rhs, pre_p, NULL, is_gimple_val, fb_rvalue)
13175 != GS_ALL_DONE)
13176 return GS_ERROR;
13179 if (TREE_CODE (*expr_p) == OMP_ATOMIC_READ)
13180 rhs = tmp_load;
13181 storestmt
13182 = gimple_build_omp_atomic_store (rhs, OMP_ATOMIC_MEMORY_ORDER (*expr_p));
13183 gimplify_seq_add_stmt (pre_p, storestmt);
13184 switch (TREE_CODE (*expr_p))
13186 case OMP_ATOMIC_READ:
13187 case OMP_ATOMIC_CAPTURE_OLD:
13188 *expr_p = tmp_load;
13189 gimple_omp_atomic_set_need_value (loadstmt);
13190 break;
13191 case OMP_ATOMIC_CAPTURE_NEW:
13192 *expr_p = rhs;
13193 gimple_omp_atomic_set_need_value (storestmt);
13194 break;
13195 default:
13196 *expr_p = NULL;
13197 break;
13200 return GS_ALL_DONE;
13203 /* Gimplify a TRANSACTION_EXPR. This involves gimplification of the
13204 body, and adding some EH bits. */
13206 static enum gimplify_status
13207 gimplify_transaction (tree *expr_p, gimple_seq *pre_p)
13209 tree expr = *expr_p, temp, tbody = TRANSACTION_EXPR_BODY (expr);
13210 gimple *body_stmt;
13211 gtransaction *trans_stmt;
13212 gimple_seq body = NULL;
13213 int subcode = 0;
13215 /* Wrap the transaction body in a BIND_EXPR so we have a context
13216 where to put decls for OMP. */
13217 if (TREE_CODE (tbody) != BIND_EXPR)
13219 tree bind = build3 (BIND_EXPR, void_type_node, NULL, tbody, NULL);
13220 TREE_SIDE_EFFECTS (bind) = 1;
13221 SET_EXPR_LOCATION (bind, EXPR_LOCATION (tbody));
13222 TRANSACTION_EXPR_BODY (expr) = bind;
13225 push_gimplify_context ();
13226 temp = voidify_wrapper_expr (*expr_p, NULL);
13228 body_stmt = gimplify_and_return_first (TRANSACTION_EXPR_BODY (expr), &body);
13229 pop_gimplify_context (body_stmt);
13231 trans_stmt = gimple_build_transaction (body);
13232 if (TRANSACTION_EXPR_OUTER (expr))
13233 subcode = GTMA_IS_OUTER;
13234 else if (TRANSACTION_EXPR_RELAXED (expr))
13235 subcode = GTMA_IS_RELAXED;
13236 gimple_transaction_set_subcode (trans_stmt, subcode);
13238 gimplify_seq_add_stmt (pre_p, trans_stmt);
13240 if (temp)
13242 *expr_p = temp;
13243 return GS_OK;
13246 *expr_p = NULL_TREE;
13247 return GS_ALL_DONE;
13250 /* Gimplify an OMP_ORDERED construct. EXPR is the tree version. BODY
13251 is the OMP_BODY of the original EXPR (which has already been
13252 gimplified so it's not present in the EXPR).
13254 Return the gimplified GIMPLE_OMP_ORDERED tuple. */
13256 static gimple *
13257 gimplify_omp_ordered (tree expr, gimple_seq body)
13259 tree c, decls;
13260 int failures = 0;
13261 unsigned int i;
13262 tree source_c = NULL_TREE;
13263 tree sink_c = NULL_TREE;
13265 if (gimplify_omp_ctxp)
13267 for (c = OMP_ORDERED_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
13268 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
13269 && gimplify_omp_ctxp->loop_iter_var.is_empty ()
13270 && (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK
13271 || OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE))
13273 error_at (OMP_CLAUSE_LOCATION (c),
13274 "%<ordered%> construct with %<depend%> clause must be "
13275 "closely nested inside a loop with %<ordered%> clause "
13276 "with a parameter");
13277 failures++;
13279 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
13280 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
13282 bool fail = false;
13283 for (decls = OMP_CLAUSE_DECL (c), i = 0;
13284 decls && TREE_CODE (decls) == TREE_LIST;
13285 decls = TREE_CHAIN (decls), ++i)
13286 if (i >= gimplify_omp_ctxp->loop_iter_var.length () / 2)
13287 continue;
13288 else if (TREE_VALUE (decls)
13289 != gimplify_omp_ctxp->loop_iter_var[2 * i])
13291 error_at (OMP_CLAUSE_LOCATION (c),
13292 "variable %qE is not an iteration "
13293 "of outermost loop %d, expected %qE",
13294 TREE_VALUE (decls), i + 1,
13295 gimplify_omp_ctxp->loop_iter_var[2 * i]);
13296 fail = true;
13297 failures++;
13299 else
13300 TREE_VALUE (decls)
13301 = gimplify_omp_ctxp->loop_iter_var[2 * i + 1];
13302 if (!fail && i != gimplify_omp_ctxp->loop_iter_var.length () / 2)
13304 error_at (OMP_CLAUSE_LOCATION (c),
13305 "number of variables in %<depend%> clause with "
13306 "%<sink%> modifier does not match number of "
13307 "iteration variables");
13308 failures++;
13310 sink_c = c;
13312 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
13313 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
13315 if (source_c)
13317 error_at (OMP_CLAUSE_LOCATION (c),
13318 "more than one %<depend%> clause with %<source%> "
13319 "modifier on an %<ordered%> construct");
13320 failures++;
13322 else
13323 source_c = c;
13326 if (source_c && sink_c)
13328 error_at (OMP_CLAUSE_LOCATION (source_c),
13329 "%<depend%> clause with %<source%> modifier specified "
13330 "together with %<depend%> clauses with %<sink%> modifier "
13331 "on the same construct");
13332 failures++;
13335 if (failures)
13336 return gimple_build_nop ();
13337 return gimple_build_omp_ordered (body, OMP_ORDERED_CLAUSES (expr));
13340 /* Convert the GENERIC expression tree *EXPR_P to GIMPLE. If the
13341 expression produces a value to be used as an operand inside a GIMPLE
13342 statement, the value will be stored back in *EXPR_P. This value will
13343 be a tree of class tcc_declaration, tcc_constant, tcc_reference or
13344 an SSA_NAME. The corresponding sequence of GIMPLE statements is
13345 emitted in PRE_P and POST_P.
13347 Additionally, this process may overwrite parts of the input
13348 expression during gimplification. Ideally, it should be
13349 possible to do non-destructive gimplification.
13351 EXPR_P points to the GENERIC expression to convert to GIMPLE. If
13352 the expression needs to evaluate to a value to be used as
13353 an operand in a GIMPLE statement, this value will be stored in
13354 *EXPR_P on exit. This happens when the caller specifies one
13355 of fb_lvalue or fb_rvalue fallback flags.
13357 PRE_P will contain the sequence of GIMPLE statements corresponding
13358 to the evaluation of EXPR and all the side-effects that must
13359 be executed before the main expression. On exit, the last
13360 statement of PRE_P is the core statement being gimplified. For
13361 instance, when gimplifying 'if (++a)' the last statement in
13362 PRE_P will be 'if (t.1)' where t.1 is the result of
13363 pre-incrementing 'a'.
13365 POST_P will contain the sequence of GIMPLE statements corresponding
13366 to the evaluation of all the side-effects that must be executed
13367 after the main expression. If this is NULL, the post
13368 side-effects are stored at the end of PRE_P.
13370 The reason why the output is split in two is to handle post
13371 side-effects explicitly. In some cases, an expression may have
13372 inner and outer post side-effects which need to be emitted in
13373 an order different from the one given by the recursive
13374 traversal. For instance, for the expression (*p--)++ the post
13375 side-effects of '--' must actually occur *after* the post
13376 side-effects of '++'. However, gimplification will first visit
13377 the inner expression, so if a separate POST sequence was not
13378 used, the resulting sequence would be:
13380 1 t.1 = *p
13381 2 p = p - 1
13382 3 t.2 = t.1 + 1
13383 4 *p = t.2
13385 However, the post-decrement operation in line #2 must not be
13386 evaluated until after the store to *p at line #4, so the
13387 correct sequence should be:
13389 1 t.1 = *p
13390 2 t.2 = t.1 + 1
13391 3 *p = t.2
13392 4 p = p - 1
13394 So, by specifying a separate post queue, it is possible
13395 to emit the post side-effects in the correct order.
13396 If POST_P is NULL, an internal queue will be used. Before
13397 returning to the caller, the sequence POST_P is appended to
13398 the main output sequence PRE_P.
13400 GIMPLE_TEST_F points to a function that takes a tree T and
13401 returns nonzero if T is in the GIMPLE form requested by the
13402 caller. The GIMPLE predicates are in gimple.c.
13404 FALLBACK tells the function what sort of a temporary we want if
13405 gimplification cannot produce an expression that complies with
13406 GIMPLE_TEST_F.
13408 fb_none means that no temporary should be generated
13409 fb_rvalue means that an rvalue is OK to generate
13410 fb_lvalue means that an lvalue is OK to generate
13411 fb_either means that either is OK, but an lvalue is preferable.
13412 fb_mayfail means that gimplification may fail (in which case
13413 GS_ERROR will be returned)
13415 The return value is either GS_ERROR or GS_ALL_DONE, since this
13416 function iterates until EXPR is completely gimplified or an error
13417 occurs. */
13419 enum gimplify_status
13420 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
13421 bool (*gimple_test_f) (tree), fallback_t fallback)
13423 tree tmp;
13424 gimple_seq internal_pre = NULL;
13425 gimple_seq internal_post = NULL;
13426 tree save_expr;
13427 bool is_statement;
13428 location_t saved_location;
13429 enum gimplify_status ret;
13430 gimple_stmt_iterator pre_last_gsi, post_last_gsi;
13431 tree label;
13433 save_expr = *expr_p;
13434 if (save_expr == NULL_TREE)
13435 return GS_ALL_DONE;
13437 /* If we are gimplifying a top-level statement, PRE_P must be valid. */
13438 is_statement = gimple_test_f == is_gimple_stmt;
13439 if (is_statement)
13440 gcc_assert (pre_p);
13442 /* Consistency checks. */
13443 if (gimple_test_f == is_gimple_reg)
13444 gcc_assert (fallback & (fb_rvalue | fb_lvalue));
13445 else if (gimple_test_f == is_gimple_val
13446 || gimple_test_f == is_gimple_call_addr
13447 || gimple_test_f == is_gimple_condexpr
13448 || gimple_test_f == is_gimple_condexpr_for_cond
13449 || gimple_test_f == is_gimple_mem_rhs
13450 || gimple_test_f == is_gimple_mem_rhs_or_call
13451 || gimple_test_f == is_gimple_reg_rhs
13452 || gimple_test_f == is_gimple_reg_rhs_or_call
13453 || gimple_test_f == is_gimple_asm_val
13454 || gimple_test_f == is_gimple_mem_ref_addr)
13455 gcc_assert (fallback & fb_rvalue);
13456 else if (gimple_test_f == is_gimple_min_lval
13457 || gimple_test_f == is_gimple_lvalue)
13458 gcc_assert (fallback & fb_lvalue);
13459 else if (gimple_test_f == is_gimple_addressable)
13460 gcc_assert (fallback & fb_either);
13461 else if (gimple_test_f == is_gimple_stmt)
13462 gcc_assert (fallback == fb_none);
13463 else
13465 /* We should have recognized the GIMPLE_TEST_F predicate to
13466 know what kind of fallback to use in case a temporary is
13467 needed to hold the value or address of *EXPR_P. */
13468 gcc_unreachable ();
13471 /* We used to check the predicate here and return immediately if it
13472 succeeds. This is wrong; the design is for gimplification to be
13473 idempotent, and for the predicates to only test for valid forms, not
13474 whether they are fully simplified. */
13475 if (pre_p == NULL)
13476 pre_p = &internal_pre;
13478 if (post_p == NULL)
13479 post_p = &internal_post;
13481 /* Remember the last statements added to PRE_P and POST_P. Every
13482 new statement added by the gimplification helpers needs to be
13483 annotated with location information. To centralize the
13484 responsibility, we remember the last statement that had been
13485 added to both queues before gimplifying *EXPR_P. If
13486 gimplification produces new statements in PRE_P and POST_P, those
13487 statements will be annotated with the same location information
13488 as *EXPR_P. */
13489 pre_last_gsi = gsi_last (*pre_p);
13490 post_last_gsi = gsi_last (*post_p);
13492 saved_location = input_location;
13493 if (save_expr != error_mark_node
13494 && EXPR_HAS_LOCATION (*expr_p))
13495 input_location = EXPR_LOCATION (*expr_p);
13497 /* Loop over the specific gimplifiers until the toplevel node
13498 remains the same. */
13501 /* Strip away as many useless type conversions as possible
13502 at the toplevel. */
13503 STRIP_USELESS_TYPE_CONVERSION (*expr_p);
13505 /* Remember the expr. */
13506 save_expr = *expr_p;
13508 /* Die, die, die, my darling. */
13509 if (error_operand_p (save_expr))
13511 ret = GS_ERROR;
13512 break;
13515 /* Do any language-specific gimplification. */
13516 ret = ((enum gimplify_status)
13517 lang_hooks.gimplify_expr (expr_p, pre_p, post_p));
13518 if (ret == GS_OK)
13520 if (*expr_p == NULL_TREE)
13521 break;
13522 if (*expr_p != save_expr)
13523 continue;
13525 else if (ret != GS_UNHANDLED)
13526 break;
13528 /* Make sure that all the cases set 'ret' appropriately. */
13529 ret = GS_UNHANDLED;
13530 switch (TREE_CODE (*expr_p))
13532 /* First deal with the special cases. */
13534 case POSTINCREMENT_EXPR:
13535 case POSTDECREMENT_EXPR:
13536 case PREINCREMENT_EXPR:
13537 case PREDECREMENT_EXPR:
13538 ret = gimplify_self_mod_expr (expr_p, pre_p, post_p,
13539 fallback != fb_none,
13540 TREE_TYPE (*expr_p));
13541 break;
13543 case VIEW_CONVERT_EXPR:
13544 if ((fallback & fb_rvalue)
13545 && is_gimple_reg_type (TREE_TYPE (*expr_p))
13546 && is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0))))
13548 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
13549 post_p, is_gimple_val, fb_rvalue);
13550 recalculate_side_effects (*expr_p);
13551 break;
13553 /* Fallthru. */
13555 case ARRAY_REF:
13556 case ARRAY_RANGE_REF:
13557 case REALPART_EXPR:
13558 case IMAGPART_EXPR:
13559 case COMPONENT_REF:
13560 ret = gimplify_compound_lval (expr_p, pre_p, post_p,
13561 fallback ? fallback : fb_rvalue);
13562 break;
13564 case COND_EXPR:
13565 ret = gimplify_cond_expr (expr_p, pre_p, fallback);
13567 /* C99 code may assign to an array in a structure value of a
13568 conditional expression, and this has undefined behavior
13569 only on execution, so create a temporary if an lvalue is
13570 required. */
13571 if (fallback == fb_lvalue)
13573 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
13574 mark_addressable (*expr_p);
13575 ret = GS_OK;
13577 break;
13579 case CALL_EXPR:
13580 ret = gimplify_call_expr (expr_p, pre_p, fallback != fb_none);
13582 /* C99 code may assign to an array in a structure returned
13583 from a function, and this has undefined behavior only on
13584 execution, so create a temporary if an lvalue is
13585 required. */
13586 if (fallback == fb_lvalue)
13588 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
13589 mark_addressable (*expr_p);
13590 ret = GS_OK;
13592 break;
13594 case TREE_LIST:
13595 gcc_unreachable ();
13597 case COMPOUND_EXPR:
13598 ret = gimplify_compound_expr (expr_p, pre_p, fallback != fb_none);
13599 break;
13601 case COMPOUND_LITERAL_EXPR:
13602 ret = gimplify_compound_literal_expr (expr_p, pre_p,
13603 gimple_test_f, fallback);
13604 break;
13606 case MODIFY_EXPR:
13607 case INIT_EXPR:
13608 ret = gimplify_modify_expr (expr_p, pre_p, post_p,
13609 fallback != fb_none);
13610 break;
13612 case TRUTH_ANDIF_EXPR:
13613 case TRUTH_ORIF_EXPR:
13615 /* Preserve the original type of the expression and the
13616 source location of the outer expression. */
13617 tree org_type = TREE_TYPE (*expr_p);
13618 *expr_p = gimple_boolify (*expr_p);
13619 *expr_p = build3_loc (input_location, COND_EXPR,
13620 org_type, *expr_p,
13621 fold_convert_loc
13622 (input_location,
13623 org_type, boolean_true_node),
13624 fold_convert_loc
13625 (input_location,
13626 org_type, boolean_false_node));
13627 ret = GS_OK;
13628 break;
13631 case TRUTH_NOT_EXPR:
13633 tree type = TREE_TYPE (*expr_p);
13634 /* The parsers are careful to generate TRUTH_NOT_EXPR
13635 only with operands that are always zero or one.
13636 We do not fold here but handle the only interesting case
13637 manually, as fold may re-introduce the TRUTH_NOT_EXPR. */
13638 *expr_p = gimple_boolify (*expr_p);
13639 if (TYPE_PRECISION (TREE_TYPE (*expr_p)) == 1)
13640 *expr_p = build1_loc (input_location, BIT_NOT_EXPR,
13641 TREE_TYPE (*expr_p),
13642 TREE_OPERAND (*expr_p, 0));
13643 else
13644 *expr_p = build2_loc (input_location, BIT_XOR_EXPR,
13645 TREE_TYPE (*expr_p),
13646 TREE_OPERAND (*expr_p, 0),
13647 build_int_cst (TREE_TYPE (*expr_p), 1));
13648 if (!useless_type_conversion_p (type, TREE_TYPE (*expr_p)))
13649 *expr_p = fold_convert_loc (input_location, type, *expr_p);
13650 ret = GS_OK;
13651 break;
13654 case ADDR_EXPR:
13655 ret = gimplify_addr_expr (expr_p, pre_p, post_p);
13656 break;
13658 case ANNOTATE_EXPR:
13660 tree cond = TREE_OPERAND (*expr_p, 0);
13661 tree kind = TREE_OPERAND (*expr_p, 1);
13662 tree data = TREE_OPERAND (*expr_p, 2);
13663 tree type = TREE_TYPE (cond);
13664 if (!INTEGRAL_TYPE_P (type))
13666 *expr_p = cond;
13667 ret = GS_OK;
13668 break;
13670 tree tmp = create_tmp_var (type);
13671 gimplify_arg (&cond, pre_p, EXPR_LOCATION (*expr_p));
13672 gcall *call
13673 = gimple_build_call_internal (IFN_ANNOTATE, 3, cond, kind, data);
13674 gimple_call_set_lhs (call, tmp);
13675 gimplify_seq_add_stmt (pre_p, call);
13676 *expr_p = tmp;
13677 ret = GS_ALL_DONE;
13678 break;
13681 case VA_ARG_EXPR:
13682 ret = gimplify_va_arg_expr (expr_p, pre_p, post_p);
13683 break;
13685 CASE_CONVERT:
13686 if (IS_EMPTY_STMT (*expr_p))
13688 ret = GS_ALL_DONE;
13689 break;
13692 if (VOID_TYPE_P (TREE_TYPE (*expr_p))
13693 || fallback == fb_none)
13695 /* Just strip a conversion to void (or in void context) and
13696 try again. */
13697 *expr_p = TREE_OPERAND (*expr_p, 0);
13698 ret = GS_OK;
13699 break;
13702 ret = gimplify_conversion (expr_p);
13703 if (ret == GS_ERROR)
13704 break;
13705 if (*expr_p != save_expr)
13706 break;
13707 /* FALLTHRU */
13709 case FIX_TRUNC_EXPR:
13710 /* unary_expr: ... | '(' cast ')' val | ... */
13711 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
13712 is_gimple_val, fb_rvalue);
13713 recalculate_side_effects (*expr_p);
13714 break;
13716 case INDIRECT_REF:
13718 bool volatilep = TREE_THIS_VOLATILE (*expr_p);
13719 bool notrap = TREE_THIS_NOTRAP (*expr_p);
13720 tree saved_ptr_type = TREE_TYPE (TREE_OPERAND (*expr_p, 0));
13722 *expr_p = fold_indirect_ref_loc (input_location, *expr_p);
13723 if (*expr_p != save_expr)
13725 ret = GS_OK;
13726 break;
13729 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
13730 is_gimple_reg, fb_rvalue);
13731 if (ret == GS_ERROR)
13732 break;
13734 recalculate_side_effects (*expr_p);
13735 *expr_p = fold_build2_loc (input_location, MEM_REF,
13736 TREE_TYPE (*expr_p),
13737 TREE_OPERAND (*expr_p, 0),
13738 build_int_cst (saved_ptr_type, 0));
13739 TREE_THIS_VOLATILE (*expr_p) = volatilep;
13740 TREE_THIS_NOTRAP (*expr_p) = notrap;
13741 ret = GS_OK;
13742 break;
13745 /* We arrive here through the various re-gimplifcation paths. */
13746 case MEM_REF:
13747 /* First try re-folding the whole thing. */
13748 tmp = fold_binary (MEM_REF, TREE_TYPE (*expr_p),
13749 TREE_OPERAND (*expr_p, 0),
13750 TREE_OPERAND (*expr_p, 1));
13751 if (tmp)
13753 REF_REVERSE_STORAGE_ORDER (tmp)
13754 = REF_REVERSE_STORAGE_ORDER (*expr_p);
13755 *expr_p = tmp;
13756 recalculate_side_effects (*expr_p);
13757 ret = GS_OK;
13758 break;
13760 /* Avoid re-gimplifying the address operand if it is already
13761 in suitable form. Re-gimplifying would mark the address
13762 operand addressable. Always gimplify when not in SSA form
13763 as we still may have to gimplify decls with value-exprs. */
13764 if (!gimplify_ctxp || !gimple_in_ssa_p (cfun)
13765 || !is_gimple_mem_ref_addr (TREE_OPERAND (*expr_p, 0)))
13767 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
13768 is_gimple_mem_ref_addr, fb_rvalue);
13769 if (ret == GS_ERROR)
13770 break;
13772 recalculate_side_effects (*expr_p);
13773 ret = GS_ALL_DONE;
13774 break;
13776 /* Constants need not be gimplified. */
13777 case INTEGER_CST:
13778 case REAL_CST:
13779 case FIXED_CST:
13780 case STRING_CST:
13781 case COMPLEX_CST:
13782 case VECTOR_CST:
13783 /* Drop the overflow flag on constants, we do not want
13784 that in the GIMPLE IL. */
13785 if (TREE_OVERFLOW_P (*expr_p))
13786 *expr_p = drop_tree_overflow (*expr_p);
13787 ret = GS_ALL_DONE;
13788 break;
13790 case CONST_DECL:
13791 /* If we require an lvalue, such as for ADDR_EXPR, retain the
13792 CONST_DECL node. Otherwise the decl is replaceable by its
13793 value. */
13794 /* ??? Should be == fb_lvalue, but ADDR_EXPR passes fb_either. */
13795 if (fallback & fb_lvalue)
13796 ret = GS_ALL_DONE;
13797 else
13799 *expr_p = DECL_INITIAL (*expr_p);
13800 ret = GS_OK;
13802 break;
13804 case DECL_EXPR:
13805 ret = gimplify_decl_expr (expr_p, pre_p);
13806 break;
13808 case BIND_EXPR:
13809 ret = gimplify_bind_expr (expr_p, pre_p);
13810 break;
13812 case LOOP_EXPR:
13813 ret = gimplify_loop_expr (expr_p, pre_p);
13814 break;
13816 case SWITCH_EXPR:
13817 ret = gimplify_switch_expr (expr_p, pre_p);
13818 break;
13820 case EXIT_EXPR:
13821 ret = gimplify_exit_expr (expr_p);
13822 break;
13824 case GOTO_EXPR:
13825 /* If the target is not LABEL, then it is a computed jump
13826 and the target needs to be gimplified. */
13827 if (TREE_CODE (GOTO_DESTINATION (*expr_p)) != LABEL_DECL)
13829 ret = gimplify_expr (&GOTO_DESTINATION (*expr_p), pre_p,
13830 NULL, is_gimple_val, fb_rvalue);
13831 if (ret == GS_ERROR)
13832 break;
13834 gimplify_seq_add_stmt (pre_p,
13835 gimple_build_goto (GOTO_DESTINATION (*expr_p)));
13836 ret = GS_ALL_DONE;
13837 break;
13839 case PREDICT_EXPR:
13840 gimplify_seq_add_stmt (pre_p,
13841 gimple_build_predict (PREDICT_EXPR_PREDICTOR (*expr_p),
13842 PREDICT_EXPR_OUTCOME (*expr_p)));
13843 ret = GS_ALL_DONE;
13844 break;
13846 case LABEL_EXPR:
13847 ret = gimplify_label_expr (expr_p, pre_p);
13848 label = LABEL_EXPR_LABEL (*expr_p);
13849 gcc_assert (decl_function_context (label) == current_function_decl);
13851 /* If the label is used in a goto statement, or address of the label
13852 is taken, we need to unpoison all variables that were seen so far.
13853 Doing so would prevent us from reporting a false positives. */
13854 if (asan_poisoned_variables
13855 && asan_used_labels != NULL
13856 && asan_used_labels->contains (label))
13857 asan_poison_variables (asan_poisoned_variables, false, pre_p);
13858 break;
13860 case CASE_LABEL_EXPR:
13861 ret = gimplify_case_label_expr (expr_p, pre_p);
13863 if (gimplify_ctxp->live_switch_vars)
13864 asan_poison_variables (gimplify_ctxp->live_switch_vars, false,
13865 pre_p);
13866 break;
13868 case RETURN_EXPR:
13869 ret = gimplify_return_expr (*expr_p, pre_p);
13870 break;
13872 case CONSTRUCTOR:
13873 /* Don't reduce this in place; let gimplify_init_constructor work its
13874 magic. Buf if we're just elaborating this for side effects, just
13875 gimplify any element that has side-effects. */
13876 if (fallback == fb_none)
13878 unsigned HOST_WIDE_INT ix;
13879 tree val;
13880 tree temp = NULL_TREE;
13881 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (*expr_p), ix, val)
13882 if (TREE_SIDE_EFFECTS (val))
13883 append_to_statement_list (val, &temp);
13885 *expr_p = temp;
13886 ret = temp ? GS_OK : GS_ALL_DONE;
13888 /* C99 code may assign to an array in a constructed
13889 structure or union, and this has undefined behavior only
13890 on execution, so create a temporary if an lvalue is
13891 required. */
13892 else if (fallback == fb_lvalue)
13894 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
13895 mark_addressable (*expr_p);
13896 ret = GS_OK;
13898 else
13899 ret = GS_ALL_DONE;
13900 break;
13902 /* The following are special cases that are not handled by the
13903 original GIMPLE grammar. */
13905 /* SAVE_EXPR nodes are converted into a GIMPLE identifier and
13906 eliminated. */
13907 case SAVE_EXPR:
13908 ret = gimplify_save_expr (expr_p, pre_p, post_p);
13909 break;
13911 case BIT_FIELD_REF:
13912 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
13913 post_p, is_gimple_lvalue, fb_either);
13914 recalculate_side_effects (*expr_p);
13915 break;
13917 case TARGET_MEM_REF:
13919 enum gimplify_status r0 = GS_ALL_DONE, r1 = GS_ALL_DONE;
13921 if (TMR_BASE (*expr_p))
13922 r0 = gimplify_expr (&TMR_BASE (*expr_p), pre_p,
13923 post_p, is_gimple_mem_ref_addr, fb_either);
13924 if (TMR_INDEX (*expr_p))
13925 r1 = gimplify_expr (&TMR_INDEX (*expr_p), pre_p,
13926 post_p, is_gimple_val, fb_rvalue);
13927 if (TMR_INDEX2 (*expr_p))
13928 r1 = gimplify_expr (&TMR_INDEX2 (*expr_p), pre_p,
13929 post_p, is_gimple_val, fb_rvalue);
13930 /* TMR_STEP and TMR_OFFSET are always integer constants. */
13931 ret = MIN (r0, r1);
13933 break;
13935 case NON_LVALUE_EXPR:
13936 /* This should have been stripped above. */
13937 gcc_unreachable ();
13939 case ASM_EXPR:
13940 ret = gimplify_asm_expr (expr_p, pre_p, post_p);
13941 break;
13943 case TRY_FINALLY_EXPR:
13944 case TRY_CATCH_EXPR:
13946 gimple_seq eval, cleanup;
13947 gtry *try_;
13949 /* Calls to destructors are generated automatically in FINALLY/CATCH
13950 block. They should have location as UNKNOWN_LOCATION. However,
13951 gimplify_call_expr will reset these call stmts to input_location
13952 if it finds stmt's location is unknown. To prevent resetting for
13953 destructors, we set the input_location to unknown.
13954 Note that this only affects the destructor calls in FINALLY/CATCH
13955 block, and will automatically reset to its original value by the
13956 end of gimplify_expr. */
13957 input_location = UNKNOWN_LOCATION;
13958 eval = cleanup = NULL;
13959 gimplify_and_add (TREE_OPERAND (*expr_p, 0), &eval);
13960 if (TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
13961 && TREE_CODE (TREE_OPERAND (*expr_p, 1)) == EH_ELSE_EXPR)
13963 gimple_seq n = NULL, e = NULL;
13964 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1),
13965 0), &n);
13966 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1),
13967 1), &e);
13968 if (!gimple_seq_empty_p (n) && !gimple_seq_empty_p (e))
13970 geh_else *stmt = gimple_build_eh_else (n, e);
13971 gimple_seq_add_stmt (&cleanup, stmt);
13974 else
13975 gimplify_and_add (TREE_OPERAND (*expr_p, 1), &cleanup);
13976 /* Don't create bogus GIMPLE_TRY with empty cleanup. */
13977 if (gimple_seq_empty_p (cleanup))
13979 gimple_seq_add_seq (pre_p, eval);
13980 ret = GS_ALL_DONE;
13981 break;
13983 try_ = gimple_build_try (eval, cleanup,
13984 TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
13985 ? GIMPLE_TRY_FINALLY
13986 : GIMPLE_TRY_CATCH);
13987 if (EXPR_HAS_LOCATION (save_expr))
13988 gimple_set_location (try_, EXPR_LOCATION (save_expr));
13989 else if (LOCATION_LOCUS (saved_location) != UNKNOWN_LOCATION)
13990 gimple_set_location (try_, saved_location);
13991 if (TREE_CODE (*expr_p) == TRY_CATCH_EXPR)
13992 gimple_try_set_catch_is_cleanup (try_,
13993 TRY_CATCH_IS_CLEANUP (*expr_p));
13994 gimplify_seq_add_stmt (pre_p, try_);
13995 ret = GS_ALL_DONE;
13996 break;
13999 case CLEANUP_POINT_EXPR:
14000 ret = gimplify_cleanup_point_expr (expr_p, pre_p);
14001 break;
14003 case TARGET_EXPR:
14004 ret = gimplify_target_expr (expr_p, pre_p, post_p);
14005 break;
14007 case CATCH_EXPR:
14009 gimple *c;
14010 gimple_seq handler = NULL;
14011 gimplify_and_add (CATCH_BODY (*expr_p), &handler);
14012 c = gimple_build_catch (CATCH_TYPES (*expr_p), handler);
14013 gimplify_seq_add_stmt (pre_p, c);
14014 ret = GS_ALL_DONE;
14015 break;
14018 case EH_FILTER_EXPR:
14020 gimple *ehf;
14021 gimple_seq failure = NULL;
14023 gimplify_and_add (EH_FILTER_FAILURE (*expr_p), &failure);
14024 ehf = gimple_build_eh_filter (EH_FILTER_TYPES (*expr_p), failure);
14025 gimple_set_no_warning (ehf, TREE_NO_WARNING (*expr_p));
14026 gimplify_seq_add_stmt (pre_p, ehf);
14027 ret = GS_ALL_DONE;
14028 break;
14031 case OBJ_TYPE_REF:
14033 enum gimplify_status r0, r1;
14034 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p,
14035 post_p, is_gimple_val, fb_rvalue);
14036 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p,
14037 post_p, is_gimple_val, fb_rvalue);
14038 TREE_SIDE_EFFECTS (*expr_p) = 0;
14039 ret = MIN (r0, r1);
14041 break;
14043 case LABEL_DECL:
14044 /* We get here when taking the address of a label. We mark
14045 the label as "forced"; meaning it can never be removed and
14046 it is a potential target for any computed goto. */
14047 FORCED_LABEL (*expr_p) = 1;
14048 ret = GS_ALL_DONE;
14049 break;
14051 case STATEMENT_LIST:
14052 ret = gimplify_statement_list (expr_p, pre_p);
14053 break;
14055 case WITH_SIZE_EXPR:
14057 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
14058 post_p == &internal_post ? NULL : post_p,
14059 gimple_test_f, fallback);
14060 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
14061 is_gimple_val, fb_rvalue);
14062 ret = GS_ALL_DONE;
14064 break;
14066 case VAR_DECL:
14067 case PARM_DECL:
14068 ret = gimplify_var_or_parm_decl (expr_p);
14069 break;
14071 case RESULT_DECL:
14072 /* When within an OMP context, notice uses of variables. */
14073 if (gimplify_omp_ctxp)
14074 omp_notice_variable (gimplify_omp_ctxp, *expr_p, true);
14075 ret = GS_ALL_DONE;
14076 break;
14078 case DEBUG_EXPR_DECL:
14079 gcc_unreachable ();
14081 case DEBUG_BEGIN_STMT:
14082 gimplify_seq_add_stmt (pre_p,
14083 gimple_build_debug_begin_stmt
14084 (TREE_BLOCK (*expr_p),
14085 EXPR_LOCATION (*expr_p)));
14086 ret = GS_ALL_DONE;
14087 *expr_p = NULL;
14088 break;
14090 case SSA_NAME:
14091 /* Allow callbacks into the gimplifier during optimization. */
14092 ret = GS_ALL_DONE;
14093 break;
14095 case OMP_PARALLEL:
14096 gimplify_omp_parallel (expr_p, pre_p);
14097 ret = GS_ALL_DONE;
14098 break;
14100 case OMP_TASK:
14101 gimplify_omp_task (expr_p, pre_p);
14102 ret = GS_ALL_DONE;
14103 break;
14105 case OMP_FOR:
14106 case OMP_SIMD:
14107 case OMP_DISTRIBUTE:
14108 case OMP_TASKLOOP:
14109 case OACC_LOOP:
14110 ret = gimplify_omp_for (expr_p, pre_p);
14111 break;
14113 case OMP_LOOP:
14114 ret = gimplify_omp_loop (expr_p, pre_p);
14115 break;
14117 case OACC_CACHE:
14118 gimplify_oacc_cache (expr_p, pre_p);
14119 ret = GS_ALL_DONE;
14120 break;
14122 case OACC_DECLARE:
14123 gimplify_oacc_declare (expr_p, pre_p);
14124 ret = GS_ALL_DONE;
14125 break;
14127 case OACC_HOST_DATA:
14128 case OACC_DATA:
14129 case OACC_KERNELS:
14130 case OACC_PARALLEL:
14131 case OACC_SERIAL:
14132 case OMP_SECTIONS:
14133 case OMP_SINGLE:
14134 case OMP_TARGET:
14135 case OMP_TARGET_DATA:
14136 case OMP_TEAMS:
14137 gimplify_omp_workshare (expr_p, pre_p);
14138 ret = GS_ALL_DONE;
14139 break;
14141 case OACC_ENTER_DATA:
14142 case OACC_EXIT_DATA:
14143 case OACC_UPDATE:
14144 case OMP_TARGET_UPDATE:
14145 case OMP_TARGET_ENTER_DATA:
14146 case OMP_TARGET_EXIT_DATA:
14147 gimplify_omp_target_update (expr_p, pre_p);
14148 ret = GS_ALL_DONE;
14149 break;
14151 case OMP_SECTION:
14152 case OMP_MASTER:
14153 case OMP_ORDERED:
14154 case OMP_CRITICAL:
14155 case OMP_SCAN:
14157 gimple_seq body = NULL;
14158 gimple *g;
14159 bool saved_in_omp_construct = in_omp_construct;
14161 in_omp_construct = true;
14162 gimplify_and_add (OMP_BODY (*expr_p), &body);
14163 in_omp_construct = saved_in_omp_construct;
14164 switch (TREE_CODE (*expr_p))
14166 case OMP_SECTION:
14167 g = gimple_build_omp_section (body);
14168 break;
14169 case OMP_MASTER:
14170 g = gimple_build_omp_master (body);
14171 break;
14172 case OMP_ORDERED:
14173 g = gimplify_omp_ordered (*expr_p, body);
14174 break;
14175 case OMP_CRITICAL:
14176 gimplify_scan_omp_clauses (&OMP_CRITICAL_CLAUSES (*expr_p),
14177 pre_p, ORT_WORKSHARE, OMP_CRITICAL);
14178 gimplify_adjust_omp_clauses (pre_p, body,
14179 &OMP_CRITICAL_CLAUSES (*expr_p),
14180 OMP_CRITICAL);
14181 g = gimple_build_omp_critical (body,
14182 OMP_CRITICAL_NAME (*expr_p),
14183 OMP_CRITICAL_CLAUSES (*expr_p));
14184 break;
14185 case OMP_SCAN:
14186 gimplify_scan_omp_clauses (&OMP_SCAN_CLAUSES (*expr_p),
14187 pre_p, ORT_WORKSHARE, OMP_SCAN);
14188 gimplify_adjust_omp_clauses (pre_p, body,
14189 &OMP_SCAN_CLAUSES (*expr_p),
14190 OMP_SCAN);
14191 g = gimple_build_omp_scan (body, OMP_SCAN_CLAUSES (*expr_p));
14192 break;
14193 default:
14194 gcc_unreachable ();
14196 gimplify_seq_add_stmt (pre_p, g);
14197 ret = GS_ALL_DONE;
14198 break;
14201 case OMP_TASKGROUP:
14203 gimple_seq body = NULL;
14205 tree *pclauses = &OMP_TASKGROUP_CLAUSES (*expr_p);
14206 bool saved_in_omp_construct = in_omp_construct;
14207 gimplify_scan_omp_clauses (pclauses, pre_p, ORT_TASKGROUP,
14208 OMP_TASKGROUP);
14209 gimplify_adjust_omp_clauses (pre_p, NULL, pclauses, OMP_TASKGROUP);
14211 in_omp_construct = true;
14212 gimplify_and_add (OMP_BODY (*expr_p), &body);
14213 in_omp_construct = saved_in_omp_construct;
14214 gimple_seq cleanup = NULL;
14215 tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_END);
14216 gimple *g = gimple_build_call (fn, 0);
14217 gimple_seq_add_stmt (&cleanup, g);
14218 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
14219 body = NULL;
14220 gimple_seq_add_stmt (&body, g);
14221 g = gimple_build_omp_taskgroup (body, *pclauses);
14222 gimplify_seq_add_stmt (pre_p, g);
14223 ret = GS_ALL_DONE;
14224 break;
14227 case OMP_ATOMIC:
14228 case OMP_ATOMIC_READ:
14229 case OMP_ATOMIC_CAPTURE_OLD:
14230 case OMP_ATOMIC_CAPTURE_NEW:
14231 ret = gimplify_omp_atomic (expr_p, pre_p);
14232 break;
14234 case TRANSACTION_EXPR:
14235 ret = gimplify_transaction (expr_p, pre_p);
14236 break;
14238 case TRUTH_AND_EXPR:
14239 case TRUTH_OR_EXPR:
14240 case TRUTH_XOR_EXPR:
14242 tree orig_type = TREE_TYPE (*expr_p);
14243 tree new_type, xop0, xop1;
14244 *expr_p = gimple_boolify (*expr_p);
14245 new_type = TREE_TYPE (*expr_p);
14246 if (!useless_type_conversion_p (orig_type, new_type))
14248 *expr_p = fold_convert_loc (input_location, orig_type, *expr_p);
14249 ret = GS_OK;
14250 break;
14253 /* Boolified binary truth expressions are semantically equivalent
14254 to bitwise binary expressions. Canonicalize them to the
14255 bitwise variant. */
14256 switch (TREE_CODE (*expr_p))
14258 case TRUTH_AND_EXPR:
14259 TREE_SET_CODE (*expr_p, BIT_AND_EXPR);
14260 break;
14261 case TRUTH_OR_EXPR:
14262 TREE_SET_CODE (*expr_p, BIT_IOR_EXPR);
14263 break;
14264 case TRUTH_XOR_EXPR:
14265 TREE_SET_CODE (*expr_p, BIT_XOR_EXPR);
14266 break;
14267 default:
14268 break;
14270 /* Now make sure that operands have compatible type to
14271 expression's new_type. */
14272 xop0 = TREE_OPERAND (*expr_p, 0);
14273 xop1 = TREE_OPERAND (*expr_p, 1);
14274 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop0)))
14275 TREE_OPERAND (*expr_p, 0) = fold_convert_loc (input_location,
14276 new_type,
14277 xop0);
14278 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop1)))
14279 TREE_OPERAND (*expr_p, 1) = fold_convert_loc (input_location,
14280 new_type,
14281 xop1);
14282 /* Continue classified as tcc_binary. */
14283 goto expr_2;
14286 case VEC_COND_EXPR:
14288 enum gimplify_status r0, r1, r2;
14290 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
14291 post_p, is_gimple_condexpr, fb_rvalue);
14292 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
14293 post_p, is_gimple_val, fb_rvalue);
14294 r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p,
14295 post_p, is_gimple_val, fb_rvalue);
14297 ret = MIN (MIN (r0, r1), r2);
14298 recalculate_side_effects (*expr_p);
14300 break;
14302 case VEC_PERM_EXPR:
14303 /* Classified as tcc_expression. */
14304 goto expr_3;
14306 case BIT_INSERT_EXPR:
14307 /* Argument 3 is a constant. */
14308 goto expr_2;
14310 case POINTER_PLUS_EXPR:
14312 enum gimplify_status r0, r1;
14313 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
14314 post_p, is_gimple_val, fb_rvalue);
14315 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
14316 post_p, is_gimple_val, fb_rvalue);
14317 recalculate_side_effects (*expr_p);
14318 ret = MIN (r0, r1);
14319 break;
14322 default:
14323 switch (TREE_CODE_CLASS (TREE_CODE (*expr_p)))
14325 case tcc_comparison:
14326 /* Handle comparison of objects of non scalar mode aggregates
14327 with a call to memcmp. It would be nice to only have to do
14328 this for variable-sized objects, but then we'd have to allow
14329 the same nest of reference nodes we allow for MODIFY_EXPR and
14330 that's too complex.
14332 Compare scalar mode aggregates as scalar mode values. Using
14333 memcmp for them would be very inefficient at best, and is
14334 plain wrong if bitfields are involved. */
14336 tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 1));
14338 /* Vector comparisons need no boolification. */
14339 if (TREE_CODE (type) == VECTOR_TYPE)
14340 goto expr_2;
14341 else if (!AGGREGATE_TYPE_P (type))
14343 tree org_type = TREE_TYPE (*expr_p);
14344 *expr_p = gimple_boolify (*expr_p);
14345 if (!useless_type_conversion_p (org_type,
14346 TREE_TYPE (*expr_p)))
14348 *expr_p = fold_convert_loc (input_location,
14349 org_type, *expr_p);
14350 ret = GS_OK;
14352 else
14353 goto expr_2;
14355 else if (TYPE_MODE (type) != BLKmode)
14356 ret = gimplify_scalar_mode_aggregate_compare (expr_p);
14357 else
14358 ret = gimplify_variable_sized_compare (expr_p);
14360 break;
14363 /* If *EXPR_P does not need to be special-cased, handle it
14364 according to its class. */
14365 case tcc_unary:
14366 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
14367 post_p, is_gimple_val, fb_rvalue);
14368 break;
14370 case tcc_binary:
14371 expr_2:
14373 enum gimplify_status r0, r1;
14375 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
14376 post_p, is_gimple_val, fb_rvalue);
14377 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
14378 post_p, is_gimple_val, fb_rvalue);
14380 ret = MIN (r0, r1);
14381 break;
14384 expr_3:
14386 enum gimplify_status r0, r1, r2;
14388 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
14389 post_p, is_gimple_val, fb_rvalue);
14390 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
14391 post_p, is_gimple_val, fb_rvalue);
14392 r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p,
14393 post_p, is_gimple_val, fb_rvalue);
14395 ret = MIN (MIN (r0, r1), r2);
14396 break;
14399 case tcc_declaration:
14400 case tcc_constant:
14401 ret = GS_ALL_DONE;
14402 goto dont_recalculate;
14404 default:
14405 gcc_unreachable ();
14408 recalculate_side_effects (*expr_p);
14410 dont_recalculate:
14411 break;
14414 gcc_assert (*expr_p || ret != GS_OK);
14416 while (ret == GS_OK);
14418 /* If we encountered an error_mark somewhere nested inside, either
14419 stub out the statement or propagate the error back out. */
14420 if (ret == GS_ERROR)
14422 if (is_statement)
14423 *expr_p = NULL;
14424 goto out;
14427 /* This was only valid as a return value from the langhook, which
14428 we handled. Make sure it doesn't escape from any other context. */
14429 gcc_assert (ret != GS_UNHANDLED);
14431 if (fallback == fb_none && *expr_p && !is_gimple_stmt (*expr_p))
14433 /* We aren't looking for a value, and we don't have a valid
14434 statement. If it doesn't have side-effects, throw it away.
14435 We can also get here with code such as "*&&L;", where L is
14436 a LABEL_DECL that is marked as FORCED_LABEL. */
14437 if (TREE_CODE (*expr_p) == LABEL_DECL
14438 || !TREE_SIDE_EFFECTS (*expr_p))
14439 *expr_p = NULL;
14440 else if (!TREE_THIS_VOLATILE (*expr_p))
14442 /* This is probably a _REF that contains something nested that
14443 has side effects. Recurse through the operands to find it. */
14444 enum tree_code code = TREE_CODE (*expr_p);
14446 switch (code)
14448 case COMPONENT_REF:
14449 case REALPART_EXPR:
14450 case IMAGPART_EXPR:
14451 case VIEW_CONVERT_EXPR:
14452 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
14453 gimple_test_f, fallback);
14454 break;
14456 case ARRAY_REF:
14457 case ARRAY_RANGE_REF:
14458 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
14459 gimple_test_f, fallback);
14460 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
14461 gimple_test_f, fallback);
14462 break;
14464 default:
14465 /* Anything else with side-effects must be converted to
14466 a valid statement before we get here. */
14467 gcc_unreachable ();
14470 *expr_p = NULL;
14472 else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p))
14473 && TYPE_MODE (TREE_TYPE (*expr_p)) != BLKmode)
14475 /* Historically, the compiler has treated a bare reference
14476 to a non-BLKmode volatile lvalue as forcing a load. */
14477 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p));
14479 /* Normally, we do not want to create a temporary for a
14480 TREE_ADDRESSABLE type because such a type should not be
14481 copied by bitwise-assignment. However, we make an
14482 exception here, as all we are doing here is ensuring that
14483 we read the bytes that make up the type. We use
14484 create_tmp_var_raw because create_tmp_var will abort when
14485 given a TREE_ADDRESSABLE type. */
14486 tree tmp = create_tmp_var_raw (type, "vol");
14487 gimple_add_tmp_var (tmp);
14488 gimplify_assign (tmp, *expr_p, pre_p);
14489 *expr_p = NULL;
14491 else
14492 /* We can't do anything useful with a volatile reference to
14493 an incomplete type, so just throw it away. Likewise for
14494 a BLKmode type, since any implicit inner load should
14495 already have been turned into an explicit one by the
14496 gimplification process. */
14497 *expr_p = NULL;
14500 /* If we are gimplifying at the statement level, we're done. Tack
14501 everything together and return. */
14502 if (fallback == fb_none || is_statement)
14504 /* Since *EXPR_P has been converted into a GIMPLE tuple, clear
14505 it out for GC to reclaim it. */
14506 *expr_p = NULL_TREE;
14508 if (!gimple_seq_empty_p (internal_pre)
14509 || !gimple_seq_empty_p (internal_post))
14511 gimplify_seq_add_seq (&internal_pre, internal_post);
14512 gimplify_seq_add_seq (pre_p, internal_pre);
14515 /* The result of gimplifying *EXPR_P is going to be the last few
14516 statements in *PRE_P and *POST_P. Add location information
14517 to all the statements that were added by the gimplification
14518 helpers. */
14519 if (!gimple_seq_empty_p (*pre_p))
14520 annotate_all_with_location_after (*pre_p, pre_last_gsi, input_location);
14522 if (!gimple_seq_empty_p (*post_p))
14523 annotate_all_with_location_after (*post_p, post_last_gsi,
14524 input_location);
14526 goto out;
14529 #ifdef ENABLE_GIMPLE_CHECKING
14530 if (*expr_p)
14532 enum tree_code code = TREE_CODE (*expr_p);
14533 /* These expressions should already be in gimple IR form. */
14534 gcc_assert (code != MODIFY_EXPR
14535 && code != ASM_EXPR
14536 && code != BIND_EXPR
14537 && code != CATCH_EXPR
14538 && (code != COND_EXPR || gimplify_ctxp->allow_rhs_cond_expr)
14539 && code != EH_FILTER_EXPR
14540 && code != GOTO_EXPR
14541 && code != LABEL_EXPR
14542 && code != LOOP_EXPR
14543 && code != SWITCH_EXPR
14544 && code != TRY_FINALLY_EXPR
14545 && code != EH_ELSE_EXPR
14546 && code != OACC_PARALLEL
14547 && code != OACC_KERNELS
14548 && code != OACC_SERIAL
14549 && code != OACC_DATA
14550 && code != OACC_HOST_DATA
14551 && code != OACC_DECLARE
14552 && code != OACC_UPDATE
14553 && code != OACC_ENTER_DATA
14554 && code != OACC_EXIT_DATA
14555 && code != OACC_CACHE
14556 && code != OMP_CRITICAL
14557 && code != OMP_FOR
14558 && code != OACC_LOOP
14559 && code != OMP_MASTER
14560 && code != OMP_TASKGROUP
14561 && code != OMP_ORDERED
14562 && code != OMP_PARALLEL
14563 && code != OMP_SCAN
14564 && code != OMP_SECTIONS
14565 && code != OMP_SECTION
14566 && code != OMP_SINGLE);
14568 #endif
14570 /* Otherwise we're gimplifying a subexpression, so the resulting
14571 value is interesting. If it's a valid operand that matches
14572 GIMPLE_TEST_F, we're done. Unless we are handling some
14573 post-effects internally; if that's the case, we need to copy into
14574 a temporary before adding the post-effects to POST_P. */
14575 if (gimple_seq_empty_p (internal_post) && (*gimple_test_f) (*expr_p))
14576 goto out;
14578 /* Otherwise, we need to create a new temporary for the gimplified
14579 expression. */
14581 /* We can't return an lvalue if we have an internal postqueue. The
14582 object the lvalue refers to would (probably) be modified by the
14583 postqueue; we need to copy the value out first, which means an
14584 rvalue. */
14585 if ((fallback & fb_lvalue)
14586 && gimple_seq_empty_p (internal_post)
14587 && is_gimple_addressable (*expr_p))
14589 /* An lvalue will do. Take the address of the expression, store it
14590 in a temporary, and replace the expression with an INDIRECT_REF of
14591 that temporary. */
14592 tree ref_alias_type = reference_alias_ptr_type (*expr_p);
14593 unsigned int ref_align = get_object_alignment (*expr_p);
14594 tree ref_type = TREE_TYPE (*expr_p);
14595 tmp = build_fold_addr_expr_loc (input_location, *expr_p);
14596 gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue);
14597 if (TYPE_ALIGN (ref_type) != ref_align)
14598 ref_type = build_aligned_type (ref_type, ref_align);
14599 *expr_p = build2 (MEM_REF, ref_type,
14600 tmp, build_zero_cst (ref_alias_type));
14602 else if ((fallback & fb_rvalue) && is_gimple_reg_rhs_or_call (*expr_p))
14604 /* An rvalue will do. Assign the gimplified expression into a
14605 new temporary TMP and replace the original expression with
14606 TMP. First, make sure that the expression has a type so that
14607 it can be assigned into a temporary. */
14608 gcc_assert (!VOID_TYPE_P (TREE_TYPE (*expr_p)));
14609 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
14611 else
14613 #ifdef ENABLE_GIMPLE_CHECKING
14614 if (!(fallback & fb_mayfail))
14616 fprintf (stderr, "gimplification failed:\n");
14617 print_generic_expr (stderr, *expr_p);
14618 debug_tree (*expr_p);
14619 internal_error ("gimplification failed");
14621 #endif
14622 gcc_assert (fallback & fb_mayfail);
14624 /* If this is an asm statement, and the user asked for the
14625 impossible, don't die. Fail and let gimplify_asm_expr
14626 issue an error. */
14627 ret = GS_ERROR;
14628 goto out;
14631 /* Make sure the temporary matches our predicate. */
14632 gcc_assert ((*gimple_test_f) (*expr_p));
14634 if (!gimple_seq_empty_p (internal_post))
14636 annotate_all_with_location (internal_post, input_location);
14637 gimplify_seq_add_seq (pre_p, internal_post);
14640 out:
14641 input_location = saved_location;
14642 return ret;
14645 /* Like gimplify_expr but make sure the gimplified result is not itself
14646 a SSA name (but a decl if it were). Temporaries required by
14647 evaluating *EXPR_P may be still SSA names. */
14649 static enum gimplify_status
14650 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
14651 bool (*gimple_test_f) (tree), fallback_t fallback,
14652 bool allow_ssa)
14654 bool was_ssa_name_p = TREE_CODE (*expr_p) == SSA_NAME;
14655 enum gimplify_status ret = gimplify_expr (expr_p, pre_p, post_p,
14656 gimple_test_f, fallback);
14657 if (! allow_ssa
14658 && TREE_CODE (*expr_p) == SSA_NAME)
14660 tree name = *expr_p;
14661 if (was_ssa_name_p)
14662 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, NULL, false);
14663 else
14665 /* Avoid the extra copy if possible. */
14666 *expr_p = create_tmp_reg (TREE_TYPE (name));
14667 if (!gimple_nop_p (SSA_NAME_DEF_STMT (name)))
14668 gimple_set_lhs (SSA_NAME_DEF_STMT (name), *expr_p);
14669 release_ssa_name (name);
14672 return ret;
14675 /* Look through TYPE for variable-sized objects and gimplify each such
14676 size that we find. Add to LIST_P any statements generated. */
14678 void
14679 gimplify_type_sizes (tree type, gimple_seq *list_p)
14681 tree field, t;
14683 if (type == NULL || type == error_mark_node)
14684 return;
14686 /* We first do the main variant, then copy into any other variants. */
14687 type = TYPE_MAIN_VARIANT (type);
14689 /* Avoid infinite recursion. */
14690 if (TYPE_SIZES_GIMPLIFIED (type))
14691 return;
14693 TYPE_SIZES_GIMPLIFIED (type) = 1;
14695 switch (TREE_CODE (type))
14697 case INTEGER_TYPE:
14698 case ENUMERAL_TYPE:
14699 case BOOLEAN_TYPE:
14700 case REAL_TYPE:
14701 case FIXED_POINT_TYPE:
14702 gimplify_one_sizepos (&TYPE_MIN_VALUE (type), list_p);
14703 gimplify_one_sizepos (&TYPE_MAX_VALUE (type), list_p);
14705 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
14707 TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type);
14708 TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type);
14710 break;
14712 case ARRAY_TYPE:
14713 /* These types may not have declarations, so handle them here. */
14714 gimplify_type_sizes (TREE_TYPE (type), list_p);
14715 gimplify_type_sizes (TYPE_DOMAIN (type), list_p);
14716 /* Ensure VLA bounds aren't removed, for -O0 they should be variables
14717 with assigned stack slots, for -O1+ -g they should be tracked
14718 by VTA. */
14719 if (!(TYPE_NAME (type)
14720 && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
14721 && DECL_IGNORED_P (TYPE_NAME (type)))
14722 && TYPE_DOMAIN (type)
14723 && INTEGRAL_TYPE_P (TYPE_DOMAIN (type)))
14725 t = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
14726 if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
14727 DECL_IGNORED_P (t) = 0;
14728 t = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
14729 if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
14730 DECL_IGNORED_P (t) = 0;
14732 break;
14734 case RECORD_TYPE:
14735 case UNION_TYPE:
14736 case QUAL_UNION_TYPE:
14737 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
14738 if (TREE_CODE (field) == FIELD_DECL)
14740 gimplify_one_sizepos (&DECL_FIELD_OFFSET (field), list_p);
14741 gimplify_one_sizepos (&DECL_SIZE (field), list_p);
14742 gimplify_one_sizepos (&DECL_SIZE_UNIT (field), list_p);
14743 gimplify_type_sizes (TREE_TYPE (field), list_p);
14745 break;
14747 case POINTER_TYPE:
14748 case REFERENCE_TYPE:
14749 /* We used to recurse on the pointed-to type here, which turned out to
14750 be incorrect because its definition might refer to variables not
14751 yet initialized at this point if a forward declaration is involved.
14753 It was actually useful for anonymous pointed-to types to ensure
14754 that the sizes evaluation dominates every possible later use of the
14755 values. Restricting to such types here would be safe since there
14756 is no possible forward declaration around, but would introduce an
14757 undesirable middle-end semantic to anonymity. We then defer to
14758 front-ends the responsibility of ensuring that the sizes are
14759 evaluated both early and late enough, e.g. by attaching artificial
14760 type declarations to the tree. */
14761 break;
14763 default:
14764 break;
14767 gimplify_one_sizepos (&TYPE_SIZE (type), list_p);
14768 gimplify_one_sizepos (&TYPE_SIZE_UNIT (type), list_p);
14770 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
14772 TYPE_SIZE (t) = TYPE_SIZE (type);
14773 TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (type);
14774 TYPE_SIZES_GIMPLIFIED (t) = 1;
14778 /* A subroutine of gimplify_type_sizes to make sure that *EXPR_P,
14779 a size or position, has had all of its SAVE_EXPRs evaluated.
14780 We add any required statements to *STMT_P. */
14782 void
14783 gimplify_one_sizepos (tree *expr_p, gimple_seq *stmt_p)
14785 tree expr = *expr_p;
14787 /* We don't do anything if the value isn't there, is constant, or contains
14788 A PLACEHOLDER_EXPR. We also don't want to do anything if it's already
14789 a VAR_DECL. If it's a VAR_DECL from another function, the gimplifier
14790 will want to replace it with a new variable, but that will cause problems
14791 if this type is from outside the function. It's OK to have that here. */
14792 if (expr == NULL_TREE
14793 || is_gimple_constant (expr)
14794 || TREE_CODE (expr) == VAR_DECL
14795 || CONTAINS_PLACEHOLDER_P (expr))
14796 return;
14798 *expr_p = unshare_expr (expr);
14800 /* SSA names in decl/type fields are a bad idea - they'll get reclaimed
14801 if the def vanishes. */
14802 gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue, false);
14804 /* If expr wasn't already is_gimple_sizepos or is_gimple_constant from the
14805 FE, ensure that it is a VAR_DECL, otherwise we might handle some decls
14806 as gimplify_vla_decl even when they would have all sizes INTEGER_CSTs. */
14807 if (is_gimple_constant (*expr_p))
14808 *expr_p = get_initialized_tmp_var (*expr_p, stmt_p, NULL, false);
14811 /* Gimplify the body of statements of FNDECL and return a GIMPLE_BIND node
14812 containing the sequence of corresponding GIMPLE statements. If DO_PARMS
14813 is true, also gimplify the parameters. */
14815 gbind *
14816 gimplify_body (tree fndecl, bool do_parms)
14818 location_t saved_location = input_location;
14819 gimple_seq parm_stmts, parm_cleanup = NULL, seq;
14820 gimple *outer_stmt;
14821 gbind *outer_bind;
14823 timevar_push (TV_TREE_GIMPLIFY);
14825 init_tree_ssa (cfun);
14827 /* Initialize for optimize_insn_for_s{ize,peed}_p possibly called during
14828 gimplification. */
14829 default_rtl_profile ();
14831 gcc_assert (gimplify_ctxp == NULL);
14832 push_gimplify_context (true);
14834 if (flag_openacc || flag_openmp)
14836 gcc_assert (gimplify_omp_ctxp == NULL);
14837 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (fndecl)))
14838 gimplify_omp_ctxp = new_omp_context (ORT_IMPLICIT_TARGET);
14841 /* Unshare most shared trees in the body and in that of any nested functions.
14842 It would seem we don't have to do this for nested functions because
14843 they are supposed to be output and then the outer function gimplified
14844 first, but the g++ front end doesn't always do it that way. */
14845 unshare_body (fndecl);
14846 unvisit_body (fndecl);
14848 /* Make sure input_location isn't set to something weird. */
14849 input_location = DECL_SOURCE_LOCATION (fndecl);
14851 /* Resolve callee-copies. This has to be done before processing
14852 the body so that DECL_VALUE_EXPR gets processed correctly. */
14853 parm_stmts = do_parms ? gimplify_parameters (&parm_cleanup) : NULL;
14855 /* Gimplify the function's body. */
14856 seq = NULL;
14857 gimplify_stmt (&DECL_SAVED_TREE (fndecl), &seq);
14858 outer_stmt = gimple_seq_first_nondebug_stmt (seq);
14859 if (!outer_stmt)
14861 outer_stmt = gimple_build_nop ();
14862 gimplify_seq_add_stmt (&seq, outer_stmt);
14865 /* The body must contain exactly one statement, a GIMPLE_BIND. If this is
14866 not the case, wrap everything in a GIMPLE_BIND to make it so. */
14867 if (gimple_code (outer_stmt) == GIMPLE_BIND
14868 && (gimple_seq_first_nondebug_stmt (seq)
14869 == gimple_seq_last_nondebug_stmt (seq)))
14871 outer_bind = as_a <gbind *> (outer_stmt);
14872 if (gimple_seq_first_stmt (seq) != outer_stmt
14873 || gimple_seq_last_stmt (seq) != outer_stmt)
14875 /* If there are debug stmts before or after outer_stmt, move them
14876 inside of outer_bind body. */
14877 gimple_stmt_iterator gsi = gsi_for_stmt (outer_stmt, &seq);
14878 gimple_seq second_seq = NULL;
14879 if (gimple_seq_first_stmt (seq) != outer_stmt
14880 && gimple_seq_last_stmt (seq) != outer_stmt)
14882 second_seq = gsi_split_seq_after (gsi);
14883 gsi_remove (&gsi, false);
14885 else if (gimple_seq_first_stmt (seq) != outer_stmt)
14886 gsi_remove (&gsi, false);
14887 else
14889 gsi_remove (&gsi, false);
14890 second_seq = seq;
14891 seq = NULL;
14893 gimple_seq_add_seq_without_update (&seq,
14894 gimple_bind_body (outer_bind));
14895 gimple_seq_add_seq_without_update (&seq, second_seq);
14896 gimple_bind_set_body (outer_bind, seq);
14899 else
14900 outer_bind = gimple_build_bind (NULL_TREE, seq, NULL);
14902 DECL_SAVED_TREE (fndecl) = NULL_TREE;
14904 /* If we had callee-copies statements, insert them at the beginning
14905 of the function and clear DECL_VALUE_EXPR_P on the parameters. */
14906 if (!gimple_seq_empty_p (parm_stmts))
14908 tree parm;
14910 gimplify_seq_add_seq (&parm_stmts, gimple_bind_body (outer_bind));
14911 if (parm_cleanup)
14913 gtry *g = gimple_build_try (parm_stmts, parm_cleanup,
14914 GIMPLE_TRY_FINALLY);
14915 parm_stmts = NULL;
14916 gimple_seq_add_stmt (&parm_stmts, g);
14918 gimple_bind_set_body (outer_bind, parm_stmts);
14920 for (parm = DECL_ARGUMENTS (current_function_decl);
14921 parm; parm = DECL_CHAIN (parm))
14922 if (DECL_HAS_VALUE_EXPR_P (parm))
14924 DECL_HAS_VALUE_EXPR_P (parm) = 0;
14925 DECL_IGNORED_P (parm) = 0;
14929 if ((flag_openacc || flag_openmp || flag_openmp_simd)
14930 && gimplify_omp_ctxp)
14932 delete_omp_context (gimplify_omp_ctxp);
14933 gimplify_omp_ctxp = NULL;
14936 pop_gimplify_context (outer_bind);
14937 gcc_assert (gimplify_ctxp == NULL);
14939 if (flag_checking && !seen_error ())
14940 verify_gimple_in_seq (gimple_bind_body (outer_bind));
14942 timevar_pop (TV_TREE_GIMPLIFY);
14943 input_location = saved_location;
14945 return outer_bind;
14948 typedef char *char_p; /* For DEF_VEC_P. */
14950 /* Return whether we should exclude FNDECL from instrumentation. */
14952 static bool
14953 flag_instrument_functions_exclude_p (tree fndecl)
14955 vec<char_p> *v;
14957 v = (vec<char_p> *) flag_instrument_functions_exclude_functions;
14958 if (v && v->length () > 0)
14960 const char *name;
14961 int i;
14962 char *s;
14964 name = lang_hooks.decl_printable_name (fndecl, 1);
14965 FOR_EACH_VEC_ELT (*v, i, s)
14966 if (strstr (name, s) != NULL)
14967 return true;
14970 v = (vec<char_p> *) flag_instrument_functions_exclude_files;
14971 if (v && v->length () > 0)
14973 const char *name;
14974 int i;
14975 char *s;
14977 name = DECL_SOURCE_FILE (fndecl);
14978 FOR_EACH_VEC_ELT (*v, i, s)
14979 if (strstr (name, s) != NULL)
14980 return true;
14983 return false;
14986 /* Entry point to the gimplification pass. FNDECL is the FUNCTION_DECL
14987 node for the function we want to gimplify.
14989 Return the sequence of GIMPLE statements corresponding to the body
14990 of FNDECL. */
14992 void
14993 gimplify_function_tree (tree fndecl)
14995 tree parm, ret;
14996 gimple_seq seq;
14997 gbind *bind;
14999 gcc_assert (!gimple_body (fndecl));
15001 if (DECL_STRUCT_FUNCTION (fndecl))
15002 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
15003 else
15004 push_struct_function (fndecl);
15006 /* Tentatively set PROP_gimple_lva here, and reset it in gimplify_va_arg_expr
15007 if necessary. */
15008 cfun->curr_properties |= PROP_gimple_lva;
15010 for (parm = DECL_ARGUMENTS (fndecl); parm ; parm = DECL_CHAIN (parm))
15012 /* Preliminarily mark non-addressed complex variables as eligible
15013 for promotion to gimple registers. We'll transform their uses
15014 as we find them. */
15015 if ((TREE_CODE (TREE_TYPE (parm)) == COMPLEX_TYPE
15016 || TREE_CODE (TREE_TYPE (parm)) == VECTOR_TYPE)
15017 && !TREE_THIS_VOLATILE (parm)
15018 && !needs_to_live_in_memory (parm))
15019 DECL_GIMPLE_REG_P (parm) = 1;
15022 ret = DECL_RESULT (fndecl);
15023 if ((TREE_CODE (TREE_TYPE (ret)) == COMPLEX_TYPE
15024 || TREE_CODE (TREE_TYPE (ret)) == VECTOR_TYPE)
15025 && !needs_to_live_in_memory (ret))
15026 DECL_GIMPLE_REG_P (ret) = 1;
15028 if (asan_sanitize_use_after_scope () && sanitize_flags_p (SANITIZE_ADDRESS))
15029 asan_poisoned_variables = new hash_set<tree> ();
15030 bind = gimplify_body (fndecl, true);
15031 if (asan_poisoned_variables)
15033 delete asan_poisoned_variables;
15034 asan_poisoned_variables = NULL;
15037 /* The tree body of the function is no longer needed, replace it
15038 with the new GIMPLE body. */
15039 seq = NULL;
15040 gimple_seq_add_stmt (&seq, bind);
15041 gimple_set_body (fndecl, seq);
15043 /* If we're instrumenting function entry/exit, then prepend the call to
15044 the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to
15045 catch the exit hook. */
15046 /* ??? Add some way to ignore exceptions for this TFE. */
15047 if (flag_instrument_function_entry_exit
15048 && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl)
15049 /* Do not instrument extern inline functions. */
15050 && !(DECL_DECLARED_INLINE_P (fndecl)
15051 && DECL_EXTERNAL (fndecl)
15052 && DECL_DISREGARD_INLINE_LIMITS (fndecl))
15053 && !flag_instrument_functions_exclude_p (fndecl))
15055 tree x;
15056 gbind *new_bind;
15057 gimple *tf;
15058 gimple_seq cleanup = NULL, body = NULL;
15059 tree tmp_var, this_fn_addr;
15060 gcall *call;
15062 /* The instrumentation hooks aren't going to call the instrumented
15063 function and the address they receive is expected to be matchable
15064 against symbol addresses. Make sure we don't create a trampoline,
15065 in case the current function is nested. */
15066 this_fn_addr = build_fold_addr_expr (current_function_decl);
15067 TREE_NO_TRAMPOLINE (this_fn_addr) = 1;
15069 x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
15070 call = gimple_build_call (x, 1, integer_zero_node);
15071 tmp_var = create_tmp_var (ptr_type_node, "return_addr");
15072 gimple_call_set_lhs (call, tmp_var);
15073 gimplify_seq_add_stmt (&cleanup, call);
15074 x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_EXIT);
15075 call = gimple_build_call (x, 2, this_fn_addr, tmp_var);
15076 gimplify_seq_add_stmt (&cleanup, call);
15077 tf = gimple_build_try (seq, cleanup, GIMPLE_TRY_FINALLY);
15079 x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
15080 call = gimple_build_call (x, 1, integer_zero_node);
15081 tmp_var = create_tmp_var (ptr_type_node, "return_addr");
15082 gimple_call_set_lhs (call, tmp_var);
15083 gimplify_seq_add_stmt (&body, call);
15084 x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_ENTER);
15085 call = gimple_build_call (x, 2, this_fn_addr, tmp_var);
15086 gimplify_seq_add_stmt (&body, call);
15087 gimplify_seq_add_stmt (&body, tf);
15088 new_bind = gimple_build_bind (NULL, body, NULL);
15090 /* Replace the current function body with the body
15091 wrapped in the try/finally TF. */
15092 seq = NULL;
15093 gimple_seq_add_stmt (&seq, new_bind);
15094 gimple_set_body (fndecl, seq);
15095 bind = new_bind;
15098 if (sanitize_flags_p (SANITIZE_THREAD))
15100 gcall *call = gimple_build_call_internal (IFN_TSAN_FUNC_EXIT, 0);
15101 gimple *tf = gimple_build_try (seq, call, GIMPLE_TRY_FINALLY);
15102 gbind *new_bind = gimple_build_bind (NULL, tf, NULL);
15103 /* Replace the current function body with the body
15104 wrapped in the try/finally TF. */
15105 seq = NULL;
15106 gimple_seq_add_stmt (&seq, new_bind);
15107 gimple_set_body (fndecl, seq);
15110 DECL_SAVED_TREE (fndecl) = NULL_TREE;
15111 cfun->curr_properties |= PROP_gimple_any;
15113 pop_cfun ();
15115 dump_function (TDI_gimple, fndecl);
15118 /* Return a dummy expression of type TYPE in order to keep going after an
15119 error. */
15121 static tree
15122 dummy_object (tree type)
15124 tree t = build_int_cst (build_pointer_type (type), 0);
15125 return build2 (MEM_REF, type, t, t);
15128 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
15129 builtin function, but a very special sort of operator. */
15131 enum gimplify_status
15132 gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p,
15133 gimple_seq *post_p ATTRIBUTE_UNUSED)
15135 tree promoted_type, have_va_type;
15136 tree valist = TREE_OPERAND (*expr_p, 0);
15137 tree type = TREE_TYPE (*expr_p);
15138 tree t, tag, aptag;
15139 location_t loc = EXPR_LOCATION (*expr_p);
15141 /* Verify that valist is of the proper type. */
15142 have_va_type = TREE_TYPE (valist);
15143 if (have_va_type == error_mark_node)
15144 return GS_ERROR;
15145 have_va_type = targetm.canonical_va_list_type (have_va_type);
15146 if (have_va_type == NULL_TREE
15147 && POINTER_TYPE_P (TREE_TYPE (valist)))
15148 /* Handle 'Case 1: Not an array type' from c-common.c/build_va_arg. */
15149 have_va_type
15150 = targetm.canonical_va_list_type (TREE_TYPE (TREE_TYPE (valist)));
15151 gcc_assert (have_va_type != NULL_TREE);
15153 /* Generate a diagnostic for requesting data of a type that cannot
15154 be passed through `...' due to type promotion at the call site. */
15155 if ((promoted_type = lang_hooks.types.type_promotes_to (type))
15156 != type)
15158 static bool gave_help;
15159 bool warned;
15160 /* Use the expansion point to handle cases such as passing bool (defined
15161 in a system header) through `...'. */
15162 location_t xloc
15163 = expansion_point_location_if_in_system_header (loc);
15165 /* Unfortunately, this is merely undefined, rather than a constraint
15166 violation, so we cannot make this an error. If this call is never
15167 executed, the program is still strictly conforming. */
15168 auto_diagnostic_group d;
15169 warned = warning_at (xloc, 0,
15170 "%qT is promoted to %qT when passed through %<...%>",
15171 type, promoted_type);
15172 if (!gave_help && warned)
15174 gave_help = true;
15175 inform (xloc, "(so you should pass %qT not %qT to %<va_arg%>)",
15176 promoted_type, type);
15179 /* We can, however, treat "undefined" any way we please.
15180 Call abort to encourage the user to fix the program. */
15181 if (warned)
15182 inform (xloc, "if this code is reached, the program will abort");
15183 /* Before the abort, allow the evaluation of the va_list
15184 expression to exit or longjmp. */
15185 gimplify_and_add (valist, pre_p);
15186 t = build_call_expr_loc (loc,
15187 builtin_decl_implicit (BUILT_IN_TRAP), 0);
15188 gimplify_and_add (t, pre_p);
15190 /* This is dead code, but go ahead and finish so that the
15191 mode of the result comes out right. */
15192 *expr_p = dummy_object (type);
15193 return GS_ALL_DONE;
15196 tag = build_int_cst (build_pointer_type (type), 0);
15197 aptag = build_int_cst (TREE_TYPE (valist), 0);
15199 *expr_p = build_call_expr_internal_loc (loc, IFN_VA_ARG, type, 3,
15200 valist, tag, aptag);
15202 /* Clear the tentatively set PROP_gimple_lva, to indicate that IFN_VA_ARG
15203 needs to be expanded. */
15204 cfun->curr_properties &= ~PROP_gimple_lva;
15206 return GS_OK;
15209 /* Build a new GIMPLE_ASSIGN tuple and append it to the end of *SEQ_P.
15211 DST/SRC are the destination and source respectively. You can pass
15212 ungimplified trees in DST or SRC, in which case they will be
15213 converted to a gimple operand if necessary.
15215 This function returns the newly created GIMPLE_ASSIGN tuple. */
15217 gimple *
15218 gimplify_assign (tree dst, tree src, gimple_seq *seq_p)
15220 tree t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
15221 gimplify_and_add (t, seq_p);
15222 ggc_free (t);
15223 return gimple_seq_last_stmt (*seq_p);
15226 inline hashval_t
15227 gimplify_hasher::hash (const elt_t *p)
15229 tree t = p->val;
15230 return iterative_hash_expr (t, 0);
15233 inline bool
15234 gimplify_hasher::equal (const elt_t *p1, const elt_t *p2)
15236 tree t1 = p1->val;
15237 tree t2 = p2->val;
15238 enum tree_code code = TREE_CODE (t1);
15240 if (TREE_CODE (t2) != code
15241 || TREE_TYPE (t1) != TREE_TYPE (t2))
15242 return false;
15244 if (!operand_equal_p (t1, t2, 0))
15245 return false;
15247 /* Only allow them to compare equal if they also hash equal; otherwise
15248 results are nondeterminate, and we fail bootstrap comparison. */
15249 gcc_checking_assert (hash (p1) == hash (p2));
15251 return true;