Emit SIMD moves as mov
[official-gcc.git] / gcc / gimplify.c
blobcf82f95160a22c0210fafbbb95c74c4b72535983
1 /* Tree lowering pass. This pass converts the GENERIC functions-as-trees
2 tree representation into the GIMPLE form.
3 Copyright (C) 2002-2017 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 "gimple.h"
31 #include "gimple-predict.h"
32 #include "tree-pass.h" /* FIXME: only for PROP_gimple_any */
33 #include "ssa.h"
34 #include "cgraph.h"
35 #include "tree-pretty-print.h"
36 #include "diagnostic-core.h"
37 #include "alias.h"
38 #include "fold-const.h"
39 #include "calls.h"
40 #include "varasm.h"
41 #include "stmt.h"
42 #include "expr.h"
43 #include "gimple-fold.h"
44 #include "tree-eh.h"
45 #include "gimplify.h"
46 #include "gimple-iterator.h"
47 #include "stor-layout.h"
48 #include "print-tree.h"
49 #include "tree-iterator.h"
50 #include "tree-inline.h"
51 #include "langhooks.h"
52 #include "tree-cfg.h"
53 #include "tree-ssa.h"
54 #include "omp-general.h"
55 #include "omp-low.h"
56 #include "gimple-low.h"
57 #include "cilk.h"
58 #include "gomp-constants.h"
59 #include "splay-tree.h"
60 #include "gimple-walk.h"
61 #include "langhooks-def.h" /* FIXME: for lhd_set_decl_assembler_name */
62 #include "builtins.h"
63 #include "asan.h"
64 #include "dbgcnt.h"
66 /* Hash set of poisoned variables in a bind expr. */
67 static hash_set<tree> *asan_poisoned_variables = NULL;
69 enum gimplify_omp_var_data
71 GOVD_SEEN = 1,
72 GOVD_EXPLICIT = 2,
73 GOVD_SHARED = 4,
74 GOVD_PRIVATE = 8,
75 GOVD_FIRSTPRIVATE = 16,
76 GOVD_LASTPRIVATE = 32,
77 GOVD_REDUCTION = 64,
78 GOVD_LOCAL = 128,
79 GOVD_MAP = 256,
80 GOVD_DEBUG_PRIVATE = 512,
81 GOVD_PRIVATE_OUTER_REF = 1024,
82 GOVD_LINEAR = 2048,
83 GOVD_ALIGNED = 4096,
85 /* Flag for GOVD_MAP: don't copy back. */
86 GOVD_MAP_TO_ONLY = 8192,
88 /* Flag for GOVD_LINEAR or GOVD_LASTPRIVATE: no outer reference. */
89 GOVD_LINEAR_LASTPRIVATE_NO_OUTER = 16384,
91 GOVD_MAP_0LEN_ARRAY = 32768,
93 /* Flag for GOVD_MAP, if it is always, to or always, tofrom mapping. */
94 GOVD_MAP_ALWAYS_TO = 65536,
96 /* Flag for shared vars that are or might be stored to in the region. */
97 GOVD_WRITTEN = 131072,
99 /* Flag for GOVD_MAP, if it is a forced mapping. */
100 GOVD_MAP_FORCE = 262144,
102 /* Flag for GOVD_MAP: must be present already. */
103 GOVD_MAP_FORCE_PRESENT = 524288,
105 GOVD_DATA_SHARE_CLASS = (GOVD_SHARED | GOVD_PRIVATE | GOVD_FIRSTPRIVATE
106 | GOVD_LASTPRIVATE | GOVD_REDUCTION | GOVD_LINEAR
107 | GOVD_LOCAL)
111 enum omp_region_type
113 ORT_WORKSHARE = 0x00,
114 ORT_SIMD = 0x01,
116 ORT_PARALLEL = 0x02,
117 ORT_COMBINED_PARALLEL = 0x03,
119 ORT_TASK = 0x04,
120 ORT_UNTIED_TASK = 0x05,
122 ORT_TEAMS = 0x08,
123 ORT_COMBINED_TEAMS = 0x09,
125 /* Data region. */
126 ORT_TARGET_DATA = 0x10,
128 /* Data region with offloading. */
129 ORT_TARGET = 0x20,
130 ORT_COMBINED_TARGET = 0x21,
132 /* OpenACC variants. */
133 ORT_ACC = 0x40, /* A generic OpenACC region. */
134 ORT_ACC_DATA = ORT_ACC | ORT_TARGET_DATA, /* Data construct. */
135 ORT_ACC_PARALLEL = ORT_ACC | ORT_TARGET, /* Parallel construct */
136 ORT_ACC_KERNELS = ORT_ACC | ORT_TARGET | 0x80, /* Kernels construct. */
137 ORT_ACC_HOST_DATA = ORT_ACC | ORT_TARGET_DATA | 0x80, /* Host data. */
139 /* Dummy OpenMP region, used to disable expansion of
140 DECL_VALUE_EXPRs in taskloop pre body. */
141 ORT_NONE = 0x100
144 /* Gimplify hashtable helper. */
146 struct gimplify_hasher : free_ptr_hash <elt_t>
148 static inline hashval_t hash (const elt_t *);
149 static inline bool equal (const elt_t *, const elt_t *);
152 struct gimplify_ctx
154 struct gimplify_ctx *prev_context;
156 vec<gbind *> bind_expr_stack;
157 tree temps;
158 gimple_seq conditional_cleanups;
159 tree exit_label;
160 tree return_temp;
162 vec<tree> case_labels;
163 hash_set<tree> *live_switch_vars;
164 /* The formal temporary table. Should this be persistent? */
165 hash_table<gimplify_hasher> *temp_htab;
167 int conditions;
168 unsigned into_ssa : 1;
169 unsigned allow_rhs_cond_expr : 1;
170 unsigned in_cleanup_point_expr : 1;
171 unsigned keep_stack : 1;
172 unsigned save_stack : 1;
173 unsigned in_switch_expr : 1;
176 struct gimplify_omp_ctx
178 struct gimplify_omp_ctx *outer_context;
179 splay_tree variables;
180 hash_set<tree> *privatized_types;
181 /* Iteration variables in an OMP_FOR. */
182 vec<tree> loop_iter_var;
183 location_t location;
184 enum omp_clause_default_kind default_kind;
185 enum omp_region_type region_type;
186 bool combined_loop;
187 bool distribute;
188 bool target_map_scalars_firstprivate;
189 bool target_map_pointers_as_0len_arrays;
190 bool target_firstprivatize_array_bases;
193 static struct gimplify_ctx *gimplify_ctxp;
194 static struct gimplify_omp_ctx *gimplify_omp_ctxp;
196 /* Forward declaration. */
197 static enum gimplify_status gimplify_compound_expr (tree *, gimple_seq *, bool);
198 static hash_map<tree, tree> *oacc_declare_returns;
199 static enum gimplify_status gimplify_expr (tree *, gimple_seq *, gimple_seq *,
200 bool (*) (tree), fallback_t, bool);
202 /* Shorter alias name for the above function for use in gimplify.c
203 only. */
205 static inline void
206 gimplify_seq_add_stmt (gimple_seq *seq_p, gimple *gs)
208 gimple_seq_add_stmt_without_update (seq_p, gs);
211 /* Append sequence SRC to the end of sequence *DST_P. If *DST_P is
212 NULL, a new sequence is allocated. This function is
213 similar to gimple_seq_add_seq, but does not scan the operands.
214 During gimplification, we need to manipulate statement sequences
215 before the def/use vectors have been constructed. */
217 static void
218 gimplify_seq_add_seq (gimple_seq *dst_p, gimple_seq src)
220 gimple_stmt_iterator si;
222 if (src == NULL)
223 return;
225 si = gsi_last (*dst_p);
226 gsi_insert_seq_after_without_update (&si, src, GSI_NEW_STMT);
230 /* Pointer to a list of allocated gimplify_ctx structs to be used for pushing
231 and popping gimplify contexts. */
233 static struct gimplify_ctx *ctx_pool = NULL;
235 /* Return a gimplify context struct from the pool. */
237 static inline struct gimplify_ctx *
238 ctx_alloc (void)
240 struct gimplify_ctx * c = ctx_pool;
242 if (c)
243 ctx_pool = c->prev_context;
244 else
245 c = XNEW (struct gimplify_ctx);
247 memset (c, '\0', sizeof (*c));
248 return c;
251 /* Put gimplify context C back into the pool. */
253 static inline void
254 ctx_free (struct gimplify_ctx *c)
256 c->prev_context = ctx_pool;
257 ctx_pool = c;
260 /* Free allocated ctx stack memory. */
262 void
263 free_gimplify_stack (void)
265 struct gimplify_ctx *c;
267 while ((c = ctx_pool))
269 ctx_pool = c->prev_context;
270 free (c);
275 /* Set up a context for the gimplifier. */
277 void
278 push_gimplify_context (bool in_ssa, bool rhs_cond_ok)
280 struct gimplify_ctx *c = ctx_alloc ();
282 c->prev_context = gimplify_ctxp;
283 gimplify_ctxp = c;
284 gimplify_ctxp->into_ssa = in_ssa;
285 gimplify_ctxp->allow_rhs_cond_expr = rhs_cond_ok;
288 /* Tear down a context for the gimplifier. If BODY is non-null, then
289 put the temporaries into the outer BIND_EXPR. Otherwise, put them
290 in the local_decls.
292 BODY is not a sequence, but the first tuple in a sequence. */
294 void
295 pop_gimplify_context (gimple *body)
297 struct gimplify_ctx *c = gimplify_ctxp;
299 gcc_assert (c
300 && (!c->bind_expr_stack.exists ()
301 || c->bind_expr_stack.is_empty ()));
302 c->bind_expr_stack.release ();
303 gimplify_ctxp = c->prev_context;
305 if (body)
306 declare_vars (c->temps, body, false);
307 else
308 record_vars (c->temps);
310 delete c->temp_htab;
311 c->temp_htab = NULL;
312 ctx_free (c);
315 /* Push a GIMPLE_BIND tuple onto the stack of bindings. */
317 static void
318 gimple_push_bind_expr (gbind *bind_stmt)
320 gimplify_ctxp->bind_expr_stack.reserve (8);
321 gimplify_ctxp->bind_expr_stack.safe_push (bind_stmt);
324 /* Pop the first element off the stack of bindings. */
326 static void
327 gimple_pop_bind_expr (void)
329 gimplify_ctxp->bind_expr_stack.pop ();
332 /* Return the first element of the stack of bindings. */
334 gbind *
335 gimple_current_bind_expr (void)
337 return gimplify_ctxp->bind_expr_stack.last ();
340 /* Return the stack of bindings created during gimplification. */
342 vec<gbind *>
343 gimple_bind_expr_stack (void)
345 return gimplify_ctxp->bind_expr_stack;
348 /* Return true iff there is a COND_EXPR between us and the innermost
349 CLEANUP_POINT_EXPR. This info is used by gimple_push_cleanup. */
351 static bool
352 gimple_conditional_context (void)
354 return gimplify_ctxp->conditions > 0;
357 /* Note that we've entered a COND_EXPR. */
359 static void
360 gimple_push_condition (void)
362 #ifdef ENABLE_GIMPLE_CHECKING
363 if (gimplify_ctxp->conditions == 0)
364 gcc_assert (gimple_seq_empty_p (gimplify_ctxp->conditional_cleanups));
365 #endif
366 ++(gimplify_ctxp->conditions);
369 /* Note that we've left a COND_EXPR. If we're back at unconditional scope
370 now, add any conditional cleanups we've seen to the prequeue. */
372 static void
373 gimple_pop_condition (gimple_seq *pre_p)
375 int conds = --(gimplify_ctxp->conditions);
377 gcc_assert (conds >= 0);
378 if (conds == 0)
380 gimplify_seq_add_seq (pre_p, gimplify_ctxp->conditional_cleanups);
381 gimplify_ctxp->conditional_cleanups = NULL;
385 /* A stable comparison routine for use with splay trees and DECLs. */
387 static int
388 splay_tree_compare_decl_uid (splay_tree_key xa, splay_tree_key xb)
390 tree a = (tree) xa;
391 tree b = (tree) xb;
393 return DECL_UID (a) - DECL_UID (b);
396 /* Create a new omp construct that deals with variable remapping. */
398 static struct gimplify_omp_ctx *
399 new_omp_context (enum omp_region_type region_type)
401 struct gimplify_omp_ctx *c;
403 c = XCNEW (struct gimplify_omp_ctx);
404 c->outer_context = gimplify_omp_ctxp;
405 c->variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0);
406 c->privatized_types = new hash_set<tree>;
407 c->location = input_location;
408 c->region_type = region_type;
409 if ((region_type & ORT_TASK) == 0)
410 c->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
411 else
412 c->default_kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
414 return c;
417 /* Destroy an omp construct that deals with variable remapping. */
419 static void
420 delete_omp_context (struct gimplify_omp_ctx *c)
422 splay_tree_delete (c->variables);
423 delete c->privatized_types;
424 c->loop_iter_var.release ();
425 XDELETE (c);
428 static void omp_add_variable (struct gimplify_omp_ctx *, tree, unsigned int);
429 static bool omp_notice_variable (struct gimplify_omp_ctx *, tree, bool);
431 /* Both gimplify the statement T and append it to *SEQ_P. This function
432 behaves exactly as gimplify_stmt, but you don't have to pass T as a
433 reference. */
435 void
436 gimplify_and_add (tree t, gimple_seq *seq_p)
438 gimplify_stmt (&t, seq_p);
441 /* Gimplify statement T into sequence *SEQ_P, and return the first
442 tuple in the sequence of generated tuples for this statement.
443 Return NULL if gimplifying T produced no tuples. */
445 static gimple *
446 gimplify_and_return_first (tree t, gimple_seq *seq_p)
448 gimple_stmt_iterator last = gsi_last (*seq_p);
450 gimplify_and_add (t, seq_p);
452 if (!gsi_end_p (last))
454 gsi_next (&last);
455 return gsi_stmt (last);
457 else
458 return gimple_seq_first_stmt (*seq_p);
461 /* Returns true iff T is a valid RHS for an assignment to an un-renamed
462 LHS, or for a call argument. */
464 static bool
465 is_gimple_mem_rhs (tree t)
467 /* If we're dealing with a renamable type, either source or dest must be
468 a renamed variable. */
469 if (is_gimple_reg_type (TREE_TYPE (t)))
470 return is_gimple_val (t);
471 else
472 return is_gimple_val (t) || is_gimple_lvalue (t);
475 /* Return true if T is a CALL_EXPR or an expression that can be
476 assigned to a temporary. Note that this predicate should only be
477 used during gimplification. See the rationale for this in
478 gimplify_modify_expr. */
480 static bool
481 is_gimple_reg_rhs_or_call (tree t)
483 return (get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS
484 || TREE_CODE (t) == CALL_EXPR);
487 /* Return true if T is a valid memory RHS or a CALL_EXPR. Note that
488 this predicate should only be used during gimplification. See the
489 rationale for this in gimplify_modify_expr. */
491 static bool
492 is_gimple_mem_rhs_or_call (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)
500 || is_gimple_lvalue (t)
501 || TREE_CLOBBER_P (t)
502 || TREE_CODE (t) == CALL_EXPR);
505 /* Create a temporary with a name derived from VAL. Subroutine of
506 lookup_tmp_var; nobody else should call this function. */
508 static inline tree
509 create_tmp_from_val (tree val)
511 /* Drop all qualifiers and address-space information from the value type. */
512 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (val));
513 tree var = create_tmp_var (type, get_name (val));
514 if (TREE_CODE (TREE_TYPE (var)) == COMPLEX_TYPE
515 || TREE_CODE (TREE_TYPE (var)) == VECTOR_TYPE)
516 DECL_GIMPLE_REG_P (var) = 1;
517 return var;
520 /* Create a temporary to hold the value of VAL. If IS_FORMAL, try to reuse
521 an existing expression temporary. */
523 static tree
524 lookup_tmp_var (tree val, bool is_formal)
526 tree ret;
528 /* If not optimizing, never really reuse a temporary. local-alloc
529 won't allocate any variable that is used in more than one basic
530 block, which means it will go into memory, causing much extra
531 work in reload and final and poorer code generation, outweighing
532 the extra memory allocation here. */
533 if (!optimize || !is_formal || TREE_SIDE_EFFECTS (val))
534 ret = create_tmp_from_val (val);
535 else
537 elt_t elt, *elt_p;
538 elt_t **slot;
540 elt.val = val;
541 if (!gimplify_ctxp->temp_htab)
542 gimplify_ctxp->temp_htab = new hash_table<gimplify_hasher> (1000);
543 slot = gimplify_ctxp->temp_htab->find_slot (&elt, INSERT);
544 if (*slot == NULL)
546 elt_p = XNEW (elt_t);
547 elt_p->val = val;
548 elt_p->temp = ret = create_tmp_from_val (val);
549 *slot = elt_p;
551 else
553 elt_p = *slot;
554 ret = elt_p->temp;
558 return ret;
561 /* Helper for get_formal_tmp_var and get_initialized_tmp_var. */
563 static tree
564 internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
565 bool is_formal, bool allow_ssa)
567 tree t, mod;
569 /* Notice that we explicitly allow VAL to be a CALL_EXPR so that we
570 can create an INIT_EXPR and convert it into a GIMPLE_CALL below. */
571 gimplify_expr (&val, pre_p, post_p, is_gimple_reg_rhs_or_call,
572 fb_rvalue);
574 if (allow_ssa
575 && gimplify_ctxp->into_ssa
576 && is_gimple_reg_type (TREE_TYPE (val)))
578 t = make_ssa_name (TYPE_MAIN_VARIANT (TREE_TYPE (val)));
579 if (! gimple_in_ssa_p (cfun))
581 const char *name = get_name (val);
582 if (name)
583 SET_SSA_NAME_VAR_OR_IDENTIFIER (t, create_tmp_var_name (name));
586 else
587 t = lookup_tmp_var (val, is_formal);
589 mod = build2 (INIT_EXPR, TREE_TYPE (t), t, unshare_expr (val));
591 SET_EXPR_LOCATION (mod, EXPR_LOC_OR_LOC (val, input_location));
593 /* gimplify_modify_expr might want to reduce this further. */
594 gimplify_and_add (mod, pre_p);
595 ggc_free (mod);
597 return t;
600 /* Return a formal temporary variable initialized with VAL. PRE_P is as
601 in gimplify_expr. Only use this function if:
603 1) The value of the unfactored expression represented by VAL will not
604 change between the initialization and use of the temporary, and
605 2) The temporary will not be otherwise modified.
607 For instance, #1 means that this is inappropriate for SAVE_EXPR temps,
608 and #2 means it is inappropriate for && temps.
610 For other cases, use get_initialized_tmp_var instead. */
612 tree
613 get_formal_tmp_var (tree val, gimple_seq *pre_p)
615 return internal_get_tmp_var (val, pre_p, NULL, true, true);
618 /* Return a temporary variable initialized with VAL. PRE_P and POST_P
619 are as in gimplify_expr. */
621 tree
622 get_initialized_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
623 bool allow_ssa)
625 return internal_get_tmp_var (val, pre_p, post_p, false, allow_ssa);
628 /* Declare all the variables in VARS in SCOPE. If DEBUG_INFO is true,
629 generate debug info for them; otherwise don't. */
631 void
632 declare_vars (tree vars, gimple *gs, bool debug_info)
634 tree last = vars;
635 if (last)
637 tree temps, block;
639 gbind *scope = as_a <gbind *> (gs);
641 temps = nreverse (last);
643 block = gimple_bind_block (scope);
644 gcc_assert (!block || TREE_CODE (block) == BLOCK);
645 if (!block || !debug_info)
647 DECL_CHAIN (last) = gimple_bind_vars (scope);
648 gimple_bind_set_vars (scope, temps);
650 else
652 /* We need to attach the nodes both to the BIND_EXPR and to its
653 associated BLOCK for debugging purposes. The key point here
654 is that the BLOCK_VARS of the BIND_EXPR_BLOCK of a BIND_EXPR
655 is a subchain of the BIND_EXPR_VARS of the BIND_EXPR. */
656 if (BLOCK_VARS (block))
657 BLOCK_VARS (block) = chainon (BLOCK_VARS (block), temps);
658 else
660 gimple_bind_set_vars (scope,
661 chainon (gimple_bind_vars (scope), temps));
662 BLOCK_VARS (block) = temps;
668 /* For VAR a VAR_DECL of variable size, try to find a constant upper bound
669 for the size and adjust DECL_SIZE/DECL_SIZE_UNIT accordingly. Abort if
670 no such upper bound can be obtained. */
672 static void
673 force_constant_size (tree var)
675 /* The only attempt we make is by querying the maximum size of objects
676 of the variable's type. */
678 HOST_WIDE_INT max_size;
680 gcc_assert (VAR_P (var));
682 max_size = max_int_size_in_bytes (TREE_TYPE (var));
684 gcc_assert (max_size >= 0);
686 DECL_SIZE_UNIT (var)
687 = build_int_cst (TREE_TYPE (DECL_SIZE_UNIT (var)), max_size);
688 DECL_SIZE (var)
689 = build_int_cst (TREE_TYPE (DECL_SIZE (var)), max_size * BITS_PER_UNIT);
692 /* Push the temporary variable TMP into the current binding. */
694 void
695 gimple_add_tmp_var_fn (struct function *fn, tree tmp)
697 gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
699 /* Later processing assumes that the object size is constant, which might
700 not be true at this point. Force the use of a constant upper bound in
701 this case. */
702 if (!tree_fits_uhwi_p (DECL_SIZE_UNIT (tmp)))
703 force_constant_size (tmp);
705 DECL_CONTEXT (tmp) = fn->decl;
706 DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
708 record_vars_into (tmp, fn->decl);
711 /* Push the temporary variable TMP into the current binding. */
713 void
714 gimple_add_tmp_var (tree tmp)
716 gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
718 /* Later processing assumes that the object size is constant, which might
719 not be true at this point. Force the use of a constant upper bound in
720 this case. */
721 if (!tree_fits_uhwi_p (DECL_SIZE_UNIT (tmp)))
722 force_constant_size (tmp);
724 DECL_CONTEXT (tmp) = current_function_decl;
725 DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
727 if (gimplify_ctxp)
729 DECL_CHAIN (tmp) = gimplify_ctxp->temps;
730 gimplify_ctxp->temps = tmp;
732 /* Mark temporaries local within the nearest enclosing parallel. */
733 if (gimplify_omp_ctxp)
735 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
736 while (ctx
737 && (ctx->region_type == ORT_WORKSHARE
738 || ctx->region_type == ORT_SIMD
739 || ctx->region_type == ORT_ACC))
740 ctx = ctx->outer_context;
741 if (ctx)
742 omp_add_variable (ctx, tmp, GOVD_LOCAL | GOVD_SEEN);
745 else if (cfun)
746 record_vars (tmp);
747 else
749 gimple_seq body_seq;
751 /* This case is for nested functions. We need to expose the locals
752 they create. */
753 body_seq = gimple_body (current_function_decl);
754 declare_vars (tmp, gimple_seq_first_stmt (body_seq), false);
760 /* This page contains routines to unshare tree nodes, i.e. to duplicate tree
761 nodes that are referenced more than once in GENERIC functions. This is
762 necessary because gimplification (translation into GIMPLE) is performed
763 by modifying tree nodes in-place, so gimplication of a shared node in a
764 first context could generate an invalid GIMPLE form in a second context.
766 This is achieved with a simple mark/copy/unmark algorithm that walks the
767 GENERIC representation top-down, marks nodes with TREE_VISITED the first
768 time it encounters them, duplicates them if they already have TREE_VISITED
769 set, and finally removes the TREE_VISITED marks it has set.
771 The algorithm works only at the function level, i.e. it generates a GENERIC
772 representation of a function with no nodes shared within the function when
773 passed a GENERIC function (except for nodes that are allowed to be shared).
775 At the global level, it is also necessary to unshare tree nodes that are
776 referenced in more than one function, for the same aforementioned reason.
777 This requires some cooperation from the front-end. There are 2 strategies:
779 1. Manual unsharing. The front-end needs to call unshare_expr on every
780 expression that might end up being shared across functions.
782 2. Deep unsharing. This is an extension of regular unsharing. Instead
783 of calling unshare_expr on expressions that might be shared across
784 functions, the front-end pre-marks them with TREE_VISITED. This will
785 ensure that they are unshared on the first reference within functions
786 when the regular unsharing algorithm runs. The counterpart is that
787 this algorithm must look deeper than for manual unsharing, which is
788 specified by LANG_HOOKS_DEEP_UNSHARING.
790 If there are only few specific cases of node sharing across functions, it is
791 probably easier for a front-end to unshare the expressions manually. On the
792 contrary, if the expressions generated at the global level are as widespread
793 as expressions generated within functions, deep unsharing is very likely the
794 way to go. */
796 /* Similar to copy_tree_r but do not copy SAVE_EXPR or TARGET_EXPR nodes.
797 These nodes model computations that must be done once. If we were to
798 unshare something like SAVE_EXPR(i++), the gimplification process would
799 create wrong code. However, if DATA is non-null, it must hold a pointer
800 set that is used to unshare the subtrees of these nodes. */
802 static tree
803 mostly_copy_tree_r (tree *tp, int *walk_subtrees, void *data)
805 tree t = *tp;
806 enum tree_code code = TREE_CODE (t);
808 /* Do not copy SAVE_EXPR, TARGET_EXPR or BIND_EXPR nodes themselves, but
809 copy their subtrees if we can make sure to do it only once. */
810 if (code == SAVE_EXPR || code == TARGET_EXPR || code == BIND_EXPR)
812 if (data && !((hash_set<tree> *)data)->add (t))
814 else
815 *walk_subtrees = 0;
818 /* Stop at types, decls, constants like copy_tree_r. */
819 else if (TREE_CODE_CLASS (code) == tcc_type
820 || TREE_CODE_CLASS (code) == tcc_declaration
821 || TREE_CODE_CLASS (code) == tcc_constant
822 /* We can't do anything sensible with a BLOCK used as an
823 expression, but we also can't just die when we see it
824 because of non-expression uses. So we avert our eyes
825 and cross our fingers. Silly Java. */
826 || code == BLOCK)
827 *walk_subtrees = 0;
829 /* Cope with the statement expression extension. */
830 else if (code == STATEMENT_LIST)
833 /* Leave the bulk of the work to copy_tree_r itself. */
834 else
835 copy_tree_r (tp, walk_subtrees, NULL);
837 return NULL_TREE;
840 /* Callback for walk_tree to unshare most of the shared trees rooted at *TP.
841 If *TP has been visited already, then *TP is deeply copied by calling
842 mostly_copy_tree_r. DATA is passed to mostly_copy_tree_r unmodified. */
844 static tree
845 copy_if_shared_r (tree *tp, int *walk_subtrees, void *data)
847 tree t = *tp;
848 enum tree_code code = TREE_CODE (t);
850 /* Skip types, decls, and constants. But we do want to look at their
851 types and the bounds of types. Mark them as visited so we properly
852 unmark their subtrees on the unmark pass. If we've already seen them,
853 don't look down further. */
854 if (TREE_CODE_CLASS (code) == tcc_type
855 || TREE_CODE_CLASS (code) == tcc_declaration
856 || TREE_CODE_CLASS (code) == tcc_constant)
858 if (TREE_VISITED (t))
859 *walk_subtrees = 0;
860 else
861 TREE_VISITED (t) = 1;
864 /* If this node has been visited already, unshare it and don't look
865 any deeper. */
866 else if (TREE_VISITED (t))
868 walk_tree (tp, mostly_copy_tree_r, data, NULL);
869 *walk_subtrees = 0;
872 /* Otherwise, mark the node as visited and keep looking. */
873 else
874 TREE_VISITED (t) = 1;
876 return NULL_TREE;
879 /* Unshare most of the shared trees rooted at *TP. DATA is passed to the
880 copy_if_shared_r callback unmodified. */
882 static inline void
883 copy_if_shared (tree *tp, void *data)
885 walk_tree (tp, copy_if_shared_r, data, NULL);
888 /* Unshare all the trees in the body of FNDECL, as well as in the bodies of
889 any nested functions. */
891 static void
892 unshare_body (tree fndecl)
894 struct cgraph_node *cgn = cgraph_node::get (fndecl);
895 /* If the language requires deep unsharing, we need a pointer set to make
896 sure we don't repeatedly unshare subtrees of unshareable nodes. */
897 hash_set<tree> *visited
898 = lang_hooks.deep_unsharing ? new hash_set<tree> : NULL;
900 copy_if_shared (&DECL_SAVED_TREE (fndecl), visited);
901 copy_if_shared (&DECL_SIZE (DECL_RESULT (fndecl)), visited);
902 copy_if_shared (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)), visited);
904 delete visited;
906 if (cgn)
907 for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
908 unshare_body (cgn->decl);
911 /* Callback for walk_tree to unmark the visited trees rooted at *TP.
912 Subtrees are walked until the first unvisited node is encountered. */
914 static tree
915 unmark_visited_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
917 tree t = *tp;
919 /* If this node has been visited, unmark it and keep looking. */
920 if (TREE_VISITED (t))
921 TREE_VISITED (t) = 0;
923 /* Otherwise, don't look any deeper. */
924 else
925 *walk_subtrees = 0;
927 return NULL_TREE;
930 /* Unmark the visited trees rooted at *TP. */
932 static inline void
933 unmark_visited (tree *tp)
935 walk_tree (tp, unmark_visited_r, NULL, NULL);
938 /* Likewise, but mark all trees as not visited. */
940 static void
941 unvisit_body (tree fndecl)
943 struct cgraph_node *cgn = cgraph_node::get (fndecl);
945 unmark_visited (&DECL_SAVED_TREE (fndecl));
946 unmark_visited (&DECL_SIZE (DECL_RESULT (fndecl)));
947 unmark_visited (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)));
949 if (cgn)
950 for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
951 unvisit_body (cgn->decl);
954 /* Unconditionally make an unshared copy of EXPR. This is used when using
955 stored expressions which span multiple functions, such as BINFO_VTABLE,
956 as the normal unsharing process can't tell that they're shared. */
958 tree
959 unshare_expr (tree expr)
961 walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
962 return expr;
965 /* Worker for unshare_expr_without_location. */
967 static tree
968 prune_expr_location (tree *tp, int *walk_subtrees, void *)
970 if (EXPR_P (*tp))
971 SET_EXPR_LOCATION (*tp, UNKNOWN_LOCATION);
972 else
973 *walk_subtrees = 0;
974 return NULL_TREE;
977 /* Similar to unshare_expr but also prune all expression locations
978 from EXPR. */
980 tree
981 unshare_expr_without_location (tree expr)
983 walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
984 if (EXPR_P (expr))
985 walk_tree (&expr, prune_expr_location, NULL, NULL);
986 return expr;
989 /* WRAPPER is a code such as BIND_EXPR or CLEANUP_POINT_EXPR which can both
990 contain statements and have a value. Assign its value to a temporary
991 and give it void_type_node. Return the temporary, or NULL_TREE if
992 WRAPPER was already void. */
994 tree
995 voidify_wrapper_expr (tree wrapper, tree temp)
997 tree type = TREE_TYPE (wrapper);
998 if (type && !VOID_TYPE_P (type))
1000 tree *p;
1002 /* Set p to point to the body of the wrapper. Loop until we find
1003 something that isn't a wrapper. */
1004 for (p = &wrapper; p && *p; )
1006 switch (TREE_CODE (*p))
1008 case BIND_EXPR:
1009 TREE_SIDE_EFFECTS (*p) = 1;
1010 TREE_TYPE (*p) = void_type_node;
1011 /* For a BIND_EXPR, the body is operand 1. */
1012 p = &BIND_EXPR_BODY (*p);
1013 break;
1015 case CLEANUP_POINT_EXPR:
1016 case TRY_FINALLY_EXPR:
1017 case TRY_CATCH_EXPR:
1018 TREE_SIDE_EFFECTS (*p) = 1;
1019 TREE_TYPE (*p) = void_type_node;
1020 p = &TREE_OPERAND (*p, 0);
1021 break;
1023 case STATEMENT_LIST:
1025 tree_stmt_iterator i = tsi_last (*p);
1026 TREE_SIDE_EFFECTS (*p) = 1;
1027 TREE_TYPE (*p) = void_type_node;
1028 p = tsi_end_p (i) ? NULL : tsi_stmt_ptr (i);
1030 break;
1032 case COMPOUND_EXPR:
1033 /* Advance to the last statement. Set all container types to
1034 void. */
1035 for (; TREE_CODE (*p) == COMPOUND_EXPR; p = &TREE_OPERAND (*p, 1))
1037 TREE_SIDE_EFFECTS (*p) = 1;
1038 TREE_TYPE (*p) = void_type_node;
1040 break;
1042 case TRANSACTION_EXPR:
1043 TREE_SIDE_EFFECTS (*p) = 1;
1044 TREE_TYPE (*p) = void_type_node;
1045 p = &TRANSACTION_EXPR_BODY (*p);
1046 break;
1048 default:
1049 /* Assume that any tree upon which voidify_wrapper_expr is
1050 directly called is a wrapper, and that its body is op0. */
1051 if (p == &wrapper)
1053 TREE_SIDE_EFFECTS (*p) = 1;
1054 TREE_TYPE (*p) = void_type_node;
1055 p = &TREE_OPERAND (*p, 0);
1056 break;
1058 goto out;
1062 out:
1063 if (p == NULL || IS_EMPTY_STMT (*p))
1064 temp = NULL_TREE;
1065 else if (temp)
1067 /* The wrapper is on the RHS of an assignment that we're pushing
1068 down. */
1069 gcc_assert (TREE_CODE (temp) == INIT_EXPR
1070 || TREE_CODE (temp) == MODIFY_EXPR);
1071 TREE_OPERAND (temp, 1) = *p;
1072 *p = temp;
1074 else
1076 temp = create_tmp_var (type, "retval");
1077 *p = build2 (INIT_EXPR, type, temp, *p);
1080 return temp;
1083 return NULL_TREE;
1086 /* Prepare calls to builtins to SAVE and RESTORE the stack as well as
1087 a temporary through which they communicate. */
1089 static void
1090 build_stack_save_restore (gcall **save, gcall **restore)
1092 tree tmp_var;
1094 *save = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_SAVE), 0);
1095 tmp_var = create_tmp_var (ptr_type_node, "saved_stack");
1096 gimple_call_set_lhs (*save, tmp_var);
1098 *restore
1099 = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_RESTORE),
1100 1, tmp_var);
1103 /* Generate IFN_ASAN_MARK call that poisons shadow of a for DECL variable. */
1105 static tree
1106 build_asan_poison_call_expr (tree decl)
1108 /* Do not poison variables that have size equal to zero. */
1109 tree unit_size = DECL_SIZE_UNIT (decl);
1110 if (zerop (unit_size))
1111 return NULL_TREE;
1113 tree base = build_fold_addr_expr (decl);
1115 return build_call_expr_internal_loc (UNKNOWN_LOCATION, IFN_ASAN_MARK,
1116 void_type_node, 3,
1117 build_int_cst (integer_type_node,
1118 ASAN_MARK_POISON),
1119 base, unit_size);
1122 /* Generate IFN_ASAN_MARK call that would poison or unpoison, depending
1123 on POISON flag, shadow memory of a DECL variable. The call will be
1124 put on location identified by IT iterator, where BEFORE flag drives
1125 position where the stmt will be put. */
1127 static void
1128 asan_poison_variable (tree decl, bool poison, gimple_stmt_iterator *it,
1129 bool before)
1131 /* When within an OMP context, do not emit ASAN_MARK internal fns. */
1132 if (gimplify_omp_ctxp)
1133 return;
1135 tree unit_size = DECL_SIZE_UNIT (decl);
1136 tree base = build_fold_addr_expr (decl);
1138 /* Do not poison variables that have size equal to zero. */
1139 if (zerop (unit_size))
1140 return;
1142 /* It's necessary to have all stack variables aligned to ASAN granularity
1143 bytes. */
1144 if (DECL_ALIGN_UNIT (decl) <= ASAN_SHADOW_GRANULARITY)
1145 SET_DECL_ALIGN (decl, BITS_PER_UNIT * ASAN_SHADOW_GRANULARITY);
1147 HOST_WIDE_INT flags = poison ? ASAN_MARK_POISON : ASAN_MARK_UNPOISON;
1149 gimple *g
1150 = gimple_build_call_internal (IFN_ASAN_MARK, 3,
1151 build_int_cst (integer_type_node, flags),
1152 base, unit_size);
1154 if (before)
1155 gsi_insert_before (it, g, GSI_NEW_STMT);
1156 else
1157 gsi_insert_after (it, g, GSI_NEW_STMT);
1160 /* Generate IFN_ASAN_MARK internal call that depending on POISON flag
1161 either poisons or unpoisons a DECL. Created statement is appended
1162 to SEQ_P gimple sequence. */
1164 static void
1165 asan_poison_variable (tree decl, bool poison, gimple_seq *seq_p)
1167 gimple_stmt_iterator it = gsi_last (*seq_p);
1168 bool before = false;
1170 if (gsi_end_p (it))
1171 before = true;
1173 asan_poison_variable (decl, poison, &it, before);
1176 /* Sort pair of VAR_DECLs A and B by DECL_UID. */
1178 static int
1179 sort_by_decl_uid (const void *a, const void *b)
1181 const tree *t1 = (const tree *)a;
1182 const tree *t2 = (const tree *)b;
1184 int uid1 = DECL_UID (*t1);
1185 int uid2 = DECL_UID (*t2);
1187 if (uid1 < uid2)
1188 return -1;
1189 else if (uid1 > uid2)
1190 return 1;
1191 else
1192 return 0;
1195 /* Generate IFN_ASAN_MARK internal call for all VARIABLES
1196 depending on POISON flag. Created statement is appended
1197 to SEQ_P gimple sequence. */
1199 static void
1200 asan_poison_variables (hash_set<tree> *variables, bool poison, gimple_seq *seq_p)
1202 unsigned c = variables->elements ();
1203 if (c == 0)
1204 return;
1206 auto_vec<tree> sorted_variables (c);
1208 for (hash_set<tree>::iterator it = variables->begin ();
1209 it != variables->end (); ++it)
1210 sorted_variables.safe_push (*it);
1212 sorted_variables.qsort (sort_by_decl_uid);
1214 unsigned i;
1215 tree var;
1216 FOR_EACH_VEC_ELT (sorted_variables, i, var)
1218 asan_poison_variable (var, poison, seq_p);
1220 /* Add use_after_scope_memory attribute for the variable in order
1221 to prevent re-written into SSA. */
1222 if (!lookup_attribute (ASAN_USE_AFTER_SCOPE_ATTRIBUTE,
1223 DECL_ATTRIBUTES (var)))
1224 DECL_ATTRIBUTES (var)
1225 = tree_cons (get_identifier (ASAN_USE_AFTER_SCOPE_ATTRIBUTE),
1226 integer_one_node,
1227 DECL_ATTRIBUTES (var));
1231 /* Gimplify a BIND_EXPR. Just voidify and recurse. */
1233 static enum gimplify_status
1234 gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p)
1236 tree bind_expr = *expr_p;
1237 bool old_keep_stack = gimplify_ctxp->keep_stack;
1238 bool old_save_stack = gimplify_ctxp->save_stack;
1239 tree t;
1240 gbind *bind_stmt;
1241 gimple_seq body, cleanup;
1242 gcall *stack_save;
1243 location_t start_locus = 0, end_locus = 0;
1244 tree ret_clauses = NULL;
1246 tree temp = voidify_wrapper_expr (bind_expr, NULL);
1248 /* Mark variables seen in this bind expr. */
1249 for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t))
1251 if (VAR_P (t))
1253 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
1255 /* Mark variable as local. */
1256 if (ctx && ctx->region_type != ORT_NONE && !DECL_EXTERNAL (t)
1257 && (! DECL_SEEN_IN_BIND_EXPR_P (t)
1258 || splay_tree_lookup (ctx->variables,
1259 (splay_tree_key) t) == NULL))
1261 if (ctx->region_type == ORT_SIMD
1262 && TREE_ADDRESSABLE (t)
1263 && !TREE_STATIC (t))
1264 omp_add_variable (ctx, t, GOVD_PRIVATE | GOVD_SEEN);
1265 else
1266 omp_add_variable (ctx, t, GOVD_LOCAL | GOVD_SEEN);
1269 DECL_SEEN_IN_BIND_EXPR_P (t) = 1;
1271 if (DECL_HARD_REGISTER (t) && !is_global_var (t) && cfun)
1272 cfun->has_local_explicit_reg_vars = true;
1275 /* Preliminarily mark non-addressed complex variables as eligible
1276 for promotion to gimple registers. We'll transform their uses
1277 as we find them. */
1278 if ((TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE
1279 || TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
1280 && !TREE_THIS_VOLATILE (t)
1281 && (VAR_P (t) && !DECL_HARD_REGISTER (t))
1282 && !needs_to_live_in_memory (t))
1283 DECL_GIMPLE_REG_P (t) = 1;
1286 bind_stmt = gimple_build_bind (BIND_EXPR_VARS (bind_expr), NULL,
1287 BIND_EXPR_BLOCK (bind_expr));
1288 gimple_push_bind_expr (bind_stmt);
1290 gimplify_ctxp->keep_stack = false;
1291 gimplify_ctxp->save_stack = false;
1293 /* Gimplify the body into the GIMPLE_BIND tuple's body. */
1294 body = NULL;
1295 gimplify_stmt (&BIND_EXPR_BODY (bind_expr), &body);
1296 gimple_bind_set_body (bind_stmt, body);
1298 /* Source location wise, the cleanup code (stack_restore and clobbers)
1299 belongs to the end of the block, so propagate what we have. The
1300 stack_save operation belongs to the beginning of block, which we can
1301 infer from the bind_expr directly if the block has no explicit
1302 assignment. */
1303 if (BIND_EXPR_BLOCK (bind_expr))
1305 end_locus = BLOCK_SOURCE_END_LOCATION (BIND_EXPR_BLOCK (bind_expr));
1306 start_locus = BLOCK_SOURCE_LOCATION (BIND_EXPR_BLOCK (bind_expr));
1308 if (start_locus == 0)
1309 start_locus = EXPR_LOCATION (bind_expr);
1311 cleanup = NULL;
1312 stack_save = NULL;
1314 /* If the code both contains VLAs and calls alloca, then we cannot reclaim
1315 the stack space allocated to the VLAs. */
1316 if (gimplify_ctxp->save_stack && !gimplify_ctxp->keep_stack)
1318 gcall *stack_restore;
1320 /* Save stack on entry and restore it on exit. Add a try_finally
1321 block to achieve this. */
1322 build_stack_save_restore (&stack_save, &stack_restore);
1324 gimple_set_location (stack_save, start_locus);
1325 gimple_set_location (stack_restore, end_locus);
1327 gimplify_seq_add_stmt (&cleanup, stack_restore);
1330 /* Add clobbers for all variables that go out of scope. */
1331 for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t))
1333 if (VAR_P (t)
1334 && !is_global_var (t)
1335 && DECL_CONTEXT (t) == current_function_decl)
1337 if (!DECL_HARD_REGISTER (t)
1338 && !TREE_THIS_VOLATILE (t)
1339 && !DECL_HAS_VALUE_EXPR_P (t)
1340 /* Only care for variables that have to be in memory. Others
1341 will be rewritten into SSA names, hence moved to the
1342 top-level. */
1343 && !is_gimple_reg (t)
1344 && flag_stack_reuse != SR_NONE)
1346 tree clobber = build_constructor (TREE_TYPE (t), NULL);
1347 gimple *clobber_stmt;
1348 TREE_THIS_VOLATILE (clobber) = 1;
1349 clobber_stmt = gimple_build_assign (t, clobber);
1350 gimple_set_location (clobber_stmt, end_locus);
1351 gimplify_seq_add_stmt (&cleanup, clobber_stmt);
1354 if (flag_openacc && oacc_declare_returns != NULL)
1356 tree *c = oacc_declare_returns->get (t);
1357 if (c != NULL)
1359 if (ret_clauses)
1360 OMP_CLAUSE_CHAIN (*c) = ret_clauses;
1362 ret_clauses = *c;
1364 oacc_declare_returns->remove (t);
1366 if (oacc_declare_returns->elements () == 0)
1368 delete oacc_declare_returns;
1369 oacc_declare_returns = NULL;
1375 if (asan_poisoned_variables != NULL
1376 && asan_poisoned_variables->contains (t))
1378 asan_poisoned_variables->remove (t);
1379 asan_poison_variable (t, true, &cleanup);
1382 if (gimplify_ctxp->live_switch_vars != NULL
1383 && gimplify_ctxp->live_switch_vars->contains (t))
1384 gimplify_ctxp->live_switch_vars->remove (t);
1387 if (ret_clauses)
1389 gomp_target *stmt;
1390 gimple_stmt_iterator si = gsi_start (cleanup);
1392 stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
1393 ret_clauses);
1394 gsi_insert_seq_before_without_update (&si, stmt, GSI_NEW_STMT);
1397 if (cleanup)
1399 gtry *gs;
1400 gimple_seq new_body;
1402 new_body = NULL;
1403 gs = gimple_build_try (gimple_bind_body (bind_stmt), cleanup,
1404 GIMPLE_TRY_FINALLY);
1406 if (stack_save)
1407 gimplify_seq_add_stmt (&new_body, stack_save);
1408 gimplify_seq_add_stmt (&new_body, gs);
1409 gimple_bind_set_body (bind_stmt, new_body);
1412 /* keep_stack propagates all the way up to the outermost BIND_EXPR. */
1413 if (!gimplify_ctxp->keep_stack)
1414 gimplify_ctxp->keep_stack = old_keep_stack;
1415 gimplify_ctxp->save_stack = old_save_stack;
1417 gimple_pop_bind_expr ();
1419 gimplify_seq_add_stmt (pre_p, bind_stmt);
1421 if (temp)
1423 *expr_p = temp;
1424 return GS_OK;
1427 *expr_p = NULL_TREE;
1428 return GS_ALL_DONE;
1431 /* Gimplify a RETURN_EXPR. If the expression to be returned is not a
1432 GIMPLE value, it is assigned to a new temporary and the statement is
1433 re-written to return the temporary.
1435 PRE_P points to the sequence where side effects that must happen before
1436 STMT should be stored. */
1438 static enum gimplify_status
1439 gimplify_return_expr (tree stmt, gimple_seq *pre_p)
1441 greturn *ret;
1442 tree ret_expr = TREE_OPERAND (stmt, 0);
1443 tree result_decl, result;
1445 if (ret_expr == error_mark_node)
1446 return GS_ERROR;
1448 /* Implicit _Cilk_sync must be inserted right before any return statement
1449 if there is a _Cilk_spawn in the function. If the user has provided a
1450 _Cilk_sync, the optimizer should remove this duplicate one. */
1451 if (fn_contains_cilk_spawn_p (cfun))
1453 tree impl_sync = build0 (CILK_SYNC_STMT, void_type_node);
1454 gimplify_and_add (impl_sync, pre_p);
1457 if (!ret_expr
1458 || TREE_CODE (ret_expr) == RESULT_DECL
1459 || ret_expr == error_mark_node)
1461 greturn *ret = gimple_build_return (ret_expr);
1462 gimple_set_no_warning (ret, TREE_NO_WARNING (stmt));
1463 gimplify_seq_add_stmt (pre_p, ret);
1464 return GS_ALL_DONE;
1467 if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))))
1468 result_decl = NULL_TREE;
1469 else
1471 result_decl = TREE_OPERAND (ret_expr, 0);
1473 /* See through a return by reference. */
1474 if (TREE_CODE (result_decl) == INDIRECT_REF)
1475 result_decl = TREE_OPERAND (result_decl, 0);
1477 gcc_assert ((TREE_CODE (ret_expr) == MODIFY_EXPR
1478 || TREE_CODE (ret_expr) == INIT_EXPR)
1479 && TREE_CODE (result_decl) == RESULT_DECL);
1482 /* If aggregate_value_p is true, then we can return the bare RESULT_DECL.
1483 Recall that aggregate_value_p is FALSE for any aggregate type that is
1484 returned in registers. If we're returning values in registers, then
1485 we don't want to extend the lifetime of the RESULT_DECL, particularly
1486 across another call. In addition, for those aggregates for which
1487 hard_function_value generates a PARALLEL, we'll die during normal
1488 expansion of structure assignments; there's special code in expand_return
1489 to handle this case that does not exist in expand_expr. */
1490 if (!result_decl)
1491 result = NULL_TREE;
1492 else if (aggregate_value_p (result_decl, TREE_TYPE (current_function_decl)))
1494 if (TREE_CODE (DECL_SIZE (result_decl)) != INTEGER_CST)
1496 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (result_decl)))
1497 gimplify_type_sizes (TREE_TYPE (result_decl), pre_p);
1498 /* Note that we don't use gimplify_vla_decl because the RESULT_DECL
1499 should be effectively allocated by the caller, i.e. all calls to
1500 this function must be subject to the Return Slot Optimization. */
1501 gimplify_one_sizepos (&DECL_SIZE (result_decl), pre_p);
1502 gimplify_one_sizepos (&DECL_SIZE_UNIT (result_decl), pre_p);
1504 result = result_decl;
1506 else if (gimplify_ctxp->return_temp)
1507 result = gimplify_ctxp->return_temp;
1508 else
1510 result = create_tmp_reg (TREE_TYPE (result_decl));
1512 /* ??? With complex control flow (usually involving abnormal edges),
1513 we can wind up warning about an uninitialized value for this. Due
1514 to how this variable is constructed and initialized, this is never
1515 true. Give up and never warn. */
1516 TREE_NO_WARNING (result) = 1;
1518 gimplify_ctxp->return_temp = result;
1521 /* Smash the lhs of the MODIFY_EXPR to the temporary we plan to use.
1522 Then gimplify the whole thing. */
1523 if (result != result_decl)
1524 TREE_OPERAND (ret_expr, 0) = result;
1526 gimplify_and_add (TREE_OPERAND (stmt, 0), pre_p);
1528 ret = gimple_build_return (result);
1529 gimple_set_no_warning (ret, TREE_NO_WARNING (stmt));
1530 gimplify_seq_add_stmt (pre_p, ret);
1532 return GS_ALL_DONE;
1535 /* Gimplify a variable-length array DECL. */
1537 static void
1538 gimplify_vla_decl (tree decl, gimple_seq *seq_p)
1540 /* This is a variable-sized decl. Simplify its size and mark it
1541 for deferred expansion. */
1542 tree t, addr, ptr_type;
1544 gimplify_one_sizepos (&DECL_SIZE (decl), seq_p);
1545 gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), seq_p);
1547 /* Don't mess with a DECL_VALUE_EXPR set by the front-end. */
1548 if (DECL_HAS_VALUE_EXPR_P (decl))
1549 return;
1551 /* All occurrences of this decl in final gimplified code will be
1552 replaced by indirection. Setting DECL_VALUE_EXPR does two
1553 things: First, it lets the rest of the gimplifier know what
1554 replacement to use. Second, it lets the debug info know
1555 where to find the value. */
1556 ptr_type = build_pointer_type (TREE_TYPE (decl));
1557 addr = create_tmp_var (ptr_type, get_name (decl));
1558 DECL_IGNORED_P (addr) = 0;
1559 t = build_fold_indirect_ref (addr);
1560 TREE_THIS_NOTRAP (t) = 1;
1561 SET_DECL_VALUE_EXPR (decl, t);
1562 DECL_HAS_VALUE_EXPR_P (decl) = 1;
1564 t = builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN);
1565 t = build_call_expr (t, 2, DECL_SIZE_UNIT (decl),
1566 size_int (DECL_ALIGN (decl)));
1567 /* The call has been built for a variable-sized object. */
1568 CALL_ALLOCA_FOR_VAR_P (t) = 1;
1569 t = fold_convert (ptr_type, t);
1570 t = build2 (MODIFY_EXPR, TREE_TYPE (addr), addr, t);
1572 gimplify_and_add (t, seq_p);
1575 /* A helper function to be called via walk_tree. Mark all labels under *TP
1576 as being forced. To be called for DECL_INITIAL of static variables. */
1578 static tree
1579 force_labels_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
1581 if (TYPE_P (*tp))
1582 *walk_subtrees = 0;
1583 if (TREE_CODE (*tp) == LABEL_DECL)
1585 FORCED_LABEL (*tp) = 1;
1586 cfun->has_forced_label_in_static = 1;
1589 return NULL_TREE;
1592 /* Gimplify a DECL_EXPR node *STMT_P by making any necessary allocation
1593 and initialization explicit. */
1595 static enum gimplify_status
1596 gimplify_decl_expr (tree *stmt_p, gimple_seq *seq_p)
1598 tree stmt = *stmt_p;
1599 tree decl = DECL_EXPR_DECL (stmt);
1601 *stmt_p = NULL_TREE;
1603 if (TREE_TYPE (decl) == error_mark_node)
1604 return GS_ERROR;
1606 if ((TREE_CODE (decl) == TYPE_DECL
1607 || VAR_P (decl))
1608 && !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl)))
1610 gimplify_type_sizes (TREE_TYPE (decl), seq_p);
1611 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
1612 gimplify_type_sizes (TREE_TYPE (TREE_TYPE (decl)), seq_p);
1615 /* ??? DECL_ORIGINAL_TYPE is streamed for LTO so it needs to be gimplified
1616 in case its size expressions contain problematic nodes like CALL_EXPR. */
1617 if (TREE_CODE (decl) == TYPE_DECL
1618 && DECL_ORIGINAL_TYPE (decl)
1619 && !TYPE_SIZES_GIMPLIFIED (DECL_ORIGINAL_TYPE (decl)))
1621 gimplify_type_sizes (DECL_ORIGINAL_TYPE (decl), seq_p);
1622 if (TREE_CODE (DECL_ORIGINAL_TYPE (decl)) == REFERENCE_TYPE)
1623 gimplify_type_sizes (TREE_TYPE (DECL_ORIGINAL_TYPE (decl)), seq_p);
1626 if (VAR_P (decl) && !DECL_EXTERNAL (decl))
1628 tree init = DECL_INITIAL (decl);
1629 bool is_vla = false;
1631 if (TREE_CODE (DECL_SIZE_UNIT (decl)) != INTEGER_CST
1632 || (!TREE_STATIC (decl)
1633 && flag_stack_check == GENERIC_STACK_CHECK
1634 && compare_tree_int (DECL_SIZE_UNIT (decl),
1635 STACK_CHECK_MAX_VAR_SIZE) > 0))
1637 gimplify_vla_decl (decl, seq_p);
1638 is_vla = true;
1641 if (asan_poisoned_variables
1642 && !is_vla
1643 && TREE_ADDRESSABLE (decl)
1644 && !TREE_STATIC (decl)
1645 && !DECL_HAS_VALUE_EXPR_P (decl)
1646 && dbg_cnt (asan_use_after_scope))
1648 asan_poisoned_variables->add (decl);
1649 asan_poison_variable (decl, false, seq_p);
1650 if (!DECL_ARTIFICIAL (decl) && gimplify_ctxp->live_switch_vars)
1651 gimplify_ctxp->live_switch_vars->add (decl);
1654 /* Some front ends do not explicitly declare all anonymous
1655 artificial variables. We compensate here by declaring the
1656 variables, though it would be better if the front ends would
1657 explicitly declare them. */
1658 if (!DECL_SEEN_IN_BIND_EXPR_P (decl)
1659 && DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
1660 gimple_add_tmp_var (decl);
1662 if (init && init != error_mark_node)
1664 if (!TREE_STATIC (decl))
1666 DECL_INITIAL (decl) = NULL_TREE;
1667 init = build2 (INIT_EXPR, void_type_node, decl, init);
1668 gimplify_and_add (init, seq_p);
1669 ggc_free (init);
1671 else
1672 /* We must still examine initializers for static variables
1673 as they may contain a label address. */
1674 walk_tree (&init, force_labels_r, NULL, NULL);
1678 return GS_ALL_DONE;
1681 /* Gimplify a LOOP_EXPR. Normally this just involves gimplifying the body
1682 and replacing the LOOP_EXPR with goto, but if the loop contains an
1683 EXIT_EXPR, we need to append a label for it to jump to. */
1685 static enum gimplify_status
1686 gimplify_loop_expr (tree *expr_p, gimple_seq *pre_p)
1688 tree saved_label = gimplify_ctxp->exit_label;
1689 tree start_label = create_artificial_label (UNKNOWN_LOCATION);
1691 gimplify_seq_add_stmt (pre_p, gimple_build_label (start_label));
1693 gimplify_ctxp->exit_label = NULL_TREE;
1695 gimplify_and_add (LOOP_EXPR_BODY (*expr_p), pre_p);
1697 gimplify_seq_add_stmt (pre_p, gimple_build_goto (start_label));
1699 if (gimplify_ctxp->exit_label)
1700 gimplify_seq_add_stmt (pre_p,
1701 gimple_build_label (gimplify_ctxp->exit_label));
1703 gimplify_ctxp->exit_label = saved_label;
1705 *expr_p = NULL;
1706 return GS_ALL_DONE;
1709 /* Gimplify a statement list onto a sequence. These may be created either
1710 by an enlightened front-end, or by shortcut_cond_expr. */
1712 static enum gimplify_status
1713 gimplify_statement_list (tree *expr_p, gimple_seq *pre_p)
1715 tree temp = voidify_wrapper_expr (*expr_p, NULL);
1717 tree_stmt_iterator i = tsi_start (*expr_p);
1719 while (!tsi_end_p (i))
1721 gimplify_stmt (tsi_stmt_ptr (i), pre_p);
1722 tsi_delink (&i);
1725 if (temp)
1727 *expr_p = temp;
1728 return GS_OK;
1731 return GS_ALL_DONE;
1734 /* Callback for walk_gimple_seq. */
1736 static tree
1737 warn_switch_unreachable_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
1738 struct walk_stmt_info *wi)
1740 gimple *stmt = gsi_stmt (*gsi_p);
1742 *handled_ops_p = true;
1743 switch (gimple_code (stmt))
1745 case GIMPLE_TRY:
1746 /* A compiler-generated cleanup or a user-written try block.
1747 If it's empty, don't dive into it--that would result in
1748 worse location info. */
1749 if (gimple_try_eval (stmt) == NULL)
1751 wi->info = stmt;
1752 return integer_zero_node;
1754 /* Fall through. */
1755 case GIMPLE_BIND:
1756 case GIMPLE_CATCH:
1757 case GIMPLE_EH_FILTER:
1758 case GIMPLE_TRANSACTION:
1759 /* Walk the sub-statements. */
1760 *handled_ops_p = false;
1761 break;
1762 case GIMPLE_CALL:
1763 if (gimple_call_internal_p (stmt, IFN_ASAN_MARK))
1765 *handled_ops_p = false;
1766 break;
1768 /* Fall through. */
1769 default:
1770 /* Save the first "real" statement (not a decl/lexical scope/...). */
1771 wi->info = stmt;
1772 return integer_zero_node;
1774 return NULL_TREE;
1777 /* Possibly warn about unreachable statements between switch's controlling
1778 expression and the first case. SEQ is the body of a switch expression. */
1780 static void
1781 maybe_warn_switch_unreachable (gimple_seq seq)
1783 if (!warn_switch_unreachable
1784 /* This warning doesn't play well with Fortran when optimizations
1785 are on. */
1786 || lang_GNU_Fortran ()
1787 || seq == NULL)
1788 return;
1790 struct walk_stmt_info wi;
1791 memset (&wi, 0, sizeof (wi));
1792 walk_gimple_seq (seq, warn_switch_unreachable_r, NULL, &wi);
1793 gimple *stmt = (gimple *) wi.info;
1795 if (stmt && gimple_code (stmt) != GIMPLE_LABEL)
1797 if (gimple_code (stmt) == GIMPLE_GOTO
1798 && TREE_CODE (gimple_goto_dest (stmt)) == LABEL_DECL
1799 && DECL_ARTIFICIAL (gimple_goto_dest (stmt)))
1800 /* Don't warn for compiler-generated gotos. These occur
1801 in Duff's devices, for example. */;
1802 else
1803 warning_at (gimple_location (stmt), OPT_Wswitch_unreachable,
1804 "statement will never be executed");
1809 /* A label entry that pairs label and a location. */
1810 struct label_entry
1812 tree label;
1813 location_t loc;
1816 /* Find LABEL in vector of label entries VEC. */
1818 static struct label_entry *
1819 find_label_entry (const auto_vec<struct label_entry> *vec, tree label)
1821 unsigned int i;
1822 struct label_entry *l;
1824 FOR_EACH_VEC_ELT (*vec, i, l)
1825 if (l->label == label)
1826 return l;
1827 return NULL;
1830 /* Return true if LABEL, a LABEL_DECL, represents a case label
1831 in a vector of labels CASES. */
1833 static bool
1834 case_label_p (const vec<tree> *cases, tree label)
1836 unsigned int i;
1837 tree l;
1839 FOR_EACH_VEC_ELT (*cases, i, l)
1840 if (CASE_LABEL (l) == label)
1841 return true;
1842 return false;
1845 /* Find the last statement in a scope STMT. */
1847 static gimple *
1848 last_stmt_in_scope (gimple *stmt)
1850 if (!stmt)
1851 return NULL;
1853 switch (gimple_code (stmt))
1855 case GIMPLE_BIND:
1857 gbind *bind = as_a <gbind *> (stmt);
1858 stmt = gimple_seq_last_stmt (gimple_bind_body (bind));
1859 return last_stmt_in_scope (stmt);
1862 case GIMPLE_TRY:
1864 gtry *try_stmt = as_a <gtry *> (stmt);
1865 stmt = gimple_seq_last_stmt (gimple_try_eval (try_stmt));
1866 gimple *last_eval = last_stmt_in_scope (stmt);
1867 if (gimple_stmt_may_fallthru (last_eval)
1868 && (last_eval == NULL
1869 || !gimple_call_internal_p (last_eval, IFN_FALLTHROUGH))
1870 && gimple_try_kind (try_stmt) == GIMPLE_TRY_FINALLY)
1872 stmt = gimple_seq_last_stmt (gimple_try_cleanup (try_stmt));
1873 return last_stmt_in_scope (stmt);
1875 else
1876 return last_eval;
1879 default:
1880 return stmt;
1884 /* Collect interesting labels in LABELS and return the statement preceding
1885 another case label, or a user-defined label. */
1887 static gimple *
1888 collect_fallthrough_labels (gimple_stmt_iterator *gsi_p,
1889 auto_vec <struct label_entry> *labels)
1891 gimple *prev = NULL;
1895 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND
1896 || gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_TRY)
1898 /* Nested scope. Only look at the last statement of
1899 the innermost scope. */
1900 location_t bind_loc = gimple_location (gsi_stmt (*gsi_p));
1901 gimple *last = last_stmt_in_scope (gsi_stmt (*gsi_p));
1902 if (last)
1904 prev = last;
1905 /* It might be a label without a location. Use the
1906 location of the scope then. */
1907 if (!gimple_has_location (prev))
1908 gimple_set_location (prev, bind_loc);
1910 gsi_next (gsi_p);
1911 continue;
1914 /* Ifs are tricky. */
1915 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_COND)
1917 gcond *cond_stmt = as_a <gcond *> (gsi_stmt (*gsi_p));
1918 tree false_lab = gimple_cond_false_label (cond_stmt);
1919 location_t if_loc = gimple_location (cond_stmt);
1921 /* If we have e.g.
1922 if (i > 1) goto <D.2259>; else goto D;
1923 we can't do much with the else-branch. */
1924 if (!DECL_ARTIFICIAL (false_lab))
1925 break;
1927 /* Go on until the false label, then one step back. */
1928 for (; !gsi_end_p (*gsi_p); gsi_next (gsi_p))
1930 gimple *stmt = gsi_stmt (*gsi_p);
1931 if (gimple_code (stmt) == GIMPLE_LABEL
1932 && gimple_label_label (as_a <glabel *> (stmt)) == false_lab)
1933 break;
1936 /* Not found? Oops. */
1937 if (gsi_end_p (*gsi_p))
1938 break;
1940 struct label_entry l = { false_lab, if_loc };
1941 labels->safe_push (l);
1943 /* Go to the last statement of the then branch. */
1944 gsi_prev (gsi_p);
1946 /* if (i != 0) goto <D.1759>; else goto <D.1760>;
1947 <D.1759>:
1948 <stmt>;
1949 goto <D.1761>;
1950 <D.1760>:
1952 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_GOTO
1953 && !gimple_has_location (gsi_stmt (*gsi_p)))
1955 /* Look at the statement before, it might be
1956 attribute fallthrough, in which case don't warn. */
1957 gsi_prev (gsi_p);
1958 bool fallthru_before_dest
1959 = gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_FALLTHROUGH);
1960 gsi_next (gsi_p);
1961 tree goto_dest = gimple_goto_dest (gsi_stmt (*gsi_p));
1962 if (!fallthru_before_dest)
1964 struct label_entry l = { goto_dest, if_loc };
1965 labels->safe_push (l);
1968 /* And move back. */
1969 gsi_next (gsi_p);
1972 /* Remember the last statement. Skip labels that are of no interest
1973 to us. */
1974 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
1976 tree label = gimple_label_label (as_a <glabel *> (gsi_stmt (*gsi_p)));
1977 if (find_label_entry (labels, label))
1978 prev = gsi_stmt (*gsi_p);
1980 else if (gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_ASAN_MARK))
1982 else
1983 prev = gsi_stmt (*gsi_p);
1984 gsi_next (gsi_p);
1986 while (!gsi_end_p (*gsi_p)
1987 /* Stop if we find a case or a user-defined label. */
1988 && (gimple_code (gsi_stmt (*gsi_p)) != GIMPLE_LABEL
1989 || !gimple_has_location (gsi_stmt (*gsi_p))));
1991 return prev;
1994 /* Return true if the switch fallthough warning should occur. LABEL is
1995 the label statement that we're falling through to. */
1997 static bool
1998 should_warn_for_implicit_fallthrough (gimple_stmt_iterator *gsi_p, tree label)
2000 gimple_stmt_iterator gsi = *gsi_p;
2002 /* Don't warn if the label is marked with a "falls through" comment. */
2003 if (FALLTHROUGH_LABEL_P (label))
2004 return false;
2006 /* Don't warn for non-case labels followed by a statement:
2007 case 0:
2008 foo ();
2009 label:
2010 bar ();
2011 as these are likely intentional. */
2012 if (!case_label_p (&gimplify_ctxp->case_labels, label))
2014 tree l;
2015 while (!gsi_end_p (gsi)
2016 && gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
2017 && (l = gimple_label_label (as_a <glabel *> (gsi_stmt (gsi))))
2018 && !case_label_p (&gimplify_ctxp->case_labels, l))
2019 gsi_next (&gsi);
2020 if (gsi_end_p (gsi) || gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL)
2021 return false;
2024 /* Don't warn for terminated branches, i.e. when the subsequent case labels
2025 immediately breaks. */
2026 gsi = *gsi_p;
2028 /* Skip all immediately following labels. */
2029 while (!gsi_end_p (gsi) && gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL)
2030 gsi_next (&gsi);
2032 /* { ... something; default:; } */
2033 if (gsi_end_p (gsi)
2034 /* { ... something; default: break; } or
2035 { ... something; default: goto L; } */
2036 || gimple_code (gsi_stmt (gsi)) == GIMPLE_GOTO
2037 /* { ... something; default: return; } */
2038 || gimple_code (gsi_stmt (gsi)) == GIMPLE_RETURN)
2039 return false;
2041 return true;
2044 /* Callback for walk_gimple_seq. */
2046 static tree
2047 warn_implicit_fallthrough_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
2048 struct walk_stmt_info *)
2050 gimple *stmt = gsi_stmt (*gsi_p);
2052 *handled_ops_p = true;
2053 switch (gimple_code (stmt))
2055 case GIMPLE_TRY:
2056 case GIMPLE_BIND:
2057 case GIMPLE_CATCH:
2058 case GIMPLE_EH_FILTER:
2059 case GIMPLE_TRANSACTION:
2060 /* Walk the sub-statements. */
2061 *handled_ops_p = false;
2062 break;
2064 /* Find a sequence of form:
2066 GIMPLE_LABEL
2067 [...]
2068 <may fallthru stmt>
2069 GIMPLE_LABEL
2071 and possibly warn. */
2072 case GIMPLE_LABEL:
2074 /* Found a label. Skip all immediately following labels. */
2075 while (!gsi_end_p (*gsi_p)
2076 && gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
2077 gsi_next (gsi_p);
2079 /* There might be no more statements. */
2080 if (gsi_end_p (*gsi_p))
2081 return integer_zero_node;
2083 /* Vector of labels that fall through. */
2084 auto_vec <struct label_entry> labels;
2085 gimple *prev = collect_fallthrough_labels (gsi_p, &labels);
2087 /* There might be no more statements. */
2088 if (gsi_end_p (*gsi_p))
2089 return integer_zero_node;
2091 gimple *next = gsi_stmt (*gsi_p);
2092 tree label;
2093 /* If what follows is a label, then we may have a fallthrough. */
2094 if (gimple_code (next) == GIMPLE_LABEL
2095 && gimple_has_location (next)
2096 && (label = gimple_label_label (as_a <glabel *> (next)))
2097 && prev != NULL)
2099 struct label_entry *l;
2100 bool warned_p = false;
2101 if (!should_warn_for_implicit_fallthrough (gsi_p, label))
2102 /* Quiet. */;
2103 else if (gimple_code (prev) == GIMPLE_LABEL
2104 && (label = gimple_label_label (as_a <glabel *> (prev)))
2105 && (l = find_label_entry (&labels, label)))
2106 warned_p = warning_at (l->loc, OPT_Wimplicit_fallthrough_,
2107 "this statement may fall through");
2108 else if (!gimple_call_internal_p (prev, IFN_FALLTHROUGH)
2109 /* Try to be clever and don't warn when the statement
2110 can't actually fall through. */
2111 && gimple_stmt_may_fallthru (prev)
2112 && gimple_has_location (prev))
2113 warned_p = warning_at (gimple_location (prev),
2114 OPT_Wimplicit_fallthrough_,
2115 "this statement may fall through");
2116 if (warned_p)
2117 inform (gimple_location (next), "here");
2119 /* Mark this label as processed so as to prevent multiple
2120 warnings in nested switches. */
2121 FALLTHROUGH_LABEL_P (label) = true;
2123 /* So that next warn_implicit_fallthrough_r will start looking for
2124 a new sequence starting with this label. */
2125 gsi_prev (gsi_p);
2128 break;
2129 default:
2130 break;
2132 return NULL_TREE;
2135 /* Warn when a switch case falls through. */
2137 static void
2138 maybe_warn_implicit_fallthrough (gimple_seq seq)
2140 if (!warn_implicit_fallthrough)
2141 return;
2143 /* This warning is meant for C/C++/ObjC/ObjC++ only. */
2144 if (!(lang_GNU_C ()
2145 || lang_GNU_CXX ()
2146 || lang_GNU_OBJC ()))
2147 return;
2149 struct walk_stmt_info wi;
2150 memset (&wi, 0, sizeof (wi));
2151 walk_gimple_seq (seq, warn_implicit_fallthrough_r, NULL, &wi);
2154 /* Callback for walk_gimple_seq. */
2156 static tree
2157 expand_FALLTHROUGH_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
2158 struct walk_stmt_info *)
2160 gimple *stmt = gsi_stmt (*gsi_p);
2162 *handled_ops_p = true;
2163 switch (gimple_code (stmt))
2165 case GIMPLE_TRY:
2166 case GIMPLE_BIND:
2167 case GIMPLE_CATCH:
2168 case GIMPLE_EH_FILTER:
2169 case GIMPLE_TRANSACTION:
2170 /* Walk the sub-statements. */
2171 *handled_ops_p = false;
2172 break;
2173 case GIMPLE_CALL:
2174 if (gimple_call_internal_p (stmt, IFN_FALLTHROUGH))
2176 gsi_remove (gsi_p, true);
2177 if (gsi_end_p (*gsi_p))
2178 return integer_zero_node;
2180 bool found = false;
2181 location_t loc = gimple_location (stmt);
2183 gimple_stmt_iterator gsi2 = *gsi_p;
2184 stmt = gsi_stmt (gsi2);
2185 if (gimple_code (stmt) == GIMPLE_GOTO && !gimple_has_location (stmt))
2187 /* Go on until the artificial label. */
2188 tree goto_dest = gimple_goto_dest (stmt);
2189 for (; !gsi_end_p (gsi2); gsi_next (&gsi2))
2191 if (gimple_code (gsi_stmt (gsi2)) == GIMPLE_LABEL
2192 && gimple_label_label (as_a <glabel *> (gsi_stmt (gsi2)))
2193 == goto_dest)
2194 break;
2197 /* Not found? Stop. */
2198 if (gsi_end_p (gsi2))
2199 break;
2201 /* Look one past it. */
2202 gsi_next (&gsi2);
2205 /* We're looking for a case label or default label here. */
2206 while (!gsi_end_p (gsi2))
2208 stmt = gsi_stmt (gsi2);
2209 if (gimple_code (stmt) == GIMPLE_LABEL)
2211 tree label = gimple_label_label (as_a <glabel *> (stmt));
2212 if (gimple_has_location (stmt) && DECL_ARTIFICIAL (label))
2214 found = true;
2215 break;
2218 else
2219 /* Something other than a label. That's not expected. */
2220 break;
2221 gsi_next (&gsi2);
2223 if (!found)
2224 warning_at (loc, 0, "attribute %<fallthrough%> not preceding "
2225 "a case label or default label");
2227 break;
2228 default:
2229 break;
2231 return NULL_TREE;
2234 /* Expand all FALLTHROUGH () calls in SEQ. */
2236 static void
2237 expand_FALLTHROUGH (gimple_seq *seq_p)
2239 struct walk_stmt_info wi;
2240 memset (&wi, 0, sizeof (wi));
2241 walk_gimple_seq_mod (seq_p, expand_FALLTHROUGH_r, NULL, &wi);
2245 /* Gimplify a SWITCH_EXPR, and collect the vector of labels it can
2246 branch to. */
2248 static enum gimplify_status
2249 gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p)
2251 tree switch_expr = *expr_p;
2252 gimple_seq switch_body_seq = NULL;
2253 enum gimplify_status ret;
2254 tree index_type = TREE_TYPE (switch_expr);
2255 if (index_type == NULL_TREE)
2256 index_type = TREE_TYPE (SWITCH_COND (switch_expr));
2258 ret = gimplify_expr (&SWITCH_COND (switch_expr), pre_p, NULL, is_gimple_val,
2259 fb_rvalue);
2260 if (ret == GS_ERROR || ret == GS_UNHANDLED)
2261 return ret;
2263 if (SWITCH_BODY (switch_expr))
2265 vec<tree> labels;
2266 vec<tree> saved_labels;
2267 hash_set<tree> *saved_live_switch_vars = NULL;
2268 tree default_case = NULL_TREE;
2269 gswitch *switch_stmt;
2271 /* If someone can be bothered to fill in the labels, they can
2272 be bothered to null out the body too. */
2273 gcc_assert (!SWITCH_LABELS (switch_expr));
2275 /* Save old labels, get new ones from body, then restore the old
2276 labels. Save all the things from the switch body to append after. */
2277 saved_labels = gimplify_ctxp->case_labels;
2278 gimplify_ctxp->case_labels.create (8);
2280 /* Do not create live_switch_vars if SWITCH_BODY is not a BIND_EXPR. */
2281 saved_live_switch_vars = gimplify_ctxp->live_switch_vars;
2282 tree_code body_type = TREE_CODE (SWITCH_BODY (switch_expr));
2283 if (body_type == BIND_EXPR || body_type == STATEMENT_LIST)
2284 gimplify_ctxp->live_switch_vars = new hash_set<tree> (4);
2285 else
2286 gimplify_ctxp->live_switch_vars = NULL;
2288 bool old_in_switch_expr = gimplify_ctxp->in_switch_expr;
2289 gimplify_ctxp->in_switch_expr = true;
2291 gimplify_stmt (&SWITCH_BODY (switch_expr), &switch_body_seq);
2293 gimplify_ctxp->in_switch_expr = old_in_switch_expr;
2294 maybe_warn_switch_unreachable (switch_body_seq);
2295 maybe_warn_implicit_fallthrough (switch_body_seq);
2296 /* Only do this for the outermost GIMPLE_SWITCH. */
2297 if (!gimplify_ctxp->in_switch_expr)
2298 expand_FALLTHROUGH (&switch_body_seq);
2300 labels = gimplify_ctxp->case_labels;
2301 gimplify_ctxp->case_labels = saved_labels;
2303 if (gimplify_ctxp->live_switch_vars)
2305 gcc_assert (gimplify_ctxp->live_switch_vars->elements () == 0);
2306 delete gimplify_ctxp->live_switch_vars;
2308 gimplify_ctxp->live_switch_vars = saved_live_switch_vars;
2310 preprocess_case_label_vec_for_gimple (labels, index_type,
2311 &default_case);
2313 if (!default_case)
2315 glabel *new_default;
2317 default_case
2318 = build_case_label (NULL_TREE, NULL_TREE,
2319 create_artificial_label (UNKNOWN_LOCATION));
2320 new_default = gimple_build_label (CASE_LABEL (default_case));
2321 gimplify_seq_add_stmt (&switch_body_seq, new_default);
2324 switch_stmt = gimple_build_switch (SWITCH_COND (switch_expr),
2325 default_case, labels);
2326 gimplify_seq_add_stmt (pre_p, switch_stmt);
2327 gimplify_seq_add_seq (pre_p, switch_body_seq);
2328 labels.release ();
2330 else
2331 gcc_assert (SWITCH_LABELS (switch_expr));
2333 return GS_ALL_DONE;
2336 /* Gimplify the LABEL_EXPR pointed to by EXPR_P. */
2338 static enum gimplify_status
2339 gimplify_label_expr (tree *expr_p, gimple_seq *pre_p)
2341 gcc_assert (decl_function_context (LABEL_EXPR_LABEL (*expr_p))
2342 == current_function_decl);
2344 glabel *label_stmt = gimple_build_label (LABEL_EXPR_LABEL (*expr_p));
2345 gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
2346 gimplify_seq_add_stmt (pre_p, label_stmt);
2348 return GS_ALL_DONE;
2351 /* Gimplify the CASE_LABEL_EXPR pointed to by EXPR_P. */
2353 static enum gimplify_status
2354 gimplify_case_label_expr (tree *expr_p, gimple_seq *pre_p)
2356 struct gimplify_ctx *ctxp;
2357 glabel *label_stmt;
2359 /* Invalid programs can play Duff's Device type games with, for example,
2360 #pragma omp parallel. At least in the C front end, we don't
2361 detect such invalid branches until after gimplification, in the
2362 diagnose_omp_blocks pass. */
2363 for (ctxp = gimplify_ctxp; ; ctxp = ctxp->prev_context)
2364 if (ctxp->case_labels.exists ())
2365 break;
2367 label_stmt = gimple_build_label (CASE_LABEL (*expr_p));
2368 gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
2369 ctxp->case_labels.safe_push (*expr_p);
2370 gimplify_seq_add_stmt (pre_p, label_stmt);
2372 return GS_ALL_DONE;
2375 /* Build a GOTO to the LABEL_DECL pointed to by LABEL_P, building it first
2376 if necessary. */
2378 tree
2379 build_and_jump (tree *label_p)
2381 if (label_p == NULL)
2382 /* If there's nowhere to jump, just fall through. */
2383 return NULL_TREE;
2385 if (*label_p == NULL_TREE)
2387 tree label = create_artificial_label (UNKNOWN_LOCATION);
2388 *label_p = label;
2391 return build1 (GOTO_EXPR, void_type_node, *label_p);
2394 /* Gimplify an EXIT_EXPR by converting to a GOTO_EXPR inside a COND_EXPR.
2395 This also involves building a label to jump to and communicating it to
2396 gimplify_loop_expr through gimplify_ctxp->exit_label. */
2398 static enum gimplify_status
2399 gimplify_exit_expr (tree *expr_p)
2401 tree cond = TREE_OPERAND (*expr_p, 0);
2402 tree expr;
2404 expr = build_and_jump (&gimplify_ctxp->exit_label);
2405 expr = build3 (COND_EXPR, void_type_node, cond, expr, NULL_TREE);
2406 *expr_p = expr;
2408 return GS_OK;
2411 /* *EXPR_P is a COMPONENT_REF being used as an rvalue. If its type is
2412 different from its canonical type, wrap the whole thing inside a
2413 NOP_EXPR and force the type of the COMPONENT_REF to be the canonical
2414 type.
2416 The canonical type of a COMPONENT_REF is the type of the field being
2417 referenced--unless the field is a bit-field which can be read directly
2418 in a smaller mode, in which case the canonical type is the
2419 sign-appropriate type corresponding to that mode. */
2421 static void
2422 canonicalize_component_ref (tree *expr_p)
2424 tree expr = *expr_p;
2425 tree type;
2427 gcc_assert (TREE_CODE (expr) == COMPONENT_REF);
2429 if (INTEGRAL_TYPE_P (TREE_TYPE (expr)))
2430 type = TREE_TYPE (get_unwidened (expr, NULL_TREE));
2431 else
2432 type = TREE_TYPE (TREE_OPERAND (expr, 1));
2434 /* One could argue that all the stuff below is not necessary for
2435 the non-bitfield case and declare it a FE error if type
2436 adjustment would be needed. */
2437 if (TREE_TYPE (expr) != type)
2439 #ifdef ENABLE_TYPES_CHECKING
2440 tree old_type = TREE_TYPE (expr);
2441 #endif
2442 int type_quals;
2444 /* We need to preserve qualifiers and propagate them from
2445 operand 0. */
2446 type_quals = TYPE_QUALS (type)
2447 | TYPE_QUALS (TREE_TYPE (TREE_OPERAND (expr, 0)));
2448 if (TYPE_QUALS (type) != type_quals)
2449 type = build_qualified_type (TYPE_MAIN_VARIANT (type), type_quals);
2451 /* Set the type of the COMPONENT_REF to the underlying type. */
2452 TREE_TYPE (expr) = type;
2454 #ifdef ENABLE_TYPES_CHECKING
2455 /* It is now a FE error, if the conversion from the canonical
2456 type to the original expression type is not useless. */
2457 gcc_assert (useless_type_conversion_p (old_type, type));
2458 #endif
2462 /* If a NOP conversion is changing a pointer to array of foo to a pointer
2463 to foo, embed that change in the ADDR_EXPR by converting
2464 T array[U];
2465 (T *)&array
2467 &array[L]
2468 where L is the lower bound. For simplicity, only do this for constant
2469 lower bound.
2470 The constraint is that the type of &array[L] is trivially convertible
2471 to T *. */
2473 static void
2474 canonicalize_addr_expr (tree *expr_p)
2476 tree expr = *expr_p;
2477 tree addr_expr = TREE_OPERAND (expr, 0);
2478 tree datype, ddatype, pddatype;
2480 /* We simplify only conversions from an ADDR_EXPR to a pointer type. */
2481 if (!POINTER_TYPE_P (TREE_TYPE (expr))
2482 || TREE_CODE (addr_expr) != ADDR_EXPR)
2483 return;
2485 /* The addr_expr type should be a pointer to an array. */
2486 datype = TREE_TYPE (TREE_TYPE (addr_expr));
2487 if (TREE_CODE (datype) != ARRAY_TYPE)
2488 return;
2490 /* The pointer to element type shall be trivially convertible to
2491 the expression pointer type. */
2492 ddatype = TREE_TYPE (datype);
2493 pddatype = build_pointer_type (ddatype);
2494 if (!useless_type_conversion_p (TYPE_MAIN_VARIANT (TREE_TYPE (expr)),
2495 pddatype))
2496 return;
2498 /* The lower bound and element sizes must be constant. */
2499 if (!TYPE_SIZE_UNIT (ddatype)
2500 || TREE_CODE (TYPE_SIZE_UNIT (ddatype)) != INTEGER_CST
2501 || !TYPE_DOMAIN (datype) || !TYPE_MIN_VALUE (TYPE_DOMAIN (datype))
2502 || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (datype))) != INTEGER_CST)
2503 return;
2505 /* All checks succeeded. Build a new node to merge the cast. */
2506 *expr_p = build4 (ARRAY_REF, ddatype, TREE_OPERAND (addr_expr, 0),
2507 TYPE_MIN_VALUE (TYPE_DOMAIN (datype)),
2508 NULL_TREE, NULL_TREE);
2509 *expr_p = build1 (ADDR_EXPR, pddatype, *expr_p);
2511 /* We can have stripped a required restrict qualifier above. */
2512 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
2513 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
2516 /* *EXPR_P is a NOP_EXPR or CONVERT_EXPR. Remove it and/or other conversions
2517 underneath as appropriate. */
2519 static enum gimplify_status
2520 gimplify_conversion (tree *expr_p)
2522 location_t loc = EXPR_LOCATION (*expr_p);
2523 gcc_assert (CONVERT_EXPR_P (*expr_p));
2525 /* Then strip away all but the outermost conversion. */
2526 STRIP_SIGN_NOPS (TREE_OPERAND (*expr_p, 0));
2528 /* And remove the outermost conversion if it's useless. */
2529 if (tree_ssa_useless_type_conversion (*expr_p))
2530 *expr_p = TREE_OPERAND (*expr_p, 0);
2532 /* If we still have a conversion at the toplevel,
2533 then canonicalize some constructs. */
2534 if (CONVERT_EXPR_P (*expr_p))
2536 tree sub = TREE_OPERAND (*expr_p, 0);
2538 /* If a NOP conversion is changing the type of a COMPONENT_REF
2539 expression, then canonicalize its type now in order to expose more
2540 redundant conversions. */
2541 if (TREE_CODE (sub) == COMPONENT_REF)
2542 canonicalize_component_ref (&TREE_OPERAND (*expr_p, 0));
2544 /* If a NOP conversion is changing a pointer to array of foo
2545 to a pointer to foo, embed that change in the ADDR_EXPR. */
2546 else if (TREE_CODE (sub) == ADDR_EXPR)
2547 canonicalize_addr_expr (expr_p);
2550 /* If we have a conversion to a non-register type force the
2551 use of a VIEW_CONVERT_EXPR instead. */
2552 if (CONVERT_EXPR_P (*expr_p) && !is_gimple_reg_type (TREE_TYPE (*expr_p)))
2553 *expr_p = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (*expr_p),
2554 TREE_OPERAND (*expr_p, 0));
2556 /* Canonicalize CONVERT_EXPR to NOP_EXPR. */
2557 if (TREE_CODE (*expr_p) == CONVERT_EXPR)
2558 TREE_SET_CODE (*expr_p, NOP_EXPR);
2560 return GS_OK;
2563 /* Nonlocal VLAs seen in the current function. */
2564 static hash_set<tree> *nonlocal_vlas;
2566 /* The VAR_DECLs created for nonlocal VLAs for debug info purposes. */
2567 static tree nonlocal_vla_vars;
2569 /* Gimplify a VAR_DECL or PARM_DECL. Return GS_OK if we expanded a
2570 DECL_VALUE_EXPR, and it's worth re-examining things. */
2572 static enum gimplify_status
2573 gimplify_var_or_parm_decl (tree *expr_p)
2575 tree decl = *expr_p;
2577 /* ??? If this is a local variable, and it has not been seen in any
2578 outer BIND_EXPR, then it's probably the result of a duplicate
2579 declaration, for which we've already issued an error. It would
2580 be really nice if the front end wouldn't leak these at all.
2581 Currently the only known culprit is C++ destructors, as seen
2582 in g++.old-deja/g++.jason/binding.C. */
2583 if (VAR_P (decl)
2584 && !DECL_SEEN_IN_BIND_EXPR_P (decl)
2585 && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl)
2586 && decl_function_context (decl) == current_function_decl)
2588 gcc_assert (seen_error ());
2589 return GS_ERROR;
2592 /* When within an OMP context, notice uses of variables. */
2593 if (gimplify_omp_ctxp && omp_notice_variable (gimplify_omp_ctxp, decl, true))
2594 return GS_ALL_DONE;
2596 /* If the decl is an alias for another expression, substitute it now. */
2597 if (DECL_HAS_VALUE_EXPR_P (decl))
2599 tree value_expr = DECL_VALUE_EXPR (decl);
2601 /* For referenced nonlocal VLAs add a decl for debugging purposes
2602 to the current function. */
2603 if (VAR_P (decl)
2604 && TREE_CODE (DECL_SIZE_UNIT (decl)) != INTEGER_CST
2605 && nonlocal_vlas != NULL
2606 && TREE_CODE (value_expr) == INDIRECT_REF
2607 && TREE_CODE (TREE_OPERAND (value_expr, 0)) == VAR_DECL
2608 && decl_function_context (decl) != current_function_decl)
2610 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
2611 while (ctx
2612 && (ctx->region_type == ORT_WORKSHARE
2613 || ctx->region_type == ORT_SIMD
2614 || ctx->region_type == ORT_ACC))
2615 ctx = ctx->outer_context;
2616 if (!ctx && !nonlocal_vlas->add (decl))
2618 tree copy = copy_node (decl);
2620 lang_hooks.dup_lang_specific_decl (copy);
2621 SET_DECL_RTL (copy, 0);
2622 TREE_USED (copy) = 1;
2623 DECL_CHAIN (copy) = nonlocal_vla_vars;
2624 nonlocal_vla_vars = copy;
2625 SET_DECL_VALUE_EXPR (copy, unshare_expr (value_expr));
2626 DECL_HAS_VALUE_EXPR_P (copy) = 1;
2630 *expr_p = unshare_expr (value_expr);
2631 return GS_OK;
2634 return GS_ALL_DONE;
2637 /* Recalculate the value of the TREE_SIDE_EFFECTS flag for T. */
2639 static void
2640 recalculate_side_effects (tree t)
2642 enum tree_code code = TREE_CODE (t);
2643 int len = TREE_OPERAND_LENGTH (t);
2644 int i;
2646 switch (TREE_CODE_CLASS (code))
2648 case tcc_expression:
2649 switch (code)
2651 case INIT_EXPR:
2652 case MODIFY_EXPR:
2653 case VA_ARG_EXPR:
2654 case PREDECREMENT_EXPR:
2655 case PREINCREMENT_EXPR:
2656 case POSTDECREMENT_EXPR:
2657 case POSTINCREMENT_EXPR:
2658 /* All of these have side-effects, no matter what their
2659 operands are. */
2660 return;
2662 default:
2663 break;
2665 /* Fall through. */
2667 case tcc_comparison: /* a comparison expression */
2668 case tcc_unary: /* a unary arithmetic expression */
2669 case tcc_binary: /* a binary arithmetic expression */
2670 case tcc_reference: /* a reference */
2671 case tcc_vl_exp: /* a function call */
2672 TREE_SIDE_EFFECTS (t) = TREE_THIS_VOLATILE (t);
2673 for (i = 0; i < len; ++i)
2675 tree op = TREE_OPERAND (t, i);
2676 if (op && TREE_SIDE_EFFECTS (op))
2677 TREE_SIDE_EFFECTS (t) = 1;
2679 break;
2681 case tcc_constant:
2682 /* No side-effects. */
2683 return;
2685 default:
2686 gcc_unreachable ();
2690 /* Gimplify the COMPONENT_REF, ARRAY_REF, REALPART_EXPR or IMAGPART_EXPR
2691 node *EXPR_P.
2693 compound_lval
2694 : min_lval '[' val ']'
2695 | min_lval '.' ID
2696 | compound_lval '[' val ']'
2697 | compound_lval '.' ID
2699 This is not part of the original SIMPLE definition, which separates
2700 array and member references, but it seems reasonable to handle them
2701 together. Also, this way we don't run into problems with union
2702 aliasing; gcc requires that for accesses through a union to alias, the
2703 union reference must be explicit, which was not always the case when we
2704 were splitting up array and member refs.
2706 PRE_P points to the sequence where side effects that must happen before
2707 *EXPR_P should be stored.
2709 POST_P points to the sequence where side effects that must happen after
2710 *EXPR_P should be stored. */
2712 static enum gimplify_status
2713 gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
2714 fallback_t fallback)
2716 tree *p;
2717 enum gimplify_status ret = GS_ALL_DONE, tret;
2718 int i;
2719 location_t loc = EXPR_LOCATION (*expr_p);
2720 tree expr = *expr_p;
2722 /* Create a stack of the subexpressions so later we can walk them in
2723 order from inner to outer. */
2724 auto_vec<tree, 10> expr_stack;
2726 /* We can handle anything that get_inner_reference can deal with. */
2727 for (p = expr_p; ; p = &TREE_OPERAND (*p, 0))
2729 restart:
2730 /* Fold INDIRECT_REFs now to turn them into ARRAY_REFs. */
2731 if (TREE_CODE (*p) == INDIRECT_REF)
2732 *p = fold_indirect_ref_loc (loc, *p);
2734 if (handled_component_p (*p))
2736 /* Expand DECL_VALUE_EXPR now. In some cases that may expose
2737 additional COMPONENT_REFs. */
2738 else if ((VAR_P (*p) || TREE_CODE (*p) == PARM_DECL)
2739 && gimplify_var_or_parm_decl (p) == GS_OK)
2740 goto restart;
2741 else
2742 break;
2744 expr_stack.safe_push (*p);
2747 gcc_assert (expr_stack.length ());
2749 /* Now EXPR_STACK is a stack of pointers to all the refs we've
2750 walked through and P points to the innermost expression.
2752 Java requires that we elaborated nodes in source order. That
2753 means we must gimplify the inner expression followed by each of
2754 the indices, in order. But we can't gimplify the inner
2755 expression until we deal with any variable bounds, sizes, or
2756 positions in order to deal with PLACEHOLDER_EXPRs.
2758 So we do this in three steps. First we deal with the annotations
2759 for any variables in the components, then we gimplify the base,
2760 then we gimplify any indices, from left to right. */
2761 for (i = expr_stack.length () - 1; i >= 0; i--)
2763 tree t = expr_stack[i];
2765 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
2767 /* Gimplify the low bound and element type size and put them into
2768 the ARRAY_REF. If these values are set, they have already been
2769 gimplified. */
2770 if (TREE_OPERAND (t, 2) == NULL_TREE)
2772 tree low = unshare_expr (array_ref_low_bound (t));
2773 if (!is_gimple_min_invariant (low))
2775 TREE_OPERAND (t, 2) = low;
2776 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
2777 post_p, is_gimple_reg,
2778 fb_rvalue);
2779 ret = MIN (ret, tret);
2782 else
2784 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
2785 is_gimple_reg, fb_rvalue);
2786 ret = MIN (ret, tret);
2789 if (TREE_OPERAND (t, 3) == NULL_TREE)
2791 tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0)));
2792 tree elmt_size = unshare_expr (array_ref_element_size (t));
2793 tree factor = size_int (TYPE_ALIGN_UNIT (elmt_type));
2795 /* Divide the element size by the alignment of the element
2796 type (above). */
2797 elmt_size
2798 = size_binop_loc (loc, EXACT_DIV_EXPR, elmt_size, factor);
2800 if (!is_gimple_min_invariant (elmt_size))
2802 TREE_OPERAND (t, 3) = elmt_size;
2803 tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p,
2804 post_p, is_gimple_reg,
2805 fb_rvalue);
2806 ret = MIN (ret, tret);
2809 else
2811 tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p, post_p,
2812 is_gimple_reg, fb_rvalue);
2813 ret = MIN (ret, tret);
2816 else if (TREE_CODE (t) == COMPONENT_REF)
2818 /* Set the field offset into T and gimplify it. */
2819 if (TREE_OPERAND (t, 2) == NULL_TREE)
2821 tree offset = unshare_expr (component_ref_field_offset (t));
2822 tree field = TREE_OPERAND (t, 1);
2823 tree factor
2824 = size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT);
2826 /* Divide the offset by its alignment. */
2827 offset = size_binop_loc (loc, EXACT_DIV_EXPR, offset, factor);
2829 if (!is_gimple_min_invariant (offset))
2831 TREE_OPERAND (t, 2) = offset;
2832 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
2833 post_p, is_gimple_reg,
2834 fb_rvalue);
2835 ret = MIN (ret, tret);
2838 else
2840 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
2841 is_gimple_reg, fb_rvalue);
2842 ret = MIN (ret, tret);
2847 /* Step 2 is to gimplify the base expression. Make sure lvalue is set
2848 so as to match the min_lval predicate. Failure to do so may result
2849 in the creation of large aggregate temporaries. */
2850 tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval,
2851 fallback | fb_lvalue);
2852 ret = MIN (ret, tret);
2854 /* And finally, the indices and operands of ARRAY_REF. During this
2855 loop we also remove any useless conversions. */
2856 for (; expr_stack.length () > 0; )
2858 tree t = expr_stack.pop ();
2860 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
2862 /* Gimplify the dimension. */
2863 if (!is_gimple_min_invariant (TREE_OPERAND (t, 1)))
2865 tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
2866 is_gimple_val, fb_rvalue);
2867 ret = MIN (ret, tret);
2871 STRIP_USELESS_TYPE_CONVERSION (TREE_OPERAND (t, 0));
2873 /* The innermost expression P may have originally had
2874 TREE_SIDE_EFFECTS set which would have caused all the outer
2875 expressions in *EXPR_P leading to P to also have had
2876 TREE_SIDE_EFFECTS set. */
2877 recalculate_side_effects (t);
2880 /* If the outermost expression is a COMPONENT_REF, canonicalize its type. */
2881 if ((fallback & fb_rvalue) && TREE_CODE (*expr_p) == COMPONENT_REF)
2883 canonicalize_component_ref (expr_p);
2886 expr_stack.release ();
2888 gcc_assert (*expr_p == expr || ret != GS_ALL_DONE);
2890 return ret;
2893 /* Gimplify the self modifying expression pointed to by EXPR_P
2894 (++, --, +=, -=).
2896 PRE_P points to the list where side effects that must happen before
2897 *EXPR_P should be stored.
2899 POST_P points to the list where side effects that must happen after
2900 *EXPR_P should be stored.
2902 WANT_VALUE is nonzero iff we want to use the value of this expression
2903 in another expression.
2905 ARITH_TYPE is the type the computation should be performed in. */
2907 enum gimplify_status
2908 gimplify_self_mod_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
2909 bool want_value, tree arith_type)
2911 enum tree_code code;
2912 tree lhs, lvalue, rhs, t1;
2913 gimple_seq post = NULL, *orig_post_p = post_p;
2914 bool postfix;
2915 enum tree_code arith_code;
2916 enum gimplify_status ret;
2917 location_t loc = EXPR_LOCATION (*expr_p);
2919 code = TREE_CODE (*expr_p);
2921 gcc_assert (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR
2922 || code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR);
2924 /* Prefix or postfix? */
2925 if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
2926 /* Faster to treat as prefix if result is not used. */
2927 postfix = want_value;
2928 else
2929 postfix = false;
2931 /* For postfix, make sure the inner expression's post side effects
2932 are executed after side effects from this expression. */
2933 if (postfix)
2934 post_p = &post;
2936 /* Add or subtract? */
2937 if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
2938 arith_code = PLUS_EXPR;
2939 else
2940 arith_code = MINUS_EXPR;
2942 /* Gimplify the LHS into a GIMPLE lvalue. */
2943 lvalue = TREE_OPERAND (*expr_p, 0);
2944 ret = gimplify_expr (&lvalue, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
2945 if (ret == GS_ERROR)
2946 return ret;
2948 /* Extract the operands to the arithmetic operation. */
2949 lhs = lvalue;
2950 rhs = TREE_OPERAND (*expr_p, 1);
2952 /* For postfix operator, we evaluate the LHS to an rvalue and then use
2953 that as the result value and in the postqueue operation. */
2954 if (postfix)
2956 ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue);
2957 if (ret == GS_ERROR)
2958 return ret;
2960 lhs = get_initialized_tmp_var (lhs, pre_p, NULL);
2963 /* For POINTERs increment, use POINTER_PLUS_EXPR. */
2964 if (POINTER_TYPE_P (TREE_TYPE (lhs)))
2966 rhs = convert_to_ptrofftype_loc (loc, rhs);
2967 if (arith_code == MINUS_EXPR)
2968 rhs = fold_build1_loc (loc, NEGATE_EXPR, TREE_TYPE (rhs), rhs);
2969 t1 = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (*expr_p), lhs, rhs);
2971 else
2972 t1 = fold_convert (TREE_TYPE (*expr_p),
2973 fold_build2 (arith_code, arith_type,
2974 fold_convert (arith_type, lhs),
2975 fold_convert (arith_type, rhs)));
2977 if (postfix)
2979 gimplify_assign (lvalue, t1, pre_p);
2980 gimplify_seq_add_seq (orig_post_p, post);
2981 *expr_p = lhs;
2982 return GS_ALL_DONE;
2984 else
2986 *expr_p = build2 (MODIFY_EXPR, TREE_TYPE (lvalue), lvalue, t1);
2987 return GS_OK;
2991 /* If *EXPR_P has a variable sized type, wrap it in a WITH_SIZE_EXPR. */
2993 static void
2994 maybe_with_size_expr (tree *expr_p)
2996 tree expr = *expr_p;
2997 tree type = TREE_TYPE (expr);
2998 tree size;
3000 /* If we've already wrapped this or the type is error_mark_node, we can't do
3001 anything. */
3002 if (TREE_CODE (expr) == WITH_SIZE_EXPR
3003 || type == error_mark_node)
3004 return;
3006 /* If the size isn't known or is a constant, we have nothing to do. */
3007 size = TYPE_SIZE_UNIT (type);
3008 if (!size || TREE_CODE (size) == INTEGER_CST)
3009 return;
3011 /* Otherwise, make a WITH_SIZE_EXPR. */
3012 size = unshare_expr (size);
3013 size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, expr);
3014 *expr_p = build2 (WITH_SIZE_EXPR, type, expr, size);
3017 /* Helper for gimplify_call_expr. Gimplify a single argument *ARG_P
3018 Store any side-effects in PRE_P. CALL_LOCATION is the location of
3019 the CALL_EXPR. If ALLOW_SSA is set the actual parameter may be
3020 gimplified to an SSA name. */
3022 enum gimplify_status
3023 gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location,
3024 bool allow_ssa)
3026 bool (*test) (tree);
3027 fallback_t fb;
3029 /* In general, we allow lvalues for function arguments to avoid
3030 extra overhead of copying large aggregates out of even larger
3031 aggregates into temporaries only to copy the temporaries to
3032 the argument list. Make optimizers happy by pulling out to
3033 temporaries those types that fit in registers. */
3034 if (is_gimple_reg_type (TREE_TYPE (*arg_p)))
3035 test = is_gimple_val, fb = fb_rvalue;
3036 else
3038 test = is_gimple_lvalue, fb = fb_either;
3039 /* Also strip a TARGET_EXPR that would force an extra copy. */
3040 if (TREE_CODE (*arg_p) == TARGET_EXPR)
3042 tree init = TARGET_EXPR_INITIAL (*arg_p);
3043 if (init
3044 && !VOID_TYPE_P (TREE_TYPE (init)))
3045 *arg_p = init;
3049 /* If this is a variable sized type, we must remember the size. */
3050 maybe_with_size_expr (arg_p);
3052 /* FIXME diagnostics: This will mess up gcc.dg/Warray-bounds.c. */
3053 /* Make sure arguments have the same location as the function call
3054 itself. */
3055 protected_set_expr_location (*arg_p, call_location);
3057 /* There is a sequence point before a function call. Side effects in
3058 the argument list must occur before the actual call. So, when
3059 gimplifying arguments, force gimplify_expr to use an internal
3060 post queue which is then appended to the end of PRE_P. */
3061 return gimplify_expr (arg_p, pre_p, NULL, test, fb, allow_ssa);
3064 /* Don't fold inside offloading or taskreg regions: it can break code by
3065 adding decl references that weren't in the source. We'll do it during
3066 omplower pass instead. */
3068 static bool
3069 maybe_fold_stmt (gimple_stmt_iterator *gsi)
3071 struct gimplify_omp_ctx *ctx;
3072 for (ctx = gimplify_omp_ctxp; ctx; ctx = ctx->outer_context)
3073 if ((ctx->region_type & (ORT_TARGET | ORT_PARALLEL | ORT_TASK)) != 0)
3074 return false;
3075 return fold_stmt (gsi);
3078 /* Add a gimple call to __builtin_cilk_detach to GIMPLE sequence PRE_P,
3079 with the pointer to the proper cilk frame. */
3080 static void
3081 gimplify_cilk_detach (gimple_seq *pre_p)
3083 tree frame = cfun->cilk_frame_decl;
3084 tree ptrf = build1 (ADDR_EXPR, cilk_frame_ptr_type_decl,
3085 frame);
3086 gcall *detach = gimple_build_call (cilk_detach_fndecl, 1,
3087 ptrf);
3088 gimplify_seq_add_stmt(pre_p, detach);
3091 /* Gimplify the CALL_EXPR node *EXPR_P into the GIMPLE sequence PRE_P.
3092 WANT_VALUE is true if the result of the call is desired. */
3094 static enum gimplify_status
3095 gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
3097 tree fndecl, parms, p, fnptrtype;
3098 enum gimplify_status ret;
3099 int i, nargs;
3100 gcall *call;
3101 bool builtin_va_start_p = false;
3102 location_t loc = EXPR_LOCATION (*expr_p);
3104 gcc_assert (TREE_CODE (*expr_p) == CALL_EXPR);
3106 /* For reliable diagnostics during inlining, it is necessary that
3107 every call_expr be annotated with file and line. */
3108 if (! EXPR_HAS_LOCATION (*expr_p))
3109 SET_EXPR_LOCATION (*expr_p, input_location);
3111 /* Gimplify internal functions created in the FEs. */
3112 if (CALL_EXPR_FN (*expr_p) == NULL_TREE)
3114 if (want_value)
3115 return GS_ALL_DONE;
3117 nargs = call_expr_nargs (*expr_p);
3118 enum internal_fn ifn = CALL_EXPR_IFN (*expr_p);
3119 auto_vec<tree> vargs (nargs);
3121 for (i = 0; i < nargs; i++)
3123 gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
3124 EXPR_LOCATION (*expr_p));
3125 vargs.quick_push (CALL_EXPR_ARG (*expr_p, i));
3128 if (EXPR_CILK_SPAWN (*expr_p))
3129 gimplify_cilk_detach (pre_p);
3130 gimple *call = gimple_build_call_internal_vec (ifn, vargs);
3131 gimplify_seq_add_stmt (pre_p, call);
3132 return GS_ALL_DONE;
3135 /* This may be a call to a builtin function.
3137 Builtin function calls may be transformed into different
3138 (and more efficient) builtin function calls under certain
3139 circumstances. Unfortunately, gimplification can muck things
3140 up enough that the builtin expanders are not aware that certain
3141 transformations are still valid.
3143 So we attempt transformation/gimplification of the call before
3144 we gimplify the CALL_EXPR. At this time we do not manage to
3145 transform all calls in the same manner as the expanders do, but
3146 we do transform most of them. */
3147 fndecl = get_callee_fndecl (*expr_p);
3148 if (fndecl
3149 && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3150 switch (DECL_FUNCTION_CODE (fndecl))
3152 case BUILT_IN_ALLOCA:
3153 case BUILT_IN_ALLOCA_WITH_ALIGN:
3154 /* If the call has been built for a variable-sized object, then we
3155 want to restore the stack level when the enclosing BIND_EXPR is
3156 exited to reclaim the allocated space; otherwise, we precisely
3157 need to do the opposite and preserve the latest stack level. */
3158 if (CALL_ALLOCA_FOR_VAR_P (*expr_p))
3159 gimplify_ctxp->save_stack = true;
3160 else
3161 gimplify_ctxp->keep_stack = true;
3162 break;
3164 case BUILT_IN_VA_START:
3166 builtin_va_start_p = TRUE;
3167 if (call_expr_nargs (*expr_p) < 2)
3169 error ("too few arguments to function %<va_start%>");
3170 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
3171 return GS_OK;
3174 if (fold_builtin_next_arg (*expr_p, true))
3176 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
3177 return GS_OK;
3179 break;
3182 default:
3185 if (fndecl && DECL_BUILT_IN (fndecl))
3187 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
3188 if (new_tree && new_tree != *expr_p)
3190 /* There was a transformation of this call which computes the
3191 same value, but in a more efficient way. Return and try
3192 again. */
3193 *expr_p = new_tree;
3194 return GS_OK;
3198 /* Remember the original function pointer type. */
3199 fnptrtype = TREE_TYPE (CALL_EXPR_FN (*expr_p));
3201 /* There is a sequence point before the call, so any side effects in
3202 the calling expression must occur before the actual call. Force
3203 gimplify_expr to use an internal post queue. */
3204 ret = gimplify_expr (&CALL_EXPR_FN (*expr_p), pre_p, NULL,
3205 is_gimple_call_addr, fb_rvalue);
3207 nargs = call_expr_nargs (*expr_p);
3209 /* Get argument types for verification. */
3210 fndecl = get_callee_fndecl (*expr_p);
3211 parms = NULL_TREE;
3212 if (fndecl)
3213 parms = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
3214 else
3215 parms = TYPE_ARG_TYPES (TREE_TYPE (fnptrtype));
3217 if (fndecl && DECL_ARGUMENTS (fndecl))
3218 p = DECL_ARGUMENTS (fndecl);
3219 else if (parms)
3220 p = parms;
3221 else
3222 p = NULL_TREE;
3223 for (i = 0; i < nargs && p; i++, p = TREE_CHAIN (p))
3226 /* If the last argument is __builtin_va_arg_pack () and it is not
3227 passed as a named argument, decrease the number of CALL_EXPR
3228 arguments and set instead the CALL_EXPR_VA_ARG_PACK flag. */
3229 if (!p
3230 && i < nargs
3231 && TREE_CODE (CALL_EXPR_ARG (*expr_p, nargs - 1)) == CALL_EXPR)
3233 tree last_arg = CALL_EXPR_ARG (*expr_p, nargs - 1);
3234 tree last_arg_fndecl = get_callee_fndecl (last_arg);
3236 if (last_arg_fndecl
3237 && TREE_CODE (last_arg_fndecl) == FUNCTION_DECL
3238 && DECL_BUILT_IN_CLASS (last_arg_fndecl) == BUILT_IN_NORMAL
3239 && DECL_FUNCTION_CODE (last_arg_fndecl) == BUILT_IN_VA_ARG_PACK)
3241 tree call = *expr_p;
3243 --nargs;
3244 *expr_p = build_call_array_loc (loc, TREE_TYPE (call),
3245 CALL_EXPR_FN (call),
3246 nargs, CALL_EXPR_ARGP (call));
3248 /* Copy all CALL_EXPR flags, location and block, except
3249 CALL_EXPR_VA_ARG_PACK flag. */
3250 CALL_EXPR_STATIC_CHAIN (*expr_p) = CALL_EXPR_STATIC_CHAIN (call);
3251 CALL_EXPR_TAILCALL (*expr_p) = CALL_EXPR_TAILCALL (call);
3252 CALL_EXPR_RETURN_SLOT_OPT (*expr_p)
3253 = CALL_EXPR_RETURN_SLOT_OPT (call);
3254 CALL_FROM_THUNK_P (*expr_p) = CALL_FROM_THUNK_P (call);
3255 SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (call));
3257 /* Set CALL_EXPR_VA_ARG_PACK. */
3258 CALL_EXPR_VA_ARG_PACK (*expr_p) = 1;
3262 /* If the call returns twice then after building the CFG the call
3263 argument computations will no longer dominate the call because
3264 we add an abnormal incoming edge to the call. So do not use SSA
3265 vars there. */
3266 bool returns_twice = call_expr_flags (*expr_p) & ECF_RETURNS_TWICE;
3268 /* Gimplify the function arguments. */
3269 if (nargs > 0)
3271 for (i = (PUSH_ARGS_REVERSED ? nargs - 1 : 0);
3272 PUSH_ARGS_REVERSED ? i >= 0 : i < nargs;
3273 PUSH_ARGS_REVERSED ? i-- : i++)
3275 enum gimplify_status t;
3277 /* Avoid gimplifying the second argument to va_start, which needs to
3278 be the plain PARM_DECL. */
3279 if ((i != 1) || !builtin_va_start_p)
3281 t = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
3282 EXPR_LOCATION (*expr_p), ! returns_twice);
3284 if (t == GS_ERROR)
3285 ret = GS_ERROR;
3290 /* Gimplify the static chain. */
3291 if (CALL_EXPR_STATIC_CHAIN (*expr_p))
3293 if (fndecl && !DECL_STATIC_CHAIN (fndecl))
3294 CALL_EXPR_STATIC_CHAIN (*expr_p) = NULL;
3295 else
3297 enum gimplify_status t;
3298 t = gimplify_arg (&CALL_EXPR_STATIC_CHAIN (*expr_p), pre_p,
3299 EXPR_LOCATION (*expr_p), ! returns_twice);
3300 if (t == GS_ERROR)
3301 ret = GS_ERROR;
3305 /* Verify the function result. */
3306 if (want_value && fndecl
3307 && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fnptrtype))))
3309 error_at (loc, "using result of function returning %<void%>");
3310 ret = GS_ERROR;
3313 /* Try this again in case gimplification exposed something. */
3314 if (ret != GS_ERROR)
3316 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
3318 if (new_tree && new_tree != *expr_p)
3320 /* There was a transformation of this call which computes the
3321 same value, but in a more efficient way. Return and try
3322 again. */
3323 *expr_p = new_tree;
3324 return GS_OK;
3327 else
3329 *expr_p = error_mark_node;
3330 return GS_ERROR;
3333 /* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its
3334 decl. This allows us to eliminate redundant or useless
3335 calls to "const" functions. */
3336 if (TREE_CODE (*expr_p) == CALL_EXPR)
3338 int flags = call_expr_flags (*expr_p);
3339 if (flags & (ECF_CONST | ECF_PURE)
3340 /* An infinite loop is considered a side effect. */
3341 && !(flags & (ECF_LOOPING_CONST_OR_PURE)))
3342 TREE_SIDE_EFFECTS (*expr_p) = 0;
3345 /* If the value is not needed by the caller, emit a new GIMPLE_CALL
3346 and clear *EXPR_P. Otherwise, leave *EXPR_P in its gimplified
3347 form and delegate the creation of a GIMPLE_CALL to
3348 gimplify_modify_expr. This is always possible because when
3349 WANT_VALUE is true, the caller wants the result of this call into
3350 a temporary, which means that we will emit an INIT_EXPR in
3351 internal_get_tmp_var which will then be handled by
3352 gimplify_modify_expr. */
3353 if (!want_value)
3355 /* The CALL_EXPR in *EXPR_P is already in GIMPLE form, so all we
3356 have to do is replicate it as a GIMPLE_CALL tuple. */
3357 gimple_stmt_iterator gsi;
3358 call = gimple_build_call_from_tree (*expr_p);
3359 gimple_call_set_fntype (call, TREE_TYPE (fnptrtype));
3360 notice_special_calls (call);
3361 if (EXPR_CILK_SPAWN (*expr_p))
3362 gimplify_cilk_detach (pre_p);
3363 gimplify_seq_add_stmt (pre_p, call);
3364 gsi = gsi_last (*pre_p);
3365 maybe_fold_stmt (&gsi);
3366 *expr_p = NULL_TREE;
3368 else
3369 /* Remember the original function type. */
3370 CALL_EXPR_FN (*expr_p) = build1 (NOP_EXPR, fnptrtype,
3371 CALL_EXPR_FN (*expr_p));
3373 return ret;
3376 /* Handle shortcut semantics in the predicate operand of a COND_EXPR by
3377 rewriting it into multiple COND_EXPRs, and possibly GOTO_EXPRs.
3379 TRUE_LABEL_P and FALSE_LABEL_P point to the labels to jump to if the
3380 condition is true or false, respectively. If null, we should generate
3381 our own to skip over the evaluation of this specific expression.
3383 LOCUS is the source location of the COND_EXPR.
3385 This function is the tree equivalent of do_jump.
3387 shortcut_cond_r should only be called by shortcut_cond_expr. */
3389 static tree
3390 shortcut_cond_r (tree pred, tree *true_label_p, tree *false_label_p,
3391 location_t locus)
3393 tree local_label = NULL_TREE;
3394 tree t, expr = NULL;
3396 /* OK, it's not a simple case; we need to pull apart the COND_EXPR to
3397 retain the shortcut semantics. Just insert the gotos here;
3398 shortcut_cond_expr will append the real blocks later. */
3399 if (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
3401 location_t new_locus;
3403 /* Turn if (a && b) into
3405 if (a); else goto no;
3406 if (b) goto yes; else goto no;
3407 (no:) */
3409 if (false_label_p == NULL)
3410 false_label_p = &local_label;
3412 /* Keep the original source location on the first 'if'. */
3413 t = shortcut_cond_r (TREE_OPERAND (pred, 0), NULL, false_label_p, locus);
3414 append_to_statement_list (t, &expr);
3416 /* Set the source location of the && on the second 'if'. */
3417 new_locus = EXPR_HAS_LOCATION (pred) ? EXPR_LOCATION (pred) : locus;
3418 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
3419 new_locus);
3420 append_to_statement_list (t, &expr);
3422 else if (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
3424 location_t new_locus;
3426 /* Turn if (a || b) into
3428 if (a) goto yes;
3429 if (b) goto yes; else goto no;
3430 (yes:) */
3432 if (true_label_p == NULL)
3433 true_label_p = &local_label;
3435 /* Keep the original source location on the first 'if'. */
3436 t = shortcut_cond_r (TREE_OPERAND (pred, 0), true_label_p, NULL, locus);
3437 append_to_statement_list (t, &expr);
3439 /* Set the source location of the || on the second 'if'. */
3440 new_locus = EXPR_HAS_LOCATION (pred) ? EXPR_LOCATION (pred) : locus;
3441 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
3442 new_locus);
3443 append_to_statement_list (t, &expr);
3445 else if (TREE_CODE (pred) == COND_EXPR
3446 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 1)))
3447 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 2))))
3449 location_t new_locus;
3451 /* As long as we're messing with gotos, turn if (a ? b : c) into
3452 if (a)
3453 if (b) goto yes; else goto no;
3454 else
3455 if (c) goto yes; else goto no;
3457 Don't do this if one of the arms has void type, which can happen
3458 in C++ when the arm is throw. */
3460 /* Keep the original source location on the first 'if'. Set the source
3461 location of the ? on the second 'if'. */
3462 new_locus = EXPR_HAS_LOCATION (pred) ? EXPR_LOCATION (pred) : locus;
3463 expr = build3 (COND_EXPR, void_type_node, TREE_OPERAND (pred, 0),
3464 shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p,
3465 false_label_p, locus),
3466 shortcut_cond_r (TREE_OPERAND (pred, 2), true_label_p,
3467 false_label_p, new_locus));
3469 else
3471 expr = build3 (COND_EXPR, void_type_node, pred,
3472 build_and_jump (true_label_p),
3473 build_and_jump (false_label_p));
3474 SET_EXPR_LOCATION (expr, locus);
3477 if (local_label)
3479 t = build1 (LABEL_EXPR, void_type_node, local_label);
3480 append_to_statement_list (t, &expr);
3483 return expr;
3486 /* Given a conditional expression EXPR with short-circuit boolean
3487 predicates using TRUTH_ANDIF_EXPR or TRUTH_ORIF_EXPR, break the
3488 predicate apart into the equivalent sequence of conditionals. */
3490 static tree
3491 shortcut_cond_expr (tree expr)
3493 tree pred = TREE_OPERAND (expr, 0);
3494 tree then_ = TREE_OPERAND (expr, 1);
3495 tree else_ = TREE_OPERAND (expr, 2);
3496 tree true_label, false_label, end_label, t;
3497 tree *true_label_p;
3498 tree *false_label_p;
3499 bool emit_end, emit_false, jump_over_else;
3500 bool then_se = then_ && TREE_SIDE_EFFECTS (then_);
3501 bool else_se = else_ && TREE_SIDE_EFFECTS (else_);
3503 /* First do simple transformations. */
3504 if (!else_se)
3506 /* If there is no 'else', turn
3507 if (a && b) then c
3508 into
3509 if (a) if (b) then c. */
3510 while (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
3512 /* Keep the original source location on the first 'if'. */
3513 location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
3514 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
3515 /* Set the source location of the && on the second 'if'. */
3516 if (EXPR_HAS_LOCATION (pred))
3517 SET_EXPR_LOCATION (expr, EXPR_LOCATION (pred));
3518 then_ = shortcut_cond_expr (expr);
3519 then_se = then_ && TREE_SIDE_EFFECTS (then_);
3520 pred = TREE_OPERAND (pred, 0);
3521 expr = build3 (COND_EXPR, void_type_node, pred, then_, NULL_TREE);
3522 SET_EXPR_LOCATION (expr, locus);
3526 if (!then_se)
3528 /* If there is no 'then', turn
3529 if (a || b); else d
3530 into
3531 if (a); else if (b); else d. */
3532 while (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
3534 /* Keep the original source location on the first 'if'. */
3535 location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
3536 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
3537 /* Set the source location of the || on the second 'if'. */
3538 if (EXPR_HAS_LOCATION (pred))
3539 SET_EXPR_LOCATION (expr, EXPR_LOCATION (pred));
3540 else_ = shortcut_cond_expr (expr);
3541 else_se = else_ && TREE_SIDE_EFFECTS (else_);
3542 pred = TREE_OPERAND (pred, 0);
3543 expr = build3 (COND_EXPR, void_type_node, pred, NULL_TREE, else_);
3544 SET_EXPR_LOCATION (expr, locus);
3548 /* If we're done, great. */
3549 if (TREE_CODE (pred) != TRUTH_ANDIF_EXPR
3550 && TREE_CODE (pred) != TRUTH_ORIF_EXPR)
3551 return expr;
3553 /* Otherwise we need to mess with gotos. Change
3554 if (a) c; else d;
3556 if (a); else goto no;
3557 c; goto end;
3558 no: d; end:
3559 and recursively gimplify the condition. */
3561 true_label = false_label = end_label = NULL_TREE;
3563 /* If our arms just jump somewhere, hijack those labels so we don't
3564 generate jumps to jumps. */
3566 if (then_
3567 && TREE_CODE (then_) == GOTO_EXPR
3568 && TREE_CODE (GOTO_DESTINATION (then_)) == LABEL_DECL)
3570 true_label = GOTO_DESTINATION (then_);
3571 then_ = NULL;
3572 then_se = false;
3575 if (else_
3576 && TREE_CODE (else_) == GOTO_EXPR
3577 && TREE_CODE (GOTO_DESTINATION (else_)) == LABEL_DECL)
3579 false_label = GOTO_DESTINATION (else_);
3580 else_ = NULL;
3581 else_se = false;
3584 /* If we aren't hijacking a label for the 'then' branch, it falls through. */
3585 if (true_label)
3586 true_label_p = &true_label;
3587 else
3588 true_label_p = NULL;
3590 /* The 'else' branch also needs a label if it contains interesting code. */
3591 if (false_label || else_se)
3592 false_label_p = &false_label;
3593 else
3594 false_label_p = NULL;
3596 /* If there was nothing else in our arms, just forward the label(s). */
3597 if (!then_se && !else_se)
3598 return shortcut_cond_r (pred, true_label_p, false_label_p,
3599 EXPR_LOC_OR_LOC (expr, input_location));
3601 /* If our last subexpression already has a terminal label, reuse it. */
3602 if (else_se)
3603 t = expr_last (else_);
3604 else if (then_se)
3605 t = expr_last (then_);
3606 else
3607 t = NULL;
3608 if (t && TREE_CODE (t) == LABEL_EXPR)
3609 end_label = LABEL_EXPR_LABEL (t);
3611 /* If we don't care about jumping to the 'else' branch, jump to the end
3612 if the condition is false. */
3613 if (!false_label_p)
3614 false_label_p = &end_label;
3616 /* We only want to emit these labels if we aren't hijacking them. */
3617 emit_end = (end_label == NULL_TREE);
3618 emit_false = (false_label == NULL_TREE);
3620 /* We only emit the jump over the else clause if we have to--if the
3621 then clause may fall through. Otherwise we can wind up with a
3622 useless jump and a useless label at the end of gimplified code,
3623 which will cause us to think that this conditional as a whole
3624 falls through even if it doesn't. If we then inline a function
3625 which ends with such a condition, that can cause us to issue an
3626 inappropriate warning about control reaching the end of a
3627 non-void function. */
3628 jump_over_else = block_may_fallthru (then_);
3630 pred = shortcut_cond_r (pred, true_label_p, false_label_p,
3631 EXPR_LOC_OR_LOC (expr, input_location));
3633 expr = NULL;
3634 append_to_statement_list (pred, &expr);
3636 append_to_statement_list (then_, &expr);
3637 if (else_se)
3639 if (jump_over_else)
3641 tree last = expr_last (expr);
3642 t = build_and_jump (&end_label);
3643 if (EXPR_HAS_LOCATION (last))
3644 SET_EXPR_LOCATION (t, EXPR_LOCATION (last));
3645 append_to_statement_list (t, &expr);
3647 if (emit_false)
3649 t = build1 (LABEL_EXPR, void_type_node, false_label);
3650 append_to_statement_list (t, &expr);
3652 append_to_statement_list (else_, &expr);
3654 if (emit_end && end_label)
3656 t = build1 (LABEL_EXPR, void_type_node, end_label);
3657 append_to_statement_list (t, &expr);
3660 return expr;
3663 /* EXPR is used in a boolean context; make sure it has BOOLEAN_TYPE. */
3665 tree
3666 gimple_boolify (tree expr)
3668 tree type = TREE_TYPE (expr);
3669 location_t loc = EXPR_LOCATION (expr);
3671 if (TREE_CODE (expr) == NE_EXPR
3672 && TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR
3673 && integer_zerop (TREE_OPERAND (expr, 1)))
3675 tree call = TREE_OPERAND (expr, 0);
3676 tree fn = get_callee_fndecl (call);
3678 /* For __builtin_expect ((long) (x), y) recurse into x as well
3679 if x is truth_value_p. */
3680 if (fn
3681 && DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL
3682 && DECL_FUNCTION_CODE (fn) == BUILT_IN_EXPECT
3683 && call_expr_nargs (call) == 2)
3685 tree arg = CALL_EXPR_ARG (call, 0);
3686 if (arg)
3688 if (TREE_CODE (arg) == NOP_EXPR
3689 && TREE_TYPE (arg) == TREE_TYPE (call))
3690 arg = TREE_OPERAND (arg, 0);
3691 if (truth_value_p (TREE_CODE (arg)))
3693 arg = gimple_boolify (arg);
3694 CALL_EXPR_ARG (call, 0)
3695 = fold_convert_loc (loc, TREE_TYPE (call), arg);
3701 switch (TREE_CODE (expr))
3703 case TRUTH_AND_EXPR:
3704 case TRUTH_OR_EXPR:
3705 case TRUTH_XOR_EXPR:
3706 case TRUTH_ANDIF_EXPR:
3707 case TRUTH_ORIF_EXPR:
3708 /* Also boolify the arguments of truth exprs. */
3709 TREE_OPERAND (expr, 1) = gimple_boolify (TREE_OPERAND (expr, 1));
3710 /* FALLTHRU */
3712 case TRUTH_NOT_EXPR:
3713 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
3715 /* These expressions always produce boolean results. */
3716 if (TREE_CODE (type) != BOOLEAN_TYPE)
3717 TREE_TYPE (expr) = boolean_type_node;
3718 return expr;
3720 case ANNOTATE_EXPR:
3721 switch ((enum annot_expr_kind) TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)))
3723 case annot_expr_ivdep_kind:
3724 case annot_expr_no_vector_kind:
3725 case annot_expr_vector_kind:
3726 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
3727 if (TREE_CODE (type) != BOOLEAN_TYPE)
3728 TREE_TYPE (expr) = boolean_type_node;
3729 return expr;
3730 default:
3731 gcc_unreachable ();
3734 default:
3735 if (COMPARISON_CLASS_P (expr))
3737 /* There expressions always prduce boolean results. */
3738 if (TREE_CODE (type) != BOOLEAN_TYPE)
3739 TREE_TYPE (expr) = boolean_type_node;
3740 return expr;
3742 /* Other expressions that get here must have boolean values, but
3743 might need to be converted to the appropriate mode. */
3744 if (TREE_CODE (type) == BOOLEAN_TYPE)
3745 return expr;
3746 return fold_convert_loc (loc, boolean_type_node, expr);
3750 /* Given a conditional expression *EXPR_P without side effects, gimplify
3751 its operands. New statements are inserted to PRE_P. */
3753 static enum gimplify_status
3754 gimplify_pure_cond_expr (tree *expr_p, gimple_seq *pre_p)
3756 tree expr = *expr_p, cond;
3757 enum gimplify_status ret, tret;
3758 enum tree_code code;
3760 cond = gimple_boolify (COND_EXPR_COND (expr));
3762 /* We need to handle && and || specially, as their gimplification
3763 creates pure cond_expr, thus leading to an infinite cycle otherwise. */
3764 code = TREE_CODE (cond);
3765 if (code == TRUTH_ANDIF_EXPR)
3766 TREE_SET_CODE (cond, TRUTH_AND_EXPR);
3767 else if (code == TRUTH_ORIF_EXPR)
3768 TREE_SET_CODE (cond, TRUTH_OR_EXPR);
3769 ret = gimplify_expr (&cond, pre_p, NULL, is_gimple_condexpr, fb_rvalue);
3770 COND_EXPR_COND (*expr_p) = cond;
3772 tret = gimplify_expr (&COND_EXPR_THEN (expr), pre_p, NULL,
3773 is_gimple_val, fb_rvalue);
3774 ret = MIN (ret, tret);
3775 tret = gimplify_expr (&COND_EXPR_ELSE (expr), pre_p, NULL,
3776 is_gimple_val, fb_rvalue);
3778 return MIN (ret, tret);
3781 /* Return true if evaluating EXPR could trap.
3782 EXPR is GENERIC, while tree_could_trap_p can be called
3783 only on GIMPLE. */
3785 static bool
3786 generic_expr_could_trap_p (tree expr)
3788 unsigned i, n;
3790 if (!expr || is_gimple_val (expr))
3791 return false;
3793 if (!EXPR_P (expr) || tree_could_trap_p (expr))
3794 return true;
3796 n = TREE_OPERAND_LENGTH (expr);
3797 for (i = 0; i < n; i++)
3798 if (generic_expr_could_trap_p (TREE_OPERAND (expr, i)))
3799 return true;
3801 return false;
3804 /* Convert the conditional expression pointed to by EXPR_P '(p) ? a : b;'
3805 into
3807 if (p) if (p)
3808 t1 = a; a;
3809 else or else
3810 t1 = b; b;
3813 The second form is used when *EXPR_P is of type void.
3815 PRE_P points to the list where side effects that must happen before
3816 *EXPR_P should be stored. */
3818 static enum gimplify_status
3819 gimplify_cond_expr (tree *expr_p, gimple_seq *pre_p, fallback_t fallback)
3821 tree expr = *expr_p;
3822 tree type = TREE_TYPE (expr);
3823 location_t loc = EXPR_LOCATION (expr);
3824 tree tmp, arm1, arm2;
3825 enum gimplify_status ret;
3826 tree label_true, label_false, label_cont;
3827 bool have_then_clause_p, have_else_clause_p;
3828 gcond *cond_stmt;
3829 enum tree_code pred_code;
3830 gimple_seq seq = NULL;
3832 /* If this COND_EXPR has a value, copy the values into a temporary within
3833 the arms. */
3834 if (!VOID_TYPE_P (type))
3836 tree then_ = TREE_OPERAND (expr, 1), else_ = TREE_OPERAND (expr, 2);
3837 tree result;
3839 /* If either an rvalue is ok or we do not require an lvalue, create the
3840 temporary. But we cannot do that if the type is addressable. */
3841 if (((fallback & fb_rvalue) || !(fallback & fb_lvalue))
3842 && !TREE_ADDRESSABLE (type))
3844 if (gimplify_ctxp->allow_rhs_cond_expr
3845 /* If either branch has side effects or could trap, it can't be
3846 evaluated unconditionally. */
3847 && !TREE_SIDE_EFFECTS (then_)
3848 && !generic_expr_could_trap_p (then_)
3849 && !TREE_SIDE_EFFECTS (else_)
3850 && !generic_expr_could_trap_p (else_))
3851 return gimplify_pure_cond_expr (expr_p, pre_p);
3853 tmp = create_tmp_var (type, "iftmp");
3854 result = tmp;
3857 /* Otherwise, only create and copy references to the values. */
3858 else
3860 type = build_pointer_type (type);
3862 if (!VOID_TYPE_P (TREE_TYPE (then_)))
3863 then_ = build_fold_addr_expr_loc (loc, then_);
3865 if (!VOID_TYPE_P (TREE_TYPE (else_)))
3866 else_ = build_fold_addr_expr_loc (loc, else_);
3868 expr
3869 = build3 (COND_EXPR, type, TREE_OPERAND (expr, 0), then_, else_);
3871 tmp = create_tmp_var (type, "iftmp");
3872 result = build_simple_mem_ref_loc (loc, tmp);
3875 /* Build the new then clause, `tmp = then_;'. But don't build the
3876 assignment if the value is void; in C++ it can be if it's a throw. */
3877 if (!VOID_TYPE_P (TREE_TYPE (then_)))
3878 TREE_OPERAND (expr, 1) = build2 (MODIFY_EXPR, type, tmp, then_);
3880 /* Similarly, build the new else clause, `tmp = else_;'. */
3881 if (!VOID_TYPE_P (TREE_TYPE (else_)))
3882 TREE_OPERAND (expr, 2) = build2 (MODIFY_EXPR, type, tmp, else_);
3884 TREE_TYPE (expr) = void_type_node;
3885 recalculate_side_effects (expr);
3887 /* Move the COND_EXPR to the prequeue. */
3888 gimplify_stmt (&expr, pre_p);
3890 *expr_p = result;
3891 return GS_ALL_DONE;
3894 /* Remove any COMPOUND_EXPR so the following cases will be caught. */
3895 STRIP_TYPE_NOPS (TREE_OPERAND (expr, 0));
3896 if (TREE_CODE (TREE_OPERAND (expr, 0)) == COMPOUND_EXPR)
3897 gimplify_compound_expr (&TREE_OPERAND (expr, 0), pre_p, true);
3899 /* Make sure the condition has BOOLEAN_TYPE. */
3900 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
3902 /* Break apart && and || conditions. */
3903 if (TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ANDIF_EXPR
3904 || TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ORIF_EXPR)
3906 expr = shortcut_cond_expr (expr);
3908 if (expr != *expr_p)
3910 *expr_p = expr;
3912 /* We can't rely on gimplify_expr to re-gimplify the expanded
3913 form properly, as cleanups might cause the target labels to be
3914 wrapped in a TRY_FINALLY_EXPR. To prevent that, we need to
3915 set up a conditional context. */
3916 gimple_push_condition ();
3917 gimplify_stmt (expr_p, &seq);
3918 gimple_pop_condition (pre_p);
3919 gimple_seq_add_seq (pre_p, seq);
3921 return GS_ALL_DONE;
3925 /* Now do the normal gimplification. */
3927 /* Gimplify condition. */
3928 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL, is_gimple_condexpr,
3929 fb_rvalue);
3930 if (ret == GS_ERROR)
3931 return GS_ERROR;
3932 gcc_assert (TREE_OPERAND (expr, 0) != NULL_TREE);
3934 gimple_push_condition ();
3936 have_then_clause_p = have_else_clause_p = false;
3937 if (TREE_OPERAND (expr, 1) != NULL
3938 && TREE_CODE (TREE_OPERAND (expr, 1)) == GOTO_EXPR
3939 && TREE_CODE (GOTO_DESTINATION (TREE_OPERAND (expr, 1))) == LABEL_DECL
3940 && (DECL_CONTEXT (GOTO_DESTINATION (TREE_OPERAND (expr, 1)))
3941 == current_function_decl)
3942 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
3943 have different locations, otherwise we end up with incorrect
3944 location information on the branches. */
3945 && (optimize
3946 || !EXPR_HAS_LOCATION (expr)
3947 || !EXPR_HAS_LOCATION (TREE_OPERAND (expr, 1))
3948 || EXPR_LOCATION (expr) == EXPR_LOCATION (TREE_OPERAND (expr, 1))))
3950 label_true = GOTO_DESTINATION (TREE_OPERAND (expr, 1));
3951 have_then_clause_p = true;
3953 else
3954 label_true = create_artificial_label (UNKNOWN_LOCATION);
3955 if (TREE_OPERAND (expr, 2) != NULL
3956 && TREE_CODE (TREE_OPERAND (expr, 2)) == GOTO_EXPR
3957 && TREE_CODE (GOTO_DESTINATION (TREE_OPERAND (expr, 2))) == LABEL_DECL
3958 && (DECL_CONTEXT (GOTO_DESTINATION (TREE_OPERAND (expr, 2)))
3959 == current_function_decl)
3960 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
3961 have different locations, otherwise we end up with incorrect
3962 location information on the branches. */
3963 && (optimize
3964 || !EXPR_HAS_LOCATION (expr)
3965 || !EXPR_HAS_LOCATION (TREE_OPERAND (expr, 2))
3966 || EXPR_LOCATION (expr) == EXPR_LOCATION (TREE_OPERAND (expr, 2))))
3968 label_false = GOTO_DESTINATION (TREE_OPERAND (expr, 2));
3969 have_else_clause_p = true;
3971 else
3972 label_false = create_artificial_label (UNKNOWN_LOCATION);
3974 gimple_cond_get_ops_from_tree (COND_EXPR_COND (expr), &pred_code, &arm1,
3975 &arm2);
3976 cond_stmt = gimple_build_cond (pred_code, arm1, arm2, label_true,
3977 label_false);
3978 gimple_set_no_warning (cond_stmt, TREE_NO_WARNING (COND_EXPR_COND (expr)));
3979 gimplify_seq_add_stmt (&seq, cond_stmt);
3980 gimple_stmt_iterator gsi = gsi_last (seq);
3981 maybe_fold_stmt (&gsi);
3983 label_cont = NULL_TREE;
3984 if (!have_then_clause_p)
3986 /* For if (...) {} else { code; } put label_true after
3987 the else block. */
3988 if (TREE_OPERAND (expr, 1) == NULL_TREE
3989 && !have_else_clause_p
3990 && TREE_OPERAND (expr, 2) != NULL_TREE)
3991 label_cont = label_true;
3992 else
3994 gimplify_seq_add_stmt (&seq, gimple_build_label (label_true));
3995 have_then_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 1), &seq);
3996 /* For if (...) { code; } else {} or
3997 if (...) { code; } else goto label; or
3998 if (...) { code; return; } else { ... }
3999 label_cont isn't needed. */
4000 if (!have_else_clause_p
4001 && TREE_OPERAND (expr, 2) != NULL_TREE
4002 && gimple_seq_may_fallthru (seq))
4004 gimple *g;
4005 label_cont = create_artificial_label (UNKNOWN_LOCATION);
4007 g = gimple_build_goto (label_cont);
4009 /* GIMPLE_COND's are very low level; they have embedded
4010 gotos. This particular embedded goto should not be marked
4011 with the location of the original COND_EXPR, as it would
4012 correspond to the COND_EXPR's condition, not the ELSE or the
4013 THEN arms. To avoid marking it with the wrong location, flag
4014 it as "no location". */
4015 gimple_set_do_not_emit_location (g);
4017 gimplify_seq_add_stmt (&seq, g);
4021 if (!have_else_clause_p)
4023 gimplify_seq_add_stmt (&seq, gimple_build_label (label_false));
4024 have_else_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 2), &seq);
4026 if (label_cont)
4027 gimplify_seq_add_stmt (&seq, gimple_build_label (label_cont));
4029 gimple_pop_condition (pre_p);
4030 gimple_seq_add_seq (pre_p, seq);
4032 if (ret == GS_ERROR)
4033 ; /* Do nothing. */
4034 else if (have_then_clause_p || have_else_clause_p)
4035 ret = GS_ALL_DONE;
4036 else
4038 /* Both arms are empty; replace the COND_EXPR with its predicate. */
4039 expr = TREE_OPERAND (expr, 0);
4040 gimplify_stmt (&expr, pre_p);
4043 *expr_p = NULL;
4044 return ret;
4047 /* Prepare the node pointed to by EXPR_P, an is_gimple_addressable expression,
4048 to be marked addressable.
4050 We cannot rely on such an expression being directly markable if a temporary
4051 has been created by the gimplification. In this case, we create another
4052 temporary and initialize it with a copy, which will become a store after we
4053 mark it addressable. This can happen if the front-end passed us something
4054 that it could not mark addressable yet, like a Fortran pass-by-reference
4055 parameter (int) floatvar. */
4057 static void
4058 prepare_gimple_addressable (tree *expr_p, gimple_seq *seq_p)
4060 while (handled_component_p (*expr_p))
4061 expr_p = &TREE_OPERAND (*expr_p, 0);
4062 if (is_gimple_reg (*expr_p))
4064 /* Do not allow an SSA name as the temporary. */
4065 tree var = get_initialized_tmp_var (*expr_p, seq_p, NULL, false);
4066 DECL_GIMPLE_REG_P (var) = 0;
4067 *expr_p = var;
4071 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4072 a call to __builtin_memcpy. */
4074 static enum gimplify_status
4075 gimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value,
4076 gimple_seq *seq_p)
4078 tree t, to, to_ptr, from, from_ptr;
4079 gcall *gs;
4080 location_t loc = EXPR_LOCATION (*expr_p);
4082 to = TREE_OPERAND (*expr_p, 0);
4083 from = TREE_OPERAND (*expr_p, 1);
4085 /* Mark the RHS addressable. Beware that it may not be possible to do so
4086 directly if a temporary has been created by the gimplification. */
4087 prepare_gimple_addressable (&from, seq_p);
4089 mark_addressable (from);
4090 from_ptr = build_fold_addr_expr_loc (loc, from);
4091 gimplify_arg (&from_ptr, seq_p, loc);
4093 mark_addressable (to);
4094 to_ptr = build_fold_addr_expr_loc (loc, to);
4095 gimplify_arg (&to_ptr, seq_p, loc);
4097 t = builtin_decl_implicit (BUILT_IN_MEMCPY);
4099 gs = gimple_build_call (t, 3, to_ptr, from_ptr, size);
4101 if (want_value)
4103 /* tmp = memcpy() */
4104 t = create_tmp_var (TREE_TYPE (to_ptr));
4105 gimple_call_set_lhs (gs, t);
4106 gimplify_seq_add_stmt (seq_p, gs);
4108 *expr_p = build_simple_mem_ref (t);
4109 return GS_ALL_DONE;
4112 gimplify_seq_add_stmt (seq_p, gs);
4113 *expr_p = NULL;
4114 return GS_ALL_DONE;
4117 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4118 a call to __builtin_memset. In this case we know that the RHS is
4119 a CONSTRUCTOR with an empty element list. */
4121 static enum gimplify_status
4122 gimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value,
4123 gimple_seq *seq_p)
4125 tree t, from, to, to_ptr;
4126 gcall *gs;
4127 location_t loc = EXPR_LOCATION (*expr_p);
4129 /* Assert our assumptions, to abort instead of producing wrong code
4130 silently if they are not met. Beware that the RHS CONSTRUCTOR might
4131 not be immediately exposed. */
4132 from = TREE_OPERAND (*expr_p, 1);
4133 if (TREE_CODE (from) == WITH_SIZE_EXPR)
4134 from = TREE_OPERAND (from, 0);
4136 gcc_assert (TREE_CODE (from) == CONSTRUCTOR
4137 && vec_safe_is_empty (CONSTRUCTOR_ELTS (from)));
4139 /* Now proceed. */
4140 to = TREE_OPERAND (*expr_p, 0);
4142 to_ptr = build_fold_addr_expr_loc (loc, to);
4143 gimplify_arg (&to_ptr, seq_p, loc);
4144 t = builtin_decl_implicit (BUILT_IN_MEMSET);
4146 gs = gimple_build_call (t, 3, to_ptr, integer_zero_node, size);
4148 if (want_value)
4150 /* tmp = memset() */
4151 t = create_tmp_var (TREE_TYPE (to_ptr));
4152 gimple_call_set_lhs (gs, t);
4153 gimplify_seq_add_stmt (seq_p, gs);
4155 *expr_p = build1 (INDIRECT_REF, TREE_TYPE (to), t);
4156 return GS_ALL_DONE;
4159 gimplify_seq_add_stmt (seq_p, gs);
4160 *expr_p = NULL;
4161 return GS_ALL_DONE;
4164 /* A subroutine of gimplify_init_ctor_preeval. Called via walk_tree,
4165 determine, cautiously, if a CONSTRUCTOR overlaps the lhs of an
4166 assignment. Return non-null if we detect a potential overlap. */
4168 struct gimplify_init_ctor_preeval_data
4170 /* The base decl of the lhs object. May be NULL, in which case we
4171 have to assume the lhs is indirect. */
4172 tree lhs_base_decl;
4174 /* The alias set of the lhs object. */
4175 alias_set_type lhs_alias_set;
4178 static tree
4179 gimplify_init_ctor_preeval_1 (tree *tp, int *walk_subtrees, void *xdata)
4181 struct gimplify_init_ctor_preeval_data *data
4182 = (struct gimplify_init_ctor_preeval_data *) xdata;
4183 tree t = *tp;
4185 /* If we find the base object, obviously we have overlap. */
4186 if (data->lhs_base_decl == t)
4187 return t;
4189 /* If the constructor component is indirect, determine if we have a
4190 potential overlap with the lhs. The only bits of information we
4191 have to go on at this point are addressability and alias sets. */
4192 if ((INDIRECT_REF_P (t)
4193 || TREE_CODE (t) == MEM_REF)
4194 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
4195 && alias_sets_conflict_p (data->lhs_alias_set, get_alias_set (t)))
4196 return t;
4198 /* If the constructor component is a call, determine if it can hide a
4199 potential overlap with the lhs through an INDIRECT_REF like above.
4200 ??? Ugh - this is completely broken. In fact this whole analysis
4201 doesn't look conservative. */
4202 if (TREE_CODE (t) == CALL_EXPR)
4204 tree type, fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (t)));
4206 for (type = TYPE_ARG_TYPES (fntype); type; type = TREE_CHAIN (type))
4207 if (POINTER_TYPE_P (TREE_VALUE (type))
4208 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
4209 && alias_sets_conflict_p (data->lhs_alias_set,
4210 get_alias_set
4211 (TREE_TYPE (TREE_VALUE (type)))))
4212 return t;
4215 if (IS_TYPE_OR_DECL_P (t))
4216 *walk_subtrees = 0;
4217 return NULL;
4220 /* A subroutine of gimplify_init_constructor. Pre-evaluate EXPR,
4221 force values that overlap with the lhs (as described by *DATA)
4222 into temporaries. */
4224 static void
4225 gimplify_init_ctor_preeval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
4226 struct gimplify_init_ctor_preeval_data *data)
4228 enum gimplify_status one;
4230 /* If the value is constant, then there's nothing to pre-evaluate. */
4231 if (TREE_CONSTANT (*expr_p))
4233 /* Ensure it does not have side effects, it might contain a reference to
4234 the object we're initializing. */
4235 gcc_assert (!TREE_SIDE_EFFECTS (*expr_p));
4236 return;
4239 /* If the type has non-trivial constructors, we can't pre-evaluate. */
4240 if (TREE_ADDRESSABLE (TREE_TYPE (*expr_p)))
4241 return;
4243 /* Recurse for nested constructors. */
4244 if (TREE_CODE (*expr_p) == CONSTRUCTOR)
4246 unsigned HOST_WIDE_INT ix;
4247 constructor_elt *ce;
4248 vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (*expr_p);
4250 FOR_EACH_VEC_SAFE_ELT (v, ix, ce)
4251 gimplify_init_ctor_preeval (&ce->value, pre_p, post_p, data);
4253 return;
4256 /* If this is a variable sized type, we must remember the size. */
4257 maybe_with_size_expr (expr_p);
4259 /* Gimplify the constructor element to something appropriate for the rhs
4260 of a MODIFY_EXPR. Given that we know the LHS is an aggregate, we know
4261 the gimplifier will consider this a store to memory. Doing this
4262 gimplification now means that we won't have to deal with complicated
4263 language-specific trees, nor trees like SAVE_EXPR that can induce
4264 exponential search behavior. */
4265 one = gimplify_expr (expr_p, pre_p, post_p, is_gimple_mem_rhs, fb_rvalue);
4266 if (one == GS_ERROR)
4268 *expr_p = NULL;
4269 return;
4272 /* If we gimplified to a bare decl, we can be sure that it doesn't overlap
4273 with the lhs, since "a = { .x=a }" doesn't make sense. This will
4274 always be true for all scalars, since is_gimple_mem_rhs insists on a
4275 temporary variable for them. */
4276 if (DECL_P (*expr_p))
4277 return;
4279 /* If this is of variable size, we have no choice but to assume it doesn't
4280 overlap since we can't make a temporary for it. */
4281 if (TREE_CODE (TYPE_SIZE (TREE_TYPE (*expr_p))) != INTEGER_CST)
4282 return;
4284 /* Otherwise, we must search for overlap ... */
4285 if (!walk_tree (expr_p, gimplify_init_ctor_preeval_1, data, NULL))
4286 return;
4288 /* ... and if found, force the value into a temporary. */
4289 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
4292 /* A subroutine of gimplify_init_ctor_eval. Create a loop for
4293 a RANGE_EXPR in a CONSTRUCTOR for an array.
4295 var = lower;
4296 loop_entry:
4297 object[var] = value;
4298 if (var == upper)
4299 goto loop_exit;
4300 var = var + 1;
4301 goto loop_entry;
4302 loop_exit:
4304 We increment var _after_ the loop exit check because we might otherwise
4305 fail if upper == TYPE_MAX_VALUE (type for upper).
4307 Note that we never have to deal with SAVE_EXPRs here, because this has
4308 already been taken care of for us, in gimplify_init_ctor_preeval(). */
4310 static void gimplify_init_ctor_eval (tree, vec<constructor_elt, va_gc> *,
4311 gimple_seq *, bool);
4313 static void
4314 gimplify_init_ctor_eval_range (tree object, tree lower, tree upper,
4315 tree value, tree array_elt_type,
4316 gimple_seq *pre_p, bool cleared)
4318 tree loop_entry_label, loop_exit_label, fall_thru_label;
4319 tree var, var_type, cref, tmp;
4321 loop_entry_label = create_artificial_label (UNKNOWN_LOCATION);
4322 loop_exit_label = create_artificial_label (UNKNOWN_LOCATION);
4323 fall_thru_label = create_artificial_label (UNKNOWN_LOCATION);
4325 /* Create and initialize the index variable. */
4326 var_type = TREE_TYPE (upper);
4327 var = create_tmp_var (var_type);
4328 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, lower));
4330 /* Add the loop entry label. */
4331 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_entry_label));
4333 /* Build the reference. */
4334 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
4335 var, NULL_TREE, NULL_TREE);
4337 /* If we are a constructor, just call gimplify_init_ctor_eval to do
4338 the store. Otherwise just assign value to the reference. */
4340 if (TREE_CODE (value) == CONSTRUCTOR)
4341 /* NB we might have to call ourself recursively through
4342 gimplify_init_ctor_eval if the value is a constructor. */
4343 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
4344 pre_p, cleared);
4345 else
4346 gimplify_seq_add_stmt (pre_p, gimple_build_assign (cref, value));
4348 /* We exit the loop when the index var is equal to the upper bound. */
4349 gimplify_seq_add_stmt (pre_p,
4350 gimple_build_cond (EQ_EXPR, var, upper,
4351 loop_exit_label, fall_thru_label));
4353 gimplify_seq_add_stmt (pre_p, gimple_build_label (fall_thru_label));
4355 /* Otherwise, increment the index var... */
4356 tmp = build2 (PLUS_EXPR, var_type, var,
4357 fold_convert (var_type, integer_one_node));
4358 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, tmp));
4360 /* ...and jump back to the loop entry. */
4361 gimplify_seq_add_stmt (pre_p, gimple_build_goto (loop_entry_label));
4363 /* Add the loop exit label. */
4364 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_exit_label));
4367 /* Return true if FDECL is accessing a field that is zero sized. */
4369 static bool
4370 zero_sized_field_decl (const_tree fdecl)
4372 if (TREE_CODE (fdecl) == FIELD_DECL && DECL_SIZE (fdecl)
4373 && integer_zerop (DECL_SIZE (fdecl)))
4374 return true;
4375 return false;
4378 /* Return true if TYPE is zero sized. */
4380 static bool
4381 zero_sized_type (const_tree type)
4383 if (AGGREGATE_TYPE_P (type) && TYPE_SIZE (type)
4384 && integer_zerop (TYPE_SIZE (type)))
4385 return true;
4386 return false;
4389 /* A subroutine of gimplify_init_constructor. Generate individual
4390 MODIFY_EXPRs for a CONSTRUCTOR. OBJECT is the LHS against which the
4391 assignments should happen. ELTS is the CONSTRUCTOR_ELTS of the
4392 CONSTRUCTOR. CLEARED is true if the entire LHS object has been
4393 zeroed first. */
4395 static void
4396 gimplify_init_ctor_eval (tree object, vec<constructor_elt, va_gc> *elts,
4397 gimple_seq *pre_p, bool cleared)
4399 tree array_elt_type = NULL;
4400 unsigned HOST_WIDE_INT ix;
4401 tree purpose, value;
4403 if (TREE_CODE (TREE_TYPE (object)) == ARRAY_TYPE)
4404 array_elt_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (object)));
4406 FOR_EACH_CONSTRUCTOR_ELT (elts, ix, purpose, value)
4408 tree cref;
4410 /* NULL values are created above for gimplification errors. */
4411 if (value == NULL)
4412 continue;
4414 if (cleared && initializer_zerop (value))
4415 continue;
4417 /* ??? Here's to hoping the front end fills in all of the indices,
4418 so we don't have to figure out what's missing ourselves. */
4419 gcc_assert (purpose);
4421 /* Skip zero-sized fields, unless value has side-effects. This can
4422 happen with calls to functions returning a zero-sized type, which
4423 we shouldn't discard. As a number of downstream passes don't
4424 expect sets of zero-sized fields, we rely on the gimplification of
4425 the MODIFY_EXPR we make below to drop the assignment statement. */
4426 if (! TREE_SIDE_EFFECTS (value) && zero_sized_field_decl (purpose))
4427 continue;
4429 /* If we have a RANGE_EXPR, we have to build a loop to assign the
4430 whole range. */
4431 if (TREE_CODE (purpose) == RANGE_EXPR)
4433 tree lower = TREE_OPERAND (purpose, 0);
4434 tree upper = TREE_OPERAND (purpose, 1);
4436 /* If the lower bound is equal to upper, just treat it as if
4437 upper was the index. */
4438 if (simple_cst_equal (lower, upper))
4439 purpose = upper;
4440 else
4442 gimplify_init_ctor_eval_range (object, lower, upper, value,
4443 array_elt_type, pre_p, cleared);
4444 continue;
4448 if (array_elt_type)
4450 /* Do not use bitsizetype for ARRAY_REF indices. */
4451 if (TYPE_DOMAIN (TREE_TYPE (object)))
4452 purpose
4453 = fold_convert (TREE_TYPE (TYPE_DOMAIN (TREE_TYPE (object))),
4454 purpose);
4455 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
4456 purpose, NULL_TREE, NULL_TREE);
4458 else
4460 gcc_assert (TREE_CODE (purpose) == FIELD_DECL);
4461 cref = build3 (COMPONENT_REF, TREE_TYPE (purpose),
4462 unshare_expr (object), purpose, NULL_TREE);
4465 if (TREE_CODE (value) == CONSTRUCTOR
4466 && TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE)
4467 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
4468 pre_p, cleared);
4469 else
4471 tree init = build2 (INIT_EXPR, TREE_TYPE (cref), cref, value);
4472 gimplify_and_add (init, pre_p);
4473 ggc_free (init);
4478 /* Return the appropriate RHS predicate for this LHS. */
4480 gimple_predicate
4481 rhs_predicate_for (tree lhs)
4483 if (is_gimple_reg (lhs))
4484 return is_gimple_reg_rhs_or_call;
4485 else
4486 return is_gimple_mem_rhs_or_call;
4489 /* Return the initial guess for an appropriate RHS predicate for this LHS,
4490 before the LHS has been gimplified. */
4492 static gimple_predicate
4493 initial_rhs_predicate_for (tree lhs)
4495 if (is_gimple_reg_type (TREE_TYPE (lhs)))
4496 return is_gimple_reg_rhs_or_call;
4497 else
4498 return is_gimple_mem_rhs_or_call;
4501 /* Gimplify a C99 compound literal expression. This just means adding
4502 the DECL_EXPR before the current statement and using its anonymous
4503 decl instead. */
4505 static enum gimplify_status
4506 gimplify_compound_literal_expr (tree *expr_p, gimple_seq *pre_p,
4507 bool (*gimple_test_f) (tree),
4508 fallback_t fallback)
4510 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (*expr_p);
4511 tree decl = DECL_EXPR_DECL (decl_s);
4512 tree init = DECL_INITIAL (decl);
4513 /* Mark the decl as addressable if the compound literal
4514 expression is addressable now, otherwise it is marked too late
4515 after we gimplify the initialization expression. */
4516 if (TREE_ADDRESSABLE (*expr_p))
4517 TREE_ADDRESSABLE (decl) = 1;
4518 /* Otherwise, if we don't need an lvalue and have a literal directly
4519 substitute it. Check if it matches the gimple predicate, as
4520 otherwise we'd generate a new temporary, and we can as well just
4521 use the decl we already have. */
4522 else if (!TREE_ADDRESSABLE (decl)
4523 && init
4524 && (fallback & fb_lvalue) == 0
4525 && gimple_test_f (init))
4527 *expr_p = init;
4528 return GS_OK;
4531 /* Preliminarily mark non-addressed complex variables as eligible
4532 for promotion to gimple registers. We'll transform their uses
4533 as we find them. */
4534 if ((TREE_CODE (TREE_TYPE (decl)) == COMPLEX_TYPE
4535 || TREE_CODE (TREE_TYPE (decl)) == VECTOR_TYPE)
4536 && !TREE_THIS_VOLATILE (decl)
4537 && !needs_to_live_in_memory (decl))
4538 DECL_GIMPLE_REG_P (decl) = 1;
4540 /* If the decl is not addressable, then it is being used in some
4541 expression or on the right hand side of a statement, and it can
4542 be put into a readonly data section. */
4543 if (!TREE_ADDRESSABLE (decl) && (fallback & fb_lvalue) == 0)
4544 TREE_READONLY (decl) = 1;
4546 /* This decl isn't mentioned in the enclosing block, so add it to the
4547 list of temps. FIXME it seems a bit of a kludge to say that
4548 anonymous artificial vars aren't pushed, but everything else is. */
4549 if (DECL_NAME (decl) == NULL_TREE && !DECL_SEEN_IN_BIND_EXPR_P (decl))
4550 gimple_add_tmp_var (decl);
4552 gimplify_and_add (decl_s, pre_p);
4553 *expr_p = decl;
4554 return GS_OK;
4557 /* Optimize embedded COMPOUND_LITERAL_EXPRs within a CONSTRUCTOR,
4558 return a new CONSTRUCTOR if something changed. */
4560 static tree
4561 optimize_compound_literals_in_ctor (tree orig_ctor)
4563 tree ctor = orig_ctor;
4564 vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ctor);
4565 unsigned int idx, num = vec_safe_length (elts);
4567 for (idx = 0; idx < num; idx++)
4569 tree value = (*elts)[idx].value;
4570 tree newval = value;
4571 if (TREE_CODE (value) == CONSTRUCTOR)
4572 newval = optimize_compound_literals_in_ctor (value);
4573 else if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR)
4575 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (value);
4576 tree decl = DECL_EXPR_DECL (decl_s);
4577 tree init = DECL_INITIAL (decl);
4579 if (!TREE_ADDRESSABLE (value)
4580 && !TREE_ADDRESSABLE (decl)
4581 && init
4582 && TREE_CODE (init) == CONSTRUCTOR)
4583 newval = optimize_compound_literals_in_ctor (init);
4585 if (newval == value)
4586 continue;
4588 if (ctor == orig_ctor)
4590 ctor = copy_node (orig_ctor);
4591 CONSTRUCTOR_ELTS (ctor) = vec_safe_copy (elts);
4592 elts = CONSTRUCTOR_ELTS (ctor);
4594 (*elts)[idx].value = newval;
4596 return ctor;
4599 /* A subroutine of gimplify_modify_expr. Break out elements of a
4600 CONSTRUCTOR used as an initializer into separate MODIFY_EXPRs.
4602 Note that we still need to clear any elements that don't have explicit
4603 initializers, so if not all elements are initialized we keep the
4604 original MODIFY_EXPR, we just remove all of the constructor elements.
4606 If NOTIFY_TEMP_CREATION is true, do not gimplify, just return
4607 GS_ERROR if we would have to create a temporary when gimplifying
4608 this constructor. Otherwise, return GS_OK.
4610 If NOTIFY_TEMP_CREATION is false, just do the gimplification. */
4612 static enum gimplify_status
4613 gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
4614 bool want_value, bool notify_temp_creation)
4616 tree object, ctor, type;
4617 enum gimplify_status ret;
4618 vec<constructor_elt, va_gc> *elts;
4620 gcc_assert (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == CONSTRUCTOR);
4622 if (!notify_temp_creation)
4624 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
4625 is_gimple_lvalue, fb_lvalue);
4626 if (ret == GS_ERROR)
4627 return ret;
4630 object = TREE_OPERAND (*expr_p, 0);
4631 ctor = TREE_OPERAND (*expr_p, 1)
4632 = optimize_compound_literals_in_ctor (TREE_OPERAND (*expr_p, 1));
4633 type = TREE_TYPE (ctor);
4634 elts = CONSTRUCTOR_ELTS (ctor);
4635 ret = GS_ALL_DONE;
4637 switch (TREE_CODE (type))
4639 case RECORD_TYPE:
4640 case UNION_TYPE:
4641 case QUAL_UNION_TYPE:
4642 case ARRAY_TYPE:
4644 struct gimplify_init_ctor_preeval_data preeval_data;
4645 HOST_WIDE_INT num_ctor_elements, num_nonzero_elements;
4646 bool cleared, complete_p, valid_const_initializer;
4648 /* Aggregate types must lower constructors to initialization of
4649 individual elements. The exception is that a CONSTRUCTOR node
4650 with no elements indicates zero-initialization of the whole. */
4651 if (vec_safe_is_empty (elts))
4653 if (notify_temp_creation)
4654 return GS_OK;
4655 break;
4658 /* Fetch information about the constructor to direct later processing.
4659 We might want to make static versions of it in various cases, and
4660 can only do so if it known to be a valid constant initializer. */
4661 valid_const_initializer
4662 = categorize_ctor_elements (ctor, &num_nonzero_elements,
4663 &num_ctor_elements, &complete_p);
4665 /* If a const aggregate variable is being initialized, then it
4666 should never be a lose to promote the variable to be static. */
4667 if (valid_const_initializer
4668 && num_nonzero_elements > 1
4669 && TREE_READONLY (object)
4670 && VAR_P (object)
4671 && (flag_merge_constants >= 2 || !TREE_ADDRESSABLE (object)))
4673 if (notify_temp_creation)
4674 return GS_ERROR;
4675 DECL_INITIAL (object) = ctor;
4676 TREE_STATIC (object) = 1;
4677 if (!DECL_NAME (object))
4678 DECL_NAME (object) = create_tmp_var_name ("C");
4679 walk_tree (&DECL_INITIAL (object), force_labels_r, NULL, NULL);
4681 /* ??? C++ doesn't automatically append a .<number> to the
4682 assembler name, and even when it does, it looks at FE private
4683 data structures to figure out what that number should be,
4684 which are not set for this variable. I suppose this is
4685 important for local statics for inline functions, which aren't
4686 "local" in the object file sense. So in order to get a unique
4687 TU-local symbol, we must invoke the lhd version now. */
4688 lhd_set_decl_assembler_name (object);
4690 *expr_p = NULL_TREE;
4691 break;
4694 /* If there are "lots" of initialized elements, even discounting
4695 those that are not address constants (and thus *must* be
4696 computed at runtime), then partition the constructor into
4697 constant and non-constant parts. Block copy the constant
4698 parts in, then generate code for the non-constant parts. */
4699 /* TODO. There's code in cp/typeck.c to do this. */
4701 if (int_size_in_bytes (TREE_TYPE (ctor)) < 0)
4702 /* store_constructor will ignore the clearing of variable-sized
4703 objects. Initializers for such objects must explicitly set
4704 every field that needs to be set. */
4705 cleared = false;
4706 else if (!complete_p && !CONSTRUCTOR_NO_CLEARING (ctor))
4707 /* If the constructor isn't complete, clear the whole object
4708 beforehand, unless CONSTRUCTOR_NO_CLEARING is set on it.
4710 ??? This ought not to be needed. For any element not present
4711 in the initializer, we should simply set them to zero. Except
4712 we'd need to *find* the elements that are not present, and that
4713 requires trickery to avoid quadratic compile-time behavior in
4714 large cases or excessive memory use in small cases. */
4715 cleared = true;
4716 else if (num_ctor_elements - num_nonzero_elements
4717 > CLEAR_RATIO (optimize_function_for_speed_p (cfun))
4718 && num_nonzero_elements < num_ctor_elements / 4)
4719 /* If there are "lots" of zeros, it's more efficient to clear
4720 the memory and then set the nonzero elements. */
4721 cleared = true;
4722 else
4723 cleared = false;
4725 /* If there are "lots" of initialized elements, and all of them
4726 are valid address constants, then the entire initializer can
4727 be dropped to memory, and then memcpy'd out. Don't do this
4728 for sparse arrays, though, as it's more efficient to follow
4729 the standard CONSTRUCTOR behavior of memset followed by
4730 individual element initialization. Also don't do this for small
4731 all-zero initializers (which aren't big enough to merit
4732 clearing), and don't try to make bitwise copies of
4733 TREE_ADDRESSABLE types.
4735 We cannot apply such transformation when compiling chkp static
4736 initializer because creation of initializer image in the memory
4737 will require static initialization of bounds for it. It should
4738 result in another gimplification of similar initializer and we
4739 may fall into infinite loop. */
4740 if (valid_const_initializer
4741 && !(cleared || num_nonzero_elements == 0)
4742 && !TREE_ADDRESSABLE (type)
4743 && (!current_function_decl
4744 || !lookup_attribute ("chkp ctor",
4745 DECL_ATTRIBUTES (current_function_decl))))
4747 HOST_WIDE_INT size = int_size_in_bytes (type);
4748 unsigned int align;
4750 /* ??? We can still get unbounded array types, at least
4751 from the C++ front end. This seems wrong, but attempt
4752 to work around it for now. */
4753 if (size < 0)
4755 size = int_size_in_bytes (TREE_TYPE (object));
4756 if (size >= 0)
4757 TREE_TYPE (ctor) = type = TREE_TYPE (object);
4760 /* Find the maximum alignment we can assume for the object. */
4761 /* ??? Make use of DECL_OFFSET_ALIGN. */
4762 if (DECL_P (object))
4763 align = DECL_ALIGN (object);
4764 else
4765 align = TYPE_ALIGN (type);
4767 /* Do a block move either if the size is so small as to make
4768 each individual move a sub-unit move on average, or if it
4769 is so large as to make individual moves inefficient. */
4770 if (size > 0
4771 && num_nonzero_elements > 1
4772 && (size < num_nonzero_elements
4773 || !can_move_by_pieces (size, align)))
4775 if (notify_temp_creation)
4776 return GS_ERROR;
4778 walk_tree (&ctor, force_labels_r, NULL, NULL);
4779 ctor = tree_output_constant_def (ctor);
4780 if (!useless_type_conversion_p (type, TREE_TYPE (ctor)))
4781 ctor = build1 (VIEW_CONVERT_EXPR, type, ctor);
4782 TREE_OPERAND (*expr_p, 1) = ctor;
4784 /* This is no longer an assignment of a CONSTRUCTOR, but
4785 we still may have processing to do on the LHS. So
4786 pretend we didn't do anything here to let that happen. */
4787 return GS_UNHANDLED;
4791 /* If the target is volatile, we have non-zero elements and more than
4792 one field to assign, initialize the target from a temporary. */
4793 if (TREE_THIS_VOLATILE (object)
4794 && !TREE_ADDRESSABLE (type)
4795 && num_nonzero_elements > 0
4796 && vec_safe_length (elts) > 1)
4798 tree temp = create_tmp_var (TYPE_MAIN_VARIANT (type));
4799 TREE_OPERAND (*expr_p, 0) = temp;
4800 *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p),
4801 *expr_p,
4802 build2 (MODIFY_EXPR, void_type_node,
4803 object, temp));
4804 return GS_OK;
4807 if (notify_temp_creation)
4808 return GS_OK;
4810 /* If there are nonzero elements and if needed, pre-evaluate to capture
4811 elements overlapping with the lhs into temporaries. We must do this
4812 before clearing to fetch the values before they are zeroed-out. */
4813 if (num_nonzero_elements > 0 && TREE_CODE (*expr_p) != INIT_EXPR)
4815 preeval_data.lhs_base_decl = get_base_address (object);
4816 if (!DECL_P (preeval_data.lhs_base_decl))
4817 preeval_data.lhs_base_decl = NULL;
4818 preeval_data.lhs_alias_set = get_alias_set (object);
4820 gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p, 1),
4821 pre_p, post_p, &preeval_data);
4824 bool ctor_has_side_effects_p
4825 = TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p, 1));
4827 if (cleared)
4829 /* Zap the CONSTRUCTOR element list, which simplifies this case.
4830 Note that we still have to gimplify, in order to handle the
4831 case of variable sized types. Avoid shared tree structures. */
4832 CONSTRUCTOR_ELTS (ctor) = NULL;
4833 TREE_SIDE_EFFECTS (ctor) = 0;
4834 object = unshare_expr (object);
4835 gimplify_stmt (expr_p, pre_p);
4838 /* If we have not block cleared the object, or if there are nonzero
4839 elements in the constructor, or if the constructor has side effects,
4840 add assignments to the individual scalar fields of the object. */
4841 if (!cleared
4842 || num_nonzero_elements > 0
4843 || ctor_has_side_effects_p)
4844 gimplify_init_ctor_eval (object, elts, pre_p, cleared);
4846 *expr_p = NULL_TREE;
4848 break;
4850 case COMPLEX_TYPE:
4852 tree r, i;
4854 if (notify_temp_creation)
4855 return GS_OK;
4857 /* Extract the real and imaginary parts out of the ctor. */
4858 gcc_assert (elts->length () == 2);
4859 r = (*elts)[0].value;
4860 i = (*elts)[1].value;
4861 if (r == NULL || i == NULL)
4863 tree zero = build_zero_cst (TREE_TYPE (type));
4864 if (r == NULL)
4865 r = zero;
4866 if (i == NULL)
4867 i = zero;
4870 /* Complex types have either COMPLEX_CST or COMPLEX_EXPR to
4871 represent creation of a complex value. */
4872 if (TREE_CONSTANT (r) && TREE_CONSTANT (i))
4874 ctor = build_complex (type, r, i);
4875 TREE_OPERAND (*expr_p, 1) = ctor;
4877 else
4879 ctor = build2 (COMPLEX_EXPR, type, r, i);
4880 TREE_OPERAND (*expr_p, 1) = ctor;
4881 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 1),
4882 pre_p,
4883 post_p,
4884 rhs_predicate_for (TREE_OPERAND (*expr_p, 0)),
4885 fb_rvalue);
4888 break;
4890 case VECTOR_TYPE:
4892 unsigned HOST_WIDE_INT ix;
4893 constructor_elt *ce;
4895 if (notify_temp_creation)
4896 return GS_OK;
4898 /* Go ahead and simplify constant constructors to VECTOR_CST. */
4899 if (TREE_CONSTANT (ctor))
4901 bool constant_p = true;
4902 tree value;
4904 /* Even when ctor is constant, it might contain non-*_CST
4905 elements, such as addresses or trapping values like
4906 1.0/0.0 - 1.0/0.0. Such expressions don't belong
4907 in VECTOR_CST nodes. */
4908 FOR_EACH_CONSTRUCTOR_VALUE (elts, ix, value)
4909 if (!CONSTANT_CLASS_P (value))
4911 constant_p = false;
4912 break;
4915 if (constant_p)
4917 TREE_OPERAND (*expr_p, 1) = build_vector_from_ctor (type, elts);
4918 break;
4921 TREE_CONSTANT (ctor) = 0;
4924 /* Vector types use CONSTRUCTOR all the way through gimple
4925 compilation as a general initializer. */
4926 FOR_EACH_VEC_SAFE_ELT (elts, ix, ce)
4928 enum gimplify_status tret;
4929 tret = gimplify_expr (&ce->value, pre_p, post_p, is_gimple_val,
4930 fb_rvalue);
4931 if (tret == GS_ERROR)
4932 ret = GS_ERROR;
4933 else if (TREE_STATIC (ctor)
4934 && !initializer_constant_valid_p (ce->value,
4935 TREE_TYPE (ce->value)))
4936 TREE_STATIC (ctor) = 0;
4938 if (!is_gimple_reg (TREE_OPERAND (*expr_p, 0)))
4939 TREE_OPERAND (*expr_p, 1) = get_formal_tmp_var (ctor, pre_p);
4941 break;
4943 default:
4944 /* So how did we get a CONSTRUCTOR for a scalar type? */
4945 gcc_unreachable ();
4948 if (ret == GS_ERROR)
4949 return GS_ERROR;
4950 /* If we have gimplified both sides of the initializer but have
4951 not emitted an assignment, do so now. */
4952 if (*expr_p)
4954 tree lhs = TREE_OPERAND (*expr_p, 0);
4955 tree rhs = TREE_OPERAND (*expr_p, 1);
4956 if (want_value && object == lhs)
4957 lhs = unshare_expr (lhs);
4958 gassign *init = gimple_build_assign (lhs, rhs);
4959 gimplify_seq_add_stmt (pre_p, init);
4961 if (want_value)
4963 *expr_p = object;
4964 return GS_OK;
4966 else
4968 *expr_p = NULL;
4969 return GS_ALL_DONE;
4973 /* Given a pointer value OP0, return a simplified version of an
4974 indirection through OP0, or NULL_TREE if no simplification is
4975 possible. This may only be applied to a rhs of an expression.
4976 Note that the resulting type may be different from the type pointed
4977 to in the sense that it is still compatible from the langhooks
4978 point of view. */
4980 static tree
4981 gimple_fold_indirect_ref_rhs (tree t)
4983 return gimple_fold_indirect_ref (t);
4986 /* Subroutine of gimplify_modify_expr to do simplifications of
4987 MODIFY_EXPRs based on the code of the RHS. We loop for as long as
4988 something changes. */
4990 static enum gimplify_status
4991 gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p,
4992 gimple_seq *pre_p, gimple_seq *post_p,
4993 bool want_value)
4995 enum gimplify_status ret = GS_UNHANDLED;
4996 bool changed;
5000 changed = false;
5001 switch (TREE_CODE (*from_p))
5003 case VAR_DECL:
5004 /* If we're assigning from a read-only variable initialized with
5005 a constructor, do the direct assignment from the constructor,
5006 but only if neither source nor target are volatile since this
5007 latter assignment might end up being done on a per-field basis. */
5008 if (DECL_INITIAL (*from_p)
5009 && TREE_READONLY (*from_p)
5010 && !TREE_THIS_VOLATILE (*from_p)
5011 && !TREE_THIS_VOLATILE (*to_p)
5012 && TREE_CODE (DECL_INITIAL (*from_p)) == CONSTRUCTOR)
5014 tree old_from = *from_p;
5015 enum gimplify_status subret;
5017 /* Move the constructor into the RHS. */
5018 *from_p = unshare_expr (DECL_INITIAL (*from_p));
5020 /* Let's see if gimplify_init_constructor will need to put
5021 it in memory. */
5022 subret = gimplify_init_constructor (expr_p, NULL, NULL,
5023 false, true);
5024 if (subret == GS_ERROR)
5026 /* If so, revert the change. */
5027 *from_p = old_from;
5029 else
5031 ret = GS_OK;
5032 changed = true;
5035 break;
5036 case INDIRECT_REF:
5038 /* If we have code like
5040 *(const A*)(A*)&x
5042 where the type of "x" is a (possibly cv-qualified variant
5043 of "A"), treat the entire expression as identical to "x".
5044 This kind of code arises in C++ when an object is bound
5045 to a const reference, and if "x" is a TARGET_EXPR we want
5046 to take advantage of the optimization below. */
5047 bool volatile_p = TREE_THIS_VOLATILE (*from_p);
5048 tree t = gimple_fold_indirect_ref_rhs (TREE_OPERAND (*from_p, 0));
5049 if (t)
5051 if (TREE_THIS_VOLATILE (t) != volatile_p)
5053 if (DECL_P (t))
5054 t = build_simple_mem_ref_loc (EXPR_LOCATION (*from_p),
5055 build_fold_addr_expr (t));
5056 if (REFERENCE_CLASS_P (t))
5057 TREE_THIS_VOLATILE (t) = volatile_p;
5059 *from_p = t;
5060 ret = GS_OK;
5061 changed = true;
5063 break;
5066 case TARGET_EXPR:
5068 /* If we are initializing something from a TARGET_EXPR, strip the
5069 TARGET_EXPR and initialize it directly, if possible. This can't
5070 be done if the initializer is void, since that implies that the
5071 temporary is set in some non-trivial way.
5073 ??? What about code that pulls out the temp and uses it
5074 elsewhere? I think that such code never uses the TARGET_EXPR as
5075 an initializer. If I'm wrong, we'll die because the temp won't
5076 have any RTL. In that case, I guess we'll need to replace
5077 references somehow. */
5078 tree init = TARGET_EXPR_INITIAL (*from_p);
5080 if (init
5081 && !VOID_TYPE_P (TREE_TYPE (init)))
5083 *from_p = init;
5084 ret = GS_OK;
5085 changed = true;
5088 break;
5090 case COMPOUND_EXPR:
5091 /* Remove any COMPOUND_EXPR in the RHS so the following cases will be
5092 caught. */
5093 gimplify_compound_expr (from_p, pre_p, true);
5094 ret = GS_OK;
5095 changed = true;
5096 break;
5098 case CONSTRUCTOR:
5099 /* If we already made some changes, let the front end have a
5100 crack at this before we break it down. */
5101 if (ret != GS_UNHANDLED)
5102 break;
5103 /* If we're initializing from a CONSTRUCTOR, break this into
5104 individual MODIFY_EXPRs. */
5105 return gimplify_init_constructor (expr_p, pre_p, post_p, want_value,
5106 false);
5108 case COND_EXPR:
5109 /* If we're assigning to a non-register type, push the assignment
5110 down into the branches. This is mandatory for ADDRESSABLE types,
5111 since we cannot generate temporaries for such, but it saves a
5112 copy in other cases as well. */
5113 if (!is_gimple_reg_type (TREE_TYPE (*from_p)))
5115 /* This code should mirror the code in gimplify_cond_expr. */
5116 enum tree_code code = TREE_CODE (*expr_p);
5117 tree cond = *from_p;
5118 tree result = *to_p;
5120 ret = gimplify_expr (&result, pre_p, post_p,
5121 is_gimple_lvalue, fb_lvalue);
5122 if (ret != GS_ERROR)
5123 ret = GS_OK;
5125 /* If we are going to write RESULT more than once, clear
5126 TREE_READONLY flag, otherwise we might incorrectly promote
5127 the variable to static const and initialize it at compile
5128 time in one of the branches. */
5129 if (VAR_P (result)
5130 && TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node
5131 && TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
5132 TREE_READONLY (result) = 0;
5133 if (TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node)
5134 TREE_OPERAND (cond, 1)
5135 = build2 (code, void_type_node, result,
5136 TREE_OPERAND (cond, 1));
5137 if (TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
5138 TREE_OPERAND (cond, 2)
5139 = build2 (code, void_type_node, unshare_expr (result),
5140 TREE_OPERAND (cond, 2));
5142 TREE_TYPE (cond) = void_type_node;
5143 recalculate_side_effects (cond);
5145 if (want_value)
5147 gimplify_and_add (cond, pre_p);
5148 *expr_p = unshare_expr (result);
5150 else
5151 *expr_p = cond;
5152 return ret;
5154 break;
5156 case CALL_EXPR:
5157 /* For calls that return in memory, give *to_p as the CALL_EXPR's
5158 return slot so that we don't generate a temporary. */
5159 if (!CALL_EXPR_RETURN_SLOT_OPT (*from_p)
5160 && aggregate_value_p (*from_p, *from_p))
5162 bool use_target;
5164 if (!(rhs_predicate_for (*to_p))(*from_p))
5165 /* If we need a temporary, *to_p isn't accurate. */
5166 use_target = false;
5167 /* It's OK to use the return slot directly unless it's an NRV. */
5168 else if (TREE_CODE (*to_p) == RESULT_DECL
5169 && DECL_NAME (*to_p) == NULL_TREE
5170 && needs_to_live_in_memory (*to_p))
5171 use_target = true;
5172 else if (is_gimple_reg_type (TREE_TYPE (*to_p))
5173 || (DECL_P (*to_p) && DECL_REGISTER (*to_p)))
5174 /* Don't force regs into memory. */
5175 use_target = false;
5176 else if (TREE_CODE (*expr_p) == INIT_EXPR)
5177 /* It's OK to use the target directly if it's being
5178 initialized. */
5179 use_target = true;
5180 else if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p)))
5181 != INTEGER_CST)
5182 /* Always use the target and thus RSO for variable-sized types.
5183 GIMPLE cannot deal with a variable-sized assignment
5184 embedded in a call statement. */
5185 use_target = true;
5186 else if (TREE_CODE (*to_p) != SSA_NAME
5187 && (!is_gimple_variable (*to_p)
5188 || needs_to_live_in_memory (*to_p)))
5189 /* Don't use the original target if it's already addressable;
5190 if its address escapes, and the called function uses the
5191 NRV optimization, a conforming program could see *to_p
5192 change before the called function returns; see c++/19317.
5193 When optimizing, the return_slot pass marks more functions
5194 as safe after we have escape info. */
5195 use_target = false;
5196 else
5197 use_target = true;
5199 if (use_target)
5201 CALL_EXPR_RETURN_SLOT_OPT (*from_p) = 1;
5202 mark_addressable (*to_p);
5205 break;
5207 case WITH_SIZE_EXPR:
5208 /* Likewise for calls that return an aggregate of non-constant size,
5209 since we would not be able to generate a temporary at all. */
5210 if (TREE_CODE (TREE_OPERAND (*from_p, 0)) == CALL_EXPR)
5212 *from_p = TREE_OPERAND (*from_p, 0);
5213 /* We don't change ret in this case because the
5214 WITH_SIZE_EXPR might have been added in
5215 gimplify_modify_expr, so returning GS_OK would lead to an
5216 infinite loop. */
5217 changed = true;
5219 break;
5221 /* If we're initializing from a container, push the initialization
5222 inside it. */
5223 case CLEANUP_POINT_EXPR:
5224 case BIND_EXPR:
5225 case STATEMENT_LIST:
5227 tree wrap = *from_p;
5228 tree t;
5230 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_min_lval,
5231 fb_lvalue);
5232 if (ret != GS_ERROR)
5233 ret = GS_OK;
5235 t = voidify_wrapper_expr (wrap, *expr_p);
5236 gcc_assert (t == *expr_p);
5238 if (want_value)
5240 gimplify_and_add (wrap, pre_p);
5241 *expr_p = unshare_expr (*to_p);
5243 else
5244 *expr_p = wrap;
5245 return GS_OK;
5248 case COMPOUND_LITERAL_EXPR:
5250 tree complit = TREE_OPERAND (*expr_p, 1);
5251 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (complit);
5252 tree decl = DECL_EXPR_DECL (decl_s);
5253 tree init = DECL_INITIAL (decl);
5255 /* struct T x = (struct T) { 0, 1, 2 } can be optimized
5256 into struct T x = { 0, 1, 2 } if the address of the
5257 compound literal has never been taken. */
5258 if (!TREE_ADDRESSABLE (complit)
5259 && !TREE_ADDRESSABLE (decl)
5260 && init)
5262 *expr_p = copy_node (*expr_p);
5263 TREE_OPERAND (*expr_p, 1) = init;
5264 return GS_OK;
5268 default:
5269 break;
5272 while (changed);
5274 return ret;
5278 /* Return true if T looks like a valid GIMPLE statement. */
5280 static bool
5281 is_gimple_stmt (tree t)
5283 const enum tree_code code = TREE_CODE (t);
5285 switch (code)
5287 case NOP_EXPR:
5288 /* The only valid NOP_EXPR is the empty statement. */
5289 return IS_EMPTY_STMT (t);
5291 case BIND_EXPR:
5292 case COND_EXPR:
5293 /* These are only valid if they're void. */
5294 return TREE_TYPE (t) == NULL || VOID_TYPE_P (TREE_TYPE (t));
5296 case SWITCH_EXPR:
5297 case GOTO_EXPR:
5298 case RETURN_EXPR:
5299 case LABEL_EXPR:
5300 case CASE_LABEL_EXPR:
5301 case TRY_CATCH_EXPR:
5302 case TRY_FINALLY_EXPR:
5303 case EH_FILTER_EXPR:
5304 case CATCH_EXPR:
5305 case ASM_EXPR:
5306 case STATEMENT_LIST:
5307 case OACC_PARALLEL:
5308 case OACC_KERNELS:
5309 case OACC_DATA:
5310 case OACC_HOST_DATA:
5311 case OACC_DECLARE:
5312 case OACC_UPDATE:
5313 case OACC_ENTER_DATA:
5314 case OACC_EXIT_DATA:
5315 case OACC_CACHE:
5316 case OMP_PARALLEL:
5317 case OMP_FOR:
5318 case OMP_SIMD:
5319 case CILK_SIMD:
5320 case OMP_DISTRIBUTE:
5321 case OACC_LOOP:
5322 case OMP_SECTIONS:
5323 case OMP_SECTION:
5324 case OMP_SINGLE:
5325 case OMP_MASTER:
5326 case OMP_TASKGROUP:
5327 case OMP_ORDERED:
5328 case OMP_CRITICAL:
5329 case OMP_TASK:
5330 case OMP_TARGET:
5331 case OMP_TARGET_DATA:
5332 case OMP_TARGET_UPDATE:
5333 case OMP_TARGET_ENTER_DATA:
5334 case OMP_TARGET_EXIT_DATA:
5335 case OMP_TASKLOOP:
5336 case OMP_TEAMS:
5337 /* These are always void. */
5338 return true;
5340 case CALL_EXPR:
5341 case MODIFY_EXPR:
5342 case PREDICT_EXPR:
5343 /* These are valid regardless of their type. */
5344 return true;
5346 default:
5347 return false;
5352 /* Promote partial stores to COMPLEX variables to total stores. *EXPR_P is
5353 a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a variable with
5354 DECL_GIMPLE_REG_P set.
5356 IMPORTANT NOTE: This promotion is performed by introducing a load of the
5357 other, unmodified part of the complex object just before the total store.
5358 As a consequence, if the object is still uninitialized, an undefined value
5359 will be loaded into a register, which may result in a spurious exception
5360 if the register is floating-point and the value happens to be a signaling
5361 NaN for example. Then the fully-fledged complex operations lowering pass
5362 followed by a DCE pass are necessary in order to fix things up. */
5364 static enum gimplify_status
5365 gimplify_modify_expr_complex_part (tree *expr_p, gimple_seq *pre_p,
5366 bool want_value)
5368 enum tree_code code, ocode;
5369 tree lhs, rhs, new_rhs, other, realpart, imagpart;
5371 lhs = TREE_OPERAND (*expr_p, 0);
5372 rhs = TREE_OPERAND (*expr_p, 1);
5373 code = TREE_CODE (lhs);
5374 lhs = TREE_OPERAND (lhs, 0);
5376 ocode = code == REALPART_EXPR ? IMAGPART_EXPR : REALPART_EXPR;
5377 other = build1 (ocode, TREE_TYPE (rhs), lhs);
5378 TREE_NO_WARNING (other) = 1;
5379 other = get_formal_tmp_var (other, pre_p);
5381 realpart = code == REALPART_EXPR ? rhs : other;
5382 imagpart = code == REALPART_EXPR ? other : rhs;
5384 if (TREE_CONSTANT (realpart) && TREE_CONSTANT (imagpart))
5385 new_rhs = build_complex (TREE_TYPE (lhs), realpart, imagpart);
5386 else
5387 new_rhs = build2 (COMPLEX_EXPR, TREE_TYPE (lhs), realpart, imagpart);
5389 gimplify_seq_add_stmt (pre_p, gimple_build_assign (lhs, new_rhs));
5390 *expr_p = (want_value) ? rhs : NULL_TREE;
5392 return GS_ALL_DONE;
5395 /* Gimplify the MODIFY_EXPR node pointed to by EXPR_P.
5397 modify_expr
5398 : varname '=' rhs
5399 | '*' ID '=' rhs
5401 PRE_P points to the list where side effects that must happen before
5402 *EXPR_P should be stored.
5404 POST_P points to the list where side effects that must happen after
5405 *EXPR_P should be stored.
5407 WANT_VALUE is nonzero iff we want to use the value of this expression
5408 in another expression. */
5410 static enum gimplify_status
5411 gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
5412 bool want_value)
5414 tree *from_p = &TREE_OPERAND (*expr_p, 1);
5415 tree *to_p = &TREE_OPERAND (*expr_p, 0);
5416 enum gimplify_status ret = GS_UNHANDLED;
5417 gimple *assign;
5418 location_t loc = EXPR_LOCATION (*expr_p);
5419 gimple_stmt_iterator gsi;
5421 gcc_assert (TREE_CODE (*expr_p) == MODIFY_EXPR
5422 || TREE_CODE (*expr_p) == INIT_EXPR);
5424 /* Trying to simplify a clobber using normal logic doesn't work,
5425 so handle it here. */
5426 if (TREE_CLOBBER_P (*from_p))
5428 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
5429 if (ret == GS_ERROR)
5430 return ret;
5431 gcc_assert (!want_value
5432 && (VAR_P (*to_p) || TREE_CODE (*to_p) == MEM_REF));
5433 gimplify_seq_add_stmt (pre_p, gimple_build_assign (*to_p, *from_p));
5434 *expr_p = NULL;
5435 return GS_ALL_DONE;
5438 /* Insert pointer conversions required by the middle-end that are not
5439 required by the frontend. This fixes middle-end type checking for
5440 for example gcc.dg/redecl-6.c. */
5441 if (POINTER_TYPE_P (TREE_TYPE (*to_p)))
5443 STRIP_USELESS_TYPE_CONVERSION (*from_p);
5444 if (!useless_type_conversion_p (TREE_TYPE (*to_p), TREE_TYPE (*from_p)))
5445 *from_p = fold_convert_loc (loc, TREE_TYPE (*to_p), *from_p);
5448 /* See if any simplifications can be done based on what the RHS is. */
5449 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
5450 want_value);
5451 if (ret != GS_UNHANDLED)
5452 return ret;
5454 /* For zero sized types only gimplify the left hand side and right hand
5455 side as statements and throw away the assignment. Do this after
5456 gimplify_modify_expr_rhs so we handle TARGET_EXPRs of addressable
5457 types properly. */
5458 if (zero_sized_type (TREE_TYPE (*from_p)) && !want_value)
5460 gimplify_stmt (from_p, pre_p);
5461 gimplify_stmt (to_p, pre_p);
5462 *expr_p = NULL_TREE;
5463 return GS_ALL_DONE;
5466 /* If the value being copied is of variable width, compute the length
5467 of the copy into a WITH_SIZE_EXPR. Note that we need to do this
5468 before gimplifying any of the operands so that we can resolve any
5469 PLACEHOLDER_EXPRs in the size. Also note that the RTL expander uses
5470 the size of the expression to be copied, not of the destination, so
5471 that is what we must do here. */
5472 maybe_with_size_expr (from_p);
5474 /* As a special case, we have to temporarily allow for assignments
5475 with a CALL_EXPR on the RHS. Since in GIMPLE a function call is
5476 a toplevel statement, when gimplifying the GENERIC expression
5477 MODIFY_EXPR <a, CALL_EXPR <foo>>, we cannot create the tuple
5478 GIMPLE_ASSIGN <a, GIMPLE_CALL <foo>>.
5480 Instead, we need to create the tuple GIMPLE_CALL <a, foo>. To
5481 prevent gimplify_expr from trying to create a new temporary for
5482 foo's LHS, we tell it that it should only gimplify until it
5483 reaches the CALL_EXPR. On return from gimplify_expr, the newly
5484 created GIMPLE_CALL <foo> will be the last statement in *PRE_P
5485 and all we need to do here is set 'a' to be its LHS. */
5487 /* Gimplify the RHS first for C++17 and bug 71104. */
5488 gimple_predicate initial_pred = initial_rhs_predicate_for (*to_p);
5489 ret = gimplify_expr (from_p, pre_p, post_p, initial_pred, fb_rvalue);
5490 if (ret == GS_ERROR)
5491 return ret;
5493 /* Then gimplify the LHS. */
5494 /* If we gimplified the RHS to a CALL_EXPR and that call may return
5495 twice we have to make sure to gimplify into non-SSA as otherwise
5496 the abnormal edge added later will make those defs not dominate
5497 their uses.
5498 ??? Technically this applies only to the registers used in the
5499 resulting non-register *TO_P. */
5500 bool saved_into_ssa = gimplify_ctxp->into_ssa;
5501 if (saved_into_ssa
5502 && TREE_CODE (*from_p) == CALL_EXPR
5503 && call_expr_flags (*from_p) & ECF_RETURNS_TWICE)
5504 gimplify_ctxp->into_ssa = false;
5505 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
5506 gimplify_ctxp->into_ssa = saved_into_ssa;
5507 if (ret == GS_ERROR)
5508 return ret;
5510 /* Now that the LHS is gimplified, re-gimplify the RHS if our initial
5511 guess for the predicate was wrong. */
5512 gimple_predicate final_pred = rhs_predicate_for (*to_p);
5513 if (final_pred != initial_pred)
5515 ret = gimplify_expr (from_p, pre_p, post_p, final_pred, fb_rvalue);
5516 if (ret == GS_ERROR)
5517 return ret;
5520 /* In case of va_arg internal fn wrappped in a WITH_SIZE_EXPR, add the type
5521 size as argument to the call. */
5522 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
5524 tree call = TREE_OPERAND (*from_p, 0);
5525 tree vlasize = TREE_OPERAND (*from_p, 1);
5527 if (TREE_CODE (call) == CALL_EXPR
5528 && CALL_EXPR_IFN (call) == IFN_VA_ARG)
5530 int nargs = call_expr_nargs (call);
5531 tree type = TREE_TYPE (call);
5532 tree ap = CALL_EXPR_ARG (call, 0);
5533 tree tag = CALL_EXPR_ARG (call, 1);
5534 tree aptag = CALL_EXPR_ARG (call, 2);
5535 tree newcall = build_call_expr_internal_loc (EXPR_LOCATION (call),
5536 IFN_VA_ARG, type,
5537 nargs + 1, ap, tag,
5538 aptag, vlasize);
5539 TREE_OPERAND (*from_p, 0) = newcall;
5543 /* Now see if the above changed *from_p to something we handle specially. */
5544 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
5545 want_value);
5546 if (ret != GS_UNHANDLED)
5547 return ret;
5549 /* If we've got a variable sized assignment between two lvalues (i.e. does
5550 not involve a call), then we can make things a bit more straightforward
5551 by converting the assignment to memcpy or memset. */
5552 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
5554 tree from = TREE_OPERAND (*from_p, 0);
5555 tree size = TREE_OPERAND (*from_p, 1);
5557 if (TREE_CODE (from) == CONSTRUCTOR)
5558 return gimplify_modify_expr_to_memset (expr_p, size, want_value, pre_p);
5560 if (is_gimple_addressable (from))
5562 *from_p = from;
5563 return gimplify_modify_expr_to_memcpy (expr_p, size, want_value,
5564 pre_p);
5568 /* Transform partial stores to non-addressable complex variables into
5569 total stores. This allows us to use real instead of virtual operands
5570 for these variables, which improves optimization. */
5571 if ((TREE_CODE (*to_p) == REALPART_EXPR
5572 || TREE_CODE (*to_p) == IMAGPART_EXPR)
5573 && is_gimple_reg (TREE_OPERAND (*to_p, 0)))
5574 return gimplify_modify_expr_complex_part (expr_p, pre_p, want_value);
5576 /* Try to alleviate the effects of the gimplification creating artificial
5577 temporaries (see for example is_gimple_reg_rhs) on the debug info, but
5578 make sure not to create DECL_DEBUG_EXPR links across functions. */
5579 if (!gimplify_ctxp->into_ssa
5580 && VAR_P (*from_p)
5581 && DECL_IGNORED_P (*from_p)
5582 && DECL_P (*to_p)
5583 && !DECL_IGNORED_P (*to_p)
5584 && decl_function_context (*to_p) == current_function_decl
5585 && decl_function_context (*from_p) == current_function_decl)
5587 if (!DECL_NAME (*from_p) && DECL_NAME (*to_p))
5588 DECL_NAME (*from_p)
5589 = create_tmp_var_name (IDENTIFIER_POINTER (DECL_NAME (*to_p)));
5590 DECL_HAS_DEBUG_EXPR_P (*from_p) = 1;
5591 SET_DECL_DEBUG_EXPR (*from_p, *to_p);
5594 if (want_value && TREE_THIS_VOLATILE (*to_p))
5595 *from_p = get_initialized_tmp_var (*from_p, pre_p, post_p);
5597 if (TREE_CODE (*from_p) == CALL_EXPR)
5599 /* Since the RHS is a CALL_EXPR, we need to create a GIMPLE_CALL
5600 instead of a GIMPLE_ASSIGN. */
5601 gcall *call_stmt;
5602 if (CALL_EXPR_FN (*from_p) == NULL_TREE)
5604 /* Gimplify internal functions created in the FEs. */
5605 int nargs = call_expr_nargs (*from_p), i;
5606 enum internal_fn ifn = CALL_EXPR_IFN (*from_p);
5607 auto_vec<tree> vargs (nargs);
5609 for (i = 0; i < nargs; i++)
5611 gimplify_arg (&CALL_EXPR_ARG (*from_p, i), pre_p,
5612 EXPR_LOCATION (*from_p));
5613 vargs.quick_push (CALL_EXPR_ARG (*from_p, i));
5615 call_stmt = gimple_build_call_internal_vec (ifn, vargs);
5616 gimple_set_location (call_stmt, EXPR_LOCATION (*expr_p));
5618 else
5620 tree fnptrtype = TREE_TYPE (CALL_EXPR_FN (*from_p));
5621 CALL_EXPR_FN (*from_p) = TREE_OPERAND (CALL_EXPR_FN (*from_p), 0);
5622 STRIP_USELESS_TYPE_CONVERSION (CALL_EXPR_FN (*from_p));
5623 tree fndecl = get_callee_fndecl (*from_p);
5624 if (fndecl
5625 && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
5626 && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT
5627 && call_expr_nargs (*from_p) == 3)
5628 call_stmt = gimple_build_call_internal (IFN_BUILTIN_EXPECT, 3,
5629 CALL_EXPR_ARG (*from_p, 0),
5630 CALL_EXPR_ARG (*from_p, 1),
5631 CALL_EXPR_ARG (*from_p, 2));
5632 else
5634 call_stmt = gimple_build_call_from_tree (*from_p);
5635 gimple_call_set_fntype (call_stmt, TREE_TYPE (fnptrtype));
5638 notice_special_calls (call_stmt);
5639 if (!gimple_call_noreturn_p (call_stmt) || !should_remove_lhs_p (*to_p))
5640 gimple_call_set_lhs (call_stmt, *to_p);
5641 else if (TREE_CODE (*to_p) == SSA_NAME)
5642 /* The above is somewhat premature, avoid ICEing later for a
5643 SSA name w/o a definition. We may have uses in the GIMPLE IL.
5644 ??? This doesn't make it a default-def. */
5645 SSA_NAME_DEF_STMT (*to_p) = gimple_build_nop ();
5647 if (EXPR_CILK_SPAWN (*from_p))
5648 gimplify_cilk_detach (pre_p);
5649 assign = call_stmt;
5651 else
5653 assign = gimple_build_assign (*to_p, *from_p);
5654 gimple_set_location (assign, EXPR_LOCATION (*expr_p));
5655 if (COMPARISON_CLASS_P (*from_p))
5656 gimple_set_no_warning (assign, TREE_NO_WARNING (*from_p));
5659 if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p))
5661 /* We should have got an SSA name from the start. */
5662 gcc_assert (TREE_CODE (*to_p) == SSA_NAME
5663 || ! gimple_in_ssa_p (cfun));
5666 gimplify_seq_add_stmt (pre_p, assign);
5667 gsi = gsi_last (*pre_p);
5668 maybe_fold_stmt (&gsi);
5670 if (want_value)
5672 *expr_p = TREE_THIS_VOLATILE (*to_p) ? *from_p : unshare_expr (*to_p);
5673 return GS_OK;
5675 else
5676 *expr_p = NULL;
5678 return GS_ALL_DONE;
5681 /* Gimplify a comparison between two variable-sized objects. Do this
5682 with a call to BUILT_IN_MEMCMP. */
5684 static enum gimplify_status
5685 gimplify_variable_sized_compare (tree *expr_p)
5687 location_t loc = EXPR_LOCATION (*expr_p);
5688 tree op0 = TREE_OPERAND (*expr_p, 0);
5689 tree op1 = TREE_OPERAND (*expr_p, 1);
5690 tree t, arg, dest, src, expr;
5692 arg = TYPE_SIZE_UNIT (TREE_TYPE (op0));
5693 arg = unshare_expr (arg);
5694 arg = SUBSTITUTE_PLACEHOLDER_IN_EXPR (arg, op0);
5695 src = build_fold_addr_expr_loc (loc, op1);
5696 dest = build_fold_addr_expr_loc (loc, op0);
5697 t = builtin_decl_implicit (BUILT_IN_MEMCMP);
5698 t = build_call_expr_loc (loc, t, 3, dest, src, arg);
5700 expr
5701 = build2 (TREE_CODE (*expr_p), TREE_TYPE (*expr_p), t, integer_zero_node);
5702 SET_EXPR_LOCATION (expr, loc);
5703 *expr_p = expr;
5705 return GS_OK;
5708 /* Gimplify a comparison between two aggregate objects of integral scalar
5709 mode as a comparison between the bitwise equivalent scalar values. */
5711 static enum gimplify_status
5712 gimplify_scalar_mode_aggregate_compare (tree *expr_p)
5714 location_t loc = EXPR_LOCATION (*expr_p);
5715 tree op0 = TREE_OPERAND (*expr_p, 0);
5716 tree op1 = TREE_OPERAND (*expr_p, 1);
5718 tree type = TREE_TYPE (op0);
5719 tree scalar_type = lang_hooks.types.type_for_mode (TYPE_MODE (type), 1);
5721 op0 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op0);
5722 op1 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op1);
5724 *expr_p
5725 = fold_build2_loc (loc, TREE_CODE (*expr_p), TREE_TYPE (*expr_p), op0, op1);
5727 return GS_OK;
5730 /* Gimplify an expression sequence. This function gimplifies each
5731 expression and rewrites the original expression with the last
5732 expression of the sequence in GIMPLE form.
5734 PRE_P points to the list where the side effects for all the
5735 expressions in the sequence will be emitted.
5737 WANT_VALUE is true when the result of the last COMPOUND_EXPR is used. */
5739 static enum gimplify_status
5740 gimplify_compound_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
5742 tree t = *expr_p;
5746 tree *sub_p = &TREE_OPERAND (t, 0);
5748 if (TREE_CODE (*sub_p) == COMPOUND_EXPR)
5749 gimplify_compound_expr (sub_p, pre_p, false);
5750 else
5751 gimplify_stmt (sub_p, pre_p);
5753 t = TREE_OPERAND (t, 1);
5755 while (TREE_CODE (t) == COMPOUND_EXPR);
5757 *expr_p = t;
5758 if (want_value)
5759 return GS_OK;
5760 else
5762 gimplify_stmt (expr_p, pre_p);
5763 return GS_ALL_DONE;
5767 /* Gimplify a SAVE_EXPR node. EXPR_P points to the expression to
5768 gimplify. After gimplification, EXPR_P will point to a new temporary
5769 that holds the original value of the SAVE_EXPR node.
5771 PRE_P points to the list where side effects that must happen before
5772 *EXPR_P should be stored. */
5774 static enum gimplify_status
5775 gimplify_save_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
5777 enum gimplify_status ret = GS_ALL_DONE;
5778 tree val;
5780 gcc_assert (TREE_CODE (*expr_p) == SAVE_EXPR);
5781 val = TREE_OPERAND (*expr_p, 0);
5783 /* If the SAVE_EXPR has not been resolved, then evaluate it once. */
5784 if (!SAVE_EXPR_RESOLVED_P (*expr_p))
5786 /* The operand may be a void-valued expression such as SAVE_EXPRs
5787 generated by the Java frontend for class initialization. It is
5788 being executed only for its side-effects. */
5789 if (TREE_TYPE (val) == void_type_node)
5791 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
5792 is_gimple_stmt, fb_none);
5793 val = NULL;
5795 else
5796 /* The temporary may not be an SSA name as later abnormal and EH
5797 control flow may invalidate use/def domination. */
5798 val = get_initialized_tmp_var (val, pre_p, post_p, false);
5800 TREE_OPERAND (*expr_p, 0) = val;
5801 SAVE_EXPR_RESOLVED_P (*expr_p) = 1;
5804 *expr_p = val;
5806 return ret;
5809 /* Rewrite the ADDR_EXPR node pointed to by EXPR_P
5811 unary_expr
5812 : ...
5813 | '&' varname
5816 PRE_P points to the list where side effects that must happen before
5817 *EXPR_P should be stored.
5819 POST_P points to the list where side effects that must happen after
5820 *EXPR_P should be stored. */
5822 static enum gimplify_status
5823 gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
5825 tree expr = *expr_p;
5826 tree op0 = TREE_OPERAND (expr, 0);
5827 enum gimplify_status ret;
5828 location_t loc = EXPR_LOCATION (*expr_p);
5830 switch (TREE_CODE (op0))
5832 case INDIRECT_REF:
5833 do_indirect_ref:
5834 /* Check if we are dealing with an expression of the form '&*ptr'.
5835 While the front end folds away '&*ptr' into 'ptr', these
5836 expressions may be generated internally by the compiler (e.g.,
5837 builtins like __builtin_va_end). */
5838 /* Caution: the silent array decomposition semantics we allow for
5839 ADDR_EXPR means we can't always discard the pair. */
5840 /* Gimplification of the ADDR_EXPR operand may drop
5841 cv-qualification conversions, so make sure we add them if
5842 needed. */
5844 tree op00 = TREE_OPERAND (op0, 0);
5845 tree t_expr = TREE_TYPE (expr);
5846 tree t_op00 = TREE_TYPE (op00);
5848 if (!useless_type_conversion_p (t_expr, t_op00))
5849 op00 = fold_convert_loc (loc, TREE_TYPE (expr), op00);
5850 *expr_p = op00;
5851 ret = GS_OK;
5853 break;
5855 case VIEW_CONVERT_EXPR:
5856 /* Take the address of our operand and then convert it to the type of
5857 this ADDR_EXPR.
5859 ??? The interactions of VIEW_CONVERT_EXPR and aliasing is not at
5860 all clear. The impact of this transformation is even less clear. */
5862 /* If the operand is a useless conversion, look through it. Doing so
5863 guarantees that the ADDR_EXPR and its operand will remain of the
5864 same type. */
5865 if (tree_ssa_useless_type_conversion (TREE_OPERAND (op0, 0)))
5866 op0 = TREE_OPERAND (op0, 0);
5868 *expr_p = fold_convert_loc (loc, TREE_TYPE (expr),
5869 build_fold_addr_expr_loc (loc,
5870 TREE_OPERAND (op0, 0)));
5871 ret = GS_OK;
5872 break;
5874 case MEM_REF:
5875 if (integer_zerop (TREE_OPERAND (op0, 1)))
5876 goto do_indirect_ref;
5878 /* fall through */
5880 default:
5881 /* If we see a call to a declared builtin or see its address
5882 being taken (we can unify those cases here) then we can mark
5883 the builtin for implicit generation by GCC. */
5884 if (TREE_CODE (op0) == FUNCTION_DECL
5885 && DECL_BUILT_IN_CLASS (op0) == BUILT_IN_NORMAL
5886 && builtin_decl_declared_p (DECL_FUNCTION_CODE (op0)))
5887 set_builtin_decl_implicit_p (DECL_FUNCTION_CODE (op0), true);
5889 /* We use fb_either here because the C frontend sometimes takes
5890 the address of a call that returns a struct; see
5891 gcc.dg/c99-array-lval-1.c. The gimplifier will correctly make
5892 the implied temporary explicit. */
5894 /* Make the operand addressable. */
5895 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, post_p,
5896 is_gimple_addressable, fb_either);
5897 if (ret == GS_ERROR)
5898 break;
5900 /* Then mark it. Beware that it may not be possible to do so directly
5901 if a temporary has been created by the gimplification. */
5902 prepare_gimple_addressable (&TREE_OPERAND (expr, 0), pre_p);
5904 op0 = TREE_OPERAND (expr, 0);
5906 /* For various reasons, the gimplification of the expression
5907 may have made a new INDIRECT_REF. */
5908 if (TREE_CODE (op0) == INDIRECT_REF)
5909 goto do_indirect_ref;
5911 mark_addressable (TREE_OPERAND (expr, 0));
5913 /* The FEs may end up building ADDR_EXPRs early on a decl with
5914 an incomplete type. Re-build ADDR_EXPRs in canonical form
5915 here. */
5916 if (!types_compatible_p (TREE_TYPE (op0), TREE_TYPE (TREE_TYPE (expr))))
5917 *expr_p = build_fold_addr_expr (op0);
5919 /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly. */
5920 recompute_tree_invariant_for_addr_expr (*expr_p);
5922 /* If we re-built the ADDR_EXPR add a conversion to the original type
5923 if required. */
5924 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
5925 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
5927 break;
5930 return ret;
5933 /* Gimplify the operands of an ASM_EXPR. Input operands should be a gimple
5934 value; output operands should be a gimple lvalue. */
5936 static enum gimplify_status
5937 gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
5939 tree expr;
5940 int noutputs;
5941 const char **oconstraints;
5942 int i;
5943 tree link;
5944 const char *constraint;
5945 bool allows_mem, allows_reg, is_inout;
5946 enum gimplify_status ret, tret;
5947 gasm *stmt;
5948 vec<tree, va_gc> *inputs;
5949 vec<tree, va_gc> *outputs;
5950 vec<tree, va_gc> *clobbers;
5951 vec<tree, va_gc> *labels;
5952 tree link_next;
5954 expr = *expr_p;
5955 noutputs = list_length (ASM_OUTPUTS (expr));
5956 oconstraints = (const char **) alloca ((noutputs) * sizeof (const char *));
5958 inputs = NULL;
5959 outputs = NULL;
5960 clobbers = NULL;
5961 labels = NULL;
5963 ret = GS_ALL_DONE;
5964 link_next = NULL_TREE;
5965 for (i = 0, link = ASM_OUTPUTS (expr); link; ++i, link = link_next)
5967 bool ok;
5968 size_t constraint_len;
5970 link_next = TREE_CHAIN (link);
5972 oconstraints[i]
5973 = constraint
5974 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
5975 constraint_len = strlen (constraint);
5976 if (constraint_len == 0)
5977 continue;
5979 ok = parse_output_constraint (&constraint, i, 0, 0,
5980 &allows_mem, &allows_reg, &is_inout);
5981 if (!ok)
5983 ret = GS_ERROR;
5984 is_inout = false;
5987 if (!allows_reg && allows_mem)
5988 mark_addressable (TREE_VALUE (link));
5990 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
5991 is_inout ? is_gimple_min_lval : is_gimple_lvalue,
5992 fb_lvalue | fb_mayfail);
5993 if (tret == GS_ERROR)
5995 error ("invalid lvalue in asm output %d", i);
5996 ret = tret;
5999 /* If the constraint does not allow memory make sure we gimplify
6000 it to a register if it is not already but its base is. This
6001 happens for complex and vector components. */
6002 if (!allows_mem)
6004 tree op = TREE_VALUE (link);
6005 if (! is_gimple_val (op)
6006 && is_gimple_reg_type (TREE_TYPE (op))
6007 && is_gimple_reg (get_base_address (op)))
6009 tree tem = create_tmp_reg (TREE_TYPE (op));
6010 tree ass;
6011 if (is_inout)
6013 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem),
6014 tem, unshare_expr (op));
6015 gimplify_and_add (ass, pre_p);
6017 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem), op, tem);
6018 gimplify_and_add (ass, post_p);
6020 TREE_VALUE (link) = tem;
6021 tret = GS_OK;
6025 vec_safe_push (outputs, link);
6026 TREE_CHAIN (link) = NULL_TREE;
6028 if (is_inout)
6030 /* An input/output operand. To give the optimizers more
6031 flexibility, split it into separate input and output
6032 operands. */
6033 tree input;
6034 /* Buffer big enough to format a 32-bit UINT_MAX into. */
6035 char buf[11];
6037 /* Turn the in/out constraint into an output constraint. */
6038 char *p = xstrdup (constraint);
6039 p[0] = '=';
6040 TREE_VALUE (TREE_PURPOSE (link)) = build_string (constraint_len, p);
6042 /* And add a matching input constraint. */
6043 if (allows_reg)
6045 sprintf (buf, "%u", i);
6047 /* If there are multiple alternatives in the constraint,
6048 handle each of them individually. Those that allow register
6049 will be replaced with operand number, the others will stay
6050 unchanged. */
6051 if (strchr (p, ',') != NULL)
6053 size_t len = 0, buflen = strlen (buf);
6054 char *beg, *end, *str, *dst;
6056 for (beg = p + 1;;)
6058 end = strchr (beg, ',');
6059 if (end == NULL)
6060 end = strchr (beg, '\0');
6061 if ((size_t) (end - beg) < buflen)
6062 len += buflen + 1;
6063 else
6064 len += end - beg + 1;
6065 if (*end)
6066 beg = end + 1;
6067 else
6068 break;
6071 str = (char *) alloca (len);
6072 for (beg = p + 1, dst = str;;)
6074 const char *tem;
6075 bool mem_p, reg_p, inout_p;
6077 end = strchr (beg, ',');
6078 if (end)
6079 *end = '\0';
6080 beg[-1] = '=';
6081 tem = beg - 1;
6082 parse_output_constraint (&tem, i, 0, 0,
6083 &mem_p, &reg_p, &inout_p);
6084 if (dst != str)
6085 *dst++ = ',';
6086 if (reg_p)
6088 memcpy (dst, buf, buflen);
6089 dst += buflen;
6091 else
6093 if (end)
6094 len = end - beg;
6095 else
6096 len = strlen (beg);
6097 memcpy (dst, beg, len);
6098 dst += len;
6100 if (end)
6101 beg = end + 1;
6102 else
6103 break;
6105 *dst = '\0';
6106 input = build_string (dst - str, str);
6108 else
6109 input = build_string (strlen (buf), buf);
6111 else
6112 input = build_string (constraint_len - 1, constraint + 1);
6114 free (p);
6116 input = build_tree_list (build_tree_list (NULL_TREE, input),
6117 unshare_expr (TREE_VALUE (link)));
6118 ASM_INPUTS (expr) = chainon (ASM_INPUTS (expr), input);
6122 link_next = NULL_TREE;
6123 for (link = ASM_INPUTS (expr); link; ++i, link = link_next)
6125 link_next = TREE_CHAIN (link);
6126 constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
6127 parse_input_constraint (&constraint, 0, 0, noutputs, 0,
6128 oconstraints, &allows_mem, &allows_reg);
6130 /* If we can't make copies, we can only accept memory. */
6131 if (TREE_ADDRESSABLE (TREE_TYPE (TREE_VALUE (link))))
6133 if (allows_mem)
6134 allows_reg = 0;
6135 else
6137 error ("impossible constraint in %<asm%>");
6138 error ("non-memory input %d must stay in memory", i);
6139 return GS_ERROR;
6143 /* If the operand is a memory input, it should be an lvalue. */
6144 if (!allows_reg && allows_mem)
6146 tree inputv = TREE_VALUE (link);
6147 STRIP_NOPS (inputv);
6148 if (TREE_CODE (inputv) == PREDECREMENT_EXPR
6149 || TREE_CODE (inputv) == PREINCREMENT_EXPR
6150 || TREE_CODE (inputv) == POSTDECREMENT_EXPR
6151 || TREE_CODE (inputv) == POSTINCREMENT_EXPR
6152 || TREE_CODE (inputv) == MODIFY_EXPR)
6153 TREE_VALUE (link) = error_mark_node;
6154 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6155 is_gimple_lvalue, fb_lvalue | fb_mayfail);
6156 if (tret != GS_ERROR)
6158 /* Unlike output operands, memory inputs are not guaranteed
6159 to be lvalues by the FE, and while the expressions are
6160 marked addressable there, if it is e.g. a statement
6161 expression, temporaries in it might not end up being
6162 addressable. They might be already used in the IL and thus
6163 it is too late to make them addressable now though. */
6164 tree x = TREE_VALUE (link);
6165 while (handled_component_p (x))
6166 x = TREE_OPERAND (x, 0);
6167 if (TREE_CODE (x) == MEM_REF
6168 && TREE_CODE (TREE_OPERAND (x, 0)) == ADDR_EXPR)
6169 x = TREE_OPERAND (TREE_OPERAND (x, 0), 0);
6170 if ((VAR_P (x)
6171 || TREE_CODE (x) == PARM_DECL
6172 || TREE_CODE (x) == RESULT_DECL)
6173 && !TREE_ADDRESSABLE (x)
6174 && is_gimple_reg (x))
6176 warning_at (EXPR_LOC_OR_LOC (TREE_VALUE (link),
6177 input_location), 0,
6178 "memory input %d is not directly addressable",
6180 prepare_gimple_addressable (&TREE_VALUE (link), pre_p);
6183 mark_addressable (TREE_VALUE (link));
6184 if (tret == GS_ERROR)
6186 error_at (EXPR_LOC_OR_LOC (TREE_VALUE (link), input_location),
6187 "memory input %d is not directly addressable", i);
6188 ret = tret;
6191 else
6193 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6194 is_gimple_asm_val, fb_rvalue);
6195 if (tret == GS_ERROR)
6196 ret = tret;
6199 TREE_CHAIN (link) = NULL_TREE;
6200 vec_safe_push (inputs, link);
6203 link_next = NULL_TREE;
6204 for (link = ASM_CLOBBERS (expr); link; ++i, link = link_next)
6206 link_next = TREE_CHAIN (link);
6207 TREE_CHAIN (link) = NULL_TREE;
6208 vec_safe_push (clobbers, link);
6211 link_next = NULL_TREE;
6212 for (link = ASM_LABELS (expr); link; ++i, link = link_next)
6214 link_next = TREE_CHAIN (link);
6215 TREE_CHAIN (link) = NULL_TREE;
6216 vec_safe_push (labels, link);
6219 /* Do not add ASMs with errors to the gimple IL stream. */
6220 if (ret != GS_ERROR)
6222 stmt = gimple_build_asm_vec (TREE_STRING_POINTER (ASM_STRING (expr)),
6223 inputs, outputs, clobbers, labels);
6225 gimple_asm_set_volatile (stmt, ASM_VOLATILE_P (expr) || noutputs == 0);
6226 gimple_asm_set_input (stmt, ASM_INPUT_P (expr));
6228 gimplify_seq_add_stmt (pre_p, stmt);
6231 return ret;
6234 /* Gimplify a CLEANUP_POINT_EXPR. Currently this works by adding
6235 GIMPLE_WITH_CLEANUP_EXPRs to the prequeue as we encounter cleanups while
6236 gimplifying the body, and converting them to TRY_FINALLY_EXPRs when we
6237 return to this function.
6239 FIXME should we complexify the prequeue handling instead? Or use flags
6240 for all the cleanups and let the optimizer tighten them up? The current
6241 code seems pretty fragile; it will break on a cleanup within any
6242 non-conditional nesting. But any such nesting would be broken, anyway;
6243 we can't write a TRY_FINALLY_EXPR that starts inside a nesting construct
6244 and continues out of it. We can do that at the RTL level, though, so
6245 having an optimizer to tighten up try/finally regions would be a Good
6246 Thing. */
6248 static enum gimplify_status
6249 gimplify_cleanup_point_expr (tree *expr_p, gimple_seq *pre_p)
6251 gimple_stmt_iterator iter;
6252 gimple_seq body_sequence = NULL;
6254 tree temp = voidify_wrapper_expr (*expr_p, NULL);
6256 /* We only care about the number of conditions between the innermost
6257 CLEANUP_POINT_EXPR and the cleanup. So save and reset the count and
6258 any cleanups collected outside the CLEANUP_POINT_EXPR. */
6259 int old_conds = gimplify_ctxp->conditions;
6260 gimple_seq old_cleanups = gimplify_ctxp->conditional_cleanups;
6261 bool old_in_cleanup_point_expr = gimplify_ctxp->in_cleanup_point_expr;
6262 gimplify_ctxp->conditions = 0;
6263 gimplify_ctxp->conditional_cleanups = NULL;
6264 gimplify_ctxp->in_cleanup_point_expr = true;
6266 gimplify_stmt (&TREE_OPERAND (*expr_p, 0), &body_sequence);
6268 gimplify_ctxp->conditions = old_conds;
6269 gimplify_ctxp->conditional_cleanups = old_cleanups;
6270 gimplify_ctxp->in_cleanup_point_expr = old_in_cleanup_point_expr;
6272 for (iter = gsi_start (body_sequence); !gsi_end_p (iter); )
6274 gimple *wce = gsi_stmt (iter);
6276 if (gimple_code (wce) == GIMPLE_WITH_CLEANUP_EXPR)
6278 if (gsi_one_before_end_p (iter))
6280 /* Note that gsi_insert_seq_before and gsi_remove do not
6281 scan operands, unlike some other sequence mutators. */
6282 if (!gimple_wce_cleanup_eh_only (wce))
6283 gsi_insert_seq_before_without_update (&iter,
6284 gimple_wce_cleanup (wce),
6285 GSI_SAME_STMT);
6286 gsi_remove (&iter, true);
6287 break;
6289 else
6291 gtry *gtry;
6292 gimple_seq seq;
6293 enum gimple_try_flags kind;
6295 if (gimple_wce_cleanup_eh_only (wce))
6296 kind = GIMPLE_TRY_CATCH;
6297 else
6298 kind = GIMPLE_TRY_FINALLY;
6299 seq = gsi_split_seq_after (iter);
6301 gtry = gimple_build_try (seq, gimple_wce_cleanup (wce), kind);
6302 /* Do not use gsi_replace here, as it may scan operands.
6303 We want to do a simple structural modification only. */
6304 gsi_set_stmt (&iter, gtry);
6305 iter = gsi_start (gtry->eval);
6308 else
6309 gsi_next (&iter);
6312 gimplify_seq_add_seq (pre_p, body_sequence);
6313 if (temp)
6315 *expr_p = temp;
6316 return GS_OK;
6318 else
6320 *expr_p = NULL;
6321 return GS_ALL_DONE;
6325 /* Insert a cleanup marker for gimplify_cleanup_point_expr. CLEANUP
6326 is the cleanup action required. EH_ONLY is true if the cleanup should
6327 only be executed if an exception is thrown, not on normal exit.
6328 If FORCE_UNCOND is true perform the cleanup unconditionally; this is
6329 only valid for clobbers. */
6331 static void
6332 gimple_push_cleanup (tree var, tree cleanup, bool eh_only, gimple_seq *pre_p,
6333 bool force_uncond = false)
6335 gimple *wce;
6336 gimple_seq cleanup_stmts = NULL;
6338 /* Errors can result in improperly nested cleanups. Which results in
6339 confusion when trying to resolve the GIMPLE_WITH_CLEANUP_EXPR. */
6340 if (seen_error ())
6341 return;
6343 if (gimple_conditional_context ())
6345 /* If we're in a conditional context, this is more complex. We only
6346 want to run the cleanup if we actually ran the initialization that
6347 necessitates it, but we want to run it after the end of the
6348 conditional context. So we wrap the try/finally around the
6349 condition and use a flag to determine whether or not to actually
6350 run the destructor. Thus
6352 test ? f(A()) : 0
6354 becomes (approximately)
6356 flag = 0;
6357 try {
6358 if (test) { A::A(temp); flag = 1; val = f(temp); }
6359 else { val = 0; }
6360 } finally {
6361 if (flag) A::~A(temp);
6365 if (force_uncond)
6367 gimplify_stmt (&cleanup, &cleanup_stmts);
6368 wce = gimple_build_wce (cleanup_stmts);
6369 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
6371 else
6373 tree flag = create_tmp_var (boolean_type_node, "cleanup");
6374 gassign *ffalse = gimple_build_assign (flag, boolean_false_node);
6375 gassign *ftrue = gimple_build_assign (flag, boolean_true_node);
6377 cleanup = build3 (COND_EXPR, void_type_node, flag, cleanup, NULL);
6378 gimplify_stmt (&cleanup, &cleanup_stmts);
6379 wce = gimple_build_wce (cleanup_stmts);
6381 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, ffalse);
6382 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
6383 gimplify_seq_add_stmt (pre_p, ftrue);
6385 /* Because of this manipulation, and the EH edges that jump
6386 threading cannot redirect, the temporary (VAR) will appear
6387 to be used uninitialized. Don't warn. */
6388 TREE_NO_WARNING (var) = 1;
6391 else
6393 gimplify_stmt (&cleanup, &cleanup_stmts);
6394 wce = gimple_build_wce (cleanup_stmts);
6395 gimple_wce_set_cleanup_eh_only (wce, eh_only);
6396 gimplify_seq_add_stmt (pre_p, wce);
6400 /* Gimplify a TARGET_EXPR which doesn't appear on the rhs of an INIT_EXPR. */
6402 static enum gimplify_status
6403 gimplify_target_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6405 tree targ = *expr_p;
6406 tree temp = TARGET_EXPR_SLOT (targ);
6407 tree init = TARGET_EXPR_INITIAL (targ);
6408 enum gimplify_status ret;
6410 bool unpoison_empty_seq = false;
6411 gimple_stmt_iterator unpoison_it;
6413 if (init)
6415 tree cleanup = NULL_TREE;
6417 /* TARGET_EXPR temps aren't part of the enclosing block, so add it
6418 to the temps list. Handle also variable length TARGET_EXPRs. */
6419 if (TREE_CODE (DECL_SIZE (temp)) != INTEGER_CST)
6421 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (temp)))
6422 gimplify_type_sizes (TREE_TYPE (temp), pre_p);
6423 gimplify_vla_decl (temp, pre_p);
6425 else
6427 /* Save location where we need to place unpoisoning. It's possible
6428 that a variable will be converted to needs_to_live_in_memory. */
6429 unpoison_it = gsi_last (*pre_p);
6430 unpoison_empty_seq = gsi_end_p (unpoison_it);
6432 gimple_add_tmp_var (temp);
6435 /* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the
6436 expression is supposed to initialize the slot. */
6437 if (VOID_TYPE_P (TREE_TYPE (init)))
6438 ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
6439 else
6441 tree init_expr = build2 (INIT_EXPR, void_type_node, temp, init);
6442 init = init_expr;
6443 ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
6444 init = NULL;
6445 ggc_free (init_expr);
6447 if (ret == GS_ERROR)
6449 /* PR c++/28266 Make sure this is expanded only once. */
6450 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
6451 return GS_ERROR;
6453 if (init)
6454 gimplify_and_add (init, pre_p);
6456 /* If needed, push the cleanup for the temp. */
6457 if (TARGET_EXPR_CLEANUP (targ))
6459 if (CLEANUP_EH_ONLY (targ))
6460 gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ),
6461 CLEANUP_EH_ONLY (targ), pre_p);
6462 else
6463 cleanup = TARGET_EXPR_CLEANUP (targ);
6466 /* Add a clobber for the temporary going out of scope, like
6467 gimplify_bind_expr. */
6468 if (gimplify_ctxp->in_cleanup_point_expr
6469 && needs_to_live_in_memory (temp))
6471 if (flag_stack_reuse == SR_ALL)
6473 tree clobber = build_constructor (TREE_TYPE (temp),
6474 NULL);
6475 TREE_THIS_VOLATILE (clobber) = true;
6476 clobber = build2 (MODIFY_EXPR, TREE_TYPE (temp), temp, clobber);
6477 gimple_push_cleanup (temp, clobber, false, pre_p, true);
6479 if (asan_poisoned_variables && dbg_cnt (asan_use_after_scope))
6481 tree asan_cleanup = build_asan_poison_call_expr (temp);
6482 if (asan_cleanup)
6484 if (unpoison_empty_seq)
6485 unpoison_it = gsi_start (*pre_p);
6487 asan_poison_variable (temp, false, &unpoison_it,
6488 unpoison_empty_seq);
6489 gimple_push_cleanup (temp, asan_cleanup, false, pre_p);
6493 if (cleanup)
6494 gimple_push_cleanup (temp, cleanup, false, pre_p);
6496 /* Only expand this once. */
6497 TREE_OPERAND (targ, 3) = init;
6498 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
6500 else
6501 /* We should have expanded this before. */
6502 gcc_assert (DECL_SEEN_IN_BIND_EXPR_P (temp));
6504 *expr_p = temp;
6505 return GS_OK;
6508 /* Gimplification of expression trees. */
6510 /* Gimplify an expression which appears at statement context. The
6511 corresponding GIMPLE statements are added to *SEQ_P. If *SEQ_P is
6512 NULL, a new sequence is allocated.
6514 Return true if we actually added a statement to the queue. */
6516 bool
6517 gimplify_stmt (tree *stmt_p, gimple_seq *seq_p)
6519 gimple_seq_node last;
6521 last = gimple_seq_last (*seq_p);
6522 gimplify_expr (stmt_p, seq_p, NULL, is_gimple_stmt, fb_none);
6523 return last != gimple_seq_last (*seq_p);
6526 /* Add FIRSTPRIVATE entries for DECL in the OpenMP the surrounding parallels
6527 to CTX. If entries already exist, force them to be some flavor of private.
6528 If there is no enclosing parallel, do nothing. */
6530 void
6531 omp_firstprivatize_variable (struct gimplify_omp_ctx *ctx, tree decl)
6533 splay_tree_node n;
6535 if (decl == NULL || !DECL_P (decl) || ctx->region_type == ORT_NONE)
6536 return;
6540 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
6541 if (n != NULL)
6543 if (n->value & GOVD_SHARED)
6544 n->value = GOVD_FIRSTPRIVATE | (n->value & GOVD_SEEN);
6545 else if (n->value & GOVD_MAP)
6546 n->value |= GOVD_MAP_TO_ONLY;
6547 else
6548 return;
6550 else if ((ctx->region_type & ORT_TARGET) != 0)
6552 if (ctx->target_map_scalars_firstprivate)
6553 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
6554 else
6555 omp_add_variable (ctx, decl, GOVD_MAP | GOVD_MAP_TO_ONLY);
6557 else if (ctx->region_type != ORT_WORKSHARE
6558 && ctx->region_type != ORT_SIMD
6559 && ctx->region_type != ORT_ACC
6560 && !(ctx->region_type & ORT_TARGET_DATA))
6561 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
6563 ctx = ctx->outer_context;
6565 while (ctx);
6568 /* Similarly for each of the type sizes of TYPE. */
6570 static void
6571 omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type)
6573 if (type == NULL || type == error_mark_node)
6574 return;
6575 type = TYPE_MAIN_VARIANT (type);
6577 if (ctx->privatized_types->add (type))
6578 return;
6580 switch (TREE_CODE (type))
6582 case INTEGER_TYPE:
6583 case ENUMERAL_TYPE:
6584 case BOOLEAN_TYPE:
6585 case REAL_TYPE:
6586 case FIXED_POINT_TYPE:
6587 omp_firstprivatize_variable (ctx, TYPE_MIN_VALUE (type));
6588 omp_firstprivatize_variable (ctx, TYPE_MAX_VALUE (type));
6589 break;
6591 case ARRAY_TYPE:
6592 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
6593 omp_firstprivatize_type_sizes (ctx, TYPE_DOMAIN (type));
6594 break;
6596 case RECORD_TYPE:
6597 case UNION_TYPE:
6598 case QUAL_UNION_TYPE:
6600 tree field;
6601 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
6602 if (TREE_CODE (field) == FIELD_DECL)
6604 omp_firstprivatize_variable (ctx, DECL_FIELD_OFFSET (field));
6605 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (field));
6608 break;
6610 case POINTER_TYPE:
6611 case REFERENCE_TYPE:
6612 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
6613 break;
6615 default:
6616 break;
6619 omp_firstprivatize_variable (ctx, TYPE_SIZE (type));
6620 omp_firstprivatize_variable (ctx, TYPE_SIZE_UNIT (type));
6621 lang_hooks.types.omp_firstprivatize_type_sizes (ctx, type);
6624 /* Add an entry for DECL in the OMP context CTX with FLAGS. */
6626 static void
6627 omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
6629 splay_tree_node n;
6630 unsigned int nflags;
6631 tree t;
6633 if (error_operand_p (decl) || ctx->region_type == ORT_NONE)
6634 return;
6636 /* Never elide decls whose type has TREE_ADDRESSABLE set. This means
6637 there are constructors involved somewhere. */
6638 if (TREE_ADDRESSABLE (TREE_TYPE (decl))
6639 || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
6640 flags |= GOVD_SEEN;
6642 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
6643 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
6645 /* We shouldn't be re-adding the decl with the same data
6646 sharing class. */
6647 gcc_assert ((n->value & GOVD_DATA_SHARE_CLASS & flags) == 0);
6648 nflags = n->value | flags;
6649 /* The only combination of data sharing classes we should see is
6650 FIRSTPRIVATE and LASTPRIVATE. However, OpenACC permits
6651 reduction variables to be used in data sharing clauses. */
6652 gcc_assert ((ctx->region_type & ORT_ACC) != 0
6653 || ((nflags & GOVD_DATA_SHARE_CLASS)
6654 == (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE))
6655 || (flags & GOVD_DATA_SHARE_CLASS) == 0);
6656 n->value = nflags;
6657 return;
6660 /* When adding a variable-sized variable, we have to handle all sorts
6661 of additional bits of data: the pointer replacement variable, and
6662 the parameters of the type. */
6663 if (DECL_SIZE (decl) && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
6665 /* Add the pointer replacement variable as PRIVATE if the variable
6666 replacement is private, else FIRSTPRIVATE since we'll need the
6667 address of the original variable either for SHARED, or for the
6668 copy into or out of the context. */
6669 if (!(flags & GOVD_LOCAL))
6671 if (flags & GOVD_MAP)
6672 nflags = GOVD_MAP | GOVD_MAP_TO_ONLY | GOVD_EXPLICIT;
6673 else if (flags & GOVD_PRIVATE)
6674 nflags = GOVD_PRIVATE;
6675 else if ((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
6676 && (flags & GOVD_FIRSTPRIVATE))
6677 nflags = GOVD_PRIVATE | GOVD_EXPLICIT;
6678 else
6679 nflags = GOVD_FIRSTPRIVATE;
6680 nflags |= flags & GOVD_SEEN;
6681 t = DECL_VALUE_EXPR (decl);
6682 gcc_assert (TREE_CODE (t) == INDIRECT_REF);
6683 t = TREE_OPERAND (t, 0);
6684 gcc_assert (DECL_P (t));
6685 omp_add_variable (ctx, t, nflags);
6688 /* Add all of the variable and type parameters (which should have
6689 been gimplified to a formal temporary) as FIRSTPRIVATE. */
6690 omp_firstprivatize_variable (ctx, DECL_SIZE_UNIT (decl));
6691 omp_firstprivatize_variable (ctx, DECL_SIZE (decl));
6692 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
6694 /* The variable-sized variable itself is never SHARED, only some form
6695 of PRIVATE. The sharing would take place via the pointer variable
6696 which we remapped above. */
6697 if (flags & GOVD_SHARED)
6698 flags = GOVD_SHARED | GOVD_DEBUG_PRIVATE
6699 | (flags & (GOVD_SEEN | GOVD_EXPLICIT));
6701 /* We're going to make use of the TYPE_SIZE_UNIT at least in the
6702 alloca statement we generate for the variable, so make sure it
6703 is available. This isn't automatically needed for the SHARED
6704 case, since we won't be allocating local storage then.
6705 For local variables TYPE_SIZE_UNIT might not be gimplified yet,
6706 in this case omp_notice_variable will be called later
6707 on when it is gimplified. */
6708 else if (! (flags & (GOVD_LOCAL | GOVD_MAP))
6709 && DECL_P (TYPE_SIZE_UNIT (TREE_TYPE (decl))))
6710 omp_notice_variable (ctx, TYPE_SIZE_UNIT (TREE_TYPE (decl)), true);
6712 else if ((flags & (GOVD_MAP | GOVD_LOCAL)) == 0
6713 && lang_hooks.decls.omp_privatize_by_reference (decl))
6715 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
6717 /* Similar to the direct variable sized case above, we'll need the
6718 size of references being privatized. */
6719 if ((flags & GOVD_SHARED) == 0)
6721 t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
6722 if (DECL_P (t))
6723 omp_notice_variable (ctx, t, true);
6727 if (n != NULL)
6728 n->value |= flags;
6729 else
6730 splay_tree_insert (ctx->variables, (splay_tree_key)decl, flags);
6732 /* For reductions clauses in OpenACC loop directives, by default create a
6733 copy clause on the enclosing parallel construct for carrying back the
6734 results. */
6735 if (ctx->region_type == ORT_ACC && (flags & GOVD_REDUCTION))
6737 struct gimplify_omp_ctx *outer_ctx = ctx->outer_context;
6738 while (outer_ctx)
6740 n = splay_tree_lookup (outer_ctx->variables, (splay_tree_key)decl);
6741 if (n != NULL)
6743 /* Ignore local variables and explicitly declared clauses. */
6744 if (n->value & (GOVD_LOCAL | GOVD_EXPLICIT))
6745 break;
6746 else if (outer_ctx->region_type == ORT_ACC_KERNELS)
6748 /* According to the OpenACC spec, such a reduction variable
6749 should already have a copy map on a kernels construct,
6750 verify that here. */
6751 gcc_assert (!(n->value & GOVD_FIRSTPRIVATE)
6752 && (n->value & GOVD_MAP));
6754 else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
6756 /* Remove firstprivate and make it a copy map. */
6757 n->value &= ~GOVD_FIRSTPRIVATE;
6758 n->value |= GOVD_MAP;
6761 else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
6763 splay_tree_insert (outer_ctx->variables, (splay_tree_key)decl,
6764 GOVD_MAP | GOVD_SEEN);
6765 break;
6767 outer_ctx = outer_ctx->outer_context;
6772 /* Notice a threadprivate variable DECL used in OMP context CTX.
6773 This just prints out diagnostics about threadprivate variable uses
6774 in untied tasks. If DECL2 is non-NULL, prevent this warning
6775 on that variable. */
6777 static bool
6778 omp_notice_threadprivate_variable (struct gimplify_omp_ctx *ctx, tree decl,
6779 tree decl2)
6781 splay_tree_node n;
6782 struct gimplify_omp_ctx *octx;
6784 for (octx = ctx; octx; octx = octx->outer_context)
6785 if ((octx->region_type & ORT_TARGET) != 0)
6787 n = splay_tree_lookup (octx->variables, (splay_tree_key)decl);
6788 if (n == NULL)
6790 error ("threadprivate variable %qE used in target region",
6791 DECL_NAME (decl));
6792 error_at (octx->location, "enclosing target region");
6793 splay_tree_insert (octx->variables, (splay_tree_key)decl, 0);
6795 if (decl2)
6796 splay_tree_insert (octx->variables, (splay_tree_key)decl2, 0);
6799 if (ctx->region_type != ORT_UNTIED_TASK)
6800 return false;
6801 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
6802 if (n == NULL)
6804 error ("threadprivate variable %qE used in untied task",
6805 DECL_NAME (decl));
6806 error_at (ctx->location, "enclosing task");
6807 splay_tree_insert (ctx->variables, (splay_tree_key)decl, 0);
6809 if (decl2)
6810 splay_tree_insert (ctx->variables, (splay_tree_key)decl2, 0);
6811 return false;
6814 /* Return true if global var DECL is device resident. */
6816 static bool
6817 device_resident_p (tree decl)
6819 tree attr = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (decl));
6821 if (!attr)
6822 return false;
6824 for (tree t = TREE_VALUE (attr); t; t = TREE_PURPOSE (t))
6826 tree c = TREE_VALUE (t);
6827 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DEVICE_RESIDENT)
6828 return true;
6831 return false;
6834 /* Return true if DECL has an ACC DECLARE attribute. */
6836 static bool
6837 is_oacc_declared (tree decl)
6839 tree t = TREE_CODE (decl) == MEM_REF ? TREE_OPERAND (decl, 0) : decl;
6840 tree declared = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (t));
6841 return declared != NULL_TREE;
6844 /* Determine outer default flags for DECL mentioned in an OMP region
6845 but not declared in an enclosing clause.
6847 ??? Some compiler-generated variables (like SAVE_EXPRs) could be
6848 remapped firstprivate instead of shared. To some extent this is
6849 addressed in omp_firstprivatize_type_sizes, but not
6850 effectively. */
6852 static unsigned
6853 omp_default_clause (struct gimplify_omp_ctx *ctx, tree decl,
6854 bool in_code, unsigned flags)
6856 enum omp_clause_default_kind default_kind = ctx->default_kind;
6857 enum omp_clause_default_kind kind;
6859 kind = lang_hooks.decls.omp_predetermined_sharing (decl);
6860 if (kind != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
6861 default_kind = kind;
6863 switch (default_kind)
6865 case OMP_CLAUSE_DEFAULT_NONE:
6867 const char *rtype;
6869 if (ctx->region_type & ORT_PARALLEL)
6870 rtype = "parallel";
6871 else if (ctx->region_type & ORT_TASK)
6872 rtype = "task";
6873 else if (ctx->region_type & ORT_TEAMS)
6874 rtype = "teams";
6875 else
6876 gcc_unreachable ();
6878 error ("%qE not specified in enclosing %qs",
6879 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rtype);
6880 error_at (ctx->location, "enclosing %qs", rtype);
6882 /* FALLTHRU */
6883 case OMP_CLAUSE_DEFAULT_SHARED:
6884 flags |= GOVD_SHARED;
6885 break;
6886 case OMP_CLAUSE_DEFAULT_PRIVATE:
6887 flags |= GOVD_PRIVATE;
6888 break;
6889 case OMP_CLAUSE_DEFAULT_FIRSTPRIVATE:
6890 flags |= GOVD_FIRSTPRIVATE;
6891 break;
6892 case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
6893 /* decl will be either GOVD_FIRSTPRIVATE or GOVD_SHARED. */
6894 gcc_assert ((ctx->region_type & ORT_TASK) != 0);
6895 if (struct gimplify_omp_ctx *octx = ctx->outer_context)
6897 omp_notice_variable (octx, decl, in_code);
6898 for (; octx; octx = octx->outer_context)
6900 splay_tree_node n2;
6902 n2 = splay_tree_lookup (octx->variables, (splay_tree_key) decl);
6903 if ((octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)) != 0
6904 && (n2 == NULL || (n2->value & GOVD_DATA_SHARE_CLASS) == 0))
6905 continue;
6906 if (n2 && (n2->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED)
6908 flags |= GOVD_FIRSTPRIVATE;
6909 goto found_outer;
6911 if ((octx->region_type & (ORT_PARALLEL | ORT_TEAMS)) != 0)
6913 flags |= GOVD_SHARED;
6914 goto found_outer;
6919 if (TREE_CODE (decl) == PARM_DECL
6920 || (!is_global_var (decl)
6921 && DECL_CONTEXT (decl) == current_function_decl))
6922 flags |= GOVD_FIRSTPRIVATE;
6923 else
6924 flags |= GOVD_SHARED;
6925 found_outer:
6926 break;
6928 default:
6929 gcc_unreachable ();
6932 return flags;
6936 /* Determine outer default flags for DECL mentioned in an OACC region
6937 but not declared in an enclosing clause. */
6939 static unsigned
6940 oacc_default_clause (struct gimplify_omp_ctx *ctx, tree decl, unsigned flags)
6942 const char *rkind;
6943 bool on_device = false;
6944 bool declared = is_oacc_declared (decl);
6945 tree type = TREE_TYPE (decl);
6947 if (lang_hooks.decls.omp_privatize_by_reference (decl))
6948 type = TREE_TYPE (type);
6950 if ((ctx->region_type & (ORT_ACC_PARALLEL | ORT_ACC_KERNELS)) != 0
6951 && is_global_var (decl)
6952 && device_resident_p (decl))
6954 on_device = true;
6955 flags |= GOVD_MAP_TO_ONLY;
6958 switch (ctx->region_type)
6960 case ORT_ACC_KERNELS:
6961 rkind = "kernels";
6963 if (AGGREGATE_TYPE_P (type))
6965 /* Aggregates default to 'present_or_copy', or 'present'. */
6966 if (ctx->default_kind != OMP_CLAUSE_DEFAULT_PRESENT)
6967 flags |= GOVD_MAP;
6968 else
6969 flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
6971 else
6972 /* Scalars default to 'copy'. */
6973 flags |= GOVD_MAP | GOVD_MAP_FORCE;
6975 break;
6977 case ORT_ACC_PARALLEL:
6978 rkind = "parallel";
6980 if (on_device || declared)
6981 flags |= GOVD_MAP;
6982 else if (AGGREGATE_TYPE_P (type))
6984 /* Aggregates default to 'present_or_copy', or 'present'. */
6985 if (ctx->default_kind != OMP_CLAUSE_DEFAULT_PRESENT)
6986 flags |= GOVD_MAP;
6987 else
6988 flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
6990 else
6991 /* Scalars default to 'firstprivate'. */
6992 flags |= GOVD_FIRSTPRIVATE;
6994 break;
6996 default:
6997 gcc_unreachable ();
7000 if (DECL_ARTIFICIAL (decl))
7001 ; /* We can get compiler-generated decls, and should not complain
7002 about them. */
7003 else if (ctx->default_kind == OMP_CLAUSE_DEFAULT_NONE)
7005 error ("%qE not specified in enclosing OpenACC %qs construct",
7006 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rkind);
7007 inform (ctx->location, "enclosing OpenACC %qs construct", rkind);
7009 else if (ctx->default_kind == OMP_CLAUSE_DEFAULT_PRESENT)
7010 ; /* Handled above. */
7011 else
7012 gcc_checking_assert (ctx->default_kind == OMP_CLAUSE_DEFAULT_SHARED);
7014 return flags;
7017 /* Record the fact that DECL was used within the OMP context CTX.
7018 IN_CODE is true when real code uses DECL, and false when we should
7019 merely emit default(none) errors. Return true if DECL is going to
7020 be remapped and thus DECL shouldn't be gimplified into its
7021 DECL_VALUE_EXPR (if any). */
7023 static bool
7024 omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
7026 splay_tree_node n;
7027 unsigned flags = in_code ? GOVD_SEEN : 0;
7028 bool ret = false, shared;
7030 if (error_operand_p (decl))
7031 return false;
7033 if (ctx->region_type == ORT_NONE)
7034 return lang_hooks.decls.omp_disregard_value_expr (decl, false);
7036 if (is_global_var (decl))
7038 /* Threadprivate variables are predetermined. */
7039 if (DECL_THREAD_LOCAL_P (decl))
7040 return omp_notice_threadprivate_variable (ctx, decl, NULL_TREE);
7042 if (DECL_HAS_VALUE_EXPR_P (decl))
7044 tree value = get_base_address (DECL_VALUE_EXPR (decl));
7046 if (value && DECL_P (value) && DECL_THREAD_LOCAL_P (value))
7047 return omp_notice_threadprivate_variable (ctx, decl, value);
7050 if (gimplify_omp_ctxp->outer_context == NULL
7051 && VAR_P (decl)
7052 && oacc_get_fn_attrib (current_function_decl))
7054 location_t loc = DECL_SOURCE_LOCATION (decl);
7056 if (lookup_attribute ("omp declare target link",
7057 DECL_ATTRIBUTES (decl)))
7059 error_at (loc,
7060 "%qE with %<link%> clause used in %<routine%> function",
7061 DECL_NAME (decl));
7062 return false;
7064 else if (!lookup_attribute ("omp declare target",
7065 DECL_ATTRIBUTES (decl)))
7067 error_at (loc,
7068 "%qE requires a %<declare%> directive for use "
7069 "in a %<routine%> function", DECL_NAME (decl));
7070 return false;
7075 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7076 if ((ctx->region_type & ORT_TARGET) != 0)
7078 ret = lang_hooks.decls.omp_disregard_value_expr (decl, true);
7079 if (n == NULL)
7081 unsigned nflags = flags;
7082 if (ctx->target_map_pointers_as_0len_arrays
7083 || ctx->target_map_scalars_firstprivate)
7085 bool is_declare_target = false;
7086 bool is_scalar = false;
7087 if (is_global_var (decl)
7088 && varpool_node::get_create (decl)->offloadable)
7090 struct gimplify_omp_ctx *octx;
7091 for (octx = ctx->outer_context;
7092 octx; octx = octx->outer_context)
7094 n = splay_tree_lookup (octx->variables,
7095 (splay_tree_key)decl);
7096 if (n
7097 && (n->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED
7098 && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
7099 break;
7101 is_declare_target = octx == NULL;
7103 if (!is_declare_target && ctx->target_map_scalars_firstprivate)
7104 is_scalar = lang_hooks.decls.omp_scalar_p (decl);
7105 if (is_declare_target)
7107 else if (ctx->target_map_pointers_as_0len_arrays
7108 && (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
7109 || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
7110 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
7111 == POINTER_TYPE)))
7112 nflags |= GOVD_MAP | GOVD_MAP_0LEN_ARRAY;
7113 else if (is_scalar)
7114 nflags |= GOVD_FIRSTPRIVATE;
7117 struct gimplify_omp_ctx *octx = ctx->outer_context;
7118 if ((ctx->region_type & ORT_ACC) && octx)
7120 /* Look in outer OpenACC contexts, to see if there's a
7121 data attribute for this variable. */
7122 omp_notice_variable (octx, decl, in_code);
7124 for (; octx; octx = octx->outer_context)
7126 if (!(octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)))
7127 break;
7128 splay_tree_node n2
7129 = splay_tree_lookup (octx->variables,
7130 (splay_tree_key) decl);
7131 if (n2)
7133 if (octx->region_type == ORT_ACC_HOST_DATA)
7134 error ("variable %qE declared in enclosing "
7135 "%<host_data%> region", DECL_NAME (decl));
7136 nflags |= GOVD_MAP;
7137 if (octx->region_type == ORT_ACC_DATA
7138 && (n2->value & GOVD_MAP_0LEN_ARRAY))
7139 nflags |= GOVD_MAP_0LEN_ARRAY;
7140 goto found_outer;
7146 tree type = TREE_TYPE (decl);
7148 if (nflags == flags
7149 && gimplify_omp_ctxp->target_firstprivatize_array_bases
7150 && lang_hooks.decls.omp_privatize_by_reference (decl))
7151 type = TREE_TYPE (type);
7152 if (nflags == flags
7153 && !lang_hooks.types.omp_mappable_type (type))
7155 error ("%qD referenced in target region does not have "
7156 "a mappable type", decl);
7157 nflags |= GOVD_MAP | GOVD_EXPLICIT;
7159 else if (nflags == flags)
7161 if ((ctx->region_type & ORT_ACC) != 0)
7162 nflags = oacc_default_clause (ctx, decl, flags);
7163 else
7164 nflags |= GOVD_MAP;
7167 found_outer:
7168 omp_add_variable (ctx, decl, nflags);
7170 else
7172 /* If nothing changed, there's nothing left to do. */
7173 if ((n->value & flags) == flags)
7174 return ret;
7175 flags |= n->value;
7176 n->value = flags;
7178 goto do_outer;
7181 if (n == NULL)
7183 if (ctx->region_type == ORT_WORKSHARE
7184 || ctx->region_type == ORT_SIMD
7185 || ctx->region_type == ORT_ACC
7186 || (ctx->region_type & ORT_TARGET_DATA) != 0)
7187 goto do_outer;
7189 flags = omp_default_clause (ctx, decl, in_code, flags);
7191 if ((flags & GOVD_PRIVATE)
7192 && lang_hooks.decls.omp_private_outer_ref (decl))
7193 flags |= GOVD_PRIVATE_OUTER_REF;
7195 omp_add_variable (ctx, decl, flags);
7197 shared = (flags & GOVD_SHARED) != 0;
7198 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7199 goto do_outer;
7202 if ((n->value & (GOVD_SEEN | GOVD_LOCAL)) == 0
7203 && (flags & (GOVD_SEEN | GOVD_LOCAL)) == GOVD_SEEN
7204 && DECL_SIZE (decl))
7206 if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
7208 splay_tree_node n2;
7209 tree t = DECL_VALUE_EXPR (decl);
7210 gcc_assert (TREE_CODE (t) == INDIRECT_REF);
7211 t = TREE_OPERAND (t, 0);
7212 gcc_assert (DECL_P (t));
7213 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
7214 n2->value |= GOVD_SEEN;
7216 else if (lang_hooks.decls.omp_privatize_by_reference (decl)
7217 && TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)))
7218 && (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))))
7219 != INTEGER_CST))
7221 splay_tree_node n2;
7222 tree t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
7223 gcc_assert (DECL_P (t));
7224 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
7225 if (n2)
7226 omp_notice_variable (ctx, t, true);
7230 shared = ((flags | n->value) & GOVD_SHARED) != 0;
7231 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7233 /* If nothing changed, there's nothing left to do. */
7234 if ((n->value & flags) == flags)
7235 return ret;
7236 flags |= n->value;
7237 n->value = flags;
7239 do_outer:
7240 /* If the variable is private in the current context, then we don't
7241 need to propagate anything to an outer context. */
7242 if ((flags & GOVD_PRIVATE) && !(flags & GOVD_PRIVATE_OUTER_REF))
7243 return ret;
7244 if ((flags & (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7245 == (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7246 return ret;
7247 if ((flags & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
7248 | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7249 == (GOVD_LASTPRIVATE | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7250 return ret;
7251 if (ctx->outer_context
7252 && omp_notice_variable (ctx->outer_context, decl, in_code))
7253 return true;
7254 return ret;
7257 /* Verify that DECL is private within CTX. If there's specific information
7258 to the contrary in the innermost scope, generate an error. */
7260 static bool
7261 omp_is_private (struct gimplify_omp_ctx *ctx, tree decl, int simd)
7263 splay_tree_node n;
7265 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7266 if (n != NULL)
7268 if (n->value & GOVD_SHARED)
7270 if (ctx == gimplify_omp_ctxp)
7272 if (simd)
7273 error ("iteration variable %qE is predetermined linear",
7274 DECL_NAME (decl));
7275 else
7276 error ("iteration variable %qE should be private",
7277 DECL_NAME (decl));
7278 n->value = GOVD_PRIVATE;
7279 return true;
7281 else
7282 return false;
7284 else if ((n->value & GOVD_EXPLICIT) != 0
7285 && (ctx == gimplify_omp_ctxp
7286 || (ctx->region_type == ORT_COMBINED_PARALLEL
7287 && gimplify_omp_ctxp->outer_context == ctx)))
7289 if ((n->value & GOVD_FIRSTPRIVATE) != 0)
7290 error ("iteration variable %qE should not be firstprivate",
7291 DECL_NAME (decl));
7292 else if ((n->value & GOVD_REDUCTION) != 0)
7293 error ("iteration variable %qE should not be reduction",
7294 DECL_NAME (decl));
7295 else if (simd == 0 && (n->value & GOVD_LINEAR) != 0)
7296 error ("iteration variable %qE should not be linear",
7297 DECL_NAME (decl));
7298 else if (simd == 1 && (n->value & GOVD_LASTPRIVATE) != 0)
7299 error ("iteration variable %qE should not be lastprivate",
7300 DECL_NAME (decl));
7301 else if (simd && (n->value & GOVD_PRIVATE) != 0)
7302 error ("iteration variable %qE should not be private",
7303 DECL_NAME (decl));
7304 else if (simd == 2 && (n->value & GOVD_LINEAR) != 0)
7305 error ("iteration variable %qE is predetermined linear",
7306 DECL_NAME (decl));
7308 return (ctx == gimplify_omp_ctxp
7309 || (ctx->region_type == ORT_COMBINED_PARALLEL
7310 && gimplify_omp_ctxp->outer_context == ctx));
7313 if (ctx->region_type != ORT_WORKSHARE
7314 && ctx->region_type != ORT_SIMD
7315 && ctx->region_type != ORT_ACC)
7316 return false;
7317 else if (ctx->outer_context)
7318 return omp_is_private (ctx->outer_context, decl, simd);
7319 return false;
7322 /* Return true if DECL is private within a parallel region
7323 that binds to the current construct's context or in parallel
7324 region's REDUCTION clause. */
7326 static bool
7327 omp_check_private (struct gimplify_omp_ctx *ctx, tree decl, bool copyprivate)
7329 splay_tree_node n;
7333 ctx = ctx->outer_context;
7334 if (ctx == NULL)
7336 if (is_global_var (decl))
7337 return false;
7339 /* References might be private, but might be shared too,
7340 when checking for copyprivate, assume they might be
7341 private, otherwise assume they might be shared. */
7342 if (copyprivate)
7343 return true;
7345 if (lang_hooks.decls.omp_privatize_by_reference (decl))
7346 return false;
7348 /* Treat C++ privatized non-static data members outside
7349 of the privatization the same. */
7350 if (omp_member_access_dummy_var (decl))
7351 return false;
7353 return true;
7356 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
7358 if ((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
7359 && (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0))
7360 continue;
7362 if (n != NULL)
7364 if ((n->value & GOVD_LOCAL) != 0
7365 && omp_member_access_dummy_var (decl))
7366 return false;
7367 return (n->value & GOVD_SHARED) == 0;
7370 while (ctx->region_type == ORT_WORKSHARE
7371 || ctx->region_type == ORT_SIMD
7372 || ctx->region_type == ORT_ACC);
7373 return false;
7376 /* Callback for walk_tree to find a DECL_EXPR for the given DECL. */
7378 static tree
7379 find_decl_expr (tree *tp, int *walk_subtrees, void *data)
7381 tree t = *tp;
7383 /* If this node has been visited, unmark it and keep looking. */
7384 if (TREE_CODE (t) == DECL_EXPR && DECL_EXPR_DECL (t) == (tree) data)
7385 return t;
7387 if (IS_TYPE_OR_DECL_P (t))
7388 *walk_subtrees = 0;
7389 return NULL_TREE;
7392 /* Scan the OMP clauses in *LIST_P, installing mappings into a new
7393 and previous omp contexts. */
7395 static void
7396 gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
7397 enum omp_region_type region_type,
7398 enum tree_code code)
7400 struct gimplify_omp_ctx *ctx, *outer_ctx;
7401 tree c;
7402 hash_map<tree, tree> *struct_map_to_clause = NULL;
7403 tree *prev_list_p = NULL;
7405 ctx = new_omp_context (region_type);
7406 outer_ctx = ctx->outer_context;
7407 if (code == OMP_TARGET)
7409 if (!lang_GNU_Fortran ())
7410 ctx->target_map_pointers_as_0len_arrays = true;
7411 ctx->target_map_scalars_firstprivate = true;
7413 if (!lang_GNU_Fortran ())
7414 switch (code)
7416 case OMP_TARGET:
7417 case OMP_TARGET_DATA:
7418 case OMP_TARGET_ENTER_DATA:
7419 case OMP_TARGET_EXIT_DATA:
7420 case OACC_DECLARE:
7421 case OACC_HOST_DATA:
7422 ctx->target_firstprivatize_array_bases = true;
7423 default:
7424 break;
7427 while ((c = *list_p) != NULL)
7429 bool remove = false;
7430 bool notice_outer = true;
7431 const char *check_non_private = NULL;
7432 unsigned int flags;
7433 tree decl;
7435 switch (OMP_CLAUSE_CODE (c))
7437 case OMP_CLAUSE_PRIVATE:
7438 flags = GOVD_PRIVATE | GOVD_EXPLICIT;
7439 if (lang_hooks.decls.omp_private_outer_ref (OMP_CLAUSE_DECL (c)))
7441 flags |= GOVD_PRIVATE_OUTER_REF;
7442 OMP_CLAUSE_PRIVATE_OUTER_REF (c) = 1;
7444 else
7445 notice_outer = false;
7446 goto do_add;
7447 case OMP_CLAUSE_SHARED:
7448 flags = GOVD_SHARED | GOVD_EXPLICIT;
7449 goto do_add;
7450 case OMP_CLAUSE_FIRSTPRIVATE:
7451 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
7452 check_non_private = "firstprivate";
7453 goto do_add;
7454 case OMP_CLAUSE_LASTPRIVATE:
7455 flags = GOVD_LASTPRIVATE | GOVD_SEEN | GOVD_EXPLICIT;
7456 check_non_private = "lastprivate";
7457 decl = OMP_CLAUSE_DECL (c);
7458 if (error_operand_p (decl))
7459 goto do_add;
7460 else if (outer_ctx
7461 && (outer_ctx->region_type == ORT_COMBINED_PARALLEL
7462 || outer_ctx->region_type == ORT_COMBINED_TEAMS)
7463 && splay_tree_lookup (outer_ctx->variables,
7464 (splay_tree_key) decl) == NULL)
7466 omp_add_variable (outer_ctx, decl, GOVD_SHARED | GOVD_SEEN);
7467 if (outer_ctx->outer_context)
7468 omp_notice_variable (outer_ctx->outer_context, decl, true);
7470 else if (outer_ctx
7471 && (outer_ctx->region_type & ORT_TASK) != 0
7472 && outer_ctx->combined_loop
7473 && splay_tree_lookup (outer_ctx->variables,
7474 (splay_tree_key) decl) == NULL)
7476 omp_add_variable (outer_ctx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
7477 if (outer_ctx->outer_context)
7478 omp_notice_variable (outer_ctx->outer_context, decl, true);
7480 else if (outer_ctx
7481 && (outer_ctx->region_type == ORT_WORKSHARE
7482 || outer_ctx->region_type == ORT_ACC)
7483 && outer_ctx->combined_loop
7484 && splay_tree_lookup (outer_ctx->variables,
7485 (splay_tree_key) decl) == NULL
7486 && !omp_check_private (outer_ctx, decl, false))
7488 omp_add_variable (outer_ctx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
7489 if (outer_ctx->outer_context
7490 && (outer_ctx->outer_context->region_type
7491 == ORT_COMBINED_PARALLEL)
7492 && splay_tree_lookup (outer_ctx->outer_context->variables,
7493 (splay_tree_key) decl) == NULL)
7495 struct gimplify_omp_ctx *octx = outer_ctx->outer_context;
7496 omp_add_variable (octx, decl, GOVD_SHARED | GOVD_SEEN);
7497 if (octx->outer_context)
7499 octx = octx->outer_context;
7500 if (octx->region_type == ORT_WORKSHARE
7501 && octx->combined_loop
7502 && splay_tree_lookup (octx->variables,
7503 (splay_tree_key) decl) == NULL
7504 && !omp_check_private (octx, decl, false))
7506 omp_add_variable (octx, decl,
7507 GOVD_LASTPRIVATE | GOVD_SEEN);
7508 octx = octx->outer_context;
7509 if (octx
7510 && octx->region_type == ORT_COMBINED_TEAMS
7511 && (splay_tree_lookup (octx->variables,
7512 (splay_tree_key) decl)
7513 == NULL))
7515 omp_add_variable (octx, decl,
7516 GOVD_SHARED | GOVD_SEEN);
7517 octx = octx->outer_context;
7520 if (octx)
7521 omp_notice_variable (octx, decl, true);
7524 else if (outer_ctx->outer_context)
7525 omp_notice_variable (outer_ctx->outer_context, decl, true);
7527 goto do_add;
7528 case OMP_CLAUSE_REDUCTION:
7529 flags = GOVD_REDUCTION | GOVD_SEEN | GOVD_EXPLICIT;
7530 /* OpenACC permits reductions on private variables. */
7531 if (!(region_type & ORT_ACC))
7532 check_non_private = "reduction";
7533 decl = OMP_CLAUSE_DECL (c);
7534 if (TREE_CODE (decl) == MEM_REF)
7536 tree type = TREE_TYPE (decl);
7537 if (gimplify_expr (&TYPE_MAX_VALUE (TYPE_DOMAIN (type)), pre_p,
7538 NULL, is_gimple_val, fb_rvalue, false)
7539 == GS_ERROR)
7541 remove = true;
7542 break;
7544 tree v = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
7545 if (DECL_P (v))
7547 omp_firstprivatize_variable (ctx, v);
7548 omp_notice_variable (ctx, v, true);
7550 decl = TREE_OPERAND (decl, 0);
7551 if (TREE_CODE (decl) == POINTER_PLUS_EXPR)
7553 if (gimplify_expr (&TREE_OPERAND (decl, 1), pre_p,
7554 NULL, is_gimple_val, fb_rvalue, false)
7555 == GS_ERROR)
7557 remove = true;
7558 break;
7560 v = TREE_OPERAND (decl, 1);
7561 if (DECL_P (v))
7563 omp_firstprivatize_variable (ctx, v);
7564 omp_notice_variable (ctx, v, true);
7566 decl = TREE_OPERAND (decl, 0);
7568 if (TREE_CODE (decl) == ADDR_EXPR
7569 || TREE_CODE (decl) == INDIRECT_REF)
7570 decl = TREE_OPERAND (decl, 0);
7572 goto do_add_decl;
7573 case OMP_CLAUSE_LINEAR:
7574 if (gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c), pre_p, NULL,
7575 is_gimple_val, fb_rvalue) == GS_ERROR)
7577 remove = true;
7578 break;
7580 else
7582 if (code == OMP_SIMD
7583 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
7585 struct gimplify_omp_ctx *octx = outer_ctx;
7586 if (octx
7587 && octx->region_type == ORT_WORKSHARE
7588 && octx->combined_loop
7589 && !octx->distribute)
7591 if (octx->outer_context
7592 && (octx->outer_context->region_type
7593 == ORT_COMBINED_PARALLEL))
7594 octx = octx->outer_context->outer_context;
7595 else
7596 octx = octx->outer_context;
7598 if (octx
7599 && octx->region_type == ORT_WORKSHARE
7600 && octx->combined_loop
7601 && octx->distribute)
7603 error_at (OMP_CLAUSE_LOCATION (c),
7604 "%<linear%> clause for variable other than "
7605 "loop iterator specified on construct "
7606 "combined with %<distribute%>");
7607 remove = true;
7608 break;
7611 /* For combined #pragma omp parallel for simd, need to put
7612 lastprivate and perhaps firstprivate too on the
7613 parallel. Similarly for #pragma omp for simd. */
7614 struct gimplify_omp_ctx *octx = outer_ctx;
7615 decl = NULL_TREE;
7618 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
7619 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
7620 break;
7621 decl = OMP_CLAUSE_DECL (c);
7622 if (error_operand_p (decl))
7624 decl = NULL_TREE;
7625 break;
7627 flags = GOVD_SEEN;
7628 if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c))
7629 flags |= GOVD_FIRSTPRIVATE;
7630 if (!OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
7631 flags |= GOVD_LASTPRIVATE;
7632 if (octx
7633 && octx->region_type == ORT_WORKSHARE
7634 && octx->combined_loop)
7636 if (octx->outer_context
7637 && (octx->outer_context->region_type
7638 == ORT_COMBINED_PARALLEL))
7639 octx = octx->outer_context;
7640 else if (omp_check_private (octx, decl, false))
7641 break;
7643 else if (octx
7644 && (octx->region_type & ORT_TASK) != 0
7645 && octx->combined_loop)
7647 else if (octx
7648 && octx->region_type == ORT_COMBINED_PARALLEL
7649 && ctx->region_type == ORT_WORKSHARE
7650 && octx == outer_ctx)
7651 flags = GOVD_SEEN | GOVD_SHARED;
7652 else if (octx
7653 && octx->region_type == ORT_COMBINED_TEAMS)
7654 flags = GOVD_SEEN | GOVD_SHARED;
7655 else if (octx
7656 && octx->region_type == ORT_COMBINED_TARGET)
7658 flags &= ~GOVD_LASTPRIVATE;
7659 if (flags == GOVD_SEEN)
7660 break;
7662 else
7663 break;
7664 splay_tree_node on
7665 = splay_tree_lookup (octx->variables,
7666 (splay_tree_key) decl);
7667 if (on && (on->value & GOVD_DATA_SHARE_CLASS) != 0)
7669 octx = NULL;
7670 break;
7672 omp_add_variable (octx, decl, flags);
7673 if (octx->outer_context == NULL)
7674 break;
7675 octx = octx->outer_context;
7677 while (1);
7678 if (octx
7679 && decl
7680 && (!OMP_CLAUSE_LINEAR_NO_COPYIN (c)
7681 || !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
7682 omp_notice_variable (octx, decl, true);
7684 flags = GOVD_LINEAR | GOVD_EXPLICIT;
7685 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
7686 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
7688 notice_outer = false;
7689 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
7691 goto do_add;
7693 case OMP_CLAUSE_MAP:
7694 decl = OMP_CLAUSE_DECL (c);
7695 if (error_operand_p (decl))
7696 remove = true;
7697 switch (code)
7699 case OMP_TARGET:
7700 break;
7701 case OACC_DATA:
7702 if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
7703 break;
7704 /* FALLTHRU */
7705 case OMP_TARGET_DATA:
7706 case OMP_TARGET_ENTER_DATA:
7707 case OMP_TARGET_EXIT_DATA:
7708 case OACC_ENTER_DATA:
7709 case OACC_EXIT_DATA:
7710 case OACC_HOST_DATA:
7711 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
7712 || (OMP_CLAUSE_MAP_KIND (c)
7713 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
7714 /* For target {,enter ,exit }data only the array slice is
7715 mapped, but not the pointer to it. */
7716 remove = true;
7717 break;
7718 default:
7719 break;
7721 if (remove)
7722 break;
7723 if (DECL_P (decl) && outer_ctx && (region_type & ORT_ACC))
7725 struct gimplify_omp_ctx *octx;
7726 for (octx = outer_ctx; octx; octx = octx->outer_context)
7728 if (octx->region_type != ORT_ACC_HOST_DATA)
7729 break;
7730 splay_tree_node n2
7731 = splay_tree_lookup (octx->variables,
7732 (splay_tree_key) decl);
7733 if (n2)
7734 error_at (OMP_CLAUSE_LOCATION (c), "variable %qE "
7735 "declared in enclosing %<host_data%> region",
7736 DECL_NAME (decl));
7739 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
7740 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
7741 : TYPE_SIZE_UNIT (TREE_TYPE (decl));
7742 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
7743 NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
7745 remove = true;
7746 break;
7748 else if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
7749 || (OMP_CLAUSE_MAP_KIND (c)
7750 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
7751 && TREE_CODE (OMP_CLAUSE_SIZE (c)) != INTEGER_CST)
7753 OMP_CLAUSE_SIZE (c)
7754 = get_initialized_tmp_var (OMP_CLAUSE_SIZE (c), pre_p, NULL,
7755 false);
7756 omp_add_variable (ctx, OMP_CLAUSE_SIZE (c),
7757 GOVD_FIRSTPRIVATE | GOVD_SEEN);
7759 if (!DECL_P (decl))
7761 tree d = decl, *pd;
7762 if (TREE_CODE (d) == ARRAY_REF)
7764 while (TREE_CODE (d) == ARRAY_REF)
7765 d = TREE_OPERAND (d, 0);
7766 if (TREE_CODE (d) == COMPONENT_REF
7767 && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE)
7768 decl = d;
7770 pd = &OMP_CLAUSE_DECL (c);
7771 if (d == decl
7772 && TREE_CODE (decl) == INDIRECT_REF
7773 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
7774 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
7775 == REFERENCE_TYPE))
7777 pd = &TREE_OPERAND (decl, 0);
7778 decl = TREE_OPERAND (decl, 0);
7780 if (TREE_CODE (decl) == COMPONENT_REF)
7782 while (TREE_CODE (decl) == COMPONENT_REF)
7783 decl = TREE_OPERAND (decl, 0);
7784 if (TREE_CODE (decl) == INDIRECT_REF
7785 && DECL_P (TREE_OPERAND (decl, 0))
7786 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
7787 == REFERENCE_TYPE))
7788 decl = TREE_OPERAND (decl, 0);
7790 if (gimplify_expr (pd, pre_p, NULL, is_gimple_lvalue, fb_lvalue)
7791 == GS_ERROR)
7793 remove = true;
7794 break;
7796 if (DECL_P (decl))
7798 if (error_operand_p (decl))
7800 remove = true;
7801 break;
7804 tree stype = TREE_TYPE (decl);
7805 if (TREE_CODE (stype) == REFERENCE_TYPE)
7806 stype = TREE_TYPE (stype);
7807 if (TYPE_SIZE_UNIT (stype) == NULL
7808 || TREE_CODE (TYPE_SIZE_UNIT (stype)) != INTEGER_CST)
7810 error_at (OMP_CLAUSE_LOCATION (c),
7811 "mapping field %qE of variable length "
7812 "structure", OMP_CLAUSE_DECL (c));
7813 remove = true;
7814 break;
7817 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER)
7819 /* Error recovery. */
7820 if (prev_list_p == NULL)
7822 remove = true;
7823 break;
7825 if (OMP_CLAUSE_CHAIN (*prev_list_p) != c)
7827 tree ch = OMP_CLAUSE_CHAIN (*prev_list_p);
7828 if (ch == NULL_TREE || OMP_CLAUSE_CHAIN (ch) != c)
7830 remove = true;
7831 break;
7836 tree offset;
7837 HOST_WIDE_INT bitsize, bitpos;
7838 machine_mode mode;
7839 int unsignedp, reversep, volatilep = 0;
7840 tree base = OMP_CLAUSE_DECL (c);
7841 while (TREE_CODE (base) == ARRAY_REF)
7842 base = TREE_OPERAND (base, 0);
7843 if (TREE_CODE (base) == INDIRECT_REF)
7844 base = TREE_OPERAND (base, 0);
7845 base = get_inner_reference (base, &bitsize, &bitpos, &offset,
7846 &mode, &unsignedp, &reversep,
7847 &volatilep);
7848 tree orig_base = base;
7849 if ((TREE_CODE (base) == INDIRECT_REF
7850 || (TREE_CODE (base) == MEM_REF
7851 && integer_zerop (TREE_OPERAND (base, 1))))
7852 && DECL_P (TREE_OPERAND (base, 0))
7853 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0)))
7854 == REFERENCE_TYPE))
7855 base = TREE_OPERAND (base, 0);
7856 gcc_assert (base == decl
7857 && (offset == NULL_TREE
7858 || TREE_CODE (offset) == INTEGER_CST));
7860 splay_tree_node n
7861 = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7862 bool ptr = (OMP_CLAUSE_MAP_KIND (c)
7863 == GOMP_MAP_ALWAYS_POINTER);
7864 if (n == NULL || (n->value & GOVD_MAP) == 0)
7866 tree l = build_omp_clause (OMP_CLAUSE_LOCATION (c),
7867 OMP_CLAUSE_MAP);
7868 OMP_CLAUSE_SET_MAP_KIND (l, GOMP_MAP_STRUCT);
7869 if (orig_base != base)
7870 OMP_CLAUSE_DECL (l) = unshare_expr (orig_base);
7871 else
7872 OMP_CLAUSE_DECL (l) = decl;
7873 OMP_CLAUSE_SIZE (l) = size_int (1);
7874 if (struct_map_to_clause == NULL)
7875 struct_map_to_clause = new hash_map<tree, tree>;
7876 struct_map_to_clause->put (decl, l);
7877 if (ptr)
7879 enum gomp_map_kind mkind
7880 = code == OMP_TARGET_EXIT_DATA
7881 ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
7882 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
7883 OMP_CLAUSE_MAP);
7884 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
7885 OMP_CLAUSE_DECL (c2)
7886 = unshare_expr (OMP_CLAUSE_DECL (c));
7887 OMP_CLAUSE_CHAIN (c2) = *prev_list_p;
7888 OMP_CLAUSE_SIZE (c2)
7889 = TYPE_SIZE_UNIT (ptr_type_node);
7890 OMP_CLAUSE_CHAIN (l) = c2;
7891 if (OMP_CLAUSE_CHAIN (*prev_list_p) != c)
7893 tree c4 = OMP_CLAUSE_CHAIN (*prev_list_p);
7894 tree c3
7895 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
7896 OMP_CLAUSE_MAP);
7897 OMP_CLAUSE_SET_MAP_KIND (c3, mkind);
7898 OMP_CLAUSE_DECL (c3)
7899 = unshare_expr (OMP_CLAUSE_DECL (c4));
7900 OMP_CLAUSE_SIZE (c3)
7901 = TYPE_SIZE_UNIT (ptr_type_node);
7902 OMP_CLAUSE_CHAIN (c3) = *prev_list_p;
7903 OMP_CLAUSE_CHAIN (c2) = c3;
7905 *prev_list_p = l;
7906 prev_list_p = NULL;
7908 else
7910 OMP_CLAUSE_CHAIN (l) = c;
7911 *list_p = l;
7912 list_p = &OMP_CLAUSE_CHAIN (l);
7914 if (orig_base != base && code == OMP_TARGET)
7916 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
7917 OMP_CLAUSE_MAP);
7918 enum gomp_map_kind mkind
7919 = GOMP_MAP_FIRSTPRIVATE_REFERENCE;
7920 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
7921 OMP_CLAUSE_DECL (c2) = decl;
7922 OMP_CLAUSE_SIZE (c2) = size_zero_node;
7923 OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (l);
7924 OMP_CLAUSE_CHAIN (l) = c2;
7926 flags = GOVD_MAP | GOVD_EXPLICIT;
7927 if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) || ptr)
7928 flags |= GOVD_SEEN;
7929 goto do_add_decl;
7931 else
7933 tree *osc = struct_map_to_clause->get (decl);
7934 tree *sc = NULL, *scp = NULL;
7935 if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) || ptr)
7936 n->value |= GOVD_SEEN;
7937 offset_int o1, o2;
7938 if (offset)
7939 o1 = wi::to_offset (offset);
7940 else
7941 o1 = 0;
7942 if (bitpos)
7943 o1 = o1 + bitpos / BITS_PER_UNIT;
7944 sc = &OMP_CLAUSE_CHAIN (*osc);
7945 if (*sc != c
7946 && (OMP_CLAUSE_MAP_KIND (*sc)
7947 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
7948 sc = &OMP_CLAUSE_CHAIN (*sc);
7949 for (; *sc != c; sc = &OMP_CLAUSE_CHAIN (*sc))
7950 if (ptr && sc == prev_list_p)
7951 break;
7952 else if (TREE_CODE (OMP_CLAUSE_DECL (*sc))
7953 != COMPONENT_REF
7954 && (TREE_CODE (OMP_CLAUSE_DECL (*sc))
7955 != INDIRECT_REF)
7956 && (TREE_CODE (OMP_CLAUSE_DECL (*sc))
7957 != ARRAY_REF))
7958 break;
7959 else
7961 tree offset2;
7962 HOST_WIDE_INT bitsize2, bitpos2;
7963 base = OMP_CLAUSE_DECL (*sc);
7964 if (TREE_CODE (base) == ARRAY_REF)
7966 while (TREE_CODE (base) == ARRAY_REF)
7967 base = TREE_OPERAND (base, 0);
7968 if (TREE_CODE (base) != COMPONENT_REF
7969 || (TREE_CODE (TREE_TYPE (base))
7970 != ARRAY_TYPE))
7971 break;
7973 else if (TREE_CODE (base) == INDIRECT_REF
7974 && (TREE_CODE (TREE_OPERAND (base, 0))
7975 == COMPONENT_REF)
7976 && (TREE_CODE (TREE_TYPE
7977 (TREE_OPERAND (base, 0)))
7978 == REFERENCE_TYPE))
7979 base = TREE_OPERAND (base, 0);
7980 base = get_inner_reference (base, &bitsize2,
7981 &bitpos2, &offset2,
7982 &mode, &unsignedp,
7983 &reversep, &volatilep);
7984 if ((TREE_CODE (base) == INDIRECT_REF
7985 || (TREE_CODE (base) == MEM_REF
7986 && integer_zerop (TREE_OPERAND (base,
7987 1))))
7988 && DECL_P (TREE_OPERAND (base, 0))
7989 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (base,
7990 0)))
7991 == REFERENCE_TYPE))
7992 base = TREE_OPERAND (base, 0);
7993 if (base != decl)
7994 break;
7995 if (scp)
7996 continue;
7997 gcc_assert (offset == NULL_TREE
7998 || TREE_CODE (offset) == INTEGER_CST);
7999 tree d1 = OMP_CLAUSE_DECL (*sc);
8000 tree d2 = OMP_CLAUSE_DECL (c);
8001 while (TREE_CODE (d1) == ARRAY_REF)
8002 d1 = TREE_OPERAND (d1, 0);
8003 while (TREE_CODE (d2) == ARRAY_REF)
8004 d2 = TREE_OPERAND (d2, 0);
8005 if (TREE_CODE (d1) == INDIRECT_REF)
8006 d1 = TREE_OPERAND (d1, 0);
8007 if (TREE_CODE (d2) == INDIRECT_REF)
8008 d2 = TREE_OPERAND (d2, 0);
8009 while (TREE_CODE (d1) == COMPONENT_REF)
8010 if (TREE_CODE (d2) == COMPONENT_REF
8011 && TREE_OPERAND (d1, 1)
8012 == TREE_OPERAND (d2, 1))
8014 d1 = TREE_OPERAND (d1, 0);
8015 d2 = TREE_OPERAND (d2, 0);
8017 else
8018 break;
8019 if (d1 == d2)
8021 error_at (OMP_CLAUSE_LOCATION (c),
8022 "%qE appears more than once in map "
8023 "clauses", OMP_CLAUSE_DECL (c));
8024 remove = true;
8025 break;
8027 if (offset2)
8028 o2 = wi::to_offset (offset2);
8029 else
8030 o2 = 0;
8031 if (bitpos2)
8032 o2 = o2 + bitpos2 / BITS_PER_UNIT;
8033 if (wi::ltu_p (o1, o2)
8034 || (wi::eq_p (o1, o2) && bitpos < bitpos2))
8036 if (ptr)
8037 scp = sc;
8038 else
8039 break;
8042 if (remove)
8043 break;
8044 OMP_CLAUSE_SIZE (*osc)
8045 = size_binop (PLUS_EXPR, OMP_CLAUSE_SIZE (*osc),
8046 size_one_node);
8047 if (ptr)
8049 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
8050 OMP_CLAUSE_MAP);
8051 tree cl = NULL_TREE;
8052 enum gomp_map_kind mkind
8053 = code == OMP_TARGET_EXIT_DATA
8054 ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
8055 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
8056 OMP_CLAUSE_DECL (c2)
8057 = unshare_expr (OMP_CLAUSE_DECL (c));
8058 OMP_CLAUSE_CHAIN (c2) = scp ? *scp : *prev_list_p;
8059 OMP_CLAUSE_SIZE (c2)
8060 = TYPE_SIZE_UNIT (ptr_type_node);
8061 cl = scp ? *prev_list_p : c2;
8062 if (OMP_CLAUSE_CHAIN (*prev_list_p) != c)
8064 tree c4 = OMP_CLAUSE_CHAIN (*prev_list_p);
8065 tree c3
8066 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
8067 OMP_CLAUSE_MAP);
8068 OMP_CLAUSE_SET_MAP_KIND (c3, mkind);
8069 OMP_CLAUSE_DECL (c3)
8070 = unshare_expr (OMP_CLAUSE_DECL (c4));
8071 OMP_CLAUSE_SIZE (c3)
8072 = TYPE_SIZE_UNIT (ptr_type_node);
8073 OMP_CLAUSE_CHAIN (c3) = *prev_list_p;
8074 if (!scp)
8075 OMP_CLAUSE_CHAIN (c2) = c3;
8076 else
8077 cl = c3;
8079 if (scp)
8080 *scp = c2;
8081 if (sc == prev_list_p)
8083 *sc = cl;
8084 prev_list_p = NULL;
8086 else
8088 *prev_list_p = OMP_CLAUSE_CHAIN (c);
8089 list_p = prev_list_p;
8090 prev_list_p = NULL;
8091 OMP_CLAUSE_CHAIN (c) = *sc;
8092 *sc = cl;
8093 continue;
8096 else if (*sc != c)
8098 *list_p = OMP_CLAUSE_CHAIN (c);
8099 OMP_CLAUSE_CHAIN (c) = *sc;
8100 *sc = c;
8101 continue;
8105 if (!remove
8106 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_POINTER
8107 && OMP_CLAUSE_CHAIN (c)
8108 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (c)) == OMP_CLAUSE_MAP
8109 && (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
8110 == GOMP_MAP_ALWAYS_POINTER))
8111 prev_list_p = list_p;
8112 break;
8114 flags = GOVD_MAP | GOVD_EXPLICIT;
8115 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TO
8116 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TOFROM)
8117 flags |= GOVD_MAP_ALWAYS_TO;
8118 goto do_add;
8120 case OMP_CLAUSE_DEPEND:
8121 if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
8123 tree deps = OMP_CLAUSE_DECL (c);
8124 while (deps && TREE_CODE (deps) == TREE_LIST)
8126 if (TREE_CODE (TREE_PURPOSE (deps)) == TRUNC_DIV_EXPR
8127 && DECL_P (TREE_OPERAND (TREE_PURPOSE (deps), 1)))
8128 gimplify_expr (&TREE_OPERAND (TREE_PURPOSE (deps), 1),
8129 pre_p, NULL, is_gimple_val, fb_rvalue);
8130 deps = TREE_CHAIN (deps);
8132 break;
8134 else if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
8135 break;
8136 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
8138 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
8139 NULL, is_gimple_val, fb_rvalue);
8140 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
8142 if (error_operand_p (OMP_CLAUSE_DECL (c)))
8144 remove = true;
8145 break;
8147 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
8148 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
8149 is_gimple_val, fb_rvalue) == GS_ERROR)
8151 remove = true;
8152 break;
8154 break;
8156 case OMP_CLAUSE_TO:
8157 case OMP_CLAUSE_FROM:
8158 case OMP_CLAUSE__CACHE_:
8159 decl = OMP_CLAUSE_DECL (c);
8160 if (error_operand_p (decl))
8162 remove = true;
8163 break;
8165 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
8166 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
8167 : TYPE_SIZE_UNIT (TREE_TYPE (decl));
8168 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
8169 NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
8171 remove = true;
8172 break;
8174 if (!DECL_P (decl))
8176 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p,
8177 NULL, is_gimple_lvalue, fb_lvalue)
8178 == GS_ERROR)
8180 remove = true;
8181 break;
8183 break;
8185 goto do_notice;
8187 case OMP_CLAUSE_USE_DEVICE_PTR:
8188 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
8189 goto do_add;
8190 case OMP_CLAUSE_IS_DEVICE_PTR:
8191 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
8192 goto do_add;
8194 do_add:
8195 decl = OMP_CLAUSE_DECL (c);
8196 do_add_decl:
8197 if (error_operand_p (decl))
8199 remove = true;
8200 break;
8202 if (DECL_NAME (decl) == NULL_TREE && (flags & GOVD_SHARED) == 0)
8204 tree t = omp_member_access_dummy_var (decl);
8205 if (t)
8207 tree v = DECL_VALUE_EXPR (decl);
8208 DECL_NAME (decl) = DECL_NAME (TREE_OPERAND (v, 1));
8209 if (outer_ctx)
8210 omp_notice_variable (outer_ctx, t, true);
8213 if (code == OACC_DATA
8214 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
8215 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
8216 flags |= GOVD_MAP_0LEN_ARRAY;
8217 omp_add_variable (ctx, decl, flags);
8218 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
8219 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
8221 omp_add_variable (ctx, OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
8222 GOVD_LOCAL | GOVD_SEEN);
8223 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
8224 && walk_tree (&OMP_CLAUSE_REDUCTION_INIT (c),
8225 find_decl_expr,
8226 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
8227 NULL) == NULL_TREE)
8228 omp_add_variable (ctx,
8229 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
8230 GOVD_LOCAL | GOVD_SEEN);
8231 gimplify_omp_ctxp = ctx;
8232 push_gimplify_context ();
8234 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
8235 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
8237 gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c),
8238 &OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c));
8239 pop_gimplify_context
8240 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c)));
8241 push_gimplify_context ();
8242 gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c),
8243 &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
8244 pop_gimplify_context
8245 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c)));
8246 OMP_CLAUSE_REDUCTION_INIT (c) = NULL_TREE;
8247 OMP_CLAUSE_REDUCTION_MERGE (c) = NULL_TREE;
8249 gimplify_omp_ctxp = outer_ctx;
8251 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
8252 && OMP_CLAUSE_LASTPRIVATE_STMT (c))
8254 gimplify_omp_ctxp = ctx;
8255 push_gimplify_context ();
8256 if (TREE_CODE (OMP_CLAUSE_LASTPRIVATE_STMT (c)) != BIND_EXPR)
8258 tree bind = build3 (BIND_EXPR, void_type_node, NULL,
8259 NULL, NULL);
8260 TREE_SIDE_EFFECTS (bind) = 1;
8261 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LASTPRIVATE_STMT (c);
8262 OMP_CLAUSE_LASTPRIVATE_STMT (c) = bind;
8264 gimplify_and_add (OMP_CLAUSE_LASTPRIVATE_STMT (c),
8265 &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
8266 pop_gimplify_context
8267 (gimple_seq_first_stmt (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c)));
8268 OMP_CLAUSE_LASTPRIVATE_STMT (c) = NULL_TREE;
8270 gimplify_omp_ctxp = outer_ctx;
8272 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
8273 && OMP_CLAUSE_LINEAR_STMT (c))
8275 gimplify_omp_ctxp = ctx;
8276 push_gimplify_context ();
8277 if (TREE_CODE (OMP_CLAUSE_LINEAR_STMT (c)) != BIND_EXPR)
8279 tree bind = build3 (BIND_EXPR, void_type_node, NULL,
8280 NULL, NULL);
8281 TREE_SIDE_EFFECTS (bind) = 1;
8282 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LINEAR_STMT (c);
8283 OMP_CLAUSE_LINEAR_STMT (c) = bind;
8285 gimplify_and_add (OMP_CLAUSE_LINEAR_STMT (c),
8286 &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c));
8287 pop_gimplify_context
8288 (gimple_seq_first_stmt (OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c)));
8289 OMP_CLAUSE_LINEAR_STMT (c) = NULL_TREE;
8291 gimplify_omp_ctxp = outer_ctx;
8293 if (notice_outer)
8294 goto do_notice;
8295 break;
8297 case OMP_CLAUSE_COPYIN:
8298 case OMP_CLAUSE_COPYPRIVATE:
8299 decl = OMP_CLAUSE_DECL (c);
8300 if (error_operand_p (decl))
8302 remove = true;
8303 break;
8305 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_COPYPRIVATE
8306 && !remove
8307 && !omp_check_private (ctx, decl, true))
8309 remove = true;
8310 if (is_global_var (decl))
8312 if (DECL_THREAD_LOCAL_P (decl))
8313 remove = false;
8314 else if (DECL_HAS_VALUE_EXPR_P (decl))
8316 tree value = get_base_address (DECL_VALUE_EXPR (decl));
8318 if (value
8319 && DECL_P (value)
8320 && DECL_THREAD_LOCAL_P (value))
8321 remove = false;
8324 if (remove)
8325 error_at (OMP_CLAUSE_LOCATION (c),
8326 "copyprivate variable %qE is not threadprivate"
8327 " or private in outer context", DECL_NAME (decl));
8329 do_notice:
8330 if (outer_ctx)
8331 omp_notice_variable (outer_ctx, decl, true);
8332 if (check_non_private
8333 && region_type == ORT_WORKSHARE
8334 && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
8335 || decl == OMP_CLAUSE_DECL (c)
8336 || (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
8337 && (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
8338 == ADDR_EXPR
8339 || (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
8340 == POINTER_PLUS_EXPR
8341 && (TREE_CODE (TREE_OPERAND (TREE_OPERAND
8342 (OMP_CLAUSE_DECL (c), 0), 0))
8343 == ADDR_EXPR)))))
8344 && omp_check_private (ctx, decl, false))
8346 error ("%s variable %qE is private in outer context",
8347 check_non_private, DECL_NAME (decl));
8348 remove = true;
8350 break;
8352 case OMP_CLAUSE_IF:
8353 if (OMP_CLAUSE_IF_MODIFIER (c) != ERROR_MARK
8354 && OMP_CLAUSE_IF_MODIFIER (c) != code)
8356 const char *p[2];
8357 for (int i = 0; i < 2; i++)
8358 switch (i ? OMP_CLAUSE_IF_MODIFIER (c) : code)
8360 case OMP_PARALLEL: p[i] = "parallel"; break;
8361 case OMP_TASK: p[i] = "task"; break;
8362 case OMP_TASKLOOP: p[i] = "taskloop"; break;
8363 case OMP_TARGET_DATA: p[i] = "target data"; break;
8364 case OMP_TARGET: p[i] = "target"; break;
8365 case OMP_TARGET_UPDATE: p[i] = "target update"; break;
8366 case OMP_TARGET_ENTER_DATA:
8367 p[i] = "target enter data"; break;
8368 case OMP_TARGET_EXIT_DATA: p[i] = "target exit data"; break;
8369 default: gcc_unreachable ();
8371 error_at (OMP_CLAUSE_LOCATION (c),
8372 "expected %qs %<if%> clause modifier rather than %qs",
8373 p[0], p[1]);
8374 remove = true;
8376 /* Fall through. */
8378 case OMP_CLAUSE_FINAL:
8379 OMP_CLAUSE_OPERAND (c, 0)
8380 = gimple_boolify (OMP_CLAUSE_OPERAND (c, 0));
8381 /* Fall through. */
8383 case OMP_CLAUSE_SCHEDULE:
8384 case OMP_CLAUSE_NUM_THREADS:
8385 case OMP_CLAUSE_NUM_TEAMS:
8386 case OMP_CLAUSE_THREAD_LIMIT:
8387 case OMP_CLAUSE_DIST_SCHEDULE:
8388 case OMP_CLAUSE_DEVICE:
8389 case OMP_CLAUSE_PRIORITY:
8390 case OMP_CLAUSE_GRAINSIZE:
8391 case OMP_CLAUSE_NUM_TASKS:
8392 case OMP_CLAUSE_HINT:
8393 case OMP_CLAUSE__CILK_FOR_COUNT_:
8394 case OMP_CLAUSE_ASYNC:
8395 case OMP_CLAUSE_WAIT:
8396 case OMP_CLAUSE_NUM_GANGS:
8397 case OMP_CLAUSE_NUM_WORKERS:
8398 case OMP_CLAUSE_VECTOR_LENGTH:
8399 case OMP_CLAUSE_WORKER:
8400 case OMP_CLAUSE_VECTOR:
8401 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
8402 is_gimple_val, fb_rvalue) == GS_ERROR)
8403 remove = true;
8404 break;
8406 case OMP_CLAUSE_GANG:
8407 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
8408 is_gimple_val, fb_rvalue) == GS_ERROR)
8409 remove = true;
8410 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 1), pre_p, NULL,
8411 is_gimple_val, fb_rvalue) == GS_ERROR)
8412 remove = true;
8413 break;
8415 case OMP_CLAUSE_NOWAIT:
8416 case OMP_CLAUSE_ORDERED:
8417 case OMP_CLAUSE_UNTIED:
8418 case OMP_CLAUSE_COLLAPSE:
8419 case OMP_CLAUSE_TILE:
8420 case OMP_CLAUSE_AUTO:
8421 case OMP_CLAUSE_SEQ:
8422 case OMP_CLAUSE_INDEPENDENT:
8423 case OMP_CLAUSE_MERGEABLE:
8424 case OMP_CLAUSE_PROC_BIND:
8425 case OMP_CLAUSE_SAFELEN:
8426 case OMP_CLAUSE_SIMDLEN:
8427 case OMP_CLAUSE_NOGROUP:
8428 case OMP_CLAUSE_THREADS:
8429 case OMP_CLAUSE_SIMD:
8430 break;
8432 case OMP_CLAUSE_DEFAULTMAP:
8433 ctx->target_map_scalars_firstprivate = false;
8434 break;
8436 case OMP_CLAUSE_ALIGNED:
8437 decl = OMP_CLAUSE_DECL (c);
8438 if (error_operand_p (decl))
8440 remove = true;
8441 break;
8443 if (gimplify_expr (&OMP_CLAUSE_ALIGNED_ALIGNMENT (c), pre_p, NULL,
8444 is_gimple_val, fb_rvalue) == GS_ERROR)
8446 remove = true;
8447 break;
8449 if (!is_global_var (decl)
8450 && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
8451 omp_add_variable (ctx, decl, GOVD_ALIGNED);
8452 break;
8454 case OMP_CLAUSE_DEFAULT:
8455 ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
8456 break;
8458 default:
8459 gcc_unreachable ();
8462 if (code == OACC_DATA
8463 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
8464 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
8465 remove = true;
8466 if (remove)
8467 *list_p = OMP_CLAUSE_CHAIN (c);
8468 else
8469 list_p = &OMP_CLAUSE_CHAIN (c);
8472 gimplify_omp_ctxp = ctx;
8473 if (struct_map_to_clause)
8474 delete struct_map_to_clause;
8477 /* Return true if DECL is a candidate for shared to firstprivate
8478 optimization. We only consider non-addressable scalars, not
8479 too big, and not references. */
8481 static bool
8482 omp_shared_to_firstprivate_optimizable_decl_p (tree decl)
8484 if (TREE_ADDRESSABLE (decl))
8485 return false;
8486 tree type = TREE_TYPE (decl);
8487 if (!is_gimple_reg_type (type)
8488 || TREE_CODE (type) == REFERENCE_TYPE
8489 || TREE_ADDRESSABLE (type))
8490 return false;
8491 /* Don't optimize too large decls, as each thread/task will have
8492 its own. */
8493 HOST_WIDE_INT len = int_size_in_bytes (type);
8494 if (len == -1 || len > 4 * POINTER_SIZE / BITS_PER_UNIT)
8495 return false;
8496 if (lang_hooks.decls.omp_privatize_by_reference (decl))
8497 return false;
8498 return true;
8501 /* Helper function of omp_find_stores_op and gimplify_adjust_omp_clauses*.
8502 For omp_shared_to_firstprivate_optimizable_decl_p decl mark it as
8503 GOVD_WRITTEN in outer contexts. */
8505 static void
8506 omp_mark_stores (struct gimplify_omp_ctx *ctx, tree decl)
8508 for (; ctx; ctx = ctx->outer_context)
8510 splay_tree_node n = splay_tree_lookup (ctx->variables,
8511 (splay_tree_key) decl);
8512 if (n == NULL)
8513 continue;
8514 else if (n->value & GOVD_SHARED)
8516 n->value |= GOVD_WRITTEN;
8517 return;
8519 else if (n->value & GOVD_DATA_SHARE_CLASS)
8520 return;
8524 /* Helper callback for walk_gimple_seq to discover possible stores
8525 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
8526 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
8527 for those. */
8529 static tree
8530 omp_find_stores_op (tree *tp, int *walk_subtrees, void *data)
8532 struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
8534 *walk_subtrees = 0;
8535 if (!wi->is_lhs)
8536 return NULL_TREE;
8538 tree op = *tp;
8541 if (handled_component_p (op))
8542 op = TREE_OPERAND (op, 0);
8543 else if ((TREE_CODE (op) == MEM_REF || TREE_CODE (op) == TARGET_MEM_REF)
8544 && TREE_CODE (TREE_OPERAND (op, 0)) == ADDR_EXPR)
8545 op = TREE_OPERAND (TREE_OPERAND (op, 0), 0);
8546 else
8547 break;
8549 while (1);
8550 if (!DECL_P (op) || !omp_shared_to_firstprivate_optimizable_decl_p (op))
8551 return NULL_TREE;
8553 omp_mark_stores (gimplify_omp_ctxp, op);
8554 return NULL_TREE;
8557 /* Helper callback for walk_gimple_seq to discover possible stores
8558 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
8559 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
8560 for those. */
8562 static tree
8563 omp_find_stores_stmt (gimple_stmt_iterator *gsi_p,
8564 bool *handled_ops_p,
8565 struct walk_stmt_info *wi)
8567 gimple *stmt = gsi_stmt (*gsi_p);
8568 switch (gimple_code (stmt))
8570 /* Don't recurse on OpenMP constructs for which
8571 gimplify_adjust_omp_clauses already handled the bodies,
8572 except handle gimple_omp_for_pre_body. */
8573 case GIMPLE_OMP_FOR:
8574 *handled_ops_p = true;
8575 if (gimple_omp_for_pre_body (stmt))
8576 walk_gimple_seq (gimple_omp_for_pre_body (stmt),
8577 omp_find_stores_stmt, omp_find_stores_op, wi);
8578 break;
8579 case GIMPLE_OMP_PARALLEL:
8580 case GIMPLE_OMP_TASK:
8581 case GIMPLE_OMP_SECTIONS:
8582 case GIMPLE_OMP_SINGLE:
8583 case GIMPLE_OMP_TARGET:
8584 case GIMPLE_OMP_TEAMS:
8585 case GIMPLE_OMP_CRITICAL:
8586 *handled_ops_p = true;
8587 break;
8588 default:
8589 break;
8591 return NULL_TREE;
8594 struct gimplify_adjust_omp_clauses_data
8596 tree *list_p;
8597 gimple_seq *pre_p;
8600 /* For all variables that were not actually used within the context,
8601 remove PRIVATE, SHARED, and FIRSTPRIVATE clauses. */
8603 static int
8604 gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
8606 tree *list_p = ((struct gimplify_adjust_omp_clauses_data *) data)->list_p;
8607 gimple_seq *pre_p
8608 = ((struct gimplify_adjust_omp_clauses_data *) data)->pre_p;
8609 tree decl = (tree) n->key;
8610 unsigned flags = n->value;
8611 enum omp_clause_code code;
8612 tree clause;
8613 bool private_debug;
8615 if (flags & (GOVD_EXPLICIT | GOVD_LOCAL))
8616 return 0;
8617 if ((flags & GOVD_SEEN) == 0)
8618 return 0;
8619 if (flags & GOVD_DEBUG_PRIVATE)
8621 gcc_assert ((flags & GOVD_DATA_SHARE_CLASS) == GOVD_SHARED);
8622 private_debug = true;
8624 else if (flags & GOVD_MAP)
8625 private_debug = false;
8626 else
8627 private_debug
8628 = lang_hooks.decls.omp_private_debug_clause (decl,
8629 !!(flags & GOVD_SHARED));
8630 if (private_debug)
8631 code = OMP_CLAUSE_PRIVATE;
8632 else if (flags & GOVD_MAP)
8634 code = OMP_CLAUSE_MAP;
8635 if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0
8636 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
8638 error ("%<_Atomic%> %qD in implicit %<map%> clause", decl);
8639 return 0;
8642 else if (flags & GOVD_SHARED)
8644 if (is_global_var (decl))
8646 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
8647 while (ctx != NULL)
8649 splay_tree_node on
8650 = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
8651 if (on && (on->value & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
8652 | GOVD_PRIVATE | GOVD_REDUCTION
8653 | GOVD_LINEAR | GOVD_MAP)) != 0)
8654 break;
8655 ctx = ctx->outer_context;
8657 if (ctx == NULL)
8658 return 0;
8660 code = OMP_CLAUSE_SHARED;
8662 else if (flags & GOVD_PRIVATE)
8663 code = OMP_CLAUSE_PRIVATE;
8664 else if (flags & GOVD_FIRSTPRIVATE)
8666 code = OMP_CLAUSE_FIRSTPRIVATE;
8667 if ((gimplify_omp_ctxp->region_type & ORT_TARGET)
8668 && (gimplify_omp_ctxp->region_type & ORT_ACC) == 0
8669 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
8671 error ("%<_Atomic%> %qD in implicit %<firstprivate%> clause on "
8672 "%<target%> construct", decl);
8673 return 0;
8676 else if (flags & GOVD_LASTPRIVATE)
8677 code = OMP_CLAUSE_LASTPRIVATE;
8678 else if (flags & GOVD_ALIGNED)
8679 return 0;
8680 else
8681 gcc_unreachable ();
8683 if (((flags & GOVD_LASTPRIVATE)
8684 || (code == OMP_CLAUSE_SHARED && (flags & GOVD_WRITTEN)))
8685 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
8686 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
8688 tree chain = *list_p;
8689 clause = build_omp_clause (input_location, code);
8690 OMP_CLAUSE_DECL (clause) = decl;
8691 OMP_CLAUSE_CHAIN (clause) = chain;
8692 if (private_debug)
8693 OMP_CLAUSE_PRIVATE_DEBUG (clause) = 1;
8694 else if (code == OMP_CLAUSE_PRIVATE && (flags & GOVD_PRIVATE_OUTER_REF))
8695 OMP_CLAUSE_PRIVATE_OUTER_REF (clause) = 1;
8696 else if (code == OMP_CLAUSE_SHARED
8697 && (flags & GOVD_WRITTEN) == 0
8698 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
8699 OMP_CLAUSE_SHARED_READONLY (clause) = 1;
8700 else if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_EXPLICIT) == 0)
8701 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (clause) = 1;
8702 else if (code == OMP_CLAUSE_MAP && (flags & GOVD_MAP_0LEN_ARRAY) != 0)
8704 tree nc = build_omp_clause (input_location, OMP_CLAUSE_MAP);
8705 OMP_CLAUSE_DECL (nc) = decl;
8706 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
8707 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == POINTER_TYPE)
8708 OMP_CLAUSE_DECL (clause)
8709 = build_simple_mem_ref_loc (input_location, decl);
8710 OMP_CLAUSE_DECL (clause)
8711 = build2 (MEM_REF, char_type_node, OMP_CLAUSE_DECL (clause),
8712 build_int_cst (build_pointer_type (char_type_node), 0));
8713 OMP_CLAUSE_SIZE (clause) = size_zero_node;
8714 OMP_CLAUSE_SIZE (nc) = size_zero_node;
8715 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_ALLOC);
8716 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (clause) = 1;
8717 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
8718 OMP_CLAUSE_CHAIN (nc) = chain;
8719 OMP_CLAUSE_CHAIN (clause) = nc;
8720 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
8721 gimplify_omp_ctxp = ctx->outer_context;
8722 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (clause), 0),
8723 pre_p, NULL, is_gimple_val, fb_rvalue);
8724 gimplify_omp_ctxp = ctx;
8726 else if (code == OMP_CLAUSE_MAP)
8728 int kind;
8729 /* Not all combinations of these GOVD_MAP flags are actually valid. */
8730 switch (flags & (GOVD_MAP_TO_ONLY
8731 | GOVD_MAP_FORCE
8732 | GOVD_MAP_FORCE_PRESENT))
8734 case 0:
8735 kind = GOMP_MAP_TOFROM;
8736 break;
8737 case GOVD_MAP_FORCE:
8738 kind = GOMP_MAP_TOFROM | GOMP_MAP_FLAG_FORCE;
8739 break;
8740 case GOVD_MAP_TO_ONLY:
8741 kind = GOMP_MAP_TO;
8742 break;
8743 case GOVD_MAP_TO_ONLY | GOVD_MAP_FORCE:
8744 kind = GOMP_MAP_TO | GOMP_MAP_FLAG_FORCE;
8745 break;
8746 case GOVD_MAP_FORCE_PRESENT:
8747 kind = GOMP_MAP_FORCE_PRESENT;
8748 break;
8749 default:
8750 gcc_unreachable ();
8752 OMP_CLAUSE_SET_MAP_KIND (clause, kind);
8753 if (DECL_SIZE (decl)
8754 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
8756 tree decl2 = DECL_VALUE_EXPR (decl);
8757 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
8758 decl2 = TREE_OPERAND (decl2, 0);
8759 gcc_assert (DECL_P (decl2));
8760 tree mem = build_simple_mem_ref (decl2);
8761 OMP_CLAUSE_DECL (clause) = mem;
8762 OMP_CLAUSE_SIZE (clause) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
8763 if (gimplify_omp_ctxp->outer_context)
8765 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
8766 omp_notice_variable (ctx, decl2, true);
8767 omp_notice_variable (ctx, OMP_CLAUSE_SIZE (clause), true);
8769 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
8770 OMP_CLAUSE_MAP);
8771 OMP_CLAUSE_DECL (nc) = decl;
8772 OMP_CLAUSE_SIZE (nc) = size_zero_node;
8773 if (gimplify_omp_ctxp->target_firstprivatize_array_bases)
8774 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
8775 else
8776 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
8777 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
8778 OMP_CLAUSE_CHAIN (clause) = nc;
8780 else if (gimplify_omp_ctxp->target_firstprivatize_array_bases
8781 && lang_hooks.decls.omp_privatize_by_reference (decl))
8783 OMP_CLAUSE_DECL (clause) = build_simple_mem_ref (decl);
8784 OMP_CLAUSE_SIZE (clause)
8785 = unshare_expr (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))));
8786 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
8787 gimplify_omp_ctxp = ctx->outer_context;
8788 gimplify_expr (&OMP_CLAUSE_SIZE (clause),
8789 pre_p, NULL, is_gimple_val, fb_rvalue);
8790 gimplify_omp_ctxp = ctx;
8791 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
8792 OMP_CLAUSE_MAP);
8793 OMP_CLAUSE_DECL (nc) = decl;
8794 OMP_CLAUSE_SIZE (nc) = size_zero_node;
8795 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_REFERENCE);
8796 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
8797 OMP_CLAUSE_CHAIN (clause) = nc;
8799 else
8800 OMP_CLAUSE_SIZE (clause) = DECL_SIZE_UNIT (decl);
8802 if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_LASTPRIVATE) != 0)
8804 tree nc = build_omp_clause (input_location, OMP_CLAUSE_LASTPRIVATE);
8805 OMP_CLAUSE_DECL (nc) = decl;
8806 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (nc) = 1;
8807 OMP_CLAUSE_CHAIN (nc) = chain;
8808 OMP_CLAUSE_CHAIN (clause) = nc;
8809 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
8810 gimplify_omp_ctxp = ctx->outer_context;
8811 lang_hooks.decls.omp_finish_clause (nc, pre_p);
8812 gimplify_omp_ctxp = ctx;
8814 *list_p = clause;
8815 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
8816 gimplify_omp_ctxp = ctx->outer_context;
8817 lang_hooks.decls.omp_finish_clause (clause, pre_p);
8818 if (gimplify_omp_ctxp)
8819 for (; clause != chain; clause = OMP_CLAUSE_CHAIN (clause))
8820 if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_MAP
8821 && DECL_P (OMP_CLAUSE_SIZE (clause)))
8822 omp_notice_variable (gimplify_omp_ctxp, OMP_CLAUSE_SIZE (clause),
8823 true);
8824 gimplify_omp_ctxp = ctx;
8825 return 0;
8828 static void
8829 gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
8830 enum tree_code code)
8832 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
8833 tree c, decl;
8835 if (body)
8837 struct gimplify_omp_ctx *octx;
8838 for (octx = ctx; octx; octx = octx->outer_context)
8839 if ((octx->region_type & (ORT_PARALLEL | ORT_TASK | ORT_TEAMS)) != 0)
8840 break;
8841 if (octx)
8843 struct walk_stmt_info wi;
8844 memset (&wi, 0, sizeof (wi));
8845 walk_gimple_seq (body, omp_find_stores_stmt,
8846 omp_find_stores_op, &wi);
8849 while ((c = *list_p) != NULL)
8851 splay_tree_node n;
8852 bool remove = false;
8854 switch (OMP_CLAUSE_CODE (c))
8856 case OMP_CLAUSE_FIRSTPRIVATE:
8857 if ((ctx->region_type & ORT_TARGET)
8858 && (ctx->region_type & ORT_ACC) == 0
8859 && TYPE_ATOMIC (strip_array_types
8860 (TREE_TYPE (OMP_CLAUSE_DECL (c)))))
8862 error_at (OMP_CLAUSE_LOCATION (c),
8863 "%<_Atomic%> %qD in %<firstprivate%> clause on "
8864 "%<target%> construct", OMP_CLAUSE_DECL (c));
8865 remove = true;
8866 break;
8868 /* FALLTHRU */
8869 case OMP_CLAUSE_PRIVATE:
8870 case OMP_CLAUSE_SHARED:
8871 case OMP_CLAUSE_LINEAR:
8872 decl = OMP_CLAUSE_DECL (c);
8873 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
8874 remove = !(n->value & GOVD_SEEN);
8875 if (! remove)
8877 bool shared = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED;
8878 if ((n->value & GOVD_DEBUG_PRIVATE)
8879 || lang_hooks.decls.omp_private_debug_clause (decl, shared))
8881 gcc_assert ((n->value & GOVD_DEBUG_PRIVATE) == 0
8882 || ((n->value & GOVD_DATA_SHARE_CLASS)
8883 == GOVD_SHARED));
8884 OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_PRIVATE);
8885 OMP_CLAUSE_PRIVATE_DEBUG (c) = 1;
8887 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
8888 && (n->value & GOVD_WRITTEN) == 0
8889 && DECL_P (decl)
8890 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
8891 OMP_CLAUSE_SHARED_READONLY (c) = 1;
8892 else if (DECL_P (decl)
8893 && ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
8894 && (n->value & GOVD_WRITTEN) != 1)
8895 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
8896 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
8897 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
8898 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
8900 break;
8902 case OMP_CLAUSE_LASTPRIVATE:
8903 /* Make sure OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE is set to
8904 accurately reflect the presence of a FIRSTPRIVATE clause. */
8905 decl = OMP_CLAUSE_DECL (c);
8906 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
8907 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c)
8908 = (n->value & GOVD_FIRSTPRIVATE) != 0;
8909 if (code == OMP_DISTRIBUTE
8910 && OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
8912 remove = true;
8913 error_at (OMP_CLAUSE_LOCATION (c),
8914 "same variable used in %<firstprivate%> and "
8915 "%<lastprivate%> clauses on %<distribute%> "
8916 "construct");
8918 if (!remove
8919 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
8920 && DECL_P (decl)
8921 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
8922 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
8923 break;
8925 case OMP_CLAUSE_ALIGNED:
8926 decl = OMP_CLAUSE_DECL (c);
8927 if (!is_global_var (decl))
8929 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
8930 remove = n == NULL || !(n->value & GOVD_SEEN);
8931 if (!remove && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
8933 struct gimplify_omp_ctx *octx;
8934 if (n != NULL
8935 && (n->value & (GOVD_DATA_SHARE_CLASS
8936 & ~GOVD_FIRSTPRIVATE)))
8937 remove = true;
8938 else
8939 for (octx = ctx->outer_context; octx;
8940 octx = octx->outer_context)
8942 n = splay_tree_lookup (octx->variables,
8943 (splay_tree_key) decl);
8944 if (n == NULL)
8945 continue;
8946 if (n->value & GOVD_LOCAL)
8947 break;
8948 /* We have to avoid assigning a shared variable
8949 to itself when trying to add
8950 __builtin_assume_aligned. */
8951 if (n->value & GOVD_SHARED)
8953 remove = true;
8954 break;
8959 else if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
8961 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
8962 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
8963 remove = true;
8965 break;
8967 case OMP_CLAUSE_MAP:
8968 if (code == OMP_TARGET_EXIT_DATA
8969 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER)
8971 remove = true;
8972 break;
8974 decl = OMP_CLAUSE_DECL (c);
8975 /* Data clauses associated with acc parallel reductions must be
8976 compatible with present_or_copy. Warn and adjust the clause
8977 if that is not the case. */
8978 if (ctx->region_type == ORT_ACC_PARALLEL)
8980 tree t = DECL_P (decl) ? decl : TREE_OPERAND (decl, 0);
8981 n = NULL;
8983 if (DECL_P (t))
8984 n = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
8986 if (n && (n->value & GOVD_REDUCTION))
8988 enum gomp_map_kind kind = OMP_CLAUSE_MAP_KIND (c);
8990 OMP_CLAUSE_MAP_IN_REDUCTION (c) = 1;
8991 if ((kind & GOMP_MAP_TOFROM) != GOMP_MAP_TOFROM
8992 && kind != GOMP_MAP_FORCE_PRESENT
8993 && kind != GOMP_MAP_POINTER)
8995 warning_at (OMP_CLAUSE_LOCATION (c), 0,
8996 "incompatible data clause with reduction "
8997 "on %qE; promoting to present_or_copy",
8998 DECL_NAME (t));
8999 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TOFROM);
9003 if (!DECL_P (decl))
9005 if ((ctx->region_type & ORT_TARGET) != 0
9006 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
9008 if (TREE_CODE (decl) == INDIRECT_REF
9009 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
9010 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
9011 == REFERENCE_TYPE))
9012 decl = TREE_OPERAND (decl, 0);
9013 if (TREE_CODE (decl) == COMPONENT_REF)
9015 while (TREE_CODE (decl) == COMPONENT_REF)
9016 decl = TREE_OPERAND (decl, 0);
9017 if (DECL_P (decl))
9019 n = splay_tree_lookup (ctx->variables,
9020 (splay_tree_key) decl);
9021 if (!(n->value & GOVD_SEEN))
9022 remove = true;
9026 break;
9028 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
9029 if ((ctx->region_type & ORT_TARGET) != 0
9030 && !(n->value & GOVD_SEEN)
9031 && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) == 0
9032 && (!is_global_var (decl)
9033 || !lookup_attribute ("omp declare target link",
9034 DECL_ATTRIBUTES (decl))))
9036 remove = true;
9037 /* For struct element mapping, if struct is never referenced
9038 in target block and none of the mapping has always modifier,
9039 remove all the struct element mappings, which immediately
9040 follow the GOMP_MAP_STRUCT map clause. */
9041 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT)
9043 HOST_WIDE_INT cnt = tree_to_shwi (OMP_CLAUSE_SIZE (c));
9044 while (cnt--)
9045 OMP_CLAUSE_CHAIN (c)
9046 = OMP_CLAUSE_CHAIN (OMP_CLAUSE_CHAIN (c));
9049 else if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT
9050 && code == OMP_TARGET_EXIT_DATA)
9051 remove = true;
9052 else if (DECL_SIZE (decl)
9053 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST
9054 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_POINTER
9055 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_POINTER
9056 && (OMP_CLAUSE_MAP_KIND (c)
9057 != GOMP_MAP_FIRSTPRIVATE_REFERENCE))
9059 /* For GOMP_MAP_FORCE_DEVICEPTR, we'll never enter here, because
9060 for these, TREE_CODE (DECL_SIZE (decl)) will always be
9061 INTEGER_CST. */
9062 gcc_assert (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FORCE_DEVICEPTR);
9064 tree decl2 = DECL_VALUE_EXPR (decl);
9065 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
9066 decl2 = TREE_OPERAND (decl2, 0);
9067 gcc_assert (DECL_P (decl2));
9068 tree mem = build_simple_mem_ref (decl2);
9069 OMP_CLAUSE_DECL (c) = mem;
9070 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
9071 if (ctx->outer_context)
9073 omp_notice_variable (ctx->outer_context, decl2, true);
9074 omp_notice_variable (ctx->outer_context,
9075 OMP_CLAUSE_SIZE (c), true);
9077 if (((ctx->region_type & ORT_TARGET) != 0
9078 || !ctx->target_firstprivatize_array_bases)
9079 && ((n->value & GOVD_SEEN) == 0
9080 || (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) == 0))
9082 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9083 OMP_CLAUSE_MAP);
9084 OMP_CLAUSE_DECL (nc) = decl;
9085 OMP_CLAUSE_SIZE (nc) = size_zero_node;
9086 if (ctx->target_firstprivatize_array_bases)
9087 OMP_CLAUSE_SET_MAP_KIND (nc,
9088 GOMP_MAP_FIRSTPRIVATE_POINTER);
9089 else
9090 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
9091 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
9092 OMP_CLAUSE_CHAIN (c) = nc;
9093 c = nc;
9096 else
9098 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
9099 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
9100 gcc_assert ((n->value & GOVD_SEEN) == 0
9101 || ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
9102 == 0));
9104 break;
9106 case OMP_CLAUSE_TO:
9107 case OMP_CLAUSE_FROM:
9108 case OMP_CLAUSE__CACHE_:
9109 decl = OMP_CLAUSE_DECL (c);
9110 if (!DECL_P (decl))
9111 break;
9112 if (DECL_SIZE (decl)
9113 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
9115 tree decl2 = DECL_VALUE_EXPR (decl);
9116 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
9117 decl2 = TREE_OPERAND (decl2, 0);
9118 gcc_assert (DECL_P (decl2));
9119 tree mem = build_simple_mem_ref (decl2);
9120 OMP_CLAUSE_DECL (c) = mem;
9121 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
9122 if (ctx->outer_context)
9124 omp_notice_variable (ctx->outer_context, decl2, true);
9125 omp_notice_variable (ctx->outer_context,
9126 OMP_CLAUSE_SIZE (c), true);
9129 else if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
9130 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
9131 break;
9133 case OMP_CLAUSE_REDUCTION:
9134 decl = OMP_CLAUSE_DECL (c);
9135 /* OpenACC reductions need a present_or_copy data clause.
9136 Add one if necessary. Error is the reduction is private. */
9137 if (ctx->region_type == ORT_ACC_PARALLEL)
9139 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
9140 if (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
9141 error_at (OMP_CLAUSE_LOCATION (c), "invalid private "
9142 "reduction on %qE", DECL_NAME (decl));
9143 else if ((n->value & GOVD_MAP) == 0)
9145 tree next = OMP_CLAUSE_CHAIN (c);
9146 tree nc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_MAP);
9147 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_TOFROM);
9148 OMP_CLAUSE_DECL (nc) = decl;
9149 OMP_CLAUSE_CHAIN (c) = nc;
9150 lang_hooks.decls.omp_finish_clause (nc, pre_p);
9151 while (1)
9153 OMP_CLAUSE_MAP_IN_REDUCTION (nc) = 1;
9154 if (OMP_CLAUSE_CHAIN (nc) == NULL)
9155 break;
9156 nc = OMP_CLAUSE_CHAIN (nc);
9158 OMP_CLAUSE_CHAIN (nc) = next;
9159 n->value |= GOVD_MAP;
9162 if (DECL_P (decl)
9163 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
9164 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
9165 break;
9166 case OMP_CLAUSE_COPYIN:
9167 case OMP_CLAUSE_COPYPRIVATE:
9168 case OMP_CLAUSE_IF:
9169 case OMP_CLAUSE_NUM_THREADS:
9170 case OMP_CLAUSE_NUM_TEAMS:
9171 case OMP_CLAUSE_THREAD_LIMIT:
9172 case OMP_CLAUSE_DIST_SCHEDULE:
9173 case OMP_CLAUSE_DEVICE:
9174 case OMP_CLAUSE_SCHEDULE:
9175 case OMP_CLAUSE_NOWAIT:
9176 case OMP_CLAUSE_ORDERED:
9177 case OMP_CLAUSE_DEFAULT:
9178 case OMP_CLAUSE_UNTIED:
9179 case OMP_CLAUSE_COLLAPSE:
9180 case OMP_CLAUSE_FINAL:
9181 case OMP_CLAUSE_MERGEABLE:
9182 case OMP_CLAUSE_PROC_BIND:
9183 case OMP_CLAUSE_SAFELEN:
9184 case OMP_CLAUSE_SIMDLEN:
9185 case OMP_CLAUSE_DEPEND:
9186 case OMP_CLAUSE_PRIORITY:
9187 case OMP_CLAUSE_GRAINSIZE:
9188 case OMP_CLAUSE_NUM_TASKS:
9189 case OMP_CLAUSE_NOGROUP:
9190 case OMP_CLAUSE_THREADS:
9191 case OMP_CLAUSE_SIMD:
9192 case OMP_CLAUSE_HINT:
9193 case OMP_CLAUSE_DEFAULTMAP:
9194 case OMP_CLAUSE_USE_DEVICE_PTR:
9195 case OMP_CLAUSE_IS_DEVICE_PTR:
9196 case OMP_CLAUSE__CILK_FOR_COUNT_:
9197 case OMP_CLAUSE_ASYNC:
9198 case OMP_CLAUSE_WAIT:
9199 case OMP_CLAUSE_INDEPENDENT:
9200 case OMP_CLAUSE_NUM_GANGS:
9201 case OMP_CLAUSE_NUM_WORKERS:
9202 case OMP_CLAUSE_VECTOR_LENGTH:
9203 case OMP_CLAUSE_GANG:
9204 case OMP_CLAUSE_WORKER:
9205 case OMP_CLAUSE_VECTOR:
9206 case OMP_CLAUSE_AUTO:
9207 case OMP_CLAUSE_SEQ:
9208 case OMP_CLAUSE_TILE:
9209 break;
9211 default:
9212 gcc_unreachable ();
9215 if (remove)
9216 *list_p = OMP_CLAUSE_CHAIN (c);
9217 else
9218 list_p = &OMP_CLAUSE_CHAIN (c);
9221 /* Add in any implicit data sharing. */
9222 struct gimplify_adjust_omp_clauses_data data;
9223 data.list_p = list_p;
9224 data.pre_p = pre_p;
9225 splay_tree_foreach (ctx->variables, gimplify_adjust_omp_clauses_1, &data);
9227 gimplify_omp_ctxp = ctx->outer_context;
9228 delete_omp_context (ctx);
9231 /* Gimplify OACC_CACHE. */
9233 static void
9234 gimplify_oacc_cache (tree *expr_p, gimple_seq *pre_p)
9236 tree expr = *expr_p;
9238 gimplify_scan_omp_clauses (&OACC_CACHE_CLAUSES (expr), pre_p, ORT_ACC,
9239 OACC_CACHE);
9240 gimplify_adjust_omp_clauses (pre_p, NULL, &OACC_CACHE_CLAUSES (expr),
9241 OACC_CACHE);
9243 /* TODO: Do something sensible with this information. */
9245 *expr_p = NULL_TREE;
9248 /* Helper function of gimplify_oacc_declare. The helper's purpose is to,
9249 if required, translate 'kind' in CLAUSE into an 'entry' kind and 'exit'
9250 kind. The entry kind will replace the one in CLAUSE, while the exit
9251 kind will be used in a new omp_clause and returned to the caller. */
9253 static tree
9254 gimplify_oacc_declare_1 (tree clause)
9256 HOST_WIDE_INT kind, new_op;
9257 bool ret = false;
9258 tree c = NULL;
9260 kind = OMP_CLAUSE_MAP_KIND (clause);
9262 switch (kind)
9264 case GOMP_MAP_ALLOC:
9265 case GOMP_MAP_FORCE_ALLOC:
9266 case GOMP_MAP_FORCE_TO:
9267 new_op = GOMP_MAP_DELETE;
9268 ret = true;
9269 break;
9271 case GOMP_MAP_FORCE_FROM:
9272 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_FORCE_ALLOC);
9273 new_op = GOMP_MAP_FORCE_FROM;
9274 ret = true;
9275 break;
9277 case GOMP_MAP_FORCE_TOFROM:
9278 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_FORCE_TO);
9279 new_op = GOMP_MAP_FORCE_FROM;
9280 ret = true;
9281 break;
9283 case GOMP_MAP_FROM:
9284 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_FORCE_ALLOC);
9285 new_op = GOMP_MAP_FROM;
9286 ret = true;
9287 break;
9289 case GOMP_MAP_TOFROM:
9290 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_TO);
9291 new_op = GOMP_MAP_FROM;
9292 ret = true;
9293 break;
9295 case GOMP_MAP_DEVICE_RESIDENT:
9296 case GOMP_MAP_FORCE_DEVICEPTR:
9297 case GOMP_MAP_FORCE_PRESENT:
9298 case GOMP_MAP_LINK:
9299 case GOMP_MAP_POINTER:
9300 case GOMP_MAP_TO:
9301 break;
9303 default:
9304 gcc_unreachable ();
9305 break;
9308 if (ret)
9310 c = build_omp_clause (OMP_CLAUSE_LOCATION (clause), OMP_CLAUSE_MAP);
9311 OMP_CLAUSE_SET_MAP_KIND (c, new_op);
9312 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clause);
9315 return c;
9318 /* Gimplify OACC_DECLARE. */
9320 static void
9321 gimplify_oacc_declare (tree *expr_p, gimple_seq *pre_p)
9323 tree expr = *expr_p;
9324 gomp_target *stmt;
9325 tree clauses, t, decl;
9327 clauses = OACC_DECLARE_CLAUSES (expr);
9329 gimplify_scan_omp_clauses (&clauses, pre_p, ORT_TARGET_DATA, OACC_DECLARE);
9330 gimplify_adjust_omp_clauses (pre_p, NULL, &clauses, OACC_DECLARE);
9332 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
9334 decl = OMP_CLAUSE_DECL (t);
9336 if (TREE_CODE (decl) == MEM_REF)
9337 decl = TREE_OPERAND (decl, 0);
9339 if (VAR_P (decl) && !is_oacc_declared (decl))
9341 tree attr = get_identifier ("oacc declare target");
9342 DECL_ATTRIBUTES (decl) = tree_cons (attr, NULL_TREE,
9343 DECL_ATTRIBUTES (decl));
9346 if (VAR_P (decl)
9347 && !is_global_var (decl)
9348 && DECL_CONTEXT (decl) == current_function_decl)
9350 tree c = gimplify_oacc_declare_1 (t);
9351 if (c)
9353 if (oacc_declare_returns == NULL)
9354 oacc_declare_returns = new hash_map<tree, tree>;
9356 oacc_declare_returns->put (decl, c);
9360 if (gimplify_omp_ctxp)
9361 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_SEEN);
9364 stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
9365 clauses);
9367 gimplify_seq_add_stmt (pre_p, stmt);
9369 *expr_p = NULL_TREE;
9372 /* Gimplify the contents of an OMP_PARALLEL statement. This involves
9373 gimplification of the body, as well as scanning the body for used
9374 variables. We need to do this scan now, because variable-sized
9375 decls will be decomposed during gimplification. */
9377 static void
9378 gimplify_omp_parallel (tree *expr_p, gimple_seq *pre_p)
9380 tree expr = *expr_p;
9381 gimple *g;
9382 gimple_seq body = NULL;
9384 gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr), pre_p,
9385 OMP_PARALLEL_COMBINED (expr)
9386 ? ORT_COMBINED_PARALLEL
9387 : ORT_PARALLEL, OMP_PARALLEL);
9389 push_gimplify_context ();
9391 g = gimplify_and_return_first (OMP_PARALLEL_BODY (expr), &body);
9392 if (gimple_code (g) == GIMPLE_BIND)
9393 pop_gimplify_context (g);
9394 else
9395 pop_gimplify_context (NULL);
9397 gimplify_adjust_omp_clauses (pre_p, body, &OMP_PARALLEL_CLAUSES (expr),
9398 OMP_PARALLEL);
9400 g = gimple_build_omp_parallel (body,
9401 OMP_PARALLEL_CLAUSES (expr),
9402 NULL_TREE, NULL_TREE);
9403 if (OMP_PARALLEL_COMBINED (expr))
9404 gimple_omp_set_subcode (g, GF_OMP_PARALLEL_COMBINED);
9405 gimplify_seq_add_stmt (pre_p, g);
9406 *expr_p = NULL_TREE;
9409 /* Gimplify the contents of an OMP_TASK statement. This involves
9410 gimplification of the body, as well as scanning the body for used
9411 variables. We need to do this scan now, because variable-sized
9412 decls will be decomposed during gimplification. */
9414 static void
9415 gimplify_omp_task (tree *expr_p, gimple_seq *pre_p)
9417 tree expr = *expr_p;
9418 gimple *g;
9419 gimple_seq body = NULL;
9421 gimplify_scan_omp_clauses (&OMP_TASK_CLAUSES (expr), pre_p,
9422 omp_find_clause (OMP_TASK_CLAUSES (expr),
9423 OMP_CLAUSE_UNTIED)
9424 ? ORT_UNTIED_TASK : ORT_TASK, OMP_TASK);
9426 push_gimplify_context ();
9428 g = gimplify_and_return_first (OMP_TASK_BODY (expr), &body);
9429 if (gimple_code (g) == GIMPLE_BIND)
9430 pop_gimplify_context (g);
9431 else
9432 pop_gimplify_context (NULL);
9434 gimplify_adjust_omp_clauses (pre_p, body, &OMP_TASK_CLAUSES (expr),
9435 OMP_TASK);
9437 g = gimple_build_omp_task (body,
9438 OMP_TASK_CLAUSES (expr),
9439 NULL_TREE, NULL_TREE,
9440 NULL_TREE, NULL_TREE, NULL_TREE);
9441 gimplify_seq_add_stmt (pre_p, g);
9442 *expr_p = NULL_TREE;
9445 /* Helper function of gimplify_omp_for, find OMP_FOR resp. OMP_SIMD
9446 with non-NULL OMP_FOR_INIT. */
9448 static tree
9449 find_combined_omp_for (tree *tp, int *walk_subtrees, void *)
9451 *walk_subtrees = 0;
9452 switch (TREE_CODE (*tp))
9454 case OMP_FOR:
9455 *walk_subtrees = 1;
9456 /* FALLTHRU */
9457 case OMP_SIMD:
9458 if (OMP_FOR_INIT (*tp) != NULL_TREE)
9459 return *tp;
9460 break;
9461 case BIND_EXPR:
9462 case STATEMENT_LIST:
9463 case OMP_PARALLEL:
9464 *walk_subtrees = 1;
9465 break;
9466 default:
9467 break;
9469 return NULL_TREE;
9472 /* Gimplify the gross structure of an OMP_FOR statement. */
9474 static enum gimplify_status
9475 gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
9477 tree for_stmt, orig_for_stmt, inner_for_stmt = NULL_TREE, decl, var, t;
9478 enum gimplify_status ret = GS_ALL_DONE;
9479 enum gimplify_status tret;
9480 gomp_for *gfor;
9481 gimple_seq for_body, for_pre_body;
9482 int i;
9483 bitmap has_decl_expr = NULL;
9484 enum omp_region_type ort = ORT_WORKSHARE;
9486 orig_for_stmt = for_stmt = *expr_p;
9488 switch (TREE_CODE (for_stmt))
9490 case OMP_FOR:
9491 case CILK_FOR:
9492 case OMP_DISTRIBUTE:
9493 break;
9494 case OACC_LOOP:
9495 ort = ORT_ACC;
9496 break;
9497 case OMP_TASKLOOP:
9498 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_UNTIED))
9499 ort = ORT_UNTIED_TASK;
9500 else
9501 ort = ORT_TASK;
9502 break;
9503 case OMP_SIMD:
9504 case CILK_SIMD:
9505 ort = ORT_SIMD;
9506 break;
9507 default:
9508 gcc_unreachable ();
9511 /* Set OMP_CLAUSE_LINEAR_NO_COPYIN flag on explicit linear
9512 clause for the IV. */
9513 if (ort == ORT_SIMD && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
9515 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), 0);
9516 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
9517 decl = TREE_OPERAND (t, 0);
9518 for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
9519 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
9520 && OMP_CLAUSE_DECL (c) == decl)
9522 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
9523 break;
9527 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
9529 gcc_assert (TREE_CODE (for_stmt) != OACC_LOOP);
9530 inner_for_stmt = walk_tree (&OMP_FOR_BODY (for_stmt),
9531 find_combined_omp_for, NULL, NULL);
9532 if (inner_for_stmt == NULL_TREE)
9534 gcc_assert (seen_error ());
9535 *expr_p = NULL_TREE;
9536 return GS_ERROR;
9540 if (TREE_CODE (for_stmt) != OMP_TASKLOOP)
9541 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p, ort,
9542 TREE_CODE (for_stmt));
9544 if (TREE_CODE (for_stmt) == OMP_DISTRIBUTE)
9545 gimplify_omp_ctxp->distribute = true;
9547 /* Handle OMP_FOR_INIT. */
9548 for_pre_body = NULL;
9549 if (ort == ORT_SIMD && OMP_FOR_PRE_BODY (for_stmt))
9551 has_decl_expr = BITMAP_ALLOC (NULL);
9552 if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == DECL_EXPR
9553 && TREE_CODE (DECL_EXPR_DECL (OMP_FOR_PRE_BODY (for_stmt)))
9554 == VAR_DECL)
9556 t = OMP_FOR_PRE_BODY (for_stmt);
9557 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
9559 else if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == STATEMENT_LIST)
9561 tree_stmt_iterator si;
9562 for (si = tsi_start (OMP_FOR_PRE_BODY (for_stmt)); !tsi_end_p (si);
9563 tsi_next (&si))
9565 t = tsi_stmt (si);
9566 if (TREE_CODE (t) == DECL_EXPR
9567 && TREE_CODE (DECL_EXPR_DECL (t)) == VAR_DECL)
9568 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
9572 if (OMP_FOR_PRE_BODY (for_stmt))
9574 if (TREE_CODE (for_stmt) != OMP_TASKLOOP || gimplify_omp_ctxp)
9575 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
9576 else
9578 struct gimplify_omp_ctx ctx;
9579 memset (&ctx, 0, sizeof (ctx));
9580 ctx.region_type = ORT_NONE;
9581 gimplify_omp_ctxp = &ctx;
9582 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
9583 gimplify_omp_ctxp = NULL;
9586 OMP_FOR_PRE_BODY (for_stmt) = NULL_TREE;
9588 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
9589 for_stmt = inner_for_stmt;
9591 /* For taskloop, need to gimplify the start, end and step before the
9592 taskloop, outside of the taskloop omp context. */
9593 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
9595 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
9597 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
9598 if (!is_gimple_constant (TREE_OPERAND (t, 1)))
9600 TREE_OPERAND (t, 1)
9601 = get_initialized_tmp_var (TREE_OPERAND (t, 1),
9602 pre_p, NULL, false);
9603 tree c = build_omp_clause (input_location,
9604 OMP_CLAUSE_FIRSTPRIVATE);
9605 OMP_CLAUSE_DECL (c) = TREE_OPERAND (t, 1);
9606 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
9607 OMP_FOR_CLAUSES (orig_for_stmt) = c;
9610 /* Handle OMP_FOR_COND. */
9611 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
9612 if (!is_gimple_constant (TREE_OPERAND (t, 1)))
9614 TREE_OPERAND (t, 1)
9615 = get_initialized_tmp_var (TREE_OPERAND (t, 1),
9616 gimple_seq_empty_p (for_pre_body)
9617 ? pre_p : &for_pre_body, NULL,
9618 false);
9619 tree c = build_omp_clause (input_location,
9620 OMP_CLAUSE_FIRSTPRIVATE);
9621 OMP_CLAUSE_DECL (c) = TREE_OPERAND (t, 1);
9622 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
9623 OMP_FOR_CLAUSES (orig_for_stmt) = c;
9626 /* Handle OMP_FOR_INCR. */
9627 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
9628 if (TREE_CODE (t) == MODIFY_EXPR)
9630 decl = TREE_OPERAND (t, 0);
9631 t = TREE_OPERAND (t, 1);
9632 tree *tp = &TREE_OPERAND (t, 1);
9633 if (TREE_CODE (t) == PLUS_EXPR && *tp == decl)
9634 tp = &TREE_OPERAND (t, 0);
9636 if (!is_gimple_constant (*tp))
9638 gimple_seq *seq = gimple_seq_empty_p (for_pre_body)
9639 ? pre_p : &for_pre_body;
9640 *tp = get_initialized_tmp_var (*tp, seq, NULL, false);
9641 tree c = build_omp_clause (input_location,
9642 OMP_CLAUSE_FIRSTPRIVATE);
9643 OMP_CLAUSE_DECL (c) = *tp;
9644 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
9645 OMP_FOR_CLAUSES (orig_for_stmt) = c;
9650 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (orig_for_stmt), pre_p, ort,
9651 OMP_TASKLOOP);
9654 if (orig_for_stmt != for_stmt)
9655 gimplify_omp_ctxp->combined_loop = true;
9657 for_body = NULL;
9658 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
9659 == TREE_VEC_LENGTH (OMP_FOR_COND (for_stmt)));
9660 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
9661 == TREE_VEC_LENGTH (OMP_FOR_INCR (for_stmt)));
9663 tree c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED);
9664 bool is_doacross = false;
9665 if (c && OMP_CLAUSE_ORDERED_EXPR (c))
9667 is_doacross = true;
9668 gimplify_omp_ctxp->loop_iter_var.create (TREE_VEC_LENGTH
9669 (OMP_FOR_INIT (for_stmt))
9670 * 2);
9672 int collapse = 1, tile = 0;
9673 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_COLLAPSE);
9674 if (c)
9675 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (c));
9676 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_TILE);
9677 if (c)
9678 tile = list_length (OMP_CLAUSE_TILE_LIST (c));
9679 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
9681 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
9682 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
9683 decl = TREE_OPERAND (t, 0);
9684 gcc_assert (DECL_P (decl));
9685 gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl))
9686 || POINTER_TYPE_P (TREE_TYPE (decl)));
9687 if (is_doacross)
9689 if (TREE_CODE (for_stmt) == OMP_FOR && OMP_FOR_ORIG_DECLS (for_stmt))
9690 gimplify_omp_ctxp->loop_iter_var.quick_push
9691 (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i));
9692 else
9693 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
9694 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
9697 /* Make sure the iteration variable is private. */
9698 tree c = NULL_TREE;
9699 tree c2 = NULL_TREE;
9700 if (orig_for_stmt != for_stmt)
9701 /* Do this only on innermost construct for combined ones. */;
9702 else if (ort == ORT_SIMD)
9704 splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
9705 (splay_tree_key) decl);
9706 omp_is_private (gimplify_omp_ctxp, decl,
9707 1 + (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
9708 != 1));
9709 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
9710 omp_notice_variable (gimplify_omp_ctxp, decl, true);
9711 else if (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
9713 c = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
9714 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
9715 unsigned int flags = GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN;
9716 if (has_decl_expr
9717 && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
9719 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
9720 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
9722 struct gimplify_omp_ctx *outer
9723 = gimplify_omp_ctxp->outer_context;
9724 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
9726 if (outer->region_type == ORT_WORKSHARE
9727 && outer->combined_loop)
9729 n = splay_tree_lookup (outer->variables,
9730 (splay_tree_key)decl);
9731 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
9733 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
9734 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
9736 else
9738 struct gimplify_omp_ctx *octx = outer->outer_context;
9739 if (octx
9740 && octx->region_type == ORT_COMBINED_PARALLEL
9741 && octx->outer_context
9742 && (octx->outer_context->region_type
9743 == ORT_WORKSHARE)
9744 && octx->outer_context->combined_loop)
9746 octx = octx->outer_context;
9747 n = splay_tree_lookup (octx->variables,
9748 (splay_tree_key)decl);
9749 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
9751 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
9752 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
9759 OMP_CLAUSE_DECL (c) = decl;
9760 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
9761 OMP_FOR_CLAUSES (for_stmt) = c;
9762 omp_add_variable (gimplify_omp_ctxp, decl, flags);
9763 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
9765 if (outer->region_type == ORT_WORKSHARE
9766 && outer->combined_loop)
9768 if (outer->outer_context
9769 && (outer->outer_context->region_type
9770 == ORT_COMBINED_PARALLEL))
9771 outer = outer->outer_context;
9772 else if (omp_check_private (outer, decl, false))
9773 outer = NULL;
9775 else if (((outer->region_type & ORT_TASK) != 0)
9776 && outer->combined_loop
9777 && !omp_check_private (gimplify_omp_ctxp,
9778 decl, false))
9780 else if (outer->region_type != ORT_COMBINED_PARALLEL)
9782 omp_notice_variable (outer, decl, true);
9783 outer = NULL;
9785 if (outer)
9787 n = splay_tree_lookup (outer->variables,
9788 (splay_tree_key)decl);
9789 if (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
9791 omp_add_variable (outer, decl,
9792 GOVD_LASTPRIVATE | GOVD_SEEN);
9793 if (outer->region_type == ORT_COMBINED_PARALLEL
9794 && outer->outer_context
9795 && (outer->outer_context->region_type
9796 == ORT_WORKSHARE)
9797 && outer->outer_context->combined_loop)
9799 outer = outer->outer_context;
9800 n = splay_tree_lookup (outer->variables,
9801 (splay_tree_key)decl);
9802 if (omp_check_private (outer, decl, false))
9803 outer = NULL;
9804 else if (n == NULL
9805 || ((n->value & GOVD_DATA_SHARE_CLASS)
9806 == 0))
9807 omp_add_variable (outer, decl,
9808 GOVD_LASTPRIVATE
9809 | GOVD_SEEN);
9810 else
9811 outer = NULL;
9813 if (outer && outer->outer_context
9814 && (outer->outer_context->region_type
9815 == ORT_COMBINED_TEAMS))
9817 outer = outer->outer_context;
9818 n = splay_tree_lookup (outer->variables,
9819 (splay_tree_key)decl);
9820 if (n == NULL
9821 || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
9822 omp_add_variable (outer, decl,
9823 GOVD_SHARED | GOVD_SEEN);
9824 else
9825 outer = NULL;
9827 if (outer && outer->outer_context)
9828 omp_notice_variable (outer->outer_context, decl,
9829 true);
9834 else
9836 bool lastprivate
9837 = (!has_decl_expr
9838 || !bitmap_bit_p (has_decl_expr, DECL_UID (decl)));
9839 struct gimplify_omp_ctx *outer
9840 = gimplify_omp_ctxp->outer_context;
9841 if (outer && lastprivate)
9843 if (outer->region_type == ORT_WORKSHARE
9844 && outer->combined_loop)
9846 n = splay_tree_lookup (outer->variables,
9847 (splay_tree_key)decl);
9848 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
9850 lastprivate = false;
9851 outer = NULL;
9853 else if (outer->outer_context
9854 && (outer->outer_context->region_type
9855 == ORT_COMBINED_PARALLEL))
9856 outer = outer->outer_context;
9857 else if (omp_check_private (outer, decl, false))
9858 outer = NULL;
9860 else if (((outer->region_type & ORT_TASK) != 0)
9861 && outer->combined_loop
9862 && !omp_check_private (gimplify_omp_ctxp,
9863 decl, false))
9865 else if (outer->region_type != ORT_COMBINED_PARALLEL)
9867 omp_notice_variable (outer, decl, true);
9868 outer = NULL;
9870 if (outer)
9872 n = splay_tree_lookup (outer->variables,
9873 (splay_tree_key)decl);
9874 if (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
9876 omp_add_variable (outer, decl,
9877 GOVD_LASTPRIVATE | GOVD_SEEN);
9878 if (outer->region_type == ORT_COMBINED_PARALLEL
9879 && outer->outer_context
9880 && (outer->outer_context->region_type
9881 == ORT_WORKSHARE)
9882 && outer->outer_context->combined_loop)
9884 outer = outer->outer_context;
9885 n = splay_tree_lookup (outer->variables,
9886 (splay_tree_key)decl);
9887 if (omp_check_private (outer, decl, false))
9888 outer = NULL;
9889 else if (n == NULL
9890 || ((n->value & GOVD_DATA_SHARE_CLASS)
9891 == 0))
9892 omp_add_variable (outer, decl,
9893 GOVD_LASTPRIVATE
9894 | GOVD_SEEN);
9895 else
9896 outer = NULL;
9898 if (outer && outer->outer_context
9899 && (outer->outer_context->region_type
9900 == ORT_COMBINED_TEAMS))
9902 outer = outer->outer_context;
9903 n = splay_tree_lookup (outer->variables,
9904 (splay_tree_key)decl);
9905 if (n == NULL
9906 || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
9907 omp_add_variable (outer, decl,
9908 GOVD_SHARED | GOVD_SEEN);
9909 else
9910 outer = NULL;
9912 if (outer && outer->outer_context)
9913 omp_notice_variable (outer->outer_context, decl,
9914 true);
9919 c = build_omp_clause (input_location,
9920 lastprivate ? OMP_CLAUSE_LASTPRIVATE
9921 : OMP_CLAUSE_PRIVATE);
9922 OMP_CLAUSE_DECL (c) = decl;
9923 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
9924 OMP_FOR_CLAUSES (for_stmt) = c;
9925 omp_add_variable (gimplify_omp_ctxp, decl,
9926 (lastprivate ? GOVD_LASTPRIVATE : GOVD_PRIVATE)
9927 | GOVD_EXPLICIT | GOVD_SEEN);
9928 c = NULL_TREE;
9931 else if (omp_is_private (gimplify_omp_ctxp, decl, 0))
9932 omp_notice_variable (gimplify_omp_ctxp, decl, true);
9933 else
9934 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN);
9936 /* If DECL is not a gimple register, create a temporary variable to act
9937 as an iteration counter. This is valid, since DECL cannot be
9938 modified in the body of the loop. Similarly for any iteration vars
9939 in simd with collapse > 1 where the iterator vars must be
9940 lastprivate. */
9941 if (orig_for_stmt != for_stmt)
9942 var = decl;
9943 else if (!is_gimple_reg (decl)
9944 || (ort == ORT_SIMD
9945 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) > 1))
9947 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
9948 /* Make sure omp_add_variable is not called on it prematurely.
9949 We call it ourselves a few lines later. */
9950 gimplify_omp_ctxp = NULL;
9951 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
9952 gimplify_omp_ctxp = ctx;
9953 TREE_OPERAND (t, 0) = var;
9955 gimplify_seq_add_stmt (&for_body, gimple_build_assign (decl, var));
9957 if (ort == ORT_SIMD
9958 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
9960 c2 = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
9961 OMP_CLAUSE_LINEAR_NO_COPYIN (c2) = 1;
9962 OMP_CLAUSE_LINEAR_NO_COPYOUT (c2) = 1;
9963 OMP_CLAUSE_DECL (c2) = var;
9964 OMP_CLAUSE_CHAIN (c2) = OMP_FOR_CLAUSES (for_stmt);
9965 OMP_FOR_CLAUSES (for_stmt) = c2;
9966 omp_add_variable (gimplify_omp_ctxp, var,
9967 GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN);
9968 if (c == NULL_TREE)
9970 c = c2;
9971 c2 = NULL_TREE;
9974 else
9975 omp_add_variable (gimplify_omp_ctxp, var,
9976 GOVD_PRIVATE | GOVD_SEEN);
9978 else
9979 var = decl;
9981 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
9982 is_gimple_val, fb_rvalue, false);
9983 ret = MIN (ret, tret);
9984 if (ret == GS_ERROR)
9985 return ret;
9987 /* Handle OMP_FOR_COND. */
9988 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
9989 gcc_assert (COMPARISON_CLASS_P (t));
9990 gcc_assert (TREE_OPERAND (t, 0) == decl);
9992 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
9993 is_gimple_val, fb_rvalue, false);
9994 ret = MIN (ret, tret);
9996 /* Handle OMP_FOR_INCR. */
9997 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
9998 switch (TREE_CODE (t))
10000 case PREINCREMENT_EXPR:
10001 case POSTINCREMENT_EXPR:
10003 tree decl = TREE_OPERAND (t, 0);
10004 /* c_omp_for_incr_canonicalize_ptr() should have been
10005 called to massage things appropriately. */
10006 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
10008 if (orig_for_stmt != for_stmt)
10009 break;
10010 t = build_int_cst (TREE_TYPE (decl), 1);
10011 if (c)
10012 OMP_CLAUSE_LINEAR_STEP (c) = t;
10013 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
10014 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
10015 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
10016 break;
10019 case PREDECREMENT_EXPR:
10020 case POSTDECREMENT_EXPR:
10021 /* c_omp_for_incr_canonicalize_ptr() should have been
10022 called to massage things appropriately. */
10023 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
10024 if (orig_for_stmt != for_stmt)
10025 break;
10026 t = build_int_cst (TREE_TYPE (decl), -1);
10027 if (c)
10028 OMP_CLAUSE_LINEAR_STEP (c) = t;
10029 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
10030 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
10031 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
10032 break;
10034 case MODIFY_EXPR:
10035 gcc_assert (TREE_OPERAND (t, 0) == decl);
10036 TREE_OPERAND (t, 0) = var;
10038 t = TREE_OPERAND (t, 1);
10039 switch (TREE_CODE (t))
10041 case PLUS_EXPR:
10042 if (TREE_OPERAND (t, 1) == decl)
10044 TREE_OPERAND (t, 1) = TREE_OPERAND (t, 0);
10045 TREE_OPERAND (t, 0) = var;
10046 break;
10049 /* Fallthru. */
10050 case MINUS_EXPR:
10051 case POINTER_PLUS_EXPR:
10052 gcc_assert (TREE_OPERAND (t, 0) == decl);
10053 TREE_OPERAND (t, 0) = var;
10054 break;
10055 default:
10056 gcc_unreachable ();
10059 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
10060 is_gimple_val, fb_rvalue, false);
10061 ret = MIN (ret, tret);
10062 if (c)
10064 tree step = TREE_OPERAND (t, 1);
10065 tree stept = TREE_TYPE (decl);
10066 if (POINTER_TYPE_P (stept))
10067 stept = sizetype;
10068 step = fold_convert (stept, step);
10069 if (TREE_CODE (t) == MINUS_EXPR)
10070 step = fold_build1 (NEGATE_EXPR, stept, step);
10071 OMP_CLAUSE_LINEAR_STEP (c) = step;
10072 if (step != TREE_OPERAND (t, 1))
10074 tret = gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c),
10075 &for_pre_body, NULL,
10076 is_gimple_val, fb_rvalue, false);
10077 ret = MIN (ret, tret);
10080 break;
10082 default:
10083 gcc_unreachable ();
10086 if (c2)
10088 gcc_assert (c);
10089 OMP_CLAUSE_LINEAR_STEP (c2) = OMP_CLAUSE_LINEAR_STEP (c);
10092 if ((var != decl || collapse > 1 || tile) && orig_for_stmt == for_stmt)
10094 for (c = OMP_FOR_CLAUSES (for_stmt); c ; c = OMP_CLAUSE_CHAIN (c))
10095 if (((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
10096 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) == NULL)
10097 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
10098 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)
10099 && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c) == NULL))
10100 && OMP_CLAUSE_DECL (c) == decl)
10102 if (is_doacross && (collapse == 1 || i >= collapse))
10103 t = var;
10104 else
10106 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
10107 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
10108 gcc_assert (TREE_OPERAND (t, 0) == var);
10109 t = TREE_OPERAND (t, 1);
10110 gcc_assert (TREE_CODE (t) == PLUS_EXPR
10111 || TREE_CODE (t) == MINUS_EXPR
10112 || TREE_CODE (t) == POINTER_PLUS_EXPR);
10113 gcc_assert (TREE_OPERAND (t, 0) == var);
10114 t = build2 (TREE_CODE (t), TREE_TYPE (decl),
10115 is_doacross ? var : decl,
10116 TREE_OPERAND (t, 1));
10118 gimple_seq *seq;
10119 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
10120 seq = &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c);
10121 else
10122 seq = &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c);
10123 gimplify_assign (decl, t, seq);
10128 BITMAP_FREE (has_decl_expr);
10130 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
10132 push_gimplify_context ();
10133 if (TREE_CODE (OMP_FOR_BODY (orig_for_stmt)) != BIND_EXPR)
10135 OMP_FOR_BODY (orig_for_stmt)
10136 = build3 (BIND_EXPR, void_type_node, NULL,
10137 OMP_FOR_BODY (orig_for_stmt), NULL);
10138 TREE_SIDE_EFFECTS (OMP_FOR_BODY (orig_for_stmt)) = 1;
10142 gimple *g = gimplify_and_return_first (OMP_FOR_BODY (orig_for_stmt),
10143 &for_body);
10145 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
10147 if (gimple_code (g) == GIMPLE_BIND)
10148 pop_gimplify_context (g);
10149 else
10150 pop_gimplify_context (NULL);
10153 if (orig_for_stmt != for_stmt)
10154 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
10156 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
10157 decl = TREE_OPERAND (t, 0);
10158 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
10159 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
10160 gimplify_omp_ctxp = ctx->outer_context;
10161 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
10162 gimplify_omp_ctxp = ctx;
10163 omp_add_variable (gimplify_omp_ctxp, var, GOVD_PRIVATE | GOVD_SEEN);
10164 TREE_OPERAND (t, 0) = var;
10165 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
10166 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
10167 TREE_OPERAND (TREE_OPERAND (t, 1), 0) = var;
10170 gimplify_adjust_omp_clauses (pre_p, for_body,
10171 &OMP_FOR_CLAUSES (orig_for_stmt),
10172 TREE_CODE (orig_for_stmt));
10174 int kind;
10175 switch (TREE_CODE (orig_for_stmt))
10177 case OMP_FOR: kind = GF_OMP_FOR_KIND_FOR; break;
10178 case OMP_SIMD: kind = GF_OMP_FOR_KIND_SIMD; break;
10179 case CILK_SIMD: kind = GF_OMP_FOR_KIND_CILKSIMD; break;
10180 case CILK_FOR: kind = GF_OMP_FOR_KIND_CILKFOR; break;
10181 case OMP_DISTRIBUTE: kind = GF_OMP_FOR_KIND_DISTRIBUTE; break;
10182 case OMP_TASKLOOP: kind = GF_OMP_FOR_KIND_TASKLOOP; break;
10183 case OACC_LOOP: kind = GF_OMP_FOR_KIND_OACC_LOOP; break;
10184 default:
10185 gcc_unreachable ();
10187 gfor = gimple_build_omp_for (for_body, kind, OMP_FOR_CLAUSES (orig_for_stmt),
10188 TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)),
10189 for_pre_body);
10190 if (orig_for_stmt != for_stmt)
10191 gimple_omp_for_set_combined_p (gfor, true);
10192 if (gimplify_omp_ctxp
10193 && (gimplify_omp_ctxp->combined_loop
10194 || (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
10195 && gimplify_omp_ctxp->outer_context
10196 && gimplify_omp_ctxp->outer_context->combined_loop)))
10198 gimple_omp_for_set_combined_into_p (gfor, true);
10199 if (gimplify_omp_ctxp->combined_loop)
10200 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_SIMD);
10201 else
10202 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_FOR);
10205 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
10207 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
10208 gimple_omp_for_set_index (gfor, i, TREE_OPERAND (t, 0));
10209 gimple_omp_for_set_initial (gfor, i, TREE_OPERAND (t, 1));
10210 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
10211 gimple_omp_for_set_cond (gfor, i, TREE_CODE (t));
10212 gimple_omp_for_set_final (gfor, i, TREE_OPERAND (t, 1));
10213 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
10214 gimple_omp_for_set_incr (gfor, i, TREE_OPERAND (t, 1));
10217 /* OMP_TASKLOOP is gimplified as two GIMPLE_OMP_FOR taskloop
10218 constructs with GIMPLE_OMP_TASK sandwiched in between them.
10219 The outer taskloop stands for computing the number of iterations,
10220 counts for collapsed loops and holding taskloop specific clauses.
10221 The task construct stands for the effect of data sharing on the
10222 explicit task it creates and the inner taskloop stands for expansion
10223 of the static loop inside of the explicit task construct. */
10224 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
10226 tree *gfor_clauses_ptr = gimple_omp_for_clauses_ptr (gfor);
10227 tree task_clauses = NULL_TREE;
10228 tree c = *gfor_clauses_ptr;
10229 tree *gtask_clauses_ptr = &task_clauses;
10230 tree outer_for_clauses = NULL_TREE;
10231 tree *gforo_clauses_ptr = &outer_for_clauses;
10232 for (; c; c = OMP_CLAUSE_CHAIN (c))
10233 switch (OMP_CLAUSE_CODE (c))
10235 /* These clauses are allowed on task, move them there. */
10236 case OMP_CLAUSE_SHARED:
10237 case OMP_CLAUSE_FIRSTPRIVATE:
10238 case OMP_CLAUSE_DEFAULT:
10239 case OMP_CLAUSE_IF:
10240 case OMP_CLAUSE_UNTIED:
10241 case OMP_CLAUSE_FINAL:
10242 case OMP_CLAUSE_MERGEABLE:
10243 case OMP_CLAUSE_PRIORITY:
10244 *gtask_clauses_ptr = c;
10245 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
10246 break;
10247 case OMP_CLAUSE_PRIVATE:
10248 if (OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c))
10250 /* We want private on outer for and firstprivate
10251 on task. */
10252 *gtask_clauses_ptr
10253 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
10254 OMP_CLAUSE_FIRSTPRIVATE);
10255 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
10256 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL);
10257 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
10258 *gforo_clauses_ptr = c;
10259 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
10261 else
10263 *gtask_clauses_ptr = c;
10264 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
10266 break;
10267 /* These clauses go into outer taskloop clauses. */
10268 case OMP_CLAUSE_GRAINSIZE:
10269 case OMP_CLAUSE_NUM_TASKS:
10270 case OMP_CLAUSE_NOGROUP:
10271 *gforo_clauses_ptr = c;
10272 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
10273 break;
10274 /* Taskloop clause we duplicate on both taskloops. */
10275 case OMP_CLAUSE_COLLAPSE:
10276 *gfor_clauses_ptr = c;
10277 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
10278 *gforo_clauses_ptr = copy_node (c);
10279 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
10280 break;
10281 /* For lastprivate, keep the clause on inner taskloop, and add
10282 a shared clause on task. If the same decl is also firstprivate,
10283 add also firstprivate clause on the inner taskloop. */
10284 case OMP_CLAUSE_LASTPRIVATE:
10285 if (OMP_CLAUSE_LASTPRIVATE_TASKLOOP_IV (c))
10287 /* For taskloop C++ lastprivate IVs, we want:
10288 1) private on outer taskloop
10289 2) firstprivate and shared on task
10290 3) lastprivate on inner taskloop */
10291 *gtask_clauses_ptr
10292 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
10293 OMP_CLAUSE_FIRSTPRIVATE);
10294 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
10295 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL);
10296 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
10297 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c) = 1;
10298 *gforo_clauses_ptr = build_omp_clause (OMP_CLAUSE_LOCATION (c),
10299 OMP_CLAUSE_PRIVATE);
10300 OMP_CLAUSE_DECL (*gforo_clauses_ptr) = OMP_CLAUSE_DECL (c);
10301 OMP_CLAUSE_PRIVATE_TASKLOOP_IV (*gforo_clauses_ptr) = 1;
10302 TREE_TYPE (*gforo_clauses_ptr) = TREE_TYPE (c);
10303 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
10305 *gfor_clauses_ptr = c;
10306 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
10307 *gtask_clauses_ptr
10308 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_SHARED);
10309 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
10310 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
10311 OMP_CLAUSE_SHARED_FIRSTPRIVATE (*gtask_clauses_ptr) = 1;
10312 gtask_clauses_ptr
10313 = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
10314 break;
10315 default:
10316 gcc_unreachable ();
10318 *gfor_clauses_ptr = NULL_TREE;
10319 *gtask_clauses_ptr = NULL_TREE;
10320 *gforo_clauses_ptr = NULL_TREE;
10321 g = gimple_build_bind (NULL_TREE, gfor, NULL_TREE);
10322 g = gimple_build_omp_task (g, task_clauses, NULL_TREE, NULL_TREE,
10323 NULL_TREE, NULL_TREE, NULL_TREE);
10324 gimple_omp_task_set_taskloop_p (g, true);
10325 g = gimple_build_bind (NULL_TREE, g, NULL_TREE);
10326 gomp_for *gforo
10327 = gimple_build_omp_for (g, GF_OMP_FOR_KIND_TASKLOOP, outer_for_clauses,
10328 gimple_omp_for_collapse (gfor),
10329 gimple_omp_for_pre_body (gfor));
10330 gimple_omp_for_set_pre_body (gfor, NULL);
10331 gimple_omp_for_set_combined_p (gforo, true);
10332 gimple_omp_for_set_combined_into_p (gfor, true);
10333 for (i = 0; i < (int) gimple_omp_for_collapse (gfor); i++)
10335 tree type = TREE_TYPE (gimple_omp_for_index (gfor, i));
10336 tree v = create_tmp_var (type);
10337 gimple_omp_for_set_index (gforo, i, v);
10338 t = unshare_expr (gimple_omp_for_initial (gfor, i));
10339 gimple_omp_for_set_initial (gforo, i, t);
10340 gimple_omp_for_set_cond (gforo, i,
10341 gimple_omp_for_cond (gfor, i));
10342 t = unshare_expr (gimple_omp_for_final (gfor, i));
10343 gimple_omp_for_set_final (gforo, i, t);
10344 t = unshare_expr (gimple_omp_for_incr (gfor, i));
10345 gcc_assert (TREE_OPERAND (t, 0) == gimple_omp_for_index (gfor, i));
10346 TREE_OPERAND (t, 0) = v;
10347 gimple_omp_for_set_incr (gforo, i, t);
10348 t = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
10349 OMP_CLAUSE_DECL (t) = v;
10350 OMP_CLAUSE_CHAIN (t) = gimple_omp_for_clauses (gforo);
10351 gimple_omp_for_set_clauses (gforo, t);
10353 gimplify_seq_add_stmt (pre_p, gforo);
10355 else
10356 gimplify_seq_add_stmt (pre_p, gfor);
10357 if (ret != GS_ALL_DONE)
10358 return GS_ERROR;
10359 *expr_p = NULL_TREE;
10360 return GS_ALL_DONE;
10363 /* Helper function of optimize_target_teams, find OMP_TEAMS inside
10364 of OMP_TARGET's body. */
10366 static tree
10367 find_omp_teams (tree *tp, int *walk_subtrees, void *)
10369 *walk_subtrees = 0;
10370 switch (TREE_CODE (*tp))
10372 case OMP_TEAMS:
10373 return *tp;
10374 case BIND_EXPR:
10375 case STATEMENT_LIST:
10376 *walk_subtrees = 1;
10377 break;
10378 default:
10379 break;
10381 return NULL_TREE;
10384 /* Helper function of optimize_target_teams, determine if the expression
10385 can be computed safely before the target construct on the host. */
10387 static tree
10388 computable_teams_clause (tree *tp, int *walk_subtrees, void *)
10390 splay_tree_node n;
10392 if (TYPE_P (*tp))
10394 *walk_subtrees = 0;
10395 return NULL_TREE;
10397 switch (TREE_CODE (*tp))
10399 case VAR_DECL:
10400 case PARM_DECL:
10401 case RESULT_DECL:
10402 *walk_subtrees = 0;
10403 if (error_operand_p (*tp)
10404 || !INTEGRAL_TYPE_P (TREE_TYPE (*tp))
10405 || DECL_HAS_VALUE_EXPR_P (*tp)
10406 || DECL_THREAD_LOCAL_P (*tp)
10407 || TREE_SIDE_EFFECTS (*tp)
10408 || TREE_THIS_VOLATILE (*tp))
10409 return *tp;
10410 if (is_global_var (*tp)
10411 && (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (*tp))
10412 || lookup_attribute ("omp declare target link",
10413 DECL_ATTRIBUTES (*tp))))
10414 return *tp;
10415 if (VAR_P (*tp)
10416 && !DECL_SEEN_IN_BIND_EXPR_P (*tp)
10417 && !is_global_var (*tp)
10418 && decl_function_context (*tp) == current_function_decl)
10419 return *tp;
10420 n = splay_tree_lookup (gimplify_omp_ctxp->variables,
10421 (splay_tree_key) *tp);
10422 if (n == NULL)
10424 if (gimplify_omp_ctxp->target_map_scalars_firstprivate)
10425 return NULL_TREE;
10426 return *tp;
10428 else if (n->value & GOVD_LOCAL)
10429 return *tp;
10430 else if (n->value & GOVD_FIRSTPRIVATE)
10431 return NULL_TREE;
10432 else if ((n->value & (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
10433 == (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
10434 return NULL_TREE;
10435 return *tp;
10436 case INTEGER_CST:
10437 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
10438 return *tp;
10439 return NULL_TREE;
10440 case TARGET_EXPR:
10441 if (TARGET_EXPR_INITIAL (*tp)
10442 || TREE_CODE (TARGET_EXPR_SLOT (*tp)) != VAR_DECL)
10443 return *tp;
10444 return computable_teams_clause (&TARGET_EXPR_SLOT (*tp),
10445 walk_subtrees, NULL);
10446 /* Allow some reasonable subset of integral arithmetics. */
10447 case PLUS_EXPR:
10448 case MINUS_EXPR:
10449 case MULT_EXPR:
10450 case TRUNC_DIV_EXPR:
10451 case CEIL_DIV_EXPR:
10452 case FLOOR_DIV_EXPR:
10453 case ROUND_DIV_EXPR:
10454 case TRUNC_MOD_EXPR:
10455 case CEIL_MOD_EXPR:
10456 case FLOOR_MOD_EXPR:
10457 case ROUND_MOD_EXPR:
10458 case RDIV_EXPR:
10459 case EXACT_DIV_EXPR:
10460 case MIN_EXPR:
10461 case MAX_EXPR:
10462 case LSHIFT_EXPR:
10463 case RSHIFT_EXPR:
10464 case BIT_IOR_EXPR:
10465 case BIT_XOR_EXPR:
10466 case BIT_AND_EXPR:
10467 case NEGATE_EXPR:
10468 case ABS_EXPR:
10469 case BIT_NOT_EXPR:
10470 case NON_LVALUE_EXPR:
10471 CASE_CONVERT:
10472 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
10473 return *tp;
10474 return NULL_TREE;
10475 /* And disallow anything else, except for comparisons. */
10476 default:
10477 if (COMPARISON_CLASS_P (*tp))
10478 return NULL_TREE;
10479 return *tp;
10483 /* Try to determine if the num_teams and/or thread_limit expressions
10484 can have their values determined already before entering the
10485 target construct.
10486 INTEGER_CSTs trivially are,
10487 integral decls that are firstprivate (explicitly or implicitly)
10488 or explicitly map(always, to:) or map(always, tofrom:) on the target
10489 region too, and expressions involving simple arithmetics on those
10490 too, function calls are not ok, dereferencing something neither etc.
10491 Add NUM_TEAMS and THREAD_LIMIT clauses to the OMP_CLAUSES of
10492 EXPR based on what we find:
10493 0 stands for clause not specified at all, use implementation default
10494 -1 stands for value that can't be determined easily before entering
10495 the target construct.
10496 If teams construct is not present at all, use 1 for num_teams
10497 and 0 for thread_limit (only one team is involved, and the thread
10498 limit is implementation defined. */
10500 static void
10501 optimize_target_teams (tree target, gimple_seq *pre_p)
10503 tree body = OMP_BODY (target);
10504 tree teams = walk_tree (&body, find_omp_teams, NULL, NULL);
10505 tree num_teams = integer_zero_node;
10506 tree thread_limit = integer_zero_node;
10507 location_t num_teams_loc = EXPR_LOCATION (target);
10508 location_t thread_limit_loc = EXPR_LOCATION (target);
10509 tree c, *p, expr;
10510 struct gimplify_omp_ctx *target_ctx = gimplify_omp_ctxp;
10512 if (teams == NULL_TREE)
10513 num_teams = integer_one_node;
10514 else
10515 for (c = OMP_TEAMS_CLAUSES (teams); c; c = OMP_CLAUSE_CHAIN (c))
10517 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS)
10519 p = &num_teams;
10520 num_teams_loc = OMP_CLAUSE_LOCATION (c);
10522 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
10524 p = &thread_limit;
10525 thread_limit_loc = OMP_CLAUSE_LOCATION (c);
10527 else
10528 continue;
10529 expr = OMP_CLAUSE_OPERAND (c, 0);
10530 if (TREE_CODE (expr) == INTEGER_CST)
10532 *p = expr;
10533 continue;
10535 if (walk_tree (&expr, computable_teams_clause, NULL, NULL))
10537 *p = integer_minus_one_node;
10538 continue;
10540 *p = expr;
10541 gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
10542 if (gimplify_expr (p, pre_p, NULL, is_gimple_val, fb_rvalue, false)
10543 == GS_ERROR)
10545 gimplify_omp_ctxp = target_ctx;
10546 *p = integer_minus_one_node;
10547 continue;
10549 gimplify_omp_ctxp = target_ctx;
10550 if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR)
10551 OMP_CLAUSE_OPERAND (c, 0) = *p;
10553 c = build_omp_clause (thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
10554 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = thread_limit;
10555 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
10556 OMP_TARGET_CLAUSES (target) = c;
10557 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
10558 OMP_CLAUSE_NUM_TEAMS_EXPR (c) = num_teams;
10559 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
10560 OMP_TARGET_CLAUSES (target) = c;
10563 /* Gimplify the gross structure of several OMP constructs. */
10565 static void
10566 gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
10568 tree expr = *expr_p;
10569 gimple *stmt;
10570 gimple_seq body = NULL;
10571 enum omp_region_type ort;
10573 switch (TREE_CODE (expr))
10575 case OMP_SECTIONS:
10576 case OMP_SINGLE:
10577 ort = ORT_WORKSHARE;
10578 break;
10579 case OMP_TARGET:
10580 ort = OMP_TARGET_COMBINED (expr) ? ORT_COMBINED_TARGET : ORT_TARGET;
10581 break;
10582 case OACC_KERNELS:
10583 ort = ORT_ACC_KERNELS;
10584 break;
10585 case OACC_PARALLEL:
10586 ort = ORT_ACC_PARALLEL;
10587 break;
10588 case OACC_DATA:
10589 ort = ORT_ACC_DATA;
10590 break;
10591 case OMP_TARGET_DATA:
10592 ort = ORT_TARGET_DATA;
10593 break;
10594 case OMP_TEAMS:
10595 ort = OMP_TEAMS_COMBINED (expr) ? ORT_COMBINED_TEAMS : ORT_TEAMS;
10596 break;
10597 case OACC_HOST_DATA:
10598 ort = ORT_ACC_HOST_DATA;
10599 break;
10600 default:
10601 gcc_unreachable ();
10603 gimplify_scan_omp_clauses (&OMP_CLAUSES (expr), pre_p, ort,
10604 TREE_CODE (expr));
10605 if (TREE_CODE (expr) == OMP_TARGET)
10606 optimize_target_teams (expr, pre_p);
10607 if ((ort & (ORT_TARGET | ORT_TARGET_DATA)) != 0)
10609 push_gimplify_context ();
10610 gimple *g = gimplify_and_return_first (OMP_BODY (expr), &body);
10611 if (gimple_code (g) == GIMPLE_BIND)
10612 pop_gimplify_context (g);
10613 else
10614 pop_gimplify_context (NULL);
10615 if ((ort & ORT_TARGET_DATA) != 0)
10617 enum built_in_function end_ix;
10618 switch (TREE_CODE (expr))
10620 case OACC_DATA:
10621 case OACC_HOST_DATA:
10622 end_ix = BUILT_IN_GOACC_DATA_END;
10623 break;
10624 case OMP_TARGET_DATA:
10625 end_ix = BUILT_IN_GOMP_TARGET_END_DATA;
10626 break;
10627 default:
10628 gcc_unreachable ();
10630 tree fn = builtin_decl_explicit (end_ix);
10631 g = gimple_build_call (fn, 0);
10632 gimple_seq cleanup = NULL;
10633 gimple_seq_add_stmt (&cleanup, g);
10634 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
10635 body = NULL;
10636 gimple_seq_add_stmt (&body, g);
10639 else
10640 gimplify_and_add (OMP_BODY (expr), &body);
10641 gimplify_adjust_omp_clauses (pre_p, body, &OMP_CLAUSES (expr),
10642 TREE_CODE (expr));
10644 switch (TREE_CODE (expr))
10646 case OACC_DATA:
10647 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_DATA,
10648 OMP_CLAUSES (expr));
10649 break;
10650 case OACC_KERNELS:
10651 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_KERNELS,
10652 OMP_CLAUSES (expr));
10653 break;
10654 case OACC_HOST_DATA:
10655 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_HOST_DATA,
10656 OMP_CLAUSES (expr));
10657 break;
10658 case OACC_PARALLEL:
10659 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_PARALLEL,
10660 OMP_CLAUSES (expr));
10661 break;
10662 case OMP_SECTIONS:
10663 stmt = gimple_build_omp_sections (body, OMP_CLAUSES (expr));
10664 break;
10665 case OMP_SINGLE:
10666 stmt = gimple_build_omp_single (body, OMP_CLAUSES (expr));
10667 break;
10668 case OMP_TARGET:
10669 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_REGION,
10670 OMP_CLAUSES (expr));
10671 break;
10672 case OMP_TARGET_DATA:
10673 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_DATA,
10674 OMP_CLAUSES (expr));
10675 break;
10676 case OMP_TEAMS:
10677 stmt = gimple_build_omp_teams (body, OMP_CLAUSES (expr));
10678 break;
10679 default:
10680 gcc_unreachable ();
10683 gimplify_seq_add_stmt (pre_p, stmt);
10684 *expr_p = NULL_TREE;
10687 /* Gimplify the gross structure of OpenACC enter/exit data, update, and OpenMP
10688 target update constructs. */
10690 static void
10691 gimplify_omp_target_update (tree *expr_p, gimple_seq *pre_p)
10693 tree expr = *expr_p;
10694 int kind;
10695 gomp_target *stmt;
10696 enum omp_region_type ort = ORT_WORKSHARE;
10698 switch (TREE_CODE (expr))
10700 case OACC_ENTER_DATA:
10701 case OACC_EXIT_DATA:
10702 kind = GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA;
10703 ort = ORT_ACC;
10704 break;
10705 case OACC_UPDATE:
10706 kind = GF_OMP_TARGET_KIND_OACC_UPDATE;
10707 ort = ORT_ACC;
10708 break;
10709 case OMP_TARGET_UPDATE:
10710 kind = GF_OMP_TARGET_KIND_UPDATE;
10711 break;
10712 case OMP_TARGET_ENTER_DATA:
10713 kind = GF_OMP_TARGET_KIND_ENTER_DATA;
10714 break;
10715 case OMP_TARGET_EXIT_DATA:
10716 kind = GF_OMP_TARGET_KIND_EXIT_DATA;
10717 break;
10718 default:
10719 gcc_unreachable ();
10721 gimplify_scan_omp_clauses (&OMP_STANDALONE_CLAUSES (expr), pre_p,
10722 ort, TREE_CODE (expr));
10723 gimplify_adjust_omp_clauses (pre_p, NULL, &OMP_STANDALONE_CLAUSES (expr),
10724 TREE_CODE (expr));
10725 stmt = gimple_build_omp_target (NULL, kind, OMP_STANDALONE_CLAUSES (expr));
10727 gimplify_seq_add_stmt (pre_p, stmt);
10728 *expr_p = NULL_TREE;
10731 /* A subroutine of gimplify_omp_atomic. The front end is supposed to have
10732 stabilized the lhs of the atomic operation as *ADDR. Return true if
10733 EXPR is this stabilized form. */
10735 static bool
10736 goa_lhs_expr_p (tree expr, tree addr)
10738 /* Also include casts to other type variants. The C front end is fond
10739 of adding these for e.g. volatile variables. This is like
10740 STRIP_TYPE_NOPS but includes the main variant lookup. */
10741 STRIP_USELESS_TYPE_CONVERSION (expr);
10743 if (TREE_CODE (expr) == INDIRECT_REF)
10745 expr = TREE_OPERAND (expr, 0);
10746 while (expr != addr
10747 && (CONVERT_EXPR_P (expr)
10748 || TREE_CODE (expr) == NON_LVALUE_EXPR)
10749 && TREE_CODE (expr) == TREE_CODE (addr)
10750 && types_compatible_p (TREE_TYPE (expr), TREE_TYPE (addr)))
10752 expr = TREE_OPERAND (expr, 0);
10753 addr = TREE_OPERAND (addr, 0);
10755 if (expr == addr)
10756 return true;
10757 return (TREE_CODE (addr) == ADDR_EXPR
10758 && TREE_CODE (expr) == ADDR_EXPR
10759 && TREE_OPERAND (addr, 0) == TREE_OPERAND (expr, 0));
10761 if (TREE_CODE (addr) == ADDR_EXPR && expr == TREE_OPERAND (addr, 0))
10762 return true;
10763 return false;
10766 /* Walk *EXPR_P and replace appearances of *LHS_ADDR with LHS_VAR. If an
10767 expression does not involve the lhs, evaluate it into a temporary.
10768 Return 1 if the lhs appeared as a subexpression, 0 if it did not,
10769 or -1 if an error was encountered. */
10771 static int
10772 goa_stabilize_expr (tree *expr_p, gimple_seq *pre_p, tree lhs_addr,
10773 tree lhs_var)
10775 tree expr = *expr_p;
10776 int saw_lhs;
10778 if (goa_lhs_expr_p (expr, lhs_addr))
10780 *expr_p = lhs_var;
10781 return 1;
10783 if (is_gimple_val (expr))
10784 return 0;
10786 saw_lhs = 0;
10787 switch (TREE_CODE_CLASS (TREE_CODE (expr)))
10789 case tcc_binary:
10790 case tcc_comparison:
10791 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p, lhs_addr,
10792 lhs_var);
10793 /* FALLTHRU */
10794 case tcc_unary:
10795 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p, lhs_addr,
10796 lhs_var);
10797 break;
10798 case tcc_expression:
10799 switch (TREE_CODE (expr))
10801 case TRUTH_ANDIF_EXPR:
10802 case TRUTH_ORIF_EXPR:
10803 case TRUTH_AND_EXPR:
10804 case TRUTH_OR_EXPR:
10805 case TRUTH_XOR_EXPR:
10806 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
10807 lhs_addr, lhs_var);
10808 /* FALLTHRU */
10809 case TRUTH_NOT_EXPR:
10810 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
10811 lhs_addr, lhs_var);
10812 break;
10813 case COMPOUND_EXPR:
10814 /* Break out any preevaluations from cp_build_modify_expr. */
10815 for (; TREE_CODE (expr) == COMPOUND_EXPR;
10816 expr = TREE_OPERAND (expr, 1))
10817 gimplify_stmt (&TREE_OPERAND (expr, 0), pre_p);
10818 *expr_p = expr;
10819 return goa_stabilize_expr (expr_p, pre_p, lhs_addr, lhs_var);
10820 default:
10821 break;
10823 break;
10824 default:
10825 break;
10828 if (saw_lhs == 0)
10830 enum gimplify_status gs;
10831 gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_val, fb_rvalue);
10832 if (gs != GS_ALL_DONE)
10833 saw_lhs = -1;
10836 return saw_lhs;
10839 /* Gimplify an OMP_ATOMIC statement. */
10841 static enum gimplify_status
10842 gimplify_omp_atomic (tree *expr_p, gimple_seq *pre_p)
10844 tree addr = TREE_OPERAND (*expr_p, 0);
10845 tree rhs = TREE_CODE (*expr_p) == OMP_ATOMIC_READ
10846 ? NULL : TREE_OPERAND (*expr_p, 1);
10847 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
10848 tree tmp_load;
10849 gomp_atomic_load *loadstmt;
10850 gomp_atomic_store *storestmt;
10852 tmp_load = create_tmp_reg (type);
10853 if (rhs && goa_stabilize_expr (&rhs, pre_p, addr, tmp_load) < 0)
10854 return GS_ERROR;
10856 if (gimplify_expr (&addr, pre_p, NULL, is_gimple_val, fb_rvalue)
10857 != GS_ALL_DONE)
10858 return GS_ERROR;
10860 loadstmt = gimple_build_omp_atomic_load (tmp_load, addr);
10861 gimplify_seq_add_stmt (pre_p, loadstmt);
10862 if (rhs && gimplify_expr (&rhs, pre_p, NULL, is_gimple_val, fb_rvalue)
10863 != GS_ALL_DONE)
10864 return GS_ERROR;
10866 if (TREE_CODE (*expr_p) == OMP_ATOMIC_READ)
10867 rhs = tmp_load;
10868 storestmt = gimple_build_omp_atomic_store (rhs);
10869 gimplify_seq_add_stmt (pre_p, storestmt);
10870 if (OMP_ATOMIC_SEQ_CST (*expr_p))
10872 gimple_omp_atomic_set_seq_cst (loadstmt);
10873 gimple_omp_atomic_set_seq_cst (storestmt);
10875 switch (TREE_CODE (*expr_p))
10877 case OMP_ATOMIC_READ:
10878 case OMP_ATOMIC_CAPTURE_OLD:
10879 *expr_p = tmp_load;
10880 gimple_omp_atomic_set_need_value (loadstmt);
10881 break;
10882 case OMP_ATOMIC_CAPTURE_NEW:
10883 *expr_p = rhs;
10884 gimple_omp_atomic_set_need_value (storestmt);
10885 break;
10886 default:
10887 *expr_p = NULL;
10888 break;
10891 return GS_ALL_DONE;
10894 /* Gimplify a TRANSACTION_EXPR. This involves gimplification of the
10895 body, and adding some EH bits. */
10897 static enum gimplify_status
10898 gimplify_transaction (tree *expr_p, gimple_seq *pre_p)
10900 tree expr = *expr_p, temp, tbody = TRANSACTION_EXPR_BODY (expr);
10901 gimple *body_stmt;
10902 gtransaction *trans_stmt;
10903 gimple_seq body = NULL;
10904 int subcode = 0;
10906 /* Wrap the transaction body in a BIND_EXPR so we have a context
10907 where to put decls for OMP. */
10908 if (TREE_CODE (tbody) != BIND_EXPR)
10910 tree bind = build3 (BIND_EXPR, void_type_node, NULL, tbody, NULL);
10911 TREE_SIDE_EFFECTS (bind) = 1;
10912 SET_EXPR_LOCATION (bind, EXPR_LOCATION (tbody));
10913 TRANSACTION_EXPR_BODY (expr) = bind;
10916 push_gimplify_context ();
10917 temp = voidify_wrapper_expr (*expr_p, NULL);
10919 body_stmt = gimplify_and_return_first (TRANSACTION_EXPR_BODY (expr), &body);
10920 pop_gimplify_context (body_stmt);
10922 trans_stmt = gimple_build_transaction (body);
10923 if (TRANSACTION_EXPR_OUTER (expr))
10924 subcode = GTMA_IS_OUTER;
10925 else if (TRANSACTION_EXPR_RELAXED (expr))
10926 subcode = GTMA_IS_RELAXED;
10927 gimple_transaction_set_subcode (trans_stmt, subcode);
10929 gimplify_seq_add_stmt (pre_p, trans_stmt);
10931 if (temp)
10933 *expr_p = temp;
10934 return GS_OK;
10937 *expr_p = NULL_TREE;
10938 return GS_ALL_DONE;
10941 /* Gimplify an OMP_ORDERED construct. EXPR is the tree version. BODY
10942 is the OMP_BODY of the original EXPR (which has already been
10943 gimplified so it's not present in the EXPR).
10945 Return the gimplified GIMPLE_OMP_ORDERED tuple. */
10947 static gimple *
10948 gimplify_omp_ordered (tree expr, gimple_seq body)
10950 tree c, decls;
10951 int failures = 0;
10952 unsigned int i;
10953 tree source_c = NULL_TREE;
10954 tree sink_c = NULL_TREE;
10956 if (gimplify_omp_ctxp)
10958 for (c = OMP_ORDERED_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
10959 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
10960 && gimplify_omp_ctxp->loop_iter_var.is_empty ()
10961 && (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK
10962 || OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE))
10964 error_at (OMP_CLAUSE_LOCATION (c),
10965 "%<ordered%> construct with %<depend%> clause must be "
10966 "closely nested inside a loop with %<ordered%> clause "
10967 "with a parameter");
10968 failures++;
10970 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
10971 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
10973 bool fail = false;
10974 for (decls = OMP_CLAUSE_DECL (c), i = 0;
10975 decls && TREE_CODE (decls) == TREE_LIST;
10976 decls = TREE_CHAIN (decls), ++i)
10977 if (i >= gimplify_omp_ctxp->loop_iter_var.length () / 2)
10978 continue;
10979 else if (TREE_VALUE (decls)
10980 != gimplify_omp_ctxp->loop_iter_var[2 * i])
10982 error_at (OMP_CLAUSE_LOCATION (c),
10983 "variable %qE is not an iteration "
10984 "of outermost loop %d, expected %qE",
10985 TREE_VALUE (decls), i + 1,
10986 gimplify_omp_ctxp->loop_iter_var[2 * i]);
10987 fail = true;
10988 failures++;
10990 else
10991 TREE_VALUE (decls)
10992 = gimplify_omp_ctxp->loop_iter_var[2 * i + 1];
10993 if (!fail && i != gimplify_omp_ctxp->loop_iter_var.length () / 2)
10995 error_at (OMP_CLAUSE_LOCATION (c),
10996 "number of variables in %<depend(sink)%> "
10997 "clause does not match number of "
10998 "iteration variables");
10999 failures++;
11001 sink_c = c;
11003 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
11004 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
11006 if (source_c)
11008 error_at (OMP_CLAUSE_LOCATION (c),
11009 "more than one %<depend(source)%> clause on an "
11010 "%<ordered%> construct");
11011 failures++;
11013 else
11014 source_c = c;
11017 if (source_c && sink_c)
11019 error_at (OMP_CLAUSE_LOCATION (source_c),
11020 "%<depend(source)%> clause specified together with "
11021 "%<depend(sink:)%> clauses on the same construct");
11022 failures++;
11025 if (failures)
11026 return gimple_build_nop ();
11027 return gimple_build_omp_ordered (body, OMP_ORDERED_CLAUSES (expr));
11030 /* Convert the GENERIC expression tree *EXPR_P to GIMPLE. If the
11031 expression produces a value to be used as an operand inside a GIMPLE
11032 statement, the value will be stored back in *EXPR_P. This value will
11033 be a tree of class tcc_declaration, tcc_constant, tcc_reference or
11034 an SSA_NAME. The corresponding sequence of GIMPLE statements is
11035 emitted in PRE_P and POST_P.
11037 Additionally, this process may overwrite parts of the input
11038 expression during gimplification. Ideally, it should be
11039 possible to do non-destructive gimplification.
11041 EXPR_P points to the GENERIC expression to convert to GIMPLE. If
11042 the expression needs to evaluate to a value to be used as
11043 an operand in a GIMPLE statement, this value will be stored in
11044 *EXPR_P on exit. This happens when the caller specifies one
11045 of fb_lvalue or fb_rvalue fallback flags.
11047 PRE_P will contain the sequence of GIMPLE statements corresponding
11048 to the evaluation of EXPR and all the side-effects that must
11049 be executed before the main expression. On exit, the last
11050 statement of PRE_P is the core statement being gimplified. For
11051 instance, when gimplifying 'if (++a)' the last statement in
11052 PRE_P will be 'if (t.1)' where t.1 is the result of
11053 pre-incrementing 'a'.
11055 POST_P will contain the sequence of GIMPLE statements corresponding
11056 to the evaluation of all the side-effects that must be executed
11057 after the main expression. If this is NULL, the post
11058 side-effects are stored at the end of PRE_P.
11060 The reason why the output is split in two is to handle post
11061 side-effects explicitly. In some cases, an expression may have
11062 inner and outer post side-effects which need to be emitted in
11063 an order different from the one given by the recursive
11064 traversal. For instance, for the expression (*p--)++ the post
11065 side-effects of '--' must actually occur *after* the post
11066 side-effects of '++'. However, gimplification will first visit
11067 the inner expression, so if a separate POST sequence was not
11068 used, the resulting sequence would be:
11070 1 t.1 = *p
11071 2 p = p - 1
11072 3 t.2 = t.1 + 1
11073 4 *p = t.2
11075 However, the post-decrement operation in line #2 must not be
11076 evaluated until after the store to *p at line #4, so the
11077 correct sequence should be:
11079 1 t.1 = *p
11080 2 t.2 = t.1 + 1
11081 3 *p = t.2
11082 4 p = p - 1
11084 So, by specifying a separate post queue, it is possible
11085 to emit the post side-effects in the correct order.
11086 If POST_P is NULL, an internal queue will be used. Before
11087 returning to the caller, the sequence POST_P is appended to
11088 the main output sequence PRE_P.
11090 GIMPLE_TEST_F points to a function that takes a tree T and
11091 returns nonzero if T is in the GIMPLE form requested by the
11092 caller. The GIMPLE predicates are in gimple.c.
11094 FALLBACK tells the function what sort of a temporary we want if
11095 gimplification cannot produce an expression that complies with
11096 GIMPLE_TEST_F.
11098 fb_none means that no temporary should be generated
11099 fb_rvalue means that an rvalue is OK to generate
11100 fb_lvalue means that an lvalue is OK to generate
11101 fb_either means that either is OK, but an lvalue is preferable.
11102 fb_mayfail means that gimplification may fail (in which case
11103 GS_ERROR will be returned)
11105 The return value is either GS_ERROR or GS_ALL_DONE, since this
11106 function iterates until EXPR is completely gimplified or an error
11107 occurs. */
11109 enum gimplify_status
11110 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
11111 bool (*gimple_test_f) (tree), fallback_t fallback)
11113 tree tmp;
11114 gimple_seq internal_pre = NULL;
11115 gimple_seq internal_post = NULL;
11116 tree save_expr;
11117 bool is_statement;
11118 location_t saved_location;
11119 enum gimplify_status ret;
11120 gimple_stmt_iterator pre_last_gsi, post_last_gsi;
11121 tree label;
11123 save_expr = *expr_p;
11124 if (save_expr == NULL_TREE)
11125 return GS_ALL_DONE;
11127 /* If we are gimplifying a top-level statement, PRE_P must be valid. */
11128 is_statement = gimple_test_f == is_gimple_stmt;
11129 if (is_statement)
11130 gcc_assert (pre_p);
11132 /* Consistency checks. */
11133 if (gimple_test_f == is_gimple_reg)
11134 gcc_assert (fallback & (fb_rvalue | fb_lvalue));
11135 else if (gimple_test_f == is_gimple_val
11136 || gimple_test_f == is_gimple_call_addr
11137 || gimple_test_f == is_gimple_condexpr
11138 || gimple_test_f == is_gimple_mem_rhs
11139 || gimple_test_f == is_gimple_mem_rhs_or_call
11140 || gimple_test_f == is_gimple_reg_rhs
11141 || gimple_test_f == is_gimple_reg_rhs_or_call
11142 || gimple_test_f == is_gimple_asm_val
11143 || gimple_test_f == is_gimple_mem_ref_addr)
11144 gcc_assert (fallback & fb_rvalue);
11145 else if (gimple_test_f == is_gimple_min_lval
11146 || gimple_test_f == is_gimple_lvalue)
11147 gcc_assert (fallback & fb_lvalue);
11148 else if (gimple_test_f == is_gimple_addressable)
11149 gcc_assert (fallback & fb_either);
11150 else if (gimple_test_f == is_gimple_stmt)
11151 gcc_assert (fallback == fb_none);
11152 else
11154 /* We should have recognized the GIMPLE_TEST_F predicate to
11155 know what kind of fallback to use in case a temporary is
11156 needed to hold the value or address of *EXPR_P. */
11157 gcc_unreachable ();
11160 /* We used to check the predicate here and return immediately if it
11161 succeeds. This is wrong; the design is for gimplification to be
11162 idempotent, and for the predicates to only test for valid forms, not
11163 whether they are fully simplified. */
11164 if (pre_p == NULL)
11165 pre_p = &internal_pre;
11167 if (post_p == NULL)
11168 post_p = &internal_post;
11170 /* Remember the last statements added to PRE_P and POST_P. Every
11171 new statement added by the gimplification helpers needs to be
11172 annotated with location information. To centralize the
11173 responsibility, we remember the last statement that had been
11174 added to both queues before gimplifying *EXPR_P. If
11175 gimplification produces new statements in PRE_P and POST_P, those
11176 statements will be annotated with the same location information
11177 as *EXPR_P. */
11178 pre_last_gsi = gsi_last (*pre_p);
11179 post_last_gsi = gsi_last (*post_p);
11181 saved_location = input_location;
11182 if (save_expr != error_mark_node
11183 && EXPR_HAS_LOCATION (*expr_p))
11184 input_location = EXPR_LOCATION (*expr_p);
11186 /* Loop over the specific gimplifiers until the toplevel node
11187 remains the same. */
11190 /* Strip away as many useless type conversions as possible
11191 at the toplevel. */
11192 STRIP_USELESS_TYPE_CONVERSION (*expr_p);
11194 /* Remember the expr. */
11195 save_expr = *expr_p;
11197 /* Die, die, die, my darling. */
11198 if (save_expr == error_mark_node
11199 || (TREE_TYPE (save_expr)
11200 && TREE_TYPE (save_expr) == error_mark_node))
11202 ret = GS_ERROR;
11203 break;
11206 /* Do any language-specific gimplification. */
11207 ret = ((enum gimplify_status)
11208 lang_hooks.gimplify_expr (expr_p, pre_p, post_p));
11209 if (ret == GS_OK)
11211 if (*expr_p == NULL_TREE)
11212 break;
11213 if (*expr_p != save_expr)
11214 continue;
11216 else if (ret != GS_UNHANDLED)
11217 break;
11219 /* Make sure that all the cases set 'ret' appropriately. */
11220 ret = GS_UNHANDLED;
11221 switch (TREE_CODE (*expr_p))
11223 /* First deal with the special cases. */
11225 case POSTINCREMENT_EXPR:
11226 case POSTDECREMENT_EXPR:
11227 case PREINCREMENT_EXPR:
11228 case PREDECREMENT_EXPR:
11229 ret = gimplify_self_mod_expr (expr_p, pre_p, post_p,
11230 fallback != fb_none,
11231 TREE_TYPE (*expr_p));
11232 break;
11234 case VIEW_CONVERT_EXPR:
11235 if (is_gimple_reg_type (TREE_TYPE (*expr_p))
11236 && is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0))))
11238 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
11239 post_p, is_gimple_val, fb_rvalue);
11240 recalculate_side_effects (*expr_p);
11241 break;
11243 /* Fallthru. */
11245 case ARRAY_REF:
11246 case ARRAY_RANGE_REF:
11247 case REALPART_EXPR:
11248 case IMAGPART_EXPR:
11249 case COMPONENT_REF:
11250 ret = gimplify_compound_lval (expr_p, pre_p, post_p,
11251 fallback ? fallback : fb_rvalue);
11252 break;
11254 case COND_EXPR:
11255 ret = gimplify_cond_expr (expr_p, pre_p, fallback);
11257 /* C99 code may assign to an array in a structure value of a
11258 conditional expression, and this has undefined behavior
11259 only on execution, so create a temporary if an lvalue is
11260 required. */
11261 if (fallback == fb_lvalue)
11263 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
11264 mark_addressable (*expr_p);
11265 ret = GS_OK;
11267 break;
11269 case CALL_EXPR:
11270 ret = gimplify_call_expr (expr_p, pre_p, fallback != fb_none);
11272 /* C99 code may assign to an array in a structure returned
11273 from a function, and this has undefined behavior only on
11274 execution, so create a temporary if an lvalue is
11275 required. */
11276 if (fallback == fb_lvalue)
11278 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
11279 mark_addressable (*expr_p);
11280 ret = GS_OK;
11282 break;
11284 case TREE_LIST:
11285 gcc_unreachable ();
11287 case COMPOUND_EXPR:
11288 ret = gimplify_compound_expr (expr_p, pre_p, fallback != fb_none);
11289 break;
11291 case COMPOUND_LITERAL_EXPR:
11292 ret = gimplify_compound_literal_expr (expr_p, pre_p,
11293 gimple_test_f, fallback);
11294 break;
11296 case MODIFY_EXPR:
11297 case INIT_EXPR:
11298 ret = gimplify_modify_expr (expr_p, pre_p, post_p,
11299 fallback != fb_none);
11300 break;
11302 case TRUTH_ANDIF_EXPR:
11303 case TRUTH_ORIF_EXPR:
11305 /* Preserve the original type of the expression and the
11306 source location of the outer expression. */
11307 tree org_type = TREE_TYPE (*expr_p);
11308 *expr_p = gimple_boolify (*expr_p);
11309 *expr_p = build3_loc (input_location, COND_EXPR,
11310 org_type, *expr_p,
11311 fold_convert_loc
11312 (input_location,
11313 org_type, boolean_true_node),
11314 fold_convert_loc
11315 (input_location,
11316 org_type, boolean_false_node));
11317 ret = GS_OK;
11318 break;
11321 case TRUTH_NOT_EXPR:
11323 tree type = TREE_TYPE (*expr_p);
11324 /* The parsers are careful to generate TRUTH_NOT_EXPR
11325 only with operands that are always zero or one.
11326 We do not fold here but handle the only interesting case
11327 manually, as fold may re-introduce the TRUTH_NOT_EXPR. */
11328 *expr_p = gimple_boolify (*expr_p);
11329 if (TYPE_PRECISION (TREE_TYPE (*expr_p)) == 1)
11330 *expr_p = build1_loc (input_location, BIT_NOT_EXPR,
11331 TREE_TYPE (*expr_p),
11332 TREE_OPERAND (*expr_p, 0));
11333 else
11334 *expr_p = build2_loc (input_location, BIT_XOR_EXPR,
11335 TREE_TYPE (*expr_p),
11336 TREE_OPERAND (*expr_p, 0),
11337 build_int_cst (TREE_TYPE (*expr_p), 1));
11338 if (!useless_type_conversion_p (type, TREE_TYPE (*expr_p)))
11339 *expr_p = fold_convert_loc (input_location, type, *expr_p);
11340 ret = GS_OK;
11341 break;
11344 case ADDR_EXPR:
11345 ret = gimplify_addr_expr (expr_p, pre_p, post_p);
11346 break;
11348 case ANNOTATE_EXPR:
11350 tree cond = TREE_OPERAND (*expr_p, 0);
11351 tree kind = TREE_OPERAND (*expr_p, 1);
11352 tree type = TREE_TYPE (cond);
11353 if (!INTEGRAL_TYPE_P (type))
11355 *expr_p = cond;
11356 ret = GS_OK;
11357 break;
11359 tree tmp = create_tmp_var (type);
11360 gimplify_arg (&cond, pre_p, EXPR_LOCATION (*expr_p));
11361 gcall *call
11362 = gimple_build_call_internal (IFN_ANNOTATE, 2, cond, kind);
11363 gimple_call_set_lhs (call, tmp);
11364 gimplify_seq_add_stmt (pre_p, call);
11365 *expr_p = tmp;
11366 ret = GS_ALL_DONE;
11367 break;
11370 case VA_ARG_EXPR:
11371 ret = gimplify_va_arg_expr (expr_p, pre_p, post_p);
11372 break;
11374 CASE_CONVERT:
11375 if (IS_EMPTY_STMT (*expr_p))
11377 ret = GS_ALL_DONE;
11378 break;
11381 if (VOID_TYPE_P (TREE_TYPE (*expr_p))
11382 || fallback == fb_none)
11384 /* Just strip a conversion to void (or in void context) and
11385 try again. */
11386 *expr_p = TREE_OPERAND (*expr_p, 0);
11387 ret = GS_OK;
11388 break;
11391 ret = gimplify_conversion (expr_p);
11392 if (ret == GS_ERROR)
11393 break;
11394 if (*expr_p != save_expr)
11395 break;
11396 /* FALLTHRU */
11398 case FIX_TRUNC_EXPR:
11399 /* unary_expr: ... | '(' cast ')' val | ... */
11400 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
11401 is_gimple_val, fb_rvalue);
11402 recalculate_side_effects (*expr_p);
11403 break;
11405 case INDIRECT_REF:
11407 bool volatilep = TREE_THIS_VOLATILE (*expr_p);
11408 bool notrap = TREE_THIS_NOTRAP (*expr_p);
11409 tree saved_ptr_type = TREE_TYPE (TREE_OPERAND (*expr_p, 0));
11411 *expr_p = fold_indirect_ref_loc (input_location, *expr_p);
11412 if (*expr_p != save_expr)
11414 ret = GS_OK;
11415 break;
11418 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
11419 is_gimple_reg, fb_rvalue);
11420 if (ret == GS_ERROR)
11421 break;
11423 recalculate_side_effects (*expr_p);
11424 *expr_p = fold_build2_loc (input_location, MEM_REF,
11425 TREE_TYPE (*expr_p),
11426 TREE_OPERAND (*expr_p, 0),
11427 build_int_cst (saved_ptr_type, 0));
11428 TREE_THIS_VOLATILE (*expr_p) = volatilep;
11429 TREE_THIS_NOTRAP (*expr_p) = notrap;
11430 ret = GS_OK;
11431 break;
11434 /* We arrive here through the various re-gimplifcation paths. */
11435 case MEM_REF:
11436 /* First try re-folding the whole thing. */
11437 tmp = fold_binary (MEM_REF, TREE_TYPE (*expr_p),
11438 TREE_OPERAND (*expr_p, 0),
11439 TREE_OPERAND (*expr_p, 1));
11440 if (tmp)
11442 REF_REVERSE_STORAGE_ORDER (tmp)
11443 = REF_REVERSE_STORAGE_ORDER (*expr_p);
11444 *expr_p = tmp;
11445 recalculate_side_effects (*expr_p);
11446 ret = GS_OK;
11447 break;
11449 /* Avoid re-gimplifying the address operand if it is already
11450 in suitable form. Re-gimplifying would mark the address
11451 operand addressable. Always gimplify when not in SSA form
11452 as we still may have to gimplify decls with value-exprs. */
11453 if (!gimplify_ctxp || !gimple_in_ssa_p (cfun)
11454 || !is_gimple_mem_ref_addr (TREE_OPERAND (*expr_p, 0)))
11456 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
11457 is_gimple_mem_ref_addr, fb_rvalue);
11458 if (ret == GS_ERROR)
11459 break;
11461 recalculate_side_effects (*expr_p);
11462 ret = GS_ALL_DONE;
11463 break;
11465 /* Constants need not be gimplified. */
11466 case INTEGER_CST:
11467 case REAL_CST:
11468 case FIXED_CST:
11469 case STRING_CST:
11470 case COMPLEX_CST:
11471 case VECTOR_CST:
11472 /* Drop the overflow flag on constants, we do not want
11473 that in the GIMPLE IL. */
11474 if (TREE_OVERFLOW_P (*expr_p))
11475 *expr_p = drop_tree_overflow (*expr_p);
11476 ret = GS_ALL_DONE;
11477 break;
11479 case CONST_DECL:
11480 /* If we require an lvalue, such as for ADDR_EXPR, retain the
11481 CONST_DECL node. Otherwise the decl is replaceable by its
11482 value. */
11483 /* ??? Should be == fb_lvalue, but ADDR_EXPR passes fb_either. */
11484 if (fallback & fb_lvalue)
11485 ret = GS_ALL_DONE;
11486 else
11488 *expr_p = DECL_INITIAL (*expr_p);
11489 ret = GS_OK;
11491 break;
11493 case DECL_EXPR:
11494 ret = gimplify_decl_expr (expr_p, pre_p);
11495 break;
11497 case BIND_EXPR:
11498 ret = gimplify_bind_expr (expr_p, pre_p);
11499 break;
11501 case LOOP_EXPR:
11502 ret = gimplify_loop_expr (expr_p, pre_p);
11503 break;
11505 case SWITCH_EXPR:
11506 ret = gimplify_switch_expr (expr_p, pre_p);
11507 break;
11509 case EXIT_EXPR:
11510 ret = gimplify_exit_expr (expr_p);
11511 break;
11513 case GOTO_EXPR:
11514 /* If the target is not LABEL, then it is a computed jump
11515 and the target needs to be gimplified. */
11516 if (TREE_CODE (GOTO_DESTINATION (*expr_p)) != LABEL_DECL)
11518 ret = gimplify_expr (&GOTO_DESTINATION (*expr_p), pre_p,
11519 NULL, is_gimple_val, fb_rvalue);
11520 if (ret == GS_ERROR)
11521 break;
11523 gimplify_seq_add_stmt (pre_p,
11524 gimple_build_goto (GOTO_DESTINATION (*expr_p)));
11525 ret = GS_ALL_DONE;
11526 break;
11528 case PREDICT_EXPR:
11529 gimplify_seq_add_stmt (pre_p,
11530 gimple_build_predict (PREDICT_EXPR_PREDICTOR (*expr_p),
11531 PREDICT_EXPR_OUTCOME (*expr_p)));
11532 ret = GS_ALL_DONE;
11533 break;
11535 case LABEL_EXPR:
11536 ret = gimplify_label_expr (expr_p, pre_p);
11537 label = LABEL_EXPR_LABEL (*expr_p);
11538 gcc_assert (decl_function_context (label) == current_function_decl);
11540 /* If the label is used in a goto statement, or address of the label
11541 is taken, we need to unpoison all variables that were seen so far.
11542 Doing so would prevent us from reporting a false positives. */
11543 if (asan_poisoned_variables
11544 && asan_used_labels != NULL
11545 && asan_used_labels->contains (label))
11546 asan_poison_variables (asan_poisoned_variables, false, pre_p);
11547 break;
11549 case CASE_LABEL_EXPR:
11550 ret = gimplify_case_label_expr (expr_p, pre_p);
11552 if (gimplify_ctxp->live_switch_vars)
11553 asan_poison_variables (gimplify_ctxp->live_switch_vars, false,
11554 pre_p);
11555 break;
11557 case RETURN_EXPR:
11558 ret = gimplify_return_expr (*expr_p, pre_p);
11559 break;
11561 case CONSTRUCTOR:
11562 /* Don't reduce this in place; let gimplify_init_constructor work its
11563 magic. Buf if we're just elaborating this for side effects, just
11564 gimplify any element that has side-effects. */
11565 if (fallback == fb_none)
11567 unsigned HOST_WIDE_INT ix;
11568 tree val;
11569 tree temp = NULL_TREE;
11570 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (*expr_p), ix, val)
11571 if (TREE_SIDE_EFFECTS (val))
11572 append_to_statement_list (val, &temp);
11574 *expr_p = temp;
11575 ret = temp ? GS_OK : GS_ALL_DONE;
11577 /* C99 code may assign to an array in a constructed
11578 structure or union, and this has undefined behavior only
11579 on execution, so create a temporary if an lvalue is
11580 required. */
11581 else if (fallback == fb_lvalue)
11583 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
11584 mark_addressable (*expr_p);
11585 ret = GS_OK;
11587 else
11588 ret = GS_ALL_DONE;
11589 break;
11591 /* The following are special cases that are not handled by the
11592 original GIMPLE grammar. */
11594 /* SAVE_EXPR nodes are converted into a GIMPLE identifier and
11595 eliminated. */
11596 case SAVE_EXPR:
11597 ret = gimplify_save_expr (expr_p, pre_p, post_p);
11598 break;
11600 case BIT_FIELD_REF:
11601 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
11602 post_p, is_gimple_lvalue, fb_either);
11603 recalculate_side_effects (*expr_p);
11604 break;
11606 case TARGET_MEM_REF:
11608 enum gimplify_status r0 = GS_ALL_DONE, r1 = GS_ALL_DONE;
11610 if (TMR_BASE (*expr_p))
11611 r0 = gimplify_expr (&TMR_BASE (*expr_p), pre_p,
11612 post_p, is_gimple_mem_ref_addr, fb_either);
11613 if (TMR_INDEX (*expr_p))
11614 r1 = gimplify_expr (&TMR_INDEX (*expr_p), pre_p,
11615 post_p, is_gimple_val, fb_rvalue);
11616 if (TMR_INDEX2 (*expr_p))
11617 r1 = gimplify_expr (&TMR_INDEX2 (*expr_p), pre_p,
11618 post_p, is_gimple_val, fb_rvalue);
11619 /* TMR_STEP and TMR_OFFSET are always integer constants. */
11620 ret = MIN (r0, r1);
11622 break;
11624 case NON_LVALUE_EXPR:
11625 /* This should have been stripped above. */
11626 gcc_unreachable ();
11628 case ASM_EXPR:
11629 ret = gimplify_asm_expr (expr_p, pre_p, post_p);
11630 break;
11632 case TRY_FINALLY_EXPR:
11633 case TRY_CATCH_EXPR:
11635 gimple_seq eval, cleanup;
11636 gtry *try_;
11638 /* Calls to destructors are generated automatically in FINALLY/CATCH
11639 block. They should have location as UNKNOWN_LOCATION. However,
11640 gimplify_call_expr will reset these call stmts to input_location
11641 if it finds stmt's location is unknown. To prevent resetting for
11642 destructors, we set the input_location to unknown.
11643 Note that this only affects the destructor calls in FINALLY/CATCH
11644 block, and will automatically reset to its original value by the
11645 end of gimplify_expr. */
11646 input_location = UNKNOWN_LOCATION;
11647 eval = cleanup = NULL;
11648 gimplify_and_add (TREE_OPERAND (*expr_p, 0), &eval);
11649 gimplify_and_add (TREE_OPERAND (*expr_p, 1), &cleanup);
11650 /* Don't create bogus GIMPLE_TRY with empty cleanup. */
11651 if (gimple_seq_empty_p (cleanup))
11653 gimple_seq_add_seq (pre_p, eval);
11654 ret = GS_ALL_DONE;
11655 break;
11657 try_ = gimple_build_try (eval, cleanup,
11658 TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
11659 ? GIMPLE_TRY_FINALLY
11660 : GIMPLE_TRY_CATCH);
11661 if (EXPR_HAS_LOCATION (save_expr))
11662 gimple_set_location (try_, EXPR_LOCATION (save_expr));
11663 else if (LOCATION_LOCUS (saved_location) != UNKNOWN_LOCATION)
11664 gimple_set_location (try_, saved_location);
11665 if (TREE_CODE (*expr_p) == TRY_CATCH_EXPR)
11666 gimple_try_set_catch_is_cleanup (try_,
11667 TRY_CATCH_IS_CLEANUP (*expr_p));
11668 gimplify_seq_add_stmt (pre_p, try_);
11669 ret = GS_ALL_DONE;
11670 break;
11673 case CLEANUP_POINT_EXPR:
11674 ret = gimplify_cleanup_point_expr (expr_p, pre_p);
11675 break;
11677 case TARGET_EXPR:
11678 ret = gimplify_target_expr (expr_p, pre_p, post_p);
11679 break;
11681 case CATCH_EXPR:
11683 gimple *c;
11684 gimple_seq handler = NULL;
11685 gimplify_and_add (CATCH_BODY (*expr_p), &handler);
11686 c = gimple_build_catch (CATCH_TYPES (*expr_p), handler);
11687 gimplify_seq_add_stmt (pre_p, c);
11688 ret = GS_ALL_DONE;
11689 break;
11692 case EH_FILTER_EXPR:
11694 gimple *ehf;
11695 gimple_seq failure = NULL;
11697 gimplify_and_add (EH_FILTER_FAILURE (*expr_p), &failure);
11698 ehf = gimple_build_eh_filter (EH_FILTER_TYPES (*expr_p), failure);
11699 gimple_set_no_warning (ehf, TREE_NO_WARNING (*expr_p));
11700 gimplify_seq_add_stmt (pre_p, ehf);
11701 ret = GS_ALL_DONE;
11702 break;
11705 case OBJ_TYPE_REF:
11707 enum gimplify_status r0, r1;
11708 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p,
11709 post_p, is_gimple_val, fb_rvalue);
11710 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p,
11711 post_p, is_gimple_val, fb_rvalue);
11712 TREE_SIDE_EFFECTS (*expr_p) = 0;
11713 ret = MIN (r0, r1);
11715 break;
11717 case LABEL_DECL:
11718 /* We get here when taking the address of a label. We mark
11719 the label as "forced"; meaning it can never be removed and
11720 it is a potential target for any computed goto. */
11721 FORCED_LABEL (*expr_p) = 1;
11722 ret = GS_ALL_DONE;
11723 break;
11725 case STATEMENT_LIST:
11726 ret = gimplify_statement_list (expr_p, pre_p);
11727 break;
11729 case WITH_SIZE_EXPR:
11731 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
11732 post_p == &internal_post ? NULL : post_p,
11733 gimple_test_f, fallback);
11734 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
11735 is_gimple_val, fb_rvalue);
11736 ret = GS_ALL_DONE;
11738 break;
11740 case VAR_DECL:
11741 case PARM_DECL:
11742 ret = gimplify_var_or_parm_decl (expr_p);
11743 break;
11745 case RESULT_DECL:
11746 /* When within an OMP context, notice uses of variables. */
11747 if (gimplify_omp_ctxp)
11748 omp_notice_variable (gimplify_omp_ctxp, *expr_p, true);
11749 ret = GS_ALL_DONE;
11750 break;
11752 case SSA_NAME:
11753 /* Allow callbacks into the gimplifier during optimization. */
11754 ret = GS_ALL_DONE;
11755 break;
11757 case OMP_PARALLEL:
11758 gimplify_omp_parallel (expr_p, pre_p);
11759 ret = GS_ALL_DONE;
11760 break;
11762 case OMP_TASK:
11763 gimplify_omp_task (expr_p, pre_p);
11764 ret = GS_ALL_DONE;
11765 break;
11767 case OMP_FOR:
11768 case OMP_SIMD:
11769 case CILK_SIMD:
11770 case CILK_FOR:
11771 case OMP_DISTRIBUTE:
11772 case OMP_TASKLOOP:
11773 case OACC_LOOP:
11774 ret = gimplify_omp_for (expr_p, pre_p);
11775 break;
11777 case OACC_CACHE:
11778 gimplify_oacc_cache (expr_p, pre_p);
11779 ret = GS_ALL_DONE;
11780 break;
11782 case OACC_DECLARE:
11783 gimplify_oacc_declare (expr_p, pre_p);
11784 ret = GS_ALL_DONE;
11785 break;
11787 case OACC_HOST_DATA:
11788 case OACC_DATA:
11789 case OACC_KERNELS:
11790 case OACC_PARALLEL:
11791 case OMP_SECTIONS:
11792 case OMP_SINGLE:
11793 case OMP_TARGET:
11794 case OMP_TARGET_DATA:
11795 case OMP_TEAMS:
11796 gimplify_omp_workshare (expr_p, pre_p);
11797 ret = GS_ALL_DONE;
11798 break;
11800 case OACC_ENTER_DATA:
11801 case OACC_EXIT_DATA:
11802 case OACC_UPDATE:
11803 case OMP_TARGET_UPDATE:
11804 case OMP_TARGET_ENTER_DATA:
11805 case OMP_TARGET_EXIT_DATA:
11806 gimplify_omp_target_update (expr_p, pre_p);
11807 ret = GS_ALL_DONE;
11808 break;
11810 case OMP_SECTION:
11811 case OMP_MASTER:
11812 case OMP_TASKGROUP:
11813 case OMP_ORDERED:
11814 case OMP_CRITICAL:
11816 gimple_seq body = NULL;
11817 gimple *g;
11819 gimplify_and_add (OMP_BODY (*expr_p), &body);
11820 switch (TREE_CODE (*expr_p))
11822 case OMP_SECTION:
11823 g = gimple_build_omp_section (body);
11824 break;
11825 case OMP_MASTER:
11826 g = gimple_build_omp_master (body);
11827 break;
11828 case OMP_TASKGROUP:
11830 gimple_seq cleanup = NULL;
11831 tree fn
11832 = builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_END);
11833 g = gimple_build_call (fn, 0);
11834 gimple_seq_add_stmt (&cleanup, g);
11835 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
11836 body = NULL;
11837 gimple_seq_add_stmt (&body, g);
11838 g = gimple_build_omp_taskgroup (body);
11840 break;
11841 case OMP_ORDERED:
11842 g = gimplify_omp_ordered (*expr_p, body);
11843 break;
11844 case OMP_CRITICAL:
11845 gimplify_scan_omp_clauses (&OMP_CRITICAL_CLAUSES (*expr_p),
11846 pre_p, ORT_WORKSHARE, OMP_CRITICAL);
11847 gimplify_adjust_omp_clauses (pre_p, body,
11848 &OMP_CRITICAL_CLAUSES (*expr_p),
11849 OMP_CRITICAL);
11850 g = gimple_build_omp_critical (body,
11851 OMP_CRITICAL_NAME (*expr_p),
11852 OMP_CRITICAL_CLAUSES (*expr_p));
11853 break;
11854 default:
11855 gcc_unreachable ();
11857 gimplify_seq_add_stmt (pre_p, g);
11858 ret = GS_ALL_DONE;
11859 break;
11862 case OMP_ATOMIC:
11863 case OMP_ATOMIC_READ:
11864 case OMP_ATOMIC_CAPTURE_OLD:
11865 case OMP_ATOMIC_CAPTURE_NEW:
11866 ret = gimplify_omp_atomic (expr_p, pre_p);
11867 break;
11869 case TRANSACTION_EXPR:
11870 ret = gimplify_transaction (expr_p, pre_p);
11871 break;
11873 case TRUTH_AND_EXPR:
11874 case TRUTH_OR_EXPR:
11875 case TRUTH_XOR_EXPR:
11877 tree orig_type = TREE_TYPE (*expr_p);
11878 tree new_type, xop0, xop1;
11879 *expr_p = gimple_boolify (*expr_p);
11880 new_type = TREE_TYPE (*expr_p);
11881 if (!useless_type_conversion_p (orig_type, new_type))
11883 *expr_p = fold_convert_loc (input_location, orig_type, *expr_p);
11884 ret = GS_OK;
11885 break;
11888 /* Boolified binary truth expressions are semantically equivalent
11889 to bitwise binary expressions. Canonicalize them to the
11890 bitwise variant. */
11891 switch (TREE_CODE (*expr_p))
11893 case TRUTH_AND_EXPR:
11894 TREE_SET_CODE (*expr_p, BIT_AND_EXPR);
11895 break;
11896 case TRUTH_OR_EXPR:
11897 TREE_SET_CODE (*expr_p, BIT_IOR_EXPR);
11898 break;
11899 case TRUTH_XOR_EXPR:
11900 TREE_SET_CODE (*expr_p, BIT_XOR_EXPR);
11901 break;
11902 default:
11903 break;
11905 /* Now make sure that operands have compatible type to
11906 expression's new_type. */
11907 xop0 = TREE_OPERAND (*expr_p, 0);
11908 xop1 = TREE_OPERAND (*expr_p, 1);
11909 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop0)))
11910 TREE_OPERAND (*expr_p, 0) = fold_convert_loc (input_location,
11911 new_type,
11912 xop0);
11913 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop1)))
11914 TREE_OPERAND (*expr_p, 1) = fold_convert_loc (input_location,
11915 new_type,
11916 xop1);
11917 /* Continue classified as tcc_binary. */
11918 goto expr_2;
11921 case VEC_COND_EXPR:
11923 enum gimplify_status r0, r1, r2;
11925 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
11926 post_p, is_gimple_condexpr, fb_rvalue);
11927 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
11928 post_p, is_gimple_val, fb_rvalue);
11929 r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p,
11930 post_p, is_gimple_val, fb_rvalue);
11932 ret = MIN (MIN (r0, r1), r2);
11933 recalculate_side_effects (*expr_p);
11935 break;
11937 case FMA_EXPR:
11938 case VEC_PERM_EXPR:
11939 /* Classified as tcc_expression. */
11940 goto expr_3;
11942 case BIT_INSERT_EXPR:
11943 /* Argument 3 is a constant. */
11944 goto expr_2;
11946 case POINTER_PLUS_EXPR:
11948 enum gimplify_status r0, r1;
11949 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
11950 post_p, is_gimple_val, fb_rvalue);
11951 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
11952 post_p, is_gimple_val, fb_rvalue);
11953 recalculate_side_effects (*expr_p);
11954 ret = MIN (r0, r1);
11955 break;
11958 case CILK_SYNC_STMT:
11960 if (!fn_contains_cilk_spawn_p (cfun))
11962 error_at (EXPR_LOCATION (*expr_p),
11963 "expected %<_Cilk_spawn%> before %<_Cilk_sync%>");
11964 ret = GS_ERROR;
11966 else
11968 gimplify_cilk_sync (expr_p, pre_p);
11969 ret = GS_ALL_DONE;
11971 break;
11974 default:
11975 switch (TREE_CODE_CLASS (TREE_CODE (*expr_p)))
11977 case tcc_comparison:
11978 /* Handle comparison of objects of non scalar mode aggregates
11979 with a call to memcmp. It would be nice to only have to do
11980 this for variable-sized objects, but then we'd have to allow
11981 the same nest of reference nodes we allow for MODIFY_EXPR and
11982 that's too complex.
11984 Compare scalar mode aggregates as scalar mode values. Using
11985 memcmp for them would be very inefficient at best, and is
11986 plain wrong if bitfields are involved. */
11988 tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 1));
11990 /* Vector comparisons need no boolification. */
11991 if (TREE_CODE (type) == VECTOR_TYPE)
11992 goto expr_2;
11993 else if (!AGGREGATE_TYPE_P (type))
11995 tree org_type = TREE_TYPE (*expr_p);
11996 *expr_p = gimple_boolify (*expr_p);
11997 if (!useless_type_conversion_p (org_type,
11998 TREE_TYPE (*expr_p)))
12000 *expr_p = fold_convert_loc (input_location,
12001 org_type, *expr_p);
12002 ret = GS_OK;
12004 else
12005 goto expr_2;
12007 else if (TYPE_MODE (type) != BLKmode)
12008 ret = gimplify_scalar_mode_aggregate_compare (expr_p);
12009 else
12010 ret = gimplify_variable_sized_compare (expr_p);
12012 break;
12015 /* If *EXPR_P does not need to be special-cased, handle it
12016 according to its class. */
12017 case tcc_unary:
12018 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
12019 post_p, is_gimple_val, fb_rvalue);
12020 break;
12022 case tcc_binary:
12023 expr_2:
12025 enum gimplify_status r0, r1;
12027 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
12028 post_p, is_gimple_val, fb_rvalue);
12029 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
12030 post_p, is_gimple_val, fb_rvalue);
12032 ret = MIN (r0, r1);
12033 break;
12036 expr_3:
12038 enum gimplify_status r0, r1, r2;
12040 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
12041 post_p, is_gimple_val, fb_rvalue);
12042 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
12043 post_p, is_gimple_val, fb_rvalue);
12044 r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p,
12045 post_p, is_gimple_val, fb_rvalue);
12047 ret = MIN (MIN (r0, r1), r2);
12048 break;
12051 case tcc_declaration:
12052 case tcc_constant:
12053 ret = GS_ALL_DONE;
12054 goto dont_recalculate;
12056 default:
12057 gcc_unreachable ();
12060 recalculate_side_effects (*expr_p);
12062 dont_recalculate:
12063 break;
12066 gcc_assert (*expr_p || ret != GS_OK);
12068 while (ret == GS_OK);
12070 /* If we encountered an error_mark somewhere nested inside, either
12071 stub out the statement or propagate the error back out. */
12072 if (ret == GS_ERROR)
12074 if (is_statement)
12075 *expr_p = NULL;
12076 goto out;
12079 /* This was only valid as a return value from the langhook, which
12080 we handled. Make sure it doesn't escape from any other context. */
12081 gcc_assert (ret != GS_UNHANDLED);
12083 if (fallback == fb_none && *expr_p && !is_gimple_stmt (*expr_p))
12085 /* We aren't looking for a value, and we don't have a valid
12086 statement. If it doesn't have side-effects, throw it away.
12087 We can also get here with code such as "*&&L;", where L is
12088 a LABEL_DECL that is marked as FORCED_LABEL. */
12089 if (TREE_CODE (*expr_p) == LABEL_DECL
12090 || !TREE_SIDE_EFFECTS (*expr_p))
12091 *expr_p = NULL;
12092 else if (!TREE_THIS_VOLATILE (*expr_p))
12094 /* This is probably a _REF that contains something nested that
12095 has side effects. Recurse through the operands to find it. */
12096 enum tree_code code = TREE_CODE (*expr_p);
12098 switch (code)
12100 case COMPONENT_REF:
12101 case REALPART_EXPR:
12102 case IMAGPART_EXPR:
12103 case VIEW_CONVERT_EXPR:
12104 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
12105 gimple_test_f, fallback);
12106 break;
12108 case ARRAY_REF:
12109 case ARRAY_RANGE_REF:
12110 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
12111 gimple_test_f, fallback);
12112 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
12113 gimple_test_f, fallback);
12114 break;
12116 default:
12117 /* Anything else with side-effects must be converted to
12118 a valid statement before we get here. */
12119 gcc_unreachable ();
12122 *expr_p = NULL;
12124 else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p))
12125 && TYPE_MODE (TREE_TYPE (*expr_p)) != BLKmode)
12127 /* Historically, the compiler has treated a bare reference
12128 to a non-BLKmode volatile lvalue as forcing a load. */
12129 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p));
12131 /* Normally, we do not want to create a temporary for a
12132 TREE_ADDRESSABLE type because such a type should not be
12133 copied by bitwise-assignment. However, we make an
12134 exception here, as all we are doing here is ensuring that
12135 we read the bytes that make up the type. We use
12136 create_tmp_var_raw because create_tmp_var will abort when
12137 given a TREE_ADDRESSABLE type. */
12138 tree tmp = create_tmp_var_raw (type, "vol");
12139 gimple_add_tmp_var (tmp);
12140 gimplify_assign (tmp, *expr_p, pre_p);
12141 *expr_p = NULL;
12143 else
12144 /* We can't do anything useful with a volatile reference to
12145 an incomplete type, so just throw it away. Likewise for
12146 a BLKmode type, since any implicit inner load should
12147 already have been turned into an explicit one by the
12148 gimplification process. */
12149 *expr_p = NULL;
12152 /* If we are gimplifying at the statement level, we're done. Tack
12153 everything together and return. */
12154 if (fallback == fb_none || is_statement)
12156 /* Since *EXPR_P has been converted into a GIMPLE tuple, clear
12157 it out for GC to reclaim it. */
12158 *expr_p = NULL_TREE;
12160 if (!gimple_seq_empty_p (internal_pre)
12161 || !gimple_seq_empty_p (internal_post))
12163 gimplify_seq_add_seq (&internal_pre, internal_post);
12164 gimplify_seq_add_seq (pre_p, internal_pre);
12167 /* The result of gimplifying *EXPR_P is going to be the last few
12168 statements in *PRE_P and *POST_P. Add location information
12169 to all the statements that were added by the gimplification
12170 helpers. */
12171 if (!gimple_seq_empty_p (*pre_p))
12172 annotate_all_with_location_after (*pre_p, pre_last_gsi, input_location);
12174 if (!gimple_seq_empty_p (*post_p))
12175 annotate_all_with_location_after (*post_p, post_last_gsi,
12176 input_location);
12178 goto out;
12181 #ifdef ENABLE_GIMPLE_CHECKING
12182 if (*expr_p)
12184 enum tree_code code = TREE_CODE (*expr_p);
12185 /* These expressions should already be in gimple IR form. */
12186 gcc_assert (code != MODIFY_EXPR
12187 && code != ASM_EXPR
12188 && code != BIND_EXPR
12189 && code != CATCH_EXPR
12190 && (code != COND_EXPR || gimplify_ctxp->allow_rhs_cond_expr)
12191 && code != EH_FILTER_EXPR
12192 && code != GOTO_EXPR
12193 && code != LABEL_EXPR
12194 && code != LOOP_EXPR
12195 && code != SWITCH_EXPR
12196 && code != TRY_FINALLY_EXPR
12197 && code != OACC_PARALLEL
12198 && code != OACC_KERNELS
12199 && code != OACC_DATA
12200 && code != OACC_HOST_DATA
12201 && code != OACC_DECLARE
12202 && code != OACC_UPDATE
12203 && code != OACC_ENTER_DATA
12204 && code != OACC_EXIT_DATA
12205 && code != OACC_CACHE
12206 && code != OMP_CRITICAL
12207 && code != OMP_FOR
12208 && code != OACC_LOOP
12209 && code != OMP_MASTER
12210 && code != OMP_TASKGROUP
12211 && code != OMP_ORDERED
12212 && code != OMP_PARALLEL
12213 && code != OMP_SECTIONS
12214 && code != OMP_SECTION
12215 && code != OMP_SINGLE);
12217 #endif
12219 /* Otherwise we're gimplifying a subexpression, so the resulting
12220 value is interesting. If it's a valid operand that matches
12221 GIMPLE_TEST_F, we're done. Unless we are handling some
12222 post-effects internally; if that's the case, we need to copy into
12223 a temporary before adding the post-effects to POST_P. */
12224 if (gimple_seq_empty_p (internal_post) && (*gimple_test_f) (*expr_p))
12225 goto out;
12227 /* Otherwise, we need to create a new temporary for the gimplified
12228 expression. */
12230 /* We can't return an lvalue if we have an internal postqueue. The
12231 object the lvalue refers to would (probably) be modified by the
12232 postqueue; we need to copy the value out first, which means an
12233 rvalue. */
12234 if ((fallback & fb_lvalue)
12235 && gimple_seq_empty_p (internal_post)
12236 && is_gimple_addressable (*expr_p))
12238 /* An lvalue will do. Take the address of the expression, store it
12239 in a temporary, and replace the expression with an INDIRECT_REF of
12240 that temporary. */
12241 tmp = build_fold_addr_expr_loc (input_location, *expr_p);
12242 gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue);
12243 *expr_p = build_simple_mem_ref (tmp);
12245 else if ((fallback & fb_rvalue) && is_gimple_reg_rhs_or_call (*expr_p))
12247 /* An rvalue will do. Assign the gimplified expression into a
12248 new temporary TMP and replace the original expression with
12249 TMP. First, make sure that the expression has a type so that
12250 it can be assigned into a temporary. */
12251 gcc_assert (!VOID_TYPE_P (TREE_TYPE (*expr_p)));
12252 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
12254 else
12256 #ifdef ENABLE_GIMPLE_CHECKING
12257 if (!(fallback & fb_mayfail))
12259 fprintf (stderr, "gimplification failed:\n");
12260 print_generic_expr (stderr, *expr_p);
12261 debug_tree (*expr_p);
12262 internal_error ("gimplification failed");
12264 #endif
12265 gcc_assert (fallback & fb_mayfail);
12267 /* If this is an asm statement, and the user asked for the
12268 impossible, don't die. Fail and let gimplify_asm_expr
12269 issue an error. */
12270 ret = GS_ERROR;
12271 goto out;
12274 /* Make sure the temporary matches our predicate. */
12275 gcc_assert ((*gimple_test_f) (*expr_p));
12277 if (!gimple_seq_empty_p (internal_post))
12279 annotate_all_with_location (internal_post, input_location);
12280 gimplify_seq_add_seq (pre_p, internal_post);
12283 out:
12284 input_location = saved_location;
12285 return ret;
12288 /* Like gimplify_expr but make sure the gimplified result is not itself
12289 a SSA name (but a decl if it were). Temporaries required by
12290 evaluating *EXPR_P may be still SSA names. */
12292 static enum gimplify_status
12293 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
12294 bool (*gimple_test_f) (tree), fallback_t fallback,
12295 bool allow_ssa)
12297 bool was_ssa_name_p = TREE_CODE (*expr_p) == SSA_NAME;
12298 enum gimplify_status ret = gimplify_expr (expr_p, pre_p, post_p,
12299 gimple_test_f, fallback);
12300 if (! allow_ssa
12301 && TREE_CODE (*expr_p) == SSA_NAME)
12303 tree name = *expr_p;
12304 if (was_ssa_name_p)
12305 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, NULL, false);
12306 else
12308 /* Avoid the extra copy if possible. */
12309 *expr_p = create_tmp_reg (TREE_TYPE (name));
12310 gimple_set_lhs (SSA_NAME_DEF_STMT (name), *expr_p);
12311 release_ssa_name (name);
12314 return ret;
12317 /* Look through TYPE for variable-sized objects and gimplify each such
12318 size that we find. Add to LIST_P any statements generated. */
12320 void
12321 gimplify_type_sizes (tree type, gimple_seq *list_p)
12323 tree field, t;
12325 if (type == NULL || type == error_mark_node)
12326 return;
12328 /* We first do the main variant, then copy into any other variants. */
12329 type = TYPE_MAIN_VARIANT (type);
12331 /* Avoid infinite recursion. */
12332 if (TYPE_SIZES_GIMPLIFIED (type))
12333 return;
12335 TYPE_SIZES_GIMPLIFIED (type) = 1;
12337 switch (TREE_CODE (type))
12339 case INTEGER_TYPE:
12340 case ENUMERAL_TYPE:
12341 case BOOLEAN_TYPE:
12342 case REAL_TYPE:
12343 case FIXED_POINT_TYPE:
12344 gimplify_one_sizepos (&TYPE_MIN_VALUE (type), list_p);
12345 gimplify_one_sizepos (&TYPE_MAX_VALUE (type), list_p);
12347 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
12349 TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type);
12350 TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type);
12352 break;
12354 case ARRAY_TYPE:
12355 /* These types may not have declarations, so handle them here. */
12356 gimplify_type_sizes (TREE_TYPE (type), list_p);
12357 gimplify_type_sizes (TYPE_DOMAIN (type), list_p);
12358 /* Ensure VLA bounds aren't removed, for -O0 they should be variables
12359 with assigned stack slots, for -O1+ -g they should be tracked
12360 by VTA. */
12361 if (!(TYPE_NAME (type)
12362 && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
12363 && DECL_IGNORED_P (TYPE_NAME (type)))
12364 && TYPE_DOMAIN (type)
12365 && INTEGRAL_TYPE_P (TYPE_DOMAIN (type)))
12367 t = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
12368 if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
12369 DECL_IGNORED_P (t) = 0;
12370 t = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
12371 if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
12372 DECL_IGNORED_P (t) = 0;
12374 break;
12376 case RECORD_TYPE:
12377 case UNION_TYPE:
12378 case QUAL_UNION_TYPE:
12379 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
12380 if (TREE_CODE (field) == FIELD_DECL)
12382 gimplify_one_sizepos (&DECL_FIELD_OFFSET (field), list_p);
12383 gimplify_one_sizepos (&DECL_SIZE (field), list_p);
12384 gimplify_one_sizepos (&DECL_SIZE_UNIT (field), list_p);
12385 gimplify_type_sizes (TREE_TYPE (field), list_p);
12387 break;
12389 case POINTER_TYPE:
12390 case REFERENCE_TYPE:
12391 /* We used to recurse on the pointed-to type here, which turned out to
12392 be incorrect because its definition might refer to variables not
12393 yet initialized at this point if a forward declaration is involved.
12395 It was actually useful for anonymous pointed-to types to ensure
12396 that the sizes evaluation dominates every possible later use of the
12397 values. Restricting to such types here would be safe since there
12398 is no possible forward declaration around, but would introduce an
12399 undesirable middle-end semantic to anonymity. We then defer to
12400 front-ends the responsibility of ensuring that the sizes are
12401 evaluated both early and late enough, e.g. by attaching artificial
12402 type declarations to the tree. */
12403 break;
12405 default:
12406 break;
12409 gimplify_one_sizepos (&TYPE_SIZE (type), list_p);
12410 gimplify_one_sizepos (&TYPE_SIZE_UNIT (type), list_p);
12412 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
12414 TYPE_SIZE (t) = TYPE_SIZE (type);
12415 TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (type);
12416 TYPE_SIZES_GIMPLIFIED (t) = 1;
12420 /* A subroutine of gimplify_type_sizes to make sure that *EXPR_P,
12421 a size or position, has had all of its SAVE_EXPRs evaluated.
12422 We add any required statements to *STMT_P. */
12424 void
12425 gimplify_one_sizepos (tree *expr_p, gimple_seq *stmt_p)
12427 tree expr = *expr_p;
12429 /* We don't do anything if the value isn't there, is constant, or contains
12430 A PLACEHOLDER_EXPR. We also don't want to do anything if it's already
12431 a VAR_DECL. If it's a VAR_DECL from another function, the gimplifier
12432 will want to replace it with a new variable, but that will cause problems
12433 if this type is from outside the function. It's OK to have that here. */
12434 if (is_gimple_sizepos (expr))
12435 return;
12437 *expr_p = unshare_expr (expr);
12439 /* SSA names in decl/type fields are a bad idea - they'll get reclaimed
12440 if the def vanishes. */
12441 gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue, false);
12444 /* Gimplify the body of statements of FNDECL and return a GIMPLE_BIND node
12445 containing the sequence of corresponding GIMPLE statements. If DO_PARMS
12446 is true, also gimplify the parameters. */
12448 gbind *
12449 gimplify_body (tree fndecl, bool do_parms)
12451 location_t saved_location = input_location;
12452 gimple_seq parm_stmts, seq;
12453 gimple *outer_stmt;
12454 gbind *outer_bind;
12455 struct cgraph_node *cgn;
12457 timevar_push (TV_TREE_GIMPLIFY);
12459 init_tree_ssa (cfun);
12461 /* Initialize for optimize_insn_for_s{ize,peed}_p possibly called during
12462 gimplification. */
12463 default_rtl_profile ();
12465 gcc_assert (gimplify_ctxp == NULL);
12466 push_gimplify_context (true);
12468 if (flag_openacc || flag_openmp)
12470 gcc_assert (gimplify_omp_ctxp == NULL);
12471 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (fndecl)))
12472 gimplify_omp_ctxp = new_omp_context (ORT_TARGET);
12475 /* Unshare most shared trees in the body and in that of any nested functions.
12476 It would seem we don't have to do this for nested functions because
12477 they are supposed to be output and then the outer function gimplified
12478 first, but the g++ front end doesn't always do it that way. */
12479 unshare_body (fndecl);
12480 unvisit_body (fndecl);
12482 cgn = cgraph_node::get (fndecl);
12483 if (cgn && cgn->origin)
12484 nonlocal_vlas = new hash_set<tree>;
12486 /* Make sure input_location isn't set to something weird. */
12487 input_location = DECL_SOURCE_LOCATION (fndecl);
12489 /* Resolve callee-copies. This has to be done before processing
12490 the body so that DECL_VALUE_EXPR gets processed correctly. */
12491 parm_stmts = do_parms ? gimplify_parameters () : NULL;
12493 /* Gimplify the function's body. */
12494 seq = NULL;
12495 gimplify_stmt (&DECL_SAVED_TREE (fndecl), &seq);
12496 outer_stmt = gimple_seq_first_stmt (seq);
12497 if (!outer_stmt)
12499 outer_stmt = gimple_build_nop ();
12500 gimplify_seq_add_stmt (&seq, outer_stmt);
12503 /* The body must contain exactly one statement, a GIMPLE_BIND. If this is
12504 not the case, wrap everything in a GIMPLE_BIND to make it so. */
12505 if (gimple_code (outer_stmt) == GIMPLE_BIND
12506 && gimple_seq_first (seq) == gimple_seq_last (seq))
12507 outer_bind = as_a <gbind *> (outer_stmt);
12508 else
12509 outer_bind = gimple_build_bind (NULL_TREE, seq, NULL);
12511 DECL_SAVED_TREE (fndecl) = NULL_TREE;
12513 /* If we had callee-copies statements, insert them at the beginning
12514 of the function and clear DECL_VALUE_EXPR_P on the parameters. */
12515 if (!gimple_seq_empty_p (parm_stmts))
12517 tree parm;
12519 gimplify_seq_add_seq (&parm_stmts, gimple_bind_body (outer_bind));
12520 gimple_bind_set_body (outer_bind, parm_stmts);
12522 for (parm = DECL_ARGUMENTS (current_function_decl);
12523 parm; parm = DECL_CHAIN (parm))
12524 if (DECL_HAS_VALUE_EXPR_P (parm))
12526 DECL_HAS_VALUE_EXPR_P (parm) = 0;
12527 DECL_IGNORED_P (parm) = 0;
12531 if (nonlocal_vlas)
12533 if (nonlocal_vla_vars)
12535 /* tree-nested.c may later on call declare_vars (..., true);
12536 which relies on BLOCK_VARS chain to be the tail of the
12537 gimple_bind_vars chain. Ensure we don't violate that
12538 assumption. */
12539 if (gimple_bind_block (outer_bind)
12540 == DECL_INITIAL (current_function_decl))
12541 declare_vars (nonlocal_vla_vars, outer_bind, true);
12542 else
12543 BLOCK_VARS (DECL_INITIAL (current_function_decl))
12544 = chainon (BLOCK_VARS (DECL_INITIAL (current_function_decl)),
12545 nonlocal_vla_vars);
12546 nonlocal_vla_vars = NULL_TREE;
12548 delete nonlocal_vlas;
12549 nonlocal_vlas = NULL;
12552 if ((flag_openacc || flag_openmp || flag_openmp_simd)
12553 && gimplify_omp_ctxp)
12555 delete_omp_context (gimplify_omp_ctxp);
12556 gimplify_omp_ctxp = NULL;
12559 pop_gimplify_context (outer_bind);
12560 gcc_assert (gimplify_ctxp == NULL);
12562 if (flag_checking && !seen_error ())
12563 verify_gimple_in_seq (gimple_bind_body (outer_bind));
12565 timevar_pop (TV_TREE_GIMPLIFY);
12566 input_location = saved_location;
12568 return outer_bind;
12571 typedef char *char_p; /* For DEF_VEC_P. */
12573 /* Return whether we should exclude FNDECL from instrumentation. */
12575 static bool
12576 flag_instrument_functions_exclude_p (tree fndecl)
12578 vec<char_p> *v;
12580 v = (vec<char_p> *) flag_instrument_functions_exclude_functions;
12581 if (v && v->length () > 0)
12583 const char *name;
12584 int i;
12585 char *s;
12587 name = lang_hooks.decl_printable_name (fndecl, 0);
12588 FOR_EACH_VEC_ELT (*v, i, s)
12589 if (strstr (name, s) != NULL)
12590 return true;
12593 v = (vec<char_p> *) flag_instrument_functions_exclude_files;
12594 if (v && v->length () > 0)
12596 const char *name;
12597 int i;
12598 char *s;
12600 name = DECL_SOURCE_FILE (fndecl);
12601 FOR_EACH_VEC_ELT (*v, i, s)
12602 if (strstr (name, s) != NULL)
12603 return true;
12606 return false;
12609 /* Entry point to the gimplification pass. FNDECL is the FUNCTION_DECL
12610 node for the function we want to gimplify.
12612 Return the sequence of GIMPLE statements corresponding to the body
12613 of FNDECL. */
12615 void
12616 gimplify_function_tree (tree fndecl)
12618 tree parm, ret;
12619 gimple_seq seq;
12620 gbind *bind;
12622 gcc_assert (!gimple_body (fndecl));
12624 if (DECL_STRUCT_FUNCTION (fndecl))
12625 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
12626 else
12627 push_struct_function (fndecl);
12629 /* Tentatively set PROP_gimple_lva here, and reset it in gimplify_va_arg_expr
12630 if necessary. */
12631 cfun->curr_properties |= PROP_gimple_lva;
12633 for (parm = DECL_ARGUMENTS (fndecl); parm ; parm = DECL_CHAIN (parm))
12635 /* Preliminarily mark non-addressed complex variables as eligible
12636 for promotion to gimple registers. We'll transform their uses
12637 as we find them. */
12638 if ((TREE_CODE (TREE_TYPE (parm)) == COMPLEX_TYPE
12639 || TREE_CODE (TREE_TYPE (parm)) == VECTOR_TYPE)
12640 && !TREE_THIS_VOLATILE (parm)
12641 && !needs_to_live_in_memory (parm))
12642 DECL_GIMPLE_REG_P (parm) = 1;
12645 ret = DECL_RESULT (fndecl);
12646 if ((TREE_CODE (TREE_TYPE (ret)) == COMPLEX_TYPE
12647 || TREE_CODE (TREE_TYPE (ret)) == VECTOR_TYPE)
12648 && !needs_to_live_in_memory (ret))
12649 DECL_GIMPLE_REG_P (ret) = 1;
12651 if (asan_sanitize_use_after_scope () && sanitize_flags_p (SANITIZE_ADDRESS))
12652 asan_poisoned_variables = new hash_set<tree> ();
12653 bind = gimplify_body (fndecl, true);
12654 if (asan_poisoned_variables)
12656 delete asan_poisoned_variables;
12657 asan_poisoned_variables = NULL;
12660 /* The tree body of the function is no longer needed, replace it
12661 with the new GIMPLE body. */
12662 seq = NULL;
12663 gimple_seq_add_stmt (&seq, bind);
12664 gimple_set_body (fndecl, seq);
12666 /* If we're instrumenting function entry/exit, then prepend the call to
12667 the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to
12668 catch the exit hook. */
12669 /* ??? Add some way to ignore exceptions for this TFE. */
12670 if (flag_instrument_function_entry_exit
12671 && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl)
12672 /* Do not instrument extern inline functions. */
12673 && !(DECL_DECLARED_INLINE_P (fndecl)
12674 && DECL_EXTERNAL (fndecl)
12675 && DECL_DISREGARD_INLINE_LIMITS (fndecl))
12676 && !flag_instrument_functions_exclude_p (fndecl))
12678 tree x;
12679 gbind *new_bind;
12680 gimple *tf;
12681 gimple_seq cleanup = NULL, body = NULL;
12682 tree tmp_var;
12683 gcall *call;
12685 x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
12686 call = gimple_build_call (x, 1, integer_zero_node);
12687 tmp_var = create_tmp_var (ptr_type_node, "return_addr");
12688 gimple_call_set_lhs (call, tmp_var);
12689 gimplify_seq_add_stmt (&cleanup, call);
12690 x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_EXIT);
12691 call = gimple_build_call (x, 2,
12692 build_fold_addr_expr (current_function_decl),
12693 tmp_var);
12694 gimplify_seq_add_stmt (&cleanup, call);
12695 tf = gimple_build_try (seq, cleanup, GIMPLE_TRY_FINALLY);
12697 x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
12698 call = gimple_build_call (x, 1, integer_zero_node);
12699 tmp_var = create_tmp_var (ptr_type_node, "return_addr");
12700 gimple_call_set_lhs (call, tmp_var);
12701 gimplify_seq_add_stmt (&body, call);
12702 x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_ENTER);
12703 call = gimple_build_call (x, 2,
12704 build_fold_addr_expr (current_function_decl),
12705 tmp_var);
12706 gimplify_seq_add_stmt (&body, call);
12707 gimplify_seq_add_stmt (&body, tf);
12708 new_bind = gimple_build_bind (NULL, body, NULL);
12710 /* Replace the current function body with the body
12711 wrapped in the try/finally TF. */
12712 seq = NULL;
12713 gimple_seq_add_stmt (&seq, new_bind);
12714 gimple_set_body (fndecl, seq);
12715 bind = new_bind;
12718 if (sanitize_flags_p (SANITIZE_THREAD))
12720 gcall *call = gimple_build_call_internal (IFN_TSAN_FUNC_EXIT, 0);
12721 gimple *tf = gimple_build_try (seq, call, GIMPLE_TRY_FINALLY);
12722 gbind *new_bind = gimple_build_bind (NULL, tf, NULL);
12723 /* Replace the current function body with the body
12724 wrapped in the try/finally TF. */
12725 seq = NULL;
12726 gimple_seq_add_stmt (&seq, new_bind);
12727 gimple_set_body (fndecl, seq);
12730 DECL_SAVED_TREE (fndecl) = NULL_TREE;
12731 cfun->curr_properties |= PROP_gimple_any;
12733 pop_cfun ();
12735 dump_function (TDI_gimple, fndecl);
12738 /* Return a dummy expression of type TYPE in order to keep going after an
12739 error. */
12741 static tree
12742 dummy_object (tree type)
12744 tree t = build_int_cst (build_pointer_type (type), 0);
12745 return build2 (MEM_REF, type, t, t);
12748 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
12749 builtin function, but a very special sort of operator. */
12751 enum gimplify_status
12752 gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p,
12753 gimple_seq *post_p ATTRIBUTE_UNUSED)
12755 tree promoted_type, have_va_type;
12756 tree valist = TREE_OPERAND (*expr_p, 0);
12757 tree type = TREE_TYPE (*expr_p);
12758 tree t, tag, aptag;
12759 location_t loc = EXPR_LOCATION (*expr_p);
12761 /* Verify that valist is of the proper type. */
12762 have_va_type = TREE_TYPE (valist);
12763 if (have_va_type == error_mark_node)
12764 return GS_ERROR;
12765 have_va_type = targetm.canonical_va_list_type (have_va_type);
12766 if (have_va_type == NULL_TREE
12767 && POINTER_TYPE_P (TREE_TYPE (valist)))
12768 /* Handle 'Case 1: Not an array type' from c-common.c/build_va_arg. */
12769 have_va_type
12770 = targetm.canonical_va_list_type (TREE_TYPE (TREE_TYPE (valist)));
12771 gcc_assert (have_va_type != NULL_TREE);
12773 /* Generate a diagnostic for requesting data of a type that cannot
12774 be passed through `...' due to type promotion at the call site. */
12775 if ((promoted_type = lang_hooks.types.type_promotes_to (type))
12776 != type)
12778 static bool gave_help;
12779 bool warned;
12780 /* Use the expansion point to handle cases such as passing bool (defined
12781 in a system header) through `...'. */
12782 source_location xloc
12783 = expansion_point_location_if_in_system_header (loc);
12785 /* Unfortunately, this is merely undefined, rather than a constraint
12786 violation, so we cannot make this an error. If this call is never
12787 executed, the program is still strictly conforming. */
12788 warned = warning_at (xloc, 0,
12789 "%qT is promoted to %qT when passed through %<...%>",
12790 type, promoted_type);
12791 if (!gave_help && warned)
12793 gave_help = true;
12794 inform (xloc, "(so you should pass %qT not %qT to %<va_arg%>)",
12795 promoted_type, type);
12798 /* We can, however, treat "undefined" any way we please.
12799 Call abort to encourage the user to fix the program. */
12800 if (warned)
12801 inform (xloc, "if this code is reached, the program will abort");
12802 /* Before the abort, allow the evaluation of the va_list
12803 expression to exit or longjmp. */
12804 gimplify_and_add (valist, pre_p);
12805 t = build_call_expr_loc (loc,
12806 builtin_decl_implicit (BUILT_IN_TRAP), 0);
12807 gimplify_and_add (t, pre_p);
12809 /* This is dead code, but go ahead and finish so that the
12810 mode of the result comes out right. */
12811 *expr_p = dummy_object (type);
12812 return GS_ALL_DONE;
12815 tag = build_int_cst (build_pointer_type (type), 0);
12816 aptag = build_int_cst (TREE_TYPE (valist), 0);
12818 *expr_p = build_call_expr_internal_loc (loc, IFN_VA_ARG, type, 3,
12819 valist, tag, aptag);
12821 /* Clear the tentatively set PROP_gimple_lva, to indicate that IFN_VA_ARG
12822 needs to be expanded. */
12823 cfun->curr_properties &= ~PROP_gimple_lva;
12825 return GS_OK;
12828 /* Build a new GIMPLE_ASSIGN tuple and append it to the end of *SEQ_P.
12830 DST/SRC are the destination and source respectively. You can pass
12831 ungimplified trees in DST or SRC, in which case they will be
12832 converted to a gimple operand if necessary.
12834 This function returns the newly created GIMPLE_ASSIGN tuple. */
12836 gimple *
12837 gimplify_assign (tree dst, tree src, gimple_seq *seq_p)
12839 tree t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
12840 gimplify_and_add (t, seq_p);
12841 ggc_free (t);
12842 return gimple_seq_last_stmt (*seq_p);
12845 inline hashval_t
12846 gimplify_hasher::hash (const elt_t *p)
12848 tree t = p->val;
12849 return iterative_hash_expr (t, 0);
12852 inline bool
12853 gimplify_hasher::equal (const elt_t *p1, const elt_t *p2)
12855 tree t1 = p1->val;
12856 tree t2 = p2->val;
12857 enum tree_code code = TREE_CODE (t1);
12859 if (TREE_CODE (t2) != code
12860 || TREE_TYPE (t1) != TREE_TYPE (t2))
12861 return false;
12863 if (!operand_equal_p (t1, t2, 0))
12864 return false;
12866 /* Only allow them to compare equal if they also hash equal; otherwise
12867 results are nondeterminate, and we fail bootstrap comparison. */
12868 gcc_checking_assert (hash (p1) == hash (p2));
12870 return true;