PR c++/80129
[official-gcc.git] / gcc / gimplify.c
blobf90ae94bc6960b25e0018bc2bb68a3a5a06adfcb
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 "tree-dump.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 GOVD_DATA_SHARE_CLASS = (GOVD_SHARED | GOVD_PRIVATE | GOVD_FIRSTPRIVATE
103 | GOVD_LASTPRIVATE | GOVD_REDUCTION | GOVD_LINEAR
104 | GOVD_LOCAL)
108 enum omp_region_type
110 ORT_WORKSHARE = 0x00,
111 ORT_SIMD = 0x01,
113 ORT_PARALLEL = 0x02,
114 ORT_COMBINED_PARALLEL = 0x03,
116 ORT_TASK = 0x04,
117 ORT_UNTIED_TASK = 0x05,
119 ORT_TEAMS = 0x08,
120 ORT_COMBINED_TEAMS = 0x09,
122 /* Data region. */
123 ORT_TARGET_DATA = 0x10,
125 /* Data region with offloading. */
126 ORT_TARGET = 0x20,
127 ORT_COMBINED_TARGET = 0x21,
129 /* OpenACC variants. */
130 ORT_ACC = 0x40, /* A generic OpenACC region. */
131 ORT_ACC_DATA = ORT_ACC | ORT_TARGET_DATA, /* Data construct. */
132 ORT_ACC_PARALLEL = ORT_ACC | ORT_TARGET, /* Parallel construct */
133 ORT_ACC_KERNELS = ORT_ACC | ORT_TARGET | 0x80, /* Kernels construct. */
134 ORT_ACC_HOST_DATA = ORT_ACC | ORT_TARGET_DATA | 0x80, /* Host data. */
136 /* Dummy OpenMP region, used to disable expansion of
137 DECL_VALUE_EXPRs in taskloop pre body. */
138 ORT_NONE = 0x100
141 /* Gimplify hashtable helper. */
143 struct gimplify_hasher : free_ptr_hash <elt_t>
145 static inline hashval_t hash (const elt_t *);
146 static inline bool equal (const elt_t *, const elt_t *);
149 struct gimplify_ctx
151 struct gimplify_ctx *prev_context;
153 vec<gbind *> bind_expr_stack;
154 tree temps;
155 gimple_seq conditional_cleanups;
156 tree exit_label;
157 tree return_temp;
159 vec<tree> case_labels;
160 hash_set<tree> *live_switch_vars;
161 /* The formal temporary table. Should this be persistent? */
162 hash_table<gimplify_hasher> *temp_htab;
164 int conditions;
165 unsigned into_ssa : 1;
166 unsigned allow_rhs_cond_expr : 1;
167 unsigned in_cleanup_point_expr : 1;
168 unsigned keep_stack : 1;
169 unsigned save_stack : 1;
170 unsigned in_switch_expr : 1;
173 struct gimplify_omp_ctx
175 struct gimplify_omp_ctx *outer_context;
176 splay_tree variables;
177 hash_set<tree> *privatized_types;
178 /* Iteration variables in an OMP_FOR. */
179 vec<tree> loop_iter_var;
180 location_t location;
181 enum omp_clause_default_kind default_kind;
182 enum omp_region_type region_type;
183 bool combined_loop;
184 bool distribute;
185 bool target_map_scalars_firstprivate;
186 bool target_map_pointers_as_0len_arrays;
187 bool target_firstprivatize_array_bases;
190 static struct gimplify_ctx *gimplify_ctxp;
191 static struct gimplify_omp_ctx *gimplify_omp_ctxp;
193 /* Forward declaration. */
194 static enum gimplify_status gimplify_compound_expr (tree *, gimple_seq *, bool);
195 static hash_map<tree, tree> *oacc_declare_returns;
196 static enum gimplify_status gimplify_expr (tree *, gimple_seq *, gimple_seq *,
197 bool (*) (tree), fallback_t, bool);
199 /* Shorter alias name for the above function for use in gimplify.c
200 only. */
202 static inline void
203 gimplify_seq_add_stmt (gimple_seq *seq_p, gimple *gs)
205 gimple_seq_add_stmt_without_update (seq_p, gs);
208 /* Append sequence SRC to the end of sequence *DST_P. If *DST_P is
209 NULL, a new sequence is allocated. This function is
210 similar to gimple_seq_add_seq, but does not scan the operands.
211 During gimplification, we need to manipulate statement sequences
212 before the def/use vectors have been constructed. */
214 static void
215 gimplify_seq_add_seq (gimple_seq *dst_p, gimple_seq src)
217 gimple_stmt_iterator si;
219 if (src == NULL)
220 return;
222 si = gsi_last (*dst_p);
223 gsi_insert_seq_after_without_update (&si, src, GSI_NEW_STMT);
227 /* Pointer to a list of allocated gimplify_ctx structs to be used for pushing
228 and popping gimplify contexts. */
230 static struct gimplify_ctx *ctx_pool = NULL;
232 /* Return a gimplify context struct from the pool. */
234 static inline struct gimplify_ctx *
235 ctx_alloc (void)
237 struct gimplify_ctx * c = ctx_pool;
239 if (c)
240 ctx_pool = c->prev_context;
241 else
242 c = XNEW (struct gimplify_ctx);
244 memset (c, '\0', sizeof (*c));
245 return c;
248 /* Put gimplify context C back into the pool. */
250 static inline void
251 ctx_free (struct gimplify_ctx *c)
253 c->prev_context = ctx_pool;
254 ctx_pool = c;
257 /* Free allocated ctx stack memory. */
259 void
260 free_gimplify_stack (void)
262 struct gimplify_ctx *c;
264 while ((c = ctx_pool))
266 ctx_pool = c->prev_context;
267 free (c);
272 /* Set up a context for the gimplifier. */
274 void
275 push_gimplify_context (bool in_ssa, bool rhs_cond_ok)
277 struct gimplify_ctx *c = ctx_alloc ();
279 c->prev_context = gimplify_ctxp;
280 gimplify_ctxp = c;
281 gimplify_ctxp->into_ssa = in_ssa;
282 gimplify_ctxp->allow_rhs_cond_expr = rhs_cond_ok;
285 /* Tear down a context for the gimplifier. If BODY is non-null, then
286 put the temporaries into the outer BIND_EXPR. Otherwise, put them
287 in the local_decls.
289 BODY is not a sequence, but the first tuple in a sequence. */
291 void
292 pop_gimplify_context (gimple *body)
294 struct gimplify_ctx *c = gimplify_ctxp;
296 gcc_assert (c
297 && (!c->bind_expr_stack.exists ()
298 || c->bind_expr_stack.is_empty ()));
299 c->bind_expr_stack.release ();
300 gimplify_ctxp = c->prev_context;
302 if (body)
303 declare_vars (c->temps, body, false);
304 else
305 record_vars (c->temps);
307 delete c->temp_htab;
308 c->temp_htab = NULL;
309 ctx_free (c);
312 /* Push a GIMPLE_BIND tuple onto the stack of bindings. */
314 static void
315 gimple_push_bind_expr (gbind *bind_stmt)
317 gimplify_ctxp->bind_expr_stack.reserve (8);
318 gimplify_ctxp->bind_expr_stack.safe_push (bind_stmt);
321 /* Pop the first element off the stack of bindings. */
323 static void
324 gimple_pop_bind_expr (void)
326 gimplify_ctxp->bind_expr_stack.pop ();
329 /* Return the first element of the stack of bindings. */
331 gbind *
332 gimple_current_bind_expr (void)
334 return gimplify_ctxp->bind_expr_stack.last ();
337 /* Return the stack of bindings created during gimplification. */
339 vec<gbind *>
340 gimple_bind_expr_stack (void)
342 return gimplify_ctxp->bind_expr_stack;
345 /* Return true iff there is a COND_EXPR between us and the innermost
346 CLEANUP_POINT_EXPR. This info is used by gimple_push_cleanup. */
348 static bool
349 gimple_conditional_context (void)
351 return gimplify_ctxp->conditions > 0;
354 /* Note that we've entered a COND_EXPR. */
356 static void
357 gimple_push_condition (void)
359 #ifdef ENABLE_GIMPLE_CHECKING
360 if (gimplify_ctxp->conditions == 0)
361 gcc_assert (gimple_seq_empty_p (gimplify_ctxp->conditional_cleanups));
362 #endif
363 ++(gimplify_ctxp->conditions);
366 /* Note that we've left a COND_EXPR. If we're back at unconditional scope
367 now, add any conditional cleanups we've seen to the prequeue. */
369 static void
370 gimple_pop_condition (gimple_seq *pre_p)
372 int conds = --(gimplify_ctxp->conditions);
374 gcc_assert (conds >= 0);
375 if (conds == 0)
377 gimplify_seq_add_seq (pre_p, gimplify_ctxp->conditional_cleanups);
378 gimplify_ctxp->conditional_cleanups = NULL;
382 /* A stable comparison routine for use with splay trees and DECLs. */
384 static int
385 splay_tree_compare_decl_uid (splay_tree_key xa, splay_tree_key xb)
387 tree a = (tree) xa;
388 tree b = (tree) xb;
390 return DECL_UID (a) - DECL_UID (b);
393 /* Create a new omp construct that deals with variable remapping. */
395 static struct gimplify_omp_ctx *
396 new_omp_context (enum omp_region_type region_type)
398 struct gimplify_omp_ctx *c;
400 c = XCNEW (struct gimplify_omp_ctx);
401 c->outer_context = gimplify_omp_ctxp;
402 c->variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0);
403 c->privatized_types = new hash_set<tree>;
404 c->location = input_location;
405 c->region_type = region_type;
406 if ((region_type & ORT_TASK) == 0)
407 c->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
408 else
409 c->default_kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
411 return c;
414 /* Destroy an omp construct that deals with variable remapping. */
416 static void
417 delete_omp_context (struct gimplify_omp_ctx *c)
419 splay_tree_delete (c->variables);
420 delete c->privatized_types;
421 c->loop_iter_var.release ();
422 XDELETE (c);
425 static void omp_add_variable (struct gimplify_omp_ctx *, tree, unsigned int);
426 static bool omp_notice_variable (struct gimplify_omp_ctx *, tree, bool);
428 /* Both gimplify the statement T and append it to *SEQ_P. This function
429 behaves exactly as gimplify_stmt, but you don't have to pass T as a
430 reference. */
432 void
433 gimplify_and_add (tree t, gimple_seq *seq_p)
435 gimplify_stmt (&t, seq_p);
438 /* Gimplify statement T into sequence *SEQ_P, and return the first
439 tuple in the sequence of generated tuples for this statement.
440 Return NULL if gimplifying T produced no tuples. */
442 static gimple *
443 gimplify_and_return_first (tree t, gimple_seq *seq_p)
445 gimple_stmt_iterator last = gsi_last (*seq_p);
447 gimplify_and_add (t, seq_p);
449 if (!gsi_end_p (last))
451 gsi_next (&last);
452 return gsi_stmt (last);
454 else
455 return gimple_seq_first_stmt (*seq_p);
458 /* Returns true iff T is a valid RHS for an assignment to an un-renamed
459 LHS, or for a call argument. */
461 static bool
462 is_gimple_mem_rhs (tree t)
464 /* If we're dealing with a renamable type, either source or dest must be
465 a renamed variable. */
466 if (is_gimple_reg_type (TREE_TYPE (t)))
467 return is_gimple_val (t);
468 else
469 return is_gimple_val (t) || is_gimple_lvalue (t);
472 /* Return true if T is a CALL_EXPR or an expression that can be
473 assigned to a temporary. Note that this predicate should only be
474 used during gimplification. See the rationale for this in
475 gimplify_modify_expr. */
477 static bool
478 is_gimple_reg_rhs_or_call (tree t)
480 return (get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS
481 || TREE_CODE (t) == CALL_EXPR);
484 /* Return true if T is a valid memory RHS or a CALL_EXPR. Note that
485 this predicate should only be used during gimplification. See the
486 rationale for this in gimplify_modify_expr. */
488 static bool
489 is_gimple_mem_rhs_or_call (tree t)
491 /* If we're dealing with a renamable type, either source or dest must be
492 a renamed variable. */
493 if (is_gimple_reg_type (TREE_TYPE (t)))
494 return is_gimple_val (t);
495 else
496 return (is_gimple_val (t) || is_gimple_lvalue (t)
497 || TREE_CODE (t) == CALL_EXPR);
500 /* Create a temporary with a name derived from VAL. Subroutine of
501 lookup_tmp_var; nobody else should call this function. */
503 static inline tree
504 create_tmp_from_val (tree val)
506 /* Drop all qualifiers and address-space information from the value type. */
507 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (val));
508 tree var = create_tmp_var (type, get_name (val));
509 if (TREE_CODE (TREE_TYPE (var)) == COMPLEX_TYPE
510 || TREE_CODE (TREE_TYPE (var)) == VECTOR_TYPE)
511 DECL_GIMPLE_REG_P (var) = 1;
512 return var;
515 /* Create a temporary to hold the value of VAL. If IS_FORMAL, try to reuse
516 an existing expression temporary. */
518 static tree
519 lookup_tmp_var (tree val, bool is_formal)
521 tree ret;
523 /* If not optimizing, never really reuse a temporary. local-alloc
524 won't allocate any variable that is used in more than one basic
525 block, which means it will go into memory, causing much extra
526 work in reload and final and poorer code generation, outweighing
527 the extra memory allocation here. */
528 if (!optimize || !is_formal || TREE_SIDE_EFFECTS (val))
529 ret = create_tmp_from_val (val);
530 else
532 elt_t elt, *elt_p;
533 elt_t **slot;
535 elt.val = val;
536 if (!gimplify_ctxp->temp_htab)
537 gimplify_ctxp->temp_htab = new hash_table<gimplify_hasher> (1000);
538 slot = gimplify_ctxp->temp_htab->find_slot (&elt, INSERT);
539 if (*slot == NULL)
541 elt_p = XNEW (elt_t);
542 elt_p->val = val;
543 elt_p->temp = ret = create_tmp_from_val (val);
544 *slot = elt_p;
546 else
548 elt_p = *slot;
549 ret = elt_p->temp;
553 return ret;
556 /* Helper for get_formal_tmp_var and get_initialized_tmp_var. */
558 static tree
559 internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
560 bool is_formal, bool allow_ssa)
562 tree t, mod;
564 /* Notice that we explicitly allow VAL to be a CALL_EXPR so that we
565 can create an INIT_EXPR and convert it into a GIMPLE_CALL below. */
566 gimplify_expr (&val, pre_p, post_p, is_gimple_reg_rhs_or_call,
567 fb_rvalue);
569 if (allow_ssa
570 && gimplify_ctxp->into_ssa
571 && is_gimple_reg_type (TREE_TYPE (val)))
573 t = make_ssa_name (TYPE_MAIN_VARIANT (TREE_TYPE (val)));
574 if (! gimple_in_ssa_p (cfun))
576 const char *name = get_name (val);
577 if (name)
578 SET_SSA_NAME_VAR_OR_IDENTIFIER (t, create_tmp_var_name (name));
581 else
582 t = lookup_tmp_var (val, is_formal);
584 mod = build2 (INIT_EXPR, TREE_TYPE (t), t, unshare_expr (val));
586 SET_EXPR_LOCATION (mod, EXPR_LOC_OR_LOC (val, input_location));
588 /* gimplify_modify_expr might want to reduce this further. */
589 gimplify_and_add (mod, pre_p);
590 ggc_free (mod);
592 return t;
595 /* Return a formal temporary variable initialized with VAL. PRE_P is as
596 in gimplify_expr. Only use this function if:
598 1) The value of the unfactored expression represented by VAL will not
599 change between the initialization and use of the temporary, and
600 2) The temporary will not be otherwise modified.
602 For instance, #1 means that this is inappropriate for SAVE_EXPR temps,
603 and #2 means it is inappropriate for && temps.
605 For other cases, use get_initialized_tmp_var instead. */
607 tree
608 get_formal_tmp_var (tree val, gimple_seq *pre_p)
610 return internal_get_tmp_var (val, pre_p, NULL, true, true);
613 /* Return a temporary variable initialized with VAL. PRE_P and POST_P
614 are as in gimplify_expr. */
616 tree
617 get_initialized_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
618 bool allow_ssa)
620 return internal_get_tmp_var (val, pre_p, post_p, false, allow_ssa);
623 /* Declare all the variables in VARS in SCOPE. If DEBUG_INFO is true,
624 generate debug info for them; otherwise don't. */
626 void
627 declare_vars (tree vars, gimple *gs, bool debug_info)
629 tree last = vars;
630 if (last)
632 tree temps, block;
634 gbind *scope = as_a <gbind *> (gs);
636 temps = nreverse (last);
638 block = gimple_bind_block (scope);
639 gcc_assert (!block || TREE_CODE (block) == BLOCK);
640 if (!block || !debug_info)
642 DECL_CHAIN (last) = gimple_bind_vars (scope);
643 gimple_bind_set_vars (scope, temps);
645 else
647 /* We need to attach the nodes both to the BIND_EXPR and to its
648 associated BLOCK for debugging purposes. The key point here
649 is that the BLOCK_VARS of the BIND_EXPR_BLOCK of a BIND_EXPR
650 is a subchain of the BIND_EXPR_VARS of the BIND_EXPR. */
651 if (BLOCK_VARS (block))
652 BLOCK_VARS (block) = chainon (BLOCK_VARS (block), temps);
653 else
655 gimple_bind_set_vars (scope,
656 chainon (gimple_bind_vars (scope), temps));
657 BLOCK_VARS (block) = temps;
663 /* For VAR a VAR_DECL of variable size, try to find a constant upper bound
664 for the size and adjust DECL_SIZE/DECL_SIZE_UNIT accordingly. Abort if
665 no such upper bound can be obtained. */
667 static void
668 force_constant_size (tree var)
670 /* The only attempt we make is by querying the maximum size of objects
671 of the variable's type. */
673 HOST_WIDE_INT max_size;
675 gcc_assert (VAR_P (var));
677 max_size = max_int_size_in_bytes (TREE_TYPE (var));
679 gcc_assert (max_size >= 0);
681 DECL_SIZE_UNIT (var)
682 = build_int_cst (TREE_TYPE (DECL_SIZE_UNIT (var)), max_size);
683 DECL_SIZE (var)
684 = build_int_cst (TREE_TYPE (DECL_SIZE (var)), max_size * BITS_PER_UNIT);
687 /* Push the temporary variable TMP into the current binding. */
689 void
690 gimple_add_tmp_var_fn (struct function *fn, tree tmp)
692 gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
694 /* Later processing assumes that the object size is constant, which might
695 not be true at this point. Force the use of a constant upper bound in
696 this case. */
697 if (!tree_fits_uhwi_p (DECL_SIZE_UNIT (tmp)))
698 force_constant_size (tmp);
700 DECL_CONTEXT (tmp) = fn->decl;
701 DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
703 record_vars_into (tmp, fn->decl);
706 /* Push the temporary variable TMP into the current binding. */
708 void
709 gimple_add_tmp_var (tree tmp)
711 gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
713 /* Later processing assumes that the object size is constant, which might
714 not be true at this point. Force the use of a constant upper bound in
715 this case. */
716 if (!tree_fits_uhwi_p (DECL_SIZE_UNIT (tmp)))
717 force_constant_size (tmp);
719 DECL_CONTEXT (tmp) = current_function_decl;
720 DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
722 if (gimplify_ctxp)
724 DECL_CHAIN (tmp) = gimplify_ctxp->temps;
725 gimplify_ctxp->temps = tmp;
727 /* Mark temporaries local within the nearest enclosing parallel. */
728 if (gimplify_omp_ctxp)
730 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
731 while (ctx
732 && (ctx->region_type == ORT_WORKSHARE
733 || ctx->region_type == ORT_SIMD
734 || ctx->region_type == ORT_ACC))
735 ctx = ctx->outer_context;
736 if (ctx)
737 omp_add_variable (ctx, tmp, GOVD_LOCAL | GOVD_SEEN);
740 else if (cfun)
741 record_vars (tmp);
742 else
744 gimple_seq body_seq;
746 /* This case is for nested functions. We need to expose the locals
747 they create. */
748 body_seq = gimple_body (current_function_decl);
749 declare_vars (tmp, gimple_seq_first_stmt (body_seq), false);
755 /* This page contains routines to unshare tree nodes, i.e. to duplicate tree
756 nodes that are referenced more than once in GENERIC functions. This is
757 necessary because gimplification (translation into GIMPLE) is performed
758 by modifying tree nodes in-place, so gimplication of a shared node in a
759 first context could generate an invalid GIMPLE form in a second context.
761 This is achieved with a simple mark/copy/unmark algorithm that walks the
762 GENERIC representation top-down, marks nodes with TREE_VISITED the first
763 time it encounters them, duplicates them if they already have TREE_VISITED
764 set, and finally removes the TREE_VISITED marks it has set.
766 The algorithm works only at the function level, i.e. it generates a GENERIC
767 representation of a function with no nodes shared within the function when
768 passed a GENERIC function (except for nodes that are allowed to be shared).
770 At the global level, it is also necessary to unshare tree nodes that are
771 referenced in more than one function, for the same aforementioned reason.
772 This requires some cooperation from the front-end. There are 2 strategies:
774 1. Manual unsharing. The front-end needs to call unshare_expr on every
775 expression that might end up being shared across functions.
777 2. Deep unsharing. This is an extension of regular unsharing. Instead
778 of calling unshare_expr on expressions that might be shared across
779 functions, the front-end pre-marks them with TREE_VISITED. This will
780 ensure that they are unshared on the first reference within functions
781 when the regular unsharing algorithm runs. The counterpart is that
782 this algorithm must look deeper than for manual unsharing, which is
783 specified by LANG_HOOKS_DEEP_UNSHARING.
785 If there are only few specific cases of node sharing across functions, it is
786 probably easier for a front-end to unshare the expressions manually. On the
787 contrary, if the expressions generated at the global level are as widespread
788 as expressions generated within functions, deep unsharing is very likely the
789 way to go. */
791 /* Similar to copy_tree_r but do not copy SAVE_EXPR or TARGET_EXPR nodes.
792 These nodes model computations that must be done once. If we were to
793 unshare something like SAVE_EXPR(i++), the gimplification process would
794 create wrong code. However, if DATA is non-null, it must hold a pointer
795 set that is used to unshare the subtrees of these nodes. */
797 static tree
798 mostly_copy_tree_r (tree *tp, int *walk_subtrees, void *data)
800 tree t = *tp;
801 enum tree_code code = TREE_CODE (t);
803 /* Do not copy SAVE_EXPR, TARGET_EXPR or BIND_EXPR nodes themselves, but
804 copy their subtrees if we can make sure to do it only once. */
805 if (code == SAVE_EXPR || code == TARGET_EXPR || code == BIND_EXPR)
807 if (data && !((hash_set<tree> *)data)->add (t))
809 else
810 *walk_subtrees = 0;
813 /* Stop at types, decls, constants like copy_tree_r. */
814 else if (TREE_CODE_CLASS (code) == tcc_type
815 || TREE_CODE_CLASS (code) == tcc_declaration
816 || TREE_CODE_CLASS (code) == tcc_constant
817 /* We can't do anything sensible with a BLOCK used as an
818 expression, but we also can't just die when we see it
819 because of non-expression uses. So we avert our eyes
820 and cross our fingers. Silly Java. */
821 || code == BLOCK)
822 *walk_subtrees = 0;
824 /* Cope with the statement expression extension. */
825 else if (code == STATEMENT_LIST)
828 /* Leave the bulk of the work to copy_tree_r itself. */
829 else
830 copy_tree_r (tp, walk_subtrees, NULL);
832 return NULL_TREE;
835 /* Callback for walk_tree to unshare most of the shared trees rooted at *TP.
836 If *TP has been visited already, then *TP is deeply copied by calling
837 mostly_copy_tree_r. DATA is passed to mostly_copy_tree_r unmodified. */
839 static tree
840 copy_if_shared_r (tree *tp, int *walk_subtrees, void *data)
842 tree t = *tp;
843 enum tree_code code = TREE_CODE (t);
845 /* Skip types, decls, and constants. But we do want to look at their
846 types and the bounds of types. Mark them as visited so we properly
847 unmark their subtrees on the unmark pass. If we've already seen them,
848 don't look down further. */
849 if (TREE_CODE_CLASS (code) == tcc_type
850 || TREE_CODE_CLASS (code) == tcc_declaration
851 || TREE_CODE_CLASS (code) == tcc_constant)
853 if (TREE_VISITED (t))
854 *walk_subtrees = 0;
855 else
856 TREE_VISITED (t) = 1;
859 /* If this node has been visited already, unshare it and don't look
860 any deeper. */
861 else if (TREE_VISITED (t))
863 walk_tree (tp, mostly_copy_tree_r, data, NULL);
864 *walk_subtrees = 0;
867 /* Otherwise, mark the node as visited and keep looking. */
868 else
869 TREE_VISITED (t) = 1;
871 return NULL_TREE;
874 /* Unshare most of the shared trees rooted at *TP. DATA is passed to the
875 copy_if_shared_r callback unmodified. */
877 static inline void
878 copy_if_shared (tree *tp, void *data)
880 walk_tree (tp, copy_if_shared_r, data, NULL);
883 /* Unshare all the trees in the body of FNDECL, as well as in the bodies of
884 any nested functions. */
886 static void
887 unshare_body (tree fndecl)
889 struct cgraph_node *cgn = cgraph_node::get (fndecl);
890 /* If the language requires deep unsharing, we need a pointer set to make
891 sure we don't repeatedly unshare subtrees of unshareable nodes. */
892 hash_set<tree> *visited
893 = lang_hooks.deep_unsharing ? new hash_set<tree> : NULL;
895 copy_if_shared (&DECL_SAVED_TREE (fndecl), visited);
896 copy_if_shared (&DECL_SIZE (DECL_RESULT (fndecl)), visited);
897 copy_if_shared (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)), visited);
899 delete visited;
901 if (cgn)
902 for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
903 unshare_body (cgn->decl);
906 /* Callback for walk_tree to unmark the visited trees rooted at *TP.
907 Subtrees are walked until the first unvisited node is encountered. */
909 static tree
910 unmark_visited_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
912 tree t = *tp;
914 /* If this node has been visited, unmark it and keep looking. */
915 if (TREE_VISITED (t))
916 TREE_VISITED (t) = 0;
918 /* Otherwise, don't look any deeper. */
919 else
920 *walk_subtrees = 0;
922 return NULL_TREE;
925 /* Unmark the visited trees rooted at *TP. */
927 static inline void
928 unmark_visited (tree *tp)
930 walk_tree (tp, unmark_visited_r, NULL, NULL);
933 /* Likewise, but mark all trees as not visited. */
935 static void
936 unvisit_body (tree fndecl)
938 struct cgraph_node *cgn = cgraph_node::get (fndecl);
940 unmark_visited (&DECL_SAVED_TREE (fndecl));
941 unmark_visited (&DECL_SIZE (DECL_RESULT (fndecl)));
942 unmark_visited (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)));
944 if (cgn)
945 for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
946 unvisit_body (cgn->decl);
949 /* Unconditionally make an unshared copy of EXPR. This is used when using
950 stored expressions which span multiple functions, such as BINFO_VTABLE,
951 as the normal unsharing process can't tell that they're shared. */
953 tree
954 unshare_expr (tree expr)
956 walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
957 return expr;
960 /* Worker for unshare_expr_without_location. */
962 static tree
963 prune_expr_location (tree *tp, int *walk_subtrees, void *)
965 if (EXPR_P (*tp))
966 SET_EXPR_LOCATION (*tp, UNKNOWN_LOCATION);
967 else
968 *walk_subtrees = 0;
969 return NULL_TREE;
972 /* Similar to unshare_expr but also prune all expression locations
973 from EXPR. */
975 tree
976 unshare_expr_without_location (tree expr)
978 walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
979 if (EXPR_P (expr))
980 walk_tree (&expr, prune_expr_location, NULL, NULL);
981 return expr;
984 /* WRAPPER is a code such as BIND_EXPR or CLEANUP_POINT_EXPR which can both
985 contain statements and have a value. Assign its value to a temporary
986 and give it void_type_node. Return the temporary, or NULL_TREE if
987 WRAPPER was already void. */
989 tree
990 voidify_wrapper_expr (tree wrapper, tree temp)
992 tree type = TREE_TYPE (wrapper);
993 if (type && !VOID_TYPE_P (type))
995 tree *p;
997 /* Set p to point to the body of the wrapper. Loop until we find
998 something that isn't a wrapper. */
999 for (p = &wrapper; p && *p; )
1001 switch (TREE_CODE (*p))
1003 case BIND_EXPR:
1004 TREE_SIDE_EFFECTS (*p) = 1;
1005 TREE_TYPE (*p) = void_type_node;
1006 /* For a BIND_EXPR, the body is operand 1. */
1007 p = &BIND_EXPR_BODY (*p);
1008 break;
1010 case CLEANUP_POINT_EXPR:
1011 case TRY_FINALLY_EXPR:
1012 case TRY_CATCH_EXPR:
1013 TREE_SIDE_EFFECTS (*p) = 1;
1014 TREE_TYPE (*p) = void_type_node;
1015 p = &TREE_OPERAND (*p, 0);
1016 break;
1018 case STATEMENT_LIST:
1020 tree_stmt_iterator i = tsi_last (*p);
1021 TREE_SIDE_EFFECTS (*p) = 1;
1022 TREE_TYPE (*p) = void_type_node;
1023 p = tsi_end_p (i) ? NULL : tsi_stmt_ptr (i);
1025 break;
1027 case COMPOUND_EXPR:
1028 /* Advance to the last statement. Set all container types to
1029 void. */
1030 for (; TREE_CODE (*p) == COMPOUND_EXPR; p = &TREE_OPERAND (*p, 1))
1032 TREE_SIDE_EFFECTS (*p) = 1;
1033 TREE_TYPE (*p) = void_type_node;
1035 break;
1037 case TRANSACTION_EXPR:
1038 TREE_SIDE_EFFECTS (*p) = 1;
1039 TREE_TYPE (*p) = void_type_node;
1040 p = &TRANSACTION_EXPR_BODY (*p);
1041 break;
1043 default:
1044 /* Assume that any tree upon which voidify_wrapper_expr is
1045 directly called is a wrapper, and that its body is op0. */
1046 if (p == &wrapper)
1048 TREE_SIDE_EFFECTS (*p) = 1;
1049 TREE_TYPE (*p) = void_type_node;
1050 p = &TREE_OPERAND (*p, 0);
1051 break;
1053 goto out;
1057 out:
1058 if (p == NULL || IS_EMPTY_STMT (*p))
1059 temp = NULL_TREE;
1060 else if (temp)
1062 /* The wrapper is on the RHS of an assignment that we're pushing
1063 down. */
1064 gcc_assert (TREE_CODE (temp) == INIT_EXPR
1065 || TREE_CODE (temp) == MODIFY_EXPR);
1066 TREE_OPERAND (temp, 1) = *p;
1067 *p = temp;
1069 else
1071 temp = create_tmp_var (type, "retval");
1072 *p = build2 (INIT_EXPR, type, temp, *p);
1075 return temp;
1078 return NULL_TREE;
1081 /* Prepare calls to builtins to SAVE and RESTORE the stack as well as
1082 a temporary through which they communicate. */
1084 static void
1085 build_stack_save_restore (gcall **save, gcall **restore)
1087 tree tmp_var;
1089 *save = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_SAVE), 0);
1090 tmp_var = create_tmp_var (ptr_type_node, "saved_stack");
1091 gimple_call_set_lhs (*save, tmp_var);
1093 *restore
1094 = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_RESTORE),
1095 1, tmp_var);
1098 /* Generate IFN_ASAN_MARK call that poisons shadow of a for DECL variable. */
1100 static tree
1101 build_asan_poison_call_expr (tree decl)
1103 /* Do not poison variables that have size equal to zero. */
1104 tree unit_size = DECL_SIZE_UNIT (decl);
1105 if (zerop (unit_size))
1106 return NULL_TREE;
1108 tree base = build_fold_addr_expr (decl);
1110 return build_call_expr_internal_loc (UNKNOWN_LOCATION, IFN_ASAN_MARK,
1111 void_type_node, 3,
1112 build_int_cst (integer_type_node,
1113 ASAN_MARK_POISON),
1114 base, unit_size);
1117 /* Generate IFN_ASAN_MARK call that would poison or unpoison, depending
1118 on POISON flag, shadow memory of a DECL variable. The call will be
1119 put on location identified by IT iterator, where BEFORE flag drives
1120 position where the stmt will be put. */
1122 static void
1123 asan_poison_variable (tree decl, bool poison, gimple_stmt_iterator *it,
1124 bool before)
1126 /* When within an OMP context, do not emit ASAN_MARK internal fns. */
1127 if (gimplify_omp_ctxp)
1128 return;
1130 tree unit_size = DECL_SIZE_UNIT (decl);
1131 tree base = build_fold_addr_expr (decl);
1133 /* Do not poison variables that have size equal to zero. */
1134 if (zerop (unit_size))
1135 return;
1137 /* It's necessary to have all stack variables aligned to ASAN granularity
1138 bytes. */
1139 if (DECL_ALIGN_UNIT (decl) <= ASAN_SHADOW_GRANULARITY)
1140 SET_DECL_ALIGN (decl, BITS_PER_UNIT * ASAN_SHADOW_GRANULARITY);
1142 HOST_WIDE_INT flags = poison ? ASAN_MARK_POISON : ASAN_MARK_UNPOISON;
1144 gimple *g
1145 = gimple_build_call_internal (IFN_ASAN_MARK, 3,
1146 build_int_cst (integer_type_node, flags),
1147 base, unit_size);
1149 if (before)
1150 gsi_insert_before (it, g, GSI_NEW_STMT);
1151 else
1152 gsi_insert_after (it, g, GSI_NEW_STMT);
1155 /* Generate IFN_ASAN_MARK internal call that depending on POISON flag
1156 either poisons or unpoisons a DECL. Created statement is appended
1157 to SEQ_P gimple sequence. */
1159 static void
1160 asan_poison_variable (tree decl, bool poison, gimple_seq *seq_p)
1162 gimple_stmt_iterator it = gsi_last (*seq_p);
1163 bool before = false;
1165 if (gsi_end_p (it))
1166 before = true;
1168 asan_poison_variable (decl, poison, &it, before);
1171 /* Sort pair of VAR_DECLs A and B by DECL_UID. */
1173 static int
1174 sort_by_decl_uid (const void *a, const void *b)
1176 const tree *t1 = (const tree *)a;
1177 const tree *t2 = (const tree *)b;
1179 int uid1 = DECL_UID (*t1);
1180 int uid2 = DECL_UID (*t2);
1182 if (uid1 < uid2)
1183 return -1;
1184 else if (uid1 > uid2)
1185 return 1;
1186 else
1187 return 0;
1190 /* Generate IFN_ASAN_MARK internal call for all VARIABLES
1191 depending on POISON flag. Created statement is appended
1192 to SEQ_P gimple sequence. */
1194 static void
1195 asan_poison_variables (hash_set<tree> *variables, bool poison, gimple_seq *seq_p)
1197 unsigned c = variables->elements ();
1198 if (c == 0)
1199 return;
1201 auto_vec<tree> sorted_variables (c);
1203 for (hash_set<tree>::iterator it = variables->begin ();
1204 it != variables->end (); ++it)
1205 sorted_variables.safe_push (*it);
1207 sorted_variables.qsort (sort_by_decl_uid);
1209 unsigned i;
1210 tree var;
1211 FOR_EACH_VEC_ELT (sorted_variables, i, var)
1213 asan_poison_variable (var, poison, seq_p);
1215 /* Add use_after_scope_memory attribute for the variable in order
1216 to prevent re-written into SSA. */
1217 if (!lookup_attribute (ASAN_USE_AFTER_SCOPE_ATTRIBUTE,
1218 DECL_ATTRIBUTES (var)))
1219 DECL_ATTRIBUTES (var)
1220 = tree_cons (get_identifier (ASAN_USE_AFTER_SCOPE_ATTRIBUTE),
1221 integer_one_node,
1222 DECL_ATTRIBUTES (var));
1226 /* Gimplify a BIND_EXPR. Just voidify and recurse. */
1228 static enum gimplify_status
1229 gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p)
1231 tree bind_expr = *expr_p;
1232 bool old_keep_stack = gimplify_ctxp->keep_stack;
1233 bool old_save_stack = gimplify_ctxp->save_stack;
1234 tree t;
1235 gbind *bind_stmt;
1236 gimple_seq body, cleanup;
1237 gcall *stack_save;
1238 location_t start_locus = 0, end_locus = 0;
1239 tree ret_clauses = NULL;
1241 tree temp = voidify_wrapper_expr (bind_expr, NULL);
1243 /* Mark variables seen in this bind expr. */
1244 for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t))
1246 if (VAR_P (t))
1248 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
1250 /* Mark variable as local. */
1251 if (ctx && ctx->region_type != ORT_NONE && !DECL_EXTERNAL (t)
1252 && (! DECL_SEEN_IN_BIND_EXPR_P (t)
1253 || splay_tree_lookup (ctx->variables,
1254 (splay_tree_key) t) == NULL))
1256 if (ctx->region_type == ORT_SIMD
1257 && TREE_ADDRESSABLE (t)
1258 && !TREE_STATIC (t))
1259 omp_add_variable (ctx, t, GOVD_PRIVATE | GOVD_SEEN);
1260 else
1261 omp_add_variable (ctx, t, GOVD_LOCAL | GOVD_SEEN);
1264 DECL_SEEN_IN_BIND_EXPR_P (t) = 1;
1266 if (DECL_HARD_REGISTER (t) && !is_global_var (t) && cfun)
1267 cfun->has_local_explicit_reg_vars = true;
1270 /* Preliminarily mark non-addressed complex variables as eligible
1271 for promotion to gimple registers. We'll transform their uses
1272 as we find them. */
1273 if ((TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE
1274 || TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
1275 && !TREE_THIS_VOLATILE (t)
1276 && (VAR_P (t) && !DECL_HARD_REGISTER (t))
1277 && !needs_to_live_in_memory (t))
1278 DECL_GIMPLE_REG_P (t) = 1;
1281 bind_stmt = gimple_build_bind (BIND_EXPR_VARS (bind_expr), NULL,
1282 BIND_EXPR_BLOCK (bind_expr));
1283 gimple_push_bind_expr (bind_stmt);
1285 gimplify_ctxp->keep_stack = false;
1286 gimplify_ctxp->save_stack = false;
1288 /* Gimplify the body into the GIMPLE_BIND tuple's body. */
1289 body = NULL;
1290 gimplify_stmt (&BIND_EXPR_BODY (bind_expr), &body);
1291 gimple_bind_set_body (bind_stmt, body);
1293 /* Source location wise, the cleanup code (stack_restore and clobbers)
1294 belongs to the end of the block, so propagate what we have. The
1295 stack_save operation belongs to the beginning of block, which we can
1296 infer from the bind_expr directly if the block has no explicit
1297 assignment. */
1298 if (BIND_EXPR_BLOCK (bind_expr))
1300 end_locus = BLOCK_SOURCE_END_LOCATION (BIND_EXPR_BLOCK (bind_expr));
1301 start_locus = BLOCK_SOURCE_LOCATION (BIND_EXPR_BLOCK (bind_expr));
1303 if (start_locus == 0)
1304 start_locus = EXPR_LOCATION (bind_expr);
1306 cleanup = NULL;
1307 stack_save = NULL;
1309 /* If the code both contains VLAs and calls alloca, then we cannot reclaim
1310 the stack space allocated to the VLAs. */
1311 if (gimplify_ctxp->save_stack && !gimplify_ctxp->keep_stack)
1313 gcall *stack_restore;
1315 /* Save stack on entry and restore it on exit. Add a try_finally
1316 block to achieve this. */
1317 build_stack_save_restore (&stack_save, &stack_restore);
1319 gimple_set_location (stack_save, start_locus);
1320 gimple_set_location (stack_restore, end_locus);
1322 gimplify_seq_add_stmt (&cleanup, stack_restore);
1325 /* Add clobbers for all variables that go out of scope. */
1326 for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t))
1328 if (VAR_P (t)
1329 && !is_global_var (t)
1330 && DECL_CONTEXT (t) == current_function_decl)
1332 if (!DECL_HARD_REGISTER (t)
1333 && !TREE_THIS_VOLATILE (t)
1334 && !DECL_HAS_VALUE_EXPR_P (t)
1335 /* Only care for variables that have to be in memory. Others
1336 will be rewritten into SSA names, hence moved to the
1337 top-level. */
1338 && !is_gimple_reg (t)
1339 && flag_stack_reuse != SR_NONE)
1341 tree clobber = build_constructor (TREE_TYPE (t), NULL);
1342 gimple *clobber_stmt;
1343 TREE_THIS_VOLATILE (clobber) = 1;
1344 clobber_stmt = gimple_build_assign (t, clobber);
1345 gimple_set_location (clobber_stmt, end_locus);
1346 gimplify_seq_add_stmt (&cleanup, clobber_stmt);
1349 if (flag_openacc && oacc_declare_returns != NULL)
1351 tree *c = oacc_declare_returns->get (t);
1352 if (c != NULL)
1354 if (ret_clauses)
1355 OMP_CLAUSE_CHAIN (*c) = ret_clauses;
1357 ret_clauses = *c;
1359 oacc_declare_returns->remove (t);
1361 if (oacc_declare_returns->elements () == 0)
1363 delete oacc_declare_returns;
1364 oacc_declare_returns = NULL;
1370 if (asan_poisoned_variables != NULL
1371 && asan_poisoned_variables->contains (t))
1373 asan_poisoned_variables->remove (t);
1374 asan_poison_variable (t, true, &cleanup);
1377 if (gimplify_ctxp->live_switch_vars != NULL
1378 && gimplify_ctxp->live_switch_vars->contains (t))
1379 gimplify_ctxp->live_switch_vars->remove (t);
1382 if (ret_clauses)
1384 gomp_target *stmt;
1385 gimple_stmt_iterator si = gsi_start (cleanup);
1387 stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
1388 ret_clauses);
1389 gsi_insert_seq_before_without_update (&si, stmt, GSI_NEW_STMT);
1392 if (cleanup)
1394 gtry *gs;
1395 gimple_seq new_body;
1397 new_body = NULL;
1398 gs = gimple_build_try (gimple_bind_body (bind_stmt), cleanup,
1399 GIMPLE_TRY_FINALLY);
1401 if (stack_save)
1402 gimplify_seq_add_stmt (&new_body, stack_save);
1403 gimplify_seq_add_stmt (&new_body, gs);
1404 gimple_bind_set_body (bind_stmt, new_body);
1407 /* keep_stack propagates all the way up to the outermost BIND_EXPR. */
1408 if (!gimplify_ctxp->keep_stack)
1409 gimplify_ctxp->keep_stack = old_keep_stack;
1410 gimplify_ctxp->save_stack = old_save_stack;
1412 gimple_pop_bind_expr ();
1414 gimplify_seq_add_stmt (pre_p, bind_stmt);
1416 if (temp)
1418 *expr_p = temp;
1419 return GS_OK;
1422 *expr_p = NULL_TREE;
1423 return GS_ALL_DONE;
1426 /* Gimplify a RETURN_EXPR. If the expression to be returned is not a
1427 GIMPLE value, it is assigned to a new temporary and the statement is
1428 re-written to return the temporary.
1430 PRE_P points to the sequence where side effects that must happen before
1431 STMT should be stored. */
1433 static enum gimplify_status
1434 gimplify_return_expr (tree stmt, gimple_seq *pre_p)
1436 greturn *ret;
1437 tree ret_expr = TREE_OPERAND (stmt, 0);
1438 tree result_decl, result;
1440 if (ret_expr == error_mark_node)
1441 return GS_ERROR;
1443 /* Implicit _Cilk_sync must be inserted right before any return statement
1444 if there is a _Cilk_spawn in the function. If the user has provided a
1445 _Cilk_sync, the optimizer should remove this duplicate one. */
1446 if (fn_contains_cilk_spawn_p (cfun))
1448 tree impl_sync = build0 (CILK_SYNC_STMT, void_type_node);
1449 gimplify_and_add (impl_sync, pre_p);
1452 if (!ret_expr
1453 || TREE_CODE (ret_expr) == RESULT_DECL
1454 || ret_expr == error_mark_node)
1456 greturn *ret = gimple_build_return (ret_expr);
1457 gimple_set_no_warning (ret, TREE_NO_WARNING (stmt));
1458 gimplify_seq_add_stmt (pre_p, ret);
1459 return GS_ALL_DONE;
1462 if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))))
1463 result_decl = NULL_TREE;
1464 else
1466 result_decl = TREE_OPERAND (ret_expr, 0);
1468 /* See through a return by reference. */
1469 if (TREE_CODE (result_decl) == INDIRECT_REF)
1470 result_decl = TREE_OPERAND (result_decl, 0);
1472 gcc_assert ((TREE_CODE (ret_expr) == MODIFY_EXPR
1473 || TREE_CODE (ret_expr) == INIT_EXPR)
1474 && TREE_CODE (result_decl) == RESULT_DECL);
1477 /* If aggregate_value_p is true, then we can return the bare RESULT_DECL.
1478 Recall that aggregate_value_p is FALSE for any aggregate type that is
1479 returned in registers. If we're returning values in registers, then
1480 we don't want to extend the lifetime of the RESULT_DECL, particularly
1481 across another call. In addition, for those aggregates for which
1482 hard_function_value generates a PARALLEL, we'll die during normal
1483 expansion of structure assignments; there's special code in expand_return
1484 to handle this case that does not exist in expand_expr. */
1485 if (!result_decl)
1486 result = NULL_TREE;
1487 else if (aggregate_value_p (result_decl, TREE_TYPE (current_function_decl)))
1489 if (TREE_CODE (DECL_SIZE (result_decl)) != INTEGER_CST)
1491 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (result_decl)))
1492 gimplify_type_sizes (TREE_TYPE (result_decl), pre_p);
1493 /* Note that we don't use gimplify_vla_decl because the RESULT_DECL
1494 should be effectively allocated by the caller, i.e. all calls to
1495 this function must be subject to the Return Slot Optimization. */
1496 gimplify_one_sizepos (&DECL_SIZE (result_decl), pre_p);
1497 gimplify_one_sizepos (&DECL_SIZE_UNIT (result_decl), pre_p);
1499 result = result_decl;
1501 else if (gimplify_ctxp->return_temp)
1502 result = gimplify_ctxp->return_temp;
1503 else
1505 result = create_tmp_reg (TREE_TYPE (result_decl));
1507 /* ??? With complex control flow (usually involving abnormal edges),
1508 we can wind up warning about an uninitialized value for this. Due
1509 to how this variable is constructed and initialized, this is never
1510 true. Give up and never warn. */
1511 TREE_NO_WARNING (result) = 1;
1513 gimplify_ctxp->return_temp = result;
1516 /* Smash the lhs of the MODIFY_EXPR to the temporary we plan to use.
1517 Then gimplify the whole thing. */
1518 if (result != result_decl)
1519 TREE_OPERAND (ret_expr, 0) = result;
1521 gimplify_and_add (TREE_OPERAND (stmt, 0), pre_p);
1523 ret = gimple_build_return (result);
1524 gimple_set_no_warning (ret, TREE_NO_WARNING (stmt));
1525 gimplify_seq_add_stmt (pre_p, ret);
1527 return GS_ALL_DONE;
1530 /* Gimplify a variable-length array DECL. */
1532 static void
1533 gimplify_vla_decl (tree decl, gimple_seq *seq_p)
1535 /* This is a variable-sized decl. Simplify its size and mark it
1536 for deferred expansion. */
1537 tree t, addr, ptr_type;
1539 gimplify_one_sizepos (&DECL_SIZE (decl), seq_p);
1540 gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), seq_p);
1542 /* Don't mess with a DECL_VALUE_EXPR set by the front-end. */
1543 if (DECL_HAS_VALUE_EXPR_P (decl))
1544 return;
1546 /* All occurrences of this decl in final gimplified code will be
1547 replaced by indirection. Setting DECL_VALUE_EXPR does two
1548 things: First, it lets the rest of the gimplifier know what
1549 replacement to use. Second, it lets the debug info know
1550 where to find the value. */
1551 ptr_type = build_pointer_type (TREE_TYPE (decl));
1552 addr = create_tmp_var (ptr_type, get_name (decl));
1553 DECL_IGNORED_P (addr) = 0;
1554 t = build_fold_indirect_ref (addr);
1555 TREE_THIS_NOTRAP (t) = 1;
1556 SET_DECL_VALUE_EXPR (decl, t);
1557 DECL_HAS_VALUE_EXPR_P (decl) = 1;
1559 t = builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN);
1560 t = build_call_expr (t, 2, DECL_SIZE_UNIT (decl),
1561 size_int (DECL_ALIGN (decl)));
1562 /* The call has been built for a variable-sized object. */
1563 CALL_ALLOCA_FOR_VAR_P (t) = 1;
1564 t = fold_convert (ptr_type, t);
1565 t = build2 (MODIFY_EXPR, TREE_TYPE (addr), addr, t);
1567 gimplify_and_add (t, seq_p);
1570 /* A helper function to be called via walk_tree. Mark all labels under *TP
1571 as being forced. To be called for DECL_INITIAL of static variables. */
1573 static tree
1574 force_labels_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
1576 if (TYPE_P (*tp))
1577 *walk_subtrees = 0;
1578 if (TREE_CODE (*tp) == LABEL_DECL)
1580 FORCED_LABEL (*tp) = 1;
1581 cfun->has_forced_label_in_static = 1;
1584 return NULL_TREE;
1587 /* Gimplify a DECL_EXPR node *STMT_P by making any necessary allocation
1588 and initialization explicit. */
1590 static enum gimplify_status
1591 gimplify_decl_expr (tree *stmt_p, gimple_seq *seq_p)
1593 tree stmt = *stmt_p;
1594 tree decl = DECL_EXPR_DECL (stmt);
1596 *stmt_p = NULL_TREE;
1598 if (TREE_TYPE (decl) == error_mark_node)
1599 return GS_ERROR;
1601 if ((TREE_CODE (decl) == TYPE_DECL
1602 || VAR_P (decl))
1603 && !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl)))
1605 gimplify_type_sizes (TREE_TYPE (decl), seq_p);
1606 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
1607 gimplify_type_sizes (TREE_TYPE (TREE_TYPE (decl)), seq_p);
1610 /* ??? DECL_ORIGINAL_TYPE is streamed for LTO so it needs to be gimplified
1611 in case its size expressions contain problematic nodes like CALL_EXPR. */
1612 if (TREE_CODE (decl) == TYPE_DECL
1613 && DECL_ORIGINAL_TYPE (decl)
1614 && !TYPE_SIZES_GIMPLIFIED (DECL_ORIGINAL_TYPE (decl)))
1616 gimplify_type_sizes (DECL_ORIGINAL_TYPE (decl), seq_p);
1617 if (TREE_CODE (DECL_ORIGINAL_TYPE (decl)) == REFERENCE_TYPE)
1618 gimplify_type_sizes (TREE_TYPE (DECL_ORIGINAL_TYPE (decl)), seq_p);
1621 if (VAR_P (decl) && !DECL_EXTERNAL (decl))
1623 tree init = DECL_INITIAL (decl);
1624 bool is_vla = false;
1626 if (TREE_CODE (DECL_SIZE_UNIT (decl)) != INTEGER_CST
1627 || (!TREE_STATIC (decl)
1628 && flag_stack_check == GENERIC_STACK_CHECK
1629 && compare_tree_int (DECL_SIZE_UNIT (decl),
1630 STACK_CHECK_MAX_VAR_SIZE) > 0))
1632 gimplify_vla_decl (decl, seq_p);
1633 is_vla = true;
1636 if (asan_poisoned_variables
1637 && !is_vla
1638 && TREE_ADDRESSABLE (decl)
1639 && !TREE_STATIC (decl)
1640 && !DECL_HAS_VALUE_EXPR_P (decl)
1641 && dbg_cnt (asan_use_after_scope))
1643 asan_poisoned_variables->add (decl);
1644 asan_poison_variable (decl, false, seq_p);
1645 if (!DECL_ARTIFICIAL (decl) && gimplify_ctxp->live_switch_vars)
1646 gimplify_ctxp->live_switch_vars->add (decl);
1649 /* Some front ends do not explicitly declare all anonymous
1650 artificial variables. We compensate here by declaring the
1651 variables, though it would be better if the front ends would
1652 explicitly declare them. */
1653 if (!DECL_SEEN_IN_BIND_EXPR_P (decl)
1654 && DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
1655 gimple_add_tmp_var (decl);
1657 if (init && init != error_mark_node)
1659 if (!TREE_STATIC (decl))
1661 DECL_INITIAL (decl) = NULL_TREE;
1662 init = build2 (INIT_EXPR, void_type_node, decl, init);
1663 gimplify_and_add (init, seq_p);
1664 ggc_free (init);
1666 else
1667 /* We must still examine initializers for static variables
1668 as they may contain a label address. */
1669 walk_tree (&init, force_labels_r, NULL, NULL);
1673 return GS_ALL_DONE;
1676 /* Gimplify a LOOP_EXPR. Normally this just involves gimplifying the body
1677 and replacing the LOOP_EXPR with goto, but if the loop contains an
1678 EXIT_EXPR, we need to append a label for it to jump to. */
1680 static enum gimplify_status
1681 gimplify_loop_expr (tree *expr_p, gimple_seq *pre_p)
1683 tree saved_label = gimplify_ctxp->exit_label;
1684 tree start_label = create_artificial_label (UNKNOWN_LOCATION);
1686 gimplify_seq_add_stmt (pre_p, gimple_build_label (start_label));
1688 gimplify_ctxp->exit_label = NULL_TREE;
1690 gimplify_and_add (LOOP_EXPR_BODY (*expr_p), pre_p);
1692 gimplify_seq_add_stmt (pre_p, gimple_build_goto (start_label));
1694 if (gimplify_ctxp->exit_label)
1695 gimplify_seq_add_stmt (pre_p,
1696 gimple_build_label (gimplify_ctxp->exit_label));
1698 gimplify_ctxp->exit_label = saved_label;
1700 *expr_p = NULL;
1701 return GS_ALL_DONE;
1704 /* Gimplify a statement list onto a sequence. These may be created either
1705 by an enlightened front-end, or by shortcut_cond_expr. */
1707 static enum gimplify_status
1708 gimplify_statement_list (tree *expr_p, gimple_seq *pre_p)
1710 tree temp = voidify_wrapper_expr (*expr_p, NULL);
1712 tree_stmt_iterator i = tsi_start (*expr_p);
1714 while (!tsi_end_p (i))
1716 gimplify_stmt (tsi_stmt_ptr (i), pre_p);
1717 tsi_delink (&i);
1720 if (temp)
1722 *expr_p = temp;
1723 return GS_OK;
1726 return GS_ALL_DONE;
1729 /* Callback for walk_gimple_seq. */
1731 static tree
1732 warn_switch_unreachable_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
1733 struct walk_stmt_info *wi)
1735 gimple *stmt = gsi_stmt (*gsi_p);
1737 *handled_ops_p = true;
1738 switch (gimple_code (stmt))
1740 case GIMPLE_TRY:
1741 /* A compiler-generated cleanup or a user-written try block.
1742 If it's empty, don't dive into it--that would result in
1743 worse location info. */
1744 if (gimple_try_eval (stmt) == NULL)
1746 wi->info = stmt;
1747 return integer_zero_node;
1749 /* Fall through. */
1750 case GIMPLE_BIND:
1751 case GIMPLE_CATCH:
1752 case GIMPLE_EH_FILTER:
1753 case GIMPLE_TRANSACTION:
1754 /* Walk the sub-statements. */
1755 *handled_ops_p = false;
1756 break;
1757 case GIMPLE_CALL:
1758 if (gimple_call_internal_p (stmt, IFN_ASAN_MARK))
1760 *handled_ops_p = false;
1761 break;
1763 /* Fall through. */
1764 default:
1765 /* Save the first "real" statement (not a decl/lexical scope/...). */
1766 wi->info = stmt;
1767 return integer_zero_node;
1769 return NULL_TREE;
1772 /* Possibly warn about unreachable statements between switch's controlling
1773 expression and the first case. SEQ is the body of a switch expression. */
1775 static void
1776 maybe_warn_switch_unreachable (gimple_seq seq)
1778 if (!warn_switch_unreachable
1779 /* This warning doesn't play well with Fortran when optimizations
1780 are on. */
1781 || lang_GNU_Fortran ()
1782 || seq == NULL)
1783 return;
1785 struct walk_stmt_info wi;
1786 memset (&wi, 0, sizeof (wi));
1787 walk_gimple_seq (seq, warn_switch_unreachable_r, NULL, &wi);
1788 gimple *stmt = (gimple *) wi.info;
1790 if (stmt && gimple_code (stmt) != GIMPLE_LABEL)
1792 if (gimple_code (stmt) == GIMPLE_GOTO
1793 && TREE_CODE (gimple_goto_dest (stmt)) == LABEL_DECL
1794 && DECL_ARTIFICIAL (gimple_goto_dest (stmt)))
1795 /* Don't warn for compiler-generated gotos. These occur
1796 in Duff's devices, for example. */;
1797 else
1798 warning_at (gimple_location (stmt), OPT_Wswitch_unreachable,
1799 "statement will never be executed");
1804 /* A label entry that pairs label and a location. */
1805 struct label_entry
1807 tree label;
1808 location_t loc;
1811 /* Find LABEL in vector of label entries VEC. */
1813 static struct label_entry *
1814 find_label_entry (const auto_vec<struct label_entry> *vec, tree label)
1816 unsigned int i;
1817 struct label_entry *l;
1819 FOR_EACH_VEC_ELT (*vec, i, l)
1820 if (l->label == label)
1821 return l;
1822 return NULL;
1825 /* Return true if LABEL, a LABEL_DECL, represents a case label
1826 in a vector of labels CASES. */
1828 static bool
1829 case_label_p (const vec<tree> *cases, tree label)
1831 unsigned int i;
1832 tree l;
1834 FOR_EACH_VEC_ELT (*cases, i, l)
1835 if (CASE_LABEL (l) == label)
1836 return true;
1837 return false;
1840 /* Find the last statement in a scope STMT. */
1842 static gimple *
1843 last_stmt_in_scope (gimple *stmt)
1845 if (!stmt)
1846 return NULL;
1848 switch (gimple_code (stmt))
1850 case GIMPLE_BIND:
1852 gbind *bind = as_a <gbind *> (stmt);
1853 stmt = gimple_seq_last_stmt (gimple_bind_body (bind));
1854 return last_stmt_in_scope (stmt);
1857 case GIMPLE_TRY:
1859 gtry *try_stmt = as_a <gtry *> (stmt);
1860 stmt = gimple_seq_last_stmt (gimple_try_eval (try_stmt));
1861 gimple *last_eval = last_stmt_in_scope (stmt);
1862 if (gimple_stmt_may_fallthru (last_eval)
1863 && (last_eval == NULL
1864 || !gimple_call_internal_p (last_eval, IFN_FALLTHROUGH))
1865 && gimple_try_kind (try_stmt) == GIMPLE_TRY_FINALLY)
1867 stmt = gimple_seq_last_stmt (gimple_try_cleanup (try_stmt));
1868 return last_stmt_in_scope (stmt);
1870 else
1871 return last_eval;
1874 default:
1875 return stmt;
1879 /* Collect interesting labels in LABELS and return the statement preceding
1880 another case label, or a user-defined label. */
1882 static gimple *
1883 collect_fallthrough_labels (gimple_stmt_iterator *gsi_p,
1884 auto_vec <struct label_entry> *labels)
1886 gimple *prev = NULL;
1890 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND
1891 || gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_TRY)
1893 /* Nested scope. Only look at the last statement of
1894 the innermost scope. */
1895 location_t bind_loc = gimple_location (gsi_stmt (*gsi_p));
1896 gimple *last = last_stmt_in_scope (gsi_stmt (*gsi_p));
1897 if (last)
1899 prev = last;
1900 /* It might be a label without a location. Use the
1901 location of the scope then. */
1902 if (!gimple_has_location (prev))
1903 gimple_set_location (prev, bind_loc);
1905 gsi_next (gsi_p);
1906 continue;
1909 /* Ifs are tricky. */
1910 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_COND)
1912 gcond *cond_stmt = as_a <gcond *> (gsi_stmt (*gsi_p));
1913 tree false_lab = gimple_cond_false_label (cond_stmt);
1914 location_t if_loc = gimple_location (cond_stmt);
1916 /* If we have e.g.
1917 if (i > 1) goto <D.2259>; else goto D;
1918 we can't do much with the else-branch. */
1919 if (!DECL_ARTIFICIAL (false_lab))
1920 break;
1922 /* Go on until the false label, then one step back. */
1923 for (; !gsi_end_p (*gsi_p); gsi_next (gsi_p))
1925 gimple *stmt = gsi_stmt (*gsi_p);
1926 if (gimple_code (stmt) == GIMPLE_LABEL
1927 && gimple_label_label (as_a <glabel *> (stmt)) == false_lab)
1928 break;
1931 /* Not found? Oops. */
1932 if (gsi_end_p (*gsi_p))
1933 break;
1935 struct label_entry l = { false_lab, if_loc };
1936 labels->safe_push (l);
1938 /* Go to the last statement of the then branch. */
1939 gsi_prev (gsi_p);
1941 /* if (i != 0) goto <D.1759>; else goto <D.1760>;
1942 <D.1759>:
1943 <stmt>;
1944 goto <D.1761>;
1945 <D.1760>:
1947 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_GOTO
1948 && !gimple_has_location (gsi_stmt (*gsi_p)))
1950 /* Look at the statement before, it might be
1951 attribute fallthrough, in which case don't warn. */
1952 gsi_prev (gsi_p);
1953 bool fallthru_before_dest
1954 = gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_FALLTHROUGH);
1955 gsi_next (gsi_p);
1956 tree goto_dest = gimple_goto_dest (gsi_stmt (*gsi_p));
1957 if (!fallthru_before_dest)
1959 struct label_entry l = { goto_dest, if_loc };
1960 labels->safe_push (l);
1963 /* And move back. */
1964 gsi_next (gsi_p);
1967 /* Remember the last statement. Skip labels that are of no interest
1968 to us. */
1969 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
1971 tree label = gimple_label_label (as_a <glabel *> (gsi_stmt (*gsi_p)));
1972 if (find_label_entry (labels, label))
1973 prev = gsi_stmt (*gsi_p);
1975 else if (gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_ASAN_MARK))
1977 else
1978 prev = gsi_stmt (*gsi_p);
1979 gsi_next (gsi_p);
1981 while (!gsi_end_p (*gsi_p)
1982 /* Stop if we find a case or a user-defined label. */
1983 && (gimple_code (gsi_stmt (*gsi_p)) != GIMPLE_LABEL
1984 || !gimple_has_location (gsi_stmt (*gsi_p))));
1986 return prev;
1989 /* Return true if the switch fallthough warning should occur. LABEL is
1990 the label statement that we're falling through to. */
1992 static bool
1993 should_warn_for_implicit_fallthrough (gimple_stmt_iterator *gsi_p, tree label)
1995 gimple_stmt_iterator gsi = *gsi_p;
1997 /* Don't warn if the label is marked with a "falls through" comment. */
1998 if (FALLTHROUGH_LABEL_P (label))
1999 return false;
2001 /* Don't warn for non-case labels followed by a statement:
2002 case 0:
2003 foo ();
2004 label:
2005 bar ();
2006 as these are likely intentional. */
2007 if (!case_label_p (&gimplify_ctxp->case_labels, label))
2009 tree l;
2010 while (!gsi_end_p (gsi)
2011 && gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
2012 && (l = gimple_label_label (as_a <glabel *> (gsi_stmt (gsi))))
2013 && !case_label_p (&gimplify_ctxp->case_labels, l))
2014 gsi_next (&gsi);
2015 if (gsi_end_p (gsi) || gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL)
2016 return false;
2019 /* Don't warn for terminated branches, i.e. when the subsequent case labels
2020 immediately breaks. */
2021 gsi = *gsi_p;
2023 /* Skip all immediately following labels. */
2024 while (!gsi_end_p (gsi) && gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL)
2025 gsi_next (&gsi);
2027 /* { ... something; default:; } */
2028 if (gsi_end_p (gsi)
2029 /* { ... something; default: break; } or
2030 { ... something; default: goto L; } */
2031 || gimple_code (gsi_stmt (gsi)) == GIMPLE_GOTO
2032 /* { ... something; default: return; } */
2033 || gimple_code (gsi_stmt (gsi)) == GIMPLE_RETURN)
2034 return false;
2036 return true;
2039 /* Callback for walk_gimple_seq. */
2041 static tree
2042 warn_implicit_fallthrough_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
2043 struct walk_stmt_info *)
2045 gimple *stmt = gsi_stmt (*gsi_p);
2047 *handled_ops_p = true;
2048 switch (gimple_code (stmt))
2050 case GIMPLE_TRY:
2051 case GIMPLE_BIND:
2052 case GIMPLE_CATCH:
2053 case GIMPLE_EH_FILTER:
2054 case GIMPLE_TRANSACTION:
2055 /* Walk the sub-statements. */
2056 *handled_ops_p = false;
2057 break;
2059 /* Find a sequence of form:
2061 GIMPLE_LABEL
2062 [...]
2063 <may fallthru stmt>
2064 GIMPLE_LABEL
2066 and possibly warn. */
2067 case GIMPLE_LABEL:
2069 /* Found a label. Skip all immediately following labels. */
2070 while (!gsi_end_p (*gsi_p)
2071 && gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
2072 gsi_next (gsi_p);
2074 /* There might be no more statements. */
2075 if (gsi_end_p (*gsi_p))
2076 return integer_zero_node;
2078 /* Vector of labels that fall through. */
2079 auto_vec <struct label_entry> labels;
2080 gimple *prev = collect_fallthrough_labels (gsi_p, &labels);
2082 /* There might be no more statements. */
2083 if (gsi_end_p (*gsi_p))
2084 return integer_zero_node;
2086 gimple *next = gsi_stmt (*gsi_p);
2087 tree label;
2088 /* If what follows is a label, then we may have a fallthrough. */
2089 if (gimple_code (next) == GIMPLE_LABEL
2090 && gimple_has_location (next)
2091 && (label = gimple_label_label (as_a <glabel *> (next)))
2092 && prev != NULL)
2094 struct label_entry *l;
2095 bool warned_p = false;
2096 if (!should_warn_for_implicit_fallthrough (gsi_p, label))
2097 /* Quiet. */;
2098 else if (gimple_code (prev) == GIMPLE_LABEL
2099 && (label = gimple_label_label (as_a <glabel *> (prev)))
2100 && (l = find_label_entry (&labels, label)))
2101 warned_p = warning_at (l->loc, OPT_Wimplicit_fallthrough_,
2102 "this statement may fall through");
2103 else if (!gimple_call_internal_p (prev, IFN_FALLTHROUGH)
2104 /* Try to be clever and don't warn when the statement
2105 can't actually fall through. */
2106 && gimple_stmt_may_fallthru (prev)
2107 && gimple_has_location (prev))
2108 warned_p = warning_at (gimple_location (prev),
2109 OPT_Wimplicit_fallthrough_,
2110 "this statement may fall through");
2111 if (warned_p)
2112 inform (gimple_location (next), "here");
2114 /* Mark this label as processed so as to prevent multiple
2115 warnings in nested switches. */
2116 FALLTHROUGH_LABEL_P (label) = true;
2118 /* So that next warn_implicit_fallthrough_r will start looking for
2119 a new sequence starting with this label. */
2120 gsi_prev (gsi_p);
2123 break;
2124 default:
2125 break;
2127 return NULL_TREE;
2130 /* Warn when a switch case falls through. */
2132 static void
2133 maybe_warn_implicit_fallthrough (gimple_seq seq)
2135 if (!warn_implicit_fallthrough)
2136 return;
2138 /* This warning is meant for C/C++/ObjC/ObjC++ only. */
2139 if (!(lang_GNU_C ()
2140 || lang_GNU_CXX ()
2141 || lang_GNU_OBJC ()))
2142 return;
2144 struct walk_stmt_info wi;
2145 memset (&wi, 0, sizeof (wi));
2146 walk_gimple_seq (seq, warn_implicit_fallthrough_r, NULL, &wi);
2149 /* Callback for walk_gimple_seq. */
2151 static tree
2152 expand_FALLTHROUGH_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
2153 struct walk_stmt_info *)
2155 gimple *stmt = gsi_stmt (*gsi_p);
2157 *handled_ops_p = true;
2158 switch (gimple_code (stmt))
2160 case GIMPLE_TRY:
2161 case GIMPLE_BIND:
2162 case GIMPLE_CATCH:
2163 case GIMPLE_EH_FILTER:
2164 case GIMPLE_TRANSACTION:
2165 /* Walk the sub-statements. */
2166 *handled_ops_p = false;
2167 break;
2168 case GIMPLE_CALL:
2169 if (gimple_call_internal_p (stmt, IFN_FALLTHROUGH))
2171 gsi_remove (gsi_p, true);
2172 if (gsi_end_p (*gsi_p))
2173 return integer_zero_node;
2175 bool found = false;
2176 location_t loc = gimple_location (stmt);
2178 gimple_stmt_iterator gsi2 = *gsi_p;
2179 stmt = gsi_stmt (gsi2);
2180 if (gimple_code (stmt) == GIMPLE_GOTO && !gimple_has_location (stmt))
2182 /* Go on until the artificial label. */
2183 tree goto_dest = gimple_goto_dest (stmt);
2184 for (; !gsi_end_p (gsi2); gsi_next (&gsi2))
2186 if (gimple_code (gsi_stmt (gsi2)) == GIMPLE_LABEL
2187 && gimple_label_label (as_a <glabel *> (gsi_stmt (gsi2)))
2188 == goto_dest)
2189 break;
2192 /* Not found? Stop. */
2193 if (gsi_end_p (gsi2))
2194 break;
2196 /* Look one past it. */
2197 gsi_next (&gsi2);
2200 /* We're looking for a case label or default label here. */
2201 while (!gsi_end_p (gsi2))
2203 stmt = gsi_stmt (gsi2);
2204 if (gimple_code (stmt) == GIMPLE_LABEL)
2206 tree label = gimple_label_label (as_a <glabel *> (stmt));
2207 if (gimple_has_location (stmt) && DECL_ARTIFICIAL (label))
2209 found = true;
2210 break;
2213 else
2214 /* Something other than a label. That's not expected. */
2215 break;
2216 gsi_next (&gsi2);
2218 if (!found)
2219 warning_at (loc, 0, "attribute %<fallthrough%> not preceding "
2220 "a case label or default label");
2222 break;
2223 default:
2224 break;
2226 return NULL_TREE;
2229 /* Expand all FALLTHROUGH () calls in SEQ. */
2231 static void
2232 expand_FALLTHROUGH (gimple_seq *seq_p)
2234 struct walk_stmt_info wi;
2235 memset (&wi, 0, sizeof (wi));
2236 walk_gimple_seq_mod (seq_p, expand_FALLTHROUGH_r, NULL, &wi);
2240 /* Gimplify a SWITCH_EXPR, and collect the vector of labels it can
2241 branch to. */
2243 static enum gimplify_status
2244 gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p)
2246 tree switch_expr = *expr_p;
2247 gimple_seq switch_body_seq = NULL;
2248 enum gimplify_status ret;
2249 tree index_type = TREE_TYPE (switch_expr);
2250 if (index_type == NULL_TREE)
2251 index_type = TREE_TYPE (SWITCH_COND (switch_expr));
2253 ret = gimplify_expr (&SWITCH_COND (switch_expr), pre_p, NULL, is_gimple_val,
2254 fb_rvalue);
2255 if (ret == GS_ERROR || ret == GS_UNHANDLED)
2256 return ret;
2258 if (SWITCH_BODY (switch_expr))
2260 vec<tree> labels;
2261 vec<tree> saved_labels;
2262 hash_set<tree> *saved_live_switch_vars = NULL;
2263 tree default_case = NULL_TREE;
2264 gswitch *switch_stmt;
2266 /* If someone can be bothered to fill in the labels, they can
2267 be bothered to null out the body too. */
2268 gcc_assert (!SWITCH_LABELS (switch_expr));
2270 /* Save old labels, get new ones from body, then restore the old
2271 labels. Save all the things from the switch body to append after. */
2272 saved_labels = gimplify_ctxp->case_labels;
2273 gimplify_ctxp->case_labels.create (8);
2275 /* Do not create live_switch_vars if SWITCH_BODY is not a BIND_EXPR. */
2276 saved_live_switch_vars = gimplify_ctxp->live_switch_vars;
2277 if (TREE_CODE (SWITCH_BODY (switch_expr)) == BIND_EXPR)
2278 gimplify_ctxp->live_switch_vars = new hash_set<tree> (4);
2279 else
2280 gimplify_ctxp->live_switch_vars = NULL;
2282 bool old_in_switch_expr = gimplify_ctxp->in_switch_expr;
2283 gimplify_ctxp->in_switch_expr = true;
2285 gimplify_stmt (&SWITCH_BODY (switch_expr), &switch_body_seq);
2287 gimplify_ctxp->in_switch_expr = old_in_switch_expr;
2288 maybe_warn_switch_unreachable (switch_body_seq);
2289 maybe_warn_implicit_fallthrough (switch_body_seq);
2290 /* Only do this for the outermost GIMPLE_SWITCH. */
2291 if (!gimplify_ctxp->in_switch_expr)
2292 expand_FALLTHROUGH (&switch_body_seq);
2294 labels = gimplify_ctxp->case_labels;
2295 gimplify_ctxp->case_labels = saved_labels;
2297 if (gimplify_ctxp->live_switch_vars)
2299 gcc_assert (gimplify_ctxp->live_switch_vars->elements () == 0);
2300 delete gimplify_ctxp->live_switch_vars;
2302 gimplify_ctxp->live_switch_vars = saved_live_switch_vars;
2304 preprocess_case_label_vec_for_gimple (labels, index_type,
2305 &default_case);
2307 if (!default_case)
2309 glabel *new_default;
2311 default_case
2312 = build_case_label (NULL_TREE, NULL_TREE,
2313 create_artificial_label (UNKNOWN_LOCATION));
2314 new_default = gimple_build_label (CASE_LABEL (default_case));
2315 gimplify_seq_add_stmt (&switch_body_seq, new_default);
2318 switch_stmt = gimple_build_switch (SWITCH_COND (switch_expr),
2319 default_case, labels);
2320 gimplify_seq_add_stmt (pre_p, switch_stmt);
2321 gimplify_seq_add_seq (pre_p, switch_body_seq);
2322 labels.release ();
2324 else
2325 gcc_assert (SWITCH_LABELS (switch_expr));
2327 return GS_ALL_DONE;
2330 /* Gimplify the LABEL_EXPR pointed to by EXPR_P. */
2332 static enum gimplify_status
2333 gimplify_label_expr (tree *expr_p, gimple_seq *pre_p)
2335 gcc_assert (decl_function_context (LABEL_EXPR_LABEL (*expr_p))
2336 == current_function_decl);
2338 glabel *label_stmt = gimple_build_label (LABEL_EXPR_LABEL (*expr_p));
2339 gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
2340 gimplify_seq_add_stmt (pre_p, label_stmt);
2342 return GS_ALL_DONE;
2345 /* Gimplify the CASE_LABEL_EXPR pointed to by EXPR_P. */
2347 static enum gimplify_status
2348 gimplify_case_label_expr (tree *expr_p, gimple_seq *pre_p)
2350 struct gimplify_ctx *ctxp;
2351 glabel *label_stmt;
2353 /* Invalid programs can play Duff's Device type games with, for example,
2354 #pragma omp parallel. At least in the C front end, we don't
2355 detect such invalid branches until after gimplification, in the
2356 diagnose_omp_blocks pass. */
2357 for (ctxp = gimplify_ctxp; ; ctxp = ctxp->prev_context)
2358 if (ctxp->case_labels.exists ())
2359 break;
2361 label_stmt = gimple_build_label (CASE_LABEL (*expr_p));
2362 gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
2363 ctxp->case_labels.safe_push (*expr_p);
2364 gimplify_seq_add_stmt (pre_p, label_stmt);
2366 return GS_ALL_DONE;
2369 /* Build a GOTO to the LABEL_DECL pointed to by LABEL_P, building it first
2370 if necessary. */
2372 tree
2373 build_and_jump (tree *label_p)
2375 if (label_p == NULL)
2376 /* If there's nowhere to jump, just fall through. */
2377 return NULL_TREE;
2379 if (*label_p == NULL_TREE)
2381 tree label = create_artificial_label (UNKNOWN_LOCATION);
2382 *label_p = label;
2385 return build1 (GOTO_EXPR, void_type_node, *label_p);
2388 /* Gimplify an EXIT_EXPR by converting to a GOTO_EXPR inside a COND_EXPR.
2389 This also involves building a label to jump to and communicating it to
2390 gimplify_loop_expr through gimplify_ctxp->exit_label. */
2392 static enum gimplify_status
2393 gimplify_exit_expr (tree *expr_p)
2395 tree cond = TREE_OPERAND (*expr_p, 0);
2396 tree expr;
2398 expr = build_and_jump (&gimplify_ctxp->exit_label);
2399 expr = build3 (COND_EXPR, void_type_node, cond, expr, NULL_TREE);
2400 *expr_p = expr;
2402 return GS_OK;
2405 /* *EXPR_P is a COMPONENT_REF being used as an rvalue. If its type is
2406 different from its canonical type, wrap the whole thing inside a
2407 NOP_EXPR and force the type of the COMPONENT_REF to be the canonical
2408 type.
2410 The canonical type of a COMPONENT_REF is the type of the field being
2411 referenced--unless the field is a bit-field which can be read directly
2412 in a smaller mode, in which case the canonical type is the
2413 sign-appropriate type corresponding to that mode. */
2415 static void
2416 canonicalize_component_ref (tree *expr_p)
2418 tree expr = *expr_p;
2419 tree type;
2421 gcc_assert (TREE_CODE (expr) == COMPONENT_REF);
2423 if (INTEGRAL_TYPE_P (TREE_TYPE (expr)))
2424 type = TREE_TYPE (get_unwidened (expr, NULL_TREE));
2425 else
2426 type = TREE_TYPE (TREE_OPERAND (expr, 1));
2428 /* One could argue that all the stuff below is not necessary for
2429 the non-bitfield case and declare it a FE error if type
2430 adjustment would be needed. */
2431 if (TREE_TYPE (expr) != type)
2433 #ifdef ENABLE_TYPES_CHECKING
2434 tree old_type = TREE_TYPE (expr);
2435 #endif
2436 int type_quals;
2438 /* We need to preserve qualifiers and propagate them from
2439 operand 0. */
2440 type_quals = TYPE_QUALS (type)
2441 | TYPE_QUALS (TREE_TYPE (TREE_OPERAND (expr, 0)));
2442 if (TYPE_QUALS (type) != type_quals)
2443 type = build_qualified_type (TYPE_MAIN_VARIANT (type), type_quals);
2445 /* Set the type of the COMPONENT_REF to the underlying type. */
2446 TREE_TYPE (expr) = type;
2448 #ifdef ENABLE_TYPES_CHECKING
2449 /* It is now a FE error, if the conversion from the canonical
2450 type to the original expression type is not useless. */
2451 gcc_assert (useless_type_conversion_p (old_type, type));
2452 #endif
2456 /* If a NOP conversion is changing a pointer to array of foo to a pointer
2457 to foo, embed that change in the ADDR_EXPR by converting
2458 T array[U];
2459 (T *)&array
2461 &array[L]
2462 where L is the lower bound. For simplicity, only do this for constant
2463 lower bound.
2464 The constraint is that the type of &array[L] is trivially convertible
2465 to T *. */
2467 static void
2468 canonicalize_addr_expr (tree *expr_p)
2470 tree expr = *expr_p;
2471 tree addr_expr = TREE_OPERAND (expr, 0);
2472 tree datype, ddatype, pddatype;
2474 /* We simplify only conversions from an ADDR_EXPR to a pointer type. */
2475 if (!POINTER_TYPE_P (TREE_TYPE (expr))
2476 || TREE_CODE (addr_expr) != ADDR_EXPR)
2477 return;
2479 /* The addr_expr type should be a pointer to an array. */
2480 datype = TREE_TYPE (TREE_TYPE (addr_expr));
2481 if (TREE_CODE (datype) != ARRAY_TYPE)
2482 return;
2484 /* The pointer to element type shall be trivially convertible to
2485 the expression pointer type. */
2486 ddatype = TREE_TYPE (datype);
2487 pddatype = build_pointer_type (ddatype);
2488 if (!useless_type_conversion_p (TYPE_MAIN_VARIANT (TREE_TYPE (expr)),
2489 pddatype))
2490 return;
2492 /* The lower bound and element sizes must be constant. */
2493 if (!TYPE_SIZE_UNIT (ddatype)
2494 || TREE_CODE (TYPE_SIZE_UNIT (ddatype)) != INTEGER_CST
2495 || !TYPE_DOMAIN (datype) || !TYPE_MIN_VALUE (TYPE_DOMAIN (datype))
2496 || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (datype))) != INTEGER_CST)
2497 return;
2499 /* All checks succeeded. Build a new node to merge the cast. */
2500 *expr_p = build4 (ARRAY_REF, ddatype, TREE_OPERAND (addr_expr, 0),
2501 TYPE_MIN_VALUE (TYPE_DOMAIN (datype)),
2502 NULL_TREE, NULL_TREE);
2503 *expr_p = build1 (ADDR_EXPR, pddatype, *expr_p);
2505 /* We can have stripped a required restrict qualifier above. */
2506 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
2507 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
2510 /* *EXPR_P is a NOP_EXPR or CONVERT_EXPR. Remove it and/or other conversions
2511 underneath as appropriate. */
2513 static enum gimplify_status
2514 gimplify_conversion (tree *expr_p)
2516 location_t loc = EXPR_LOCATION (*expr_p);
2517 gcc_assert (CONVERT_EXPR_P (*expr_p));
2519 /* Then strip away all but the outermost conversion. */
2520 STRIP_SIGN_NOPS (TREE_OPERAND (*expr_p, 0));
2522 /* And remove the outermost conversion if it's useless. */
2523 if (tree_ssa_useless_type_conversion (*expr_p))
2524 *expr_p = TREE_OPERAND (*expr_p, 0);
2526 /* If we still have a conversion at the toplevel,
2527 then canonicalize some constructs. */
2528 if (CONVERT_EXPR_P (*expr_p))
2530 tree sub = TREE_OPERAND (*expr_p, 0);
2532 /* If a NOP conversion is changing the type of a COMPONENT_REF
2533 expression, then canonicalize its type now in order to expose more
2534 redundant conversions. */
2535 if (TREE_CODE (sub) == COMPONENT_REF)
2536 canonicalize_component_ref (&TREE_OPERAND (*expr_p, 0));
2538 /* If a NOP conversion is changing a pointer to array of foo
2539 to a pointer to foo, embed that change in the ADDR_EXPR. */
2540 else if (TREE_CODE (sub) == ADDR_EXPR)
2541 canonicalize_addr_expr (expr_p);
2544 /* If we have a conversion to a non-register type force the
2545 use of a VIEW_CONVERT_EXPR instead. */
2546 if (CONVERT_EXPR_P (*expr_p) && !is_gimple_reg_type (TREE_TYPE (*expr_p)))
2547 *expr_p = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (*expr_p),
2548 TREE_OPERAND (*expr_p, 0));
2550 /* Canonicalize CONVERT_EXPR to NOP_EXPR. */
2551 if (TREE_CODE (*expr_p) == CONVERT_EXPR)
2552 TREE_SET_CODE (*expr_p, NOP_EXPR);
2554 return GS_OK;
2557 /* Nonlocal VLAs seen in the current function. */
2558 static hash_set<tree> *nonlocal_vlas;
2560 /* The VAR_DECLs created for nonlocal VLAs for debug info purposes. */
2561 static tree nonlocal_vla_vars;
2563 /* Gimplify a VAR_DECL or PARM_DECL. Return GS_OK if we expanded a
2564 DECL_VALUE_EXPR, and it's worth re-examining things. */
2566 static enum gimplify_status
2567 gimplify_var_or_parm_decl (tree *expr_p)
2569 tree decl = *expr_p;
2571 /* ??? If this is a local variable, and it has not been seen in any
2572 outer BIND_EXPR, then it's probably the result of a duplicate
2573 declaration, for which we've already issued an error. It would
2574 be really nice if the front end wouldn't leak these at all.
2575 Currently the only known culprit is C++ destructors, as seen
2576 in g++.old-deja/g++.jason/binding.C. */
2577 if (VAR_P (decl)
2578 && !DECL_SEEN_IN_BIND_EXPR_P (decl)
2579 && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl)
2580 && decl_function_context (decl) == current_function_decl)
2582 gcc_assert (seen_error ());
2583 return GS_ERROR;
2586 /* When within an OMP context, notice uses of variables. */
2587 if (gimplify_omp_ctxp && omp_notice_variable (gimplify_omp_ctxp, decl, true))
2588 return GS_ALL_DONE;
2590 /* If the decl is an alias for another expression, substitute it now. */
2591 if (DECL_HAS_VALUE_EXPR_P (decl))
2593 tree value_expr = DECL_VALUE_EXPR (decl);
2595 /* For referenced nonlocal VLAs add a decl for debugging purposes
2596 to the current function. */
2597 if (VAR_P (decl)
2598 && TREE_CODE (DECL_SIZE_UNIT (decl)) != INTEGER_CST
2599 && nonlocal_vlas != NULL
2600 && TREE_CODE (value_expr) == INDIRECT_REF
2601 && TREE_CODE (TREE_OPERAND (value_expr, 0)) == VAR_DECL
2602 && decl_function_context (decl) != current_function_decl)
2604 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
2605 while (ctx
2606 && (ctx->region_type == ORT_WORKSHARE
2607 || ctx->region_type == ORT_SIMD
2608 || ctx->region_type == ORT_ACC))
2609 ctx = ctx->outer_context;
2610 if (!ctx && !nonlocal_vlas->add (decl))
2612 tree copy = copy_node (decl);
2614 lang_hooks.dup_lang_specific_decl (copy);
2615 SET_DECL_RTL (copy, 0);
2616 TREE_USED (copy) = 1;
2617 DECL_CHAIN (copy) = nonlocal_vla_vars;
2618 nonlocal_vla_vars = copy;
2619 SET_DECL_VALUE_EXPR (copy, unshare_expr (value_expr));
2620 DECL_HAS_VALUE_EXPR_P (copy) = 1;
2624 *expr_p = unshare_expr (value_expr);
2625 return GS_OK;
2628 return GS_ALL_DONE;
2631 /* Recalculate the value of the TREE_SIDE_EFFECTS flag for T. */
2633 static void
2634 recalculate_side_effects (tree t)
2636 enum tree_code code = TREE_CODE (t);
2637 int len = TREE_OPERAND_LENGTH (t);
2638 int i;
2640 switch (TREE_CODE_CLASS (code))
2642 case tcc_expression:
2643 switch (code)
2645 case INIT_EXPR:
2646 case MODIFY_EXPR:
2647 case VA_ARG_EXPR:
2648 case PREDECREMENT_EXPR:
2649 case PREINCREMENT_EXPR:
2650 case POSTDECREMENT_EXPR:
2651 case POSTINCREMENT_EXPR:
2652 /* All of these have side-effects, no matter what their
2653 operands are. */
2654 return;
2656 default:
2657 break;
2659 /* Fall through. */
2661 case tcc_comparison: /* a comparison expression */
2662 case tcc_unary: /* a unary arithmetic expression */
2663 case tcc_binary: /* a binary arithmetic expression */
2664 case tcc_reference: /* a reference */
2665 case tcc_vl_exp: /* a function call */
2666 TREE_SIDE_EFFECTS (t) = TREE_THIS_VOLATILE (t);
2667 for (i = 0; i < len; ++i)
2669 tree op = TREE_OPERAND (t, i);
2670 if (op && TREE_SIDE_EFFECTS (op))
2671 TREE_SIDE_EFFECTS (t) = 1;
2673 break;
2675 case tcc_constant:
2676 /* No side-effects. */
2677 return;
2679 default:
2680 gcc_unreachable ();
2684 /* Gimplify the COMPONENT_REF, ARRAY_REF, REALPART_EXPR or IMAGPART_EXPR
2685 node *EXPR_P.
2687 compound_lval
2688 : min_lval '[' val ']'
2689 | min_lval '.' ID
2690 | compound_lval '[' val ']'
2691 | compound_lval '.' ID
2693 This is not part of the original SIMPLE definition, which separates
2694 array and member references, but it seems reasonable to handle them
2695 together. Also, this way we don't run into problems with union
2696 aliasing; gcc requires that for accesses through a union to alias, the
2697 union reference must be explicit, which was not always the case when we
2698 were splitting up array and member refs.
2700 PRE_P points to the sequence where side effects that must happen before
2701 *EXPR_P should be stored.
2703 POST_P points to the sequence where side effects that must happen after
2704 *EXPR_P should be stored. */
2706 static enum gimplify_status
2707 gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
2708 fallback_t fallback)
2710 tree *p;
2711 enum gimplify_status ret = GS_ALL_DONE, tret;
2712 int i;
2713 location_t loc = EXPR_LOCATION (*expr_p);
2714 tree expr = *expr_p;
2716 /* Create a stack of the subexpressions so later we can walk them in
2717 order from inner to outer. */
2718 auto_vec<tree, 10> expr_stack;
2720 /* We can handle anything that get_inner_reference can deal with. */
2721 for (p = expr_p; ; p = &TREE_OPERAND (*p, 0))
2723 restart:
2724 /* Fold INDIRECT_REFs now to turn them into ARRAY_REFs. */
2725 if (TREE_CODE (*p) == INDIRECT_REF)
2726 *p = fold_indirect_ref_loc (loc, *p);
2728 if (handled_component_p (*p))
2730 /* Expand DECL_VALUE_EXPR now. In some cases that may expose
2731 additional COMPONENT_REFs. */
2732 else if ((VAR_P (*p) || TREE_CODE (*p) == PARM_DECL)
2733 && gimplify_var_or_parm_decl (p) == GS_OK)
2734 goto restart;
2735 else
2736 break;
2738 expr_stack.safe_push (*p);
2741 gcc_assert (expr_stack.length ());
2743 /* Now EXPR_STACK is a stack of pointers to all the refs we've
2744 walked through and P points to the innermost expression.
2746 Java requires that we elaborated nodes in source order. That
2747 means we must gimplify the inner expression followed by each of
2748 the indices, in order. But we can't gimplify the inner
2749 expression until we deal with any variable bounds, sizes, or
2750 positions in order to deal with PLACEHOLDER_EXPRs.
2752 So we do this in three steps. First we deal with the annotations
2753 for any variables in the components, then we gimplify the base,
2754 then we gimplify any indices, from left to right. */
2755 for (i = expr_stack.length () - 1; i >= 0; i--)
2757 tree t = expr_stack[i];
2759 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
2761 /* Gimplify the low bound and element type size and put them into
2762 the ARRAY_REF. If these values are set, they have already been
2763 gimplified. */
2764 if (TREE_OPERAND (t, 2) == NULL_TREE)
2766 tree low = unshare_expr (array_ref_low_bound (t));
2767 if (!is_gimple_min_invariant (low))
2769 TREE_OPERAND (t, 2) = low;
2770 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
2771 post_p, is_gimple_reg,
2772 fb_rvalue);
2773 ret = MIN (ret, tret);
2776 else
2778 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
2779 is_gimple_reg, fb_rvalue);
2780 ret = MIN (ret, tret);
2783 if (TREE_OPERAND (t, 3) == NULL_TREE)
2785 tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0)));
2786 tree elmt_size = unshare_expr (array_ref_element_size (t));
2787 tree factor = size_int (TYPE_ALIGN_UNIT (elmt_type));
2789 /* Divide the element size by the alignment of the element
2790 type (above). */
2791 elmt_size
2792 = size_binop_loc (loc, EXACT_DIV_EXPR, elmt_size, factor);
2794 if (!is_gimple_min_invariant (elmt_size))
2796 TREE_OPERAND (t, 3) = elmt_size;
2797 tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p,
2798 post_p, is_gimple_reg,
2799 fb_rvalue);
2800 ret = MIN (ret, tret);
2803 else
2805 tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p, post_p,
2806 is_gimple_reg, fb_rvalue);
2807 ret = MIN (ret, tret);
2810 else if (TREE_CODE (t) == COMPONENT_REF)
2812 /* Set the field offset into T and gimplify it. */
2813 if (TREE_OPERAND (t, 2) == NULL_TREE)
2815 tree offset = unshare_expr (component_ref_field_offset (t));
2816 tree field = TREE_OPERAND (t, 1);
2817 tree factor
2818 = size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT);
2820 /* Divide the offset by its alignment. */
2821 offset = size_binop_loc (loc, EXACT_DIV_EXPR, offset, factor);
2823 if (!is_gimple_min_invariant (offset))
2825 TREE_OPERAND (t, 2) = offset;
2826 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
2827 post_p, is_gimple_reg,
2828 fb_rvalue);
2829 ret = MIN (ret, tret);
2832 else
2834 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
2835 is_gimple_reg, fb_rvalue);
2836 ret = MIN (ret, tret);
2841 /* Step 2 is to gimplify the base expression. Make sure lvalue is set
2842 so as to match the min_lval predicate. Failure to do so may result
2843 in the creation of large aggregate temporaries. */
2844 tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval,
2845 fallback | fb_lvalue);
2846 ret = MIN (ret, tret);
2848 /* And finally, the indices and operands of ARRAY_REF. During this
2849 loop we also remove any useless conversions. */
2850 for (; expr_stack.length () > 0; )
2852 tree t = expr_stack.pop ();
2854 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
2856 /* Gimplify the dimension. */
2857 if (!is_gimple_min_invariant (TREE_OPERAND (t, 1)))
2859 tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
2860 is_gimple_val, fb_rvalue);
2861 ret = MIN (ret, tret);
2865 STRIP_USELESS_TYPE_CONVERSION (TREE_OPERAND (t, 0));
2867 /* The innermost expression P may have originally had
2868 TREE_SIDE_EFFECTS set which would have caused all the outer
2869 expressions in *EXPR_P leading to P to also have had
2870 TREE_SIDE_EFFECTS set. */
2871 recalculate_side_effects (t);
2874 /* If the outermost expression is a COMPONENT_REF, canonicalize its type. */
2875 if ((fallback & fb_rvalue) && TREE_CODE (*expr_p) == COMPONENT_REF)
2877 canonicalize_component_ref (expr_p);
2880 expr_stack.release ();
2882 gcc_assert (*expr_p == expr || ret != GS_ALL_DONE);
2884 return ret;
2887 /* Gimplify the self modifying expression pointed to by EXPR_P
2888 (++, --, +=, -=).
2890 PRE_P points to the list where side effects that must happen before
2891 *EXPR_P should be stored.
2893 POST_P points to the list where side effects that must happen after
2894 *EXPR_P should be stored.
2896 WANT_VALUE is nonzero iff we want to use the value of this expression
2897 in another expression.
2899 ARITH_TYPE is the type the computation should be performed in. */
2901 enum gimplify_status
2902 gimplify_self_mod_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
2903 bool want_value, tree arith_type)
2905 enum tree_code code;
2906 tree lhs, lvalue, rhs, t1;
2907 gimple_seq post = NULL, *orig_post_p = post_p;
2908 bool postfix;
2909 enum tree_code arith_code;
2910 enum gimplify_status ret;
2911 location_t loc = EXPR_LOCATION (*expr_p);
2913 code = TREE_CODE (*expr_p);
2915 gcc_assert (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR
2916 || code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR);
2918 /* Prefix or postfix? */
2919 if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
2920 /* Faster to treat as prefix if result is not used. */
2921 postfix = want_value;
2922 else
2923 postfix = false;
2925 /* For postfix, make sure the inner expression's post side effects
2926 are executed after side effects from this expression. */
2927 if (postfix)
2928 post_p = &post;
2930 /* Add or subtract? */
2931 if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
2932 arith_code = PLUS_EXPR;
2933 else
2934 arith_code = MINUS_EXPR;
2936 /* Gimplify the LHS into a GIMPLE lvalue. */
2937 lvalue = TREE_OPERAND (*expr_p, 0);
2938 ret = gimplify_expr (&lvalue, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
2939 if (ret == GS_ERROR)
2940 return ret;
2942 /* Extract the operands to the arithmetic operation. */
2943 lhs = lvalue;
2944 rhs = TREE_OPERAND (*expr_p, 1);
2946 /* For postfix operator, we evaluate the LHS to an rvalue and then use
2947 that as the result value and in the postqueue operation. */
2948 if (postfix)
2950 ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue);
2951 if (ret == GS_ERROR)
2952 return ret;
2954 lhs = get_initialized_tmp_var (lhs, pre_p, NULL);
2957 /* For POINTERs increment, use POINTER_PLUS_EXPR. */
2958 if (POINTER_TYPE_P (TREE_TYPE (lhs)))
2960 rhs = convert_to_ptrofftype_loc (loc, rhs);
2961 if (arith_code == MINUS_EXPR)
2962 rhs = fold_build1_loc (loc, NEGATE_EXPR, TREE_TYPE (rhs), rhs);
2963 t1 = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (*expr_p), lhs, rhs);
2965 else
2966 t1 = fold_convert (TREE_TYPE (*expr_p),
2967 fold_build2 (arith_code, arith_type,
2968 fold_convert (arith_type, lhs),
2969 fold_convert (arith_type, rhs)));
2971 if (postfix)
2973 gimplify_assign (lvalue, t1, pre_p);
2974 gimplify_seq_add_seq (orig_post_p, post);
2975 *expr_p = lhs;
2976 return GS_ALL_DONE;
2978 else
2980 *expr_p = build2 (MODIFY_EXPR, TREE_TYPE (lvalue), lvalue, t1);
2981 return GS_OK;
2985 /* If *EXPR_P has a variable sized type, wrap it in a WITH_SIZE_EXPR. */
2987 static void
2988 maybe_with_size_expr (tree *expr_p)
2990 tree expr = *expr_p;
2991 tree type = TREE_TYPE (expr);
2992 tree size;
2994 /* If we've already wrapped this or the type is error_mark_node, we can't do
2995 anything. */
2996 if (TREE_CODE (expr) == WITH_SIZE_EXPR
2997 || type == error_mark_node)
2998 return;
3000 /* If the size isn't known or is a constant, we have nothing to do. */
3001 size = TYPE_SIZE_UNIT (type);
3002 if (!size || TREE_CODE (size) == INTEGER_CST)
3003 return;
3005 /* Otherwise, make a WITH_SIZE_EXPR. */
3006 size = unshare_expr (size);
3007 size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, expr);
3008 *expr_p = build2 (WITH_SIZE_EXPR, type, expr, size);
3011 /* Helper for gimplify_call_expr. Gimplify a single argument *ARG_P
3012 Store any side-effects in PRE_P. CALL_LOCATION is the location of
3013 the CALL_EXPR. If ALLOW_SSA is set the actual parameter may be
3014 gimplified to an SSA name. */
3016 enum gimplify_status
3017 gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location,
3018 bool allow_ssa)
3020 bool (*test) (tree);
3021 fallback_t fb;
3023 /* In general, we allow lvalues for function arguments to avoid
3024 extra overhead of copying large aggregates out of even larger
3025 aggregates into temporaries only to copy the temporaries to
3026 the argument list. Make optimizers happy by pulling out to
3027 temporaries those types that fit in registers. */
3028 if (is_gimple_reg_type (TREE_TYPE (*arg_p)))
3029 test = is_gimple_val, fb = fb_rvalue;
3030 else
3032 test = is_gimple_lvalue, fb = fb_either;
3033 /* Also strip a TARGET_EXPR that would force an extra copy. */
3034 if (TREE_CODE (*arg_p) == TARGET_EXPR)
3036 tree init = TARGET_EXPR_INITIAL (*arg_p);
3037 if (init
3038 && !VOID_TYPE_P (TREE_TYPE (init)))
3039 *arg_p = init;
3043 /* If this is a variable sized type, we must remember the size. */
3044 maybe_with_size_expr (arg_p);
3046 /* FIXME diagnostics: This will mess up gcc.dg/Warray-bounds.c. */
3047 /* Make sure arguments have the same location as the function call
3048 itself. */
3049 protected_set_expr_location (*arg_p, call_location);
3051 /* There is a sequence point before a function call. Side effects in
3052 the argument list must occur before the actual call. So, when
3053 gimplifying arguments, force gimplify_expr to use an internal
3054 post queue which is then appended to the end of PRE_P. */
3055 return gimplify_expr (arg_p, pre_p, NULL, test, fb, allow_ssa);
3058 /* Don't fold inside offloading or taskreg regions: it can break code by
3059 adding decl references that weren't in the source. We'll do it during
3060 omplower pass instead. */
3062 static bool
3063 maybe_fold_stmt (gimple_stmt_iterator *gsi)
3065 struct gimplify_omp_ctx *ctx;
3066 for (ctx = gimplify_omp_ctxp; ctx; ctx = ctx->outer_context)
3067 if ((ctx->region_type & (ORT_TARGET | ORT_PARALLEL | ORT_TASK)) != 0)
3068 return false;
3069 return fold_stmt (gsi);
3072 /* Gimplify the CALL_EXPR node *EXPR_P into the GIMPLE sequence PRE_P.
3073 WANT_VALUE is true if the result of the call is desired. */
3075 static enum gimplify_status
3076 gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
3078 tree fndecl, parms, p, fnptrtype;
3079 enum gimplify_status ret;
3080 int i, nargs;
3081 gcall *call;
3082 bool builtin_va_start_p = false;
3083 location_t loc = EXPR_LOCATION (*expr_p);
3085 gcc_assert (TREE_CODE (*expr_p) == CALL_EXPR);
3087 /* For reliable diagnostics during inlining, it is necessary that
3088 every call_expr be annotated with file and line. */
3089 if (! EXPR_HAS_LOCATION (*expr_p))
3090 SET_EXPR_LOCATION (*expr_p, input_location);
3092 /* Gimplify internal functions created in the FEs. */
3093 if (CALL_EXPR_FN (*expr_p) == NULL_TREE)
3095 if (want_value)
3096 return GS_ALL_DONE;
3098 nargs = call_expr_nargs (*expr_p);
3099 enum internal_fn ifn = CALL_EXPR_IFN (*expr_p);
3100 auto_vec<tree> vargs (nargs);
3102 for (i = 0; i < nargs; i++)
3104 gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
3105 EXPR_LOCATION (*expr_p));
3106 vargs.quick_push (CALL_EXPR_ARG (*expr_p, i));
3108 gimple *call = gimple_build_call_internal_vec (ifn, vargs);
3109 gimplify_seq_add_stmt (pre_p, call);
3110 return GS_ALL_DONE;
3113 /* This may be a call to a builtin function.
3115 Builtin function calls may be transformed into different
3116 (and more efficient) builtin function calls under certain
3117 circumstances. Unfortunately, gimplification can muck things
3118 up enough that the builtin expanders are not aware that certain
3119 transformations are still valid.
3121 So we attempt transformation/gimplification of the call before
3122 we gimplify the CALL_EXPR. At this time we do not manage to
3123 transform all calls in the same manner as the expanders do, but
3124 we do transform most of them. */
3125 fndecl = get_callee_fndecl (*expr_p);
3126 if (fndecl
3127 && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3128 switch (DECL_FUNCTION_CODE (fndecl))
3130 case BUILT_IN_ALLOCA:
3131 case BUILT_IN_ALLOCA_WITH_ALIGN:
3132 /* If the call has been built for a variable-sized object, then we
3133 want to restore the stack level when the enclosing BIND_EXPR is
3134 exited to reclaim the allocated space; otherwise, we precisely
3135 need to do the opposite and preserve the latest stack level. */
3136 if (CALL_ALLOCA_FOR_VAR_P (*expr_p))
3137 gimplify_ctxp->save_stack = true;
3138 else
3139 gimplify_ctxp->keep_stack = true;
3140 break;
3142 case BUILT_IN_VA_START:
3144 builtin_va_start_p = TRUE;
3145 if (call_expr_nargs (*expr_p) < 2)
3147 error ("too few arguments to function %<va_start%>");
3148 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
3149 return GS_OK;
3152 if (fold_builtin_next_arg (*expr_p, true))
3154 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
3155 return GS_OK;
3157 break;
3160 default:
3163 if (fndecl && DECL_BUILT_IN (fndecl))
3165 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
3166 if (new_tree && new_tree != *expr_p)
3168 /* There was a transformation of this call which computes the
3169 same value, but in a more efficient way. Return and try
3170 again. */
3171 *expr_p = new_tree;
3172 return GS_OK;
3176 /* Remember the original function pointer type. */
3177 fnptrtype = TREE_TYPE (CALL_EXPR_FN (*expr_p));
3179 /* There is a sequence point before the call, so any side effects in
3180 the calling expression must occur before the actual call. Force
3181 gimplify_expr to use an internal post queue. */
3182 ret = gimplify_expr (&CALL_EXPR_FN (*expr_p), pre_p, NULL,
3183 is_gimple_call_addr, fb_rvalue);
3185 nargs = call_expr_nargs (*expr_p);
3187 /* Get argument types for verification. */
3188 fndecl = get_callee_fndecl (*expr_p);
3189 parms = NULL_TREE;
3190 if (fndecl)
3191 parms = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
3192 else
3193 parms = TYPE_ARG_TYPES (TREE_TYPE (fnptrtype));
3195 if (fndecl && DECL_ARGUMENTS (fndecl))
3196 p = DECL_ARGUMENTS (fndecl);
3197 else if (parms)
3198 p = parms;
3199 else
3200 p = NULL_TREE;
3201 for (i = 0; i < nargs && p; i++, p = TREE_CHAIN (p))
3204 /* If the last argument is __builtin_va_arg_pack () and it is not
3205 passed as a named argument, decrease the number of CALL_EXPR
3206 arguments and set instead the CALL_EXPR_VA_ARG_PACK flag. */
3207 if (!p
3208 && i < nargs
3209 && TREE_CODE (CALL_EXPR_ARG (*expr_p, nargs - 1)) == CALL_EXPR)
3211 tree last_arg = CALL_EXPR_ARG (*expr_p, nargs - 1);
3212 tree last_arg_fndecl = get_callee_fndecl (last_arg);
3214 if (last_arg_fndecl
3215 && TREE_CODE (last_arg_fndecl) == FUNCTION_DECL
3216 && DECL_BUILT_IN_CLASS (last_arg_fndecl) == BUILT_IN_NORMAL
3217 && DECL_FUNCTION_CODE (last_arg_fndecl) == BUILT_IN_VA_ARG_PACK)
3219 tree call = *expr_p;
3221 --nargs;
3222 *expr_p = build_call_array_loc (loc, TREE_TYPE (call),
3223 CALL_EXPR_FN (call),
3224 nargs, CALL_EXPR_ARGP (call));
3226 /* Copy all CALL_EXPR flags, location and block, except
3227 CALL_EXPR_VA_ARG_PACK flag. */
3228 CALL_EXPR_STATIC_CHAIN (*expr_p) = CALL_EXPR_STATIC_CHAIN (call);
3229 CALL_EXPR_TAILCALL (*expr_p) = CALL_EXPR_TAILCALL (call);
3230 CALL_EXPR_RETURN_SLOT_OPT (*expr_p)
3231 = CALL_EXPR_RETURN_SLOT_OPT (call);
3232 CALL_FROM_THUNK_P (*expr_p) = CALL_FROM_THUNK_P (call);
3233 SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (call));
3235 /* Set CALL_EXPR_VA_ARG_PACK. */
3236 CALL_EXPR_VA_ARG_PACK (*expr_p) = 1;
3240 /* If the call returns twice then after building the CFG the call
3241 argument computations will no longer dominate the call because
3242 we add an abnormal incoming edge to the call. So do not use SSA
3243 vars there. */
3244 bool returns_twice = call_expr_flags (*expr_p) & ECF_RETURNS_TWICE;
3246 /* Gimplify the function arguments. */
3247 if (nargs > 0)
3249 for (i = (PUSH_ARGS_REVERSED ? nargs - 1 : 0);
3250 PUSH_ARGS_REVERSED ? i >= 0 : i < nargs;
3251 PUSH_ARGS_REVERSED ? i-- : i++)
3253 enum gimplify_status t;
3255 /* Avoid gimplifying the second argument to va_start, which needs to
3256 be the plain PARM_DECL. */
3257 if ((i != 1) || !builtin_va_start_p)
3259 t = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
3260 EXPR_LOCATION (*expr_p), ! returns_twice);
3262 if (t == GS_ERROR)
3263 ret = GS_ERROR;
3268 /* Gimplify the static chain. */
3269 if (CALL_EXPR_STATIC_CHAIN (*expr_p))
3271 if (fndecl && !DECL_STATIC_CHAIN (fndecl))
3272 CALL_EXPR_STATIC_CHAIN (*expr_p) = NULL;
3273 else
3275 enum gimplify_status t;
3276 t = gimplify_arg (&CALL_EXPR_STATIC_CHAIN (*expr_p), pre_p,
3277 EXPR_LOCATION (*expr_p), ! returns_twice);
3278 if (t == GS_ERROR)
3279 ret = GS_ERROR;
3283 /* Verify the function result. */
3284 if (want_value && fndecl
3285 && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fnptrtype))))
3287 error_at (loc, "using result of function returning %<void%>");
3288 ret = GS_ERROR;
3291 /* Try this again in case gimplification exposed something. */
3292 if (ret != GS_ERROR)
3294 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
3296 if (new_tree && new_tree != *expr_p)
3298 /* There was a transformation of this call which computes the
3299 same value, but in a more efficient way. Return and try
3300 again. */
3301 *expr_p = new_tree;
3302 return GS_OK;
3305 else
3307 *expr_p = error_mark_node;
3308 return GS_ERROR;
3311 /* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its
3312 decl. This allows us to eliminate redundant or useless
3313 calls to "const" functions. */
3314 if (TREE_CODE (*expr_p) == CALL_EXPR)
3316 int flags = call_expr_flags (*expr_p);
3317 if (flags & (ECF_CONST | ECF_PURE)
3318 /* An infinite loop is considered a side effect. */
3319 && !(flags & (ECF_LOOPING_CONST_OR_PURE)))
3320 TREE_SIDE_EFFECTS (*expr_p) = 0;
3323 /* If the value is not needed by the caller, emit a new GIMPLE_CALL
3324 and clear *EXPR_P. Otherwise, leave *EXPR_P in its gimplified
3325 form and delegate the creation of a GIMPLE_CALL to
3326 gimplify_modify_expr. This is always possible because when
3327 WANT_VALUE is true, the caller wants the result of this call into
3328 a temporary, which means that we will emit an INIT_EXPR in
3329 internal_get_tmp_var which will then be handled by
3330 gimplify_modify_expr. */
3331 if (!want_value)
3333 /* The CALL_EXPR in *EXPR_P is already in GIMPLE form, so all we
3334 have to do is replicate it as a GIMPLE_CALL tuple. */
3335 gimple_stmt_iterator gsi;
3336 call = gimple_build_call_from_tree (*expr_p);
3337 gimple_call_set_fntype (call, TREE_TYPE (fnptrtype));
3338 notice_special_calls (call);
3339 gimplify_seq_add_stmt (pre_p, call);
3340 gsi = gsi_last (*pre_p);
3341 maybe_fold_stmt (&gsi);
3342 *expr_p = NULL_TREE;
3344 else
3345 /* Remember the original function type. */
3346 CALL_EXPR_FN (*expr_p) = build1 (NOP_EXPR, fnptrtype,
3347 CALL_EXPR_FN (*expr_p));
3349 return ret;
3352 /* Handle shortcut semantics in the predicate operand of a COND_EXPR by
3353 rewriting it into multiple COND_EXPRs, and possibly GOTO_EXPRs.
3355 TRUE_LABEL_P and FALSE_LABEL_P point to the labels to jump to if the
3356 condition is true or false, respectively. If null, we should generate
3357 our own to skip over the evaluation of this specific expression.
3359 LOCUS is the source location of the COND_EXPR.
3361 This function is the tree equivalent of do_jump.
3363 shortcut_cond_r should only be called by shortcut_cond_expr. */
3365 static tree
3366 shortcut_cond_r (tree pred, tree *true_label_p, tree *false_label_p,
3367 location_t locus)
3369 tree local_label = NULL_TREE;
3370 tree t, expr = NULL;
3372 /* OK, it's not a simple case; we need to pull apart the COND_EXPR to
3373 retain the shortcut semantics. Just insert the gotos here;
3374 shortcut_cond_expr will append the real blocks later. */
3375 if (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
3377 location_t new_locus;
3379 /* Turn if (a && b) into
3381 if (a); else goto no;
3382 if (b) goto yes; else goto no;
3383 (no:) */
3385 if (false_label_p == NULL)
3386 false_label_p = &local_label;
3388 /* Keep the original source location on the first 'if'. */
3389 t = shortcut_cond_r (TREE_OPERAND (pred, 0), NULL, false_label_p, locus);
3390 append_to_statement_list (t, &expr);
3392 /* Set the source location of the && on the second 'if'. */
3393 new_locus = EXPR_HAS_LOCATION (pred) ? EXPR_LOCATION (pred) : locus;
3394 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
3395 new_locus);
3396 append_to_statement_list (t, &expr);
3398 else if (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
3400 location_t new_locus;
3402 /* Turn if (a || b) into
3404 if (a) goto yes;
3405 if (b) goto yes; else goto no;
3406 (yes:) */
3408 if (true_label_p == NULL)
3409 true_label_p = &local_label;
3411 /* Keep the original source location on the first 'if'. */
3412 t = shortcut_cond_r (TREE_OPERAND (pred, 0), true_label_p, NULL, locus);
3413 append_to_statement_list (t, &expr);
3415 /* Set the source location of the || on the second 'if'. */
3416 new_locus = EXPR_HAS_LOCATION (pred) ? EXPR_LOCATION (pred) : locus;
3417 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
3418 new_locus);
3419 append_to_statement_list (t, &expr);
3421 else if (TREE_CODE (pred) == COND_EXPR
3422 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 1)))
3423 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 2))))
3425 location_t new_locus;
3427 /* As long as we're messing with gotos, turn if (a ? b : c) into
3428 if (a)
3429 if (b) goto yes; else goto no;
3430 else
3431 if (c) goto yes; else goto no;
3433 Don't do this if one of the arms has void type, which can happen
3434 in C++ when the arm is throw. */
3436 /* Keep the original source location on the first 'if'. Set the source
3437 location of the ? on the second 'if'. */
3438 new_locus = EXPR_HAS_LOCATION (pred) ? EXPR_LOCATION (pred) : locus;
3439 expr = build3 (COND_EXPR, void_type_node, TREE_OPERAND (pred, 0),
3440 shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p,
3441 false_label_p, locus),
3442 shortcut_cond_r (TREE_OPERAND (pred, 2), true_label_p,
3443 false_label_p, new_locus));
3445 else
3447 expr = build3 (COND_EXPR, void_type_node, pred,
3448 build_and_jump (true_label_p),
3449 build_and_jump (false_label_p));
3450 SET_EXPR_LOCATION (expr, locus);
3453 if (local_label)
3455 t = build1 (LABEL_EXPR, void_type_node, local_label);
3456 append_to_statement_list (t, &expr);
3459 return expr;
3462 /* Given a conditional expression EXPR with short-circuit boolean
3463 predicates using TRUTH_ANDIF_EXPR or TRUTH_ORIF_EXPR, break the
3464 predicate apart into the equivalent sequence of conditionals. */
3466 static tree
3467 shortcut_cond_expr (tree expr)
3469 tree pred = TREE_OPERAND (expr, 0);
3470 tree then_ = TREE_OPERAND (expr, 1);
3471 tree else_ = TREE_OPERAND (expr, 2);
3472 tree true_label, false_label, end_label, t;
3473 tree *true_label_p;
3474 tree *false_label_p;
3475 bool emit_end, emit_false, jump_over_else;
3476 bool then_se = then_ && TREE_SIDE_EFFECTS (then_);
3477 bool else_se = else_ && TREE_SIDE_EFFECTS (else_);
3479 /* First do simple transformations. */
3480 if (!else_se)
3482 /* If there is no 'else', turn
3483 if (a && b) then c
3484 into
3485 if (a) if (b) then c. */
3486 while (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
3488 /* Keep the original source location on the first 'if'. */
3489 location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
3490 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
3491 /* Set the source location of the && on the second 'if'. */
3492 if (EXPR_HAS_LOCATION (pred))
3493 SET_EXPR_LOCATION (expr, EXPR_LOCATION (pred));
3494 then_ = shortcut_cond_expr (expr);
3495 then_se = then_ && TREE_SIDE_EFFECTS (then_);
3496 pred = TREE_OPERAND (pred, 0);
3497 expr = build3 (COND_EXPR, void_type_node, pred, then_, NULL_TREE);
3498 SET_EXPR_LOCATION (expr, locus);
3502 if (!then_se)
3504 /* If there is no 'then', turn
3505 if (a || b); else d
3506 into
3507 if (a); else if (b); else d. */
3508 while (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
3510 /* Keep the original source location on the first 'if'. */
3511 location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
3512 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
3513 /* Set the source location of the || on the second 'if'. */
3514 if (EXPR_HAS_LOCATION (pred))
3515 SET_EXPR_LOCATION (expr, EXPR_LOCATION (pred));
3516 else_ = shortcut_cond_expr (expr);
3517 else_se = else_ && TREE_SIDE_EFFECTS (else_);
3518 pred = TREE_OPERAND (pred, 0);
3519 expr = build3 (COND_EXPR, void_type_node, pred, NULL_TREE, else_);
3520 SET_EXPR_LOCATION (expr, locus);
3524 /* If we're done, great. */
3525 if (TREE_CODE (pred) != TRUTH_ANDIF_EXPR
3526 && TREE_CODE (pred) != TRUTH_ORIF_EXPR)
3527 return expr;
3529 /* Otherwise we need to mess with gotos. Change
3530 if (a) c; else d;
3532 if (a); else goto no;
3533 c; goto end;
3534 no: d; end:
3535 and recursively gimplify the condition. */
3537 true_label = false_label = end_label = NULL_TREE;
3539 /* If our arms just jump somewhere, hijack those labels so we don't
3540 generate jumps to jumps. */
3542 if (then_
3543 && TREE_CODE (then_) == GOTO_EXPR
3544 && TREE_CODE (GOTO_DESTINATION (then_)) == LABEL_DECL)
3546 true_label = GOTO_DESTINATION (then_);
3547 then_ = NULL;
3548 then_se = false;
3551 if (else_
3552 && TREE_CODE (else_) == GOTO_EXPR
3553 && TREE_CODE (GOTO_DESTINATION (else_)) == LABEL_DECL)
3555 false_label = GOTO_DESTINATION (else_);
3556 else_ = NULL;
3557 else_se = false;
3560 /* If we aren't hijacking a label for the 'then' branch, it falls through. */
3561 if (true_label)
3562 true_label_p = &true_label;
3563 else
3564 true_label_p = NULL;
3566 /* The 'else' branch also needs a label if it contains interesting code. */
3567 if (false_label || else_se)
3568 false_label_p = &false_label;
3569 else
3570 false_label_p = NULL;
3572 /* If there was nothing else in our arms, just forward the label(s). */
3573 if (!then_se && !else_se)
3574 return shortcut_cond_r (pred, true_label_p, false_label_p,
3575 EXPR_LOC_OR_LOC (expr, input_location));
3577 /* If our last subexpression already has a terminal label, reuse it. */
3578 if (else_se)
3579 t = expr_last (else_);
3580 else if (then_se)
3581 t = expr_last (then_);
3582 else
3583 t = NULL;
3584 if (t && TREE_CODE (t) == LABEL_EXPR)
3585 end_label = LABEL_EXPR_LABEL (t);
3587 /* If we don't care about jumping to the 'else' branch, jump to the end
3588 if the condition is false. */
3589 if (!false_label_p)
3590 false_label_p = &end_label;
3592 /* We only want to emit these labels if we aren't hijacking them. */
3593 emit_end = (end_label == NULL_TREE);
3594 emit_false = (false_label == NULL_TREE);
3596 /* We only emit the jump over the else clause if we have to--if the
3597 then clause may fall through. Otherwise we can wind up with a
3598 useless jump and a useless label at the end of gimplified code,
3599 which will cause us to think that this conditional as a whole
3600 falls through even if it doesn't. If we then inline a function
3601 which ends with such a condition, that can cause us to issue an
3602 inappropriate warning about control reaching the end of a
3603 non-void function. */
3604 jump_over_else = block_may_fallthru (then_);
3606 pred = shortcut_cond_r (pred, true_label_p, false_label_p,
3607 EXPR_LOC_OR_LOC (expr, input_location));
3609 expr = NULL;
3610 append_to_statement_list (pred, &expr);
3612 append_to_statement_list (then_, &expr);
3613 if (else_se)
3615 if (jump_over_else)
3617 tree last = expr_last (expr);
3618 t = build_and_jump (&end_label);
3619 if (EXPR_HAS_LOCATION (last))
3620 SET_EXPR_LOCATION (t, EXPR_LOCATION (last));
3621 append_to_statement_list (t, &expr);
3623 if (emit_false)
3625 t = build1 (LABEL_EXPR, void_type_node, false_label);
3626 append_to_statement_list (t, &expr);
3628 append_to_statement_list (else_, &expr);
3630 if (emit_end && end_label)
3632 t = build1 (LABEL_EXPR, void_type_node, end_label);
3633 append_to_statement_list (t, &expr);
3636 return expr;
3639 /* EXPR is used in a boolean context; make sure it has BOOLEAN_TYPE. */
3641 tree
3642 gimple_boolify (tree expr)
3644 tree type = TREE_TYPE (expr);
3645 location_t loc = EXPR_LOCATION (expr);
3647 if (TREE_CODE (expr) == NE_EXPR
3648 && TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR
3649 && integer_zerop (TREE_OPERAND (expr, 1)))
3651 tree call = TREE_OPERAND (expr, 0);
3652 tree fn = get_callee_fndecl (call);
3654 /* For __builtin_expect ((long) (x), y) recurse into x as well
3655 if x is truth_value_p. */
3656 if (fn
3657 && DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL
3658 && DECL_FUNCTION_CODE (fn) == BUILT_IN_EXPECT
3659 && call_expr_nargs (call) == 2)
3661 tree arg = CALL_EXPR_ARG (call, 0);
3662 if (arg)
3664 if (TREE_CODE (arg) == NOP_EXPR
3665 && TREE_TYPE (arg) == TREE_TYPE (call))
3666 arg = TREE_OPERAND (arg, 0);
3667 if (truth_value_p (TREE_CODE (arg)))
3669 arg = gimple_boolify (arg);
3670 CALL_EXPR_ARG (call, 0)
3671 = fold_convert_loc (loc, TREE_TYPE (call), arg);
3677 switch (TREE_CODE (expr))
3679 case TRUTH_AND_EXPR:
3680 case TRUTH_OR_EXPR:
3681 case TRUTH_XOR_EXPR:
3682 case TRUTH_ANDIF_EXPR:
3683 case TRUTH_ORIF_EXPR:
3684 /* Also boolify the arguments of truth exprs. */
3685 TREE_OPERAND (expr, 1) = gimple_boolify (TREE_OPERAND (expr, 1));
3686 /* FALLTHRU */
3688 case TRUTH_NOT_EXPR:
3689 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
3691 /* These expressions always produce boolean results. */
3692 if (TREE_CODE (type) != BOOLEAN_TYPE)
3693 TREE_TYPE (expr) = boolean_type_node;
3694 return expr;
3696 case ANNOTATE_EXPR:
3697 switch ((enum annot_expr_kind) TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)))
3699 case annot_expr_ivdep_kind:
3700 case annot_expr_no_vector_kind:
3701 case annot_expr_vector_kind:
3702 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
3703 if (TREE_CODE (type) != BOOLEAN_TYPE)
3704 TREE_TYPE (expr) = boolean_type_node;
3705 return expr;
3706 default:
3707 gcc_unreachable ();
3710 default:
3711 if (COMPARISON_CLASS_P (expr))
3713 /* There expressions always prduce boolean results. */
3714 if (TREE_CODE (type) != BOOLEAN_TYPE)
3715 TREE_TYPE (expr) = boolean_type_node;
3716 return expr;
3718 /* Other expressions that get here must have boolean values, but
3719 might need to be converted to the appropriate mode. */
3720 if (TREE_CODE (type) == BOOLEAN_TYPE)
3721 return expr;
3722 return fold_convert_loc (loc, boolean_type_node, expr);
3726 /* Given a conditional expression *EXPR_P without side effects, gimplify
3727 its operands. New statements are inserted to PRE_P. */
3729 static enum gimplify_status
3730 gimplify_pure_cond_expr (tree *expr_p, gimple_seq *pre_p)
3732 tree expr = *expr_p, cond;
3733 enum gimplify_status ret, tret;
3734 enum tree_code code;
3736 cond = gimple_boolify (COND_EXPR_COND (expr));
3738 /* We need to handle && and || specially, as their gimplification
3739 creates pure cond_expr, thus leading to an infinite cycle otherwise. */
3740 code = TREE_CODE (cond);
3741 if (code == TRUTH_ANDIF_EXPR)
3742 TREE_SET_CODE (cond, TRUTH_AND_EXPR);
3743 else if (code == TRUTH_ORIF_EXPR)
3744 TREE_SET_CODE (cond, TRUTH_OR_EXPR);
3745 ret = gimplify_expr (&cond, pre_p, NULL, is_gimple_condexpr, fb_rvalue);
3746 COND_EXPR_COND (*expr_p) = cond;
3748 tret = gimplify_expr (&COND_EXPR_THEN (expr), pre_p, NULL,
3749 is_gimple_val, fb_rvalue);
3750 ret = MIN (ret, tret);
3751 tret = gimplify_expr (&COND_EXPR_ELSE (expr), pre_p, NULL,
3752 is_gimple_val, fb_rvalue);
3754 return MIN (ret, tret);
3757 /* Return true if evaluating EXPR could trap.
3758 EXPR is GENERIC, while tree_could_trap_p can be called
3759 only on GIMPLE. */
3761 static bool
3762 generic_expr_could_trap_p (tree expr)
3764 unsigned i, n;
3766 if (!expr || is_gimple_val (expr))
3767 return false;
3769 if (!EXPR_P (expr) || tree_could_trap_p (expr))
3770 return true;
3772 n = TREE_OPERAND_LENGTH (expr);
3773 for (i = 0; i < n; i++)
3774 if (generic_expr_could_trap_p (TREE_OPERAND (expr, i)))
3775 return true;
3777 return false;
3780 /* Convert the conditional expression pointed to by EXPR_P '(p) ? a : b;'
3781 into
3783 if (p) if (p)
3784 t1 = a; a;
3785 else or else
3786 t1 = b; b;
3789 The second form is used when *EXPR_P is of type void.
3791 PRE_P points to the list where side effects that must happen before
3792 *EXPR_P should be stored. */
3794 static enum gimplify_status
3795 gimplify_cond_expr (tree *expr_p, gimple_seq *pre_p, fallback_t fallback)
3797 tree expr = *expr_p;
3798 tree type = TREE_TYPE (expr);
3799 location_t loc = EXPR_LOCATION (expr);
3800 tree tmp, arm1, arm2;
3801 enum gimplify_status ret;
3802 tree label_true, label_false, label_cont;
3803 bool have_then_clause_p, have_else_clause_p;
3804 gcond *cond_stmt;
3805 enum tree_code pred_code;
3806 gimple_seq seq = NULL;
3808 /* If this COND_EXPR has a value, copy the values into a temporary within
3809 the arms. */
3810 if (!VOID_TYPE_P (type))
3812 tree then_ = TREE_OPERAND (expr, 1), else_ = TREE_OPERAND (expr, 2);
3813 tree result;
3815 /* If either an rvalue is ok or we do not require an lvalue, create the
3816 temporary. But we cannot do that if the type is addressable. */
3817 if (((fallback & fb_rvalue) || !(fallback & fb_lvalue))
3818 && !TREE_ADDRESSABLE (type))
3820 if (gimplify_ctxp->allow_rhs_cond_expr
3821 /* If either branch has side effects or could trap, it can't be
3822 evaluated unconditionally. */
3823 && !TREE_SIDE_EFFECTS (then_)
3824 && !generic_expr_could_trap_p (then_)
3825 && !TREE_SIDE_EFFECTS (else_)
3826 && !generic_expr_could_trap_p (else_))
3827 return gimplify_pure_cond_expr (expr_p, pre_p);
3829 tmp = create_tmp_var (type, "iftmp");
3830 result = tmp;
3833 /* Otherwise, only create and copy references to the values. */
3834 else
3836 type = build_pointer_type (type);
3838 if (!VOID_TYPE_P (TREE_TYPE (then_)))
3839 then_ = build_fold_addr_expr_loc (loc, then_);
3841 if (!VOID_TYPE_P (TREE_TYPE (else_)))
3842 else_ = build_fold_addr_expr_loc (loc, else_);
3844 expr
3845 = build3 (COND_EXPR, type, TREE_OPERAND (expr, 0), then_, else_);
3847 tmp = create_tmp_var (type, "iftmp");
3848 result = build_simple_mem_ref_loc (loc, tmp);
3851 /* Build the new then clause, `tmp = then_;'. But don't build the
3852 assignment if the value is void; in C++ it can be if it's a throw. */
3853 if (!VOID_TYPE_P (TREE_TYPE (then_)))
3854 TREE_OPERAND (expr, 1) = build2 (MODIFY_EXPR, type, tmp, then_);
3856 /* Similarly, build the new else clause, `tmp = else_;'. */
3857 if (!VOID_TYPE_P (TREE_TYPE (else_)))
3858 TREE_OPERAND (expr, 2) = build2 (MODIFY_EXPR, type, tmp, else_);
3860 TREE_TYPE (expr) = void_type_node;
3861 recalculate_side_effects (expr);
3863 /* Move the COND_EXPR to the prequeue. */
3864 gimplify_stmt (&expr, pre_p);
3866 *expr_p = result;
3867 return GS_ALL_DONE;
3870 /* Remove any COMPOUND_EXPR so the following cases will be caught. */
3871 STRIP_TYPE_NOPS (TREE_OPERAND (expr, 0));
3872 if (TREE_CODE (TREE_OPERAND (expr, 0)) == COMPOUND_EXPR)
3873 gimplify_compound_expr (&TREE_OPERAND (expr, 0), pre_p, true);
3875 /* Make sure the condition has BOOLEAN_TYPE. */
3876 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
3878 /* Break apart && and || conditions. */
3879 if (TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ANDIF_EXPR
3880 || TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ORIF_EXPR)
3882 expr = shortcut_cond_expr (expr);
3884 if (expr != *expr_p)
3886 *expr_p = expr;
3888 /* We can't rely on gimplify_expr to re-gimplify the expanded
3889 form properly, as cleanups might cause the target labels to be
3890 wrapped in a TRY_FINALLY_EXPR. To prevent that, we need to
3891 set up a conditional context. */
3892 gimple_push_condition ();
3893 gimplify_stmt (expr_p, &seq);
3894 gimple_pop_condition (pre_p);
3895 gimple_seq_add_seq (pre_p, seq);
3897 return GS_ALL_DONE;
3901 /* Now do the normal gimplification. */
3903 /* Gimplify condition. */
3904 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL, is_gimple_condexpr,
3905 fb_rvalue);
3906 if (ret == GS_ERROR)
3907 return GS_ERROR;
3908 gcc_assert (TREE_OPERAND (expr, 0) != NULL_TREE);
3910 gimple_push_condition ();
3912 have_then_clause_p = have_else_clause_p = false;
3913 if (TREE_OPERAND (expr, 1) != NULL
3914 && TREE_CODE (TREE_OPERAND (expr, 1)) == GOTO_EXPR
3915 && TREE_CODE (GOTO_DESTINATION (TREE_OPERAND (expr, 1))) == LABEL_DECL
3916 && (DECL_CONTEXT (GOTO_DESTINATION (TREE_OPERAND (expr, 1)))
3917 == current_function_decl)
3918 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
3919 have different locations, otherwise we end up with incorrect
3920 location information on the branches. */
3921 && (optimize
3922 || !EXPR_HAS_LOCATION (expr)
3923 || !EXPR_HAS_LOCATION (TREE_OPERAND (expr, 1))
3924 || EXPR_LOCATION (expr) == EXPR_LOCATION (TREE_OPERAND (expr, 1))))
3926 label_true = GOTO_DESTINATION (TREE_OPERAND (expr, 1));
3927 have_then_clause_p = true;
3929 else
3930 label_true = create_artificial_label (UNKNOWN_LOCATION);
3931 if (TREE_OPERAND (expr, 2) != NULL
3932 && TREE_CODE (TREE_OPERAND (expr, 2)) == GOTO_EXPR
3933 && TREE_CODE (GOTO_DESTINATION (TREE_OPERAND (expr, 2))) == LABEL_DECL
3934 && (DECL_CONTEXT (GOTO_DESTINATION (TREE_OPERAND (expr, 2)))
3935 == current_function_decl)
3936 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
3937 have different locations, otherwise we end up with incorrect
3938 location information on the branches. */
3939 && (optimize
3940 || !EXPR_HAS_LOCATION (expr)
3941 || !EXPR_HAS_LOCATION (TREE_OPERAND (expr, 2))
3942 || EXPR_LOCATION (expr) == EXPR_LOCATION (TREE_OPERAND (expr, 2))))
3944 label_false = GOTO_DESTINATION (TREE_OPERAND (expr, 2));
3945 have_else_clause_p = true;
3947 else
3948 label_false = create_artificial_label (UNKNOWN_LOCATION);
3950 gimple_cond_get_ops_from_tree (COND_EXPR_COND (expr), &pred_code, &arm1,
3951 &arm2);
3952 cond_stmt = gimple_build_cond (pred_code, arm1, arm2, label_true,
3953 label_false);
3954 gimple_set_no_warning (cond_stmt, TREE_NO_WARNING (COND_EXPR_COND (expr)));
3955 gimplify_seq_add_stmt (&seq, cond_stmt);
3956 gimple_stmt_iterator gsi = gsi_last (seq);
3957 maybe_fold_stmt (&gsi);
3959 label_cont = NULL_TREE;
3960 if (!have_then_clause_p)
3962 /* For if (...) {} else { code; } put label_true after
3963 the else block. */
3964 if (TREE_OPERAND (expr, 1) == NULL_TREE
3965 && !have_else_clause_p
3966 && TREE_OPERAND (expr, 2) != NULL_TREE)
3967 label_cont = label_true;
3968 else
3970 gimplify_seq_add_stmt (&seq, gimple_build_label (label_true));
3971 have_then_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 1), &seq);
3972 /* For if (...) { code; } else {} or
3973 if (...) { code; } else goto label; or
3974 if (...) { code; return; } else { ... }
3975 label_cont isn't needed. */
3976 if (!have_else_clause_p
3977 && TREE_OPERAND (expr, 2) != NULL_TREE
3978 && gimple_seq_may_fallthru (seq))
3980 gimple *g;
3981 label_cont = create_artificial_label (UNKNOWN_LOCATION);
3983 g = gimple_build_goto (label_cont);
3985 /* GIMPLE_COND's are very low level; they have embedded
3986 gotos. This particular embedded goto should not be marked
3987 with the location of the original COND_EXPR, as it would
3988 correspond to the COND_EXPR's condition, not the ELSE or the
3989 THEN arms. To avoid marking it with the wrong location, flag
3990 it as "no location". */
3991 gimple_set_do_not_emit_location (g);
3993 gimplify_seq_add_stmt (&seq, g);
3997 if (!have_else_clause_p)
3999 gimplify_seq_add_stmt (&seq, gimple_build_label (label_false));
4000 have_else_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 2), &seq);
4002 if (label_cont)
4003 gimplify_seq_add_stmt (&seq, gimple_build_label (label_cont));
4005 gimple_pop_condition (pre_p);
4006 gimple_seq_add_seq (pre_p, seq);
4008 if (ret == GS_ERROR)
4009 ; /* Do nothing. */
4010 else if (have_then_clause_p || have_else_clause_p)
4011 ret = GS_ALL_DONE;
4012 else
4014 /* Both arms are empty; replace the COND_EXPR with its predicate. */
4015 expr = TREE_OPERAND (expr, 0);
4016 gimplify_stmt (&expr, pre_p);
4019 *expr_p = NULL;
4020 return ret;
4023 /* Prepare the node pointed to by EXPR_P, an is_gimple_addressable expression,
4024 to be marked addressable.
4026 We cannot rely on such an expression being directly markable if a temporary
4027 has been created by the gimplification. In this case, we create another
4028 temporary and initialize it with a copy, which will become a store after we
4029 mark it addressable. This can happen if the front-end passed us something
4030 that it could not mark addressable yet, like a Fortran pass-by-reference
4031 parameter (int) floatvar. */
4033 static void
4034 prepare_gimple_addressable (tree *expr_p, gimple_seq *seq_p)
4036 while (handled_component_p (*expr_p))
4037 expr_p = &TREE_OPERAND (*expr_p, 0);
4038 if (is_gimple_reg (*expr_p))
4040 /* Do not allow an SSA name as the temporary. */
4041 tree var = get_initialized_tmp_var (*expr_p, seq_p, NULL, false);
4042 DECL_GIMPLE_REG_P (var) = 0;
4043 *expr_p = var;
4047 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4048 a call to __builtin_memcpy. */
4050 static enum gimplify_status
4051 gimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value,
4052 gimple_seq *seq_p)
4054 tree t, to, to_ptr, from, from_ptr;
4055 gcall *gs;
4056 location_t loc = EXPR_LOCATION (*expr_p);
4058 to = TREE_OPERAND (*expr_p, 0);
4059 from = TREE_OPERAND (*expr_p, 1);
4061 /* Mark the RHS addressable. Beware that it may not be possible to do so
4062 directly if a temporary has been created by the gimplification. */
4063 prepare_gimple_addressable (&from, seq_p);
4065 mark_addressable (from);
4066 from_ptr = build_fold_addr_expr_loc (loc, from);
4067 gimplify_arg (&from_ptr, seq_p, loc);
4069 mark_addressable (to);
4070 to_ptr = build_fold_addr_expr_loc (loc, to);
4071 gimplify_arg (&to_ptr, seq_p, loc);
4073 t = builtin_decl_implicit (BUILT_IN_MEMCPY);
4075 gs = gimple_build_call (t, 3, to_ptr, from_ptr, size);
4077 if (want_value)
4079 /* tmp = memcpy() */
4080 t = create_tmp_var (TREE_TYPE (to_ptr));
4081 gimple_call_set_lhs (gs, t);
4082 gimplify_seq_add_stmt (seq_p, gs);
4084 *expr_p = build_simple_mem_ref (t);
4085 return GS_ALL_DONE;
4088 gimplify_seq_add_stmt (seq_p, gs);
4089 *expr_p = NULL;
4090 return GS_ALL_DONE;
4093 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4094 a call to __builtin_memset. In this case we know that the RHS is
4095 a CONSTRUCTOR with an empty element list. */
4097 static enum gimplify_status
4098 gimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value,
4099 gimple_seq *seq_p)
4101 tree t, from, to, to_ptr;
4102 gcall *gs;
4103 location_t loc = EXPR_LOCATION (*expr_p);
4105 /* Assert our assumptions, to abort instead of producing wrong code
4106 silently if they are not met. Beware that the RHS CONSTRUCTOR might
4107 not be immediately exposed. */
4108 from = TREE_OPERAND (*expr_p, 1);
4109 if (TREE_CODE (from) == WITH_SIZE_EXPR)
4110 from = TREE_OPERAND (from, 0);
4112 gcc_assert (TREE_CODE (from) == CONSTRUCTOR
4113 && vec_safe_is_empty (CONSTRUCTOR_ELTS (from)));
4115 /* Now proceed. */
4116 to = TREE_OPERAND (*expr_p, 0);
4118 to_ptr = build_fold_addr_expr_loc (loc, to);
4119 gimplify_arg (&to_ptr, seq_p, loc);
4120 t = builtin_decl_implicit (BUILT_IN_MEMSET);
4122 gs = gimple_build_call (t, 3, to_ptr, integer_zero_node, size);
4124 if (want_value)
4126 /* tmp = memset() */
4127 t = create_tmp_var (TREE_TYPE (to_ptr));
4128 gimple_call_set_lhs (gs, t);
4129 gimplify_seq_add_stmt (seq_p, gs);
4131 *expr_p = build1 (INDIRECT_REF, TREE_TYPE (to), t);
4132 return GS_ALL_DONE;
4135 gimplify_seq_add_stmt (seq_p, gs);
4136 *expr_p = NULL;
4137 return GS_ALL_DONE;
4140 /* A subroutine of gimplify_init_ctor_preeval. Called via walk_tree,
4141 determine, cautiously, if a CONSTRUCTOR overlaps the lhs of an
4142 assignment. Return non-null if we detect a potential overlap. */
4144 struct gimplify_init_ctor_preeval_data
4146 /* The base decl of the lhs object. May be NULL, in which case we
4147 have to assume the lhs is indirect. */
4148 tree lhs_base_decl;
4150 /* The alias set of the lhs object. */
4151 alias_set_type lhs_alias_set;
4154 static tree
4155 gimplify_init_ctor_preeval_1 (tree *tp, int *walk_subtrees, void *xdata)
4157 struct gimplify_init_ctor_preeval_data *data
4158 = (struct gimplify_init_ctor_preeval_data *) xdata;
4159 tree t = *tp;
4161 /* If we find the base object, obviously we have overlap. */
4162 if (data->lhs_base_decl == t)
4163 return t;
4165 /* If the constructor component is indirect, determine if we have a
4166 potential overlap with the lhs. The only bits of information we
4167 have to go on at this point are addressability and alias sets. */
4168 if ((INDIRECT_REF_P (t)
4169 || TREE_CODE (t) == MEM_REF)
4170 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
4171 && alias_sets_conflict_p (data->lhs_alias_set, get_alias_set (t)))
4172 return t;
4174 /* If the constructor component is a call, determine if it can hide a
4175 potential overlap with the lhs through an INDIRECT_REF like above.
4176 ??? Ugh - this is completely broken. In fact this whole analysis
4177 doesn't look conservative. */
4178 if (TREE_CODE (t) == CALL_EXPR)
4180 tree type, fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (t)));
4182 for (type = TYPE_ARG_TYPES (fntype); type; type = TREE_CHAIN (type))
4183 if (POINTER_TYPE_P (TREE_VALUE (type))
4184 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
4185 && alias_sets_conflict_p (data->lhs_alias_set,
4186 get_alias_set
4187 (TREE_TYPE (TREE_VALUE (type)))))
4188 return t;
4191 if (IS_TYPE_OR_DECL_P (t))
4192 *walk_subtrees = 0;
4193 return NULL;
4196 /* A subroutine of gimplify_init_constructor. Pre-evaluate EXPR,
4197 force values that overlap with the lhs (as described by *DATA)
4198 into temporaries. */
4200 static void
4201 gimplify_init_ctor_preeval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
4202 struct gimplify_init_ctor_preeval_data *data)
4204 enum gimplify_status one;
4206 /* If the value is constant, then there's nothing to pre-evaluate. */
4207 if (TREE_CONSTANT (*expr_p))
4209 /* Ensure it does not have side effects, it might contain a reference to
4210 the object we're initializing. */
4211 gcc_assert (!TREE_SIDE_EFFECTS (*expr_p));
4212 return;
4215 /* If the type has non-trivial constructors, we can't pre-evaluate. */
4216 if (TREE_ADDRESSABLE (TREE_TYPE (*expr_p)))
4217 return;
4219 /* Recurse for nested constructors. */
4220 if (TREE_CODE (*expr_p) == CONSTRUCTOR)
4222 unsigned HOST_WIDE_INT ix;
4223 constructor_elt *ce;
4224 vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (*expr_p);
4226 FOR_EACH_VEC_SAFE_ELT (v, ix, ce)
4227 gimplify_init_ctor_preeval (&ce->value, pre_p, post_p, data);
4229 return;
4232 /* If this is a variable sized type, we must remember the size. */
4233 maybe_with_size_expr (expr_p);
4235 /* Gimplify the constructor element to something appropriate for the rhs
4236 of a MODIFY_EXPR. Given that we know the LHS is an aggregate, we know
4237 the gimplifier will consider this a store to memory. Doing this
4238 gimplification now means that we won't have to deal with complicated
4239 language-specific trees, nor trees like SAVE_EXPR that can induce
4240 exponential search behavior. */
4241 one = gimplify_expr (expr_p, pre_p, post_p, is_gimple_mem_rhs, fb_rvalue);
4242 if (one == GS_ERROR)
4244 *expr_p = NULL;
4245 return;
4248 /* If we gimplified to a bare decl, we can be sure that it doesn't overlap
4249 with the lhs, since "a = { .x=a }" doesn't make sense. This will
4250 always be true for all scalars, since is_gimple_mem_rhs insists on a
4251 temporary variable for them. */
4252 if (DECL_P (*expr_p))
4253 return;
4255 /* If this is of variable size, we have no choice but to assume it doesn't
4256 overlap since we can't make a temporary for it. */
4257 if (TREE_CODE (TYPE_SIZE (TREE_TYPE (*expr_p))) != INTEGER_CST)
4258 return;
4260 /* Otherwise, we must search for overlap ... */
4261 if (!walk_tree (expr_p, gimplify_init_ctor_preeval_1, data, NULL))
4262 return;
4264 /* ... and if found, force the value into a temporary. */
4265 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
4268 /* A subroutine of gimplify_init_ctor_eval. Create a loop for
4269 a RANGE_EXPR in a CONSTRUCTOR for an array.
4271 var = lower;
4272 loop_entry:
4273 object[var] = value;
4274 if (var == upper)
4275 goto loop_exit;
4276 var = var + 1;
4277 goto loop_entry;
4278 loop_exit:
4280 We increment var _after_ the loop exit check because we might otherwise
4281 fail if upper == TYPE_MAX_VALUE (type for upper).
4283 Note that we never have to deal with SAVE_EXPRs here, because this has
4284 already been taken care of for us, in gimplify_init_ctor_preeval(). */
4286 static void gimplify_init_ctor_eval (tree, vec<constructor_elt, va_gc> *,
4287 gimple_seq *, bool);
4289 static void
4290 gimplify_init_ctor_eval_range (tree object, tree lower, tree upper,
4291 tree value, tree array_elt_type,
4292 gimple_seq *pre_p, bool cleared)
4294 tree loop_entry_label, loop_exit_label, fall_thru_label;
4295 tree var, var_type, cref, tmp;
4297 loop_entry_label = create_artificial_label (UNKNOWN_LOCATION);
4298 loop_exit_label = create_artificial_label (UNKNOWN_LOCATION);
4299 fall_thru_label = create_artificial_label (UNKNOWN_LOCATION);
4301 /* Create and initialize the index variable. */
4302 var_type = TREE_TYPE (upper);
4303 var = create_tmp_var (var_type);
4304 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, lower));
4306 /* Add the loop entry label. */
4307 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_entry_label));
4309 /* Build the reference. */
4310 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
4311 var, NULL_TREE, NULL_TREE);
4313 /* If we are a constructor, just call gimplify_init_ctor_eval to do
4314 the store. Otherwise just assign value to the reference. */
4316 if (TREE_CODE (value) == CONSTRUCTOR)
4317 /* NB we might have to call ourself recursively through
4318 gimplify_init_ctor_eval if the value is a constructor. */
4319 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
4320 pre_p, cleared);
4321 else
4322 gimplify_seq_add_stmt (pre_p, gimple_build_assign (cref, value));
4324 /* We exit the loop when the index var is equal to the upper bound. */
4325 gimplify_seq_add_stmt (pre_p,
4326 gimple_build_cond (EQ_EXPR, var, upper,
4327 loop_exit_label, fall_thru_label));
4329 gimplify_seq_add_stmt (pre_p, gimple_build_label (fall_thru_label));
4331 /* Otherwise, increment the index var... */
4332 tmp = build2 (PLUS_EXPR, var_type, var,
4333 fold_convert (var_type, integer_one_node));
4334 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, tmp));
4336 /* ...and jump back to the loop entry. */
4337 gimplify_seq_add_stmt (pre_p, gimple_build_goto (loop_entry_label));
4339 /* Add the loop exit label. */
4340 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_exit_label));
4343 /* Return true if FDECL is accessing a field that is zero sized. */
4345 static bool
4346 zero_sized_field_decl (const_tree fdecl)
4348 if (TREE_CODE (fdecl) == FIELD_DECL && DECL_SIZE (fdecl)
4349 && integer_zerop (DECL_SIZE (fdecl)))
4350 return true;
4351 return false;
4354 /* Return true if TYPE is zero sized. */
4356 static bool
4357 zero_sized_type (const_tree type)
4359 if (AGGREGATE_TYPE_P (type) && TYPE_SIZE (type)
4360 && integer_zerop (TYPE_SIZE (type)))
4361 return true;
4362 return false;
4365 /* A subroutine of gimplify_init_constructor. Generate individual
4366 MODIFY_EXPRs for a CONSTRUCTOR. OBJECT is the LHS against which the
4367 assignments should happen. ELTS is the CONSTRUCTOR_ELTS of the
4368 CONSTRUCTOR. CLEARED is true if the entire LHS object has been
4369 zeroed first. */
4371 static void
4372 gimplify_init_ctor_eval (tree object, vec<constructor_elt, va_gc> *elts,
4373 gimple_seq *pre_p, bool cleared)
4375 tree array_elt_type = NULL;
4376 unsigned HOST_WIDE_INT ix;
4377 tree purpose, value;
4379 if (TREE_CODE (TREE_TYPE (object)) == ARRAY_TYPE)
4380 array_elt_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (object)));
4382 FOR_EACH_CONSTRUCTOR_ELT (elts, ix, purpose, value)
4384 tree cref;
4386 /* NULL values are created above for gimplification errors. */
4387 if (value == NULL)
4388 continue;
4390 if (cleared && initializer_zerop (value))
4391 continue;
4393 /* ??? Here's to hoping the front end fills in all of the indices,
4394 so we don't have to figure out what's missing ourselves. */
4395 gcc_assert (purpose);
4397 /* Skip zero-sized fields, unless value has side-effects. This can
4398 happen with calls to functions returning a zero-sized type, which
4399 we shouldn't discard. As a number of downstream passes don't
4400 expect sets of zero-sized fields, we rely on the gimplification of
4401 the MODIFY_EXPR we make below to drop the assignment statement. */
4402 if (! TREE_SIDE_EFFECTS (value) && zero_sized_field_decl (purpose))
4403 continue;
4405 /* If we have a RANGE_EXPR, we have to build a loop to assign the
4406 whole range. */
4407 if (TREE_CODE (purpose) == RANGE_EXPR)
4409 tree lower = TREE_OPERAND (purpose, 0);
4410 tree upper = TREE_OPERAND (purpose, 1);
4412 /* If the lower bound is equal to upper, just treat it as if
4413 upper was the index. */
4414 if (simple_cst_equal (lower, upper))
4415 purpose = upper;
4416 else
4418 gimplify_init_ctor_eval_range (object, lower, upper, value,
4419 array_elt_type, pre_p, cleared);
4420 continue;
4424 if (array_elt_type)
4426 /* Do not use bitsizetype for ARRAY_REF indices. */
4427 if (TYPE_DOMAIN (TREE_TYPE (object)))
4428 purpose
4429 = fold_convert (TREE_TYPE (TYPE_DOMAIN (TREE_TYPE (object))),
4430 purpose);
4431 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
4432 purpose, NULL_TREE, NULL_TREE);
4434 else
4436 gcc_assert (TREE_CODE (purpose) == FIELD_DECL);
4437 cref = build3 (COMPONENT_REF, TREE_TYPE (purpose),
4438 unshare_expr (object), purpose, NULL_TREE);
4441 if (TREE_CODE (value) == CONSTRUCTOR
4442 && TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE)
4443 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
4444 pre_p, cleared);
4445 else
4447 tree init = build2 (INIT_EXPR, TREE_TYPE (cref), cref, value);
4448 gimplify_and_add (init, pre_p);
4449 ggc_free (init);
4454 /* Return the appropriate RHS predicate for this LHS. */
4456 gimple_predicate
4457 rhs_predicate_for (tree lhs)
4459 if (is_gimple_reg (lhs))
4460 return is_gimple_reg_rhs_or_call;
4461 else
4462 return is_gimple_mem_rhs_or_call;
4465 /* Return the initial guess for an appropriate RHS predicate for this LHS,
4466 before the LHS has been gimplified. */
4468 static gimple_predicate
4469 initial_rhs_predicate_for (tree lhs)
4471 if (is_gimple_reg_type (TREE_TYPE (lhs)))
4472 return is_gimple_reg_rhs_or_call;
4473 else
4474 return is_gimple_mem_rhs_or_call;
4477 /* Gimplify a C99 compound literal expression. This just means adding
4478 the DECL_EXPR before the current statement and using its anonymous
4479 decl instead. */
4481 static enum gimplify_status
4482 gimplify_compound_literal_expr (tree *expr_p, gimple_seq *pre_p,
4483 bool (*gimple_test_f) (tree),
4484 fallback_t fallback)
4486 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (*expr_p);
4487 tree decl = DECL_EXPR_DECL (decl_s);
4488 tree init = DECL_INITIAL (decl);
4489 /* Mark the decl as addressable if the compound literal
4490 expression is addressable now, otherwise it is marked too late
4491 after we gimplify the initialization expression. */
4492 if (TREE_ADDRESSABLE (*expr_p))
4493 TREE_ADDRESSABLE (decl) = 1;
4494 /* Otherwise, if we don't need an lvalue and have a literal directly
4495 substitute it. Check if it matches the gimple predicate, as
4496 otherwise we'd generate a new temporary, and we can as well just
4497 use the decl we already have. */
4498 else if (!TREE_ADDRESSABLE (decl)
4499 && init
4500 && (fallback & fb_lvalue) == 0
4501 && gimple_test_f (init))
4503 *expr_p = init;
4504 return GS_OK;
4507 /* Preliminarily mark non-addressed complex variables as eligible
4508 for promotion to gimple registers. We'll transform their uses
4509 as we find them. */
4510 if ((TREE_CODE (TREE_TYPE (decl)) == COMPLEX_TYPE
4511 || TREE_CODE (TREE_TYPE (decl)) == VECTOR_TYPE)
4512 && !TREE_THIS_VOLATILE (decl)
4513 && !needs_to_live_in_memory (decl))
4514 DECL_GIMPLE_REG_P (decl) = 1;
4516 /* If the decl is not addressable, then it is being used in some
4517 expression or on the right hand side of a statement, and it can
4518 be put into a readonly data section. */
4519 if (!TREE_ADDRESSABLE (decl) && (fallback & fb_lvalue) == 0)
4520 TREE_READONLY (decl) = 1;
4522 /* This decl isn't mentioned in the enclosing block, so add it to the
4523 list of temps. FIXME it seems a bit of a kludge to say that
4524 anonymous artificial vars aren't pushed, but everything else is. */
4525 if (DECL_NAME (decl) == NULL_TREE && !DECL_SEEN_IN_BIND_EXPR_P (decl))
4526 gimple_add_tmp_var (decl);
4528 gimplify_and_add (decl_s, pre_p);
4529 *expr_p = decl;
4530 return GS_OK;
4533 /* Optimize embedded COMPOUND_LITERAL_EXPRs within a CONSTRUCTOR,
4534 return a new CONSTRUCTOR if something changed. */
4536 static tree
4537 optimize_compound_literals_in_ctor (tree orig_ctor)
4539 tree ctor = orig_ctor;
4540 vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ctor);
4541 unsigned int idx, num = vec_safe_length (elts);
4543 for (idx = 0; idx < num; idx++)
4545 tree value = (*elts)[idx].value;
4546 tree newval = value;
4547 if (TREE_CODE (value) == CONSTRUCTOR)
4548 newval = optimize_compound_literals_in_ctor (value);
4549 else if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR)
4551 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (value);
4552 tree decl = DECL_EXPR_DECL (decl_s);
4553 tree init = DECL_INITIAL (decl);
4555 if (!TREE_ADDRESSABLE (value)
4556 && !TREE_ADDRESSABLE (decl)
4557 && init
4558 && TREE_CODE (init) == CONSTRUCTOR)
4559 newval = optimize_compound_literals_in_ctor (init);
4561 if (newval == value)
4562 continue;
4564 if (ctor == orig_ctor)
4566 ctor = copy_node (orig_ctor);
4567 CONSTRUCTOR_ELTS (ctor) = vec_safe_copy (elts);
4568 elts = CONSTRUCTOR_ELTS (ctor);
4570 (*elts)[idx].value = newval;
4572 return ctor;
4575 /* A subroutine of gimplify_modify_expr. Break out elements of a
4576 CONSTRUCTOR used as an initializer into separate MODIFY_EXPRs.
4578 Note that we still need to clear any elements that don't have explicit
4579 initializers, so if not all elements are initialized we keep the
4580 original MODIFY_EXPR, we just remove all of the constructor elements.
4582 If NOTIFY_TEMP_CREATION is true, do not gimplify, just return
4583 GS_ERROR if we would have to create a temporary when gimplifying
4584 this constructor. Otherwise, return GS_OK.
4586 If NOTIFY_TEMP_CREATION is false, just do the gimplification. */
4588 static enum gimplify_status
4589 gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
4590 bool want_value, bool notify_temp_creation)
4592 tree object, ctor, type;
4593 enum gimplify_status ret;
4594 vec<constructor_elt, va_gc> *elts;
4596 gcc_assert (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == CONSTRUCTOR);
4598 if (!notify_temp_creation)
4600 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
4601 is_gimple_lvalue, fb_lvalue);
4602 if (ret == GS_ERROR)
4603 return ret;
4606 object = TREE_OPERAND (*expr_p, 0);
4607 ctor = TREE_OPERAND (*expr_p, 1)
4608 = optimize_compound_literals_in_ctor (TREE_OPERAND (*expr_p, 1));
4609 type = TREE_TYPE (ctor);
4610 elts = CONSTRUCTOR_ELTS (ctor);
4611 ret = GS_ALL_DONE;
4613 switch (TREE_CODE (type))
4615 case RECORD_TYPE:
4616 case UNION_TYPE:
4617 case QUAL_UNION_TYPE:
4618 case ARRAY_TYPE:
4620 struct gimplify_init_ctor_preeval_data preeval_data;
4621 HOST_WIDE_INT num_ctor_elements, num_nonzero_elements;
4622 bool cleared, complete_p, valid_const_initializer;
4624 /* Aggregate types must lower constructors to initialization of
4625 individual elements. The exception is that a CONSTRUCTOR node
4626 with no elements indicates zero-initialization of the whole. */
4627 if (vec_safe_is_empty (elts))
4629 if (notify_temp_creation)
4630 return GS_OK;
4631 break;
4634 /* Fetch information about the constructor to direct later processing.
4635 We might want to make static versions of it in various cases, and
4636 can only do so if it known to be a valid constant initializer. */
4637 valid_const_initializer
4638 = categorize_ctor_elements (ctor, &num_nonzero_elements,
4639 &num_ctor_elements, &complete_p);
4641 /* If a const aggregate variable is being initialized, then it
4642 should never be a lose to promote the variable to be static. */
4643 if (valid_const_initializer
4644 && num_nonzero_elements > 1
4645 && TREE_READONLY (object)
4646 && VAR_P (object)
4647 && (flag_merge_constants >= 2 || !TREE_ADDRESSABLE (object)))
4649 if (notify_temp_creation)
4650 return GS_ERROR;
4651 DECL_INITIAL (object) = ctor;
4652 TREE_STATIC (object) = 1;
4653 if (!DECL_NAME (object))
4654 DECL_NAME (object) = create_tmp_var_name ("C");
4655 walk_tree (&DECL_INITIAL (object), force_labels_r, NULL, NULL);
4657 /* ??? C++ doesn't automatically append a .<number> to the
4658 assembler name, and even when it does, it looks at FE private
4659 data structures to figure out what that number should be,
4660 which are not set for this variable. I suppose this is
4661 important for local statics for inline functions, which aren't
4662 "local" in the object file sense. So in order to get a unique
4663 TU-local symbol, we must invoke the lhd version now. */
4664 lhd_set_decl_assembler_name (object);
4666 *expr_p = NULL_TREE;
4667 break;
4670 /* If there are "lots" of initialized elements, even discounting
4671 those that are not address constants (and thus *must* be
4672 computed at runtime), then partition the constructor into
4673 constant and non-constant parts. Block copy the constant
4674 parts in, then generate code for the non-constant parts. */
4675 /* TODO. There's code in cp/typeck.c to do this. */
4677 if (int_size_in_bytes (TREE_TYPE (ctor)) < 0)
4678 /* store_constructor will ignore the clearing of variable-sized
4679 objects. Initializers for such objects must explicitly set
4680 every field that needs to be set. */
4681 cleared = false;
4682 else if (!complete_p && !CONSTRUCTOR_NO_CLEARING (ctor))
4683 /* If the constructor isn't complete, clear the whole object
4684 beforehand, unless CONSTRUCTOR_NO_CLEARING is set on it.
4686 ??? This ought not to be needed. For any element not present
4687 in the initializer, we should simply set them to zero. Except
4688 we'd need to *find* the elements that are not present, and that
4689 requires trickery to avoid quadratic compile-time behavior in
4690 large cases or excessive memory use in small cases. */
4691 cleared = true;
4692 else if (num_ctor_elements - num_nonzero_elements
4693 > CLEAR_RATIO (optimize_function_for_speed_p (cfun))
4694 && num_nonzero_elements < num_ctor_elements / 4)
4695 /* If there are "lots" of zeros, it's more efficient to clear
4696 the memory and then set the nonzero elements. */
4697 cleared = true;
4698 else
4699 cleared = false;
4701 /* If there are "lots" of initialized elements, and all of them
4702 are valid address constants, then the entire initializer can
4703 be dropped to memory, and then memcpy'd out. Don't do this
4704 for sparse arrays, though, as it's more efficient to follow
4705 the standard CONSTRUCTOR behavior of memset followed by
4706 individual element initialization. Also don't do this for small
4707 all-zero initializers (which aren't big enough to merit
4708 clearing), and don't try to make bitwise copies of
4709 TREE_ADDRESSABLE types.
4711 We cannot apply such transformation when compiling chkp static
4712 initializer because creation of initializer image in the memory
4713 will require static initialization of bounds for it. It should
4714 result in another gimplification of similar initializer and we
4715 may fall into infinite loop. */
4716 if (valid_const_initializer
4717 && !(cleared || num_nonzero_elements == 0)
4718 && !TREE_ADDRESSABLE (type)
4719 && (!current_function_decl
4720 || !lookup_attribute ("chkp ctor",
4721 DECL_ATTRIBUTES (current_function_decl))))
4723 HOST_WIDE_INT size = int_size_in_bytes (type);
4724 unsigned int align;
4726 /* ??? We can still get unbounded array types, at least
4727 from the C++ front end. This seems wrong, but attempt
4728 to work around it for now. */
4729 if (size < 0)
4731 size = int_size_in_bytes (TREE_TYPE (object));
4732 if (size >= 0)
4733 TREE_TYPE (ctor) = type = TREE_TYPE (object);
4736 /* Find the maximum alignment we can assume for the object. */
4737 /* ??? Make use of DECL_OFFSET_ALIGN. */
4738 if (DECL_P (object))
4739 align = DECL_ALIGN (object);
4740 else
4741 align = TYPE_ALIGN (type);
4743 /* Do a block move either if the size is so small as to make
4744 each individual move a sub-unit move on average, or if it
4745 is so large as to make individual moves inefficient. */
4746 if (size > 0
4747 && num_nonzero_elements > 1
4748 && (size < num_nonzero_elements
4749 || !can_move_by_pieces (size, align)))
4751 if (notify_temp_creation)
4752 return GS_ERROR;
4754 walk_tree (&ctor, force_labels_r, NULL, NULL);
4755 ctor = tree_output_constant_def (ctor);
4756 if (!useless_type_conversion_p (type, TREE_TYPE (ctor)))
4757 ctor = build1 (VIEW_CONVERT_EXPR, type, ctor);
4758 TREE_OPERAND (*expr_p, 1) = ctor;
4760 /* This is no longer an assignment of a CONSTRUCTOR, but
4761 we still may have processing to do on the LHS. So
4762 pretend we didn't do anything here to let that happen. */
4763 return GS_UNHANDLED;
4767 /* If the target is volatile, we have non-zero elements and more than
4768 one field to assign, initialize the target from a temporary. */
4769 if (TREE_THIS_VOLATILE (object)
4770 && !TREE_ADDRESSABLE (type)
4771 && num_nonzero_elements > 0
4772 && vec_safe_length (elts) > 1)
4774 tree temp = create_tmp_var (TYPE_MAIN_VARIANT (type));
4775 TREE_OPERAND (*expr_p, 0) = temp;
4776 *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p),
4777 *expr_p,
4778 build2 (MODIFY_EXPR, void_type_node,
4779 object, temp));
4780 return GS_OK;
4783 if (notify_temp_creation)
4784 return GS_OK;
4786 /* If there are nonzero elements and if needed, pre-evaluate to capture
4787 elements overlapping with the lhs into temporaries. We must do this
4788 before clearing to fetch the values before they are zeroed-out. */
4789 if (num_nonzero_elements > 0 && TREE_CODE (*expr_p) != INIT_EXPR)
4791 preeval_data.lhs_base_decl = get_base_address (object);
4792 if (!DECL_P (preeval_data.lhs_base_decl))
4793 preeval_data.lhs_base_decl = NULL;
4794 preeval_data.lhs_alias_set = get_alias_set (object);
4796 gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p, 1),
4797 pre_p, post_p, &preeval_data);
4800 bool ctor_has_side_effects_p
4801 = TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p, 1));
4803 if (cleared)
4805 /* Zap the CONSTRUCTOR element list, which simplifies this case.
4806 Note that we still have to gimplify, in order to handle the
4807 case of variable sized types. Avoid shared tree structures. */
4808 CONSTRUCTOR_ELTS (ctor) = NULL;
4809 TREE_SIDE_EFFECTS (ctor) = 0;
4810 object = unshare_expr (object);
4811 gimplify_stmt (expr_p, pre_p);
4814 /* If we have not block cleared the object, or if there are nonzero
4815 elements in the constructor, or if the constructor has side effects,
4816 add assignments to the individual scalar fields of the object. */
4817 if (!cleared
4818 || num_nonzero_elements > 0
4819 || ctor_has_side_effects_p)
4820 gimplify_init_ctor_eval (object, elts, pre_p, cleared);
4822 *expr_p = NULL_TREE;
4824 break;
4826 case COMPLEX_TYPE:
4828 tree r, i;
4830 if (notify_temp_creation)
4831 return GS_OK;
4833 /* Extract the real and imaginary parts out of the ctor. */
4834 gcc_assert (elts->length () == 2);
4835 r = (*elts)[0].value;
4836 i = (*elts)[1].value;
4837 if (r == NULL || i == NULL)
4839 tree zero = build_zero_cst (TREE_TYPE (type));
4840 if (r == NULL)
4841 r = zero;
4842 if (i == NULL)
4843 i = zero;
4846 /* Complex types have either COMPLEX_CST or COMPLEX_EXPR to
4847 represent creation of a complex value. */
4848 if (TREE_CONSTANT (r) && TREE_CONSTANT (i))
4850 ctor = build_complex (type, r, i);
4851 TREE_OPERAND (*expr_p, 1) = ctor;
4853 else
4855 ctor = build2 (COMPLEX_EXPR, type, r, i);
4856 TREE_OPERAND (*expr_p, 1) = ctor;
4857 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 1),
4858 pre_p,
4859 post_p,
4860 rhs_predicate_for (TREE_OPERAND (*expr_p, 0)),
4861 fb_rvalue);
4864 break;
4866 case VECTOR_TYPE:
4868 unsigned HOST_WIDE_INT ix;
4869 constructor_elt *ce;
4871 if (notify_temp_creation)
4872 return GS_OK;
4874 /* Go ahead and simplify constant constructors to VECTOR_CST. */
4875 if (TREE_CONSTANT (ctor))
4877 bool constant_p = true;
4878 tree value;
4880 /* Even when ctor is constant, it might contain non-*_CST
4881 elements, such as addresses or trapping values like
4882 1.0/0.0 - 1.0/0.0. Such expressions don't belong
4883 in VECTOR_CST nodes. */
4884 FOR_EACH_CONSTRUCTOR_VALUE (elts, ix, value)
4885 if (!CONSTANT_CLASS_P (value))
4887 constant_p = false;
4888 break;
4891 if (constant_p)
4893 TREE_OPERAND (*expr_p, 1) = build_vector_from_ctor (type, elts);
4894 break;
4897 TREE_CONSTANT (ctor) = 0;
4900 /* Vector types use CONSTRUCTOR all the way through gimple
4901 compilation as a general initializer. */
4902 FOR_EACH_VEC_SAFE_ELT (elts, ix, ce)
4904 enum gimplify_status tret;
4905 tret = gimplify_expr (&ce->value, pre_p, post_p, is_gimple_val,
4906 fb_rvalue);
4907 if (tret == GS_ERROR)
4908 ret = GS_ERROR;
4909 else if (TREE_STATIC (ctor)
4910 && !initializer_constant_valid_p (ce->value,
4911 TREE_TYPE (ce->value)))
4912 TREE_STATIC (ctor) = 0;
4914 if (!is_gimple_reg (TREE_OPERAND (*expr_p, 0)))
4915 TREE_OPERAND (*expr_p, 1) = get_formal_tmp_var (ctor, pre_p);
4917 break;
4919 default:
4920 /* So how did we get a CONSTRUCTOR for a scalar type? */
4921 gcc_unreachable ();
4924 if (ret == GS_ERROR)
4925 return GS_ERROR;
4926 /* If we have gimplified both sides of the initializer but have
4927 not emitted an assignment, do so now. */
4928 if (*expr_p)
4930 tree lhs = TREE_OPERAND (*expr_p, 0);
4931 tree rhs = TREE_OPERAND (*expr_p, 1);
4932 if (want_value && object == lhs)
4933 lhs = unshare_expr (lhs);
4934 gassign *init = gimple_build_assign (lhs, rhs);
4935 gimplify_seq_add_stmt (pre_p, init);
4937 if (want_value)
4939 *expr_p = object;
4940 return GS_OK;
4942 else
4944 *expr_p = NULL;
4945 return GS_ALL_DONE;
4949 /* Given a pointer value OP0, return a simplified version of an
4950 indirection through OP0, or NULL_TREE if no simplification is
4951 possible. This may only be applied to a rhs of an expression.
4952 Note that the resulting type may be different from the type pointed
4953 to in the sense that it is still compatible from the langhooks
4954 point of view. */
4956 static tree
4957 gimple_fold_indirect_ref_rhs (tree t)
4959 return gimple_fold_indirect_ref (t);
4962 /* Subroutine of gimplify_modify_expr to do simplifications of
4963 MODIFY_EXPRs based on the code of the RHS. We loop for as long as
4964 something changes. */
4966 static enum gimplify_status
4967 gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p,
4968 gimple_seq *pre_p, gimple_seq *post_p,
4969 bool want_value)
4971 enum gimplify_status ret = GS_UNHANDLED;
4972 bool changed;
4976 changed = false;
4977 switch (TREE_CODE (*from_p))
4979 case VAR_DECL:
4980 /* If we're assigning from a read-only variable initialized with
4981 a constructor, do the direct assignment from the constructor,
4982 but only if neither source nor target are volatile since this
4983 latter assignment might end up being done on a per-field basis. */
4984 if (DECL_INITIAL (*from_p)
4985 && TREE_READONLY (*from_p)
4986 && !TREE_THIS_VOLATILE (*from_p)
4987 && !TREE_THIS_VOLATILE (*to_p)
4988 && TREE_CODE (DECL_INITIAL (*from_p)) == CONSTRUCTOR)
4990 tree old_from = *from_p;
4991 enum gimplify_status subret;
4993 /* Move the constructor into the RHS. */
4994 *from_p = unshare_expr (DECL_INITIAL (*from_p));
4996 /* Let's see if gimplify_init_constructor will need to put
4997 it in memory. */
4998 subret = gimplify_init_constructor (expr_p, NULL, NULL,
4999 false, true);
5000 if (subret == GS_ERROR)
5002 /* If so, revert the change. */
5003 *from_p = old_from;
5005 else
5007 ret = GS_OK;
5008 changed = true;
5011 break;
5012 case INDIRECT_REF:
5014 /* If we have code like
5016 *(const A*)(A*)&x
5018 where the type of "x" is a (possibly cv-qualified variant
5019 of "A"), treat the entire expression as identical to "x".
5020 This kind of code arises in C++ when an object is bound
5021 to a const reference, and if "x" is a TARGET_EXPR we want
5022 to take advantage of the optimization below. */
5023 bool volatile_p = TREE_THIS_VOLATILE (*from_p);
5024 tree t = gimple_fold_indirect_ref_rhs (TREE_OPERAND (*from_p, 0));
5025 if (t)
5027 if (TREE_THIS_VOLATILE (t) != volatile_p)
5029 if (DECL_P (t))
5030 t = build_simple_mem_ref_loc (EXPR_LOCATION (*from_p),
5031 build_fold_addr_expr (t));
5032 if (REFERENCE_CLASS_P (t))
5033 TREE_THIS_VOLATILE (t) = volatile_p;
5035 *from_p = t;
5036 ret = GS_OK;
5037 changed = true;
5039 break;
5042 case TARGET_EXPR:
5044 /* If we are initializing something from a TARGET_EXPR, strip the
5045 TARGET_EXPR and initialize it directly, if possible. This can't
5046 be done if the initializer is void, since that implies that the
5047 temporary is set in some non-trivial way.
5049 ??? What about code that pulls out the temp and uses it
5050 elsewhere? I think that such code never uses the TARGET_EXPR as
5051 an initializer. If I'm wrong, we'll die because the temp won't
5052 have any RTL. In that case, I guess we'll need to replace
5053 references somehow. */
5054 tree init = TARGET_EXPR_INITIAL (*from_p);
5056 if (init
5057 && !VOID_TYPE_P (TREE_TYPE (init)))
5059 *from_p = init;
5060 ret = GS_OK;
5061 changed = true;
5064 break;
5066 case COMPOUND_EXPR:
5067 /* Remove any COMPOUND_EXPR in the RHS so the following cases will be
5068 caught. */
5069 gimplify_compound_expr (from_p, pre_p, true);
5070 ret = GS_OK;
5071 changed = true;
5072 break;
5074 case CONSTRUCTOR:
5075 /* If we already made some changes, let the front end have a
5076 crack at this before we break it down. */
5077 if (ret != GS_UNHANDLED)
5078 break;
5079 /* If we're initializing from a CONSTRUCTOR, break this into
5080 individual MODIFY_EXPRs. */
5081 return gimplify_init_constructor (expr_p, pre_p, post_p, want_value,
5082 false);
5084 case COND_EXPR:
5085 /* If we're assigning to a non-register type, push the assignment
5086 down into the branches. This is mandatory for ADDRESSABLE types,
5087 since we cannot generate temporaries for such, but it saves a
5088 copy in other cases as well. */
5089 if (!is_gimple_reg_type (TREE_TYPE (*from_p)))
5091 /* This code should mirror the code in gimplify_cond_expr. */
5092 enum tree_code code = TREE_CODE (*expr_p);
5093 tree cond = *from_p;
5094 tree result = *to_p;
5096 ret = gimplify_expr (&result, pre_p, post_p,
5097 is_gimple_lvalue, fb_lvalue);
5098 if (ret != GS_ERROR)
5099 ret = GS_OK;
5101 /* If we are going to write RESULT more than once, clear
5102 TREE_READONLY flag, otherwise we might incorrectly promote
5103 the variable to static const and initialize it at compile
5104 time in one of the branches. */
5105 if (VAR_P (result)
5106 && TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node
5107 && TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
5108 TREE_READONLY (result) = 0;
5109 if (TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node)
5110 TREE_OPERAND (cond, 1)
5111 = build2 (code, void_type_node, result,
5112 TREE_OPERAND (cond, 1));
5113 if (TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
5114 TREE_OPERAND (cond, 2)
5115 = build2 (code, void_type_node, unshare_expr (result),
5116 TREE_OPERAND (cond, 2));
5118 TREE_TYPE (cond) = void_type_node;
5119 recalculate_side_effects (cond);
5121 if (want_value)
5123 gimplify_and_add (cond, pre_p);
5124 *expr_p = unshare_expr (result);
5126 else
5127 *expr_p = cond;
5128 return ret;
5130 break;
5132 case CALL_EXPR:
5133 /* For calls that return in memory, give *to_p as the CALL_EXPR's
5134 return slot so that we don't generate a temporary. */
5135 if (!CALL_EXPR_RETURN_SLOT_OPT (*from_p)
5136 && aggregate_value_p (*from_p, *from_p))
5138 bool use_target;
5140 if (!(rhs_predicate_for (*to_p))(*from_p))
5141 /* If we need a temporary, *to_p isn't accurate. */
5142 use_target = false;
5143 /* It's OK to use the return slot directly unless it's an NRV. */
5144 else if (TREE_CODE (*to_p) == RESULT_DECL
5145 && DECL_NAME (*to_p) == NULL_TREE
5146 && needs_to_live_in_memory (*to_p))
5147 use_target = true;
5148 else if (is_gimple_reg_type (TREE_TYPE (*to_p))
5149 || (DECL_P (*to_p) && DECL_REGISTER (*to_p)))
5150 /* Don't force regs into memory. */
5151 use_target = false;
5152 else if (TREE_CODE (*expr_p) == INIT_EXPR)
5153 /* It's OK to use the target directly if it's being
5154 initialized. */
5155 use_target = true;
5156 else if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p)))
5157 != INTEGER_CST)
5158 /* Always use the target and thus RSO for variable-sized types.
5159 GIMPLE cannot deal with a variable-sized assignment
5160 embedded in a call statement. */
5161 use_target = true;
5162 else if (TREE_CODE (*to_p) != SSA_NAME
5163 && (!is_gimple_variable (*to_p)
5164 || needs_to_live_in_memory (*to_p)))
5165 /* Don't use the original target if it's already addressable;
5166 if its address escapes, and the called function uses the
5167 NRV optimization, a conforming program could see *to_p
5168 change before the called function returns; see c++/19317.
5169 When optimizing, the return_slot pass marks more functions
5170 as safe after we have escape info. */
5171 use_target = false;
5172 else
5173 use_target = true;
5175 if (use_target)
5177 CALL_EXPR_RETURN_SLOT_OPT (*from_p) = 1;
5178 mark_addressable (*to_p);
5181 break;
5183 case WITH_SIZE_EXPR:
5184 /* Likewise for calls that return an aggregate of non-constant size,
5185 since we would not be able to generate a temporary at all. */
5186 if (TREE_CODE (TREE_OPERAND (*from_p, 0)) == CALL_EXPR)
5188 *from_p = TREE_OPERAND (*from_p, 0);
5189 /* We don't change ret in this case because the
5190 WITH_SIZE_EXPR might have been added in
5191 gimplify_modify_expr, so returning GS_OK would lead to an
5192 infinite loop. */
5193 changed = true;
5195 break;
5197 /* If we're initializing from a container, push the initialization
5198 inside it. */
5199 case CLEANUP_POINT_EXPR:
5200 case BIND_EXPR:
5201 case STATEMENT_LIST:
5203 tree wrap = *from_p;
5204 tree t;
5206 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_min_lval,
5207 fb_lvalue);
5208 if (ret != GS_ERROR)
5209 ret = GS_OK;
5211 t = voidify_wrapper_expr (wrap, *expr_p);
5212 gcc_assert (t == *expr_p);
5214 if (want_value)
5216 gimplify_and_add (wrap, pre_p);
5217 *expr_p = unshare_expr (*to_p);
5219 else
5220 *expr_p = wrap;
5221 return GS_OK;
5224 case COMPOUND_LITERAL_EXPR:
5226 tree complit = TREE_OPERAND (*expr_p, 1);
5227 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (complit);
5228 tree decl = DECL_EXPR_DECL (decl_s);
5229 tree init = DECL_INITIAL (decl);
5231 /* struct T x = (struct T) { 0, 1, 2 } can be optimized
5232 into struct T x = { 0, 1, 2 } if the address of the
5233 compound literal has never been taken. */
5234 if (!TREE_ADDRESSABLE (complit)
5235 && !TREE_ADDRESSABLE (decl)
5236 && init)
5238 *expr_p = copy_node (*expr_p);
5239 TREE_OPERAND (*expr_p, 1) = init;
5240 return GS_OK;
5244 default:
5245 break;
5248 while (changed);
5250 return ret;
5254 /* Return true if T looks like a valid GIMPLE statement. */
5256 static bool
5257 is_gimple_stmt (tree t)
5259 const enum tree_code code = TREE_CODE (t);
5261 switch (code)
5263 case NOP_EXPR:
5264 /* The only valid NOP_EXPR is the empty statement. */
5265 return IS_EMPTY_STMT (t);
5267 case BIND_EXPR:
5268 case COND_EXPR:
5269 /* These are only valid if they're void. */
5270 return TREE_TYPE (t) == NULL || VOID_TYPE_P (TREE_TYPE (t));
5272 case SWITCH_EXPR:
5273 case GOTO_EXPR:
5274 case RETURN_EXPR:
5275 case LABEL_EXPR:
5276 case CASE_LABEL_EXPR:
5277 case TRY_CATCH_EXPR:
5278 case TRY_FINALLY_EXPR:
5279 case EH_FILTER_EXPR:
5280 case CATCH_EXPR:
5281 case ASM_EXPR:
5282 case STATEMENT_LIST:
5283 case OACC_PARALLEL:
5284 case OACC_KERNELS:
5285 case OACC_DATA:
5286 case OACC_HOST_DATA:
5287 case OACC_DECLARE:
5288 case OACC_UPDATE:
5289 case OACC_ENTER_DATA:
5290 case OACC_EXIT_DATA:
5291 case OACC_CACHE:
5292 case OMP_PARALLEL:
5293 case OMP_FOR:
5294 case OMP_SIMD:
5295 case CILK_SIMD:
5296 case OMP_DISTRIBUTE:
5297 case OACC_LOOP:
5298 case OMP_SECTIONS:
5299 case OMP_SECTION:
5300 case OMP_SINGLE:
5301 case OMP_MASTER:
5302 case OMP_TASKGROUP:
5303 case OMP_ORDERED:
5304 case OMP_CRITICAL:
5305 case OMP_TASK:
5306 case OMP_TARGET:
5307 case OMP_TARGET_DATA:
5308 case OMP_TARGET_UPDATE:
5309 case OMP_TARGET_ENTER_DATA:
5310 case OMP_TARGET_EXIT_DATA:
5311 case OMP_TASKLOOP:
5312 case OMP_TEAMS:
5313 /* These are always void. */
5314 return true;
5316 case CALL_EXPR:
5317 case MODIFY_EXPR:
5318 case PREDICT_EXPR:
5319 /* These are valid regardless of their type. */
5320 return true;
5322 default:
5323 return false;
5328 /* Promote partial stores to COMPLEX variables to total stores. *EXPR_P is
5329 a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a variable with
5330 DECL_GIMPLE_REG_P set.
5332 IMPORTANT NOTE: This promotion is performed by introducing a load of the
5333 other, unmodified part of the complex object just before the total store.
5334 As a consequence, if the object is still uninitialized, an undefined value
5335 will be loaded into a register, which may result in a spurious exception
5336 if the register is floating-point and the value happens to be a signaling
5337 NaN for example. Then the fully-fledged complex operations lowering pass
5338 followed by a DCE pass are necessary in order to fix things up. */
5340 static enum gimplify_status
5341 gimplify_modify_expr_complex_part (tree *expr_p, gimple_seq *pre_p,
5342 bool want_value)
5344 enum tree_code code, ocode;
5345 tree lhs, rhs, new_rhs, other, realpart, imagpart;
5347 lhs = TREE_OPERAND (*expr_p, 0);
5348 rhs = TREE_OPERAND (*expr_p, 1);
5349 code = TREE_CODE (lhs);
5350 lhs = TREE_OPERAND (lhs, 0);
5352 ocode = code == REALPART_EXPR ? IMAGPART_EXPR : REALPART_EXPR;
5353 other = build1 (ocode, TREE_TYPE (rhs), lhs);
5354 TREE_NO_WARNING (other) = 1;
5355 other = get_formal_tmp_var (other, pre_p);
5357 realpart = code == REALPART_EXPR ? rhs : other;
5358 imagpart = code == REALPART_EXPR ? other : rhs;
5360 if (TREE_CONSTANT (realpart) && TREE_CONSTANT (imagpart))
5361 new_rhs = build_complex (TREE_TYPE (lhs), realpart, imagpart);
5362 else
5363 new_rhs = build2 (COMPLEX_EXPR, TREE_TYPE (lhs), realpart, imagpart);
5365 gimplify_seq_add_stmt (pre_p, gimple_build_assign (lhs, new_rhs));
5366 *expr_p = (want_value) ? rhs : NULL_TREE;
5368 return GS_ALL_DONE;
5371 /* Gimplify the MODIFY_EXPR node pointed to by EXPR_P.
5373 modify_expr
5374 : varname '=' rhs
5375 | '*' ID '=' rhs
5377 PRE_P points to the list where side effects that must happen before
5378 *EXPR_P should be stored.
5380 POST_P points to the list where side effects that must happen after
5381 *EXPR_P should be stored.
5383 WANT_VALUE is nonzero iff we want to use the value of this expression
5384 in another expression. */
5386 static enum gimplify_status
5387 gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
5388 bool want_value)
5390 tree *from_p = &TREE_OPERAND (*expr_p, 1);
5391 tree *to_p = &TREE_OPERAND (*expr_p, 0);
5392 enum gimplify_status ret = GS_UNHANDLED;
5393 gimple *assign;
5394 location_t loc = EXPR_LOCATION (*expr_p);
5395 gimple_stmt_iterator gsi;
5397 gcc_assert (TREE_CODE (*expr_p) == MODIFY_EXPR
5398 || TREE_CODE (*expr_p) == INIT_EXPR);
5400 /* Trying to simplify a clobber using normal logic doesn't work,
5401 so handle it here. */
5402 if (TREE_CLOBBER_P (*from_p))
5404 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
5405 if (ret == GS_ERROR)
5406 return ret;
5407 gcc_assert (!want_value
5408 && (VAR_P (*to_p) || TREE_CODE (*to_p) == MEM_REF));
5409 gimplify_seq_add_stmt (pre_p, gimple_build_assign (*to_p, *from_p));
5410 *expr_p = NULL;
5411 return GS_ALL_DONE;
5414 /* Insert pointer conversions required by the middle-end that are not
5415 required by the frontend. This fixes middle-end type checking for
5416 for example gcc.dg/redecl-6.c. */
5417 if (POINTER_TYPE_P (TREE_TYPE (*to_p)))
5419 STRIP_USELESS_TYPE_CONVERSION (*from_p);
5420 if (!useless_type_conversion_p (TREE_TYPE (*to_p), TREE_TYPE (*from_p)))
5421 *from_p = fold_convert_loc (loc, TREE_TYPE (*to_p), *from_p);
5424 /* See if any simplifications can be done based on what the RHS is. */
5425 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
5426 want_value);
5427 if (ret != GS_UNHANDLED)
5428 return ret;
5430 /* For zero sized types only gimplify the left hand side and right hand
5431 side as statements and throw away the assignment. Do this after
5432 gimplify_modify_expr_rhs so we handle TARGET_EXPRs of addressable
5433 types properly. */
5434 if (zero_sized_type (TREE_TYPE (*from_p)) && !want_value)
5436 gimplify_stmt (from_p, pre_p);
5437 gimplify_stmt (to_p, pre_p);
5438 *expr_p = NULL_TREE;
5439 return GS_ALL_DONE;
5442 /* If the value being copied is of variable width, compute the length
5443 of the copy into a WITH_SIZE_EXPR. Note that we need to do this
5444 before gimplifying any of the operands so that we can resolve any
5445 PLACEHOLDER_EXPRs in the size. Also note that the RTL expander uses
5446 the size of the expression to be copied, not of the destination, so
5447 that is what we must do here. */
5448 maybe_with_size_expr (from_p);
5450 /* As a special case, we have to temporarily allow for assignments
5451 with a CALL_EXPR on the RHS. Since in GIMPLE a function call is
5452 a toplevel statement, when gimplifying the GENERIC expression
5453 MODIFY_EXPR <a, CALL_EXPR <foo>>, we cannot create the tuple
5454 GIMPLE_ASSIGN <a, GIMPLE_CALL <foo>>.
5456 Instead, we need to create the tuple GIMPLE_CALL <a, foo>. To
5457 prevent gimplify_expr from trying to create a new temporary for
5458 foo's LHS, we tell it that it should only gimplify until it
5459 reaches the CALL_EXPR. On return from gimplify_expr, the newly
5460 created GIMPLE_CALL <foo> will be the last statement in *PRE_P
5461 and all we need to do here is set 'a' to be its LHS. */
5463 /* Gimplify the RHS first for C++17 and bug 71104. */
5464 gimple_predicate initial_pred = initial_rhs_predicate_for (*to_p);
5465 ret = gimplify_expr (from_p, pre_p, post_p, initial_pred, fb_rvalue);
5466 if (ret == GS_ERROR)
5467 return ret;
5469 /* Then gimplify the LHS. */
5470 /* If we gimplified the RHS to a CALL_EXPR and that call may return
5471 twice we have to make sure to gimplify into non-SSA as otherwise
5472 the abnormal edge added later will make those defs not dominate
5473 their uses.
5474 ??? Technically this applies only to the registers used in the
5475 resulting non-register *TO_P. */
5476 bool saved_into_ssa = gimplify_ctxp->into_ssa;
5477 if (saved_into_ssa
5478 && TREE_CODE (*from_p) == CALL_EXPR
5479 && call_expr_flags (*from_p) & ECF_RETURNS_TWICE)
5480 gimplify_ctxp->into_ssa = false;
5481 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
5482 gimplify_ctxp->into_ssa = saved_into_ssa;
5483 if (ret == GS_ERROR)
5484 return ret;
5486 /* Now that the LHS is gimplified, re-gimplify the RHS if our initial
5487 guess for the predicate was wrong. */
5488 gimple_predicate final_pred = rhs_predicate_for (*to_p);
5489 if (final_pred != initial_pred)
5491 ret = gimplify_expr (from_p, pre_p, post_p, final_pred, fb_rvalue);
5492 if (ret == GS_ERROR)
5493 return ret;
5496 /* In case of va_arg internal fn wrappped in a WITH_SIZE_EXPR, add the type
5497 size as argument to the call. */
5498 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
5500 tree call = TREE_OPERAND (*from_p, 0);
5501 tree vlasize = TREE_OPERAND (*from_p, 1);
5503 if (TREE_CODE (call) == CALL_EXPR
5504 && CALL_EXPR_IFN (call) == IFN_VA_ARG)
5506 int nargs = call_expr_nargs (call);
5507 tree type = TREE_TYPE (call);
5508 tree ap = CALL_EXPR_ARG (call, 0);
5509 tree tag = CALL_EXPR_ARG (call, 1);
5510 tree aptag = CALL_EXPR_ARG (call, 2);
5511 tree newcall = build_call_expr_internal_loc (EXPR_LOCATION (call),
5512 IFN_VA_ARG, type,
5513 nargs + 1, ap, tag,
5514 aptag, vlasize);
5515 TREE_OPERAND (*from_p, 0) = newcall;
5519 /* Now see if the above changed *from_p to something we handle specially. */
5520 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
5521 want_value);
5522 if (ret != GS_UNHANDLED)
5523 return ret;
5525 /* If we've got a variable sized assignment between two lvalues (i.e. does
5526 not involve a call), then we can make things a bit more straightforward
5527 by converting the assignment to memcpy or memset. */
5528 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
5530 tree from = TREE_OPERAND (*from_p, 0);
5531 tree size = TREE_OPERAND (*from_p, 1);
5533 if (TREE_CODE (from) == CONSTRUCTOR)
5534 return gimplify_modify_expr_to_memset (expr_p, size, want_value, pre_p);
5536 if (is_gimple_addressable (from))
5538 *from_p = from;
5539 return gimplify_modify_expr_to_memcpy (expr_p, size, want_value,
5540 pre_p);
5544 /* Transform partial stores to non-addressable complex variables into
5545 total stores. This allows us to use real instead of virtual operands
5546 for these variables, which improves optimization. */
5547 if ((TREE_CODE (*to_p) == REALPART_EXPR
5548 || TREE_CODE (*to_p) == IMAGPART_EXPR)
5549 && is_gimple_reg (TREE_OPERAND (*to_p, 0)))
5550 return gimplify_modify_expr_complex_part (expr_p, pre_p, want_value);
5552 /* Try to alleviate the effects of the gimplification creating artificial
5553 temporaries (see for example is_gimple_reg_rhs) on the debug info, but
5554 make sure not to create DECL_DEBUG_EXPR links across functions. */
5555 if (!gimplify_ctxp->into_ssa
5556 && VAR_P (*from_p)
5557 && DECL_IGNORED_P (*from_p)
5558 && DECL_P (*to_p)
5559 && !DECL_IGNORED_P (*to_p)
5560 && decl_function_context (*to_p) == current_function_decl)
5562 if (!DECL_NAME (*from_p) && DECL_NAME (*to_p))
5563 DECL_NAME (*from_p)
5564 = create_tmp_var_name (IDENTIFIER_POINTER (DECL_NAME (*to_p)));
5565 DECL_HAS_DEBUG_EXPR_P (*from_p) = 1;
5566 SET_DECL_DEBUG_EXPR (*from_p, *to_p);
5569 if (want_value && TREE_THIS_VOLATILE (*to_p))
5570 *from_p = get_initialized_tmp_var (*from_p, pre_p, post_p);
5572 if (TREE_CODE (*from_p) == CALL_EXPR)
5574 /* Since the RHS is a CALL_EXPR, we need to create a GIMPLE_CALL
5575 instead of a GIMPLE_ASSIGN. */
5576 gcall *call_stmt;
5577 if (CALL_EXPR_FN (*from_p) == NULL_TREE)
5579 /* Gimplify internal functions created in the FEs. */
5580 int nargs = call_expr_nargs (*from_p), i;
5581 enum internal_fn ifn = CALL_EXPR_IFN (*from_p);
5582 auto_vec<tree> vargs (nargs);
5584 for (i = 0; i < nargs; i++)
5586 gimplify_arg (&CALL_EXPR_ARG (*from_p, i), pre_p,
5587 EXPR_LOCATION (*from_p));
5588 vargs.quick_push (CALL_EXPR_ARG (*from_p, i));
5590 call_stmt = gimple_build_call_internal_vec (ifn, vargs);
5591 gimple_set_location (call_stmt, EXPR_LOCATION (*expr_p));
5593 else
5595 tree fnptrtype = TREE_TYPE (CALL_EXPR_FN (*from_p));
5596 CALL_EXPR_FN (*from_p) = TREE_OPERAND (CALL_EXPR_FN (*from_p), 0);
5597 STRIP_USELESS_TYPE_CONVERSION (CALL_EXPR_FN (*from_p));
5598 tree fndecl = get_callee_fndecl (*from_p);
5599 if (fndecl
5600 && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
5601 && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT
5602 && call_expr_nargs (*from_p) == 3)
5603 call_stmt = gimple_build_call_internal (IFN_BUILTIN_EXPECT, 3,
5604 CALL_EXPR_ARG (*from_p, 0),
5605 CALL_EXPR_ARG (*from_p, 1),
5606 CALL_EXPR_ARG (*from_p, 2));
5607 else
5609 call_stmt = gimple_build_call_from_tree (*from_p);
5610 gimple_call_set_fntype (call_stmt, TREE_TYPE (fnptrtype));
5613 notice_special_calls (call_stmt);
5614 if (!gimple_call_noreturn_p (call_stmt) || !should_remove_lhs_p (*to_p))
5615 gimple_call_set_lhs (call_stmt, *to_p);
5616 else if (TREE_CODE (*to_p) == SSA_NAME)
5617 /* The above is somewhat premature, avoid ICEing later for a
5618 SSA name w/o a definition. We may have uses in the GIMPLE IL.
5619 ??? This doesn't make it a default-def. */
5620 SSA_NAME_DEF_STMT (*to_p) = gimple_build_nop ();
5621 assign = call_stmt;
5623 else
5625 assign = gimple_build_assign (*to_p, *from_p);
5626 gimple_set_location (assign, EXPR_LOCATION (*expr_p));
5627 if (COMPARISON_CLASS_P (*from_p))
5628 gimple_set_no_warning (assign, TREE_NO_WARNING (*from_p));
5631 if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p))
5633 /* We should have got an SSA name from the start. */
5634 gcc_assert (TREE_CODE (*to_p) == SSA_NAME
5635 || ! gimple_in_ssa_p (cfun));
5638 gimplify_seq_add_stmt (pre_p, assign);
5639 gsi = gsi_last (*pre_p);
5640 maybe_fold_stmt (&gsi);
5642 if (want_value)
5644 *expr_p = TREE_THIS_VOLATILE (*to_p) ? *from_p : unshare_expr (*to_p);
5645 return GS_OK;
5647 else
5648 *expr_p = NULL;
5650 return GS_ALL_DONE;
5653 /* Gimplify a comparison between two variable-sized objects. Do this
5654 with a call to BUILT_IN_MEMCMP. */
5656 static enum gimplify_status
5657 gimplify_variable_sized_compare (tree *expr_p)
5659 location_t loc = EXPR_LOCATION (*expr_p);
5660 tree op0 = TREE_OPERAND (*expr_p, 0);
5661 tree op1 = TREE_OPERAND (*expr_p, 1);
5662 tree t, arg, dest, src, expr;
5664 arg = TYPE_SIZE_UNIT (TREE_TYPE (op0));
5665 arg = unshare_expr (arg);
5666 arg = SUBSTITUTE_PLACEHOLDER_IN_EXPR (arg, op0);
5667 src = build_fold_addr_expr_loc (loc, op1);
5668 dest = build_fold_addr_expr_loc (loc, op0);
5669 t = builtin_decl_implicit (BUILT_IN_MEMCMP);
5670 t = build_call_expr_loc (loc, t, 3, dest, src, arg);
5672 expr
5673 = build2 (TREE_CODE (*expr_p), TREE_TYPE (*expr_p), t, integer_zero_node);
5674 SET_EXPR_LOCATION (expr, loc);
5675 *expr_p = expr;
5677 return GS_OK;
5680 /* Gimplify a comparison between two aggregate objects of integral scalar
5681 mode as a comparison between the bitwise equivalent scalar values. */
5683 static enum gimplify_status
5684 gimplify_scalar_mode_aggregate_compare (tree *expr_p)
5686 location_t loc = EXPR_LOCATION (*expr_p);
5687 tree op0 = TREE_OPERAND (*expr_p, 0);
5688 tree op1 = TREE_OPERAND (*expr_p, 1);
5690 tree type = TREE_TYPE (op0);
5691 tree scalar_type = lang_hooks.types.type_for_mode (TYPE_MODE (type), 1);
5693 op0 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op0);
5694 op1 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op1);
5696 *expr_p
5697 = fold_build2_loc (loc, TREE_CODE (*expr_p), TREE_TYPE (*expr_p), op0, op1);
5699 return GS_OK;
5702 /* Gimplify an expression sequence. This function gimplifies each
5703 expression and rewrites the original expression with the last
5704 expression of the sequence in GIMPLE form.
5706 PRE_P points to the list where the side effects for all the
5707 expressions in the sequence will be emitted.
5709 WANT_VALUE is true when the result of the last COMPOUND_EXPR is used. */
5711 static enum gimplify_status
5712 gimplify_compound_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
5714 tree t = *expr_p;
5718 tree *sub_p = &TREE_OPERAND (t, 0);
5720 if (TREE_CODE (*sub_p) == COMPOUND_EXPR)
5721 gimplify_compound_expr (sub_p, pre_p, false);
5722 else
5723 gimplify_stmt (sub_p, pre_p);
5725 t = TREE_OPERAND (t, 1);
5727 while (TREE_CODE (t) == COMPOUND_EXPR);
5729 *expr_p = t;
5730 if (want_value)
5731 return GS_OK;
5732 else
5734 gimplify_stmt (expr_p, pre_p);
5735 return GS_ALL_DONE;
5739 /* Gimplify a SAVE_EXPR node. EXPR_P points to the expression to
5740 gimplify. After gimplification, EXPR_P will point to a new temporary
5741 that holds the original value of the SAVE_EXPR node.
5743 PRE_P points to the list where side effects that must happen before
5744 *EXPR_P should be stored. */
5746 static enum gimplify_status
5747 gimplify_save_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
5749 enum gimplify_status ret = GS_ALL_DONE;
5750 tree val;
5752 gcc_assert (TREE_CODE (*expr_p) == SAVE_EXPR);
5753 val = TREE_OPERAND (*expr_p, 0);
5755 /* If the SAVE_EXPR has not been resolved, then evaluate it once. */
5756 if (!SAVE_EXPR_RESOLVED_P (*expr_p))
5758 /* The operand may be a void-valued expression such as SAVE_EXPRs
5759 generated by the Java frontend for class initialization. It is
5760 being executed only for its side-effects. */
5761 if (TREE_TYPE (val) == void_type_node)
5763 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
5764 is_gimple_stmt, fb_none);
5765 val = NULL;
5767 else
5768 /* The temporary may not be an SSA name as later abnormal and EH
5769 control flow may invalidate use/def domination. */
5770 val = get_initialized_tmp_var (val, pre_p, post_p, false);
5772 TREE_OPERAND (*expr_p, 0) = val;
5773 SAVE_EXPR_RESOLVED_P (*expr_p) = 1;
5776 *expr_p = val;
5778 return ret;
5781 /* Rewrite the ADDR_EXPR node pointed to by EXPR_P
5783 unary_expr
5784 : ...
5785 | '&' varname
5788 PRE_P points to the list where side effects that must happen before
5789 *EXPR_P should be stored.
5791 POST_P points to the list where side effects that must happen after
5792 *EXPR_P should be stored. */
5794 static enum gimplify_status
5795 gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
5797 tree expr = *expr_p;
5798 tree op0 = TREE_OPERAND (expr, 0);
5799 enum gimplify_status ret;
5800 location_t loc = EXPR_LOCATION (*expr_p);
5802 switch (TREE_CODE (op0))
5804 case INDIRECT_REF:
5805 do_indirect_ref:
5806 /* Check if we are dealing with an expression of the form '&*ptr'.
5807 While the front end folds away '&*ptr' into 'ptr', these
5808 expressions may be generated internally by the compiler (e.g.,
5809 builtins like __builtin_va_end). */
5810 /* Caution: the silent array decomposition semantics we allow for
5811 ADDR_EXPR means we can't always discard the pair. */
5812 /* Gimplification of the ADDR_EXPR operand may drop
5813 cv-qualification conversions, so make sure we add them if
5814 needed. */
5816 tree op00 = TREE_OPERAND (op0, 0);
5817 tree t_expr = TREE_TYPE (expr);
5818 tree t_op00 = TREE_TYPE (op00);
5820 if (!useless_type_conversion_p (t_expr, t_op00))
5821 op00 = fold_convert_loc (loc, TREE_TYPE (expr), op00);
5822 *expr_p = op00;
5823 ret = GS_OK;
5825 break;
5827 case VIEW_CONVERT_EXPR:
5828 /* Take the address of our operand and then convert it to the type of
5829 this ADDR_EXPR.
5831 ??? The interactions of VIEW_CONVERT_EXPR and aliasing is not at
5832 all clear. The impact of this transformation is even less clear. */
5834 /* If the operand is a useless conversion, look through it. Doing so
5835 guarantees that the ADDR_EXPR and its operand will remain of the
5836 same type. */
5837 if (tree_ssa_useless_type_conversion (TREE_OPERAND (op0, 0)))
5838 op0 = TREE_OPERAND (op0, 0);
5840 *expr_p = fold_convert_loc (loc, TREE_TYPE (expr),
5841 build_fold_addr_expr_loc (loc,
5842 TREE_OPERAND (op0, 0)));
5843 ret = GS_OK;
5844 break;
5846 case MEM_REF:
5847 if (integer_zerop (TREE_OPERAND (op0, 1)))
5848 goto do_indirect_ref;
5850 /* fall through */
5852 default:
5853 /* If we see a call to a declared builtin or see its address
5854 being taken (we can unify those cases here) then we can mark
5855 the builtin for implicit generation by GCC. */
5856 if (TREE_CODE (op0) == FUNCTION_DECL
5857 && DECL_BUILT_IN_CLASS (op0) == BUILT_IN_NORMAL
5858 && builtin_decl_declared_p (DECL_FUNCTION_CODE (op0)))
5859 set_builtin_decl_implicit_p (DECL_FUNCTION_CODE (op0), true);
5861 /* We use fb_either here because the C frontend sometimes takes
5862 the address of a call that returns a struct; see
5863 gcc.dg/c99-array-lval-1.c. The gimplifier will correctly make
5864 the implied temporary explicit. */
5866 /* Make the operand addressable. */
5867 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, post_p,
5868 is_gimple_addressable, fb_either);
5869 if (ret == GS_ERROR)
5870 break;
5872 /* Then mark it. Beware that it may not be possible to do so directly
5873 if a temporary has been created by the gimplification. */
5874 prepare_gimple_addressable (&TREE_OPERAND (expr, 0), pre_p);
5876 op0 = TREE_OPERAND (expr, 0);
5878 /* For various reasons, the gimplification of the expression
5879 may have made a new INDIRECT_REF. */
5880 if (TREE_CODE (op0) == INDIRECT_REF)
5881 goto do_indirect_ref;
5883 mark_addressable (TREE_OPERAND (expr, 0));
5885 /* The FEs may end up building ADDR_EXPRs early on a decl with
5886 an incomplete type. Re-build ADDR_EXPRs in canonical form
5887 here. */
5888 if (!types_compatible_p (TREE_TYPE (op0), TREE_TYPE (TREE_TYPE (expr))))
5889 *expr_p = build_fold_addr_expr (op0);
5891 /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly. */
5892 recompute_tree_invariant_for_addr_expr (*expr_p);
5894 /* If we re-built the ADDR_EXPR add a conversion to the original type
5895 if required. */
5896 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
5897 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
5899 break;
5902 return ret;
5905 /* Gimplify the operands of an ASM_EXPR. Input operands should be a gimple
5906 value; output operands should be a gimple lvalue. */
5908 static enum gimplify_status
5909 gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
5911 tree expr;
5912 int noutputs;
5913 const char **oconstraints;
5914 int i;
5915 tree link;
5916 const char *constraint;
5917 bool allows_mem, allows_reg, is_inout;
5918 enum gimplify_status ret, tret;
5919 gasm *stmt;
5920 vec<tree, va_gc> *inputs;
5921 vec<tree, va_gc> *outputs;
5922 vec<tree, va_gc> *clobbers;
5923 vec<tree, va_gc> *labels;
5924 tree link_next;
5926 expr = *expr_p;
5927 noutputs = list_length (ASM_OUTPUTS (expr));
5928 oconstraints = (const char **) alloca ((noutputs) * sizeof (const char *));
5930 inputs = NULL;
5931 outputs = NULL;
5932 clobbers = NULL;
5933 labels = NULL;
5935 ret = GS_ALL_DONE;
5936 link_next = NULL_TREE;
5937 for (i = 0, link = ASM_OUTPUTS (expr); link; ++i, link = link_next)
5939 bool ok;
5940 size_t constraint_len;
5942 link_next = TREE_CHAIN (link);
5944 oconstraints[i]
5945 = constraint
5946 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
5947 constraint_len = strlen (constraint);
5948 if (constraint_len == 0)
5949 continue;
5951 ok = parse_output_constraint (&constraint, i, 0, 0,
5952 &allows_mem, &allows_reg, &is_inout);
5953 if (!ok)
5955 ret = GS_ERROR;
5956 is_inout = false;
5959 if (!allows_reg && allows_mem)
5960 mark_addressable (TREE_VALUE (link));
5962 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
5963 is_inout ? is_gimple_min_lval : is_gimple_lvalue,
5964 fb_lvalue | fb_mayfail);
5965 if (tret == GS_ERROR)
5967 error ("invalid lvalue in asm output %d", i);
5968 ret = tret;
5971 /* If the constraint does not allow memory make sure we gimplify
5972 it to a register if it is not already but its base is. This
5973 happens for complex and vector components. */
5974 if (!allows_mem)
5976 tree op = TREE_VALUE (link);
5977 if (! is_gimple_val (op)
5978 && is_gimple_reg_type (TREE_TYPE (op))
5979 && is_gimple_reg (get_base_address (op)))
5981 tree tem = create_tmp_reg (TREE_TYPE (op));
5982 tree ass;
5983 if (is_inout)
5985 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem),
5986 tem, unshare_expr (op));
5987 gimplify_and_add (ass, pre_p);
5989 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem), op, tem);
5990 gimplify_and_add (ass, post_p);
5992 TREE_VALUE (link) = tem;
5993 tret = GS_OK;
5997 vec_safe_push (outputs, link);
5998 TREE_CHAIN (link) = NULL_TREE;
6000 if (is_inout)
6002 /* An input/output operand. To give the optimizers more
6003 flexibility, split it into separate input and output
6004 operands. */
6005 tree input;
6006 /* Buffer big enough to format a 32-bit UINT_MAX into. */
6007 char buf[11];
6009 /* Turn the in/out constraint into an output constraint. */
6010 char *p = xstrdup (constraint);
6011 p[0] = '=';
6012 TREE_VALUE (TREE_PURPOSE (link)) = build_string (constraint_len, p);
6014 /* And add a matching input constraint. */
6015 if (allows_reg)
6017 sprintf (buf, "%u", i);
6019 /* If there are multiple alternatives in the constraint,
6020 handle each of them individually. Those that allow register
6021 will be replaced with operand number, the others will stay
6022 unchanged. */
6023 if (strchr (p, ',') != NULL)
6025 size_t len = 0, buflen = strlen (buf);
6026 char *beg, *end, *str, *dst;
6028 for (beg = p + 1;;)
6030 end = strchr (beg, ',');
6031 if (end == NULL)
6032 end = strchr (beg, '\0');
6033 if ((size_t) (end - beg) < buflen)
6034 len += buflen + 1;
6035 else
6036 len += end - beg + 1;
6037 if (*end)
6038 beg = end + 1;
6039 else
6040 break;
6043 str = (char *) alloca (len);
6044 for (beg = p + 1, dst = str;;)
6046 const char *tem;
6047 bool mem_p, reg_p, inout_p;
6049 end = strchr (beg, ',');
6050 if (end)
6051 *end = '\0';
6052 beg[-1] = '=';
6053 tem = beg - 1;
6054 parse_output_constraint (&tem, i, 0, 0,
6055 &mem_p, &reg_p, &inout_p);
6056 if (dst != str)
6057 *dst++ = ',';
6058 if (reg_p)
6060 memcpy (dst, buf, buflen);
6061 dst += buflen;
6063 else
6065 if (end)
6066 len = end - beg;
6067 else
6068 len = strlen (beg);
6069 memcpy (dst, beg, len);
6070 dst += len;
6072 if (end)
6073 beg = end + 1;
6074 else
6075 break;
6077 *dst = '\0';
6078 input = build_string (dst - str, str);
6080 else
6081 input = build_string (strlen (buf), buf);
6083 else
6084 input = build_string (constraint_len - 1, constraint + 1);
6086 free (p);
6088 input = build_tree_list (build_tree_list (NULL_TREE, input),
6089 unshare_expr (TREE_VALUE (link)));
6090 ASM_INPUTS (expr) = chainon (ASM_INPUTS (expr), input);
6094 link_next = NULL_TREE;
6095 for (link = ASM_INPUTS (expr); link; ++i, link = link_next)
6097 link_next = TREE_CHAIN (link);
6098 constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
6099 parse_input_constraint (&constraint, 0, 0, noutputs, 0,
6100 oconstraints, &allows_mem, &allows_reg);
6102 /* If we can't make copies, we can only accept memory. */
6103 if (TREE_ADDRESSABLE (TREE_TYPE (TREE_VALUE (link))))
6105 if (allows_mem)
6106 allows_reg = 0;
6107 else
6109 error ("impossible constraint in %<asm%>");
6110 error ("non-memory input %d must stay in memory", i);
6111 return GS_ERROR;
6115 /* If the operand is a memory input, it should be an lvalue. */
6116 if (!allows_reg && allows_mem)
6118 tree inputv = TREE_VALUE (link);
6119 STRIP_NOPS (inputv);
6120 if (TREE_CODE (inputv) == PREDECREMENT_EXPR
6121 || TREE_CODE (inputv) == PREINCREMENT_EXPR
6122 || TREE_CODE (inputv) == POSTDECREMENT_EXPR
6123 || TREE_CODE (inputv) == POSTINCREMENT_EXPR
6124 || TREE_CODE (inputv) == MODIFY_EXPR)
6125 TREE_VALUE (link) = error_mark_node;
6126 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6127 is_gimple_lvalue, fb_lvalue | fb_mayfail);
6128 if (tret != GS_ERROR)
6130 /* Unlike output operands, memory inputs are not guaranteed
6131 to be lvalues by the FE, and while the expressions are
6132 marked addressable there, if it is e.g. a statement
6133 expression, temporaries in it might not end up being
6134 addressable. They might be already used in the IL and thus
6135 it is too late to make them addressable now though. */
6136 tree x = TREE_VALUE (link);
6137 while (handled_component_p (x))
6138 x = TREE_OPERAND (x, 0);
6139 if (TREE_CODE (x) == MEM_REF
6140 && TREE_CODE (TREE_OPERAND (x, 0)) == ADDR_EXPR)
6141 x = TREE_OPERAND (TREE_OPERAND (x, 0), 0);
6142 if ((VAR_P (x)
6143 || TREE_CODE (x) == PARM_DECL
6144 || TREE_CODE (x) == RESULT_DECL)
6145 && !TREE_ADDRESSABLE (x)
6146 && is_gimple_reg (x))
6148 warning_at (EXPR_LOC_OR_LOC (TREE_VALUE (link),
6149 input_location), 0,
6150 "memory input %d is not directly addressable",
6152 prepare_gimple_addressable (&TREE_VALUE (link), pre_p);
6155 mark_addressable (TREE_VALUE (link));
6156 if (tret == GS_ERROR)
6158 error_at (EXPR_LOC_OR_LOC (TREE_VALUE (link), input_location),
6159 "memory input %d is not directly addressable", i);
6160 ret = tret;
6163 else
6165 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6166 is_gimple_asm_val, fb_rvalue);
6167 if (tret == GS_ERROR)
6168 ret = tret;
6171 TREE_CHAIN (link) = NULL_TREE;
6172 vec_safe_push (inputs, link);
6175 link_next = NULL_TREE;
6176 for (link = ASM_CLOBBERS (expr); link; ++i, link = link_next)
6178 link_next = TREE_CHAIN (link);
6179 TREE_CHAIN (link) = NULL_TREE;
6180 vec_safe_push (clobbers, link);
6183 link_next = NULL_TREE;
6184 for (link = ASM_LABELS (expr); link; ++i, link = link_next)
6186 link_next = TREE_CHAIN (link);
6187 TREE_CHAIN (link) = NULL_TREE;
6188 vec_safe_push (labels, link);
6191 /* Do not add ASMs with errors to the gimple IL stream. */
6192 if (ret != GS_ERROR)
6194 stmt = gimple_build_asm_vec (TREE_STRING_POINTER (ASM_STRING (expr)),
6195 inputs, outputs, clobbers, labels);
6197 gimple_asm_set_volatile (stmt, ASM_VOLATILE_P (expr) || noutputs == 0);
6198 gimple_asm_set_input (stmt, ASM_INPUT_P (expr));
6200 gimplify_seq_add_stmt (pre_p, stmt);
6203 return ret;
6206 /* Gimplify a CLEANUP_POINT_EXPR. Currently this works by adding
6207 GIMPLE_WITH_CLEANUP_EXPRs to the prequeue as we encounter cleanups while
6208 gimplifying the body, and converting them to TRY_FINALLY_EXPRs when we
6209 return to this function.
6211 FIXME should we complexify the prequeue handling instead? Or use flags
6212 for all the cleanups and let the optimizer tighten them up? The current
6213 code seems pretty fragile; it will break on a cleanup within any
6214 non-conditional nesting. But any such nesting would be broken, anyway;
6215 we can't write a TRY_FINALLY_EXPR that starts inside a nesting construct
6216 and continues out of it. We can do that at the RTL level, though, so
6217 having an optimizer to tighten up try/finally regions would be a Good
6218 Thing. */
6220 static enum gimplify_status
6221 gimplify_cleanup_point_expr (tree *expr_p, gimple_seq *pre_p)
6223 gimple_stmt_iterator iter;
6224 gimple_seq body_sequence = NULL;
6226 tree temp = voidify_wrapper_expr (*expr_p, NULL);
6228 /* We only care about the number of conditions between the innermost
6229 CLEANUP_POINT_EXPR and the cleanup. So save and reset the count and
6230 any cleanups collected outside the CLEANUP_POINT_EXPR. */
6231 int old_conds = gimplify_ctxp->conditions;
6232 gimple_seq old_cleanups = gimplify_ctxp->conditional_cleanups;
6233 bool old_in_cleanup_point_expr = gimplify_ctxp->in_cleanup_point_expr;
6234 gimplify_ctxp->conditions = 0;
6235 gimplify_ctxp->conditional_cleanups = NULL;
6236 gimplify_ctxp->in_cleanup_point_expr = true;
6238 gimplify_stmt (&TREE_OPERAND (*expr_p, 0), &body_sequence);
6240 gimplify_ctxp->conditions = old_conds;
6241 gimplify_ctxp->conditional_cleanups = old_cleanups;
6242 gimplify_ctxp->in_cleanup_point_expr = old_in_cleanup_point_expr;
6244 for (iter = gsi_start (body_sequence); !gsi_end_p (iter); )
6246 gimple *wce = gsi_stmt (iter);
6248 if (gimple_code (wce) == GIMPLE_WITH_CLEANUP_EXPR)
6250 if (gsi_one_before_end_p (iter))
6252 /* Note that gsi_insert_seq_before and gsi_remove do not
6253 scan operands, unlike some other sequence mutators. */
6254 if (!gimple_wce_cleanup_eh_only (wce))
6255 gsi_insert_seq_before_without_update (&iter,
6256 gimple_wce_cleanup (wce),
6257 GSI_SAME_STMT);
6258 gsi_remove (&iter, true);
6259 break;
6261 else
6263 gtry *gtry;
6264 gimple_seq seq;
6265 enum gimple_try_flags kind;
6267 if (gimple_wce_cleanup_eh_only (wce))
6268 kind = GIMPLE_TRY_CATCH;
6269 else
6270 kind = GIMPLE_TRY_FINALLY;
6271 seq = gsi_split_seq_after (iter);
6273 gtry = gimple_build_try (seq, gimple_wce_cleanup (wce), kind);
6274 /* Do not use gsi_replace here, as it may scan operands.
6275 We want to do a simple structural modification only. */
6276 gsi_set_stmt (&iter, gtry);
6277 iter = gsi_start (gtry->eval);
6280 else
6281 gsi_next (&iter);
6284 gimplify_seq_add_seq (pre_p, body_sequence);
6285 if (temp)
6287 *expr_p = temp;
6288 return GS_OK;
6290 else
6292 *expr_p = NULL;
6293 return GS_ALL_DONE;
6297 /* Insert a cleanup marker for gimplify_cleanup_point_expr. CLEANUP
6298 is the cleanup action required. EH_ONLY is true if the cleanup should
6299 only be executed if an exception is thrown, not on normal exit.
6300 If FORCE_UNCOND is true perform the cleanup unconditionally; this is
6301 only valid for clobbers. */
6303 static void
6304 gimple_push_cleanup (tree var, tree cleanup, bool eh_only, gimple_seq *pre_p,
6305 bool force_uncond = false)
6307 gimple *wce;
6308 gimple_seq cleanup_stmts = NULL;
6310 /* Errors can result in improperly nested cleanups. Which results in
6311 confusion when trying to resolve the GIMPLE_WITH_CLEANUP_EXPR. */
6312 if (seen_error ())
6313 return;
6315 if (gimple_conditional_context () && ! force_uncond)
6317 /* If we're in a conditional context, this is more complex. We only
6318 want to run the cleanup if we actually ran the initialization that
6319 necessitates it, but we want to run it after the end of the
6320 conditional context. So we wrap the try/finally around the
6321 condition and use a flag to determine whether or not to actually
6322 run the destructor. Thus
6324 test ? f(A()) : 0
6326 becomes (approximately)
6328 flag = 0;
6329 try {
6330 if (test) { A::A(temp); flag = 1; val = f(temp); }
6331 else { val = 0; }
6332 } finally {
6333 if (flag) A::~A(temp);
6337 tree flag = create_tmp_var (boolean_type_node, "cleanup");
6338 gassign *ffalse = gimple_build_assign (flag, boolean_false_node);
6339 gassign *ftrue = gimple_build_assign (flag, boolean_true_node);
6341 cleanup = build3 (COND_EXPR, void_type_node, flag, cleanup, NULL);
6342 gimplify_stmt (&cleanup, &cleanup_stmts);
6343 wce = gimple_build_wce (cleanup_stmts);
6345 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, ffalse);
6346 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
6347 gimplify_seq_add_stmt (pre_p, ftrue);
6349 /* Because of this manipulation, and the EH edges that jump
6350 threading cannot redirect, the temporary (VAR) will appear
6351 to be used uninitialized. Don't warn. */
6352 TREE_NO_WARNING (var) = 1;
6354 else
6356 gimplify_stmt (&cleanup, &cleanup_stmts);
6357 wce = gimple_build_wce (cleanup_stmts);
6358 gimple_wce_set_cleanup_eh_only (wce, eh_only);
6359 gimplify_seq_add_stmt (pre_p, wce);
6363 /* Gimplify a TARGET_EXPR which doesn't appear on the rhs of an INIT_EXPR. */
6365 static enum gimplify_status
6366 gimplify_target_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6368 tree targ = *expr_p;
6369 tree temp = TARGET_EXPR_SLOT (targ);
6370 tree init = TARGET_EXPR_INITIAL (targ);
6371 enum gimplify_status ret;
6373 bool unpoison_empty_seq = false;
6374 gimple_stmt_iterator unpoison_it;
6376 if (init)
6378 tree cleanup = NULL_TREE;
6380 /* TARGET_EXPR temps aren't part of the enclosing block, so add it
6381 to the temps list. Handle also variable length TARGET_EXPRs. */
6382 if (TREE_CODE (DECL_SIZE (temp)) != INTEGER_CST)
6384 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (temp)))
6385 gimplify_type_sizes (TREE_TYPE (temp), pre_p);
6386 gimplify_vla_decl (temp, pre_p);
6388 else
6390 /* Save location where we need to place unpoisoning. It's possible
6391 that a variable will be converted to needs_to_live_in_memory. */
6392 unpoison_it = gsi_last (*pre_p);
6393 unpoison_empty_seq = gsi_end_p (unpoison_it);
6395 gimple_add_tmp_var (temp);
6398 /* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the
6399 expression is supposed to initialize the slot. */
6400 if (VOID_TYPE_P (TREE_TYPE (init)))
6401 ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
6402 else
6404 tree init_expr = build2 (INIT_EXPR, void_type_node, temp, init);
6405 init = init_expr;
6406 ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
6407 init = NULL;
6408 ggc_free (init_expr);
6410 if (ret == GS_ERROR)
6412 /* PR c++/28266 Make sure this is expanded only once. */
6413 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
6414 return GS_ERROR;
6416 if (init)
6417 gimplify_and_add (init, pre_p);
6419 /* If needed, push the cleanup for the temp. */
6420 if (TARGET_EXPR_CLEANUP (targ))
6422 if (CLEANUP_EH_ONLY (targ))
6423 gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ),
6424 CLEANUP_EH_ONLY (targ), pre_p);
6425 else
6426 cleanup = TARGET_EXPR_CLEANUP (targ);
6429 /* Add a clobber for the temporary going out of scope, like
6430 gimplify_bind_expr. */
6431 if (gimplify_ctxp->in_cleanup_point_expr
6432 && needs_to_live_in_memory (temp))
6434 if (flag_stack_reuse == SR_ALL)
6436 tree clobber = build_constructor (TREE_TYPE (temp),
6437 NULL);
6438 TREE_THIS_VOLATILE (clobber) = true;
6439 clobber = build2 (MODIFY_EXPR, TREE_TYPE (temp), temp, clobber);
6440 gimple_push_cleanup (temp, clobber, false, pre_p, true);
6442 if (asan_poisoned_variables && dbg_cnt (asan_use_after_scope))
6444 tree asan_cleanup = build_asan_poison_call_expr (temp);
6445 if (asan_cleanup)
6447 if (unpoison_empty_seq)
6448 unpoison_it = gsi_start (*pre_p);
6450 asan_poison_variable (temp, false, &unpoison_it,
6451 unpoison_empty_seq);
6452 gimple_push_cleanup (temp, asan_cleanup, false, pre_p);
6456 if (cleanup)
6457 gimple_push_cleanup (temp, cleanup, false, pre_p);
6459 /* Only expand this once. */
6460 TREE_OPERAND (targ, 3) = init;
6461 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
6463 else
6464 /* We should have expanded this before. */
6465 gcc_assert (DECL_SEEN_IN_BIND_EXPR_P (temp));
6467 *expr_p = temp;
6468 return GS_OK;
6471 /* Gimplification of expression trees. */
6473 /* Gimplify an expression which appears at statement context. The
6474 corresponding GIMPLE statements are added to *SEQ_P. If *SEQ_P is
6475 NULL, a new sequence is allocated.
6477 Return true if we actually added a statement to the queue. */
6479 bool
6480 gimplify_stmt (tree *stmt_p, gimple_seq *seq_p)
6482 gimple_seq_node last;
6484 last = gimple_seq_last (*seq_p);
6485 gimplify_expr (stmt_p, seq_p, NULL, is_gimple_stmt, fb_none);
6486 return last != gimple_seq_last (*seq_p);
6489 /* Add FIRSTPRIVATE entries for DECL in the OpenMP the surrounding parallels
6490 to CTX. If entries already exist, force them to be some flavor of private.
6491 If there is no enclosing parallel, do nothing. */
6493 void
6494 omp_firstprivatize_variable (struct gimplify_omp_ctx *ctx, tree decl)
6496 splay_tree_node n;
6498 if (decl == NULL || !DECL_P (decl) || ctx->region_type == ORT_NONE)
6499 return;
6503 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
6504 if (n != NULL)
6506 if (n->value & GOVD_SHARED)
6507 n->value = GOVD_FIRSTPRIVATE | (n->value & GOVD_SEEN);
6508 else if (n->value & GOVD_MAP)
6509 n->value |= GOVD_MAP_TO_ONLY;
6510 else
6511 return;
6513 else if ((ctx->region_type & ORT_TARGET) != 0)
6515 if (ctx->target_map_scalars_firstprivate)
6516 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
6517 else
6518 omp_add_variable (ctx, decl, GOVD_MAP | GOVD_MAP_TO_ONLY);
6520 else if (ctx->region_type != ORT_WORKSHARE
6521 && ctx->region_type != ORT_SIMD
6522 && ctx->region_type != ORT_ACC
6523 && !(ctx->region_type & ORT_TARGET_DATA))
6524 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
6526 ctx = ctx->outer_context;
6528 while (ctx);
6531 /* Similarly for each of the type sizes of TYPE. */
6533 static void
6534 omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type)
6536 if (type == NULL || type == error_mark_node)
6537 return;
6538 type = TYPE_MAIN_VARIANT (type);
6540 if (ctx->privatized_types->add (type))
6541 return;
6543 switch (TREE_CODE (type))
6545 case INTEGER_TYPE:
6546 case ENUMERAL_TYPE:
6547 case BOOLEAN_TYPE:
6548 case REAL_TYPE:
6549 case FIXED_POINT_TYPE:
6550 omp_firstprivatize_variable (ctx, TYPE_MIN_VALUE (type));
6551 omp_firstprivatize_variable (ctx, TYPE_MAX_VALUE (type));
6552 break;
6554 case ARRAY_TYPE:
6555 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
6556 omp_firstprivatize_type_sizes (ctx, TYPE_DOMAIN (type));
6557 break;
6559 case RECORD_TYPE:
6560 case UNION_TYPE:
6561 case QUAL_UNION_TYPE:
6563 tree field;
6564 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
6565 if (TREE_CODE (field) == FIELD_DECL)
6567 omp_firstprivatize_variable (ctx, DECL_FIELD_OFFSET (field));
6568 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (field));
6571 break;
6573 case POINTER_TYPE:
6574 case REFERENCE_TYPE:
6575 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
6576 break;
6578 default:
6579 break;
6582 omp_firstprivatize_variable (ctx, TYPE_SIZE (type));
6583 omp_firstprivatize_variable (ctx, TYPE_SIZE_UNIT (type));
6584 lang_hooks.types.omp_firstprivatize_type_sizes (ctx, type);
6587 /* Add an entry for DECL in the OMP context CTX with FLAGS. */
6589 static void
6590 omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
6592 splay_tree_node n;
6593 unsigned int nflags;
6594 tree t;
6596 if (error_operand_p (decl) || ctx->region_type == ORT_NONE)
6597 return;
6599 /* Never elide decls whose type has TREE_ADDRESSABLE set. This means
6600 there are constructors involved somewhere. */
6601 if (TREE_ADDRESSABLE (TREE_TYPE (decl))
6602 || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
6603 flags |= GOVD_SEEN;
6605 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
6606 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
6608 /* We shouldn't be re-adding the decl with the same data
6609 sharing class. */
6610 gcc_assert ((n->value & GOVD_DATA_SHARE_CLASS & flags) == 0);
6611 nflags = n->value | flags;
6612 /* The only combination of data sharing classes we should see is
6613 FIRSTPRIVATE and LASTPRIVATE. However, OpenACC permits
6614 reduction variables to be used in data sharing clauses. */
6615 gcc_assert ((ctx->region_type & ORT_ACC) != 0
6616 || ((nflags & GOVD_DATA_SHARE_CLASS)
6617 == (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE))
6618 || (flags & GOVD_DATA_SHARE_CLASS) == 0);
6619 n->value = nflags;
6620 return;
6623 /* When adding a variable-sized variable, we have to handle all sorts
6624 of additional bits of data: the pointer replacement variable, and
6625 the parameters of the type. */
6626 if (DECL_SIZE (decl) && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
6628 /* Add the pointer replacement variable as PRIVATE if the variable
6629 replacement is private, else FIRSTPRIVATE since we'll need the
6630 address of the original variable either for SHARED, or for the
6631 copy into or out of the context. */
6632 if (!(flags & GOVD_LOCAL))
6634 if (flags & GOVD_MAP)
6635 nflags = GOVD_MAP | GOVD_MAP_TO_ONLY | GOVD_EXPLICIT;
6636 else if (flags & GOVD_PRIVATE)
6637 nflags = GOVD_PRIVATE;
6638 else if ((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
6639 && (flags & GOVD_FIRSTPRIVATE))
6640 nflags = GOVD_PRIVATE | GOVD_EXPLICIT;
6641 else
6642 nflags = GOVD_FIRSTPRIVATE;
6643 nflags |= flags & GOVD_SEEN;
6644 t = DECL_VALUE_EXPR (decl);
6645 gcc_assert (TREE_CODE (t) == INDIRECT_REF);
6646 t = TREE_OPERAND (t, 0);
6647 gcc_assert (DECL_P (t));
6648 omp_add_variable (ctx, t, nflags);
6651 /* Add all of the variable and type parameters (which should have
6652 been gimplified to a formal temporary) as FIRSTPRIVATE. */
6653 omp_firstprivatize_variable (ctx, DECL_SIZE_UNIT (decl));
6654 omp_firstprivatize_variable (ctx, DECL_SIZE (decl));
6655 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
6657 /* The variable-sized variable itself is never SHARED, only some form
6658 of PRIVATE. The sharing would take place via the pointer variable
6659 which we remapped above. */
6660 if (flags & GOVD_SHARED)
6661 flags = GOVD_PRIVATE | GOVD_DEBUG_PRIVATE
6662 | (flags & (GOVD_SEEN | GOVD_EXPLICIT));
6664 /* We're going to make use of the TYPE_SIZE_UNIT at least in the
6665 alloca statement we generate for the variable, so make sure it
6666 is available. This isn't automatically needed for the SHARED
6667 case, since we won't be allocating local storage then.
6668 For local variables TYPE_SIZE_UNIT might not be gimplified yet,
6669 in this case omp_notice_variable will be called later
6670 on when it is gimplified. */
6671 else if (! (flags & (GOVD_LOCAL | GOVD_MAP))
6672 && DECL_P (TYPE_SIZE_UNIT (TREE_TYPE (decl))))
6673 omp_notice_variable (ctx, TYPE_SIZE_UNIT (TREE_TYPE (decl)), true);
6675 else if ((flags & (GOVD_MAP | GOVD_LOCAL)) == 0
6676 && lang_hooks.decls.omp_privatize_by_reference (decl))
6678 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
6680 /* Similar to the direct variable sized case above, we'll need the
6681 size of references being privatized. */
6682 if ((flags & GOVD_SHARED) == 0)
6684 t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
6685 if (DECL_P (t))
6686 omp_notice_variable (ctx, t, true);
6690 if (n != NULL)
6691 n->value |= flags;
6692 else
6693 splay_tree_insert (ctx->variables, (splay_tree_key)decl, flags);
6695 /* For reductions clauses in OpenACC loop directives, by default create a
6696 copy clause on the enclosing parallel construct for carrying back the
6697 results. */
6698 if (ctx->region_type == ORT_ACC && (flags & GOVD_REDUCTION))
6700 struct gimplify_omp_ctx *outer_ctx = ctx->outer_context;
6701 while (outer_ctx)
6703 n = splay_tree_lookup (outer_ctx->variables, (splay_tree_key)decl);
6704 if (n != NULL)
6706 /* Ignore local variables and explicitly declared clauses. */
6707 if (n->value & (GOVD_LOCAL | GOVD_EXPLICIT))
6708 break;
6709 else if (outer_ctx->region_type == ORT_ACC_KERNELS)
6711 /* According to the OpenACC spec, such a reduction variable
6712 should already have a copy map on a kernels construct,
6713 verify that here. */
6714 gcc_assert (!(n->value & GOVD_FIRSTPRIVATE)
6715 && (n->value & GOVD_MAP));
6717 else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
6719 /* Remove firstprivate and make it a copy map. */
6720 n->value &= ~GOVD_FIRSTPRIVATE;
6721 n->value |= GOVD_MAP;
6724 else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
6726 splay_tree_insert (outer_ctx->variables, (splay_tree_key)decl,
6727 GOVD_MAP | GOVD_SEEN);
6728 break;
6730 outer_ctx = outer_ctx->outer_context;
6735 /* Notice a threadprivate variable DECL used in OMP context CTX.
6736 This just prints out diagnostics about threadprivate variable uses
6737 in untied tasks. If DECL2 is non-NULL, prevent this warning
6738 on that variable. */
6740 static bool
6741 omp_notice_threadprivate_variable (struct gimplify_omp_ctx *ctx, tree decl,
6742 tree decl2)
6744 splay_tree_node n;
6745 struct gimplify_omp_ctx *octx;
6747 for (octx = ctx; octx; octx = octx->outer_context)
6748 if ((octx->region_type & ORT_TARGET) != 0)
6750 n = splay_tree_lookup (octx->variables, (splay_tree_key)decl);
6751 if (n == NULL)
6753 error ("threadprivate variable %qE used in target region",
6754 DECL_NAME (decl));
6755 error_at (octx->location, "enclosing target region");
6756 splay_tree_insert (octx->variables, (splay_tree_key)decl, 0);
6758 if (decl2)
6759 splay_tree_insert (octx->variables, (splay_tree_key)decl2, 0);
6762 if (ctx->region_type != ORT_UNTIED_TASK)
6763 return false;
6764 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
6765 if (n == NULL)
6767 error ("threadprivate variable %qE used in untied task",
6768 DECL_NAME (decl));
6769 error_at (ctx->location, "enclosing task");
6770 splay_tree_insert (ctx->variables, (splay_tree_key)decl, 0);
6772 if (decl2)
6773 splay_tree_insert (ctx->variables, (splay_tree_key)decl2, 0);
6774 return false;
6777 /* Return true if global var DECL is device resident. */
6779 static bool
6780 device_resident_p (tree decl)
6782 tree attr = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (decl));
6784 if (!attr)
6785 return false;
6787 for (tree t = TREE_VALUE (attr); t; t = TREE_PURPOSE (t))
6789 tree c = TREE_VALUE (t);
6790 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DEVICE_RESIDENT)
6791 return true;
6794 return false;
6797 /* Return true if DECL has an ACC DECLARE attribute. */
6799 static bool
6800 is_oacc_declared (tree decl)
6802 tree t = TREE_CODE (decl) == MEM_REF ? TREE_OPERAND (decl, 0) : decl;
6803 tree declared = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (t));
6804 return declared != NULL_TREE;
6807 /* Determine outer default flags for DECL mentioned in an OMP region
6808 but not declared in an enclosing clause.
6810 ??? Some compiler-generated variables (like SAVE_EXPRs) could be
6811 remapped firstprivate instead of shared. To some extent this is
6812 addressed in omp_firstprivatize_type_sizes, but not
6813 effectively. */
6815 static unsigned
6816 omp_default_clause (struct gimplify_omp_ctx *ctx, tree decl,
6817 bool in_code, unsigned flags)
6819 enum omp_clause_default_kind default_kind = ctx->default_kind;
6820 enum omp_clause_default_kind kind;
6822 kind = lang_hooks.decls.omp_predetermined_sharing (decl);
6823 if (kind != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
6824 default_kind = kind;
6826 switch (default_kind)
6828 case OMP_CLAUSE_DEFAULT_NONE:
6830 const char *rtype;
6832 if (ctx->region_type & ORT_PARALLEL)
6833 rtype = "parallel";
6834 else if (ctx->region_type & ORT_TASK)
6835 rtype = "task";
6836 else if (ctx->region_type & ORT_TEAMS)
6837 rtype = "teams";
6838 else
6839 gcc_unreachable ();
6841 error ("%qE not specified in enclosing %s",
6842 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rtype);
6843 error_at (ctx->location, "enclosing %s", rtype);
6845 /* FALLTHRU */
6846 case OMP_CLAUSE_DEFAULT_SHARED:
6847 flags |= GOVD_SHARED;
6848 break;
6849 case OMP_CLAUSE_DEFAULT_PRIVATE:
6850 flags |= GOVD_PRIVATE;
6851 break;
6852 case OMP_CLAUSE_DEFAULT_FIRSTPRIVATE:
6853 flags |= GOVD_FIRSTPRIVATE;
6854 break;
6855 case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
6856 /* decl will be either GOVD_FIRSTPRIVATE or GOVD_SHARED. */
6857 gcc_assert ((ctx->region_type & ORT_TASK) != 0);
6858 if (struct gimplify_omp_ctx *octx = ctx->outer_context)
6860 omp_notice_variable (octx, decl, in_code);
6861 for (; octx; octx = octx->outer_context)
6863 splay_tree_node n2;
6865 n2 = splay_tree_lookup (octx->variables, (splay_tree_key) decl);
6866 if ((octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)) != 0
6867 && (n2 == NULL || (n2->value & GOVD_DATA_SHARE_CLASS) == 0))
6868 continue;
6869 if (n2 && (n2->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED)
6871 flags |= GOVD_FIRSTPRIVATE;
6872 goto found_outer;
6874 if ((octx->region_type & (ORT_PARALLEL | ORT_TEAMS)) != 0)
6876 flags |= GOVD_SHARED;
6877 goto found_outer;
6882 if (TREE_CODE (decl) == PARM_DECL
6883 || (!is_global_var (decl)
6884 && DECL_CONTEXT (decl) == current_function_decl))
6885 flags |= GOVD_FIRSTPRIVATE;
6886 else
6887 flags |= GOVD_SHARED;
6888 found_outer:
6889 break;
6891 default:
6892 gcc_unreachable ();
6895 return flags;
6899 /* Determine outer default flags for DECL mentioned in an OACC region
6900 but not declared in an enclosing clause. */
6902 static unsigned
6903 oacc_default_clause (struct gimplify_omp_ctx *ctx, tree decl, unsigned flags)
6905 const char *rkind;
6906 bool on_device = false;
6907 bool declared = is_oacc_declared (decl);
6908 tree type = TREE_TYPE (decl);
6910 if (lang_hooks.decls.omp_privatize_by_reference (decl))
6911 type = TREE_TYPE (type);
6913 if ((ctx->region_type & (ORT_ACC_PARALLEL | ORT_ACC_KERNELS)) != 0
6914 && is_global_var (decl)
6915 && device_resident_p (decl))
6917 on_device = true;
6918 flags |= GOVD_MAP_TO_ONLY;
6921 switch (ctx->region_type)
6923 default:
6924 gcc_unreachable ();
6926 case ORT_ACC_KERNELS:
6927 /* Scalars are default 'copy' under kernels, non-scalars are default
6928 'present_or_copy'. */
6929 flags |= GOVD_MAP;
6930 if (!AGGREGATE_TYPE_P (type))
6931 flags |= GOVD_MAP_FORCE;
6933 rkind = "kernels";
6934 break;
6936 case ORT_ACC_PARALLEL:
6938 if (on_device || AGGREGATE_TYPE_P (type) || declared)
6939 /* Aggregates default to 'present_or_copy'. */
6940 flags |= GOVD_MAP;
6941 else
6942 /* Scalars default to 'firstprivate'. */
6943 flags |= GOVD_FIRSTPRIVATE;
6944 rkind = "parallel";
6946 break;
6949 if (DECL_ARTIFICIAL (decl))
6950 ; /* We can get compiler-generated decls, and should not complain
6951 about them. */
6952 else if (ctx->default_kind == OMP_CLAUSE_DEFAULT_NONE)
6954 error ("%qE not specified in enclosing OpenACC %qs construct",
6955 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rkind);
6956 inform (ctx->location, "enclosing OpenACC %qs construct", rkind);
6958 else
6959 gcc_checking_assert (ctx->default_kind == OMP_CLAUSE_DEFAULT_SHARED);
6961 return flags;
6964 /* Record the fact that DECL was used within the OMP context CTX.
6965 IN_CODE is true when real code uses DECL, and false when we should
6966 merely emit default(none) errors. Return true if DECL is going to
6967 be remapped and thus DECL shouldn't be gimplified into its
6968 DECL_VALUE_EXPR (if any). */
6970 static bool
6971 omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
6973 splay_tree_node n;
6974 unsigned flags = in_code ? GOVD_SEEN : 0;
6975 bool ret = false, shared;
6977 if (error_operand_p (decl))
6978 return false;
6980 if (ctx->region_type == ORT_NONE)
6981 return lang_hooks.decls.omp_disregard_value_expr (decl, false);
6983 if (is_global_var (decl))
6985 /* Threadprivate variables are predetermined. */
6986 if (DECL_THREAD_LOCAL_P (decl))
6987 return omp_notice_threadprivate_variable (ctx, decl, NULL_TREE);
6989 if (DECL_HAS_VALUE_EXPR_P (decl))
6991 tree value = get_base_address (DECL_VALUE_EXPR (decl));
6993 if (value && DECL_P (value) && DECL_THREAD_LOCAL_P (value))
6994 return omp_notice_threadprivate_variable (ctx, decl, value);
6997 if (gimplify_omp_ctxp->outer_context == NULL
6998 && VAR_P (decl)
6999 && oacc_get_fn_attrib (current_function_decl))
7001 location_t loc = DECL_SOURCE_LOCATION (decl);
7003 if (lookup_attribute ("omp declare target link",
7004 DECL_ATTRIBUTES (decl)))
7006 error_at (loc,
7007 "%qE with %<link%> clause used in %<routine%> function",
7008 DECL_NAME (decl));
7009 return false;
7011 else if (!lookup_attribute ("omp declare target",
7012 DECL_ATTRIBUTES (decl)))
7014 error_at (loc,
7015 "%qE requires a %<declare%> directive for use "
7016 "in a %<routine%> function", DECL_NAME (decl));
7017 return false;
7022 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7023 if ((ctx->region_type & ORT_TARGET) != 0)
7025 ret = lang_hooks.decls.omp_disregard_value_expr (decl, true);
7026 if (n == NULL)
7028 unsigned nflags = flags;
7029 if (ctx->target_map_pointers_as_0len_arrays
7030 || ctx->target_map_scalars_firstprivate)
7032 bool is_declare_target = false;
7033 bool is_scalar = false;
7034 if (is_global_var (decl)
7035 && varpool_node::get_create (decl)->offloadable)
7037 struct gimplify_omp_ctx *octx;
7038 for (octx = ctx->outer_context;
7039 octx; octx = octx->outer_context)
7041 n = splay_tree_lookup (octx->variables,
7042 (splay_tree_key)decl);
7043 if (n
7044 && (n->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED
7045 && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
7046 break;
7048 is_declare_target = octx == NULL;
7050 if (!is_declare_target && ctx->target_map_scalars_firstprivate)
7051 is_scalar = lang_hooks.decls.omp_scalar_p (decl);
7052 if (is_declare_target)
7054 else if (ctx->target_map_pointers_as_0len_arrays
7055 && (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
7056 || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
7057 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
7058 == POINTER_TYPE)))
7059 nflags |= GOVD_MAP | GOVD_MAP_0LEN_ARRAY;
7060 else if (is_scalar)
7061 nflags |= GOVD_FIRSTPRIVATE;
7064 struct gimplify_omp_ctx *octx = ctx->outer_context;
7065 if ((ctx->region_type & ORT_ACC) && octx)
7067 /* Look in outer OpenACC contexts, to see if there's a
7068 data attribute for this variable. */
7069 omp_notice_variable (octx, decl, in_code);
7071 for (; octx; octx = octx->outer_context)
7073 if (!(octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)))
7074 break;
7075 splay_tree_node n2
7076 = splay_tree_lookup (octx->variables,
7077 (splay_tree_key) decl);
7078 if (n2)
7080 if (octx->region_type == ORT_ACC_HOST_DATA)
7081 error ("variable %qE declared in enclosing "
7082 "%<host_data%> region", DECL_NAME (decl));
7083 nflags |= GOVD_MAP;
7084 if (octx->region_type == ORT_ACC_DATA
7085 && (n2->value & GOVD_MAP_0LEN_ARRAY))
7086 nflags |= GOVD_MAP_0LEN_ARRAY;
7087 goto found_outer;
7093 tree type = TREE_TYPE (decl);
7095 if (nflags == flags
7096 && gimplify_omp_ctxp->target_firstprivatize_array_bases
7097 && lang_hooks.decls.omp_privatize_by_reference (decl))
7098 type = TREE_TYPE (type);
7099 if (nflags == flags
7100 && !lang_hooks.types.omp_mappable_type (type))
7102 error ("%qD referenced in target region does not have "
7103 "a mappable type", decl);
7104 nflags |= GOVD_MAP | GOVD_EXPLICIT;
7106 else if (nflags == flags)
7108 if ((ctx->region_type & ORT_ACC) != 0)
7109 nflags = oacc_default_clause (ctx, decl, flags);
7110 else
7111 nflags |= GOVD_MAP;
7114 found_outer:
7115 omp_add_variable (ctx, decl, nflags);
7117 else
7119 /* If nothing changed, there's nothing left to do. */
7120 if ((n->value & flags) == flags)
7121 return ret;
7122 flags |= n->value;
7123 n->value = flags;
7125 goto do_outer;
7128 if (n == NULL)
7130 if (ctx->region_type == ORT_WORKSHARE
7131 || ctx->region_type == ORT_SIMD
7132 || ctx->region_type == ORT_ACC
7133 || (ctx->region_type & ORT_TARGET_DATA) != 0)
7134 goto do_outer;
7136 flags = omp_default_clause (ctx, decl, in_code, flags);
7138 if ((flags & GOVD_PRIVATE)
7139 && lang_hooks.decls.omp_private_outer_ref (decl))
7140 flags |= GOVD_PRIVATE_OUTER_REF;
7142 omp_add_variable (ctx, decl, flags);
7144 shared = (flags & GOVD_SHARED) != 0;
7145 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7146 goto do_outer;
7149 if ((n->value & (GOVD_SEEN | GOVD_LOCAL)) == 0
7150 && (flags & (GOVD_SEEN | GOVD_LOCAL)) == GOVD_SEEN
7151 && DECL_SIZE (decl))
7153 if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
7155 splay_tree_node n2;
7156 tree t = DECL_VALUE_EXPR (decl);
7157 gcc_assert (TREE_CODE (t) == INDIRECT_REF);
7158 t = TREE_OPERAND (t, 0);
7159 gcc_assert (DECL_P (t));
7160 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
7161 n2->value |= GOVD_SEEN;
7163 else if (lang_hooks.decls.omp_privatize_by_reference (decl)
7164 && TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)))
7165 && (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))))
7166 != INTEGER_CST))
7168 splay_tree_node n2;
7169 tree t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
7170 gcc_assert (DECL_P (t));
7171 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
7172 if (n2)
7173 omp_notice_variable (ctx, t, true);
7177 shared = ((flags | n->value) & GOVD_SHARED) != 0;
7178 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7180 /* If nothing changed, there's nothing left to do. */
7181 if ((n->value & flags) == flags)
7182 return ret;
7183 flags |= n->value;
7184 n->value = flags;
7186 do_outer:
7187 /* If the variable is private in the current context, then we don't
7188 need to propagate anything to an outer context. */
7189 if ((flags & GOVD_PRIVATE) && !(flags & GOVD_PRIVATE_OUTER_REF))
7190 return ret;
7191 if ((flags & (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7192 == (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7193 return ret;
7194 if ((flags & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
7195 | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7196 == (GOVD_LASTPRIVATE | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7197 return ret;
7198 if (ctx->outer_context
7199 && omp_notice_variable (ctx->outer_context, decl, in_code))
7200 return true;
7201 return ret;
7204 /* Verify that DECL is private within CTX. If there's specific information
7205 to the contrary in the innermost scope, generate an error. */
7207 static bool
7208 omp_is_private (struct gimplify_omp_ctx *ctx, tree decl, int simd)
7210 splay_tree_node n;
7212 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7213 if (n != NULL)
7215 if (n->value & GOVD_SHARED)
7217 if (ctx == gimplify_omp_ctxp)
7219 if (simd)
7220 error ("iteration variable %qE is predetermined linear",
7221 DECL_NAME (decl));
7222 else
7223 error ("iteration variable %qE should be private",
7224 DECL_NAME (decl));
7225 n->value = GOVD_PRIVATE;
7226 return true;
7228 else
7229 return false;
7231 else if ((n->value & GOVD_EXPLICIT) != 0
7232 && (ctx == gimplify_omp_ctxp
7233 || (ctx->region_type == ORT_COMBINED_PARALLEL
7234 && gimplify_omp_ctxp->outer_context == ctx)))
7236 if ((n->value & GOVD_FIRSTPRIVATE) != 0)
7237 error ("iteration variable %qE should not be firstprivate",
7238 DECL_NAME (decl));
7239 else if ((n->value & GOVD_REDUCTION) != 0)
7240 error ("iteration variable %qE should not be reduction",
7241 DECL_NAME (decl));
7242 else if (simd == 0 && (n->value & GOVD_LINEAR) != 0)
7243 error ("iteration variable %qE should not be linear",
7244 DECL_NAME (decl));
7245 else if (simd == 1 && (n->value & GOVD_LASTPRIVATE) != 0)
7246 error ("iteration variable %qE should not be lastprivate",
7247 DECL_NAME (decl));
7248 else if (simd && (n->value & GOVD_PRIVATE) != 0)
7249 error ("iteration variable %qE should not be private",
7250 DECL_NAME (decl));
7251 else if (simd == 2 && (n->value & GOVD_LINEAR) != 0)
7252 error ("iteration variable %qE is predetermined linear",
7253 DECL_NAME (decl));
7255 return (ctx == gimplify_omp_ctxp
7256 || (ctx->region_type == ORT_COMBINED_PARALLEL
7257 && gimplify_omp_ctxp->outer_context == ctx));
7260 if (ctx->region_type != ORT_WORKSHARE
7261 && ctx->region_type != ORT_SIMD
7262 && ctx->region_type != ORT_ACC)
7263 return false;
7264 else if (ctx->outer_context)
7265 return omp_is_private (ctx->outer_context, decl, simd);
7266 return false;
7269 /* Return true if DECL is private within a parallel region
7270 that binds to the current construct's context or in parallel
7271 region's REDUCTION clause. */
7273 static bool
7274 omp_check_private (struct gimplify_omp_ctx *ctx, tree decl, bool copyprivate)
7276 splay_tree_node n;
7280 ctx = ctx->outer_context;
7281 if (ctx == NULL)
7283 if (is_global_var (decl))
7284 return false;
7286 /* References might be private, but might be shared too,
7287 when checking for copyprivate, assume they might be
7288 private, otherwise assume they might be shared. */
7289 if (copyprivate)
7290 return true;
7292 if (lang_hooks.decls.omp_privatize_by_reference (decl))
7293 return false;
7295 /* Treat C++ privatized non-static data members outside
7296 of the privatization the same. */
7297 if (omp_member_access_dummy_var (decl))
7298 return false;
7300 return true;
7303 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
7305 if ((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
7306 && (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0))
7307 continue;
7309 if (n != NULL)
7311 if ((n->value & GOVD_LOCAL) != 0
7312 && omp_member_access_dummy_var (decl))
7313 return false;
7314 return (n->value & GOVD_SHARED) == 0;
7317 while (ctx->region_type == ORT_WORKSHARE
7318 || ctx->region_type == ORT_SIMD
7319 || ctx->region_type == ORT_ACC);
7320 return false;
7323 /* Callback for walk_tree to find a DECL_EXPR for the given DECL. */
7325 static tree
7326 find_decl_expr (tree *tp, int *walk_subtrees, void *data)
7328 tree t = *tp;
7330 /* If this node has been visited, unmark it and keep looking. */
7331 if (TREE_CODE (t) == DECL_EXPR && DECL_EXPR_DECL (t) == (tree) data)
7332 return t;
7334 if (IS_TYPE_OR_DECL_P (t))
7335 *walk_subtrees = 0;
7336 return NULL_TREE;
7339 /* Scan the OMP clauses in *LIST_P, installing mappings into a new
7340 and previous omp contexts. */
7342 static void
7343 gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
7344 enum omp_region_type region_type,
7345 enum tree_code code)
7347 struct gimplify_omp_ctx *ctx, *outer_ctx;
7348 tree c;
7349 hash_map<tree, tree> *struct_map_to_clause = NULL;
7350 tree *prev_list_p = NULL;
7352 ctx = new_omp_context (region_type);
7353 outer_ctx = ctx->outer_context;
7354 if (code == OMP_TARGET)
7356 if (!lang_GNU_Fortran ())
7357 ctx->target_map_pointers_as_0len_arrays = true;
7358 ctx->target_map_scalars_firstprivate = true;
7360 if (!lang_GNU_Fortran ())
7361 switch (code)
7363 case OMP_TARGET:
7364 case OMP_TARGET_DATA:
7365 case OMP_TARGET_ENTER_DATA:
7366 case OMP_TARGET_EXIT_DATA:
7367 case OACC_DECLARE:
7368 case OACC_HOST_DATA:
7369 ctx->target_firstprivatize_array_bases = true;
7370 default:
7371 break;
7374 while ((c = *list_p) != NULL)
7376 bool remove = false;
7377 bool notice_outer = true;
7378 const char *check_non_private = NULL;
7379 unsigned int flags;
7380 tree decl;
7382 switch (OMP_CLAUSE_CODE (c))
7384 case OMP_CLAUSE_PRIVATE:
7385 flags = GOVD_PRIVATE | GOVD_EXPLICIT;
7386 if (lang_hooks.decls.omp_private_outer_ref (OMP_CLAUSE_DECL (c)))
7388 flags |= GOVD_PRIVATE_OUTER_REF;
7389 OMP_CLAUSE_PRIVATE_OUTER_REF (c) = 1;
7391 else
7392 notice_outer = false;
7393 goto do_add;
7394 case OMP_CLAUSE_SHARED:
7395 flags = GOVD_SHARED | GOVD_EXPLICIT;
7396 goto do_add;
7397 case OMP_CLAUSE_FIRSTPRIVATE:
7398 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
7399 check_non_private = "firstprivate";
7400 goto do_add;
7401 case OMP_CLAUSE_LASTPRIVATE:
7402 flags = GOVD_LASTPRIVATE | GOVD_SEEN | GOVD_EXPLICIT;
7403 check_non_private = "lastprivate";
7404 decl = OMP_CLAUSE_DECL (c);
7405 if (error_operand_p (decl))
7406 goto do_add;
7407 else if (outer_ctx
7408 && (outer_ctx->region_type == ORT_COMBINED_PARALLEL
7409 || outer_ctx->region_type == ORT_COMBINED_TEAMS)
7410 && splay_tree_lookup (outer_ctx->variables,
7411 (splay_tree_key) decl) == NULL)
7413 omp_add_variable (outer_ctx, decl, GOVD_SHARED | GOVD_SEEN);
7414 if (outer_ctx->outer_context)
7415 omp_notice_variable (outer_ctx->outer_context, decl, true);
7417 else if (outer_ctx
7418 && (outer_ctx->region_type & ORT_TASK) != 0
7419 && outer_ctx->combined_loop
7420 && splay_tree_lookup (outer_ctx->variables,
7421 (splay_tree_key) decl) == NULL)
7423 omp_add_variable (outer_ctx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
7424 if (outer_ctx->outer_context)
7425 omp_notice_variable (outer_ctx->outer_context, decl, true);
7427 else if (outer_ctx
7428 && (outer_ctx->region_type == ORT_WORKSHARE
7429 || outer_ctx->region_type == ORT_ACC)
7430 && outer_ctx->combined_loop
7431 && splay_tree_lookup (outer_ctx->variables,
7432 (splay_tree_key) decl) == NULL
7433 && !omp_check_private (outer_ctx, decl, false))
7435 omp_add_variable (outer_ctx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
7436 if (outer_ctx->outer_context
7437 && (outer_ctx->outer_context->region_type
7438 == ORT_COMBINED_PARALLEL)
7439 && splay_tree_lookup (outer_ctx->outer_context->variables,
7440 (splay_tree_key) decl) == NULL)
7442 struct gimplify_omp_ctx *octx = outer_ctx->outer_context;
7443 omp_add_variable (octx, decl, GOVD_SHARED | GOVD_SEEN);
7444 if (octx->outer_context)
7446 octx = octx->outer_context;
7447 if (octx->region_type == ORT_WORKSHARE
7448 && octx->combined_loop
7449 && splay_tree_lookup (octx->variables,
7450 (splay_tree_key) decl) == NULL
7451 && !omp_check_private (octx, decl, false))
7453 omp_add_variable (octx, decl,
7454 GOVD_LASTPRIVATE | GOVD_SEEN);
7455 octx = octx->outer_context;
7456 if (octx
7457 && octx->region_type == ORT_COMBINED_TEAMS
7458 && (splay_tree_lookup (octx->variables,
7459 (splay_tree_key) decl)
7460 == NULL))
7462 omp_add_variable (octx, decl,
7463 GOVD_SHARED | GOVD_SEEN);
7464 octx = octx->outer_context;
7467 if (octx)
7468 omp_notice_variable (octx, decl, true);
7471 else if (outer_ctx->outer_context)
7472 omp_notice_variable (outer_ctx->outer_context, decl, true);
7474 goto do_add;
7475 case OMP_CLAUSE_REDUCTION:
7476 flags = GOVD_REDUCTION | GOVD_SEEN | GOVD_EXPLICIT;
7477 /* OpenACC permits reductions on private variables. */
7478 if (!(region_type & ORT_ACC))
7479 check_non_private = "reduction";
7480 decl = OMP_CLAUSE_DECL (c);
7481 if (TREE_CODE (decl) == MEM_REF)
7483 tree type = TREE_TYPE (decl);
7484 if (gimplify_expr (&TYPE_MAX_VALUE (TYPE_DOMAIN (type)), pre_p,
7485 NULL, is_gimple_val, fb_rvalue, false)
7486 == GS_ERROR)
7488 remove = true;
7489 break;
7491 tree v = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
7492 if (DECL_P (v))
7494 omp_firstprivatize_variable (ctx, v);
7495 omp_notice_variable (ctx, v, true);
7497 decl = TREE_OPERAND (decl, 0);
7498 if (TREE_CODE (decl) == POINTER_PLUS_EXPR)
7500 if (gimplify_expr (&TREE_OPERAND (decl, 1), pre_p,
7501 NULL, is_gimple_val, fb_rvalue, false)
7502 == GS_ERROR)
7504 remove = true;
7505 break;
7507 v = TREE_OPERAND (decl, 1);
7508 if (DECL_P (v))
7510 omp_firstprivatize_variable (ctx, v);
7511 omp_notice_variable (ctx, v, true);
7513 decl = TREE_OPERAND (decl, 0);
7515 if (TREE_CODE (decl) == ADDR_EXPR
7516 || TREE_CODE (decl) == INDIRECT_REF)
7517 decl = TREE_OPERAND (decl, 0);
7519 goto do_add_decl;
7520 case OMP_CLAUSE_LINEAR:
7521 if (gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c), pre_p, NULL,
7522 is_gimple_val, fb_rvalue) == GS_ERROR)
7524 remove = true;
7525 break;
7527 else
7529 if (code == OMP_SIMD
7530 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
7532 struct gimplify_omp_ctx *octx = outer_ctx;
7533 if (octx
7534 && octx->region_type == ORT_WORKSHARE
7535 && octx->combined_loop
7536 && !octx->distribute)
7538 if (octx->outer_context
7539 && (octx->outer_context->region_type
7540 == ORT_COMBINED_PARALLEL))
7541 octx = octx->outer_context->outer_context;
7542 else
7543 octx = octx->outer_context;
7545 if (octx
7546 && octx->region_type == ORT_WORKSHARE
7547 && octx->combined_loop
7548 && octx->distribute)
7550 error_at (OMP_CLAUSE_LOCATION (c),
7551 "%<linear%> clause for variable other than "
7552 "loop iterator specified on construct "
7553 "combined with %<distribute%>");
7554 remove = true;
7555 break;
7558 /* For combined #pragma omp parallel for simd, need to put
7559 lastprivate and perhaps firstprivate too on the
7560 parallel. Similarly for #pragma omp for simd. */
7561 struct gimplify_omp_ctx *octx = outer_ctx;
7562 decl = NULL_TREE;
7565 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
7566 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
7567 break;
7568 decl = OMP_CLAUSE_DECL (c);
7569 if (error_operand_p (decl))
7571 decl = NULL_TREE;
7572 break;
7574 flags = GOVD_SEEN;
7575 if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c))
7576 flags |= GOVD_FIRSTPRIVATE;
7577 if (!OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
7578 flags |= GOVD_LASTPRIVATE;
7579 if (octx
7580 && octx->region_type == ORT_WORKSHARE
7581 && octx->combined_loop)
7583 if (octx->outer_context
7584 && (octx->outer_context->region_type
7585 == ORT_COMBINED_PARALLEL))
7586 octx = octx->outer_context;
7587 else if (omp_check_private (octx, decl, false))
7588 break;
7590 else if (octx
7591 && (octx->region_type & ORT_TASK) != 0
7592 && octx->combined_loop)
7594 else if (octx
7595 && octx->region_type == ORT_COMBINED_PARALLEL
7596 && ctx->region_type == ORT_WORKSHARE
7597 && octx == outer_ctx)
7598 flags = GOVD_SEEN | GOVD_SHARED;
7599 else if (octx
7600 && octx->region_type == ORT_COMBINED_TEAMS)
7601 flags = GOVD_SEEN | GOVD_SHARED;
7602 else if (octx
7603 && octx->region_type == ORT_COMBINED_TARGET)
7605 flags &= ~GOVD_LASTPRIVATE;
7606 if (flags == GOVD_SEEN)
7607 break;
7609 else
7610 break;
7611 splay_tree_node on
7612 = splay_tree_lookup (octx->variables,
7613 (splay_tree_key) decl);
7614 if (on && (on->value & GOVD_DATA_SHARE_CLASS) != 0)
7616 octx = NULL;
7617 break;
7619 omp_add_variable (octx, decl, flags);
7620 if (octx->outer_context == NULL)
7621 break;
7622 octx = octx->outer_context;
7624 while (1);
7625 if (octx
7626 && decl
7627 && (!OMP_CLAUSE_LINEAR_NO_COPYIN (c)
7628 || !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
7629 omp_notice_variable (octx, decl, true);
7631 flags = GOVD_LINEAR | GOVD_EXPLICIT;
7632 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
7633 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
7635 notice_outer = false;
7636 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
7638 goto do_add;
7640 case OMP_CLAUSE_MAP:
7641 decl = OMP_CLAUSE_DECL (c);
7642 if (error_operand_p (decl))
7643 remove = true;
7644 switch (code)
7646 case OMP_TARGET:
7647 break;
7648 case OACC_DATA:
7649 if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
7650 break;
7651 /* FALLTHRU */
7652 case OMP_TARGET_DATA:
7653 case OMP_TARGET_ENTER_DATA:
7654 case OMP_TARGET_EXIT_DATA:
7655 case OACC_ENTER_DATA:
7656 case OACC_EXIT_DATA:
7657 case OACC_HOST_DATA:
7658 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
7659 || (OMP_CLAUSE_MAP_KIND (c)
7660 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
7661 /* For target {,enter ,exit }data only the array slice is
7662 mapped, but not the pointer to it. */
7663 remove = true;
7664 break;
7665 default:
7666 break;
7668 if (remove)
7669 break;
7670 if (DECL_P (decl) && outer_ctx && (region_type & ORT_ACC))
7672 struct gimplify_omp_ctx *octx;
7673 for (octx = outer_ctx; octx; octx = octx->outer_context)
7675 if (octx->region_type != ORT_ACC_HOST_DATA)
7676 break;
7677 splay_tree_node n2
7678 = splay_tree_lookup (octx->variables,
7679 (splay_tree_key) decl);
7680 if (n2)
7681 error_at (OMP_CLAUSE_LOCATION (c), "variable %qE "
7682 "declared in enclosing %<host_data%> region",
7683 DECL_NAME (decl));
7686 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
7687 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
7688 : TYPE_SIZE_UNIT (TREE_TYPE (decl));
7689 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
7690 NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
7692 remove = true;
7693 break;
7695 else if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
7696 || (OMP_CLAUSE_MAP_KIND (c)
7697 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
7698 && TREE_CODE (OMP_CLAUSE_SIZE (c)) != INTEGER_CST)
7700 OMP_CLAUSE_SIZE (c)
7701 = get_initialized_tmp_var (OMP_CLAUSE_SIZE (c), pre_p, NULL,
7702 false);
7703 omp_add_variable (ctx, OMP_CLAUSE_SIZE (c),
7704 GOVD_FIRSTPRIVATE | GOVD_SEEN);
7706 if (!DECL_P (decl))
7708 tree d = decl, *pd;
7709 if (TREE_CODE (d) == ARRAY_REF)
7711 while (TREE_CODE (d) == ARRAY_REF)
7712 d = TREE_OPERAND (d, 0);
7713 if (TREE_CODE (d) == COMPONENT_REF
7714 && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE)
7715 decl = d;
7717 pd = &OMP_CLAUSE_DECL (c);
7718 if (d == decl
7719 && TREE_CODE (decl) == INDIRECT_REF
7720 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
7721 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
7722 == REFERENCE_TYPE))
7724 pd = &TREE_OPERAND (decl, 0);
7725 decl = TREE_OPERAND (decl, 0);
7727 if (TREE_CODE (decl) == COMPONENT_REF)
7729 while (TREE_CODE (decl) == COMPONENT_REF)
7730 decl = TREE_OPERAND (decl, 0);
7731 if (TREE_CODE (decl) == INDIRECT_REF
7732 && DECL_P (TREE_OPERAND (decl, 0))
7733 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
7734 == REFERENCE_TYPE))
7735 decl = TREE_OPERAND (decl, 0);
7737 if (gimplify_expr (pd, pre_p, NULL, is_gimple_lvalue, fb_lvalue)
7738 == GS_ERROR)
7740 remove = true;
7741 break;
7743 if (DECL_P (decl))
7745 if (error_operand_p (decl))
7747 remove = true;
7748 break;
7751 tree stype = TREE_TYPE (decl);
7752 if (TREE_CODE (stype) == REFERENCE_TYPE)
7753 stype = TREE_TYPE (stype);
7754 if (TYPE_SIZE_UNIT (stype) == NULL
7755 || TREE_CODE (TYPE_SIZE_UNIT (stype)) != INTEGER_CST)
7757 error_at (OMP_CLAUSE_LOCATION (c),
7758 "mapping field %qE of variable length "
7759 "structure", OMP_CLAUSE_DECL (c));
7760 remove = true;
7761 break;
7764 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER)
7766 /* Error recovery. */
7767 if (prev_list_p == NULL)
7769 remove = true;
7770 break;
7772 if (OMP_CLAUSE_CHAIN (*prev_list_p) != c)
7774 tree ch = OMP_CLAUSE_CHAIN (*prev_list_p);
7775 if (ch == NULL_TREE || OMP_CLAUSE_CHAIN (ch) != c)
7777 remove = true;
7778 break;
7783 tree offset;
7784 HOST_WIDE_INT bitsize, bitpos;
7785 machine_mode mode;
7786 int unsignedp, reversep, volatilep = 0;
7787 tree base = OMP_CLAUSE_DECL (c);
7788 while (TREE_CODE (base) == ARRAY_REF)
7789 base = TREE_OPERAND (base, 0);
7790 if (TREE_CODE (base) == INDIRECT_REF)
7791 base = TREE_OPERAND (base, 0);
7792 base = get_inner_reference (base, &bitsize, &bitpos, &offset,
7793 &mode, &unsignedp, &reversep,
7794 &volatilep);
7795 tree orig_base = base;
7796 if ((TREE_CODE (base) == INDIRECT_REF
7797 || (TREE_CODE (base) == MEM_REF
7798 && integer_zerop (TREE_OPERAND (base, 1))))
7799 && DECL_P (TREE_OPERAND (base, 0))
7800 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0)))
7801 == REFERENCE_TYPE))
7802 base = TREE_OPERAND (base, 0);
7803 gcc_assert (base == decl
7804 && (offset == NULL_TREE
7805 || TREE_CODE (offset) == INTEGER_CST));
7807 splay_tree_node n
7808 = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7809 bool ptr = (OMP_CLAUSE_MAP_KIND (c)
7810 == GOMP_MAP_ALWAYS_POINTER);
7811 if (n == NULL || (n->value & GOVD_MAP) == 0)
7813 tree l = build_omp_clause (OMP_CLAUSE_LOCATION (c),
7814 OMP_CLAUSE_MAP);
7815 OMP_CLAUSE_SET_MAP_KIND (l, GOMP_MAP_STRUCT);
7816 if (orig_base != base)
7817 OMP_CLAUSE_DECL (l) = unshare_expr (orig_base);
7818 else
7819 OMP_CLAUSE_DECL (l) = decl;
7820 OMP_CLAUSE_SIZE (l) = size_int (1);
7821 if (struct_map_to_clause == NULL)
7822 struct_map_to_clause = new hash_map<tree, tree>;
7823 struct_map_to_clause->put (decl, l);
7824 if (ptr)
7826 enum gomp_map_kind mkind
7827 = code == OMP_TARGET_EXIT_DATA
7828 ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
7829 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
7830 OMP_CLAUSE_MAP);
7831 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
7832 OMP_CLAUSE_DECL (c2)
7833 = unshare_expr (OMP_CLAUSE_DECL (c));
7834 OMP_CLAUSE_CHAIN (c2) = *prev_list_p;
7835 OMP_CLAUSE_SIZE (c2)
7836 = TYPE_SIZE_UNIT (ptr_type_node);
7837 OMP_CLAUSE_CHAIN (l) = c2;
7838 if (OMP_CLAUSE_CHAIN (*prev_list_p) != c)
7840 tree c4 = OMP_CLAUSE_CHAIN (*prev_list_p);
7841 tree c3
7842 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
7843 OMP_CLAUSE_MAP);
7844 OMP_CLAUSE_SET_MAP_KIND (c3, mkind);
7845 OMP_CLAUSE_DECL (c3)
7846 = unshare_expr (OMP_CLAUSE_DECL (c4));
7847 OMP_CLAUSE_SIZE (c3)
7848 = TYPE_SIZE_UNIT (ptr_type_node);
7849 OMP_CLAUSE_CHAIN (c3) = *prev_list_p;
7850 OMP_CLAUSE_CHAIN (c2) = c3;
7852 *prev_list_p = l;
7853 prev_list_p = NULL;
7855 else
7857 OMP_CLAUSE_CHAIN (l) = c;
7858 *list_p = l;
7859 list_p = &OMP_CLAUSE_CHAIN (l);
7861 if (orig_base != base && code == OMP_TARGET)
7863 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
7864 OMP_CLAUSE_MAP);
7865 enum gomp_map_kind mkind
7866 = GOMP_MAP_FIRSTPRIVATE_REFERENCE;
7867 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
7868 OMP_CLAUSE_DECL (c2) = decl;
7869 OMP_CLAUSE_SIZE (c2) = size_zero_node;
7870 OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (l);
7871 OMP_CLAUSE_CHAIN (l) = c2;
7873 flags = GOVD_MAP | GOVD_EXPLICIT;
7874 if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) || ptr)
7875 flags |= GOVD_SEEN;
7876 goto do_add_decl;
7878 else
7880 tree *osc = struct_map_to_clause->get (decl);
7881 tree *sc = NULL, *scp = NULL;
7882 if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) || ptr)
7883 n->value |= GOVD_SEEN;
7884 offset_int o1, o2;
7885 if (offset)
7886 o1 = wi::to_offset (offset);
7887 else
7888 o1 = 0;
7889 if (bitpos)
7890 o1 = o1 + bitpos / BITS_PER_UNIT;
7891 sc = &OMP_CLAUSE_CHAIN (*osc);
7892 if (*sc != c
7893 && (OMP_CLAUSE_MAP_KIND (*sc)
7894 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
7895 sc = &OMP_CLAUSE_CHAIN (*sc);
7896 for (; *sc != c; sc = &OMP_CLAUSE_CHAIN (*sc))
7897 if (ptr && sc == prev_list_p)
7898 break;
7899 else if (TREE_CODE (OMP_CLAUSE_DECL (*sc))
7900 != COMPONENT_REF
7901 && (TREE_CODE (OMP_CLAUSE_DECL (*sc))
7902 != INDIRECT_REF)
7903 && (TREE_CODE (OMP_CLAUSE_DECL (*sc))
7904 != ARRAY_REF))
7905 break;
7906 else
7908 tree offset2;
7909 HOST_WIDE_INT bitsize2, bitpos2;
7910 base = OMP_CLAUSE_DECL (*sc);
7911 if (TREE_CODE (base) == ARRAY_REF)
7913 while (TREE_CODE (base) == ARRAY_REF)
7914 base = TREE_OPERAND (base, 0);
7915 if (TREE_CODE (base) != COMPONENT_REF
7916 || (TREE_CODE (TREE_TYPE (base))
7917 != ARRAY_TYPE))
7918 break;
7920 else if (TREE_CODE (base) == INDIRECT_REF
7921 && (TREE_CODE (TREE_OPERAND (base, 0))
7922 == COMPONENT_REF)
7923 && (TREE_CODE (TREE_TYPE
7924 (TREE_OPERAND (base, 0)))
7925 == REFERENCE_TYPE))
7926 base = TREE_OPERAND (base, 0);
7927 base = get_inner_reference (base, &bitsize2,
7928 &bitpos2, &offset2,
7929 &mode, &unsignedp,
7930 &reversep, &volatilep);
7931 if ((TREE_CODE (base) == INDIRECT_REF
7932 || (TREE_CODE (base) == MEM_REF
7933 && integer_zerop (TREE_OPERAND (base,
7934 1))))
7935 && DECL_P (TREE_OPERAND (base, 0))
7936 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (base,
7937 0)))
7938 == REFERENCE_TYPE))
7939 base = TREE_OPERAND (base, 0);
7940 if (base != decl)
7941 break;
7942 if (scp)
7943 continue;
7944 gcc_assert (offset == NULL_TREE
7945 || TREE_CODE (offset) == INTEGER_CST);
7946 tree d1 = OMP_CLAUSE_DECL (*sc);
7947 tree d2 = OMP_CLAUSE_DECL (c);
7948 while (TREE_CODE (d1) == ARRAY_REF)
7949 d1 = TREE_OPERAND (d1, 0);
7950 while (TREE_CODE (d2) == ARRAY_REF)
7951 d2 = TREE_OPERAND (d2, 0);
7952 if (TREE_CODE (d1) == INDIRECT_REF)
7953 d1 = TREE_OPERAND (d1, 0);
7954 if (TREE_CODE (d2) == INDIRECT_REF)
7955 d2 = TREE_OPERAND (d2, 0);
7956 while (TREE_CODE (d1) == COMPONENT_REF)
7957 if (TREE_CODE (d2) == COMPONENT_REF
7958 && TREE_OPERAND (d1, 1)
7959 == TREE_OPERAND (d2, 1))
7961 d1 = TREE_OPERAND (d1, 0);
7962 d2 = TREE_OPERAND (d2, 0);
7964 else
7965 break;
7966 if (d1 == d2)
7968 error_at (OMP_CLAUSE_LOCATION (c),
7969 "%qE appears more than once in map "
7970 "clauses", OMP_CLAUSE_DECL (c));
7971 remove = true;
7972 break;
7974 if (offset2)
7975 o2 = wi::to_offset (offset2);
7976 else
7977 o2 = 0;
7978 if (bitpos2)
7979 o2 = o2 + bitpos2 / BITS_PER_UNIT;
7980 if (wi::ltu_p (o1, o2)
7981 || (wi::eq_p (o1, o2) && bitpos < bitpos2))
7983 if (ptr)
7984 scp = sc;
7985 else
7986 break;
7989 if (remove)
7990 break;
7991 OMP_CLAUSE_SIZE (*osc)
7992 = size_binop (PLUS_EXPR, OMP_CLAUSE_SIZE (*osc),
7993 size_one_node);
7994 if (ptr)
7996 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
7997 OMP_CLAUSE_MAP);
7998 tree cl = NULL_TREE;
7999 enum gomp_map_kind mkind
8000 = code == OMP_TARGET_EXIT_DATA
8001 ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
8002 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
8003 OMP_CLAUSE_DECL (c2)
8004 = unshare_expr (OMP_CLAUSE_DECL (c));
8005 OMP_CLAUSE_CHAIN (c2) = scp ? *scp : *prev_list_p;
8006 OMP_CLAUSE_SIZE (c2)
8007 = TYPE_SIZE_UNIT (ptr_type_node);
8008 cl = scp ? *prev_list_p : c2;
8009 if (OMP_CLAUSE_CHAIN (*prev_list_p) != c)
8011 tree c4 = OMP_CLAUSE_CHAIN (*prev_list_p);
8012 tree c3
8013 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
8014 OMP_CLAUSE_MAP);
8015 OMP_CLAUSE_SET_MAP_KIND (c3, mkind);
8016 OMP_CLAUSE_DECL (c3)
8017 = unshare_expr (OMP_CLAUSE_DECL (c4));
8018 OMP_CLAUSE_SIZE (c3)
8019 = TYPE_SIZE_UNIT (ptr_type_node);
8020 OMP_CLAUSE_CHAIN (c3) = *prev_list_p;
8021 if (!scp)
8022 OMP_CLAUSE_CHAIN (c2) = c3;
8023 else
8024 cl = c3;
8026 if (scp)
8027 *scp = c2;
8028 if (sc == prev_list_p)
8030 *sc = cl;
8031 prev_list_p = NULL;
8033 else
8035 *prev_list_p = OMP_CLAUSE_CHAIN (c);
8036 list_p = prev_list_p;
8037 prev_list_p = NULL;
8038 OMP_CLAUSE_CHAIN (c) = *sc;
8039 *sc = cl;
8040 continue;
8043 else if (*sc != c)
8045 *list_p = OMP_CLAUSE_CHAIN (c);
8046 OMP_CLAUSE_CHAIN (c) = *sc;
8047 *sc = c;
8048 continue;
8052 if (!remove
8053 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_POINTER
8054 && OMP_CLAUSE_CHAIN (c)
8055 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (c)) == OMP_CLAUSE_MAP
8056 && (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
8057 == GOMP_MAP_ALWAYS_POINTER))
8058 prev_list_p = list_p;
8059 break;
8061 flags = GOVD_MAP | GOVD_EXPLICIT;
8062 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TO
8063 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TOFROM)
8064 flags |= GOVD_MAP_ALWAYS_TO;
8065 goto do_add;
8067 case OMP_CLAUSE_DEPEND:
8068 if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
8070 tree deps = OMP_CLAUSE_DECL (c);
8071 while (deps && TREE_CODE (deps) == TREE_LIST)
8073 if (TREE_CODE (TREE_PURPOSE (deps)) == TRUNC_DIV_EXPR
8074 && DECL_P (TREE_OPERAND (TREE_PURPOSE (deps), 1)))
8075 gimplify_expr (&TREE_OPERAND (TREE_PURPOSE (deps), 1),
8076 pre_p, NULL, is_gimple_val, fb_rvalue);
8077 deps = TREE_CHAIN (deps);
8079 break;
8081 else if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
8082 break;
8083 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
8085 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
8086 NULL, is_gimple_val, fb_rvalue);
8087 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
8089 if (error_operand_p (OMP_CLAUSE_DECL (c)))
8091 remove = true;
8092 break;
8094 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
8095 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
8096 is_gimple_val, fb_rvalue) == GS_ERROR)
8098 remove = true;
8099 break;
8101 break;
8103 case OMP_CLAUSE_TO:
8104 case OMP_CLAUSE_FROM:
8105 case OMP_CLAUSE__CACHE_:
8106 decl = OMP_CLAUSE_DECL (c);
8107 if (error_operand_p (decl))
8109 remove = true;
8110 break;
8112 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
8113 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
8114 : TYPE_SIZE_UNIT (TREE_TYPE (decl));
8115 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
8116 NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
8118 remove = true;
8119 break;
8121 if (!DECL_P (decl))
8123 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p,
8124 NULL, is_gimple_lvalue, fb_lvalue)
8125 == GS_ERROR)
8127 remove = true;
8128 break;
8130 break;
8132 goto do_notice;
8134 case OMP_CLAUSE_USE_DEVICE_PTR:
8135 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
8136 goto do_add;
8137 case OMP_CLAUSE_IS_DEVICE_PTR:
8138 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
8139 goto do_add;
8141 do_add:
8142 decl = OMP_CLAUSE_DECL (c);
8143 do_add_decl:
8144 if (error_operand_p (decl))
8146 remove = true;
8147 break;
8149 if (DECL_NAME (decl) == NULL_TREE && (flags & GOVD_SHARED) == 0)
8151 tree t = omp_member_access_dummy_var (decl);
8152 if (t)
8154 tree v = DECL_VALUE_EXPR (decl);
8155 DECL_NAME (decl) = DECL_NAME (TREE_OPERAND (v, 1));
8156 if (outer_ctx)
8157 omp_notice_variable (outer_ctx, t, true);
8160 if (code == OACC_DATA
8161 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
8162 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
8163 flags |= GOVD_MAP_0LEN_ARRAY;
8164 omp_add_variable (ctx, decl, flags);
8165 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
8166 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
8168 omp_add_variable (ctx, OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
8169 GOVD_LOCAL | GOVD_SEEN);
8170 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
8171 && walk_tree (&OMP_CLAUSE_REDUCTION_INIT (c),
8172 find_decl_expr,
8173 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
8174 NULL) == NULL_TREE)
8175 omp_add_variable (ctx,
8176 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
8177 GOVD_LOCAL | GOVD_SEEN);
8178 gimplify_omp_ctxp = ctx;
8179 push_gimplify_context ();
8181 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
8182 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
8184 gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c),
8185 &OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c));
8186 pop_gimplify_context
8187 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c)));
8188 push_gimplify_context ();
8189 gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c),
8190 &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
8191 pop_gimplify_context
8192 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c)));
8193 OMP_CLAUSE_REDUCTION_INIT (c) = NULL_TREE;
8194 OMP_CLAUSE_REDUCTION_MERGE (c) = NULL_TREE;
8196 gimplify_omp_ctxp = outer_ctx;
8198 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
8199 && OMP_CLAUSE_LASTPRIVATE_STMT (c))
8201 gimplify_omp_ctxp = ctx;
8202 push_gimplify_context ();
8203 if (TREE_CODE (OMP_CLAUSE_LASTPRIVATE_STMT (c)) != BIND_EXPR)
8205 tree bind = build3 (BIND_EXPR, void_type_node, NULL,
8206 NULL, NULL);
8207 TREE_SIDE_EFFECTS (bind) = 1;
8208 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LASTPRIVATE_STMT (c);
8209 OMP_CLAUSE_LASTPRIVATE_STMT (c) = bind;
8211 gimplify_and_add (OMP_CLAUSE_LASTPRIVATE_STMT (c),
8212 &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
8213 pop_gimplify_context
8214 (gimple_seq_first_stmt (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c)));
8215 OMP_CLAUSE_LASTPRIVATE_STMT (c) = NULL_TREE;
8217 gimplify_omp_ctxp = outer_ctx;
8219 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
8220 && OMP_CLAUSE_LINEAR_STMT (c))
8222 gimplify_omp_ctxp = ctx;
8223 push_gimplify_context ();
8224 if (TREE_CODE (OMP_CLAUSE_LINEAR_STMT (c)) != BIND_EXPR)
8226 tree bind = build3 (BIND_EXPR, void_type_node, NULL,
8227 NULL, NULL);
8228 TREE_SIDE_EFFECTS (bind) = 1;
8229 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LINEAR_STMT (c);
8230 OMP_CLAUSE_LINEAR_STMT (c) = bind;
8232 gimplify_and_add (OMP_CLAUSE_LINEAR_STMT (c),
8233 &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c));
8234 pop_gimplify_context
8235 (gimple_seq_first_stmt (OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c)));
8236 OMP_CLAUSE_LINEAR_STMT (c) = NULL_TREE;
8238 gimplify_omp_ctxp = outer_ctx;
8240 if (notice_outer)
8241 goto do_notice;
8242 break;
8244 case OMP_CLAUSE_COPYIN:
8245 case OMP_CLAUSE_COPYPRIVATE:
8246 decl = OMP_CLAUSE_DECL (c);
8247 if (error_operand_p (decl))
8249 remove = true;
8250 break;
8252 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_COPYPRIVATE
8253 && !remove
8254 && !omp_check_private (ctx, decl, true))
8256 remove = true;
8257 if (is_global_var (decl))
8259 if (DECL_THREAD_LOCAL_P (decl))
8260 remove = false;
8261 else if (DECL_HAS_VALUE_EXPR_P (decl))
8263 tree value = get_base_address (DECL_VALUE_EXPR (decl));
8265 if (value
8266 && DECL_P (value)
8267 && DECL_THREAD_LOCAL_P (value))
8268 remove = false;
8271 if (remove)
8272 error_at (OMP_CLAUSE_LOCATION (c),
8273 "copyprivate variable %qE is not threadprivate"
8274 " or private in outer context", DECL_NAME (decl));
8276 do_notice:
8277 if (outer_ctx)
8278 omp_notice_variable (outer_ctx, decl, true);
8279 if (check_non_private
8280 && region_type == ORT_WORKSHARE
8281 && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
8282 || decl == OMP_CLAUSE_DECL (c)
8283 || (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
8284 && (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
8285 == ADDR_EXPR
8286 || (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
8287 == POINTER_PLUS_EXPR
8288 && (TREE_CODE (TREE_OPERAND (TREE_OPERAND
8289 (OMP_CLAUSE_DECL (c), 0), 0))
8290 == ADDR_EXPR)))))
8291 && omp_check_private (ctx, decl, false))
8293 error ("%s variable %qE is private in outer context",
8294 check_non_private, DECL_NAME (decl));
8295 remove = true;
8297 break;
8299 case OMP_CLAUSE_IF:
8300 if (OMP_CLAUSE_IF_MODIFIER (c) != ERROR_MARK
8301 && OMP_CLAUSE_IF_MODIFIER (c) != code)
8303 const char *p[2];
8304 for (int i = 0; i < 2; i++)
8305 switch (i ? OMP_CLAUSE_IF_MODIFIER (c) : code)
8307 case OMP_PARALLEL: p[i] = "parallel"; break;
8308 case OMP_TASK: p[i] = "task"; break;
8309 case OMP_TASKLOOP: p[i] = "taskloop"; break;
8310 case OMP_TARGET_DATA: p[i] = "target data"; break;
8311 case OMP_TARGET: p[i] = "target"; break;
8312 case OMP_TARGET_UPDATE: p[i] = "target update"; break;
8313 case OMP_TARGET_ENTER_DATA:
8314 p[i] = "target enter data"; break;
8315 case OMP_TARGET_EXIT_DATA: p[i] = "target exit data"; break;
8316 default: gcc_unreachable ();
8318 error_at (OMP_CLAUSE_LOCATION (c),
8319 "expected %qs %<if%> clause modifier rather than %qs",
8320 p[0], p[1]);
8321 remove = true;
8323 /* Fall through. */
8325 case OMP_CLAUSE_FINAL:
8326 OMP_CLAUSE_OPERAND (c, 0)
8327 = gimple_boolify (OMP_CLAUSE_OPERAND (c, 0));
8328 /* Fall through. */
8330 case OMP_CLAUSE_SCHEDULE:
8331 case OMP_CLAUSE_NUM_THREADS:
8332 case OMP_CLAUSE_NUM_TEAMS:
8333 case OMP_CLAUSE_THREAD_LIMIT:
8334 case OMP_CLAUSE_DIST_SCHEDULE:
8335 case OMP_CLAUSE_DEVICE:
8336 case OMP_CLAUSE_PRIORITY:
8337 case OMP_CLAUSE_GRAINSIZE:
8338 case OMP_CLAUSE_NUM_TASKS:
8339 case OMP_CLAUSE_HINT:
8340 case OMP_CLAUSE__CILK_FOR_COUNT_:
8341 case OMP_CLAUSE_ASYNC:
8342 case OMP_CLAUSE_WAIT:
8343 case OMP_CLAUSE_NUM_GANGS:
8344 case OMP_CLAUSE_NUM_WORKERS:
8345 case OMP_CLAUSE_VECTOR_LENGTH:
8346 case OMP_CLAUSE_WORKER:
8347 case OMP_CLAUSE_VECTOR:
8348 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
8349 is_gimple_val, fb_rvalue) == GS_ERROR)
8350 remove = true;
8351 break;
8353 case OMP_CLAUSE_GANG:
8354 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
8355 is_gimple_val, fb_rvalue) == GS_ERROR)
8356 remove = true;
8357 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 1), pre_p, NULL,
8358 is_gimple_val, fb_rvalue) == GS_ERROR)
8359 remove = true;
8360 break;
8362 case OMP_CLAUSE_NOWAIT:
8363 case OMP_CLAUSE_ORDERED:
8364 case OMP_CLAUSE_UNTIED:
8365 case OMP_CLAUSE_COLLAPSE:
8366 case OMP_CLAUSE_TILE:
8367 case OMP_CLAUSE_AUTO:
8368 case OMP_CLAUSE_SEQ:
8369 case OMP_CLAUSE_INDEPENDENT:
8370 case OMP_CLAUSE_MERGEABLE:
8371 case OMP_CLAUSE_PROC_BIND:
8372 case OMP_CLAUSE_SAFELEN:
8373 case OMP_CLAUSE_SIMDLEN:
8374 case OMP_CLAUSE_NOGROUP:
8375 case OMP_CLAUSE_THREADS:
8376 case OMP_CLAUSE_SIMD:
8377 break;
8379 case OMP_CLAUSE_DEFAULTMAP:
8380 ctx->target_map_scalars_firstprivate = false;
8381 break;
8383 case OMP_CLAUSE_ALIGNED:
8384 decl = OMP_CLAUSE_DECL (c);
8385 if (error_operand_p (decl))
8387 remove = true;
8388 break;
8390 if (gimplify_expr (&OMP_CLAUSE_ALIGNED_ALIGNMENT (c), pre_p, NULL,
8391 is_gimple_val, fb_rvalue) == GS_ERROR)
8393 remove = true;
8394 break;
8396 if (!is_global_var (decl)
8397 && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
8398 omp_add_variable (ctx, decl, GOVD_ALIGNED);
8399 break;
8401 case OMP_CLAUSE_DEFAULT:
8402 ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
8403 break;
8405 default:
8406 gcc_unreachable ();
8409 if (code == OACC_DATA
8410 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
8411 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
8412 remove = true;
8413 if (remove)
8414 *list_p = OMP_CLAUSE_CHAIN (c);
8415 else
8416 list_p = &OMP_CLAUSE_CHAIN (c);
8419 gimplify_omp_ctxp = ctx;
8420 if (struct_map_to_clause)
8421 delete struct_map_to_clause;
8424 /* Return true if DECL is a candidate for shared to firstprivate
8425 optimization. We only consider non-addressable scalars, not
8426 too big, and not references. */
8428 static bool
8429 omp_shared_to_firstprivate_optimizable_decl_p (tree decl)
8431 if (TREE_ADDRESSABLE (decl))
8432 return false;
8433 tree type = TREE_TYPE (decl);
8434 if (!is_gimple_reg_type (type)
8435 || TREE_CODE (type) == REFERENCE_TYPE
8436 || TREE_ADDRESSABLE (type))
8437 return false;
8438 /* Don't optimize too large decls, as each thread/task will have
8439 its own. */
8440 HOST_WIDE_INT len = int_size_in_bytes (type);
8441 if (len == -1 || len > 4 * POINTER_SIZE / BITS_PER_UNIT)
8442 return false;
8443 if (lang_hooks.decls.omp_privatize_by_reference (decl))
8444 return false;
8445 return true;
8448 /* Helper function of omp_find_stores_op and gimplify_adjust_omp_clauses*.
8449 For omp_shared_to_firstprivate_optimizable_decl_p decl mark it as
8450 GOVD_WRITTEN in outer contexts. */
8452 static void
8453 omp_mark_stores (struct gimplify_omp_ctx *ctx, tree decl)
8455 for (; ctx; ctx = ctx->outer_context)
8457 splay_tree_node n = splay_tree_lookup (ctx->variables,
8458 (splay_tree_key) decl);
8459 if (n == NULL)
8460 continue;
8461 else if (n->value & GOVD_SHARED)
8463 n->value |= GOVD_WRITTEN;
8464 return;
8466 else if (n->value & GOVD_DATA_SHARE_CLASS)
8467 return;
8471 /* Helper callback for walk_gimple_seq to discover possible stores
8472 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
8473 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
8474 for those. */
8476 static tree
8477 omp_find_stores_op (tree *tp, int *walk_subtrees, void *data)
8479 struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
8481 *walk_subtrees = 0;
8482 if (!wi->is_lhs)
8483 return NULL_TREE;
8485 tree op = *tp;
8488 if (handled_component_p (op))
8489 op = TREE_OPERAND (op, 0);
8490 else if ((TREE_CODE (op) == MEM_REF || TREE_CODE (op) == TARGET_MEM_REF)
8491 && TREE_CODE (TREE_OPERAND (op, 0)) == ADDR_EXPR)
8492 op = TREE_OPERAND (TREE_OPERAND (op, 0), 0);
8493 else
8494 break;
8496 while (1);
8497 if (!DECL_P (op) || !omp_shared_to_firstprivate_optimizable_decl_p (op))
8498 return NULL_TREE;
8500 omp_mark_stores (gimplify_omp_ctxp, op);
8501 return NULL_TREE;
8504 /* Helper callback for walk_gimple_seq to discover possible stores
8505 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
8506 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
8507 for those. */
8509 static tree
8510 omp_find_stores_stmt (gimple_stmt_iterator *gsi_p,
8511 bool *handled_ops_p,
8512 struct walk_stmt_info *wi)
8514 gimple *stmt = gsi_stmt (*gsi_p);
8515 switch (gimple_code (stmt))
8517 /* Don't recurse on OpenMP constructs for which
8518 gimplify_adjust_omp_clauses already handled the bodies,
8519 except handle gimple_omp_for_pre_body. */
8520 case GIMPLE_OMP_FOR:
8521 *handled_ops_p = true;
8522 if (gimple_omp_for_pre_body (stmt))
8523 walk_gimple_seq (gimple_omp_for_pre_body (stmt),
8524 omp_find_stores_stmt, omp_find_stores_op, wi);
8525 break;
8526 case GIMPLE_OMP_PARALLEL:
8527 case GIMPLE_OMP_TASK:
8528 case GIMPLE_OMP_SECTIONS:
8529 case GIMPLE_OMP_SINGLE:
8530 case GIMPLE_OMP_TARGET:
8531 case GIMPLE_OMP_TEAMS:
8532 case GIMPLE_OMP_CRITICAL:
8533 *handled_ops_p = true;
8534 break;
8535 default:
8536 break;
8538 return NULL_TREE;
8541 struct gimplify_adjust_omp_clauses_data
8543 tree *list_p;
8544 gimple_seq *pre_p;
8547 /* For all variables that were not actually used within the context,
8548 remove PRIVATE, SHARED, and FIRSTPRIVATE clauses. */
8550 static int
8551 gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
8553 tree *list_p = ((struct gimplify_adjust_omp_clauses_data *) data)->list_p;
8554 gimple_seq *pre_p
8555 = ((struct gimplify_adjust_omp_clauses_data *) data)->pre_p;
8556 tree decl = (tree) n->key;
8557 unsigned flags = n->value;
8558 enum omp_clause_code code;
8559 tree clause;
8560 bool private_debug;
8562 if (flags & (GOVD_EXPLICIT | GOVD_LOCAL))
8563 return 0;
8564 if ((flags & GOVD_SEEN) == 0)
8565 return 0;
8566 if (flags & GOVD_DEBUG_PRIVATE)
8568 gcc_assert ((flags & GOVD_DATA_SHARE_CLASS) == GOVD_PRIVATE);
8569 private_debug = true;
8571 else if (flags & GOVD_MAP)
8572 private_debug = false;
8573 else
8574 private_debug
8575 = lang_hooks.decls.omp_private_debug_clause (decl,
8576 !!(flags & GOVD_SHARED));
8577 if (private_debug)
8578 code = OMP_CLAUSE_PRIVATE;
8579 else if (flags & GOVD_MAP)
8581 code = OMP_CLAUSE_MAP;
8582 if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0
8583 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
8585 error ("%<_Atomic%> %qD in implicit %<map%> clause", decl);
8586 return 0;
8589 else if (flags & GOVD_SHARED)
8591 if (is_global_var (decl))
8593 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
8594 while (ctx != NULL)
8596 splay_tree_node on
8597 = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
8598 if (on && (on->value & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
8599 | GOVD_PRIVATE | GOVD_REDUCTION
8600 | GOVD_LINEAR | GOVD_MAP)) != 0)
8601 break;
8602 ctx = ctx->outer_context;
8604 if (ctx == NULL)
8605 return 0;
8607 code = OMP_CLAUSE_SHARED;
8609 else if (flags & GOVD_PRIVATE)
8610 code = OMP_CLAUSE_PRIVATE;
8611 else if (flags & GOVD_FIRSTPRIVATE)
8613 code = OMP_CLAUSE_FIRSTPRIVATE;
8614 if ((gimplify_omp_ctxp->region_type & ORT_TARGET)
8615 && (gimplify_omp_ctxp->region_type & ORT_ACC) == 0
8616 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
8618 error ("%<_Atomic%> %qD in implicit %<firstprivate%> clause on "
8619 "%<target%> construct", decl);
8620 return 0;
8623 else if (flags & GOVD_LASTPRIVATE)
8624 code = OMP_CLAUSE_LASTPRIVATE;
8625 else if (flags & GOVD_ALIGNED)
8626 return 0;
8627 else
8628 gcc_unreachable ();
8630 if (((flags & GOVD_LASTPRIVATE)
8631 || (code == OMP_CLAUSE_SHARED && (flags & GOVD_WRITTEN)))
8632 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
8633 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
8635 tree chain = *list_p;
8636 clause = build_omp_clause (input_location, code);
8637 OMP_CLAUSE_DECL (clause) = decl;
8638 OMP_CLAUSE_CHAIN (clause) = chain;
8639 if (private_debug)
8640 OMP_CLAUSE_PRIVATE_DEBUG (clause) = 1;
8641 else if (code == OMP_CLAUSE_PRIVATE && (flags & GOVD_PRIVATE_OUTER_REF))
8642 OMP_CLAUSE_PRIVATE_OUTER_REF (clause) = 1;
8643 else if (code == OMP_CLAUSE_SHARED
8644 && (flags & GOVD_WRITTEN) == 0
8645 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
8646 OMP_CLAUSE_SHARED_READONLY (clause) = 1;
8647 else if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_EXPLICIT) == 0)
8648 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (clause) = 1;
8649 else if (code == OMP_CLAUSE_MAP && (flags & GOVD_MAP_0LEN_ARRAY) != 0)
8651 tree nc = build_omp_clause (input_location, OMP_CLAUSE_MAP);
8652 OMP_CLAUSE_DECL (nc) = decl;
8653 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
8654 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == POINTER_TYPE)
8655 OMP_CLAUSE_DECL (clause)
8656 = build_simple_mem_ref_loc (input_location, decl);
8657 OMP_CLAUSE_DECL (clause)
8658 = build2 (MEM_REF, char_type_node, OMP_CLAUSE_DECL (clause),
8659 build_int_cst (build_pointer_type (char_type_node), 0));
8660 OMP_CLAUSE_SIZE (clause) = size_zero_node;
8661 OMP_CLAUSE_SIZE (nc) = size_zero_node;
8662 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_ALLOC);
8663 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (clause) = 1;
8664 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
8665 OMP_CLAUSE_CHAIN (nc) = chain;
8666 OMP_CLAUSE_CHAIN (clause) = nc;
8667 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
8668 gimplify_omp_ctxp = ctx->outer_context;
8669 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (clause), 0),
8670 pre_p, NULL, is_gimple_val, fb_rvalue);
8671 gimplify_omp_ctxp = ctx;
8673 else if (code == OMP_CLAUSE_MAP)
8675 int kind = (flags & GOVD_MAP_TO_ONLY
8676 ? GOMP_MAP_TO
8677 : GOMP_MAP_TOFROM);
8678 if (flags & GOVD_MAP_FORCE)
8679 kind |= GOMP_MAP_FLAG_FORCE;
8680 OMP_CLAUSE_SET_MAP_KIND (clause, kind);
8681 if (DECL_SIZE (decl)
8682 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
8684 tree decl2 = DECL_VALUE_EXPR (decl);
8685 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
8686 decl2 = TREE_OPERAND (decl2, 0);
8687 gcc_assert (DECL_P (decl2));
8688 tree mem = build_simple_mem_ref (decl2);
8689 OMP_CLAUSE_DECL (clause) = mem;
8690 OMP_CLAUSE_SIZE (clause) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
8691 if (gimplify_omp_ctxp->outer_context)
8693 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
8694 omp_notice_variable (ctx, decl2, true);
8695 omp_notice_variable (ctx, OMP_CLAUSE_SIZE (clause), true);
8697 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
8698 OMP_CLAUSE_MAP);
8699 OMP_CLAUSE_DECL (nc) = decl;
8700 OMP_CLAUSE_SIZE (nc) = size_zero_node;
8701 if (gimplify_omp_ctxp->target_firstprivatize_array_bases)
8702 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
8703 else
8704 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
8705 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
8706 OMP_CLAUSE_CHAIN (clause) = nc;
8708 else if (gimplify_omp_ctxp->target_firstprivatize_array_bases
8709 && lang_hooks.decls.omp_privatize_by_reference (decl))
8711 OMP_CLAUSE_DECL (clause) = build_simple_mem_ref (decl);
8712 OMP_CLAUSE_SIZE (clause)
8713 = unshare_expr (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))));
8714 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
8715 gimplify_omp_ctxp = ctx->outer_context;
8716 gimplify_expr (&OMP_CLAUSE_SIZE (clause),
8717 pre_p, NULL, is_gimple_val, fb_rvalue);
8718 gimplify_omp_ctxp = ctx;
8719 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
8720 OMP_CLAUSE_MAP);
8721 OMP_CLAUSE_DECL (nc) = decl;
8722 OMP_CLAUSE_SIZE (nc) = size_zero_node;
8723 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_REFERENCE);
8724 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
8725 OMP_CLAUSE_CHAIN (clause) = nc;
8727 else
8728 OMP_CLAUSE_SIZE (clause) = DECL_SIZE_UNIT (decl);
8730 if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_LASTPRIVATE) != 0)
8732 tree nc = build_omp_clause (input_location, OMP_CLAUSE_LASTPRIVATE);
8733 OMP_CLAUSE_DECL (nc) = decl;
8734 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (nc) = 1;
8735 OMP_CLAUSE_CHAIN (nc) = chain;
8736 OMP_CLAUSE_CHAIN (clause) = nc;
8737 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
8738 gimplify_omp_ctxp = ctx->outer_context;
8739 lang_hooks.decls.omp_finish_clause (nc, pre_p);
8740 gimplify_omp_ctxp = ctx;
8742 *list_p = clause;
8743 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
8744 gimplify_omp_ctxp = ctx->outer_context;
8745 lang_hooks.decls.omp_finish_clause (clause, pre_p);
8746 if (gimplify_omp_ctxp)
8747 for (; clause != chain; clause = OMP_CLAUSE_CHAIN (clause))
8748 if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_MAP
8749 && DECL_P (OMP_CLAUSE_SIZE (clause)))
8750 omp_notice_variable (gimplify_omp_ctxp, OMP_CLAUSE_SIZE (clause),
8751 true);
8752 gimplify_omp_ctxp = ctx;
8753 return 0;
8756 static void
8757 gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
8758 enum tree_code code)
8760 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
8761 tree c, decl;
8763 if (body)
8765 struct gimplify_omp_ctx *octx;
8766 for (octx = ctx; octx; octx = octx->outer_context)
8767 if ((octx->region_type & (ORT_PARALLEL | ORT_TASK | ORT_TEAMS)) != 0)
8768 break;
8769 if (octx)
8771 struct walk_stmt_info wi;
8772 memset (&wi, 0, sizeof (wi));
8773 walk_gimple_seq (body, omp_find_stores_stmt,
8774 omp_find_stores_op, &wi);
8777 while ((c = *list_p) != NULL)
8779 splay_tree_node n;
8780 bool remove = false;
8782 switch (OMP_CLAUSE_CODE (c))
8784 case OMP_CLAUSE_FIRSTPRIVATE:
8785 if ((ctx->region_type & ORT_TARGET)
8786 && (ctx->region_type & ORT_ACC) == 0
8787 && TYPE_ATOMIC (strip_array_types
8788 (TREE_TYPE (OMP_CLAUSE_DECL (c)))))
8790 error_at (OMP_CLAUSE_LOCATION (c),
8791 "%<_Atomic%> %qD in %<firstprivate%> clause on "
8792 "%<target%> construct", OMP_CLAUSE_DECL (c));
8793 remove = true;
8794 break;
8796 /* FALLTHRU */
8797 case OMP_CLAUSE_PRIVATE:
8798 case OMP_CLAUSE_SHARED:
8799 case OMP_CLAUSE_LINEAR:
8800 decl = OMP_CLAUSE_DECL (c);
8801 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
8802 remove = !(n->value & GOVD_SEEN);
8803 if (! remove)
8805 bool shared = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED;
8806 if ((n->value & GOVD_DEBUG_PRIVATE)
8807 || lang_hooks.decls.omp_private_debug_clause (decl, shared))
8809 gcc_assert ((n->value & GOVD_DEBUG_PRIVATE) == 0
8810 || ((n->value & GOVD_DATA_SHARE_CLASS)
8811 == GOVD_PRIVATE));
8812 OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_PRIVATE);
8813 OMP_CLAUSE_PRIVATE_DEBUG (c) = 1;
8815 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
8816 && (n->value & GOVD_WRITTEN) == 0
8817 && DECL_P (decl)
8818 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
8819 OMP_CLAUSE_SHARED_READONLY (c) = 1;
8820 else if (DECL_P (decl)
8821 && ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
8822 && (n->value & GOVD_WRITTEN) != 1)
8823 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
8824 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
8825 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
8826 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
8828 break;
8830 case OMP_CLAUSE_LASTPRIVATE:
8831 /* Make sure OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE is set to
8832 accurately reflect the presence of a FIRSTPRIVATE clause. */
8833 decl = OMP_CLAUSE_DECL (c);
8834 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
8835 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c)
8836 = (n->value & GOVD_FIRSTPRIVATE) != 0;
8837 if (code == OMP_DISTRIBUTE
8838 && OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
8840 remove = true;
8841 error_at (OMP_CLAUSE_LOCATION (c),
8842 "same variable used in %<firstprivate%> and "
8843 "%<lastprivate%> clauses on %<distribute%> "
8844 "construct");
8846 if (!remove
8847 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
8848 && DECL_P (decl)
8849 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
8850 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
8851 break;
8853 case OMP_CLAUSE_ALIGNED:
8854 decl = OMP_CLAUSE_DECL (c);
8855 if (!is_global_var (decl))
8857 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
8858 remove = n == NULL || !(n->value & GOVD_SEEN);
8859 if (!remove && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
8861 struct gimplify_omp_ctx *octx;
8862 if (n != NULL
8863 && (n->value & (GOVD_DATA_SHARE_CLASS
8864 & ~GOVD_FIRSTPRIVATE)))
8865 remove = true;
8866 else
8867 for (octx = ctx->outer_context; octx;
8868 octx = octx->outer_context)
8870 n = splay_tree_lookup (octx->variables,
8871 (splay_tree_key) decl);
8872 if (n == NULL)
8873 continue;
8874 if (n->value & GOVD_LOCAL)
8875 break;
8876 /* We have to avoid assigning a shared variable
8877 to itself when trying to add
8878 __builtin_assume_aligned. */
8879 if (n->value & GOVD_SHARED)
8881 remove = true;
8882 break;
8887 else if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
8889 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
8890 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
8891 remove = true;
8893 break;
8895 case OMP_CLAUSE_MAP:
8896 if (code == OMP_TARGET_EXIT_DATA
8897 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER)
8899 remove = true;
8900 break;
8902 decl = OMP_CLAUSE_DECL (c);
8903 /* Data clauses associated with acc parallel reductions must be
8904 compatible with present_or_copy. Warn and adjust the clause
8905 if that is not the case. */
8906 if (ctx->region_type == ORT_ACC_PARALLEL)
8908 tree t = DECL_P (decl) ? decl : TREE_OPERAND (decl, 0);
8909 n = NULL;
8911 if (DECL_P (t))
8912 n = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
8914 if (n && (n->value & GOVD_REDUCTION))
8916 enum gomp_map_kind kind = OMP_CLAUSE_MAP_KIND (c);
8918 OMP_CLAUSE_MAP_IN_REDUCTION (c) = 1;
8919 if ((kind & GOMP_MAP_TOFROM) != GOMP_MAP_TOFROM
8920 && kind != GOMP_MAP_FORCE_PRESENT
8921 && kind != GOMP_MAP_POINTER)
8923 warning_at (OMP_CLAUSE_LOCATION (c), 0,
8924 "incompatible data clause with reduction "
8925 "on %qE; promoting to present_or_copy",
8926 DECL_NAME (t));
8927 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TOFROM);
8931 if (!DECL_P (decl))
8933 if ((ctx->region_type & ORT_TARGET) != 0
8934 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
8936 if (TREE_CODE (decl) == INDIRECT_REF
8937 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
8938 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
8939 == REFERENCE_TYPE))
8940 decl = TREE_OPERAND (decl, 0);
8941 if (TREE_CODE (decl) == COMPONENT_REF)
8943 while (TREE_CODE (decl) == COMPONENT_REF)
8944 decl = TREE_OPERAND (decl, 0);
8945 if (DECL_P (decl))
8947 n = splay_tree_lookup (ctx->variables,
8948 (splay_tree_key) decl);
8949 if (!(n->value & GOVD_SEEN))
8950 remove = true;
8954 break;
8956 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
8957 if ((ctx->region_type & ORT_TARGET) != 0
8958 && !(n->value & GOVD_SEEN)
8959 && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) == 0
8960 && (!is_global_var (decl)
8961 || !lookup_attribute ("omp declare target link",
8962 DECL_ATTRIBUTES (decl))))
8964 remove = true;
8965 /* For struct element mapping, if struct is never referenced
8966 in target block and none of the mapping has always modifier,
8967 remove all the struct element mappings, which immediately
8968 follow the GOMP_MAP_STRUCT map clause. */
8969 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT)
8971 HOST_WIDE_INT cnt = tree_to_shwi (OMP_CLAUSE_SIZE (c));
8972 while (cnt--)
8973 OMP_CLAUSE_CHAIN (c)
8974 = OMP_CLAUSE_CHAIN (OMP_CLAUSE_CHAIN (c));
8977 else if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT
8978 && code == OMP_TARGET_EXIT_DATA)
8979 remove = true;
8980 else if (DECL_SIZE (decl)
8981 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST
8982 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_POINTER
8983 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_POINTER
8984 && (OMP_CLAUSE_MAP_KIND (c)
8985 != GOMP_MAP_FIRSTPRIVATE_REFERENCE))
8987 /* For GOMP_MAP_FORCE_DEVICEPTR, we'll never enter here, because
8988 for these, TREE_CODE (DECL_SIZE (decl)) will always be
8989 INTEGER_CST. */
8990 gcc_assert (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FORCE_DEVICEPTR);
8992 tree decl2 = DECL_VALUE_EXPR (decl);
8993 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
8994 decl2 = TREE_OPERAND (decl2, 0);
8995 gcc_assert (DECL_P (decl2));
8996 tree mem = build_simple_mem_ref (decl2);
8997 OMP_CLAUSE_DECL (c) = mem;
8998 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
8999 if (ctx->outer_context)
9001 omp_notice_variable (ctx->outer_context, decl2, true);
9002 omp_notice_variable (ctx->outer_context,
9003 OMP_CLAUSE_SIZE (c), true);
9005 if (((ctx->region_type & ORT_TARGET) != 0
9006 || !ctx->target_firstprivatize_array_bases)
9007 && ((n->value & GOVD_SEEN) == 0
9008 || (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) == 0))
9010 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9011 OMP_CLAUSE_MAP);
9012 OMP_CLAUSE_DECL (nc) = decl;
9013 OMP_CLAUSE_SIZE (nc) = size_zero_node;
9014 if (ctx->target_firstprivatize_array_bases)
9015 OMP_CLAUSE_SET_MAP_KIND (nc,
9016 GOMP_MAP_FIRSTPRIVATE_POINTER);
9017 else
9018 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
9019 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
9020 OMP_CLAUSE_CHAIN (c) = nc;
9021 c = nc;
9024 else
9026 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
9027 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
9028 gcc_assert ((n->value & GOVD_SEEN) == 0
9029 || ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
9030 == 0));
9032 break;
9034 case OMP_CLAUSE_TO:
9035 case OMP_CLAUSE_FROM:
9036 case OMP_CLAUSE__CACHE_:
9037 decl = OMP_CLAUSE_DECL (c);
9038 if (!DECL_P (decl))
9039 break;
9040 if (DECL_SIZE (decl)
9041 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
9043 tree decl2 = DECL_VALUE_EXPR (decl);
9044 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
9045 decl2 = TREE_OPERAND (decl2, 0);
9046 gcc_assert (DECL_P (decl2));
9047 tree mem = build_simple_mem_ref (decl2);
9048 OMP_CLAUSE_DECL (c) = mem;
9049 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
9050 if (ctx->outer_context)
9052 omp_notice_variable (ctx->outer_context, decl2, true);
9053 omp_notice_variable (ctx->outer_context,
9054 OMP_CLAUSE_SIZE (c), true);
9057 else if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
9058 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
9059 break;
9061 case OMP_CLAUSE_REDUCTION:
9062 decl = OMP_CLAUSE_DECL (c);
9063 /* OpenACC reductions need a present_or_copy data clause.
9064 Add one if necessary. Error is the reduction is private. */
9065 if (ctx->region_type == ORT_ACC_PARALLEL)
9067 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
9068 if (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
9069 error_at (OMP_CLAUSE_LOCATION (c), "invalid private "
9070 "reduction on %qE", DECL_NAME (decl));
9071 else if ((n->value & GOVD_MAP) == 0)
9073 tree next = OMP_CLAUSE_CHAIN (c);
9074 tree nc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_MAP);
9075 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_TOFROM);
9076 OMP_CLAUSE_DECL (nc) = decl;
9077 OMP_CLAUSE_CHAIN (c) = nc;
9078 lang_hooks.decls.omp_finish_clause (nc, pre_p);
9079 while (1)
9081 OMP_CLAUSE_MAP_IN_REDUCTION (nc) = 1;
9082 if (OMP_CLAUSE_CHAIN (nc) == NULL)
9083 break;
9084 nc = OMP_CLAUSE_CHAIN (nc);
9086 OMP_CLAUSE_CHAIN (nc) = next;
9087 n->value |= GOVD_MAP;
9090 if (DECL_P (decl)
9091 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
9092 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
9093 break;
9094 case OMP_CLAUSE_COPYIN:
9095 case OMP_CLAUSE_COPYPRIVATE:
9096 case OMP_CLAUSE_IF:
9097 case OMP_CLAUSE_NUM_THREADS:
9098 case OMP_CLAUSE_NUM_TEAMS:
9099 case OMP_CLAUSE_THREAD_LIMIT:
9100 case OMP_CLAUSE_DIST_SCHEDULE:
9101 case OMP_CLAUSE_DEVICE:
9102 case OMP_CLAUSE_SCHEDULE:
9103 case OMP_CLAUSE_NOWAIT:
9104 case OMP_CLAUSE_ORDERED:
9105 case OMP_CLAUSE_DEFAULT:
9106 case OMP_CLAUSE_UNTIED:
9107 case OMP_CLAUSE_COLLAPSE:
9108 case OMP_CLAUSE_FINAL:
9109 case OMP_CLAUSE_MERGEABLE:
9110 case OMP_CLAUSE_PROC_BIND:
9111 case OMP_CLAUSE_SAFELEN:
9112 case OMP_CLAUSE_SIMDLEN:
9113 case OMP_CLAUSE_DEPEND:
9114 case OMP_CLAUSE_PRIORITY:
9115 case OMP_CLAUSE_GRAINSIZE:
9116 case OMP_CLAUSE_NUM_TASKS:
9117 case OMP_CLAUSE_NOGROUP:
9118 case OMP_CLAUSE_THREADS:
9119 case OMP_CLAUSE_SIMD:
9120 case OMP_CLAUSE_HINT:
9121 case OMP_CLAUSE_DEFAULTMAP:
9122 case OMP_CLAUSE_USE_DEVICE_PTR:
9123 case OMP_CLAUSE_IS_DEVICE_PTR:
9124 case OMP_CLAUSE__CILK_FOR_COUNT_:
9125 case OMP_CLAUSE_ASYNC:
9126 case OMP_CLAUSE_WAIT:
9127 case OMP_CLAUSE_INDEPENDENT:
9128 case OMP_CLAUSE_NUM_GANGS:
9129 case OMP_CLAUSE_NUM_WORKERS:
9130 case OMP_CLAUSE_VECTOR_LENGTH:
9131 case OMP_CLAUSE_GANG:
9132 case OMP_CLAUSE_WORKER:
9133 case OMP_CLAUSE_VECTOR:
9134 case OMP_CLAUSE_AUTO:
9135 case OMP_CLAUSE_SEQ:
9136 case OMP_CLAUSE_TILE:
9137 break;
9139 default:
9140 gcc_unreachable ();
9143 if (remove)
9144 *list_p = OMP_CLAUSE_CHAIN (c);
9145 else
9146 list_p = &OMP_CLAUSE_CHAIN (c);
9149 /* Add in any implicit data sharing. */
9150 struct gimplify_adjust_omp_clauses_data data;
9151 data.list_p = list_p;
9152 data.pre_p = pre_p;
9153 splay_tree_foreach (ctx->variables, gimplify_adjust_omp_clauses_1, &data);
9155 gimplify_omp_ctxp = ctx->outer_context;
9156 delete_omp_context (ctx);
9159 /* Gimplify OACC_CACHE. */
9161 static void
9162 gimplify_oacc_cache (tree *expr_p, gimple_seq *pre_p)
9164 tree expr = *expr_p;
9166 gimplify_scan_omp_clauses (&OACC_CACHE_CLAUSES (expr), pre_p, ORT_ACC,
9167 OACC_CACHE);
9168 gimplify_adjust_omp_clauses (pre_p, NULL, &OACC_CACHE_CLAUSES (expr),
9169 OACC_CACHE);
9171 /* TODO: Do something sensible with this information. */
9173 *expr_p = NULL_TREE;
9176 /* Helper function of gimplify_oacc_declare. The helper's purpose is to,
9177 if required, translate 'kind' in CLAUSE into an 'entry' kind and 'exit'
9178 kind. The entry kind will replace the one in CLAUSE, while the exit
9179 kind will be used in a new omp_clause and returned to the caller. */
9181 static tree
9182 gimplify_oacc_declare_1 (tree clause)
9184 HOST_WIDE_INT kind, new_op;
9185 bool ret = false;
9186 tree c = NULL;
9188 kind = OMP_CLAUSE_MAP_KIND (clause);
9190 switch (kind)
9192 case GOMP_MAP_ALLOC:
9193 case GOMP_MAP_FORCE_ALLOC:
9194 case GOMP_MAP_FORCE_TO:
9195 new_op = GOMP_MAP_DELETE;
9196 ret = true;
9197 break;
9199 case GOMP_MAP_FORCE_FROM:
9200 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_FORCE_ALLOC);
9201 new_op = GOMP_MAP_FORCE_FROM;
9202 ret = true;
9203 break;
9205 case GOMP_MAP_FORCE_TOFROM:
9206 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_FORCE_TO);
9207 new_op = GOMP_MAP_FORCE_FROM;
9208 ret = true;
9209 break;
9211 case GOMP_MAP_FROM:
9212 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_FORCE_ALLOC);
9213 new_op = GOMP_MAP_FROM;
9214 ret = true;
9215 break;
9217 case GOMP_MAP_TOFROM:
9218 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_TO);
9219 new_op = GOMP_MAP_FROM;
9220 ret = true;
9221 break;
9223 case GOMP_MAP_DEVICE_RESIDENT:
9224 case GOMP_MAP_FORCE_DEVICEPTR:
9225 case GOMP_MAP_FORCE_PRESENT:
9226 case GOMP_MAP_LINK:
9227 case GOMP_MAP_POINTER:
9228 case GOMP_MAP_TO:
9229 break;
9231 default:
9232 gcc_unreachable ();
9233 break;
9236 if (ret)
9238 c = build_omp_clause (OMP_CLAUSE_LOCATION (clause), OMP_CLAUSE_MAP);
9239 OMP_CLAUSE_SET_MAP_KIND (c, new_op);
9240 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clause);
9243 return c;
9246 /* Gimplify OACC_DECLARE. */
9248 static void
9249 gimplify_oacc_declare (tree *expr_p, gimple_seq *pre_p)
9251 tree expr = *expr_p;
9252 gomp_target *stmt;
9253 tree clauses, t, decl;
9255 clauses = OACC_DECLARE_CLAUSES (expr);
9257 gimplify_scan_omp_clauses (&clauses, pre_p, ORT_TARGET_DATA, OACC_DECLARE);
9258 gimplify_adjust_omp_clauses (pre_p, NULL, &clauses, OACC_DECLARE);
9260 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
9262 decl = OMP_CLAUSE_DECL (t);
9264 if (TREE_CODE (decl) == MEM_REF)
9265 decl = TREE_OPERAND (decl, 0);
9267 if (VAR_P (decl) && !is_oacc_declared (decl))
9269 tree attr = get_identifier ("oacc declare target");
9270 DECL_ATTRIBUTES (decl) = tree_cons (attr, NULL_TREE,
9271 DECL_ATTRIBUTES (decl));
9274 if (VAR_P (decl)
9275 && !is_global_var (decl)
9276 && DECL_CONTEXT (decl) == current_function_decl)
9278 tree c = gimplify_oacc_declare_1 (t);
9279 if (c)
9281 if (oacc_declare_returns == NULL)
9282 oacc_declare_returns = new hash_map<tree, tree>;
9284 oacc_declare_returns->put (decl, c);
9288 if (gimplify_omp_ctxp)
9289 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_SEEN);
9292 stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
9293 clauses);
9295 gimplify_seq_add_stmt (pre_p, stmt);
9297 *expr_p = NULL_TREE;
9300 /* Gimplify the contents of an OMP_PARALLEL statement. This involves
9301 gimplification of the body, as well as scanning the body for used
9302 variables. We need to do this scan now, because variable-sized
9303 decls will be decomposed during gimplification. */
9305 static void
9306 gimplify_omp_parallel (tree *expr_p, gimple_seq *pre_p)
9308 tree expr = *expr_p;
9309 gimple *g;
9310 gimple_seq body = NULL;
9312 gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr), pre_p,
9313 OMP_PARALLEL_COMBINED (expr)
9314 ? ORT_COMBINED_PARALLEL
9315 : ORT_PARALLEL, OMP_PARALLEL);
9317 push_gimplify_context ();
9319 g = gimplify_and_return_first (OMP_PARALLEL_BODY (expr), &body);
9320 if (gimple_code (g) == GIMPLE_BIND)
9321 pop_gimplify_context (g);
9322 else
9323 pop_gimplify_context (NULL);
9325 gimplify_adjust_omp_clauses (pre_p, body, &OMP_PARALLEL_CLAUSES (expr),
9326 OMP_PARALLEL);
9328 g = gimple_build_omp_parallel (body,
9329 OMP_PARALLEL_CLAUSES (expr),
9330 NULL_TREE, NULL_TREE);
9331 if (OMP_PARALLEL_COMBINED (expr))
9332 gimple_omp_set_subcode (g, GF_OMP_PARALLEL_COMBINED);
9333 gimplify_seq_add_stmt (pre_p, g);
9334 *expr_p = NULL_TREE;
9337 /* Gimplify the contents of an OMP_TASK statement. This involves
9338 gimplification of the body, as well as scanning the body for used
9339 variables. We need to do this scan now, because variable-sized
9340 decls will be decomposed during gimplification. */
9342 static void
9343 gimplify_omp_task (tree *expr_p, gimple_seq *pre_p)
9345 tree expr = *expr_p;
9346 gimple *g;
9347 gimple_seq body = NULL;
9349 gimplify_scan_omp_clauses (&OMP_TASK_CLAUSES (expr), pre_p,
9350 omp_find_clause (OMP_TASK_CLAUSES (expr),
9351 OMP_CLAUSE_UNTIED)
9352 ? ORT_UNTIED_TASK : ORT_TASK, OMP_TASK);
9354 push_gimplify_context ();
9356 g = gimplify_and_return_first (OMP_TASK_BODY (expr), &body);
9357 if (gimple_code (g) == GIMPLE_BIND)
9358 pop_gimplify_context (g);
9359 else
9360 pop_gimplify_context (NULL);
9362 gimplify_adjust_omp_clauses (pre_p, body, &OMP_TASK_CLAUSES (expr),
9363 OMP_TASK);
9365 g = gimple_build_omp_task (body,
9366 OMP_TASK_CLAUSES (expr),
9367 NULL_TREE, NULL_TREE,
9368 NULL_TREE, NULL_TREE, NULL_TREE);
9369 gimplify_seq_add_stmt (pre_p, g);
9370 *expr_p = NULL_TREE;
9373 /* Helper function of gimplify_omp_for, find OMP_FOR resp. OMP_SIMD
9374 with non-NULL OMP_FOR_INIT. */
9376 static tree
9377 find_combined_omp_for (tree *tp, int *walk_subtrees, void *)
9379 *walk_subtrees = 0;
9380 switch (TREE_CODE (*tp))
9382 case OMP_FOR:
9383 *walk_subtrees = 1;
9384 /* FALLTHRU */
9385 case OMP_SIMD:
9386 if (OMP_FOR_INIT (*tp) != NULL_TREE)
9387 return *tp;
9388 break;
9389 case BIND_EXPR:
9390 case STATEMENT_LIST:
9391 case OMP_PARALLEL:
9392 *walk_subtrees = 1;
9393 break;
9394 default:
9395 break;
9397 return NULL_TREE;
9400 /* Gimplify the gross structure of an OMP_FOR statement. */
9402 static enum gimplify_status
9403 gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
9405 tree for_stmt, orig_for_stmt, inner_for_stmt = NULL_TREE, decl, var, t;
9406 enum gimplify_status ret = GS_ALL_DONE;
9407 enum gimplify_status tret;
9408 gomp_for *gfor;
9409 gimple_seq for_body, for_pre_body;
9410 int i;
9411 bitmap has_decl_expr = NULL;
9412 enum omp_region_type ort = ORT_WORKSHARE;
9414 orig_for_stmt = for_stmt = *expr_p;
9416 switch (TREE_CODE (for_stmt))
9418 case OMP_FOR:
9419 case CILK_FOR:
9420 case OMP_DISTRIBUTE:
9421 break;
9422 case OACC_LOOP:
9423 ort = ORT_ACC;
9424 break;
9425 case OMP_TASKLOOP:
9426 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_UNTIED))
9427 ort = ORT_UNTIED_TASK;
9428 else
9429 ort = ORT_TASK;
9430 break;
9431 case OMP_SIMD:
9432 case CILK_SIMD:
9433 ort = ORT_SIMD;
9434 break;
9435 default:
9436 gcc_unreachable ();
9439 /* Set OMP_CLAUSE_LINEAR_NO_COPYIN flag on explicit linear
9440 clause for the IV. */
9441 if (ort == ORT_SIMD && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
9443 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), 0);
9444 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
9445 decl = TREE_OPERAND (t, 0);
9446 for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
9447 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
9448 && OMP_CLAUSE_DECL (c) == decl)
9450 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
9451 break;
9455 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
9457 gcc_assert (TREE_CODE (for_stmt) != OACC_LOOP);
9458 inner_for_stmt = walk_tree (&OMP_FOR_BODY (for_stmt),
9459 find_combined_omp_for, NULL, NULL);
9460 if (inner_for_stmt == NULL_TREE)
9462 gcc_assert (seen_error ());
9463 *expr_p = NULL_TREE;
9464 return GS_ERROR;
9468 if (TREE_CODE (for_stmt) != OMP_TASKLOOP)
9469 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p, ort,
9470 TREE_CODE (for_stmt));
9472 if (TREE_CODE (for_stmt) == OMP_DISTRIBUTE)
9473 gimplify_omp_ctxp->distribute = true;
9475 /* Handle OMP_FOR_INIT. */
9476 for_pre_body = NULL;
9477 if (ort == ORT_SIMD && OMP_FOR_PRE_BODY (for_stmt))
9479 has_decl_expr = BITMAP_ALLOC (NULL);
9480 if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == DECL_EXPR
9481 && TREE_CODE (DECL_EXPR_DECL (OMP_FOR_PRE_BODY (for_stmt)))
9482 == VAR_DECL)
9484 t = OMP_FOR_PRE_BODY (for_stmt);
9485 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
9487 else if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == STATEMENT_LIST)
9489 tree_stmt_iterator si;
9490 for (si = tsi_start (OMP_FOR_PRE_BODY (for_stmt)); !tsi_end_p (si);
9491 tsi_next (&si))
9493 t = tsi_stmt (si);
9494 if (TREE_CODE (t) == DECL_EXPR
9495 && TREE_CODE (DECL_EXPR_DECL (t)) == VAR_DECL)
9496 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
9500 if (OMP_FOR_PRE_BODY (for_stmt))
9502 if (TREE_CODE (for_stmt) != OMP_TASKLOOP || gimplify_omp_ctxp)
9503 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
9504 else
9506 struct gimplify_omp_ctx ctx;
9507 memset (&ctx, 0, sizeof (ctx));
9508 ctx.region_type = ORT_NONE;
9509 gimplify_omp_ctxp = &ctx;
9510 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
9511 gimplify_omp_ctxp = NULL;
9514 OMP_FOR_PRE_BODY (for_stmt) = NULL_TREE;
9516 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
9517 for_stmt = inner_for_stmt;
9519 /* For taskloop, need to gimplify the start, end and step before the
9520 taskloop, outside of the taskloop omp context. */
9521 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
9523 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
9525 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
9526 if (!is_gimple_constant (TREE_OPERAND (t, 1)))
9528 TREE_OPERAND (t, 1)
9529 = get_initialized_tmp_var (TREE_OPERAND (t, 1),
9530 pre_p, NULL, false);
9531 tree c = build_omp_clause (input_location,
9532 OMP_CLAUSE_FIRSTPRIVATE);
9533 OMP_CLAUSE_DECL (c) = TREE_OPERAND (t, 1);
9534 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
9535 OMP_FOR_CLAUSES (orig_for_stmt) = c;
9538 /* Handle OMP_FOR_COND. */
9539 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
9540 if (!is_gimple_constant (TREE_OPERAND (t, 1)))
9542 TREE_OPERAND (t, 1)
9543 = get_initialized_tmp_var (TREE_OPERAND (t, 1),
9544 gimple_seq_empty_p (for_pre_body)
9545 ? pre_p : &for_pre_body, NULL,
9546 false);
9547 tree c = build_omp_clause (input_location,
9548 OMP_CLAUSE_FIRSTPRIVATE);
9549 OMP_CLAUSE_DECL (c) = TREE_OPERAND (t, 1);
9550 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
9551 OMP_FOR_CLAUSES (orig_for_stmt) = c;
9554 /* Handle OMP_FOR_INCR. */
9555 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
9556 if (TREE_CODE (t) == MODIFY_EXPR)
9558 decl = TREE_OPERAND (t, 0);
9559 t = TREE_OPERAND (t, 1);
9560 tree *tp = &TREE_OPERAND (t, 1);
9561 if (TREE_CODE (t) == PLUS_EXPR && *tp == decl)
9562 tp = &TREE_OPERAND (t, 0);
9564 if (!is_gimple_constant (*tp))
9566 gimple_seq *seq = gimple_seq_empty_p (for_pre_body)
9567 ? pre_p : &for_pre_body;
9568 *tp = get_initialized_tmp_var (*tp, seq, NULL, false);
9569 tree c = build_omp_clause (input_location,
9570 OMP_CLAUSE_FIRSTPRIVATE);
9571 OMP_CLAUSE_DECL (c) = *tp;
9572 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
9573 OMP_FOR_CLAUSES (orig_for_stmt) = c;
9578 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (orig_for_stmt), pre_p, ort,
9579 OMP_TASKLOOP);
9582 if (orig_for_stmt != for_stmt)
9583 gimplify_omp_ctxp->combined_loop = true;
9585 for_body = NULL;
9586 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
9587 == TREE_VEC_LENGTH (OMP_FOR_COND (for_stmt)));
9588 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
9589 == TREE_VEC_LENGTH (OMP_FOR_INCR (for_stmt)));
9591 tree c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED);
9592 bool is_doacross = false;
9593 if (c && OMP_CLAUSE_ORDERED_EXPR (c))
9595 is_doacross = true;
9596 gimplify_omp_ctxp->loop_iter_var.create (TREE_VEC_LENGTH
9597 (OMP_FOR_INIT (for_stmt))
9598 * 2);
9600 int collapse = 1, tile = 0;
9601 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_COLLAPSE);
9602 if (c)
9603 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (c));
9604 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_TILE);
9605 if (c)
9606 tile = list_length (OMP_CLAUSE_TILE_LIST (c));
9607 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
9609 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
9610 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
9611 decl = TREE_OPERAND (t, 0);
9612 gcc_assert (DECL_P (decl));
9613 gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl))
9614 || POINTER_TYPE_P (TREE_TYPE (decl)));
9615 if (is_doacross)
9617 if (TREE_CODE (for_stmt) == OMP_FOR && OMP_FOR_ORIG_DECLS (for_stmt))
9618 gimplify_omp_ctxp->loop_iter_var.quick_push
9619 (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i));
9620 else
9621 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
9622 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
9625 /* Make sure the iteration variable is private. */
9626 tree c = NULL_TREE;
9627 tree c2 = NULL_TREE;
9628 if (orig_for_stmt != for_stmt)
9629 /* Do this only on innermost construct for combined ones. */;
9630 else if (ort == ORT_SIMD)
9632 splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
9633 (splay_tree_key) decl);
9634 omp_is_private (gimplify_omp_ctxp, decl,
9635 1 + (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
9636 != 1));
9637 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
9638 omp_notice_variable (gimplify_omp_ctxp, decl, true);
9639 else if (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
9641 c = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
9642 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
9643 unsigned int flags = GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN;
9644 if (has_decl_expr
9645 && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
9647 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
9648 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
9650 struct gimplify_omp_ctx *outer
9651 = gimplify_omp_ctxp->outer_context;
9652 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
9654 if (outer->region_type == ORT_WORKSHARE
9655 && outer->combined_loop)
9657 n = splay_tree_lookup (outer->variables,
9658 (splay_tree_key)decl);
9659 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
9661 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
9662 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
9664 else
9666 struct gimplify_omp_ctx *octx = outer->outer_context;
9667 if (octx
9668 && octx->region_type == ORT_COMBINED_PARALLEL
9669 && octx->outer_context
9670 && (octx->outer_context->region_type
9671 == ORT_WORKSHARE)
9672 && octx->outer_context->combined_loop)
9674 octx = octx->outer_context;
9675 n = splay_tree_lookup (octx->variables,
9676 (splay_tree_key)decl);
9677 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
9679 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
9680 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
9687 OMP_CLAUSE_DECL (c) = decl;
9688 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
9689 OMP_FOR_CLAUSES (for_stmt) = c;
9690 omp_add_variable (gimplify_omp_ctxp, decl, flags);
9691 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
9693 if (outer->region_type == ORT_WORKSHARE
9694 && outer->combined_loop)
9696 if (outer->outer_context
9697 && (outer->outer_context->region_type
9698 == ORT_COMBINED_PARALLEL))
9699 outer = outer->outer_context;
9700 else if (omp_check_private (outer, decl, false))
9701 outer = NULL;
9703 else if (((outer->region_type & ORT_TASK) != 0)
9704 && outer->combined_loop
9705 && !omp_check_private (gimplify_omp_ctxp,
9706 decl, false))
9708 else if (outer->region_type != ORT_COMBINED_PARALLEL)
9710 omp_notice_variable (outer, decl, true);
9711 outer = NULL;
9713 if (outer)
9715 n = splay_tree_lookup (outer->variables,
9716 (splay_tree_key)decl);
9717 if (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
9719 omp_add_variable (outer, decl,
9720 GOVD_LASTPRIVATE | GOVD_SEEN);
9721 if (outer->region_type == ORT_COMBINED_PARALLEL
9722 && outer->outer_context
9723 && (outer->outer_context->region_type
9724 == ORT_WORKSHARE)
9725 && outer->outer_context->combined_loop)
9727 outer = outer->outer_context;
9728 n = splay_tree_lookup (outer->variables,
9729 (splay_tree_key)decl);
9730 if (omp_check_private (outer, decl, false))
9731 outer = NULL;
9732 else if (n == NULL
9733 || ((n->value & GOVD_DATA_SHARE_CLASS)
9734 == 0))
9735 omp_add_variable (outer, decl,
9736 GOVD_LASTPRIVATE
9737 | GOVD_SEEN);
9738 else
9739 outer = NULL;
9741 if (outer && outer->outer_context
9742 && (outer->outer_context->region_type
9743 == ORT_COMBINED_TEAMS))
9745 outer = outer->outer_context;
9746 n = splay_tree_lookup (outer->variables,
9747 (splay_tree_key)decl);
9748 if (n == NULL
9749 || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
9750 omp_add_variable (outer, decl,
9751 GOVD_SHARED | GOVD_SEEN);
9752 else
9753 outer = NULL;
9755 if (outer && outer->outer_context)
9756 omp_notice_variable (outer->outer_context, decl,
9757 true);
9762 else
9764 bool lastprivate
9765 = (!has_decl_expr
9766 || !bitmap_bit_p (has_decl_expr, DECL_UID (decl)));
9767 struct gimplify_omp_ctx *outer
9768 = gimplify_omp_ctxp->outer_context;
9769 if (outer && lastprivate)
9771 if (outer->region_type == ORT_WORKSHARE
9772 && outer->combined_loop)
9774 n = splay_tree_lookup (outer->variables,
9775 (splay_tree_key)decl);
9776 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
9778 lastprivate = false;
9779 outer = NULL;
9781 else if (outer->outer_context
9782 && (outer->outer_context->region_type
9783 == ORT_COMBINED_PARALLEL))
9784 outer = outer->outer_context;
9785 else if (omp_check_private (outer, decl, false))
9786 outer = NULL;
9788 else if (((outer->region_type & ORT_TASK) != 0)
9789 && outer->combined_loop
9790 && !omp_check_private (gimplify_omp_ctxp,
9791 decl, false))
9793 else if (outer->region_type != ORT_COMBINED_PARALLEL)
9795 omp_notice_variable (outer, decl, true);
9796 outer = NULL;
9798 if (outer)
9800 n = splay_tree_lookup (outer->variables,
9801 (splay_tree_key)decl);
9802 if (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
9804 omp_add_variable (outer, decl,
9805 GOVD_LASTPRIVATE | GOVD_SEEN);
9806 if (outer->region_type == ORT_COMBINED_PARALLEL
9807 && outer->outer_context
9808 && (outer->outer_context->region_type
9809 == ORT_WORKSHARE)
9810 && outer->outer_context->combined_loop)
9812 outer = outer->outer_context;
9813 n = splay_tree_lookup (outer->variables,
9814 (splay_tree_key)decl);
9815 if (omp_check_private (outer, decl, false))
9816 outer = NULL;
9817 else if (n == NULL
9818 || ((n->value & GOVD_DATA_SHARE_CLASS)
9819 == 0))
9820 omp_add_variable (outer, decl,
9821 GOVD_LASTPRIVATE
9822 | GOVD_SEEN);
9823 else
9824 outer = NULL;
9826 if (outer && outer->outer_context
9827 && (outer->outer_context->region_type
9828 == ORT_COMBINED_TEAMS))
9830 outer = outer->outer_context;
9831 n = splay_tree_lookup (outer->variables,
9832 (splay_tree_key)decl);
9833 if (n == NULL
9834 || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
9835 omp_add_variable (outer, decl,
9836 GOVD_SHARED | GOVD_SEEN);
9837 else
9838 outer = NULL;
9840 if (outer && outer->outer_context)
9841 omp_notice_variable (outer->outer_context, decl,
9842 true);
9847 c = build_omp_clause (input_location,
9848 lastprivate ? OMP_CLAUSE_LASTPRIVATE
9849 : OMP_CLAUSE_PRIVATE);
9850 OMP_CLAUSE_DECL (c) = decl;
9851 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
9852 OMP_FOR_CLAUSES (for_stmt) = c;
9853 omp_add_variable (gimplify_omp_ctxp, decl,
9854 (lastprivate ? GOVD_LASTPRIVATE : GOVD_PRIVATE)
9855 | GOVD_EXPLICIT | GOVD_SEEN);
9856 c = NULL_TREE;
9859 else if (omp_is_private (gimplify_omp_ctxp, decl, 0))
9860 omp_notice_variable (gimplify_omp_ctxp, decl, true);
9861 else
9862 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN);
9864 /* If DECL is not a gimple register, create a temporary variable to act
9865 as an iteration counter. This is valid, since DECL cannot be
9866 modified in the body of the loop. Similarly for any iteration vars
9867 in simd with collapse > 1 where the iterator vars must be
9868 lastprivate. */
9869 if (orig_for_stmt != for_stmt)
9870 var = decl;
9871 else if (!is_gimple_reg (decl)
9872 || (ort == ORT_SIMD
9873 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) > 1))
9875 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
9876 /* Make sure omp_add_variable is not called on it prematurely.
9877 We call it ourselves a few lines later. */
9878 gimplify_omp_ctxp = NULL;
9879 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
9880 gimplify_omp_ctxp = ctx;
9881 TREE_OPERAND (t, 0) = var;
9883 gimplify_seq_add_stmt (&for_body, gimple_build_assign (decl, var));
9885 if (ort == ORT_SIMD
9886 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
9888 c2 = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
9889 OMP_CLAUSE_LINEAR_NO_COPYIN (c2) = 1;
9890 OMP_CLAUSE_LINEAR_NO_COPYOUT (c2) = 1;
9891 OMP_CLAUSE_DECL (c2) = var;
9892 OMP_CLAUSE_CHAIN (c2) = OMP_FOR_CLAUSES (for_stmt);
9893 OMP_FOR_CLAUSES (for_stmt) = c2;
9894 omp_add_variable (gimplify_omp_ctxp, var,
9895 GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN);
9896 if (c == NULL_TREE)
9898 c = c2;
9899 c2 = NULL_TREE;
9902 else
9903 omp_add_variable (gimplify_omp_ctxp, var,
9904 GOVD_PRIVATE | GOVD_SEEN);
9906 else
9907 var = decl;
9909 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
9910 is_gimple_val, fb_rvalue, false);
9911 ret = MIN (ret, tret);
9912 if (ret == GS_ERROR)
9913 return ret;
9915 /* Handle OMP_FOR_COND. */
9916 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
9917 gcc_assert (COMPARISON_CLASS_P (t));
9918 gcc_assert (TREE_OPERAND (t, 0) == decl);
9920 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
9921 is_gimple_val, fb_rvalue, false);
9922 ret = MIN (ret, tret);
9924 /* Handle OMP_FOR_INCR. */
9925 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
9926 switch (TREE_CODE (t))
9928 case PREINCREMENT_EXPR:
9929 case POSTINCREMENT_EXPR:
9931 tree decl = TREE_OPERAND (t, 0);
9932 /* c_omp_for_incr_canonicalize_ptr() should have been
9933 called to massage things appropriately. */
9934 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
9936 if (orig_for_stmt != for_stmt)
9937 break;
9938 t = build_int_cst (TREE_TYPE (decl), 1);
9939 if (c)
9940 OMP_CLAUSE_LINEAR_STEP (c) = t;
9941 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
9942 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
9943 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
9944 break;
9947 case PREDECREMENT_EXPR:
9948 case POSTDECREMENT_EXPR:
9949 /* c_omp_for_incr_canonicalize_ptr() should have been
9950 called to massage things appropriately. */
9951 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
9952 if (orig_for_stmt != for_stmt)
9953 break;
9954 t = build_int_cst (TREE_TYPE (decl), -1);
9955 if (c)
9956 OMP_CLAUSE_LINEAR_STEP (c) = t;
9957 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
9958 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
9959 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
9960 break;
9962 case MODIFY_EXPR:
9963 gcc_assert (TREE_OPERAND (t, 0) == decl);
9964 TREE_OPERAND (t, 0) = var;
9966 t = TREE_OPERAND (t, 1);
9967 switch (TREE_CODE (t))
9969 case PLUS_EXPR:
9970 if (TREE_OPERAND (t, 1) == decl)
9972 TREE_OPERAND (t, 1) = TREE_OPERAND (t, 0);
9973 TREE_OPERAND (t, 0) = var;
9974 break;
9977 /* Fallthru. */
9978 case MINUS_EXPR:
9979 case POINTER_PLUS_EXPR:
9980 gcc_assert (TREE_OPERAND (t, 0) == decl);
9981 TREE_OPERAND (t, 0) = var;
9982 break;
9983 default:
9984 gcc_unreachable ();
9987 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
9988 is_gimple_val, fb_rvalue, false);
9989 ret = MIN (ret, tret);
9990 if (c)
9992 tree step = TREE_OPERAND (t, 1);
9993 tree stept = TREE_TYPE (decl);
9994 if (POINTER_TYPE_P (stept))
9995 stept = sizetype;
9996 step = fold_convert (stept, step);
9997 if (TREE_CODE (t) == MINUS_EXPR)
9998 step = fold_build1 (NEGATE_EXPR, stept, step);
9999 OMP_CLAUSE_LINEAR_STEP (c) = step;
10000 if (step != TREE_OPERAND (t, 1))
10002 tret = gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c),
10003 &for_pre_body, NULL,
10004 is_gimple_val, fb_rvalue, false);
10005 ret = MIN (ret, tret);
10008 break;
10010 default:
10011 gcc_unreachable ();
10014 if (c2)
10016 gcc_assert (c);
10017 OMP_CLAUSE_LINEAR_STEP (c2) = OMP_CLAUSE_LINEAR_STEP (c);
10020 if ((var != decl || collapse > 1 || tile) && orig_for_stmt == for_stmt)
10022 for (c = OMP_FOR_CLAUSES (for_stmt); c ; c = OMP_CLAUSE_CHAIN (c))
10023 if (((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
10024 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) == NULL)
10025 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
10026 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)
10027 && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c) == NULL))
10028 && OMP_CLAUSE_DECL (c) == decl)
10030 if (is_doacross && (collapse == 1 || i >= collapse))
10031 t = var;
10032 else
10034 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
10035 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
10036 gcc_assert (TREE_OPERAND (t, 0) == var);
10037 t = TREE_OPERAND (t, 1);
10038 gcc_assert (TREE_CODE (t) == PLUS_EXPR
10039 || TREE_CODE (t) == MINUS_EXPR
10040 || TREE_CODE (t) == POINTER_PLUS_EXPR);
10041 gcc_assert (TREE_OPERAND (t, 0) == var);
10042 t = build2 (TREE_CODE (t), TREE_TYPE (decl),
10043 is_doacross ? var : decl,
10044 TREE_OPERAND (t, 1));
10046 gimple_seq *seq;
10047 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
10048 seq = &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c);
10049 else
10050 seq = &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c);
10051 gimplify_assign (decl, t, seq);
10056 BITMAP_FREE (has_decl_expr);
10058 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
10060 push_gimplify_context ();
10061 if (TREE_CODE (OMP_FOR_BODY (orig_for_stmt)) != BIND_EXPR)
10063 OMP_FOR_BODY (orig_for_stmt)
10064 = build3 (BIND_EXPR, void_type_node, NULL,
10065 OMP_FOR_BODY (orig_for_stmt), NULL);
10066 TREE_SIDE_EFFECTS (OMP_FOR_BODY (orig_for_stmt)) = 1;
10070 gimple *g = gimplify_and_return_first (OMP_FOR_BODY (orig_for_stmt),
10071 &for_body);
10073 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
10075 if (gimple_code (g) == GIMPLE_BIND)
10076 pop_gimplify_context (g);
10077 else
10078 pop_gimplify_context (NULL);
10081 if (orig_for_stmt != for_stmt)
10082 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
10084 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
10085 decl = TREE_OPERAND (t, 0);
10086 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
10087 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
10088 gimplify_omp_ctxp = ctx->outer_context;
10089 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
10090 gimplify_omp_ctxp = ctx;
10091 omp_add_variable (gimplify_omp_ctxp, var, GOVD_PRIVATE | GOVD_SEEN);
10092 TREE_OPERAND (t, 0) = var;
10093 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
10094 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
10095 TREE_OPERAND (TREE_OPERAND (t, 1), 0) = var;
10098 gimplify_adjust_omp_clauses (pre_p, for_body,
10099 &OMP_FOR_CLAUSES (orig_for_stmt),
10100 TREE_CODE (orig_for_stmt));
10102 int kind;
10103 switch (TREE_CODE (orig_for_stmt))
10105 case OMP_FOR: kind = GF_OMP_FOR_KIND_FOR; break;
10106 case OMP_SIMD: kind = GF_OMP_FOR_KIND_SIMD; break;
10107 case CILK_SIMD: kind = GF_OMP_FOR_KIND_CILKSIMD; break;
10108 case CILK_FOR: kind = GF_OMP_FOR_KIND_CILKFOR; break;
10109 case OMP_DISTRIBUTE: kind = GF_OMP_FOR_KIND_DISTRIBUTE; break;
10110 case OMP_TASKLOOP: kind = GF_OMP_FOR_KIND_TASKLOOP; break;
10111 case OACC_LOOP: kind = GF_OMP_FOR_KIND_OACC_LOOP; break;
10112 default:
10113 gcc_unreachable ();
10115 gfor = gimple_build_omp_for (for_body, kind, OMP_FOR_CLAUSES (orig_for_stmt),
10116 TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)),
10117 for_pre_body);
10118 if (orig_for_stmt != for_stmt)
10119 gimple_omp_for_set_combined_p (gfor, true);
10120 if (gimplify_omp_ctxp
10121 && (gimplify_omp_ctxp->combined_loop
10122 || (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
10123 && gimplify_omp_ctxp->outer_context
10124 && gimplify_omp_ctxp->outer_context->combined_loop)))
10126 gimple_omp_for_set_combined_into_p (gfor, true);
10127 if (gimplify_omp_ctxp->combined_loop)
10128 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_SIMD);
10129 else
10130 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_FOR);
10133 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
10135 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
10136 gimple_omp_for_set_index (gfor, i, TREE_OPERAND (t, 0));
10137 gimple_omp_for_set_initial (gfor, i, TREE_OPERAND (t, 1));
10138 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
10139 gimple_omp_for_set_cond (gfor, i, TREE_CODE (t));
10140 gimple_omp_for_set_final (gfor, i, TREE_OPERAND (t, 1));
10141 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
10142 gimple_omp_for_set_incr (gfor, i, TREE_OPERAND (t, 1));
10145 /* OMP_TASKLOOP is gimplified as two GIMPLE_OMP_FOR taskloop
10146 constructs with GIMPLE_OMP_TASK sandwiched in between them.
10147 The outer taskloop stands for computing the number of iterations,
10148 counts for collapsed loops and holding taskloop specific clauses.
10149 The task construct stands for the effect of data sharing on the
10150 explicit task it creates and the inner taskloop stands for expansion
10151 of the static loop inside of the explicit task construct. */
10152 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
10154 tree *gfor_clauses_ptr = gimple_omp_for_clauses_ptr (gfor);
10155 tree task_clauses = NULL_TREE;
10156 tree c = *gfor_clauses_ptr;
10157 tree *gtask_clauses_ptr = &task_clauses;
10158 tree outer_for_clauses = NULL_TREE;
10159 tree *gforo_clauses_ptr = &outer_for_clauses;
10160 for (; c; c = OMP_CLAUSE_CHAIN (c))
10161 switch (OMP_CLAUSE_CODE (c))
10163 /* These clauses are allowed on task, move them there. */
10164 case OMP_CLAUSE_SHARED:
10165 case OMP_CLAUSE_FIRSTPRIVATE:
10166 case OMP_CLAUSE_DEFAULT:
10167 case OMP_CLAUSE_IF:
10168 case OMP_CLAUSE_UNTIED:
10169 case OMP_CLAUSE_FINAL:
10170 case OMP_CLAUSE_MERGEABLE:
10171 case OMP_CLAUSE_PRIORITY:
10172 *gtask_clauses_ptr = c;
10173 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
10174 break;
10175 case OMP_CLAUSE_PRIVATE:
10176 if (OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c))
10178 /* We want private on outer for and firstprivate
10179 on task. */
10180 *gtask_clauses_ptr
10181 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
10182 OMP_CLAUSE_FIRSTPRIVATE);
10183 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
10184 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL);
10185 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
10186 *gforo_clauses_ptr = c;
10187 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
10189 else
10191 *gtask_clauses_ptr = c;
10192 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
10194 break;
10195 /* These clauses go into outer taskloop clauses. */
10196 case OMP_CLAUSE_GRAINSIZE:
10197 case OMP_CLAUSE_NUM_TASKS:
10198 case OMP_CLAUSE_NOGROUP:
10199 *gforo_clauses_ptr = c;
10200 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
10201 break;
10202 /* Taskloop clause we duplicate on both taskloops. */
10203 case OMP_CLAUSE_COLLAPSE:
10204 *gfor_clauses_ptr = c;
10205 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
10206 *gforo_clauses_ptr = copy_node (c);
10207 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
10208 break;
10209 /* For lastprivate, keep the clause on inner taskloop, and add
10210 a shared clause on task. If the same decl is also firstprivate,
10211 add also firstprivate clause on the inner taskloop. */
10212 case OMP_CLAUSE_LASTPRIVATE:
10213 if (OMP_CLAUSE_LASTPRIVATE_TASKLOOP_IV (c))
10215 /* For taskloop C++ lastprivate IVs, we want:
10216 1) private on outer taskloop
10217 2) firstprivate and shared on task
10218 3) lastprivate on inner taskloop */
10219 *gtask_clauses_ptr
10220 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
10221 OMP_CLAUSE_FIRSTPRIVATE);
10222 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
10223 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL);
10224 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
10225 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c) = 1;
10226 *gforo_clauses_ptr = build_omp_clause (OMP_CLAUSE_LOCATION (c),
10227 OMP_CLAUSE_PRIVATE);
10228 OMP_CLAUSE_DECL (*gforo_clauses_ptr) = OMP_CLAUSE_DECL (c);
10229 OMP_CLAUSE_PRIVATE_TASKLOOP_IV (*gforo_clauses_ptr) = 1;
10230 TREE_TYPE (*gforo_clauses_ptr) = TREE_TYPE (c);
10231 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
10233 *gfor_clauses_ptr = c;
10234 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
10235 *gtask_clauses_ptr
10236 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_SHARED);
10237 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
10238 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
10239 OMP_CLAUSE_SHARED_FIRSTPRIVATE (*gtask_clauses_ptr) = 1;
10240 gtask_clauses_ptr
10241 = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
10242 break;
10243 default:
10244 gcc_unreachable ();
10246 *gfor_clauses_ptr = NULL_TREE;
10247 *gtask_clauses_ptr = NULL_TREE;
10248 *gforo_clauses_ptr = NULL_TREE;
10249 g = gimple_build_bind (NULL_TREE, gfor, NULL_TREE);
10250 g = gimple_build_omp_task (g, task_clauses, NULL_TREE, NULL_TREE,
10251 NULL_TREE, NULL_TREE, NULL_TREE);
10252 gimple_omp_task_set_taskloop_p (g, true);
10253 g = gimple_build_bind (NULL_TREE, g, NULL_TREE);
10254 gomp_for *gforo
10255 = gimple_build_omp_for (g, GF_OMP_FOR_KIND_TASKLOOP, outer_for_clauses,
10256 gimple_omp_for_collapse (gfor),
10257 gimple_omp_for_pre_body (gfor));
10258 gimple_omp_for_set_pre_body (gfor, NULL);
10259 gimple_omp_for_set_combined_p (gforo, true);
10260 gimple_omp_for_set_combined_into_p (gfor, true);
10261 for (i = 0; i < (int) gimple_omp_for_collapse (gfor); i++)
10263 tree type = TREE_TYPE (gimple_omp_for_index (gfor, i));
10264 tree v = create_tmp_var (type);
10265 gimple_omp_for_set_index (gforo, i, v);
10266 t = unshare_expr (gimple_omp_for_initial (gfor, i));
10267 gimple_omp_for_set_initial (gforo, i, t);
10268 gimple_omp_for_set_cond (gforo, i,
10269 gimple_omp_for_cond (gfor, i));
10270 t = unshare_expr (gimple_omp_for_final (gfor, i));
10271 gimple_omp_for_set_final (gforo, i, t);
10272 t = unshare_expr (gimple_omp_for_incr (gfor, i));
10273 gcc_assert (TREE_OPERAND (t, 0) == gimple_omp_for_index (gfor, i));
10274 TREE_OPERAND (t, 0) = v;
10275 gimple_omp_for_set_incr (gforo, i, t);
10276 t = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
10277 OMP_CLAUSE_DECL (t) = v;
10278 OMP_CLAUSE_CHAIN (t) = gimple_omp_for_clauses (gforo);
10279 gimple_omp_for_set_clauses (gforo, t);
10281 gimplify_seq_add_stmt (pre_p, gforo);
10283 else
10284 gimplify_seq_add_stmt (pre_p, gfor);
10285 if (ret != GS_ALL_DONE)
10286 return GS_ERROR;
10287 *expr_p = NULL_TREE;
10288 return GS_ALL_DONE;
10291 /* Helper function of optimize_target_teams, find OMP_TEAMS inside
10292 of OMP_TARGET's body. */
10294 static tree
10295 find_omp_teams (tree *tp, int *walk_subtrees, void *)
10297 *walk_subtrees = 0;
10298 switch (TREE_CODE (*tp))
10300 case OMP_TEAMS:
10301 return *tp;
10302 case BIND_EXPR:
10303 case STATEMENT_LIST:
10304 *walk_subtrees = 1;
10305 break;
10306 default:
10307 break;
10309 return NULL_TREE;
10312 /* Helper function of optimize_target_teams, determine if the expression
10313 can be computed safely before the target construct on the host. */
10315 static tree
10316 computable_teams_clause (tree *tp, int *walk_subtrees, void *)
10318 splay_tree_node n;
10320 if (TYPE_P (*tp))
10322 *walk_subtrees = 0;
10323 return NULL_TREE;
10325 switch (TREE_CODE (*tp))
10327 case VAR_DECL:
10328 case PARM_DECL:
10329 case RESULT_DECL:
10330 *walk_subtrees = 0;
10331 if (error_operand_p (*tp)
10332 || !INTEGRAL_TYPE_P (TREE_TYPE (*tp))
10333 || DECL_HAS_VALUE_EXPR_P (*tp)
10334 || DECL_THREAD_LOCAL_P (*tp)
10335 || TREE_SIDE_EFFECTS (*tp)
10336 || TREE_THIS_VOLATILE (*tp))
10337 return *tp;
10338 if (is_global_var (*tp)
10339 && (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (*tp))
10340 || lookup_attribute ("omp declare target link",
10341 DECL_ATTRIBUTES (*tp))))
10342 return *tp;
10343 if (VAR_P (*tp)
10344 && !DECL_SEEN_IN_BIND_EXPR_P (*tp)
10345 && !is_global_var (*tp)
10346 && decl_function_context (*tp) == current_function_decl)
10347 return *tp;
10348 n = splay_tree_lookup (gimplify_omp_ctxp->variables,
10349 (splay_tree_key) *tp);
10350 if (n == NULL)
10352 if (gimplify_omp_ctxp->target_map_scalars_firstprivate)
10353 return NULL_TREE;
10354 return *tp;
10356 else if (n->value & GOVD_LOCAL)
10357 return *tp;
10358 else if (n->value & GOVD_FIRSTPRIVATE)
10359 return NULL_TREE;
10360 else if ((n->value & (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
10361 == (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
10362 return NULL_TREE;
10363 return *tp;
10364 case INTEGER_CST:
10365 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
10366 return *tp;
10367 return NULL_TREE;
10368 case TARGET_EXPR:
10369 if (TARGET_EXPR_INITIAL (*tp)
10370 || TREE_CODE (TARGET_EXPR_SLOT (*tp)) != VAR_DECL)
10371 return *tp;
10372 return computable_teams_clause (&TARGET_EXPR_SLOT (*tp),
10373 walk_subtrees, NULL);
10374 /* Allow some reasonable subset of integral arithmetics. */
10375 case PLUS_EXPR:
10376 case MINUS_EXPR:
10377 case MULT_EXPR:
10378 case TRUNC_DIV_EXPR:
10379 case CEIL_DIV_EXPR:
10380 case FLOOR_DIV_EXPR:
10381 case ROUND_DIV_EXPR:
10382 case TRUNC_MOD_EXPR:
10383 case CEIL_MOD_EXPR:
10384 case FLOOR_MOD_EXPR:
10385 case ROUND_MOD_EXPR:
10386 case RDIV_EXPR:
10387 case EXACT_DIV_EXPR:
10388 case MIN_EXPR:
10389 case MAX_EXPR:
10390 case LSHIFT_EXPR:
10391 case RSHIFT_EXPR:
10392 case BIT_IOR_EXPR:
10393 case BIT_XOR_EXPR:
10394 case BIT_AND_EXPR:
10395 case NEGATE_EXPR:
10396 case ABS_EXPR:
10397 case BIT_NOT_EXPR:
10398 case NON_LVALUE_EXPR:
10399 CASE_CONVERT:
10400 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
10401 return *tp;
10402 return NULL_TREE;
10403 /* And disallow anything else, except for comparisons. */
10404 default:
10405 if (COMPARISON_CLASS_P (*tp))
10406 return NULL_TREE;
10407 return *tp;
10411 /* Try to determine if the num_teams and/or thread_limit expressions
10412 can have their values determined already before entering the
10413 target construct.
10414 INTEGER_CSTs trivially are,
10415 integral decls that are firstprivate (explicitly or implicitly)
10416 or explicitly map(always, to:) or map(always, tofrom:) on the target
10417 region too, and expressions involving simple arithmetics on those
10418 too, function calls are not ok, dereferencing something neither etc.
10419 Add NUM_TEAMS and THREAD_LIMIT clauses to the OMP_CLAUSES of
10420 EXPR based on what we find:
10421 0 stands for clause not specified at all, use implementation default
10422 -1 stands for value that can't be determined easily before entering
10423 the target construct.
10424 If teams construct is not present at all, use 1 for num_teams
10425 and 0 for thread_limit (only one team is involved, and the thread
10426 limit is implementation defined. */
10428 static void
10429 optimize_target_teams (tree target, gimple_seq *pre_p)
10431 tree body = OMP_BODY (target);
10432 tree teams = walk_tree (&body, find_omp_teams, NULL, NULL);
10433 tree num_teams = integer_zero_node;
10434 tree thread_limit = integer_zero_node;
10435 location_t num_teams_loc = EXPR_LOCATION (target);
10436 location_t thread_limit_loc = EXPR_LOCATION (target);
10437 tree c, *p, expr;
10438 struct gimplify_omp_ctx *target_ctx = gimplify_omp_ctxp;
10440 if (teams == NULL_TREE)
10441 num_teams = integer_one_node;
10442 else
10443 for (c = OMP_TEAMS_CLAUSES (teams); c; c = OMP_CLAUSE_CHAIN (c))
10445 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS)
10447 p = &num_teams;
10448 num_teams_loc = OMP_CLAUSE_LOCATION (c);
10450 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
10452 p = &thread_limit;
10453 thread_limit_loc = OMP_CLAUSE_LOCATION (c);
10455 else
10456 continue;
10457 expr = OMP_CLAUSE_OPERAND (c, 0);
10458 if (TREE_CODE (expr) == INTEGER_CST)
10460 *p = expr;
10461 continue;
10463 if (walk_tree (&expr, computable_teams_clause, NULL, NULL))
10465 *p = integer_minus_one_node;
10466 continue;
10468 *p = expr;
10469 gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
10470 if (gimplify_expr (p, pre_p, NULL, is_gimple_val, fb_rvalue, false)
10471 == GS_ERROR)
10473 gimplify_omp_ctxp = target_ctx;
10474 *p = integer_minus_one_node;
10475 continue;
10477 gimplify_omp_ctxp = target_ctx;
10478 if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR)
10479 OMP_CLAUSE_OPERAND (c, 0) = *p;
10481 c = build_omp_clause (thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
10482 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = thread_limit;
10483 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
10484 OMP_TARGET_CLAUSES (target) = c;
10485 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
10486 OMP_CLAUSE_NUM_TEAMS_EXPR (c) = num_teams;
10487 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
10488 OMP_TARGET_CLAUSES (target) = c;
10491 /* Gimplify the gross structure of several OMP constructs. */
10493 static void
10494 gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
10496 tree expr = *expr_p;
10497 gimple *stmt;
10498 gimple_seq body = NULL;
10499 enum omp_region_type ort;
10501 switch (TREE_CODE (expr))
10503 case OMP_SECTIONS:
10504 case OMP_SINGLE:
10505 ort = ORT_WORKSHARE;
10506 break;
10507 case OMP_TARGET:
10508 ort = OMP_TARGET_COMBINED (expr) ? ORT_COMBINED_TARGET : ORT_TARGET;
10509 break;
10510 case OACC_KERNELS:
10511 ort = ORT_ACC_KERNELS;
10512 break;
10513 case OACC_PARALLEL:
10514 ort = ORT_ACC_PARALLEL;
10515 break;
10516 case OACC_DATA:
10517 ort = ORT_ACC_DATA;
10518 break;
10519 case OMP_TARGET_DATA:
10520 ort = ORT_TARGET_DATA;
10521 break;
10522 case OMP_TEAMS:
10523 ort = OMP_TEAMS_COMBINED (expr) ? ORT_COMBINED_TEAMS : ORT_TEAMS;
10524 break;
10525 case OACC_HOST_DATA:
10526 ort = ORT_ACC_HOST_DATA;
10527 break;
10528 default:
10529 gcc_unreachable ();
10531 gimplify_scan_omp_clauses (&OMP_CLAUSES (expr), pre_p, ort,
10532 TREE_CODE (expr));
10533 if (TREE_CODE (expr) == OMP_TARGET)
10534 optimize_target_teams (expr, pre_p);
10535 if ((ort & (ORT_TARGET | ORT_TARGET_DATA)) != 0)
10537 push_gimplify_context ();
10538 gimple *g = gimplify_and_return_first (OMP_BODY (expr), &body);
10539 if (gimple_code (g) == GIMPLE_BIND)
10540 pop_gimplify_context (g);
10541 else
10542 pop_gimplify_context (NULL);
10543 if ((ort & ORT_TARGET_DATA) != 0)
10545 enum built_in_function end_ix;
10546 switch (TREE_CODE (expr))
10548 case OACC_DATA:
10549 case OACC_HOST_DATA:
10550 end_ix = BUILT_IN_GOACC_DATA_END;
10551 break;
10552 case OMP_TARGET_DATA:
10553 end_ix = BUILT_IN_GOMP_TARGET_END_DATA;
10554 break;
10555 default:
10556 gcc_unreachable ();
10558 tree fn = builtin_decl_explicit (end_ix);
10559 g = gimple_build_call (fn, 0);
10560 gimple_seq cleanup = NULL;
10561 gimple_seq_add_stmt (&cleanup, g);
10562 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
10563 body = NULL;
10564 gimple_seq_add_stmt (&body, g);
10567 else
10568 gimplify_and_add (OMP_BODY (expr), &body);
10569 gimplify_adjust_omp_clauses (pre_p, body, &OMP_CLAUSES (expr),
10570 TREE_CODE (expr));
10572 switch (TREE_CODE (expr))
10574 case OACC_DATA:
10575 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_DATA,
10576 OMP_CLAUSES (expr));
10577 break;
10578 case OACC_KERNELS:
10579 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_KERNELS,
10580 OMP_CLAUSES (expr));
10581 break;
10582 case OACC_HOST_DATA:
10583 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_HOST_DATA,
10584 OMP_CLAUSES (expr));
10585 break;
10586 case OACC_PARALLEL:
10587 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_PARALLEL,
10588 OMP_CLAUSES (expr));
10589 break;
10590 case OMP_SECTIONS:
10591 stmt = gimple_build_omp_sections (body, OMP_CLAUSES (expr));
10592 break;
10593 case OMP_SINGLE:
10594 stmt = gimple_build_omp_single (body, OMP_CLAUSES (expr));
10595 break;
10596 case OMP_TARGET:
10597 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_REGION,
10598 OMP_CLAUSES (expr));
10599 break;
10600 case OMP_TARGET_DATA:
10601 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_DATA,
10602 OMP_CLAUSES (expr));
10603 break;
10604 case OMP_TEAMS:
10605 stmt = gimple_build_omp_teams (body, OMP_CLAUSES (expr));
10606 break;
10607 default:
10608 gcc_unreachable ();
10611 gimplify_seq_add_stmt (pre_p, stmt);
10612 *expr_p = NULL_TREE;
10615 /* Gimplify the gross structure of OpenACC enter/exit data, update, and OpenMP
10616 target update constructs. */
10618 static void
10619 gimplify_omp_target_update (tree *expr_p, gimple_seq *pre_p)
10621 tree expr = *expr_p;
10622 int kind;
10623 gomp_target *stmt;
10624 enum omp_region_type ort = ORT_WORKSHARE;
10626 switch (TREE_CODE (expr))
10628 case OACC_ENTER_DATA:
10629 case OACC_EXIT_DATA:
10630 kind = GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA;
10631 ort = ORT_ACC;
10632 break;
10633 case OACC_UPDATE:
10634 kind = GF_OMP_TARGET_KIND_OACC_UPDATE;
10635 ort = ORT_ACC;
10636 break;
10637 case OMP_TARGET_UPDATE:
10638 kind = GF_OMP_TARGET_KIND_UPDATE;
10639 break;
10640 case OMP_TARGET_ENTER_DATA:
10641 kind = GF_OMP_TARGET_KIND_ENTER_DATA;
10642 break;
10643 case OMP_TARGET_EXIT_DATA:
10644 kind = GF_OMP_TARGET_KIND_EXIT_DATA;
10645 break;
10646 default:
10647 gcc_unreachable ();
10649 gimplify_scan_omp_clauses (&OMP_STANDALONE_CLAUSES (expr), pre_p,
10650 ort, TREE_CODE (expr));
10651 gimplify_adjust_omp_clauses (pre_p, NULL, &OMP_STANDALONE_CLAUSES (expr),
10652 TREE_CODE (expr));
10653 stmt = gimple_build_omp_target (NULL, kind, OMP_STANDALONE_CLAUSES (expr));
10655 gimplify_seq_add_stmt (pre_p, stmt);
10656 *expr_p = NULL_TREE;
10659 /* A subroutine of gimplify_omp_atomic. The front end is supposed to have
10660 stabilized the lhs of the atomic operation as *ADDR. Return true if
10661 EXPR is this stabilized form. */
10663 static bool
10664 goa_lhs_expr_p (tree expr, tree addr)
10666 /* Also include casts to other type variants. The C front end is fond
10667 of adding these for e.g. volatile variables. This is like
10668 STRIP_TYPE_NOPS but includes the main variant lookup. */
10669 STRIP_USELESS_TYPE_CONVERSION (expr);
10671 if (TREE_CODE (expr) == INDIRECT_REF)
10673 expr = TREE_OPERAND (expr, 0);
10674 while (expr != addr
10675 && (CONVERT_EXPR_P (expr)
10676 || TREE_CODE (expr) == NON_LVALUE_EXPR)
10677 && TREE_CODE (expr) == TREE_CODE (addr)
10678 && types_compatible_p (TREE_TYPE (expr), TREE_TYPE (addr)))
10680 expr = TREE_OPERAND (expr, 0);
10681 addr = TREE_OPERAND (addr, 0);
10683 if (expr == addr)
10684 return true;
10685 return (TREE_CODE (addr) == ADDR_EXPR
10686 && TREE_CODE (expr) == ADDR_EXPR
10687 && TREE_OPERAND (addr, 0) == TREE_OPERAND (expr, 0));
10689 if (TREE_CODE (addr) == ADDR_EXPR && expr == TREE_OPERAND (addr, 0))
10690 return true;
10691 return false;
10694 /* Walk *EXPR_P and replace appearances of *LHS_ADDR with LHS_VAR. If an
10695 expression does not involve the lhs, evaluate it into a temporary.
10696 Return 1 if the lhs appeared as a subexpression, 0 if it did not,
10697 or -1 if an error was encountered. */
10699 static int
10700 goa_stabilize_expr (tree *expr_p, gimple_seq *pre_p, tree lhs_addr,
10701 tree lhs_var)
10703 tree expr = *expr_p;
10704 int saw_lhs;
10706 if (goa_lhs_expr_p (expr, lhs_addr))
10708 *expr_p = lhs_var;
10709 return 1;
10711 if (is_gimple_val (expr))
10712 return 0;
10714 saw_lhs = 0;
10715 switch (TREE_CODE_CLASS (TREE_CODE (expr)))
10717 case tcc_binary:
10718 case tcc_comparison:
10719 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p, lhs_addr,
10720 lhs_var);
10721 /* FALLTHRU */
10722 case tcc_unary:
10723 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p, lhs_addr,
10724 lhs_var);
10725 break;
10726 case tcc_expression:
10727 switch (TREE_CODE (expr))
10729 case TRUTH_ANDIF_EXPR:
10730 case TRUTH_ORIF_EXPR:
10731 case TRUTH_AND_EXPR:
10732 case TRUTH_OR_EXPR:
10733 case TRUTH_XOR_EXPR:
10734 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
10735 lhs_addr, lhs_var);
10736 /* FALLTHRU */
10737 case TRUTH_NOT_EXPR:
10738 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
10739 lhs_addr, lhs_var);
10740 break;
10741 case COMPOUND_EXPR:
10742 /* Break out any preevaluations from cp_build_modify_expr. */
10743 for (; TREE_CODE (expr) == COMPOUND_EXPR;
10744 expr = TREE_OPERAND (expr, 1))
10745 gimplify_stmt (&TREE_OPERAND (expr, 0), pre_p);
10746 *expr_p = expr;
10747 return goa_stabilize_expr (expr_p, pre_p, lhs_addr, lhs_var);
10748 default:
10749 break;
10751 break;
10752 default:
10753 break;
10756 if (saw_lhs == 0)
10758 enum gimplify_status gs;
10759 gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_val, fb_rvalue);
10760 if (gs != GS_ALL_DONE)
10761 saw_lhs = -1;
10764 return saw_lhs;
10767 /* Gimplify an OMP_ATOMIC statement. */
10769 static enum gimplify_status
10770 gimplify_omp_atomic (tree *expr_p, gimple_seq *pre_p)
10772 tree addr = TREE_OPERAND (*expr_p, 0);
10773 tree rhs = TREE_CODE (*expr_p) == OMP_ATOMIC_READ
10774 ? NULL : TREE_OPERAND (*expr_p, 1);
10775 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
10776 tree tmp_load;
10777 gomp_atomic_load *loadstmt;
10778 gomp_atomic_store *storestmt;
10780 tmp_load = create_tmp_reg (type);
10781 if (rhs && goa_stabilize_expr (&rhs, pre_p, addr, tmp_load) < 0)
10782 return GS_ERROR;
10784 if (gimplify_expr (&addr, pre_p, NULL, is_gimple_val, fb_rvalue)
10785 != GS_ALL_DONE)
10786 return GS_ERROR;
10788 loadstmt = gimple_build_omp_atomic_load (tmp_load, addr);
10789 gimplify_seq_add_stmt (pre_p, loadstmt);
10790 if (rhs && gimplify_expr (&rhs, pre_p, NULL, is_gimple_val, fb_rvalue)
10791 != GS_ALL_DONE)
10792 return GS_ERROR;
10794 if (TREE_CODE (*expr_p) == OMP_ATOMIC_READ)
10795 rhs = tmp_load;
10796 storestmt = gimple_build_omp_atomic_store (rhs);
10797 gimplify_seq_add_stmt (pre_p, storestmt);
10798 if (OMP_ATOMIC_SEQ_CST (*expr_p))
10800 gimple_omp_atomic_set_seq_cst (loadstmt);
10801 gimple_omp_atomic_set_seq_cst (storestmt);
10803 switch (TREE_CODE (*expr_p))
10805 case OMP_ATOMIC_READ:
10806 case OMP_ATOMIC_CAPTURE_OLD:
10807 *expr_p = tmp_load;
10808 gimple_omp_atomic_set_need_value (loadstmt);
10809 break;
10810 case OMP_ATOMIC_CAPTURE_NEW:
10811 *expr_p = rhs;
10812 gimple_omp_atomic_set_need_value (storestmt);
10813 break;
10814 default:
10815 *expr_p = NULL;
10816 break;
10819 return GS_ALL_DONE;
10822 /* Gimplify a TRANSACTION_EXPR. This involves gimplification of the
10823 body, and adding some EH bits. */
10825 static enum gimplify_status
10826 gimplify_transaction (tree *expr_p, gimple_seq *pre_p)
10828 tree expr = *expr_p, temp, tbody = TRANSACTION_EXPR_BODY (expr);
10829 gimple *body_stmt;
10830 gtransaction *trans_stmt;
10831 gimple_seq body = NULL;
10832 int subcode = 0;
10834 /* Wrap the transaction body in a BIND_EXPR so we have a context
10835 where to put decls for OMP. */
10836 if (TREE_CODE (tbody) != BIND_EXPR)
10838 tree bind = build3 (BIND_EXPR, void_type_node, NULL, tbody, NULL);
10839 TREE_SIDE_EFFECTS (bind) = 1;
10840 SET_EXPR_LOCATION (bind, EXPR_LOCATION (tbody));
10841 TRANSACTION_EXPR_BODY (expr) = bind;
10844 push_gimplify_context ();
10845 temp = voidify_wrapper_expr (*expr_p, NULL);
10847 body_stmt = gimplify_and_return_first (TRANSACTION_EXPR_BODY (expr), &body);
10848 pop_gimplify_context (body_stmt);
10850 trans_stmt = gimple_build_transaction (body);
10851 if (TRANSACTION_EXPR_OUTER (expr))
10852 subcode = GTMA_IS_OUTER;
10853 else if (TRANSACTION_EXPR_RELAXED (expr))
10854 subcode = GTMA_IS_RELAXED;
10855 gimple_transaction_set_subcode (trans_stmt, subcode);
10857 gimplify_seq_add_stmt (pre_p, trans_stmt);
10859 if (temp)
10861 *expr_p = temp;
10862 return GS_OK;
10865 *expr_p = NULL_TREE;
10866 return GS_ALL_DONE;
10869 /* Gimplify an OMP_ORDERED construct. EXPR is the tree version. BODY
10870 is the OMP_BODY of the original EXPR (which has already been
10871 gimplified so it's not present in the EXPR).
10873 Return the gimplified GIMPLE_OMP_ORDERED tuple. */
10875 static gimple *
10876 gimplify_omp_ordered (tree expr, gimple_seq body)
10878 tree c, decls;
10879 int failures = 0;
10880 unsigned int i;
10881 tree source_c = NULL_TREE;
10882 tree sink_c = NULL_TREE;
10884 if (gimplify_omp_ctxp)
10886 for (c = OMP_ORDERED_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
10887 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
10888 && gimplify_omp_ctxp->loop_iter_var.is_empty ()
10889 && (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK
10890 || OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE))
10892 error_at (OMP_CLAUSE_LOCATION (c),
10893 "%<ordered%> construct with %<depend%> clause must be "
10894 "closely nested inside a loop with %<ordered%> clause "
10895 "with a parameter");
10896 failures++;
10898 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
10899 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
10901 bool fail = false;
10902 for (decls = OMP_CLAUSE_DECL (c), i = 0;
10903 decls && TREE_CODE (decls) == TREE_LIST;
10904 decls = TREE_CHAIN (decls), ++i)
10905 if (i >= gimplify_omp_ctxp->loop_iter_var.length () / 2)
10906 continue;
10907 else if (TREE_VALUE (decls)
10908 != gimplify_omp_ctxp->loop_iter_var[2 * i])
10910 error_at (OMP_CLAUSE_LOCATION (c),
10911 "variable %qE is not an iteration "
10912 "of outermost loop %d, expected %qE",
10913 TREE_VALUE (decls), i + 1,
10914 gimplify_omp_ctxp->loop_iter_var[2 * i]);
10915 fail = true;
10916 failures++;
10918 else
10919 TREE_VALUE (decls)
10920 = gimplify_omp_ctxp->loop_iter_var[2 * i + 1];
10921 if (!fail && i != gimplify_omp_ctxp->loop_iter_var.length () / 2)
10923 error_at (OMP_CLAUSE_LOCATION (c),
10924 "number of variables in %<depend(sink)%> "
10925 "clause does not match number of "
10926 "iteration variables");
10927 failures++;
10929 sink_c = c;
10931 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
10932 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
10934 if (source_c)
10936 error_at (OMP_CLAUSE_LOCATION (c),
10937 "more than one %<depend(source)%> clause on an "
10938 "%<ordered%> construct");
10939 failures++;
10941 else
10942 source_c = c;
10945 if (source_c && sink_c)
10947 error_at (OMP_CLAUSE_LOCATION (source_c),
10948 "%<depend(source)%> clause specified together with "
10949 "%<depend(sink:)%> clauses on the same construct");
10950 failures++;
10953 if (failures)
10954 return gimple_build_nop ();
10955 return gimple_build_omp_ordered (body, OMP_ORDERED_CLAUSES (expr));
10958 /* Convert the GENERIC expression tree *EXPR_P to GIMPLE. If the
10959 expression produces a value to be used as an operand inside a GIMPLE
10960 statement, the value will be stored back in *EXPR_P. This value will
10961 be a tree of class tcc_declaration, tcc_constant, tcc_reference or
10962 an SSA_NAME. The corresponding sequence of GIMPLE statements is
10963 emitted in PRE_P and POST_P.
10965 Additionally, this process may overwrite parts of the input
10966 expression during gimplification. Ideally, it should be
10967 possible to do non-destructive gimplification.
10969 EXPR_P points to the GENERIC expression to convert to GIMPLE. If
10970 the expression needs to evaluate to a value to be used as
10971 an operand in a GIMPLE statement, this value will be stored in
10972 *EXPR_P on exit. This happens when the caller specifies one
10973 of fb_lvalue or fb_rvalue fallback flags.
10975 PRE_P will contain the sequence of GIMPLE statements corresponding
10976 to the evaluation of EXPR and all the side-effects that must
10977 be executed before the main expression. On exit, the last
10978 statement of PRE_P is the core statement being gimplified. For
10979 instance, when gimplifying 'if (++a)' the last statement in
10980 PRE_P will be 'if (t.1)' where t.1 is the result of
10981 pre-incrementing 'a'.
10983 POST_P will contain the sequence of GIMPLE statements corresponding
10984 to the evaluation of all the side-effects that must be executed
10985 after the main expression. If this is NULL, the post
10986 side-effects are stored at the end of PRE_P.
10988 The reason why the output is split in two is to handle post
10989 side-effects explicitly. In some cases, an expression may have
10990 inner and outer post side-effects which need to be emitted in
10991 an order different from the one given by the recursive
10992 traversal. For instance, for the expression (*p--)++ the post
10993 side-effects of '--' must actually occur *after* the post
10994 side-effects of '++'. However, gimplification will first visit
10995 the inner expression, so if a separate POST sequence was not
10996 used, the resulting sequence would be:
10998 1 t.1 = *p
10999 2 p = p - 1
11000 3 t.2 = t.1 + 1
11001 4 *p = t.2
11003 However, the post-decrement operation in line #2 must not be
11004 evaluated until after the store to *p at line #4, so the
11005 correct sequence should be:
11007 1 t.1 = *p
11008 2 t.2 = t.1 + 1
11009 3 *p = t.2
11010 4 p = p - 1
11012 So, by specifying a separate post queue, it is possible
11013 to emit the post side-effects in the correct order.
11014 If POST_P is NULL, an internal queue will be used. Before
11015 returning to the caller, the sequence POST_P is appended to
11016 the main output sequence PRE_P.
11018 GIMPLE_TEST_F points to a function that takes a tree T and
11019 returns nonzero if T is in the GIMPLE form requested by the
11020 caller. The GIMPLE predicates are in gimple.c.
11022 FALLBACK tells the function what sort of a temporary we want if
11023 gimplification cannot produce an expression that complies with
11024 GIMPLE_TEST_F.
11026 fb_none means that no temporary should be generated
11027 fb_rvalue means that an rvalue is OK to generate
11028 fb_lvalue means that an lvalue is OK to generate
11029 fb_either means that either is OK, but an lvalue is preferable.
11030 fb_mayfail means that gimplification may fail (in which case
11031 GS_ERROR will be returned)
11033 The return value is either GS_ERROR or GS_ALL_DONE, since this
11034 function iterates until EXPR is completely gimplified or an error
11035 occurs. */
11037 enum gimplify_status
11038 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
11039 bool (*gimple_test_f) (tree), fallback_t fallback)
11041 tree tmp;
11042 gimple_seq internal_pre = NULL;
11043 gimple_seq internal_post = NULL;
11044 tree save_expr;
11045 bool is_statement;
11046 location_t saved_location;
11047 enum gimplify_status ret;
11048 gimple_stmt_iterator pre_last_gsi, post_last_gsi;
11049 tree label;
11051 save_expr = *expr_p;
11052 if (save_expr == NULL_TREE)
11053 return GS_ALL_DONE;
11055 /* If we are gimplifying a top-level statement, PRE_P must be valid. */
11056 is_statement = gimple_test_f == is_gimple_stmt;
11057 if (is_statement)
11058 gcc_assert (pre_p);
11060 /* Consistency checks. */
11061 if (gimple_test_f == is_gimple_reg)
11062 gcc_assert (fallback & (fb_rvalue | fb_lvalue));
11063 else if (gimple_test_f == is_gimple_val
11064 || gimple_test_f == is_gimple_call_addr
11065 || gimple_test_f == is_gimple_condexpr
11066 || gimple_test_f == is_gimple_mem_rhs
11067 || gimple_test_f == is_gimple_mem_rhs_or_call
11068 || gimple_test_f == is_gimple_reg_rhs
11069 || gimple_test_f == is_gimple_reg_rhs_or_call
11070 || gimple_test_f == is_gimple_asm_val
11071 || gimple_test_f == is_gimple_mem_ref_addr)
11072 gcc_assert (fallback & fb_rvalue);
11073 else if (gimple_test_f == is_gimple_min_lval
11074 || gimple_test_f == is_gimple_lvalue)
11075 gcc_assert (fallback & fb_lvalue);
11076 else if (gimple_test_f == is_gimple_addressable)
11077 gcc_assert (fallback & fb_either);
11078 else if (gimple_test_f == is_gimple_stmt)
11079 gcc_assert (fallback == fb_none);
11080 else
11082 /* We should have recognized the GIMPLE_TEST_F predicate to
11083 know what kind of fallback to use in case a temporary is
11084 needed to hold the value or address of *EXPR_P. */
11085 gcc_unreachable ();
11088 /* We used to check the predicate here and return immediately if it
11089 succeeds. This is wrong; the design is for gimplification to be
11090 idempotent, and for the predicates to only test for valid forms, not
11091 whether they are fully simplified. */
11092 if (pre_p == NULL)
11093 pre_p = &internal_pre;
11095 if (post_p == NULL)
11096 post_p = &internal_post;
11098 /* Remember the last statements added to PRE_P and POST_P. Every
11099 new statement added by the gimplification helpers needs to be
11100 annotated with location information. To centralize the
11101 responsibility, we remember the last statement that had been
11102 added to both queues before gimplifying *EXPR_P. If
11103 gimplification produces new statements in PRE_P and POST_P, those
11104 statements will be annotated with the same location information
11105 as *EXPR_P. */
11106 pre_last_gsi = gsi_last (*pre_p);
11107 post_last_gsi = gsi_last (*post_p);
11109 saved_location = input_location;
11110 if (save_expr != error_mark_node
11111 && EXPR_HAS_LOCATION (*expr_p))
11112 input_location = EXPR_LOCATION (*expr_p);
11114 /* Loop over the specific gimplifiers until the toplevel node
11115 remains the same. */
11118 /* Strip away as many useless type conversions as possible
11119 at the toplevel. */
11120 STRIP_USELESS_TYPE_CONVERSION (*expr_p);
11122 /* Remember the expr. */
11123 save_expr = *expr_p;
11125 /* Die, die, die, my darling. */
11126 if (save_expr == error_mark_node
11127 || (TREE_TYPE (save_expr)
11128 && TREE_TYPE (save_expr) == error_mark_node))
11130 ret = GS_ERROR;
11131 break;
11134 /* Do any language-specific gimplification. */
11135 ret = ((enum gimplify_status)
11136 lang_hooks.gimplify_expr (expr_p, pre_p, post_p));
11137 if (ret == GS_OK)
11139 if (*expr_p == NULL_TREE)
11140 break;
11141 if (*expr_p != save_expr)
11142 continue;
11144 else if (ret != GS_UNHANDLED)
11145 break;
11147 /* Make sure that all the cases set 'ret' appropriately. */
11148 ret = GS_UNHANDLED;
11149 switch (TREE_CODE (*expr_p))
11151 /* First deal with the special cases. */
11153 case POSTINCREMENT_EXPR:
11154 case POSTDECREMENT_EXPR:
11155 case PREINCREMENT_EXPR:
11156 case PREDECREMENT_EXPR:
11157 ret = gimplify_self_mod_expr (expr_p, pre_p, post_p,
11158 fallback != fb_none,
11159 TREE_TYPE (*expr_p));
11160 break;
11162 case VIEW_CONVERT_EXPR:
11163 if (is_gimple_reg_type (TREE_TYPE (*expr_p))
11164 && is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0))))
11166 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
11167 post_p, is_gimple_val, fb_rvalue);
11168 recalculate_side_effects (*expr_p);
11169 break;
11171 /* Fallthru. */
11173 case ARRAY_REF:
11174 case ARRAY_RANGE_REF:
11175 case REALPART_EXPR:
11176 case IMAGPART_EXPR:
11177 case COMPONENT_REF:
11178 ret = gimplify_compound_lval (expr_p, pre_p, post_p,
11179 fallback ? fallback : fb_rvalue);
11180 break;
11182 case COND_EXPR:
11183 ret = gimplify_cond_expr (expr_p, pre_p, fallback);
11185 /* C99 code may assign to an array in a structure value of a
11186 conditional expression, and this has undefined behavior
11187 only on execution, so create a temporary if an lvalue is
11188 required. */
11189 if (fallback == fb_lvalue)
11191 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
11192 mark_addressable (*expr_p);
11193 ret = GS_OK;
11195 break;
11197 case CALL_EXPR:
11198 ret = gimplify_call_expr (expr_p, pre_p, fallback != fb_none);
11200 /* C99 code may assign to an array in a structure returned
11201 from a function, and this has undefined behavior only on
11202 execution, so create a temporary if an lvalue is
11203 required. */
11204 if (fallback == fb_lvalue)
11206 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
11207 mark_addressable (*expr_p);
11208 ret = GS_OK;
11210 break;
11212 case TREE_LIST:
11213 gcc_unreachable ();
11215 case COMPOUND_EXPR:
11216 ret = gimplify_compound_expr (expr_p, pre_p, fallback != fb_none);
11217 break;
11219 case COMPOUND_LITERAL_EXPR:
11220 ret = gimplify_compound_literal_expr (expr_p, pre_p,
11221 gimple_test_f, fallback);
11222 break;
11224 case MODIFY_EXPR:
11225 case INIT_EXPR:
11226 ret = gimplify_modify_expr (expr_p, pre_p, post_p,
11227 fallback != fb_none);
11228 break;
11230 case TRUTH_ANDIF_EXPR:
11231 case TRUTH_ORIF_EXPR:
11233 /* Preserve the original type of the expression and the
11234 source location of the outer expression. */
11235 tree org_type = TREE_TYPE (*expr_p);
11236 *expr_p = gimple_boolify (*expr_p);
11237 *expr_p = build3_loc (input_location, COND_EXPR,
11238 org_type, *expr_p,
11239 fold_convert_loc
11240 (input_location,
11241 org_type, boolean_true_node),
11242 fold_convert_loc
11243 (input_location,
11244 org_type, boolean_false_node));
11245 ret = GS_OK;
11246 break;
11249 case TRUTH_NOT_EXPR:
11251 tree type = TREE_TYPE (*expr_p);
11252 /* The parsers are careful to generate TRUTH_NOT_EXPR
11253 only with operands that are always zero or one.
11254 We do not fold here but handle the only interesting case
11255 manually, as fold may re-introduce the TRUTH_NOT_EXPR. */
11256 *expr_p = gimple_boolify (*expr_p);
11257 if (TYPE_PRECISION (TREE_TYPE (*expr_p)) == 1)
11258 *expr_p = build1_loc (input_location, BIT_NOT_EXPR,
11259 TREE_TYPE (*expr_p),
11260 TREE_OPERAND (*expr_p, 0));
11261 else
11262 *expr_p = build2_loc (input_location, BIT_XOR_EXPR,
11263 TREE_TYPE (*expr_p),
11264 TREE_OPERAND (*expr_p, 0),
11265 build_int_cst (TREE_TYPE (*expr_p), 1));
11266 if (!useless_type_conversion_p (type, TREE_TYPE (*expr_p)))
11267 *expr_p = fold_convert_loc (input_location, type, *expr_p);
11268 ret = GS_OK;
11269 break;
11272 case ADDR_EXPR:
11273 ret = gimplify_addr_expr (expr_p, pre_p, post_p);
11274 break;
11276 case ANNOTATE_EXPR:
11278 tree cond = TREE_OPERAND (*expr_p, 0);
11279 tree kind = TREE_OPERAND (*expr_p, 1);
11280 tree type = TREE_TYPE (cond);
11281 if (!INTEGRAL_TYPE_P (type))
11283 *expr_p = cond;
11284 ret = GS_OK;
11285 break;
11287 tree tmp = create_tmp_var (type);
11288 gimplify_arg (&cond, pre_p, EXPR_LOCATION (*expr_p));
11289 gcall *call
11290 = gimple_build_call_internal (IFN_ANNOTATE, 2, cond, kind);
11291 gimple_call_set_lhs (call, tmp);
11292 gimplify_seq_add_stmt (pre_p, call);
11293 *expr_p = tmp;
11294 ret = GS_ALL_DONE;
11295 break;
11298 case VA_ARG_EXPR:
11299 ret = gimplify_va_arg_expr (expr_p, pre_p, post_p);
11300 break;
11302 CASE_CONVERT:
11303 if (IS_EMPTY_STMT (*expr_p))
11305 ret = GS_ALL_DONE;
11306 break;
11309 if (VOID_TYPE_P (TREE_TYPE (*expr_p))
11310 || fallback == fb_none)
11312 /* Just strip a conversion to void (or in void context) and
11313 try again. */
11314 *expr_p = TREE_OPERAND (*expr_p, 0);
11315 ret = GS_OK;
11316 break;
11319 ret = gimplify_conversion (expr_p);
11320 if (ret == GS_ERROR)
11321 break;
11322 if (*expr_p != save_expr)
11323 break;
11324 /* FALLTHRU */
11326 case FIX_TRUNC_EXPR:
11327 /* unary_expr: ... | '(' cast ')' val | ... */
11328 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
11329 is_gimple_val, fb_rvalue);
11330 recalculate_side_effects (*expr_p);
11331 break;
11333 case INDIRECT_REF:
11335 bool volatilep = TREE_THIS_VOLATILE (*expr_p);
11336 bool notrap = TREE_THIS_NOTRAP (*expr_p);
11337 tree saved_ptr_type = TREE_TYPE (TREE_OPERAND (*expr_p, 0));
11339 *expr_p = fold_indirect_ref_loc (input_location, *expr_p);
11340 if (*expr_p != save_expr)
11342 ret = GS_OK;
11343 break;
11346 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
11347 is_gimple_reg, fb_rvalue);
11348 if (ret == GS_ERROR)
11349 break;
11351 recalculate_side_effects (*expr_p);
11352 *expr_p = fold_build2_loc (input_location, MEM_REF,
11353 TREE_TYPE (*expr_p),
11354 TREE_OPERAND (*expr_p, 0),
11355 build_int_cst (saved_ptr_type, 0));
11356 TREE_THIS_VOLATILE (*expr_p) = volatilep;
11357 TREE_THIS_NOTRAP (*expr_p) = notrap;
11358 ret = GS_OK;
11359 break;
11362 /* We arrive here through the various re-gimplifcation paths. */
11363 case MEM_REF:
11364 /* First try re-folding the whole thing. */
11365 tmp = fold_binary (MEM_REF, TREE_TYPE (*expr_p),
11366 TREE_OPERAND (*expr_p, 0),
11367 TREE_OPERAND (*expr_p, 1));
11368 if (tmp)
11370 REF_REVERSE_STORAGE_ORDER (tmp)
11371 = REF_REVERSE_STORAGE_ORDER (*expr_p);
11372 *expr_p = tmp;
11373 recalculate_side_effects (*expr_p);
11374 ret = GS_OK;
11375 break;
11377 /* Avoid re-gimplifying the address operand if it is already
11378 in suitable form. Re-gimplifying would mark the address
11379 operand addressable. Always gimplify when not in SSA form
11380 as we still may have to gimplify decls with value-exprs. */
11381 if (!gimplify_ctxp || !gimple_in_ssa_p (cfun)
11382 || !is_gimple_mem_ref_addr (TREE_OPERAND (*expr_p, 0)))
11384 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
11385 is_gimple_mem_ref_addr, fb_rvalue);
11386 if (ret == GS_ERROR)
11387 break;
11389 recalculate_side_effects (*expr_p);
11390 ret = GS_ALL_DONE;
11391 break;
11393 /* Constants need not be gimplified. */
11394 case INTEGER_CST:
11395 case REAL_CST:
11396 case FIXED_CST:
11397 case STRING_CST:
11398 case COMPLEX_CST:
11399 case VECTOR_CST:
11400 /* Drop the overflow flag on constants, we do not want
11401 that in the GIMPLE IL. */
11402 if (TREE_OVERFLOW_P (*expr_p))
11403 *expr_p = drop_tree_overflow (*expr_p);
11404 ret = GS_ALL_DONE;
11405 break;
11407 case CONST_DECL:
11408 /* If we require an lvalue, such as for ADDR_EXPR, retain the
11409 CONST_DECL node. Otherwise the decl is replaceable by its
11410 value. */
11411 /* ??? Should be == fb_lvalue, but ADDR_EXPR passes fb_either. */
11412 if (fallback & fb_lvalue)
11413 ret = GS_ALL_DONE;
11414 else
11416 *expr_p = DECL_INITIAL (*expr_p);
11417 ret = GS_OK;
11419 break;
11421 case DECL_EXPR:
11422 ret = gimplify_decl_expr (expr_p, pre_p);
11423 break;
11425 case BIND_EXPR:
11426 ret = gimplify_bind_expr (expr_p, pre_p);
11427 break;
11429 case LOOP_EXPR:
11430 ret = gimplify_loop_expr (expr_p, pre_p);
11431 break;
11433 case SWITCH_EXPR:
11434 ret = gimplify_switch_expr (expr_p, pre_p);
11435 break;
11437 case EXIT_EXPR:
11438 ret = gimplify_exit_expr (expr_p);
11439 break;
11441 case GOTO_EXPR:
11442 /* If the target is not LABEL, then it is a computed jump
11443 and the target needs to be gimplified. */
11444 if (TREE_CODE (GOTO_DESTINATION (*expr_p)) != LABEL_DECL)
11446 ret = gimplify_expr (&GOTO_DESTINATION (*expr_p), pre_p,
11447 NULL, is_gimple_val, fb_rvalue);
11448 if (ret == GS_ERROR)
11449 break;
11451 gimplify_seq_add_stmt (pre_p,
11452 gimple_build_goto (GOTO_DESTINATION (*expr_p)));
11453 ret = GS_ALL_DONE;
11454 break;
11456 case PREDICT_EXPR:
11457 gimplify_seq_add_stmt (pre_p,
11458 gimple_build_predict (PREDICT_EXPR_PREDICTOR (*expr_p),
11459 PREDICT_EXPR_OUTCOME (*expr_p)));
11460 ret = GS_ALL_DONE;
11461 break;
11463 case LABEL_EXPR:
11464 ret = gimplify_label_expr (expr_p, pre_p);
11465 label = LABEL_EXPR_LABEL (*expr_p);
11466 gcc_assert (decl_function_context (label) == current_function_decl);
11468 /* If the label is used in a goto statement, or address of the label
11469 is taken, we need to unpoison all variables that were seen so far.
11470 Doing so would prevent us from reporting a false positives. */
11471 if (asan_poisoned_variables
11472 && asan_used_labels != NULL
11473 && asan_used_labels->contains (label))
11474 asan_poison_variables (asan_poisoned_variables, false, pre_p);
11475 break;
11477 case CASE_LABEL_EXPR:
11478 ret = gimplify_case_label_expr (expr_p, pre_p);
11480 if (gimplify_ctxp->live_switch_vars)
11481 asan_poison_variables (gimplify_ctxp->live_switch_vars, false,
11482 pre_p);
11483 break;
11485 case RETURN_EXPR:
11486 ret = gimplify_return_expr (*expr_p, pre_p);
11487 break;
11489 case CONSTRUCTOR:
11490 /* Don't reduce this in place; let gimplify_init_constructor work its
11491 magic. Buf if we're just elaborating this for side effects, just
11492 gimplify any element that has side-effects. */
11493 if (fallback == fb_none)
11495 unsigned HOST_WIDE_INT ix;
11496 tree val;
11497 tree temp = NULL_TREE;
11498 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (*expr_p), ix, val)
11499 if (TREE_SIDE_EFFECTS (val))
11500 append_to_statement_list (val, &temp);
11502 *expr_p = temp;
11503 ret = temp ? GS_OK : GS_ALL_DONE;
11505 /* C99 code may assign to an array in a constructed
11506 structure or union, and this has undefined behavior only
11507 on execution, so create a temporary if an lvalue is
11508 required. */
11509 else if (fallback == fb_lvalue)
11511 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
11512 mark_addressable (*expr_p);
11513 ret = GS_OK;
11515 else
11516 ret = GS_ALL_DONE;
11517 break;
11519 /* The following are special cases that are not handled by the
11520 original GIMPLE grammar. */
11522 /* SAVE_EXPR nodes are converted into a GIMPLE identifier and
11523 eliminated. */
11524 case SAVE_EXPR:
11525 ret = gimplify_save_expr (expr_p, pre_p, post_p);
11526 break;
11528 case BIT_FIELD_REF:
11529 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
11530 post_p, is_gimple_lvalue, fb_either);
11531 recalculate_side_effects (*expr_p);
11532 break;
11534 case TARGET_MEM_REF:
11536 enum gimplify_status r0 = GS_ALL_DONE, r1 = GS_ALL_DONE;
11538 if (TMR_BASE (*expr_p))
11539 r0 = gimplify_expr (&TMR_BASE (*expr_p), pre_p,
11540 post_p, is_gimple_mem_ref_addr, fb_either);
11541 if (TMR_INDEX (*expr_p))
11542 r1 = gimplify_expr (&TMR_INDEX (*expr_p), pre_p,
11543 post_p, is_gimple_val, fb_rvalue);
11544 if (TMR_INDEX2 (*expr_p))
11545 r1 = gimplify_expr (&TMR_INDEX2 (*expr_p), pre_p,
11546 post_p, is_gimple_val, fb_rvalue);
11547 /* TMR_STEP and TMR_OFFSET are always integer constants. */
11548 ret = MIN (r0, r1);
11550 break;
11552 case NON_LVALUE_EXPR:
11553 /* This should have been stripped above. */
11554 gcc_unreachable ();
11556 case ASM_EXPR:
11557 ret = gimplify_asm_expr (expr_p, pre_p, post_p);
11558 break;
11560 case TRY_FINALLY_EXPR:
11561 case TRY_CATCH_EXPR:
11563 gimple_seq eval, cleanup;
11564 gtry *try_;
11566 /* Calls to destructors are generated automatically in FINALLY/CATCH
11567 block. They should have location as UNKNOWN_LOCATION. However,
11568 gimplify_call_expr will reset these call stmts to input_location
11569 if it finds stmt's location is unknown. To prevent resetting for
11570 destructors, we set the input_location to unknown.
11571 Note that this only affects the destructor calls in FINALLY/CATCH
11572 block, and will automatically reset to its original value by the
11573 end of gimplify_expr. */
11574 input_location = UNKNOWN_LOCATION;
11575 eval = cleanup = NULL;
11576 gimplify_and_add (TREE_OPERAND (*expr_p, 0), &eval);
11577 gimplify_and_add (TREE_OPERAND (*expr_p, 1), &cleanup);
11578 /* Don't create bogus GIMPLE_TRY with empty cleanup. */
11579 if (gimple_seq_empty_p (cleanup))
11581 gimple_seq_add_seq (pre_p, eval);
11582 ret = GS_ALL_DONE;
11583 break;
11585 try_ = gimple_build_try (eval, cleanup,
11586 TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
11587 ? GIMPLE_TRY_FINALLY
11588 : GIMPLE_TRY_CATCH);
11589 if (EXPR_HAS_LOCATION (save_expr))
11590 gimple_set_location (try_, EXPR_LOCATION (save_expr));
11591 else if (LOCATION_LOCUS (saved_location) != UNKNOWN_LOCATION)
11592 gimple_set_location (try_, saved_location);
11593 if (TREE_CODE (*expr_p) == TRY_CATCH_EXPR)
11594 gimple_try_set_catch_is_cleanup (try_,
11595 TRY_CATCH_IS_CLEANUP (*expr_p));
11596 gimplify_seq_add_stmt (pre_p, try_);
11597 ret = GS_ALL_DONE;
11598 break;
11601 case CLEANUP_POINT_EXPR:
11602 ret = gimplify_cleanup_point_expr (expr_p, pre_p);
11603 break;
11605 case TARGET_EXPR:
11606 ret = gimplify_target_expr (expr_p, pre_p, post_p);
11607 break;
11609 case CATCH_EXPR:
11611 gimple *c;
11612 gimple_seq handler = NULL;
11613 gimplify_and_add (CATCH_BODY (*expr_p), &handler);
11614 c = gimple_build_catch (CATCH_TYPES (*expr_p), handler);
11615 gimplify_seq_add_stmt (pre_p, c);
11616 ret = GS_ALL_DONE;
11617 break;
11620 case EH_FILTER_EXPR:
11622 gimple *ehf;
11623 gimple_seq failure = NULL;
11625 gimplify_and_add (EH_FILTER_FAILURE (*expr_p), &failure);
11626 ehf = gimple_build_eh_filter (EH_FILTER_TYPES (*expr_p), failure);
11627 gimple_set_no_warning (ehf, TREE_NO_WARNING (*expr_p));
11628 gimplify_seq_add_stmt (pre_p, ehf);
11629 ret = GS_ALL_DONE;
11630 break;
11633 case OBJ_TYPE_REF:
11635 enum gimplify_status r0, r1;
11636 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p,
11637 post_p, is_gimple_val, fb_rvalue);
11638 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p,
11639 post_p, is_gimple_val, fb_rvalue);
11640 TREE_SIDE_EFFECTS (*expr_p) = 0;
11641 ret = MIN (r0, r1);
11643 break;
11645 case LABEL_DECL:
11646 /* We get here when taking the address of a label. We mark
11647 the label as "forced"; meaning it can never be removed and
11648 it is a potential target for any computed goto. */
11649 FORCED_LABEL (*expr_p) = 1;
11650 ret = GS_ALL_DONE;
11651 break;
11653 case STATEMENT_LIST:
11654 ret = gimplify_statement_list (expr_p, pre_p);
11655 break;
11657 case WITH_SIZE_EXPR:
11659 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
11660 post_p == &internal_post ? NULL : post_p,
11661 gimple_test_f, fallback);
11662 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
11663 is_gimple_val, fb_rvalue);
11664 ret = GS_ALL_DONE;
11666 break;
11668 case VAR_DECL:
11669 case PARM_DECL:
11670 ret = gimplify_var_or_parm_decl (expr_p);
11671 break;
11673 case RESULT_DECL:
11674 /* When within an OMP context, notice uses of variables. */
11675 if (gimplify_omp_ctxp)
11676 omp_notice_variable (gimplify_omp_ctxp, *expr_p, true);
11677 ret = GS_ALL_DONE;
11678 break;
11680 case SSA_NAME:
11681 /* Allow callbacks into the gimplifier during optimization. */
11682 ret = GS_ALL_DONE;
11683 break;
11685 case OMP_PARALLEL:
11686 gimplify_omp_parallel (expr_p, pre_p);
11687 ret = GS_ALL_DONE;
11688 break;
11690 case OMP_TASK:
11691 gimplify_omp_task (expr_p, pre_p);
11692 ret = GS_ALL_DONE;
11693 break;
11695 case OMP_FOR:
11696 case OMP_SIMD:
11697 case CILK_SIMD:
11698 case CILK_FOR:
11699 case OMP_DISTRIBUTE:
11700 case OMP_TASKLOOP:
11701 case OACC_LOOP:
11702 ret = gimplify_omp_for (expr_p, pre_p);
11703 break;
11705 case OACC_CACHE:
11706 gimplify_oacc_cache (expr_p, pre_p);
11707 ret = GS_ALL_DONE;
11708 break;
11710 case OACC_DECLARE:
11711 gimplify_oacc_declare (expr_p, pre_p);
11712 ret = GS_ALL_DONE;
11713 break;
11715 case OACC_HOST_DATA:
11716 case OACC_DATA:
11717 case OACC_KERNELS:
11718 case OACC_PARALLEL:
11719 case OMP_SECTIONS:
11720 case OMP_SINGLE:
11721 case OMP_TARGET:
11722 case OMP_TARGET_DATA:
11723 case OMP_TEAMS:
11724 gimplify_omp_workshare (expr_p, pre_p);
11725 ret = GS_ALL_DONE;
11726 break;
11728 case OACC_ENTER_DATA:
11729 case OACC_EXIT_DATA:
11730 case OACC_UPDATE:
11731 case OMP_TARGET_UPDATE:
11732 case OMP_TARGET_ENTER_DATA:
11733 case OMP_TARGET_EXIT_DATA:
11734 gimplify_omp_target_update (expr_p, pre_p);
11735 ret = GS_ALL_DONE;
11736 break;
11738 case OMP_SECTION:
11739 case OMP_MASTER:
11740 case OMP_TASKGROUP:
11741 case OMP_ORDERED:
11742 case OMP_CRITICAL:
11744 gimple_seq body = NULL;
11745 gimple *g;
11747 gimplify_and_add (OMP_BODY (*expr_p), &body);
11748 switch (TREE_CODE (*expr_p))
11750 case OMP_SECTION:
11751 g = gimple_build_omp_section (body);
11752 break;
11753 case OMP_MASTER:
11754 g = gimple_build_omp_master (body);
11755 break;
11756 case OMP_TASKGROUP:
11758 gimple_seq cleanup = NULL;
11759 tree fn
11760 = builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_END);
11761 g = gimple_build_call (fn, 0);
11762 gimple_seq_add_stmt (&cleanup, g);
11763 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
11764 body = NULL;
11765 gimple_seq_add_stmt (&body, g);
11766 g = gimple_build_omp_taskgroup (body);
11768 break;
11769 case OMP_ORDERED:
11770 g = gimplify_omp_ordered (*expr_p, body);
11771 break;
11772 case OMP_CRITICAL:
11773 gimplify_scan_omp_clauses (&OMP_CRITICAL_CLAUSES (*expr_p),
11774 pre_p, ORT_WORKSHARE, OMP_CRITICAL);
11775 gimplify_adjust_omp_clauses (pre_p, body,
11776 &OMP_CRITICAL_CLAUSES (*expr_p),
11777 OMP_CRITICAL);
11778 g = gimple_build_omp_critical (body,
11779 OMP_CRITICAL_NAME (*expr_p),
11780 OMP_CRITICAL_CLAUSES (*expr_p));
11781 break;
11782 default:
11783 gcc_unreachable ();
11785 gimplify_seq_add_stmt (pre_p, g);
11786 ret = GS_ALL_DONE;
11787 break;
11790 case OMP_ATOMIC:
11791 case OMP_ATOMIC_READ:
11792 case OMP_ATOMIC_CAPTURE_OLD:
11793 case OMP_ATOMIC_CAPTURE_NEW:
11794 ret = gimplify_omp_atomic (expr_p, pre_p);
11795 break;
11797 case TRANSACTION_EXPR:
11798 ret = gimplify_transaction (expr_p, pre_p);
11799 break;
11801 case TRUTH_AND_EXPR:
11802 case TRUTH_OR_EXPR:
11803 case TRUTH_XOR_EXPR:
11805 tree orig_type = TREE_TYPE (*expr_p);
11806 tree new_type, xop0, xop1;
11807 *expr_p = gimple_boolify (*expr_p);
11808 new_type = TREE_TYPE (*expr_p);
11809 if (!useless_type_conversion_p (orig_type, new_type))
11811 *expr_p = fold_convert_loc (input_location, orig_type, *expr_p);
11812 ret = GS_OK;
11813 break;
11816 /* Boolified binary truth expressions are semantically equivalent
11817 to bitwise binary expressions. Canonicalize them to the
11818 bitwise variant. */
11819 switch (TREE_CODE (*expr_p))
11821 case TRUTH_AND_EXPR:
11822 TREE_SET_CODE (*expr_p, BIT_AND_EXPR);
11823 break;
11824 case TRUTH_OR_EXPR:
11825 TREE_SET_CODE (*expr_p, BIT_IOR_EXPR);
11826 break;
11827 case TRUTH_XOR_EXPR:
11828 TREE_SET_CODE (*expr_p, BIT_XOR_EXPR);
11829 break;
11830 default:
11831 break;
11833 /* Now make sure that operands have compatible type to
11834 expression's new_type. */
11835 xop0 = TREE_OPERAND (*expr_p, 0);
11836 xop1 = TREE_OPERAND (*expr_p, 1);
11837 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop0)))
11838 TREE_OPERAND (*expr_p, 0) = fold_convert_loc (input_location,
11839 new_type,
11840 xop0);
11841 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop1)))
11842 TREE_OPERAND (*expr_p, 1) = fold_convert_loc (input_location,
11843 new_type,
11844 xop1);
11845 /* Continue classified as tcc_binary. */
11846 goto expr_2;
11849 case VEC_COND_EXPR:
11851 enum gimplify_status r0, r1, r2;
11853 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
11854 post_p, is_gimple_condexpr, fb_rvalue);
11855 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
11856 post_p, is_gimple_val, fb_rvalue);
11857 r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p,
11858 post_p, is_gimple_val, fb_rvalue);
11860 ret = MIN (MIN (r0, r1), r2);
11861 recalculate_side_effects (*expr_p);
11863 break;
11865 case FMA_EXPR:
11866 case VEC_PERM_EXPR:
11867 /* Classified as tcc_expression. */
11868 goto expr_3;
11870 case BIT_INSERT_EXPR:
11871 /* Argument 3 is a constant. */
11872 goto expr_2;
11874 case POINTER_PLUS_EXPR:
11876 enum gimplify_status r0, r1;
11877 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
11878 post_p, is_gimple_val, fb_rvalue);
11879 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
11880 post_p, is_gimple_val, fb_rvalue);
11881 recalculate_side_effects (*expr_p);
11882 ret = MIN (r0, r1);
11883 break;
11886 case CILK_SYNC_STMT:
11888 if (!fn_contains_cilk_spawn_p (cfun))
11890 error_at (EXPR_LOCATION (*expr_p),
11891 "expected %<_Cilk_spawn%> before %<_Cilk_sync%>");
11892 ret = GS_ERROR;
11894 else
11896 gimplify_cilk_sync (expr_p, pre_p);
11897 ret = GS_ALL_DONE;
11899 break;
11902 default:
11903 switch (TREE_CODE_CLASS (TREE_CODE (*expr_p)))
11905 case tcc_comparison:
11906 /* Handle comparison of objects of non scalar mode aggregates
11907 with a call to memcmp. It would be nice to only have to do
11908 this for variable-sized objects, but then we'd have to allow
11909 the same nest of reference nodes we allow for MODIFY_EXPR and
11910 that's too complex.
11912 Compare scalar mode aggregates as scalar mode values. Using
11913 memcmp for them would be very inefficient at best, and is
11914 plain wrong if bitfields are involved. */
11916 tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 1));
11918 /* Vector comparisons need no boolification. */
11919 if (TREE_CODE (type) == VECTOR_TYPE)
11920 goto expr_2;
11921 else if (!AGGREGATE_TYPE_P (type))
11923 tree org_type = TREE_TYPE (*expr_p);
11924 *expr_p = gimple_boolify (*expr_p);
11925 if (!useless_type_conversion_p (org_type,
11926 TREE_TYPE (*expr_p)))
11928 *expr_p = fold_convert_loc (input_location,
11929 org_type, *expr_p);
11930 ret = GS_OK;
11932 else
11933 goto expr_2;
11935 else if (TYPE_MODE (type) != BLKmode)
11936 ret = gimplify_scalar_mode_aggregate_compare (expr_p);
11937 else
11938 ret = gimplify_variable_sized_compare (expr_p);
11940 break;
11943 /* If *EXPR_P does not need to be special-cased, handle it
11944 according to its class. */
11945 case tcc_unary:
11946 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
11947 post_p, is_gimple_val, fb_rvalue);
11948 break;
11950 case tcc_binary:
11951 expr_2:
11953 enum gimplify_status r0, r1;
11955 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
11956 post_p, is_gimple_val, fb_rvalue);
11957 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
11958 post_p, is_gimple_val, fb_rvalue);
11960 ret = MIN (r0, r1);
11961 break;
11964 expr_3:
11966 enum gimplify_status r0, r1, r2;
11968 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
11969 post_p, is_gimple_val, fb_rvalue);
11970 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
11971 post_p, is_gimple_val, fb_rvalue);
11972 r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p,
11973 post_p, is_gimple_val, fb_rvalue);
11975 ret = MIN (MIN (r0, r1), r2);
11976 break;
11979 case tcc_declaration:
11980 case tcc_constant:
11981 ret = GS_ALL_DONE;
11982 goto dont_recalculate;
11984 default:
11985 gcc_unreachable ();
11988 recalculate_side_effects (*expr_p);
11990 dont_recalculate:
11991 break;
11994 gcc_assert (*expr_p || ret != GS_OK);
11996 while (ret == GS_OK);
11998 /* If we encountered an error_mark somewhere nested inside, either
11999 stub out the statement or propagate the error back out. */
12000 if (ret == GS_ERROR)
12002 if (is_statement)
12003 *expr_p = NULL;
12004 goto out;
12007 /* This was only valid as a return value from the langhook, which
12008 we handled. Make sure it doesn't escape from any other context. */
12009 gcc_assert (ret != GS_UNHANDLED);
12011 if (fallback == fb_none && *expr_p && !is_gimple_stmt (*expr_p))
12013 /* We aren't looking for a value, and we don't have a valid
12014 statement. If it doesn't have side-effects, throw it away.
12015 We can also get here with code such as "*&&L;", where L is
12016 a LABEL_DECL that is marked as FORCED_LABEL. */
12017 if (TREE_CODE (*expr_p) == LABEL_DECL
12018 || !TREE_SIDE_EFFECTS (*expr_p))
12019 *expr_p = NULL;
12020 else if (!TREE_THIS_VOLATILE (*expr_p))
12022 /* This is probably a _REF that contains something nested that
12023 has side effects. Recurse through the operands to find it. */
12024 enum tree_code code = TREE_CODE (*expr_p);
12026 switch (code)
12028 case COMPONENT_REF:
12029 case REALPART_EXPR:
12030 case IMAGPART_EXPR:
12031 case VIEW_CONVERT_EXPR:
12032 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
12033 gimple_test_f, fallback);
12034 break;
12036 case ARRAY_REF:
12037 case ARRAY_RANGE_REF:
12038 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
12039 gimple_test_f, fallback);
12040 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
12041 gimple_test_f, fallback);
12042 break;
12044 default:
12045 /* Anything else with side-effects must be converted to
12046 a valid statement before we get here. */
12047 gcc_unreachable ();
12050 *expr_p = NULL;
12052 else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p))
12053 && TYPE_MODE (TREE_TYPE (*expr_p)) != BLKmode)
12055 /* Historically, the compiler has treated a bare reference
12056 to a non-BLKmode volatile lvalue as forcing a load. */
12057 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p));
12059 /* Normally, we do not want to create a temporary for a
12060 TREE_ADDRESSABLE type because such a type should not be
12061 copied by bitwise-assignment. However, we make an
12062 exception here, as all we are doing here is ensuring that
12063 we read the bytes that make up the type. We use
12064 create_tmp_var_raw because create_tmp_var will abort when
12065 given a TREE_ADDRESSABLE type. */
12066 tree tmp = create_tmp_var_raw (type, "vol");
12067 gimple_add_tmp_var (tmp);
12068 gimplify_assign (tmp, *expr_p, pre_p);
12069 *expr_p = NULL;
12071 else
12072 /* We can't do anything useful with a volatile reference to
12073 an incomplete type, so just throw it away. Likewise for
12074 a BLKmode type, since any implicit inner load should
12075 already have been turned into an explicit one by the
12076 gimplification process. */
12077 *expr_p = NULL;
12080 /* If we are gimplifying at the statement level, we're done. Tack
12081 everything together and return. */
12082 if (fallback == fb_none || is_statement)
12084 /* Since *EXPR_P has been converted into a GIMPLE tuple, clear
12085 it out for GC to reclaim it. */
12086 *expr_p = NULL_TREE;
12088 if (!gimple_seq_empty_p (internal_pre)
12089 || !gimple_seq_empty_p (internal_post))
12091 gimplify_seq_add_seq (&internal_pre, internal_post);
12092 gimplify_seq_add_seq (pre_p, internal_pre);
12095 /* The result of gimplifying *EXPR_P is going to be the last few
12096 statements in *PRE_P and *POST_P. Add location information
12097 to all the statements that were added by the gimplification
12098 helpers. */
12099 if (!gimple_seq_empty_p (*pre_p))
12100 annotate_all_with_location_after (*pre_p, pre_last_gsi, input_location);
12102 if (!gimple_seq_empty_p (*post_p))
12103 annotate_all_with_location_after (*post_p, post_last_gsi,
12104 input_location);
12106 goto out;
12109 #ifdef ENABLE_GIMPLE_CHECKING
12110 if (*expr_p)
12112 enum tree_code code = TREE_CODE (*expr_p);
12113 /* These expressions should already be in gimple IR form. */
12114 gcc_assert (code != MODIFY_EXPR
12115 && code != ASM_EXPR
12116 && code != BIND_EXPR
12117 && code != CATCH_EXPR
12118 && (code != COND_EXPR || gimplify_ctxp->allow_rhs_cond_expr)
12119 && code != EH_FILTER_EXPR
12120 && code != GOTO_EXPR
12121 && code != LABEL_EXPR
12122 && code != LOOP_EXPR
12123 && code != SWITCH_EXPR
12124 && code != TRY_FINALLY_EXPR
12125 && code != OACC_PARALLEL
12126 && code != OACC_KERNELS
12127 && code != OACC_DATA
12128 && code != OACC_HOST_DATA
12129 && code != OACC_DECLARE
12130 && code != OACC_UPDATE
12131 && code != OACC_ENTER_DATA
12132 && code != OACC_EXIT_DATA
12133 && code != OACC_CACHE
12134 && code != OMP_CRITICAL
12135 && code != OMP_FOR
12136 && code != OACC_LOOP
12137 && code != OMP_MASTER
12138 && code != OMP_TASKGROUP
12139 && code != OMP_ORDERED
12140 && code != OMP_PARALLEL
12141 && code != OMP_SECTIONS
12142 && code != OMP_SECTION
12143 && code != OMP_SINGLE);
12145 #endif
12147 /* Otherwise we're gimplifying a subexpression, so the resulting
12148 value is interesting. If it's a valid operand that matches
12149 GIMPLE_TEST_F, we're done. Unless we are handling some
12150 post-effects internally; if that's the case, we need to copy into
12151 a temporary before adding the post-effects to POST_P. */
12152 if (gimple_seq_empty_p (internal_post) && (*gimple_test_f) (*expr_p))
12153 goto out;
12155 /* Otherwise, we need to create a new temporary for the gimplified
12156 expression. */
12158 /* We can't return an lvalue if we have an internal postqueue. The
12159 object the lvalue refers to would (probably) be modified by the
12160 postqueue; we need to copy the value out first, which means an
12161 rvalue. */
12162 if ((fallback & fb_lvalue)
12163 && gimple_seq_empty_p (internal_post)
12164 && is_gimple_addressable (*expr_p))
12166 /* An lvalue will do. Take the address of the expression, store it
12167 in a temporary, and replace the expression with an INDIRECT_REF of
12168 that temporary. */
12169 tmp = build_fold_addr_expr_loc (input_location, *expr_p);
12170 gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue);
12171 *expr_p = build_simple_mem_ref (tmp);
12173 else if ((fallback & fb_rvalue) && is_gimple_reg_rhs_or_call (*expr_p))
12175 /* An rvalue will do. Assign the gimplified expression into a
12176 new temporary TMP and replace the original expression with
12177 TMP. First, make sure that the expression has a type so that
12178 it can be assigned into a temporary. */
12179 gcc_assert (!VOID_TYPE_P (TREE_TYPE (*expr_p)));
12180 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
12182 else
12184 #ifdef ENABLE_GIMPLE_CHECKING
12185 if (!(fallback & fb_mayfail))
12187 fprintf (stderr, "gimplification failed:\n");
12188 print_generic_expr (stderr, *expr_p, 0);
12189 debug_tree (*expr_p);
12190 internal_error ("gimplification failed");
12192 #endif
12193 gcc_assert (fallback & fb_mayfail);
12195 /* If this is an asm statement, and the user asked for the
12196 impossible, don't die. Fail and let gimplify_asm_expr
12197 issue an error. */
12198 ret = GS_ERROR;
12199 goto out;
12202 /* Make sure the temporary matches our predicate. */
12203 gcc_assert ((*gimple_test_f) (*expr_p));
12205 if (!gimple_seq_empty_p (internal_post))
12207 annotate_all_with_location (internal_post, input_location);
12208 gimplify_seq_add_seq (pre_p, internal_post);
12211 out:
12212 input_location = saved_location;
12213 return ret;
12216 /* Like gimplify_expr but make sure the gimplified result is not itself
12217 a SSA name (but a decl if it were). Temporaries required by
12218 evaluating *EXPR_P may be still SSA names. */
12220 static enum gimplify_status
12221 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
12222 bool (*gimple_test_f) (tree), fallback_t fallback,
12223 bool allow_ssa)
12225 bool was_ssa_name_p = TREE_CODE (*expr_p) == SSA_NAME;
12226 enum gimplify_status ret = gimplify_expr (expr_p, pre_p, post_p,
12227 gimple_test_f, fallback);
12228 if (! allow_ssa
12229 && TREE_CODE (*expr_p) == SSA_NAME)
12231 tree name = *expr_p;
12232 if (was_ssa_name_p)
12233 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, NULL, false);
12234 else
12236 /* Avoid the extra copy if possible. */
12237 *expr_p = create_tmp_reg (TREE_TYPE (name));
12238 gimple_set_lhs (SSA_NAME_DEF_STMT (name), *expr_p);
12239 release_ssa_name (name);
12242 return ret;
12245 /* Look through TYPE for variable-sized objects and gimplify each such
12246 size that we find. Add to LIST_P any statements generated. */
12248 void
12249 gimplify_type_sizes (tree type, gimple_seq *list_p)
12251 tree field, t;
12253 if (type == NULL || type == error_mark_node)
12254 return;
12256 /* We first do the main variant, then copy into any other variants. */
12257 type = TYPE_MAIN_VARIANT (type);
12259 /* Avoid infinite recursion. */
12260 if (TYPE_SIZES_GIMPLIFIED (type))
12261 return;
12263 TYPE_SIZES_GIMPLIFIED (type) = 1;
12265 switch (TREE_CODE (type))
12267 case INTEGER_TYPE:
12268 case ENUMERAL_TYPE:
12269 case BOOLEAN_TYPE:
12270 case REAL_TYPE:
12271 case FIXED_POINT_TYPE:
12272 gimplify_one_sizepos (&TYPE_MIN_VALUE (type), list_p);
12273 gimplify_one_sizepos (&TYPE_MAX_VALUE (type), list_p);
12275 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
12277 TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type);
12278 TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type);
12280 break;
12282 case ARRAY_TYPE:
12283 /* These types may not have declarations, so handle them here. */
12284 gimplify_type_sizes (TREE_TYPE (type), list_p);
12285 gimplify_type_sizes (TYPE_DOMAIN (type), list_p);
12286 /* Ensure VLA bounds aren't removed, for -O0 they should be variables
12287 with assigned stack slots, for -O1+ -g they should be tracked
12288 by VTA. */
12289 if (!(TYPE_NAME (type)
12290 && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
12291 && DECL_IGNORED_P (TYPE_NAME (type)))
12292 && TYPE_DOMAIN (type)
12293 && INTEGRAL_TYPE_P (TYPE_DOMAIN (type)))
12295 t = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
12296 if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
12297 DECL_IGNORED_P (t) = 0;
12298 t = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
12299 if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
12300 DECL_IGNORED_P (t) = 0;
12302 break;
12304 case RECORD_TYPE:
12305 case UNION_TYPE:
12306 case QUAL_UNION_TYPE:
12307 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
12308 if (TREE_CODE (field) == FIELD_DECL)
12310 gimplify_one_sizepos (&DECL_FIELD_OFFSET (field), list_p);
12311 gimplify_one_sizepos (&DECL_SIZE (field), list_p);
12312 gimplify_one_sizepos (&DECL_SIZE_UNIT (field), list_p);
12313 gimplify_type_sizes (TREE_TYPE (field), list_p);
12315 break;
12317 case POINTER_TYPE:
12318 case REFERENCE_TYPE:
12319 /* We used to recurse on the pointed-to type here, which turned out to
12320 be incorrect because its definition might refer to variables not
12321 yet initialized at this point if a forward declaration is involved.
12323 It was actually useful for anonymous pointed-to types to ensure
12324 that the sizes evaluation dominates every possible later use of the
12325 values. Restricting to such types here would be safe since there
12326 is no possible forward declaration around, but would introduce an
12327 undesirable middle-end semantic to anonymity. We then defer to
12328 front-ends the responsibility of ensuring that the sizes are
12329 evaluated both early and late enough, e.g. by attaching artificial
12330 type declarations to the tree. */
12331 break;
12333 default:
12334 break;
12337 gimplify_one_sizepos (&TYPE_SIZE (type), list_p);
12338 gimplify_one_sizepos (&TYPE_SIZE_UNIT (type), list_p);
12340 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
12342 TYPE_SIZE (t) = TYPE_SIZE (type);
12343 TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (type);
12344 TYPE_SIZES_GIMPLIFIED (t) = 1;
12348 /* A subroutine of gimplify_type_sizes to make sure that *EXPR_P,
12349 a size or position, has had all of its SAVE_EXPRs evaluated.
12350 We add any required statements to *STMT_P. */
12352 void
12353 gimplify_one_sizepos (tree *expr_p, gimple_seq *stmt_p)
12355 tree expr = *expr_p;
12357 /* We don't do anything if the value isn't there, is constant, or contains
12358 A PLACEHOLDER_EXPR. We also don't want to do anything if it's already
12359 a VAR_DECL. If it's a VAR_DECL from another function, the gimplifier
12360 will want to replace it with a new variable, but that will cause problems
12361 if this type is from outside the function. It's OK to have that here. */
12362 if (is_gimple_sizepos (expr))
12363 return;
12365 *expr_p = unshare_expr (expr);
12367 /* SSA names in decl/type fields are a bad idea - they'll get reclaimed
12368 if the def vanishes. */
12369 gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue, false);
12372 /* Gimplify the body of statements of FNDECL and return a GIMPLE_BIND node
12373 containing the sequence of corresponding GIMPLE statements. If DO_PARMS
12374 is true, also gimplify the parameters. */
12376 gbind *
12377 gimplify_body (tree fndecl, bool do_parms)
12379 location_t saved_location = input_location;
12380 gimple_seq parm_stmts, seq;
12381 gimple *outer_stmt;
12382 gbind *outer_bind;
12383 struct cgraph_node *cgn;
12385 timevar_push (TV_TREE_GIMPLIFY);
12387 init_tree_ssa (cfun);
12389 /* Initialize for optimize_insn_for_s{ize,peed}_p possibly called during
12390 gimplification. */
12391 default_rtl_profile ();
12393 gcc_assert (gimplify_ctxp == NULL);
12394 push_gimplify_context (true);
12396 if (flag_openacc || flag_openmp)
12398 gcc_assert (gimplify_omp_ctxp == NULL);
12399 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (fndecl)))
12400 gimplify_omp_ctxp = new_omp_context (ORT_TARGET);
12403 /* Unshare most shared trees in the body and in that of any nested functions.
12404 It would seem we don't have to do this for nested functions because
12405 they are supposed to be output and then the outer function gimplified
12406 first, but the g++ front end doesn't always do it that way. */
12407 unshare_body (fndecl);
12408 unvisit_body (fndecl);
12410 cgn = cgraph_node::get (fndecl);
12411 if (cgn && cgn->origin)
12412 nonlocal_vlas = new hash_set<tree>;
12414 /* Make sure input_location isn't set to something weird. */
12415 input_location = DECL_SOURCE_LOCATION (fndecl);
12417 /* Resolve callee-copies. This has to be done before processing
12418 the body so that DECL_VALUE_EXPR gets processed correctly. */
12419 parm_stmts = do_parms ? gimplify_parameters () : NULL;
12421 /* Gimplify the function's body. */
12422 seq = NULL;
12423 gimplify_stmt (&DECL_SAVED_TREE (fndecl), &seq);
12424 outer_stmt = gimple_seq_first_stmt (seq);
12425 if (!outer_stmt)
12427 outer_stmt = gimple_build_nop ();
12428 gimplify_seq_add_stmt (&seq, outer_stmt);
12431 /* The body must contain exactly one statement, a GIMPLE_BIND. If this is
12432 not the case, wrap everything in a GIMPLE_BIND to make it so. */
12433 if (gimple_code (outer_stmt) == GIMPLE_BIND
12434 && gimple_seq_first (seq) == gimple_seq_last (seq))
12435 outer_bind = as_a <gbind *> (outer_stmt);
12436 else
12437 outer_bind = gimple_build_bind (NULL_TREE, seq, NULL);
12439 DECL_SAVED_TREE (fndecl) = NULL_TREE;
12441 /* If we had callee-copies statements, insert them at the beginning
12442 of the function and clear DECL_VALUE_EXPR_P on the parameters. */
12443 if (!gimple_seq_empty_p (parm_stmts))
12445 tree parm;
12447 gimplify_seq_add_seq (&parm_stmts, gimple_bind_body (outer_bind));
12448 gimple_bind_set_body (outer_bind, parm_stmts);
12450 for (parm = DECL_ARGUMENTS (current_function_decl);
12451 parm; parm = DECL_CHAIN (parm))
12452 if (DECL_HAS_VALUE_EXPR_P (parm))
12454 DECL_HAS_VALUE_EXPR_P (parm) = 0;
12455 DECL_IGNORED_P (parm) = 0;
12459 if (nonlocal_vlas)
12461 if (nonlocal_vla_vars)
12463 /* tree-nested.c may later on call declare_vars (..., true);
12464 which relies on BLOCK_VARS chain to be the tail of the
12465 gimple_bind_vars chain. Ensure we don't violate that
12466 assumption. */
12467 if (gimple_bind_block (outer_bind)
12468 == DECL_INITIAL (current_function_decl))
12469 declare_vars (nonlocal_vla_vars, outer_bind, true);
12470 else
12471 BLOCK_VARS (DECL_INITIAL (current_function_decl))
12472 = chainon (BLOCK_VARS (DECL_INITIAL (current_function_decl)),
12473 nonlocal_vla_vars);
12474 nonlocal_vla_vars = NULL_TREE;
12476 delete nonlocal_vlas;
12477 nonlocal_vlas = NULL;
12480 if ((flag_openacc || flag_openmp || flag_openmp_simd)
12481 && gimplify_omp_ctxp)
12483 delete_omp_context (gimplify_omp_ctxp);
12484 gimplify_omp_ctxp = NULL;
12487 pop_gimplify_context (outer_bind);
12488 gcc_assert (gimplify_ctxp == NULL);
12490 if (flag_checking && !seen_error ())
12491 verify_gimple_in_seq (gimple_bind_body (outer_bind));
12493 timevar_pop (TV_TREE_GIMPLIFY);
12494 input_location = saved_location;
12496 return outer_bind;
12499 typedef char *char_p; /* For DEF_VEC_P. */
12501 /* Return whether we should exclude FNDECL from instrumentation. */
12503 static bool
12504 flag_instrument_functions_exclude_p (tree fndecl)
12506 vec<char_p> *v;
12508 v = (vec<char_p> *) flag_instrument_functions_exclude_functions;
12509 if (v && v->length () > 0)
12511 const char *name;
12512 int i;
12513 char *s;
12515 name = lang_hooks.decl_printable_name (fndecl, 0);
12516 FOR_EACH_VEC_ELT (*v, i, s)
12517 if (strstr (name, s) != NULL)
12518 return true;
12521 v = (vec<char_p> *) flag_instrument_functions_exclude_files;
12522 if (v && v->length () > 0)
12524 const char *name;
12525 int i;
12526 char *s;
12528 name = DECL_SOURCE_FILE (fndecl);
12529 FOR_EACH_VEC_ELT (*v, i, s)
12530 if (strstr (name, s) != NULL)
12531 return true;
12534 return false;
12537 /* Entry point to the gimplification pass. FNDECL is the FUNCTION_DECL
12538 node for the function we want to gimplify.
12540 Return the sequence of GIMPLE statements corresponding to the body
12541 of FNDECL. */
12543 void
12544 gimplify_function_tree (tree fndecl)
12546 tree parm, ret;
12547 gimple_seq seq;
12548 gbind *bind;
12550 gcc_assert (!gimple_body (fndecl));
12552 if (DECL_STRUCT_FUNCTION (fndecl))
12553 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
12554 else
12555 push_struct_function (fndecl);
12557 /* Tentatively set PROP_gimple_lva here, and reset it in gimplify_va_arg_expr
12558 if necessary. */
12559 cfun->curr_properties |= PROP_gimple_lva;
12561 for (parm = DECL_ARGUMENTS (fndecl); parm ; parm = DECL_CHAIN (parm))
12563 /* Preliminarily mark non-addressed complex variables as eligible
12564 for promotion to gimple registers. We'll transform their uses
12565 as we find them. */
12566 if ((TREE_CODE (TREE_TYPE (parm)) == COMPLEX_TYPE
12567 || TREE_CODE (TREE_TYPE (parm)) == VECTOR_TYPE)
12568 && !TREE_THIS_VOLATILE (parm)
12569 && !needs_to_live_in_memory (parm))
12570 DECL_GIMPLE_REG_P (parm) = 1;
12573 ret = DECL_RESULT (fndecl);
12574 if ((TREE_CODE (TREE_TYPE (ret)) == COMPLEX_TYPE
12575 || TREE_CODE (TREE_TYPE (ret)) == VECTOR_TYPE)
12576 && !needs_to_live_in_memory (ret))
12577 DECL_GIMPLE_REG_P (ret) = 1;
12579 if (asan_sanitize_use_after_scope () && !asan_no_sanitize_address_p ())
12580 asan_poisoned_variables = new hash_set<tree> ();
12581 bind = gimplify_body (fndecl, true);
12582 if (asan_poisoned_variables)
12584 delete asan_poisoned_variables;
12585 asan_poisoned_variables = NULL;
12588 /* The tree body of the function is no longer needed, replace it
12589 with the new GIMPLE body. */
12590 seq = NULL;
12591 gimple_seq_add_stmt (&seq, bind);
12592 gimple_set_body (fndecl, seq);
12594 /* If we're instrumenting function entry/exit, then prepend the call to
12595 the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to
12596 catch the exit hook. */
12597 /* ??? Add some way to ignore exceptions for this TFE. */
12598 if (flag_instrument_function_entry_exit
12599 && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl)
12600 /* Do not instrument extern inline functions. */
12601 && !(DECL_DECLARED_INLINE_P (fndecl)
12602 && DECL_EXTERNAL (fndecl)
12603 && DECL_DISREGARD_INLINE_LIMITS (fndecl))
12604 && !flag_instrument_functions_exclude_p (fndecl))
12606 tree x;
12607 gbind *new_bind;
12608 gimple *tf;
12609 gimple_seq cleanup = NULL, body = NULL;
12610 tree tmp_var;
12611 gcall *call;
12613 x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
12614 call = gimple_build_call (x, 1, integer_zero_node);
12615 tmp_var = create_tmp_var (ptr_type_node, "return_addr");
12616 gimple_call_set_lhs (call, tmp_var);
12617 gimplify_seq_add_stmt (&cleanup, call);
12618 x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_EXIT);
12619 call = gimple_build_call (x, 2,
12620 build_fold_addr_expr (current_function_decl),
12621 tmp_var);
12622 gimplify_seq_add_stmt (&cleanup, call);
12623 tf = gimple_build_try (seq, cleanup, GIMPLE_TRY_FINALLY);
12625 x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
12626 call = gimple_build_call (x, 1, integer_zero_node);
12627 tmp_var = create_tmp_var (ptr_type_node, "return_addr");
12628 gimple_call_set_lhs (call, tmp_var);
12629 gimplify_seq_add_stmt (&body, call);
12630 x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_ENTER);
12631 call = gimple_build_call (x, 2,
12632 build_fold_addr_expr (current_function_decl),
12633 tmp_var);
12634 gimplify_seq_add_stmt (&body, call);
12635 gimplify_seq_add_stmt (&body, tf);
12636 new_bind = gimple_build_bind (NULL, body, NULL);
12638 /* Replace the current function body with the body
12639 wrapped in the try/finally TF. */
12640 seq = NULL;
12641 gimple_seq_add_stmt (&seq, new_bind);
12642 gimple_set_body (fndecl, seq);
12643 bind = new_bind;
12646 if ((flag_sanitize & SANITIZE_THREAD) != 0
12647 && !lookup_attribute ("no_sanitize_thread", DECL_ATTRIBUTES (fndecl)))
12649 gcall *call = gimple_build_call_internal (IFN_TSAN_FUNC_EXIT, 0);
12650 gimple *tf = gimple_build_try (seq, call, GIMPLE_TRY_FINALLY);
12651 gbind *new_bind = gimple_build_bind (NULL, tf, NULL);
12652 /* Replace the current function body with the body
12653 wrapped in the try/finally TF. */
12654 seq = NULL;
12655 gimple_seq_add_stmt (&seq, new_bind);
12656 gimple_set_body (fndecl, seq);
12659 DECL_SAVED_TREE (fndecl) = NULL_TREE;
12660 cfun->curr_properties |= PROP_gimple_any;
12662 pop_cfun ();
12664 dump_function (TDI_generic, fndecl);
12667 /* Return a dummy expression of type TYPE in order to keep going after an
12668 error. */
12670 static tree
12671 dummy_object (tree type)
12673 tree t = build_int_cst (build_pointer_type (type), 0);
12674 return build2 (MEM_REF, type, t, t);
12677 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
12678 builtin function, but a very special sort of operator. */
12680 enum gimplify_status
12681 gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p,
12682 gimple_seq *post_p ATTRIBUTE_UNUSED)
12684 tree promoted_type, have_va_type;
12685 tree valist = TREE_OPERAND (*expr_p, 0);
12686 tree type = TREE_TYPE (*expr_p);
12687 tree t, tag, aptag;
12688 location_t loc = EXPR_LOCATION (*expr_p);
12690 /* Verify that valist is of the proper type. */
12691 have_va_type = TREE_TYPE (valist);
12692 if (have_va_type == error_mark_node)
12693 return GS_ERROR;
12694 have_va_type = targetm.canonical_va_list_type (have_va_type);
12695 if (have_va_type == NULL_TREE
12696 && POINTER_TYPE_P (TREE_TYPE (valist)))
12697 /* Handle 'Case 1: Not an array type' from c-common.c/build_va_arg. */
12698 have_va_type
12699 = targetm.canonical_va_list_type (TREE_TYPE (TREE_TYPE (valist)));
12700 gcc_assert (have_va_type != NULL_TREE);
12702 /* Generate a diagnostic for requesting data of a type that cannot
12703 be passed through `...' due to type promotion at the call site. */
12704 if ((promoted_type = lang_hooks.types.type_promotes_to (type))
12705 != type)
12707 static bool gave_help;
12708 bool warned;
12709 /* Use the expansion point to handle cases such as passing bool (defined
12710 in a system header) through `...'. */
12711 source_location xloc
12712 = expansion_point_location_if_in_system_header (loc);
12714 /* Unfortunately, this is merely undefined, rather than a constraint
12715 violation, so we cannot make this an error. If this call is never
12716 executed, the program is still strictly conforming. */
12717 warned = warning_at (xloc, 0,
12718 "%qT is promoted to %qT when passed through %<...%>",
12719 type, promoted_type);
12720 if (!gave_help && warned)
12722 gave_help = true;
12723 inform (xloc, "(so you should pass %qT not %qT to %<va_arg%>)",
12724 promoted_type, type);
12727 /* We can, however, treat "undefined" any way we please.
12728 Call abort to encourage the user to fix the program. */
12729 if (warned)
12730 inform (xloc, "if this code is reached, the program will abort");
12731 /* Before the abort, allow the evaluation of the va_list
12732 expression to exit or longjmp. */
12733 gimplify_and_add (valist, pre_p);
12734 t = build_call_expr_loc (loc,
12735 builtin_decl_implicit (BUILT_IN_TRAP), 0);
12736 gimplify_and_add (t, pre_p);
12738 /* This is dead code, but go ahead and finish so that the
12739 mode of the result comes out right. */
12740 *expr_p = dummy_object (type);
12741 return GS_ALL_DONE;
12744 tag = build_int_cst (build_pointer_type (type), 0);
12745 aptag = build_int_cst (TREE_TYPE (valist), 0);
12747 *expr_p = build_call_expr_internal_loc (loc, IFN_VA_ARG, type, 3,
12748 valist, tag, aptag);
12750 /* Clear the tentatively set PROP_gimple_lva, to indicate that IFN_VA_ARG
12751 needs to be expanded. */
12752 cfun->curr_properties &= ~PROP_gimple_lva;
12754 return GS_OK;
12757 /* Build a new GIMPLE_ASSIGN tuple and append it to the end of *SEQ_P.
12759 DST/SRC are the destination and source respectively. You can pass
12760 ungimplified trees in DST or SRC, in which case they will be
12761 converted to a gimple operand if necessary.
12763 This function returns the newly created GIMPLE_ASSIGN tuple. */
12765 gimple *
12766 gimplify_assign (tree dst, tree src, gimple_seq *seq_p)
12768 tree t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
12769 gimplify_and_add (t, seq_p);
12770 ggc_free (t);
12771 return gimple_seq_last_stmt (*seq_p);
12774 inline hashval_t
12775 gimplify_hasher::hash (const elt_t *p)
12777 tree t = p->val;
12778 return iterative_hash_expr (t, 0);
12781 inline bool
12782 gimplify_hasher::equal (const elt_t *p1, const elt_t *p2)
12784 tree t1 = p1->val;
12785 tree t2 = p2->val;
12786 enum tree_code code = TREE_CODE (t1);
12788 if (TREE_CODE (t2) != code
12789 || TREE_TYPE (t1) != TREE_TYPE (t2))
12790 return false;
12792 if (!operand_equal_p (t1, t2, 0))
12793 return false;
12795 /* Only allow them to compare equal if they also hash equal; otherwise
12796 results are nondeterminate, and we fail bootstrap comparison. */
12797 gcc_checking_assert (hash (p1) == hash (p2));
12799 return true;