2018-11-09 Richard Biener <rguenther@suse.de>
[official-gcc.git] / gcc / gimplify.c
blob61dca240db6de51cfa7b78320c9e14cc22fa3f3c
1 /* Tree lowering pass. This pass converts the GENERIC functions-as-trees
2 tree representation into the GIMPLE form.
3 Copyright (C) 2002-2018 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"
69 /* Hash set of poisoned variables in a bind expr. */
70 static hash_set<tree> *asan_poisoned_variables = NULL;
72 enum gimplify_omp_var_data
74 GOVD_SEEN = 1,
75 GOVD_EXPLICIT = 2,
76 GOVD_SHARED = 4,
77 GOVD_PRIVATE = 8,
78 GOVD_FIRSTPRIVATE = 16,
79 GOVD_LASTPRIVATE = 32,
80 GOVD_REDUCTION = 64,
81 GOVD_LOCAL = 128,
82 GOVD_MAP = 256,
83 GOVD_DEBUG_PRIVATE = 512,
84 GOVD_PRIVATE_OUTER_REF = 1024,
85 GOVD_LINEAR = 2048,
86 GOVD_ALIGNED = 4096,
88 /* Flag for GOVD_MAP: don't copy back. */
89 GOVD_MAP_TO_ONLY = 8192,
91 /* Flag for GOVD_LINEAR or GOVD_LASTPRIVATE: no outer reference. */
92 GOVD_LINEAR_LASTPRIVATE_NO_OUTER = 16384,
94 GOVD_MAP_0LEN_ARRAY = 32768,
96 /* Flag for GOVD_MAP, if it is always, to or always, tofrom mapping. */
97 GOVD_MAP_ALWAYS_TO = 65536,
99 /* Flag for shared vars that are or might be stored to in the region. */
100 GOVD_WRITTEN = 131072,
102 /* Flag for GOVD_MAP, if it is a forced mapping. */
103 GOVD_MAP_FORCE = 262144,
105 /* Flag for GOVD_MAP: must be present already. */
106 GOVD_MAP_FORCE_PRESENT = 524288,
108 /* Flag for GOVD_MAP: only allocate. */
109 GOVD_MAP_ALLOC_ONLY = 1048576,
111 /* Flag for GOVD_MAP: only copy back. */
112 GOVD_MAP_FROM_ONLY = 2097152,
114 GOVD_NONTEMPORAL = 4194304,
116 GOVD_DATA_SHARE_CLASS = (GOVD_SHARED | GOVD_PRIVATE | GOVD_FIRSTPRIVATE
117 | GOVD_LASTPRIVATE | GOVD_REDUCTION | GOVD_LINEAR
118 | GOVD_LOCAL)
122 enum omp_region_type
124 ORT_WORKSHARE = 0x00,
125 ORT_TASKGROUP = 0x01,
126 ORT_SIMD = 0x04,
128 ORT_PARALLEL = 0x08,
129 ORT_COMBINED_PARALLEL = ORT_PARALLEL | 1,
131 ORT_TASK = 0x10,
132 ORT_UNTIED_TASK = ORT_TASK | 1,
133 ORT_TASKLOOP = ORT_TASK | 2,
134 ORT_UNTIED_TASKLOOP = ORT_UNTIED_TASK | 2,
136 ORT_TEAMS = 0x20,
137 ORT_COMBINED_TEAMS = ORT_TEAMS | 1,
138 ORT_HOST_TEAMS = ORT_TEAMS | 2,
139 ORT_COMBINED_HOST_TEAMS = ORT_COMBINED_TEAMS | 2,
141 /* Data region. */
142 ORT_TARGET_DATA = 0x40,
144 /* Data region with offloading. */
145 ORT_TARGET = 0x80,
146 ORT_COMBINED_TARGET = ORT_TARGET | 1,
148 /* OpenACC variants. */
149 ORT_ACC = 0x100, /* A generic OpenACC region. */
150 ORT_ACC_DATA = ORT_ACC | ORT_TARGET_DATA, /* Data construct. */
151 ORT_ACC_PARALLEL = ORT_ACC | ORT_TARGET, /* Parallel construct */
152 ORT_ACC_KERNELS = ORT_ACC | ORT_TARGET | 2, /* Kernels construct. */
153 ORT_ACC_HOST_DATA = ORT_ACC | ORT_TARGET_DATA | 2, /* Host data. */
155 /* Dummy OpenMP region, used to disable expansion of
156 DECL_VALUE_EXPRs in taskloop pre body. */
157 ORT_NONE = 0x200
160 /* Gimplify hashtable helper. */
162 struct gimplify_hasher : free_ptr_hash <elt_t>
164 static inline hashval_t hash (const elt_t *);
165 static inline bool equal (const elt_t *, const elt_t *);
168 struct gimplify_ctx
170 struct gimplify_ctx *prev_context;
172 vec<gbind *> bind_expr_stack;
173 tree temps;
174 gimple_seq conditional_cleanups;
175 tree exit_label;
176 tree return_temp;
178 vec<tree> case_labels;
179 hash_set<tree> *live_switch_vars;
180 /* The formal temporary table. Should this be persistent? */
181 hash_table<gimplify_hasher> *temp_htab;
183 int conditions;
184 unsigned into_ssa : 1;
185 unsigned allow_rhs_cond_expr : 1;
186 unsigned in_cleanup_point_expr : 1;
187 unsigned keep_stack : 1;
188 unsigned save_stack : 1;
189 unsigned in_switch_expr : 1;
192 enum gimplify_defaultmap_kind
194 GDMK_SCALAR,
195 GDMK_AGGREGATE,
196 GDMK_ALLOCATABLE,
197 GDMK_POINTER
200 struct gimplify_omp_ctx
202 struct gimplify_omp_ctx *outer_context;
203 splay_tree variables;
204 hash_set<tree> *privatized_types;
205 /* Iteration variables in an OMP_FOR. */
206 vec<tree> loop_iter_var;
207 location_t location;
208 enum omp_clause_default_kind default_kind;
209 enum omp_region_type region_type;
210 bool combined_loop;
211 bool distribute;
212 bool target_firstprivatize_array_bases;
213 int defaultmap[4];
216 static struct gimplify_ctx *gimplify_ctxp;
217 static struct gimplify_omp_ctx *gimplify_omp_ctxp;
219 /* Forward declaration. */
220 static enum gimplify_status gimplify_compound_expr (tree *, gimple_seq *, bool);
221 static hash_map<tree, tree> *oacc_declare_returns;
222 static enum gimplify_status gimplify_expr (tree *, gimple_seq *, gimple_seq *,
223 bool (*) (tree), fallback_t, bool);
225 /* Shorter alias name for the above function for use in gimplify.c
226 only. */
228 static inline void
229 gimplify_seq_add_stmt (gimple_seq *seq_p, gimple *gs)
231 gimple_seq_add_stmt_without_update (seq_p, gs);
234 /* Append sequence SRC to the end of sequence *DST_P. If *DST_P is
235 NULL, a new sequence is allocated. This function is
236 similar to gimple_seq_add_seq, but does not scan the operands.
237 During gimplification, we need to manipulate statement sequences
238 before the def/use vectors have been constructed. */
240 static void
241 gimplify_seq_add_seq (gimple_seq *dst_p, gimple_seq src)
243 gimple_stmt_iterator si;
245 if (src == NULL)
246 return;
248 si = gsi_last (*dst_p);
249 gsi_insert_seq_after_without_update (&si, src, GSI_NEW_STMT);
253 /* Pointer to a list of allocated gimplify_ctx structs to be used for pushing
254 and popping gimplify contexts. */
256 static struct gimplify_ctx *ctx_pool = NULL;
258 /* Return a gimplify context struct from the pool. */
260 static inline struct gimplify_ctx *
261 ctx_alloc (void)
263 struct gimplify_ctx * c = ctx_pool;
265 if (c)
266 ctx_pool = c->prev_context;
267 else
268 c = XNEW (struct gimplify_ctx);
270 memset (c, '\0', sizeof (*c));
271 return c;
274 /* Put gimplify context C back into the pool. */
276 static inline void
277 ctx_free (struct gimplify_ctx *c)
279 c->prev_context = ctx_pool;
280 ctx_pool = c;
283 /* Free allocated ctx stack memory. */
285 void
286 free_gimplify_stack (void)
288 struct gimplify_ctx *c;
290 while ((c = ctx_pool))
292 ctx_pool = c->prev_context;
293 free (c);
298 /* Set up a context for the gimplifier. */
300 void
301 push_gimplify_context (bool in_ssa, bool rhs_cond_ok)
303 struct gimplify_ctx *c = ctx_alloc ();
305 c->prev_context = gimplify_ctxp;
306 gimplify_ctxp = c;
307 gimplify_ctxp->into_ssa = in_ssa;
308 gimplify_ctxp->allow_rhs_cond_expr = rhs_cond_ok;
311 /* Tear down a context for the gimplifier. If BODY is non-null, then
312 put the temporaries into the outer BIND_EXPR. Otherwise, put them
313 in the local_decls.
315 BODY is not a sequence, but the first tuple in a sequence. */
317 void
318 pop_gimplify_context (gimple *body)
320 struct gimplify_ctx *c = gimplify_ctxp;
322 gcc_assert (c
323 && (!c->bind_expr_stack.exists ()
324 || c->bind_expr_stack.is_empty ()));
325 c->bind_expr_stack.release ();
326 gimplify_ctxp = c->prev_context;
328 if (body)
329 declare_vars (c->temps, body, false);
330 else
331 record_vars (c->temps);
333 delete c->temp_htab;
334 c->temp_htab = NULL;
335 ctx_free (c);
338 /* Push a GIMPLE_BIND tuple onto the stack of bindings. */
340 static void
341 gimple_push_bind_expr (gbind *bind_stmt)
343 gimplify_ctxp->bind_expr_stack.reserve (8);
344 gimplify_ctxp->bind_expr_stack.safe_push (bind_stmt);
347 /* Pop the first element off the stack of bindings. */
349 static void
350 gimple_pop_bind_expr (void)
352 gimplify_ctxp->bind_expr_stack.pop ();
355 /* Return the first element of the stack of bindings. */
357 gbind *
358 gimple_current_bind_expr (void)
360 return gimplify_ctxp->bind_expr_stack.last ();
363 /* Return the stack of bindings created during gimplification. */
365 vec<gbind *>
366 gimple_bind_expr_stack (void)
368 return gimplify_ctxp->bind_expr_stack;
371 /* Return true iff there is a COND_EXPR between us and the innermost
372 CLEANUP_POINT_EXPR. This info is used by gimple_push_cleanup. */
374 static bool
375 gimple_conditional_context (void)
377 return gimplify_ctxp->conditions > 0;
380 /* Note that we've entered a COND_EXPR. */
382 static void
383 gimple_push_condition (void)
385 #ifdef ENABLE_GIMPLE_CHECKING
386 if (gimplify_ctxp->conditions == 0)
387 gcc_assert (gimple_seq_empty_p (gimplify_ctxp->conditional_cleanups));
388 #endif
389 ++(gimplify_ctxp->conditions);
392 /* Note that we've left a COND_EXPR. If we're back at unconditional scope
393 now, add any conditional cleanups we've seen to the prequeue. */
395 static void
396 gimple_pop_condition (gimple_seq *pre_p)
398 int conds = --(gimplify_ctxp->conditions);
400 gcc_assert (conds >= 0);
401 if (conds == 0)
403 gimplify_seq_add_seq (pre_p, gimplify_ctxp->conditional_cleanups);
404 gimplify_ctxp->conditional_cleanups = NULL;
408 /* A stable comparison routine for use with splay trees and DECLs. */
410 static int
411 splay_tree_compare_decl_uid (splay_tree_key xa, splay_tree_key xb)
413 tree a = (tree) xa;
414 tree b = (tree) xb;
416 return DECL_UID (a) - DECL_UID (b);
419 /* Create a new omp construct that deals with variable remapping. */
421 static struct gimplify_omp_ctx *
422 new_omp_context (enum omp_region_type region_type)
424 struct gimplify_omp_ctx *c;
426 c = XCNEW (struct gimplify_omp_ctx);
427 c->outer_context = gimplify_omp_ctxp;
428 c->variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0);
429 c->privatized_types = new hash_set<tree>;
430 c->location = input_location;
431 c->region_type = region_type;
432 if ((region_type & ORT_TASK) == 0)
433 c->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
434 else
435 c->default_kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
436 c->defaultmap[GDMK_SCALAR] = GOVD_MAP;
437 c->defaultmap[GDMK_AGGREGATE] = GOVD_MAP;
438 c->defaultmap[GDMK_ALLOCATABLE] = GOVD_MAP;
439 c->defaultmap[GDMK_POINTER] = GOVD_MAP;
441 return c;
444 /* Destroy an omp construct that deals with variable remapping. */
446 static void
447 delete_omp_context (struct gimplify_omp_ctx *c)
449 splay_tree_delete (c->variables);
450 delete c->privatized_types;
451 c->loop_iter_var.release ();
452 XDELETE (c);
455 static void omp_add_variable (struct gimplify_omp_ctx *, tree, unsigned int);
456 static bool omp_notice_variable (struct gimplify_omp_ctx *, tree, bool);
458 /* Both gimplify the statement T and append it to *SEQ_P. This function
459 behaves exactly as gimplify_stmt, but you don't have to pass T as a
460 reference. */
462 void
463 gimplify_and_add (tree t, gimple_seq *seq_p)
465 gimplify_stmt (&t, seq_p);
468 /* Gimplify statement T into sequence *SEQ_P, and return the first
469 tuple in the sequence of generated tuples for this statement.
470 Return NULL if gimplifying T produced no tuples. */
472 static gimple *
473 gimplify_and_return_first (tree t, gimple_seq *seq_p)
475 gimple_stmt_iterator last = gsi_last (*seq_p);
477 gimplify_and_add (t, seq_p);
479 if (!gsi_end_p (last))
481 gsi_next (&last);
482 return gsi_stmt (last);
484 else
485 return gimple_seq_first_stmt (*seq_p);
488 /* Returns true iff T is a valid RHS for an assignment to an un-renamed
489 LHS, or for a call argument. */
491 static bool
492 is_gimple_mem_rhs (tree t)
494 /* If we're dealing with a renamable type, either source or dest must be
495 a renamed variable. */
496 if (is_gimple_reg_type (TREE_TYPE (t)))
497 return is_gimple_val (t);
498 else
499 return is_gimple_val (t) || is_gimple_lvalue (t);
502 /* Return true if T is a CALL_EXPR or an expression that can be
503 assigned to a temporary. Note that this predicate should only be
504 used during gimplification. See the rationale for this in
505 gimplify_modify_expr. */
507 static bool
508 is_gimple_reg_rhs_or_call (tree t)
510 return (get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS
511 || TREE_CODE (t) == CALL_EXPR);
514 /* Return true if T is a valid memory RHS or a CALL_EXPR. Note that
515 this predicate should only be used during gimplification. See the
516 rationale for this in gimplify_modify_expr. */
518 static bool
519 is_gimple_mem_rhs_or_call (tree t)
521 /* If we're dealing with a renamable type, either source or dest must be
522 a renamed variable. */
523 if (is_gimple_reg_type (TREE_TYPE (t)))
524 return is_gimple_val (t);
525 else
526 return (is_gimple_val (t)
527 || is_gimple_lvalue (t)
528 || TREE_CLOBBER_P (t)
529 || TREE_CODE (t) == CALL_EXPR);
532 /* Create a temporary with a name derived from VAL. Subroutine of
533 lookup_tmp_var; nobody else should call this function. */
535 static inline tree
536 create_tmp_from_val (tree val)
538 /* Drop all qualifiers and address-space information from the value type. */
539 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (val));
540 tree var = create_tmp_var (type, get_name (val));
541 if (TREE_CODE (TREE_TYPE (var)) == COMPLEX_TYPE
542 || TREE_CODE (TREE_TYPE (var)) == VECTOR_TYPE)
543 DECL_GIMPLE_REG_P (var) = 1;
544 return var;
547 /* Create a temporary to hold the value of VAL. If IS_FORMAL, try to reuse
548 an existing expression temporary. */
550 static tree
551 lookup_tmp_var (tree val, bool is_formal)
553 tree ret;
555 /* If not optimizing, never really reuse a temporary. local-alloc
556 won't allocate any variable that is used in more than one basic
557 block, which means it will go into memory, causing much extra
558 work in reload and final and poorer code generation, outweighing
559 the extra memory allocation here. */
560 if (!optimize || !is_formal || TREE_SIDE_EFFECTS (val))
561 ret = create_tmp_from_val (val);
562 else
564 elt_t elt, *elt_p;
565 elt_t **slot;
567 elt.val = val;
568 if (!gimplify_ctxp->temp_htab)
569 gimplify_ctxp->temp_htab = new hash_table<gimplify_hasher> (1000);
570 slot = gimplify_ctxp->temp_htab->find_slot (&elt, INSERT);
571 if (*slot == NULL)
573 elt_p = XNEW (elt_t);
574 elt_p->val = val;
575 elt_p->temp = ret = create_tmp_from_val (val);
576 *slot = elt_p;
578 else
580 elt_p = *slot;
581 ret = elt_p->temp;
585 return ret;
588 /* Helper for get_formal_tmp_var and get_initialized_tmp_var. */
590 static tree
591 internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
592 bool is_formal, bool allow_ssa)
594 tree t, mod;
596 /* Notice that we explicitly allow VAL to be a CALL_EXPR so that we
597 can create an INIT_EXPR and convert it into a GIMPLE_CALL below. */
598 gimplify_expr (&val, pre_p, post_p, is_gimple_reg_rhs_or_call,
599 fb_rvalue);
601 if (allow_ssa
602 && gimplify_ctxp->into_ssa
603 && is_gimple_reg_type (TREE_TYPE (val)))
605 t = make_ssa_name (TYPE_MAIN_VARIANT (TREE_TYPE (val)));
606 if (! gimple_in_ssa_p (cfun))
608 const char *name = get_name (val);
609 if (name)
610 SET_SSA_NAME_VAR_OR_IDENTIFIER (t, create_tmp_var_name (name));
613 else
614 t = lookup_tmp_var (val, is_formal);
616 mod = build2 (INIT_EXPR, TREE_TYPE (t), t, unshare_expr (val));
618 SET_EXPR_LOCATION (mod, EXPR_LOC_OR_LOC (val, input_location));
620 /* gimplify_modify_expr might want to reduce this further. */
621 gimplify_and_add (mod, pre_p);
622 ggc_free (mod);
624 return t;
627 /* Return a formal temporary variable initialized with VAL. PRE_P is as
628 in gimplify_expr. Only use this function if:
630 1) The value of the unfactored expression represented by VAL will not
631 change between the initialization and use of the temporary, and
632 2) The temporary will not be otherwise modified.
634 For instance, #1 means that this is inappropriate for SAVE_EXPR temps,
635 and #2 means it is inappropriate for && temps.
637 For other cases, use get_initialized_tmp_var instead. */
639 tree
640 get_formal_tmp_var (tree val, gimple_seq *pre_p)
642 return internal_get_tmp_var (val, pre_p, NULL, true, true);
645 /* Return a temporary variable initialized with VAL. PRE_P and POST_P
646 are as in gimplify_expr. */
648 tree
649 get_initialized_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
650 bool allow_ssa)
652 return internal_get_tmp_var (val, pre_p, post_p, false, allow_ssa);
655 /* Declare all the variables in VARS in SCOPE. If DEBUG_INFO is true,
656 generate debug info for them; otherwise don't. */
658 void
659 declare_vars (tree vars, gimple *gs, bool debug_info)
661 tree last = vars;
662 if (last)
664 tree temps, block;
666 gbind *scope = as_a <gbind *> (gs);
668 temps = nreverse (last);
670 block = gimple_bind_block (scope);
671 gcc_assert (!block || TREE_CODE (block) == BLOCK);
672 if (!block || !debug_info)
674 DECL_CHAIN (last) = gimple_bind_vars (scope);
675 gimple_bind_set_vars (scope, temps);
677 else
679 /* We need to attach the nodes both to the BIND_EXPR and to its
680 associated BLOCK for debugging purposes. The key point here
681 is that the BLOCK_VARS of the BIND_EXPR_BLOCK of a BIND_EXPR
682 is a subchain of the BIND_EXPR_VARS of the BIND_EXPR. */
683 if (BLOCK_VARS (block))
684 BLOCK_VARS (block) = chainon (BLOCK_VARS (block), temps);
685 else
687 gimple_bind_set_vars (scope,
688 chainon (gimple_bind_vars (scope), temps));
689 BLOCK_VARS (block) = temps;
695 /* For VAR a VAR_DECL of variable size, try to find a constant upper bound
696 for the size and adjust DECL_SIZE/DECL_SIZE_UNIT accordingly. Abort if
697 no such upper bound can be obtained. */
699 static void
700 force_constant_size (tree var)
702 /* The only attempt we make is by querying the maximum size of objects
703 of the variable's type. */
705 HOST_WIDE_INT max_size;
707 gcc_assert (VAR_P (var));
709 max_size = max_int_size_in_bytes (TREE_TYPE (var));
711 gcc_assert (max_size >= 0);
713 DECL_SIZE_UNIT (var)
714 = build_int_cst (TREE_TYPE (DECL_SIZE_UNIT (var)), max_size);
715 DECL_SIZE (var)
716 = build_int_cst (TREE_TYPE (DECL_SIZE (var)), max_size * BITS_PER_UNIT);
719 /* Push the temporary variable TMP into the current binding. */
721 void
722 gimple_add_tmp_var_fn (struct function *fn, tree tmp)
724 gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
726 /* Later processing assumes that the object size is constant, which might
727 not be true at this point. Force the use of a constant upper bound in
728 this case. */
729 if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp)))
730 force_constant_size (tmp);
732 DECL_CONTEXT (tmp) = fn->decl;
733 DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
735 record_vars_into (tmp, fn->decl);
738 /* Push the temporary variable TMP into the current binding. */
740 void
741 gimple_add_tmp_var (tree tmp)
743 gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
745 /* Later processing assumes that the object size is constant, which might
746 not be true at this point. Force the use of a constant upper bound in
747 this case. */
748 if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp)))
749 force_constant_size (tmp);
751 DECL_CONTEXT (tmp) = current_function_decl;
752 DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
754 if (gimplify_ctxp)
756 DECL_CHAIN (tmp) = gimplify_ctxp->temps;
757 gimplify_ctxp->temps = tmp;
759 /* Mark temporaries local within the nearest enclosing parallel. */
760 if (gimplify_omp_ctxp)
762 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
763 while (ctx
764 && (ctx->region_type == ORT_WORKSHARE
765 || ctx->region_type == ORT_TASKGROUP
766 || ctx->region_type == ORT_SIMD
767 || ctx->region_type == ORT_ACC))
768 ctx = ctx->outer_context;
769 if (ctx)
770 omp_add_variable (ctx, tmp, GOVD_LOCAL | GOVD_SEEN);
773 else if (cfun)
774 record_vars (tmp);
775 else
777 gimple_seq body_seq;
779 /* This case is for nested functions. We need to expose the locals
780 they create. */
781 body_seq = gimple_body (current_function_decl);
782 declare_vars (tmp, gimple_seq_first_stmt (body_seq), false);
788 /* This page contains routines to unshare tree nodes, i.e. to duplicate tree
789 nodes that are referenced more than once in GENERIC functions. This is
790 necessary because gimplification (translation into GIMPLE) is performed
791 by modifying tree nodes in-place, so gimplication of a shared node in a
792 first context could generate an invalid GIMPLE form in a second context.
794 This is achieved with a simple mark/copy/unmark algorithm that walks the
795 GENERIC representation top-down, marks nodes with TREE_VISITED the first
796 time it encounters them, duplicates them if they already have TREE_VISITED
797 set, and finally removes the TREE_VISITED marks it has set.
799 The algorithm works only at the function level, i.e. it generates a GENERIC
800 representation of a function with no nodes shared within the function when
801 passed a GENERIC function (except for nodes that are allowed to be shared).
803 At the global level, it is also necessary to unshare tree nodes that are
804 referenced in more than one function, for the same aforementioned reason.
805 This requires some cooperation from the front-end. There are 2 strategies:
807 1. Manual unsharing. The front-end needs to call unshare_expr on every
808 expression that might end up being shared across functions.
810 2. Deep unsharing. This is an extension of regular unsharing. Instead
811 of calling unshare_expr on expressions that might be shared across
812 functions, the front-end pre-marks them with TREE_VISITED. This will
813 ensure that they are unshared on the first reference within functions
814 when the regular unsharing algorithm runs. The counterpart is that
815 this algorithm must look deeper than for manual unsharing, which is
816 specified by LANG_HOOKS_DEEP_UNSHARING.
818 If there are only few specific cases of node sharing across functions, it is
819 probably easier for a front-end to unshare the expressions manually. On the
820 contrary, if the expressions generated at the global level are as widespread
821 as expressions generated within functions, deep unsharing is very likely the
822 way to go. */
824 /* Similar to copy_tree_r but do not copy SAVE_EXPR or TARGET_EXPR nodes.
825 These nodes model computations that must be done once. If we were to
826 unshare something like SAVE_EXPR(i++), the gimplification process would
827 create wrong code. However, if DATA is non-null, it must hold a pointer
828 set that is used to unshare the subtrees of these nodes. */
830 static tree
831 mostly_copy_tree_r (tree *tp, int *walk_subtrees, void *data)
833 tree t = *tp;
834 enum tree_code code = TREE_CODE (t);
836 /* Do not copy SAVE_EXPR, TARGET_EXPR or BIND_EXPR nodes themselves, but
837 copy their subtrees if we can make sure to do it only once. */
838 if (code == SAVE_EXPR || code == TARGET_EXPR || code == BIND_EXPR)
840 if (data && !((hash_set<tree> *)data)->add (t))
842 else
843 *walk_subtrees = 0;
846 /* Stop at types, decls, constants like copy_tree_r. */
847 else if (TREE_CODE_CLASS (code) == tcc_type
848 || TREE_CODE_CLASS (code) == tcc_declaration
849 || TREE_CODE_CLASS (code) == tcc_constant)
850 *walk_subtrees = 0;
852 /* Cope with the statement expression extension. */
853 else if (code == STATEMENT_LIST)
856 /* Leave the bulk of the work to copy_tree_r itself. */
857 else
858 copy_tree_r (tp, walk_subtrees, NULL);
860 return NULL_TREE;
863 /* Callback for walk_tree to unshare most of the shared trees rooted at *TP.
864 If *TP has been visited already, then *TP is deeply copied by calling
865 mostly_copy_tree_r. DATA is passed to mostly_copy_tree_r unmodified. */
867 static tree
868 copy_if_shared_r (tree *tp, int *walk_subtrees, void *data)
870 tree t = *tp;
871 enum tree_code code = TREE_CODE (t);
873 /* Skip types, decls, and constants. But we do want to look at their
874 types and the bounds of types. Mark them as visited so we properly
875 unmark their subtrees on the unmark pass. If we've already seen them,
876 don't look down further. */
877 if (TREE_CODE_CLASS (code) == tcc_type
878 || TREE_CODE_CLASS (code) == tcc_declaration
879 || TREE_CODE_CLASS (code) == tcc_constant)
881 if (TREE_VISITED (t))
882 *walk_subtrees = 0;
883 else
884 TREE_VISITED (t) = 1;
887 /* If this node has been visited already, unshare it and don't look
888 any deeper. */
889 else if (TREE_VISITED (t))
891 walk_tree (tp, mostly_copy_tree_r, data, NULL);
892 *walk_subtrees = 0;
895 /* Otherwise, mark the node as visited and keep looking. */
896 else
897 TREE_VISITED (t) = 1;
899 return NULL_TREE;
902 /* Unshare most of the shared trees rooted at *TP. DATA is passed to the
903 copy_if_shared_r callback unmodified. */
905 static inline void
906 copy_if_shared (tree *tp, void *data)
908 walk_tree (tp, copy_if_shared_r, data, NULL);
911 /* Unshare all the trees in the body of FNDECL, as well as in the bodies of
912 any nested functions. */
914 static void
915 unshare_body (tree fndecl)
917 struct cgraph_node *cgn = cgraph_node::get (fndecl);
918 /* If the language requires deep unsharing, we need a pointer set to make
919 sure we don't repeatedly unshare subtrees of unshareable nodes. */
920 hash_set<tree> *visited
921 = lang_hooks.deep_unsharing ? new hash_set<tree> : NULL;
923 copy_if_shared (&DECL_SAVED_TREE (fndecl), visited);
924 copy_if_shared (&DECL_SIZE (DECL_RESULT (fndecl)), visited);
925 copy_if_shared (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)), visited);
927 delete visited;
929 if (cgn)
930 for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
931 unshare_body (cgn->decl);
934 /* Callback for walk_tree to unmark the visited trees rooted at *TP.
935 Subtrees are walked until the first unvisited node is encountered. */
937 static tree
938 unmark_visited_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
940 tree t = *tp;
942 /* If this node has been visited, unmark it and keep looking. */
943 if (TREE_VISITED (t))
944 TREE_VISITED (t) = 0;
946 /* Otherwise, don't look any deeper. */
947 else
948 *walk_subtrees = 0;
950 return NULL_TREE;
953 /* Unmark the visited trees rooted at *TP. */
955 static inline void
956 unmark_visited (tree *tp)
958 walk_tree (tp, unmark_visited_r, NULL, NULL);
961 /* Likewise, but mark all trees as not visited. */
963 static void
964 unvisit_body (tree fndecl)
966 struct cgraph_node *cgn = cgraph_node::get (fndecl);
968 unmark_visited (&DECL_SAVED_TREE (fndecl));
969 unmark_visited (&DECL_SIZE (DECL_RESULT (fndecl)));
970 unmark_visited (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)));
972 if (cgn)
973 for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
974 unvisit_body (cgn->decl);
977 /* Unconditionally make an unshared copy of EXPR. This is used when using
978 stored expressions which span multiple functions, such as BINFO_VTABLE,
979 as the normal unsharing process can't tell that they're shared. */
981 tree
982 unshare_expr (tree expr)
984 walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
985 return expr;
988 /* Worker for unshare_expr_without_location. */
990 static tree
991 prune_expr_location (tree *tp, int *walk_subtrees, void *)
993 if (EXPR_P (*tp))
994 SET_EXPR_LOCATION (*tp, UNKNOWN_LOCATION);
995 else
996 *walk_subtrees = 0;
997 return NULL_TREE;
1000 /* Similar to unshare_expr but also prune all expression locations
1001 from EXPR. */
1003 tree
1004 unshare_expr_without_location (tree expr)
1006 walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
1007 if (EXPR_P (expr))
1008 walk_tree (&expr, prune_expr_location, NULL, NULL);
1009 return expr;
1012 /* Return the EXPR_LOCATION of EXPR, if it (maybe recursively) has
1013 one, OR_ELSE otherwise. The location of a STATEMENT_LISTs
1014 comprising at least one DEBUG_BEGIN_STMT followed by exactly one
1015 EXPR is the location of the EXPR. */
1017 static location_t
1018 rexpr_location (tree expr, location_t or_else = UNKNOWN_LOCATION)
1020 if (!expr)
1021 return or_else;
1023 if (EXPR_HAS_LOCATION (expr))
1024 return EXPR_LOCATION (expr);
1026 if (TREE_CODE (expr) != STATEMENT_LIST)
1027 return or_else;
1029 tree_stmt_iterator i = tsi_start (expr);
1031 bool found = false;
1032 while (!tsi_end_p (i) && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT)
1034 found = true;
1035 tsi_next (&i);
1038 if (!found || !tsi_one_before_end_p (i))
1039 return or_else;
1041 return rexpr_location (tsi_stmt (i), or_else);
1044 /* Return TRUE iff EXPR (maybe recursively) has a location; see
1045 rexpr_location for the potential recursion. */
1047 static inline bool
1048 rexpr_has_location (tree expr)
1050 return rexpr_location (expr) != UNKNOWN_LOCATION;
1054 /* WRAPPER is a code such as BIND_EXPR or CLEANUP_POINT_EXPR which can both
1055 contain statements and have a value. Assign its value to a temporary
1056 and give it void_type_node. Return the temporary, or NULL_TREE if
1057 WRAPPER was already void. */
1059 tree
1060 voidify_wrapper_expr (tree wrapper, tree temp)
1062 tree type = TREE_TYPE (wrapper);
1063 if (type && !VOID_TYPE_P (type))
1065 tree *p;
1067 /* Set p to point to the body of the wrapper. Loop until we find
1068 something that isn't a wrapper. */
1069 for (p = &wrapper; p && *p; )
1071 switch (TREE_CODE (*p))
1073 case BIND_EXPR:
1074 TREE_SIDE_EFFECTS (*p) = 1;
1075 TREE_TYPE (*p) = void_type_node;
1076 /* For a BIND_EXPR, the body is operand 1. */
1077 p = &BIND_EXPR_BODY (*p);
1078 break;
1080 case CLEANUP_POINT_EXPR:
1081 case TRY_FINALLY_EXPR:
1082 case TRY_CATCH_EXPR:
1083 TREE_SIDE_EFFECTS (*p) = 1;
1084 TREE_TYPE (*p) = void_type_node;
1085 p = &TREE_OPERAND (*p, 0);
1086 break;
1088 case STATEMENT_LIST:
1090 tree_stmt_iterator i = tsi_last (*p);
1091 TREE_SIDE_EFFECTS (*p) = 1;
1092 TREE_TYPE (*p) = void_type_node;
1093 p = tsi_end_p (i) ? NULL : tsi_stmt_ptr (i);
1095 break;
1097 case COMPOUND_EXPR:
1098 /* Advance to the last statement. Set all container types to
1099 void. */
1100 for (; TREE_CODE (*p) == COMPOUND_EXPR; p = &TREE_OPERAND (*p, 1))
1102 TREE_SIDE_EFFECTS (*p) = 1;
1103 TREE_TYPE (*p) = void_type_node;
1105 break;
1107 case TRANSACTION_EXPR:
1108 TREE_SIDE_EFFECTS (*p) = 1;
1109 TREE_TYPE (*p) = void_type_node;
1110 p = &TRANSACTION_EXPR_BODY (*p);
1111 break;
1113 default:
1114 /* Assume that any tree upon which voidify_wrapper_expr is
1115 directly called is a wrapper, and that its body is op0. */
1116 if (p == &wrapper)
1118 TREE_SIDE_EFFECTS (*p) = 1;
1119 TREE_TYPE (*p) = void_type_node;
1120 p = &TREE_OPERAND (*p, 0);
1121 break;
1123 goto out;
1127 out:
1128 if (p == NULL || IS_EMPTY_STMT (*p))
1129 temp = NULL_TREE;
1130 else if (temp)
1132 /* The wrapper is on the RHS of an assignment that we're pushing
1133 down. */
1134 gcc_assert (TREE_CODE (temp) == INIT_EXPR
1135 || TREE_CODE (temp) == MODIFY_EXPR);
1136 TREE_OPERAND (temp, 1) = *p;
1137 *p = temp;
1139 else
1141 temp = create_tmp_var (type, "retval");
1142 *p = build2 (INIT_EXPR, type, temp, *p);
1145 return temp;
1148 return NULL_TREE;
1151 /* Prepare calls to builtins to SAVE and RESTORE the stack as well as
1152 a temporary through which they communicate. */
1154 static void
1155 build_stack_save_restore (gcall **save, gcall **restore)
1157 tree tmp_var;
1159 *save = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_SAVE), 0);
1160 tmp_var = create_tmp_var (ptr_type_node, "saved_stack");
1161 gimple_call_set_lhs (*save, tmp_var);
1163 *restore
1164 = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_RESTORE),
1165 1, tmp_var);
1168 /* Generate IFN_ASAN_MARK call that poisons shadow of a for DECL variable. */
1170 static tree
1171 build_asan_poison_call_expr (tree decl)
1173 /* Do not poison variables that have size equal to zero. */
1174 tree unit_size = DECL_SIZE_UNIT (decl);
1175 if (zerop (unit_size))
1176 return NULL_TREE;
1178 tree base = build_fold_addr_expr (decl);
1180 return build_call_expr_internal_loc (UNKNOWN_LOCATION, IFN_ASAN_MARK,
1181 void_type_node, 3,
1182 build_int_cst (integer_type_node,
1183 ASAN_MARK_POISON),
1184 base, unit_size);
1187 /* Generate IFN_ASAN_MARK call that would poison or unpoison, depending
1188 on POISON flag, shadow memory of a DECL variable. The call will be
1189 put on location identified by IT iterator, where BEFORE flag drives
1190 position where the stmt will be put. */
1192 static void
1193 asan_poison_variable (tree decl, bool poison, gimple_stmt_iterator *it,
1194 bool before)
1196 tree unit_size = DECL_SIZE_UNIT (decl);
1197 tree base = build_fold_addr_expr (decl);
1199 /* Do not poison variables that have size equal to zero. */
1200 if (zerop (unit_size))
1201 return;
1203 /* It's necessary to have all stack variables aligned to ASAN granularity
1204 bytes. */
1205 if (DECL_ALIGN_UNIT (decl) <= ASAN_SHADOW_GRANULARITY)
1206 SET_DECL_ALIGN (decl, BITS_PER_UNIT * ASAN_SHADOW_GRANULARITY);
1208 HOST_WIDE_INT flags = poison ? ASAN_MARK_POISON : ASAN_MARK_UNPOISON;
1210 gimple *g
1211 = gimple_build_call_internal (IFN_ASAN_MARK, 3,
1212 build_int_cst (integer_type_node, flags),
1213 base, unit_size);
1215 if (before)
1216 gsi_insert_before (it, g, GSI_NEW_STMT);
1217 else
1218 gsi_insert_after (it, g, GSI_NEW_STMT);
1221 /* Generate IFN_ASAN_MARK internal call that depending on POISON flag
1222 either poisons or unpoisons a DECL. Created statement is appended
1223 to SEQ_P gimple sequence. */
1225 static void
1226 asan_poison_variable (tree decl, bool poison, gimple_seq *seq_p)
1228 gimple_stmt_iterator it = gsi_last (*seq_p);
1229 bool before = false;
1231 if (gsi_end_p (it))
1232 before = true;
1234 asan_poison_variable (decl, poison, &it, before);
1237 /* Sort pair of VAR_DECLs A and B by DECL_UID. */
1239 static int
1240 sort_by_decl_uid (const void *a, const void *b)
1242 const tree *t1 = (const tree *)a;
1243 const tree *t2 = (const tree *)b;
1245 int uid1 = DECL_UID (*t1);
1246 int uid2 = DECL_UID (*t2);
1248 if (uid1 < uid2)
1249 return -1;
1250 else if (uid1 > uid2)
1251 return 1;
1252 else
1253 return 0;
1256 /* Generate IFN_ASAN_MARK internal call for all VARIABLES
1257 depending on POISON flag. Created statement is appended
1258 to SEQ_P gimple sequence. */
1260 static void
1261 asan_poison_variables (hash_set<tree> *variables, bool poison, gimple_seq *seq_p)
1263 unsigned c = variables->elements ();
1264 if (c == 0)
1265 return;
1267 auto_vec<tree> sorted_variables (c);
1269 for (hash_set<tree>::iterator it = variables->begin ();
1270 it != variables->end (); ++it)
1271 sorted_variables.safe_push (*it);
1273 sorted_variables.qsort (sort_by_decl_uid);
1275 unsigned i;
1276 tree var;
1277 FOR_EACH_VEC_ELT (sorted_variables, i, var)
1279 asan_poison_variable (var, poison, seq_p);
1281 /* Add use_after_scope_memory attribute for the variable in order
1282 to prevent re-written into SSA. */
1283 if (!lookup_attribute (ASAN_USE_AFTER_SCOPE_ATTRIBUTE,
1284 DECL_ATTRIBUTES (var)))
1285 DECL_ATTRIBUTES (var)
1286 = tree_cons (get_identifier (ASAN_USE_AFTER_SCOPE_ATTRIBUTE),
1287 integer_one_node,
1288 DECL_ATTRIBUTES (var));
1292 /* Gimplify a BIND_EXPR. Just voidify and recurse. */
1294 static enum gimplify_status
1295 gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p)
1297 tree bind_expr = *expr_p;
1298 bool old_keep_stack = gimplify_ctxp->keep_stack;
1299 bool old_save_stack = gimplify_ctxp->save_stack;
1300 tree t;
1301 gbind *bind_stmt;
1302 gimple_seq body, cleanup;
1303 gcall *stack_save;
1304 location_t start_locus = 0, end_locus = 0;
1305 tree ret_clauses = NULL;
1307 tree temp = voidify_wrapper_expr (bind_expr, NULL);
1309 /* Mark variables seen in this bind expr. */
1310 for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t))
1312 if (VAR_P (t))
1314 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
1316 /* Mark variable as local. */
1317 if (ctx && ctx->region_type != ORT_NONE && !DECL_EXTERNAL (t)
1318 && (! DECL_SEEN_IN_BIND_EXPR_P (t)
1319 || splay_tree_lookup (ctx->variables,
1320 (splay_tree_key) t) == NULL))
1322 if (ctx->region_type == ORT_SIMD
1323 && TREE_ADDRESSABLE (t)
1324 && !TREE_STATIC (t))
1325 omp_add_variable (ctx, t, GOVD_PRIVATE | GOVD_SEEN);
1326 else
1327 omp_add_variable (ctx, t, GOVD_LOCAL | GOVD_SEEN);
1330 DECL_SEEN_IN_BIND_EXPR_P (t) = 1;
1332 if (DECL_HARD_REGISTER (t) && !is_global_var (t) && cfun)
1333 cfun->has_local_explicit_reg_vars = true;
1336 /* Preliminarily mark non-addressed complex variables as eligible
1337 for promotion to gimple registers. We'll transform their uses
1338 as we find them. */
1339 if ((TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE
1340 || TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
1341 && !TREE_THIS_VOLATILE (t)
1342 && (VAR_P (t) && !DECL_HARD_REGISTER (t))
1343 && !needs_to_live_in_memory (t))
1344 DECL_GIMPLE_REG_P (t) = 1;
1347 bind_stmt = gimple_build_bind (BIND_EXPR_VARS (bind_expr), NULL,
1348 BIND_EXPR_BLOCK (bind_expr));
1349 gimple_push_bind_expr (bind_stmt);
1351 gimplify_ctxp->keep_stack = false;
1352 gimplify_ctxp->save_stack = false;
1354 /* Gimplify the body into the GIMPLE_BIND tuple's body. */
1355 body = NULL;
1356 gimplify_stmt (&BIND_EXPR_BODY (bind_expr), &body);
1357 gimple_bind_set_body (bind_stmt, body);
1359 /* Source location wise, the cleanup code (stack_restore and clobbers)
1360 belongs to the end of the block, so propagate what we have. The
1361 stack_save operation belongs to the beginning of block, which we can
1362 infer from the bind_expr directly if the block has no explicit
1363 assignment. */
1364 if (BIND_EXPR_BLOCK (bind_expr))
1366 end_locus = BLOCK_SOURCE_END_LOCATION (BIND_EXPR_BLOCK (bind_expr));
1367 start_locus = BLOCK_SOURCE_LOCATION (BIND_EXPR_BLOCK (bind_expr));
1369 if (start_locus == 0)
1370 start_locus = EXPR_LOCATION (bind_expr);
1372 cleanup = NULL;
1373 stack_save = NULL;
1375 /* If the code both contains VLAs and calls alloca, then we cannot reclaim
1376 the stack space allocated to the VLAs. */
1377 if (gimplify_ctxp->save_stack && !gimplify_ctxp->keep_stack)
1379 gcall *stack_restore;
1381 /* Save stack on entry and restore it on exit. Add a try_finally
1382 block to achieve this. */
1383 build_stack_save_restore (&stack_save, &stack_restore);
1385 gimple_set_location (stack_save, start_locus);
1386 gimple_set_location (stack_restore, end_locus);
1388 gimplify_seq_add_stmt (&cleanup, stack_restore);
1391 /* Add clobbers for all variables that go out of scope. */
1392 for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t))
1394 if (VAR_P (t)
1395 && !is_global_var (t)
1396 && DECL_CONTEXT (t) == current_function_decl)
1398 if (!DECL_HARD_REGISTER (t)
1399 && !TREE_THIS_VOLATILE (t)
1400 && !DECL_HAS_VALUE_EXPR_P (t)
1401 /* Only care for variables that have to be in memory. Others
1402 will be rewritten into SSA names, hence moved to the
1403 top-level. */
1404 && !is_gimple_reg (t)
1405 && flag_stack_reuse != SR_NONE)
1407 tree clobber = build_clobber (TREE_TYPE (t));
1408 gimple *clobber_stmt;
1409 clobber_stmt = gimple_build_assign (t, clobber);
1410 gimple_set_location (clobber_stmt, end_locus);
1411 gimplify_seq_add_stmt (&cleanup, clobber_stmt);
1414 if (flag_openacc && oacc_declare_returns != NULL)
1416 tree *c = oacc_declare_returns->get (t);
1417 if (c != NULL)
1419 if (ret_clauses)
1420 OMP_CLAUSE_CHAIN (*c) = ret_clauses;
1422 ret_clauses = *c;
1424 oacc_declare_returns->remove (t);
1426 if (oacc_declare_returns->elements () == 0)
1428 delete oacc_declare_returns;
1429 oacc_declare_returns = NULL;
1435 if (asan_poisoned_variables != NULL
1436 && asan_poisoned_variables->contains (t))
1438 asan_poisoned_variables->remove (t);
1439 asan_poison_variable (t, true, &cleanup);
1442 if (gimplify_ctxp->live_switch_vars != NULL
1443 && gimplify_ctxp->live_switch_vars->contains (t))
1444 gimplify_ctxp->live_switch_vars->remove (t);
1447 if (ret_clauses)
1449 gomp_target *stmt;
1450 gimple_stmt_iterator si = gsi_start (cleanup);
1452 stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
1453 ret_clauses);
1454 gsi_insert_seq_before_without_update (&si, stmt, GSI_NEW_STMT);
1457 if (cleanup)
1459 gtry *gs;
1460 gimple_seq new_body;
1462 new_body = NULL;
1463 gs = gimple_build_try (gimple_bind_body (bind_stmt), cleanup,
1464 GIMPLE_TRY_FINALLY);
1466 if (stack_save)
1467 gimplify_seq_add_stmt (&new_body, stack_save);
1468 gimplify_seq_add_stmt (&new_body, gs);
1469 gimple_bind_set_body (bind_stmt, new_body);
1472 /* keep_stack propagates all the way up to the outermost BIND_EXPR. */
1473 if (!gimplify_ctxp->keep_stack)
1474 gimplify_ctxp->keep_stack = old_keep_stack;
1475 gimplify_ctxp->save_stack = old_save_stack;
1477 gimple_pop_bind_expr ();
1479 gimplify_seq_add_stmt (pre_p, bind_stmt);
1481 if (temp)
1483 *expr_p = temp;
1484 return GS_OK;
1487 *expr_p = NULL_TREE;
1488 return GS_ALL_DONE;
1491 /* Maybe add early return predict statement to PRE_P sequence. */
1493 static void
1494 maybe_add_early_return_predict_stmt (gimple_seq *pre_p)
1496 /* If we are not in a conditional context, add PREDICT statement. */
1497 if (gimple_conditional_context ())
1499 gimple *predict = gimple_build_predict (PRED_TREE_EARLY_RETURN,
1500 NOT_TAKEN);
1501 gimplify_seq_add_stmt (pre_p, predict);
1505 /* Gimplify a RETURN_EXPR. If the expression to be returned is not a
1506 GIMPLE value, it is assigned to a new temporary and the statement is
1507 re-written to return the temporary.
1509 PRE_P points to the sequence where side effects that must happen before
1510 STMT should be stored. */
1512 static enum gimplify_status
1513 gimplify_return_expr (tree stmt, gimple_seq *pre_p)
1515 greturn *ret;
1516 tree ret_expr = TREE_OPERAND (stmt, 0);
1517 tree result_decl, result;
1519 if (ret_expr == error_mark_node)
1520 return GS_ERROR;
1522 if (!ret_expr
1523 || TREE_CODE (ret_expr) == RESULT_DECL)
1525 maybe_add_early_return_predict_stmt (pre_p);
1526 greturn *ret = gimple_build_return (ret_expr);
1527 gimple_set_no_warning (ret, TREE_NO_WARNING (stmt));
1528 gimplify_seq_add_stmt (pre_p, ret);
1529 return GS_ALL_DONE;
1532 if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))))
1533 result_decl = NULL_TREE;
1534 else
1536 result_decl = TREE_OPERAND (ret_expr, 0);
1538 /* See through a return by reference. */
1539 if (TREE_CODE (result_decl) == INDIRECT_REF)
1540 result_decl = TREE_OPERAND (result_decl, 0);
1542 gcc_assert ((TREE_CODE (ret_expr) == MODIFY_EXPR
1543 || TREE_CODE (ret_expr) == INIT_EXPR)
1544 && TREE_CODE (result_decl) == RESULT_DECL);
1547 /* If aggregate_value_p is true, then we can return the bare RESULT_DECL.
1548 Recall that aggregate_value_p is FALSE for any aggregate type that is
1549 returned in registers. If we're returning values in registers, then
1550 we don't want to extend the lifetime of the RESULT_DECL, particularly
1551 across another call. In addition, for those aggregates for which
1552 hard_function_value generates a PARALLEL, we'll die during normal
1553 expansion of structure assignments; there's special code in expand_return
1554 to handle this case that does not exist in expand_expr. */
1555 if (!result_decl)
1556 result = NULL_TREE;
1557 else if (aggregate_value_p (result_decl, TREE_TYPE (current_function_decl)))
1559 if (TREE_CODE (DECL_SIZE (result_decl)) != INTEGER_CST)
1561 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (result_decl)))
1562 gimplify_type_sizes (TREE_TYPE (result_decl), pre_p);
1563 /* Note that we don't use gimplify_vla_decl because the RESULT_DECL
1564 should be effectively allocated by the caller, i.e. all calls to
1565 this function must be subject to the Return Slot Optimization. */
1566 gimplify_one_sizepos (&DECL_SIZE (result_decl), pre_p);
1567 gimplify_one_sizepos (&DECL_SIZE_UNIT (result_decl), pre_p);
1569 result = result_decl;
1571 else if (gimplify_ctxp->return_temp)
1572 result = gimplify_ctxp->return_temp;
1573 else
1575 result = create_tmp_reg (TREE_TYPE (result_decl));
1577 /* ??? With complex control flow (usually involving abnormal edges),
1578 we can wind up warning about an uninitialized value for this. Due
1579 to how this variable is constructed and initialized, this is never
1580 true. Give up and never warn. */
1581 TREE_NO_WARNING (result) = 1;
1583 gimplify_ctxp->return_temp = result;
1586 /* Smash the lhs of the MODIFY_EXPR to the temporary we plan to use.
1587 Then gimplify the whole thing. */
1588 if (result != result_decl)
1589 TREE_OPERAND (ret_expr, 0) = result;
1591 gimplify_and_add (TREE_OPERAND (stmt, 0), pre_p);
1593 maybe_add_early_return_predict_stmt (pre_p);
1594 ret = gimple_build_return (result);
1595 gimple_set_no_warning (ret, TREE_NO_WARNING (stmt));
1596 gimplify_seq_add_stmt (pre_p, ret);
1598 return GS_ALL_DONE;
1601 /* Gimplify a variable-length array DECL. */
1603 static void
1604 gimplify_vla_decl (tree decl, gimple_seq *seq_p)
1606 /* This is a variable-sized decl. Simplify its size and mark it
1607 for deferred expansion. */
1608 tree t, addr, ptr_type;
1610 gimplify_one_sizepos (&DECL_SIZE (decl), seq_p);
1611 gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), seq_p);
1613 /* Don't mess with a DECL_VALUE_EXPR set by the front-end. */
1614 if (DECL_HAS_VALUE_EXPR_P (decl))
1615 return;
1617 /* All occurrences of this decl in final gimplified code will be
1618 replaced by indirection. Setting DECL_VALUE_EXPR does two
1619 things: First, it lets the rest of the gimplifier know what
1620 replacement to use. Second, it lets the debug info know
1621 where to find the value. */
1622 ptr_type = build_pointer_type (TREE_TYPE (decl));
1623 addr = create_tmp_var (ptr_type, get_name (decl));
1624 DECL_IGNORED_P (addr) = 0;
1625 t = build_fold_indirect_ref (addr);
1626 TREE_THIS_NOTRAP (t) = 1;
1627 SET_DECL_VALUE_EXPR (decl, t);
1628 DECL_HAS_VALUE_EXPR_P (decl) = 1;
1630 t = build_alloca_call_expr (DECL_SIZE_UNIT (decl), DECL_ALIGN (decl),
1631 max_int_size_in_bytes (TREE_TYPE (decl)));
1632 /* The call has been built for a variable-sized object. */
1633 CALL_ALLOCA_FOR_VAR_P (t) = 1;
1634 t = fold_convert (ptr_type, t);
1635 t = build2 (MODIFY_EXPR, TREE_TYPE (addr), addr, t);
1637 gimplify_and_add (t, seq_p);
1640 /* A helper function to be called via walk_tree. Mark all labels under *TP
1641 as being forced. To be called for DECL_INITIAL of static variables. */
1643 static tree
1644 force_labels_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
1646 if (TYPE_P (*tp))
1647 *walk_subtrees = 0;
1648 if (TREE_CODE (*tp) == LABEL_DECL)
1650 FORCED_LABEL (*tp) = 1;
1651 cfun->has_forced_label_in_static = 1;
1654 return NULL_TREE;
1657 /* Gimplify a DECL_EXPR node *STMT_P by making any necessary allocation
1658 and initialization explicit. */
1660 static enum gimplify_status
1661 gimplify_decl_expr (tree *stmt_p, gimple_seq *seq_p)
1663 tree stmt = *stmt_p;
1664 tree decl = DECL_EXPR_DECL (stmt);
1666 *stmt_p = NULL_TREE;
1668 if (TREE_TYPE (decl) == error_mark_node)
1669 return GS_ERROR;
1671 if ((TREE_CODE (decl) == TYPE_DECL
1672 || VAR_P (decl))
1673 && !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl)))
1675 gimplify_type_sizes (TREE_TYPE (decl), seq_p);
1676 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
1677 gimplify_type_sizes (TREE_TYPE (TREE_TYPE (decl)), seq_p);
1680 /* ??? DECL_ORIGINAL_TYPE is streamed for LTO so it needs to be gimplified
1681 in case its size expressions contain problematic nodes like CALL_EXPR. */
1682 if (TREE_CODE (decl) == TYPE_DECL
1683 && DECL_ORIGINAL_TYPE (decl)
1684 && !TYPE_SIZES_GIMPLIFIED (DECL_ORIGINAL_TYPE (decl)))
1686 gimplify_type_sizes (DECL_ORIGINAL_TYPE (decl), seq_p);
1687 if (TREE_CODE (DECL_ORIGINAL_TYPE (decl)) == REFERENCE_TYPE)
1688 gimplify_type_sizes (TREE_TYPE (DECL_ORIGINAL_TYPE (decl)), seq_p);
1691 if (VAR_P (decl) && !DECL_EXTERNAL (decl))
1693 tree init = DECL_INITIAL (decl);
1694 bool is_vla = false;
1696 if (TREE_CODE (DECL_SIZE_UNIT (decl)) != INTEGER_CST
1697 || (!TREE_STATIC (decl)
1698 && flag_stack_check == GENERIC_STACK_CHECK
1699 && compare_tree_int (DECL_SIZE_UNIT (decl),
1700 STACK_CHECK_MAX_VAR_SIZE) > 0))
1702 gimplify_vla_decl (decl, seq_p);
1703 is_vla = true;
1706 if (asan_poisoned_variables
1707 && !is_vla
1708 && TREE_ADDRESSABLE (decl)
1709 && !TREE_STATIC (decl)
1710 && !DECL_HAS_VALUE_EXPR_P (decl)
1711 && DECL_ALIGN (decl) <= MAX_SUPPORTED_STACK_ALIGNMENT
1712 && dbg_cnt (asan_use_after_scope)
1713 && !gimplify_omp_ctxp)
1715 asan_poisoned_variables->add (decl);
1716 asan_poison_variable (decl, false, seq_p);
1717 if (!DECL_ARTIFICIAL (decl) && gimplify_ctxp->live_switch_vars)
1718 gimplify_ctxp->live_switch_vars->add (decl);
1721 /* Some front ends do not explicitly declare all anonymous
1722 artificial variables. We compensate here by declaring the
1723 variables, though it would be better if the front ends would
1724 explicitly declare them. */
1725 if (!DECL_SEEN_IN_BIND_EXPR_P (decl)
1726 && DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
1727 gimple_add_tmp_var (decl);
1729 if (init && init != error_mark_node)
1731 if (!TREE_STATIC (decl))
1733 DECL_INITIAL (decl) = NULL_TREE;
1734 init = build2 (INIT_EXPR, void_type_node, decl, init);
1735 gimplify_and_add (init, seq_p);
1736 ggc_free (init);
1738 else
1739 /* We must still examine initializers for static variables
1740 as they may contain a label address. */
1741 walk_tree (&init, force_labels_r, NULL, NULL);
1745 return GS_ALL_DONE;
1748 /* Gimplify a LOOP_EXPR. Normally this just involves gimplifying the body
1749 and replacing the LOOP_EXPR with goto, but if the loop contains an
1750 EXIT_EXPR, we need to append a label for it to jump to. */
1752 static enum gimplify_status
1753 gimplify_loop_expr (tree *expr_p, gimple_seq *pre_p)
1755 tree saved_label = gimplify_ctxp->exit_label;
1756 tree start_label = create_artificial_label (UNKNOWN_LOCATION);
1758 gimplify_seq_add_stmt (pre_p, gimple_build_label (start_label));
1760 gimplify_ctxp->exit_label = NULL_TREE;
1762 gimplify_and_add (LOOP_EXPR_BODY (*expr_p), pre_p);
1764 gimplify_seq_add_stmt (pre_p, gimple_build_goto (start_label));
1766 if (gimplify_ctxp->exit_label)
1767 gimplify_seq_add_stmt (pre_p,
1768 gimple_build_label (gimplify_ctxp->exit_label));
1770 gimplify_ctxp->exit_label = saved_label;
1772 *expr_p = NULL;
1773 return GS_ALL_DONE;
1776 /* Gimplify a statement list onto a sequence. These may be created either
1777 by an enlightened front-end, or by shortcut_cond_expr. */
1779 static enum gimplify_status
1780 gimplify_statement_list (tree *expr_p, gimple_seq *pre_p)
1782 tree temp = voidify_wrapper_expr (*expr_p, NULL);
1784 tree_stmt_iterator i = tsi_start (*expr_p);
1786 while (!tsi_end_p (i))
1788 gimplify_stmt (tsi_stmt_ptr (i), pre_p);
1789 tsi_delink (&i);
1792 if (temp)
1794 *expr_p = temp;
1795 return GS_OK;
1798 return GS_ALL_DONE;
1801 /* Callback for walk_gimple_seq. */
1803 static tree
1804 warn_switch_unreachable_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
1805 struct walk_stmt_info *wi)
1807 gimple *stmt = gsi_stmt (*gsi_p);
1809 *handled_ops_p = true;
1810 switch (gimple_code (stmt))
1812 case GIMPLE_TRY:
1813 /* A compiler-generated cleanup or a user-written try block.
1814 If it's empty, don't dive into it--that would result in
1815 worse location info. */
1816 if (gimple_try_eval (stmt) == NULL)
1818 wi->info = stmt;
1819 return integer_zero_node;
1821 /* Fall through. */
1822 case GIMPLE_BIND:
1823 case GIMPLE_CATCH:
1824 case GIMPLE_EH_FILTER:
1825 case GIMPLE_TRANSACTION:
1826 /* Walk the sub-statements. */
1827 *handled_ops_p = false;
1828 break;
1830 case GIMPLE_DEBUG:
1831 /* Ignore these. We may generate them before declarations that
1832 are never executed. If there's something to warn about,
1833 there will be non-debug stmts too, and we'll catch those. */
1834 break;
1836 case GIMPLE_CALL:
1837 if (gimple_call_internal_p (stmt, IFN_ASAN_MARK))
1839 *handled_ops_p = false;
1840 break;
1842 /* Fall through. */
1843 default:
1844 /* Save the first "real" statement (not a decl/lexical scope/...). */
1845 wi->info = stmt;
1846 return integer_zero_node;
1848 return NULL_TREE;
1851 /* Possibly warn about unreachable statements between switch's controlling
1852 expression and the first case. SEQ is the body of a switch expression. */
1854 static void
1855 maybe_warn_switch_unreachable (gimple_seq seq)
1857 if (!warn_switch_unreachable
1858 /* This warning doesn't play well with Fortran when optimizations
1859 are on. */
1860 || lang_GNU_Fortran ()
1861 || seq == NULL)
1862 return;
1864 struct walk_stmt_info wi;
1865 memset (&wi, 0, sizeof (wi));
1866 walk_gimple_seq (seq, warn_switch_unreachable_r, NULL, &wi);
1867 gimple *stmt = (gimple *) wi.info;
1869 if (stmt && gimple_code (stmt) != GIMPLE_LABEL)
1871 if (gimple_code (stmt) == GIMPLE_GOTO
1872 && TREE_CODE (gimple_goto_dest (stmt)) == LABEL_DECL
1873 && DECL_ARTIFICIAL (gimple_goto_dest (stmt)))
1874 /* Don't warn for compiler-generated gotos. These occur
1875 in Duff's devices, for example. */;
1876 else
1877 warning_at (gimple_location (stmt), OPT_Wswitch_unreachable,
1878 "statement will never be executed");
1883 /* A label entry that pairs label and a location. */
1884 struct label_entry
1886 tree label;
1887 location_t loc;
1890 /* Find LABEL in vector of label entries VEC. */
1892 static struct label_entry *
1893 find_label_entry (const auto_vec<struct label_entry> *vec, tree label)
1895 unsigned int i;
1896 struct label_entry *l;
1898 FOR_EACH_VEC_ELT (*vec, i, l)
1899 if (l->label == label)
1900 return l;
1901 return NULL;
1904 /* Return true if LABEL, a LABEL_DECL, represents a case label
1905 in a vector of labels CASES. */
1907 static bool
1908 case_label_p (const vec<tree> *cases, tree label)
1910 unsigned int i;
1911 tree l;
1913 FOR_EACH_VEC_ELT (*cases, i, l)
1914 if (CASE_LABEL (l) == label)
1915 return true;
1916 return false;
1919 /* Find the last nondebug statement in a scope STMT. */
1921 static gimple *
1922 last_stmt_in_scope (gimple *stmt)
1924 if (!stmt)
1925 return NULL;
1927 switch (gimple_code (stmt))
1929 case GIMPLE_BIND:
1931 gbind *bind = as_a <gbind *> (stmt);
1932 stmt = gimple_seq_last_nondebug_stmt (gimple_bind_body (bind));
1933 return last_stmt_in_scope (stmt);
1936 case GIMPLE_TRY:
1938 gtry *try_stmt = as_a <gtry *> (stmt);
1939 stmt = gimple_seq_last_nondebug_stmt (gimple_try_eval (try_stmt));
1940 gimple *last_eval = last_stmt_in_scope (stmt);
1941 if (gimple_stmt_may_fallthru (last_eval)
1942 && (last_eval == NULL
1943 || !gimple_call_internal_p (last_eval, IFN_FALLTHROUGH))
1944 && gimple_try_kind (try_stmt) == GIMPLE_TRY_FINALLY)
1946 stmt = gimple_seq_last_nondebug_stmt (gimple_try_cleanup (try_stmt));
1947 return last_stmt_in_scope (stmt);
1949 else
1950 return last_eval;
1953 case GIMPLE_DEBUG:
1954 gcc_unreachable ();
1956 default:
1957 return stmt;
1961 /* Collect interesting labels in LABELS and return the statement preceding
1962 another case label, or a user-defined label. */
1964 static gimple *
1965 collect_fallthrough_labels (gimple_stmt_iterator *gsi_p,
1966 auto_vec <struct label_entry> *labels)
1968 gimple *prev = NULL;
1972 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND)
1974 /* Recognize the special GIMPLE_BIND added by gimplify_switch_expr,
1975 which starts on a GIMPLE_SWITCH and ends with a break label.
1976 Handle that as a single statement that can fall through. */
1977 gbind *bind = as_a <gbind *> (gsi_stmt (*gsi_p));
1978 gimple *first = gimple_seq_first_stmt (gimple_bind_body (bind));
1979 gimple *last = gimple_seq_last_stmt (gimple_bind_body (bind));
1980 if (last
1981 && gimple_code (first) == GIMPLE_SWITCH
1982 && gimple_code (last) == GIMPLE_LABEL)
1984 tree label = gimple_label_label (as_a <glabel *> (last));
1985 if (SWITCH_BREAK_LABEL_P (label))
1987 prev = bind;
1988 gsi_next (gsi_p);
1989 continue;
1993 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND
1994 || gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_TRY)
1996 /* Nested scope. Only look at the last statement of
1997 the innermost scope. */
1998 location_t bind_loc = gimple_location (gsi_stmt (*gsi_p));
1999 gimple *last = last_stmt_in_scope (gsi_stmt (*gsi_p));
2000 if (last)
2002 prev = last;
2003 /* It might be a label without a location. Use the
2004 location of the scope then. */
2005 if (!gimple_has_location (prev))
2006 gimple_set_location (prev, bind_loc);
2008 gsi_next (gsi_p);
2009 continue;
2012 /* Ifs are tricky. */
2013 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_COND)
2015 gcond *cond_stmt = as_a <gcond *> (gsi_stmt (*gsi_p));
2016 tree false_lab = gimple_cond_false_label (cond_stmt);
2017 location_t if_loc = gimple_location (cond_stmt);
2019 /* If we have e.g.
2020 if (i > 1) goto <D.2259>; else goto D;
2021 we can't do much with the else-branch. */
2022 if (!DECL_ARTIFICIAL (false_lab))
2023 break;
2025 /* Go on until the false label, then one step back. */
2026 for (; !gsi_end_p (*gsi_p); gsi_next (gsi_p))
2028 gimple *stmt = gsi_stmt (*gsi_p);
2029 if (gimple_code (stmt) == GIMPLE_LABEL
2030 && gimple_label_label (as_a <glabel *> (stmt)) == false_lab)
2031 break;
2034 /* Not found? Oops. */
2035 if (gsi_end_p (*gsi_p))
2036 break;
2038 struct label_entry l = { false_lab, if_loc };
2039 labels->safe_push (l);
2041 /* Go to the last statement of the then branch. */
2042 gsi_prev (gsi_p);
2044 /* if (i != 0) goto <D.1759>; else goto <D.1760>;
2045 <D.1759>:
2046 <stmt>;
2047 goto <D.1761>;
2048 <D.1760>:
2050 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_GOTO
2051 && !gimple_has_location (gsi_stmt (*gsi_p)))
2053 /* Look at the statement before, it might be
2054 attribute fallthrough, in which case don't warn. */
2055 gsi_prev (gsi_p);
2056 bool fallthru_before_dest
2057 = gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_FALLTHROUGH);
2058 gsi_next (gsi_p);
2059 tree goto_dest = gimple_goto_dest (gsi_stmt (*gsi_p));
2060 if (!fallthru_before_dest)
2062 struct label_entry l = { goto_dest, if_loc };
2063 labels->safe_push (l);
2066 /* And move back. */
2067 gsi_next (gsi_p);
2070 /* Remember the last statement. Skip labels that are of no interest
2071 to us. */
2072 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
2074 tree label = gimple_label_label (as_a <glabel *> (gsi_stmt (*gsi_p)));
2075 if (find_label_entry (labels, label))
2076 prev = gsi_stmt (*gsi_p);
2078 else if (gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_ASAN_MARK))
2080 else if (!is_gimple_debug (gsi_stmt (*gsi_p)))
2081 prev = gsi_stmt (*gsi_p);
2082 gsi_next (gsi_p);
2084 while (!gsi_end_p (*gsi_p)
2085 /* Stop if we find a case or a user-defined label. */
2086 && (gimple_code (gsi_stmt (*gsi_p)) != GIMPLE_LABEL
2087 || !gimple_has_location (gsi_stmt (*gsi_p))));
2089 return prev;
2092 /* Return true if the switch fallthough warning should occur. LABEL is
2093 the label statement that we're falling through to. */
2095 static bool
2096 should_warn_for_implicit_fallthrough (gimple_stmt_iterator *gsi_p, tree label)
2098 gimple_stmt_iterator gsi = *gsi_p;
2100 /* Don't warn if the label is marked with a "falls through" comment. */
2101 if (FALLTHROUGH_LABEL_P (label))
2102 return false;
2104 /* Don't warn for non-case labels followed by a statement:
2105 case 0:
2106 foo ();
2107 label:
2108 bar ();
2109 as these are likely intentional. */
2110 if (!case_label_p (&gimplify_ctxp->case_labels, label))
2112 tree l;
2113 while (!gsi_end_p (gsi)
2114 && gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
2115 && (l = gimple_label_label (as_a <glabel *> (gsi_stmt (gsi))))
2116 && !case_label_p (&gimplify_ctxp->case_labels, l))
2117 gsi_next_nondebug (&gsi);
2118 if (gsi_end_p (gsi) || gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL)
2119 return false;
2122 /* Don't warn for terminated branches, i.e. when the subsequent case labels
2123 immediately breaks. */
2124 gsi = *gsi_p;
2126 /* Skip all immediately following labels. */
2127 while (!gsi_end_p (gsi)
2128 && (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
2129 || gimple_code (gsi_stmt (gsi)) == GIMPLE_PREDICT))
2130 gsi_next_nondebug (&gsi);
2132 /* { ... something; default:; } */
2133 if (gsi_end_p (gsi)
2134 /* { ... something; default: break; } or
2135 { ... something; default: goto L; } */
2136 || gimple_code (gsi_stmt (gsi)) == GIMPLE_GOTO
2137 /* { ... something; default: return; } */
2138 || gimple_code (gsi_stmt (gsi)) == GIMPLE_RETURN)
2139 return false;
2141 return true;
2144 /* Callback for walk_gimple_seq. */
2146 static tree
2147 warn_implicit_fallthrough_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
2148 struct walk_stmt_info *)
2150 gimple *stmt = gsi_stmt (*gsi_p);
2152 *handled_ops_p = true;
2153 switch (gimple_code (stmt))
2155 case GIMPLE_TRY:
2156 case GIMPLE_BIND:
2157 case GIMPLE_CATCH:
2158 case GIMPLE_EH_FILTER:
2159 case GIMPLE_TRANSACTION:
2160 /* Walk the sub-statements. */
2161 *handled_ops_p = false;
2162 break;
2164 /* Find a sequence of form:
2166 GIMPLE_LABEL
2167 [...]
2168 <may fallthru stmt>
2169 GIMPLE_LABEL
2171 and possibly warn. */
2172 case GIMPLE_LABEL:
2174 /* Found a label. Skip all immediately following labels. */
2175 while (!gsi_end_p (*gsi_p)
2176 && gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
2177 gsi_next_nondebug (gsi_p);
2179 /* There might be no more statements. */
2180 if (gsi_end_p (*gsi_p))
2181 return integer_zero_node;
2183 /* Vector of labels that fall through. */
2184 auto_vec <struct label_entry> labels;
2185 gimple *prev = collect_fallthrough_labels (gsi_p, &labels);
2187 /* There might be no more statements. */
2188 if (gsi_end_p (*gsi_p))
2189 return integer_zero_node;
2191 gimple *next = gsi_stmt (*gsi_p);
2192 tree label;
2193 /* If what follows is a label, then we may have a fallthrough. */
2194 if (gimple_code (next) == GIMPLE_LABEL
2195 && gimple_has_location (next)
2196 && (label = gimple_label_label (as_a <glabel *> (next)))
2197 && prev != NULL)
2199 struct label_entry *l;
2200 bool warned_p = false;
2201 auto_diagnostic_group d;
2202 if (!should_warn_for_implicit_fallthrough (gsi_p, label))
2203 /* Quiet. */;
2204 else if (gimple_code (prev) == GIMPLE_LABEL
2205 && (label = gimple_label_label (as_a <glabel *> (prev)))
2206 && (l = find_label_entry (&labels, label)))
2207 warned_p = warning_at (l->loc, OPT_Wimplicit_fallthrough_,
2208 "this statement may fall through");
2209 else if (!gimple_call_internal_p (prev, IFN_FALLTHROUGH)
2210 /* Try to be clever and don't warn when the statement
2211 can't actually fall through. */
2212 && gimple_stmt_may_fallthru (prev)
2213 && gimple_has_location (prev))
2214 warned_p = warning_at (gimple_location (prev),
2215 OPT_Wimplicit_fallthrough_,
2216 "this statement may fall through");
2217 if (warned_p)
2218 inform (gimple_location (next), "here");
2220 /* Mark this label as processed so as to prevent multiple
2221 warnings in nested switches. */
2222 FALLTHROUGH_LABEL_P (label) = true;
2224 /* So that next warn_implicit_fallthrough_r will start looking for
2225 a new sequence starting with this label. */
2226 gsi_prev (gsi_p);
2229 break;
2230 default:
2231 break;
2233 return NULL_TREE;
2236 /* Warn when a switch case falls through. */
2238 static void
2239 maybe_warn_implicit_fallthrough (gimple_seq seq)
2241 if (!warn_implicit_fallthrough)
2242 return;
2244 /* This warning is meant for C/C++/ObjC/ObjC++ only. */
2245 if (!(lang_GNU_C ()
2246 || lang_GNU_CXX ()
2247 || lang_GNU_OBJC ()))
2248 return;
2250 struct walk_stmt_info wi;
2251 memset (&wi, 0, sizeof (wi));
2252 walk_gimple_seq (seq, warn_implicit_fallthrough_r, NULL, &wi);
2255 /* Callback for walk_gimple_seq. */
2257 static tree
2258 expand_FALLTHROUGH_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
2259 struct walk_stmt_info *)
2261 gimple *stmt = gsi_stmt (*gsi_p);
2263 *handled_ops_p = true;
2264 switch (gimple_code (stmt))
2266 case GIMPLE_TRY:
2267 case GIMPLE_BIND:
2268 case GIMPLE_CATCH:
2269 case GIMPLE_EH_FILTER:
2270 case GIMPLE_TRANSACTION:
2271 /* Walk the sub-statements. */
2272 *handled_ops_p = false;
2273 break;
2274 case GIMPLE_CALL:
2275 if (gimple_call_internal_p (stmt, IFN_FALLTHROUGH))
2277 gsi_remove (gsi_p, true);
2278 if (gsi_end_p (*gsi_p))
2279 return integer_zero_node;
2281 bool found = false;
2282 location_t loc = gimple_location (stmt);
2284 gimple_stmt_iterator gsi2 = *gsi_p;
2285 stmt = gsi_stmt (gsi2);
2286 if (gimple_code (stmt) == GIMPLE_GOTO && !gimple_has_location (stmt))
2288 /* Go on until the artificial label. */
2289 tree goto_dest = gimple_goto_dest (stmt);
2290 for (; !gsi_end_p (gsi2); gsi_next (&gsi2))
2292 if (gimple_code (gsi_stmt (gsi2)) == GIMPLE_LABEL
2293 && gimple_label_label (as_a <glabel *> (gsi_stmt (gsi2)))
2294 == goto_dest)
2295 break;
2298 /* Not found? Stop. */
2299 if (gsi_end_p (gsi2))
2300 break;
2302 /* Look one past it. */
2303 gsi_next (&gsi2);
2306 /* We're looking for a case label or default label here. */
2307 while (!gsi_end_p (gsi2))
2309 stmt = gsi_stmt (gsi2);
2310 if (gimple_code (stmt) == GIMPLE_LABEL)
2312 tree label = gimple_label_label (as_a <glabel *> (stmt));
2313 if (gimple_has_location (stmt) && DECL_ARTIFICIAL (label))
2315 found = true;
2316 break;
2319 else if (gimple_call_internal_p (stmt, IFN_ASAN_MARK))
2321 else if (!is_gimple_debug (stmt))
2322 /* Anything else is not expected. */
2323 break;
2324 gsi_next (&gsi2);
2326 if (!found)
2327 warning_at (loc, 0, "attribute %<fallthrough%> not preceding "
2328 "a case label or default label");
2330 break;
2331 default:
2332 break;
2334 return NULL_TREE;
2337 /* Expand all FALLTHROUGH () calls in SEQ. */
2339 static void
2340 expand_FALLTHROUGH (gimple_seq *seq_p)
2342 struct walk_stmt_info wi;
2343 memset (&wi, 0, sizeof (wi));
2344 walk_gimple_seq_mod (seq_p, expand_FALLTHROUGH_r, NULL, &wi);
2348 /* Gimplify a SWITCH_EXPR, and collect the vector of labels it can
2349 branch to. */
2351 static enum gimplify_status
2352 gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p)
2354 tree switch_expr = *expr_p;
2355 gimple_seq switch_body_seq = NULL;
2356 enum gimplify_status ret;
2357 tree index_type = TREE_TYPE (switch_expr);
2358 if (index_type == NULL_TREE)
2359 index_type = TREE_TYPE (SWITCH_COND (switch_expr));
2361 ret = gimplify_expr (&SWITCH_COND (switch_expr), pre_p, NULL, is_gimple_val,
2362 fb_rvalue);
2363 if (ret == GS_ERROR || ret == GS_UNHANDLED)
2364 return ret;
2366 if (SWITCH_BODY (switch_expr))
2368 vec<tree> labels;
2369 vec<tree> saved_labels;
2370 hash_set<tree> *saved_live_switch_vars = NULL;
2371 tree default_case = NULL_TREE;
2372 gswitch *switch_stmt;
2374 /* Save old labels, get new ones from body, then restore the old
2375 labels. Save all the things from the switch body to append after. */
2376 saved_labels = gimplify_ctxp->case_labels;
2377 gimplify_ctxp->case_labels.create (8);
2379 /* Do not create live_switch_vars if SWITCH_BODY is not a BIND_EXPR. */
2380 saved_live_switch_vars = gimplify_ctxp->live_switch_vars;
2381 tree_code body_type = TREE_CODE (SWITCH_BODY (switch_expr));
2382 if (body_type == BIND_EXPR || body_type == STATEMENT_LIST)
2383 gimplify_ctxp->live_switch_vars = new hash_set<tree> (4);
2384 else
2385 gimplify_ctxp->live_switch_vars = NULL;
2387 bool old_in_switch_expr = gimplify_ctxp->in_switch_expr;
2388 gimplify_ctxp->in_switch_expr = true;
2390 gimplify_stmt (&SWITCH_BODY (switch_expr), &switch_body_seq);
2392 gimplify_ctxp->in_switch_expr = old_in_switch_expr;
2393 maybe_warn_switch_unreachable (switch_body_seq);
2394 maybe_warn_implicit_fallthrough (switch_body_seq);
2395 /* Only do this for the outermost GIMPLE_SWITCH. */
2396 if (!gimplify_ctxp->in_switch_expr)
2397 expand_FALLTHROUGH (&switch_body_seq);
2399 labels = gimplify_ctxp->case_labels;
2400 gimplify_ctxp->case_labels = saved_labels;
2402 if (gimplify_ctxp->live_switch_vars)
2404 gcc_assert (gimplify_ctxp->live_switch_vars->elements () == 0);
2405 delete gimplify_ctxp->live_switch_vars;
2407 gimplify_ctxp->live_switch_vars = saved_live_switch_vars;
2409 preprocess_case_label_vec_for_gimple (labels, index_type,
2410 &default_case);
2412 bool add_bind = false;
2413 if (!default_case)
2415 glabel *new_default;
2417 default_case
2418 = build_case_label (NULL_TREE, NULL_TREE,
2419 create_artificial_label (UNKNOWN_LOCATION));
2420 if (old_in_switch_expr)
2422 SWITCH_BREAK_LABEL_P (CASE_LABEL (default_case)) = 1;
2423 add_bind = true;
2425 new_default = gimple_build_label (CASE_LABEL (default_case));
2426 gimplify_seq_add_stmt (&switch_body_seq, new_default);
2428 else if (old_in_switch_expr)
2430 gimple *last = gimple_seq_last_stmt (switch_body_seq);
2431 if (last && gimple_code (last) == GIMPLE_LABEL)
2433 tree label = gimple_label_label (as_a <glabel *> (last));
2434 if (SWITCH_BREAK_LABEL_P (label))
2435 add_bind = true;
2439 switch_stmt = gimple_build_switch (SWITCH_COND (switch_expr),
2440 default_case, labels);
2441 /* For the benefit of -Wimplicit-fallthrough, if switch_body_seq
2442 ends with a GIMPLE_LABEL holding SWITCH_BREAK_LABEL_P LABEL_DECL,
2443 wrap the GIMPLE_SWITCH up to that GIMPLE_LABEL into a GIMPLE_BIND,
2444 so that we can easily find the start and end of the switch
2445 statement. */
2446 if (add_bind)
2448 gimple_seq bind_body = NULL;
2449 gimplify_seq_add_stmt (&bind_body, switch_stmt);
2450 gimple_seq_add_seq (&bind_body, switch_body_seq);
2451 gbind *bind = gimple_build_bind (NULL_TREE, bind_body, NULL_TREE);
2452 gimple_set_location (bind, EXPR_LOCATION (switch_expr));
2453 gimplify_seq_add_stmt (pre_p, bind);
2455 else
2457 gimplify_seq_add_stmt (pre_p, switch_stmt);
2458 gimplify_seq_add_seq (pre_p, switch_body_seq);
2460 labels.release ();
2462 else
2463 gcc_unreachable ();
2465 return GS_ALL_DONE;
2468 /* Gimplify the LABEL_EXPR pointed to by EXPR_P. */
2470 static enum gimplify_status
2471 gimplify_label_expr (tree *expr_p, gimple_seq *pre_p)
2473 gcc_assert (decl_function_context (LABEL_EXPR_LABEL (*expr_p))
2474 == current_function_decl);
2476 tree label = LABEL_EXPR_LABEL (*expr_p);
2477 glabel *label_stmt = gimple_build_label (label);
2478 gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
2479 gimplify_seq_add_stmt (pre_p, label_stmt);
2481 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label)))
2482 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_COLD_LABEL,
2483 NOT_TAKEN));
2484 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label)))
2485 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_HOT_LABEL,
2486 TAKEN));
2488 return GS_ALL_DONE;
2491 /* Gimplify the CASE_LABEL_EXPR pointed to by EXPR_P. */
2493 static enum gimplify_status
2494 gimplify_case_label_expr (tree *expr_p, gimple_seq *pre_p)
2496 struct gimplify_ctx *ctxp;
2497 glabel *label_stmt;
2499 /* Invalid programs can play Duff's Device type games with, for example,
2500 #pragma omp parallel. At least in the C front end, we don't
2501 detect such invalid branches until after gimplification, in the
2502 diagnose_omp_blocks pass. */
2503 for (ctxp = gimplify_ctxp; ; ctxp = ctxp->prev_context)
2504 if (ctxp->case_labels.exists ())
2505 break;
2507 label_stmt = gimple_build_label (CASE_LABEL (*expr_p));
2508 gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
2509 ctxp->case_labels.safe_push (*expr_p);
2510 gimplify_seq_add_stmt (pre_p, label_stmt);
2512 return GS_ALL_DONE;
2515 /* Build a GOTO to the LABEL_DECL pointed to by LABEL_P, building it first
2516 if necessary. */
2518 tree
2519 build_and_jump (tree *label_p)
2521 if (label_p == NULL)
2522 /* If there's nowhere to jump, just fall through. */
2523 return NULL_TREE;
2525 if (*label_p == NULL_TREE)
2527 tree label = create_artificial_label (UNKNOWN_LOCATION);
2528 *label_p = label;
2531 return build1 (GOTO_EXPR, void_type_node, *label_p);
2534 /* Gimplify an EXIT_EXPR by converting to a GOTO_EXPR inside a COND_EXPR.
2535 This also involves building a label to jump to and communicating it to
2536 gimplify_loop_expr through gimplify_ctxp->exit_label. */
2538 static enum gimplify_status
2539 gimplify_exit_expr (tree *expr_p)
2541 tree cond = TREE_OPERAND (*expr_p, 0);
2542 tree expr;
2544 expr = build_and_jump (&gimplify_ctxp->exit_label);
2545 expr = build3 (COND_EXPR, void_type_node, cond, expr, NULL_TREE);
2546 *expr_p = expr;
2548 return GS_OK;
2551 /* *EXPR_P is a COMPONENT_REF being used as an rvalue. If its type is
2552 different from its canonical type, wrap the whole thing inside a
2553 NOP_EXPR and force the type of the COMPONENT_REF to be the canonical
2554 type.
2556 The canonical type of a COMPONENT_REF is the type of the field being
2557 referenced--unless the field is a bit-field which can be read directly
2558 in a smaller mode, in which case the canonical type is the
2559 sign-appropriate type corresponding to that mode. */
2561 static void
2562 canonicalize_component_ref (tree *expr_p)
2564 tree expr = *expr_p;
2565 tree type;
2567 gcc_assert (TREE_CODE (expr) == COMPONENT_REF);
2569 if (INTEGRAL_TYPE_P (TREE_TYPE (expr)))
2570 type = TREE_TYPE (get_unwidened (expr, NULL_TREE));
2571 else
2572 type = TREE_TYPE (TREE_OPERAND (expr, 1));
2574 /* One could argue that all the stuff below is not necessary for
2575 the non-bitfield case and declare it a FE error if type
2576 adjustment would be needed. */
2577 if (TREE_TYPE (expr) != type)
2579 #ifdef ENABLE_TYPES_CHECKING
2580 tree old_type = TREE_TYPE (expr);
2581 #endif
2582 int type_quals;
2584 /* We need to preserve qualifiers and propagate them from
2585 operand 0. */
2586 type_quals = TYPE_QUALS (type)
2587 | TYPE_QUALS (TREE_TYPE (TREE_OPERAND (expr, 0)));
2588 if (TYPE_QUALS (type) != type_quals)
2589 type = build_qualified_type (TYPE_MAIN_VARIANT (type), type_quals);
2591 /* Set the type of the COMPONENT_REF to the underlying type. */
2592 TREE_TYPE (expr) = type;
2594 #ifdef ENABLE_TYPES_CHECKING
2595 /* It is now a FE error, if the conversion from the canonical
2596 type to the original expression type is not useless. */
2597 gcc_assert (useless_type_conversion_p (old_type, type));
2598 #endif
2602 /* If a NOP conversion is changing a pointer to array of foo to a pointer
2603 to foo, embed that change in the ADDR_EXPR by converting
2604 T array[U];
2605 (T *)&array
2607 &array[L]
2608 where L is the lower bound. For simplicity, only do this for constant
2609 lower bound.
2610 The constraint is that the type of &array[L] is trivially convertible
2611 to T *. */
2613 static void
2614 canonicalize_addr_expr (tree *expr_p)
2616 tree expr = *expr_p;
2617 tree addr_expr = TREE_OPERAND (expr, 0);
2618 tree datype, ddatype, pddatype;
2620 /* We simplify only conversions from an ADDR_EXPR to a pointer type. */
2621 if (!POINTER_TYPE_P (TREE_TYPE (expr))
2622 || TREE_CODE (addr_expr) != ADDR_EXPR)
2623 return;
2625 /* The addr_expr type should be a pointer to an array. */
2626 datype = TREE_TYPE (TREE_TYPE (addr_expr));
2627 if (TREE_CODE (datype) != ARRAY_TYPE)
2628 return;
2630 /* The pointer to element type shall be trivially convertible to
2631 the expression pointer type. */
2632 ddatype = TREE_TYPE (datype);
2633 pddatype = build_pointer_type (ddatype);
2634 if (!useless_type_conversion_p (TYPE_MAIN_VARIANT (TREE_TYPE (expr)),
2635 pddatype))
2636 return;
2638 /* The lower bound and element sizes must be constant. */
2639 if (!TYPE_SIZE_UNIT (ddatype)
2640 || TREE_CODE (TYPE_SIZE_UNIT (ddatype)) != INTEGER_CST
2641 || !TYPE_DOMAIN (datype) || !TYPE_MIN_VALUE (TYPE_DOMAIN (datype))
2642 || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (datype))) != INTEGER_CST)
2643 return;
2645 /* All checks succeeded. Build a new node to merge the cast. */
2646 *expr_p = build4 (ARRAY_REF, ddatype, TREE_OPERAND (addr_expr, 0),
2647 TYPE_MIN_VALUE (TYPE_DOMAIN (datype)),
2648 NULL_TREE, NULL_TREE);
2649 *expr_p = build1 (ADDR_EXPR, pddatype, *expr_p);
2651 /* We can have stripped a required restrict qualifier above. */
2652 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
2653 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
2656 /* *EXPR_P is a NOP_EXPR or CONVERT_EXPR. Remove it and/or other conversions
2657 underneath as appropriate. */
2659 static enum gimplify_status
2660 gimplify_conversion (tree *expr_p)
2662 location_t loc = EXPR_LOCATION (*expr_p);
2663 gcc_assert (CONVERT_EXPR_P (*expr_p));
2665 /* Then strip away all but the outermost conversion. */
2666 STRIP_SIGN_NOPS (TREE_OPERAND (*expr_p, 0));
2668 /* And remove the outermost conversion if it's useless. */
2669 if (tree_ssa_useless_type_conversion (*expr_p))
2670 *expr_p = TREE_OPERAND (*expr_p, 0);
2672 /* If we still have a conversion at the toplevel,
2673 then canonicalize some constructs. */
2674 if (CONVERT_EXPR_P (*expr_p))
2676 tree sub = TREE_OPERAND (*expr_p, 0);
2678 /* If a NOP conversion is changing the type of a COMPONENT_REF
2679 expression, then canonicalize its type now in order to expose more
2680 redundant conversions. */
2681 if (TREE_CODE (sub) == COMPONENT_REF)
2682 canonicalize_component_ref (&TREE_OPERAND (*expr_p, 0));
2684 /* If a NOP conversion is changing a pointer to array of foo
2685 to a pointer to foo, embed that change in the ADDR_EXPR. */
2686 else if (TREE_CODE (sub) == ADDR_EXPR)
2687 canonicalize_addr_expr (expr_p);
2690 /* If we have a conversion to a non-register type force the
2691 use of a VIEW_CONVERT_EXPR instead. */
2692 if (CONVERT_EXPR_P (*expr_p) && !is_gimple_reg_type (TREE_TYPE (*expr_p)))
2693 *expr_p = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (*expr_p),
2694 TREE_OPERAND (*expr_p, 0));
2696 /* Canonicalize CONVERT_EXPR to NOP_EXPR. */
2697 if (TREE_CODE (*expr_p) == CONVERT_EXPR)
2698 TREE_SET_CODE (*expr_p, NOP_EXPR);
2700 return GS_OK;
2703 /* Gimplify a VAR_DECL or PARM_DECL. Return GS_OK if we expanded a
2704 DECL_VALUE_EXPR, and it's worth re-examining things. */
2706 static enum gimplify_status
2707 gimplify_var_or_parm_decl (tree *expr_p)
2709 tree decl = *expr_p;
2711 /* ??? If this is a local variable, and it has not been seen in any
2712 outer BIND_EXPR, then it's probably the result of a duplicate
2713 declaration, for which we've already issued an error. It would
2714 be really nice if the front end wouldn't leak these at all.
2715 Currently the only known culprit is C++ destructors, as seen
2716 in g++.old-deja/g++.jason/binding.C. */
2717 if (VAR_P (decl)
2718 && !DECL_SEEN_IN_BIND_EXPR_P (decl)
2719 && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl)
2720 && decl_function_context (decl) == current_function_decl)
2722 gcc_assert (seen_error ());
2723 return GS_ERROR;
2726 /* When within an OMP context, notice uses of variables. */
2727 if (gimplify_omp_ctxp && omp_notice_variable (gimplify_omp_ctxp, decl, true))
2728 return GS_ALL_DONE;
2730 /* If the decl is an alias for another expression, substitute it now. */
2731 if (DECL_HAS_VALUE_EXPR_P (decl))
2733 *expr_p = unshare_expr (DECL_VALUE_EXPR (decl));
2734 return GS_OK;
2737 return GS_ALL_DONE;
2740 /* Recalculate the value of the TREE_SIDE_EFFECTS flag for T. */
2742 static void
2743 recalculate_side_effects (tree t)
2745 enum tree_code code = TREE_CODE (t);
2746 int len = TREE_OPERAND_LENGTH (t);
2747 int i;
2749 switch (TREE_CODE_CLASS (code))
2751 case tcc_expression:
2752 switch (code)
2754 case INIT_EXPR:
2755 case MODIFY_EXPR:
2756 case VA_ARG_EXPR:
2757 case PREDECREMENT_EXPR:
2758 case PREINCREMENT_EXPR:
2759 case POSTDECREMENT_EXPR:
2760 case POSTINCREMENT_EXPR:
2761 /* All of these have side-effects, no matter what their
2762 operands are. */
2763 return;
2765 default:
2766 break;
2768 /* Fall through. */
2770 case tcc_comparison: /* a comparison expression */
2771 case tcc_unary: /* a unary arithmetic expression */
2772 case tcc_binary: /* a binary arithmetic expression */
2773 case tcc_reference: /* a reference */
2774 case tcc_vl_exp: /* a function call */
2775 TREE_SIDE_EFFECTS (t) = TREE_THIS_VOLATILE (t);
2776 for (i = 0; i < len; ++i)
2778 tree op = TREE_OPERAND (t, i);
2779 if (op && TREE_SIDE_EFFECTS (op))
2780 TREE_SIDE_EFFECTS (t) = 1;
2782 break;
2784 case tcc_constant:
2785 /* No side-effects. */
2786 return;
2788 default:
2789 gcc_unreachable ();
2793 /* Gimplify the COMPONENT_REF, ARRAY_REF, REALPART_EXPR or IMAGPART_EXPR
2794 node *EXPR_P.
2796 compound_lval
2797 : min_lval '[' val ']'
2798 | min_lval '.' ID
2799 | compound_lval '[' val ']'
2800 | compound_lval '.' ID
2802 This is not part of the original SIMPLE definition, which separates
2803 array and member references, but it seems reasonable to handle them
2804 together. Also, this way we don't run into problems with union
2805 aliasing; gcc requires that for accesses through a union to alias, the
2806 union reference must be explicit, which was not always the case when we
2807 were splitting up array and member refs.
2809 PRE_P points to the sequence where side effects that must happen before
2810 *EXPR_P should be stored.
2812 POST_P points to the sequence where side effects that must happen after
2813 *EXPR_P should be stored. */
2815 static enum gimplify_status
2816 gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
2817 fallback_t fallback)
2819 tree *p;
2820 enum gimplify_status ret = GS_ALL_DONE, tret;
2821 int i;
2822 location_t loc = EXPR_LOCATION (*expr_p);
2823 tree expr = *expr_p;
2825 /* Create a stack of the subexpressions so later we can walk them in
2826 order from inner to outer. */
2827 auto_vec<tree, 10> expr_stack;
2829 /* We can handle anything that get_inner_reference can deal with. */
2830 for (p = expr_p; ; p = &TREE_OPERAND (*p, 0))
2832 restart:
2833 /* Fold INDIRECT_REFs now to turn them into ARRAY_REFs. */
2834 if (TREE_CODE (*p) == INDIRECT_REF)
2835 *p = fold_indirect_ref_loc (loc, *p);
2837 if (handled_component_p (*p))
2839 /* Expand DECL_VALUE_EXPR now. In some cases that may expose
2840 additional COMPONENT_REFs. */
2841 else if ((VAR_P (*p) || TREE_CODE (*p) == PARM_DECL)
2842 && gimplify_var_or_parm_decl (p) == GS_OK)
2843 goto restart;
2844 else
2845 break;
2847 expr_stack.safe_push (*p);
2850 gcc_assert (expr_stack.length ());
2852 /* Now EXPR_STACK is a stack of pointers to all the refs we've
2853 walked through and P points to the innermost expression.
2855 Java requires that we elaborated nodes in source order. That
2856 means we must gimplify the inner expression followed by each of
2857 the indices, in order. But we can't gimplify the inner
2858 expression until we deal with any variable bounds, sizes, or
2859 positions in order to deal with PLACEHOLDER_EXPRs.
2861 So we do this in three steps. First we deal with the annotations
2862 for any variables in the components, then we gimplify the base,
2863 then we gimplify any indices, from left to right. */
2864 for (i = expr_stack.length () - 1; i >= 0; i--)
2866 tree t = expr_stack[i];
2868 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
2870 /* Gimplify the low bound and element type size and put them into
2871 the ARRAY_REF. If these values are set, they have already been
2872 gimplified. */
2873 if (TREE_OPERAND (t, 2) == NULL_TREE)
2875 tree low = unshare_expr (array_ref_low_bound (t));
2876 if (!is_gimple_min_invariant (low))
2878 TREE_OPERAND (t, 2) = low;
2879 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
2880 post_p, is_gimple_reg,
2881 fb_rvalue);
2882 ret = MIN (ret, tret);
2885 else
2887 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
2888 is_gimple_reg, fb_rvalue);
2889 ret = MIN (ret, tret);
2892 if (TREE_OPERAND (t, 3) == NULL_TREE)
2894 tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0)));
2895 tree elmt_size = unshare_expr (array_ref_element_size (t));
2896 tree factor = size_int (TYPE_ALIGN_UNIT (elmt_type));
2898 /* Divide the element size by the alignment of the element
2899 type (above). */
2900 elmt_size
2901 = size_binop_loc (loc, EXACT_DIV_EXPR, elmt_size, factor);
2903 if (!is_gimple_min_invariant (elmt_size))
2905 TREE_OPERAND (t, 3) = elmt_size;
2906 tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p,
2907 post_p, is_gimple_reg,
2908 fb_rvalue);
2909 ret = MIN (ret, tret);
2912 else
2914 tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p, post_p,
2915 is_gimple_reg, fb_rvalue);
2916 ret = MIN (ret, tret);
2919 else if (TREE_CODE (t) == COMPONENT_REF)
2921 /* Set the field offset into T and gimplify it. */
2922 if (TREE_OPERAND (t, 2) == NULL_TREE)
2924 tree offset = unshare_expr (component_ref_field_offset (t));
2925 tree field = TREE_OPERAND (t, 1);
2926 tree factor
2927 = size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT);
2929 /* Divide the offset by its alignment. */
2930 offset = size_binop_loc (loc, EXACT_DIV_EXPR, offset, factor);
2932 if (!is_gimple_min_invariant (offset))
2934 TREE_OPERAND (t, 2) = offset;
2935 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
2936 post_p, is_gimple_reg,
2937 fb_rvalue);
2938 ret = MIN (ret, tret);
2941 else
2943 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
2944 is_gimple_reg, fb_rvalue);
2945 ret = MIN (ret, tret);
2950 /* Step 2 is to gimplify the base expression. Make sure lvalue is set
2951 so as to match the min_lval predicate. Failure to do so may result
2952 in the creation of large aggregate temporaries. */
2953 tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval,
2954 fallback | fb_lvalue);
2955 ret = MIN (ret, tret);
2957 /* And finally, the indices and operands of ARRAY_REF. During this
2958 loop we also remove any useless conversions. */
2959 for (; expr_stack.length () > 0; )
2961 tree t = expr_stack.pop ();
2963 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
2965 /* Gimplify the dimension. */
2966 if (!is_gimple_min_invariant (TREE_OPERAND (t, 1)))
2968 tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
2969 is_gimple_val, fb_rvalue);
2970 ret = MIN (ret, tret);
2974 STRIP_USELESS_TYPE_CONVERSION (TREE_OPERAND (t, 0));
2976 /* The innermost expression P may have originally had
2977 TREE_SIDE_EFFECTS set which would have caused all the outer
2978 expressions in *EXPR_P leading to P to also have had
2979 TREE_SIDE_EFFECTS set. */
2980 recalculate_side_effects (t);
2983 /* If the outermost expression is a COMPONENT_REF, canonicalize its type. */
2984 if ((fallback & fb_rvalue) && TREE_CODE (*expr_p) == COMPONENT_REF)
2986 canonicalize_component_ref (expr_p);
2989 expr_stack.release ();
2991 gcc_assert (*expr_p == expr || ret != GS_ALL_DONE);
2993 return ret;
2996 /* Gimplify the self modifying expression pointed to by EXPR_P
2997 (++, --, +=, -=).
2999 PRE_P points to the list where side effects that must happen before
3000 *EXPR_P should be stored.
3002 POST_P points to the list where side effects that must happen after
3003 *EXPR_P should be stored.
3005 WANT_VALUE is nonzero iff we want to use the value of this expression
3006 in another expression.
3008 ARITH_TYPE is the type the computation should be performed in. */
3010 enum gimplify_status
3011 gimplify_self_mod_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
3012 bool want_value, tree arith_type)
3014 enum tree_code code;
3015 tree lhs, lvalue, rhs, t1;
3016 gimple_seq post = NULL, *orig_post_p = post_p;
3017 bool postfix;
3018 enum tree_code arith_code;
3019 enum gimplify_status ret;
3020 location_t loc = EXPR_LOCATION (*expr_p);
3022 code = TREE_CODE (*expr_p);
3024 gcc_assert (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR
3025 || code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR);
3027 /* Prefix or postfix? */
3028 if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
3029 /* Faster to treat as prefix if result is not used. */
3030 postfix = want_value;
3031 else
3032 postfix = false;
3034 /* For postfix, make sure the inner expression's post side effects
3035 are executed after side effects from this expression. */
3036 if (postfix)
3037 post_p = &post;
3039 /* Add or subtract? */
3040 if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
3041 arith_code = PLUS_EXPR;
3042 else
3043 arith_code = MINUS_EXPR;
3045 /* Gimplify the LHS into a GIMPLE lvalue. */
3046 lvalue = TREE_OPERAND (*expr_p, 0);
3047 ret = gimplify_expr (&lvalue, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
3048 if (ret == GS_ERROR)
3049 return ret;
3051 /* Extract the operands to the arithmetic operation. */
3052 lhs = lvalue;
3053 rhs = TREE_OPERAND (*expr_p, 1);
3055 /* For postfix operator, we evaluate the LHS to an rvalue and then use
3056 that as the result value and in the postqueue operation. */
3057 if (postfix)
3059 ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue);
3060 if (ret == GS_ERROR)
3061 return ret;
3063 lhs = get_initialized_tmp_var (lhs, pre_p, NULL);
3066 /* For POINTERs increment, use POINTER_PLUS_EXPR. */
3067 if (POINTER_TYPE_P (TREE_TYPE (lhs)))
3069 rhs = convert_to_ptrofftype_loc (loc, rhs);
3070 if (arith_code == MINUS_EXPR)
3071 rhs = fold_build1_loc (loc, NEGATE_EXPR, TREE_TYPE (rhs), rhs);
3072 t1 = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (*expr_p), lhs, rhs);
3074 else
3075 t1 = fold_convert (TREE_TYPE (*expr_p),
3076 fold_build2 (arith_code, arith_type,
3077 fold_convert (arith_type, lhs),
3078 fold_convert (arith_type, rhs)));
3080 if (postfix)
3082 gimplify_assign (lvalue, t1, pre_p);
3083 gimplify_seq_add_seq (orig_post_p, post);
3084 *expr_p = lhs;
3085 return GS_ALL_DONE;
3087 else
3089 *expr_p = build2 (MODIFY_EXPR, TREE_TYPE (lvalue), lvalue, t1);
3090 return GS_OK;
3094 /* If *EXPR_P has a variable sized type, wrap it in a WITH_SIZE_EXPR. */
3096 static void
3097 maybe_with_size_expr (tree *expr_p)
3099 tree expr = *expr_p;
3100 tree type = TREE_TYPE (expr);
3101 tree size;
3103 /* If we've already wrapped this or the type is error_mark_node, we can't do
3104 anything. */
3105 if (TREE_CODE (expr) == WITH_SIZE_EXPR
3106 || type == error_mark_node)
3107 return;
3109 /* If the size isn't known or is a constant, we have nothing to do. */
3110 size = TYPE_SIZE_UNIT (type);
3111 if (!size || poly_int_tree_p (size))
3112 return;
3114 /* Otherwise, make a WITH_SIZE_EXPR. */
3115 size = unshare_expr (size);
3116 size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, expr);
3117 *expr_p = build2 (WITH_SIZE_EXPR, type, expr, size);
3120 /* Helper for gimplify_call_expr. Gimplify a single argument *ARG_P
3121 Store any side-effects in PRE_P. CALL_LOCATION is the location of
3122 the CALL_EXPR. If ALLOW_SSA is set the actual parameter may be
3123 gimplified to an SSA name. */
3125 enum gimplify_status
3126 gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location,
3127 bool allow_ssa)
3129 bool (*test) (tree);
3130 fallback_t fb;
3132 /* In general, we allow lvalues for function arguments to avoid
3133 extra overhead of copying large aggregates out of even larger
3134 aggregates into temporaries only to copy the temporaries to
3135 the argument list. Make optimizers happy by pulling out to
3136 temporaries those types that fit in registers. */
3137 if (is_gimple_reg_type (TREE_TYPE (*arg_p)))
3138 test = is_gimple_val, fb = fb_rvalue;
3139 else
3141 test = is_gimple_lvalue, fb = fb_either;
3142 /* Also strip a TARGET_EXPR that would force an extra copy. */
3143 if (TREE_CODE (*arg_p) == TARGET_EXPR)
3145 tree init = TARGET_EXPR_INITIAL (*arg_p);
3146 if (init
3147 && !VOID_TYPE_P (TREE_TYPE (init)))
3148 *arg_p = init;
3152 /* If this is a variable sized type, we must remember the size. */
3153 maybe_with_size_expr (arg_p);
3155 /* FIXME diagnostics: This will mess up gcc.dg/Warray-bounds.c. */
3156 /* Make sure arguments have the same location as the function call
3157 itself. */
3158 protected_set_expr_location (*arg_p, call_location);
3160 /* There is a sequence point before a function call. Side effects in
3161 the argument list must occur before the actual call. So, when
3162 gimplifying arguments, force gimplify_expr to use an internal
3163 post queue which is then appended to the end of PRE_P. */
3164 return gimplify_expr (arg_p, pre_p, NULL, test, fb, allow_ssa);
3167 /* Don't fold inside offloading or taskreg regions: it can break code by
3168 adding decl references that weren't in the source. We'll do it during
3169 omplower pass instead. */
3171 static bool
3172 maybe_fold_stmt (gimple_stmt_iterator *gsi)
3174 struct gimplify_omp_ctx *ctx;
3175 for (ctx = gimplify_omp_ctxp; ctx; ctx = ctx->outer_context)
3176 if ((ctx->region_type & (ORT_TARGET | ORT_PARALLEL | ORT_TASK)) != 0)
3177 return false;
3178 else if ((ctx->region_type & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
3179 return false;
3180 return fold_stmt (gsi);
3183 /* Gimplify the CALL_EXPR node *EXPR_P into the GIMPLE sequence PRE_P.
3184 WANT_VALUE is true if the result of the call is desired. */
3186 static enum gimplify_status
3187 gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
3189 tree fndecl, parms, p, fnptrtype;
3190 enum gimplify_status ret;
3191 int i, nargs;
3192 gcall *call;
3193 bool builtin_va_start_p = false;
3194 location_t loc = EXPR_LOCATION (*expr_p);
3196 gcc_assert (TREE_CODE (*expr_p) == CALL_EXPR);
3198 /* For reliable diagnostics during inlining, it is necessary that
3199 every call_expr be annotated with file and line. */
3200 if (! EXPR_HAS_LOCATION (*expr_p))
3201 SET_EXPR_LOCATION (*expr_p, input_location);
3203 /* Gimplify internal functions created in the FEs. */
3204 if (CALL_EXPR_FN (*expr_p) == NULL_TREE)
3206 if (want_value)
3207 return GS_ALL_DONE;
3209 nargs = call_expr_nargs (*expr_p);
3210 enum internal_fn ifn = CALL_EXPR_IFN (*expr_p);
3211 auto_vec<tree> vargs (nargs);
3213 for (i = 0; i < nargs; i++)
3215 gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
3216 EXPR_LOCATION (*expr_p));
3217 vargs.quick_push (CALL_EXPR_ARG (*expr_p, i));
3220 gcall *call = gimple_build_call_internal_vec (ifn, vargs);
3221 gimple_call_set_nothrow (call, TREE_NOTHROW (*expr_p));
3222 gimplify_seq_add_stmt (pre_p, call);
3223 return GS_ALL_DONE;
3226 /* This may be a call to a builtin function.
3228 Builtin function calls may be transformed into different
3229 (and more efficient) builtin function calls under certain
3230 circumstances. Unfortunately, gimplification can muck things
3231 up enough that the builtin expanders are not aware that certain
3232 transformations are still valid.
3234 So we attempt transformation/gimplification of the call before
3235 we gimplify the CALL_EXPR. At this time we do not manage to
3236 transform all calls in the same manner as the expanders do, but
3237 we do transform most of them. */
3238 fndecl = get_callee_fndecl (*expr_p);
3239 if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
3240 switch (DECL_FUNCTION_CODE (fndecl))
3242 CASE_BUILT_IN_ALLOCA:
3243 /* If the call has been built for a variable-sized object, then we
3244 want to restore the stack level when the enclosing BIND_EXPR is
3245 exited to reclaim the allocated space; otherwise, we precisely
3246 need to do the opposite and preserve the latest stack level. */
3247 if (CALL_ALLOCA_FOR_VAR_P (*expr_p))
3248 gimplify_ctxp->save_stack = true;
3249 else
3250 gimplify_ctxp->keep_stack = true;
3251 break;
3253 case BUILT_IN_VA_START:
3255 builtin_va_start_p = TRUE;
3256 if (call_expr_nargs (*expr_p) < 2)
3258 error ("too few arguments to function %<va_start%>");
3259 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
3260 return GS_OK;
3263 if (fold_builtin_next_arg (*expr_p, true))
3265 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
3266 return GS_OK;
3268 break;
3271 default:
3274 if (fndecl && fndecl_built_in_p (fndecl))
3276 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
3277 if (new_tree && new_tree != *expr_p)
3279 /* There was a transformation of this call which computes the
3280 same value, but in a more efficient way. Return and try
3281 again. */
3282 *expr_p = new_tree;
3283 return GS_OK;
3287 /* Remember the original function pointer type. */
3288 fnptrtype = TREE_TYPE (CALL_EXPR_FN (*expr_p));
3290 /* There is a sequence point before the call, so any side effects in
3291 the calling expression must occur before the actual call. Force
3292 gimplify_expr to use an internal post queue. */
3293 ret = gimplify_expr (&CALL_EXPR_FN (*expr_p), pre_p, NULL,
3294 is_gimple_call_addr, fb_rvalue);
3296 nargs = call_expr_nargs (*expr_p);
3298 /* Get argument types for verification. */
3299 fndecl = get_callee_fndecl (*expr_p);
3300 parms = NULL_TREE;
3301 if (fndecl)
3302 parms = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
3303 else
3304 parms = TYPE_ARG_TYPES (TREE_TYPE (fnptrtype));
3306 if (fndecl && DECL_ARGUMENTS (fndecl))
3307 p = DECL_ARGUMENTS (fndecl);
3308 else if (parms)
3309 p = parms;
3310 else
3311 p = NULL_TREE;
3312 for (i = 0; i < nargs && p; i++, p = TREE_CHAIN (p))
3315 /* If the last argument is __builtin_va_arg_pack () and it is not
3316 passed as a named argument, decrease the number of CALL_EXPR
3317 arguments and set instead the CALL_EXPR_VA_ARG_PACK flag. */
3318 if (!p
3319 && i < nargs
3320 && TREE_CODE (CALL_EXPR_ARG (*expr_p, nargs - 1)) == CALL_EXPR)
3322 tree last_arg = CALL_EXPR_ARG (*expr_p, nargs - 1);
3323 tree last_arg_fndecl = get_callee_fndecl (last_arg);
3325 if (last_arg_fndecl
3326 && fndecl_built_in_p (last_arg_fndecl, BUILT_IN_VA_ARG_PACK))
3328 tree call = *expr_p;
3330 --nargs;
3331 *expr_p = build_call_array_loc (loc, TREE_TYPE (call),
3332 CALL_EXPR_FN (call),
3333 nargs, CALL_EXPR_ARGP (call));
3335 /* Copy all CALL_EXPR flags, location and block, except
3336 CALL_EXPR_VA_ARG_PACK flag. */
3337 CALL_EXPR_STATIC_CHAIN (*expr_p) = CALL_EXPR_STATIC_CHAIN (call);
3338 CALL_EXPR_TAILCALL (*expr_p) = CALL_EXPR_TAILCALL (call);
3339 CALL_EXPR_RETURN_SLOT_OPT (*expr_p)
3340 = CALL_EXPR_RETURN_SLOT_OPT (call);
3341 CALL_FROM_THUNK_P (*expr_p) = CALL_FROM_THUNK_P (call);
3342 SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (call));
3344 /* Set CALL_EXPR_VA_ARG_PACK. */
3345 CALL_EXPR_VA_ARG_PACK (*expr_p) = 1;
3349 /* If the call returns twice then after building the CFG the call
3350 argument computations will no longer dominate the call because
3351 we add an abnormal incoming edge to the call. So do not use SSA
3352 vars there. */
3353 bool returns_twice = call_expr_flags (*expr_p) & ECF_RETURNS_TWICE;
3355 /* Gimplify the function arguments. */
3356 if (nargs > 0)
3358 for (i = (PUSH_ARGS_REVERSED ? nargs - 1 : 0);
3359 PUSH_ARGS_REVERSED ? i >= 0 : i < nargs;
3360 PUSH_ARGS_REVERSED ? i-- : i++)
3362 enum gimplify_status t;
3364 /* Avoid gimplifying the second argument to va_start, which needs to
3365 be the plain PARM_DECL. */
3366 if ((i != 1) || !builtin_va_start_p)
3368 t = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
3369 EXPR_LOCATION (*expr_p), ! returns_twice);
3371 if (t == GS_ERROR)
3372 ret = GS_ERROR;
3377 /* Gimplify the static chain. */
3378 if (CALL_EXPR_STATIC_CHAIN (*expr_p))
3380 if (fndecl && !DECL_STATIC_CHAIN (fndecl))
3381 CALL_EXPR_STATIC_CHAIN (*expr_p) = NULL;
3382 else
3384 enum gimplify_status t;
3385 t = gimplify_arg (&CALL_EXPR_STATIC_CHAIN (*expr_p), pre_p,
3386 EXPR_LOCATION (*expr_p), ! returns_twice);
3387 if (t == GS_ERROR)
3388 ret = GS_ERROR;
3392 /* Verify the function result. */
3393 if (want_value && fndecl
3394 && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fnptrtype))))
3396 error_at (loc, "using result of function returning %<void%>");
3397 ret = GS_ERROR;
3400 /* Try this again in case gimplification exposed something. */
3401 if (ret != GS_ERROR)
3403 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
3405 if (new_tree && new_tree != *expr_p)
3407 /* There was a transformation of this call which computes the
3408 same value, but in a more efficient way. Return and try
3409 again. */
3410 *expr_p = new_tree;
3411 return GS_OK;
3414 else
3416 *expr_p = error_mark_node;
3417 return GS_ERROR;
3420 /* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its
3421 decl. This allows us to eliminate redundant or useless
3422 calls to "const" functions. */
3423 if (TREE_CODE (*expr_p) == CALL_EXPR)
3425 int flags = call_expr_flags (*expr_p);
3426 if (flags & (ECF_CONST | ECF_PURE)
3427 /* An infinite loop is considered a side effect. */
3428 && !(flags & (ECF_LOOPING_CONST_OR_PURE)))
3429 TREE_SIDE_EFFECTS (*expr_p) = 0;
3432 /* If the value is not needed by the caller, emit a new GIMPLE_CALL
3433 and clear *EXPR_P. Otherwise, leave *EXPR_P in its gimplified
3434 form and delegate the creation of a GIMPLE_CALL to
3435 gimplify_modify_expr. This is always possible because when
3436 WANT_VALUE is true, the caller wants the result of this call into
3437 a temporary, which means that we will emit an INIT_EXPR in
3438 internal_get_tmp_var which will then be handled by
3439 gimplify_modify_expr. */
3440 if (!want_value)
3442 /* The CALL_EXPR in *EXPR_P is already in GIMPLE form, so all we
3443 have to do is replicate it as a GIMPLE_CALL tuple. */
3444 gimple_stmt_iterator gsi;
3445 call = gimple_build_call_from_tree (*expr_p, fnptrtype);
3446 notice_special_calls (call);
3447 gimplify_seq_add_stmt (pre_p, call);
3448 gsi = gsi_last (*pre_p);
3449 maybe_fold_stmt (&gsi);
3450 *expr_p = NULL_TREE;
3452 else
3453 /* Remember the original function type. */
3454 CALL_EXPR_FN (*expr_p) = build1 (NOP_EXPR, fnptrtype,
3455 CALL_EXPR_FN (*expr_p));
3457 return ret;
3460 /* Handle shortcut semantics in the predicate operand of a COND_EXPR by
3461 rewriting it into multiple COND_EXPRs, and possibly GOTO_EXPRs.
3463 TRUE_LABEL_P and FALSE_LABEL_P point to the labels to jump to if the
3464 condition is true or false, respectively. If null, we should generate
3465 our own to skip over the evaluation of this specific expression.
3467 LOCUS is the source location of the COND_EXPR.
3469 This function is the tree equivalent of do_jump.
3471 shortcut_cond_r should only be called by shortcut_cond_expr. */
3473 static tree
3474 shortcut_cond_r (tree pred, tree *true_label_p, tree *false_label_p,
3475 location_t locus)
3477 tree local_label = NULL_TREE;
3478 tree t, expr = NULL;
3480 /* OK, it's not a simple case; we need to pull apart the COND_EXPR to
3481 retain the shortcut semantics. Just insert the gotos here;
3482 shortcut_cond_expr will append the real blocks later. */
3483 if (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
3485 location_t new_locus;
3487 /* Turn if (a && b) into
3489 if (a); else goto no;
3490 if (b) goto yes; else goto no;
3491 (no:) */
3493 if (false_label_p == NULL)
3494 false_label_p = &local_label;
3496 /* Keep the original source location on the first 'if'. */
3497 t = shortcut_cond_r (TREE_OPERAND (pred, 0), NULL, false_label_p, locus);
3498 append_to_statement_list (t, &expr);
3500 /* Set the source location of the && on the second 'if'. */
3501 new_locus = rexpr_location (pred, locus);
3502 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
3503 new_locus);
3504 append_to_statement_list (t, &expr);
3506 else if (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
3508 location_t new_locus;
3510 /* Turn if (a || b) into
3512 if (a) goto yes;
3513 if (b) goto yes; else goto no;
3514 (yes:) */
3516 if (true_label_p == NULL)
3517 true_label_p = &local_label;
3519 /* Keep the original source location on the first 'if'. */
3520 t = shortcut_cond_r (TREE_OPERAND (pred, 0), true_label_p, NULL, locus);
3521 append_to_statement_list (t, &expr);
3523 /* Set the source location of the || on the second 'if'. */
3524 new_locus = rexpr_location (pred, locus);
3525 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
3526 new_locus);
3527 append_to_statement_list (t, &expr);
3529 else if (TREE_CODE (pred) == COND_EXPR
3530 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 1)))
3531 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 2))))
3533 location_t new_locus;
3535 /* As long as we're messing with gotos, turn if (a ? b : c) into
3536 if (a)
3537 if (b) goto yes; else goto no;
3538 else
3539 if (c) goto yes; else goto no;
3541 Don't do this if one of the arms has void type, which can happen
3542 in C++ when the arm is throw. */
3544 /* Keep the original source location on the first 'if'. Set the source
3545 location of the ? on the second 'if'. */
3546 new_locus = rexpr_location (pred, locus);
3547 expr = build3 (COND_EXPR, void_type_node, TREE_OPERAND (pred, 0),
3548 shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p,
3549 false_label_p, locus),
3550 shortcut_cond_r (TREE_OPERAND (pred, 2), true_label_p,
3551 false_label_p, new_locus));
3553 else
3555 expr = build3 (COND_EXPR, void_type_node, pred,
3556 build_and_jump (true_label_p),
3557 build_and_jump (false_label_p));
3558 SET_EXPR_LOCATION (expr, locus);
3561 if (local_label)
3563 t = build1 (LABEL_EXPR, void_type_node, local_label);
3564 append_to_statement_list (t, &expr);
3567 return expr;
3570 /* If EXPR is a GOTO_EXPR, return it. If it is a STATEMENT_LIST, skip
3571 any of its leading DEBUG_BEGIN_STMTS and recurse on the subsequent
3572 statement, if it is the last one. Otherwise, return NULL. */
3574 static tree
3575 find_goto (tree expr)
3577 if (!expr)
3578 return NULL_TREE;
3580 if (TREE_CODE (expr) == GOTO_EXPR)
3581 return expr;
3583 if (TREE_CODE (expr) != STATEMENT_LIST)
3584 return NULL_TREE;
3586 tree_stmt_iterator i = tsi_start (expr);
3588 while (!tsi_end_p (i) && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT)
3589 tsi_next (&i);
3591 if (!tsi_one_before_end_p (i))
3592 return NULL_TREE;
3594 return find_goto (tsi_stmt (i));
3597 /* Same as find_goto, except that it returns NULL if the destination
3598 is not a LABEL_DECL. */
3600 static inline tree
3601 find_goto_label (tree expr)
3603 tree dest = find_goto (expr);
3604 if (dest && TREE_CODE (GOTO_DESTINATION (dest)) == LABEL_DECL)
3605 return dest;
3606 return NULL_TREE;
3609 /* Given a conditional expression EXPR with short-circuit boolean
3610 predicates using TRUTH_ANDIF_EXPR or TRUTH_ORIF_EXPR, break the
3611 predicate apart into the equivalent sequence of conditionals. */
3613 static tree
3614 shortcut_cond_expr (tree expr)
3616 tree pred = TREE_OPERAND (expr, 0);
3617 tree then_ = TREE_OPERAND (expr, 1);
3618 tree else_ = TREE_OPERAND (expr, 2);
3619 tree true_label, false_label, end_label, t;
3620 tree *true_label_p;
3621 tree *false_label_p;
3622 bool emit_end, emit_false, jump_over_else;
3623 bool then_se = then_ && TREE_SIDE_EFFECTS (then_);
3624 bool else_se = else_ && TREE_SIDE_EFFECTS (else_);
3626 /* First do simple transformations. */
3627 if (!else_se)
3629 /* If there is no 'else', turn
3630 if (a && b) then c
3631 into
3632 if (a) if (b) then c. */
3633 while (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
3635 /* Keep the original source location on the first 'if'. */
3636 location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
3637 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
3638 /* Set the source location of the && on the second 'if'. */
3639 if (rexpr_has_location (pred))
3640 SET_EXPR_LOCATION (expr, rexpr_location (pred));
3641 then_ = shortcut_cond_expr (expr);
3642 then_se = then_ && TREE_SIDE_EFFECTS (then_);
3643 pred = TREE_OPERAND (pred, 0);
3644 expr = build3 (COND_EXPR, void_type_node, pred, then_, NULL_TREE);
3645 SET_EXPR_LOCATION (expr, locus);
3649 if (!then_se)
3651 /* If there is no 'then', turn
3652 if (a || b); else d
3653 into
3654 if (a); else if (b); else d. */
3655 while (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
3657 /* Keep the original source location on the first 'if'. */
3658 location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
3659 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
3660 /* Set the source location of the || on the second 'if'. */
3661 if (rexpr_has_location (pred))
3662 SET_EXPR_LOCATION (expr, rexpr_location (pred));
3663 else_ = shortcut_cond_expr (expr);
3664 else_se = else_ && TREE_SIDE_EFFECTS (else_);
3665 pred = TREE_OPERAND (pred, 0);
3666 expr = build3 (COND_EXPR, void_type_node, pred, NULL_TREE, else_);
3667 SET_EXPR_LOCATION (expr, locus);
3671 /* If we're done, great. */
3672 if (TREE_CODE (pred) != TRUTH_ANDIF_EXPR
3673 && TREE_CODE (pred) != TRUTH_ORIF_EXPR)
3674 return expr;
3676 /* Otherwise we need to mess with gotos. Change
3677 if (a) c; else d;
3679 if (a); else goto no;
3680 c; goto end;
3681 no: d; end:
3682 and recursively gimplify the condition. */
3684 true_label = false_label = end_label = NULL_TREE;
3686 /* If our arms just jump somewhere, hijack those labels so we don't
3687 generate jumps to jumps. */
3689 if (tree then_goto = find_goto_label (then_))
3691 true_label = GOTO_DESTINATION (then_goto);
3692 then_ = NULL;
3693 then_se = false;
3696 if (tree else_goto = find_goto_label (else_))
3698 false_label = GOTO_DESTINATION (else_goto);
3699 else_ = NULL;
3700 else_se = false;
3703 /* If we aren't hijacking a label for the 'then' branch, it falls through. */
3704 if (true_label)
3705 true_label_p = &true_label;
3706 else
3707 true_label_p = NULL;
3709 /* The 'else' branch also needs a label if it contains interesting code. */
3710 if (false_label || else_se)
3711 false_label_p = &false_label;
3712 else
3713 false_label_p = NULL;
3715 /* If there was nothing else in our arms, just forward the label(s). */
3716 if (!then_se && !else_se)
3717 return shortcut_cond_r (pred, true_label_p, false_label_p,
3718 EXPR_LOC_OR_LOC (expr, input_location));
3720 /* If our last subexpression already has a terminal label, reuse it. */
3721 if (else_se)
3722 t = expr_last (else_);
3723 else if (then_se)
3724 t = expr_last (then_);
3725 else
3726 t = NULL;
3727 if (t && TREE_CODE (t) == LABEL_EXPR)
3728 end_label = LABEL_EXPR_LABEL (t);
3730 /* If we don't care about jumping to the 'else' branch, jump to the end
3731 if the condition is false. */
3732 if (!false_label_p)
3733 false_label_p = &end_label;
3735 /* We only want to emit these labels if we aren't hijacking them. */
3736 emit_end = (end_label == NULL_TREE);
3737 emit_false = (false_label == NULL_TREE);
3739 /* We only emit the jump over the else clause if we have to--if the
3740 then clause may fall through. Otherwise we can wind up with a
3741 useless jump and a useless label at the end of gimplified code,
3742 which will cause us to think that this conditional as a whole
3743 falls through even if it doesn't. If we then inline a function
3744 which ends with such a condition, that can cause us to issue an
3745 inappropriate warning about control reaching the end of a
3746 non-void function. */
3747 jump_over_else = block_may_fallthru (then_);
3749 pred = shortcut_cond_r (pred, true_label_p, false_label_p,
3750 EXPR_LOC_OR_LOC (expr, input_location));
3752 expr = NULL;
3753 append_to_statement_list (pred, &expr);
3755 append_to_statement_list (then_, &expr);
3756 if (else_se)
3758 if (jump_over_else)
3760 tree last = expr_last (expr);
3761 t = build_and_jump (&end_label);
3762 if (rexpr_has_location (last))
3763 SET_EXPR_LOCATION (t, rexpr_location (last));
3764 append_to_statement_list (t, &expr);
3766 if (emit_false)
3768 t = build1 (LABEL_EXPR, void_type_node, false_label);
3769 append_to_statement_list (t, &expr);
3771 append_to_statement_list (else_, &expr);
3773 if (emit_end && end_label)
3775 t = build1 (LABEL_EXPR, void_type_node, end_label);
3776 append_to_statement_list (t, &expr);
3779 return expr;
3782 /* EXPR is used in a boolean context; make sure it has BOOLEAN_TYPE. */
3784 tree
3785 gimple_boolify (tree expr)
3787 tree type = TREE_TYPE (expr);
3788 location_t loc = EXPR_LOCATION (expr);
3790 if (TREE_CODE (expr) == NE_EXPR
3791 && TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR
3792 && integer_zerop (TREE_OPERAND (expr, 1)))
3794 tree call = TREE_OPERAND (expr, 0);
3795 tree fn = get_callee_fndecl (call);
3797 /* For __builtin_expect ((long) (x), y) recurse into x as well
3798 if x is truth_value_p. */
3799 if (fn
3800 && fndecl_built_in_p (fn, BUILT_IN_EXPECT)
3801 && call_expr_nargs (call) == 2)
3803 tree arg = CALL_EXPR_ARG (call, 0);
3804 if (arg)
3806 if (TREE_CODE (arg) == NOP_EXPR
3807 && TREE_TYPE (arg) == TREE_TYPE (call))
3808 arg = TREE_OPERAND (arg, 0);
3809 if (truth_value_p (TREE_CODE (arg)))
3811 arg = gimple_boolify (arg);
3812 CALL_EXPR_ARG (call, 0)
3813 = fold_convert_loc (loc, TREE_TYPE (call), arg);
3819 switch (TREE_CODE (expr))
3821 case TRUTH_AND_EXPR:
3822 case TRUTH_OR_EXPR:
3823 case TRUTH_XOR_EXPR:
3824 case TRUTH_ANDIF_EXPR:
3825 case TRUTH_ORIF_EXPR:
3826 /* Also boolify the arguments of truth exprs. */
3827 TREE_OPERAND (expr, 1) = gimple_boolify (TREE_OPERAND (expr, 1));
3828 /* FALLTHRU */
3830 case TRUTH_NOT_EXPR:
3831 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
3833 /* These expressions always produce boolean results. */
3834 if (TREE_CODE (type) != BOOLEAN_TYPE)
3835 TREE_TYPE (expr) = boolean_type_node;
3836 return expr;
3838 case ANNOTATE_EXPR:
3839 switch ((enum annot_expr_kind) TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)))
3841 case annot_expr_ivdep_kind:
3842 case annot_expr_unroll_kind:
3843 case annot_expr_no_vector_kind:
3844 case annot_expr_vector_kind:
3845 case annot_expr_parallel_kind:
3846 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
3847 if (TREE_CODE (type) != BOOLEAN_TYPE)
3848 TREE_TYPE (expr) = boolean_type_node;
3849 return expr;
3850 default:
3851 gcc_unreachable ();
3854 default:
3855 if (COMPARISON_CLASS_P (expr))
3857 /* There expressions always prduce boolean results. */
3858 if (TREE_CODE (type) != BOOLEAN_TYPE)
3859 TREE_TYPE (expr) = boolean_type_node;
3860 return expr;
3862 /* Other expressions that get here must have boolean values, but
3863 might need to be converted to the appropriate mode. */
3864 if (TREE_CODE (type) == BOOLEAN_TYPE)
3865 return expr;
3866 return fold_convert_loc (loc, boolean_type_node, expr);
3870 /* Given a conditional expression *EXPR_P without side effects, gimplify
3871 its operands. New statements are inserted to PRE_P. */
3873 static enum gimplify_status
3874 gimplify_pure_cond_expr (tree *expr_p, gimple_seq *pre_p)
3876 tree expr = *expr_p, cond;
3877 enum gimplify_status ret, tret;
3878 enum tree_code code;
3880 cond = gimple_boolify (COND_EXPR_COND (expr));
3882 /* We need to handle && and || specially, as their gimplification
3883 creates pure cond_expr, thus leading to an infinite cycle otherwise. */
3884 code = TREE_CODE (cond);
3885 if (code == TRUTH_ANDIF_EXPR)
3886 TREE_SET_CODE (cond, TRUTH_AND_EXPR);
3887 else if (code == TRUTH_ORIF_EXPR)
3888 TREE_SET_CODE (cond, TRUTH_OR_EXPR);
3889 ret = gimplify_expr (&cond, pre_p, NULL, is_gimple_condexpr, fb_rvalue);
3890 COND_EXPR_COND (*expr_p) = cond;
3892 tret = gimplify_expr (&COND_EXPR_THEN (expr), pre_p, NULL,
3893 is_gimple_val, fb_rvalue);
3894 ret = MIN (ret, tret);
3895 tret = gimplify_expr (&COND_EXPR_ELSE (expr), pre_p, NULL,
3896 is_gimple_val, fb_rvalue);
3898 return MIN (ret, tret);
3901 /* Return true if evaluating EXPR could trap.
3902 EXPR is GENERIC, while tree_could_trap_p can be called
3903 only on GIMPLE. */
3905 bool
3906 generic_expr_could_trap_p (tree expr)
3908 unsigned i, n;
3910 if (!expr || is_gimple_val (expr))
3911 return false;
3913 if (!EXPR_P (expr) || tree_could_trap_p (expr))
3914 return true;
3916 n = TREE_OPERAND_LENGTH (expr);
3917 for (i = 0; i < n; i++)
3918 if (generic_expr_could_trap_p (TREE_OPERAND (expr, i)))
3919 return true;
3921 return false;
3924 /* Convert the conditional expression pointed to by EXPR_P '(p) ? a : b;'
3925 into
3927 if (p) if (p)
3928 t1 = a; a;
3929 else or else
3930 t1 = b; b;
3933 The second form is used when *EXPR_P is of type void.
3935 PRE_P points to the list where side effects that must happen before
3936 *EXPR_P should be stored. */
3938 static enum gimplify_status
3939 gimplify_cond_expr (tree *expr_p, gimple_seq *pre_p, fallback_t fallback)
3941 tree expr = *expr_p;
3942 tree type = TREE_TYPE (expr);
3943 location_t loc = EXPR_LOCATION (expr);
3944 tree tmp, arm1, arm2;
3945 enum gimplify_status ret;
3946 tree label_true, label_false, label_cont;
3947 bool have_then_clause_p, have_else_clause_p;
3948 gcond *cond_stmt;
3949 enum tree_code pred_code;
3950 gimple_seq seq = NULL;
3952 /* If this COND_EXPR has a value, copy the values into a temporary within
3953 the arms. */
3954 if (!VOID_TYPE_P (type))
3956 tree then_ = TREE_OPERAND (expr, 1), else_ = TREE_OPERAND (expr, 2);
3957 tree result;
3959 /* If either an rvalue is ok or we do not require an lvalue, create the
3960 temporary. But we cannot do that if the type is addressable. */
3961 if (((fallback & fb_rvalue) || !(fallback & fb_lvalue))
3962 && !TREE_ADDRESSABLE (type))
3964 if (gimplify_ctxp->allow_rhs_cond_expr
3965 /* If either branch has side effects or could trap, it can't be
3966 evaluated unconditionally. */
3967 && !TREE_SIDE_EFFECTS (then_)
3968 && !generic_expr_could_trap_p (then_)
3969 && !TREE_SIDE_EFFECTS (else_)
3970 && !generic_expr_could_trap_p (else_))
3971 return gimplify_pure_cond_expr (expr_p, pre_p);
3973 tmp = create_tmp_var (type, "iftmp");
3974 result = tmp;
3977 /* Otherwise, only create and copy references to the values. */
3978 else
3980 type = build_pointer_type (type);
3982 if (!VOID_TYPE_P (TREE_TYPE (then_)))
3983 then_ = build_fold_addr_expr_loc (loc, then_);
3985 if (!VOID_TYPE_P (TREE_TYPE (else_)))
3986 else_ = build_fold_addr_expr_loc (loc, else_);
3988 expr
3989 = build3 (COND_EXPR, type, TREE_OPERAND (expr, 0), then_, else_);
3991 tmp = create_tmp_var (type, "iftmp");
3992 result = build_simple_mem_ref_loc (loc, tmp);
3995 /* Build the new then clause, `tmp = then_;'. But don't build the
3996 assignment if the value is void; in C++ it can be if it's a throw. */
3997 if (!VOID_TYPE_P (TREE_TYPE (then_)))
3998 TREE_OPERAND (expr, 1) = build2 (MODIFY_EXPR, type, tmp, then_);
4000 /* Similarly, build the new else clause, `tmp = else_;'. */
4001 if (!VOID_TYPE_P (TREE_TYPE (else_)))
4002 TREE_OPERAND (expr, 2) = build2 (MODIFY_EXPR, type, tmp, else_);
4004 TREE_TYPE (expr) = void_type_node;
4005 recalculate_side_effects (expr);
4007 /* Move the COND_EXPR to the prequeue. */
4008 gimplify_stmt (&expr, pre_p);
4010 *expr_p = result;
4011 return GS_ALL_DONE;
4014 /* Remove any COMPOUND_EXPR so the following cases will be caught. */
4015 STRIP_TYPE_NOPS (TREE_OPERAND (expr, 0));
4016 if (TREE_CODE (TREE_OPERAND (expr, 0)) == COMPOUND_EXPR)
4017 gimplify_compound_expr (&TREE_OPERAND (expr, 0), pre_p, true);
4019 /* Make sure the condition has BOOLEAN_TYPE. */
4020 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
4022 /* Break apart && and || conditions. */
4023 if (TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ANDIF_EXPR
4024 || TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ORIF_EXPR)
4026 expr = shortcut_cond_expr (expr);
4028 if (expr != *expr_p)
4030 *expr_p = expr;
4032 /* We can't rely on gimplify_expr to re-gimplify the expanded
4033 form properly, as cleanups might cause the target labels to be
4034 wrapped in a TRY_FINALLY_EXPR. To prevent that, we need to
4035 set up a conditional context. */
4036 gimple_push_condition ();
4037 gimplify_stmt (expr_p, &seq);
4038 gimple_pop_condition (pre_p);
4039 gimple_seq_add_seq (pre_p, seq);
4041 return GS_ALL_DONE;
4045 /* Now do the normal gimplification. */
4047 /* Gimplify condition. */
4048 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL, is_gimple_condexpr,
4049 fb_rvalue);
4050 if (ret == GS_ERROR)
4051 return GS_ERROR;
4052 gcc_assert (TREE_OPERAND (expr, 0) != NULL_TREE);
4054 gimple_push_condition ();
4056 have_then_clause_p = have_else_clause_p = false;
4057 label_true = find_goto_label (TREE_OPERAND (expr, 1));
4058 if (label_true
4059 && DECL_CONTEXT (GOTO_DESTINATION (label_true)) == current_function_decl
4060 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4061 have different locations, otherwise we end up with incorrect
4062 location information on the branches. */
4063 && (optimize
4064 || !EXPR_HAS_LOCATION (expr)
4065 || !rexpr_has_location (label_true)
4066 || EXPR_LOCATION (expr) == rexpr_location (label_true)))
4068 have_then_clause_p = true;
4069 label_true = GOTO_DESTINATION (label_true);
4071 else
4072 label_true = create_artificial_label (UNKNOWN_LOCATION);
4073 label_false = find_goto_label (TREE_OPERAND (expr, 2));
4074 if (label_false
4075 && DECL_CONTEXT (GOTO_DESTINATION (label_false)) == current_function_decl
4076 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4077 have different locations, otherwise we end up with incorrect
4078 location information on the branches. */
4079 && (optimize
4080 || !EXPR_HAS_LOCATION (expr)
4081 || !rexpr_has_location (label_false)
4082 || EXPR_LOCATION (expr) == rexpr_location (label_false)))
4084 have_else_clause_p = true;
4085 label_false = GOTO_DESTINATION (label_false);
4087 else
4088 label_false = create_artificial_label (UNKNOWN_LOCATION);
4090 gimple_cond_get_ops_from_tree (COND_EXPR_COND (expr), &pred_code, &arm1,
4091 &arm2);
4092 cond_stmt = gimple_build_cond (pred_code, arm1, arm2, label_true,
4093 label_false);
4094 gimple_set_no_warning (cond_stmt, TREE_NO_WARNING (COND_EXPR_COND (expr)));
4095 gimplify_seq_add_stmt (&seq, cond_stmt);
4096 gimple_stmt_iterator gsi = gsi_last (seq);
4097 maybe_fold_stmt (&gsi);
4099 label_cont = NULL_TREE;
4100 if (!have_then_clause_p)
4102 /* For if (...) {} else { code; } put label_true after
4103 the else block. */
4104 if (TREE_OPERAND (expr, 1) == NULL_TREE
4105 && !have_else_clause_p
4106 && TREE_OPERAND (expr, 2) != NULL_TREE)
4107 label_cont = label_true;
4108 else
4110 gimplify_seq_add_stmt (&seq, gimple_build_label (label_true));
4111 have_then_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 1), &seq);
4112 /* For if (...) { code; } else {} or
4113 if (...) { code; } else goto label; or
4114 if (...) { code; return; } else { ... }
4115 label_cont isn't needed. */
4116 if (!have_else_clause_p
4117 && TREE_OPERAND (expr, 2) != NULL_TREE
4118 && gimple_seq_may_fallthru (seq))
4120 gimple *g;
4121 label_cont = create_artificial_label (UNKNOWN_LOCATION);
4123 g = gimple_build_goto (label_cont);
4125 /* GIMPLE_COND's are very low level; they have embedded
4126 gotos. This particular embedded goto should not be marked
4127 with the location of the original COND_EXPR, as it would
4128 correspond to the COND_EXPR's condition, not the ELSE or the
4129 THEN arms. To avoid marking it with the wrong location, flag
4130 it as "no location". */
4131 gimple_set_do_not_emit_location (g);
4133 gimplify_seq_add_stmt (&seq, g);
4137 if (!have_else_clause_p)
4139 gimplify_seq_add_stmt (&seq, gimple_build_label (label_false));
4140 have_else_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 2), &seq);
4142 if (label_cont)
4143 gimplify_seq_add_stmt (&seq, gimple_build_label (label_cont));
4145 gimple_pop_condition (pre_p);
4146 gimple_seq_add_seq (pre_p, seq);
4148 if (ret == GS_ERROR)
4149 ; /* Do nothing. */
4150 else if (have_then_clause_p || have_else_clause_p)
4151 ret = GS_ALL_DONE;
4152 else
4154 /* Both arms are empty; replace the COND_EXPR with its predicate. */
4155 expr = TREE_OPERAND (expr, 0);
4156 gimplify_stmt (&expr, pre_p);
4159 *expr_p = NULL;
4160 return ret;
4163 /* Prepare the node pointed to by EXPR_P, an is_gimple_addressable expression,
4164 to be marked addressable.
4166 We cannot rely on such an expression being directly markable if a temporary
4167 has been created by the gimplification. In this case, we create another
4168 temporary and initialize it with a copy, which will become a store after we
4169 mark it addressable. This can happen if the front-end passed us something
4170 that it could not mark addressable yet, like a Fortran pass-by-reference
4171 parameter (int) floatvar. */
4173 static void
4174 prepare_gimple_addressable (tree *expr_p, gimple_seq *seq_p)
4176 while (handled_component_p (*expr_p))
4177 expr_p = &TREE_OPERAND (*expr_p, 0);
4178 if (is_gimple_reg (*expr_p))
4180 /* Do not allow an SSA name as the temporary. */
4181 tree var = get_initialized_tmp_var (*expr_p, seq_p, NULL, false);
4182 DECL_GIMPLE_REG_P (var) = 0;
4183 *expr_p = var;
4187 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4188 a call to __builtin_memcpy. */
4190 static enum gimplify_status
4191 gimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value,
4192 gimple_seq *seq_p)
4194 tree t, to, to_ptr, from, from_ptr;
4195 gcall *gs;
4196 location_t loc = EXPR_LOCATION (*expr_p);
4198 to = TREE_OPERAND (*expr_p, 0);
4199 from = TREE_OPERAND (*expr_p, 1);
4201 /* Mark the RHS addressable. Beware that it may not be possible to do so
4202 directly if a temporary has been created by the gimplification. */
4203 prepare_gimple_addressable (&from, seq_p);
4205 mark_addressable (from);
4206 from_ptr = build_fold_addr_expr_loc (loc, from);
4207 gimplify_arg (&from_ptr, seq_p, loc);
4209 mark_addressable (to);
4210 to_ptr = build_fold_addr_expr_loc (loc, to);
4211 gimplify_arg (&to_ptr, seq_p, loc);
4213 t = builtin_decl_implicit (BUILT_IN_MEMCPY);
4215 gs = gimple_build_call (t, 3, to_ptr, from_ptr, size);
4217 if (want_value)
4219 /* tmp = memcpy() */
4220 t = create_tmp_var (TREE_TYPE (to_ptr));
4221 gimple_call_set_lhs (gs, t);
4222 gimplify_seq_add_stmt (seq_p, gs);
4224 *expr_p = build_simple_mem_ref (t);
4225 return GS_ALL_DONE;
4228 gimplify_seq_add_stmt (seq_p, gs);
4229 *expr_p = NULL;
4230 return GS_ALL_DONE;
4233 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4234 a call to __builtin_memset. In this case we know that the RHS is
4235 a CONSTRUCTOR with an empty element list. */
4237 static enum gimplify_status
4238 gimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value,
4239 gimple_seq *seq_p)
4241 tree t, from, to, to_ptr;
4242 gcall *gs;
4243 location_t loc = EXPR_LOCATION (*expr_p);
4245 /* Assert our assumptions, to abort instead of producing wrong code
4246 silently if they are not met. Beware that the RHS CONSTRUCTOR might
4247 not be immediately exposed. */
4248 from = TREE_OPERAND (*expr_p, 1);
4249 if (TREE_CODE (from) == WITH_SIZE_EXPR)
4250 from = TREE_OPERAND (from, 0);
4252 gcc_assert (TREE_CODE (from) == CONSTRUCTOR
4253 && vec_safe_is_empty (CONSTRUCTOR_ELTS (from)));
4255 /* Now proceed. */
4256 to = TREE_OPERAND (*expr_p, 0);
4258 to_ptr = build_fold_addr_expr_loc (loc, to);
4259 gimplify_arg (&to_ptr, seq_p, loc);
4260 t = builtin_decl_implicit (BUILT_IN_MEMSET);
4262 gs = gimple_build_call (t, 3, to_ptr, integer_zero_node, size);
4264 if (want_value)
4266 /* tmp = memset() */
4267 t = create_tmp_var (TREE_TYPE (to_ptr));
4268 gimple_call_set_lhs (gs, t);
4269 gimplify_seq_add_stmt (seq_p, gs);
4271 *expr_p = build1 (INDIRECT_REF, TREE_TYPE (to), t);
4272 return GS_ALL_DONE;
4275 gimplify_seq_add_stmt (seq_p, gs);
4276 *expr_p = NULL;
4277 return GS_ALL_DONE;
4280 /* A subroutine of gimplify_init_ctor_preeval. Called via walk_tree,
4281 determine, cautiously, if a CONSTRUCTOR overlaps the lhs of an
4282 assignment. Return non-null if we detect a potential overlap. */
4284 struct gimplify_init_ctor_preeval_data
4286 /* The base decl of the lhs object. May be NULL, in which case we
4287 have to assume the lhs is indirect. */
4288 tree lhs_base_decl;
4290 /* The alias set of the lhs object. */
4291 alias_set_type lhs_alias_set;
4294 static tree
4295 gimplify_init_ctor_preeval_1 (tree *tp, int *walk_subtrees, void *xdata)
4297 struct gimplify_init_ctor_preeval_data *data
4298 = (struct gimplify_init_ctor_preeval_data *) xdata;
4299 tree t = *tp;
4301 /* If we find the base object, obviously we have overlap. */
4302 if (data->lhs_base_decl == t)
4303 return t;
4305 /* If the constructor component is indirect, determine if we have a
4306 potential overlap with the lhs. The only bits of information we
4307 have to go on at this point are addressability and alias sets. */
4308 if ((INDIRECT_REF_P (t)
4309 || TREE_CODE (t) == MEM_REF)
4310 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
4311 && alias_sets_conflict_p (data->lhs_alias_set, get_alias_set (t)))
4312 return t;
4314 /* If the constructor component is a call, determine if it can hide a
4315 potential overlap with the lhs through an INDIRECT_REF like above.
4316 ??? Ugh - this is completely broken. In fact this whole analysis
4317 doesn't look conservative. */
4318 if (TREE_CODE (t) == CALL_EXPR)
4320 tree type, fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (t)));
4322 for (type = TYPE_ARG_TYPES (fntype); type; type = TREE_CHAIN (type))
4323 if (POINTER_TYPE_P (TREE_VALUE (type))
4324 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
4325 && alias_sets_conflict_p (data->lhs_alias_set,
4326 get_alias_set
4327 (TREE_TYPE (TREE_VALUE (type)))))
4328 return t;
4331 if (IS_TYPE_OR_DECL_P (t))
4332 *walk_subtrees = 0;
4333 return NULL;
4336 /* A subroutine of gimplify_init_constructor. Pre-evaluate EXPR,
4337 force values that overlap with the lhs (as described by *DATA)
4338 into temporaries. */
4340 static void
4341 gimplify_init_ctor_preeval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
4342 struct gimplify_init_ctor_preeval_data *data)
4344 enum gimplify_status one;
4346 /* If the value is constant, then there's nothing to pre-evaluate. */
4347 if (TREE_CONSTANT (*expr_p))
4349 /* Ensure it does not have side effects, it might contain a reference to
4350 the object we're initializing. */
4351 gcc_assert (!TREE_SIDE_EFFECTS (*expr_p));
4352 return;
4355 /* If the type has non-trivial constructors, we can't pre-evaluate. */
4356 if (TREE_ADDRESSABLE (TREE_TYPE (*expr_p)))
4357 return;
4359 /* Recurse for nested constructors. */
4360 if (TREE_CODE (*expr_p) == CONSTRUCTOR)
4362 unsigned HOST_WIDE_INT ix;
4363 constructor_elt *ce;
4364 vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (*expr_p);
4366 FOR_EACH_VEC_SAFE_ELT (v, ix, ce)
4367 gimplify_init_ctor_preeval (&ce->value, pre_p, post_p, data);
4369 return;
4372 /* If this is a variable sized type, we must remember the size. */
4373 maybe_with_size_expr (expr_p);
4375 /* Gimplify the constructor element to something appropriate for the rhs
4376 of a MODIFY_EXPR. Given that we know the LHS is an aggregate, we know
4377 the gimplifier will consider this a store to memory. Doing this
4378 gimplification now means that we won't have to deal with complicated
4379 language-specific trees, nor trees like SAVE_EXPR that can induce
4380 exponential search behavior. */
4381 one = gimplify_expr (expr_p, pre_p, post_p, is_gimple_mem_rhs, fb_rvalue);
4382 if (one == GS_ERROR)
4384 *expr_p = NULL;
4385 return;
4388 /* If we gimplified to a bare decl, we can be sure that it doesn't overlap
4389 with the lhs, since "a = { .x=a }" doesn't make sense. This will
4390 always be true for all scalars, since is_gimple_mem_rhs insists on a
4391 temporary variable for them. */
4392 if (DECL_P (*expr_p))
4393 return;
4395 /* If this is of variable size, we have no choice but to assume it doesn't
4396 overlap since we can't make a temporary for it. */
4397 if (TREE_CODE (TYPE_SIZE (TREE_TYPE (*expr_p))) != INTEGER_CST)
4398 return;
4400 /* Otherwise, we must search for overlap ... */
4401 if (!walk_tree (expr_p, gimplify_init_ctor_preeval_1, data, NULL))
4402 return;
4404 /* ... and if found, force the value into a temporary. */
4405 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
4408 /* A subroutine of gimplify_init_ctor_eval. Create a loop for
4409 a RANGE_EXPR in a CONSTRUCTOR for an array.
4411 var = lower;
4412 loop_entry:
4413 object[var] = value;
4414 if (var == upper)
4415 goto loop_exit;
4416 var = var + 1;
4417 goto loop_entry;
4418 loop_exit:
4420 We increment var _after_ the loop exit check because we might otherwise
4421 fail if upper == TYPE_MAX_VALUE (type for upper).
4423 Note that we never have to deal with SAVE_EXPRs here, because this has
4424 already been taken care of for us, in gimplify_init_ctor_preeval(). */
4426 static void gimplify_init_ctor_eval (tree, vec<constructor_elt, va_gc> *,
4427 gimple_seq *, bool);
4429 static void
4430 gimplify_init_ctor_eval_range (tree object, tree lower, tree upper,
4431 tree value, tree array_elt_type,
4432 gimple_seq *pre_p, bool cleared)
4434 tree loop_entry_label, loop_exit_label, fall_thru_label;
4435 tree var, var_type, cref, tmp;
4437 loop_entry_label = create_artificial_label (UNKNOWN_LOCATION);
4438 loop_exit_label = create_artificial_label (UNKNOWN_LOCATION);
4439 fall_thru_label = create_artificial_label (UNKNOWN_LOCATION);
4441 /* Create and initialize the index variable. */
4442 var_type = TREE_TYPE (upper);
4443 var = create_tmp_var (var_type);
4444 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, lower));
4446 /* Add the loop entry label. */
4447 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_entry_label));
4449 /* Build the reference. */
4450 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
4451 var, NULL_TREE, NULL_TREE);
4453 /* If we are a constructor, just call gimplify_init_ctor_eval to do
4454 the store. Otherwise just assign value to the reference. */
4456 if (TREE_CODE (value) == CONSTRUCTOR)
4457 /* NB we might have to call ourself recursively through
4458 gimplify_init_ctor_eval if the value is a constructor. */
4459 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
4460 pre_p, cleared);
4461 else
4462 gimplify_seq_add_stmt (pre_p, gimple_build_assign (cref, value));
4464 /* We exit the loop when the index var is equal to the upper bound. */
4465 gimplify_seq_add_stmt (pre_p,
4466 gimple_build_cond (EQ_EXPR, var, upper,
4467 loop_exit_label, fall_thru_label));
4469 gimplify_seq_add_stmt (pre_p, gimple_build_label (fall_thru_label));
4471 /* Otherwise, increment the index var... */
4472 tmp = build2 (PLUS_EXPR, var_type, var,
4473 fold_convert (var_type, integer_one_node));
4474 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, tmp));
4476 /* ...and jump back to the loop entry. */
4477 gimplify_seq_add_stmt (pre_p, gimple_build_goto (loop_entry_label));
4479 /* Add the loop exit label. */
4480 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_exit_label));
4483 /* Return true if FDECL is accessing a field that is zero sized. */
4485 static bool
4486 zero_sized_field_decl (const_tree fdecl)
4488 if (TREE_CODE (fdecl) == FIELD_DECL && DECL_SIZE (fdecl)
4489 && integer_zerop (DECL_SIZE (fdecl)))
4490 return true;
4491 return false;
4494 /* Return true if TYPE is zero sized. */
4496 static bool
4497 zero_sized_type (const_tree type)
4499 if (AGGREGATE_TYPE_P (type) && TYPE_SIZE (type)
4500 && integer_zerop (TYPE_SIZE (type)))
4501 return true;
4502 return false;
4505 /* A subroutine of gimplify_init_constructor. Generate individual
4506 MODIFY_EXPRs for a CONSTRUCTOR. OBJECT is the LHS against which the
4507 assignments should happen. ELTS is the CONSTRUCTOR_ELTS of the
4508 CONSTRUCTOR. CLEARED is true if the entire LHS object has been
4509 zeroed first. */
4511 static void
4512 gimplify_init_ctor_eval (tree object, vec<constructor_elt, va_gc> *elts,
4513 gimple_seq *pre_p, bool cleared)
4515 tree array_elt_type = NULL;
4516 unsigned HOST_WIDE_INT ix;
4517 tree purpose, value;
4519 if (TREE_CODE (TREE_TYPE (object)) == ARRAY_TYPE)
4520 array_elt_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (object)));
4522 FOR_EACH_CONSTRUCTOR_ELT (elts, ix, purpose, value)
4524 tree cref;
4526 /* NULL values are created above for gimplification errors. */
4527 if (value == NULL)
4528 continue;
4530 if (cleared && initializer_zerop (value))
4531 continue;
4533 /* ??? Here's to hoping the front end fills in all of the indices,
4534 so we don't have to figure out what's missing ourselves. */
4535 gcc_assert (purpose);
4537 /* Skip zero-sized fields, unless value has side-effects. This can
4538 happen with calls to functions returning a zero-sized type, which
4539 we shouldn't discard. As a number of downstream passes don't
4540 expect sets of zero-sized fields, we rely on the gimplification of
4541 the MODIFY_EXPR we make below to drop the assignment statement. */
4542 if (! TREE_SIDE_EFFECTS (value) && zero_sized_field_decl (purpose))
4543 continue;
4545 /* If we have a RANGE_EXPR, we have to build a loop to assign the
4546 whole range. */
4547 if (TREE_CODE (purpose) == RANGE_EXPR)
4549 tree lower = TREE_OPERAND (purpose, 0);
4550 tree upper = TREE_OPERAND (purpose, 1);
4552 /* If the lower bound is equal to upper, just treat it as if
4553 upper was the index. */
4554 if (simple_cst_equal (lower, upper))
4555 purpose = upper;
4556 else
4558 gimplify_init_ctor_eval_range (object, lower, upper, value,
4559 array_elt_type, pre_p, cleared);
4560 continue;
4564 if (array_elt_type)
4566 /* Do not use bitsizetype for ARRAY_REF indices. */
4567 if (TYPE_DOMAIN (TREE_TYPE (object)))
4568 purpose
4569 = fold_convert (TREE_TYPE (TYPE_DOMAIN (TREE_TYPE (object))),
4570 purpose);
4571 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
4572 purpose, NULL_TREE, NULL_TREE);
4574 else
4576 gcc_assert (TREE_CODE (purpose) == FIELD_DECL);
4577 cref = build3 (COMPONENT_REF, TREE_TYPE (purpose),
4578 unshare_expr (object), purpose, NULL_TREE);
4581 if (TREE_CODE (value) == CONSTRUCTOR
4582 && TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE)
4583 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
4584 pre_p, cleared);
4585 else
4587 tree init = build2 (INIT_EXPR, TREE_TYPE (cref), cref, value);
4588 gimplify_and_add (init, pre_p);
4589 ggc_free (init);
4594 /* Return the appropriate RHS predicate for this LHS. */
4596 gimple_predicate
4597 rhs_predicate_for (tree lhs)
4599 if (is_gimple_reg (lhs))
4600 return is_gimple_reg_rhs_or_call;
4601 else
4602 return is_gimple_mem_rhs_or_call;
4605 /* Return the initial guess for an appropriate RHS predicate for this LHS,
4606 before the LHS has been gimplified. */
4608 static gimple_predicate
4609 initial_rhs_predicate_for (tree lhs)
4611 if (is_gimple_reg_type (TREE_TYPE (lhs)))
4612 return is_gimple_reg_rhs_or_call;
4613 else
4614 return is_gimple_mem_rhs_or_call;
4617 /* Gimplify a C99 compound literal expression. This just means adding
4618 the DECL_EXPR before the current statement and using its anonymous
4619 decl instead. */
4621 static enum gimplify_status
4622 gimplify_compound_literal_expr (tree *expr_p, gimple_seq *pre_p,
4623 bool (*gimple_test_f) (tree),
4624 fallback_t fallback)
4626 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (*expr_p);
4627 tree decl = DECL_EXPR_DECL (decl_s);
4628 tree init = DECL_INITIAL (decl);
4629 /* Mark the decl as addressable if the compound literal
4630 expression is addressable now, otherwise it is marked too late
4631 after we gimplify the initialization expression. */
4632 if (TREE_ADDRESSABLE (*expr_p))
4633 TREE_ADDRESSABLE (decl) = 1;
4634 /* Otherwise, if we don't need an lvalue and have a literal directly
4635 substitute it. Check if it matches the gimple predicate, as
4636 otherwise we'd generate a new temporary, and we can as well just
4637 use the decl we already have. */
4638 else if (!TREE_ADDRESSABLE (decl)
4639 && init
4640 && (fallback & fb_lvalue) == 0
4641 && gimple_test_f (init))
4643 *expr_p = init;
4644 return GS_OK;
4647 /* Preliminarily mark non-addressed complex variables as eligible
4648 for promotion to gimple registers. We'll transform their uses
4649 as we find them. */
4650 if ((TREE_CODE (TREE_TYPE (decl)) == COMPLEX_TYPE
4651 || TREE_CODE (TREE_TYPE (decl)) == VECTOR_TYPE)
4652 && !TREE_THIS_VOLATILE (decl)
4653 && !needs_to_live_in_memory (decl))
4654 DECL_GIMPLE_REG_P (decl) = 1;
4656 /* If the decl is not addressable, then it is being used in some
4657 expression or on the right hand side of a statement, and it can
4658 be put into a readonly data section. */
4659 if (!TREE_ADDRESSABLE (decl) && (fallback & fb_lvalue) == 0)
4660 TREE_READONLY (decl) = 1;
4662 /* This decl isn't mentioned in the enclosing block, so add it to the
4663 list of temps. FIXME it seems a bit of a kludge to say that
4664 anonymous artificial vars aren't pushed, but everything else is. */
4665 if (DECL_NAME (decl) == NULL_TREE && !DECL_SEEN_IN_BIND_EXPR_P (decl))
4666 gimple_add_tmp_var (decl);
4668 gimplify_and_add (decl_s, pre_p);
4669 *expr_p = decl;
4670 return GS_OK;
4673 /* Optimize embedded COMPOUND_LITERAL_EXPRs within a CONSTRUCTOR,
4674 return a new CONSTRUCTOR if something changed. */
4676 static tree
4677 optimize_compound_literals_in_ctor (tree orig_ctor)
4679 tree ctor = orig_ctor;
4680 vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ctor);
4681 unsigned int idx, num = vec_safe_length (elts);
4683 for (idx = 0; idx < num; idx++)
4685 tree value = (*elts)[idx].value;
4686 tree newval = value;
4687 if (TREE_CODE (value) == CONSTRUCTOR)
4688 newval = optimize_compound_literals_in_ctor (value);
4689 else if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR)
4691 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (value);
4692 tree decl = DECL_EXPR_DECL (decl_s);
4693 tree init = DECL_INITIAL (decl);
4695 if (!TREE_ADDRESSABLE (value)
4696 && !TREE_ADDRESSABLE (decl)
4697 && init
4698 && TREE_CODE (init) == CONSTRUCTOR)
4699 newval = optimize_compound_literals_in_ctor (init);
4701 if (newval == value)
4702 continue;
4704 if (ctor == orig_ctor)
4706 ctor = copy_node (orig_ctor);
4707 CONSTRUCTOR_ELTS (ctor) = vec_safe_copy (elts);
4708 elts = CONSTRUCTOR_ELTS (ctor);
4710 (*elts)[idx].value = newval;
4712 return ctor;
4715 /* A subroutine of gimplify_modify_expr. Break out elements of a
4716 CONSTRUCTOR used as an initializer into separate MODIFY_EXPRs.
4718 Note that we still need to clear any elements that don't have explicit
4719 initializers, so if not all elements are initialized we keep the
4720 original MODIFY_EXPR, we just remove all of the constructor elements.
4722 If NOTIFY_TEMP_CREATION is true, do not gimplify, just return
4723 GS_ERROR if we would have to create a temporary when gimplifying
4724 this constructor. Otherwise, return GS_OK.
4726 If NOTIFY_TEMP_CREATION is false, just do the gimplification. */
4728 static enum gimplify_status
4729 gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
4730 bool want_value, bool notify_temp_creation)
4732 tree object, ctor, type;
4733 enum gimplify_status ret;
4734 vec<constructor_elt, va_gc> *elts;
4736 gcc_assert (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == CONSTRUCTOR);
4738 if (!notify_temp_creation)
4740 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
4741 is_gimple_lvalue, fb_lvalue);
4742 if (ret == GS_ERROR)
4743 return ret;
4746 object = TREE_OPERAND (*expr_p, 0);
4747 ctor = TREE_OPERAND (*expr_p, 1)
4748 = optimize_compound_literals_in_ctor (TREE_OPERAND (*expr_p, 1));
4749 type = TREE_TYPE (ctor);
4750 elts = CONSTRUCTOR_ELTS (ctor);
4751 ret = GS_ALL_DONE;
4753 switch (TREE_CODE (type))
4755 case RECORD_TYPE:
4756 case UNION_TYPE:
4757 case QUAL_UNION_TYPE:
4758 case ARRAY_TYPE:
4760 struct gimplify_init_ctor_preeval_data preeval_data;
4761 HOST_WIDE_INT num_ctor_elements, num_nonzero_elements;
4762 bool cleared, complete_p, valid_const_initializer;
4764 /* Aggregate types must lower constructors to initialization of
4765 individual elements. The exception is that a CONSTRUCTOR node
4766 with no elements indicates zero-initialization of the whole. */
4767 if (vec_safe_is_empty (elts))
4769 if (notify_temp_creation)
4770 return GS_OK;
4771 break;
4774 /* Fetch information about the constructor to direct later processing.
4775 We might want to make static versions of it in various cases, and
4776 can only do so if it known to be a valid constant initializer. */
4777 valid_const_initializer
4778 = categorize_ctor_elements (ctor, &num_nonzero_elements,
4779 &num_ctor_elements, &complete_p);
4781 /* If a const aggregate variable is being initialized, then it
4782 should never be a lose to promote the variable to be static. */
4783 if (valid_const_initializer
4784 && num_nonzero_elements > 1
4785 && TREE_READONLY (object)
4786 && VAR_P (object)
4787 && (flag_merge_constants >= 2 || !TREE_ADDRESSABLE (object)))
4789 if (notify_temp_creation)
4790 return GS_ERROR;
4791 DECL_INITIAL (object) = ctor;
4792 TREE_STATIC (object) = 1;
4793 if (!DECL_NAME (object))
4794 DECL_NAME (object) = create_tmp_var_name ("C");
4795 walk_tree (&DECL_INITIAL (object), force_labels_r, NULL, NULL);
4797 /* ??? C++ doesn't automatically append a .<number> to the
4798 assembler name, and even when it does, it looks at FE private
4799 data structures to figure out what that number should be,
4800 which are not set for this variable. I suppose this is
4801 important for local statics for inline functions, which aren't
4802 "local" in the object file sense. So in order to get a unique
4803 TU-local symbol, we must invoke the lhd version now. */
4804 lhd_set_decl_assembler_name (object);
4806 *expr_p = NULL_TREE;
4807 break;
4810 /* If there are "lots" of initialized elements, even discounting
4811 those that are not address constants (and thus *must* be
4812 computed at runtime), then partition the constructor into
4813 constant and non-constant parts. Block copy the constant
4814 parts in, then generate code for the non-constant parts. */
4815 /* TODO. There's code in cp/typeck.c to do this. */
4817 if (int_size_in_bytes (TREE_TYPE (ctor)) < 0)
4818 /* store_constructor will ignore the clearing of variable-sized
4819 objects. Initializers for such objects must explicitly set
4820 every field that needs to be set. */
4821 cleared = false;
4822 else if (!complete_p)
4823 /* If the constructor isn't complete, clear the whole object
4824 beforehand, unless CONSTRUCTOR_NO_CLEARING is set on it.
4826 ??? This ought not to be needed. For any element not present
4827 in the initializer, we should simply set them to zero. Except
4828 we'd need to *find* the elements that are not present, and that
4829 requires trickery to avoid quadratic compile-time behavior in
4830 large cases or excessive memory use in small cases. */
4831 cleared = !CONSTRUCTOR_NO_CLEARING (ctor);
4832 else if (num_ctor_elements - num_nonzero_elements
4833 > CLEAR_RATIO (optimize_function_for_speed_p (cfun))
4834 && num_nonzero_elements < num_ctor_elements / 4)
4835 /* If there are "lots" of zeros, it's more efficient to clear
4836 the memory and then set the nonzero elements. */
4837 cleared = true;
4838 else
4839 cleared = false;
4841 /* If there are "lots" of initialized elements, and all of them
4842 are valid address constants, then the entire initializer can
4843 be dropped to memory, and then memcpy'd out. Don't do this
4844 for sparse arrays, though, as it's more efficient to follow
4845 the standard CONSTRUCTOR behavior of memset followed by
4846 individual element initialization. Also don't do this for small
4847 all-zero initializers (which aren't big enough to merit
4848 clearing), and don't try to make bitwise copies of
4849 TREE_ADDRESSABLE types. */
4851 if (valid_const_initializer
4852 && !(cleared || num_nonzero_elements == 0)
4853 && !TREE_ADDRESSABLE (type))
4855 HOST_WIDE_INT size = int_size_in_bytes (type);
4856 unsigned int align;
4858 /* ??? We can still get unbounded array types, at least
4859 from the C++ front end. This seems wrong, but attempt
4860 to work around it for now. */
4861 if (size < 0)
4863 size = int_size_in_bytes (TREE_TYPE (object));
4864 if (size >= 0)
4865 TREE_TYPE (ctor) = type = TREE_TYPE (object);
4868 /* Find the maximum alignment we can assume for the object. */
4869 /* ??? Make use of DECL_OFFSET_ALIGN. */
4870 if (DECL_P (object))
4871 align = DECL_ALIGN (object);
4872 else
4873 align = TYPE_ALIGN (type);
4875 /* Do a block move either if the size is so small as to make
4876 each individual move a sub-unit move on average, or if it
4877 is so large as to make individual moves inefficient. */
4878 if (size > 0
4879 && num_nonzero_elements > 1
4880 && (size < num_nonzero_elements
4881 || !can_move_by_pieces (size, align)))
4883 if (notify_temp_creation)
4884 return GS_ERROR;
4886 walk_tree (&ctor, force_labels_r, NULL, NULL);
4887 ctor = tree_output_constant_def (ctor);
4888 if (!useless_type_conversion_p (type, TREE_TYPE (ctor)))
4889 ctor = build1 (VIEW_CONVERT_EXPR, type, ctor);
4890 TREE_OPERAND (*expr_p, 1) = ctor;
4892 /* This is no longer an assignment of a CONSTRUCTOR, but
4893 we still may have processing to do on the LHS. So
4894 pretend we didn't do anything here to let that happen. */
4895 return GS_UNHANDLED;
4899 /* If the target is volatile, we have non-zero elements and more than
4900 one field to assign, initialize the target from a temporary. */
4901 if (TREE_THIS_VOLATILE (object)
4902 && !TREE_ADDRESSABLE (type)
4903 && num_nonzero_elements > 0
4904 && vec_safe_length (elts) > 1)
4906 tree temp = create_tmp_var (TYPE_MAIN_VARIANT (type));
4907 TREE_OPERAND (*expr_p, 0) = temp;
4908 *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p),
4909 *expr_p,
4910 build2 (MODIFY_EXPR, void_type_node,
4911 object, temp));
4912 return GS_OK;
4915 if (notify_temp_creation)
4916 return GS_OK;
4918 /* If there are nonzero elements and if needed, pre-evaluate to capture
4919 elements overlapping with the lhs into temporaries. We must do this
4920 before clearing to fetch the values before they are zeroed-out. */
4921 if (num_nonzero_elements > 0 && TREE_CODE (*expr_p) != INIT_EXPR)
4923 preeval_data.lhs_base_decl = get_base_address (object);
4924 if (!DECL_P (preeval_data.lhs_base_decl))
4925 preeval_data.lhs_base_decl = NULL;
4926 preeval_data.lhs_alias_set = get_alias_set (object);
4928 gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p, 1),
4929 pre_p, post_p, &preeval_data);
4932 bool ctor_has_side_effects_p
4933 = TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p, 1));
4935 if (cleared)
4937 /* Zap the CONSTRUCTOR element list, which simplifies this case.
4938 Note that we still have to gimplify, in order to handle the
4939 case of variable sized types. Avoid shared tree structures. */
4940 CONSTRUCTOR_ELTS (ctor) = NULL;
4941 TREE_SIDE_EFFECTS (ctor) = 0;
4942 object = unshare_expr (object);
4943 gimplify_stmt (expr_p, pre_p);
4946 /* If we have not block cleared the object, or if there are nonzero
4947 elements in the constructor, or if the constructor has side effects,
4948 add assignments to the individual scalar fields of the object. */
4949 if (!cleared
4950 || num_nonzero_elements > 0
4951 || ctor_has_side_effects_p)
4952 gimplify_init_ctor_eval (object, elts, pre_p, cleared);
4954 *expr_p = NULL_TREE;
4956 break;
4958 case COMPLEX_TYPE:
4960 tree r, i;
4962 if (notify_temp_creation)
4963 return GS_OK;
4965 /* Extract the real and imaginary parts out of the ctor. */
4966 gcc_assert (elts->length () == 2);
4967 r = (*elts)[0].value;
4968 i = (*elts)[1].value;
4969 if (r == NULL || i == NULL)
4971 tree zero = build_zero_cst (TREE_TYPE (type));
4972 if (r == NULL)
4973 r = zero;
4974 if (i == NULL)
4975 i = zero;
4978 /* Complex types have either COMPLEX_CST or COMPLEX_EXPR to
4979 represent creation of a complex value. */
4980 if (TREE_CONSTANT (r) && TREE_CONSTANT (i))
4982 ctor = build_complex (type, r, i);
4983 TREE_OPERAND (*expr_p, 1) = ctor;
4985 else
4987 ctor = build2 (COMPLEX_EXPR, type, r, i);
4988 TREE_OPERAND (*expr_p, 1) = ctor;
4989 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 1),
4990 pre_p,
4991 post_p,
4992 rhs_predicate_for (TREE_OPERAND (*expr_p, 0)),
4993 fb_rvalue);
4996 break;
4998 case VECTOR_TYPE:
5000 unsigned HOST_WIDE_INT ix;
5001 constructor_elt *ce;
5003 if (notify_temp_creation)
5004 return GS_OK;
5006 /* Go ahead and simplify constant constructors to VECTOR_CST. */
5007 if (TREE_CONSTANT (ctor))
5009 bool constant_p = true;
5010 tree value;
5012 /* Even when ctor is constant, it might contain non-*_CST
5013 elements, such as addresses or trapping values like
5014 1.0/0.0 - 1.0/0.0. Such expressions don't belong
5015 in VECTOR_CST nodes. */
5016 FOR_EACH_CONSTRUCTOR_VALUE (elts, ix, value)
5017 if (!CONSTANT_CLASS_P (value))
5019 constant_p = false;
5020 break;
5023 if (constant_p)
5025 TREE_OPERAND (*expr_p, 1) = build_vector_from_ctor (type, elts);
5026 break;
5029 TREE_CONSTANT (ctor) = 0;
5032 /* Vector types use CONSTRUCTOR all the way through gimple
5033 compilation as a general initializer. */
5034 FOR_EACH_VEC_SAFE_ELT (elts, ix, ce)
5036 enum gimplify_status tret;
5037 tret = gimplify_expr (&ce->value, pre_p, post_p, is_gimple_val,
5038 fb_rvalue);
5039 if (tret == GS_ERROR)
5040 ret = GS_ERROR;
5041 else if (TREE_STATIC (ctor)
5042 && !initializer_constant_valid_p (ce->value,
5043 TREE_TYPE (ce->value)))
5044 TREE_STATIC (ctor) = 0;
5046 if (!is_gimple_reg (TREE_OPERAND (*expr_p, 0)))
5047 TREE_OPERAND (*expr_p, 1) = get_formal_tmp_var (ctor, pre_p);
5049 break;
5051 default:
5052 /* So how did we get a CONSTRUCTOR for a scalar type? */
5053 gcc_unreachable ();
5056 if (ret == GS_ERROR)
5057 return GS_ERROR;
5058 /* If we have gimplified both sides of the initializer but have
5059 not emitted an assignment, do so now. */
5060 if (*expr_p)
5062 tree lhs = TREE_OPERAND (*expr_p, 0);
5063 tree rhs = TREE_OPERAND (*expr_p, 1);
5064 if (want_value && object == lhs)
5065 lhs = unshare_expr (lhs);
5066 gassign *init = gimple_build_assign (lhs, rhs);
5067 gimplify_seq_add_stmt (pre_p, init);
5069 if (want_value)
5071 *expr_p = object;
5072 return GS_OK;
5074 else
5076 *expr_p = NULL;
5077 return GS_ALL_DONE;
5081 /* Given a pointer value OP0, return a simplified version of an
5082 indirection through OP0, or NULL_TREE if no simplification is
5083 possible. This may only be applied to a rhs of an expression.
5084 Note that the resulting type may be different from the type pointed
5085 to in the sense that it is still compatible from the langhooks
5086 point of view. */
5088 static tree
5089 gimple_fold_indirect_ref_rhs (tree t)
5091 return gimple_fold_indirect_ref (t);
5094 /* Subroutine of gimplify_modify_expr to do simplifications of
5095 MODIFY_EXPRs based on the code of the RHS. We loop for as long as
5096 something changes. */
5098 static enum gimplify_status
5099 gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p,
5100 gimple_seq *pre_p, gimple_seq *post_p,
5101 bool want_value)
5103 enum gimplify_status ret = GS_UNHANDLED;
5104 bool changed;
5108 changed = false;
5109 switch (TREE_CODE (*from_p))
5111 case VAR_DECL:
5112 /* If we're assigning from a read-only variable initialized with
5113 a constructor, do the direct assignment from the constructor,
5114 but only if neither source nor target are volatile since this
5115 latter assignment might end up being done on a per-field basis. */
5116 if (DECL_INITIAL (*from_p)
5117 && TREE_READONLY (*from_p)
5118 && !TREE_THIS_VOLATILE (*from_p)
5119 && !TREE_THIS_VOLATILE (*to_p)
5120 && TREE_CODE (DECL_INITIAL (*from_p)) == CONSTRUCTOR)
5122 tree old_from = *from_p;
5123 enum gimplify_status subret;
5125 /* Move the constructor into the RHS. */
5126 *from_p = unshare_expr (DECL_INITIAL (*from_p));
5128 /* Let's see if gimplify_init_constructor will need to put
5129 it in memory. */
5130 subret = gimplify_init_constructor (expr_p, NULL, NULL,
5131 false, true);
5132 if (subret == GS_ERROR)
5134 /* If so, revert the change. */
5135 *from_p = old_from;
5137 else
5139 ret = GS_OK;
5140 changed = true;
5143 break;
5144 case INDIRECT_REF:
5146 /* If we have code like
5148 *(const A*)(A*)&x
5150 where the type of "x" is a (possibly cv-qualified variant
5151 of "A"), treat the entire expression as identical to "x".
5152 This kind of code arises in C++ when an object is bound
5153 to a const reference, and if "x" is a TARGET_EXPR we want
5154 to take advantage of the optimization below. */
5155 bool volatile_p = TREE_THIS_VOLATILE (*from_p);
5156 tree t = gimple_fold_indirect_ref_rhs (TREE_OPERAND (*from_p, 0));
5157 if (t)
5159 if (TREE_THIS_VOLATILE (t) != volatile_p)
5161 if (DECL_P (t))
5162 t = build_simple_mem_ref_loc (EXPR_LOCATION (*from_p),
5163 build_fold_addr_expr (t));
5164 if (REFERENCE_CLASS_P (t))
5165 TREE_THIS_VOLATILE (t) = volatile_p;
5167 *from_p = t;
5168 ret = GS_OK;
5169 changed = true;
5171 break;
5174 case TARGET_EXPR:
5176 /* If we are initializing something from a TARGET_EXPR, strip the
5177 TARGET_EXPR and initialize it directly, if possible. This can't
5178 be done if the initializer is void, since that implies that the
5179 temporary is set in some non-trivial way.
5181 ??? What about code that pulls out the temp and uses it
5182 elsewhere? I think that such code never uses the TARGET_EXPR as
5183 an initializer. If I'm wrong, we'll die because the temp won't
5184 have any RTL. In that case, I guess we'll need to replace
5185 references somehow. */
5186 tree init = TARGET_EXPR_INITIAL (*from_p);
5188 if (init
5189 && (TREE_CODE (*expr_p) != MODIFY_EXPR
5190 || !TARGET_EXPR_NO_ELIDE (*from_p))
5191 && !VOID_TYPE_P (TREE_TYPE (init)))
5193 *from_p = init;
5194 ret = GS_OK;
5195 changed = true;
5198 break;
5200 case COMPOUND_EXPR:
5201 /* Remove any COMPOUND_EXPR in the RHS so the following cases will be
5202 caught. */
5203 gimplify_compound_expr (from_p, pre_p, true);
5204 ret = GS_OK;
5205 changed = true;
5206 break;
5208 case CONSTRUCTOR:
5209 /* If we already made some changes, let the front end have a
5210 crack at this before we break it down. */
5211 if (ret != GS_UNHANDLED)
5212 break;
5213 /* If we're initializing from a CONSTRUCTOR, break this into
5214 individual MODIFY_EXPRs. */
5215 return gimplify_init_constructor (expr_p, pre_p, post_p, want_value,
5216 false);
5218 case COND_EXPR:
5219 /* If we're assigning to a non-register type, push the assignment
5220 down into the branches. This is mandatory for ADDRESSABLE types,
5221 since we cannot generate temporaries for such, but it saves a
5222 copy in other cases as well. */
5223 if (!is_gimple_reg_type (TREE_TYPE (*from_p)))
5225 /* This code should mirror the code in gimplify_cond_expr. */
5226 enum tree_code code = TREE_CODE (*expr_p);
5227 tree cond = *from_p;
5228 tree result = *to_p;
5230 ret = gimplify_expr (&result, pre_p, post_p,
5231 is_gimple_lvalue, fb_lvalue);
5232 if (ret != GS_ERROR)
5233 ret = GS_OK;
5235 /* If we are going to write RESULT more than once, clear
5236 TREE_READONLY flag, otherwise we might incorrectly promote
5237 the variable to static const and initialize it at compile
5238 time in one of the branches. */
5239 if (VAR_P (result)
5240 && TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node
5241 && TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
5242 TREE_READONLY (result) = 0;
5243 if (TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node)
5244 TREE_OPERAND (cond, 1)
5245 = build2 (code, void_type_node, result,
5246 TREE_OPERAND (cond, 1));
5247 if (TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
5248 TREE_OPERAND (cond, 2)
5249 = build2 (code, void_type_node, unshare_expr (result),
5250 TREE_OPERAND (cond, 2));
5252 TREE_TYPE (cond) = void_type_node;
5253 recalculate_side_effects (cond);
5255 if (want_value)
5257 gimplify_and_add (cond, pre_p);
5258 *expr_p = unshare_expr (result);
5260 else
5261 *expr_p = cond;
5262 return ret;
5264 break;
5266 case CALL_EXPR:
5267 /* For calls that return in memory, give *to_p as the CALL_EXPR's
5268 return slot so that we don't generate a temporary. */
5269 if (!CALL_EXPR_RETURN_SLOT_OPT (*from_p)
5270 && aggregate_value_p (*from_p, *from_p))
5272 bool use_target;
5274 if (!(rhs_predicate_for (*to_p))(*from_p))
5275 /* If we need a temporary, *to_p isn't accurate. */
5276 use_target = false;
5277 /* It's OK to use the return slot directly unless it's an NRV. */
5278 else if (TREE_CODE (*to_p) == RESULT_DECL
5279 && DECL_NAME (*to_p) == NULL_TREE
5280 && needs_to_live_in_memory (*to_p))
5281 use_target = true;
5282 else if (is_gimple_reg_type (TREE_TYPE (*to_p))
5283 || (DECL_P (*to_p) && DECL_REGISTER (*to_p)))
5284 /* Don't force regs into memory. */
5285 use_target = false;
5286 else if (TREE_CODE (*expr_p) == INIT_EXPR)
5287 /* It's OK to use the target directly if it's being
5288 initialized. */
5289 use_target = true;
5290 else if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p)))
5291 != INTEGER_CST)
5292 /* Always use the target and thus RSO for variable-sized types.
5293 GIMPLE cannot deal with a variable-sized assignment
5294 embedded in a call statement. */
5295 use_target = true;
5296 else if (TREE_CODE (*to_p) != SSA_NAME
5297 && (!is_gimple_variable (*to_p)
5298 || needs_to_live_in_memory (*to_p)))
5299 /* Don't use the original target if it's already addressable;
5300 if its address escapes, and the called function uses the
5301 NRV optimization, a conforming program could see *to_p
5302 change before the called function returns; see c++/19317.
5303 When optimizing, the return_slot pass marks more functions
5304 as safe after we have escape info. */
5305 use_target = false;
5306 else
5307 use_target = true;
5309 if (use_target)
5311 CALL_EXPR_RETURN_SLOT_OPT (*from_p) = 1;
5312 mark_addressable (*to_p);
5315 break;
5317 case WITH_SIZE_EXPR:
5318 /* Likewise for calls that return an aggregate of non-constant size,
5319 since we would not be able to generate a temporary at all. */
5320 if (TREE_CODE (TREE_OPERAND (*from_p, 0)) == CALL_EXPR)
5322 *from_p = TREE_OPERAND (*from_p, 0);
5323 /* We don't change ret in this case because the
5324 WITH_SIZE_EXPR might have been added in
5325 gimplify_modify_expr, so returning GS_OK would lead to an
5326 infinite loop. */
5327 changed = true;
5329 break;
5331 /* If we're initializing from a container, push the initialization
5332 inside it. */
5333 case CLEANUP_POINT_EXPR:
5334 case BIND_EXPR:
5335 case STATEMENT_LIST:
5337 tree wrap = *from_p;
5338 tree t;
5340 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_min_lval,
5341 fb_lvalue);
5342 if (ret != GS_ERROR)
5343 ret = GS_OK;
5345 t = voidify_wrapper_expr (wrap, *expr_p);
5346 gcc_assert (t == *expr_p);
5348 if (want_value)
5350 gimplify_and_add (wrap, pre_p);
5351 *expr_p = unshare_expr (*to_p);
5353 else
5354 *expr_p = wrap;
5355 return GS_OK;
5358 case COMPOUND_LITERAL_EXPR:
5360 tree complit = TREE_OPERAND (*expr_p, 1);
5361 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (complit);
5362 tree decl = DECL_EXPR_DECL (decl_s);
5363 tree init = DECL_INITIAL (decl);
5365 /* struct T x = (struct T) { 0, 1, 2 } can be optimized
5366 into struct T x = { 0, 1, 2 } if the address of the
5367 compound literal has never been taken. */
5368 if (!TREE_ADDRESSABLE (complit)
5369 && !TREE_ADDRESSABLE (decl)
5370 && init)
5372 *expr_p = copy_node (*expr_p);
5373 TREE_OPERAND (*expr_p, 1) = init;
5374 return GS_OK;
5378 default:
5379 break;
5382 while (changed);
5384 return ret;
5388 /* Return true if T looks like a valid GIMPLE statement. */
5390 static bool
5391 is_gimple_stmt (tree t)
5393 const enum tree_code code = TREE_CODE (t);
5395 switch (code)
5397 case NOP_EXPR:
5398 /* The only valid NOP_EXPR is the empty statement. */
5399 return IS_EMPTY_STMT (t);
5401 case BIND_EXPR:
5402 case COND_EXPR:
5403 /* These are only valid if they're void. */
5404 return TREE_TYPE (t) == NULL || VOID_TYPE_P (TREE_TYPE (t));
5406 case SWITCH_EXPR:
5407 case GOTO_EXPR:
5408 case RETURN_EXPR:
5409 case LABEL_EXPR:
5410 case CASE_LABEL_EXPR:
5411 case TRY_CATCH_EXPR:
5412 case TRY_FINALLY_EXPR:
5413 case EH_FILTER_EXPR:
5414 case CATCH_EXPR:
5415 case ASM_EXPR:
5416 case STATEMENT_LIST:
5417 case OACC_PARALLEL:
5418 case OACC_KERNELS:
5419 case OACC_DATA:
5420 case OACC_HOST_DATA:
5421 case OACC_DECLARE:
5422 case OACC_UPDATE:
5423 case OACC_ENTER_DATA:
5424 case OACC_EXIT_DATA:
5425 case OACC_CACHE:
5426 case OMP_PARALLEL:
5427 case OMP_FOR:
5428 case OMP_SIMD:
5429 case OMP_DISTRIBUTE:
5430 case OACC_LOOP:
5431 case OMP_SECTIONS:
5432 case OMP_SECTION:
5433 case OMP_SINGLE:
5434 case OMP_MASTER:
5435 case OMP_TASKGROUP:
5436 case OMP_ORDERED:
5437 case OMP_CRITICAL:
5438 case OMP_TASK:
5439 case OMP_TARGET:
5440 case OMP_TARGET_DATA:
5441 case OMP_TARGET_UPDATE:
5442 case OMP_TARGET_ENTER_DATA:
5443 case OMP_TARGET_EXIT_DATA:
5444 case OMP_TASKLOOP:
5445 case OMP_TEAMS:
5446 /* These are always void. */
5447 return true;
5449 case CALL_EXPR:
5450 case MODIFY_EXPR:
5451 case PREDICT_EXPR:
5452 /* These are valid regardless of their type. */
5453 return true;
5455 default:
5456 return false;
5461 /* Promote partial stores to COMPLEX variables to total stores. *EXPR_P is
5462 a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a variable with
5463 DECL_GIMPLE_REG_P set.
5465 IMPORTANT NOTE: This promotion is performed by introducing a load of the
5466 other, unmodified part of the complex object just before the total store.
5467 As a consequence, if the object is still uninitialized, an undefined value
5468 will be loaded into a register, which may result in a spurious exception
5469 if the register is floating-point and the value happens to be a signaling
5470 NaN for example. Then the fully-fledged complex operations lowering pass
5471 followed by a DCE pass are necessary in order to fix things up. */
5473 static enum gimplify_status
5474 gimplify_modify_expr_complex_part (tree *expr_p, gimple_seq *pre_p,
5475 bool want_value)
5477 enum tree_code code, ocode;
5478 tree lhs, rhs, new_rhs, other, realpart, imagpart;
5480 lhs = TREE_OPERAND (*expr_p, 0);
5481 rhs = TREE_OPERAND (*expr_p, 1);
5482 code = TREE_CODE (lhs);
5483 lhs = TREE_OPERAND (lhs, 0);
5485 ocode = code == REALPART_EXPR ? IMAGPART_EXPR : REALPART_EXPR;
5486 other = build1 (ocode, TREE_TYPE (rhs), lhs);
5487 TREE_NO_WARNING (other) = 1;
5488 other = get_formal_tmp_var (other, pre_p);
5490 realpart = code == REALPART_EXPR ? rhs : other;
5491 imagpart = code == REALPART_EXPR ? other : rhs;
5493 if (TREE_CONSTANT (realpart) && TREE_CONSTANT (imagpart))
5494 new_rhs = build_complex (TREE_TYPE (lhs), realpart, imagpart);
5495 else
5496 new_rhs = build2 (COMPLEX_EXPR, TREE_TYPE (lhs), realpart, imagpart);
5498 gimplify_seq_add_stmt (pre_p, gimple_build_assign (lhs, new_rhs));
5499 *expr_p = (want_value) ? rhs : NULL_TREE;
5501 return GS_ALL_DONE;
5504 /* Gimplify the MODIFY_EXPR node pointed to by EXPR_P.
5506 modify_expr
5507 : varname '=' rhs
5508 | '*' ID '=' rhs
5510 PRE_P points to the list where side effects that must happen before
5511 *EXPR_P should be stored.
5513 POST_P points to the list where side effects that must happen after
5514 *EXPR_P should be stored.
5516 WANT_VALUE is nonzero iff we want to use the value of this expression
5517 in another expression. */
5519 static enum gimplify_status
5520 gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
5521 bool want_value)
5523 tree *from_p = &TREE_OPERAND (*expr_p, 1);
5524 tree *to_p = &TREE_OPERAND (*expr_p, 0);
5525 enum gimplify_status ret = GS_UNHANDLED;
5526 gimple *assign;
5527 location_t loc = EXPR_LOCATION (*expr_p);
5528 gimple_stmt_iterator gsi;
5530 gcc_assert (TREE_CODE (*expr_p) == MODIFY_EXPR
5531 || TREE_CODE (*expr_p) == INIT_EXPR);
5533 /* Trying to simplify a clobber using normal logic doesn't work,
5534 so handle it here. */
5535 if (TREE_CLOBBER_P (*from_p))
5537 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
5538 if (ret == GS_ERROR)
5539 return ret;
5540 gcc_assert (!want_value);
5541 if (!VAR_P (*to_p) && TREE_CODE (*to_p) != MEM_REF)
5543 tree addr = get_initialized_tmp_var (build_fold_addr_expr (*to_p),
5544 pre_p, post_p);
5545 *to_p = build_simple_mem_ref_loc (EXPR_LOCATION (*to_p), addr);
5547 gimplify_seq_add_stmt (pre_p, gimple_build_assign (*to_p, *from_p));
5548 *expr_p = NULL;
5549 return GS_ALL_DONE;
5552 /* Insert pointer conversions required by the middle-end that are not
5553 required by the frontend. This fixes middle-end type checking for
5554 for example gcc.dg/redecl-6.c. */
5555 if (POINTER_TYPE_P (TREE_TYPE (*to_p)))
5557 STRIP_USELESS_TYPE_CONVERSION (*from_p);
5558 if (!useless_type_conversion_p (TREE_TYPE (*to_p), TREE_TYPE (*from_p)))
5559 *from_p = fold_convert_loc (loc, TREE_TYPE (*to_p), *from_p);
5562 /* See if any simplifications can be done based on what the RHS is. */
5563 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
5564 want_value);
5565 if (ret != GS_UNHANDLED)
5566 return ret;
5568 /* For zero sized types only gimplify the left hand side and right hand
5569 side as statements and throw away the assignment. Do this after
5570 gimplify_modify_expr_rhs so we handle TARGET_EXPRs of addressable
5571 types properly. */
5572 if (zero_sized_type (TREE_TYPE (*from_p))
5573 && !want_value
5574 /* Don't do this for calls that return addressable types, expand_call
5575 relies on those having a lhs. */
5576 && !(TREE_ADDRESSABLE (TREE_TYPE (*from_p))
5577 && TREE_CODE (*from_p) == CALL_EXPR))
5579 gimplify_stmt (from_p, pre_p);
5580 gimplify_stmt (to_p, pre_p);
5581 *expr_p = NULL_TREE;
5582 return GS_ALL_DONE;
5585 /* If the value being copied is of variable width, compute the length
5586 of the copy into a WITH_SIZE_EXPR. Note that we need to do this
5587 before gimplifying any of the operands so that we can resolve any
5588 PLACEHOLDER_EXPRs in the size. Also note that the RTL expander uses
5589 the size of the expression to be copied, not of the destination, so
5590 that is what we must do here. */
5591 maybe_with_size_expr (from_p);
5593 /* As a special case, we have to temporarily allow for assignments
5594 with a CALL_EXPR on the RHS. Since in GIMPLE a function call is
5595 a toplevel statement, when gimplifying the GENERIC expression
5596 MODIFY_EXPR <a, CALL_EXPR <foo>>, we cannot create the tuple
5597 GIMPLE_ASSIGN <a, GIMPLE_CALL <foo>>.
5599 Instead, we need to create the tuple GIMPLE_CALL <a, foo>. To
5600 prevent gimplify_expr from trying to create a new temporary for
5601 foo's LHS, we tell it that it should only gimplify until it
5602 reaches the CALL_EXPR. On return from gimplify_expr, the newly
5603 created GIMPLE_CALL <foo> will be the last statement in *PRE_P
5604 and all we need to do here is set 'a' to be its LHS. */
5606 /* Gimplify the RHS first for C++17 and bug 71104. */
5607 gimple_predicate initial_pred = initial_rhs_predicate_for (*to_p);
5608 ret = gimplify_expr (from_p, pre_p, post_p, initial_pred, fb_rvalue);
5609 if (ret == GS_ERROR)
5610 return ret;
5612 /* Then gimplify the LHS. */
5613 /* If we gimplified the RHS to a CALL_EXPR and that call may return
5614 twice we have to make sure to gimplify into non-SSA as otherwise
5615 the abnormal edge added later will make those defs not dominate
5616 their uses.
5617 ??? Technically this applies only to the registers used in the
5618 resulting non-register *TO_P. */
5619 bool saved_into_ssa = gimplify_ctxp->into_ssa;
5620 if (saved_into_ssa
5621 && TREE_CODE (*from_p) == CALL_EXPR
5622 && call_expr_flags (*from_p) & ECF_RETURNS_TWICE)
5623 gimplify_ctxp->into_ssa = false;
5624 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
5625 gimplify_ctxp->into_ssa = saved_into_ssa;
5626 if (ret == GS_ERROR)
5627 return ret;
5629 /* Now that the LHS is gimplified, re-gimplify the RHS if our initial
5630 guess for the predicate was wrong. */
5631 gimple_predicate final_pred = rhs_predicate_for (*to_p);
5632 if (final_pred != initial_pred)
5634 ret = gimplify_expr (from_p, pre_p, post_p, final_pred, fb_rvalue);
5635 if (ret == GS_ERROR)
5636 return ret;
5639 /* In case of va_arg internal fn wrappped in a WITH_SIZE_EXPR, add the type
5640 size as argument to the call. */
5641 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
5643 tree call = TREE_OPERAND (*from_p, 0);
5644 tree vlasize = TREE_OPERAND (*from_p, 1);
5646 if (TREE_CODE (call) == CALL_EXPR
5647 && CALL_EXPR_IFN (call) == IFN_VA_ARG)
5649 int nargs = call_expr_nargs (call);
5650 tree type = TREE_TYPE (call);
5651 tree ap = CALL_EXPR_ARG (call, 0);
5652 tree tag = CALL_EXPR_ARG (call, 1);
5653 tree aptag = CALL_EXPR_ARG (call, 2);
5654 tree newcall = build_call_expr_internal_loc (EXPR_LOCATION (call),
5655 IFN_VA_ARG, type,
5656 nargs + 1, ap, tag,
5657 aptag, vlasize);
5658 TREE_OPERAND (*from_p, 0) = newcall;
5662 /* Now see if the above changed *from_p to something we handle specially. */
5663 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
5664 want_value);
5665 if (ret != GS_UNHANDLED)
5666 return ret;
5668 /* If we've got a variable sized assignment between two lvalues (i.e. does
5669 not involve a call), then we can make things a bit more straightforward
5670 by converting the assignment to memcpy or memset. */
5671 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
5673 tree from = TREE_OPERAND (*from_p, 0);
5674 tree size = TREE_OPERAND (*from_p, 1);
5676 if (TREE_CODE (from) == CONSTRUCTOR)
5677 return gimplify_modify_expr_to_memset (expr_p, size, want_value, pre_p);
5679 if (is_gimple_addressable (from))
5681 *from_p = from;
5682 return gimplify_modify_expr_to_memcpy (expr_p, size, want_value,
5683 pre_p);
5687 /* Transform partial stores to non-addressable complex variables into
5688 total stores. This allows us to use real instead of virtual operands
5689 for these variables, which improves optimization. */
5690 if ((TREE_CODE (*to_p) == REALPART_EXPR
5691 || TREE_CODE (*to_p) == IMAGPART_EXPR)
5692 && is_gimple_reg (TREE_OPERAND (*to_p, 0)))
5693 return gimplify_modify_expr_complex_part (expr_p, pre_p, want_value);
5695 /* Try to alleviate the effects of the gimplification creating artificial
5696 temporaries (see for example is_gimple_reg_rhs) on the debug info, but
5697 make sure not to create DECL_DEBUG_EXPR links across functions. */
5698 if (!gimplify_ctxp->into_ssa
5699 && VAR_P (*from_p)
5700 && DECL_IGNORED_P (*from_p)
5701 && DECL_P (*to_p)
5702 && !DECL_IGNORED_P (*to_p)
5703 && decl_function_context (*to_p) == current_function_decl
5704 && decl_function_context (*from_p) == current_function_decl)
5706 if (!DECL_NAME (*from_p) && DECL_NAME (*to_p))
5707 DECL_NAME (*from_p)
5708 = create_tmp_var_name (IDENTIFIER_POINTER (DECL_NAME (*to_p)));
5709 DECL_HAS_DEBUG_EXPR_P (*from_p) = 1;
5710 SET_DECL_DEBUG_EXPR (*from_p, *to_p);
5713 if (want_value && TREE_THIS_VOLATILE (*to_p))
5714 *from_p = get_initialized_tmp_var (*from_p, pre_p, post_p);
5716 if (TREE_CODE (*from_p) == CALL_EXPR)
5718 /* Since the RHS is a CALL_EXPR, we need to create a GIMPLE_CALL
5719 instead of a GIMPLE_ASSIGN. */
5720 gcall *call_stmt;
5721 if (CALL_EXPR_FN (*from_p) == NULL_TREE)
5723 /* Gimplify internal functions created in the FEs. */
5724 int nargs = call_expr_nargs (*from_p), i;
5725 enum internal_fn ifn = CALL_EXPR_IFN (*from_p);
5726 auto_vec<tree> vargs (nargs);
5728 for (i = 0; i < nargs; i++)
5730 gimplify_arg (&CALL_EXPR_ARG (*from_p, i), pre_p,
5731 EXPR_LOCATION (*from_p));
5732 vargs.quick_push (CALL_EXPR_ARG (*from_p, i));
5734 call_stmt = gimple_build_call_internal_vec (ifn, vargs);
5735 gimple_call_set_nothrow (call_stmt, TREE_NOTHROW (*from_p));
5736 gimple_set_location (call_stmt, EXPR_LOCATION (*expr_p));
5738 else
5740 tree fnptrtype = TREE_TYPE (CALL_EXPR_FN (*from_p));
5741 CALL_EXPR_FN (*from_p) = TREE_OPERAND (CALL_EXPR_FN (*from_p), 0);
5742 STRIP_USELESS_TYPE_CONVERSION (CALL_EXPR_FN (*from_p));
5743 tree fndecl = get_callee_fndecl (*from_p);
5744 if (fndecl
5745 && fndecl_built_in_p (fndecl, BUILT_IN_EXPECT)
5746 && call_expr_nargs (*from_p) == 3)
5747 call_stmt = gimple_build_call_internal (IFN_BUILTIN_EXPECT, 3,
5748 CALL_EXPR_ARG (*from_p, 0),
5749 CALL_EXPR_ARG (*from_p, 1),
5750 CALL_EXPR_ARG (*from_p, 2));
5751 else
5753 call_stmt = gimple_build_call_from_tree (*from_p, fnptrtype);
5756 notice_special_calls (call_stmt);
5757 if (!gimple_call_noreturn_p (call_stmt) || !should_remove_lhs_p (*to_p))
5758 gimple_call_set_lhs (call_stmt, *to_p);
5759 else if (TREE_CODE (*to_p) == SSA_NAME)
5760 /* The above is somewhat premature, avoid ICEing later for a
5761 SSA name w/o a definition. We may have uses in the GIMPLE IL.
5762 ??? This doesn't make it a default-def. */
5763 SSA_NAME_DEF_STMT (*to_p) = gimple_build_nop ();
5765 assign = call_stmt;
5767 else
5769 assign = gimple_build_assign (*to_p, *from_p);
5770 gimple_set_location (assign, EXPR_LOCATION (*expr_p));
5771 if (COMPARISON_CLASS_P (*from_p))
5772 gimple_set_no_warning (assign, TREE_NO_WARNING (*from_p));
5775 if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p))
5777 /* We should have got an SSA name from the start. */
5778 gcc_assert (TREE_CODE (*to_p) == SSA_NAME
5779 || ! gimple_in_ssa_p (cfun));
5782 gimplify_seq_add_stmt (pre_p, assign);
5783 gsi = gsi_last (*pre_p);
5784 maybe_fold_stmt (&gsi);
5786 if (want_value)
5788 *expr_p = TREE_THIS_VOLATILE (*to_p) ? *from_p : unshare_expr (*to_p);
5789 return GS_OK;
5791 else
5792 *expr_p = NULL;
5794 return GS_ALL_DONE;
5797 /* Gimplify a comparison between two variable-sized objects. Do this
5798 with a call to BUILT_IN_MEMCMP. */
5800 static enum gimplify_status
5801 gimplify_variable_sized_compare (tree *expr_p)
5803 location_t loc = EXPR_LOCATION (*expr_p);
5804 tree op0 = TREE_OPERAND (*expr_p, 0);
5805 tree op1 = TREE_OPERAND (*expr_p, 1);
5806 tree t, arg, dest, src, expr;
5808 arg = TYPE_SIZE_UNIT (TREE_TYPE (op0));
5809 arg = unshare_expr (arg);
5810 arg = SUBSTITUTE_PLACEHOLDER_IN_EXPR (arg, op0);
5811 src = build_fold_addr_expr_loc (loc, op1);
5812 dest = build_fold_addr_expr_loc (loc, op0);
5813 t = builtin_decl_implicit (BUILT_IN_MEMCMP);
5814 t = build_call_expr_loc (loc, t, 3, dest, src, arg);
5816 expr
5817 = build2 (TREE_CODE (*expr_p), TREE_TYPE (*expr_p), t, integer_zero_node);
5818 SET_EXPR_LOCATION (expr, loc);
5819 *expr_p = expr;
5821 return GS_OK;
5824 /* Gimplify a comparison between two aggregate objects of integral scalar
5825 mode as a comparison between the bitwise equivalent scalar values. */
5827 static enum gimplify_status
5828 gimplify_scalar_mode_aggregate_compare (tree *expr_p)
5830 location_t loc = EXPR_LOCATION (*expr_p);
5831 tree op0 = TREE_OPERAND (*expr_p, 0);
5832 tree op1 = TREE_OPERAND (*expr_p, 1);
5834 tree type = TREE_TYPE (op0);
5835 tree scalar_type = lang_hooks.types.type_for_mode (TYPE_MODE (type), 1);
5837 op0 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op0);
5838 op1 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op1);
5840 *expr_p
5841 = fold_build2_loc (loc, TREE_CODE (*expr_p), TREE_TYPE (*expr_p), op0, op1);
5843 return GS_OK;
5846 /* Gimplify an expression sequence. This function gimplifies each
5847 expression and rewrites the original expression with the last
5848 expression of the sequence in GIMPLE form.
5850 PRE_P points to the list where the side effects for all the
5851 expressions in the sequence will be emitted.
5853 WANT_VALUE is true when the result of the last COMPOUND_EXPR is used. */
5855 static enum gimplify_status
5856 gimplify_compound_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
5858 tree t = *expr_p;
5862 tree *sub_p = &TREE_OPERAND (t, 0);
5864 if (TREE_CODE (*sub_p) == COMPOUND_EXPR)
5865 gimplify_compound_expr (sub_p, pre_p, false);
5866 else
5867 gimplify_stmt (sub_p, pre_p);
5869 t = TREE_OPERAND (t, 1);
5871 while (TREE_CODE (t) == COMPOUND_EXPR);
5873 *expr_p = t;
5874 if (want_value)
5875 return GS_OK;
5876 else
5878 gimplify_stmt (expr_p, pre_p);
5879 return GS_ALL_DONE;
5883 /* Gimplify a SAVE_EXPR node. EXPR_P points to the expression to
5884 gimplify. After gimplification, EXPR_P will point to a new temporary
5885 that holds the original value of the SAVE_EXPR node.
5887 PRE_P points to the list where side effects that must happen before
5888 *EXPR_P should be stored. */
5890 static enum gimplify_status
5891 gimplify_save_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
5893 enum gimplify_status ret = GS_ALL_DONE;
5894 tree val;
5896 gcc_assert (TREE_CODE (*expr_p) == SAVE_EXPR);
5897 val = TREE_OPERAND (*expr_p, 0);
5899 /* If the SAVE_EXPR has not been resolved, then evaluate it once. */
5900 if (!SAVE_EXPR_RESOLVED_P (*expr_p))
5902 /* The operand may be a void-valued expression. It is
5903 being executed only for its side-effects. */
5904 if (TREE_TYPE (val) == void_type_node)
5906 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
5907 is_gimple_stmt, fb_none);
5908 val = NULL;
5910 else
5911 /* The temporary may not be an SSA name as later abnormal and EH
5912 control flow may invalidate use/def domination. When in SSA
5913 form then assume there are no such issues and SAVE_EXPRs only
5914 appear via GENERIC foldings. */
5915 val = get_initialized_tmp_var (val, pre_p, post_p,
5916 gimple_in_ssa_p (cfun));
5918 TREE_OPERAND (*expr_p, 0) = val;
5919 SAVE_EXPR_RESOLVED_P (*expr_p) = 1;
5922 *expr_p = val;
5924 return ret;
5927 /* Rewrite the ADDR_EXPR node pointed to by EXPR_P
5929 unary_expr
5930 : ...
5931 | '&' varname
5934 PRE_P points to the list where side effects that must happen before
5935 *EXPR_P should be stored.
5937 POST_P points to the list where side effects that must happen after
5938 *EXPR_P should be stored. */
5940 static enum gimplify_status
5941 gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
5943 tree expr = *expr_p;
5944 tree op0 = TREE_OPERAND (expr, 0);
5945 enum gimplify_status ret;
5946 location_t loc = EXPR_LOCATION (*expr_p);
5948 switch (TREE_CODE (op0))
5950 case INDIRECT_REF:
5951 do_indirect_ref:
5952 /* Check if we are dealing with an expression of the form '&*ptr'.
5953 While the front end folds away '&*ptr' into 'ptr', these
5954 expressions may be generated internally by the compiler (e.g.,
5955 builtins like __builtin_va_end). */
5956 /* Caution: the silent array decomposition semantics we allow for
5957 ADDR_EXPR means we can't always discard the pair. */
5958 /* Gimplification of the ADDR_EXPR operand may drop
5959 cv-qualification conversions, so make sure we add them if
5960 needed. */
5962 tree op00 = TREE_OPERAND (op0, 0);
5963 tree t_expr = TREE_TYPE (expr);
5964 tree t_op00 = TREE_TYPE (op00);
5966 if (!useless_type_conversion_p (t_expr, t_op00))
5967 op00 = fold_convert_loc (loc, TREE_TYPE (expr), op00);
5968 *expr_p = op00;
5969 ret = GS_OK;
5971 break;
5973 case VIEW_CONVERT_EXPR:
5974 /* Take the address of our operand and then convert it to the type of
5975 this ADDR_EXPR.
5977 ??? The interactions of VIEW_CONVERT_EXPR and aliasing is not at
5978 all clear. The impact of this transformation is even less clear. */
5980 /* If the operand is a useless conversion, look through it. Doing so
5981 guarantees that the ADDR_EXPR and its operand will remain of the
5982 same type. */
5983 if (tree_ssa_useless_type_conversion (TREE_OPERAND (op0, 0)))
5984 op0 = TREE_OPERAND (op0, 0);
5986 *expr_p = fold_convert_loc (loc, TREE_TYPE (expr),
5987 build_fold_addr_expr_loc (loc,
5988 TREE_OPERAND (op0, 0)));
5989 ret = GS_OK;
5990 break;
5992 case MEM_REF:
5993 if (integer_zerop (TREE_OPERAND (op0, 1)))
5994 goto do_indirect_ref;
5996 /* fall through */
5998 default:
5999 /* If we see a call to a declared builtin or see its address
6000 being taken (we can unify those cases here) then we can mark
6001 the builtin for implicit generation by GCC. */
6002 if (TREE_CODE (op0) == FUNCTION_DECL
6003 && fndecl_built_in_p (op0, BUILT_IN_NORMAL)
6004 && builtin_decl_declared_p (DECL_FUNCTION_CODE (op0)))
6005 set_builtin_decl_implicit_p (DECL_FUNCTION_CODE (op0), true);
6007 /* We use fb_either here because the C frontend sometimes takes
6008 the address of a call that returns a struct; see
6009 gcc.dg/c99-array-lval-1.c. The gimplifier will correctly make
6010 the implied temporary explicit. */
6012 /* Make the operand addressable. */
6013 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, post_p,
6014 is_gimple_addressable, fb_either);
6015 if (ret == GS_ERROR)
6016 break;
6018 /* Then mark it. Beware that it may not be possible to do so directly
6019 if a temporary has been created by the gimplification. */
6020 prepare_gimple_addressable (&TREE_OPERAND (expr, 0), pre_p);
6022 op0 = TREE_OPERAND (expr, 0);
6024 /* For various reasons, the gimplification of the expression
6025 may have made a new INDIRECT_REF. */
6026 if (TREE_CODE (op0) == INDIRECT_REF)
6027 goto do_indirect_ref;
6029 mark_addressable (TREE_OPERAND (expr, 0));
6031 /* The FEs may end up building ADDR_EXPRs early on a decl with
6032 an incomplete type. Re-build ADDR_EXPRs in canonical form
6033 here. */
6034 if (!types_compatible_p (TREE_TYPE (op0), TREE_TYPE (TREE_TYPE (expr))))
6035 *expr_p = build_fold_addr_expr (op0);
6037 /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly. */
6038 recompute_tree_invariant_for_addr_expr (*expr_p);
6040 /* If we re-built the ADDR_EXPR add a conversion to the original type
6041 if required. */
6042 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
6043 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
6045 break;
6048 return ret;
6051 /* Gimplify the operands of an ASM_EXPR. Input operands should be a gimple
6052 value; output operands should be a gimple lvalue. */
6054 static enum gimplify_status
6055 gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6057 tree expr;
6058 int noutputs;
6059 const char **oconstraints;
6060 int i;
6061 tree link;
6062 const char *constraint;
6063 bool allows_mem, allows_reg, is_inout;
6064 enum gimplify_status ret, tret;
6065 gasm *stmt;
6066 vec<tree, va_gc> *inputs;
6067 vec<tree, va_gc> *outputs;
6068 vec<tree, va_gc> *clobbers;
6069 vec<tree, va_gc> *labels;
6070 tree link_next;
6072 expr = *expr_p;
6073 noutputs = list_length (ASM_OUTPUTS (expr));
6074 oconstraints = (const char **) alloca ((noutputs) * sizeof (const char *));
6076 inputs = NULL;
6077 outputs = NULL;
6078 clobbers = NULL;
6079 labels = NULL;
6081 ret = GS_ALL_DONE;
6082 link_next = NULL_TREE;
6083 for (i = 0, link = ASM_OUTPUTS (expr); link; ++i, link = link_next)
6085 bool ok;
6086 size_t constraint_len;
6088 link_next = TREE_CHAIN (link);
6090 oconstraints[i]
6091 = constraint
6092 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
6093 constraint_len = strlen (constraint);
6094 if (constraint_len == 0)
6095 continue;
6097 ok = parse_output_constraint (&constraint, i, 0, 0,
6098 &allows_mem, &allows_reg, &is_inout);
6099 if (!ok)
6101 ret = GS_ERROR;
6102 is_inout = false;
6105 if (!allows_reg && allows_mem)
6106 mark_addressable (TREE_VALUE (link));
6108 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6109 is_inout ? is_gimple_min_lval : is_gimple_lvalue,
6110 fb_lvalue | fb_mayfail);
6111 if (tret == GS_ERROR)
6113 error ("invalid lvalue in asm output %d", i);
6114 ret = tret;
6117 /* If the constraint does not allow memory make sure we gimplify
6118 it to a register if it is not already but its base is. This
6119 happens for complex and vector components. */
6120 if (!allows_mem)
6122 tree op = TREE_VALUE (link);
6123 if (! is_gimple_val (op)
6124 && is_gimple_reg_type (TREE_TYPE (op))
6125 && is_gimple_reg (get_base_address (op)))
6127 tree tem = create_tmp_reg (TREE_TYPE (op));
6128 tree ass;
6129 if (is_inout)
6131 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem),
6132 tem, unshare_expr (op));
6133 gimplify_and_add (ass, pre_p);
6135 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem), op, tem);
6136 gimplify_and_add (ass, post_p);
6138 TREE_VALUE (link) = tem;
6139 tret = GS_OK;
6143 vec_safe_push (outputs, link);
6144 TREE_CHAIN (link) = NULL_TREE;
6146 if (is_inout)
6148 /* An input/output operand. To give the optimizers more
6149 flexibility, split it into separate input and output
6150 operands. */
6151 tree input;
6152 /* Buffer big enough to format a 32-bit UINT_MAX into. */
6153 char buf[11];
6155 /* Turn the in/out constraint into an output constraint. */
6156 char *p = xstrdup (constraint);
6157 p[0] = '=';
6158 TREE_VALUE (TREE_PURPOSE (link)) = build_string (constraint_len, p);
6160 /* And add a matching input constraint. */
6161 if (allows_reg)
6163 sprintf (buf, "%u", i);
6165 /* If there are multiple alternatives in the constraint,
6166 handle each of them individually. Those that allow register
6167 will be replaced with operand number, the others will stay
6168 unchanged. */
6169 if (strchr (p, ',') != NULL)
6171 size_t len = 0, buflen = strlen (buf);
6172 char *beg, *end, *str, *dst;
6174 for (beg = p + 1;;)
6176 end = strchr (beg, ',');
6177 if (end == NULL)
6178 end = strchr (beg, '\0');
6179 if ((size_t) (end - beg) < buflen)
6180 len += buflen + 1;
6181 else
6182 len += end - beg + 1;
6183 if (*end)
6184 beg = end + 1;
6185 else
6186 break;
6189 str = (char *) alloca (len);
6190 for (beg = p + 1, dst = str;;)
6192 const char *tem;
6193 bool mem_p, reg_p, inout_p;
6195 end = strchr (beg, ',');
6196 if (end)
6197 *end = '\0';
6198 beg[-1] = '=';
6199 tem = beg - 1;
6200 parse_output_constraint (&tem, i, 0, 0,
6201 &mem_p, &reg_p, &inout_p);
6202 if (dst != str)
6203 *dst++ = ',';
6204 if (reg_p)
6206 memcpy (dst, buf, buflen);
6207 dst += buflen;
6209 else
6211 if (end)
6212 len = end - beg;
6213 else
6214 len = strlen (beg);
6215 memcpy (dst, beg, len);
6216 dst += len;
6218 if (end)
6219 beg = end + 1;
6220 else
6221 break;
6223 *dst = '\0';
6224 input = build_string (dst - str, str);
6226 else
6227 input = build_string (strlen (buf), buf);
6229 else
6230 input = build_string (constraint_len - 1, constraint + 1);
6232 free (p);
6234 input = build_tree_list (build_tree_list (NULL_TREE, input),
6235 unshare_expr (TREE_VALUE (link)));
6236 ASM_INPUTS (expr) = chainon (ASM_INPUTS (expr), input);
6240 link_next = NULL_TREE;
6241 for (link = ASM_INPUTS (expr); link; ++i, link = link_next)
6243 link_next = TREE_CHAIN (link);
6244 constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
6245 parse_input_constraint (&constraint, 0, 0, noutputs, 0,
6246 oconstraints, &allows_mem, &allows_reg);
6248 /* If we can't make copies, we can only accept memory. */
6249 if (TREE_ADDRESSABLE (TREE_TYPE (TREE_VALUE (link))))
6251 if (allows_mem)
6252 allows_reg = 0;
6253 else
6255 error ("impossible constraint in %<asm%>");
6256 error ("non-memory input %d must stay in memory", i);
6257 return GS_ERROR;
6261 /* If the operand is a memory input, it should be an lvalue. */
6262 if (!allows_reg && allows_mem)
6264 tree inputv = TREE_VALUE (link);
6265 STRIP_NOPS (inputv);
6266 if (TREE_CODE (inputv) == PREDECREMENT_EXPR
6267 || TREE_CODE (inputv) == PREINCREMENT_EXPR
6268 || TREE_CODE (inputv) == POSTDECREMENT_EXPR
6269 || TREE_CODE (inputv) == POSTINCREMENT_EXPR
6270 || TREE_CODE (inputv) == MODIFY_EXPR)
6271 TREE_VALUE (link) = error_mark_node;
6272 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6273 is_gimple_lvalue, fb_lvalue | fb_mayfail);
6274 if (tret != GS_ERROR)
6276 /* Unlike output operands, memory inputs are not guaranteed
6277 to be lvalues by the FE, and while the expressions are
6278 marked addressable there, if it is e.g. a statement
6279 expression, temporaries in it might not end up being
6280 addressable. They might be already used in the IL and thus
6281 it is too late to make them addressable now though. */
6282 tree x = TREE_VALUE (link);
6283 while (handled_component_p (x))
6284 x = TREE_OPERAND (x, 0);
6285 if (TREE_CODE (x) == MEM_REF
6286 && TREE_CODE (TREE_OPERAND (x, 0)) == ADDR_EXPR)
6287 x = TREE_OPERAND (TREE_OPERAND (x, 0), 0);
6288 if ((VAR_P (x)
6289 || TREE_CODE (x) == PARM_DECL
6290 || TREE_CODE (x) == RESULT_DECL)
6291 && !TREE_ADDRESSABLE (x)
6292 && is_gimple_reg (x))
6294 warning_at (EXPR_LOC_OR_LOC (TREE_VALUE (link),
6295 input_location), 0,
6296 "memory input %d is not directly addressable",
6298 prepare_gimple_addressable (&TREE_VALUE (link), pre_p);
6301 mark_addressable (TREE_VALUE (link));
6302 if (tret == GS_ERROR)
6304 error_at (EXPR_LOC_OR_LOC (TREE_VALUE (link), input_location),
6305 "memory input %d is not directly addressable", i);
6306 ret = tret;
6309 else
6311 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6312 is_gimple_asm_val, fb_rvalue);
6313 if (tret == GS_ERROR)
6314 ret = tret;
6317 TREE_CHAIN (link) = NULL_TREE;
6318 vec_safe_push (inputs, link);
6321 link_next = NULL_TREE;
6322 for (link = ASM_CLOBBERS (expr); link; ++i, link = link_next)
6324 link_next = TREE_CHAIN (link);
6325 TREE_CHAIN (link) = NULL_TREE;
6326 vec_safe_push (clobbers, link);
6329 link_next = NULL_TREE;
6330 for (link = ASM_LABELS (expr); link; ++i, link = link_next)
6332 link_next = TREE_CHAIN (link);
6333 TREE_CHAIN (link) = NULL_TREE;
6334 vec_safe_push (labels, link);
6337 /* Do not add ASMs with errors to the gimple IL stream. */
6338 if (ret != GS_ERROR)
6340 stmt = gimple_build_asm_vec (TREE_STRING_POINTER (ASM_STRING (expr)),
6341 inputs, outputs, clobbers, labels);
6343 gimple_asm_set_volatile (stmt, ASM_VOLATILE_P (expr) || noutputs == 0);
6344 gimple_asm_set_input (stmt, ASM_INPUT_P (expr));
6346 gimplify_seq_add_stmt (pre_p, stmt);
6349 return ret;
6352 /* Gimplify a CLEANUP_POINT_EXPR. Currently this works by adding
6353 GIMPLE_WITH_CLEANUP_EXPRs to the prequeue as we encounter cleanups while
6354 gimplifying the body, and converting them to TRY_FINALLY_EXPRs when we
6355 return to this function.
6357 FIXME should we complexify the prequeue handling instead? Or use flags
6358 for all the cleanups and let the optimizer tighten them up? The current
6359 code seems pretty fragile; it will break on a cleanup within any
6360 non-conditional nesting. But any such nesting would be broken, anyway;
6361 we can't write a TRY_FINALLY_EXPR that starts inside a nesting construct
6362 and continues out of it. We can do that at the RTL level, though, so
6363 having an optimizer to tighten up try/finally regions would be a Good
6364 Thing. */
6366 static enum gimplify_status
6367 gimplify_cleanup_point_expr (tree *expr_p, gimple_seq *pre_p)
6369 gimple_stmt_iterator iter;
6370 gimple_seq body_sequence = NULL;
6372 tree temp = voidify_wrapper_expr (*expr_p, NULL);
6374 /* We only care about the number of conditions between the innermost
6375 CLEANUP_POINT_EXPR and the cleanup. So save and reset the count and
6376 any cleanups collected outside the CLEANUP_POINT_EXPR. */
6377 int old_conds = gimplify_ctxp->conditions;
6378 gimple_seq old_cleanups = gimplify_ctxp->conditional_cleanups;
6379 bool old_in_cleanup_point_expr = gimplify_ctxp->in_cleanup_point_expr;
6380 gimplify_ctxp->conditions = 0;
6381 gimplify_ctxp->conditional_cleanups = NULL;
6382 gimplify_ctxp->in_cleanup_point_expr = true;
6384 gimplify_stmt (&TREE_OPERAND (*expr_p, 0), &body_sequence);
6386 gimplify_ctxp->conditions = old_conds;
6387 gimplify_ctxp->conditional_cleanups = old_cleanups;
6388 gimplify_ctxp->in_cleanup_point_expr = old_in_cleanup_point_expr;
6390 for (iter = gsi_start (body_sequence); !gsi_end_p (iter); )
6392 gimple *wce = gsi_stmt (iter);
6394 if (gimple_code (wce) == GIMPLE_WITH_CLEANUP_EXPR)
6396 if (gsi_one_before_end_p (iter))
6398 /* Note that gsi_insert_seq_before and gsi_remove do not
6399 scan operands, unlike some other sequence mutators. */
6400 if (!gimple_wce_cleanup_eh_only (wce))
6401 gsi_insert_seq_before_without_update (&iter,
6402 gimple_wce_cleanup (wce),
6403 GSI_SAME_STMT);
6404 gsi_remove (&iter, true);
6405 break;
6407 else
6409 gtry *gtry;
6410 gimple_seq seq;
6411 enum gimple_try_flags kind;
6413 if (gimple_wce_cleanup_eh_only (wce))
6414 kind = GIMPLE_TRY_CATCH;
6415 else
6416 kind = GIMPLE_TRY_FINALLY;
6417 seq = gsi_split_seq_after (iter);
6419 gtry = gimple_build_try (seq, gimple_wce_cleanup (wce), kind);
6420 /* Do not use gsi_replace here, as it may scan operands.
6421 We want to do a simple structural modification only. */
6422 gsi_set_stmt (&iter, gtry);
6423 iter = gsi_start (gtry->eval);
6426 else
6427 gsi_next (&iter);
6430 gimplify_seq_add_seq (pre_p, body_sequence);
6431 if (temp)
6433 *expr_p = temp;
6434 return GS_OK;
6436 else
6438 *expr_p = NULL;
6439 return GS_ALL_DONE;
6443 /* Insert a cleanup marker for gimplify_cleanup_point_expr. CLEANUP
6444 is the cleanup action required. EH_ONLY is true if the cleanup should
6445 only be executed if an exception is thrown, not on normal exit.
6446 If FORCE_UNCOND is true perform the cleanup unconditionally; this is
6447 only valid for clobbers. */
6449 static void
6450 gimple_push_cleanup (tree var, tree cleanup, bool eh_only, gimple_seq *pre_p,
6451 bool force_uncond = false)
6453 gimple *wce;
6454 gimple_seq cleanup_stmts = NULL;
6456 /* Errors can result in improperly nested cleanups. Which results in
6457 confusion when trying to resolve the GIMPLE_WITH_CLEANUP_EXPR. */
6458 if (seen_error ())
6459 return;
6461 if (gimple_conditional_context ())
6463 /* If we're in a conditional context, this is more complex. We only
6464 want to run the cleanup if we actually ran the initialization that
6465 necessitates it, but we want to run it after the end of the
6466 conditional context. So we wrap the try/finally around the
6467 condition and use a flag to determine whether or not to actually
6468 run the destructor. Thus
6470 test ? f(A()) : 0
6472 becomes (approximately)
6474 flag = 0;
6475 try {
6476 if (test) { A::A(temp); flag = 1; val = f(temp); }
6477 else { val = 0; }
6478 } finally {
6479 if (flag) A::~A(temp);
6483 if (force_uncond)
6485 gimplify_stmt (&cleanup, &cleanup_stmts);
6486 wce = gimple_build_wce (cleanup_stmts);
6487 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
6489 else
6491 tree flag = create_tmp_var (boolean_type_node, "cleanup");
6492 gassign *ffalse = gimple_build_assign (flag, boolean_false_node);
6493 gassign *ftrue = gimple_build_assign (flag, boolean_true_node);
6495 cleanup = build3 (COND_EXPR, void_type_node, flag, cleanup, NULL);
6496 gimplify_stmt (&cleanup, &cleanup_stmts);
6497 wce = gimple_build_wce (cleanup_stmts);
6499 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, ffalse);
6500 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
6501 gimplify_seq_add_stmt (pre_p, ftrue);
6503 /* Because of this manipulation, and the EH edges that jump
6504 threading cannot redirect, the temporary (VAR) will appear
6505 to be used uninitialized. Don't warn. */
6506 TREE_NO_WARNING (var) = 1;
6509 else
6511 gimplify_stmt (&cleanup, &cleanup_stmts);
6512 wce = gimple_build_wce (cleanup_stmts);
6513 gimple_wce_set_cleanup_eh_only (wce, eh_only);
6514 gimplify_seq_add_stmt (pre_p, wce);
6518 /* Gimplify a TARGET_EXPR which doesn't appear on the rhs of an INIT_EXPR. */
6520 static enum gimplify_status
6521 gimplify_target_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6523 tree targ = *expr_p;
6524 tree temp = TARGET_EXPR_SLOT (targ);
6525 tree init = TARGET_EXPR_INITIAL (targ);
6526 enum gimplify_status ret;
6528 bool unpoison_empty_seq = false;
6529 gimple_stmt_iterator unpoison_it;
6531 if (init)
6533 tree cleanup = NULL_TREE;
6535 /* TARGET_EXPR temps aren't part of the enclosing block, so add it
6536 to the temps list. Handle also variable length TARGET_EXPRs. */
6537 if (TREE_CODE (DECL_SIZE (temp)) != INTEGER_CST)
6539 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (temp)))
6540 gimplify_type_sizes (TREE_TYPE (temp), pre_p);
6541 gimplify_vla_decl (temp, pre_p);
6543 else
6545 /* Save location where we need to place unpoisoning. It's possible
6546 that a variable will be converted to needs_to_live_in_memory. */
6547 unpoison_it = gsi_last (*pre_p);
6548 unpoison_empty_seq = gsi_end_p (unpoison_it);
6550 gimple_add_tmp_var (temp);
6553 /* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the
6554 expression is supposed to initialize the slot. */
6555 if (VOID_TYPE_P (TREE_TYPE (init)))
6556 ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
6557 else
6559 tree init_expr = build2 (INIT_EXPR, void_type_node, temp, init);
6560 init = init_expr;
6561 ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
6562 init = NULL;
6563 ggc_free (init_expr);
6565 if (ret == GS_ERROR)
6567 /* PR c++/28266 Make sure this is expanded only once. */
6568 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
6569 return GS_ERROR;
6571 if (init)
6572 gimplify_and_add (init, pre_p);
6574 /* If needed, push the cleanup for the temp. */
6575 if (TARGET_EXPR_CLEANUP (targ))
6577 if (CLEANUP_EH_ONLY (targ))
6578 gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ),
6579 CLEANUP_EH_ONLY (targ), pre_p);
6580 else
6581 cleanup = TARGET_EXPR_CLEANUP (targ);
6584 /* Add a clobber for the temporary going out of scope, like
6585 gimplify_bind_expr. */
6586 if (gimplify_ctxp->in_cleanup_point_expr
6587 && needs_to_live_in_memory (temp))
6589 if (flag_stack_reuse == SR_ALL)
6591 tree clobber = build_clobber (TREE_TYPE (temp));
6592 clobber = build2 (MODIFY_EXPR, TREE_TYPE (temp), temp, clobber);
6593 gimple_push_cleanup (temp, clobber, false, pre_p, true);
6595 if (asan_poisoned_variables
6596 && DECL_ALIGN (temp) <= MAX_SUPPORTED_STACK_ALIGNMENT
6597 && dbg_cnt (asan_use_after_scope)
6598 && !gimplify_omp_ctxp)
6600 tree asan_cleanup = build_asan_poison_call_expr (temp);
6601 if (asan_cleanup)
6603 if (unpoison_empty_seq)
6604 unpoison_it = gsi_start (*pre_p);
6606 asan_poison_variable (temp, false, &unpoison_it,
6607 unpoison_empty_seq);
6608 gimple_push_cleanup (temp, asan_cleanup, false, pre_p);
6612 if (cleanup)
6613 gimple_push_cleanup (temp, cleanup, false, pre_p);
6615 /* Only expand this once. */
6616 TREE_OPERAND (targ, 3) = init;
6617 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
6619 else
6620 /* We should have expanded this before. */
6621 gcc_assert (DECL_SEEN_IN_BIND_EXPR_P (temp));
6623 *expr_p = temp;
6624 return GS_OK;
6627 /* Gimplification of expression trees. */
6629 /* Gimplify an expression which appears at statement context. The
6630 corresponding GIMPLE statements are added to *SEQ_P. If *SEQ_P is
6631 NULL, a new sequence is allocated.
6633 Return true if we actually added a statement to the queue. */
6635 bool
6636 gimplify_stmt (tree *stmt_p, gimple_seq *seq_p)
6638 gimple_seq_node last;
6640 last = gimple_seq_last (*seq_p);
6641 gimplify_expr (stmt_p, seq_p, NULL, is_gimple_stmt, fb_none);
6642 return last != gimple_seq_last (*seq_p);
6645 /* Add FIRSTPRIVATE entries for DECL in the OpenMP the surrounding parallels
6646 to CTX. If entries already exist, force them to be some flavor of private.
6647 If there is no enclosing parallel, do nothing. */
6649 void
6650 omp_firstprivatize_variable (struct gimplify_omp_ctx *ctx, tree decl)
6652 splay_tree_node n;
6654 if (decl == NULL || !DECL_P (decl) || ctx->region_type == ORT_NONE)
6655 return;
6659 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
6660 if (n != NULL)
6662 if (n->value & GOVD_SHARED)
6663 n->value = GOVD_FIRSTPRIVATE | (n->value & GOVD_SEEN);
6664 else if (n->value & GOVD_MAP)
6665 n->value |= GOVD_MAP_TO_ONLY;
6666 else
6667 return;
6669 else if ((ctx->region_type & ORT_TARGET) != 0)
6671 if (ctx->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE)
6672 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
6673 else
6674 omp_add_variable (ctx, decl, GOVD_MAP | GOVD_MAP_TO_ONLY);
6676 else if (ctx->region_type != ORT_WORKSHARE
6677 && ctx->region_type != ORT_TASKGROUP
6678 && ctx->region_type != ORT_SIMD
6679 && ctx->region_type != ORT_ACC
6680 && !(ctx->region_type & ORT_TARGET_DATA))
6681 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
6683 ctx = ctx->outer_context;
6685 while (ctx);
6688 /* Similarly for each of the type sizes of TYPE. */
6690 static void
6691 omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type)
6693 if (type == NULL || type == error_mark_node)
6694 return;
6695 type = TYPE_MAIN_VARIANT (type);
6697 if (ctx->privatized_types->add (type))
6698 return;
6700 switch (TREE_CODE (type))
6702 case INTEGER_TYPE:
6703 case ENUMERAL_TYPE:
6704 case BOOLEAN_TYPE:
6705 case REAL_TYPE:
6706 case FIXED_POINT_TYPE:
6707 omp_firstprivatize_variable (ctx, TYPE_MIN_VALUE (type));
6708 omp_firstprivatize_variable (ctx, TYPE_MAX_VALUE (type));
6709 break;
6711 case ARRAY_TYPE:
6712 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
6713 omp_firstprivatize_type_sizes (ctx, TYPE_DOMAIN (type));
6714 break;
6716 case RECORD_TYPE:
6717 case UNION_TYPE:
6718 case QUAL_UNION_TYPE:
6720 tree field;
6721 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
6722 if (TREE_CODE (field) == FIELD_DECL)
6724 omp_firstprivatize_variable (ctx, DECL_FIELD_OFFSET (field));
6725 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (field));
6728 break;
6730 case POINTER_TYPE:
6731 case REFERENCE_TYPE:
6732 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
6733 break;
6735 default:
6736 break;
6739 omp_firstprivatize_variable (ctx, TYPE_SIZE (type));
6740 omp_firstprivatize_variable (ctx, TYPE_SIZE_UNIT (type));
6741 lang_hooks.types.omp_firstprivatize_type_sizes (ctx, type);
6744 /* Add an entry for DECL in the OMP context CTX with FLAGS. */
6746 static void
6747 omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
6749 splay_tree_node n;
6750 unsigned int nflags;
6751 tree t;
6753 if (error_operand_p (decl) || ctx->region_type == ORT_NONE)
6754 return;
6756 /* Never elide decls whose type has TREE_ADDRESSABLE set. This means
6757 there are constructors involved somewhere. Exception is a shared clause,
6758 there is nothing privatized in that case. */
6759 if ((flags & GOVD_SHARED) == 0
6760 && (TREE_ADDRESSABLE (TREE_TYPE (decl))
6761 || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))))
6762 flags |= GOVD_SEEN;
6764 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
6765 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
6767 /* We shouldn't be re-adding the decl with the same data
6768 sharing class. */
6769 gcc_assert ((n->value & GOVD_DATA_SHARE_CLASS & flags) == 0);
6770 nflags = n->value | flags;
6771 /* The only combination of data sharing classes we should see is
6772 FIRSTPRIVATE and LASTPRIVATE. However, OpenACC permits
6773 reduction variables to be used in data sharing clauses. */
6774 gcc_assert ((ctx->region_type & ORT_ACC) != 0
6775 || ((nflags & GOVD_DATA_SHARE_CLASS)
6776 == (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE))
6777 || (flags & GOVD_DATA_SHARE_CLASS) == 0);
6778 n->value = nflags;
6779 return;
6782 /* When adding a variable-sized variable, we have to handle all sorts
6783 of additional bits of data: the pointer replacement variable, and
6784 the parameters of the type. */
6785 if (DECL_SIZE (decl) && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
6787 /* Add the pointer replacement variable as PRIVATE if the variable
6788 replacement is private, else FIRSTPRIVATE since we'll need the
6789 address of the original variable either for SHARED, or for the
6790 copy into or out of the context. */
6791 if (!(flags & GOVD_LOCAL) && ctx->region_type != ORT_TASKGROUP)
6793 if (flags & GOVD_MAP)
6794 nflags = GOVD_MAP | GOVD_MAP_TO_ONLY | GOVD_EXPLICIT;
6795 else if (flags & GOVD_PRIVATE)
6796 nflags = GOVD_PRIVATE;
6797 else if ((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
6798 && (flags & GOVD_FIRSTPRIVATE))
6799 nflags = GOVD_PRIVATE | GOVD_EXPLICIT;
6800 else
6801 nflags = GOVD_FIRSTPRIVATE;
6802 nflags |= flags & GOVD_SEEN;
6803 t = DECL_VALUE_EXPR (decl);
6804 gcc_assert (TREE_CODE (t) == INDIRECT_REF);
6805 t = TREE_OPERAND (t, 0);
6806 gcc_assert (DECL_P (t));
6807 omp_add_variable (ctx, t, nflags);
6810 /* Add all of the variable and type parameters (which should have
6811 been gimplified to a formal temporary) as FIRSTPRIVATE. */
6812 omp_firstprivatize_variable (ctx, DECL_SIZE_UNIT (decl));
6813 omp_firstprivatize_variable (ctx, DECL_SIZE (decl));
6814 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
6816 /* The variable-sized variable itself is never SHARED, only some form
6817 of PRIVATE. The sharing would take place via the pointer variable
6818 which we remapped above. */
6819 if (flags & GOVD_SHARED)
6820 flags = GOVD_SHARED | GOVD_DEBUG_PRIVATE
6821 | (flags & (GOVD_SEEN | GOVD_EXPLICIT));
6823 /* We're going to make use of the TYPE_SIZE_UNIT at least in the
6824 alloca statement we generate for the variable, so make sure it
6825 is available. This isn't automatically needed for the SHARED
6826 case, since we won't be allocating local storage then.
6827 For local variables TYPE_SIZE_UNIT might not be gimplified yet,
6828 in this case omp_notice_variable will be called later
6829 on when it is gimplified. */
6830 else if (! (flags & (GOVD_LOCAL | GOVD_MAP))
6831 && DECL_P (TYPE_SIZE_UNIT (TREE_TYPE (decl))))
6832 omp_notice_variable (ctx, TYPE_SIZE_UNIT (TREE_TYPE (decl)), true);
6834 else if ((flags & (GOVD_MAP | GOVD_LOCAL)) == 0
6835 && lang_hooks.decls.omp_privatize_by_reference (decl))
6837 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
6839 /* Similar to the direct variable sized case above, we'll need the
6840 size of references being privatized. */
6841 if ((flags & GOVD_SHARED) == 0)
6843 t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
6844 if (DECL_P (t))
6845 omp_notice_variable (ctx, t, true);
6849 if (n != NULL)
6850 n->value |= flags;
6851 else
6852 splay_tree_insert (ctx->variables, (splay_tree_key)decl, flags);
6854 /* For reductions clauses in OpenACC loop directives, by default create a
6855 copy clause on the enclosing parallel construct for carrying back the
6856 results. */
6857 if (ctx->region_type == ORT_ACC && (flags & GOVD_REDUCTION))
6859 struct gimplify_omp_ctx *outer_ctx = ctx->outer_context;
6860 while (outer_ctx)
6862 n = splay_tree_lookup (outer_ctx->variables, (splay_tree_key)decl);
6863 if (n != NULL)
6865 /* Ignore local variables and explicitly declared clauses. */
6866 if (n->value & (GOVD_LOCAL | GOVD_EXPLICIT))
6867 break;
6868 else if (outer_ctx->region_type == ORT_ACC_KERNELS)
6870 /* According to the OpenACC spec, such a reduction variable
6871 should already have a copy map on a kernels construct,
6872 verify that here. */
6873 gcc_assert (!(n->value & GOVD_FIRSTPRIVATE)
6874 && (n->value & GOVD_MAP));
6876 else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
6878 /* Remove firstprivate and make it a copy map. */
6879 n->value &= ~GOVD_FIRSTPRIVATE;
6880 n->value |= GOVD_MAP;
6883 else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
6885 splay_tree_insert (outer_ctx->variables, (splay_tree_key)decl,
6886 GOVD_MAP | GOVD_SEEN);
6887 break;
6889 outer_ctx = outer_ctx->outer_context;
6894 /* Notice a threadprivate variable DECL used in OMP context CTX.
6895 This just prints out diagnostics about threadprivate variable uses
6896 in untied tasks. If DECL2 is non-NULL, prevent this warning
6897 on that variable. */
6899 static bool
6900 omp_notice_threadprivate_variable (struct gimplify_omp_ctx *ctx, tree decl,
6901 tree decl2)
6903 splay_tree_node n;
6904 struct gimplify_omp_ctx *octx;
6906 for (octx = ctx; octx; octx = octx->outer_context)
6907 if ((octx->region_type & ORT_TARGET) != 0)
6909 n = splay_tree_lookup (octx->variables, (splay_tree_key)decl);
6910 if (n == NULL)
6912 error ("threadprivate variable %qE used in target region",
6913 DECL_NAME (decl));
6914 error_at (octx->location, "enclosing target region");
6915 splay_tree_insert (octx->variables, (splay_tree_key)decl, 0);
6917 if (decl2)
6918 splay_tree_insert (octx->variables, (splay_tree_key)decl2, 0);
6921 if (ctx->region_type != ORT_UNTIED_TASK)
6922 return false;
6923 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
6924 if (n == NULL)
6926 error ("threadprivate variable %qE used in untied task",
6927 DECL_NAME (decl));
6928 error_at (ctx->location, "enclosing task");
6929 splay_tree_insert (ctx->variables, (splay_tree_key)decl, 0);
6931 if (decl2)
6932 splay_tree_insert (ctx->variables, (splay_tree_key)decl2, 0);
6933 return false;
6936 /* Return true if global var DECL is device resident. */
6938 static bool
6939 device_resident_p (tree decl)
6941 tree attr = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (decl));
6943 if (!attr)
6944 return false;
6946 for (tree t = TREE_VALUE (attr); t; t = TREE_PURPOSE (t))
6948 tree c = TREE_VALUE (t);
6949 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DEVICE_RESIDENT)
6950 return true;
6953 return false;
6956 /* Return true if DECL has an ACC DECLARE attribute. */
6958 static bool
6959 is_oacc_declared (tree decl)
6961 tree t = TREE_CODE (decl) == MEM_REF ? TREE_OPERAND (decl, 0) : decl;
6962 tree declared = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (t));
6963 return declared != NULL_TREE;
6966 /* Determine outer default flags for DECL mentioned in an OMP region
6967 but not declared in an enclosing clause.
6969 ??? Some compiler-generated variables (like SAVE_EXPRs) could be
6970 remapped firstprivate instead of shared. To some extent this is
6971 addressed in omp_firstprivatize_type_sizes, but not
6972 effectively. */
6974 static unsigned
6975 omp_default_clause (struct gimplify_omp_ctx *ctx, tree decl,
6976 bool in_code, unsigned flags)
6978 enum omp_clause_default_kind default_kind = ctx->default_kind;
6979 enum omp_clause_default_kind kind;
6981 kind = lang_hooks.decls.omp_predetermined_sharing (decl);
6982 if (kind != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
6983 default_kind = kind;
6985 switch (default_kind)
6987 case OMP_CLAUSE_DEFAULT_NONE:
6989 const char *rtype;
6991 if (ctx->region_type & ORT_PARALLEL)
6992 rtype = "parallel";
6993 else if ((ctx->region_type & ORT_TASKLOOP) == ORT_TASKLOOP)
6994 rtype = "taskloop";
6995 else if (ctx->region_type & ORT_TASK)
6996 rtype = "task";
6997 else if (ctx->region_type & ORT_TEAMS)
6998 rtype = "teams";
6999 else
7000 gcc_unreachable ();
7002 error ("%qE not specified in enclosing %qs",
7003 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rtype);
7004 error_at (ctx->location, "enclosing %qs", rtype);
7006 /* FALLTHRU */
7007 case OMP_CLAUSE_DEFAULT_SHARED:
7008 flags |= GOVD_SHARED;
7009 break;
7010 case OMP_CLAUSE_DEFAULT_PRIVATE:
7011 flags |= GOVD_PRIVATE;
7012 break;
7013 case OMP_CLAUSE_DEFAULT_FIRSTPRIVATE:
7014 flags |= GOVD_FIRSTPRIVATE;
7015 break;
7016 case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
7017 /* decl will be either GOVD_FIRSTPRIVATE or GOVD_SHARED. */
7018 gcc_assert ((ctx->region_type & ORT_TASK) != 0);
7019 if (struct gimplify_omp_ctx *octx = ctx->outer_context)
7021 omp_notice_variable (octx, decl, in_code);
7022 for (; octx; octx = octx->outer_context)
7024 splay_tree_node n2;
7026 n2 = splay_tree_lookup (octx->variables, (splay_tree_key) decl);
7027 if ((octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)) != 0
7028 && (n2 == NULL || (n2->value & GOVD_DATA_SHARE_CLASS) == 0))
7029 continue;
7030 if (n2 && (n2->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED)
7032 flags |= GOVD_FIRSTPRIVATE;
7033 goto found_outer;
7035 if ((octx->region_type & (ORT_PARALLEL | ORT_TEAMS)) != 0)
7037 flags |= GOVD_SHARED;
7038 goto found_outer;
7043 if (TREE_CODE (decl) == PARM_DECL
7044 || (!is_global_var (decl)
7045 && DECL_CONTEXT (decl) == current_function_decl))
7046 flags |= GOVD_FIRSTPRIVATE;
7047 else
7048 flags |= GOVD_SHARED;
7049 found_outer:
7050 break;
7052 default:
7053 gcc_unreachable ();
7056 return flags;
7060 /* Determine outer default flags for DECL mentioned in an OACC region
7061 but not declared in an enclosing clause. */
7063 static unsigned
7064 oacc_default_clause (struct gimplify_omp_ctx *ctx, tree decl, unsigned flags)
7066 const char *rkind;
7067 bool on_device = false;
7068 bool declared = is_oacc_declared (decl);
7069 tree type = TREE_TYPE (decl);
7071 if (lang_hooks.decls.omp_privatize_by_reference (decl))
7072 type = TREE_TYPE (type);
7074 if ((ctx->region_type & (ORT_ACC_PARALLEL | ORT_ACC_KERNELS)) != 0
7075 && is_global_var (decl)
7076 && device_resident_p (decl))
7078 on_device = true;
7079 flags |= GOVD_MAP_TO_ONLY;
7082 switch (ctx->region_type)
7084 case ORT_ACC_KERNELS:
7085 rkind = "kernels";
7087 if (AGGREGATE_TYPE_P (type))
7089 /* Aggregates default to 'present_or_copy', or 'present'. */
7090 if (ctx->default_kind != OMP_CLAUSE_DEFAULT_PRESENT)
7091 flags |= GOVD_MAP;
7092 else
7093 flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
7095 else
7096 /* Scalars default to 'copy'. */
7097 flags |= GOVD_MAP | GOVD_MAP_FORCE;
7099 break;
7101 case ORT_ACC_PARALLEL:
7102 rkind = "parallel";
7104 if (on_device || declared)
7105 flags |= GOVD_MAP;
7106 else if (AGGREGATE_TYPE_P (type))
7108 /* Aggregates default to 'present_or_copy', or 'present'. */
7109 if (ctx->default_kind != OMP_CLAUSE_DEFAULT_PRESENT)
7110 flags |= GOVD_MAP;
7111 else
7112 flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
7114 else
7115 /* Scalars default to 'firstprivate'. */
7116 flags |= GOVD_FIRSTPRIVATE;
7118 break;
7120 default:
7121 gcc_unreachable ();
7124 if (DECL_ARTIFICIAL (decl))
7125 ; /* We can get compiler-generated decls, and should not complain
7126 about them. */
7127 else if (ctx->default_kind == OMP_CLAUSE_DEFAULT_NONE)
7129 error ("%qE not specified in enclosing OpenACC %qs construct",
7130 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rkind);
7131 inform (ctx->location, "enclosing OpenACC %qs construct", rkind);
7133 else if (ctx->default_kind == OMP_CLAUSE_DEFAULT_PRESENT)
7134 ; /* Handled above. */
7135 else
7136 gcc_checking_assert (ctx->default_kind == OMP_CLAUSE_DEFAULT_SHARED);
7138 return flags;
7141 /* Record the fact that DECL was used within the OMP context CTX.
7142 IN_CODE is true when real code uses DECL, and false when we should
7143 merely emit default(none) errors. Return true if DECL is going to
7144 be remapped and thus DECL shouldn't be gimplified into its
7145 DECL_VALUE_EXPR (if any). */
7147 static bool
7148 omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
7150 splay_tree_node n;
7151 unsigned flags = in_code ? GOVD_SEEN : 0;
7152 bool ret = false, shared;
7154 if (error_operand_p (decl))
7155 return false;
7157 if (ctx->region_type == ORT_NONE)
7158 return lang_hooks.decls.omp_disregard_value_expr (decl, false);
7160 if (is_global_var (decl))
7162 /* Threadprivate variables are predetermined. */
7163 if (DECL_THREAD_LOCAL_P (decl))
7164 return omp_notice_threadprivate_variable (ctx, decl, NULL_TREE);
7166 if (DECL_HAS_VALUE_EXPR_P (decl))
7168 tree value = get_base_address (DECL_VALUE_EXPR (decl));
7170 if (value && DECL_P (value) && DECL_THREAD_LOCAL_P (value))
7171 return omp_notice_threadprivate_variable (ctx, decl, value);
7174 if (gimplify_omp_ctxp->outer_context == NULL
7175 && VAR_P (decl)
7176 && oacc_get_fn_attrib (current_function_decl))
7178 location_t loc = DECL_SOURCE_LOCATION (decl);
7180 if (lookup_attribute ("omp declare target link",
7181 DECL_ATTRIBUTES (decl)))
7183 error_at (loc,
7184 "%qE with %<link%> clause used in %<routine%> function",
7185 DECL_NAME (decl));
7186 return false;
7188 else if (!lookup_attribute ("omp declare target",
7189 DECL_ATTRIBUTES (decl)))
7191 error_at (loc,
7192 "%qE requires a %<declare%> directive for use "
7193 "in a %<routine%> function", DECL_NAME (decl));
7194 return false;
7199 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7200 if ((ctx->region_type & ORT_TARGET) != 0)
7202 ret = lang_hooks.decls.omp_disregard_value_expr (decl, true);
7203 if (n == NULL)
7205 unsigned nflags = flags;
7206 if ((ctx->region_type & ORT_ACC) == 0)
7208 bool is_declare_target = false;
7209 if (is_global_var (decl)
7210 && varpool_node::get_create (decl)->offloadable)
7212 struct gimplify_omp_ctx *octx;
7213 for (octx = ctx->outer_context;
7214 octx; octx = octx->outer_context)
7216 n = splay_tree_lookup (octx->variables,
7217 (splay_tree_key)decl);
7218 if (n
7219 && (n->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED
7220 && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
7221 break;
7223 is_declare_target = octx == NULL;
7225 if (!is_declare_target)
7227 int gdmk;
7228 if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
7229 || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
7230 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
7231 == POINTER_TYPE)))
7232 gdmk = GDMK_POINTER;
7233 else if (lang_hooks.decls.omp_scalar_p (decl))
7234 gdmk = GDMK_SCALAR;
7235 else
7236 gdmk = GDMK_AGGREGATE;
7237 if (ctx->defaultmap[gdmk] == 0)
7239 tree d = lang_hooks.decls.omp_report_decl (decl);
7240 error ("%qE not specified in enclosing %<target%>",
7241 DECL_NAME (d));
7242 error_at (ctx->location, "enclosing %<target%>");
7244 else if (ctx->defaultmap[gdmk]
7245 & (GOVD_MAP_0LEN_ARRAY | GOVD_FIRSTPRIVATE))
7246 nflags |= ctx->defaultmap[gdmk];
7247 else
7249 gcc_assert (ctx->defaultmap[gdmk] & GOVD_MAP);
7250 nflags |= ctx->defaultmap[gdmk] & ~GOVD_MAP;
7255 struct gimplify_omp_ctx *octx = ctx->outer_context;
7256 if ((ctx->region_type & ORT_ACC) && octx)
7258 /* Look in outer OpenACC contexts, to see if there's a
7259 data attribute for this variable. */
7260 omp_notice_variable (octx, decl, in_code);
7262 for (; octx; octx = octx->outer_context)
7264 if (!(octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)))
7265 break;
7266 splay_tree_node n2
7267 = splay_tree_lookup (octx->variables,
7268 (splay_tree_key) decl);
7269 if (n2)
7271 if (octx->region_type == ORT_ACC_HOST_DATA)
7272 error ("variable %qE declared in enclosing "
7273 "%<host_data%> region", DECL_NAME (decl));
7274 nflags |= GOVD_MAP;
7275 if (octx->region_type == ORT_ACC_DATA
7276 && (n2->value & GOVD_MAP_0LEN_ARRAY))
7277 nflags |= GOVD_MAP_0LEN_ARRAY;
7278 goto found_outer;
7283 if ((nflags & ~(GOVD_MAP_TO_ONLY | GOVD_MAP_FROM_ONLY
7284 | GOVD_MAP_ALLOC_ONLY)) == flags)
7286 tree type = TREE_TYPE (decl);
7288 if (gimplify_omp_ctxp->target_firstprivatize_array_bases
7289 && lang_hooks.decls.omp_privatize_by_reference (decl))
7290 type = TREE_TYPE (type);
7291 if (!lang_hooks.types.omp_mappable_type (type))
7293 error ("%qD referenced in target region does not have "
7294 "a mappable type", decl);
7295 nflags |= GOVD_MAP | GOVD_EXPLICIT;
7297 else
7299 if ((ctx->region_type & ORT_ACC) != 0)
7300 nflags = oacc_default_clause (ctx, decl, flags);
7301 else
7302 nflags |= GOVD_MAP;
7305 found_outer:
7306 omp_add_variable (ctx, decl, nflags);
7308 else
7310 /* If nothing changed, there's nothing left to do. */
7311 if ((n->value & flags) == flags)
7312 return ret;
7313 flags |= n->value;
7314 n->value = flags;
7316 goto do_outer;
7319 if (n == NULL)
7321 if (ctx->region_type == ORT_WORKSHARE
7322 || ctx->region_type == ORT_TASKGROUP
7323 || ctx->region_type == ORT_SIMD
7324 || ctx->region_type == ORT_ACC
7325 || (ctx->region_type & ORT_TARGET_DATA) != 0)
7326 goto do_outer;
7328 flags = omp_default_clause (ctx, decl, in_code, flags);
7330 if ((flags & GOVD_PRIVATE)
7331 && lang_hooks.decls.omp_private_outer_ref (decl))
7332 flags |= GOVD_PRIVATE_OUTER_REF;
7334 omp_add_variable (ctx, decl, flags);
7336 shared = (flags & GOVD_SHARED) != 0;
7337 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7338 goto do_outer;
7341 if ((n->value & (GOVD_SEEN | GOVD_LOCAL)) == 0
7342 && (flags & (GOVD_SEEN | GOVD_LOCAL)) == GOVD_SEEN
7343 && DECL_SIZE (decl))
7345 if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
7347 splay_tree_node n2;
7348 tree t = DECL_VALUE_EXPR (decl);
7349 gcc_assert (TREE_CODE (t) == INDIRECT_REF);
7350 t = TREE_OPERAND (t, 0);
7351 gcc_assert (DECL_P (t));
7352 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
7353 n2->value |= GOVD_SEEN;
7355 else if (lang_hooks.decls.omp_privatize_by_reference (decl)
7356 && TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)))
7357 && (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))))
7358 != INTEGER_CST))
7360 splay_tree_node n2;
7361 tree t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
7362 gcc_assert (DECL_P (t));
7363 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
7364 if (n2)
7365 omp_notice_variable (ctx, t, true);
7369 shared = ((flags | n->value) & GOVD_SHARED) != 0;
7370 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7372 /* If nothing changed, there's nothing left to do. */
7373 if ((n->value & flags) == flags)
7374 return ret;
7375 flags |= n->value;
7376 n->value = flags;
7378 do_outer:
7379 /* If the variable is private in the current context, then we don't
7380 need to propagate anything to an outer context. */
7381 if ((flags & GOVD_PRIVATE) && !(flags & GOVD_PRIVATE_OUTER_REF))
7382 return ret;
7383 if ((flags & (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7384 == (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7385 return ret;
7386 if ((flags & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
7387 | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7388 == (GOVD_LASTPRIVATE | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7389 return ret;
7390 if (ctx->outer_context
7391 && omp_notice_variable (ctx->outer_context, decl, in_code))
7392 return true;
7393 return ret;
7396 /* Verify that DECL is private within CTX. If there's specific information
7397 to the contrary in the innermost scope, generate an error. */
7399 static bool
7400 omp_is_private (struct gimplify_omp_ctx *ctx, tree decl, int simd)
7402 splay_tree_node n;
7404 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7405 if (n != NULL)
7407 if (n->value & GOVD_SHARED)
7409 if (ctx == gimplify_omp_ctxp)
7411 if (simd)
7412 error ("iteration variable %qE is predetermined linear",
7413 DECL_NAME (decl));
7414 else
7415 error ("iteration variable %qE should be private",
7416 DECL_NAME (decl));
7417 n->value = GOVD_PRIVATE;
7418 return true;
7420 else
7421 return false;
7423 else if ((n->value & GOVD_EXPLICIT) != 0
7424 && (ctx == gimplify_omp_ctxp
7425 || (ctx->region_type == ORT_COMBINED_PARALLEL
7426 && gimplify_omp_ctxp->outer_context == ctx)))
7428 if ((n->value & GOVD_FIRSTPRIVATE) != 0)
7429 error ("iteration variable %qE should not be firstprivate",
7430 DECL_NAME (decl));
7431 else if ((n->value & GOVD_REDUCTION) != 0)
7432 error ("iteration variable %qE should not be reduction",
7433 DECL_NAME (decl));
7434 else if (simd != 1 && (n->value & GOVD_LINEAR) != 0)
7435 error ("iteration variable %qE should not be linear",
7436 DECL_NAME (decl));
7438 return (ctx == gimplify_omp_ctxp
7439 || (ctx->region_type == ORT_COMBINED_PARALLEL
7440 && gimplify_omp_ctxp->outer_context == ctx));
7443 if (ctx->region_type != ORT_WORKSHARE
7444 && ctx->region_type != ORT_TASKGROUP
7445 && ctx->region_type != ORT_SIMD
7446 && ctx->region_type != ORT_ACC)
7447 return false;
7448 else if (ctx->outer_context)
7449 return omp_is_private (ctx->outer_context, decl, simd);
7450 return false;
7453 /* Return true if DECL is private within a parallel region
7454 that binds to the current construct's context or in parallel
7455 region's REDUCTION clause. */
7457 static bool
7458 omp_check_private (struct gimplify_omp_ctx *ctx, tree decl, bool copyprivate)
7460 splay_tree_node n;
7464 ctx = ctx->outer_context;
7465 if (ctx == NULL)
7467 if (is_global_var (decl))
7468 return false;
7470 /* References might be private, but might be shared too,
7471 when checking for copyprivate, assume they might be
7472 private, otherwise assume they might be shared. */
7473 if (copyprivate)
7474 return true;
7476 if (lang_hooks.decls.omp_privatize_by_reference (decl))
7477 return false;
7479 /* Treat C++ privatized non-static data members outside
7480 of the privatization the same. */
7481 if (omp_member_access_dummy_var (decl))
7482 return false;
7484 return true;
7487 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
7489 if ((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
7490 && (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0))
7491 continue;
7493 if (n != NULL)
7495 if ((n->value & GOVD_LOCAL) != 0
7496 && omp_member_access_dummy_var (decl))
7497 return false;
7498 return (n->value & GOVD_SHARED) == 0;
7501 while (ctx->region_type == ORT_WORKSHARE
7502 || ctx->region_type == ORT_TASKGROUP
7503 || ctx->region_type == ORT_SIMD
7504 || ctx->region_type == ORT_ACC);
7505 return false;
7508 /* Callback for walk_tree to find a DECL_EXPR for the given DECL. */
7510 static tree
7511 find_decl_expr (tree *tp, int *walk_subtrees, void *data)
7513 tree t = *tp;
7515 /* If this node has been visited, unmark it and keep looking. */
7516 if (TREE_CODE (t) == DECL_EXPR && DECL_EXPR_DECL (t) == (tree) data)
7517 return t;
7519 if (IS_TYPE_OR_DECL_P (t))
7520 *walk_subtrees = 0;
7521 return NULL_TREE;
7524 /* If *LIST_P contains any OpenMP depend clauses with iterators,
7525 lower all the depend clauses by populating corresponding depend
7526 array. Returns 0 if there are no such depend clauses, or
7527 2 if all depend clauses should be removed, 1 otherwise. */
7529 static int
7530 gimplify_omp_depend (tree *list_p, gimple_seq *pre_p)
7532 tree c;
7533 gimple *g;
7534 size_t n[4] = { 0, 0, 0, 0 };
7535 bool unused[4];
7536 tree counts[4] = { NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE };
7537 tree last_iter = NULL_TREE, last_count = NULL_TREE;
7538 size_t i, j;
7539 location_t first_loc = UNKNOWN_LOCATION;
7541 for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
7542 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
7544 switch (OMP_CLAUSE_DEPEND_KIND (c))
7546 case OMP_CLAUSE_DEPEND_IN:
7547 i = 2;
7548 break;
7549 case OMP_CLAUSE_DEPEND_OUT:
7550 case OMP_CLAUSE_DEPEND_INOUT:
7551 i = 0;
7552 break;
7553 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
7554 i = 1;
7555 break;
7556 case OMP_CLAUSE_DEPEND_DEPOBJ:
7557 i = 3;
7558 break;
7559 case OMP_CLAUSE_DEPEND_SOURCE:
7560 case OMP_CLAUSE_DEPEND_SINK:
7561 continue;
7562 default:
7563 gcc_unreachable ();
7565 tree t = OMP_CLAUSE_DECL (c);
7566 if (first_loc == UNKNOWN_LOCATION)
7567 first_loc = OMP_CLAUSE_LOCATION (c);
7568 if (TREE_CODE (t) == TREE_LIST
7569 && TREE_PURPOSE (t)
7570 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
7572 if (TREE_PURPOSE (t) != last_iter)
7574 tree tcnt = size_one_node;
7575 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
7577 if (gimplify_expr (&TREE_VEC_ELT (it, 1), pre_p, NULL,
7578 is_gimple_val, fb_rvalue) == GS_ERROR
7579 || gimplify_expr (&TREE_VEC_ELT (it, 2), pre_p, NULL,
7580 is_gimple_val, fb_rvalue) == GS_ERROR
7581 || gimplify_expr (&TREE_VEC_ELT (it, 3), pre_p, NULL,
7582 is_gimple_val, fb_rvalue) == GS_ERROR
7583 || (gimplify_expr (&TREE_VEC_ELT (it, 4), pre_p, NULL,
7584 is_gimple_val, fb_rvalue)
7585 == GS_ERROR))
7586 return 2;
7587 tree var = TREE_VEC_ELT (it, 0);
7588 tree begin = TREE_VEC_ELT (it, 1);
7589 tree end = TREE_VEC_ELT (it, 2);
7590 tree step = TREE_VEC_ELT (it, 3);
7591 tree orig_step = TREE_VEC_ELT (it, 4);
7592 tree type = TREE_TYPE (var);
7593 tree stype = TREE_TYPE (step);
7594 location_t loc = DECL_SOURCE_LOCATION (var);
7595 tree endmbegin;
7596 /* Compute count for this iterator as
7597 orig_step > 0
7598 ? (begin < end ? (end - begin + (step - 1)) / step : 0)
7599 : (begin > end ? (end - begin + (step + 1)) / step : 0)
7600 and compute product of those for the entire depend
7601 clause. */
7602 if (POINTER_TYPE_P (type))
7603 endmbegin = fold_build2_loc (loc, POINTER_DIFF_EXPR,
7604 stype, end, begin);
7605 else
7606 endmbegin = fold_build2_loc (loc, MINUS_EXPR, type,
7607 end, begin);
7608 tree stepm1 = fold_build2_loc (loc, MINUS_EXPR, stype,
7609 step,
7610 build_int_cst (stype, 1));
7611 tree stepp1 = fold_build2_loc (loc, PLUS_EXPR, stype, step,
7612 build_int_cst (stype, 1));
7613 tree pos = fold_build2_loc (loc, PLUS_EXPR, stype,
7614 unshare_expr (endmbegin),
7615 stepm1);
7616 pos = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype,
7617 pos, step);
7618 tree neg = fold_build2_loc (loc, PLUS_EXPR, stype,
7619 endmbegin, stepp1);
7620 if (TYPE_UNSIGNED (stype))
7622 neg = fold_build1_loc (loc, NEGATE_EXPR, stype, neg);
7623 step = fold_build1_loc (loc, NEGATE_EXPR, stype, step);
7625 neg = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype,
7626 neg, step);
7627 step = NULL_TREE;
7628 tree cond = fold_build2_loc (loc, LT_EXPR,
7629 boolean_type_node,
7630 begin, end);
7631 pos = fold_build3_loc (loc, COND_EXPR, stype, cond, pos,
7632 build_int_cst (stype, 0));
7633 cond = fold_build2_loc (loc, LT_EXPR, boolean_type_node,
7634 end, begin);
7635 neg = fold_build3_loc (loc, COND_EXPR, stype, cond, neg,
7636 build_int_cst (stype, 0));
7637 tree osteptype = TREE_TYPE (orig_step);
7638 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
7639 orig_step,
7640 build_int_cst (osteptype, 0));
7641 tree cnt = fold_build3_loc (loc, COND_EXPR, stype,
7642 cond, pos, neg);
7643 cnt = fold_convert_loc (loc, sizetype, cnt);
7644 if (gimplify_expr (&cnt, pre_p, NULL, is_gimple_val,
7645 fb_rvalue) == GS_ERROR)
7646 return 2;
7647 tcnt = size_binop_loc (loc, MULT_EXPR, tcnt, cnt);
7649 if (gimplify_expr (&tcnt, pre_p, NULL, is_gimple_val,
7650 fb_rvalue) == GS_ERROR)
7651 return 2;
7652 last_iter = TREE_PURPOSE (t);
7653 last_count = tcnt;
7655 if (counts[i] == NULL_TREE)
7656 counts[i] = last_count;
7657 else
7658 counts[i] = size_binop_loc (OMP_CLAUSE_LOCATION (c),
7659 PLUS_EXPR, counts[i], last_count);
7661 else
7662 n[i]++;
7664 for (i = 0; i < 4; i++)
7665 if (counts[i])
7666 break;
7667 if (i == 4)
7668 return 0;
7670 tree total = size_zero_node;
7671 for (i = 0; i < 4; i++)
7673 unused[i] = counts[i] == NULL_TREE && n[i] == 0;
7674 if (counts[i] == NULL_TREE)
7675 counts[i] = size_zero_node;
7676 if (n[i])
7677 counts[i] = size_binop (PLUS_EXPR, counts[i], size_int (n[i]));
7678 if (gimplify_expr (&counts[i], pre_p, NULL, is_gimple_val,
7679 fb_rvalue) == GS_ERROR)
7680 return 2;
7681 total = size_binop (PLUS_EXPR, total, counts[i]);
7684 if (gimplify_expr (&total, pre_p, NULL, is_gimple_val, fb_rvalue)
7685 == GS_ERROR)
7686 return 2;
7687 bool is_old = unused[1] && unused[3];
7688 tree totalpx = size_binop (PLUS_EXPR, unshare_expr (total),
7689 size_int (is_old ? 1 : 4));
7690 tree type = build_array_type (ptr_type_node, build_index_type (totalpx));
7691 tree array = create_tmp_var_raw (type);
7692 TREE_ADDRESSABLE (array) = 1;
7693 if (TREE_CODE (totalpx) != INTEGER_CST)
7695 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (array)))
7696 gimplify_type_sizes (TREE_TYPE (array), pre_p);
7697 if (gimplify_omp_ctxp)
7699 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
7700 while (ctx
7701 && (ctx->region_type == ORT_WORKSHARE
7702 || ctx->region_type == ORT_TASKGROUP
7703 || ctx->region_type == ORT_SIMD
7704 || ctx->region_type == ORT_ACC))
7705 ctx = ctx->outer_context;
7706 if (ctx)
7707 omp_add_variable (ctx, array, GOVD_LOCAL | GOVD_SEEN);
7709 gimplify_vla_decl (array, pre_p);
7711 else
7712 gimple_add_tmp_var (array);
7713 tree r = build4 (ARRAY_REF, ptr_type_node, array, size_int (0), NULL_TREE,
7714 NULL_TREE);
7715 tree tem;
7716 if (!is_old)
7718 tem = build2 (MODIFY_EXPR, void_type_node, r,
7719 build_int_cst (ptr_type_node, 0));
7720 gimplify_and_add (tem, pre_p);
7721 r = build4 (ARRAY_REF, ptr_type_node, array, size_int (1), NULL_TREE,
7722 NULL_TREE);
7724 tem = build2 (MODIFY_EXPR, void_type_node, r,
7725 fold_convert (ptr_type_node, total));
7726 gimplify_and_add (tem, pre_p);
7727 for (i = 1; i < (is_old ? 2 : 4); i++)
7729 r = build4 (ARRAY_REF, ptr_type_node, array, size_int (i + !is_old),
7730 NULL_TREE, NULL_TREE);
7731 tem = build2 (MODIFY_EXPR, void_type_node, r, counts[i - 1]);
7732 gimplify_and_add (tem, pre_p);
7735 tree cnts[4];
7736 for (j = 4; j; j--)
7737 if (!unused[j - 1])
7738 break;
7739 for (i = 0; i < 4; i++)
7741 if (i && (i >= j || unused[i - 1]))
7743 cnts[i] = cnts[i - 1];
7744 continue;
7746 cnts[i] = create_tmp_var (sizetype);
7747 if (i == 0)
7748 g = gimple_build_assign (cnts[i], size_int (is_old ? 2 : 5));
7749 else
7751 tree t;
7752 if (is_old)
7753 t = size_binop (PLUS_EXPR, counts[0], size_int (2));
7754 else
7755 t = size_binop (PLUS_EXPR, cnts[i - 1], counts[i - 1]);
7756 if (gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue)
7757 == GS_ERROR)
7758 return 2;
7759 g = gimple_build_assign (cnts[i], t);
7761 gimple_seq_add_stmt (pre_p, g);
7764 last_iter = NULL_TREE;
7765 tree last_bind = NULL_TREE;
7766 tree *last_body = NULL;
7767 for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
7768 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
7770 switch (OMP_CLAUSE_DEPEND_KIND (c))
7772 case OMP_CLAUSE_DEPEND_IN:
7773 i = 2;
7774 break;
7775 case OMP_CLAUSE_DEPEND_OUT:
7776 case OMP_CLAUSE_DEPEND_INOUT:
7777 i = 0;
7778 break;
7779 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
7780 i = 1;
7781 break;
7782 case OMP_CLAUSE_DEPEND_DEPOBJ:
7783 i = 3;
7784 break;
7785 case OMP_CLAUSE_DEPEND_SOURCE:
7786 case OMP_CLAUSE_DEPEND_SINK:
7787 continue;
7788 default:
7789 gcc_unreachable ();
7791 tree t = OMP_CLAUSE_DECL (c);
7792 if (TREE_CODE (t) == TREE_LIST
7793 && TREE_PURPOSE (t)
7794 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
7796 if (TREE_PURPOSE (t) != last_iter)
7798 if (last_bind)
7799 gimplify_and_add (last_bind, pre_p);
7800 tree block = TREE_VEC_ELT (TREE_PURPOSE (t), 5);
7801 last_bind = build3 (BIND_EXPR, void_type_node,
7802 BLOCK_VARS (block), NULL, block);
7803 TREE_SIDE_EFFECTS (last_bind) = 1;
7804 SET_EXPR_LOCATION (last_bind, OMP_CLAUSE_LOCATION (c));
7805 tree *p = &BIND_EXPR_BODY (last_bind);
7806 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
7808 tree var = TREE_VEC_ELT (it, 0);
7809 tree begin = TREE_VEC_ELT (it, 1);
7810 tree end = TREE_VEC_ELT (it, 2);
7811 tree step = TREE_VEC_ELT (it, 3);
7812 tree orig_step = TREE_VEC_ELT (it, 4);
7813 tree type = TREE_TYPE (var);
7814 location_t loc = DECL_SOURCE_LOCATION (var);
7815 /* Emit:
7816 var = begin;
7817 goto cond_label;
7818 beg_label:
7820 var = var + step;
7821 cond_label:
7822 if (orig_step > 0) {
7823 if (var < end) goto beg_label;
7824 } else {
7825 if (var > end) goto beg_label;
7827 for each iterator, with inner iterators added to
7828 the ... above. */
7829 tree beg_label = create_artificial_label (loc);
7830 tree cond_label = NULL_TREE;
7831 tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
7832 var, begin);
7833 append_to_statement_list_force (tem, p);
7834 tem = build_and_jump (&cond_label);
7835 append_to_statement_list_force (tem, p);
7836 tem = build1 (LABEL_EXPR, void_type_node, beg_label);
7837 append_to_statement_list (tem, p);
7838 tree bind = build3 (BIND_EXPR, void_type_node, NULL_TREE,
7839 NULL_TREE, NULL_TREE);
7840 TREE_SIDE_EFFECTS (bind) = 1;
7841 SET_EXPR_LOCATION (bind, loc);
7842 append_to_statement_list_force (bind, p);
7843 if (POINTER_TYPE_P (type))
7844 tem = build2_loc (loc, POINTER_PLUS_EXPR, type,
7845 var, fold_convert_loc (loc, sizetype,
7846 step));
7847 else
7848 tem = build2_loc (loc, PLUS_EXPR, type, var, step);
7849 tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
7850 var, tem);
7851 append_to_statement_list_force (tem, p);
7852 tem = build1 (LABEL_EXPR, void_type_node, cond_label);
7853 append_to_statement_list (tem, p);
7854 tree cond = fold_build2_loc (loc, LT_EXPR,
7855 boolean_type_node,
7856 var, end);
7857 tree pos
7858 = fold_build3_loc (loc, COND_EXPR, void_type_node,
7859 cond, build_and_jump (&beg_label),
7860 void_node);
7861 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
7862 var, end);
7863 tree neg
7864 = fold_build3_loc (loc, COND_EXPR, void_type_node,
7865 cond, build_and_jump (&beg_label),
7866 void_node);
7867 tree osteptype = TREE_TYPE (orig_step);
7868 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
7869 orig_step,
7870 build_int_cst (osteptype, 0));
7871 tem = fold_build3_loc (loc, COND_EXPR, void_type_node,
7872 cond, pos, neg);
7873 append_to_statement_list_force (tem, p);
7874 p = &BIND_EXPR_BODY (bind);
7876 last_body = p;
7878 last_iter = TREE_PURPOSE (t);
7879 if (TREE_CODE (TREE_VALUE (t)) == COMPOUND_EXPR)
7881 append_to_statement_list (TREE_OPERAND (TREE_VALUE (t),
7882 0), last_body);
7883 TREE_VALUE (t) = TREE_OPERAND (TREE_VALUE (t), 1);
7885 if (error_operand_p (TREE_VALUE (t)))
7886 return 2;
7887 TREE_VALUE (t) = build_fold_addr_expr (TREE_VALUE (t));
7888 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
7889 NULL_TREE, NULL_TREE);
7890 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
7891 void_type_node, r, TREE_VALUE (t));
7892 append_to_statement_list_force (tem, last_body);
7893 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
7894 void_type_node, cnts[i],
7895 size_binop (PLUS_EXPR, cnts[i], size_int (1)));
7896 append_to_statement_list_force (tem, last_body);
7897 TREE_VALUE (t) = null_pointer_node;
7899 else
7901 if (last_bind)
7903 gimplify_and_add (last_bind, pre_p);
7904 last_bind = NULL_TREE;
7906 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
7908 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
7909 NULL, is_gimple_val, fb_rvalue);
7910 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
7912 if (error_operand_p (OMP_CLAUSE_DECL (c)))
7913 return 2;
7914 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
7915 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
7916 is_gimple_val, fb_rvalue) == GS_ERROR)
7917 return 2;
7918 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
7919 NULL_TREE, NULL_TREE);
7920 tem = build2 (MODIFY_EXPR, void_type_node, r, OMP_CLAUSE_DECL (c));
7921 gimplify_and_add (tem, pre_p);
7922 g = gimple_build_assign (cnts[i], size_binop (PLUS_EXPR, cnts[i],
7923 size_int (1)));
7924 gimple_seq_add_stmt (pre_p, g);
7927 if (last_bind)
7928 gimplify_and_add (last_bind, pre_p);
7929 tree cond = boolean_false_node;
7930 if (is_old)
7932 if (!unused[0])
7933 cond = build2_loc (first_loc, NE_EXPR, boolean_type_node, cnts[0],
7934 size_binop_loc (first_loc, PLUS_EXPR, counts[0],
7935 size_int (2)));
7936 if (!unused[2])
7937 cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond,
7938 build2_loc (first_loc, NE_EXPR, boolean_type_node,
7939 cnts[2],
7940 size_binop_loc (first_loc, PLUS_EXPR,
7941 totalpx,
7942 size_int (1))));
7944 else
7946 tree prev = size_int (5);
7947 for (i = 0; i < 4; i++)
7949 if (unused[i])
7950 continue;
7951 prev = size_binop_loc (first_loc, PLUS_EXPR, counts[i], prev);
7952 cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond,
7953 build2_loc (first_loc, NE_EXPR, boolean_type_node,
7954 cnts[i], unshare_expr (prev)));
7957 tem = build3_loc (first_loc, COND_EXPR, void_type_node, cond,
7958 build_call_expr_loc (first_loc,
7959 builtin_decl_explicit (BUILT_IN_TRAP),
7960 0), void_node);
7961 gimplify_and_add (tem, pre_p);
7962 c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_DEPEND);
7963 OMP_CLAUSE_DEPEND_KIND (c) = OMP_CLAUSE_DEPEND_LAST;
7964 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (array);
7965 OMP_CLAUSE_CHAIN (c) = *list_p;
7966 *list_p = c;
7967 return 1;
7970 /* Scan the OMP clauses in *LIST_P, installing mappings into a new
7971 and previous omp contexts. */
7973 static void
7974 gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
7975 enum omp_region_type region_type,
7976 enum tree_code code)
7978 struct gimplify_omp_ctx *ctx, *outer_ctx;
7979 tree c;
7980 hash_map<tree, tree> *struct_map_to_clause = NULL;
7981 tree *prev_list_p = NULL;
7982 int handled_depend_iterators = -1;
7983 int nowait = -1;
7985 ctx = new_omp_context (region_type);
7986 outer_ctx = ctx->outer_context;
7987 if (code == OMP_TARGET)
7989 if (!lang_GNU_Fortran ())
7990 ctx->defaultmap[GDMK_POINTER] = GOVD_MAP | GOVD_MAP_0LEN_ARRAY;
7991 ctx->defaultmap[GDMK_SCALAR] = GOVD_FIRSTPRIVATE;
7993 if (!lang_GNU_Fortran ())
7994 switch (code)
7996 case OMP_TARGET:
7997 case OMP_TARGET_DATA:
7998 case OMP_TARGET_ENTER_DATA:
7999 case OMP_TARGET_EXIT_DATA:
8000 case OACC_DECLARE:
8001 case OACC_HOST_DATA:
8002 case OACC_PARALLEL:
8003 case OACC_KERNELS:
8004 ctx->target_firstprivatize_array_bases = true;
8005 default:
8006 break;
8009 while ((c = *list_p) != NULL)
8011 bool remove = false;
8012 bool notice_outer = true;
8013 const char *check_non_private = NULL;
8014 unsigned int flags;
8015 tree decl;
8017 switch (OMP_CLAUSE_CODE (c))
8019 case OMP_CLAUSE_PRIVATE:
8020 flags = GOVD_PRIVATE | GOVD_EXPLICIT;
8021 if (lang_hooks.decls.omp_private_outer_ref (OMP_CLAUSE_DECL (c)))
8023 flags |= GOVD_PRIVATE_OUTER_REF;
8024 OMP_CLAUSE_PRIVATE_OUTER_REF (c) = 1;
8026 else
8027 notice_outer = false;
8028 goto do_add;
8029 case OMP_CLAUSE_SHARED:
8030 flags = GOVD_SHARED | GOVD_EXPLICIT;
8031 goto do_add;
8032 case OMP_CLAUSE_FIRSTPRIVATE:
8033 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
8034 check_non_private = "firstprivate";
8035 goto do_add;
8036 case OMP_CLAUSE_LASTPRIVATE:
8037 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
8038 switch (code)
8040 case OMP_DISTRIBUTE:
8041 error_at (OMP_CLAUSE_LOCATION (c),
8042 "conditional %<lastprivate%> clause on "
8043 "%<distribute%> construct");
8044 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
8045 break;
8046 case OMP_TASKLOOP:
8047 error_at (OMP_CLAUSE_LOCATION (c),
8048 "conditional %<lastprivate%> clause on "
8049 "%<taskloop%> construct");
8050 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
8051 break;
8052 default:
8053 break;
8055 flags = GOVD_LASTPRIVATE | GOVD_SEEN | GOVD_EXPLICIT;
8056 check_non_private = "lastprivate";
8057 decl = OMP_CLAUSE_DECL (c);
8058 if (error_operand_p (decl))
8059 goto do_add;
8060 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)
8061 && !lang_hooks.decls.omp_scalar_p (decl))
8063 error_at (OMP_CLAUSE_LOCATION (c),
8064 "non-scalar variable %qD in conditional "
8065 "%<lastprivate%> clause", decl);
8066 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
8068 if (outer_ctx
8069 && (outer_ctx->region_type == ORT_COMBINED_PARALLEL
8070 || ((outer_ctx->region_type & ORT_COMBINED_TEAMS)
8071 == ORT_COMBINED_TEAMS))
8072 && splay_tree_lookup (outer_ctx->variables,
8073 (splay_tree_key) decl) == NULL)
8075 omp_add_variable (outer_ctx, decl, GOVD_SHARED | GOVD_SEEN);
8076 if (outer_ctx->outer_context)
8077 omp_notice_variable (outer_ctx->outer_context, decl, true);
8079 else if (outer_ctx
8080 && (outer_ctx->region_type & ORT_TASK) != 0
8081 && outer_ctx->combined_loop
8082 && splay_tree_lookup (outer_ctx->variables,
8083 (splay_tree_key) decl) == NULL)
8085 omp_add_variable (outer_ctx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
8086 if (outer_ctx->outer_context)
8087 omp_notice_variable (outer_ctx->outer_context, decl, true);
8089 else if (outer_ctx
8090 && (outer_ctx->region_type == ORT_WORKSHARE
8091 || outer_ctx->region_type == ORT_ACC)
8092 && outer_ctx->combined_loop
8093 && splay_tree_lookup (outer_ctx->variables,
8094 (splay_tree_key) decl) == NULL
8095 && !omp_check_private (outer_ctx, decl, false))
8097 omp_add_variable (outer_ctx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
8098 if (outer_ctx->outer_context
8099 && (outer_ctx->outer_context->region_type
8100 == ORT_COMBINED_PARALLEL)
8101 && splay_tree_lookup (outer_ctx->outer_context->variables,
8102 (splay_tree_key) decl) == NULL)
8104 struct gimplify_omp_ctx *octx = outer_ctx->outer_context;
8105 omp_add_variable (octx, decl, GOVD_SHARED | GOVD_SEEN);
8106 if (octx->outer_context)
8108 octx = octx->outer_context;
8109 if (octx->region_type == ORT_WORKSHARE
8110 && octx->combined_loop
8111 && splay_tree_lookup (octx->variables,
8112 (splay_tree_key) decl) == NULL
8113 && !omp_check_private (octx, decl, false))
8115 omp_add_variable (octx, decl,
8116 GOVD_LASTPRIVATE | GOVD_SEEN);
8117 octx = octx->outer_context;
8118 if (octx
8119 && ((octx->region_type & ORT_COMBINED_TEAMS)
8120 == ORT_COMBINED_TEAMS)
8121 && (splay_tree_lookup (octx->variables,
8122 (splay_tree_key) decl)
8123 == NULL))
8125 omp_add_variable (octx, decl,
8126 GOVD_SHARED | GOVD_SEEN);
8127 octx = octx->outer_context;
8130 if (octx)
8131 omp_notice_variable (octx, decl, true);
8134 else if (outer_ctx->outer_context)
8135 omp_notice_variable (outer_ctx->outer_context, decl, true);
8137 goto do_add;
8138 case OMP_CLAUSE_REDUCTION:
8139 if (OMP_CLAUSE_REDUCTION_TASK (c))
8141 if (region_type == ORT_WORKSHARE)
8143 if (nowait == -1)
8144 nowait = omp_find_clause (*list_p,
8145 OMP_CLAUSE_NOWAIT) != NULL_TREE;
8146 if (nowait
8147 && (outer_ctx == NULL
8148 || outer_ctx->region_type != ORT_COMBINED_PARALLEL))
8150 error_at (OMP_CLAUSE_LOCATION (c),
8151 "%<task%> reduction modifier on a construct "
8152 "with a %<nowait%> clause");
8153 OMP_CLAUSE_REDUCTION_TASK (c) = 0;
8156 else if ((region_type & ORT_PARALLEL) != ORT_PARALLEL)
8158 error_at (OMP_CLAUSE_LOCATION (c),
8159 "invalid %<task%> reduction modifier on construct "
8160 "other than %<parallel%>, %<for%> or %<sections%>");
8161 OMP_CLAUSE_REDUCTION_TASK (c) = 0;
8164 /* FALLTHRU */
8165 case OMP_CLAUSE_IN_REDUCTION:
8166 case OMP_CLAUSE_TASK_REDUCTION:
8167 flags = GOVD_REDUCTION | GOVD_SEEN | GOVD_EXPLICIT;
8168 /* OpenACC permits reductions on private variables. */
8169 if (!(region_type & ORT_ACC)
8170 /* taskgroup is actually not a worksharing region. */
8171 && code != OMP_TASKGROUP)
8172 check_non_private = omp_clause_code_name[OMP_CLAUSE_CODE (c)];
8173 decl = OMP_CLAUSE_DECL (c);
8174 if (TREE_CODE (decl) == MEM_REF)
8176 tree type = TREE_TYPE (decl);
8177 if (gimplify_expr (&TYPE_MAX_VALUE (TYPE_DOMAIN (type)), pre_p,
8178 NULL, is_gimple_val, fb_rvalue, false)
8179 == GS_ERROR)
8181 remove = true;
8182 break;
8184 tree v = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
8185 if (DECL_P (v))
8187 omp_firstprivatize_variable (ctx, v);
8188 omp_notice_variable (ctx, v, true);
8190 decl = TREE_OPERAND (decl, 0);
8191 if (TREE_CODE (decl) == POINTER_PLUS_EXPR)
8193 if (gimplify_expr (&TREE_OPERAND (decl, 1), pre_p,
8194 NULL, is_gimple_val, fb_rvalue, false)
8195 == GS_ERROR)
8197 remove = true;
8198 break;
8200 v = TREE_OPERAND (decl, 1);
8201 if (DECL_P (v))
8203 omp_firstprivatize_variable (ctx, v);
8204 omp_notice_variable (ctx, v, true);
8206 decl = TREE_OPERAND (decl, 0);
8208 if (TREE_CODE (decl) == ADDR_EXPR
8209 || TREE_CODE (decl) == INDIRECT_REF)
8210 decl = TREE_OPERAND (decl, 0);
8212 goto do_add_decl;
8213 case OMP_CLAUSE_LINEAR:
8214 if (gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c), pre_p, NULL,
8215 is_gimple_val, fb_rvalue) == GS_ERROR)
8217 remove = true;
8218 break;
8220 else
8222 if (code == OMP_SIMD
8223 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
8225 struct gimplify_omp_ctx *octx = outer_ctx;
8226 if (octx
8227 && octx->region_type == ORT_WORKSHARE
8228 && octx->combined_loop
8229 && !octx->distribute)
8231 if (octx->outer_context
8232 && (octx->outer_context->region_type
8233 == ORT_COMBINED_PARALLEL))
8234 octx = octx->outer_context->outer_context;
8235 else
8236 octx = octx->outer_context;
8238 if (octx
8239 && octx->region_type == ORT_WORKSHARE
8240 && octx->combined_loop
8241 && octx->distribute)
8243 error_at (OMP_CLAUSE_LOCATION (c),
8244 "%<linear%> clause for variable other than "
8245 "loop iterator specified on construct "
8246 "combined with %<distribute%>");
8247 remove = true;
8248 break;
8251 /* For combined #pragma omp parallel for simd, need to put
8252 lastprivate and perhaps firstprivate too on the
8253 parallel. Similarly for #pragma omp for simd. */
8254 struct gimplify_omp_ctx *octx = outer_ctx;
8255 decl = NULL_TREE;
8258 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
8259 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
8260 break;
8261 decl = OMP_CLAUSE_DECL (c);
8262 if (error_operand_p (decl))
8264 decl = NULL_TREE;
8265 break;
8267 flags = GOVD_SEEN;
8268 if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c))
8269 flags |= GOVD_FIRSTPRIVATE;
8270 if (!OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
8271 flags |= GOVD_LASTPRIVATE;
8272 if (octx
8273 && octx->region_type == ORT_WORKSHARE
8274 && octx->combined_loop)
8276 if (octx->outer_context
8277 && (octx->outer_context->region_type
8278 == ORT_COMBINED_PARALLEL))
8279 octx = octx->outer_context;
8280 else if (omp_check_private (octx, decl, false))
8281 break;
8283 else if (octx
8284 && (octx->region_type & ORT_TASK) != 0
8285 && octx->combined_loop)
8287 else if (octx
8288 && octx->region_type == ORT_COMBINED_PARALLEL
8289 && ctx->region_type == ORT_WORKSHARE
8290 && octx == outer_ctx)
8291 flags = GOVD_SEEN | GOVD_SHARED;
8292 else if (octx
8293 && ((octx->region_type & ORT_COMBINED_TEAMS)
8294 == ORT_COMBINED_TEAMS))
8295 flags = GOVD_SEEN | GOVD_SHARED;
8296 else if (octx
8297 && octx->region_type == ORT_COMBINED_TARGET)
8299 flags &= ~GOVD_LASTPRIVATE;
8300 if (flags == GOVD_SEEN)
8301 break;
8303 else
8304 break;
8305 splay_tree_node on
8306 = splay_tree_lookup (octx->variables,
8307 (splay_tree_key) decl);
8308 if (on && (on->value & GOVD_DATA_SHARE_CLASS) != 0)
8310 octx = NULL;
8311 break;
8313 omp_add_variable (octx, decl, flags);
8314 if (octx->outer_context == NULL)
8315 break;
8316 octx = octx->outer_context;
8318 while (1);
8319 if (octx
8320 && decl
8321 && (!OMP_CLAUSE_LINEAR_NO_COPYIN (c)
8322 || !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
8323 omp_notice_variable (octx, decl, true);
8325 flags = GOVD_LINEAR | GOVD_EXPLICIT;
8326 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
8327 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
8329 notice_outer = false;
8330 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
8332 goto do_add;
8334 case OMP_CLAUSE_MAP:
8335 decl = OMP_CLAUSE_DECL (c);
8336 if (error_operand_p (decl))
8337 remove = true;
8338 switch (code)
8340 case OMP_TARGET:
8341 break;
8342 case OACC_DATA:
8343 if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
8344 break;
8345 /* FALLTHRU */
8346 case OMP_TARGET_DATA:
8347 case OMP_TARGET_ENTER_DATA:
8348 case OMP_TARGET_EXIT_DATA:
8349 case OACC_ENTER_DATA:
8350 case OACC_EXIT_DATA:
8351 case OACC_HOST_DATA:
8352 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
8353 || (OMP_CLAUSE_MAP_KIND (c)
8354 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
8355 /* For target {,enter ,exit }data only the array slice is
8356 mapped, but not the pointer to it. */
8357 remove = true;
8358 break;
8359 default:
8360 break;
8362 if (remove)
8363 break;
8364 if (DECL_P (decl) && outer_ctx && (region_type & ORT_ACC))
8366 struct gimplify_omp_ctx *octx;
8367 for (octx = outer_ctx; octx; octx = octx->outer_context)
8369 if (octx->region_type != ORT_ACC_HOST_DATA)
8370 break;
8371 splay_tree_node n2
8372 = splay_tree_lookup (octx->variables,
8373 (splay_tree_key) decl);
8374 if (n2)
8375 error_at (OMP_CLAUSE_LOCATION (c), "variable %qE "
8376 "declared in enclosing %<host_data%> region",
8377 DECL_NAME (decl));
8380 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
8381 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
8382 : TYPE_SIZE_UNIT (TREE_TYPE (decl));
8383 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
8384 NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
8386 remove = true;
8387 break;
8389 else if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
8390 || (OMP_CLAUSE_MAP_KIND (c)
8391 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
8392 && TREE_CODE (OMP_CLAUSE_SIZE (c)) != INTEGER_CST)
8394 OMP_CLAUSE_SIZE (c)
8395 = get_initialized_tmp_var (OMP_CLAUSE_SIZE (c), pre_p, NULL,
8396 false);
8397 omp_add_variable (ctx, OMP_CLAUSE_SIZE (c),
8398 GOVD_FIRSTPRIVATE | GOVD_SEEN);
8400 if (!DECL_P (decl))
8402 tree d = decl, *pd;
8403 if (TREE_CODE (d) == ARRAY_REF)
8405 while (TREE_CODE (d) == ARRAY_REF)
8406 d = TREE_OPERAND (d, 0);
8407 if (TREE_CODE (d) == COMPONENT_REF
8408 && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE)
8409 decl = d;
8411 pd = &OMP_CLAUSE_DECL (c);
8412 if (d == decl
8413 && TREE_CODE (decl) == INDIRECT_REF
8414 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
8415 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
8416 == REFERENCE_TYPE))
8418 pd = &TREE_OPERAND (decl, 0);
8419 decl = TREE_OPERAND (decl, 0);
8421 if (TREE_CODE (decl) == COMPONENT_REF)
8423 while (TREE_CODE (decl) == COMPONENT_REF)
8424 decl = TREE_OPERAND (decl, 0);
8425 if (TREE_CODE (decl) == INDIRECT_REF
8426 && DECL_P (TREE_OPERAND (decl, 0))
8427 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
8428 == REFERENCE_TYPE))
8429 decl = TREE_OPERAND (decl, 0);
8431 if (gimplify_expr (pd, pre_p, NULL, is_gimple_lvalue, fb_lvalue)
8432 == GS_ERROR)
8434 remove = true;
8435 break;
8437 if (DECL_P (decl))
8439 if (error_operand_p (decl))
8441 remove = true;
8442 break;
8445 tree stype = TREE_TYPE (decl);
8446 if (TREE_CODE (stype) == REFERENCE_TYPE)
8447 stype = TREE_TYPE (stype);
8448 if (TYPE_SIZE_UNIT (stype) == NULL
8449 || TREE_CODE (TYPE_SIZE_UNIT (stype)) != INTEGER_CST)
8451 error_at (OMP_CLAUSE_LOCATION (c),
8452 "mapping field %qE of variable length "
8453 "structure", OMP_CLAUSE_DECL (c));
8454 remove = true;
8455 break;
8458 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER)
8460 /* Error recovery. */
8461 if (prev_list_p == NULL)
8463 remove = true;
8464 break;
8466 if (OMP_CLAUSE_CHAIN (*prev_list_p) != c)
8468 tree ch = OMP_CLAUSE_CHAIN (*prev_list_p);
8469 if (ch == NULL_TREE || OMP_CLAUSE_CHAIN (ch) != c)
8471 remove = true;
8472 break;
8477 tree offset;
8478 poly_int64 bitsize, bitpos;
8479 machine_mode mode;
8480 int unsignedp, reversep, volatilep = 0;
8481 tree base = OMP_CLAUSE_DECL (c);
8482 while (TREE_CODE (base) == ARRAY_REF)
8483 base = TREE_OPERAND (base, 0);
8484 if (TREE_CODE (base) == INDIRECT_REF)
8485 base = TREE_OPERAND (base, 0);
8486 base = get_inner_reference (base, &bitsize, &bitpos, &offset,
8487 &mode, &unsignedp, &reversep,
8488 &volatilep);
8489 tree orig_base = base;
8490 if ((TREE_CODE (base) == INDIRECT_REF
8491 || (TREE_CODE (base) == MEM_REF
8492 && integer_zerop (TREE_OPERAND (base, 1))))
8493 && DECL_P (TREE_OPERAND (base, 0))
8494 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0)))
8495 == REFERENCE_TYPE))
8496 base = TREE_OPERAND (base, 0);
8497 gcc_assert (base == decl
8498 && (offset == NULL_TREE
8499 || poly_int_tree_p (offset)));
8501 splay_tree_node n
8502 = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
8503 bool ptr = (OMP_CLAUSE_MAP_KIND (c)
8504 == GOMP_MAP_ALWAYS_POINTER);
8505 if (n == NULL || (n->value & GOVD_MAP) == 0)
8507 tree l = build_omp_clause (OMP_CLAUSE_LOCATION (c),
8508 OMP_CLAUSE_MAP);
8509 OMP_CLAUSE_SET_MAP_KIND (l, GOMP_MAP_STRUCT);
8510 if (orig_base != base)
8511 OMP_CLAUSE_DECL (l) = unshare_expr (orig_base);
8512 else
8513 OMP_CLAUSE_DECL (l) = decl;
8514 OMP_CLAUSE_SIZE (l) = size_int (1);
8515 if (struct_map_to_clause == NULL)
8516 struct_map_to_clause = new hash_map<tree, tree>;
8517 struct_map_to_clause->put (decl, l);
8518 if (ptr)
8520 enum gomp_map_kind mkind
8521 = code == OMP_TARGET_EXIT_DATA
8522 ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
8523 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
8524 OMP_CLAUSE_MAP);
8525 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
8526 OMP_CLAUSE_DECL (c2)
8527 = unshare_expr (OMP_CLAUSE_DECL (c));
8528 OMP_CLAUSE_CHAIN (c2) = *prev_list_p;
8529 OMP_CLAUSE_SIZE (c2)
8530 = TYPE_SIZE_UNIT (ptr_type_node);
8531 OMP_CLAUSE_CHAIN (l) = c2;
8532 if (OMP_CLAUSE_CHAIN (*prev_list_p) != c)
8534 tree c4 = OMP_CLAUSE_CHAIN (*prev_list_p);
8535 tree c3
8536 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
8537 OMP_CLAUSE_MAP);
8538 OMP_CLAUSE_SET_MAP_KIND (c3, mkind);
8539 OMP_CLAUSE_DECL (c3)
8540 = unshare_expr (OMP_CLAUSE_DECL (c4));
8541 OMP_CLAUSE_SIZE (c3)
8542 = TYPE_SIZE_UNIT (ptr_type_node);
8543 OMP_CLAUSE_CHAIN (c3) = *prev_list_p;
8544 OMP_CLAUSE_CHAIN (c2) = c3;
8546 *prev_list_p = l;
8547 prev_list_p = NULL;
8549 else
8551 OMP_CLAUSE_CHAIN (l) = c;
8552 *list_p = l;
8553 list_p = &OMP_CLAUSE_CHAIN (l);
8555 if (orig_base != base && code == OMP_TARGET)
8557 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
8558 OMP_CLAUSE_MAP);
8559 enum gomp_map_kind mkind
8560 = GOMP_MAP_FIRSTPRIVATE_REFERENCE;
8561 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
8562 OMP_CLAUSE_DECL (c2) = decl;
8563 OMP_CLAUSE_SIZE (c2) = size_zero_node;
8564 OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (l);
8565 OMP_CLAUSE_CHAIN (l) = c2;
8567 flags = GOVD_MAP | GOVD_EXPLICIT;
8568 if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) || ptr)
8569 flags |= GOVD_SEEN;
8570 goto do_add_decl;
8572 else
8574 tree *osc = struct_map_to_clause->get (decl);
8575 tree *sc = NULL, *scp = NULL;
8576 if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) || ptr)
8577 n->value |= GOVD_SEEN;
8578 poly_offset_int o1, o2;
8579 if (offset)
8580 o1 = wi::to_poly_offset (offset);
8581 else
8582 o1 = 0;
8583 if (maybe_ne (bitpos, 0))
8584 o1 += bits_to_bytes_round_down (bitpos);
8585 sc = &OMP_CLAUSE_CHAIN (*osc);
8586 if (*sc != c
8587 && (OMP_CLAUSE_MAP_KIND (*sc)
8588 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
8589 sc = &OMP_CLAUSE_CHAIN (*sc);
8590 for (; *sc != c; sc = &OMP_CLAUSE_CHAIN (*sc))
8591 if (ptr && sc == prev_list_p)
8592 break;
8593 else if (TREE_CODE (OMP_CLAUSE_DECL (*sc))
8594 != COMPONENT_REF
8595 && (TREE_CODE (OMP_CLAUSE_DECL (*sc))
8596 != INDIRECT_REF)
8597 && (TREE_CODE (OMP_CLAUSE_DECL (*sc))
8598 != ARRAY_REF))
8599 break;
8600 else
8602 tree offset2;
8603 poly_int64 bitsize2, bitpos2;
8604 base = OMP_CLAUSE_DECL (*sc);
8605 if (TREE_CODE (base) == ARRAY_REF)
8607 while (TREE_CODE (base) == ARRAY_REF)
8608 base = TREE_OPERAND (base, 0);
8609 if (TREE_CODE (base) != COMPONENT_REF
8610 || (TREE_CODE (TREE_TYPE (base))
8611 != ARRAY_TYPE))
8612 break;
8614 else if (TREE_CODE (base) == INDIRECT_REF
8615 && (TREE_CODE (TREE_OPERAND (base, 0))
8616 == COMPONENT_REF)
8617 && (TREE_CODE (TREE_TYPE
8618 (TREE_OPERAND (base, 0)))
8619 == REFERENCE_TYPE))
8620 base = TREE_OPERAND (base, 0);
8621 base = get_inner_reference (base, &bitsize2,
8622 &bitpos2, &offset2,
8623 &mode, &unsignedp,
8624 &reversep, &volatilep);
8625 if ((TREE_CODE (base) == INDIRECT_REF
8626 || (TREE_CODE (base) == MEM_REF
8627 && integer_zerop (TREE_OPERAND (base,
8628 1))))
8629 && DECL_P (TREE_OPERAND (base, 0))
8630 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (base,
8631 0)))
8632 == REFERENCE_TYPE))
8633 base = TREE_OPERAND (base, 0);
8634 if (base != decl)
8635 break;
8636 if (scp)
8637 continue;
8638 gcc_assert (offset == NULL_TREE
8639 || poly_int_tree_p (offset));
8640 tree d1 = OMP_CLAUSE_DECL (*sc);
8641 tree d2 = OMP_CLAUSE_DECL (c);
8642 while (TREE_CODE (d1) == ARRAY_REF)
8643 d1 = TREE_OPERAND (d1, 0);
8644 while (TREE_CODE (d2) == ARRAY_REF)
8645 d2 = TREE_OPERAND (d2, 0);
8646 if (TREE_CODE (d1) == INDIRECT_REF)
8647 d1 = TREE_OPERAND (d1, 0);
8648 if (TREE_CODE (d2) == INDIRECT_REF)
8649 d2 = TREE_OPERAND (d2, 0);
8650 while (TREE_CODE (d1) == COMPONENT_REF)
8651 if (TREE_CODE (d2) == COMPONENT_REF
8652 && TREE_OPERAND (d1, 1)
8653 == TREE_OPERAND (d2, 1))
8655 d1 = TREE_OPERAND (d1, 0);
8656 d2 = TREE_OPERAND (d2, 0);
8658 else
8659 break;
8660 if (d1 == d2)
8662 error_at (OMP_CLAUSE_LOCATION (c),
8663 "%qE appears more than once in map "
8664 "clauses", OMP_CLAUSE_DECL (c));
8665 remove = true;
8666 break;
8668 if (offset2)
8669 o2 = wi::to_poly_offset (offset2);
8670 else
8671 o2 = 0;
8672 o2 += bits_to_bytes_round_down (bitpos2);
8673 if (maybe_lt (o1, o2)
8674 || (known_eq (o1, 2)
8675 && maybe_lt (bitpos, bitpos2)))
8677 if (ptr)
8678 scp = sc;
8679 else
8680 break;
8683 if (remove)
8684 break;
8685 OMP_CLAUSE_SIZE (*osc)
8686 = size_binop (PLUS_EXPR, OMP_CLAUSE_SIZE (*osc),
8687 size_one_node);
8688 if (ptr)
8690 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
8691 OMP_CLAUSE_MAP);
8692 tree cl = NULL_TREE;
8693 enum gomp_map_kind mkind
8694 = code == OMP_TARGET_EXIT_DATA
8695 ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
8696 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
8697 OMP_CLAUSE_DECL (c2)
8698 = unshare_expr (OMP_CLAUSE_DECL (c));
8699 OMP_CLAUSE_CHAIN (c2) = scp ? *scp : *prev_list_p;
8700 OMP_CLAUSE_SIZE (c2)
8701 = TYPE_SIZE_UNIT (ptr_type_node);
8702 cl = scp ? *prev_list_p : c2;
8703 if (OMP_CLAUSE_CHAIN (*prev_list_p) != c)
8705 tree c4 = OMP_CLAUSE_CHAIN (*prev_list_p);
8706 tree c3
8707 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
8708 OMP_CLAUSE_MAP);
8709 OMP_CLAUSE_SET_MAP_KIND (c3, mkind);
8710 OMP_CLAUSE_DECL (c3)
8711 = unshare_expr (OMP_CLAUSE_DECL (c4));
8712 OMP_CLAUSE_SIZE (c3)
8713 = TYPE_SIZE_UNIT (ptr_type_node);
8714 OMP_CLAUSE_CHAIN (c3) = *prev_list_p;
8715 if (!scp)
8716 OMP_CLAUSE_CHAIN (c2) = c3;
8717 else
8718 cl = c3;
8720 if (scp)
8721 *scp = c2;
8722 if (sc == prev_list_p)
8724 *sc = cl;
8725 prev_list_p = NULL;
8727 else
8729 *prev_list_p = OMP_CLAUSE_CHAIN (c);
8730 list_p = prev_list_p;
8731 prev_list_p = NULL;
8732 OMP_CLAUSE_CHAIN (c) = *sc;
8733 *sc = cl;
8734 continue;
8737 else if (*sc != c)
8739 *list_p = OMP_CLAUSE_CHAIN (c);
8740 OMP_CLAUSE_CHAIN (c) = *sc;
8741 *sc = c;
8742 continue;
8746 if (!remove
8747 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_POINTER
8748 && OMP_CLAUSE_CHAIN (c)
8749 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (c)) == OMP_CLAUSE_MAP
8750 && (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
8751 == GOMP_MAP_ALWAYS_POINTER))
8752 prev_list_p = list_p;
8753 break;
8755 flags = GOVD_MAP | GOVD_EXPLICIT;
8756 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TO
8757 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TOFROM)
8758 flags |= GOVD_MAP_ALWAYS_TO;
8759 goto do_add;
8761 case OMP_CLAUSE_DEPEND:
8762 if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
8764 tree deps = OMP_CLAUSE_DECL (c);
8765 while (deps && TREE_CODE (deps) == TREE_LIST)
8767 if (TREE_CODE (TREE_PURPOSE (deps)) == TRUNC_DIV_EXPR
8768 && DECL_P (TREE_OPERAND (TREE_PURPOSE (deps), 1)))
8769 gimplify_expr (&TREE_OPERAND (TREE_PURPOSE (deps), 1),
8770 pre_p, NULL, is_gimple_val, fb_rvalue);
8771 deps = TREE_CHAIN (deps);
8773 break;
8775 else if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
8776 break;
8777 if (handled_depend_iterators == -1)
8778 handled_depend_iterators = gimplify_omp_depend (list_p, pre_p);
8779 if (handled_depend_iterators)
8781 if (handled_depend_iterators == 2)
8782 remove = true;
8783 break;
8785 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
8787 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
8788 NULL, is_gimple_val, fb_rvalue);
8789 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
8791 if (error_operand_p (OMP_CLAUSE_DECL (c)))
8793 remove = true;
8794 break;
8796 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
8797 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
8798 is_gimple_val, fb_rvalue) == GS_ERROR)
8800 remove = true;
8801 break;
8803 break;
8805 case OMP_CLAUSE_TO:
8806 case OMP_CLAUSE_FROM:
8807 case OMP_CLAUSE__CACHE_:
8808 decl = OMP_CLAUSE_DECL (c);
8809 if (error_operand_p (decl))
8811 remove = true;
8812 break;
8814 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
8815 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
8816 : TYPE_SIZE_UNIT (TREE_TYPE (decl));
8817 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
8818 NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
8820 remove = true;
8821 break;
8823 if (!DECL_P (decl))
8825 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p,
8826 NULL, is_gimple_lvalue, fb_lvalue)
8827 == GS_ERROR)
8829 remove = true;
8830 break;
8832 break;
8834 goto do_notice;
8836 case OMP_CLAUSE_USE_DEVICE_PTR:
8837 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
8838 goto do_add;
8839 case OMP_CLAUSE_IS_DEVICE_PTR:
8840 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
8841 goto do_add;
8843 do_add:
8844 decl = OMP_CLAUSE_DECL (c);
8845 do_add_decl:
8846 if (error_operand_p (decl))
8848 remove = true;
8849 break;
8851 if (DECL_NAME (decl) == NULL_TREE && (flags & GOVD_SHARED) == 0)
8853 tree t = omp_member_access_dummy_var (decl);
8854 if (t)
8856 tree v = DECL_VALUE_EXPR (decl);
8857 DECL_NAME (decl) = DECL_NAME (TREE_OPERAND (v, 1));
8858 if (outer_ctx)
8859 omp_notice_variable (outer_ctx, t, true);
8862 if (code == OACC_DATA
8863 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
8864 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
8865 flags |= GOVD_MAP_0LEN_ARRAY;
8866 omp_add_variable (ctx, decl, flags);
8867 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
8868 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
8869 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
8870 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
8872 omp_add_variable (ctx, OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
8873 GOVD_LOCAL | GOVD_SEEN);
8874 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
8875 && walk_tree (&OMP_CLAUSE_REDUCTION_INIT (c),
8876 find_decl_expr,
8877 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
8878 NULL) == NULL_TREE)
8879 omp_add_variable (ctx,
8880 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
8881 GOVD_LOCAL | GOVD_SEEN);
8882 gimplify_omp_ctxp = ctx;
8883 push_gimplify_context ();
8885 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
8886 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
8888 gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c),
8889 &OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c));
8890 pop_gimplify_context
8891 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c)));
8892 push_gimplify_context ();
8893 gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c),
8894 &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
8895 pop_gimplify_context
8896 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c)));
8897 OMP_CLAUSE_REDUCTION_INIT (c) = NULL_TREE;
8898 OMP_CLAUSE_REDUCTION_MERGE (c) = NULL_TREE;
8900 gimplify_omp_ctxp = outer_ctx;
8902 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
8903 && OMP_CLAUSE_LASTPRIVATE_STMT (c))
8905 gimplify_omp_ctxp = ctx;
8906 push_gimplify_context ();
8907 if (TREE_CODE (OMP_CLAUSE_LASTPRIVATE_STMT (c)) != BIND_EXPR)
8909 tree bind = build3 (BIND_EXPR, void_type_node, NULL,
8910 NULL, NULL);
8911 TREE_SIDE_EFFECTS (bind) = 1;
8912 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LASTPRIVATE_STMT (c);
8913 OMP_CLAUSE_LASTPRIVATE_STMT (c) = bind;
8915 gimplify_and_add (OMP_CLAUSE_LASTPRIVATE_STMT (c),
8916 &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
8917 pop_gimplify_context
8918 (gimple_seq_first_stmt (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c)));
8919 OMP_CLAUSE_LASTPRIVATE_STMT (c) = NULL_TREE;
8921 gimplify_omp_ctxp = outer_ctx;
8923 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
8924 && OMP_CLAUSE_LINEAR_STMT (c))
8926 gimplify_omp_ctxp = ctx;
8927 push_gimplify_context ();
8928 if (TREE_CODE (OMP_CLAUSE_LINEAR_STMT (c)) != BIND_EXPR)
8930 tree bind = build3 (BIND_EXPR, void_type_node, NULL,
8931 NULL, NULL);
8932 TREE_SIDE_EFFECTS (bind) = 1;
8933 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LINEAR_STMT (c);
8934 OMP_CLAUSE_LINEAR_STMT (c) = bind;
8936 gimplify_and_add (OMP_CLAUSE_LINEAR_STMT (c),
8937 &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c));
8938 pop_gimplify_context
8939 (gimple_seq_first_stmt (OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c)));
8940 OMP_CLAUSE_LINEAR_STMT (c) = NULL_TREE;
8942 gimplify_omp_ctxp = outer_ctx;
8944 if (notice_outer)
8945 goto do_notice;
8946 break;
8948 case OMP_CLAUSE_COPYIN:
8949 case OMP_CLAUSE_COPYPRIVATE:
8950 decl = OMP_CLAUSE_DECL (c);
8951 if (error_operand_p (decl))
8953 remove = true;
8954 break;
8956 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_COPYPRIVATE
8957 && !remove
8958 && !omp_check_private (ctx, decl, true))
8960 remove = true;
8961 if (is_global_var (decl))
8963 if (DECL_THREAD_LOCAL_P (decl))
8964 remove = false;
8965 else if (DECL_HAS_VALUE_EXPR_P (decl))
8967 tree value = get_base_address (DECL_VALUE_EXPR (decl));
8969 if (value
8970 && DECL_P (value)
8971 && DECL_THREAD_LOCAL_P (value))
8972 remove = false;
8975 if (remove)
8976 error_at (OMP_CLAUSE_LOCATION (c),
8977 "copyprivate variable %qE is not threadprivate"
8978 " or private in outer context", DECL_NAME (decl));
8980 do_notice:
8981 if ((region_type & ORT_TASKLOOP) == ORT_TASKLOOP
8982 && outer_ctx
8983 && outer_ctx->region_type == ORT_COMBINED_PARALLEL
8984 && (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
8985 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
8986 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE))
8988 splay_tree_node on
8989 = splay_tree_lookup (outer_ctx->variables,
8990 (splay_tree_key)decl);
8991 if (on == NULL || (on->value & GOVD_DATA_SHARE_CLASS) == 0)
8993 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
8994 && TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
8995 && (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
8996 || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
8997 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
8998 == POINTER_TYPE))))
8999 omp_firstprivatize_variable (outer_ctx, decl);
9000 else
9001 omp_add_variable (outer_ctx, decl,
9002 GOVD_SEEN | GOVD_SHARED);
9003 omp_notice_variable (outer_ctx, decl, true);
9006 if (outer_ctx)
9007 omp_notice_variable (outer_ctx, decl, true);
9008 if (check_non_private
9009 && region_type == ORT_WORKSHARE
9010 && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
9011 || decl == OMP_CLAUSE_DECL (c)
9012 || (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
9013 && (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
9014 == ADDR_EXPR
9015 || (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
9016 == POINTER_PLUS_EXPR
9017 && (TREE_CODE (TREE_OPERAND (TREE_OPERAND
9018 (OMP_CLAUSE_DECL (c), 0), 0))
9019 == ADDR_EXPR)))))
9020 && omp_check_private (ctx, decl, false))
9022 error ("%s variable %qE is private in outer context",
9023 check_non_private, DECL_NAME (decl));
9024 remove = true;
9026 break;
9028 case OMP_CLAUSE_IF:
9029 if (OMP_CLAUSE_IF_MODIFIER (c) != ERROR_MARK
9030 && OMP_CLAUSE_IF_MODIFIER (c) != code)
9032 const char *p[2];
9033 for (int i = 0; i < 2; i++)
9034 switch (i ? OMP_CLAUSE_IF_MODIFIER (c) : code)
9036 case VOID_CST: p[i] = "cancel"; break;
9037 case OMP_PARALLEL: p[i] = "parallel"; break;
9038 case OMP_SIMD: p[i] = "simd"; break;
9039 case OMP_TASK: p[i] = "task"; break;
9040 case OMP_TASKLOOP: p[i] = "taskloop"; break;
9041 case OMP_TARGET_DATA: p[i] = "target data"; break;
9042 case OMP_TARGET: p[i] = "target"; break;
9043 case OMP_TARGET_UPDATE: p[i] = "target update"; break;
9044 case OMP_TARGET_ENTER_DATA:
9045 p[i] = "target enter data"; break;
9046 case OMP_TARGET_EXIT_DATA: p[i] = "target exit data"; break;
9047 default: gcc_unreachable ();
9049 error_at (OMP_CLAUSE_LOCATION (c),
9050 "expected %qs %<if%> clause modifier rather than %qs",
9051 p[0], p[1]);
9052 remove = true;
9054 /* Fall through. */
9056 case OMP_CLAUSE_FINAL:
9057 OMP_CLAUSE_OPERAND (c, 0)
9058 = gimple_boolify (OMP_CLAUSE_OPERAND (c, 0));
9059 /* Fall through. */
9061 case OMP_CLAUSE_SCHEDULE:
9062 case OMP_CLAUSE_NUM_THREADS:
9063 case OMP_CLAUSE_NUM_TEAMS:
9064 case OMP_CLAUSE_THREAD_LIMIT:
9065 case OMP_CLAUSE_DIST_SCHEDULE:
9066 case OMP_CLAUSE_DEVICE:
9067 case OMP_CLAUSE_PRIORITY:
9068 case OMP_CLAUSE_GRAINSIZE:
9069 case OMP_CLAUSE_NUM_TASKS:
9070 case OMP_CLAUSE_HINT:
9071 case OMP_CLAUSE_ASYNC:
9072 case OMP_CLAUSE_WAIT:
9073 case OMP_CLAUSE_NUM_GANGS:
9074 case OMP_CLAUSE_NUM_WORKERS:
9075 case OMP_CLAUSE_VECTOR_LENGTH:
9076 case OMP_CLAUSE_WORKER:
9077 case OMP_CLAUSE_VECTOR:
9078 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
9079 is_gimple_val, fb_rvalue) == GS_ERROR)
9080 remove = true;
9081 break;
9083 case OMP_CLAUSE_GANG:
9084 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
9085 is_gimple_val, fb_rvalue) == GS_ERROR)
9086 remove = true;
9087 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 1), pre_p, NULL,
9088 is_gimple_val, fb_rvalue) == GS_ERROR)
9089 remove = true;
9090 break;
9092 case OMP_CLAUSE_NOWAIT:
9093 nowait = 1;
9094 break;
9096 case OMP_CLAUSE_ORDERED:
9097 case OMP_CLAUSE_UNTIED:
9098 case OMP_CLAUSE_COLLAPSE:
9099 case OMP_CLAUSE_TILE:
9100 case OMP_CLAUSE_AUTO:
9101 case OMP_CLAUSE_SEQ:
9102 case OMP_CLAUSE_INDEPENDENT:
9103 case OMP_CLAUSE_MERGEABLE:
9104 case OMP_CLAUSE_PROC_BIND:
9105 case OMP_CLAUSE_SAFELEN:
9106 case OMP_CLAUSE_SIMDLEN:
9107 case OMP_CLAUSE_NOGROUP:
9108 case OMP_CLAUSE_THREADS:
9109 case OMP_CLAUSE_SIMD:
9110 case OMP_CLAUSE_IF_PRESENT:
9111 case OMP_CLAUSE_FINALIZE:
9112 break;
9114 case OMP_CLAUSE_DEFAULTMAP:
9115 enum gimplify_defaultmap_kind gdmkmin, gdmkmax;
9116 switch (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c))
9118 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
9119 gdmkmin = GDMK_SCALAR;
9120 gdmkmax = GDMK_POINTER;
9121 break;
9122 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
9123 gdmkmin = gdmkmax = GDMK_SCALAR;
9124 break;
9125 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
9126 gdmkmin = gdmkmax = GDMK_AGGREGATE;
9127 break;
9128 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALLOCATABLE:
9129 gdmkmin = gdmkmax = GDMK_ALLOCATABLE;
9130 break;
9131 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
9132 gdmkmin = gdmkmax = GDMK_POINTER;
9133 break;
9134 default:
9135 gcc_unreachable ();
9137 for (int gdmk = gdmkmin; gdmk <= gdmkmax; gdmk++)
9138 switch (OMP_CLAUSE_DEFAULTMAP_BEHAVIOR (c))
9140 case OMP_CLAUSE_DEFAULTMAP_ALLOC:
9141 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_ALLOC_ONLY;
9142 break;
9143 case OMP_CLAUSE_DEFAULTMAP_TO:
9144 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_TO_ONLY;
9145 break;
9146 case OMP_CLAUSE_DEFAULTMAP_FROM:
9147 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_FROM_ONLY;
9148 break;
9149 case OMP_CLAUSE_DEFAULTMAP_TOFROM:
9150 ctx->defaultmap[gdmk] = GOVD_MAP;
9151 break;
9152 case OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE:
9153 ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE;
9154 break;
9155 case OMP_CLAUSE_DEFAULTMAP_NONE:
9156 ctx->defaultmap[gdmk] = 0;
9157 break;
9158 case OMP_CLAUSE_DEFAULTMAP_DEFAULT:
9159 switch (gdmk)
9161 case GDMK_SCALAR:
9162 ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE;
9163 break;
9164 case GDMK_AGGREGATE:
9165 case GDMK_ALLOCATABLE:
9166 ctx->defaultmap[gdmk] = GOVD_MAP;
9167 break;
9168 case GDMK_POINTER:
9169 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_0LEN_ARRAY;
9170 break;
9171 default:
9172 gcc_unreachable ();
9174 break;
9175 default:
9176 gcc_unreachable ();
9178 break;
9180 case OMP_CLAUSE_ALIGNED:
9181 decl = OMP_CLAUSE_DECL (c);
9182 if (error_operand_p (decl))
9184 remove = true;
9185 break;
9187 if (gimplify_expr (&OMP_CLAUSE_ALIGNED_ALIGNMENT (c), pre_p, NULL,
9188 is_gimple_val, fb_rvalue) == GS_ERROR)
9190 remove = true;
9191 break;
9193 if (!is_global_var (decl)
9194 && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
9195 omp_add_variable (ctx, decl, GOVD_ALIGNED);
9196 break;
9198 case OMP_CLAUSE_NONTEMPORAL:
9199 decl = OMP_CLAUSE_DECL (c);
9200 if (error_operand_p (decl))
9202 remove = true;
9203 break;
9205 omp_add_variable (ctx, decl, GOVD_NONTEMPORAL);
9206 break;
9208 case OMP_CLAUSE_DEFAULT:
9209 ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
9210 break;
9212 default:
9213 gcc_unreachable ();
9216 if (code == OACC_DATA
9217 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9218 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
9219 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
9220 remove = true;
9221 if (remove)
9222 *list_p = OMP_CLAUSE_CHAIN (c);
9223 else
9224 list_p = &OMP_CLAUSE_CHAIN (c);
9227 gimplify_omp_ctxp = ctx;
9228 if (struct_map_to_clause)
9229 delete struct_map_to_clause;
9232 /* Return true if DECL is a candidate for shared to firstprivate
9233 optimization. We only consider non-addressable scalars, not
9234 too big, and not references. */
9236 static bool
9237 omp_shared_to_firstprivate_optimizable_decl_p (tree decl)
9239 if (TREE_ADDRESSABLE (decl))
9240 return false;
9241 tree type = TREE_TYPE (decl);
9242 if (!is_gimple_reg_type (type)
9243 || TREE_CODE (type) == REFERENCE_TYPE
9244 || TREE_ADDRESSABLE (type))
9245 return false;
9246 /* Don't optimize too large decls, as each thread/task will have
9247 its own. */
9248 HOST_WIDE_INT len = int_size_in_bytes (type);
9249 if (len == -1 || len > 4 * POINTER_SIZE / BITS_PER_UNIT)
9250 return false;
9251 if (lang_hooks.decls.omp_privatize_by_reference (decl))
9252 return false;
9253 return true;
9256 /* Helper function of omp_find_stores_op and gimplify_adjust_omp_clauses*.
9257 For omp_shared_to_firstprivate_optimizable_decl_p decl mark it as
9258 GOVD_WRITTEN in outer contexts. */
9260 static void
9261 omp_mark_stores (struct gimplify_omp_ctx *ctx, tree decl)
9263 for (; ctx; ctx = ctx->outer_context)
9265 splay_tree_node n = splay_tree_lookup (ctx->variables,
9266 (splay_tree_key) decl);
9267 if (n == NULL)
9268 continue;
9269 else if (n->value & GOVD_SHARED)
9271 n->value |= GOVD_WRITTEN;
9272 return;
9274 else if (n->value & GOVD_DATA_SHARE_CLASS)
9275 return;
9279 /* Helper callback for walk_gimple_seq to discover possible stores
9280 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
9281 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
9282 for those. */
9284 static tree
9285 omp_find_stores_op (tree *tp, int *walk_subtrees, void *data)
9287 struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
9289 *walk_subtrees = 0;
9290 if (!wi->is_lhs)
9291 return NULL_TREE;
9293 tree op = *tp;
9296 if (handled_component_p (op))
9297 op = TREE_OPERAND (op, 0);
9298 else if ((TREE_CODE (op) == MEM_REF || TREE_CODE (op) == TARGET_MEM_REF)
9299 && TREE_CODE (TREE_OPERAND (op, 0)) == ADDR_EXPR)
9300 op = TREE_OPERAND (TREE_OPERAND (op, 0), 0);
9301 else
9302 break;
9304 while (1);
9305 if (!DECL_P (op) || !omp_shared_to_firstprivate_optimizable_decl_p (op))
9306 return NULL_TREE;
9308 omp_mark_stores (gimplify_omp_ctxp, op);
9309 return NULL_TREE;
9312 /* Helper callback for walk_gimple_seq to discover possible stores
9313 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
9314 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
9315 for those. */
9317 static tree
9318 omp_find_stores_stmt (gimple_stmt_iterator *gsi_p,
9319 bool *handled_ops_p,
9320 struct walk_stmt_info *wi)
9322 gimple *stmt = gsi_stmt (*gsi_p);
9323 switch (gimple_code (stmt))
9325 /* Don't recurse on OpenMP constructs for which
9326 gimplify_adjust_omp_clauses already handled the bodies,
9327 except handle gimple_omp_for_pre_body. */
9328 case GIMPLE_OMP_FOR:
9329 *handled_ops_p = true;
9330 if (gimple_omp_for_pre_body (stmt))
9331 walk_gimple_seq (gimple_omp_for_pre_body (stmt),
9332 omp_find_stores_stmt, omp_find_stores_op, wi);
9333 break;
9334 case GIMPLE_OMP_PARALLEL:
9335 case GIMPLE_OMP_TASK:
9336 case GIMPLE_OMP_SECTIONS:
9337 case GIMPLE_OMP_SINGLE:
9338 case GIMPLE_OMP_TARGET:
9339 case GIMPLE_OMP_TEAMS:
9340 case GIMPLE_OMP_CRITICAL:
9341 *handled_ops_p = true;
9342 break;
9343 default:
9344 break;
9346 return NULL_TREE;
9349 struct gimplify_adjust_omp_clauses_data
9351 tree *list_p;
9352 gimple_seq *pre_p;
9355 /* For all variables that were not actually used within the context,
9356 remove PRIVATE, SHARED, and FIRSTPRIVATE clauses. */
9358 static int
9359 gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
9361 tree *list_p = ((struct gimplify_adjust_omp_clauses_data *) data)->list_p;
9362 gimple_seq *pre_p
9363 = ((struct gimplify_adjust_omp_clauses_data *) data)->pre_p;
9364 tree decl = (tree) n->key;
9365 unsigned flags = n->value;
9366 enum omp_clause_code code;
9367 tree clause;
9368 bool private_debug;
9370 if (flags & (GOVD_EXPLICIT | GOVD_LOCAL))
9371 return 0;
9372 if ((flags & GOVD_SEEN) == 0)
9373 return 0;
9374 if (flags & GOVD_DEBUG_PRIVATE)
9376 gcc_assert ((flags & GOVD_DATA_SHARE_CLASS) == GOVD_SHARED);
9377 private_debug = true;
9379 else if (flags & GOVD_MAP)
9380 private_debug = false;
9381 else
9382 private_debug
9383 = lang_hooks.decls.omp_private_debug_clause (decl,
9384 !!(flags & GOVD_SHARED));
9385 if (private_debug)
9386 code = OMP_CLAUSE_PRIVATE;
9387 else if (flags & GOVD_MAP)
9389 code = OMP_CLAUSE_MAP;
9390 if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0
9391 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
9393 error ("%<_Atomic%> %qD in implicit %<map%> clause", decl);
9394 return 0;
9397 else if (flags & GOVD_SHARED)
9399 if (is_global_var (decl))
9401 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
9402 while (ctx != NULL)
9404 splay_tree_node on
9405 = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
9406 if (on && (on->value & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
9407 | GOVD_PRIVATE | GOVD_REDUCTION
9408 | GOVD_LINEAR | GOVD_MAP)) != 0)
9409 break;
9410 ctx = ctx->outer_context;
9412 if (ctx == NULL)
9413 return 0;
9415 code = OMP_CLAUSE_SHARED;
9417 else if (flags & GOVD_PRIVATE)
9418 code = OMP_CLAUSE_PRIVATE;
9419 else if (flags & GOVD_FIRSTPRIVATE)
9421 code = OMP_CLAUSE_FIRSTPRIVATE;
9422 if ((gimplify_omp_ctxp->region_type & ORT_TARGET)
9423 && (gimplify_omp_ctxp->region_type & ORT_ACC) == 0
9424 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
9426 error ("%<_Atomic%> %qD in implicit %<firstprivate%> clause on "
9427 "%<target%> construct", decl);
9428 return 0;
9431 else if (flags & GOVD_LASTPRIVATE)
9432 code = OMP_CLAUSE_LASTPRIVATE;
9433 else if (flags & (GOVD_ALIGNED | GOVD_NONTEMPORAL))
9434 return 0;
9435 else
9436 gcc_unreachable ();
9438 if (((flags & GOVD_LASTPRIVATE)
9439 || (code == OMP_CLAUSE_SHARED && (flags & GOVD_WRITTEN)))
9440 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
9441 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
9443 tree chain = *list_p;
9444 clause = build_omp_clause (input_location, code);
9445 OMP_CLAUSE_DECL (clause) = decl;
9446 OMP_CLAUSE_CHAIN (clause) = chain;
9447 if (private_debug)
9448 OMP_CLAUSE_PRIVATE_DEBUG (clause) = 1;
9449 else if (code == OMP_CLAUSE_PRIVATE && (flags & GOVD_PRIVATE_OUTER_REF))
9450 OMP_CLAUSE_PRIVATE_OUTER_REF (clause) = 1;
9451 else if (code == OMP_CLAUSE_SHARED
9452 && (flags & GOVD_WRITTEN) == 0
9453 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
9454 OMP_CLAUSE_SHARED_READONLY (clause) = 1;
9455 else if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_EXPLICIT) == 0)
9456 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (clause) = 1;
9457 else if (code == OMP_CLAUSE_MAP && (flags & GOVD_MAP_0LEN_ARRAY) != 0)
9459 tree nc = build_omp_clause (input_location, OMP_CLAUSE_MAP);
9460 OMP_CLAUSE_DECL (nc) = decl;
9461 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
9462 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == POINTER_TYPE)
9463 OMP_CLAUSE_DECL (clause)
9464 = build_simple_mem_ref_loc (input_location, decl);
9465 OMP_CLAUSE_DECL (clause)
9466 = build2 (MEM_REF, char_type_node, OMP_CLAUSE_DECL (clause),
9467 build_int_cst (build_pointer_type (char_type_node), 0));
9468 OMP_CLAUSE_SIZE (clause) = size_zero_node;
9469 OMP_CLAUSE_SIZE (nc) = size_zero_node;
9470 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_ALLOC);
9471 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (clause) = 1;
9472 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
9473 OMP_CLAUSE_CHAIN (nc) = chain;
9474 OMP_CLAUSE_CHAIN (clause) = nc;
9475 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
9476 gimplify_omp_ctxp = ctx->outer_context;
9477 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (clause), 0),
9478 pre_p, NULL, is_gimple_val, fb_rvalue);
9479 gimplify_omp_ctxp = ctx;
9481 else if (code == OMP_CLAUSE_MAP)
9483 int kind;
9484 /* Not all combinations of these GOVD_MAP flags are actually valid. */
9485 switch (flags & (GOVD_MAP_TO_ONLY
9486 | GOVD_MAP_FORCE
9487 | GOVD_MAP_FORCE_PRESENT
9488 | GOVD_MAP_ALLOC_ONLY
9489 | GOVD_MAP_FROM_ONLY))
9491 case 0:
9492 kind = GOMP_MAP_TOFROM;
9493 break;
9494 case GOVD_MAP_FORCE:
9495 kind = GOMP_MAP_TOFROM | GOMP_MAP_FLAG_FORCE;
9496 break;
9497 case GOVD_MAP_TO_ONLY:
9498 kind = GOMP_MAP_TO;
9499 break;
9500 case GOVD_MAP_FROM_ONLY:
9501 kind = GOMP_MAP_FROM;
9502 break;
9503 case GOVD_MAP_ALLOC_ONLY:
9504 kind = GOMP_MAP_ALLOC;
9505 break;
9506 case GOVD_MAP_TO_ONLY | GOVD_MAP_FORCE:
9507 kind = GOMP_MAP_TO | GOMP_MAP_FLAG_FORCE;
9508 break;
9509 case GOVD_MAP_FORCE_PRESENT:
9510 kind = GOMP_MAP_FORCE_PRESENT;
9511 break;
9512 default:
9513 gcc_unreachable ();
9515 OMP_CLAUSE_SET_MAP_KIND (clause, kind);
9516 if (DECL_SIZE (decl)
9517 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
9519 tree decl2 = DECL_VALUE_EXPR (decl);
9520 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
9521 decl2 = TREE_OPERAND (decl2, 0);
9522 gcc_assert (DECL_P (decl2));
9523 tree mem = build_simple_mem_ref (decl2);
9524 OMP_CLAUSE_DECL (clause) = mem;
9525 OMP_CLAUSE_SIZE (clause) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
9526 if (gimplify_omp_ctxp->outer_context)
9528 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
9529 omp_notice_variable (ctx, decl2, true);
9530 omp_notice_variable (ctx, OMP_CLAUSE_SIZE (clause), true);
9532 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
9533 OMP_CLAUSE_MAP);
9534 OMP_CLAUSE_DECL (nc) = decl;
9535 OMP_CLAUSE_SIZE (nc) = size_zero_node;
9536 if (gimplify_omp_ctxp->target_firstprivatize_array_bases)
9537 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
9538 else
9539 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
9540 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
9541 OMP_CLAUSE_CHAIN (clause) = nc;
9543 else if (gimplify_omp_ctxp->target_firstprivatize_array_bases
9544 && lang_hooks.decls.omp_privatize_by_reference (decl))
9546 OMP_CLAUSE_DECL (clause) = build_simple_mem_ref (decl);
9547 OMP_CLAUSE_SIZE (clause)
9548 = unshare_expr (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))));
9549 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
9550 gimplify_omp_ctxp = ctx->outer_context;
9551 gimplify_expr (&OMP_CLAUSE_SIZE (clause),
9552 pre_p, NULL, is_gimple_val, fb_rvalue);
9553 gimplify_omp_ctxp = ctx;
9554 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
9555 OMP_CLAUSE_MAP);
9556 OMP_CLAUSE_DECL (nc) = decl;
9557 OMP_CLAUSE_SIZE (nc) = size_zero_node;
9558 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_REFERENCE);
9559 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
9560 OMP_CLAUSE_CHAIN (clause) = nc;
9562 else
9563 OMP_CLAUSE_SIZE (clause) = DECL_SIZE_UNIT (decl);
9565 if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_LASTPRIVATE) != 0)
9567 tree nc = build_omp_clause (input_location, OMP_CLAUSE_LASTPRIVATE);
9568 OMP_CLAUSE_DECL (nc) = decl;
9569 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (nc) = 1;
9570 OMP_CLAUSE_CHAIN (nc) = chain;
9571 OMP_CLAUSE_CHAIN (clause) = nc;
9572 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
9573 gimplify_omp_ctxp = ctx->outer_context;
9574 lang_hooks.decls.omp_finish_clause (nc, pre_p);
9575 gimplify_omp_ctxp = ctx;
9577 *list_p = clause;
9578 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
9579 gimplify_omp_ctxp = ctx->outer_context;
9580 lang_hooks.decls.omp_finish_clause (clause, pre_p);
9581 if (gimplify_omp_ctxp)
9582 for (; clause != chain; clause = OMP_CLAUSE_CHAIN (clause))
9583 if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_MAP
9584 && DECL_P (OMP_CLAUSE_SIZE (clause)))
9585 omp_notice_variable (gimplify_omp_ctxp, OMP_CLAUSE_SIZE (clause),
9586 true);
9587 gimplify_omp_ctxp = ctx;
9588 return 0;
9591 static void
9592 gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
9593 enum tree_code code)
9595 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
9596 tree c, decl;
9598 if (body)
9600 struct gimplify_omp_ctx *octx;
9601 for (octx = ctx; octx; octx = octx->outer_context)
9602 if ((octx->region_type & (ORT_PARALLEL | ORT_TASK | ORT_TEAMS)) != 0)
9603 break;
9604 if (octx)
9606 struct walk_stmt_info wi;
9607 memset (&wi, 0, sizeof (wi));
9608 walk_gimple_seq (body, omp_find_stores_stmt,
9609 omp_find_stores_op, &wi);
9612 while ((c = *list_p) != NULL)
9614 splay_tree_node n;
9615 bool remove = false;
9617 switch (OMP_CLAUSE_CODE (c))
9619 case OMP_CLAUSE_FIRSTPRIVATE:
9620 if ((ctx->region_type & ORT_TARGET)
9621 && (ctx->region_type & ORT_ACC) == 0
9622 && TYPE_ATOMIC (strip_array_types
9623 (TREE_TYPE (OMP_CLAUSE_DECL (c)))))
9625 error_at (OMP_CLAUSE_LOCATION (c),
9626 "%<_Atomic%> %qD in %<firstprivate%> clause on "
9627 "%<target%> construct", OMP_CLAUSE_DECL (c));
9628 remove = true;
9629 break;
9631 /* FALLTHRU */
9632 case OMP_CLAUSE_PRIVATE:
9633 case OMP_CLAUSE_SHARED:
9634 case OMP_CLAUSE_LINEAR:
9635 decl = OMP_CLAUSE_DECL (c);
9636 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
9637 remove = !(n->value & GOVD_SEEN);
9638 if (! remove)
9640 bool shared = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED;
9641 if ((n->value & GOVD_DEBUG_PRIVATE)
9642 || lang_hooks.decls.omp_private_debug_clause (decl, shared))
9644 gcc_assert ((n->value & GOVD_DEBUG_PRIVATE) == 0
9645 || ((n->value & GOVD_DATA_SHARE_CLASS)
9646 == GOVD_SHARED));
9647 OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_PRIVATE);
9648 OMP_CLAUSE_PRIVATE_DEBUG (c) = 1;
9650 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
9651 && (n->value & GOVD_WRITTEN) == 0
9652 && DECL_P (decl)
9653 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
9654 OMP_CLAUSE_SHARED_READONLY (c) = 1;
9655 else if (DECL_P (decl)
9656 && ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
9657 && (n->value & GOVD_WRITTEN) != 0)
9658 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
9659 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
9660 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
9661 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
9663 break;
9665 case OMP_CLAUSE_LASTPRIVATE:
9666 /* Make sure OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE is set to
9667 accurately reflect the presence of a FIRSTPRIVATE clause. */
9668 decl = OMP_CLAUSE_DECL (c);
9669 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
9670 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c)
9671 = (n->value & GOVD_FIRSTPRIVATE) != 0;
9672 if (code == OMP_DISTRIBUTE
9673 && OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
9675 remove = true;
9676 error_at (OMP_CLAUSE_LOCATION (c),
9677 "same variable used in %<firstprivate%> and "
9678 "%<lastprivate%> clauses on %<distribute%> "
9679 "construct");
9681 if (!remove
9682 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
9683 && DECL_P (decl)
9684 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
9685 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
9686 break;
9688 case OMP_CLAUSE_ALIGNED:
9689 decl = OMP_CLAUSE_DECL (c);
9690 if (!is_global_var (decl))
9692 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
9693 remove = n == NULL || !(n->value & GOVD_SEEN);
9694 if (!remove && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
9696 struct gimplify_omp_ctx *octx;
9697 if (n != NULL
9698 && (n->value & (GOVD_DATA_SHARE_CLASS
9699 & ~GOVD_FIRSTPRIVATE)))
9700 remove = true;
9701 else
9702 for (octx = ctx->outer_context; octx;
9703 octx = octx->outer_context)
9705 n = splay_tree_lookup (octx->variables,
9706 (splay_tree_key) decl);
9707 if (n == NULL)
9708 continue;
9709 if (n->value & GOVD_LOCAL)
9710 break;
9711 /* We have to avoid assigning a shared variable
9712 to itself when trying to add
9713 __builtin_assume_aligned. */
9714 if (n->value & GOVD_SHARED)
9716 remove = true;
9717 break;
9722 else if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
9724 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
9725 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
9726 remove = true;
9728 break;
9730 case OMP_CLAUSE_NONTEMPORAL:
9731 decl = OMP_CLAUSE_DECL (c);
9732 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
9733 remove = n == NULL || !(n->value & GOVD_SEEN);
9734 break;
9736 case OMP_CLAUSE_MAP:
9737 if (code == OMP_TARGET_EXIT_DATA
9738 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER)
9740 remove = true;
9741 break;
9743 decl = OMP_CLAUSE_DECL (c);
9744 /* Data clauses associated with acc parallel reductions must be
9745 compatible with present_or_copy. Warn and adjust the clause
9746 if that is not the case. */
9747 if (ctx->region_type == ORT_ACC_PARALLEL)
9749 tree t = DECL_P (decl) ? decl : TREE_OPERAND (decl, 0);
9750 n = NULL;
9752 if (DECL_P (t))
9753 n = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
9755 if (n && (n->value & GOVD_REDUCTION))
9757 enum gomp_map_kind kind = OMP_CLAUSE_MAP_KIND (c);
9759 OMP_CLAUSE_MAP_IN_REDUCTION (c) = 1;
9760 if ((kind & GOMP_MAP_TOFROM) != GOMP_MAP_TOFROM
9761 && kind != GOMP_MAP_FORCE_PRESENT
9762 && kind != GOMP_MAP_POINTER)
9764 warning_at (OMP_CLAUSE_LOCATION (c), 0,
9765 "incompatible data clause with reduction "
9766 "on %qE; promoting to present_or_copy",
9767 DECL_NAME (t));
9768 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TOFROM);
9772 if (!DECL_P (decl))
9774 if ((ctx->region_type & ORT_TARGET) != 0
9775 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
9777 if (TREE_CODE (decl) == INDIRECT_REF
9778 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
9779 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
9780 == REFERENCE_TYPE))
9781 decl = TREE_OPERAND (decl, 0);
9782 if (TREE_CODE (decl) == COMPONENT_REF)
9784 while (TREE_CODE (decl) == COMPONENT_REF)
9785 decl = TREE_OPERAND (decl, 0);
9786 if (DECL_P (decl))
9788 n = splay_tree_lookup (ctx->variables,
9789 (splay_tree_key) decl);
9790 if (!(n->value & GOVD_SEEN))
9791 remove = true;
9795 break;
9797 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
9798 if ((ctx->region_type & ORT_TARGET) != 0
9799 && !(n->value & GOVD_SEEN)
9800 && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) == 0
9801 && (!is_global_var (decl)
9802 || !lookup_attribute ("omp declare target link",
9803 DECL_ATTRIBUTES (decl))))
9805 remove = true;
9806 /* For struct element mapping, if struct is never referenced
9807 in target block and none of the mapping has always modifier,
9808 remove all the struct element mappings, which immediately
9809 follow the GOMP_MAP_STRUCT map clause. */
9810 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT)
9812 HOST_WIDE_INT cnt = tree_to_shwi (OMP_CLAUSE_SIZE (c));
9813 while (cnt--)
9814 OMP_CLAUSE_CHAIN (c)
9815 = OMP_CLAUSE_CHAIN (OMP_CLAUSE_CHAIN (c));
9818 else if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT
9819 && code == OMP_TARGET_EXIT_DATA)
9820 remove = true;
9821 else if (DECL_SIZE (decl)
9822 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST
9823 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_POINTER
9824 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_POINTER
9825 && (OMP_CLAUSE_MAP_KIND (c)
9826 != GOMP_MAP_FIRSTPRIVATE_REFERENCE))
9828 /* For GOMP_MAP_FORCE_DEVICEPTR, we'll never enter here, because
9829 for these, TREE_CODE (DECL_SIZE (decl)) will always be
9830 INTEGER_CST. */
9831 gcc_assert (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FORCE_DEVICEPTR);
9833 tree decl2 = DECL_VALUE_EXPR (decl);
9834 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
9835 decl2 = TREE_OPERAND (decl2, 0);
9836 gcc_assert (DECL_P (decl2));
9837 tree mem = build_simple_mem_ref (decl2);
9838 OMP_CLAUSE_DECL (c) = mem;
9839 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
9840 if (ctx->outer_context)
9842 omp_notice_variable (ctx->outer_context, decl2, true);
9843 omp_notice_variable (ctx->outer_context,
9844 OMP_CLAUSE_SIZE (c), true);
9846 if (((ctx->region_type & ORT_TARGET) != 0
9847 || !ctx->target_firstprivatize_array_bases)
9848 && ((n->value & GOVD_SEEN) == 0
9849 || (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) == 0))
9851 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9852 OMP_CLAUSE_MAP);
9853 OMP_CLAUSE_DECL (nc) = decl;
9854 OMP_CLAUSE_SIZE (nc) = size_zero_node;
9855 if (ctx->target_firstprivatize_array_bases)
9856 OMP_CLAUSE_SET_MAP_KIND (nc,
9857 GOMP_MAP_FIRSTPRIVATE_POINTER);
9858 else
9859 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
9860 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
9861 OMP_CLAUSE_CHAIN (c) = nc;
9862 c = nc;
9865 else
9867 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
9868 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
9869 gcc_assert ((n->value & GOVD_SEEN) == 0
9870 || ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
9871 == 0));
9873 break;
9875 case OMP_CLAUSE_TO:
9876 case OMP_CLAUSE_FROM:
9877 case OMP_CLAUSE__CACHE_:
9878 decl = OMP_CLAUSE_DECL (c);
9879 if (!DECL_P (decl))
9880 break;
9881 if (DECL_SIZE (decl)
9882 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
9884 tree decl2 = DECL_VALUE_EXPR (decl);
9885 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
9886 decl2 = TREE_OPERAND (decl2, 0);
9887 gcc_assert (DECL_P (decl2));
9888 tree mem = build_simple_mem_ref (decl2);
9889 OMP_CLAUSE_DECL (c) = mem;
9890 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
9891 if (ctx->outer_context)
9893 omp_notice_variable (ctx->outer_context, decl2, true);
9894 omp_notice_variable (ctx->outer_context,
9895 OMP_CLAUSE_SIZE (c), true);
9898 else if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
9899 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
9900 break;
9902 case OMP_CLAUSE_REDUCTION:
9903 case OMP_CLAUSE_IN_REDUCTION:
9904 case OMP_CLAUSE_TASK_REDUCTION:
9905 decl = OMP_CLAUSE_DECL (c);
9906 /* OpenACC reductions need a present_or_copy data clause.
9907 Add one if necessary. Emit error when the reduction is private. */
9908 if (ctx->region_type == ORT_ACC_PARALLEL)
9910 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
9911 if (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
9913 remove = true;
9914 error_at (OMP_CLAUSE_LOCATION (c), "invalid private "
9915 "reduction on %qE", DECL_NAME (decl));
9917 else if ((n->value & GOVD_MAP) == 0)
9919 tree next = OMP_CLAUSE_CHAIN (c);
9920 tree nc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_MAP);
9921 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_TOFROM);
9922 OMP_CLAUSE_DECL (nc) = decl;
9923 OMP_CLAUSE_CHAIN (c) = nc;
9924 lang_hooks.decls.omp_finish_clause (nc, pre_p);
9925 while (1)
9927 OMP_CLAUSE_MAP_IN_REDUCTION (nc) = 1;
9928 if (OMP_CLAUSE_CHAIN (nc) == NULL)
9929 break;
9930 nc = OMP_CLAUSE_CHAIN (nc);
9932 OMP_CLAUSE_CHAIN (nc) = next;
9933 n->value |= GOVD_MAP;
9936 if (DECL_P (decl)
9937 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
9938 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
9939 break;
9940 case OMP_CLAUSE_COPYIN:
9941 case OMP_CLAUSE_COPYPRIVATE:
9942 case OMP_CLAUSE_IF:
9943 case OMP_CLAUSE_NUM_THREADS:
9944 case OMP_CLAUSE_NUM_TEAMS:
9945 case OMP_CLAUSE_THREAD_LIMIT:
9946 case OMP_CLAUSE_DIST_SCHEDULE:
9947 case OMP_CLAUSE_DEVICE:
9948 case OMP_CLAUSE_SCHEDULE:
9949 case OMP_CLAUSE_NOWAIT:
9950 case OMP_CLAUSE_ORDERED:
9951 case OMP_CLAUSE_DEFAULT:
9952 case OMP_CLAUSE_UNTIED:
9953 case OMP_CLAUSE_COLLAPSE:
9954 case OMP_CLAUSE_FINAL:
9955 case OMP_CLAUSE_MERGEABLE:
9956 case OMP_CLAUSE_PROC_BIND:
9957 case OMP_CLAUSE_SAFELEN:
9958 case OMP_CLAUSE_SIMDLEN:
9959 case OMP_CLAUSE_DEPEND:
9960 case OMP_CLAUSE_PRIORITY:
9961 case OMP_CLAUSE_GRAINSIZE:
9962 case OMP_CLAUSE_NUM_TASKS:
9963 case OMP_CLAUSE_NOGROUP:
9964 case OMP_CLAUSE_THREADS:
9965 case OMP_CLAUSE_SIMD:
9966 case OMP_CLAUSE_HINT:
9967 case OMP_CLAUSE_DEFAULTMAP:
9968 case OMP_CLAUSE_USE_DEVICE_PTR:
9969 case OMP_CLAUSE_IS_DEVICE_PTR:
9970 case OMP_CLAUSE_ASYNC:
9971 case OMP_CLAUSE_WAIT:
9972 case OMP_CLAUSE_INDEPENDENT:
9973 case OMP_CLAUSE_NUM_GANGS:
9974 case OMP_CLAUSE_NUM_WORKERS:
9975 case OMP_CLAUSE_VECTOR_LENGTH:
9976 case OMP_CLAUSE_GANG:
9977 case OMP_CLAUSE_WORKER:
9978 case OMP_CLAUSE_VECTOR:
9979 case OMP_CLAUSE_AUTO:
9980 case OMP_CLAUSE_SEQ:
9981 case OMP_CLAUSE_TILE:
9982 case OMP_CLAUSE_IF_PRESENT:
9983 case OMP_CLAUSE_FINALIZE:
9984 break;
9986 default:
9987 gcc_unreachable ();
9990 if (remove)
9991 *list_p = OMP_CLAUSE_CHAIN (c);
9992 else
9993 list_p = &OMP_CLAUSE_CHAIN (c);
9996 /* Add in any implicit data sharing. */
9997 struct gimplify_adjust_omp_clauses_data data;
9998 data.list_p = list_p;
9999 data.pre_p = pre_p;
10000 splay_tree_foreach (ctx->variables, gimplify_adjust_omp_clauses_1, &data);
10002 gimplify_omp_ctxp = ctx->outer_context;
10003 delete_omp_context (ctx);
10006 /* Gimplify OACC_CACHE. */
10008 static void
10009 gimplify_oacc_cache (tree *expr_p, gimple_seq *pre_p)
10011 tree expr = *expr_p;
10013 gimplify_scan_omp_clauses (&OACC_CACHE_CLAUSES (expr), pre_p, ORT_ACC,
10014 OACC_CACHE);
10015 gimplify_adjust_omp_clauses (pre_p, NULL, &OACC_CACHE_CLAUSES (expr),
10016 OACC_CACHE);
10018 /* TODO: Do something sensible with this information. */
10020 *expr_p = NULL_TREE;
10023 /* Helper function of gimplify_oacc_declare. The helper's purpose is to,
10024 if required, translate 'kind' in CLAUSE into an 'entry' kind and 'exit'
10025 kind. The entry kind will replace the one in CLAUSE, while the exit
10026 kind will be used in a new omp_clause and returned to the caller. */
10028 static tree
10029 gimplify_oacc_declare_1 (tree clause)
10031 HOST_WIDE_INT kind, new_op;
10032 bool ret = false;
10033 tree c = NULL;
10035 kind = OMP_CLAUSE_MAP_KIND (clause);
10037 switch (kind)
10039 case GOMP_MAP_ALLOC:
10040 new_op = GOMP_MAP_RELEASE;
10041 ret = true;
10042 break;
10044 case GOMP_MAP_FROM:
10045 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_FORCE_ALLOC);
10046 new_op = GOMP_MAP_FROM;
10047 ret = true;
10048 break;
10050 case GOMP_MAP_TOFROM:
10051 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_TO);
10052 new_op = GOMP_MAP_FROM;
10053 ret = true;
10054 break;
10056 case GOMP_MAP_DEVICE_RESIDENT:
10057 case GOMP_MAP_FORCE_DEVICEPTR:
10058 case GOMP_MAP_FORCE_PRESENT:
10059 case GOMP_MAP_LINK:
10060 case GOMP_MAP_POINTER:
10061 case GOMP_MAP_TO:
10062 break;
10064 default:
10065 gcc_unreachable ();
10066 break;
10069 if (ret)
10071 c = build_omp_clause (OMP_CLAUSE_LOCATION (clause), OMP_CLAUSE_MAP);
10072 OMP_CLAUSE_SET_MAP_KIND (c, new_op);
10073 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clause);
10076 return c;
10079 /* Gimplify OACC_DECLARE. */
10081 static void
10082 gimplify_oacc_declare (tree *expr_p, gimple_seq *pre_p)
10084 tree expr = *expr_p;
10085 gomp_target *stmt;
10086 tree clauses, t, decl;
10088 clauses = OACC_DECLARE_CLAUSES (expr);
10090 gimplify_scan_omp_clauses (&clauses, pre_p, ORT_TARGET_DATA, OACC_DECLARE);
10091 gimplify_adjust_omp_clauses (pre_p, NULL, &clauses, OACC_DECLARE);
10093 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
10095 decl = OMP_CLAUSE_DECL (t);
10097 if (TREE_CODE (decl) == MEM_REF)
10098 decl = TREE_OPERAND (decl, 0);
10100 if (VAR_P (decl) && !is_oacc_declared (decl))
10102 tree attr = get_identifier ("oacc declare target");
10103 DECL_ATTRIBUTES (decl) = tree_cons (attr, NULL_TREE,
10104 DECL_ATTRIBUTES (decl));
10107 if (VAR_P (decl)
10108 && !is_global_var (decl)
10109 && DECL_CONTEXT (decl) == current_function_decl)
10111 tree c = gimplify_oacc_declare_1 (t);
10112 if (c)
10114 if (oacc_declare_returns == NULL)
10115 oacc_declare_returns = new hash_map<tree, tree>;
10117 oacc_declare_returns->put (decl, c);
10121 if (gimplify_omp_ctxp)
10122 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_SEEN);
10125 stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
10126 clauses);
10128 gimplify_seq_add_stmt (pre_p, stmt);
10130 *expr_p = NULL_TREE;
10133 /* Gimplify the contents of an OMP_PARALLEL statement. This involves
10134 gimplification of the body, as well as scanning the body for used
10135 variables. We need to do this scan now, because variable-sized
10136 decls will be decomposed during gimplification. */
10138 static void
10139 gimplify_omp_parallel (tree *expr_p, gimple_seq *pre_p)
10141 tree expr = *expr_p;
10142 gimple *g;
10143 gimple_seq body = NULL;
10145 gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr), pre_p,
10146 OMP_PARALLEL_COMBINED (expr)
10147 ? ORT_COMBINED_PARALLEL
10148 : ORT_PARALLEL, OMP_PARALLEL);
10150 push_gimplify_context ();
10152 g = gimplify_and_return_first (OMP_PARALLEL_BODY (expr), &body);
10153 if (gimple_code (g) == GIMPLE_BIND)
10154 pop_gimplify_context (g);
10155 else
10156 pop_gimplify_context (NULL);
10158 gimplify_adjust_omp_clauses (pre_p, body, &OMP_PARALLEL_CLAUSES (expr),
10159 OMP_PARALLEL);
10161 g = gimple_build_omp_parallel (body,
10162 OMP_PARALLEL_CLAUSES (expr),
10163 NULL_TREE, NULL_TREE);
10164 if (OMP_PARALLEL_COMBINED (expr))
10165 gimple_omp_set_subcode (g, GF_OMP_PARALLEL_COMBINED);
10166 gimplify_seq_add_stmt (pre_p, g);
10167 *expr_p = NULL_TREE;
10170 /* Gimplify the contents of an OMP_TASK statement. This involves
10171 gimplification of the body, as well as scanning the body for used
10172 variables. We need to do this scan now, because variable-sized
10173 decls will be decomposed during gimplification. */
10175 static void
10176 gimplify_omp_task (tree *expr_p, gimple_seq *pre_p)
10178 tree expr = *expr_p;
10179 gimple *g;
10180 gimple_seq body = NULL;
10182 if (OMP_TASK_BODY (expr) == NULL_TREE)
10183 for (tree c = OMP_TASK_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
10184 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
10185 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_MUTEXINOUTSET)
10187 error_at (OMP_CLAUSE_LOCATION (c),
10188 "%<mutexinoutset%> kind in %<depend%> clause on a "
10189 "%<taskwait%> construct");
10190 break;
10193 gimplify_scan_omp_clauses (&OMP_TASK_CLAUSES (expr), pre_p,
10194 omp_find_clause (OMP_TASK_CLAUSES (expr),
10195 OMP_CLAUSE_UNTIED)
10196 ? ORT_UNTIED_TASK : ORT_TASK, OMP_TASK);
10198 if (OMP_TASK_BODY (expr))
10200 push_gimplify_context ();
10202 g = gimplify_and_return_first (OMP_TASK_BODY (expr), &body);
10203 if (gimple_code (g) == GIMPLE_BIND)
10204 pop_gimplify_context (g);
10205 else
10206 pop_gimplify_context (NULL);
10209 gimplify_adjust_omp_clauses (pre_p, body, &OMP_TASK_CLAUSES (expr),
10210 OMP_TASK);
10212 g = gimple_build_omp_task (body,
10213 OMP_TASK_CLAUSES (expr),
10214 NULL_TREE, NULL_TREE,
10215 NULL_TREE, NULL_TREE, NULL_TREE);
10216 if (OMP_TASK_BODY (expr) == NULL_TREE)
10217 gimple_omp_task_set_taskwait_p (g, true);
10218 gimplify_seq_add_stmt (pre_p, g);
10219 *expr_p = NULL_TREE;
10222 /* Helper function of gimplify_omp_for, find OMP_FOR resp. OMP_SIMD
10223 with non-NULL OMP_FOR_INIT. Also, fill in pdata array,
10224 pdata[0] non-NULL if there is anything non-trivial in between, pdata[1]
10225 is address of OMP_PARALLEL in between if any, pdata[2] is address of
10226 OMP_FOR in between if any and pdata[3] is address of the inner
10227 OMP_FOR/OMP_SIMD. */
10229 static tree
10230 find_combined_omp_for (tree *tp, int *walk_subtrees, void *data)
10232 tree **pdata = (tree **) data;
10233 *walk_subtrees = 0;
10234 switch (TREE_CODE (*tp))
10236 case OMP_FOR:
10237 if (OMP_FOR_INIT (*tp) != NULL_TREE)
10239 pdata[3] = tp;
10240 return *tp;
10242 pdata[2] = tp;
10243 *walk_subtrees = 1;
10244 break;
10245 case OMP_SIMD:
10246 if (OMP_FOR_INIT (*tp) != NULL_TREE)
10248 pdata[3] = tp;
10249 return *tp;
10251 break;
10252 case BIND_EXPR:
10253 if (BIND_EXPR_VARS (*tp)
10254 || (BIND_EXPR_BLOCK (*tp)
10255 && BLOCK_VARS (BIND_EXPR_BLOCK (*tp))))
10256 pdata[0] = tp;
10257 *walk_subtrees = 1;
10258 break;
10259 case STATEMENT_LIST:
10260 if (!tsi_one_before_end_p (tsi_start (*tp)))
10261 pdata[0] = tp;
10262 *walk_subtrees = 1;
10263 break;
10264 case TRY_FINALLY_EXPR:
10265 pdata[0] = tp;
10266 *walk_subtrees = 1;
10267 break;
10268 case OMP_PARALLEL:
10269 pdata[1] = tp;
10270 *walk_subtrees = 1;
10271 break;
10272 default:
10273 break;
10275 return NULL_TREE;
10278 /* Gimplify the gross structure of an OMP_FOR statement. */
10280 static enum gimplify_status
10281 gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
10283 tree for_stmt, orig_for_stmt, inner_for_stmt = NULL_TREE, decl, var, t;
10284 enum gimplify_status ret = GS_ALL_DONE;
10285 enum gimplify_status tret;
10286 gomp_for *gfor;
10287 gimple_seq for_body, for_pre_body;
10288 int i;
10289 bitmap has_decl_expr = NULL;
10290 enum omp_region_type ort = ORT_WORKSHARE;
10292 orig_for_stmt = for_stmt = *expr_p;
10294 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
10296 tree *data[4] = { NULL, NULL, NULL, NULL };
10297 gcc_assert (TREE_CODE (for_stmt) != OACC_LOOP);
10298 inner_for_stmt = walk_tree (&OMP_FOR_BODY (for_stmt),
10299 find_combined_omp_for, data, NULL);
10300 if (inner_for_stmt == NULL_TREE)
10302 gcc_assert (seen_error ());
10303 *expr_p = NULL_TREE;
10304 return GS_ERROR;
10306 if (data[2] && OMP_FOR_PRE_BODY (*data[2]))
10308 append_to_statement_list_force (OMP_FOR_PRE_BODY (*data[2]),
10309 &OMP_FOR_PRE_BODY (for_stmt));
10310 OMP_FOR_PRE_BODY (*data[2]) = NULL_TREE;
10312 if (OMP_FOR_PRE_BODY (inner_for_stmt))
10314 append_to_statement_list_force (OMP_FOR_PRE_BODY (inner_for_stmt),
10315 &OMP_FOR_PRE_BODY (for_stmt));
10316 OMP_FOR_PRE_BODY (inner_for_stmt) = NULL_TREE;
10319 if (data[0])
10321 /* We have some statements or variable declarations in between
10322 the composite construct directives. Move them around the
10323 inner_for_stmt. */
10324 data[0] = expr_p;
10325 for (i = 0; i < 3; i++)
10326 if (data[i])
10328 tree t = *data[i];
10329 if (i < 2 && data[i + 1] == &OMP_BODY (t))
10330 data[i + 1] = data[i];
10331 *data[i] = OMP_BODY (t);
10332 tree body = build3 (BIND_EXPR, void_type_node, NULL_TREE,
10333 NULL_TREE, make_node (BLOCK));
10334 OMP_BODY (t) = body;
10335 append_to_statement_list_force (inner_for_stmt,
10336 &BIND_EXPR_BODY (body));
10337 *data[3] = t;
10338 data[3] = tsi_stmt_ptr (tsi_start (BIND_EXPR_BODY (body)));
10339 gcc_assert (*data[3] == inner_for_stmt);
10341 return GS_OK;
10344 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
10345 if (OMP_FOR_ORIG_DECLS (inner_for_stmt)
10346 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
10347 i)) == TREE_LIST
10348 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
10349 i)))
10351 tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
10352 /* Class iterators aren't allowed on OMP_SIMD, so the only
10353 case we need to solve is distribute parallel for. */
10354 gcc_assert (TREE_CODE (inner_for_stmt) == OMP_FOR
10355 && TREE_CODE (for_stmt) == OMP_DISTRIBUTE
10356 && data[1]);
10357 tree orig_decl = TREE_PURPOSE (orig);
10358 tree last = TREE_VALUE (orig);
10359 tree *pc;
10360 for (pc = &OMP_FOR_CLAUSES (inner_for_stmt);
10361 *pc; pc = &OMP_CLAUSE_CHAIN (*pc))
10362 if ((OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE
10363 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LASTPRIVATE)
10364 && OMP_CLAUSE_DECL (*pc) == orig_decl)
10365 break;
10366 if (*pc == NULL_TREE)
10368 else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE)
10370 /* private clause will appear only on inner_for_stmt.
10371 Change it into firstprivate, and add private clause
10372 on for_stmt. */
10373 tree c = copy_node (*pc);
10374 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
10375 OMP_FOR_CLAUSES (for_stmt) = c;
10376 OMP_CLAUSE_CODE (*pc) = OMP_CLAUSE_FIRSTPRIVATE;
10377 lang_hooks.decls.omp_finish_clause (*pc, pre_p);
10379 else
10381 /* lastprivate clause will appear on both inner_for_stmt
10382 and for_stmt. Add firstprivate clause to
10383 inner_for_stmt. */
10384 tree c = build_omp_clause (OMP_CLAUSE_LOCATION (*pc),
10385 OMP_CLAUSE_FIRSTPRIVATE);
10386 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (*pc);
10387 OMP_CLAUSE_CHAIN (c) = *pc;
10388 *pc = c;
10389 lang_hooks.decls.omp_finish_clause (*pc, pre_p);
10391 tree c = build_omp_clause (UNKNOWN_LOCATION,
10392 OMP_CLAUSE_FIRSTPRIVATE);
10393 OMP_CLAUSE_DECL (c) = last;
10394 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
10395 OMP_PARALLEL_CLAUSES (*data[1]) = c;
10396 c = build_omp_clause (UNKNOWN_LOCATION,
10397 *pc ? OMP_CLAUSE_SHARED
10398 : OMP_CLAUSE_FIRSTPRIVATE);
10399 OMP_CLAUSE_DECL (c) = orig_decl;
10400 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
10401 OMP_PARALLEL_CLAUSES (*data[1]) = c;
10403 /* Similarly, take care of C++ range for temporaries, those should
10404 be firstprivate on OMP_PARALLEL if any. */
10405 if (data[1])
10406 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
10407 if (OMP_FOR_ORIG_DECLS (inner_for_stmt)
10408 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
10409 i)) == TREE_LIST
10410 && TREE_CHAIN (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
10411 i)))
10413 tree orig
10414 = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
10415 tree v = TREE_CHAIN (orig);
10416 tree c = build_omp_clause (UNKNOWN_LOCATION,
10417 OMP_CLAUSE_FIRSTPRIVATE);
10418 /* First add firstprivate clause for the __for_end artificial
10419 decl. */
10420 OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 1);
10421 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
10422 == REFERENCE_TYPE)
10423 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
10424 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
10425 OMP_PARALLEL_CLAUSES (*data[1]) = c;
10426 if (TREE_VEC_ELT (v, 0))
10428 /* And now the same for __for_range artificial decl if it
10429 exists. */
10430 c = build_omp_clause (UNKNOWN_LOCATION,
10431 OMP_CLAUSE_FIRSTPRIVATE);
10432 OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 0);
10433 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
10434 == REFERENCE_TYPE)
10435 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
10436 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
10437 OMP_PARALLEL_CLAUSES (*data[1]) = c;
10442 switch (TREE_CODE (for_stmt))
10444 case OMP_FOR:
10445 case OMP_DISTRIBUTE:
10446 break;
10447 case OACC_LOOP:
10448 ort = ORT_ACC;
10449 break;
10450 case OMP_TASKLOOP:
10451 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_UNTIED))
10452 ort = ORT_UNTIED_TASKLOOP;
10453 else
10454 ort = ORT_TASKLOOP;
10455 break;
10456 case OMP_SIMD:
10457 ort = ORT_SIMD;
10458 break;
10459 default:
10460 gcc_unreachable ();
10463 /* Set OMP_CLAUSE_LINEAR_NO_COPYIN flag on explicit linear
10464 clause for the IV. */
10465 if (ort == ORT_SIMD && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
10467 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), 0);
10468 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
10469 decl = TREE_OPERAND (t, 0);
10470 for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
10471 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
10472 && OMP_CLAUSE_DECL (c) == decl)
10474 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
10475 break;
10479 if (TREE_CODE (for_stmt) != OMP_TASKLOOP)
10480 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p, ort,
10481 TREE_CODE (for_stmt));
10483 if (TREE_CODE (for_stmt) == OMP_DISTRIBUTE)
10484 gimplify_omp_ctxp->distribute = true;
10486 /* Handle OMP_FOR_INIT. */
10487 for_pre_body = NULL;
10488 if ((ort == ORT_SIMD
10489 || (inner_for_stmt && TREE_CODE (inner_for_stmt) == OMP_SIMD))
10490 && OMP_FOR_PRE_BODY (for_stmt))
10492 has_decl_expr = BITMAP_ALLOC (NULL);
10493 if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == DECL_EXPR
10494 && TREE_CODE (DECL_EXPR_DECL (OMP_FOR_PRE_BODY (for_stmt)))
10495 == VAR_DECL)
10497 t = OMP_FOR_PRE_BODY (for_stmt);
10498 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
10500 else if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == STATEMENT_LIST)
10502 tree_stmt_iterator si;
10503 for (si = tsi_start (OMP_FOR_PRE_BODY (for_stmt)); !tsi_end_p (si);
10504 tsi_next (&si))
10506 t = tsi_stmt (si);
10507 if (TREE_CODE (t) == DECL_EXPR
10508 && TREE_CODE (DECL_EXPR_DECL (t)) == VAR_DECL)
10509 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
10513 if (OMP_FOR_PRE_BODY (for_stmt))
10515 if (TREE_CODE (for_stmt) != OMP_TASKLOOP || gimplify_omp_ctxp)
10516 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
10517 else
10519 struct gimplify_omp_ctx ctx;
10520 memset (&ctx, 0, sizeof (ctx));
10521 ctx.region_type = ORT_NONE;
10522 gimplify_omp_ctxp = &ctx;
10523 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
10524 gimplify_omp_ctxp = NULL;
10527 OMP_FOR_PRE_BODY (for_stmt) = NULL_TREE;
10529 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
10530 for_stmt = inner_for_stmt;
10532 /* For taskloop, need to gimplify the start, end and step before the
10533 taskloop, outside of the taskloop omp context. */
10534 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
10536 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
10538 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
10539 if (!is_gimple_constant (TREE_OPERAND (t, 1)))
10541 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
10542 TREE_OPERAND (t, 1)
10543 = get_initialized_tmp_var (TREE_OPERAND (t, 1),
10544 gimple_seq_empty_p (for_pre_body)
10545 ? pre_p : &for_pre_body, NULL,
10546 false);
10547 /* Reference to pointer conversion is considered useless,
10548 but is significant for firstprivate clause. Force it
10549 here. */
10550 if (TREE_CODE (type) == POINTER_TYPE
10551 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 1)))
10552 == REFERENCE_TYPE))
10554 tree v = create_tmp_var (TYPE_MAIN_VARIANT (type));
10555 tree m = build2 (INIT_EXPR, TREE_TYPE (v), v,
10556 TREE_OPERAND (t, 1));
10557 gimplify_and_add (m, gimple_seq_empty_p (for_pre_body)
10558 ? pre_p : &for_pre_body);
10559 TREE_OPERAND (t, 1) = v;
10561 tree c = build_omp_clause (input_location,
10562 OMP_CLAUSE_FIRSTPRIVATE);
10563 OMP_CLAUSE_DECL (c) = TREE_OPERAND (t, 1);
10564 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
10565 OMP_FOR_CLAUSES (orig_for_stmt) = c;
10568 /* Handle OMP_FOR_COND. */
10569 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
10570 if (!is_gimple_constant (TREE_OPERAND (t, 1)))
10572 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
10573 TREE_OPERAND (t, 1)
10574 = get_initialized_tmp_var (TREE_OPERAND (t, 1),
10575 gimple_seq_empty_p (for_pre_body)
10576 ? pre_p : &for_pre_body, NULL,
10577 false);
10578 /* Reference to pointer conversion is considered useless,
10579 but is significant for firstprivate clause. Force it
10580 here. */
10581 if (TREE_CODE (type) == POINTER_TYPE
10582 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 1)))
10583 == REFERENCE_TYPE))
10585 tree v = create_tmp_var (TYPE_MAIN_VARIANT (type));
10586 tree m = build2 (INIT_EXPR, TREE_TYPE (v), v,
10587 TREE_OPERAND (t, 1));
10588 gimplify_and_add (m, gimple_seq_empty_p (for_pre_body)
10589 ? pre_p : &for_pre_body);
10590 TREE_OPERAND (t, 1) = v;
10592 tree c = build_omp_clause (input_location,
10593 OMP_CLAUSE_FIRSTPRIVATE);
10594 OMP_CLAUSE_DECL (c) = TREE_OPERAND (t, 1);
10595 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
10596 OMP_FOR_CLAUSES (orig_for_stmt) = c;
10599 /* Handle OMP_FOR_INCR. */
10600 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
10601 if (TREE_CODE (t) == MODIFY_EXPR)
10603 decl = TREE_OPERAND (t, 0);
10604 t = TREE_OPERAND (t, 1);
10605 tree *tp = &TREE_OPERAND (t, 1);
10606 if (TREE_CODE (t) == PLUS_EXPR && *tp == decl)
10607 tp = &TREE_OPERAND (t, 0);
10609 if (!is_gimple_constant (*tp))
10611 gimple_seq *seq = gimple_seq_empty_p (for_pre_body)
10612 ? pre_p : &for_pre_body;
10613 *tp = get_initialized_tmp_var (*tp, seq, NULL, false);
10614 tree c = build_omp_clause (input_location,
10615 OMP_CLAUSE_FIRSTPRIVATE);
10616 OMP_CLAUSE_DECL (c) = *tp;
10617 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
10618 OMP_FOR_CLAUSES (orig_for_stmt) = c;
10623 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (orig_for_stmt), pre_p, ort,
10624 OMP_TASKLOOP);
10627 if (orig_for_stmt != for_stmt)
10628 gimplify_omp_ctxp->combined_loop = true;
10630 for_body = NULL;
10631 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
10632 == TREE_VEC_LENGTH (OMP_FOR_COND (for_stmt)));
10633 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
10634 == TREE_VEC_LENGTH (OMP_FOR_INCR (for_stmt)));
10636 tree c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED);
10637 bool is_doacross = false;
10638 if (c && OMP_CLAUSE_ORDERED_EXPR (c))
10640 is_doacross = true;
10641 gimplify_omp_ctxp->loop_iter_var.create (TREE_VEC_LENGTH
10642 (OMP_FOR_INIT (for_stmt))
10643 * 2);
10645 int collapse = 1, tile = 0;
10646 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_COLLAPSE);
10647 if (c)
10648 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (c));
10649 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_TILE);
10650 if (c)
10651 tile = list_length (OMP_CLAUSE_TILE_LIST (c));
10652 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
10654 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
10655 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
10656 decl = TREE_OPERAND (t, 0);
10657 gcc_assert (DECL_P (decl));
10658 gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl))
10659 || POINTER_TYPE_P (TREE_TYPE (decl)));
10660 if (is_doacross)
10662 if (TREE_CODE (for_stmt) == OMP_FOR && OMP_FOR_ORIG_DECLS (for_stmt))
10664 tree orig_decl = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
10665 if (TREE_CODE (orig_decl) == TREE_LIST)
10667 orig_decl = TREE_PURPOSE (orig_decl);
10668 if (!orig_decl)
10669 orig_decl = decl;
10671 gimplify_omp_ctxp->loop_iter_var.quick_push (orig_decl);
10673 else
10674 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
10675 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
10678 /* Make sure the iteration variable is private. */
10679 tree c = NULL_TREE;
10680 tree c2 = NULL_TREE;
10681 if (orig_for_stmt != for_stmt)
10683 /* Preserve this information until we gimplify the inner simd. */
10684 if (has_decl_expr
10685 && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
10686 TREE_PRIVATE (t) = 1;
10688 else if (ort == ORT_SIMD)
10690 splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
10691 (splay_tree_key) decl);
10692 omp_is_private (gimplify_omp_ctxp, decl,
10693 1 + (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
10694 != 1));
10695 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
10696 omp_notice_variable (gimplify_omp_ctxp, decl, true);
10697 else if (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
10699 c = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
10700 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
10701 unsigned int flags = GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN;
10702 if ((has_decl_expr
10703 && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
10704 || TREE_PRIVATE (t))
10706 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
10707 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
10709 struct gimplify_omp_ctx *outer
10710 = gimplify_omp_ctxp->outer_context;
10711 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
10713 if (outer->region_type == ORT_WORKSHARE
10714 && outer->combined_loop)
10716 n = splay_tree_lookup (outer->variables,
10717 (splay_tree_key)decl);
10718 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
10720 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
10721 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
10723 else
10725 struct gimplify_omp_ctx *octx = outer->outer_context;
10726 if (octx
10727 && octx->region_type == ORT_COMBINED_PARALLEL
10728 && octx->outer_context
10729 && (octx->outer_context->region_type
10730 == ORT_WORKSHARE)
10731 && octx->outer_context->combined_loop)
10733 octx = octx->outer_context;
10734 n = splay_tree_lookup (octx->variables,
10735 (splay_tree_key)decl);
10736 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
10738 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
10739 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
10746 OMP_CLAUSE_DECL (c) = decl;
10747 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
10748 OMP_FOR_CLAUSES (for_stmt) = c;
10749 omp_add_variable (gimplify_omp_ctxp, decl, flags);
10750 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
10752 if (outer->region_type == ORT_WORKSHARE
10753 && outer->combined_loop)
10755 if (outer->outer_context
10756 && (outer->outer_context->region_type
10757 == ORT_COMBINED_PARALLEL))
10758 outer = outer->outer_context;
10759 else if (omp_check_private (outer, decl, false))
10760 outer = NULL;
10762 else if (((outer->region_type & ORT_TASKLOOP)
10763 == ORT_TASKLOOP)
10764 && outer->combined_loop
10765 && !omp_check_private (gimplify_omp_ctxp,
10766 decl, false))
10768 else if (outer->region_type != ORT_COMBINED_PARALLEL)
10770 omp_notice_variable (outer, decl, true);
10771 outer = NULL;
10773 if (outer)
10775 n = splay_tree_lookup (outer->variables,
10776 (splay_tree_key)decl);
10777 if (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
10779 omp_add_variable (outer, decl,
10780 GOVD_LASTPRIVATE | GOVD_SEEN);
10781 if (outer->region_type == ORT_COMBINED_PARALLEL
10782 && outer->outer_context
10783 && (outer->outer_context->region_type
10784 == ORT_WORKSHARE)
10785 && outer->outer_context->combined_loop)
10787 outer = outer->outer_context;
10788 n = splay_tree_lookup (outer->variables,
10789 (splay_tree_key)decl);
10790 if (omp_check_private (outer, decl, false))
10791 outer = NULL;
10792 else if (n == NULL
10793 || ((n->value & GOVD_DATA_SHARE_CLASS)
10794 == 0))
10795 omp_add_variable (outer, decl,
10796 GOVD_LASTPRIVATE
10797 | GOVD_SEEN);
10798 else
10799 outer = NULL;
10801 if (outer && outer->outer_context
10802 && ((outer->outer_context->region_type
10803 & ORT_COMBINED_TEAMS) == ORT_COMBINED_TEAMS
10804 || (((outer->region_type & ORT_TASKLOOP)
10805 == ORT_TASKLOOP)
10806 && (outer->outer_context->region_type
10807 == ORT_COMBINED_PARALLEL))))
10809 outer = outer->outer_context;
10810 n = splay_tree_lookup (outer->variables,
10811 (splay_tree_key)decl);
10812 if (n == NULL
10813 || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
10814 omp_add_variable (outer, decl,
10815 GOVD_SHARED | GOVD_SEEN);
10816 else
10817 outer = NULL;
10819 if (outer && outer->outer_context)
10820 omp_notice_variable (outer->outer_context, decl,
10821 true);
10826 else
10828 bool lastprivate
10829 = (!has_decl_expr
10830 || !bitmap_bit_p (has_decl_expr, DECL_UID (decl)));
10831 if (TREE_PRIVATE (t))
10832 lastprivate = false;
10833 struct gimplify_omp_ctx *outer
10834 = gimplify_omp_ctxp->outer_context;
10835 if (outer && lastprivate)
10837 if (outer->region_type == ORT_WORKSHARE
10838 && outer->combined_loop)
10840 n = splay_tree_lookup (outer->variables,
10841 (splay_tree_key)decl);
10842 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
10844 lastprivate = false;
10845 outer = NULL;
10847 else if (outer->outer_context
10848 && (outer->outer_context->region_type
10849 == ORT_COMBINED_PARALLEL))
10850 outer = outer->outer_context;
10851 else if (omp_check_private (outer, decl, false))
10852 outer = NULL;
10854 else if (((outer->region_type & ORT_TASKLOOP)
10855 == ORT_TASKLOOP)
10856 && outer->combined_loop
10857 && !omp_check_private (gimplify_omp_ctxp,
10858 decl, false))
10860 else if (outer->region_type != ORT_COMBINED_PARALLEL)
10862 omp_notice_variable (outer, decl, true);
10863 outer = NULL;
10865 if (outer)
10867 n = splay_tree_lookup (outer->variables,
10868 (splay_tree_key)decl);
10869 if (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
10871 omp_add_variable (outer, decl,
10872 GOVD_LASTPRIVATE | GOVD_SEEN);
10873 if (outer->region_type == ORT_COMBINED_PARALLEL
10874 && outer->outer_context
10875 && (outer->outer_context->region_type
10876 == ORT_WORKSHARE)
10877 && outer->outer_context->combined_loop)
10879 outer = outer->outer_context;
10880 n = splay_tree_lookup (outer->variables,
10881 (splay_tree_key)decl);
10882 if (omp_check_private (outer, decl, false))
10883 outer = NULL;
10884 else if (n == NULL
10885 || ((n->value & GOVD_DATA_SHARE_CLASS)
10886 == 0))
10887 omp_add_variable (outer, decl,
10888 GOVD_LASTPRIVATE
10889 | GOVD_SEEN);
10890 else
10891 outer = NULL;
10893 if (outer && outer->outer_context
10894 && ((outer->outer_context->region_type
10895 & ORT_COMBINED_TEAMS) == ORT_COMBINED_TEAMS
10896 || (((outer->region_type & ORT_TASKLOOP)
10897 == ORT_TASKLOOP)
10898 && (outer->outer_context->region_type
10899 == ORT_COMBINED_PARALLEL))))
10901 outer = outer->outer_context;
10902 n = splay_tree_lookup (outer->variables,
10903 (splay_tree_key)decl);
10904 if (n == NULL
10905 || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
10906 omp_add_variable (outer, decl,
10907 GOVD_SHARED | GOVD_SEEN);
10908 else
10909 outer = NULL;
10911 if (outer && outer->outer_context)
10912 omp_notice_variable (outer->outer_context, decl,
10913 true);
10918 c = build_omp_clause (input_location,
10919 lastprivate ? OMP_CLAUSE_LASTPRIVATE
10920 : OMP_CLAUSE_PRIVATE);
10921 OMP_CLAUSE_DECL (c) = decl;
10922 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
10923 OMP_FOR_CLAUSES (for_stmt) = c;
10924 omp_add_variable (gimplify_omp_ctxp, decl,
10925 (lastprivate ? GOVD_LASTPRIVATE : GOVD_PRIVATE)
10926 | GOVD_EXPLICIT | GOVD_SEEN);
10927 c = NULL_TREE;
10930 else if (omp_is_private (gimplify_omp_ctxp, decl, 0))
10931 omp_notice_variable (gimplify_omp_ctxp, decl, true);
10932 else
10933 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN);
10935 /* If DECL is not a gimple register, create a temporary variable to act
10936 as an iteration counter. This is valid, since DECL cannot be
10937 modified in the body of the loop. Similarly for any iteration vars
10938 in simd with collapse > 1 where the iterator vars must be
10939 lastprivate. */
10940 if (orig_for_stmt != for_stmt)
10941 var = decl;
10942 else if (!is_gimple_reg (decl)
10943 || (ort == ORT_SIMD
10944 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) > 1))
10946 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
10947 /* Make sure omp_add_variable is not called on it prematurely.
10948 We call it ourselves a few lines later. */
10949 gimplify_omp_ctxp = NULL;
10950 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
10951 gimplify_omp_ctxp = ctx;
10952 TREE_OPERAND (t, 0) = var;
10954 gimplify_seq_add_stmt (&for_body, gimple_build_assign (decl, var));
10956 if (ort == ORT_SIMD
10957 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
10959 c2 = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
10960 OMP_CLAUSE_LINEAR_NO_COPYIN (c2) = 1;
10961 OMP_CLAUSE_LINEAR_NO_COPYOUT (c2) = 1;
10962 OMP_CLAUSE_DECL (c2) = var;
10963 OMP_CLAUSE_CHAIN (c2) = OMP_FOR_CLAUSES (for_stmt);
10964 OMP_FOR_CLAUSES (for_stmt) = c2;
10965 omp_add_variable (gimplify_omp_ctxp, var,
10966 GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN);
10967 if (c == NULL_TREE)
10969 c = c2;
10970 c2 = NULL_TREE;
10973 else
10974 omp_add_variable (gimplify_omp_ctxp, var,
10975 GOVD_PRIVATE | GOVD_SEEN);
10977 else
10978 var = decl;
10980 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
10981 is_gimple_val, fb_rvalue, false);
10982 ret = MIN (ret, tret);
10983 if (ret == GS_ERROR)
10984 return ret;
10986 /* Handle OMP_FOR_COND. */
10987 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
10988 gcc_assert (COMPARISON_CLASS_P (t));
10989 gcc_assert (TREE_OPERAND (t, 0) == decl);
10991 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
10992 is_gimple_val, fb_rvalue, false);
10993 ret = MIN (ret, tret);
10995 /* Handle OMP_FOR_INCR. */
10996 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
10997 switch (TREE_CODE (t))
10999 case PREINCREMENT_EXPR:
11000 case POSTINCREMENT_EXPR:
11002 tree decl = TREE_OPERAND (t, 0);
11003 /* c_omp_for_incr_canonicalize_ptr() should have been
11004 called to massage things appropriately. */
11005 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
11007 if (orig_for_stmt != for_stmt)
11008 break;
11009 t = build_int_cst (TREE_TYPE (decl), 1);
11010 if (c)
11011 OMP_CLAUSE_LINEAR_STEP (c) = t;
11012 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
11013 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
11014 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
11015 break;
11018 case PREDECREMENT_EXPR:
11019 case POSTDECREMENT_EXPR:
11020 /* c_omp_for_incr_canonicalize_ptr() should have been
11021 called to massage things appropriately. */
11022 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
11023 if (orig_for_stmt != for_stmt)
11024 break;
11025 t = build_int_cst (TREE_TYPE (decl), -1);
11026 if (c)
11027 OMP_CLAUSE_LINEAR_STEP (c) = t;
11028 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
11029 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
11030 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
11031 break;
11033 case MODIFY_EXPR:
11034 gcc_assert (TREE_OPERAND (t, 0) == decl);
11035 TREE_OPERAND (t, 0) = var;
11037 t = TREE_OPERAND (t, 1);
11038 switch (TREE_CODE (t))
11040 case PLUS_EXPR:
11041 if (TREE_OPERAND (t, 1) == decl)
11043 TREE_OPERAND (t, 1) = TREE_OPERAND (t, 0);
11044 TREE_OPERAND (t, 0) = var;
11045 break;
11048 /* Fallthru. */
11049 case MINUS_EXPR:
11050 case POINTER_PLUS_EXPR:
11051 gcc_assert (TREE_OPERAND (t, 0) == decl);
11052 TREE_OPERAND (t, 0) = var;
11053 break;
11054 default:
11055 gcc_unreachable ();
11058 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
11059 is_gimple_val, fb_rvalue, false);
11060 ret = MIN (ret, tret);
11061 if (c)
11063 tree step = TREE_OPERAND (t, 1);
11064 tree stept = TREE_TYPE (decl);
11065 if (POINTER_TYPE_P (stept))
11066 stept = sizetype;
11067 step = fold_convert (stept, step);
11068 if (TREE_CODE (t) == MINUS_EXPR)
11069 step = fold_build1 (NEGATE_EXPR, stept, step);
11070 OMP_CLAUSE_LINEAR_STEP (c) = step;
11071 if (step != TREE_OPERAND (t, 1))
11073 tret = gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c),
11074 &for_pre_body, NULL,
11075 is_gimple_val, fb_rvalue, false);
11076 ret = MIN (ret, tret);
11079 break;
11081 default:
11082 gcc_unreachable ();
11085 if (c2)
11087 gcc_assert (c);
11088 OMP_CLAUSE_LINEAR_STEP (c2) = OMP_CLAUSE_LINEAR_STEP (c);
11091 if ((var != decl || collapse > 1 || tile) && orig_for_stmt == for_stmt)
11093 for (c = OMP_FOR_CLAUSES (for_stmt); c ; c = OMP_CLAUSE_CHAIN (c))
11094 if (((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
11095 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) == NULL)
11096 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
11097 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)
11098 && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c) == NULL))
11099 && OMP_CLAUSE_DECL (c) == decl)
11101 if (is_doacross && (collapse == 1 || i >= collapse))
11102 t = var;
11103 else
11105 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
11106 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
11107 gcc_assert (TREE_OPERAND (t, 0) == var);
11108 t = TREE_OPERAND (t, 1);
11109 gcc_assert (TREE_CODE (t) == PLUS_EXPR
11110 || TREE_CODE (t) == MINUS_EXPR
11111 || TREE_CODE (t) == POINTER_PLUS_EXPR);
11112 gcc_assert (TREE_OPERAND (t, 0) == var);
11113 t = build2 (TREE_CODE (t), TREE_TYPE (decl),
11114 is_doacross ? var : decl,
11115 TREE_OPERAND (t, 1));
11117 gimple_seq *seq;
11118 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
11119 seq = &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c);
11120 else
11121 seq = &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c);
11122 gimplify_assign (decl, t, seq);
11127 BITMAP_FREE (has_decl_expr);
11129 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
11131 push_gimplify_context ();
11132 if (TREE_CODE (OMP_FOR_BODY (orig_for_stmt)) != BIND_EXPR)
11134 OMP_FOR_BODY (orig_for_stmt)
11135 = build3 (BIND_EXPR, void_type_node, NULL,
11136 OMP_FOR_BODY (orig_for_stmt), NULL);
11137 TREE_SIDE_EFFECTS (OMP_FOR_BODY (orig_for_stmt)) = 1;
11141 gimple *g = gimplify_and_return_first (OMP_FOR_BODY (orig_for_stmt),
11142 &for_body);
11144 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
11146 if (gimple_code (g) == GIMPLE_BIND)
11147 pop_gimplify_context (g);
11148 else
11149 pop_gimplify_context (NULL);
11152 if (orig_for_stmt != for_stmt)
11153 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
11155 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
11156 decl = TREE_OPERAND (t, 0);
11157 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
11158 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
11159 gimplify_omp_ctxp = ctx->outer_context;
11160 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
11161 gimplify_omp_ctxp = ctx;
11162 omp_add_variable (gimplify_omp_ctxp, var, GOVD_PRIVATE | GOVD_SEEN);
11163 TREE_OPERAND (t, 0) = var;
11164 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
11165 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
11166 TREE_OPERAND (TREE_OPERAND (t, 1), 0) = var;
11169 gimplify_adjust_omp_clauses (pre_p, for_body,
11170 &OMP_FOR_CLAUSES (orig_for_stmt),
11171 TREE_CODE (orig_for_stmt));
11173 int kind;
11174 switch (TREE_CODE (orig_for_stmt))
11176 case OMP_FOR: kind = GF_OMP_FOR_KIND_FOR; break;
11177 case OMP_SIMD: kind = GF_OMP_FOR_KIND_SIMD; break;
11178 case OMP_DISTRIBUTE: kind = GF_OMP_FOR_KIND_DISTRIBUTE; break;
11179 case OMP_TASKLOOP: kind = GF_OMP_FOR_KIND_TASKLOOP; break;
11180 case OACC_LOOP: kind = GF_OMP_FOR_KIND_OACC_LOOP; break;
11181 default:
11182 gcc_unreachable ();
11184 gfor = gimple_build_omp_for (for_body, kind, OMP_FOR_CLAUSES (orig_for_stmt),
11185 TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)),
11186 for_pre_body);
11187 if (orig_for_stmt != for_stmt)
11188 gimple_omp_for_set_combined_p (gfor, true);
11189 if (gimplify_omp_ctxp
11190 && (gimplify_omp_ctxp->combined_loop
11191 || (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
11192 && gimplify_omp_ctxp->outer_context
11193 && gimplify_omp_ctxp->outer_context->combined_loop)))
11195 gimple_omp_for_set_combined_into_p (gfor, true);
11196 if (gimplify_omp_ctxp->combined_loop)
11197 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_SIMD);
11198 else
11199 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_FOR);
11202 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
11204 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
11205 gimple_omp_for_set_index (gfor, i, TREE_OPERAND (t, 0));
11206 gimple_omp_for_set_initial (gfor, i, TREE_OPERAND (t, 1));
11207 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
11208 gimple_omp_for_set_cond (gfor, i, TREE_CODE (t));
11209 gimple_omp_for_set_final (gfor, i, TREE_OPERAND (t, 1));
11210 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
11211 gimple_omp_for_set_incr (gfor, i, TREE_OPERAND (t, 1));
11214 /* OMP_TASKLOOP is gimplified as two GIMPLE_OMP_FOR taskloop
11215 constructs with GIMPLE_OMP_TASK sandwiched in between them.
11216 The outer taskloop stands for computing the number of iterations,
11217 counts for collapsed loops and holding taskloop specific clauses.
11218 The task construct stands for the effect of data sharing on the
11219 explicit task it creates and the inner taskloop stands for expansion
11220 of the static loop inside of the explicit task construct. */
11221 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
11223 tree *gfor_clauses_ptr = gimple_omp_for_clauses_ptr (gfor);
11224 tree task_clauses = NULL_TREE;
11225 tree c = *gfor_clauses_ptr;
11226 tree *gtask_clauses_ptr = &task_clauses;
11227 tree outer_for_clauses = NULL_TREE;
11228 tree *gforo_clauses_ptr = &outer_for_clauses;
11229 for (; c; c = OMP_CLAUSE_CHAIN (c))
11230 switch (OMP_CLAUSE_CODE (c))
11232 /* These clauses are allowed on task, move them there. */
11233 case OMP_CLAUSE_SHARED:
11234 case OMP_CLAUSE_FIRSTPRIVATE:
11235 case OMP_CLAUSE_DEFAULT:
11236 case OMP_CLAUSE_IF:
11237 case OMP_CLAUSE_UNTIED:
11238 case OMP_CLAUSE_FINAL:
11239 case OMP_CLAUSE_MERGEABLE:
11240 case OMP_CLAUSE_PRIORITY:
11241 case OMP_CLAUSE_REDUCTION:
11242 case OMP_CLAUSE_IN_REDUCTION:
11243 *gtask_clauses_ptr = c;
11244 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
11245 break;
11246 case OMP_CLAUSE_PRIVATE:
11247 if (OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c))
11249 /* We want private on outer for and firstprivate
11250 on task. */
11251 *gtask_clauses_ptr
11252 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
11253 OMP_CLAUSE_FIRSTPRIVATE);
11254 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
11255 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL);
11256 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
11257 *gforo_clauses_ptr = c;
11258 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
11260 else
11262 *gtask_clauses_ptr = c;
11263 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
11265 break;
11266 /* These clauses go into outer taskloop clauses. */
11267 case OMP_CLAUSE_GRAINSIZE:
11268 case OMP_CLAUSE_NUM_TASKS:
11269 case OMP_CLAUSE_NOGROUP:
11270 *gforo_clauses_ptr = c;
11271 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
11272 break;
11273 /* Taskloop clause we duplicate on both taskloops. */
11274 case OMP_CLAUSE_COLLAPSE:
11275 *gfor_clauses_ptr = c;
11276 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
11277 *gforo_clauses_ptr = copy_node (c);
11278 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
11279 break;
11280 /* For lastprivate, keep the clause on inner taskloop, and add
11281 a shared clause on task. If the same decl is also firstprivate,
11282 add also firstprivate clause on the inner taskloop. */
11283 case OMP_CLAUSE_LASTPRIVATE:
11284 if (OMP_CLAUSE_LASTPRIVATE_TASKLOOP_IV (c))
11286 /* For taskloop C++ lastprivate IVs, we want:
11287 1) private on outer taskloop
11288 2) firstprivate and shared on task
11289 3) lastprivate on inner taskloop */
11290 *gtask_clauses_ptr
11291 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
11292 OMP_CLAUSE_FIRSTPRIVATE);
11293 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
11294 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL);
11295 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
11296 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c) = 1;
11297 *gforo_clauses_ptr = build_omp_clause (OMP_CLAUSE_LOCATION (c),
11298 OMP_CLAUSE_PRIVATE);
11299 OMP_CLAUSE_DECL (*gforo_clauses_ptr) = OMP_CLAUSE_DECL (c);
11300 OMP_CLAUSE_PRIVATE_TASKLOOP_IV (*gforo_clauses_ptr) = 1;
11301 TREE_TYPE (*gforo_clauses_ptr) = TREE_TYPE (c);
11302 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
11304 *gfor_clauses_ptr = c;
11305 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
11306 *gtask_clauses_ptr
11307 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_SHARED);
11308 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
11309 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
11310 OMP_CLAUSE_SHARED_FIRSTPRIVATE (*gtask_clauses_ptr) = 1;
11311 gtask_clauses_ptr
11312 = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
11313 break;
11314 default:
11315 gcc_unreachable ();
11317 *gfor_clauses_ptr = NULL_TREE;
11318 *gtask_clauses_ptr = NULL_TREE;
11319 *gforo_clauses_ptr = NULL_TREE;
11320 g = gimple_build_bind (NULL_TREE, gfor, NULL_TREE);
11321 g = gimple_build_omp_task (g, task_clauses, NULL_TREE, NULL_TREE,
11322 NULL_TREE, NULL_TREE, NULL_TREE);
11323 gimple_omp_task_set_taskloop_p (g, true);
11324 g = gimple_build_bind (NULL_TREE, g, NULL_TREE);
11325 gomp_for *gforo
11326 = gimple_build_omp_for (g, GF_OMP_FOR_KIND_TASKLOOP, outer_for_clauses,
11327 gimple_omp_for_collapse (gfor),
11328 gimple_omp_for_pre_body (gfor));
11329 gimple_omp_for_set_pre_body (gfor, NULL);
11330 gimple_omp_for_set_combined_p (gforo, true);
11331 gimple_omp_for_set_combined_into_p (gfor, true);
11332 for (i = 0; i < (int) gimple_omp_for_collapse (gfor); i++)
11334 tree type = TREE_TYPE (gimple_omp_for_index (gfor, i));
11335 tree v = create_tmp_var (type);
11336 gimple_omp_for_set_index (gforo, i, v);
11337 t = unshare_expr (gimple_omp_for_initial (gfor, i));
11338 gimple_omp_for_set_initial (gforo, i, t);
11339 gimple_omp_for_set_cond (gforo, i,
11340 gimple_omp_for_cond (gfor, i));
11341 t = unshare_expr (gimple_omp_for_final (gfor, i));
11342 gimple_omp_for_set_final (gforo, i, t);
11343 t = unshare_expr (gimple_omp_for_incr (gfor, i));
11344 gcc_assert (TREE_OPERAND (t, 0) == gimple_omp_for_index (gfor, i));
11345 TREE_OPERAND (t, 0) = v;
11346 gimple_omp_for_set_incr (gforo, i, t);
11347 t = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
11348 OMP_CLAUSE_DECL (t) = v;
11349 OMP_CLAUSE_CHAIN (t) = gimple_omp_for_clauses (gforo);
11350 gimple_omp_for_set_clauses (gforo, t);
11352 gimplify_seq_add_stmt (pre_p, gforo);
11354 else
11355 gimplify_seq_add_stmt (pre_p, gfor);
11356 if (ret != GS_ALL_DONE)
11357 return GS_ERROR;
11358 *expr_p = NULL_TREE;
11359 return GS_ALL_DONE;
11362 /* Helper function of optimize_target_teams, find OMP_TEAMS inside
11363 of OMP_TARGET's body. */
11365 static tree
11366 find_omp_teams (tree *tp, int *walk_subtrees, void *)
11368 *walk_subtrees = 0;
11369 switch (TREE_CODE (*tp))
11371 case OMP_TEAMS:
11372 return *tp;
11373 case BIND_EXPR:
11374 case STATEMENT_LIST:
11375 *walk_subtrees = 1;
11376 break;
11377 default:
11378 break;
11380 return NULL_TREE;
11383 /* Helper function of optimize_target_teams, determine if the expression
11384 can be computed safely before the target construct on the host. */
11386 static tree
11387 computable_teams_clause (tree *tp, int *walk_subtrees, void *)
11389 splay_tree_node n;
11391 if (TYPE_P (*tp))
11393 *walk_subtrees = 0;
11394 return NULL_TREE;
11396 switch (TREE_CODE (*tp))
11398 case VAR_DECL:
11399 case PARM_DECL:
11400 case RESULT_DECL:
11401 *walk_subtrees = 0;
11402 if (error_operand_p (*tp)
11403 || !INTEGRAL_TYPE_P (TREE_TYPE (*tp))
11404 || DECL_HAS_VALUE_EXPR_P (*tp)
11405 || DECL_THREAD_LOCAL_P (*tp)
11406 || TREE_SIDE_EFFECTS (*tp)
11407 || TREE_THIS_VOLATILE (*tp))
11408 return *tp;
11409 if (is_global_var (*tp)
11410 && (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (*tp))
11411 || lookup_attribute ("omp declare target link",
11412 DECL_ATTRIBUTES (*tp))))
11413 return *tp;
11414 if (VAR_P (*tp)
11415 && !DECL_SEEN_IN_BIND_EXPR_P (*tp)
11416 && !is_global_var (*tp)
11417 && decl_function_context (*tp) == current_function_decl)
11418 return *tp;
11419 n = splay_tree_lookup (gimplify_omp_ctxp->variables,
11420 (splay_tree_key) *tp);
11421 if (n == NULL)
11423 if (gimplify_omp_ctxp->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE)
11424 return NULL_TREE;
11425 return *tp;
11427 else if (n->value & GOVD_LOCAL)
11428 return *tp;
11429 else if (n->value & GOVD_FIRSTPRIVATE)
11430 return NULL_TREE;
11431 else if ((n->value & (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
11432 == (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
11433 return NULL_TREE;
11434 return *tp;
11435 case INTEGER_CST:
11436 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
11437 return *tp;
11438 return NULL_TREE;
11439 case TARGET_EXPR:
11440 if (TARGET_EXPR_INITIAL (*tp)
11441 || TREE_CODE (TARGET_EXPR_SLOT (*tp)) != VAR_DECL)
11442 return *tp;
11443 return computable_teams_clause (&TARGET_EXPR_SLOT (*tp),
11444 walk_subtrees, NULL);
11445 /* Allow some reasonable subset of integral arithmetics. */
11446 case PLUS_EXPR:
11447 case MINUS_EXPR:
11448 case MULT_EXPR:
11449 case TRUNC_DIV_EXPR:
11450 case CEIL_DIV_EXPR:
11451 case FLOOR_DIV_EXPR:
11452 case ROUND_DIV_EXPR:
11453 case TRUNC_MOD_EXPR:
11454 case CEIL_MOD_EXPR:
11455 case FLOOR_MOD_EXPR:
11456 case ROUND_MOD_EXPR:
11457 case RDIV_EXPR:
11458 case EXACT_DIV_EXPR:
11459 case MIN_EXPR:
11460 case MAX_EXPR:
11461 case LSHIFT_EXPR:
11462 case RSHIFT_EXPR:
11463 case BIT_IOR_EXPR:
11464 case BIT_XOR_EXPR:
11465 case BIT_AND_EXPR:
11466 case NEGATE_EXPR:
11467 case ABS_EXPR:
11468 case BIT_NOT_EXPR:
11469 case NON_LVALUE_EXPR:
11470 CASE_CONVERT:
11471 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
11472 return *tp;
11473 return NULL_TREE;
11474 /* And disallow anything else, except for comparisons. */
11475 default:
11476 if (COMPARISON_CLASS_P (*tp))
11477 return NULL_TREE;
11478 return *tp;
11482 /* Try to determine if the num_teams and/or thread_limit expressions
11483 can have their values determined already before entering the
11484 target construct.
11485 INTEGER_CSTs trivially are,
11486 integral decls that are firstprivate (explicitly or implicitly)
11487 or explicitly map(always, to:) or map(always, tofrom:) on the target
11488 region too, and expressions involving simple arithmetics on those
11489 too, function calls are not ok, dereferencing something neither etc.
11490 Add NUM_TEAMS and THREAD_LIMIT clauses to the OMP_CLAUSES of
11491 EXPR based on what we find:
11492 0 stands for clause not specified at all, use implementation default
11493 -1 stands for value that can't be determined easily before entering
11494 the target construct.
11495 If teams construct is not present at all, use 1 for num_teams
11496 and 0 for thread_limit (only one team is involved, and the thread
11497 limit is implementation defined. */
11499 static void
11500 optimize_target_teams (tree target, gimple_seq *pre_p)
11502 tree body = OMP_BODY (target);
11503 tree teams = walk_tree (&body, find_omp_teams, NULL, NULL);
11504 tree num_teams = integer_zero_node;
11505 tree thread_limit = integer_zero_node;
11506 location_t num_teams_loc = EXPR_LOCATION (target);
11507 location_t thread_limit_loc = EXPR_LOCATION (target);
11508 tree c, *p, expr;
11509 struct gimplify_omp_ctx *target_ctx = gimplify_omp_ctxp;
11511 if (teams == NULL_TREE)
11512 num_teams = integer_one_node;
11513 else
11514 for (c = OMP_TEAMS_CLAUSES (teams); c; c = OMP_CLAUSE_CHAIN (c))
11516 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS)
11518 p = &num_teams;
11519 num_teams_loc = OMP_CLAUSE_LOCATION (c);
11521 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
11523 p = &thread_limit;
11524 thread_limit_loc = OMP_CLAUSE_LOCATION (c);
11526 else
11527 continue;
11528 expr = OMP_CLAUSE_OPERAND (c, 0);
11529 if (TREE_CODE (expr) == INTEGER_CST)
11531 *p = expr;
11532 continue;
11534 if (walk_tree (&expr, computable_teams_clause, NULL, NULL))
11536 *p = integer_minus_one_node;
11537 continue;
11539 *p = expr;
11540 gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
11541 if (gimplify_expr (p, pre_p, NULL, is_gimple_val, fb_rvalue, false)
11542 == GS_ERROR)
11544 gimplify_omp_ctxp = target_ctx;
11545 *p = integer_minus_one_node;
11546 continue;
11548 gimplify_omp_ctxp = target_ctx;
11549 if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR)
11550 OMP_CLAUSE_OPERAND (c, 0) = *p;
11552 c = build_omp_clause (thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
11553 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = thread_limit;
11554 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
11555 OMP_TARGET_CLAUSES (target) = c;
11556 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
11557 OMP_CLAUSE_NUM_TEAMS_EXPR (c) = num_teams;
11558 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
11559 OMP_TARGET_CLAUSES (target) = c;
11562 /* Gimplify the gross structure of several OMP constructs. */
11564 static void
11565 gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
11567 tree expr = *expr_p;
11568 gimple *stmt;
11569 gimple_seq body = NULL;
11570 enum omp_region_type ort;
11572 switch (TREE_CODE (expr))
11574 case OMP_SECTIONS:
11575 case OMP_SINGLE:
11576 ort = ORT_WORKSHARE;
11577 break;
11578 case OMP_TARGET:
11579 ort = OMP_TARGET_COMBINED (expr) ? ORT_COMBINED_TARGET : ORT_TARGET;
11580 break;
11581 case OACC_KERNELS:
11582 ort = ORT_ACC_KERNELS;
11583 break;
11584 case OACC_PARALLEL:
11585 ort = ORT_ACC_PARALLEL;
11586 break;
11587 case OACC_DATA:
11588 ort = ORT_ACC_DATA;
11589 break;
11590 case OMP_TARGET_DATA:
11591 ort = ORT_TARGET_DATA;
11592 break;
11593 case OMP_TEAMS:
11594 ort = OMP_TEAMS_COMBINED (expr) ? ORT_COMBINED_TEAMS : ORT_TEAMS;
11595 if (gimplify_omp_ctxp == NULL
11596 || (gimplify_omp_ctxp->region_type == ORT_TARGET
11597 && gimplify_omp_ctxp->outer_context == NULL
11598 && lookup_attribute ("omp declare target",
11599 DECL_ATTRIBUTES (current_function_decl))))
11600 ort = (enum omp_region_type) (ort | ORT_HOST_TEAMS);
11601 break;
11602 case OACC_HOST_DATA:
11603 ort = ORT_ACC_HOST_DATA;
11604 break;
11605 default:
11606 gcc_unreachable ();
11608 gimplify_scan_omp_clauses (&OMP_CLAUSES (expr), pre_p, ort,
11609 TREE_CODE (expr));
11610 if (TREE_CODE (expr) == OMP_TARGET)
11611 optimize_target_teams (expr, pre_p);
11612 if ((ort & (ORT_TARGET | ORT_TARGET_DATA)) != 0
11613 || (ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
11615 push_gimplify_context ();
11616 gimple *g = gimplify_and_return_first (OMP_BODY (expr), &body);
11617 if (gimple_code (g) == GIMPLE_BIND)
11618 pop_gimplify_context (g);
11619 else
11620 pop_gimplify_context (NULL);
11621 if ((ort & ORT_TARGET_DATA) != 0)
11623 enum built_in_function end_ix;
11624 switch (TREE_CODE (expr))
11626 case OACC_DATA:
11627 case OACC_HOST_DATA:
11628 end_ix = BUILT_IN_GOACC_DATA_END;
11629 break;
11630 case OMP_TARGET_DATA:
11631 end_ix = BUILT_IN_GOMP_TARGET_END_DATA;
11632 break;
11633 default:
11634 gcc_unreachable ();
11636 tree fn = builtin_decl_explicit (end_ix);
11637 g = gimple_build_call (fn, 0);
11638 gimple_seq cleanup = NULL;
11639 gimple_seq_add_stmt (&cleanup, g);
11640 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
11641 body = NULL;
11642 gimple_seq_add_stmt (&body, g);
11645 else
11646 gimplify_and_add (OMP_BODY (expr), &body);
11647 gimplify_adjust_omp_clauses (pre_p, body, &OMP_CLAUSES (expr),
11648 TREE_CODE (expr));
11650 switch (TREE_CODE (expr))
11652 case OACC_DATA:
11653 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_DATA,
11654 OMP_CLAUSES (expr));
11655 break;
11656 case OACC_KERNELS:
11657 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_KERNELS,
11658 OMP_CLAUSES (expr));
11659 break;
11660 case OACC_HOST_DATA:
11661 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_HOST_DATA,
11662 OMP_CLAUSES (expr));
11663 break;
11664 case OACC_PARALLEL:
11665 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_PARALLEL,
11666 OMP_CLAUSES (expr));
11667 break;
11668 case OMP_SECTIONS:
11669 stmt = gimple_build_omp_sections (body, OMP_CLAUSES (expr));
11670 break;
11671 case OMP_SINGLE:
11672 stmt = gimple_build_omp_single (body, OMP_CLAUSES (expr));
11673 break;
11674 case OMP_TARGET:
11675 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_REGION,
11676 OMP_CLAUSES (expr));
11677 break;
11678 case OMP_TARGET_DATA:
11679 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_DATA,
11680 OMP_CLAUSES (expr));
11681 break;
11682 case OMP_TEAMS:
11683 stmt = gimple_build_omp_teams (body, OMP_CLAUSES (expr));
11684 if ((ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
11685 gimple_omp_teams_set_host (as_a <gomp_teams *> (stmt), true);
11686 break;
11687 default:
11688 gcc_unreachable ();
11691 gimplify_seq_add_stmt (pre_p, stmt);
11692 *expr_p = NULL_TREE;
11695 /* Gimplify the gross structure of OpenACC enter/exit data, update, and OpenMP
11696 target update constructs. */
11698 static void
11699 gimplify_omp_target_update (tree *expr_p, gimple_seq *pre_p)
11701 tree expr = *expr_p;
11702 int kind;
11703 gomp_target *stmt;
11704 enum omp_region_type ort = ORT_WORKSHARE;
11706 switch (TREE_CODE (expr))
11708 case OACC_ENTER_DATA:
11709 case OACC_EXIT_DATA:
11710 kind = GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA;
11711 ort = ORT_ACC;
11712 break;
11713 case OACC_UPDATE:
11714 kind = GF_OMP_TARGET_KIND_OACC_UPDATE;
11715 ort = ORT_ACC;
11716 break;
11717 case OMP_TARGET_UPDATE:
11718 kind = GF_OMP_TARGET_KIND_UPDATE;
11719 break;
11720 case OMP_TARGET_ENTER_DATA:
11721 kind = GF_OMP_TARGET_KIND_ENTER_DATA;
11722 break;
11723 case OMP_TARGET_EXIT_DATA:
11724 kind = GF_OMP_TARGET_KIND_EXIT_DATA;
11725 break;
11726 default:
11727 gcc_unreachable ();
11729 gimplify_scan_omp_clauses (&OMP_STANDALONE_CLAUSES (expr), pre_p,
11730 ort, TREE_CODE (expr));
11731 gimplify_adjust_omp_clauses (pre_p, NULL, &OMP_STANDALONE_CLAUSES (expr),
11732 TREE_CODE (expr));
11733 if (TREE_CODE (expr) == OACC_UPDATE
11734 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
11735 OMP_CLAUSE_IF_PRESENT))
11737 /* The runtime uses GOMP_MAP_{TO,FROM} to denote the if_present
11738 clause. */
11739 for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
11740 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
11741 switch (OMP_CLAUSE_MAP_KIND (c))
11743 case GOMP_MAP_FORCE_TO:
11744 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TO);
11745 break;
11746 case GOMP_MAP_FORCE_FROM:
11747 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FROM);
11748 break;
11749 default:
11750 break;
11753 else if (TREE_CODE (expr) == OACC_EXIT_DATA
11754 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
11755 OMP_CLAUSE_FINALIZE))
11757 /* Use GOMP_MAP_DELETE/GOMP_MAP_FORCE_FROM to denote that "finalize"
11758 semantics apply to all mappings of this OpenACC directive. */
11759 bool finalize_marked = false;
11760 for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
11761 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
11762 switch (OMP_CLAUSE_MAP_KIND (c))
11764 case GOMP_MAP_FROM:
11765 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_FROM);
11766 finalize_marked = true;
11767 break;
11768 case GOMP_MAP_RELEASE:
11769 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_DELETE);
11770 finalize_marked = true;
11771 break;
11772 default:
11773 /* Check consistency: libgomp relies on the very first data
11774 mapping clause being marked, so make sure we did that before
11775 any other mapping clauses. */
11776 gcc_assert (finalize_marked);
11777 break;
11780 stmt = gimple_build_omp_target (NULL, kind, OMP_STANDALONE_CLAUSES (expr));
11782 gimplify_seq_add_stmt (pre_p, stmt);
11783 *expr_p = NULL_TREE;
11786 /* A subroutine of gimplify_omp_atomic. The front end is supposed to have
11787 stabilized the lhs of the atomic operation as *ADDR. Return true if
11788 EXPR is this stabilized form. */
11790 static bool
11791 goa_lhs_expr_p (tree expr, tree addr)
11793 /* Also include casts to other type variants. The C front end is fond
11794 of adding these for e.g. volatile variables. This is like
11795 STRIP_TYPE_NOPS but includes the main variant lookup. */
11796 STRIP_USELESS_TYPE_CONVERSION (expr);
11798 if (TREE_CODE (expr) == INDIRECT_REF)
11800 expr = TREE_OPERAND (expr, 0);
11801 while (expr != addr
11802 && (CONVERT_EXPR_P (expr)
11803 || TREE_CODE (expr) == NON_LVALUE_EXPR)
11804 && TREE_CODE (expr) == TREE_CODE (addr)
11805 && types_compatible_p (TREE_TYPE (expr), TREE_TYPE (addr)))
11807 expr = TREE_OPERAND (expr, 0);
11808 addr = TREE_OPERAND (addr, 0);
11810 if (expr == addr)
11811 return true;
11812 return (TREE_CODE (addr) == ADDR_EXPR
11813 && TREE_CODE (expr) == ADDR_EXPR
11814 && TREE_OPERAND (addr, 0) == TREE_OPERAND (expr, 0));
11816 if (TREE_CODE (addr) == ADDR_EXPR && expr == TREE_OPERAND (addr, 0))
11817 return true;
11818 return false;
11821 /* Walk *EXPR_P and replace appearances of *LHS_ADDR with LHS_VAR. If an
11822 expression does not involve the lhs, evaluate it into a temporary.
11823 Return 1 if the lhs appeared as a subexpression, 0 if it did not,
11824 or -1 if an error was encountered. */
11826 static int
11827 goa_stabilize_expr (tree *expr_p, gimple_seq *pre_p, tree lhs_addr,
11828 tree lhs_var)
11830 tree expr = *expr_p;
11831 int saw_lhs;
11833 if (goa_lhs_expr_p (expr, lhs_addr))
11835 *expr_p = lhs_var;
11836 return 1;
11838 if (is_gimple_val (expr))
11839 return 0;
11841 saw_lhs = 0;
11842 switch (TREE_CODE_CLASS (TREE_CODE (expr)))
11844 case tcc_binary:
11845 case tcc_comparison:
11846 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p, lhs_addr,
11847 lhs_var);
11848 /* FALLTHRU */
11849 case tcc_unary:
11850 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p, lhs_addr,
11851 lhs_var);
11852 break;
11853 case tcc_expression:
11854 switch (TREE_CODE (expr))
11856 case TRUTH_ANDIF_EXPR:
11857 case TRUTH_ORIF_EXPR:
11858 case TRUTH_AND_EXPR:
11859 case TRUTH_OR_EXPR:
11860 case TRUTH_XOR_EXPR:
11861 case BIT_INSERT_EXPR:
11862 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
11863 lhs_addr, lhs_var);
11864 /* FALLTHRU */
11865 case TRUTH_NOT_EXPR:
11866 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
11867 lhs_addr, lhs_var);
11868 break;
11869 case COMPOUND_EXPR:
11870 /* Break out any preevaluations from cp_build_modify_expr. */
11871 for (; TREE_CODE (expr) == COMPOUND_EXPR;
11872 expr = TREE_OPERAND (expr, 1))
11873 gimplify_stmt (&TREE_OPERAND (expr, 0), pre_p);
11874 *expr_p = expr;
11875 return goa_stabilize_expr (expr_p, pre_p, lhs_addr, lhs_var);
11876 default:
11877 break;
11879 break;
11880 case tcc_reference:
11881 if (TREE_CODE (expr) == BIT_FIELD_REF)
11882 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
11883 lhs_addr, lhs_var);
11884 break;
11885 default:
11886 break;
11889 if (saw_lhs == 0)
11891 enum gimplify_status gs;
11892 gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_val, fb_rvalue);
11893 if (gs != GS_ALL_DONE)
11894 saw_lhs = -1;
11897 return saw_lhs;
11900 /* Gimplify an OMP_ATOMIC statement. */
11902 static enum gimplify_status
11903 gimplify_omp_atomic (tree *expr_p, gimple_seq *pre_p)
11905 tree addr = TREE_OPERAND (*expr_p, 0);
11906 tree rhs = TREE_CODE (*expr_p) == OMP_ATOMIC_READ
11907 ? NULL : TREE_OPERAND (*expr_p, 1);
11908 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
11909 tree tmp_load;
11910 gomp_atomic_load *loadstmt;
11911 gomp_atomic_store *storestmt;
11913 tmp_load = create_tmp_reg (type);
11914 if (rhs && goa_stabilize_expr (&rhs, pre_p, addr, tmp_load) < 0)
11915 return GS_ERROR;
11917 if (gimplify_expr (&addr, pre_p, NULL, is_gimple_val, fb_rvalue)
11918 != GS_ALL_DONE)
11919 return GS_ERROR;
11921 loadstmt = gimple_build_omp_atomic_load (tmp_load, addr,
11922 OMP_ATOMIC_MEMORY_ORDER (*expr_p));
11923 gimplify_seq_add_stmt (pre_p, loadstmt);
11924 if (rhs && gimplify_expr (&rhs, pre_p, NULL, is_gimple_val, fb_rvalue)
11925 != GS_ALL_DONE)
11926 return GS_ERROR;
11928 if (TREE_CODE (*expr_p) == OMP_ATOMIC_READ)
11929 rhs = tmp_load;
11930 storestmt
11931 = gimple_build_omp_atomic_store (rhs, OMP_ATOMIC_MEMORY_ORDER (*expr_p));
11932 gimplify_seq_add_stmt (pre_p, storestmt);
11933 switch (TREE_CODE (*expr_p))
11935 case OMP_ATOMIC_READ:
11936 case OMP_ATOMIC_CAPTURE_OLD:
11937 *expr_p = tmp_load;
11938 gimple_omp_atomic_set_need_value (loadstmt);
11939 break;
11940 case OMP_ATOMIC_CAPTURE_NEW:
11941 *expr_p = rhs;
11942 gimple_omp_atomic_set_need_value (storestmt);
11943 break;
11944 default:
11945 *expr_p = NULL;
11946 break;
11949 return GS_ALL_DONE;
11952 /* Gimplify a TRANSACTION_EXPR. This involves gimplification of the
11953 body, and adding some EH bits. */
11955 static enum gimplify_status
11956 gimplify_transaction (tree *expr_p, gimple_seq *pre_p)
11958 tree expr = *expr_p, temp, tbody = TRANSACTION_EXPR_BODY (expr);
11959 gimple *body_stmt;
11960 gtransaction *trans_stmt;
11961 gimple_seq body = NULL;
11962 int subcode = 0;
11964 /* Wrap the transaction body in a BIND_EXPR so we have a context
11965 where to put decls for OMP. */
11966 if (TREE_CODE (tbody) != BIND_EXPR)
11968 tree bind = build3 (BIND_EXPR, void_type_node, NULL, tbody, NULL);
11969 TREE_SIDE_EFFECTS (bind) = 1;
11970 SET_EXPR_LOCATION (bind, EXPR_LOCATION (tbody));
11971 TRANSACTION_EXPR_BODY (expr) = bind;
11974 push_gimplify_context ();
11975 temp = voidify_wrapper_expr (*expr_p, NULL);
11977 body_stmt = gimplify_and_return_first (TRANSACTION_EXPR_BODY (expr), &body);
11978 pop_gimplify_context (body_stmt);
11980 trans_stmt = gimple_build_transaction (body);
11981 if (TRANSACTION_EXPR_OUTER (expr))
11982 subcode = GTMA_IS_OUTER;
11983 else if (TRANSACTION_EXPR_RELAXED (expr))
11984 subcode = GTMA_IS_RELAXED;
11985 gimple_transaction_set_subcode (trans_stmt, subcode);
11987 gimplify_seq_add_stmt (pre_p, trans_stmt);
11989 if (temp)
11991 *expr_p = temp;
11992 return GS_OK;
11995 *expr_p = NULL_TREE;
11996 return GS_ALL_DONE;
11999 /* Gimplify an OMP_ORDERED construct. EXPR is the tree version. BODY
12000 is the OMP_BODY of the original EXPR (which has already been
12001 gimplified so it's not present in the EXPR).
12003 Return the gimplified GIMPLE_OMP_ORDERED tuple. */
12005 static gimple *
12006 gimplify_omp_ordered (tree expr, gimple_seq body)
12008 tree c, decls;
12009 int failures = 0;
12010 unsigned int i;
12011 tree source_c = NULL_TREE;
12012 tree sink_c = NULL_TREE;
12014 if (gimplify_omp_ctxp)
12016 for (c = OMP_ORDERED_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
12017 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
12018 && gimplify_omp_ctxp->loop_iter_var.is_empty ()
12019 && (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK
12020 || OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE))
12022 error_at (OMP_CLAUSE_LOCATION (c),
12023 "%<ordered%> construct with %<depend%> clause must be "
12024 "closely nested inside a loop with %<ordered%> clause "
12025 "with a parameter");
12026 failures++;
12028 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
12029 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
12031 bool fail = false;
12032 for (decls = OMP_CLAUSE_DECL (c), i = 0;
12033 decls && TREE_CODE (decls) == TREE_LIST;
12034 decls = TREE_CHAIN (decls), ++i)
12035 if (i >= gimplify_omp_ctxp->loop_iter_var.length () / 2)
12036 continue;
12037 else if (TREE_VALUE (decls)
12038 != gimplify_omp_ctxp->loop_iter_var[2 * i])
12040 error_at (OMP_CLAUSE_LOCATION (c),
12041 "variable %qE is not an iteration "
12042 "of outermost loop %d, expected %qE",
12043 TREE_VALUE (decls), i + 1,
12044 gimplify_omp_ctxp->loop_iter_var[2 * i]);
12045 fail = true;
12046 failures++;
12048 else
12049 TREE_VALUE (decls)
12050 = gimplify_omp_ctxp->loop_iter_var[2 * i + 1];
12051 if (!fail && i != gimplify_omp_ctxp->loop_iter_var.length () / 2)
12053 error_at (OMP_CLAUSE_LOCATION (c),
12054 "number of variables in %<depend(sink)%> "
12055 "clause does not match number of "
12056 "iteration variables");
12057 failures++;
12059 sink_c = c;
12061 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
12062 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
12064 if (source_c)
12066 error_at (OMP_CLAUSE_LOCATION (c),
12067 "more than one %<depend(source)%> clause on an "
12068 "%<ordered%> construct");
12069 failures++;
12071 else
12072 source_c = c;
12075 if (source_c && sink_c)
12077 error_at (OMP_CLAUSE_LOCATION (source_c),
12078 "%<depend(source)%> clause specified together with "
12079 "%<depend(sink:)%> clauses on the same construct");
12080 failures++;
12083 if (failures)
12084 return gimple_build_nop ();
12085 return gimple_build_omp_ordered (body, OMP_ORDERED_CLAUSES (expr));
12088 /* Convert the GENERIC expression tree *EXPR_P to GIMPLE. If the
12089 expression produces a value to be used as an operand inside a GIMPLE
12090 statement, the value will be stored back in *EXPR_P. This value will
12091 be a tree of class tcc_declaration, tcc_constant, tcc_reference or
12092 an SSA_NAME. The corresponding sequence of GIMPLE statements is
12093 emitted in PRE_P and POST_P.
12095 Additionally, this process may overwrite parts of the input
12096 expression during gimplification. Ideally, it should be
12097 possible to do non-destructive gimplification.
12099 EXPR_P points to the GENERIC expression to convert to GIMPLE. If
12100 the expression needs to evaluate to a value to be used as
12101 an operand in a GIMPLE statement, this value will be stored in
12102 *EXPR_P on exit. This happens when the caller specifies one
12103 of fb_lvalue or fb_rvalue fallback flags.
12105 PRE_P will contain the sequence of GIMPLE statements corresponding
12106 to the evaluation of EXPR and all the side-effects that must
12107 be executed before the main expression. On exit, the last
12108 statement of PRE_P is the core statement being gimplified. For
12109 instance, when gimplifying 'if (++a)' the last statement in
12110 PRE_P will be 'if (t.1)' where t.1 is the result of
12111 pre-incrementing 'a'.
12113 POST_P will contain the sequence of GIMPLE statements corresponding
12114 to the evaluation of all the side-effects that must be executed
12115 after the main expression. If this is NULL, the post
12116 side-effects are stored at the end of PRE_P.
12118 The reason why the output is split in two is to handle post
12119 side-effects explicitly. In some cases, an expression may have
12120 inner and outer post side-effects which need to be emitted in
12121 an order different from the one given by the recursive
12122 traversal. For instance, for the expression (*p--)++ the post
12123 side-effects of '--' must actually occur *after* the post
12124 side-effects of '++'. However, gimplification will first visit
12125 the inner expression, so if a separate POST sequence was not
12126 used, the resulting sequence would be:
12128 1 t.1 = *p
12129 2 p = p - 1
12130 3 t.2 = t.1 + 1
12131 4 *p = t.2
12133 However, the post-decrement operation in line #2 must not be
12134 evaluated until after the store to *p at line #4, so the
12135 correct sequence should be:
12137 1 t.1 = *p
12138 2 t.2 = t.1 + 1
12139 3 *p = t.2
12140 4 p = p - 1
12142 So, by specifying a separate post queue, it is possible
12143 to emit the post side-effects in the correct order.
12144 If POST_P is NULL, an internal queue will be used. Before
12145 returning to the caller, the sequence POST_P is appended to
12146 the main output sequence PRE_P.
12148 GIMPLE_TEST_F points to a function that takes a tree T and
12149 returns nonzero if T is in the GIMPLE form requested by the
12150 caller. The GIMPLE predicates are in gimple.c.
12152 FALLBACK tells the function what sort of a temporary we want if
12153 gimplification cannot produce an expression that complies with
12154 GIMPLE_TEST_F.
12156 fb_none means that no temporary should be generated
12157 fb_rvalue means that an rvalue is OK to generate
12158 fb_lvalue means that an lvalue is OK to generate
12159 fb_either means that either is OK, but an lvalue is preferable.
12160 fb_mayfail means that gimplification may fail (in which case
12161 GS_ERROR will be returned)
12163 The return value is either GS_ERROR or GS_ALL_DONE, since this
12164 function iterates until EXPR is completely gimplified or an error
12165 occurs. */
12167 enum gimplify_status
12168 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
12169 bool (*gimple_test_f) (tree), fallback_t fallback)
12171 tree tmp;
12172 gimple_seq internal_pre = NULL;
12173 gimple_seq internal_post = NULL;
12174 tree save_expr;
12175 bool is_statement;
12176 location_t saved_location;
12177 enum gimplify_status ret;
12178 gimple_stmt_iterator pre_last_gsi, post_last_gsi;
12179 tree label;
12181 save_expr = *expr_p;
12182 if (save_expr == NULL_TREE)
12183 return GS_ALL_DONE;
12185 /* If we are gimplifying a top-level statement, PRE_P must be valid. */
12186 is_statement = gimple_test_f == is_gimple_stmt;
12187 if (is_statement)
12188 gcc_assert (pre_p);
12190 /* Consistency checks. */
12191 if (gimple_test_f == is_gimple_reg)
12192 gcc_assert (fallback & (fb_rvalue | fb_lvalue));
12193 else if (gimple_test_f == is_gimple_val
12194 || gimple_test_f == is_gimple_call_addr
12195 || gimple_test_f == is_gimple_condexpr
12196 || gimple_test_f == is_gimple_mem_rhs
12197 || gimple_test_f == is_gimple_mem_rhs_or_call
12198 || gimple_test_f == is_gimple_reg_rhs
12199 || gimple_test_f == is_gimple_reg_rhs_or_call
12200 || gimple_test_f == is_gimple_asm_val
12201 || gimple_test_f == is_gimple_mem_ref_addr)
12202 gcc_assert (fallback & fb_rvalue);
12203 else if (gimple_test_f == is_gimple_min_lval
12204 || gimple_test_f == is_gimple_lvalue)
12205 gcc_assert (fallback & fb_lvalue);
12206 else if (gimple_test_f == is_gimple_addressable)
12207 gcc_assert (fallback & fb_either);
12208 else if (gimple_test_f == is_gimple_stmt)
12209 gcc_assert (fallback == fb_none);
12210 else
12212 /* We should have recognized the GIMPLE_TEST_F predicate to
12213 know what kind of fallback to use in case a temporary is
12214 needed to hold the value or address of *EXPR_P. */
12215 gcc_unreachable ();
12218 /* We used to check the predicate here and return immediately if it
12219 succeeds. This is wrong; the design is for gimplification to be
12220 idempotent, and for the predicates to only test for valid forms, not
12221 whether they are fully simplified. */
12222 if (pre_p == NULL)
12223 pre_p = &internal_pre;
12225 if (post_p == NULL)
12226 post_p = &internal_post;
12228 /* Remember the last statements added to PRE_P and POST_P. Every
12229 new statement added by the gimplification helpers needs to be
12230 annotated with location information. To centralize the
12231 responsibility, we remember the last statement that had been
12232 added to both queues before gimplifying *EXPR_P. If
12233 gimplification produces new statements in PRE_P and POST_P, those
12234 statements will be annotated with the same location information
12235 as *EXPR_P. */
12236 pre_last_gsi = gsi_last (*pre_p);
12237 post_last_gsi = gsi_last (*post_p);
12239 saved_location = input_location;
12240 if (save_expr != error_mark_node
12241 && EXPR_HAS_LOCATION (*expr_p))
12242 input_location = EXPR_LOCATION (*expr_p);
12244 /* Loop over the specific gimplifiers until the toplevel node
12245 remains the same. */
12248 /* Strip away as many useless type conversions as possible
12249 at the toplevel. */
12250 STRIP_USELESS_TYPE_CONVERSION (*expr_p);
12252 /* Remember the expr. */
12253 save_expr = *expr_p;
12255 /* Die, die, die, my darling. */
12256 if (error_operand_p (save_expr))
12258 ret = GS_ERROR;
12259 break;
12262 /* Do any language-specific gimplification. */
12263 ret = ((enum gimplify_status)
12264 lang_hooks.gimplify_expr (expr_p, pre_p, post_p));
12265 if (ret == GS_OK)
12267 if (*expr_p == NULL_TREE)
12268 break;
12269 if (*expr_p != save_expr)
12270 continue;
12272 else if (ret != GS_UNHANDLED)
12273 break;
12275 /* Make sure that all the cases set 'ret' appropriately. */
12276 ret = GS_UNHANDLED;
12277 switch (TREE_CODE (*expr_p))
12279 /* First deal with the special cases. */
12281 case POSTINCREMENT_EXPR:
12282 case POSTDECREMENT_EXPR:
12283 case PREINCREMENT_EXPR:
12284 case PREDECREMENT_EXPR:
12285 ret = gimplify_self_mod_expr (expr_p, pre_p, post_p,
12286 fallback != fb_none,
12287 TREE_TYPE (*expr_p));
12288 break;
12290 case VIEW_CONVERT_EXPR:
12291 if (is_gimple_reg_type (TREE_TYPE (*expr_p))
12292 && is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0))))
12294 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
12295 post_p, is_gimple_val, fb_rvalue);
12296 recalculate_side_effects (*expr_p);
12297 break;
12299 /* Fallthru. */
12301 case ARRAY_REF:
12302 case ARRAY_RANGE_REF:
12303 case REALPART_EXPR:
12304 case IMAGPART_EXPR:
12305 case COMPONENT_REF:
12306 ret = gimplify_compound_lval (expr_p, pre_p, post_p,
12307 fallback ? fallback : fb_rvalue);
12308 break;
12310 case COND_EXPR:
12311 ret = gimplify_cond_expr (expr_p, pre_p, fallback);
12313 /* C99 code may assign to an array in a structure value of a
12314 conditional expression, and this has undefined behavior
12315 only on execution, so create a temporary if an lvalue is
12316 required. */
12317 if (fallback == fb_lvalue)
12319 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
12320 mark_addressable (*expr_p);
12321 ret = GS_OK;
12323 break;
12325 case CALL_EXPR:
12326 ret = gimplify_call_expr (expr_p, pre_p, fallback != fb_none);
12328 /* C99 code may assign to an array in a structure returned
12329 from a function, and this has undefined behavior only on
12330 execution, so create a temporary if an lvalue is
12331 required. */
12332 if (fallback == fb_lvalue)
12334 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
12335 mark_addressable (*expr_p);
12336 ret = GS_OK;
12338 break;
12340 case TREE_LIST:
12341 gcc_unreachable ();
12343 case COMPOUND_EXPR:
12344 ret = gimplify_compound_expr (expr_p, pre_p, fallback != fb_none);
12345 break;
12347 case COMPOUND_LITERAL_EXPR:
12348 ret = gimplify_compound_literal_expr (expr_p, pre_p,
12349 gimple_test_f, fallback);
12350 break;
12352 case MODIFY_EXPR:
12353 case INIT_EXPR:
12354 ret = gimplify_modify_expr (expr_p, pre_p, post_p,
12355 fallback != fb_none);
12356 break;
12358 case TRUTH_ANDIF_EXPR:
12359 case TRUTH_ORIF_EXPR:
12361 /* Preserve the original type of the expression and the
12362 source location of the outer expression. */
12363 tree org_type = TREE_TYPE (*expr_p);
12364 *expr_p = gimple_boolify (*expr_p);
12365 *expr_p = build3_loc (input_location, COND_EXPR,
12366 org_type, *expr_p,
12367 fold_convert_loc
12368 (input_location,
12369 org_type, boolean_true_node),
12370 fold_convert_loc
12371 (input_location,
12372 org_type, boolean_false_node));
12373 ret = GS_OK;
12374 break;
12377 case TRUTH_NOT_EXPR:
12379 tree type = TREE_TYPE (*expr_p);
12380 /* The parsers are careful to generate TRUTH_NOT_EXPR
12381 only with operands that are always zero or one.
12382 We do not fold here but handle the only interesting case
12383 manually, as fold may re-introduce the TRUTH_NOT_EXPR. */
12384 *expr_p = gimple_boolify (*expr_p);
12385 if (TYPE_PRECISION (TREE_TYPE (*expr_p)) == 1)
12386 *expr_p = build1_loc (input_location, BIT_NOT_EXPR,
12387 TREE_TYPE (*expr_p),
12388 TREE_OPERAND (*expr_p, 0));
12389 else
12390 *expr_p = build2_loc (input_location, BIT_XOR_EXPR,
12391 TREE_TYPE (*expr_p),
12392 TREE_OPERAND (*expr_p, 0),
12393 build_int_cst (TREE_TYPE (*expr_p), 1));
12394 if (!useless_type_conversion_p (type, TREE_TYPE (*expr_p)))
12395 *expr_p = fold_convert_loc (input_location, type, *expr_p);
12396 ret = GS_OK;
12397 break;
12400 case ADDR_EXPR:
12401 ret = gimplify_addr_expr (expr_p, pre_p, post_p);
12402 break;
12404 case ANNOTATE_EXPR:
12406 tree cond = TREE_OPERAND (*expr_p, 0);
12407 tree kind = TREE_OPERAND (*expr_p, 1);
12408 tree data = TREE_OPERAND (*expr_p, 2);
12409 tree type = TREE_TYPE (cond);
12410 if (!INTEGRAL_TYPE_P (type))
12412 *expr_p = cond;
12413 ret = GS_OK;
12414 break;
12416 tree tmp = create_tmp_var (type);
12417 gimplify_arg (&cond, pre_p, EXPR_LOCATION (*expr_p));
12418 gcall *call
12419 = gimple_build_call_internal (IFN_ANNOTATE, 3, cond, kind, data);
12420 gimple_call_set_lhs (call, tmp);
12421 gimplify_seq_add_stmt (pre_p, call);
12422 *expr_p = tmp;
12423 ret = GS_ALL_DONE;
12424 break;
12427 case VA_ARG_EXPR:
12428 ret = gimplify_va_arg_expr (expr_p, pre_p, post_p);
12429 break;
12431 CASE_CONVERT:
12432 if (IS_EMPTY_STMT (*expr_p))
12434 ret = GS_ALL_DONE;
12435 break;
12438 if (VOID_TYPE_P (TREE_TYPE (*expr_p))
12439 || fallback == fb_none)
12441 /* Just strip a conversion to void (or in void context) and
12442 try again. */
12443 *expr_p = TREE_OPERAND (*expr_p, 0);
12444 ret = GS_OK;
12445 break;
12448 ret = gimplify_conversion (expr_p);
12449 if (ret == GS_ERROR)
12450 break;
12451 if (*expr_p != save_expr)
12452 break;
12453 /* FALLTHRU */
12455 case FIX_TRUNC_EXPR:
12456 /* unary_expr: ... | '(' cast ')' val | ... */
12457 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
12458 is_gimple_val, fb_rvalue);
12459 recalculate_side_effects (*expr_p);
12460 break;
12462 case INDIRECT_REF:
12464 bool volatilep = TREE_THIS_VOLATILE (*expr_p);
12465 bool notrap = TREE_THIS_NOTRAP (*expr_p);
12466 tree saved_ptr_type = TREE_TYPE (TREE_OPERAND (*expr_p, 0));
12468 *expr_p = fold_indirect_ref_loc (input_location, *expr_p);
12469 if (*expr_p != save_expr)
12471 ret = GS_OK;
12472 break;
12475 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
12476 is_gimple_reg, fb_rvalue);
12477 if (ret == GS_ERROR)
12478 break;
12480 recalculate_side_effects (*expr_p);
12481 *expr_p = fold_build2_loc (input_location, MEM_REF,
12482 TREE_TYPE (*expr_p),
12483 TREE_OPERAND (*expr_p, 0),
12484 build_int_cst (saved_ptr_type, 0));
12485 TREE_THIS_VOLATILE (*expr_p) = volatilep;
12486 TREE_THIS_NOTRAP (*expr_p) = notrap;
12487 ret = GS_OK;
12488 break;
12491 /* We arrive here through the various re-gimplifcation paths. */
12492 case MEM_REF:
12493 /* First try re-folding the whole thing. */
12494 tmp = fold_binary (MEM_REF, TREE_TYPE (*expr_p),
12495 TREE_OPERAND (*expr_p, 0),
12496 TREE_OPERAND (*expr_p, 1));
12497 if (tmp)
12499 REF_REVERSE_STORAGE_ORDER (tmp)
12500 = REF_REVERSE_STORAGE_ORDER (*expr_p);
12501 *expr_p = tmp;
12502 recalculate_side_effects (*expr_p);
12503 ret = GS_OK;
12504 break;
12506 /* Avoid re-gimplifying the address operand if it is already
12507 in suitable form. Re-gimplifying would mark the address
12508 operand addressable. Always gimplify when not in SSA form
12509 as we still may have to gimplify decls with value-exprs. */
12510 if (!gimplify_ctxp || !gimple_in_ssa_p (cfun)
12511 || !is_gimple_mem_ref_addr (TREE_OPERAND (*expr_p, 0)))
12513 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
12514 is_gimple_mem_ref_addr, fb_rvalue);
12515 if (ret == GS_ERROR)
12516 break;
12518 recalculate_side_effects (*expr_p);
12519 ret = GS_ALL_DONE;
12520 break;
12522 /* Constants need not be gimplified. */
12523 case INTEGER_CST:
12524 case REAL_CST:
12525 case FIXED_CST:
12526 case STRING_CST:
12527 case COMPLEX_CST:
12528 case VECTOR_CST:
12529 /* Drop the overflow flag on constants, we do not want
12530 that in the GIMPLE IL. */
12531 if (TREE_OVERFLOW_P (*expr_p))
12532 *expr_p = drop_tree_overflow (*expr_p);
12533 ret = GS_ALL_DONE;
12534 break;
12536 case CONST_DECL:
12537 /* If we require an lvalue, such as for ADDR_EXPR, retain the
12538 CONST_DECL node. Otherwise the decl is replaceable by its
12539 value. */
12540 /* ??? Should be == fb_lvalue, but ADDR_EXPR passes fb_either. */
12541 if (fallback & fb_lvalue)
12542 ret = GS_ALL_DONE;
12543 else
12545 *expr_p = DECL_INITIAL (*expr_p);
12546 ret = GS_OK;
12548 break;
12550 case DECL_EXPR:
12551 ret = gimplify_decl_expr (expr_p, pre_p);
12552 break;
12554 case BIND_EXPR:
12555 ret = gimplify_bind_expr (expr_p, pre_p);
12556 break;
12558 case LOOP_EXPR:
12559 ret = gimplify_loop_expr (expr_p, pre_p);
12560 break;
12562 case SWITCH_EXPR:
12563 ret = gimplify_switch_expr (expr_p, pre_p);
12564 break;
12566 case EXIT_EXPR:
12567 ret = gimplify_exit_expr (expr_p);
12568 break;
12570 case GOTO_EXPR:
12571 /* If the target is not LABEL, then it is a computed jump
12572 and the target needs to be gimplified. */
12573 if (TREE_CODE (GOTO_DESTINATION (*expr_p)) != LABEL_DECL)
12575 ret = gimplify_expr (&GOTO_DESTINATION (*expr_p), pre_p,
12576 NULL, is_gimple_val, fb_rvalue);
12577 if (ret == GS_ERROR)
12578 break;
12580 gimplify_seq_add_stmt (pre_p,
12581 gimple_build_goto (GOTO_DESTINATION (*expr_p)));
12582 ret = GS_ALL_DONE;
12583 break;
12585 case PREDICT_EXPR:
12586 gimplify_seq_add_stmt (pre_p,
12587 gimple_build_predict (PREDICT_EXPR_PREDICTOR (*expr_p),
12588 PREDICT_EXPR_OUTCOME (*expr_p)));
12589 ret = GS_ALL_DONE;
12590 break;
12592 case LABEL_EXPR:
12593 ret = gimplify_label_expr (expr_p, pre_p);
12594 label = LABEL_EXPR_LABEL (*expr_p);
12595 gcc_assert (decl_function_context (label) == current_function_decl);
12597 /* If the label is used in a goto statement, or address of the label
12598 is taken, we need to unpoison all variables that were seen so far.
12599 Doing so would prevent us from reporting a false positives. */
12600 if (asan_poisoned_variables
12601 && asan_used_labels != NULL
12602 && asan_used_labels->contains (label))
12603 asan_poison_variables (asan_poisoned_variables, false, pre_p);
12604 break;
12606 case CASE_LABEL_EXPR:
12607 ret = gimplify_case_label_expr (expr_p, pre_p);
12609 if (gimplify_ctxp->live_switch_vars)
12610 asan_poison_variables (gimplify_ctxp->live_switch_vars, false,
12611 pre_p);
12612 break;
12614 case RETURN_EXPR:
12615 ret = gimplify_return_expr (*expr_p, pre_p);
12616 break;
12618 case CONSTRUCTOR:
12619 /* Don't reduce this in place; let gimplify_init_constructor work its
12620 magic. Buf if we're just elaborating this for side effects, just
12621 gimplify any element that has side-effects. */
12622 if (fallback == fb_none)
12624 unsigned HOST_WIDE_INT ix;
12625 tree val;
12626 tree temp = NULL_TREE;
12627 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (*expr_p), ix, val)
12628 if (TREE_SIDE_EFFECTS (val))
12629 append_to_statement_list (val, &temp);
12631 *expr_p = temp;
12632 ret = temp ? GS_OK : GS_ALL_DONE;
12634 /* C99 code may assign to an array in a constructed
12635 structure or union, and this has undefined behavior only
12636 on execution, so create a temporary if an lvalue is
12637 required. */
12638 else if (fallback == fb_lvalue)
12640 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
12641 mark_addressable (*expr_p);
12642 ret = GS_OK;
12644 else
12645 ret = GS_ALL_DONE;
12646 break;
12648 /* The following are special cases that are not handled by the
12649 original GIMPLE grammar. */
12651 /* SAVE_EXPR nodes are converted into a GIMPLE identifier and
12652 eliminated. */
12653 case SAVE_EXPR:
12654 ret = gimplify_save_expr (expr_p, pre_p, post_p);
12655 break;
12657 case BIT_FIELD_REF:
12658 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
12659 post_p, is_gimple_lvalue, fb_either);
12660 recalculate_side_effects (*expr_p);
12661 break;
12663 case TARGET_MEM_REF:
12665 enum gimplify_status r0 = GS_ALL_DONE, r1 = GS_ALL_DONE;
12667 if (TMR_BASE (*expr_p))
12668 r0 = gimplify_expr (&TMR_BASE (*expr_p), pre_p,
12669 post_p, is_gimple_mem_ref_addr, fb_either);
12670 if (TMR_INDEX (*expr_p))
12671 r1 = gimplify_expr (&TMR_INDEX (*expr_p), pre_p,
12672 post_p, is_gimple_val, fb_rvalue);
12673 if (TMR_INDEX2 (*expr_p))
12674 r1 = gimplify_expr (&TMR_INDEX2 (*expr_p), pre_p,
12675 post_p, is_gimple_val, fb_rvalue);
12676 /* TMR_STEP and TMR_OFFSET are always integer constants. */
12677 ret = MIN (r0, r1);
12679 break;
12681 case NON_LVALUE_EXPR:
12682 /* This should have been stripped above. */
12683 gcc_unreachable ();
12685 case ASM_EXPR:
12686 ret = gimplify_asm_expr (expr_p, pre_p, post_p);
12687 break;
12689 case TRY_FINALLY_EXPR:
12690 case TRY_CATCH_EXPR:
12692 gimple_seq eval, cleanup;
12693 gtry *try_;
12695 /* Calls to destructors are generated automatically in FINALLY/CATCH
12696 block. They should have location as UNKNOWN_LOCATION. However,
12697 gimplify_call_expr will reset these call stmts to input_location
12698 if it finds stmt's location is unknown. To prevent resetting for
12699 destructors, we set the input_location to unknown.
12700 Note that this only affects the destructor calls in FINALLY/CATCH
12701 block, and will automatically reset to its original value by the
12702 end of gimplify_expr. */
12703 input_location = UNKNOWN_LOCATION;
12704 eval = cleanup = NULL;
12705 gimplify_and_add (TREE_OPERAND (*expr_p, 0), &eval);
12706 gimplify_and_add (TREE_OPERAND (*expr_p, 1), &cleanup);
12707 /* Don't create bogus GIMPLE_TRY with empty cleanup. */
12708 if (gimple_seq_empty_p (cleanup))
12710 gimple_seq_add_seq (pre_p, eval);
12711 ret = GS_ALL_DONE;
12712 break;
12714 try_ = gimple_build_try (eval, cleanup,
12715 TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
12716 ? GIMPLE_TRY_FINALLY
12717 : GIMPLE_TRY_CATCH);
12718 if (EXPR_HAS_LOCATION (save_expr))
12719 gimple_set_location (try_, EXPR_LOCATION (save_expr));
12720 else if (LOCATION_LOCUS (saved_location) != UNKNOWN_LOCATION)
12721 gimple_set_location (try_, saved_location);
12722 if (TREE_CODE (*expr_p) == TRY_CATCH_EXPR)
12723 gimple_try_set_catch_is_cleanup (try_,
12724 TRY_CATCH_IS_CLEANUP (*expr_p));
12725 gimplify_seq_add_stmt (pre_p, try_);
12726 ret = GS_ALL_DONE;
12727 break;
12730 case CLEANUP_POINT_EXPR:
12731 ret = gimplify_cleanup_point_expr (expr_p, pre_p);
12732 break;
12734 case TARGET_EXPR:
12735 ret = gimplify_target_expr (expr_p, pre_p, post_p);
12736 break;
12738 case CATCH_EXPR:
12740 gimple *c;
12741 gimple_seq handler = NULL;
12742 gimplify_and_add (CATCH_BODY (*expr_p), &handler);
12743 c = gimple_build_catch (CATCH_TYPES (*expr_p), handler);
12744 gimplify_seq_add_stmt (pre_p, c);
12745 ret = GS_ALL_DONE;
12746 break;
12749 case EH_FILTER_EXPR:
12751 gimple *ehf;
12752 gimple_seq failure = NULL;
12754 gimplify_and_add (EH_FILTER_FAILURE (*expr_p), &failure);
12755 ehf = gimple_build_eh_filter (EH_FILTER_TYPES (*expr_p), failure);
12756 gimple_set_no_warning (ehf, TREE_NO_WARNING (*expr_p));
12757 gimplify_seq_add_stmt (pre_p, ehf);
12758 ret = GS_ALL_DONE;
12759 break;
12762 case OBJ_TYPE_REF:
12764 enum gimplify_status r0, r1;
12765 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p,
12766 post_p, is_gimple_val, fb_rvalue);
12767 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p,
12768 post_p, is_gimple_val, fb_rvalue);
12769 TREE_SIDE_EFFECTS (*expr_p) = 0;
12770 ret = MIN (r0, r1);
12772 break;
12774 case LABEL_DECL:
12775 /* We get here when taking the address of a label. We mark
12776 the label as "forced"; meaning it can never be removed and
12777 it is a potential target for any computed goto. */
12778 FORCED_LABEL (*expr_p) = 1;
12779 ret = GS_ALL_DONE;
12780 break;
12782 case STATEMENT_LIST:
12783 ret = gimplify_statement_list (expr_p, pre_p);
12784 break;
12786 case WITH_SIZE_EXPR:
12788 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
12789 post_p == &internal_post ? NULL : post_p,
12790 gimple_test_f, fallback);
12791 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
12792 is_gimple_val, fb_rvalue);
12793 ret = GS_ALL_DONE;
12795 break;
12797 case VAR_DECL:
12798 case PARM_DECL:
12799 ret = gimplify_var_or_parm_decl (expr_p);
12800 break;
12802 case RESULT_DECL:
12803 /* When within an OMP context, notice uses of variables. */
12804 if (gimplify_omp_ctxp)
12805 omp_notice_variable (gimplify_omp_ctxp, *expr_p, true);
12806 ret = GS_ALL_DONE;
12807 break;
12809 case DEBUG_EXPR_DECL:
12810 gcc_unreachable ();
12812 case DEBUG_BEGIN_STMT:
12813 gimplify_seq_add_stmt (pre_p,
12814 gimple_build_debug_begin_stmt
12815 (TREE_BLOCK (*expr_p),
12816 EXPR_LOCATION (*expr_p)));
12817 ret = GS_ALL_DONE;
12818 *expr_p = NULL;
12819 break;
12821 case SSA_NAME:
12822 /* Allow callbacks into the gimplifier during optimization. */
12823 ret = GS_ALL_DONE;
12824 break;
12826 case OMP_PARALLEL:
12827 gimplify_omp_parallel (expr_p, pre_p);
12828 ret = GS_ALL_DONE;
12829 break;
12831 case OMP_TASK:
12832 gimplify_omp_task (expr_p, pre_p);
12833 ret = GS_ALL_DONE;
12834 break;
12836 case OMP_FOR:
12837 case OMP_SIMD:
12838 case OMP_DISTRIBUTE:
12839 case OMP_TASKLOOP:
12840 case OACC_LOOP:
12841 ret = gimplify_omp_for (expr_p, pre_p);
12842 break;
12844 case OACC_CACHE:
12845 gimplify_oacc_cache (expr_p, pre_p);
12846 ret = GS_ALL_DONE;
12847 break;
12849 case OACC_DECLARE:
12850 gimplify_oacc_declare (expr_p, pre_p);
12851 ret = GS_ALL_DONE;
12852 break;
12854 case OACC_HOST_DATA:
12855 case OACC_DATA:
12856 case OACC_KERNELS:
12857 case OACC_PARALLEL:
12858 case OMP_SECTIONS:
12859 case OMP_SINGLE:
12860 case OMP_TARGET:
12861 case OMP_TARGET_DATA:
12862 case OMP_TEAMS:
12863 gimplify_omp_workshare (expr_p, pre_p);
12864 ret = GS_ALL_DONE;
12865 break;
12867 case OACC_ENTER_DATA:
12868 case OACC_EXIT_DATA:
12869 case OACC_UPDATE:
12870 case OMP_TARGET_UPDATE:
12871 case OMP_TARGET_ENTER_DATA:
12872 case OMP_TARGET_EXIT_DATA:
12873 gimplify_omp_target_update (expr_p, pre_p);
12874 ret = GS_ALL_DONE;
12875 break;
12877 case OMP_SECTION:
12878 case OMP_MASTER:
12879 case OMP_ORDERED:
12880 case OMP_CRITICAL:
12882 gimple_seq body = NULL;
12883 gimple *g;
12885 gimplify_and_add (OMP_BODY (*expr_p), &body);
12886 switch (TREE_CODE (*expr_p))
12888 case OMP_SECTION:
12889 g = gimple_build_omp_section (body);
12890 break;
12891 case OMP_MASTER:
12892 g = gimple_build_omp_master (body);
12893 break;
12894 case OMP_ORDERED:
12895 g = gimplify_omp_ordered (*expr_p, body);
12896 break;
12897 case OMP_CRITICAL:
12898 gimplify_scan_omp_clauses (&OMP_CRITICAL_CLAUSES (*expr_p),
12899 pre_p, ORT_WORKSHARE, OMP_CRITICAL);
12900 gimplify_adjust_omp_clauses (pre_p, body,
12901 &OMP_CRITICAL_CLAUSES (*expr_p),
12902 OMP_CRITICAL);
12903 g = gimple_build_omp_critical (body,
12904 OMP_CRITICAL_NAME (*expr_p),
12905 OMP_CRITICAL_CLAUSES (*expr_p));
12906 break;
12907 default:
12908 gcc_unreachable ();
12910 gimplify_seq_add_stmt (pre_p, g);
12911 ret = GS_ALL_DONE;
12912 break;
12915 case OMP_TASKGROUP:
12917 gimple_seq body = NULL;
12919 tree *pclauses = &OMP_TASKGROUP_CLAUSES (*expr_p);
12920 gimplify_scan_omp_clauses (pclauses, pre_p, ORT_TASKGROUP,
12921 OMP_TASKGROUP);
12922 gimplify_adjust_omp_clauses (pre_p, NULL, pclauses, OMP_TASKGROUP);
12923 gimplify_and_add (OMP_BODY (*expr_p), &body);
12924 gimple_seq cleanup = NULL;
12925 tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_END);
12926 gimple *g = gimple_build_call (fn, 0);
12927 gimple_seq_add_stmt (&cleanup, g);
12928 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
12929 body = NULL;
12930 gimple_seq_add_stmt (&body, g);
12931 g = gimple_build_omp_taskgroup (body, *pclauses);
12932 gimplify_seq_add_stmt (pre_p, g);
12933 ret = GS_ALL_DONE;
12934 break;
12937 case OMP_ATOMIC:
12938 case OMP_ATOMIC_READ:
12939 case OMP_ATOMIC_CAPTURE_OLD:
12940 case OMP_ATOMIC_CAPTURE_NEW:
12941 ret = gimplify_omp_atomic (expr_p, pre_p);
12942 break;
12944 case TRANSACTION_EXPR:
12945 ret = gimplify_transaction (expr_p, pre_p);
12946 break;
12948 case TRUTH_AND_EXPR:
12949 case TRUTH_OR_EXPR:
12950 case TRUTH_XOR_EXPR:
12952 tree orig_type = TREE_TYPE (*expr_p);
12953 tree new_type, xop0, xop1;
12954 *expr_p = gimple_boolify (*expr_p);
12955 new_type = TREE_TYPE (*expr_p);
12956 if (!useless_type_conversion_p (orig_type, new_type))
12958 *expr_p = fold_convert_loc (input_location, orig_type, *expr_p);
12959 ret = GS_OK;
12960 break;
12963 /* Boolified binary truth expressions are semantically equivalent
12964 to bitwise binary expressions. Canonicalize them to the
12965 bitwise variant. */
12966 switch (TREE_CODE (*expr_p))
12968 case TRUTH_AND_EXPR:
12969 TREE_SET_CODE (*expr_p, BIT_AND_EXPR);
12970 break;
12971 case TRUTH_OR_EXPR:
12972 TREE_SET_CODE (*expr_p, BIT_IOR_EXPR);
12973 break;
12974 case TRUTH_XOR_EXPR:
12975 TREE_SET_CODE (*expr_p, BIT_XOR_EXPR);
12976 break;
12977 default:
12978 break;
12980 /* Now make sure that operands have compatible type to
12981 expression's new_type. */
12982 xop0 = TREE_OPERAND (*expr_p, 0);
12983 xop1 = TREE_OPERAND (*expr_p, 1);
12984 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop0)))
12985 TREE_OPERAND (*expr_p, 0) = fold_convert_loc (input_location,
12986 new_type,
12987 xop0);
12988 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop1)))
12989 TREE_OPERAND (*expr_p, 1) = fold_convert_loc (input_location,
12990 new_type,
12991 xop1);
12992 /* Continue classified as tcc_binary. */
12993 goto expr_2;
12996 case VEC_COND_EXPR:
12998 enum gimplify_status r0, r1, r2;
13000 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
13001 post_p, is_gimple_condexpr, fb_rvalue);
13002 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
13003 post_p, is_gimple_val, fb_rvalue);
13004 r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p,
13005 post_p, is_gimple_val, fb_rvalue);
13007 ret = MIN (MIN (r0, r1), r2);
13008 recalculate_side_effects (*expr_p);
13010 break;
13012 case VEC_PERM_EXPR:
13013 /* Classified as tcc_expression. */
13014 goto expr_3;
13016 case BIT_INSERT_EXPR:
13017 /* Argument 3 is a constant. */
13018 goto expr_2;
13020 case POINTER_PLUS_EXPR:
13022 enum gimplify_status r0, r1;
13023 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
13024 post_p, is_gimple_val, fb_rvalue);
13025 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
13026 post_p, is_gimple_val, fb_rvalue);
13027 recalculate_side_effects (*expr_p);
13028 ret = MIN (r0, r1);
13029 break;
13032 default:
13033 switch (TREE_CODE_CLASS (TREE_CODE (*expr_p)))
13035 case tcc_comparison:
13036 /* Handle comparison of objects of non scalar mode aggregates
13037 with a call to memcmp. It would be nice to only have to do
13038 this for variable-sized objects, but then we'd have to allow
13039 the same nest of reference nodes we allow for MODIFY_EXPR and
13040 that's too complex.
13042 Compare scalar mode aggregates as scalar mode values. Using
13043 memcmp for them would be very inefficient at best, and is
13044 plain wrong if bitfields are involved. */
13046 tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 1));
13048 /* Vector comparisons need no boolification. */
13049 if (TREE_CODE (type) == VECTOR_TYPE)
13050 goto expr_2;
13051 else if (!AGGREGATE_TYPE_P (type))
13053 tree org_type = TREE_TYPE (*expr_p);
13054 *expr_p = gimple_boolify (*expr_p);
13055 if (!useless_type_conversion_p (org_type,
13056 TREE_TYPE (*expr_p)))
13058 *expr_p = fold_convert_loc (input_location,
13059 org_type, *expr_p);
13060 ret = GS_OK;
13062 else
13063 goto expr_2;
13065 else if (TYPE_MODE (type) != BLKmode)
13066 ret = gimplify_scalar_mode_aggregate_compare (expr_p);
13067 else
13068 ret = gimplify_variable_sized_compare (expr_p);
13070 break;
13073 /* If *EXPR_P does not need to be special-cased, handle it
13074 according to its class. */
13075 case tcc_unary:
13076 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
13077 post_p, is_gimple_val, fb_rvalue);
13078 break;
13080 case tcc_binary:
13081 expr_2:
13083 enum gimplify_status r0, r1;
13085 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
13086 post_p, is_gimple_val, fb_rvalue);
13087 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
13088 post_p, is_gimple_val, fb_rvalue);
13090 ret = MIN (r0, r1);
13091 break;
13094 expr_3:
13096 enum gimplify_status r0, r1, r2;
13098 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
13099 post_p, is_gimple_val, fb_rvalue);
13100 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
13101 post_p, is_gimple_val, fb_rvalue);
13102 r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p,
13103 post_p, is_gimple_val, fb_rvalue);
13105 ret = MIN (MIN (r0, r1), r2);
13106 break;
13109 case tcc_declaration:
13110 case tcc_constant:
13111 ret = GS_ALL_DONE;
13112 goto dont_recalculate;
13114 default:
13115 gcc_unreachable ();
13118 recalculate_side_effects (*expr_p);
13120 dont_recalculate:
13121 break;
13124 gcc_assert (*expr_p || ret != GS_OK);
13126 while (ret == GS_OK);
13128 /* If we encountered an error_mark somewhere nested inside, either
13129 stub out the statement or propagate the error back out. */
13130 if (ret == GS_ERROR)
13132 if (is_statement)
13133 *expr_p = NULL;
13134 goto out;
13137 /* This was only valid as a return value from the langhook, which
13138 we handled. Make sure it doesn't escape from any other context. */
13139 gcc_assert (ret != GS_UNHANDLED);
13141 if (fallback == fb_none && *expr_p && !is_gimple_stmt (*expr_p))
13143 /* We aren't looking for a value, and we don't have a valid
13144 statement. If it doesn't have side-effects, throw it away.
13145 We can also get here with code such as "*&&L;", where L is
13146 a LABEL_DECL that is marked as FORCED_LABEL. */
13147 if (TREE_CODE (*expr_p) == LABEL_DECL
13148 || !TREE_SIDE_EFFECTS (*expr_p))
13149 *expr_p = NULL;
13150 else if (!TREE_THIS_VOLATILE (*expr_p))
13152 /* This is probably a _REF that contains something nested that
13153 has side effects. Recurse through the operands to find it. */
13154 enum tree_code code = TREE_CODE (*expr_p);
13156 switch (code)
13158 case COMPONENT_REF:
13159 case REALPART_EXPR:
13160 case IMAGPART_EXPR:
13161 case VIEW_CONVERT_EXPR:
13162 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
13163 gimple_test_f, fallback);
13164 break;
13166 case ARRAY_REF:
13167 case ARRAY_RANGE_REF:
13168 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
13169 gimple_test_f, fallback);
13170 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
13171 gimple_test_f, fallback);
13172 break;
13174 default:
13175 /* Anything else with side-effects must be converted to
13176 a valid statement before we get here. */
13177 gcc_unreachable ();
13180 *expr_p = NULL;
13182 else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p))
13183 && TYPE_MODE (TREE_TYPE (*expr_p)) != BLKmode)
13185 /* Historically, the compiler has treated a bare reference
13186 to a non-BLKmode volatile lvalue as forcing a load. */
13187 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p));
13189 /* Normally, we do not want to create a temporary for a
13190 TREE_ADDRESSABLE type because such a type should not be
13191 copied by bitwise-assignment. However, we make an
13192 exception here, as all we are doing here is ensuring that
13193 we read the bytes that make up the type. We use
13194 create_tmp_var_raw because create_tmp_var will abort when
13195 given a TREE_ADDRESSABLE type. */
13196 tree tmp = create_tmp_var_raw (type, "vol");
13197 gimple_add_tmp_var (tmp);
13198 gimplify_assign (tmp, *expr_p, pre_p);
13199 *expr_p = NULL;
13201 else
13202 /* We can't do anything useful with a volatile reference to
13203 an incomplete type, so just throw it away. Likewise for
13204 a BLKmode type, since any implicit inner load should
13205 already have been turned into an explicit one by the
13206 gimplification process. */
13207 *expr_p = NULL;
13210 /* If we are gimplifying at the statement level, we're done. Tack
13211 everything together and return. */
13212 if (fallback == fb_none || is_statement)
13214 /* Since *EXPR_P has been converted into a GIMPLE tuple, clear
13215 it out for GC to reclaim it. */
13216 *expr_p = NULL_TREE;
13218 if (!gimple_seq_empty_p (internal_pre)
13219 || !gimple_seq_empty_p (internal_post))
13221 gimplify_seq_add_seq (&internal_pre, internal_post);
13222 gimplify_seq_add_seq (pre_p, internal_pre);
13225 /* The result of gimplifying *EXPR_P is going to be the last few
13226 statements in *PRE_P and *POST_P. Add location information
13227 to all the statements that were added by the gimplification
13228 helpers. */
13229 if (!gimple_seq_empty_p (*pre_p))
13230 annotate_all_with_location_after (*pre_p, pre_last_gsi, input_location);
13232 if (!gimple_seq_empty_p (*post_p))
13233 annotate_all_with_location_after (*post_p, post_last_gsi,
13234 input_location);
13236 goto out;
13239 #ifdef ENABLE_GIMPLE_CHECKING
13240 if (*expr_p)
13242 enum tree_code code = TREE_CODE (*expr_p);
13243 /* These expressions should already be in gimple IR form. */
13244 gcc_assert (code != MODIFY_EXPR
13245 && code != ASM_EXPR
13246 && code != BIND_EXPR
13247 && code != CATCH_EXPR
13248 && (code != COND_EXPR || gimplify_ctxp->allow_rhs_cond_expr)
13249 && code != EH_FILTER_EXPR
13250 && code != GOTO_EXPR
13251 && code != LABEL_EXPR
13252 && code != LOOP_EXPR
13253 && code != SWITCH_EXPR
13254 && code != TRY_FINALLY_EXPR
13255 && code != OACC_PARALLEL
13256 && code != OACC_KERNELS
13257 && code != OACC_DATA
13258 && code != OACC_HOST_DATA
13259 && code != OACC_DECLARE
13260 && code != OACC_UPDATE
13261 && code != OACC_ENTER_DATA
13262 && code != OACC_EXIT_DATA
13263 && code != OACC_CACHE
13264 && code != OMP_CRITICAL
13265 && code != OMP_FOR
13266 && code != OACC_LOOP
13267 && code != OMP_MASTER
13268 && code != OMP_TASKGROUP
13269 && code != OMP_ORDERED
13270 && code != OMP_PARALLEL
13271 && code != OMP_SECTIONS
13272 && code != OMP_SECTION
13273 && code != OMP_SINGLE);
13275 #endif
13277 /* Otherwise we're gimplifying a subexpression, so the resulting
13278 value is interesting. If it's a valid operand that matches
13279 GIMPLE_TEST_F, we're done. Unless we are handling some
13280 post-effects internally; if that's the case, we need to copy into
13281 a temporary before adding the post-effects to POST_P. */
13282 if (gimple_seq_empty_p (internal_post) && (*gimple_test_f) (*expr_p))
13283 goto out;
13285 /* Otherwise, we need to create a new temporary for the gimplified
13286 expression. */
13288 /* We can't return an lvalue if we have an internal postqueue. The
13289 object the lvalue refers to would (probably) be modified by the
13290 postqueue; we need to copy the value out first, which means an
13291 rvalue. */
13292 if ((fallback & fb_lvalue)
13293 && gimple_seq_empty_p (internal_post)
13294 && is_gimple_addressable (*expr_p))
13296 /* An lvalue will do. Take the address of the expression, store it
13297 in a temporary, and replace the expression with an INDIRECT_REF of
13298 that temporary. */
13299 tree ref_alias_type = reference_alias_ptr_type (*expr_p);
13300 unsigned int ref_align = get_object_alignment (*expr_p);
13301 tree ref_type = TREE_TYPE (*expr_p);
13302 tmp = build_fold_addr_expr_loc (input_location, *expr_p);
13303 gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue);
13304 if (TYPE_ALIGN (ref_type) != ref_align)
13305 ref_type = build_aligned_type (ref_type, ref_align);
13306 *expr_p = build2 (MEM_REF, ref_type,
13307 tmp, build_zero_cst (ref_alias_type));
13309 else if ((fallback & fb_rvalue) && is_gimple_reg_rhs_or_call (*expr_p))
13311 /* An rvalue will do. Assign the gimplified expression into a
13312 new temporary TMP and replace the original expression with
13313 TMP. First, make sure that the expression has a type so that
13314 it can be assigned into a temporary. */
13315 gcc_assert (!VOID_TYPE_P (TREE_TYPE (*expr_p)));
13316 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
13318 else
13320 #ifdef ENABLE_GIMPLE_CHECKING
13321 if (!(fallback & fb_mayfail))
13323 fprintf (stderr, "gimplification failed:\n");
13324 print_generic_expr (stderr, *expr_p);
13325 debug_tree (*expr_p);
13326 internal_error ("gimplification failed");
13328 #endif
13329 gcc_assert (fallback & fb_mayfail);
13331 /* If this is an asm statement, and the user asked for the
13332 impossible, don't die. Fail and let gimplify_asm_expr
13333 issue an error. */
13334 ret = GS_ERROR;
13335 goto out;
13338 /* Make sure the temporary matches our predicate. */
13339 gcc_assert ((*gimple_test_f) (*expr_p));
13341 if (!gimple_seq_empty_p (internal_post))
13343 annotate_all_with_location (internal_post, input_location);
13344 gimplify_seq_add_seq (pre_p, internal_post);
13347 out:
13348 input_location = saved_location;
13349 return ret;
13352 /* Like gimplify_expr but make sure the gimplified result is not itself
13353 a SSA name (but a decl if it were). Temporaries required by
13354 evaluating *EXPR_P may be still SSA names. */
13356 static enum gimplify_status
13357 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
13358 bool (*gimple_test_f) (tree), fallback_t fallback,
13359 bool allow_ssa)
13361 bool was_ssa_name_p = TREE_CODE (*expr_p) == SSA_NAME;
13362 enum gimplify_status ret = gimplify_expr (expr_p, pre_p, post_p,
13363 gimple_test_f, fallback);
13364 if (! allow_ssa
13365 && TREE_CODE (*expr_p) == SSA_NAME)
13367 tree name = *expr_p;
13368 if (was_ssa_name_p)
13369 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, NULL, false);
13370 else
13372 /* Avoid the extra copy if possible. */
13373 *expr_p = create_tmp_reg (TREE_TYPE (name));
13374 gimple_set_lhs (SSA_NAME_DEF_STMT (name), *expr_p);
13375 release_ssa_name (name);
13378 return ret;
13381 /* Look through TYPE for variable-sized objects and gimplify each such
13382 size that we find. Add to LIST_P any statements generated. */
13384 void
13385 gimplify_type_sizes (tree type, gimple_seq *list_p)
13387 tree field, t;
13389 if (type == NULL || type == error_mark_node)
13390 return;
13392 /* We first do the main variant, then copy into any other variants. */
13393 type = TYPE_MAIN_VARIANT (type);
13395 /* Avoid infinite recursion. */
13396 if (TYPE_SIZES_GIMPLIFIED (type))
13397 return;
13399 TYPE_SIZES_GIMPLIFIED (type) = 1;
13401 switch (TREE_CODE (type))
13403 case INTEGER_TYPE:
13404 case ENUMERAL_TYPE:
13405 case BOOLEAN_TYPE:
13406 case REAL_TYPE:
13407 case FIXED_POINT_TYPE:
13408 gimplify_one_sizepos (&TYPE_MIN_VALUE (type), list_p);
13409 gimplify_one_sizepos (&TYPE_MAX_VALUE (type), list_p);
13411 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
13413 TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type);
13414 TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type);
13416 break;
13418 case ARRAY_TYPE:
13419 /* These types may not have declarations, so handle them here. */
13420 gimplify_type_sizes (TREE_TYPE (type), list_p);
13421 gimplify_type_sizes (TYPE_DOMAIN (type), list_p);
13422 /* Ensure VLA bounds aren't removed, for -O0 they should be variables
13423 with assigned stack slots, for -O1+ -g they should be tracked
13424 by VTA. */
13425 if (!(TYPE_NAME (type)
13426 && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
13427 && DECL_IGNORED_P (TYPE_NAME (type)))
13428 && TYPE_DOMAIN (type)
13429 && INTEGRAL_TYPE_P (TYPE_DOMAIN (type)))
13431 t = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
13432 if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
13433 DECL_IGNORED_P (t) = 0;
13434 t = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
13435 if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
13436 DECL_IGNORED_P (t) = 0;
13438 break;
13440 case RECORD_TYPE:
13441 case UNION_TYPE:
13442 case QUAL_UNION_TYPE:
13443 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
13444 if (TREE_CODE (field) == FIELD_DECL)
13446 gimplify_one_sizepos (&DECL_FIELD_OFFSET (field), list_p);
13447 gimplify_one_sizepos (&DECL_SIZE (field), list_p);
13448 gimplify_one_sizepos (&DECL_SIZE_UNIT (field), list_p);
13449 gimplify_type_sizes (TREE_TYPE (field), list_p);
13451 break;
13453 case POINTER_TYPE:
13454 case REFERENCE_TYPE:
13455 /* We used to recurse on the pointed-to type here, which turned out to
13456 be incorrect because its definition might refer to variables not
13457 yet initialized at this point if a forward declaration is involved.
13459 It was actually useful for anonymous pointed-to types to ensure
13460 that the sizes evaluation dominates every possible later use of the
13461 values. Restricting to such types here would be safe since there
13462 is no possible forward declaration around, but would introduce an
13463 undesirable middle-end semantic to anonymity. We then defer to
13464 front-ends the responsibility of ensuring that the sizes are
13465 evaluated both early and late enough, e.g. by attaching artificial
13466 type declarations to the tree. */
13467 break;
13469 default:
13470 break;
13473 gimplify_one_sizepos (&TYPE_SIZE (type), list_p);
13474 gimplify_one_sizepos (&TYPE_SIZE_UNIT (type), list_p);
13476 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
13478 TYPE_SIZE (t) = TYPE_SIZE (type);
13479 TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (type);
13480 TYPE_SIZES_GIMPLIFIED (t) = 1;
13484 /* A subroutine of gimplify_type_sizes to make sure that *EXPR_P,
13485 a size or position, has had all of its SAVE_EXPRs evaluated.
13486 We add any required statements to *STMT_P. */
13488 void
13489 gimplify_one_sizepos (tree *expr_p, gimple_seq *stmt_p)
13491 tree expr = *expr_p;
13493 /* We don't do anything if the value isn't there, is constant, or contains
13494 A PLACEHOLDER_EXPR. We also don't want to do anything if it's already
13495 a VAR_DECL. If it's a VAR_DECL from another function, the gimplifier
13496 will want to replace it with a new variable, but that will cause problems
13497 if this type is from outside the function. It's OK to have that here. */
13498 if (expr == NULL_TREE
13499 || is_gimple_constant (expr)
13500 || TREE_CODE (expr) == VAR_DECL
13501 || CONTAINS_PLACEHOLDER_P (expr))
13502 return;
13504 *expr_p = unshare_expr (expr);
13506 /* SSA names in decl/type fields are a bad idea - they'll get reclaimed
13507 if the def vanishes. */
13508 gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue, false);
13510 /* If expr wasn't already is_gimple_sizepos or is_gimple_constant from the
13511 FE, ensure that it is a VAR_DECL, otherwise we might handle some decls
13512 as gimplify_vla_decl even when they would have all sizes INTEGER_CSTs. */
13513 if (is_gimple_constant (*expr_p))
13514 *expr_p = get_initialized_tmp_var (*expr_p, stmt_p, NULL, false);
13517 /* Gimplify the body of statements of FNDECL and return a GIMPLE_BIND node
13518 containing the sequence of corresponding GIMPLE statements. If DO_PARMS
13519 is true, also gimplify the parameters. */
13521 gbind *
13522 gimplify_body (tree fndecl, bool do_parms)
13524 location_t saved_location = input_location;
13525 gimple_seq parm_stmts, parm_cleanup = NULL, seq;
13526 gimple *outer_stmt;
13527 gbind *outer_bind;
13529 timevar_push (TV_TREE_GIMPLIFY);
13531 init_tree_ssa (cfun);
13533 /* Initialize for optimize_insn_for_s{ize,peed}_p possibly called during
13534 gimplification. */
13535 default_rtl_profile ();
13537 gcc_assert (gimplify_ctxp == NULL);
13538 push_gimplify_context (true);
13540 if (flag_openacc || flag_openmp)
13542 gcc_assert (gimplify_omp_ctxp == NULL);
13543 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (fndecl)))
13544 gimplify_omp_ctxp = new_omp_context (ORT_TARGET);
13547 /* Unshare most shared trees in the body and in that of any nested functions.
13548 It would seem we don't have to do this for nested functions because
13549 they are supposed to be output and then the outer function gimplified
13550 first, but the g++ front end doesn't always do it that way. */
13551 unshare_body (fndecl);
13552 unvisit_body (fndecl);
13554 /* Make sure input_location isn't set to something weird. */
13555 input_location = DECL_SOURCE_LOCATION (fndecl);
13557 /* Resolve callee-copies. This has to be done before processing
13558 the body so that DECL_VALUE_EXPR gets processed correctly. */
13559 parm_stmts = do_parms ? gimplify_parameters (&parm_cleanup) : NULL;
13561 /* Gimplify the function's body. */
13562 seq = NULL;
13563 gimplify_stmt (&DECL_SAVED_TREE (fndecl), &seq);
13564 outer_stmt = gimple_seq_first_stmt (seq);
13565 if (!outer_stmt)
13567 outer_stmt = gimple_build_nop ();
13568 gimplify_seq_add_stmt (&seq, outer_stmt);
13571 /* The body must contain exactly one statement, a GIMPLE_BIND. If this is
13572 not the case, wrap everything in a GIMPLE_BIND to make it so. */
13573 if (gimple_code (outer_stmt) == GIMPLE_BIND
13574 && gimple_seq_first (seq) == gimple_seq_last (seq))
13575 outer_bind = as_a <gbind *> (outer_stmt);
13576 else
13577 outer_bind = gimple_build_bind (NULL_TREE, seq, NULL);
13579 DECL_SAVED_TREE (fndecl) = NULL_TREE;
13581 /* If we had callee-copies statements, insert them at the beginning
13582 of the function and clear DECL_VALUE_EXPR_P on the parameters. */
13583 if (!gimple_seq_empty_p (parm_stmts))
13585 tree parm;
13587 gimplify_seq_add_seq (&parm_stmts, gimple_bind_body (outer_bind));
13588 if (parm_cleanup)
13590 gtry *g = gimple_build_try (parm_stmts, parm_cleanup,
13591 GIMPLE_TRY_FINALLY);
13592 parm_stmts = NULL;
13593 gimple_seq_add_stmt (&parm_stmts, g);
13595 gimple_bind_set_body (outer_bind, parm_stmts);
13597 for (parm = DECL_ARGUMENTS (current_function_decl);
13598 parm; parm = DECL_CHAIN (parm))
13599 if (DECL_HAS_VALUE_EXPR_P (parm))
13601 DECL_HAS_VALUE_EXPR_P (parm) = 0;
13602 DECL_IGNORED_P (parm) = 0;
13606 if ((flag_openacc || flag_openmp || flag_openmp_simd)
13607 && gimplify_omp_ctxp)
13609 delete_omp_context (gimplify_omp_ctxp);
13610 gimplify_omp_ctxp = NULL;
13613 pop_gimplify_context (outer_bind);
13614 gcc_assert (gimplify_ctxp == NULL);
13616 if (flag_checking && !seen_error ())
13617 verify_gimple_in_seq (gimple_bind_body (outer_bind));
13619 timevar_pop (TV_TREE_GIMPLIFY);
13620 input_location = saved_location;
13622 return outer_bind;
13625 typedef char *char_p; /* For DEF_VEC_P. */
13627 /* Return whether we should exclude FNDECL from instrumentation. */
13629 static bool
13630 flag_instrument_functions_exclude_p (tree fndecl)
13632 vec<char_p> *v;
13634 v = (vec<char_p> *) flag_instrument_functions_exclude_functions;
13635 if (v && v->length () > 0)
13637 const char *name;
13638 int i;
13639 char *s;
13641 name = lang_hooks.decl_printable_name (fndecl, 0);
13642 FOR_EACH_VEC_ELT (*v, i, s)
13643 if (strstr (name, s) != NULL)
13644 return true;
13647 v = (vec<char_p> *) flag_instrument_functions_exclude_files;
13648 if (v && v->length () > 0)
13650 const char *name;
13651 int i;
13652 char *s;
13654 name = DECL_SOURCE_FILE (fndecl);
13655 FOR_EACH_VEC_ELT (*v, i, s)
13656 if (strstr (name, s) != NULL)
13657 return true;
13660 return false;
13663 /* Entry point to the gimplification pass. FNDECL is the FUNCTION_DECL
13664 node for the function we want to gimplify.
13666 Return the sequence of GIMPLE statements corresponding to the body
13667 of FNDECL. */
13669 void
13670 gimplify_function_tree (tree fndecl)
13672 tree parm, ret;
13673 gimple_seq seq;
13674 gbind *bind;
13676 gcc_assert (!gimple_body (fndecl));
13678 if (DECL_STRUCT_FUNCTION (fndecl))
13679 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
13680 else
13681 push_struct_function (fndecl);
13683 /* Tentatively set PROP_gimple_lva here, and reset it in gimplify_va_arg_expr
13684 if necessary. */
13685 cfun->curr_properties |= PROP_gimple_lva;
13687 for (parm = DECL_ARGUMENTS (fndecl); parm ; parm = DECL_CHAIN (parm))
13689 /* Preliminarily mark non-addressed complex variables as eligible
13690 for promotion to gimple registers. We'll transform their uses
13691 as we find them. */
13692 if ((TREE_CODE (TREE_TYPE (parm)) == COMPLEX_TYPE
13693 || TREE_CODE (TREE_TYPE (parm)) == VECTOR_TYPE)
13694 && !TREE_THIS_VOLATILE (parm)
13695 && !needs_to_live_in_memory (parm))
13696 DECL_GIMPLE_REG_P (parm) = 1;
13699 ret = DECL_RESULT (fndecl);
13700 if ((TREE_CODE (TREE_TYPE (ret)) == COMPLEX_TYPE
13701 || TREE_CODE (TREE_TYPE (ret)) == VECTOR_TYPE)
13702 && !needs_to_live_in_memory (ret))
13703 DECL_GIMPLE_REG_P (ret) = 1;
13705 if (asan_sanitize_use_after_scope () && sanitize_flags_p (SANITIZE_ADDRESS))
13706 asan_poisoned_variables = new hash_set<tree> ();
13707 bind = gimplify_body (fndecl, true);
13708 if (asan_poisoned_variables)
13710 delete asan_poisoned_variables;
13711 asan_poisoned_variables = NULL;
13714 /* The tree body of the function is no longer needed, replace it
13715 with the new GIMPLE body. */
13716 seq = NULL;
13717 gimple_seq_add_stmt (&seq, bind);
13718 gimple_set_body (fndecl, seq);
13720 /* If we're instrumenting function entry/exit, then prepend the call to
13721 the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to
13722 catch the exit hook. */
13723 /* ??? Add some way to ignore exceptions for this TFE. */
13724 if (flag_instrument_function_entry_exit
13725 && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl)
13726 /* Do not instrument extern inline functions. */
13727 && !(DECL_DECLARED_INLINE_P (fndecl)
13728 && DECL_EXTERNAL (fndecl)
13729 && DECL_DISREGARD_INLINE_LIMITS (fndecl))
13730 && !flag_instrument_functions_exclude_p (fndecl))
13732 tree x;
13733 gbind *new_bind;
13734 gimple *tf;
13735 gimple_seq cleanup = NULL, body = NULL;
13736 tree tmp_var, this_fn_addr;
13737 gcall *call;
13739 /* The instrumentation hooks aren't going to call the instrumented
13740 function and the address they receive is expected to be matchable
13741 against symbol addresses. Make sure we don't create a trampoline,
13742 in case the current function is nested. */
13743 this_fn_addr = build_fold_addr_expr (current_function_decl);
13744 TREE_NO_TRAMPOLINE (this_fn_addr) = 1;
13746 x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
13747 call = gimple_build_call (x, 1, integer_zero_node);
13748 tmp_var = create_tmp_var (ptr_type_node, "return_addr");
13749 gimple_call_set_lhs (call, tmp_var);
13750 gimplify_seq_add_stmt (&cleanup, call);
13751 x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_EXIT);
13752 call = gimple_build_call (x, 2, this_fn_addr, tmp_var);
13753 gimplify_seq_add_stmt (&cleanup, call);
13754 tf = gimple_build_try (seq, cleanup, GIMPLE_TRY_FINALLY);
13756 x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
13757 call = gimple_build_call (x, 1, integer_zero_node);
13758 tmp_var = create_tmp_var (ptr_type_node, "return_addr");
13759 gimple_call_set_lhs (call, tmp_var);
13760 gimplify_seq_add_stmt (&body, call);
13761 x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_ENTER);
13762 call = gimple_build_call (x, 2, this_fn_addr, tmp_var);
13763 gimplify_seq_add_stmt (&body, call);
13764 gimplify_seq_add_stmt (&body, tf);
13765 new_bind = gimple_build_bind (NULL, body, NULL);
13767 /* Replace the current function body with the body
13768 wrapped in the try/finally TF. */
13769 seq = NULL;
13770 gimple_seq_add_stmt (&seq, new_bind);
13771 gimple_set_body (fndecl, seq);
13772 bind = new_bind;
13775 if (sanitize_flags_p (SANITIZE_THREAD))
13777 gcall *call = gimple_build_call_internal (IFN_TSAN_FUNC_EXIT, 0);
13778 gimple *tf = gimple_build_try (seq, call, GIMPLE_TRY_FINALLY);
13779 gbind *new_bind = gimple_build_bind (NULL, tf, NULL);
13780 /* Replace the current function body with the body
13781 wrapped in the try/finally TF. */
13782 seq = NULL;
13783 gimple_seq_add_stmt (&seq, new_bind);
13784 gimple_set_body (fndecl, seq);
13787 DECL_SAVED_TREE (fndecl) = NULL_TREE;
13788 cfun->curr_properties |= PROP_gimple_any;
13790 pop_cfun ();
13792 dump_function (TDI_gimple, fndecl);
13795 /* Return a dummy expression of type TYPE in order to keep going after an
13796 error. */
13798 static tree
13799 dummy_object (tree type)
13801 tree t = build_int_cst (build_pointer_type (type), 0);
13802 return build2 (MEM_REF, type, t, t);
13805 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
13806 builtin function, but a very special sort of operator. */
13808 enum gimplify_status
13809 gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p,
13810 gimple_seq *post_p ATTRIBUTE_UNUSED)
13812 tree promoted_type, have_va_type;
13813 tree valist = TREE_OPERAND (*expr_p, 0);
13814 tree type = TREE_TYPE (*expr_p);
13815 tree t, tag, aptag;
13816 location_t loc = EXPR_LOCATION (*expr_p);
13818 /* Verify that valist is of the proper type. */
13819 have_va_type = TREE_TYPE (valist);
13820 if (have_va_type == error_mark_node)
13821 return GS_ERROR;
13822 have_va_type = targetm.canonical_va_list_type (have_va_type);
13823 if (have_va_type == NULL_TREE
13824 && POINTER_TYPE_P (TREE_TYPE (valist)))
13825 /* Handle 'Case 1: Not an array type' from c-common.c/build_va_arg. */
13826 have_va_type
13827 = targetm.canonical_va_list_type (TREE_TYPE (TREE_TYPE (valist)));
13828 gcc_assert (have_va_type != NULL_TREE);
13830 /* Generate a diagnostic for requesting data of a type that cannot
13831 be passed through `...' due to type promotion at the call site. */
13832 if ((promoted_type = lang_hooks.types.type_promotes_to (type))
13833 != type)
13835 static bool gave_help;
13836 bool warned;
13837 /* Use the expansion point to handle cases such as passing bool (defined
13838 in a system header) through `...'. */
13839 source_location xloc
13840 = expansion_point_location_if_in_system_header (loc);
13842 /* Unfortunately, this is merely undefined, rather than a constraint
13843 violation, so we cannot make this an error. If this call is never
13844 executed, the program is still strictly conforming. */
13845 auto_diagnostic_group d;
13846 warned = warning_at (xloc, 0,
13847 "%qT is promoted to %qT when passed through %<...%>",
13848 type, promoted_type);
13849 if (!gave_help && warned)
13851 gave_help = true;
13852 inform (xloc, "(so you should pass %qT not %qT to %<va_arg%>)",
13853 promoted_type, type);
13856 /* We can, however, treat "undefined" any way we please.
13857 Call abort to encourage the user to fix the program. */
13858 if (warned)
13859 inform (xloc, "if this code is reached, the program will abort");
13860 /* Before the abort, allow the evaluation of the va_list
13861 expression to exit or longjmp. */
13862 gimplify_and_add (valist, pre_p);
13863 t = build_call_expr_loc (loc,
13864 builtin_decl_implicit (BUILT_IN_TRAP), 0);
13865 gimplify_and_add (t, pre_p);
13867 /* This is dead code, but go ahead and finish so that the
13868 mode of the result comes out right. */
13869 *expr_p = dummy_object (type);
13870 return GS_ALL_DONE;
13873 tag = build_int_cst (build_pointer_type (type), 0);
13874 aptag = build_int_cst (TREE_TYPE (valist), 0);
13876 *expr_p = build_call_expr_internal_loc (loc, IFN_VA_ARG, type, 3,
13877 valist, tag, aptag);
13879 /* Clear the tentatively set PROP_gimple_lva, to indicate that IFN_VA_ARG
13880 needs to be expanded. */
13881 cfun->curr_properties &= ~PROP_gimple_lva;
13883 return GS_OK;
13886 /* Build a new GIMPLE_ASSIGN tuple and append it to the end of *SEQ_P.
13888 DST/SRC are the destination and source respectively. You can pass
13889 ungimplified trees in DST or SRC, in which case they will be
13890 converted to a gimple operand if necessary.
13892 This function returns the newly created GIMPLE_ASSIGN tuple. */
13894 gimple *
13895 gimplify_assign (tree dst, tree src, gimple_seq *seq_p)
13897 tree t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
13898 gimplify_and_add (t, seq_p);
13899 ggc_free (t);
13900 return gimple_seq_last_stmt (*seq_p);
13903 inline hashval_t
13904 gimplify_hasher::hash (const elt_t *p)
13906 tree t = p->val;
13907 return iterative_hash_expr (t, 0);
13910 inline bool
13911 gimplify_hasher::equal (const elt_t *p1, const elt_t *p2)
13913 tree t1 = p1->val;
13914 tree t2 = p2->val;
13915 enum tree_code code = TREE_CODE (t1);
13917 if (TREE_CODE (t2) != code
13918 || TREE_TYPE (t1) != TREE_TYPE (t2))
13919 return false;
13921 if (!operand_equal_p (t1, t2, 0))
13922 return false;
13924 /* Only allow them to compare equal if they also hash equal; otherwise
13925 results are nondeterminate, and we fail bootstrap comparison. */
13926 gcc_checking_assert (hash (p1) == hash (p2));
13928 return true;