2016-09-26 François Dumont <fdumont@gcc.gnu.org>
[official-gcc.git] / gcc / gimplify.c
blob66bb8be264b45bab8477233bc7b95f83eeb75a08
1 /* Tree lowering pass. This pass converts the GENERIC functions-as-trees
2 tree representation into the GIMPLE form.
3 Copyright (C) 2002-2016 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-low.h"
55 #include "gimple-low.h"
56 #include "cilk.h"
57 #include "gomp-constants.h"
58 #include "tree-dump.h"
59 #include "gimple-walk.h"
60 #include "langhooks-def.h" /* FIXME: for lhd_set_decl_assembler_name */
61 #include "builtins.h"
63 enum gimplify_omp_var_data
65 GOVD_SEEN = 1,
66 GOVD_EXPLICIT = 2,
67 GOVD_SHARED = 4,
68 GOVD_PRIVATE = 8,
69 GOVD_FIRSTPRIVATE = 16,
70 GOVD_LASTPRIVATE = 32,
71 GOVD_REDUCTION = 64,
72 GOVD_LOCAL = 128,
73 GOVD_MAP = 256,
74 GOVD_DEBUG_PRIVATE = 512,
75 GOVD_PRIVATE_OUTER_REF = 1024,
76 GOVD_LINEAR = 2048,
77 GOVD_ALIGNED = 4096,
79 /* Flag for GOVD_MAP: don't copy back. */
80 GOVD_MAP_TO_ONLY = 8192,
82 /* Flag for GOVD_LINEAR or GOVD_LASTPRIVATE: no outer reference. */
83 GOVD_LINEAR_LASTPRIVATE_NO_OUTER = 16384,
85 GOVD_MAP_0LEN_ARRAY = 32768,
87 /* Flag for GOVD_MAP, if it is always, to or always, tofrom mapping. */
88 GOVD_MAP_ALWAYS_TO = 65536,
90 /* Flag for shared vars that are or might be stored to in the region. */
91 GOVD_WRITTEN = 131072,
93 /* Flag for GOVD_MAP, if it is a forced mapping. */
94 GOVD_MAP_FORCE = 262144,
96 GOVD_DATA_SHARE_CLASS = (GOVD_SHARED | GOVD_PRIVATE | GOVD_FIRSTPRIVATE
97 | GOVD_LASTPRIVATE | GOVD_REDUCTION | GOVD_LINEAR
98 | GOVD_LOCAL)
102 enum omp_region_type
104 ORT_WORKSHARE = 0x00,
105 ORT_SIMD = 0x01,
107 ORT_PARALLEL = 0x02,
108 ORT_COMBINED_PARALLEL = 0x03,
110 ORT_TASK = 0x04,
111 ORT_UNTIED_TASK = 0x05,
113 ORT_TEAMS = 0x08,
114 ORT_COMBINED_TEAMS = 0x09,
116 /* Data region. */
117 ORT_TARGET_DATA = 0x10,
119 /* Data region with offloading. */
120 ORT_TARGET = 0x20,
121 ORT_COMBINED_TARGET = 0x21,
123 /* OpenACC variants. */
124 ORT_ACC = 0x40, /* A generic OpenACC region. */
125 ORT_ACC_DATA = ORT_ACC | ORT_TARGET_DATA, /* Data construct. */
126 ORT_ACC_PARALLEL = ORT_ACC | ORT_TARGET, /* Parallel construct */
127 ORT_ACC_KERNELS = ORT_ACC | ORT_TARGET | 0x80, /* Kernels construct. */
128 ORT_ACC_HOST_DATA = ORT_ACC | ORT_TARGET_DATA | 0x80, /* Host data. */
130 /* Dummy OpenMP region, used to disable expansion of
131 DECL_VALUE_EXPRs in taskloop pre body. */
132 ORT_NONE = 0x100
135 /* Gimplify hashtable helper. */
137 struct gimplify_hasher : free_ptr_hash <elt_t>
139 static inline hashval_t hash (const elt_t *);
140 static inline bool equal (const elt_t *, const elt_t *);
143 struct gimplify_ctx
145 struct gimplify_ctx *prev_context;
147 vec<gbind *> bind_expr_stack;
148 tree temps;
149 gimple_seq conditional_cleanups;
150 tree exit_label;
151 tree return_temp;
153 vec<tree> case_labels;
154 /* The formal temporary table. Should this be persistent? */
155 hash_table<gimplify_hasher> *temp_htab;
157 int conditions;
158 unsigned into_ssa : 1;
159 unsigned allow_rhs_cond_expr : 1;
160 unsigned in_cleanup_point_expr : 1;
161 unsigned keep_stack : 1;
162 unsigned save_stack : 1;
163 unsigned in_switch_expr : 1;
166 struct gimplify_omp_ctx
168 struct gimplify_omp_ctx *outer_context;
169 splay_tree variables;
170 hash_set<tree> *privatized_types;
171 /* Iteration variables in an OMP_FOR. */
172 vec<tree> loop_iter_var;
173 location_t location;
174 enum omp_clause_default_kind default_kind;
175 enum omp_region_type region_type;
176 bool combined_loop;
177 bool distribute;
178 bool target_map_scalars_firstprivate;
179 bool target_map_pointers_as_0len_arrays;
180 bool target_firstprivatize_array_bases;
183 static struct gimplify_ctx *gimplify_ctxp;
184 static struct gimplify_omp_ctx *gimplify_omp_ctxp;
186 /* Forward declaration. */
187 static enum gimplify_status gimplify_compound_expr (tree *, gimple_seq *, bool);
188 static hash_map<tree, tree> *oacc_declare_returns;
189 static enum gimplify_status gimplify_expr (tree *, gimple_seq *, gimple_seq *,
190 bool (*) (tree), fallback_t, bool);
192 /* Shorter alias name for the above function for use in gimplify.c
193 only. */
195 static inline void
196 gimplify_seq_add_stmt (gimple_seq *seq_p, gimple *gs)
198 gimple_seq_add_stmt_without_update (seq_p, gs);
201 /* Append sequence SRC to the end of sequence *DST_P. If *DST_P is
202 NULL, a new sequence is allocated. This function is
203 similar to gimple_seq_add_seq, but does not scan the operands.
204 During gimplification, we need to manipulate statement sequences
205 before the def/use vectors have been constructed. */
207 static void
208 gimplify_seq_add_seq (gimple_seq *dst_p, gimple_seq src)
210 gimple_stmt_iterator si;
212 if (src == NULL)
213 return;
215 si = gsi_last (*dst_p);
216 gsi_insert_seq_after_without_update (&si, src, GSI_NEW_STMT);
220 /* Pointer to a list of allocated gimplify_ctx structs to be used for pushing
221 and popping gimplify contexts. */
223 static struct gimplify_ctx *ctx_pool = NULL;
225 /* Return a gimplify context struct from the pool. */
227 static inline struct gimplify_ctx *
228 ctx_alloc (void)
230 struct gimplify_ctx * c = ctx_pool;
232 if (c)
233 ctx_pool = c->prev_context;
234 else
235 c = XNEW (struct gimplify_ctx);
237 memset (c, '\0', sizeof (*c));
238 return c;
241 /* Put gimplify context C back into the pool. */
243 static inline void
244 ctx_free (struct gimplify_ctx *c)
246 c->prev_context = ctx_pool;
247 ctx_pool = c;
250 /* Free allocated ctx stack memory. */
252 void
253 free_gimplify_stack (void)
255 struct gimplify_ctx *c;
257 while ((c = ctx_pool))
259 ctx_pool = c->prev_context;
260 free (c);
265 /* Set up a context for the gimplifier. */
267 void
268 push_gimplify_context (bool in_ssa, bool rhs_cond_ok)
270 struct gimplify_ctx *c = ctx_alloc ();
272 c->prev_context = gimplify_ctxp;
273 gimplify_ctxp = c;
274 gimplify_ctxp->into_ssa = in_ssa;
275 gimplify_ctxp->allow_rhs_cond_expr = rhs_cond_ok;
278 /* Tear down a context for the gimplifier. If BODY is non-null, then
279 put the temporaries into the outer BIND_EXPR. Otherwise, put them
280 in the local_decls.
282 BODY is not a sequence, but the first tuple in a sequence. */
284 void
285 pop_gimplify_context (gimple *body)
287 struct gimplify_ctx *c = gimplify_ctxp;
289 gcc_assert (c
290 && (!c->bind_expr_stack.exists ()
291 || c->bind_expr_stack.is_empty ()));
292 c->bind_expr_stack.release ();
293 gimplify_ctxp = c->prev_context;
295 if (body)
296 declare_vars (c->temps, body, false);
297 else
298 record_vars (c->temps);
300 delete c->temp_htab;
301 c->temp_htab = NULL;
302 ctx_free (c);
305 /* Push a GIMPLE_BIND tuple onto the stack of bindings. */
307 static void
308 gimple_push_bind_expr (gbind *bind_stmt)
310 gimplify_ctxp->bind_expr_stack.reserve (8);
311 gimplify_ctxp->bind_expr_stack.safe_push (bind_stmt);
314 /* Pop the first element off the stack of bindings. */
316 static void
317 gimple_pop_bind_expr (void)
319 gimplify_ctxp->bind_expr_stack.pop ();
322 /* Return the first element of the stack of bindings. */
324 gbind *
325 gimple_current_bind_expr (void)
327 return gimplify_ctxp->bind_expr_stack.last ();
330 /* Return the stack of bindings created during gimplification. */
332 vec<gbind *>
333 gimple_bind_expr_stack (void)
335 return gimplify_ctxp->bind_expr_stack;
338 /* Return true iff there is a COND_EXPR between us and the innermost
339 CLEANUP_POINT_EXPR. This info is used by gimple_push_cleanup. */
341 static bool
342 gimple_conditional_context (void)
344 return gimplify_ctxp->conditions > 0;
347 /* Note that we've entered a COND_EXPR. */
349 static void
350 gimple_push_condition (void)
352 #ifdef ENABLE_GIMPLE_CHECKING
353 if (gimplify_ctxp->conditions == 0)
354 gcc_assert (gimple_seq_empty_p (gimplify_ctxp->conditional_cleanups));
355 #endif
356 ++(gimplify_ctxp->conditions);
359 /* Note that we've left a COND_EXPR. If we're back at unconditional scope
360 now, add any conditional cleanups we've seen to the prequeue. */
362 static void
363 gimple_pop_condition (gimple_seq *pre_p)
365 int conds = --(gimplify_ctxp->conditions);
367 gcc_assert (conds >= 0);
368 if (conds == 0)
370 gimplify_seq_add_seq (pre_p, gimplify_ctxp->conditional_cleanups);
371 gimplify_ctxp->conditional_cleanups = NULL;
375 /* A stable comparison routine for use with splay trees and DECLs. */
377 static int
378 splay_tree_compare_decl_uid (splay_tree_key xa, splay_tree_key xb)
380 tree a = (tree) xa;
381 tree b = (tree) xb;
383 return DECL_UID (a) - DECL_UID (b);
386 /* Create a new omp construct that deals with variable remapping. */
388 static struct gimplify_omp_ctx *
389 new_omp_context (enum omp_region_type region_type)
391 struct gimplify_omp_ctx *c;
393 c = XCNEW (struct gimplify_omp_ctx);
394 c->outer_context = gimplify_omp_ctxp;
395 c->variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0);
396 c->privatized_types = new hash_set<tree>;
397 c->location = input_location;
398 c->region_type = region_type;
399 if ((region_type & ORT_TASK) == 0)
400 c->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
401 else
402 c->default_kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
404 return c;
407 /* Destroy an omp construct that deals with variable remapping. */
409 static void
410 delete_omp_context (struct gimplify_omp_ctx *c)
412 splay_tree_delete (c->variables);
413 delete c->privatized_types;
414 c->loop_iter_var.release ();
415 XDELETE (c);
418 static void omp_add_variable (struct gimplify_omp_ctx *, tree, unsigned int);
419 static bool omp_notice_variable (struct gimplify_omp_ctx *, tree, bool);
421 /* Both gimplify the statement T and append it to *SEQ_P. This function
422 behaves exactly as gimplify_stmt, but you don't have to pass T as a
423 reference. */
425 void
426 gimplify_and_add (tree t, gimple_seq *seq_p)
428 gimplify_stmt (&t, seq_p);
431 /* Gimplify statement T into sequence *SEQ_P, and return the first
432 tuple in the sequence of generated tuples for this statement.
433 Return NULL if gimplifying T produced no tuples. */
435 static gimple *
436 gimplify_and_return_first (tree t, gimple_seq *seq_p)
438 gimple_stmt_iterator last = gsi_last (*seq_p);
440 gimplify_and_add (t, seq_p);
442 if (!gsi_end_p (last))
444 gsi_next (&last);
445 return gsi_stmt (last);
447 else
448 return gimple_seq_first_stmt (*seq_p);
451 /* Returns true iff T is a valid RHS for an assignment to an un-renamed
452 LHS, or for a call argument. */
454 static bool
455 is_gimple_mem_rhs (tree t)
457 /* If we're dealing with a renamable type, either source or dest must be
458 a renamed variable. */
459 if (is_gimple_reg_type (TREE_TYPE (t)))
460 return is_gimple_val (t);
461 else
462 return is_gimple_val (t) || is_gimple_lvalue (t);
465 /* Return true if T is a CALL_EXPR or an expression that can be
466 assigned to a temporary. Note that this predicate should only be
467 used during gimplification. See the rationale for this in
468 gimplify_modify_expr. */
470 static bool
471 is_gimple_reg_rhs_or_call (tree t)
473 return (get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS
474 || TREE_CODE (t) == CALL_EXPR);
477 /* Return true if T is a valid memory RHS or a CALL_EXPR. Note that
478 this predicate should only be used during gimplification. See the
479 rationale for this in gimplify_modify_expr. */
481 static bool
482 is_gimple_mem_rhs_or_call (tree t)
484 /* If we're dealing with a renamable type, either source or dest must be
485 a renamed variable. */
486 if (is_gimple_reg_type (TREE_TYPE (t)))
487 return is_gimple_val (t);
488 else
489 return (is_gimple_val (t) || is_gimple_lvalue (t)
490 || TREE_CODE (t) == CALL_EXPR);
493 /* Create a temporary with a name derived from VAL. Subroutine of
494 lookup_tmp_var; nobody else should call this function. */
496 static inline tree
497 create_tmp_from_val (tree val)
499 /* Drop all qualifiers and address-space information from the value type. */
500 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (val));
501 tree var = create_tmp_var (type, get_name (val));
502 if (TREE_CODE (TREE_TYPE (var)) == COMPLEX_TYPE
503 || TREE_CODE (TREE_TYPE (var)) == VECTOR_TYPE)
504 DECL_GIMPLE_REG_P (var) = 1;
505 return var;
508 /* Create a temporary to hold the value of VAL. If IS_FORMAL, try to reuse
509 an existing expression temporary. */
511 static tree
512 lookup_tmp_var (tree val, bool is_formal)
514 tree ret;
516 /* If not optimizing, never really reuse a temporary. local-alloc
517 won't allocate any variable that is used in more than one basic
518 block, which means it will go into memory, causing much extra
519 work in reload and final and poorer code generation, outweighing
520 the extra memory allocation here. */
521 if (!optimize || !is_formal || TREE_SIDE_EFFECTS (val))
522 ret = create_tmp_from_val (val);
523 else
525 elt_t elt, *elt_p;
526 elt_t **slot;
528 elt.val = val;
529 if (!gimplify_ctxp->temp_htab)
530 gimplify_ctxp->temp_htab = new hash_table<gimplify_hasher> (1000);
531 slot = gimplify_ctxp->temp_htab->find_slot (&elt, INSERT);
532 if (*slot == NULL)
534 elt_p = XNEW (elt_t);
535 elt_p->val = val;
536 elt_p->temp = ret = create_tmp_from_val (val);
537 *slot = elt_p;
539 else
541 elt_p = *slot;
542 ret = elt_p->temp;
546 return ret;
549 /* Helper for get_formal_tmp_var and get_initialized_tmp_var. */
551 static tree
552 internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
553 bool is_formal, bool allow_ssa)
555 tree t, mod;
557 /* Notice that we explicitly allow VAL to be a CALL_EXPR so that we
558 can create an INIT_EXPR and convert it into a GIMPLE_CALL below. */
559 gimplify_expr (&val, pre_p, post_p, is_gimple_reg_rhs_or_call,
560 fb_rvalue);
562 if (allow_ssa
563 && gimplify_ctxp->into_ssa
564 && is_gimple_reg_type (TREE_TYPE (val)))
566 t = make_ssa_name (TYPE_MAIN_VARIANT (TREE_TYPE (val)));
567 if (! gimple_in_ssa_p (cfun))
569 const char *name = get_name (val);
570 if (name)
571 SET_SSA_NAME_VAR_OR_IDENTIFIER (t, create_tmp_var_name (name));
574 else
575 t = lookup_tmp_var (val, is_formal);
577 mod = build2 (INIT_EXPR, TREE_TYPE (t), t, unshare_expr (val));
579 SET_EXPR_LOCATION (mod, EXPR_LOC_OR_LOC (val, input_location));
581 /* gimplify_modify_expr might want to reduce this further. */
582 gimplify_and_add (mod, pre_p);
583 ggc_free (mod);
585 return t;
588 /* Return a formal temporary variable initialized with VAL. PRE_P is as
589 in gimplify_expr. Only use this function if:
591 1) The value of the unfactored expression represented by VAL will not
592 change between the initialization and use of the temporary, and
593 2) The temporary will not be otherwise modified.
595 For instance, #1 means that this is inappropriate for SAVE_EXPR temps,
596 and #2 means it is inappropriate for && temps.
598 For other cases, use get_initialized_tmp_var instead. */
600 tree
601 get_formal_tmp_var (tree val, gimple_seq *pre_p)
603 return internal_get_tmp_var (val, pre_p, NULL, true, true);
606 /* Return a temporary variable initialized with VAL. PRE_P and POST_P
607 are as in gimplify_expr. */
609 tree
610 get_initialized_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
611 bool allow_ssa)
613 return internal_get_tmp_var (val, pre_p, post_p, false, allow_ssa);
616 /* Declare all the variables in VARS in SCOPE. If DEBUG_INFO is true,
617 generate debug info for them; otherwise don't. */
619 void
620 declare_vars (tree vars, gimple *gs, bool debug_info)
622 tree last = vars;
623 if (last)
625 tree temps, block;
627 gbind *scope = as_a <gbind *> (gs);
629 temps = nreverse (last);
631 block = gimple_bind_block (scope);
632 gcc_assert (!block || TREE_CODE (block) == BLOCK);
633 if (!block || !debug_info)
635 DECL_CHAIN (last) = gimple_bind_vars (scope);
636 gimple_bind_set_vars (scope, temps);
638 else
640 /* We need to attach the nodes both to the BIND_EXPR and to its
641 associated BLOCK for debugging purposes. The key point here
642 is that the BLOCK_VARS of the BIND_EXPR_BLOCK of a BIND_EXPR
643 is a subchain of the BIND_EXPR_VARS of the BIND_EXPR. */
644 if (BLOCK_VARS (block))
645 BLOCK_VARS (block) = chainon (BLOCK_VARS (block), temps);
646 else
648 gimple_bind_set_vars (scope,
649 chainon (gimple_bind_vars (scope), temps));
650 BLOCK_VARS (block) = temps;
656 /* For VAR a VAR_DECL of variable size, try to find a constant upper bound
657 for the size and adjust DECL_SIZE/DECL_SIZE_UNIT accordingly. Abort if
658 no such upper bound can be obtained. */
660 static void
661 force_constant_size (tree var)
663 /* The only attempt we make is by querying the maximum size of objects
664 of the variable's type. */
666 HOST_WIDE_INT max_size;
668 gcc_assert (TREE_CODE (var) == VAR_DECL);
670 max_size = max_int_size_in_bytes (TREE_TYPE (var));
672 gcc_assert (max_size >= 0);
674 DECL_SIZE_UNIT (var)
675 = build_int_cst (TREE_TYPE (DECL_SIZE_UNIT (var)), max_size);
676 DECL_SIZE (var)
677 = build_int_cst (TREE_TYPE (DECL_SIZE (var)), max_size * BITS_PER_UNIT);
680 /* Push the temporary variable TMP into the current binding. */
682 void
683 gimple_add_tmp_var_fn (struct function *fn, tree tmp)
685 gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
687 /* Later processing assumes that the object size is constant, which might
688 not be true at this point. Force the use of a constant upper bound in
689 this case. */
690 if (!tree_fits_uhwi_p (DECL_SIZE_UNIT (tmp)))
691 force_constant_size (tmp);
693 DECL_CONTEXT (tmp) = fn->decl;
694 DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
696 record_vars_into (tmp, fn->decl);
699 /* Push the temporary variable TMP into the current binding. */
701 void
702 gimple_add_tmp_var (tree tmp)
704 gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
706 /* Later processing assumes that the object size is constant, which might
707 not be true at this point. Force the use of a constant upper bound in
708 this case. */
709 if (!tree_fits_uhwi_p (DECL_SIZE_UNIT (tmp)))
710 force_constant_size (tmp);
712 DECL_CONTEXT (tmp) = current_function_decl;
713 DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
715 if (gimplify_ctxp)
717 DECL_CHAIN (tmp) = gimplify_ctxp->temps;
718 gimplify_ctxp->temps = tmp;
720 /* Mark temporaries local within the nearest enclosing parallel. */
721 if (gimplify_omp_ctxp)
723 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
724 while (ctx
725 && (ctx->region_type == ORT_WORKSHARE
726 || ctx->region_type == ORT_SIMD
727 || ctx->region_type == ORT_ACC))
728 ctx = ctx->outer_context;
729 if (ctx)
730 omp_add_variable (ctx, tmp, GOVD_LOCAL | GOVD_SEEN);
733 else if (cfun)
734 record_vars (tmp);
735 else
737 gimple_seq body_seq;
739 /* This case is for nested functions. We need to expose the locals
740 they create. */
741 body_seq = gimple_body (current_function_decl);
742 declare_vars (tmp, gimple_seq_first_stmt (body_seq), false);
748 /* This page contains routines to unshare tree nodes, i.e. to duplicate tree
749 nodes that are referenced more than once in GENERIC functions. This is
750 necessary because gimplification (translation into GIMPLE) is performed
751 by modifying tree nodes in-place, so gimplication of a shared node in a
752 first context could generate an invalid GIMPLE form in a second context.
754 This is achieved with a simple mark/copy/unmark algorithm that walks the
755 GENERIC representation top-down, marks nodes with TREE_VISITED the first
756 time it encounters them, duplicates them if they already have TREE_VISITED
757 set, and finally removes the TREE_VISITED marks it has set.
759 The algorithm works only at the function level, i.e. it generates a GENERIC
760 representation of a function with no nodes shared within the function when
761 passed a GENERIC function (except for nodes that are allowed to be shared).
763 At the global level, it is also necessary to unshare tree nodes that are
764 referenced in more than one function, for the same aforementioned reason.
765 This requires some cooperation from the front-end. There are 2 strategies:
767 1. Manual unsharing. The front-end needs to call unshare_expr on every
768 expression that might end up being shared across functions.
770 2. Deep unsharing. This is an extension of regular unsharing. Instead
771 of calling unshare_expr on expressions that might be shared across
772 functions, the front-end pre-marks them with TREE_VISITED. This will
773 ensure that they are unshared on the first reference within functions
774 when the regular unsharing algorithm runs. The counterpart is that
775 this algorithm must look deeper than for manual unsharing, which is
776 specified by LANG_HOOKS_DEEP_UNSHARING.
778 If there are only few specific cases of node sharing across functions, it is
779 probably easier for a front-end to unshare the expressions manually. On the
780 contrary, if the expressions generated at the global level are as widespread
781 as expressions generated within functions, deep unsharing is very likely the
782 way to go. */
784 /* Similar to copy_tree_r but do not copy SAVE_EXPR or TARGET_EXPR nodes.
785 These nodes model computations that must be done once. If we were to
786 unshare something like SAVE_EXPR(i++), the gimplification process would
787 create wrong code. However, if DATA is non-null, it must hold a pointer
788 set that is used to unshare the subtrees of these nodes. */
790 static tree
791 mostly_copy_tree_r (tree *tp, int *walk_subtrees, void *data)
793 tree t = *tp;
794 enum tree_code code = TREE_CODE (t);
796 /* Do not copy SAVE_EXPR, TARGET_EXPR or BIND_EXPR nodes themselves, but
797 copy their subtrees if we can make sure to do it only once. */
798 if (code == SAVE_EXPR || code == TARGET_EXPR || code == BIND_EXPR)
800 if (data && !((hash_set<tree> *)data)->add (t))
802 else
803 *walk_subtrees = 0;
806 /* Stop at types, decls, constants like copy_tree_r. */
807 else if (TREE_CODE_CLASS (code) == tcc_type
808 || TREE_CODE_CLASS (code) == tcc_declaration
809 || TREE_CODE_CLASS (code) == tcc_constant
810 /* We can't do anything sensible with a BLOCK used as an
811 expression, but we also can't just die when we see it
812 because of non-expression uses. So we avert our eyes
813 and cross our fingers. Silly Java. */
814 || code == BLOCK)
815 *walk_subtrees = 0;
817 /* Cope with the statement expression extension. */
818 else if (code == STATEMENT_LIST)
821 /* Leave the bulk of the work to copy_tree_r itself. */
822 else
823 copy_tree_r (tp, walk_subtrees, NULL);
825 return NULL_TREE;
828 /* Callback for walk_tree to unshare most of the shared trees rooted at *TP.
829 If *TP has been visited already, then *TP is deeply copied by calling
830 mostly_copy_tree_r. DATA is passed to mostly_copy_tree_r unmodified. */
832 static tree
833 copy_if_shared_r (tree *tp, int *walk_subtrees, void *data)
835 tree t = *tp;
836 enum tree_code code = TREE_CODE (t);
838 /* Skip types, decls, and constants. But we do want to look at their
839 types and the bounds of types. Mark them as visited so we properly
840 unmark their subtrees on the unmark pass. If we've already seen them,
841 don't look down further. */
842 if (TREE_CODE_CLASS (code) == tcc_type
843 || TREE_CODE_CLASS (code) == tcc_declaration
844 || TREE_CODE_CLASS (code) == tcc_constant)
846 if (TREE_VISITED (t))
847 *walk_subtrees = 0;
848 else
849 TREE_VISITED (t) = 1;
852 /* If this node has been visited already, unshare it and don't look
853 any deeper. */
854 else if (TREE_VISITED (t))
856 walk_tree (tp, mostly_copy_tree_r, data, NULL);
857 *walk_subtrees = 0;
860 /* Otherwise, mark the node as visited and keep looking. */
861 else
862 TREE_VISITED (t) = 1;
864 return NULL_TREE;
867 /* Unshare most of the shared trees rooted at *TP. DATA is passed to the
868 copy_if_shared_r callback unmodified. */
870 static inline void
871 copy_if_shared (tree *tp, void *data)
873 walk_tree (tp, copy_if_shared_r, data, NULL);
876 /* Unshare all the trees in the body of FNDECL, as well as in the bodies of
877 any nested functions. */
879 static void
880 unshare_body (tree fndecl)
882 struct cgraph_node *cgn = cgraph_node::get (fndecl);
883 /* If the language requires deep unsharing, we need a pointer set to make
884 sure we don't repeatedly unshare subtrees of unshareable nodes. */
885 hash_set<tree> *visited
886 = lang_hooks.deep_unsharing ? new hash_set<tree> : NULL;
888 copy_if_shared (&DECL_SAVED_TREE (fndecl), visited);
889 copy_if_shared (&DECL_SIZE (DECL_RESULT (fndecl)), visited);
890 copy_if_shared (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)), visited);
892 delete visited;
894 if (cgn)
895 for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
896 unshare_body (cgn->decl);
899 /* Callback for walk_tree to unmark the visited trees rooted at *TP.
900 Subtrees are walked until the first unvisited node is encountered. */
902 static tree
903 unmark_visited_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
905 tree t = *tp;
907 /* If this node has been visited, unmark it and keep looking. */
908 if (TREE_VISITED (t))
909 TREE_VISITED (t) = 0;
911 /* Otherwise, don't look any deeper. */
912 else
913 *walk_subtrees = 0;
915 return NULL_TREE;
918 /* Unmark the visited trees rooted at *TP. */
920 static inline void
921 unmark_visited (tree *tp)
923 walk_tree (tp, unmark_visited_r, NULL, NULL);
926 /* Likewise, but mark all trees as not visited. */
928 static void
929 unvisit_body (tree fndecl)
931 struct cgraph_node *cgn = cgraph_node::get (fndecl);
933 unmark_visited (&DECL_SAVED_TREE (fndecl));
934 unmark_visited (&DECL_SIZE (DECL_RESULT (fndecl)));
935 unmark_visited (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)));
937 if (cgn)
938 for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
939 unvisit_body (cgn->decl);
942 /* Unconditionally make an unshared copy of EXPR. This is used when using
943 stored expressions which span multiple functions, such as BINFO_VTABLE,
944 as the normal unsharing process can't tell that they're shared. */
946 tree
947 unshare_expr (tree expr)
949 walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
950 return expr;
953 /* Worker for unshare_expr_without_location. */
955 static tree
956 prune_expr_location (tree *tp, int *walk_subtrees, void *)
958 if (EXPR_P (*tp))
959 SET_EXPR_LOCATION (*tp, UNKNOWN_LOCATION);
960 else
961 *walk_subtrees = 0;
962 return NULL_TREE;
965 /* Similar to unshare_expr but also prune all expression locations
966 from EXPR. */
968 tree
969 unshare_expr_without_location (tree expr)
971 walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
972 if (EXPR_P (expr))
973 walk_tree (&expr, prune_expr_location, NULL, NULL);
974 return expr;
977 /* WRAPPER is a code such as BIND_EXPR or CLEANUP_POINT_EXPR which can both
978 contain statements and have a value. Assign its value to a temporary
979 and give it void_type_node. Return the temporary, or NULL_TREE if
980 WRAPPER was already void. */
982 tree
983 voidify_wrapper_expr (tree wrapper, tree temp)
985 tree type = TREE_TYPE (wrapper);
986 if (type && !VOID_TYPE_P (type))
988 tree *p;
990 /* Set p to point to the body of the wrapper. Loop until we find
991 something that isn't a wrapper. */
992 for (p = &wrapper; p && *p; )
994 switch (TREE_CODE (*p))
996 case BIND_EXPR:
997 TREE_SIDE_EFFECTS (*p) = 1;
998 TREE_TYPE (*p) = void_type_node;
999 /* For a BIND_EXPR, the body is operand 1. */
1000 p = &BIND_EXPR_BODY (*p);
1001 break;
1003 case CLEANUP_POINT_EXPR:
1004 case TRY_FINALLY_EXPR:
1005 case TRY_CATCH_EXPR:
1006 TREE_SIDE_EFFECTS (*p) = 1;
1007 TREE_TYPE (*p) = void_type_node;
1008 p = &TREE_OPERAND (*p, 0);
1009 break;
1011 case STATEMENT_LIST:
1013 tree_stmt_iterator i = tsi_last (*p);
1014 TREE_SIDE_EFFECTS (*p) = 1;
1015 TREE_TYPE (*p) = void_type_node;
1016 p = tsi_end_p (i) ? NULL : tsi_stmt_ptr (i);
1018 break;
1020 case COMPOUND_EXPR:
1021 /* Advance to the last statement. Set all container types to
1022 void. */
1023 for (; TREE_CODE (*p) == COMPOUND_EXPR; p = &TREE_OPERAND (*p, 1))
1025 TREE_SIDE_EFFECTS (*p) = 1;
1026 TREE_TYPE (*p) = void_type_node;
1028 break;
1030 case TRANSACTION_EXPR:
1031 TREE_SIDE_EFFECTS (*p) = 1;
1032 TREE_TYPE (*p) = void_type_node;
1033 p = &TRANSACTION_EXPR_BODY (*p);
1034 break;
1036 default:
1037 /* Assume that any tree upon which voidify_wrapper_expr is
1038 directly called is a wrapper, and that its body is op0. */
1039 if (p == &wrapper)
1041 TREE_SIDE_EFFECTS (*p) = 1;
1042 TREE_TYPE (*p) = void_type_node;
1043 p = &TREE_OPERAND (*p, 0);
1044 break;
1046 goto out;
1050 out:
1051 if (p == NULL || IS_EMPTY_STMT (*p))
1052 temp = NULL_TREE;
1053 else if (temp)
1055 /* The wrapper is on the RHS of an assignment that we're pushing
1056 down. */
1057 gcc_assert (TREE_CODE (temp) == INIT_EXPR
1058 || TREE_CODE (temp) == MODIFY_EXPR);
1059 TREE_OPERAND (temp, 1) = *p;
1060 *p = temp;
1062 else
1064 temp = create_tmp_var (type, "retval");
1065 *p = build2 (INIT_EXPR, type, temp, *p);
1068 return temp;
1071 return NULL_TREE;
1074 /* Prepare calls to builtins to SAVE and RESTORE the stack as well as
1075 a temporary through which they communicate. */
1077 static void
1078 build_stack_save_restore (gcall **save, gcall **restore)
1080 tree tmp_var;
1082 *save = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_SAVE), 0);
1083 tmp_var = create_tmp_var (ptr_type_node, "saved_stack");
1084 gimple_call_set_lhs (*save, tmp_var);
1086 *restore
1087 = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_RESTORE),
1088 1, tmp_var);
1091 /* Gimplify a BIND_EXPR. Just voidify and recurse. */
1093 static enum gimplify_status
1094 gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p)
1096 tree bind_expr = *expr_p;
1097 bool old_keep_stack = gimplify_ctxp->keep_stack;
1098 bool old_save_stack = gimplify_ctxp->save_stack;
1099 tree t;
1100 gbind *bind_stmt;
1101 gimple_seq body, cleanup;
1102 gcall *stack_save;
1103 location_t start_locus = 0, end_locus = 0;
1104 tree ret_clauses = NULL;
1106 tree temp = voidify_wrapper_expr (bind_expr, NULL);
1108 /* Mark variables seen in this bind expr. */
1109 for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t))
1111 if (TREE_CODE (t) == VAR_DECL)
1113 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
1115 /* Mark variable as local. */
1116 if (ctx && ctx->region_type != ORT_NONE && !DECL_EXTERNAL (t)
1117 && (! DECL_SEEN_IN_BIND_EXPR_P (t)
1118 || splay_tree_lookup (ctx->variables,
1119 (splay_tree_key) t) == NULL))
1121 if (ctx->region_type == ORT_SIMD
1122 && TREE_ADDRESSABLE (t)
1123 && !TREE_STATIC (t))
1124 omp_add_variable (ctx, t, GOVD_PRIVATE | GOVD_SEEN);
1125 else
1126 omp_add_variable (ctx, t, GOVD_LOCAL | GOVD_SEEN);
1129 DECL_SEEN_IN_BIND_EXPR_P (t) = 1;
1131 if (DECL_HARD_REGISTER (t) && !is_global_var (t) && cfun)
1132 cfun->has_local_explicit_reg_vars = true;
1135 /* Preliminarily mark non-addressed complex variables as eligible
1136 for promotion to gimple registers. We'll transform their uses
1137 as we find them. */
1138 if ((TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE
1139 || TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
1140 && !TREE_THIS_VOLATILE (t)
1141 && (TREE_CODE (t) == VAR_DECL && !DECL_HARD_REGISTER (t))
1142 && !needs_to_live_in_memory (t))
1143 DECL_GIMPLE_REG_P (t) = 1;
1146 bind_stmt = gimple_build_bind (BIND_EXPR_VARS (bind_expr), NULL,
1147 BIND_EXPR_BLOCK (bind_expr));
1148 gimple_push_bind_expr (bind_stmt);
1150 gimplify_ctxp->keep_stack = false;
1151 gimplify_ctxp->save_stack = false;
1153 /* Gimplify the body into the GIMPLE_BIND tuple's body. */
1154 body = NULL;
1155 gimplify_stmt (&BIND_EXPR_BODY (bind_expr), &body);
1156 gimple_bind_set_body (bind_stmt, body);
1158 /* Source location wise, the cleanup code (stack_restore and clobbers)
1159 belongs to the end of the block, so propagate what we have. The
1160 stack_save operation belongs to the beginning of block, which we can
1161 infer from the bind_expr directly if the block has no explicit
1162 assignment. */
1163 if (BIND_EXPR_BLOCK (bind_expr))
1165 end_locus = BLOCK_SOURCE_END_LOCATION (BIND_EXPR_BLOCK (bind_expr));
1166 start_locus = BLOCK_SOURCE_LOCATION (BIND_EXPR_BLOCK (bind_expr));
1168 if (start_locus == 0)
1169 start_locus = EXPR_LOCATION (bind_expr);
1171 cleanup = NULL;
1172 stack_save = NULL;
1174 /* If the code both contains VLAs and calls alloca, then we cannot reclaim
1175 the stack space allocated to the VLAs. */
1176 if (gimplify_ctxp->save_stack && !gimplify_ctxp->keep_stack)
1178 gcall *stack_restore;
1180 /* Save stack on entry and restore it on exit. Add a try_finally
1181 block to achieve this. */
1182 build_stack_save_restore (&stack_save, &stack_restore);
1184 gimple_set_location (stack_save, start_locus);
1185 gimple_set_location (stack_restore, end_locus);
1187 gimplify_seq_add_stmt (&cleanup, stack_restore);
1190 /* Add clobbers for all variables that go out of scope. */
1191 for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t))
1193 if (TREE_CODE (t) == VAR_DECL
1194 && !is_global_var (t)
1195 && DECL_CONTEXT (t) == current_function_decl
1196 && !DECL_HARD_REGISTER (t)
1197 && !TREE_THIS_VOLATILE (t)
1198 && !DECL_HAS_VALUE_EXPR_P (t)
1199 /* Only care for variables that have to be in memory. Others
1200 will be rewritten into SSA names, hence moved to the top-level. */
1201 && !is_gimple_reg (t)
1202 && flag_stack_reuse != SR_NONE)
1204 tree clobber = build_constructor (TREE_TYPE (t), NULL);
1205 gimple *clobber_stmt;
1206 TREE_THIS_VOLATILE (clobber) = 1;
1207 clobber_stmt = gimple_build_assign (t, clobber);
1208 gimple_set_location (clobber_stmt, end_locus);
1209 gimplify_seq_add_stmt (&cleanup, clobber_stmt);
1211 if (flag_openacc && oacc_declare_returns != NULL)
1213 tree *c = oacc_declare_returns->get (t);
1214 if (c != NULL)
1216 if (ret_clauses)
1217 OMP_CLAUSE_CHAIN (*c) = ret_clauses;
1219 ret_clauses = *c;
1221 oacc_declare_returns->remove (t);
1223 if (oacc_declare_returns->elements () == 0)
1225 delete oacc_declare_returns;
1226 oacc_declare_returns = NULL;
1233 if (ret_clauses)
1235 gomp_target *stmt;
1236 gimple_stmt_iterator si = gsi_start (cleanup);
1238 stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
1239 ret_clauses);
1240 gsi_insert_seq_before_without_update (&si, stmt, GSI_NEW_STMT);
1243 if (cleanup)
1245 gtry *gs;
1246 gimple_seq new_body;
1248 new_body = NULL;
1249 gs = gimple_build_try (gimple_bind_body (bind_stmt), cleanup,
1250 GIMPLE_TRY_FINALLY);
1252 if (stack_save)
1253 gimplify_seq_add_stmt (&new_body, stack_save);
1254 gimplify_seq_add_stmt (&new_body, gs);
1255 gimple_bind_set_body (bind_stmt, new_body);
1258 /* keep_stack propagates all the way up to the outermost BIND_EXPR. */
1259 if (!gimplify_ctxp->keep_stack)
1260 gimplify_ctxp->keep_stack = old_keep_stack;
1261 gimplify_ctxp->save_stack = old_save_stack;
1263 gimple_pop_bind_expr ();
1265 gimplify_seq_add_stmt (pre_p, bind_stmt);
1267 if (temp)
1269 *expr_p = temp;
1270 return GS_OK;
1273 *expr_p = NULL_TREE;
1274 return GS_ALL_DONE;
1277 /* Gimplify a RETURN_EXPR. If the expression to be returned is not a
1278 GIMPLE value, it is assigned to a new temporary and the statement is
1279 re-written to return the temporary.
1281 PRE_P points to the sequence where side effects that must happen before
1282 STMT should be stored. */
1284 static enum gimplify_status
1285 gimplify_return_expr (tree stmt, gimple_seq *pre_p)
1287 greturn *ret;
1288 tree ret_expr = TREE_OPERAND (stmt, 0);
1289 tree result_decl, result;
1291 if (ret_expr == error_mark_node)
1292 return GS_ERROR;
1294 /* Implicit _Cilk_sync must be inserted right before any return statement
1295 if there is a _Cilk_spawn in the function. If the user has provided a
1296 _Cilk_sync, the optimizer should remove this duplicate one. */
1297 if (fn_contains_cilk_spawn_p (cfun))
1299 tree impl_sync = build0 (CILK_SYNC_STMT, void_type_node);
1300 gimplify_and_add (impl_sync, pre_p);
1303 if (!ret_expr
1304 || TREE_CODE (ret_expr) == RESULT_DECL
1305 || ret_expr == error_mark_node)
1307 greturn *ret = gimple_build_return (ret_expr);
1308 gimple_set_no_warning (ret, TREE_NO_WARNING (stmt));
1309 gimplify_seq_add_stmt (pre_p, ret);
1310 return GS_ALL_DONE;
1313 if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))))
1314 result_decl = NULL_TREE;
1315 else
1317 result_decl = TREE_OPERAND (ret_expr, 0);
1319 /* See through a return by reference. */
1320 if (TREE_CODE (result_decl) == INDIRECT_REF)
1321 result_decl = TREE_OPERAND (result_decl, 0);
1323 gcc_assert ((TREE_CODE (ret_expr) == MODIFY_EXPR
1324 || TREE_CODE (ret_expr) == INIT_EXPR)
1325 && TREE_CODE (result_decl) == RESULT_DECL);
1328 /* If aggregate_value_p is true, then we can return the bare RESULT_DECL.
1329 Recall that aggregate_value_p is FALSE for any aggregate type that is
1330 returned in registers. If we're returning values in registers, then
1331 we don't want to extend the lifetime of the RESULT_DECL, particularly
1332 across another call. In addition, for those aggregates for which
1333 hard_function_value generates a PARALLEL, we'll die during normal
1334 expansion of structure assignments; there's special code in expand_return
1335 to handle this case that does not exist in expand_expr. */
1336 if (!result_decl)
1337 result = NULL_TREE;
1338 else if (aggregate_value_p (result_decl, TREE_TYPE (current_function_decl)))
1340 if (TREE_CODE (DECL_SIZE (result_decl)) != INTEGER_CST)
1342 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (result_decl)))
1343 gimplify_type_sizes (TREE_TYPE (result_decl), pre_p);
1344 /* Note that we don't use gimplify_vla_decl because the RESULT_DECL
1345 should be effectively allocated by the caller, i.e. all calls to
1346 this function must be subject to the Return Slot Optimization. */
1347 gimplify_one_sizepos (&DECL_SIZE (result_decl), pre_p);
1348 gimplify_one_sizepos (&DECL_SIZE_UNIT (result_decl), pre_p);
1350 result = result_decl;
1352 else if (gimplify_ctxp->return_temp)
1353 result = gimplify_ctxp->return_temp;
1354 else
1356 result = create_tmp_reg (TREE_TYPE (result_decl));
1358 /* ??? With complex control flow (usually involving abnormal edges),
1359 we can wind up warning about an uninitialized value for this. Due
1360 to how this variable is constructed and initialized, this is never
1361 true. Give up and never warn. */
1362 TREE_NO_WARNING (result) = 1;
1364 gimplify_ctxp->return_temp = result;
1367 /* Smash the lhs of the MODIFY_EXPR to the temporary we plan to use.
1368 Then gimplify the whole thing. */
1369 if (result != result_decl)
1370 TREE_OPERAND (ret_expr, 0) = result;
1372 gimplify_and_add (TREE_OPERAND (stmt, 0), pre_p);
1374 ret = gimple_build_return (result);
1375 gimple_set_no_warning (ret, TREE_NO_WARNING (stmt));
1376 gimplify_seq_add_stmt (pre_p, ret);
1378 return GS_ALL_DONE;
1381 /* Gimplify a variable-length array DECL. */
1383 static void
1384 gimplify_vla_decl (tree decl, gimple_seq *seq_p)
1386 /* This is a variable-sized decl. Simplify its size and mark it
1387 for deferred expansion. */
1388 tree t, addr, ptr_type;
1390 gimplify_one_sizepos (&DECL_SIZE (decl), seq_p);
1391 gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), seq_p);
1393 /* Don't mess with a DECL_VALUE_EXPR set by the front-end. */
1394 if (DECL_HAS_VALUE_EXPR_P (decl))
1395 return;
1397 /* All occurrences of this decl in final gimplified code will be
1398 replaced by indirection. Setting DECL_VALUE_EXPR does two
1399 things: First, it lets the rest of the gimplifier know what
1400 replacement to use. Second, it lets the debug info know
1401 where to find the value. */
1402 ptr_type = build_pointer_type (TREE_TYPE (decl));
1403 addr = create_tmp_var (ptr_type, get_name (decl));
1404 DECL_IGNORED_P (addr) = 0;
1405 t = build_fold_indirect_ref (addr);
1406 TREE_THIS_NOTRAP (t) = 1;
1407 SET_DECL_VALUE_EXPR (decl, t);
1408 DECL_HAS_VALUE_EXPR_P (decl) = 1;
1410 t = builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN);
1411 t = build_call_expr (t, 2, DECL_SIZE_UNIT (decl),
1412 size_int (DECL_ALIGN (decl)));
1413 /* The call has been built for a variable-sized object. */
1414 CALL_ALLOCA_FOR_VAR_P (t) = 1;
1415 t = fold_convert (ptr_type, t);
1416 t = build2 (MODIFY_EXPR, TREE_TYPE (addr), addr, t);
1418 gimplify_and_add (t, seq_p);
1421 /* A helper function to be called via walk_tree. Mark all labels under *TP
1422 as being forced. To be called for DECL_INITIAL of static variables. */
1424 static tree
1425 force_labels_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
1427 if (TYPE_P (*tp))
1428 *walk_subtrees = 0;
1429 if (TREE_CODE (*tp) == LABEL_DECL)
1431 FORCED_LABEL (*tp) = 1;
1432 cfun->has_forced_label_in_static = 1;
1435 return NULL_TREE;
1438 /* Gimplify a DECL_EXPR node *STMT_P by making any necessary allocation
1439 and initialization explicit. */
1441 static enum gimplify_status
1442 gimplify_decl_expr (tree *stmt_p, gimple_seq *seq_p)
1444 tree stmt = *stmt_p;
1445 tree decl = DECL_EXPR_DECL (stmt);
1447 *stmt_p = NULL_TREE;
1449 if (TREE_TYPE (decl) == error_mark_node)
1450 return GS_ERROR;
1452 if ((TREE_CODE (decl) == TYPE_DECL
1453 || TREE_CODE (decl) == VAR_DECL)
1454 && !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl)))
1456 gimplify_type_sizes (TREE_TYPE (decl), seq_p);
1457 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
1458 gimplify_type_sizes (TREE_TYPE (TREE_TYPE (decl)), seq_p);
1461 /* ??? DECL_ORIGINAL_TYPE is streamed for LTO so it needs to be gimplified
1462 in case its size expressions contain problematic nodes like CALL_EXPR. */
1463 if (TREE_CODE (decl) == TYPE_DECL
1464 && DECL_ORIGINAL_TYPE (decl)
1465 && !TYPE_SIZES_GIMPLIFIED (DECL_ORIGINAL_TYPE (decl)))
1467 gimplify_type_sizes (DECL_ORIGINAL_TYPE (decl), seq_p);
1468 if (TREE_CODE (DECL_ORIGINAL_TYPE (decl)) == REFERENCE_TYPE)
1469 gimplify_type_sizes (TREE_TYPE (DECL_ORIGINAL_TYPE (decl)), seq_p);
1472 if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
1474 tree init = DECL_INITIAL (decl);
1476 if (TREE_CODE (DECL_SIZE_UNIT (decl)) != INTEGER_CST
1477 || (!TREE_STATIC (decl)
1478 && flag_stack_check == GENERIC_STACK_CHECK
1479 && compare_tree_int (DECL_SIZE_UNIT (decl),
1480 STACK_CHECK_MAX_VAR_SIZE) > 0))
1481 gimplify_vla_decl (decl, seq_p);
1483 /* Some front ends do not explicitly declare all anonymous
1484 artificial variables. We compensate here by declaring the
1485 variables, though it would be better if the front ends would
1486 explicitly declare them. */
1487 if (!DECL_SEEN_IN_BIND_EXPR_P (decl)
1488 && DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
1489 gimple_add_tmp_var (decl);
1491 if (init && init != error_mark_node)
1493 if (!TREE_STATIC (decl))
1495 DECL_INITIAL (decl) = NULL_TREE;
1496 init = build2 (INIT_EXPR, void_type_node, decl, init);
1497 gimplify_and_add (init, seq_p);
1498 ggc_free (init);
1500 else
1501 /* We must still examine initializers for static variables
1502 as they may contain a label address. */
1503 walk_tree (&init, force_labels_r, NULL, NULL);
1507 return GS_ALL_DONE;
1510 /* Gimplify a LOOP_EXPR. Normally this just involves gimplifying the body
1511 and replacing the LOOP_EXPR with goto, but if the loop contains an
1512 EXIT_EXPR, we need to append a label for it to jump to. */
1514 static enum gimplify_status
1515 gimplify_loop_expr (tree *expr_p, gimple_seq *pre_p)
1517 tree saved_label = gimplify_ctxp->exit_label;
1518 tree start_label = create_artificial_label (UNKNOWN_LOCATION);
1520 gimplify_seq_add_stmt (pre_p, gimple_build_label (start_label));
1522 gimplify_ctxp->exit_label = NULL_TREE;
1524 gimplify_and_add (LOOP_EXPR_BODY (*expr_p), pre_p);
1526 gimplify_seq_add_stmt (pre_p, gimple_build_goto (start_label));
1528 if (gimplify_ctxp->exit_label)
1529 gimplify_seq_add_stmt (pre_p,
1530 gimple_build_label (gimplify_ctxp->exit_label));
1532 gimplify_ctxp->exit_label = saved_label;
1534 *expr_p = NULL;
1535 return GS_ALL_DONE;
1538 /* Gimplify a statement list onto a sequence. These may be created either
1539 by an enlightened front-end, or by shortcut_cond_expr. */
1541 static enum gimplify_status
1542 gimplify_statement_list (tree *expr_p, gimple_seq *pre_p)
1544 tree temp = voidify_wrapper_expr (*expr_p, NULL);
1546 tree_stmt_iterator i = tsi_start (*expr_p);
1548 while (!tsi_end_p (i))
1550 gimplify_stmt (tsi_stmt_ptr (i), pre_p);
1551 tsi_delink (&i);
1554 if (temp)
1556 *expr_p = temp;
1557 return GS_OK;
1560 return GS_ALL_DONE;
1563 /* Callback for walk_gimple_seq. */
1565 static tree
1566 warn_switch_unreachable_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
1567 struct walk_stmt_info *wi)
1569 gimple *stmt = gsi_stmt (*gsi_p);
1571 *handled_ops_p = true;
1572 switch (gimple_code (stmt))
1574 case GIMPLE_TRY:
1575 /* A compiler-generated cleanup or a user-written try block.
1576 If it's empty, don't dive into it--that would result in
1577 worse location info. */
1578 if (gimple_try_eval (stmt) == NULL)
1580 wi->info = stmt;
1581 return integer_zero_node;
1583 /* Fall through. */
1584 case GIMPLE_BIND:
1585 case GIMPLE_CATCH:
1586 case GIMPLE_EH_FILTER:
1587 case GIMPLE_TRANSACTION:
1588 /* Walk the sub-statements. */
1589 *handled_ops_p = false;
1590 break;
1591 default:
1592 /* Save the first "real" statement (not a decl/lexical scope/...). */
1593 wi->info = stmt;
1594 return integer_zero_node;
1596 return NULL_TREE;
1599 /* Possibly warn about unreachable statements between switch's controlling
1600 expression and the first case. SEQ is the body of a switch expression. */
1602 static void
1603 maybe_warn_switch_unreachable (gimple_seq seq)
1605 if (!warn_switch_unreachable
1606 /* This warning doesn't play well with Fortran when optimizations
1607 are on. */
1608 || lang_GNU_Fortran ()
1609 || seq == NULL)
1610 return;
1612 struct walk_stmt_info wi;
1613 memset (&wi, 0, sizeof (wi));
1614 walk_gimple_seq (seq, warn_switch_unreachable_r, NULL, &wi);
1615 gimple *stmt = (gimple *) wi.info;
1617 if (stmt && gimple_code (stmt) != GIMPLE_LABEL)
1619 if (gimple_code (stmt) == GIMPLE_GOTO
1620 && TREE_CODE (gimple_goto_dest (stmt)) == LABEL_DECL
1621 && DECL_ARTIFICIAL (gimple_goto_dest (stmt)))
1622 /* Don't warn for compiler-generated gotos. These occur
1623 in Duff's devices, for example. */;
1624 else
1625 warning_at (gimple_location (stmt), OPT_Wswitch_unreachable,
1626 "statement will never be executed");
1631 /* A label entry that pairs label and a location. */
1632 struct label_entry
1634 tree label;
1635 location_t loc;
1638 /* Find LABEL in vector of label entries VEC. */
1640 static struct label_entry *
1641 find_label_entry (const auto_vec<struct label_entry> *vec, tree label)
1643 unsigned int i;
1644 struct label_entry *l;
1646 FOR_EACH_VEC_ELT (*vec, i, l)
1647 if (l->label == label)
1648 return l;
1649 return NULL;
1652 /* Return true if LABEL, a LABEL_DECL, represents a case label
1653 in a vector of labels CASES. */
1655 static bool
1656 case_label_p (const vec<tree> *cases, tree label)
1658 unsigned int i;
1659 tree l;
1661 FOR_EACH_VEC_ELT (*cases, i, l)
1662 if (CASE_LABEL (l) == label)
1663 return true;
1664 return false;
1667 /* Find the last statement in a scope STMT. */
1669 static gimple *
1670 last_stmt_in_scope (gimple *stmt)
1672 if (!stmt)
1673 return NULL;
1675 switch (gimple_code (stmt))
1677 case GIMPLE_BIND:
1679 gbind *bind = as_a <gbind *> (stmt);
1680 stmt = gimple_seq_last_stmt (gimple_bind_body (bind));
1681 return last_stmt_in_scope (stmt);
1684 case GIMPLE_TRY:
1686 gtry *try_stmt = as_a <gtry *> (stmt);
1687 stmt = gimple_seq_last_stmt (gimple_try_eval (try_stmt));
1688 gimple *last_eval = last_stmt_in_scope (stmt);
1689 if (gimple_stmt_may_fallthru (last_eval)
1690 && gimple_try_kind (try_stmt) == GIMPLE_TRY_FINALLY)
1692 stmt = gimple_seq_last_stmt (gimple_try_cleanup (try_stmt));
1693 return last_stmt_in_scope (stmt);
1695 else
1696 return last_eval;
1699 default:
1700 return stmt;
1704 /* Collect interesting labels in LABELS and return the statement preceding
1705 another case label, or a user-defined label. */
1707 static gimple *
1708 collect_fallthrough_labels (gimple_stmt_iterator *gsi_p,
1709 auto_vec <struct label_entry> *labels)
1711 gimple *prev = NULL;
1715 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND
1716 || gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_TRY)
1718 /* Nested scope. Only look at the last statement of
1719 the innermost scope. */
1720 location_t bind_loc = gimple_location (gsi_stmt (*gsi_p));
1721 gimple *last = last_stmt_in_scope (gsi_stmt (*gsi_p));
1722 if (last)
1724 prev = last;
1725 /* It might be a label without a location. Use the
1726 location of the scope then. */
1727 if (!gimple_has_location (prev))
1728 gimple_set_location (prev, bind_loc);
1730 gsi_next (gsi_p);
1731 continue;
1734 /* Ifs are tricky. */
1735 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_COND)
1737 gcond *cond_stmt = as_a <gcond *> (gsi_stmt (*gsi_p));
1738 tree false_lab = gimple_cond_false_label (cond_stmt);
1739 location_t if_loc = gimple_location (cond_stmt);
1741 /* If we have e.g.
1742 if (i > 1) goto <D.2259>; else goto D;
1743 we can't do much with the else-branch. */
1744 if (!DECL_ARTIFICIAL (false_lab))
1745 break;
1747 /* Go on until the false label, then one step back. */
1748 for (; !gsi_end_p (*gsi_p); gsi_next (gsi_p))
1750 gimple *stmt = gsi_stmt (*gsi_p);
1751 if (gimple_code (stmt) == GIMPLE_LABEL
1752 && gimple_label_label (as_a <glabel *> (stmt)) == false_lab)
1753 break;
1756 /* Not found? Oops. */
1757 if (gsi_end_p (*gsi_p))
1758 break;
1760 struct label_entry l = { false_lab, if_loc };
1761 labels->safe_push (l);
1763 /* Go to the last statement of the then branch. */
1764 gsi_prev (gsi_p);
1766 /* if (i != 0) goto <D.1759>; else goto <D.1760>;
1767 <D.1759>:
1768 <stmt>;
1769 goto <D.1761>;
1770 <D.1760>:
1772 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_GOTO
1773 && !gimple_has_location (gsi_stmt (*gsi_p)))
1775 /* Look at the statement before, it might be
1776 attribute fallthrough, in which case don't warn. */
1777 gsi_prev (gsi_p);
1778 bool fallthru_before_dest
1779 = gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_FALLTHROUGH);
1780 gsi_next (gsi_p);
1781 tree goto_dest = gimple_goto_dest (gsi_stmt (*gsi_p));
1782 if (!fallthru_before_dest)
1784 struct label_entry l = { goto_dest, if_loc };
1785 labels->safe_push (l);
1788 /* And move back. */
1789 gsi_next (gsi_p);
1792 /* Remember the last statement. Skip labels that are of no interest
1793 to us. */
1794 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
1796 tree label = gimple_label_label (as_a <glabel *> (gsi_stmt (*gsi_p)));
1797 if (find_label_entry (labels, label))
1798 prev = gsi_stmt (*gsi_p);
1800 else
1801 prev = gsi_stmt (*gsi_p);
1802 gsi_next (gsi_p);
1804 while (!gsi_end_p (*gsi_p)
1805 /* Stop if we find a case or a user-defined label. */
1806 && (gimple_code (gsi_stmt (*gsi_p)) != GIMPLE_LABEL
1807 || !gimple_has_location (gsi_stmt (*gsi_p))));
1809 return prev;
1812 /* Return true if the switch fallthough warning should occur. LABEL is
1813 the label statement that we're falling through to. */
1815 static bool
1816 should_warn_for_implicit_fallthrough (gimple_stmt_iterator *gsi_p, tree label)
1818 gimple_stmt_iterator gsi = *gsi_p;
1820 /* Don't warn for a non-case label followed by a statement:
1821 case 0:
1822 foo ();
1823 label:
1824 bar ();
1825 as these are likely intentional. */
1826 if (!case_label_p (&gimplify_ctxp->case_labels, label))
1828 gsi_next (&gsi);
1829 if (gsi_end_p (gsi) || gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL)
1830 return false;
1833 /* Don't warn for terminated branches, i.e. when the subsequent case labels
1834 immediately breaks. */
1835 gsi = *gsi_p;
1837 /* Skip all immediately following labels. */
1838 while (!gsi_end_p (gsi) && gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL)
1839 gsi_next (&gsi);
1841 /* { ... something; default:; } */
1842 if (gsi_end_p (gsi)
1843 /* { ... something; default: break; } or
1844 { ... something; default: goto L; } */
1845 || gimple_code (gsi_stmt (gsi)) == GIMPLE_GOTO
1846 /* { ... something; default: return; } */
1847 || gimple_code (gsi_stmt (gsi)) == GIMPLE_RETURN)
1848 return false;
1850 return true;
1853 /* Callback for walk_gimple_seq. */
1855 static tree
1856 warn_implicit_fallthrough_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
1857 struct walk_stmt_info *)
1859 gimple *stmt = gsi_stmt (*gsi_p);
1861 *handled_ops_p = true;
1862 switch (gimple_code (stmt))
1864 case GIMPLE_TRY:
1865 case GIMPLE_BIND:
1866 case GIMPLE_CATCH:
1867 case GIMPLE_EH_FILTER:
1868 case GIMPLE_TRANSACTION:
1869 /* Walk the sub-statements. */
1870 *handled_ops_p = false;
1871 break;
1873 /* Find a sequence of form:
1875 GIMPLE_LABEL
1876 [...]
1877 <may fallthru stmt>
1878 GIMPLE_LABEL
1880 and possibly warn. */
1881 case GIMPLE_LABEL:
1883 /* Found a label. Skip all immediately following labels. */
1884 while (!gsi_end_p (*gsi_p)
1885 && gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
1886 gsi_next (gsi_p);
1888 /* There might be no more statements. */
1889 if (gsi_end_p (*gsi_p))
1890 return integer_zero_node;
1892 /* Vector of labels that fall through. */
1893 auto_vec <struct label_entry> labels;
1894 gimple *prev = collect_fallthrough_labels (gsi_p, &labels);
1896 /* There might be no more statements. */
1897 if (gsi_end_p (*gsi_p))
1898 return integer_zero_node;
1900 gimple *next = gsi_stmt (*gsi_p);
1901 tree label;
1902 /* If what follows is a label, then we may have a fallthrough. */
1903 if (gimple_code (next) == GIMPLE_LABEL
1904 && gimple_has_location (next)
1905 && (label = gimple_label_label (as_a <glabel *> (next)))
1906 && !FALLTHROUGH_LABEL_P (label)
1907 && prev != NULL)
1909 struct label_entry *l;
1910 bool warned_p = false;
1911 if (!should_warn_for_implicit_fallthrough (gsi_p, label))
1912 /* Quiet. */;
1913 else if (gimple_code (prev) == GIMPLE_LABEL
1914 && (label = gimple_label_label (as_a <glabel *> (prev)))
1915 && (l = find_label_entry (&labels, label)))
1916 warned_p = warning_at (l->loc, OPT_Wimplicit_fallthrough,
1917 "this statement may fall through");
1918 else if (!gimple_call_internal_p (prev, IFN_FALLTHROUGH)
1919 /* Try to be clever and don't warn when the statement
1920 can't actually fall through. */
1921 && gimple_stmt_may_fallthru (prev)
1922 && gimple_has_location (prev))
1923 warned_p = warning_at (gimple_location (prev),
1924 OPT_Wimplicit_fallthrough,
1925 "this statement may fall through");
1926 if (warned_p)
1927 inform (gimple_location (next), "here");
1929 /* Mark this label as processed so as to prevent multiple
1930 warnings in nested switches. */
1931 FALLTHROUGH_LABEL_P (label) = true;
1933 /* So that next warn_implicit_fallthrough_r will start looking for
1934 a new sequence starting with this label. */
1935 gsi_prev (gsi_p);
1938 break;
1939 default:
1940 break;
1942 return NULL_TREE;
1945 /* Warn when a switch case falls through. */
1947 static void
1948 maybe_warn_implicit_fallthrough (gimple_seq seq)
1950 if (!warn_implicit_fallthrough)
1951 return;
1953 /* This warning is meant for C/C++/ObjC/ObjC++ only. */
1954 if (!(lang_GNU_C ()
1955 || lang_GNU_CXX ()
1956 || lang_GNU_OBJC ()))
1957 return;
1959 struct walk_stmt_info wi;
1960 memset (&wi, 0, sizeof (wi));
1961 walk_gimple_seq (seq, warn_implicit_fallthrough_r, NULL, &wi);
1964 /* Callback for walk_gimple_seq. */
1966 static tree
1967 expand_FALLTHROUGH_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
1968 struct walk_stmt_info *)
1970 gimple *stmt = gsi_stmt (*gsi_p);
1972 *handled_ops_p = true;
1973 switch (gimple_code (stmt))
1975 case GIMPLE_TRY:
1976 case GIMPLE_BIND:
1977 case GIMPLE_CATCH:
1978 case GIMPLE_EH_FILTER:
1979 case GIMPLE_TRANSACTION:
1980 /* Walk the sub-statements. */
1981 *handled_ops_p = false;
1982 break;
1983 case GIMPLE_CALL:
1984 if (gimple_call_internal_p (stmt, IFN_FALLTHROUGH))
1986 gsi_remove (gsi_p, true);
1987 if (gsi_end_p (*gsi_p))
1988 return integer_zero_node;
1990 bool found = false;
1991 location_t loc = gimple_location (stmt);
1993 gimple_stmt_iterator gsi2 = *gsi_p;
1994 stmt = gsi_stmt (gsi2);
1995 if (gimple_code (stmt) == GIMPLE_GOTO && !gimple_has_location (stmt))
1997 /* Go on until the artificial label. */
1998 tree goto_dest = gimple_goto_dest (stmt);
1999 for (; !gsi_end_p (gsi2); gsi_next (&gsi2))
2001 if (gimple_code (gsi_stmt (gsi2)) == GIMPLE_LABEL
2002 && gimple_label_label (as_a <glabel *> (gsi_stmt (gsi2)))
2003 == goto_dest)
2004 break;
2007 /* Not found? Stop. */
2008 if (gsi_end_p (gsi2))
2009 break;
2011 /* Look one past it. */
2012 gsi_next (&gsi2);
2015 /* We're looking for a case label or default label here. */
2016 while (!gsi_end_p (gsi2))
2018 stmt = gsi_stmt (gsi2);
2019 if (gimple_code (stmt) == GIMPLE_LABEL)
2021 tree label = gimple_label_label (as_a <glabel *> (stmt));
2022 if (gimple_has_location (stmt) && DECL_ARTIFICIAL (label))
2024 found = true;
2025 break;
2028 else
2029 /* Something other than a label. That's not expected. */
2030 break;
2031 gsi_next (&gsi2);
2033 if (!found)
2034 warning_at (loc, 0, "attribute %<fallthrough%> not preceding "
2035 "a case label or default label");
2037 break;
2038 default:
2039 break;
2041 return NULL_TREE;
2044 /* Expand all FALLTHROUGH () calls in SEQ. */
2046 static void
2047 expand_FALLTHROUGH (gimple_seq *seq_p)
2049 struct walk_stmt_info wi;
2050 memset (&wi, 0, sizeof (wi));
2051 walk_gimple_seq_mod (seq_p, expand_FALLTHROUGH_r, NULL, &wi);
2055 /* Gimplify a SWITCH_EXPR, and collect the vector of labels it can
2056 branch to. */
2058 static enum gimplify_status
2059 gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p)
2061 tree switch_expr = *expr_p;
2062 gimple_seq switch_body_seq = NULL;
2063 enum gimplify_status ret;
2064 tree index_type = TREE_TYPE (switch_expr);
2065 if (index_type == NULL_TREE)
2066 index_type = TREE_TYPE (SWITCH_COND (switch_expr));
2068 ret = gimplify_expr (&SWITCH_COND (switch_expr), pre_p, NULL, is_gimple_val,
2069 fb_rvalue);
2070 if (ret == GS_ERROR || ret == GS_UNHANDLED)
2071 return ret;
2073 if (SWITCH_BODY (switch_expr))
2075 vec<tree> labels;
2076 vec<tree> saved_labels;
2077 tree default_case = NULL_TREE;
2078 gswitch *switch_stmt;
2080 /* If someone can be bothered to fill in the labels, they can
2081 be bothered to null out the body too. */
2082 gcc_assert (!SWITCH_LABELS (switch_expr));
2084 /* Save old labels, get new ones from body, then restore the old
2085 labels. Save all the things from the switch body to append after. */
2086 saved_labels = gimplify_ctxp->case_labels;
2087 gimplify_ctxp->case_labels.create (8);
2088 bool old_in_switch_expr = gimplify_ctxp->in_switch_expr;
2089 gimplify_ctxp->in_switch_expr = true;
2091 gimplify_stmt (&SWITCH_BODY (switch_expr), &switch_body_seq);
2093 gimplify_ctxp->in_switch_expr = old_in_switch_expr;
2094 maybe_warn_switch_unreachable (switch_body_seq);
2095 maybe_warn_implicit_fallthrough (switch_body_seq);
2096 /* Only do this for the outermost GIMPLE_SWITCH. */
2097 if (!gimplify_ctxp->in_switch_expr)
2098 expand_FALLTHROUGH (&switch_body_seq);
2100 labels = gimplify_ctxp->case_labels;
2101 gimplify_ctxp->case_labels = saved_labels;
2103 preprocess_case_label_vec_for_gimple (labels, index_type,
2104 &default_case);
2106 if (!default_case)
2108 glabel *new_default;
2110 default_case
2111 = build_case_label (NULL_TREE, NULL_TREE,
2112 create_artificial_label (UNKNOWN_LOCATION));
2113 new_default = gimple_build_label (CASE_LABEL (default_case));
2114 gimplify_seq_add_stmt (&switch_body_seq, new_default);
2117 switch_stmt = gimple_build_switch (SWITCH_COND (switch_expr),
2118 default_case, labels);
2119 gimplify_seq_add_stmt (pre_p, switch_stmt);
2120 gimplify_seq_add_seq (pre_p, switch_body_seq);
2121 labels.release ();
2123 else
2124 gcc_assert (SWITCH_LABELS (switch_expr));
2126 return GS_ALL_DONE;
2129 /* Gimplify the LABEL_EXPR pointed to by EXPR_P. */
2131 static enum gimplify_status
2132 gimplify_label_expr (tree *expr_p, gimple_seq *pre_p)
2134 gcc_assert (decl_function_context (LABEL_EXPR_LABEL (*expr_p))
2135 == current_function_decl);
2137 glabel *label_stmt = gimple_build_label (LABEL_EXPR_LABEL (*expr_p));
2138 gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
2139 gimplify_seq_add_stmt (pre_p, label_stmt);
2141 return GS_ALL_DONE;
2144 /* Gimplify the CASE_LABEL_EXPR pointed to by EXPR_P. */
2146 static enum gimplify_status
2147 gimplify_case_label_expr (tree *expr_p, gimple_seq *pre_p)
2149 struct gimplify_ctx *ctxp;
2150 glabel *label_stmt;
2152 /* Invalid programs can play Duff's Device type games with, for example,
2153 #pragma omp parallel. At least in the C front end, we don't
2154 detect such invalid branches until after gimplification, in the
2155 diagnose_omp_blocks pass. */
2156 for (ctxp = gimplify_ctxp; ; ctxp = ctxp->prev_context)
2157 if (ctxp->case_labels.exists ())
2158 break;
2160 label_stmt = gimple_build_label (CASE_LABEL (*expr_p));
2161 gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
2162 ctxp->case_labels.safe_push (*expr_p);
2163 gimplify_seq_add_stmt (pre_p, label_stmt);
2165 return GS_ALL_DONE;
2168 /* Build a GOTO to the LABEL_DECL pointed to by LABEL_P, building it first
2169 if necessary. */
2171 tree
2172 build_and_jump (tree *label_p)
2174 if (label_p == NULL)
2175 /* If there's nowhere to jump, just fall through. */
2176 return NULL_TREE;
2178 if (*label_p == NULL_TREE)
2180 tree label = create_artificial_label (UNKNOWN_LOCATION);
2181 *label_p = label;
2184 return build1 (GOTO_EXPR, void_type_node, *label_p);
2187 /* Gimplify an EXIT_EXPR by converting to a GOTO_EXPR inside a COND_EXPR.
2188 This also involves building a label to jump to and communicating it to
2189 gimplify_loop_expr through gimplify_ctxp->exit_label. */
2191 static enum gimplify_status
2192 gimplify_exit_expr (tree *expr_p)
2194 tree cond = TREE_OPERAND (*expr_p, 0);
2195 tree expr;
2197 expr = build_and_jump (&gimplify_ctxp->exit_label);
2198 expr = build3 (COND_EXPR, void_type_node, cond, expr, NULL_TREE);
2199 *expr_p = expr;
2201 return GS_OK;
2204 /* *EXPR_P is a COMPONENT_REF being used as an rvalue. If its type is
2205 different from its canonical type, wrap the whole thing inside a
2206 NOP_EXPR and force the type of the COMPONENT_REF to be the canonical
2207 type.
2209 The canonical type of a COMPONENT_REF is the type of the field being
2210 referenced--unless the field is a bit-field which can be read directly
2211 in a smaller mode, in which case the canonical type is the
2212 sign-appropriate type corresponding to that mode. */
2214 static void
2215 canonicalize_component_ref (tree *expr_p)
2217 tree expr = *expr_p;
2218 tree type;
2220 gcc_assert (TREE_CODE (expr) == COMPONENT_REF);
2222 if (INTEGRAL_TYPE_P (TREE_TYPE (expr)))
2223 type = TREE_TYPE (get_unwidened (expr, NULL_TREE));
2224 else
2225 type = TREE_TYPE (TREE_OPERAND (expr, 1));
2227 /* One could argue that all the stuff below is not necessary for
2228 the non-bitfield case and declare it a FE error if type
2229 adjustment would be needed. */
2230 if (TREE_TYPE (expr) != type)
2232 #ifdef ENABLE_TYPES_CHECKING
2233 tree old_type = TREE_TYPE (expr);
2234 #endif
2235 int type_quals;
2237 /* We need to preserve qualifiers and propagate them from
2238 operand 0. */
2239 type_quals = TYPE_QUALS (type)
2240 | TYPE_QUALS (TREE_TYPE (TREE_OPERAND (expr, 0)));
2241 if (TYPE_QUALS (type) != type_quals)
2242 type = build_qualified_type (TYPE_MAIN_VARIANT (type), type_quals);
2244 /* Set the type of the COMPONENT_REF to the underlying type. */
2245 TREE_TYPE (expr) = type;
2247 #ifdef ENABLE_TYPES_CHECKING
2248 /* It is now a FE error, if the conversion from the canonical
2249 type to the original expression type is not useless. */
2250 gcc_assert (useless_type_conversion_p (old_type, type));
2251 #endif
2255 /* If a NOP conversion is changing a pointer to array of foo to a pointer
2256 to foo, embed that change in the ADDR_EXPR by converting
2257 T array[U];
2258 (T *)&array
2260 &array[L]
2261 where L is the lower bound. For simplicity, only do this for constant
2262 lower bound.
2263 The constraint is that the type of &array[L] is trivially convertible
2264 to T *. */
2266 static void
2267 canonicalize_addr_expr (tree *expr_p)
2269 tree expr = *expr_p;
2270 tree addr_expr = TREE_OPERAND (expr, 0);
2271 tree datype, ddatype, pddatype;
2273 /* We simplify only conversions from an ADDR_EXPR to a pointer type. */
2274 if (!POINTER_TYPE_P (TREE_TYPE (expr))
2275 || TREE_CODE (addr_expr) != ADDR_EXPR)
2276 return;
2278 /* The addr_expr type should be a pointer to an array. */
2279 datype = TREE_TYPE (TREE_TYPE (addr_expr));
2280 if (TREE_CODE (datype) != ARRAY_TYPE)
2281 return;
2283 /* The pointer to element type shall be trivially convertible to
2284 the expression pointer type. */
2285 ddatype = TREE_TYPE (datype);
2286 pddatype = build_pointer_type (ddatype);
2287 if (!useless_type_conversion_p (TYPE_MAIN_VARIANT (TREE_TYPE (expr)),
2288 pddatype))
2289 return;
2291 /* The lower bound and element sizes must be constant. */
2292 if (!TYPE_SIZE_UNIT (ddatype)
2293 || TREE_CODE (TYPE_SIZE_UNIT (ddatype)) != INTEGER_CST
2294 || !TYPE_DOMAIN (datype) || !TYPE_MIN_VALUE (TYPE_DOMAIN (datype))
2295 || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (datype))) != INTEGER_CST)
2296 return;
2298 /* All checks succeeded. Build a new node to merge the cast. */
2299 *expr_p = build4 (ARRAY_REF, ddatype, TREE_OPERAND (addr_expr, 0),
2300 TYPE_MIN_VALUE (TYPE_DOMAIN (datype)),
2301 NULL_TREE, NULL_TREE);
2302 *expr_p = build1 (ADDR_EXPR, pddatype, *expr_p);
2304 /* We can have stripped a required restrict qualifier above. */
2305 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
2306 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
2309 /* *EXPR_P is a NOP_EXPR or CONVERT_EXPR. Remove it and/or other conversions
2310 underneath as appropriate. */
2312 static enum gimplify_status
2313 gimplify_conversion (tree *expr_p)
2315 location_t loc = EXPR_LOCATION (*expr_p);
2316 gcc_assert (CONVERT_EXPR_P (*expr_p));
2318 /* Then strip away all but the outermost conversion. */
2319 STRIP_SIGN_NOPS (TREE_OPERAND (*expr_p, 0));
2321 /* And remove the outermost conversion if it's useless. */
2322 if (tree_ssa_useless_type_conversion (*expr_p))
2323 *expr_p = TREE_OPERAND (*expr_p, 0);
2325 /* If we still have a conversion at the toplevel,
2326 then canonicalize some constructs. */
2327 if (CONVERT_EXPR_P (*expr_p))
2329 tree sub = TREE_OPERAND (*expr_p, 0);
2331 /* If a NOP conversion is changing the type of a COMPONENT_REF
2332 expression, then canonicalize its type now in order to expose more
2333 redundant conversions. */
2334 if (TREE_CODE (sub) == COMPONENT_REF)
2335 canonicalize_component_ref (&TREE_OPERAND (*expr_p, 0));
2337 /* If a NOP conversion is changing a pointer to array of foo
2338 to a pointer to foo, embed that change in the ADDR_EXPR. */
2339 else if (TREE_CODE (sub) == ADDR_EXPR)
2340 canonicalize_addr_expr (expr_p);
2343 /* If we have a conversion to a non-register type force the
2344 use of a VIEW_CONVERT_EXPR instead. */
2345 if (CONVERT_EXPR_P (*expr_p) && !is_gimple_reg_type (TREE_TYPE (*expr_p)))
2346 *expr_p = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (*expr_p),
2347 TREE_OPERAND (*expr_p, 0));
2349 /* Canonicalize CONVERT_EXPR to NOP_EXPR. */
2350 if (TREE_CODE (*expr_p) == CONVERT_EXPR)
2351 TREE_SET_CODE (*expr_p, NOP_EXPR);
2353 return GS_OK;
2356 /* Nonlocal VLAs seen in the current function. */
2357 static hash_set<tree> *nonlocal_vlas;
2359 /* The VAR_DECLs created for nonlocal VLAs for debug info purposes. */
2360 static tree nonlocal_vla_vars;
2362 /* Gimplify a VAR_DECL or PARM_DECL. Return GS_OK if we expanded a
2363 DECL_VALUE_EXPR, and it's worth re-examining things. */
2365 static enum gimplify_status
2366 gimplify_var_or_parm_decl (tree *expr_p)
2368 tree decl = *expr_p;
2370 /* ??? If this is a local variable, and it has not been seen in any
2371 outer BIND_EXPR, then it's probably the result of a duplicate
2372 declaration, for which we've already issued an error. It would
2373 be really nice if the front end wouldn't leak these at all.
2374 Currently the only known culprit is C++ destructors, as seen
2375 in g++.old-deja/g++.jason/binding.C. */
2376 if (TREE_CODE (decl) == VAR_DECL
2377 && !DECL_SEEN_IN_BIND_EXPR_P (decl)
2378 && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl)
2379 && decl_function_context (decl) == current_function_decl)
2381 gcc_assert (seen_error ());
2382 return GS_ERROR;
2385 /* When within an OMP context, notice uses of variables. */
2386 if (gimplify_omp_ctxp && omp_notice_variable (gimplify_omp_ctxp, decl, true))
2387 return GS_ALL_DONE;
2389 /* If the decl is an alias for another expression, substitute it now. */
2390 if (DECL_HAS_VALUE_EXPR_P (decl))
2392 tree value_expr = DECL_VALUE_EXPR (decl);
2394 /* For referenced nonlocal VLAs add a decl for debugging purposes
2395 to the current function. */
2396 if (TREE_CODE (decl) == VAR_DECL
2397 && TREE_CODE (DECL_SIZE_UNIT (decl)) != INTEGER_CST
2398 && nonlocal_vlas != NULL
2399 && TREE_CODE (value_expr) == INDIRECT_REF
2400 && TREE_CODE (TREE_OPERAND (value_expr, 0)) == VAR_DECL
2401 && decl_function_context (decl) != current_function_decl)
2403 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
2404 while (ctx
2405 && (ctx->region_type == ORT_WORKSHARE
2406 || ctx->region_type == ORT_SIMD
2407 || ctx->region_type == ORT_ACC))
2408 ctx = ctx->outer_context;
2409 if (!ctx && !nonlocal_vlas->add (decl))
2411 tree copy = copy_node (decl);
2413 lang_hooks.dup_lang_specific_decl (copy);
2414 SET_DECL_RTL (copy, 0);
2415 TREE_USED (copy) = 1;
2416 DECL_CHAIN (copy) = nonlocal_vla_vars;
2417 nonlocal_vla_vars = copy;
2418 SET_DECL_VALUE_EXPR (copy, unshare_expr (value_expr));
2419 DECL_HAS_VALUE_EXPR_P (copy) = 1;
2423 *expr_p = unshare_expr (value_expr);
2424 return GS_OK;
2427 return GS_ALL_DONE;
2430 /* Recalculate the value of the TREE_SIDE_EFFECTS flag for T. */
2432 static void
2433 recalculate_side_effects (tree t)
2435 enum tree_code code = TREE_CODE (t);
2436 int len = TREE_OPERAND_LENGTH (t);
2437 int i;
2439 switch (TREE_CODE_CLASS (code))
2441 case tcc_expression:
2442 switch (code)
2444 case INIT_EXPR:
2445 case MODIFY_EXPR:
2446 case VA_ARG_EXPR:
2447 case PREDECREMENT_EXPR:
2448 case PREINCREMENT_EXPR:
2449 case POSTDECREMENT_EXPR:
2450 case POSTINCREMENT_EXPR:
2451 /* All of these have side-effects, no matter what their
2452 operands are. */
2453 return;
2455 default:
2456 break;
2458 /* Fall through. */
2460 case tcc_comparison: /* a comparison expression */
2461 case tcc_unary: /* a unary arithmetic expression */
2462 case tcc_binary: /* a binary arithmetic expression */
2463 case tcc_reference: /* a reference */
2464 case tcc_vl_exp: /* a function call */
2465 TREE_SIDE_EFFECTS (t) = TREE_THIS_VOLATILE (t);
2466 for (i = 0; i < len; ++i)
2468 tree op = TREE_OPERAND (t, i);
2469 if (op && TREE_SIDE_EFFECTS (op))
2470 TREE_SIDE_EFFECTS (t) = 1;
2472 break;
2474 case tcc_constant:
2475 /* No side-effects. */
2476 return;
2478 default:
2479 gcc_unreachable ();
2483 /* Gimplify the COMPONENT_REF, ARRAY_REF, REALPART_EXPR or IMAGPART_EXPR
2484 node *EXPR_P.
2486 compound_lval
2487 : min_lval '[' val ']'
2488 | min_lval '.' ID
2489 | compound_lval '[' val ']'
2490 | compound_lval '.' ID
2492 This is not part of the original SIMPLE definition, which separates
2493 array and member references, but it seems reasonable to handle them
2494 together. Also, this way we don't run into problems with union
2495 aliasing; gcc requires that for accesses through a union to alias, the
2496 union reference must be explicit, which was not always the case when we
2497 were splitting up array and member refs.
2499 PRE_P points to the sequence where side effects that must happen before
2500 *EXPR_P should be stored.
2502 POST_P points to the sequence where side effects that must happen after
2503 *EXPR_P should be stored. */
2505 static enum gimplify_status
2506 gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
2507 fallback_t fallback)
2509 tree *p;
2510 enum gimplify_status ret = GS_ALL_DONE, tret;
2511 int i;
2512 location_t loc = EXPR_LOCATION (*expr_p);
2513 tree expr = *expr_p;
2515 /* Create a stack of the subexpressions so later we can walk them in
2516 order from inner to outer. */
2517 auto_vec<tree, 10> expr_stack;
2519 /* We can handle anything that get_inner_reference can deal with. */
2520 for (p = expr_p; ; p = &TREE_OPERAND (*p, 0))
2522 restart:
2523 /* Fold INDIRECT_REFs now to turn them into ARRAY_REFs. */
2524 if (TREE_CODE (*p) == INDIRECT_REF)
2525 *p = fold_indirect_ref_loc (loc, *p);
2527 if (handled_component_p (*p))
2529 /* Expand DECL_VALUE_EXPR now. In some cases that may expose
2530 additional COMPONENT_REFs. */
2531 else if ((TREE_CODE (*p) == VAR_DECL || TREE_CODE (*p) == PARM_DECL)
2532 && gimplify_var_or_parm_decl (p) == GS_OK)
2533 goto restart;
2534 else
2535 break;
2537 expr_stack.safe_push (*p);
2540 gcc_assert (expr_stack.length ());
2542 /* Now EXPR_STACK is a stack of pointers to all the refs we've
2543 walked through and P points to the innermost expression.
2545 Java requires that we elaborated nodes in source order. That
2546 means we must gimplify the inner expression followed by each of
2547 the indices, in order. But we can't gimplify the inner
2548 expression until we deal with any variable bounds, sizes, or
2549 positions in order to deal with PLACEHOLDER_EXPRs.
2551 So we do this in three steps. First we deal with the annotations
2552 for any variables in the components, then we gimplify the base,
2553 then we gimplify any indices, from left to right. */
2554 for (i = expr_stack.length () - 1; i >= 0; i--)
2556 tree t = expr_stack[i];
2558 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
2560 /* Gimplify the low bound and element type size and put them into
2561 the ARRAY_REF. If these values are set, they have already been
2562 gimplified. */
2563 if (TREE_OPERAND (t, 2) == NULL_TREE)
2565 tree low = unshare_expr (array_ref_low_bound (t));
2566 if (!is_gimple_min_invariant (low))
2568 TREE_OPERAND (t, 2) = low;
2569 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
2570 post_p, is_gimple_reg,
2571 fb_rvalue);
2572 ret = MIN (ret, tret);
2575 else
2577 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
2578 is_gimple_reg, fb_rvalue);
2579 ret = MIN (ret, tret);
2582 if (TREE_OPERAND (t, 3) == NULL_TREE)
2584 tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0)));
2585 tree elmt_size = unshare_expr (array_ref_element_size (t));
2586 tree factor = size_int (TYPE_ALIGN_UNIT (elmt_type));
2588 /* Divide the element size by the alignment of the element
2589 type (above). */
2590 elmt_size
2591 = size_binop_loc (loc, EXACT_DIV_EXPR, elmt_size, factor);
2593 if (!is_gimple_min_invariant (elmt_size))
2595 TREE_OPERAND (t, 3) = elmt_size;
2596 tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p,
2597 post_p, is_gimple_reg,
2598 fb_rvalue);
2599 ret = MIN (ret, tret);
2602 else
2604 tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p, post_p,
2605 is_gimple_reg, fb_rvalue);
2606 ret = MIN (ret, tret);
2609 else if (TREE_CODE (t) == COMPONENT_REF)
2611 /* Set the field offset into T and gimplify it. */
2612 if (TREE_OPERAND (t, 2) == NULL_TREE)
2614 tree offset = unshare_expr (component_ref_field_offset (t));
2615 tree field = TREE_OPERAND (t, 1);
2616 tree factor
2617 = size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT);
2619 /* Divide the offset by its alignment. */
2620 offset = size_binop_loc (loc, EXACT_DIV_EXPR, offset, factor);
2622 if (!is_gimple_min_invariant (offset))
2624 TREE_OPERAND (t, 2) = offset;
2625 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
2626 post_p, is_gimple_reg,
2627 fb_rvalue);
2628 ret = MIN (ret, tret);
2631 else
2633 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
2634 is_gimple_reg, fb_rvalue);
2635 ret = MIN (ret, tret);
2640 /* Step 2 is to gimplify the base expression. Make sure lvalue is set
2641 so as to match the min_lval predicate. Failure to do so may result
2642 in the creation of large aggregate temporaries. */
2643 tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval,
2644 fallback | fb_lvalue);
2645 ret = MIN (ret, tret);
2647 /* And finally, the indices and operands of ARRAY_REF. During this
2648 loop we also remove any useless conversions. */
2649 for (; expr_stack.length () > 0; )
2651 tree t = expr_stack.pop ();
2653 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
2655 /* Gimplify the dimension. */
2656 if (!is_gimple_min_invariant (TREE_OPERAND (t, 1)))
2658 tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
2659 is_gimple_val, fb_rvalue);
2660 ret = MIN (ret, tret);
2664 STRIP_USELESS_TYPE_CONVERSION (TREE_OPERAND (t, 0));
2666 /* The innermost expression P may have originally had
2667 TREE_SIDE_EFFECTS set which would have caused all the outer
2668 expressions in *EXPR_P leading to P to also have had
2669 TREE_SIDE_EFFECTS set. */
2670 recalculate_side_effects (t);
2673 /* If the outermost expression is a COMPONENT_REF, canonicalize its type. */
2674 if ((fallback & fb_rvalue) && TREE_CODE (*expr_p) == COMPONENT_REF)
2676 canonicalize_component_ref (expr_p);
2679 expr_stack.release ();
2681 gcc_assert (*expr_p == expr || ret != GS_ALL_DONE);
2683 return ret;
2686 /* Gimplify the self modifying expression pointed to by EXPR_P
2687 (++, --, +=, -=).
2689 PRE_P points to the list where side effects that must happen before
2690 *EXPR_P should be stored.
2692 POST_P points to the list where side effects that must happen after
2693 *EXPR_P should be stored.
2695 WANT_VALUE is nonzero iff we want to use the value of this expression
2696 in another expression.
2698 ARITH_TYPE is the type the computation should be performed in. */
2700 enum gimplify_status
2701 gimplify_self_mod_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
2702 bool want_value, tree arith_type)
2704 enum tree_code code;
2705 tree lhs, lvalue, rhs, t1;
2706 gimple_seq post = NULL, *orig_post_p = post_p;
2707 bool postfix;
2708 enum tree_code arith_code;
2709 enum gimplify_status ret;
2710 location_t loc = EXPR_LOCATION (*expr_p);
2712 code = TREE_CODE (*expr_p);
2714 gcc_assert (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR
2715 || code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR);
2717 /* Prefix or postfix? */
2718 if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
2719 /* Faster to treat as prefix if result is not used. */
2720 postfix = want_value;
2721 else
2722 postfix = false;
2724 /* For postfix, make sure the inner expression's post side effects
2725 are executed after side effects from this expression. */
2726 if (postfix)
2727 post_p = &post;
2729 /* Add or subtract? */
2730 if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
2731 arith_code = PLUS_EXPR;
2732 else
2733 arith_code = MINUS_EXPR;
2735 /* Gimplify the LHS into a GIMPLE lvalue. */
2736 lvalue = TREE_OPERAND (*expr_p, 0);
2737 ret = gimplify_expr (&lvalue, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
2738 if (ret == GS_ERROR)
2739 return ret;
2741 /* Extract the operands to the arithmetic operation. */
2742 lhs = lvalue;
2743 rhs = TREE_OPERAND (*expr_p, 1);
2745 /* For postfix operator, we evaluate the LHS to an rvalue and then use
2746 that as the result value and in the postqueue operation. */
2747 if (postfix)
2749 ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue);
2750 if (ret == GS_ERROR)
2751 return ret;
2753 lhs = get_initialized_tmp_var (lhs, pre_p, NULL);
2756 /* For POINTERs increment, use POINTER_PLUS_EXPR. */
2757 if (POINTER_TYPE_P (TREE_TYPE (lhs)))
2759 rhs = convert_to_ptrofftype_loc (loc, rhs);
2760 if (arith_code == MINUS_EXPR)
2761 rhs = fold_build1_loc (loc, NEGATE_EXPR, TREE_TYPE (rhs), rhs);
2762 t1 = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (*expr_p), lhs, rhs);
2764 else
2765 t1 = fold_convert (TREE_TYPE (*expr_p),
2766 fold_build2 (arith_code, arith_type,
2767 fold_convert (arith_type, lhs),
2768 fold_convert (arith_type, rhs)));
2770 if (postfix)
2772 gimplify_assign (lvalue, t1, pre_p);
2773 gimplify_seq_add_seq (orig_post_p, post);
2774 *expr_p = lhs;
2775 return GS_ALL_DONE;
2777 else
2779 *expr_p = build2 (MODIFY_EXPR, TREE_TYPE (lvalue), lvalue, t1);
2780 return GS_OK;
2784 /* If *EXPR_P has a variable sized type, wrap it in a WITH_SIZE_EXPR. */
2786 static void
2787 maybe_with_size_expr (tree *expr_p)
2789 tree expr = *expr_p;
2790 tree type = TREE_TYPE (expr);
2791 tree size;
2793 /* If we've already wrapped this or the type is error_mark_node, we can't do
2794 anything. */
2795 if (TREE_CODE (expr) == WITH_SIZE_EXPR
2796 || type == error_mark_node)
2797 return;
2799 /* If the size isn't known or is a constant, we have nothing to do. */
2800 size = TYPE_SIZE_UNIT (type);
2801 if (!size || TREE_CODE (size) == INTEGER_CST)
2802 return;
2804 /* Otherwise, make a WITH_SIZE_EXPR. */
2805 size = unshare_expr (size);
2806 size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, expr);
2807 *expr_p = build2 (WITH_SIZE_EXPR, type, expr, size);
2810 /* Helper for gimplify_call_expr. Gimplify a single argument *ARG_P
2811 Store any side-effects in PRE_P. CALL_LOCATION is the location of
2812 the CALL_EXPR. If ALLOW_SSA is set the actual parameter may be
2813 gimplified to an SSA name. */
2815 enum gimplify_status
2816 gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location,
2817 bool allow_ssa)
2819 bool (*test) (tree);
2820 fallback_t fb;
2822 /* In general, we allow lvalues for function arguments to avoid
2823 extra overhead of copying large aggregates out of even larger
2824 aggregates into temporaries only to copy the temporaries to
2825 the argument list. Make optimizers happy by pulling out to
2826 temporaries those types that fit in registers. */
2827 if (is_gimple_reg_type (TREE_TYPE (*arg_p)))
2828 test = is_gimple_val, fb = fb_rvalue;
2829 else
2831 test = is_gimple_lvalue, fb = fb_either;
2832 /* Also strip a TARGET_EXPR that would force an extra copy. */
2833 if (TREE_CODE (*arg_p) == TARGET_EXPR)
2835 tree init = TARGET_EXPR_INITIAL (*arg_p);
2836 if (init
2837 && !VOID_TYPE_P (TREE_TYPE (init)))
2838 *arg_p = init;
2842 /* If this is a variable sized type, we must remember the size. */
2843 maybe_with_size_expr (arg_p);
2845 /* FIXME diagnostics: This will mess up gcc.dg/Warray-bounds.c. */
2846 /* Make sure arguments have the same location as the function call
2847 itself. */
2848 protected_set_expr_location (*arg_p, call_location);
2850 /* There is a sequence point before a function call. Side effects in
2851 the argument list must occur before the actual call. So, when
2852 gimplifying arguments, force gimplify_expr to use an internal
2853 post queue which is then appended to the end of PRE_P. */
2854 return gimplify_expr (arg_p, pre_p, NULL, test, fb, allow_ssa);
2857 /* Don't fold inside offloading or taskreg regions: it can break code by
2858 adding decl references that weren't in the source. We'll do it during
2859 omplower pass instead. */
2861 static bool
2862 maybe_fold_stmt (gimple_stmt_iterator *gsi)
2864 struct gimplify_omp_ctx *ctx;
2865 for (ctx = gimplify_omp_ctxp; ctx; ctx = ctx->outer_context)
2866 if ((ctx->region_type & (ORT_TARGET | ORT_PARALLEL | ORT_TASK)) != 0)
2867 return false;
2868 return fold_stmt (gsi);
2871 /* Gimplify the CALL_EXPR node *EXPR_P into the GIMPLE sequence PRE_P.
2872 WANT_VALUE is true if the result of the call is desired. */
2874 static enum gimplify_status
2875 gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
2877 tree fndecl, parms, p, fnptrtype;
2878 enum gimplify_status ret;
2879 int i, nargs;
2880 gcall *call;
2881 bool builtin_va_start_p = false;
2882 location_t loc = EXPR_LOCATION (*expr_p);
2884 gcc_assert (TREE_CODE (*expr_p) == CALL_EXPR);
2886 /* For reliable diagnostics during inlining, it is necessary that
2887 every call_expr be annotated with file and line. */
2888 if (! EXPR_HAS_LOCATION (*expr_p))
2889 SET_EXPR_LOCATION (*expr_p, input_location);
2891 /* Gimplify internal functions created in the FEs. */
2892 if (CALL_EXPR_FN (*expr_p) == NULL_TREE)
2894 if (want_value)
2895 return GS_ALL_DONE;
2897 nargs = call_expr_nargs (*expr_p);
2898 enum internal_fn ifn = CALL_EXPR_IFN (*expr_p);
2899 auto_vec<tree> vargs (nargs);
2901 for (i = 0; i < nargs; i++)
2903 gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
2904 EXPR_LOCATION (*expr_p));
2905 vargs.quick_push (CALL_EXPR_ARG (*expr_p, i));
2907 gimple *call = gimple_build_call_internal_vec (ifn, vargs);
2908 gimplify_seq_add_stmt (pre_p, call);
2909 return GS_ALL_DONE;
2912 /* This may be a call to a builtin function.
2914 Builtin function calls may be transformed into different
2915 (and more efficient) builtin function calls under certain
2916 circumstances. Unfortunately, gimplification can muck things
2917 up enough that the builtin expanders are not aware that certain
2918 transformations are still valid.
2920 So we attempt transformation/gimplification of the call before
2921 we gimplify the CALL_EXPR. At this time we do not manage to
2922 transform all calls in the same manner as the expanders do, but
2923 we do transform most of them. */
2924 fndecl = get_callee_fndecl (*expr_p);
2925 if (fndecl
2926 && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
2927 switch (DECL_FUNCTION_CODE (fndecl))
2929 case BUILT_IN_ALLOCA:
2930 case BUILT_IN_ALLOCA_WITH_ALIGN:
2931 /* If the call has been built for a variable-sized object, then we
2932 want to restore the stack level when the enclosing BIND_EXPR is
2933 exited to reclaim the allocated space; otherwise, we precisely
2934 need to do the opposite and preserve the latest stack level. */
2935 if (CALL_ALLOCA_FOR_VAR_P (*expr_p))
2936 gimplify_ctxp->save_stack = true;
2937 else
2938 gimplify_ctxp->keep_stack = true;
2939 break;
2941 case BUILT_IN_VA_START:
2943 builtin_va_start_p = TRUE;
2944 if (call_expr_nargs (*expr_p) < 2)
2946 error ("too few arguments to function %<va_start%>");
2947 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
2948 return GS_OK;
2951 if (fold_builtin_next_arg (*expr_p, true))
2953 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
2954 return GS_OK;
2956 break;
2959 default:
2962 if (fndecl && DECL_BUILT_IN (fndecl))
2964 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
2965 if (new_tree && new_tree != *expr_p)
2967 /* There was a transformation of this call which computes the
2968 same value, but in a more efficient way. Return and try
2969 again. */
2970 *expr_p = new_tree;
2971 return GS_OK;
2975 /* Remember the original function pointer type. */
2976 fnptrtype = TREE_TYPE (CALL_EXPR_FN (*expr_p));
2978 /* There is a sequence point before the call, so any side effects in
2979 the calling expression must occur before the actual call. Force
2980 gimplify_expr to use an internal post queue. */
2981 ret = gimplify_expr (&CALL_EXPR_FN (*expr_p), pre_p, NULL,
2982 is_gimple_call_addr, fb_rvalue);
2984 nargs = call_expr_nargs (*expr_p);
2986 /* Get argument types for verification. */
2987 fndecl = get_callee_fndecl (*expr_p);
2988 parms = NULL_TREE;
2989 if (fndecl)
2990 parms = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
2991 else
2992 parms = TYPE_ARG_TYPES (TREE_TYPE (fnptrtype));
2994 if (fndecl && DECL_ARGUMENTS (fndecl))
2995 p = DECL_ARGUMENTS (fndecl);
2996 else if (parms)
2997 p = parms;
2998 else
2999 p = NULL_TREE;
3000 for (i = 0; i < nargs && p; i++, p = TREE_CHAIN (p))
3003 /* If the last argument is __builtin_va_arg_pack () and it is not
3004 passed as a named argument, decrease the number of CALL_EXPR
3005 arguments and set instead the CALL_EXPR_VA_ARG_PACK flag. */
3006 if (!p
3007 && i < nargs
3008 && TREE_CODE (CALL_EXPR_ARG (*expr_p, nargs - 1)) == CALL_EXPR)
3010 tree last_arg = CALL_EXPR_ARG (*expr_p, nargs - 1);
3011 tree last_arg_fndecl = get_callee_fndecl (last_arg);
3013 if (last_arg_fndecl
3014 && TREE_CODE (last_arg_fndecl) == FUNCTION_DECL
3015 && DECL_BUILT_IN_CLASS (last_arg_fndecl) == BUILT_IN_NORMAL
3016 && DECL_FUNCTION_CODE (last_arg_fndecl) == BUILT_IN_VA_ARG_PACK)
3018 tree call = *expr_p;
3020 --nargs;
3021 *expr_p = build_call_array_loc (loc, TREE_TYPE (call),
3022 CALL_EXPR_FN (call),
3023 nargs, CALL_EXPR_ARGP (call));
3025 /* Copy all CALL_EXPR flags, location and block, except
3026 CALL_EXPR_VA_ARG_PACK flag. */
3027 CALL_EXPR_STATIC_CHAIN (*expr_p) = CALL_EXPR_STATIC_CHAIN (call);
3028 CALL_EXPR_TAILCALL (*expr_p) = CALL_EXPR_TAILCALL (call);
3029 CALL_EXPR_RETURN_SLOT_OPT (*expr_p)
3030 = CALL_EXPR_RETURN_SLOT_OPT (call);
3031 CALL_FROM_THUNK_P (*expr_p) = CALL_FROM_THUNK_P (call);
3032 SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (call));
3034 /* Set CALL_EXPR_VA_ARG_PACK. */
3035 CALL_EXPR_VA_ARG_PACK (*expr_p) = 1;
3039 /* If the call returns twice then after building the CFG the call
3040 argument computations will no longer dominate the call because
3041 we add an abnormal incoming edge to the call. So do not use SSA
3042 vars there. */
3043 bool returns_twice = call_expr_flags (*expr_p) & ECF_RETURNS_TWICE;
3045 /* Gimplify the function arguments. */
3046 if (nargs > 0)
3048 for (i = (PUSH_ARGS_REVERSED ? nargs - 1 : 0);
3049 PUSH_ARGS_REVERSED ? i >= 0 : i < nargs;
3050 PUSH_ARGS_REVERSED ? i-- : i++)
3052 enum gimplify_status t;
3054 /* Avoid gimplifying the second argument to va_start, which needs to
3055 be the plain PARM_DECL. */
3056 if ((i != 1) || !builtin_va_start_p)
3058 t = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
3059 EXPR_LOCATION (*expr_p), ! returns_twice);
3061 if (t == GS_ERROR)
3062 ret = GS_ERROR;
3067 /* Gimplify the static chain. */
3068 if (CALL_EXPR_STATIC_CHAIN (*expr_p))
3070 if (fndecl && !DECL_STATIC_CHAIN (fndecl))
3071 CALL_EXPR_STATIC_CHAIN (*expr_p) = NULL;
3072 else
3074 enum gimplify_status t;
3075 t = gimplify_arg (&CALL_EXPR_STATIC_CHAIN (*expr_p), pre_p,
3076 EXPR_LOCATION (*expr_p), ! returns_twice);
3077 if (t == GS_ERROR)
3078 ret = GS_ERROR;
3082 /* Verify the function result. */
3083 if (want_value && fndecl
3084 && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fnptrtype))))
3086 error_at (loc, "using result of function returning %<void%>");
3087 ret = GS_ERROR;
3090 /* Try this again in case gimplification exposed something. */
3091 if (ret != GS_ERROR)
3093 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
3095 if (new_tree && new_tree != *expr_p)
3097 /* There was a transformation of this call which computes the
3098 same value, but in a more efficient way. Return and try
3099 again. */
3100 *expr_p = new_tree;
3101 return GS_OK;
3104 else
3106 *expr_p = error_mark_node;
3107 return GS_ERROR;
3110 /* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its
3111 decl. This allows us to eliminate redundant or useless
3112 calls to "const" functions. */
3113 if (TREE_CODE (*expr_p) == CALL_EXPR)
3115 int flags = call_expr_flags (*expr_p);
3116 if (flags & (ECF_CONST | ECF_PURE)
3117 /* An infinite loop is considered a side effect. */
3118 && !(flags & (ECF_LOOPING_CONST_OR_PURE)))
3119 TREE_SIDE_EFFECTS (*expr_p) = 0;
3122 /* If the value is not needed by the caller, emit a new GIMPLE_CALL
3123 and clear *EXPR_P. Otherwise, leave *EXPR_P in its gimplified
3124 form and delegate the creation of a GIMPLE_CALL to
3125 gimplify_modify_expr. This is always possible because when
3126 WANT_VALUE is true, the caller wants the result of this call into
3127 a temporary, which means that we will emit an INIT_EXPR in
3128 internal_get_tmp_var which will then be handled by
3129 gimplify_modify_expr. */
3130 if (!want_value)
3132 /* The CALL_EXPR in *EXPR_P is already in GIMPLE form, so all we
3133 have to do is replicate it as a GIMPLE_CALL tuple. */
3134 gimple_stmt_iterator gsi;
3135 call = gimple_build_call_from_tree (*expr_p);
3136 gimple_call_set_fntype (call, TREE_TYPE (fnptrtype));
3137 notice_special_calls (call);
3138 gimplify_seq_add_stmt (pre_p, call);
3139 gsi = gsi_last (*pre_p);
3140 maybe_fold_stmt (&gsi);
3141 *expr_p = NULL_TREE;
3143 else
3144 /* Remember the original function type. */
3145 CALL_EXPR_FN (*expr_p) = build1 (NOP_EXPR, fnptrtype,
3146 CALL_EXPR_FN (*expr_p));
3148 return ret;
3151 /* Handle shortcut semantics in the predicate operand of a COND_EXPR by
3152 rewriting it into multiple COND_EXPRs, and possibly GOTO_EXPRs.
3154 TRUE_LABEL_P and FALSE_LABEL_P point to the labels to jump to if the
3155 condition is true or false, respectively. If null, we should generate
3156 our own to skip over the evaluation of this specific expression.
3158 LOCUS is the source location of the COND_EXPR.
3160 This function is the tree equivalent of do_jump.
3162 shortcut_cond_r should only be called by shortcut_cond_expr. */
3164 static tree
3165 shortcut_cond_r (tree pred, tree *true_label_p, tree *false_label_p,
3166 location_t locus)
3168 tree local_label = NULL_TREE;
3169 tree t, expr = NULL;
3171 /* OK, it's not a simple case; we need to pull apart the COND_EXPR to
3172 retain the shortcut semantics. Just insert the gotos here;
3173 shortcut_cond_expr will append the real blocks later. */
3174 if (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
3176 location_t new_locus;
3178 /* Turn if (a && b) into
3180 if (a); else goto no;
3181 if (b) goto yes; else goto no;
3182 (no:) */
3184 if (false_label_p == NULL)
3185 false_label_p = &local_label;
3187 /* Keep the original source location on the first 'if'. */
3188 t = shortcut_cond_r (TREE_OPERAND (pred, 0), NULL, false_label_p, locus);
3189 append_to_statement_list (t, &expr);
3191 /* Set the source location of the && on the second 'if'. */
3192 new_locus = EXPR_HAS_LOCATION (pred) ? EXPR_LOCATION (pred) : locus;
3193 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
3194 new_locus);
3195 append_to_statement_list (t, &expr);
3197 else if (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
3199 location_t new_locus;
3201 /* Turn if (a || b) into
3203 if (a) goto yes;
3204 if (b) goto yes; else goto no;
3205 (yes:) */
3207 if (true_label_p == NULL)
3208 true_label_p = &local_label;
3210 /* Keep the original source location on the first 'if'. */
3211 t = shortcut_cond_r (TREE_OPERAND (pred, 0), true_label_p, NULL, locus);
3212 append_to_statement_list (t, &expr);
3214 /* Set the source location of the || on the second 'if'. */
3215 new_locus = EXPR_HAS_LOCATION (pred) ? EXPR_LOCATION (pred) : locus;
3216 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
3217 new_locus);
3218 append_to_statement_list (t, &expr);
3220 else if (TREE_CODE (pred) == COND_EXPR
3221 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 1)))
3222 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 2))))
3224 location_t new_locus;
3226 /* As long as we're messing with gotos, turn if (a ? b : c) into
3227 if (a)
3228 if (b) goto yes; else goto no;
3229 else
3230 if (c) goto yes; else goto no;
3232 Don't do this if one of the arms has void type, which can happen
3233 in C++ when the arm is throw. */
3235 /* Keep the original source location on the first 'if'. Set the source
3236 location of the ? on the second 'if'. */
3237 new_locus = EXPR_HAS_LOCATION (pred) ? EXPR_LOCATION (pred) : locus;
3238 expr = build3 (COND_EXPR, void_type_node, TREE_OPERAND (pred, 0),
3239 shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p,
3240 false_label_p, locus),
3241 shortcut_cond_r (TREE_OPERAND (pred, 2), true_label_p,
3242 false_label_p, new_locus));
3244 else
3246 expr = build3 (COND_EXPR, void_type_node, pred,
3247 build_and_jump (true_label_p),
3248 build_and_jump (false_label_p));
3249 SET_EXPR_LOCATION (expr, locus);
3252 if (local_label)
3254 t = build1 (LABEL_EXPR, void_type_node, local_label);
3255 append_to_statement_list (t, &expr);
3258 return expr;
3261 /* Given a conditional expression EXPR with short-circuit boolean
3262 predicates using TRUTH_ANDIF_EXPR or TRUTH_ORIF_EXPR, break the
3263 predicate apart into the equivalent sequence of conditionals. */
3265 static tree
3266 shortcut_cond_expr (tree expr)
3268 tree pred = TREE_OPERAND (expr, 0);
3269 tree then_ = TREE_OPERAND (expr, 1);
3270 tree else_ = TREE_OPERAND (expr, 2);
3271 tree true_label, false_label, end_label, t;
3272 tree *true_label_p;
3273 tree *false_label_p;
3274 bool emit_end, emit_false, jump_over_else;
3275 bool then_se = then_ && TREE_SIDE_EFFECTS (then_);
3276 bool else_se = else_ && TREE_SIDE_EFFECTS (else_);
3278 /* First do simple transformations. */
3279 if (!else_se)
3281 /* If there is no 'else', turn
3282 if (a && b) then c
3283 into
3284 if (a) if (b) then c. */
3285 while (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
3287 /* Keep the original source location on the first 'if'. */
3288 location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
3289 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
3290 /* Set the source location of the && on the second 'if'. */
3291 if (EXPR_HAS_LOCATION (pred))
3292 SET_EXPR_LOCATION (expr, EXPR_LOCATION (pred));
3293 then_ = shortcut_cond_expr (expr);
3294 then_se = then_ && TREE_SIDE_EFFECTS (then_);
3295 pred = TREE_OPERAND (pred, 0);
3296 expr = build3 (COND_EXPR, void_type_node, pred, then_, NULL_TREE);
3297 SET_EXPR_LOCATION (expr, locus);
3301 if (!then_se)
3303 /* If there is no 'then', turn
3304 if (a || b); else d
3305 into
3306 if (a); else if (b); else d. */
3307 while (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
3309 /* Keep the original source location on the first 'if'. */
3310 location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
3311 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
3312 /* Set the source location of the || on the second 'if'. */
3313 if (EXPR_HAS_LOCATION (pred))
3314 SET_EXPR_LOCATION (expr, EXPR_LOCATION (pred));
3315 else_ = shortcut_cond_expr (expr);
3316 else_se = else_ && TREE_SIDE_EFFECTS (else_);
3317 pred = TREE_OPERAND (pred, 0);
3318 expr = build3 (COND_EXPR, void_type_node, pred, NULL_TREE, else_);
3319 SET_EXPR_LOCATION (expr, locus);
3323 /* If we're done, great. */
3324 if (TREE_CODE (pred) != TRUTH_ANDIF_EXPR
3325 && TREE_CODE (pred) != TRUTH_ORIF_EXPR)
3326 return expr;
3328 /* Otherwise we need to mess with gotos. Change
3329 if (a) c; else d;
3331 if (a); else goto no;
3332 c; goto end;
3333 no: d; end:
3334 and recursively gimplify the condition. */
3336 true_label = false_label = end_label = NULL_TREE;
3338 /* If our arms just jump somewhere, hijack those labels so we don't
3339 generate jumps to jumps. */
3341 if (then_
3342 && TREE_CODE (then_) == GOTO_EXPR
3343 && TREE_CODE (GOTO_DESTINATION (then_)) == LABEL_DECL)
3345 true_label = GOTO_DESTINATION (then_);
3346 then_ = NULL;
3347 then_se = false;
3350 if (else_
3351 && TREE_CODE (else_) == GOTO_EXPR
3352 && TREE_CODE (GOTO_DESTINATION (else_)) == LABEL_DECL)
3354 false_label = GOTO_DESTINATION (else_);
3355 else_ = NULL;
3356 else_se = false;
3359 /* If we aren't hijacking a label for the 'then' branch, it falls through. */
3360 if (true_label)
3361 true_label_p = &true_label;
3362 else
3363 true_label_p = NULL;
3365 /* The 'else' branch also needs a label if it contains interesting code. */
3366 if (false_label || else_se)
3367 false_label_p = &false_label;
3368 else
3369 false_label_p = NULL;
3371 /* If there was nothing else in our arms, just forward the label(s). */
3372 if (!then_se && !else_se)
3373 return shortcut_cond_r (pred, true_label_p, false_label_p,
3374 EXPR_LOC_OR_LOC (expr, input_location));
3376 /* If our last subexpression already has a terminal label, reuse it. */
3377 if (else_se)
3378 t = expr_last (else_);
3379 else if (then_se)
3380 t = expr_last (then_);
3381 else
3382 t = NULL;
3383 if (t && TREE_CODE (t) == LABEL_EXPR)
3384 end_label = LABEL_EXPR_LABEL (t);
3386 /* If we don't care about jumping to the 'else' branch, jump to the end
3387 if the condition is false. */
3388 if (!false_label_p)
3389 false_label_p = &end_label;
3391 /* We only want to emit these labels if we aren't hijacking them. */
3392 emit_end = (end_label == NULL_TREE);
3393 emit_false = (false_label == NULL_TREE);
3395 /* We only emit the jump over the else clause if we have to--if the
3396 then clause may fall through. Otherwise we can wind up with a
3397 useless jump and a useless label at the end of gimplified code,
3398 which will cause us to think that this conditional as a whole
3399 falls through even if it doesn't. If we then inline a function
3400 which ends with such a condition, that can cause us to issue an
3401 inappropriate warning about control reaching the end of a
3402 non-void function. */
3403 jump_over_else = block_may_fallthru (then_);
3405 pred = shortcut_cond_r (pred, true_label_p, false_label_p,
3406 EXPR_LOC_OR_LOC (expr, input_location));
3408 expr = NULL;
3409 append_to_statement_list (pred, &expr);
3411 append_to_statement_list (then_, &expr);
3412 if (else_se)
3414 if (jump_over_else)
3416 tree last = expr_last (expr);
3417 t = build_and_jump (&end_label);
3418 if (EXPR_HAS_LOCATION (last))
3419 SET_EXPR_LOCATION (t, EXPR_LOCATION (last));
3420 append_to_statement_list (t, &expr);
3422 if (emit_false)
3424 t = build1 (LABEL_EXPR, void_type_node, false_label);
3425 append_to_statement_list (t, &expr);
3427 append_to_statement_list (else_, &expr);
3429 if (emit_end && end_label)
3431 t = build1 (LABEL_EXPR, void_type_node, end_label);
3432 append_to_statement_list (t, &expr);
3435 return expr;
3438 /* EXPR is used in a boolean context; make sure it has BOOLEAN_TYPE. */
3440 tree
3441 gimple_boolify (tree expr)
3443 tree type = TREE_TYPE (expr);
3444 location_t loc = EXPR_LOCATION (expr);
3446 if (TREE_CODE (expr) == NE_EXPR
3447 && TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR
3448 && integer_zerop (TREE_OPERAND (expr, 1)))
3450 tree call = TREE_OPERAND (expr, 0);
3451 tree fn = get_callee_fndecl (call);
3453 /* For __builtin_expect ((long) (x), y) recurse into x as well
3454 if x is truth_value_p. */
3455 if (fn
3456 && DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL
3457 && DECL_FUNCTION_CODE (fn) == BUILT_IN_EXPECT
3458 && call_expr_nargs (call) == 2)
3460 tree arg = CALL_EXPR_ARG (call, 0);
3461 if (arg)
3463 if (TREE_CODE (arg) == NOP_EXPR
3464 && TREE_TYPE (arg) == TREE_TYPE (call))
3465 arg = TREE_OPERAND (arg, 0);
3466 if (truth_value_p (TREE_CODE (arg)))
3468 arg = gimple_boolify (arg);
3469 CALL_EXPR_ARG (call, 0)
3470 = fold_convert_loc (loc, TREE_TYPE (call), arg);
3476 switch (TREE_CODE (expr))
3478 case TRUTH_AND_EXPR:
3479 case TRUTH_OR_EXPR:
3480 case TRUTH_XOR_EXPR:
3481 case TRUTH_ANDIF_EXPR:
3482 case TRUTH_ORIF_EXPR:
3483 /* Also boolify the arguments of truth exprs. */
3484 TREE_OPERAND (expr, 1) = gimple_boolify (TREE_OPERAND (expr, 1));
3485 /* FALLTHRU */
3487 case TRUTH_NOT_EXPR:
3488 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
3490 /* These expressions always produce boolean results. */
3491 if (TREE_CODE (type) != BOOLEAN_TYPE)
3492 TREE_TYPE (expr) = boolean_type_node;
3493 return expr;
3495 case ANNOTATE_EXPR:
3496 switch ((enum annot_expr_kind) TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)))
3498 case annot_expr_ivdep_kind:
3499 case annot_expr_no_vector_kind:
3500 case annot_expr_vector_kind:
3501 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
3502 if (TREE_CODE (type) != BOOLEAN_TYPE)
3503 TREE_TYPE (expr) = boolean_type_node;
3504 return expr;
3505 default:
3506 gcc_unreachable ();
3509 default:
3510 if (COMPARISON_CLASS_P (expr))
3512 /* There expressions always prduce boolean results. */
3513 if (TREE_CODE (type) != BOOLEAN_TYPE)
3514 TREE_TYPE (expr) = boolean_type_node;
3515 return expr;
3517 /* Other expressions that get here must have boolean values, but
3518 might need to be converted to the appropriate mode. */
3519 if (TREE_CODE (type) == BOOLEAN_TYPE)
3520 return expr;
3521 return fold_convert_loc (loc, boolean_type_node, expr);
3525 /* Given a conditional expression *EXPR_P without side effects, gimplify
3526 its operands. New statements are inserted to PRE_P. */
3528 static enum gimplify_status
3529 gimplify_pure_cond_expr (tree *expr_p, gimple_seq *pre_p)
3531 tree expr = *expr_p, cond;
3532 enum gimplify_status ret, tret;
3533 enum tree_code code;
3535 cond = gimple_boolify (COND_EXPR_COND (expr));
3537 /* We need to handle && and || specially, as their gimplification
3538 creates pure cond_expr, thus leading to an infinite cycle otherwise. */
3539 code = TREE_CODE (cond);
3540 if (code == TRUTH_ANDIF_EXPR)
3541 TREE_SET_CODE (cond, TRUTH_AND_EXPR);
3542 else if (code == TRUTH_ORIF_EXPR)
3543 TREE_SET_CODE (cond, TRUTH_OR_EXPR);
3544 ret = gimplify_expr (&cond, pre_p, NULL, is_gimple_condexpr, fb_rvalue);
3545 COND_EXPR_COND (*expr_p) = cond;
3547 tret = gimplify_expr (&COND_EXPR_THEN (expr), pre_p, NULL,
3548 is_gimple_val, fb_rvalue);
3549 ret = MIN (ret, tret);
3550 tret = gimplify_expr (&COND_EXPR_ELSE (expr), pre_p, NULL,
3551 is_gimple_val, fb_rvalue);
3553 return MIN (ret, tret);
3556 /* Return true if evaluating EXPR could trap.
3557 EXPR is GENERIC, while tree_could_trap_p can be called
3558 only on GIMPLE. */
3560 static bool
3561 generic_expr_could_trap_p (tree expr)
3563 unsigned i, n;
3565 if (!expr || is_gimple_val (expr))
3566 return false;
3568 if (!EXPR_P (expr) || tree_could_trap_p (expr))
3569 return true;
3571 n = TREE_OPERAND_LENGTH (expr);
3572 for (i = 0; i < n; i++)
3573 if (generic_expr_could_trap_p (TREE_OPERAND (expr, i)))
3574 return true;
3576 return false;
3579 /* Convert the conditional expression pointed to by EXPR_P '(p) ? a : b;'
3580 into
3582 if (p) if (p)
3583 t1 = a; a;
3584 else or else
3585 t1 = b; b;
3588 The second form is used when *EXPR_P is of type void.
3590 PRE_P points to the list where side effects that must happen before
3591 *EXPR_P should be stored. */
3593 static enum gimplify_status
3594 gimplify_cond_expr (tree *expr_p, gimple_seq *pre_p, fallback_t fallback)
3596 tree expr = *expr_p;
3597 tree type = TREE_TYPE (expr);
3598 location_t loc = EXPR_LOCATION (expr);
3599 tree tmp, arm1, arm2;
3600 enum gimplify_status ret;
3601 tree label_true, label_false, label_cont;
3602 bool have_then_clause_p, have_else_clause_p;
3603 gcond *cond_stmt;
3604 enum tree_code pred_code;
3605 gimple_seq seq = NULL;
3607 /* If this COND_EXPR has a value, copy the values into a temporary within
3608 the arms. */
3609 if (!VOID_TYPE_P (type))
3611 tree then_ = TREE_OPERAND (expr, 1), else_ = TREE_OPERAND (expr, 2);
3612 tree result;
3614 /* If either an rvalue is ok or we do not require an lvalue, create the
3615 temporary. But we cannot do that if the type is addressable. */
3616 if (((fallback & fb_rvalue) || !(fallback & fb_lvalue))
3617 && !TREE_ADDRESSABLE (type))
3619 if (gimplify_ctxp->allow_rhs_cond_expr
3620 /* If either branch has side effects or could trap, it can't be
3621 evaluated unconditionally. */
3622 && !TREE_SIDE_EFFECTS (then_)
3623 && !generic_expr_could_trap_p (then_)
3624 && !TREE_SIDE_EFFECTS (else_)
3625 && !generic_expr_could_trap_p (else_))
3626 return gimplify_pure_cond_expr (expr_p, pre_p);
3628 tmp = create_tmp_var (type, "iftmp");
3629 result = tmp;
3632 /* Otherwise, only create and copy references to the values. */
3633 else
3635 type = build_pointer_type (type);
3637 if (!VOID_TYPE_P (TREE_TYPE (then_)))
3638 then_ = build_fold_addr_expr_loc (loc, then_);
3640 if (!VOID_TYPE_P (TREE_TYPE (else_)))
3641 else_ = build_fold_addr_expr_loc (loc, else_);
3643 expr
3644 = build3 (COND_EXPR, type, TREE_OPERAND (expr, 0), then_, else_);
3646 tmp = create_tmp_var (type, "iftmp");
3647 result = build_simple_mem_ref_loc (loc, tmp);
3650 /* Build the new then clause, `tmp = then_;'. But don't build the
3651 assignment if the value is void; in C++ it can be if it's a throw. */
3652 if (!VOID_TYPE_P (TREE_TYPE (then_)))
3653 TREE_OPERAND (expr, 1) = build2 (MODIFY_EXPR, type, tmp, then_);
3655 /* Similarly, build the new else clause, `tmp = else_;'. */
3656 if (!VOID_TYPE_P (TREE_TYPE (else_)))
3657 TREE_OPERAND (expr, 2) = build2 (MODIFY_EXPR, type, tmp, else_);
3659 TREE_TYPE (expr) = void_type_node;
3660 recalculate_side_effects (expr);
3662 /* Move the COND_EXPR to the prequeue. */
3663 gimplify_stmt (&expr, pre_p);
3665 *expr_p = result;
3666 return GS_ALL_DONE;
3669 /* Remove any COMPOUND_EXPR so the following cases will be caught. */
3670 STRIP_TYPE_NOPS (TREE_OPERAND (expr, 0));
3671 if (TREE_CODE (TREE_OPERAND (expr, 0)) == COMPOUND_EXPR)
3672 gimplify_compound_expr (&TREE_OPERAND (expr, 0), pre_p, true);
3674 /* Make sure the condition has BOOLEAN_TYPE. */
3675 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
3677 /* Break apart && and || conditions. */
3678 if (TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ANDIF_EXPR
3679 || TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ORIF_EXPR)
3681 expr = shortcut_cond_expr (expr);
3683 if (expr != *expr_p)
3685 *expr_p = expr;
3687 /* We can't rely on gimplify_expr to re-gimplify the expanded
3688 form properly, as cleanups might cause the target labels to be
3689 wrapped in a TRY_FINALLY_EXPR. To prevent that, we need to
3690 set up a conditional context. */
3691 gimple_push_condition ();
3692 gimplify_stmt (expr_p, &seq);
3693 gimple_pop_condition (pre_p);
3694 gimple_seq_add_seq (pre_p, seq);
3696 return GS_ALL_DONE;
3700 /* Now do the normal gimplification. */
3702 /* Gimplify condition. */
3703 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL, is_gimple_condexpr,
3704 fb_rvalue);
3705 if (ret == GS_ERROR)
3706 return GS_ERROR;
3707 gcc_assert (TREE_OPERAND (expr, 0) != NULL_TREE);
3709 gimple_push_condition ();
3711 have_then_clause_p = have_else_clause_p = false;
3712 if (TREE_OPERAND (expr, 1) != NULL
3713 && TREE_CODE (TREE_OPERAND (expr, 1)) == GOTO_EXPR
3714 && TREE_CODE (GOTO_DESTINATION (TREE_OPERAND (expr, 1))) == LABEL_DECL
3715 && (DECL_CONTEXT (GOTO_DESTINATION (TREE_OPERAND (expr, 1)))
3716 == current_function_decl)
3717 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
3718 have different locations, otherwise we end up with incorrect
3719 location information on the branches. */
3720 && (optimize
3721 || !EXPR_HAS_LOCATION (expr)
3722 || !EXPR_HAS_LOCATION (TREE_OPERAND (expr, 1))
3723 || EXPR_LOCATION (expr) == EXPR_LOCATION (TREE_OPERAND (expr, 1))))
3725 label_true = GOTO_DESTINATION (TREE_OPERAND (expr, 1));
3726 have_then_clause_p = true;
3728 else
3729 label_true = create_artificial_label (UNKNOWN_LOCATION);
3730 if (TREE_OPERAND (expr, 2) != NULL
3731 && TREE_CODE (TREE_OPERAND (expr, 2)) == GOTO_EXPR
3732 && TREE_CODE (GOTO_DESTINATION (TREE_OPERAND (expr, 2))) == LABEL_DECL
3733 && (DECL_CONTEXT (GOTO_DESTINATION (TREE_OPERAND (expr, 2)))
3734 == current_function_decl)
3735 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
3736 have different locations, otherwise we end up with incorrect
3737 location information on the branches. */
3738 && (optimize
3739 || !EXPR_HAS_LOCATION (expr)
3740 || !EXPR_HAS_LOCATION (TREE_OPERAND (expr, 2))
3741 || EXPR_LOCATION (expr) == EXPR_LOCATION (TREE_OPERAND (expr, 2))))
3743 label_false = GOTO_DESTINATION (TREE_OPERAND (expr, 2));
3744 have_else_clause_p = true;
3746 else
3747 label_false = create_artificial_label (UNKNOWN_LOCATION);
3749 gimple_cond_get_ops_from_tree (COND_EXPR_COND (expr), &pred_code, &arm1,
3750 &arm2);
3751 cond_stmt = gimple_build_cond (pred_code, arm1, arm2, label_true,
3752 label_false);
3753 gimple_set_no_warning (cond_stmt, TREE_NO_WARNING (COND_EXPR_COND (expr)));
3754 gimplify_seq_add_stmt (&seq, cond_stmt);
3755 gimple_stmt_iterator gsi = gsi_last (seq);
3756 maybe_fold_stmt (&gsi);
3758 label_cont = NULL_TREE;
3759 if (!have_then_clause_p)
3761 /* For if (...) {} else { code; } put label_true after
3762 the else block. */
3763 if (TREE_OPERAND (expr, 1) == NULL_TREE
3764 && !have_else_clause_p
3765 && TREE_OPERAND (expr, 2) != NULL_TREE)
3766 label_cont = label_true;
3767 else
3769 gimplify_seq_add_stmt (&seq, gimple_build_label (label_true));
3770 have_then_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 1), &seq);
3771 /* For if (...) { code; } else {} or
3772 if (...) { code; } else goto label; or
3773 if (...) { code; return; } else { ... }
3774 label_cont isn't needed. */
3775 if (!have_else_clause_p
3776 && TREE_OPERAND (expr, 2) != NULL_TREE
3777 && gimple_seq_may_fallthru (seq))
3779 gimple *g;
3780 label_cont = create_artificial_label (UNKNOWN_LOCATION);
3782 g = gimple_build_goto (label_cont);
3784 /* GIMPLE_COND's are very low level; they have embedded
3785 gotos. This particular embedded goto should not be marked
3786 with the location of the original COND_EXPR, as it would
3787 correspond to the COND_EXPR's condition, not the ELSE or the
3788 THEN arms. To avoid marking it with the wrong location, flag
3789 it as "no location". */
3790 gimple_set_do_not_emit_location (g);
3792 gimplify_seq_add_stmt (&seq, g);
3796 if (!have_else_clause_p)
3798 gimplify_seq_add_stmt (&seq, gimple_build_label (label_false));
3799 have_else_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 2), &seq);
3801 if (label_cont)
3802 gimplify_seq_add_stmt (&seq, gimple_build_label (label_cont));
3804 gimple_pop_condition (pre_p);
3805 gimple_seq_add_seq (pre_p, seq);
3807 if (ret == GS_ERROR)
3808 ; /* Do nothing. */
3809 else if (have_then_clause_p || have_else_clause_p)
3810 ret = GS_ALL_DONE;
3811 else
3813 /* Both arms are empty; replace the COND_EXPR with its predicate. */
3814 expr = TREE_OPERAND (expr, 0);
3815 gimplify_stmt (&expr, pre_p);
3818 *expr_p = NULL;
3819 return ret;
3822 /* Prepare the node pointed to by EXPR_P, an is_gimple_addressable expression,
3823 to be marked addressable.
3825 We cannot rely on such an expression being directly markable if a temporary
3826 has been created by the gimplification. In this case, we create another
3827 temporary and initialize it with a copy, which will become a store after we
3828 mark it addressable. This can happen if the front-end passed us something
3829 that it could not mark addressable yet, like a Fortran pass-by-reference
3830 parameter (int) floatvar. */
3832 static void
3833 prepare_gimple_addressable (tree *expr_p, gimple_seq *seq_p)
3835 while (handled_component_p (*expr_p))
3836 expr_p = &TREE_OPERAND (*expr_p, 0);
3837 if (is_gimple_reg (*expr_p))
3839 /* Do not allow an SSA name as the temporary. */
3840 tree var = get_initialized_tmp_var (*expr_p, seq_p, NULL, false);
3841 DECL_GIMPLE_REG_P (var) = 0;
3842 *expr_p = var;
3846 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
3847 a call to __builtin_memcpy. */
3849 static enum gimplify_status
3850 gimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value,
3851 gimple_seq *seq_p)
3853 tree t, to, to_ptr, from, from_ptr;
3854 gcall *gs;
3855 location_t loc = EXPR_LOCATION (*expr_p);
3857 to = TREE_OPERAND (*expr_p, 0);
3858 from = TREE_OPERAND (*expr_p, 1);
3860 /* Mark the RHS addressable. Beware that it may not be possible to do so
3861 directly if a temporary has been created by the gimplification. */
3862 prepare_gimple_addressable (&from, seq_p);
3864 mark_addressable (from);
3865 from_ptr = build_fold_addr_expr_loc (loc, from);
3866 gimplify_arg (&from_ptr, seq_p, loc);
3868 mark_addressable (to);
3869 to_ptr = build_fold_addr_expr_loc (loc, to);
3870 gimplify_arg (&to_ptr, seq_p, loc);
3872 t = builtin_decl_implicit (BUILT_IN_MEMCPY);
3874 gs = gimple_build_call (t, 3, to_ptr, from_ptr, size);
3876 if (want_value)
3878 /* tmp = memcpy() */
3879 t = create_tmp_var (TREE_TYPE (to_ptr));
3880 gimple_call_set_lhs (gs, t);
3881 gimplify_seq_add_stmt (seq_p, gs);
3883 *expr_p = build_simple_mem_ref (t);
3884 return GS_ALL_DONE;
3887 gimplify_seq_add_stmt (seq_p, gs);
3888 *expr_p = NULL;
3889 return GS_ALL_DONE;
3892 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
3893 a call to __builtin_memset. In this case we know that the RHS is
3894 a CONSTRUCTOR with an empty element list. */
3896 static enum gimplify_status
3897 gimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value,
3898 gimple_seq *seq_p)
3900 tree t, from, to, to_ptr;
3901 gcall *gs;
3902 location_t loc = EXPR_LOCATION (*expr_p);
3904 /* Assert our assumptions, to abort instead of producing wrong code
3905 silently if they are not met. Beware that the RHS CONSTRUCTOR might
3906 not be immediately exposed. */
3907 from = TREE_OPERAND (*expr_p, 1);
3908 if (TREE_CODE (from) == WITH_SIZE_EXPR)
3909 from = TREE_OPERAND (from, 0);
3911 gcc_assert (TREE_CODE (from) == CONSTRUCTOR
3912 && vec_safe_is_empty (CONSTRUCTOR_ELTS (from)));
3914 /* Now proceed. */
3915 to = TREE_OPERAND (*expr_p, 0);
3917 to_ptr = build_fold_addr_expr_loc (loc, to);
3918 gimplify_arg (&to_ptr, seq_p, loc);
3919 t = builtin_decl_implicit (BUILT_IN_MEMSET);
3921 gs = gimple_build_call (t, 3, to_ptr, integer_zero_node, size);
3923 if (want_value)
3925 /* tmp = memset() */
3926 t = create_tmp_var (TREE_TYPE (to_ptr));
3927 gimple_call_set_lhs (gs, t);
3928 gimplify_seq_add_stmt (seq_p, gs);
3930 *expr_p = build1 (INDIRECT_REF, TREE_TYPE (to), t);
3931 return GS_ALL_DONE;
3934 gimplify_seq_add_stmt (seq_p, gs);
3935 *expr_p = NULL;
3936 return GS_ALL_DONE;
3939 /* A subroutine of gimplify_init_ctor_preeval. Called via walk_tree,
3940 determine, cautiously, if a CONSTRUCTOR overlaps the lhs of an
3941 assignment. Return non-null if we detect a potential overlap. */
3943 struct gimplify_init_ctor_preeval_data
3945 /* The base decl of the lhs object. May be NULL, in which case we
3946 have to assume the lhs is indirect. */
3947 tree lhs_base_decl;
3949 /* The alias set of the lhs object. */
3950 alias_set_type lhs_alias_set;
3953 static tree
3954 gimplify_init_ctor_preeval_1 (tree *tp, int *walk_subtrees, void *xdata)
3956 struct gimplify_init_ctor_preeval_data *data
3957 = (struct gimplify_init_ctor_preeval_data *) xdata;
3958 tree t = *tp;
3960 /* If we find the base object, obviously we have overlap. */
3961 if (data->lhs_base_decl == t)
3962 return t;
3964 /* If the constructor component is indirect, determine if we have a
3965 potential overlap with the lhs. The only bits of information we
3966 have to go on at this point are addressability and alias sets. */
3967 if ((INDIRECT_REF_P (t)
3968 || TREE_CODE (t) == MEM_REF)
3969 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
3970 && alias_sets_conflict_p (data->lhs_alias_set, get_alias_set (t)))
3971 return t;
3973 /* If the constructor component is a call, determine if it can hide a
3974 potential overlap with the lhs through an INDIRECT_REF like above.
3975 ??? Ugh - this is completely broken. In fact this whole analysis
3976 doesn't look conservative. */
3977 if (TREE_CODE (t) == CALL_EXPR)
3979 tree type, fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (t)));
3981 for (type = TYPE_ARG_TYPES (fntype); type; type = TREE_CHAIN (type))
3982 if (POINTER_TYPE_P (TREE_VALUE (type))
3983 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
3984 && alias_sets_conflict_p (data->lhs_alias_set,
3985 get_alias_set
3986 (TREE_TYPE (TREE_VALUE (type)))))
3987 return t;
3990 if (IS_TYPE_OR_DECL_P (t))
3991 *walk_subtrees = 0;
3992 return NULL;
3995 /* A subroutine of gimplify_init_constructor. Pre-evaluate EXPR,
3996 force values that overlap with the lhs (as described by *DATA)
3997 into temporaries. */
3999 static void
4000 gimplify_init_ctor_preeval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
4001 struct gimplify_init_ctor_preeval_data *data)
4003 enum gimplify_status one;
4005 /* If the value is constant, then there's nothing to pre-evaluate. */
4006 if (TREE_CONSTANT (*expr_p))
4008 /* Ensure it does not have side effects, it might contain a reference to
4009 the object we're initializing. */
4010 gcc_assert (!TREE_SIDE_EFFECTS (*expr_p));
4011 return;
4014 /* If the type has non-trivial constructors, we can't pre-evaluate. */
4015 if (TREE_ADDRESSABLE (TREE_TYPE (*expr_p)))
4016 return;
4018 /* Recurse for nested constructors. */
4019 if (TREE_CODE (*expr_p) == CONSTRUCTOR)
4021 unsigned HOST_WIDE_INT ix;
4022 constructor_elt *ce;
4023 vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (*expr_p);
4025 FOR_EACH_VEC_SAFE_ELT (v, ix, ce)
4026 gimplify_init_ctor_preeval (&ce->value, pre_p, post_p, data);
4028 return;
4031 /* If this is a variable sized type, we must remember the size. */
4032 maybe_with_size_expr (expr_p);
4034 /* Gimplify the constructor element to something appropriate for the rhs
4035 of a MODIFY_EXPR. Given that we know the LHS is an aggregate, we know
4036 the gimplifier will consider this a store to memory. Doing this
4037 gimplification now means that we won't have to deal with complicated
4038 language-specific trees, nor trees like SAVE_EXPR that can induce
4039 exponential search behavior. */
4040 one = gimplify_expr (expr_p, pre_p, post_p, is_gimple_mem_rhs, fb_rvalue);
4041 if (one == GS_ERROR)
4043 *expr_p = NULL;
4044 return;
4047 /* If we gimplified to a bare decl, we can be sure that it doesn't overlap
4048 with the lhs, since "a = { .x=a }" doesn't make sense. This will
4049 always be true for all scalars, since is_gimple_mem_rhs insists on a
4050 temporary variable for them. */
4051 if (DECL_P (*expr_p))
4052 return;
4054 /* If this is of variable size, we have no choice but to assume it doesn't
4055 overlap since we can't make a temporary for it. */
4056 if (TREE_CODE (TYPE_SIZE (TREE_TYPE (*expr_p))) != INTEGER_CST)
4057 return;
4059 /* Otherwise, we must search for overlap ... */
4060 if (!walk_tree (expr_p, gimplify_init_ctor_preeval_1, data, NULL))
4061 return;
4063 /* ... and if found, force the value into a temporary. */
4064 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
4067 /* A subroutine of gimplify_init_ctor_eval. Create a loop for
4068 a RANGE_EXPR in a CONSTRUCTOR for an array.
4070 var = lower;
4071 loop_entry:
4072 object[var] = value;
4073 if (var == upper)
4074 goto loop_exit;
4075 var = var + 1;
4076 goto loop_entry;
4077 loop_exit:
4079 We increment var _after_ the loop exit check because we might otherwise
4080 fail if upper == TYPE_MAX_VALUE (type for upper).
4082 Note that we never have to deal with SAVE_EXPRs here, because this has
4083 already been taken care of for us, in gimplify_init_ctor_preeval(). */
4085 static void gimplify_init_ctor_eval (tree, vec<constructor_elt, va_gc> *,
4086 gimple_seq *, bool);
4088 static void
4089 gimplify_init_ctor_eval_range (tree object, tree lower, tree upper,
4090 tree value, tree array_elt_type,
4091 gimple_seq *pre_p, bool cleared)
4093 tree loop_entry_label, loop_exit_label, fall_thru_label;
4094 tree var, var_type, cref, tmp;
4096 loop_entry_label = create_artificial_label (UNKNOWN_LOCATION);
4097 loop_exit_label = create_artificial_label (UNKNOWN_LOCATION);
4098 fall_thru_label = create_artificial_label (UNKNOWN_LOCATION);
4100 /* Create and initialize the index variable. */
4101 var_type = TREE_TYPE (upper);
4102 var = create_tmp_var (var_type);
4103 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, lower));
4105 /* Add the loop entry label. */
4106 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_entry_label));
4108 /* Build the reference. */
4109 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
4110 var, NULL_TREE, NULL_TREE);
4112 /* If we are a constructor, just call gimplify_init_ctor_eval to do
4113 the store. Otherwise just assign value to the reference. */
4115 if (TREE_CODE (value) == CONSTRUCTOR)
4116 /* NB we might have to call ourself recursively through
4117 gimplify_init_ctor_eval if the value is a constructor. */
4118 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
4119 pre_p, cleared);
4120 else
4121 gimplify_seq_add_stmt (pre_p, gimple_build_assign (cref, value));
4123 /* We exit the loop when the index var is equal to the upper bound. */
4124 gimplify_seq_add_stmt (pre_p,
4125 gimple_build_cond (EQ_EXPR, var, upper,
4126 loop_exit_label, fall_thru_label));
4128 gimplify_seq_add_stmt (pre_p, gimple_build_label (fall_thru_label));
4130 /* Otherwise, increment the index var... */
4131 tmp = build2 (PLUS_EXPR, var_type, var,
4132 fold_convert (var_type, integer_one_node));
4133 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, tmp));
4135 /* ...and jump back to the loop entry. */
4136 gimplify_seq_add_stmt (pre_p, gimple_build_goto (loop_entry_label));
4138 /* Add the loop exit label. */
4139 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_exit_label));
4142 /* Return true if FDECL is accessing a field that is zero sized. */
4144 static bool
4145 zero_sized_field_decl (const_tree fdecl)
4147 if (TREE_CODE (fdecl) == FIELD_DECL && DECL_SIZE (fdecl)
4148 && integer_zerop (DECL_SIZE (fdecl)))
4149 return true;
4150 return false;
4153 /* Return true if TYPE is zero sized. */
4155 static bool
4156 zero_sized_type (const_tree type)
4158 if (AGGREGATE_TYPE_P (type) && TYPE_SIZE (type)
4159 && integer_zerop (TYPE_SIZE (type)))
4160 return true;
4161 return false;
4164 /* A subroutine of gimplify_init_constructor. Generate individual
4165 MODIFY_EXPRs for a CONSTRUCTOR. OBJECT is the LHS against which the
4166 assignments should happen. ELTS is the CONSTRUCTOR_ELTS of the
4167 CONSTRUCTOR. CLEARED is true if the entire LHS object has been
4168 zeroed first. */
4170 static void
4171 gimplify_init_ctor_eval (tree object, vec<constructor_elt, va_gc> *elts,
4172 gimple_seq *pre_p, bool cleared)
4174 tree array_elt_type = NULL;
4175 unsigned HOST_WIDE_INT ix;
4176 tree purpose, value;
4178 if (TREE_CODE (TREE_TYPE (object)) == ARRAY_TYPE)
4179 array_elt_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (object)));
4181 FOR_EACH_CONSTRUCTOR_ELT (elts, ix, purpose, value)
4183 tree cref;
4185 /* NULL values are created above for gimplification errors. */
4186 if (value == NULL)
4187 continue;
4189 if (cleared && initializer_zerop (value))
4190 continue;
4192 /* ??? Here's to hoping the front end fills in all of the indices,
4193 so we don't have to figure out what's missing ourselves. */
4194 gcc_assert (purpose);
4196 /* Skip zero-sized fields, unless value has side-effects. This can
4197 happen with calls to functions returning a zero-sized type, which
4198 we shouldn't discard. As a number of downstream passes don't
4199 expect sets of zero-sized fields, we rely on the gimplification of
4200 the MODIFY_EXPR we make below to drop the assignment statement. */
4201 if (! TREE_SIDE_EFFECTS (value) && zero_sized_field_decl (purpose))
4202 continue;
4204 /* If we have a RANGE_EXPR, we have to build a loop to assign the
4205 whole range. */
4206 if (TREE_CODE (purpose) == RANGE_EXPR)
4208 tree lower = TREE_OPERAND (purpose, 0);
4209 tree upper = TREE_OPERAND (purpose, 1);
4211 /* If the lower bound is equal to upper, just treat it as if
4212 upper was the index. */
4213 if (simple_cst_equal (lower, upper))
4214 purpose = upper;
4215 else
4217 gimplify_init_ctor_eval_range (object, lower, upper, value,
4218 array_elt_type, pre_p, cleared);
4219 continue;
4223 if (array_elt_type)
4225 /* Do not use bitsizetype for ARRAY_REF indices. */
4226 if (TYPE_DOMAIN (TREE_TYPE (object)))
4227 purpose
4228 = fold_convert (TREE_TYPE (TYPE_DOMAIN (TREE_TYPE (object))),
4229 purpose);
4230 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
4231 purpose, NULL_TREE, NULL_TREE);
4233 else
4235 gcc_assert (TREE_CODE (purpose) == FIELD_DECL);
4236 cref = build3 (COMPONENT_REF, TREE_TYPE (purpose),
4237 unshare_expr (object), purpose, NULL_TREE);
4240 if (TREE_CODE (value) == CONSTRUCTOR
4241 && TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE)
4242 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
4243 pre_p, cleared);
4244 else
4246 tree init = build2 (INIT_EXPR, TREE_TYPE (cref), cref, value);
4247 gimplify_and_add (init, pre_p);
4248 ggc_free (init);
4253 /* Return the appropriate RHS predicate for this LHS. */
4255 gimple_predicate
4256 rhs_predicate_for (tree lhs)
4258 if (is_gimple_reg (lhs))
4259 return is_gimple_reg_rhs_or_call;
4260 else
4261 return is_gimple_mem_rhs_or_call;
4264 /* Return the initial guess for an appropriate RHS predicate for this LHS,
4265 before the LHS has been gimplified. */
4267 static gimple_predicate
4268 initial_rhs_predicate_for (tree lhs)
4270 if (is_gimple_reg_type (TREE_TYPE (lhs)))
4271 return is_gimple_reg_rhs_or_call;
4272 else
4273 return is_gimple_mem_rhs_or_call;
4276 /* Gimplify a C99 compound literal expression. This just means adding
4277 the DECL_EXPR before the current statement and using its anonymous
4278 decl instead. */
4280 static enum gimplify_status
4281 gimplify_compound_literal_expr (tree *expr_p, gimple_seq *pre_p,
4282 bool (*gimple_test_f) (tree),
4283 fallback_t fallback)
4285 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (*expr_p);
4286 tree decl = DECL_EXPR_DECL (decl_s);
4287 tree init = DECL_INITIAL (decl);
4288 /* Mark the decl as addressable if the compound literal
4289 expression is addressable now, otherwise it is marked too late
4290 after we gimplify the initialization expression. */
4291 if (TREE_ADDRESSABLE (*expr_p))
4292 TREE_ADDRESSABLE (decl) = 1;
4293 /* Otherwise, if we don't need an lvalue and have a literal directly
4294 substitute it. Check if it matches the gimple predicate, as
4295 otherwise we'd generate a new temporary, and we can as well just
4296 use the decl we already have. */
4297 else if (!TREE_ADDRESSABLE (decl)
4298 && init
4299 && (fallback & fb_lvalue) == 0
4300 && gimple_test_f (init))
4302 *expr_p = init;
4303 return GS_OK;
4306 /* Preliminarily mark non-addressed complex variables as eligible
4307 for promotion to gimple registers. We'll transform their uses
4308 as we find them. */
4309 if ((TREE_CODE (TREE_TYPE (decl)) == COMPLEX_TYPE
4310 || TREE_CODE (TREE_TYPE (decl)) == VECTOR_TYPE)
4311 && !TREE_THIS_VOLATILE (decl)
4312 && !needs_to_live_in_memory (decl))
4313 DECL_GIMPLE_REG_P (decl) = 1;
4315 /* If the decl is not addressable, then it is being used in some
4316 expression or on the right hand side of a statement, and it can
4317 be put into a readonly data section. */
4318 if (!TREE_ADDRESSABLE (decl) && (fallback & fb_lvalue) == 0)
4319 TREE_READONLY (decl) = 1;
4321 /* This decl isn't mentioned in the enclosing block, so add it to the
4322 list of temps. FIXME it seems a bit of a kludge to say that
4323 anonymous artificial vars aren't pushed, but everything else is. */
4324 if (DECL_NAME (decl) == NULL_TREE && !DECL_SEEN_IN_BIND_EXPR_P (decl))
4325 gimple_add_tmp_var (decl);
4327 gimplify_and_add (decl_s, pre_p);
4328 *expr_p = decl;
4329 return GS_OK;
4332 /* Optimize embedded COMPOUND_LITERAL_EXPRs within a CONSTRUCTOR,
4333 return a new CONSTRUCTOR if something changed. */
4335 static tree
4336 optimize_compound_literals_in_ctor (tree orig_ctor)
4338 tree ctor = orig_ctor;
4339 vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ctor);
4340 unsigned int idx, num = vec_safe_length (elts);
4342 for (idx = 0; idx < num; idx++)
4344 tree value = (*elts)[idx].value;
4345 tree newval = value;
4346 if (TREE_CODE (value) == CONSTRUCTOR)
4347 newval = optimize_compound_literals_in_ctor (value);
4348 else if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR)
4350 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (value);
4351 tree decl = DECL_EXPR_DECL (decl_s);
4352 tree init = DECL_INITIAL (decl);
4354 if (!TREE_ADDRESSABLE (value)
4355 && !TREE_ADDRESSABLE (decl)
4356 && init
4357 && TREE_CODE (init) == CONSTRUCTOR)
4358 newval = optimize_compound_literals_in_ctor (init);
4360 if (newval == value)
4361 continue;
4363 if (ctor == orig_ctor)
4365 ctor = copy_node (orig_ctor);
4366 CONSTRUCTOR_ELTS (ctor) = vec_safe_copy (elts);
4367 elts = CONSTRUCTOR_ELTS (ctor);
4369 (*elts)[idx].value = newval;
4371 return ctor;
4374 /* A subroutine of gimplify_modify_expr. Break out elements of a
4375 CONSTRUCTOR used as an initializer into separate MODIFY_EXPRs.
4377 Note that we still need to clear any elements that don't have explicit
4378 initializers, so if not all elements are initialized we keep the
4379 original MODIFY_EXPR, we just remove all of the constructor elements.
4381 If NOTIFY_TEMP_CREATION is true, do not gimplify, just return
4382 GS_ERROR if we would have to create a temporary when gimplifying
4383 this constructor. Otherwise, return GS_OK.
4385 If NOTIFY_TEMP_CREATION is false, just do the gimplification. */
4387 static enum gimplify_status
4388 gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
4389 bool want_value, bool notify_temp_creation)
4391 tree object, ctor, type;
4392 enum gimplify_status ret;
4393 vec<constructor_elt, va_gc> *elts;
4395 gcc_assert (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == CONSTRUCTOR);
4397 if (!notify_temp_creation)
4399 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
4400 is_gimple_lvalue, fb_lvalue);
4401 if (ret == GS_ERROR)
4402 return ret;
4405 object = TREE_OPERAND (*expr_p, 0);
4406 ctor = TREE_OPERAND (*expr_p, 1) =
4407 optimize_compound_literals_in_ctor (TREE_OPERAND (*expr_p, 1));
4408 type = TREE_TYPE (ctor);
4409 elts = CONSTRUCTOR_ELTS (ctor);
4410 ret = GS_ALL_DONE;
4412 switch (TREE_CODE (type))
4414 case RECORD_TYPE:
4415 case UNION_TYPE:
4416 case QUAL_UNION_TYPE:
4417 case ARRAY_TYPE:
4419 struct gimplify_init_ctor_preeval_data preeval_data;
4420 HOST_WIDE_INT num_ctor_elements, num_nonzero_elements;
4421 bool cleared, complete_p, valid_const_initializer;
4423 /* Aggregate types must lower constructors to initialization of
4424 individual elements. The exception is that a CONSTRUCTOR node
4425 with no elements indicates zero-initialization of the whole. */
4426 if (vec_safe_is_empty (elts))
4428 if (notify_temp_creation)
4429 return GS_OK;
4430 break;
4433 /* Fetch information about the constructor to direct later processing.
4434 We might want to make static versions of it in various cases, and
4435 can only do so if it known to be a valid constant initializer. */
4436 valid_const_initializer
4437 = categorize_ctor_elements (ctor, &num_nonzero_elements,
4438 &num_ctor_elements, &complete_p);
4440 /* If a const aggregate variable is being initialized, then it
4441 should never be a lose to promote the variable to be static. */
4442 if (valid_const_initializer
4443 && num_nonzero_elements > 1
4444 && TREE_READONLY (object)
4445 && TREE_CODE (object) == VAR_DECL
4446 && (flag_merge_constants >= 2 || !TREE_ADDRESSABLE (object)))
4448 if (notify_temp_creation)
4449 return GS_ERROR;
4450 DECL_INITIAL (object) = ctor;
4451 TREE_STATIC (object) = 1;
4452 if (!DECL_NAME (object))
4453 DECL_NAME (object) = create_tmp_var_name ("C");
4454 walk_tree (&DECL_INITIAL (object), force_labels_r, NULL, NULL);
4456 /* ??? C++ doesn't automatically append a .<number> to the
4457 assembler name, and even when it does, it looks at FE private
4458 data structures to figure out what that number should be,
4459 which are not set for this variable. I suppose this is
4460 important for local statics for inline functions, which aren't
4461 "local" in the object file sense. So in order to get a unique
4462 TU-local symbol, we must invoke the lhd version now. */
4463 lhd_set_decl_assembler_name (object);
4465 *expr_p = NULL_TREE;
4466 break;
4469 /* If there are "lots" of initialized elements, even discounting
4470 those that are not address constants (and thus *must* be
4471 computed at runtime), then partition the constructor into
4472 constant and non-constant parts. Block copy the constant
4473 parts in, then generate code for the non-constant parts. */
4474 /* TODO. There's code in cp/typeck.c to do this. */
4476 if (int_size_in_bytes (TREE_TYPE (ctor)) < 0)
4477 /* store_constructor will ignore the clearing of variable-sized
4478 objects. Initializers for such objects must explicitly set
4479 every field that needs to be set. */
4480 cleared = false;
4481 else if (!complete_p && !CONSTRUCTOR_NO_CLEARING (ctor))
4482 /* If the constructor isn't complete, clear the whole object
4483 beforehand, unless CONSTRUCTOR_NO_CLEARING is set on it.
4485 ??? This ought not to be needed. For any element not present
4486 in the initializer, we should simply set them to zero. Except
4487 we'd need to *find* the elements that are not present, and that
4488 requires trickery to avoid quadratic compile-time behavior in
4489 large cases or excessive memory use in small cases. */
4490 cleared = true;
4491 else if (num_ctor_elements - num_nonzero_elements
4492 > CLEAR_RATIO (optimize_function_for_speed_p (cfun))
4493 && num_nonzero_elements < num_ctor_elements / 4)
4494 /* If there are "lots" of zeros, it's more efficient to clear
4495 the memory and then set the nonzero elements. */
4496 cleared = true;
4497 else
4498 cleared = false;
4500 /* If there are "lots" of initialized elements, and all of them
4501 are valid address constants, then the entire initializer can
4502 be dropped to memory, and then memcpy'd out. Don't do this
4503 for sparse arrays, though, as it's more efficient to follow
4504 the standard CONSTRUCTOR behavior of memset followed by
4505 individual element initialization. Also don't do this for small
4506 all-zero initializers (which aren't big enough to merit
4507 clearing), and don't try to make bitwise copies of
4508 TREE_ADDRESSABLE types.
4510 We cannot apply such transformation when compiling chkp static
4511 initializer because creation of initializer image in the memory
4512 will require static initialization of bounds for it. It should
4513 result in another gimplification of similar initializer and we
4514 may fall into infinite loop. */
4515 if (valid_const_initializer
4516 && !(cleared || num_nonzero_elements == 0)
4517 && !TREE_ADDRESSABLE (type)
4518 && (!current_function_decl
4519 || !lookup_attribute ("chkp ctor",
4520 DECL_ATTRIBUTES (current_function_decl))))
4522 HOST_WIDE_INT size = int_size_in_bytes (type);
4523 unsigned int align;
4525 /* ??? We can still get unbounded array types, at least
4526 from the C++ front end. This seems wrong, but attempt
4527 to work around it for now. */
4528 if (size < 0)
4530 size = int_size_in_bytes (TREE_TYPE (object));
4531 if (size >= 0)
4532 TREE_TYPE (ctor) = type = TREE_TYPE (object);
4535 /* Find the maximum alignment we can assume for the object. */
4536 /* ??? Make use of DECL_OFFSET_ALIGN. */
4537 if (DECL_P (object))
4538 align = DECL_ALIGN (object);
4539 else
4540 align = TYPE_ALIGN (type);
4542 /* Do a block move either if the size is so small as to make
4543 each individual move a sub-unit move on average, or if it
4544 is so large as to make individual moves inefficient. */
4545 if (size > 0
4546 && num_nonzero_elements > 1
4547 && (size < num_nonzero_elements
4548 || !can_move_by_pieces (size, align)))
4550 if (notify_temp_creation)
4551 return GS_ERROR;
4553 walk_tree (&ctor, force_labels_r, NULL, NULL);
4554 ctor = tree_output_constant_def (ctor);
4555 if (!useless_type_conversion_p (type, TREE_TYPE (ctor)))
4556 ctor = build1 (VIEW_CONVERT_EXPR, type, ctor);
4557 TREE_OPERAND (*expr_p, 1) = ctor;
4559 /* This is no longer an assignment of a CONSTRUCTOR, but
4560 we still may have processing to do on the LHS. So
4561 pretend we didn't do anything here to let that happen. */
4562 return GS_UNHANDLED;
4566 /* If the target is volatile, we have non-zero elements and more than
4567 one field to assign, initialize the target from a temporary. */
4568 if (TREE_THIS_VOLATILE (object)
4569 && !TREE_ADDRESSABLE (type)
4570 && num_nonzero_elements > 0
4571 && vec_safe_length (elts) > 1)
4573 tree temp = create_tmp_var (TYPE_MAIN_VARIANT (type));
4574 TREE_OPERAND (*expr_p, 0) = temp;
4575 *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p),
4576 *expr_p,
4577 build2 (MODIFY_EXPR, void_type_node,
4578 object, temp));
4579 return GS_OK;
4582 if (notify_temp_creation)
4583 return GS_OK;
4585 /* If there are nonzero elements and if needed, pre-evaluate to capture
4586 elements overlapping with the lhs into temporaries. We must do this
4587 before clearing to fetch the values before they are zeroed-out. */
4588 if (num_nonzero_elements > 0 && TREE_CODE (*expr_p) != INIT_EXPR)
4590 preeval_data.lhs_base_decl = get_base_address (object);
4591 if (!DECL_P (preeval_data.lhs_base_decl))
4592 preeval_data.lhs_base_decl = NULL;
4593 preeval_data.lhs_alias_set = get_alias_set (object);
4595 gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p, 1),
4596 pre_p, post_p, &preeval_data);
4599 bool ctor_has_side_effects_p
4600 = TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p, 1));
4602 if (cleared)
4604 /* Zap the CONSTRUCTOR element list, which simplifies this case.
4605 Note that we still have to gimplify, in order to handle the
4606 case of variable sized types. Avoid shared tree structures. */
4607 CONSTRUCTOR_ELTS (ctor) = NULL;
4608 TREE_SIDE_EFFECTS (ctor) = 0;
4609 object = unshare_expr (object);
4610 gimplify_stmt (expr_p, pre_p);
4613 /* If we have not block cleared the object, or if there are nonzero
4614 elements in the constructor, or if the constructor has side effects,
4615 add assignments to the individual scalar fields of the object. */
4616 if (!cleared
4617 || num_nonzero_elements > 0
4618 || ctor_has_side_effects_p)
4619 gimplify_init_ctor_eval (object, elts, pre_p, cleared);
4621 *expr_p = NULL_TREE;
4623 break;
4625 case COMPLEX_TYPE:
4627 tree r, i;
4629 if (notify_temp_creation)
4630 return GS_OK;
4632 /* Extract the real and imaginary parts out of the ctor. */
4633 gcc_assert (elts->length () == 2);
4634 r = (*elts)[0].value;
4635 i = (*elts)[1].value;
4636 if (r == NULL || i == NULL)
4638 tree zero = build_zero_cst (TREE_TYPE (type));
4639 if (r == NULL)
4640 r = zero;
4641 if (i == NULL)
4642 i = zero;
4645 /* Complex types have either COMPLEX_CST or COMPLEX_EXPR to
4646 represent creation of a complex value. */
4647 if (TREE_CONSTANT (r) && TREE_CONSTANT (i))
4649 ctor = build_complex (type, r, i);
4650 TREE_OPERAND (*expr_p, 1) = ctor;
4652 else
4654 ctor = build2 (COMPLEX_EXPR, type, r, i);
4655 TREE_OPERAND (*expr_p, 1) = ctor;
4656 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 1),
4657 pre_p,
4658 post_p,
4659 rhs_predicate_for (TREE_OPERAND (*expr_p, 0)),
4660 fb_rvalue);
4663 break;
4665 case VECTOR_TYPE:
4667 unsigned HOST_WIDE_INT ix;
4668 constructor_elt *ce;
4670 if (notify_temp_creation)
4671 return GS_OK;
4673 /* Go ahead and simplify constant constructors to VECTOR_CST. */
4674 if (TREE_CONSTANT (ctor))
4676 bool constant_p = true;
4677 tree value;
4679 /* Even when ctor is constant, it might contain non-*_CST
4680 elements, such as addresses or trapping values like
4681 1.0/0.0 - 1.0/0.0. Such expressions don't belong
4682 in VECTOR_CST nodes. */
4683 FOR_EACH_CONSTRUCTOR_VALUE (elts, ix, value)
4684 if (!CONSTANT_CLASS_P (value))
4686 constant_p = false;
4687 break;
4690 if (constant_p)
4692 TREE_OPERAND (*expr_p, 1) = build_vector_from_ctor (type, elts);
4693 break;
4696 TREE_CONSTANT (ctor) = 0;
4699 /* Vector types use CONSTRUCTOR all the way through gimple
4700 compilation as a general initializer. */
4701 FOR_EACH_VEC_SAFE_ELT (elts, ix, ce)
4703 enum gimplify_status tret;
4704 tret = gimplify_expr (&ce->value, pre_p, post_p, is_gimple_val,
4705 fb_rvalue);
4706 if (tret == GS_ERROR)
4707 ret = GS_ERROR;
4708 else if (TREE_STATIC (ctor)
4709 && !initializer_constant_valid_p (ce->value,
4710 TREE_TYPE (ce->value)))
4711 TREE_STATIC (ctor) = 0;
4713 if (!is_gimple_reg (TREE_OPERAND (*expr_p, 0)))
4714 TREE_OPERAND (*expr_p, 1) = get_formal_tmp_var (ctor, pre_p);
4716 break;
4718 default:
4719 /* So how did we get a CONSTRUCTOR for a scalar type? */
4720 gcc_unreachable ();
4723 if (ret == GS_ERROR)
4724 return GS_ERROR;
4725 else if (want_value)
4727 *expr_p = object;
4728 return GS_OK;
4730 else
4732 /* If we have gimplified both sides of the initializer but have
4733 not emitted an assignment, do so now. */
4734 if (*expr_p)
4736 tree lhs = TREE_OPERAND (*expr_p, 0);
4737 tree rhs = TREE_OPERAND (*expr_p, 1);
4738 gassign *init = gimple_build_assign (lhs, rhs);
4739 gimplify_seq_add_stmt (pre_p, init);
4740 *expr_p = NULL;
4743 return GS_ALL_DONE;
4747 /* Given a pointer value OP0, return a simplified version of an
4748 indirection through OP0, or NULL_TREE if no simplification is
4749 possible. This may only be applied to a rhs of an expression.
4750 Note that the resulting type may be different from the type pointed
4751 to in the sense that it is still compatible from the langhooks
4752 point of view. */
4754 static tree
4755 gimple_fold_indirect_ref_rhs (tree t)
4757 return gimple_fold_indirect_ref (t);
4760 /* Subroutine of gimplify_modify_expr to do simplifications of
4761 MODIFY_EXPRs based on the code of the RHS. We loop for as long as
4762 something changes. */
4764 static enum gimplify_status
4765 gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p,
4766 gimple_seq *pre_p, gimple_seq *post_p,
4767 bool want_value)
4769 enum gimplify_status ret = GS_UNHANDLED;
4770 bool changed;
4774 changed = false;
4775 switch (TREE_CODE (*from_p))
4777 case VAR_DECL:
4778 /* If we're assigning from a read-only variable initialized with
4779 a constructor, do the direct assignment from the constructor,
4780 but only if neither source nor target are volatile since this
4781 latter assignment might end up being done on a per-field basis. */
4782 if (DECL_INITIAL (*from_p)
4783 && TREE_READONLY (*from_p)
4784 && !TREE_THIS_VOLATILE (*from_p)
4785 && !TREE_THIS_VOLATILE (*to_p)
4786 && TREE_CODE (DECL_INITIAL (*from_p)) == CONSTRUCTOR)
4788 tree old_from = *from_p;
4789 enum gimplify_status subret;
4791 /* Move the constructor into the RHS. */
4792 *from_p = unshare_expr (DECL_INITIAL (*from_p));
4794 /* Let's see if gimplify_init_constructor will need to put
4795 it in memory. */
4796 subret = gimplify_init_constructor (expr_p, NULL, NULL,
4797 false, true);
4798 if (subret == GS_ERROR)
4800 /* If so, revert the change. */
4801 *from_p = old_from;
4803 else
4805 ret = GS_OK;
4806 changed = true;
4809 break;
4810 case INDIRECT_REF:
4812 /* If we have code like
4814 *(const A*)(A*)&x
4816 where the type of "x" is a (possibly cv-qualified variant
4817 of "A"), treat the entire expression as identical to "x".
4818 This kind of code arises in C++ when an object is bound
4819 to a const reference, and if "x" is a TARGET_EXPR we want
4820 to take advantage of the optimization below. */
4821 bool volatile_p = TREE_THIS_VOLATILE (*from_p);
4822 tree t = gimple_fold_indirect_ref_rhs (TREE_OPERAND (*from_p, 0));
4823 if (t)
4825 if (TREE_THIS_VOLATILE (t) != volatile_p)
4827 if (DECL_P (t))
4828 t = build_simple_mem_ref_loc (EXPR_LOCATION (*from_p),
4829 build_fold_addr_expr (t));
4830 if (REFERENCE_CLASS_P (t))
4831 TREE_THIS_VOLATILE (t) = volatile_p;
4833 *from_p = t;
4834 ret = GS_OK;
4835 changed = true;
4837 break;
4840 case TARGET_EXPR:
4842 /* If we are initializing something from a TARGET_EXPR, strip the
4843 TARGET_EXPR and initialize it directly, if possible. This can't
4844 be done if the initializer is void, since that implies that the
4845 temporary is set in some non-trivial way.
4847 ??? What about code that pulls out the temp and uses it
4848 elsewhere? I think that such code never uses the TARGET_EXPR as
4849 an initializer. If I'm wrong, we'll die because the temp won't
4850 have any RTL. In that case, I guess we'll need to replace
4851 references somehow. */
4852 tree init = TARGET_EXPR_INITIAL (*from_p);
4854 if (init
4855 && !VOID_TYPE_P (TREE_TYPE (init)))
4857 *from_p = init;
4858 ret = GS_OK;
4859 changed = true;
4862 break;
4864 case COMPOUND_EXPR:
4865 /* Remove any COMPOUND_EXPR in the RHS so the following cases will be
4866 caught. */
4867 gimplify_compound_expr (from_p, pre_p, true);
4868 ret = GS_OK;
4869 changed = true;
4870 break;
4872 case CONSTRUCTOR:
4873 /* If we already made some changes, let the front end have a
4874 crack at this before we break it down. */
4875 if (ret != GS_UNHANDLED)
4876 break;
4877 /* If we're initializing from a CONSTRUCTOR, break this into
4878 individual MODIFY_EXPRs. */
4879 return gimplify_init_constructor (expr_p, pre_p, post_p, want_value,
4880 false);
4882 case COND_EXPR:
4883 /* If we're assigning to a non-register type, push the assignment
4884 down into the branches. This is mandatory for ADDRESSABLE types,
4885 since we cannot generate temporaries for such, but it saves a
4886 copy in other cases as well. */
4887 if (!is_gimple_reg_type (TREE_TYPE (*from_p)))
4889 /* This code should mirror the code in gimplify_cond_expr. */
4890 enum tree_code code = TREE_CODE (*expr_p);
4891 tree cond = *from_p;
4892 tree result = *to_p;
4894 ret = gimplify_expr (&result, pre_p, post_p,
4895 is_gimple_lvalue, fb_lvalue);
4896 if (ret != GS_ERROR)
4897 ret = GS_OK;
4899 if (TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node)
4900 TREE_OPERAND (cond, 1)
4901 = build2 (code, void_type_node, result,
4902 TREE_OPERAND (cond, 1));
4903 if (TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
4904 TREE_OPERAND (cond, 2)
4905 = build2 (code, void_type_node, unshare_expr (result),
4906 TREE_OPERAND (cond, 2));
4908 TREE_TYPE (cond) = void_type_node;
4909 recalculate_side_effects (cond);
4911 if (want_value)
4913 gimplify_and_add (cond, pre_p);
4914 *expr_p = unshare_expr (result);
4916 else
4917 *expr_p = cond;
4918 return ret;
4920 break;
4922 case CALL_EXPR:
4923 /* For calls that return in memory, give *to_p as the CALL_EXPR's
4924 return slot so that we don't generate a temporary. */
4925 if (!CALL_EXPR_RETURN_SLOT_OPT (*from_p)
4926 && aggregate_value_p (*from_p, *from_p))
4928 bool use_target;
4930 if (!(rhs_predicate_for (*to_p))(*from_p))
4931 /* If we need a temporary, *to_p isn't accurate. */
4932 use_target = false;
4933 /* It's OK to use the return slot directly unless it's an NRV. */
4934 else if (TREE_CODE (*to_p) == RESULT_DECL
4935 && DECL_NAME (*to_p) == NULL_TREE
4936 && needs_to_live_in_memory (*to_p))
4937 use_target = true;
4938 else if (is_gimple_reg_type (TREE_TYPE (*to_p))
4939 || (DECL_P (*to_p) && DECL_REGISTER (*to_p)))
4940 /* Don't force regs into memory. */
4941 use_target = false;
4942 else if (TREE_CODE (*expr_p) == INIT_EXPR)
4943 /* It's OK to use the target directly if it's being
4944 initialized. */
4945 use_target = true;
4946 else if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p)))
4947 != INTEGER_CST)
4948 /* Always use the target and thus RSO for variable-sized types.
4949 GIMPLE cannot deal with a variable-sized assignment
4950 embedded in a call statement. */
4951 use_target = true;
4952 else if (TREE_CODE (*to_p) != SSA_NAME
4953 && (!is_gimple_variable (*to_p)
4954 || needs_to_live_in_memory (*to_p)))
4955 /* Don't use the original target if it's already addressable;
4956 if its address escapes, and the called function uses the
4957 NRV optimization, a conforming program could see *to_p
4958 change before the called function returns; see c++/19317.
4959 When optimizing, the return_slot pass marks more functions
4960 as safe after we have escape info. */
4961 use_target = false;
4962 else
4963 use_target = true;
4965 if (use_target)
4967 CALL_EXPR_RETURN_SLOT_OPT (*from_p) = 1;
4968 mark_addressable (*to_p);
4971 break;
4973 case WITH_SIZE_EXPR:
4974 /* Likewise for calls that return an aggregate of non-constant size,
4975 since we would not be able to generate a temporary at all. */
4976 if (TREE_CODE (TREE_OPERAND (*from_p, 0)) == CALL_EXPR)
4978 *from_p = TREE_OPERAND (*from_p, 0);
4979 /* We don't change ret in this case because the
4980 WITH_SIZE_EXPR might have been added in
4981 gimplify_modify_expr, so returning GS_OK would lead to an
4982 infinite loop. */
4983 changed = true;
4985 break;
4987 /* If we're initializing from a container, push the initialization
4988 inside it. */
4989 case CLEANUP_POINT_EXPR:
4990 case BIND_EXPR:
4991 case STATEMENT_LIST:
4993 tree wrap = *from_p;
4994 tree t;
4996 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_min_lval,
4997 fb_lvalue);
4998 if (ret != GS_ERROR)
4999 ret = GS_OK;
5001 t = voidify_wrapper_expr (wrap, *expr_p);
5002 gcc_assert (t == *expr_p);
5004 if (want_value)
5006 gimplify_and_add (wrap, pre_p);
5007 *expr_p = unshare_expr (*to_p);
5009 else
5010 *expr_p = wrap;
5011 return GS_OK;
5014 case COMPOUND_LITERAL_EXPR:
5016 tree complit = TREE_OPERAND (*expr_p, 1);
5017 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (complit);
5018 tree decl = DECL_EXPR_DECL (decl_s);
5019 tree init = DECL_INITIAL (decl);
5021 /* struct T x = (struct T) { 0, 1, 2 } can be optimized
5022 into struct T x = { 0, 1, 2 } if the address of the
5023 compound literal has never been taken. */
5024 if (!TREE_ADDRESSABLE (complit)
5025 && !TREE_ADDRESSABLE (decl)
5026 && init)
5028 *expr_p = copy_node (*expr_p);
5029 TREE_OPERAND (*expr_p, 1) = init;
5030 return GS_OK;
5034 default:
5035 break;
5038 while (changed);
5040 return ret;
5044 /* Return true if T looks like a valid GIMPLE statement. */
5046 static bool
5047 is_gimple_stmt (tree t)
5049 const enum tree_code code = TREE_CODE (t);
5051 switch (code)
5053 case NOP_EXPR:
5054 /* The only valid NOP_EXPR is the empty statement. */
5055 return IS_EMPTY_STMT (t);
5057 case BIND_EXPR:
5058 case COND_EXPR:
5059 /* These are only valid if they're void. */
5060 return TREE_TYPE (t) == NULL || VOID_TYPE_P (TREE_TYPE (t));
5062 case SWITCH_EXPR:
5063 case GOTO_EXPR:
5064 case RETURN_EXPR:
5065 case LABEL_EXPR:
5066 case CASE_LABEL_EXPR:
5067 case TRY_CATCH_EXPR:
5068 case TRY_FINALLY_EXPR:
5069 case EH_FILTER_EXPR:
5070 case CATCH_EXPR:
5071 case ASM_EXPR:
5072 case STATEMENT_LIST:
5073 case OACC_PARALLEL:
5074 case OACC_KERNELS:
5075 case OACC_DATA:
5076 case OACC_HOST_DATA:
5077 case OACC_DECLARE:
5078 case OACC_UPDATE:
5079 case OACC_ENTER_DATA:
5080 case OACC_EXIT_DATA:
5081 case OACC_CACHE:
5082 case OMP_PARALLEL:
5083 case OMP_FOR:
5084 case OMP_SIMD:
5085 case CILK_SIMD:
5086 case OMP_DISTRIBUTE:
5087 case OACC_LOOP:
5088 case OMP_SECTIONS:
5089 case OMP_SECTION:
5090 case OMP_SINGLE:
5091 case OMP_MASTER:
5092 case OMP_TASKGROUP:
5093 case OMP_ORDERED:
5094 case OMP_CRITICAL:
5095 case OMP_TASK:
5096 case OMP_TARGET:
5097 case OMP_TARGET_DATA:
5098 case OMP_TARGET_UPDATE:
5099 case OMP_TARGET_ENTER_DATA:
5100 case OMP_TARGET_EXIT_DATA:
5101 case OMP_TASKLOOP:
5102 case OMP_TEAMS:
5103 /* These are always void. */
5104 return true;
5106 case CALL_EXPR:
5107 case MODIFY_EXPR:
5108 case PREDICT_EXPR:
5109 /* These are valid regardless of their type. */
5110 return true;
5112 default:
5113 return false;
5118 /* Promote partial stores to COMPLEX variables to total stores. *EXPR_P is
5119 a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a variable with
5120 DECL_GIMPLE_REG_P set.
5122 IMPORTANT NOTE: This promotion is performed by introducing a load of the
5123 other, unmodified part of the complex object just before the total store.
5124 As a consequence, if the object is still uninitialized, an undefined value
5125 will be loaded into a register, which may result in a spurious exception
5126 if the register is floating-point and the value happens to be a signaling
5127 NaN for example. Then the fully-fledged complex operations lowering pass
5128 followed by a DCE pass are necessary in order to fix things up. */
5130 static enum gimplify_status
5131 gimplify_modify_expr_complex_part (tree *expr_p, gimple_seq *pre_p,
5132 bool want_value)
5134 enum tree_code code, ocode;
5135 tree lhs, rhs, new_rhs, other, realpart, imagpart;
5137 lhs = TREE_OPERAND (*expr_p, 0);
5138 rhs = TREE_OPERAND (*expr_p, 1);
5139 code = TREE_CODE (lhs);
5140 lhs = TREE_OPERAND (lhs, 0);
5142 ocode = code == REALPART_EXPR ? IMAGPART_EXPR : REALPART_EXPR;
5143 other = build1 (ocode, TREE_TYPE (rhs), lhs);
5144 TREE_NO_WARNING (other) = 1;
5145 other = get_formal_tmp_var (other, pre_p);
5147 realpart = code == REALPART_EXPR ? rhs : other;
5148 imagpart = code == REALPART_EXPR ? other : rhs;
5150 if (TREE_CONSTANT (realpart) && TREE_CONSTANT (imagpart))
5151 new_rhs = build_complex (TREE_TYPE (lhs), realpart, imagpart);
5152 else
5153 new_rhs = build2 (COMPLEX_EXPR, TREE_TYPE (lhs), realpart, imagpart);
5155 gimplify_seq_add_stmt (pre_p, gimple_build_assign (lhs, new_rhs));
5156 *expr_p = (want_value) ? rhs : NULL_TREE;
5158 return GS_ALL_DONE;
5161 /* Gimplify the MODIFY_EXPR node pointed to by EXPR_P.
5163 modify_expr
5164 : varname '=' rhs
5165 | '*' ID '=' rhs
5167 PRE_P points to the list where side effects that must happen before
5168 *EXPR_P should be stored.
5170 POST_P points to the list where side effects that must happen after
5171 *EXPR_P should be stored.
5173 WANT_VALUE is nonzero iff we want to use the value of this expression
5174 in another expression. */
5176 static enum gimplify_status
5177 gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
5178 bool want_value)
5180 tree *from_p = &TREE_OPERAND (*expr_p, 1);
5181 tree *to_p = &TREE_OPERAND (*expr_p, 0);
5182 enum gimplify_status ret = GS_UNHANDLED;
5183 gimple *assign;
5184 location_t loc = EXPR_LOCATION (*expr_p);
5185 gimple_stmt_iterator gsi;
5187 gcc_assert (TREE_CODE (*expr_p) == MODIFY_EXPR
5188 || TREE_CODE (*expr_p) == INIT_EXPR);
5190 /* Trying to simplify a clobber using normal logic doesn't work,
5191 so handle it here. */
5192 if (TREE_CLOBBER_P (*from_p))
5194 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
5195 if (ret == GS_ERROR)
5196 return ret;
5197 gcc_assert (!want_value
5198 && (TREE_CODE (*to_p) == VAR_DECL
5199 || TREE_CODE (*to_p) == MEM_REF));
5200 gimplify_seq_add_stmt (pre_p, gimple_build_assign (*to_p, *from_p));
5201 *expr_p = NULL;
5202 return GS_ALL_DONE;
5205 /* Insert pointer conversions required by the middle-end that are not
5206 required by the frontend. This fixes middle-end type checking for
5207 for example gcc.dg/redecl-6.c. */
5208 if (POINTER_TYPE_P (TREE_TYPE (*to_p)))
5210 STRIP_USELESS_TYPE_CONVERSION (*from_p);
5211 if (!useless_type_conversion_p (TREE_TYPE (*to_p), TREE_TYPE (*from_p)))
5212 *from_p = fold_convert_loc (loc, TREE_TYPE (*to_p), *from_p);
5215 /* See if any simplifications can be done based on what the RHS is. */
5216 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
5217 want_value);
5218 if (ret != GS_UNHANDLED)
5219 return ret;
5221 /* For zero sized types only gimplify the left hand side and right hand
5222 side as statements and throw away the assignment. Do this after
5223 gimplify_modify_expr_rhs so we handle TARGET_EXPRs of addressable
5224 types properly. */
5225 if (zero_sized_type (TREE_TYPE (*from_p)) && !want_value)
5227 gimplify_stmt (from_p, pre_p);
5228 gimplify_stmt (to_p, pre_p);
5229 *expr_p = NULL_TREE;
5230 return GS_ALL_DONE;
5233 /* If the value being copied is of variable width, compute the length
5234 of the copy into a WITH_SIZE_EXPR. Note that we need to do this
5235 before gimplifying any of the operands so that we can resolve any
5236 PLACEHOLDER_EXPRs in the size. Also note that the RTL expander uses
5237 the size of the expression to be copied, not of the destination, so
5238 that is what we must do here. */
5239 maybe_with_size_expr (from_p);
5241 /* As a special case, we have to temporarily allow for assignments
5242 with a CALL_EXPR on the RHS. Since in GIMPLE a function call is
5243 a toplevel statement, when gimplifying the GENERIC expression
5244 MODIFY_EXPR <a, CALL_EXPR <foo>>, we cannot create the tuple
5245 GIMPLE_ASSIGN <a, GIMPLE_CALL <foo>>.
5247 Instead, we need to create the tuple GIMPLE_CALL <a, foo>. To
5248 prevent gimplify_expr from trying to create a new temporary for
5249 foo's LHS, we tell it that it should only gimplify until it
5250 reaches the CALL_EXPR. On return from gimplify_expr, the newly
5251 created GIMPLE_CALL <foo> will be the last statement in *PRE_P
5252 and all we need to do here is set 'a' to be its LHS. */
5254 /* Gimplify the RHS first for C++17 and bug 71104. */
5255 gimple_predicate initial_pred = initial_rhs_predicate_for (*to_p);
5256 ret = gimplify_expr (from_p, pre_p, post_p, initial_pred, fb_rvalue);
5257 if (ret == GS_ERROR)
5258 return ret;
5260 /* Then gimplify the LHS. */
5261 /* If we gimplified the RHS to a CALL_EXPR and that call may return
5262 twice we have to make sure to gimplify into non-SSA as otherwise
5263 the abnormal edge added later will make those defs not dominate
5264 their uses.
5265 ??? Technically this applies only to the registers used in the
5266 resulting non-register *TO_P. */
5267 bool saved_into_ssa = gimplify_ctxp->into_ssa;
5268 if (saved_into_ssa
5269 && TREE_CODE (*from_p) == CALL_EXPR
5270 && call_expr_flags (*from_p) & ECF_RETURNS_TWICE)
5271 gimplify_ctxp->into_ssa = false;
5272 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
5273 gimplify_ctxp->into_ssa = saved_into_ssa;
5274 if (ret == GS_ERROR)
5275 return ret;
5277 /* Now that the LHS is gimplified, re-gimplify the RHS if our initial
5278 guess for the predicate was wrong. */
5279 gimple_predicate final_pred = rhs_predicate_for (*to_p);
5280 if (final_pred != initial_pred)
5282 ret = gimplify_expr (from_p, pre_p, post_p, final_pred, fb_rvalue);
5283 if (ret == GS_ERROR)
5284 return ret;
5287 /* In case of va_arg internal fn wrappped in a WITH_SIZE_EXPR, add the type
5288 size as argument to the call. */
5289 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
5291 tree call = TREE_OPERAND (*from_p, 0);
5292 tree vlasize = TREE_OPERAND (*from_p, 1);
5294 if (TREE_CODE (call) == CALL_EXPR
5295 && CALL_EXPR_IFN (call) == IFN_VA_ARG)
5297 int nargs = call_expr_nargs (call);
5298 tree type = TREE_TYPE (call);
5299 tree ap = CALL_EXPR_ARG (call, 0);
5300 tree tag = CALL_EXPR_ARG (call, 1);
5301 tree aptag = CALL_EXPR_ARG (call, 2);
5302 tree newcall = build_call_expr_internal_loc (EXPR_LOCATION (call),
5303 IFN_VA_ARG, type,
5304 nargs + 1, ap, tag,
5305 aptag, vlasize);
5306 TREE_OPERAND (*from_p, 0) = newcall;
5310 /* Now see if the above changed *from_p to something we handle specially. */
5311 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
5312 want_value);
5313 if (ret != GS_UNHANDLED)
5314 return ret;
5316 /* If we've got a variable sized assignment between two lvalues (i.e. does
5317 not involve a call), then we can make things a bit more straightforward
5318 by converting the assignment to memcpy or memset. */
5319 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
5321 tree from = TREE_OPERAND (*from_p, 0);
5322 tree size = TREE_OPERAND (*from_p, 1);
5324 if (TREE_CODE (from) == CONSTRUCTOR)
5325 return gimplify_modify_expr_to_memset (expr_p, size, want_value, pre_p);
5327 if (is_gimple_addressable (from))
5329 *from_p = from;
5330 return gimplify_modify_expr_to_memcpy (expr_p, size, want_value,
5331 pre_p);
5335 /* Transform partial stores to non-addressable complex variables into
5336 total stores. This allows us to use real instead of virtual operands
5337 for these variables, which improves optimization. */
5338 if ((TREE_CODE (*to_p) == REALPART_EXPR
5339 || TREE_CODE (*to_p) == IMAGPART_EXPR)
5340 && is_gimple_reg (TREE_OPERAND (*to_p, 0)))
5341 return gimplify_modify_expr_complex_part (expr_p, pre_p, want_value);
5343 /* Try to alleviate the effects of the gimplification creating artificial
5344 temporaries (see for example is_gimple_reg_rhs) on the debug info, but
5345 make sure not to create DECL_DEBUG_EXPR links across functions. */
5346 if (!gimplify_ctxp->into_ssa
5347 && TREE_CODE (*from_p) == VAR_DECL
5348 && DECL_IGNORED_P (*from_p)
5349 && DECL_P (*to_p)
5350 && !DECL_IGNORED_P (*to_p)
5351 && decl_function_context (*to_p) == current_function_decl)
5353 if (!DECL_NAME (*from_p) && DECL_NAME (*to_p))
5354 DECL_NAME (*from_p)
5355 = create_tmp_var_name (IDENTIFIER_POINTER (DECL_NAME (*to_p)));
5356 DECL_HAS_DEBUG_EXPR_P (*from_p) = 1;
5357 SET_DECL_DEBUG_EXPR (*from_p, *to_p);
5360 if (want_value && TREE_THIS_VOLATILE (*to_p))
5361 *from_p = get_initialized_tmp_var (*from_p, pre_p, post_p);
5363 if (TREE_CODE (*from_p) == CALL_EXPR)
5365 /* Since the RHS is a CALL_EXPR, we need to create a GIMPLE_CALL
5366 instead of a GIMPLE_ASSIGN. */
5367 gcall *call_stmt;
5368 if (CALL_EXPR_FN (*from_p) == NULL_TREE)
5370 /* Gimplify internal functions created in the FEs. */
5371 int nargs = call_expr_nargs (*from_p), i;
5372 enum internal_fn ifn = CALL_EXPR_IFN (*from_p);
5373 auto_vec<tree> vargs (nargs);
5375 for (i = 0; i < nargs; i++)
5377 gimplify_arg (&CALL_EXPR_ARG (*from_p, i), pre_p,
5378 EXPR_LOCATION (*from_p));
5379 vargs.quick_push (CALL_EXPR_ARG (*from_p, i));
5381 call_stmt = gimple_build_call_internal_vec (ifn, vargs);
5382 gimple_set_location (call_stmt, EXPR_LOCATION (*expr_p));
5384 else
5386 tree fnptrtype = TREE_TYPE (CALL_EXPR_FN (*from_p));
5387 CALL_EXPR_FN (*from_p) = TREE_OPERAND (CALL_EXPR_FN (*from_p), 0);
5388 STRIP_USELESS_TYPE_CONVERSION (CALL_EXPR_FN (*from_p));
5389 tree fndecl = get_callee_fndecl (*from_p);
5390 if (fndecl
5391 && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
5392 && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT
5393 && call_expr_nargs (*from_p) == 3)
5394 call_stmt = gimple_build_call_internal (IFN_BUILTIN_EXPECT, 3,
5395 CALL_EXPR_ARG (*from_p, 0),
5396 CALL_EXPR_ARG (*from_p, 1),
5397 CALL_EXPR_ARG (*from_p, 2));
5398 else
5400 call_stmt = gimple_build_call_from_tree (*from_p);
5401 gimple_call_set_fntype (call_stmt, TREE_TYPE (fnptrtype));
5404 notice_special_calls (call_stmt);
5405 if (!gimple_call_noreturn_p (call_stmt) || !should_remove_lhs_p (*to_p))
5406 gimple_call_set_lhs (call_stmt, *to_p);
5407 else if (TREE_CODE (*to_p) == SSA_NAME)
5408 /* The above is somewhat premature, avoid ICEing later for a
5409 SSA name w/o a definition. We may have uses in the GIMPLE IL.
5410 ??? This doesn't make it a default-def. */
5411 SSA_NAME_DEF_STMT (*to_p) = gimple_build_nop ();
5412 assign = call_stmt;
5414 else
5416 assign = gimple_build_assign (*to_p, *from_p);
5417 gimple_set_location (assign, EXPR_LOCATION (*expr_p));
5418 if (COMPARISON_CLASS_P (*from_p))
5419 gimple_set_no_warning (assign, TREE_NO_WARNING (*from_p));
5422 if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p))
5424 /* We should have got an SSA name from the start. */
5425 gcc_assert (TREE_CODE (*to_p) == SSA_NAME
5426 || ! gimple_in_ssa_p (cfun));
5429 gimplify_seq_add_stmt (pre_p, assign);
5430 gsi = gsi_last (*pre_p);
5431 maybe_fold_stmt (&gsi);
5433 if (want_value)
5435 *expr_p = TREE_THIS_VOLATILE (*to_p) ? *from_p : unshare_expr (*to_p);
5436 return GS_OK;
5438 else
5439 *expr_p = NULL;
5441 return GS_ALL_DONE;
5444 /* Gimplify a comparison between two variable-sized objects. Do this
5445 with a call to BUILT_IN_MEMCMP. */
5447 static enum gimplify_status
5448 gimplify_variable_sized_compare (tree *expr_p)
5450 location_t loc = EXPR_LOCATION (*expr_p);
5451 tree op0 = TREE_OPERAND (*expr_p, 0);
5452 tree op1 = TREE_OPERAND (*expr_p, 1);
5453 tree t, arg, dest, src, expr;
5455 arg = TYPE_SIZE_UNIT (TREE_TYPE (op0));
5456 arg = unshare_expr (arg);
5457 arg = SUBSTITUTE_PLACEHOLDER_IN_EXPR (arg, op0);
5458 src = build_fold_addr_expr_loc (loc, op1);
5459 dest = build_fold_addr_expr_loc (loc, op0);
5460 t = builtin_decl_implicit (BUILT_IN_MEMCMP);
5461 t = build_call_expr_loc (loc, t, 3, dest, src, arg);
5463 expr
5464 = build2 (TREE_CODE (*expr_p), TREE_TYPE (*expr_p), t, integer_zero_node);
5465 SET_EXPR_LOCATION (expr, loc);
5466 *expr_p = expr;
5468 return GS_OK;
5471 /* Gimplify a comparison between two aggregate objects of integral scalar
5472 mode as a comparison between the bitwise equivalent scalar values. */
5474 static enum gimplify_status
5475 gimplify_scalar_mode_aggregate_compare (tree *expr_p)
5477 location_t loc = EXPR_LOCATION (*expr_p);
5478 tree op0 = TREE_OPERAND (*expr_p, 0);
5479 tree op1 = TREE_OPERAND (*expr_p, 1);
5481 tree type = TREE_TYPE (op0);
5482 tree scalar_type = lang_hooks.types.type_for_mode (TYPE_MODE (type), 1);
5484 op0 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op0);
5485 op1 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op1);
5487 *expr_p
5488 = fold_build2_loc (loc, TREE_CODE (*expr_p), TREE_TYPE (*expr_p), op0, op1);
5490 return GS_OK;
5493 /* Gimplify an expression sequence. This function gimplifies each
5494 expression and rewrites the original expression with the last
5495 expression of the sequence in GIMPLE form.
5497 PRE_P points to the list where the side effects for all the
5498 expressions in the sequence will be emitted.
5500 WANT_VALUE is true when the result of the last COMPOUND_EXPR is used. */
5502 static enum gimplify_status
5503 gimplify_compound_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
5505 tree t = *expr_p;
5509 tree *sub_p = &TREE_OPERAND (t, 0);
5511 if (TREE_CODE (*sub_p) == COMPOUND_EXPR)
5512 gimplify_compound_expr (sub_p, pre_p, false);
5513 else
5514 gimplify_stmt (sub_p, pre_p);
5516 t = TREE_OPERAND (t, 1);
5518 while (TREE_CODE (t) == COMPOUND_EXPR);
5520 *expr_p = t;
5521 if (want_value)
5522 return GS_OK;
5523 else
5525 gimplify_stmt (expr_p, pre_p);
5526 return GS_ALL_DONE;
5530 /* Gimplify a SAVE_EXPR node. EXPR_P points to the expression to
5531 gimplify. After gimplification, EXPR_P will point to a new temporary
5532 that holds the original value of the SAVE_EXPR node.
5534 PRE_P points to the list where side effects that must happen before
5535 *EXPR_P should be stored. */
5537 static enum gimplify_status
5538 gimplify_save_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
5540 enum gimplify_status ret = GS_ALL_DONE;
5541 tree val;
5543 gcc_assert (TREE_CODE (*expr_p) == SAVE_EXPR);
5544 val = TREE_OPERAND (*expr_p, 0);
5546 /* If the SAVE_EXPR has not been resolved, then evaluate it once. */
5547 if (!SAVE_EXPR_RESOLVED_P (*expr_p))
5549 /* The operand may be a void-valued expression such as SAVE_EXPRs
5550 generated by the Java frontend for class initialization. It is
5551 being executed only for its side-effects. */
5552 if (TREE_TYPE (val) == void_type_node)
5554 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
5555 is_gimple_stmt, fb_none);
5556 val = NULL;
5558 else
5559 /* The temporary may not be an SSA name as later abnormal and EH
5560 control flow may invalidate use/def domination. */
5561 val = get_initialized_tmp_var (val, pre_p, post_p, false);
5563 TREE_OPERAND (*expr_p, 0) = val;
5564 SAVE_EXPR_RESOLVED_P (*expr_p) = 1;
5567 *expr_p = val;
5569 return ret;
5572 /* Rewrite the ADDR_EXPR node pointed to by EXPR_P
5574 unary_expr
5575 : ...
5576 | '&' varname
5579 PRE_P points to the list where side effects that must happen before
5580 *EXPR_P should be stored.
5582 POST_P points to the list where side effects that must happen after
5583 *EXPR_P should be stored. */
5585 static enum gimplify_status
5586 gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
5588 tree expr = *expr_p;
5589 tree op0 = TREE_OPERAND (expr, 0);
5590 enum gimplify_status ret;
5591 location_t loc = EXPR_LOCATION (*expr_p);
5593 switch (TREE_CODE (op0))
5595 case INDIRECT_REF:
5596 do_indirect_ref:
5597 /* Check if we are dealing with an expression of the form '&*ptr'.
5598 While the front end folds away '&*ptr' into 'ptr', these
5599 expressions may be generated internally by the compiler (e.g.,
5600 builtins like __builtin_va_end). */
5601 /* Caution: the silent array decomposition semantics we allow for
5602 ADDR_EXPR means we can't always discard the pair. */
5603 /* Gimplification of the ADDR_EXPR operand may drop
5604 cv-qualification conversions, so make sure we add them if
5605 needed. */
5607 tree op00 = TREE_OPERAND (op0, 0);
5608 tree t_expr = TREE_TYPE (expr);
5609 tree t_op00 = TREE_TYPE (op00);
5611 if (!useless_type_conversion_p (t_expr, t_op00))
5612 op00 = fold_convert_loc (loc, TREE_TYPE (expr), op00);
5613 *expr_p = op00;
5614 ret = GS_OK;
5616 break;
5618 case VIEW_CONVERT_EXPR:
5619 /* Take the address of our operand and then convert it to the type of
5620 this ADDR_EXPR.
5622 ??? The interactions of VIEW_CONVERT_EXPR and aliasing is not at
5623 all clear. The impact of this transformation is even less clear. */
5625 /* If the operand is a useless conversion, look through it. Doing so
5626 guarantees that the ADDR_EXPR and its operand will remain of the
5627 same type. */
5628 if (tree_ssa_useless_type_conversion (TREE_OPERAND (op0, 0)))
5629 op0 = TREE_OPERAND (op0, 0);
5631 *expr_p = fold_convert_loc (loc, TREE_TYPE (expr),
5632 build_fold_addr_expr_loc (loc,
5633 TREE_OPERAND (op0, 0)));
5634 ret = GS_OK;
5635 break;
5637 case MEM_REF:
5638 if (integer_zerop (TREE_OPERAND (op0, 1)))
5639 goto do_indirect_ref;
5641 /* fall through */
5643 default:
5644 /* If we see a call to a declared builtin or see its address
5645 being taken (we can unify those cases here) then we can mark
5646 the builtin for implicit generation by GCC. */
5647 if (TREE_CODE (op0) == FUNCTION_DECL
5648 && DECL_BUILT_IN_CLASS (op0) == BUILT_IN_NORMAL
5649 && builtin_decl_declared_p (DECL_FUNCTION_CODE (op0)))
5650 set_builtin_decl_implicit_p (DECL_FUNCTION_CODE (op0), true);
5652 /* We use fb_either here because the C frontend sometimes takes
5653 the address of a call that returns a struct; see
5654 gcc.dg/c99-array-lval-1.c. The gimplifier will correctly make
5655 the implied temporary explicit. */
5657 /* Make the operand addressable. */
5658 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, post_p,
5659 is_gimple_addressable, fb_either);
5660 if (ret == GS_ERROR)
5661 break;
5663 /* Then mark it. Beware that it may not be possible to do so directly
5664 if a temporary has been created by the gimplification. */
5665 prepare_gimple_addressable (&TREE_OPERAND (expr, 0), pre_p);
5667 op0 = TREE_OPERAND (expr, 0);
5669 /* For various reasons, the gimplification of the expression
5670 may have made a new INDIRECT_REF. */
5671 if (TREE_CODE (op0) == INDIRECT_REF)
5672 goto do_indirect_ref;
5674 mark_addressable (TREE_OPERAND (expr, 0));
5676 /* The FEs may end up building ADDR_EXPRs early on a decl with
5677 an incomplete type. Re-build ADDR_EXPRs in canonical form
5678 here. */
5679 if (!types_compatible_p (TREE_TYPE (op0), TREE_TYPE (TREE_TYPE (expr))))
5680 *expr_p = build_fold_addr_expr (op0);
5682 /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly. */
5683 recompute_tree_invariant_for_addr_expr (*expr_p);
5685 /* If we re-built the ADDR_EXPR add a conversion to the original type
5686 if required. */
5687 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
5688 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
5690 break;
5693 return ret;
5696 /* Gimplify the operands of an ASM_EXPR. Input operands should be a gimple
5697 value; output operands should be a gimple lvalue. */
5699 static enum gimplify_status
5700 gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
5702 tree expr;
5703 int noutputs;
5704 const char **oconstraints;
5705 int i;
5706 tree link;
5707 const char *constraint;
5708 bool allows_mem, allows_reg, is_inout;
5709 enum gimplify_status ret, tret;
5710 gasm *stmt;
5711 vec<tree, va_gc> *inputs;
5712 vec<tree, va_gc> *outputs;
5713 vec<tree, va_gc> *clobbers;
5714 vec<tree, va_gc> *labels;
5715 tree link_next;
5717 expr = *expr_p;
5718 noutputs = list_length (ASM_OUTPUTS (expr));
5719 oconstraints = (const char **) alloca ((noutputs) * sizeof (const char *));
5721 inputs = NULL;
5722 outputs = NULL;
5723 clobbers = NULL;
5724 labels = NULL;
5726 ret = GS_ALL_DONE;
5727 link_next = NULL_TREE;
5728 for (i = 0, link = ASM_OUTPUTS (expr); link; ++i, link = link_next)
5730 bool ok;
5731 size_t constraint_len;
5733 link_next = TREE_CHAIN (link);
5735 oconstraints[i]
5736 = constraint
5737 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
5738 constraint_len = strlen (constraint);
5739 if (constraint_len == 0)
5740 continue;
5742 ok = parse_output_constraint (&constraint, i, 0, 0,
5743 &allows_mem, &allows_reg, &is_inout);
5744 if (!ok)
5746 ret = GS_ERROR;
5747 is_inout = false;
5750 if (!allows_reg && allows_mem)
5751 mark_addressable (TREE_VALUE (link));
5753 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
5754 is_inout ? is_gimple_min_lval : is_gimple_lvalue,
5755 fb_lvalue | fb_mayfail);
5756 if (tret == GS_ERROR)
5758 error ("invalid lvalue in asm output %d", i);
5759 ret = tret;
5762 /* If the constraint does not allow memory make sure we gimplify
5763 it to a register if it is not already but its base is. This
5764 happens for complex and vector components. */
5765 if (!allows_mem)
5767 tree op = TREE_VALUE (link);
5768 if (! is_gimple_val (op)
5769 && is_gimple_reg_type (TREE_TYPE (op))
5770 && is_gimple_reg (get_base_address (op)))
5772 tree tem = create_tmp_reg (TREE_TYPE (op));
5773 tree ass;
5774 if (is_inout)
5776 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem),
5777 tem, unshare_expr (op));
5778 gimplify_and_add (ass, pre_p);
5780 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem), op, tem);
5781 gimplify_and_add (ass, post_p);
5783 TREE_VALUE (link) = tem;
5784 tret = GS_OK;
5788 vec_safe_push (outputs, link);
5789 TREE_CHAIN (link) = NULL_TREE;
5791 if (is_inout)
5793 /* An input/output operand. To give the optimizers more
5794 flexibility, split it into separate input and output
5795 operands. */
5796 tree input;
5797 /* Buffer big enough to format a 32-bit UINT_MAX into. */
5798 char buf[11];
5800 /* Turn the in/out constraint into an output constraint. */
5801 char *p = xstrdup (constraint);
5802 p[0] = '=';
5803 TREE_VALUE (TREE_PURPOSE (link)) = build_string (constraint_len, p);
5805 /* And add a matching input constraint. */
5806 if (allows_reg)
5808 sprintf (buf, "%u", i);
5810 /* If there are multiple alternatives in the constraint,
5811 handle each of them individually. Those that allow register
5812 will be replaced with operand number, the others will stay
5813 unchanged. */
5814 if (strchr (p, ',') != NULL)
5816 size_t len = 0, buflen = strlen (buf);
5817 char *beg, *end, *str, *dst;
5819 for (beg = p + 1;;)
5821 end = strchr (beg, ',');
5822 if (end == NULL)
5823 end = strchr (beg, '\0');
5824 if ((size_t) (end - beg) < buflen)
5825 len += buflen + 1;
5826 else
5827 len += end - beg + 1;
5828 if (*end)
5829 beg = end + 1;
5830 else
5831 break;
5834 str = (char *) alloca (len);
5835 for (beg = p + 1, dst = str;;)
5837 const char *tem;
5838 bool mem_p, reg_p, inout_p;
5840 end = strchr (beg, ',');
5841 if (end)
5842 *end = '\0';
5843 beg[-1] = '=';
5844 tem = beg - 1;
5845 parse_output_constraint (&tem, i, 0, 0,
5846 &mem_p, &reg_p, &inout_p);
5847 if (dst != str)
5848 *dst++ = ',';
5849 if (reg_p)
5851 memcpy (dst, buf, buflen);
5852 dst += buflen;
5854 else
5856 if (end)
5857 len = end - beg;
5858 else
5859 len = strlen (beg);
5860 memcpy (dst, beg, len);
5861 dst += len;
5863 if (end)
5864 beg = end + 1;
5865 else
5866 break;
5868 *dst = '\0';
5869 input = build_string (dst - str, str);
5871 else
5872 input = build_string (strlen (buf), buf);
5874 else
5875 input = build_string (constraint_len - 1, constraint + 1);
5877 free (p);
5879 input = build_tree_list (build_tree_list (NULL_TREE, input),
5880 unshare_expr (TREE_VALUE (link)));
5881 ASM_INPUTS (expr) = chainon (ASM_INPUTS (expr), input);
5885 link_next = NULL_TREE;
5886 for (link = ASM_INPUTS (expr); link; ++i, link = link_next)
5888 link_next = TREE_CHAIN (link);
5889 constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
5890 parse_input_constraint (&constraint, 0, 0, noutputs, 0,
5891 oconstraints, &allows_mem, &allows_reg);
5893 /* If we can't make copies, we can only accept memory. */
5894 if (TREE_ADDRESSABLE (TREE_TYPE (TREE_VALUE (link))))
5896 if (allows_mem)
5897 allows_reg = 0;
5898 else
5900 error ("impossible constraint in %<asm%>");
5901 error ("non-memory input %d must stay in memory", i);
5902 return GS_ERROR;
5906 /* If the operand is a memory input, it should be an lvalue. */
5907 if (!allows_reg && allows_mem)
5909 tree inputv = TREE_VALUE (link);
5910 STRIP_NOPS (inputv);
5911 if (TREE_CODE (inputv) == PREDECREMENT_EXPR
5912 || TREE_CODE (inputv) == PREINCREMENT_EXPR
5913 || TREE_CODE (inputv) == POSTDECREMENT_EXPR
5914 || TREE_CODE (inputv) == POSTINCREMENT_EXPR
5915 || TREE_CODE (inputv) == MODIFY_EXPR)
5916 TREE_VALUE (link) = error_mark_node;
5917 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
5918 is_gimple_lvalue, fb_lvalue | fb_mayfail);
5919 if (tret != GS_ERROR)
5921 /* Unlike output operands, memory inputs are not guaranteed
5922 to be lvalues by the FE, and while the expressions are
5923 marked addressable there, if it is e.g. a statement
5924 expression, temporaries in it might not end up being
5925 addressable. They might be already used in the IL and thus
5926 it is too late to make them addressable now though. */
5927 tree x = TREE_VALUE (link);
5928 while (handled_component_p (x))
5929 x = TREE_OPERAND (x, 0);
5930 if (TREE_CODE (x) == MEM_REF
5931 && TREE_CODE (TREE_OPERAND (x, 0)) == ADDR_EXPR)
5932 x = TREE_OPERAND (TREE_OPERAND (x, 0), 0);
5933 if ((TREE_CODE (x) == VAR_DECL
5934 || TREE_CODE (x) == PARM_DECL
5935 || TREE_CODE (x) == RESULT_DECL)
5936 && !TREE_ADDRESSABLE (x)
5937 && is_gimple_reg (x))
5939 warning_at (EXPR_LOC_OR_LOC (TREE_VALUE (link),
5940 input_location), 0,
5941 "memory input %d is not directly addressable",
5943 prepare_gimple_addressable (&TREE_VALUE (link), pre_p);
5946 mark_addressable (TREE_VALUE (link));
5947 if (tret == GS_ERROR)
5949 error_at (EXPR_LOC_OR_LOC (TREE_VALUE (link), input_location),
5950 "memory input %d is not directly addressable", i);
5951 ret = tret;
5954 else
5956 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
5957 is_gimple_asm_val, fb_rvalue);
5958 if (tret == GS_ERROR)
5959 ret = tret;
5962 TREE_CHAIN (link) = NULL_TREE;
5963 vec_safe_push (inputs, link);
5966 link_next = NULL_TREE;
5967 for (link = ASM_CLOBBERS (expr); link; ++i, link = link_next)
5969 link_next = TREE_CHAIN (link);
5970 TREE_CHAIN (link) = NULL_TREE;
5971 vec_safe_push (clobbers, link);
5974 link_next = NULL_TREE;
5975 for (link = ASM_LABELS (expr); link; ++i, link = link_next)
5977 link_next = TREE_CHAIN (link);
5978 TREE_CHAIN (link) = NULL_TREE;
5979 vec_safe_push (labels, link);
5982 /* Do not add ASMs with errors to the gimple IL stream. */
5983 if (ret != GS_ERROR)
5985 stmt = gimple_build_asm_vec (TREE_STRING_POINTER (ASM_STRING (expr)),
5986 inputs, outputs, clobbers, labels);
5988 gimple_asm_set_volatile (stmt, ASM_VOLATILE_P (expr) || noutputs == 0);
5989 gimple_asm_set_input (stmt, ASM_INPUT_P (expr));
5991 gimplify_seq_add_stmt (pre_p, stmt);
5994 return ret;
5997 /* Gimplify a CLEANUP_POINT_EXPR. Currently this works by adding
5998 GIMPLE_WITH_CLEANUP_EXPRs to the prequeue as we encounter cleanups while
5999 gimplifying the body, and converting them to TRY_FINALLY_EXPRs when we
6000 return to this function.
6002 FIXME should we complexify the prequeue handling instead? Or use flags
6003 for all the cleanups and let the optimizer tighten them up? The current
6004 code seems pretty fragile; it will break on a cleanup within any
6005 non-conditional nesting. But any such nesting would be broken, anyway;
6006 we can't write a TRY_FINALLY_EXPR that starts inside a nesting construct
6007 and continues out of it. We can do that at the RTL level, though, so
6008 having an optimizer to tighten up try/finally regions would be a Good
6009 Thing. */
6011 static enum gimplify_status
6012 gimplify_cleanup_point_expr (tree *expr_p, gimple_seq *pre_p)
6014 gimple_stmt_iterator iter;
6015 gimple_seq body_sequence = NULL;
6017 tree temp = voidify_wrapper_expr (*expr_p, NULL);
6019 /* We only care about the number of conditions between the innermost
6020 CLEANUP_POINT_EXPR and the cleanup. So save and reset the count and
6021 any cleanups collected outside the CLEANUP_POINT_EXPR. */
6022 int old_conds = gimplify_ctxp->conditions;
6023 gimple_seq old_cleanups = gimplify_ctxp->conditional_cleanups;
6024 bool old_in_cleanup_point_expr = gimplify_ctxp->in_cleanup_point_expr;
6025 gimplify_ctxp->conditions = 0;
6026 gimplify_ctxp->conditional_cleanups = NULL;
6027 gimplify_ctxp->in_cleanup_point_expr = true;
6029 gimplify_stmt (&TREE_OPERAND (*expr_p, 0), &body_sequence);
6031 gimplify_ctxp->conditions = old_conds;
6032 gimplify_ctxp->conditional_cleanups = old_cleanups;
6033 gimplify_ctxp->in_cleanup_point_expr = old_in_cleanup_point_expr;
6035 for (iter = gsi_start (body_sequence); !gsi_end_p (iter); )
6037 gimple *wce = gsi_stmt (iter);
6039 if (gimple_code (wce) == GIMPLE_WITH_CLEANUP_EXPR)
6041 if (gsi_one_before_end_p (iter))
6043 /* Note that gsi_insert_seq_before and gsi_remove do not
6044 scan operands, unlike some other sequence mutators. */
6045 if (!gimple_wce_cleanup_eh_only (wce))
6046 gsi_insert_seq_before_without_update (&iter,
6047 gimple_wce_cleanup (wce),
6048 GSI_SAME_STMT);
6049 gsi_remove (&iter, true);
6050 break;
6052 else
6054 gtry *gtry;
6055 gimple_seq seq;
6056 enum gimple_try_flags kind;
6058 if (gimple_wce_cleanup_eh_only (wce))
6059 kind = GIMPLE_TRY_CATCH;
6060 else
6061 kind = GIMPLE_TRY_FINALLY;
6062 seq = gsi_split_seq_after (iter);
6064 gtry = gimple_build_try (seq, gimple_wce_cleanup (wce), kind);
6065 /* Do not use gsi_replace here, as it may scan operands.
6066 We want to do a simple structural modification only. */
6067 gsi_set_stmt (&iter, gtry);
6068 iter = gsi_start (gtry->eval);
6071 else
6072 gsi_next (&iter);
6075 gimplify_seq_add_seq (pre_p, body_sequence);
6076 if (temp)
6078 *expr_p = temp;
6079 return GS_OK;
6081 else
6083 *expr_p = NULL;
6084 return GS_ALL_DONE;
6088 /* Insert a cleanup marker for gimplify_cleanup_point_expr. CLEANUP
6089 is the cleanup action required. EH_ONLY is true if the cleanup should
6090 only be executed if an exception is thrown, not on normal exit. */
6092 static void
6093 gimple_push_cleanup (tree var, tree cleanup, bool eh_only, gimple_seq *pre_p)
6095 gimple *wce;
6096 gimple_seq cleanup_stmts = NULL;
6098 /* Errors can result in improperly nested cleanups. Which results in
6099 confusion when trying to resolve the GIMPLE_WITH_CLEANUP_EXPR. */
6100 if (seen_error ())
6101 return;
6103 if (gimple_conditional_context ())
6105 /* If we're in a conditional context, this is more complex. We only
6106 want to run the cleanup if we actually ran the initialization that
6107 necessitates it, but we want to run it after the end of the
6108 conditional context. So we wrap the try/finally around the
6109 condition and use a flag to determine whether or not to actually
6110 run the destructor. Thus
6112 test ? f(A()) : 0
6114 becomes (approximately)
6116 flag = 0;
6117 try {
6118 if (test) { A::A(temp); flag = 1; val = f(temp); }
6119 else { val = 0; }
6120 } finally {
6121 if (flag) A::~A(temp);
6125 tree flag = create_tmp_var (boolean_type_node, "cleanup");
6126 gassign *ffalse = gimple_build_assign (flag, boolean_false_node);
6127 gassign *ftrue = gimple_build_assign (flag, boolean_true_node);
6129 cleanup = build3 (COND_EXPR, void_type_node, flag, cleanup, NULL);
6130 gimplify_stmt (&cleanup, &cleanup_stmts);
6131 wce = gimple_build_wce (cleanup_stmts);
6133 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, ffalse);
6134 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
6135 gimplify_seq_add_stmt (pre_p, ftrue);
6137 /* Because of this manipulation, and the EH edges that jump
6138 threading cannot redirect, the temporary (VAR) will appear
6139 to be used uninitialized. Don't warn. */
6140 TREE_NO_WARNING (var) = 1;
6142 else
6144 gimplify_stmt (&cleanup, &cleanup_stmts);
6145 wce = gimple_build_wce (cleanup_stmts);
6146 gimple_wce_set_cleanup_eh_only (wce, eh_only);
6147 gimplify_seq_add_stmt (pre_p, wce);
6151 /* Gimplify a TARGET_EXPR which doesn't appear on the rhs of an INIT_EXPR. */
6153 static enum gimplify_status
6154 gimplify_target_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6156 tree targ = *expr_p;
6157 tree temp = TARGET_EXPR_SLOT (targ);
6158 tree init = TARGET_EXPR_INITIAL (targ);
6159 enum gimplify_status ret;
6161 if (init)
6163 tree cleanup = NULL_TREE;
6165 /* TARGET_EXPR temps aren't part of the enclosing block, so add it
6166 to the temps list. Handle also variable length TARGET_EXPRs. */
6167 if (TREE_CODE (DECL_SIZE (temp)) != INTEGER_CST)
6169 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (temp)))
6170 gimplify_type_sizes (TREE_TYPE (temp), pre_p);
6171 gimplify_vla_decl (temp, pre_p);
6173 else
6174 gimple_add_tmp_var (temp);
6176 /* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the
6177 expression is supposed to initialize the slot. */
6178 if (VOID_TYPE_P (TREE_TYPE (init)))
6179 ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
6180 else
6182 tree init_expr = build2 (INIT_EXPR, void_type_node, temp, init);
6183 init = init_expr;
6184 ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
6185 init = NULL;
6186 ggc_free (init_expr);
6188 if (ret == GS_ERROR)
6190 /* PR c++/28266 Make sure this is expanded only once. */
6191 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
6192 return GS_ERROR;
6194 if (init)
6195 gimplify_and_add (init, pre_p);
6197 /* If needed, push the cleanup for the temp. */
6198 if (TARGET_EXPR_CLEANUP (targ))
6200 if (CLEANUP_EH_ONLY (targ))
6201 gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ),
6202 CLEANUP_EH_ONLY (targ), pre_p);
6203 else
6204 cleanup = TARGET_EXPR_CLEANUP (targ);
6207 /* Add a clobber for the temporary going out of scope, like
6208 gimplify_bind_expr. */
6209 if (gimplify_ctxp->in_cleanup_point_expr
6210 && needs_to_live_in_memory (temp)
6211 && flag_stack_reuse == SR_ALL)
6213 tree clobber = build_constructor (TREE_TYPE (temp),
6214 NULL);
6215 TREE_THIS_VOLATILE (clobber) = true;
6216 clobber = build2 (MODIFY_EXPR, TREE_TYPE (temp), temp, clobber);
6217 if (cleanup)
6218 cleanup = build2 (COMPOUND_EXPR, void_type_node, cleanup,
6219 clobber);
6220 else
6221 cleanup = clobber;
6224 if (cleanup)
6225 gimple_push_cleanup (temp, cleanup, false, pre_p);
6227 /* Only expand this once. */
6228 TREE_OPERAND (targ, 3) = init;
6229 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
6231 else
6232 /* We should have expanded this before. */
6233 gcc_assert (DECL_SEEN_IN_BIND_EXPR_P (temp));
6235 *expr_p = temp;
6236 return GS_OK;
6239 /* Gimplification of expression trees. */
6241 /* Gimplify an expression which appears at statement context. The
6242 corresponding GIMPLE statements are added to *SEQ_P. If *SEQ_P is
6243 NULL, a new sequence is allocated.
6245 Return true if we actually added a statement to the queue. */
6247 bool
6248 gimplify_stmt (tree *stmt_p, gimple_seq *seq_p)
6250 gimple_seq_node last;
6252 last = gimple_seq_last (*seq_p);
6253 gimplify_expr (stmt_p, seq_p, NULL, is_gimple_stmt, fb_none);
6254 return last != gimple_seq_last (*seq_p);
6257 /* Add FIRSTPRIVATE entries for DECL in the OpenMP the surrounding parallels
6258 to CTX. If entries already exist, force them to be some flavor of private.
6259 If there is no enclosing parallel, do nothing. */
6261 void
6262 omp_firstprivatize_variable (struct gimplify_omp_ctx *ctx, tree decl)
6264 splay_tree_node n;
6266 if (decl == NULL || !DECL_P (decl) || ctx->region_type == ORT_NONE)
6267 return;
6271 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
6272 if (n != NULL)
6274 if (n->value & GOVD_SHARED)
6275 n->value = GOVD_FIRSTPRIVATE | (n->value & GOVD_SEEN);
6276 else if (n->value & GOVD_MAP)
6277 n->value |= GOVD_MAP_TO_ONLY;
6278 else
6279 return;
6281 else if ((ctx->region_type & ORT_TARGET) != 0)
6283 if (ctx->target_map_scalars_firstprivate)
6284 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
6285 else
6286 omp_add_variable (ctx, decl, GOVD_MAP | GOVD_MAP_TO_ONLY);
6288 else if (ctx->region_type != ORT_WORKSHARE
6289 && ctx->region_type != ORT_SIMD
6290 && ctx->region_type != ORT_ACC
6291 && !(ctx->region_type & ORT_TARGET_DATA))
6292 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
6294 ctx = ctx->outer_context;
6296 while (ctx);
6299 /* Similarly for each of the type sizes of TYPE. */
6301 static void
6302 omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type)
6304 if (type == NULL || type == error_mark_node)
6305 return;
6306 type = TYPE_MAIN_VARIANT (type);
6308 if (ctx->privatized_types->add (type))
6309 return;
6311 switch (TREE_CODE (type))
6313 case INTEGER_TYPE:
6314 case ENUMERAL_TYPE:
6315 case BOOLEAN_TYPE:
6316 case REAL_TYPE:
6317 case FIXED_POINT_TYPE:
6318 omp_firstprivatize_variable (ctx, TYPE_MIN_VALUE (type));
6319 omp_firstprivatize_variable (ctx, TYPE_MAX_VALUE (type));
6320 break;
6322 case ARRAY_TYPE:
6323 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
6324 omp_firstprivatize_type_sizes (ctx, TYPE_DOMAIN (type));
6325 break;
6327 case RECORD_TYPE:
6328 case UNION_TYPE:
6329 case QUAL_UNION_TYPE:
6331 tree field;
6332 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
6333 if (TREE_CODE (field) == FIELD_DECL)
6335 omp_firstprivatize_variable (ctx, DECL_FIELD_OFFSET (field));
6336 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (field));
6339 break;
6341 case POINTER_TYPE:
6342 case REFERENCE_TYPE:
6343 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
6344 break;
6346 default:
6347 break;
6350 omp_firstprivatize_variable (ctx, TYPE_SIZE (type));
6351 omp_firstprivatize_variable (ctx, TYPE_SIZE_UNIT (type));
6352 lang_hooks.types.omp_firstprivatize_type_sizes (ctx, type);
6355 /* Add an entry for DECL in the OMP context CTX with FLAGS. */
6357 static void
6358 omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
6360 splay_tree_node n;
6361 unsigned int nflags;
6362 tree t;
6364 if (error_operand_p (decl) || ctx->region_type == ORT_NONE)
6365 return;
6367 /* Never elide decls whose type has TREE_ADDRESSABLE set. This means
6368 there are constructors involved somewhere. */
6369 if (TREE_ADDRESSABLE (TREE_TYPE (decl))
6370 || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
6371 flags |= GOVD_SEEN;
6373 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
6374 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
6376 /* We shouldn't be re-adding the decl with the same data
6377 sharing class. */
6378 gcc_assert ((n->value & GOVD_DATA_SHARE_CLASS & flags) == 0);
6379 nflags = n->value | flags;
6380 /* The only combination of data sharing classes we should see is
6381 FIRSTPRIVATE and LASTPRIVATE. However, OpenACC permits
6382 reduction variables to be used in data sharing clauses. */
6383 gcc_assert ((ctx->region_type & ORT_ACC) != 0
6384 || ((nflags & GOVD_DATA_SHARE_CLASS)
6385 == (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE))
6386 || (flags & GOVD_DATA_SHARE_CLASS) == 0);
6387 n->value = nflags;
6388 return;
6391 /* When adding a variable-sized variable, we have to handle all sorts
6392 of additional bits of data: the pointer replacement variable, and
6393 the parameters of the type. */
6394 if (DECL_SIZE (decl) && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
6396 /* Add the pointer replacement variable as PRIVATE if the variable
6397 replacement is private, else FIRSTPRIVATE since we'll need the
6398 address of the original variable either for SHARED, or for the
6399 copy into or out of the context. */
6400 if (!(flags & GOVD_LOCAL))
6402 if (flags & GOVD_MAP)
6403 nflags = GOVD_MAP | GOVD_MAP_TO_ONLY | GOVD_EXPLICIT;
6404 else if (flags & GOVD_PRIVATE)
6405 nflags = GOVD_PRIVATE;
6406 else if ((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
6407 && (flags & GOVD_FIRSTPRIVATE))
6408 nflags = GOVD_PRIVATE | GOVD_EXPLICIT;
6409 else
6410 nflags = GOVD_FIRSTPRIVATE;
6411 nflags |= flags & GOVD_SEEN;
6412 t = DECL_VALUE_EXPR (decl);
6413 gcc_assert (TREE_CODE (t) == INDIRECT_REF);
6414 t = TREE_OPERAND (t, 0);
6415 gcc_assert (DECL_P (t));
6416 omp_add_variable (ctx, t, nflags);
6419 /* Add all of the variable and type parameters (which should have
6420 been gimplified to a formal temporary) as FIRSTPRIVATE. */
6421 omp_firstprivatize_variable (ctx, DECL_SIZE_UNIT (decl));
6422 omp_firstprivatize_variable (ctx, DECL_SIZE (decl));
6423 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
6425 /* The variable-sized variable itself is never SHARED, only some form
6426 of PRIVATE. The sharing would take place via the pointer variable
6427 which we remapped above. */
6428 if (flags & GOVD_SHARED)
6429 flags = GOVD_PRIVATE | GOVD_DEBUG_PRIVATE
6430 | (flags & (GOVD_SEEN | GOVD_EXPLICIT));
6432 /* We're going to make use of the TYPE_SIZE_UNIT at least in the
6433 alloca statement we generate for the variable, so make sure it
6434 is available. This isn't automatically needed for the SHARED
6435 case, since we won't be allocating local storage then.
6436 For local variables TYPE_SIZE_UNIT might not be gimplified yet,
6437 in this case omp_notice_variable will be called later
6438 on when it is gimplified. */
6439 else if (! (flags & (GOVD_LOCAL | GOVD_MAP))
6440 && DECL_P (TYPE_SIZE_UNIT (TREE_TYPE (decl))))
6441 omp_notice_variable (ctx, TYPE_SIZE_UNIT (TREE_TYPE (decl)), true);
6443 else if ((flags & (GOVD_MAP | GOVD_LOCAL)) == 0
6444 && lang_hooks.decls.omp_privatize_by_reference (decl))
6446 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
6448 /* Similar to the direct variable sized case above, we'll need the
6449 size of references being privatized. */
6450 if ((flags & GOVD_SHARED) == 0)
6452 t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
6453 if (DECL_P (t))
6454 omp_notice_variable (ctx, t, true);
6458 if (n != NULL)
6459 n->value |= flags;
6460 else
6461 splay_tree_insert (ctx->variables, (splay_tree_key)decl, flags);
6463 /* For reductions clauses in OpenACC loop directives, by default create a
6464 copy clause on the enclosing parallel construct for carrying back the
6465 results. */
6466 if (ctx->region_type == ORT_ACC && (flags & GOVD_REDUCTION))
6468 struct gimplify_omp_ctx *outer_ctx = ctx->outer_context;
6469 while (outer_ctx)
6471 n = splay_tree_lookup (outer_ctx->variables, (splay_tree_key)decl);
6472 if (n != NULL)
6474 /* Ignore local variables and explicitly declared clauses. */
6475 if (n->value & (GOVD_LOCAL | GOVD_EXPLICIT))
6476 break;
6477 else if (outer_ctx->region_type == ORT_ACC_KERNELS)
6479 /* According to the OpenACC spec, such a reduction variable
6480 should already have a copy map on a kernels construct,
6481 verify that here. */
6482 gcc_assert (!(n->value & GOVD_FIRSTPRIVATE)
6483 && (n->value & GOVD_MAP));
6485 else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
6487 /* Remove firstprivate and make it a copy map. */
6488 n->value &= ~GOVD_FIRSTPRIVATE;
6489 n->value |= GOVD_MAP;
6492 else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
6494 splay_tree_insert (outer_ctx->variables, (splay_tree_key)decl,
6495 GOVD_MAP | GOVD_SEEN);
6496 break;
6498 outer_ctx = outer_ctx->outer_context;
6503 /* Notice a threadprivate variable DECL used in OMP context CTX.
6504 This just prints out diagnostics about threadprivate variable uses
6505 in untied tasks. If DECL2 is non-NULL, prevent this warning
6506 on that variable. */
6508 static bool
6509 omp_notice_threadprivate_variable (struct gimplify_omp_ctx *ctx, tree decl,
6510 tree decl2)
6512 splay_tree_node n;
6513 struct gimplify_omp_ctx *octx;
6515 for (octx = ctx; octx; octx = octx->outer_context)
6516 if ((octx->region_type & ORT_TARGET) != 0)
6518 n = splay_tree_lookup (octx->variables, (splay_tree_key)decl);
6519 if (n == NULL)
6521 error ("threadprivate variable %qE used in target region",
6522 DECL_NAME (decl));
6523 error_at (octx->location, "enclosing target region");
6524 splay_tree_insert (octx->variables, (splay_tree_key)decl, 0);
6526 if (decl2)
6527 splay_tree_insert (octx->variables, (splay_tree_key)decl2, 0);
6530 if (ctx->region_type != ORT_UNTIED_TASK)
6531 return false;
6532 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
6533 if (n == NULL)
6535 error ("threadprivate variable %qE used in untied task",
6536 DECL_NAME (decl));
6537 error_at (ctx->location, "enclosing task");
6538 splay_tree_insert (ctx->variables, (splay_tree_key)decl, 0);
6540 if (decl2)
6541 splay_tree_insert (ctx->variables, (splay_tree_key)decl2, 0);
6542 return false;
6545 /* Return true if global var DECL is device resident. */
6547 static bool
6548 device_resident_p (tree decl)
6550 tree attr = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (decl));
6552 if (!attr)
6553 return false;
6555 for (tree t = TREE_VALUE (attr); t; t = TREE_PURPOSE (t))
6557 tree c = TREE_VALUE (t);
6558 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DEVICE_RESIDENT)
6559 return true;
6562 return false;
6565 /* Determine outer default flags for DECL mentioned in an OMP region
6566 but not declared in an enclosing clause.
6568 ??? Some compiler-generated variables (like SAVE_EXPRs) could be
6569 remapped firstprivate instead of shared. To some extent this is
6570 addressed in omp_firstprivatize_type_sizes, but not
6571 effectively. */
6573 static unsigned
6574 omp_default_clause (struct gimplify_omp_ctx *ctx, tree decl,
6575 bool in_code, unsigned flags)
6577 enum omp_clause_default_kind default_kind = ctx->default_kind;
6578 enum omp_clause_default_kind kind;
6580 kind = lang_hooks.decls.omp_predetermined_sharing (decl);
6581 if (kind != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
6582 default_kind = kind;
6584 switch (default_kind)
6586 case OMP_CLAUSE_DEFAULT_NONE:
6588 const char *rtype;
6590 if (ctx->region_type & ORT_PARALLEL)
6591 rtype = "parallel";
6592 else if (ctx->region_type & ORT_TASK)
6593 rtype = "task";
6594 else if (ctx->region_type & ORT_TEAMS)
6595 rtype = "teams";
6596 else
6597 gcc_unreachable ();
6599 error ("%qE not specified in enclosing %s",
6600 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rtype);
6601 error_at (ctx->location, "enclosing %s", rtype);
6603 /* FALLTHRU */
6604 case OMP_CLAUSE_DEFAULT_SHARED:
6605 flags |= GOVD_SHARED;
6606 break;
6607 case OMP_CLAUSE_DEFAULT_PRIVATE:
6608 flags |= GOVD_PRIVATE;
6609 break;
6610 case OMP_CLAUSE_DEFAULT_FIRSTPRIVATE:
6611 flags |= GOVD_FIRSTPRIVATE;
6612 break;
6613 case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
6614 /* decl will be either GOVD_FIRSTPRIVATE or GOVD_SHARED. */
6615 gcc_assert ((ctx->region_type & ORT_TASK) != 0);
6616 if (struct gimplify_omp_ctx *octx = ctx->outer_context)
6618 omp_notice_variable (octx, decl, in_code);
6619 for (; octx; octx = octx->outer_context)
6621 splay_tree_node n2;
6623 n2 = splay_tree_lookup (octx->variables, (splay_tree_key) decl);
6624 if ((octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)) != 0
6625 && (n2 == NULL || (n2->value & GOVD_DATA_SHARE_CLASS) == 0))
6626 continue;
6627 if (n2 && (n2->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED)
6629 flags |= GOVD_FIRSTPRIVATE;
6630 goto found_outer;
6632 if ((octx->region_type & (ORT_PARALLEL | ORT_TEAMS)) != 0)
6634 flags |= GOVD_SHARED;
6635 goto found_outer;
6640 if (TREE_CODE (decl) == PARM_DECL
6641 || (!is_global_var (decl)
6642 && DECL_CONTEXT (decl) == current_function_decl))
6643 flags |= GOVD_FIRSTPRIVATE;
6644 else
6645 flags |= GOVD_SHARED;
6646 found_outer:
6647 break;
6649 default:
6650 gcc_unreachable ();
6653 return flags;
6657 /* Determine outer default flags for DECL mentioned in an OACC region
6658 but not declared in an enclosing clause. */
6660 static unsigned
6661 oacc_default_clause (struct gimplify_omp_ctx *ctx, tree decl, unsigned flags)
6663 const char *rkind;
6664 bool on_device = false;
6665 tree type = TREE_TYPE (decl);
6667 if (lang_hooks.decls.omp_privatize_by_reference (decl))
6668 type = TREE_TYPE (type);
6670 if ((ctx->region_type & (ORT_ACC_PARALLEL | ORT_ACC_KERNELS)) != 0
6671 && is_global_var (decl)
6672 && device_resident_p (decl))
6674 on_device = true;
6675 flags |= GOVD_MAP_TO_ONLY;
6678 switch (ctx->region_type)
6680 default:
6681 gcc_unreachable ();
6683 case ORT_ACC_KERNELS:
6684 /* Scalars are default 'copy' under kernels, non-scalars are default
6685 'present_or_copy'. */
6686 flags |= GOVD_MAP;
6687 if (!AGGREGATE_TYPE_P (type))
6688 flags |= GOVD_MAP_FORCE;
6690 rkind = "kernels";
6691 break;
6693 case ORT_ACC_PARALLEL:
6695 if (on_device || AGGREGATE_TYPE_P (type))
6696 /* Aggregates default to 'present_or_copy'. */
6697 flags |= GOVD_MAP;
6698 else
6699 /* Scalars default to 'firstprivate'. */
6700 flags |= GOVD_FIRSTPRIVATE;
6701 rkind = "parallel";
6703 break;
6706 if (DECL_ARTIFICIAL (decl))
6707 ; /* We can get compiler-generated decls, and should not complain
6708 about them. */
6709 else if (ctx->default_kind == OMP_CLAUSE_DEFAULT_NONE)
6711 error ("%qE not specified in enclosing OpenACC %qs construct",
6712 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rkind);
6713 inform (ctx->location, "enclosing OpenACC %qs construct", rkind);
6715 else
6716 gcc_checking_assert (ctx->default_kind == OMP_CLAUSE_DEFAULT_SHARED);
6718 return flags;
6721 /* Record the fact that DECL was used within the OMP context CTX.
6722 IN_CODE is true when real code uses DECL, and false when we should
6723 merely emit default(none) errors. Return true if DECL is going to
6724 be remapped and thus DECL shouldn't be gimplified into its
6725 DECL_VALUE_EXPR (if any). */
6727 static bool
6728 omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
6730 splay_tree_node n;
6731 unsigned flags = in_code ? GOVD_SEEN : 0;
6732 bool ret = false, shared;
6734 if (error_operand_p (decl))
6735 return false;
6737 if (ctx->region_type == ORT_NONE)
6738 return lang_hooks.decls.omp_disregard_value_expr (decl, false);
6740 if (is_global_var (decl))
6742 /* Threadprivate variables are predetermined. */
6743 if (DECL_THREAD_LOCAL_P (decl))
6744 return omp_notice_threadprivate_variable (ctx, decl, NULL_TREE);
6746 if (DECL_HAS_VALUE_EXPR_P (decl))
6748 tree value = get_base_address (DECL_VALUE_EXPR (decl));
6750 if (value && DECL_P (value) && DECL_THREAD_LOCAL_P (value))
6751 return omp_notice_threadprivate_variable (ctx, decl, value);
6754 if (gimplify_omp_ctxp->outer_context == NULL
6755 && VAR_P (decl)
6756 && get_oacc_fn_attrib (current_function_decl))
6758 location_t loc = DECL_SOURCE_LOCATION (decl);
6760 if (lookup_attribute ("omp declare target link",
6761 DECL_ATTRIBUTES (decl)))
6763 error_at (loc,
6764 "%qE with %<link%> clause used in %<routine%> function",
6765 DECL_NAME (decl));
6766 return false;
6768 else if (!lookup_attribute ("omp declare target",
6769 DECL_ATTRIBUTES (decl)))
6771 error_at (loc,
6772 "%qE requires a %<declare%> directive for use "
6773 "in a %<routine%> function", DECL_NAME (decl));
6774 return false;
6779 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
6780 if ((ctx->region_type & ORT_TARGET) != 0)
6782 ret = lang_hooks.decls.omp_disregard_value_expr (decl, true);
6783 if (n == NULL)
6785 unsigned nflags = flags;
6786 if (ctx->target_map_pointers_as_0len_arrays
6787 || ctx->target_map_scalars_firstprivate)
6789 bool is_declare_target = false;
6790 bool is_scalar = false;
6791 if (is_global_var (decl)
6792 && varpool_node::get_create (decl)->offloadable)
6794 struct gimplify_omp_ctx *octx;
6795 for (octx = ctx->outer_context;
6796 octx; octx = octx->outer_context)
6798 n = splay_tree_lookup (octx->variables,
6799 (splay_tree_key)decl);
6800 if (n
6801 && (n->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED
6802 && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
6803 break;
6805 is_declare_target = octx == NULL;
6807 if (!is_declare_target && ctx->target_map_scalars_firstprivate)
6809 tree type = TREE_TYPE (decl);
6810 if (TREE_CODE (type) == REFERENCE_TYPE)
6811 type = TREE_TYPE (type);
6812 if (TREE_CODE (type) == COMPLEX_TYPE)
6813 type = TREE_TYPE (type);
6814 if (INTEGRAL_TYPE_P (type)
6815 || SCALAR_FLOAT_TYPE_P (type)
6816 || TREE_CODE (type) == POINTER_TYPE)
6817 is_scalar = true;
6819 if (is_declare_target)
6821 else if (ctx->target_map_pointers_as_0len_arrays
6822 && (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
6823 || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
6824 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
6825 == POINTER_TYPE)))
6826 nflags |= GOVD_MAP | GOVD_MAP_0LEN_ARRAY;
6827 else if (is_scalar)
6828 nflags |= GOVD_FIRSTPRIVATE;
6831 struct gimplify_omp_ctx *octx = ctx->outer_context;
6832 if ((ctx->region_type & ORT_ACC) && octx)
6834 /* Look in outer OpenACC contexts, to see if there's a
6835 data attribute for this variable. */
6836 omp_notice_variable (octx, decl, in_code);
6838 for (; octx; octx = octx->outer_context)
6840 if (!(octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)))
6841 break;
6842 splay_tree_node n2
6843 = splay_tree_lookup (octx->variables,
6844 (splay_tree_key) decl);
6845 if (n2)
6847 if (octx->region_type == ORT_ACC_HOST_DATA)
6848 error ("variable %qE declared in enclosing "
6849 "%<host_data%> region", DECL_NAME (decl));
6850 nflags |= GOVD_MAP;
6851 if (octx->region_type == ORT_ACC_DATA
6852 && (n2->value & GOVD_MAP_0LEN_ARRAY))
6853 nflags |= GOVD_MAP_0LEN_ARRAY;
6854 goto found_outer;
6860 tree type = TREE_TYPE (decl);
6862 if (nflags == flags
6863 && gimplify_omp_ctxp->target_firstprivatize_array_bases
6864 && lang_hooks.decls.omp_privatize_by_reference (decl))
6865 type = TREE_TYPE (type);
6866 if (nflags == flags
6867 && !lang_hooks.types.omp_mappable_type (type))
6869 error ("%qD referenced in target region does not have "
6870 "a mappable type", decl);
6871 nflags |= GOVD_MAP | GOVD_EXPLICIT;
6873 else if (nflags == flags)
6875 if ((ctx->region_type & ORT_ACC) != 0)
6876 nflags = oacc_default_clause (ctx, decl, flags);
6877 else
6878 nflags |= GOVD_MAP;
6881 found_outer:
6882 omp_add_variable (ctx, decl, nflags);
6884 else
6886 /* If nothing changed, there's nothing left to do. */
6887 if ((n->value & flags) == flags)
6888 return ret;
6889 flags |= n->value;
6890 n->value = flags;
6892 goto do_outer;
6895 if (n == NULL)
6897 if (ctx->region_type == ORT_WORKSHARE
6898 || ctx->region_type == ORT_SIMD
6899 || ctx->region_type == ORT_ACC
6900 || (ctx->region_type & ORT_TARGET_DATA) != 0)
6901 goto do_outer;
6903 flags = omp_default_clause (ctx, decl, in_code, flags);
6905 if ((flags & GOVD_PRIVATE)
6906 && lang_hooks.decls.omp_private_outer_ref (decl))
6907 flags |= GOVD_PRIVATE_OUTER_REF;
6909 omp_add_variable (ctx, decl, flags);
6911 shared = (flags & GOVD_SHARED) != 0;
6912 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
6913 goto do_outer;
6916 if ((n->value & (GOVD_SEEN | GOVD_LOCAL)) == 0
6917 && (flags & (GOVD_SEEN | GOVD_LOCAL)) == GOVD_SEEN
6918 && DECL_SIZE (decl))
6920 if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
6922 splay_tree_node n2;
6923 tree t = DECL_VALUE_EXPR (decl);
6924 gcc_assert (TREE_CODE (t) == INDIRECT_REF);
6925 t = TREE_OPERAND (t, 0);
6926 gcc_assert (DECL_P (t));
6927 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
6928 n2->value |= GOVD_SEEN;
6930 else if (lang_hooks.decls.omp_privatize_by_reference (decl)
6931 && TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)))
6932 && (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))))
6933 != INTEGER_CST))
6935 splay_tree_node n2;
6936 tree t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
6937 gcc_assert (DECL_P (t));
6938 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
6939 if (n2)
6940 n2->value |= GOVD_SEEN;
6944 shared = ((flags | n->value) & GOVD_SHARED) != 0;
6945 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
6947 /* If nothing changed, there's nothing left to do. */
6948 if ((n->value & flags) == flags)
6949 return ret;
6950 flags |= n->value;
6951 n->value = flags;
6953 do_outer:
6954 /* If the variable is private in the current context, then we don't
6955 need to propagate anything to an outer context. */
6956 if ((flags & GOVD_PRIVATE) && !(flags & GOVD_PRIVATE_OUTER_REF))
6957 return ret;
6958 if ((flags & (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
6959 == (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
6960 return ret;
6961 if ((flags & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
6962 | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
6963 == (GOVD_LASTPRIVATE | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
6964 return ret;
6965 if (ctx->outer_context
6966 && omp_notice_variable (ctx->outer_context, decl, in_code))
6967 return true;
6968 return ret;
6971 /* Verify that DECL is private within CTX. If there's specific information
6972 to the contrary in the innermost scope, generate an error. */
6974 static bool
6975 omp_is_private (struct gimplify_omp_ctx *ctx, tree decl, int simd)
6977 splay_tree_node n;
6979 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
6980 if (n != NULL)
6982 if (n->value & GOVD_SHARED)
6984 if (ctx == gimplify_omp_ctxp)
6986 if (simd)
6987 error ("iteration variable %qE is predetermined linear",
6988 DECL_NAME (decl));
6989 else
6990 error ("iteration variable %qE should be private",
6991 DECL_NAME (decl));
6992 n->value = GOVD_PRIVATE;
6993 return true;
6995 else
6996 return false;
6998 else if ((n->value & GOVD_EXPLICIT) != 0
6999 && (ctx == gimplify_omp_ctxp
7000 || (ctx->region_type == ORT_COMBINED_PARALLEL
7001 && gimplify_omp_ctxp->outer_context == ctx)))
7003 if ((n->value & GOVD_FIRSTPRIVATE) != 0)
7004 error ("iteration variable %qE should not be firstprivate",
7005 DECL_NAME (decl));
7006 else if ((n->value & GOVD_REDUCTION) != 0)
7007 error ("iteration variable %qE should not be reduction",
7008 DECL_NAME (decl));
7009 else if (simd == 0 && (n->value & GOVD_LINEAR) != 0)
7010 error ("iteration variable %qE should not be linear",
7011 DECL_NAME (decl));
7012 else if (simd == 1 && (n->value & GOVD_LASTPRIVATE) != 0)
7013 error ("iteration variable %qE should not be lastprivate",
7014 DECL_NAME (decl));
7015 else if (simd && (n->value & GOVD_PRIVATE) != 0)
7016 error ("iteration variable %qE should not be private",
7017 DECL_NAME (decl));
7018 else if (simd == 2 && (n->value & GOVD_LINEAR) != 0)
7019 error ("iteration variable %qE is predetermined linear",
7020 DECL_NAME (decl));
7022 return (ctx == gimplify_omp_ctxp
7023 || (ctx->region_type == ORT_COMBINED_PARALLEL
7024 && gimplify_omp_ctxp->outer_context == ctx));
7027 if (ctx->region_type != ORT_WORKSHARE
7028 && ctx->region_type != ORT_SIMD
7029 && ctx->region_type != ORT_ACC)
7030 return false;
7031 else if (ctx->outer_context)
7032 return omp_is_private (ctx->outer_context, decl, simd);
7033 return false;
7036 /* Return true if DECL is private within a parallel region
7037 that binds to the current construct's context or in parallel
7038 region's REDUCTION clause. */
7040 static bool
7041 omp_check_private (struct gimplify_omp_ctx *ctx, tree decl, bool copyprivate)
7043 splay_tree_node n;
7047 ctx = ctx->outer_context;
7048 if (ctx == NULL)
7050 if (is_global_var (decl))
7051 return false;
7053 /* References might be private, but might be shared too,
7054 when checking for copyprivate, assume they might be
7055 private, otherwise assume they might be shared. */
7056 if (copyprivate)
7057 return true;
7059 if (lang_hooks.decls.omp_privatize_by_reference (decl))
7060 return false;
7062 /* Treat C++ privatized non-static data members outside
7063 of the privatization the same. */
7064 if (omp_member_access_dummy_var (decl))
7065 return false;
7067 return true;
7070 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
7072 if ((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
7073 && (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0))
7074 continue;
7076 if (n != NULL)
7078 if ((n->value & GOVD_LOCAL) != 0
7079 && omp_member_access_dummy_var (decl))
7080 return false;
7081 return (n->value & GOVD_SHARED) == 0;
7084 while (ctx->region_type == ORT_WORKSHARE
7085 || ctx->region_type == ORT_SIMD
7086 || ctx->region_type == ORT_ACC);
7087 return false;
7090 /* Return true if the CTX is combined with distribute and thus
7091 lastprivate can't be supported. */
7093 static bool
7094 omp_no_lastprivate (struct gimplify_omp_ctx *ctx)
7098 if (ctx->outer_context == NULL)
7099 return false;
7100 ctx = ctx->outer_context;
7101 switch (ctx->region_type)
7103 case ORT_WORKSHARE:
7104 if (!ctx->combined_loop)
7105 return false;
7106 if (ctx->distribute)
7107 return lang_GNU_Fortran ();
7108 break;
7109 case ORT_COMBINED_PARALLEL:
7110 break;
7111 case ORT_COMBINED_TEAMS:
7112 return lang_GNU_Fortran ();
7113 default:
7114 return false;
7117 while (1);
7120 /* Callback for walk_tree to find a DECL_EXPR for the given DECL. */
7122 static tree
7123 find_decl_expr (tree *tp, int *walk_subtrees, void *data)
7125 tree t = *tp;
7127 /* If this node has been visited, unmark it and keep looking. */
7128 if (TREE_CODE (t) == DECL_EXPR && DECL_EXPR_DECL (t) == (tree) data)
7129 return t;
7131 if (IS_TYPE_OR_DECL_P (t))
7132 *walk_subtrees = 0;
7133 return NULL_TREE;
7136 /* Scan the OMP clauses in *LIST_P, installing mappings into a new
7137 and previous omp contexts. */
7139 static void
7140 gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
7141 enum omp_region_type region_type,
7142 enum tree_code code)
7144 struct gimplify_omp_ctx *ctx, *outer_ctx;
7145 tree c;
7146 hash_map<tree, tree> *struct_map_to_clause = NULL;
7147 tree *prev_list_p = NULL;
7149 ctx = new_omp_context (region_type);
7150 outer_ctx = ctx->outer_context;
7151 if (code == OMP_TARGET && !lang_GNU_Fortran ())
7153 ctx->target_map_pointers_as_0len_arrays = true;
7154 /* FIXME: For Fortran we want to set this too, when
7155 the Fortran FE is updated to OpenMP 4.5. */
7156 ctx->target_map_scalars_firstprivate = true;
7158 if (!lang_GNU_Fortran ())
7159 switch (code)
7161 case OMP_TARGET:
7162 case OMP_TARGET_DATA:
7163 case OMP_TARGET_ENTER_DATA:
7164 case OMP_TARGET_EXIT_DATA:
7165 case OACC_HOST_DATA:
7166 ctx->target_firstprivatize_array_bases = true;
7167 default:
7168 break;
7171 while ((c = *list_p) != NULL)
7173 bool remove = false;
7174 bool notice_outer = true;
7175 const char *check_non_private = NULL;
7176 unsigned int flags;
7177 tree decl;
7179 switch (OMP_CLAUSE_CODE (c))
7181 case OMP_CLAUSE_PRIVATE:
7182 flags = GOVD_PRIVATE | GOVD_EXPLICIT;
7183 if (lang_hooks.decls.omp_private_outer_ref (OMP_CLAUSE_DECL (c)))
7185 flags |= GOVD_PRIVATE_OUTER_REF;
7186 OMP_CLAUSE_PRIVATE_OUTER_REF (c) = 1;
7188 else
7189 notice_outer = false;
7190 goto do_add;
7191 case OMP_CLAUSE_SHARED:
7192 flags = GOVD_SHARED | GOVD_EXPLICIT;
7193 goto do_add;
7194 case OMP_CLAUSE_FIRSTPRIVATE:
7195 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
7196 check_non_private = "firstprivate";
7197 goto do_add;
7198 case OMP_CLAUSE_LASTPRIVATE:
7199 flags = GOVD_LASTPRIVATE | GOVD_SEEN | GOVD_EXPLICIT;
7200 check_non_private = "lastprivate";
7201 decl = OMP_CLAUSE_DECL (c);
7202 if (omp_no_lastprivate (ctx))
7204 notice_outer = false;
7205 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
7207 else if (error_operand_p (decl))
7208 goto do_add;
7209 else if (outer_ctx
7210 && (outer_ctx->region_type == ORT_COMBINED_PARALLEL
7211 || outer_ctx->region_type == ORT_COMBINED_TEAMS)
7212 && splay_tree_lookup (outer_ctx->variables,
7213 (splay_tree_key) decl) == NULL)
7215 omp_add_variable (outer_ctx, decl, GOVD_SHARED | GOVD_SEEN);
7216 if (outer_ctx->outer_context)
7217 omp_notice_variable (outer_ctx->outer_context, decl, true);
7219 else if (outer_ctx
7220 && (outer_ctx->region_type & ORT_TASK) != 0
7221 && outer_ctx->combined_loop
7222 && splay_tree_lookup (outer_ctx->variables,
7223 (splay_tree_key) decl) == NULL)
7225 omp_add_variable (outer_ctx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
7226 if (outer_ctx->outer_context)
7227 omp_notice_variable (outer_ctx->outer_context, decl, true);
7229 else if (outer_ctx
7230 && (outer_ctx->region_type == ORT_WORKSHARE
7231 || outer_ctx->region_type == ORT_ACC)
7232 && outer_ctx->combined_loop
7233 && splay_tree_lookup (outer_ctx->variables,
7234 (splay_tree_key) decl) == NULL
7235 && !omp_check_private (outer_ctx, decl, false))
7237 omp_add_variable (outer_ctx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
7238 if (outer_ctx->outer_context
7239 && (outer_ctx->outer_context->region_type
7240 == ORT_COMBINED_PARALLEL)
7241 && splay_tree_lookup (outer_ctx->outer_context->variables,
7242 (splay_tree_key) decl) == NULL)
7244 struct gimplify_omp_ctx *octx = outer_ctx->outer_context;
7245 omp_add_variable (octx, decl, GOVD_SHARED | GOVD_SEEN);
7246 if (octx->outer_context)
7247 omp_notice_variable (octx->outer_context, decl, true);
7249 else if (outer_ctx->outer_context)
7250 omp_notice_variable (outer_ctx->outer_context, decl, true);
7252 goto do_add;
7253 case OMP_CLAUSE_REDUCTION:
7254 flags = GOVD_REDUCTION | GOVD_SEEN | GOVD_EXPLICIT;
7255 /* OpenACC permits reductions on private variables. */
7256 if (!(region_type & ORT_ACC))
7257 check_non_private = "reduction";
7258 decl = OMP_CLAUSE_DECL (c);
7259 if (TREE_CODE (decl) == MEM_REF)
7261 tree type = TREE_TYPE (decl);
7262 if (gimplify_expr (&TYPE_MAX_VALUE (TYPE_DOMAIN (type)), pre_p,
7263 NULL, is_gimple_val, fb_rvalue, false)
7264 == GS_ERROR)
7266 remove = true;
7267 break;
7269 tree v = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
7270 if (DECL_P (v))
7272 omp_firstprivatize_variable (ctx, v);
7273 omp_notice_variable (ctx, v, true);
7275 decl = TREE_OPERAND (decl, 0);
7276 if (TREE_CODE (decl) == POINTER_PLUS_EXPR)
7278 if (gimplify_expr (&TREE_OPERAND (decl, 1), pre_p,
7279 NULL, is_gimple_val, fb_rvalue, false)
7280 == GS_ERROR)
7282 remove = true;
7283 break;
7285 v = TREE_OPERAND (decl, 1);
7286 if (DECL_P (v))
7288 omp_firstprivatize_variable (ctx, v);
7289 omp_notice_variable (ctx, v, true);
7291 decl = TREE_OPERAND (decl, 0);
7293 if (TREE_CODE (decl) == ADDR_EXPR
7294 || TREE_CODE (decl) == INDIRECT_REF)
7295 decl = TREE_OPERAND (decl, 0);
7297 goto do_add_decl;
7298 case OMP_CLAUSE_LINEAR:
7299 if (gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c), pre_p, NULL,
7300 is_gimple_val, fb_rvalue) == GS_ERROR)
7302 remove = true;
7303 break;
7305 else
7307 if (code == OMP_SIMD
7308 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
7310 struct gimplify_omp_ctx *octx = outer_ctx;
7311 if (octx
7312 && octx->region_type == ORT_WORKSHARE
7313 && octx->combined_loop
7314 && !octx->distribute)
7316 if (octx->outer_context
7317 && (octx->outer_context->region_type
7318 == ORT_COMBINED_PARALLEL))
7319 octx = octx->outer_context->outer_context;
7320 else
7321 octx = octx->outer_context;
7323 if (octx
7324 && octx->region_type == ORT_WORKSHARE
7325 && octx->combined_loop
7326 && octx->distribute
7327 && !lang_GNU_Fortran ())
7329 error_at (OMP_CLAUSE_LOCATION (c),
7330 "%<linear%> clause for variable other than "
7331 "loop iterator specified on construct "
7332 "combined with %<distribute%>");
7333 remove = true;
7334 break;
7337 /* For combined #pragma omp parallel for simd, need to put
7338 lastprivate and perhaps firstprivate too on the
7339 parallel. Similarly for #pragma omp for simd. */
7340 struct gimplify_omp_ctx *octx = outer_ctx;
7341 decl = NULL_TREE;
7342 if (omp_no_lastprivate (ctx))
7343 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
7346 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
7347 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
7348 break;
7349 decl = OMP_CLAUSE_DECL (c);
7350 if (error_operand_p (decl))
7352 decl = NULL_TREE;
7353 break;
7355 flags = GOVD_SEEN;
7356 if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c))
7357 flags |= GOVD_FIRSTPRIVATE;
7358 if (!OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
7359 flags |= GOVD_LASTPRIVATE;
7360 if (octx
7361 && octx->region_type == ORT_WORKSHARE
7362 && octx->combined_loop)
7364 if (octx->outer_context
7365 && (octx->outer_context->region_type
7366 == ORT_COMBINED_PARALLEL))
7367 octx = octx->outer_context;
7368 else if (omp_check_private (octx, decl, false))
7369 break;
7371 else if (octx
7372 && (octx->region_type & ORT_TASK) != 0
7373 && octx->combined_loop)
7375 else if (octx
7376 && octx->region_type == ORT_COMBINED_PARALLEL
7377 && ctx->region_type == ORT_WORKSHARE
7378 && octx == outer_ctx)
7379 flags = GOVD_SEEN | GOVD_SHARED;
7380 else if (octx
7381 && octx->region_type == ORT_COMBINED_TEAMS)
7382 flags = GOVD_SEEN | GOVD_SHARED;
7383 else if (octx
7384 && octx->region_type == ORT_COMBINED_TARGET)
7386 flags &= ~GOVD_LASTPRIVATE;
7387 if (flags == GOVD_SEEN)
7388 break;
7390 else
7391 break;
7392 splay_tree_node on
7393 = splay_tree_lookup (octx->variables,
7394 (splay_tree_key) decl);
7395 if (on && (on->value & GOVD_DATA_SHARE_CLASS) != 0)
7397 octx = NULL;
7398 break;
7400 omp_add_variable (octx, decl, flags);
7401 if (octx->outer_context == NULL)
7402 break;
7403 octx = octx->outer_context;
7405 while (1);
7406 if (octx
7407 && decl
7408 && (!OMP_CLAUSE_LINEAR_NO_COPYIN (c)
7409 || !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
7410 omp_notice_variable (octx, decl, true);
7412 flags = GOVD_LINEAR | GOVD_EXPLICIT;
7413 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
7414 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
7416 notice_outer = false;
7417 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
7419 goto do_add;
7421 case OMP_CLAUSE_MAP:
7422 decl = OMP_CLAUSE_DECL (c);
7423 if (error_operand_p (decl))
7424 remove = true;
7425 switch (code)
7427 case OMP_TARGET:
7428 break;
7429 case OACC_DATA:
7430 if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
7431 break;
7432 /* FALLTHRU */
7433 case OMP_TARGET_DATA:
7434 case OMP_TARGET_ENTER_DATA:
7435 case OMP_TARGET_EXIT_DATA:
7436 case OACC_ENTER_DATA:
7437 case OACC_EXIT_DATA:
7438 case OACC_HOST_DATA:
7439 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
7440 || (OMP_CLAUSE_MAP_KIND (c)
7441 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
7442 /* For target {,enter ,exit }data only the array slice is
7443 mapped, but not the pointer to it. */
7444 remove = true;
7445 break;
7446 default:
7447 break;
7449 if (remove)
7450 break;
7451 if (DECL_P (decl) && outer_ctx && (region_type & ORT_ACC))
7453 struct gimplify_omp_ctx *octx;
7454 for (octx = outer_ctx; octx; octx = octx->outer_context)
7456 if (octx->region_type != ORT_ACC_HOST_DATA)
7457 break;
7458 splay_tree_node n2
7459 = splay_tree_lookup (octx->variables,
7460 (splay_tree_key) decl);
7461 if (n2)
7462 error_at (OMP_CLAUSE_LOCATION (c), "variable %qE "
7463 "declared in enclosing %<host_data%> region",
7464 DECL_NAME (decl));
7467 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
7468 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
7469 : TYPE_SIZE_UNIT (TREE_TYPE (decl));
7470 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
7471 NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
7473 remove = true;
7474 break;
7476 else if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
7477 || (OMP_CLAUSE_MAP_KIND (c)
7478 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
7479 && TREE_CODE (OMP_CLAUSE_SIZE (c)) != INTEGER_CST)
7481 OMP_CLAUSE_SIZE (c)
7482 = get_initialized_tmp_var (OMP_CLAUSE_SIZE (c), pre_p, NULL,
7483 false);
7484 omp_add_variable (ctx, OMP_CLAUSE_SIZE (c),
7485 GOVD_FIRSTPRIVATE | GOVD_SEEN);
7487 if (!DECL_P (decl))
7489 tree d = decl, *pd;
7490 if (TREE_CODE (d) == ARRAY_REF)
7492 while (TREE_CODE (d) == ARRAY_REF)
7493 d = TREE_OPERAND (d, 0);
7494 if (TREE_CODE (d) == COMPONENT_REF
7495 && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE)
7496 decl = d;
7498 pd = &OMP_CLAUSE_DECL (c);
7499 if (d == decl
7500 && TREE_CODE (decl) == INDIRECT_REF
7501 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
7502 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
7503 == REFERENCE_TYPE))
7505 pd = &TREE_OPERAND (decl, 0);
7506 decl = TREE_OPERAND (decl, 0);
7508 if (TREE_CODE (decl) == COMPONENT_REF)
7510 while (TREE_CODE (decl) == COMPONENT_REF)
7511 decl = TREE_OPERAND (decl, 0);
7512 if (TREE_CODE (decl) == INDIRECT_REF
7513 && DECL_P (TREE_OPERAND (decl, 0))
7514 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
7515 == REFERENCE_TYPE))
7516 decl = TREE_OPERAND (decl, 0);
7518 if (gimplify_expr (pd, pre_p, NULL, is_gimple_lvalue, fb_lvalue)
7519 == GS_ERROR)
7521 remove = true;
7522 break;
7524 if (DECL_P (decl))
7526 if (error_operand_p (decl))
7528 remove = true;
7529 break;
7532 tree stype = TREE_TYPE (decl);
7533 if (TREE_CODE (stype) == REFERENCE_TYPE)
7534 stype = TREE_TYPE (stype);
7535 if (TYPE_SIZE_UNIT (stype) == NULL
7536 || TREE_CODE (TYPE_SIZE_UNIT (stype)) != INTEGER_CST)
7538 error_at (OMP_CLAUSE_LOCATION (c),
7539 "mapping field %qE of variable length "
7540 "structure", OMP_CLAUSE_DECL (c));
7541 remove = true;
7542 break;
7545 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER)
7547 /* Error recovery. */
7548 if (prev_list_p == NULL)
7550 remove = true;
7551 break;
7553 if (OMP_CLAUSE_CHAIN (*prev_list_p) != c)
7555 tree ch = OMP_CLAUSE_CHAIN (*prev_list_p);
7556 if (ch == NULL_TREE || OMP_CLAUSE_CHAIN (ch) != c)
7558 remove = true;
7559 break;
7564 tree offset;
7565 HOST_WIDE_INT bitsize, bitpos;
7566 machine_mode mode;
7567 int unsignedp, reversep, volatilep = 0;
7568 tree base = OMP_CLAUSE_DECL (c);
7569 while (TREE_CODE (base) == ARRAY_REF)
7570 base = TREE_OPERAND (base, 0);
7571 if (TREE_CODE (base) == INDIRECT_REF)
7572 base = TREE_OPERAND (base, 0);
7573 base = get_inner_reference (base, &bitsize, &bitpos, &offset,
7574 &mode, &unsignedp, &reversep,
7575 &volatilep);
7576 tree orig_base = base;
7577 if ((TREE_CODE (base) == INDIRECT_REF
7578 || (TREE_CODE (base) == MEM_REF
7579 && integer_zerop (TREE_OPERAND (base, 1))))
7580 && DECL_P (TREE_OPERAND (base, 0))
7581 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0)))
7582 == REFERENCE_TYPE))
7583 base = TREE_OPERAND (base, 0);
7584 gcc_assert (base == decl
7585 && (offset == NULL_TREE
7586 || TREE_CODE (offset) == INTEGER_CST));
7588 splay_tree_node n
7589 = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7590 bool ptr = (OMP_CLAUSE_MAP_KIND (c)
7591 == GOMP_MAP_ALWAYS_POINTER);
7592 if (n == NULL || (n->value & GOVD_MAP) == 0)
7594 tree l = build_omp_clause (OMP_CLAUSE_LOCATION (c),
7595 OMP_CLAUSE_MAP);
7596 OMP_CLAUSE_SET_MAP_KIND (l, GOMP_MAP_STRUCT);
7597 if (orig_base != base)
7598 OMP_CLAUSE_DECL (l) = unshare_expr (orig_base);
7599 else
7600 OMP_CLAUSE_DECL (l) = decl;
7601 OMP_CLAUSE_SIZE (l) = size_int (1);
7602 if (struct_map_to_clause == NULL)
7603 struct_map_to_clause = new hash_map<tree, tree>;
7604 struct_map_to_clause->put (decl, l);
7605 if (ptr)
7607 enum gomp_map_kind mkind
7608 = code == OMP_TARGET_EXIT_DATA
7609 ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
7610 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
7611 OMP_CLAUSE_MAP);
7612 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
7613 OMP_CLAUSE_DECL (c2)
7614 = unshare_expr (OMP_CLAUSE_DECL (c));
7615 OMP_CLAUSE_CHAIN (c2) = *prev_list_p;
7616 OMP_CLAUSE_SIZE (c2)
7617 = TYPE_SIZE_UNIT (ptr_type_node);
7618 OMP_CLAUSE_CHAIN (l) = c2;
7619 if (OMP_CLAUSE_CHAIN (*prev_list_p) != c)
7621 tree c4 = OMP_CLAUSE_CHAIN (*prev_list_p);
7622 tree c3
7623 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
7624 OMP_CLAUSE_MAP);
7625 OMP_CLAUSE_SET_MAP_KIND (c3, mkind);
7626 OMP_CLAUSE_DECL (c3)
7627 = unshare_expr (OMP_CLAUSE_DECL (c4));
7628 OMP_CLAUSE_SIZE (c3)
7629 = TYPE_SIZE_UNIT (ptr_type_node);
7630 OMP_CLAUSE_CHAIN (c3) = *prev_list_p;
7631 OMP_CLAUSE_CHAIN (c2) = c3;
7633 *prev_list_p = l;
7634 prev_list_p = NULL;
7636 else
7638 OMP_CLAUSE_CHAIN (l) = c;
7639 *list_p = l;
7640 list_p = &OMP_CLAUSE_CHAIN (l);
7642 if (orig_base != base && code == OMP_TARGET)
7644 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
7645 OMP_CLAUSE_MAP);
7646 enum gomp_map_kind mkind
7647 = GOMP_MAP_FIRSTPRIVATE_REFERENCE;
7648 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
7649 OMP_CLAUSE_DECL (c2) = decl;
7650 OMP_CLAUSE_SIZE (c2) = size_zero_node;
7651 OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (l);
7652 OMP_CLAUSE_CHAIN (l) = c2;
7654 flags = GOVD_MAP | GOVD_EXPLICIT;
7655 if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) || ptr)
7656 flags |= GOVD_SEEN;
7657 goto do_add_decl;
7659 else
7661 tree *osc = struct_map_to_clause->get (decl);
7662 tree *sc = NULL, *scp = NULL;
7663 if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) || ptr)
7664 n->value |= GOVD_SEEN;
7665 offset_int o1, o2;
7666 if (offset)
7667 o1 = wi::to_offset (offset);
7668 else
7669 o1 = 0;
7670 if (bitpos)
7671 o1 = o1 + bitpos / BITS_PER_UNIT;
7672 sc = &OMP_CLAUSE_CHAIN (*osc);
7673 if (*sc != c
7674 && (OMP_CLAUSE_MAP_KIND (*sc)
7675 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
7676 sc = &OMP_CLAUSE_CHAIN (*sc);
7677 for (; *sc != c; sc = &OMP_CLAUSE_CHAIN (*sc))
7678 if (ptr && sc == prev_list_p)
7679 break;
7680 else if (TREE_CODE (OMP_CLAUSE_DECL (*sc))
7681 != COMPONENT_REF
7682 && (TREE_CODE (OMP_CLAUSE_DECL (*sc))
7683 != INDIRECT_REF)
7684 && (TREE_CODE (OMP_CLAUSE_DECL (*sc))
7685 != ARRAY_REF))
7686 break;
7687 else
7689 tree offset2;
7690 HOST_WIDE_INT bitsize2, bitpos2;
7691 base = OMP_CLAUSE_DECL (*sc);
7692 if (TREE_CODE (base) == ARRAY_REF)
7694 while (TREE_CODE (base) == ARRAY_REF)
7695 base = TREE_OPERAND (base, 0);
7696 if (TREE_CODE (base) != COMPONENT_REF
7697 || (TREE_CODE (TREE_TYPE (base))
7698 != ARRAY_TYPE))
7699 break;
7701 else if (TREE_CODE (base) == INDIRECT_REF
7702 && (TREE_CODE (TREE_OPERAND (base, 0))
7703 == COMPONENT_REF)
7704 && (TREE_CODE (TREE_TYPE
7705 (TREE_OPERAND (base, 0)))
7706 == REFERENCE_TYPE))
7707 base = TREE_OPERAND (base, 0);
7708 base = get_inner_reference (base, &bitsize2,
7709 &bitpos2, &offset2,
7710 &mode, &unsignedp,
7711 &reversep, &volatilep);
7712 if ((TREE_CODE (base) == INDIRECT_REF
7713 || (TREE_CODE (base) == MEM_REF
7714 && integer_zerop (TREE_OPERAND (base,
7715 1))))
7716 && DECL_P (TREE_OPERAND (base, 0))
7717 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (base,
7718 0)))
7719 == REFERENCE_TYPE))
7720 base = TREE_OPERAND (base, 0);
7721 if (base != decl)
7722 break;
7723 if (scp)
7724 continue;
7725 gcc_assert (offset == NULL_TREE
7726 || TREE_CODE (offset) == INTEGER_CST);
7727 tree d1 = OMP_CLAUSE_DECL (*sc);
7728 tree d2 = OMP_CLAUSE_DECL (c);
7729 while (TREE_CODE (d1) == ARRAY_REF)
7730 d1 = TREE_OPERAND (d1, 0);
7731 while (TREE_CODE (d2) == ARRAY_REF)
7732 d2 = TREE_OPERAND (d2, 0);
7733 if (TREE_CODE (d1) == INDIRECT_REF)
7734 d1 = TREE_OPERAND (d1, 0);
7735 if (TREE_CODE (d2) == INDIRECT_REF)
7736 d2 = TREE_OPERAND (d2, 0);
7737 while (TREE_CODE (d1) == COMPONENT_REF)
7738 if (TREE_CODE (d2) == COMPONENT_REF
7739 && TREE_OPERAND (d1, 1)
7740 == TREE_OPERAND (d2, 1))
7742 d1 = TREE_OPERAND (d1, 0);
7743 d2 = TREE_OPERAND (d2, 0);
7745 else
7746 break;
7747 if (d1 == d2)
7749 error_at (OMP_CLAUSE_LOCATION (c),
7750 "%qE appears more than once in map "
7751 "clauses", OMP_CLAUSE_DECL (c));
7752 remove = true;
7753 break;
7755 if (offset2)
7756 o2 = wi::to_offset (offset2);
7757 else
7758 o2 = 0;
7759 if (bitpos2)
7760 o2 = o2 + bitpos2 / BITS_PER_UNIT;
7761 if (wi::ltu_p (o1, o2)
7762 || (wi::eq_p (o1, o2) && bitpos < bitpos2))
7764 if (ptr)
7765 scp = sc;
7766 else
7767 break;
7770 if (remove)
7771 break;
7772 OMP_CLAUSE_SIZE (*osc)
7773 = size_binop (PLUS_EXPR, OMP_CLAUSE_SIZE (*osc),
7774 size_one_node);
7775 if (ptr)
7777 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
7778 OMP_CLAUSE_MAP);
7779 tree cl = NULL_TREE;
7780 enum gomp_map_kind mkind
7781 = code == OMP_TARGET_EXIT_DATA
7782 ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
7783 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
7784 OMP_CLAUSE_DECL (c2)
7785 = unshare_expr (OMP_CLAUSE_DECL (c));
7786 OMP_CLAUSE_CHAIN (c2) = scp ? *scp : *prev_list_p;
7787 OMP_CLAUSE_SIZE (c2)
7788 = TYPE_SIZE_UNIT (ptr_type_node);
7789 cl = scp ? *prev_list_p : c2;
7790 if (OMP_CLAUSE_CHAIN (*prev_list_p) != c)
7792 tree c4 = OMP_CLAUSE_CHAIN (*prev_list_p);
7793 tree c3
7794 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
7795 OMP_CLAUSE_MAP);
7796 OMP_CLAUSE_SET_MAP_KIND (c3, mkind);
7797 OMP_CLAUSE_DECL (c3)
7798 = unshare_expr (OMP_CLAUSE_DECL (c4));
7799 OMP_CLAUSE_SIZE (c3)
7800 = TYPE_SIZE_UNIT (ptr_type_node);
7801 OMP_CLAUSE_CHAIN (c3) = *prev_list_p;
7802 if (!scp)
7803 OMP_CLAUSE_CHAIN (c2) = c3;
7804 else
7805 cl = c3;
7807 if (scp)
7808 *scp = c2;
7809 if (sc == prev_list_p)
7811 *sc = cl;
7812 prev_list_p = NULL;
7814 else
7816 *prev_list_p = OMP_CLAUSE_CHAIN (c);
7817 list_p = prev_list_p;
7818 prev_list_p = NULL;
7819 OMP_CLAUSE_CHAIN (c) = *sc;
7820 *sc = cl;
7821 continue;
7824 else if (*sc != c)
7826 *list_p = OMP_CLAUSE_CHAIN (c);
7827 OMP_CLAUSE_CHAIN (c) = *sc;
7828 *sc = c;
7829 continue;
7833 if (!remove
7834 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_POINTER
7835 && OMP_CLAUSE_CHAIN (c)
7836 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (c)) == OMP_CLAUSE_MAP
7837 && (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
7838 == GOMP_MAP_ALWAYS_POINTER))
7839 prev_list_p = list_p;
7840 break;
7842 flags = GOVD_MAP | GOVD_EXPLICIT;
7843 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TO
7844 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TOFROM)
7845 flags |= GOVD_MAP_ALWAYS_TO;
7846 goto do_add;
7848 case OMP_CLAUSE_DEPEND:
7849 if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK
7850 || OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
7852 /* Nothing to do. OMP_CLAUSE_DECL will be lowered in
7853 omp-low.c. */
7854 break;
7856 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
7858 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
7859 NULL, is_gimple_val, fb_rvalue);
7860 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
7862 if (error_operand_p (OMP_CLAUSE_DECL (c)))
7864 remove = true;
7865 break;
7867 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
7868 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
7869 is_gimple_val, fb_rvalue) == GS_ERROR)
7871 remove = true;
7872 break;
7874 break;
7876 case OMP_CLAUSE_TO:
7877 case OMP_CLAUSE_FROM:
7878 case OMP_CLAUSE__CACHE_:
7879 decl = OMP_CLAUSE_DECL (c);
7880 if (error_operand_p (decl))
7882 remove = true;
7883 break;
7885 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
7886 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
7887 : TYPE_SIZE_UNIT (TREE_TYPE (decl));
7888 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
7889 NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
7891 remove = true;
7892 break;
7894 if (!DECL_P (decl))
7896 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p,
7897 NULL, is_gimple_lvalue, fb_lvalue)
7898 == GS_ERROR)
7900 remove = true;
7901 break;
7903 break;
7905 goto do_notice;
7907 case OMP_CLAUSE_USE_DEVICE_PTR:
7908 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
7909 goto do_add;
7910 case OMP_CLAUSE_IS_DEVICE_PTR:
7911 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
7912 goto do_add;
7914 do_add:
7915 decl = OMP_CLAUSE_DECL (c);
7916 do_add_decl:
7917 if (error_operand_p (decl))
7919 remove = true;
7920 break;
7922 if (DECL_NAME (decl) == NULL_TREE && (flags & GOVD_SHARED) == 0)
7924 tree t = omp_member_access_dummy_var (decl);
7925 if (t)
7927 tree v = DECL_VALUE_EXPR (decl);
7928 DECL_NAME (decl) = DECL_NAME (TREE_OPERAND (v, 1));
7929 if (outer_ctx)
7930 omp_notice_variable (outer_ctx, t, true);
7933 if (code == OACC_DATA
7934 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
7935 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
7936 flags |= GOVD_MAP_0LEN_ARRAY;
7937 omp_add_variable (ctx, decl, flags);
7938 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
7939 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
7941 omp_add_variable (ctx, OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
7942 GOVD_LOCAL | GOVD_SEEN);
7943 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
7944 && walk_tree (&OMP_CLAUSE_REDUCTION_INIT (c),
7945 find_decl_expr,
7946 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
7947 NULL) == NULL_TREE)
7948 omp_add_variable (ctx,
7949 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
7950 GOVD_LOCAL | GOVD_SEEN);
7951 gimplify_omp_ctxp = ctx;
7952 push_gimplify_context ();
7954 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
7955 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
7957 gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c),
7958 &OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c));
7959 pop_gimplify_context
7960 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c)));
7961 push_gimplify_context ();
7962 gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c),
7963 &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
7964 pop_gimplify_context
7965 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c)));
7966 OMP_CLAUSE_REDUCTION_INIT (c) = NULL_TREE;
7967 OMP_CLAUSE_REDUCTION_MERGE (c) = NULL_TREE;
7969 gimplify_omp_ctxp = outer_ctx;
7971 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
7972 && OMP_CLAUSE_LASTPRIVATE_STMT (c))
7974 gimplify_omp_ctxp = ctx;
7975 push_gimplify_context ();
7976 if (TREE_CODE (OMP_CLAUSE_LASTPRIVATE_STMT (c)) != BIND_EXPR)
7978 tree bind = build3 (BIND_EXPR, void_type_node, NULL,
7979 NULL, NULL);
7980 TREE_SIDE_EFFECTS (bind) = 1;
7981 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LASTPRIVATE_STMT (c);
7982 OMP_CLAUSE_LASTPRIVATE_STMT (c) = bind;
7984 gimplify_and_add (OMP_CLAUSE_LASTPRIVATE_STMT (c),
7985 &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
7986 pop_gimplify_context
7987 (gimple_seq_first_stmt (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c)));
7988 OMP_CLAUSE_LASTPRIVATE_STMT (c) = NULL_TREE;
7990 gimplify_omp_ctxp = outer_ctx;
7992 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
7993 && OMP_CLAUSE_LINEAR_STMT (c))
7995 gimplify_omp_ctxp = ctx;
7996 push_gimplify_context ();
7997 if (TREE_CODE (OMP_CLAUSE_LINEAR_STMT (c)) != BIND_EXPR)
7999 tree bind = build3 (BIND_EXPR, void_type_node, NULL,
8000 NULL, NULL);
8001 TREE_SIDE_EFFECTS (bind) = 1;
8002 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LINEAR_STMT (c);
8003 OMP_CLAUSE_LINEAR_STMT (c) = bind;
8005 gimplify_and_add (OMP_CLAUSE_LINEAR_STMT (c),
8006 &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c));
8007 pop_gimplify_context
8008 (gimple_seq_first_stmt (OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c)));
8009 OMP_CLAUSE_LINEAR_STMT (c) = NULL_TREE;
8011 gimplify_omp_ctxp = outer_ctx;
8013 if (notice_outer)
8014 goto do_notice;
8015 break;
8017 case OMP_CLAUSE_COPYIN:
8018 case OMP_CLAUSE_COPYPRIVATE:
8019 decl = OMP_CLAUSE_DECL (c);
8020 if (error_operand_p (decl))
8022 remove = true;
8023 break;
8025 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_COPYPRIVATE
8026 && !remove
8027 && !omp_check_private (ctx, decl, true))
8029 remove = true;
8030 if (is_global_var (decl))
8032 if (DECL_THREAD_LOCAL_P (decl))
8033 remove = false;
8034 else if (DECL_HAS_VALUE_EXPR_P (decl))
8036 tree value = get_base_address (DECL_VALUE_EXPR (decl));
8038 if (value
8039 && DECL_P (value)
8040 && DECL_THREAD_LOCAL_P (value))
8041 remove = false;
8044 if (remove)
8045 error_at (OMP_CLAUSE_LOCATION (c),
8046 "copyprivate variable %qE is not threadprivate"
8047 " or private in outer context", DECL_NAME (decl));
8049 do_notice:
8050 if (outer_ctx)
8051 omp_notice_variable (outer_ctx, decl, true);
8052 if (check_non_private
8053 && region_type == ORT_WORKSHARE
8054 && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
8055 || decl == OMP_CLAUSE_DECL (c)
8056 || (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
8057 && (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
8058 == ADDR_EXPR
8059 || (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
8060 == POINTER_PLUS_EXPR
8061 && (TREE_CODE (TREE_OPERAND (TREE_OPERAND
8062 (OMP_CLAUSE_DECL (c), 0), 0))
8063 == ADDR_EXPR)))))
8064 && omp_check_private (ctx, decl, false))
8066 error ("%s variable %qE is private in outer context",
8067 check_non_private, DECL_NAME (decl));
8068 remove = true;
8070 break;
8072 case OMP_CLAUSE_IF:
8073 if (OMP_CLAUSE_IF_MODIFIER (c) != ERROR_MARK
8074 && OMP_CLAUSE_IF_MODIFIER (c) != code)
8076 const char *p[2];
8077 for (int i = 0; i < 2; i++)
8078 switch (i ? OMP_CLAUSE_IF_MODIFIER (c) : code)
8080 case OMP_PARALLEL: p[i] = "parallel"; break;
8081 case OMP_TASK: p[i] = "task"; break;
8082 case OMP_TASKLOOP: p[i] = "taskloop"; break;
8083 case OMP_TARGET_DATA: p[i] = "target data"; break;
8084 case OMP_TARGET: p[i] = "target"; break;
8085 case OMP_TARGET_UPDATE: p[i] = "target update"; break;
8086 case OMP_TARGET_ENTER_DATA:
8087 p[i] = "target enter data"; break;
8088 case OMP_TARGET_EXIT_DATA: p[i] = "target exit data"; break;
8089 default: gcc_unreachable ();
8091 error_at (OMP_CLAUSE_LOCATION (c),
8092 "expected %qs %<if%> clause modifier rather than %qs",
8093 p[0], p[1]);
8094 remove = true;
8096 /* Fall through. */
8098 case OMP_CLAUSE_FINAL:
8099 OMP_CLAUSE_OPERAND (c, 0)
8100 = gimple_boolify (OMP_CLAUSE_OPERAND (c, 0));
8101 /* Fall through. */
8103 case OMP_CLAUSE_SCHEDULE:
8104 case OMP_CLAUSE_NUM_THREADS:
8105 case OMP_CLAUSE_NUM_TEAMS:
8106 case OMP_CLAUSE_THREAD_LIMIT:
8107 case OMP_CLAUSE_DIST_SCHEDULE:
8108 case OMP_CLAUSE_DEVICE:
8109 case OMP_CLAUSE_PRIORITY:
8110 case OMP_CLAUSE_GRAINSIZE:
8111 case OMP_CLAUSE_NUM_TASKS:
8112 case OMP_CLAUSE_HINT:
8113 case OMP_CLAUSE__CILK_FOR_COUNT_:
8114 case OMP_CLAUSE_ASYNC:
8115 case OMP_CLAUSE_WAIT:
8116 case OMP_CLAUSE_NUM_GANGS:
8117 case OMP_CLAUSE_NUM_WORKERS:
8118 case OMP_CLAUSE_VECTOR_LENGTH:
8119 case OMP_CLAUSE_WORKER:
8120 case OMP_CLAUSE_VECTOR:
8121 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
8122 is_gimple_val, fb_rvalue) == GS_ERROR)
8123 remove = true;
8124 break;
8126 case OMP_CLAUSE_GANG:
8127 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
8128 is_gimple_val, fb_rvalue) == GS_ERROR)
8129 remove = true;
8130 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 1), pre_p, NULL,
8131 is_gimple_val, fb_rvalue) == GS_ERROR)
8132 remove = true;
8133 break;
8135 case OMP_CLAUSE_TILE:
8136 for (tree list = OMP_CLAUSE_TILE_LIST (c); !remove && list;
8137 list = TREE_CHAIN (list))
8139 if (gimplify_expr (&TREE_VALUE (list), pre_p, NULL,
8140 is_gimple_val, fb_rvalue) == GS_ERROR)
8141 remove = true;
8143 break;
8145 case OMP_CLAUSE_NOWAIT:
8146 case OMP_CLAUSE_ORDERED:
8147 case OMP_CLAUSE_UNTIED:
8148 case OMP_CLAUSE_COLLAPSE:
8149 case OMP_CLAUSE_AUTO:
8150 case OMP_CLAUSE_SEQ:
8151 case OMP_CLAUSE_INDEPENDENT:
8152 case OMP_CLAUSE_MERGEABLE:
8153 case OMP_CLAUSE_PROC_BIND:
8154 case OMP_CLAUSE_SAFELEN:
8155 case OMP_CLAUSE_SIMDLEN:
8156 case OMP_CLAUSE_NOGROUP:
8157 case OMP_CLAUSE_THREADS:
8158 case OMP_CLAUSE_SIMD:
8159 break;
8161 case OMP_CLAUSE_DEFAULTMAP:
8162 ctx->target_map_scalars_firstprivate = false;
8163 break;
8165 case OMP_CLAUSE_ALIGNED:
8166 decl = OMP_CLAUSE_DECL (c);
8167 if (error_operand_p (decl))
8169 remove = true;
8170 break;
8172 if (gimplify_expr (&OMP_CLAUSE_ALIGNED_ALIGNMENT (c), pre_p, NULL,
8173 is_gimple_val, fb_rvalue) == GS_ERROR)
8175 remove = true;
8176 break;
8178 if (!is_global_var (decl)
8179 && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
8180 omp_add_variable (ctx, decl, GOVD_ALIGNED);
8181 break;
8183 case OMP_CLAUSE_DEFAULT:
8184 ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
8185 break;
8187 default:
8188 gcc_unreachable ();
8191 if (code == OACC_DATA
8192 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
8193 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
8194 remove = true;
8195 if (remove)
8196 *list_p = OMP_CLAUSE_CHAIN (c);
8197 else
8198 list_p = &OMP_CLAUSE_CHAIN (c);
8201 gimplify_omp_ctxp = ctx;
8202 if (struct_map_to_clause)
8203 delete struct_map_to_clause;
8206 /* Return true if DECL is a candidate for shared to firstprivate
8207 optimization. We only consider non-addressable scalars, not
8208 too big, and not references. */
8210 static bool
8211 omp_shared_to_firstprivate_optimizable_decl_p (tree decl)
8213 if (TREE_ADDRESSABLE (decl))
8214 return false;
8215 tree type = TREE_TYPE (decl);
8216 if (!is_gimple_reg_type (type)
8217 || TREE_CODE (type) == REFERENCE_TYPE
8218 || TREE_ADDRESSABLE (type))
8219 return false;
8220 /* Don't optimize too large decls, as each thread/task will have
8221 its own. */
8222 HOST_WIDE_INT len = int_size_in_bytes (type);
8223 if (len == -1 || len > 4 * POINTER_SIZE / BITS_PER_UNIT)
8224 return false;
8225 if (lang_hooks.decls.omp_privatize_by_reference (decl))
8226 return false;
8227 return true;
8230 /* Helper function of omp_find_stores_op and gimplify_adjust_omp_clauses*.
8231 For omp_shared_to_firstprivate_optimizable_decl_p decl mark it as
8232 GOVD_WRITTEN in outer contexts. */
8234 static void
8235 omp_mark_stores (struct gimplify_omp_ctx *ctx, tree decl)
8237 for (; ctx; ctx = ctx->outer_context)
8239 splay_tree_node n = splay_tree_lookup (ctx->variables,
8240 (splay_tree_key) decl);
8241 if (n == NULL)
8242 continue;
8243 else if (n->value & GOVD_SHARED)
8245 n->value |= GOVD_WRITTEN;
8246 return;
8248 else if (n->value & GOVD_DATA_SHARE_CLASS)
8249 return;
8253 /* Helper callback for walk_gimple_seq to discover possible stores
8254 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
8255 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
8256 for those. */
8258 static tree
8259 omp_find_stores_op (tree *tp, int *walk_subtrees, void *data)
8261 struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
8263 *walk_subtrees = 0;
8264 if (!wi->is_lhs)
8265 return NULL_TREE;
8267 tree op = *tp;
8270 if (handled_component_p (op))
8271 op = TREE_OPERAND (op, 0);
8272 else if ((TREE_CODE (op) == MEM_REF || TREE_CODE (op) == TARGET_MEM_REF)
8273 && TREE_CODE (TREE_OPERAND (op, 0)) == ADDR_EXPR)
8274 op = TREE_OPERAND (TREE_OPERAND (op, 0), 0);
8275 else
8276 break;
8278 while (1);
8279 if (!DECL_P (op) || !omp_shared_to_firstprivate_optimizable_decl_p (op))
8280 return NULL_TREE;
8282 omp_mark_stores (gimplify_omp_ctxp, op);
8283 return NULL_TREE;
8286 /* Helper callback for walk_gimple_seq to discover possible stores
8287 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
8288 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
8289 for those. */
8291 static tree
8292 omp_find_stores_stmt (gimple_stmt_iterator *gsi_p,
8293 bool *handled_ops_p,
8294 struct walk_stmt_info *wi)
8296 gimple *stmt = gsi_stmt (*gsi_p);
8297 switch (gimple_code (stmt))
8299 /* Don't recurse on OpenMP constructs for which
8300 gimplify_adjust_omp_clauses already handled the bodies,
8301 except handle gimple_omp_for_pre_body. */
8302 case GIMPLE_OMP_FOR:
8303 *handled_ops_p = true;
8304 if (gimple_omp_for_pre_body (stmt))
8305 walk_gimple_seq (gimple_omp_for_pre_body (stmt),
8306 omp_find_stores_stmt, omp_find_stores_op, wi);
8307 break;
8308 case GIMPLE_OMP_PARALLEL:
8309 case GIMPLE_OMP_TASK:
8310 case GIMPLE_OMP_SECTIONS:
8311 case GIMPLE_OMP_SINGLE:
8312 case GIMPLE_OMP_TARGET:
8313 case GIMPLE_OMP_TEAMS:
8314 case GIMPLE_OMP_CRITICAL:
8315 *handled_ops_p = true;
8316 break;
8317 default:
8318 break;
8320 return NULL_TREE;
8323 struct gimplify_adjust_omp_clauses_data
8325 tree *list_p;
8326 gimple_seq *pre_p;
8329 /* For all variables that were not actually used within the context,
8330 remove PRIVATE, SHARED, and FIRSTPRIVATE clauses. */
8332 static int
8333 gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
8335 tree *list_p = ((struct gimplify_adjust_omp_clauses_data *) data)->list_p;
8336 gimple_seq *pre_p
8337 = ((struct gimplify_adjust_omp_clauses_data *) data)->pre_p;
8338 tree decl = (tree) n->key;
8339 unsigned flags = n->value;
8340 enum omp_clause_code code;
8341 tree clause;
8342 bool private_debug;
8344 if (flags & (GOVD_EXPLICIT | GOVD_LOCAL))
8345 return 0;
8346 if ((flags & GOVD_SEEN) == 0)
8347 return 0;
8348 if (flags & GOVD_DEBUG_PRIVATE)
8350 gcc_assert ((flags & GOVD_DATA_SHARE_CLASS) == GOVD_PRIVATE);
8351 private_debug = true;
8353 else if (flags & GOVD_MAP)
8354 private_debug = false;
8355 else
8356 private_debug
8357 = lang_hooks.decls.omp_private_debug_clause (decl,
8358 !!(flags & GOVD_SHARED));
8359 if (private_debug)
8360 code = OMP_CLAUSE_PRIVATE;
8361 else if (flags & GOVD_MAP)
8363 code = OMP_CLAUSE_MAP;
8364 if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0
8365 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
8367 error ("%<_Atomic%> %qD in implicit %<map%> clause", decl);
8368 return 0;
8371 else if (flags & GOVD_SHARED)
8373 if (is_global_var (decl))
8375 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
8376 while (ctx != NULL)
8378 splay_tree_node on
8379 = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
8380 if (on && (on->value & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
8381 | GOVD_PRIVATE | GOVD_REDUCTION
8382 | GOVD_LINEAR | GOVD_MAP)) != 0)
8383 break;
8384 ctx = ctx->outer_context;
8386 if (ctx == NULL)
8387 return 0;
8389 code = OMP_CLAUSE_SHARED;
8391 else if (flags & GOVD_PRIVATE)
8392 code = OMP_CLAUSE_PRIVATE;
8393 else if (flags & GOVD_FIRSTPRIVATE)
8395 code = OMP_CLAUSE_FIRSTPRIVATE;
8396 if ((gimplify_omp_ctxp->region_type & ORT_TARGET)
8397 && (gimplify_omp_ctxp->region_type & ORT_ACC) == 0
8398 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
8400 error ("%<_Atomic%> %qD in implicit %<firstprivate%> clause on "
8401 "%<target%> construct", decl);
8402 return 0;
8405 else if (flags & GOVD_LASTPRIVATE)
8406 code = OMP_CLAUSE_LASTPRIVATE;
8407 else if (flags & GOVD_ALIGNED)
8408 return 0;
8409 else
8410 gcc_unreachable ();
8412 if (((flags & GOVD_LASTPRIVATE)
8413 || (code == OMP_CLAUSE_SHARED && (flags & GOVD_WRITTEN)))
8414 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
8415 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
8417 clause = build_omp_clause (input_location, code);
8418 OMP_CLAUSE_DECL (clause) = decl;
8419 OMP_CLAUSE_CHAIN (clause) = *list_p;
8420 if (private_debug)
8421 OMP_CLAUSE_PRIVATE_DEBUG (clause) = 1;
8422 else if (code == OMP_CLAUSE_PRIVATE && (flags & GOVD_PRIVATE_OUTER_REF))
8423 OMP_CLAUSE_PRIVATE_OUTER_REF (clause) = 1;
8424 else if (code == OMP_CLAUSE_SHARED
8425 && (flags & GOVD_WRITTEN) == 0
8426 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
8427 OMP_CLAUSE_SHARED_READONLY (clause) = 1;
8428 else if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_EXPLICIT) == 0)
8429 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (clause) = 1;
8430 else if (code == OMP_CLAUSE_MAP && (flags & GOVD_MAP_0LEN_ARRAY) != 0)
8432 tree nc = build_omp_clause (input_location, OMP_CLAUSE_MAP);
8433 OMP_CLAUSE_DECL (nc) = decl;
8434 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
8435 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == POINTER_TYPE)
8436 OMP_CLAUSE_DECL (clause)
8437 = build_simple_mem_ref_loc (input_location, decl);
8438 OMP_CLAUSE_DECL (clause)
8439 = build2 (MEM_REF, char_type_node, OMP_CLAUSE_DECL (clause),
8440 build_int_cst (build_pointer_type (char_type_node), 0));
8441 OMP_CLAUSE_SIZE (clause) = size_zero_node;
8442 OMP_CLAUSE_SIZE (nc) = size_zero_node;
8443 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_ALLOC);
8444 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (clause) = 1;
8445 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
8446 OMP_CLAUSE_CHAIN (nc) = *list_p;
8447 OMP_CLAUSE_CHAIN (clause) = nc;
8448 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
8449 gimplify_omp_ctxp = ctx->outer_context;
8450 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (clause), 0),
8451 pre_p, NULL, is_gimple_val, fb_rvalue);
8452 gimplify_omp_ctxp = ctx;
8454 else if (code == OMP_CLAUSE_MAP)
8456 int kind = (flags & GOVD_MAP_TO_ONLY
8457 ? GOMP_MAP_TO
8458 : GOMP_MAP_TOFROM);
8459 if (flags & GOVD_MAP_FORCE)
8460 kind |= GOMP_MAP_FLAG_FORCE;
8461 OMP_CLAUSE_SET_MAP_KIND (clause, kind);
8462 if (DECL_SIZE (decl)
8463 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
8465 tree decl2 = DECL_VALUE_EXPR (decl);
8466 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
8467 decl2 = TREE_OPERAND (decl2, 0);
8468 gcc_assert (DECL_P (decl2));
8469 tree mem = build_simple_mem_ref (decl2);
8470 OMP_CLAUSE_DECL (clause) = mem;
8471 OMP_CLAUSE_SIZE (clause) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
8472 if (gimplify_omp_ctxp->outer_context)
8474 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
8475 omp_notice_variable (ctx, decl2, true);
8476 omp_notice_variable (ctx, OMP_CLAUSE_SIZE (clause), true);
8478 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
8479 OMP_CLAUSE_MAP);
8480 OMP_CLAUSE_DECL (nc) = decl;
8481 OMP_CLAUSE_SIZE (nc) = size_zero_node;
8482 if (gimplify_omp_ctxp->target_firstprivatize_array_bases)
8483 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
8484 else
8485 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
8486 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
8487 OMP_CLAUSE_CHAIN (clause) = nc;
8489 else if (gimplify_omp_ctxp->target_firstprivatize_array_bases
8490 && lang_hooks.decls.omp_privatize_by_reference (decl))
8492 OMP_CLAUSE_DECL (clause) = build_simple_mem_ref (decl);
8493 OMP_CLAUSE_SIZE (clause)
8494 = unshare_expr (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))));
8495 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
8496 gimplify_omp_ctxp = ctx->outer_context;
8497 gimplify_expr (&OMP_CLAUSE_SIZE (clause),
8498 pre_p, NULL, is_gimple_val, fb_rvalue);
8499 gimplify_omp_ctxp = ctx;
8500 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
8501 OMP_CLAUSE_MAP);
8502 OMP_CLAUSE_DECL (nc) = decl;
8503 OMP_CLAUSE_SIZE (nc) = size_zero_node;
8504 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_REFERENCE);
8505 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
8506 OMP_CLAUSE_CHAIN (clause) = nc;
8508 else
8509 OMP_CLAUSE_SIZE (clause) = DECL_SIZE_UNIT (decl);
8511 if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_LASTPRIVATE) != 0)
8513 tree nc = build_omp_clause (input_location, OMP_CLAUSE_LASTPRIVATE);
8514 OMP_CLAUSE_DECL (nc) = decl;
8515 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (nc) = 1;
8516 OMP_CLAUSE_CHAIN (nc) = *list_p;
8517 OMP_CLAUSE_CHAIN (clause) = nc;
8518 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
8519 gimplify_omp_ctxp = ctx->outer_context;
8520 lang_hooks.decls.omp_finish_clause (nc, pre_p);
8521 gimplify_omp_ctxp = ctx;
8523 *list_p = clause;
8524 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
8525 gimplify_omp_ctxp = ctx->outer_context;
8526 lang_hooks.decls.omp_finish_clause (clause, pre_p);
8527 gimplify_omp_ctxp = ctx;
8528 return 0;
8531 static void
8532 gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
8533 enum tree_code code)
8535 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
8536 tree c, decl;
8538 if (body)
8540 struct gimplify_omp_ctx *octx;
8541 for (octx = ctx; octx; octx = octx->outer_context)
8542 if ((octx->region_type & (ORT_PARALLEL | ORT_TASK | ORT_TEAMS)) != 0)
8543 break;
8544 if (octx)
8546 struct walk_stmt_info wi;
8547 memset (&wi, 0, sizeof (wi));
8548 walk_gimple_seq (body, omp_find_stores_stmt,
8549 omp_find_stores_op, &wi);
8552 while ((c = *list_p) != NULL)
8554 splay_tree_node n;
8555 bool remove = false;
8557 switch (OMP_CLAUSE_CODE (c))
8559 case OMP_CLAUSE_FIRSTPRIVATE:
8560 if ((ctx->region_type & ORT_TARGET)
8561 && (ctx->region_type & ORT_ACC) == 0
8562 && TYPE_ATOMIC (strip_array_types
8563 (TREE_TYPE (OMP_CLAUSE_DECL (c)))))
8565 error_at (OMP_CLAUSE_LOCATION (c),
8566 "%<_Atomic%> %qD in %<firstprivate%> clause on "
8567 "%<target%> construct", OMP_CLAUSE_DECL (c));
8568 remove = true;
8569 break;
8571 /* FALLTHRU */
8572 case OMP_CLAUSE_PRIVATE:
8573 case OMP_CLAUSE_SHARED:
8574 case OMP_CLAUSE_LINEAR:
8575 decl = OMP_CLAUSE_DECL (c);
8576 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
8577 remove = !(n->value & GOVD_SEEN);
8578 if (! remove)
8580 bool shared = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED;
8581 if ((n->value & GOVD_DEBUG_PRIVATE)
8582 || lang_hooks.decls.omp_private_debug_clause (decl, shared))
8584 gcc_assert ((n->value & GOVD_DEBUG_PRIVATE) == 0
8585 || ((n->value & GOVD_DATA_SHARE_CLASS)
8586 == GOVD_PRIVATE));
8587 OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_PRIVATE);
8588 OMP_CLAUSE_PRIVATE_DEBUG (c) = 1;
8590 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
8591 && (n->value & GOVD_WRITTEN) == 0
8592 && DECL_P (decl)
8593 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
8594 OMP_CLAUSE_SHARED_READONLY (c) = 1;
8595 else if (DECL_P (decl)
8596 && ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
8597 && (n->value & GOVD_WRITTEN) != 1)
8598 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
8599 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
8600 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
8601 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
8603 break;
8605 case OMP_CLAUSE_LASTPRIVATE:
8606 /* Make sure OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE is set to
8607 accurately reflect the presence of a FIRSTPRIVATE clause. */
8608 decl = OMP_CLAUSE_DECL (c);
8609 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
8610 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c)
8611 = (n->value & GOVD_FIRSTPRIVATE) != 0;
8612 if (omp_no_lastprivate (ctx))
8614 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
8615 remove = true;
8616 else
8617 OMP_CLAUSE_CODE (c) = OMP_CLAUSE_PRIVATE;
8619 else if (code == OMP_DISTRIBUTE
8620 && OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
8622 remove = true;
8623 error_at (OMP_CLAUSE_LOCATION (c),
8624 "same variable used in %<firstprivate%> and "
8625 "%<lastprivate%> clauses on %<distribute%> "
8626 "construct");
8628 if (!remove
8629 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
8630 && DECL_P (decl)
8631 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
8632 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
8633 break;
8635 case OMP_CLAUSE_ALIGNED:
8636 decl = OMP_CLAUSE_DECL (c);
8637 if (!is_global_var (decl))
8639 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
8640 remove = n == NULL || !(n->value & GOVD_SEEN);
8641 if (!remove && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
8643 struct gimplify_omp_ctx *octx;
8644 if (n != NULL
8645 && (n->value & (GOVD_DATA_SHARE_CLASS
8646 & ~GOVD_FIRSTPRIVATE)))
8647 remove = true;
8648 else
8649 for (octx = ctx->outer_context; octx;
8650 octx = octx->outer_context)
8652 n = splay_tree_lookup (octx->variables,
8653 (splay_tree_key) decl);
8654 if (n == NULL)
8655 continue;
8656 if (n->value & GOVD_LOCAL)
8657 break;
8658 /* We have to avoid assigning a shared variable
8659 to itself when trying to add
8660 __builtin_assume_aligned. */
8661 if (n->value & GOVD_SHARED)
8663 remove = true;
8664 break;
8669 else if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
8671 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
8672 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
8673 remove = true;
8675 break;
8677 case OMP_CLAUSE_MAP:
8678 if (code == OMP_TARGET_EXIT_DATA
8679 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER)
8681 remove = true;
8682 break;
8684 decl = OMP_CLAUSE_DECL (c);
8685 /* Data clauses associated with acc parallel reductions must be
8686 compatible with present_or_copy. Warn and adjust the clause
8687 if that is not the case. */
8688 if (ctx->region_type == ORT_ACC_PARALLEL)
8690 tree t = DECL_P (decl) ? decl : TREE_OPERAND (decl, 0);
8691 n = NULL;
8693 if (DECL_P (t))
8694 n = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
8696 if (n && (n->value & GOVD_REDUCTION))
8698 enum gomp_map_kind kind = OMP_CLAUSE_MAP_KIND (c);
8700 OMP_CLAUSE_MAP_IN_REDUCTION (c) = 1;
8701 if ((kind & GOMP_MAP_TOFROM) != GOMP_MAP_TOFROM
8702 && kind != GOMP_MAP_FORCE_PRESENT
8703 && kind != GOMP_MAP_POINTER)
8705 warning_at (OMP_CLAUSE_LOCATION (c), 0,
8706 "incompatible data clause with reduction "
8707 "on %qE; promoting to present_or_copy",
8708 DECL_NAME (t));
8709 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TOFROM);
8713 if (!DECL_P (decl))
8715 if ((ctx->region_type & ORT_TARGET) != 0
8716 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
8718 if (TREE_CODE (decl) == INDIRECT_REF
8719 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
8720 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
8721 == REFERENCE_TYPE))
8722 decl = TREE_OPERAND (decl, 0);
8723 if (TREE_CODE (decl) == COMPONENT_REF)
8725 while (TREE_CODE (decl) == COMPONENT_REF)
8726 decl = TREE_OPERAND (decl, 0);
8727 if (DECL_P (decl))
8729 n = splay_tree_lookup (ctx->variables,
8730 (splay_tree_key) decl);
8731 if (!(n->value & GOVD_SEEN))
8732 remove = true;
8736 break;
8738 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
8739 if ((ctx->region_type & ORT_TARGET) != 0
8740 && !(n->value & GOVD_SEEN)
8741 && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) == 0
8742 && !lookup_attribute ("omp declare target link",
8743 DECL_ATTRIBUTES (decl)))
8745 remove = true;
8746 /* For struct element mapping, if struct is never referenced
8747 in target block and none of the mapping has always modifier,
8748 remove all the struct element mappings, which immediately
8749 follow the GOMP_MAP_STRUCT map clause. */
8750 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT)
8752 HOST_WIDE_INT cnt = tree_to_shwi (OMP_CLAUSE_SIZE (c));
8753 while (cnt--)
8754 OMP_CLAUSE_CHAIN (c)
8755 = OMP_CLAUSE_CHAIN (OMP_CLAUSE_CHAIN (c));
8758 else if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT
8759 && code == OMP_TARGET_EXIT_DATA)
8760 remove = true;
8761 else if (DECL_SIZE (decl)
8762 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST
8763 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_POINTER
8764 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_POINTER
8765 && (OMP_CLAUSE_MAP_KIND (c)
8766 != GOMP_MAP_FIRSTPRIVATE_REFERENCE))
8768 /* For GOMP_MAP_FORCE_DEVICEPTR, we'll never enter here, because
8769 for these, TREE_CODE (DECL_SIZE (decl)) will always be
8770 INTEGER_CST. */
8771 gcc_assert (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FORCE_DEVICEPTR);
8773 tree decl2 = DECL_VALUE_EXPR (decl);
8774 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
8775 decl2 = TREE_OPERAND (decl2, 0);
8776 gcc_assert (DECL_P (decl2));
8777 tree mem = build_simple_mem_ref (decl2);
8778 OMP_CLAUSE_DECL (c) = mem;
8779 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
8780 if (ctx->outer_context)
8782 omp_notice_variable (ctx->outer_context, decl2, true);
8783 omp_notice_variable (ctx->outer_context,
8784 OMP_CLAUSE_SIZE (c), true);
8786 if (((ctx->region_type & ORT_TARGET) != 0
8787 || !ctx->target_firstprivatize_array_bases)
8788 && ((n->value & GOVD_SEEN) == 0
8789 || (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) == 0))
8791 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
8792 OMP_CLAUSE_MAP);
8793 OMP_CLAUSE_DECL (nc) = decl;
8794 OMP_CLAUSE_SIZE (nc) = size_zero_node;
8795 if (ctx->target_firstprivatize_array_bases)
8796 OMP_CLAUSE_SET_MAP_KIND (nc,
8797 GOMP_MAP_FIRSTPRIVATE_POINTER);
8798 else
8799 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
8800 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
8801 OMP_CLAUSE_CHAIN (c) = nc;
8802 c = nc;
8805 else
8807 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
8808 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
8809 gcc_assert ((n->value & GOVD_SEEN) == 0
8810 || ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
8811 == 0));
8813 break;
8815 case OMP_CLAUSE_TO:
8816 case OMP_CLAUSE_FROM:
8817 case OMP_CLAUSE__CACHE_:
8818 decl = OMP_CLAUSE_DECL (c);
8819 if (!DECL_P (decl))
8820 break;
8821 if (DECL_SIZE (decl)
8822 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
8824 tree decl2 = DECL_VALUE_EXPR (decl);
8825 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
8826 decl2 = TREE_OPERAND (decl2, 0);
8827 gcc_assert (DECL_P (decl2));
8828 tree mem = build_simple_mem_ref (decl2);
8829 OMP_CLAUSE_DECL (c) = mem;
8830 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
8831 if (ctx->outer_context)
8833 omp_notice_variable (ctx->outer_context, decl2, true);
8834 omp_notice_variable (ctx->outer_context,
8835 OMP_CLAUSE_SIZE (c), true);
8838 else if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
8839 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
8840 break;
8842 case OMP_CLAUSE_REDUCTION:
8843 decl = OMP_CLAUSE_DECL (c);
8844 /* OpenACC reductions need a present_or_copy data clause.
8845 Add one if necessary. Error is the reduction is private. */
8846 if (ctx->region_type == ORT_ACC_PARALLEL)
8848 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
8849 if (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
8850 error_at (OMP_CLAUSE_LOCATION (c), "invalid private "
8851 "reduction on %qE", DECL_NAME (decl));
8852 else if ((n->value & GOVD_MAP) == 0)
8854 tree next = OMP_CLAUSE_CHAIN (c);
8855 tree nc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_MAP);
8856 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_TOFROM);
8857 OMP_CLAUSE_DECL (nc) = decl;
8858 OMP_CLAUSE_CHAIN (c) = nc;
8859 lang_hooks.decls.omp_finish_clause (nc, pre_p);
8860 while (1)
8862 OMP_CLAUSE_MAP_IN_REDUCTION (nc) = 1;
8863 if (OMP_CLAUSE_CHAIN (nc) == NULL)
8864 break;
8865 nc = OMP_CLAUSE_CHAIN (nc);
8867 OMP_CLAUSE_CHAIN (nc) = next;
8868 n->value |= GOVD_MAP;
8871 if (DECL_P (decl)
8872 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
8873 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
8874 break;
8875 case OMP_CLAUSE_COPYIN:
8876 case OMP_CLAUSE_COPYPRIVATE:
8877 case OMP_CLAUSE_IF:
8878 case OMP_CLAUSE_NUM_THREADS:
8879 case OMP_CLAUSE_NUM_TEAMS:
8880 case OMP_CLAUSE_THREAD_LIMIT:
8881 case OMP_CLAUSE_DIST_SCHEDULE:
8882 case OMP_CLAUSE_DEVICE:
8883 case OMP_CLAUSE_SCHEDULE:
8884 case OMP_CLAUSE_NOWAIT:
8885 case OMP_CLAUSE_ORDERED:
8886 case OMP_CLAUSE_DEFAULT:
8887 case OMP_CLAUSE_UNTIED:
8888 case OMP_CLAUSE_COLLAPSE:
8889 case OMP_CLAUSE_FINAL:
8890 case OMP_CLAUSE_MERGEABLE:
8891 case OMP_CLAUSE_PROC_BIND:
8892 case OMP_CLAUSE_SAFELEN:
8893 case OMP_CLAUSE_SIMDLEN:
8894 case OMP_CLAUSE_DEPEND:
8895 case OMP_CLAUSE_PRIORITY:
8896 case OMP_CLAUSE_GRAINSIZE:
8897 case OMP_CLAUSE_NUM_TASKS:
8898 case OMP_CLAUSE_NOGROUP:
8899 case OMP_CLAUSE_THREADS:
8900 case OMP_CLAUSE_SIMD:
8901 case OMP_CLAUSE_HINT:
8902 case OMP_CLAUSE_DEFAULTMAP:
8903 case OMP_CLAUSE_USE_DEVICE_PTR:
8904 case OMP_CLAUSE_IS_DEVICE_PTR:
8905 case OMP_CLAUSE__CILK_FOR_COUNT_:
8906 case OMP_CLAUSE_ASYNC:
8907 case OMP_CLAUSE_WAIT:
8908 case OMP_CLAUSE_INDEPENDENT:
8909 case OMP_CLAUSE_NUM_GANGS:
8910 case OMP_CLAUSE_NUM_WORKERS:
8911 case OMP_CLAUSE_VECTOR_LENGTH:
8912 case OMP_CLAUSE_GANG:
8913 case OMP_CLAUSE_WORKER:
8914 case OMP_CLAUSE_VECTOR:
8915 case OMP_CLAUSE_AUTO:
8916 case OMP_CLAUSE_SEQ:
8917 break;
8919 case OMP_CLAUSE_TILE:
8920 /* We're not yet making use of the information provided by OpenACC
8921 tile clauses. Discard these here, to simplify later middle end
8922 processing. */
8923 remove = true;
8924 break;
8926 default:
8927 gcc_unreachable ();
8930 if (remove)
8931 *list_p = OMP_CLAUSE_CHAIN (c);
8932 else
8933 list_p = &OMP_CLAUSE_CHAIN (c);
8936 /* Add in any implicit data sharing. */
8937 struct gimplify_adjust_omp_clauses_data data;
8938 data.list_p = list_p;
8939 data.pre_p = pre_p;
8940 splay_tree_foreach (ctx->variables, gimplify_adjust_omp_clauses_1, &data);
8942 gimplify_omp_ctxp = ctx->outer_context;
8943 delete_omp_context (ctx);
8946 /* Gimplify OACC_CACHE. */
8948 static void
8949 gimplify_oacc_cache (tree *expr_p, gimple_seq *pre_p)
8951 tree expr = *expr_p;
8953 gimplify_scan_omp_clauses (&OACC_CACHE_CLAUSES (expr), pre_p, ORT_ACC,
8954 OACC_CACHE);
8955 gimplify_adjust_omp_clauses (pre_p, NULL, &OACC_CACHE_CLAUSES (expr),
8956 OACC_CACHE);
8958 /* TODO: Do something sensible with this information. */
8960 *expr_p = NULL_TREE;
8963 /* Helper function of gimplify_oacc_declare. The helper's purpose is to,
8964 if required, translate 'kind' in CLAUSE into an 'entry' kind and 'exit'
8965 kind. The entry kind will replace the one in CLAUSE, while the exit
8966 kind will be used in a new omp_clause and returned to the caller. */
8968 static tree
8969 gimplify_oacc_declare_1 (tree clause)
8971 HOST_WIDE_INT kind, new_op;
8972 bool ret = false;
8973 tree c = NULL;
8975 kind = OMP_CLAUSE_MAP_KIND (clause);
8977 switch (kind)
8979 case GOMP_MAP_ALLOC:
8980 case GOMP_MAP_FORCE_ALLOC:
8981 case GOMP_MAP_FORCE_TO:
8982 new_op = GOMP_MAP_DELETE;
8983 ret = true;
8984 break;
8986 case GOMP_MAP_FORCE_FROM:
8987 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_FORCE_ALLOC);
8988 new_op = GOMP_MAP_FORCE_FROM;
8989 ret = true;
8990 break;
8992 case GOMP_MAP_FORCE_TOFROM:
8993 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_FORCE_TO);
8994 new_op = GOMP_MAP_FORCE_FROM;
8995 ret = true;
8996 break;
8998 case GOMP_MAP_FROM:
8999 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_FORCE_ALLOC);
9000 new_op = GOMP_MAP_FROM;
9001 ret = true;
9002 break;
9004 case GOMP_MAP_TOFROM:
9005 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_TO);
9006 new_op = GOMP_MAP_FROM;
9007 ret = true;
9008 break;
9010 case GOMP_MAP_DEVICE_RESIDENT:
9011 case GOMP_MAP_FORCE_DEVICEPTR:
9012 case GOMP_MAP_FORCE_PRESENT:
9013 case GOMP_MAP_LINK:
9014 case GOMP_MAP_POINTER:
9015 case GOMP_MAP_TO:
9016 break;
9018 default:
9019 gcc_unreachable ();
9020 break;
9023 if (ret)
9025 c = build_omp_clause (OMP_CLAUSE_LOCATION (clause), OMP_CLAUSE_MAP);
9026 OMP_CLAUSE_SET_MAP_KIND (c, new_op);
9027 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clause);
9030 return c;
9033 /* Gimplify OACC_DECLARE. */
9035 static void
9036 gimplify_oacc_declare (tree *expr_p, gimple_seq *pre_p)
9038 tree expr = *expr_p;
9039 gomp_target *stmt;
9040 tree clauses, t;
9042 clauses = OACC_DECLARE_CLAUSES (expr);
9044 gimplify_scan_omp_clauses (&clauses, pre_p, ORT_TARGET_DATA, OACC_DECLARE);
9046 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
9048 tree decl = OMP_CLAUSE_DECL (t);
9050 if (TREE_CODE (decl) == MEM_REF)
9051 continue;
9053 if (TREE_CODE (decl) == VAR_DECL
9054 && !is_global_var (decl)
9055 && DECL_CONTEXT (decl) == current_function_decl)
9057 tree c = gimplify_oacc_declare_1 (t);
9058 if (c)
9060 if (oacc_declare_returns == NULL)
9061 oacc_declare_returns = new hash_map<tree, tree>;
9063 oacc_declare_returns->put (decl, c);
9067 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_SEEN);
9070 stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
9071 clauses);
9073 gimplify_seq_add_stmt (pre_p, stmt);
9075 *expr_p = NULL_TREE;
9078 /* Gimplify the contents of an OMP_PARALLEL statement. This involves
9079 gimplification of the body, as well as scanning the body for used
9080 variables. We need to do this scan now, because variable-sized
9081 decls will be decomposed during gimplification. */
9083 static void
9084 gimplify_omp_parallel (tree *expr_p, gimple_seq *pre_p)
9086 tree expr = *expr_p;
9087 gimple *g;
9088 gimple_seq body = NULL;
9090 gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr), pre_p,
9091 OMP_PARALLEL_COMBINED (expr)
9092 ? ORT_COMBINED_PARALLEL
9093 : ORT_PARALLEL, OMP_PARALLEL);
9095 push_gimplify_context ();
9097 g = gimplify_and_return_first (OMP_PARALLEL_BODY (expr), &body);
9098 if (gimple_code (g) == GIMPLE_BIND)
9099 pop_gimplify_context (g);
9100 else
9101 pop_gimplify_context (NULL);
9103 gimplify_adjust_omp_clauses (pre_p, body, &OMP_PARALLEL_CLAUSES (expr),
9104 OMP_PARALLEL);
9106 g = gimple_build_omp_parallel (body,
9107 OMP_PARALLEL_CLAUSES (expr),
9108 NULL_TREE, NULL_TREE);
9109 if (OMP_PARALLEL_COMBINED (expr))
9110 gimple_omp_set_subcode (g, GF_OMP_PARALLEL_COMBINED);
9111 gimplify_seq_add_stmt (pre_p, g);
9112 *expr_p = NULL_TREE;
9115 /* Gimplify the contents of an OMP_TASK statement. This involves
9116 gimplification of the body, as well as scanning the body for used
9117 variables. We need to do this scan now, because variable-sized
9118 decls will be decomposed during gimplification. */
9120 static void
9121 gimplify_omp_task (tree *expr_p, gimple_seq *pre_p)
9123 tree expr = *expr_p;
9124 gimple *g;
9125 gimple_seq body = NULL;
9127 gimplify_scan_omp_clauses (&OMP_TASK_CLAUSES (expr), pre_p,
9128 find_omp_clause (OMP_TASK_CLAUSES (expr),
9129 OMP_CLAUSE_UNTIED)
9130 ? ORT_UNTIED_TASK : ORT_TASK, OMP_TASK);
9132 push_gimplify_context ();
9134 g = gimplify_and_return_first (OMP_TASK_BODY (expr), &body);
9135 if (gimple_code (g) == GIMPLE_BIND)
9136 pop_gimplify_context (g);
9137 else
9138 pop_gimplify_context (NULL);
9140 gimplify_adjust_omp_clauses (pre_p, body, &OMP_TASK_CLAUSES (expr),
9141 OMP_TASK);
9143 g = gimple_build_omp_task (body,
9144 OMP_TASK_CLAUSES (expr),
9145 NULL_TREE, NULL_TREE,
9146 NULL_TREE, NULL_TREE, NULL_TREE);
9147 gimplify_seq_add_stmt (pre_p, g);
9148 *expr_p = NULL_TREE;
9151 /* Helper function of gimplify_omp_for, find OMP_FOR resp. OMP_SIMD
9152 with non-NULL OMP_FOR_INIT. */
9154 static tree
9155 find_combined_omp_for (tree *tp, int *walk_subtrees, void *)
9157 *walk_subtrees = 0;
9158 switch (TREE_CODE (*tp))
9160 case OMP_FOR:
9161 *walk_subtrees = 1;
9162 /* FALLTHRU */
9163 case OMP_SIMD:
9164 if (OMP_FOR_INIT (*tp) != NULL_TREE)
9165 return *tp;
9166 break;
9167 case BIND_EXPR:
9168 case STATEMENT_LIST:
9169 case OMP_PARALLEL:
9170 *walk_subtrees = 1;
9171 break;
9172 default:
9173 break;
9175 return NULL_TREE;
9178 /* Gimplify the gross structure of an OMP_FOR statement. */
9180 static enum gimplify_status
9181 gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
9183 tree for_stmt, orig_for_stmt, inner_for_stmt = NULL_TREE, decl, var, t;
9184 enum gimplify_status ret = GS_ALL_DONE;
9185 enum gimplify_status tret;
9186 gomp_for *gfor;
9187 gimple_seq for_body, for_pre_body;
9188 int i;
9189 bitmap has_decl_expr = NULL;
9190 enum omp_region_type ort = ORT_WORKSHARE;
9192 orig_for_stmt = for_stmt = *expr_p;
9194 switch (TREE_CODE (for_stmt))
9196 case OMP_FOR:
9197 case CILK_FOR:
9198 case OMP_DISTRIBUTE:
9199 break;
9200 case OACC_LOOP:
9201 ort = ORT_ACC;
9202 break;
9203 case OMP_TASKLOOP:
9204 if (find_omp_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_UNTIED))
9205 ort = ORT_UNTIED_TASK;
9206 else
9207 ort = ORT_TASK;
9208 break;
9209 case OMP_SIMD:
9210 case CILK_SIMD:
9211 ort = ORT_SIMD;
9212 break;
9213 default:
9214 gcc_unreachable ();
9217 /* Set OMP_CLAUSE_LINEAR_NO_COPYIN flag on explicit linear
9218 clause for the IV. */
9219 if (ort == ORT_SIMD && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
9221 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), 0);
9222 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
9223 decl = TREE_OPERAND (t, 0);
9224 for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
9225 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
9226 && OMP_CLAUSE_DECL (c) == decl)
9228 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
9229 break;
9233 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
9235 gcc_assert (TREE_CODE (for_stmt) != OACC_LOOP);
9236 inner_for_stmt = walk_tree (&OMP_FOR_BODY (for_stmt),
9237 find_combined_omp_for, NULL, NULL);
9238 if (inner_for_stmt == NULL_TREE)
9240 gcc_assert (seen_error ());
9241 *expr_p = NULL_TREE;
9242 return GS_ERROR;
9246 if (TREE_CODE (for_stmt) != OMP_TASKLOOP)
9247 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p, ort,
9248 TREE_CODE (for_stmt));
9250 if (TREE_CODE (for_stmt) == OMP_DISTRIBUTE)
9251 gimplify_omp_ctxp->distribute = true;
9253 /* Handle OMP_FOR_INIT. */
9254 for_pre_body = NULL;
9255 if (ort == ORT_SIMD && OMP_FOR_PRE_BODY (for_stmt))
9257 has_decl_expr = BITMAP_ALLOC (NULL);
9258 if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == DECL_EXPR
9259 && TREE_CODE (DECL_EXPR_DECL (OMP_FOR_PRE_BODY (for_stmt)))
9260 == VAR_DECL)
9262 t = OMP_FOR_PRE_BODY (for_stmt);
9263 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
9265 else if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == STATEMENT_LIST)
9267 tree_stmt_iterator si;
9268 for (si = tsi_start (OMP_FOR_PRE_BODY (for_stmt)); !tsi_end_p (si);
9269 tsi_next (&si))
9271 t = tsi_stmt (si);
9272 if (TREE_CODE (t) == DECL_EXPR
9273 && TREE_CODE (DECL_EXPR_DECL (t)) == VAR_DECL)
9274 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
9278 if (OMP_FOR_PRE_BODY (for_stmt))
9280 if (TREE_CODE (for_stmt) != OMP_TASKLOOP || gimplify_omp_ctxp)
9281 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
9282 else
9284 struct gimplify_omp_ctx ctx;
9285 memset (&ctx, 0, sizeof (ctx));
9286 ctx.region_type = ORT_NONE;
9287 gimplify_omp_ctxp = &ctx;
9288 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
9289 gimplify_omp_ctxp = NULL;
9292 OMP_FOR_PRE_BODY (for_stmt) = NULL_TREE;
9294 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
9295 for_stmt = inner_for_stmt;
9297 /* For taskloop, need to gimplify the start, end and step before the
9298 taskloop, outside of the taskloop omp context. */
9299 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
9301 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
9303 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
9304 if (!is_gimple_constant (TREE_OPERAND (t, 1)))
9306 TREE_OPERAND (t, 1)
9307 = get_initialized_tmp_var (TREE_OPERAND (t, 1),
9308 pre_p, NULL, false);
9309 tree c = build_omp_clause (input_location,
9310 OMP_CLAUSE_FIRSTPRIVATE);
9311 OMP_CLAUSE_DECL (c) = TREE_OPERAND (t, 1);
9312 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
9313 OMP_FOR_CLAUSES (orig_for_stmt) = c;
9316 /* Handle OMP_FOR_COND. */
9317 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
9318 if (!is_gimple_constant (TREE_OPERAND (t, 1)))
9320 TREE_OPERAND (t, 1)
9321 = get_initialized_tmp_var (TREE_OPERAND (t, 1),
9322 gimple_seq_empty_p (for_pre_body)
9323 ? pre_p : &for_pre_body, NULL,
9324 false);
9325 tree c = build_omp_clause (input_location,
9326 OMP_CLAUSE_FIRSTPRIVATE);
9327 OMP_CLAUSE_DECL (c) = TREE_OPERAND (t, 1);
9328 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
9329 OMP_FOR_CLAUSES (orig_for_stmt) = c;
9332 /* Handle OMP_FOR_INCR. */
9333 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
9334 if (TREE_CODE (t) == MODIFY_EXPR)
9336 decl = TREE_OPERAND (t, 0);
9337 t = TREE_OPERAND (t, 1);
9338 tree *tp = &TREE_OPERAND (t, 1);
9339 if (TREE_CODE (t) == PLUS_EXPR && *tp == decl)
9340 tp = &TREE_OPERAND (t, 0);
9342 if (!is_gimple_constant (*tp))
9344 gimple_seq *seq = gimple_seq_empty_p (for_pre_body)
9345 ? pre_p : &for_pre_body;
9346 *tp = get_initialized_tmp_var (*tp, seq, NULL, false);
9347 tree c = build_omp_clause (input_location,
9348 OMP_CLAUSE_FIRSTPRIVATE);
9349 OMP_CLAUSE_DECL (c) = *tp;
9350 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
9351 OMP_FOR_CLAUSES (orig_for_stmt) = c;
9356 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (orig_for_stmt), pre_p, ort,
9357 OMP_TASKLOOP);
9360 if (orig_for_stmt != for_stmt)
9361 gimplify_omp_ctxp->combined_loop = true;
9363 for_body = NULL;
9364 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
9365 == TREE_VEC_LENGTH (OMP_FOR_COND (for_stmt)));
9366 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
9367 == TREE_VEC_LENGTH (OMP_FOR_INCR (for_stmt)));
9369 tree c = find_omp_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED);
9370 bool is_doacross = false;
9371 if (c && OMP_CLAUSE_ORDERED_EXPR (c))
9373 is_doacross = true;
9374 gimplify_omp_ctxp->loop_iter_var.create (TREE_VEC_LENGTH
9375 (OMP_FOR_INIT (for_stmt))
9376 * 2);
9378 int collapse = 1;
9379 c = find_omp_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_COLLAPSE);
9380 if (c)
9381 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (c));
9382 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
9384 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
9385 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
9386 decl = TREE_OPERAND (t, 0);
9387 gcc_assert (DECL_P (decl));
9388 gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl))
9389 || POINTER_TYPE_P (TREE_TYPE (decl)));
9390 if (is_doacross)
9392 if (TREE_CODE (for_stmt) == OMP_FOR && OMP_FOR_ORIG_DECLS (for_stmt))
9393 gimplify_omp_ctxp->loop_iter_var.quick_push
9394 (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i));
9395 else
9396 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
9397 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
9400 /* Make sure the iteration variable is private. */
9401 tree c = NULL_TREE;
9402 tree c2 = NULL_TREE;
9403 if (orig_for_stmt != for_stmt)
9404 /* Do this only on innermost construct for combined ones. */;
9405 else if (ort == ORT_SIMD)
9407 splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
9408 (splay_tree_key) decl);
9409 omp_is_private (gimplify_omp_ctxp, decl,
9410 1 + (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
9411 != 1));
9412 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
9413 omp_notice_variable (gimplify_omp_ctxp, decl, true);
9414 else if (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
9416 c = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
9417 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
9418 unsigned int flags = GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN;
9419 if ((has_decl_expr
9420 && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
9421 || omp_no_lastprivate (gimplify_omp_ctxp))
9423 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
9424 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
9426 struct gimplify_omp_ctx *outer
9427 = gimplify_omp_ctxp->outer_context;
9428 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
9430 if (outer->region_type == ORT_WORKSHARE
9431 && outer->combined_loop)
9433 n = splay_tree_lookup (outer->variables,
9434 (splay_tree_key)decl);
9435 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
9437 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
9438 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
9440 else
9442 struct gimplify_omp_ctx *octx = outer->outer_context;
9443 if (octx
9444 && octx->region_type == ORT_COMBINED_PARALLEL
9445 && octx->outer_context
9446 && (octx->outer_context->region_type
9447 == ORT_WORKSHARE)
9448 && octx->outer_context->combined_loop)
9450 octx = octx->outer_context;
9451 n = splay_tree_lookup (octx->variables,
9452 (splay_tree_key)decl);
9453 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
9455 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
9456 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
9463 OMP_CLAUSE_DECL (c) = decl;
9464 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
9465 OMP_FOR_CLAUSES (for_stmt) = c;
9466 omp_add_variable (gimplify_omp_ctxp, decl, flags);
9467 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
9469 if (outer->region_type == ORT_WORKSHARE
9470 && outer->combined_loop)
9472 if (outer->outer_context
9473 && (outer->outer_context->region_type
9474 == ORT_COMBINED_PARALLEL))
9475 outer = outer->outer_context;
9476 else if (omp_check_private (outer, decl, false))
9477 outer = NULL;
9479 else if (((outer->region_type & ORT_TASK) != 0)
9480 && outer->combined_loop
9481 && !omp_check_private (gimplify_omp_ctxp,
9482 decl, false))
9484 else if (outer->region_type != ORT_COMBINED_PARALLEL)
9486 omp_notice_variable (outer, decl, true);
9487 outer = NULL;
9489 if (outer)
9491 n = splay_tree_lookup (outer->variables,
9492 (splay_tree_key)decl);
9493 if (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
9495 omp_add_variable (outer, decl,
9496 GOVD_LASTPRIVATE | GOVD_SEEN);
9497 if (outer->region_type == ORT_COMBINED_PARALLEL
9498 && outer->outer_context
9499 && (outer->outer_context->region_type
9500 == ORT_WORKSHARE)
9501 && outer->outer_context->combined_loop)
9503 outer = outer->outer_context;
9504 n = splay_tree_lookup (outer->variables,
9505 (splay_tree_key)decl);
9506 if (omp_check_private (outer, decl, false))
9507 outer = NULL;
9508 else if (n == NULL
9509 || ((n->value & GOVD_DATA_SHARE_CLASS)
9510 == 0))
9511 omp_add_variable (outer, decl,
9512 GOVD_LASTPRIVATE
9513 | GOVD_SEEN);
9514 else
9515 outer = NULL;
9517 if (outer && outer->outer_context
9518 && (outer->outer_context->region_type
9519 == ORT_COMBINED_TEAMS))
9521 outer = outer->outer_context;
9522 n = splay_tree_lookup (outer->variables,
9523 (splay_tree_key)decl);
9524 if (n == NULL
9525 || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
9526 omp_add_variable (outer, decl,
9527 GOVD_SHARED | GOVD_SEEN);
9528 else
9529 outer = NULL;
9531 if (outer && outer->outer_context)
9532 omp_notice_variable (outer->outer_context, decl,
9533 true);
9538 else
9540 bool lastprivate
9541 = (!has_decl_expr
9542 || !bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
9543 && !omp_no_lastprivate (gimplify_omp_ctxp);
9544 struct gimplify_omp_ctx *outer
9545 = gimplify_omp_ctxp->outer_context;
9546 if (outer && lastprivate)
9548 if (outer->region_type == ORT_WORKSHARE
9549 && outer->combined_loop)
9551 n = splay_tree_lookup (outer->variables,
9552 (splay_tree_key)decl);
9553 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
9555 lastprivate = false;
9556 outer = NULL;
9558 else if (outer->outer_context
9559 && (outer->outer_context->region_type
9560 == ORT_COMBINED_PARALLEL))
9561 outer = outer->outer_context;
9562 else if (omp_check_private (outer, decl, false))
9563 outer = NULL;
9565 else if (((outer->region_type & ORT_TASK) != 0)
9566 && outer->combined_loop
9567 && !omp_check_private (gimplify_omp_ctxp,
9568 decl, false))
9570 else if (outer->region_type != ORT_COMBINED_PARALLEL)
9572 omp_notice_variable (outer, decl, true);
9573 outer = NULL;
9575 if (outer)
9577 n = splay_tree_lookup (outer->variables,
9578 (splay_tree_key)decl);
9579 if (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
9581 omp_add_variable (outer, decl,
9582 GOVD_LASTPRIVATE | GOVD_SEEN);
9583 if (outer->region_type == ORT_COMBINED_PARALLEL
9584 && outer->outer_context
9585 && (outer->outer_context->region_type
9586 == ORT_WORKSHARE)
9587 && outer->outer_context->combined_loop)
9589 outer = outer->outer_context;
9590 n = splay_tree_lookup (outer->variables,
9591 (splay_tree_key)decl);
9592 if (omp_check_private (outer, decl, false))
9593 outer = NULL;
9594 else if (n == NULL
9595 || ((n->value & GOVD_DATA_SHARE_CLASS)
9596 == 0))
9597 omp_add_variable (outer, decl,
9598 GOVD_LASTPRIVATE
9599 | GOVD_SEEN);
9600 else
9601 outer = NULL;
9603 if (outer && outer->outer_context
9604 && (outer->outer_context->region_type
9605 == ORT_COMBINED_TEAMS))
9607 outer = outer->outer_context;
9608 n = splay_tree_lookup (outer->variables,
9609 (splay_tree_key)decl);
9610 if (n == NULL
9611 || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
9612 omp_add_variable (outer, decl,
9613 GOVD_SHARED | GOVD_SEEN);
9614 else
9615 outer = NULL;
9617 if (outer && outer->outer_context)
9618 omp_notice_variable (outer->outer_context, decl,
9619 true);
9624 c = build_omp_clause (input_location,
9625 lastprivate ? OMP_CLAUSE_LASTPRIVATE
9626 : OMP_CLAUSE_PRIVATE);
9627 OMP_CLAUSE_DECL (c) = decl;
9628 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
9629 OMP_FOR_CLAUSES (for_stmt) = c;
9630 omp_add_variable (gimplify_omp_ctxp, decl,
9631 (lastprivate ? GOVD_LASTPRIVATE : GOVD_PRIVATE)
9632 | GOVD_EXPLICIT | GOVD_SEEN);
9633 c = NULL_TREE;
9636 else if (omp_is_private (gimplify_omp_ctxp, decl, 0))
9637 omp_notice_variable (gimplify_omp_ctxp, decl, true);
9638 else
9639 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN);
9641 /* If DECL is not a gimple register, create a temporary variable to act
9642 as an iteration counter. This is valid, since DECL cannot be
9643 modified in the body of the loop. Similarly for any iteration vars
9644 in simd with collapse > 1 where the iterator vars must be
9645 lastprivate. */
9646 if (orig_for_stmt != for_stmt)
9647 var = decl;
9648 else if (!is_gimple_reg (decl)
9649 || (ort == ORT_SIMD
9650 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) > 1))
9652 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
9653 /* Make sure omp_add_variable is not called on it prematurely.
9654 We call it ourselves a few lines later. */
9655 gimplify_omp_ctxp = NULL;
9656 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
9657 gimplify_omp_ctxp = ctx;
9658 TREE_OPERAND (t, 0) = var;
9660 gimplify_seq_add_stmt (&for_body, gimple_build_assign (decl, var));
9662 if (ort == ORT_SIMD
9663 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
9665 c2 = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
9666 OMP_CLAUSE_LINEAR_NO_COPYIN (c2) = 1;
9667 OMP_CLAUSE_LINEAR_NO_COPYOUT (c2) = 1;
9668 OMP_CLAUSE_DECL (c2) = var;
9669 OMP_CLAUSE_CHAIN (c2) = OMP_FOR_CLAUSES (for_stmt);
9670 OMP_FOR_CLAUSES (for_stmt) = c2;
9671 omp_add_variable (gimplify_omp_ctxp, var,
9672 GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN);
9673 if (c == NULL_TREE)
9675 c = c2;
9676 c2 = NULL_TREE;
9679 else
9680 omp_add_variable (gimplify_omp_ctxp, var,
9681 GOVD_PRIVATE | GOVD_SEEN);
9683 else
9684 var = decl;
9686 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
9687 is_gimple_val, fb_rvalue, false);
9688 ret = MIN (ret, tret);
9689 if (ret == GS_ERROR)
9690 return ret;
9692 /* Handle OMP_FOR_COND. */
9693 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
9694 gcc_assert (COMPARISON_CLASS_P (t));
9695 gcc_assert (TREE_OPERAND (t, 0) == decl);
9697 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
9698 is_gimple_val, fb_rvalue, false);
9699 ret = MIN (ret, tret);
9701 /* Handle OMP_FOR_INCR. */
9702 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
9703 switch (TREE_CODE (t))
9705 case PREINCREMENT_EXPR:
9706 case POSTINCREMENT_EXPR:
9708 tree decl = TREE_OPERAND (t, 0);
9709 /* c_omp_for_incr_canonicalize_ptr() should have been
9710 called to massage things appropriately. */
9711 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
9713 if (orig_for_stmt != for_stmt)
9714 break;
9715 t = build_int_cst (TREE_TYPE (decl), 1);
9716 if (c)
9717 OMP_CLAUSE_LINEAR_STEP (c) = t;
9718 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
9719 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
9720 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
9721 break;
9724 case PREDECREMENT_EXPR:
9725 case POSTDECREMENT_EXPR:
9726 /* c_omp_for_incr_canonicalize_ptr() should have been
9727 called to massage things appropriately. */
9728 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
9729 if (orig_for_stmt != for_stmt)
9730 break;
9731 t = build_int_cst (TREE_TYPE (decl), -1);
9732 if (c)
9733 OMP_CLAUSE_LINEAR_STEP (c) = t;
9734 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
9735 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
9736 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
9737 break;
9739 case MODIFY_EXPR:
9740 gcc_assert (TREE_OPERAND (t, 0) == decl);
9741 TREE_OPERAND (t, 0) = var;
9743 t = TREE_OPERAND (t, 1);
9744 switch (TREE_CODE (t))
9746 case PLUS_EXPR:
9747 if (TREE_OPERAND (t, 1) == decl)
9749 TREE_OPERAND (t, 1) = TREE_OPERAND (t, 0);
9750 TREE_OPERAND (t, 0) = var;
9751 break;
9754 /* Fallthru. */
9755 case MINUS_EXPR:
9756 case POINTER_PLUS_EXPR:
9757 gcc_assert (TREE_OPERAND (t, 0) == decl);
9758 TREE_OPERAND (t, 0) = var;
9759 break;
9760 default:
9761 gcc_unreachable ();
9764 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
9765 is_gimple_val, fb_rvalue, false);
9766 ret = MIN (ret, tret);
9767 if (c)
9769 tree step = TREE_OPERAND (t, 1);
9770 tree stept = TREE_TYPE (decl);
9771 if (POINTER_TYPE_P (stept))
9772 stept = sizetype;
9773 step = fold_convert (stept, step);
9774 if (TREE_CODE (t) == MINUS_EXPR)
9775 step = fold_build1 (NEGATE_EXPR, stept, step);
9776 OMP_CLAUSE_LINEAR_STEP (c) = step;
9777 if (step != TREE_OPERAND (t, 1))
9779 tret = gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c),
9780 &for_pre_body, NULL,
9781 is_gimple_val, fb_rvalue, false);
9782 ret = MIN (ret, tret);
9785 break;
9787 default:
9788 gcc_unreachable ();
9791 if (c2)
9793 gcc_assert (c);
9794 OMP_CLAUSE_LINEAR_STEP (c2) = OMP_CLAUSE_LINEAR_STEP (c);
9797 if ((var != decl || collapse > 1) && orig_for_stmt == for_stmt)
9799 for (c = OMP_FOR_CLAUSES (for_stmt); c ; c = OMP_CLAUSE_CHAIN (c))
9800 if (((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
9801 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) == NULL)
9802 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
9803 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)
9804 && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c) == NULL))
9805 && OMP_CLAUSE_DECL (c) == decl)
9807 if (is_doacross && (collapse == 1 || i >= collapse))
9808 t = var;
9809 else
9811 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
9812 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
9813 gcc_assert (TREE_OPERAND (t, 0) == var);
9814 t = TREE_OPERAND (t, 1);
9815 gcc_assert (TREE_CODE (t) == PLUS_EXPR
9816 || TREE_CODE (t) == MINUS_EXPR
9817 || TREE_CODE (t) == POINTER_PLUS_EXPR);
9818 gcc_assert (TREE_OPERAND (t, 0) == var);
9819 t = build2 (TREE_CODE (t), TREE_TYPE (decl),
9820 is_doacross ? var : decl,
9821 TREE_OPERAND (t, 1));
9823 gimple_seq *seq;
9824 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
9825 seq = &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c);
9826 else
9827 seq = &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c);
9828 gimplify_assign (decl, t, seq);
9833 BITMAP_FREE (has_decl_expr);
9835 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
9837 push_gimplify_context ();
9838 if (TREE_CODE (OMP_FOR_BODY (orig_for_stmt)) != BIND_EXPR)
9840 OMP_FOR_BODY (orig_for_stmt)
9841 = build3 (BIND_EXPR, void_type_node, NULL,
9842 OMP_FOR_BODY (orig_for_stmt), NULL);
9843 TREE_SIDE_EFFECTS (OMP_FOR_BODY (orig_for_stmt)) = 1;
9847 gimple *g = gimplify_and_return_first (OMP_FOR_BODY (orig_for_stmt),
9848 &for_body);
9850 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
9852 if (gimple_code (g) == GIMPLE_BIND)
9853 pop_gimplify_context (g);
9854 else
9855 pop_gimplify_context (NULL);
9858 if (orig_for_stmt != for_stmt)
9859 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
9861 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
9862 decl = TREE_OPERAND (t, 0);
9863 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
9864 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
9865 gimplify_omp_ctxp = ctx->outer_context;
9866 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
9867 gimplify_omp_ctxp = ctx;
9868 omp_add_variable (gimplify_omp_ctxp, var, GOVD_PRIVATE | GOVD_SEEN);
9869 TREE_OPERAND (t, 0) = var;
9870 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
9871 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
9872 TREE_OPERAND (TREE_OPERAND (t, 1), 0) = var;
9875 gimplify_adjust_omp_clauses (pre_p, for_body,
9876 &OMP_FOR_CLAUSES (orig_for_stmt),
9877 TREE_CODE (orig_for_stmt));
9879 int kind;
9880 switch (TREE_CODE (orig_for_stmt))
9882 case OMP_FOR: kind = GF_OMP_FOR_KIND_FOR; break;
9883 case OMP_SIMD: kind = GF_OMP_FOR_KIND_SIMD; break;
9884 case CILK_SIMD: kind = GF_OMP_FOR_KIND_CILKSIMD; break;
9885 case CILK_FOR: kind = GF_OMP_FOR_KIND_CILKFOR; break;
9886 case OMP_DISTRIBUTE: kind = GF_OMP_FOR_KIND_DISTRIBUTE; break;
9887 case OMP_TASKLOOP: kind = GF_OMP_FOR_KIND_TASKLOOP; break;
9888 case OACC_LOOP: kind = GF_OMP_FOR_KIND_OACC_LOOP; break;
9889 default:
9890 gcc_unreachable ();
9892 gfor = gimple_build_omp_for (for_body, kind, OMP_FOR_CLAUSES (orig_for_stmt),
9893 TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)),
9894 for_pre_body);
9895 if (orig_for_stmt != for_stmt)
9896 gimple_omp_for_set_combined_p (gfor, true);
9897 if (gimplify_omp_ctxp
9898 && (gimplify_omp_ctxp->combined_loop
9899 || (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
9900 && gimplify_omp_ctxp->outer_context
9901 && gimplify_omp_ctxp->outer_context->combined_loop)))
9903 gimple_omp_for_set_combined_into_p (gfor, true);
9904 if (gimplify_omp_ctxp->combined_loop)
9905 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_SIMD);
9906 else
9907 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_FOR);
9910 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
9912 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
9913 gimple_omp_for_set_index (gfor, i, TREE_OPERAND (t, 0));
9914 gimple_omp_for_set_initial (gfor, i, TREE_OPERAND (t, 1));
9915 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
9916 gimple_omp_for_set_cond (gfor, i, TREE_CODE (t));
9917 gimple_omp_for_set_final (gfor, i, TREE_OPERAND (t, 1));
9918 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
9919 gimple_omp_for_set_incr (gfor, i, TREE_OPERAND (t, 1));
9922 /* OMP_TASKLOOP is gimplified as two GIMPLE_OMP_FOR taskloop
9923 constructs with GIMPLE_OMP_TASK sandwiched in between them.
9924 The outer taskloop stands for computing the number of iterations,
9925 counts for collapsed loops and holding taskloop specific clauses.
9926 The task construct stands for the effect of data sharing on the
9927 explicit task it creates and the inner taskloop stands for expansion
9928 of the static loop inside of the explicit task construct. */
9929 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
9931 tree *gfor_clauses_ptr = gimple_omp_for_clauses_ptr (gfor);
9932 tree task_clauses = NULL_TREE;
9933 tree c = *gfor_clauses_ptr;
9934 tree *gtask_clauses_ptr = &task_clauses;
9935 tree outer_for_clauses = NULL_TREE;
9936 tree *gforo_clauses_ptr = &outer_for_clauses;
9937 for (; c; c = OMP_CLAUSE_CHAIN (c))
9938 switch (OMP_CLAUSE_CODE (c))
9940 /* These clauses are allowed on task, move them there. */
9941 case OMP_CLAUSE_SHARED:
9942 case OMP_CLAUSE_FIRSTPRIVATE:
9943 case OMP_CLAUSE_DEFAULT:
9944 case OMP_CLAUSE_IF:
9945 case OMP_CLAUSE_UNTIED:
9946 case OMP_CLAUSE_FINAL:
9947 case OMP_CLAUSE_MERGEABLE:
9948 case OMP_CLAUSE_PRIORITY:
9949 *gtask_clauses_ptr = c;
9950 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
9951 break;
9952 case OMP_CLAUSE_PRIVATE:
9953 if (OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c))
9955 /* We want private on outer for and firstprivate
9956 on task. */
9957 *gtask_clauses_ptr
9958 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9959 OMP_CLAUSE_FIRSTPRIVATE);
9960 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
9961 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL);
9962 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
9963 *gforo_clauses_ptr = c;
9964 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
9966 else
9968 *gtask_clauses_ptr = c;
9969 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
9971 break;
9972 /* These clauses go into outer taskloop clauses. */
9973 case OMP_CLAUSE_GRAINSIZE:
9974 case OMP_CLAUSE_NUM_TASKS:
9975 case OMP_CLAUSE_NOGROUP:
9976 *gforo_clauses_ptr = c;
9977 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
9978 break;
9979 /* Taskloop clause we duplicate on both taskloops. */
9980 case OMP_CLAUSE_COLLAPSE:
9981 *gfor_clauses_ptr = c;
9982 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
9983 *gforo_clauses_ptr = copy_node (c);
9984 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
9985 break;
9986 /* For lastprivate, keep the clause on inner taskloop, and add
9987 a shared clause on task. If the same decl is also firstprivate,
9988 add also firstprivate clause on the inner taskloop. */
9989 case OMP_CLAUSE_LASTPRIVATE:
9990 if (OMP_CLAUSE_LASTPRIVATE_TASKLOOP_IV (c))
9992 /* For taskloop C++ lastprivate IVs, we want:
9993 1) private on outer taskloop
9994 2) firstprivate and shared on task
9995 3) lastprivate on inner taskloop */
9996 *gtask_clauses_ptr
9997 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9998 OMP_CLAUSE_FIRSTPRIVATE);
9999 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
10000 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL);
10001 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
10002 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c) = 1;
10003 *gforo_clauses_ptr = build_omp_clause (OMP_CLAUSE_LOCATION (c),
10004 OMP_CLAUSE_PRIVATE);
10005 OMP_CLAUSE_DECL (*gforo_clauses_ptr) = OMP_CLAUSE_DECL (c);
10006 OMP_CLAUSE_PRIVATE_TASKLOOP_IV (*gforo_clauses_ptr) = 1;
10007 TREE_TYPE (*gforo_clauses_ptr) = TREE_TYPE (c);
10008 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
10010 *gfor_clauses_ptr = c;
10011 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
10012 *gtask_clauses_ptr
10013 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_SHARED);
10014 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
10015 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
10016 OMP_CLAUSE_SHARED_FIRSTPRIVATE (*gtask_clauses_ptr) = 1;
10017 gtask_clauses_ptr
10018 = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
10019 break;
10020 default:
10021 gcc_unreachable ();
10023 *gfor_clauses_ptr = NULL_TREE;
10024 *gtask_clauses_ptr = NULL_TREE;
10025 *gforo_clauses_ptr = NULL_TREE;
10026 g = gimple_build_bind (NULL_TREE, gfor, NULL_TREE);
10027 g = gimple_build_omp_task (g, task_clauses, NULL_TREE, NULL_TREE,
10028 NULL_TREE, NULL_TREE, NULL_TREE);
10029 gimple_omp_task_set_taskloop_p (g, true);
10030 g = gimple_build_bind (NULL_TREE, g, NULL_TREE);
10031 gomp_for *gforo
10032 = gimple_build_omp_for (g, GF_OMP_FOR_KIND_TASKLOOP, outer_for_clauses,
10033 gimple_omp_for_collapse (gfor),
10034 gimple_omp_for_pre_body (gfor));
10035 gimple_omp_for_set_pre_body (gfor, NULL);
10036 gimple_omp_for_set_combined_p (gforo, true);
10037 gimple_omp_for_set_combined_into_p (gfor, true);
10038 for (i = 0; i < (int) gimple_omp_for_collapse (gfor); i++)
10040 t = unshare_expr (gimple_omp_for_index (gfor, i));
10041 gimple_omp_for_set_index (gforo, i, t);
10042 t = unshare_expr (gimple_omp_for_initial (gfor, i));
10043 gimple_omp_for_set_initial (gforo, i, t);
10044 gimple_omp_for_set_cond (gforo, i,
10045 gimple_omp_for_cond (gfor, i));
10046 t = unshare_expr (gimple_omp_for_final (gfor, i));
10047 gimple_omp_for_set_final (gforo, i, t);
10048 t = unshare_expr (gimple_omp_for_incr (gfor, i));
10049 gimple_omp_for_set_incr (gforo, i, t);
10051 gimplify_seq_add_stmt (pre_p, gforo);
10053 else
10054 gimplify_seq_add_stmt (pre_p, gfor);
10055 if (ret != GS_ALL_DONE)
10056 return GS_ERROR;
10057 *expr_p = NULL_TREE;
10058 return GS_ALL_DONE;
10061 /* Helper function of optimize_target_teams, find OMP_TEAMS inside
10062 of OMP_TARGET's body. */
10064 static tree
10065 find_omp_teams (tree *tp, int *walk_subtrees, void *)
10067 *walk_subtrees = 0;
10068 switch (TREE_CODE (*tp))
10070 case OMP_TEAMS:
10071 return *tp;
10072 case BIND_EXPR:
10073 case STATEMENT_LIST:
10074 *walk_subtrees = 1;
10075 break;
10076 default:
10077 break;
10079 return NULL_TREE;
10082 /* Helper function of optimize_target_teams, determine if the expression
10083 can be computed safely before the target construct on the host. */
10085 static tree
10086 computable_teams_clause (tree *tp, int *walk_subtrees, void *)
10088 splay_tree_node n;
10090 if (TYPE_P (*tp))
10092 *walk_subtrees = 0;
10093 return NULL_TREE;
10095 switch (TREE_CODE (*tp))
10097 case VAR_DECL:
10098 case PARM_DECL:
10099 case RESULT_DECL:
10100 *walk_subtrees = 0;
10101 if (error_operand_p (*tp)
10102 || !INTEGRAL_TYPE_P (TREE_TYPE (*tp))
10103 || DECL_HAS_VALUE_EXPR_P (*tp)
10104 || DECL_THREAD_LOCAL_P (*tp)
10105 || TREE_SIDE_EFFECTS (*tp)
10106 || TREE_THIS_VOLATILE (*tp))
10107 return *tp;
10108 if (is_global_var (*tp)
10109 && (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (*tp))
10110 || lookup_attribute ("omp declare target link",
10111 DECL_ATTRIBUTES (*tp))))
10112 return *tp;
10113 n = splay_tree_lookup (gimplify_omp_ctxp->variables,
10114 (splay_tree_key) *tp);
10115 if (n == NULL)
10117 if (gimplify_omp_ctxp->target_map_scalars_firstprivate)
10118 return NULL_TREE;
10119 return *tp;
10121 else if (n->value & GOVD_LOCAL)
10122 return *tp;
10123 else if (n->value & GOVD_FIRSTPRIVATE)
10124 return NULL_TREE;
10125 else if ((n->value & (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
10126 == (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
10127 return NULL_TREE;
10128 return *tp;
10129 case INTEGER_CST:
10130 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
10131 return *tp;
10132 return NULL_TREE;
10133 case TARGET_EXPR:
10134 if (TARGET_EXPR_INITIAL (*tp)
10135 || TREE_CODE (TARGET_EXPR_SLOT (*tp)) != VAR_DECL)
10136 return *tp;
10137 return computable_teams_clause (&TARGET_EXPR_SLOT (*tp),
10138 walk_subtrees, NULL);
10139 /* Allow some reasonable subset of integral arithmetics. */
10140 case PLUS_EXPR:
10141 case MINUS_EXPR:
10142 case MULT_EXPR:
10143 case TRUNC_DIV_EXPR:
10144 case CEIL_DIV_EXPR:
10145 case FLOOR_DIV_EXPR:
10146 case ROUND_DIV_EXPR:
10147 case TRUNC_MOD_EXPR:
10148 case CEIL_MOD_EXPR:
10149 case FLOOR_MOD_EXPR:
10150 case ROUND_MOD_EXPR:
10151 case RDIV_EXPR:
10152 case EXACT_DIV_EXPR:
10153 case MIN_EXPR:
10154 case MAX_EXPR:
10155 case LSHIFT_EXPR:
10156 case RSHIFT_EXPR:
10157 case BIT_IOR_EXPR:
10158 case BIT_XOR_EXPR:
10159 case BIT_AND_EXPR:
10160 case NEGATE_EXPR:
10161 case ABS_EXPR:
10162 case BIT_NOT_EXPR:
10163 case NON_LVALUE_EXPR:
10164 CASE_CONVERT:
10165 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
10166 return *tp;
10167 return NULL_TREE;
10168 /* And disallow anything else, except for comparisons. */
10169 default:
10170 if (COMPARISON_CLASS_P (*tp))
10171 return NULL_TREE;
10172 return *tp;
10176 /* Try to determine if the num_teams and/or thread_limit expressions
10177 can have their values determined already before entering the
10178 target construct.
10179 INTEGER_CSTs trivially are,
10180 integral decls that are firstprivate (explicitly or implicitly)
10181 or explicitly map(always, to:) or map(always, tofrom:) on the target
10182 region too, and expressions involving simple arithmetics on those
10183 too, function calls are not ok, dereferencing something neither etc.
10184 Add NUM_TEAMS and THREAD_LIMIT clauses to the OMP_CLAUSES of
10185 EXPR based on what we find:
10186 0 stands for clause not specified at all, use implementation default
10187 -1 stands for value that can't be determined easily before entering
10188 the target construct.
10189 If teams construct is not present at all, use 1 for num_teams
10190 and 0 for thread_limit (only one team is involved, and the thread
10191 limit is implementation defined. */
10193 static void
10194 optimize_target_teams (tree target, gimple_seq *pre_p)
10196 tree body = OMP_BODY (target);
10197 tree teams = walk_tree (&body, find_omp_teams, NULL, NULL);
10198 tree num_teams = integer_zero_node;
10199 tree thread_limit = integer_zero_node;
10200 location_t num_teams_loc = EXPR_LOCATION (target);
10201 location_t thread_limit_loc = EXPR_LOCATION (target);
10202 tree c, *p, expr;
10203 struct gimplify_omp_ctx *target_ctx = gimplify_omp_ctxp;
10205 if (teams == NULL_TREE)
10206 num_teams = integer_one_node;
10207 else
10208 for (c = OMP_TEAMS_CLAUSES (teams); c; c = OMP_CLAUSE_CHAIN (c))
10210 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS)
10212 p = &num_teams;
10213 num_teams_loc = OMP_CLAUSE_LOCATION (c);
10215 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
10217 p = &thread_limit;
10218 thread_limit_loc = OMP_CLAUSE_LOCATION (c);
10220 else
10221 continue;
10222 expr = OMP_CLAUSE_OPERAND (c, 0);
10223 if (TREE_CODE (expr) == INTEGER_CST)
10225 *p = expr;
10226 continue;
10228 if (walk_tree (&expr, computable_teams_clause, NULL, NULL))
10230 *p = integer_minus_one_node;
10231 continue;
10233 *p = expr;
10234 gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
10235 if (gimplify_expr (p, pre_p, NULL, is_gimple_val, fb_rvalue, false)
10236 == GS_ERROR)
10238 gimplify_omp_ctxp = target_ctx;
10239 *p = integer_minus_one_node;
10240 continue;
10242 gimplify_omp_ctxp = target_ctx;
10243 if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR)
10244 OMP_CLAUSE_OPERAND (c, 0) = *p;
10246 c = build_omp_clause (thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
10247 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = thread_limit;
10248 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
10249 OMP_TARGET_CLAUSES (target) = c;
10250 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
10251 OMP_CLAUSE_NUM_TEAMS_EXPR (c) = num_teams;
10252 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
10253 OMP_TARGET_CLAUSES (target) = c;
10256 /* Gimplify the gross structure of several OMP constructs. */
10258 static void
10259 gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
10261 tree expr = *expr_p;
10262 gimple *stmt;
10263 gimple_seq body = NULL;
10264 enum omp_region_type ort;
10266 switch (TREE_CODE (expr))
10268 case OMP_SECTIONS:
10269 case OMP_SINGLE:
10270 ort = ORT_WORKSHARE;
10271 break;
10272 case OMP_TARGET:
10273 ort = OMP_TARGET_COMBINED (expr) ? ORT_COMBINED_TARGET : ORT_TARGET;
10274 break;
10275 case OACC_KERNELS:
10276 ort = ORT_ACC_KERNELS;
10277 break;
10278 case OACC_PARALLEL:
10279 ort = ORT_ACC_PARALLEL;
10280 break;
10281 case OACC_DATA:
10282 ort = ORT_ACC_DATA;
10283 break;
10284 case OMP_TARGET_DATA:
10285 ort = ORT_TARGET_DATA;
10286 break;
10287 case OMP_TEAMS:
10288 ort = OMP_TEAMS_COMBINED (expr) ? ORT_COMBINED_TEAMS : ORT_TEAMS;
10289 break;
10290 case OACC_HOST_DATA:
10291 ort = ORT_ACC_HOST_DATA;
10292 break;
10293 default:
10294 gcc_unreachable ();
10296 gimplify_scan_omp_clauses (&OMP_CLAUSES (expr), pre_p, ort,
10297 TREE_CODE (expr));
10298 if (TREE_CODE (expr) == OMP_TARGET)
10299 optimize_target_teams (expr, pre_p);
10300 if ((ort & (ORT_TARGET | ORT_TARGET_DATA)) != 0)
10302 push_gimplify_context ();
10303 gimple *g = gimplify_and_return_first (OMP_BODY (expr), &body);
10304 if (gimple_code (g) == GIMPLE_BIND)
10305 pop_gimplify_context (g);
10306 else
10307 pop_gimplify_context (NULL);
10308 if ((ort & ORT_TARGET_DATA) != 0)
10310 enum built_in_function end_ix;
10311 switch (TREE_CODE (expr))
10313 case OACC_DATA:
10314 case OACC_HOST_DATA:
10315 end_ix = BUILT_IN_GOACC_DATA_END;
10316 break;
10317 case OMP_TARGET_DATA:
10318 end_ix = BUILT_IN_GOMP_TARGET_END_DATA;
10319 break;
10320 default:
10321 gcc_unreachable ();
10323 tree fn = builtin_decl_explicit (end_ix);
10324 g = gimple_build_call (fn, 0);
10325 gimple_seq cleanup = NULL;
10326 gimple_seq_add_stmt (&cleanup, g);
10327 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
10328 body = NULL;
10329 gimple_seq_add_stmt (&body, g);
10332 else
10333 gimplify_and_add (OMP_BODY (expr), &body);
10334 gimplify_adjust_omp_clauses (pre_p, body, &OMP_CLAUSES (expr),
10335 TREE_CODE (expr));
10337 switch (TREE_CODE (expr))
10339 case OACC_DATA:
10340 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_DATA,
10341 OMP_CLAUSES (expr));
10342 break;
10343 case OACC_KERNELS:
10344 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_KERNELS,
10345 OMP_CLAUSES (expr));
10346 break;
10347 case OACC_HOST_DATA:
10348 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_HOST_DATA,
10349 OMP_CLAUSES (expr));
10350 break;
10351 case OACC_PARALLEL:
10352 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_PARALLEL,
10353 OMP_CLAUSES (expr));
10354 break;
10355 case OMP_SECTIONS:
10356 stmt = gimple_build_omp_sections (body, OMP_CLAUSES (expr));
10357 break;
10358 case OMP_SINGLE:
10359 stmt = gimple_build_omp_single (body, OMP_CLAUSES (expr));
10360 break;
10361 case OMP_TARGET:
10362 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_REGION,
10363 OMP_CLAUSES (expr));
10364 break;
10365 case OMP_TARGET_DATA:
10366 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_DATA,
10367 OMP_CLAUSES (expr));
10368 break;
10369 case OMP_TEAMS:
10370 stmt = gimple_build_omp_teams (body, OMP_CLAUSES (expr));
10371 break;
10372 default:
10373 gcc_unreachable ();
10376 gimplify_seq_add_stmt (pre_p, stmt);
10377 *expr_p = NULL_TREE;
10380 /* Gimplify the gross structure of OpenACC enter/exit data, update, and OpenMP
10381 target update constructs. */
10383 static void
10384 gimplify_omp_target_update (tree *expr_p, gimple_seq *pre_p)
10386 tree expr = *expr_p;
10387 int kind;
10388 gomp_target *stmt;
10389 enum omp_region_type ort = ORT_WORKSHARE;
10391 switch (TREE_CODE (expr))
10393 case OACC_ENTER_DATA:
10394 case OACC_EXIT_DATA:
10395 kind = GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA;
10396 ort = ORT_ACC;
10397 break;
10398 case OACC_UPDATE:
10399 kind = GF_OMP_TARGET_KIND_OACC_UPDATE;
10400 ort = ORT_ACC;
10401 break;
10402 case OMP_TARGET_UPDATE:
10403 kind = GF_OMP_TARGET_KIND_UPDATE;
10404 break;
10405 case OMP_TARGET_ENTER_DATA:
10406 kind = GF_OMP_TARGET_KIND_ENTER_DATA;
10407 break;
10408 case OMP_TARGET_EXIT_DATA:
10409 kind = GF_OMP_TARGET_KIND_EXIT_DATA;
10410 break;
10411 default:
10412 gcc_unreachable ();
10414 gimplify_scan_omp_clauses (&OMP_STANDALONE_CLAUSES (expr), pre_p,
10415 ort, TREE_CODE (expr));
10416 gimplify_adjust_omp_clauses (pre_p, NULL, &OMP_STANDALONE_CLAUSES (expr),
10417 TREE_CODE (expr));
10418 stmt = gimple_build_omp_target (NULL, kind, OMP_STANDALONE_CLAUSES (expr));
10420 gimplify_seq_add_stmt (pre_p, stmt);
10421 *expr_p = NULL_TREE;
10424 /* A subroutine of gimplify_omp_atomic. The front end is supposed to have
10425 stabilized the lhs of the atomic operation as *ADDR. Return true if
10426 EXPR is this stabilized form. */
10428 static bool
10429 goa_lhs_expr_p (tree expr, tree addr)
10431 /* Also include casts to other type variants. The C front end is fond
10432 of adding these for e.g. volatile variables. This is like
10433 STRIP_TYPE_NOPS but includes the main variant lookup. */
10434 STRIP_USELESS_TYPE_CONVERSION (expr);
10436 if (TREE_CODE (expr) == INDIRECT_REF)
10438 expr = TREE_OPERAND (expr, 0);
10439 while (expr != addr
10440 && (CONVERT_EXPR_P (expr)
10441 || TREE_CODE (expr) == NON_LVALUE_EXPR)
10442 && TREE_CODE (expr) == TREE_CODE (addr)
10443 && types_compatible_p (TREE_TYPE (expr), TREE_TYPE (addr)))
10445 expr = TREE_OPERAND (expr, 0);
10446 addr = TREE_OPERAND (addr, 0);
10448 if (expr == addr)
10449 return true;
10450 return (TREE_CODE (addr) == ADDR_EXPR
10451 && TREE_CODE (expr) == ADDR_EXPR
10452 && TREE_OPERAND (addr, 0) == TREE_OPERAND (expr, 0));
10454 if (TREE_CODE (addr) == ADDR_EXPR && expr == TREE_OPERAND (addr, 0))
10455 return true;
10456 return false;
10459 /* Walk *EXPR_P and replace appearances of *LHS_ADDR with LHS_VAR. If an
10460 expression does not involve the lhs, evaluate it into a temporary.
10461 Return 1 if the lhs appeared as a subexpression, 0 if it did not,
10462 or -1 if an error was encountered. */
10464 static int
10465 goa_stabilize_expr (tree *expr_p, gimple_seq *pre_p, tree lhs_addr,
10466 tree lhs_var)
10468 tree expr = *expr_p;
10469 int saw_lhs;
10471 if (goa_lhs_expr_p (expr, lhs_addr))
10473 *expr_p = lhs_var;
10474 return 1;
10476 if (is_gimple_val (expr))
10477 return 0;
10479 saw_lhs = 0;
10480 switch (TREE_CODE_CLASS (TREE_CODE (expr)))
10482 case tcc_binary:
10483 case tcc_comparison:
10484 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p, lhs_addr,
10485 lhs_var);
10486 /* FALLTHRU */
10487 case tcc_unary:
10488 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p, lhs_addr,
10489 lhs_var);
10490 break;
10491 case tcc_expression:
10492 switch (TREE_CODE (expr))
10494 case TRUTH_ANDIF_EXPR:
10495 case TRUTH_ORIF_EXPR:
10496 case TRUTH_AND_EXPR:
10497 case TRUTH_OR_EXPR:
10498 case TRUTH_XOR_EXPR:
10499 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
10500 lhs_addr, lhs_var);
10501 /* FALLTHRU */
10502 case TRUTH_NOT_EXPR:
10503 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
10504 lhs_addr, lhs_var);
10505 break;
10506 case COMPOUND_EXPR:
10507 /* Break out any preevaluations from cp_build_modify_expr. */
10508 for (; TREE_CODE (expr) == COMPOUND_EXPR;
10509 expr = TREE_OPERAND (expr, 1))
10510 gimplify_stmt (&TREE_OPERAND (expr, 0), pre_p);
10511 *expr_p = expr;
10512 return goa_stabilize_expr (expr_p, pre_p, lhs_addr, lhs_var);
10513 default:
10514 break;
10516 break;
10517 default:
10518 break;
10521 if (saw_lhs == 0)
10523 enum gimplify_status gs;
10524 gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_val, fb_rvalue);
10525 if (gs != GS_ALL_DONE)
10526 saw_lhs = -1;
10529 return saw_lhs;
10532 /* Gimplify an OMP_ATOMIC statement. */
10534 static enum gimplify_status
10535 gimplify_omp_atomic (tree *expr_p, gimple_seq *pre_p)
10537 tree addr = TREE_OPERAND (*expr_p, 0);
10538 tree rhs = TREE_CODE (*expr_p) == OMP_ATOMIC_READ
10539 ? NULL : TREE_OPERAND (*expr_p, 1);
10540 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
10541 tree tmp_load;
10542 gomp_atomic_load *loadstmt;
10543 gomp_atomic_store *storestmt;
10545 tmp_load = create_tmp_reg (type);
10546 if (rhs && goa_stabilize_expr (&rhs, pre_p, addr, tmp_load) < 0)
10547 return GS_ERROR;
10549 if (gimplify_expr (&addr, pre_p, NULL, is_gimple_val, fb_rvalue)
10550 != GS_ALL_DONE)
10551 return GS_ERROR;
10553 loadstmt = gimple_build_omp_atomic_load (tmp_load, addr);
10554 gimplify_seq_add_stmt (pre_p, loadstmt);
10555 if (rhs && gimplify_expr (&rhs, pre_p, NULL, is_gimple_val, fb_rvalue)
10556 != GS_ALL_DONE)
10557 return GS_ERROR;
10559 if (TREE_CODE (*expr_p) == OMP_ATOMIC_READ)
10560 rhs = tmp_load;
10561 storestmt = gimple_build_omp_atomic_store (rhs);
10562 gimplify_seq_add_stmt (pre_p, storestmt);
10563 if (OMP_ATOMIC_SEQ_CST (*expr_p))
10565 gimple_omp_atomic_set_seq_cst (loadstmt);
10566 gimple_omp_atomic_set_seq_cst (storestmt);
10568 switch (TREE_CODE (*expr_p))
10570 case OMP_ATOMIC_READ:
10571 case OMP_ATOMIC_CAPTURE_OLD:
10572 *expr_p = tmp_load;
10573 gimple_omp_atomic_set_need_value (loadstmt);
10574 break;
10575 case OMP_ATOMIC_CAPTURE_NEW:
10576 *expr_p = rhs;
10577 gimple_omp_atomic_set_need_value (storestmt);
10578 break;
10579 default:
10580 *expr_p = NULL;
10581 break;
10584 return GS_ALL_DONE;
10587 /* Gimplify a TRANSACTION_EXPR. This involves gimplification of the
10588 body, and adding some EH bits. */
10590 static enum gimplify_status
10591 gimplify_transaction (tree *expr_p, gimple_seq *pre_p)
10593 tree expr = *expr_p, temp, tbody = TRANSACTION_EXPR_BODY (expr);
10594 gimple *body_stmt;
10595 gtransaction *trans_stmt;
10596 gimple_seq body = NULL;
10597 int subcode = 0;
10599 /* Wrap the transaction body in a BIND_EXPR so we have a context
10600 where to put decls for OMP. */
10601 if (TREE_CODE (tbody) != BIND_EXPR)
10603 tree bind = build3 (BIND_EXPR, void_type_node, NULL, tbody, NULL);
10604 TREE_SIDE_EFFECTS (bind) = 1;
10605 SET_EXPR_LOCATION (bind, EXPR_LOCATION (tbody));
10606 TRANSACTION_EXPR_BODY (expr) = bind;
10609 push_gimplify_context ();
10610 temp = voidify_wrapper_expr (*expr_p, NULL);
10612 body_stmt = gimplify_and_return_first (TRANSACTION_EXPR_BODY (expr), &body);
10613 pop_gimplify_context (body_stmt);
10615 trans_stmt = gimple_build_transaction (body);
10616 if (TRANSACTION_EXPR_OUTER (expr))
10617 subcode = GTMA_IS_OUTER;
10618 else if (TRANSACTION_EXPR_RELAXED (expr))
10619 subcode = GTMA_IS_RELAXED;
10620 gimple_transaction_set_subcode (trans_stmt, subcode);
10622 gimplify_seq_add_stmt (pre_p, trans_stmt);
10624 if (temp)
10626 *expr_p = temp;
10627 return GS_OK;
10630 *expr_p = NULL_TREE;
10631 return GS_ALL_DONE;
10634 /* Gimplify an OMP_ORDERED construct. EXPR is the tree version. BODY
10635 is the OMP_BODY of the original EXPR (which has already been
10636 gimplified so it's not present in the EXPR).
10638 Return the gimplified GIMPLE_OMP_ORDERED tuple. */
10640 static gimple *
10641 gimplify_omp_ordered (tree expr, gimple_seq body)
10643 tree c, decls;
10644 int failures = 0;
10645 unsigned int i;
10646 tree source_c = NULL_TREE;
10647 tree sink_c = NULL_TREE;
10649 if (gimplify_omp_ctxp)
10651 for (c = OMP_ORDERED_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
10652 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
10653 && gimplify_omp_ctxp->loop_iter_var.is_empty ()
10654 && (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK
10655 || OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE))
10657 error_at (OMP_CLAUSE_LOCATION (c),
10658 "%<ordered%> construct with %<depend%> clause must be "
10659 "closely nested inside a loop with %<ordered%> clause "
10660 "with a parameter");
10661 failures++;
10663 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
10664 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
10666 bool fail = false;
10667 for (decls = OMP_CLAUSE_DECL (c), i = 0;
10668 decls && TREE_CODE (decls) == TREE_LIST;
10669 decls = TREE_CHAIN (decls), ++i)
10670 if (i >= gimplify_omp_ctxp->loop_iter_var.length () / 2)
10671 continue;
10672 else if (TREE_VALUE (decls)
10673 != gimplify_omp_ctxp->loop_iter_var[2 * i])
10675 error_at (OMP_CLAUSE_LOCATION (c),
10676 "variable %qE is not an iteration "
10677 "of outermost loop %d, expected %qE",
10678 TREE_VALUE (decls), i + 1,
10679 gimplify_omp_ctxp->loop_iter_var[2 * i]);
10680 fail = true;
10681 failures++;
10683 else
10684 TREE_VALUE (decls)
10685 = gimplify_omp_ctxp->loop_iter_var[2 * i + 1];
10686 if (!fail && i != gimplify_omp_ctxp->loop_iter_var.length () / 2)
10688 error_at (OMP_CLAUSE_LOCATION (c),
10689 "number of variables in %<depend(sink)%> "
10690 "clause does not match number of "
10691 "iteration variables");
10692 failures++;
10694 sink_c = c;
10696 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
10697 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
10699 if (source_c)
10701 error_at (OMP_CLAUSE_LOCATION (c),
10702 "more than one %<depend(source)%> clause on an "
10703 "%<ordered%> construct");
10704 failures++;
10706 else
10707 source_c = c;
10710 if (source_c && sink_c)
10712 error_at (OMP_CLAUSE_LOCATION (source_c),
10713 "%<depend(source)%> clause specified together with "
10714 "%<depend(sink:)%> clauses on the same construct");
10715 failures++;
10718 if (failures)
10719 return gimple_build_nop ();
10720 return gimple_build_omp_ordered (body, OMP_ORDERED_CLAUSES (expr));
10723 /* Convert the GENERIC expression tree *EXPR_P to GIMPLE. If the
10724 expression produces a value to be used as an operand inside a GIMPLE
10725 statement, the value will be stored back in *EXPR_P. This value will
10726 be a tree of class tcc_declaration, tcc_constant, tcc_reference or
10727 an SSA_NAME. The corresponding sequence of GIMPLE statements is
10728 emitted in PRE_P and POST_P.
10730 Additionally, this process may overwrite parts of the input
10731 expression during gimplification. Ideally, it should be
10732 possible to do non-destructive gimplification.
10734 EXPR_P points to the GENERIC expression to convert to GIMPLE. If
10735 the expression needs to evaluate to a value to be used as
10736 an operand in a GIMPLE statement, this value will be stored in
10737 *EXPR_P on exit. This happens when the caller specifies one
10738 of fb_lvalue or fb_rvalue fallback flags.
10740 PRE_P will contain the sequence of GIMPLE statements corresponding
10741 to the evaluation of EXPR and all the side-effects that must
10742 be executed before the main expression. On exit, the last
10743 statement of PRE_P is the core statement being gimplified. For
10744 instance, when gimplifying 'if (++a)' the last statement in
10745 PRE_P will be 'if (t.1)' where t.1 is the result of
10746 pre-incrementing 'a'.
10748 POST_P will contain the sequence of GIMPLE statements corresponding
10749 to the evaluation of all the side-effects that must be executed
10750 after the main expression. If this is NULL, the post
10751 side-effects are stored at the end of PRE_P.
10753 The reason why the output is split in two is to handle post
10754 side-effects explicitly. In some cases, an expression may have
10755 inner and outer post side-effects which need to be emitted in
10756 an order different from the one given by the recursive
10757 traversal. For instance, for the expression (*p--)++ the post
10758 side-effects of '--' must actually occur *after* the post
10759 side-effects of '++'. However, gimplification will first visit
10760 the inner expression, so if a separate POST sequence was not
10761 used, the resulting sequence would be:
10763 1 t.1 = *p
10764 2 p = p - 1
10765 3 t.2 = t.1 + 1
10766 4 *p = t.2
10768 However, the post-decrement operation in line #2 must not be
10769 evaluated until after the store to *p at line #4, so the
10770 correct sequence should be:
10772 1 t.1 = *p
10773 2 t.2 = t.1 + 1
10774 3 *p = t.2
10775 4 p = p - 1
10777 So, by specifying a separate post queue, it is possible
10778 to emit the post side-effects in the correct order.
10779 If POST_P is NULL, an internal queue will be used. Before
10780 returning to the caller, the sequence POST_P is appended to
10781 the main output sequence PRE_P.
10783 GIMPLE_TEST_F points to a function that takes a tree T and
10784 returns nonzero if T is in the GIMPLE form requested by the
10785 caller. The GIMPLE predicates are in gimple.c.
10787 FALLBACK tells the function what sort of a temporary we want if
10788 gimplification cannot produce an expression that complies with
10789 GIMPLE_TEST_F.
10791 fb_none means that no temporary should be generated
10792 fb_rvalue means that an rvalue is OK to generate
10793 fb_lvalue means that an lvalue is OK to generate
10794 fb_either means that either is OK, but an lvalue is preferable.
10795 fb_mayfail means that gimplification may fail (in which case
10796 GS_ERROR will be returned)
10798 The return value is either GS_ERROR or GS_ALL_DONE, since this
10799 function iterates until EXPR is completely gimplified or an error
10800 occurs. */
10802 enum gimplify_status
10803 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
10804 bool (*gimple_test_f) (tree), fallback_t fallback)
10806 tree tmp;
10807 gimple_seq internal_pre = NULL;
10808 gimple_seq internal_post = NULL;
10809 tree save_expr;
10810 bool is_statement;
10811 location_t saved_location;
10812 enum gimplify_status ret;
10813 gimple_stmt_iterator pre_last_gsi, post_last_gsi;
10815 save_expr = *expr_p;
10816 if (save_expr == NULL_TREE)
10817 return GS_ALL_DONE;
10819 /* If we are gimplifying a top-level statement, PRE_P must be valid. */
10820 is_statement = gimple_test_f == is_gimple_stmt;
10821 if (is_statement)
10822 gcc_assert (pre_p);
10824 /* Consistency checks. */
10825 if (gimple_test_f == is_gimple_reg)
10826 gcc_assert (fallback & (fb_rvalue | fb_lvalue));
10827 else if (gimple_test_f == is_gimple_val
10828 || gimple_test_f == is_gimple_call_addr
10829 || gimple_test_f == is_gimple_condexpr
10830 || gimple_test_f == is_gimple_mem_rhs
10831 || gimple_test_f == is_gimple_mem_rhs_or_call
10832 || gimple_test_f == is_gimple_reg_rhs
10833 || gimple_test_f == is_gimple_reg_rhs_or_call
10834 || gimple_test_f == is_gimple_asm_val
10835 || gimple_test_f == is_gimple_mem_ref_addr)
10836 gcc_assert (fallback & fb_rvalue);
10837 else if (gimple_test_f == is_gimple_min_lval
10838 || gimple_test_f == is_gimple_lvalue)
10839 gcc_assert (fallback & fb_lvalue);
10840 else if (gimple_test_f == is_gimple_addressable)
10841 gcc_assert (fallback & fb_either);
10842 else if (gimple_test_f == is_gimple_stmt)
10843 gcc_assert (fallback == fb_none);
10844 else
10846 /* We should have recognized the GIMPLE_TEST_F predicate to
10847 know what kind of fallback to use in case a temporary is
10848 needed to hold the value or address of *EXPR_P. */
10849 gcc_unreachable ();
10852 /* We used to check the predicate here and return immediately if it
10853 succeeds. This is wrong; the design is for gimplification to be
10854 idempotent, and for the predicates to only test for valid forms, not
10855 whether they are fully simplified. */
10856 if (pre_p == NULL)
10857 pre_p = &internal_pre;
10859 if (post_p == NULL)
10860 post_p = &internal_post;
10862 /* Remember the last statements added to PRE_P and POST_P. Every
10863 new statement added by the gimplification helpers needs to be
10864 annotated with location information. To centralize the
10865 responsibility, we remember the last statement that had been
10866 added to both queues before gimplifying *EXPR_P. If
10867 gimplification produces new statements in PRE_P and POST_P, those
10868 statements will be annotated with the same location information
10869 as *EXPR_P. */
10870 pre_last_gsi = gsi_last (*pre_p);
10871 post_last_gsi = gsi_last (*post_p);
10873 saved_location = input_location;
10874 if (save_expr != error_mark_node
10875 && EXPR_HAS_LOCATION (*expr_p))
10876 input_location = EXPR_LOCATION (*expr_p);
10878 /* Loop over the specific gimplifiers until the toplevel node
10879 remains the same. */
10882 /* Strip away as many useless type conversions as possible
10883 at the toplevel. */
10884 STRIP_USELESS_TYPE_CONVERSION (*expr_p);
10886 /* Remember the expr. */
10887 save_expr = *expr_p;
10889 /* Die, die, die, my darling. */
10890 if (save_expr == error_mark_node
10891 || (TREE_TYPE (save_expr)
10892 && TREE_TYPE (save_expr) == error_mark_node))
10894 ret = GS_ERROR;
10895 break;
10898 /* Do any language-specific gimplification. */
10899 ret = ((enum gimplify_status)
10900 lang_hooks.gimplify_expr (expr_p, pre_p, post_p));
10901 if (ret == GS_OK)
10903 if (*expr_p == NULL_TREE)
10904 break;
10905 if (*expr_p != save_expr)
10906 continue;
10908 else if (ret != GS_UNHANDLED)
10909 break;
10911 /* Make sure that all the cases set 'ret' appropriately. */
10912 ret = GS_UNHANDLED;
10913 switch (TREE_CODE (*expr_p))
10915 /* First deal with the special cases. */
10917 case POSTINCREMENT_EXPR:
10918 case POSTDECREMENT_EXPR:
10919 case PREINCREMENT_EXPR:
10920 case PREDECREMENT_EXPR:
10921 ret = gimplify_self_mod_expr (expr_p, pre_p, post_p,
10922 fallback != fb_none,
10923 TREE_TYPE (*expr_p));
10924 break;
10926 case VIEW_CONVERT_EXPR:
10927 if (is_gimple_reg_type (TREE_TYPE (*expr_p))
10928 && is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0))))
10930 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
10931 post_p, is_gimple_val, fb_rvalue);
10932 recalculate_side_effects (*expr_p);
10933 break;
10935 /* Fallthru. */
10937 case ARRAY_REF:
10938 case ARRAY_RANGE_REF:
10939 case REALPART_EXPR:
10940 case IMAGPART_EXPR:
10941 case COMPONENT_REF:
10942 ret = gimplify_compound_lval (expr_p, pre_p, post_p,
10943 fallback ? fallback : fb_rvalue);
10944 break;
10946 case COND_EXPR:
10947 ret = gimplify_cond_expr (expr_p, pre_p, fallback);
10949 /* C99 code may assign to an array in a structure value of a
10950 conditional expression, and this has undefined behavior
10951 only on execution, so create a temporary if an lvalue is
10952 required. */
10953 if (fallback == fb_lvalue)
10955 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
10956 mark_addressable (*expr_p);
10957 ret = GS_OK;
10959 break;
10961 case CALL_EXPR:
10962 ret = gimplify_call_expr (expr_p, pre_p, fallback != fb_none);
10964 /* C99 code may assign to an array in a structure returned
10965 from a function, and this has undefined behavior only on
10966 execution, so create a temporary if an lvalue is
10967 required. */
10968 if (fallback == fb_lvalue)
10970 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
10971 mark_addressable (*expr_p);
10972 ret = GS_OK;
10974 break;
10976 case TREE_LIST:
10977 gcc_unreachable ();
10979 case COMPOUND_EXPR:
10980 ret = gimplify_compound_expr (expr_p, pre_p, fallback != fb_none);
10981 break;
10983 case COMPOUND_LITERAL_EXPR:
10984 ret = gimplify_compound_literal_expr (expr_p, pre_p,
10985 gimple_test_f, fallback);
10986 break;
10988 case MODIFY_EXPR:
10989 case INIT_EXPR:
10990 ret = gimplify_modify_expr (expr_p, pre_p, post_p,
10991 fallback != fb_none);
10992 break;
10994 case TRUTH_ANDIF_EXPR:
10995 case TRUTH_ORIF_EXPR:
10997 /* Preserve the original type of the expression and the
10998 source location of the outer expression. */
10999 tree org_type = TREE_TYPE (*expr_p);
11000 *expr_p = gimple_boolify (*expr_p);
11001 *expr_p = build3_loc (input_location, COND_EXPR,
11002 org_type, *expr_p,
11003 fold_convert_loc
11004 (input_location,
11005 org_type, boolean_true_node),
11006 fold_convert_loc
11007 (input_location,
11008 org_type, boolean_false_node));
11009 ret = GS_OK;
11010 break;
11013 case TRUTH_NOT_EXPR:
11015 tree type = TREE_TYPE (*expr_p);
11016 /* The parsers are careful to generate TRUTH_NOT_EXPR
11017 only with operands that are always zero or one.
11018 We do not fold here but handle the only interesting case
11019 manually, as fold may re-introduce the TRUTH_NOT_EXPR. */
11020 *expr_p = gimple_boolify (*expr_p);
11021 if (TYPE_PRECISION (TREE_TYPE (*expr_p)) == 1)
11022 *expr_p = build1_loc (input_location, BIT_NOT_EXPR,
11023 TREE_TYPE (*expr_p),
11024 TREE_OPERAND (*expr_p, 0));
11025 else
11026 *expr_p = build2_loc (input_location, BIT_XOR_EXPR,
11027 TREE_TYPE (*expr_p),
11028 TREE_OPERAND (*expr_p, 0),
11029 build_int_cst (TREE_TYPE (*expr_p), 1));
11030 if (!useless_type_conversion_p (type, TREE_TYPE (*expr_p)))
11031 *expr_p = fold_convert_loc (input_location, type, *expr_p);
11032 ret = GS_OK;
11033 break;
11036 case ADDR_EXPR:
11037 ret = gimplify_addr_expr (expr_p, pre_p, post_p);
11038 break;
11040 case ANNOTATE_EXPR:
11042 tree cond = TREE_OPERAND (*expr_p, 0);
11043 tree kind = TREE_OPERAND (*expr_p, 1);
11044 tree type = TREE_TYPE (cond);
11045 if (!INTEGRAL_TYPE_P (type))
11047 *expr_p = cond;
11048 ret = GS_OK;
11049 break;
11051 tree tmp = create_tmp_var (type);
11052 gimplify_arg (&cond, pre_p, EXPR_LOCATION (*expr_p));
11053 gcall *call
11054 = gimple_build_call_internal (IFN_ANNOTATE, 2, cond, kind);
11055 gimple_call_set_lhs (call, tmp);
11056 gimplify_seq_add_stmt (pre_p, call);
11057 *expr_p = tmp;
11058 ret = GS_ALL_DONE;
11059 break;
11062 case VA_ARG_EXPR:
11063 ret = gimplify_va_arg_expr (expr_p, pre_p, post_p);
11064 break;
11066 CASE_CONVERT:
11067 if (IS_EMPTY_STMT (*expr_p))
11069 ret = GS_ALL_DONE;
11070 break;
11073 if (VOID_TYPE_P (TREE_TYPE (*expr_p))
11074 || fallback == fb_none)
11076 /* Just strip a conversion to void (or in void context) and
11077 try again. */
11078 *expr_p = TREE_OPERAND (*expr_p, 0);
11079 ret = GS_OK;
11080 break;
11083 ret = gimplify_conversion (expr_p);
11084 if (ret == GS_ERROR)
11085 break;
11086 if (*expr_p != save_expr)
11087 break;
11088 /* FALLTHRU */
11090 case FIX_TRUNC_EXPR:
11091 /* unary_expr: ... | '(' cast ')' val | ... */
11092 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
11093 is_gimple_val, fb_rvalue);
11094 recalculate_side_effects (*expr_p);
11095 break;
11097 case INDIRECT_REF:
11099 bool volatilep = TREE_THIS_VOLATILE (*expr_p);
11100 bool notrap = TREE_THIS_NOTRAP (*expr_p);
11101 tree saved_ptr_type = TREE_TYPE (TREE_OPERAND (*expr_p, 0));
11103 *expr_p = fold_indirect_ref_loc (input_location, *expr_p);
11104 if (*expr_p != save_expr)
11106 ret = GS_OK;
11107 break;
11110 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
11111 is_gimple_reg, fb_rvalue);
11112 if (ret == GS_ERROR)
11113 break;
11115 recalculate_side_effects (*expr_p);
11116 *expr_p = fold_build2_loc (input_location, MEM_REF,
11117 TREE_TYPE (*expr_p),
11118 TREE_OPERAND (*expr_p, 0),
11119 build_int_cst (saved_ptr_type, 0));
11120 TREE_THIS_VOLATILE (*expr_p) = volatilep;
11121 TREE_THIS_NOTRAP (*expr_p) = notrap;
11122 ret = GS_OK;
11123 break;
11126 /* We arrive here through the various re-gimplifcation paths. */
11127 case MEM_REF:
11128 /* First try re-folding the whole thing. */
11129 tmp = fold_binary (MEM_REF, TREE_TYPE (*expr_p),
11130 TREE_OPERAND (*expr_p, 0),
11131 TREE_OPERAND (*expr_p, 1));
11132 if (tmp)
11134 REF_REVERSE_STORAGE_ORDER (tmp)
11135 = REF_REVERSE_STORAGE_ORDER (*expr_p);
11136 *expr_p = tmp;
11137 recalculate_side_effects (*expr_p);
11138 ret = GS_OK;
11139 break;
11141 /* Avoid re-gimplifying the address operand if it is already
11142 in suitable form. Re-gimplifying would mark the address
11143 operand addressable. Always gimplify when not in SSA form
11144 as we still may have to gimplify decls with value-exprs. */
11145 if (!gimplify_ctxp || !gimple_in_ssa_p (cfun)
11146 || !is_gimple_mem_ref_addr (TREE_OPERAND (*expr_p, 0)))
11148 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
11149 is_gimple_mem_ref_addr, fb_rvalue);
11150 if (ret == GS_ERROR)
11151 break;
11153 recalculate_side_effects (*expr_p);
11154 ret = GS_ALL_DONE;
11155 break;
11157 /* Constants need not be gimplified. */
11158 case INTEGER_CST:
11159 case REAL_CST:
11160 case FIXED_CST:
11161 case STRING_CST:
11162 case COMPLEX_CST:
11163 case VECTOR_CST:
11164 /* Drop the overflow flag on constants, we do not want
11165 that in the GIMPLE IL. */
11166 if (TREE_OVERFLOW_P (*expr_p))
11167 *expr_p = drop_tree_overflow (*expr_p);
11168 ret = GS_ALL_DONE;
11169 break;
11171 case CONST_DECL:
11172 /* If we require an lvalue, such as for ADDR_EXPR, retain the
11173 CONST_DECL node. Otherwise the decl is replaceable by its
11174 value. */
11175 /* ??? Should be == fb_lvalue, but ADDR_EXPR passes fb_either. */
11176 if (fallback & fb_lvalue)
11177 ret = GS_ALL_DONE;
11178 else
11180 *expr_p = DECL_INITIAL (*expr_p);
11181 ret = GS_OK;
11183 break;
11185 case DECL_EXPR:
11186 ret = gimplify_decl_expr (expr_p, pre_p);
11187 break;
11189 case BIND_EXPR:
11190 ret = gimplify_bind_expr (expr_p, pre_p);
11191 break;
11193 case LOOP_EXPR:
11194 ret = gimplify_loop_expr (expr_p, pre_p);
11195 break;
11197 case SWITCH_EXPR:
11198 ret = gimplify_switch_expr (expr_p, pre_p);
11199 break;
11201 case EXIT_EXPR:
11202 ret = gimplify_exit_expr (expr_p);
11203 break;
11205 case GOTO_EXPR:
11206 /* If the target is not LABEL, then it is a computed jump
11207 and the target needs to be gimplified. */
11208 if (TREE_CODE (GOTO_DESTINATION (*expr_p)) != LABEL_DECL)
11210 ret = gimplify_expr (&GOTO_DESTINATION (*expr_p), pre_p,
11211 NULL, is_gimple_val, fb_rvalue);
11212 if (ret == GS_ERROR)
11213 break;
11215 gimplify_seq_add_stmt (pre_p,
11216 gimple_build_goto (GOTO_DESTINATION (*expr_p)));
11217 ret = GS_ALL_DONE;
11218 break;
11220 case PREDICT_EXPR:
11221 gimplify_seq_add_stmt (pre_p,
11222 gimple_build_predict (PREDICT_EXPR_PREDICTOR (*expr_p),
11223 PREDICT_EXPR_OUTCOME (*expr_p)));
11224 ret = GS_ALL_DONE;
11225 break;
11227 case LABEL_EXPR:
11228 ret = gimplify_label_expr (expr_p, pre_p);
11229 break;
11231 case CASE_LABEL_EXPR:
11232 ret = gimplify_case_label_expr (expr_p, pre_p);
11233 break;
11235 case RETURN_EXPR:
11236 ret = gimplify_return_expr (*expr_p, pre_p);
11237 break;
11239 case CONSTRUCTOR:
11240 /* Don't reduce this in place; let gimplify_init_constructor work its
11241 magic. Buf if we're just elaborating this for side effects, just
11242 gimplify any element that has side-effects. */
11243 if (fallback == fb_none)
11245 unsigned HOST_WIDE_INT ix;
11246 tree val;
11247 tree temp = NULL_TREE;
11248 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (*expr_p), ix, val)
11249 if (TREE_SIDE_EFFECTS (val))
11250 append_to_statement_list (val, &temp);
11252 *expr_p = temp;
11253 ret = temp ? GS_OK : GS_ALL_DONE;
11255 /* C99 code may assign to an array in a constructed
11256 structure or union, and this has undefined behavior only
11257 on execution, so create a temporary if an lvalue is
11258 required. */
11259 else if (fallback == fb_lvalue)
11261 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
11262 mark_addressable (*expr_p);
11263 ret = GS_OK;
11265 else
11266 ret = GS_ALL_DONE;
11267 break;
11269 /* The following are special cases that are not handled by the
11270 original GIMPLE grammar. */
11272 /* SAVE_EXPR nodes are converted into a GIMPLE identifier and
11273 eliminated. */
11274 case SAVE_EXPR:
11275 ret = gimplify_save_expr (expr_p, pre_p, post_p);
11276 break;
11278 case BIT_FIELD_REF:
11279 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
11280 post_p, is_gimple_lvalue, fb_either);
11281 recalculate_side_effects (*expr_p);
11282 break;
11284 case TARGET_MEM_REF:
11286 enum gimplify_status r0 = GS_ALL_DONE, r1 = GS_ALL_DONE;
11288 if (TMR_BASE (*expr_p))
11289 r0 = gimplify_expr (&TMR_BASE (*expr_p), pre_p,
11290 post_p, is_gimple_mem_ref_addr, fb_either);
11291 if (TMR_INDEX (*expr_p))
11292 r1 = gimplify_expr (&TMR_INDEX (*expr_p), pre_p,
11293 post_p, is_gimple_val, fb_rvalue);
11294 if (TMR_INDEX2 (*expr_p))
11295 r1 = gimplify_expr (&TMR_INDEX2 (*expr_p), pre_p,
11296 post_p, is_gimple_val, fb_rvalue);
11297 /* TMR_STEP and TMR_OFFSET are always integer constants. */
11298 ret = MIN (r0, r1);
11300 break;
11302 case NON_LVALUE_EXPR:
11303 /* This should have been stripped above. */
11304 gcc_unreachable ();
11306 case ASM_EXPR:
11307 ret = gimplify_asm_expr (expr_p, pre_p, post_p);
11308 break;
11310 case TRY_FINALLY_EXPR:
11311 case TRY_CATCH_EXPR:
11313 gimple_seq eval, cleanup;
11314 gtry *try_;
11316 /* Calls to destructors are generated automatically in FINALLY/CATCH
11317 block. They should have location as UNKNOWN_LOCATION. However,
11318 gimplify_call_expr will reset these call stmts to input_location
11319 if it finds stmt's location is unknown. To prevent resetting for
11320 destructors, we set the input_location to unknown.
11321 Note that this only affects the destructor calls in FINALLY/CATCH
11322 block, and will automatically reset to its original value by the
11323 end of gimplify_expr. */
11324 input_location = UNKNOWN_LOCATION;
11325 eval = cleanup = NULL;
11326 gimplify_and_add (TREE_OPERAND (*expr_p, 0), &eval);
11327 gimplify_and_add (TREE_OPERAND (*expr_p, 1), &cleanup);
11328 /* Don't create bogus GIMPLE_TRY with empty cleanup. */
11329 if (gimple_seq_empty_p (cleanup))
11331 gimple_seq_add_seq (pre_p, eval);
11332 ret = GS_ALL_DONE;
11333 break;
11335 try_ = gimple_build_try (eval, cleanup,
11336 TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
11337 ? GIMPLE_TRY_FINALLY
11338 : GIMPLE_TRY_CATCH);
11339 if (EXPR_HAS_LOCATION (save_expr))
11340 gimple_set_location (try_, EXPR_LOCATION (save_expr));
11341 else if (LOCATION_LOCUS (saved_location) != UNKNOWN_LOCATION)
11342 gimple_set_location (try_, saved_location);
11343 if (TREE_CODE (*expr_p) == TRY_CATCH_EXPR)
11344 gimple_try_set_catch_is_cleanup (try_,
11345 TRY_CATCH_IS_CLEANUP (*expr_p));
11346 gimplify_seq_add_stmt (pre_p, try_);
11347 ret = GS_ALL_DONE;
11348 break;
11351 case CLEANUP_POINT_EXPR:
11352 ret = gimplify_cleanup_point_expr (expr_p, pre_p);
11353 break;
11355 case TARGET_EXPR:
11356 ret = gimplify_target_expr (expr_p, pre_p, post_p);
11357 break;
11359 case CATCH_EXPR:
11361 gimple *c;
11362 gimple_seq handler = NULL;
11363 gimplify_and_add (CATCH_BODY (*expr_p), &handler);
11364 c = gimple_build_catch (CATCH_TYPES (*expr_p), handler);
11365 gimplify_seq_add_stmt (pre_p, c);
11366 ret = GS_ALL_DONE;
11367 break;
11370 case EH_FILTER_EXPR:
11372 gimple *ehf;
11373 gimple_seq failure = NULL;
11375 gimplify_and_add (EH_FILTER_FAILURE (*expr_p), &failure);
11376 ehf = gimple_build_eh_filter (EH_FILTER_TYPES (*expr_p), failure);
11377 gimple_set_no_warning (ehf, TREE_NO_WARNING (*expr_p));
11378 gimplify_seq_add_stmt (pre_p, ehf);
11379 ret = GS_ALL_DONE;
11380 break;
11383 case OBJ_TYPE_REF:
11385 enum gimplify_status r0, r1;
11386 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p,
11387 post_p, is_gimple_val, fb_rvalue);
11388 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p,
11389 post_p, is_gimple_val, fb_rvalue);
11390 TREE_SIDE_EFFECTS (*expr_p) = 0;
11391 ret = MIN (r0, r1);
11393 break;
11395 case LABEL_DECL:
11396 /* We get here when taking the address of a label. We mark
11397 the label as "forced"; meaning it can never be removed and
11398 it is a potential target for any computed goto. */
11399 FORCED_LABEL (*expr_p) = 1;
11400 ret = GS_ALL_DONE;
11401 break;
11403 case STATEMENT_LIST:
11404 ret = gimplify_statement_list (expr_p, pre_p);
11405 break;
11407 case WITH_SIZE_EXPR:
11409 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
11410 post_p == &internal_post ? NULL : post_p,
11411 gimple_test_f, fallback);
11412 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
11413 is_gimple_val, fb_rvalue);
11414 ret = GS_ALL_DONE;
11416 break;
11418 case VAR_DECL:
11419 case PARM_DECL:
11420 ret = gimplify_var_or_parm_decl (expr_p);
11421 break;
11423 case RESULT_DECL:
11424 /* When within an OMP context, notice uses of variables. */
11425 if (gimplify_omp_ctxp)
11426 omp_notice_variable (gimplify_omp_ctxp, *expr_p, true);
11427 ret = GS_ALL_DONE;
11428 break;
11430 case SSA_NAME:
11431 /* Allow callbacks into the gimplifier during optimization. */
11432 ret = GS_ALL_DONE;
11433 break;
11435 case OMP_PARALLEL:
11436 gimplify_omp_parallel (expr_p, pre_p);
11437 ret = GS_ALL_DONE;
11438 break;
11440 case OMP_TASK:
11441 gimplify_omp_task (expr_p, pre_p);
11442 ret = GS_ALL_DONE;
11443 break;
11445 case OMP_FOR:
11446 case OMP_SIMD:
11447 case CILK_SIMD:
11448 case CILK_FOR:
11449 case OMP_DISTRIBUTE:
11450 case OMP_TASKLOOP:
11451 case OACC_LOOP:
11452 ret = gimplify_omp_for (expr_p, pre_p);
11453 break;
11455 case OACC_CACHE:
11456 gimplify_oacc_cache (expr_p, pre_p);
11457 ret = GS_ALL_DONE;
11458 break;
11460 case OACC_DECLARE:
11461 gimplify_oacc_declare (expr_p, pre_p);
11462 ret = GS_ALL_DONE;
11463 break;
11465 case OACC_HOST_DATA:
11466 case OACC_DATA:
11467 case OACC_KERNELS:
11468 case OACC_PARALLEL:
11469 case OMP_SECTIONS:
11470 case OMP_SINGLE:
11471 case OMP_TARGET:
11472 case OMP_TARGET_DATA:
11473 case OMP_TEAMS:
11474 gimplify_omp_workshare (expr_p, pre_p);
11475 ret = GS_ALL_DONE;
11476 break;
11478 case OACC_ENTER_DATA:
11479 case OACC_EXIT_DATA:
11480 case OACC_UPDATE:
11481 case OMP_TARGET_UPDATE:
11482 case OMP_TARGET_ENTER_DATA:
11483 case OMP_TARGET_EXIT_DATA:
11484 gimplify_omp_target_update (expr_p, pre_p);
11485 ret = GS_ALL_DONE;
11486 break;
11488 case OMP_SECTION:
11489 case OMP_MASTER:
11490 case OMP_TASKGROUP:
11491 case OMP_ORDERED:
11492 case OMP_CRITICAL:
11494 gimple_seq body = NULL;
11495 gimple *g;
11497 gimplify_and_add (OMP_BODY (*expr_p), &body);
11498 switch (TREE_CODE (*expr_p))
11500 case OMP_SECTION:
11501 g = gimple_build_omp_section (body);
11502 break;
11503 case OMP_MASTER:
11504 g = gimple_build_omp_master (body);
11505 break;
11506 case OMP_TASKGROUP:
11508 gimple_seq cleanup = NULL;
11509 tree fn
11510 = builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_END);
11511 g = gimple_build_call (fn, 0);
11512 gimple_seq_add_stmt (&cleanup, g);
11513 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
11514 body = NULL;
11515 gimple_seq_add_stmt (&body, g);
11516 g = gimple_build_omp_taskgroup (body);
11518 break;
11519 case OMP_ORDERED:
11520 g = gimplify_omp_ordered (*expr_p, body);
11521 break;
11522 case OMP_CRITICAL:
11523 gimplify_scan_omp_clauses (&OMP_CRITICAL_CLAUSES (*expr_p),
11524 pre_p, ORT_WORKSHARE, OMP_CRITICAL);
11525 gimplify_adjust_omp_clauses (pre_p, body,
11526 &OMP_CRITICAL_CLAUSES (*expr_p),
11527 OMP_CRITICAL);
11528 g = gimple_build_omp_critical (body,
11529 OMP_CRITICAL_NAME (*expr_p),
11530 OMP_CRITICAL_CLAUSES (*expr_p));
11531 break;
11532 default:
11533 gcc_unreachable ();
11535 gimplify_seq_add_stmt (pre_p, g);
11536 ret = GS_ALL_DONE;
11537 break;
11540 case OMP_ATOMIC:
11541 case OMP_ATOMIC_READ:
11542 case OMP_ATOMIC_CAPTURE_OLD:
11543 case OMP_ATOMIC_CAPTURE_NEW:
11544 ret = gimplify_omp_atomic (expr_p, pre_p);
11545 break;
11547 case TRANSACTION_EXPR:
11548 ret = gimplify_transaction (expr_p, pre_p);
11549 break;
11551 case TRUTH_AND_EXPR:
11552 case TRUTH_OR_EXPR:
11553 case TRUTH_XOR_EXPR:
11555 tree orig_type = TREE_TYPE (*expr_p);
11556 tree new_type, xop0, xop1;
11557 *expr_p = gimple_boolify (*expr_p);
11558 new_type = TREE_TYPE (*expr_p);
11559 if (!useless_type_conversion_p (orig_type, new_type))
11561 *expr_p = fold_convert_loc (input_location, orig_type, *expr_p);
11562 ret = GS_OK;
11563 break;
11566 /* Boolified binary truth expressions are semantically equivalent
11567 to bitwise binary expressions. Canonicalize them to the
11568 bitwise variant. */
11569 switch (TREE_CODE (*expr_p))
11571 case TRUTH_AND_EXPR:
11572 TREE_SET_CODE (*expr_p, BIT_AND_EXPR);
11573 break;
11574 case TRUTH_OR_EXPR:
11575 TREE_SET_CODE (*expr_p, BIT_IOR_EXPR);
11576 break;
11577 case TRUTH_XOR_EXPR:
11578 TREE_SET_CODE (*expr_p, BIT_XOR_EXPR);
11579 break;
11580 default:
11581 break;
11583 /* Now make sure that operands have compatible type to
11584 expression's new_type. */
11585 xop0 = TREE_OPERAND (*expr_p, 0);
11586 xop1 = TREE_OPERAND (*expr_p, 1);
11587 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop0)))
11588 TREE_OPERAND (*expr_p, 0) = fold_convert_loc (input_location,
11589 new_type,
11590 xop0);
11591 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop1)))
11592 TREE_OPERAND (*expr_p, 1) = fold_convert_loc (input_location,
11593 new_type,
11594 xop1);
11595 /* Continue classified as tcc_binary. */
11596 goto expr_2;
11599 case VEC_COND_EXPR:
11601 enum gimplify_status r0, r1, r2;
11603 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
11604 post_p, is_gimple_condexpr, fb_rvalue);
11605 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
11606 post_p, is_gimple_val, fb_rvalue);
11607 r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p,
11608 post_p, is_gimple_val, fb_rvalue);
11610 ret = MIN (MIN (r0, r1), r2);
11611 recalculate_side_effects (*expr_p);
11613 break;
11615 case FMA_EXPR:
11616 case VEC_PERM_EXPR:
11617 /* Classified as tcc_expression. */
11618 goto expr_3;
11620 case BIT_INSERT_EXPR:
11621 /* Argument 3 is a constant. */
11622 goto expr_2;
11624 case POINTER_PLUS_EXPR:
11626 enum gimplify_status r0, r1;
11627 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
11628 post_p, is_gimple_val, fb_rvalue);
11629 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
11630 post_p, is_gimple_val, fb_rvalue);
11631 recalculate_side_effects (*expr_p);
11632 ret = MIN (r0, r1);
11633 break;
11636 case CILK_SYNC_STMT:
11638 if (!fn_contains_cilk_spawn_p (cfun))
11640 error_at (EXPR_LOCATION (*expr_p),
11641 "expected %<_Cilk_spawn%> before %<_Cilk_sync%>");
11642 ret = GS_ERROR;
11644 else
11646 gimplify_cilk_sync (expr_p, pre_p);
11647 ret = GS_ALL_DONE;
11649 break;
11652 default:
11653 switch (TREE_CODE_CLASS (TREE_CODE (*expr_p)))
11655 case tcc_comparison:
11656 /* Handle comparison of objects of non scalar mode aggregates
11657 with a call to memcmp. It would be nice to only have to do
11658 this for variable-sized objects, but then we'd have to allow
11659 the same nest of reference nodes we allow for MODIFY_EXPR and
11660 that's too complex.
11662 Compare scalar mode aggregates as scalar mode values. Using
11663 memcmp for them would be very inefficient at best, and is
11664 plain wrong if bitfields are involved. */
11666 tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 1));
11668 /* Vector comparisons need no boolification. */
11669 if (TREE_CODE (type) == VECTOR_TYPE)
11670 goto expr_2;
11671 else if (!AGGREGATE_TYPE_P (type))
11673 tree org_type = TREE_TYPE (*expr_p);
11674 *expr_p = gimple_boolify (*expr_p);
11675 if (!useless_type_conversion_p (org_type,
11676 TREE_TYPE (*expr_p)))
11678 *expr_p = fold_convert_loc (input_location,
11679 org_type, *expr_p);
11680 ret = GS_OK;
11682 else
11683 goto expr_2;
11685 else if (TYPE_MODE (type) != BLKmode)
11686 ret = gimplify_scalar_mode_aggregate_compare (expr_p);
11687 else
11688 ret = gimplify_variable_sized_compare (expr_p);
11690 break;
11693 /* If *EXPR_P does not need to be special-cased, handle it
11694 according to its class. */
11695 case tcc_unary:
11696 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
11697 post_p, is_gimple_val, fb_rvalue);
11698 break;
11700 case tcc_binary:
11701 expr_2:
11703 enum gimplify_status r0, r1;
11705 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
11706 post_p, is_gimple_val, fb_rvalue);
11707 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
11708 post_p, is_gimple_val, fb_rvalue);
11710 ret = MIN (r0, r1);
11711 break;
11714 expr_3:
11716 enum gimplify_status r0, r1, r2;
11718 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
11719 post_p, is_gimple_val, fb_rvalue);
11720 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
11721 post_p, is_gimple_val, fb_rvalue);
11722 r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p,
11723 post_p, is_gimple_val, fb_rvalue);
11725 ret = MIN (MIN (r0, r1), r2);
11726 break;
11729 case tcc_declaration:
11730 case tcc_constant:
11731 ret = GS_ALL_DONE;
11732 goto dont_recalculate;
11734 default:
11735 gcc_unreachable ();
11738 recalculate_side_effects (*expr_p);
11740 dont_recalculate:
11741 break;
11744 gcc_assert (*expr_p || ret != GS_OK);
11746 while (ret == GS_OK);
11748 /* If we encountered an error_mark somewhere nested inside, either
11749 stub out the statement or propagate the error back out. */
11750 if (ret == GS_ERROR)
11752 if (is_statement)
11753 *expr_p = NULL;
11754 goto out;
11757 /* This was only valid as a return value from the langhook, which
11758 we handled. Make sure it doesn't escape from any other context. */
11759 gcc_assert (ret != GS_UNHANDLED);
11761 if (fallback == fb_none && *expr_p && !is_gimple_stmt (*expr_p))
11763 /* We aren't looking for a value, and we don't have a valid
11764 statement. If it doesn't have side-effects, throw it away. */
11765 if (!TREE_SIDE_EFFECTS (*expr_p))
11766 *expr_p = NULL;
11767 else if (!TREE_THIS_VOLATILE (*expr_p))
11769 /* This is probably a _REF that contains something nested that
11770 has side effects. Recurse through the operands to find it. */
11771 enum tree_code code = TREE_CODE (*expr_p);
11773 switch (code)
11775 case COMPONENT_REF:
11776 case REALPART_EXPR:
11777 case IMAGPART_EXPR:
11778 case VIEW_CONVERT_EXPR:
11779 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
11780 gimple_test_f, fallback);
11781 break;
11783 case ARRAY_REF:
11784 case ARRAY_RANGE_REF:
11785 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
11786 gimple_test_f, fallback);
11787 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
11788 gimple_test_f, fallback);
11789 break;
11791 default:
11792 /* Anything else with side-effects must be converted to
11793 a valid statement before we get here. */
11794 gcc_unreachable ();
11797 *expr_p = NULL;
11799 else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p))
11800 && TYPE_MODE (TREE_TYPE (*expr_p)) != BLKmode)
11802 /* Historically, the compiler has treated a bare reference
11803 to a non-BLKmode volatile lvalue as forcing a load. */
11804 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p));
11806 /* Normally, we do not want to create a temporary for a
11807 TREE_ADDRESSABLE type because such a type should not be
11808 copied by bitwise-assignment. However, we make an
11809 exception here, as all we are doing here is ensuring that
11810 we read the bytes that make up the type. We use
11811 create_tmp_var_raw because create_tmp_var will abort when
11812 given a TREE_ADDRESSABLE type. */
11813 tree tmp = create_tmp_var_raw (type, "vol");
11814 gimple_add_tmp_var (tmp);
11815 gimplify_assign (tmp, *expr_p, pre_p);
11816 *expr_p = NULL;
11818 else
11819 /* We can't do anything useful with a volatile reference to
11820 an incomplete type, so just throw it away. Likewise for
11821 a BLKmode type, since any implicit inner load should
11822 already have been turned into an explicit one by the
11823 gimplification process. */
11824 *expr_p = NULL;
11827 /* If we are gimplifying at the statement level, we're done. Tack
11828 everything together and return. */
11829 if (fallback == fb_none || is_statement)
11831 /* Since *EXPR_P has been converted into a GIMPLE tuple, clear
11832 it out for GC to reclaim it. */
11833 *expr_p = NULL_TREE;
11835 if (!gimple_seq_empty_p (internal_pre)
11836 || !gimple_seq_empty_p (internal_post))
11838 gimplify_seq_add_seq (&internal_pre, internal_post);
11839 gimplify_seq_add_seq (pre_p, internal_pre);
11842 /* The result of gimplifying *EXPR_P is going to be the last few
11843 statements in *PRE_P and *POST_P. Add location information
11844 to all the statements that were added by the gimplification
11845 helpers. */
11846 if (!gimple_seq_empty_p (*pre_p))
11847 annotate_all_with_location_after (*pre_p, pre_last_gsi, input_location);
11849 if (!gimple_seq_empty_p (*post_p))
11850 annotate_all_with_location_after (*post_p, post_last_gsi,
11851 input_location);
11853 goto out;
11856 #ifdef ENABLE_GIMPLE_CHECKING
11857 if (*expr_p)
11859 enum tree_code code = TREE_CODE (*expr_p);
11860 /* These expressions should already be in gimple IR form. */
11861 gcc_assert (code != MODIFY_EXPR
11862 && code != ASM_EXPR
11863 && code != BIND_EXPR
11864 && code != CATCH_EXPR
11865 && (code != COND_EXPR || gimplify_ctxp->allow_rhs_cond_expr)
11866 && code != EH_FILTER_EXPR
11867 && code != GOTO_EXPR
11868 && code != LABEL_EXPR
11869 && code != LOOP_EXPR
11870 && code != SWITCH_EXPR
11871 && code != TRY_FINALLY_EXPR
11872 && code != OACC_PARALLEL
11873 && code != OACC_KERNELS
11874 && code != OACC_DATA
11875 && code != OACC_HOST_DATA
11876 && code != OACC_DECLARE
11877 && code != OACC_UPDATE
11878 && code != OACC_ENTER_DATA
11879 && code != OACC_EXIT_DATA
11880 && code != OACC_CACHE
11881 && code != OMP_CRITICAL
11882 && code != OMP_FOR
11883 && code != OACC_LOOP
11884 && code != OMP_MASTER
11885 && code != OMP_TASKGROUP
11886 && code != OMP_ORDERED
11887 && code != OMP_PARALLEL
11888 && code != OMP_SECTIONS
11889 && code != OMP_SECTION
11890 && code != OMP_SINGLE);
11892 #endif
11894 /* Otherwise we're gimplifying a subexpression, so the resulting
11895 value is interesting. If it's a valid operand that matches
11896 GIMPLE_TEST_F, we're done. Unless we are handling some
11897 post-effects internally; if that's the case, we need to copy into
11898 a temporary before adding the post-effects to POST_P. */
11899 if (gimple_seq_empty_p (internal_post) && (*gimple_test_f) (*expr_p))
11900 goto out;
11902 /* Otherwise, we need to create a new temporary for the gimplified
11903 expression. */
11905 /* We can't return an lvalue if we have an internal postqueue. The
11906 object the lvalue refers to would (probably) be modified by the
11907 postqueue; we need to copy the value out first, which means an
11908 rvalue. */
11909 if ((fallback & fb_lvalue)
11910 && gimple_seq_empty_p (internal_post)
11911 && is_gimple_addressable (*expr_p))
11913 /* An lvalue will do. Take the address of the expression, store it
11914 in a temporary, and replace the expression with an INDIRECT_REF of
11915 that temporary. */
11916 tmp = build_fold_addr_expr_loc (input_location, *expr_p);
11917 gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue);
11918 *expr_p = build_simple_mem_ref (tmp);
11920 else if ((fallback & fb_rvalue) && is_gimple_reg_rhs_or_call (*expr_p))
11922 /* An rvalue will do. Assign the gimplified expression into a
11923 new temporary TMP and replace the original expression with
11924 TMP. First, make sure that the expression has a type so that
11925 it can be assigned into a temporary. */
11926 gcc_assert (!VOID_TYPE_P (TREE_TYPE (*expr_p)));
11927 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
11929 else
11931 #ifdef ENABLE_GIMPLE_CHECKING
11932 if (!(fallback & fb_mayfail))
11934 fprintf (stderr, "gimplification failed:\n");
11935 print_generic_expr (stderr, *expr_p, 0);
11936 debug_tree (*expr_p);
11937 internal_error ("gimplification failed");
11939 #endif
11940 gcc_assert (fallback & fb_mayfail);
11942 /* If this is an asm statement, and the user asked for the
11943 impossible, don't die. Fail and let gimplify_asm_expr
11944 issue an error. */
11945 ret = GS_ERROR;
11946 goto out;
11949 /* Make sure the temporary matches our predicate. */
11950 gcc_assert ((*gimple_test_f) (*expr_p));
11952 if (!gimple_seq_empty_p (internal_post))
11954 annotate_all_with_location (internal_post, input_location);
11955 gimplify_seq_add_seq (pre_p, internal_post);
11958 out:
11959 input_location = saved_location;
11960 return ret;
11963 /* Like gimplify_expr but make sure the gimplified result is not itself
11964 a SSA name (but a decl if it were). Temporaries required by
11965 evaluating *EXPR_P may be still SSA names. */
11967 static enum gimplify_status
11968 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
11969 bool (*gimple_test_f) (tree), fallback_t fallback,
11970 bool allow_ssa)
11972 bool was_ssa_name_p = TREE_CODE (*expr_p) == SSA_NAME;
11973 enum gimplify_status ret = gimplify_expr (expr_p, pre_p, post_p,
11974 gimple_test_f, fallback);
11975 if (! allow_ssa
11976 && TREE_CODE (*expr_p) == SSA_NAME)
11978 tree name = *expr_p;
11979 if (was_ssa_name_p)
11980 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, NULL, false);
11981 else
11983 /* Avoid the extra copy if possible. */
11984 *expr_p = create_tmp_reg (TREE_TYPE (name));
11985 gimple_set_lhs (SSA_NAME_DEF_STMT (name), *expr_p);
11986 release_ssa_name (name);
11989 return ret;
11992 /* Look through TYPE for variable-sized objects and gimplify each such
11993 size that we find. Add to LIST_P any statements generated. */
11995 void
11996 gimplify_type_sizes (tree type, gimple_seq *list_p)
11998 tree field, t;
12000 if (type == NULL || type == error_mark_node)
12001 return;
12003 /* We first do the main variant, then copy into any other variants. */
12004 type = TYPE_MAIN_VARIANT (type);
12006 /* Avoid infinite recursion. */
12007 if (TYPE_SIZES_GIMPLIFIED (type))
12008 return;
12010 TYPE_SIZES_GIMPLIFIED (type) = 1;
12012 switch (TREE_CODE (type))
12014 case INTEGER_TYPE:
12015 case ENUMERAL_TYPE:
12016 case BOOLEAN_TYPE:
12017 case REAL_TYPE:
12018 case FIXED_POINT_TYPE:
12019 gimplify_one_sizepos (&TYPE_MIN_VALUE (type), list_p);
12020 gimplify_one_sizepos (&TYPE_MAX_VALUE (type), list_p);
12022 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
12024 TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type);
12025 TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type);
12027 break;
12029 case ARRAY_TYPE:
12030 /* These types may not have declarations, so handle them here. */
12031 gimplify_type_sizes (TREE_TYPE (type), list_p);
12032 gimplify_type_sizes (TYPE_DOMAIN (type), list_p);
12033 /* Ensure VLA bounds aren't removed, for -O0 they should be variables
12034 with assigned stack slots, for -O1+ -g they should be tracked
12035 by VTA. */
12036 if (!(TYPE_NAME (type)
12037 && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
12038 && DECL_IGNORED_P (TYPE_NAME (type)))
12039 && TYPE_DOMAIN (type)
12040 && INTEGRAL_TYPE_P (TYPE_DOMAIN (type)))
12042 t = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
12043 if (t && TREE_CODE (t) == VAR_DECL && DECL_ARTIFICIAL (t))
12044 DECL_IGNORED_P (t) = 0;
12045 t = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
12046 if (t && TREE_CODE (t) == VAR_DECL && DECL_ARTIFICIAL (t))
12047 DECL_IGNORED_P (t) = 0;
12049 break;
12051 case RECORD_TYPE:
12052 case UNION_TYPE:
12053 case QUAL_UNION_TYPE:
12054 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
12055 if (TREE_CODE (field) == FIELD_DECL)
12057 gimplify_one_sizepos (&DECL_FIELD_OFFSET (field), list_p);
12058 gimplify_one_sizepos (&DECL_SIZE (field), list_p);
12059 gimplify_one_sizepos (&DECL_SIZE_UNIT (field), list_p);
12060 gimplify_type_sizes (TREE_TYPE (field), list_p);
12062 break;
12064 case POINTER_TYPE:
12065 case REFERENCE_TYPE:
12066 /* We used to recurse on the pointed-to type here, which turned out to
12067 be incorrect because its definition might refer to variables not
12068 yet initialized at this point if a forward declaration is involved.
12070 It was actually useful for anonymous pointed-to types to ensure
12071 that the sizes evaluation dominates every possible later use of the
12072 values. Restricting to such types here would be safe since there
12073 is no possible forward declaration around, but would introduce an
12074 undesirable middle-end semantic to anonymity. We then defer to
12075 front-ends the responsibility of ensuring that the sizes are
12076 evaluated both early and late enough, e.g. by attaching artificial
12077 type declarations to the tree. */
12078 break;
12080 default:
12081 break;
12084 gimplify_one_sizepos (&TYPE_SIZE (type), list_p);
12085 gimplify_one_sizepos (&TYPE_SIZE_UNIT (type), list_p);
12087 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
12089 TYPE_SIZE (t) = TYPE_SIZE (type);
12090 TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (type);
12091 TYPE_SIZES_GIMPLIFIED (t) = 1;
12095 /* A subroutine of gimplify_type_sizes to make sure that *EXPR_P,
12096 a size or position, has had all of its SAVE_EXPRs evaluated.
12097 We add any required statements to *STMT_P. */
12099 void
12100 gimplify_one_sizepos (tree *expr_p, gimple_seq *stmt_p)
12102 tree expr = *expr_p;
12104 /* We don't do anything if the value isn't there, is constant, or contains
12105 A PLACEHOLDER_EXPR. We also don't want to do anything if it's already
12106 a VAR_DECL. If it's a VAR_DECL from another function, the gimplifier
12107 will want to replace it with a new variable, but that will cause problems
12108 if this type is from outside the function. It's OK to have that here. */
12109 if (is_gimple_sizepos (expr))
12110 return;
12112 *expr_p = unshare_expr (expr);
12114 /* SSA names in decl/type fields are a bad idea - they'll get reclaimed
12115 if the def vanishes. */
12116 gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue, false);
12119 /* Gimplify the body of statements of FNDECL and return a GIMPLE_BIND node
12120 containing the sequence of corresponding GIMPLE statements. If DO_PARMS
12121 is true, also gimplify the parameters. */
12123 gbind *
12124 gimplify_body (tree fndecl, bool do_parms)
12126 location_t saved_location = input_location;
12127 gimple_seq parm_stmts, seq;
12128 gimple *outer_stmt;
12129 gbind *outer_bind;
12130 struct cgraph_node *cgn;
12132 timevar_push (TV_TREE_GIMPLIFY);
12134 init_tree_ssa (cfun);
12136 /* Initialize for optimize_insn_for_s{ize,peed}_p possibly called during
12137 gimplification. */
12138 default_rtl_profile ();
12140 gcc_assert (gimplify_ctxp == NULL);
12141 push_gimplify_context (true);
12143 if (flag_openacc || flag_openmp)
12145 gcc_assert (gimplify_omp_ctxp == NULL);
12146 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (fndecl)))
12147 gimplify_omp_ctxp = new_omp_context (ORT_TARGET);
12150 /* Unshare most shared trees in the body and in that of any nested functions.
12151 It would seem we don't have to do this for nested functions because
12152 they are supposed to be output and then the outer function gimplified
12153 first, but the g++ front end doesn't always do it that way. */
12154 unshare_body (fndecl);
12155 unvisit_body (fndecl);
12157 cgn = cgraph_node::get (fndecl);
12158 if (cgn && cgn->origin)
12159 nonlocal_vlas = new hash_set<tree>;
12161 /* Make sure input_location isn't set to something weird. */
12162 input_location = DECL_SOURCE_LOCATION (fndecl);
12164 /* Resolve callee-copies. This has to be done before processing
12165 the body so that DECL_VALUE_EXPR gets processed correctly. */
12166 parm_stmts = do_parms ? gimplify_parameters () : NULL;
12168 /* Gimplify the function's body. */
12169 seq = NULL;
12170 gimplify_stmt (&DECL_SAVED_TREE (fndecl), &seq);
12171 outer_stmt = gimple_seq_first_stmt (seq);
12172 if (!outer_stmt)
12174 outer_stmt = gimple_build_nop ();
12175 gimplify_seq_add_stmt (&seq, outer_stmt);
12178 /* The body must contain exactly one statement, a GIMPLE_BIND. If this is
12179 not the case, wrap everything in a GIMPLE_BIND to make it so. */
12180 if (gimple_code (outer_stmt) == GIMPLE_BIND
12181 && gimple_seq_first (seq) == gimple_seq_last (seq))
12182 outer_bind = as_a <gbind *> (outer_stmt);
12183 else
12184 outer_bind = gimple_build_bind (NULL_TREE, seq, NULL);
12186 DECL_SAVED_TREE (fndecl) = NULL_TREE;
12188 /* If we had callee-copies statements, insert them at the beginning
12189 of the function and clear DECL_VALUE_EXPR_P on the parameters. */
12190 if (!gimple_seq_empty_p (parm_stmts))
12192 tree parm;
12194 gimplify_seq_add_seq (&parm_stmts, gimple_bind_body (outer_bind));
12195 gimple_bind_set_body (outer_bind, parm_stmts);
12197 for (parm = DECL_ARGUMENTS (current_function_decl);
12198 parm; parm = DECL_CHAIN (parm))
12199 if (DECL_HAS_VALUE_EXPR_P (parm))
12201 DECL_HAS_VALUE_EXPR_P (parm) = 0;
12202 DECL_IGNORED_P (parm) = 0;
12206 if (nonlocal_vlas)
12208 if (nonlocal_vla_vars)
12210 /* tree-nested.c may later on call declare_vars (..., true);
12211 which relies on BLOCK_VARS chain to be the tail of the
12212 gimple_bind_vars chain. Ensure we don't violate that
12213 assumption. */
12214 if (gimple_bind_block (outer_bind)
12215 == DECL_INITIAL (current_function_decl))
12216 declare_vars (nonlocal_vla_vars, outer_bind, true);
12217 else
12218 BLOCK_VARS (DECL_INITIAL (current_function_decl))
12219 = chainon (BLOCK_VARS (DECL_INITIAL (current_function_decl)),
12220 nonlocal_vla_vars);
12221 nonlocal_vla_vars = NULL_TREE;
12223 delete nonlocal_vlas;
12224 nonlocal_vlas = NULL;
12227 if ((flag_openacc || flag_openmp || flag_openmp_simd)
12228 && gimplify_omp_ctxp)
12230 delete_omp_context (gimplify_omp_ctxp);
12231 gimplify_omp_ctxp = NULL;
12234 pop_gimplify_context (outer_bind);
12235 gcc_assert (gimplify_ctxp == NULL);
12237 if (flag_checking && !seen_error ())
12238 verify_gimple_in_seq (gimple_bind_body (outer_bind));
12240 timevar_pop (TV_TREE_GIMPLIFY);
12241 input_location = saved_location;
12243 return outer_bind;
12246 typedef char *char_p; /* For DEF_VEC_P. */
12248 /* Return whether we should exclude FNDECL from instrumentation. */
12250 static bool
12251 flag_instrument_functions_exclude_p (tree fndecl)
12253 vec<char_p> *v;
12255 v = (vec<char_p> *) flag_instrument_functions_exclude_functions;
12256 if (v && v->length () > 0)
12258 const char *name;
12259 int i;
12260 char *s;
12262 name = lang_hooks.decl_printable_name (fndecl, 0);
12263 FOR_EACH_VEC_ELT (*v, i, s)
12264 if (strstr (name, s) != NULL)
12265 return true;
12268 v = (vec<char_p> *) flag_instrument_functions_exclude_files;
12269 if (v && v->length () > 0)
12271 const char *name;
12272 int i;
12273 char *s;
12275 name = DECL_SOURCE_FILE (fndecl);
12276 FOR_EACH_VEC_ELT (*v, i, s)
12277 if (strstr (name, s) != NULL)
12278 return true;
12281 return false;
12284 /* Entry point to the gimplification pass. FNDECL is the FUNCTION_DECL
12285 node for the function we want to gimplify.
12287 Return the sequence of GIMPLE statements corresponding to the body
12288 of FNDECL. */
12290 void
12291 gimplify_function_tree (tree fndecl)
12293 tree parm, ret;
12294 gimple_seq seq;
12295 gbind *bind;
12297 gcc_assert (!gimple_body (fndecl));
12299 if (DECL_STRUCT_FUNCTION (fndecl))
12300 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
12301 else
12302 push_struct_function (fndecl);
12304 /* Tentatively set PROP_gimple_lva here, and reset it in gimplify_va_arg_expr
12305 if necessary. */
12306 cfun->curr_properties |= PROP_gimple_lva;
12308 for (parm = DECL_ARGUMENTS (fndecl); parm ; parm = DECL_CHAIN (parm))
12310 /* Preliminarily mark non-addressed complex variables as eligible
12311 for promotion to gimple registers. We'll transform their uses
12312 as we find them. */
12313 if ((TREE_CODE (TREE_TYPE (parm)) == COMPLEX_TYPE
12314 || TREE_CODE (TREE_TYPE (parm)) == VECTOR_TYPE)
12315 && !TREE_THIS_VOLATILE (parm)
12316 && !needs_to_live_in_memory (parm))
12317 DECL_GIMPLE_REG_P (parm) = 1;
12320 ret = DECL_RESULT (fndecl);
12321 if ((TREE_CODE (TREE_TYPE (ret)) == COMPLEX_TYPE
12322 || TREE_CODE (TREE_TYPE (ret)) == VECTOR_TYPE)
12323 && !needs_to_live_in_memory (ret))
12324 DECL_GIMPLE_REG_P (ret) = 1;
12326 bind = gimplify_body (fndecl, true);
12328 /* The tree body of the function is no longer needed, replace it
12329 with the new GIMPLE body. */
12330 seq = NULL;
12331 gimple_seq_add_stmt (&seq, bind);
12332 gimple_set_body (fndecl, seq);
12334 /* If we're instrumenting function entry/exit, then prepend the call to
12335 the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to
12336 catch the exit hook. */
12337 /* ??? Add some way to ignore exceptions for this TFE. */
12338 if (flag_instrument_function_entry_exit
12339 && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl)
12340 && !flag_instrument_functions_exclude_p (fndecl))
12342 tree x;
12343 gbind *new_bind;
12344 gimple *tf;
12345 gimple_seq cleanup = NULL, body = NULL;
12346 tree tmp_var;
12347 gcall *call;
12349 x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
12350 call = gimple_build_call (x, 1, integer_zero_node);
12351 tmp_var = create_tmp_var (ptr_type_node, "return_addr");
12352 gimple_call_set_lhs (call, tmp_var);
12353 gimplify_seq_add_stmt (&cleanup, call);
12354 x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_EXIT);
12355 call = gimple_build_call (x, 2,
12356 build_fold_addr_expr (current_function_decl),
12357 tmp_var);
12358 gimplify_seq_add_stmt (&cleanup, call);
12359 tf = gimple_build_try (seq, cleanup, GIMPLE_TRY_FINALLY);
12361 x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
12362 call = gimple_build_call (x, 1, integer_zero_node);
12363 tmp_var = create_tmp_var (ptr_type_node, "return_addr");
12364 gimple_call_set_lhs (call, tmp_var);
12365 gimplify_seq_add_stmt (&body, call);
12366 x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_ENTER);
12367 call = gimple_build_call (x, 2,
12368 build_fold_addr_expr (current_function_decl),
12369 tmp_var);
12370 gimplify_seq_add_stmt (&body, call);
12371 gimplify_seq_add_stmt (&body, tf);
12372 new_bind = gimple_build_bind (NULL, body, gimple_bind_block (bind));
12373 /* Clear the block for BIND, since it is no longer directly inside
12374 the function, but within a try block. */
12375 gimple_bind_set_block (bind, NULL);
12377 /* Replace the current function body with the body
12378 wrapped in the try/finally TF. */
12379 seq = NULL;
12380 gimple_seq_add_stmt (&seq, new_bind);
12381 gimple_set_body (fndecl, seq);
12382 bind = new_bind;
12385 if ((flag_sanitize & SANITIZE_THREAD) != 0
12386 && !lookup_attribute ("no_sanitize_thread", DECL_ATTRIBUTES (fndecl)))
12388 gcall *call = gimple_build_call_internal (IFN_TSAN_FUNC_EXIT, 0);
12389 gimple *tf = gimple_build_try (seq, call, GIMPLE_TRY_FINALLY);
12390 gbind *new_bind = gimple_build_bind (NULL, tf, gimple_bind_block (bind));
12391 /* Clear the block for BIND, since it is no longer directly inside
12392 the function, but within a try block. */
12393 gimple_bind_set_block (bind, NULL);
12394 /* Replace the current function body with the body
12395 wrapped in the try/finally TF. */
12396 seq = NULL;
12397 gimple_seq_add_stmt (&seq, new_bind);
12398 gimple_set_body (fndecl, seq);
12401 DECL_SAVED_TREE (fndecl) = NULL_TREE;
12402 cfun->curr_properties |= PROP_gimple_any;
12404 pop_cfun ();
12406 dump_function (TDI_generic, fndecl);
12409 /* Return a dummy expression of type TYPE in order to keep going after an
12410 error. */
12412 static tree
12413 dummy_object (tree type)
12415 tree t = build_int_cst (build_pointer_type (type), 0);
12416 return build2 (MEM_REF, type, t, t);
12419 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
12420 builtin function, but a very special sort of operator. */
12422 enum gimplify_status
12423 gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p,
12424 gimple_seq *post_p ATTRIBUTE_UNUSED)
12426 tree promoted_type, have_va_type;
12427 tree valist = TREE_OPERAND (*expr_p, 0);
12428 tree type = TREE_TYPE (*expr_p);
12429 tree t, tag, aptag;
12430 location_t loc = EXPR_LOCATION (*expr_p);
12432 /* Verify that valist is of the proper type. */
12433 have_va_type = TREE_TYPE (valist);
12434 if (have_va_type == error_mark_node)
12435 return GS_ERROR;
12436 have_va_type = targetm.canonical_va_list_type (have_va_type);
12437 if (have_va_type == NULL_TREE
12438 && TREE_CODE (valist) == ADDR_EXPR)
12439 /* Handle 'Case 1: Not an array type' from c-common.c/build_va_arg. */
12440 have_va_type
12441 = targetm.canonical_va_list_type (TREE_TYPE (TREE_TYPE (valist)));
12442 gcc_assert (have_va_type != NULL_TREE);
12444 /* Generate a diagnostic for requesting data of a type that cannot
12445 be passed through `...' due to type promotion at the call site. */
12446 if ((promoted_type = lang_hooks.types.type_promotes_to (type))
12447 != type)
12449 static bool gave_help;
12450 bool warned;
12451 /* Use the expansion point to handle cases such as passing bool (defined
12452 in a system header) through `...'. */
12453 source_location xloc
12454 = expansion_point_location_if_in_system_header (loc);
12456 /* Unfortunately, this is merely undefined, rather than a constraint
12457 violation, so we cannot make this an error. If this call is never
12458 executed, the program is still strictly conforming. */
12459 warned = warning_at (xloc, 0,
12460 "%qT is promoted to %qT when passed through %<...%>",
12461 type, promoted_type);
12462 if (!gave_help && warned)
12464 gave_help = true;
12465 inform (xloc, "(so you should pass %qT not %qT to %<va_arg%>)",
12466 promoted_type, type);
12469 /* We can, however, treat "undefined" any way we please.
12470 Call abort to encourage the user to fix the program. */
12471 if (warned)
12472 inform (xloc, "if this code is reached, the program will abort");
12473 /* Before the abort, allow the evaluation of the va_list
12474 expression to exit or longjmp. */
12475 gimplify_and_add (valist, pre_p);
12476 t = build_call_expr_loc (loc,
12477 builtin_decl_implicit (BUILT_IN_TRAP), 0);
12478 gimplify_and_add (t, pre_p);
12480 /* This is dead code, but go ahead and finish so that the
12481 mode of the result comes out right. */
12482 *expr_p = dummy_object (type);
12483 return GS_ALL_DONE;
12486 tag = build_int_cst (build_pointer_type (type), 0);
12487 aptag = build_int_cst (TREE_TYPE (valist), 0);
12489 *expr_p = build_call_expr_internal_loc (loc, IFN_VA_ARG, type, 3,
12490 valist, tag, aptag);
12492 /* Clear the tentatively set PROP_gimple_lva, to indicate that IFN_VA_ARG
12493 needs to be expanded. */
12494 cfun->curr_properties &= ~PROP_gimple_lva;
12496 return GS_OK;
12499 /* Build a new GIMPLE_ASSIGN tuple and append it to the end of *SEQ_P.
12501 DST/SRC are the destination and source respectively. You can pass
12502 ungimplified trees in DST or SRC, in which case they will be
12503 converted to a gimple operand if necessary.
12505 This function returns the newly created GIMPLE_ASSIGN tuple. */
12507 gimple *
12508 gimplify_assign (tree dst, tree src, gimple_seq *seq_p)
12510 tree t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
12511 gimplify_and_add (t, seq_p);
12512 ggc_free (t);
12513 return gimple_seq_last_stmt (*seq_p);
12516 inline hashval_t
12517 gimplify_hasher::hash (const elt_t *p)
12519 tree t = p->val;
12520 return iterative_hash_expr (t, 0);
12523 inline bool
12524 gimplify_hasher::equal (const elt_t *p1, const elt_t *p2)
12526 tree t1 = p1->val;
12527 tree t2 = p2->val;
12528 enum tree_code code = TREE_CODE (t1);
12530 if (TREE_CODE (t2) != code
12531 || TREE_TYPE (t1) != TREE_TYPE (t2))
12532 return false;
12534 if (!operand_equal_p (t1, t2, 0))
12535 return false;
12537 /* Only allow them to compare equal if they also hash equal; otherwise
12538 results are nondeterminate, and we fail bootstrap comparison. */
12539 gcc_checking_assert (hash (p1) == hash (p2));
12541 return true;