2016-10-07 Richard Biener <rguenther@suse.de>
[official-gcc.git] / gcc / gimplify.c
blob2266333442aaac60f0d75a5fe45cc5f93a6da2e8
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 && (last_eval == NULL
1691 || !gimple_call_internal_p (last_eval, IFN_FALLTHROUGH))
1692 && gimple_try_kind (try_stmt) == GIMPLE_TRY_FINALLY)
1694 stmt = gimple_seq_last_stmt (gimple_try_cleanup (try_stmt));
1695 return last_stmt_in_scope (stmt);
1697 else
1698 return last_eval;
1701 default:
1702 return stmt;
1706 /* Collect interesting labels in LABELS and return the statement preceding
1707 another case label, or a user-defined label. */
1709 static gimple *
1710 collect_fallthrough_labels (gimple_stmt_iterator *gsi_p,
1711 auto_vec <struct label_entry> *labels)
1713 gimple *prev = NULL;
1717 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND
1718 || gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_TRY)
1720 /* Nested scope. Only look at the last statement of
1721 the innermost scope. */
1722 location_t bind_loc = gimple_location (gsi_stmt (*gsi_p));
1723 gimple *last = last_stmt_in_scope (gsi_stmt (*gsi_p));
1724 if (last)
1726 prev = last;
1727 /* It might be a label without a location. Use the
1728 location of the scope then. */
1729 if (!gimple_has_location (prev))
1730 gimple_set_location (prev, bind_loc);
1732 gsi_next (gsi_p);
1733 continue;
1736 /* Ifs are tricky. */
1737 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_COND)
1739 gcond *cond_stmt = as_a <gcond *> (gsi_stmt (*gsi_p));
1740 tree false_lab = gimple_cond_false_label (cond_stmt);
1741 location_t if_loc = gimple_location (cond_stmt);
1743 /* If we have e.g.
1744 if (i > 1) goto <D.2259>; else goto D;
1745 we can't do much with the else-branch. */
1746 if (!DECL_ARTIFICIAL (false_lab))
1747 break;
1749 /* Go on until the false label, then one step back. */
1750 for (; !gsi_end_p (*gsi_p); gsi_next (gsi_p))
1752 gimple *stmt = gsi_stmt (*gsi_p);
1753 if (gimple_code (stmt) == GIMPLE_LABEL
1754 && gimple_label_label (as_a <glabel *> (stmt)) == false_lab)
1755 break;
1758 /* Not found? Oops. */
1759 if (gsi_end_p (*gsi_p))
1760 break;
1762 struct label_entry l = { false_lab, if_loc };
1763 labels->safe_push (l);
1765 /* Go to the last statement of the then branch. */
1766 gsi_prev (gsi_p);
1768 /* if (i != 0) goto <D.1759>; else goto <D.1760>;
1769 <D.1759>:
1770 <stmt>;
1771 goto <D.1761>;
1772 <D.1760>:
1774 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_GOTO
1775 && !gimple_has_location (gsi_stmt (*gsi_p)))
1777 /* Look at the statement before, it might be
1778 attribute fallthrough, in which case don't warn. */
1779 gsi_prev (gsi_p);
1780 bool fallthru_before_dest
1781 = gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_FALLTHROUGH);
1782 gsi_next (gsi_p);
1783 tree goto_dest = gimple_goto_dest (gsi_stmt (*gsi_p));
1784 if (!fallthru_before_dest)
1786 struct label_entry l = { goto_dest, if_loc };
1787 labels->safe_push (l);
1790 /* And move back. */
1791 gsi_next (gsi_p);
1794 /* Remember the last statement. Skip labels that are of no interest
1795 to us. */
1796 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
1798 tree label = gimple_label_label (as_a <glabel *> (gsi_stmt (*gsi_p)));
1799 if (find_label_entry (labels, label))
1800 prev = gsi_stmt (*gsi_p);
1802 else
1803 prev = gsi_stmt (*gsi_p);
1804 gsi_next (gsi_p);
1806 while (!gsi_end_p (*gsi_p)
1807 /* Stop if we find a case or a user-defined label. */
1808 && (gimple_code (gsi_stmt (*gsi_p)) != GIMPLE_LABEL
1809 || !gimple_has_location (gsi_stmt (*gsi_p))));
1811 return prev;
1814 /* Return true if the switch fallthough warning should occur. LABEL is
1815 the label statement that we're falling through to. */
1817 static bool
1818 should_warn_for_implicit_fallthrough (gimple_stmt_iterator *gsi_p, tree label)
1820 gimple_stmt_iterator gsi = *gsi_p;
1822 /* Don't warn if the label is marked with a "falls through" comment. */
1823 if (FALLTHROUGH_LABEL_P (label))
1824 return false;
1826 /* Don't warn for a non-case label followed by a statement:
1827 case 0:
1828 foo ();
1829 label:
1830 bar ();
1831 as these are likely intentional. */
1832 if (!case_label_p (&gimplify_ctxp->case_labels, label))
1834 gsi_next (&gsi);
1835 if (gsi_end_p (gsi) || gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL)
1836 return false;
1839 /* Don't warn for terminated branches, i.e. when the subsequent case labels
1840 immediately breaks. */
1841 gsi = *gsi_p;
1843 /* Skip all immediately following labels. */
1844 while (!gsi_end_p (gsi) && gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL)
1845 gsi_next (&gsi);
1847 /* { ... something; default:; } */
1848 if (gsi_end_p (gsi)
1849 /* { ... something; default: break; } or
1850 { ... something; default: goto L; } */
1851 || gimple_code (gsi_stmt (gsi)) == GIMPLE_GOTO
1852 /* { ... something; default: return; } */
1853 || gimple_code (gsi_stmt (gsi)) == GIMPLE_RETURN)
1854 return false;
1856 return true;
1859 /* Callback for walk_gimple_seq. */
1861 static tree
1862 warn_implicit_fallthrough_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
1863 struct walk_stmt_info *)
1865 gimple *stmt = gsi_stmt (*gsi_p);
1867 *handled_ops_p = true;
1868 switch (gimple_code (stmt))
1870 case GIMPLE_TRY:
1871 case GIMPLE_BIND:
1872 case GIMPLE_CATCH:
1873 case GIMPLE_EH_FILTER:
1874 case GIMPLE_TRANSACTION:
1875 /* Walk the sub-statements. */
1876 *handled_ops_p = false;
1877 break;
1879 /* Find a sequence of form:
1881 GIMPLE_LABEL
1882 [...]
1883 <may fallthru stmt>
1884 GIMPLE_LABEL
1886 and possibly warn. */
1887 case GIMPLE_LABEL:
1889 /* Found a label. Skip all immediately following labels. */
1890 while (!gsi_end_p (*gsi_p)
1891 && gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
1892 gsi_next (gsi_p);
1894 /* There might be no more statements. */
1895 if (gsi_end_p (*gsi_p))
1896 return integer_zero_node;
1898 /* Vector of labels that fall through. */
1899 auto_vec <struct label_entry> labels;
1900 gimple *prev = collect_fallthrough_labels (gsi_p, &labels);
1902 /* There might be no more statements. */
1903 if (gsi_end_p (*gsi_p))
1904 return integer_zero_node;
1906 gimple *next = gsi_stmt (*gsi_p);
1907 tree label;
1908 /* If what follows is a label, then we may have a fallthrough. */
1909 if (gimple_code (next) == GIMPLE_LABEL
1910 && gimple_has_location (next)
1911 && (label = gimple_label_label (as_a <glabel *> (next)))
1912 && prev != NULL)
1914 struct label_entry *l;
1915 bool warned_p = false;
1916 if (!should_warn_for_implicit_fallthrough (gsi_p, label))
1917 /* Quiet. */;
1918 else if (gimple_code (prev) == GIMPLE_LABEL
1919 && (label = gimple_label_label (as_a <glabel *> (prev)))
1920 && (l = find_label_entry (&labels, label)))
1921 warned_p = warning_at (l->loc, OPT_Wimplicit_fallthrough,
1922 "this statement may fall through");
1923 else if (!gimple_call_internal_p (prev, IFN_FALLTHROUGH)
1924 /* Try to be clever and don't warn when the statement
1925 can't actually fall through. */
1926 && gimple_stmt_may_fallthru (prev)
1927 && gimple_has_location (prev))
1928 warned_p = warning_at (gimple_location (prev),
1929 OPT_Wimplicit_fallthrough,
1930 "this statement may fall through");
1931 if (warned_p)
1932 inform (gimple_location (next), "here");
1934 /* Mark this label as processed so as to prevent multiple
1935 warnings in nested switches. */
1936 FALLTHROUGH_LABEL_P (label) = true;
1938 /* So that next warn_implicit_fallthrough_r will start looking for
1939 a new sequence starting with this label. */
1940 gsi_prev (gsi_p);
1943 break;
1944 default:
1945 break;
1947 return NULL_TREE;
1950 /* Warn when a switch case falls through. */
1952 static void
1953 maybe_warn_implicit_fallthrough (gimple_seq seq)
1955 if (!warn_implicit_fallthrough)
1956 return;
1958 /* This warning is meant for C/C++/ObjC/ObjC++ only. */
1959 if (!(lang_GNU_C ()
1960 || lang_GNU_CXX ()
1961 || lang_GNU_OBJC ()))
1962 return;
1964 struct walk_stmt_info wi;
1965 memset (&wi, 0, sizeof (wi));
1966 walk_gimple_seq (seq, warn_implicit_fallthrough_r, NULL, &wi);
1969 /* Callback for walk_gimple_seq. */
1971 static tree
1972 expand_FALLTHROUGH_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
1973 struct walk_stmt_info *)
1975 gimple *stmt = gsi_stmt (*gsi_p);
1977 *handled_ops_p = true;
1978 switch (gimple_code (stmt))
1980 case GIMPLE_TRY:
1981 case GIMPLE_BIND:
1982 case GIMPLE_CATCH:
1983 case GIMPLE_EH_FILTER:
1984 case GIMPLE_TRANSACTION:
1985 /* Walk the sub-statements. */
1986 *handled_ops_p = false;
1987 break;
1988 case GIMPLE_CALL:
1989 if (gimple_call_internal_p (stmt, IFN_FALLTHROUGH))
1991 gsi_remove (gsi_p, true);
1992 if (gsi_end_p (*gsi_p))
1993 return integer_zero_node;
1995 bool found = false;
1996 location_t loc = gimple_location (stmt);
1998 gimple_stmt_iterator gsi2 = *gsi_p;
1999 stmt = gsi_stmt (gsi2);
2000 if (gimple_code (stmt) == GIMPLE_GOTO && !gimple_has_location (stmt))
2002 /* Go on until the artificial label. */
2003 tree goto_dest = gimple_goto_dest (stmt);
2004 for (; !gsi_end_p (gsi2); gsi_next (&gsi2))
2006 if (gimple_code (gsi_stmt (gsi2)) == GIMPLE_LABEL
2007 && gimple_label_label (as_a <glabel *> (gsi_stmt (gsi2)))
2008 == goto_dest)
2009 break;
2012 /* Not found? Stop. */
2013 if (gsi_end_p (gsi2))
2014 break;
2016 /* Look one past it. */
2017 gsi_next (&gsi2);
2020 /* We're looking for a case label or default label here. */
2021 while (!gsi_end_p (gsi2))
2023 stmt = gsi_stmt (gsi2);
2024 if (gimple_code (stmt) == GIMPLE_LABEL)
2026 tree label = gimple_label_label (as_a <glabel *> (stmt));
2027 if (gimple_has_location (stmt) && DECL_ARTIFICIAL (label))
2029 found = true;
2030 break;
2033 else
2034 /* Something other than a label. That's not expected. */
2035 break;
2036 gsi_next (&gsi2);
2038 if (!found)
2039 warning_at (loc, 0, "attribute %<fallthrough%> not preceding "
2040 "a case label or default label");
2042 break;
2043 default:
2044 break;
2046 return NULL_TREE;
2049 /* Expand all FALLTHROUGH () calls in SEQ. */
2051 static void
2052 expand_FALLTHROUGH (gimple_seq *seq_p)
2054 struct walk_stmt_info wi;
2055 memset (&wi, 0, sizeof (wi));
2056 walk_gimple_seq_mod (seq_p, expand_FALLTHROUGH_r, NULL, &wi);
2060 /* Gimplify a SWITCH_EXPR, and collect the vector of labels it can
2061 branch to. */
2063 static enum gimplify_status
2064 gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p)
2066 tree switch_expr = *expr_p;
2067 gimple_seq switch_body_seq = NULL;
2068 enum gimplify_status ret;
2069 tree index_type = TREE_TYPE (switch_expr);
2070 if (index_type == NULL_TREE)
2071 index_type = TREE_TYPE (SWITCH_COND (switch_expr));
2073 ret = gimplify_expr (&SWITCH_COND (switch_expr), pre_p, NULL, is_gimple_val,
2074 fb_rvalue);
2075 if (ret == GS_ERROR || ret == GS_UNHANDLED)
2076 return ret;
2078 if (SWITCH_BODY (switch_expr))
2080 vec<tree> labels;
2081 vec<tree> saved_labels;
2082 tree default_case = NULL_TREE;
2083 gswitch *switch_stmt;
2085 /* If someone can be bothered to fill in the labels, they can
2086 be bothered to null out the body too. */
2087 gcc_assert (!SWITCH_LABELS (switch_expr));
2089 /* Save old labels, get new ones from body, then restore the old
2090 labels. Save all the things from the switch body to append after. */
2091 saved_labels = gimplify_ctxp->case_labels;
2092 gimplify_ctxp->case_labels.create (8);
2093 bool old_in_switch_expr = gimplify_ctxp->in_switch_expr;
2094 gimplify_ctxp->in_switch_expr = true;
2096 gimplify_stmt (&SWITCH_BODY (switch_expr), &switch_body_seq);
2098 gimplify_ctxp->in_switch_expr = old_in_switch_expr;
2099 maybe_warn_switch_unreachable (switch_body_seq);
2100 maybe_warn_implicit_fallthrough (switch_body_seq);
2101 /* Only do this for the outermost GIMPLE_SWITCH. */
2102 if (!gimplify_ctxp->in_switch_expr)
2103 expand_FALLTHROUGH (&switch_body_seq);
2105 labels = gimplify_ctxp->case_labels;
2106 gimplify_ctxp->case_labels = saved_labels;
2108 preprocess_case_label_vec_for_gimple (labels, index_type,
2109 &default_case);
2111 if (!default_case)
2113 glabel *new_default;
2115 default_case
2116 = build_case_label (NULL_TREE, NULL_TREE,
2117 create_artificial_label (UNKNOWN_LOCATION));
2118 new_default = gimple_build_label (CASE_LABEL (default_case));
2119 gimplify_seq_add_stmt (&switch_body_seq, new_default);
2122 switch_stmt = gimple_build_switch (SWITCH_COND (switch_expr),
2123 default_case, labels);
2124 gimplify_seq_add_stmt (pre_p, switch_stmt);
2125 gimplify_seq_add_seq (pre_p, switch_body_seq);
2126 labels.release ();
2128 else
2129 gcc_assert (SWITCH_LABELS (switch_expr));
2131 return GS_ALL_DONE;
2134 /* Gimplify the LABEL_EXPR pointed to by EXPR_P. */
2136 static enum gimplify_status
2137 gimplify_label_expr (tree *expr_p, gimple_seq *pre_p)
2139 gcc_assert (decl_function_context (LABEL_EXPR_LABEL (*expr_p))
2140 == current_function_decl);
2142 glabel *label_stmt = gimple_build_label (LABEL_EXPR_LABEL (*expr_p));
2143 gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
2144 gimplify_seq_add_stmt (pre_p, label_stmt);
2146 return GS_ALL_DONE;
2149 /* Gimplify the CASE_LABEL_EXPR pointed to by EXPR_P. */
2151 static enum gimplify_status
2152 gimplify_case_label_expr (tree *expr_p, gimple_seq *pre_p)
2154 struct gimplify_ctx *ctxp;
2155 glabel *label_stmt;
2157 /* Invalid programs can play Duff's Device type games with, for example,
2158 #pragma omp parallel. At least in the C front end, we don't
2159 detect such invalid branches until after gimplification, in the
2160 diagnose_omp_blocks pass. */
2161 for (ctxp = gimplify_ctxp; ; ctxp = ctxp->prev_context)
2162 if (ctxp->case_labels.exists ())
2163 break;
2165 label_stmt = gimple_build_label (CASE_LABEL (*expr_p));
2166 gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
2167 ctxp->case_labels.safe_push (*expr_p);
2168 gimplify_seq_add_stmt (pre_p, label_stmt);
2170 return GS_ALL_DONE;
2173 /* Build a GOTO to the LABEL_DECL pointed to by LABEL_P, building it first
2174 if necessary. */
2176 tree
2177 build_and_jump (tree *label_p)
2179 if (label_p == NULL)
2180 /* If there's nowhere to jump, just fall through. */
2181 return NULL_TREE;
2183 if (*label_p == NULL_TREE)
2185 tree label = create_artificial_label (UNKNOWN_LOCATION);
2186 *label_p = label;
2189 return build1 (GOTO_EXPR, void_type_node, *label_p);
2192 /* Gimplify an EXIT_EXPR by converting to a GOTO_EXPR inside a COND_EXPR.
2193 This also involves building a label to jump to and communicating it to
2194 gimplify_loop_expr through gimplify_ctxp->exit_label. */
2196 static enum gimplify_status
2197 gimplify_exit_expr (tree *expr_p)
2199 tree cond = TREE_OPERAND (*expr_p, 0);
2200 tree expr;
2202 expr = build_and_jump (&gimplify_ctxp->exit_label);
2203 expr = build3 (COND_EXPR, void_type_node, cond, expr, NULL_TREE);
2204 *expr_p = expr;
2206 return GS_OK;
2209 /* *EXPR_P is a COMPONENT_REF being used as an rvalue. If its type is
2210 different from its canonical type, wrap the whole thing inside a
2211 NOP_EXPR and force the type of the COMPONENT_REF to be the canonical
2212 type.
2214 The canonical type of a COMPONENT_REF is the type of the field being
2215 referenced--unless the field is a bit-field which can be read directly
2216 in a smaller mode, in which case the canonical type is the
2217 sign-appropriate type corresponding to that mode. */
2219 static void
2220 canonicalize_component_ref (tree *expr_p)
2222 tree expr = *expr_p;
2223 tree type;
2225 gcc_assert (TREE_CODE (expr) == COMPONENT_REF);
2227 if (INTEGRAL_TYPE_P (TREE_TYPE (expr)))
2228 type = TREE_TYPE (get_unwidened (expr, NULL_TREE));
2229 else
2230 type = TREE_TYPE (TREE_OPERAND (expr, 1));
2232 /* One could argue that all the stuff below is not necessary for
2233 the non-bitfield case and declare it a FE error if type
2234 adjustment would be needed. */
2235 if (TREE_TYPE (expr) != type)
2237 #ifdef ENABLE_TYPES_CHECKING
2238 tree old_type = TREE_TYPE (expr);
2239 #endif
2240 int type_quals;
2242 /* We need to preserve qualifiers and propagate them from
2243 operand 0. */
2244 type_quals = TYPE_QUALS (type)
2245 | TYPE_QUALS (TREE_TYPE (TREE_OPERAND (expr, 0)));
2246 if (TYPE_QUALS (type) != type_quals)
2247 type = build_qualified_type (TYPE_MAIN_VARIANT (type), type_quals);
2249 /* Set the type of the COMPONENT_REF to the underlying type. */
2250 TREE_TYPE (expr) = type;
2252 #ifdef ENABLE_TYPES_CHECKING
2253 /* It is now a FE error, if the conversion from the canonical
2254 type to the original expression type is not useless. */
2255 gcc_assert (useless_type_conversion_p (old_type, type));
2256 #endif
2260 /* If a NOP conversion is changing a pointer to array of foo to a pointer
2261 to foo, embed that change in the ADDR_EXPR by converting
2262 T array[U];
2263 (T *)&array
2265 &array[L]
2266 where L is the lower bound. For simplicity, only do this for constant
2267 lower bound.
2268 The constraint is that the type of &array[L] is trivially convertible
2269 to T *. */
2271 static void
2272 canonicalize_addr_expr (tree *expr_p)
2274 tree expr = *expr_p;
2275 tree addr_expr = TREE_OPERAND (expr, 0);
2276 tree datype, ddatype, pddatype;
2278 /* We simplify only conversions from an ADDR_EXPR to a pointer type. */
2279 if (!POINTER_TYPE_P (TREE_TYPE (expr))
2280 || TREE_CODE (addr_expr) != ADDR_EXPR)
2281 return;
2283 /* The addr_expr type should be a pointer to an array. */
2284 datype = TREE_TYPE (TREE_TYPE (addr_expr));
2285 if (TREE_CODE (datype) != ARRAY_TYPE)
2286 return;
2288 /* The pointer to element type shall be trivially convertible to
2289 the expression pointer type. */
2290 ddatype = TREE_TYPE (datype);
2291 pddatype = build_pointer_type (ddatype);
2292 if (!useless_type_conversion_p (TYPE_MAIN_VARIANT (TREE_TYPE (expr)),
2293 pddatype))
2294 return;
2296 /* The lower bound and element sizes must be constant. */
2297 if (!TYPE_SIZE_UNIT (ddatype)
2298 || TREE_CODE (TYPE_SIZE_UNIT (ddatype)) != INTEGER_CST
2299 || !TYPE_DOMAIN (datype) || !TYPE_MIN_VALUE (TYPE_DOMAIN (datype))
2300 || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (datype))) != INTEGER_CST)
2301 return;
2303 /* All checks succeeded. Build a new node to merge the cast. */
2304 *expr_p = build4 (ARRAY_REF, ddatype, TREE_OPERAND (addr_expr, 0),
2305 TYPE_MIN_VALUE (TYPE_DOMAIN (datype)),
2306 NULL_TREE, NULL_TREE);
2307 *expr_p = build1 (ADDR_EXPR, pddatype, *expr_p);
2309 /* We can have stripped a required restrict qualifier above. */
2310 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
2311 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
2314 /* *EXPR_P is a NOP_EXPR or CONVERT_EXPR. Remove it and/or other conversions
2315 underneath as appropriate. */
2317 static enum gimplify_status
2318 gimplify_conversion (tree *expr_p)
2320 location_t loc = EXPR_LOCATION (*expr_p);
2321 gcc_assert (CONVERT_EXPR_P (*expr_p));
2323 /* Then strip away all but the outermost conversion. */
2324 STRIP_SIGN_NOPS (TREE_OPERAND (*expr_p, 0));
2326 /* And remove the outermost conversion if it's useless. */
2327 if (tree_ssa_useless_type_conversion (*expr_p))
2328 *expr_p = TREE_OPERAND (*expr_p, 0);
2330 /* If we still have a conversion at the toplevel,
2331 then canonicalize some constructs. */
2332 if (CONVERT_EXPR_P (*expr_p))
2334 tree sub = TREE_OPERAND (*expr_p, 0);
2336 /* If a NOP conversion is changing the type of a COMPONENT_REF
2337 expression, then canonicalize its type now in order to expose more
2338 redundant conversions. */
2339 if (TREE_CODE (sub) == COMPONENT_REF)
2340 canonicalize_component_ref (&TREE_OPERAND (*expr_p, 0));
2342 /* If a NOP conversion is changing a pointer to array of foo
2343 to a pointer to foo, embed that change in the ADDR_EXPR. */
2344 else if (TREE_CODE (sub) == ADDR_EXPR)
2345 canonicalize_addr_expr (expr_p);
2348 /* If we have a conversion to a non-register type force the
2349 use of a VIEW_CONVERT_EXPR instead. */
2350 if (CONVERT_EXPR_P (*expr_p) && !is_gimple_reg_type (TREE_TYPE (*expr_p)))
2351 *expr_p = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (*expr_p),
2352 TREE_OPERAND (*expr_p, 0));
2354 /* Canonicalize CONVERT_EXPR to NOP_EXPR. */
2355 if (TREE_CODE (*expr_p) == CONVERT_EXPR)
2356 TREE_SET_CODE (*expr_p, NOP_EXPR);
2358 return GS_OK;
2361 /* Nonlocal VLAs seen in the current function. */
2362 static hash_set<tree> *nonlocal_vlas;
2364 /* The VAR_DECLs created for nonlocal VLAs for debug info purposes. */
2365 static tree nonlocal_vla_vars;
2367 /* Gimplify a VAR_DECL or PARM_DECL. Return GS_OK if we expanded a
2368 DECL_VALUE_EXPR, and it's worth re-examining things. */
2370 static enum gimplify_status
2371 gimplify_var_or_parm_decl (tree *expr_p)
2373 tree decl = *expr_p;
2375 /* ??? If this is a local variable, and it has not been seen in any
2376 outer BIND_EXPR, then it's probably the result of a duplicate
2377 declaration, for which we've already issued an error. It would
2378 be really nice if the front end wouldn't leak these at all.
2379 Currently the only known culprit is C++ destructors, as seen
2380 in g++.old-deja/g++.jason/binding.C. */
2381 if (TREE_CODE (decl) == VAR_DECL
2382 && !DECL_SEEN_IN_BIND_EXPR_P (decl)
2383 && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl)
2384 && decl_function_context (decl) == current_function_decl)
2386 gcc_assert (seen_error ());
2387 return GS_ERROR;
2390 /* When within an OMP context, notice uses of variables. */
2391 if (gimplify_omp_ctxp && omp_notice_variable (gimplify_omp_ctxp, decl, true))
2392 return GS_ALL_DONE;
2394 /* If the decl is an alias for another expression, substitute it now. */
2395 if (DECL_HAS_VALUE_EXPR_P (decl))
2397 tree value_expr = DECL_VALUE_EXPR (decl);
2399 /* For referenced nonlocal VLAs add a decl for debugging purposes
2400 to the current function. */
2401 if (TREE_CODE (decl) == VAR_DECL
2402 && TREE_CODE (DECL_SIZE_UNIT (decl)) != INTEGER_CST
2403 && nonlocal_vlas != NULL
2404 && TREE_CODE (value_expr) == INDIRECT_REF
2405 && TREE_CODE (TREE_OPERAND (value_expr, 0)) == VAR_DECL
2406 && decl_function_context (decl) != current_function_decl)
2408 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
2409 while (ctx
2410 && (ctx->region_type == ORT_WORKSHARE
2411 || ctx->region_type == ORT_SIMD
2412 || ctx->region_type == ORT_ACC))
2413 ctx = ctx->outer_context;
2414 if (!ctx && !nonlocal_vlas->add (decl))
2416 tree copy = copy_node (decl);
2418 lang_hooks.dup_lang_specific_decl (copy);
2419 SET_DECL_RTL (copy, 0);
2420 TREE_USED (copy) = 1;
2421 DECL_CHAIN (copy) = nonlocal_vla_vars;
2422 nonlocal_vla_vars = copy;
2423 SET_DECL_VALUE_EXPR (copy, unshare_expr (value_expr));
2424 DECL_HAS_VALUE_EXPR_P (copy) = 1;
2428 *expr_p = unshare_expr (value_expr);
2429 return GS_OK;
2432 return GS_ALL_DONE;
2435 /* Recalculate the value of the TREE_SIDE_EFFECTS flag for T. */
2437 static void
2438 recalculate_side_effects (tree t)
2440 enum tree_code code = TREE_CODE (t);
2441 int len = TREE_OPERAND_LENGTH (t);
2442 int i;
2444 switch (TREE_CODE_CLASS (code))
2446 case tcc_expression:
2447 switch (code)
2449 case INIT_EXPR:
2450 case MODIFY_EXPR:
2451 case VA_ARG_EXPR:
2452 case PREDECREMENT_EXPR:
2453 case PREINCREMENT_EXPR:
2454 case POSTDECREMENT_EXPR:
2455 case POSTINCREMENT_EXPR:
2456 /* All of these have side-effects, no matter what their
2457 operands are. */
2458 return;
2460 default:
2461 break;
2463 /* Fall through. */
2465 case tcc_comparison: /* a comparison expression */
2466 case tcc_unary: /* a unary arithmetic expression */
2467 case tcc_binary: /* a binary arithmetic expression */
2468 case tcc_reference: /* a reference */
2469 case tcc_vl_exp: /* a function call */
2470 TREE_SIDE_EFFECTS (t) = TREE_THIS_VOLATILE (t);
2471 for (i = 0; i < len; ++i)
2473 tree op = TREE_OPERAND (t, i);
2474 if (op && TREE_SIDE_EFFECTS (op))
2475 TREE_SIDE_EFFECTS (t) = 1;
2477 break;
2479 case tcc_constant:
2480 /* No side-effects. */
2481 return;
2483 default:
2484 gcc_unreachable ();
2488 /* Gimplify the COMPONENT_REF, ARRAY_REF, REALPART_EXPR or IMAGPART_EXPR
2489 node *EXPR_P.
2491 compound_lval
2492 : min_lval '[' val ']'
2493 | min_lval '.' ID
2494 | compound_lval '[' val ']'
2495 | compound_lval '.' ID
2497 This is not part of the original SIMPLE definition, which separates
2498 array and member references, but it seems reasonable to handle them
2499 together. Also, this way we don't run into problems with union
2500 aliasing; gcc requires that for accesses through a union to alias, the
2501 union reference must be explicit, which was not always the case when we
2502 were splitting up array and member refs.
2504 PRE_P points to the sequence where side effects that must happen before
2505 *EXPR_P should be stored.
2507 POST_P points to the sequence where side effects that must happen after
2508 *EXPR_P should be stored. */
2510 static enum gimplify_status
2511 gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
2512 fallback_t fallback)
2514 tree *p;
2515 enum gimplify_status ret = GS_ALL_DONE, tret;
2516 int i;
2517 location_t loc = EXPR_LOCATION (*expr_p);
2518 tree expr = *expr_p;
2520 /* Create a stack of the subexpressions so later we can walk them in
2521 order from inner to outer. */
2522 auto_vec<tree, 10> expr_stack;
2524 /* We can handle anything that get_inner_reference can deal with. */
2525 for (p = expr_p; ; p = &TREE_OPERAND (*p, 0))
2527 restart:
2528 /* Fold INDIRECT_REFs now to turn them into ARRAY_REFs. */
2529 if (TREE_CODE (*p) == INDIRECT_REF)
2530 *p = fold_indirect_ref_loc (loc, *p);
2532 if (handled_component_p (*p))
2534 /* Expand DECL_VALUE_EXPR now. In some cases that may expose
2535 additional COMPONENT_REFs. */
2536 else if ((TREE_CODE (*p) == VAR_DECL || TREE_CODE (*p) == PARM_DECL)
2537 && gimplify_var_or_parm_decl (p) == GS_OK)
2538 goto restart;
2539 else
2540 break;
2542 expr_stack.safe_push (*p);
2545 gcc_assert (expr_stack.length ());
2547 /* Now EXPR_STACK is a stack of pointers to all the refs we've
2548 walked through and P points to the innermost expression.
2550 Java requires that we elaborated nodes in source order. That
2551 means we must gimplify the inner expression followed by each of
2552 the indices, in order. But we can't gimplify the inner
2553 expression until we deal with any variable bounds, sizes, or
2554 positions in order to deal with PLACEHOLDER_EXPRs.
2556 So we do this in three steps. First we deal with the annotations
2557 for any variables in the components, then we gimplify the base,
2558 then we gimplify any indices, from left to right. */
2559 for (i = expr_stack.length () - 1; i >= 0; i--)
2561 tree t = expr_stack[i];
2563 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
2565 /* Gimplify the low bound and element type size and put them into
2566 the ARRAY_REF. If these values are set, they have already been
2567 gimplified. */
2568 if (TREE_OPERAND (t, 2) == NULL_TREE)
2570 tree low = unshare_expr (array_ref_low_bound (t));
2571 if (!is_gimple_min_invariant (low))
2573 TREE_OPERAND (t, 2) = low;
2574 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
2575 post_p, is_gimple_reg,
2576 fb_rvalue);
2577 ret = MIN (ret, tret);
2580 else
2582 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
2583 is_gimple_reg, fb_rvalue);
2584 ret = MIN (ret, tret);
2587 if (TREE_OPERAND (t, 3) == NULL_TREE)
2589 tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0)));
2590 tree elmt_size = unshare_expr (array_ref_element_size (t));
2591 tree factor = size_int (TYPE_ALIGN_UNIT (elmt_type));
2593 /* Divide the element size by the alignment of the element
2594 type (above). */
2595 elmt_size
2596 = size_binop_loc (loc, EXACT_DIV_EXPR, elmt_size, factor);
2598 if (!is_gimple_min_invariant (elmt_size))
2600 TREE_OPERAND (t, 3) = elmt_size;
2601 tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p,
2602 post_p, is_gimple_reg,
2603 fb_rvalue);
2604 ret = MIN (ret, tret);
2607 else
2609 tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p, post_p,
2610 is_gimple_reg, fb_rvalue);
2611 ret = MIN (ret, tret);
2614 else if (TREE_CODE (t) == COMPONENT_REF)
2616 /* Set the field offset into T and gimplify it. */
2617 if (TREE_OPERAND (t, 2) == NULL_TREE)
2619 tree offset = unshare_expr (component_ref_field_offset (t));
2620 tree field = TREE_OPERAND (t, 1);
2621 tree factor
2622 = size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT);
2624 /* Divide the offset by its alignment. */
2625 offset = size_binop_loc (loc, EXACT_DIV_EXPR, offset, factor);
2627 if (!is_gimple_min_invariant (offset))
2629 TREE_OPERAND (t, 2) = offset;
2630 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
2631 post_p, is_gimple_reg,
2632 fb_rvalue);
2633 ret = MIN (ret, tret);
2636 else
2638 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
2639 is_gimple_reg, fb_rvalue);
2640 ret = MIN (ret, tret);
2645 /* Step 2 is to gimplify the base expression. Make sure lvalue is set
2646 so as to match the min_lval predicate. Failure to do so may result
2647 in the creation of large aggregate temporaries. */
2648 tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval,
2649 fallback | fb_lvalue);
2650 ret = MIN (ret, tret);
2652 /* And finally, the indices and operands of ARRAY_REF. During this
2653 loop we also remove any useless conversions. */
2654 for (; expr_stack.length () > 0; )
2656 tree t = expr_stack.pop ();
2658 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
2660 /* Gimplify the dimension. */
2661 if (!is_gimple_min_invariant (TREE_OPERAND (t, 1)))
2663 tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
2664 is_gimple_val, fb_rvalue);
2665 ret = MIN (ret, tret);
2669 STRIP_USELESS_TYPE_CONVERSION (TREE_OPERAND (t, 0));
2671 /* The innermost expression P may have originally had
2672 TREE_SIDE_EFFECTS set which would have caused all the outer
2673 expressions in *EXPR_P leading to P to also have had
2674 TREE_SIDE_EFFECTS set. */
2675 recalculate_side_effects (t);
2678 /* If the outermost expression is a COMPONENT_REF, canonicalize its type. */
2679 if ((fallback & fb_rvalue) && TREE_CODE (*expr_p) == COMPONENT_REF)
2681 canonicalize_component_ref (expr_p);
2684 expr_stack.release ();
2686 gcc_assert (*expr_p == expr || ret != GS_ALL_DONE);
2688 return ret;
2691 /* Gimplify the self modifying expression pointed to by EXPR_P
2692 (++, --, +=, -=).
2694 PRE_P points to the list where side effects that must happen before
2695 *EXPR_P should be stored.
2697 POST_P points to the list where side effects that must happen after
2698 *EXPR_P should be stored.
2700 WANT_VALUE is nonzero iff we want to use the value of this expression
2701 in another expression.
2703 ARITH_TYPE is the type the computation should be performed in. */
2705 enum gimplify_status
2706 gimplify_self_mod_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
2707 bool want_value, tree arith_type)
2709 enum tree_code code;
2710 tree lhs, lvalue, rhs, t1;
2711 gimple_seq post = NULL, *orig_post_p = post_p;
2712 bool postfix;
2713 enum tree_code arith_code;
2714 enum gimplify_status ret;
2715 location_t loc = EXPR_LOCATION (*expr_p);
2717 code = TREE_CODE (*expr_p);
2719 gcc_assert (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR
2720 || code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR);
2722 /* Prefix or postfix? */
2723 if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
2724 /* Faster to treat as prefix if result is not used. */
2725 postfix = want_value;
2726 else
2727 postfix = false;
2729 /* For postfix, make sure the inner expression's post side effects
2730 are executed after side effects from this expression. */
2731 if (postfix)
2732 post_p = &post;
2734 /* Add or subtract? */
2735 if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
2736 arith_code = PLUS_EXPR;
2737 else
2738 arith_code = MINUS_EXPR;
2740 /* Gimplify the LHS into a GIMPLE lvalue. */
2741 lvalue = TREE_OPERAND (*expr_p, 0);
2742 ret = gimplify_expr (&lvalue, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
2743 if (ret == GS_ERROR)
2744 return ret;
2746 /* Extract the operands to the arithmetic operation. */
2747 lhs = lvalue;
2748 rhs = TREE_OPERAND (*expr_p, 1);
2750 /* For postfix operator, we evaluate the LHS to an rvalue and then use
2751 that as the result value and in the postqueue operation. */
2752 if (postfix)
2754 ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue);
2755 if (ret == GS_ERROR)
2756 return ret;
2758 lhs = get_initialized_tmp_var (lhs, pre_p, NULL);
2761 /* For POINTERs increment, use POINTER_PLUS_EXPR. */
2762 if (POINTER_TYPE_P (TREE_TYPE (lhs)))
2764 rhs = convert_to_ptrofftype_loc (loc, rhs);
2765 if (arith_code == MINUS_EXPR)
2766 rhs = fold_build1_loc (loc, NEGATE_EXPR, TREE_TYPE (rhs), rhs);
2767 t1 = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (*expr_p), lhs, rhs);
2769 else
2770 t1 = fold_convert (TREE_TYPE (*expr_p),
2771 fold_build2 (arith_code, arith_type,
2772 fold_convert (arith_type, lhs),
2773 fold_convert (arith_type, rhs)));
2775 if (postfix)
2777 gimplify_assign (lvalue, t1, pre_p);
2778 gimplify_seq_add_seq (orig_post_p, post);
2779 *expr_p = lhs;
2780 return GS_ALL_DONE;
2782 else
2784 *expr_p = build2 (MODIFY_EXPR, TREE_TYPE (lvalue), lvalue, t1);
2785 return GS_OK;
2789 /* If *EXPR_P has a variable sized type, wrap it in a WITH_SIZE_EXPR. */
2791 static void
2792 maybe_with_size_expr (tree *expr_p)
2794 tree expr = *expr_p;
2795 tree type = TREE_TYPE (expr);
2796 tree size;
2798 /* If we've already wrapped this or the type is error_mark_node, we can't do
2799 anything. */
2800 if (TREE_CODE (expr) == WITH_SIZE_EXPR
2801 || type == error_mark_node)
2802 return;
2804 /* If the size isn't known or is a constant, we have nothing to do. */
2805 size = TYPE_SIZE_UNIT (type);
2806 if (!size || TREE_CODE (size) == INTEGER_CST)
2807 return;
2809 /* Otherwise, make a WITH_SIZE_EXPR. */
2810 size = unshare_expr (size);
2811 size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, expr);
2812 *expr_p = build2 (WITH_SIZE_EXPR, type, expr, size);
2815 /* Helper for gimplify_call_expr. Gimplify a single argument *ARG_P
2816 Store any side-effects in PRE_P. CALL_LOCATION is the location of
2817 the CALL_EXPR. If ALLOW_SSA is set the actual parameter may be
2818 gimplified to an SSA name. */
2820 enum gimplify_status
2821 gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location,
2822 bool allow_ssa)
2824 bool (*test) (tree);
2825 fallback_t fb;
2827 /* In general, we allow lvalues for function arguments to avoid
2828 extra overhead of copying large aggregates out of even larger
2829 aggregates into temporaries only to copy the temporaries to
2830 the argument list. Make optimizers happy by pulling out to
2831 temporaries those types that fit in registers. */
2832 if (is_gimple_reg_type (TREE_TYPE (*arg_p)))
2833 test = is_gimple_val, fb = fb_rvalue;
2834 else
2836 test = is_gimple_lvalue, fb = fb_either;
2837 /* Also strip a TARGET_EXPR that would force an extra copy. */
2838 if (TREE_CODE (*arg_p) == TARGET_EXPR)
2840 tree init = TARGET_EXPR_INITIAL (*arg_p);
2841 if (init
2842 && !VOID_TYPE_P (TREE_TYPE (init)))
2843 *arg_p = init;
2847 /* If this is a variable sized type, we must remember the size. */
2848 maybe_with_size_expr (arg_p);
2850 /* FIXME diagnostics: This will mess up gcc.dg/Warray-bounds.c. */
2851 /* Make sure arguments have the same location as the function call
2852 itself. */
2853 protected_set_expr_location (*arg_p, call_location);
2855 /* There is a sequence point before a function call. Side effects in
2856 the argument list must occur before the actual call. So, when
2857 gimplifying arguments, force gimplify_expr to use an internal
2858 post queue which is then appended to the end of PRE_P. */
2859 return gimplify_expr (arg_p, pre_p, NULL, test, fb, allow_ssa);
2862 /* Don't fold inside offloading or taskreg regions: it can break code by
2863 adding decl references that weren't in the source. We'll do it during
2864 omplower pass instead. */
2866 static bool
2867 maybe_fold_stmt (gimple_stmt_iterator *gsi)
2869 struct gimplify_omp_ctx *ctx;
2870 for (ctx = gimplify_omp_ctxp; ctx; ctx = ctx->outer_context)
2871 if ((ctx->region_type & (ORT_TARGET | ORT_PARALLEL | ORT_TASK)) != 0)
2872 return false;
2873 return fold_stmt (gsi);
2876 /* Gimplify the CALL_EXPR node *EXPR_P into the GIMPLE sequence PRE_P.
2877 WANT_VALUE is true if the result of the call is desired. */
2879 static enum gimplify_status
2880 gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
2882 tree fndecl, parms, p, fnptrtype;
2883 enum gimplify_status ret;
2884 int i, nargs;
2885 gcall *call;
2886 bool builtin_va_start_p = false;
2887 location_t loc = EXPR_LOCATION (*expr_p);
2889 gcc_assert (TREE_CODE (*expr_p) == CALL_EXPR);
2891 /* For reliable diagnostics during inlining, it is necessary that
2892 every call_expr be annotated with file and line. */
2893 if (! EXPR_HAS_LOCATION (*expr_p))
2894 SET_EXPR_LOCATION (*expr_p, input_location);
2896 /* Gimplify internal functions created in the FEs. */
2897 if (CALL_EXPR_FN (*expr_p) == NULL_TREE)
2899 if (want_value)
2900 return GS_ALL_DONE;
2902 nargs = call_expr_nargs (*expr_p);
2903 enum internal_fn ifn = CALL_EXPR_IFN (*expr_p);
2904 auto_vec<tree> vargs (nargs);
2906 for (i = 0; i < nargs; i++)
2908 gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
2909 EXPR_LOCATION (*expr_p));
2910 vargs.quick_push (CALL_EXPR_ARG (*expr_p, i));
2912 gimple *call = gimple_build_call_internal_vec (ifn, vargs);
2913 gimplify_seq_add_stmt (pre_p, call);
2914 return GS_ALL_DONE;
2917 /* This may be a call to a builtin function.
2919 Builtin function calls may be transformed into different
2920 (and more efficient) builtin function calls under certain
2921 circumstances. Unfortunately, gimplification can muck things
2922 up enough that the builtin expanders are not aware that certain
2923 transformations are still valid.
2925 So we attempt transformation/gimplification of the call before
2926 we gimplify the CALL_EXPR. At this time we do not manage to
2927 transform all calls in the same manner as the expanders do, but
2928 we do transform most of them. */
2929 fndecl = get_callee_fndecl (*expr_p);
2930 if (fndecl
2931 && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
2932 switch (DECL_FUNCTION_CODE (fndecl))
2934 case BUILT_IN_ALLOCA:
2935 case BUILT_IN_ALLOCA_WITH_ALIGN:
2936 /* If the call has been built for a variable-sized object, then we
2937 want to restore the stack level when the enclosing BIND_EXPR is
2938 exited to reclaim the allocated space; otherwise, we precisely
2939 need to do the opposite and preserve the latest stack level. */
2940 if (CALL_ALLOCA_FOR_VAR_P (*expr_p))
2941 gimplify_ctxp->save_stack = true;
2942 else
2943 gimplify_ctxp->keep_stack = true;
2944 break;
2946 case BUILT_IN_VA_START:
2948 builtin_va_start_p = TRUE;
2949 if (call_expr_nargs (*expr_p) < 2)
2951 error ("too few arguments to function %<va_start%>");
2952 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
2953 return GS_OK;
2956 if (fold_builtin_next_arg (*expr_p, true))
2958 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
2959 return GS_OK;
2961 break;
2964 default:
2967 if (fndecl && DECL_BUILT_IN (fndecl))
2969 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
2970 if (new_tree && new_tree != *expr_p)
2972 /* There was a transformation of this call which computes the
2973 same value, but in a more efficient way. Return and try
2974 again. */
2975 *expr_p = new_tree;
2976 return GS_OK;
2980 /* Remember the original function pointer type. */
2981 fnptrtype = TREE_TYPE (CALL_EXPR_FN (*expr_p));
2983 /* There is a sequence point before the call, so any side effects in
2984 the calling expression must occur before the actual call. Force
2985 gimplify_expr to use an internal post queue. */
2986 ret = gimplify_expr (&CALL_EXPR_FN (*expr_p), pre_p, NULL,
2987 is_gimple_call_addr, fb_rvalue);
2989 nargs = call_expr_nargs (*expr_p);
2991 /* Get argument types for verification. */
2992 fndecl = get_callee_fndecl (*expr_p);
2993 parms = NULL_TREE;
2994 if (fndecl)
2995 parms = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
2996 else
2997 parms = TYPE_ARG_TYPES (TREE_TYPE (fnptrtype));
2999 if (fndecl && DECL_ARGUMENTS (fndecl))
3000 p = DECL_ARGUMENTS (fndecl);
3001 else if (parms)
3002 p = parms;
3003 else
3004 p = NULL_TREE;
3005 for (i = 0; i < nargs && p; i++, p = TREE_CHAIN (p))
3008 /* If the last argument is __builtin_va_arg_pack () and it is not
3009 passed as a named argument, decrease the number of CALL_EXPR
3010 arguments and set instead the CALL_EXPR_VA_ARG_PACK flag. */
3011 if (!p
3012 && i < nargs
3013 && TREE_CODE (CALL_EXPR_ARG (*expr_p, nargs - 1)) == CALL_EXPR)
3015 tree last_arg = CALL_EXPR_ARG (*expr_p, nargs - 1);
3016 tree last_arg_fndecl = get_callee_fndecl (last_arg);
3018 if (last_arg_fndecl
3019 && TREE_CODE (last_arg_fndecl) == FUNCTION_DECL
3020 && DECL_BUILT_IN_CLASS (last_arg_fndecl) == BUILT_IN_NORMAL
3021 && DECL_FUNCTION_CODE (last_arg_fndecl) == BUILT_IN_VA_ARG_PACK)
3023 tree call = *expr_p;
3025 --nargs;
3026 *expr_p = build_call_array_loc (loc, TREE_TYPE (call),
3027 CALL_EXPR_FN (call),
3028 nargs, CALL_EXPR_ARGP (call));
3030 /* Copy all CALL_EXPR flags, location and block, except
3031 CALL_EXPR_VA_ARG_PACK flag. */
3032 CALL_EXPR_STATIC_CHAIN (*expr_p) = CALL_EXPR_STATIC_CHAIN (call);
3033 CALL_EXPR_TAILCALL (*expr_p) = CALL_EXPR_TAILCALL (call);
3034 CALL_EXPR_RETURN_SLOT_OPT (*expr_p)
3035 = CALL_EXPR_RETURN_SLOT_OPT (call);
3036 CALL_FROM_THUNK_P (*expr_p) = CALL_FROM_THUNK_P (call);
3037 SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (call));
3039 /* Set CALL_EXPR_VA_ARG_PACK. */
3040 CALL_EXPR_VA_ARG_PACK (*expr_p) = 1;
3044 /* If the call returns twice then after building the CFG the call
3045 argument computations will no longer dominate the call because
3046 we add an abnormal incoming edge to the call. So do not use SSA
3047 vars there. */
3048 bool returns_twice = call_expr_flags (*expr_p) & ECF_RETURNS_TWICE;
3050 /* Gimplify the function arguments. */
3051 if (nargs > 0)
3053 for (i = (PUSH_ARGS_REVERSED ? nargs - 1 : 0);
3054 PUSH_ARGS_REVERSED ? i >= 0 : i < nargs;
3055 PUSH_ARGS_REVERSED ? i-- : i++)
3057 enum gimplify_status t;
3059 /* Avoid gimplifying the second argument to va_start, which needs to
3060 be the plain PARM_DECL. */
3061 if ((i != 1) || !builtin_va_start_p)
3063 t = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
3064 EXPR_LOCATION (*expr_p), ! returns_twice);
3066 if (t == GS_ERROR)
3067 ret = GS_ERROR;
3072 /* Gimplify the static chain. */
3073 if (CALL_EXPR_STATIC_CHAIN (*expr_p))
3075 if (fndecl && !DECL_STATIC_CHAIN (fndecl))
3076 CALL_EXPR_STATIC_CHAIN (*expr_p) = NULL;
3077 else
3079 enum gimplify_status t;
3080 t = gimplify_arg (&CALL_EXPR_STATIC_CHAIN (*expr_p), pre_p,
3081 EXPR_LOCATION (*expr_p), ! returns_twice);
3082 if (t == GS_ERROR)
3083 ret = GS_ERROR;
3087 /* Verify the function result. */
3088 if (want_value && fndecl
3089 && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fnptrtype))))
3091 error_at (loc, "using result of function returning %<void%>");
3092 ret = GS_ERROR;
3095 /* Try this again in case gimplification exposed something. */
3096 if (ret != GS_ERROR)
3098 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
3100 if (new_tree && new_tree != *expr_p)
3102 /* There was a transformation of this call which computes the
3103 same value, but in a more efficient way. Return and try
3104 again. */
3105 *expr_p = new_tree;
3106 return GS_OK;
3109 else
3111 *expr_p = error_mark_node;
3112 return GS_ERROR;
3115 /* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its
3116 decl. This allows us to eliminate redundant or useless
3117 calls to "const" functions. */
3118 if (TREE_CODE (*expr_p) == CALL_EXPR)
3120 int flags = call_expr_flags (*expr_p);
3121 if (flags & (ECF_CONST | ECF_PURE)
3122 /* An infinite loop is considered a side effect. */
3123 && !(flags & (ECF_LOOPING_CONST_OR_PURE)))
3124 TREE_SIDE_EFFECTS (*expr_p) = 0;
3127 /* If the value is not needed by the caller, emit a new GIMPLE_CALL
3128 and clear *EXPR_P. Otherwise, leave *EXPR_P in its gimplified
3129 form and delegate the creation of a GIMPLE_CALL to
3130 gimplify_modify_expr. This is always possible because when
3131 WANT_VALUE is true, the caller wants the result of this call into
3132 a temporary, which means that we will emit an INIT_EXPR in
3133 internal_get_tmp_var which will then be handled by
3134 gimplify_modify_expr. */
3135 if (!want_value)
3137 /* The CALL_EXPR in *EXPR_P is already in GIMPLE form, so all we
3138 have to do is replicate it as a GIMPLE_CALL tuple. */
3139 gimple_stmt_iterator gsi;
3140 call = gimple_build_call_from_tree (*expr_p);
3141 gimple_call_set_fntype (call, TREE_TYPE (fnptrtype));
3142 notice_special_calls (call);
3143 gimplify_seq_add_stmt (pre_p, call);
3144 gsi = gsi_last (*pre_p);
3145 maybe_fold_stmt (&gsi);
3146 *expr_p = NULL_TREE;
3148 else
3149 /* Remember the original function type. */
3150 CALL_EXPR_FN (*expr_p) = build1 (NOP_EXPR, fnptrtype,
3151 CALL_EXPR_FN (*expr_p));
3153 return ret;
3156 /* Handle shortcut semantics in the predicate operand of a COND_EXPR by
3157 rewriting it into multiple COND_EXPRs, and possibly GOTO_EXPRs.
3159 TRUE_LABEL_P and FALSE_LABEL_P point to the labels to jump to if the
3160 condition is true or false, respectively. If null, we should generate
3161 our own to skip over the evaluation of this specific expression.
3163 LOCUS is the source location of the COND_EXPR.
3165 This function is the tree equivalent of do_jump.
3167 shortcut_cond_r should only be called by shortcut_cond_expr. */
3169 static tree
3170 shortcut_cond_r (tree pred, tree *true_label_p, tree *false_label_p,
3171 location_t locus)
3173 tree local_label = NULL_TREE;
3174 tree t, expr = NULL;
3176 /* OK, it's not a simple case; we need to pull apart the COND_EXPR to
3177 retain the shortcut semantics. Just insert the gotos here;
3178 shortcut_cond_expr will append the real blocks later. */
3179 if (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
3181 location_t new_locus;
3183 /* Turn if (a && b) into
3185 if (a); else goto no;
3186 if (b) goto yes; else goto no;
3187 (no:) */
3189 if (false_label_p == NULL)
3190 false_label_p = &local_label;
3192 /* Keep the original source location on the first 'if'. */
3193 t = shortcut_cond_r (TREE_OPERAND (pred, 0), NULL, false_label_p, locus);
3194 append_to_statement_list (t, &expr);
3196 /* Set the source location of the && on the second 'if'. */
3197 new_locus = EXPR_HAS_LOCATION (pred) ? EXPR_LOCATION (pred) : locus;
3198 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
3199 new_locus);
3200 append_to_statement_list (t, &expr);
3202 else if (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
3204 location_t new_locus;
3206 /* Turn if (a || b) into
3208 if (a) goto yes;
3209 if (b) goto yes; else goto no;
3210 (yes:) */
3212 if (true_label_p == NULL)
3213 true_label_p = &local_label;
3215 /* Keep the original source location on the first 'if'. */
3216 t = shortcut_cond_r (TREE_OPERAND (pred, 0), true_label_p, NULL, locus);
3217 append_to_statement_list (t, &expr);
3219 /* Set the source location of the || on the second 'if'. */
3220 new_locus = EXPR_HAS_LOCATION (pred) ? EXPR_LOCATION (pred) : locus;
3221 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
3222 new_locus);
3223 append_to_statement_list (t, &expr);
3225 else if (TREE_CODE (pred) == COND_EXPR
3226 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 1)))
3227 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 2))))
3229 location_t new_locus;
3231 /* As long as we're messing with gotos, turn if (a ? b : c) into
3232 if (a)
3233 if (b) goto yes; else goto no;
3234 else
3235 if (c) goto yes; else goto no;
3237 Don't do this if one of the arms has void type, which can happen
3238 in C++ when the arm is throw. */
3240 /* Keep the original source location on the first 'if'. Set the source
3241 location of the ? on the second 'if'. */
3242 new_locus = EXPR_HAS_LOCATION (pred) ? EXPR_LOCATION (pred) : locus;
3243 expr = build3 (COND_EXPR, void_type_node, TREE_OPERAND (pred, 0),
3244 shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p,
3245 false_label_p, locus),
3246 shortcut_cond_r (TREE_OPERAND (pred, 2), true_label_p,
3247 false_label_p, new_locus));
3249 else
3251 expr = build3 (COND_EXPR, void_type_node, pred,
3252 build_and_jump (true_label_p),
3253 build_and_jump (false_label_p));
3254 SET_EXPR_LOCATION (expr, locus);
3257 if (local_label)
3259 t = build1 (LABEL_EXPR, void_type_node, local_label);
3260 append_to_statement_list (t, &expr);
3263 return expr;
3266 /* Given a conditional expression EXPR with short-circuit boolean
3267 predicates using TRUTH_ANDIF_EXPR or TRUTH_ORIF_EXPR, break the
3268 predicate apart into the equivalent sequence of conditionals. */
3270 static tree
3271 shortcut_cond_expr (tree expr)
3273 tree pred = TREE_OPERAND (expr, 0);
3274 tree then_ = TREE_OPERAND (expr, 1);
3275 tree else_ = TREE_OPERAND (expr, 2);
3276 tree true_label, false_label, end_label, t;
3277 tree *true_label_p;
3278 tree *false_label_p;
3279 bool emit_end, emit_false, jump_over_else;
3280 bool then_se = then_ && TREE_SIDE_EFFECTS (then_);
3281 bool else_se = else_ && TREE_SIDE_EFFECTS (else_);
3283 /* First do simple transformations. */
3284 if (!else_se)
3286 /* If there is no 'else', turn
3287 if (a && b) then c
3288 into
3289 if (a) if (b) then c. */
3290 while (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
3292 /* Keep the original source location on the first 'if'. */
3293 location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
3294 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
3295 /* Set the source location of the && on the second 'if'. */
3296 if (EXPR_HAS_LOCATION (pred))
3297 SET_EXPR_LOCATION (expr, EXPR_LOCATION (pred));
3298 then_ = shortcut_cond_expr (expr);
3299 then_se = then_ && TREE_SIDE_EFFECTS (then_);
3300 pred = TREE_OPERAND (pred, 0);
3301 expr = build3 (COND_EXPR, void_type_node, pred, then_, NULL_TREE);
3302 SET_EXPR_LOCATION (expr, locus);
3306 if (!then_se)
3308 /* If there is no 'then', turn
3309 if (a || b); else d
3310 into
3311 if (a); else if (b); else d. */
3312 while (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
3314 /* Keep the original source location on the first 'if'. */
3315 location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
3316 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
3317 /* Set the source location of the || on the second 'if'. */
3318 if (EXPR_HAS_LOCATION (pred))
3319 SET_EXPR_LOCATION (expr, EXPR_LOCATION (pred));
3320 else_ = shortcut_cond_expr (expr);
3321 else_se = else_ && TREE_SIDE_EFFECTS (else_);
3322 pred = TREE_OPERAND (pred, 0);
3323 expr = build3 (COND_EXPR, void_type_node, pred, NULL_TREE, else_);
3324 SET_EXPR_LOCATION (expr, locus);
3328 /* If we're done, great. */
3329 if (TREE_CODE (pred) != TRUTH_ANDIF_EXPR
3330 && TREE_CODE (pred) != TRUTH_ORIF_EXPR)
3331 return expr;
3333 /* Otherwise we need to mess with gotos. Change
3334 if (a) c; else d;
3336 if (a); else goto no;
3337 c; goto end;
3338 no: d; end:
3339 and recursively gimplify the condition. */
3341 true_label = false_label = end_label = NULL_TREE;
3343 /* If our arms just jump somewhere, hijack those labels so we don't
3344 generate jumps to jumps. */
3346 if (then_
3347 && TREE_CODE (then_) == GOTO_EXPR
3348 && TREE_CODE (GOTO_DESTINATION (then_)) == LABEL_DECL)
3350 true_label = GOTO_DESTINATION (then_);
3351 then_ = NULL;
3352 then_se = false;
3355 if (else_
3356 && TREE_CODE (else_) == GOTO_EXPR
3357 && TREE_CODE (GOTO_DESTINATION (else_)) == LABEL_DECL)
3359 false_label = GOTO_DESTINATION (else_);
3360 else_ = NULL;
3361 else_se = false;
3364 /* If we aren't hijacking a label for the 'then' branch, it falls through. */
3365 if (true_label)
3366 true_label_p = &true_label;
3367 else
3368 true_label_p = NULL;
3370 /* The 'else' branch also needs a label if it contains interesting code. */
3371 if (false_label || else_se)
3372 false_label_p = &false_label;
3373 else
3374 false_label_p = NULL;
3376 /* If there was nothing else in our arms, just forward the label(s). */
3377 if (!then_se && !else_se)
3378 return shortcut_cond_r (pred, true_label_p, false_label_p,
3379 EXPR_LOC_OR_LOC (expr, input_location));
3381 /* If our last subexpression already has a terminal label, reuse it. */
3382 if (else_se)
3383 t = expr_last (else_);
3384 else if (then_se)
3385 t = expr_last (then_);
3386 else
3387 t = NULL;
3388 if (t && TREE_CODE (t) == LABEL_EXPR)
3389 end_label = LABEL_EXPR_LABEL (t);
3391 /* If we don't care about jumping to the 'else' branch, jump to the end
3392 if the condition is false. */
3393 if (!false_label_p)
3394 false_label_p = &end_label;
3396 /* We only want to emit these labels if we aren't hijacking them. */
3397 emit_end = (end_label == NULL_TREE);
3398 emit_false = (false_label == NULL_TREE);
3400 /* We only emit the jump over the else clause if we have to--if the
3401 then clause may fall through. Otherwise we can wind up with a
3402 useless jump and a useless label at the end of gimplified code,
3403 which will cause us to think that this conditional as a whole
3404 falls through even if it doesn't. If we then inline a function
3405 which ends with such a condition, that can cause us to issue an
3406 inappropriate warning about control reaching the end of a
3407 non-void function. */
3408 jump_over_else = block_may_fallthru (then_);
3410 pred = shortcut_cond_r (pred, true_label_p, false_label_p,
3411 EXPR_LOC_OR_LOC (expr, input_location));
3413 expr = NULL;
3414 append_to_statement_list (pred, &expr);
3416 append_to_statement_list (then_, &expr);
3417 if (else_se)
3419 if (jump_over_else)
3421 tree last = expr_last (expr);
3422 t = build_and_jump (&end_label);
3423 if (EXPR_HAS_LOCATION (last))
3424 SET_EXPR_LOCATION (t, EXPR_LOCATION (last));
3425 append_to_statement_list (t, &expr);
3427 if (emit_false)
3429 t = build1 (LABEL_EXPR, void_type_node, false_label);
3430 append_to_statement_list (t, &expr);
3432 append_to_statement_list (else_, &expr);
3434 if (emit_end && end_label)
3436 t = build1 (LABEL_EXPR, void_type_node, end_label);
3437 append_to_statement_list (t, &expr);
3440 return expr;
3443 /* EXPR is used in a boolean context; make sure it has BOOLEAN_TYPE. */
3445 tree
3446 gimple_boolify (tree expr)
3448 tree type = TREE_TYPE (expr);
3449 location_t loc = EXPR_LOCATION (expr);
3451 if (TREE_CODE (expr) == NE_EXPR
3452 && TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR
3453 && integer_zerop (TREE_OPERAND (expr, 1)))
3455 tree call = TREE_OPERAND (expr, 0);
3456 tree fn = get_callee_fndecl (call);
3458 /* For __builtin_expect ((long) (x), y) recurse into x as well
3459 if x is truth_value_p. */
3460 if (fn
3461 && DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL
3462 && DECL_FUNCTION_CODE (fn) == BUILT_IN_EXPECT
3463 && call_expr_nargs (call) == 2)
3465 tree arg = CALL_EXPR_ARG (call, 0);
3466 if (arg)
3468 if (TREE_CODE (arg) == NOP_EXPR
3469 && TREE_TYPE (arg) == TREE_TYPE (call))
3470 arg = TREE_OPERAND (arg, 0);
3471 if (truth_value_p (TREE_CODE (arg)))
3473 arg = gimple_boolify (arg);
3474 CALL_EXPR_ARG (call, 0)
3475 = fold_convert_loc (loc, TREE_TYPE (call), arg);
3481 switch (TREE_CODE (expr))
3483 case TRUTH_AND_EXPR:
3484 case TRUTH_OR_EXPR:
3485 case TRUTH_XOR_EXPR:
3486 case TRUTH_ANDIF_EXPR:
3487 case TRUTH_ORIF_EXPR:
3488 /* Also boolify the arguments of truth exprs. */
3489 TREE_OPERAND (expr, 1) = gimple_boolify (TREE_OPERAND (expr, 1));
3490 /* FALLTHRU */
3492 case TRUTH_NOT_EXPR:
3493 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
3495 /* These expressions always produce boolean results. */
3496 if (TREE_CODE (type) != BOOLEAN_TYPE)
3497 TREE_TYPE (expr) = boolean_type_node;
3498 return expr;
3500 case ANNOTATE_EXPR:
3501 switch ((enum annot_expr_kind) TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)))
3503 case annot_expr_ivdep_kind:
3504 case annot_expr_no_vector_kind:
3505 case annot_expr_vector_kind:
3506 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
3507 if (TREE_CODE (type) != BOOLEAN_TYPE)
3508 TREE_TYPE (expr) = boolean_type_node;
3509 return expr;
3510 default:
3511 gcc_unreachable ();
3514 default:
3515 if (COMPARISON_CLASS_P (expr))
3517 /* There expressions always prduce boolean results. */
3518 if (TREE_CODE (type) != BOOLEAN_TYPE)
3519 TREE_TYPE (expr) = boolean_type_node;
3520 return expr;
3522 /* Other expressions that get here must have boolean values, but
3523 might need to be converted to the appropriate mode. */
3524 if (TREE_CODE (type) == BOOLEAN_TYPE)
3525 return expr;
3526 return fold_convert_loc (loc, boolean_type_node, expr);
3530 /* Given a conditional expression *EXPR_P without side effects, gimplify
3531 its operands. New statements are inserted to PRE_P. */
3533 static enum gimplify_status
3534 gimplify_pure_cond_expr (tree *expr_p, gimple_seq *pre_p)
3536 tree expr = *expr_p, cond;
3537 enum gimplify_status ret, tret;
3538 enum tree_code code;
3540 cond = gimple_boolify (COND_EXPR_COND (expr));
3542 /* We need to handle && and || specially, as their gimplification
3543 creates pure cond_expr, thus leading to an infinite cycle otherwise. */
3544 code = TREE_CODE (cond);
3545 if (code == TRUTH_ANDIF_EXPR)
3546 TREE_SET_CODE (cond, TRUTH_AND_EXPR);
3547 else if (code == TRUTH_ORIF_EXPR)
3548 TREE_SET_CODE (cond, TRUTH_OR_EXPR);
3549 ret = gimplify_expr (&cond, pre_p, NULL, is_gimple_condexpr, fb_rvalue);
3550 COND_EXPR_COND (*expr_p) = cond;
3552 tret = gimplify_expr (&COND_EXPR_THEN (expr), pre_p, NULL,
3553 is_gimple_val, fb_rvalue);
3554 ret = MIN (ret, tret);
3555 tret = gimplify_expr (&COND_EXPR_ELSE (expr), pre_p, NULL,
3556 is_gimple_val, fb_rvalue);
3558 return MIN (ret, tret);
3561 /* Return true if evaluating EXPR could trap.
3562 EXPR is GENERIC, while tree_could_trap_p can be called
3563 only on GIMPLE. */
3565 static bool
3566 generic_expr_could_trap_p (tree expr)
3568 unsigned i, n;
3570 if (!expr || is_gimple_val (expr))
3571 return false;
3573 if (!EXPR_P (expr) || tree_could_trap_p (expr))
3574 return true;
3576 n = TREE_OPERAND_LENGTH (expr);
3577 for (i = 0; i < n; i++)
3578 if (generic_expr_could_trap_p (TREE_OPERAND (expr, i)))
3579 return true;
3581 return false;
3584 /* Convert the conditional expression pointed to by EXPR_P '(p) ? a : b;'
3585 into
3587 if (p) if (p)
3588 t1 = a; a;
3589 else or else
3590 t1 = b; b;
3593 The second form is used when *EXPR_P is of type void.
3595 PRE_P points to the list where side effects that must happen before
3596 *EXPR_P should be stored. */
3598 static enum gimplify_status
3599 gimplify_cond_expr (tree *expr_p, gimple_seq *pre_p, fallback_t fallback)
3601 tree expr = *expr_p;
3602 tree type = TREE_TYPE (expr);
3603 location_t loc = EXPR_LOCATION (expr);
3604 tree tmp, arm1, arm2;
3605 enum gimplify_status ret;
3606 tree label_true, label_false, label_cont;
3607 bool have_then_clause_p, have_else_clause_p;
3608 gcond *cond_stmt;
3609 enum tree_code pred_code;
3610 gimple_seq seq = NULL;
3612 /* If this COND_EXPR has a value, copy the values into a temporary within
3613 the arms. */
3614 if (!VOID_TYPE_P (type))
3616 tree then_ = TREE_OPERAND (expr, 1), else_ = TREE_OPERAND (expr, 2);
3617 tree result;
3619 /* If either an rvalue is ok or we do not require an lvalue, create the
3620 temporary. But we cannot do that if the type is addressable. */
3621 if (((fallback & fb_rvalue) || !(fallback & fb_lvalue))
3622 && !TREE_ADDRESSABLE (type))
3624 if (gimplify_ctxp->allow_rhs_cond_expr
3625 /* If either branch has side effects or could trap, it can't be
3626 evaluated unconditionally. */
3627 && !TREE_SIDE_EFFECTS (then_)
3628 && !generic_expr_could_trap_p (then_)
3629 && !TREE_SIDE_EFFECTS (else_)
3630 && !generic_expr_could_trap_p (else_))
3631 return gimplify_pure_cond_expr (expr_p, pre_p);
3633 tmp = create_tmp_var (type, "iftmp");
3634 result = tmp;
3637 /* Otherwise, only create and copy references to the values. */
3638 else
3640 type = build_pointer_type (type);
3642 if (!VOID_TYPE_P (TREE_TYPE (then_)))
3643 then_ = build_fold_addr_expr_loc (loc, then_);
3645 if (!VOID_TYPE_P (TREE_TYPE (else_)))
3646 else_ = build_fold_addr_expr_loc (loc, else_);
3648 expr
3649 = build3 (COND_EXPR, type, TREE_OPERAND (expr, 0), then_, else_);
3651 tmp = create_tmp_var (type, "iftmp");
3652 result = build_simple_mem_ref_loc (loc, tmp);
3655 /* Build the new then clause, `tmp = then_;'. But don't build the
3656 assignment if the value is void; in C++ it can be if it's a throw. */
3657 if (!VOID_TYPE_P (TREE_TYPE (then_)))
3658 TREE_OPERAND (expr, 1) = build2 (MODIFY_EXPR, type, tmp, then_);
3660 /* Similarly, build the new else clause, `tmp = else_;'. */
3661 if (!VOID_TYPE_P (TREE_TYPE (else_)))
3662 TREE_OPERAND (expr, 2) = build2 (MODIFY_EXPR, type, tmp, else_);
3664 TREE_TYPE (expr) = void_type_node;
3665 recalculate_side_effects (expr);
3667 /* Move the COND_EXPR to the prequeue. */
3668 gimplify_stmt (&expr, pre_p);
3670 *expr_p = result;
3671 return GS_ALL_DONE;
3674 /* Remove any COMPOUND_EXPR so the following cases will be caught. */
3675 STRIP_TYPE_NOPS (TREE_OPERAND (expr, 0));
3676 if (TREE_CODE (TREE_OPERAND (expr, 0)) == COMPOUND_EXPR)
3677 gimplify_compound_expr (&TREE_OPERAND (expr, 0), pre_p, true);
3679 /* Make sure the condition has BOOLEAN_TYPE. */
3680 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
3682 /* Break apart && and || conditions. */
3683 if (TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ANDIF_EXPR
3684 || TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ORIF_EXPR)
3686 expr = shortcut_cond_expr (expr);
3688 if (expr != *expr_p)
3690 *expr_p = expr;
3692 /* We can't rely on gimplify_expr to re-gimplify the expanded
3693 form properly, as cleanups might cause the target labels to be
3694 wrapped in a TRY_FINALLY_EXPR. To prevent that, we need to
3695 set up a conditional context. */
3696 gimple_push_condition ();
3697 gimplify_stmt (expr_p, &seq);
3698 gimple_pop_condition (pre_p);
3699 gimple_seq_add_seq (pre_p, seq);
3701 return GS_ALL_DONE;
3705 /* Now do the normal gimplification. */
3707 /* Gimplify condition. */
3708 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL, is_gimple_condexpr,
3709 fb_rvalue);
3710 if (ret == GS_ERROR)
3711 return GS_ERROR;
3712 gcc_assert (TREE_OPERAND (expr, 0) != NULL_TREE);
3714 gimple_push_condition ();
3716 have_then_clause_p = have_else_clause_p = false;
3717 if (TREE_OPERAND (expr, 1) != NULL
3718 && TREE_CODE (TREE_OPERAND (expr, 1)) == GOTO_EXPR
3719 && TREE_CODE (GOTO_DESTINATION (TREE_OPERAND (expr, 1))) == LABEL_DECL
3720 && (DECL_CONTEXT (GOTO_DESTINATION (TREE_OPERAND (expr, 1)))
3721 == current_function_decl)
3722 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
3723 have different locations, otherwise we end up with incorrect
3724 location information on the branches. */
3725 && (optimize
3726 || !EXPR_HAS_LOCATION (expr)
3727 || !EXPR_HAS_LOCATION (TREE_OPERAND (expr, 1))
3728 || EXPR_LOCATION (expr) == EXPR_LOCATION (TREE_OPERAND (expr, 1))))
3730 label_true = GOTO_DESTINATION (TREE_OPERAND (expr, 1));
3731 have_then_clause_p = true;
3733 else
3734 label_true = create_artificial_label (UNKNOWN_LOCATION);
3735 if (TREE_OPERAND (expr, 2) != NULL
3736 && TREE_CODE (TREE_OPERAND (expr, 2)) == GOTO_EXPR
3737 && TREE_CODE (GOTO_DESTINATION (TREE_OPERAND (expr, 2))) == LABEL_DECL
3738 && (DECL_CONTEXT (GOTO_DESTINATION (TREE_OPERAND (expr, 2)))
3739 == current_function_decl)
3740 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
3741 have different locations, otherwise we end up with incorrect
3742 location information on the branches. */
3743 && (optimize
3744 || !EXPR_HAS_LOCATION (expr)
3745 || !EXPR_HAS_LOCATION (TREE_OPERAND (expr, 2))
3746 || EXPR_LOCATION (expr) == EXPR_LOCATION (TREE_OPERAND (expr, 2))))
3748 label_false = GOTO_DESTINATION (TREE_OPERAND (expr, 2));
3749 have_else_clause_p = true;
3751 else
3752 label_false = create_artificial_label (UNKNOWN_LOCATION);
3754 gimple_cond_get_ops_from_tree (COND_EXPR_COND (expr), &pred_code, &arm1,
3755 &arm2);
3756 cond_stmt = gimple_build_cond (pred_code, arm1, arm2, label_true,
3757 label_false);
3758 gimple_set_no_warning (cond_stmt, TREE_NO_WARNING (COND_EXPR_COND (expr)));
3759 gimplify_seq_add_stmt (&seq, cond_stmt);
3760 gimple_stmt_iterator gsi = gsi_last (seq);
3761 maybe_fold_stmt (&gsi);
3763 label_cont = NULL_TREE;
3764 if (!have_then_clause_p)
3766 /* For if (...) {} else { code; } put label_true after
3767 the else block. */
3768 if (TREE_OPERAND (expr, 1) == NULL_TREE
3769 && !have_else_clause_p
3770 && TREE_OPERAND (expr, 2) != NULL_TREE)
3771 label_cont = label_true;
3772 else
3774 gimplify_seq_add_stmt (&seq, gimple_build_label (label_true));
3775 have_then_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 1), &seq);
3776 /* For if (...) { code; } else {} or
3777 if (...) { code; } else goto label; or
3778 if (...) { code; return; } else { ... }
3779 label_cont isn't needed. */
3780 if (!have_else_clause_p
3781 && TREE_OPERAND (expr, 2) != NULL_TREE
3782 && gimple_seq_may_fallthru (seq))
3784 gimple *g;
3785 label_cont = create_artificial_label (UNKNOWN_LOCATION);
3787 g = gimple_build_goto (label_cont);
3789 /* GIMPLE_COND's are very low level; they have embedded
3790 gotos. This particular embedded goto should not be marked
3791 with the location of the original COND_EXPR, as it would
3792 correspond to the COND_EXPR's condition, not the ELSE or the
3793 THEN arms. To avoid marking it with the wrong location, flag
3794 it as "no location". */
3795 gimple_set_do_not_emit_location (g);
3797 gimplify_seq_add_stmt (&seq, g);
3801 if (!have_else_clause_p)
3803 gimplify_seq_add_stmt (&seq, gimple_build_label (label_false));
3804 have_else_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 2), &seq);
3806 if (label_cont)
3807 gimplify_seq_add_stmt (&seq, gimple_build_label (label_cont));
3809 gimple_pop_condition (pre_p);
3810 gimple_seq_add_seq (pre_p, seq);
3812 if (ret == GS_ERROR)
3813 ; /* Do nothing. */
3814 else if (have_then_clause_p || have_else_clause_p)
3815 ret = GS_ALL_DONE;
3816 else
3818 /* Both arms are empty; replace the COND_EXPR with its predicate. */
3819 expr = TREE_OPERAND (expr, 0);
3820 gimplify_stmt (&expr, pre_p);
3823 *expr_p = NULL;
3824 return ret;
3827 /* Prepare the node pointed to by EXPR_P, an is_gimple_addressable expression,
3828 to be marked addressable.
3830 We cannot rely on such an expression being directly markable if a temporary
3831 has been created by the gimplification. In this case, we create another
3832 temporary and initialize it with a copy, which will become a store after we
3833 mark it addressable. This can happen if the front-end passed us something
3834 that it could not mark addressable yet, like a Fortran pass-by-reference
3835 parameter (int) floatvar. */
3837 static void
3838 prepare_gimple_addressable (tree *expr_p, gimple_seq *seq_p)
3840 while (handled_component_p (*expr_p))
3841 expr_p = &TREE_OPERAND (*expr_p, 0);
3842 if (is_gimple_reg (*expr_p))
3844 /* Do not allow an SSA name as the temporary. */
3845 tree var = get_initialized_tmp_var (*expr_p, seq_p, NULL, false);
3846 DECL_GIMPLE_REG_P (var) = 0;
3847 *expr_p = var;
3851 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
3852 a call to __builtin_memcpy. */
3854 static enum gimplify_status
3855 gimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value,
3856 gimple_seq *seq_p)
3858 tree t, to, to_ptr, from, from_ptr;
3859 gcall *gs;
3860 location_t loc = EXPR_LOCATION (*expr_p);
3862 to = TREE_OPERAND (*expr_p, 0);
3863 from = TREE_OPERAND (*expr_p, 1);
3865 /* Mark the RHS addressable. Beware that it may not be possible to do so
3866 directly if a temporary has been created by the gimplification. */
3867 prepare_gimple_addressable (&from, seq_p);
3869 mark_addressable (from);
3870 from_ptr = build_fold_addr_expr_loc (loc, from);
3871 gimplify_arg (&from_ptr, seq_p, loc);
3873 mark_addressable (to);
3874 to_ptr = build_fold_addr_expr_loc (loc, to);
3875 gimplify_arg (&to_ptr, seq_p, loc);
3877 t = builtin_decl_implicit (BUILT_IN_MEMCPY);
3879 gs = gimple_build_call (t, 3, to_ptr, from_ptr, size);
3881 if (want_value)
3883 /* tmp = memcpy() */
3884 t = create_tmp_var (TREE_TYPE (to_ptr));
3885 gimple_call_set_lhs (gs, t);
3886 gimplify_seq_add_stmt (seq_p, gs);
3888 *expr_p = build_simple_mem_ref (t);
3889 return GS_ALL_DONE;
3892 gimplify_seq_add_stmt (seq_p, gs);
3893 *expr_p = NULL;
3894 return GS_ALL_DONE;
3897 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
3898 a call to __builtin_memset. In this case we know that the RHS is
3899 a CONSTRUCTOR with an empty element list. */
3901 static enum gimplify_status
3902 gimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value,
3903 gimple_seq *seq_p)
3905 tree t, from, to, to_ptr;
3906 gcall *gs;
3907 location_t loc = EXPR_LOCATION (*expr_p);
3909 /* Assert our assumptions, to abort instead of producing wrong code
3910 silently if they are not met. Beware that the RHS CONSTRUCTOR might
3911 not be immediately exposed. */
3912 from = TREE_OPERAND (*expr_p, 1);
3913 if (TREE_CODE (from) == WITH_SIZE_EXPR)
3914 from = TREE_OPERAND (from, 0);
3916 gcc_assert (TREE_CODE (from) == CONSTRUCTOR
3917 && vec_safe_is_empty (CONSTRUCTOR_ELTS (from)));
3919 /* Now proceed. */
3920 to = TREE_OPERAND (*expr_p, 0);
3922 to_ptr = build_fold_addr_expr_loc (loc, to);
3923 gimplify_arg (&to_ptr, seq_p, loc);
3924 t = builtin_decl_implicit (BUILT_IN_MEMSET);
3926 gs = gimple_build_call (t, 3, to_ptr, integer_zero_node, size);
3928 if (want_value)
3930 /* tmp = memset() */
3931 t = create_tmp_var (TREE_TYPE (to_ptr));
3932 gimple_call_set_lhs (gs, t);
3933 gimplify_seq_add_stmt (seq_p, gs);
3935 *expr_p = build1 (INDIRECT_REF, TREE_TYPE (to), t);
3936 return GS_ALL_DONE;
3939 gimplify_seq_add_stmt (seq_p, gs);
3940 *expr_p = NULL;
3941 return GS_ALL_DONE;
3944 /* A subroutine of gimplify_init_ctor_preeval. Called via walk_tree,
3945 determine, cautiously, if a CONSTRUCTOR overlaps the lhs of an
3946 assignment. Return non-null if we detect a potential overlap. */
3948 struct gimplify_init_ctor_preeval_data
3950 /* The base decl of the lhs object. May be NULL, in which case we
3951 have to assume the lhs is indirect. */
3952 tree lhs_base_decl;
3954 /* The alias set of the lhs object. */
3955 alias_set_type lhs_alias_set;
3958 static tree
3959 gimplify_init_ctor_preeval_1 (tree *tp, int *walk_subtrees, void *xdata)
3961 struct gimplify_init_ctor_preeval_data *data
3962 = (struct gimplify_init_ctor_preeval_data *) xdata;
3963 tree t = *tp;
3965 /* If we find the base object, obviously we have overlap. */
3966 if (data->lhs_base_decl == t)
3967 return t;
3969 /* If the constructor component is indirect, determine if we have a
3970 potential overlap with the lhs. The only bits of information we
3971 have to go on at this point are addressability and alias sets. */
3972 if ((INDIRECT_REF_P (t)
3973 || TREE_CODE (t) == MEM_REF)
3974 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
3975 && alias_sets_conflict_p (data->lhs_alias_set, get_alias_set (t)))
3976 return t;
3978 /* If the constructor component is a call, determine if it can hide a
3979 potential overlap with the lhs through an INDIRECT_REF like above.
3980 ??? Ugh - this is completely broken. In fact this whole analysis
3981 doesn't look conservative. */
3982 if (TREE_CODE (t) == CALL_EXPR)
3984 tree type, fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (t)));
3986 for (type = TYPE_ARG_TYPES (fntype); type; type = TREE_CHAIN (type))
3987 if (POINTER_TYPE_P (TREE_VALUE (type))
3988 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
3989 && alias_sets_conflict_p (data->lhs_alias_set,
3990 get_alias_set
3991 (TREE_TYPE (TREE_VALUE (type)))))
3992 return t;
3995 if (IS_TYPE_OR_DECL_P (t))
3996 *walk_subtrees = 0;
3997 return NULL;
4000 /* A subroutine of gimplify_init_constructor. Pre-evaluate EXPR,
4001 force values that overlap with the lhs (as described by *DATA)
4002 into temporaries. */
4004 static void
4005 gimplify_init_ctor_preeval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
4006 struct gimplify_init_ctor_preeval_data *data)
4008 enum gimplify_status one;
4010 /* If the value is constant, then there's nothing to pre-evaluate. */
4011 if (TREE_CONSTANT (*expr_p))
4013 /* Ensure it does not have side effects, it might contain a reference to
4014 the object we're initializing. */
4015 gcc_assert (!TREE_SIDE_EFFECTS (*expr_p));
4016 return;
4019 /* If the type has non-trivial constructors, we can't pre-evaluate. */
4020 if (TREE_ADDRESSABLE (TREE_TYPE (*expr_p)))
4021 return;
4023 /* Recurse for nested constructors. */
4024 if (TREE_CODE (*expr_p) == CONSTRUCTOR)
4026 unsigned HOST_WIDE_INT ix;
4027 constructor_elt *ce;
4028 vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (*expr_p);
4030 FOR_EACH_VEC_SAFE_ELT (v, ix, ce)
4031 gimplify_init_ctor_preeval (&ce->value, pre_p, post_p, data);
4033 return;
4036 /* If this is a variable sized type, we must remember the size. */
4037 maybe_with_size_expr (expr_p);
4039 /* Gimplify the constructor element to something appropriate for the rhs
4040 of a MODIFY_EXPR. Given that we know the LHS is an aggregate, we know
4041 the gimplifier will consider this a store to memory. Doing this
4042 gimplification now means that we won't have to deal with complicated
4043 language-specific trees, nor trees like SAVE_EXPR that can induce
4044 exponential search behavior. */
4045 one = gimplify_expr (expr_p, pre_p, post_p, is_gimple_mem_rhs, fb_rvalue);
4046 if (one == GS_ERROR)
4048 *expr_p = NULL;
4049 return;
4052 /* If we gimplified to a bare decl, we can be sure that it doesn't overlap
4053 with the lhs, since "a = { .x=a }" doesn't make sense. This will
4054 always be true for all scalars, since is_gimple_mem_rhs insists on a
4055 temporary variable for them. */
4056 if (DECL_P (*expr_p))
4057 return;
4059 /* If this is of variable size, we have no choice but to assume it doesn't
4060 overlap since we can't make a temporary for it. */
4061 if (TREE_CODE (TYPE_SIZE (TREE_TYPE (*expr_p))) != INTEGER_CST)
4062 return;
4064 /* Otherwise, we must search for overlap ... */
4065 if (!walk_tree (expr_p, gimplify_init_ctor_preeval_1, data, NULL))
4066 return;
4068 /* ... and if found, force the value into a temporary. */
4069 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
4072 /* A subroutine of gimplify_init_ctor_eval. Create a loop for
4073 a RANGE_EXPR in a CONSTRUCTOR for an array.
4075 var = lower;
4076 loop_entry:
4077 object[var] = value;
4078 if (var == upper)
4079 goto loop_exit;
4080 var = var + 1;
4081 goto loop_entry;
4082 loop_exit:
4084 We increment var _after_ the loop exit check because we might otherwise
4085 fail if upper == TYPE_MAX_VALUE (type for upper).
4087 Note that we never have to deal with SAVE_EXPRs here, because this has
4088 already been taken care of for us, in gimplify_init_ctor_preeval(). */
4090 static void gimplify_init_ctor_eval (tree, vec<constructor_elt, va_gc> *,
4091 gimple_seq *, bool);
4093 static void
4094 gimplify_init_ctor_eval_range (tree object, tree lower, tree upper,
4095 tree value, tree array_elt_type,
4096 gimple_seq *pre_p, bool cleared)
4098 tree loop_entry_label, loop_exit_label, fall_thru_label;
4099 tree var, var_type, cref, tmp;
4101 loop_entry_label = create_artificial_label (UNKNOWN_LOCATION);
4102 loop_exit_label = create_artificial_label (UNKNOWN_LOCATION);
4103 fall_thru_label = create_artificial_label (UNKNOWN_LOCATION);
4105 /* Create and initialize the index variable. */
4106 var_type = TREE_TYPE (upper);
4107 var = create_tmp_var (var_type);
4108 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, lower));
4110 /* Add the loop entry label. */
4111 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_entry_label));
4113 /* Build the reference. */
4114 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
4115 var, NULL_TREE, NULL_TREE);
4117 /* If we are a constructor, just call gimplify_init_ctor_eval to do
4118 the store. Otherwise just assign value to the reference. */
4120 if (TREE_CODE (value) == CONSTRUCTOR)
4121 /* NB we might have to call ourself recursively through
4122 gimplify_init_ctor_eval if the value is a constructor. */
4123 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
4124 pre_p, cleared);
4125 else
4126 gimplify_seq_add_stmt (pre_p, gimple_build_assign (cref, value));
4128 /* We exit the loop when the index var is equal to the upper bound. */
4129 gimplify_seq_add_stmt (pre_p,
4130 gimple_build_cond (EQ_EXPR, var, upper,
4131 loop_exit_label, fall_thru_label));
4133 gimplify_seq_add_stmt (pre_p, gimple_build_label (fall_thru_label));
4135 /* Otherwise, increment the index var... */
4136 tmp = build2 (PLUS_EXPR, var_type, var,
4137 fold_convert (var_type, integer_one_node));
4138 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, tmp));
4140 /* ...and jump back to the loop entry. */
4141 gimplify_seq_add_stmt (pre_p, gimple_build_goto (loop_entry_label));
4143 /* Add the loop exit label. */
4144 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_exit_label));
4147 /* Return true if FDECL is accessing a field that is zero sized. */
4149 static bool
4150 zero_sized_field_decl (const_tree fdecl)
4152 if (TREE_CODE (fdecl) == FIELD_DECL && DECL_SIZE (fdecl)
4153 && integer_zerop (DECL_SIZE (fdecl)))
4154 return true;
4155 return false;
4158 /* Return true if TYPE is zero sized. */
4160 static bool
4161 zero_sized_type (const_tree type)
4163 if (AGGREGATE_TYPE_P (type) && TYPE_SIZE (type)
4164 && integer_zerop (TYPE_SIZE (type)))
4165 return true;
4166 return false;
4169 /* A subroutine of gimplify_init_constructor. Generate individual
4170 MODIFY_EXPRs for a CONSTRUCTOR. OBJECT is the LHS against which the
4171 assignments should happen. ELTS is the CONSTRUCTOR_ELTS of the
4172 CONSTRUCTOR. CLEARED is true if the entire LHS object has been
4173 zeroed first. */
4175 static void
4176 gimplify_init_ctor_eval (tree object, vec<constructor_elt, va_gc> *elts,
4177 gimple_seq *pre_p, bool cleared)
4179 tree array_elt_type = NULL;
4180 unsigned HOST_WIDE_INT ix;
4181 tree purpose, value;
4183 if (TREE_CODE (TREE_TYPE (object)) == ARRAY_TYPE)
4184 array_elt_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (object)));
4186 FOR_EACH_CONSTRUCTOR_ELT (elts, ix, purpose, value)
4188 tree cref;
4190 /* NULL values are created above for gimplification errors. */
4191 if (value == NULL)
4192 continue;
4194 if (cleared && initializer_zerop (value))
4195 continue;
4197 /* ??? Here's to hoping the front end fills in all of the indices,
4198 so we don't have to figure out what's missing ourselves. */
4199 gcc_assert (purpose);
4201 /* Skip zero-sized fields, unless value has side-effects. This can
4202 happen with calls to functions returning a zero-sized type, which
4203 we shouldn't discard. As a number of downstream passes don't
4204 expect sets of zero-sized fields, we rely on the gimplification of
4205 the MODIFY_EXPR we make below to drop the assignment statement. */
4206 if (! TREE_SIDE_EFFECTS (value) && zero_sized_field_decl (purpose))
4207 continue;
4209 /* If we have a RANGE_EXPR, we have to build a loop to assign the
4210 whole range. */
4211 if (TREE_CODE (purpose) == RANGE_EXPR)
4213 tree lower = TREE_OPERAND (purpose, 0);
4214 tree upper = TREE_OPERAND (purpose, 1);
4216 /* If the lower bound is equal to upper, just treat it as if
4217 upper was the index. */
4218 if (simple_cst_equal (lower, upper))
4219 purpose = upper;
4220 else
4222 gimplify_init_ctor_eval_range (object, lower, upper, value,
4223 array_elt_type, pre_p, cleared);
4224 continue;
4228 if (array_elt_type)
4230 /* Do not use bitsizetype for ARRAY_REF indices. */
4231 if (TYPE_DOMAIN (TREE_TYPE (object)))
4232 purpose
4233 = fold_convert (TREE_TYPE (TYPE_DOMAIN (TREE_TYPE (object))),
4234 purpose);
4235 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
4236 purpose, NULL_TREE, NULL_TREE);
4238 else
4240 gcc_assert (TREE_CODE (purpose) == FIELD_DECL);
4241 cref = build3 (COMPONENT_REF, TREE_TYPE (purpose),
4242 unshare_expr (object), purpose, NULL_TREE);
4245 if (TREE_CODE (value) == CONSTRUCTOR
4246 && TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE)
4247 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
4248 pre_p, cleared);
4249 else
4251 tree init = build2 (INIT_EXPR, TREE_TYPE (cref), cref, value);
4252 gimplify_and_add (init, pre_p);
4253 ggc_free (init);
4258 /* Return the appropriate RHS predicate for this LHS. */
4260 gimple_predicate
4261 rhs_predicate_for (tree lhs)
4263 if (is_gimple_reg (lhs))
4264 return is_gimple_reg_rhs_or_call;
4265 else
4266 return is_gimple_mem_rhs_or_call;
4269 /* Return the initial guess for an appropriate RHS predicate for this LHS,
4270 before the LHS has been gimplified. */
4272 static gimple_predicate
4273 initial_rhs_predicate_for (tree lhs)
4275 if (is_gimple_reg_type (TREE_TYPE (lhs)))
4276 return is_gimple_reg_rhs_or_call;
4277 else
4278 return is_gimple_mem_rhs_or_call;
4281 /* Gimplify a C99 compound literal expression. This just means adding
4282 the DECL_EXPR before the current statement and using its anonymous
4283 decl instead. */
4285 static enum gimplify_status
4286 gimplify_compound_literal_expr (tree *expr_p, gimple_seq *pre_p,
4287 bool (*gimple_test_f) (tree),
4288 fallback_t fallback)
4290 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (*expr_p);
4291 tree decl = DECL_EXPR_DECL (decl_s);
4292 tree init = DECL_INITIAL (decl);
4293 /* Mark the decl as addressable if the compound literal
4294 expression is addressable now, otherwise it is marked too late
4295 after we gimplify the initialization expression. */
4296 if (TREE_ADDRESSABLE (*expr_p))
4297 TREE_ADDRESSABLE (decl) = 1;
4298 /* Otherwise, if we don't need an lvalue and have a literal directly
4299 substitute it. Check if it matches the gimple predicate, as
4300 otherwise we'd generate a new temporary, and we can as well just
4301 use the decl we already have. */
4302 else if (!TREE_ADDRESSABLE (decl)
4303 && init
4304 && (fallback & fb_lvalue) == 0
4305 && gimple_test_f (init))
4307 *expr_p = init;
4308 return GS_OK;
4311 /* Preliminarily mark non-addressed complex variables as eligible
4312 for promotion to gimple registers. We'll transform their uses
4313 as we find them. */
4314 if ((TREE_CODE (TREE_TYPE (decl)) == COMPLEX_TYPE
4315 || TREE_CODE (TREE_TYPE (decl)) == VECTOR_TYPE)
4316 && !TREE_THIS_VOLATILE (decl)
4317 && !needs_to_live_in_memory (decl))
4318 DECL_GIMPLE_REG_P (decl) = 1;
4320 /* If the decl is not addressable, then it is being used in some
4321 expression or on the right hand side of a statement, and it can
4322 be put into a readonly data section. */
4323 if (!TREE_ADDRESSABLE (decl) && (fallback & fb_lvalue) == 0)
4324 TREE_READONLY (decl) = 1;
4326 /* This decl isn't mentioned in the enclosing block, so add it to the
4327 list of temps. FIXME it seems a bit of a kludge to say that
4328 anonymous artificial vars aren't pushed, but everything else is. */
4329 if (DECL_NAME (decl) == NULL_TREE && !DECL_SEEN_IN_BIND_EXPR_P (decl))
4330 gimple_add_tmp_var (decl);
4332 gimplify_and_add (decl_s, pre_p);
4333 *expr_p = decl;
4334 return GS_OK;
4337 /* Optimize embedded COMPOUND_LITERAL_EXPRs within a CONSTRUCTOR,
4338 return a new CONSTRUCTOR if something changed. */
4340 static tree
4341 optimize_compound_literals_in_ctor (tree orig_ctor)
4343 tree ctor = orig_ctor;
4344 vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ctor);
4345 unsigned int idx, num = vec_safe_length (elts);
4347 for (idx = 0; idx < num; idx++)
4349 tree value = (*elts)[idx].value;
4350 tree newval = value;
4351 if (TREE_CODE (value) == CONSTRUCTOR)
4352 newval = optimize_compound_literals_in_ctor (value);
4353 else if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR)
4355 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (value);
4356 tree decl = DECL_EXPR_DECL (decl_s);
4357 tree init = DECL_INITIAL (decl);
4359 if (!TREE_ADDRESSABLE (value)
4360 && !TREE_ADDRESSABLE (decl)
4361 && init
4362 && TREE_CODE (init) == CONSTRUCTOR)
4363 newval = optimize_compound_literals_in_ctor (init);
4365 if (newval == value)
4366 continue;
4368 if (ctor == orig_ctor)
4370 ctor = copy_node (orig_ctor);
4371 CONSTRUCTOR_ELTS (ctor) = vec_safe_copy (elts);
4372 elts = CONSTRUCTOR_ELTS (ctor);
4374 (*elts)[idx].value = newval;
4376 return ctor;
4379 /* A subroutine of gimplify_modify_expr. Break out elements of a
4380 CONSTRUCTOR used as an initializer into separate MODIFY_EXPRs.
4382 Note that we still need to clear any elements that don't have explicit
4383 initializers, so if not all elements are initialized we keep the
4384 original MODIFY_EXPR, we just remove all of the constructor elements.
4386 If NOTIFY_TEMP_CREATION is true, do not gimplify, just return
4387 GS_ERROR if we would have to create a temporary when gimplifying
4388 this constructor. Otherwise, return GS_OK.
4390 If NOTIFY_TEMP_CREATION is false, just do the gimplification. */
4392 static enum gimplify_status
4393 gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
4394 bool want_value, bool notify_temp_creation)
4396 tree object, ctor, type;
4397 enum gimplify_status ret;
4398 vec<constructor_elt, va_gc> *elts;
4400 gcc_assert (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == CONSTRUCTOR);
4402 if (!notify_temp_creation)
4404 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
4405 is_gimple_lvalue, fb_lvalue);
4406 if (ret == GS_ERROR)
4407 return ret;
4410 object = TREE_OPERAND (*expr_p, 0);
4411 ctor = TREE_OPERAND (*expr_p, 1) =
4412 optimize_compound_literals_in_ctor (TREE_OPERAND (*expr_p, 1));
4413 type = TREE_TYPE (ctor);
4414 elts = CONSTRUCTOR_ELTS (ctor);
4415 ret = GS_ALL_DONE;
4417 switch (TREE_CODE (type))
4419 case RECORD_TYPE:
4420 case UNION_TYPE:
4421 case QUAL_UNION_TYPE:
4422 case ARRAY_TYPE:
4424 struct gimplify_init_ctor_preeval_data preeval_data;
4425 HOST_WIDE_INT num_ctor_elements, num_nonzero_elements;
4426 bool cleared, complete_p, valid_const_initializer;
4428 /* Aggregate types must lower constructors to initialization of
4429 individual elements. The exception is that a CONSTRUCTOR node
4430 with no elements indicates zero-initialization of the whole. */
4431 if (vec_safe_is_empty (elts))
4433 if (notify_temp_creation)
4434 return GS_OK;
4435 break;
4438 /* Fetch information about the constructor to direct later processing.
4439 We might want to make static versions of it in various cases, and
4440 can only do so if it known to be a valid constant initializer. */
4441 valid_const_initializer
4442 = categorize_ctor_elements (ctor, &num_nonzero_elements,
4443 &num_ctor_elements, &complete_p);
4445 /* If a const aggregate variable is being initialized, then it
4446 should never be a lose to promote the variable to be static. */
4447 if (valid_const_initializer
4448 && num_nonzero_elements > 1
4449 && TREE_READONLY (object)
4450 && TREE_CODE (object) == VAR_DECL
4451 && (flag_merge_constants >= 2 || !TREE_ADDRESSABLE (object)))
4453 if (notify_temp_creation)
4454 return GS_ERROR;
4455 DECL_INITIAL (object) = ctor;
4456 TREE_STATIC (object) = 1;
4457 if (!DECL_NAME (object))
4458 DECL_NAME (object) = create_tmp_var_name ("C");
4459 walk_tree (&DECL_INITIAL (object), force_labels_r, NULL, NULL);
4461 /* ??? C++ doesn't automatically append a .<number> to the
4462 assembler name, and even when it does, it looks at FE private
4463 data structures to figure out what that number should be,
4464 which are not set for this variable. I suppose this is
4465 important for local statics for inline functions, which aren't
4466 "local" in the object file sense. So in order to get a unique
4467 TU-local symbol, we must invoke the lhd version now. */
4468 lhd_set_decl_assembler_name (object);
4470 *expr_p = NULL_TREE;
4471 break;
4474 /* If there are "lots" of initialized elements, even discounting
4475 those that are not address constants (and thus *must* be
4476 computed at runtime), then partition the constructor into
4477 constant and non-constant parts. Block copy the constant
4478 parts in, then generate code for the non-constant parts. */
4479 /* TODO. There's code in cp/typeck.c to do this. */
4481 if (int_size_in_bytes (TREE_TYPE (ctor)) < 0)
4482 /* store_constructor will ignore the clearing of variable-sized
4483 objects. Initializers for such objects must explicitly set
4484 every field that needs to be set. */
4485 cleared = false;
4486 else if (!complete_p && !CONSTRUCTOR_NO_CLEARING (ctor))
4487 /* If the constructor isn't complete, clear the whole object
4488 beforehand, unless CONSTRUCTOR_NO_CLEARING is set on it.
4490 ??? This ought not to be needed. For any element not present
4491 in the initializer, we should simply set them to zero. Except
4492 we'd need to *find* the elements that are not present, and that
4493 requires trickery to avoid quadratic compile-time behavior in
4494 large cases or excessive memory use in small cases. */
4495 cleared = true;
4496 else if (num_ctor_elements - num_nonzero_elements
4497 > CLEAR_RATIO (optimize_function_for_speed_p (cfun))
4498 && num_nonzero_elements < num_ctor_elements / 4)
4499 /* If there are "lots" of zeros, it's more efficient to clear
4500 the memory and then set the nonzero elements. */
4501 cleared = true;
4502 else
4503 cleared = false;
4505 /* If there are "lots" of initialized elements, and all of them
4506 are valid address constants, then the entire initializer can
4507 be dropped to memory, and then memcpy'd out. Don't do this
4508 for sparse arrays, though, as it's more efficient to follow
4509 the standard CONSTRUCTOR behavior of memset followed by
4510 individual element initialization. Also don't do this for small
4511 all-zero initializers (which aren't big enough to merit
4512 clearing), and don't try to make bitwise copies of
4513 TREE_ADDRESSABLE types.
4515 We cannot apply such transformation when compiling chkp static
4516 initializer because creation of initializer image in the memory
4517 will require static initialization of bounds for it. It should
4518 result in another gimplification of similar initializer and we
4519 may fall into infinite loop. */
4520 if (valid_const_initializer
4521 && !(cleared || num_nonzero_elements == 0)
4522 && !TREE_ADDRESSABLE (type)
4523 && (!current_function_decl
4524 || !lookup_attribute ("chkp ctor",
4525 DECL_ATTRIBUTES (current_function_decl))))
4527 HOST_WIDE_INT size = int_size_in_bytes (type);
4528 unsigned int align;
4530 /* ??? We can still get unbounded array types, at least
4531 from the C++ front end. This seems wrong, but attempt
4532 to work around it for now. */
4533 if (size < 0)
4535 size = int_size_in_bytes (TREE_TYPE (object));
4536 if (size >= 0)
4537 TREE_TYPE (ctor) = type = TREE_TYPE (object);
4540 /* Find the maximum alignment we can assume for the object. */
4541 /* ??? Make use of DECL_OFFSET_ALIGN. */
4542 if (DECL_P (object))
4543 align = DECL_ALIGN (object);
4544 else
4545 align = TYPE_ALIGN (type);
4547 /* Do a block move either if the size is so small as to make
4548 each individual move a sub-unit move on average, or if it
4549 is so large as to make individual moves inefficient. */
4550 if (size > 0
4551 && num_nonzero_elements > 1
4552 && (size < num_nonzero_elements
4553 || !can_move_by_pieces (size, align)))
4555 if (notify_temp_creation)
4556 return GS_ERROR;
4558 walk_tree (&ctor, force_labels_r, NULL, NULL);
4559 ctor = tree_output_constant_def (ctor);
4560 if (!useless_type_conversion_p (type, TREE_TYPE (ctor)))
4561 ctor = build1 (VIEW_CONVERT_EXPR, type, ctor);
4562 TREE_OPERAND (*expr_p, 1) = ctor;
4564 /* This is no longer an assignment of a CONSTRUCTOR, but
4565 we still may have processing to do on the LHS. So
4566 pretend we didn't do anything here to let that happen. */
4567 return GS_UNHANDLED;
4571 /* If the target is volatile, we have non-zero elements and more than
4572 one field to assign, initialize the target from a temporary. */
4573 if (TREE_THIS_VOLATILE (object)
4574 && !TREE_ADDRESSABLE (type)
4575 && num_nonzero_elements > 0
4576 && vec_safe_length (elts) > 1)
4578 tree temp = create_tmp_var (TYPE_MAIN_VARIANT (type));
4579 TREE_OPERAND (*expr_p, 0) = temp;
4580 *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p),
4581 *expr_p,
4582 build2 (MODIFY_EXPR, void_type_node,
4583 object, temp));
4584 return GS_OK;
4587 if (notify_temp_creation)
4588 return GS_OK;
4590 /* If there are nonzero elements and if needed, pre-evaluate to capture
4591 elements overlapping with the lhs into temporaries. We must do this
4592 before clearing to fetch the values before they are zeroed-out. */
4593 if (num_nonzero_elements > 0 && TREE_CODE (*expr_p) != INIT_EXPR)
4595 preeval_data.lhs_base_decl = get_base_address (object);
4596 if (!DECL_P (preeval_data.lhs_base_decl))
4597 preeval_data.lhs_base_decl = NULL;
4598 preeval_data.lhs_alias_set = get_alias_set (object);
4600 gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p, 1),
4601 pre_p, post_p, &preeval_data);
4604 bool ctor_has_side_effects_p
4605 = TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p, 1));
4607 if (cleared)
4609 /* Zap the CONSTRUCTOR element list, which simplifies this case.
4610 Note that we still have to gimplify, in order to handle the
4611 case of variable sized types. Avoid shared tree structures. */
4612 CONSTRUCTOR_ELTS (ctor) = NULL;
4613 TREE_SIDE_EFFECTS (ctor) = 0;
4614 object = unshare_expr (object);
4615 gimplify_stmt (expr_p, pre_p);
4618 /* If we have not block cleared the object, or if there are nonzero
4619 elements in the constructor, or if the constructor has side effects,
4620 add assignments to the individual scalar fields of the object. */
4621 if (!cleared
4622 || num_nonzero_elements > 0
4623 || ctor_has_side_effects_p)
4624 gimplify_init_ctor_eval (object, elts, pre_p, cleared);
4626 *expr_p = NULL_TREE;
4628 break;
4630 case COMPLEX_TYPE:
4632 tree r, i;
4634 if (notify_temp_creation)
4635 return GS_OK;
4637 /* Extract the real and imaginary parts out of the ctor. */
4638 gcc_assert (elts->length () == 2);
4639 r = (*elts)[0].value;
4640 i = (*elts)[1].value;
4641 if (r == NULL || i == NULL)
4643 tree zero = build_zero_cst (TREE_TYPE (type));
4644 if (r == NULL)
4645 r = zero;
4646 if (i == NULL)
4647 i = zero;
4650 /* Complex types have either COMPLEX_CST or COMPLEX_EXPR to
4651 represent creation of a complex value. */
4652 if (TREE_CONSTANT (r) && TREE_CONSTANT (i))
4654 ctor = build_complex (type, r, i);
4655 TREE_OPERAND (*expr_p, 1) = ctor;
4657 else
4659 ctor = build2 (COMPLEX_EXPR, type, r, i);
4660 TREE_OPERAND (*expr_p, 1) = ctor;
4661 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 1),
4662 pre_p,
4663 post_p,
4664 rhs_predicate_for (TREE_OPERAND (*expr_p, 0)),
4665 fb_rvalue);
4668 break;
4670 case VECTOR_TYPE:
4672 unsigned HOST_WIDE_INT ix;
4673 constructor_elt *ce;
4675 if (notify_temp_creation)
4676 return GS_OK;
4678 /* Go ahead and simplify constant constructors to VECTOR_CST. */
4679 if (TREE_CONSTANT (ctor))
4681 bool constant_p = true;
4682 tree value;
4684 /* Even when ctor is constant, it might contain non-*_CST
4685 elements, such as addresses or trapping values like
4686 1.0/0.0 - 1.0/0.0. Such expressions don't belong
4687 in VECTOR_CST nodes. */
4688 FOR_EACH_CONSTRUCTOR_VALUE (elts, ix, value)
4689 if (!CONSTANT_CLASS_P (value))
4691 constant_p = false;
4692 break;
4695 if (constant_p)
4697 TREE_OPERAND (*expr_p, 1) = build_vector_from_ctor (type, elts);
4698 break;
4701 TREE_CONSTANT (ctor) = 0;
4704 /* Vector types use CONSTRUCTOR all the way through gimple
4705 compilation as a general initializer. */
4706 FOR_EACH_VEC_SAFE_ELT (elts, ix, ce)
4708 enum gimplify_status tret;
4709 tret = gimplify_expr (&ce->value, pre_p, post_p, is_gimple_val,
4710 fb_rvalue);
4711 if (tret == GS_ERROR)
4712 ret = GS_ERROR;
4713 else if (TREE_STATIC (ctor)
4714 && !initializer_constant_valid_p (ce->value,
4715 TREE_TYPE (ce->value)))
4716 TREE_STATIC (ctor) = 0;
4718 if (!is_gimple_reg (TREE_OPERAND (*expr_p, 0)))
4719 TREE_OPERAND (*expr_p, 1) = get_formal_tmp_var (ctor, pre_p);
4721 break;
4723 default:
4724 /* So how did we get a CONSTRUCTOR for a scalar type? */
4725 gcc_unreachable ();
4728 if (ret == GS_ERROR)
4729 return GS_ERROR;
4730 else if (want_value)
4732 *expr_p = object;
4733 return GS_OK;
4735 else
4737 /* If we have gimplified both sides of the initializer but have
4738 not emitted an assignment, do so now. */
4739 if (*expr_p)
4741 tree lhs = TREE_OPERAND (*expr_p, 0);
4742 tree rhs = TREE_OPERAND (*expr_p, 1);
4743 gassign *init = gimple_build_assign (lhs, rhs);
4744 gimplify_seq_add_stmt (pre_p, init);
4745 *expr_p = NULL;
4748 return GS_ALL_DONE;
4752 /* Given a pointer value OP0, return a simplified version of an
4753 indirection through OP0, or NULL_TREE if no simplification is
4754 possible. This may only be applied to a rhs of an expression.
4755 Note that the resulting type may be different from the type pointed
4756 to in the sense that it is still compatible from the langhooks
4757 point of view. */
4759 static tree
4760 gimple_fold_indirect_ref_rhs (tree t)
4762 return gimple_fold_indirect_ref (t);
4765 /* Subroutine of gimplify_modify_expr to do simplifications of
4766 MODIFY_EXPRs based on the code of the RHS. We loop for as long as
4767 something changes. */
4769 static enum gimplify_status
4770 gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p,
4771 gimple_seq *pre_p, gimple_seq *post_p,
4772 bool want_value)
4774 enum gimplify_status ret = GS_UNHANDLED;
4775 bool changed;
4779 changed = false;
4780 switch (TREE_CODE (*from_p))
4782 case VAR_DECL:
4783 /* If we're assigning from a read-only variable initialized with
4784 a constructor, do the direct assignment from the constructor,
4785 but only if neither source nor target are volatile since this
4786 latter assignment might end up being done on a per-field basis. */
4787 if (DECL_INITIAL (*from_p)
4788 && TREE_READONLY (*from_p)
4789 && !TREE_THIS_VOLATILE (*from_p)
4790 && !TREE_THIS_VOLATILE (*to_p)
4791 && TREE_CODE (DECL_INITIAL (*from_p)) == CONSTRUCTOR)
4793 tree old_from = *from_p;
4794 enum gimplify_status subret;
4796 /* Move the constructor into the RHS. */
4797 *from_p = unshare_expr (DECL_INITIAL (*from_p));
4799 /* Let's see if gimplify_init_constructor will need to put
4800 it in memory. */
4801 subret = gimplify_init_constructor (expr_p, NULL, NULL,
4802 false, true);
4803 if (subret == GS_ERROR)
4805 /* If so, revert the change. */
4806 *from_p = old_from;
4808 else
4810 ret = GS_OK;
4811 changed = true;
4814 break;
4815 case INDIRECT_REF:
4817 /* If we have code like
4819 *(const A*)(A*)&x
4821 where the type of "x" is a (possibly cv-qualified variant
4822 of "A"), treat the entire expression as identical to "x".
4823 This kind of code arises in C++ when an object is bound
4824 to a const reference, and if "x" is a TARGET_EXPR we want
4825 to take advantage of the optimization below. */
4826 bool volatile_p = TREE_THIS_VOLATILE (*from_p);
4827 tree t = gimple_fold_indirect_ref_rhs (TREE_OPERAND (*from_p, 0));
4828 if (t)
4830 if (TREE_THIS_VOLATILE (t) != volatile_p)
4832 if (DECL_P (t))
4833 t = build_simple_mem_ref_loc (EXPR_LOCATION (*from_p),
4834 build_fold_addr_expr (t));
4835 if (REFERENCE_CLASS_P (t))
4836 TREE_THIS_VOLATILE (t) = volatile_p;
4838 *from_p = t;
4839 ret = GS_OK;
4840 changed = true;
4842 break;
4845 case TARGET_EXPR:
4847 /* If we are initializing something from a TARGET_EXPR, strip the
4848 TARGET_EXPR and initialize it directly, if possible. This can't
4849 be done if the initializer is void, since that implies that the
4850 temporary is set in some non-trivial way.
4852 ??? What about code that pulls out the temp and uses it
4853 elsewhere? I think that such code never uses the TARGET_EXPR as
4854 an initializer. If I'm wrong, we'll die because the temp won't
4855 have any RTL. In that case, I guess we'll need to replace
4856 references somehow. */
4857 tree init = TARGET_EXPR_INITIAL (*from_p);
4859 if (init
4860 && !VOID_TYPE_P (TREE_TYPE (init)))
4862 *from_p = init;
4863 ret = GS_OK;
4864 changed = true;
4867 break;
4869 case COMPOUND_EXPR:
4870 /* Remove any COMPOUND_EXPR in the RHS so the following cases will be
4871 caught. */
4872 gimplify_compound_expr (from_p, pre_p, true);
4873 ret = GS_OK;
4874 changed = true;
4875 break;
4877 case CONSTRUCTOR:
4878 /* If we already made some changes, let the front end have a
4879 crack at this before we break it down. */
4880 if (ret != GS_UNHANDLED)
4881 break;
4882 /* If we're initializing from a CONSTRUCTOR, break this into
4883 individual MODIFY_EXPRs. */
4884 return gimplify_init_constructor (expr_p, pre_p, post_p, want_value,
4885 false);
4887 case COND_EXPR:
4888 /* If we're assigning to a non-register type, push the assignment
4889 down into the branches. This is mandatory for ADDRESSABLE types,
4890 since we cannot generate temporaries for such, but it saves a
4891 copy in other cases as well. */
4892 if (!is_gimple_reg_type (TREE_TYPE (*from_p)))
4894 /* This code should mirror the code in gimplify_cond_expr. */
4895 enum tree_code code = TREE_CODE (*expr_p);
4896 tree cond = *from_p;
4897 tree result = *to_p;
4899 ret = gimplify_expr (&result, pre_p, post_p,
4900 is_gimple_lvalue, fb_lvalue);
4901 if (ret != GS_ERROR)
4902 ret = GS_OK;
4904 if (TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node)
4905 TREE_OPERAND (cond, 1)
4906 = build2 (code, void_type_node, result,
4907 TREE_OPERAND (cond, 1));
4908 if (TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
4909 TREE_OPERAND (cond, 2)
4910 = build2 (code, void_type_node, unshare_expr (result),
4911 TREE_OPERAND (cond, 2));
4913 TREE_TYPE (cond) = void_type_node;
4914 recalculate_side_effects (cond);
4916 if (want_value)
4918 gimplify_and_add (cond, pre_p);
4919 *expr_p = unshare_expr (result);
4921 else
4922 *expr_p = cond;
4923 return ret;
4925 break;
4927 case CALL_EXPR:
4928 /* For calls that return in memory, give *to_p as the CALL_EXPR's
4929 return slot so that we don't generate a temporary. */
4930 if (!CALL_EXPR_RETURN_SLOT_OPT (*from_p)
4931 && aggregate_value_p (*from_p, *from_p))
4933 bool use_target;
4935 if (!(rhs_predicate_for (*to_p))(*from_p))
4936 /* If we need a temporary, *to_p isn't accurate. */
4937 use_target = false;
4938 /* It's OK to use the return slot directly unless it's an NRV. */
4939 else if (TREE_CODE (*to_p) == RESULT_DECL
4940 && DECL_NAME (*to_p) == NULL_TREE
4941 && needs_to_live_in_memory (*to_p))
4942 use_target = true;
4943 else if (is_gimple_reg_type (TREE_TYPE (*to_p))
4944 || (DECL_P (*to_p) && DECL_REGISTER (*to_p)))
4945 /* Don't force regs into memory. */
4946 use_target = false;
4947 else if (TREE_CODE (*expr_p) == INIT_EXPR)
4948 /* It's OK to use the target directly if it's being
4949 initialized. */
4950 use_target = true;
4951 else if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p)))
4952 != INTEGER_CST)
4953 /* Always use the target and thus RSO for variable-sized types.
4954 GIMPLE cannot deal with a variable-sized assignment
4955 embedded in a call statement. */
4956 use_target = true;
4957 else if (TREE_CODE (*to_p) != SSA_NAME
4958 && (!is_gimple_variable (*to_p)
4959 || needs_to_live_in_memory (*to_p)))
4960 /* Don't use the original target if it's already addressable;
4961 if its address escapes, and the called function uses the
4962 NRV optimization, a conforming program could see *to_p
4963 change before the called function returns; see c++/19317.
4964 When optimizing, the return_slot pass marks more functions
4965 as safe after we have escape info. */
4966 use_target = false;
4967 else
4968 use_target = true;
4970 if (use_target)
4972 CALL_EXPR_RETURN_SLOT_OPT (*from_p) = 1;
4973 mark_addressable (*to_p);
4976 break;
4978 case WITH_SIZE_EXPR:
4979 /* Likewise for calls that return an aggregate of non-constant size,
4980 since we would not be able to generate a temporary at all. */
4981 if (TREE_CODE (TREE_OPERAND (*from_p, 0)) == CALL_EXPR)
4983 *from_p = TREE_OPERAND (*from_p, 0);
4984 /* We don't change ret in this case because the
4985 WITH_SIZE_EXPR might have been added in
4986 gimplify_modify_expr, so returning GS_OK would lead to an
4987 infinite loop. */
4988 changed = true;
4990 break;
4992 /* If we're initializing from a container, push the initialization
4993 inside it. */
4994 case CLEANUP_POINT_EXPR:
4995 case BIND_EXPR:
4996 case STATEMENT_LIST:
4998 tree wrap = *from_p;
4999 tree t;
5001 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_min_lval,
5002 fb_lvalue);
5003 if (ret != GS_ERROR)
5004 ret = GS_OK;
5006 t = voidify_wrapper_expr (wrap, *expr_p);
5007 gcc_assert (t == *expr_p);
5009 if (want_value)
5011 gimplify_and_add (wrap, pre_p);
5012 *expr_p = unshare_expr (*to_p);
5014 else
5015 *expr_p = wrap;
5016 return GS_OK;
5019 case COMPOUND_LITERAL_EXPR:
5021 tree complit = TREE_OPERAND (*expr_p, 1);
5022 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (complit);
5023 tree decl = DECL_EXPR_DECL (decl_s);
5024 tree init = DECL_INITIAL (decl);
5026 /* struct T x = (struct T) { 0, 1, 2 } can be optimized
5027 into struct T x = { 0, 1, 2 } if the address of the
5028 compound literal has never been taken. */
5029 if (!TREE_ADDRESSABLE (complit)
5030 && !TREE_ADDRESSABLE (decl)
5031 && init)
5033 *expr_p = copy_node (*expr_p);
5034 TREE_OPERAND (*expr_p, 1) = init;
5035 return GS_OK;
5039 default:
5040 break;
5043 while (changed);
5045 return ret;
5049 /* Return true if T looks like a valid GIMPLE statement. */
5051 static bool
5052 is_gimple_stmt (tree t)
5054 const enum tree_code code = TREE_CODE (t);
5056 switch (code)
5058 case NOP_EXPR:
5059 /* The only valid NOP_EXPR is the empty statement. */
5060 return IS_EMPTY_STMT (t);
5062 case BIND_EXPR:
5063 case COND_EXPR:
5064 /* These are only valid if they're void. */
5065 return TREE_TYPE (t) == NULL || VOID_TYPE_P (TREE_TYPE (t));
5067 case SWITCH_EXPR:
5068 case GOTO_EXPR:
5069 case RETURN_EXPR:
5070 case LABEL_EXPR:
5071 case CASE_LABEL_EXPR:
5072 case TRY_CATCH_EXPR:
5073 case TRY_FINALLY_EXPR:
5074 case EH_FILTER_EXPR:
5075 case CATCH_EXPR:
5076 case ASM_EXPR:
5077 case STATEMENT_LIST:
5078 case OACC_PARALLEL:
5079 case OACC_KERNELS:
5080 case OACC_DATA:
5081 case OACC_HOST_DATA:
5082 case OACC_DECLARE:
5083 case OACC_UPDATE:
5084 case OACC_ENTER_DATA:
5085 case OACC_EXIT_DATA:
5086 case OACC_CACHE:
5087 case OMP_PARALLEL:
5088 case OMP_FOR:
5089 case OMP_SIMD:
5090 case CILK_SIMD:
5091 case OMP_DISTRIBUTE:
5092 case OACC_LOOP:
5093 case OMP_SECTIONS:
5094 case OMP_SECTION:
5095 case OMP_SINGLE:
5096 case OMP_MASTER:
5097 case OMP_TASKGROUP:
5098 case OMP_ORDERED:
5099 case OMP_CRITICAL:
5100 case OMP_TASK:
5101 case OMP_TARGET:
5102 case OMP_TARGET_DATA:
5103 case OMP_TARGET_UPDATE:
5104 case OMP_TARGET_ENTER_DATA:
5105 case OMP_TARGET_EXIT_DATA:
5106 case OMP_TASKLOOP:
5107 case OMP_TEAMS:
5108 /* These are always void. */
5109 return true;
5111 case CALL_EXPR:
5112 case MODIFY_EXPR:
5113 case PREDICT_EXPR:
5114 /* These are valid regardless of their type. */
5115 return true;
5117 default:
5118 return false;
5123 /* Promote partial stores to COMPLEX variables to total stores. *EXPR_P is
5124 a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a variable with
5125 DECL_GIMPLE_REG_P set.
5127 IMPORTANT NOTE: This promotion is performed by introducing a load of the
5128 other, unmodified part of the complex object just before the total store.
5129 As a consequence, if the object is still uninitialized, an undefined value
5130 will be loaded into a register, which may result in a spurious exception
5131 if the register is floating-point and the value happens to be a signaling
5132 NaN for example. Then the fully-fledged complex operations lowering pass
5133 followed by a DCE pass are necessary in order to fix things up. */
5135 static enum gimplify_status
5136 gimplify_modify_expr_complex_part (tree *expr_p, gimple_seq *pre_p,
5137 bool want_value)
5139 enum tree_code code, ocode;
5140 tree lhs, rhs, new_rhs, other, realpart, imagpart;
5142 lhs = TREE_OPERAND (*expr_p, 0);
5143 rhs = TREE_OPERAND (*expr_p, 1);
5144 code = TREE_CODE (lhs);
5145 lhs = TREE_OPERAND (lhs, 0);
5147 ocode = code == REALPART_EXPR ? IMAGPART_EXPR : REALPART_EXPR;
5148 other = build1 (ocode, TREE_TYPE (rhs), lhs);
5149 TREE_NO_WARNING (other) = 1;
5150 other = get_formal_tmp_var (other, pre_p);
5152 realpart = code == REALPART_EXPR ? rhs : other;
5153 imagpart = code == REALPART_EXPR ? other : rhs;
5155 if (TREE_CONSTANT (realpart) && TREE_CONSTANT (imagpart))
5156 new_rhs = build_complex (TREE_TYPE (lhs), realpart, imagpart);
5157 else
5158 new_rhs = build2 (COMPLEX_EXPR, TREE_TYPE (lhs), realpart, imagpart);
5160 gimplify_seq_add_stmt (pre_p, gimple_build_assign (lhs, new_rhs));
5161 *expr_p = (want_value) ? rhs : NULL_TREE;
5163 return GS_ALL_DONE;
5166 /* Gimplify the MODIFY_EXPR node pointed to by EXPR_P.
5168 modify_expr
5169 : varname '=' rhs
5170 | '*' ID '=' rhs
5172 PRE_P points to the list where side effects that must happen before
5173 *EXPR_P should be stored.
5175 POST_P points to the list where side effects that must happen after
5176 *EXPR_P should be stored.
5178 WANT_VALUE is nonzero iff we want to use the value of this expression
5179 in another expression. */
5181 static enum gimplify_status
5182 gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
5183 bool want_value)
5185 tree *from_p = &TREE_OPERAND (*expr_p, 1);
5186 tree *to_p = &TREE_OPERAND (*expr_p, 0);
5187 enum gimplify_status ret = GS_UNHANDLED;
5188 gimple *assign;
5189 location_t loc = EXPR_LOCATION (*expr_p);
5190 gimple_stmt_iterator gsi;
5192 gcc_assert (TREE_CODE (*expr_p) == MODIFY_EXPR
5193 || TREE_CODE (*expr_p) == INIT_EXPR);
5195 /* Trying to simplify a clobber using normal logic doesn't work,
5196 so handle it here. */
5197 if (TREE_CLOBBER_P (*from_p))
5199 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
5200 if (ret == GS_ERROR)
5201 return ret;
5202 gcc_assert (!want_value
5203 && (TREE_CODE (*to_p) == VAR_DECL
5204 || TREE_CODE (*to_p) == MEM_REF));
5205 gimplify_seq_add_stmt (pre_p, gimple_build_assign (*to_p, *from_p));
5206 *expr_p = NULL;
5207 return GS_ALL_DONE;
5210 /* Insert pointer conversions required by the middle-end that are not
5211 required by the frontend. This fixes middle-end type checking for
5212 for example gcc.dg/redecl-6.c. */
5213 if (POINTER_TYPE_P (TREE_TYPE (*to_p)))
5215 STRIP_USELESS_TYPE_CONVERSION (*from_p);
5216 if (!useless_type_conversion_p (TREE_TYPE (*to_p), TREE_TYPE (*from_p)))
5217 *from_p = fold_convert_loc (loc, TREE_TYPE (*to_p), *from_p);
5220 /* See if any simplifications can be done based on what the RHS is. */
5221 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
5222 want_value);
5223 if (ret != GS_UNHANDLED)
5224 return ret;
5226 /* For zero sized types only gimplify the left hand side and right hand
5227 side as statements and throw away the assignment. Do this after
5228 gimplify_modify_expr_rhs so we handle TARGET_EXPRs of addressable
5229 types properly. */
5230 if (zero_sized_type (TREE_TYPE (*from_p)) && !want_value)
5232 gimplify_stmt (from_p, pre_p);
5233 gimplify_stmt (to_p, pre_p);
5234 *expr_p = NULL_TREE;
5235 return GS_ALL_DONE;
5238 /* If the value being copied is of variable width, compute the length
5239 of the copy into a WITH_SIZE_EXPR. Note that we need to do this
5240 before gimplifying any of the operands so that we can resolve any
5241 PLACEHOLDER_EXPRs in the size. Also note that the RTL expander uses
5242 the size of the expression to be copied, not of the destination, so
5243 that is what we must do here. */
5244 maybe_with_size_expr (from_p);
5246 /* As a special case, we have to temporarily allow for assignments
5247 with a CALL_EXPR on the RHS. Since in GIMPLE a function call is
5248 a toplevel statement, when gimplifying the GENERIC expression
5249 MODIFY_EXPR <a, CALL_EXPR <foo>>, we cannot create the tuple
5250 GIMPLE_ASSIGN <a, GIMPLE_CALL <foo>>.
5252 Instead, we need to create the tuple GIMPLE_CALL <a, foo>. To
5253 prevent gimplify_expr from trying to create a new temporary for
5254 foo's LHS, we tell it that it should only gimplify until it
5255 reaches the CALL_EXPR. On return from gimplify_expr, the newly
5256 created GIMPLE_CALL <foo> will be the last statement in *PRE_P
5257 and all we need to do here is set 'a' to be its LHS. */
5259 /* Gimplify the RHS first for C++17 and bug 71104. */
5260 gimple_predicate initial_pred = initial_rhs_predicate_for (*to_p);
5261 ret = gimplify_expr (from_p, pre_p, post_p, initial_pred, fb_rvalue);
5262 if (ret == GS_ERROR)
5263 return ret;
5265 /* Then gimplify the LHS. */
5266 /* If we gimplified the RHS to a CALL_EXPR and that call may return
5267 twice we have to make sure to gimplify into non-SSA as otherwise
5268 the abnormal edge added later will make those defs not dominate
5269 their uses.
5270 ??? Technically this applies only to the registers used in the
5271 resulting non-register *TO_P. */
5272 bool saved_into_ssa = gimplify_ctxp->into_ssa;
5273 if (saved_into_ssa
5274 && TREE_CODE (*from_p) == CALL_EXPR
5275 && call_expr_flags (*from_p) & ECF_RETURNS_TWICE)
5276 gimplify_ctxp->into_ssa = false;
5277 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
5278 gimplify_ctxp->into_ssa = saved_into_ssa;
5279 if (ret == GS_ERROR)
5280 return ret;
5282 /* Now that the LHS is gimplified, re-gimplify the RHS if our initial
5283 guess for the predicate was wrong. */
5284 gimple_predicate final_pred = rhs_predicate_for (*to_p);
5285 if (final_pred != initial_pred)
5287 ret = gimplify_expr (from_p, pre_p, post_p, final_pred, fb_rvalue);
5288 if (ret == GS_ERROR)
5289 return ret;
5292 /* In case of va_arg internal fn wrappped in a WITH_SIZE_EXPR, add the type
5293 size as argument to the call. */
5294 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
5296 tree call = TREE_OPERAND (*from_p, 0);
5297 tree vlasize = TREE_OPERAND (*from_p, 1);
5299 if (TREE_CODE (call) == CALL_EXPR
5300 && CALL_EXPR_IFN (call) == IFN_VA_ARG)
5302 int nargs = call_expr_nargs (call);
5303 tree type = TREE_TYPE (call);
5304 tree ap = CALL_EXPR_ARG (call, 0);
5305 tree tag = CALL_EXPR_ARG (call, 1);
5306 tree aptag = CALL_EXPR_ARG (call, 2);
5307 tree newcall = build_call_expr_internal_loc (EXPR_LOCATION (call),
5308 IFN_VA_ARG, type,
5309 nargs + 1, ap, tag,
5310 aptag, vlasize);
5311 TREE_OPERAND (*from_p, 0) = newcall;
5315 /* Now see if the above changed *from_p to something we handle specially. */
5316 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
5317 want_value);
5318 if (ret != GS_UNHANDLED)
5319 return ret;
5321 /* If we've got a variable sized assignment between two lvalues (i.e. does
5322 not involve a call), then we can make things a bit more straightforward
5323 by converting the assignment to memcpy or memset. */
5324 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
5326 tree from = TREE_OPERAND (*from_p, 0);
5327 tree size = TREE_OPERAND (*from_p, 1);
5329 if (TREE_CODE (from) == CONSTRUCTOR)
5330 return gimplify_modify_expr_to_memset (expr_p, size, want_value, pre_p);
5332 if (is_gimple_addressable (from))
5334 *from_p = from;
5335 return gimplify_modify_expr_to_memcpy (expr_p, size, want_value,
5336 pre_p);
5340 /* Transform partial stores to non-addressable complex variables into
5341 total stores. This allows us to use real instead of virtual operands
5342 for these variables, which improves optimization. */
5343 if ((TREE_CODE (*to_p) == REALPART_EXPR
5344 || TREE_CODE (*to_p) == IMAGPART_EXPR)
5345 && is_gimple_reg (TREE_OPERAND (*to_p, 0)))
5346 return gimplify_modify_expr_complex_part (expr_p, pre_p, want_value);
5348 /* Try to alleviate the effects of the gimplification creating artificial
5349 temporaries (see for example is_gimple_reg_rhs) on the debug info, but
5350 make sure not to create DECL_DEBUG_EXPR links across functions. */
5351 if (!gimplify_ctxp->into_ssa
5352 && TREE_CODE (*from_p) == VAR_DECL
5353 && DECL_IGNORED_P (*from_p)
5354 && DECL_P (*to_p)
5355 && !DECL_IGNORED_P (*to_p)
5356 && decl_function_context (*to_p) == current_function_decl)
5358 if (!DECL_NAME (*from_p) && DECL_NAME (*to_p))
5359 DECL_NAME (*from_p)
5360 = create_tmp_var_name (IDENTIFIER_POINTER (DECL_NAME (*to_p)));
5361 DECL_HAS_DEBUG_EXPR_P (*from_p) = 1;
5362 SET_DECL_DEBUG_EXPR (*from_p, *to_p);
5365 if (want_value && TREE_THIS_VOLATILE (*to_p))
5366 *from_p = get_initialized_tmp_var (*from_p, pre_p, post_p);
5368 if (TREE_CODE (*from_p) == CALL_EXPR)
5370 /* Since the RHS is a CALL_EXPR, we need to create a GIMPLE_CALL
5371 instead of a GIMPLE_ASSIGN. */
5372 gcall *call_stmt;
5373 if (CALL_EXPR_FN (*from_p) == NULL_TREE)
5375 /* Gimplify internal functions created in the FEs. */
5376 int nargs = call_expr_nargs (*from_p), i;
5377 enum internal_fn ifn = CALL_EXPR_IFN (*from_p);
5378 auto_vec<tree> vargs (nargs);
5380 for (i = 0; i < nargs; i++)
5382 gimplify_arg (&CALL_EXPR_ARG (*from_p, i), pre_p,
5383 EXPR_LOCATION (*from_p));
5384 vargs.quick_push (CALL_EXPR_ARG (*from_p, i));
5386 call_stmt = gimple_build_call_internal_vec (ifn, vargs);
5387 gimple_set_location (call_stmt, EXPR_LOCATION (*expr_p));
5389 else
5391 tree fnptrtype = TREE_TYPE (CALL_EXPR_FN (*from_p));
5392 CALL_EXPR_FN (*from_p) = TREE_OPERAND (CALL_EXPR_FN (*from_p), 0);
5393 STRIP_USELESS_TYPE_CONVERSION (CALL_EXPR_FN (*from_p));
5394 tree fndecl = get_callee_fndecl (*from_p);
5395 if (fndecl
5396 && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
5397 && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT
5398 && call_expr_nargs (*from_p) == 3)
5399 call_stmt = gimple_build_call_internal (IFN_BUILTIN_EXPECT, 3,
5400 CALL_EXPR_ARG (*from_p, 0),
5401 CALL_EXPR_ARG (*from_p, 1),
5402 CALL_EXPR_ARG (*from_p, 2));
5403 else
5405 call_stmt = gimple_build_call_from_tree (*from_p);
5406 gimple_call_set_fntype (call_stmt, TREE_TYPE (fnptrtype));
5409 notice_special_calls (call_stmt);
5410 if (!gimple_call_noreturn_p (call_stmt) || !should_remove_lhs_p (*to_p))
5411 gimple_call_set_lhs (call_stmt, *to_p);
5412 else if (TREE_CODE (*to_p) == SSA_NAME)
5413 /* The above is somewhat premature, avoid ICEing later for a
5414 SSA name w/o a definition. We may have uses in the GIMPLE IL.
5415 ??? This doesn't make it a default-def. */
5416 SSA_NAME_DEF_STMT (*to_p) = gimple_build_nop ();
5417 assign = call_stmt;
5419 else
5421 assign = gimple_build_assign (*to_p, *from_p);
5422 gimple_set_location (assign, EXPR_LOCATION (*expr_p));
5423 if (COMPARISON_CLASS_P (*from_p))
5424 gimple_set_no_warning (assign, TREE_NO_WARNING (*from_p));
5427 if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p))
5429 /* We should have got an SSA name from the start. */
5430 gcc_assert (TREE_CODE (*to_p) == SSA_NAME
5431 || ! gimple_in_ssa_p (cfun));
5434 gimplify_seq_add_stmt (pre_p, assign);
5435 gsi = gsi_last (*pre_p);
5436 maybe_fold_stmt (&gsi);
5438 if (want_value)
5440 *expr_p = TREE_THIS_VOLATILE (*to_p) ? *from_p : unshare_expr (*to_p);
5441 return GS_OK;
5443 else
5444 *expr_p = NULL;
5446 return GS_ALL_DONE;
5449 /* Gimplify a comparison between two variable-sized objects. Do this
5450 with a call to BUILT_IN_MEMCMP. */
5452 static enum gimplify_status
5453 gimplify_variable_sized_compare (tree *expr_p)
5455 location_t loc = EXPR_LOCATION (*expr_p);
5456 tree op0 = TREE_OPERAND (*expr_p, 0);
5457 tree op1 = TREE_OPERAND (*expr_p, 1);
5458 tree t, arg, dest, src, expr;
5460 arg = TYPE_SIZE_UNIT (TREE_TYPE (op0));
5461 arg = unshare_expr (arg);
5462 arg = SUBSTITUTE_PLACEHOLDER_IN_EXPR (arg, op0);
5463 src = build_fold_addr_expr_loc (loc, op1);
5464 dest = build_fold_addr_expr_loc (loc, op0);
5465 t = builtin_decl_implicit (BUILT_IN_MEMCMP);
5466 t = build_call_expr_loc (loc, t, 3, dest, src, arg);
5468 expr
5469 = build2 (TREE_CODE (*expr_p), TREE_TYPE (*expr_p), t, integer_zero_node);
5470 SET_EXPR_LOCATION (expr, loc);
5471 *expr_p = expr;
5473 return GS_OK;
5476 /* Gimplify a comparison between two aggregate objects of integral scalar
5477 mode as a comparison between the bitwise equivalent scalar values. */
5479 static enum gimplify_status
5480 gimplify_scalar_mode_aggregate_compare (tree *expr_p)
5482 location_t loc = EXPR_LOCATION (*expr_p);
5483 tree op0 = TREE_OPERAND (*expr_p, 0);
5484 tree op1 = TREE_OPERAND (*expr_p, 1);
5486 tree type = TREE_TYPE (op0);
5487 tree scalar_type = lang_hooks.types.type_for_mode (TYPE_MODE (type), 1);
5489 op0 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op0);
5490 op1 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op1);
5492 *expr_p
5493 = fold_build2_loc (loc, TREE_CODE (*expr_p), TREE_TYPE (*expr_p), op0, op1);
5495 return GS_OK;
5498 /* Gimplify an expression sequence. This function gimplifies each
5499 expression and rewrites the original expression with the last
5500 expression of the sequence in GIMPLE form.
5502 PRE_P points to the list where the side effects for all the
5503 expressions in the sequence will be emitted.
5505 WANT_VALUE is true when the result of the last COMPOUND_EXPR is used. */
5507 static enum gimplify_status
5508 gimplify_compound_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
5510 tree t = *expr_p;
5514 tree *sub_p = &TREE_OPERAND (t, 0);
5516 if (TREE_CODE (*sub_p) == COMPOUND_EXPR)
5517 gimplify_compound_expr (sub_p, pre_p, false);
5518 else
5519 gimplify_stmt (sub_p, pre_p);
5521 t = TREE_OPERAND (t, 1);
5523 while (TREE_CODE (t) == COMPOUND_EXPR);
5525 *expr_p = t;
5526 if (want_value)
5527 return GS_OK;
5528 else
5530 gimplify_stmt (expr_p, pre_p);
5531 return GS_ALL_DONE;
5535 /* Gimplify a SAVE_EXPR node. EXPR_P points to the expression to
5536 gimplify. After gimplification, EXPR_P will point to a new temporary
5537 that holds the original value of the SAVE_EXPR node.
5539 PRE_P points to the list where side effects that must happen before
5540 *EXPR_P should be stored. */
5542 static enum gimplify_status
5543 gimplify_save_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
5545 enum gimplify_status ret = GS_ALL_DONE;
5546 tree val;
5548 gcc_assert (TREE_CODE (*expr_p) == SAVE_EXPR);
5549 val = TREE_OPERAND (*expr_p, 0);
5551 /* If the SAVE_EXPR has not been resolved, then evaluate it once. */
5552 if (!SAVE_EXPR_RESOLVED_P (*expr_p))
5554 /* The operand may be a void-valued expression such as SAVE_EXPRs
5555 generated by the Java frontend for class initialization. It is
5556 being executed only for its side-effects. */
5557 if (TREE_TYPE (val) == void_type_node)
5559 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
5560 is_gimple_stmt, fb_none);
5561 val = NULL;
5563 else
5564 /* The temporary may not be an SSA name as later abnormal and EH
5565 control flow may invalidate use/def domination. */
5566 val = get_initialized_tmp_var (val, pre_p, post_p, false);
5568 TREE_OPERAND (*expr_p, 0) = val;
5569 SAVE_EXPR_RESOLVED_P (*expr_p) = 1;
5572 *expr_p = val;
5574 return ret;
5577 /* Rewrite the ADDR_EXPR node pointed to by EXPR_P
5579 unary_expr
5580 : ...
5581 | '&' varname
5584 PRE_P points to the list where side effects that must happen before
5585 *EXPR_P should be stored.
5587 POST_P points to the list where side effects that must happen after
5588 *EXPR_P should be stored. */
5590 static enum gimplify_status
5591 gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
5593 tree expr = *expr_p;
5594 tree op0 = TREE_OPERAND (expr, 0);
5595 enum gimplify_status ret;
5596 location_t loc = EXPR_LOCATION (*expr_p);
5598 switch (TREE_CODE (op0))
5600 case INDIRECT_REF:
5601 do_indirect_ref:
5602 /* Check if we are dealing with an expression of the form '&*ptr'.
5603 While the front end folds away '&*ptr' into 'ptr', these
5604 expressions may be generated internally by the compiler (e.g.,
5605 builtins like __builtin_va_end). */
5606 /* Caution: the silent array decomposition semantics we allow for
5607 ADDR_EXPR means we can't always discard the pair. */
5608 /* Gimplification of the ADDR_EXPR operand may drop
5609 cv-qualification conversions, so make sure we add them if
5610 needed. */
5612 tree op00 = TREE_OPERAND (op0, 0);
5613 tree t_expr = TREE_TYPE (expr);
5614 tree t_op00 = TREE_TYPE (op00);
5616 if (!useless_type_conversion_p (t_expr, t_op00))
5617 op00 = fold_convert_loc (loc, TREE_TYPE (expr), op00);
5618 *expr_p = op00;
5619 ret = GS_OK;
5621 break;
5623 case VIEW_CONVERT_EXPR:
5624 /* Take the address of our operand and then convert it to the type of
5625 this ADDR_EXPR.
5627 ??? The interactions of VIEW_CONVERT_EXPR and aliasing is not at
5628 all clear. The impact of this transformation is even less clear. */
5630 /* If the operand is a useless conversion, look through it. Doing so
5631 guarantees that the ADDR_EXPR and its operand will remain of the
5632 same type. */
5633 if (tree_ssa_useless_type_conversion (TREE_OPERAND (op0, 0)))
5634 op0 = TREE_OPERAND (op0, 0);
5636 *expr_p = fold_convert_loc (loc, TREE_TYPE (expr),
5637 build_fold_addr_expr_loc (loc,
5638 TREE_OPERAND (op0, 0)));
5639 ret = GS_OK;
5640 break;
5642 case MEM_REF:
5643 if (integer_zerop (TREE_OPERAND (op0, 1)))
5644 goto do_indirect_ref;
5646 /* fall through */
5648 default:
5649 /* If we see a call to a declared builtin or see its address
5650 being taken (we can unify those cases here) then we can mark
5651 the builtin for implicit generation by GCC. */
5652 if (TREE_CODE (op0) == FUNCTION_DECL
5653 && DECL_BUILT_IN_CLASS (op0) == BUILT_IN_NORMAL
5654 && builtin_decl_declared_p (DECL_FUNCTION_CODE (op0)))
5655 set_builtin_decl_implicit_p (DECL_FUNCTION_CODE (op0), true);
5657 /* We use fb_either here because the C frontend sometimes takes
5658 the address of a call that returns a struct; see
5659 gcc.dg/c99-array-lval-1.c. The gimplifier will correctly make
5660 the implied temporary explicit. */
5662 /* Make the operand addressable. */
5663 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, post_p,
5664 is_gimple_addressable, fb_either);
5665 if (ret == GS_ERROR)
5666 break;
5668 /* Then mark it. Beware that it may not be possible to do so directly
5669 if a temporary has been created by the gimplification. */
5670 prepare_gimple_addressable (&TREE_OPERAND (expr, 0), pre_p);
5672 op0 = TREE_OPERAND (expr, 0);
5674 /* For various reasons, the gimplification of the expression
5675 may have made a new INDIRECT_REF. */
5676 if (TREE_CODE (op0) == INDIRECT_REF)
5677 goto do_indirect_ref;
5679 mark_addressable (TREE_OPERAND (expr, 0));
5681 /* The FEs may end up building ADDR_EXPRs early on a decl with
5682 an incomplete type. Re-build ADDR_EXPRs in canonical form
5683 here. */
5684 if (!types_compatible_p (TREE_TYPE (op0), TREE_TYPE (TREE_TYPE (expr))))
5685 *expr_p = build_fold_addr_expr (op0);
5687 /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly. */
5688 recompute_tree_invariant_for_addr_expr (*expr_p);
5690 /* If we re-built the ADDR_EXPR add a conversion to the original type
5691 if required. */
5692 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
5693 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
5695 break;
5698 return ret;
5701 /* Gimplify the operands of an ASM_EXPR. Input operands should be a gimple
5702 value; output operands should be a gimple lvalue. */
5704 static enum gimplify_status
5705 gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
5707 tree expr;
5708 int noutputs;
5709 const char **oconstraints;
5710 int i;
5711 tree link;
5712 const char *constraint;
5713 bool allows_mem, allows_reg, is_inout;
5714 enum gimplify_status ret, tret;
5715 gasm *stmt;
5716 vec<tree, va_gc> *inputs;
5717 vec<tree, va_gc> *outputs;
5718 vec<tree, va_gc> *clobbers;
5719 vec<tree, va_gc> *labels;
5720 tree link_next;
5722 expr = *expr_p;
5723 noutputs = list_length (ASM_OUTPUTS (expr));
5724 oconstraints = (const char **) alloca ((noutputs) * sizeof (const char *));
5726 inputs = NULL;
5727 outputs = NULL;
5728 clobbers = NULL;
5729 labels = NULL;
5731 ret = GS_ALL_DONE;
5732 link_next = NULL_TREE;
5733 for (i = 0, link = ASM_OUTPUTS (expr); link; ++i, link = link_next)
5735 bool ok;
5736 size_t constraint_len;
5738 link_next = TREE_CHAIN (link);
5740 oconstraints[i]
5741 = constraint
5742 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
5743 constraint_len = strlen (constraint);
5744 if (constraint_len == 0)
5745 continue;
5747 ok = parse_output_constraint (&constraint, i, 0, 0,
5748 &allows_mem, &allows_reg, &is_inout);
5749 if (!ok)
5751 ret = GS_ERROR;
5752 is_inout = false;
5755 if (!allows_reg && allows_mem)
5756 mark_addressable (TREE_VALUE (link));
5758 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
5759 is_inout ? is_gimple_min_lval : is_gimple_lvalue,
5760 fb_lvalue | fb_mayfail);
5761 if (tret == GS_ERROR)
5763 error ("invalid lvalue in asm output %d", i);
5764 ret = tret;
5767 /* If the constraint does not allow memory make sure we gimplify
5768 it to a register if it is not already but its base is. This
5769 happens for complex and vector components. */
5770 if (!allows_mem)
5772 tree op = TREE_VALUE (link);
5773 if (! is_gimple_val (op)
5774 && is_gimple_reg_type (TREE_TYPE (op))
5775 && is_gimple_reg (get_base_address (op)))
5777 tree tem = create_tmp_reg (TREE_TYPE (op));
5778 tree ass;
5779 if (is_inout)
5781 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem),
5782 tem, unshare_expr (op));
5783 gimplify_and_add (ass, pre_p);
5785 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem), op, tem);
5786 gimplify_and_add (ass, post_p);
5788 TREE_VALUE (link) = tem;
5789 tret = GS_OK;
5793 vec_safe_push (outputs, link);
5794 TREE_CHAIN (link) = NULL_TREE;
5796 if (is_inout)
5798 /* An input/output operand. To give the optimizers more
5799 flexibility, split it into separate input and output
5800 operands. */
5801 tree input;
5802 /* Buffer big enough to format a 32-bit UINT_MAX into. */
5803 char buf[11];
5805 /* Turn the in/out constraint into an output constraint. */
5806 char *p = xstrdup (constraint);
5807 p[0] = '=';
5808 TREE_VALUE (TREE_PURPOSE (link)) = build_string (constraint_len, p);
5810 /* And add a matching input constraint. */
5811 if (allows_reg)
5813 sprintf (buf, "%u", i);
5815 /* If there are multiple alternatives in the constraint,
5816 handle each of them individually. Those that allow register
5817 will be replaced with operand number, the others will stay
5818 unchanged. */
5819 if (strchr (p, ',') != NULL)
5821 size_t len = 0, buflen = strlen (buf);
5822 char *beg, *end, *str, *dst;
5824 for (beg = p + 1;;)
5826 end = strchr (beg, ',');
5827 if (end == NULL)
5828 end = strchr (beg, '\0');
5829 if ((size_t) (end - beg) < buflen)
5830 len += buflen + 1;
5831 else
5832 len += end - beg + 1;
5833 if (*end)
5834 beg = end + 1;
5835 else
5836 break;
5839 str = (char *) alloca (len);
5840 for (beg = p + 1, dst = str;;)
5842 const char *tem;
5843 bool mem_p, reg_p, inout_p;
5845 end = strchr (beg, ',');
5846 if (end)
5847 *end = '\0';
5848 beg[-1] = '=';
5849 tem = beg - 1;
5850 parse_output_constraint (&tem, i, 0, 0,
5851 &mem_p, &reg_p, &inout_p);
5852 if (dst != str)
5853 *dst++ = ',';
5854 if (reg_p)
5856 memcpy (dst, buf, buflen);
5857 dst += buflen;
5859 else
5861 if (end)
5862 len = end - beg;
5863 else
5864 len = strlen (beg);
5865 memcpy (dst, beg, len);
5866 dst += len;
5868 if (end)
5869 beg = end + 1;
5870 else
5871 break;
5873 *dst = '\0';
5874 input = build_string (dst - str, str);
5876 else
5877 input = build_string (strlen (buf), buf);
5879 else
5880 input = build_string (constraint_len - 1, constraint + 1);
5882 free (p);
5884 input = build_tree_list (build_tree_list (NULL_TREE, input),
5885 unshare_expr (TREE_VALUE (link)));
5886 ASM_INPUTS (expr) = chainon (ASM_INPUTS (expr), input);
5890 link_next = NULL_TREE;
5891 for (link = ASM_INPUTS (expr); link; ++i, link = link_next)
5893 link_next = TREE_CHAIN (link);
5894 constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
5895 parse_input_constraint (&constraint, 0, 0, noutputs, 0,
5896 oconstraints, &allows_mem, &allows_reg);
5898 /* If we can't make copies, we can only accept memory. */
5899 if (TREE_ADDRESSABLE (TREE_TYPE (TREE_VALUE (link))))
5901 if (allows_mem)
5902 allows_reg = 0;
5903 else
5905 error ("impossible constraint in %<asm%>");
5906 error ("non-memory input %d must stay in memory", i);
5907 return GS_ERROR;
5911 /* If the operand is a memory input, it should be an lvalue. */
5912 if (!allows_reg && allows_mem)
5914 tree inputv = TREE_VALUE (link);
5915 STRIP_NOPS (inputv);
5916 if (TREE_CODE (inputv) == PREDECREMENT_EXPR
5917 || TREE_CODE (inputv) == PREINCREMENT_EXPR
5918 || TREE_CODE (inputv) == POSTDECREMENT_EXPR
5919 || TREE_CODE (inputv) == POSTINCREMENT_EXPR
5920 || TREE_CODE (inputv) == MODIFY_EXPR)
5921 TREE_VALUE (link) = error_mark_node;
5922 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
5923 is_gimple_lvalue, fb_lvalue | fb_mayfail);
5924 if (tret != GS_ERROR)
5926 /* Unlike output operands, memory inputs are not guaranteed
5927 to be lvalues by the FE, and while the expressions are
5928 marked addressable there, if it is e.g. a statement
5929 expression, temporaries in it might not end up being
5930 addressable. They might be already used in the IL and thus
5931 it is too late to make them addressable now though. */
5932 tree x = TREE_VALUE (link);
5933 while (handled_component_p (x))
5934 x = TREE_OPERAND (x, 0);
5935 if (TREE_CODE (x) == MEM_REF
5936 && TREE_CODE (TREE_OPERAND (x, 0)) == ADDR_EXPR)
5937 x = TREE_OPERAND (TREE_OPERAND (x, 0), 0);
5938 if ((TREE_CODE (x) == VAR_DECL
5939 || TREE_CODE (x) == PARM_DECL
5940 || TREE_CODE (x) == RESULT_DECL)
5941 && !TREE_ADDRESSABLE (x)
5942 && is_gimple_reg (x))
5944 warning_at (EXPR_LOC_OR_LOC (TREE_VALUE (link),
5945 input_location), 0,
5946 "memory input %d is not directly addressable",
5948 prepare_gimple_addressable (&TREE_VALUE (link), pre_p);
5951 mark_addressable (TREE_VALUE (link));
5952 if (tret == GS_ERROR)
5954 error_at (EXPR_LOC_OR_LOC (TREE_VALUE (link), input_location),
5955 "memory input %d is not directly addressable", i);
5956 ret = tret;
5959 else
5961 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
5962 is_gimple_asm_val, fb_rvalue);
5963 if (tret == GS_ERROR)
5964 ret = tret;
5967 TREE_CHAIN (link) = NULL_TREE;
5968 vec_safe_push (inputs, link);
5971 link_next = NULL_TREE;
5972 for (link = ASM_CLOBBERS (expr); link; ++i, link = link_next)
5974 link_next = TREE_CHAIN (link);
5975 TREE_CHAIN (link) = NULL_TREE;
5976 vec_safe_push (clobbers, link);
5979 link_next = NULL_TREE;
5980 for (link = ASM_LABELS (expr); link; ++i, link = link_next)
5982 link_next = TREE_CHAIN (link);
5983 TREE_CHAIN (link) = NULL_TREE;
5984 vec_safe_push (labels, link);
5987 /* Do not add ASMs with errors to the gimple IL stream. */
5988 if (ret != GS_ERROR)
5990 stmt = gimple_build_asm_vec (TREE_STRING_POINTER (ASM_STRING (expr)),
5991 inputs, outputs, clobbers, labels);
5993 gimple_asm_set_volatile (stmt, ASM_VOLATILE_P (expr) || noutputs == 0);
5994 gimple_asm_set_input (stmt, ASM_INPUT_P (expr));
5996 gimplify_seq_add_stmt (pre_p, stmt);
5999 return ret;
6002 /* Gimplify a CLEANUP_POINT_EXPR. Currently this works by adding
6003 GIMPLE_WITH_CLEANUP_EXPRs to the prequeue as we encounter cleanups while
6004 gimplifying the body, and converting them to TRY_FINALLY_EXPRs when we
6005 return to this function.
6007 FIXME should we complexify the prequeue handling instead? Or use flags
6008 for all the cleanups and let the optimizer tighten them up? The current
6009 code seems pretty fragile; it will break on a cleanup within any
6010 non-conditional nesting. But any such nesting would be broken, anyway;
6011 we can't write a TRY_FINALLY_EXPR that starts inside a nesting construct
6012 and continues out of it. We can do that at the RTL level, though, so
6013 having an optimizer to tighten up try/finally regions would be a Good
6014 Thing. */
6016 static enum gimplify_status
6017 gimplify_cleanup_point_expr (tree *expr_p, gimple_seq *pre_p)
6019 gimple_stmt_iterator iter;
6020 gimple_seq body_sequence = NULL;
6022 tree temp = voidify_wrapper_expr (*expr_p, NULL);
6024 /* We only care about the number of conditions between the innermost
6025 CLEANUP_POINT_EXPR and the cleanup. So save and reset the count and
6026 any cleanups collected outside the CLEANUP_POINT_EXPR. */
6027 int old_conds = gimplify_ctxp->conditions;
6028 gimple_seq old_cleanups = gimplify_ctxp->conditional_cleanups;
6029 bool old_in_cleanup_point_expr = gimplify_ctxp->in_cleanup_point_expr;
6030 gimplify_ctxp->conditions = 0;
6031 gimplify_ctxp->conditional_cleanups = NULL;
6032 gimplify_ctxp->in_cleanup_point_expr = true;
6034 gimplify_stmt (&TREE_OPERAND (*expr_p, 0), &body_sequence);
6036 gimplify_ctxp->conditions = old_conds;
6037 gimplify_ctxp->conditional_cleanups = old_cleanups;
6038 gimplify_ctxp->in_cleanup_point_expr = old_in_cleanup_point_expr;
6040 for (iter = gsi_start (body_sequence); !gsi_end_p (iter); )
6042 gimple *wce = gsi_stmt (iter);
6044 if (gimple_code (wce) == GIMPLE_WITH_CLEANUP_EXPR)
6046 if (gsi_one_before_end_p (iter))
6048 /* Note that gsi_insert_seq_before and gsi_remove do not
6049 scan operands, unlike some other sequence mutators. */
6050 if (!gimple_wce_cleanup_eh_only (wce))
6051 gsi_insert_seq_before_without_update (&iter,
6052 gimple_wce_cleanup (wce),
6053 GSI_SAME_STMT);
6054 gsi_remove (&iter, true);
6055 break;
6057 else
6059 gtry *gtry;
6060 gimple_seq seq;
6061 enum gimple_try_flags kind;
6063 if (gimple_wce_cleanup_eh_only (wce))
6064 kind = GIMPLE_TRY_CATCH;
6065 else
6066 kind = GIMPLE_TRY_FINALLY;
6067 seq = gsi_split_seq_after (iter);
6069 gtry = gimple_build_try (seq, gimple_wce_cleanup (wce), kind);
6070 /* Do not use gsi_replace here, as it may scan operands.
6071 We want to do a simple structural modification only. */
6072 gsi_set_stmt (&iter, gtry);
6073 iter = gsi_start (gtry->eval);
6076 else
6077 gsi_next (&iter);
6080 gimplify_seq_add_seq (pre_p, body_sequence);
6081 if (temp)
6083 *expr_p = temp;
6084 return GS_OK;
6086 else
6088 *expr_p = NULL;
6089 return GS_ALL_DONE;
6093 /* Insert a cleanup marker for gimplify_cleanup_point_expr. CLEANUP
6094 is the cleanup action required. EH_ONLY is true if the cleanup should
6095 only be executed if an exception is thrown, not on normal exit. */
6097 static void
6098 gimple_push_cleanup (tree var, tree cleanup, bool eh_only, gimple_seq *pre_p)
6100 gimple *wce;
6101 gimple_seq cleanup_stmts = NULL;
6103 /* Errors can result in improperly nested cleanups. Which results in
6104 confusion when trying to resolve the GIMPLE_WITH_CLEANUP_EXPR. */
6105 if (seen_error ())
6106 return;
6108 if (gimple_conditional_context ())
6110 /* If we're in a conditional context, this is more complex. We only
6111 want to run the cleanup if we actually ran the initialization that
6112 necessitates it, but we want to run it after the end of the
6113 conditional context. So we wrap the try/finally around the
6114 condition and use a flag to determine whether or not to actually
6115 run the destructor. Thus
6117 test ? f(A()) : 0
6119 becomes (approximately)
6121 flag = 0;
6122 try {
6123 if (test) { A::A(temp); flag = 1; val = f(temp); }
6124 else { val = 0; }
6125 } finally {
6126 if (flag) A::~A(temp);
6130 tree flag = create_tmp_var (boolean_type_node, "cleanup");
6131 gassign *ffalse = gimple_build_assign (flag, boolean_false_node);
6132 gassign *ftrue = gimple_build_assign (flag, boolean_true_node);
6134 cleanup = build3 (COND_EXPR, void_type_node, flag, cleanup, NULL);
6135 gimplify_stmt (&cleanup, &cleanup_stmts);
6136 wce = gimple_build_wce (cleanup_stmts);
6138 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, ffalse);
6139 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
6140 gimplify_seq_add_stmt (pre_p, ftrue);
6142 /* Because of this manipulation, and the EH edges that jump
6143 threading cannot redirect, the temporary (VAR) will appear
6144 to be used uninitialized. Don't warn. */
6145 TREE_NO_WARNING (var) = 1;
6147 else
6149 gimplify_stmt (&cleanup, &cleanup_stmts);
6150 wce = gimple_build_wce (cleanup_stmts);
6151 gimple_wce_set_cleanup_eh_only (wce, eh_only);
6152 gimplify_seq_add_stmt (pre_p, wce);
6156 /* Gimplify a TARGET_EXPR which doesn't appear on the rhs of an INIT_EXPR. */
6158 static enum gimplify_status
6159 gimplify_target_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6161 tree targ = *expr_p;
6162 tree temp = TARGET_EXPR_SLOT (targ);
6163 tree init = TARGET_EXPR_INITIAL (targ);
6164 enum gimplify_status ret;
6166 if (init)
6168 tree cleanup = NULL_TREE;
6170 /* TARGET_EXPR temps aren't part of the enclosing block, so add it
6171 to the temps list. Handle also variable length TARGET_EXPRs. */
6172 if (TREE_CODE (DECL_SIZE (temp)) != INTEGER_CST)
6174 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (temp)))
6175 gimplify_type_sizes (TREE_TYPE (temp), pre_p);
6176 gimplify_vla_decl (temp, pre_p);
6178 else
6179 gimple_add_tmp_var (temp);
6181 /* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the
6182 expression is supposed to initialize the slot. */
6183 if (VOID_TYPE_P (TREE_TYPE (init)))
6184 ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
6185 else
6187 tree init_expr = build2 (INIT_EXPR, void_type_node, temp, init);
6188 init = init_expr;
6189 ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
6190 init = NULL;
6191 ggc_free (init_expr);
6193 if (ret == GS_ERROR)
6195 /* PR c++/28266 Make sure this is expanded only once. */
6196 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
6197 return GS_ERROR;
6199 if (init)
6200 gimplify_and_add (init, pre_p);
6202 /* If needed, push the cleanup for the temp. */
6203 if (TARGET_EXPR_CLEANUP (targ))
6205 if (CLEANUP_EH_ONLY (targ))
6206 gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ),
6207 CLEANUP_EH_ONLY (targ), pre_p);
6208 else
6209 cleanup = TARGET_EXPR_CLEANUP (targ);
6212 /* Add a clobber for the temporary going out of scope, like
6213 gimplify_bind_expr. */
6214 if (gimplify_ctxp->in_cleanup_point_expr
6215 && needs_to_live_in_memory (temp)
6216 && flag_stack_reuse == SR_ALL)
6218 tree clobber = build_constructor (TREE_TYPE (temp),
6219 NULL);
6220 TREE_THIS_VOLATILE (clobber) = true;
6221 clobber = build2 (MODIFY_EXPR, TREE_TYPE (temp), temp, clobber);
6222 if (cleanup)
6223 cleanup = build2 (COMPOUND_EXPR, void_type_node, cleanup,
6224 clobber);
6225 else
6226 cleanup = clobber;
6229 if (cleanup)
6230 gimple_push_cleanup (temp, cleanup, false, pre_p);
6232 /* Only expand this once. */
6233 TREE_OPERAND (targ, 3) = init;
6234 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
6236 else
6237 /* We should have expanded this before. */
6238 gcc_assert (DECL_SEEN_IN_BIND_EXPR_P (temp));
6240 *expr_p = temp;
6241 return GS_OK;
6244 /* Gimplification of expression trees. */
6246 /* Gimplify an expression which appears at statement context. The
6247 corresponding GIMPLE statements are added to *SEQ_P. If *SEQ_P is
6248 NULL, a new sequence is allocated.
6250 Return true if we actually added a statement to the queue. */
6252 bool
6253 gimplify_stmt (tree *stmt_p, gimple_seq *seq_p)
6255 gimple_seq_node last;
6257 last = gimple_seq_last (*seq_p);
6258 gimplify_expr (stmt_p, seq_p, NULL, is_gimple_stmt, fb_none);
6259 return last != gimple_seq_last (*seq_p);
6262 /* Add FIRSTPRIVATE entries for DECL in the OpenMP the surrounding parallels
6263 to CTX. If entries already exist, force them to be some flavor of private.
6264 If there is no enclosing parallel, do nothing. */
6266 void
6267 omp_firstprivatize_variable (struct gimplify_omp_ctx *ctx, tree decl)
6269 splay_tree_node n;
6271 if (decl == NULL || !DECL_P (decl) || ctx->region_type == ORT_NONE)
6272 return;
6276 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
6277 if (n != NULL)
6279 if (n->value & GOVD_SHARED)
6280 n->value = GOVD_FIRSTPRIVATE | (n->value & GOVD_SEEN);
6281 else if (n->value & GOVD_MAP)
6282 n->value |= GOVD_MAP_TO_ONLY;
6283 else
6284 return;
6286 else if ((ctx->region_type & ORT_TARGET) != 0)
6288 if (ctx->target_map_scalars_firstprivate)
6289 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
6290 else
6291 omp_add_variable (ctx, decl, GOVD_MAP | GOVD_MAP_TO_ONLY);
6293 else if (ctx->region_type != ORT_WORKSHARE
6294 && ctx->region_type != ORT_SIMD
6295 && ctx->region_type != ORT_ACC
6296 && !(ctx->region_type & ORT_TARGET_DATA))
6297 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
6299 ctx = ctx->outer_context;
6301 while (ctx);
6304 /* Similarly for each of the type sizes of TYPE. */
6306 static void
6307 omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type)
6309 if (type == NULL || type == error_mark_node)
6310 return;
6311 type = TYPE_MAIN_VARIANT (type);
6313 if (ctx->privatized_types->add (type))
6314 return;
6316 switch (TREE_CODE (type))
6318 case INTEGER_TYPE:
6319 case ENUMERAL_TYPE:
6320 case BOOLEAN_TYPE:
6321 case REAL_TYPE:
6322 case FIXED_POINT_TYPE:
6323 omp_firstprivatize_variable (ctx, TYPE_MIN_VALUE (type));
6324 omp_firstprivatize_variable (ctx, TYPE_MAX_VALUE (type));
6325 break;
6327 case ARRAY_TYPE:
6328 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
6329 omp_firstprivatize_type_sizes (ctx, TYPE_DOMAIN (type));
6330 break;
6332 case RECORD_TYPE:
6333 case UNION_TYPE:
6334 case QUAL_UNION_TYPE:
6336 tree field;
6337 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
6338 if (TREE_CODE (field) == FIELD_DECL)
6340 omp_firstprivatize_variable (ctx, DECL_FIELD_OFFSET (field));
6341 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (field));
6344 break;
6346 case POINTER_TYPE:
6347 case REFERENCE_TYPE:
6348 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
6349 break;
6351 default:
6352 break;
6355 omp_firstprivatize_variable (ctx, TYPE_SIZE (type));
6356 omp_firstprivatize_variable (ctx, TYPE_SIZE_UNIT (type));
6357 lang_hooks.types.omp_firstprivatize_type_sizes (ctx, type);
6360 /* Add an entry for DECL in the OMP context CTX with FLAGS. */
6362 static void
6363 omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
6365 splay_tree_node n;
6366 unsigned int nflags;
6367 tree t;
6369 if (error_operand_p (decl) || ctx->region_type == ORT_NONE)
6370 return;
6372 /* Never elide decls whose type has TREE_ADDRESSABLE set. This means
6373 there are constructors involved somewhere. */
6374 if (TREE_ADDRESSABLE (TREE_TYPE (decl))
6375 || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
6376 flags |= GOVD_SEEN;
6378 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
6379 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
6381 /* We shouldn't be re-adding the decl with the same data
6382 sharing class. */
6383 gcc_assert ((n->value & GOVD_DATA_SHARE_CLASS & flags) == 0);
6384 nflags = n->value | flags;
6385 /* The only combination of data sharing classes we should see is
6386 FIRSTPRIVATE and LASTPRIVATE. However, OpenACC permits
6387 reduction variables to be used in data sharing clauses. */
6388 gcc_assert ((ctx->region_type & ORT_ACC) != 0
6389 || ((nflags & GOVD_DATA_SHARE_CLASS)
6390 == (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE))
6391 || (flags & GOVD_DATA_SHARE_CLASS) == 0);
6392 n->value = nflags;
6393 return;
6396 /* When adding a variable-sized variable, we have to handle all sorts
6397 of additional bits of data: the pointer replacement variable, and
6398 the parameters of the type. */
6399 if (DECL_SIZE (decl) && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
6401 /* Add the pointer replacement variable as PRIVATE if the variable
6402 replacement is private, else FIRSTPRIVATE since we'll need the
6403 address of the original variable either for SHARED, or for the
6404 copy into or out of the context. */
6405 if (!(flags & GOVD_LOCAL))
6407 if (flags & GOVD_MAP)
6408 nflags = GOVD_MAP | GOVD_MAP_TO_ONLY | GOVD_EXPLICIT;
6409 else if (flags & GOVD_PRIVATE)
6410 nflags = GOVD_PRIVATE;
6411 else if ((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
6412 && (flags & GOVD_FIRSTPRIVATE))
6413 nflags = GOVD_PRIVATE | GOVD_EXPLICIT;
6414 else
6415 nflags = GOVD_FIRSTPRIVATE;
6416 nflags |= flags & GOVD_SEEN;
6417 t = DECL_VALUE_EXPR (decl);
6418 gcc_assert (TREE_CODE (t) == INDIRECT_REF);
6419 t = TREE_OPERAND (t, 0);
6420 gcc_assert (DECL_P (t));
6421 omp_add_variable (ctx, t, nflags);
6424 /* Add all of the variable and type parameters (which should have
6425 been gimplified to a formal temporary) as FIRSTPRIVATE. */
6426 omp_firstprivatize_variable (ctx, DECL_SIZE_UNIT (decl));
6427 omp_firstprivatize_variable (ctx, DECL_SIZE (decl));
6428 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
6430 /* The variable-sized variable itself is never SHARED, only some form
6431 of PRIVATE. The sharing would take place via the pointer variable
6432 which we remapped above. */
6433 if (flags & GOVD_SHARED)
6434 flags = GOVD_PRIVATE | GOVD_DEBUG_PRIVATE
6435 | (flags & (GOVD_SEEN | GOVD_EXPLICIT));
6437 /* We're going to make use of the TYPE_SIZE_UNIT at least in the
6438 alloca statement we generate for the variable, so make sure it
6439 is available. This isn't automatically needed for the SHARED
6440 case, since we won't be allocating local storage then.
6441 For local variables TYPE_SIZE_UNIT might not be gimplified yet,
6442 in this case omp_notice_variable will be called later
6443 on when it is gimplified. */
6444 else if (! (flags & (GOVD_LOCAL | GOVD_MAP))
6445 && DECL_P (TYPE_SIZE_UNIT (TREE_TYPE (decl))))
6446 omp_notice_variable (ctx, TYPE_SIZE_UNIT (TREE_TYPE (decl)), true);
6448 else if ((flags & (GOVD_MAP | GOVD_LOCAL)) == 0
6449 && lang_hooks.decls.omp_privatize_by_reference (decl))
6451 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
6453 /* Similar to the direct variable sized case above, we'll need the
6454 size of references being privatized. */
6455 if ((flags & GOVD_SHARED) == 0)
6457 t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
6458 if (DECL_P (t))
6459 omp_notice_variable (ctx, t, true);
6463 if (n != NULL)
6464 n->value |= flags;
6465 else
6466 splay_tree_insert (ctx->variables, (splay_tree_key)decl, flags);
6468 /* For reductions clauses in OpenACC loop directives, by default create a
6469 copy clause on the enclosing parallel construct for carrying back the
6470 results. */
6471 if (ctx->region_type == ORT_ACC && (flags & GOVD_REDUCTION))
6473 struct gimplify_omp_ctx *outer_ctx = ctx->outer_context;
6474 while (outer_ctx)
6476 n = splay_tree_lookup (outer_ctx->variables, (splay_tree_key)decl);
6477 if (n != NULL)
6479 /* Ignore local variables and explicitly declared clauses. */
6480 if (n->value & (GOVD_LOCAL | GOVD_EXPLICIT))
6481 break;
6482 else if (outer_ctx->region_type == ORT_ACC_KERNELS)
6484 /* According to the OpenACC spec, such a reduction variable
6485 should already have a copy map on a kernels construct,
6486 verify that here. */
6487 gcc_assert (!(n->value & GOVD_FIRSTPRIVATE)
6488 && (n->value & GOVD_MAP));
6490 else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
6492 /* Remove firstprivate and make it a copy map. */
6493 n->value &= ~GOVD_FIRSTPRIVATE;
6494 n->value |= GOVD_MAP;
6497 else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
6499 splay_tree_insert (outer_ctx->variables, (splay_tree_key)decl,
6500 GOVD_MAP | GOVD_SEEN);
6501 break;
6503 outer_ctx = outer_ctx->outer_context;
6508 /* Notice a threadprivate variable DECL used in OMP context CTX.
6509 This just prints out diagnostics about threadprivate variable uses
6510 in untied tasks. If DECL2 is non-NULL, prevent this warning
6511 on that variable. */
6513 static bool
6514 omp_notice_threadprivate_variable (struct gimplify_omp_ctx *ctx, tree decl,
6515 tree decl2)
6517 splay_tree_node n;
6518 struct gimplify_omp_ctx *octx;
6520 for (octx = ctx; octx; octx = octx->outer_context)
6521 if ((octx->region_type & ORT_TARGET) != 0)
6523 n = splay_tree_lookup (octx->variables, (splay_tree_key)decl);
6524 if (n == NULL)
6526 error ("threadprivate variable %qE used in target region",
6527 DECL_NAME (decl));
6528 error_at (octx->location, "enclosing target region");
6529 splay_tree_insert (octx->variables, (splay_tree_key)decl, 0);
6531 if (decl2)
6532 splay_tree_insert (octx->variables, (splay_tree_key)decl2, 0);
6535 if (ctx->region_type != ORT_UNTIED_TASK)
6536 return false;
6537 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
6538 if (n == NULL)
6540 error ("threadprivate variable %qE used in untied task",
6541 DECL_NAME (decl));
6542 error_at (ctx->location, "enclosing task");
6543 splay_tree_insert (ctx->variables, (splay_tree_key)decl, 0);
6545 if (decl2)
6546 splay_tree_insert (ctx->variables, (splay_tree_key)decl2, 0);
6547 return false;
6550 /* Return true if global var DECL is device resident. */
6552 static bool
6553 device_resident_p (tree decl)
6555 tree attr = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (decl));
6557 if (!attr)
6558 return false;
6560 for (tree t = TREE_VALUE (attr); t; t = TREE_PURPOSE (t))
6562 tree c = TREE_VALUE (t);
6563 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DEVICE_RESIDENT)
6564 return true;
6567 return false;
6570 /* Determine outer default flags for DECL mentioned in an OMP region
6571 but not declared in an enclosing clause.
6573 ??? Some compiler-generated variables (like SAVE_EXPRs) could be
6574 remapped firstprivate instead of shared. To some extent this is
6575 addressed in omp_firstprivatize_type_sizes, but not
6576 effectively. */
6578 static unsigned
6579 omp_default_clause (struct gimplify_omp_ctx *ctx, tree decl,
6580 bool in_code, unsigned flags)
6582 enum omp_clause_default_kind default_kind = ctx->default_kind;
6583 enum omp_clause_default_kind kind;
6585 kind = lang_hooks.decls.omp_predetermined_sharing (decl);
6586 if (kind != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
6587 default_kind = kind;
6589 switch (default_kind)
6591 case OMP_CLAUSE_DEFAULT_NONE:
6593 const char *rtype;
6595 if (ctx->region_type & ORT_PARALLEL)
6596 rtype = "parallel";
6597 else if (ctx->region_type & ORT_TASK)
6598 rtype = "task";
6599 else if (ctx->region_type & ORT_TEAMS)
6600 rtype = "teams";
6601 else
6602 gcc_unreachable ();
6604 error ("%qE not specified in enclosing %s",
6605 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rtype);
6606 error_at (ctx->location, "enclosing %s", rtype);
6608 /* FALLTHRU */
6609 case OMP_CLAUSE_DEFAULT_SHARED:
6610 flags |= GOVD_SHARED;
6611 break;
6612 case OMP_CLAUSE_DEFAULT_PRIVATE:
6613 flags |= GOVD_PRIVATE;
6614 break;
6615 case OMP_CLAUSE_DEFAULT_FIRSTPRIVATE:
6616 flags |= GOVD_FIRSTPRIVATE;
6617 break;
6618 case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
6619 /* decl will be either GOVD_FIRSTPRIVATE or GOVD_SHARED. */
6620 gcc_assert ((ctx->region_type & ORT_TASK) != 0);
6621 if (struct gimplify_omp_ctx *octx = ctx->outer_context)
6623 omp_notice_variable (octx, decl, in_code);
6624 for (; octx; octx = octx->outer_context)
6626 splay_tree_node n2;
6628 n2 = splay_tree_lookup (octx->variables, (splay_tree_key) decl);
6629 if ((octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)) != 0
6630 && (n2 == NULL || (n2->value & GOVD_DATA_SHARE_CLASS) == 0))
6631 continue;
6632 if (n2 && (n2->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED)
6634 flags |= GOVD_FIRSTPRIVATE;
6635 goto found_outer;
6637 if ((octx->region_type & (ORT_PARALLEL | ORT_TEAMS)) != 0)
6639 flags |= GOVD_SHARED;
6640 goto found_outer;
6645 if (TREE_CODE (decl) == PARM_DECL
6646 || (!is_global_var (decl)
6647 && DECL_CONTEXT (decl) == current_function_decl))
6648 flags |= GOVD_FIRSTPRIVATE;
6649 else
6650 flags |= GOVD_SHARED;
6651 found_outer:
6652 break;
6654 default:
6655 gcc_unreachable ();
6658 return flags;
6662 /* Determine outer default flags for DECL mentioned in an OACC region
6663 but not declared in an enclosing clause. */
6665 static unsigned
6666 oacc_default_clause (struct gimplify_omp_ctx *ctx, tree decl, unsigned flags)
6668 const char *rkind;
6669 bool on_device = false;
6670 tree type = TREE_TYPE (decl);
6672 if (lang_hooks.decls.omp_privatize_by_reference (decl))
6673 type = TREE_TYPE (type);
6675 if ((ctx->region_type & (ORT_ACC_PARALLEL | ORT_ACC_KERNELS)) != 0
6676 && is_global_var (decl)
6677 && device_resident_p (decl))
6679 on_device = true;
6680 flags |= GOVD_MAP_TO_ONLY;
6683 switch (ctx->region_type)
6685 default:
6686 gcc_unreachable ();
6688 case ORT_ACC_KERNELS:
6689 /* Scalars are default 'copy' under kernels, non-scalars are default
6690 'present_or_copy'. */
6691 flags |= GOVD_MAP;
6692 if (!AGGREGATE_TYPE_P (type))
6693 flags |= GOVD_MAP_FORCE;
6695 rkind = "kernels";
6696 break;
6698 case ORT_ACC_PARALLEL:
6700 if (on_device || AGGREGATE_TYPE_P (type))
6701 /* Aggregates default to 'present_or_copy'. */
6702 flags |= GOVD_MAP;
6703 else
6704 /* Scalars default to 'firstprivate'. */
6705 flags |= GOVD_FIRSTPRIVATE;
6706 rkind = "parallel";
6708 break;
6711 if (DECL_ARTIFICIAL (decl))
6712 ; /* We can get compiler-generated decls, and should not complain
6713 about them. */
6714 else if (ctx->default_kind == OMP_CLAUSE_DEFAULT_NONE)
6716 error ("%qE not specified in enclosing OpenACC %qs construct",
6717 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rkind);
6718 inform (ctx->location, "enclosing OpenACC %qs construct", rkind);
6720 else
6721 gcc_checking_assert (ctx->default_kind == OMP_CLAUSE_DEFAULT_SHARED);
6723 return flags;
6726 /* Record the fact that DECL was used within the OMP context CTX.
6727 IN_CODE is true when real code uses DECL, and false when we should
6728 merely emit default(none) errors. Return true if DECL is going to
6729 be remapped and thus DECL shouldn't be gimplified into its
6730 DECL_VALUE_EXPR (if any). */
6732 static bool
6733 omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
6735 splay_tree_node n;
6736 unsigned flags = in_code ? GOVD_SEEN : 0;
6737 bool ret = false, shared;
6739 if (error_operand_p (decl))
6740 return false;
6742 if (ctx->region_type == ORT_NONE)
6743 return lang_hooks.decls.omp_disregard_value_expr (decl, false);
6745 if (is_global_var (decl))
6747 /* Threadprivate variables are predetermined. */
6748 if (DECL_THREAD_LOCAL_P (decl))
6749 return omp_notice_threadprivate_variable (ctx, decl, NULL_TREE);
6751 if (DECL_HAS_VALUE_EXPR_P (decl))
6753 tree value = get_base_address (DECL_VALUE_EXPR (decl));
6755 if (value && DECL_P (value) && DECL_THREAD_LOCAL_P (value))
6756 return omp_notice_threadprivate_variable (ctx, decl, value);
6759 if (gimplify_omp_ctxp->outer_context == NULL
6760 && VAR_P (decl)
6761 && get_oacc_fn_attrib (current_function_decl))
6763 location_t loc = DECL_SOURCE_LOCATION (decl);
6765 if (lookup_attribute ("omp declare target link",
6766 DECL_ATTRIBUTES (decl)))
6768 error_at (loc,
6769 "%qE with %<link%> clause used in %<routine%> function",
6770 DECL_NAME (decl));
6771 return false;
6773 else if (!lookup_attribute ("omp declare target",
6774 DECL_ATTRIBUTES (decl)))
6776 error_at (loc,
6777 "%qE requires a %<declare%> directive for use "
6778 "in a %<routine%> function", DECL_NAME (decl));
6779 return false;
6784 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
6785 if ((ctx->region_type & ORT_TARGET) != 0)
6787 ret = lang_hooks.decls.omp_disregard_value_expr (decl, true);
6788 if (n == NULL)
6790 unsigned nflags = flags;
6791 if (ctx->target_map_pointers_as_0len_arrays
6792 || ctx->target_map_scalars_firstprivate)
6794 bool is_declare_target = false;
6795 bool is_scalar = false;
6796 if (is_global_var (decl)
6797 && varpool_node::get_create (decl)->offloadable)
6799 struct gimplify_omp_ctx *octx;
6800 for (octx = ctx->outer_context;
6801 octx; octx = octx->outer_context)
6803 n = splay_tree_lookup (octx->variables,
6804 (splay_tree_key)decl);
6805 if (n
6806 && (n->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED
6807 && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
6808 break;
6810 is_declare_target = octx == NULL;
6812 if (!is_declare_target && ctx->target_map_scalars_firstprivate)
6814 tree type = TREE_TYPE (decl);
6815 if (TREE_CODE (type) == REFERENCE_TYPE)
6816 type = TREE_TYPE (type);
6817 if (TREE_CODE (type) == COMPLEX_TYPE)
6818 type = TREE_TYPE (type);
6819 if (INTEGRAL_TYPE_P (type)
6820 || SCALAR_FLOAT_TYPE_P (type)
6821 || TREE_CODE (type) == POINTER_TYPE)
6822 is_scalar = true;
6824 if (is_declare_target)
6826 else if (ctx->target_map_pointers_as_0len_arrays
6827 && (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
6828 || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
6829 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
6830 == POINTER_TYPE)))
6831 nflags |= GOVD_MAP | GOVD_MAP_0LEN_ARRAY;
6832 else if (is_scalar)
6833 nflags |= GOVD_FIRSTPRIVATE;
6836 struct gimplify_omp_ctx *octx = ctx->outer_context;
6837 if ((ctx->region_type & ORT_ACC) && octx)
6839 /* Look in outer OpenACC contexts, to see if there's a
6840 data attribute for this variable. */
6841 omp_notice_variable (octx, decl, in_code);
6843 for (; octx; octx = octx->outer_context)
6845 if (!(octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)))
6846 break;
6847 splay_tree_node n2
6848 = splay_tree_lookup (octx->variables,
6849 (splay_tree_key) decl);
6850 if (n2)
6852 if (octx->region_type == ORT_ACC_HOST_DATA)
6853 error ("variable %qE declared in enclosing "
6854 "%<host_data%> region", DECL_NAME (decl));
6855 nflags |= GOVD_MAP;
6856 if (octx->region_type == ORT_ACC_DATA
6857 && (n2->value & GOVD_MAP_0LEN_ARRAY))
6858 nflags |= GOVD_MAP_0LEN_ARRAY;
6859 goto found_outer;
6865 tree type = TREE_TYPE (decl);
6867 if (nflags == flags
6868 && gimplify_omp_ctxp->target_firstprivatize_array_bases
6869 && lang_hooks.decls.omp_privatize_by_reference (decl))
6870 type = TREE_TYPE (type);
6871 if (nflags == flags
6872 && !lang_hooks.types.omp_mappable_type (type))
6874 error ("%qD referenced in target region does not have "
6875 "a mappable type", decl);
6876 nflags |= GOVD_MAP | GOVD_EXPLICIT;
6878 else if (nflags == flags)
6880 if ((ctx->region_type & ORT_ACC) != 0)
6881 nflags = oacc_default_clause (ctx, decl, flags);
6882 else
6883 nflags |= GOVD_MAP;
6886 found_outer:
6887 omp_add_variable (ctx, decl, nflags);
6889 else
6891 /* If nothing changed, there's nothing left to do. */
6892 if ((n->value & flags) == flags)
6893 return ret;
6894 flags |= n->value;
6895 n->value = flags;
6897 goto do_outer;
6900 if (n == NULL)
6902 if (ctx->region_type == ORT_WORKSHARE
6903 || ctx->region_type == ORT_SIMD
6904 || ctx->region_type == ORT_ACC
6905 || (ctx->region_type & ORT_TARGET_DATA) != 0)
6906 goto do_outer;
6908 flags = omp_default_clause (ctx, decl, in_code, flags);
6910 if ((flags & GOVD_PRIVATE)
6911 && lang_hooks.decls.omp_private_outer_ref (decl))
6912 flags |= GOVD_PRIVATE_OUTER_REF;
6914 omp_add_variable (ctx, decl, flags);
6916 shared = (flags & GOVD_SHARED) != 0;
6917 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
6918 goto do_outer;
6921 if ((n->value & (GOVD_SEEN | GOVD_LOCAL)) == 0
6922 && (flags & (GOVD_SEEN | GOVD_LOCAL)) == GOVD_SEEN
6923 && DECL_SIZE (decl))
6925 if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
6927 splay_tree_node n2;
6928 tree t = DECL_VALUE_EXPR (decl);
6929 gcc_assert (TREE_CODE (t) == INDIRECT_REF);
6930 t = TREE_OPERAND (t, 0);
6931 gcc_assert (DECL_P (t));
6932 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
6933 n2->value |= GOVD_SEEN;
6935 else if (lang_hooks.decls.omp_privatize_by_reference (decl)
6936 && TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)))
6937 && (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))))
6938 != INTEGER_CST))
6940 splay_tree_node n2;
6941 tree t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
6942 gcc_assert (DECL_P (t));
6943 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
6944 if (n2)
6945 n2->value |= GOVD_SEEN;
6949 shared = ((flags | n->value) & GOVD_SHARED) != 0;
6950 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
6952 /* If nothing changed, there's nothing left to do. */
6953 if ((n->value & flags) == flags)
6954 return ret;
6955 flags |= n->value;
6956 n->value = flags;
6958 do_outer:
6959 /* If the variable is private in the current context, then we don't
6960 need to propagate anything to an outer context. */
6961 if ((flags & GOVD_PRIVATE) && !(flags & GOVD_PRIVATE_OUTER_REF))
6962 return ret;
6963 if ((flags & (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
6964 == (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
6965 return ret;
6966 if ((flags & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
6967 | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
6968 == (GOVD_LASTPRIVATE | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
6969 return ret;
6970 if (ctx->outer_context
6971 && omp_notice_variable (ctx->outer_context, decl, in_code))
6972 return true;
6973 return ret;
6976 /* Verify that DECL is private within CTX. If there's specific information
6977 to the contrary in the innermost scope, generate an error. */
6979 static bool
6980 omp_is_private (struct gimplify_omp_ctx *ctx, tree decl, int simd)
6982 splay_tree_node n;
6984 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
6985 if (n != NULL)
6987 if (n->value & GOVD_SHARED)
6989 if (ctx == gimplify_omp_ctxp)
6991 if (simd)
6992 error ("iteration variable %qE is predetermined linear",
6993 DECL_NAME (decl));
6994 else
6995 error ("iteration variable %qE should be private",
6996 DECL_NAME (decl));
6997 n->value = GOVD_PRIVATE;
6998 return true;
7000 else
7001 return false;
7003 else if ((n->value & GOVD_EXPLICIT) != 0
7004 && (ctx == gimplify_omp_ctxp
7005 || (ctx->region_type == ORT_COMBINED_PARALLEL
7006 && gimplify_omp_ctxp->outer_context == ctx)))
7008 if ((n->value & GOVD_FIRSTPRIVATE) != 0)
7009 error ("iteration variable %qE should not be firstprivate",
7010 DECL_NAME (decl));
7011 else if ((n->value & GOVD_REDUCTION) != 0)
7012 error ("iteration variable %qE should not be reduction",
7013 DECL_NAME (decl));
7014 else if (simd == 0 && (n->value & GOVD_LINEAR) != 0)
7015 error ("iteration variable %qE should not be linear",
7016 DECL_NAME (decl));
7017 else if (simd == 1 && (n->value & GOVD_LASTPRIVATE) != 0)
7018 error ("iteration variable %qE should not be lastprivate",
7019 DECL_NAME (decl));
7020 else if (simd && (n->value & GOVD_PRIVATE) != 0)
7021 error ("iteration variable %qE should not be private",
7022 DECL_NAME (decl));
7023 else if (simd == 2 && (n->value & GOVD_LINEAR) != 0)
7024 error ("iteration variable %qE is predetermined linear",
7025 DECL_NAME (decl));
7027 return (ctx == gimplify_omp_ctxp
7028 || (ctx->region_type == ORT_COMBINED_PARALLEL
7029 && gimplify_omp_ctxp->outer_context == ctx));
7032 if (ctx->region_type != ORT_WORKSHARE
7033 && ctx->region_type != ORT_SIMD
7034 && ctx->region_type != ORT_ACC)
7035 return false;
7036 else if (ctx->outer_context)
7037 return omp_is_private (ctx->outer_context, decl, simd);
7038 return false;
7041 /* Return true if DECL is private within a parallel region
7042 that binds to the current construct's context or in parallel
7043 region's REDUCTION clause. */
7045 static bool
7046 omp_check_private (struct gimplify_omp_ctx *ctx, tree decl, bool copyprivate)
7048 splay_tree_node n;
7052 ctx = ctx->outer_context;
7053 if (ctx == NULL)
7055 if (is_global_var (decl))
7056 return false;
7058 /* References might be private, but might be shared too,
7059 when checking for copyprivate, assume they might be
7060 private, otherwise assume they might be shared. */
7061 if (copyprivate)
7062 return true;
7064 if (lang_hooks.decls.omp_privatize_by_reference (decl))
7065 return false;
7067 /* Treat C++ privatized non-static data members outside
7068 of the privatization the same. */
7069 if (omp_member_access_dummy_var (decl))
7070 return false;
7072 return true;
7075 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
7077 if ((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
7078 && (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0))
7079 continue;
7081 if (n != NULL)
7083 if ((n->value & GOVD_LOCAL) != 0
7084 && omp_member_access_dummy_var (decl))
7085 return false;
7086 return (n->value & GOVD_SHARED) == 0;
7089 while (ctx->region_type == ORT_WORKSHARE
7090 || ctx->region_type == ORT_SIMD
7091 || ctx->region_type == ORT_ACC);
7092 return false;
7095 /* Return true if the CTX is combined with distribute and thus
7096 lastprivate can't be supported. */
7098 static bool
7099 omp_no_lastprivate (struct gimplify_omp_ctx *ctx)
7103 if (ctx->outer_context == NULL)
7104 return false;
7105 ctx = ctx->outer_context;
7106 switch (ctx->region_type)
7108 case ORT_WORKSHARE:
7109 if (!ctx->combined_loop)
7110 return false;
7111 if (ctx->distribute)
7112 return lang_GNU_Fortran ();
7113 break;
7114 case ORT_COMBINED_PARALLEL:
7115 break;
7116 case ORT_COMBINED_TEAMS:
7117 return lang_GNU_Fortran ();
7118 default:
7119 return false;
7122 while (1);
7125 /* Callback for walk_tree to find a DECL_EXPR for the given DECL. */
7127 static tree
7128 find_decl_expr (tree *tp, int *walk_subtrees, void *data)
7130 tree t = *tp;
7132 /* If this node has been visited, unmark it and keep looking. */
7133 if (TREE_CODE (t) == DECL_EXPR && DECL_EXPR_DECL (t) == (tree) data)
7134 return t;
7136 if (IS_TYPE_OR_DECL_P (t))
7137 *walk_subtrees = 0;
7138 return NULL_TREE;
7141 /* Scan the OMP clauses in *LIST_P, installing mappings into a new
7142 and previous omp contexts. */
7144 static void
7145 gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
7146 enum omp_region_type region_type,
7147 enum tree_code code)
7149 struct gimplify_omp_ctx *ctx, *outer_ctx;
7150 tree c;
7151 hash_map<tree, tree> *struct_map_to_clause = NULL;
7152 tree *prev_list_p = NULL;
7154 ctx = new_omp_context (region_type);
7155 outer_ctx = ctx->outer_context;
7156 if (code == OMP_TARGET && !lang_GNU_Fortran ())
7158 ctx->target_map_pointers_as_0len_arrays = true;
7159 /* FIXME: For Fortran we want to set this too, when
7160 the Fortran FE is updated to OpenMP 4.5. */
7161 ctx->target_map_scalars_firstprivate = true;
7163 if (!lang_GNU_Fortran ())
7164 switch (code)
7166 case OMP_TARGET:
7167 case OMP_TARGET_DATA:
7168 case OMP_TARGET_ENTER_DATA:
7169 case OMP_TARGET_EXIT_DATA:
7170 case OACC_HOST_DATA:
7171 ctx->target_firstprivatize_array_bases = true;
7172 default:
7173 break;
7176 while ((c = *list_p) != NULL)
7178 bool remove = false;
7179 bool notice_outer = true;
7180 const char *check_non_private = NULL;
7181 unsigned int flags;
7182 tree decl;
7184 switch (OMP_CLAUSE_CODE (c))
7186 case OMP_CLAUSE_PRIVATE:
7187 flags = GOVD_PRIVATE | GOVD_EXPLICIT;
7188 if (lang_hooks.decls.omp_private_outer_ref (OMP_CLAUSE_DECL (c)))
7190 flags |= GOVD_PRIVATE_OUTER_REF;
7191 OMP_CLAUSE_PRIVATE_OUTER_REF (c) = 1;
7193 else
7194 notice_outer = false;
7195 goto do_add;
7196 case OMP_CLAUSE_SHARED:
7197 flags = GOVD_SHARED | GOVD_EXPLICIT;
7198 goto do_add;
7199 case OMP_CLAUSE_FIRSTPRIVATE:
7200 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
7201 check_non_private = "firstprivate";
7202 goto do_add;
7203 case OMP_CLAUSE_LASTPRIVATE:
7204 flags = GOVD_LASTPRIVATE | GOVD_SEEN | GOVD_EXPLICIT;
7205 check_non_private = "lastprivate";
7206 decl = OMP_CLAUSE_DECL (c);
7207 if (omp_no_lastprivate (ctx))
7209 notice_outer = false;
7210 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
7212 else if (error_operand_p (decl))
7213 goto do_add;
7214 else if (outer_ctx
7215 && (outer_ctx->region_type == ORT_COMBINED_PARALLEL
7216 || outer_ctx->region_type == ORT_COMBINED_TEAMS)
7217 && splay_tree_lookup (outer_ctx->variables,
7218 (splay_tree_key) decl) == NULL)
7220 omp_add_variable (outer_ctx, decl, GOVD_SHARED | GOVD_SEEN);
7221 if (outer_ctx->outer_context)
7222 omp_notice_variable (outer_ctx->outer_context, decl, true);
7224 else if (outer_ctx
7225 && (outer_ctx->region_type & ORT_TASK) != 0
7226 && outer_ctx->combined_loop
7227 && splay_tree_lookup (outer_ctx->variables,
7228 (splay_tree_key) decl) == NULL)
7230 omp_add_variable (outer_ctx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
7231 if (outer_ctx->outer_context)
7232 omp_notice_variable (outer_ctx->outer_context, decl, true);
7234 else if (outer_ctx
7235 && (outer_ctx->region_type == ORT_WORKSHARE
7236 || outer_ctx->region_type == ORT_ACC)
7237 && outer_ctx->combined_loop
7238 && splay_tree_lookup (outer_ctx->variables,
7239 (splay_tree_key) decl) == NULL
7240 && !omp_check_private (outer_ctx, decl, false))
7242 omp_add_variable (outer_ctx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
7243 if (outer_ctx->outer_context
7244 && (outer_ctx->outer_context->region_type
7245 == ORT_COMBINED_PARALLEL)
7246 && splay_tree_lookup (outer_ctx->outer_context->variables,
7247 (splay_tree_key) decl) == NULL)
7249 struct gimplify_omp_ctx *octx = outer_ctx->outer_context;
7250 omp_add_variable (octx, decl, GOVD_SHARED | GOVD_SEEN);
7251 if (octx->outer_context)
7252 omp_notice_variable (octx->outer_context, decl, true);
7254 else if (outer_ctx->outer_context)
7255 omp_notice_variable (outer_ctx->outer_context, decl, true);
7257 goto do_add;
7258 case OMP_CLAUSE_REDUCTION:
7259 flags = GOVD_REDUCTION | GOVD_SEEN | GOVD_EXPLICIT;
7260 /* OpenACC permits reductions on private variables. */
7261 if (!(region_type & ORT_ACC))
7262 check_non_private = "reduction";
7263 decl = OMP_CLAUSE_DECL (c);
7264 if (TREE_CODE (decl) == MEM_REF)
7266 tree type = TREE_TYPE (decl);
7267 if (gimplify_expr (&TYPE_MAX_VALUE (TYPE_DOMAIN (type)), pre_p,
7268 NULL, is_gimple_val, fb_rvalue, false)
7269 == GS_ERROR)
7271 remove = true;
7272 break;
7274 tree v = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
7275 if (DECL_P (v))
7277 omp_firstprivatize_variable (ctx, v);
7278 omp_notice_variable (ctx, v, true);
7280 decl = TREE_OPERAND (decl, 0);
7281 if (TREE_CODE (decl) == POINTER_PLUS_EXPR)
7283 if (gimplify_expr (&TREE_OPERAND (decl, 1), pre_p,
7284 NULL, is_gimple_val, fb_rvalue, false)
7285 == GS_ERROR)
7287 remove = true;
7288 break;
7290 v = TREE_OPERAND (decl, 1);
7291 if (DECL_P (v))
7293 omp_firstprivatize_variable (ctx, v);
7294 omp_notice_variable (ctx, v, true);
7296 decl = TREE_OPERAND (decl, 0);
7298 if (TREE_CODE (decl) == ADDR_EXPR
7299 || TREE_CODE (decl) == INDIRECT_REF)
7300 decl = TREE_OPERAND (decl, 0);
7302 goto do_add_decl;
7303 case OMP_CLAUSE_LINEAR:
7304 if (gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c), pre_p, NULL,
7305 is_gimple_val, fb_rvalue) == GS_ERROR)
7307 remove = true;
7308 break;
7310 else
7312 if (code == OMP_SIMD
7313 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
7315 struct gimplify_omp_ctx *octx = outer_ctx;
7316 if (octx
7317 && octx->region_type == ORT_WORKSHARE
7318 && octx->combined_loop
7319 && !octx->distribute)
7321 if (octx->outer_context
7322 && (octx->outer_context->region_type
7323 == ORT_COMBINED_PARALLEL))
7324 octx = octx->outer_context->outer_context;
7325 else
7326 octx = octx->outer_context;
7328 if (octx
7329 && octx->region_type == ORT_WORKSHARE
7330 && octx->combined_loop
7331 && octx->distribute
7332 && !lang_GNU_Fortran ())
7334 error_at (OMP_CLAUSE_LOCATION (c),
7335 "%<linear%> clause for variable other than "
7336 "loop iterator specified on construct "
7337 "combined with %<distribute%>");
7338 remove = true;
7339 break;
7342 /* For combined #pragma omp parallel for simd, need to put
7343 lastprivate and perhaps firstprivate too on the
7344 parallel. Similarly for #pragma omp for simd. */
7345 struct gimplify_omp_ctx *octx = outer_ctx;
7346 decl = NULL_TREE;
7347 if (omp_no_lastprivate (ctx))
7348 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
7351 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
7352 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
7353 break;
7354 decl = OMP_CLAUSE_DECL (c);
7355 if (error_operand_p (decl))
7357 decl = NULL_TREE;
7358 break;
7360 flags = GOVD_SEEN;
7361 if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c))
7362 flags |= GOVD_FIRSTPRIVATE;
7363 if (!OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
7364 flags |= GOVD_LASTPRIVATE;
7365 if (octx
7366 && octx->region_type == ORT_WORKSHARE
7367 && octx->combined_loop)
7369 if (octx->outer_context
7370 && (octx->outer_context->region_type
7371 == ORT_COMBINED_PARALLEL))
7372 octx = octx->outer_context;
7373 else if (omp_check_private (octx, decl, false))
7374 break;
7376 else if (octx
7377 && (octx->region_type & ORT_TASK) != 0
7378 && octx->combined_loop)
7380 else if (octx
7381 && octx->region_type == ORT_COMBINED_PARALLEL
7382 && ctx->region_type == ORT_WORKSHARE
7383 && octx == outer_ctx)
7384 flags = GOVD_SEEN | GOVD_SHARED;
7385 else if (octx
7386 && octx->region_type == ORT_COMBINED_TEAMS)
7387 flags = GOVD_SEEN | GOVD_SHARED;
7388 else if (octx
7389 && octx->region_type == ORT_COMBINED_TARGET)
7391 flags &= ~GOVD_LASTPRIVATE;
7392 if (flags == GOVD_SEEN)
7393 break;
7395 else
7396 break;
7397 splay_tree_node on
7398 = splay_tree_lookup (octx->variables,
7399 (splay_tree_key) decl);
7400 if (on && (on->value & GOVD_DATA_SHARE_CLASS) != 0)
7402 octx = NULL;
7403 break;
7405 omp_add_variable (octx, decl, flags);
7406 if (octx->outer_context == NULL)
7407 break;
7408 octx = octx->outer_context;
7410 while (1);
7411 if (octx
7412 && decl
7413 && (!OMP_CLAUSE_LINEAR_NO_COPYIN (c)
7414 || !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
7415 omp_notice_variable (octx, decl, true);
7417 flags = GOVD_LINEAR | GOVD_EXPLICIT;
7418 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
7419 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
7421 notice_outer = false;
7422 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
7424 goto do_add;
7426 case OMP_CLAUSE_MAP:
7427 decl = OMP_CLAUSE_DECL (c);
7428 if (error_operand_p (decl))
7429 remove = true;
7430 switch (code)
7432 case OMP_TARGET:
7433 break;
7434 case OACC_DATA:
7435 if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
7436 break;
7437 /* FALLTHRU */
7438 case OMP_TARGET_DATA:
7439 case OMP_TARGET_ENTER_DATA:
7440 case OMP_TARGET_EXIT_DATA:
7441 case OACC_ENTER_DATA:
7442 case OACC_EXIT_DATA:
7443 case OACC_HOST_DATA:
7444 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
7445 || (OMP_CLAUSE_MAP_KIND (c)
7446 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
7447 /* For target {,enter ,exit }data only the array slice is
7448 mapped, but not the pointer to it. */
7449 remove = true;
7450 break;
7451 default:
7452 break;
7454 if (remove)
7455 break;
7456 if (DECL_P (decl) && outer_ctx && (region_type & ORT_ACC))
7458 struct gimplify_omp_ctx *octx;
7459 for (octx = outer_ctx; octx; octx = octx->outer_context)
7461 if (octx->region_type != ORT_ACC_HOST_DATA)
7462 break;
7463 splay_tree_node n2
7464 = splay_tree_lookup (octx->variables,
7465 (splay_tree_key) decl);
7466 if (n2)
7467 error_at (OMP_CLAUSE_LOCATION (c), "variable %qE "
7468 "declared in enclosing %<host_data%> region",
7469 DECL_NAME (decl));
7472 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
7473 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
7474 : TYPE_SIZE_UNIT (TREE_TYPE (decl));
7475 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
7476 NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
7478 remove = true;
7479 break;
7481 else if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
7482 || (OMP_CLAUSE_MAP_KIND (c)
7483 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
7484 && TREE_CODE (OMP_CLAUSE_SIZE (c)) != INTEGER_CST)
7486 OMP_CLAUSE_SIZE (c)
7487 = get_initialized_tmp_var (OMP_CLAUSE_SIZE (c), pre_p, NULL,
7488 false);
7489 omp_add_variable (ctx, OMP_CLAUSE_SIZE (c),
7490 GOVD_FIRSTPRIVATE | GOVD_SEEN);
7492 if (!DECL_P (decl))
7494 tree d = decl, *pd;
7495 if (TREE_CODE (d) == ARRAY_REF)
7497 while (TREE_CODE (d) == ARRAY_REF)
7498 d = TREE_OPERAND (d, 0);
7499 if (TREE_CODE (d) == COMPONENT_REF
7500 && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE)
7501 decl = d;
7503 pd = &OMP_CLAUSE_DECL (c);
7504 if (d == decl
7505 && TREE_CODE (decl) == INDIRECT_REF
7506 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
7507 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
7508 == REFERENCE_TYPE))
7510 pd = &TREE_OPERAND (decl, 0);
7511 decl = TREE_OPERAND (decl, 0);
7513 if (TREE_CODE (decl) == COMPONENT_REF)
7515 while (TREE_CODE (decl) == COMPONENT_REF)
7516 decl = TREE_OPERAND (decl, 0);
7517 if (TREE_CODE (decl) == INDIRECT_REF
7518 && DECL_P (TREE_OPERAND (decl, 0))
7519 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
7520 == REFERENCE_TYPE))
7521 decl = TREE_OPERAND (decl, 0);
7523 if (gimplify_expr (pd, pre_p, NULL, is_gimple_lvalue, fb_lvalue)
7524 == GS_ERROR)
7526 remove = true;
7527 break;
7529 if (DECL_P (decl))
7531 if (error_operand_p (decl))
7533 remove = true;
7534 break;
7537 tree stype = TREE_TYPE (decl);
7538 if (TREE_CODE (stype) == REFERENCE_TYPE)
7539 stype = TREE_TYPE (stype);
7540 if (TYPE_SIZE_UNIT (stype) == NULL
7541 || TREE_CODE (TYPE_SIZE_UNIT (stype)) != INTEGER_CST)
7543 error_at (OMP_CLAUSE_LOCATION (c),
7544 "mapping field %qE of variable length "
7545 "structure", OMP_CLAUSE_DECL (c));
7546 remove = true;
7547 break;
7550 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER)
7552 /* Error recovery. */
7553 if (prev_list_p == NULL)
7555 remove = true;
7556 break;
7558 if (OMP_CLAUSE_CHAIN (*prev_list_p) != c)
7560 tree ch = OMP_CLAUSE_CHAIN (*prev_list_p);
7561 if (ch == NULL_TREE || OMP_CLAUSE_CHAIN (ch) != c)
7563 remove = true;
7564 break;
7569 tree offset;
7570 HOST_WIDE_INT bitsize, bitpos;
7571 machine_mode mode;
7572 int unsignedp, reversep, volatilep = 0;
7573 tree base = OMP_CLAUSE_DECL (c);
7574 while (TREE_CODE (base) == ARRAY_REF)
7575 base = TREE_OPERAND (base, 0);
7576 if (TREE_CODE (base) == INDIRECT_REF)
7577 base = TREE_OPERAND (base, 0);
7578 base = get_inner_reference (base, &bitsize, &bitpos, &offset,
7579 &mode, &unsignedp, &reversep,
7580 &volatilep);
7581 tree orig_base = base;
7582 if ((TREE_CODE (base) == INDIRECT_REF
7583 || (TREE_CODE (base) == MEM_REF
7584 && integer_zerop (TREE_OPERAND (base, 1))))
7585 && DECL_P (TREE_OPERAND (base, 0))
7586 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0)))
7587 == REFERENCE_TYPE))
7588 base = TREE_OPERAND (base, 0);
7589 gcc_assert (base == decl
7590 && (offset == NULL_TREE
7591 || TREE_CODE (offset) == INTEGER_CST));
7593 splay_tree_node n
7594 = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7595 bool ptr = (OMP_CLAUSE_MAP_KIND (c)
7596 == GOMP_MAP_ALWAYS_POINTER);
7597 if (n == NULL || (n->value & GOVD_MAP) == 0)
7599 tree l = build_omp_clause (OMP_CLAUSE_LOCATION (c),
7600 OMP_CLAUSE_MAP);
7601 OMP_CLAUSE_SET_MAP_KIND (l, GOMP_MAP_STRUCT);
7602 if (orig_base != base)
7603 OMP_CLAUSE_DECL (l) = unshare_expr (orig_base);
7604 else
7605 OMP_CLAUSE_DECL (l) = decl;
7606 OMP_CLAUSE_SIZE (l) = size_int (1);
7607 if (struct_map_to_clause == NULL)
7608 struct_map_to_clause = new hash_map<tree, tree>;
7609 struct_map_to_clause->put (decl, l);
7610 if (ptr)
7612 enum gomp_map_kind mkind
7613 = code == OMP_TARGET_EXIT_DATA
7614 ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
7615 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
7616 OMP_CLAUSE_MAP);
7617 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
7618 OMP_CLAUSE_DECL (c2)
7619 = unshare_expr (OMP_CLAUSE_DECL (c));
7620 OMP_CLAUSE_CHAIN (c2) = *prev_list_p;
7621 OMP_CLAUSE_SIZE (c2)
7622 = TYPE_SIZE_UNIT (ptr_type_node);
7623 OMP_CLAUSE_CHAIN (l) = c2;
7624 if (OMP_CLAUSE_CHAIN (*prev_list_p) != c)
7626 tree c4 = OMP_CLAUSE_CHAIN (*prev_list_p);
7627 tree c3
7628 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
7629 OMP_CLAUSE_MAP);
7630 OMP_CLAUSE_SET_MAP_KIND (c3, mkind);
7631 OMP_CLAUSE_DECL (c3)
7632 = unshare_expr (OMP_CLAUSE_DECL (c4));
7633 OMP_CLAUSE_SIZE (c3)
7634 = TYPE_SIZE_UNIT (ptr_type_node);
7635 OMP_CLAUSE_CHAIN (c3) = *prev_list_p;
7636 OMP_CLAUSE_CHAIN (c2) = c3;
7638 *prev_list_p = l;
7639 prev_list_p = NULL;
7641 else
7643 OMP_CLAUSE_CHAIN (l) = c;
7644 *list_p = l;
7645 list_p = &OMP_CLAUSE_CHAIN (l);
7647 if (orig_base != base && code == OMP_TARGET)
7649 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
7650 OMP_CLAUSE_MAP);
7651 enum gomp_map_kind mkind
7652 = GOMP_MAP_FIRSTPRIVATE_REFERENCE;
7653 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
7654 OMP_CLAUSE_DECL (c2) = decl;
7655 OMP_CLAUSE_SIZE (c2) = size_zero_node;
7656 OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (l);
7657 OMP_CLAUSE_CHAIN (l) = c2;
7659 flags = GOVD_MAP | GOVD_EXPLICIT;
7660 if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) || ptr)
7661 flags |= GOVD_SEEN;
7662 goto do_add_decl;
7664 else
7666 tree *osc = struct_map_to_clause->get (decl);
7667 tree *sc = NULL, *scp = NULL;
7668 if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) || ptr)
7669 n->value |= GOVD_SEEN;
7670 offset_int o1, o2;
7671 if (offset)
7672 o1 = wi::to_offset (offset);
7673 else
7674 o1 = 0;
7675 if (bitpos)
7676 o1 = o1 + bitpos / BITS_PER_UNIT;
7677 sc = &OMP_CLAUSE_CHAIN (*osc);
7678 if (*sc != c
7679 && (OMP_CLAUSE_MAP_KIND (*sc)
7680 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
7681 sc = &OMP_CLAUSE_CHAIN (*sc);
7682 for (; *sc != c; sc = &OMP_CLAUSE_CHAIN (*sc))
7683 if (ptr && sc == prev_list_p)
7684 break;
7685 else if (TREE_CODE (OMP_CLAUSE_DECL (*sc))
7686 != COMPONENT_REF
7687 && (TREE_CODE (OMP_CLAUSE_DECL (*sc))
7688 != INDIRECT_REF)
7689 && (TREE_CODE (OMP_CLAUSE_DECL (*sc))
7690 != ARRAY_REF))
7691 break;
7692 else
7694 tree offset2;
7695 HOST_WIDE_INT bitsize2, bitpos2;
7696 base = OMP_CLAUSE_DECL (*sc);
7697 if (TREE_CODE (base) == ARRAY_REF)
7699 while (TREE_CODE (base) == ARRAY_REF)
7700 base = TREE_OPERAND (base, 0);
7701 if (TREE_CODE (base) != COMPONENT_REF
7702 || (TREE_CODE (TREE_TYPE (base))
7703 != ARRAY_TYPE))
7704 break;
7706 else if (TREE_CODE (base) == INDIRECT_REF
7707 && (TREE_CODE (TREE_OPERAND (base, 0))
7708 == COMPONENT_REF)
7709 && (TREE_CODE (TREE_TYPE
7710 (TREE_OPERAND (base, 0)))
7711 == REFERENCE_TYPE))
7712 base = TREE_OPERAND (base, 0);
7713 base = get_inner_reference (base, &bitsize2,
7714 &bitpos2, &offset2,
7715 &mode, &unsignedp,
7716 &reversep, &volatilep);
7717 if ((TREE_CODE (base) == INDIRECT_REF
7718 || (TREE_CODE (base) == MEM_REF
7719 && integer_zerop (TREE_OPERAND (base,
7720 1))))
7721 && DECL_P (TREE_OPERAND (base, 0))
7722 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (base,
7723 0)))
7724 == REFERENCE_TYPE))
7725 base = TREE_OPERAND (base, 0);
7726 if (base != decl)
7727 break;
7728 if (scp)
7729 continue;
7730 gcc_assert (offset == NULL_TREE
7731 || TREE_CODE (offset) == INTEGER_CST);
7732 tree d1 = OMP_CLAUSE_DECL (*sc);
7733 tree d2 = OMP_CLAUSE_DECL (c);
7734 while (TREE_CODE (d1) == ARRAY_REF)
7735 d1 = TREE_OPERAND (d1, 0);
7736 while (TREE_CODE (d2) == ARRAY_REF)
7737 d2 = TREE_OPERAND (d2, 0);
7738 if (TREE_CODE (d1) == INDIRECT_REF)
7739 d1 = TREE_OPERAND (d1, 0);
7740 if (TREE_CODE (d2) == INDIRECT_REF)
7741 d2 = TREE_OPERAND (d2, 0);
7742 while (TREE_CODE (d1) == COMPONENT_REF)
7743 if (TREE_CODE (d2) == COMPONENT_REF
7744 && TREE_OPERAND (d1, 1)
7745 == TREE_OPERAND (d2, 1))
7747 d1 = TREE_OPERAND (d1, 0);
7748 d2 = TREE_OPERAND (d2, 0);
7750 else
7751 break;
7752 if (d1 == d2)
7754 error_at (OMP_CLAUSE_LOCATION (c),
7755 "%qE appears more than once in map "
7756 "clauses", OMP_CLAUSE_DECL (c));
7757 remove = true;
7758 break;
7760 if (offset2)
7761 o2 = wi::to_offset (offset2);
7762 else
7763 o2 = 0;
7764 if (bitpos2)
7765 o2 = o2 + bitpos2 / BITS_PER_UNIT;
7766 if (wi::ltu_p (o1, o2)
7767 || (wi::eq_p (o1, o2) && bitpos < bitpos2))
7769 if (ptr)
7770 scp = sc;
7771 else
7772 break;
7775 if (remove)
7776 break;
7777 OMP_CLAUSE_SIZE (*osc)
7778 = size_binop (PLUS_EXPR, OMP_CLAUSE_SIZE (*osc),
7779 size_one_node);
7780 if (ptr)
7782 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
7783 OMP_CLAUSE_MAP);
7784 tree cl = NULL_TREE;
7785 enum gomp_map_kind mkind
7786 = code == OMP_TARGET_EXIT_DATA
7787 ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
7788 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
7789 OMP_CLAUSE_DECL (c2)
7790 = unshare_expr (OMP_CLAUSE_DECL (c));
7791 OMP_CLAUSE_CHAIN (c2) = scp ? *scp : *prev_list_p;
7792 OMP_CLAUSE_SIZE (c2)
7793 = TYPE_SIZE_UNIT (ptr_type_node);
7794 cl = scp ? *prev_list_p : c2;
7795 if (OMP_CLAUSE_CHAIN (*prev_list_p) != c)
7797 tree c4 = OMP_CLAUSE_CHAIN (*prev_list_p);
7798 tree c3
7799 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
7800 OMP_CLAUSE_MAP);
7801 OMP_CLAUSE_SET_MAP_KIND (c3, mkind);
7802 OMP_CLAUSE_DECL (c3)
7803 = unshare_expr (OMP_CLAUSE_DECL (c4));
7804 OMP_CLAUSE_SIZE (c3)
7805 = TYPE_SIZE_UNIT (ptr_type_node);
7806 OMP_CLAUSE_CHAIN (c3) = *prev_list_p;
7807 if (!scp)
7808 OMP_CLAUSE_CHAIN (c2) = c3;
7809 else
7810 cl = c3;
7812 if (scp)
7813 *scp = c2;
7814 if (sc == prev_list_p)
7816 *sc = cl;
7817 prev_list_p = NULL;
7819 else
7821 *prev_list_p = OMP_CLAUSE_CHAIN (c);
7822 list_p = prev_list_p;
7823 prev_list_p = NULL;
7824 OMP_CLAUSE_CHAIN (c) = *sc;
7825 *sc = cl;
7826 continue;
7829 else if (*sc != c)
7831 *list_p = OMP_CLAUSE_CHAIN (c);
7832 OMP_CLAUSE_CHAIN (c) = *sc;
7833 *sc = c;
7834 continue;
7838 if (!remove
7839 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_POINTER
7840 && OMP_CLAUSE_CHAIN (c)
7841 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (c)) == OMP_CLAUSE_MAP
7842 && (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
7843 == GOMP_MAP_ALWAYS_POINTER))
7844 prev_list_p = list_p;
7845 break;
7847 flags = GOVD_MAP | GOVD_EXPLICIT;
7848 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TO
7849 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TOFROM)
7850 flags |= GOVD_MAP_ALWAYS_TO;
7851 goto do_add;
7853 case OMP_CLAUSE_DEPEND:
7854 if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK
7855 || OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
7857 /* Nothing to do. OMP_CLAUSE_DECL will be lowered in
7858 omp-low.c. */
7859 break;
7861 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
7863 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
7864 NULL, is_gimple_val, fb_rvalue);
7865 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
7867 if (error_operand_p (OMP_CLAUSE_DECL (c)))
7869 remove = true;
7870 break;
7872 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
7873 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
7874 is_gimple_val, fb_rvalue) == GS_ERROR)
7876 remove = true;
7877 break;
7879 break;
7881 case OMP_CLAUSE_TO:
7882 case OMP_CLAUSE_FROM:
7883 case OMP_CLAUSE__CACHE_:
7884 decl = OMP_CLAUSE_DECL (c);
7885 if (error_operand_p (decl))
7887 remove = true;
7888 break;
7890 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
7891 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
7892 : TYPE_SIZE_UNIT (TREE_TYPE (decl));
7893 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
7894 NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
7896 remove = true;
7897 break;
7899 if (!DECL_P (decl))
7901 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p,
7902 NULL, is_gimple_lvalue, fb_lvalue)
7903 == GS_ERROR)
7905 remove = true;
7906 break;
7908 break;
7910 goto do_notice;
7912 case OMP_CLAUSE_USE_DEVICE_PTR:
7913 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
7914 goto do_add;
7915 case OMP_CLAUSE_IS_DEVICE_PTR:
7916 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
7917 goto do_add;
7919 do_add:
7920 decl = OMP_CLAUSE_DECL (c);
7921 do_add_decl:
7922 if (error_operand_p (decl))
7924 remove = true;
7925 break;
7927 if (DECL_NAME (decl) == NULL_TREE && (flags & GOVD_SHARED) == 0)
7929 tree t = omp_member_access_dummy_var (decl);
7930 if (t)
7932 tree v = DECL_VALUE_EXPR (decl);
7933 DECL_NAME (decl) = DECL_NAME (TREE_OPERAND (v, 1));
7934 if (outer_ctx)
7935 omp_notice_variable (outer_ctx, t, true);
7938 if (code == OACC_DATA
7939 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
7940 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
7941 flags |= GOVD_MAP_0LEN_ARRAY;
7942 omp_add_variable (ctx, decl, flags);
7943 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
7944 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
7946 omp_add_variable (ctx, OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
7947 GOVD_LOCAL | GOVD_SEEN);
7948 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
7949 && walk_tree (&OMP_CLAUSE_REDUCTION_INIT (c),
7950 find_decl_expr,
7951 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
7952 NULL) == NULL_TREE)
7953 omp_add_variable (ctx,
7954 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
7955 GOVD_LOCAL | GOVD_SEEN);
7956 gimplify_omp_ctxp = ctx;
7957 push_gimplify_context ();
7959 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
7960 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
7962 gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c),
7963 &OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c));
7964 pop_gimplify_context
7965 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c)));
7966 push_gimplify_context ();
7967 gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c),
7968 &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
7969 pop_gimplify_context
7970 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c)));
7971 OMP_CLAUSE_REDUCTION_INIT (c) = NULL_TREE;
7972 OMP_CLAUSE_REDUCTION_MERGE (c) = NULL_TREE;
7974 gimplify_omp_ctxp = outer_ctx;
7976 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
7977 && OMP_CLAUSE_LASTPRIVATE_STMT (c))
7979 gimplify_omp_ctxp = ctx;
7980 push_gimplify_context ();
7981 if (TREE_CODE (OMP_CLAUSE_LASTPRIVATE_STMT (c)) != BIND_EXPR)
7983 tree bind = build3 (BIND_EXPR, void_type_node, NULL,
7984 NULL, NULL);
7985 TREE_SIDE_EFFECTS (bind) = 1;
7986 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LASTPRIVATE_STMT (c);
7987 OMP_CLAUSE_LASTPRIVATE_STMT (c) = bind;
7989 gimplify_and_add (OMP_CLAUSE_LASTPRIVATE_STMT (c),
7990 &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
7991 pop_gimplify_context
7992 (gimple_seq_first_stmt (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c)));
7993 OMP_CLAUSE_LASTPRIVATE_STMT (c) = NULL_TREE;
7995 gimplify_omp_ctxp = outer_ctx;
7997 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
7998 && OMP_CLAUSE_LINEAR_STMT (c))
8000 gimplify_omp_ctxp = ctx;
8001 push_gimplify_context ();
8002 if (TREE_CODE (OMP_CLAUSE_LINEAR_STMT (c)) != BIND_EXPR)
8004 tree bind = build3 (BIND_EXPR, void_type_node, NULL,
8005 NULL, NULL);
8006 TREE_SIDE_EFFECTS (bind) = 1;
8007 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LINEAR_STMT (c);
8008 OMP_CLAUSE_LINEAR_STMT (c) = bind;
8010 gimplify_and_add (OMP_CLAUSE_LINEAR_STMT (c),
8011 &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c));
8012 pop_gimplify_context
8013 (gimple_seq_first_stmt (OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c)));
8014 OMP_CLAUSE_LINEAR_STMT (c) = NULL_TREE;
8016 gimplify_omp_ctxp = outer_ctx;
8018 if (notice_outer)
8019 goto do_notice;
8020 break;
8022 case OMP_CLAUSE_COPYIN:
8023 case OMP_CLAUSE_COPYPRIVATE:
8024 decl = OMP_CLAUSE_DECL (c);
8025 if (error_operand_p (decl))
8027 remove = true;
8028 break;
8030 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_COPYPRIVATE
8031 && !remove
8032 && !omp_check_private (ctx, decl, true))
8034 remove = true;
8035 if (is_global_var (decl))
8037 if (DECL_THREAD_LOCAL_P (decl))
8038 remove = false;
8039 else if (DECL_HAS_VALUE_EXPR_P (decl))
8041 tree value = get_base_address (DECL_VALUE_EXPR (decl));
8043 if (value
8044 && DECL_P (value)
8045 && DECL_THREAD_LOCAL_P (value))
8046 remove = false;
8049 if (remove)
8050 error_at (OMP_CLAUSE_LOCATION (c),
8051 "copyprivate variable %qE is not threadprivate"
8052 " or private in outer context", DECL_NAME (decl));
8054 do_notice:
8055 if (outer_ctx)
8056 omp_notice_variable (outer_ctx, decl, true);
8057 if (check_non_private
8058 && region_type == ORT_WORKSHARE
8059 && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
8060 || decl == OMP_CLAUSE_DECL (c)
8061 || (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
8062 && (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
8063 == ADDR_EXPR
8064 || (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
8065 == POINTER_PLUS_EXPR
8066 && (TREE_CODE (TREE_OPERAND (TREE_OPERAND
8067 (OMP_CLAUSE_DECL (c), 0), 0))
8068 == ADDR_EXPR)))))
8069 && omp_check_private (ctx, decl, false))
8071 error ("%s variable %qE is private in outer context",
8072 check_non_private, DECL_NAME (decl));
8073 remove = true;
8075 break;
8077 case OMP_CLAUSE_IF:
8078 if (OMP_CLAUSE_IF_MODIFIER (c) != ERROR_MARK
8079 && OMP_CLAUSE_IF_MODIFIER (c) != code)
8081 const char *p[2];
8082 for (int i = 0; i < 2; i++)
8083 switch (i ? OMP_CLAUSE_IF_MODIFIER (c) : code)
8085 case OMP_PARALLEL: p[i] = "parallel"; break;
8086 case OMP_TASK: p[i] = "task"; break;
8087 case OMP_TASKLOOP: p[i] = "taskloop"; break;
8088 case OMP_TARGET_DATA: p[i] = "target data"; break;
8089 case OMP_TARGET: p[i] = "target"; break;
8090 case OMP_TARGET_UPDATE: p[i] = "target update"; break;
8091 case OMP_TARGET_ENTER_DATA:
8092 p[i] = "target enter data"; break;
8093 case OMP_TARGET_EXIT_DATA: p[i] = "target exit data"; break;
8094 default: gcc_unreachable ();
8096 error_at (OMP_CLAUSE_LOCATION (c),
8097 "expected %qs %<if%> clause modifier rather than %qs",
8098 p[0], p[1]);
8099 remove = true;
8101 /* Fall through. */
8103 case OMP_CLAUSE_FINAL:
8104 OMP_CLAUSE_OPERAND (c, 0)
8105 = gimple_boolify (OMP_CLAUSE_OPERAND (c, 0));
8106 /* Fall through. */
8108 case OMP_CLAUSE_SCHEDULE:
8109 case OMP_CLAUSE_NUM_THREADS:
8110 case OMP_CLAUSE_NUM_TEAMS:
8111 case OMP_CLAUSE_THREAD_LIMIT:
8112 case OMP_CLAUSE_DIST_SCHEDULE:
8113 case OMP_CLAUSE_DEVICE:
8114 case OMP_CLAUSE_PRIORITY:
8115 case OMP_CLAUSE_GRAINSIZE:
8116 case OMP_CLAUSE_NUM_TASKS:
8117 case OMP_CLAUSE_HINT:
8118 case OMP_CLAUSE__CILK_FOR_COUNT_:
8119 case OMP_CLAUSE_ASYNC:
8120 case OMP_CLAUSE_WAIT:
8121 case OMP_CLAUSE_NUM_GANGS:
8122 case OMP_CLAUSE_NUM_WORKERS:
8123 case OMP_CLAUSE_VECTOR_LENGTH:
8124 case OMP_CLAUSE_WORKER:
8125 case OMP_CLAUSE_VECTOR:
8126 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
8127 is_gimple_val, fb_rvalue) == GS_ERROR)
8128 remove = true;
8129 break;
8131 case OMP_CLAUSE_GANG:
8132 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
8133 is_gimple_val, fb_rvalue) == GS_ERROR)
8134 remove = true;
8135 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 1), pre_p, NULL,
8136 is_gimple_val, fb_rvalue) == GS_ERROR)
8137 remove = true;
8138 break;
8140 case OMP_CLAUSE_TILE:
8141 for (tree list = OMP_CLAUSE_TILE_LIST (c); !remove && list;
8142 list = TREE_CHAIN (list))
8144 if (gimplify_expr (&TREE_VALUE (list), pre_p, NULL,
8145 is_gimple_val, fb_rvalue) == GS_ERROR)
8146 remove = true;
8148 break;
8150 case OMP_CLAUSE_NOWAIT:
8151 case OMP_CLAUSE_ORDERED:
8152 case OMP_CLAUSE_UNTIED:
8153 case OMP_CLAUSE_COLLAPSE:
8154 case OMP_CLAUSE_AUTO:
8155 case OMP_CLAUSE_SEQ:
8156 case OMP_CLAUSE_INDEPENDENT:
8157 case OMP_CLAUSE_MERGEABLE:
8158 case OMP_CLAUSE_PROC_BIND:
8159 case OMP_CLAUSE_SAFELEN:
8160 case OMP_CLAUSE_SIMDLEN:
8161 case OMP_CLAUSE_NOGROUP:
8162 case OMP_CLAUSE_THREADS:
8163 case OMP_CLAUSE_SIMD:
8164 break;
8166 case OMP_CLAUSE_DEFAULTMAP:
8167 ctx->target_map_scalars_firstprivate = false;
8168 break;
8170 case OMP_CLAUSE_ALIGNED:
8171 decl = OMP_CLAUSE_DECL (c);
8172 if (error_operand_p (decl))
8174 remove = true;
8175 break;
8177 if (gimplify_expr (&OMP_CLAUSE_ALIGNED_ALIGNMENT (c), pre_p, NULL,
8178 is_gimple_val, fb_rvalue) == GS_ERROR)
8180 remove = true;
8181 break;
8183 if (!is_global_var (decl)
8184 && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
8185 omp_add_variable (ctx, decl, GOVD_ALIGNED);
8186 break;
8188 case OMP_CLAUSE_DEFAULT:
8189 ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
8190 break;
8192 default:
8193 gcc_unreachable ();
8196 if (code == OACC_DATA
8197 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
8198 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
8199 remove = true;
8200 if (remove)
8201 *list_p = OMP_CLAUSE_CHAIN (c);
8202 else
8203 list_p = &OMP_CLAUSE_CHAIN (c);
8206 gimplify_omp_ctxp = ctx;
8207 if (struct_map_to_clause)
8208 delete struct_map_to_clause;
8211 /* Return true if DECL is a candidate for shared to firstprivate
8212 optimization. We only consider non-addressable scalars, not
8213 too big, and not references. */
8215 static bool
8216 omp_shared_to_firstprivate_optimizable_decl_p (tree decl)
8218 if (TREE_ADDRESSABLE (decl))
8219 return false;
8220 tree type = TREE_TYPE (decl);
8221 if (!is_gimple_reg_type (type)
8222 || TREE_CODE (type) == REFERENCE_TYPE
8223 || TREE_ADDRESSABLE (type))
8224 return false;
8225 /* Don't optimize too large decls, as each thread/task will have
8226 its own. */
8227 HOST_WIDE_INT len = int_size_in_bytes (type);
8228 if (len == -1 || len > 4 * POINTER_SIZE / BITS_PER_UNIT)
8229 return false;
8230 if (lang_hooks.decls.omp_privatize_by_reference (decl))
8231 return false;
8232 return true;
8235 /* Helper function of omp_find_stores_op and gimplify_adjust_omp_clauses*.
8236 For omp_shared_to_firstprivate_optimizable_decl_p decl mark it as
8237 GOVD_WRITTEN in outer contexts. */
8239 static void
8240 omp_mark_stores (struct gimplify_omp_ctx *ctx, tree decl)
8242 for (; ctx; ctx = ctx->outer_context)
8244 splay_tree_node n = splay_tree_lookup (ctx->variables,
8245 (splay_tree_key) decl);
8246 if (n == NULL)
8247 continue;
8248 else if (n->value & GOVD_SHARED)
8250 n->value |= GOVD_WRITTEN;
8251 return;
8253 else if (n->value & GOVD_DATA_SHARE_CLASS)
8254 return;
8258 /* Helper callback for walk_gimple_seq to discover possible stores
8259 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
8260 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
8261 for those. */
8263 static tree
8264 omp_find_stores_op (tree *tp, int *walk_subtrees, void *data)
8266 struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
8268 *walk_subtrees = 0;
8269 if (!wi->is_lhs)
8270 return NULL_TREE;
8272 tree op = *tp;
8275 if (handled_component_p (op))
8276 op = TREE_OPERAND (op, 0);
8277 else if ((TREE_CODE (op) == MEM_REF || TREE_CODE (op) == TARGET_MEM_REF)
8278 && TREE_CODE (TREE_OPERAND (op, 0)) == ADDR_EXPR)
8279 op = TREE_OPERAND (TREE_OPERAND (op, 0), 0);
8280 else
8281 break;
8283 while (1);
8284 if (!DECL_P (op) || !omp_shared_to_firstprivate_optimizable_decl_p (op))
8285 return NULL_TREE;
8287 omp_mark_stores (gimplify_omp_ctxp, op);
8288 return NULL_TREE;
8291 /* Helper callback for walk_gimple_seq to discover possible stores
8292 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
8293 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
8294 for those. */
8296 static tree
8297 omp_find_stores_stmt (gimple_stmt_iterator *gsi_p,
8298 bool *handled_ops_p,
8299 struct walk_stmt_info *wi)
8301 gimple *stmt = gsi_stmt (*gsi_p);
8302 switch (gimple_code (stmt))
8304 /* Don't recurse on OpenMP constructs for which
8305 gimplify_adjust_omp_clauses already handled the bodies,
8306 except handle gimple_omp_for_pre_body. */
8307 case GIMPLE_OMP_FOR:
8308 *handled_ops_p = true;
8309 if (gimple_omp_for_pre_body (stmt))
8310 walk_gimple_seq (gimple_omp_for_pre_body (stmt),
8311 omp_find_stores_stmt, omp_find_stores_op, wi);
8312 break;
8313 case GIMPLE_OMP_PARALLEL:
8314 case GIMPLE_OMP_TASK:
8315 case GIMPLE_OMP_SECTIONS:
8316 case GIMPLE_OMP_SINGLE:
8317 case GIMPLE_OMP_TARGET:
8318 case GIMPLE_OMP_TEAMS:
8319 case GIMPLE_OMP_CRITICAL:
8320 *handled_ops_p = true;
8321 break;
8322 default:
8323 break;
8325 return NULL_TREE;
8328 struct gimplify_adjust_omp_clauses_data
8330 tree *list_p;
8331 gimple_seq *pre_p;
8334 /* For all variables that were not actually used within the context,
8335 remove PRIVATE, SHARED, and FIRSTPRIVATE clauses. */
8337 static int
8338 gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
8340 tree *list_p = ((struct gimplify_adjust_omp_clauses_data *) data)->list_p;
8341 gimple_seq *pre_p
8342 = ((struct gimplify_adjust_omp_clauses_data *) data)->pre_p;
8343 tree decl = (tree) n->key;
8344 unsigned flags = n->value;
8345 enum omp_clause_code code;
8346 tree clause;
8347 bool private_debug;
8349 if (flags & (GOVD_EXPLICIT | GOVD_LOCAL))
8350 return 0;
8351 if ((flags & GOVD_SEEN) == 0)
8352 return 0;
8353 if (flags & GOVD_DEBUG_PRIVATE)
8355 gcc_assert ((flags & GOVD_DATA_SHARE_CLASS) == GOVD_PRIVATE);
8356 private_debug = true;
8358 else if (flags & GOVD_MAP)
8359 private_debug = false;
8360 else
8361 private_debug
8362 = lang_hooks.decls.omp_private_debug_clause (decl,
8363 !!(flags & GOVD_SHARED));
8364 if (private_debug)
8365 code = OMP_CLAUSE_PRIVATE;
8366 else if (flags & GOVD_MAP)
8368 code = OMP_CLAUSE_MAP;
8369 if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0
8370 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
8372 error ("%<_Atomic%> %qD in implicit %<map%> clause", decl);
8373 return 0;
8376 else if (flags & GOVD_SHARED)
8378 if (is_global_var (decl))
8380 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
8381 while (ctx != NULL)
8383 splay_tree_node on
8384 = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
8385 if (on && (on->value & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
8386 | GOVD_PRIVATE | GOVD_REDUCTION
8387 | GOVD_LINEAR | GOVD_MAP)) != 0)
8388 break;
8389 ctx = ctx->outer_context;
8391 if (ctx == NULL)
8392 return 0;
8394 code = OMP_CLAUSE_SHARED;
8396 else if (flags & GOVD_PRIVATE)
8397 code = OMP_CLAUSE_PRIVATE;
8398 else if (flags & GOVD_FIRSTPRIVATE)
8400 code = OMP_CLAUSE_FIRSTPRIVATE;
8401 if ((gimplify_omp_ctxp->region_type & ORT_TARGET)
8402 && (gimplify_omp_ctxp->region_type & ORT_ACC) == 0
8403 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
8405 error ("%<_Atomic%> %qD in implicit %<firstprivate%> clause on "
8406 "%<target%> construct", decl);
8407 return 0;
8410 else if (flags & GOVD_LASTPRIVATE)
8411 code = OMP_CLAUSE_LASTPRIVATE;
8412 else if (flags & GOVD_ALIGNED)
8413 return 0;
8414 else
8415 gcc_unreachable ();
8417 if (((flags & GOVD_LASTPRIVATE)
8418 || (code == OMP_CLAUSE_SHARED && (flags & GOVD_WRITTEN)))
8419 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
8420 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
8422 clause = build_omp_clause (input_location, code);
8423 OMP_CLAUSE_DECL (clause) = decl;
8424 OMP_CLAUSE_CHAIN (clause) = *list_p;
8425 if (private_debug)
8426 OMP_CLAUSE_PRIVATE_DEBUG (clause) = 1;
8427 else if (code == OMP_CLAUSE_PRIVATE && (flags & GOVD_PRIVATE_OUTER_REF))
8428 OMP_CLAUSE_PRIVATE_OUTER_REF (clause) = 1;
8429 else if (code == OMP_CLAUSE_SHARED
8430 && (flags & GOVD_WRITTEN) == 0
8431 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
8432 OMP_CLAUSE_SHARED_READONLY (clause) = 1;
8433 else if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_EXPLICIT) == 0)
8434 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (clause) = 1;
8435 else if (code == OMP_CLAUSE_MAP && (flags & GOVD_MAP_0LEN_ARRAY) != 0)
8437 tree nc = build_omp_clause (input_location, OMP_CLAUSE_MAP);
8438 OMP_CLAUSE_DECL (nc) = decl;
8439 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
8440 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == POINTER_TYPE)
8441 OMP_CLAUSE_DECL (clause)
8442 = build_simple_mem_ref_loc (input_location, decl);
8443 OMP_CLAUSE_DECL (clause)
8444 = build2 (MEM_REF, char_type_node, OMP_CLAUSE_DECL (clause),
8445 build_int_cst (build_pointer_type (char_type_node), 0));
8446 OMP_CLAUSE_SIZE (clause) = size_zero_node;
8447 OMP_CLAUSE_SIZE (nc) = size_zero_node;
8448 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_ALLOC);
8449 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (clause) = 1;
8450 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
8451 OMP_CLAUSE_CHAIN (nc) = *list_p;
8452 OMP_CLAUSE_CHAIN (clause) = nc;
8453 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
8454 gimplify_omp_ctxp = ctx->outer_context;
8455 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (clause), 0),
8456 pre_p, NULL, is_gimple_val, fb_rvalue);
8457 gimplify_omp_ctxp = ctx;
8459 else if (code == OMP_CLAUSE_MAP)
8461 int kind = (flags & GOVD_MAP_TO_ONLY
8462 ? GOMP_MAP_TO
8463 : GOMP_MAP_TOFROM);
8464 if (flags & GOVD_MAP_FORCE)
8465 kind |= GOMP_MAP_FLAG_FORCE;
8466 OMP_CLAUSE_SET_MAP_KIND (clause, kind);
8467 if (DECL_SIZE (decl)
8468 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
8470 tree decl2 = DECL_VALUE_EXPR (decl);
8471 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
8472 decl2 = TREE_OPERAND (decl2, 0);
8473 gcc_assert (DECL_P (decl2));
8474 tree mem = build_simple_mem_ref (decl2);
8475 OMP_CLAUSE_DECL (clause) = mem;
8476 OMP_CLAUSE_SIZE (clause) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
8477 if (gimplify_omp_ctxp->outer_context)
8479 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
8480 omp_notice_variable (ctx, decl2, true);
8481 omp_notice_variable (ctx, OMP_CLAUSE_SIZE (clause), true);
8483 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
8484 OMP_CLAUSE_MAP);
8485 OMP_CLAUSE_DECL (nc) = decl;
8486 OMP_CLAUSE_SIZE (nc) = size_zero_node;
8487 if (gimplify_omp_ctxp->target_firstprivatize_array_bases)
8488 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
8489 else
8490 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
8491 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
8492 OMP_CLAUSE_CHAIN (clause) = nc;
8494 else if (gimplify_omp_ctxp->target_firstprivatize_array_bases
8495 && lang_hooks.decls.omp_privatize_by_reference (decl))
8497 OMP_CLAUSE_DECL (clause) = build_simple_mem_ref (decl);
8498 OMP_CLAUSE_SIZE (clause)
8499 = unshare_expr (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))));
8500 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
8501 gimplify_omp_ctxp = ctx->outer_context;
8502 gimplify_expr (&OMP_CLAUSE_SIZE (clause),
8503 pre_p, NULL, is_gimple_val, fb_rvalue);
8504 gimplify_omp_ctxp = ctx;
8505 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
8506 OMP_CLAUSE_MAP);
8507 OMP_CLAUSE_DECL (nc) = decl;
8508 OMP_CLAUSE_SIZE (nc) = size_zero_node;
8509 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_REFERENCE);
8510 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
8511 OMP_CLAUSE_CHAIN (clause) = nc;
8513 else
8514 OMP_CLAUSE_SIZE (clause) = DECL_SIZE_UNIT (decl);
8516 if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_LASTPRIVATE) != 0)
8518 tree nc = build_omp_clause (input_location, OMP_CLAUSE_LASTPRIVATE);
8519 OMP_CLAUSE_DECL (nc) = decl;
8520 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (nc) = 1;
8521 OMP_CLAUSE_CHAIN (nc) = *list_p;
8522 OMP_CLAUSE_CHAIN (clause) = nc;
8523 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
8524 gimplify_omp_ctxp = ctx->outer_context;
8525 lang_hooks.decls.omp_finish_clause (nc, pre_p);
8526 gimplify_omp_ctxp = ctx;
8528 *list_p = clause;
8529 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
8530 gimplify_omp_ctxp = ctx->outer_context;
8531 lang_hooks.decls.omp_finish_clause (clause, pre_p);
8532 gimplify_omp_ctxp = ctx;
8533 return 0;
8536 static void
8537 gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
8538 enum tree_code code)
8540 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
8541 tree c, decl;
8543 if (body)
8545 struct gimplify_omp_ctx *octx;
8546 for (octx = ctx; octx; octx = octx->outer_context)
8547 if ((octx->region_type & (ORT_PARALLEL | ORT_TASK | ORT_TEAMS)) != 0)
8548 break;
8549 if (octx)
8551 struct walk_stmt_info wi;
8552 memset (&wi, 0, sizeof (wi));
8553 walk_gimple_seq (body, omp_find_stores_stmt,
8554 omp_find_stores_op, &wi);
8557 while ((c = *list_p) != NULL)
8559 splay_tree_node n;
8560 bool remove = false;
8562 switch (OMP_CLAUSE_CODE (c))
8564 case OMP_CLAUSE_FIRSTPRIVATE:
8565 if ((ctx->region_type & ORT_TARGET)
8566 && (ctx->region_type & ORT_ACC) == 0
8567 && TYPE_ATOMIC (strip_array_types
8568 (TREE_TYPE (OMP_CLAUSE_DECL (c)))))
8570 error_at (OMP_CLAUSE_LOCATION (c),
8571 "%<_Atomic%> %qD in %<firstprivate%> clause on "
8572 "%<target%> construct", OMP_CLAUSE_DECL (c));
8573 remove = true;
8574 break;
8576 /* FALLTHRU */
8577 case OMP_CLAUSE_PRIVATE:
8578 case OMP_CLAUSE_SHARED:
8579 case OMP_CLAUSE_LINEAR:
8580 decl = OMP_CLAUSE_DECL (c);
8581 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
8582 remove = !(n->value & GOVD_SEEN);
8583 if (! remove)
8585 bool shared = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED;
8586 if ((n->value & GOVD_DEBUG_PRIVATE)
8587 || lang_hooks.decls.omp_private_debug_clause (decl, shared))
8589 gcc_assert ((n->value & GOVD_DEBUG_PRIVATE) == 0
8590 || ((n->value & GOVD_DATA_SHARE_CLASS)
8591 == GOVD_PRIVATE));
8592 OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_PRIVATE);
8593 OMP_CLAUSE_PRIVATE_DEBUG (c) = 1;
8595 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
8596 && (n->value & GOVD_WRITTEN) == 0
8597 && DECL_P (decl)
8598 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
8599 OMP_CLAUSE_SHARED_READONLY (c) = 1;
8600 else if (DECL_P (decl)
8601 && ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
8602 && (n->value & GOVD_WRITTEN) != 1)
8603 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
8604 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
8605 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
8606 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
8608 break;
8610 case OMP_CLAUSE_LASTPRIVATE:
8611 /* Make sure OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE is set to
8612 accurately reflect the presence of a FIRSTPRIVATE clause. */
8613 decl = OMP_CLAUSE_DECL (c);
8614 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
8615 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c)
8616 = (n->value & GOVD_FIRSTPRIVATE) != 0;
8617 if (omp_no_lastprivate (ctx))
8619 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
8620 remove = true;
8621 else
8622 OMP_CLAUSE_CODE (c) = OMP_CLAUSE_PRIVATE;
8624 else if (code == OMP_DISTRIBUTE
8625 && OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
8627 remove = true;
8628 error_at (OMP_CLAUSE_LOCATION (c),
8629 "same variable used in %<firstprivate%> and "
8630 "%<lastprivate%> clauses on %<distribute%> "
8631 "construct");
8633 if (!remove
8634 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
8635 && DECL_P (decl)
8636 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
8637 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
8638 break;
8640 case OMP_CLAUSE_ALIGNED:
8641 decl = OMP_CLAUSE_DECL (c);
8642 if (!is_global_var (decl))
8644 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
8645 remove = n == NULL || !(n->value & GOVD_SEEN);
8646 if (!remove && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
8648 struct gimplify_omp_ctx *octx;
8649 if (n != NULL
8650 && (n->value & (GOVD_DATA_SHARE_CLASS
8651 & ~GOVD_FIRSTPRIVATE)))
8652 remove = true;
8653 else
8654 for (octx = ctx->outer_context; octx;
8655 octx = octx->outer_context)
8657 n = splay_tree_lookup (octx->variables,
8658 (splay_tree_key) decl);
8659 if (n == NULL)
8660 continue;
8661 if (n->value & GOVD_LOCAL)
8662 break;
8663 /* We have to avoid assigning a shared variable
8664 to itself when trying to add
8665 __builtin_assume_aligned. */
8666 if (n->value & GOVD_SHARED)
8668 remove = true;
8669 break;
8674 else if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
8676 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
8677 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
8678 remove = true;
8680 break;
8682 case OMP_CLAUSE_MAP:
8683 if (code == OMP_TARGET_EXIT_DATA
8684 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER)
8686 remove = true;
8687 break;
8689 decl = OMP_CLAUSE_DECL (c);
8690 /* Data clauses associated with acc parallel reductions must be
8691 compatible with present_or_copy. Warn and adjust the clause
8692 if that is not the case. */
8693 if (ctx->region_type == ORT_ACC_PARALLEL)
8695 tree t = DECL_P (decl) ? decl : TREE_OPERAND (decl, 0);
8696 n = NULL;
8698 if (DECL_P (t))
8699 n = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
8701 if (n && (n->value & GOVD_REDUCTION))
8703 enum gomp_map_kind kind = OMP_CLAUSE_MAP_KIND (c);
8705 OMP_CLAUSE_MAP_IN_REDUCTION (c) = 1;
8706 if ((kind & GOMP_MAP_TOFROM) != GOMP_MAP_TOFROM
8707 && kind != GOMP_MAP_FORCE_PRESENT
8708 && kind != GOMP_MAP_POINTER)
8710 warning_at (OMP_CLAUSE_LOCATION (c), 0,
8711 "incompatible data clause with reduction "
8712 "on %qE; promoting to present_or_copy",
8713 DECL_NAME (t));
8714 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TOFROM);
8718 if (!DECL_P (decl))
8720 if ((ctx->region_type & ORT_TARGET) != 0
8721 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
8723 if (TREE_CODE (decl) == INDIRECT_REF
8724 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
8725 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
8726 == REFERENCE_TYPE))
8727 decl = TREE_OPERAND (decl, 0);
8728 if (TREE_CODE (decl) == COMPONENT_REF)
8730 while (TREE_CODE (decl) == COMPONENT_REF)
8731 decl = TREE_OPERAND (decl, 0);
8732 if (DECL_P (decl))
8734 n = splay_tree_lookup (ctx->variables,
8735 (splay_tree_key) decl);
8736 if (!(n->value & GOVD_SEEN))
8737 remove = true;
8741 break;
8743 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
8744 if ((ctx->region_type & ORT_TARGET) != 0
8745 && !(n->value & GOVD_SEEN)
8746 && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) == 0
8747 && !lookup_attribute ("omp declare target link",
8748 DECL_ATTRIBUTES (decl)))
8750 remove = true;
8751 /* For struct element mapping, if struct is never referenced
8752 in target block and none of the mapping has always modifier,
8753 remove all the struct element mappings, which immediately
8754 follow the GOMP_MAP_STRUCT map clause. */
8755 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT)
8757 HOST_WIDE_INT cnt = tree_to_shwi (OMP_CLAUSE_SIZE (c));
8758 while (cnt--)
8759 OMP_CLAUSE_CHAIN (c)
8760 = OMP_CLAUSE_CHAIN (OMP_CLAUSE_CHAIN (c));
8763 else if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT
8764 && code == OMP_TARGET_EXIT_DATA)
8765 remove = true;
8766 else if (DECL_SIZE (decl)
8767 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST
8768 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_POINTER
8769 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_POINTER
8770 && (OMP_CLAUSE_MAP_KIND (c)
8771 != GOMP_MAP_FIRSTPRIVATE_REFERENCE))
8773 /* For GOMP_MAP_FORCE_DEVICEPTR, we'll never enter here, because
8774 for these, TREE_CODE (DECL_SIZE (decl)) will always be
8775 INTEGER_CST. */
8776 gcc_assert (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FORCE_DEVICEPTR);
8778 tree decl2 = DECL_VALUE_EXPR (decl);
8779 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
8780 decl2 = TREE_OPERAND (decl2, 0);
8781 gcc_assert (DECL_P (decl2));
8782 tree mem = build_simple_mem_ref (decl2);
8783 OMP_CLAUSE_DECL (c) = mem;
8784 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
8785 if (ctx->outer_context)
8787 omp_notice_variable (ctx->outer_context, decl2, true);
8788 omp_notice_variable (ctx->outer_context,
8789 OMP_CLAUSE_SIZE (c), true);
8791 if (((ctx->region_type & ORT_TARGET) != 0
8792 || !ctx->target_firstprivatize_array_bases)
8793 && ((n->value & GOVD_SEEN) == 0
8794 || (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) == 0))
8796 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
8797 OMP_CLAUSE_MAP);
8798 OMP_CLAUSE_DECL (nc) = decl;
8799 OMP_CLAUSE_SIZE (nc) = size_zero_node;
8800 if (ctx->target_firstprivatize_array_bases)
8801 OMP_CLAUSE_SET_MAP_KIND (nc,
8802 GOMP_MAP_FIRSTPRIVATE_POINTER);
8803 else
8804 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
8805 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
8806 OMP_CLAUSE_CHAIN (c) = nc;
8807 c = nc;
8810 else
8812 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
8813 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
8814 gcc_assert ((n->value & GOVD_SEEN) == 0
8815 || ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
8816 == 0));
8818 break;
8820 case OMP_CLAUSE_TO:
8821 case OMP_CLAUSE_FROM:
8822 case OMP_CLAUSE__CACHE_:
8823 decl = OMP_CLAUSE_DECL (c);
8824 if (!DECL_P (decl))
8825 break;
8826 if (DECL_SIZE (decl)
8827 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
8829 tree decl2 = DECL_VALUE_EXPR (decl);
8830 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
8831 decl2 = TREE_OPERAND (decl2, 0);
8832 gcc_assert (DECL_P (decl2));
8833 tree mem = build_simple_mem_ref (decl2);
8834 OMP_CLAUSE_DECL (c) = mem;
8835 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
8836 if (ctx->outer_context)
8838 omp_notice_variable (ctx->outer_context, decl2, true);
8839 omp_notice_variable (ctx->outer_context,
8840 OMP_CLAUSE_SIZE (c), true);
8843 else if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
8844 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
8845 break;
8847 case OMP_CLAUSE_REDUCTION:
8848 decl = OMP_CLAUSE_DECL (c);
8849 /* OpenACC reductions need a present_or_copy data clause.
8850 Add one if necessary. Error is the reduction is private. */
8851 if (ctx->region_type == ORT_ACC_PARALLEL)
8853 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
8854 if (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
8855 error_at (OMP_CLAUSE_LOCATION (c), "invalid private "
8856 "reduction on %qE", DECL_NAME (decl));
8857 else if ((n->value & GOVD_MAP) == 0)
8859 tree next = OMP_CLAUSE_CHAIN (c);
8860 tree nc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_MAP);
8861 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_TOFROM);
8862 OMP_CLAUSE_DECL (nc) = decl;
8863 OMP_CLAUSE_CHAIN (c) = nc;
8864 lang_hooks.decls.omp_finish_clause (nc, pre_p);
8865 while (1)
8867 OMP_CLAUSE_MAP_IN_REDUCTION (nc) = 1;
8868 if (OMP_CLAUSE_CHAIN (nc) == NULL)
8869 break;
8870 nc = OMP_CLAUSE_CHAIN (nc);
8872 OMP_CLAUSE_CHAIN (nc) = next;
8873 n->value |= GOVD_MAP;
8876 if (DECL_P (decl)
8877 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
8878 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
8879 break;
8880 case OMP_CLAUSE_COPYIN:
8881 case OMP_CLAUSE_COPYPRIVATE:
8882 case OMP_CLAUSE_IF:
8883 case OMP_CLAUSE_NUM_THREADS:
8884 case OMP_CLAUSE_NUM_TEAMS:
8885 case OMP_CLAUSE_THREAD_LIMIT:
8886 case OMP_CLAUSE_DIST_SCHEDULE:
8887 case OMP_CLAUSE_DEVICE:
8888 case OMP_CLAUSE_SCHEDULE:
8889 case OMP_CLAUSE_NOWAIT:
8890 case OMP_CLAUSE_ORDERED:
8891 case OMP_CLAUSE_DEFAULT:
8892 case OMP_CLAUSE_UNTIED:
8893 case OMP_CLAUSE_COLLAPSE:
8894 case OMP_CLAUSE_FINAL:
8895 case OMP_CLAUSE_MERGEABLE:
8896 case OMP_CLAUSE_PROC_BIND:
8897 case OMP_CLAUSE_SAFELEN:
8898 case OMP_CLAUSE_SIMDLEN:
8899 case OMP_CLAUSE_DEPEND:
8900 case OMP_CLAUSE_PRIORITY:
8901 case OMP_CLAUSE_GRAINSIZE:
8902 case OMP_CLAUSE_NUM_TASKS:
8903 case OMP_CLAUSE_NOGROUP:
8904 case OMP_CLAUSE_THREADS:
8905 case OMP_CLAUSE_SIMD:
8906 case OMP_CLAUSE_HINT:
8907 case OMP_CLAUSE_DEFAULTMAP:
8908 case OMP_CLAUSE_USE_DEVICE_PTR:
8909 case OMP_CLAUSE_IS_DEVICE_PTR:
8910 case OMP_CLAUSE__CILK_FOR_COUNT_:
8911 case OMP_CLAUSE_ASYNC:
8912 case OMP_CLAUSE_WAIT:
8913 case OMP_CLAUSE_INDEPENDENT:
8914 case OMP_CLAUSE_NUM_GANGS:
8915 case OMP_CLAUSE_NUM_WORKERS:
8916 case OMP_CLAUSE_VECTOR_LENGTH:
8917 case OMP_CLAUSE_GANG:
8918 case OMP_CLAUSE_WORKER:
8919 case OMP_CLAUSE_VECTOR:
8920 case OMP_CLAUSE_AUTO:
8921 case OMP_CLAUSE_SEQ:
8922 break;
8924 case OMP_CLAUSE_TILE:
8925 /* We're not yet making use of the information provided by OpenACC
8926 tile clauses. Discard these here, to simplify later middle end
8927 processing. */
8928 remove = true;
8929 break;
8931 default:
8932 gcc_unreachable ();
8935 if (remove)
8936 *list_p = OMP_CLAUSE_CHAIN (c);
8937 else
8938 list_p = &OMP_CLAUSE_CHAIN (c);
8941 /* Add in any implicit data sharing. */
8942 struct gimplify_adjust_omp_clauses_data data;
8943 data.list_p = list_p;
8944 data.pre_p = pre_p;
8945 splay_tree_foreach (ctx->variables, gimplify_adjust_omp_clauses_1, &data);
8947 gimplify_omp_ctxp = ctx->outer_context;
8948 delete_omp_context (ctx);
8951 /* Gimplify OACC_CACHE. */
8953 static void
8954 gimplify_oacc_cache (tree *expr_p, gimple_seq *pre_p)
8956 tree expr = *expr_p;
8958 gimplify_scan_omp_clauses (&OACC_CACHE_CLAUSES (expr), pre_p, ORT_ACC,
8959 OACC_CACHE);
8960 gimplify_adjust_omp_clauses (pre_p, NULL, &OACC_CACHE_CLAUSES (expr),
8961 OACC_CACHE);
8963 /* TODO: Do something sensible with this information. */
8965 *expr_p = NULL_TREE;
8968 /* Helper function of gimplify_oacc_declare. The helper's purpose is to,
8969 if required, translate 'kind' in CLAUSE into an 'entry' kind and 'exit'
8970 kind. The entry kind will replace the one in CLAUSE, while the exit
8971 kind will be used in a new omp_clause and returned to the caller. */
8973 static tree
8974 gimplify_oacc_declare_1 (tree clause)
8976 HOST_WIDE_INT kind, new_op;
8977 bool ret = false;
8978 tree c = NULL;
8980 kind = OMP_CLAUSE_MAP_KIND (clause);
8982 switch (kind)
8984 case GOMP_MAP_ALLOC:
8985 case GOMP_MAP_FORCE_ALLOC:
8986 case GOMP_MAP_FORCE_TO:
8987 new_op = GOMP_MAP_DELETE;
8988 ret = true;
8989 break;
8991 case GOMP_MAP_FORCE_FROM:
8992 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_FORCE_ALLOC);
8993 new_op = GOMP_MAP_FORCE_FROM;
8994 ret = true;
8995 break;
8997 case GOMP_MAP_FORCE_TOFROM:
8998 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_FORCE_TO);
8999 new_op = GOMP_MAP_FORCE_FROM;
9000 ret = true;
9001 break;
9003 case GOMP_MAP_FROM:
9004 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_FORCE_ALLOC);
9005 new_op = GOMP_MAP_FROM;
9006 ret = true;
9007 break;
9009 case GOMP_MAP_TOFROM:
9010 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_TO);
9011 new_op = GOMP_MAP_FROM;
9012 ret = true;
9013 break;
9015 case GOMP_MAP_DEVICE_RESIDENT:
9016 case GOMP_MAP_FORCE_DEVICEPTR:
9017 case GOMP_MAP_FORCE_PRESENT:
9018 case GOMP_MAP_LINK:
9019 case GOMP_MAP_POINTER:
9020 case GOMP_MAP_TO:
9021 break;
9023 default:
9024 gcc_unreachable ();
9025 break;
9028 if (ret)
9030 c = build_omp_clause (OMP_CLAUSE_LOCATION (clause), OMP_CLAUSE_MAP);
9031 OMP_CLAUSE_SET_MAP_KIND (c, new_op);
9032 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clause);
9035 return c;
9038 /* Gimplify OACC_DECLARE. */
9040 static void
9041 gimplify_oacc_declare (tree *expr_p, gimple_seq *pre_p)
9043 tree expr = *expr_p;
9044 gomp_target *stmt;
9045 tree clauses, t;
9047 clauses = OACC_DECLARE_CLAUSES (expr);
9049 gimplify_scan_omp_clauses (&clauses, pre_p, ORT_TARGET_DATA, OACC_DECLARE);
9051 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
9053 tree decl = OMP_CLAUSE_DECL (t);
9055 if (TREE_CODE (decl) == MEM_REF)
9056 continue;
9058 if (TREE_CODE (decl) == VAR_DECL
9059 && !is_global_var (decl)
9060 && DECL_CONTEXT (decl) == current_function_decl)
9062 tree c = gimplify_oacc_declare_1 (t);
9063 if (c)
9065 if (oacc_declare_returns == NULL)
9066 oacc_declare_returns = new hash_map<tree, tree>;
9068 oacc_declare_returns->put (decl, c);
9072 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_SEEN);
9075 stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
9076 clauses);
9078 gimplify_seq_add_stmt (pre_p, stmt);
9080 *expr_p = NULL_TREE;
9083 /* Gimplify the contents of an OMP_PARALLEL statement. This involves
9084 gimplification of the body, as well as scanning the body for used
9085 variables. We need to do this scan now, because variable-sized
9086 decls will be decomposed during gimplification. */
9088 static void
9089 gimplify_omp_parallel (tree *expr_p, gimple_seq *pre_p)
9091 tree expr = *expr_p;
9092 gimple *g;
9093 gimple_seq body = NULL;
9095 gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr), pre_p,
9096 OMP_PARALLEL_COMBINED (expr)
9097 ? ORT_COMBINED_PARALLEL
9098 : ORT_PARALLEL, OMP_PARALLEL);
9100 push_gimplify_context ();
9102 g = gimplify_and_return_first (OMP_PARALLEL_BODY (expr), &body);
9103 if (gimple_code (g) == GIMPLE_BIND)
9104 pop_gimplify_context (g);
9105 else
9106 pop_gimplify_context (NULL);
9108 gimplify_adjust_omp_clauses (pre_p, body, &OMP_PARALLEL_CLAUSES (expr),
9109 OMP_PARALLEL);
9111 g = gimple_build_omp_parallel (body,
9112 OMP_PARALLEL_CLAUSES (expr),
9113 NULL_TREE, NULL_TREE);
9114 if (OMP_PARALLEL_COMBINED (expr))
9115 gimple_omp_set_subcode (g, GF_OMP_PARALLEL_COMBINED);
9116 gimplify_seq_add_stmt (pre_p, g);
9117 *expr_p = NULL_TREE;
9120 /* Gimplify the contents of an OMP_TASK statement. This involves
9121 gimplification of the body, as well as scanning the body for used
9122 variables. We need to do this scan now, because variable-sized
9123 decls will be decomposed during gimplification. */
9125 static void
9126 gimplify_omp_task (tree *expr_p, gimple_seq *pre_p)
9128 tree expr = *expr_p;
9129 gimple *g;
9130 gimple_seq body = NULL;
9132 gimplify_scan_omp_clauses (&OMP_TASK_CLAUSES (expr), pre_p,
9133 find_omp_clause (OMP_TASK_CLAUSES (expr),
9134 OMP_CLAUSE_UNTIED)
9135 ? ORT_UNTIED_TASK : ORT_TASK, OMP_TASK);
9137 push_gimplify_context ();
9139 g = gimplify_and_return_first (OMP_TASK_BODY (expr), &body);
9140 if (gimple_code (g) == GIMPLE_BIND)
9141 pop_gimplify_context (g);
9142 else
9143 pop_gimplify_context (NULL);
9145 gimplify_adjust_omp_clauses (pre_p, body, &OMP_TASK_CLAUSES (expr),
9146 OMP_TASK);
9148 g = gimple_build_omp_task (body,
9149 OMP_TASK_CLAUSES (expr),
9150 NULL_TREE, NULL_TREE,
9151 NULL_TREE, NULL_TREE, NULL_TREE);
9152 gimplify_seq_add_stmt (pre_p, g);
9153 *expr_p = NULL_TREE;
9156 /* Helper function of gimplify_omp_for, find OMP_FOR resp. OMP_SIMD
9157 with non-NULL OMP_FOR_INIT. */
9159 static tree
9160 find_combined_omp_for (tree *tp, int *walk_subtrees, void *)
9162 *walk_subtrees = 0;
9163 switch (TREE_CODE (*tp))
9165 case OMP_FOR:
9166 *walk_subtrees = 1;
9167 /* FALLTHRU */
9168 case OMP_SIMD:
9169 if (OMP_FOR_INIT (*tp) != NULL_TREE)
9170 return *tp;
9171 break;
9172 case BIND_EXPR:
9173 case STATEMENT_LIST:
9174 case OMP_PARALLEL:
9175 *walk_subtrees = 1;
9176 break;
9177 default:
9178 break;
9180 return NULL_TREE;
9183 /* Gimplify the gross structure of an OMP_FOR statement. */
9185 static enum gimplify_status
9186 gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
9188 tree for_stmt, orig_for_stmt, inner_for_stmt = NULL_TREE, decl, var, t;
9189 enum gimplify_status ret = GS_ALL_DONE;
9190 enum gimplify_status tret;
9191 gomp_for *gfor;
9192 gimple_seq for_body, for_pre_body;
9193 int i;
9194 bitmap has_decl_expr = NULL;
9195 enum omp_region_type ort = ORT_WORKSHARE;
9197 orig_for_stmt = for_stmt = *expr_p;
9199 switch (TREE_CODE (for_stmt))
9201 case OMP_FOR:
9202 case CILK_FOR:
9203 case OMP_DISTRIBUTE:
9204 break;
9205 case OACC_LOOP:
9206 ort = ORT_ACC;
9207 break;
9208 case OMP_TASKLOOP:
9209 if (find_omp_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_UNTIED))
9210 ort = ORT_UNTIED_TASK;
9211 else
9212 ort = ORT_TASK;
9213 break;
9214 case OMP_SIMD:
9215 case CILK_SIMD:
9216 ort = ORT_SIMD;
9217 break;
9218 default:
9219 gcc_unreachable ();
9222 /* Set OMP_CLAUSE_LINEAR_NO_COPYIN flag on explicit linear
9223 clause for the IV. */
9224 if (ort == ORT_SIMD && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
9226 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), 0);
9227 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
9228 decl = TREE_OPERAND (t, 0);
9229 for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
9230 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
9231 && OMP_CLAUSE_DECL (c) == decl)
9233 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
9234 break;
9238 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
9240 gcc_assert (TREE_CODE (for_stmt) != OACC_LOOP);
9241 inner_for_stmt = walk_tree (&OMP_FOR_BODY (for_stmt),
9242 find_combined_omp_for, NULL, NULL);
9243 if (inner_for_stmt == NULL_TREE)
9245 gcc_assert (seen_error ());
9246 *expr_p = NULL_TREE;
9247 return GS_ERROR;
9251 if (TREE_CODE (for_stmt) != OMP_TASKLOOP)
9252 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p, ort,
9253 TREE_CODE (for_stmt));
9255 if (TREE_CODE (for_stmt) == OMP_DISTRIBUTE)
9256 gimplify_omp_ctxp->distribute = true;
9258 /* Handle OMP_FOR_INIT. */
9259 for_pre_body = NULL;
9260 if (ort == ORT_SIMD && OMP_FOR_PRE_BODY (for_stmt))
9262 has_decl_expr = BITMAP_ALLOC (NULL);
9263 if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == DECL_EXPR
9264 && TREE_CODE (DECL_EXPR_DECL (OMP_FOR_PRE_BODY (for_stmt)))
9265 == VAR_DECL)
9267 t = OMP_FOR_PRE_BODY (for_stmt);
9268 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
9270 else if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == STATEMENT_LIST)
9272 tree_stmt_iterator si;
9273 for (si = tsi_start (OMP_FOR_PRE_BODY (for_stmt)); !tsi_end_p (si);
9274 tsi_next (&si))
9276 t = tsi_stmt (si);
9277 if (TREE_CODE (t) == DECL_EXPR
9278 && TREE_CODE (DECL_EXPR_DECL (t)) == VAR_DECL)
9279 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
9283 if (OMP_FOR_PRE_BODY (for_stmt))
9285 if (TREE_CODE (for_stmt) != OMP_TASKLOOP || gimplify_omp_ctxp)
9286 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
9287 else
9289 struct gimplify_omp_ctx ctx;
9290 memset (&ctx, 0, sizeof (ctx));
9291 ctx.region_type = ORT_NONE;
9292 gimplify_omp_ctxp = &ctx;
9293 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
9294 gimplify_omp_ctxp = NULL;
9297 OMP_FOR_PRE_BODY (for_stmt) = NULL_TREE;
9299 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
9300 for_stmt = inner_for_stmt;
9302 /* For taskloop, need to gimplify the start, end and step before the
9303 taskloop, outside of the taskloop omp context. */
9304 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
9306 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
9308 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
9309 if (!is_gimple_constant (TREE_OPERAND (t, 1)))
9311 TREE_OPERAND (t, 1)
9312 = get_initialized_tmp_var (TREE_OPERAND (t, 1),
9313 pre_p, NULL, false);
9314 tree c = build_omp_clause (input_location,
9315 OMP_CLAUSE_FIRSTPRIVATE);
9316 OMP_CLAUSE_DECL (c) = TREE_OPERAND (t, 1);
9317 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
9318 OMP_FOR_CLAUSES (orig_for_stmt) = c;
9321 /* Handle OMP_FOR_COND. */
9322 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
9323 if (!is_gimple_constant (TREE_OPERAND (t, 1)))
9325 TREE_OPERAND (t, 1)
9326 = get_initialized_tmp_var (TREE_OPERAND (t, 1),
9327 gimple_seq_empty_p (for_pre_body)
9328 ? pre_p : &for_pre_body, NULL,
9329 false);
9330 tree c = build_omp_clause (input_location,
9331 OMP_CLAUSE_FIRSTPRIVATE);
9332 OMP_CLAUSE_DECL (c) = TREE_OPERAND (t, 1);
9333 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
9334 OMP_FOR_CLAUSES (orig_for_stmt) = c;
9337 /* Handle OMP_FOR_INCR. */
9338 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
9339 if (TREE_CODE (t) == MODIFY_EXPR)
9341 decl = TREE_OPERAND (t, 0);
9342 t = TREE_OPERAND (t, 1);
9343 tree *tp = &TREE_OPERAND (t, 1);
9344 if (TREE_CODE (t) == PLUS_EXPR && *tp == decl)
9345 tp = &TREE_OPERAND (t, 0);
9347 if (!is_gimple_constant (*tp))
9349 gimple_seq *seq = gimple_seq_empty_p (for_pre_body)
9350 ? pre_p : &for_pre_body;
9351 *tp = get_initialized_tmp_var (*tp, seq, NULL, false);
9352 tree c = build_omp_clause (input_location,
9353 OMP_CLAUSE_FIRSTPRIVATE);
9354 OMP_CLAUSE_DECL (c) = *tp;
9355 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
9356 OMP_FOR_CLAUSES (orig_for_stmt) = c;
9361 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (orig_for_stmt), pre_p, ort,
9362 OMP_TASKLOOP);
9365 if (orig_for_stmt != for_stmt)
9366 gimplify_omp_ctxp->combined_loop = true;
9368 for_body = NULL;
9369 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
9370 == TREE_VEC_LENGTH (OMP_FOR_COND (for_stmt)));
9371 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
9372 == TREE_VEC_LENGTH (OMP_FOR_INCR (for_stmt)));
9374 tree c = find_omp_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED);
9375 bool is_doacross = false;
9376 if (c && OMP_CLAUSE_ORDERED_EXPR (c))
9378 is_doacross = true;
9379 gimplify_omp_ctxp->loop_iter_var.create (TREE_VEC_LENGTH
9380 (OMP_FOR_INIT (for_stmt))
9381 * 2);
9383 int collapse = 1;
9384 c = find_omp_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_COLLAPSE);
9385 if (c)
9386 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (c));
9387 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
9389 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
9390 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
9391 decl = TREE_OPERAND (t, 0);
9392 gcc_assert (DECL_P (decl));
9393 gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl))
9394 || POINTER_TYPE_P (TREE_TYPE (decl)));
9395 if (is_doacross)
9397 if (TREE_CODE (for_stmt) == OMP_FOR && OMP_FOR_ORIG_DECLS (for_stmt))
9398 gimplify_omp_ctxp->loop_iter_var.quick_push
9399 (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i));
9400 else
9401 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
9402 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
9405 /* Make sure the iteration variable is private. */
9406 tree c = NULL_TREE;
9407 tree c2 = NULL_TREE;
9408 if (orig_for_stmt != for_stmt)
9409 /* Do this only on innermost construct for combined ones. */;
9410 else if (ort == ORT_SIMD)
9412 splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
9413 (splay_tree_key) decl);
9414 omp_is_private (gimplify_omp_ctxp, decl,
9415 1 + (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
9416 != 1));
9417 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
9418 omp_notice_variable (gimplify_omp_ctxp, decl, true);
9419 else if (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
9421 c = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
9422 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
9423 unsigned int flags = GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN;
9424 if ((has_decl_expr
9425 && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
9426 || omp_no_lastprivate (gimplify_omp_ctxp))
9428 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
9429 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
9431 struct gimplify_omp_ctx *outer
9432 = gimplify_omp_ctxp->outer_context;
9433 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
9435 if (outer->region_type == ORT_WORKSHARE
9436 && outer->combined_loop)
9438 n = splay_tree_lookup (outer->variables,
9439 (splay_tree_key)decl);
9440 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
9442 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
9443 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
9445 else
9447 struct gimplify_omp_ctx *octx = outer->outer_context;
9448 if (octx
9449 && octx->region_type == ORT_COMBINED_PARALLEL
9450 && octx->outer_context
9451 && (octx->outer_context->region_type
9452 == ORT_WORKSHARE)
9453 && octx->outer_context->combined_loop)
9455 octx = octx->outer_context;
9456 n = splay_tree_lookup (octx->variables,
9457 (splay_tree_key)decl);
9458 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
9460 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
9461 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
9468 OMP_CLAUSE_DECL (c) = decl;
9469 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
9470 OMP_FOR_CLAUSES (for_stmt) = c;
9471 omp_add_variable (gimplify_omp_ctxp, decl, flags);
9472 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
9474 if (outer->region_type == ORT_WORKSHARE
9475 && outer->combined_loop)
9477 if (outer->outer_context
9478 && (outer->outer_context->region_type
9479 == ORT_COMBINED_PARALLEL))
9480 outer = outer->outer_context;
9481 else if (omp_check_private (outer, decl, false))
9482 outer = NULL;
9484 else if (((outer->region_type & ORT_TASK) != 0)
9485 && outer->combined_loop
9486 && !omp_check_private (gimplify_omp_ctxp,
9487 decl, false))
9489 else if (outer->region_type != ORT_COMBINED_PARALLEL)
9491 omp_notice_variable (outer, decl, true);
9492 outer = NULL;
9494 if (outer)
9496 n = splay_tree_lookup (outer->variables,
9497 (splay_tree_key)decl);
9498 if (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
9500 omp_add_variable (outer, decl,
9501 GOVD_LASTPRIVATE | GOVD_SEEN);
9502 if (outer->region_type == ORT_COMBINED_PARALLEL
9503 && outer->outer_context
9504 && (outer->outer_context->region_type
9505 == ORT_WORKSHARE)
9506 && outer->outer_context->combined_loop)
9508 outer = outer->outer_context;
9509 n = splay_tree_lookup (outer->variables,
9510 (splay_tree_key)decl);
9511 if (omp_check_private (outer, decl, false))
9512 outer = NULL;
9513 else if (n == NULL
9514 || ((n->value & GOVD_DATA_SHARE_CLASS)
9515 == 0))
9516 omp_add_variable (outer, decl,
9517 GOVD_LASTPRIVATE
9518 | GOVD_SEEN);
9519 else
9520 outer = NULL;
9522 if (outer && outer->outer_context
9523 && (outer->outer_context->region_type
9524 == ORT_COMBINED_TEAMS))
9526 outer = outer->outer_context;
9527 n = splay_tree_lookup (outer->variables,
9528 (splay_tree_key)decl);
9529 if (n == NULL
9530 || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
9531 omp_add_variable (outer, decl,
9532 GOVD_SHARED | GOVD_SEEN);
9533 else
9534 outer = NULL;
9536 if (outer && outer->outer_context)
9537 omp_notice_variable (outer->outer_context, decl,
9538 true);
9543 else
9545 bool lastprivate
9546 = (!has_decl_expr
9547 || !bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
9548 && !omp_no_lastprivate (gimplify_omp_ctxp);
9549 struct gimplify_omp_ctx *outer
9550 = gimplify_omp_ctxp->outer_context;
9551 if (outer && lastprivate)
9553 if (outer->region_type == ORT_WORKSHARE
9554 && outer->combined_loop)
9556 n = splay_tree_lookup (outer->variables,
9557 (splay_tree_key)decl);
9558 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
9560 lastprivate = false;
9561 outer = NULL;
9563 else if (outer->outer_context
9564 && (outer->outer_context->region_type
9565 == ORT_COMBINED_PARALLEL))
9566 outer = outer->outer_context;
9567 else if (omp_check_private (outer, decl, false))
9568 outer = NULL;
9570 else if (((outer->region_type & ORT_TASK) != 0)
9571 && outer->combined_loop
9572 && !omp_check_private (gimplify_omp_ctxp,
9573 decl, false))
9575 else if (outer->region_type != ORT_COMBINED_PARALLEL)
9577 omp_notice_variable (outer, decl, true);
9578 outer = NULL;
9580 if (outer)
9582 n = splay_tree_lookup (outer->variables,
9583 (splay_tree_key)decl);
9584 if (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
9586 omp_add_variable (outer, decl,
9587 GOVD_LASTPRIVATE | GOVD_SEEN);
9588 if (outer->region_type == ORT_COMBINED_PARALLEL
9589 && outer->outer_context
9590 && (outer->outer_context->region_type
9591 == ORT_WORKSHARE)
9592 && outer->outer_context->combined_loop)
9594 outer = outer->outer_context;
9595 n = splay_tree_lookup (outer->variables,
9596 (splay_tree_key)decl);
9597 if (omp_check_private (outer, decl, false))
9598 outer = NULL;
9599 else if (n == NULL
9600 || ((n->value & GOVD_DATA_SHARE_CLASS)
9601 == 0))
9602 omp_add_variable (outer, decl,
9603 GOVD_LASTPRIVATE
9604 | GOVD_SEEN);
9605 else
9606 outer = NULL;
9608 if (outer && outer->outer_context
9609 && (outer->outer_context->region_type
9610 == ORT_COMBINED_TEAMS))
9612 outer = outer->outer_context;
9613 n = splay_tree_lookup (outer->variables,
9614 (splay_tree_key)decl);
9615 if (n == NULL
9616 || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
9617 omp_add_variable (outer, decl,
9618 GOVD_SHARED | GOVD_SEEN);
9619 else
9620 outer = NULL;
9622 if (outer && outer->outer_context)
9623 omp_notice_variable (outer->outer_context, decl,
9624 true);
9629 c = build_omp_clause (input_location,
9630 lastprivate ? OMP_CLAUSE_LASTPRIVATE
9631 : OMP_CLAUSE_PRIVATE);
9632 OMP_CLAUSE_DECL (c) = decl;
9633 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
9634 OMP_FOR_CLAUSES (for_stmt) = c;
9635 omp_add_variable (gimplify_omp_ctxp, decl,
9636 (lastprivate ? GOVD_LASTPRIVATE : GOVD_PRIVATE)
9637 | GOVD_EXPLICIT | GOVD_SEEN);
9638 c = NULL_TREE;
9641 else if (omp_is_private (gimplify_omp_ctxp, decl, 0))
9642 omp_notice_variable (gimplify_omp_ctxp, decl, true);
9643 else
9644 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN);
9646 /* If DECL is not a gimple register, create a temporary variable to act
9647 as an iteration counter. This is valid, since DECL cannot be
9648 modified in the body of the loop. Similarly for any iteration vars
9649 in simd with collapse > 1 where the iterator vars must be
9650 lastprivate. */
9651 if (orig_for_stmt != for_stmt)
9652 var = decl;
9653 else if (!is_gimple_reg (decl)
9654 || (ort == ORT_SIMD
9655 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) > 1))
9657 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
9658 /* Make sure omp_add_variable is not called on it prematurely.
9659 We call it ourselves a few lines later. */
9660 gimplify_omp_ctxp = NULL;
9661 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
9662 gimplify_omp_ctxp = ctx;
9663 TREE_OPERAND (t, 0) = var;
9665 gimplify_seq_add_stmt (&for_body, gimple_build_assign (decl, var));
9667 if (ort == ORT_SIMD
9668 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
9670 c2 = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
9671 OMP_CLAUSE_LINEAR_NO_COPYIN (c2) = 1;
9672 OMP_CLAUSE_LINEAR_NO_COPYOUT (c2) = 1;
9673 OMP_CLAUSE_DECL (c2) = var;
9674 OMP_CLAUSE_CHAIN (c2) = OMP_FOR_CLAUSES (for_stmt);
9675 OMP_FOR_CLAUSES (for_stmt) = c2;
9676 omp_add_variable (gimplify_omp_ctxp, var,
9677 GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN);
9678 if (c == NULL_TREE)
9680 c = c2;
9681 c2 = NULL_TREE;
9684 else
9685 omp_add_variable (gimplify_omp_ctxp, var,
9686 GOVD_PRIVATE | GOVD_SEEN);
9688 else
9689 var = decl;
9691 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
9692 is_gimple_val, fb_rvalue, false);
9693 ret = MIN (ret, tret);
9694 if (ret == GS_ERROR)
9695 return ret;
9697 /* Handle OMP_FOR_COND. */
9698 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
9699 gcc_assert (COMPARISON_CLASS_P (t));
9700 gcc_assert (TREE_OPERAND (t, 0) == decl);
9702 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
9703 is_gimple_val, fb_rvalue, false);
9704 ret = MIN (ret, tret);
9706 /* Handle OMP_FOR_INCR. */
9707 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
9708 switch (TREE_CODE (t))
9710 case PREINCREMENT_EXPR:
9711 case POSTINCREMENT_EXPR:
9713 tree decl = TREE_OPERAND (t, 0);
9714 /* c_omp_for_incr_canonicalize_ptr() should have been
9715 called to massage things appropriately. */
9716 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
9718 if (orig_for_stmt != for_stmt)
9719 break;
9720 t = build_int_cst (TREE_TYPE (decl), 1);
9721 if (c)
9722 OMP_CLAUSE_LINEAR_STEP (c) = t;
9723 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
9724 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
9725 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
9726 break;
9729 case PREDECREMENT_EXPR:
9730 case POSTDECREMENT_EXPR:
9731 /* c_omp_for_incr_canonicalize_ptr() should have been
9732 called to massage things appropriately. */
9733 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
9734 if (orig_for_stmt != for_stmt)
9735 break;
9736 t = build_int_cst (TREE_TYPE (decl), -1);
9737 if (c)
9738 OMP_CLAUSE_LINEAR_STEP (c) = t;
9739 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
9740 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
9741 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
9742 break;
9744 case MODIFY_EXPR:
9745 gcc_assert (TREE_OPERAND (t, 0) == decl);
9746 TREE_OPERAND (t, 0) = var;
9748 t = TREE_OPERAND (t, 1);
9749 switch (TREE_CODE (t))
9751 case PLUS_EXPR:
9752 if (TREE_OPERAND (t, 1) == decl)
9754 TREE_OPERAND (t, 1) = TREE_OPERAND (t, 0);
9755 TREE_OPERAND (t, 0) = var;
9756 break;
9759 /* Fallthru. */
9760 case MINUS_EXPR:
9761 case POINTER_PLUS_EXPR:
9762 gcc_assert (TREE_OPERAND (t, 0) == decl);
9763 TREE_OPERAND (t, 0) = var;
9764 break;
9765 default:
9766 gcc_unreachable ();
9769 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
9770 is_gimple_val, fb_rvalue, false);
9771 ret = MIN (ret, tret);
9772 if (c)
9774 tree step = TREE_OPERAND (t, 1);
9775 tree stept = TREE_TYPE (decl);
9776 if (POINTER_TYPE_P (stept))
9777 stept = sizetype;
9778 step = fold_convert (stept, step);
9779 if (TREE_CODE (t) == MINUS_EXPR)
9780 step = fold_build1 (NEGATE_EXPR, stept, step);
9781 OMP_CLAUSE_LINEAR_STEP (c) = step;
9782 if (step != TREE_OPERAND (t, 1))
9784 tret = gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c),
9785 &for_pre_body, NULL,
9786 is_gimple_val, fb_rvalue, false);
9787 ret = MIN (ret, tret);
9790 break;
9792 default:
9793 gcc_unreachable ();
9796 if (c2)
9798 gcc_assert (c);
9799 OMP_CLAUSE_LINEAR_STEP (c2) = OMP_CLAUSE_LINEAR_STEP (c);
9802 if ((var != decl || collapse > 1) && orig_for_stmt == for_stmt)
9804 for (c = OMP_FOR_CLAUSES (for_stmt); c ; c = OMP_CLAUSE_CHAIN (c))
9805 if (((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
9806 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) == NULL)
9807 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
9808 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)
9809 && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c) == NULL))
9810 && OMP_CLAUSE_DECL (c) == decl)
9812 if (is_doacross && (collapse == 1 || i >= collapse))
9813 t = var;
9814 else
9816 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
9817 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
9818 gcc_assert (TREE_OPERAND (t, 0) == var);
9819 t = TREE_OPERAND (t, 1);
9820 gcc_assert (TREE_CODE (t) == PLUS_EXPR
9821 || TREE_CODE (t) == MINUS_EXPR
9822 || TREE_CODE (t) == POINTER_PLUS_EXPR);
9823 gcc_assert (TREE_OPERAND (t, 0) == var);
9824 t = build2 (TREE_CODE (t), TREE_TYPE (decl),
9825 is_doacross ? var : decl,
9826 TREE_OPERAND (t, 1));
9828 gimple_seq *seq;
9829 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
9830 seq = &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c);
9831 else
9832 seq = &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c);
9833 gimplify_assign (decl, t, seq);
9838 BITMAP_FREE (has_decl_expr);
9840 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
9842 push_gimplify_context ();
9843 if (TREE_CODE (OMP_FOR_BODY (orig_for_stmt)) != BIND_EXPR)
9845 OMP_FOR_BODY (orig_for_stmt)
9846 = build3 (BIND_EXPR, void_type_node, NULL,
9847 OMP_FOR_BODY (orig_for_stmt), NULL);
9848 TREE_SIDE_EFFECTS (OMP_FOR_BODY (orig_for_stmt)) = 1;
9852 gimple *g = gimplify_and_return_first (OMP_FOR_BODY (orig_for_stmt),
9853 &for_body);
9855 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
9857 if (gimple_code (g) == GIMPLE_BIND)
9858 pop_gimplify_context (g);
9859 else
9860 pop_gimplify_context (NULL);
9863 if (orig_for_stmt != for_stmt)
9864 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
9866 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
9867 decl = TREE_OPERAND (t, 0);
9868 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
9869 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
9870 gimplify_omp_ctxp = ctx->outer_context;
9871 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
9872 gimplify_omp_ctxp = ctx;
9873 omp_add_variable (gimplify_omp_ctxp, var, GOVD_PRIVATE | GOVD_SEEN);
9874 TREE_OPERAND (t, 0) = var;
9875 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
9876 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
9877 TREE_OPERAND (TREE_OPERAND (t, 1), 0) = var;
9880 gimplify_adjust_omp_clauses (pre_p, for_body,
9881 &OMP_FOR_CLAUSES (orig_for_stmt),
9882 TREE_CODE (orig_for_stmt));
9884 int kind;
9885 switch (TREE_CODE (orig_for_stmt))
9887 case OMP_FOR: kind = GF_OMP_FOR_KIND_FOR; break;
9888 case OMP_SIMD: kind = GF_OMP_FOR_KIND_SIMD; break;
9889 case CILK_SIMD: kind = GF_OMP_FOR_KIND_CILKSIMD; break;
9890 case CILK_FOR: kind = GF_OMP_FOR_KIND_CILKFOR; break;
9891 case OMP_DISTRIBUTE: kind = GF_OMP_FOR_KIND_DISTRIBUTE; break;
9892 case OMP_TASKLOOP: kind = GF_OMP_FOR_KIND_TASKLOOP; break;
9893 case OACC_LOOP: kind = GF_OMP_FOR_KIND_OACC_LOOP; break;
9894 default:
9895 gcc_unreachable ();
9897 gfor = gimple_build_omp_for (for_body, kind, OMP_FOR_CLAUSES (orig_for_stmt),
9898 TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)),
9899 for_pre_body);
9900 if (orig_for_stmt != for_stmt)
9901 gimple_omp_for_set_combined_p (gfor, true);
9902 if (gimplify_omp_ctxp
9903 && (gimplify_omp_ctxp->combined_loop
9904 || (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
9905 && gimplify_omp_ctxp->outer_context
9906 && gimplify_omp_ctxp->outer_context->combined_loop)))
9908 gimple_omp_for_set_combined_into_p (gfor, true);
9909 if (gimplify_omp_ctxp->combined_loop)
9910 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_SIMD);
9911 else
9912 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_FOR);
9915 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
9917 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
9918 gimple_omp_for_set_index (gfor, i, TREE_OPERAND (t, 0));
9919 gimple_omp_for_set_initial (gfor, i, TREE_OPERAND (t, 1));
9920 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
9921 gimple_omp_for_set_cond (gfor, i, TREE_CODE (t));
9922 gimple_omp_for_set_final (gfor, i, TREE_OPERAND (t, 1));
9923 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
9924 gimple_omp_for_set_incr (gfor, i, TREE_OPERAND (t, 1));
9927 /* OMP_TASKLOOP is gimplified as two GIMPLE_OMP_FOR taskloop
9928 constructs with GIMPLE_OMP_TASK sandwiched in between them.
9929 The outer taskloop stands for computing the number of iterations,
9930 counts for collapsed loops and holding taskloop specific clauses.
9931 The task construct stands for the effect of data sharing on the
9932 explicit task it creates and the inner taskloop stands for expansion
9933 of the static loop inside of the explicit task construct. */
9934 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
9936 tree *gfor_clauses_ptr = gimple_omp_for_clauses_ptr (gfor);
9937 tree task_clauses = NULL_TREE;
9938 tree c = *gfor_clauses_ptr;
9939 tree *gtask_clauses_ptr = &task_clauses;
9940 tree outer_for_clauses = NULL_TREE;
9941 tree *gforo_clauses_ptr = &outer_for_clauses;
9942 for (; c; c = OMP_CLAUSE_CHAIN (c))
9943 switch (OMP_CLAUSE_CODE (c))
9945 /* These clauses are allowed on task, move them there. */
9946 case OMP_CLAUSE_SHARED:
9947 case OMP_CLAUSE_FIRSTPRIVATE:
9948 case OMP_CLAUSE_DEFAULT:
9949 case OMP_CLAUSE_IF:
9950 case OMP_CLAUSE_UNTIED:
9951 case OMP_CLAUSE_FINAL:
9952 case OMP_CLAUSE_MERGEABLE:
9953 case OMP_CLAUSE_PRIORITY:
9954 *gtask_clauses_ptr = c;
9955 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
9956 break;
9957 case OMP_CLAUSE_PRIVATE:
9958 if (OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c))
9960 /* We want private on outer for and firstprivate
9961 on task. */
9962 *gtask_clauses_ptr
9963 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9964 OMP_CLAUSE_FIRSTPRIVATE);
9965 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
9966 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL);
9967 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
9968 *gforo_clauses_ptr = c;
9969 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
9971 else
9973 *gtask_clauses_ptr = c;
9974 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
9976 break;
9977 /* These clauses go into outer taskloop clauses. */
9978 case OMP_CLAUSE_GRAINSIZE:
9979 case OMP_CLAUSE_NUM_TASKS:
9980 case OMP_CLAUSE_NOGROUP:
9981 *gforo_clauses_ptr = c;
9982 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
9983 break;
9984 /* Taskloop clause we duplicate on both taskloops. */
9985 case OMP_CLAUSE_COLLAPSE:
9986 *gfor_clauses_ptr = c;
9987 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
9988 *gforo_clauses_ptr = copy_node (c);
9989 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
9990 break;
9991 /* For lastprivate, keep the clause on inner taskloop, and add
9992 a shared clause on task. If the same decl is also firstprivate,
9993 add also firstprivate clause on the inner taskloop. */
9994 case OMP_CLAUSE_LASTPRIVATE:
9995 if (OMP_CLAUSE_LASTPRIVATE_TASKLOOP_IV (c))
9997 /* For taskloop C++ lastprivate IVs, we want:
9998 1) private on outer taskloop
9999 2) firstprivate and shared on task
10000 3) lastprivate on inner taskloop */
10001 *gtask_clauses_ptr
10002 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
10003 OMP_CLAUSE_FIRSTPRIVATE);
10004 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
10005 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL);
10006 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
10007 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c) = 1;
10008 *gforo_clauses_ptr = build_omp_clause (OMP_CLAUSE_LOCATION (c),
10009 OMP_CLAUSE_PRIVATE);
10010 OMP_CLAUSE_DECL (*gforo_clauses_ptr) = OMP_CLAUSE_DECL (c);
10011 OMP_CLAUSE_PRIVATE_TASKLOOP_IV (*gforo_clauses_ptr) = 1;
10012 TREE_TYPE (*gforo_clauses_ptr) = TREE_TYPE (c);
10013 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
10015 *gfor_clauses_ptr = c;
10016 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
10017 *gtask_clauses_ptr
10018 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_SHARED);
10019 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
10020 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
10021 OMP_CLAUSE_SHARED_FIRSTPRIVATE (*gtask_clauses_ptr) = 1;
10022 gtask_clauses_ptr
10023 = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
10024 break;
10025 default:
10026 gcc_unreachable ();
10028 *gfor_clauses_ptr = NULL_TREE;
10029 *gtask_clauses_ptr = NULL_TREE;
10030 *gforo_clauses_ptr = NULL_TREE;
10031 g = gimple_build_bind (NULL_TREE, gfor, NULL_TREE);
10032 g = gimple_build_omp_task (g, task_clauses, NULL_TREE, NULL_TREE,
10033 NULL_TREE, NULL_TREE, NULL_TREE);
10034 gimple_omp_task_set_taskloop_p (g, true);
10035 g = gimple_build_bind (NULL_TREE, g, NULL_TREE);
10036 gomp_for *gforo
10037 = gimple_build_omp_for (g, GF_OMP_FOR_KIND_TASKLOOP, outer_for_clauses,
10038 gimple_omp_for_collapse (gfor),
10039 gimple_omp_for_pre_body (gfor));
10040 gimple_omp_for_set_pre_body (gfor, NULL);
10041 gimple_omp_for_set_combined_p (gforo, true);
10042 gimple_omp_for_set_combined_into_p (gfor, true);
10043 for (i = 0; i < (int) gimple_omp_for_collapse (gfor); i++)
10045 t = unshare_expr (gimple_omp_for_index (gfor, i));
10046 gimple_omp_for_set_index (gforo, i, t);
10047 t = unshare_expr (gimple_omp_for_initial (gfor, i));
10048 gimple_omp_for_set_initial (gforo, i, t);
10049 gimple_omp_for_set_cond (gforo, i,
10050 gimple_omp_for_cond (gfor, i));
10051 t = unshare_expr (gimple_omp_for_final (gfor, i));
10052 gimple_omp_for_set_final (gforo, i, t);
10053 t = unshare_expr (gimple_omp_for_incr (gfor, i));
10054 gimple_omp_for_set_incr (gforo, i, t);
10056 gimplify_seq_add_stmt (pre_p, gforo);
10058 else
10059 gimplify_seq_add_stmt (pre_p, gfor);
10060 if (ret != GS_ALL_DONE)
10061 return GS_ERROR;
10062 *expr_p = NULL_TREE;
10063 return GS_ALL_DONE;
10066 /* Helper function of optimize_target_teams, find OMP_TEAMS inside
10067 of OMP_TARGET's body. */
10069 static tree
10070 find_omp_teams (tree *tp, int *walk_subtrees, void *)
10072 *walk_subtrees = 0;
10073 switch (TREE_CODE (*tp))
10075 case OMP_TEAMS:
10076 return *tp;
10077 case BIND_EXPR:
10078 case STATEMENT_LIST:
10079 *walk_subtrees = 1;
10080 break;
10081 default:
10082 break;
10084 return NULL_TREE;
10087 /* Helper function of optimize_target_teams, determine if the expression
10088 can be computed safely before the target construct on the host. */
10090 static tree
10091 computable_teams_clause (tree *tp, int *walk_subtrees, void *)
10093 splay_tree_node n;
10095 if (TYPE_P (*tp))
10097 *walk_subtrees = 0;
10098 return NULL_TREE;
10100 switch (TREE_CODE (*tp))
10102 case VAR_DECL:
10103 case PARM_DECL:
10104 case RESULT_DECL:
10105 *walk_subtrees = 0;
10106 if (error_operand_p (*tp)
10107 || !INTEGRAL_TYPE_P (TREE_TYPE (*tp))
10108 || DECL_HAS_VALUE_EXPR_P (*tp)
10109 || DECL_THREAD_LOCAL_P (*tp)
10110 || TREE_SIDE_EFFECTS (*tp)
10111 || TREE_THIS_VOLATILE (*tp))
10112 return *tp;
10113 if (is_global_var (*tp)
10114 && (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (*tp))
10115 || lookup_attribute ("omp declare target link",
10116 DECL_ATTRIBUTES (*tp))))
10117 return *tp;
10118 n = splay_tree_lookup (gimplify_omp_ctxp->variables,
10119 (splay_tree_key) *tp);
10120 if (n == NULL)
10122 if (gimplify_omp_ctxp->target_map_scalars_firstprivate)
10123 return NULL_TREE;
10124 return *tp;
10126 else if (n->value & GOVD_LOCAL)
10127 return *tp;
10128 else if (n->value & GOVD_FIRSTPRIVATE)
10129 return NULL_TREE;
10130 else if ((n->value & (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
10131 == (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
10132 return NULL_TREE;
10133 return *tp;
10134 case INTEGER_CST:
10135 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
10136 return *tp;
10137 return NULL_TREE;
10138 case TARGET_EXPR:
10139 if (TARGET_EXPR_INITIAL (*tp)
10140 || TREE_CODE (TARGET_EXPR_SLOT (*tp)) != VAR_DECL)
10141 return *tp;
10142 return computable_teams_clause (&TARGET_EXPR_SLOT (*tp),
10143 walk_subtrees, NULL);
10144 /* Allow some reasonable subset of integral arithmetics. */
10145 case PLUS_EXPR:
10146 case MINUS_EXPR:
10147 case MULT_EXPR:
10148 case TRUNC_DIV_EXPR:
10149 case CEIL_DIV_EXPR:
10150 case FLOOR_DIV_EXPR:
10151 case ROUND_DIV_EXPR:
10152 case TRUNC_MOD_EXPR:
10153 case CEIL_MOD_EXPR:
10154 case FLOOR_MOD_EXPR:
10155 case ROUND_MOD_EXPR:
10156 case RDIV_EXPR:
10157 case EXACT_DIV_EXPR:
10158 case MIN_EXPR:
10159 case MAX_EXPR:
10160 case LSHIFT_EXPR:
10161 case RSHIFT_EXPR:
10162 case BIT_IOR_EXPR:
10163 case BIT_XOR_EXPR:
10164 case BIT_AND_EXPR:
10165 case NEGATE_EXPR:
10166 case ABS_EXPR:
10167 case BIT_NOT_EXPR:
10168 case NON_LVALUE_EXPR:
10169 CASE_CONVERT:
10170 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
10171 return *tp;
10172 return NULL_TREE;
10173 /* And disallow anything else, except for comparisons. */
10174 default:
10175 if (COMPARISON_CLASS_P (*tp))
10176 return NULL_TREE;
10177 return *tp;
10181 /* Try to determine if the num_teams and/or thread_limit expressions
10182 can have their values determined already before entering the
10183 target construct.
10184 INTEGER_CSTs trivially are,
10185 integral decls that are firstprivate (explicitly or implicitly)
10186 or explicitly map(always, to:) or map(always, tofrom:) on the target
10187 region too, and expressions involving simple arithmetics on those
10188 too, function calls are not ok, dereferencing something neither etc.
10189 Add NUM_TEAMS and THREAD_LIMIT clauses to the OMP_CLAUSES of
10190 EXPR based on what we find:
10191 0 stands for clause not specified at all, use implementation default
10192 -1 stands for value that can't be determined easily before entering
10193 the target construct.
10194 If teams construct is not present at all, use 1 for num_teams
10195 and 0 for thread_limit (only one team is involved, and the thread
10196 limit is implementation defined. */
10198 static void
10199 optimize_target_teams (tree target, gimple_seq *pre_p)
10201 tree body = OMP_BODY (target);
10202 tree teams = walk_tree (&body, find_omp_teams, NULL, NULL);
10203 tree num_teams = integer_zero_node;
10204 tree thread_limit = integer_zero_node;
10205 location_t num_teams_loc = EXPR_LOCATION (target);
10206 location_t thread_limit_loc = EXPR_LOCATION (target);
10207 tree c, *p, expr;
10208 struct gimplify_omp_ctx *target_ctx = gimplify_omp_ctxp;
10210 if (teams == NULL_TREE)
10211 num_teams = integer_one_node;
10212 else
10213 for (c = OMP_TEAMS_CLAUSES (teams); c; c = OMP_CLAUSE_CHAIN (c))
10215 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS)
10217 p = &num_teams;
10218 num_teams_loc = OMP_CLAUSE_LOCATION (c);
10220 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
10222 p = &thread_limit;
10223 thread_limit_loc = OMP_CLAUSE_LOCATION (c);
10225 else
10226 continue;
10227 expr = OMP_CLAUSE_OPERAND (c, 0);
10228 if (TREE_CODE (expr) == INTEGER_CST)
10230 *p = expr;
10231 continue;
10233 if (walk_tree (&expr, computable_teams_clause, NULL, NULL))
10235 *p = integer_minus_one_node;
10236 continue;
10238 *p = expr;
10239 gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
10240 if (gimplify_expr (p, pre_p, NULL, is_gimple_val, fb_rvalue, false)
10241 == GS_ERROR)
10243 gimplify_omp_ctxp = target_ctx;
10244 *p = integer_minus_one_node;
10245 continue;
10247 gimplify_omp_ctxp = target_ctx;
10248 if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR)
10249 OMP_CLAUSE_OPERAND (c, 0) = *p;
10251 c = build_omp_clause (thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
10252 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = thread_limit;
10253 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
10254 OMP_TARGET_CLAUSES (target) = c;
10255 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
10256 OMP_CLAUSE_NUM_TEAMS_EXPR (c) = num_teams;
10257 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
10258 OMP_TARGET_CLAUSES (target) = c;
10261 /* Gimplify the gross structure of several OMP constructs. */
10263 static void
10264 gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
10266 tree expr = *expr_p;
10267 gimple *stmt;
10268 gimple_seq body = NULL;
10269 enum omp_region_type ort;
10271 switch (TREE_CODE (expr))
10273 case OMP_SECTIONS:
10274 case OMP_SINGLE:
10275 ort = ORT_WORKSHARE;
10276 break;
10277 case OMP_TARGET:
10278 ort = OMP_TARGET_COMBINED (expr) ? ORT_COMBINED_TARGET : ORT_TARGET;
10279 break;
10280 case OACC_KERNELS:
10281 ort = ORT_ACC_KERNELS;
10282 break;
10283 case OACC_PARALLEL:
10284 ort = ORT_ACC_PARALLEL;
10285 break;
10286 case OACC_DATA:
10287 ort = ORT_ACC_DATA;
10288 break;
10289 case OMP_TARGET_DATA:
10290 ort = ORT_TARGET_DATA;
10291 break;
10292 case OMP_TEAMS:
10293 ort = OMP_TEAMS_COMBINED (expr) ? ORT_COMBINED_TEAMS : ORT_TEAMS;
10294 break;
10295 case OACC_HOST_DATA:
10296 ort = ORT_ACC_HOST_DATA;
10297 break;
10298 default:
10299 gcc_unreachable ();
10301 gimplify_scan_omp_clauses (&OMP_CLAUSES (expr), pre_p, ort,
10302 TREE_CODE (expr));
10303 if (TREE_CODE (expr) == OMP_TARGET)
10304 optimize_target_teams (expr, pre_p);
10305 if ((ort & (ORT_TARGET | ORT_TARGET_DATA)) != 0)
10307 push_gimplify_context ();
10308 gimple *g = gimplify_and_return_first (OMP_BODY (expr), &body);
10309 if (gimple_code (g) == GIMPLE_BIND)
10310 pop_gimplify_context (g);
10311 else
10312 pop_gimplify_context (NULL);
10313 if ((ort & ORT_TARGET_DATA) != 0)
10315 enum built_in_function end_ix;
10316 switch (TREE_CODE (expr))
10318 case OACC_DATA:
10319 case OACC_HOST_DATA:
10320 end_ix = BUILT_IN_GOACC_DATA_END;
10321 break;
10322 case OMP_TARGET_DATA:
10323 end_ix = BUILT_IN_GOMP_TARGET_END_DATA;
10324 break;
10325 default:
10326 gcc_unreachable ();
10328 tree fn = builtin_decl_explicit (end_ix);
10329 g = gimple_build_call (fn, 0);
10330 gimple_seq cleanup = NULL;
10331 gimple_seq_add_stmt (&cleanup, g);
10332 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
10333 body = NULL;
10334 gimple_seq_add_stmt (&body, g);
10337 else
10338 gimplify_and_add (OMP_BODY (expr), &body);
10339 gimplify_adjust_omp_clauses (pre_p, body, &OMP_CLAUSES (expr),
10340 TREE_CODE (expr));
10342 switch (TREE_CODE (expr))
10344 case OACC_DATA:
10345 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_DATA,
10346 OMP_CLAUSES (expr));
10347 break;
10348 case OACC_KERNELS:
10349 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_KERNELS,
10350 OMP_CLAUSES (expr));
10351 break;
10352 case OACC_HOST_DATA:
10353 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_HOST_DATA,
10354 OMP_CLAUSES (expr));
10355 break;
10356 case OACC_PARALLEL:
10357 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_PARALLEL,
10358 OMP_CLAUSES (expr));
10359 break;
10360 case OMP_SECTIONS:
10361 stmt = gimple_build_omp_sections (body, OMP_CLAUSES (expr));
10362 break;
10363 case OMP_SINGLE:
10364 stmt = gimple_build_omp_single (body, OMP_CLAUSES (expr));
10365 break;
10366 case OMP_TARGET:
10367 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_REGION,
10368 OMP_CLAUSES (expr));
10369 break;
10370 case OMP_TARGET_DATA:
10371 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_DATA,
10372 OMP_CLAUSES (expr));
10373 break;
10374 case OMP_TEAMS:
10375 stmt = gimple_build_omp_teams (body, OMP_CLAUSES (expr));
10376 break;
10377 default:
10378 gcc_unreachable ();
10381 gimplify_seq_add_stmt (pre_p, stmt);
10382 *expr_p = NULL_TREE;
10385 /* Gimplify the gross structure of OpenACC enter/exit data, update, and OpenMP
10386 target update constructs. */
10388 static void
10389 gimplify_omp_target_update (tree *expr_p, gimple_seq *pre_p)
10391 tree expr = *expr_p;
10392 int kind;
10393 gomp_target *stmt;
10394 enum omp_region_type ort = ORT_WORKSHARE;
10396 switch (TREE_CODE (expr))
10398 case OACC_ENTER_DATA:
10399 case OACC_EXIT_DATA:
10400 kind = GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA;
10401 ort = ORT_ACC;
10402 break;
10403 case OACC_UPDATE:
10404 kind = GF_OMP_TARGET_KIND_OACC_UPDATE;
10405 ort = ORT_ACC;
10406 break;
10407 case OMP_TARGET_UPDATE:
10408 kind = GF_OMP_TARGET_KIND_UPDATE;
10409 break;
10410 case OMP_TARGET_ENTER_DATA:
10411 kind = GF_OMP_TARGET_KIND_ENTER_DATA;
10412 break;
10413 case OMP_TARGET_EXIT_DATA:
10414 kind = GF_OMP_TARGET_KIND_EXIT_DATA;
10415 break;
10416 default:
10417 gcc_unreachable ();
10419 gimplify_scan_omp_clauses (&OMP_STANDALONE_CLAUSES (expr), pre_p,
10420 ort, TREE_CODE (expr));
10421 gimplify_adjust_omp_clauses (pre_p, NULL, &OMP_STANDALONE_CLAUSES (expr),
10422 TREE_CODE (expr));
10423 stmt = gimple_build_omp_target (NULL, kind, OMP_STANDALONE_CLAUSES (expr));
10425 gimplify_seq_add_stmt (pre_p, stmt);
10426 *expr_p = NULL_TREE;
10429 /* A subroutine of gimplify_omp_atomic. The front end is supposed to have
10430 stabilized the lhs of the atomic operation as *ADDR. Return true if
10431 EXPR is this stabilized form. */
10433 static bool
10434 goa_lhs_expr_p (tree expr, tree addr)
10436 /* Also include casts to other type variants. The C front end is fond
10437 of adding these for e.g. volatile variables. This is like
10438 STRIP_TYPE_NOPS but includes the main variant lookup. */
10439 STRIP_USELESS_TYPE_CONVERSION (expr);
10441 if (TREE_CODE (expr) == INDIRECT_REF)
10443 expr = TREE_OPERAND (expr, 0);
10444 while (expr != addr
10445 && (CONVERT_EXPR_P (expr)
10446 || TREE_CODE (expr) == NON_LVALUE_EXPR)
10447 && TREE_CODE (expr) == TREE_CODE (addr)
10448 && types_compatible_p (TREE_TYPE (expr), TREE_TYPE (addr)))
10450 expr = TREE_OPERAND (expr, 0);
10451 addr = TREE_OPERAND (addr, 0);
10453 if (expr == addr)
10454 return true;
10455 return (TREE_CODE (addr) == ADDR_EXPR
10456 && TREE_CODE (expr) == ADDR_EXPR
10457 && TREE_OPERAND (addr, 0) == TREE_OPERAND (expr, 0));
10459 if (TREE_CODE (addr) == ADDR_EXPR && expr == TREE_OPERAND (addr, 0))
10460 return true;
10461 return false;
10464 /* Walk *EXPR_P and replace appearances of *LHS_ADDR with LHS_VAR. If an
10465 expression does not involve the lhs, evaluate it into a temporary.
10466 Return 1 if the lhs appeared as a subexpression, 0 if it did not,
10467 or -1 if an error was encountered. */
10469 static int
10470 goa_stabilize_expr (tree *expr_p, gimple_seq *pre_p, tree lhs_addr,
10471 tree lhs_var)
10473 tree expr = *expr_p;
10474 int saw_lhs;
10476 if (goa_lhs_expr_p (expr, lhs_addr))
10478 *expr_p = lhs_var;
10479 return 1;
10481 if (is_gimple_val (expr))
10482 return 0;
10484 saw_lhs = 0;
10485 switch (TREE_CODE_CLASS (TREE_CODE (expr)))
10487 case tcc_binary:
10488 case tcc_comparison:
10489 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p, lhs_addr,
10490 lhs_var);
10491 /* FALLTHRU */
10492 case tcc_unary:
10493 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p, lhs_addr,
10494 lhs_var);
10495 break;
10496 case tcc_expression:
10497 switch (TREE_CODE (expr))
10499 case TRUTH_ANDIF_EXPR:
10500 case TRUTH_ORIF_EXPR:
10501 case TRUTH_AND_EXPR:
10502 case TRUTH_OR_EXPR:
10503 case TRUTH_XOR_EXPR:
10504 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
10505 lhs_addr, lhs_var);
10506 /* FALLTHRU */
10507 case TRUTH_NOT_EXPR:
10508 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
10509 lhs_addr, lhs_var);
10510 break;
10511 case COMPOUND_EXPR:
10512 /* Break out any preevaluations from cp_build_modify_expr. */
10513 for (; TREE_CODE (expr) == COMPOUND_EXPR;
10514 expr = TREE_OPERAND (expr, 1))
10515 gimplify_stmt (&TREE_OPERAND (expr, 0), pre_p);
10516 *expr_p = expr;
10517 return goa_stabilize_expr (expr_p, pre_p, lhs_addr, lhs_var);
10518 default:
10519 break;
10521 break;
10522 default:
10523 break;
10526 if (saw_lhs == 0)
10528 enum gimplify_status gs;
10529 gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_val, fb_rvalue);
10530 if (gs != GS_ALL_DONE)
10531 saw_lhs = -1;
10534 return saw_lhs;
10537 /* Gimplify an OMP_ATOMIC statement. */
10539 static enum gimplify_status
10540 gimplify_omp_atomic (tree *expr_p, gimple_seq *pre_p)
10542 tree addr = TREE_OPERAND (*expr_p, 0);
10543 tree rhs = TREE_CODE (*expr_p) == OMP_ATOMIC_READ
10544 ? NULL : TREE_OPERAND (*expr_p, 1);
10545 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
10546 tree tmp_load;
10547 gomp_atomic_load *loadstmt;
10548 gomp_atomic_store *storestmt;
10550 tmp_load = create_tmp_reg (type);
10551 if (rhs && goa_stabilize_expr (&rhs, pre_p, addr, tmp_load) < 0)
10552 return GS_ERROR;
10554 if (gimplify_expr (&addr, pre_p, NULL, is_gimple_val, fb_rvalue)
10555 != GS_ALL_DONE)
10556 return GS_ERROR;
10558 loadstmt = gimple_build_omp_atomic_load (tmp_load, addr);
10559 gimplify_seq_add_stmt (pre_p, loadstmt);
10560 if (rhs && gimplify_expr (&rhs, pre_p, NULL, is_gimple_val, fb_rvalue)
10561 != GS_ALL_DONE)
10562 return GS_ERROR;
10564 if (TREE_CODE (*expr_p) == OMP_ATOMIC_READ)
10565 rhs = tmp_load;
10566 storestmt = gimple_build_omp_atomic_store (rhs);
10567 gimplify_seq_add_stmt (pre_p, storestmt);
10568 if (OMP_ATOMIC_SEQ_CST (*expr_p))
10570 gimple_omp_atomic_set_seq_cst (loadstmt);
10571 gimple_omp_atomic_set_seq_cst (storestmt);
10573 switch (TREE_CODE (*expr_p))
10575 case OMP_ATOMIC_READ:
10576 case OMP_ATOMIC_CAPTURE_OLD:
10577 *expr_p = tmp_load;
10578 gimple_omp_atomic_set_need_value (loadstmt);
10579 break;
10580 case OMP_ATOMIC_CAPTURE_NEW:
10581 *expr_p = rhs;
10582 gimple_omp_atomic_set_need_value (storestmt);
10583 break;
10584 default:
10585 *expr_p = NULL;
10586 break;
10589 return GS_ALL_DONE;
10592 /* Gimplify a TRANSACTION_EXPR. This involves gimplification of the
10593 body, and adding some EH bits. */
10595 static enum gimplify_status
10596 gimplify_transaction (tree *expr_p, gimple_seq *pre_p)
10598 tree expr = *expr_p, temp, tbody = TRANSACTION_EXPR_BODY (expr);
10599 gimple *body_stmt;
10600 gtransaction *trans_stmt;
10601 gimple_seq body = NULL;
10602 int subcode = 0;
10604 /* Wrap the transaction body in a BIND_EXPR so we have a context
10605 where to put decls for OMP. */
10606 if (TREE_CODE (tbody) != BIND_EXPR)
10608 tree bind = build3 (BIND_EXPR, void_type_node, NULL, tbody, NULL);
10609 TREE_SIDE_EFFECTS (bind) = 1;
10610 SET_EXPR_LOCATION (bind, EXPR_LOCATION (tbody));
10611 TRANSACTION_EXPR_BODY (expr) = bind;
10614 push_gimplify_context ();
10615 temp = voidify_wrapper_expr (*expr_p, NULL);
10617 body_stmt = gimplify_and_return_first (TRANSACTION_EXPR_BODY (expr), &body);
10618 pop_gimplify_context (body_stmt);
10620 trans_stmt = gimple_build_transaction (body);
10621 if (TRANSACTION_EXPR_OUTER (expr))
10622 subcode = GTMA_IS_OUTER;
10623 else if (TRANSACTION_EXPR_RELAXED (expr))
10624 subcode = GTMA_IS_RELAXED;
10625 gimple_transaction_set_subcode (trans_stmt, subcode);
10627 gimplify_seq_add_stmt (pre_p, trans_stmt);
10629 if (temp)
10631 *expr_p = temp;
10632 return GS_OK;
10635 *expr_p = NULL_TREE;
10636 return GS_ALL_DONE;
10639 /* Gimplify an OMP_ORDERED construct. EXPR is the tree version. BODY
10640 is the OMP_BODY of the original EXPR (which has already been
10641 gimplified so it's not present in the EXPR).
10643 Return the gimplified GIMPLE_OMP_ORDERED tuple. */
10645 static gimple *
10646 gimplify_omp_ordered (tree expr, gimple_seq body)
10648 tree c, decls;
10649 int failures = 0;
10650 unsigned int i;
10651 tree source_c = NULL_TREE;
10652 tree sink_c = NULL_TREE;
10654 if (gimplify_omp_ctxp)
10656 for (c = OMP_ORDERED_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
10657 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
10658 && gimplify_omp_ctxp->loop_iter_var.is_empty ()
10659 && (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK
10660 || OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE))
10662 error_at (OMP_CLAUSE_LOCATION (c),
10663 "%<ordered%> construct with %<depend%> clause must be "
10664 "closely nested inside a loop with %<ordered%> clause "
10665 "with a parameter");
10666 failures++;
10668 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
10669 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
10671 bool fail = false;
10672 for (decls = OMP_CLAUSE_DECL (c), i = 0;
10673 decls && TREE_CODE (decls) == TREE_LIST;
10674 decls = TREE_CHAIN (decls), ++i)
10675 if (i >= gimplify_omp_ctxp->loop_iter_var.length () / 2)
10676 continue;
10677 else if (TREE_VALUE (decls)
10678 != gimplify_omp_ctxp->loop_iter_var[2 * i])
10680 error_at (OMP_CLAUSE_LOCATION (c),
10681 "variable %qE is not an iteration "
10682 "of outermost loop %d, expected %qE",
10683 TREE_VALUE (decls), i + 1,
10684 gimplify_omp_ctxp->loop_iter_var[2 * i]);
10685 fail = true;
10686 failures++;
10688 else
10689 TREE_VALUE (decls)
10690 = gimplify_omp_ctxp->loop_iter_var[2 * i + 1];
10691 if (!fail && i != gimplify_omp_ctxp->loop_iter_var.length () / 2)
10693 error_at (OMP_CLAUSE_LOCATION (c),
10694 "number of variables in %<depend(sink)%> "
10695 "clause does not match number of "
10696 "iteration variables");
10697 failures++;
10699 sink_c = c;
10701 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
10702 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
10704 if (source_c)
10706 error_at (OMP_CLAUSE_LOCATION (c),
10707 "more than one %<depend(source)%> clause on an "
10708 "%<ordered%> construct");
10709 failures++;
10711 else
10712 source_c = c;
10715 if (source_c && sink_c)
10717 error_at (OMP_CLAUSE_LOCATION (source_c),
10718 "%<depend(source)%> clause specified together with "
10719 "%<depend(sink:)%> clauses on the same construct");
10720 failures++;
10723 if (failures)
10724 return gimple_build_nop ();
10725 return gimple_build_omp_ordered (body, OMP_ORDERED_CLAUSES (expr));
10728 /* Convert the GENERIC expression tree *EXPR_P to GIMPLE. If the
10729 expression produces a value to be used as an operand inside a GIMPLE
10730 statement, the value will be stored back in *EXPR_P. This value will
10731 be a tree of class tcc_declaration, tcc_constant, tcc_reference or
10732 an SSA_NAME. The corresponding sequence of GIMPLE statements is
10733 emitted in PRE_P and POST_P.
10735 Additionally, this process may overwrite parts of the input
10736 expression during gimplification. Ideally, it should be
10737 possible to do non-destructive gimplification.
10739 EXPR_P points to the GENERIC expression to convert to GIMPLE. If
10740 the expression needs to evaluate to a value to be used as
10741 an operand in a GIMPLE statement, this value will be stored in
10742 *EXPR_P on exit. This happens when the caller specifies one
10743 of fb_lvalue or fb_rvalue fallback flags.
10745 PRE_P will contain the sequence of GIMPLE statements corresponding
10746 to the evaluation of EXPR and all the side-effects that must
10747 be executed before the main expression. On exit, the last
10748 statement of PRE_P is the core statement being gimplified. For
10749 instance, when gimplifying 'if (++a)' the last statement in
10750 PRE_P will be 'if (t.1)' where t.1 is the result of
10751 pre-incrementing 'a'.
10753 POST_P will contain the sequence of GIMPLE statements corresponding
10754 to the evaluation of all the side-effects that must be executed
10755 after the main expression. If this is NULL, the post
10756 side-effects are stored at the end of PRE_P.
10758 The reason why the output is split in two is to handle post
10759 side-effects explicitly. In some cases, an expression may have
10760 inner and outer post side-effects which need to be emitted in
10761 an order different from the one given by the recursive
10762 traversal. For instance, for the expression (*p--)++ the post
10763 side-effects of '--' must actually occur *after* the post
10764 side-effects of '++'. However, gimplification will first visit
10765 the inner expression, so if a separate POST sequence was not
10766 used, the resulting sequence would be:
10768 1 t.1 = *p
10769 2 p = p - 1
10770 3 t.2 = t.1 + 1
10771 4 *p = t.2
10773 However, the post-decrement operation in line #2 must not be
10774 evaluated until after the store to *p at line #4, so the
10775 correct sequence should be:
10777 1 t.1 = *p
10778 2 t.2 = t.1 + 1
10779 3 *p = t.2
10780 4 p = p - 1
10782 So, by specifying a separate post queue, it is possible
10783 to emit the post side-effects in the correct order.
10784 If POST_P is NULL, an internal queue will be used. Before
10785 returning to the caller, the sequence POST_P is appended to
10786 the main output sequence PRE_P.
10788 GIMPLE_TEST_F points to a function that takes a tree T and
10789 returns nonzero if T is in the GIMPLE form requested by the
10790 caller. The GIMPLE predicates are in gimple.c.
10792 FALLBACK tells the function what sort of a temporary we want if
10793 gimplification cannot produce an expression that complies with
10794 GIMPLE_TEST_F.
10796 fb_none means that no temporary should be generated
10797 fb_rvalue means that an rvalue is OK to generate
10798 fb_lvalue means that an lvalue is OK to generate
10799 fb_either means that either is OK, but an lvalue is preferable.
10800 fb_mayfail means that gimplification may fail (in which case
10801 GS_ERROR will be returned)
10803 The return value is either GS_ERROR or GS_ALL_DONE, since this
10804 function iterates until EXPR is completely gimplified or an error
10805 occurs. */
10807 enum gimplify_status
10808 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
10809 bool (*gimple_test_f) (tree), fallback_t fallback)
10811 tree tmp;
10812 gimple_seq internal_pre = NULL;
10813 gimple_seq internal_post = NULL;
10814 tree save_expr;
10815 bool is_statement;
10816 location_t saved_location;
10817 enum gimplify_status ret;
10818 gimple_stmt_iterator pre_last_gsi, post_last_gsi;
10820 save_expr = *expr_p;
10821 if (save_expr == NULL_TREE)
10822 return GS_ALL_DONE;
10824 /* If we are gimplifying a top-level statement, PRE_P must be valid. */
10825 is_statement = gimple_test_f == is_gimple_stmt;
10826 if (is_statement)
10827 gcc_assert (pre_p);
10829 /* Consistency checks. */
10830 if (gimple_test_f == is_gimple_reg)
10831 gcc_assert (fallback & (fb_rvalue | fb_lvalue));
10832 else if (gimple_test_f == is_gimple_val
10833 || gimple_test_f == is_gimple_call_addr
10834 || gimple_test_f == is_gimple_condexpr
10835 || gimple_test_f == is_gimple_mem_rhs
10836 || gimple_test_f == is_gimple_mem_rhs_or_call
10837 || gimple_test_f == is_gimple_reg_rhs
10838 || gimple_test_f == is_gimple_reg_rhs_or_call
10839 || gimple_test_f == is_gimple_asm_val
10840 || gimple_test_f == is_gimple_mem_ref_addr)
10841 gcc_assert (fallback & fb_rvalue);
10842 else if (gimple_test_f == is_gimple_min_lval
10843 || gimple_test_f == is_gimple_lvalue)
10844 gcc_assert (fallback & fb_lvalue);
10845 else if (gimple_test_f == is_gimple_addressable)
10846 gcc_assert (fallback & fb_either);
10847 else if (gimple_test_f == is_gimple_stmt)
10848 gcc_assert (fallback == fb_none);
10849 else
10851 /* We should have recognized the GIMPLE_TEST_F predicate to
10852 know what kind of fallback to use in case a temporary is
10853 needed to hold the value or address of *EXPR_P. */
10854 gcc_unreachable ();
10857 /* We used to check the predicate here and return immediately if it
10858 succeeds. This is wrong; the design is for gimplification to be
10859 idempotent, and for the predicates to only test for valid forms, not
10860 whether they are fully simplified. */
10861 if (pre_p == NULL)
10862 pre_p = &internal_pre;
10864 if (post_p == NULL)
10865 post_p = &internal_post;
10867 /* Remember the last statements added to PRE_P and POST_P. Every
10868 new statement added by the gimplification helpers needs to be
10869 annotated with location information. To centralize the
10870 responsibility, we remember the last statement that had been
10871 added to both queues before gimplifying *EXPR_P. If
10872 gimplification produces new statements in PRE_P and POST_P, those
10873 statements will be annotated with the same location information
10874 as *EXPR_P. */
10875 pre_last_gsi = gsi_last (*pre_p);
10876 post_last_gsi = gsi_last (*post_p);
10878 saved_location = input_location;
10879 if (save_expr != error_mark_node
10880 && EXPR_HAS_LOCATION (*expr_p))
10881 input_location = EXPR_LOCATION (*expr_p);
10883 /* Loop over the specific gimplifiers until the toplevel node
10884 remains the same. */
10887 /* Strip away as many useless type conversions as possible
10888 at the toplevel. */
10889 STRIP_USELESS_TYPE_CONVERSION (*expr_p);
10891 /* Remember the expr. */
10892 save_expr = *expr_p;
10894 /* Die, die, die, my darling. */
10895 if (save_expr == error_mark_node
10896 || (TREE_TYPE (save_expr)
10897 && TREE_TYPE (save_expr) == error_mark_node))
10899 ret = GS_ERROR;
10900 break;
10903 /* Do any language-specific gimplification. */
10904 ret = ((enum gimplify_status)
10905 lang_hooks.gimplify_expr (expr_p, pre_p, post_p));
10906 if (ret == GS_OK)
10908 if (*expr_p == NULL_TREE)
10909 break;
10910 if (*expr_p != save_expr)
10911 continue;
10913 else if (ret != GS_UNHANDLED)
10914 break;
10916 /* Make sure that all the cases set 'ret' appropriately. */
10917 ret = GS_UNHANDLED;
10918 switch (TREE_CODE (*expr_p))
10920 /* First deal with the special cases. */
10922 case POSTINCREMENT_EXPR:
10923 case POSTDECREMENT_EXPR:
10924 case PREINCREMENT_EXPR:
10925 case PREDECREMENT_EXPR:
10926 ret = gimplify_self_mod_expr (expr_p, pre_p, post_p,
10927 fallback != fb_none,
10928 TREE_TYPE (*expr_p));
10929 break;
10931 case VIEW_CONVERT_EXPR:
10932 if (is_gimple_reg_type (TREE_TYPE (*expr_p))
10933 && is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0))))
10935 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
10936 post_p, is_gimple_val, fb_rvalue);
10937 recalculate_side_effects (*expr_p);
10938 break;
10940 /* Fallthru. */
10942 case ARRAY_REF:
10943 case ARRAY_RANGE_REF:
10944 case REALPART_EXPR:
10945 case IMAGPART_EXPR:
10946 case COMPONENT_REF:
10947 ret = gimplify_compound_lval (expr_p, pre_p, post_p,
10948 fallback ? fallback : fb_rvalue);
10949 break;
10951 case COND_EXPR:
10952 ret = gimplify_cond_expr (expr_p, pre_p, fallback);
10954 /* C99 code may assign to an array in a structure value of a
10955 conditional expression, and this has undefined behavior
10956 only on execution, so create a temporary if an lvalue is
10957 required. */
10958 if (fallback == fb_lvalue)
10960 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
10961 mark_addressable (*expr_p);
10962 ret = GS_OK;
10964 break;
10966 case CALL_EXPR:
10967 ret = gimplify_call_expr (expr_p, pre_p, fallback != fb_none);
10969 /* C99 code may assign to an array in a structure returned
10970 from a function, and this has undefined behavior only on
10971 execution, so create a temporary if an lvalue is
10972 required. */
10973 if (fallback == fb_lvalue)
10975 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
10976 mark_addressable (*expr_p);
10977 ret = GS_OK;
10979 break;
10981 case TREE_LIST:
10982 gcc_unreachable ();
10984 case COMPOUND_EXPR:
10985 ret = gimplify_compound_expr (expr_p, pre_p, fallback != fb_none);
10986 break;
10988 case COMPOUND_LITERAL_EXPR:
10989 ret = gimplify_compound_literal_expr (expr_p, pre_p,
10990 gimple_test_f, fallback);
10991 break;
10993 case MODIFY_EXPR:
10994 case INIT_EXPR:
10995 ret = gimplify_modify_expr (expr_p, pre_p, post_p,
10996 fallback != fb_none);
10997 break;
10999 case TRUTH_ANDIF_EXPR:
11000 case TRUTH_ORIF_EXPR:
11002 /* Preserve the original type of the expression and the
11003 source location of the outer expression. */
11004 tree org_type = TREE_TYPE (*expr_p);
11005 *expr_p = gimple_boolify (*expr_p);
11006 *expr_p = build3_loc (input_location, COND_EXPR,
11007 org_type, *expr_p,
11008 fold_convert_loc
11009 (input_location,
11010 org_type, boolean_true_node),
11011 fold_convert_loc
11012 (input_location,
11013 org_type, boolean_false_node));
11014 ret = GS_OK;
11015 break;
11018 case TRUTH_NOT_EXPR:
11020 tree type = TREE_TYPE (*expr_p);
11021 /* The parsers are careful to generate TRUTH_NOT_EXPR
11022 only with operands that are always zero or one.
11023 We do not fold here but handle the only interesting case
11024 manually, as fold may re-introduce the TRUTH_NOT_EXPR. */
11025 *expr_p = gimple_boolify (*expr_p);
11026 if (TYPE_PRECISION (TREE_TYPE (*expr_p)) == 1)
11027 *expr_p = build1_loc (input_location, BIT_NOT_EXPR,
11028 TREE_TYPE (*expr_p),
11029 TREE_OPERAND (*expr_p, 0));
11030 else
11031 *expr_p = build2_loc (input_location, BIT_XOR_EXPR,
11032 TREE_TYPE (*expr_p),
11033 TREE_OPERAND (*expr_p, 0),
11034 build_int_cst (TREE_TYPE (*expr_p), 1));
11035 if (!useless_type_conversion_p (type, TREE_TYPE (*expr_p)))
11036 *expr_p = fold_convert_loc (input_location, type, *expr_p);
11037 ret = GS_OK;
11038 break;
11041 case ADDR_EXPR:
11042 ret = gimplify_addr_expr (expr_p, pre_p, post_p);
11043 break;
11045 case ANNOTATE_EXPR:
11047 tree cond = TREE_OPERAND (*expr_p, 0);
11048 tree kind = TREE_OPERAND (*expr_p, 1);
11049 tree type = TREE_TYPE (cond);
11050 if (!INTEGRAL_TYPE_P (type))
11052 *expr_p = cond;
11053 ret = GS_OK;
11054 break;
11056 tree tmp = create_tmp_var (type);
11057 gimplify_arg (&cond, pre_p, EXPR_LOCATION (*expr_p));
11058 gcall *call
11059 = gimple_build_call_internal (IFN_ANNOTATE, 2, cond, kind);
11060 gimple_call_set_lhs (call, tmp);
11061 gimplify_seq_add_stmt (pre_p, call);
11062 *expr_p = tmp;
11063 ret = GS_ALL_DONE;
11064 break;
11067 case VA_ARG_EXPR:
11068 ret = gimplify_va_arg_expr (expr_p, pre_p, post_p);
11069 break;
11071 CASE_CONVERT:
11072 if (IS_EMPTY_STMT (*expr_p))
11074 ret = GS_ALL_DONE;
11075 break;
11078 if (VOID_TYPE_P (TREE_TYPE (*expr_p))
11079 || fallback == fb_none)
11081 /* Just strip a conversion to void (or in void context) and
11082 try again. */
11083 *expr_p = TREE_OPERAND (*expr_p, 0);
11084 ret = GS_OK;
11085 break;
11088 ret = gimplify_conversion (expr_p);
11089 if (ret == GS_ERROR)
11090 break;
11091 if (*expr_p != save_expr)
11092 break;
11093 /* FALLTHRU */
11095 case FIX_TRUNC_EXPR:
11096 /* unary_expr: ... | '(' cast ')' val | ... */
11097 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
11098 is_gimple_val, fb_rvalue);
11099 recalculate_side_effects (*expr_p);
11100 break;
11102 case INDIRECT_REF:
11104 bool volatilep = TREE_THIS_VOLATILE (*expr_p);
11105 bool notrap = TREE_THIS_NOTRAP (*expr_p);
11106 tree saved_ptr_type = TREE_TYPE (TREE_OPERAND (*expr_p, 0));
11108 *expr_p = fold_indirect_ref_loc (input_location, *expr_p);
11109 if (*expr_p != save_expr)
11111 ret = GS_OK;
11112 break;
11115 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
11116 is_gimple_reg, fb_rvalue);
11117 if (ret == GS_ERROR)
11118 break;
11120 recalculate_side_effects (*expr_p);
11121 *expr_p = fold_build2_loc (input_location, MEM_REF,
11122 TREE_TYPE (*expr_p),
11123 TREE_OPERAND (*expr_p, 0),
11124 build_int_cst (saved_ptr_type, 0));
11125 TREE_THIS_VOLATILE (*expr_p) = volatilep;
11126 TREE_THIS_NOTRAP (*expr_p) = notrap;
11127 ret = GS_OK;
11128 break;
11131 /* We arrive here through the various re-gimplifcation paths. */
11132 case MEM_REF:
11133 /* First try re-folding the whole thing. */
11134 tmp = fold_binary (MEM_REF, TREE_TYPE (*expr_p),
11135 TREE_OPERAND (*expr_p, 0),
11136 TREE_OPERAND (*expr_p, 1));
11137 if (tmp)
11139 REF_REVERSE_STORAGE_ORDER (tmp)
11140 = REF_REVERSE_STORAGE_ORDER (*expr_p);
11141 *expr_p = tmp;
11142 recalculate_side_effects (*expr_p);
11143 ret = GS_OK;
11144 break;
11146 /* Avoid re-gimplifying the address operand if it is already
11147 in suitable form. Re-gimplifying would mark the address
11148 operand addressable. Always gimplify when not in SSA form
11149 as we still may have to gimplify decls with value-exprs. */
11150 if (!gimplify_ctxp || !gimple_in_ssa_p (cfun)
11151 || !is_gimple_mem_ref_addr (TREE_OPERAND (*expr_p, 0)))
11153 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
11154 is_gimple_mem_ref_addr, fb_rvalue);
11155 if (ret == GS_ERROR)
11156 break;
11158 recalculate_side_effects (*expr_p);
11159 ret = GS_ALL_DONE;
11160 break;
11162 /* Constants need not be gimplified. */
11163 case INTEGER_CST:
11164 case REAL_CST:
11165 case FIXED_CST:
11166 case STRING_CST:
11167 case COMPLEX_CST:
11168 case VECTOR_CST:
11169 /* Drop the overflow flag on constants, we do not want
11170 that in the GIMPLE IL. */
11171 if (TREE_OVERFLOW_P (*expr_p))
11172 *expr_p = drop_tree_overflow (*expr_p);
11173 ret = GS_ALL_DONE;
11174 break;
11176 case CONST_DECL:
11177 /* If we require an lvalue, such as for ADDR_EXPR, retain the
11178 CONST_DECL node. Otherwise the decl is replaceable by its
11179 value. */
11180 /* ??? Should be == fb_lvalue, but ADDR_EXPR passes fb_either. */
11181 if (fallback & fb_lvalue)
11182 ret = GS_ALL_DONE;
11183 else
11185 *expr_p = DECL_INITIAL (*expr_p);
11186 ret = GS_OK;
11188 break;
11190 case DECL_EXPR:
11191 ret = gimplify_decl_expr (expr_p, pre_p);
11192 break;
11194 case BIND_EXPR:
11195 ret = gimplify_bind_expr (expr_p, pre_p);
11196 break;
11198 case LOOP_EXPR:
11199 ret = gimplify_loop_expr (expr_p, pre_p);
11200 break;
11202 case SWITCH_EXPR:
11203 ret = gimplify_switch_expr (expr_p, pre_p);
11204 break;
11206 case EXIT_EXPR:
11207 ret = gimplify_exit_expr (expr_p);
11208 break;
11210 case GOTO_EXPR:
11211 /* If the target is not LABEL, then it is a computed jump
11212 and the target needs to be gimplified. */
11213 if (TREE_CODE (GOTO_DESTINATION (*expr_p)) != LABEL_DECL)
11215 ret = gimplify_expr (&GOTO_DESTINATION (*expr_p), pre_p,
11216 NULL, is_gimple_val, fb_rvalue);
11217 if (ret == GS_ERROR)
11218 break;
11220 gimplify_seq_add_stmt (pre_p,
11221 gimple_build_goto (GOTO_DESTINATION (*expr_p)));
11222 ret = GS_ALL_DONE;
11223 break;
11225 case PREDICT_EXPR:
11226 gimplify_seq_add_stmt (pre_p,
11227 gimple_build_predict (PREDICT_EXPR_PREDICTOR (*expr_p),
11228 PREDICT_EXPR_OUTCOME (*expr_p)));
11229 ret = GS_ALL_DONE;
11230 break;
11232 case LABEL_EXPR:
11233 ret = gimplify_label_expr (expr_p, pre_p);
11234 break;
11236 case CASE_LABEL_EXPR:
11237 ret = gimplify_case_label_expr (expr_p, pre_p);
11238 break;
11240 case RETURN_EXPR:
11241 ret = gimplify_return_expr (*expr_p, pre_p);
11242 break;
11244 case CONSTRUCTOR:
11245 /* Don't reduce this in place; let gimplify_init_constructor work its
11246 magic. Buf if we're just elaborating this for side effects, just
11247 gimplify any element that has side-effects. */
11248 if (fallback == fb_none)
11250 unsigned HOST_WIDE_INT ix;
11251 tree val;
11252 tree temp = NULL_TREE;
11253 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (*expr_p), ix, val)
11254 if (TREE_SIDE_EFFECTS (val))
11255 append_to_statement_list (val, &temp);
11257 *expr_p = temp;
11258 ret = temp ? GS_OK : GS_ALL_DONE;
11260 /* C99 code may assign to an array in a constructed
11261 structure or union, and this has undefined behavior only
11262 on execution, so create a temporary if an lvalue is
11263 required. */
11264 else if (fallback == fb_lvalue)
11266 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
11267 mark_addressable (*expr_p);
11268 ret = GS_OK;
11270 else
11271 ret = GS_ALL_DONE;
11272 break;
11274 /* The following are special cases that are not handled by the
11275 original GIMPLE grammar. */
11277 /* SAVE_EXPR nodes are converted into a GIMPLE identifier and
11278 eliminated. */
11279 case SAVE_EXPR:
11280 ret = gimplify_save_expr (expr_p, pre_p, post_p);
11281 break;
11283 case BIT_FIELD_REF:
11284 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
11285 post_p, is_gimple_lvalue, fb_either);
11286 recalculate_side_effects (*expr_p);
11287 break;
11289 case TARGET_MEM_REF:
11291 enum gimplify_status r0 = GS_ALL_DONE, r1 = GS_ALL_DONE;
11293 if (TMR_BASE (*expr_p))
11294 r0 = gimplify_expr (&TMR_BASE (*expr_p), pre_p,
11295 post_p, is_gimple_mem_ref_addr, fb_either);
11296 if (TMR_INDEX (*expr_p))
11297 r1 = gimplify_expr (&TMR_INDEX (*expr_p), pre_p,
11298 post_p, is_gimple_val, fb_rvalue);
11299 if (TMR_INDEX2 (*expr_p))
11300 r1 = gimplify_expr (&TMR_INDEX2 (*expr_p), pre_p,
11301 post_p, is_gimple_val, fb_rvalue);
11302 /* TMR_STEP and TMR_OFFSET are always integer constants. */
11303 ret = MIN (r0, r1);
11305 break;
11307 case NON_LVALUE_EXPR:
11308 /* This should have been stripped above. */
11309 gcc_unreachable ();
11311 case ASM_EXPR:
11312 ret = gimplify_asm_expr (expr_p, pre_p, post_p);
11313 break;
11315 case TRY_FINALLY_EXPR:
11316 case TRY_CATCH_EXPR:
11318 gimple_seq eval, cleanup;
11319 gtry *try_;
11321 /* Calls to destructors are generated automatically in FINALLY/CATCH
11322 block. They should have location as UNKNOWN_LOCATION. However,
11323 gimplify_call_expr will reset these call stmts to input_location
11324 if it finds stmt's location is unknown. To prevent resetting for
11325 destructors, we set the input_location to unknown.
11326 Note that this only affects the destructor calls in FINALLY/CATCH
11327 block, and will automatically reset to its original value by the
11328 end of gimplify_expr. */
11329 input_location = UNKNOWN_LOCATION;
11330 eval = cleanup = NULL;
11331 gimplify_and_add (TREE_OPERAND (*expr_p, 0), &eval);
11332 gimplify_and_add (TREE_OPERAND (*expr_p, 1), &cleanup);
11333 /* Don't create bogus GIMPLE_TRY with empty cleanup. */
11334 if (gimple_seq_empty_p (cleanup))
11336 gimple_seq_add_seq (pre_p, eval);
11337 ret = GS_ALL_DONE;
11338 break;
11340 try_ = gimple_build_try (eval, cleanup,
11341 TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
11342 ? GIMPLE_TRY_FINALLY
11343 : GIMPLE_TRY_CATCH);
11344 if (EXPR_HAS_LOCATION (save_expr))
11345 gimple_set_location (try_, EXPR_LOCATION (save_expr));
11346 else if (LOCATION_LOCUS (saved_location) != UNKNOWN_LOCATION)
11347 gimple_set_location (try_, saved_location);
11348 if (TREE_CODE (*expr_p) == TRY_CATCH_EXPR)
11349 gimple_try_set_catch_is_cleanup (try_,
11350 TRY_CATCH_IS_CLEANUP (*expr_p));
11351 gimplify_seq_add_stmt (pre_p, try_);
11352 ret = GS_ALL_DONE;
11353 break;
11356 case CLEANUP_POINT_EXPR:
11357 ret = gimplify_cleanup_point_expr (expr_p, pre_p);
11358 break;
11360 case TARGET_EXPR:
11361 ret = gimplify_target_expr (expr_p, pre_p, post_p);
11362 break;
11364 case CATCH_EXPR:
11366 gimple *c;
11367 gimple_seq handler = NULL;
11368 gimplify_and_add (CATCH_BODY (*expr_p), &handler);
11369 c = gimple_build_catch (CATCH_TYPES (*expr_p), handler);
11370 gimplify_seq_add_stmt (pre_p, c);
11371 ret = GS_ALL_DONE;
11372 break;
11375 case EH_FILTER_EXPR:
11377 gimple *ehf;
11378 gimple_seq failure = NULL;
11380 gimplify_and_add (EH_FILTER_FAILURE (*expr_p), &failure);
11381 ehf = gimple_build_eh_filter (EH_FILTER_TYPES (*expr_p), failure);
11382 gimple_set_no_warning (ehf, TREE_NO_WARNING (*expr_p));
11383 gimplify_seq_add_stmt (pre_p, ehf);
11384 ret = GS_ALL_DONE;
11385 break;
11388 case OBJ_TYPE_REF:
11390 enum gimplify_status r0, r1;
11391 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p,
11392 post_p, is_gimple_val, fb_rvalue);
11393 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p,
11394 post_p, is_gimple_val, fb_rvalue);
11395 TREE_SIDE_EFFECTS (*expr_p) = 0;
11396 ret = MIN (r0, r1);
11398 break;
11400 case LABEL_DECL:
11401 /* We get here when taking the address of a label. We mark
11402 the label as "forced"; meaning it can never be removed and
11403 it is a potential target for any computed goto. */
11404 FORCED_LABEL (*expr_p) = 1;
11405 ret = GS_ALL_DONE;
11406 break;
11408 case STATEMENT_LIST:
11409 ret = gimplify_statement_list (expr_p, pre_p);
11410 break;
11412 case WITH_SIZE_EXPR:
11414 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
11415 post_p == &internal_post ? NULL : post_p,
11416 gimple_test_f, fallback);
11417 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
11418 is_gimple_val, fb_rvalue);
11419 ret = GS_ALL_DONE;
11421 break;
11423 case VAR_DECL:
11424 case PARM_DECL:
11425 ret = gimplify_var_or_parm_decl (expr_p);
11426 break;
11428 case RESULT_DECL:
11429 /* When within an OMP context, notice uses of variables. */
11430 if (gimplify_omp_ctxp)
11431 omp_notice_variable (gimplify_omp_ctxp, *expr_p, true);
11432 ret = GS_ALL_DONE;
11433 break;
11435 case SSA_NAME:
11436 /* Allow callbacks into the gimplifier during optimization. */
11437 ret = GS_ALL_DONE;
11438 break;
11440 case OMP_PARALLEL:
11441 gimplify_omp_parallel (expr_p, pre_p);
11442 ret = GS_ALL_DONE;
11443 break;
11445 case OMP_TASK:
11446 gimplify_omp_task (expr_p, pre_p);
11447 ret = GS_ALL_DONE;
11448 break;
11450 case OMP_FOR:
11451 case OMP_SIMD:
11452 case CILK_SIMD:
11453 case CILK_FOR:
11454 case OMP_DISTRIBUTE:
11455 case OMP_TASKLOOP:
11456 case OACC_LOOP:
11457 ret = gimplify_omp_for (expr_p, pre_p);
11458 break;
11460 case OACC_CACHE:
11461 gimplify_oacc_cache (expr_p, pre_p);
11462 ret = GS_ALL_DONE;
11463 break;
11465 case OACC_DECLARE:
11466 gimplify_oacc_declare (expr_p, pre_p);
11467 ret = GS_ALL_DONE;
11468 break;
11470 case OACC_HOST_DATA:
11471 case OACC_DATA:
11472 case OACC_KERNELS:
11473 case OACC_PARALLEL:
11474 case OMP_SECTIONS:
11475 case OMP_SINGLE:
11476 case OMP_TARGET:
11477 case OMP_TARGET_DATA:
11478 case OMP_TEAMS:
11479 gimplify_omp_workshare (expr_p, pre_p);
11480 ret = GS_ALL_DONE;
11481 break;
11483 case OACC_ENTER_DATA:
11484 case OACC_EXIT_DATA:
11485 case OACC_UPDATE:
11486 case OMP_TARGET_UPDATE:
11487 case OMP_TARGET_ENTER_DATA:
11488 case OMP_TARGET_EXIT_DATA:
11489 gimplify_omp_target_update (expr_p, pre_p);
11490 ret = GS_ALL_DONE;
11491 break;
11493 case OMP_SECTION:
11494 case OMP_MASTER:
11495 case OMP_TASKGROUP:
11496 case OMP_ORDERED:
11497 case OMP_CRITICAL:
11499 gimple_seq body = NULL;
11500 gimple *g;
11502 gimplify_and_add (OMP_BODY (*expr_p), &body);
11503 switch (TREE_CODE (*expr_p))
11505 case OMP_SECTION:
11506 g = gimple_build_omp_section (body);
11507 break;
11508 case OMP_MASTER:
11509 g = gimple_build_omp_master (body);
11510 break;
11511 case OMP_TASKGROUP:
11513 gimple_seq cleanup = NULL;
11514 tree fn
11515 = builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_END);
11516 g = gimple_build_call (fn, 0);
11517 gimple_seq_add_stmt (&cleanup, g);
11518 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
11519 body = NULL;
11520 gimple_seq_add_stmt (&body, g);
11521 g = gimple_build_omp_taskgroup (body);
11523 break;
11524 case OMP_ORDERED:
11525 g = gimplify_omp_ordered (*expr_p, body);
11526 break;
11527 case OMP_CRITICAL:
11528 gimplify_scan_omp_clauses (&OMP_CRITICAL_CLAUSES (*expr_p),
11529 pre_p, ORT_WORKSHARE, OMP_CRITICAL);
11530 gimplify_adjust_omp_clauses (pre_p, body,
11531 &OMP_CRITICAL_CLAUSES (*expr_p),
11532 OMP_CRITICAL);
11533 g = gimple_build_omp_critical (body,
11534 OMP_CRITICAL_NAME (*expr_p),
11535 OMP_CRITICAL_CLAUSES (*expr_p));
11536 break;
11537 default:
11538 gcc_unreachable ();
11540 gimplify_seq_add_stmt (pre_p, g);
11541 ret = GS_ALL_DONE;
11542 break;
11545 case OMP_ATOMIC:
11546 case OMP_ATOMIC_READ:
11547 case OMP_ATOMIC_CAPTURE_OLD:
11548 case OMP_ATOMIC_CAPTURE_NEW:
11549 ret = gimplify_omp_atomic (expr_p, pre_p);
11550 break;
11552 case TRANSACTION_EXPR:
11553 ret = gimplify_transaction (expr_p, pre_p);
11554 break;
11556 case TRUTH_AND_EXPR:
11557 case TRUTH_OR_EXPR:
11558 case TRUTH_XOR_EXPR:
11560 tree orig_type = TREE_TYPE (*expr_p);
11561 tree new_type, xop0, xop1;
11562 *expr_p = gimple_boolify (*expr_p);
11563 new_type = TREE_TYPE (*expr_p);
11564 if (!useless_type_conversion_p (orig_type, new_type))
11566 *expr_p = fold_convert_loc (input_location, orig_type, *expr_p);
11567 ret = GS_OK;
11568 break;
11571 /* Boolified binary truth expressions are semantically equivalent
11572 to bitwise binary expressions. Canonicalize them to the
11573 bitwise variant. */
11574 switch (TREE_CODE (*expr_p))
11576 case TRUTH_AND_EXPR:
11577 TREE_SET_CODE (*expr_p, BIT_AND_EXPR);
11578 break;
11579 case TRUTH_OR_EXPR:
11580 TREE_SET_CODE (*expr_p, BIT_IOR_EXPR);
11581 break;
11582 case TRUTH_XOR_EXPR:
11583 TREE_SET_CODE (*expr_p, BIT_XOR_EXPR);
11584 break;
11585 default:
11586 break;
11588 /* Now make sure that operands have compatible type to
11589 expression's new_type. */
11590 xop0 = TREE_OPERAND (*expr_p, 0);
11591 xop1 = TREE_OPERAND (*expr_p, 1);
11592 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop0)))
11593 TREE_OPERAND (*expr_p, 0) = fold_convert_loc (input_location,
11594 new_type,
11595 xop0);
11596 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop1)))
11597 TREE_OPERAND (*expr_p, 1) = fold_convert_loc (input_location,
11598 new_type,
11599 xop1);
11600 /* Continue classified as tcc_binary. */
11601 goto expr_2;
11604 case VEC_COND_EXPR:
11606 enum gimplify_status r0, r1, r2;
11608 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
11609 post_p, is_gimple_condexpr, fb_rvalue);
11610 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
11611 post_p, is_gimple_val, fb_rvalue);
11612 r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p,
11613 post_p, is_gimple_val, fb_rvalue);
11615 ret = MIN (MIN (r0, r1), r2);
11616 recalculate_side_effects (*expr_p);
11618 break;
11620 case FMA_EXPR:
11621 case VEC_PERM_EXPR:
11622 /* Classified as tcc_expression. */
11623 goto expr_3;
11625 case BIT_INSERT_EXPR:
11626 /* Argument 3 is a constant. */
11627 goto expr_2;
11629 case POINTER_PLUS_EXPR:
11631 enum gimplify_status r0, r1;
11632 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
11633 post_p, is_gimple_val, fb_rvalue);
11634 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
11635 post_p, is_gimple_val, fb_rvalue);
11636 recalculate_side_effects (*expr_p);
11637 ret = MIN (r0, r1);
11638 break;
11641 case CILK_SYNC_STMT:
11643 if (!fn_contains_cilk_spawn_p (cfun))
11645 error_at (EXPR_LOCATION (*expr_p),
11646 "expected %<_Cilk_spawn%> before %<_Cilk_sync%>");
11647 ret = GS_ERROR;
11649 else
11651 gimplify_cilk_sync (expr_p, pre_p);
11652 ret = GS_ALL_DONE;
11654 break;
11657 default:
11658 switch (TREE_CODE_CLASS (TREE_CODE (*expr_p)))
11660 case tcc_comparison:
11661 /* Handle comparison of objects of non scalar mode aggregates
11662 with a call to memcmp. It would be nice to only have to do
11663 this for variable-sized objects, but then we'd have to allow
11664 the same nest of reference nodes we allow for MODIFY_EXPR and
11665 that's too complex.
11667 Compare scalar mode aggregates as scalar mode values. Using
11668 memcmp for them would be very inefficient at best, and is
11669 plain wrong if bitfields are involved. */
11671 tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 1));
11673 /* Vector comparisons need no boolification. */
11674 if (TREE_CODE (type) == VECTOR_TYPE)
11675 goto expr_2;
11676 else if (!AGGREGATE_TYPE_P (type))
11678 tree org_type = TREE_TYPE (*expr_p);
11679 *expr_p = gimple_boolify (*expr_p);
11680 if (!useless_type_conversion_p (org_type,
11681 TREE_TYPE (*expr_p)))
11683 *expr_p = fold_convert_loc (input_location,
11684 org_type, *expr_p);
11685 ret = GS_OK;
11687 else
11688 goto expr_2;
11690 else if (TYPE_MODE (type) != BLKmode)
11691 ret = gimplify_scalar_mode_aggregate_compare (expr_p);
11692 else
11693 ret = gimplify_variable_sized_compare (expr_p);
11695 break;
11698 /* If *EXPR_P does not need to be special-cased, handle it
11699 according to its class. */
11700 case tcc_unary:
11701 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
11702 post_p, is_gimple_val, fb_rvalue);
11703 break;
11705 case tcc_binary:
11706 expr_2:
11708 enum gimplify_status r0, r1;
11710 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
11711 post_p, is_gimple_val, fb_rvalue);
11712 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
11713 post_p, is_gimple_val, fb_rvalue);
11715 ret = MIN (r0, r1);
11716 break;
11719 expr_3:
11721 enum gimplify_status r0, r1, r2;
11723 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
11724 post_p, is_gimple_val, fb_rvalue);
11725 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
11726 post_p, is_gimple_val, fb_rvalue);
11727 r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p,
11728 post_p, is_gimple_val, fb_rvalue);
11730 ret = MIN (MIN (r0, r1), r2);
11731 break;
11734 case tcc_declaration:
11735 case tcc_constant:
11736 ret = GS_ALL_DONE;
11737 goto dont_recalculate;
11739 default:
11740 gcc_unreachable ();
11743 recalculate_side_effects (*expr_p);
11745 dont_recalculate:
11746 break;
11749 gcc_assert (*expr_p || ret != GS_OK);
11751 while (ret == GS_OK);
11753 /* If we encountered an error_mark somewhere nested inside, either
11754 stub out the statement or propagate the error back out. */
11755 if (ret == GS_ERROR)
11757 if (is_statement)
11758 *expr_p = NULL;
11759 goto out;
11762 /* This was only valid as a return value from the langhook, which
11763 we handled. Make sure it doesn't escape from any other context. */
11764 gcc_assert (ret != GS_UNHANDLED);
11766 if (fallback == fb_none && *expr_p && !is_gimple_stmt (*expr_p))
11768 /* We aren't looking for a value, and we don't have a valid
11769 statement. If it doesn't have side-effects, throw it away. */
11770 if (!TREE_SIDE_EFFECTS (*expr_p))
11771 *expr_p = NULL;
11772 else if (!TREE_THIS_VOLATILE (*expr_p))
11774 /* This is probably a _REF that contains something nested that
11775 has side effects. Recurse through the operands to find it. */
11776 enum tree_code code = TREE_CODE (*expr_p);
11778 switch (code)
11780 case COMPONENT_REF:
11781 case REALPART_EXPR:
11782 case IMAGPART_EXPR:
11783 case VIEW_CONVERT_EXPR:
11784 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
11785 gimple_test_f, fallback);
11786 break;
11788 case ARRAY_REF:
11789 case ARRAY_RANGE_REF:
11790 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
11791 gimple_test_f, fallback);
11792 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
11793 gimple_test_f, fallback);
11794 break;
11796 default:
11797 /* Anything else with side-effects must be converted to
11798 a valid statement before we get here. */
11799 gcc_unreachable ();
11802 *expr_p = NULL;
11804 else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p))
11805 && TYPE_MODE (TREE_TYPE (*expr_p)) != BLKmode)
11807 /* Historically, the compiler has treated a bare reference
11808 to a non-BLKmode volatile lvalue as forcing a load. */
11809 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p));
11811 /* Normally, we do not want to create a temporary for a
11812 TREE_ADDRESSABLE type because such a type should not be
11813 copied by bitwise-assignment. However, we make an
11814 exception here, as all we are doing here is ensuring that
11815 we read the bytes that make up the type. We use
11816 create_tmp_var_raw because create_tmp_var will abort when
11817 given a TREE_ADDRESSABLE type. */
11818 tree tmp = create_tmp_var_raw (type, "vol");
11819 gimple_add_tmp_var (tmp);
11820 gimplify_assign (tmp, *expr_p, pre_p);
11821 *expr_p = NULL;
11823 else
11824 /* We can't do anything useful with a volatile reference to
11825 an incomplete type, so just throw it away. Likewise for
11826 a BLKmode type, since any implicit inner load should
11827 already have been turned into an explicit one by the
11828 gimplification process. */
11829 *expr_p = NULL;
11832 /* If we are gimplifying at the statement level, we're done. Tack
11833 everything together and return. */
11834 if (fallback == fb_none || is_statement)
11836 /* Since *EXPR_P has been converted into a GIMPLE tuple, clear
11837 it out for GC to reclaim it. */
11838 *expr_p = NULL_TREE;
11840 if (!gimple_seq_empty_p (internal_pre)
11841 || !gimple_seq_empty_p (internal_post))
11843 gimplify_seq_add_seq (&internal_pre, internal_post);
11844 gimplify_seq_add_seq (pre_p, internal_pre);
11847 /* The result of gimplifying *EXPR_P is going to be the last few
11848 statements in *PRE_P and *POST_P. Add location information
11849 to all the statements that were added by the gimplification
11850 helpers. */
11851 if (!gimple_seq_empty_p (*pre_p))
11852 annotate_all_with_location_after (*pre_p, pre_last_gsi, input_location);
11854 if (!gimple_seq_empty_p (*post_p))
11855 annotate_all_with_location_after (*post_p, post_last_gsi,
11856 input_location);
11858 goto out;
11861 #ifdef ENABLE_GIMPLE_CHECKING
11862 if (*expr_p)
11864 enum tree_code code = TREE_CODE (*expr_p);
11865 /* These expressions should already be in gimple IR form. */
11866 gcc_assert (code != MODIFY_EXPR
11867 && code != ASM_EXPR
11868 && code != BIND_EXPR
11869 && code != CATCH_EXPR
11870 && (code != COND_EXPR || gimplify_ctxp->allow_rhs_cond_expr)
11871 && code != EH_FILTER_EXPR
11872 && code != GOTO_EXPR
11873 && code != LABEL_EXPR
11874 && code != LOOP_EXPR
11875 && code != SWITCH_EXPR
11876 && code != TRY_FINALLY_EXPR
11877 && code != OACC_PARALLEL
11878 && code != OACC_KERNELS
11879 && code != OACC_DATA
11880 && code != OACC_HOST_DATA
11881 && code != OACC_DECLARE
11882 && code != OACC_UPDATE
11883 && code != OACC_ENTER_DATA
11884 && code != OACC_EXIT_DATA
11885 && code != OACC_CACHE
11886 && code != OMP_CRITICAL
11887 && code != OMP_FOR
11888 && code != OACC_LOOP
11889 && code != OMP_MASTER
11890 && code != OMP_TASKGROUP
11891 && code != OMP_ORDERED
11892 && code != OMP_PARALLEL
11893 && code != OMP_SECTIONS
11894 && code != OMP_SECTION
11895 && code != OMP_SINGLE);
11897 #endif
11899 /* Otherwise we're gimplifying a subexpression, so the resulting
11900 value is interesting. If it's a valid operand that matches
11901 GIMPLE_TEST_F, we're done. Unless we are handling some
11902 post-effects internally; if that's the case, we need to copy into
11903 a temporary before adding the post-effects to POST_P. */
11904 if (gimple_seq_empty_p (internal_post) && (*gimple_test_f) (*expr_p))
11905 goto out;
11907 /* Otherwise, we need to create a new temporary for the gimplified
11908 expression. */
11910 /* We can't return an lvalue if we have an internal postqueue. The
11911 object the lvalue refers to would (probably) be modified by the
11912 postqueue; we need to copy the value out first, which means an
11913 rvalue. */
11914 if ((fallback & fb_lvalue)
11915 && gimple_seq_empty_p (internal_post)
11916 && is_gimple_addressable (*expr_p))
11918 /* An lvalue will do. Take the address of the expression, store it
11919 in a temporary, and replace the expression with an INDIRECT_REF of
11920 that temporary. */
11921 tmp = build_fold_addr_expr_loc (input_location, *expr_p);
11922 gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue);
11923 *expr_p = build_simple_mem_ref (tmp);
11925 else if ((fallback & fb_rvalue) && is_gimple_reg_rhs_or_call (*expr_p))
11927 /* An rvalue will do. Assign the gimplified expression into a
11928 new temporary TMP and replace the original expression with
11929 TMP. First, make sure that the expression has a type so that
11930 it can be assigned into a temporary. */
11931 gcc_assert (!VOID_TYPE_P (TREE_TYPE (*expr_p)));
11932 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
11934 else
11936 #ifdef ENABLE_GIMPLE_CHECKING
11937 if (!(fallback & fb_mayfail))
11939 fprintf (stderr, "gimplification failed:\n");
11940 print_generic_expr (stderr, *expr_p, 0);
11941 debug_tree (*expr_p);
11942 internal_error ("gimplification failed");
11944 #endif
11945 gcc_assert (fallback & fb_mayfail);
11947 /* If this is an asm statement, and the user asked for the
11948 impossible, don't die. Fail and let gimplify_asm_expr
11949 issue an error. */
11950 ret = GS_ERROR;
11951 goto out;
11954 /* Make sure the temporary matches our predicate. */
11955 gcc_assert ((*gimple_test_f) (*expr_p));
11957 if (!gimple_seq_empty_p (internal_post))
11959 annotate_all_with_location (internal_post, input_location);
11960 gimplify_seq_add_seq (pre_p, internal_post);
11963 out:
11964 input_location = saved_location;
11965 return ret;
11968 /* Like gimplify_expr but make sure the gimplified result is not itself
11969 a SSA name (but a decl if it were). Temporaries required by
11970 evaluating *EXPR_P may be still SSA names. */
11972 static enum gimplify_status
11973 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
11974 bool (*gimple_test_f) (tree), fallback_t fallback,
11975 bool allow_ssa)
11977 bool was_ssa_name_p = TREE_CODE (*expr_p) == SSA_NAME;
11978 enum gimplify_status ret = gimplify_expr (expr_p, pre_p, post_p,
11979 gimple_test_f, fallback);
11980 if (! allow_ssa
11981 && TREE_CODE (*expr_p) == SSA_NAME)
11983 tree name = *expr_p;
11984 if (was_ssa_name_p)
11985 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, NULL, false);
11986 else
11988 /* Avoid the extra copy if possible. */
11989 *expr_p = create_tmp_reg (TREE_TYPE (name));
11990 gimple_set_lhs (SSA_NAME_DEF_STMT (name), *expr_p);
11991 release_ssa_name (name);
11994 return ret;
11997 /* Look through TYPE for variable-sized objects and gimplify each such
11998 size that we find. Add to LIST_P any statements generated. */
12000 void
12001 gimplify_type_sizes (tree type, gimple_seq *list_p)
12003 tree field, t;
12005 if (type == NULL || type == error_mark_node)
12006 return;
12008 /* We first do the main variant, then copy into any other variants. */
12009 type = TYPE_MAIN_VARIANT (type);
12011 /* Avoid infinite recursion. */
12012 if (TYPE_SIZES_GIMPLIFIED (type))
12013 return;
12015 TYPE_SIZES_GIMPLIFIED (type) = 1;
12017 switch (TREE_CODE (type))
12019 case INTEGER_TYPE:
12020 case ENUMERAL_TYPE:
12021 case BOOLEAN_TYPE:
12022 case REAL_TYPE:
12023 case FIXED_POINT_TYPE:
12024 gimplify_one_sizepos (&TYPE_MIN_VALUE (type), list_p);
12025 gimplify_one_sizepos (&TYPE_MAX_VALUE (type), list_p);
12027 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
12029 TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type);
12030 TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type);
12032 break;
12034 case ARRAY_TYPE:
12035 /* These types may not have declarations, so handle them here. */
12036 gimplify_type_sizes (TREE_TYPE (type), list_p);
12037 gimplify_type_sizes (TYPE_DOMAIN (type), list_p);
12038 /* Ensure VLA bounds aren't removed, for -O0 they should be variables
12039 with assigned stack slots, for -O1+ -g they should be tracked
12040 by VTA. */
12041 if (!(TYPE_NAME (type)
12042 && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
12043 && DECL_IGNORED_P (TYPE_NAME (type)))
12044 && TYPE_DOMAIN (type)
12045 && INTEGRAL_TYPE_P (TYPE_DOMAIN (type)))
12047 t = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
12048 if (t && TREE_CODE (t) == VAR_DECL && DECL_ARTIFICIAL (t))
12049 DECL_IGNORED_P (t) = 0;
12050 t = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
12051 if (t && TREE_CODE (t) == VAR_DECL && DECL_ARTIFICIAL (t))
12052 DECL_IGNORED_P (t) = 0;
12054 break;
12056 case RECORD_TYPE:
12057 case UNION_TYPE:
12058 case QUAL_UNION_TYPE:
12059 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
12060 if (TREE_CODE (field) == FIELD_DECL)
12062 gimplify_one_sizepos (&DECL_FIELD_OFFSET (field), list_p);
12063 gimplify_one_sizepos (&DECL_SIZE (field), list_p);
12064 gimplify_one_sizepos (&DECL_SIZE_UNIT (field), list_p);
12065 gimplify_type_sizes (TREE_TYPE (field), list_p);
12067 break;
12069 case POINTER_TYPE:
12070 case REFERENCE_TYPE:
12071 /* We used to recurse on the pointed-to type here, which turned out to
12072 be incorrect because its definition might refer to variables not
12073 yet initialized at this point if a forward declaration is involved.
12075 It was actually useful for anonymous pointed-to types to ensure
12076 that the sizes evaluation dominates every possible later use of the
12077 values. Restricting to such types here would be safe since there
12078 is no possible forward declaration around, but would introduce an
12079 undesirable middle-end semantic to anonymity. We then defer to
12080 front-ends the responsibility of ensuring that the sizes are
12081 evaluated both early and late enough, e.g. by attaching artificial
12082 type declarations to the tree. */
12083 break;
12085 default:
12086 break;
12089 gimplify_one_sizepos (&TYPE_SIZE (type), list_p);
12090 gimplify_one_sizepos (&TYPE_SIZE_UNIT (type), list_p);
12092 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
12094 TYPE_SIZE (t) = TYPE_SIZE (type);
12095 TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (type);
12096 TYPE_SIZES_GIMPLIFIED (t) = 1;
12100 /* A subroutine of gimplify_type_sizes to make sure that *EXPR_P,
12101 a size or position, has had all of its SAVE_EXPRs evaluated.
12102 We add any required statements to *STMT_P. */
12104 void
12105 gimplify_one_sizepos (tree *expr_p, gimple_seq *stmt_p)
12107 tree expr = *expr_p;
12109 /* We don't do anything if the value isn't there, is constant, or contains
12110 A PLACEHOLDER_EXPR. We also don't want to do anything if it's already
12111 a VAR_DECL. If it's a VAR_DECL from another function, the gimplifier
12112 will want to replace it with a new variable, but that will cause problems
12113 if this type is from outside the function. It's OK to have that here. */
12114 if (is_gimple_sizepos (expr))
12115 return;
12117 *expr_p = unshare_expr (expr);
12119 /* SSA names in decl/type fields are a bad idea - they'll get reclaimed
12120 if the def vanishes. */
12121 gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue, false);
12124 /* Gimplify the body of statements of FNDECL and return a GIMPLE_BIND node
12125 containing the sequence of corresponding GIMPLE statements. If DO_PARMS
12126 is true, also gimplify the parameters. */
12128 gbind *
12129 gimplify_body (tree fndecl, bool do_parms)
12131 location_t saved_location = input_location;
12132 gimple_seq parm_stmts, seq;
12133 gimple *outer_stmt;
12134 gbind *outer_bind;
12135 struct cgraph_node *cgn;
12137 timevar_push (TV_TREE_GIMPLIFY);
12139 init_tree_ssa (cfun);
12141 /* Initialize for optimize_insn_for_s{ize,peed}_p possibly called during
12142 gimplification. */
12143 default_rtl_profile ();
12145 gcc_assert (gimplify_ctxp == NULL);
12146 push_gimplify_context (true);
12148 if (flag_openacc || flag_openmp)
12150 gcc_assert (gimplify_omp_ctxp == NULL);
12151 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (fndecl)))
12152 gimplify_omp_ctxp = new_omp_context (ORT_TARGET);
12155 /* Unshare most shared trees in the body and in that of any nested functions.
12156 It would seem we don't have to do this for nested functions because
12157 they are supposed to be output and then the outer function gimplified
12158 first, but the g++ front end doesn't always do it that way. */
12159 unshare_body (fndecl);
12160 unvisit_body (fndecl);
12162 cgn = cgraph_node::get (fndecl);
12163 if (cgn && cgn->origin)
12164 nonlocal_vlas = new hash_set<tree>;
12166 /* Make sure input_location isn't set to something weird. */
12167 input_location = DECL_SOURCE_LOCATION (fndecl);
12169 /* Resolve callee-copies. This has to be done before processing
12170 the body so that DECL_VALUE_EXPR gets processed correctly. */
12171 parm_stmts = do_parms ? gimplify_parameters () : NULL;
12173 /* Gimplify the function's body. */
12174 seq = NULL;
12175 gimplify_stmt (&DECL_SAVED_TREE (fndecl), &seq);
12176 outer_stmt = gimple_seq_first_stmt (seq);
12177 if (!outer_stmt)
12179 outer_stmt = gimple_build_nop ();
12180 gimplify_seq_add_stmt (&seq, outer_stmt);
12183 /* The body must contain exactly one statement, a GIMPLE_BIND. If this is
12184 not the case, wrap everything in a GIMPLE_BIND to make it so. */
12185 if (gimple_code (outer_stmt) == GIMPLE_BIND
12186 && gimple_seq_first (seq) == gimple_seq_last (seq))
12187 outer_bind = as_a <gbind *> (outer_stmt);
12188 else
12189 outer_bind = gimple_build_bind (NULL_TREE, seq, NULL);
12191 DECL_SAVED_TREE (fndecl) = NULL_TREE;
12193 /* If we had callee-copies statements, insert them at the beginning
12194 of the function and clear DECL_VALUE_EXPR_P on the parameters. */
12195 if (!gimple_seq_empty_p (parm_stmts))
12197 tree parm;
12199 gimplify_seq_add_seq (&parm_stmts, gimple_bind_body (outer_bind));
12200 gimple_bind_set_body (outer_bind, parm_stmts);
12202 for (parm = DECL_ARGUMENTS (current_function_decl);
12203 parm; parm = DECL_CHAIN (parm))
12204 if (DECL_HAS_VALUE_EXPR_P (parm))
12206 DECL_HAS_VALUE_EXPR_P (parm) = 0;
12207 DECL_IGNORED_P (parm) = 0;
12211 if (nonlocal_vlas)
12213 if (nonlocal_vla_vars)
12215 /* tree-nested.c may later on call declare_vars (..., true);
12216 which relies on BLOCK_VARS chain to be the tail of the
12217 gimple_bind_vars chain. Ensure we don't violate that
12218 assumption. */
12219 if (gimple_bind_block (outer_bind)
12220 == DECL_INITIAL (current_function_decl))
12221 declare_vars (nonlocal_vla_vars, outer_bind, true);
12222 else
12223 BLOCK_VARS (DECL_INITIAL (current_function_decl))
12224 = chainon (BLOCK_VARS (DECL_INITIAL (current_function_decl)),
12225 nonlocal_vla_vars);
12226 nonlocal_vla_vars = NULL_TREE;
12228 delete nonlocal_vlas;
12229 nonlocal_vlas = NULL;
12232 if ((flag_openacc || flag_openmp || flag_openmp_simd)
12233 && gimplify_omp_ctxp)
12235 delete_omp_context (gimplify_omp_ctxp);
12236 gimplify_omp_ctxp = NULL;
12239 pop_gimplify_context (outer_bind);
12240 gcc_assert (gimplify_ctxp == NULL);
12242 if (flag_checking && !seen_error ())
12243 verify_gimple_in_seq (gimple_bind_body (outer_bind));
12245 timevar_pop (TV_TREE_GIMPLIFY);
12246 input_location = saved_location;
12248 return outer_bind;
12251 typedef char *char_p; /* For DEF_VEC_P. */
12253 /* Return whether we should exclude FNDECL from instrumentation. */
12255 static bool
12256 flag_instrument_functions_exclude_p (tree fndecl)
12258 vec<char_p> *v;
12260 v = (vec<char_p> *) flag_instrument_functions_exclude_functions;
12261 if (v && v->length () > 0)
12263 const char *name;
12264 int i;
12265 char *s;
12267 name = lang_hooks.decl_printable_name (fndecl, 0);
12268 FOR_EACH_VEC_ELT (*v, i, s)
12269 if (strstr (name, s) != NULL)
12270 return true;
12273 v = (vec<char_p> *) flag_instrument_functions_exclude_files;
12274 if (v && v->length () > 0)
12276 const char *name;
12277 int i;
12278 char *s;
12280 name = DECL_SOURCE_FILE (fndecl);
12281 FOR_EACH_VEC_ELT (*v, i, s)
12282 if (strstr (name, s) != NULL)
12283 return true;
12286 return false;
12289 /* Entry point to the gimplification pass. FNDECL is the FUNCTION_DECL
12290 node for the function we want to gimplify.
12292 Return the sequence of GIMPLE statements corresponding to the body
12293 of FNDECL. */
12295 void
12296 gimplify_function_tree (tree fndecl)
12298 tree parm, ret;
12299 gimple_seq seq;
12300 gbind *bind;
12302 gcc_assert (!gimple_body (fndecl));
12304 if (DECL_STRUCT_FUNCTION (fndecl))
12305 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
12306 else
12307 push_struct_function (fndecl);
12309 /* Tentatively set PROP_gimple_lva here, and reset it in gimplify_va_arg_expr
12310 if necessary. */
12311 cfun->curr_properties |= PROP_gimple_lva;
12313 for (parm = DECL_ARGUMENTS (fndecl); parm ; parm = DECL_CHAIN (parm))
12315 /* Preliminarily mark non-addressed complex variables as eligible
12316 for promotion to gimple registers. We'll transform their uses
12317 as we find them. */
12318 if ((TREE_CODE (TREE_TYPE (parm)) == COMPLEX_TYPE
12319 || TREE_CODE (TREE_TYPE (parm)) == VECTOR_TYPE)
12320 && !TREE_THIS_VOLATILE (parm)
12321 && !needs_to_live_in_memory (parm))
12322 DECL_GIMPLE_REG_P (parm) = 1;
12325 ret = DECL_RESULT (fndecl);
12326 if ((TREE_CODE (TREE_TYPE (ret)) == COMPLEX_TYPE
12327 || TREE_CODE (TREE_TYPE (ret)) == VECTOR_TYPE)
12328 && !needs_to_live_in_memory (ret))
12329 DECL_GIMPLE_REG_P (ret) = 1;
12331 bind = gimplify_body (fndecl, true);
12333 /* The tree body of the function is no longer needed, replace it
12334 with the new GIMPLE body. */
12335 seq = NULL;
12336 gimple_seq_add_stmt (&seq, bind);
12337 gimple_set_body (fndecl, seq);
12339 /* If we're instrumenting function entry/exit, then prepend the call to
12340 the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to
12341 catch the exit hook. */
12342 /* ??? Add some way to ignore exceptions for this TFE. */
12343 if (flag_instrument_function_entry_exit
12344 && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl)
12345 && !flag_instrument_functions_exclude_p (fndecl))
12347 tree x;
12348 gbind *new_bind;
12349 gimple *tf;
12350 gimple_seq cleanup = NULL, body = NULL;
12351 tree tmp_var;
12352 gcall *call;
12354 x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
12355 call = gimple_build_call (x, 1, integer_zero_node);
12356 tmp_var = create_tmp_var (ptr_type_node, "return_addr");
12357 gimple_call_set_lhs (call, tmp_var);
12358 gimplify_seq_add_stmt (&cleanup, call);
12359 x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_EXIT);
12360 call = gimple_build_call (x, 2,
12361 build_fold_addr_expr (current_function_decl),
12362 tmp_var);
12363 gimplify_seq_add_stmt (&cleanup, call);
12364 tf = gimple_build_try (seq, cleanup, GIMPLE_TRY_FINALLY);
12366 x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
12367 call = gimple_build_call (x, 1, integer_zero_node);
12368 tmp_var = create_tmp_var (ptr_type_node, "return_addr");
12369 gimple_call_set_lhs (call, tmp_var);
12370 gimplify_seq_add_stmt (&body, call);
12371 x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_ENTER);
12372 call = gimple_build_call (x, 2,
12373 build_fold_addr_expr (current_function_decl),
12374 tmp_var);
12375 gimplify_seq_add_stmt (&body, call);
12376 gimplify_seq_add_stmt (&body, tf);
12377 new_bind = gimple_build_bind (NULL, body, gimple_bind_block (bind));
12378 /* Clear the block for BIND, since it is no longer directly inside
12379 the function, but within a try block. */
12380 gimple_bind_set_block (bind, NULL);
12382 /* Replace the current function body with the body
12383 wrapped in the try/finally TF. */
12384 seq = NULL;
12385 gimple_seq_add_stmt (&seq, new_bind);
12386 gimple_set_body (fndecl, seq);
12387 bind = new_bind;
12390 if ((flag_sanitize & SANITIZE_THREAD) != 0
12391 && !lookup_attribute ("no_sanitize_thread", DECL_ATTRIBUTES (fndecl)))
12393 gcall *call = gimple_build_call_internal (IFN_TSAN_FUNC_EXIT, 0);
12394 gimple *tf = gimple_build_try (seq, call, GIMPLE_TRY_FINALLY);
12395 gbind *new_bind = gimple_build_bind (NULL, tf, gimple_bind_block (bind));
12396 /* Clear the block for BIND, since it is no longer directly inside
12397 the function, but within a try block. */
12398 gimple_bind_set_block (bind, NULL);
12399 /* Replace the current function body with the body
12400 wrapped in the try/finally TF. */
12401 seq = NULL;
12402 gimple_seq_add_stmt (&seq, new_bind);
12403 gimple_set_body (fndecl, seq);
12406 DECL_SAVED_TREE (fndecl) = NULL_TREE;
12407 cfun->curr_properties |= PROP_gimple_any;
12409 pop_cfun ();
12411 dump_function (TDI_generic, fndecl);
12414 /* Return a dummy expression of type TYPE in order to keep going after an
12415 error. */
12417 static tree
12418 dummy_object (tree type)
12420 tree t = build_int_cst (build_pointer_type (type), 0);
12421 return build2 (MEM_REF, type, t, t);
12424 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
12425 builtin function, but a very special sort of operator. */
12427 enum gimplify_status
12428 gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p,
12429 gimple_seq *post_p ATTRIBUTE_UNUSED)
12431 tree promoted_type, have_va_type;
12432 tree valist = TREE_OPERAND (*expr_p, 0);
12433 tree type = TREE_TYPE (*expr_p);
12434 tree t, tag, aptag;
12435 location_t loc = EXPR_LOCATION (*expr_p);
12437 /* Verify that valist is of the proper type. */
12438 have_va_type = TREE_TYPE (valist);
12439 if (have_va_type == error_mark_node)
12440 return GS_ERROR;
12441 have_va_type = targetm.canonical_va_list_type (have_va_type);
12442 if (have_va_type == NULL_TREE
12443 && TREE_CODE (valist) == ADDR_EXPR)
12444 /* Handle 'Case 1: Not an array type' from c-common.c/build_va_arg. */
12445 have_va_type
12446 = targetm.canonical_va_list_type (TREE_TYPE (TREE_TYPE (valist)));
12447 gcc_assert (have_va_type != NULL_TREE);
12449 /* Generate a diagnostic for requesting data of a type that cannot
12450 be passed through `...' due to type promotion at the call site. */
12451 if ((promoted_type = lang_hooks.types.type_promotes_to (type))
12452 != type)
12454 static bool gave_help;
12455 bool warned;
12456 /* Use the expansion point to handle cases such as passing bool (defined
12457 in a system header) through `...'. */
12458 source_location xloc
12459 = expansion_point_location_if_in_system_header (loc);
12461 /* Unfortunately, this is merely undefined, rather than a constraint
12462 violation, so we cannot make this an error. If this call is never
12463 executed, the program is still strictly conforming. */
12464 warned = warning_at (xloc, 0,
12465 "%qT is promoted to %qT when passed through %<...%>",
12466 type, promoted_type);
12467 if (!gave_help && warned)
12469 gave_help = true;
12470 inform (xloc, "(so you should pass %qT not %qT to %<va_arg%>)",
12471 promoted_type, type);
12474 /* We can, however, treat "undefined" any way we please.
12475 Call abort to encourage the user to fix the program. */
12476 if (warned)
12477 inform (xloc, "if this code is reached, the program will abort");
12478 /* Before the abort, allow the evaluation of the va_list
12479 expression to exit or longjmp. */
12480 gimplify_and_add (valist, pre_p);
12481 t = build_call_expr_loc (loc,
12482 builtin_decl_implicit (BUILT_IN_TRAP), 0);
12483 gimplify_and_add (t, pre_p);
12485 /* This is dead code, but go ahead and finish so that the
12486 mode of the result comes out right. */
12487 *expr_p = dummy_object (type);
12488 return GS_ALL_DONE;
12491 tag = build_int_cst (build_pointer_type (type), 0);
12492 aptag = build_int_cst (TREE_TYPE (valist), 0);
12494 *expr_p = build_call_expr_internal_loc (loc, IFN_VA_ARG, type, 3,
12495 valist, tag, aptag);
12497 /* Clear the tentatively set PROP_gimple_lva, to indicate that IFN_VA_ARG
12498 needs to be expanded. */
12499 cfun->curr_properties &= ~PROP_gimple_lva;
12501 return GS_OK;
12504 /* Build a new GIMPLE_ASSIGN tuple and append it to the end of *SEQ_P.
12506 DST/SRC are the destination and source respectively. You can pass
12507 ungimplified trees in DST or SRC, in which case they will be
12508 converted to a gimple operand if necessary.
12510 This function returns the newly created GIMPLE_ASSIGN tuple. */
12512 gimple *
12513 gimplify_assign (tree dst, tree src, gimple_seq *seq_p)
12515 tree t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
12516 gimplify_and_add (t, seq_p);
12517 ggc_free (t);
12518 return gimple_seq_last_stmt (*seq_p);
12521 inline hashval_t
12522 gimplify_hasher::hash (const elt_t *p)
12524 tree t = p->val;
12525 return iterative_hash_expr (t, 0);
12528 inline bool
12529 gimplify_hasher::equal (const elt_t *p1, const elt_t *p2)
12531 tree t1 = p1->val;
12532 tree t2 = p2->val;
12533 enum tree_code code = TREE_CODE (t1);
12535 if (TREE_CODE (t2) != code
12536 || TREE_TYPE (t1) != TREE_TYPE (t2))
12537 return false;
12539 if (!operand_equal_p (t1, t2, 0))
12540 return false;
12542 /* Only allow them to compare equal if they also hash equal; otherwise
12543 results are nondeterminate, and we fail bootstrap comparison. */
12544 gcc_checking_assert (hash (p1) == hash (p2));
12546 return true;