RISC-V: Fix more splitters accidentally calling gen_reg_rtx.
[official-gcc.git] / gcc / gimplify.c
blob623cdbfed7c758611466a2955c047ad3b6abf936
1 /* Tree lowering pass. This pass converts the GENERIC functions-as-trees
2 tree representation into the GIMPLE form.
3 Copyright (C) 2002-2019 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 GOVD_DATA_SHARE_CLASS = (GOVD_SHARED | GOVD_PRIVATE | GOVD_FIRSTPRIVATE
127 | GOVD_LASTPRIVATE | GOVD_REDUCTION | GOVD_LINEAR
128 | GOVD_LOCAL)
132 enum omp_region_type
134 ORT_WORKSHARE = 0x00,
135 ORT_TASKGROUP = 0x01,
136 ORT_SIMD = 0x04,
138 ORT_PARALLEL = 0x08,
139 ORT_COMBINED_PARALLEL = ORT_PARALLEL | 1,
141 ORT_TASK = 0x10,
142 ORT_UNTIED_TASK = ORT_TASK | 1,
143 ORT_TASKLOOP = ORT_TASK | 2,
144 ORT_UNTIED_TASKLOOP = ORT_UNTIED_TASK | 2,
146 ORT_TEAMS = 0x20,
147 ORT_COMBINED_TEAMS = ORT_TEAMS | 1,
148 ORT_HOST_TEAMS = ORT_TEAMS | 2,
149 ORT_COMBINED_HOST_TEAMS = ORT_COMBINED_TEAMS | 2,
151 /* Data region. */
152 ORT_TARGET_DATA = 0x40,
154 /* Data region with offloading. */
155 ORT_TARGET = 0x80,
156 ORT_COMBINED_TARGET = ORT_TARGET | 1,
157 ORT_IMPLICIT_TARGET = ORT_TARGET | 2,
159 /* OpenACC variants. */
160 ORT_ACC = 0x100, /* A generic OpenACC region. */
161 ORT_ACC_DATA = ORT_ACC | ORT_TARGET_DATA, /* Data construct. */
162 ORT_ACC_PARALLEL = ORT_ACC | ORT_TARGET, /* Parallel construct */
163 ORT_ACC_KERNELS = ORT_ACC | ORT_TARGET | 2, /* Kernels construct. */
164 ORT_ACC_HOST_DATA = ORT_ACC | ORT_TARGET_DATA | 2, /* Host data. */
166 /* Dummy OpenMP region, used to disable expansion of
167 DECL_VALUE_EXPRs in taskloop pre body. */
168 ORT_NONE = 0x200
171 /* Gimplify hashtable helper. */
173 struct gimplify_hasher : free_ptr_hash <elt_t>
175 static inline hashval_t hash (const elt_t *);
176 static inline bool equal (const elt_t *, const elt_t *);
179 struct gimplify_ctx
181 struct gimplify_ctx *prev_context;
183 vec<gbind *> bind_expr_stack;
184 tree temps;
185 gimple_seq conditional_cleanups;
186 tree exit_label;
187 tree return_temp;
189 vec<tree> case_labels;
190 hash_set<tree> *live_switch_vars;
191 /* The formal temporary table. Should this be persistent? */
192 hash_table<gimplify_hasher> *temp_htab;
194 int conditions;
195 unsigned into_ssa : 1;
196 unsigned allow_rhs_cond_expr : 1;
197 unsigned in_cleanup_point_expr : 1;
198 unsigned keep_stack : 1;
199 unsigned save_stack : 1;
200 unsigned in_switch_expr : 1;
203 enum gimplify_defaultmap_kind
205 GDMK_SCALAR,
206 GDMK_AGGREGATE,
207 GDMK_ALLOCATABLE,
208 GDMK_POINTER
211 struct gimplify_omp_ctx
213 struct gimplify_omp_ctx *outer_context;
214 splay_tree variables;
215 hash_set<tree> *privatized_types;
216 tree clauses;
217 /* Iteration variables in an OMP_FOR. */
218 vec<tree> loop_iter_var;
219 location_t location;
220 enum omp_clause_default_kind default_kind;
221 enum omp_region_type region_type;
222 bool combined_loop;
223 bool distribute;
224 bool target_firstprivatize_array_bases;
225 bool add_safelen1;
226 bool order_concurrent;
227 int defaultmap[4];
230 static struct gimplify_ctx *gimplify_ctxp;
231 static struct gimplify_omp_ctx *gimplify_omp_ctxp;
232 static bool in_omp_construct;
234 /* Forward declaration. */
235 static enum gimplify_status gimplify_compound_expr (tree *, gimple_seq *, bool);
236 static hash_map<tree, tree> *oacc_declare_returns;
237 static enum gimplify_status gimplify_expr (tree *, gimple_seq *, gimple_seq *,
238 bool (*) (tree), fallback_t, bool);
240 /* Shorter alias name for the above function for use in gimplify.c
241 only. */
243 static inline void
244 gimplify_seq_add_stmt (gimple_seq *seq_p, gimple *gs)
246 gimple_seq_add_stmt_without_update (seq_p, gs);
249 /* Append sequence SRC to the end of sequence *DST_P. If *DST_P is
250 NULL, a new sequence is allocated. This function is
251 similar to gimple_seq_add_seq, but does not scan the operands.
252 During gimplification, we need to manipulate statement sequences
253 before the def/use vectors have been constructed. */
255 static void
256 gimplify_seq_add_seq (gimple_seq *dst_p, gimple_seq src)
258 gimple_stmt_iterator si;
260 if (src == NULL)
261 return;
263 si = gsi_last (*dst_p);
264 gsi_insert_seq_after_without_update (&si, src, GSI_NEW_STMT);
268 /* Pointer to a list of allocated gimplify_ctx structs to be used for pushing
269 and popping gimplify contexts. */
271 static struct gimplify_ctx *ctx_pool = NULL;
273 /* Return a gimplify context struct from the pool. */
275 static inline struct gimplify_ctx *
276 ctx_alloc (void)
278 struct gimplify_ctx * c = ctx_pool;
280 if (c)
281 ctx_pool = c->prev_context;
282 else
283 c = XNEW (struct gimplify_ctx);
285 memset (c, '\0', sizeof (*c));
286 return c;
289 /* Put gimplify context C back into the pool. */
291 static inline void
292 ctx_free (struct gimplify_ctx *c)
294 c->prev_context = ctx_pool;
295 ctx_pool = c;
298 /* Free allocated ctx stack memory. */
300 void
301 free_gimplify_stack (void)
303 struct gimplify_ctx *c;
305 while ((c = ctx_pool))
307 ctx_pool = c->prev_context;
308 free (c);
313 /* Set up a context for the gimplifier. */
315 void
316 push_gimplify_context (bool in_ssa, bool rhs_cond_ok)
318 struct gimplify_ctx *c = ctx_alloc ();
320 c->prev_context = gimplify_ctxp;
321 gimplify_ctxp = c;
322 gimplify_ctxp->into_ssa = in_ssa;
323 gimplify_ctxp->allow_rhs_cond_expr = rhs_cond_ok;
326 /* Tear down a context for the gimplifier. If BODY is non-null, then
327 put the temporaries into the outer BIND_EXPR. Otherwise, put them
328 in the local_decls.
330 BODY is not a sequence, but the first tuple in a sequence. */
332 void
333 pop_gimplify_context (gimple *body)
335 struct gimplify_ctx *c = gimplify_ctxp;
337 gcc_assert (c
338 && (!c->bind_expr_stack.exists ()
339 || c->bind_expr_stack.is_empty ()));
340 c->bind_expr_stack.release ();
341 gimplify_ctxp = c->prev_context;
343 if (body)
344 declare_vars (c->temps, body, false);
345 else
346 record_vars (c->temps);
348 delete c->temp_htab;
349 c->temp_htab = NULL;
350 ctx_free (c);
353 /* Push a GIMPLE_BIND tuple onto the stack of bindings. */
355 static void
356 gimple_push_bind_expr (gbind *bind_stmt)
358 gimplify_ctxp->bind_expr_stack.reserve (8);
359 gimplify_ctxp->bind_expr_stack.safe_push (bind_stmt);
362 /* Pop the first element off the stack of bindings. */
364 static void
365 gimple_pop_bind_expr (void)
367 gimplify_ctxp->bind_expr_stack.pop ();
370 /* Return the first element of the stack of bindings. */
372 gbind *
373 gimple_current_bind_expr (void)
375 return gimplify_ctxp->bind_expr_stack.last ();
378 /* Return the stack of bindings created during gimplification. */
380 vec<gbind *>
381 gimple_bind_expr_stack (void)
383 return gimplify_ctxp->bind_expr_stack;
386 /* Return true iff there is a COND_EXPR between us and the innermost
387 CLEANUP_POINT_EXPR. This info is used by gimple_push_cleanup. */
389 static bool
390 gimple_conditional_context (void)
392 return gimplify_ctxp->conditions > 0;
395 /* Note that we've entered a COND_EXPR. */
397 static void
398 gimple_push_condition (void)
400 #ifdef ENABLE_GIMPLE_CHECKING
401 if (gimplify_ctxp->conditions == 0)
402 gcc_assert (gimple_seq_empty_p (gimplify_ctxp->conditional_cleanups));
403 #endif
404 ++(gimplify_ctxp->conditions);
407 /* Note that we've left a COND_EXPR. If we're back at unconditional scope
408 now, add any conditional cleanups we've seen to the prequeue. */
410 static void
411 gimple_pop_condition (gimple_seq *pre_p)
413 int conds = --(gimplify_ctxp->conditions);
415 gcc_assert (conds >= 0);
416 if (conds == 0)
418 gimplify_seq_add_seq (pre_p, gimplify_ctxp->conditional_cleanups);
419 gimplify_ctxp->conditional_cleanups = NULL;
423 /* A stable comparison routine for use with splay trees and DECLs. */
425 static int
426 splay_tree_compare_decl_uid (splay_tree_key xa, splay_tree_key xb)
428 tree a = (tree) xa;
429 tree b = (tree) xb;
431 return DECL_UID (a) - DECL_UID (b);
434 /* Create a new omp construct that deals with variable remapping. */
436 static struct gimplify_omp_ctx *
437 new_omp_context (enum omp_region_type region_type)
439 struct gimplify_omp_ctx *c;
441 c = XCNEW (struct gimplify_omp_ctx);
442 c->outer_context = gimplify_omp_ctxp;
443 c->variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0);
444 c->privatized_types = new hash_set<tree>;
445 c->location = input_location;
446 c->region_type = region_type;
447 if ((region_type & ORT_TASK) == 0)
448 c->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
449 else
450 c->default_kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
451 c->defaultmap[GDMK_SCALAR] = GOVD_MAP;
452 c->defaultmap[GDMK_AGGREGATE] = GOVD_MAP;
453 c->defaultmap[GDMK_ALLOCATABLE] = GOVD_MAP;
454 c->defaultmap[GDMK_POINTER] = GOVD_MAP;
456 return c;
459 /* Destroy an omp construct that deals with variable remapping. */
461 static void
462 delete_omp_context (struct gimplify_omp_ctx *c)
464 splay_tree_delete (c->variables);
465 delete c->privatized_types;
466 c->loop_iter_var.release ();
467 XDELETE (c);
470 static void omp_add_variable (struct gimplify_omp_ctx *, tree, unsigned int);
471 static bool omp_notice_variable (struct gimplify_omp_ctx *, tree, bool);
473 /* Both gimplify the statement T and append it to *SEQ_P. This function
474 behaves exactly as gimplify_stmt, but you don't have to pass T as a
475 reference. */
477 void
478 gimplify_and_add (tree t, gimple_seq *seq_p)
480 gimplify_stmt (&t, seq_p);
483 /* Gimplify statement T into sequence *SEQ_P, and return the first
484 tuple in the sequence of generated tuples for this statement.
485 Return NULL if gimplifying T produced no tuples. */
487 static gimple *
488 gimplify_and_return_first (tree t, gimple_seq *seq_p)
490 gimple_stmt_iterator last = gsi_last (*seq_p);
492 gimplify_and_add (t, seq_p);
494 if (!gsi_end_p (last))
496 gsi_next (&last);
497 return gsi_stmt (last);
499 else
500 return gimple_seq_first_stmt (*seq_p);
503 /* Returns true iff T is a valid RHS for an assignment to an un-renamed
504 LHS, or for a call argument. */
506 static bool
507 is_gimple_mem_rhs (tree t)
509 /* If we're dealing with a renamable type, either source or dest must be
510 a renamed variable. */
511 if (is_gimple_reg_type (TREE_TYPE (t)))
512 return is_gimple_val (t);
513 else
514 return is_gimple_val (t) || is_gimple_lvalue (t);
517 /* Return true if T is a CALL_EXPR or an expression that can be
518 assigned to a temporary. Note that this predicate should only be
519 used during gimplification. See the rationale for this in
520 gimplify_modify_expr. */
522 static bool
523 is_gimple_reg_rhs_or_call (tree t)
525 return (get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS
526 || TREE_CODE (t) == CALL_EXPR);
529 /* Return true if T is a valid memory RHS or a CALL_EXPR. Note that
530 this predicate should only be used during gimplification. See the
531 rationale for this in gimplify_modify_expr. */
533 static bool
534 is_gimple_mem_rhs_or_call (tree t)
536 /* If we're dealing with a renamable type, either source or dest must be
537 a renamed variable. */
538 if (is_gimple_reg_type (TREE_TYPE (t)))
539 return is_gimple_val (t);
540 else
541 return (is_gimple_val (t)
542 || is_gimple_lvalue (t)
543 || TREE_CLOBBER_P (t)
544 || TREE_CODE (t) == CALL_EXPR);
547 /* Create a temporary with a name derived from VAL. Subroutine of
548 lookup_tmp_var; nobody else should call this function. */
550 static inline tree
551 create_tmp_from_val (tree val)
553 /* Drop all qualifiers and address-space information from the value type. */
554 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (val));
555 tree var = create_tmp_var (type, get_name (val));
556 if (TREE_CODE (TREE_TYPE (var)) == COMPLEX_TYPE
557 || TREE_CODE (TREE_TYPE (var)) == VECTOR_TYPE)
558 DECL_GIMPLE_REG_P (var) = 1;
559 return var;
562 /* Create a temporary to hold the value of VAL. If IS_FORMAL, try to reuse
563 an existing expression temporary. */
565 static tree
566 lookup_tmp_var (tree val, bool is_formal)
568 tree ret;
570 /* If not optimizing, never really reuse a temporary. local-alloc
571 won't allocate any variable that is used in more than one basic
572 block, which means it will go into memory, causing much extra
573 work in reload and final and poorer code generation, outweighing
574 the extra memory allocation here. */
575 if (!optimize || !is_formal || TREE_SIDE_EFFECTS (val))
576 ret = create_tmp_from_val (val);
577 else
579 elt_t elt, *elt_p;
580 elt_t **slot;
582 elt.val = val;
583 if (!gimplify_ctxp->temp_htab)
584 gimplify_ctxp->temp_htab = new hash_table<gimplify_hasher> (1000);
585 slot = gimplify_ctxp->temp_htab->find_slot (&elt, INSERT);
586 if (*slot == NULL)
588 elt_p = XNEW (elt_t);
589 elt_p->val = val;
590 elt_p->temp = ret = create_tmp_from_val (val);
591 *slot = elt_p;
593 else
595 elt_p = *slot;
596 ret = elt_p->temp;
600 return ret;
603 /* Helper for get_formal_tmp_var and get_initialized_tmp_var. */
605 static tree
606 internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
607 bool is_formal, bool allow_ssa)
609 tree t, mod;
611 /* Notice that we explicitly allow VAL to be a CALL_EXPR so that we
612 can create an INIT_EXPR and convert it into a GIMPLE_CALL below. */
613 gimplify_expr (&val, pre_p, post_p, is_gimple_reg_rhs_or_call,
614 fb_rvalue);
616 if (allow_ssa
617 && gimplify_ctxp->into_ssa
618 && is_gimple_reg_type (TREE_TYPE (val)))
620 t = make_ssa_name (TYPE_MAIN_VARIANT (TREE_TYPE (val)));
621 if (! gimple_in_ssa_p (cfun))
623 const char *name = get_name (val);
624 if (name)
625 SET_SSA_NAME_VAR_OR_IDENTIFIER (t, create_tmp_var_name (name));
628 else
629 t = lookup_tmp_var (val, is_formal);
631 mod = build2 (INIT_EXPR, TREE_TYPE (t), t, unshare_expr (val));
633 SET_EXPR_LOCATION (mod, EXPR_LOC_OR_LOC (val, input_location));
635 /* gimplify_modify_expr might want to reduce this further. */
636 gimplify_and_add (mod, pre_p);
637 ggc_free (mod);
639 return t;
642 /* Return a formal temporary variable initialized with VAL. PRE_P is as
643 in gimplify_expr. Only use this function if:
645 1) The value of the unfactored expression represented by VAL will not
646 change between the initialization and use of the temporary, and
647 2) The temporary will not be otherwise modified.
649 For instance, #1 means that this is inappropriate for SAVE_EXPR temps,
650 and #2 means it is inappropriate for && temps.
652 For other cases, use get_initialized_tmp_var instead. */
654 tree
655 get_formal_tmp_var (tree val, gimple_seq *pre_p)
657 return internal_get_tmp_var (val, pre_p, NULL, true, true);
660 /* Return a temporary variable initialized with VAL. PRE_P and POST_P
661 are as in gimplify_expr. */
663 tree
664 get_initialized_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
665 bool allow_ssa)
667 return internal_get_tmp_var (val, pre_p, post_p, false, allow_ssa);
670 /* Declare all the variables in VARS in SCOPE. If DEBUG_INFO is true,
671 generate debug info for them; otherwise don't. */
673 void
674 declare_vars (tree vars, gimple *gs, bool debug_info)
676 tree last = vars;
677 if (last)
679 tree temps, block;
681 gbind *scope = as_a <gbind *> (gs);
683 temps = nreverse (last);
685 block = gimple_bind_block (scope);
686 gcc_assert (!block || TREE_CODE (block) == BLOCK);
687 if (!block || !debug_info)
689 DECL_CHAIN (last) = gimple_bind_vars (scope);
690 gimple_bind_set_vars (scope, temps);
692 else
694 /* We need to attach the nodes both to the BIND_EXPR and to its
695 associated BLOCK for debugging purposes. The key point here
696 is that the BLOCK_VARS of the BIND_EXPR_BLOCK of a BIND_EXPR
697 is a subchain of the BIND_EXPR_VARS of the BIND_EXPR. */
698 if (BLOCK_VARS (block))
699 BLOCK_VARS (block) = chainon (BLOCK_VARS (block), temps);
700 else
702 gimple_bind_set_vars (scope,
703 chainon (gimple_bind_vars (scope), temps));
704 BLOCK_VARS (block) = temps;
710 /* For VAR a VAR_DECL of variable size, try to find a constant upper bound
711 for the size and adjust DECL_SIZE/DECL_SIZE_UNIT accordingly. Abort if
712 no such upper bound can be obtained. */
714 static void
715 force_constant_size (tree var)
717 /* The only attempt we make is by querying the maximum size of objects
718 of the variable's type. */
720 HOST_WIDE_INT max_size;
722 gcc_assert (VAR_P (var));
724 max_size = max_int_size_in_bytes (TREE_TYPE (var));
726 gcc_assert (max_size >= 0);
728 DECL_SIZE_UNIT (var)
729 = build_int_cst (TREE_TYPE (DECL_SIZE_UNIT (var)), max_size);
730 DECL_SIZE (var)
731 = build_int_cst (TREE_TYPE (DECL_SIZE (var)), max_size * BITS_PER_UNIT);
734 /* Push the temporary variable TMP into the current binding. */
736 void
737 gimple_add_tmp_var_fn (struct function *fn, tree tmp)
739 gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
741 /* Later processing assumes that the object size is constant, which might
742 not be true at this point. Force the use of a constant upper bound in
743 this case. */
744 if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp)))
745 force_constant_size (tmp);
747 DECL_CONTEXT (tmp) = fn->decl;
748 DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
750 record_vars_into (tmp, fn->decl);
753 /* Push the temporary variable TMP into the current binding. */
755 void
756 gimple_add_tmp_var (tree tmp)
758 gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
760 /* Later processing assumes that the object size is constant, which might
761 not be true at this point. Force the use of a constant upper bound in
762 this case. */
763 if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp)))
764 force_constant_size (tmp);
766 DECL_CONTEXT (tmp) = current_function_decl;
767 DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
769 if (gimplify_ctxp)
771 DECL_CHAIN (tmp) = gimplify_ctxp->temps;
772 gimplify_ctxp->temps = tmp;
774 /* Mark temporaries local within the nearest enclosing parallel. */
775 if (gimplify_omp_ctxp)
777 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
778 int flag = GOVD_LOCAL;
779 while (ctx
780 && (ctx->region_type == ORT_WORKSHARE
781 || ctx->region_type == ORT_TASKGROUP
782 || ctx->region_type == ORT_SIMD
783 || ctx->region_type == ORT_ACC))
785 if (ctx->region_type == ORT_SIMD
786 && TREE_ADDRESSABLE (tmp)
787 && !TREE_STATIC (tmp))
789 if (TREE_CODE (DECL_SIZE_UNIT (tmp)) != INTEGER_CST)
790 ctx->add_safelen1 = true;
791 else
792 flag = GOVD_PRIVATE;
793 break;
795 ctx = ctx->outer_context;
797 if (ctx)
798 omp_add_variable (ctx, tmp, flag | GOVD_SEEN);
801 else if (cfun)
802 record_vars (tmp);
803 else
805 gimple_seq body_seq;
807 /* This case is for nested functions. We need to expose the locals
808 they create. */
809 body_seq = gimple_body (current_function_decl);
810 declare_vars (tmp, gimple_seq_first_stmt (body_seq), false);
816 /* This page contains routines to unshare tree nodes, i.e. to duplicate tree
817 nodes that are referenced more than once in GENERIC functions. This is
818 necessary because gimplification (translation into GIMPLE) is performed
819 by modifying tree nodes in-place, so gimplication of a shared node in a
820 first context could generate an invalid GIMPLE form in a second context.
822 This is achieved with a simple mark/copy/unmark algorithm that walks the
823 GENERIC representation top-down, marks nodes with TREE_VISITED the first
824 time it encounters them, duplicates them if they already have TREE_VISITED
825 set, and finally removes the TREE_VISITED marks it has set.
827 The algorithm works only at the function level, i.e. it generates a GENERIC
828 representation of a function with no nodes shared within the function when
829 passed a GENERIC function (except for nodes that are allowed to be shared).
831 At the global level, it is also necessary to unshare tree nodes that are
832 referenced in more than one function, for the same aforementioned reason.
833 This requires some cooperation from the front-end. There are 2 strategies:
835 1. Manual unsharing. The front-end needs to call unshare_expr on every
836 expression that might end up being shared across functions.
838 2. Deep unsharing. This is an extension of regular unsharing. Instead
839 of calling unshare_expr on expressions that might be shared across
840 functions, the front-end pre-marks them with TREE_VISITED. This will
841 ensure that they are unshared on the first reference within functions
842 when the regular unsharing algorithm runs. The counterpart is that
843 this algorithm must look deeper than for manual unsharing, which is
844 specified by LANG_HOOKS_DEEP_UNSHARING.
846 If there are only few specific cases of node sharing across functions, it is
847 probably easier for a front-end to unshare the expressions manually. On the
848 contrary, if the expressions generated at the global level are as widespread
849 as expressions generated within functions, deep unsharing is very likely the
850 way to go. */
852 /* Similar to copy_tree_r but do not copy SAVE_EXPR or TARGET_EXPR nodes.
853 These nodes model computations that must be done once. If we were to
854 unshare something like SAVE_EXPR(i++), the gimplification process would
855 create wrong code. However, if DATA is non-null, it must hold a pointer
856 set that is used to unshare the subtrees of these nodes. */
858 static tree
859 mostly_copy_tree_r (tree *tp, int *walk_subtrees, void *data)
861 tree t = *tp;
862 enum tree_code code = TREE_CODE (t);
864 /* Do not copy SAVE_EXPR, TARGET_EXPR or BIND_EXPR nodes themselves, but
865 copy their subtrees if we can make sure to do it only once. */
866 if (code == SAVE_EXPR || code == TARGET_EXPR || code == BIND_EXPR)
868 if (data && !((hash_set<tree> *)data)->add (t))
870 else
871 *walk_subtrees = 0;
874 /* Stop at types, decls, constants like copy_tree_r. */
875 else if (TREE_CODE_CLASS (code) == tcc_type
876 || TREE_CODE_CLASS (code) == tcc_declaration
877 || TREE_CODE_CLASS (code) == tcc_constant)
878 *walk_subtrees = 0;
880 /* Cope with the statement expression extension. */
881 else if (code == STATEMENT_LIST)
884 /* Leave the bulk of the work to copy_tree_r itself. */
885 else
886 copy_tree_r (tp, walk_subtrees, NULL);
888 return NULL_TREE;
891 /* Callback for walk_tree to unshare most of the shared trees rooted at *TP.
892 If *TP has been visited already, then *TP is deeply copied by calling
893 mostly_copy_tree_r. DATA is passed to mostly_copy_tree_r unmodified. */
895 static tree
896 copy_if_shared_r (tree *tp, int *walk_subtrees, void *data)
898 tree t = *tp;
899 enum tree_code code = TREE_CODE (t);
901 /* Skip types, decls, and constants. But we do want to look at their
902 types and the bounds of types. Mark them as visited so we properly
903 unmark their subtrees on the unmark pass. If we've already seen them,
904 don't look down further. */
905 if (TREE_CODE_CLASS (code) == tcc_type
906 || TREE_CODE_CLASS (code) == tcc_declaration
907 || TREE_CODE_CLASS (code) == tcc_constant)
909 if (TREE_VISITED (t))
910 *walk_subtrees = 0;
911 else
912 TREE_VISITED (t) = 1;
915 /* If this node has been visited already, unshare it and don't look
916 any deeper. */
917 else if (TREE_VISITED (t))
919 walk_tree (tp, mostly_copy_tree_r, data, NULL);
920 *walk_subtrees = 0;
923 /* Otherwise, mark the node as visited and keep looking. */
924 else
925 TREE_VISITED (t) = 1;
927 return NULL_TREE;
930 /* Unshare most of the shared trees rooted at *TP. DATA is passed to the
931 copy_if_shared_r callback unmodified. */
933 static inline void
934 copy_if_shared (tree *tp, void *data)
936 walk_tree (tp, copy_if_shared_r, data, NULL);
939 /* Unshare all the trees in the body of FNDECL, as well as in the bodies of
940 any nested functions. */
942 static void
943 unshare_body (tree fndecl)
945 struct cgraph_node *cgn = cgraph_node::get (fndecl);
946 /* If the language requires deep unsharing, we need a pointer set to make
947 sure we don't repeatedly unshare subtrees of unshareable nodes. */
948 hash_set<tree> *visited
949 = lang_hooks.deep_unsharing ? new hash_set<tree> : NULL;
951 copy_if_shared (&DECL_SAVED_TREE (fndecl), visited);
952 copy_if_shared (&DECL_SIZE (DECL_RESULT (fndecl)), visited);
953 copy_if_shared (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)), visited);
955 delete visited;
957 if (cgn)
958 for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
959 unshare_body (cgn->decl);
962 /* Callback for walk_tree to unmark the visited trees rooted at *TP.
963 Subtrees are walked until the first unvisited node is encountered. */
965 static tree
966 unmark_visited_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
968 tree t = *tp;
970 /* If this node has been visited, unmark it and keep looking. */
971 if (TREE_VISITED (t))
972 TREE_VISITED (t) = 0;
974 /* Otherwise, don't look any deeper. */
975 else
976 *walk_subtrees = 0;
978 return NULL_TREE;
981 /* Unmark the visited trees rooted at *TP. */
983 static inline void
984 unmark_visited (tree *tp)
986 walk_tree (tp, unmark_visited_r, NULL, NULL);
989 /* Likewise, but mark all trees as not visited. */
991 static void
992 unvisit_body (tree fndecl)
994 struct cgraph_node *cgn = cgraph_node::get (fndecl);
996 unmark_visited (&DECL_SAVED_TREE (fndecl));
997 unmark_visited (&DECL_SIZE (DECL_RESULT (fndecl)));
998 unmark_visited (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)));
1000 if (cgn)
1001 for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
1002 unvisit_body (cgn->decl);
1005 /* Unconditionally make an unshared copy of EXPR. This is used when using
1006 stored expressions which span multiple functions, such as BINFO_VTABLE,
1007 as the normal unsharing process can't tell that they're shared. */
1009 tree
1010 unshare_expr (tree expr)
1012 walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
1013 return expr;
1016 /* Worker for unshare_expr_without_location. */
1018 static tree
1019 prune_expr_location (tree *tp, int *walk_subtrees, void *)
1021 if (EXPR_P (*tp))
1022 SET_EXPR_LOCATION (*tp, UNKNOWN_LOCATION);
1023 else
1024 *walk_subtrees = 0;
1025 return NULL_TREE;
1028 /* Similar to unshare_expr but also prune all expression locations
1029 from EXPR. */
1031 tree
1032 unshare_expr_without_location (tree expr)
1034 walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
1035 if (EXPR_P (expr))
1036 walk_tree (&expr, prune_expr_location, NULL, NULL);
1037 return expr;
1040 /* Return the EXPR_LOCATION of EXPR, if it (maybe recursively) has
1041 one, OR_ELSE otherwise. The location of a STATEMENT_LISTs
1042 comprising at least one DEBUG_BEGIN_STMT followed by exactly one
1043 EXPR is the location of the EXPR. */
1045 static location_t
1046 rexpr_location (tree expr, location_t or_else = UNKNOWN_LOCATION)
1048 if (!expr)
1049 return or_else;
1051 if (EXPR_HAS_LOCATION (expr))
1052 return EXPR_LOCATION (expr);
1054 if (TREE_CODE (expr) != STATEMENT_LIST)
1055 return or_else;
1057 tree_stmt_iterator i = tsi_start (expr);
1059 bool found = false;
1060 while (!tsi_end_p (i) && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT)
1062 found = true;
1063 tsi_next (&i);
1066 if (!found || !tsi_one_before_end_p (i))
1067 return or_else;
1069 return rexpr_location (tsi_stmt (i), or_else);
1072 /* Return TRUE iff EXPR (maybe recursively) has a location; see
1073 rexpr_location for the potential recursion. */
1075 static inline bool
1076 rexpr_has_location (tree expr)
1078 return rexpr_location (expr) != UNKNOWN_LOCATION;
1082 /* WRAPPER is a code such as BIND_EXPR or CLEANUP_POINT_EXPR which can both
1083 contain statements and have a value. Assign its value to a temporary
1084 and give it void_type_node. Return the temporary, or NULL_TREE if
1085 WRAPPER was already void. */
1087 tree
1088 voidify_wrapper_expr (tree wrapper, tree temp)
1090 tree type = TREE_TYPE (wrapper);
1091 if (type && !VOID_TYPE_P (type))
1093 tree *p;
1095 /* Set p to point to the body of the wrapper. Loop until we find
1096 something that isn't a wrapper. */
1097 for (p = &wrapper; p && *p; )
1099 switch (TREE_CODE (*p))
1101 case BIND_EXPR:
1102 TREE_SIDE_EFFECTS (*p) = 1;
1103 TREE_TYPE (*p) = void_type_node;
1104 /* For a BIND_EXPR, the body is operand 1. */
1105 p = &BIND_EXPR_BODY (*p);
1106 break;
1108 case CLEANUP_POINT_EXPR:
1109 case TRY_FINALLY_EXPR:
1110 case TRY_CATCH_EXPR:
1111 TREE_SIDE_EFFECTS (*p) = 1;
1112 TREE_TYPE (*p) = void_type_node;
1113 p = &TREE_OPERAND (*p, 0);
1114 break;
1116 case STATEMENT_LIST:
1118 tree_stmt_iterator i = tsi_last (*p);
1119 TREE_SIDE_EFFECTS (*p) = 1;
1120 TREE_TYPE (*p) = void_type_node;
1121 p = tsi_end_p (i) ? NULL : tsi_stmt_ptr (i);
1123 break;
1125 case COMPOUND_EXPR:
1126 /* Advance to the last statement. Set all container types to
1127 void. */
1128 for (; TREE_CODE (*p) == COMPOUND_EXPR; p = &TREE_OPERAND (*p, 1))
1130 TREE_SIDE_EFFECTS (*p) = 1;
1131 TREE_TYPE (*p) = void_type_node;
1133 break;
1135 case TRANSACTION_EXPR:
1136 TREE_SIDE_EFFECTS (*p) = 1;
1137 TREE_TYPE (*p) = void_type_node;
1138 p = &TRANSACTION_EXPR_BODY (*p);
1139 break;
1141 default:
1142 /* Assume that any tree upon which voidify_wrapper_expr is
1143 directly called is a wrapper, and that its body is op0. */
1144 if (p == &wrapper)
1146 TREE_SIDE_EFFECTS (*p) = 1;
1147 TREE_TYPE (*p) = void_type_node;
1148 p = &TREE_OPERAND (*p, 0);
1149 break;
1151 goto out;
1155 out:
1156 if (p == NULL || IS_EMPTY_STMT (*p))
1157 temp = NULL_TREE;
1158 else if (temp)
1160 /* The wrapper is on the RHS of an assignment that we're pushing
1161 down. */
1162 gcc_assert (TREE_CODE (temp) == INIT_EXPR
1163 || TREE_CODE (temp) == MODIFY_EXPR);
1164 TREE_OPERAND (temp, 1) = *p;
1165 *p = temp;
1167 else
1169 temp = create_tmp_var (type, "retval");
1170 *p = build2 (INIT_EXPR, type, temp, *p);
1173 return temp;
1176 return NULL_TREE;
1179 /* Prepare calls to builtins to SAVE and RESTORE the stack as well as
1180 a temporary through which they communicate. */
1182 static void
1183 build_stack_save_restore (gcall **save, gcall **restore)
1185 tree tmp_var;
1187 *save = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_SAVE), 0);
1188 tmp_var = create_tmp_var (ptr_type_node, "saved_stack");
1189 gimple_call_set_lhs (*save, tmp_var);
1191 *restore
1192 = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_RESTORE),
1193 1, tmp_var);
1196 /* Generate IFN_ASAN_MARK call that poisons shadow of a for DECL variable. */
1198 static tree
1199 build_asan_poison_call_expr (tree decl)
1201 /* Do not poison variables that have size equal to zero. */
1202 tree unit_size = DECL_SIZE_UNIT (decl);
1203 if (zerop (unit_size))
1204 return NULL_TREE;
1206 tree base = build_fold_addr_expr (decl);
1208 return build_call_expr_internal_loc (UNKNOWN_LOCATION, IFN_ASAN_MARK,
1209 void_type_node, 3,
1210 build_int_cst (integer_type_node,
1211 ASAN_MARK_POISON),
1212 base, unit_size);
1215 /* Generate IFN_ASAN_MARK call that would poison or unpoison, depending
1216 on POISON flag, shadow memory of a DECL variable. The call will be
1217 put on location identified by IT iterator, where BEFORE flag drives
1218 position where the stmt will be put. */
1220 static void
1221 asan_poison_variable (tree decl, bool poison, gimple_stmt_iterator *it,
1222 bool before)
1224 tree unit_size = DECL_SIZE_UNIT (decl);
1225 tree base = build_fold_addr_expr (decl);
1227 /* Do not poison variables that have size equal to zero. */
1228 if (zerop (unit_size))
1229 return;
1231 /* It's necessary to have all stack variables aligned to ASAN granularity
1232 bytes. */
1233 if (DECL_ALIGN_UNIT (decl) <= ASAN_SHADOW_GRANULARITY)
1234 SET_DECL_ALIGN (decl, BITS_PER_UNIT * ASAN_SHADOW_GRANULARITY);
1236 HOST_WIDE_INT flags = poison ? ASAN_MARK_POISON : ASAN_MARK_UNPOISON;
1238 gimple *g
1239 = gimple_build_call_internal (IFN_ASAN_MARK, 3,
1240 build_int_cst (integer_type_node, flags),
1241 base, unit_size);
1243 if (before)
1244 gsi_insert_before (it, g, GSI_NEW_STMT);
1245 else
1246 gsi_insert_after (it, g, GSI_NEW_STMT);
1249 /* Generate IFN_ASAN_MARK internal call that depending on POISON flag
1250 either poisons or unpoisons a DECL. Created statement is appended
1251 to SEQ_P gimple sequence. */
1253 static void
1254 asan_poison_variable (tree decl, bool poison, gimple_seq *seq_p)
1256 gimple_stmt_iterator it = gsi_last (*seq_p);
1257 bool before = false;
1259 if (gsi_end_p (it))
1260 before = true;
1262 asan_poison_variable (decl, poison, &it, before);
1265 /* Sort pair of VAR_DECLs A and B by DECL_UID. */
1267 static int
1268 sort_by_decl_uid (const void *a, const void *b)
1270 const tree *t1 = (const tree *)a;
1271 const tree *t2 = (const tree *)b;
1273 int uid1 = DECL_UID (*t1);
1274 int uid2 = DECL_UID (*t2);
1276 if (uid1 < uid2)
1277 return -1;
1278 else if (uid1 > uid2)
1279 return 1;
1280 else
1281 return 0;
1284 /* Generate IFN_ASAN_MARK internal call for all VARIABLES
1285 depending on POISON flag. Created statement is appended
1286 to SEQ_P gimple sequence. */
1288 static void
1289 asan_poison_variables (hash_set<tree> *variables, bool poison, gimple_seq *seq_p)
1291 unsigned c = variables->elements ();
1292 if (c == 0)
1293 return;
1295 auto_vec<tree> sorted_variables (c);
1297 for (hash_set<tree>::iterator it = variables->begin ();
1298 it != variables->end (); ++it)
1299 sorted_variables.safe_push (*it);
1301 sorted_variables.qsort (sort_by_decl_uid);
1303 unsigned i;
1304 tree var;
1305 FOR_EACH_VEC_ELT (sorted_variables, i, var)
1307 asan_poison_variable (var, poison, seq_p);
1309 /* Add use_after_scope_memory attribute for the variable in order
1310 to prevent re-written into SSA. */
1311 if (!lookup_attribute (ASAN_USE_AFTER_SCOPE_ATTRIBUTE,
1312 DECL_ATTRIBUTES (var)))
1313 DECL_ATTRIBUTES (var)
1314 = tree_cons (get_identifier (ASAN_USE_AFTER_SCOPE_ATTRIBUTE),
1315 integer_one_node,
1316 DECL_ATTRIBUTES (var));
1320 /* Gimplify a BIND_EXPR. Just voidify and recurse. */
1322 static enum gimplify_status
1323 gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p)
1325 tree bind_expr = *expr_p;
1326 bool old_keep_stack = gimplify_ctxp->keep_stack;
1327 bool old_save_stack = gimplify_ctxp->save_stack;
1328 tree t;
1329 gbind *bind_stmt;
1330 gimple_seq body, cleanup;
1331 gcall *stack_save;
1332 location_t start_locus = 0, end_locus = 0;
1333 tree ret_clauses = NULL;
1335 tree temp = voidify_wrapper_expr (bind_expr, NULL);
1337 /* Mark variables seen in this bind expr. */
1338 for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t))
1340 if (VAR_P (t))
1342 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
1344 /* Mark variable as local. */
1345 if (ctx && ctx->region_type != ORT_NONE && !DECL_EXTERNAL (t))
1347 if (! DECL_SEEN_IN_BIND_EXPR_P (t)
1348 || splay_tree_lookup (ctx->variables,
1349 (splay_tree_key) t) == NULL)
1351 int flag = GOVD_LOCAL;
1352 if (ctx->region_type == ORT_SIMD
1353 && TREE_ADDRESSABLE (t)
1354 && !TREE_STATIC (t))
1356 if (TREE_CODE (DECL_SIZE_UNIT (t)) != INTEGER_CST)
1357 ctx->add_safelen1 = true;
1358 else
1359 flag = GOVD_PRIVATE;
1361 omp_add_variable (ctx, t, flag | GOVD_SEEN);
1363 /* Static locals inside of target construct or offloaded
1364 routines need to be "omp declare target". */
1365 if (TREE_STATIC (t))
1366 for (; ctx; ctx = ctx->outer_context)
1367 if ((ctx->region_type & ORT_TARGET) != 0)
1369 if (!lookup_attribute ("omp declare target",
1370 DECL_ATTRIBUTES (t)))
1372 tree id = get_identifier ("omp declare target");
1373 DECL_ATTRIBUTES (t)
1374 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
1375 varpool_node *node = varpool_node::get (t);
1376 if (node)
1378 node->offloadable = 1;
1379 if (ENABLE_OFFLOADING && !DECL_EXTERNAL (t))
1381 g->have_offload = true;
1382 if (!in_lto_p)
1383 vec_safe_push (offload_vars, t);
1387 break;
1391 DECL_SEEN_IN_BIND_EXPR_P (t) = 1;
1393 if (DECL_HARD_REGISTER (t) && !is_global_var (t) && cfun)
1394 cfun->has_local_explicit_reg_vars = true;
1397 /* Preliminarily mark non-addressed complex variables as eligible
1398 for promotion to gimple registers. We'll transform their uses
1399 as we find them. */
1400 if ((TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE
1401 || TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
1402 && !TREE_THIS_VOLATILE (t)
1403 && (VAR_P (t) && !DECL_HARD_REGISTER (t))
1404 && !needs_to_live_in_memory (t))
1405 DECL_GIMPLE_REG_P (t) = 1;
1408 bind_stmt = gimple_build_bind (BIND_EXPR_VARS (bind_expr), NULL,
1409 BIND_EXPR_BLOCK (bind_expr));
1410 gimple_push_bind_expr (bind_stmt);
1412 gimplify_ctxp->keep_stack = false;
1413 gimplify_ctxp->save_stack = false;
1415 /* Gimplify the body into the GIMPLE_BIND tuple's body. */
1416 body = NULL;
1417 gimplify_stmt (&BIND_EXPR_BODY (bind_expr), &body);
1418 gimple_bind_set_body (bind_stmt, body);
1420 /* Source location wise, the cleanup code (stack_restore and clobbers)
1421 belongs to the end of the block, so propagate what we have. The
1422 stack_save operation belongs to the beginning of block, which we can
1423 infer from the bind_expr directly if the block has no explicit
1424 assignment. */
1425 if (BIND_EXPR_BLOCK (bind_expr))
1427 end_locus = BLOCK_SOURCE_END_LOCATION (BIND_EXPR_BLOCK (bind_expr));
1428 start_locus = BLOCK_SOURCE_LOCATION (BIND_EXPR_BLOCK (bind_expr));
1430 if (start_locus == 0)
1431 start_locus = EXPR_LOCATION (bind_expr);
1433 cleanup = NULL;
1434 stack_save = NULL;
1436 /* If the code both contains VLAs and calls alloca, then we cannot reclaim
1437 the stack space allocated to the VLAs. */
1438 if (gimplify_ctxp->save_stack && !gimplify_ctxp->keep_stack)
1440 gcall *stack_restore;
1442 /* Save stack on entry and restore it on exit. Add a try_finally
1443 block to achieve this. */
1444 build_stack_save_restore (&stack_save, &stack_restore);
1446 gimple_set_location (stack_save, start_locus);
1447 gimple_set_location (stack_restore, end_locus);
1449 gimplify_seq_add_stmt (&cleanup, stack_restore);
1452 /* Add clobbers for all variables that go out of scope. */
1453 for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t))
1455 if (VAR_P (t)
1456 && !is_global_var (t)
1457 && DECL_CONTEXT (t) == current_function_decl)
1459 if (!DECL_HARD_REGISTER (t)
1460 && !TREE_THIS_VOLATILE (t)
1461 && !DECL_HAS_VALUE_EXPR_P (t)
1462 /* Only care for variables that have to be in memory. Others
1463 will be rewritten into SSA names, hence moved to the
1464 top-level. */
1465 && !is_gimple_reg (t)
1466 && flag_stack_reuse != SR_NONE)
1468 tree clobber = build_clobber (TREE_TYPE (t));
1469 gimple *clobber_stmt;
1470 clobber_stmt = gimple_build_assign (t, clobber);
1471 gimple_set_location (clobber_stmt, end_locus);
1472 gimplify_seq_add_stmt (&cleanup, clobber_stmt);
1475 if (flag_openacc && oacc_declare_returns != NULL)
1477 tree *c = oacc_declare_returns->get (t);
1478 if (c != NULL)
1480 if (ret_clauses)
1481 OMP_CLAUSE_CHAIN (*c) = ret_clauses;
1483 ret_clauses = *c;
1485 oacc_declare_returns->remove (t);
1487 if (oacc_declare_returns->is_empty ())
1489 delete oacc_declare_returns;
1490 oacc_declare_returns = NULL;
1496 if (asan_poisoned_variables != NULL
1497 && asan_poisoned_variables->contains (t))
1499 asan_poisoned_variables->remove (t);
1500 asan_poison_variable (t, true, &cleanup);
1503 if (gimplify_ctxp->live_switch_vars != NULL
1504 && gimplify_ctxp->live_switch_vars->contains (t))
1505 gimplify_ctxp->live_switch_vars->remove (t);
1508 if (ret_clauses)
1510 gomp_target *stmt;
1511 gimple_stmt_iterator si = gsi_start (cleanup);
1513 stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
1514 ret_clauses);
1515 gsi_insert_seq_before_without_update (&si, stmt, GSI_NEW_STMT);
1518 if (cleanup)
1520 gtry *gs;
1521 gimple_seq new_body;
1523 new_body = NULL;
1524 gs = gimple_build_try (gimple_bind_body (bind_stmt), cleanup,
1525 GIMPLE_TRY_FINALLY);
1527 if (stack_save)
1528 gimplify_seq_add_stmt (&new_body, stack_save);
1529 gimplify_seq_add_stmt (&new_body, gs);
1530 gimple_bind_set_body (bind_stmt, new_body);
1533 /* keep_stack propagates all the way up to the outermost BIND_EXPR. */
1534 if (!gimplify_ctxp->keep_stack)
1535 gimplify_ctxp->keep_stack = old_keep_stack;
1536 gimplify_ctxp->save_stack = old_save_stack;
1538 gimple_pop_bind_expr ();
1540 gimplify_seq_add_stmt (pre_p, bind_stmt);
1542 if (temp)
1544 *expr_p = temp;
1545 return GS_OK;
1548 *expr_p = NULL_TREE;
1549 return GS_ALL_DONE;
1552 /* Maybe add early return predict statement to PRE_P sequence. */
1554 static void
1555 maybe_add_early_return_predict_stmt (gimple_seq *pre_p)
1557 /* If we are not in a conditional context, add PREDICT statement. */
1558 if (gimple_conditional_context ())
1560 gimple *predict = gimple_build_predict (PRED_TREE_EARLY_RETURN,
1561 NOT_TAKEN);
1562 gimplify_seq_add_stmt (pre_p, predict);
1566 /* Gimplify a RETURN_EXPR. If the expression to be returned is not a
1567 GIMPLE value, it is assigned to a new temporary and the statement is
1568 re-written to return the temporary.
1570 PRE_P points to the sequence where side effects that must happen before
1571 STMT should be stored. */
1573 static enum gimplify_status
1574 gimplify_return_expr (tree stmt, gimple_seq *pre_p)
1576 greturn *ret;
1577 tree ret_expr = TREE_OPERAND (stmt, 0);
1578 tree result_decl, result;
1580 if (ret_expr == error_mark_node)
1581 return GS_ERROR;
1583 if (!ret_expr
1584 || TREE_CODE (ret_expr) == RESULT_DECL)
1586 maybe_add_early_return_predict_stmt (pre_p);
1587 greturn *ret = gimple_build_return (ret_expr);
1588 gimple_set_no_warning (ret, TREE_NO_WARNING (stmt));
1589 gimplify_seq_add_stmt (pre_p, ret);
1590 return GS_ALL_DONE;
1593 if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))))
1594 result_decl = NULL_TREE;
1595 else
1597 result_decl = TREE_OPERAND (ret_expr, 0);
1599 /* See through a return by reference. */
1600 if (TREE_CODE (result_decl) == INDIRECT_REF)
1601 result_decl = TREE_OPERAND (result_decl, 0);
1603 gcc_assert ((TREE_CODE (ret_expr) == MODIFY_EXPR
1604 || TREE_CODE (ret_expr) == INIT_EXPR)
1605 && TREE_CODE (result_decl) == RESULT_DECL);
1608 /* If aggregate_value_p is true, then we can return the bare RESULT_DECL.
1609 Recall that aggregate_value_p is FALSE for any aggregate type that is
1610 returned in registers. If we're returning values in registers, then
1611 we don't want to extend the lifetime of the RESULT_DECL, particularly
1612 across another call. In addition, for those aggregates for which
1613 hard_function_value generates a PARALLEL, we'll die during normal
1614 expansion of structure assignments; there's special code in expand_return
1615 to handle this case that does not exist in expand_expr. */
1616 if (!result_decl)
1617 result = NULL_TREE;
1618 else if (aggregate_value_p (result_decl, TREE_TYPE (current_function_decl)))
1620 if (TREE_CODE (DECL_SIZE (result_decl)) != INTEGER_CST)
1622 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (result_decl)))
1623 gimplify_type_sizes (TREE_TYPE (result_decl), pre_p);
1624 /* Note that we don't use gimplify_vla_decl because the RESULT_DECL
1625 should be effectively allocated by the caller, i.e. all calls to
1626 this function must be subject to the Return Slot Optimization. */
1627 gimplify_one_sizepos (&DECL_SIZE (result_decl), pre_p);
1628 gimplify_one_sizepos (&DECL_SIZE_UNIT (result_decl), pre_p);
1630 result = result_decl;
1632 else if (gimplify_ctxp->return_temp)
1633 result = gimplify_ctxp->return_temp;
1634 else
1636 result = create_tmp_reg (TREE_TYPE (result_decl));
1638 /* ??? With complex control flow (usually involving abnormal edges),
1639 we can wind up warning about an uninitialized value for this. Due
1640 to how this variable is constructed and initialized, this is never
1641 true. Give up and never warn. */
1642 TREE_NO_WARNING (result) = 1;
1644 gimplify_ctxp->return_temp = result;
1647 /* Smash the lhs of the MODIFY_EXPR to the temporary we plan to use.
1648 Then gimplify the whole thing. */
1649 if (result != result_decl)
1650 TREE_OPERAND (ret_expr, 0) = result;
1652 gimplify_and_add (TREE_OPERAND (stmt, 0), pre_p);
1654 maybe_add_early_return_predict_stmt (pre_p);
1655 ret = gimple_build_return (result);
1656 gimple_set_no_warning (ret, TREE_NO_WARNING (stmt));
1657 gimplify_seq_add_stmt (pre_p, ret);
1659 return GS_ALL_DONE;
1662 /* Gimplify a variable-length array DECL. */
1664 static void
1665 gimplify_vla_decl (tree decl, gimple_seq *seq_p)
1667 /* This is a variable-sized decl. Simplify its size and mark it
1668 for deferred expansion. */
1669 tree t, addr, ptr_type;
1671 gimplify_one_sizepos (&DECL_SIZE (decl), seq_p);
1672 gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), seq_p);
1674 /* Don't mess with a DECL_VALUE_EXPR set by the front-end. */
1675 if (DECL_HAS_VALUE_EXPR_P (decl))
1676 return;
1678 /* All occurrences of this decl in final gimplified code will be
1679 replaced by indirection. Setting DECL_VALUE_EXPR does two
1680 things: First, it lets the rest of the gimplifier know what
1681 replacement to use. Second, it lets the debug info know
1682 where to find the value. */
1683 ptr_type = build_pointer_type (TREE_TYPE (decl));
1684 addr = create_tmp_var (ptr_type, get_name (decl));
1685 DECL_IGNORED_P (addr) = 0;
1686 t = build_fold_indirect_ref (addr);
1687 TREE_THIS_NOTRAP (t) = 1;
1688 SET_DECL_VALUE_EXPR (decl, t);
1689 DECL_HAS_VALUE_EXPR_P (decl) = 1;
1691 t = build_alloca_call_expr (DECL_SIZE_UNIT (decl), DECL_ALIGN (decl),
1692 max_int_size_in_bytes (TREE_TYPE (decl)));
1693 /* The call has been built for a variable-sized object. */
1694 CALL_ALLOCA_FOR_VAR_P (t) = 1;
1695 t = fold_convert (ptr_type, t);
1696 t = build2 (MODIFY_EXPR, TREE_TYPE (addr), addr, t);
1698 gimplify_and_add (t, seq_p);
1701 /* A helper function to be called via walk_tree. Mark all labels under *TP
1702 as being forced. To be called for DECL_INITIAL of static variables. */
1704 static tree
1705 force_labels_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
1707 if (TYPE_P (*tp))
1708 *walk_subtrees = 0;
1709 if (TREE_CODE (*tp) == LABEL_DECL)
1711 FORCED_LABEL (*tp) = 1;
1712 cfun->has_forced_label_in_static = 1;
1715 return NULL_TREE;
1718 /* Gimplify a DECL_EXPR node *STMT_P by making any necessary allocation
1719 and initialization explicit. */
1721 static enum gimplify_status
1722 gimplify_decl_expr (tree *stmt_p, gimple_seq *seq_p)
1724 tree stmt = *stmt_p;
1725 tree decl = DECL_EXPR_DECL (stmt);
1727 *stmt_p = NULL_TREE;
1729 if (TREE_TYPE (decl) == error_mark_node)
1730 return GS_ERROR;
1732 if ((TREE_CODE (decl) == TYPE_DECL
1733 || VAR_P (decl))
1734 && !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl)))
1736 gimplify_type_sizes (TREE_TYPE (decl), seq_p);
1737 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
1738 gimplify_type_sizes (TREE_TYPE (TREE_TYPE (decl)), seq_p);
1741 /* ??? DECL_ORIGINAL_TYPE is streamed for LTO so it needs to be gimplified
1742 in case its size expressions contain problematic nodes like CALL_EXPR. */
1743 if (TREE_CODE (decl) == TYPE_DECL
1744 && DECL_ORIGINAL_TYPE (decl)
1745 && !TYPE_SIZES_GIMPLIFIED (DECL_ORIGINAL_TYPE (decl)))
1747 gimplify_type_sizes (DECL_ORIGINAL_TYPE (decl), seq_p);
1748 if (TREE_CODE (DECL_ORIGINAL_TYPE (decl)) == REFERENCE_TYPE)
1749 gimplify_type_sizes (TREE_TYPE (DECL_ORIGINAL_TYPE (decl)), seq_p);
1752 if (VAR_P (decl) && !DECL_EXTERNAL (decl))
1754 tree init = DECL_INITIAL (decl);
1755 bool is_vla = false;
1757 poly_uint64 size;
1758 if (!poly_int_tree_p (DECL_SIZE_UNIT (decl), &size)
1759 || (!TREE_STATIC (decl)
1760 && flag_stack_check == GENERIC_STACK_CHECK
1761 && maybe_gt (size,
1762 (unsigned HOST_WIDE_INT) STACK_CHECK_MAX_VAR_SIZE)))
1764 gimplify_vla_decl (decl, seq_p);
1765 is_vla = true;
1768 if (asan_poisoned_variables
1769 && !is_vla
1770 && TREE_ADDRESSABLE (decl)
1771 && !TREE_STATIC (decl)
1772 && !DECL_HAS_VALUE_EXPR_P (decl)
1773 && DECL_ALIGN (decl) <= MAX_SUPPORTED_STACK_ALIGNMENT
1774 && dbg_cnt (asan_use_after_scope)
1775 && !gimplify_omp_ctxp)
1777 asan_poisoned_variables->add (decl);
1778 asan_poison_variable (decl, false, seq_p);
1779 if (!DECL_ARTIFICIAL (decl) && gimplify_ctxp->live_switch_vars)
1780 gimplify_ctxp->live_switch_vars->add (decl);
1783 /* Some front ends do not explicitly declare all anonymous
1784 artificial variables. We compensate here by declaring the
1785 variables, though it would be better if the front ends would
1786 explicitly declare them. */
1787 if (!DECL_SEEN_IN_BIND_EXPR_P (decl)
1788 && DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
1789 gimple_add_tmp_var (decl);
1791 if (init && init != error_mark_node)
1793 if (!TREE_STATIC (decl))
1795 DECL_INITIAL (decl) = NULL_TREE;
1796 init = build2 (INIT_EXPR, void_type_node, decl, init);
1797 gimplify_and_add (init, seq_p);
1798 ggc_free (init);
1800 else
1801 /* We must still examine initializers for static variables
1802 as they may contain a label address. */
1803 walk_tree (&init, force_labels_r, NULL, NULL);
1807 return GS_ALL_DONE;
1810 /* Gimplify a LOOP_EXPR. Normally this just involves gimplifying the body
1811 and replacing the LOOP_EXPR with goto, but if the loop contains an
1812 EXIT_EXPR, we need to append a label for it to jump to. */
1814 static enum gimplify_status
1815 gimplify_loop_expr (tree *expr_p, gimple_seq *pre_p)
1817 tree saved_label = gimplify_ctxp->exit_label;
1818 tree start_label = create_artificial_label (UNKNOWN_LOCATION);
1820 gimplify_seq_add_stmt (pre_p, gimple_build_label (start_label));
1822 gimplify_ctxp->exit_label = NULL_TREE;
1824 gimplify_and_add (LOOP_EXPR_BODY (*expr_p), pre_p);
1826 gimplify_seq_add_stmt (pre_p, gimple_build_goto (start_label));
1828 if (gimplify_ctxp->exit_label)
1829 gimplify_seq_add_stmt (pre_p,
1830 gimple_build_label (gimplify_ctxp->exit_label));
1832 gimplify_ctxp->exit_label = saved_label;
1834 *expr_p = NULL;
1835 return GS_ALL_DONE;
1838 /* Gimplify a statement list onto a sequence. These may be created either
1839 by an enlightened front-end, or by shortcut_cond_expr. */
1841 static enum gimplify_status
1842 gimplify_statement_list (tree *expr_p, gimple_seq *pre_p)
1844 tree temp = voidify_wrapper_expr (*expr_p, NULL);
1846 tree_stmt_iterator i = tsi_start (*expr_p);
1848 while (!tsi_end_p (i))
1850 gimplify_stmt (tsi_stmt_ptr (i), pre_p);
1851 tsi_delink (&i);
1854 if (temp)
1856 *expr_p = temp;
1857 return GS_OK;
1860 return GS_ALL_DONE;
1863 /* Callback for walk_gimple_seq. */
1865 static tree
1866 warn_switch_unreachable_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
1867 struct walk_stmt_info *wi)
1869 gimple *stmt = gsi_stmt (*gsi_p);
1871 *handled_ops_p = true;
1872 switch (gimple_code (stmt))
1874 case GIMPLE_TRY:
1875 /* A compiler-generated cleanup or a user-written try block.
1876 If it's empty, don't dive into it--that would result in
1877 worse location info. */
1878 if (gimple_try_eval (stmt) == NULL)
1880 wi->info = stmt;
1881 return integer_zero_node;
1883 /* Fall through. */
1884 case GIMPLE_BIND:
1885 case GIMPLE_CATCH:
1886 case GIMPLE_EH_FILTER:
1887 case GIMPLE_TRANSACTION:
1888 /* Walk the sub-statements. */
1889 *handled_ops_p = false;
1890 break;
1892 case GIMPLE_DEBUG:
1893 /* Ignore these. We may generate them before declarations that
1894 are never executed. If there's something to warn about,
1895 there will be non-debug stmts too, and we'll catch those. */
1896 break;
1898 case GIMPLE_CALL:
1899 if (gimple_call_internal_p (stmt, IFN_ASAN_MARK))
1901 *handled_ops_p = false;
1902 break;
1904 /* Fall through. */
1905 default:
1906 /* Save the first "real" statement (not a decl/lexical scope/...). */
1907 wi->info = stmt;
1908 return integer_zero_node;
1910 return NULL_TREE;
1913 /* Possibly warn about unreachable statements between switch's controlling
1914 expression and the first case. SEQ is the body of a switch expression. */
1916 static void
1917 maybe_warn_switch_unreachable (gimple_seq seq)
1919 if (!warn_switch_unreachable
1920 /* This warning doesn't play well with Fortran when optimizations
1921 are on. */
1922 || lang_GNU_Fortran ()
1923 || seq == NULL)
1924 return;
1926 struct walk_stmt_info wi;
1927 memset (&wi, 0, sizeof (wi));
1928 walk_gimple_seq (seq, warn_switch_unreachable_r, NULL, &wi);
1929 gimple *stmt = (gimple *) wi.info;
1931 if (stmt && gimple_code (stmt) != GIMPLE_LABEL)
1933 if (gimple_code (stmt) == GIMPLE_GOTO
1934 && TREE_CODE (gimple_goto_dest (stmt)) == LABEL_DECL
1935 && DECL_ARTIFICIAL (gimple_goto_dest (stmt)))
1936 /* Don't warn for compiler-generated gotos. These occur
1937 in Duff's devices, for example. */;
1938 else
1939 warning_at (gimple_location (stmt), OPT_Wswitch_unreachable,
1940 "statement will never be executed");
1945 /* A label entry that pairs label and a location. */
1946 struct label_entry
1948 tree label;
1949 location_t loc;
1952 /* Find LABEL in vector of label entries VEC. */
1954 static struct label_entry *
1955 find_label_entry (const auto_vec<struct label_entry> *vec, tree label)
1957 unsigned int i;
1958 struct label_entry *l;
1960 FOR_EACH_VEC_ELT (*vec, i, l)
1961 if (l->label == label)
1962 return l;
1963 return NULL;
1966 /* Return true if LABEL, a LABEL_DECL, represents a case label
1967 in a vector of labels CASES. */
1969 static bool
1970 case_label_p (const vec<tree> *cases, tree label)
1972 unsigned int i;
1973 tree l;
1975 FOR_EACH_VEC_ELT (*cases, i, l)
1976 if (CASE_LABEL (l) == label)
1977 return true;
1978 return false;
1981 /* Find the last nondebug statement in a scope STMT. */
1983 static gimple *
1984 last_stmt_in_scope (gimple *stmt)
1986 if (!stmt)
1987 return NULL;
1989 switch (gimple_code (stmt))
1991 case GIMPLE_BIND:
1993 gbind *bind = as_a <gbind *> (stmt);
1994 stmt = gimple_seq_last_nondebug_stmt (gimple_bind_body (bind));
1995 return last_stmt_in_scope (stmt);
1998 case GIMPLE_TRY:
2000 gtry *try_stmt = as_a <gtry *> (stmt);
2001 stmt = gimple_seq_last_nondebug_stmt (gimple_try_eval (try_stmt));
2002 gimple *last_eval = last_stmt_in_scope (stmt);
2003 if (gimple_stmt_may_fallthru (last_eval)
2004 && (last_eval == NULL
2005 || !gimple_call_internal_p (last_eval, IFN_FALLTHROUGH))
2006 && gimple_try_kind (try_stmt) == GIMPLE_TRY_FINALLY)
2008 stmt = gimple_seq_last_nondebug_stmt (gimple_try_cleanup (try_stmt));
2009 return last_stmt_in_scope (stmt);
2011 else
2012 return last_eval;
2015 case GIMPLE_DEBUG:
2016 gcc_unreachable ();
2018 default:
2019 return stmt;
2023 /* Collect interesting labels in LABELS and return the statement preceding
2024 another case label, or a user-defined label. Store a location useful
2025 to give warnings at *PREVLOC (usually the location of the returned
2026 statement or of its surrounding scope). */
2028 static gimple *
2029 collect_fallthrough_labels (gimple_stmt_iterator *gsi_p,
2030 auto_vec <struct label_entry> *labels,
2031 location_t *prevloc)
2033 gimple *prev = NULL;
2035 *prevloc = UNKNOWN_LOCATION;
2038 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND)
2040 /* Recognize the special GIMPLE_BIND added by gimplify_switch_expr,
2041 which starts on a GIMPLE_SWITCH and ends with a break label.
2042 Handle that as a single statement that can fall through. */
2043 gbind *bind = as_a <gbind *> (gsi_stmt (*gsi_p));
2044 gimple *first = gimple_seq_first_stmt (gimple_bind_body (bind));
2045 gimple *last = gimple_seq_last_stmt (gimple_bind_body (bind));
2046 if (last
2047 && gimple_code (first) == GIMPLE_SWITCH
2048 && gimple_code (last) == GIMPLE_LABEL)
2050 tree label = gimple_label_label (as_a <glabel *> (last));
2051 if (SWITCH_BREAK_LABEL_P (label))
2053 prev = bind;
2054 gsi_next (gsi_p);
2055 continue;
2059 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND
2060 || gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_TRY)
2062 /* Nested scope. Only look at the last statement of
2063 the innermost scope. */
2064 location_t bind_loc = gimple_location (gsi_stmt (*gsi_p));
2065 gimple *last = last_stmt_in_scope (gsi_stmt (*gsi_p));
2066 if (last)
2068 prev = last;
2069 /* It might be a label without a location. Use the
2070 location of the scope then. */
2071 if (!gimple_has_location (prev))
2072 *prevloc = bind_loc;
2074 gsi_next (gsi_p);
2075 continue;
2078 /* Ifs are tricky. */
2079 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_COND)
2081 gcond *cond_stmt = as_a <gcond *> (gsi_stmt (*gsi_p));
2082 tree false_lab = gimple_cond_false_label (cond_stmt);
2083 location_t if_loc = gimple_location (cond_stmt);
2085 /* If we have e.g.
2086 if (i > 1) goto <D.2259>; else goto D;
2087 we can't do much with the else-branch. */
2088 if (!DECL_ARTIFICIAL (false_lab))
2089 break;
2091 /* Go on until the false label, then one step back. */
2092 for (; !gsi_end_p (*gsi_p); gsi_next (gsi_p))
2094 gimple *stmt = gsi_stmt (*gsi_p);
2095 if (gimple_code (stmt) == GIMPLE_LABEL
2096 && gimple_label_label (as_a <glabel *> (stmt)) == false_lab)
2097 break;
2100 /* Not found? Oops. */
2101 if (gsi_end_p (*gsi_p))
2102 break;
2104 struct label_entry l = { false_lab, if_loc };
2105 labels->safe_push (l);
2107 /* Go to the last statement of the then branch. */
2108 gsi_prev (gsi_p);
2110 /* if (i != 0) goto <D.1759>; else goto <D.1760>;
2111 <D.1759>:
2112 <stmt>;
2113 goto <D.1761>;
2114 <D.1760>:
2116 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_GOTO
2117 && !gimple_has_location (gsi_stmt (*gsi_p)))
2119 /* Look at the statement before, it might be
2120 attribute fallthrough, in which case don't warn. */
2121 gsi_prev (gsi_p);
2122 bool fallthru_before_dest
2123 = gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_FALLTHROUGH);
2124 gsi_next (gsi_p);
2125 tree goto_dest = gimple_goto_dest (gsi_stmt (*gsi_p));
2126 if (!fallthru_before_dest)
2128 struct label_entry l = { goto_dest, if_loc };
2129 labels->safe_push (l);
2132 /* And move back. */
2133 gsi_next (gsi_p);
2136 /* Remember the last statement. Skip labels that are of no interest
2137 to us. */
2138 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
2140 tree label = gimple_label_label (as_a <glabel *> (gsi_stmt (*gsi_p)));
2141 if (find_label_entry (labels, label))
2142 prev = gsi_stmt (*gsi_p);
2144 else if (gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_ASAN_MARK))
2146 else if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_PREDICT)
2148 else if (!is_gimple_debug (gsi_stmt (*gsi_p)))
2149 prev = gsi_stmt (*gsi_p);
2150 gsi_next (gsi_p);
2152 while (!gsi_end_p (*gsi_p)
2153 /* Stop if we find a case or a user-defined label. */
2154 && (gimple_code (gsi_stmt (*gsi_p)) != GIMPLE_LABEL
2155 || !gimple_has_location (gsi_stmt (*gsi_p))));
2157 if (prev && gimple_has_location (prev))
2158 *prevloc = gimple_location (prev);
2159 return prev;
2162 /* Return true if the switch fallthough warning should occur. LABEL is
2163 the label statement that we're falling through to. */
2165 static bool
2166 should_warn_for_implicit_fallthrough (gimple_stmt_iterator *gsi_p, tree label)
2168 gimple_stmt_iterator gsi = *gsi_p;
2170 /* Don't warn if the label is marked with a "falls through" comment. */
2171 if (FALLTHROUGH_LABEL_P (label))
2172 return false;
2174 /* Don't warn for non-case labels followed by a statement:
2175 case 0:
2176 foo ();
2177 label:
2178 bar ();
2179 as these are likely intentional. */
2180 if (!case_label_p (&gimplify_ctxp->case_labels, label))
2182 tree l;
2183 while (!gsi_end_p (gsi)
2184 && gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
2185 && (l = gimple_label_label (as_a <glabel *> (gsi_stmt (gsi))))
2186 && !case_label_p (&gimplify_ctxp->case_labels, l))
2187 gsi_next_nondebug (&gsi);
2188 if (gsi_end_p (gsi) || gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL)
2189 return false;
2192 /* Don't warn for terminated branches, i.e. when the subsequent case labels
2193 immediately breaks. */
2194 gsi = *gsi_p;
2196 /* Skip all immediately following labels. */
2197 while (!gsi_end_p (gsi)
2198 && (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
2199 || gimple_code (gsi_stmt (gsi)) == GIMPLE_PREDICT))
2200 gsi_next_nondebug (&gsi);
2202 /* { ... something; default:; } */
2203 if (gsi_end_p (gsi)
2204 /* { ... something; default: break; } or
2205 { ... something; default: goto L; } */
2206 || gimple_code (gsi_stmt (gsi)) == GIMPLE_GOTO
2207 /* { ... something; default: return; } */
2208 || gimple_code (gsi_stmt (gsi)) == GIMPLE_RETURN)
2209 return false;
2211 return true;
2214 /* Callback for walk_gimple_seq. */
2216 static tree
2217 warn_implicit_fallthrough_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
2218 struct walk_stmt_info *)
2220 gimple *stmt = gsi_stmt (*gsi_p);
2222 *handled_ops_p = true;
2223 switch (gimple_code (stmt))
2225 case GIMPLE_TRY:
2226 case GIMPLE_BIND:
2227 case GIMPLE_CATCH:
2228 case GIMPLE_EH_FILTER:
2229 case GIMPLE_TRANSACTION:
2230 /* Walk the sub-statements. */
2231 *handled_ops_p = false;
2232 break;
2234 /* Find a sequence of form:
2236 GIMPLE_LABEL
2237 [...]
2238 <may fallthru stmt>
2239 GIMPLE_LABEL
2241 and possibly warn. */
2242 case GIMPLE_LABEL:
2244 /* Found a label. Skip all immediately following labels. */
2245 while (!gsi_end_p (*gsi_p)
2246 && gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
2247 gsi_next_nondebug (gsi_p);
2249 /* There might be no more statements. */
2250 if (gsi_end_p (*gsi_p))
2251 return integer_zero_node;
2253 /* Vector of labels that fall through. */
2254 auto_vec <struct label_entry> labels;
2255 location_t prevloc;
2256 gimple *prev = collect_fallthrough_labels (gsi_p, &labels, &prevloc);
2258 /* There might be no more statements. */
2259 if (gsi_end_p (*gsi_p))
2260 return integer_zero_node;
2262 gimple *next = gsi_stmt (*gsi_p);
2263 tree label;
2264 /* If what follows is a label, then we may have a fallthrough. */
2265 if (gimple_code (next) == GIMPLE_LABEL
2266 && gimple_has_location (next)
2267 && (label = gimple_label_label (as_a <glabel *> (next)))
2268 && prev != NULL)
2270 struct label_entry *l;
2271 bool warned_p = false;
2272 auto_diagnostic_group d;
2273 if (!should_warn_for_implicit_fallthrough (gsi_p, label))
2274 /* Quiet. */;
2275 else if (gimple_code (prev) == GIMPLE_LABEL
2276 && (label = gimple_label_label (as_a <glabel *> (prev)))
2277 && (l = find_label_entry (&labels, label)))
2278 warned_p = warning_at (l->loc, OPT_Wimplicit_fallthrough_,
2279 "this statement may fall through");
2280 else if (!gimple_call_internal_p (prev, IFN_FALLTHROUGH)
2281 /* Try to be clever and don't warn when the statement
2282 can't actually fall through. */
2283 && gimple_stmt_may_fallthru (prev)
2284 && prevloc != UNKNOWN_LOCATION)
2285 warned_p = warning_at (prevloc,
2286 OPT_Wimplicit_fallthrough_,
2287 "this statement may fall through");
2288 if (warned_p)
2289 inform (gimple_location (next), "here");
2291 /* Mark this label as processed so as to prevent multiple
2292 warnings in nested switches. */
2293 FALLTHROUGH_LABEL_P (label) = true;
2295 /* So that next warn_implicit_fallthrough_r will start looking for
2296 a new sequence starting with this label. */
2297 gsi_prev (gsi_p);
2300 break;
2301 default:
2302 break;
2304 return NULL_TREE;
2307 /* Warn when a switch case falls through. */
2309 static void
2310 maybe_warn_implicit_fallthrough (gimple_seq seq)
2312 if (!warn_implicit_fallthrough)
2313 return;
2315 /* This warning is meant for C/C++/ObjC/ObjC++ only. */
2316 if (!(lang_GNU_C ()
2317 || lang_GNU_CXX ()
2318 || lang_GNU_OBJC ()))
2319 return;
2321 struct walk_stmt_info wi;
2322 memset (&wi, 0, sizeof (wi));
2323 walk_gimple_seq (seq, warn_implicit_fallthrough_r, NULL, &wi);
2326 /* Callback for walk_gimple_seq. */
2328 static tree
2329 expand_FALLTHROUGH_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
2330 struct walk_stmt_info *wi)
2332 gimple *stmt = gsi_stmt (*gsi_p);
2334 *handled_ops_p = true;
2335 switch (gimple_code (stmt))
2337 case GIMPLE_TRY:
2338 case GIMPLE_BIND:
2339 case GIMPLE_CATCH:
2340 case GIMPLE_EH_FILTER:
2341 case GIMPLE_TRANSACTION:
2342 /* Walk the sub-statements. */
2343 *handled_ops_p = false;
2344 break;
2345 case GIMPLE_CALL:
2346 if (gimple_call_internal_p (stmt, IFN_FALLTHROUGH))
2348 gsi_remove (gsi_p, true);
2349 if (gsi_end_p (*gsi_p))
2351 *static_cast<location_t *>(wi->info) = gimple_location (stmt);
2352 return integer_zero_node;
2355 bool found = false;
2356 location_t loc = gimple_location (stmt);
2358 gimple_stmt_iterator gsi2 = *gsi_p;
2359 stmt = gsi_stmt (gsi2);
2360 if (gimple_code (stmt) == GIMPLE_GOTO && !gimple_has_location (stmt))
2362 /* Go on until the artificial label. */
2363 tree goto_dest = gimple_goto_dest (stmt);
2364 for (; !gsi_end_p (gsi2); gsi_next (&gsi2))
2366 if (gimple_code (gsi_stmt (gsi2)) == GIMPLE_LABEL
2367 && gimple_label_label (as_a <glabel *> (gsi_stmt (gsi2)))
2368 == goto_dest)
2369 break;
2372 /* Not found? Stop. */
2373 if (gsi_end_p (gsi2))
2374 break;
2376 /* Look one past it. */
2377 gsi_next (&gsi2);
2380 /* We're looking for a case label or default label here. */
2381 while (!gsi_end_p (gsi2))
2383 stmt = gsi_stmt (gsi2);
2384 if (gimple_code (stmt) == GIMPLE_LABEL)
2386 tree label = gimple_label_label (as_a <glabel *> (stmt));
2387 if (gimple_has_location (stmt) && DECL_ARTIFICIAL (label))
2389 found = true;
2390 break;
2393 else if (gimple_call_internal_p (stmt, IFN_ASAN_MARK))
2395 else if (!is_gimple_debug (stmt))
2396 /* Anything else is not expected. */
2397 break;
2398 gsi_next (&gsi2);
2400 if (!found)
2401 warning_at (loc, 0, "attribute %<fallthrough%> not preceding "
2402 "a case label or default label");
2404 break;
2405 default:
2406 break;
2408 return NULL_TREE;
2411 /* Expand all FALLTHROUGH () calls in SEQ. */
2413 static void
2414 expand_FALLTHROUGH (gimple_seq *seq_p)
2416 struct walk_stmt_info wi;
2417 location_t loc;
2418 memset (&wi, 0, sizeof (wi));
2419 wi.info = (void *) &loc;
2420 walk_gimple_seq_mod (seq_p, expand_FALLTHROUGH_r, NULL, &wi);
2421 if (wi.callback_result == integer_zero_node)
2422 /* We've found [[fallthrough]]; at the end of a switch, which the C++
2423 standard says is ill-formed; see [dcl.attr.fallthrough]. */
2424 warning_at (loc, 0, "attribute %<fallthrough%> not preceding "
2425 "a case label or default label");
2429 /* Gimplify a SWITCH_EXPR, and collect the vector of labels it can
2430 branch to. */
2432 static enum gimplify_status
2433 gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p)
2435 tree switch_expr = *expr_p;
2436 gimple_seq switch_body_seq = NULL;
2437 enum gimplify_status ret;
2438 tree index_type = TREE_TYPE (switch_expr);
2439 if (index_type == NULL_TREE)
2440 index_type = TREE_TYPE (SWITCH_COND (switch_expr));
2442 ret = gimplify_expr (&SWITCH_COND (switch_expr), pre_p, NULL, is_gimple_val,
2443 fb_rvalue);
2444 if (ret == GS_ERROR || ret == GS_UNHANDLED)
2445 return ret;
2447 if (SWITCH_BODY (switch_expr))
2449 vec<tree> labels;
2450 vec<tree> saved_labels;
2451 hash_set<tree> *saved_live_switch_vars = NULL;
2452 tree default_case = NULL_TREE;
2453 gswitch *switch_stmt;
2455 /* Save old labels, get new ones from body, then restore the old
2456 labels. Save all the things from the switch body to append after. */
2457 saved_labels = gimplify_ctxp->case_labels;
2458 gimplify_ctxp->case_labels.create (8);
2460 /* Do not create live_switch_vars if SWITCH_BODY is not a BIND_EXPR. */
2461 saved_live_switch_vars = gimplify_ctxp->live_switch_vars;
2462 tree_code body_type = TREE_CODE (SWITCH_BODY (switch_expr));
2463 if (body_type == BIND_EXPR || body_type == STATEMENT_LIST)
2464 gimplify_ctxp->live_switch_vars = new hash_set<tree> (4);
2465 else
2466 gimplify_ctxp->live_switch_vars = NULL;
2468 bool old_in_switch_expr = gimplify_ctxp->in_switch_expr;
2469 gimplify_ctxp->in_switch_expr = true;
2471 gimplify_stmt (&SWITCH_BODY (switch_expr), &switch_body_seq);
2473 gimplify_ctxp->in_switch_expr = old_in_switch_expr;
2474 maybe_warn_switch_unreachable (switch_body_seq);
2475 maybe_warn_implicit_fallthrough (switch_body_seq);
2476 /* Only do this for the outermost GIMPLE_SWITCH. */
2477 if (!gimplify_ctxp->in_switch_expr)
2478 expand_FALLTHROUGH (&switch_body_seq);
2480 labels = gimplify_ctxp->case_labels;
2481 gimplify_ctxp->case_labels = saved_labels;
2483 if (gimplify_ctxp->live_switch_vars)
2485 gcc_assert (gimplify_ctxp->live_switch_vars->is_empty ());
2486 delete gimplify_ctxp->live_switch_vars;
2488 gimplify_ctxp->live_switch_vars = saved_live_switch_vars;
2490 preprocess_case_label_vec_for_gimple (labels, index_type,
2491 &default_case);
2493 bool add_bind = false;
2494 if (!default_case)
2496 glabel *new_default;
2498 default_case
2499 = build_case_label (NULL_TREE, NULL_TREE,
2500 create_artificial_label (UNKNOWN_LOCATION));
2501 if (old_in_switch_expr)
2503 SWITCH_BREAK_LABEL_P (CASE_LABEL (default_case)) = 1;
2504 add_bind = true;
2506 new_default = gimple_build_label (CASE_LABEL (default_case));
2507 gimplify_seq_add_stmt (&switch_body_seq, new_default);
2509 else if (old_in_switch_expr)
2511 gimple *last = gimple_seq_last_stmt (switch_body_seq);
2512 if (last && gimple_code (last) == GIMPLE_LABEL)
2514 tree label = gimple_label_label (as_a <glabel *> (last));
2515 if (SWITCH_BREAK_LABEL_P (label))
2516 add_bind = true;
2520 switch_stmt = gimple_build_switch (SWITCH_COND (switch_expr),
2521 default_case, labels);
2522 /* For the benefit of -Wimplicit-fallthrough, if switch_body_seq
2523 ends with a GIMPLE_LABEL holding SWITCH_BREAK_LABEL_P LABEL_DECL,
2524 wrap the GIMPLE_SWITCH up to that GIMPLE_LABEL into a GIMPLE_BIND,
2525 so that we can easily find the start and end of the switch
2526 statement. */
2527 if (add_bind)
2529 gimple_seq bind_body = NULL;
2530 gimplify_seq_add_stmt (&bind_body, switch_stmt);
2531 gimple_seq_add_seq (&bind_body, switch_body_seq);
2532 gbind *bind = gimple_build_bind (NULL_TREE, bind_body, NULL_TREE);
2533 gimple_set_location (bind, EXPR_LOCATION (switch_expr));
2534 gimplify_seq_add_stmt (pre_p, bind);
2536 else
2538 gimplify_seq_add_stmt (pre_p, switch_stmt);
2539 gimplify_seq_add_seq (pre_p, switch_body_seq);
2541 labels.release ();
2543 else
2544 gcc_unreachable ();
2546 return GS_ALL_DONE;
2549 /* Gimplify the LABEL_EXPR pointed to by EXPR_P. */
2551 static enum gimplify_status
2552 gimplify_label_expr (tree *expr_p, gimple_seq *pre_p)
2554 gcc_assert (decl_function_context (LABEL_EXPR_LABEL (*expr_p))
2555 == current_function_decl);
2557 tree label = LABEL_EXPR_LABEL (*expr_p);
2558 glabel *label_stmt = gimple_build_label (label);
2559 gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
2560 gimplify_seq_add_stmt (pre_p, label_stmt);
2562 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label)))
2563 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_COLD_LABEL,
2564 NOT_TAKEN));
2565 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label)))
2566 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_HOT_LABEL,
2567 TAKEN));
2569 return GS_ALL_DONE;
2572 /* Gimplify the CASE_LABEL_EXPR pointed to by EXPR_P. */
2574 static enum gimplify_status
2575 gimplify_case_label_expr (tree *expr_p, gimple_seq *pre_p)
2577 struct gimplify_ctx *ctxp;
2578 glabel *label_stmt;
2580 /* Invalid programs can play Duff's Device type games with, for example,
2581 #pragma omp parallel. At least in the C front end, we don't
2582 detect such invalid branches until after gimplification, in the
2583 diagnose_omp_blocks pass. */
2584 for (ctxp = gimplify_ctxp; ; ctxp = ctxp->prev_context)
2585 if (ctxp->case_labels.exists ())
2586 break;
2588 tree label = CASE_LABEL (*expr_p);
2589 label_stmt = gimple_build_label (label);
2590 gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
2591 ctxp->case_labels.safe_push (*expr_p);
2592 gimplify_seq_add_stmt (pre_p, label_stmt);
2594 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label)))
2595 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_COLD_LABEL,
2596 NOT_TAKEN));
2597 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label)))
2598 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_HOT_LABEL,
2599 TAKEN));
2601 return GS_ALL_DONE;
2604 /* Build a GOTO to the LABEL_DECL pointed to by LABEL_P, building it first
2605 if necessary. */
2607 tree
2608 build_and_jump (tree *label_p)
2610 if (label_p == NULL)
2611 /* If there's nowhere to jump, just fall through. */
2612 return NULL_TREE;
2614 if (*label_p == NULL_TREE)
2616 tree label = create_artificial_label (UNKNOWN_LOCATION);
2617 *label_p = label;
2620 return build1 (GOTO_EXPR, void_type_node, *label_p);
2623 /* Gimplify an EXIT_EXPR by converting to a GOTO_EXPR inside a COND_EXPR.
2624 This also involves building a label to jump to and communicating it to
2625 gimplify_loop_expr through gimplify_ctxp->exit_label. */
2627 static enum gimplify_status
2628 gimplify_exit_expr (tree *expr_p)
2630 tree cond = TREE_OPERAND (*expr_p, 0);
2631 tree expr;
2633 expr = build_and_jump (&gimplify_ctxp->exit_label);
2634 expr = build3 (COND_EXPR, void_type_node, cond, expr, NULL_TREE);
2635 *expr_p = expr;
2637 return GS_OK;
2640 /* *EXPR_P is a COMPONENT_REF being used as an rvalue. If its type is
2641 different from its canonical type, wrap the whole thing inside a
2642 NOP_EXPR and force the type of the COMPONENT_REF to be the canonical
2643 type.
2645 The canonical type of a COMPONENT_REF is the type of the field being
2646 referenced--unless the field is a bit-field which can be read directly
2647 in a smaller mode, in which case the canonical type is the
2648 sign-appropriate type corresponding to that mode. */
2650 static void
2651 canonicalize_component_ref (tree *expr_p)
2653 tree expr = *expr_p;
2654 tree type;
2656 gcc_assert (TREE_CODE (expr) == COMPONENT_REF);
2658 if (INTEGRAL_TYPE_P (TREE_TYPE (expr)))
2659 type = TREE_TYPE (get_unwidened (expr, NULL_TREE));
2660 else
2661 type = TREE_TYPE (TREE_OPERAND (expr, 1));
2663 /* One could argue that all the stuff below is not necessary for
2664 the non-bitfield case and declare it a FE error if type
2665 adjustment would be needed. */
2666 if (TREE_TYPE (expr) != type)
2668 #ifdef ENABLE_TYPES_CHECKING
2669 tree old_type = TREE_TYPE (expr);
2670 #endif
2671 int type_quals;
2673 /* We need to preserve qualifiers and propagate them from
2674 operand 0. */
2675 type_quals = TYPE_QUALS (type)
2676 | TYPE_QUALS (TREE_TYPE (TREE_OPERAND (expr, 0)));
2677 if (TYPE_QUALS (type) != type_quals)
2678 type = build_qualified_type (TYPE_MAIN_VARIANT (type), type_quals);
2680 /* Set the type of the COMPONENT_REF to the underlying type. */
2681 TREE_TYPE (expr) = type;
2683 #ifdef ENABLE_TYPES_CHECKING
2684 /* It is now a FE error, if the conversion from the canonical
2685 type to the original expression type is not useless. */
2686 gcc_assert (useless_type_conversion_p (old_type, type));
2687 #endif
2691 /* If a NOP conversion is changing a pointer to array of foo to a pointer
2692 to foo, embed that change in the ADDR_EXPR by converting
2693 T array[U];
2694 (T *)&array
2696 &array[L]
2697 where L is the lower bound. For simplicity, only do this for constant
2698 lower bound.
2699 The constraint is that the type of &array[L] is trivially convertible
2700 to T *. */
2702 static void
2703 canonicalize_addr_expr (tree *expr_p)
2705 tree expr = *expr_p;
2706 tree addr_expr = TREE_OPERAND (expr, 0);
2707 tree datype, ddatype, pddatype;
2709 /* We simplify only conversions from an ADDR_EXPR to a pointer type. */
2710 if (!POINTER_TYPE_P (TREE_TYPE (expr))
2711 || TREE_CODE (addr_expr) != ADDR_EXPR)
2712 return;
2714 /* The addr_expr type should be a pointer to an array. */
2715 datype = TREE_TYPE (TREE_TYPE (addr_expr));
2716 if (TREE_CODE (datype) != ARRAY_TYPE)
2717 return;
2719 /* The pointer to element type shall be trivially convertible to
2720 the expression pointer type. */
2721 ddatype = TREE_TYPE (datype);
2722 pddatype = build_pointer_type (ddatype);
2723 if (!useless_type_conversion_p (TYPE_MAIN_VARIANT (TREE_TYPE (expr)),
2724 pddatype))
2725 return;
2727 /* The lower bound and element sizes must be constant. */
2728 if (!TYPE_SIZE_UNIT (ddatype)
2729 || TREE_CODE (TYPE_SIZE_UNIT (ddatype)) != INTEGER_CST
2730 || !TYPE_DOMAIN (datype) || !TYPE_MIN_VALUE (TYPE_DOMAIN (datype))
2731 || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (datype))) != INTEGER_CST)
2732 return;
2734 /* All checks succeeded. Build a new node to merge the cast. */
2735 *expr_p = build4 (ARRAY_REF, ddatype, TREE_OPERAND (addr_expr, 0),
2736 TYPE_MIN_VALUE (TYPE_DOMAIN (datype)),
2737 NULL_TREE, NULL_TREE);
2738 *expr_p = build1 (ADDR_EXPR, pddatype, *expr_p);
2740 /* We can have stripped a required restrict qualifier above. */
2741 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
2742 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
2745 /* *EXPR_P is a NOP_EXPR or CONVERT_EXPR. Remove it and/or other conversions
2746 underneath as appropriate. */
2748 static enum gimplify_status
2749 gimplify_conversion (tree *expr_p)
2751 location_t loc = EXPR_LOCATION (*expr_p);
2752 gcc_assert (CONVERT_EXPR_P (*expr_p));
2754 /* Then strip away all but the outermost conversion. */
2755 STRIP_SIGN_NOPS (TREE_OPERAND (*expr_p, 0));
2757 /* And remove the outermost conversion if it's useless. */
2758 if (tree_ssa_useless_type_conversion (*expr_p))
2759 *expr_p = TREE_OPERAND (*expr_p, 0);
2761 /* If we still have a conversion at the toplevel,
2762 then canonicalize some constructs. */
2763 if (CONVERT_EXPR_P (*expr_p))
2765 tree sub = TREE_OPERAND (*expr_p, 0);
2767 /* If a NOP conversion is changing the type of a COMPONENT_REF
2768 expression, then canonicalize its type now in order to expose more
2769 redundant conversions. */
2770 if (TREE_CODE (sub) == COMPONENT_REF)
2771 canonicalize_component_ref (&TREE_OPERAND (*expr_p, 0));
2773 /* If a NOP conversion is changing a pointer to array of foo
2774 to a pointer to foo, embed that change in the ADDR_EXPR. */
2775 else if (TREE_CODE (sub) == ADDR_EXPR)
2776 canonicalize_addr_expr (expr_p);
2779 /* If we have a conversion to a non-register type force the
2780 use of a VIEW_CONVERT_EXPR instead. */
2781 if (CONVERT_EXPR_P (*expr_p) && !is_gimple_reg_type (TREE_TYPE (*expr_p)))
2782 *expr_p = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (*expr_p),
2783 TREE_OPERAND (*expr_p, 0));
2785 /* Canonicalize CONVERT_EXPR to NOP_EXPR. */
2786 if (TREE_CODE (*expr_p) == CONVERT_EXPR)
2787 TREE_SET_CODE (*expr_p, NOP_EXPR);
2789 return GS_OK;
2792 /* Gimplify a VAR_DECL or PARM_DECL. Return GS_OK if we expanded a
2793 DECL_VALUE_EXPR, and it's worth re-examining things. */
2795 static enum gimplify_status
2796 gimplify_var_or_parm_decl (tree *expr_p)
2798 tree decl = *expr_p;
2800 /* ??? If this is a local variable, and it has not been seen in any
2801 outer BIND_EXPR, then it's probably the result of a duplicate
2802 declaration, for which we've already issued an error. It would
2803 be really nice if the front end wouldn't leak these at all.
2804 Currently the only known culprit is C++ destructors, as seen
2805 in g++.old-deja/g++.jason/binding.C. */
2806 if (VAR_P (decl)
2807 && !DECL_SEEN_IN_BIND_EXPR_P (decl)
2808 && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl)
2809 && decl_function_context (decl) == current_function_decl)
2811 gcc_assert (seen_error ());
2812 return GS_ERROR;
2815 /* When within an OMP context, notice uses of variables. */
2816 if (gimplify_omp_ctxp && omp_notice_variable (gimplify_omp_ctxp, decl, true))
2817 return GS_ALL_DONE;
2819 /* If the decl is an alias for another expression, substitute it now. */
2820 if (DECL_HAS_VALUE_EXPR_P (decl))
2822 *expr_p = unshare_expr (DECL_VALUE_EXPR (decl));
2823 return GS_OK;
2826 return GS_ALL_DONE;
2829 /* Recalculate the value of the TREE_SIDE_EFFECTS flag for T. */
2831 static void
2832 recalculate_side_effects (tree t)
2834 enum tree_code code = TREE_CODE (t);
2835 int len = TREE_OPERAND_LENGTH (t);
2836 int i;
2838 switch (TREE_CODE_CLASS (code))
2840 case tcc_expression:
2841 switch (code)
2843 case INIT_EXPR:
2844 case MODIFY_EXPR:
2845 case VA_ARG_EXPR:
2846 case PREDECREMENT_EXPR:
2847 case PREINCREMENT_EXPR:
2848 case POSTDECREMENT_EXPR:
2849 case POSTINCREMENT_EXPR:
2850 /* All of these have side-effects, no matter what their
2851 operands are. */
2852 return;
2854 default:
2855 break;
2857 /* Fall through. */
2859 case tcc_comparison: /* a comparison expression */
2860 case tcc_unary: /* a unary arithmetic expression */
2861 case tcc_binary: /* a binary arithmetic expression */
2862 case tcc_reference: /* a reference */
2863 case tcc_vl_exp: /* a function call */
2864 TREE_SIDE_EFFECTS (t) = TREE_THIS_VOLATILE (t);
2865 for (i = 0; i < len; ++i)
2867 tree op = TREE_OPERAND (t, i);
2868 if (op && TREE_SIDE_EFFECTS (op))
2869 TREE_SIDE_EFFECTS (t) = 1;
2871 break;
2873 case tcc_constant:
2874 /* No side-effects. */
2875 return;
2877 default:
2878 gcc_unreachable ();
2882 /* Gimplify the COMPONENT_REF, ARRAY_REF, REALPART_EXPR or IMAGPART_EXPR
2883 node *EXPR_P.
2885 compound_lval
2886 : min_lval '[' val ']'
2887 | min_lval '.' ID
2888 | compound_lval '[' val ']'
2889 | compound_lval '.' ID
2891 This is not part of the original SIMPLE definition, which separates
2892 array and member references, but it seems reasonable to handle them
2893 together. Also, this way we don't run into problems with union
2894 aliasing; gcc requires that for accesses through a union to alias, the
2895 union reference must be explicit, which was not always the case when we
2896 were splitting up array and member refs.
2898 PRE_P points to the sequence where side effects that must happen before
2899 *EXPR_P should be stored.
2901 POST_P points to the sequence where side effects that must happen after
2902 *EXPR_P should be stored. */
2904 static enum gimplify_status
2905 gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
2906 fallback_t fallback)
2908 tree *p;
2909 enum gimplify_status ret = GS_ALL_DONE, tret;
2910 int i;
2911 location_t loc = EXPR_LOCATION (*expr_p);
2912 tree expr = *expr_p;
2914 /* Create a stack of the subexpressions so later we can walk them in
2915 order from inner to outer. */
2916 auto_vec<tree, 10> expr_stack;
2918 /* We can handle anything that get_inner_reference can deal with. */
2919 for (p = expr_p; ; p = &TREE_OPERAND (*p, 0))
2921 restart:
2922 /* Fold INDIRECT_REFs now to turn them into ARRAY_REFs. */
2923 if (TREE_CODE (*p) == INDIRECT_REF)
2924 *p = fold_indirect_ref_loc (loc, *p);
2926 if (handled_component_p (*p))
2928 /* Expand DECL_VALUE_EXPR now. In some cases that may expose
2929 additional COMPONENT_REFs. */
2930 else if ((VAR_P (*p) || TREE_CODE (*p) == PARM_DECL)
2931 && gimplify_var_or_parm_decl (p) == GS_OK)
2932 goto restart;
2933 else
2934 break;
2936 expr_stack.safe_push (*p);
2939 gcc_assert (expr_stack.length ());
2941 /* Now EXPR_STACK is a stack of pointers to all the refs we've
2942 walked through and P points to the innermost expression.
2944 Java requires that we elaborated nodes in source order. That
2945 means we must gimplify the inner expression followed by each of
2946 the indices, in order. But we can't gimplify the inner
2947 expression until we deal with any variable bounds, sizes, or
2948 positions in order to deal with PLACEHOLDER_EXPRs.
2950 So we do this in three steps. First we deal with the annotations
2951 for any variables in the components, then we gimplify the base,
2952 then we gimplify any indices, from left to right. */
2953 for (i = expr_stack.length () - 1; i >= 0; i--)
2955 tree t = expr_stack[i];
2957 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
2959 /* Gimplify the low bound and element type size and put them into
2960 the ARRAY_REF. If these values are set, they have already been
2961 gimplified. */
2962 if (TREE_OPERAND (t, 2) == NULL_TREE)
2964 tree low = unshare_expr (array_ref_low_bound (t));
2965 if (!is_gimple_min_invariant (low))
2967 TREE_OPERAND (t, 2) = low;
2968 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
2969 post_p, is_gimple_reg,
2970 fb_rvalue);
2971 ret = MIN (ret, tret);
2974 else
2976 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
2977 is_gimple_reg, fb_rvalue);
2978 ret = MIN (ret, tret);
2981 if (TREE_OPERAND (t, 3) == NULL_TREE)
2983 tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0)));
2984 tree elmt_size = unshare_expr (array_ref_element_size (t));
2985 tree factor = size_int (TYPE_ALIGN_UNIT (elmt_type));
2987 /* Divide the element size by the alignment of the element
2988 type (above). */
2989 elmt_size
2990 = size_binop_loc (loc, EXACT_DIV_EXPR, elmt_size, factor);
2992 if (!is_gimple_min_invariant (elmt_size))
2994 TREE_OPERAND (t, 3) = elmt_size;
2995 tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p,
2996 post_p, is_gimple_reg,
2997 fb_rvalue);
2998 ret = MIN (ret, tret);
3001 else
3003 tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p, post_p,
3004 is_gimple_reg, fb_rvalue);
3005 ret = MIN (ret, tret);
3008 else if (TREE_CODE (t) == COMPONENT_REF)
3010 /* Set the field offset into T and gimplify it. */
3011 if (TREE_OPERAND (t, 2) == NULL_TREE)
3013 tree offset = unshare_expr (component_ref_field_offset (t));
3014 tree field = TREE_OPERAND (t, 1);
3015 tree factor
3016 = size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT);
3018 /* Divide the offset by its alignment. */
3019 offset = size_binop_loc (loc, EXACT_DIV_EXPR, offset, factor);
3021 if (!is_gimple_min_invariant (offset))
3023 TREE_OPERAND (t, 2) = offset;
3024 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
3025 post_p, is_gimple_reg,
3026 fb_rvalue);
3027 ret = MIN (ret, tret);
3030 else
3032 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
3033 is_gimple_reg, fb_rvalue);
3034 ret = MIN (ret, tret);
3039 /* Step 2 is to gimplify the base expression. Make sure lvalue is set
3040 so as to match the min_lval predicate. Failure to do so may result
3041 in the creation of large aggregate temporaries. */
3042 tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval,
3043 fallback | fb_lvalue);
3044 ret = MIN (ret, tret);
3046 /* And finally, the indices and operands of ARRAY_REF. During this
3047 loop we also remove any useless conversions. */
3048 for (; expr_stack.length () > 0; )
3050 tree t = expr_stack.pop ();
3052 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
3054 /* Gimplify the dimension. */
3055 if (!is_gimple_min_invariant (TREE_OPERAND (t, 1)))
3057 tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
3058 is_gimple_val, fb_rvalue);
3059 ret = MIN (ret, tret);
3063 STRIP_USELESS_TYPE_CONVERSION (TREE_OPERAND (t, 0));
3065 /* The innermost expression P may have originally had
3066 TREE_SIDE_EFFECTS set which would have caused all the outer
3067 expressions in *EXPR_P leading to P to also have had
3068 TREE_SIDE_EFFECTS set. */
3069 recalculate_side_effects (t);
3072 /* If the outermost expression is a COMPONENT_REF, canonicalize its type. */
3073 if ((fallback & fb_rvalue) && TREE_CODE (*expr_p) == COMPONENT_REF)
3075 canonicalize_component_ref (expr_p);
3078 expr_stack.release ();
3080 gcc_assert (*expr_p == expr || ret != GS_ALL_DONE);
3082 return ret;
3085 /* Gimplify the self modifying expression pointed to by EXPR_P
3086 (++, --, +=, -=).
3088 PRE_P points to the list where side effects that must happen before
3089 *EXPR_P should be stored.
3091 POST_P points to the list where side effects that must happen after
3092 *EXPR_P should be stored.
3094 WANT_VALUE is nonzero iff we want to use the value of this expression
3095 in another expression.
3097 ARITH_TYPE is the type the computation should be performed in. */
3099 enum gimplify_status
3100 gimplify_self_mod_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
3101 bool want_value, tree arith_type)
3103 enum tree_code code;
3104 tree lhs, lvalue, rhs, t1;
3105 gimple_seq post = NULL, *orig_post_p = post_p;
3106 bool postfix;
3107 enum tree_code arith_code;
3108 enum gimplify_status ret;
3109 location_t loc = EXPR_LOCATION (*expr_p);
3111 code = TREE_CODE (*expr_p);
3113 gcc_assert (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR
3114 || code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR);
3116 /* Prefix or postfix? */
3117 if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
3118 /* Faster to treat as prefix if result is not used. */
3119 postfix = want_value;
3120 else
3121 postfix = false;
3123 /* For postfix, make sure the inner expression's post side effects
3124 are executed after side effects from this expression. */
3125 if (postfix)
3126 post_p = &post;
3128 /* Add or subtract? */
3129 if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
3130 arith_code = PLUS_EXPR;
3131 else
3132 arith_code = MINUS_EXPR;
3134 /* Gimplify the LHS into a GIMPLE lvalue. */
3135 lvalue = TREE_OPERAND (*expr_p, 0);
3136 ret = gimplify_expr (&lvalue, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
3137 if (ret == GS_ERROR)
3138 return ret;
3140 /* Extract the operands to the arithmetic operation. */
3141 lhs = lvalue;
3142 rhs = TREE_OPERAND (*expr_p, 1);
3144 /* For postfix operator, we evaluate the LHS to an rvalue and then use
3145 that as the result value and in the postqueue operation. */
3146 if (postfix)
3148 ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue);
3149 if (ret == GS_ERROR)
3150 return ret;
3152 lhs = get_initialized_tmp_var (lhs, pre_p, NULL);
3155 /* For POINTERs increment, use POINTER_PLUS_EXPR. */
3156 if (POINTER_TYPE_P (TREE_TYPE (lhs)))
3158 rhs = convert_to_ptrofftype_loc (loc, rhs);
3159 if (arith_code == MINUS_EXPR)
3160 rhs = fold_build1_loc (loc, NEGATE_EXPR, TREE_TYPE (rhs), rhs);
3161 t1 = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (*expr_p), lhs, rhs);
3163 else
3164 t1 = fold_convert (TREE_TYPE (*expr_p),
3165 fold_build2 (arith_code, arith_type,
3166 fold_convert (arith_type, lhs),
3167 fold_convert (arith_type, rhs)));
3169 if (postfix)
3171 gimplify_assign (lvalue, t1, pre_p);
3172 gimplify_seq_add_seq (orig_post_p, post);
3173 *expr_p = lhs;
3174 return GS_ALL_DONE;
3176 else
3178 *expr_p = build2 (MODIFY_EXPR, TREE_TYPE (lvalue), lvalue, t1);
3179 return GS_OK;
3183 /* If *EXPR_P has a variable sized type, wrap it in a WITH_SIZE_EXPR. */
3185 static void
3186 maybe_with_size_expr (tree *expr_p)
3188 tree expr = *expr_p;
3189 tree type = TREE_TYPE (expr);
3190 tree size;
3192 /* If we've already wrapped this or the type is error_mark_node, we can't do
3193 anything. */
3194 if (TREE_CODE (expr) == WITH_SIZE_EXPR
3195 || type == error_mark_node)
3196 return;
3198 /* If the size isn't known or is a constant, we have nothing to do. */
3199 size = TYPE_SIZE_UNIT (type);
3200 if (!size || poly_int_tree_p (size))
3201 return;
3203 /* Otherwise, make a WITH_SIZE_EXPR. */
3204 size = unshare_expr (size);
3205 size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, expr);
3206 *expr_p = build2 (WITH_SIZE_EXPR, type, expr, size);
3209 /* Helper for gimplify_call_expr. Gimplify a single argument *ARG_P
3210 Store any side-effects in PRE_P. CALL_LOCATION is the location of
3211 the CALL_EXPR. If ALLOW_SSA is set the actual parameter may be
3212 gimplified to an SSA name. */
3214 enum gimplify_status
3215 gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location,
3216 bool allow_ssa)
3218 bool (*test) (tree);
3219 fallback_t fb;
3221 /* In general, we allow lvalues for function arguments to avoid
3222 extra overhead of copying large aggregates out of even larger
3223 aggregates into temporaries only to copy the temporaries to
3224 the argument list. Make optimizers happy by pulling out to
3225 temporaries those types that fit in registers. */
3226 if (is_gimple_reg_type (TREE_TYPE (*arg_p)))
3227 test = is_gimple_val, fb = fb_rvalue;
3228 else
3230 test = is_gimple_lvalue, fb = fb_either;
3231 /* Also strip a TARGET_EXPR that would force an extra copy. */
3232 if (TREE_CODE (*arg_p) == TARGET_EXPR)
3234 tree init = TARGET_EXPR_INITIAL (*arg_p);
3235 if (init
3236 && !VOID_TYPE_P (TREE_TYPE (init)))
3237 *arg_p = init;
3241 /* If this is a variable sized type, we must remember the size. */
3242 maybe_with_size_expr (arg_p);
3244 /* FIXME diagnostics: This will mess up gcc.dg/Warray-bounds.c. */
3245 /* Make sure arguments have the same location as the function call
3246 itself. */
3247 protected_set_expr_location (*arg_p, call_location);
3249 /* There is a sequence point before a function call. Side effects in
3250 the argument list must occur before the actual call. So, when
3251 gimplifying arguments, force gimplify_expr to use an internal
3252 post queue which is then appended to the end of PRE_P. */
3253 return gimplify_expr (arg_p, pre_p, NULL, test, fb, allow_ssa);
3256 /* Don't fold inside offloading or taskreg regions: it can break code by
3257 adding decl references that weren't in the source. We'll do it during
3258 omplower pass instead. */
3260 static bool
3261 maybe_fold_stmt (gimple_stmt_iterator *gsi)
3263 struct gimplify_omp_ctx *ctx;
3264 for (ctx = gimplify_omp_ctxp; ctx; ctx = ctx->outer_context)
3265 if ((ctx->region_type & (ORT_TARGET | ORT_PARALLEL | ORT_TASK)) != 0)
3266 return false;
3267 else if ((ctx->region_type & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
3268 return false;
3269 /* Delay folding of builtins until the IL is in consistent state
3270 so the diagnostic machinery can do a better job. */
3271 if (gimple_call_builtin_p (gsi_stmt (*gsi)))
3272 return false;
3273 return fold_stmt (gsi);
3276 /* Gimplify the CALL_EXPR node *EXPR_P into the GIMPLE sequence PRE_P.
3277 WANT_VALUE is true if the result of the call is desired. */
3279 static enum gimplify_status
3280 gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
3282 tree fndecl, parms, p, fnptrtype;
3283 enum gimplify_status ret;
3284 int i, nargs;
3285 gcall *call;
3286 bool builtin_va_start_p = false;
3287 location_t loc = EXPR_LOCATION (*expr_p);
3289 gcc_assert (TREE_CODE (*expr_p) == CALL_EXPR);
3291 /* For reliable diagnostics during inlining, it is necessary that
3292 every call_expr be annotated with file and line. */
3293 if (! EXPR_HAS_LOCATION (*expr_p))
3294 SET_EXPR_LOCATION (*expr_p, input_location);
3296 /* Gimplify internal functions created in the FEs. */
3297 if (CALL_EXPR_FN (*expr_p) == NULL_TREE)
3299 if (want_value)
3300 return GS_ALL_DONE;
3302 nargs = call_expr_nargs (*expr_p);
3303 enum internal_fn ifn = CALL_EXPR_IFN (*expr_p);
3304 auto_vec<tree> vargs (nargs);
3306 for (i = 0; i < nargs; i++)
3308 gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
3309 EXPR_LOCATION (*expr_p));
3310 vargs.quick_push (CALL_EXPR_ARG (*expr_p, i));
3313 gcall *call = gimple_build_call_internal_vec (ifn, vargs);
3314 gimple_call_set_nothrow (call, TREE_NOTHROW (*expr_p));
3315 gimplify_seq_add_stmt (pre_p, call);
3316 return GS_ALL_DONE;
3319 /* This may be a call to a builtin function.
3321 Builtin function calls may be transformed into different
3322 (and more efficient) builtin function calls under certain
3323 circumstances. Unfortunately, gimplification can muck things
3324 up enough that the builtin expanders are not aware that certain
3325 transformations are still valid.
3327 So we attempt transformation/gimplification of the call before
3328 we gimplify the CALL_EXPR. At this time we do not manage to
3329 transform all calls in the same manner as the expanders do, but
3330 we do transform most of them. */
3331 fndecl = get_callee_fndecl (*expr_p);
3332 if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
3333 switch (DECL_FUNCTION_CODE (fndecl))
3335 CASE_BUILT_IN_ALLOCA:
3336 /* If the call has been built for a variable-sized object, then we
3337 want to restore the stack level when the enclosing BIND_EXPR is
3338 exited to reclaim the allocated space; otherwise, we precisely
3339 need to do the opposite and preserve the latest stack level. */
3340 if (CALL_ALLOCA_FOR_VAR_P (*expr_p))
3341 gimplify_ctxp->save_stack = true;
3342 else
3343 gimplify_ctxp->keep_stack = true;
3344 break;
3346 case BUILT_IN_VA_START:
3348 builtin_va_start_p = TRUE;
3349 if (call_expr_nargs (*expr_p) < 2)
3351 error ("too few arguments to function %<va_start%>");
3352 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
3353 return GS_OK;
3356 if (fold_builtin_next_arg (*expr_p, true))
3358 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
3359 return GS_OK;
3361 break;
3364 case BUILT_IN_EH_RETURN:
3365 cfun->calls_eh_return = true;
3366 break;
3368 default:
3371 if (fndecl && fndecl_built_in_p (fndecl))
3373 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
3374 if (new_tree && new_tree != *expr_p)
3376 /* There was a transformation of this call which computes the
3377 same value, but in a more efficient way. Return and try
3378 again. */
3379 *expr_p = new_tree;
3380 return GS_OK;
3384 /* Remember the original function pointer type. */
3385 fnptrtype = TREE_TYPE (CALL_EXPR_FN (*expr_p));
3387 /* There is a sequence point before the call, so any side effects in
3388 the calling expression must occur before the actual call. Force
3389 gimplify_expr to use an internal post queue. */
3390 ret = gimplify_expr (&CALL_EXPR_FN (*expr_p), pre_p, NULL,
3391 is_gimple_call_addr, fb_rvalue);
3393 nargs = call_expr_nargs (*expr_p);
3395 /* Get argument types for verification. */
3396 fndecl = get_callee_fndecl (*expr_p);
3397 parms = NULL_TREE;
3398 if (fndecl)
3399 parms = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
3400 else
3401 parms = TYPE_ARG_TYPES (TREE_TYPE (fnptrtype));
3403 if (fndecl && DECL_ARGUMENTS (fndecl))
3404 p = DECL_ARGUMENTS (fndecl);
3405 else if (parms)
3406 p = parms;
3407 else
3408 p = NULL_TREE;
3409 for (i = 0; i < nargs && p; i++, p = TREE_CHAIN (p))
3412 /* If the last argument is __builtin_va_arg_pack () and it is not
3413 passed as a named argument, decrease the number of CALL_EXPR
3414 arguments and set instead the CALL_EXPR_VA_ARG_PACK flag. */
3415 if (!p
3416 && i < nargs
3417 && TREE_CODE (CALL_EXPR_ARG (*expr_p, nargs - 1)) == CALL_EXPR)
3419 tree last_arg = CALL_EXPR_ARG (*expr_p, nargs - 1);
3420 tree last_arg_fndecl = get_callee_fndecl (last_arg);
3422 if (last_arg_fndecl
3423 && fndecl_built_in_p (last_arg_fndecl, BUILT_IN_VA_ARG_PACK))
3425 tree call = *expr_p;
3427 --nargs;
3428 *expr_p = build_call_array_loc (loc, TREE_TYPE (call),
3429 CALL_EXPR_FN (call),
3430 nargs, CALL_EXPR_ARGP (call));
3432 /* Copy all CALL_EXPR flags, location and block, except
3433 CALL_EXPR_VA_ARG_PACK flag. */
3434 CALL_EXPR_STATIC_CHAIN (*expr_p) = CALL_EXPR_STATIC_CHAIN (call);
3435 CALL_EXPR_TAILCALL (*expr_p) = CALL_EXPR_TAILCALL (call);
3436 CALL_EXPR_RETURN_SLOT_OPT (*expr_p)
3437 = CALL_EXPR_RETURN_SLOT_OPT (call);
3438 CALL_FROM_THUNK_P (*expr_p) = CALL_FROM_THUNK_P (call);
3439 SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (call));
3441 /* Set CALL_EXPR_VA_ARG_PACK. */
3442 CALL_EXPR_VA_ARG_PACK (*expr_p) = 1;
3446 /* If the call returns twice then after building the CFG the call
3447 argument computations will no longer dominate the call because
3448 we add an abnormal incoming edge to the call. So do not use SSA
3449 vars there. */
3450 bool returns_twice = call_expr_flags (*expr_p) & ECF_RETURNS_TWICE;
3452 /* Gimplify the function arguments. */
3453 if (nargs > 0)
3455 for (i = (PUSH_ARGS_REVERSED ? nargs - 1 : 0);
3456 PUSH_ARGS_REVERSED ? i >= 0 : i < nargs;
3457 PUSH_ARGS_REVERSED ? i-- : i++)
3459 enum gimplify_status t;
3461 /* Avoid gimplifying the second argument to va_start, which needs to
3462 be the plain PARM_DECL. */
3463 if ((i != 1) || !builtin_va_start_p)
3465 t = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
3466 EXPR_LOCATION (*expr_p), ! returns_twice);
3468 if (t == GS_ERROR)
3469 ret = GS_ERROR;
3474 /* Gimplify the static chain. */
3475 if (CALL_EXPR_STATIC_CHAIN (*expr_p))
3477 if (fndecl && !DECL_STATIC_CHAIN (fndecl))
3478 CALL_EXPR_STATIC_CHAIN (*expr_p) = NULL;
3479 else
3481 enum gimplify_status t;
3482 t = gimplify_arg (&CALL_EXPR_STATIC_CHAIN (*expr_p), pre_p,
3483 EXPR_LOCATION (*expr_p), ! returns_twice);
3484 if (t == GS_ERROR)
3485 ret = GS_ERROR;
3489 /* Verify the function result. */
3490 if (want_value && fndecl
3491 && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fnptrtype))))
3493 error_at (loc, "using result of function returning %<void%>");
3494 ret = GS_ERROR;
3497 /* Try this again in case gimplification exposed something. */
3498 if (ret != GS_ERROR)
3500 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
3502 if (new_tree && new_tree != *expr_p)
3504 /* There was a transformation of this call which computes the
3505 same value, but in a more efficient way. Return and try
3506 again. */
3507 *expr_p = new_tree;
3508 return GS_OK;
3511 else
3513 *expr_p = error_mark_node;
3514 return GS_ERROR;
3517 /* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its
3518 decl. This allows us to eliminate redundant or useless
3519 calls to "const" functions. */
3520 if (TREE_CODE (*expr_p) == CALL_EXPR)
3522 int flags = call_expr_flags (*expr_p);
3523 if (flags & (ECF_CONST | ECF_PURE)
3524 /* An infinite loop is considered a side effect. */
3525 && !(flags & (ECF_LOOPING_CONST_OR_PURE)))
3526 TREE_SIDE_EFFECTS (*expr_p) = 0;
3529 /* If the value is not needed by the caller, emit a new GIMPLE_CALL
3530 and clear *EXPR_P. Otherwise, leave *EXPR_P in its gimplified
3531 form and delegate the creation of a GIMPLE_CALL to
3532 gimplify_modify_expr. This is always possible because when
3533 WANT_VALUE is true, the caller wants the result of this call into
3534 a temporary, which means that we will emit an INIT_EXPR in
3535 internal_get_tmp_var which will then be handled by
3536 gimplify_modify_expr. */
3537 if (!want_value)
3539 /* The CALL_EXPR in *EXPR_P is already in GIMPLE form, so all we
3540 have to do is replicate it as a GIMPLE_CALL tuple. */
3541 gimple_stmt_iterator gsi;
3542 call = gimple_build_call_from_tree (*expr_p, fnptrtype);
3543 notice_special_calls (call);
3544 gimplify_seq_add_stmt (pre_p, call);
3545 gsi = gsi_last (*pre_p);
3546 maybe_fold_stmt (&gsi);
3547 *expr_p = NULL_TREE;
3549 else
3550 /* Remember the original function type. */
3551 CALL_EXPR_FN (*expr_p) = build1 (NOP_EXPR, fnptrtype,
3552 CALL_EXPR_FN (*expr_p));
3554 return ret;
3557 /* Handle shortcut semantics in the predicate operand of a COND_EXPR by
3558 rewriting it into multiple COND_EXPRs, and possibly GOTO_EXPRs.
3560 TRUE_LABEL_P and FALSE_LABEL_P point to the labels to jump to if the
3561 condition is true or false, respectively. If null, we should generate
3562 our own to skip over the evaluation of this specific expression.
3564 LOCUS is the source location of the COND_EXPR.
3566 This function is the tree equivalent of do_jump.
3568 shortcut_cond_r should only be called by shortcut_cond_expr. */
3570 static tree
3571 shortcut_cond_r (tree pred, tree *true_label_p, tree *false_label_p,
3572 location_t locus)
3574 tree local_label = NULL_TREE;
3575 tree t, expr = NULL;
3577 /* OK, it's not a simple case; we need to pull apart the COND_EXPR to
3578 retain the shortcut semantics. Just insert the gotos here;
3579 shortcut_cond_expr will append the real blocks later. */
3580 if (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
3582 location_t new_locus;
3584 /* Turn if (a && b) into
3586 if (a); else goto no;
3587 if (b) goto yes; else goto no;
3588 (no:) */
3590 if (false_label_p == NULL)
3591 false_label_p = &local_label;
3593 /* Keep the original source location on the first 'if'. */
3594 t = shortcut_cond_r (TREE_OPERAND (pred, 0), NULL, false_label_p, locus);
3595 append_to_statement_list (t, &expr);
3597 /* Set the source location of the && on the second 'if'. */
3598 new_locus = rexpr_location (pred, locus);
3599 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
3600 new_locus);
3601 append_to_statement_list (t, &expr);
3603 else if (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
3605 location_t new_locus;
3607 /* Turn if (a || b) into
3609 if (a) goto yes;
3610 if (b) goto yes; else goto no;
3611 (yes:) */
3613 if (true_label_p == NULL)
3614 true_label_p = &local_label;
3616 /* Keep the original source location on the first 'if'. */
3617 t = shortcut_cond_r (TREE_OPERAND (pred, 0), true_label_p, NULL, locus);
3618 append_to_statement_list (t, &expr);
3620 /* Set the source location of the || on the second 'if'. */
3621 new_locus = rexpr_location (pred, locus);
3622 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
3623 new_locus);
3624 append_to_statement_list (t, &expr);
3626 else if (TREE_CODE (pred) == COND_EXPR
3627 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 1)))
3628 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 2))))
3630 location_t new_locus;
3632 /* As long as we're messing with gotos, turn if (a ? b : c) into
3633 if (a)
3634 if (b) goto yes; else goto no;
3635 else
3636 if (c) goto yes; else goto no;
3638 Don't do this if one of the arms has void type, which can happen
3639 in C++ when the arm is throw. */
3641 /* Keep the original source location on the first 'if'. Set the source
3642 location of the ? on the second 'if'. */
3643 new_locus = rexpr_location (pred, locus);
3644 expr = build3 (COND_EXPR, void_type_node, TREE_OPERAND (pred, 0),
3645 shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p,
3646 false_label_p, locus),
3647 shortcut_cond_r (TREE_OPERAND (pred, 2), true_label_p,
3648 false_label_p, new_locus));
3650 else
3652 expr = build3 (COND_EXPR, void_type_node, pred,
3653 build_and_jump (true_label_p),
3654 build_and_jump (false_label_p));
3655 SET_EXPR_LOCATION (expr, locus);
3658 if (local_label)
3660 t = build1 (LABEL_EXPR, void_type_node, local_label);
3661 append_to_statement_list (t, &expr);
3664 return expr;
3667 /* If EXPR is a GOTO_EXPR, return it. If it is a STATEMENT_LIST, skip
3668 any of its leading DEBUG_BEGIN_STMTS and recurse on the subsequent
3669 statement, if it is the last one. Otherwise, return NULL. */
3671 static tree
3672 find_goto (tree expr)
3674 if (!expr)
3675 return NULL_TREE;
3677 if (TREE_CODE (expr) == GOTO_EXPR)
3678 return expr;
3680 if (TREE_CODE (expr) != STATEMENT_LIST)
3681 return NULL_TREE;
3683 tree_stmt_iterator i = tsi_start (expr);
3685 while (!tsi_end_p (i) && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT)
3686 tsi_next (&i);
3688 if (!tsi_one_before_end_p (i))
3689 return NULL_TREE;
3691 return find_goto (tsi_stmt (i));
3694 /* Same as find_goto, except that it returns NULL if the destination
3695 is not a LABEL_DECL. */
3697 static inline tree
3698 find_goto_label (tree expr)
3700 tree dest = find_goto (expr);
3701 if (dest && TREE_CODE (GOTO_DESTINATION (dest)) == LABEL_DECL)
3702 return dest;
3703 return NULL_TREE;
3706 /* Given a conditional expression EXPR with short-circuit boolean
3707 predicates using TRUTH_ANDIF_EXPR or TRUTH_ORIF_EXPR, break the
3708 predicate apart into the equivalent sequence of conditionals. */
3710 static tree
3711 shortcut_cond_expr (tree expr)
3713 tree pred = TREE_OPERAND (expr, 0);
3714 tree then_ = TREE_OPERAND (expr, 1);
3715 tree else_ = TREE_OPERAND (expr, 2);
3716 tree true_label, false_label, end_label, t;
3717 tree *true_label_p;
3718 tree *false_label_p;
3719 bool emit_end, emit_false, jump_over_else;
3720 bool then_se = then_ && TREE_SIDE_EFFECTS (then_);
3721 bool else_se = else_ && TREE_SIDE_EFFECTS (else_);
3723 /* First do simple transformations. */
3724 if (!else_se)
3726 /* If there is no 'else', turn
3727 if (a && b) then c
3728 into
3729 if (a) if (b) then c. */
3730 while (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
3732 /* Keep the original source location on the first 'if'. */
3733 location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
3734 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
3735 /* Set the source location of the && on the second 'if'. */
3736 if (rexpr_has_location (pred))
3737 SET_EXPR_LOCATION (expr, rexpr_location (pred));
3738 then_ = shortcut_cond_expr (expr);
3739 then_se = then_ && TREE_SIDE_EFFECTS (then_);
3740 pred = TREE_OPERAND (pred, 0);
3741 expr = build3 (COND_EXPR, void_type_node, pred, then_, NULL_TREE);
3742 SET_EXPR_LOCATION (expr, locus);
3746 if (!then_se)
3748 /* If there is no 'then', turn
3749 if (a || b); else d
3750 into
3751 if (a); else if (b); else d. */
3752 while (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
3754 /* Keep the original source location on the first 'if'. */
3755 location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
3756 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
3757 /* Set the source location of the || on the second 'if'. */
3758 if (rexpr_has_location (pred))
3759 SET_EXPR_LOCATION (expr, rexpr_location (pred));
3760 else_ = shortcut_cond_expr (expr);
3761 else_se = else_ && TREE_SIDE_EFFECTS (else_);
3762 pred = TREE_OPERAND (pred, 0);
3763 expr = build3 (COND_EXPR, void_type_node, pred, NULL_TREE, else_);
3764 SET_EXPR_LOCATION (expr, locus);
3768 /* If we're done, great. */
3769 if (TREE_CODE (pred) != TRUTH_ANDIF_EXPR
3770 && TREE_CODE (pred) != TRUTH_ORIF_EXPR)
3771 return expr;
3773 /* Otherwise we need to mess with gotos. Change
3774 if (a) c; else d;
3776 if (a); else goto no;
3777 c; goto end;
3778 no: d; end:
3779 and recursively gimplify the condition. */
3781 true_label = false_label = end_label = NULL_TREE;
3783 /* If our arms just jump somewhere, hijack those labels so we don't
3784 generate jumps to jumps. */
3786 if (tree then_goto = find_goto_label (then_))
3788 true_label = GOTO_DESTINATION (then_goto);
3789 then_ = NULL;
3790 then_se = false;
3793 if (tree else_goto = find_goto_label (else_))
3795 false_label = GOTO_DESTINATION (else_goto);
3796 else_ = NULL;
3797 else_se = false;
3800 /* If we aren't hijacking a label for the 'then' branch, it falls through. */
3801 if (true_label)
3802 true_label_p = &true_label;
3803 else
3804 true_label_p = NULL;
3806 /* The 'else' branch also needs a label if it contains interesting code. */
3807 if (false_label || else_se)
3808 false_label_p = &false_label;
3809 else
3810 false_label_p = NULL;
3812 /* If there was nothing else in our arms, just forward the label(s). */
3813 if (!then_se && !else_se)
3814 return shortcut_cond_r (pred, true_label_p, false_label_p,
3815 EXPR_LOC_OR_LOC (expr, input_location));
3817 /* If our last subexpression already has a terminal label, reuse it. */
3818 if (else_se)
3819 t = expr_last (else_);
3820 else if (then_se)
3821 t = expr_last (then_);
3822 else
3823 t = NULL;
3824 if (t && TREE_CODE (t) == LABEL_EXPR)
3825 end_label = LABEL_EXPR_LABEL (t);
3827 /* If we don't care about jumping to the 'else' branch, jump to the end
3828 if the condition is false. */
3829 if (!false_label_p)
3830 false_label_p = &end_label;
3832 /* We only want to emit these labels if we aren't hijacking them. */
3833 emit_end = (end_label == NULL_TREE);
3834 emit_false = (false_label == NULL_TREE);
3836 /* We only emit the jump over the else clause if we have to--if the
3837 then clause may fall through. Otherwise we can wind up with a
3838 useless jump and a useless label at the end of gimplified code,
3839 which will cause us to think that this conditional as a whole
3840 falls through even if it doesn't. If we then inline a function
3841 which ends with such a condition, that can cause us to issue an
3842 inappropriate warning about control reaching the end of a
3843 non-void function. */
3844 jump_over_else = block_may_fallthru (then_);
3846 pred = shortcut_cond_r (pred, true_label_p, false_label_p,
3847 EXPR_LOC_OR_LOC (expr, input_location));
3849 expr = NULL;
3850 append_to_statement_list (pred, &expr);
3852 append_to_statement_list (then_, &expr);
3853 if (else_se)
3855 if (jump_over_else)
3857 tree last = expr_last (expr);
3858 t = build_and_jump (&end_label);
3859 if (rexpr_has_location (last))
3860 SET_EXPR_LOCATION (t, rexpr_location (last));
3861 append_to_statement_list (t, &expr);
3863 if (emit_false)
3865 t = build1 (LABEL_EXPR, void_type_node, false_label);
3866 append_to_statement_list (t, &expr);
3868 append_to_statement_list (else_, &expr);
3870 if (emit_end && end_label)
3872 t = build1 (LABEL_EXPR, void_type_node, end_label);
3873 append_to_statement_list (t, &expr);
3876 return expr;
3879 /* EXPR is used in a boolean context; make sure it has BOOLEAN_TYPE. */
3881 tree
3882 gimple_boolify (tree expr)
3884 tree type = TREE_TYPE (expr);
3885 location_t loc = EXPR_LOCATION (expr);
3887 if (TREE_CODE (expr) == NE_EXPR
3888 && TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR
3889 && integer_zerop (TREE_OPERAND (expr, 1)))
3891 tree call = TREE_OPERAND (expr, 0);
3892 tree fn = get_callee_fndecl (call);
3894 /* For __builtin_expect ((long) (x), y) recurse into x as well
3895 if x is truth_value_p. */
3896 if (fn
3897 && fndecl_built_in_p (fn, BUILT_IN_EXPECT)
3898 && call_expr_nargs (call) == 2)
3900 tree arg = CALL_EXPR_ARG (call, 0);
3901 if (arg)
3903 if (TREE_CODE (arg) == NOP_EXPR
3904 && TREE_TYPE (arg) == TREE_TYPE (call))
3905 arg = TREE_OPERAND (arg, 0);
3906 if (truth_value_p (TREE_CODE (arg)))
3908 arg = gimple_boolify (arg);
3909 CALL_EXPR_ARG (call, 0)
3910 = fold_convert_loc (loc, TREE_TYPE (call), arg);
3916 switch (TREE_CODE (expr))
3918 case TRUTH_AND_EXPR:
3919 case TRUTH_OR_EXPR:
3920 case TRUTH_XOR_EXPR:
3921 case TRUTH_ANDIF_EXPR:
3922 case TRUTH_ORIF_EXPR:
3923 /* Also boolify the arguments of truth exprs. */
3924 TREE_OPERAND (expr, 1) = gimple_boolify (TREE_OPERAND (expr, 1));
3925 /* FALLTHRU */
3927 case TRUTH_NOT_EXPR:
3928 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
3930 /* These expressions always produce boolean results. */
3931 if (TREE_CODE (type) != BOOLEAN_TYPE)
3932 TREE_TYPE (expr) = boolean_type_node;
3933 return expr;
3935 case ANNOTATE_EXPR:
3936 switch ((enum annot_expr_kind) TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)))
3938 case annot_expr_ivdep_kind:
3939 case annot_expr_unroll_kind:
3940 case annot_expr_no_vector_kind:
3941 case annot_expr_vector_kind:
3942 case annot_expr_parallel_kind:
3943 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
3944 if (TREE_CODE (type) != BOOLEAN_TYPE)
3945 TREE_TYPE (expr) = boolean_type_node;
3946 return expr;
3947 default:
3948 gcc_unreachable ();
3951 default:
3952 if (COMPARISON_CLASS_P (expr))
3954 /* There expressions always prduce boolean results. */
3955 if (TREE_CODE (type) != BOOLEAN_TYPE)
3956 TREE_TYPE (expr) = boolean_type_node;
3957 return expr;
3959 /* Other expressions that get here must have boolean values, but
3960 might need to be converted to the appropriate mode. */
3961 if (TREE_CODE (type) == BOOLEAN_TYPE)
3962 return expr;
3963 return fold_convert_loc (loc, boolean_type_node, expr);
3967 /* Given a conditional expression *EXPR_P without side effects, gimplify
3968 its operands. New statements are inserted to PRE_P. */
3970 static enum gimplify_status
3971 gimplify_pure_cond_expr (tree *expr_p, gimple_seq *pre_p)
3973 tree expr = *expr_p, cond;
3974 enum gimplify_status ret, tret;
3975 enum tree_code code;
3977 cond = gimple_boolify (COND_EXPR_COND (expr));
3979 /* We need to handle && and || specially, as their gimplification
3980 creates pure cond_expr, thus leading to an infinite cycle otherwise. */
3981 code = TREE_CODE (cond);
3982 if (code == TRUTH_ANDIF_EXPR)
3983 TREE_SET_CODE (cond, TRUTH_AND_EXPR);
3984 else if (code == TRUTH_ORIF_EXPR)
3985 TREE_SET_CODE (cond, TRUTH_OR_EXPR);
3986 ret = gimplify_expr (&cond, pre_p, NULL, is_gimple_condexpr, fb_rvalue);
3987 COND_EXPR_COND (*expr_p) = cond;
3989 tret = gimplify_expr (&COND_EXPR_THEN (expr), pre_p, NULL,
3990 is_gimple_val, fb_rvalue);
3991 ret = MIN (ret, tret);
3992 tret = gimplify_expr (&COND_EXPR_ELSE (expr), pre_p, NULL,
3993 is_gimple_val, fb_rvalue);
3995 return MIN (ret, tret);
3998 /* Return true if evaluating EXPR could trap.
3999 EXPR is GENERIC, while tree_could_trap_p can be called
4000 only on GIMPLE. */
4002 bool
4003 generic_expr_could_trap_p (tree expr)
4005 unsigned i, n;
4007 if (!expr || is_gimple_val (expr))
4008 return false;
4010 if (!EXPR_P (expr) || tree_could_trap_p (expr))
4011 return true;
4013 n = TREE_OPERAND_LENGTH (expr);
4014 for (i = 0; i < n; i++)
4015 if (generic_expr_could_trap_p (TREE_OPERAND (expr, i)))
4016 return true;
4018 return false;
4021 /* Convert the conditional expression pointed to by EXPR_P '(p) ? a : b;'
4022 into
4024 if (p) if (p)
4025 t1 = a; a;
4026 else or else
4027 t1 = b; b;
4030 The second form is used when *EXPR_P is of type void.
4032 PRE_P points to the list where side effects that must happen before
4033 *EXPR_P should be stored. */
4035 static enum gimplify_status
4036 gimplify_cond_expr (tree *expr_p, gimple_seq *pre_p, fallback_t fallback)
4038 tree expr = *expr_p;
4039 tree type = TREE_TYPE (expr);
4040 location_t loc = EXPR_LOCATION (expr);
4041 tree tmp, arm1, arm2;
4042 enum gimplify_status ret;
4043 tree label_true, label_false, label_cont;
4044 bool have_then_clause_p, have_else_clause_p;
4045 gcond *cond_stmt;
4046 enum tree_code pred_code;
4047 gimple_seq seq = NULL;
4049 /* If this COND_EXPR has a value, copy the values into a temporary within
4050 the arms. */
4051 if (!VOID_TYPE_P (type))
4053 tree then_ = TREE_OPERAND (expr, 1), else_ = TREE_OPERAND (expr, 2);
4054 tree result;
4056 /* If either an rvalue is ok or we do not require an lvalue, create the
4057 temporary. But we cannot do that if the type is addressable. */
4058 if (((fallback & fb_rvalue) || !(fallback & fb_lvalue))
4059 && !TREE_ADDRESSABLE (type))
4061 if (gimplify_ctxp->allow_rhs_cond_expr
4062 /* If either branch has side effects or could trap, it can't be
4063 evaluated unconditionally. */
4064 && !TREE_SIDE_EFFECTS (then_)
4065 && !generic_expr_could_trap_p (then_)
4066 && !TREE_SIDE_EFFECTS (else_)
4067 && !generic_expr_could_trap_p (else_))
4068 return gimplify_pure_cond_expr (expr_p, pre_p);
4070 tmp = create_tmp_var (type, "iftmp");
4071 result = tmp;
4074 /* Otherwise, only create and copy references to the values. */
4075 else
4077 type = build_pointer_type (type);
4079 if (!VOID_TYPE_P (TREE_TYPE (then_)))
4080 then_ = build_fold_addr_expr_loc (loc, then_);
4082 if (!VOID_TYPE_P (TREE_TYPE (else_)))
4083 else_ = build_fold_addr_expr_loc (loc, else_);
4085 expr
4086 = build3 (COND_EXPR, type, TREE_OPERAND (expr, 0), then_, else_);
4088 tmp = create_tmp_var (type, "iftmp");
4089 result = build_simple_mem_ref_loc (loc, tmp);
4092 /* Build the new then clause, `tmp = then_;'. But don't build the
4093 assignment if the value is void; in C++ it can be if it's a throw. */
4094 if (!VOID_TYPE_P (TREE_TYPE (then_)))
4095 TREE_OPERAND (expr, 1) = build2 (INIT_EXPR, type, tmp, then_);
4097 /* Similarly, build the new else clause, `tmp = else_;'. */
4098 if (!VOID_TYPE_P (TREE_TYPE (else_)))
4099 TREE_OPERAND (expr, 2) = build2 (INIT_EXPR, type, tmp, else_);
4101 TREE_TYPE (expr) = void_type_node;
4102 recalculate_side_effects (expr);
4104 /* Move the COND_EXPR to the prequeue. */
4105 gimplify_stmt (&expr, pre_p);
4107 *expr_p = result;
4108 return GS_ALL_DONE;
4111 /* Remove any COMPOUND_EXPR so the following cases will be caught. */
4112 STRIP_TYPE_NOPS (TREE_OPERAND (expr, 0));
4113 if (TREE_CODE (TREE_OPERAND (expr, 0)) == COMPOUND_EXPR)
4114 gimplify_compound_expr (&TREE_OPERAND (expr, 0), pre_p, true);
4116 /* Make sure the condition has BOOLEAN_TYPE. */
4117 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
4119 /* Break apart && and || conditions. */
4120 if (TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ANDIF_EXPR
4121 || TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ORIF_EXPR)
4123 expr = shortcut_cond_expr (expr);
4125 if (expr != *expr_p)
4127 *expr_p = expr;
4129 /* We can't rely on gimplify_expr to re-gimplify the expanded
4130 form properly, as cleanups might cause the target labels to be
4131 wrapped in a TRY_FINALLY_EXPR. To prevent that, we need to
4132 set up a conditional context. */
4133 gimple_push_condition ();
4134 gimplify_stmt (expr_p, &seq);
4135 gimple_pop_condition (pre_p);
4136 gimple_seq_add_seq (pre_p, seq);
4138 return GS_ALL_DONE;
4142 /* Now do the normal gimplification. */
4144 /* Gimplify condition. */
4145 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL, is_gimple_condexpr,
4146 fb_rvalue);
4147 if (ret == GS_ERROR)
4148 return GS_ERROR;
4149 gcc_assert (TREE_OPERAND (expr, 0) != NULL_TREE);
4151 gimple_push_condition ();
4153 have_then_clause_p = have_else_clause_p = false;
4154 label_true = find_goto_label (TREE_OPERAND (expr, 1));
4155 if (label_true
4156 && DECL_CONTEXT (GOTO_DESTINATION (label_true)) == current_function_decl
4157 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4158 have different locations, otherwise we end up with incorrect
4159 location information on the branches. */
4160 && (optimize
4161 || !EXPR_HAS_LOCATION (expr)
4162 || !rexpr_has_location (label_true)
4163 || EXPR_LOCATION (expr) == rexpr_location (label_true)))
4165 have_then_clause_p = true;
4166 label_true = GOTO_DESTINATION (label_true);
4168 else
4169 label_true = create_artificial_label (UNKNOWN_LOCATION);
4170 label_false = find_goto_label (TREE_OPERAND (expr, 2));
4171 if (label_false
4172 && DECL_CONTEXT (GOTO_DESTINATION (label_false)) == current_function_decl
4173 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4174 have different locations, otherwise we end up with incorrect
4175 location information on the branches. */
4176 && (optimize
4177 || !EXPR_HAS_LOCATION (expr)
4178 || !rexpr_has_location (label_false)
4179 || EXPR_LOCATION (expr) == rexpr_location (label_false)))
4181 have_else_clause_p = true;
4182 label_false = GOTO_DESTINATION (label_false);
4184 else
4185 label_false = create_artificial_label (UNKNOWN_LOCATION);
4187 gimple_cond_get_ops_from_tree (COND_EXPR_COND (expr), &pred_code, &arm1,
4188 &arm2);
4189 cond_stmt = gimple_build_cond (pred_code, arm1, arm2, label_true,
4190 label_false);
4191 gimple_set_no_warning (cond_stmt, TREE_NO_WARNING (COND_EXPR_COND (expr)));
4192 gimplify_seq_add_stmt (&seq, cond_stmt);
4193 gimple_stmt_iterator gsi = gsi_last (seq);
4194 maybe_fold_stmt (&gsi);
4196 label_cont = NULL_TREE;
4197 if (!have_then_clause_p)
4199 /* For if (...) {} else { code; } put label_true after
4200 the else block. */
4201 if (TREE_OPERAND (expr, 1) == NULL_TREE
4202 && !have_else_clause_p
4203 && TREE_OPERAND (expr, 2) != NULL_TREE)
4204 label_cont = label_true;
4205 else
4207 gimplify_seq_add_stmt (&seq, gimple_build_label (label_true));
4208 have_then_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 1), &seq);
4209 /* For if (...) { code; } else {} or
4210 if (...) { code; } else goto label; or
4211 if (...) { code; return; } else { ... }
4212 label_cont isn't needed. */
4213 if (!have_else_clause_p
4214 && TREE_OPERAND (expr, 2) != NULL_TREE
4215 && gimple_seq_may_fallthru (seq))
4217 gimple *g;
4218 label_cont = create_artificial_label (UNKNOWN_LOCATION);
4220 g = gimple_build_goto (label_cont);
4222 /* GIMPLE_COND's are very low level; they have embedded
4223 gotos. This particular embedded goto should not be marked
4224 with the location of the original COND_EXPR, as it would
4225 correspond to the COND_EXPR's condition, not the ELSE or the
4226 THEN arms. To avoid marking it with the wrong location, flag
4227 it as "no location". */
4228 gimple_set_do_not_emit_location (g);
4230 gimplify_seq_add_stmt (&seq, g);
4234 if (!have_else_clause_p)
4236 gimplify_seq_add_stmt (&seq, gimple_build_label (label_false));
4237 have_else_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 2), &seq);
4239 if (label_cont)
4240 gimplify_seq_add_stmt (&seq, gimple_build_label (label_cont));
4242 gimple_pop_condition (pre_p);
4243 gimple_seq_add_seq (pre_p, seq);
4245 if (ret == GS_ERROR)
4246 ; /* Do nothing. */
4247 else if (have_then_clause_p || have_else_clause_p)
4248 ret = GS_ALL_DONE;
4249 else
4251 /* Both arms are empty; replace the COND_EXPR with its predicate. */
4252 expr = TREE_OPERAND (expr, 0);
4253 gimplify_stmt (&expr, pre_p);
4256 *expr_p = NULL;
4257 return ret;
4260 /* Prepare the node pointed to by EXPR_P, an is_gimple_addressable expression,
4261 to be marked addressable.
4263 We cannot rely on such an expression being directly markable if a temporary
4264 has been created by the gimplification. In this case, we create another
4265 temporary and initialize it with a copy, which will become a store after we
4266 mark it addressable. This can happen if the front-end passed us something
4267 that it could not mark addressable yet, like a Fortran pass-by-reference
4268 parameter (int) floatvar. */
4270 static void
4271 prepare_gimple_addressable (tree *expr_p, gimple_seq *seq_p)
4273 while (handled_component_p (*expr_p))
4274 expr_p = &TREE_OPERAND (*expr_p, 0);
4275 if (is_gimple_reg (*expr_p))
4277 /* Do not allow an SSA name as the temporary. */
4278 tree var = get_initialized_tmp_var (*expr_p, seq_p, NULL, false);
4279 DECL_GIMPLE_REG_P (var) = 0;
4280 *expr_p = var;
4284 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4285 a call to __builtin_memcpy. */
4287 static enum gimplify_status
4288 gimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value,
4289 gimple_seq *seq_p)
4291 tree t, to, to_ptr, from, from_ptr;
4292 gcall *gs;
4293 location_t loc = EXPR_LOCATION (*expr_p);
4295 to = TREE_OPERAND (*expr_p, 0);
4296 from = TREE_OPERAND (*expr_p, 1);
4298 /* Mark the RHS addressable. Beware that it may not be possible to do so
4299 directly if a temporary has been created by the gimplification. */
4300 prepare_gimple_addressable (&from, seq_p);
4302 mark_addressable (from);
4303 from_ptr = build_fold_addr_expr_loc (loc, from);
4304 gimplify_arg (&from_ptr, seq_p, loc);
4306 mark_addressable (to);
4307 to_ptr = build_fold_addr_expr_loc (loc, to);
4308 gimplify_arg (&to_ptr, seq_p, loc);
4310 t = builtin_decl_implicit (BUILT_IN_MEMCPY);
4312 gs = gimple_build_call (t, 3, to_ptr, from_ptr, size);
4314 if (want_value)
4316 /* tmp = memcpy() */
4317 t = create_tmp_var (TREE_TYPE (to_ptr));
4318 gimple_call_set_lhs (gs, t);
4319 gimplify_seq_add_stmt (seq_p, gs);
4321 *expr_p = build_simple_mem_ref (t);
4322 return GS_ALL_DONE;
4325 gimplify_seq_add_stmt (seq_p, gs);
4326 *expr_p = NULL;
4327 return GS_ALL_DONE;
4330 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4331 a call to __builtin_memset. In this case we know that the RHS is
4332 a CONSTRUCTOR with an empty element list. */
4334 static enum gimplify_status
4335 gimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value,
4336 gimple_seq *seq_p)
4338 tree t, from, to, to_ptr;
4339 gcall *gs;
4340 location_t loc = EXPR_LOCATION (*expr_p);
4342 /* Assert our assumptions, to abort instead of producing wrong code
4343 silently if they are not met. Beware that the RHS CONSTRUCTOR might
4344 not be immediately exposed. */
4345 from = TREE_OPERAND (*expr_p, 1);
4346 if (TREE_CODE (from) == WITH_SIZE_EXPR)
4347 from = TREE_OPERAND (from, 0);
4349 gcc_assert (TREE_CODE (from) == CONSTRUCTOR
4350 && vec_safe_is_empty (CONSTRUCTOR_ELTS (from)));
4352 /* Now proceed. */
4353 to = TREE_OPERAND (*expr_p, 0);
4355 to_ptr = build_fold_addr_expr_loc (loc, to);
4356 gimplify_arg (&to_ptr, seq_p, loc);
4357 t = builtin_decl_implicit (BUILT_IN_MEMSET);
4359 gs = gimple_build_call (t, 3, to_ptr, integer_zero_node, size);
4361 if (want_value)
4363 /* tmp = memset() */
4364 t = create_tmp_var (TREE_TYPE (to_ptr));
4365 gimple_call_set_lhs (gs, t);
4366 gimplify_seq_add_stmt (seq_p, gs);
4368 *expr_p = build1 (INDIRECT_REF, TREE_TYPE (to), t);
4369 return GS_ALL_DONE;
4372 gimplify_seq_add_stmt (seq_p, gs);
4373 *expr_p = NULL;
4374 return GS_ALL_DONE;
4377 /* A subroutine of gimplify_init_ctor_preeval. Called via walk_tree,
4378 determine, cautiously, if a CONSTRUCTOR overlaps the lhs of an
4379 assignment. Return non-null if we detect a potential overlap. */
4381 struct gimplify_init_ctor_preeval_data
4383 /* The base decl of the lhs object. May be NULL, in which case we
4384 have to assume the lhs is indirect. */
4385 tree lhs_base_decl;
4387 /* The alias set of the lhs object. */
4388 alias_set_type lhs_alias_set;
4391 static tree
4392 gimplify_init_ctor_preeval_1 (tree *tp, int *walk_subtrees, void *xdata)
4394 struct gimplify_init_ctor_preeval_data *data
4395 = (struct gimplify_init_ctor_preeval_data *) xdata;
4396 tree t = *tp;
4398 /* If we find the base object, obviously we have overlap. */
4399 if (data->lhs_base_decl == t)
4400 return t;
4402 /* If the constructor component is indirect, determine if we have a
4403 potential overlap with the lhs. The only bits of information we
4404 have to go on at this point are addressability and alias sets. */
4405 if ((INDIRECT_REF_P (t)
4406 || TREE_CODE (t) == MEM_REF)
4407 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
4408 && alias_sets_conflict_p (data->lhs_alias_set, get_alias_set (t)))
4409 return t;
4411 /* If the constructor component is a call, determine if it can hide a
4412 potential overlap with the lhs through an INDIRECT_REF like above.
4413 ??? Ugh - this is completely broken. In fact this whole analysis
4414 doesn't look conservative. */
4415 if (TREE_CODE (t) == CALL_EXPR)
4417 tree type, fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (t)));
4419 for (type = TYPE_ARG_TYPES (fntype); type; type = TREE_CHAIN (type))
4420 if (POINTER_TYPE_P (TREE_VALUE (type))
4421 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
4422 && alias_sets_conflict_p (data->lhs_alias_set,
4423 get_alias_set
4424 (TREE_TYPE (TREE_VALUE (type)))))
4425 return t;
4428 if (IS_TYPE_OR_DECL_P (t))
4429 *walk_subtrees = 0;
4430 return NULL;
4433 /* A subroutine of gimplify_init_constructor. Pre-evaluate EXPR,
4434 force values that overlap with the lhs (as described by *DATA)
4435 into temporaries. */
4437 static void
4438 gimplify_init_ctor_preeval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
4439 struct gimplify_init_ctor_preeval_data *data)
4441 enum gimplify_status one;
4443 /* If the value is constant, then there's nothing to pre-evaluate. */
4444 if (TREE_CONSTANT (*expr_p))
4446 /* Ensure it does not have side effects, it might contain a reference to
4447 the object we're initializing. */
4448 gcc_assert (!TREE_SIDE_EFFECTS (*expr_p));
4449 return;
4452 /* If the type has non-trivial constructors, we can't pre-evaluate. */
4453 if (TREE_ADDRESSABLE (TREE_TYPE (*expr_p)))
4454 return;
4456 /* Recurse for nested constructors. */
4457 if (TREE_CODE (*expr_p) == CONSTRUCTOR)
4459 unsigned HOST_WIDE_INT ix;
4460 constructor_elt *ce;
4461 vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (*expr_p);
4463 FOR_EACH_VEC_SAFE_ELT (v, ix, ce)
4464 gimplify_init_ctor_preeval (&ce->value, pre_p, post_p, data);
4466 return;
4469 /* If this is a variable sized type, we must remember the size. */
4470 maybe_with_size_expr (expr_p);
4472 /* Gimplify the constructor element to something appropriate for the rhs
4473 of a MODIFY_EXPR. Given that we know the LHS is an aggregate, we know
4474 the gimplifier will consider this a store to memory. Doing this
4475 gimplification now means that we won't have to deal with complicated
4476 language-specific trees, nor trees like SAVE_EXPR that can induce
4477 exponential search behavior. */
4478 one = gimplify_expr (expr_p, pre_p, post_p, is_gimple_mem_rhs, fb_rvalue);
4479 if (one == GS_ERROR)
4481 *expr_p = NULL;
4482 return;
4485 /* If we gimplified to a bare decl, we can be sure that it doesn't overlap
4486 with the lhs, since "a = { .x=a }" doesn't make sense. This will
4487 always be true for all scalars, since is_gimple_mem_rhs insists on a
4488 temporary variable for them. */
4489 if (DECL_P (*expr_p))
4490 return;
4492 /* If this is of variable size, we have no choice but to assume it doesn't
4493 overlap since we can't make a temporary for it. */
4494 if (TREE_CODE (TYPE_SIZE (TREE_TYPE (*expr_p))) != INTEGER_CST)
4495 return;
4497 /* Otherwise, we must search for overlap ... */
4498 if (!walk_tree (expr_p, gimplify_init_ctor_preeval_1, data, NULL))
4499 return;
4501 /* ... and if found, force the value into a temporary. */
4502 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
4505 /* A subroutine of gimplify_init_ctor_eval. Create a loop for
4506 a RANGE_EXPR in a CONSTRUCTOR for an array.
4508 var = lower;
4509 loop_entry:
4510 object[var] = value;
4511 if (var == upper)
4512 goto loop_exit;
4513 var = var + 1;
4514 goto loop_entry;
4515 loop_exit:
4517 We increment var _after_ the loop exit check because we might otherwise
4518 fail if upper == TYPE_MAX_VALUE (type for upper).
4520 Note that we never have to deal with SAVE_EXPRs here, because this has
4521 already been taken care of for us, in gimplify_init_ctor_preeval(). */
4523 static void gimplify_init_ctor_eval (tree, vec<constructor_elt, va_gc> *,
4524 gimple_seq *, bool);
4526 static void
4527 gimplify_init_ctor_eval_range (tree object, tree lower, tree upper,
4528 tree value, tree array_elt_type,
4529 gimple_seq *pre_p, bool cleared)
4531 tree loop_entry_label, loop_exit_label, fall_thru_label;
4532 tree var, var_type, cref, tmp;
4534 loop_entry_label = create_artificial_label (UNKNOWN_LOCATION);
4535 loop_exit_label = create_artificial_label (UNKNOWN_LOCATION);
4536 fall_thru_label = create_artificial_label (UNKNOWN_LOCATION);
4538 /* Create and initialize the index variable. */
4539 var_type = TREE_TYPE (upper);
4540 var = create_tmp_var (var_type);
4541 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, lower));
4543 /* Add the loop entry label. */
4544 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_entry_label));
4546 /* Build the reference. */
4547 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
4548 var, NULL_TREE, NULL_TREE);
4550 /* If we are a constructor, just call gimplify_init_ctor_eval to do
4551 the store. Otherwise just assign value to the reference. */
4553 if (TREE_CODE (value) == CONSTRUCTOR)
4554 /* NB we might have to call ourself recursively through
4555 gimplify_init_ctor_eval if the value is a constructor. */
4556 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
4557 pre_p, cleared);
4558 else
4559 gimplify_seq_add_stmt (pre_p, gimple_build_assign (cref, value));
4561 /* We exit the loop when the index var is equal to the upper bound. */
4562 gimplify_seq_add_stmt (pre_p,
4563 gimple_build_cond (EQ_EXPR, var, upper,
4564 loop_exit_label, fall_thru_label));
4566 gimplify_seq_add_stmt (pre_p, gimple_build_label (fall_thru_label));
4568 /* Otherwise, increment the index var... */
4569 tmp = build2 (PLUS_EXPR, var_type, var,
4570 fold_convert (var_type, integer_one_node));
4571 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, tmp));
4573 /* ...and jump back to the loop entry. */
4574 gimplify_seq_add_stmt (pre_p, gimple_build_goto (loop_entry_label));
4576 /* Add the loop exit label. */
4577 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_exit_label));
4580 /* Return true if FDECL is accessing a field that is zero sized. */
4582 static bool
4583 zero_sized_field_decl (const_tree fdecl)
4585 if (TREE_CODE (fdecl) == FIELD_DECL && DECL_SIZE (fdecl)
4586 && integer_zerop (DECL_SIZE (fdecl)))
4587 return true;
4588 return false;
4591 /* Return true if TYPE is zero sized. */
4593 static bool
4594 zero_sized_type (const_tree type)
4596 if (AGGREGATE_TYPE_P (type) && TYPE_SIZE (type)
4597 && integer_zerop (TYPE_SIZE (type)))
4598 return true;
4599 return false;
4602 /* A subroutine of gimplify_init_constructor. Generate individual
4603 MODIFY_EXPRs for a CONSTRUCTOR. OBJECT is the LHS against which the
4604 assignments should happen. ELTS is the CONSTRUCTOR_ELTS of the
4605 CONSTRUCTOR. CLEARED is true if the entire LHS object has been
4606 zeroed first. */
4608 static void
4609 gimplify_init_ctor_eval (tree object, vec<constructor_elt, va_gc> *elts,
4610 gimple_seq *pre_p, bool cleared)
4612 tree array_elt_type = NULL;
4613 unsigned HOST_WIDE_INT ix;
4614 tree purpose, value;
4616 if (TREE_CODE (TREE_TYPE (object)) == ARRAY_TYPE)
4617 array_elt_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (object)));
4619 FOR_EACH_CONSTRUCTOR_ELT (elts, ix, purpose, value)
4621 tree cref;
4623 /* NULL values are created above for gimplification errors. */
4624 if (value == NULL)
4625 continue;
4627 if (cleared && initializer_zerop (value))
4628 continue;
4630 /* ??? Here's to hoping the front end fills in all of the indices,
4631 so we don't have to figure out what's missing ourselves. */
4632 gcc_assert (purpose);
4634 /* Skip zero-sized fields, unless value has side-effects. This can
4635 happen with calls to functions returning a zero-sized type, which
4636 we shouldn't discard. As a number of downstream passes don't
4637 expect sets of zero-sized fields, we rely on the gimplification of
4638 the MODIFY_EXPR we make below to drop the assignment statement. */
4639 if (! TREE_SIDE_EFFECTS (value) && zero_sized_field_decl (purpose))
4640 continue;
4642 /* If we have a RANGE_EXPR, we have to build a loop to assign the
4643 whole range. */
4644 if (TREE_CODE (purpose) == RANGE_EXPR)
4646 tree lower = TREE_OPERAND (purpose, 0);
4647 tree upper = TREE_OPERAND (purpose, 1);
4649 /* If the lower bound is equal to upper, just treat it as if
4650 upper was the index. */
4651 if (simple_cst_equal (lower, upper))
4652 purpose = upper;
4653 else
4655 gimplify_init_ctor_eval_range (object, lower, upper, value,
4656 array_elt_type, pre_p, cleared);
4657 continue;
4661 if (array_elt_type)
4663 /* Do not use bitsizetype for ARRAY_REF indices. */
4664 if (TYPE_DOMAIN (TREE_TYPE (object)))
4665 purpose
4666 = fold_convert (TREE_TYPE (TYPE_DOMAIN (TREE_TYPE (object))),
4667 purpose);
4668 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
4669 purpose, NULL_TREE, NULL_TREE);
4671 else
4673 gcc_assert (TREE_CODE (purpose) == FIELD_DECL);
4674 cref = build3 (COMPONENT_REF, TREE_TYPE (purpose),
4675 unshare_expr (object), purpose, NULL_TREE);
4678 if (TREE_CODE (value) == CONSTRUCTOR
4679 && TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE)
4680 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
4681 pre_p, cleared);
4682 else
4684 tree init = build2 (INIT_EXPR, TREE_TYPE (cref), cref, value);
4685 gimplify_and_add (init, pre_p);
4686 ggc_free (init);
4691 /* Return the appropriate RHS predicate for this LHS. */
4693 gimple_predicate
4694 rhs_predicate_for (tree lhs)
4696 if (is_gimple_reg (lhs))
4697 return is_gimple_reg_rhs_or_call;
4698 else
4699 return is_gimple_mem_rhs_or_call;
4702 /* Return the initial guess for an appropriate RHS predicate for this LHS,
4703 before the LHS has been gimplified. */
4705 static gimple_predicate
4706 initial_rhs_predicate_for (tree lhs)
4708 if (is_gimple_reg_type (TREE_TYPE (lhs)))
4709 return is_gimple_reg_rhs_or_call;
4710 else
4711 return is_gimple_mem_rhs_or_call;
4714 /* Gimplify a C99 compound literal expression. This just means adding
4715 the DECL_EXPR before the current statement and using its anonymous
4716 decl instead. */
4718 static enum gimplify_status
4719 gimplify_compound_literal_expr (tree *expr_p, gimple_seq *pre_p,
4720 bool (*gimple_test_f) (tree),
4721 fallback_t fallback)
4723 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (*expr_p);
4724 tree decl = DECL_EXPR_DECL (decl_s);
4725 tree init = DECL_INITIAL (decl);
4726 /* Mark the decl as addressable if the compound literal
4727 expression is addressable now, otherwise it is marked too late
4728 after we gimplify the initialization expression. */
4729 if (TREE_ADDRESSABLE (*expr_p))
4730 TREE_ADDRESSABLE (decl) = 1;
4731 /* Otherwise, if we don't need an lvalue and have a literal directly
4732 substitute it. Check if it matches the gimple predicate, as
4733 otherwise we'd generate a new temporary, and we can as well just
4734 use the decl we already have. */
4735 else if (!TREE_ADDRESSABLE (decl)
4736 && !TREE_THIS_VOLATILE (decl)
4737 && init
4738 && (fallback & fb_lvalue) == 0
4739 && gimple_test_f (init))
4741 *expr_p = init;
4742 return GS_OK;
4745 /* Preliminarily mark non-addressed complex variables as eligible
4746 for promotion to gimple registers. We'll transform their uses
4747 as we find them. */
4748 if ((TREE_CODE (TREE_TYPE (decl)) == COMPLEX_TYPE
4749 || TREE_CODE (TREE_TYPE (decl)) == VECTOR_TYPE)
4750 && !TREE_THIS_VOLATILE (decl)
4751 && !needs_to_live_in_memory (decl))
4752 DECL_GIMPLE_REG_P (decl) = 1;
4754 /* If the decl is not addressable, then it is being used in some
4755 expression or on the right hand side of a statement, and it can
4756 be put into a readonly data section. */
4757 if (!TREE_ADDRESSABLE (decl) && (fallback & fb_lvalue) == 0)
4758 TREE_READONLY (decl) = 1;
4760 /* This decl isn't mentioned in the enclosing block, so add it to the
4761 list of temps. FIXME it seems a bit of a kludge to say that
4762 anonymous artificial vars aren't pushed, but everything else is. */
4763 if (DECL_NAME (decl) == NULL_TREE && !DECL_SEEN_IN_BIND_EXPR_P (decl))
4764 gimple_add_tmp_var (decl);
4766 gimplify_and_add (decl_s, pre_p);
4767 *expr_p = decl;
4768 return GS_OK;
4771 /* Optimize embedded COMPOUND_LITERAL_EXPRs within a CONSTRUCTOR,
4772 return a new CONSTRUCTOR if something changed. */
4774 static tree
4775 optimize_compound_literals_in_ctor (tree orig_ctor)
4777 tree ctor = orig_ctor;
4778 vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ctor);
4779 unsigned int idx, num = vec_safe_length (elts);
4781 for (idx = 0; idx < num; idx++)
4783 tree value = (*elts)[idx].value;
4784 tree newval = value;
4785 if (TREE_CODE (value) == CONSTRUCTOR)
4786 newval = optimize_compound_literals_in_ctor (value);
4787 else if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR)
4789 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (value);
4790 tree decl = DECL_EXPR_DECL (decl_s);
4791 tree init = DECL_INITIAL (decl);
4793 if (!TREE_ADDRESSABLE (value)
4794 && !TREE_ADDRESSABLE (decl)
4795 && init
4796 && TREE_CODE (init) == CONSTRUCTOR)
4797 newval = optimize_compound_literals_in_ctor (init);
4799 if (newval == value)
4800 continue;
4802 if (ctor == orig_ctor)
4804 ctor = copy_node (orig_ctor);
4805 CONSTRUCTOR_ELTS (ctor) = vec_safe_copy (elts);
4806 elts = CONSTRUCTOR_ELTS (ctor);
4808 (*elts)[idx].value = newval;
4810 return ctor;
4813 /* A subroutine of gimplify_modify_expr. Break out elements of a
4814 CONSTRUCTOR used as an initializer into separate MODIFY_EXPRs.
4816 Note that we still need to clear any elements that don't have explicit
4817 initializers, so if not all elements are initialized we keep the
4818 original MODIFY_EXPR, we just remove all of the constructor elements.
4820 If NOTIFY_TEMP_CREATION is true, do not gimplify, just return
4821 GS_ERROR if we would have to create a temporary when gimplifying
4822 this constructor. Otherwise, return GS_OK.
4824 If NOTIFY_TEMP_CREATION is false, just do the gimplification. */
4826 static enum gimplify_status
4827 gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
4828 bool want_value, bool notify_temp_creation)
4830 tree object, ctor, type;
4831 enum gimplify_status ret;
4832 vec<constructor_elt, va_gc> *elts;
4834 gcc_assert (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == CONSTRUCTOR);
4836 if (!notify_temp_creation)
4838 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
4839 is_gimple_lvalue, fb_lvalue);
4840 if (ret == GS_ERROR)
4841 return ret;
4844 object = TREE_OPERAND (*expr_p, 0);
4845 ctor = TREE_OPERAND (*expr_p, 1)
4846 = optimize_compound_literals_in_ctor (TREE_OPERAND (*expr_p, 1));
4847 type = TREE_TYPE (ctor);
4848 elts = CONSTRUCTOR_ELTS (ctor);
4849 ret = GS_ALL_DONE;
4851 switch (TREE_CODE (type))
4853 case RECORD_TYPE:
4854 case UNION_TYPE:
4855 case QUAL_UNION_TYPE:
4856 case ARRAY_TYPE:
4858 struct gimplify_init_ctor_preeval_data preeval_data;
4859 HOST_WIDE_INT num_ctor_elements, num_nonzero_elements;
4860 HOST_WIDE_INT num_unique_nonzero_elements;
4861 bool cleared, complete_p, valid_const_initializer;
4862 /* Use readonly data for initializers of this or smaller size
4863 regardless of the num_nonzero_elements / num_unique_nonzero_elements
4864 ratio. */
4865 const HOST_WIDE_INT min_unique_size = 64;
4866 /* If num_nonzero_elements / num_unique_nonzero_elements ratio
4867 is smaller than this, use readonly data. */
4868 const int unique_nonzero_ratio = 8;
4870 /* Aggregate types must lower constructors to initialization of
4871 individual elements. The exception is that a CONSTRUCTOR node
4872 with no elements indicates zero-initialization of the whole. */
4873 if (vec_safe_is_empty (elts))
4875 if (notify_temp_creation)
4876 return GS_OK;
4877 break;
4880 /* Fetch information about the constructor to direct later processing.
4881 We might want to make static versions of it in various cases, and
4882 can only do so if it known to be a valid constant initializer. */
4883 valid_const_initializer
4884 = categorize_ctor_elements (ctor, &num_nonzero_elements,
4885 &num_unique_nonzero_elements,
4886 &num_ctor_elements, &complete_p);
4888 /* If a const aggregate variable is being initialized, then it
4889 should never be a lose to promote the variable to be static. */
4890 if (valid_const_initializer
4891 && num_nonzero_elements > 1
4892 && TREE_READONLY (object)
4893 && VAR_P (object)
4894 && (flag_merge_constants >= 2 || !TREE_ADDRESSABLE (object))
4895 /* For ctors that have many repeated nonzero elements
4896 represented through RANGE_EXPRs, prefer initializing
4897 those through runtime loops over copies of large amounts
4898 of data from readonly data section. */
4899 && (num_unique_nonzero_elements
4900 > num_nonzero_elements / unique_nonzero_ratio
4901 || ((unsigned HOST_WIDE_INT) int_size_in_bytes (type)
4902 <= (unsigned HOST_WIDE_INT) min_unique_size)))
4904 if (notify_temp_creation)
4905 return GS_ERROR;
4906 DECL_INITIAL (object) = ctor;
4907 TREE_STATIC (object) = 1;
4908 if (!DECL_NAME (object))
4909 DECL_NAME (object) = create_tmp_var_name ("C");
4910 walk_tree (&DECL_INITIAL (object), force_labels_r, NULL, NULL);
4912 /* ??? C++ doesn't automatically append a .<number> to the
4913 assembler name, and even when it does, it looks at FE private
4914 data structures to figure out what that number should be,
4915 which are not set for this variable. I suppose this is
4916 important for local statics for inline functions, which aren't
4917 "local" in the object file sense. So in order to get a unique
4918 TU-local symbol, we must invoke the lhd version now. */
4919 lhd_set_decl_assembler_name (object);
4921 *expr_p = NULL_TREE;
4922 break;
4925 /* If there are "lots" of initialized elements, even discounting
4926 those that are not address constants (and thus *must* be
4927 computed at runtime), then partition the constructor into
4928 constant and non-constant parts. Block copy the constant
4929 parts in, then generate code for the non-constant parts. */
4930 /* TODO. There's code in cp/typeck.c to do this. */
4932 if (int_size_in_bytes (TREE_TYPE (ctor)) < 0)
4933 /* store_constructor will ignore the clearing of variable-sized
4934 objects. Initializers for such objects must explicitly set
4935 every field that needs to be set. */
4936 cleared = false;
4937 else if (!complete_p)
4938 /* If the constructor isn't complete, clear the whole object
4939 beforehand, unless CONSTRUCTOR_NO_CLEARING is set on it.
4941 ??? This ought not to be needed. For any element not present
4942 in the initializer, we should simply set them to zero. Except
4943 we'd need to *find* the elements that are not present, and that
4944 requires trickery to avoid quadratic compile-time behavior in
4945 large cases or excessive memory use in small cases. */
4946 cleared = !CONSTRUCTOR_NO_CLEARING (ctor);
4947 else if (num_ctor_elements - num_nonzero_elements
4948 > CLEAR_RATIO (optimize_function_for_speed_p (cfun))
4949 && num_nonzero_elements < num_ctor_elements / 4)
4950 /* If there are "lots" of zeros, it's more efficient to clear
4951 the memory and then set the nonzero elements. */
4952 cleared = true;
4953 else
4954 cleared = false;
4956 /* If there are "lots" of initialized elements, and all of them
4957 are valid address constants, then the entire initializer can
4958 be dropped to memory, and then memcpy'd out. Don't do this
4959 for sparse arrays, though, as it's more efficient to follow
4960 the standard CONSTRUCTOR behavior of memset followed by
4961 individual element initialization. Also don't do this for small
4962 all-zero initializers (which aren't big enough to merit
4963 clearing), and don't try to make bitwise copies of
4964 TREE_ADDRESSABLE types. */
4966 if (valid_const_initializer
4967 && !(cleared || num_nonzero_elements == 0)
4968 && !TREE_ADDRESSABLE (type))
4970 HOST_WIDE_INT size = int_size_in_bytes (type);
4971 unsigned int align;
4973 /* ??? We can still get unbounded array types, at least
4974 from the C++ front end. This seems wrong, but attempt
4975 to work around it for now. */
4976 if (size < 0)
4978 size = int_size_in_bytes (TREE_TYPE (object));
4979 if (size >= 0)
4980 TREE_TYPE (ctor) = type = TREE_TYPE (object);
4983 /* Find the maximum alignment we can assume for the object. */
4984 /* ??? Make use of DECL_OFFSET_ALIGN. */
4985 if (DECL_P (object))
4986 align = DECL_ALIGN (object);
4987 else
4988 align = TYPE_ALIGN (type);
4990 /* Do a block move either if the size is so small as to make
4991 each individual move a sub-unit move on average, or if it
4992 is so large as to make individual moves inefficient. */
4993 if (size > 0
4994 && num_nonzero_elements > 1
4995 /* For ctors that have many repeated nonzero elements
4996 represented through RANGE_EXPRs, prefer initializing
4997 those through runtime loops over copies of large amounts
4998 of data from readonly data section. */
4999 && (num_unique_nonzero_elements
5000 > num_nonzero_elements / unique_nonzero_ratio
5001 || size <= min_unique_size)
5002 && (size < num_nonzero_elements
5003 || !can_move_by_pieces (size, align)))
5005 if (notify_temp_creation)
5006 return GS_ERROR;
5008 walk_tree (&ctor, force_labels_r, NULL, NULL);
5009 ctor = tree_output_constant_def (ctor);
5010 if (!useless_type_conversion_p (type, TREE_TYPE (ctor)))
5011 ctor = build1 (VIEW_CONVERT_EXPR, type, ctor);
5012 TREE_OPERAND (*expr_p, 1) = ctor;
5014 /* This is no longer an assignment of a CONSTRUCTOR, but
5015 we still may have processing to do on the LHS. So
5016 pretend we didn't do anything here to let that happen. */
5017 return GS_UNHANDLED;
5021 /* If the target is volatile, we have non-zero elements and more than
5022 one field to assign, initialize the target from a temporary. */
5023 if (TREE_THIS_VOLATILE (object)
5024 && !TREE_ADDRESSABLE (type)
5025 && (num_nonzero_elements > 0 || !cleared)
5026 && vec_safe_length (elts) > 1)
5028 tree temp = create_tmp_var (TYPE_MAIN_VARIANT (type));
5029 TREE_OPERAND (*expr_p, 0) = temp;
5030 *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p),
5031 *expr_p,
5032 build2 (MODIFY_EXPR, void_type_node,
5033 object, temp));
5034 return GS_OK;
5037 if (notify_temp_creation)
5038 return GS_OK;
5040 /* If there are nonzero elements and if needed, pre-evaluate to capture
5041 elements overlapping with the lhs into temporaries. We must do this
5042 before clearing to fetch the values before they are zeroed-out. */
5043 if (num_nonzero_elements > 0 && TREE_CODE (*expr_p) != INIT_EXPR)
5045 preeval_data.lhs_base_decl = get_base_address (object);
5046 if (!DECL_P (preeval_data.lhs_base_decl))
5047 preeval_data.lhs_base_decl = NULL;
5048 preeval_data.lhs_alias_set = get_alias_set (object);
5050 gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p, 1),
5051 pre_p, post_p, &preeval_data);
5054 bool ctor_has_side_effects_p
5055 = TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p, 1));
5057 if (cleared)
5059 /* Zap the CONSTRUCTOR element list, which simplifies this case.
5060 Note that we still have to gimplify, in order to handle the
5061 case of variable sized types. Avoid shared tree structures. */
5062 CONSTRUCTOR_ELTS (ctor) = NULL;
5063 TREE_SIDE_EFFECTS (ctor) = 0;
5064 object = unshare_expr (object);
5065 gimplify_stmt (expr_p, pre_p);
5068 /* If we have not block cleared the object, or if there are nonzero
5069 elements in the constructor, or if the constructor has side effects,
5070 add assignments to the individual scalar fields of the object. */
5071 if (!cleared
5072 || num_nonzero_elements > 0
5073 || ctor_has_side_effects_p)
5074 gimplify_init_ctor_eval (object, elts, pre_p, cleared);
5076 *expr_p = NULL_TREE;
5078 break;
5080 case COMPLEX_TYPE:
5082 tree r, i;
5084 if (notify_temp_creation)
5085 return GS_OK;
5087 /* Extract the real and imaginary parts out of the ctor. */
5088 gcc_assert (elts->length () == 2);
5089 r = (*elts)[0].value;
5090 i = (*elts)[1].value;
5091 if (r == NULL || i == NULL)
5093 tree zero = build_zero_cst (TREE_TYPE (type));
5094 if (r == NULL)
5095 r = zero;
5096 if (i == NULL)
5097 i = zero;
5100 /* Complex types have either COMPLEX_CST or COMPLEX_EXPR to
5101 represent creation of a complex value. */
5102 if (TREE_CONSTANT (r) && TREE_CONSTANT (i))
5104 ctor = build_complex (type, r, i);
5105 TREE_OPERAND (*expr_p, 1) = ctor;
5107 else
5109 ctor = build2 (COMPLEX_EXPR, type, r, i);
5110 TREE_OPERAND (*expr_p, 1) = ctor;
5111 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 1),
5112 pre_p,
5113 post_p,
5114 rhs_predicate_for (TREE_OPERAND (*expr_p, 0)),
5115 fb_rvalue);
5118 break;
5120 case VECTOR_TYPE:
5122 unsigned HOST_WIDE_INT ix;
5123 constructor_elt *ce;
5125 if (notify_temp_creation)
5126 return GS_OK;
5128 /* Go ahead and simplify constant constructors to VECTOR_CST. */
5129 if (TREE_CONSTANT (ctor))
5131 bool constant_p = true;
5132 tree value;
5134 /* Even when ctor is constant, it might contain non-*_CST
5135 elements, such as addresses or trapping values like
5136 1.0/0.0 - 1.0/0.0. Such expressions don't belong
5137 in VECTOR_CST nodes. */
5138 FOR_EACH_CONSTRUCTOR_VALUE (elts, ix, value)
5139 if (!CONSTANT_CLASS_P (value))
5141 constant_p = false;
5142 break;
5145 if (constant_p)
5147 TREE_OPERAND (*expr_p, 1) = build_vector_from_ctor (type, elts);
5148 break;
5151 TREE_CONSTANT (ctor) = 0;
5154 /* Vector types use CONSTRUCTOR all the way through gimple
5155 compilation as a general initializer. */
5156 FOR_EACH_VEC_SAFE_ELT (elts, ix, ce)
5158 enum gimplify_status tret;
5159 tret = gimplify_expr (&ce->value, pre_p, post_p, is_gimple_val,
5160 fb_rvalue);
5161 if (tret == GS_ERROR)
5162 ret = GS_ERROR;
5163 else if (TREE_STATIC (ctor)
5164 && !initializer_constant_valid_p (ce->value,
5165 TREE_TYPE (ce->value)))
5166 TREE_STATIC (ctor) = 0;
5168 if (!is_gimple_reg (TREE_OPERAND (*expr_p, 0)))
5169 TREE_OPERAND (*expr_p, 1) = get_formal_tmp_var (ctor, pre_p);
5171 break;
5173 default:
5174 /* So how did we get a CONSTRUCTOR for a scalar type? */
5175 gcc_unreachable ();
5178 if (ret == GS_ERROR)
5179 return GS_ERROR;
5180 /* If we have gimplified both sides of the initializer but have
5181 not emitted an assignment, do so now. */
5182 if (*expr_p)
5184 tree lhs = TREE_OPERAND (*expr_p, 0);
5185 tree rhs = TREE_OPERAND (*expr_p, 1);
5186 if (want_value && object == lhs)
5187 lhs = unshare_expr (lhs);
5188 gassign *init = gimple_build_assign (lhs, rhs);
5189 gimplify_seq_add_stmt (pre_p, init);
5191 if (want_value)
5193 *expr_p = object;
5194 return GS_OK;
5196 else
5198 *expr_p = NULL;
5199 return GS_ALL_DONE;
5203 /* Given a pointer value OP0, return a simplified version of an
5204 indirection through OP0, or NULL_TREE if no simplification is
5205 possible. This may only be applied to a rhs of an expression.
5206 Note that the resulting type may be different from the type pointed
5207 to in the sense that it is still compatible from the langhooks
5208 point of view. */
5210 static tree
5211 gimple_fold_indirect_ref_rhs (tree t)
5213 return gimple_fold_indirect_ref (t);
5216 /* Subroutine of gimplify_modify_expr to do simplifications of
5217 MODIFY_EXPRs based on the code of the RHS. We loop for as long as
5218 something changes. */
5220 static enum gimplify_status
5221 gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p,
5222 gimple_seq *pre_p, gimple_seq *post_p,
5223 bool want_value)
5225 enum gimplify_status ret = GS_UNHANDLED;
5226 bool changed;
5230 changed = false;
5231 switch (TREE_CODE (*from_p))
5233 case VAR_DECL:
5234 /* If we're assigning from a read-only variable initialized with
5235 a constructor, do the direct assignment from the constructor,
5236 but only if neither source nor target are volatile since this
5237 latter assignment might end up being done on a per-field basis. */
5238 if (DECL_INITIAL (*from_p)
5239 && TREE_READONLY (*from_p)
5240 && !TREE_THIS_VOLATILE (*from_p)
5241 && !TREE_THIS_VOLATILE (*to_p)
5242 && TREE_CODE (DECL_INITIAL (*from_p)) == CONSTRUCTOR)
5244 tree old_from = *from_p;
5245 enum gimplify_status subret;
5247 /* Move the constructor into the RHS. */
5248 *from_p = unshare_expr (DECL_INITIAL (*from_p));
5250 /* Let's see if gimplify_init_constructor will need to put
5251 it in memory. */
5252 subret = gimplify_init_constructor (expr_p, NULL, NULL,
5253 false, true);
5254 if (subret == GS_ERROR)
5256 /* If so, revert the change. */
5257 *from_p = old_from;
5259 else
5261 ret = GS_OK;
5262 changed = true;
5265 break;
5266 case INDIRECT_REF:
5268 /* If we have code like
5270 *(const A*)(A*)&x
5272 where the type of "x" is a (possibly cv-qualified variant
5273 of "A"), treat the entire expression as identical to "x".
5274 This kind of code arises in C++ when an object is bound
5275 to a const reference, and if "x" is a TARGET_EXPR we want
5276 to take advantage of the optimization below. */
5277 bool volatile_p = TREE_THIS_VOLATILE (*from_p);
5278 tree t = gimple_fold_indirect_ref_rhs (TREE_OPERAND (*from_p, 0));
5279 if (t)
5281 if (TREE_THIS_VOLATILE (t) != volatile_p)
5283 if (DECL_P (t))
5284 t = build_simple_mem_ref_loc (EXPR_LOCATION (*from_p),
5285 build_fold_addr_expr (t));
5286 if (REFERENCE_CLASS_P (t))
5287 TREE_THIS_VOLATILE (t) = volatile_p;
5289 *from_p = t;
5290 ret = GS_OK;
5291 changed = true;
5293 break;
5296 case TARGET_EXPR:
5298 /* If we are initializing something from a TARGET_EXPR, strip the
5299 TARGET_EXPR and initialize it directly, if possible. This can't
5300 be done if the initializer is void, since that implies that the
5301 temporary is set in some non-trivial way.
5303 ??? What about code that pulls out the temp and uses it
5304 elsewhere? I think that such code never uses the TARGET_EXPR as
5305 an initializer. If I'm wrong, we'll die because the temp won't
5306 have any RTL. In that case, I guess we'll need to replace
5307 references somehow. */
5308 tree init = TARGET_EXPR_INITIAL (*from_p);
5310 if (init
5311 && (TREE_CODE (*expr_p) != MODIFY_EXPR
5312 || !TARGET_EXPR_NO_ELIDE (*from_p))
5313 && !VOID_TYPE_P (TREE_TYPE (init)))
5315 *from_p = init;
5316 ret = GS_OK;
5317 changed = true;
5320 break;
5322 case COMPOUND_EXPR:
5323 /* Remove any COMPOUND_EXPR in the RHS so the following cases will be
5324 caught. */
5325 gimplify_compound_expr (from_p, pre_p, true);
5326 ret = GS_OK;
5327 changed = true;
5328 break;
5330 case CONSTRUCTOR:
5331 /* If we already made some changes, let the front end have a
5332 crack at this before we break it down. */
5333 if (ret != GS_UNHANDLED)
5334 break;
5335 /* If we're initializing from a CONSTRUCTOR, break this into
5336 individual MODIFY_EXPRs. */
5337 return gimplify_init_constructor (expr_p, pre_p, post_p, want_value,
5338 false);
5340 case COND_EXPR:
5341 /* If we're assigning to a non-register type, push the assignment
5342 down into the branches. This is mandatory for ADDRESSABLE types,
5343 since we cannot generate temporaries for such, but it saves a
5344 copy in other cases as well. */
5345 if (!is_gimple_reg_type (TREE_TYPE (*from_p)))
5347 /* This code should mirror the code in gimplify_cond_expr. */
5348 enum tree_code code = TREE_CODE (*expr_p);
5349 tree cond = *from_p;
5350 tree result = *to_p;
5352 ret = gimplify_expr (&result, pre_p, post_p,
5353 is_gimple_lvalue, fb_lvalue);
5354 if (ret != GS_ERROR)
5355 ret = GS_OK;
5357 /* If we are going to write RESULT more than once, clear
5358 TREE_READONLY flag, otherwise we might incorrectly promote
5359 the variable to static const and initialize it at compile
5360 time in one of the branches. */
5361 if (VAR_P (result)
5362 && TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node
5363 && TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
5364 TREE_READONLY (result) = 0;
5365 if (TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node)
5366 TREE_OPERAND (cond, 1)
5367 = build2 (code, void_type_node, result,
5368 TREE_OPERAND (cond, 1));
5369 if (TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
5370 TREE_OPERAND (cond, 2)
5371 = build2 (code, void_type_node, unshare_expr (result),
5372 TREE_OPERAND (cond, 2));
5374 TREE_TYPE (cond) = void_type_node;
5375 recalculate_side_effects (cond);
5377 if (want_value)
5379 gimplify_and_add (cond, pre_p);
5380 *expr_p = unshare_expr (result);
5382 else
5383 *expr_p = cond;
5384 return ret;
5386 break;
5388 case CALL_EXPR:
5389 /* For calls that return in memory, give *to_p as the CALL_EXPR's
5390 return slot so that we don't generate a temporary. */
5391 if (!CALL_EXPR_RETURN_SLOT_OPT (*from_p)
5392 && aggregate_value_p (*from_p, *from_p))
5394 bool use_target;
5396 if (!(rhs_predicate_for (*to_p))(*from_p))
5397 /* If we need a temporary, *to_p isn't accurate. */
5398 use_target = false;
5399 /* It's OK to use the return slot directly unless it's an NRV. */
5400 else if (TREE_CODE (*to_p) == RESULT_DECL
5401 && DECL_NAME (*to_p) == NULL_TREE
5402 && needs_to_live_in_memory (*to_p))
5403 use_target = true;
5404 else if (is_gimple_reg_type (TREE_TYPE (*to_p))
5405 || (DECL_P (*to_p) && DECL_REGISTER (*to_p)))
5406 /* Don't force regs into memory. */
5407 use_target = false;
5408 else if (TREE_CODE (*expr_p) == INIT_EXPR)
5409 /* It's OK to use the target directly if it's being
5410 initialized. */
5411 use_target = true;
5412 else if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p)))
5413 != INTEGER_CST)
5414 /* Always use the target and thus RSO for variable-sized types.
5415 GIMPLE cannot deal with a variable-sized assignment
5416 embedded in a call statement. */
5417 use_target = true;
5418 else if (TREE_CODE (*to_p) != SSA_NAME
5419 && (!is_gimple_variable (*to_p)
5420 || needs_to_live_in_memory (*to_p)))
5421 /* Don't use the original target if it's already addressable;
5422 if its address escapes, and the called function uses the
5423 NRV optimization, a conforming program could see *to_p
5424 change before the called function returns; see c++/19317.
5425 When optimizing, the return_slot pass marks more functions
5426 as safe after we have escape info. */
5427 use_target = false;
5428 else
5429 use_target = true;
5431 if (use_target)
5433 CALL_EXPR_RETURN_SLOT_OPT (*from_p) = 1;
5434 mark_addressable (*to_p);
5437 break;
5439 case WITH_SIZE_EXPR:
5440 /* Likewise for calls that return an aggregate of non-constant size,
5441 since we would not be able to generate a temporary at all. */
5442 if (TREE_CODE (TREE_OPERAND (*from_p, 0)) == CALL_EXPR)
5444 *from_p = TREE_OPERAND (*from_p, 0);
5445 /* We don't change ret in this case because the
5446 WITH_SIZE_EXPR might have been added in
5447 gimplify_modify_expr, so returning GS_OK would lead to an
5448 infinite loop. */
5449 changed = true;
5451 break;
5453 /* If we're initializing from a container, push the initialization
5454 inside it. */
5455 case CLEANUP_POINT_EXPR:
5456 case BIND_EXPR:
5457 case STATEMENT_LIST:
5459 tree wrap = *from_p;
5460 tree t;
5462 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_min_lval,
5463 fb_lvalue);
5464 if (ret != GS_ERROR)
5465 ret = GS_OK;
5467 t = voidify_wrapper_expr (wrap, *expr_p);
5468 gcc_assert (t == *expr_p);
5470 if (want_value)
5472 gimplify_and_add (wrap, pre_p);
5473 *expr_p = unshare_expr (*to_p);
5475 else
5476 *expr_p = wrap;
5477 return GS_OK;
5480 case COMPOUND_LITERAL_EXPR:
5482 tree complit = TREE_OPERAND (*expr_p, 1);
5483 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (complit);
5484 tree decl = DECL_EXPR_DECL (decl_s);
5485 tree init = DECL_INITIAL (decl);
5487 /* struct T x = (struct T) { 0, 1, 2 } can be optimized
5488 into struct T x = { 0, 1, 2 } if the address of the
5489 compound literal has never been taken. */
5490 if (!TREE_ADDRESSABLE (complit)
5491 && !TREE_ADDRESSABLE (decl)
5492 && init)
5494 *expr_p = copy_node (*expr_p);
5495 TREE_OPERAND (*expr_p, 1) = init;
5496 return GS_OK;
5500 default:
5501 break;
5504 while (changed);
5506 return ret;
5510 /* Return true if T looks like a valid GIMPLE statement. */
5512 static bool
5513 is_gimple_stmt (tree t)
5515 const enum tree_code code = TREE_CODE (t);
5517 switch (code)
5519 case NOP_EXPR:
5520 /* The only valid NOP_EXPR is the empty statement. */
5521 return IS_EMPTY_STMT (t);
5523 case BIND_EXPR:
5524 case COND_EXPR:
5525 /* These are only valid if they're void. */
5526 return TREE_TYPE (t) == NULL || VOID_TYPE_P (TREE_TYPE (t));
5528 case SWITCH_EXPR:
5529 case GOTO_EXPR:
5530 case RETURN_EXPR:
5531 case LABEL_EXPR:
5532 case CASE_LABEL_EXPR:
5533 case TRY_CATCH_EXPR:
5534 case TRY_FINALLY_EXPR:
5535 case EH_FILTER_EXPR:
5536 case CATCH_EXPR:
5537 case ASM_EXPR:
5538 case STATEMENT_LIST:
5539 case OACC_PARALLEL:
5540 case OACC_KERNELS:
5541 case OACC_DATA:
5542 case OACC_HOST_DATA:
5543 case OACC_DECLARE:
5544 case OACC_UPDATE:
5545 case OACC_ENTER_DATA:
5546 case OACC_EXIT_DATA:
5547 case OACC_CACHE:
5548 case OMP_PARALLEL:
5549 case OMP_FOR:
5550 case OMP_SIMD:
5551 case OMP_DISTRIBUTE:
5552 case OMP_LOOP:
5553 case OACC_LOOP:
5554 case OMP_SCAN:
5555 case OMP_SECTIONS:
5556 case OMP_SECTION:
5557 case OMP_SINGLE:
5558 case OMP_MASTER:
5559 case OMP_TASKGROUP:
5560 case OMP_ORDERED:
5561 case OMP_CRITICAL:
5562 case OMP_TASK:
5563 case OMP_TARGET:
5564 case OMP_TARGET_DATA:
5565 case OMP_TARGET_UPDATE:
5566 case OMP_TARGET_ENTER_DATA:
5567 case OMP_TARGET_EXIT_DATA:
5568 case OMP_TASKLOOP:
5569 case OMP_TEAMS:
5570 /* These are always void. */
5571 return true;
5573 case CALL_EXPR:
5574 case MODIFY_EXPR:
5575 case PREDICT_EXPR:
5576 /* These are valid regardless of their type. */
5577 return true;
5579 default:
5580 return false;
5585 /* Promote partial stores to COMPLEX variables to total stores. *EXPR_P is
5586 a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a variable with
5587 DECL_GIMPLE_REG_P set.
5589 IMPORTANT NOTE: This promotion is performed by introducing a load of the
5590 other, unmodified part of the complex object just before the total store.
5591 As a consequence, if the object is still uninitialized, an undefined value
5592 will be loaded into a register, which may result in a spurious exception
5593 if the register is floating-point and the value happens to be a signaling
5594 NaN for example. Then the fully-fledged complex operations lowering pass
5595 followed by a DCE pass are necessary in order to fix things up. */
5597 static enum gimplify_status
5598 gimplify_modify_expr_complex_part (tree *expr_p, gimple_seq *pre_p,
5599 bool want_value)
5601 enum tree_code code, ocode;
5602 tree lhs, rhs, new_rhs, other, realpart, imagpart;
5604 lhs = TREE_OPERAND (*expr_p, 0);
5605 rhs = TREE_OPERAND (*expr_p, 1);
5606 code = TREE_CODE (lhs);
5607 lhs = TREE_OPERAND (lhs, 0);
5609 ocode = code == REALPART_EXPR ? IMAGPART_EXPR : REALPART_EXPR;
5610 other = build1 (ocode, TREE_TYPE (rhs), lhs);
5611 TREE_NO_WARNING (other) = 1;
5612 other = get_formal_tmp_var (other, pre_p);
5614 realpart = code == REALPART_EXPR ? rhs : other;
5615 imagpart = code == REALPART_EXPR ? other : rhs;
5617 if (TREE_CONSTANT (realpart) && TREE_CONSTANT (imagpart))
5618 new_rhs = build_complex (TREE_TYPE (lhs), realpart, imagpart);
5619 else
5620 new_rhs = build2 (COMPLEX_EXPR, TREE_TYPE (lhs), realpart, imagpart);
5622 gimplify_seq_add_stmt (pre_p, gimple_build_assign (lhs, new_rhs));
5623 *expr_p = (want_value) ? rhs : NULL_TREE;
5625 return GS_ALL_DONE;
5628 /* Gimplify the MODIFY_EXPR node pointed to by EXPR_P.
5630 modify_expr
5631 : varname '=' rhs
5632 | '*' ID '=' rhs
5634 PRE_P points to the list where side effects that must happen before
5635 *EXPR_P should be stored.
5637 POST_P points to the list where side effects that must happen after
5638 *EXPR_P should be stored.
5640 WANT_VALUE is nonzero iff we want to use the value of this expression
5641 in another expression. */
5643 static enum gimplify_status
5644 gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
5645 bool want_value)
5647 tree *from_p = &TREE_OPERAND (*expr_p, 1);
5648 tree *to_p = &TREE_OPERAND (*expr_p, 0);
5649 enum gimplify_status ret = GS_UNHANDLED;
5650 gimple *assign;
5651 location_t loc = EXPR_LOCATION (*expr_p);
5652 gimple_stmt_iterator gsi;
5654 gcc_assert (TREE_CODE (*expr_p) == MODIFY_EXPR
5655 || TREE_CODE (*expr_p) == INIT_EXPR);
5657 /* Trying to simplify a clobber using normal logic doesn't work,
5658 so handle it here. */
5659 if (TREE_CLOBBER_P (*from_p))
5661 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
5662 if (ret == GS_ERROR)
5663 return ret;
5664 gcc_assert (!want_value);
5665 if (!VAR_P (*to_p) && TREE_CODE (*to_p) != MEM_REF)
5667 tree addr = get_initialized_tmp_var (build_fold_addr_expr (*to_p),
5668 pre_p, post_p);
5669 *to_p = build_simple_mem_ref_loc (EXPR_LOCATION (*to_p), addr);
5671 gimplify_seq_add_stmt (pre_p, gimple_build_assign (*to_p, *from_p));
5672 *expr_p = NULL;
5673 return GS_ALL_DONE;
5676 /* Insert pointer conversions required by the middle-end that are not
5677 required by the frontend. This fixes middle-end type checking for
5678 for example gcc.dg/redecl-6.c. */
5679 if (POINTER_TYPE_P (TREE_TYPE (*to_p)))
5681 STRIP_USELESS_TYPE_CONVERSION (*from_p);
5682 if (!useless_type_conversion_p (TREE_TYPE (*to_p), TREE_TYPE (*from_p)))
5683 *from_p = fold_convert_loc (loc, TREE_TYPE (*to_p), *from_p);
5686 /* See if any simplifications can be done based on what the RHS is. */
5687 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
5688 want_value);
5689 if (ret != GS_UNHANDLED)
5690 return ret;
5692 /* For zero sized types only gimplify the left hand side and right hand
5693 side as statements and throw away the assignment. Do this after
5694 gimplify_modify_expr_rhs so we handle TARGET_EXPRs of addressable
5695 types properly. */
5696 if (zero_sized_type (TREE_TYPE (*from_p))
5697 && !want_value
5698 /* Don't do this for calls that return addressable types, expand_call
5699 relies on those having a lhs. */
5700 && !(TREE_ADDRESSABLE (TREE_TYPE (*from_p))
5701 && TREE_CODE (*from_p) == CALL_EXPR))
5703 gimplify_stmt (from_p, pre_p);
5704 gimplify_stmt (to_p, pre_p);
5705 *expr_p = NULL_TREE;
5706 return GS_ALL_DONE;
5709 /* If the value being copied is of variable width, compute the length
5710 of the copy into a WITH_SIZE_EXPR. Note that we need to do this
5711 before gimplifying any of the operands so that we can resolve any
5712 PLACEHOLDER_EXPRs in the size. Also note that the RTL expander uses
5713 the size of the expression to be copied, not of the destination, so
5714 that is what we must do here. */
5715 maybe_with_size_expr (from_p);
5717 /* As a special case, we have to temporarily allow for assignments
5718 with a CALL_EXPR on the RHS. Since in GIMPLE a function call is
5719 a toplevel statement, when gimplifying the GENERIC expression
5720 MODIFY_EXPR <a, CALL_EXPR <foo>>, we cannot create the tuple
5721 GIMPLE_ASSIGN <a, GIMPLE_CALL <foo>>.
5723 Instead, we need to create the tuple GIMPLE_CALL <a, foo>. To
5724 prevent gimplify_expr from trying to create a new temporary for
5725 foo's LHS, we tell it that it should only gimplify until it
5726 reaches the CALL_EXPR. On return from gimplify_expr, the newly
5727 created GIMPLE_CALL <foo> will be the last statement in *PRE_P
5728 and all we need to do here is set 'a' to be its LHS. */
5730 /* Gimplify the RHS first for C++17 and bug 71104. */
5731 gimple_predicate initial_pred = initial_rhs_predicate_for (*to_p);
5732 ret = gimplify_expr (from_p, pre_p, post_p, initial_pred, fb_rvalue);
5733 if (ret == GS_ERROR)
5734 return ret;
5736 /* Then gimplify the LHS. */
5737 /* If we gimplified the RHS to a CALL_EXPR and that call may return
5738 twice we have to make sure to gimplify into non-SSA as otherwise
5739 the abnormal edge added later will make those defs not dominate
5740 their uses.
5741 ??? Technically this applies only to the registers used in the
5742 resulting non-register *TO_P. */
5743 bool saved_into_ssa = gimplify_ctxp->into_ssa;
5744 if (saved_into_ssa
5745 && TREE_CODE (*from_p) == CALL_EXPR
5746 && call_expr_flags (*from_p) & ECF_RETURNS_TWICE)
5747 gimplify_ctxp->into_ssa = false;
5748 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
5749 gimplify_ctxp->into_ssa = saved_into_ssa;
5750 if (ret == GS_ERROR)
5751 return ret;
5753 /* Now that the LHS is gimplified, re-gimplify the RHS if our initial
5754 guess for the predicate was wrong. */
5755 gimple_predicate final_pred = rhs_predicate_for (*to_p);
5756 if (final_pred != initial_pred)
5758 ret = gimplify_expr (from_p, pre_p, post_p, final_pred, fb_rvalue);
5759 if (ret == GS_ERROR)
5760 return ret;
5763 /* In case of va_arg internal fn wrappped in a WITH_SIZE_EXPR, add the type
5764 size as argument to the call. */
5765 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
5767 tree call = TREE_OPERAND (*from_p, 0);
5768 tree vlasize = TREE_OPERAND (*from_p, 1);
5770 if (TREE_CODE (call) == CALL_EXPR
5771 && CALL_EXPR_IFN (call) == IFN_VA_ARG)
5773 int nargs = call_expr_nargs (call);
5774 tree type = TREE_TYPE (call);
5775 tree ap = CALL_EXPR_ARG (call, 0);
5776 tree tag = CALL_EXPR_ARG (call, 1);
5777 tree aptag = CALL_EXPR_ARG (call, 2);
5778 tree newcall = build_call_expr_internal_loc (EXPR_LOCATION (call),
5779 IFN_VA_ARG, type,
5780 nargs + 1, ap, tag,
5781 aptag, vlasize);
5782 TREE_OPERAND (*from_p, 0) = newcall;
5786 /* Now see if the above changed *from_p to something we handle specially. */
5787 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
5788 want_value);
5789 if (ret != GS_UNHANDLED)
5790 return ret;
5792 /* If we've got a variable sized assignment between two lvalues (i.e. does
5793 not involve a call), then we can make things a bit more straightforward
5794 by converting the assignment to memcpy or memset. */
5795 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
5797 tree from = TREE_OPERAND (*from_p, 0);
5798 tree size = TREE_OPERAND (*from_p, 1);
5800 if (TREE_CODE (from) == CONSTRUCTOR)
5801 return gimplify_modify_expr_to_memset (expr_p, size, want_value, pre_p);
5803 if (is_gimple_addressable (from))
5805 *from_p = from;
5806 return gimplify_modify_expr_to_memcpy (expr_p, size, want_value,
5807 pre_p);
5811 /* Transform partial stores to non-addressable complex variables into
5812 total stores. This allows us to use real instead of virtual operands
5813 for these variables, which improves optimization. */
5814 if ((TREE_CODE (*to_p) == REALPART_EXPR
5815 || TREE_CODE (*to_p) == IMAGPART_EXPR)
5816 && is_gimple_reg (TREE_OPERAND (*to_p, 0)))
5817 return gimplify_modify_expr_complex_part (expr_p, pre_p, want_value);
5819 /* Try to alleviate the effects of the gimplification creating artificial
5820 temporaries (see for example is_gimple_reg_rhs) on the debug info, but
5821 make sure not to create DECL_DEBUG_EXPR links across functions. */
5822 if (!gimplify_ctxp->into_ssa
5823 && VAR_P (*from_p)
5824 && DECL_IGNORED_P (*from_p)
5825 && DECL_P (*to_p)
5826 && !DECL_IGNORED_P (*to_p)
5827 && decl_function_context (*to_p) == current_function_decl
5828 && decl_function_context (*from_p) == current_function_decl)
5830 if (!DECL_NAME (*from_p) && DECL_NAME (*to_p))
5831 DECL_NAME (*from_p)
5832 = create_tmp_var_name (IDENTIFIER_POINTER (DECL_NAME (*to_p)));
5833 DECL_HAS_DEBUG_EXPR_P (*from_p) = 1;
5834 SET_DECL_DEBUG_EXPR (*from_p, *to_p);
5837 if (want_value && TREE_THIS_VOLATILE (*to_p))
5838 *from_p = get_initialized_tmp_var (*from_p, pre_p, post_p);
5840 if (TREE_CODE (*from_p) == CALL_EXPR)
5842 /* Since the RHS is a CALL_EXPR, we need to create a GIMPLE_CALL
5843 instead of a GIMPLE_ASSIGN. */
5844 gcall *call_stmt;
5845 if (CALL_EXPR_FN (*from_p) == NULL_TREE)
5847 /* Gimplify internal functions created in the FEs. */
5848 int nargs = call_expr_nargs (*from_p), i;
5849 enum internal_fn ifn = CALL_EXPR_IFN (*from_p);
5850 auto_vec<tree> vargs (nargs);
5852 for (i = 0; i < nargs; i++)
5854 gimplify_arg (&CALL_EXPR_ARG (*from_p, i), pre_p,
5855 EXPR_LOCATION (*from_p));
5856 vargs.quick_push (CALL_EXPR_ARG (*from_p, i));
5858 call_stmt = gimple_build_call_internal_vec (ifn, vargs);
5859 gimple_call_set_nothrow (call_stmt, TREE_NOTHROW (*from_p));
5860 gimple_set_location (call_stmt, EXPR_LOCATION (*expr_p));
5862 else
5864 tree fnptrtype = TREE_TYPE (CALL_EXPR_FN (*from_p));
5865 CALL_EXPR_FN (*from_p) = TREE_OPERAND (CALL_EXPR_FN (*from_p), 0);
5866 STRIP_USELESS_TYPE_CONVERSION (CALL_EXPR_FN (*from_p));
5867 tree fndecl = get_callee_fndecl (*from_p);
5868 if (fndecl
5869 && fndecl_built_in_p (fndecl, BUILT_IN_EXPECT)
5870 && call_expr_nargs (*from_p) == 3)
5871 call_stmt = gimple_build_call_internal (IFN_BUILTIN_EXPECT, 3,
5872 CALL_EXPR_ARG (*from_p, 0),
5873 CALL_EXPR_ARG (*from_p, 1),
5874 CALL_EXPR_ARG (*from_p, 2));
5875 else
5877 call_stmt = gimple_build_call_from_tree (*from_p, fnptrtype);
5880 notice_special_calls (call_stmt);
5881 if (!gimple_call_noreturn_p (call_stmt) || !should_remove_lhs_p (*to_p))
5882 gimple_call_set_lhs (call_stmt, *to_p);
5883 else if (TREE_CODE (*to_p) == SSA_NAME)
5884 /* The above is somewhat premature, avoid ICEing later for a
5885 SSA name w/o a definition. We may have uses in the GIMPLE IL.
5886 ??? This doesn't make it a default-def. */
5887 SSA_NAME_DEF_STMT (*to_p) = gimple_build_nop ();
5889 assign = call_stmt;
5891 else
5893 assign = gimple_build_assign (*to_p, *from_p);
5894 gimple_set_location (assign, EXPR_LOCATION (*expr_p));
5895 if (COMPARISON_CLASS_P (*from_p))
5896 gimple_set_no_warning (assign, TREE_NO_WARNING (*from_p));
5899 if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p))
5901 /* We should have got an SSA name from the start. */
5902 gcc_assert (TREE_CODE (*to_p) == SSA_NAME
5903 || ! gimple_in_ssa_p (cfun));
5906 gimplify_seq_add_stmt (pre_p, assign);
5907 gsi = gsi_last (*pre_p);
5908 maybe_fold_stmt (&gsi);
5910 if (want_value)
5912 *expr_p = TREE_THIS_VOLATILE (*to_p) ? *from_p : unshare_expr (*to_p);
5913 return GS_OK;
5915 else
5916 *expr_p = NULL;
5918 return GS_ALL_DONE;
5921 /* Gimplify a comparison between two variable-sized objects. Do this
5922 with a call to BUILT_IN_MEMCMP. */
5924 static enum gimplify_status
5925 gimplify_variable_sized_compare (tree *expr_p)
5927 location_t loc = EXPR_LOCATION (*expr_p);
5928 tree op0 = TREE_OPERAND (*expr_p, 0);
5929 tree op1 = TREE_OPERAND (*expr_p, 1);
5930 tree t, arg, dest, src, expr;
5932 arg = TYPE_SIZE_UNIT (TREE_TYPE (op0));
5933 arg = unshare_expr (arg);
5934 arg = SUBSTITUTE_PLACEHOLDER_IN_EXPR (arg, op0);
5935 src = build_fold_addr_expr_loc (loc, op1);
5936 dest = build_fold_addr_expr_loc (loc, op0);
5937 t = builtin_decl_implicit (BUILT_IN_MEMCMP);
5938 t = build_call_expr_loc (loc, t, 3, dest, src, arg);
5940 expr
5941 = build2 (TREE_CODE (*expr_p), TREE_TYPE (*expr_p), t, integer_zero_node);
5942 SET_EXPR_LOCATION (expr, loc);
5943 *expr_p = expr;
5945 return GS_OK;
5948 /* Gimplify a comparison between two aggregate objects of integral scalar
5949 mode as a comparison between the bitwise equivalent scalar values. */
5951 static enum gimplify_status
5952 gimplify_scalar_mode_aggregate_compare (tree *expr_p)
5954 location_t loc = EXPR_LOCATION (*expr_p);
5955 tree op0 = TREE_OPERAND (*expr_p, 0);
5956 tree op1 = TREE_OPERAND (*expr_p, 1);
5958 tree type = TREE_TYPE (op0);
5959 tree scalar_type = lang_hooks.types.type_for_mode (TYPE_MODE (type), 1);
5961 op0 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op0);
5962 op1 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op1);
5964 *expr_p
5965 = fold_build2_loc (loc, TREE_CODE (*expr_p), TREE_TYPE (*expr_p), op0, op1);
5967 return GS_OK;
5970 /* Gimplify an expression sequence. This function gimplifies each
5971 expression and rewrites the original expression with the last
5972 expression of the sequence in GIMPLE form.
5974 PRE_P points to the list where the side effects for all the
5975 expressions in the sequence will be emitted.
5977 WANT_VALUE is true when the result of the last COMPOUND_EXPR is used. */
5979 static enum gimplify_status
5980 gimplify_compound_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
5982 tree t = *expr_p;
5986 tree *sub_p = &TREE_OPERAND (t, 0);
5988 if (TREE_CODE (*sub_p) == COMPOUND_EXPR)
5989 gimplify_compound_expr (sub_p, pre_p, false);
5990 else
5991 gimplify_stmt (sub_p, pre_p);
5993 t = TREE_OPERAND (t, 1);
5995 while (TREE_CODE (t) == COMPOUND_EXPR);
5997 *expr_p = t;
5998 if (want_value)
5999 return GS_OK;
6000 else
6002 gimplify_stmt (expr_p, pre_p);
6003 return GS_ALL_DONE;
6007 /* Gimplify a SAVE_EXPR node. EXPR_P points to the expression to
6008 gimplify. After gimplification, EXPR_P will point to a new temporary
6009 that holds the original value of the SAVE_EXPR node.
6011 PRE_P points to the list where side effects that must happen before
6012 *EXPR_P should be stored. */
6014 static enum gimplify_status
6015 gimplify_save_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6017 enum gimplify_status ret = GS_ALL_DONE;
6018 tree val;
6020 gcc_assert (TREE_CODE (*expr_p) == SAVE_EXPR);
6021 val = TREE_OPERAND (*expr_p, 0);
6023 /* If the SAVE_EXPR has not been resolved, then evaluate it once. */
6024 if (!SAVE_EXPR_RESOLVED_P (*expr_p))
6026 /* The operand may be a void-valued expression. It is
6027 being executed only for its side-effects. */
6028 if (TREE_TYPE (val) == void_type_node)
6030 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
6031 is_gimple_stmt, fb_none);
6032 val = NULL;
6034 else
6035 /* The temporary may not be an SSA name as later abnormal and EH
6036 control flow may invalidate use/def domination. When in SSA
6037 form then assume there are no such issues and SAVE_EXPRs only
6038 appear via GENERIC foldings. */
6039 val = get_initialized_tmp_var (val, pre_p, post_p,
6040 gimple_in_ssa_p (cfun));
6042 TREE_OPERAND (*expr_p, 0) = val;
6043 SAVE_EXPR_RESOLVED_P (*expr_p) = 1;
6046 *expr_p = val;
6048 return ret;
6051 /* Rewrite the ADDR_EXPR node pointed to by EXPR_P
6053 unary_expr
6054 : ...
6055 | '&' varname
6058 PRE_P points to the list where side effects that must happen before
6059 *EXPR_P should be stored.
6061 POST_P points to the list where side effects that must happen after
6062 *EXPR_P should be stored. */
6064 static enum gimplify_status
6065 gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6067 tree expr = *expr_p;
6068 tree op0 = TREE_OPERAND (expr, 0);
6069 enum gimplify_status ret;
6070 location_t loc = EXPR_LOCATION (*expr_p);
6072 switch (TREE_CODE (op0))
6074 case INDIRECT_REF:
6075 do_indirect_ref:
6076 /* Check if we are dealing with an expression of the form '&*ptr'.
6077 While the front end folds away '&*ptr' into 'ptr', these
6078 expressions may be generated internally by the compiler (e.g.,
6079 builtins like __builtin_va_end). */
6080 /* Caution: the silent array decomposition semantics we allow for
6081 ADDR_EXPR means we can't always discard the pair. */
6082 /* Gimplification of the ADDR_EXPR operand may drop
6083 cv-qualification conversions, so make sure we add them if
6084 needed. */
6086 tree op00 = TREE_OPERAND (op0, 0);
6087 tree t_expr = TREE_TYPE (expr);
6088 tree t_op00 = TREE_TYPE (op00);
6090 if (!useless_type_conversion_p (t_expr, t_op00))
6091 op00 = fold_convert_loc (loc, TREE_TYPE (expr), op00);
6092 *expr_p = op00;
6093 ret = GS_OK;
6095 break;
6097 case VIEW_CONVERT_EXPR:
6098 /* Take the address of our operand and then convert it to the type of
6099 this ADDR_EXPR.
6101 ??? The interactions of VIEW_CONVERT_EXPR and aliasing is not at
6102 all clear. The impact of this transformation is even less clear. */
6104 /* If the operand is a useless conversion, look through it. Doing so
6105 guarantees that the ADDR_EXPR and its operand will remain of the
6106 same type. */
6107 if (tree_ssa_useless_type_conversion (TREE_OPERAND (op0, 0)))
6108 op0 = TREE_OPERAND (op0, 0);
6110 *expr_p = fold_convert_loc (loc, TREE_TYPE (expr),
6111 build_fold_addr_expr_loc (loc,
6112 TREE_OPERAND (op0, 0)));
6113 ret = GS_OK;
6114 break;
6116 case MEM_REF:
6117 if (integer_zerop (TREE_OPERAND (op0, 1)))
6118 goto do_indirect_ref;
6120 /* fall through */
6122 default:
6123 /* If we see a call to a declared builtin or see its address
6124 being taken (we can unify those cases here) then we can mark
6125 the builtin for implicit generation by GCC. */
6126 if (TREE_CODE (op0) == FUNCTION_DECL
6127 && fndecl_built_in_p (op0, BUILT_IN_NORMAL)
6128 && builtin_decl_declared_p (DECL_FUNCTION_CODE (op0)))
6129 set_builtin_decl_implicit_p (DECL_FUNCTION_CODE (op0), true);
6131 /* We use fb_either here because the C frontend sometimes takes
6132 the address of a call that returns a struct; see
6133 gcc.dg/c99-array-lval-1.c. The gimplifier will correctly make
6134 the implied temporary explicit. */
6136 /* Make the operand addressable. */
6137 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, post_p,
6138 is_gimple_addressable, fb_either);
6139 if (ret == GS_ERROR)
6140 break;
6142 /* Then mark it. Beware that it may not be possible to do so directly
6143 if a temporary has been created by the gimplification. */
6144 prepare_gimple_addressable (&TREE_OPERAND (expr, 0), pre_p);
6146 op0 = TREE_OPERAND (expr, 0);
6148 /* For various reasons, the gimplification of the expression
6149 may have made a new INDIRECT_REF. */
6150 if (TREE_CODE (op0) == INDIRECT_REF)
6151 goto do_indirect_ref;
6153 mark_addressable (TREE_OPERAND (expr, 0));
6155 /* The FEs may end up building ADDR_EXPRs early on a decl with
6156 an incomplete type. Re-build ADDR_EXPRs in canonical form
6157 here. */
6158 if (!types_compatible_p (TREE_TYPE (op0), TREE_TYPE (TREE_TYPE (expr))))
6159 *expr_p = build_fold_addr_expr (op0);
6161 /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly. */
6162 recompute_tree_invariant_for_addr_expr (*expr_p);
6164 /* If we re-built the ADDR_EXPR add a conversion to the original type
6165 if required. */
6166 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
6167 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
6169 break;
6172 return ret;
6175 /* Gimplify the operands of an ASM_EXPR. Input operands should be a gimple
6176 value; output operands should be a gimple lvalue. */
6178 static enum gimplify_status
6179 gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6181 tree expr;
6182 int noutputs;
6183 const char **oconstraints;
6184 int i;
6185 tree link;
6186 const char *constraint;
6187 bool allows_mem, allows_reg, is_inout;
6188 enum gimplify_status ret, tret;
6189 gasm *stmt;
6190 vec<tree, va_gc> *inputs;
6191 vec<tree, va_gc> *outputs;
6192 vec<tree, va_gc> *clobbers;
6193 vec<tree, va_gc> *labels;
6194 tree link_next;
6196 expr = *expr_p;
6197 noutputs = list_length (ASM_OUTPUTS (expr));
6198 oconstraints = (const char **) alloca ((noutputs) * sizeof (const char *));
6200 inputs = NULL;
6201 outputs = NULL;
6202 clobbers = NULL;
6203 labels = NULL;
6205 ret = GS_ALL_DONE;
6206 link_next = NULL_TREE;
6207 for (i = 0, link = ASM_OUTPUTS (expr); link; ++i, link = link_next)
6209 bool ok;
6210 size_t constraint_len;
6212 link_next = TREE_CHAIN (link);
6214 oconstraints[i]
6215 = constraint
6216 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
6217 constraint_len = strlen (constraint);
6218 if (constraint_len == 0)
6219 continue;
6221 ok = parse_output_constraint (&constraint, i, 0, 0,
6222 &allows_mem, &allows_reg, &is_inout);
6223 if (!ok)
6225 ret = GS_ERROR;
6226 is_inout = false;
6229 /* If we can't make copies, we can only accept memory. */
6230 if (TREE_ADDRESSABLE (TREE_TYPE (TREE_VALUE (link))))
6232 if (allows_mem)
6233 allows_reg = 0;
6234 else
6236 error ("impossible constraint in %<asm%>");
6237 error ("non-memory output %d must stay in memory", i);
6238 return GS_ERROR;
6242 if (!allows_reg && allows_mem)
6243 mark_addressable (TREE_VALUE (link));
6245 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6246 is_inout ? is_gimple_min_lval : is_gimple_lvalue,
6247 fb_lvalue | fb_mayfail);
6248 if (tret == GS_ERROR)
6250 error ("invalid lvalue in %<asm%> output %d", i);
6251 ret = tret;
6254 /* If the constraint does not allow memory make sure we gimplify
6255 it to a register if it is not already but its base is. This
6256 happens for complex and vector components. */
6257 if (!allows_mem)
6259 tree op = TREE_VALUE (link);
6260 if (! is_gimple_val (op)
6261 && is_gimple_reg_type (TREE_TYPE (op))
6262 && is_gimple_reg (get_base_address (op)))
6264 tree tem = create_tmp_reg (TREE_TYPE (op));
6265 tree ass;
6266 if (is_inout)
6268 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem),
6269 tem, unshare_expr (op));
6270 gimplify_and_add (ass, pre_p);
6272 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem), op, tem);
6273 gimplify_and_add (ass, post_p);
6275 TREE_VALUE (link) = tem;
6276 tret = GS_OK;
6280 vec_safe_push (outputs, link);
6281 TREE_CHAIN (link) = NULL_TREE;
6283 if (is_inout)
6285 /* An input/output operand. To give the optimizers more
6286 flexibility, split it into separate input and output
6287 operands. */
6288 tree input;
6289 /* Buffer big enough to format a 32-bit UINT_MAX into. */
6290 char buf[11];
6292 /* Turn the in/out constraint into an output constraint. */
6293 char *p = xstrdup (constraint);
6294 p[0] = '=';
6295 TREE_VALUE (TREE_PURPOSE (link)) = build_string (constraint_len, p);
6297 /* And add a matching input constraint. */
6298 if (allows_reg)
6300 sprintf (buf, "%u", i);
6302 /* If there are multiple alternatives in the constraint,
6303 handle each of them individually. Those that allow register
6304 will be replaced with operand number, the others will stay
6305 unchanged. */
6306 if (strchr (p, ',') != NULL)
6308 size_t len = 0, buflen = strlen (buf);
6309 char *beg, *end, *str, *dst;
6311 for (beg = p + 1;;)
6313 end = strchr (beg, ',');
6314 if (end == NULL)
6315 end = strchr (beg, '\0');
6316 if ((size_t) (end - beg) < buflen)
6317 len += buflen + 1;
6318 else
6319 len += end - beg + 1;
6320 if (*end)
6321 beg = end + 1;
6322 else
6323 break;
6326 str = (char *) alloca (len);
6327 for (beg = p + 1, dst = str;;)
6329 const char *tem;
6330 bool mem_p, reg_p, inout_p;
6332 end = strchr (beg, ',');
6333 if (end)
6334 *end = '\0';
6335 beg[-1] = '=';
6336 tem = beg - 1;
6337 parse_output_constraint (&tem, i, 0, 0,
6338 &mem_p, &reg_p, &inout_p);
6339 if (dst != str)
6340 *dst++ = ',';
6341 if (reg_p)
6343 memcpy (dst, buf, buflen);
6344 dst += buflen;
6346 else
6348 if (end)
6349 len = end - beg;
6350 else
6351 len = strlen (beg);
6352 memcpy (dst, beg, len);
6353 dst += len;
6355 if (end)
6356 beg = end + 1;
6357 else
6358 break;
6360 *dst = '\0';
6361 input = build_string (dst - str, str);
6363 else
6364 input = build_string (strlen (buf), buf);
6366 else
6367 input = build_string (constraint_len - 1, constraint + 1);
6369 free (p);
6371 input = build_tree_list (build_tree_list (NULL_TREE, input),
6372 unshare_expr (TREE_VALUE (link)));
6373 ASM_INPUTS (expr) = chainon (ASM_INPUTS (expr), input);
6377 link_next = NULL_TREE;
6378 for (link = ASM_INPUTS (expr); link; ++i, link = link_next)
6380 link_next = TREE_CHAIN (link);
6381 constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
6382 parse_input_constraint (&constraint, 0, 0, noutputs, 0,
6383 oconstraints, &allows_mem, &allows_reg);
6385 /* If we can't make copies, we can only accept memory. */
6386 if (TREE_ADDRESSABLE (TREE_TYPE (TREE_VALUE (link))))
6388 if (allows_mem)
6389 allows_reg = 0;
6390 else
6392 error ("impossible constraint in %<asm%>");
6393 error ("non-memory input %d must stay in memory", i);
6394 return GS_ERROR;
6398 /* If the operand is a memory input, it should be an lvalue. */
6399 if (!allows_reg && allows_mem)
6401 tree inputv = TREE_VALUE (link);
6402 STRIP_NOPS (inputv);
6403 if (TREE_CODE (inputv) == PREDECREMENT_EXPR
6404 || TREE_CODE (inputv) == PREINCREMENT_EXPR
6405 || TREE_CODE (inputv) == POSTDECREMENT_EXPR
6406 || TREE_CODE (inputv) == POSTINCREMENT_EXPR
6407 || TREE_CODE (inputv) == MODIFY_EXPR)
6408 TREE_VALUE (link) = error_mark_node;
6409 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6410 is_gimple_lvalue, fb_lvalue | fb_mayfail);
6411 if (tret != GS_ERROR)
6413 /* Unlike output operands, memory inputs are not guaranteed
6414 to be lvalues by the FE, and while the expressions are
6415 marked addressable there, if it is e.g. a statement
6416 expression, temporaries in it might not end up being
6417 addressable. They might be already used in the IL and thus
6418 it is too late to make them addressable now though. */
6419 tree x = TREE_VALUE (link);
6420 while (handled_component_p (x))
6421 x = TREE_OPERAND (x, 0);
6422 if (TREE_CODE (x) == MEM_REF
6423 && TREE_CODE (TREE_OPERAND (x, 0)) == ADDR_EXPR)
6424 x = TREE_OPERAND (TREE_OPERAND (x, 0), 0);
6425 if ((VAR_P (x)
6426 || TREE_CODE (x) == PARM_DECL
6427 || TREE_CODE (x) == RESULT_DECL)
6428 && !TREE_ADDRESSABLE (x)
6429 && is_gimple_reg (x))
6431 warning_at (EXPR_LOC_OR_LOC (TREE_VALUE (link),
6432 input_location), 0,
6433 "memory input %d is not directly addressable",
6435 prepare_gimple_addressable (&TREE_VALUE (link), pre_p);
6438 mark_addressable (TREE_VALUE (link));
6439 if (tret == GS_ERROR)
6441 error_at (EXPR_LOC_OR_LOC (TREE_VALUE (link), input_location),
6442 "memory input %d is not directly addressable", i);
6443 ret = tret;
6446 else
6448 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6449 is_gimple_asm_val, fb_rvalue);
6450 if (tret == GS_ERROR)
6451 ret = tret;
6454 TREE_CHAIN (link) = NULL_TREE;
6455 vec_safe_push (inputs, link);
6458 link_next = NULL_TREE;
6459 for (link = ASM_CLOBBERS (expr); link; ++i, link = link_next)
6461 link_next = TREE_CHAIN (link);
6462 TREE_CHAIN (link) = NULL_TREE;
6463 vec_safe_push (clobbers, link);
6466 link_next = NULL_TREE;
6467 for (link = ASM_LABELS (expr); link; ++i, link = link_next)
6469 link_next = TREE_CHAIN (link);
6470 TREE_CHAIN (link) = NULL_TREE;
6471 vec_safe_push (labels, link);
6474 /* Do not add ASMs with errors to the gimple IL stream. */
6475 if (ret != GS_ERROR)
6477 stmt = gimple_build_asm_vec (TREE_STRING_POINTER (ASM_STRING (expr)),
6478 inputs, outputs, clobbers, labels);
6480 gimple_asm_set_volatile (stmt, ASM_VOLATILE_P (expr) || noutputs == 0);
6481 gimple_asm_set_input (stmt, ASM_INPUT_P (expr));
6482 gimple_asm_set_inline (stmt, ASM_INLINE_P (expr));
6484 gimplify_seq_add_stmt (pre_p, stmt);
6487 return ret;
6490 /* Gimplify a CLEANUP_POINT_EXPR. Currently this works by adding
6491 GIMPLE_WITH_CLEANUP_EXPRs to the prequeue as we encounter cleanups while
6492 gimplifying the body, and converting them to TRY_FINALLY_EXPRs when we
6493 return to this function.
6495 FIXME should we complexify the prequeue handling instead? Or use flags
6496 for all the cleanups and let the optimizer tighten them up? The current
6497 code seems pretty fragile; it will break on a cleanup within any
6498 non-conditional nesting. But any such nesting would be broken, anyway;
6499 we can't write a TRY_FINALLY_EXPR that starts inside a nesting construct
6500 and continues out of it. We can do that at the RTL level, though, so
6501 having an optimizer to tighten up try/finally regions would be a Good
6502 Thing. */
6504 static enum gimplify_status
6505 gimplify_cleanup_point_expr (tree *expr_p, gimple_seq *pre_p)
6507 gimple_stmt_iterator iter;
6508 gimple_seq body_sequence = NULL;
6510 tree temp = voidify_wrapper_expr (*expr_p, NULL);
6512 /* We only care about the number of conditions between the innermost
6513 CLEANUP_POINT_EXPR and the cleanup. So save and reset the count and
6514 any cleanups collected outside the CLEANUP_POINT_EXPR. */
6515 int old_conds = gimplify_ctxp->conditions;
6516 gimple_seq old_cleanups = gimplify_ctxp->conditional_cleanups;
6517 bool old_in_cleanup_point_expr = gimplify_ctxp->in_cleanup_point_expr;
6518 gimplify_ctxp->conditions = 0;
6519 gimplify_ctxp->conditional_cleanups = NULL;
6520 gimplify_ctxp->in_cleanup_point_expr = true;
6522 gimplify_stmt (&TREE_OPERAND (*expr_p, 0), &body_sequence);
6524 gimplify_ctxp->conditions = old_conds;
6525 gimplify_ctxp->conditional_cleanups = old_cleanups;
6526 gimplify_ctxp->in_cleanup_point_expr = old_in_cleanup_point_expr;
6528 for (iter = gsi_start (body_sequence); !gsi_end_p (iter); )
6530 gimple *wce = gsi_stmt (iter);
6532 if (gimple_code (wce) == GIMPLE_WITH_CLEANUP_EXPR)
6534 if (gsi_one_before_end_p (iter))
6536 /* Note that gsi_insert_seq_before and gsi_remove do not
6537 scan operands, unlike some other sequence mutators. */
6538 if (!gimple_wce_cleanup_eh_only (wce))
6539 gsi_insert_seq_before_without_update (&iter,
6540 gimple_wce_cleanup (wce),
6541 GSI_SAME_STMT);
6542 gsi_remove (&iter, true);
6543 break;
6545 else
6547 gtry *gtry;
6548 gimple_seq seq;
6549 enum gimple_try_flags kind;
6551 if (gimple_wce_cleanup_eh_only (wce))
6552 kind = GIMPLE_TRY_CATCH;
6553 else
6554 kind = GIMPLE_TRY_FINALLY;
6555 seq = gsi_split_seq_after (iter);
6557 gtry = gimple_build_try (seq, gimple_wce_cleanup (wce), kind);
6558 /* Do not use gsi_replace here, as it may scan operands.
6559 We want to do a simple structural modification only. */
6560 gsi_set_stmt (&iter, gtry);
6561 iter = gsi_start (gtry->eval);
6564 else
6565 gsi_next (&iter);
6568 gimplify_seq_add_seq (pre_p, body_sequence);
6569 if (temp)
6571 *expr_p = temp;
6572 return GS_OK;
6574 else
6576 *expr_p = NULL;
6577 return GS_ALL_DONE;
6581 /* Insert a cleanup marker for gimplify_cleanup_point_expr. CLEANUP
6582 is the cleanup action required. EH_ONLY is true if the cleanup should
6583 only be executed if an exception is thrown, not on normal exit.
6584 If FORCE_UNCOND is true perform the cleanup unconditionally; this is
6585 only valid for clobbers. */
6587 static void
6588 gimple_push_cleanup (tree var, tree cleanup, bool eh_only, gimple_seq *pre_p,
6589 bool force_uncond = false)
6591 gimple *wce;
6592 gimple_seq cleanup_stmts = NULL;
6594 /* Errors can result in improperly nested cleanups. Which results in
6595 confusion when trying to resolve the GIMPLE_WITH_CLEANUP_EXPR. */
6596 if (seen_error ())
6597 return;
6599 if (gimple_conditional_context ())
6601 /* If we're in a conditional context, this is more complex. We only
6602 want to run the cleanup if we actually ran the initialization that
6603 necessitates it, but we want to run it after the end of the
6604 conditional context. So we wrap the try/finally around the
6605 condition and use a flag to determine whether or not to actually
6606 run the destructor. Thus
6608 test ? f(A()) : 0
6610 becomes (approximately)
6612 flag = 0;
6613 try {
6614 if (test) { A::A(temp); flag = 1; val = f(temp); }
6615 else { val = 0; }
6616 } finally {
6617 if (flag) A::~A(temp);
6621 if (force_uncond)
6623 gimplify_stmt (&cleanup, &cleanup_stmts);
6624 wce = gimple_build_wce (cleanup_stmts);
6625 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
6627 else
6629 tree flag = create_tmp_var (boolean_type_node, "cleanup");
6630 gassign *ffalse = gimple_build_assign (flag, boolean_false_node);
6631 gassign *ftrue = gimple_build_assign (flag, boolean_true_node);
6633 cleanup = build3 (COND_EXPR, void_type_node, flag, cleanup, NULL);
6634 gimplify_stmt (&cleanup, &cleanup_stmts);
6635 wce = gimple_build_wce (cleanup_stmts);
6637 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, ffalse);
6638 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
6639 gimplify_seq_add_stmt (pre_p, ftrue);
6641 /* Because of this manipulation, and the EH edges that jump
6642 threading cannot redirect, the temporary (VAR) will appear
6643 to be used uninitialized. Don't warn. */
6644 TREE_NO_WARNING (var) = 1;
6647 else
6649 gimplify_stmt (&cleanup, &cleanup_stmts);
6650 wce = gimple_build_wce (cleanup_stmts);
6651 gimple_wce_set_cleanup_eh_only (wce, eh_only);
6652 gimplify_seq_add_stmt (pre_p, wce);
6656 /* Gimplify a TARGET_EXPR which doesn't appear on the rhs of an INIT_EXPR. */
6658 static enum gimplify_status
6659 gimplify_target_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6661 tree targ = *expr_p;
6662 tree temp = TARGET_EXPR_SLOT (targ);
6663 tree init = TARGET_EXPR_INITIAL (targ);
6664 enum gimplify_status ret;
6666 bool unpoison_empty_seq = false;
6667 gimple_stmt_iterator unpoison_it;
6669 if (init)
6671 tree cleanup = NULL_TREE;
6673 /* TARGET_EXPR temps aren't part of the enclosing block, so add it
6674 to the temps list. Handle also variable length TARGET_EXPRs. */
6675 if (TREE_CODE (DECL_SIZE (temp)) != INTEGER_CST)
6677 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (temp)))
6678 gimplify_type_sizes (TREE_TYPE (temp), pre_p);
6679 gimplify_vla_decl (temp, pre_p);
6681 else
6683 /* Save location where we need to place unpoisoning. It's possible
6684 that a variable will be converted to needs_to_live_in_memory. */
6685 unpoison_it = gsi_last (*pre_p);
6686 unpoison_empty_seq = gsi_end_p (unpoison_it);
6688 gimple_add_tmp_var (temp);
6691 /* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the
6692 expression is supposed to initialize the slot. */
6693 if (VOID_TYPE_P (TREE_TYPE (init)))
6694 ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
6695 else
6697 tree init_expr = build2 (INIT_EXPR, void_type_node, temp, init);
6698 init = init_expr;
6699 ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
6700 init = NULL;
6701 ggc_free (init_expr);
6703 if (ret == GS_ERROR)
6705 /* PR c++/28266 Make sure this is expanded only once. */
6706 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
6707 return GS_ERROR;
6709 if (init)
6710 gimplify_and_add (init, pre_p);
6712 /* If needed, push the cleanup for the temp. */
6713 if (TARGET_EXPR_CLEANUP (targ))
6715 if (CLEANUP_EH_ONLY (targ))
6716 gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ),
6717 CLEANUP_EH_ONLY (targ), pre_p);
6718 else
6719 cleanup = TARGET_EXPR_CLEANUP (targ);
6722 /* Add a clobber for the temporary going out of scope, like
6723 gimplify_bind_expr. */
6724 if (gimplify_ctxp->in_cleanup_point_expr
6725 && needs_to_live_in_memory (temp))
6727 if (flag_stack_reuse == SR_ALL)
6729 tree clobber = build_clobber (TREE_TYPE (temp));
6730 clobber = build2 (MODIFY_EXPR, TREE_TYPE (temp), temp, clobber);
6731 gimple_push_cleanup (temp, clobber, false, pre_p, true);
6733 if (asan_poisoned_variables
6734 && DECL_ALIGN (temp) <= MAX_SUPPORTED_STACK_ALIGNMENT
6735 && !TREE_STATIC (temp)
6736 && dbg_cnt (asan_use_after_scope)
6737 && !gimplify_omp_ctxp)
6739 tree asan_cleanup = build_asan_poison_call_expr (temp);
6740 if (asan_cleanup)
6742 if (unpoison_empty_seq)
6743 unpoison_it = gsi_start (*pre_p);
6745 asan_poison_variable (temp, false, &unpoison_it,
6746 unpoison_empty_seq);
6747 gimple_push_cleanup (temp, asan_cleanup, false, pre_p);
6751 if (cleanup)
6752 gimple_push_cleanup (temp, cleanup, false, pre_p);
6754 /* Only expand this once. */
6755 TREE_OPERAND (targ, 3) = init;
6756 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
6758 else
6759 /* We should have expanded this before. */
6760 gcc_assert (DECL_SEEN_IN_BIND_EXPR_P (temp));
6762 *expr_p = temp;
6763 return GS_OK;
6766 /* Gimplification of expression trees. */
6768 /* Gimplify an expression which appears at statement context. The
6769 corresponding GIMPLE statements are added to *SEQ_P. If *SEQ_P is
6770 NULL, a new sequence is allocated.
6772 Return true if we actually added a statement to the queue. */
6774 bool
6775 gimplify_stmt (tree *stmt_p, gimple_seq *seq_p)
6777 gimple_seq_node last;
6779 last = gimple_seq_last (*seq_p);
6780 gimplify_expr (stmt_p, seq_p, NULL, is_gimple_stmt, fb_none);
6781 return last != gimple_seq_last (*seq_p);
6784 /* Add FIRSTPRIVATE entries for DECL in the OpenMP the surrounding parallels
6785 to CTX. If entries already exist, force them to be some flavor of private.
6786 If there is no enclosing parallel, do nothing. */
6788 void
6789 omp_firstprivatize_variable (struct gimplify_omp_ctx *ctx, tree decl)
6791 splay_tree_node n;
6793 if (decl == NULL || !DECL_P (decl) || ctx->region_type == ORT_NONE)
6794 return;
6798 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
6799 if (n != NULL)
6801 if (n->value & GOVD_SHARED)
6802 n->value = GOVD_FIRSTPRIVATE | (n->value & GOVD_SEEN);
6803 else if (n->value & GOVD_MAP)
6804 n->value |= GOVD_MAP_TO_ONLY;
6805 else
6806 return;
6808 else if ((ctx->region_type & ORT_TARGET) != 0)
6810 if (ctx->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE)
6811 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
6812 else
6813 omp_add_variable (ctx, decl, GOVD_MAP | GOVD_MAP_TO_ONLY);
6815 else if (ctx->region_type != ORT_WORKSHARE
6816 && ctx->region_type != ORT_TASKGROUP
6817 && ctx->region_type != ORT_SIMD
6818 && ctx->region_type != ORT_ACC
6819 && !(ctx->region_type & ORT_TARGET_DATA))
6820 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
6822 ctx = ctx->outer_context;
6824 while (ctx);
6827 /* Similarly for each of the type sizes of TYPE. */
6829 static void
6830 omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type)
6832 if (type == NULL || type == error_mark_node)
6833 return;
6834 type = TYPE_MAIN_VARIANT (type);
6836 if (ctx->privatized_types->add (type))
6837 return;
6839 switch (TREE_CODE (type))
6841 case INTEGER_TYPE:
6842 case ENUMERAL_TYPE:
6843 case BOOLEAN_TYPE:
6844 case REAL_TYPE:
6845 case FIXED_POINT_TYPE:
6846 omp_firstprivatize_variable (ctx, TYPE_MIN_VALUE (type));
6847 omp_firstprivatize_variable (ctx, TYPE_MAX_VALUE (type));
6848 break;
6850 case ARRAY_TYPE:
6851 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
6852 omp_firstprivatize_type_sizes (ctx, TYPE_DOMAIN (type));
6853 break;
6855 case RECORD_TYPE:
6856 case UNION_TYPE:
6857 case QUAL_UNION_TYPE:
6859 tree field;
6860 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
6861 if (TREE_CODE (field) == FIELD_DECL)
6863 omp_firstprivatize_variable (ctx, DECL_FIELD_OFFSET (field));
6864 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (field));
6867 break;
6869 case POINTER_TYPE:
6870 case REFERENCE_TYPE:
6871 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
6872 break;
6874 default:
6875 break;
6878 omp_firstprivatize_variable (ctx, TYPE_SIZE (type));
6879 omp_firstprivatize_variable (ctx, TYPE_SIZE_UNIT (type));
6880 lang_hooks.types.omp_firstprivatize_type_sizes (ctx, type);
6883 /* Add an entry for DECL in the OMP context CTX with FLAGS. */
6885 static void
6886 omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
6888 splay_tree_node n;
6889 unsigned int nflags;
6890 tree t;
6892 if (error_operand_p (decl) || ctx->region_type == ORT_NONE)
6893 return;
6895 /* Never elide decls whose type has TREE_ADDRESSABLE set. This means
6896 there are constructors involved somewhere. Exception is a shared clause,
6897 there is nothing privatized in that case. */
6898 if ((flags & GOVD_SHARED) == 0
6899 && (TREE_ADDRESSABLE (TREE_TYPE (decl))
6900 || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))))
6901 flags |= GOVD_SEEN;
6903 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
6904 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
6906 /* We shouldn't be re-adding the decl with the same data
6907 sharing class. */
6908 gcc_assert ((n->value & GOVD_DATA_SHARE_CLASS & flags) == 0);
6909 nflags = n->value | flags;
6910 /* The only combination of data sharing classes we should see is
6911 FIRSTPRIVATE and LASTPRIVATE. However, OpenACC permits
6912 reduction variables to be used in data sharing clauses. */
6913 gcc_assert ((ctx->region_type & ORT_ACC) != 0
6914 || ((nflags & GOVD_DATA_SHARE_CLASS)
6915 == (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE))
6916 || (flags & GOVD_DATA_SHARE_CLASS) == 0);
6917 n->value = nflags;
6918 return;
6921 /* When adding a variable-sized variable, we have to handle all sorts
6922 of additional bits of data: the pointer replacement variable, and
6923 the parameters of the type. */
6924 if (DECL_SIZE (decl) && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
6926 /* Add the pointer replacement variable as PRIVATE if the variable
6927 replacement is private, else FIRSTPRIVATE since we'll need the
6928 address of the original variable either for SHARED, or for the
6929 copy into or out of the context. */
6930 if (!(flags & GOVD_LOCAL) && ctx->region_type != ORT_TASKGROUP)
6932 if (flags & GOVD_MAP)
6933 nflags = GOVD_MAP | GOVD_MAP_TO_ONLY | GOVD_EXPLICIT;
6934 else if (flags & GOVD_PRIVATE)
6935 nflags = GOVD_PRIVATE;
6936 else if (((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
6937 && (flags & GOVD_FIRSTPRIVATE))
6938 || (ctx->region_type == ORT_TARGET_DATA
6939 && (flags & GOVD_DATA_SHARE_CLASS) == 0))
6940 nflags = GOVD_PRIVATE | GOVD_EXPLICIT;
6941 else
6942 nflags = GOVD_FIRSTPRIVATE;
6943 nflags |= flags & GOVD_SEEN;
6944 t = DECL_VALUE_EXPR (decl);
6945 gcc_assert (TREE_CODE (t) == INDIRECT_REF);
6946 t = TREE_OPERAND (t, 0);
6947 gcc_assert (DECL_P (t));
6948 omp_add_variable (ctx, t, nflags);
6951 /* Add all of the variable and type parameters (which should have
6952 been gimplified to a formal temporary) as FIRSTPRIVATE. */
6953 omp_firstprivatize_variable (ctx, DECL_SIZE_UNIT (decl));
6954 omp_firstprivatize_variable (ctx, DECL_SIZE (decl));
6955 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
6957 /* The variable-sized variable itself is never SHARED, only some form
6958 of PRIVATE. The sharing would take place via the pointer variable
6959 which we remapped above. */
6960 if (flags & GOVD_SHARED)
6961 flags = GOVD_SHARED | GOVD_DEBUG_PRIVATE
6962 | (flags & (GOVD_SEEN | GOVD_EXPLICIT));
6964 /* We're going to make use of the TYPE_SIZE_UNIT at least in the
6965 alloca statement we generate for the variable, so make sure it
6966 is available. This isn't automatically needed for the SHARED
6967 case, since we won't be allocating local storage then.
6968 For local variables TYPE_SIZE_UNIT might not be gimplified yet,
6969 in this case omp_notice_variable will be called later
6970 on when it is gimplified. */
6971 else if (! (flags & (GOVD_LOCAL | GOVD_MAP))
6972 && DECL_P (TYPE_SIZE_UNIT (TREE_TYPE (decl))))
6973 omp_notice_variable (ctx, TYPE_SIZE_UNIT (TREE_TYPE (decl)), true);
6975 else if ((flags & (GOVD_MAP | GOVD_LOCAL)) == 0
6976 && lang_hooks.decls.omp_privatize_by_reference (decl))
6978 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
6980 /* Similar to the direct variable sized case above, we'll need the
6981 size of references being privatized. */
6982 if ((flags & GOVD_SHARED) == 0)
6984 t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
6985 if (DECL_P (t))
6986 omp_notice_variable (ctx, t, true);
6990 if (n != NULL)
6991 n->value |= flags;
6992 else
6993 splay_tree_insert (ctx->variables, (splay_tree_key)decl, flags);
6995 /* For reductions clauses in OpenACC loop directives, by default create a
6996 copy clause on the enclosing parallel construct for carrying back the
6997 results. */
6998 if (ctx->region_type == ORT_ACC && (flags & GOVD_REDUCTION))
7000 struct gimplify_omp_ctx *outer_ctx = ctx->outer_context;
7001 while (outer_ctx)
7003 n = splay_tree_lookup (outer_ctx->variables, (splay_tree_key)decl);
7004 if (n != NULL)
7006 /* Ignore local variables and explicitly declared clauses. */
7007 if (n->value & (GOVD_LOCAL | GOVD_EXPLICIT))
7008 break;
7009 else if (outer_ctx->region_type == ORT_ACC_KERNELS)
7011 /* According to the OpenACC spec, such a reduction variable
7012 should already have a copy map on a kernels construct,
7013 verify that here. */
7014 gcc_assert (!(n->value & GOVD_FIRSTPRIVATE)
7015 && (n->value & GOVD_MAP));
7017 else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
7019 /* Remove firstprivate and make it a copy map. */
7020 n->value &= ~GOVD_FIRSTPRIVATE;
7021 n->value |= GOVD_MAP;
7024 else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
7026 splay_tree_insert (outer_ctx->variables, (splay_tree_key)decl,
7027 GOVD_MAP | GOVD_SEEN);
7028 break;
7030 outer_ctx = outer_ctx->outer_context;
7035 /* Notice a threadprivate variable DECL used in OMP context CTX.
7036 This just prints out diagnostics about threadprivate variable uses
7037 in untied tasks. If DECL2 is non-NULL, prevent this warning
7038 on that variable. */
7040 static bool
7041 omp_notice_threadprivate_variable (struct gimplify_omp_ctx *ctx, tree decl,
7042 tree decl2)
7044 splay_tree_node n;
7045 struct gimplify_omp_ctx *octx;
7047 for (octx = ctx; octx; octx = octx->outer_context)
7048 if ((octx->region_type & ORT_TARGET) != 0
7049 || octx->order_concurrent)
7051 n = splay_tree_lookup (octx->variables, (splay_tree_key)decl);
7052 if (n == NULL)
7054 if (octx->order_concurrent)
7056 error ("threadprivate variable %qE used in a region with"
7057 " %<order(concurrent)%> clause", DECL_NAME (decl));
7058 error_at (octx->location, "enclosing region");
7060 else
7062 error ("threadprivate variable %qE used in target region",
7063 DECL_NAME (decl));
7064 error_at (octx->location, "enclosing target region");
7066 splay_tree_insert (octx->variables, (splay_tree_key)decl, 0);
7068 if (decl2)
7069 splay_tree_insert (octx->variables, (splay_tree_key)decl2, 0);
7072 if (ctx->region_type != ORT_UNTIED_TASK)
7073 return false;
7074 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7075 if (n == NULL)
7077 error ("threadprivate variable %qE used in untied task",
7078 DECL_NAME (decl));
7079 error_at (ctx->location, "enclosing task");
7080 splay_tree_insert (ctx->variables, (splay_tree_key)decl, 0);
7082 if (decl2)
7083 splay_tree_insert (ctx->variables, (splay_tree_key)decl2, 0);
7084 return false;
7087 /* Return true if global var DECL is device resident. */
7089 static bool
7090 device_resident_p (tree decl)
7092 tree attr = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (decl));
7094 if (!attr)
7095 return false;
7097 for (tree t = TREE_VALUE (attr); t; t = TREE_PURPOSE (t))
7099 tree c = TREE_VALUE (t);
7100 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DEVICE_RESIDENT)
7101 return true;
7104 return false;
7107 /* Return true if DECL has an ACC DECLARE attribute. */
7109 static bool
7110 is_oacc_declared (tree decl)
7112 tree t = TREE_CODE (decl) == MEM_REF ? TREE_OPERAND (decl, 0) : decl;
7113 tree declared = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (t));
7114 return declared != NULL_TREE;
7117 /* Determine outer default flags for DECL mentioned in an OMP region
7118 but not declared in an enclosing clause.
7120 ??? Some compiler-generated variables (like SAVE_EXPRs) could be
7121 remapped firstprivate instead of shared. To some extent this is
7122 addressed in omp_firstprivatize_type_sizes, but not
7123 effectively. */
7125 static unsigned
7126 omp_default_clause (struct gimplify_omp_ctx *ctx, tree decl,
7127 bool in_code, unsigned flags)
7129 enum omp_clause_default_kind default_kind = ctx->default_kind;
7130 enum omp_clause_default_kind kind;
7132 kind = lang_hooks.decls.omp_predetermined_sharing (decl);
7133 if (kind != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
7134 default_kind = kind;
7136 switch (default_kind)
7138 case OMP_CLAUSE_DEFAULT_NONE:
7140 const char *rtype;
7142 if (ctx->region_type & ORT_PARALLEL)
7143 rtype = "parallel";
7144 else if ((ctx->region_type & ORT_TASKLOOP) == ORT_TASKLOOP)
7145 rtype = "taskloop";
7146 else if (ctx->region_type & ORT_TASK)
7147 rtype = "task";
7148 else if (ctx->region_type & ORT_TEAMS)
7149 rtype = "teams";
7150 else
7151 gcc_unreachable ();
7153 error ("%qE not specified in enclosing %qs",
7154 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rtype);
7155 error_at (ctx->location, "enclosing %qs", rtype);
7157 /* FALLTHRU */
7158 case OMP_CLAUSE_DEFAULT_SHARED:
7159 flags |= GOVD_SHARED;
7160 break;
7161 case OMP_CLAUSE_DEFAULT_PRIVATE:
7162 flags |= GOVD_PRIVATE;
7163 break;
7164 case OMP_CLAUSE_DEFAULT_FIRSTPRIVATE:
7165 flags |= GOVD_FIRSTPRIVATE;
7166 break;
7167 case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
7168 /* decl will be either GOVD_FIRSTPRIVATE or GOVD_SHARED. */
7169 gcc_assert ((ctx->region_type & ORT_TASK) != 0);
7170 if (struct gimplify_omp_ctx *octx = ctx->outer_context)
7172 omp_notice_variable (octx, decl, in_code);
7173 for (; octx; octx = octx->outer_context)
7175 splay_tree_node n2;
7177 n2 = splay_tree_lookup (octx->variables, (splay_tree_key) decl);
7178 if ((octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)) != 0
7179 && (n2 == NULL || (n2->value & GOVD_DATA_SHARE_CLASS) == 0))
7180 continue;
7181 if (n2 && (n2->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED)
7183 flags |= GOVD_FIRSTPRIVATE;
7184 goto found_outer;
7186 if ((octx->region_type & (ORT_PARALLEL | ORT_TEAMS)) != 0)
7188 flags |= GOVD_SHARED;
7189 goto found_outer;
7194 if (TREE_CODE (decl) == PARM_DECL
7195 || (!is_global_var (decl)
7196 && DECL_CONTEXT (decl) == current_function_decl))
7197 flags |= GOVD_FIRSTPRIVATE;
7198 else
7199 flags |= GOVD_SHARED;
7200 found_outer:
7201 break;
7203 default:
7204 gcc_unreachable ();
7207 return flags;
7211 /* Determine outer default flags for DECL mentioned in an OACC region
7212 but not declared in an enclosing clause. */
7214 static unsigned
7215 oacc_default_clause (struct gimplify_omp_ctx *ctx, tree decl, unsigned flags)
7217 const char *rkind;
7218 bool on_device = false;
7219 bool declared = is_oacc_declared (decl);
7220 tree type = TREE_TYPE (decl);
7222 if (lang_hooks.decls.omp_privatize_by_reference (decl))
7223 type = TREE_TYPE (type);
7225 if ((ctx->region_type & (ORT_ACC_PARALLEL | ORT_ACC_KERNELS)) != 0
7226 && is_global_var (decl)
7227 && device_resident_p (decl))
7229 on_device = true;
7230 flags |= GOVD_MAP_TO_ONLY;
7233 switch (ctx->region_type)
7235 case ORT_ACC_KERNELS:
7236 rkind = "kernels";
7238 if (AGGREGATE_TYPE_P (type))
7240 /* Aggregates default to 'present_or_copy', or 'present'. */
7241 if (ctx->default_kind != OMP_CLAUSE_DEFAULT_PRESENT)
7242 flags |= GOVD_MAP;
7243 else
7244 flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
7246 else
7247 /* Scalars default to 'copy'. */
7248 flags |= GOVD_MAP | GOVD_MAP_FORCE;
7250 break;
7252 case ORT_ACC_PARALLEL:
7253 rkind = "parallel";
7255 if (on_device || declared)
7256 flags |= GOVD_MAP;
7257 else if (AGGREGATE_TYPE_P (type))
7259 /* Aggregates default to 'present_or_copy', or 'present'. */
7260 if (ctx->default_kind != OMP_CLAUSE_DEFAULT_PRESENT)
7261 flags |= GOVD_MAP;
7262 else
7263 flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
7265 else
7266 /* Scalars default to 'firstprivate'. */
7267 flags |= GOVD_FIRSTPRIVATE;
7269 break;
7271 default:
7272 gcc_unreachable ();
7275 if (DECL_ARTIFICIAL (decl))
7276 ; /* We can get compiler-generated decls, and should not complain
7277 about them. */
7278 else if (ctx->default_kind == OMP_CLAUSE_DEFAULT_NONE)
7280 error ("%qE not specified in enclosing OpenACC %qs construct",
7281 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rkind);
7282 inform (ctx->location, "enclosing OpenACC %qs construct", rkind);
7284 else if (ctx->default_kind == OMP_CLAUSE_DEFAULT_PRESENT)
7285 ; /* Handled above. */
7286 else
7287 gcc_checking_assert (ctx->default_kind == OMP_CLAUSE_DEFAULT_SHARED);
7289 return flags;
7292 /* Record the fact that DECL was used within the OMP context CTX.
7293 IN_CODE is true when real code uses DECL, and false when we should
7294 merely emit default(none) errors. Return true if DECL is going to
7295 be remapped and thus DECL shouldn't be gimplified into its
7296 DECL_VALUE_EXPR (if any). */
7298 static bool
7299 omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
7301 splay_tree_node n;
7302 unsigned flags = in_code ? GOVD_SEEN : 0;
7303 bool ret = false, shared;
7305 if (error_operand_p (decl))
7306 return false;
7308 if (ctx->region_type == ORT_NONE)
7309 return lang_hooks.decls.omp_disregard_value_expr (decl, false);
7311 if (is_global_var (decl))
7313 /* Threadprivate variables are predetermined. */
7314 if (DECL_THREAD_LOCAL_P (decl))
7315 return omp_notice_threadprivate_variable (ctx, decl, NULL_TREE);
7317 if (DECL_HAS_VALUE_EXPR_P (decl))
7319 tree value = get_base_address (DECL_VALUE_EXPR (decl));
7321 if (value && DECL_P (value) && DECL_THREAD_LOCAL_P (value))
7322 return omp_notice_threadprivate_variable (ctx, decl, value);
7325 if (gimplify_omp_ctxp->outer_context == NULL
7326 && VAR_P (decl)
7327 && oacc_get_fn_attrib (current_function_decl))
7329 location_t loc = DECL_SOURCE_LOCATION (decl);
7331 if (lookup_attribute ("omp declare target link",
7332 DECL_ATTRIBUTES (decl)))
7334 error_at (loc,
7335 "%qE with %<link%> clause used in %<routine%> function",
7336 DECL_NAME (decl));
7337 return false;
7339 else if (!lookup_attribute ("omp declare target",
7340 DECL_ATTRIBUTES (decl)))
7342 error_at (loc,
7343 "%qE requires a %<declare%> directive for use "
7344 "in a %<routine%> function", DECL_NAME (decl));
7345 return false;
7350 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7351 if ((ctx->region_type & ORT_TARGET) != 0)
7353 ret = lang_hooks.decls.omp_disregard_value_expr (decl, true);
7354 if (n == NULL)
7356 unsigned nflags = flags;
7357 if ((ctx->region_type & ORT_ACC) == 0)
7359 bool is_declare_target = false;
7360 if (is_global_var (decl)
7361 && varpool_node::get_create (decl)->offloadable)
7363 struct gimplify_omp_ctx *octx;
7364 for (octx = ctx->outer_context;
7365 octx; octx = octx->outer_context)
7367 n = splay_tree_lookup (octx->variables,
7368 (splay_tree_key)decl);
7369 if (n
7370 && (n->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED
7371 && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
7372 break;
7374 is_declare_target = octx == NULL;
7376 if (!is_declare_target)
7378 int gdmk;
7379 if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
7380 || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
7381 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
7382 == POINTER_TYPE)))
7383 gdmk = GDMK_POINTER;
7384 else if (lang_hooks.decls.omp_scalar_p (decl))
7385 gdmk = GDMK_SCALAR;
7386 else
7387 gdmk = GDMK_AGGREGATE;
7388 if (ctx->defaultmap[gdmk] == 0)
7390 tree d = lang_hooks.decls.omp_report_decl (decl);
7391 error ("%qE not specified in enclosing %<target%>",
7392 DECL_NAME (d));
7393 error_at (ctx->location, "enclosing %<target%>");
7395 else if (ctx->defaultmap[gdmk]
7396 & (GOVD_MAP_0LEN_ARRAY | GOVD_FIRSTPRIVATE))
7397 nflags |= ctx->defaultmap[gdmk];
7398 else
7400 gcc_assert (ctx->defaultmap[gdmk] & GOVD_MAP);
7401 nflags |= ctx->defaultmap[gdmk] & ~GOVD_MAP;
7406 struct gimplify_omp_ctx *octx = ctx->outer_context;
7407 if ((ctx->region_type & ORT_ACC) && octx)
7409 /* Look in outer OpenACC contexts, to see if there's a
7410 data attribute for this variable. */
7411 omp_notice_variable (octx, decl, in_code);
7413 for (; octx; octx = octx->outer_context)
7415 if (!(octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)))
7416 break;
7417 splay_tree_node n2
7418 = splay_tree_lookup (octx->variables,
7419 (splay_tree_key) decl);
7420 if (n2)
7422 if (octx->region_type == ORT_ACC_HOST_DATA)
7423 error ("variable %qE declared in enclosing "
7424 "%<host_data%> region", DECL_NAME (decl));
7425 nflags |= GOVD_MAP;
7426 if (octx->region_type == ORT_ACC_DATA
7427 && (n2->value & GOVD_MAP_0LEN_ARRAY))
7428 nflags |= GOVD_MAP_0LEN_ARRAY;
7429 goto found_outer;
7434 if ((nflags & ~(GOVD_MAP_TO_ONLY | GOVD_MAP_FROM_ONLY
7435 | GOVD_MAP_ALLOC_ONLY)) == flags)
7437 tree type = TREE_TYPE (decl);
7439 if (gimplify_omp_ctxp->target_firstprivatize_array_bases
7440 && lang_hooks.decls.omp_privatize_by_reference (decl))
7441 type = TREE_TYPE (type);
7442 if (!lang_hooks.types.omp_mappable_type (type))
7444 error ("%qD referenced in target region does not have "
7445 "a mappable type", decl);
7446 nflags |= GOVD_MAP | GOVD_EXPLICIT;
7448 else
7450 if ((ctx->region_type & ORT_ACC) != 0)
7451 nflags = oacc_default_clause (ctx, decl, flags);
7452 else
7453 nflags |= GOVD_MAP;
7456 found_outer:
7457 omp_add_variable (ctx, decl, nflags);
7459 else
7461 /* If nothing changed, there's nothing left to do. */
7462 if ((n->value & flags) == flags)
7463 return ret;
7464 flags |= n->value;
7465 n->value = flags;
7467 goto do_outer;
7470 if (n == NULL)
7472 if (ctx->region_type == ORT_WORKSHARE
7473 || ctx->region_type == ORT_TASKGROUP
7474 || ctx->region_type == ORT_SIMD
7475 || ctx->region_type == ORT_ACC
7476 || (ctx->region_type & ORT_TARGET_DATA) != 0)
7477 goto do_outer;
7479 flags = omp_default_clause (ctx, decl, in_code, flags);
7481 if ((flags & GOVD_PRIVATE)
7482 && lang_hooks.decls.omp_private_outer_ref (decl))
7483 flags |= GOVD_PRIVATE_OUTER_REF;
7485 omp_add_variable (ctx, decl, flags);
7487 shared = (flags & GOVD_SHARED) != 0;
7488 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7489 goto do_outer;
7492 if ((n->value & (GOVD_SEEN | GOVD_LOCAL)) == 0
7493 && (flags & (GOVD_SEEN | GOVD_LOCAL)) == GOVD_SEEN
7494 && DECL_SIZE (decl))
7496 if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
7498 splay_tree_node n2;
7499 tree t = DECL_VALUE_EXPR (decl);
7500 gcc_assert (TREE_CODE (t) == INDIRECT_REF);
7501 t = TREE_OPERAND (t, 0);
7502 gcc_assert (DECL_P (t));
7503 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
7504 n2->value |= GOVD_SEEN;
7506 else if (lang_hooks.decls.omp_privatize_by_reference (decl)
7507 && TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)))
7508 && (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))))
7509 != INTEGER_CST))
7511 splay_tree_node n2;
7512 tree t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
7513 gcc_assert (DECL_P (t));
7514 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
7515 if (n2)
7516 omp_notice_variable (ctx, t, true);
7520 shared = ((flags | n->value) & GOVD_SHARED) != 0;
7521 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7523 /* If nothing changed, there's nothing left to do. */
7524 if ((n->value & flags) == flags)
7525 return ret;
7526 flags |= n->value;
7527 n->value = flags;
7529 do_outer:
7530 /* If the variable is private in the current context, then we don't
7531 need to propagate anything to an outer context. */
7532 if ((flags & GOVD_PRIVATE) && !(flags & GOVD_PRIVATE_OUTER_REF))
7533 return ret;
7534 if ((flags & (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7535 == (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7536 return ret;
7537 if ((flags & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
7538 | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7539 == (GOVD_LASTPRIVATE | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7540 return ret;
7541 if (ctx->outer_context
7542 && omp_notice_variable (ctx->outer_context, decl, in_code))
7543 return true;
7544 return ret;
7547 /* Verify that DECL is private within CTX. If there's specific information
7548 to the contrary in the innermost scope, generate an error. */
7550 static bool
7551 omp_is_private (struct gimplify_omp_ctx *ctx, tree decl, int simd)
7553 splay_tree_node n;
7555 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7556 if (n != NULL)
7558 if (n->value & GOVD_SHARED)
7560 if (ctx == gimplify_omp_ctxp)
7562 if (simd)
7563 error ("iteration variable %qE is predetermined linear",
7564 DECL_NAME (decl));
7565 else
7566 error ("iteration variable %qE should be private",
7567 DECL_NAME (decl));
7568 n->value = GOVD_PRIVATE;
7569 return true;
7571 else
7572 return false;
7574 else if ((n->value & GOVD_EXPLICIT) != 0
7575 && (ctx == gimplify_omp_ctxp
7576 || (ctx->region_type == ORT_COMBINED_PARALLEL
7577 && gimplify_omp_ctxp->outer_context == ctx)))
7579 if ((n->value & GOVD_FIRSTPRIVATE) != 0)
7580 error ("iteration variable %qE should not be firstprivate",
7581 DECL_NAME (decl));
7582 else if ((n->value & GOVD_REDUCTION) != 0)
7583 error ("iteration variable %qE should not be reduction",
7584 DECL_NAME (decl));
7585 else if (simd != 1 && (n->value & GOVD_LINEAR) != 0)
7586 error ("iteration variable %qE should not be linear",
7587 DECL_NAME (decl));
7589 return (ctx == gimplify_omp_ctxp
7590 || (ctx->region_type == ORT_COMBINED_PARALLEL
7591 && gimplify_omp_ctxp->outer_context == ctx));
7594 if (ctx->region_type != ORT_WORKSHARE
7595 && ctx->region_type != ORT_TASKGROUP
7596 && ctx->region_type != ORT_SIMD
7597 && ctx->region_type != ORT_ACC)
7598 return false;
7599 else if (ctx->outer_context)
7600 return omp_is_private (ctx->outer_context, decl, simd);
7601 return false;
7604 /* Return true if DECL is private within a parallel region
7605 that binds to the current construct's context or in parallel
7606 region's REDUCTION clause. */
7608 static bool
7609 omp_check_private (struct gimplify_omp_ctx *ctx, tree decl, bool copyprivate)
7611 splay_tree_node n;
7615 ctx = ctx->outer_context;
7616 if (ctx == NULL)
7618 if (is_global_var (decl))
7619 return false;
7621 /* References might be private, but might be shared too,
7622 when checking for copyprivate, assume they might be
7623 private, otherwise assume they might be shared. */
7624 if (copyprivate)
7625 return true;
7627 if (lang_hooks.decls.omp_privatize_by_reference (decl))
7628 return false;
7630 /* Treat C++ privatized non-static data members outside
7631 of the privatization the same. */
7632 if (omp_member_access_dummy_var (decl))
7633 return false;
7635 return true;
7638 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
7640 if ((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
7641 && (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0))
7642 continue;
7644 if (n != NULL)
7646 if ((n->value & GOVD_LOCAL) != 0
7647 && omp_member_access_dummy_var (decl))
7648 return false;
7649 return (n->value & GOVD_SHARED) == 0;
7652 while (ctx->region_type == ORT_WORKSHARE
7653 || ctx->region_type == ORT_TASKGROUP
7654 || ctx->region_type == ORT_SIMD
7655 || ctx->region_type == ORT_ACC);
7656 return false;
7659 /* Callback for walk_tree to find a DECL_EXPR for the given DECL. */
7661 static tree
7662 find_decl_expr (tree *tp, int *walk_subtrees, void *data)
7664 tree t = *tp;
7666 /* If this node has been visited, unmark it and keep looking. */
7667 if (TREE_CODE (t) == DECL_EXPR && DECL_EXPR_DECL (t) == (tree) data)
7668 return t;
7670 if (IS_TYPE_OR_DECL_P (t))
7671 *walk_subtrees = 0;
7672 return NULL_TREE;
7675 /* If *LIST_P contains any OpenMP depend clauses with iterators,
7676 lower all the depend clauses by populating corresponding depend
7677 array. Returns 0 if there are no such depend clauses, or
7678 2 if all depend clauses should be removed, 1 otherwise. */
7680 static int
7681 gimplify_omp_depend (tree *list_p, gimple_seq *pre_p)
7683 tree c;
7684 gimple *g;
7685 size_t n[4] = { 0, 0, 0, 0 };
7686 bool unused[4];
7687 tree counts[4] = { NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE };
7688 tree last_iter = NULL_TREE, last_count = NULL_TREE;
7689 size_t i, j;
7690 location_t first_loc = UNKNOWN_LOCATION;
7692 for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
7693 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
7695 switch (OMP_CLAUSE_DEPEND_KIND (c))
7697 case OMP_CLAUSE_DEPEND_IN:
7698 i = 2;
7699 break;
7700 case OMP_CLAUSE_DEPEND_OUT:
7701 case OMP_CLAUSE_DEPEND_INOUT:
7702 i = 0;
7703 break;
7704 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
7705 i = 1;
7706 break;
7707 case OMP_CLAUSE_DEPEND_DEPOBJ:
7708 i = 3;
7709 break;
7710 case OMP_CLAUSE_DEPEND_SOURCE:
7711 case OMP_CLAUSE_DEPEND_SINK:
7712 continue;
7713 default:
7714 gcc_unreachable ();
7716 tree t = OMP_CLAUSE_DECL (c);
7717 if (first_loc == UNKNOWN_LOCATION)
7718 first_loc = OMP_CLAUSE_LOCATION (c);
7719 if (TREE_CODE (t) == TREE_LIST
7720 && TREE_PURPOSE (t)
7721 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
7723 if (TREE_PURPOSE (t) != last_iter)
7725 tree tcnt = size_one_node;
7726 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
7728 if (gimplify_expr (&TREE_VEC_ELT (it, 1), pre_p, NULL,
7729 is_gimple_val, fb_rvalue) == GS_ERROR
7730 || gimplify_expr (&TREE_VEC_ELT (it, 2), pre_p, NULL,
7731 is_gimple_val, fb_rvalue) == GS_ERROR
7732 || gimplify_expr (&TREE_VEC_ELT (it, 3), pre_p, NULL,
7733 is_gimple_val, fb_rvalue) == GS_ERROR
7734 || (gimplify_expr (&TREE_VEC_ELT (it, 4), pre_p, NULL,
7735 is_gimple_val, fb_rvalue)
7736 == GS_ERROR))
7737 return 2;
7738 tree var = TREE_VEC_ELT (it, 0);
7739 tree begin = TREE_VEC_ELT (it, 1);
7740 tree end = TREE_VEC_ELT (it, 2);
7741 tree step = TREE_VEC_ELT (it, 3);
7742 tree orig_step = TREE_VEC_ELT (it, 4);
7743 tree type = TREE_TYPE (var);
7744 tree stype = TREE_TYPE (step);
7745 location_t loc = DECL_SOURCE_LOCATION (var);
7746 tree endmbegin;
7747 /* Compute count for this iterator as
7748 orig_step > 0
7749 ? (begin < end ? (end - begin + (step - 1)) / step : 0)
7750 : (begin > end ? (end - begin + (step + 1)) / step : 0)
7751 and compute product of those for the entire depend
7752 clause. */
7753 if (POINTER_TYPE_P (type))
7754 endmbegin = fold_build2_loc (loc, POINTER_DIFF_EXPR,
7755 stype, end, begin);
7756 else
7757 endmbegin = fold_build2_loc (loc, MINUS_EXPR, type,
7758 end, begin);
7759 tree stepm1 = fold_build2_loc (loc, MINUS_EXPR, stype,
7760 step,
7761 build_int_cst (stype, 1));
7762 tree stepp1 = fold_build2_loc (loc, PLUS_EXPR, stype, step,
7763 build_int_cst (stype, 1));
7764 tree pos = fold_build2_loc (loc, PLUS_EXPR, stype,
7765 unshare_expr (endmbegin),
7766 stepm1);
7767 pos = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype,
7768 pos, step);
7769 tree neg = fold_build2_loc (loc, PLUS_EXPR, stype,
7770 endmbegin, stepp1);
7771 if (TYPE_UNSIGNED (stype))
7773 neg = fold_build1_loc (loc, NEGATE_EXPR, stype, neg);
7774 step = fold_build1_loc (loc, NEGATE_EXPR, stype, step);
7776 neg = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype,
7777 neg, step);
7778 step = NULL_TREE;
7779 tree cond = fold_build2_loc (loc, LT_EXPR,
7780 boolean_type_node,
7781 begin, end);
7782 pos = fold_build3_loc (loc, COND_EXPR, stype, cond, pos,
7783 build_int_cst (stype, 0));
7784 cond = fold_build2_loc (loc, LT_EXPR, boolean_type_node,
7785 end, begin);
7786 neg = fold_build3_loc (loc, COND_EXPR, stype, cond, neg,
7787 build_int_cst (stype, 0));
7788 tree osteptype = TREE_TYPE (orig_step);
7789 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
7790 orig_step,
7791 build_int_cst (osteptype, 0));
7792 tree cnt = fold_build3_loc (loc, COND_EXPR, stype,
7793 cond, pos, neg);
7794 cnt = fold_convert_loc (loc, sizetype, cnt);
7795 if (gimplify_expr (&cnt, pre_p, NULL, is_gimple_val,
7796 fb_rvalue) == GS_ERROR)
7797 return 2;
7798 tcnt = size_binop_loc (loc, MULT_EXPR, tcnt, cnt);
7800 if (gimplify_expr (&tcnt, pre_p, NULL, is_gimple_val,
7801 fb_rvalue) == GS_ERROR)
7802 return 2;
7803 last_iter = TREE_PURPOSE (t);
7804 last_count = tcnt;
7806 if (counts[i] == NULL_TREE)
7807 counts[i] = last_count;
7808 else
7809 counts[i] = size_binop_loc (OMP_CLAUSE_LOCATION (c),
7810 PLUS_EXPR, counts[i], last_count);
7812 else
7813 n[i]++;
7815 for (i = 0; i < 4; i++)
7816 if (counts[i])
7817 break;
7818 if (i == 4)
7819 return 0;
7821 tree total = size_zero_node;
7822 for (i = 0; i < 4; i++)
7824 unused[i] = counts[i] == NULL_TREE && n[i] == 0;
7825 if (counts[i] == NULL_TREE)
7826 counts[i] = size_zero_node;
7827 if (n[i])
7828 counts[i] = size_binop (PLUS_EXPR, counts[i], size_int (n[i]));
7829 if (gimplify_expr (&counts[i], pre_p, NULL, is_gimple_val,
7830 fb_rvalue) == GS_ERROR)
7831 return 2;
7832 total = size_binop (PLUS_EXPR, total, counts[i]);
7835 if (gimplify_expr (&total, pre_p, NULL, is_gimple_val, fb_rvalue)
7836 == GS_ERROR)
7837 return 2;
7838 bool is_old = unused[1] && unused[3];
7839 tree totalpx = size_binop (PLUS_EXPR, unshare_expr (total),
7840 size_int (is_old ? 1 : 4));
7841 tree type = build_array_type (ptr_type_node, build_index_type (totalpx));
7842 tree array = create_tmp_var_raw (type);
7843 TREE_ADDRESSABLE (array) = 1;
7844 if (TREE_CODE (totalpx) != INTEGER_CST)
7846 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (array)))
7847 gimplify_type_sizes (TREE_TYPE (array), pre_p);
7848 if (gimplify_omp_ctxp)
7850 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
7851 while (ctx
7852 && (ctx->region_type == ORT_WORKSHARE
7853 || ctx->region_type == ORT_TASKGROUP
7854 || ctx->region_type == ORT_SIMD
7855 || ctx->region_type == ORT_ACC))
7856 ctx = ctx->outer_context;
7857 if (ctx)
7858 omp_add_variable (ctx, array, GOVD_LOCAL | GOVD_SEEN);
7860 gimplify_vla_decl (array, pre_p);
7862 else
7863 gimple_add_tmp_var (array);
7864 tree r = build4 (ARRAY_REF, ptr_type_node, array, size_int (0), NULL_TREE,
7865 NULL_TREE);
7866 tree tem;
7867 if (!is_old)
7869 tem = build2 (MODIFY_EXPR, void_type_node, r,
7870 build_int_cst (ptr_type_node, 0));
7871 gimplify_and_add (tem, pre_p);
7872 r = build4 (ARRAY_REF, ptr_type_node, array, size_int (1), NULL_TREE,
7873 NULL_TREE);
7875 tem = build2 (MODIFY_EXPR, void_type_node, r,
7876 fold_convert (ptr_type_node, total));
7877 gimplify_and_add (tem, pre_p);
7878 for (i = 1; i < (is_old ? 2 : 4); i++)
7880 r = build4 (ARRAY_REF, ptr_type_node, array, size_int (i + !is_old),
7881 NULL_TREE, NULL_TREE);
7882 tem = build2 (MODIFY_EXPR, void_type_node, r, counts[i - 1]);
7883 gimplify_and_add (tem, pre_p);
7886 tree cnts[4];
7887 for (j = 4; j; j--)
7888 if (!unused[j - 1])
7889 break;
7890 for (i = 0; i < 4; i++)
7892 if (i && (i >= j || unused[i - 1]))
7894 cnts[i] = cnts[i - 1];
7895 continue;
7897 cnts[i] = create_tmp_var (sizetype);
7898 if (i == 0)
7899 g = gimple_build_assign (cnts[i], size_int (is_old ? 2 : 5));
7900 else
7902 tree t;
7903 if (is_old)
7904 t = size_binop (PLUS_EXPR, counts[0], size_int (2));
7905 else
7906 t = size_binop (PLUS_EXPR, cnts[i - 1], counts[i - 1]);
7907 if (gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue)
7908 == GS_ERROR)
7909 return 2;
7910 g = gimple_build_assign (cnts[i], t);
7912 gimple_seq_add_stmt (pre_p, g);
7915 last_iter = NULL_TREE;
7916 tree last_bind = NULL_TREE;
7917 tree *last_body = NULL;
7918 for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
7919 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
7921 switch (OMP_CLAUSE_DEPEND_KIND (c))
7923 case OMP_CLAUSE_DEPEND_IN:
7924 i = 2;
7925 break;
7926 case OMP_CLAUSE_DEPEND_OUT:
7927 case OMP_CLAUSE_DEPEND_INOUT:
7928 i = 0;
7929 break;
7930 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
7931 i = 1;
7932 break;
7933 case OMP_CLAUSE_DEPEND_DEPOBJ:
7934 i = 3;
7935 break;
7936 case OMP_CLAUSE_DEPEND_SOURCE:
7937 case OMP_CLAUSE_DEPEND_SINK:
7938 continue;
7939 default:
7940 gcc_unreachable ();
7942 tree t = OMP_CLAUSE_DECL (c);
7943 if (TREE_CODE (t) == TREE_LIST
7944 && TREE_PURPOSE (t)
7945 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
7947 if (TREE_PURPOSE (t) != last_iter)
7949 if (last_bind)
7950 gimplify_and_add (last_bind, pre_p);
7951 tree block = TREE_VEC_ELT (TREE_PURPOSE (t), 5);
7952 last_bind = build3 (BIND_EXPR, void_type_node,
7953 BLOCK_VARS (block), NULL, block);
7954 TREE_SIDE_EFFECTS (last_bind) = 1;
7955 SET_EXPR_LOCATION (last_bind, OMP_CLAUSE_LOCATION (c));
7956 tree *p = &BIND_EXPR_BODY (last_bind);
7957 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
7959 tree var = TREE_VEC_ELT (it, 0);
7960 tree begin = TREE_VEC_ELT (it, 1);
7961 tree end = TREE_VEC_ELT (it, 2);
7962 tree step = TREE_VEC_ELT (it, 3);
7963 tree orig_step = TREE_VEC_ELT (it, 4);
7964 tree type = TREE_TYPE (var);
7965 location_t loc = DECL_SOURCE_LOCATION (var);
7966 /* Emit:
7967 var = begin;
7968 goto cond_label;
7969 beg_label:
7971 var = var + step;
7972 cond_label:
7973 if (orig_step > 0) {
7974 if (var < end) goto beg_label;
7975 } else {
7976 if (var > end) goto beg_label;
7978 for each iterator, with inner iterators added to
7979 the ... above. */
7980 tree beg_label = create_artificial_label (loc);
7981 tree cond_label = NULL_TREE;
7982 tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
7983 var, begin);
7984 append_to_statement_list_force (tem, p);
7985 tem = build_and_jump (&cond_label);
7986 append_to_statement_list_force (tem, p);
7987 tem = build1 (LABEL_EXPR, void_type_node, beg_label);
7988 append_to_statement_list (tem, p);
7989 tree bind = build3 (BIND_EXPR, void_type_node, NULL_TREE,
7990 NULL_TREE, NULL_TREE);
7991 TREE_SIDE_EFFECTS (bind) = 1;
7992 SET_EXPR_LOCATION (bind, loc);
7993 append_to_statement_list_force (bind, p);
7994 if (POINTER_TYPE_P (type))
7995 tem = build2_loc (loc, POINTER_PLUS_EXPR, type,
7996 var, fold_convert_loc (loc, sizetype,
7997 step));
7998 else
7999 tem = build2_loc (loc, PLUS_EXPR, type, var, step);
8000 tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
8001 var, tem);
8002 append_to_statement_list_force (tem, p);
8003 tem = build1 (LABEL_EXPR, void_type_node, cond_label);
8004 append_to_statement_list (tem, p);
8005 tree cond = fold_build2_loc (loc, LT_EXPR,
8006 boolean_type_node,
8007 var, end);
8008 tree pos
8009 = fold_build3_loc (loc, COND_EXPR, void_type_node,
8010 cond, build_and_jump (&beg_label),
8011 void_node);
8012 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8013 var, end);
8014 tree neg
8015 = fold_build3_loc (loc, COND_EXPR, void_type_node,
8016 cond, build_and_jump (&beg_label),
8017 void_node);
8018 tree osteptype = TREE_TYPE (orig_step);
8019 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8020 orig_step,
8021 build_int_cst (osteptype, 0));
8022 tem = fold_build3_loc (loc, COND_EXPR, void_type_node,
8023 cond, pos, neg);
8024 append_to_statement_list_force (tem, p);
8025 p = &BIND_EXPR_BODY (bind);
8027 last_body = p;
8029 last_iter = TREE_PURPOSE (t);
8030 if (TREE_CODE (TREE_VALUE (t)) == COMPOUND_EXPR)
8032 append_to_statement_list (TREE_OPERAND (TREE_VALUE (t),
8033 0), last_body);
8034 TREE_VALUE (t) = TREE_OPERAND (TREE_VALUE (t), 1);
8036 if (error_operand_p (TREE_VALUE (t)))
8037 return 2;
8038 TREE_VALUE (t) = build_fold_addr_expr (TREE_VALUE (t));
8039 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
8040 NULL_TREE, NULL_TREE);
8041 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
8042 void_type_node, r, TREE_VALUE (t));
8043 append_to_statement_list_force (tem, last_body);
8044 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
8045 void_type_node, cnts[i],
8046 size_binop (PLUS_EXPR, cnts[i], size_int (1)));
8047 append_to_statement_list_force (tem, last_body);
8048 TREE_VALUE (t) = null_pointer_node;
8050 else
8052 if (last_bind)
8054 gimplify_and_add (last_bind, pre_p);
8055 last_bind = NULL_TREE;
8057 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
8059 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
8060 NULL, is_gimple_val, fb_rvalue);
8061 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
8063 if (error_operand_p (OMP_CLAUSE_DECL (c)))
8064 return 2;
8065 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
8066 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
8067 is_gimple_val, fb_rvalue) == GS_ERROR)
8068 return 2;
8069 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
8070 NULL_TREE, NULL_TREE);
8071 tem = build2 (MODIFY_EXPR, void_type_node, r, OMP_CLAUSE_DECL (c));
8072 gimplify_and_add (tem, pre_p);
8073 g = gimple_build_assign (cnts[i], size_binop (PLUS_EXPR, cnts[i],
8074 size_int (1)));
8075 gimple_seq_add_stmt (pre_p, g);
8078 if (last_bind)
8079 gimplify_and_add (last_bind, pre_p);
8080 tree cond = boolean_false_node;
8081 if (is_old)
8083 if (!unused[0])
8084 cond = build2_loc (first_loc, NE_EXPR, boolean_type_node, cnts[0],
8085 size_binop_loc (first_loc, PLUS_EXPR, counts[0],
8086 size_int (2)));
8087 if (!unused[2])
8088 cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond,
8089 build2_loc (first_loc, NE_EXPR, boolean_type_node,
8090 cnts[2],
8091 size_binop_loc (first_loc, PLUS_EXPR,
8092 totalpx,
8093 size_int (1))));
8095 else
8097 tree prev = size_int (5);
8098 for (i = 0; i < 4; i++)
8100 if (unused[i])
8101 continue;
8102 prev = size_binop_loc (first_loc, PLUS_EXPR, counts[i], prev);
8103 cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond,
8104 build2_loc (first_loc, NE_EXPR, boolean_type_node,
8105 cnts[i], unshare_expr (prev)));
8108 tem = build3_loc (first_loc, COND_EXPR, void_type_node, cond,
8109 build_call_expr_loc (first_loc,
8110 builtin_decl_explicit (BUILT_IN_TRAP),
8111 0), void_node);
8112 gimplify_and_add (tem, pre_p);
8113 c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_DEPEND);
8114 OMP_CLAUSE_DEPEND_KIND (c) = OMP_CLAUSE_DEPEND_LAST;
8115 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (array);
8116 OMP_CLAUSE_CHAIN (c) = *list_p;
8117 *list_p = c;
8118 return 1;
8121 /* Scan the OMP clauses in *LIST_P, installing mappings into a new
8122 and previous omp contexts. */
8124 static void
8125 gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
8126 enum omp_region_type region_type,
8127 enum tree_code code)
8129 struct gimplify_omp_ctx *ctx, *outer_ctx;
8130 tree c;
8131 hash_map<tree, tree> *struct_map_to_clause = NULL;
8132 tree *prev_list_p = NULL, *orig_list_p = list_p;
8133 int handled_depend_iterators = -1;
8134 int nowait = -1;
8136 ctx = new_omp_context (region_type);
8137 outer_ctx = ctx->outer_context;
8138 if (code == OMP_TARGET)
8140 if (!lang_GNU_Fortran ())
8141 ctx->defaultmap[GDMK_POINTER] = GOVD_MAP | GOVD_MAP_0LEN_ARRAY;
8142 ctx->defaultmap[GDMK_SCALAR] = GOVD_FIRSTPRIVATE;
8144 if (!lang_GNU_Fortran ())
8145 switch (code)
8147 case OMP_TARGET:
8148 case OMP_TARGET_DATA:
8149 case OMP_TARGET_ENTER_DATA:
8150 case OMP_TARGET_EXIT_DATA:
8151 case OACC_DECLARE:
8152 case OACC_HOST_DATA:
8153 case OACC_PARALLEL:
8154 case OACC_KERNELS:
8155 ctx->target_firstprivatize_array_bases = true;
8156 default:
8157 break;
8160 while ((c = *list_p) != NULL)
8162 bool remove = false;
8163 bool notice_outer = true;
8164 const char *check_non_private = NULL;
8165 unsigned int flags;
8166 tree decl;
8168 switch (OMP_CLAUSE_CODE (c))
8170 case OMP_CLAUSE_PRIVATE:
8171 flags = GOVD_PRIVATE | GOVD_EXPLICIT;
8172 if (lang_hooks.decls.omp_private_outer_ref (OMP_CLAUSE_DECL (c)))
8174 flags |= GOVD_PRIVATE_OUTER_REF;
8175 OMP_CLAUSE_PRIVATE_OUTER_REF (c) = 1;
8177 else
8178 notice_outer = false;
8179 goto do_add;
8180 case OMP_CLAUSE_SHARED:
8181 flags = GOVD_SHARED | GOVD_EXPLICIT;
8182 goto do_add;
8183 case OMP_CLAUSE_FIRSTPRIVATE:
8184 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
8185 check_non_private = "firstprivate";
8186 goto do_add;
8187 case OMP_CLAUSE_LASTPRIVATE:
8188 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
8189 switch (code)
8191 case OMP_DISTRIBUTE:
8192 error_at (OMP_CLAUSE_LOCATION (c),
8193 "conditional %<lastprivate%> clause on "
8194 "%qs construct", "distribute");
8195 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
8196 break;
8197 case OMP_TASKLOOP:
8198 error_at (OMP_CLAUSE_LOCATION (c),
8199 "conditional %<lastprivate%> clause on "
8200 "%qs construct", "taskloop");
8201 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
8202 break;
8203 default:
8204 break;
8206 flags = GOVD_LASTPRIVATE | GOVD_SEEN | GOVD_EXPLICIT;
8207 if (code != OMP_LOOP)
8208 check_non_private = "lastprivate";
8209 decl = OMP_CLAUSE_DECL (c);
8210 if (error_operand_p (decl))
8211 goto do_add;
8212 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)
8213 && !lang_hooks.decls.omp_scalar_p (decl))
8215 error_at (OMP_CLAUSE_LOCATION (c),
8216 "non-scalar variable %qD in conditional "
8217 "%<lastprivate%> clause", decl);
8218 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
8220 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
8221 flags |= GOVD_LASTPRIVATE_CONDITIONAL;
8222 if (outer_ctx
8223 && (outer_ctx->region_type == ORT_COMBINED_PARALLEL
8224 || ((outer_ctx->region_type & ORT_COMBINED_TEAMS)
8225 == ORT_COMBINED_TEAMS))
8226 && splay_tree_lookup (outer_ctx->variables,
8227 (splay_tree_key) decl) == NULL)
8229 omp_add_variable (outer_ctx, decl, GOVD_SHARED | GOVD_SEEN);
8230 if (outer_ctx->outer_context)
8231 omp_notice_variable (outer_ctx->outer_context, decl, true);
8233 else if (outer_ctx
8234 && (outer_ctx->region_type & ORT_TASK) != 0
8235 && outer_ctx->combined_loop
8236 && splay_tree_lookup (outer_ctx->variables,
8237 (splay_tree_key) decl) == NULL)
8239 omp_add_variable (outer_ctx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
8240 if (outer_ctx->outer_context)
8241 omp_notice_variable (outer_ctx->outer_context, decl, true);
8243 else if (outer_ctx
8244 && (outer_ctx->region_type == ORT_WORKSHARE
8245 || outer_ctx->region_type == ORT_ACC)
8246 && outer_ctx->combined_loop
8247 && splay_tree_lookup (outer_ctx->variables,
8248 (splay_tree_key) decl) == NULL
8249 && !omp_check_private (outer_ctx, decl, false))
8251 omp_add_variable (outer_ctx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
8252 if (outer_ctx->outer_context
8253 && (outer_ctx->outer_context->region_type
8254 == ORT_COMBINED_PARALLEL)
8255 && splay_tree_lookup (outer_ctx->outer_context->variables,
8256 (splay_tree_key) decl) == NULL)
8258 struct gimplify_omp_ctx *octx = outer_ctx->outer_context;
8259 omp_add_variable (octx, decl, GOVD_SHARED | GOVD_SEEN);
8260 if (octx->outer_context)
8262 octx = octx->outer_context;
8263 if (octx->region_type == ORT_WORKSHARE
8264 && octx->combined_loop
8265 && splay_tree_lookup (octx->variables,
8266 (splay_tree_key) decl) == NULL
8267 && !omp_check_private (octx, decl, false))
8269 omp_add_variable (octx, decl,
8270 GOVD_LASTPRIVATE | GOVD_SEEN);
8271 octx = octx->outer_context;
8272 if (octx
8273 && ((octx->region_type & ORT_COMBINED_TEAMS)
8274 == ORT_COMBINED_TEAMS)
8275 && (splay_tree_lookup (octx->variables,
8276 (splay_tree_key) decl)
8277 == NULL))
8279 omp_add_variable (octx, decl,
8280 GOVD_SHARED | GOVD_SEEN);
8281 octx = octx->outer_context;
8284 if (octx)
8285 omp_notice_variable (octx, decl, true);
8288 else if (outer_ctx->outer_context)
8289 omp_notice_variable (outer_ctx->outer_context, decl, true);
8291 goto do_add;
8292 case OMP_CLAUSE_REDUCTION:
8293 if (OMP_CLAUSE_REDUCTION_TASK (c))
8295 if (region_type == ORT_WORKSHARE)
8297 if (nowait == -1)
8298 nowait = omp_find_clause (*list_p,
8299 OMP_CLAUSE_NOWAIT) != NULL_TREE;
8300 if (nowait
8301 && (outer_ctx == NULL
8302 || outer_ctx->region_type != ORT_COMBINED_PARALLEL))
8304 error_at (OMP_CLAUSE_LOCATION (c),
8305 "%<task%> reduction modifier on a construct "
8306 "with a %<nowait%> clause");
8307 OMP_CLAUSE_REDUCTION_TASK (c) = 0;
8310 else if ((region_type & ORT_PARALLEL) != ORT_PARALLEL)
8312 error_at (OMP_CLAUSE_LOCATION (c),
8313 "invalid %<task%> reduction modifier on construct "
8314 "other than %<parallel%>, %<for%> or %<sections%>");
8315 OMP_CLAUSE_REDUCTION_TASK (c) = 0;
8318 if (OMP_CLAUSE_REDUCTION_INSCAN (c))
8319 switch (code)
8321 case OMP_SECTIONS:
8322 error_at (OMP_CLAUSE_LOCATION (c),
8323 "%<inscan%> %<reduction%> clause on "
8324 "%qs construct", "sections");
8325 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
8326 break;
8327 case OMP_PARALLEL:
8328 error_at (OMP_CLAUSE_LOCATION (c),
8329 "%<inscan%> %<reduction%> clause on "
8330 "%qs construct", "parallel");
8331 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
8332 break;
8333 case OMP_TEAMS:
8334 error_at (OMP_CLAUSE_LOCATION (c),
8335 "%<inscan%> %<reduction%> clause on "
8336 "%qs construct", "teams");
8337 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
8338 break;
8339 case OMP_TASKLOOP:
8340 error_at (OMP_CLAUSE_LOCATION (c),
8341 "%<inscan%> %<reduction%> clause on "
8342 "%qs construct", "taskloop");
8343 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
8344 break;
8345 default:
8346 break;
8348 /* FALLTHRU */
8349 case OMP_CLAUSE_IN_REDUCTION:
8350 case OMP_CLAUSE_TASK_REDUCTION:
8351 flags = GOVD_REDUCTION | GOVD_SEEN | GOVD_EXPLICIT;
8352 /* OpenACC permits reductions on private variables. */
8353 if (!(region_type & ORT_ACC)
8354 /* taskgroup is actually not a worksharing region. */
8355 && code != OMP_TASKGROUP)
8356 check_non_private = omp_clause_code_name[OMP_CLAUSE_CODE (c)];
8357 decl = OMP_CLAUSE_DECL (c);
8358 if (TREE_CODE (decl) == MEM_REF)
8360 tree type = TREE_TYPE (decl);
8361 if (gimplify_expr (&TYPE_MAX_VALUE (TYPE_DOMAIN (type)), pre_p,
8362 NULL, is_gimple_val, fb_rvalue, false)
8363 == GS_ERROR)
8365 remove = true;
8366 break;
8368 tree v = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
8369 if (DECL_P (v))
8371 omp_firstprivatize_variable (ctx, v);
8372 omp_notice_variable (ctx, v, true);
8374 decl = TREE_OPERAND (decl, 0);
8375 if (TREE_CODE (decl) == POINTER_PLUS_EXPR)
8377 if (gimplify_expr (&TREE_OPERAND (decl, 1), pre_p,
8378 NULL, is_gimple_val, fb_rvalue, false)
8379 == GS_ERROR)
8381 remove = true;
8382 break;
8384 v = TREE_OPERAND (decl, 1);
8385 if (DECL_P (v))
8387 omp_firstprivatize_variable (ctx, v);
8388 omp_notice_variable (ctx, v, true);
8390 decl = TREE_OPERAND (decl, 0);
8392 if (TREE_CODE (decl) == ADDR_EXPR
8393 || TREE_CODE (decl) == INDIRECT_REF)
8394 decl = TREE_OPERAND (decl, 0);
8396 goto do_add_decl;
8397 case OMP_CLAUSE_LINEAR:
8398 if (gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c), pre_p, NULL,
8399 is_gimple_val, fb_rvalue) == GS_ERROR)
8401 remove = true;
8402 break;
8404 else
8406 if (code == OMP_SIMD
8407 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
8409 struct gimplify_omp_ctx *octx = outer_ctx;
8410 if (octx
8411 && octx->region_type == ORT_WORKSHARE
8412 && octx->combined_loop
8413 && !octx->distribute)
8415 if (octx->outer_context
8416 && (octx->outer_context->region_type
8417 == ORT_COMBINED_PARALLEL))
8418 octx = octx->outer_context->outer_context;
8419 else
8420 octx = octx->outer_context;
8422 if (octx
8423 && octx->region_type == ORT_WORKSHARE
8424 && octx->combined_loop
8425 && octx->distribute)
8427 error_at (OMP_CLAUSE_LOCATION (c),
8428 "%<linear%> clause for variable other than "
8429 "loop iterator specified on construct "
8430 "combined with %<distribute%>");
8431 remove = true;
8432 break;
8435 /* For combined #pragma omp parallel for simd, need to put
8436 lastprivate and perhaps firstprivate too on the
8437 parallel. Similarly for #pragma omp for simd. */
8438 struct gimplify_omp_ctx *octx = outer_ctx;
8439 decl = NULL_TREE;
8442 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
8443 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
8444 break;
8445 decl = OMP_CLAUSE_DECL (c);
8446 if (error_operand_p (decl))
8448 decl = NULL_TREE;
8449 break;
8451 flags = GOVD_SEEN;
8452 if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c))
8453 flags |= GOVD_FIRSTPRIVATE;
8454 if (!OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
8455 flags |= GOVD_LASTPRIVATE;
8456 if (octx
8457 && octx->region_type == ORT_WORKSHARE
8458 && octx->combined_loop)
8460 if (octx->outer_context
8461 && (octx->outer_context->region_type
8462 == ORT_COMBINED_PARALLEL))
8463 octx = octx->outer_context;
8464 else if (omp_check_private (octx, decl, false))
8465 break;
8467 else if (octx
8468 && (octx->region_type & ORT_TASK) != 0
8469 && octx->combined_loop)
8471 else if (octx
8472 && octx->region_type == ORT_COMBINED_PARALLEL
8473 && ctx->region_type == ORT_WORKSHARE
8474 && octx == outer_ctx)
8475 flags = GOVD_SEEN | GOVD_SHARED;
8476 else if (octx
8477 && ((octx->region_type & ORT_COMBINED_TEAMS)
8478 == ORT_COMBINED_TEAMS))
8479 flags = GOVD_SEEN | GOVD_SHARED;
8480 else if (octx
8481 && octx->region_type == ORT_COMBINED_TARGET)
8483 flags &= ~GOVD_LASTPRIVATE;
8484 if (flags == GOVD_SEEN)
8485 break;
8487 else
8488 break;
8489 splay_tree_node on
8490 = splay_tree_lookup (octx->variables,
8491 (splay_tree_key) decl);
8492 if (on && (on->value & GOVD_DATA_SHARE_CLASS) != 0)
8494 octx = NULL;
8495 break;
8497 omp_add_variable (octx, decl, flags);
8498 if (octx->outer_context == NULL)
8499 break;
8500 octx = octx->outer_context;
8502 while (1);
8503 if (octx
8504 && decl
8505 && (!OMP_CLAUSE_LINEAR_NO_COPYIN (c)
8506 || !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
8507 omp_notice_variable (octx, decl, true);
8509 flags = GOVD_LINEAR | GOVD_EXPLICIT;
8510 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
8511 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
8513 notice_outer = false;
8514 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
8516 goto do_add;
8518 case OMP_CLAUSE_MAP:
8519 decl = OMP_CLAUSE_DECL (c);
8520 if (error_operand_p (decl))
8521 remove = true;
8522 switch (code)
8524 case OMP_TARGET:
8525 break;
8526 case OACC_DATA:
8527 if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
8528 break;
8529 /* FALLTHRU */
8530 case OMP_TARGET_DATA:
8531 case OMP_TARGET_ENTER_DATA:
8532 case OMP_TARGET_EXIT_DATA:
8533 case OACC_ENTER_DATA:
8534 case OACC_EXIT_DATA:
8535 case OACC_HOST_DATA:
8536 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
8537 || (OMP_CLAUSE_MAP_KIND (c)
8538 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
8539 /* For target {,enter ,exit }data only the array slice is
8540 mapped, but not the pointer to it. */
8541 remove = true;
8542 break;
8543 default:
8544 break;
8546 if (remove)
8547 break;
8548 if (DECL_P (decl) && outer_ctx && (region_type & ORT_ACC))
8550 struct gimplify_omp_ctx *octx;
8551 for (octx = outer_ctx; octx; octx = octx->outer_context)
8553 if (octx->region_type != ORT_ACC_HOST_DATA)
8554 break;
8555 splay_tree_node n2
8556 = splay_tree_lookup (octx->variables,
8557 (splay_tree_key) decl);
8558 if (n2)
8559 error_at (OMP_CLAUSE_LOCATION (c), "variable %qE "
8560 "declared in enclosing %<host_data%> region",
8561 DECL_NAME (decl));
8564 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
8565 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
8566 : TYPE_SIZE_UNIT (TREE_TYPE (decl));
8567 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
8568 NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
8570 remove = true;
8571 break;
8573 else if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
8574 || (OMP_CLAUSE_MAP_KIND (c)
8575 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
8576 && TREE_CODE (OMP_CLAUSE_SIZE (c)) != INTEGER_CST)
8578 OMP_CLAUSE_SIZE (c)
8579 = get_initialized_tmp_var (OMP_CLAUSE_SIZE (c), pre_p, NULL,
8580 false);
8581 omp_add_variable (ctx, OMP_CLAUSE_SIZE (c),
8582 GOVD_FIRSTPRIVATE | GOVD_SEEN);
8584 if (!DECL_P (decl))
8586 tree d = decl, *pd;
8587 if (TREE_CODE (d) == ARRAY_REF)
8589 while (TREE_CODE (d) == ARRAY_REF)
8590 d = TREE_OPERAND (d, 0);
8591 if (TREE_CODE (d) == COMPONENT_REF
8592 && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE)
8593 decl = d;
8595 pd = &OMP_CLAUSE_DECL (c);
8596 if (d == decl
8597 && TREE_CODE (decl) == INDIRECT_REF
8598 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
8599 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
8600 == REFERENCE_TYPE))
8602 pd = &TREE_OPERAND (decl, 0);
8603 decl = TREE_OPERAND (decl, 0);
8605 if (TREE_CODE (decl) == COMPONENT_REF)
8607 while (TREE_CODE (decl) == COMPONENT_REF)
8608 decl = TREE_OPERAND (decl, 0);
8609 if (TREE_CODE (decl) == INDIRECT_REF
8610 && DECL_P (TREE_OPERAND (decl, 0))
8611 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
8612 == REFERENCE_TYPE))
8613 decl = TREE_OPERAND (decl, 0);
8615 if (gimplify_expr (pd, pre_p, NULL, is_gimple_lvalue, fb_lvalue)
8616 == GS_ERROR)
8618 remove = true;
8619 break;
8621 if (DECL_P (decl))
8623 if (error_operand_p (decl))
8625 remove = true;
8626 break;
8629 tree stype = TREE_TYPE (decl);
8630 if (TREE_CODE (stype) == REFERENCE_TYPE)
8631 stype = TREE_TYPE (stype);
8632 if (TYPE_SIZE_UNIT (stype) == NULL
8633 || TREE_CODE (TYPE_SIZE_UNIT (stype)) != INTEGER_CST)
8635 error_at (OMP_CLAUSE_LOCATION (c),
8636 "mapping field %qE of variable length "
8637 "structure", OMP_CLAUSE_DECL (c));
8638 remove = true;
8639 break;
8642 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER)
8644 /* Error recovery. */
8645 if (prev_list_p == NULL)
8647 remove = true;
8648 break;
8650 if (OMP_CLAUSE_CHAIN (*prev_list_p) != c)
8652 tree ch = OMP_CLAUSE_CHAIN (*prev_list_p);
8653 if (ch == NULL_TREE || OMP_CLAUSE_CHAIN (ch) != c)
8655 remove = true;
8656 break;
8661 tree offset;
8662 poly_int64 bitsize, bitpos;
8663 machine_mode mode;
8664 int unsignedp, reversep, volatilep = 0;
8665 tree base = OMP_CLAUSE_DECL (c);
8666 while (TREE_CODE (base) == ARRAY_REF)
8667 base = TREE_OPERAND (base, 0);
8668 if (TREE_CODE (base) == INDIRECT_REF)
8669 base = TREE_OPERAND (base, 0);
8670 base = get_inner_reference (base, &bitsize, &bitpos, &offset,
8671 &mode, &unsignedp, &reversep,
8672 &volatilep);
8673 tree orig_base = base;
8674 if ((TREE_CODE (base) == INDIRECT_REF
8675 || (TREE_CODE (base) == MEM_REF
8676 && integer_zerop (TREE_OPERAND (base, 1))))
8677 && DECL_P (TREE_OPERAND (base, 0))
8678 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0)))
8679 == REFERENCE_TYPE))
8680 base = TREE_OPERAND (base, 0);
8681 gcc_assert (base == decl
8682 && (offset == NULL_TREE
8683 || poly_int_tree_p (offset)));
8685 splay_tree_node n
8686 = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
8687 bool ptr = (OMP_CLAUSE_MAP_KIND (c)
8688 == GOMP_MAP_ALWAYS_POINTER);
8689 if (n == NULL || (n->value & GOVD_MAP) == 0)
8691 tree l = build_omp_clause (OMP_CLAUSE_LOCATION (c),
8692 OMP_CLAUSE_MAP);
8693 OMP_CLAUSE_SET_MAP_KIND (l, GOMP_MAP_STRUCT);
8694 if (orig_base != base)
8695 OMP_CLAUSE_DECL (l) = unshare_expr (orig_base);
8696 else
8697 OMP_CLAUSE_DECL (l) = decl;
8698 OMP_CLAUSE_SIZE (l) = size_int (1);
8699 if (struct_map_to_clause == NULL)
8700 struct_map_to_clause = new hash_map<tree, tree>;
8701 struct_map_to_clause->put (decl, l);
8702 if (ptr)
8704 enum gomp_map_kind mkind
8705 = code == OMP_TARGET_EXIT_DATA
8706 ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
8707 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
8708 OMP_CLAUSE_MAP);
8709 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
8710 OMP_CLAUSE_DECL (c2)
8711 = unshare_expr (OMP_CLAUSE_DECL (c));
8712 OMP_CLAUSE_CHAIN (c2) = *prev_list_p;
8713 OMP_CLAUSE_SIZE (c2)
8714 = TYPE_SIZE_UNIT (ptr_type_node);
8715 OMP_CLAUSE_CHAIN (l) = c2;
8716 if (OMP_CLAUSE_CHAIN (*prev_list_p) != c)
8718 tree c4 = OMP_CLAUSE_CHAIN (*prev_list_p);
8719 tree c3
8720 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
8721 OMP_CLAUSE_MAP);
8722 OMP_CLAUSE_SET_MAP_KIND (c3, mkind);
8723 OMP_CLAUSE_DECL (c3)
8724 = unshare_expr (OMP_CLAUSE_DECL (c4));
8725 OMP_CLAUSE_SIZE (c3)
8726 = TYPE_SIZE_UNIT (ptr_type_node);
8727 OMP_CLAUSE_CHAIN (c3) = *prev_list_p;
8728 OMP_CLAUSE_CHAIN (c2) = c3;
8730 *prev_list_p = l;
8731 prev_list_p = NULL;
8733 else
8735 OMP_CLAUSE_CHAIN (l) = c;
8736 *list_p = l;
8737 list_p = &OMP_CLAUSE_CHAIN (l);
8739 if (orig_base != base && code == OMP_TARGET)
8741 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
8742 OMP_CLAUSE_MAP);
8743 enum gomp_map_kind mkind
8744 = GOMP_MAP_FIRSTPRIVATE_REFERENCE;
8745 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
8746 OMP_CLAUSE_DECL (c2) = decl;
8747 OMP_CLAUSE_SIZE (c2) = size_zero_node;
8748 OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (l);
8749 OMP_CLAUSE_CHAIN (l) = c2;
8751 flags = GOVD_MAP | GOVD_EXPLICIT;
8752 if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) || ptr)
8753 flags |= GOVD_SEEN;
8754 goto do_add_decl;
8756 else
8758 tree *osc = struct_map_to_clause->get (decl);
8759 tree *sc = NULL, *scp = NULL;
8760 if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) || ptr)
8761 n->value |= GOVD_SEEN;
8762 poly_offset_int o1, o2;
8763 if (offset)
8764 o1 = wi::to_poly_offset (offset);
8765 else
8766 o1 = 0;
8767 if (maybe_ne (bitpos, 0))
8768 o1 += bits_to_bytes_round_down (bitpos);
8769 sc = &OMP_CLAUSE_CHAIN (*osc);
8770 if (*sc != c
8771 && (OMP_CLAUSE_MAP_KIND (*sc)
8772 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
8773 sc = &OMP_CLAUSE_CHAIN (*sc);
8774 for (; *sc != c; sc = &OMP_CLAUSE_CHAIN (*sc))
8775 if (ptr && sc == prev_list_p)
8776 break;
8777 else if (TREE_CODE (OMP_CLAUSE_DECL (*sc))
8778 != COMPONENT_REF
8779 && (TREE_CODE (OMP_CLAUSE_DECL (*sc))
8780 != INDIRECT_REF)
8781 && (TREE_CODE (OMP_CLAUSE_DECL (*sc))
8782 != ARRAY_REF))
8783 break;
8784 else
8786 tree offset2;
8787 poly_int64 bitsize2, bitpos2;
8788 base = OMP_CLAUSE_DECL (*sc);
8789 if (TREE_CODE (base) == ARRAY_REF)
8791 while (TREE_CODE (base) == ARRAY_REF)
8792 base = TREE_OPERAND (base, 0);
8793 if (TREE_CODE (base) != COMPONENT_REF
8794 || (TREE_CODE (TREE_TYPE (base))
8795 != ARRAY_TYPE))
8796 break;
8798 else if (TREE_CODE (base) == INDIRECT_REF
8799 && (TREE_CODE (TREE_OPERAND (base, 0))
8800 == COMPONENT_REF)
8801 && (TREE_CODE (TREE_TYPE
8802 (TREE_OPERAND (base, 0)))
8803 == REFERENCE_TYPE))
8804 base = TREE_OPERAND (base, 0);
8805 base = get_inner_reference (base, &bitsize2,
8806 &bitpos2, &offset2,
8807 &mode, &unsignedp,
8808 &reversep, &volatilep);
8809 if ((TREE_CODE (base) == INDIRECT_REF
8810 || (TREE_CODE (base) == MEM_REF
8811 && integer_zerop (TREE_OPERAND (base,
8812 1))))
8813 && DECL_P (TREE_OPERAND (base, 0))
8814 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (base,
8815 0)))
8816 == REFERENCE_TYPE))
8817 base = TREE_OPERAND (base, 0);
8818 if (base != decl)
8819 break;
8820 if (scp)
8821 continue;
8822 gcc_assert (offset == NULL_TREE
8823 || poly_int_tree_p (offset));
8824 tree d1 = OMP_CLAUSE_DECL (*sc);
8825 tree d2 = OMP_CLAUSE_DECL (c);
8826 while (TREE_CODE (d1) == ARRAY_REF)
8827 d1 = TREE_OPERAND (d1, 0);
8828 while (TREE_CODE (d2) == ARRAY_REF)
8829 d2 = TREE_OPERAND (d2, 0);
8830 if (TREE_CODE (d1) == INDIRECT_REF)
8831 d1 = TREE_OPERAND (d1, 0);
8832 if (TREE_CODE (d2) == INDIRECT_REF)
8833 d2 = TREE_OPERAND (d2, 0);
8834 while (TREE_CODE (d1) == COMPONENT_REF)
8835 if (TREE_CODE (d2) == COMPONENT_REF
8836 && TREE_OPERAND (d1, 1)
8837 == TREE_OPERAND (d2, 1))
8839 d1 = TREE_OPERAND (d1, 0);
8840 d2 = TREE_OPERAND (d2, 0);
8842 else
8843 break;
8844 if (d1 == d2)
8846 error_at (OMP_CLAUSE_LOCATION (c),
8847 "%qE appears more than once in map "
8848 "clauses", OMP_CLAUSE_DECL (c));
8849 remove = true;
8850 break;
8852 if (offset2)
8853 o2 = wi::to_poly_offset (offset2);
8854 else
8855 o2 = 0;
8856 o2 += bits_to_bytes_round_down (bitpos2);
8857 if (maybe_lt (o1, o2)
8858 || (known_eq (o1, o2)
8859 && maybe_lt (bitpos, bitpos2)))
8861 if (ptr)
8862 scp = sc;
8863 else
8864 break;
8867 if (remove)
8868 break;
8869 OMP_CLAUSE_SIZE (*osc)
8870 = size_binop (PLUS_EXPR, OMP_CLAUSE_SIZE (*osc),
8871 size_one_node);
8872 if (ptr)
8874 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
8875 OMP_CLAUSE_MAP);
8876 tree cl = NULL_TREE;
8877 enum gomp_map_kind mkind
8878 = code == OMP_TARGET_EXIT_DATA
8879 ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
8880 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
8881 OMP_CLAUSE_DECL (c2)
8882 = unshare_expr (OMP_CLAUSE_DECL (c));
8883 OMP_CLAUSE_CHAIN (c2) = scp ? *scp : *prev_list_p;
8884 OMP_CLAUSE_SIZE (c2)
8885 = TYPE_SIZE_UNIT (ptr_type_node);
8886 cl = scp ? *prev_list_p : c2;
8887 if (OMP_CLAUSE_CHAIN (*prev_list_p) != c)
8889 tree c4 = OMP_CLAUSE_CHAIN (*prev_list_p);
8890 tree c3
8891 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
8892 OMP_CLAUSE_MAP);
8893 OMP_CLAUSE_SET_MAP_KIND (c3, mkind);
8894 OMP_CLAUSE_DECL (c3)
8895 = unshare_expr (OMP_CLAUSE_DECL (c4));
8896 OMP_CLAUSE_SIZE (c3)
8897 = TYPE_SIZE_UNIT (ptr_type_node);
8898 OMP_CLAUSE_CHAIN (c3) = *prev_list_p;
8899 if (!scp)
8900 OMP_CLAUSE_CHAIN (c2) = c3;
8901 else
8902 cl = c3;
8904 if (scp)
8905 *scp = c2;
8906 if (sc == prev_list_p)
8908 *sc = cl;
8909 prev_list_p = NULL;
8911 else
8913 *prev_list_p = OMP_CLAUSE_CHAIN (c);
8914 list_p = prev_list_p;
8915 prev_list_p = NULL;
8916 OMP_CLAUSE_CHAIN (c) = *sc;
8917 *sc = cl;
8918 continue;
8921 else if (*sc != c)
8923 *list_p = OMP_CLAUSE_CHAIN (c);
8924 OMP_CLAUSE_CHAIN (c) = *sc;
8925 *sc = c;
8926 continue;
8930 if (!remove
8931 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_POINTER
8932 && OMP_CLAUSE_CHAIN (c)
8933 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (c)) == OMP_CLAUSE_MAP
8934 && (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
8935 == GOMP_MAP_ALWAYS_POINTER))
8936 prev_list_p = list_p;
8937 break;
8939 flags = GOVD_MAP | GOVD_EXPLICIT;
8940 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TO
8941 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TOFROM)
8942 flags |= GOVD_MAP_ALWAYS_TO;
8943 goto do_add;
8945 case OMP_CLAUSE_DEPEND:
8946 if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
8948 tree deps = OMP_CLAUSE_DECL (c);
8949 while (deps && TREE_CODE (deps) == TREE_LIST)
8951 if (TREE_CODE (TREE_PURPOSE (deps)) == TRUNC_DIV_EXPR
8952 && DECL_P (TREE_OPERAND (TREE_PURPOSE (deps), 1)))
8953 gimplify_expr (&TREE_OPERAND (TREE_PURPOSE (deps), 1),
8954 pre_p, NULL, is_gimple_val, fb_rvalue);
8955 deps = TREE_CHAIN (deps);
8957 break;
8959 else if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
8960 break;
8961 if (handled_depend_iterators == -1)
8962 handled_depend_iterators = gimplify_omp_depend (list_p, pre_p);
8963 if (handled_depend_iterators)
8965 if (handled_depend_iterators == 2)
8966 remove = true;
8967 break;
8969 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
8971 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
8972 NULL, is_gimple_val, fb_rvalue);
8973 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
8975 if (error_operand_p (OMP_CLAUSE_DECL (c)))
8977 remove = true;
8978 break;
8980 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
8981 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
8982 is_gimple_val, fb_rvalue) == GS_ERROR)
8984 remove = true;
8985 break;
8987 break;
8989 case OMP_CLAUSE_TO:
8990 case OMP_CLAUSE_FROM:
8991 case OMP_CLAUSE__CACHE_:
8992 decl = OMP_CLAUSE_DECL (c);
8993 if (error_operand_p (decl))
8995 remove = true;
8996 break;
8998 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
8999 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
9000 : TYPE_SIZE_UNIT (TREE_TYPE (decl));
9001 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
9002 NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
9004 remove = true;
9005 break;
9007 if (!DECL_P (decl))
9009 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p,
9010 NULL, is_gimple_lvalue, fb_lvalue)
9011 == GS_ERROR)
9013 remove = true;
9014 break;
9016 break;
9018 goto do_notice;
9020 case OMP_CLAUSE_USE_DEVICE_PTR:
9021 case OMP_CLAUSE_USE_DEVICE_ADDR:
9022 flags = GOVD_EXPLICIT;
9023 goto do_add;
9025 case OMP_CLAUSE_IS_DEVICE_PTR:
9026 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
9027 goto do_add;
9029 do_add:
9030 decl = OMP_CLAUSE_DECL (c);
9031 do_add_decl:
9032 if (error_operand_p (decl))
9034 remove = true;
9035 break;
9037 if (DECL_NAME (decl) == NULL_TREE && (flags & GOVD_SHARED) == 0)
9039 tree t = omp_member_access_dummy_var (decl);
9040 if (t)
9042 tree v = DECL_VALUE_EXPR (decl);
9043 DECL_NAME (decl) = DECL_NAME (TREE_OPERAND (v, 1));
9044 if (outer_ctx)
9045 omp_notice_variable (outer_ctx, t, true);
9048 if (code == OACC_DATA
9049 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9050 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
9051 flags |= GOVD_MAP_0LEN_ARRAY;
9052 omp_add_variable (ctx, decl, flags);
9053 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
9054 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
9055 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
9056 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
9058 omp_add_variable (ctx, OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
9059 GOVD_LOCAL | GOVD_SEEN);
9060 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
9061 && walk_tree (&OMP_CLAUSE_REDUCTION_INIT (c),
9062 find_decl_expr,
9063 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
9064 NULL) == NULL_TREE)
9065 omp_add_variable (ctx,
9066 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
9067 GOVD_LOCAL | GOVD_SEEN);
9068 gimplify_omp_ctxp = ctx;
9069 push_gimplify_context ();
9071 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
9072 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
9074 gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c),
9075 &OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c));
9076 pop_gimplify_context
9077 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c)));
9078 push_gimplify_context ();
9079 gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c),
9080 &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
9081 pop_gimplify_context
9082 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c)));
9083 OMP_CLAUSE_REDUCTION_INIT (c) = NULL_TREE;
9084 OMP_CLAUSE_REDUCTION_MERGE (c) = NULL_TREE;
9086 gimplify_omp_ctxp = outer_ctx;
9088 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
9089 && OMP_CLAUSE_LASTPRIVATE_STMT (c))
9091 gimplify_omp_ctxp = ctx;
9092 push_gimplify_context ();
9093 if (TREE_CODE (OMP_CLAUSE_LASTPRIVATE_STMT (c)) != BIND_EXPR)
9095 tree bind = build3 (BIND_EXPR, void_type_node, NULL,
9096 NULL, NULL);
9097 TREE_SIDE_EFFECTS (bind) = 1;
9098 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LASTPRIVATE_STMT (c);
9099 OMP_CLAUSE_LASTPRIVATE_STMT (c) = bind;
9101 gimplify_and_add (OMP_CLAUSE_LASTPRIVATE_STMT (c),
9102 &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
9103 pop_gimplify_context
9104 (gimple_seq_first_stmt (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c)));
9105 OMP_CLAUSE_LASTPRIVATE_STMT (c) = NULL_TREE;
9107 gimplify_omp_ctxp = outer_ctx;
9109 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
9110 && OMP_CLAUSE_LINEAR_STMT (c))
9112 gimplify_omp_ctxp = ctx;
9113 push_gimplify_context ();
9114 if (TREE_CODE (OMP_CLAUSE_LINEAR_STMT (c)) != BIND_EXPR)
9116 tree bind = build3 (BIND_EXPR, void_type_node, NULL,
9117 NULL, NULL);
9118 TREE_SIDE_EFFECTS (bind) = 1;
9119 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LINEAR_STMT (c);
9120 OMP_CLAUSE_LINEAR_STMT (c) = bind;
9122 gimplify_and_add (OMP_CLAUSE_LINEAR_STMT (c),
9123 &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c));
9124 pop_gimplify_context
9125 (gimple_seq_first_stmt (OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c)));
9126 OMP_CLAUSE_LINEAR_STMT (c) = NULL_TREE;
9128 gimplify_omp_ctxp = outer_ctx;
9130 if (notice_outer)
9131 goto do_notice;
9132 break;
9134 case OMP_CLAUSE_COPYIN:
9135 case OMP_CLAUSE_COPYPRIVATE:
9136 decl = OMP_CLAUSE_DECL (c);
9137 if (error_operand_p (decl))
9139 remove = true;
9140 break;
9142 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_COPYPRIVATE
9143 && !remove
9144 && !omp_check_private (ctx, decl, true))
9146 remove = true;
9147 if (is_global_var (decl))
9149 if (DECL_THREAD_LOCAL_P (decl))
9150 remove = false;
9151 else if (DECL_HAS_VALUE_EXPR_P (decl))
9153 tree value = get_base_address (DECL_VALUE_EXPR (decl));
9155 if (value
9156 && DECL_P (value)
9157 && DECL_THREAD_LOCAL_P (value))
9158 remove = false;
9161 if (remove)
9162 error_at (OMP_CLAUSE_LOCATION (c),
9163 "copyprivate variable %qE is not threadprivate"
9164 " or private in outer context", DECL_NAME (decl));
9166 do_notice:
9167 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
9168 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
9169 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
9170 && outer_ctx
9171 && ((region_type & ORT_TASKLOOP) == ORT_TASKLOOP
9172 || (region_type == ORT_WORKSHARE
9173 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
9174 && (OMP_CLAUSE_REDUCTION_INSCAN (c)
9175 || code == OMP_LOOP)))
9176 && (outer_ctx->region_type == ORT_COMBINED_PARALLEL
9177 || (code == OMP_LOOP
9178 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
9179 && ((outer_ctx->region_type & ORT_COMBINED_TEAMS)
9180 == ORT_COMBINED_TEAMS))))
9182 splay_tree_node on
9183 = splay_tree_lookup (outer_ctx->variables,
9184 (splay_tree_key)decl);
9185 if (on == NULL || (on->value & GOVD_DATA_SHARE_CLASS) == 0)
9187 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
9188 && TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
9189 && (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
9190 || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
9191 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
9192 == POINTER_TYPE))))
9193 omp_firstprivatize_variable (outer_ctx, decl);
9194 else
9195 omp_add_variable (outer_ctx, decl,
9196 GOVD_SEEN | GOVD_SHARED);
9197 omp_notice_variable (outer_ctx, decl, true);
9200 if (outer_ctx)
9201 omp_notice_variable (outer_ctx, decl, true);
9202 if (check_non_private
9203 && region_type == ORT_WORKSHARE
9204 && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
9205 || decl == OMP_CLAUSE_DECL (c)
9206 || (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
9207 && (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
9208 == ADDR_EXPR
9209 || (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
9210 == POINTER_PLUS_EXPR
9211 && (TREE_CODE (TREE_OPERAND (TREE_OPERAND
9212 (OMP_CLAUSE_DECL (c), 0), 0))
9213 == ADDR_EXPR)))))
9214 && omp_check_private (ctx, decl, false))
9216 error ("%s variable %qE is private in outer context",
9217 check_non_private, DECL_NAME (decl));
9218 remove = true;
9220 break;
9222 case OMP_CLAUSE_IF:
9223 if (OMP_CLAUSE_IF_MODIFIER (c) != ERROR_MARK
9224 && OMP_CLAUSE_IF_MODIFIER (c) != code)
9226 const char *p[2];
9227 for (int i = 0; i < 2; i++)
9228 switch (i ? OMP_CLAUSE_IF_MODIFIER (c) : code)
9230 case VOID_CST: p[i] = "cancel"; break;
9231 case OMP_PARALLEL: p[i] = "parallel"; break;
9232 case OMP_SIMD: p[i] = "simd"; break;
9233 case OMP_TASK: p[i] = "task"; break;
9234 case OMP_TASKLOOP: p[i] = "taskloop"; break;
9235 case OMP_TARGET_DATA: p[i] = "target data"; break;
9236 case OMP_TARGET: p[i] = "target"; break;
9237 case OMP_TARGET_UPDATE: p[i] = "target update"; break;
9238 case OMP_TARGET_ENTER_DATA:
9239 p[i] = "target enter data"; break;
9240 case OMP_TARGET_EXIT_DATA: p[i] = "target exit data"; break;
9241 default: gcc_unreachable ();
9243 error_at (OMP_CLAUSE_LOCATION (c),
9244 "expected %qs %<if%> clause modifier rather than %qs",
9245 p[0], p[1]);
9246 remove = true;
9248 /* Fall through. */
9250 case OMP_CLAUSE_FINAL:
9251 OMP_CLAUSE_OPERAND (c, 0)
9252 = gimple_boolify (OMP_CLAUSE_OPERAND (c, 0));
9253 /* Fall through. */
9255 case OMP_CLAUSE_SCHEDULE:
9256 case OMP_CLAUSE_NUM_THREADS:
9257 case OMP_CLAUSE_NUM_TEAMS:
9258 case OMP_CLAUSE_THREAD_LIMIT:
9259 case OMP_CLAUSE_DIST_SCHEDULE:
9260 case OMP_CLAUSE_DEVICE:
9261 case OMP_CLAUSE_PRIORITY:
9262 case OMP_CLAUSE_GRAINSIZE:
9263 case OMP_CLAUSE_NUM_TASKS:
9264 case OMP_CLAUSE_HINT:
9265 case OMP_CLAUSE_ASYNC:
9266 case OMP_CLAUSE_WAIT:
9267 case OMP_CLAUSE_NUM_GANGS:
9268 case OMP_CLAUSE_NUM_WORKERS:
9269 case OMP_CLAUSE_VECTOR_LENGTH:
9270 case OMP_CLAUSE_WORKER:
9271 case OMP_CLAUSE_VECTOR:
9272 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
9273 is_gimple_val, fb_rvalue) == GS_ERROR)
9274 remove = true;
9275 break;
9277 case OMP_CLAUSE_GANG:
9278 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
9279 is_gimple_val, fb_rvalue) == GS_ERROR)
9280 remove = true;
9281 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 1), pre_p, NULL,
9282 is_gimple_val, fb_rvalue) == GS_ERROR)
9283 remove = true;
9284 break;
9286 case OMP_CLAUSE_NOWAIT:
9287 nowait = 1;
9288 break;
9290 case OMP_CLAUSE_ORDERED:
9291 case OMP_CLAUSE_UNTIED:
9292 case OMP_CLAUSE_COLLAPSE:
9293 case OMP_CLAUSE_TILE:
9294 case OMP_CLAUSE_AUTO:
9295 case OMP_CLAUSE_SEQ:
9296 case OMP_CLAUSE_INDEPENDENT:
9297 case OMP_CLAUSE_MERGEABLE:
9298 case OMP_CLAUSE_PROC_BIND:
9299 case OMP_CLAUSE_SAFELEN:
9300 case OMP_CLAUSE_SIMDLEN:
9301 case OMP_CLAUSE_NOGROUP:
9302 case OMP_CLAUSE_THREADS:
9303 case OMP_CLAUSE_SIMD:
9304 case OMP_CLAUSE_BIND:
9305 case OMP_CLAUSE_IF_PRESENT:
9306 case OMP_CLAUSE_FINALIZE:
9307 break;
9309 case OMP_CLAUSE_ORDER:
9310 ctx->order_concurrent = true;
9311 break;
9313 case OMP_CLAUSE_DEFAULTMAP:
9314 enum gimplify_defaultmap_kind gdmkmin, gdmkmax;
9315 switch (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c))
9317 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
9318 gdmkmin = GDMK_SCALAR;
9319 gdmkmax = GDMK_POINTER;
9320 break;
9321 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
9322 gdmkmin = gdmkmax = GDMK_SCALAR;
9323 break;
9324 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
9325 gdmkmin = gdmkmax = GDMK_AGGREGATE;
9326 break;
9327 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALLOCATABLE:
9328 gdmkmin = gdmkmax = GDMK_ALLOCATABLE;
9329 break;
9330 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
9331 gdmkmin = gdmkmax = GDMK_POINTER;
9332 break;
9333 default:
9334 gcc_unreachable ();
9336 for (int gdmk = gdmkmin; gdmk <= gdmkmax; gdmk++)
9337 switch (OMP_CLAUSE_DEFAULTMAP_BEHAVIOR (c))
9339 case OMP_CLAUSE_DEFAULTMAP_ALLOC:
9340 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_ALLOC_ONLY;
9341 break;
9342 case OMP_CLAUSE_DEFAULTMAP_TO:
9343 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_TO_ONLY;
9344 break;
9345 case OMP_CLAUSE_DEFAULTMAP_FROM:
9346 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_FROM_ONLY;
9347 break;
9348 case OMP_CLAUSE_DEFAULTMAP_TOFROM:
9349 ctx->defaultmap[gdmk] = GOVD_MAP;
9350 break;
9351 case OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE:
9352 ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE;
9353 break;
9354 case OMP_CLAUSE_DEFAULTMAP_NONE:
9355 ctx->defaultmap[gdmk] = 0;
9356 break;
9357 case OMP_CLAUSE_DEFAULTMAP_DEFAULT:
9358 switch (gdmk)
9360 case GDMK_SCALAR:
9361 ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE;
9362 break;
9363 case GDMK_AGGREGATE:
9364 case GDMK_ALLOCATABLE:
9365 ctx->defaultmap[gdmk] = GOVD_MAP;
9366 break;
9367 case GDMK_POINTER:
9368 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_0LEN_ARRAY;
9369 break;
9370 default:
9371 gcc_unreachable ();
9373 break;
9374 default:
9375 gcc_unreachable ();
9377 break;
9379 case OMP_CLAUSE_ALIGNED:
9380 decl = OMP_CLAUSE_DECL (c);
9381 if (error_operand_p (decl))
9383 remove = true;
9384 break;
9386 if (gimplify_expr (&OMP_CLAUSE_ALIGNED_ALIGNMENT (c), pre_p, NULL,
9387 is_gimple_val, fb_rvalue) == GS_ERROR)
9389 remove = true;
9390 break;
9392 if (!is_global_var (decl)
9393 && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
9394 omp_add_variable (ctx, decl, GOVD_ALIGNED);
9395 break;
9397 case OMP_CLAUSE_NONTEMPORAL:
9398 decl = OMP_CLAUSE_DECL (c);
9399 if (error_operand_p (decl))
9401 remove = true;
9402 break;
9404 omp_add_variable (ctx, decl, GOVD_NONTEMPORAL);
9405 break;
9407 case OMP_CLAUSE_DEFAULT:
9408 ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
9409 break;
9411 case OMP_CLAUSE_INCLUSIVE:
9412 case OMP_CLAUSE_EXCLUSIVE:
9413 decl = OMP_CLAUSE_DECL (c);
9415 splay_tree_node n = splay_tree_lookup (outer_ctx->variables,
9416 (splay_tree_key) decl);
9417 if (n == NULL || (n->value & GOVD_REDUCTION) == 0)
9419 error_at (OMP_CLAUSE_LOCATION (c),
9420 "%qD specified in %qs clause but not in %<inscan%> "
9421 "%<reduction%> clause on the containing construct",
9422 decl, omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
9423 remove = true;
9425 else
9427 n->value |= GOVD_REDUCTION_INSCAN;
9428 if (outer_ctx->region_type == ORT_SIMD
9429 && outer_ctx->outer_context
9430 && outer_ctx->outer_context->region_type == ORT_WORKSHARE)
9432 n = splay_tree_lookup (outer_ctx->outer_context->variables,
9433 (splay_tree_key) decl);
9434 if (n && (n->value & GOVD_REDUCTION) != 0)
9435 n->value |= GOVD_REDUCTION_INSCAN;
9439 break;
9441 default:
9442 gcc_unreachable ();
9445 if (code == OACC_DATA
9446 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9447 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
9448 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
9449 remove = true;
9450 if (remove)
9451 *list_p = OMP_CLAUSE_CHAIN (c);
9452 else
9453 list_p = &OMP_CLAUSE_CHAIN (c);
9456 ctx->clauses = *orig_list_p;
9457 gimplify_omp_ctxp = ctx;
9458 if (struct_map_to_clause)
9459 delete struct_map_to_clause;
9462 /* Return true if DECL is a candidate for shared to firstprivate
9463 optimization. We only consider non-addressable scalars, not
9464 too big, and not references. */
9466 static bool
9467 omp_shared_to_firstprivate_optimizable_decl_p (tree decl)
9469 if (TREE_ADDRESSABLE (decl))
9470 return false;
9471 tree type = TREE_TYPE (decl);
9472 if (!is_gimple_reg_type (type)
9473 || TREE_CODE (type) == REFERENCE_TYPE
9474 || TREE_ADDRESSABLE (type))
9475 return false;
9476 /* Don't optimize too large decls, as each thread/task will have
9477 its own. */
9478 HOST_WIDE_INT len = int_size_in_bytes (type);
9479 if (len == -1 || len > 4 * POINTER_SIZE / BITS_PER_UNIT)
9480 return false;
9481 if (lang_hooks.decls.omp_privatize_by_reference (decl))
9482 return false;
9483 return true;
9486 /* Helper function of omp_find_stores_op and gimplify_adjust_omp_clauses*.
9487 For omp_shared_to_firstprivate_optimizable_decl_p decl mark it as
9488 GOVD_WRITTEN in outer contexts. */
9490 static void
9491 omp_mark_stores (struct gimplify_omp_ctx *ctx, tree decl)
9493 for (; ctx; ctx = ctx->outer_context)
9495 splay_tree_node n = splay_tree_lookup (ctx->variables,
9496 (splay_tree_key) decl);
9497 if (n == NULL)
9498 continue;
9499 else if (n->value & GOVD_SHARED)
9501 n->value |= GOVD_WRITTEN;
9502 return;
9504 else if (n->value & GOVD_DATA_SHARE_CLASS)
9505 return;
9509 /* Helper callback for walk_gimple_seq to discover possible stores
9510 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
9511 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
9512 for those. */
9514 static tree
9515 omp_find_stores_op (tree *tp, int *walk_subtrees, void *data)
9517 struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
9519 *walk_subtrees = 0;
9520 if (!wi->is_lhs)
9521 return NULL_TREE;
9523 tree op = *tp;
9526 if (handled_component_p (op))
9527 op = TREE_OPERAND (op, 0);
9528 else if ((TREE_CODE (op) == MEM_REF || TREE_CODE (op) == TARGET_MEM_REF)
9529 && TREE_CODE (TREE_OPERAND (op, 0)) == ADDR_EXPR)
9530 op = TREE_OPERAND (TREE_OPERAND (op, 0), 0);
9531 else
9532 break;
9534 while (1);
9535 if (!DECL_P (op) || !omp_shared_to_firstprivate_optimizable_decl_p (op))
9536 return NULL_TREE;
9538 omp_mark_stores (gimplify_omp_ctxp, op);
9539 return NULL_TREE;
9542 /* Helper callback for walk_gimple_seq to discover possible stores
9543 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
9544 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
9545 for those. */
9547 static tree
9548 omp_find_stores_stmt (gimple_stmt_iterator *gsi_p,
9549 bool *handled_ops_p,
9550 struct walk_stmt_info *wi)
9552 gimple *stmt = gsi_stmt (*gsi_p);
9553 switch (gimple_code (stmt))
9555 /* Don't recurse on OpenMP constructs for which
9556 gimplify_adjust_omp_clauses already handled the bodies,
9557 except handle gimple_omp_for_pre_body. */
9558 case GIMPLE_OMP_FOR:
9559 *handled_ops_p = true;
9560 if (gimple_omp_for_pre_body (stmt))
9561 walk_gimple_seq (gimple_omp_for_pre_body (stmt),
9562 omp_find_stores_stmt, omp_find_stores_op, wi);
9563 break;
9564 case GIMPLE_OMP_PARALLEL:
9565 case GIMPLE_OMP_TASK:
9566 case GIMPLE_OMP_SECTIONS:
9567 case GIMPLE_OMP_SINGLE:
9568 case GIMPLE_OMP_TARGET:
9569 case GIMPLE_OMP_TEAMS:
9570 case GIMPLE_OMP_CRITICAL:
9571 *handled_ops_p = true;
9572 break;
9573 default:
9574 break;
9576 return NULL_TREE;
9579 struct gimplify_adjust_omp_clauses_data
9581 tree *list_p;
9582 gimple_seq *pre_p;
9585 /* For all variables that were not actually used within the context,
9586 remove PRIVATE, SHARED, and FIRSTPRIVATE clauses. */
9588 static int
9589 gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
9591 tree *list_p = ((struct gimplify_adjust_omp_clauses_data *) data)->list_p;
9592 gimple_seq *pre_p
9593 = ((struct gimplify_adjust_omp_clauses_data *) data)->pre_p;
9594 tree decl = (tree) n->key;
9595 unsigned flags = n->value;
9596 enum omp_clause_code code;
9597 tree clause;
9598 bool private_debug;
9600 if (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
9601 && (flags & GOVD_LASTPRIVATE_CONDITIONAL) != 0)
9602 flags = GOVD_SHARED | GOVD_SEEN | GOVD_WRITTEN;
9603 if (flags & (GOVD_EXPLICIT | GOVD_LOCAL))
9604 return 0;
9605 if ((flags & GOVD_SEEN) == 0)
9606 return 0;
9607 if (flags & GOVD_DEBUG_PRIVATE)
9609 gcc_assert ((flags & GOVD_DATA_SHARE_CLASS) == GOVD_SHARED);
9610 private_debug = true;
9612 else if (flags & GOVD_MAP)
9613 private_debug = false;
9614 else
9615 private_debug
9616 = lang_hooks.decls.omp_private_debug_clause (decl,
9617 !!(flags & GOVD_SHARED));
9618 if (private_debug)
9619 code = OMP_CLAUSE_PRIVATE;
9620 else if (flags & GOVD_MAP)
9622 code = OMP_CLAUSE_MAP;
9623 if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0
9624 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
9626 error ("%<_Atomic%> %qD in implicit %<map%> clause", decl);
9627 return 0;
9630 else if (flags & GOVD_SHARED)
9632 if (is_global_var (decl))
9634 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
9635 while (ctx != NULL)
9637 splay_tree_node on
9638 = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
9639 if (on && (on->value & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
9640 | GOVD_PRIVATE | GOVD_REDUCTION
9641 | GOVD_LINEAR | GOVD_MAP)) != 0)
9642 break;
9643 ctx = ctx->outer_context;
9645 if (ctx == NULL)
9646 return 0;
9648 code = OMP_CLAUSE_SHARED;
9650 else if (flags & GOVD_PRIVATE)
9651 code = OMP_CLAUSE_PRIVATE;
9652 else if (flags & GOVD_FIRSTPRIVATE)
9654 code = OMP_CLAUSE_FIRSTPRIVATE;
9655 if ((gimplify_omp_ctxp->region_type & ORT_TARGET)
9656 && (gimplify_omp_ctxp->region_type & ORT_ACC) == 0
9657 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
9659 error ("%<_Atomic%> %qD in implicit %<firstprivate%> clause on "
9660 "%<target%> construct", decl);
9661 return 0;
9664 else if (flags & GOVD_LASTPRIVATE)
9665 code = OMP_CLAUSE_LASTPRIVATE;
9666 else if (flags & (GOVD_ALIGNED | GOVD_NONTEMPORAL))
9667 return 0;
9668 else if (flags & GOVD_CONDTEMP)
9670 code = OMP_CLAUSE__CONDTEMP_;
9671 gimple_add_tmp_var (decl);
9673 else
9674 gcc_unreachable ();
9676 if (((flags & GOVD_LASTPRIVATE)
9677 || (code == OMP_CLAUSE_SHARED && (flags & GOVD_WRITTEN)))
9678 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
9679 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
9681 tree chain = *list_p;
9682 clause = build_omp_clause (input_location, code);
9683 OMP_CLAUSE_DECL (clause) = decl;
9684 OMP_CLAUSE_CHAIN (clause) = chain;
9685 if (private_debug)
9686 OMP_CLAUSE_PRIVATE_DEBUG (clause) = 1;
9687 else if (code == OMP_CLAUSE_PRIVATE && (flags & GOVD_PRIVATE_OUTER_REF))
9688 OMP_CLAUSE_PRIVATE_OUTER_REF (clause) = 1;
9689 else if (code == OMP_CLAUSE_SHARED
9690 && (flags & GOVD_WRITTEN) == 0
9691 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
9692 OMP_CLAUSE_SHARED_READONLY (clause) = 1;
9693 else if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_EXPLICIT) == 0)
9694 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (clause) = 1;
9695 else if (code == OMP_CLAUSE_MAP && (flags & GOVD_MAP_0LEN_ARRAY) != 0)
9697 tree nc = build_omp_clause (input_location, OMP_CLAUSE_MAP);
9698 OMP_CLAUSE_DECL (nc) = decl;
9699 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
9700 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == POINTER_TYPE)
9701 OMP_CLAUSE_DECL (clause)
9702 = build_simple_mem_ref_loc (input_location, decl);
9703 OMP_CLAUSE_DECL (clause)
9704 = build2 (MEM_REF, char_type_node, OMP_CLAUSE_DECL (clause),
9705 build_int_cst (build_pointer_type (char_type_node), 0));
9706 OMP_CLAUSE_SIZE (clause) = size_zero_node;
9707 OMP_CLAUSE_SIZE (nc) = size_zero_node;
9708 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_ALLOC);
9709 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (clause) = 1;
9710 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
9711 OMP_CLAUSE_CHAIN (nc) = chain;
9712 OMP_CLAUSE_CHAIN (clause) = nc;
9713 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
9714 gimplify_omp_ctxp = ctx->outer_context;
9715 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (clause), 0),
9716 pre_p, NULL, is_gimple_val, fb_rvalue);
9717 gimplify_omp_ctxp = ctx;
9719 else if (code == OMP_CLAUSE_MAP)
9721 int kind;
9722 /* Not all combinations of these GOVD_MAP flags are actually valid. */
9723 switch (flags & (GOVD_MAP_TO_ONLY
9724 | GOVD_MAP_FORCE
9725 | GOVD_MAP_FORCE_PRESENT
9726 | GOVD_MAP_ALLOC_ONLY
9727 | GOVD_MAP_FROM_ONLY))
9729 case 0:
9730 kind = GOMP_MAP_TOFROM;
9731 break;
9732 case GOVD_MAP_FORCE:
9733 kind = GOMP_MAP_TOFROM | GOMP_MAP_FLAG_FORCE;
9734 break;
9735 case GOVD_MAP_TO_ONLY:
9736 kind = GOMP_MAP_TO;
9737 break;
9738 case GOVD_MAP_FROM_ONLY:
9739 kind = GOMP_MAP_FROM;
9740 break;
9741 case GOVD_MAP_ALLOC_ONLY:
9742 kind = GOMP_MAP_ALLOC;
9743 break;
9744 case GOVD_MAP_TO_ONLY | GOVD_MAP_FORCE:
9745 kind = GOMP_MAP_TO | GOMP_MAP_FLAG_FORCE;
9746 break;
9747 case GOVD_MAP_FORCE_PRESENT:
9748 kind = GOMP_MAP_FORCE_PRESENT;
9749 break;
9750 default:
9751 gcc_unreachable ();
9753 OMP_CLAUSE_SET_MAP_KIND (clause, kind);
9754 if (DECL_SIZE (decl)
9755 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
9757 tree decl2 = DECL_VALUE_EXPR (decl);
9758 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
9759 decl2 = TREE_OPERAND (decl2, 0);
9760 gcc_assert (DECL_P (decl2));
9761 tree mem = build_simple_mem_ref (decl2);
9762 OMP_CLAUSE_DECL (clause) = mem;
9763 OMP_CLAUSE_SIZE (clause) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
9764 if (gimplify_omp_ctxp->outer_context)
9766 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
9767 omp_notice_variable (ctx, decl2, true);
9768 omp_notice_variable (ctx, OMP_CLAUSE_SIZE (clause), true);
9770 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
9771 OMP_CLAUSE_MAP);
9772 OMP_CLAUSE_DECL (nc) = decl;
9773 OMP_CLAUSE_SIZE (nc) = size_zero_node;
9774 if (gimplify_omp_ctxp->target_firstprivatize_array_bases)
9775 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
9776 else
9777 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
9778 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
9779 OMP_CLAUSE_CHAIN (clause) = nc;
9781 else if (gimplify_omp_ctxp->target_firstprivatize_array_bases
9782 && lang_hooks.decls.omp_privatize_by_reference (decl))
9784 OMP_CLAUSE_DECL (clause) = build_simple_mem_ref (decl);
9785 OMP_CLAUSE_SIZE (clause)
9786 = unshare_expr (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))));
9787 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
9788 gimplify_omp_ctxp = ctx->outer_context;
9789 gimplify_expr (&OMP_CLAUSE_SIZE (clause),
9790 pre_p, NULL, is_gimple_val, fb_rvalue);
9791 gimplify_omp_ctxp = ctx;
9792 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
9793 OMP_CLAUSE_MAP);
9794 OMP_CLAUSE_DECL (nc) = decl;
9795 OMP_CLAUSE_SIZE (nc) = size_zero_node;
9796 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_REFERENCE);
9797 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
9798 OMP_CLAUSE_CHAIN (clause) = nc;
9800 else
9801 OMP_CLAUSE_SIZE (clause) = DECL_SIZE_UNIT (decl);
9803 if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_LASTPRIVATE) != 0)
9805 tree nc = build_omp_clause (input_location, OMP_CLAUSE_LASTPRIVATE);
9806 OMP_CLAUSE_DECL (nc) = decl;
9807 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (nc) = 1;
9808 OMP_CLAUSE_CHAIN (nc) = chain;
9809 OMP_CLAUSE_CHAIN (clause) = nc;
9810 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
9811 gimplify_omp_ctxp = ctx->outer_context;
9812 lang_hooks.decls.omp_finish_clause (nc, pre_p);
9813 gimplify_omp_ctxp = ctx;
9815 *list_p = clause;
9816 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
9817 gimplify_omp_ctxp = ctx->outer_context;
9818 lang_hooks.decls.omp_finish_clause (clause, pre_p);
9819 if (gimplify_omp_ctxp)
9820 for (; clause != chain; clause = OMP_CLAUSE_CHAIN (clause))
9821 if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_MAP
9822 && DECL_P (OMP_CLAUSE_SIZE (clause)))
9823 omp_notice_variable (gimplify_omp_ctxp, OMP_CLAUSE_SIZE (clause),
9824 true);
9825 gimplify_omp_ctxp = ctx;
9826 return 0;
9829 static void
9830 gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
9831 enum tree_code code)
9833 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
9834 tree *orig_list_p = list_p;
9835 tree c, decl;
9836 bool has_inscan_reductions = false;
9838 if (body)
9840 struct gimplify_omp_ctx *octx;
9841 for (octx = ctx; octx; octx = octx->outer_context)
9842 if ((octx->region_type & (ORT_PARALLEL | ORT_TASK | ORT_TEAMS)) != 0)
9843 break;
9844 if (octx)
9846 struct walk_stmt_info wi;
9847 memset (&wi, 0, sizeof (wi));
9848 walk_gimple_seq (body, omp_find_stores_stmt,
9849 omp_find_stores_op, &wi);
9853 if (ctx->add_safelen1)
9855 /* If there are VLAs in the body of simd loop, prevent
9856 vectorization. */
9857 gcc_assert (ctx->region_type == ORT_SIMD);
9858 c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_SAFELEN);
9859 OMP_CLAUSE_SAFELEN_EXPR (c) = integer_one_node;
9860 OMP_CLAUSE_CHAIN (c) = *list_p;
9861 *list_p = c;
9862 list_p = &OMP_CLAUSE_CHAIN (c);
9865 if (ctx->region_type == ORT_WORKSHARE
9866 && ctx->outer_context
9867 && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL)
9869 for (c = ctx->outer_context->clauses; c; c = OMP_CLAUSE_CHAIN (c))
9870 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
9871 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
9873 decl = OMP_CLAUSE_DECL (c);
9874 splay_tree_node n
9875 = splay_tree_lookup (ctx->outer_context->variables,
9876 (splay_tree_key) decl);
9877 gcc_checking_assert (!splay_tree_lookup (ctx->variables,
9878 (splay_tree_key) decl));
9879 omp_add_variable (ctx, decl, n->value);
9880 tree c2 = copy_node (c);
9881 OMP_CLAUSE_CHAIN (c2) = *list_p;
9882 *list_p = c2;
9883 if ((n->value & GOVD_FIRSTPRIVATE) == 0)
9884 continue;
9885 c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9886 OMP_CLAUSE_FIRSTPRIVATE);
9887 OMP_CLAUSE_DECL (c2) = decl;
9888 OMP_CLAUSE_CHAIN (c2) = *list_p;
9889 *list_p = c2;
9892 while ((c = *list_p) != NULL)
9894 splay_tree_node n;
9895 bool remove = false;
9897 switch (OMP_CLAUSE_CODE (c))
9899 case OMP_CLAUSE_FIRSTPRIVATE:
9900 if ((ctx->region_type & ORT_TARGET)
9901 && (ctx->region_type & ORT_ACC) == 0
9902 && TYPE_ATOMIC (strip_array_types
9903 (TREE_TYPE (OMP_CLAUSE_DECL (c)))))
9905 error_at (OMP_CLAUSE_LOCATION (c),
9906 "%<_Atomic%> %qD in %<firstprivate%> clause on "
9907 "%<target%> construct", OMP_CLAUSE_DECL (c));
9908 remove = true;
9909 break;
9911 /* FALLTHRU */
9912 case OMP_CLAUSE_PRIVATE:
9913 case OMP_CLAUSE_SHARED:
9914 case OMP_CLAUSE_LINEAR:
9915 decl = OMP_CLAUSE_DECL (c);
9916 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
9917 remove = !(n->value & GOVD_SEEN);
9918 if ((n->value & GOVD_LASTPRIVATE_CONDITIONAL) != 0
9919 && code == OMP_PARALLEL
9920 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
9921 remove = true;
9922 if (! remove)
9924 bool shared = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED;
9925 if ((n->value & GOVD_DEBUG_PRIVATE)
9926 || lang_hooks.decls.omp_private_debug_clause (decl, shared))
9928 gcc_assert ((n->value & GOVD_DEBUG_PRIVATE) == 0
9929 || ((n->value & GOVD_DATA_SHARE_CLASS)
9930 == GOVD_SHARED));
9931 OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_PRIVATE);
9932 OMP_CLAUSE_PRIVATE_DEBUG (c) = 1;
9934 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
9935 && (n->value & GOVD_WRITTEN) == 0
9936 && DECL_P (decl)
9937 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
9938 OMP_CLAUSE_SHARED_READONLY (c) = 1;
9939 else if (DECL_P (decl)
9940 && ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
9941 && (n->value & GOVD_WRITTEN) != 0)
9942 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
9943 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
9944 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
9945 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
9947 break;
9949 case OMP_CLAUSE_LASTPRIVATE:
9950 /* Make sure OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE is set to
9951 accurately reflect the presence of a FIRSTPRIVATE clause. */
9952 decl = OMP_CLAUSE_DECL (c);
9953 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
9954 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c)
9955 = (n->value & GOVD_FIRSTPRIVATE) != 0;
9956 if (code == OMP_DISTRIBUTE
9957 && OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
9959 remove = true;
9960 error_at (OMP_CLAUSE_LOCATION (c),
9961 "same variable used in %<firstprivate%> and "
9962 "%<lastprivate%> clauses on %<distribute%> "
9963 "construct");
9965 if (!remove
9966 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
9967 && DECL_P (decl)
9968 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
9969 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
9970 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) && code == OMP_PARALLEL)
9971 remove = true;
9972 break;
9974 case OMP_CLAUSE_ALIGNED:
9975 decl = OMP_CLAUSE_DECL (c);
9976 if (!is_global_var (decl))
9978 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
9979 remove = n == NULL || !(n->value & GOVD_SEEN);
9980 if (!remove && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
9982 struct gimplify_omp_ctx *octx;
9983 if (n != NULL
9984 && (n->value & (GOVD_DATA_SHARE_CLASS
9985 & ~GOVD_FIRSTPRIVATE)))
9986 remove = true;
9987 else
9988 for (octx = ctx->outer_context; octx;
9989 octx = octx->outer_context)
9991 n = splay_tree_lookup (octx->variables,
9992 (splay_tree_key) decl);
9993 if (n == NULL)
9994 continue;
9995 if (n->value & GOVD_LOCAL)
9996 break;
9997 /* We have to avoid assigning a shared variable
9998 to itself when trying to add
9999 __builtin_assume_aligned. */
10000 if (n->value & GOVD_SHARED)
10002 remove = true;
10003 break;
10008 else if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
10010 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10011 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
10012 remove = true;
10014 break;
10016 case OMP_CLAUSE_NONTEMPORAL:
10017 decl = OMP_CLAUSE_DECL (c);
10018 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10019 remove = n == NULL || !(n->value & GOVD_SEEN);
10020 break;
10022 case OMP_CLAUSE_MAP:
10023 if (code == OMP_TARGET_EXIT_DATA
10024 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER)
10026 remove = true;
10027 break;
10029 decl = OMP_CLAUSE_DECL (c);
10030 /* Data clauses associated with acc parallel reductions must be
10031 compatible with present_or_copy. Warn and adjust the clause
10032 if that is not the case. */
10033 if (ctx->region_type == ORT_ACC_PARALLEL)
10035 tree t = DECL_P (decl) ? decl : TREE_OPERAND (decl, 0);
10036 n = NULL;
10038 if (DECL_P (t))
10039 n = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
10041 if (n && (n->value & GOVD_REDUCTION))
10043 enum gomp_map_kind kind = OMP_CLAUSE_MAP_KIND (c);
10045 OMP_CLAUSE_MAP_IN_REDUCTION (c) = 1;
10046 if ((kind & GOMP_MAP_TOFROM) != GOMP_MAP_TOFROM
10047 && kind != GOMP_MAP_FORCE_PRESENT
10048 && kind != GOMP_MAP_POINTER)
10050 warning_at (OMP_CLAUSE_LOCATION (c), 0,
10051 "incompatible data clause with reduction "
10052 "on %qE; promoting to %<present_or_copy%>",
10053 DECL_NAME (t));
10054 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TOFROM);
10058 if (!DECL_P (decl))
10060 if ((ctx->region_type & ORT_TARGET) != 0
10061 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
10063 if (TREE_CODE (decl) == INDIRECT_REF
10064 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
10065 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
10066 == REFERENCE_TYPE))
10067 decl = TREE_OPERAND (decl, 0);
10068 if (TREE_CODE (decl) == COMPONENT_REF)
10070 while (TREE_CODE (decl) == COMPONENT_REF)
10071 decl = TREE_OPERAND (decl, 0);
10072 if (DECL_P (decl))
10074 n = splay_tree_lookup (ctx->variables,
10075 (splay_tree_key) decl);
10076 if (!(n->value & GOVD_SEEN))
10077 remove = true;
10081 break;
10083 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10084 if ((ctx->region_type & ORT_TARGET) != 0
10085 && !(n->value & GOVD_SEEN)
10086 && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) == 0
10087 && (!is_global_var (decl)
10088 || !lookup_attribute ("omp declare target link",
10089 DECL_ATTRIBUTES (decl))))
10091 remove = true;
10092 /* For struct element mapping, if struct is never referenced
10093 in target block and none of the mapping has always modifier,
10094 remove all the struct element mappings, which immediately
10095 follow the GOMP_MAP_STRUCT map clause. */
10096 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT)
10098 HOST_WIDE_INT cnt = tree_to_shwi (OMP_CLAUSE_SIZE (c));
10099 while (cnt--)
10100 OMP_CLAUSE_CHAIN (c)
10101 = OMP_CLAUSE_CHAIN (OMP_CLAUSE_CHAIN (c));
10104 else if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT
10105 && code == OMP_TARGET_EXIT_DATA)
10106 remove = true;
10107 else if (DECL_SIZE (decl)
10108 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST
10109 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_POINTER
10110 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_POINTER
10111 && (OMP_CLAUSE_MAP_KIND (c)
10112 != GOMP_MAP_FIRSTPRIVATE_REFERENCE))
10114 /* For GOMP_MAP_FORCE_DEVICEPTR, we'll never enter here, because
10115 for these, TREE_CODE (DECL_SIZE (decl)) will always be
10116 INTEGER_CST. */
10117 gcc_assert (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FORCE_DEVICEPTR);
10119 tree decl2 = DECL_VALUE_EXPR (decl);
10120 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
10121 decl2 = TREE_OPERAND (decl2, 0);
10122 gcc_assert (DECL_P (decl2));
10123 tree mem = build_simple_mem_ref (decl2);
10124 OMP_CLAUSE_DECL (c) = mem;
10125 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
10126 if (ctx->outer_context)
10128 omp_notice_variable (ctx->outer_context, decl2, true);
10129 omp_notice_variable (ctx->outer_context,
10130 OMP_CLAUSE_SIZE (c), true);
10132 if (((ctx->region_type & ORT_TARGET) != 0
10133 || !ctx->target_firstprivatize_array_bases)
10134 && ((n->value & GOVD_SEEN) == 0
10135 || (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) == 0))
10137 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
10138 OMP_CLAUSE_MAP);
10139 OMP_CLAUSE_DECL (nc) = decl;
10140 OMP_CLAUSE_SIZE (nc) = size_zero_node;
10141 if (ctx->target_firstprivatize_array_bases)
10142 OMP_CLAUSE_SET_MAP_KIND (nc,
10143 GOMP_MAP_FIRSTPRIVATE_POINTER);
10144 else
10145 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
10146 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
10147 OMP_CLAUSE_CHAIN (c) = nc;
10148 c = nc;
10151 else
10153 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
10154 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
10155 gcc_assert ((n->value & GOVD_SEEN) == 0
10156 || ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
10157 == 0));
10159 break;
10161 case OMP_CLAUSE_TO:
10162 case OMP_CLAUSE_FROM:
10163 case OMP_CLAUSE__CACHE_:
10164 decl = OMP_CLAUSE_DECL (c);
10165 if (!DECL_P (decl))
10166 break;
10167 if (DECL_SIZE (decl)
10168 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
10170 tree decl2 = DECL_VALUE_EXPR (decl);
10171 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
10172 decl2 = TREE_OPERAND (decl2, 0);
10173 gcc_assert (DECL_P (decl2));
10174 tree mem = build_simple_mem_ref (decl2);
10175 OMP_CLAUSE_DECL (c) = mem;
10176 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
10177 if (ctx->outer_context)
10179 omp_notice_variable (ctx->outer_context, decl2, true);
10180 omp_notice_variable (ctx->outer_context,
10181 OMP_CLAUSE_SIZE (c), true);
10184 else if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
10185 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
10186 break;
10188 case OMP_CLAUSE_REDUCTION:
10189 if (OMP_CLAUSE_REDUCTION_INSCAN (c))
10191 decl = OMP_CLAUSE_DECL (c);
10192 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10193 if ((n->value & GOVD_REDUCTION_INSCAN) == 0)
10195 remove = true;
10196 error_at (OMP_CLAUSE_LOCATION (c),
10197 "%qD specified in %<inscan%> %<reduction%> clause "
10198 "but not in %<scan%> directive clause", decl);
10199 break;
10201 has_inscan_reductions = true;
10203 /* FALLTHRU */
10204 case OMP_CLAUSE_IN_REDUCTION:
10205 case OMP_CLAUSE_TASK_REDUCTION:
10206 decl = OMP_CLAUSE_DECL (c);
10207 /* OpenACC reductions need a present_or_copy data clause.
10208 Add one if necessary. Emit error when the reduction is private. */
10209 if (ctx->region_type == ORT_ACC_PARALLEL)
10211 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10212 if (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
10214 remove = true;
10215 error_at (OMP_CLAUSE_LOCATION (c), "invalid private "
10216 "reduction on %qE", DECL_NAME (decl));
10218 else if ((n->value & GOVD_MAP) == 0)
10220 tree next = OMP_CLAUSE_CHAIN (c);
10221 tree nc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_MAP);
10222 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_TOFROM);
10223 OMP_CLAUSE_DECL (nc) = decl;
10224 OMP_CLAUSE_CHAIN (c) = nc;
10225 lang_hooks.decls.omp_finish_clause (nc, pre_p);
10226 while (1)
10228 OMP_CLAUSE_MAP_IN_REDUCTION (nc) = 1;
10229 if (OMP_CLAUSE_CHAIN (nc) == NULL)
10230 break;
10231 nc = OMP_CLAUSE_CHAIN (nc);
10233 OMP_CLAUSE_CHAIN (nc) = next;
10234 n->value |= GOVD_MAP;
10237 if (DECL_P (decl)
10238 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
10239 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
10240 break;
10241 case OMP_CLAUSE_COPYIN:
10242 case OMP_CLAUSE_COPYPRIVATE:
10243 case OMP_CLAUSE_IF:
10244 case OMP_CLAUSE_NUM_THREADS:
10245 case OMP_CLAUSE_NUM_TEAMS:
10246 case OMP_CLAUSE_THREAD_LIMIT:
10247 case OMP_CLAUSE_DIST_SCHEDULE:
10248 case OMP_CLAUSE_DEVICE:
10249 case OMP_CLAUSE_SCHEDULE:
10250 case OMP_CLAUSE_NOWAIT:
10251 case OMP_CLAUSE_ORDERED:
10252 case OMP_CLAUSE_DEFAULT:
10253 case OMP_CLAUSE_UNTIED:
10254 case OMP_CLAUSE_COLLAPSE:
10255 case OMP_CLAUSE_FINAL:
10256 case OMP_CLAUSE_MERGEABLE:
10257 case OMP_CLAUSE_PROC_BIND:
10258 case OMP_CLAUSE_SAFELEN:
10259 case OMP_CLAUSE_SIMDLEN:
10260 case OMP_CLAUSE_DEPEND:
10261 case OMP_CLAUSE_PRIORITY:
10262 case OMP_CLAUSE_GRAINSIZE:
10263 case OMP_CLAUSE_NUM_TASKS:
10264 case OMP_CLAUSE_NOGROUP:
10265 case OMP_CLAUSE_THREADS:
10266 case OMP_CLAUSE_SIMD:
10267 case OMP_CLAUSE_HINT:
10268 case OMP_CLAUSE_DEFAULTMAP:
10269 case OMP_CLAUSE_ORDER:
10270 case OMP_CLAUSE_BIND:
10271 case OMP_CLAUSE_USE_DEVICE_PTR:
10272 case OMP_CLAUSE_USE_DEVICE_ADDR:
10273 case OMP_CLAUSE_IS_DEVICE_PTR:
10274 case OMP_CLAUSE_ASYNC:
10275 case OMP_CLAUSE_WAIT:
10276 case OMP_CLAUSE_INDEPENDENT:
10277 case OMP_CLAUSE_NUM_GANGS:
10278 case OMP_CLAUSE_NUM_WORKERS:
10279 case OMP_CLAUSE_VECTOR_LENGTH:
10280 case OMP_CLAUSE_GANG:
10281 case OMP_CLAUSE_WORKER:
10282 case OMP_CLAUSE_VECTOR:
10283 case OMP_CLAUSE_AUTO:
10284 case OMP_CLAUSE_SEQ:
10285 case OMP_CLAUSE_TILE:
10286 case OMP_CLAUSE_IF_PRESENT:
10287 case OMP_CLAUSE_FINALIZE:
10288 case OMP_CLAUSE_INCLUSIVE:
10289 case OMP_CLAUSE_EXCLUSIVE:
10290 break;
10292 default:
10293 gcc_unreachable ();
10296 if (remove)
10297 *list_p = OMP_CLAUSE_CHAIN (c);
10298 else
10299 list_p = &OMP_CLAUSE_CHAIN (c);
10302 /* Add in any implicit data sharing. */
10303 struct gimplify_adjust_omp_clauses_data data;
10304 data.list_p = list_p;
10305 data.pre_p = pre_p;
10306 splay_tree_foreach (ctx->variables, gimplify_adjust_omp_clauses_1, &data);
10308 if (has_inscan_reductions)
10309 for (c = *orig_list_p; c; c = OMP_CLAUSE_CHAIN (c))
10310 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
10311 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
10313 error_at (OMP_CLAUSE_LOCATION (c),
10314 "%<inscan%> %<reduction%> clause used together with "
10315 "%<linear%> clause for a variable other than loop "
10316 "iterator");
10317 break;
10320 gimplify_omp_ctxp = ctx->outer_context;
10321 delete_omp_context (ctx);
10324 /* Gimplify OACC_CACHE. */
10326 static void
10327 gimplify_oacc_cache (tree *expr_p, gimple_seq *pre_p)
10329 tree expr = *expr_p;
10331 gimplify_scan_omp_clauses (&OACC_CACHE_CLAUSES (expr), pre_p, ORT_ACC,
10332 OACC_CACHE);
10333 gimplify_adjust_omp_clauses (pre_p, NULL, &OACC_CACHE_CLAUSES (expr),
10334 OACC_CACHE);
10336 /* TODO: Do something sensible with this information. */
10338 *expr_p = NULL_TREE;
10341 /* Helper function of gimplify_oacc_declare. The helper's purpose is to,
10342 if required, translate 'kind' in CLAUSE into an 'entry' kind and 'exit'
10343 kind. The entry kind will replace the one in CLAUSE, while the exit
10344 kind will be used in a new omp_clause and returned to the caller. */
10346 static tree
10347 gimplify_oacc_declare_1 (tree clause)
10349 HOST_WIDE_INT kind, new_op;
10350 bool ret = false;
10351 tree c = NULL;
10353 kind = OMP_CLAUSE_MAP_KIND (clause);
10355 switch (kind)
10357 case GOMP_MAP_ALLOC:
10358 new_op = GOMP_MAP_RELEASE;
10359 ret = true;
10360 break;
10362 case GOMP_MAP_FROM:
10363 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_FORCE_ALLOC);
10364 new_op = GOMP_MAP_FROM;
10365 ret = true;
10366 break;
10368 case GOMP_MAP_TOFROM:
10369 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_TO);
10370 new_op = GOMP_MAP_FROM;
10371 ret = true;
10372 break;
10374 case GOMP_MAP_DEVICE_RESIDENT:
10375 case GOMP_MAP_FORCE_DEVICEPTR:
10376 case GOMP_MAP_FORCE_PRESENT:
10377 case GOMP_MAP_LINK:
10378 case GOMP_MAP_POINTER:
10379 case GOMP_MAP_TO:
10380 break;
10382 default:
10383 gcc_unreachable ();
10384 break;
10387 if (ret)
10389 c = build_omp_clause (OMP_CLAUSE_LOCATION (clause), OMP_CLAUSE_MAP);
10390 OMP_CLAUSE_SET_MAP_KIND (c, new_op);
10391 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clause);
10394 return c;
10397 /* Gimplify OACC_DECLARE. */
10399 static void
10400 gimplify_oacc_declare (tree *expr_p, gimple_seq *pre_p)
10402 tree expr = *expr_p;
10403 gomp_target *stmt;
10404 tree clauses, t, decl;
10406 clauses = OACC_DECLARE_CLAUSES (expr);
10408 gimplify_scan_omp_clauses (&clauses, pre_p, ORT_TARGET_DATA, OACC_DECLARE);
10409 gimplify_adjust_omp_clauses (pre_p, NULL, &clauses, OACC_DECLARE);
10411 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
10413 decl = OMP_CLAUSE_DECL (t);
10415 if (TREE_CODE (decl) == MEM_REF)
10416 decl = TREE_OPERAND (decl, 0);
10418 if (VAR_P (decl) && !is_oacc_declared (decl))
10420 tree attr = get_identifier ("oacc declare target");
10421 DECL_ATTRIBUTES (decl) = tree_cons (attr, NULL_TREE,
10422 DECL_ATTRIBUTES (decl));
10425 if (VAR_P (decl)
10426 && !is_global_var (decl)
10427 && DECL_CONTEXT (decl) == current_function_decl)
10429 tree c = gimplify_oacc_declare_1 (t);
10430 if (c)
10432 if (oacc_declare_returns == NULL)
10433 oacc_declare_returns = new hash_map<tree, tree>;
10435 oacc_declare_returns->put (decl, c);
10439 if (gimplify_omp_ctxp)
10440 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_SEEN);
10443 stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
10444 clauses);
10446 gimplify_seq_add_stmt (pre_p, stmt);
10448 *expr_p = NULL_TREE;
10451 /* Gimplify the contents of an OMP_PARALLEL statement. This involves
10452 gimplification of the body, as well as scanning the body for used
10453 variables. We need to do this scan now, because variable-sized
10454 decls will be decomposed during gimplification. */
10456 static void
10457 gimplify_omp_parallel (tree *expr_p, gimple_seq *pre_p)
10459 tree expr = *expr_p;
10460 gimple *g;
10461 gimple_seq body = NULL;
10463 gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr), pre_p,
10464 OMP_PARALLEL_COMBINED (expr)
10465 ? ORT_COMBINED_PARALLEL
10466 : ORT_PARALLEL, OMP_PARALLEL);
10468 push_gimplify_context ();
10470 g = gimplify_and_return_first (OMP_PARALLEL_BODY (expr), &body);
10471 if (gimple_code (g) == GIMPLE_BIND)
10472 pop_gimplify_context (g);
10473 else
10474 pop_gimplify_context (NULL);
10476 gimplify_adjust_omp_clauses (pre_p, body, &OMP_PARALLEL_CLAUSES (expr),
10477 OMP_PARALLEL);
10479 g = gimple_build_omp_parallel (body,
10480 OMP_PARALLEL_CLAUSES (expr),
10481 NULL_TREE, NULL_TREE);
10482 if (OMP_PARALLEL_COMBINED (expr))
10483 gimple_omp_set_subcode (g, GF_OMP_PARALLEL_COMBINED);
10484 gimplify_seq_add_stmt (pre_p, g);
10485 *expr_p = NULL_TREE;
10488 /* Gimplify the contents of an OMP_TASK statement. This involves
10489 gimplification of the body, as well as scanning the body for used
10490 variables. We need to do this scan now, because variable-sized
10491 decls will be decomposed during gimplification. */
10493 static void
10494 gimplify_omp_task (tree *expr_p, gimple_seq *pre_p)
10496 tree expr = *expr_p;
10497 gimple *g;
10498 gimple_seq body = NULL;
10500 if (OMP_TASK_BODY (expr) == NULL_TREE)
10501 for (tree c = OMP_TASK_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
10502 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
10503 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_MUTEXINOUTSET)
10505 error_at (OMP_CLAUSE_LOCATION (c),
10506 "%<mutexinoutset%> kind in %<depend%> clause on a "
10507 "%<taskwait%> construct");
10508 break;
10511 gimplify_scan_omp_clauses (&OMP_TASK_CLAUSES (expr), pre_p,
10512 omp_find_clause (OMP_TASK_CLAUSES (expr),
10513 OMP_CLAUSE_UNTIED)
10514 ? ORT_UNTIED_TASK : ORT_TASK, OMP_TASK);
10516 if (OMP_TASK_BODY (expr))
10518 push_gimplify_context ();
10520 g = gimplify_and_return_first (OMP_TASK_BODY (expr), &body);
10521 if (gimple_code (g) == GIMPLE_BIND)
10522 pop_gimplify_context (g);
10523 else
10524 pop_gimplify_context (NULL);
10527 gimplify_adjust_omp_clauses (pre_p, body, &OMP_TASK_CLAUSES (expr),
10528 OMP_TASK);
10530 g = gimple_build_omp_task (body,
10531 OMP_TASK_CLAUSES (expr),
10532 NULL_TREE, NULL_TREE,
10533 NULL_TREE, NULL_TREE, NULL_TREE);
10534 if (OMP_TASK_BODY (expr) == NULL_TREE)
10535 gimple_omp_task_set_taskwait_p (g, true);
10536 gimplify_seq_add_stmt (pre_p, g);
10537 *expr_p = NULL_TREE;
10540 /* Helper function of gimplify_omp_for, find OMP_FOR resp. OMP_SIMD
10541 with non-NULL OMP_FOR_INIT. Also, fill in pdata array,
10542 pdata[0] non-NULL if there is anything non-trivial in between, pdata[1]
10543 is address of OMP_PARALLEL in between if any, pdata[2] is address of
10544 OMP_FOR in between if any and pdata[3] is address of the inner
10545 OMP_FOR/OMP_SIMD. */
10547 static tree
10548 find_combined_omp_for (tree *tp, int *walk_subtrees, void *data)
10550 tree **pdata = (tree **) data;
10551 *walk_subtrees = 0;
10552 switch (TREE_CODE (*tp))
10554 case OMP_FOR:
10555 if (OMP_FOR_INIT (*tp) != NULL_TREE)
10557 pdata[3] = tp;
10558 return *tp;
10560 pdata[2] = tp;
10561 *walk_subtrees = 1;
10562 break;
10563 case OMP_SIMD:
10564 if (OMP_FOR_INIT (*tp) != NULL_TREE)
10566 pdata[3] = tp;
10567 return *tp;
10569 break;
10570 case BIND_EXPR:
10571 if (BIND_EXPR_VARS (*tp)
10572 || (BIND_EXPR_BLOCK (*tp)
10573 && BLOCK_VARS (BIND_EXPR_BLOCK (*tp))))
10574 pdata[0] = tp;
10575 *walk_subtrees = 1;
10576 break;
10577 case STATEMENT_LIST:
10578 if (!tsi_one_before_end_p (tsi_start (*tp)))
10579 pdata[0] = tp;
10580 *walk_subtrees = 1;
10581 break;
10582 case TRY_FINALLY_EXPR:
10583 pdata[0] = tp;
10584 *walk_subtrees = 1;
10585 break;
10586 case OMP_PARALLEL:
10587 pdata[1] = tp;
10588 *walk_subtrees = 1;
10589 break;
10590 default:
10591 break;
10593 return NULL_TREE;
10596 /* Gimplify the gross structure of an OMP_FOR statement. */
10598 static enum gimplify_status
10599 gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
10601 tree for_stmt, orig_for_stmt, inner_for_stmt = NULL_TREE, decl, var, t;
10602 enum gimplify_status ret = GS_ALL_DONE;
10603 enum gimplify_status tret;
10604 gomp_for *gfor;
10605 gimple_seq for_body, for_pre_body;
10606 int i;
10607 bitmap has_decl_expr = NULL;
10608 enum omp_region_type ort = ORT_WORKSHARE;
10610 orig_for_stmt = for_stmt = *expr_p;
10612 bool loop_p = (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_BIND)
10613 != NULL_TREE);
10614 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
10616 tree *data[4] = { NULL, NULL, NULL, NULL };
10617 gcc_assert (TREE_CODE (for_stmt) != OACC_LOOP);
10618 inner_for_stmt = walk_tree (&OMP_FOR_BODY (for_stmt),
10619 find_combined_omp_for, data, NULL);
10620 if (inner_for_stmt == NULL_TREE)
10622 gcc_assert (seen_error ());
10623 *expr_p = NULL_TREE;
10624 return GS_ERROR;
10626 if (data[2] && OMP_FOR_PRE_BODY (*data[2]))
10628 append_to_statement_list_force (OMP_FOR_PRE_BODY (*data[2]),
10629 &OMP_FOR_PRE_BODY (for_stmt));
10630 OMP_FOR_PRE_BODY (*data[2]) = NULL_TREE;
10632 if (OMP_FOR_PRE_BODY (inner_for_stmt))
10634 append_to_statement_list_force (OMP_FOR_PRE_BODY (inner_for_stmt),
10635 &OMP_FOR_PRE_BODY (for_stmt));
10636 OMP_FOR_PRE_BODY (inner_for_stmt) = NULL_TREE;
10639 if (data[0])
10641 /* We have some statements or variable declarations in between
10642 the composite construct directives. Move them around the
10643 inner_for_stmt. */
10644 data[0] = expr_p;
10645 for (i = 0; i < 3; i++)
10646 if (data[i])
10648 tree t = *data[i];
10649 if (i < 2 && data[i + 1] == &OMP_BODY (t))
10650 data[i + 1] = data[i];
10651 *data[i] = OMP_BODY (t);
10652 tree body = build3 (BIND_EXPR, void_type_node, NULL_TREE,
10653 NULL_TREE, make_node (BLOCK));
10654 OMP_BODY (t) = body;
10655 append_to_statement_list_force (inner_for_stmt,
10656 &BIND_EXPR_BODY (body));
10657 *data[3] = t;
10658 data[3] = tsi_stmt_ptr (tsi_start (BIND_EXPR_BODY (body)));
10659 gcc_assert (*data[3] == inner_for_stmt);
10661 return GS_OK;
10664 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
10665 if (!loop_p
10666 && OMP_FOR_ORIG_DECLS (inner_for_stmt)
10667 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
10668 i)) == TREE_LIST
10669 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
10670 i)))
10672 tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
10673 /* Class iterators aren't allowed on OMP_SIMD, so the only
10674 case we need to solve is distribute parallel for. They are
10675 allowed on the loop construct, but that is already handled
10676 in gimplify_omp_loop. */
10677 gcc_assert (TREE_CODE (inner_for_stmt) == OMP_FOR
10678 && TREE_CODE (for_stmt) == OMP_DISTRIBUTE
10679 && data[1]);
10680 tree orig_decl = TREE_PURPOSE (orig);
10681 tree last = TREE_VALUE (orig);
10682 tree *pc;
10683 for (pc = &OMP_FOR_CLAUSES (inner_for_stmt);
10684 *pc; pc = &OMP_CLAUSE_CHAIN (*pc))
10685 if ((OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE
10686 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LASTPRIVATE)
10687 && OMP_CLAUSE_DECL (*pc) == orig_decl)
10688 break;
10689 if (*pc == NULL_TREE)
10691 tree *spc;
10692 for (spc = &OMP_PARALLEL_CLAUSES (*data[1]);
10693 *spc; spc = &OMP_CLAUSE_CHAIN (*spc))
10694 if (OMP_CLAUSE_CODE (*spc) == OMP_CLAUSE_PRIVATE
10695 && OMP_CLAUSE_DECL (*spc) == orig_decl)
10696 break;
10697 if (*spc)
10699 tree c = *spc;
10700 *spc = OMP_CLAUSE_CHAIN (c);
10701 OMP_CLAUSE_CHAIN (c) = NULL_TREE;
10702 *pc = c;
10705 if (*pc == NULL_TREE)
10707 else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE)
10709 /* private clause will appear only on inner_for_stmt.
10710 Change it into firstprivate, and add private clause
10711 on for_stmt. */
10712 tree c = copy_node (*pc);
10713 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
10714 OMP_FOR_CLAUSES (for_stmt) = c;
10715 OMP_CLAUSE_CODE (*pc) = OMP_CLAUSE_FIRSTPRIVATE;
10716 lang_hooks.decls.omp_finish_clause (*pc, pre_p);
10718 else
10720 /* lastprivate clause will appear on both inner_for_stmt
10721 and for_stmt. Add firstprivate clause to
10722 inner_for_stmt. */
10723 tree c = build_omp_clause (OMP_CLAUSE_LOCATION (*pc),
10724 OMP_CLAUSE_FIRSTPRIVATE);
10725 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (*pc);
10726 OMP_CLAUSE_CHAIN (c) = *pc;
10727 *pc = c;
10728 lang_hooks.decls.omp_finish_clause (*pc, pre_p);
10730 tree c = build_omp_clause (UNKNOWN_LOCATION,
10731 OMP_CLAUSE_FIRSTPRIVATE);
10732 OMP_CLAUSE_DECL (c) = last;
10733 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
10734 OMP_PARALLEL_CLAUSES (*data[1]) = c;
10735 c = build_omp_clause (UNKNOWN_LOCATION,
10736 *pc ? OMP_CLAUSE_SHARED
10737 : OMP_CLAUSE_FIRSTPRIVATE);
10738 OMP_CLAUSE_DECL (c) = orig_decl;
10739 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
10740 OMP_PARALLEL_CLAUSES (*data[1]) = c;
10742 /* Similarly, take care of C++ range for temporaries, those should
10743 be firstprivate on OMP_PARALLEL if any. */
10744 if (data[1])
10745 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
10746 if (OMP_FOR_ORIG_DECLS (inner_for_stmt)
10747 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
10748 i)) == TREE_LIST
10749 && TREE_CHAIN (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
10750 i)))
10752 tree orig
10753 = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
10754 tree v = TREE_CHAIN (orig);
10755 tree c = build_omp_clause (UNKNOWN_LOCATION,
10756 OMP_CLAUSE_FIRSTPRIVATE);
10757 /* First add firstprivate clause for the __for_end artificial
10758 decl. */
10759 OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 1);
10760 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
10761 == REFERENCE_TYPE)
10762 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
10763 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
10764 OMP_PARALLEL_CLAUSES (*data[1]) = c;
10765 if (TREE_VEC_ELT (v, 0))
10767 /* And now the same for __for_range artificial decl if it
10768 exists. */
10769 c = build_omp_clause (UNKNOWN_LOCATION,
10770 OMP_CLAUSE_FIRSTPRIVATE);
10771 OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 0);
10772 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
10773 == REFERENCE_TYPE)
10774 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
10775 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
10776 OMP_PARALLEL_CLAUSES (*data[1]) = c;
10781 switch (TREE_CODE (for_stmt))
10783 case OMP_FOR:
10784 case OMP_DISTRIBUTE:
10785 break;
10786 case OACC_LOOP:
10787 ort = ORT_ACC;
10788 break;
10789 case OMP_TASKLOOP:
10790 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_UNTIED))
10791 ort = ORT_UNTIED_TASKLOOP;
10792 else
10793 ort = ORT_TASKLOOP;
10794 break;
10795 case OMP_SIMD:
10796 ort = ORT_SIMD;
10797 break;
10798 default:
10799 gcc_unreachable ();
10802 /* Set OMP_CLAUSE_LINEAR_NO_COPYIN flag on explicit linear
10803 clause for the IV. */
10804 if (ort == ORT_SIMD && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
10806 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), 0);
10807 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
10808 decl = TREE_OPERAND (t, 0);
10809 for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
10810 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
10811 && OMP_CLAUSE_DECL (c) == decl)
10813 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
10814 break;
10818 if (TREE_CODE (for_stmt) != OMP_TASKLOOP)
10819 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p, ort,
10820 loop_p && TREE_CODE (for_stmt) != OMP_SIMD
10821 ? OMP_LOOP : TREE_CODE (for_stmt));
10823 if (TREE_CODE (for_stmt) == OMP_DISTRIBUTE)
10824 gimplify_omp_ctxp->distribute = true;
10826 /* Handle OMP_FOR_INIT. */
10827 for_pre_body = NULL;
10828 if ((ort == ORT_SIMD
10829 || (inner_for_stmt && TREE_CODE (inner_for_stmt) == OMP_SIMD))
10830 && OMP_FOR_PRE_BODY (for_stmt))
10832 has_decl_expr = BITMAP_ALLOC (NULL);
10833 if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == DECL_EXPR
10834 && TREE_CODE (DECL_EXPR_DECL (OMP_FOR_PRE_BODY (for_stmt)))
10835 == VAR_DECL)
10837 t = OMP_FOR_PRE_BODY (for_stmt);
10838 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
10840 else if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == STATEMENT_LIST)
10842 tree_stmt_iterator si;
10843 for (si = tsi_start (OMP_FOR_PRE_BODY (for_stmt)); !tsi_end_p (si);
10844 tsi_next (&si))
10846 t = tsi_stmt (si);
10847 if (TREE_CODE (t) == DECL_EXPR
10848 && TREE_CODE (DECL_EXPR_DECL (t)) == VAR_DECL)
10849 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
10853 if (OMP_FOR_PRE_BODY (for_stmt))
10855 if (TREE_CODE (for_stmt) != OMP_TASKLOOP || gimplify_omp_ctxp)
10856 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
10857 else
10859 struct gimplify_omp_ctx ctx;
10860 memset (&ctx, 0, sizeof (ctx));
10861 ctx.region_type = ORT_NONE;
10862 gimplify_omp_ctxp = &ctx;
10863 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
10864 gimplify_omp_ctxp = NULL;
10867 OMP_FOR_PRE_BODY (for_stmt) = NULL_TREE;
10869 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
10870 for_stmt = inner_for_stmt;
10872 /* For taskloop, need to gimplify the start, end and step before the
10873 taskloop, outside of the taskloop omp context. */
10874 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
10876 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
10878 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
10879 if (!is_gimple_constant (TREE_OPERAND (t, 1)))
10881 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
10882 TREE_OPERAND (t, 1)
10883 = get_initialized_tmp_var (TREE_OPERAND (t, 1),
10884 gimple_seq_empty_p (for_pre_body)
10885 ? pre_p : &for_pre_body, NULL,
10886 false);
10887 /* Reference to pointer conversion is considered useless,
10888 but is significant for firstprivate clause. Force it
10889 here. */
10890 if (TREE_CODE (type) == POINTER_TYPE
10891 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 1)))
10892 == REFERENCE_TYPE))
10894 tree v = create_tmp_var (TYPE_MAIN_VARIANT (type));
10895 tree m = build2 (INIT_EXPR, TREE_TYPE (v), v,
10896 TREE_OPERAND (t, 1));
10897 gimplify_and_add (m, gimple_seq_empty_p (for_pre_body)
10898 ? pre_p : &for_pre_body);
10899 TREE_OPERAND (t, 1) = v;
10901 tree c = build_omp_clause (input_location,
10902 OMP_CLAUSE_FIRSTPRIVATE);
10903 OMP_CLAUSE_DECL (c) = TREE_OPERAND (t, 1);
10904 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
10905 OMP_FOR_CLAUSES (orig_for_stmt) = c;
10908 /* Handle OMP_FOR_COND. */
10909 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
10910 if (!is_gimple_constant (TREE_OPERAND (t, 1)))
10912 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
10913 TREE_OPERAND (t, 1)
10914 = get_initialized_tmp_var (TREE_OPERAND (t, 1),
10915 gimple_seq_empty_p (for_pre_body)
10916 ? pre_p : &for_pre_body, NULL,
10917 false);
10918 /* Reference to pointer conversion is considered useless,
10919 but is significant for firstprivate clause. Force it
10920 here. */
10921 if (TREE_CODE (type) == POINTER_TYPE
10922 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 1)))
10923 == REFERENCE_TYPE))
10925 tree v = create_tmp_var (TYPE_MAIN_VARIANT (type));
10926 tree m = build2 (INIT_EXPR, TREE_TYPE (v), v,
10927 TREE_OPERAND (t, 1));
10928 gimplify_and_add (m, gimple_seq_empty_p (for_pre_body)
10929 ? pre_p : &for_pre_body);
10930 TREE_OPERAND (t, 1) = v;
10932 tree c = build_omp_clause (input_location,
10933 OMP_CLAUSE_FIRSTPRIVATE);
10934 OMP_CLAUSE_DECL (c) = TREE_OPERAND (t, 1);
10935 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
10936 OMP_FOR_CLAUSES (orig_for_stmt) = c;
10939 /* Handle OMP_FOR_INCR. */
10940 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
10941 if (TREE_CODE (t) == MODIFY_EXPR)
10943 decl = TREE_OPERAND (t, 0);
10944 t = TREE_OPERAND (t, 1);
10945 tree *tp = &TREE_OPERAND (t, 1);
10946 if (TREE_CODE (t) == PLUS_EXPR && *tp == decl)
10947 tp = &TREE_OPERAND (t, 0);
10949 if (!is_gimple_constant (*tp))
10951 gimple_seq *seq = gimple_seq_empty_p (for_pre_body)
10952 ? pre_p : &for_pre_body;
10953 *tp = get_initialized_tmp_var (*tp, seq, NULL, false);
10954 tree c = build_omp_clause (input_location,
10955 OMP_CLAUSE_FIRSTPRIVATE);
10956 OMP_CLAUSE_DECL (c) = *tp;
10957 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
10958 OMP_FOR_CLAUSES (orig_for_stmt) = c;
10963 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (orig_for_stmt), pre_p, ort,
10964 OMP_TASKLOOP);
10967 if (orig_for_stmt != for_stmt)
10968 gimplify_omp_ctxp->combined_loop = true;
10970 for_body = NULL;
10971 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
10972 == TREE_VEC_LENGTH (OMP_FOR_COND (for_stmt)));
10973 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
10974 == TREE_VEC_LENGTH (OMP_FOR_INCR (for_stmt)));
10976 tree c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED);
10977 bool is_doacross = false;
10978 if (c && OMP_CLAUSE_ORDERED_EXPR (c))
10980 is_doacross = true;
10981 gimplify_omp_ctxp->loop_iter_var.create (TREE_VEC_LENGTH
10982 (OMP_FOR_INIT (for_stmt))
10983 * 2);
10985 int collapse = 1, tile = 0;
10986 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_COLLAPSE);
10987 if (c)
10988 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (c));
10989 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_TILE);
10990 if (c)
10991 tile = list_length (OMP_CLAUSE_TILE_LIST (c));
10992 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
10994 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
10995 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
10996 decl = TREE_OPERAND (t, 0);
10997 gcc_assert (DECL_P (decl));
10998 gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl))
10999 || POINTER_TYPE_P (TREE_TYPE (decl)));
11000 if (is_doacross)
11002 if (TREE_CODE (for_stmt) == OMP_FOR && OMP_FOR_ORIG_DECLS (for_stmt))
11004 tree orig_decl = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
11005 if (TREE_CODE (orig_decl) == TREE_LIST)
11007 orig_decl = TREE_PURPOSE (orig_decl);
11008 if (!orig_decl)
11009 orig_decl = decl;
11011 gimplify_omp_ctxp->loop_iter_var.quick_push (orig_decl);
11013 else
11014 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
11015 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
11018 /* Make sure the iteration variable is private. */
11019 tree c = NULL_TREE;
11020 tree c2 = NULL_TREE;
11021 if (orig_for_stmt != for_stmt)
11023 /* Preserve this information until we gimplify the inner simd. */
11024 if (has_decl_expr
11025 && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
11026 TREE_PRIVATE (t) = 1;
11028 else if (ort == ORT_SIMD)
11030 splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
11031 (splay_tree_key) decl);
11032 omp_is_private (gimplify_omp_ctxp, decl,
11033 1 + (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
11034 != 1));
11035 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
11037 omp_notice_variable (gimplify_omp_ctxp, decl, true);
11038 if (n->value & GOVD_LASTPRIVATE_CONDITIONAL)
11039 for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
11040 OMP_CLAUSE_LASTPRIVATE);
11041 c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
11042 OMP_CLAUSE_LASTPRIVATE))
11043 if (OMP_CLAUSE_DECL (c3) == decl)
11045 warning_at (OMP_CLAUSE_LOCATION (c3), 0,
11046 "conditional %<lastprivate%> on loop "
11047 "iterator %qD ignored", decl);
11048 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
11049 n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
11052 else if (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1 && !loop_p)
11054 c = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
11055 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
11056 unsigned int flags = GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN;
11057 if ((has_decl_expr
11058 && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
11059 || TREE_PRIVATE (t))
11061 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
11062 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
11064 struct gimplify_omp_ctx *outer
11065 = gimplify_omp_ctxp->outer_context;
11066 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
11068 if (outer->region_type == ORT_WORKSHARE
11069 && outer->combined_loop)
11071 n = splay_tree_lookup (outer->variables,
11072 (splay_tree_key)decl);
11073 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
11075 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
11076 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
11078 else
11080 struct gimplify_omp_ctx *octx = outer->outer_context;
11081 if (octx
11082 && octx->region_type == ORT_COMBINED_PARALLEL
11083 && octx->outer_context
11084 && (octx->outer_context->region_type
11085 == ORT_WORKSHARE)
11086 && octx->outer_context->combined_loop)
11088 octx = octx->outer_context;
11089 n = splay_tree_lookup (octx->variables,
11090 (splay_tree_key)decl);
11091 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
11093 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
11094 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
11101 OMP_CLAUSE_DECL (c) = decl;
11102 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
11103 OMP_FOR_CLAUSES (for_stmt) = c;
11104 omp_add_variable (gimplify_omp_ctxp, decl, flags);
11105 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
11107 if (outer->region_type == ORT_WORKSHARE
11108 && outer->combined_loop)
11110 if (outer->outer_context
11111 && (outer->outer_context->region_type
11112 == ORT_COMBINED_PARALLEL))
11113 outer = outer->outer_context;
11114 else if (omp_check_private (outer, decl, false))
11115 outer = NULL;
11117 else if (((outer->region_type & ORT_TASKLOOP)
11118 == ORT_TASKLOOP)
11119 && outer->combined_loop
11120 && !omp_check_private (gimplify_omp_ctxp,
11121 decl, false))
11123 else if (outer->region_type != ORT_COMBINED_PARALLEL)
11125 omp_notice_variable (outer, decl, true);
11126 outer = NULL;
11128 if (outer)
11130 n = splay_tree_lookup (outer->variables,
11131 (splay_tree_key)decl);
11132 if (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
11134 omp_add_variable (outer, decl,
11135 GOVD_LASTPRIVATE | GOVD_SEEN);
11136 if (outer->region_type == ORT_COMBINED_PARALLEL
11137 && outer->outer_context
11138 && (outer->outer_context->region_type
11139 == ORT_WORKSHARE)
11140 && outer->outer_context->combined_loop)
11142 outer = outer->outer_context;
11143 n = splay_tree_lookup (outer->variables,
11144 (splay_tree_key)decl);
11145 if (omp_check_private (outer, decl, false))
11146 outer = NULL;
11147 else if (n == NULL
11148 || ((n->value & GOVD_DATA_SHARE_CLASS)
11149 == 0))
11150 omp_add_variable (outer, decl,
11151 GOVD_LASTPRIVATE
11152 | GOVD_SEEN);
11153 else
11154 outer = NULL;
11156 if (outer && outer->outer_context
11157 && ((outer->outer_context->region_type
11158 & ORT_COMBINED_TEAMS) == ORT_COMBINED_TEAMS
11159 || (((outer->region_type & ORT_TASKLOOP)
11160 == ORT_TASKLOOP)
11161 && (outer->outer_context->region_type
11162 == ORT_COMBINED_PARALLEL))))
11164 outer = outer->outer_context;
11165 n = splay_tree_lookup (outer->variables,
11166 (splay_tree_key)decl);
11167 if (n == NULL
11168 || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
11169 omp_add_variable (outer, decl,
11170 GOVD_SHARED | GOVD_SEEN);
11171 else
11172 outer = NULL;
11174 if (outer && outer->outer_context)
11175 omp_notice_variable (outer->outer_context, decl,
11176 true);
11181 else
11183 bool lastprivate
11184 = (!has_decl_expr
11185 || !bitmap_bit_p (has_decl_expr, DECL_UID (decl)));
11186 if (TREE_PRIVATE (t))
11187 lastprivate = false;
11188 if (loop_p && OMP_FOR_ORIG_DECLS (for_stmt))
11190 tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
11191 if (TREE_CODE (elt) == TREE_LIST && TREE_PURPOSE (elt))
11192 lastprivate = false;
11195 struct gimplify_omp_ctx *outer
11196 = gimplify_omp_ctxp->outer_context;
11197 if (outer && lastprivate)
11199 if (outer->region_type == ORT_WORKSHARE
11200 && outer->combined_loop)
11202 n = splay_tree_lookup (outer->variables,
11203 (splay_tree_key)decl);
11204 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
11206 lastprivate = false;
11207 outer = NULL;
11209 else if (outer->outer_context
11210 && (outer->outer_context->region_type
11211 == ORT_COMBINED_PARALLEL))
11212 outer = outer->outer_context;
11213 else if (omp_check_private (outer, decl, false))
11214 outer = NULL;
11216 else if (((outer->region_type & ORT_TASKLOOP)
11217 == ORT_TASKLOOP)
11218 && outer->combined_loop
11219 && !omp_check_private (gimplify_omp_ctxp,
11220 decl, false))
11222 else if (outer->region_type != ORT_COMBINED_PARALLEL)
11224 omp_notice_variable (outer, decl, true);
11225 outer = NULL;
11227 if (outer)
11229 n = splay_tree_lookup (outer->variables,
11230 (splay_tree_key)decl);
11231 if (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
11233 omp_add_variable (outer, decl,
11234 GOVD_LASTPRIVATE | GOVD_SEEN);
11235 if (outer->region_type == ORT_COMBINED_PARALLEL
11236 && outer->outer_context
11237 && (outer->outer_context->region_type
11238 == ORT_WORKSHARE)
11239 && outer->outer_context->combined_loop)
11241 outer = outer->outer_context;
11242 n = splay_tree_lookup (outer->variables,
11243 (splay_tree_key)decl);
11244 if (omp_check_private (outer, decl, false))
11245 outer = NULL;
11246 else if (n == NULL
11247 || ((n->value & GOVD_DATA_SHARE_CLASS)
11248 == 0))
11249 omp_add_variable (outer, decl,
11250 GOVD_LASTPRIVATE
11251 | GOVD_SEEN);
11252 else
11253 outer = NULL;
11255 if (outer && outer->outer_context
11256 && ((outer->outer_context->region_type
11257 & ORT_COMBINED_TEAMS) == ORT_COMBINED_TEAMS
11258 || (((outer->region_type & ORT_TASKLOOP)
11259 == ORT_TASKLOOP)
11260 && (outer->outer_context->region_type
11261 == ORT_COMBINED_PARALLEL))))
11263 outer = outer->outer_context;
11264 n = splay_tree_lookup (outer->variables,
11265 (splay_tree_key)decl);
11266 if (n == NULL
11267 || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
11268 omp_add_variable (outer, decl,
11269 GOVD_SHARED | GOVD_SEEN);
11270 else
11271 outer = NULL;
11273 if (outer && outer->outer_context)
11274 omp_notice_variable (outer->outer_context, decl,
11275 true);
11280 c = build_omp_clause (input_location,
11281 lastprivate ? OMP_CLAUSE_LASTPRIVATE
11282 : OMP_CLAUSE_PRIVATE);
11283 OMP_CLAUSE_DECL (c) = decl;
11284 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
11285 OMP_FOR_CLAUSES (for_stmt) = c;
11286 omp_add_variable (gimplify_omp_ctxp, decl,
11287 (lastprivate ? GOVD_LASTPRIVATE : GOVD_PRIVATE)
11288 | GOVD_EXPLICIT | GOVD_SEEN);
11289 c = NULL_TREE;
11292 else if (omp_is_private (gimplify_omp_ctxp, decl, 0))
11294 omp_notice_variable (gimplify_omp_ctxp, decl, true);
11295 splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
11296 (splay_tree_key) decl);
11297 if (n && (n->value & GOVD_LASTPRIVATE_CONDITIONAL))
11298 for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
11299 OMP_CLAUSE_LASTPRIVATE);
11300 c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
11301 OMP_CLAUSE_LASTPRIVATE))
11302 if (OMP_CLAUSE_DECL (c3) == decl)
11304 warning_at (OMP_CLAUSE_LOCATION (c3), 0,
11305 "conditional %<lastprivate%> on loop "
11306 "iterator %qD ignored", decl);
11307 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
11308 n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
11311 else
11312 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN);
11314 /* If DECL is not a gimple register, create a temporary variable to act
11315 as an iteration counter. This is valid, since DECL cannot be
11316 modified in the body of the loop. Similarly for any iteration vars
11317 in simd with collapse > 1 where the iterator vars must be
11318 lastprivate. */
11319 if (orig_for_stmt != for_stmt)
11320 var = decl;
11321 else if (!is_gimple_reg (decl)
11322 || (ort == ORT_SIMD
11323 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) > 1))
11325 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
11326 /* Make sure omp_add_variable is not called on it prematurely.
11327 We call it ourselves a few lines later. */
11328 gimplify_omp_ctxp = NULL;
11329 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
11330 gimplify_omp_ctxp = ctx;
11331 TREE_OPERAND (t, 0) = var;
11333 gimplify_seq_add_stmt (&for_body, gimple_build_assign (decl, var));
11335 if (ort == ORT_SIMD
11336 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
11338 c2 = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
11339 OMP_CLAUSE_LINEAR_NO_COPYIN (c2) = 1;
11340 OMP_CLAUSE_LINEAR_NO_COPYOUT (c2) = 1;
11341 OMP_CLAUSE_DECL (c2) = var;
11342 OMP_CLAUSE_CHAIN (c2) = OMP_FOR_CLAUSES (for_stmt);
11343 OMP_FOR_CLAUSES (for_stmt) = c2;
11344 omp_add_variable (gimplify_omp_ctxp, var,
11345 GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN);
11346 if (c == NULL_TREE)
11348 c = c2;
11349 c2 = NULL_TREE;
11352 else
11353 omp_add_variable (gimplify_omp_ctxp, var,
11354 GOVD_PRIVATE | GOVD_SEEN);
11356 else
11357 var = decl;
11359 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
11360 is_gimple_val, fb_rvalue, false);
11361 ret = MIN (ret, tret);
11362 if (ret == GS_ERROR)
11363 return ret;
11365 /* Handle OMP_FOR_COND. */
11366 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
11367 gcc_assert (COMPARISON_CLASS_P (t));
11368 gcc_assert (TREE_OPERAND (t, 0) == decl);
11370 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
11371 is_gimple_val, fb_rvalue, false);
11372 ret = MIN (ret, tret);
11374 /* Handle OMP_FOR_INCR. */
11375 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
11376 switch (TREE_CODE (t))
11378 case PREINCREMENT_EXPR:
11379 case POSTINCREMENT_EXPR:
11381 tree decl = TREE_OPERAND (t, 0);
11382 /* c_omp_for_incr_canonicalize_ptr() should have been
11383 called to massage things appropriately. */
11384 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
11386 if (orig_for_stmt != for_stmt)
11387 break;
11388 t = build_int_cst (TREE_TYPE (decl), 1);
11389 if (c)
11390 OMP_CLAUSE_LINEAR_STEP (c) = t;
11391 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
11392 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
11393 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
11394 break;
11397 case PREDECREMENT_EXPR:
11398 case POSTDECREMENT_EXPR:
11399 /* c_omp_for_incr_canonicalize_ptr() should have been
11400 called to massage things appropriately. */
11401 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
11402 if (orig_for_stmt != for_stmt)
11403 break;
11404 t = build_int_cst (TREE_TYPE (decl), -1);
11405 if (c)
11406 OMP_CLAUSE_LINEAR_STEP (c) = t;
11407 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
11408 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
11409 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
11410 break;
11412 case MODIFY_EXPR:
11413 gcc_assert (TREE_OPERAND (t, 0) == decl);
11414 TREE_OPERAND (t, 0) = var;
11416 t = TREE_OPERAND (t, 1);
11417 switch (TREE_CODE (t))
11419 case PLUS_EXPR:
11420 if (TREE_OPERAND (t, 1) == decl)
11422 TREE_OPERAND (t, 1) = TREE_OPERAND (t, 0);
11423 TREE_OPERAND (t, 0) = var;
11424 break;
11427 /* Fallthru. */
11428 case MINUS_EXPR:
11429 case POINTER_PLUS_EXPR:
11430 gcc_assert (TREE_OPERAND (t, 0) == decl);
11431 TREE_OPERAND (t, 0) = var;
11432 break;
11433 default:
11434 gcc_unreachable ();
11437 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
11438 is_gimple_val, fb_rvalue, false);
11439 ret = MIN (ret, tret);
11440 if (c)
11442 tree step = TREE_OPERAND (t, 1);
11443 tree stept = TREE_TYPE (decl);
11444 if (POINTER_TYPE_P (stept))
11445 stept = sizetype;
11446 step = fold_convert (stept, step);
11447 if (TREE_CODE (t) == MINUS_EXPR)
11448 step = fold_build1 (NEGATE_EXPR, stept, step);
11449 OMP_CLAUSE_LINEAR_STEP (c) = step;
11450 if (step != TREE_OPERAND (t, 1))
11452 tret = gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c),
11453 &for_pre_body, NULL,
11454 is_gimple_val, fb_rvalue, false);
11455 ret = MIN (ret, tret);
11458 break;
11460 default:
11461 gcc_unreachable ();
11464 if (c2)
11466 gcc_assert (c);
11467 OMP_CLAUSE_LINEAR_STEP (c2) = OMP_CLAUSE_LINEAR_STEP (c);
11470 if ((var != decl || collapse > 1 || tile) && orig_for_stmt == for_stmt)
11472 for (c = OMP_FOR_CLAUSES (for_stmt); c ; c = OMP_CLAUSE_CHAIN (c))
11473 if (((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
11474 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) == NULL)
11475 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
11476 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)
11477 && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c) == NULL))
11478 && OMP_CLAUSE_DECL (c) == decl)
11480 if (is_doacross && (collapse == 1 || i >= collapse))
11481 t = var;
11482 else
11484 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
11485 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
11486 gcc_assert (TREE_OPERAND (t, 0) == var);
11487 t = TREE_OPERAND (t, 1);
11488 gcc_assert (TREE_CODE (t) == PLUS_EXPR
11489 || TREE_CODE (t) == MINUS_EXPR
11490 || TREE_CODE (t) == POINTER_PLUS_EXPR);
11491 gcc_assert (TREE_OPERAND (t, 0) == var);
11492 t = build2 (TREE_CODE (t), TREE_TYPE (decl),
11493 is_doacross ? var : decl,
11494 TREE_OPERAND (t, 1));
11496 gimple_seq *seq;
11497 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
11498 seq = &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c);
11499 else
11500 seq = &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c);
11501 push_gimplify_context ();
11502 gimplify_assign (decl, t, seq);
11503 gimple *bind = NULL;
11504 if (gimplify_ctxp->temps)
11506 bind = gimple_build_bind (NULL_TREE, *seq, NULL_TREE);
11507 *seq = NULL;
11508 gimplify_seq_add_stmt (seq, bind);
11510 pop_gimplify_context (bind);
11515 BITMAP_FREE (has_decl_expr);
11517 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP
11518 || (loop_p && orig_for_stmt == for_stmt))
11520 push_gimplify_context ();
11521 if (TREE_CODE (OMP_FOR_BODY (orig_for_stmt)) != BIND_EXPR)
11523 OMP_FOR_BODY (orig_for_stmt)
11524 = build3 (BIND_EXPR, void_type_node, NULL,
11525 OMP_FOR_BODY (orig_for_stmt), NULL);
11526 TREE_SIDE_EFFECTS (OMP_FOR_BODY (orig_for_stmt)) = 1;
11530 gimple *g = gimplify_and_return_first (OMP_FOR_BODY (orig_for_stmt),
11531 &for_body);
11533 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP
11534 || (loop_p && orig_for_stmt == for_stmt))
11536 if (gimple_code (g) == GIMPLE_BIND)
11537 pop_gimplify_context (g);
11538 else
11539 pop_gimplify_context (NULL);
11542 if (orig_for_stmt != for_stmt)
11543 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
11545 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
11546 decl = TREE_OPERAND (t, 0);
11547 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
11548 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
11549 gimplify_omp_ctxp = ctx->outer_context;
11550 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
11551 gimplify_omp_ctxp = ctx;
11552 omp_add_variable (gimplify_omp_ctxp, var, GOVD_PRIVATE | GOVD_SEEN);
11553 TREE_OPERAND (t, 0) = var;
11554 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
11555 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
11556 TREE_OPERAND (TREE_OPERAND (t, 1), 0) = var;
11559 gimplify_adjust_omp_clauses (pre_p, for_body,
11560 &OMP_FOR_CLAUSES (orig_for_stmt),
11561 TREE_CODE (orig_for_stmt));
11563 int kind;
11564 switch (TREE_CODE (orig_for_stmt))
11566 case OMP_FOR: kind = GF_OMP_FOR_KIND_FOR; break;
11567 case OMP_SIMD: kind = GF_OMP_FOR_KIND_SIMD; break;
11568 case OMP_DISTRIBUTE: kind = GF_OMP_FOR_KIND_DISTRIBUTE; break;
11569 case OMP_TASKLOOP: kind = GF_OMP_FOR_KIND_TASKLOOP; break;
11570 case OACC_LOOP: kind = GF_OMP_FOR_KIND_OACC_LOOP; break;
11571 default:
11572 gcc_unreachable ();
11574 if (loop_p && kind == GF_OMP_FOR_KIND_SIMD)
11576 gimplify_seq_add_seq (pre_p, for_pre_body);
11577 for_pre_body = NULL;
11579 gfor = gimple_build_omp_for (for_body, kind, OMP_FOR_CLAUSES (orig_for_stmt),
11580 TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)),
11581 for_pre_body);
11582 if (orig_for_stmt != for_stmt)
11583 gimple_omp_for_set_combined_p (gfor, true);
11584 if (gimplify_omp_ctxp
11585 && (gimplify_omp_ctxp->combined_loop
11586 || (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
11587 && gimplify_omp_ctxp->outer_context
11588 && gimplify_omp_ctxp->outer_context->combined_loop)))
11590 gimple_omp_for_set_combined_into_p (gfor, true);
11591 if (gimplify_omp_ctxp->combined_loop)
11592 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_SIMD);
11593 else
11594 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_FOR);
11597 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
11599 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
11600 gimple_omp_for_set_index (gfor, i, TREE_OPERAND (t, 0));
11601 gimple_omp_for_set_initial (gfor, i, TREE_OPERAND (t, 1));
11602 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
11603 gimple_omp_for_set_cond (gfor, i, TREE_CODE (t));
11604 gimple_omp_for_set_final (gfor, i, TREE_OPERAND (t, 1));
11605 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
11606 gimple_omp_for_set_incr (gfor, i, TREE_OPERAND (t, 1));
11609 /* OMP_TASKLOOP is gimplified as two GIMPLE_OMP_FOR taskloop
11610 constructs with GIMPLE_OMP_TASK sandwiched in between them.
11611 The outer taskloop stands for computing the number of iterations,
11612 counts for collapsed loops and holding taskloop specific clauses.
11613 The task construct stands for the effect of data sharing on the
11614 explicit task it creates and the inner taskloop stands for expansion
11615 of the static loop inside of the explicit task construct. */
11616 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
11618 tree *gfor_clauses_ptr = gimple_omp_for_clauses_ptr (gfor);
11619 tree task_clauses = NULL_TREE;
11620 tree c = *gfor_clauses_ptr;
11621 tree *gtask_clauses_ptr = &task_clauses;
11622 tree outer_for_clauses = NULL_TREE;
11623 tree *gforo_clauses_ptr = &outer_for_clauses;
11624 for (; c; c = OMP_CLAUSE_CHAIN (c))
11625 switch (OMP_CLAUSE_CODE (c))
11627 /* These clauses are allowed on task, move them there. */
11628 case OMP_CLAUSE_SHARED:
11629 case OMP_CLAUSE_FIRSTPRIVATE:
11630 case OMP_CLAUSE_DEFAULT:
11631 case OMP_CLAUSE_IF:
11632 case OMP_CLAUSE_UNTIED:
11633 case OMP_CLAUSE_FINAL:
11634 case OMP_CLAUSE_MERGEABLE:
11635 case OMP_CLAUSE_PRIORITY:
11636 case OMP_CLAUSE_REDUCTION:
11637 case OMP_CLAUSE_IN_REDUCTION:
11638 *gtask_clauses_ptr = c;
11639 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
11640 break;
11641 case OMP_CLAUSE_PRIVATE:
11642 if (OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c))
11644 /* We want private on outer for and firstprivate
11645 on task. */
11646 *gtask_clauses_ptr
11647 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
11648 OMP_CLAUSE_FIRSTPRIVATE);
11649 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
11650 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL);
11651 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
11652 *gforo_clauses_ptr = c;
11653 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
11655 else
11657 *gtask_clauses_ptr = c;
11658 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
11660 break;
11661 /* These clauses go into outer taskloop clauses. */
11662 case OMP_CLAUSE_GRAINSIZE:
11663 case OMP_CLAUSE_NUM_TASKS:
11664 case OMP_CLAUSE_NOGROUP:
11665 *gforo_clauses_ptr = c;
11666 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
11667 break;
11668 /* Taskloop clause we duplicate on both taskloops. */
11669 case OMP_CLAUSE_COLLAPSE:
11670 *gfor_clauses_ptr = c;
11671 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
11672 *gforo_clauses_ptr = copy_node (c);
11673 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
11674 break;
11675 /* For lastprivate, keep the clause on inner taskloop, and add
11676 a shared clause on task. If the same decl is also firstprivate,
11677 add also firstprivate clause on the inner taskloop. */
11678 case OMP_CLAUSE_LASTPRIVATE:
11679 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
11681 /* For taskloop C++ lastprivate IVs, we want:
11682 1) private on outer taskloop
11683 2) firstprivate and shared on task
11684 3) lastprivate on inner taskloop */
11685 *gtask_clauses_ptr
11686 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
11687 OMP_CLAUSE_FIRSTPRIVATE);
11688 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
11689 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL);
11690 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
11691 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c) = 1;
11692 *gforo_clauses_ptr = build_omp_clause (OMP_CLAUSE_LOCATION (c),
11693 OMP_CLAUSE_PRIVATE);
11694 OMP_CLAUSE_DECL (*gforo_clauses_ptr) = OMP_CLAUSE_DECL (c);
11695 OMP_CLAUSE_PRIVATE_TASKLOOP_IV (*gforo_clauses_ptr) = 1;
11696 TREE_TYPE (*gforo_clauses_ptr) = TREE_TYPE (c);
11697 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
11699 *gfor_clauses_ptr = c;
11700 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
11701 *gtask_clauses_ptr
11702 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_SHARED);
11703 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
11704 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
11705 OMP_CLAUSE_SHARED_FIRSTPRIVATE (*gtask_clauses_ptr) = 1;
11706 gtask_clauses_ptr
11707 = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
11708 break;
11709 default:
11710 gcc_unreachable ();
11712 *gfor_clauses_ptr = NULL_TREE;
11713 *gtask_clauses_ptr = NULL_TREE;
11714 *gforo_clauses_ptr = NULL_TREE;
11715 g = gimple_build_bind (NULL_TREE, gfor, NULL_TREE);
11716 g = gimple_build_omp_task (g, task_clauses, NULL_TREE, NULL_TREE,
11717 NULL_TREE, NULL_TREE, NULL_TREE);
11718 gimple_omp_task_set_taskloop_p (g, true);
11719 g = gimple_build_bind (NULL_TREE, g, NULL_TREE);
11720 gomp_for *gforo
11721 = gimple_build_omp_for (g, GF_OMP_FOR_KIND_TASKLOOP, outer_for_clauses,
11722 gimple_omp_for_collapse (gfor),
11723 gimple_omp_for_pre_body (gfor));
11724 gimple_omp_for_set_pre_body (gfor, NULL);
11725 gimple_omp_for_set_combined_p (gforo, true);
11726 gimple_omp_for_set_combined_into_p (gfor, true);
11727 for (i = 0; i < (int) gimple_omp_for_collapse (gfor); i++)
11729 tree type = TREE_TYPE (gimple_omp_for_index (gfor, i));
11730 tree v = create_tmp_var (type);
11731 gimple_omp_for_set_index (gforo, i, v);
11732 t = unshare_expr (gimple_omp_for_initial (gfor, i));
11733 gimple_omp_for_set_initial (gforo, i, t);
11734 gimple_omp_for_set_cond (gforo, i,
11735 gimple_omp_for_cond (gfor, i));
11736 t = unshare_expr (gimple_omp_for_final (gfor, i));
11737 gimple_omp_for_set_final (gforo, i, t);
11738 t = unshare_expr (gimple_omp_for_incr (gfor, i));
11739 gcc_assert (TREE_OPERAND (t, 0) == gimple_omp_for_index (gfor, i));
11740 TREE_OPERAND (t, 0) = v;
11741 gimple_omp_for_set_incr (gforo, i, t);
11742 t = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
11743 OMP_CLAUSE_DECL (t) = v;
11744 OMP_CLAUSE_CHAIN (t) = gimple_omp_for_clauses (gforo);
11745 gimple_omp_for_set_clauses (gforo, t);
11747 gimplify_seq_add_stmt (pre_p, gforo);
11749 else
11750 gimplify_seq_add_stmt (pre_p, gfor);
11752 if (TREE_CODE (orig_for_stmt) == OMP_FOR)
11754 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
11755 unsigned lastprivate_conditional = 0;
11756 while (ctx
11757 && (ctx->region_type == ORT_TARGET_DATA
11758 || ctx->region_type == ORT_TASKGROUP))
11759 ctx = ctx->outer_context;
11760 if (ctx && (ctx->region_type & ORT_PARALLEL) != 0)
11761 for (tree c = gimple_omp_for_clauses (gfor);
11762 c; c = OMP_CLAUSE_CHAIN (c))
11763 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
11764 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
11765 ++lastprivate_conditional;
11766 if (lastprivate_conditional)
11768 struct omp_for_data fd;
11769 omp_extract_for_data (gfor, &fd, NULL);
11770 tree type = build_array_type_nelts (unsigned_type_for (fd.iter_type),
11771 lastprivate_conditional);
11772 tree var = create_tmp_var_raw (type);
11773 tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__CONDTEMP_);
11774 OMP_CLAUSE_DECL (c) = var;
11775 OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor);
11776 gimple_omp_for_set_clauses (gfor, c);
11777 omp_add_variable (ctx, var, GOVD_CONDTEMP | GOVD_SEEN);
11780 else if (TREE_CODE (orig_for_stmt) == OMP_SIMD)
11782 unsigned lastprivate_conditional = 0;
11783 for (tree c = gimple_omp_for_clauses (gfor); c; c = OMP_CLAUSE_CHAIN (c))
11784 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
11785 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
11786 ++lastprivate_conditional;
11787 if (lastprivate_conditional)
11789 struct omp_for_data fd;
11790 omp_extract_for_data (gfor, &fd, NULL);
11791 tree type = unsigned_type_for (fd.iter_type);
11792 while (lastprivate_conditional--)
11794 tree c = build_omp_clause (UNKNOWN_LOCATION,
11795 OMP_CLAUSE__CONDTEMP_);
11796 OMP_CLAUSE_DECL (c) = create_tmp_var (type);
11797 OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor);
11798 gimple_omp_for_set_clauses (gfor, c);
11803 if (ret != GS_ALL_DONE)
11804 return GS_ERROR;
11805 *expr_p = NULL_TREE;
11806 return GS_ALL_DONE;
11809 /* Helper for gimplify_omp_loop, called through walk_tree. */
11811 static tree
11812 replace_reduction_placeholders (tree *tp, int *walk_subtrees, void *data)
11814 if (DECL_P (*tp))
11816 tree *d = (tree *) data;
11817 if (*tp == OMP_CLAUSE_REDUCTION_PLACEHOLDER (d[0]))
11819 *tp = OMP_CLAUSE_REDUCTION_PLACEHOLDER (d[1]);
11820 *walk_subtrees = 0;
11822 else if (*tp == OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (d[0]))
11824 *tp = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (d[1]);
11825 *walk_subtrees = 0;
11828 return NULL_TREE;
11831 /* Gimplify the gross structure of an OMP_LOOP statement. */
11833 static enum gimplify_status
11834 gimplify_omp_loop (tree *expr_p, gimple_seq *pre_p)
11836 tree for_stmt = *expr_p;
11837 tree clauses = OMP_FOR_CLAUSES (for_stmt);
11838 struct gimplify_omp_ctx *octx = gimplify_omp_ctxp;
11839 enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
11840 int i;
11842 /* If order is not present, the behavior is as if order(concurrent)
11843 appeared. */
11844 tree order = omp_find_clause (clauses, OMP_CLAUSE_ORDER);
11845 if (order == NULL_TREE)
11847 order = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_ORDER);
11848 OMP_CLAUSE_CHAIN (order) = clauses;
11849 OMP_FOR_CLAUSES (for_stmt) = clauses = order;
11852 tree bind = omp_find_clause (clauses, OMP_CLAUSE_BIND);
11853 if (bind == NULL_TREE)
11855 if (!flag_openmp) /* flag_openmp_simd */
11857 else if (octx && (octx->region_type & ORT_TEAMS) != 0)
11858 kind = OMP_CLAUSE_BIND_TEAMS;
11859 else if (octx && (octx->region_type & ORT_PARALLEL) != 0)
11860 kind = OMP_CLAUSE_BIND_PARALLEL;
11861 else
11863 for (; octx; octx = octx->outer_context)
11865 if ((octx->region_type & ORT_ACC) != 0
11866 || octx->region_type == ORT_NONE
11867 || octx->region_type == ORT_IMPLICIT_TARGET)
11868 continue;
11869 break;
11871 if (octx == NULL && !in_omp_construct)
11872 error_at (EXPR_LOCATION (for_stmt),
11873 "%<bind%> clause not specified on a %<loop%> "
11874 "construct not nested inside another OpenMP construct");
11876 bind = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_BIND);
11877 OMP_CLAUSE_CHAIN (bind) = clauses;
11878 OMP_CLAUSE_BIND_KIND (bind) = kind;
11879 OMP_FOR_CLAUSES (for_stmt) = bind;
11881 else
11882 switch (OMP_CLAUSE_BIND_KIND (bind))
11884 case OMP_CLAUSE_BIND_THREAD:
11885 break;
11886 case OMP_CLAUSE_BIND_PARALLEL:
11887 if (!flag_openmp) /* flag_openmp_simd */
11889 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
11890 break;
11892 for (; octx; octx = octx->outer_context)
11893 if (octx->region_type == ORT_SIMD
11894 && omp_find_clause (octx->clauses, OMP_CLAUSE_BIND) == NULL_TREE)
11896 error_at (EXPR_LOCATION (for_stmt),
11897 "%<bind(parallel)%> on a %<loop%> construct nested "
11898 "inside %<simd%> construct");
11899 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
11900 break;
11902 kind = OMP_CLAUSE_BIND_PARALLEL;
11903 break;
11904 case OMP_CLAUSE_BIND_TEAMS:
11905 if (!flag_openmp) /* flag_openmp_simd */
11907 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
11908 break;
11910 if ((octx
11911 && octx->region_type != ORT_IMPLICIT_TARGET
11912 && octx->region_type != ORT_NONE
11913 && (octx->region_type & ORT_TEAMS) == 0)
11914 || in_omp_construct)
11916 error_at (EXPR_LOCATION (for_stmt),
11917 "%<bind(teams)%> on a %<loop%> region not strictly "
11918 "nested inside of a %<teams%> region");
11919 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
11920 break;
11922 kind = OMP_CLAUSE_BIND_TEAMS;
11923 break;
11924 default:
11925 gcc_unreachable ();
11928 for (tree *pc = &OMP_FOR_CLAUSES (for_stmt); *pc; )
11929 switch (OMP_CLAUSE_CODE (*pc))
11931 case OMP_CLAUSE_REDUCTION:
11932 if (OMP_CLAUSE_REDUCTION_INSCAN (*pc))
11934 error_at (OMP_CLAUSE_LOCATION (*pc),
11935 "%<inscan%> %<reduction%> clause on "
11936 "%qs construct", "loop");
11937 OMP_CLAUSE_REDUCTION_INSCAN (*pc) = 0;
11939 if (OMP_CLAUSE_REDUCTION_TASK (*pc))
11941 error_at (OMP_CLAUSE_LOCATION (*pc),
11942 "invalid %<task%> reduction modifier on construct "
11943 "other than %<parallel%>, %<for%> or %<sections%>");
11944 OMP_CLAUSE_REDUCTION_TASK (*pc) = 0;
11946 pc = &OMP_CLAUSE_CHAIN (*pc);
11947 break;
11948 case OMP_CLAUSE_LASTPRIVATE:
11949 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
11951 tree t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
11952 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
11953 if (OMP_CLAUSE_DECL (*pc) == TREE_OPERAND (t, 0))
11954 break;
11955 if (OMP_FOR_ORIG_DECLS (for_stmt)
11956 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt),
11957 i)) == TREE_LIST
11958 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt),
11959 i)))
11961 tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
11962 if (OMP_CLAUSE_DECL (*pc) == TREE_PURPOSE (orig))
11963 break;
11966 if (i == TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)))
11968 error_at (OMP_CLAUSE_LOCATION (*pc),
11969 "%<lastprivate%> clause on a %<loop%> construct refers "
11970 "to a variable %qD which is not the loop iterator",
11971 OMP_CLAUSE_DECL (*pc));
11972 *pc = OMP_CLAUSE_CHAIN (*pc);
11973 break;
11975 pc = &OMP_CLAUSE_CHAIN (*pc);
11976 break;
11977 default:
11978 pc = &OMP_CLAUSE_CHAIN (*pc);
11979 break;
11982 TREE_SET_CODE (for_stmt, OMP_SIMD);
11984 int last;
11985 switch (kind)
11987 case OMP_CLAUSE_BIND_THREAD: last = 0; break;
11988 case OMP_CLAUSE_BIND_PARALLEL: last = 1; break;
11989 case OMP_CLAUSE_BIND_TEAMS: last = 2; break;
11991 for (int pass = 1; pass <= last; pass++)
11993 if (pass == 2)
11995 tree bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
11996 append_to_statement_list (*expr_p, &BIND_EXPR_BODY (bind));
11997 *expr_p = make_node (OMP_PARALLEL);
11998 TREE_TYPE (*expr_p) = void_type_node;
11999 OMP_PARALLEL_BODY (*expr_p) = bind;
12000 OMP_PARALLEL_COMBINED (*expr_p) = 1;
12001 SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (for_stmt));
12002 tree *pc = &OMP_PARALLEL_CLAUSES (*expr_p);
12003 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
12004 if (OMP_FOR_ORIG_DECLS (for_stmt)
12005 && (TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i))
12006 == TREE_LIST))
12008 tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
12009 if (TREE_PURPOSE (elt) && TREE_VALUE (elt))
12011 *pc = build_omp_clause (UNKNOWN_LOCATION,
12012 OMP_CLAUSE_FIRSTPRIVATE);
12013 OMP_CLAUSE_DECL (*pc) = TREE_VALUE (elt);
12014 pc = &OMP_CLAUSE_CHAIN (*pc);
12018 tree t = make_node (pass == 2 ? OMP_DISTRIBUTE : OMP_FOR);
12019 tree *pc = &OMP_FOR_CLAUSES (t);
12020 TREE_TYPE (t) = void_type_node;
12021 OMP_FOR_BODY (t) = *expr_p;
12022 SET_EXPR_LOCATION (t, EXPR_LOCATION (for_stmt));
12023 for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
12024 switch (OMP_CLAUSE_CODE (c))
12026 case OMP_CLAUSE_BIND:
12027 case OMP_CLAUSE_ORDER:
12028 case OMP_CLAUSE_COLLAPSE:
12029 *pc = copy_node (c);
12030 pc = &OMP_CLAUSE_CHAIN (*pc);
12031 break;
12032 case OMP_CLAUSE_PRIVATE:
12033 case OMP_CLAUSE_FIRSTPRIVATE:
12034 /* Only needed on innermost. */
12035 break;
12036 case OMP_CLAUSE_LASTPRIVATE:
12037 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c) && pass != last)
12039 *pc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
12040 OMP_CLAUSE_FIRSTPRIVATE);
12041 OMP_CLAUSE_DECL (*pc) = OMP_CLAUSE_DECL (c);
12042 lang_hooks.decls.omp_finish_clause (*pc, NULL);
12043 pc = &OMP_CLAUSE_CHAIN (*pc);
12045 *pc = copy_node (c);
12046 OMP_CLAUSE_LASTPRIVATE_STMT (*pc) = NULL_TREE;
12047 TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
12048 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
12050 if (pass != last)
12051 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (*pc) = 1;
12052 else
12053 lang_hooks.decls.omp_finish_clause (*pc, NULL);
12054 OMP_CLAUSE_LASTPRIVATE_LOOP_IV (*pc) = 0;
12056 pc = &OMP_CLAUSE_CHAIN (*pc);
12057 break;
12058 case OMP_CLAUSE_REDUCTION:
12059 *pc = copy_node (c);
12060 OMP_CLAUSE_DECL (*pc) = unshare_expr (OMP_CLAUSE_DECL (c));
12061 TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
12062 OMP_CLAUSE_REDUCTION_INIT (*pc)
12063 = unshare_expr (OMP_CLAUSE_REDUCTION_INIT (c));
12064 OMP_CLAUSE_REDUCTION_MERGE (*pc)
12065 = unshare_expr (OMP_CLAUSE_REDUCTION_MERGE (c));
12066 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc))
12068 OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc)
12069 = copy_node (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c));
12070 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc))
12071 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc)
12072 = copy_node (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c));
12073 tree nc = *pc;
12074 tree data[2] = { c, nc };
12075 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_INIT (nc),
12076 replace_reduction_placeholders,
12077 data);
12078 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_MERGE (nc),
12079 replace_reduction_placeholders,
12080 data);
12082 pc = &OMP_CLAUSE_CHAIN (*pc);
12083 break;
12084 default:
12085 gcc_unreachable ();
12087 *pc = NULL_TREE;
12088 *expr_p = t;
12090 return gimplify_omp_for (expr_p, pre_p);
12094 /* Helper function of optimize_target_teams, find OMP_TEAMS inside
12095 of OMP_TARGET's body. */
12097 static tree
12098 find_omp_teams (tree *tp, int *walk_subtrees, void *)
12100 *walk_subtrees = 0;
12101 switch (TREE_CODE (*tp))
12103 case OMP_TEAMS:
12104 return *tp;
12105 case BIND_EXPR:
12106 case STATEMENT_LIST:
12107 *walk_subtrees = 1;
12108 break;
12109 default:
12110 break;
12112 return NULL_TREE;
12115 /* Helper function of optimize_target_teams, determine if the expression
12116 can be computed safely before the target construct on the host. */
12118 static tree
12119 computable_teams_clause (tree *tp, int *walk_subtrees, void *)
12121 splay_tree_node n;
12123 if (TYPE_P (*tp))
12125 *walk_subtrees = 0;
12126 return NULL_TREE;
12128 switch (TREE_CODE (*tp))
12130 case VAR_DECL:
12131 case PARM_DECL:
12132 case RESULT_DECL:
12133 *walk_subtrees = 0;
12134 if (error_operand_p (*tp)
12135 || !INTEGRAL_TYPE_P (TREE_TYPE (*tp))
12136 || DECL_HAS_VALUE_EXPR_P (*tp)
12137 || DECL_THREAD_LOCAL_P (*tp)
12138 || TREE_SIDE_EFFECTS (*tp)
12139 || TREE_THIS_VOLATILE (*tp))
12140 return *tp;
12141 if (is_global_var (*tp)
12142 && (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (*tp))
12143 || lookup_attribute ("omp declare target link",
12144 DECL_ATTRIBUTES (*tp))))
12145 return *tp;
12146 if (VAR_P (*tp)
12147 && !DECL_SEEN_IN_BIND_EXPR_P (*tp)
12148 && !is_global_var (*tp)
12149 && decl_function_context (*tp) == current_function_decl)
12150 return *tp;
12151 n = splay_tree_lookup (gimplify_omp_ctxp->variables,
12152 (splay_tree_key) *tp);
12153 if (n == NULL)
12155 if (gimplify_omp_ctxp->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE)
12156 return NULL_TREE;
12157 return *tp;
12159 else if (n->value & GOVD_LOCAL)
12160 return *tp;
12161 else if (n->value & GOVD_FIRSTPRIVATE)
12162 return NULL_TREE;
12163 else if ((n->value & (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
12164 == (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
12165 return NULL_TREE;
12166 return *tp;
12167 case INTEGER_CST:
12168 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
12169 return *tp;
12170 return NULL_TREE;
12171 case TARGET_EXPR:
12172 if (TARGET_EXPR_INITIAL (*tp)
12173 || TREE_CODE (TARGET_EXPR_SLOT (*tp)) != VAR_DECL)
12174 return *tp;
12175 return computable_teams_clause (&TARGET_EXPR_SLOT (*tp),
12176 walk_subtrees, NULL);
12177 /* Allow some reasonable subset of integral arithmetics. */
12178 case PLUS_EXPR:
12179 case MINUS_EXPR:
12180 case MULT_EXPR:
12181 case TRUNC_DIV_EXPR:
12182 case CEIL_DIV_EXPR:
12183 case FLOOR_DIV_EXPR:
12184 case ROUND_DIV_EXPR:
12185 case TRUNC_MOD_EXPR:
12186 case CEIL_MOD_EXPR:
12187 case FLOOR_MOD_EXPR:
12188 case ROUND_MOD_EXPR:
12189 case RDIV_EXPR:
12190 case EXACT_DIV_EXPR:
12191 case MIN_EXPR:
12192 case MAX_EXPR:
12193 case LSHIFT_EXPR:
12194 case RSHIFT_EXPR:
12195 case BIT_IOR_EXPR:
12196 case BIT_XOR_EXPR:
12197 case BIT_AND_EXPR:
12198 case NEGATE_EXPR:
12199 case ABS_EXPR:
12200 case BIT_NOT_EXPR:
12201 case NON_LVALUE_EXPR:
12202 CASE_CONVERT:
12203 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
12204 return *tp;
12205 return NULL_TREE;
12206 /* And disallow anything else, except for comparisons. */
12207 default:
12208 if (COMPARISON_CLASS_P (*tp))
12209 return NULL_TREE;
12210 return *tp;
12214 /* Try to determine if the num_teams and/or thread_limit expressions
12215 can have their values determined already before entering the
12216 target construct.
12217 INTEGER_CSTs trivially are,
12218 integral decls that are firstprivate (explicitly or implicitly)
12219 or explicitly map(always, to:) or map(always, tofrom:) on the target
12220 region too, and expressions involving simple arithmetics on those
12221 too, function calls are not ok, dereferencing something neither etc.
12222 Add NUM_TEAMS and THREAD_LIMIT clauses to the OMP_CLAUSES of
12223 EXPR based on what we find:
12224 0 stands for clause not specified at all, use implementation default
12225 -1 stands for value that can't be determined easily before entering
12226 the target construct.
12227 If teams construct is not present at all, use 1 for num_teams
12228 and 0 for thread_limit (only one team is involved, and the thread
12229 limit is implementation defined. */
12231 static void
12232 optimize_target_teams (tree target, gimple_seq *pre_p)
12234 tree body = OMP_BODY (target);
12235 tree teams = walk_tree (&body, find_omp_teams, NULL, NULL);
12236 tree num_teams = integer_zero_node;
12237 tree thread_limit = integer_zero_node;
12238 location_t num_teams_loc = EXPR_LOCATION (target);
12239 location_t thread_limit_loc = EXPR_LOCATION (target);
12240 tree c, *p, expr;
12241 struct gimplify_omp_ctx *target_ctx = gimplify_omp_ctxp;
12243 if (teams == NULL_TREE)
12244 num_teams = integer_one_node;
12245 else
12246 for (c = OMP_TEAMS_CLAUSES (teams); c; c = OMP_CLAUSE_CHAIN (c))
12248 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS)
12250 p = &num_teams;
12251 num_teams_loc = OMP_CLAUSE_LOCATION (c);
12253 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
12255 p = &thread_limit;
12256 thread_limit_loc = OMP_CLAUSE_LOCATION (c);
12258 else
12259 continue;
12260 expr = OMP_CLAUSE_OPERAND (c, 0);
12261 if (TREE_CODE (expr) == INTEGER_CST)
12263 *p = expr;
12264 continue;
12266 if (walk_tree (&expr, computable_teams_clause, NULL, NULL))
12268 *p = integer_minus_one_node;
12269 continue;
12271 *p = expr;
12272 gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
12273 if (gimplify_expr (p, pre_p, NULL, is_gimple_val, fb_rvalue, false)
12274 == GS_ERROR)
12276 gimplify_omp_ctxp = target_ctx;
12277 *p = integer_minus_one_node;
12278 continue;
12280 gimplify_omp_ctxp = target_ctx;
12281 if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR)
12282 OMP_CLAUSE_OPERAND (c, 0) = *p;
12284 c = build_omp_clause (thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
12285 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = thread_limit;
12286 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
12287 OMP_TARGET_CLAUSES (target) = c;
12288 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
12289 OMP_CLAUSE_NUM_TEAMS_EXPR (c) = num_teams;
12290 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
12291 OMP_TARGET_CLAUSES (target) = c;
12294 /* Gimplify the gross structure of several OMP constructs. */
12296 static void
12297 gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
12299 tree expr = *expr_p;
12300 gimple *stmt;
12301 gimple_seq body = NULL;
12302 enum omp_region_type ort;
12304 switch (TREE_CODE (expr))
12306 case OMP_SECTIONS:
12307 case OMP_SINGLE:
12308 ort = ORT_WORKSHARE;
12309 break;
12310 case OMP_TARGET:
12311 ort = OMP_TARGET_COMBINED (expr) ? ORT_COMBINED_TARGET : ORT_TARGET;
12312 break;
12313 case OACC_KERNELS:
12314 ort = ORT_ACC_KERNELS;
12315 break;
12316 case OACC_PARALLEL:
12317 ort = ORT_ACC_PARALLEL;
12318 break;
12319 case OACC_DATA:
12320 ort = ORT_ACC_DATA;
12321 break;
12322 case OMP_TARGET_DATA:
12323 ort = ORT_TARGET_DATA;
12324 break;
12325 case OMP_TEAMS:
12326 ort = OMP_TEAMS_COMBINED (expr) ? ORT_COMBINED_TEAMS : ORT_TEAMS;
12327 if (gimplify_omp_ctxp == NULL
12328 || gimplify_omp_ctxp->region_type == ORT_IMPLICIT_TARGET)
12329 ort = (enum omp_region_type) (ort | ORT_HOST_TEAMS);
12330 break;
12331 case OACC_HOST_DATA:
12332 ort = ORT_ACC_HOST_DATA;
12333 break;
12334 default:
12335 gcc_unreachable ();
12338 bool save_in_omp_construct = in_omp_construct;
12339 if ((ort & ORT_ACC) == 0)
12340 in_omp_construct = false;
12341 gimplify_scan_omp_clauses (&OMP_CLAUSES (expr), pre_p, ort,
12342 TREE_CODE (expr));
12343 if (TREE_CODE (expr) == OMP_TARGET)
12344 optimize_target_teams (expr, pre_p);
12345 if ((ort & (ORT_TARGET | ORT_TARGET_DATA)) != 0
12346 || (ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
12348 push_gimplify_context ();
12349 gimple *g = gimplify_and_return_first (OMP_BODY (expr), &body);
12350 if (gimple_code (g) == GIMPLE_BIND)
12351 pop_gimplify_context (g);
12352 else
12353 pop_gimplify_context (NULL);
12354 if ((ort & ORT_TARGET_DATA) != 0)
12356 enum built_in_function end_ix;
12357 switch (TREE_CODE (expr))
12359 case OACC_DATA:
12360 case OACC_HOST_DATA:
12361 end_ix = BUILT_IN_GOACC_DATA_END;
12362 break;
12363 case OMP_TARGET_DATA:
12364 end_ix = BUILT_IN_GOMP_TARGET_END_DATA;
12365 break;
12366 default:
12367 gcc_unreachable ();
12369 tree fn = builtin_decl_explicit (end_ix);
12370 g = gimple_build_call (fn, 0);
12371 gimple_seq cleanup = NULL;
12372 gimple_seq_add_stmt (&cleanup, g);
12373 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
12374 body = NULL;
12375 gimple_seq_add_stmt (&body, g);
12378 else
12379 gimplify_and_add (OMP_BODY (expr), &body);
12380 gimplify_adjust_omp_clauses (pre_p, body, &OMP_CLAUSES (expr),
12381 TREE_CODE (expr));
12382 in_omp_construct = save_in_omp_construct;
12384 switch (TREE_CODE (expr))
12386 case OACC_DATA:
12387 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_DATA,
12388 OMP_CLAUSES (expr));
12389 break;
12390 case OACC_KERNELS:
12391 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_KERNELS,
12392 OMP_CLAUSES (expr));
12393 break;
12394 case OACC_HOST_DATA:
12395 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_HOST_DATA,
12396 OMP_CLAUSES (expr));
12397 break;
12398 case OACC_PARALLEL:
12399 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_PARALLEL,
12400 OMP_CLAUSES (expr));
12401 break;
12402 case OMP_SECTIONS:
12403 stmt = gimple_build_omp_sections (body, OMP_CLAUSES (expr));
12404 break;
12405 case OMP_SINGLE:
12406 stmt = gimple_build_omp_single (body, OMP_CLAUSES (expr));
12407 break;
12408 case OMP_TARGET:
12409 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_REGION,
12410 OMP_CLAUSES (expr));
12411 break;
12412 case OMP_TARGET_DATA:
12413 /* Put use_device_{ptr,addr} clauses last, as map clauses are supposed
12414 to be evaluated before the use_device_{ptr,addr} clauses if they
12415 refer to the same variables. */
12417 tree use_device_clauses;
12418 tree *pc, *uc = &use_device_clauses;
12419 for (pc = &OMP_CLAUSES (expr); *pc; )
12420 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
12421 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
12423 *uc = *pc;
12424 *pc = OMP_CLAUSE_CHAIN (*pc);
12425 uc = &OMP_CLAUSE_CHAIN (*uc);
12427 else
12428 pc = &OMP_CLAUSE_CHAIN (*pc);
12429 *uc = NULL_TREE;
12430 *pc = use_device_clauses;
12431 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_DATA,
12432 OMP_CLAUSES (expr));
12434 break;
12435 case OMP_TEAMS:
12436 stmt = gimple_build_omp_teams (body, OMP_CLAUSES (expr));
12437 if ((ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
12438 gimple_omp_teams_set_host (as_a <gomp_teams *> (stmt), true);
12439 break;
12440 default:
12441 gcc_unreachable ();
12444 gimplify_seq_add_stmt (pre_p, stmt);
12445 *expr_p = NULL_TREE;
12448 /* Gimplify the gross structure of OpenACC enter/exit data, update, and OpenMP
12449 target update constructs. */
12451 static void
12452 gimplify_omp_target_update (tree *expr_p, gimple_seq *pre_p)
12454 tree expr = *expr_p;
12455 int kind;
12456 gomp_target *stmt;
12457 enum omp_region_type ort = ORT_WORKSHARE;
12459 switch (TREE_CODE (expr))
12461 case OACC_ENTER_DATA:
12462 case OACC_EXIT_DATA:
12463 kind = GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA;
12464 ort = ORT_ACC;
12465 break;
12466 case OACC_UPDATE:
12467 kind = GF_OMP_TARGET_KIND_OACC_UPDATE;
12468 ort = ORT_ACC;
12469 break;
12470 case OMP_TARGET_UPDATE:
12471 kind = GF_OMP_TARGET_KIND_UPDATE;
12472 break;
12473 case OMP_TARGET_ENTER_DATA:
12474 kind = GF_OMP_TARGET_KIND_ENTER_DATA;
12475 break;
12476 case OMP_TARGET_EXIT_DATA:
12477 kind = GF_OMP_TARGET_KIND_EXIT_DATA;
12478 break;
12479 default:
12480 gcc_unreachable ();
12482 gimplify_scan_omp_clauses (&OMP_STANDALONE_CLAUSES (expr), pre_p,
12483 ort, TREE_CODE (expr));
12484 gimplify_adjust_omp_clauses (pre_p, NULL, &OMP_STANDALONE_CLAUSES (expr),
12485 TREE_CODE (expr));
12486 if (TREE_CODE (expr) == OACC_UPDATE
12487 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
12488 OMP_CLAUSE_IF_PRESENT))
12490 /* The runtime uses GOMP_MAP_{TO,FROM} to denote the if_present
12491 clause. */
12492 for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
12493 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
12494 switch (OMP_CLAUSE_MAP_KIND (c))
12496 case GOMP_MAP_FORCE_TO:
12497 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TO);
12498 break;
12499 case GOMP_MAP_FORCE_FROM:
12500 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FROM);
12501 break;
12502 default:
12503 break;
12506 else if (TREE_CODE (expr) == OACC_EXIT_DATA
12507 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
12508 OMP_CLAUSE_FINALIZE))
12510 /* Use GOMP_MAP_DELETE/GOMP_MAP_FORCE_FROM to denote that "finalize"
12511 semantics apply to all mappings of this OpenACC directive. */
12512 bool finalize_marked = false;
12513 for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
12514 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
12515 switch (OMP_CLAUSE_MAP_KIND (c))
12517 case GOMP_MAP_FROM:
12518 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_FROM);
12519 finalize_marked = true;
12520 break;
12521 case GOMP_MAP_RELEASE:
12522 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_DELETE);
12523 finalize_marked = true;
12524 break;
12525 default:
12526 /* Check consistency: libgomp relies on the very first data
12527 mapping clause being marked, so make sure we did that before
12528 any other mapping clauses. */
12529 gcc_assert (finalize_marked);
12530 break;
12533 stmt = gimple_build_omp_target (NULL, kind, OMP_STANDALONE_CLAUSES (expr));
12535 gimplify_seq_add_stmt (pre_p, stmt);
12536 *expr_p = NULL_TREE;
12539 /* A subroutine of gimplify_omp_atomic. The front end is supposed to have
12540 stabilized the lhs of the atomic operation as *ADDR. Return true if
12541 EXPR is this stabilized form. */
12543 static bool
12544 goa_lhs_expr_p (tree expr, tree addr)
12546 /* Also include casts to other type variants. The C front end is fond
12547 of adding these for e.g. volatile variables. This is like
12548 STRIP_TYPE_NOPS but includes the main variant lookup. */
12549 STRIP_USELESS_TYPE_CONVERSION (expr);
12551 if (TREE_CODE (expr) == INDIRECT_REF)
12553 expr = TREE_OPERAND (expr, 0);
12554 while (expr != addr
12555 && (CONVERT_EXPR_P (expr)
12556 || TREE_CODE (expr) == NON_LVALUE_EXPR)
12557 && TREE_CODE (expr) == TREE_CODE (addr)
12558 && types_compatible_p (TREE_TYPE (expr), TREE_TYPE (addr)))
12560 expr = TREE_OPERAND (expr, 0);
12561 addr = TREE_OPERAND (addr, 0);
12563 if (expr == addr)
12564 return true;
12565 return (TREE_CODE (addr) == ADDR_EXPR
12566 && TREE_CODE (expr) == ADDR_EXPR
12567 && TREE_OPERAND (addr, 0) == TREE_OPERAND (expr, 0));
12569 if (TREE_CODE (addr) == ADDR_EXPR && expr == TREE_OPERAND (addr, 0))
12570 return true;
12571 return false;
12574 /* Walk *EXPR_P and replace appearances of *LHS_ADDR with LHS_VAR. If an
12575 expression does not involve the lhs, evaluate it into a temporary.
12576 Return 1 if the lhs appeared as a subexpression, 0 if it did not,
12577 or -1 if an error was encountered. */
12579 static int
12580 goa_stabilize_expr (tree *expr_p, gimple_seq *pre_p, tree lhs_addr,
12581 tree lhs_var)
12583 tree expr = *expr_p;
12584 int saw_lhs;
12586 if (goa_lhs_expr_p (expr, lhs_addr))
12588 *expr_p = lhs_var;
12589 return 1;
12591 if (is_gimple_val (expr))
12592 return 0;
12594 saw_lhs = 0;
12595 switch (TREE_CODE_CLASS (TREE_CODE (expr)))
12597 case tcc_binary:
12598 case tcc_comparison:
12599 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p, lhs_addr,
12600 lhs_var);
12601 /* FALLTHRU */
12602 case tcc_unary:
12603 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p, lhs_addr,
12604 lhs_var);
12605 break;
12606 case tcc_expression:
12607 switch (TREE_CODE (expr))
12609 case TRUTH_ANDIF_EXPR:
12610 case TRUTH_ORIF_EXPR:
12611 case TRUTH_AND_EXPR:
12612 case TRUTH_OR_EXPR:
12613 case TRUTH_XOR_EXPR:
12614 case BIT_INSERT_EXPR:
12615 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
12616 lhs_addr, lhs_var);
12617 /* FALLTHRU */
12618 case TRUTH_NOT_EXPR:
12619 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
12620 lhs_addr, lhs_var);
12621 break;
12622 case COMPOUND_EXPR:
12623 /* Break out any preevaluations from cp_build_modify_expr. */
12624 for (; TREE_CODE (expr) == COMPOUND_EXPR;
12625 expr = TREE_OPERAND (expr, 1))
12626 gimplify_stmt (&TREE_OPERAND (expr, 0), pre_p);
12627 *expr_p = expr;
12628 return goa_stabilize_expr (expr_p, pre_p, lhs_addr, lhs_var);
12629 default:
12630 break;
12632 break;
12633 case tcc_reference:
12634 if (TREE_CODE (expr) == BIT_FIELD_REF)
12635 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
12636 lhs_addr, lhs_var);
12637 break;
12638 default:
12639 break;
12642 if (saw_lhs == 0)
12644 enum gimplify_status gs;
12645 gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_val, fb_rvalue);
12646 if (gs != GS_ALL_DONE)
12647 saw_lhs = -1;
12650 return saw_lhs;
12653 /* Gimplify an OMP_ATOMIC statement. */
12655 static enum gimplify_status
12656 gimplify_omp_atomic (tree *expr_p, gimple_seq *pre_p)
12658 tree addr = TREE_OPERAND (*expr_p, 0);
12659 tree rhs = TREE_CODE (*expr_p) == OMP_ATOMIC_READ
12660 ? NULL : TREE_OPERAND (*expr_p, 1);
12661 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
12662 tree tmp_load;
12663 gomp_atomic_load *loadstmt;
12664 gomp_atomic_store *storestmt;
12666 tmp_load = create_tmp_reg (type);
12667 if (rhs && goa_stabilize_expr (&rhs, pre_p, addr, tmp_load) < 0)
12668 return GS_ERROR;
12670 if (gimplify_expr (&addr, pre_p, NULL, is_gimple_val, fb_rvalue)
12671 != GS_ALL_DONE)
12672 return GS_ERROR;
12674 loadstmt = gimple_build_omp_atomic_load (tmp_load, addr,
12675 OMP_ATOMIC_MEMORY_ORDER (*expr_p));
12676 gimplify_seq_add_stmt (pre_p, loadstmt);
12677 if (rhs)
12679 /* BIT_INSERT_EXPR is not valid for non-integral bitfield
12680 representatives. Use BIT_FIELD_REF on the lhs instead. */
12681 if (TREE_CODE (rhs) == BIT_INSERT_EXPR
12682 && !INTEGRAL_TYPE_P (TREE_TYPE (tmp_load)))
12684 tree bitpos = TREE_OPERAND (rhs, 2);
12685 tree op1 = TREE_OPERAND (rhs, 1);
12686 tree bitsize;
12687 tree tmp_store = tmp_load;
12688 if (TREE_CODE (*expr_p) == OMP_ATOMIC_CAPTURE_OLD)
12689 tmp_store = get_initialized_tmp_var (tmp_load, pre_p, NULL);
12690 if (INTEGRAL_TYPE_P (TREE_TYPE (op1)))
12691 bitsize = bitsize_int (TYPE_PRECISION (TREE_TYPE (op1)));
12692 else
12693 bitsize = TYPE_SIZE (TREE_TYPE (op1));
12694 gcc_assert (TREE_OPERAND (rhs, 0) == tmp_load);
12695 tree t = build2_loc (EXPR_LOCATION (rhs),
12696 MODIFY_EXPR, void_type_node,
12697 build3_loc (EXPR_LOCATION (rhs), BIT_FIELD_REF,
12698 TREE_TYPE (op1), tmp_store, bitsize,
12699 bitpos), op1);
12700 gimplify_and_add (t, pre_p);
12701 rhs = tmp_store;
12703 if (gimplify_expr (&rhs, pre_p, NULL, is_gimple_val, fb_rvalue)
12704 != GS_ALL_DONE)
12705 return GS_ERROR;
12708 if (TREE_CODE (*expr_p) == OMP_ATOMIC_READ)
12709 rhs = tmp_load;
12710 storestmt
12711 = gimple_build_omp_atomic_store (rhs, OMP_ATOMIC_MEMORY_ORDER (*expr_p));
12712 gimplify_seq_add_stmt (pre_p, storestmt);
12713 switch (TREE_CODE (*expr_p))
12715 case OMP_ATOMIC_READ:
12716 case OMP_ATOMIC_CAPTURE_OLD:
12717 *expr_p = tmp_load;
12718 gimple_omp_atomic_set_need_value (loadstmt);
12719 break;
12720 case OMP_ATOMIC_CAPTURE_NEW:
12721 *expr_p = rhs;
12722 gimple_omp_atomic_set_need_value (storestmt);
12723 break;
12724 default:
12725 *expr_p = NULL;
12726 break;
12729 return GS_ALL_DONE;
12732 /* Gimplify a TRANSACTION_EXPR. This involves gimplification of the
12733 body, and adding some EH bits. */
12735 static enum gimplify_status
12736 gimplify_transaction (tree *expr_p, gimple_seq *pre_p)
12738 tree expr = *expr_p, temp, tbody = TRANSACTION_EXPR_BODY (expr);
12739 gimple *body_stmt;
12740 gtransaction *trans_stmt;
12741 gimple_seq body = NULL;
12742 int subcode = 0;
12744 /* Wrap the transaction body in a BIND_EXPR so we have a context
12745 where to put decls for OMP. */
12746 if (TREE_CODE (tbody) != BIND_EXPR)
12748 tree bind = build3 (BIND_EXPR, void_type_node, NULL, tbody, NULL);
12749 TREE_SIDE_EFFECTS (bind) = 1;
12750 SET_EXPR_LOCATION (bind, EXPR_LOCATION (tbody));
12751 TRANSACTION_EXPR_BODY (expr) = bind;
12754 push_gimplify_context ();
12755 temp = voidify_wrapper_expr (*expr_p, NULL);
12757 body_stmt = gimplify_and_return_first (TRANSACTION_EXPR_BODY (expr), &body);
12758 pop_gimplify_context (body_stmt);
12760 trans_stmt = gimple_build_transaction (body);
12761 if (TRANSACTION_EXPR_OUTER (expr))
12762 subcode = GTMA_IS_OUTER;
12763 else if (TRANSACTION_EXPR_RELAXED (expr))
12764 subcode = GTMA_IS_RELAXED;
12765 gimple_transaction_set_subcode (trans_stmt, subcode);
12767 gimplify_seq_add_stmt (pre_p, trans_stmt);
12769 if (temp)
12771 *expr_p = temp;
12772 return GS_OK;
12775 *expr_p = NULL_TREE;
12776 return GS_ALL_DONE;
12779 /* Gimplify an OMP_ORDERED construct. EXPR is the tree version. BODY
12780 is the OMP_BODY of the original EXPR (which has already been
12781 gimplified so it's not present in the EXPR).
12783 Return the gimplified GIMPLE_OMP_ORDERED tuple. */
12785 static gimple *
12786 gimplify_omp_ordered (tree expr, gimple_seq body)
12788 tree c, decls;
12789 int failures = 0;
12790 unsigned int i;
12791 tree source_c = NULL_TREE;
12792 tree sink_c = NULL_TREE;
12794 if (gimplify_omp_ctxp)
12796 for (c = OMP_ORDERED_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
12797 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
12798 && gimplify_omp_ctxp->loop_iter_var.is_empty ()
12799 && (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK
12800 || OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE))
12802 error_at (OMP_CLAUSE_LOCATION (c),
12803 "%<ordered%> construct with %<depend%> clause must be "
12804 "closely nested inside a loop with %<ordered%> clause "
12805 "with a parameter");
12806 failures++;
12808 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
12809 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
12811 bool fail = false;
12812 for (decls = OMP_CLAUSE_DECL (c), i = 0;
12813 decls && TREE_CODE (decls) == TREE_LIST;
12814 decls = TREE_CHAIN (decls), ++i)
12815 if (i >= gimplify_omp_ctxp->loop_iter_var.length () / 2)
12816 continue;
12817 else if (TREE_VALUE (decls)
12818 != gimplify_omp_ctxp->loop_iter_var[2 * i])
12820 error_at (OMP_CLAUSE_LOCATION (c),
12821 "variable %qE is not an iteration "
12822 "of outermost loop %d, expected %qE",
12823 TREE_VALUE (decls), i + 1,
12824 gimplify_omp_ctxp->loop_iter_var[2 * i]);
12825 fail = true;
12826 failures++;
12828 else
12829 TREE_VALUE (decls)
12830 = gimplify_omp_ctxp->loop_iter_var[2 * i + 1];
12831 if (!fail && i != gimplify_omp_ctxp->loop_iter_var.length () / 2)
12833 error_at (OMP_CLAUSE_LOCATION (c),
12834 "number of variables in %<depend%> clause with "
12835 "%<sink%> modifier does not match number of "
12836 "iteration variables");
12837 failures++;
12839 sink_c = c;
12841 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
12842 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
12844 if (source_c)
12846 error_at (OMP_CLAUSE_LOCATION (c),
12847 "more than one %<depend%> clause with %<source%> "
12848 "modifier on an %<ordered%> construct");
12849 failures++;
12851 else
12852 source_c = c;
12855 if (source_c && sink_c)
12857 error_at (OMP_CLAUSE_LOCATION (source_c),
12858 "%<depend%> clause with %<source%> modifier specified "
12859 "together with %<depend%> clauses with %<sink%> modifier "
12860 "on the same construct");
12861 failures++;
12864 if (failures)
12865 return gimple_build_nop ();
12866 return gimple_build_omp_ordered (body, OMP_ORDERED_CLAUSES (expr));
12869 /* Convert the GENERIC expression tree *EXPR_P to GIMPLE. If the
12870 expression produces a value to be used as an operand inside a GIMPLE
12871 statement, the value will be stored back in *EXPR_P. This value will
12872 be a tree of class tcc_declaration, tcc_constant, tcc_reference or
12873 an SSA_NAME. The corresponding sequence of GIMPLE statements is
12874 emitted in PRE_P and POST_P.
12876 Additionally, this process may overwrite parts of the input
12877 expression during gimplification. Ideally, it should be
12878 possible to do non-destructive gimplification.
12880 EXPR_P points to the GENERIC expression to convert to GIMPLE. If
12881 the expression needs to evaluate to a value to be used as
12882 an operand in a GIMPLE statement, this value will be stored in
12883 *EXPR_P on exit. This happens when the caller specifies one
12884 of fb_lvalue or fb_rvalue fallback flags.
12886 PRE_P will contain the sequence of GIMPLE statements corresponding
12887 to the evaluation of EXPR and all the side-effects that must
12888 be executed before the main expression. On exit, the last
12889 statement of PRE_P is the core statement being gimplified. For
12890 instance, when gimplifying 'if (++a)' the last statement in
12891 PRE_P will be 'if (t.1)' where t.1 is the result of
12892 pre-incrementing 'a'.
12894 POST_P will contain the sequence of GIMPLE statements corresponding
12895 to the evaluation of all the side-effects that must be executed
12896 after the main expression. If this is NULL, the post
12897 side-effects are stored at the end of PRE_P.
12899 The reason why the output is split in two is to handle post
12900 side-effects explicitly. In some cases, an expression may have
12901 inner and outer post side-effects which need to be emitted in
12902 an order different from the one given by the recursive
12903 traversal. For instance, for the expression (*p--)++ the post
12904 side-effects of '--' must actually occur *after* the post
12905 side-effects of '++'. However, gimplification will first visit
12906 the inner expression, so if a separate POST sequence was not
12907 used, the resulting sequence would be:
12909 1 t.1 = *p
12910 2 p = p - 1
12911 3 t.2 = t.1 + 1
12912 4 *p = t.2
12914 However, the post-decrement operation in line #2 must not be
12915 evaluated until after the store to *p at line #4, so the
12916 correct sequence should be:
12918 1 t.1 = *p
12919 2 t.2 = t.1 + 1
12920 3 *p = t.2
12921 4 p = p - 1
12923 So, by specifying a separate post queue, it is possible
12924 to emit the post side-effects in the correct order.
12925 If POST_P is NULL, an internal queue will be used. Before
12926 returning to the caller, the sequence POST_P is appended to
12927 the main output sequence PRE_P.
12929 GIMPLE_TEST_F points to a function that takes a tree T and
12930 returns nonzero if T is in the GIMPLE form requested by the
12931 caller. The GIMPLE predicates are in gimple.c.
12933 FALLBACK tells the function what sort of a temporary we want if
12934 gimplification cannot produce an expression that complies with
12935 GIMPLE_TEST_F.
12937 fb_none means that no temporary should be generated
12938 fb_rvalue means that an rvalue is OK to generate
12939 fb_lvalue means that an lvalue is OK to generate
12940 fb_either means that either is OK, but an lvalue is preferable.
12941 fb_mayfail means that gimplification may fail (in which case
12942 GS_ERROR will be returned)
12944 The return value is either GS_ERROR or GS_ALL_DONE, since this
12945 function iterates until EXPR is completely gimplified or an error
12946 occurs. */
12948 enum gimplify_status
12949 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
12950 bool (*gimple_test_f) (tree), fallback_t fallback)
12952 tree tmp;
12953 gimple_seq internal_pre = NULL;
12954 gimple_seq internal_post = NULL;
12955 tree save_expr;
12956 bool is_statement;
12957 location_t saved_location;
12958 enum gimplify_status ret;
12959 gimple_stmt_iterator pre_last_gsi, post_last_gsi;
12960 tree label;
12962 save_expr = *expr_p;
12963 if (save_expr == NULL_TREE)
12964 return GS_ALL_DONE;
12966 /* If we are gimplifying a top-level statement, PRE_P must be valid. */
12967 is_statement = gimple_test_f == is_gimple_stmt;
12968 if (is_statement)
12969 gcc_assert (pre_p);
12971 /* Consistency checks. */
12972 if (gimple_test_f == is_gimple_reg)
12973 gcc_assert (fallback & (fb_rvalue | fb_lvalue));
12974 else if (gimple_test_f == is_gimple_val
12975 || gimple_test_f == is_gimple_call_addr
12976 || gimple_test_f == is_gimple_condexpr
12977 || gimple_test_f == is_gimple_mem_rhs
12978 || gimple_test_f == is_gimple_mem_rhs_or_call
12979 || gimple_test_f == is_gimple_reg_rhs
12980 || gimple_test_f == is_gimple_reg_rhs_or_call
12981 || gimple_test_f == is_gimple_asm_val
12982 || gimple_test_f == is_gimple_mem_ref_addr)
12983 gcc_assert (fallback & fb_rvalue);
12984 else if (gimple_test_f == is_gimple_min_lval
12985 || gimple_test_f == is_gimple_lvalue)
12986 gcc_assert (fallback & fb_lvalue);
12987 else if (gimple_test_f == is_gimple_addressable)
12988 gcc_assert (fallback & fb_either);
12989 else if (gimple_test_f == is_gimple_stmt)
12990 gcc_assert (fallback == fb_none);
12991 else
12993 /* We should have recognized the GIMPLE_TEST_F predicate to
12994 know what kind of fallback to use in case a temporary is
12995 needed to hold the value or address of *EXPR_P. */
12996 gcc_unreachable ();
12999 /* We used to check the predicate here and return immediately if it
13000 succeeds. This is wrong; the design is for gimplification to be
13001 idempotent, and for the predicates to only test for valid forms, not
13002 whether they are fully simplified. */
13003 if (pre_p == NULL)
13004 pre_p = &internal_pre;
13006 if (post_p == NULL)
13007 post_p = &internal_post;
13009 /* Remember the last statements added to PRE_P and POST_P. Every
13010 new statement added by the gimplification helpers needs to be
13011 annotated with location information. To centralize the
13012 responsibility, we remember the last statement that had been
13013 added to both queues before gimplifying *EXPR_P. If
13014 gimplification produces new statements in PRE_P and POST_P, those
13015 statements will be annotated with the same location information
13016 as *EXPR_P. */
13017 pre_last_gsi = gsi_last (*pre_p);
13018 post_last_gsi = gsi_last (*post_p);
13020 saved_location = input_location;
13021 if (save_expr != error_mark_node
13022 && EXPR_HAS_LOCATION (*expr_p))
13023 input_location = EXPR_LOCATION (*expr_p);
13025 /* Loop over the specific gimplifiers until the toplevel node
13026 remains the same. */
13029 /* Strip away as many useless type conversions as possible
13030 at the toplevel. */
13031 STRIP_USELESS_TYPE_CONVERSION (*expr_p);
13033 /* Remember the expr. */
13034 save_expr = *expr_p;
13036 /* Die, die, die, my darling. */
13037 if (error_operand_p (save_expr))
13039 ret = GS_ERROR;
13040 break;
13043 /* Do any language-specific gimplification. */
13044 ret = ((enum gimplify_status)
13045 lang_hooks.gimplify_expr (expr_p, pre_p, post_p));
13046 if (ret == GS_OK)
13048 if (*expr_p == NULL_TREE)
13049 break;
13050 if (*expr_p != save_expr)
13051 continue;
13053 else if (ret != GS_UNHANDLED)
13054 break;
13056 /* Make sure that all the cases set 'ret' appropriately. */
13057 ret = GS_UNHANDLED;
13058 switch (TREE_CODE (*expr_p))
13060 /* First deal with the special cases. */
13062 case POSTINCREMENT_EXPR:
13063 case POSTDECREMENT_EXPR:
13064 case PREINCREMENT_EXPR:
13065 case PREDECREMENT_EXPR:
13066 ret = gimplify_self_mod_expr (expr_p, pre_p, post_p,
13067 fallback != fb_none,
13068 TREE_TYPE (*expr_p));
13069 break;
13071 case VIEW_CONVERT_EXPR:
13072 if ((fallback & fb_rvalue)
13073 && is_gimple_reg_type (TREE_TYPE (*expr_p))
13074 && is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0))))
13076 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
13077 post_p, is_gimple_val, fb_rvalue);
13078 recalculate_side_effects (*expr_p);
13079 break;
13081 /* Fallthru. */
13083 case ARRAY_REF:
13084 case ARRAY_RANGE_REF:
13085 case REALPART_EXPR:
13086 case IMAGPART_EXPR:
13087 case COMPONENT_REF:
13088 ret = gimplify_compound_lval (expr_p, pre_p, post_p,
13089 fallback ? fallback : fb_rvalue);
13090 break;
13092 case COND_EXPR:
13093 ret = gimplify_cond_expr (expr_p, pre_p, fallback);
13095 /* C99 code may assign to an array in a structure value of a
13096 conditional expression, and this has undefined behavior
13097 only on execution, so create a temporary if an lvalue is
13098 required. */
13099 if (fallback == fb_lvalue)
13101 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
13102 mark_addressable (*expr_p);
13103 ret = GS_OK;
13105 break;
13107 case CALL_EXPR:
13108 ret = gimplify_call_expr (expr_p, pre_p, fallback != fb_none);
13110 /* C99 code may assign to an array in a structure returned
13111 from a function, and this has undefined behavior only on
13112 execution, so create a temporary if an lvalue is
13113 required. */
13114 if (fallback == fb_lvalue)
13116 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
13117 mark_addressable (*expr_p);
13118 ret = GS_OK;
13120 break;
13122 case TREE_LIST:
13123 gcc_unreachable ();
13125 case COMPOUND_EXPR:
13126 ret = gimplify_compound_expr (expr_p, pre_p, fallback != fb_none);
13127 break;
13129 case COMPOUND_LITERAL_EXPR:
13130 ret = gimplify_compound_literal_expr (expr_p, pre_p,
13131 gimple_test_f, fallback);
13132 break;
13134 case MODIFY_EXPR:
13135 case INIT_EXPR:
13136 ret = gimplify_modify_expr (expr_p, pre_p, post_p,
13137 fallback != fb_none);
13138 break;
13140 case TRUTH_ANDIF_EXPR:
13141 case TRUTH_ORIF_EXPR:
13143 /* Preserve the original type of the expression and the
13144 source location of the outer expression. */
13145 tree org_type = TREE_TYPE (*expr_p);
13146 *expr_p = gimple_boolify (*expr_p);
13147 *expr_p = build3_loc (input_location, COND_EXPR,
13148 org_type, *expr_p,
13149 fold_convert_loc
13150 (input_location,
13151 org_type, boolean_true_node),
13152 fold_convert_loc
13153 (input_location,
13154 org_type, boolean_false_node));
13155 ret = GS_OK;
13156 break;
13159 case TRUTH_NOT_EXPR:
13161 tree type = TREE_TYPE (*expr_p);
13162 /* The parsers are careful to generate TRUTH_NOT_EXPR
13163 only with operands that are always zero or one.
13164 We do not fold here but handle the only interesting case
13165 manually, as fold may re-introduce the TRUTH_NOT_EXPR. */
13166 *expr_p = gimple_boolify (*expr_p);
13167 if (TYPE_PRECISION (TREE_TYPE (*expr_p)) == 1)
13168 *expr_p = build1_loc (input_location, BIT_NOT_EXPR,
13169 TREE_TYPE (*expr_p),
13170 TREE_OPERAND (*expr_p, 0));
13171 else
13172 *expr_p = build2_loc (input_location, BIT_XOR_EXPR,
13173 TREE_TYPE (*expr_p),
13174 TREE_OPERAND (*expr_p, 0),
13175 build_int_cst (TREE_TYPE (*expr_p), 1));
13176 if (!useless_type_conversion_p (type, TREE_TYPE (*expr_p)))
13177 *expr_p = fold_convert_loc (input_location, type, *expr_p);
13178 ret = GS_OK;
13179 break;
13182 case ADDR_EXPR:
13183 ret = gimplify_addr_expr (expr_p, pre_p, post_p);
13184 break;
13186 case ANNOTATE_EXPR:
13188 tree cond = TREE_OPERAND (*expr_p, 0);
13189 tree kind = TREE_OPERAND (*expr_p, 1);
13190 tree data = TREE_OPERAND (*expr_p, 2);
13191 tree type = TREE_TYPE (cond);
13192 if (!INTEGRAL_TYPE_P (type))
13194 *expr_p = cond;
13195 ret = GS_OK;
13196 break;
13198 tree tmp = create_tmp_var (type);
13199 gimplify_arg (&cond, pre_p, EXPR_LOCATION (*expr_p));
13200 gcall *call
13201 = gimple_build_call_internal (IFN_ANNOTATE, 3, cond, kind, data);
13202 gimple_call_set_lhs (call, tmp);
13203 gimplify_seq_add_stmt (pre_p, call);
13204 *expr_p = tmp;
13205 ret = GS_ALL_DONE;
13206 break;
13209 case VA_ARG_EXPR:
13210 ret = gimplify_va_arg_expr (expr_p, pre_p, post_p);
13211 break;
13213 CASE_CONVERT:
13214 if (IS_EMPTY_STMT (*expr_p))
13216 ret = GS_ALL_DONE;
13217 break;
13220 if (VOID_TYPE_P (TREE_TYPE (*expr_p))
13221 || fallback == fb_none)
13223 /* Just strip a conversion to void (or in void context) and
13224 try again. */
13225 *expr_p = TREE_OPERAND (*expr_p, 0);
13226 ret = GS_OK;
13227 break;
13230 ret = gimplify_conversion (expr_p);
13231 if (ret == GS_ERROR)
13232 break;
13233 if (*expr_p != save_expr)
13234 break;
13235 /* FALLTHRU */
13237 case FIX_TRUNC_EXPR:
13238 /* unary_expr: ... | '(' cast ')' val | ... */
13239 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
13240 is_gimple_val, fb_rvalue);
13241 recalculate_side_effects (*expr_p);
13242 break;
13244 case INDIRECT_REF:
13246 bool volatilep = TREE_THIS_VOLATILE (*expr_p);
13247 bool notrap = TREE_THIS_NOTRAP (*expr_p);
13248 tree saved_ptr_type = TREE_TYPE (TREE_OPERAND (*expr_p, 0));
13250 *expr_p = fold_indirect_ref_loc (input_location, *expr_p);
13251 if (*expr_p != save_expr)
13253 ret = GS_OK;
13254 break;
13257 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
13258 is_gimple_reg, fb_rvalue);
13259 if (ret == GS_ERROR)
13260 break;
13262 recalculate_side_effects (*expr_p);
13263 *expr_p = fold_build2_loc (input_location, MEM_REF,
13264 TREE_TYPE (*expr_p),
13265 TREE_OPERAND (*expr_p, 0),
13266 build_int_cst (saved_ptr_type, 0));
13267 TREE_THIS_VOLATILE (*expr_p) = volatilep;
13268 TREE_THIS_NOTRAP (*expr_p) = notrap;
13269 ret = GS_OK;
13270 break;
13273 /* We arrive here through the various re-gimplifcation paths. */
13274 case MEM_REF:
13275 /* First try re-folding the whole thing. */
13276 tmp = fold_binary (MEM_REF, TREE_TYPE (*expr_p),
13277 TREE_OPERAND (*expr_p, 0),
13278 TREE_OPERAND (*expr_p, 1));
13279 if (tmp)
13281 REF_REVERSE_STORAGE_ORDER (tmp)
13282 = REF_REVERSE_STORAGE_ORDER (*expr_p);
13283 *expr_p = tmp;
13284 recalculate_side_effects (*expr_p);
13285 ret = GS_OK;
13286 break;
13288 /* Avoid re-gimplifying the address operand if it is already
13289 in suitable form. Re-gimplifying would mark the address
13290 operand addressable. Always gimplify when not in SSA form
13291 as we still may have to gimplify decls with value-exprs. */
13292 if (!gimplify_ctxp || !gimple_in_ssa_p (cfun)
13293 || !is_gimple_mem_ref_addr (TREE_OPERAND (*expr_p, 0)))
13295 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
13296 is_gimple_mem_ref_addr, fb_rvalue);
13297 if (ret == GS_ERROR)
13298 break;
13300 recalculate_side_effects (*expr_p);
13301 ret = GS_ALL_DONE;
13302 break;
13304 /* Constants need not be gimplified. */
13305 case INTEGER_CST:
13306 case REAL_CST:
13307 case FIXED_CST:
13308 case STRING_CST:
13309 case COMPLEX_CST:
13310 case VECTOR_CST:
13311 /* Drop the overflow flag on constants, we do not want
13312 that in the GIMPLE IL. */
13313 if (TREE_OVERFLOW_P (*expr_p))
13314 *expr_p = drop_tree_overflow (*expr_p);
13315 ret = GS_ALL_DONE;
13316 break;
13318 case CONST_DECL:
13319 /* If we require an lvalue, such as for ADDR_EXPR, retain the
13320 CONST_DECL node. Otherwise the decl is replaceable by its
13321 value. */
13322 /* ??? Should be == fb_lvalue, but ADDR_EXPR passes fb_either. */
13323 if (fallback & fb_lvalue)
13324 ret = GS_ALL_DONE;
13325 else
13327 *expr_p = DECL_INITIAL (*expr_p);
13328 ret = GS_OK;
13330 break;
13332 case DECL_EXPR:
13333 ret = gimplify_decl_expr (expr_p, pre_p);
13334 break;
13336 case BIND_EXPR:
13337 ret = gimplify_bind_expr (expr_p, pre_p);
13338 break;
13340 case LOOP_EXPR:
13341 ret = gimplify_loop_expr (expr_p, pre_p);
13342 break;
13344 case SWITCH_EXPR:
13345 ret = gimplify_switch_expr (expr_p, pre_p);
13346 break;
13348 case EXIT_EXPR:
13349 ret = gimplify_exit_expr (expr_p);
13350 break;
13352 case GOTO_EXPR:
13353 /* If the target is not LABEL, then it is a computed jump
13354 and the target needs to be gimplified. */
13355 if (TREE_CODE (GOTO_DESTINATION (*expr_p)) != LABEL_DECL)
13357 ret = gimplify_expr (&GOTO_DESTINATION (*expr_p), pre_p,
13358 NULL, is_gimple_val, fb_rvalue);
13359 if (ret == GS_ERROR)
13360 break;
13362 gimplify_seq_add_stmt (pre_p,
13363 gimple_build_goto (GOTO_DESTINATION (*expr_p)));
13364 ret = GS_ALL_DONE;
13365 break;
13367 case PREDICT_EXPR:
13368 gimplify_seq_add_stmt (pre_p,
13369 gimple_build_predict (PREDICT_EXPR_PREDICTOR (*expr_p),
13370 PREDICT_EXPR_OUTCOME (*expr_p)));
13371 ret = GS_ALL_DONE;
13372 break;
13374 case LABEL_EXPR:
13375 ret = gimplify_label_expr (expr_p, pre_p);
13376 label = LABEL_EXPR_LABEL (*expr_p);
13377 gcc_assert (decl_function_context (label) == current_function_decl);
13379 /* If the label is used in a goto statement, or address of the label
13380 is taken, we need to unpoison all variables that were seen so far.
13381 Doing so would prevent us from reporting a false positives. */
13382 if (asan_poisoned_variables
13383 && asan_used_labels != NULL
13384 && asan_used_labels->contains (label))
13385 asan_poison_variables (asan_poisoned_variables, false, pre_p);
13386 break;
13388 case CASE_LABEL_EXPR:
13389 ret = gimplify_case_label_expr (expr_p, pre_p);
13391 if (gimplify_ctxp->live_switch_vars)
13392 asan_poison_variables (gimplify_ctxp->live_switch_vars, false,
13393 pre_p);
13394 break;
13396 case RETURN_EXPR:
13397 ret = gimplify_return_expr (*expr_p, pre_p);
13398 break;
13400 case CONSTRUCTOR:
13401 /* Don't reduce this in place; let gimplify_init_constructor work its
13402 magic. Buf if we're just elaborating this for side effects, just
13403 gimplify any element that has side-effects. */
13404 if (fallback == fb_none)
13406 unsigned HOST_WIDE_INT ix;
13407 tree val;
13408 tree temp = NULL_TREE;
13409 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (*expr_p), ix, val)
13410 if (TREE_SIDE_EFFECTS (val))
13411 append_to_statement_list (val, &temp);
13413 *expr_p = temp;
13414 ret = temp ? GS_OK : GS_ALL_DONE;
13416 /* C99 code may assign to an array in a constructed
13417 structure or union, and this has undefined behavior only
13418 on execution, so create a temporary if an lvalue is
13419 required. */
13420 else if (fallback == fb_lvalue)
13422 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
13423 mark_addressable (*expr_p);
13424 ret = GS_OK;
13426 else
13427 ret = GS_ALL_DONE;
13428 break;
13430 /* The following are special cases that are not handled by the
13431 original GIMPLE grammar. */
13433 /* SAVE_EXPR nodes are converted into a GIMPLE identifier and
13434 eliminated. */
13435 case SAVE_EXPR:
13436 ret = gimplify_save_expr (expr_p, pre_p, post_p);
13437 break;
13439 case BIT_FIELD_REF:
13440 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
13441 post_p, is_gimple_lvalue, fb_either);
13442 recalculate_side_effects (*expr_p);
13443 break;
13445 case TARGET_MEM_REF:
13447 enum gimplify_status r0 = GS_ALL_DONE, r1 = GS_ALL_DONE;
13449 if (TMR_BASE (*expr_p))
13450 r0 = gimplify_expr (&TMR_BASE (*expr_p), pre_p,
13451 post_p, is_gimple_mem_ref_addr, fb_either);
13452 if (TMR_INDEX (*expr_p))
13453 r1 = gimplify_expr (&TMR_INDEX (*expr_p), pre_p,
13454 post_p, is_gimple_val, fb_rvalue);
13455 if (TMR_INDEX2 (*expr_p))
13456 r1 = gimplify_expr (&TMR_INDEX2 (*expr_p), pre_p,
13457 post_p, is_gimple_val, fb_rvalue);
13458 /* TMR_STEP and TMR_OFFSET are always integer constants. */
13459 ret = MIN (r0, r1);
13461 break;
13463 case NON_LVALUE_EXPR:
13464 /* This should have been stripped above. */
13465 gcc_unreachable ();
13467 case ASM_EXPR:
13468 ret = gimplify_asm_expr (expr_p, pre_p, post_p);
13469 break;
13471 case TRY_FINALLY_EXPR:
13472 case TRY_CATCH_EXPR:
13474 gimple_seq eval, cleanup;
13475 gtry *try_;
13477 /* Calls to destructors are generated automatically in FINALLY/CATCH
13478 block. They should have location as UNKNOWN_LOCATION. However,
13479 gimplify_call_expr will reset these call stmts to input_location
13480 if it finds stmt's location is unknown. To prevent resetting for
13481 destructors, we set the input_location to unknown.
13482 Note that this only affects the destructor calls in FINALLY/CATCH
13483 block, and will automatically reset to its original value by the
13484 end of gimplify_expr. */
13485 input_location = UNKNOWN_LOCATION;
13486 eval = cleanup = NULL;
13487 gimplify_and_add (TREE_OPERAND (*expr_p, 0), &eval);
13488 if (TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
13489 && TREE_CODE (TREE_OPERAND (*expr_p, 1)) == EH_ELSE_EXPR)
13491 gimple_seq n = NULL, e = NULL;
13492 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1),
13493 0), &n);
13494 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1),
13495 1), &e);
13496 if (!gimple_seq_empty_p (n) && !gimple_seq_empty_p (e))
13498 geh_else *stmt = gimple_build_eh_else (n, e);
13499 gimple_seq_add_stmt (&cleanup, stmt);
13502 else
13503 gimplify_and_add (TREE_OPERAND (*expr_p, 1), &cleanup);
13504 /* Don't create bogus GIMPLE_TRY with empty cleanup. */
13505 if (gimple_seq_empty_p (cleanup))
13507 gimple_seq_add_seq (pre_p, eval);
13508 ret = GS_ALL_DONE;
13509 break;
13511 try_ = gimple_build_try (eval, cleanup,
13512 TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
13513 ? GIMPLE_TRY_FINALLY
13514 : GIMPLE_TRY_CATCH);
13515 if (EXPR_HAS_LOCATION (save_expr))
13516 gimple_set_location (try_, EXPR_LOCATION (save_expr));
13517 else if (LOCATION_LOCUS (saved_location) != UNKNOWN_LOCATION)
13518 gimple_set_location (try_, saved_location);
13519 if (TREE_CODE (*expr_p) == TRY_CATCH_EXPR)
13520 gimple_try_set_catch_is_cleanup (try_,
13521 TRY_CATCH_IS_CLEANUP (*expr_p));
13522 gimplify_seq_add_stmt (pre_p, try_);
13523 ret = GS_ALL_DONE;
13524 break;
13527 case CLEANUP_POINT_EXPR:
13528 ret = gimplify_cleanup_point_expr (expr_p, pre_p);
13529 break;
13531 case TARGET_EXPR:
13532 ret = gimplify_target_expr (expr_p, pre_p, post_p);
13533 break;
13535 case CATCH_EXPR:
13537 gimple *c;
13538 gimple_seq handler = NULL;
13539 gimplify_and_add (CATCH_BODY (*expr_p), &handler);
13540 c = gimple_build_catch (CATCH_TYPES (*expr_p), handler);
13541 gimplify_seq_add_stmt (pre_p, c);
13542 ret = GS_ALL_DONE;
13543 break;
13546 case EH_FILTER_EXPR:
13548 gimple *ehf;
13549 gimple_seq failure = NULL;
13551 gimplify_and_add (EH_FILTER_FAILURE (*expr_p), &failure);
13552 ehf = gimple_build_eh_filter (EH_FILTER_TYPES (*expr_p), failure);
13553 gimple_set_no_warning (ehf, TREE_NO_WARNING (*expr_p));
13554 gimplify_seq_add_stmt (pre_p, ehf);
13555 ret = GS_ALL_DONE;
13556 break;
13559 case OBJ_TYPE_REF:
13561 enum gimplify_status r0, r1;
13562 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p,
13563 post_p, is_gimple_val, fb_rvalue);
13564 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p,
13565 post_p, is_gimple_val, fb_rvalue);
13566 TREE_SIDE_EFFECTS (*expr_p) = 0;
13567 ret = MIN (r0, r1);
13569 break;
13571 case LABEL_DECL:
13572 /* We get here when taking the address of a label. We mark
13573 the label as "forced"; meaning it can never be removed and
13574 it is a potential target for any computed goto. */
13575 FORCED_LABEL (*expr_p) = 1;
13576 ret = GS_ALL_DONE;
13577 break;
13579 case STATEMENT_LIST:
13580 ret = gimplify_statement_list (expr_p, pre_p);
13581 break;
13583 case WITH_SIZE_EXPR:
13585 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
13586 post_p == &internal_post ? NULL : post_p,
13587 gimple_test_f, fallback);
13588 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
13589 is_gimple_val, fb_rvalue);
13590 ret = GS_ALL_DONE;
13592 break;
13594 case VAR_DECL:
13595 case PARM_DECL:
13596 ret = gimplify_var_or_parm_decl (expr_p);
13597 break;
13599 case RESULT_DECL:
13600 /* When within an OMP context, notice uses of variables. */
13601 if (gimplify_omp_ctxp)
13602 omp_notice_variable (gimplify_omp_ctxp, *expr_p, true);
13603 ret = GS_ALL_DONE;
13604 break;
13606 case DEBUG_EXPR_DECL:
13607 gcc_unreachable ();
13609 case DEBUG_BEGIN_STMT:
13610 gimplify_seq_add_stmt (pre_p,
13611 gimple_build_debug_begin_stmt
13612 (TREE_BLOCK (*expr_p),
13613 EXPR_LOCATION (*expr_p)));
13614 ret = GS_ALL_DONE;
13615 *expr_p = NULL;
13616 break;
13618 case SSA_NAME:
13619 /* Allow callbacks into the gimplifier during optimization. */
13620 ret = GS_ALL_DONE;
13621 break;
13623 case OMP_PARALLEL:
13624 gimplify_omp_parallel (expr_p, pre_p);
13625 ret = GS_ALL_DONE;
13626 break;
13628 case OMP_TASK:
13629 gimplify_omp_task (expr_p, pre_p);
13630 ret = GS_ALL_DONE;
13631 break;
13633 case OMP_FOR:
13634 case OMP_SIMD:
13635 case OMP_DISTRIBUTE:
13636 case OMP_TASKLOOP:
13637 case OACC_LOOP:
13638 ret = gimplify_omp_for (expr_p, pre_p);
13639 break;
13641 case OMP_LOOP:
13642 ret = gimplify_omp_loop (expr_p, pre_p);
13643 break;
13645 case OACC_CACHE:
13646 gimplify_oacc_cache (expr_p, pre_p);
13647 ret = GS_ALL_DONE;
13648 break;
13650 case OACC_DECLARE:
13651 gimplify_oacc_declare (expr_p, pre_p);
13652 ret = GS_ALL_DONE;
13653 break;
13655 case OACC_HOST_DATA:
13656 case OACC_DATA:
13657 case OACC_KERNELS:
13658 case OACC_PARALLEL:
13659 case OMP_SECTIONS:
13660 case OMP_SINGLE:
13661 case OMP_TARGET:
13662 case OMP_TARGET_DATA:
13663 case OMP_TEAMS:
13664 gimplify_omp_workshare (expr_p, pre_p);
13665 ret = GS_ALL_DONE;
13666 break;
13668 case OACC_ENTER_DATA:
13669 case OACC_EXIT_DATA:
13670 case OACC_UPDATE:
13671 case OMP_TARGET_UPDATE:
13672 case OMP_TARGET_ENTER_DATA:
13673 case OMP_TARGET_EXIT_DATA:
13674 gimplify_omp_target_update (expr_p, pre_p);
13675 ret = GS_ALL_DONE;
13676 break;
13678 case OMP_SECTION:
13679 case OMP_MASTER:
13680 case OMP_ORDERED:
13681 case OMP_CRITICAL:
13682 case OMP_SCAN:
13684 gimple_seq body = NULL;
13685 gimple *g;
13686 bool saved_in_omp_construct = in_omp_construct;
13688 in_omp_construct = true;
13689 gimplify_and_add (OMP_BODY (*expr_p), &body);
13690 in_omp_construct = saved_in_omp_construct;
13691 switch (TREE_CODE (*expr_p))
13693 case OMP_SECTION:
13694 g = gimple_build_omp_section (body);
13695 break;
13696 case OMP_MASTER:
13697 g = gimple_build_omp_master (body);
13698 break;
13699 case OMP_ORDERED:
13700 g = gimplify_omp_ordered (*expr_p, body);
13701 break;
13702 case OMP_CRITICAL:
13703 gimplify_scan_omp_clauses (&OMP_CRITICAL_CLAUSES (*expr_p),
13704 pre_p, ORT_WORKSHARE, OMP_CRITICAL);
13705 gimplify_adjust_omp_clauses (pre_p, body,
13706 &OMP_CRITICAL_CLAUSES (*expr_p),
13707 OMP_CRITICAL);
13708 g = gimple_build_omp_critical (body,
13709 OMP_CRITICAL_NAME (*expr_p),
13710 OMP_CRITICAL_CLAUSES (*expr_p));
13711 break;
13712 case OMP_SCAN:
13713 gimplify_scan_omp_clauses (&OMP_SCAN_CLAUSES (*expr_p),
13714 pre_p, ORT_WORKSHARE, OMP_SCAN);
13715 gimplify_adjust_omp_clauses (pre_p, body,
13716 &OMP_SCAN_CLAUSES (*expr_p),
13717 OMP_SCAN);
13718 g = gimple_build_omp_scan (body, OMP_SCAN_CLAUSES (*expr_p));
13719 break;
13720 default:
13721 gcc_unreachable ();
13723 gimplify_seq_add_stmt (pre_p, g);
13724 ret = GS_ALL_DONE;
13725 break;
13728 case OMP_TASKGROUP:
13730 gimple_seq body = NULL;
13732 tree *pclauses = &OMP_TASKGROUP_CLAUSES (*expr_p);
13733 bool saved_in_omp_construct = in_omp_construct;
13734 gimplify_scan_omp_clauses (pclauses, pre_p, ORT_TASKGROUP,
13735 OMP_TASKGROUP);
13736 gimplify_adjust_omp_clauses (pre_p, NULL, pclauses, OMP_TASKGROUP);
13738 in_omp_construct = true;
13739 gimplify_and_add (OMP_BODY (*expr_p), &body);
13740 in_omp_construct = saved_in_omp_construct;
13741 gimple_seq cleanup = NULL;
13742 tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_END);
13743 gimple *g = gimple_build_call (fn, 0);
13744 gimple_seq_add_stmt (&cleanup, g);
13745 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
13746 body = NULL;
13747 gimple_seq_add_stmt (&body, g);
13748 g = gimple_build_omp_taskgroup (body, *pclauses);
13749 gimplify_seq_add_stmt (pre_p, g);
13750 ret = GS_ALL_DONE;
13751 break;
13754 case OMP_ATOMIC:
13755 case OMP_ATOMIC_READ:
13756 case OMP_ATOMIC_CAPTURE_OLD:
13757 case OMP_ATOMIC_CAPTURE_NEW:
13758 ret = gimplify_omp_atomic (expr_p, pre_p);
13759 break;
13761 case TRANSACTION_EXPR:
13762 ret = gimplify_transaction (expr_p, pre_p);
13763 break;
13765 case TRUTH_AND_EXPR:
13766 case TRUTH_OR_EXPR:
13767 case TRUTH_XOR_EXPR:
13769 tree orig_type = TREE_TYPE (*expr_p);
13770 tree new_type, xop0, xop1;
13771 *expr_p = gimple_boolify (*expr_p);
13772 new_type = TREE_TYPE (*expr_p);
13773 if (!useless_type_conversion_p (orig_type, new_type))
13775 *expr_p = fold_convert_loc (input_location, orig_type, *expr_p);
13776 ret = GS_OK;
13777 break;
13780 /* Boolified binary truth expressions are semantically equivalent
13781 to bitwise binary expressions. Canonicalize them to the
13782 bitwise variant. */
13783 switch (TREE_CODE (*expr_p))
13785 case TRUTH_AND_EXPR:
13786 TREE_SET_CODE (*expr_p, BIT_AND_EXPR);
13787 break;
13788 case TRUTH_OR_EXPR:
13789 TREE_SET_CODE (*expr_p, BIT_IOR_EXPR);
13790 break;
13791 case TRUTH_XOR_EXPR:
13792 TREE_SET_CODE (*expr_p, BIT_XOR_EXPR);
13793 break;
13794 default:
13795 break;
13797 /* Now make sure that operands have compatible type to
13798 expression's new_type. */
13799 xop0 = TREE_OPERAND (*expr_p, 0);
13800 xop1 = TREE_OPERAND (*expr_p, 1);
13801 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop0)))
13802 TREE_OPERAND (*expr_p, 0) = fold_convert_loc (input_location,
13803 new_type,
13804 xop0);
13805 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop1)))
13806 TREE_OPERAND (*expr_p, 1) = fold_convert_loc (input_location,
13807 new_type,
13808 xop1);
13809 /* Continue classified as tcc_binary. */
13810 goto expr_2;
13813 case VEC_COND_EXPR:
13815 enum gimplify_status r0, r1, r2;
13817 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
13818 post_p, is_gimple_condexpr, fb_rvalue);
13819 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
13820 post_p, is_gimple_val, fb_rvalue);
13821 r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p,
13822 post_p, is_gimple_val, fb_rvalue);
13824 ret = MIN (MIN (r0, r1), r2);
13825 recalculate_side_effects (*expr_p);
13827 break;
13829 case VEC_PERM_EXPR:
13830 /* Classified as tcc_expression. */
13831 goto expr_3;
13833 case BIT_INSERT_EXPR:
13834 /* Argument 3 is a constant. */
13835 goto expr_2;
13837 case POINTER_PLUS_EXPR:
13839 enum gimplify_status r0, r1;
13840 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
13841 post_p, is_gimple_val, fb_rvalue);
13842 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
13843 post_p, is_gimple_val, fb_rvalue);
13844 recalculate_side_effects (*expr_p);
13845 ret = MIN (r0, r1);
13846 break;
13849 default:
13850 switch (TREE_CODE_CLASS (TREE_CODE (*expr_p)))
13852 case tcc_comparison:
13853 /* Handle comparison of objects of non scalar mode aggregates
13854 with a call to memcmp. It would be nice to only have to do
13855 this for variable-sized objects, but then we'd have to allow
13856 the same nest of reference nodes we allow for MODIFY_EXPR and
13857 that's too complex.
13859 Compare scalar mode aggregates as scalar mode values. Using
13860 memcmp for them would be very inefficient at best, and is
13861 plain wrong if bitfields are involved. */
13863 tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 1));
13865 /* Vector comparisons need no boolification. */
13866 if (TREE_CODE (type) == VECTOR_TYPE)
13867 goto expr_2;
13868 else if (!AGGREGATE_TYPE_P (type))
13870 tree org_type = TREE_TYPE (*expr_p);
13871 *expr_p = gimple_boolify (*expr_p);
13872 if (!useless_type_conversion_p (org_type,
13873 TREE_TYPE (*expr_p)))
13875 *expr_p = fold_convert_loc (input_location,
13876 org_type, *expr_p);
13877 ret = GS_OK;
13879 else
13880 goto expr_2;
13882 else if (TYPE_MODE (type) != BLKmode)
13883 ret = gimplify_scalar_mode_aggregate_compare (expr_p);
13884 else
13885 ret = gimplify_variable_sized_compare (expr_p);
13887 break;
13890 /* If *EXPR_P does not need to be special-cased, handle it
13891 according to its class. */
13892 case tcc_unary:
13893 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
13894 post_p, is_gimple_val, fb_rvalue);
13895 break;
13897 case tcc_binary:
13898 expr_2:
13900 enum gimplify_status r0, r1;
13902 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
13903 post_p, is_gimple_val, fb_rvalue);
13904 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
13905 post_p, is_gimple_val, fb_rvalue);
13907 ret = MIN (r0, r1);
13908 break;
13911 expr_3:
13913 enum gimplify_status r0, r1, r2;
13915 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
13916 post_p, is_gimple_val, fb_rvalue);
13917 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
13918 post_p, is_gimple_val, fb_rvalue);
13919 r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p,
13920 post_p, is_gimple_val, fb_rvalue);
13922 ret = MIN (MIN (r0, r1), r2);
13923 break;
13926 case tcc_declaration:
13927 case tcc_constant:
13928 ret = GS_ALL_DONE;
13929 goto dont_recalculate;
13931 default:
13932 gcc_unreachable ();
13935 recalculate_side_effects (*expr_p);
13937 dont_recalculate:
13938 break;
13941 gcc_assert (*expr_p || ret != GS_OK);
13943 while (ret == GS_OK);
13945 /* If we encountered an error_mark somewhere nested inside, either
13946 stub out the statement or propagate the error back out. */
13947 if (ret == GS_ERROR)
13949 if (is_statement)
13950 *expr_p = NULL;
13951 goto out;
13954 /* This was only valid as a return value from the langhook, which
13955 we handled. Make sure it doesn't escape from any other context. */
13956 gcc_assert (ret != GS_UNHANDLED);
13958 if (fallback == fb_none && *expr_p && !is_gimple_stmt (*expr_p))
13960 /* We aren't looking for a value, and we don't have a valid
13961 statement. If it doesn't have side-effects, throw it away.
13962 We can also get here with code such as "*&&L;", where L is
13963 a LABEL_DECL that is marked as FORCED_LABEL. */
13964 if (TREE_CODE (*expr_p) == LABEL_DECL
13965 || !TREE_SIDE_EFFECTS (*expr_p))
13966 *expr_p = NULL;
13967 else if (!TREE_THIS_VOLATILE (*expr_p))
13969 /* This is probably a _REF that contains something nested that
13970 has side effects. Recurse through the operands to find it. */
13971 enum tree_code code = TREE_CODE (*expr_p);
13973 switch (code)
13975 case COMPONENT_REF:
13976 case REALPART_EXPR:
13977 case IMAGPART_EXPR:
13978 case VIEW_CONVERT_EXPR:
13979 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
13980 gimple_test_f, fallback);
13981 break;
13983 case ARRAY_REF:
13984 case ARRAY_RANGE_REF:
13985 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
13986 gimple_test_f, fallback);
13987 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
13988 gimple_test_f, fallback);
13989 break;
13991 default:
13992 /* Anything else with side-effects must be converted to
13993 a valid statement before we get here. */
13994 gcc_unreachable ();
13997 *expr_p = NULL;
13999 else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p))
14000 && TYPE_MODE (TREE_TYPE (*expr_p)) != BLKmode)
14002 /* Historically, the compiler has treated a bare reference
14003 to a non-BLKmode volatile lvalue as forcing a load. */
14004 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p));
14006 /* Normally, we do not want to create a temporary for a
14007 TREE_ADDRESSABLE type because such a type should not be
14008 copied by bitwise-assignment. However, we make an
14009 exception here, as all we are doing here is ensuring that
14010 we read the bytes that make up the type. We use
14011 create_tmp_var_raw because create_tmp_var will abort when
14012 given a TREE_ADDRESSABLE type. */
14013 tree tmp = create_tmp_var_raw (type, "vol");
14014 gimple_add_tmp_var (tmp);
14015 gimplify_assign (tmp, *expr_p, pre_p);
14016 *expr_p = NULL;
14018 else
14019 /* We can't do anything useful with a volatile reference to
14020 an incomplete type, so just throw it away. Likewise for
14021 a BLKmode type, since any implicit inner load should
14022 already have been turned into an explicit one by the
14023 gimplification process. */
14024 *expr_p = NULL;
14027 /* If we are gimplifying at the statement level, we're done. Tack
14028 everything together and return. */
14029 if (fallback == fb_none || is_statement)
14031 /* Since *EXPR_P has been converted into a GIMPLE tuple, clear
14032 it out for GC to reclaim it. */
14033 *expr_p = NULL_TREE;
14035 if (!gimple_seq_empty_p (internal_pre)
14036 || !gimple_seq_empty_p (internal_post))
14038 gimplify_seq_add_seq (&internal_pre, internal_post);
14039 gimplify_seq_add_seq (pre_p, internal_pre);
14042 /* The result of gimplifying *EXPR_P is going to be the last few
14043 statements in *PRE_P and *POST_P. Add location information
14044 to all the statements that were added by the gimplification
14045 helpers. */
14046 if (!gimple_seq_empty_p (*pre_p))
14047 annotate_all_with_location_after (*pre_p, pre_last_gsi, input_location);
14049 if (!gimple_seq_empty_p (*post_p))
14050 annotate_all_with_location_after (*post_p, post_last_gsi,
14051 input_location);
14053 goto out;
14056 #ifdef ENABLE_GIMPLE_CHECKING
14057 if (*expr_p)
14059 enum tree_code code = TREE_CODE (*expr_p);
14060 /* These expressions should already be in gimple IR form. */
14061 gcc_assert (code != MODIFY_EXPR
14062 && code != ASM_EXPR
14063 && code != BIND_EXPR
14064 && code != CATCH_EXPR
14065 && (code != COND_EXPR || gimplify_ctxp->allow_rhs_cond_expr)
14066 && code != EH_FILTER_EXPR
14067 && code != GOTO_EXPR
14068 && code != LABEL_EXPR
14069 && code != LOOP_EXPR
14070 && code != SWITCH_EXPR
14071 && code != TRY_FINALLY_EXPR
14072 && code != EH_ELSE_EXPR
14073 && code != OACC_PARALLEL
14074 && code != OACC_KERNELS
14075 && code != OACC_DATA
14076 && code != OACC_HOST_DATA
14077 && code != OACC_DECLARE
14078 && code != OACC_UPDATE
14079 && code != OACC_ENTER_DATA
14080 && code != OACC_EXIT_DATA
14081 && code != OACC_CACHE
14082 && code != OMP_CRITICAL
14083 && code != OMP_FOR
14084 && code != OACC_LOOP
14085 && code != OMP_MASTER
14086 && code != OMP_TASKGROUP
14087 && code != OMP_ORDERED
14088 && code != OMP_PARALLEL
14089 && code != OMP_SCAN
14090 && code != OMP_SECTIONS
14091 && code != OMP_SECTION
14092 && code != OMP_SINGLE);
14094 #endif
14096 /* Otherwise we're gimplifying a subexpression, so the resulting
14097 value is interesting. If it's a valid operand that matches
14098 GIMPLE_TEST_F, we're done. Unless we are handling some
14099 post-effects internally; if that's the case, we need to copy into
14100 a temporary before adding the post-effects to POST_P. */
14101 if (gimple_seq_empty_p (internal_post) && (*gimple_test_f) (*expr_p))
14102 goto out;
14104 /* Otherwise, we need to create a new temporary for the gimplified
14105 expression. */
14107 /* We can't return an lvalue if we have an internal postqueue. The
14108 object the lvalue refers to would (probably) be modified by the
14109 postqueue; we need to copy the value out first, which means an
14110 rvalue. */
14111 if ((fallback & fb_lvalue)
14112 && gimple_seq_empty_p (internal_post)
14113 && is_gimple_addressable (*expr_p))
14115 /* An lvalue will do. Take the address of the expression, store it
14116 in a temporary, and replace the expression with an INDIRECT_REF of
14117 that temporary. */
14118 tree ref_alias_type = reference_alias_ptr_type (*expr_p);
14119 unsigned int ref_align = get_object_alignment (*expr_p);
14120 tree ref_type = TREE_TYPE (*expr_p);
14121 tmp = build_fold_addr_expr_loc (input_location, *expr_p);
14122 gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue);
14123 if (TYPE_ALIGN (ref_type) != ref_align)
14124 ref_type = build_aligned_type (ref_type, ref_align);
14125 *expr_p = build2 (MEM_REF, ref_type,
14126 tmp, build_zero_cst (ref_alias_type));
14128 else if ((fallback & fb_rvalue) && is_gimple_reg_rhs_or_call (*expr_p))
14130 /* An rvalue will do. Assign the gimplified expression into a
14131 new temporary TMP and replace the original expression with
14132 TMP. First, make sure that the expression has a type so that
14133 it can be assigned into a temporary. */
14134 gcc_assert (!VOID_TYPE_P (TREE_TYPE (*expr_p)));
14135 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
14137 else
14139 #ifdef ENABLE_GIMPLE_CHECKING
14140 if (!(fallback & fb_mayfail))
14142 fprintf (stderr, "gimplification failed:\n");
14143 print_generic_expr (stderr, *expr_p);
14144 debug_tree (*expr_p);
14145 internal_error ("gimplification failed");
14147 #endif
14148 gcc_assert (fallback & fb_mayfail);
14150 /* If this is an asm statement, and the user asked for the
14151 impossible, don't die. Fail and let gimplify_asm_expr
14152 issue an error. */
14153 ret = GS_ERROR;
14154 goto out;
14157 /* Make sure the temporary matches our predicate. */
14158 gcc_assert ((*gimple_test_f) (*expr_p));
14160 if (!gimple_seq_empty_p (internal_post))
14162 annotate_all_with_location (internal_post, input_location);
14163 gimplify_seq_add_seq (pre_p, internal_post);
14166 out:
14167 input_location = saved_location;
14168 return ret;
14171 /* Like gimplify_expr but make sure the gimplified result is not itself
14172 a SSA name (but a decl if it were). Temporaries required by
14173 evaluating *EXPR_P may be still SSA names. */
14175 static enum gimplify_status
14176 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
14177 bool (*gimple_test_f) (tree), fallback_t fallback,
14178 bool allow_ssa)
14180 bool was_ssa_name_p = TREE_CODE (*expr_p) == SSA_NAME;
14181 enum gimplify_status ret = gimplify_expr (expr_p, pre_p, post_p,
14182 gimple_test_f, fallback);
14183 if (! allow_ssa
14184 && TREE_CODE (*expr_p) == SSA_NAME)
14186 tree name = *expr_p;
14187 if (was_ssa_name_p)
14188 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, NULL, false);
14189 else
14191 /* Avoid the extra copy if possible. */
14192 *expr_p = create_tmp_reg (TREE_TYPE (name));
14193 gimple_set_lhs (SSA_NAME_DEF_STMT (name), *expr_p);
14194 release_ssa_name (name);
14197 return ret;
14200 /* Look through TYPE for variable-sized objects and gimplify each such
14201 size that we find. Add to LIST_P any statements generated. */
14203 void
14204 gimplify_type_sizes (tree type, gimple_seq *list_p)
14206 tree field, t;
14208 if (type == NULL || type == error_mark_node)
14209 return;
14211 /* We first do the main variant, then copy into any other variants. */
14212 type = TYPE_MAIN_VARIANT (type);
14214 /* Avoid infinite recursion. */
14215 if (TYPE_SIZES_GIMPLIFIED (type))
14216 return;
14218 TYPE_SIZES_GIMPLIFIED (type) = 1;
14220 switch (TREE_CODE (type))
14222 case INTEGER_TYPE:
14223 case ENUMERAL_TYPE:
14224 case BOOLEAN_TYPE:
14225 case REAL_TYPE:
14226 case FIXED_POINT_TYPE:
14227 gimplify_one_sizepos (&TYPE_MIN_VALUE (type), list_p);
14228 gimplify_one_sizepos (&TYPE_MAX_VALUE (type), list_p);
14230 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
14232 TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type);
14233 TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type);
14235 break;
14237 case ARRAY_TYPE:
14238 /* These types may not have declarations, so handle them here. */
14239 gimplify_type_sizes (TREE_TYPE (type), list_p);
14240 gimplify_type_sizes (TYPE_DOMAIN (type), list_p);
14241 /* Ensure VLA bounds aren't removed, for -O0 they should be variables
14242 with assigned stack slots, for -O1+ -g they should be tracked
14243 by VTA. */
14244 if (!(TYPE_NAME (type)
14245 && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
14246 && DECL_IGNORED_P (TYPE_NAME (type)))
14247 && TYPE_DOMAIN (type)
14248 && INTEGRAL_TYPE_P (TYPE_DOMAIN (type)))
14250 t = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
14251 if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
14252 DECL_IGNORED_P (t) = 0;
14253 t = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
14254 if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
14255 DECL_IGNORED_P (t) = 0;
14257 break;
14259 case RECORD_TYPE:
14260 case UNION_TYPE:
14261 case QUAL_UNION_TYPE:
14262 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
14263 if (TREE_CODE (field) == FIELD_DECL)
14265 gimplify_one_sizepos (&DECL_FIELD_OFFSET (field), list_p);
14266 gimplify_one_sizepos (&DECL_SIZE (field), list_p);
14267 gimplify_one_sizepos (&DECL_SIZE_UNIT (field), list_p);
14268 gimplify_type_sizes (TREE_TYPE (field), list_p);
14270 break;
14272 case POINTER_TYPE:
14273 case REFERENCE_TYPE:
14274 /* We used to recurse on the pointed-to type here, which turned out to
14275 be incorrect because its definition might refer to variables not
14276 yet initialized at this point if a forward declaration is involved.
14278 It was actually useful for anonymous pointed-to types to ensure
14279 that the sizes evaluation dominates every possible later use of the
14280 values. Restricting to such types here would be safe since there
14281 is no possible forward declaration around, but would introduce an
14282 undesirable middle-end semantic to anonymity. We then defer to
14283 front-ends the responsibility of ensuring that the sizes are
14284 evaluated both early and late enough, e.g. by attaching artificial
14285 type declarations to the tree. */
14286 break;
14288 default:
14289 break;
14292 gimplify_one_sizepos (&TYPE_SIZE (type), list_p);
14293 gimplify_one_sizepos (&TYPE_SIZE_UNIT (type), list_p);
14295 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
14297 TYPE_SIZE (t) = TYPE_SIZE (type);
14298 TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (type);
14299 TYPE_SIZES_GIMPLIFIED (t) = 1;
14303 /* A subroutine of gimplify_type_sizes to make sure that *EXPR_P,
14304 a size or position, has had all of its SAVE_EXPRs evaluated.
14305 We add any required statements to *STMT_P. */
14307 void
14308 gimplify_one_sizepos (tree *expr_p, gimple_seq *stmt_p)
14310 tree expr = *expr_p;
14312 /* We don't do anything if the value isn't there, is constant, or contains
14313 A PLACEHOLDER_EXPR. We also don't want to do anything if it's already
14314 a VAR_DECL. If it's a VAR_DECL from another function, the gimplifier
14315 will want to replace it with a new variable, but that will cause problems
14316 if this type is from outside the function. It's OK to have that here. */
14317 if (expr == NULL_TREE
14318 || is_gimple_constant (expr)
14319 || TREE_CODE (expr) == VAR_DECL
14320 || CONTAINS_PLACEHOLDER_P (expr))
14321 return;
14323 *expr_p = unshare_expr (expr);
14325 /* SSA names in decl/type fields are a bad idea - they'll get reclaimed
14326 if the def vanishes. */
14327 gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue, false);
14329 /* If expr wasn't already is_gimple_sizepos or is_gimple_constant from the
14330 FE, ensure that it is a VAR_DECL, otherwise we might handle some decls
14331 as gimplify_vla_decl even when they would have all sizes INTEGER_CSTs. */
14332 if (is_gimple_constant (*expr_p))
14333 *expr_p = get_initialized_tmp_var (*expr_p, stmt_p, NULL, false);
14336 /* Gimplify the body of statements of FNDECL and return a GIMPLE_BIND node
14337 containing the sequence of corresponding GIMPLE statements. If DO_PARMS
14338 is true, also gimplify the parameters. */
14340 gbind *
14341 gimplify_body (tree fndecl, bool do_parms)
14343 location_t saved_location = input_location;
14344 gimple_seq parm_stmts, parm_cleanup = NULL, seq;
14345 gimple *outer_stmt;
14346 gbind *outer_bind;
14348 timevar_push (TV_TREE_GIMPLIFY);
14350 init_tree_ssa (cfun);
14352 /* Initialize for optimize_insn_for_s{ize,peed}_p possibly called during
14353 gimplification. */
14354 default_rtl_profile ();
14356 gcc_assert (gimplify_ctxp == NULL);
14357 push_gimplify_context (true);
14359 if (flag_openacc || flag_openmp)
14361 gcc_assert (gimplify_omp_ctxp == NULL);
14362 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (fndecl)))
14363 gimplify_omp_ctxp = new_omp_context (ORT_IMPLICIT_TARGET);
14366 /* Unshare most shared trees in the body and in that of any nested functions.
14367 It would seem we don't have to do this for nested functions because
14368 they are supposed to be output and then the outer function gimplified
14369 first, but the g++ front end doesn't always do it that way. */
14370 unshare_body (fndecl);
14371 unvisit_body (fndecl);
14373 /* Make sure input_location isn't set to something weird. */
14374 input_location = DECL_SOURCE_LOCATION (fndecl);
14376 /* Resolve callee-copies. This has to be done before processing
14377 the body so that DECL_VALUE_EXPR gets processed correctly. */
14378 parm_stmts = do_parms ? gimplify_parameters (&parm_cleanup) : NULL;
14380 /* Gimplify the function's body. */
14381 seq = NULL;
14382 gimplify_stmt (&DECL_SAVED_TREE (fndecl), &seq);
14383 outer_stmt = gimple_seq_first_stmt (seq);
14384 if (!outer_stmt)
14386 outer_stmt = gimple_build_nop ();
14387 gimplify_seq_add_stmt (&seq, outer_stmt);
14390 /* The body must contain exactly one statement, a GIMPLE_BIND. If this is
14391 not the case, wrap everything in a GIMPLE_BIND to make it so. */
14392 if (gimple_code (outer_stmt) == GIMPLE_BIND
14393 && gimple_seq_first (seq) == gimple_seq_last (seq))
14394 outer_bind = as_a <gbind *> (outer_stmt);
14395 else
14396 outer_bind = gimple_build_bind (NULL_TREE, seq, NULL);
14398 DECL_SAVED_TREE (fndecl) = NULL_TREE;
14400 /* If we had callee-copies statements, insert them at the beginning
14401 of the function and clear DECL_VALUE_EXPR_P on the parameters. */
14402 if (!gimple_seq_empty_p (parm_stmts))
14404 tree parm;
14406 gimplify_seq_add_seq (&parm_stmts, gimple_bind_body (outer_bind));
14407 if (parm_cleanup)
14409 gtry *g = gimple_build_try (parm_stmts, parm_cleanup,
14410 GIMPLE_TRY_FINALLY);
14411 parm_stmts = NULL;
14412 gimple_seq_add_stmt (&parm_stmts, g);
14414 gimple_bind_set_body (outer_bind, parm_stmts);
14416 for (parm = DECL_ARGUMENTS (current_function_decl);
14417 parm; parm = DECL_CHAIN (parm))
14418 if (DECL_HAS_VALUE_EXPR_P (parm))
14420 DECL_HAS_VALUE_EXPR_P (parm) = 0;
14421 DECL_IGNORED_P (parm) = 0;
14425 if ((flag_openacc || flag_openmp || flag_openmp_simd)
14426 && gimplify_omp_ctxp)
14428 delete_omp_context (gimplify_omp_ctxp);
14429 gimplify_omp_ctxp = NULL;
14432 pop_gimplify_context (outer_bind);
14433 gcc_assert (gimplify_ctxp == NULL);
14435 if (flag_checking && !seen_error ())
14436 verify_gimple_in_seq (gimple_bind_body (outer_bind));
14438 timevar_pop (TV_TREE_GIMPLIFY);
14439 input_location = saved_location;
14441 return outer_bind;
14444 typedef char *char_p; /* For DEF_VEC_P. */
14446 /* Return whether we should exclude FNDECL from instrumentation. */
14448 static bool
14449 flag_instrument_functions_exclude_p (tree fndecl)
14451 vec<char_p> *v;
14453 v = (vec<char_p> *) flag_instrument_functions_exclude_functions;
14454 if (v && v->length () > 0)
14456 const char *name;
14457 int i;
14458 char *s;
14460 name = lang_hooks.decl_printable_name (fndecl, 1);
14461 FOR_EACH_VEC_ELT (*v, i, s)
14462 if (strstr (name, s) != NULL)
14463 return true;
14466 v = (vec<char_p> *) flag_instrument_functions_exclude_files;
14467 if (v && v->length () > 0)
14469 const char *name;
14470 int i;
14471 char *s;
14473 name = DECL_SOURCE_FILE (fndecl);
14474 FOR_EACH_VEC_ELT (*v, i, s)
14475 if (strstr (name, s) != NULL)
14476 return true;
14479 return false;
14482 /* Entry point to the gimplification pass. FNDECL is the FUNCTION_DECL
14483 node for the function we want to gimplify.
14485 Return the sequence of GIMPLE statements corresponding to the body
14486 of FNDECL. */
14488 void
14489 gimplify_function_tree (tree fndecl)
14491 tree parm, ret;
14492 gimple_seq seq;
14493 gbind *bind;
14495 gcc_assert (!gimple_body (fndecl));
14497 if (DECL_STRUCT_FUNCTION (fndecl))
14498 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
14499 else
14500 push_struct_function (fndecl);
14502 /* Tentatively set PROP_gimple_lva here, and reset it in gimplify_va_arg_expr
14503 if necessary. */
14504 cfun->curr_properties |= PROP_gimple_lva;
14506 for (parm = DECL_ARGUMENTS (fndecl); parm ; parm = DECL_CHAIN (parm))
14508 /* Preliminarily mark non-addressed complex variables as eligible
14509 for promotion to gimple registers. We'll transform their uses
14510 as we find them. */
14511 if ((TREE_CODE (TREE_TYPE (parm)) == COMPLEX_TYPE
14512 || TREE_CODE (TREE_TYPE (parm)) == VECTOR_TYPE)
14513 && !TREE_THIS_VOLATILE (parm)
14514 && !needs_to_live_in_memory (parm))
14515 DECL_GIMPLE_REG_P (parm) = 1;
14518 ret = DECL_RESULT (fndecl);
14519 if ((TREE_CODE (TREE_TYPE (ret)) == COMPLEX_TYPE
14520 || TREE_CODE (TREE_TYPE (ret)) == VECTOR_TYPE)
14521 && !needs_to_live_in_memory (ret))
14522 DECL_GIMPLE_REG_P (ret) = 1;
14524 if (asan_sanitize_use_after_scope () && sanitize_flags_p (SANITIZE_ADDRESS))
14525 asan_poisoned_variables = new hash_set<tree> ();
14526 bind = gimplify_body (fndecl, true);
14527 if (asan_poisoned_variables)
14529 delete asan_poisoned_variables;
14530 asan_poisoned_variables = NULL;
14533 /* The tree body of the function is no longer needed, replace it
14534 with the new GIMPLE body. */
14535 seq = NULL;
14536 gimple_seq_add_stmt (&seq, bind);
14537 gimple_set_body (fndecl, seq);
14539 /* If we're instrumenting function entry/exit, then prepend the call to
14540 the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to
14541 catch the exit hook. */
14542 /* ??? Add some way to ignore exceptions for this TFE. */
14543 if (flag_instrument_function_entry_exit
14544 && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl)
14545 /* Do not instrument extern inline functions. */
14546 && !(DECL_DECLARED_INLINE_P (fndecl)
14547 && DECL_EXTERNAL (fndecl)
14548 && DECL_DISREGARD_INLINE_LIMITS (fndecl))
14549 && !flag_instrument_functions_exclude_p (fndecl))
14551 tree x;
14552 gbind *new_bind;
14553 gimple *tf;
14554 gimple_seq cleanup = NULL, body = NULL;
14555 tree tmp_var, this_fn_addr;
14556 gcall *call;
14558 /* The instrumentation hooks aren't going to call the instrumented
14559 function and the address they receive is expected to be matchable
14560 against symbol addresses. Make sure we don't create a trampoline,
14561 in case the current function is nested. */
14562 this_fn_addr = build_fold_addr_expr (current_function_decl);
14563 TREE_NO_TRAMPOLINE (this_fn_addr) = 1;
14565 x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
14566 call = gimple_build_call (x, 1, integer_zero_node);
14567 tmp_var = create_tmp_var (ptr_type_node, "return_addr");
14568 gimple_call_set_lhs (call, tmp_var);
14569 gimplify_seq_add_stmt (&cleanup, call);
14570 x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_EXIT);
14571 call = gimple_build_call (x, 2, this_fn_addr, tmp_var);
14572 gimplify_seq_add_stmt (&cleanup, call);
14573 tf = gimple_build_try (seq, cleanup, GIMPLE_TRY_FINALLY);
14575 x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
14576 call = gimple_build_call (x, 1, integer_zero_node);
14577 tmp_var = create_tmp_var (ptr_type_node, "return_addr");
14578 gimple_call_set_lhs (call, tmp_var);
14579 gimplify_seq_add_stmt (&body, call);
14580 x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_ENTER);
14581 call = gimple_build_call (x, 2, this_fn_addr, tmp_var);
14582 gimplify_seq_add_stmt (&body, call);
14583 gimplify_seq_add_stmt (&body, tf);
14584 new_bind = gimple_build_bind (NULL, body, NULL);
14586 /* Replace the current function body with the body
14587 wrapped in the try/finally TF. */
14588 seq = NULL;
14589 gimple_seq_add_stmt (&seq, new_bind);
14590 gimple_set_body (fndecl, seq);
14591 bind = new_bind;
14594 if (sanitize_flags_p (SANITIZE_THREAD))
14596 gcall *call = gimple_build_call_internal (IFN_TSAN_FUNC_EXIT, 0);
14597 gimple *tf = gimple_build_try (seq, call, GIMPLE_TRY_FINALLY);
14598 gbind *new_bind = gimple_build_bind (NULL, tf, NULL);
14599 /* Replace the current function body with the body
14600 wrapped in the try/finally TF. */
14601 seq = NULL;
14602 gimple_seq_add_stmt (&seq, new_bind);
14603 gimple_set_body (fndecl, seq);
14606 DECL_SAVED_TREE (fndecl) = NULL_TREE;
14607 cfun->curr_properties |= PROP_gimple_any;
14609 pop_cfun ();
14611 dump_function (TDI_gimple, fndecl);
14614 /* Return a dummy expression of type TYPE in order to keep going after an
14615 error. */
14617 static tree
14618 dummy_object (tree type)
14620 tree t = build_int_cst (build_pointer_type (type), 0);
14621 return build2 (MEM_REF, type, t, t);
14624 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
14625 builtin function, but a very special sort of operator. */
14627 enum gimplify_status
14628 gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p,
14629 gimple_seq *post_p ATTRIBUTE_UNUSED)
14631 tree promoted_type, have_va_type;
14632 tree valist = TREE_OPERAND (*expr_p, 0);
14633 tree type = TREE_TYPE (*expr_p);
14634 tree t, tag, aptag;
14635 location_t loc = EXPR_LOCATION (*expr_p);
14637 /* Verify that valist is of the proper type. */
14638 have_va_type = TREE_TYPE (valist);
14639 if (have_va_type == error_mark_node)
14640 return GS_ERROR;
14641 have_va_type = targetm.canonical_va_list_type (have_va_type);
14642 if (have_va_type == NULL_TREE
14643 && POINTER_TYPE_P (TREE_TYPE (valist)))
14644 /* Handle 'Case 1: Not an array type' from c-common.c/build_va_arg. */
14645 have_va_type
14646 = targetm.canonical_va_list_type (TREE_TYPE (TREE_TYPE (valist)));
14647 gcc_assert (have_va_type != NULL_TREE);
14649 /* Generate a diagnostic for requesting data of a type that cannot
14650 be passed through `...' due to type promotion at the call site. */
14651 if ((promoted_type = lang_hooks.types.type_promotes_to (type))
14652 != type)
14654 static bool gave_help;
14655 bool warned;
14656 /* Use the expansion point to handle cases such as passing bool (defined
14657 in a system header) through `...'. */
14658 location_t xloc
14659 = expansion_point_location_if_in_system_header (loc);
14661 /* Unfortunately, this is merely undefined, rather than a constraint
14662 violation, so we cannot make this an error. If this call is never
14663 executed, the program is still strictly conforming. */
14664 auto_diagnostic_group d;
14665 warned = warning_at (xloc, 0,
14666 "%qT is promoted to %qT when passed through %<...%>",
14667 type, promoted_type);
14668 if (!gave_help && warned)
14670 gave_help = true;
14671 inform (xloc, "(so you should pass %qT not %qT to %<va_arg%>)",
14672 promoted_type, type);
14675 /* We can, however, treat "undefined" any way we please.
14676 Call abort to encourage the user to fix the program. */
14677 if (warned)
14678 inform (xloc, "if this code is reached, the program will abort");
14679 /* Before the abort, allow the evaluation of the va_list
14680 expression to exit or longjmp. */
14681 gimplify_and_add (valist, pre_p);
14682 t = build_call_expr_loc (loc,
14683 builtin_decl_implicit (BUILT_IN_TRAP), 0);
14684 gimplify_and_add (t, pre_p);
14686 /* This is dead code, but go ahead and finish so that the
14687 mode of the result comes out right. */
14688 *expr_p = dummy_object (type);
14689 return GS_ALL_DONE;
14692 tag = build_int_cst (build_pointer_type (type), 0);
14693 aptag = build_int_cst (TREE_TYPE (valist), 0);
14695 *expr_p = build_call_expr_internal_loc (loc, IFN_VA_ARG, type, 3,
14696 valist, tag, aptag);
14698 /* Clear the tentatively set PROP_gimple_lva, to indicate that IFN_VA_ARG
14699 needs to be expanded. */
14700 cfun->curr_properties &= ~PROP_gimple_lva;
14702 return GS_OK;
14705 /* Build a new GIMPLE_ASSIGN tuple and append it to the end of *SEQ_P.
14707 DST/SRC are the destination and source respectively. You can pass
14708 ungimplified trees in DST or SRC, in which case they will be
14709 converted to a gimple operand if necessary.
14711 This function returns the newly created GIMPLE_ASSIGN tuple. */
14713 gimple *
14714 gimplify_assign (tree dst, tree src, gimple_seq *seq_p)
14716 tree t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
14717 gimplify_and_add (t, seq_p);
14718 ggc_free (t);
14719 return gimple_seq_last_stmt (*seq_p);
14722 inline hashval_t
14723 gimplify_hasher::hash (const elt_t *p)
14725 tree t = p->val;
14726 return iterative_hash_expr (t, 0);
14729 inline bool
14730 gimplify_hasher::equal (const elt_t *p1, const elt_t *p2)
14732 tree t1 = p1->val;
14733 tree t2 = p2->val;
14734 enum tree_code code = TREE_CODE (t1);
14736 if (TREE_CODE (t2) != code
14737 || TREE_TYPE (t1) != TREE_TYPE (t2))
14738 return false;
14740 if (!operand_equal_p (t1, t2, 0))
14741 return false;
14743 /* Only allow them to compare equal if they also hash equal; otherwise
14744 results are nondeterminate, and we fail bootstrap comparison. */
14745 gcc_checking_assert (hash (p1) == hash (p2));
14747 return true;