2016-08-24 Michael Collison <michael.collison@linaro.org>
[official-gcc.git] / gcc / gimplify.c
blob4715332eddf4f4de74a56a5df4feacd021c4e10c
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;
165 struct gimplify_omp_ctx
167 struct gimplify_omp_ctx *outer_context;
168 splay_tree variables;
169 hash_set<tree> *privatized_types;
170 /* Iteration variables in an OMP_FOR. */
171 vec<tree> loop_iter_var;
172 location_t location;
173 enum omp_clause_default_kind default_kind;
174 enum omp_region_type region_type;
175 bool combined_loop;
176 bool distribute;
177 bool target_map_scalars_firstprivate;
178 bool target_map_pointers_as_0len_arrays;
179 bool target_firstprivatize_array_bases;
182 static struct gimplify_ctx *gimplify_ctxp;
183 static struct gimplify_omp_ctx *gimplify_omp_ctxp;
185 /* Forward declaration. */
186 static enum gimplify_status gimplify_compound_expr (tree *, gimple_seq *, bool);
187 static hash_map<tree, tree> *oacc_declare_returns;
188 static enum gimplify_status gimplify_expr (tree *, gimple_seq *, gimple_seq *,
189 bool (*) (tree), fallback_t, bool);
191 /* Shorter alias name for the above function for use in gimplify.c
192 only. */
194 static inline void
195 gimplify_seq_add_stmt (gimple_seq *seq_p, gimple *gs)
197 gimple_seq_add_stmt_without_update (seq_p, gs);
200 /* Append sequence SRC to the end of sequence *DST_P. If *DST_P is
201 NULL, a new sequence is allocated. This function is
202 similar to gimple_seq_add_seq, but does not scan the operands.
203 During gimplification, we need to manipulate statement sequences
204 before the def/use vectors have been constructed. */
206 static void
207 gimplify_seq_add_seq (gimple_seq *dst_p, gimple_seq src)
209 gimple_stmt_iterator si;
211 if (src == NULL)
212 return;
214 si = gsi_last (*dst_p);
215 gsi_insert_seq_after_without_update (&si, src, GSI_NEW_STMT);
219 /* Pointer to a list of allocated gimplify_ctx structs to be used for pushing
220 and popping gimplify contexts. */
222 static struct gimplify_ctx *ctx_pool = NULL;
224 /* Return a gimplify context struct from the pool. */
226 static inline struct gimplify_ctx *
227 ctx_alloc (void)
229 struct gimplify_ctx * c = ctx_pool;
231 if (c)
232 ctx_pool = c->prev_context;
233 else
234 c = XNEW (struct gimplify_ctx);
236 memset (c, '\0', sizeof (*c));
237 return c;
240 /* Put gimplify context C back into the pool. */
242 static inline void
243 ctx_free (struct gimplify_ctx *c)
245 c->prev_context = ctx_pool;
246 ctx_pool = c;
249 /* Free allocated ctx stack memory. */
251 void
252 free_gimplify_stack (void)
254 struct gimplify_ctx *c;
256 while ((c = ctx_pool))
258 ctx_pool = c->prev_context;
259 free (c);
264 /* Set up a context for the gimplifier. */
266 void
267 push_gimplify_context (bool in_ssa, bool rhs_cond_ok)
269 struct gimplify_ctx *c = ctx_alloc ();
271 c->prev_context = gimplify_ctxp;
272 gimplify_ctxp = c;
273 gimplify_ctxp->into_ssa = in_ssa;
274 gimplify_ctxp->allow_rhs_cond_expr = rhs_cond_ok;
277 /* Tear down a context for the gimplifier. If BODY is non-null, then
278 put the temporaries into the outer BIND_EXPR. Otherwise, put them
279 in the local_decls.
281 BODY is not a sequence, but the first tuple in a sequence. */
283 void
284 pop_gimplify_context (gimple *body)
286 struct gimplify_ctx *c = gimplify_ctxp;
288 gcc_assert (c
289 && (!c->bind_expr_stack.exists ()
290 || c->bind_expr_stack.is_empty ()));
291 c->bind_expr_stack.release ();
292 gimplify_ctxp = c->prev_context;
294 if (body)
295 declare_vars (c->temps, body, false);
296 else
297 record_vars (c->temps);
299 delete c->temp_htab;
300 c->temp_htab = NULL;
301 ctx_free (c);
304 /* Push a GIMPLE_BIND tuple onto the stack of bindings. */
306 static void
307 gimple_push_bind_expr (gbind *bind_stmt)
309 gimplify_ctxp->bind_expr_stack.reserve (8);
310 gimplify_ctxp->bind_expr_stack.safe_push (bind_stmt);
313 /* Pop the first element off the stack of bindings. */
315 static void
316 gimple_pop_bind_expr (void)
318 gimplify_ctxp->bind_expr_stack.pop ();
321 /* Return the first element of the stack of bindings. */
323 gbind *
324 gimple_current_bind_expr (void)
326 return gimplify_ctxp->bind_expr_stack.last ();
329 /* Return the stack of bindings created during gimplification. */
331 vec<gbind *>
332 gimple_bind_expr_stack (void)
334 return gimplify_ctxp->bind_expr_stack;
337 /* Return true iff there is a COND_EXPR between us and the innermost
338 CLEANUP_POINT_EXPR. This info is used by gimple_push_cleanup. */
340 static bool
341 gimple_conditional_context (void)
343 return gimplify_ctxp->conditions > 0;
346 /* Note that we've entered a COND_EXPR. */
348 static void
349 gimple_push_condition (void)
351 #ifdef ENABLE_GIMPLE_CHECKING
352 if (gimplify_ctxp->conditions == 0)
353 gcc_assert (gimple_seq_empty_p (gimplify_ctxp->conditional_cleanups));
354 #endif
355 ++(gimplify_ctxp->conditions);
358 /* Note that we've left a COND_EXPR. If we're back at unconditional scope
359 now, add any conditional cleanups we've seen to the prequeue. */
361 static void
362 gimple_pop_condition (gimple_seq *pre_p)
364 int conds = --(gimplify_ctxp->conditions);
366 gcc_assert (conds >= 0);
367 if (conds == 0)
369 gimplify_seq_add_seq (pre_p, gimplify_ctxp->conditional_cleanups);
370 gimplify_ctxp->conditional_cleanups = NULL;
374 /* A stable comparison routine for use with splay trees and DECLs. */
376 static int
377 splay_tree_compare_decl_uid (splay_tree_key xa, splay_tree_key xb)
379 tree a = (tree) xa;
380 tree b = (tree) xb;
382 return DECL_UID (a) - DECL_UID (b);
385 /* Create a new omp construct that deals with variable remapping. */
387 static struct gimplify_omp_ctx *
388 new_omp_context (enum omp_region_type region_type)
390 struct gimplify_omp_ctx *c;
392 c = XCNEW (struct gimplify_omp_ctx);
393 c->outer_context = gimplify_omp_ctxp;
394 c->variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0);
395 c->privatized_types = new hash_set<tree>;
396 c->location = input_location;
397 c->region_type = region_type;
398 if ((region_type & ORT_TASK) == 0)
399 c->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
400 else
401 c->default_kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
403 return c;
406 /* Destroy an omp construct that deals with variable remapping. */
408 static void
409 delete_omp_context (struct gimplify_omp_ctx *c)
411 splay_tree_delete (c->variables);
412 delete c->privatized_types;
413 c->loop_iter_var.release ();
414 XDELETE (c);
417 static void omp_add_variable (struct gimplify_omp_ctx *, tree, unsigned int);
418 static bool omp_notice_variable (struct gimplify_omp_ctx *, tree, bool);
420 /* Both gimplify the statement T and append it to *SEQ_P. This function
421 behaves exactly as gimplify_stmt, but you don't have to pass T as a
422 reference. */
424 void
425 gimplify_and_add (tree t, gimple_seq *seq_p)
427 gimplify_stmt (&t, seq_p);
430 /* Gimplify statement T into sequence *SEQ_P, and return the first
431 tuple in the sequence of generated tuples for this statement.
432 Return NULL if gimplifying T produced no tuples. */
434 static gimple *
435 gimplify_and_return_first (tree t, gimple_seq *seq_p)
437 gimple_stmt_iterator last = gsi_last (*seq_p);
439 gimplify_and_add (t, seq_p);
441 if (!gsi_end_p (last))
443 gsi_next (&last);
444 return gsi_stmt (last);
446 else
447 return gimple_seq_first_stmt (*seq_p);
450 /* Returns true iff T is a valid RHS for an assignment to an un-renamed
451 LHS, or for a call argument. */
453 static bool
454 is_gimple_mem_rhs (tree t)
456 /* If we're dealing with a renamable type, either source or dest must be
457 a renamed variable. */
458 if (is_gimple_reg_type (TREE_TYPE (t)))
459 return is_gimple_val (t);
460 else
461 return is_gimple_val (t) || is_gimple_lvalue (t);
464 /* Return true if T is a CALL_EXPR or an expression that can be
465 assigned to a temporary. Note that this predicate should only be
466 used during gimplification. See the rationale for this in
467 gimplify_modify_expr. */
469 static bool
470 is_gimple_reg_rhs_or_call (tree t)
472 return (get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS
473 || TREE_CODE (t) == CALL_EXPR);
476 /* Return true if T is a valid memory RHS or a CALL_EXPR. Note that
477 this predicate should only be used during gimplification. See the
478 rationale for this in gimplify_modify_expr. */
480 static bool
481 is_gimple_mem_rhs_or_call (tree t)
483 /* If we're dealing with a renamable type, either source or dest must be
484 a renamed variable. */
485 if (is_gimple_reg_type (TREE_TYPE (t)))
486 return is_gimple_val (t);
487 else
488 return (is_gimple_val (t) || is_gimple_lvalue (t)
489 || TREE_CODE (t) == CALL_EXPR);
492 /* Create a temporary with a name derived from VAL. Subroutine of
493 lookup_tmp_var; nobody else should call this function. */
495 static inline tree
496 create_tmp_from_val (tree val)
498 /* Drop all qualifiers and address-space information from the value type. */
499 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (val));
500 tree var = create_tmp_var (type, get_name (val));
501 if (TREE_CODE (TREE_TYPE (var)) == COMPLEX_TYPE
502 || TREE_CODE (TREE_TYPE (var)) == VECTOR_TYPE)
503 DECL_GIMPLE_REG_P (var) = 1;
504 return var;
507 /* Create a temporary to hold the value of VAL. If IS_FORMAL, try to reuse
508 an existing expression temporary. */
510 static tree
511 lookup_tmp_var (tree val, bool is_formal)
513 tree ret;
515 /* If not optimizing, never really reuse a temporary. local-alloc
516 won't allocate any variable that is used in more than one basic
517 block, which means it will go into memory, causing much extra
518 work in reload and final and poorer code generation, outweighing
519 the extra memory allocation here. */
520 if (!optimize || !is_formal || TREE_SIDE_EFFECTS (val))
521 ret = create_tmp_from_val (val);
522 else
524 elt_t elt, *elt_p;
525 elt_t **slot;
527 elt.val = val;
528 if (!gimplify_ctxp->temp_htab)
529 gimplify_ctxp->temp_htab = new hash_table<gimplify_hasher> (1000);
530 slot = gimplify_ctxp->temp_htab->find_slot (&elt, INSERT);
531 if (*slot == NULL)
533 elt_p = XNEW (elt_t);
534 elt_p->val = val;
535 elt_p->temp = ret = create_tmp_from_val (val);
536 *slot = elt_p;
538 else
540 elt_p = *slot;
541 ret = elt_p->temp;
545 return ret;
548 /* Helper for get_formal_tmp_var and get_initialized_tmp_var. */
550 static tree
551 internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
552 bool is_formal, bool allow_ssa)
554 tree t, mod;
556 /* Notice that we explicitly allow VAL to be a CALL_EXPR so that we
557 can create an INIT_EXPR and convert it into a GIMPLE_CALL below. */
558 gimplify_expr (&val, pre_p, post_p, is_gimple_reg_rhs_or_call,
559 fb_rvalue);
561 if (allow_ssa
562 && gimplify_ctxp->into_ssa
563 && is_gimple_reg_type (TREE_TYPE (val)))
565 t = make_ssa_name (TYPE_MAIN_VARIANT (TREE_TYPE (val)));
566 if (! gimple_in_ssa_p (cfun))
568 const char *name = get_name (val);
569 if (name)
570 SET_SSA_NAME_VAR_OR_IDENTIFIER (t, create_tmp_var_name (name));
573 else
574 t = lookup_tmp_var (val, is_formal);
576 mod = build2 (INIT_EXPR, TREE_TYPE (t), t, unshare_expr (val));
578 SET_EXPR_LOCATION (mod, EXPR_LOC_OR_LOC (val, input_location));
580 /* gimplify_modify_expr might want to reduce this further. */
581 gimplify_and_add (mod, pre_p);
582 ggc_free (mod);
584 return t;
587 /* Return a formal temporary variable initialized with VAL. PRE_P is as
588 in gimplify_expr. Only use this function if:
590 1) The value of the unfactored expression represented by VAL will not
591 change between the initialization and use of the temporary, and
592 2) The temporary will not be otherwise modified.
594 For instance, #1 means that this is inappropriate for SAVE_EXPR temps,
595 and #2 means it is inappropriate for && temps.
597 For other cases, use get_initialized_tmp_var instead. */
599 tree
600 get_formal_tmp_var (tree val, gimple_seq *pre_p)
602 return internal_get_tmp_var (val, pre_p, NULL, true, true);
605 /* Return a temporary variable initialized with VAL. PRE_P and POST_P
606 are as in gimplify_expr. */
608 tree
609 get_initialized_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
610 bool allow_ssa)
612 return internal_get_tmp_var (val, pre_p, post_p, false, allow_ssa);
615 /* Declare all the variables in VARS in SCOPE. If DEBUG_INFO is true,
616 generate debug info for them; otherwise don't. */
618 void
619 declare_vars (tree vars, gimple *gs, bool debug_info)
621 tree last = vars;
622 if (last)
624 tree temps, block;
626 gbind *scope = as_a <gbind *> (gs);
628 temps = nreverse (last);
630 block = gimple_bind_block (scope);
631 gcc_assert (!block || TREE_CODE (block) == BLOCK);
632 if (!block || !debug_info)
634 DECL_CHAIN (last) = gimple_bind_vars (scope);
635 gimple_bind_set_vars (scope, temps);
637 else
639 /* We need to attach the nodes both to the BIND_EXPR and to its
640 associated BLOCK for debugging purposes. The key point here
641 is that the BLOCK_VARS of the BIND_EXPR_BLOCK of a BIND_EXPR
642 is a subchain of the BIND_EXPR_VARS of the BIND_EXPR. */
643 if (BLOCK_VARS (block))
644 BLOCK_VARS (block) = chainon (BLOCK_VARS (block), temps);
645 else
647 gimple_bind_set_vars (scope,
648 chainon (gimple_bind_vars (scope), temps));
649 BLOCK_VARS (block) = temps;
655 /* For VAR a VAR_DECL of variable size, try to find a constant upper bound
656 for the size and adjust DECL_SIZE/DECL_SIZE_UNIT accordingly. Abort if
657 no such upper bound can be obtained. */
659 static void
660 force_constant_size (tree var)
662 /* The only attempt we make is by querying the maximum size of objects
663 of the variable's type. */
665 HOST_WIDE_INT max_size;
667 gcc_assert (TREE_CODE (var) == VAR_DECL);
669 max_size = max_int_size_in_bytes (TREE_TYPE (var));
671 gcc_assert (max_size >= 0);
673 DECL_SIZE_UNIT (var)
674 = build_int_cst (TREE_TYPE (DECL_SIZE_UNIT (var)), max_size);
675 DECL_SIZE (var)
676 = build_int_cst (TREE_TYPE (DECL_SIZE (var)), max_size * BITS_PER_UNIT);
679 /* Push the temporary variable TMP into the current binding. */
681 void
682 gimple_add_tmp_var_fn (struct function *fn, tree tmp)
684 gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
686 /* Later processing assumes that the object size is constant, which might
687 not be true at this point. Force the use of a constant upper bound in
688 this case. */
689 if (!tree_fits_uhwi_p (DECL_SIZE_UNIT (tmp)))
690 force_constant_size (tmp);
692 DECL_CONTEXT (tmp) = fn->decl;
693 DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
695 record_vars_into (tmp, fn->decl);
698 /* Push the temporary variable TMP into the current binding. */
700 void
701 gimple_add_tmp_var (tree tmp)
703 gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
705 /* Later processing assumes that the object size is constant, which might
706 not be true at this point. Force the use of a constant upper bound in
707 this case. */
708 if (!tree_fits_uhwi_p (DECL_SIZE_UNIT (tmp)))
709 force_constant_size (tmp);
711 DECL_CONTEXT (tmp) = current_function_decl;
712 DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
714 if (gimplify_ctxp)
716 DECL_CHAIN (tmp) = gimplify_ctxp->temps;
717 gimplify_ctxp->temps = tmp;
719 /* Mark temporaries local within the nearest enclosing parallel. */
720 if (gimplify_omp_ctxp)
722 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
723 while (ctx
724 && (ctx->region_type == ORT_WORKSHARE
725 || ctx->region_type == ORT_SIMD
726 || ctx->region_type == ORT_ACC))
727 ctx = ctx->outer_context;
728 if (ctx)
729 omp_add_variable (ctx, tmp, GOVD_LOCAL | GOVD_SEEN);
732 else if (cfun)
733 record_vars (tmp);
734 else
736 gimple_seq body_seq;
738 /* This case is for nested functions. We need to expose the locals
739 they create. */
740 body_seq = gimple_body (current_function_decl);
741 declare_vars (tmp, gimple_seq_first_stmt (body_seq), false);
747 /* This page contains routines to unshare tree nodes, i.e. to duplicate tree
748 nodes that are referenced more than once in GENERIC functions. This is
749 necessary because gimplification (translation into GIMPLE) is performed
750 by modifying tree nodes in-place, so gimplication of a shared node in a
751 first context could generate an invalid GIMPLE form in a second context.
753 This is achieved with a simple mark/copy/unmark algorithm that walks the
754 GENERIC representation top-down, marks nodes with TREE_VISITED the first
755 time it encounters them, duplicates them if they already have TREE_VISITED
756 set, and finally removes the TREE_VISITED marks it has set.
758 The algorithm works only at the function level, i.e. it generates a GENERIC
759 representation of a function with no nodes shared within the function when
760 passed a GENERIC function (except for nodes that are allowed to be shared).
762 At the global level, it is also necessary to unshare tree nodes that are
763 referenced in more than one function, for the same aforementioned reason.
764 This requires some cooperation from the front-end. There are 2 strategies:
766 1. Manual unsharing. The front-end needs to call unshare_expr on every
767 expression that might end up being shared across functions.
769 2. Deep unsharing. This is an extension of regular unsharing. Instead
770 of calling unshare_expr on expressions that might be shared across
771 functions, the front-end pre-marks them with TREE_VISITED. This will
772 ensure that they are unshared on the first reference within functions
773 when the regular unsharing algorithm runs. The counterpart is that
774 this algorithm must look deeper than for manual unsharing, which is
775 specified by LANG_HOOKS_DEEP_UNSHARING.
777 If there are only few specific cases of node sharing across functions, it is
778 probably easier for a front-end to unshare the expressions manually. On the
779 contrary, if the expressions generated at the global level are as widespread
780 as expressions generated within functions, deep unsharing is very likely the
781 way to go. */
783 /* Similar to copy_tree_r but do not copy SAVE_EXPR or TARGET_EXPR nodes.
784 These nodes model computations that must be done once. If we were to
785 unshare something like SAVE_EXPR(i++), the gimplification process would
786 create wrong code. However, if DATA is non-null, it must hold a pointer
787 set that is used to unshare the subtrees of these nodes. */
789 static tree
790 mostly_copy_tree_r (tree *tp, int *walk_subtrees, void *data)
792 tree t = *tp;
793 enum tree_code code = TREE_CODE (t);
795 /* Do not copy SAVE_EXPR, TARGET_EXPR or BIND_EXPR nodes themselves, but
796 copy their subtrees if we can make sure to do it only once. */
797 if (code == SAVE_EXPR || code == TARGET_EXPR || code == BIND_EXPR)
799 if (data && !((hash_set<tree> *)data)->add (t))
801 else
802 *walk_subtrees = 0;
805 /* Stop at types, decls, constants like copy_tree_r. */
806 else if (TREE_CODE_CLASS (code) == tcc_type
807 || TREE_CODE_CLASS (code) == tcc_declaration
808 || TREE_CODE_CLASS (code) == tcc_constant
809 /* We can't do anything sensible with a BLOCK used as an
810 expression, but we also can't just die when we see it
811 because of non-expression uses. So we avert our eyes
812 and cross our fingers. Silly Java. */
813 || code == BLOCK)
814 *walk_subtrees = 0;
816 /* Cope with the statement expression extension. */
817 else if (code == STATEMENT_LIST)
820 /* Leave the bulk of the work to copy_tree_r itself. */
821 else
822 copy_tree_r (tp, walk_subtrees, NULL);
824 return NULL_TREE;
827 /* Callback for walk_tree to unshare most of the shared trees rooted at *TP.
828 If *TP has been visited already, then *TP is deeply copied by calling
829 mostly_copy_tree_r. DATA is passed to mostly_copy_tree_r unmodified. */
831 static tree
832 copy_if_shared_r (tree *tp, int *walk_subtrees, void *data)
834 tree t = *tp;
835 enum tree_code code = TREE_CODE (t);
837 /* Skip types, decls, and constants. But we do want to look at their
838 types and the bounds of types. Mark them as visited so we properly
839 unmark their subtrees on the unmark pass. If we've already seen them,
840 don't look down further. */
841 if (TREE_CODE_CLASS (code) == tcc_type
842 || TREE_CODE_CLASS (code) == tcc_declaration
843 || TREE_CODE_CLASS (code) == tcc_constant)
845 if (TREE_VISITED (t))
846 *walk_subtrees = 0;
847 else
848 TREE_VISITED (t) = 1;
851 /* If this node has been visited already, unshare it and don't look
852 any deeper. */
853 else if (TREE_VISITED (t))
855 walk_tree (tp, mostly_copy_tree_r, data, NULL);
856 *walk_subtrees = 0;
859 /* Otherwise, mark the node as visited and keep looking. */
860 else
861 TREE_VISITED (t) = 1;
863 return NULL_TREE;
866 /* Unshare most of the shared trees rooted at *TP. DATA is passed to the
867 copy_if_shared_r callback unmodified. */
869 static inline void
870 copy_if_shared (tree *tp, void *data)
872 walk_tree (tp, copy_if_shared_r, data, NULL);
875 /* Unshare all the trees in the body of FNDECL, as well as in the bodies of
876 any nested functions. */
878 static void
879 unshare_body (tree fndecl)
881 struct cgraph_node *cgn = cgraph_node::get (fndecl);
882 /* If the language requires deep unsharing, we need a pointer set to make
883 sure we don't repeatedly unshare subtrees of unshareable nodes. */
884 hash_set<tree> *visited
885 = lang_hooks.deep_unsharing ? new hash_set<tree> : NULL;
887 copy_if_shared (&DECL_SAVED_TREE (fndecl), visited);
888 copy_if_shared (&DECL_SIZE (DECL_RESULT (fndecl)), visited);
889 copy_if_shared (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)), visited);
891 delete visited;
893 if (cgn)
894 for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
895 unshare_body (cgn->decl);
898 /* Callback for walk_tree to unmark the visited trees rooted at *TP.
899 Subtrees are walked until the first unvisited node is encountered. */
901 static tree
902 unmark_visited_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
904 tree t = *tp;
906 /* If this node has been visited, unmark it and keep looking. */
907 if (TREE_VISITED (t))
908 TREE_VISITED (t) = 0;
910 /* Otherwise, don't look any deeper. */
911 else
912 *walk_subtrees = 0;
914 return NULL_TREE;
917 /* Unmark the visited trees rooted at *TP. */
919 static inline void
920 unmark_visited (tree *tp)
922 walk_tree (tp, unmark_visited_r, NULL, NULL);
925 /* Likewise, but mark all trees as not visited. */
927 static void
928 unvisit_body (tree fndecl)
930 struct cgraph_node *cgn = cgraph_node::get (fndecl);
932 unmark_visited (&DECL_SAVED_TREE (fndecl));
933 unmark_visited (&DECL_SIZE (DECL_RESULT (fndecl)));
934 unmark_visited (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)));
936 if (cgn)
937 for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
938 unvisit_body (cgn->decl);
941 /* Unconditionally make an unshared copy of EXPR. This is used when using
942 stored expressions which span multiple functions, such as BINFO_VTABLE,
943 as the normal unsharing process can't tell that they're shared. */
945 tree
946 unshare_expr (tree expr)
948 walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
949 return expr;
952 /* Worker for unshare_expr_without_location. */
954 static tree
955 prune_expr_location (tree *tp, int *walk_subtrees, void *)
957 if (EXPR_P (*tp))
958 SET_EXPR_LOCATION (*tp, UNKNOWN_LOCATION);
959 else
960 *walk_subtrees = 0;
961 return NULL_TREE;
964 /* Similar to unshare_expr but also prune all expression locations
965 from EXPR. */
967 tree
968 unshare_expr_without_location (tree expr)
970 walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
971 if (EXPR_P (expr))
972 walk_tree (&expr, prune_expr_location, NULL, NULL);
973 return expr;
976 /* WRAPPER is a code such as BIND_EXPR or CLEANUP_POINT_EXPR which can both
977 contain statements and have a value. Assign its value to a temporary
978 and give it void_type_node. Return the temporary, or NULL_TREE if
979 WRAPPER was already void. */
981 tree
982 voidify_wrapper_expr (tree wrapper, tree temp)
984 tree type = TREE_TYPE (wrapper);
985 if (type && !VOID_TYPE_P (type))
987 tree *p;
989 /* Set p to point to the body of the wrapper. Loop until we find
990 something that isn't a wrapper. */
991 for (p = &wrapper; p && *p; )
993 switch (TREE_CODE (*p))
995 case BIND_EXPR:
996 TREE_SIDE_EFFECTS (*p) = 1;
997 TREE_TYPE (*p) = void_type_node;
998 /* For a BIND_EXPR, the body is operand 1. */
999 p = &BIND_EXPR_BODY (*p);
1000 break;
1002 case CLEANUP_POINT_EXPR:
1003 case TRY_FINALLY_EXPR:
1004 case TRY_CATCH_EXPR:
1005 TREE_SIDE_EFFECTS (*p) = 1;
1006 TREE_TYPE (*p) = void_type_node;
1007 p = &TREE_OPERAND (*p, 0);
1008 break;
1010 case STATEMENT_LIST:
1012 tree_stmt_iterator i = tsi_last (*p);
1013 TREE_SIDE_EFFECTS (*p) = 1;
1014 TREE_TYPE (*p) = void_type_node;
1015 p = tsi_end_p (i) ? NULL : tsi_stmt_ptr (i);
1017 break;
1019 case COMPOUND_EXPR:
1020 /* Advance to the last statement. Set all container types to
1021 void. */
1022 for (; TREE_CODE (*p) == COMPOUND_EXPR; p = &TREE_OPERAND (*p, 1))
1024 TREE_SIDE_EFFECTS (*p) = 1;
1025 TREE_TYPE (*p) = void_type_node;
1027 break;
1029 case TRANSACTION_EXPR:
1030 TREE_SIDE_EFFECTS (*p) = 1;
1031 TREE_TYPE (*p) = void_type_node;
1032 p = &TRANSACTION_EXPR_BODY (*p);
1033 break;
1035 default:
1036 /* Assume that any tree upon which voidify_wrapper_expr is
1037 directly called is a wrapper, and that its body is op0. */
1038 if (p == &wrapper)
1040 TREE_SIDE_EFFECTS (*p) = 1;
1041 TREE_TYPE (*p) = void_type_node;
1042 p = &TREE_OPERAND (*p, 0);
1043 break;
1045 goto out;
1049 out:
1050 if (p == NULL || IS_EMPTY_STMT (*p))
1051 temp = NULL_TREE;
1052 else if (temp)
1054 /* The wrapper is on the RHS of an assignment that we're pushing
1055 down. */
1056 gcc_assert (TREE_CODE (temp) == INIT_EXPR
1057 || TREE_CODE (temp) == MODIFY_EXPR);
1058 TREE_OPERAND (temp, 1) = *p;
1059 *p = temp;
1061 else
1063 temp = create_tmp_var (type, "retval");
1064 *p = build2 (INIT_EXPR, type, temp, *p);
1067 return temp;
1070 return NULL_TREE;
1073 /* Prepare calls to builtins to SAVE and RESTORE the stack as well as
1074 a temporary through which they communicate. */
1076 static void
1077 build_stack_save_restore (gcall **save, gcall **restore)
1079 tree tmp_var;
1081 *save = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_SAVE), 0);
1082 tmp_var = create_tmp_var (ptr_type_node, "saved_stack");
1083 gimple_call_set_lhs (*save, tmp_var);
1085 *restore
1086 = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_RESTORE),
1087 1, tmp_var);
1090 /* Gimplify a BIND_EXPR. Just voidify and recurse. */
1092 static enum gimplify_status
1093 gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p)
1095 tree bind_expr = *expr_p;
1096 bool old_keep_stack = gimplify_ctxp->keep_stack;
1097 bool old_save_stack = gimplify_ctxp->save_stack;
1098 tree t;
1099 gbind *bind_stmt;
1100 gimple_seq body, cleanup;
1101 gcall *stack_save;
1102 location_t start_locus = 0, end_locus = 0;
1103 tree ret_clauses = NULL;
1105 tree temp = voidify_wrapper_expr (bind_expr, NULL);
1107 /* Mark variables seen in this bind expr. */
1108 for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t))
1110 if (TREE_CODE (t) == VAR_DECL)
1112 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
1114 /* Mark variable as local. */
1115 if (ctx && ctx->region_type != ORT_NONE && !DECL_EXTERNAL (t)
1116 && (! DECL_SEEN_IN_BIND_EXPR_P (t)
1117 || splay_tree_lookup (ctx->variables,
1118 (splay_tree_key) t) == NULL))
1120 if (ctx->region_type == ORT_SIMD
1121 && TREE_ADDRESSABLE (t)
1122 && !TREE_STATIC (t))
1123 omp_add_variable (ctx, t, GOVD_PRIVATE | GOVD_SEEN);
1124 else
1125 omp_add_variable (ctx, t, GOVD_LOCAL | GOVD_SEEN);
1128 DECL_SEEN_IN_BIND_EXPR_P (t) = 1;
1130 if (DECL_HARD_REGISTER (t) && !is_global_var (t) && cfun)
1131 cfun->has_local_explicit_reg_vars = true;
1134 /* Preliminarily mark non-addressed complex variables as eligible
1135 for promotion to gimple registers. We'll transform their uses
1136 as we find them. */
1137 if ((TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE
1138 || TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
1139 && !TREE_THIS_VOLATILE (t)
1140 && (TREE_CODE (t) == VAR_DECL && !DECL_HARD_REGISTER (t))
1141 && !needs_to_live_in_memory (t))
1142 DECL_GIMPLE_REG_P (t) = 1;
1145 bind_stmt = gimple_build_bind (BIND_EXPR_VARS (bind_expr), NULL,
1146 BIND_EXPR_BLOCK (bind_expr));
1147 gimple_push_bind_expr (bind_stmt);
1149 gimplify_ctxp->keep_stack = false;
1150 gimplify_ctxp->save_stack = false;
1152 /* Gimplify the body into the GIMPLE_BIND tuple's body. */
1153 body = NULL;
1154 gimplify_stmt (&BIND_EXPR_BODY (bind_expr), &body);
1155 gimple_bind_set_body (bind_stmt, body);
1157 /* Source location wise, the cleanup code (stack_restore and clobbers)
1158 belongs to the end of the block, so propagate what we have. The
1159 stack_save operation belongs to the beginning of block, which we can
1160 infer from the bind_expr directly if the block has no explicit
1161 assignment. */
1162 if (BIND_EXPR_BLOCK (bind_expr))
1164 end_locus = BLOCK_SOURCE_END_LOCATION (BIND_EXPR_BLOCK (bind_expr));
1165 start_locus = BLOCK_SOURCE_LOCATION (BIND_EXPR_BLOCK (bind_expr));
1167 if (start_locus == 0)
1168 start_locus = EXPR_LOCATION (bind_expr);
1170 cleanup = NULL;
1171 stack_save = NULL;
1173 /* If the code both contains VLAs and calls alloca, then we cannot reclaim
1174 the stack space allocated to the VLAs. */
1175 if (gimplify_ctxp->save_stack && !gimplify_ctxp->keep_stack)
1177 gcall *stack_restore;
1179 /* Save stack on entry and restore it on exit. Add a try_finally
1180 block to achieve this. */
1181 build_stack_save_restore (&stack_save, &stack_restore);
1183 gimple_set_location (stack_save, start_locus);
1184 gimple_set_location (stack_restore, end_locus);
1186 gimplify_seq_add_stmt (&cleanup, stack_restore);
1189 /* Add clobbers for all variables that go out of scope. */
1190 for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t))
1192 if (TREE_CODE (t) == VAR_DECL
1193 && !is_global_var (t)
1194 && DECL_CONTEXT (t) == current_function_decl
1195 && !DECL_HARD_REGISTER (t)
1196 && !TREE_THIS_VOLATILE (t)
1197 && !DECL_HAS_VALUE_EXPR_P (t)
1198 /* Only care for variables that have to be in memory. Others
1199 will be rewritten into SSA names, hence moved to the top-level. */
1200 && !is_gimple_reg (t)
1201 && flag_stack_reuse != SR_NONE)
1203 tree clobber = build_constructor (TREE_TYPE (t), NULL);
1204 gimple *clobber_stmt;
1205 TREE_THIS_VOLATILE (clobber) = 1;
1206 clobber_stmt = gimple_build_assign (t, clobber);
1207 gimple_set_location (clobber_stmt, end_locus);
1208 gimplify_seq_add_stmt (&cleanup, clobber_stmt);
1210 if (flag_openacc && oacc_declare_returns != NULL)
1212 tree *c = oacc_declare_returns->get (t);
1213 if (c != NULL)
1215 if (ret_clauses)
1216 OMP_CLAUSE_CHAIN (*c) = ret_clauses;
1218 ret_clauses = *c;
1220 oacc_declare_returns->remove (t);
1222 if (oacc_declare_returns->elements () == 0)
1224 delete oacc_declare_returns;
1225 oacc_declare_returns = NULL;
1232 if (ret_clauses)
1234 gomp_target *stmt;
1235 gimple_stmt_iterator si = gsi_start (cleanup);
1237 stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
1238 ret_clauses);
1239 gsi_insert_seq_before_without_update (&si, stmt, GSI_NEW_STMT);
1242 if (cleanup)
1244 gtry *gs;
1245 gimple_seq new_body;
1247 new_body = NULL;
1248 gs = gimple_build_try (gimple_bind_body (bind_stmt), cleanup,
1249 GIMPLE_TRY_FINALLY);
1251 if (stack_save)
1252 gimplify_seq_add_stmt (&new_body, stack_save);
1253 gimplify_seq_add_stmt (&new_body, gs);
1254 gimple_bind_set_body (bind_stmt, new_body);
1257 /* keep_stack propagates all the way up to the outermost BIND_EXPR. */
1258 if (!gimplify_ctxp->keep_stack)
1259 gimplify_ctxp->keep_stack = old_keep_stack;
1260 gimplify_ctxp->save_stack = old_save_stack;
1262 gimple_pop_bind_expr ();
1264 gimplify_seq_add_stmt (pre_p, bind_stmt);
1266 if (temp)
1268 *expr_p = temp;
1269 return GS_OK;
1272 *expr_p = NULL_TREE;
1273 return GS_ALL_DONE;
1276 /* Gimplify a RETURN_EXPR. If the expression to be returned is not a
1277 GIMPLE value, it is assigned to a new temporary and the statement is
1278 re-written to return the temporary.
1280 PRE_P points to the sequence where side effects that must happen before
1281 STMT should be stored. */
1283 static enum gimplify_status
1284 gimplify_return_expr (tree stmt, gimple_seq *pre_p)
1286 greturn *ret;
1287 tree ret_expr = TREE_OPERAND (stmt, 0);
1288 tree result_decl, result;
1290 if (ret_expr == error_mark_node)
1291 return GS_ERROR;
1293 /* Implicit _Cilk_sync must be inserted right before any return statement
1294 if there is a _Cilk_spawn in the function. If the user has provided a
1295 _Cilk_sync, the optimizer should remove this duplicate one. */
1296 if (fn_contains_cilk_spawn_p (cfun))
1298 tree impl_sync = build0 (CILK_SYNC_STMT, void_type_node);
1299 gimplify_and_add (impl_sync, pre_p);
1302 if (!ret_expr
1303 || TREE_CODE (ret_expr) == RESULT_DECL
1304 || ret_expr == error_mark_node)
1306 greturn *ret = gimple_build_return (ret_expr);
1307 gimple_set_no_warning (ret, TREE_NO_WARNING (stmt));
1308 gimplify_seq_add_stmt (pre_p, ret);
1309 return GS_ALL_DONE;
1312 if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))))
1313 result_decl = NULL_TREE;
1314 else
1316 result_decl = TREE_OPERAND (ret_expr, 0);
1318 /* See through a return by reference. */
1319 if (TREE_CODE (result_decl) == INDIRECT_REF)
1320 result_decl = TREE_OPERAND (result_decl, 0);
1322 gcc_assert ((TREE_CODE (ret_expr) == MODIFY_EXPR
1323 || TREE_CODE (ret_expr) == INIT_EXPR)
1324 && TREE_CODE (result_decl) == RESULT_DECL);
1327 /* If aggregate_value_p is true, then we can return the bare RESULT_DECL.
1328 Recall that aggregate_value_p is FALSE for any aggregate type that is
1329 returned in registers. If we're returning values in registers, then
1330 we don't want to extend the lifetime of the RESULT_DECL, particularly
1331 across another call. In addition, for those aggregates for which
1332 hard_function_value generates a PARALLEL, we'll die during normal
1333 expansion of structure assignments; there's special code in expand_return
1334 to handle this case that does not exist in expand_expr. */
1335 if (!result_decl)
1336 result = NULL_TREE;
1337 else if (aggregate_value_p (result_decl, TREE_TYPE (current_function_decl)))
1339 if (TREE_CODE (DECL_SIZE (result_decl)) != INTEGER_CST)
1341 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (result_decl)))
1342 gimplify_type_sizes (TREE_TYPE (result_decl), pre_p);
1343 /* Note that we don't use gimplify_vla_decl because the RESULT_DECL
1344 should be effectively allocated by the caller, i.e. all calls to
1345 this function must be subject to the Return Slot Optimization. */
1346 gimplify_one_sizepos (&DECL_SIZE (result_decl), pre_p);
1347 gimplify_one_sizepos (&DECL_SIZE_UNIT (result_decl), pre_p);
1349 result = result_decl;
1351 else if (gimplify_ctxp->return_temp)
1352 result = gimplify_ctxp->return_temp;
1353 else
1355 result = create_tmp_reg (TREE_TYPE (result_decl));
1357 /* ??? With complex control flow (usually involving abnormal edges),
1358 we can wind up warning about an uninitialized value for this. Due
1359 to how this variable is constructed and initialized, this is never
1360 true. Give up and never warn. */
1361 TREE_NO_WARNING (result) = 1;
1363 gimplify_ctxp->return_temp = result;
1366 /* Smash the lhs of the MODIFY_EXPR to the temporary we plan to use.
1367 Then gimplify the whole thing. */
1368 if (result != result_decl)
1369 TREE_OPERAND (ret_expr, 0) = result;
1371 gimplify_and_add (TREE_OPERAND (stmt, 0), pre_p);
1373 ret = gimple_build_return (result);
1374 gimple_set_no_warning (ret, TREE_NO_WARNING (stmt));
1375 gimplify_seq_add_stmt (pre_p, ret);
1377 return GS_ALL_DONE;
1380 /* Gimplify a variable-length array DECL. */
1382 static void
1383 gimplify_vla_decl (tree decl, gimple_seq *seq_p)
1385 /* This is a variable-sized decl. Simplify its size and mark it
1386 for deferred expansion. */
1387 tree t, addr, ptr_type;
1389 gimplify_one_sizepos (&DECL_SIZE (decl), seq_p);
1390 gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), seq_p);
1392 /* Don't mess with a DECL_VALUE_EXPR set by the front-end. */
1393 if (DECL_HAS_VALUE_EXPR_P (decl))
1394 return;
1396 /* All occurrences of this decl in final gimplified code will be
1397 replaced by indirection. Setting DECL_VALUE_EXPR does two
1398 things: First, it lets the rest of the gimplifier know what
1399 replacement to use. Second, it lets the debug info know
1400 where to find the value. */
1401 ptr_type = build_pointer_type (TREE_TYPE (decl));
1402 addr = create_tmp_var (ptr_type, get_name (decl));
1403 DECL_IGNORED_P (addr) = 0;
1404 t = build_fold_indirect_ref (addr);
1405 TREE_THIS_NOTRAP (t) = 1;
1406 SET_DECL_VALUE_EXPR (decl, t);
1407 DECL_HAS_VALUE_EXPR_P (decl) = 1;
1409 t = builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN);
1410 t = build_call_expr (t, 2, DECL_SIZE_UNIT (decl),
1411 size_int (DECL_ALIGN (decl)));
1412 /* The call has been built for a variable-sized object. */
1413 CALL_ALLOCA_FOR_VAR_P (t) = 1;
1414 t = fold_convert (ptr_type, t);
1415 t = build2 (MODIFY_EXPR, TREE_TYPE (addr), addr, t);
1417 gimplify_and_add (t, seq_p);
1420 /* A helper function to be called via walk_tree. Mark all labels under *TP
1421 as being forced. To be called for DECL_INITIAL of static variables. */
1423 static tree
1424 force_labels_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
1426 if (TYPE_P (*tp))
1427 *walk_subtrees = 0;
1428 if (TREE_CODE (*tp) == LABEL_DECL)
1430 FORCED_LABEL (*tp) = 1;
1431 cfun->has_forced_label_in_static = 1;
1434 return NULL_TREE;
1437 /* Gimplify a DECL_EXPR node *STMT_P by making any necessary allocation
1438 and initialization explicit. */
1440 static enum gimplify_status
1441 gimplify_decl_expr (tree *stmt_p, gimple_seq *seq_p)
1443 tree stmt = *stmt_p;
1444 tree decl = DECL_EXPR_DECL (stmt);
1446 *stmt_p = NULL_TREE;
1448 if (TREE_TYPE (decl) == error_mark_node)
1449 return GS_ERROR;
1451 if ((TREE_CODE (decl) == TYPE_DECL
1452 || TREE_CODE (decl) == VAR_DECL)
1453 && !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl)))
1455 gimplify_type_sizes (TREE_TYPE (decl), seq_p);
1456 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
1457 gimplify_type_sizes (TREE_TYPE (TREE_TYPE (decl)), seq_p);
1460 /* ??? DECL_ORIGINAL_TYPE is streamed for LTO so it needs to be gimplified
1461 in case its size expressions contain problematic nodes like CALL_EXPR. */
1462 if (TREE_CODE (decl) == TYPE_DECL
1463 && DECL_ORIGINAL_TYPE (decl)
1464 && !TYPE_SIZES_GIMPLIFIED (DECL_ORIGINAL_TYPE (decl)))
1466 gimplify_type_sizes (DECL_ORIGINAL_TYPE (decl), seq_p);
1467 if (TREE_CODE (DECL_ORIGINAL_TYPE (decl)) == REFERENCE_TYPE)
1468 gimplify_type_sizes (TREE_TYPE (DECL_ORIGINAL_TYPE (decl)), seq_p);
1471 if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
1473 tree init = DECL_INITIAL (decl);
1475 if (TREE_CODE (DECL_SIZE_UNIT (decl)) != INTEGER_CST
1476 || (!TREE_STATIC (decl)
1477 && flag_stack_check == GENERIC_STACK_CHECK
1478 && compare_tree_int (DECL_SIZE_UNIT (decl),
1479 STACK_CHECK_MAX_VAR_SIZE) > 0))
1480 gimplify_vla_decl (decl, seq_p);
1482 /* Some front ends do not explicitly declare all anonymous
1483 artificial variables. We compensate here by declaring the
1484 variables, though it would be better if the front ends would
1485 explicitly declare them. */
1486 if (!DECL_SEEN_IN_BIND_EXPR_P (decl)
1487 && DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
1488 gimple_add_tmp_var (decl);
1490 if (init && init != error_mark_node)
1492 if (!TREE_STATIC (decl))
1494 DECL_INITIAL (decl) = NULL_TREE;
1495 init = build2 (INIT_EXPR, void_type_node, decl, init);
1496 gimplify_and_add (init, seq_p);
1497 ggc_free (init);
1499 else
1500 /* We must still examine initializers for static variables
1501 as they may contain a label address. */
1502 walk_tree (&init, force_labels_r, NULL, NULL);
1506 return GS_ALL_DONE;
1509 /* Gimplify a LOOP_EXPR. Normally this just involves gimplifying the body
1510 and replacing the LOOP_EXPR with goto, but if the loop contains an
1511 EXIT_EXPR, we need to append a label for it to jump to. */
1513 static enum gimplify_status
1514 gimplify_loop_expr (tree *expr_p, gimple_seq *pre_p)
1516 tree saved_label = gimplify_ctxp->exit_label;
1517 tree start_label = create_artificial_label (UNKNOWN_LOCATION);
1519 gimplify_seq_add_stmt (pre_p, gimple_build_label (start_label));
1521 gimplify_ctxp->exit_label = NULL_TREE;
1523 gimplify_and_add (LOOP_EXPR_BODY (*expr_p), pre_p);
1525 gimplify_seq_add_stmt (pre_p, gimple_build_goto (start_label));
1527 if (gimplify_ctxp->exit_label)
1528 gimplify_seq_add_stmt (pre_p,
1529 gimple_build_label (gimplify_ctxp->exit_label));
1531 gimplify_ctxp->exit_label = saved_label;
1533 *expr_p = NULL;
1534 return GS_ALL_DONE;
1537 /* Gimplify a statement list onto a sequence. These may be created either
1538 by an enlightened front-end, or by shortcut_cond_expr. */
1540 static enum gimplify_status
1541 gimplify_statement_list (tree *expr_p, gimple_seq *pre_p)
1543 tree temp = voidify_wrapper_expr (*expr_p, NULL);
1545 tree_stmt_iterator i = tsi_start (*expr_p);
1547 while (!tsi_end_p (i))
1549 gimplify_stmt (tsi_stmt_ptr (i), pre_p);
1550 tsi_delink (&i);
1553 if (temp)
1555 *expr_p = temp;
1556 return GS_OK;
1559 return GS_ALL_DONE;
1562 /* Callback for walk_gimple_seq. */
1564 static tree
1565 warn_switch_unreachable_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
1566 struct walk_stmt_info *wi)
1568 gimple *stmt = gsi_stmt (*gsi_p);
1570 *handled_ops_p = true;
1571 switch (gimple_code (stmt))
1573 case GIMPLE_TRY:
1574 /* A compiler-generated cleanup or a user-written try block.
1575 If it's empty, don't dive into it--that would result in
1576 worse location info. */
1577 if (gimple_try_eval (stmt) == NULL)
1579 wi->info = stmt;
1580 return integer_zero_node;
1582 /* Fall through. */
1583 case GIMPLE_BIND:
1584 case GIMPLE_CATCH:
1585 case GIMPLE_EH_FILTER:
1586 case GIMPLE_TRANSACTION:
1587 /* Walk the sub-statements. */
1588 *handled_ops_p = false;
1589 break;
1590 default:
1591 /* Save the first "real" statement (not a decl/lexical scope/...). */
1592 wi->info = stmt;
1593 return integer_zero_node;
1595 return NULL_TREE;
1598 /* Possibly warn about unreachable statements between switch's controlling
1599 expression and the first case. SEQ is the body of a switch expression. */
1601 static void
1602 maybe_warn_switch_unreachable (gimple_seq seq)
1604 if (!warn_switch_unreachable
1605 /* This warning doesn't play well with Fortran when optimizations
1606 are on. */
1607 || lang_GNU_Fortran ()
1608 || seq == NULL)
1609 return;
1611 struct walk_stmt_info wi;
1612 memset (&wi, 0, sizeof (wi));
1613 walk_gimple_seq (seq, warn_switch_unreachable_r, NULL, &wi);
1614 gimple *stmt = (gimple *) wi.info;
1616 if (stmt && gimple_code (stmt) != GIMPLE_LABEL)
1618 if (gimple_code (stmt) == GIMPLE_GOTO
1619 && TREE_CODE (gimple_goto_dest (stmt)) == LABEL_DECL
1620 && DECL_ARTIFICIAL (gimple_goto_dest (stmt)))
1621 /* Don't warn for compiler-generated gotos. These occur
1622 in Duff's devices, for example. */;
1623 else
1624 warning_at (gimple_location (stmt), OPT_Wswitch_unreachable,
1625 "statement will never be executed");
1630 /* Gimplify a SWITCH_EXPR, and collect the vector of labels it can
1631 branch to. */
1633 static enum gimplify_status
1634 gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p)
1636 tree switch_expr = *expr_p;
1637 gimple_seq switch_body_seq = NULL;
1638 enum gimplify_status ret;
1639 tree index_type = TREE_TYPE (switch_expr);
1640 if (index_type == NULL_TREE)
1641 index_type = TREE_TYPE (SWITCH_COND (switch_expr));
1643 ret = gimplify_expr (&SWITCH_COND (switch_expr), pre_p, NULL, is_gimple_val,
1644 fb_rvalue);
1645 if (ret == GS_ERROR || ret == GS_UNHANDLED)
1646 return ret;
1648 if (SWITCH_BODY (switch_expr))
1650 vec<tree> labels;
1651 vec<tree> saved_labels;
1652 tree default_case = NULL_TREE;
1653 gswitch *switch_stmt;
1655 /* If someone can be bothered to fill in the labels, they can
1656 be bothered to null out the body too. */
1657 gcc_assert (!SWITCH_LABELS (switch_expr));
1659 /* Save old labels, get new ones from body, then restore the old
1660 labels. Save all the things from the switch body to append after. */
1661 saved_labels = gimplify_ctxp->case_labels;
1662 gimplify_ctxp->case_labels.create (8);
1664 gimplify_stmt (&SWITCH_BODY (switch_expr), &switch_body_seq);
1666 maybe_warn_switch_unreachable (switch_body_seq);
1668 labels = gimplify_ctxp->case_labels;
1669 gimplify_ctxp->case_labels = saved_labels;
1671 preprocess_case_label_vec_for_gimple (labels, index_type,
1672 &default_case);
1674 if (!default_case)
1676 glabel *new_default;
1678 default_case
1679 = build_case_label (NULL_TREE, NULL_TREE,
1680 create_artificial_label (UNKNOWN_LOCATION));
1681 new_default = gimple_build_label (CASE_LABEL (default_case));
1682 gimplify_seq_add_stmt (&switch_body_seq, new_default);
1685 switch_stmt = gimple_build_switch (SWITCH_COND (switch_expr),
1686 default_case, labels);
1687 gimplify_seq_add_stmt (pre_p, switch_stmt);
1688 gimplify_seq_add_seq (pre_p, switch_body_seq);
1689 labels.release ();
1691 else
1692 gcc_assert (SWITCH_LABELS (switch_expr));
1694 return GS_ALL_DONE;
1697 /* Gimplify the CASE_LABEL_EXPR pointed to by EXPR_P. */
1699 static enum gimplify_status
1700 gimplify_case_label_expr (tree *expr_p, gimple_seq *pre_p)
1702 struct gimplify_ctx *ctxp;
1703 glabel *label_stmt;
1705 /* Invalid programs can play Duff's Device type games with, for example,
1706 #pragma omp parallel. At least in the C front end, we don't
1707 detect such invalid branches until after gimplification, in the
1708 diagnose_omp_blocks pass. */
1709 for (ctxp = gimplify_ctxp; ; ctxp = ctxp->prev_context)
1710 if (ctxp->case_labels.exists ())
1711 break;
1713 label_stmt = gimple_build_label (CASE_LABEL (*expr_p));
1714 ctxp->case_labels.safe_push (*expr_p);
1715 gimplify_seq_add_stmt (pre_p, label_stmt);
1717 return GS_ALL_DONE;
1720 /* Build a GOTO to the LABEL_DECL pointed to by LABEL_P, building it first
1721 if necessary. */
1723 tree
1724 build_and_jump (tree *label_p)
1726 if (label_p == NULL)
1727 /* If there's nowhere to jump, just fall through. */
1728 return NULL_TREE;
1730 if (*label_p == NULL_TREE)
1732 tree label = create_artificial_label (UNKNOWN_LOCATION);
1733 *label_p = label;
1736 return build1 (GOTO_EXPR, void_type_node, *label_p);
1739 /* Gimplify an EXIT_EXPR by converting to a GOTO_EXPR inside a COND_EXPR.
1740 This also involves building a label to jump to and communicating it to
1741 gimplify_loop_expr through gimplify_ctxp->exit_label. */
1743 static enum gimplify_status
1744 gimplify_exit_expr (tree *expr_p)
1746 tree cond = TREE_OPERAND (*expr_p, 0);
1747 tree expr;
1749 expr = build_and_jump (&gimplify_ctxp->exit_label);
1750 expr = build3 (COND_EXPR, void_type_node, cond, expr, NULL_TREE);
1751 *expr_p = expr;
1753 return GS_OK;
1756 /* *EXPR_P is a COMPONENT_REF being used as an rvalue. If its type is
1757 different from its canonical type, wrap the whole thing inside a
1758 NOP_EXPR and force the type of the COMPONENT_REF to be the canonical
1759 type.
1761 The canonical type of a COMPONENT_REF is the type of the field being
1762 referenced--unless the field is a bit-field which can be read directly
1763 in a smaller mode, in which case the canonical type is the
1764 sign-appropriate type corresponding to that mode. */
1766 static void
1767 canonicalize_component_ref (tree *expr_p)
1769 tree expr = *expr_p;
1770 tree type;
1772 gcc_assert (TREE_CODE (expr) == COMPONENT_REF);
1774 if (INTEGRAL_TYPE_P (TREE_TYPE (expr)))
1775 type = TREE_TYPE (get_unwidened (expr, NULL_TREE));
1776 else
1777 type = TREE_TYPE (TREE_OPERAND (expr, 1));
1779 /* One could argue that all the stuff below is not necessary for
1780 the non-bitfield case and declare it a FE error if type
1781 adjustment would be needed. */
1782 if (TREE_TYPE (expr) != type)
1784 #ifdef ENABLE_TYPES_CHECKING
1785 tree old_type = TREE_TYPE (expr);
1786 #endif
1787 int type_quals;
1789 /* We need to preserve qualifiers and propagate them from
1790 operand 0. */
1791 type_quals = TYPE_QUALS (type)
1792 | TYPE_QUALS (TREE_TYPE (TREE_OPERAND (expr, 0)));
1793 if (TYPE_QUALS (type) != type_quals)
1794 type = build_qualified_type (TYPE_MAIN_VARIANT (type), type_quals);
1796 /* Set the type of the COMPONENT_REF to the underlying type. */
1797 TREE_TYPE (expr) = type;
1799 #ifdef ENABLE_TYPES_CHECKING
1800 /* It is now a FE error, if the conversion from the canonical
1801 type to the original expression type is not useless. */
1802 gcc_assert (useless_type_conversion_p (old_type, type));
1803 #endif
1807 /* If a NOP conversion is changing a pointer to array of foo to a pointer
1808 to foo, embed that change in the ADDR_EXPR by converting
1809 T array[U];
1810 (T *)&array
1812 &array[L]
1813 where L is the lower bound. For simplicity, only do this for constant
1814 lower bound.
1815 The constraint is that the type of &array[L] is trivially convertible
1816 to T *. */
1818 static void
1819 canonicalize_addr_expr (tree *expr_p)
1821 tree expr = *expr_p;
1822 tree addr_expr = TREE_OPERAND (expr, 0);
1823 tree datype, ddatype, pddatype;
1825 /* We simplify only conversions from an ADDR_EXPR to a pointer type. */
1826 if (!POINTER_TYPE_P (TREE_TYPE (expr))
1827 || TREE_CODE (addr_expr) != ADDR_EXPR)
1828 return;
1830 /* The addr_expr type should be a pointer to an array. */
1831 datype = TREE_TYPE (TREE_TYPE (addr_expr));
1832 if (TREE_CODE (datype) != ARRAY_TYPE)
1833 return;
1835 /* The pointer to element type shall be trivially convertible to
1836 the expression pointer type. */
1837 ddatype = TREE_TYPE (datype);
1838 pddatype = build_pointer_type (ddatype);
1839 if (!useless_type_conversion_p (TYPE_MAIN_VARIANT (TREE_TYPE (expr)),
1840 pddatype))
1841 return;
1843 /* The lower bound and element sizes must be constant. */
1844 if (!TYPE_SIZE_UNIT (ddatype)
1845 || TREE_CODE (TYPE_SIZE_UNIT (ddatype)) != INTEGER_CST
1846 || !TYPE_DOMAIN (datype) || !TYPE_MIN_VALUE (TYPE_DOMAIN (datype))
1847 || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (datype))) != INTEGER_CST)
1848 return;
1850 /* All checks succeeded. Build a new node to merge the cast. */
1851 *expr_p = build4 (ARRAY_REF, ddatype, TREE_OPERAND (addr_expr, 0),
1852 TYPE_MIN_VALUE (TYPE_DOMAIN (datype)),
1853 NULL_TREE, NULL_TREE);
1854 *expr_p = build1 (ADDR_EXPR, pddatype, *expr_p);
1856 /* We can have stripped a required restrict qualifier above. */
1857 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
1858 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
1861 /* *EXPR_P is a NOP_EXPR or CONVERT_EXPR. Remove it and/or other conversions
1862 underneath as appropriate. */
1864 static enum gimplify_status
1865 gimplify_conversion (tree *expr_p)
1867 location_t loc = EXPR_LOCATION (*expr_p);
1868 gcc_assert (CONVERT_EXPR_P (*expr_p));
1870 /* Then strip away all but the outermost conversion. */
1871 STRIP_SIGN_NOPS (TREE_OPERAND (*expr_p, 0));
1873 /* And remove the outermost conversion if it's useless. */
1874 if (tree_ssa_useless_type_conversion (*expr_p))
1875 *expr_p = TREE_OPERAND (*expr_p, 0);
1877 /* If we still have a conversion at the toplevel,
1878 then canonicalize some constructs. */
1879 if (CONVERT_EXPR_P (*expr_p))
1881 tree sub = TREE_OPERAND (*expr_p, 0);
1883 /* If a NOP conversion is changing the type of a COMPONENT_REF
1884 expression, then canonicalize its type now in order to expose more
1885 redundant conversions. */
1886 if (TREE_CODE (sub) == COMPONENT_REF)
1887 canonicalize_component_ref (&TREE_OPERAND (*expr_p, 0));
1889 /* If a NOP conversion is changing a pointer to array of foo
1890 to a pointer to foo, embed that change in the ADDR_EXPR. */
1891 else if (TREE_CODE (sub) == ADDR_EXPR)
1892 canonicalize_addr_expr (expr_p);
1895 /* If we have a conversion to a non-register type force the
1896 use of a VIEW_CONVERT_EXPR instead. */
1897 if (CONVERT_EXPR_P (*expr_p) && !is_gimple_reg_type (TREE_TYPE (*expr_p)))
1898 *expr_p = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (*expr_p),
1899 TREE_OPERAND (*expr_p, 0));
1901 /* Canonicalize CONVERT_EXPR to NOP_EXPR. */
1902 if (TREE_CODE (*expr_p) == CONVERT_EXPR)
1903 TREE_SET_CODE (*expr_p, NOP_EXPR);
1905 return GS_OK;
1908 /* Nonlocal VLAs seen in the current function. */
1909 static hash_set<tree> *nonlocal_vlas;
1911 /* The VAR_DECLs created for nonlocal VLAs for debug info purposes. */
1912 static tree nonlocal_vla_vars;
1914 /* Gimplify a VAR_DECL or PARM_DECL. Return GS_OK if we expanded a
1915 DECL_VALUE_EXPR, and it's worth re-examining things. */
1917 static enum gimplify_status
1918 gimplify_var_or_parm_decl (tree *expr_p)
1920 tree decl = *expr_p;
1922 /* ??? If this is a local variable, and it has not been seen in any
1923 outer BIND_EXPR, then it's probably the result of a duplicate
1924 declaration, for which we've already issued an error. It would
1925 be really nice if the front end wouldn't leak these at all.
1926 Currently the only known culprit is C++ destructors, as seen
1927 in g++.old-deja/g++.jason/binding.C. */
1928 if (TREE_CODE (decl) == VAR_DECL
1929 && !DECL_SEEN_IN_BIND_EXPR_P (decl)
1930 && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl)
1931 && decl_function_context (decl) == current_function_decl)
1933 gcc_assert (seen_error ());
1934 return GS_ERROR;
1937 /* When within an OMP context, notice uses of variables. */
1938 if (gimplify_omp_ctxp && omp_notice_variable (gimplify_omp_ctxp, decl, true))
1939 return GS_ALL_DONE;
1941 /* If the decl is an alias for another expression, substitute it now. */
1942 if (DECL_HAS_VALUE_EXPR_P (decl))
1944 tree value_expr = DECL_VALUE_EXPR (decl);
1946 /* For referenced nonlocal VLAs add a decl for debugging purposes
1947 to the current function. */
1948 if (TREE_CODE (decl) == VAR_DECL
1949 && TREE_CODE (DECL_SIZE_UNIT (decl)) != INTEGER_CST
1950 && nonlocal_vlas != NULL
1951 && TREE_CODE (value_expr) == INDIRECT_REF
1952 && TREE_CODE (TREE_OPERAND (value_expr, 0)) == VAR_DECL
1953 && decl_function_context (decl) != current_function_decl)
1955 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
1956 while (ctx
1957 && (ctx->region_type == ORT_WORKSHARE
1958 || ctx->region_type == ORT_SIMD
1959 || ctx->region_type == ORT_ACC))
1960 ctx = ctx->outer_context;
1961 if (!ctx && !nonlocal_vlas->add (decl))
1963 tree copy = copy_node (decl);
1965 lang_hooks.dup_lang_specific_decl (copy);
1966 SET_DECL_RTL (copy, 0);
1967 TREE_USED (copy) = 1;
1968 DECL_CHAIN (copy) = nonlocal_vla_vars;
1969 nonlocal_vla_vars = copy;
1970 SET_DECL_VALUE_EXPR (copy, unshare_expr (value_expr));
1971 DECL_HAS_VALUE_EXPR_P (copy) = 1;
1975 *expr_p = unshare_expr (value_expr);
1976 return GS_OK;
1979 return GS_ALL_DONE;
1982 /* Recalculate the value of the TREE_SIDE_EFFECTS flag for T. */
1984 static void
1985 recalculate_side_effects (tree t)
1987 enum tree_code code = TREE_CODE (t);
1988 int len = TREE_OPERAND_LENGTH (t);
1989 int i;
1991 switch (TREE_CODE_CLASS (code))
1993 case tcc_expression:
1994 switch (code)
1996 case INIT_EXPR:
1997 case MODIFY_EXPR:
1998 case VA_ARG_EXPR:
1999 case PREDECREMENT_EXPR:
2000 case PREINCREMENT_EXPR:
2001 case POSTDECREMENT_EXPR:
2002 case POSTINCREMENT_EXPR:
2003 /* All of these have side-effects, no matter what their
2004 operands are. */
2005 return;
2007 default:
2008 break;
2010 /* Fall through. */
2012 case tcc_comparison: /* a comparison expression */
2013 case tcc_unary: /* a unary arithmetic expression */
2014 case tcc_binary: /* a binary arithmetic expression */
2015 case tcc_reference: /* a reference */
2016 case tcc_vl_exp: /* a function call */
2017 TREE_SIDE_EFFECTS (t) = TREE_THIS_VOLATILE (t);
2018 for (i = 0; i < len; ++i)
2020 tree op = TREE_OPERAND (t, i);
2021 if (op && TREE_SIDE_EFFECTS (op))
2022 TREE_SIDE_EFFECTS (t) = 1;
2024 break;
2026 case tcc_constant:
2027 /* No side-effects. */
2028 return;
2030 default:
2031 gcc_unreachable ();
2035 /* Gimplify the COMPONENT_REF, ARRAY_REF, REALPART_EXPR or IMAGPART_EXPR
2036 node *EXPR_P.
2038 compound_lval
2039 : min_lval '[' val ']'
2040 | min_lval '.' ID
2041 | compound_lval '[' val ']'
2042 | compound_lval '.' ID
2044 This is not part of the original SIMPLE definition, which separates
2045 array and member references, but it seems reasonable to handle them
2046 together. Also, this way we don't run into problems with union
2047 aliasing; gcc requires that for accesses through a union to alias, the
2048 union reference must be explicit, which was not always the case when we
2049 were splitting up array and member refs.
2051 PRE_P points to the sequence where side effects that must happen before
2052 *EXPR_P should be stored.
2054 POST_P points to the sequence where side effects that must happen after
2055 *EXPR_P should be stored. */
2057 static enum gimplify_status
2058 gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
2059 fallback_t fallback)
2061 tree *p;
2062 enum gimplify_status ret = GS_ALL_DONE, tret;
2063 int i;
2064 location_t loc = EXPR_LOCATION (*expr_p);
2065 tree expr = *expr_p;
2067 /* Create a stack of the subexpressions so later we can walk them in
2068 order from inner to outer. */
2069 auto_vec<tree, 10> expr_stack;
2071 /* We can handle anything that get_inner_reference can deal with. */
2072 for (p = expr_p; ; p = &TREE_OPERAND (*p, 0))
2074 restart:
2075 /* Fold INDIRECT_REFs now to turn them into ARRAY_REFs. */
2076 if (TREE_CODE (*p) == INDIRECT_REF)
2077 *p = fold_indirect_ref_loc (loc, *p);
2079 if (handled_component_p (*p))
2081 /* Expand DECL_VALUE_EXPR now. In some cases that may expose
2082 additional COMPONENT_REFs. */
2083 else if ((TREE_CODE (*p) == VAR_DECL || TREE_CODE (*p) == PARM_DECL)
2084 && gimplify_var_or_parm_decl (p) == GS_OK)
2085 goto restart;
2086 else
2087 break;
2089 expr_stack.safe_push (*p);
2092 gcc_assert (expr_stack.length ());
2094 /* Now EXPR_STACK is a stack of pointers to all the refs we've
2095 walked through and P points to the innermost expression.
2097 Java requires that we elaborated nodes in source order. That
2098 means we must gimplify the inner expression followed by each of
2099 the indices, in order. But we can't gimplify the inner
2100 expression until we deal with any variable bounds, sizes, or
2101 positions in order to deal with PLACEHOLDER_EXPRs.
2103 So we do this in three steps. First we deal with the annotations
2104 for any variables in the components, then we gimplify the base,
2105 then we gimplify any indices, from left to right. */
2106 for (i = expr_stack.length () - 1; i >= 0; i--)
2108 tree t = expr_stack[i];
2110 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
2112 /* Gimplify the low bound and element type size and put them into
2113 the ARRAY_REF. If these values are set, they have already been
2114 gimplified. */
2115 if (TREE_OPERAND (t, 2) == NULL_TREE)
2117 tree low = unshare_expr (array_ref_low_bound (t));
2118 if (!is_gimple_min_invariant (low))
2120 TREE_OPERAND (t, 2) = low;
2121 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
2122 post_p, is_gimple_reg,
2123 fb_rvalue);
2124 ret = MIN (ret, tret);
2127 else
2129 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
2130 is_gimple_reg, fb_rvalue);
2131 ret = MIN (ret, tret);
2134 if (TREE_OPERAND (t, 3) == NULL_TREE)
2136 tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0)));
2137 tree elmt_size = unshare_expr (array_ref_element_size (t));
2138 tree factor = size_int (TYPE_ALIGN_UNIT (elmt_type));
2140 /* Divide the element size by the alignment of the element
2141 type (above). */
2142 elmt_size
2143 = size_binop_loc (loc, EXACT_DIV_EXPR, elmt_size, factor);
2145 if (!is_gimple_min_invariant (elmt_size))
2147 TREE_OPERAND (t, 3) = elmt_size;
2148 tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p,
2149 post_p, is_gimple_reg,
2150 fb_rvalue);
2151 ret = MIN (ret, tret);
2154 else
2156 tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p, post_p,
2157 is_gimple_reg, fb_rvalue);
2158 ret = MIN (ret, tret);
2161 else if (TREE_CODE (t) == COMPONENT_REF)
2163 /* Set the field offset into T and gimplify it. */
2164 if (TREE_OPERAND (t, 2) == NULL_TREE)
2166 tree offset = unshare_expr (component_ref_field_offset (t));
2167 tree field = TREE_OPERAND (t, 1);
2168 tree factor
2169 = size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT);
2171 /* Divide the offset by its alignment. */
2172 offset = size_binop_loc (loc, EXACT_DIV_EXPR, offset, factor);
2174 if (!is_gimple_min_invariant (offset))
2176 TREE_OPERAND (t, 2) = offset;
2177 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
2178 post_p, is_gimple_reg,
2179 fb_rvalue);
2180 ret = MIN (ret, tret);
2183 else
2185 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
2186 is_gimple_reg, fb_rvalue);
2187 ret = MIN (ret, tret);
2192 /* Step 2 is to gimplify the base expression. Make sure lvalue is set
2193 so as to match the min_lval predicate. Failure to do so may result
2194 in the creation of large aggregate temporaries. */
2195 tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval,
2196 fallback | fb_lvalue);
2197 ret = MIN (ret, tret);
2199 /* And finally, the indices and operands of ARRAY_REF. During this
2200 loop we also remove any useless conversions. */
2201 for (; expr_stack.length () > 0; )
2203 tree t = expr_stack.pop ();
2205 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
2207 /* Gimplify the dimension. */
2208 if (!is_gimple_min_invariant (TREE_OPERAND (t, 1)))
2210 tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
2211 is_gimple_val, fb_rvalue);
2212 ret = MIN (ret, tret);
2216 STRIP_USELESS_TYPE_CONVERSION (TREE_OPERAND (t, 0));
2218 /* The innermost expression P may have originally had
2219 TREE_SIDE_EFFECTS set which would have caused all the outer
2220 expressions in *EXPR_P leading to P to also have had
2221 TREE_SIDE_EFFECTS set. */
2222 recalculate_side_effects (t);
2225 /* If the outermost expression is a COMPONENT_REF, canonicalize its type. */
2226 if ((fallback & fb_rvalue) && TREE_CODE (*expr_p) == COMPONENT_REF)
2228 canonicalize_component_ref (expr_p);
2231 expr_stack.release ();
2233 gcc_assert (*expr_p == expr || ret != GS_ALL_DONE);
2235 return ret;
2238 /* Gimplify the self modifying expression pointed to by EXPR_P
2239 (++, --, +=, -=).
2241 PRE_P points to the list where side effects that must happen before
2242 *EXPR_P should be stored.
2244 POST_P points to the list where side effects that must happen after
2245 *EXPR_P should be stored.
2247 WANT_VALUE is nonzero iff we want to use the value of this expression
2248 in another expression.
2250 ARITH_TYPE is the type the computation should be performed in. */
2252 enum gimplify_status
2253 gimplify_self_mod_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
2254 bool want_value, tree arith_type)
2256 enum tree_code code;
2257 tree lhs, lvalue, rhs, t1;
2258 gimple_seq post = NULL, *orig_post_p = post_p;
2259 bool postfix;
2260 enum tree_code arith_code;
2261 enum gimplify_status ret;
2262 location_t loc = EXPR_LOCATION (*expr_p);
2264 code = TREE_CODE (*expr_p);
2266 gcc_assert (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR
2267 || code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR);
2269 /* Prefix or postfix? */
2270 if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
2271 /* Faster to treat as prefix if result is not used. */
2272 postfix = want_value;
2273 else
2274 postfix = false;
2276 /* For postfix, make sure the inner expression's post side effects
2277 are executed after side effects from this expression. */
2278 if (postfix)
2279 post_p = &post;
2281 /* Add or subtract? */
2282 if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
2283 arith_code = PLUS_EXPR;
2284 else
2285 arith_code = MINUS_EXPR;
2287 /* Gimplify the LHS into a GIMPLE lvalue. */
2288 lvalue = TREE_OPERAND (*expr_p, 0);
2289 ret = gimplify_expr (&lvalue, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
2290 if (ret == GS_ERROR)
2291 return ret;
2293 /* Extract the operands to the arithmetic operation. */
2294 lhs = lvalue;
2295 rhs = TREE_OPERAND (*expr_p, 1);
2297 /* For postfix operator, we evaluate the LHS to an rvalue and then use
2298 that as the result value and in the postqueue operation. */
2299 if (postfix)
2301 ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue);
2302 if (ret == GS_ERROR)
2303 return ret;
2305 lhs = get_initialized_tmp_var (lhs, pre_p, NULL);
2308 /* For POINTERs increment, use POINTER_PLUS_EXPR. */
2309 if (POINTER_TYPE_P (TREE_TYPE (lhs)))
2311 rhs = convert_to_ptrofftype_loc (loc, rhs);
2312 if (arith_code == MINUS_EXPR)
2313 rhs = fold_build1_loc (loc, NEGATE_EXPR, TREE_TYPE (rhs), rhs);
2314 t1 = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (*expr_p), lhs, rhs);
2316 else
2317 t1 = fold_convert (TREE_TYPE (*expr_p),
2318 fold_build2 (arith_code, arith_type,
2319 fold_convert (arith_type, lhs),
2320 fold_convert (arith_type, rhs)));
2322 if (postfix)
2324 gimplify_assign (lvalue, t1, pre_p);
2325 gimplify_seq_add_seq (orig_post_p, post);
2326 *expr_p = lhs;
2327 return GS_ALL_DONE;
2329 else
2331 *expr_p = build2 (MODIFY_EXPR, TREE_TYPE (lvalue), lvalue, t1);
2332 return GS_OK;
2336 /* If *EXPR_P has a variable sized type, wrap it in a WITH_SIZE_EXPR. */
2338 static void
2339 maybe_with_size_expr (tree *expr_p)
2341 tree expr = *expr_p;
2342 tree type = TREE_TYPE (expr);
2343 tree size;
2345 /* If we've already wrapped this or the type is error_mark_node, we can't do
2346 anything. */
2347 if (TREE_CODE (expr) == WITH_SIZE_EXPR
2348 || type == error_mark_node)
2349 return;
2351 /* If the size isn't known or is a constant, we have nothing to do. */
2352 size = TYPE_SIZE_UNIT (type);
2353 if (!size || TREE_CODE (size) == INTEGER_CST)
2354 return;
2356 /* Otherwise, make a WITH_SIZE_EXPR. */
2357 size = unshare_expr (size);
2358 size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, expr);
2359 *expr_p = build2 (WITH_SIZE_EXPR, type, expr, size);
2362 /* Helper for gimplify_call_expr. Gimplify a single argument *ARG_P
2363 Store any side-effects in PRE_P. CALL_LOCATION is the location of
2364 the CALL_EXPR. If ALLOW_SSA is set the actual parameter may be
2365 gimplified to an SSA name. */
2367 enum gimplify_status
2368 gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location,
2369 bool allow_ssa)
2371 bool (*test) (tree);
2372 fallback_t fb;
2374 /* In general, we allow lvalues for function arguments to avoid
2375 extra overhead of copying large aggregates out of even larger
2376 aggregates into temporaries only to copy the temporaries to
2377 the argument list. Make optimizers happy by pulling out to
2378 temporaries those types that fit in registers. */
2379 if (is_gimple_reg_type (TREE_TYPE (*arg_p)))
2380 test = is_gimple_val, fb = fb_rvalue;
2381 else
2383 test = is_gimple_lvalue, fb = fb_either;
2384 /* Also strip a TARGET_EXPR that would force an extra copy. */
2385 if (TREE_CODE (*arg_p) == TARGET_EXPR)
2387 tree init = TARGET_EXPR_INITIAL (*arg_p);
2388 if (init
2389 && !VOID_TYPE_P (TREE_TYPE (init)))
2390 *arg_p = init;
2394 /* If this is a variable sized type, we must remember the size. */
2395 maybe_with_size_expr (arg_p);
2397 /* FIXME diagnostics: This will mess up gcc.dg/Warray-bounds.c. */
2398 /* Make sure arguments have the same location as the function call
2399 itself. */
2400 protected_set_expr_location (*arg_p, call_location);
2402 /* There is a sequence point before a function call. Side effects in
2403 the argument list must occur before the actual call. So, when
2404 gimplifying arguments, force gimplify_expr to use an internal
2405 post queue which is then appended to the end of PRE_P. */
2406 return gimplify_expr (arg_p, pre_p, NULL, test, fb, allow_ssa);
2409 /* Don't fold inside offloading or taskreg regions: it can break code by
2410 adding decl references that weren't in the source. We'll do it during
2411 omplower pass instead. */
2413 static bool
2414 maybe_fold_stmt (gimple_stmt_iterator *gsi)
2416 struct gimplify_omp_ctx *ctx;
2417 for (ctx = gimplify_omp_ctxp; ctx; ctx = ctx->outer_context)
2418 if ((ctx->region_type & (ORT_TARGET | ORT_PARALLEL | ORT_TASK)) != 0)
2419 return false;
2420 return fold_stmt (gsi);
2423 /* Gimplify the CALL_EXPR node *EXPR_P into the GIMPLE sequence PRE_P.
2424 WANT_VALUE is true if the result of the call is desired. */
2426 static enum gimplify_status
2427 gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
2429 tree fndecl, parms, p, fnptrtype;
2430 enum gimplify_status ret;
2431 int i, nargs;
2432 gcall *call;
2433 bool builtin_va_start_p = false;
2434 location_t loc = EXPR_LOCATION (*expr_p);
2436 gcc_assert (TREE_CODE (*expr_p) == CALL_EXPR);
2438 /* For reliable diagnostics during inlining, it is necessary that
2439 every call_expr be annotated with file and line. */
2440 if (! EXPR_HAS_LOCATION (*expr_p))
2441 SET_EXPR_LOCATION (*expr_p, input_location);
2443 /* Gimplify internal functions created in the FEs. */
2444 if (CALL_EXPR_FN (*expr_p) == NULL_TREE)
2446 if (want_value)
2447 return GS_ALL_DONE;
2449 nargs = call_expr_nargs (*expr_p);
2450 enum internal_fn ifn = CALL_EXPR_IFN (*expr_p);
2451 auto_vec<tree> vargs (nargs);
2453 for (i = 0; i < nargs; i++)
2455 gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
2456 EXPR_LOCATION (*expr_p));
2457 vargs.quick_push (CALL_EXPR_ARG (*expr_p, i));
2459 gimple *call = gimple_build_call_internal_vec (ifn, vargs);
2460 gimplify_seq_add_stmt (pre_p, call);
2461 return GS_ALL_DONE;
2464 /* This may be a call to a builtin function.
2466 Builtin function calls may be transformed into different
2467 (and more efficient) builtin function calls under certain
2468 circumstances. Unfortunately, gimplification can muck things
2469 up enough that the builtin expanders are not aware that certain
2470 transformations are still valid.
2472 So we attempt transformation/gimplification of the call before
2473 we gimplify the CALL_EXPR. At this time we do not manage to
2474 transform all calls in the same manner as the expanders do, but
2475 we do transform most of them. */
2476 fndecl = get_callee_fndecl (*expr_p);
2477 if (fndecl
2478 && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
2479 switch (DECL_FUNCTION_CODE (fndecl))
2481 case BUILT_IN_ALLOCA:
2482 case BUILT_IN_ALLOCA_WITH_ALIGN:
2483 /* If the call has been built for a variable-sized object, then we
2484 want to restore the stack level when the enclosing BIND_EXPR is
2485 exited to reclaim the allocated space; otherwise, we precisely
2486 need to do the opposite and preserve the latest stack level. */
2487 if (CALL_ALLOCA_FOR_VAR_P (*expr_p))
2488 gimplify_ctxp->save_stack = true;
2489 else
2490 gimplify_ctxp->keep_stack = true;
2491 break;
2493 case BUILT_IN_VA_START:
2495 builtin_va_start_p = TRUE;
2496 if (call_expr_nargs (*expr_p) < 2)
2498 error ("too few arguments to function %<va_start%>");
2499 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
2500 return GS_OK;
2503 if (fold_builtin_next_arg (*expr_p, true))
2505 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
2506 return GS_OK;
2508 break;
2511 default:
2514 if (fndecl && DECL_BUILT_IN (fndecl))
2516 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
2517 if (new_tree && new_tree != *expr_p)
2519 /* There was a transformation of this call which computes the
2520 same value, but in a more efficient way. Return and try
2521 again. */
2522 *expr_p = new_tree;
2523 return GS_OK;
2527 /* Remember the original function pointer type. */
2528 fnptrtype = TREE_TYPE (CALL_EXPR_FN (*expr_p));
2530 /* There is a sequence point before the call, so any side effects in
2531 the calling expression must occur before the actual call. Force
2532 gimplify_expr to use an internal post queue. */
2533 ret = gimplify_expr (&CALL_EXPR_FN (*expr_p), pre_p, NULL,
2534 is_gimple_call_addr, fb_rvalue);
2536 nargs = call_expr_nargs (*expr_p);
2538 /* Get argument types for verification. */
2539 fndecl = get_callee_fndecl (*expr_p);
2540 parms = NULL_TREE;
2541 if (fndecl)
2542 parms = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
2543 else
2544 parms = TYPE_ARG_TYPES (TREE_TYPE (fnptrtype));
2546 if (fndecl && DECL_ARGUMENTS (fndecl))
2547 p = DECL_ARGUMENTS (fndecl);
2548 else if (parms)
2549 p = parms;
2550 else
2551 p = NULL_TREE;
2552 for (i = 0; i < nargs && p; i++, p = TREE_CHAIN (p))
2555 /* If the last argument is __builtin_va_arg_pack () and it is not
2556 passed as a named argument, decrease the number of CALL_EXPR
2557 arguments and set instead the CALL_EXPR_VA_ARG_PACK flag. */
2558 if (!p
2559 && i < nargs
2560 && TREE_CODE (CALL_EXPR_ARG (*expr_p, nargs - 1)) == CALL_EXPR)
2562 tree last_arg = CALL_EXPR_ARG (*expr_p, nargs - 1);
2563 tree last_arg_fndecl = get_callee_fndecl (last_arg);
2565 if (last_arg_fndecl
2566 && TREE_CODE (last_arg_fndecl) == FUNCTION_DECL
2567 && DECL_BUILT_IN_CLASS (last_arg_fndecl) == BUILT_IN_NORMAL
2568 && DECL_FUNCTION_CODE (last_arg_fndecl) == BUILT_IN_VA_ARG_PACK)
2570 tree call = *expr_p;
2572 --nargs;
2573 *expr_p = build_call_array_loc (loc, TREE_TYPE (call),
2574 CALL_EXPR_FN (call),
2575 nargs, CALL_EXPR_ARGP (call));
2577 /* Copy all CALL_EXPR flags, location and block, except
2578 CALL_EXPR_VA_ARG_PACK flag. */
2579 CALL_EXPR_STATIC_CHAIN (*expr_p) = CALL_EXPR_STATIC_CHAIN (call);
2580 CALL_EXPR_TAILCALL (*expr_p) = CALL_EXPR_TAILCALL (call);
2581 CALL_EXPR_RETURN_SLOT_OPT (*expr_p)
2582 = CALL_EXPR_RETURN_SLOT_OPT (call);
2583 CALL_FROM_THUNK_P (*expr_p) = CALL_FROM_THUNK_P (call);
2584 SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (call));
2586 /* Set CALL_EXPR_VA_ARG_PACK. */
2587 CALL_EXPR_VA_ARG_PACK (*expr_p) = 1;
2591 /* If the call returns twice then after building the CFG the call
2592 argument computations will no longer dominate the call because
2593 we add an abnormal incoming edge to the call. So do not use SSA
2594 vars there. */
2595 bool returns_twice = call_expr_flags (*expr_p) & ECF_RETURNS_TWICE;
2597 /* Gimplify the function arguments. */
2598 if (nargs > 0)
2600 for (i = (PUSH_ARGS_REVERSED ? nargs - 1 : 0);
2601 PUSH_ARGS_REVERSED ? i >= 0 : i < nargs;
2602 PUSH_ARGS_REVERSED ? i-- : i++)
2604 enum gimplify_status t;
2606 /* Avoid gimplifying the second argument to va_start, which needs to
2607 be the plain PARM_DECL. */
2608 if ((i != 1) || !builtin_va_start_p)
2610 t = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
2611 EXPR_LOCATION (*expr_p), ! returns_twice);
2613 if (t == GS_ERROR)
2614 ret = GS_ERROR;
2619 /* Gimplify the static chain. */
2620 if (CALL_EXPR_STATIC_CHAIN (*expr_p))
2622 if (fndecl && !DECL_STATIC_CHAIN (fndecl))
2623 CALL_EXPR_STATIC_CHAIN (*expr_p) = NULL;
2624 else
2626 enum gimplify_status t;
2627 t = gimplify_arg (&CALL_EXPR_STATIC_CHAIN (*expr_p), pre_p,
2628 EXPR_LOCATION (*expr_p), ! returns_twice);
2629 if (t == GS_ERROR)
2630 ret = GS_ERROR;
2634 /* Verify the function result. */
2635 if (want_value && fndecl
2636 && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fnptrtype))))
2638 error_at (loc, "using result of function returning %<void%>");
2639 ret = GS_ERROR;
2642 /* Try this again in case gimplification exposed something. */
2643 if (ret != GS_ERROR)
2645 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
2647 if (new_tree && new_tree != *expr_p)
2649 /* There was a transformation of this call which computes the
2650 same value, but in a more efficient way. Return and try
2651 again. */
2652 *expr_p = new_tree;
2653 return GS_OK;
2656 else
2658 *expr_p = error_mark_node;
2659 return GS_ERROR;
2662 /* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its
2663 decl. This allows us to eliminate redundant or useless
2664 calls to "const" functions. */
2665 if (TREE_CODE (*expr_p) == CALL_EXPR)
2667 int flags = call_expr_flags (*expr_p);
2668 if (flags & (ECF_CONST | ECF_PURE)
2669 /* An infinite loop is considered a side effect. */
2670 && !(flags & (ECF_LOOPING_CONST_OR_PURE)))
2671 TREE_SIDE_EFFECTS (*expr_p) = 0;
2674 /* If the value is not needed by the caller, emit a new GIMPLE_CALL
2675 and clear *EXPR_P. Otherwise, leave *EXPR_P in its gimplified
2676 form and delegate the creation of a GIMPLE_CALL to
2677 gimplify_modify_expr. This is always possible because when
2678 WANT_VALUE is true, the caller wants the result of this call into
2679 a temporary, which means that we will emit an INIT_EXPR in
2680 internal_get_tmp_var which will then be handled by
2681 gimplify_modify_expr. */
2682 if (!want_value)
2684 /* The CALL_EXPR in *EXPR_P is already in GIMPLE form, so all we
2685 have to do is replicate it as a GIMPLE_CALL tuple. */
2686 gimple_stmt_iterator gsi;
2687 call = gimple_build_call_from_tree (*expr_p);
2688 gimple_call_set_fntype (call, TREE_TYPE (fnptrtype));
2689 notice_special_calls (call);
2690 gimplify_seq_add_stmt (pre_p, call);
2691 gsi = gsi_last (*pre_p);
2692 maybe_fold_stmt (&gsi);
2693 *expr_p = NULL_TREE;
2695 else
2696 /* Remember the original function type. */
2697 CALL_EXPR_FN (*expr_p) = build1 (NOP_EXPR, fnptrtype,
2698 CALL_EXPR_FN (*expr_p));
2700 return ret;
2703 /* Handle shortcut semantics in the predicate operand of a COND_EXPR by
2704 rewriting it into multiple COND_EXPRs, and possibly GOTO_EXPRs.
2706 TRUE_LABEL_P and FALSE_LABEL_P point to the labels to jump to if the
2707 condition is true or false, respectively. If null, we should generate
2708 our own to skip over the evaluation of this specific expression.
2710 LOCUS is the source location of the COND_EXPR.
2712 This function is the tree equivalent of do_jump.
2714 shortcut_cond_r should only be called by shortcut_cond_expr. */
2716 static tree
2717 shortcut_cond_r (tree pred, tree *true_label_p, tree *false_label_p,
2718 location_t locus)
2720 tree local_label = NULL_TREE;
2721 tree t, expr = NULL;
2723 /* OK, it's not a simple case; we need to pull apart the COND_EXPR to
2724 retain the shortcut semantics. Just insert the gotos here;
2725 shortcut_cond_expr will append the real blocks later. */
2726 if (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
2728 location_t new_locus;
2730 /* Turn if (a && b) into
2732 if (a); else goto no;
2733 if (b) goto yes; else goto no;
2734 (no:) */
2736 if (false_label_p == NULL)
2737 false_label_p = &local_label;
2739 /* Keep the original source location on the first 'if'. */
2740 t = shortcut_cond_r (TREE_OPERAND (pred, 0), NULL, false_label_p, locus);
2741 append_to_statement_list (t, &expr);
2743 /* Set the source location of the && on the second 'if'. */
2744 new_locus = EXPR_HAS_LOCATION (pred) ? EXPR_LOCATION (pred) : locus;
2745 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
2746 new_locus);
2747 append_to_statement_list (t, &expr);
2749 else if (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
2751 location_t new_locus;
2753 /* Turn if (a || b) into
2755 if (a) goto yes;
2756 if (b) goto yes; else goto no;
2757 (yes:) */
2759 if (true_label_p == NULL)
2760 true_label_p = &local_label;
2762 /* Keep the original source location on the first 'if'. */
2763 t = shortcut_cond_r (TREE_OPERAND (pred, 0), true_label_p, NULL, locus);
2764 append_to_statement_list (t, &expr);
2766 /* Set the source location of the || on the second 'if'. */
2767 new_locus = EXPR_HAS_LOCATION (pred) ? EXPR_LOCATION (pred) : locus;
2768 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
2769 new_locus);
2770 append_to_statement_list (t, &expr);
2772 else if (TREE_CODE (pred) == COND_EXPR
2773 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 1)))
2774 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 2))))
2776 location_t new_locus;
2778 /* As long as we're messing with gotos, turn if (a ? b : c) into
2779 if (a)
2780 if (b) goto yes; else goto no;
2781 else
2782 if (c) goto yes; else goto no;
2784 Don't do this if one of the arms has void type, which can happen
2785 in C++ when the arm is throw. */
2787 /* Keep the original source location on the first 'if'. Set the source
2788 location of the ? on the second 'if'. */
2789 new_locus = EXPR_HAS_LOCATION (pred) ? EXPR_LOCATION (pred) : locus;
2790 expr = build3 (COND_EXPR, void_type_node, TREE_OPERAND (pred, 0),
2791 shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p,
2792 false_label_p, locus),
2793 shortcut_cond_r (TREE_OPERAND (pred, 2), true_label_p,
2794 false_label_p, new_locus));
2796 else
2798 expr = build3 (COND_EXPR, void_type_node, pred,
2799 build_and_jump (true_label_p),
2800 build_and_jump (false_label_p));
2801 SET_EXPR_LOCATION (expr, locus);
2804 if (local_label)
2806 t = build1 (LABEL_EXPR, void_type_node, local_label);
2807 append_to_statement_list (t, &expr);
2810 return expr;
2813 /* Given a conditional expression EXPR with short-circuit boolean
2814 predicates using TRUTH_ANDIF_EXPR or TRUTH_ORIF_EXPR, break the
2815 predicate apart into the equivalent sequence of conditionals. */
2817 static tree
2818 shortcut_cond_expr (tree expr)
2820 tree pred = TREE_OPERAND (expr, 0);
2821 tree then_ = TREE_OPERAND (expr, 1);
2822 tree else_ = TREE_OPERAND (expr, 2);
2823 tree true_label, false_label, end_label, t;
2824 tree *true_label_p;
2825 tree *false_label_p;
2826 bool emit_end, emit_false, jump_over_else;
2827 bool then_se = then_ && TREE_SIDE_EFFECTS (then_);
2828 bool else_se = else_ && TREE_SIDE_EFFECTS (else_);
2830 /* First do simple transformations. */
2831 if (!else_se)
2833 /* If there is no 'else', turn
2834 if (a && b) then c
2835 into
2836 if (a) if (b) then c. */
2837 while (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
2839 /* Keep the original source location on the first 'if'. */
2840 location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
2841 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
2842 /* Set the source location of the && on the second 'if'. */
2843 if (EXPR_HAS_LOCATION (pred))
2844 SET_EXPR_LOCATION (expr, EXPR_LOCATION (pred));
2845 then_ = shortcut_cond_expr (expr);
2846 then_se = then_ && TREE_SIDE_EFFECTS (then_);
2847 pred = TREE_OPERAND (pred, 0);
2848 expr = build3 (COND_EXPR, void_type_node, pred, then_, NULL_TREE);
2849 SET_EXPR_LOCATION (expr, locus);
2853 if (!then_se)
2855 /* If there is no 'then', turn
2856 if (a || b); else d
2857 into
2858 if (a); else if (b); else d. */
2859 while (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
2861 /* Keep the original source location on the first 'if'. */
2862 location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
2863 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
2864 /* Set the source location of the || on the second 'if'. */
2865 if (EXPR_HAS_LOCATION (pred))
2866 SET_EXPR_LOCATION (expr, EXPR_LOCATION (pred));
2867 else_ = shortcut_cond_expr (expr);
2868 else_se = else_ && TREE_SIDE_EFFECTS (else_);
2869 pred = TREE_OPERAND (pred, 0);
2870 expr = build3 (COND_EXPR, void_type_node, pred, NULL_TREE, else_);
2871 SET_EXPR_LOCATION (expr, locus);
2875 /* If we're done, great. */
2876 if (TREE_CODE (pred) != TRUTH_ANDIF_EXPR
2877 && TREE_CODE (pred) != TRUTH_ORIF_EXPR)
2878 return expr;
2880 /* Otherwise we need to mess with gotos. Change
2881 if (a) c; else d;
2883 if (a); else goto no;
2884 c; goto end;
2885 no: d; end:
2886 and recursively gimplify the condition. */
2888 true_label = false_label = end_label = NULL_TREE;
2890 /* If our arms just jump somewhere, hijack those labels so we don't
2891 generate jumps to jumps. */
2893 if (then_
2894 && TREE_CODE (then_) == GOTO_EXPR
2895 && TREE_CODE (GOTO_DESTINATION (then_)) == LABEL_DECL)
2897 true_label = GOTO_DESTINATION (then_);
2898 then_ = NULL;
2899 then_se = false;
2902 if (else_
2903 && TREE_CODE (else_) == GOTO_EXPR
2904 && TREE_CODE (GOTO_DESTINATION (else_)) == LABEL_DECL)
2906 false_label = GOTO_DESTINATION (else_);
2907 else_ = NULL;
2908 else_se = false;
2911 /* If we aren't hijacking a label for the 'then' branch, it falls through. */
2912 if (true_label)
2913 true_label_p = &true_label;
2914 else
2915 true_label_p = NULL;
2917 /* The 'else' branch also needs a label if it contains interesting code. */
2918 if (false_label || else_se)
2919 false_label_p = &false_label;
2920 else
2921 false_label_p = NULL;
2923 /* If there was nothing else in our arms, just forward the label(s). */
2924 if (!then_se && !else_se)
2925 return shortcut_cond_r (pred, true_label_p, false_label_p,
2926 EXPR_LOC_OR_LOC (expr, input_location));
2928 /* If our last subexpression already has a terminal label, reuse it. */
2929 if (else_se)
2930 t = expr_last (else_);
2931 else if (then_se)
2932 t = expr_last (then_);
2933 else
2934 t = NULL;
2935 if (t && TREE_CODE (t) == LABEL_EXPR)
2936 end_label = LABEL_EXPR_LABEL (t);
2938 /* If we don't care about jumping to the 'else' branch, jump to the end
2939 if the condition is false. */
2940 if (!false_label_p)
2941 false_label_p = &end_label;
2943 /* We only want to emit these labels if we aren't hijacking them. */
2944 emit_end = (end_label == NULL_TREE);
2945 emit_false = (false_label == NULL_TREE);
2947 /* We only emit the jump over the else clause if we have to--if the
2948 then clause may fall through. Otherwise we can wind up with a
2949 useless jump and a useless label at the end of gimplified code,
2950 which will cause us to think that this conditional as a whole
2951 falls through even if it doesn't. If we then inline a function
2952 which ends with such a condition, that can cause us to issue an
2953 inappropriate warning about control reaching the end of a
2954 non-void function. */
2955 jump_over_else = block_may_fallthru (then_);
2957 pred = shortcut_cond_r (pred, true_label_p, false_label_p,
2958 EXPR_LOC_OR_LOC (expr, input_location));
2960 expr = NULL;
2961 append_to_statement_list (pred, &expr);
2963 append_to_statement_list (then_, &expr);
2964 if (else_se)
2966 if (jump_over_else)
2968 tree last = expr_last (expr);
2969 t = build_and_jump (&end_label);
2970 if (EXPR_HAS_LOCATION (last))
2971 SET_EXPR_LOCATION (t, EXPR_LOCATION (last));
2972 append_to_statement_list (t, &expr);
2974 if (emit_false)
2976 t = build1 (LABEL_EXPR, void_type_node, false_label);
2977 append_to_statement_list (t, &expr);
2979 append_to_statement_list (else_, &expr);
2981 if (emit_end && end_label)
2983 t = build1 (LABEL_EXPR, void_type_node, end_label);
2984 append_to_statement_list (t, &expr);
2987 return expr;
2990 /* EXPR is used in a boolean context; make sure it has BOOLEAN_TYPE. */
2992 tree
2993 gimple_boolify (tree expr)
2995 tree type = TREE_TYPE (expr);
2996 location_t loc = EXPR_LOCATION (expr);
2998 if (TREE_CODE (expr) == NE_EXPR
2999 && TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR
3000 && integer_zerop (TREE_OPERAND (expr, 1)))
3002 tree call = TREE_OPERAND (expr, 0);
3003 tree fn = get_callee_fndecl (call);
3005 /* For __builtin_expect ((long) (x), y) recurse into x as well
3006 if x is truth_value_p. */
3007 if (fn
3008 && DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL
3009 && DECL_FUNCTION_CODE (fn) == BUILT_IN_EXPECT
3010 && call_expr_nargs (call) == 2)
3012 tree arg = CALL_EXPR_ARG (call, 0);
3013 if (arg)
3015 if (TREE_CODE (arg) == NOP_EXPR
3016 && TREE_TYPE (arg) == TREE_TYPE (call))
3017 arg = TREE_OPERAND (arg, 0);
3018 if (truth_value_p (TREE_CODE (arg)))
3020 arg = gimple_boolify (arg);
3021 CALL_EXPR_ARG (call, 0)
3022 = fold_convert_loc (loc, TREE_TYPE (call), arg);
3028 switch (TREE_CODE (expr))
3030 case TRUTH_AND_EXPR:
3031 case TRUTH_OR_EXPR:
3032 case TRUTH_XOR_EXPR:
3033 case TRUTH_ANDIF_EXPR:
3034 case TRUTH_ORIF_EXPR:
3035 /* Also boolify the arguments of truth exprs. */
3036 TREE_OPERAND (expr, 1) = gimple_boolify (TREE_OPERAND (expr, 1));
3037 /* FALLTHRU */
3039 case TRUTH_NOT_EXPR:
3040 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
3042 /* These expressions always produce boolean results. */
3043 if (TREE_CODE (type) != BOOLEAN_TYPE)
3044 TREE_TYPE (expr) = boolean_type_node;
3045 return expr;
3047 case ANNOTATE_EXPR:
3048 switch ((enum annot_expr_kind) TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)))
3050 case annot_expr_ivdep_kind:
3051 case annot_expr_no_vector_kind:
3052 case annot_expr_vector_kind:
3053 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
3054 if (TREE_CODE (type) != BOOLEAN_TYPE)
3055 TREE_TYPE (expr) = boolean_type_node;
3056 return expr;
3057 default:
3058 gcc_unreachable ();
3061 default:
3062 if (COMPARISON_CLASS_P (expr))
3064 /* There expressions always prduce boolean results. */
3065 if (TREE_CODE (type) != BOOLEAN_TYPE)
3066 TREE_TYPE (expr) = boolean_type_node;
3067 return expr;
3069 /* Other expressions that get here must have boolean values, but
3070 might need to be converted to the appropriate mode. */
3071 if (TREE_CODE (type) == BOOLEAN_TYPE)
3072 return expr;
3073 return fold_convert_loc (loc, boolean_type_node, expr);
3077 /* Given a conditional expression *EXPR_P without side effects, gimplify
3078 its operands. New statements are inserted to PRE_P. */
3080 static enum gimplify_status
3081 gimplify_pure_cond_expr (tree *expr_p, gimple_seq *pre_p)
3083 tree expr = *expr_p, cond;
3084 enum gimplify_status ret, tret;
3085 enum tree_code code;
3087 cond = gimple_boolify (COND_EXPR_COND (expr));
3089 /* We need to handle && and || specially, as their gimplification
3090 creates pure cond_expr, thus leading to an infinite cycle otherwise. */
3091 code = TREE_CODE (cond);
3092 if (code == TRUTH_ANDIF_EXPR)
3093 TREE_SET_CODE (cond, TRUTH_AND_EXPR);
3094 else if (code == TRUTH_ORIF_EXPR)
3095 TREE_SET_CODE (cond, TRUTH_OR_EXPR);
3096 ret = gimplify_expr (&cond, pre_p, NULL, is_gimple_condexpr, fb_rvalue);
3097 COND_EXPR_COND (*expr_p) = cond;
3099 tret = gimplify_expr (&COND_EXPR_THEN (expr), pre_p, NULL,
3100 is_gimple_val, fb_rvalue);
3101 ret = MIN (ret, tret);
3102 tret = gimplify_expr (&COND_EXPR_ELSE (expr), pre_p, NULL,
3103 is_gimple_val, fb_rvalue);
3105 return MIN (ret, tret);
3108 /* Return true if evaluating EXPR could trap.
3109 EXPR is GENERIC, while tree_could_trap_p can be called
3110 only on GIMPLE. */
3112 static bool
3113 generic_expr_could_trap_p (tree expr)
3115 unsigned i, n;
3117 if (!expr || is_gimple_val (expr))
3118 return false;
3120 if (!EXPR_P (expr) || tree_could_trap_p (expr))
3121 return true;
3123 n = TREE_OPERAND_LENGTH (expr);
3124 for (i = 0; i < n; i++)
3125 if (generic_expr_could_trap_p (TREE_OPERAND (expr, i)))
3126 return true;
3128 return false;
3131 /* Convert the conditional expression pointed to by EXPR_P '(p) ? a : b;'
3132 into
3134 if (p) if (p)
3135 t1 = a; a;
3136 else or else
3137 t1 = b; b;
3140 The second form is used when *EXPR_P is of type void.
3142 PRE_P points to the list where side effects that must happen before
3143 *EXPR_P should be stored. */
3145 static enum gimplify_status
3146 gimplify_cond_expr (tree *expr_p, gimple_seq *pre_p, fallback_t fallback)
3148 tree expr = *expr_p;
3149 tree type = TREE_TYPE (expr);
3150 location_t loc = EXPR_LOCATION (expr);
3151 tree tmp, arm1, arm2;
3152 enum gimplify_status ret;
3153 tree label_true, label_false, label_cont;
3154 bool have_then_clause_p, have_else_clause_p;
3155 gcond *cond_stmt;
3156 enum tree_code pred_code;
3157 gimple_seq seq = NULL;
3159 /* If this COND_EXPR has a value, copy the values into a temporary within
3160 the arms. */
3161 if (!VOID_TYPE_P (type))
3163 tree then_ = TREE_OPERAND (expr, 1), else_ = TREE_OPERAND (expr, 2);
3164 tree result;
3166 /* If either an rvalue is ok or we do not require an lvalue, create the
3167 temporary. But we cannot do that if the type is addressable. */
3168 if (((fallback & fb_rvalue) || !(fallback & fb_lvalue))
3169 && !TREE_ADDRESSABLE (type))
3171 if (gimplify_ctxp->allow_rhs_cond_expr
3172 /* If either branch has side effects or could trap, it can't be
3173 evaluated unconditionally. */
3174 && !TREE_SIDE_EFFECTS (then_)
3175 && !generic_expr_could_trap_p (then_)
3176 && !TREE_SIDE_EFFECTS (else_)
3177 && !generic_expr_could_trap_p (else_))
3178 return gimplify_pure_cond_expr (expr_p, pre_p);
3180 tmp = create_tmp_var (type, "iftmp");
3181 result = tmp;
3184 /* Otherwise, only create and copy references to the values. */
3185 else
3187 type = build_pointer_type (type);
3189 if (!VOID_TYPE_P (TREE_TYPE (then_)))
3190 then_ = build_fold_addr_expr_loc (loc, then_);
3192 if (!VOID_TYPE_P (TREE_TYPE (else_)))
3193 else_ = build_fold_addr_expr_loc (loc, else_);
3195 expr
3196 = build3 (COND_EXPR, type, TREE_OPERAND (expr, 0), then_, else_);
3198 tmp = create_tmp_var (type, "iftmp");
3199 result = build_simple_mem_ref_loc (loc, tmp);
3202 /* Build the new then clause, `tmp = then_;'. But don't build the
3203 assignment if the value is void; in C++ it can be if it's a throw. */
3204 if (!VOID_TYPE_P (TREE_TYPE (then_)))
3205 TREE_OPERAND (expr, 1) = build2 (MODIFY_EXPR, type, tmp, then_);
3207 /* Similarly, build the new else clause, `tmp = else_;'. */
3208 if (!VOID_TYPE_P (TREE_TYPE (else_)))
3209 TREE_OPERAND (expr, 2) = build2 (MODIFY_EXPR, type, tmp, else_);
3211 TREE_TYPE (expr) = void_type_node;
3212 recalculate_side_effects (expr);
3214 /* Move the COND_EXPR to the prequeue. */
3215 gimplify_stmt (&expr, pre_p);
3217 *expr_p = result;
3218 return GS_ALL_DONE;
3221 /* Remove any COMPOUND_EXPR so the following cases will be caught. */
3222 STRIP_TYPE_NOPS (TREE_OPERAND (expr, 0));
3223 if (TREE_CODE (TREE_OPERAND (expr, 0)) == COMPOUND_EXPR)
3224 gimplify_compound_expr (&TREE_OPERAND (expr, 0), pre_p, true);
3226 /* Make sure the condition has BOOLEAN_TYPE. */
3227 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
3229 /* Break apart && and || conditions. */
3230 if (TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ANDIF_EXPR
3231 || TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ORIF_EXPR)
3233 expr = shortcut_cond_expr (expr);
3235 if (expr != *expr_p)
3237 *expr_p = expr;
3239 /* We can't rely on gimplify_expr to re-gimplify the expanded
3240 form properly, as cleanups might cause the target labels to be
3241 wrapped in a TRY_FINALLY_EXPR. To prevent that, we need to
3242 set up a conditional context. */
3243 gimple_push_condition ();
3244 gimplify_stmt (expr_p, &seq);
3245 gimple_pop_condition (pre_p);
3246 gimple_seq_add_seq (pre_p, seq);
3248 return GS_ALL_DONE;
3252 /* Now do the normal gimplification. */
3254 /* Gimplify condition. */
3255 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL, is_gimple_condexpr,
3256 fb_rvalue);
3257 if (ret == GS_ERROR)
3258 return GS_ERROR;
3259 gcc_assert (TREE_OPERAND (expr, 0) != NULL_TREE);
3261 gimple_push_condition ();
3263 have_then_clause_p = have_else_clause_p = false;
3264 if (TREE_OPERAND (expr, 1) != NULL
3265 && TREE_CODE (TREE_OPERAND (expr, 1)) == GOTO_EXPR
3266 && TREE_CODE (GOTO_DESTINATION (TREE_OPERAND (expr, 1))) == LABEL_DECL
3267 && (DECL_CONTEXT (GOTO_DESTINATION (TREE_OPERAND (expr, 1)))
3268 == current_function_decl)
3269 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
3270 have different locations, otherwise we end up with incorrect
3271 location information on the branches. */
3272 && (optimize
3273 || !EXPR_HAS_LOCATION (expr)
3274 || !EXPR_HAS_LOCATION (TREE_OPERAND (expr, 1))
3275 || EXPR_LOCATION (expr) == EXPR_LOCATION (TREE_OPERAND (expr, 1))))
3277 label_true = GOTO_DESTINATION (TREE_OPERAND (expr, 1));
3278 have_then_clause_p = true;
3280 else
3281 label_true = create_artificial_label (UNKNOWN_LOCATION);
3282 if (TREE_OPERAND (expr, 2) != NULL
3283 && TREE_CODE (TREE_OPERAND (expr, 2)) == GOTO_EXPR
3284 && TREE_CODE (GOTO_DESTINATION (TREE_OPERAND (expr, 2))) == LABEL_DECL
3285 && (DECL_CONTEXT (GOTO_DESTINATION (TREE_OPERAND (expr, 2)))
3286 == current_function_decl)
3287 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
3288 have different locations, otherwise we end up with incorrect
3289 location information on the branches. */
3290 && (optimize
3291 || !EXPR_HAS_LOCATION (expr)
3292 || !EXPR_HAS_LOCATION (TREE_OPERAND (expr, 2))
3293 || EXPR_LOCATION (expr) == EXPR_LOCATION (TREE_OPERAND (expr, 2))))
3295 label_false = GOTO_DESTINATION (TREE_OPERAND (expr, 2));
3296 have_else_clause_p = true;
3298 else
3299 label_false = create_artificial_label (UNKNOWN_LOCATION);
3301 gimple_cond_get_ops_from_tree (COND_EXPR_COND (expr), &pred_code, &arm1,
3302 &arm2);
3303 cond_stmt = gimple_build_cond (pred_code, arm1, arm2, label_true,
3304 label_false);
3305 gimple_set_no_warning (cond_stmt, TREE_NO_WARNING (COND_EXPR_COND (expr)));
3306 gimplify_seq_add_stmt (&seq, cond_stmt);
3307 gimple_stmt_iterator gsi = gsi_last (seq);
3308 maybe_fold_stmt (&gsi);
3310 label_cont = NULL_TREE;
3311 if (!have_then_clause_p)
3313 /* For if (...) {} else { code; } put label_true after
3314 the else block. */
3315 if (TREE_OPERAND (expr, 1) == NULL_TREE
3316 && !have_else_clause_p
3317 && TREE_OPERAND (expr, 2) != NULL_TREE)
3318 label_cont = label_true;
3319 else
3321 gimplify_seq_add_stmt (&seq, gimple_build_label (label_true));
3322 have_then_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 1), &seq);
3323 /* For if (...) { code; } else {} or
3324 if (...) { code; } else goto label; or
3325 if (...) { code; return; } else { ... }
3326 label_cont isn't needed. */
3327 if (!have_else_clause_p
3328 && TREE_OPERAND (expr, 2) != NULL_TREE
3329 && gimple_seq_may_fallthru (seq))
3331 gimple *g;
3332 label_cont = create_artificial_label (UNKNOWN_LOCATION);
3334 g = gimple_build_goto (label_cont);
3336 /* GIMPLE_COND's are very low level; they have embedded
3337 gotos. This particular embedded goto should not be marked
3338 with the location of the original COND_EXPR, as it would
3339 correspond to the COND_EXPR's condition, not the ELSE or the
3340 THEN arms. To avoid marking it with the wrong location, flag
3341 it as "no location". */
3342 gimple_set_do_not_emit_location (g);
3344 gimplify_seq_add_stmt (&seq, g);
3348 if (!have_else_clause_p)
3350 gimplify_seq_add_stmt (&seq, gimple_build_label (label_false));
3351 have_else_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 2), &seq);
3353 if (label_cont)
3354 gimplify_seq_add_stmt (&seq, gimple_build_label (label_cont));
3356 gimple_pop_condition (pre_p);
3357 gimple_seq_add_seq (pre_p, seq);
3359 if (ret == GS_ERROR)
3360 ; /* Do nothing. */
3361 else if (have_then_clause_p || have_else_clause_p)
3362 ret = GS_ALL_DONE;
3363 else
3365 /* Both arms are empty; replace the COND_EXPR with its predicate. */
3366 expr = TREE_OPERAND (expr, 0);
3367 gimplify_stmt (&expr, pre_p);
3370 *expr_p = NULL;
3371 return ret;
3374 /* Prepare the node pointed to by EXPR_P, an is_gimple_addressable expression,
3375 to be marked addressable.
3377 We cannot rely on such an expression being directly markable if a temporary
3378 has been created by the gimplification. In this case, we create another
3379 temporary and initialize it with a copy, which will become a store after we
3380 mark it addressable. This can happen if the front-end passed us something
3381 that it could not mark addressable yet, like a Fortran pass-by-reference
3382 parameter (int) floatvar. */
3384 static void
3385 prepare_gimple_addressable (tree *expr_p, gimple_seq *seq_p)
3387 while (handled_component_p (*expr_p))
3388 expr_p = &TREE_OPERAND (*expr_p, 0);
3389 if (is_gimple_reg (*expr_p))
3391 /* Do not allow an SSA name as the temporary. */
3392 tree var = get_initialized_tmp_var (*expr_p, seq_p, NULL, false);
3393 DECL_GIMPLE_REG_P (var) = 0;
3394 *expr_p = var;
3398 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
3399 a call to __builtin_memcpy. */
3401 static enum gimplify_status
3402 gimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value,
3403 gimple_seq *seq_p)
3405 tree t, to, to_ptr, from, from_ptr;
3406 gcall *gs;
3407 location_t loc = EXPR_LOCATION (*expr_p);
3409 to = TREE_OPERAND (*expr_p, 0);
3410 from = TREE_OPERAND (*expr_p, 1);
3412 /* Mark the RHS addressable. Beware that it may not be possible to do so
3413 directly if a temporary has been created by the gimplification. */
3414 prepare_gimple_addressable (&from, seq_p);
3416 mark_addressable (from);
3417 from_ptr = build_fold_addr_expr_loc (loc, from);
3418 gimplify_arg (&from_ptr, seq_p, loc);
3420 mark_addressable (to);
3421 to_ptr = build_fold_addr_expr_loc (loc, to);
3422 gimplify_arg (&to_ptr, seq_p, loc);
3424 t = builtin_decl_implicit (BUILT_IN_MEMCPY);
3426 gs = gimple_build_call (t, 3, to_ptr, from_ptr, size);
3428 if (want_value)
3430 /* tmp = memcpy() */
3431 t = create_tmp_var (TREE_TYPE (to_ptr));
3432 gimple_call_set_lhs (gs, t);
3433 gimplify_seq_add_stmt (seq_p, gs);
3435 *expr_p = build_simple_mem_ref (t);
3436 return GS_ALL_DONE;
3439 gimplify_seq_add_stmt (seq_p, gs);
3440 *expr_p = NULL;
3441 return GS_ALL_DONE;
3444 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
3445 a call to __builtin_memset. In this case we know that the RHS is
3446 a CONSTRUCTOR with an empty element list. */
3448 static enum gimplify_status
3449 gimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value,
3450 gimple_seq *seq_p)
3452 tree t, from, to, to_ptr;
3453 gcall *gs;
3454 location_t loc = EXPR_LOCATION (*expr_p);
3456 /* Assert our assumptions, to abort instead of producing wrong code
3457 silently if they are not met. Beware that the RHS CONSTRUCTOR might
3458 not be immediately exposed. */
3459 from = TREE_OPERAND (*expr_p, 1);
3460 if (TREE_CODE (from) == WITH_SIZE_EXPR)
3461 from = TREE_OPERAND (from, 0);
3463 gcc_assert (TREE_CODE (from) == CONSTRUCTOR
3464 && vec_safe_is_empty (CONSTRUCTOR_ELTS (from)));
3466 /* Now proceed. */
3467 to = TREE_OPERAND (*expr_p, 0);
3469 to_ptr = build_fold_addr_expr_loc (loc, to);
3470 gimplify_arg (&to_ptr, seq_p, loc);
3471 t = builtin_decl_implicit (BUILT_IN_MEMSET);
3473 gs = gimple_build_call (t, 3, to_ptr, integer_zero_node, size);
3475 if (want_value)
3477 /* tmp = memset() */
3478 t = create_tmp_var (TREE_TYPE (to_ptr));
3479 gimple_call_set_lhs (gs, t);
3480 gimplify_seq_add_stmt (seq_p, gs);
3482 *expr_p = build1 (INDIRECT_REF, TREE_TYPE (to), t);
3483 return GS_ALL_DONE;
3486 gimplify_seq_add_stmt (seq_p, gs);
3487 *expr_p = NULL;
3488 return GS_ALL_DONE;
3491 /* A subroutine of gimplify_init_ctor_preeval. Called via walk_tree,
3492 determine, cautiously, if a CONSTRUCTOR overlaps the lhs of an
3493 assignment. Return non-null if we detect a potential overlap. */
3495 struct gimplify_init_ctor_preeval_data
3497 /* The base decl of the lhs object. May be NULL, in which case we
3498 have to assume the lhs is indirect. */
3499 tree lhs_base_decl;
3501 /* The alias set of the lhs object. */
3502 alias_set_type lhs_alias_set;
3505 static tree
3506 gimplify_init_ctor_preeval_1 (tree *tp, int *walk_subtrees, void *xdata)
3508 struct gimplify_init_ctor_preeval_data *data
3509 = (struct gimplify_init_ctor_preeval_data *) xdata;
3510 tree t = *tp;
3512 /* If we find the base object, obviously we have overlap. */
3513 if (data->lhs_base_decl == t)
3514 return t;
3516 /* If the constructor component is indirect, determine if we have a
3517 potential overlap with the lhs. The only bits of information we
3518 have to go on at this point are addressability and alias sets. */
3519 if ((INDIRECT_REF_P (t)
3520 || TREE_CODE (t) == MEM_REF)
3521 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
3522 && alias_sets_conflict_p (data->lhs_alias_set, get_alias_set (t)))
3523 return t;
3525 /* If the constructor component is a call, determine if it can hide a
3526 potential overlap with the lhs through an INDIRECT_REF like above.
3527 ??? Ugh - this is completely broken. In fact this whole analysis
3528 doesn't look conservative. */
3529 if (TREE_CODE (t) == CALL_EXPR)
3531 tree type, fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (t)));
3533 for (type = TYPE_ARG_TYPES (fntype); type; type = TREE_CHAIN (type))
3534 if (POINTER_TYPE_P (TREE_VALUE (type))
3535 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
3536 && alias_sets_conflict_p (data->lhs_alias_set,
3537 get_alias_set
3538 (TREE_TYPE (TREE_VALUE (type)))))
3539 return t;
3542 if (IS_TYPE_OR_DECL_P (t))
3543 *walk_subtrees = 0;
3544 return NULL;
3547 /* A subroutine of gimplify_init_constructor. Pre-evaluate EXPR,
3548 force values that overlap with the lhs (as described by *DATA)
3549 into temporaries. */
3551 static void
3552 gimplify_init_ctor_preeval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
3553 struct gimplify_init_ctor_preeval_data *data)
3555 enum gimplify_status one;
3557 /* If the value is constant, then there's nothing to pre-evaluate. */
3558 if (TREE_CONSTANT (*expr_p))
3560 /* Ensure it does not have side effects, it might contain a reference to
3561 the object we're initializing. */
3562 gcc_assert (!TREE_SIDE_EFFECTS (*expr_p));
3563 return;
3566 /* If the type has non-trivial constructors, we can't pre-evaluate. */
3567 if (TREE_ADDRESSABLE (TREE_TYPE (*expr_p)))
3568 return;
3570 /* Recurse for nested constructors. */
3571 if (TREE_CODE (*expr_p) == CONSTRUCTOR)
3573 unsigned HOST_WIDE_INT ix;
3574 constructor_elt *ce;
3575 vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (*expr_p);
3577 FOR_EACH_VEC_SAFE_ELT (v, ix, ce)
3578 gimplify_init_ctor_preeval (&ce->value, pre_p, post_p, data);
3580 return;
3583 /* If this is a variable sized type, we must remember the size. */
3584 maybe_with_size_expr (expr_p);
3586 /* Gimplify the constructor element to something appropriate for the rhs
3587 of a MODIFY_EXPR. Given that we know the LHS is an aggregate, we know
3588 the gimplifier will consider this a store to memory. Doing this
3589 gimplification now means that we won't have to deal with complicated
3590 language-specific trees, nor trees like SAVE_EXPR that can induce
3591 exponential search behavior. */
3592 one = gimplify_expr (expr_p, pre_p, post_p, is_gimple_mem_rhs, fb_rvalue);
3593 if (one == GS_ERROR)
3595 *expr_p = NULL;
3596 return;
3599 /* If we gimplified to a bare decl, we can be sure that it doesn't overlap
3600 with the lhs, since "a = { .x=a }" doesn't make sense. This will
3601 always be true for all scalars, since is_gimple_mem_rhs insists on a
3602 temporary variable for them. */
3603 if (DECL_P (*expr_p))
3604 return;
3606 /* If this is of variable size, we have no choice but to assume it doesn't
3607 overlap since we can't make a temporary for it. */
3608 if (TREE_CODE (TYPE_SIZE (TREE_TYPE (*expr_p))) != INTEGER_CST)
3609 return;
3611 /* Otherwise, we must search for overlap ... */
3612 if (!walk_tree (expr_p, gimplify_init_ctor_preeval_1, data, NULL))
3613 return;
3615 /* ... and if found, force the value into a temporary. */
3616 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
3619 /* A subroutine of gimplify_init_ctor_eval. Create a loop for
3620 a RANGE_EXPR in a CONSTRUCTOR for an array.
3622 var = lower;
3623 loop_entry:
3624 object[var] = value;
3625 if (var == upper)
3626 goto loop_exit;
3627 var = var + 1;
3628 goto loop_entry;
3629 loop_exit:
3631 We increment var _after_ the loop exit check because we might otherwise
3632 fail if upper == TYPE_MAX_VALUE (type for upper).
3634 Note that we never have to deal with SAVE_EXPRs here, because this has
3635 already been taken care of for us, in gimplify_init_ctor_preeval(). */
3637 static void gimplify_init_ctor_eval (tree, vec<constructor_elt, va_gc> *,
3638 gimple_seq *, bool);
3640 static void
3641 gimplify_init_ctor_eval_range (tree object, tree lower, tree upper,
3642 tree value, tree array_elt_type,
3643 gimple_seq *pre_p, bool cleared)
3645 tree loop_entry_label, loop_exit_label, fall_thru_label;
3646 tree var, var_type, cref, tmp;
3648 loop_entry_label = create_artificial_label (UNKNOWN_LOCATION);
3649 loop_exit_label = create_artificial_label (UNKNOWN_LOCATION);
3650 fall_thru_label = create_artificial_label (UNKNOWN_LOCATION);
3652 /* Create and initialize the index variable. */
3653 var_type = TREE_TYPE (upper);
3654 var = create_tmp_var (var_type);
3655 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, lower));
3657 /* Add the loop entry label. */
3658 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_entry_label));
3660 /* Build the reference. */
3661 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
3662 var, NULL_TREE, NULL_TREE);
3664 /* If we are a constructor, just call gimplify_init_ctor_eval to do
3665 the store. Otherwise just assign value to the reference. */
3667 if (TREE_CODE (value) == CONSTRUCTOR)
3668 /* NB we might have to call ourself recursively through
3669 gimplify_init_ctor_eval if the value is a constructor. */
3670 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
3671 pre_p, cleared);
3672 else
3673 gimplify_seq_add_stmt (pre_p, gimple_build_assign (cref, value));
3675 /* We exit the loop when the index var is equal to the upper bound. */
3676 gimplify_seq_add_stmt (pre_p,
3677 gimple_build_cond (EQ_EXPR, var, upper,
3678 loop_exit_label, fall_thru_label));
3680 gimplify_seq_add_stmt (pre_p, gimple_build_label (fall_thru_label));
3682 /* Otherwise, increment the index var... */
3683 tmp = build2 (PLUS_EXPR, var_type, var,
3684 fold_convert (var_type, integer_one_node));
3685 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, tmp));
3687 /* ...and jump back to the loop entry. */
3688 gimplify_seq_add_stmt (pre_p, gimple_build_goto (loop_entry_label));
3690 /* Add the loop exit label. */
3691 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_exit_label));
3694 /* Return true if FDECL is accessing a field that is zero sized. */
3696 static bool
3697 zero_sized_field_decl (const_tree fdecl)
3699 if (TREE_CODE (fdecl) == FIELD_DECL && DECL_SIZE (fdecl)
3700 && integer_zerop (DECL_SIZE (fdecl)))
3701 return true;
3702 return false;
3705 /* Return true if TYPE is zero sized. */
3707 static bool
3708 zero_sized_type (const_tree type)
3710 if (AGGREGATE_TYPE_P (type) && TYPE_SIZE (type)
3711 && integer_zerop (TYPE_SIZE (type)))
3712 return true;
3713 return false;
3716 /* A subroutine of gimplify_init_constructor. Generate individual
3717 MODIFY_EXPRs for a CONSTRUCTOR. OBJECT is the LHS against which the
3718 assignments should happen. ELTS is the CONSTRUCTOR_ELTS of the
3719 CONSTRUCTOR. CLEARED is true if the entire LHS object has been
3720 zeroed first. */
3722 static void
3723 gimplify_init_ctor_eval (tree object, vec<constructor_elt, va_gc> *elts,
3724 gimple_seq *pre_p, bool cleared)
3726 tree array_elt_type = NULL;
3727 unsigned HOST_WIDE_INT ix;
3728 tree purpose, value;
3730 if (TREE_CODE (TREE_TYPE (object)) == ARRAY_TYPE)
3731 array_elt_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (object)));
3733 FOR_EACH_CONSTRUCTOR_ELT (elts, ix, purpose, value)
3735 tree cref;
3737 /* NULL values are created above for gimplification errors. */
3738 if (value == NULL)
3739 continue;
3741 if (cleared && initializer_zerop (value))
3742 continue;
3744 /* ??? Here's to hoping the front end fills in all of the indices,
3745 so we don't have to figure out what's missing ourselves. */
3746 gcc_assert (purpose);
3748 /* Skip zero-sized fields, unless value has side-effects. This can
3749 happen with calls to functions returning a zero-sized type, which
3750 we shouldn't discard. As a number of downstream passes don't
3751 expect sets of zero-sized fields, we rely on the gimplification of
3752 the MODIFY_EXPR we make below to drop the assignment statement. */
3753 if (! TREE_SIDE_EFFECTS (value) && zero_sized_field_decl (purpose))
3754 continue;
3756 /* If we have a RANGE_EXPR, we have to build a loop to assign the
3757 whole range. */
3758 if (TREE_CODE (purpose) == RANGE_EXPR)
3760 tree lower = TREE_OPERAND (purpose, 0);
3761 tree upper = TREE_OPERAND (purpose, 1);
3763 /* If the lower bound is equal to upper, just treat it as if
3764 upper was the index. */
3765 if (simple_cst_equal (lower, upper))
3766 purpose = upper;
3767 else
3769 gimplify_init_ctor_eval_range (object, lower, upper, value,
3770 array_elt_type, pre_p, cleared);
3771 continue;
3775 if (array_elt_type)
3777 /* Do not use bitsizetype for ARRAY_REF indices. */
3778 if (TYPE_DOMAIN (TREE_TYPE (object)))
3779 purpose
3780 = fold_convert (TREE_TYPE (TYPE_DOMAIN (TREE_TYPE (object))),
3781 purpose);
3782 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
3783 purpose, NULL_TREE, NULL_TREE);
3785 else
3787 gcc_assert (TREE_CODE (purpose) == FIELD_DECL);
3788 cref = build3 (COMPONENT_REF, TREE_TYPE (purpose),
3789 unshare_expr (object), purpose, NULL_TREE);
3792 if (TREE_CODE (value) == CONSTRUCTOR
3793 && TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE)
3794 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
3795 pre_p, cleared);
3796 else
3798 tree init = build2 (INIT_EXPR, TREE_TYPE (cref), cref, value);
3799 gimplify_and_add (init, pre_p);
3800 ggc_free (init);
3805 /* Return the appropriate RHS predicate for this LHS. */
3807 gimple_predicate
3808 rhs_predicate_for (tree lhs)
3810 if (is_gimple_reg (lhs))
3811 return is_gimple_reg_rhs_or_call;
3812 else
3813 return is_gimple_mem_rhs_or_call;
3816 /* Return the initial guess for an appropriate RHS predicate for this LHS,
3817 before the LHS has been gimplified. */
3819 static gimple_predicate
3820 initial_rhs_predicate_for (tree lhs)
3822 if (is_gimple_reg_type (TREE_TYPE (lhs)))
3823 return is_gimple_reg_rhs_or_call;
3824 else
3825 return is_gimple_mem_rhs_or_call;
3828 /* Gimplify a C99 compound literal expression. This just means adding
3829 the DECL_EXPR before the current statement and using its anonymous
3830 decl instead. */
3832 static enum gimplify_status
3833 gimplify_compound_literal_expr (tree *expr_p, gimple_seq *pre_p,
3834 bool (*gimple_test_f) (tree),
3835 fallback_t fallback)
3837 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (*expr_p);
3838 tree decl = DECL_EXPR_DECL (decl_s);
3839 tree init = DECL_INITIAL (decl);
3840 /* Mark the decl as addressable if the compound literal
3841 expression is addressable now, otherwise it is marked too late
3842 after we gimplify the initialization expression. */
3843 if (TREE_ADDRESSABLE (*expr_p))
3844 TREE_ADDRESSABLE (decl) = 1;
3845 /* Otherwise, if we don't need an lvalue and have a literal directly
3846 substitute it. Check if it matches the gimple predicate, as
3847 otherwise we'd generate a new temporary, and we can as well just
3848 use the decl we already have. */
3849 else if (!TREE_ADDRESSABLE (decl)
3850 && init
3851 && (fallback & fb_lvalue) == 0
3852 && gimple_test_f (init))
3854 *expr_p = init;
3855 return GS_OK;
3858 /* Preliminarily mark non-addressed complex variables as eligible
3859 for promotion to gimple registers. We'll transform their uses
3860 as we find them. */
3861 if ((TREE_CODE (TREE_TYPE (decl)) == COMPLEX_TYPE
3862 || TREE_CODE (TREE_TYPE (decl)) == VECTOR_TYPE)
3863 && !TREE_THIS_VOLATILE (decl)
3864 && !needs_to_live_in_memory (decl))
3865 DECL_GIMPLE_REG_P (decl) = 1;
3867 /* If the decl is not addressable, then it is being used in some
3868 expression or on the right hand side of a statement, and it can
3869 be put into a readonly data section. */
3870 if (!TREE_ADDRESSABLE (decl) && (fallback & fb_lvalue) == 0)
3871 TREE_READONLY (decl) = 1;
3873 /* This decl isn't mentioned in the enclosing block, so add it to the
3874 list of temps. FIXME it seems a bit of a kludge to say that
3875 anonymous artificial vars aren't pushed, but everything else is. */
3876 if (DECL_NAME (decl) == NULL_TREE && !DECL_SEEN_IN_BIND_EXPR_P (decl))
3877 gimple_add_tmp_var (decl);
3879 gimplify_and_add (decl_s, pre_p);
3880 *expr_p = decl;
3881 return GS_OK;
3884 /* Optimize embedded COMPOUND_LITERAL_EXPRs within a CONSTRUCTOR,
3885 return a new CONSTRUCTOR if something changed. */
3887 static tree
3888 optimize_compound_literals_in_ctor (tree orig_ctor)
3890 tree ctor = orig_ctor;
3891 vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ctor);
3892 unsigned int idx, num = vec_safe_length (elts);
3894 for (idx = 0; idx < num; idx++)
3896 tree value = (*elts)[idx].value;
3897 tree newval = value;
3898 if (TREE_CODE (value) == CONSTRUCTOR)
3899 newval = optimize_compound_literals_in_ctor (value);
3900 else if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR)
3902 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (value);
3903 tree decl = DECL_EXPR_DECL (decl_s);
3904 tree init = DECL_INITIAL (decl);
3906 if (!TREE_ADDRESSABLE (value)
3907 && !TREE_ADDRESSABLE (decl)
3908 && init
3909 && TREE_CODE (init) == CONSTRUCTOR)
3910 newval = optimize_compound_literals_in_ctor (init);
3912 if (newval == value)
3913 continue;
3915 if (ctor == orig_ctor)
3917 ctor = copy_node (orig_ctor);
3918 CONSTRUCTOR_ELTS (ctor) = vec_safe_copy (elts);
3919 elts = CONSTRUCTOR_ELTS (ctor);
3921 (*elts)[idx].value = newval;
3923 return ctor;
3926 /* A subroutine of gimplify_modify_expr. Break out elements of a
3927 CONSTRUCTOR used as an initializer into separate MODIFY_EXPRs.
3929 Note that we still need to clear any elements that don't have explicit
3930 initializers, so if not all elements are initialized we keep the
3931 original MODIFY_EXPR, we just remove all of the constructor elements.
3933 If NOTIFY_TEMP_CREATION is true, do not gimplify, just return
3934 GS_ERROR if we would have to create a temporary when gimplifying
3935 this constructor. Otherwise, return GS_OK.
3937 If NOTIFY_TEMP_CREATION is false, just do the gimplification. */
3939 static enum gimplify_status
3940 gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
3941 bool want_value, bool notify_temp_creation)
3943 tree object, ctor, type;
3944 enum gimplify_status ret;
3945 vec<constructor_elt, va_gc> *elts;
3947 gcc_assert (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == CONSTRUCTOR);
3949 if (!notify_temp_creation)
3951 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
3952 is_gimple_lvalue, fb_lvalue);
3953 if (ret == GS_ERROR)
3954 return ret;
3957 object = TREE_OPERAND (*expr_p, 0);
3958 ctor = TREE_OPERAND (*expr_p, 1) =
3959 optimize_compound_literals_in_ctor (TREE_OPERAND (*expr_p, 1));
3960 type = TREE_TYPE (ctor);
3961 elts = CONSTRUCTOR_ELTS (ctor);
3962 ret = GS_ALL_DONE;
3964 switch (TREE_CODE (type))
3966 case RECORD_TYPE:
3967 case UNION_TYPE:
3968 case QUAL_UNION_TYPE:
3969 case ARRAY_TYPE:
3971 struct gimplify_init_ctor_preeval_data preeval_data;
3972 HOST_WIDE_INT num_ctor_elements, num_nonzero_elements;
3973 bool cleared, complete_p, valid_const_initializer;
3975 /* Aggregate types must lower constructors to initialization of
3976 individual elements. The exception is that a CONSTRUCTOR node
3977 with no elements indicates zero-initialization of the whole. */
3978 if (vec_safe_is_empty (elts))
3980 if (notify_temp_creation)
3981 return GS_OK;
3982 break;
3985 /* Fetch information about the constructor to direct later processing.
3986 We might want to make static versions of it in various cases, and
3987 can only do so if it known to be a valid constant initializer. */
3988 valid_const_initializer
3989 = categorize_ctor_elements (ctor, &num_nonzero_elements,
3990 &num_ctor_elements, &complete_p);
3992 /* If a const aggregate variable is being initialized, then it
3993 should never be a lose to promote the variable to be static. */
3994 if (valid_const_initializer
3995 && num_nonzero_elements > 1
3996 && TREE_READONLY (object)
3997 && TREE_CODE (object) == VAR_DECL
3998 && (flag_merge_constants >= 2 || !TREE_ADDRESSABLE (object)))
4000 if (notify_temp_creation)
4001 return GS_ERROR;
4002 DECL_INITIAL (object) = ctor;
4003 TREE_STATIC (object) = 1;
4004 if (!DECL_NAME (object))
4005 DECL_NAME (object) = create_tmp_var_name ("C");
4006 walk_tree (&DECL_INITIAL (object), force_labels_r, NULL, NULL);
4008 /* ??? C++ doesn't automatically append a .<number> to the
4009 assembler name, and even when it does, it looks at FE private
4010 data structures to figure out what that number should be,
4011 which are not set for this variable. I suppose this is
4012 important for local statics for inline functions, which aren't
4013 "local" in the object file sense. So in order to get a unique
4014 TU-local symbol, we must invoke the lhd version now. */
4015 lhd_set_decl_assembler_name (object);
4017 *expr_p = NULL_TREE;
4018 break;
4021 /* If there are "lots" of initialized elements, even discounting
4022 those that are not address constants (and thus *must* be
4023 computed at runtime), then partition the constructor into
4024 constant and non-constant parts. Block copy the constant
4025 parts in, then generate code for the non-constant parts. */
4026 /* TODO. There's code in cp/typeck.c to do this. */
4028 if (int_size_in_bytes (TREE_TYPE (ctor)) < 0)
4029 /* store_constructor will ignore the clearing of variable-sized
4030 objects. Initializers for such objects must explicitly set
4031 every field that needs to be set. */
4032 cleared = false;
4033 else if (!complete_p && !CONSTRUCTOR_NO_CLEARING (ctor))
4034 /* If the constructor isn't complete, clear the whole object
4035 beforehand, unless CONSTRUCTOR_NO_CLEARING is set on it.
4037 ??? This ought not to be needed. For any element not present
4038 in the initializer, we should simply set them to zero. Except
4039 we'd need to *find* the elements that are not present, and that
4040 requires trickery to avoid quadratic compile-time behavior in
4041 large cases or excessive memory use in small cases. */
4042 cleared = true;
4043 else if (num_ctor_elements - num_nonzero_elements
4044 > CLEAR_RATIO (optimize_function_for_speed_p (cfun))
4045 && num_nonzero_elements < num_ctor_elements / 4)
4046 /* If there are "lots" of zeros, it's more efficient to clear
4047 the memory and then set the nonzero elements. */
4048 cleared = true;
4049 else
4050 cleared = false;
4052 /* If there are "lots" of initialized elements, and all of them
4053 are valid address constants, then the entire initializer can
4054 be dropped to memory, and then memcpy'd out. Don't do this
4055 for sparse arrays, though, as it's more efficient to follow
4056 the standard CONSTRUCTOR behavior of memset followed by
4057 individual element initialization. Also don't do this for small
4058 all-zero initializers (which aren't big enough to merit
4059 clearing), and don't try to make bitwise copies of
4060 TREE_ADDRESSABLE types.
4062 We cannot apply such transformation when compiling chkp static
4063 initializer because creation of initializer image in the memory
4064 will require static initialization of bounds for it. It should
4065 result in another gimplification of similar initializer and we
4066 may fall into infinite loop. */
4067 if (valid_const_initializer
4068 && !(cleared || num_nonzero_elements == 0)
4069 && !TREE_ADDRESSABLE (type)
4070 && (!current_function_decl
4071 || !lookup_attribute ("chkp ctor",
4072 DECL_ATTRIBUTES (current_function_decl))))
4074 HOST_WIDE_INT size = int_size_in_bytes (type);
4075 unsigned int align;
4077 /* ??? We can still get unbounded array types, at least
4078 from the C++ front end. This seems wrong, but attempt
4079 to work around it for now. */
4080 if (size < 0)
4082 size = int_size_in_bytes (TREE_TYPE (object));
4083 if (size >= 0)
4084 TREE_TYPE (ctor) = type = TREE_TYPE (object);
4087 /* Find the maximum alignment we can assume for the object. */
4088 /* ??? Make use of DECL_OFFSET_ALIGN. */
4089 if (DECL_P (object))
4090 align = DECL_ALIGN (object);
4091 else
4092 align = TYPE_ALIGN (type);
4094 /* Do a block move either if the size is so small as to make
4095 each individual move a sub-unit move on average, or if it
4096 is so large as to make individual moves inefficient. */
4097 if (size > 0
4098 && num_nonzero_elements > 1
4099 && (size < num_nonzero_elements
4100 || !can_move_by_pieces (size, align)))
4102 if (notify_temp_creation)
4103 return GS_ERROR;
4105 walk_tree (&ctor, force_labels_r, NULL, NULL);
4106 ctor = tree_output_constant_def (ctor);
4107 if (!useless_type_conversion_p (type, TREE_TYPE (ctor)))
4108 ctor = build1 (VIEW_CONVERT_EXPR, type, ctor);
4109 TREE_OPERAND (*expr_p, 1) = ctor;
4111 /* This is no longer an assignment of a CONSTRUCTOR, but
4112 we still may have processing to do on the LHS. So
4113 pretend we didn't do anything here to let that happen. */
4114 return GS_UNHANDLED;
4118 /* If the target is volatile, we have non-zero elements and more than
4119 one field to assign, initialize the target from a temporary. */
4120 if (TREE_THIS_VOLATILE (object)
4121 && !TREE_ADDRESSABLE (type)
4122 && num_nonzero_elements > 0
4123 && vec_safe_length (elts) > 1)
4125 tree temp = create_tmp_var (TYPE_MAIN_VARIANT (type));
4126 TREE_OPERAND (*expr_p, 0) = temp;
4127 *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p),
4128 *expr_p,
4129 build2 (MODIFY_EXPR, void_type_node,
4130 object, temp));
4131 return GS_OK;
4134 if (notify_temp_creation)
4135 return GS_OK;
4137 /* If there are nonzero elements and if needed, pre-evaluate to capture
4138 elements overlapping with the lhs into temporaries. We must do this
4139 before clearing to fetch the values before they are zeroed-out. */
4140 if (num_nonzero_elements > 0 && TREE_CODE (*expr_p) != INIT_EXPR)
4142 preeval_data.lhs_base_decl = get_base_address (object);
4143 if (!DECL_P (preeval_data.lhs_base_decl))
4144 preeval_data.lhs_base_decl = NULL;
4145 preeval_data.lhs_alias_set = get_alias_set (object);
4147 gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p, 1),
4148 pre_p, post_p, &preeval_data);
4151 bool ctor_has_side_effects_p
4152 = TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p, 1));
4154 if (cleared)
4156 /* Zap the CONSTRUCTOR element list, which simplifies this case.
4157 Note that we still have to gimplify, in order to handle the
4158 case of variable sized types. Avoid shared tree structures. */
4159 CONSTRUCTOR_ELTS (ctor) = NULL;
4160 TREE_SIDE_EFFECTS (ctor) = 0;
4161 object = unshare_expr (object);
4162 gimplify_stmt (expr_p, pre_p);
4165 /* If we have not block cleared the object, or if there are nonzero
4166 elements in the constructor, or if the constructor has side effects,
4167 add assignments to the individual scalar fields of the object. */
4168 if (!cleared
4169 || num_nonzero_elements > 0
4170 || ctor_has_side_effects_p)
4171 gimplify_init_ctor_eval (object, elts, pre_p, cleared);
4173 *expr_p = NULL_TREE;
4175 break;
4177 case COMPLEX_TYPE:
4179 tree r, i;
4181 if (notify_temp_creation)
4182 return GS_OK;
4184 /* Extract the real and imaginary parts out of the ctor. */
4185 gcc_assert (elts->length () == 2);
4186 r = (*elts)[0].value;
4187 i = (*elts)[1].value;
4188 if (r == NULL || i == NULL)
4190 tree zero = build_zero_cst (TREE_TYPE (type));
4191 if (r == NULL)
4192 r = zero;
4193 if (i == NULL)
4194 i = zero;
4197 /* Complex types have either COMPLEX_CST or COMPLEX_EXPR to
4198 represent creation of a complex value. */
4199 if (TREE_CONSTANT (r) && TREE_CONSTANT (i))
4201 ctor = build_complex (type, r, i);
4202 TREE_OPERAND (*expr_p, 1) = ctor;
4204 else
4206 ctor = build2 (COMPLEX_EXPR, type, r, i);
4207 TREE_OPERAND (*expr_p, 1) = ctor;
4208 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 1),
4209 pre_p,
4210 post_p,
4211 rhs_predicate_for (TREE_OPERAND (*expr_p, 0)),
4212 fb_rvalue);
4215 break;
4217 case VECTOR_TYPE:
4219 unsigned HOST_WIDE_INT ix;
4220 constructor_elt *ce;
4222 if (notify_temp_creation)
4223 return GS_OK;
4225 /* Go ahead and simplify constant constructors to VECTOR_CST. */
4226 if (TREE_CONSTANT (ctor))
4228 bool constant_p = true;
4229 tree value;
4231 /* Even when ctor is constant, it might contain non-*_CST
4232 elements, such as addresses or trapping values like
4233 1.0/0.0 - 1.0/0.0. Such expressions don't belong
4234 in VECTOR_CST nodes. */
4235 FOR_EACH_CONSTRUCTOR_VALUE (elts, ix, value)
4236 if (!CONSTANT_CLASS_P (value))
4238 constant_p = false;
4239 break;
4242 if (constant_p)
4244 TREE_OPERAND (*expr_p, 1) = build_vector_from_ctor (type, elts);
4245 break;
4248 TREE_CONSTANT (ctor) = 0;
4251 /* Vector types use CONSTRUCTOR all the way through gimple
4252 compilation as a general initializer. */
4253 FOR_EACH_VEC_SAFE_ELT (elts, ix, ce)
4255 enum gimplify_status tret;
4256 tret = gimplify_expr (&ce->value, pre_p, post_p, is_gimple_val,
4257 fb_rvalue);
4258 if (tret == GS_ERROR)
4259 ret = GS_ERROR;
4260 else if (TREE_STATIC (ctor)
4261 && !initializer_constant_valid_p (ce->value,
4262 TREE_TYPE (ce->value)))
4263 TREE_STATIC (ctor) = 0;
4265 if (!is_gimple_reg (TREE_OPERAND (*expr_p, 0)))
4266 TREE_OPERAND (*expr_p, 1) = get_formal_tmp_var (ctor, pre_p);
4268 break;
4270 default:
4271 /* So how did we get a CONSTRUCTOR for a scalar type? */
4272 gcc_unreachable ();
4275 if (ret == GS_ERROR)
4276 return GS_ERROR;
4277 else if (want_value)
4279 *expr_p = object;
4280 return GS_OK;
4282 else
4284 /* If we have gimplified both sides of the initializer but have
4285 not emitted an assignment, do so now. */
4286 if (*expr_p)
4288 tree lhs = TREE_OPERAND (*expr_p, 0);
4289 tree rhs = TREE_OPERAND (*expr_p, 1);
4290 gassign *init = gimple_build_assign (lhs, rhs);
4291 gimplify_seq_add_stmt (pre_p, init);
4292 *expr_p = NULL;
4295 return GS_ALL_DONE;
4299 /* Given a pointer value OP0, return a simplified version of an
4300 indirection through OP0, or NULL_TREE if no simplification is
4301 possible. This may only be applied to a rhs of an expression.
4302 Note that the resulting type may be different from the type pointed
4303 to in the sense that it is still compatible from the langhooks
4304 point of view. */
4306 static tree
4307 gimple_fold_indirect_ref_rhs (tree t)
4309 return gimple_fold_indirect_ref (t);
4312 /* Subroutine of gimplify_modify_expr to do simplifications of
4313 MODIFY_EXPRs based on the code of the RHS. We loop for as long as
4314 something changes. */
4316 static enum gimplify_status
4317 gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p,
4318 gimple_seq *pre_p, gimple_seq *post_p,
4319 bool want_value)
4321 enum gimplify_status ret = GS_UNHANDLED;
4322 bool changed;
4326 changed = false;
4327 switch (TREE_CODE (*from_p))
4329 case VAR_DECL:
4330 /* If we're assigning from a read-only variable initialized with
4331 a constructor, do the direct assignment from the constructor,
4332 but only if neither source nor target are volatile since this
4333 latter assignment might end up being done on a per-field basis. */
4334 if (DECL_INITIAL (*from_p)
4335 && TREE_READONLY (*from_p)
4336 && !TREE_THIS_VOLATILE (*from_p)
4337 && !TREE_THIS_VOLATILE (*to_p)
4338 && TREE_CODE (DECL_INITIAL (*from_p)) == CONSTRUCTOR)
4340 tree old_from = *from_p;
4341 enum gimplify_status subret;
4343 /* Move the constructor into the RHS. */
4344 *from_p = unshare_expr (DECL_INITIAL (*from_p));
4346 /* Let's see if gimplify_init_constructor will need to put
4347 it in memory. */
4348 subret = gimplify_init_constructor (expr_p, NULL, NULL,
4349 false, true);
4350 if (subret == GS_ERROR)
4352 /* If so, revert the change. */
4353 *from_p = old_from;
4355 else
4357 ret = GS_OK;
4358 changed = true;
4361 break;
4362 case INDIRECT_REF:
4364 /* If we have code like
4366 *(const A*)(A*)&x
4368 where the type of "x" is a (possibly cv-qualified variant
4369 of "A"), treat the entire expression as identical to "x".
4370 This kind of code arises in C++ when an object is bound
4371 to a const reference, and if "x" is a TARGET_EXPR we want
4372 to take advantage of the optimization below. */
4373 bool volatile_p = TREE_THIS_VOLATILE (*from_p);
4374 tree t = gimple_fold_indirect_ref_rhs (TREE_OPERAND (*from_p, 0));
4375 if (t)
4377 if (TREE_THIS_VOLATILE (t) != volatile_p)
4379 if (DECL_P (t))
4380 t = build_simple_mem_ref_loc (EXPR_LOCATION (*from_p),
4381 build_fold_addr_expr (t));
4382 if (REFERENCE_CLASS_P (t))
4383 TREE_THIS_VOLATILE (t) = volatile_p;
4385 *from_p = t;
4386 ret = GS_OK;
4387 changed = true;
4389 break;
4392 case TARGET_EXPR:
4394 /* If we are initializing something from a TARGET_EXPR, strip the
4395 TARGET_EXPR and initialize it directly, if possible. This can't
4396 be done if the initializer is void, since that implies that the
4397 temporary is set in some non-trivial way.
4399 ??? What about code that pulls out the temp and uses it
4400 elsewhere? I think that such code never uses the TARGET_EXPR as
4401 an initializer. If I'm wrong, we'll die because the temp won't
4402 have any RTL. In that case, I guess we'll need to replace
4403 references somehow. */
4404 tree init = TARGET_EXPR_INITIAL (*from_p);
4406 if (init
4407 && !VOID_TYPE_P (TREE_TYPE (init)))
4409 *from_p = init;
4410 ret = GS_OK;
4411 changed = true;
4414 break;
4416 case COMPOUND_EXPR:
4417 /* Remove any COMPOUND_EXPR in the RHS so the following cases will be
4418 caught. */
4419 gimplify_compound_expr (from_p, pre_p, true);
4420 ret = GS_OK;
4421 changed = true;
4422 break;
4424 case CONSTRUCTOR:
4425 /* If we already made some changes, let the front end have a
4426 crack at this before we break it down. */
4427 if (ret != GS_UNHANDLED)
4428 break;
4429 /* If we're initializing from a CONSTRUCTOR, break this into
4430 individual MODIFY_EXPRs. */
4431 return gimplify_init_constructor (expr_p, pre_p, post_p, want_value,
4432 false);
4434 case COND_EXPR:
4435 /* If we're assigning to a non-register type, push the assignment
4436 down into the branches. This is mandatory for ADDRESSABLE types,
4437 since we cannot generate temporaries for such, but it saves a
4438 copy in other cases as well. */
4439 if (!is_gimple_reg_type (TREE_TYPE (*from_p)))
4441 /* This code should mirror the code in gimplify_cond_expr. */
4442 enum tree_code code = TREE_CODE (*expr_p);
4443 tree cond = *from_p;
4444 tree result = *to_p;
4446 ret = gimplify_expr (&result, pre_p, post_p,
4447 is_gimple_lvalue, fb_lvalue);
4448 if (ret != GS_ERROR)
4449 ret = GS_OK;
4451 if (TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node)
4452 TREE_OPERAND (cond, 1)
4453 = build2 (code, void_type_node, result,
4454 TREE_OPERAND (cond, 1));
4455 if (TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
4456 TREE_OPERAND (cond, 2)
4457 = build2 (code, void_type_node, unshare_expr (result),
4458 TREE_OPERAND (cond, 2));
4460 TREE_TYPE (cond) = void_type_node;
4461 recalculate_side_effects (cond);
4463 if (want_value)
4465 gimplify_and_add (cond, pre_p);
4466 *expr_p = unshare_expr (result);
4468 else
4469 *expr_p = cond;
4470 return ret;
4472 break;
4474 case CALL_EXPR:
4475 /* For calls that return in memory, give *to_p as the CALL_EXPR's
4476 return slot so that we don't generate a temporary. */
4477 if (!CALL_EXPR_RETURN_SLOT_OPT (*from_p)
4478 && aggregate_value_p (*from_p, *from_p))
4480 bool use_target;
4482 if (!(rhs_predicate_for (*to_p))(*from_p))
4483 /* If we need a temporary, *to_p isn't accurate. */
4484 use_target = false;
4485 /* It's OK to use the return slot directly unless it's an NRV. */
4486 else if (TREE_CODE (*to_p) == RESULT_DECL
4487 && DECL_NAME (*to_p) == NULL_TREE
4488 && needs_to_live_in_memory (*to_p))
4489 use_target = true;
4490 else if (is_gimple_reg_type (TREE_TYPE (*to_p))
4491 || (DECL_P (*to_p) && DECL_REGISTER (*to_p)))
4492 /* Don't force regs into memory. */
4493 use_target = false;
4494 else if (TREE_CODE (*expr_p) == INIT_EXPR)
4495 /* It's OK to use the target directly if it's being
4496 initialized. */
4497 use_target = true;
4498 else if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p)))
4499 != INTEGER_CST)
4500 /* Always use the target and thus RSO for variable-sized types.
4501 GIMPLE cannot deal with a variable-sized assignment
4502 embedded in a call statement. */
4503 use_target = true;
4504 else if (TREE_CODE (*to_p) != SSA_NAME
4505 && (!is_gimple_variable (*to_p)
4506 || needs_to_live_in_memory (*to_p)))
4507 /* Don't use the original target if it's already addressable;
4508 if its address escapes, and the called function uses the
4509 NRV optimization, a conforming program could see *to_p
4510 change before the called function returns; see c++/19317.
4511 When optimizing, the return_slot pass marks more functions
4512 as safe after we have escape info. */
4513 use_target = false;
4514 else
4515 use_target = true;
4517 if (use_target)
4519 CALL_EXPR_RETURN_SLOT_OPT (*from_p) = 1;
4520 mark_addressable (*to_p);
4523 break;
4525 case WITH_SIZE_EXPR:
4526 /* Likewise for calls that return an aggregate of non-constant size,
4527 since we would not be able to generate a temporary at all. */
4528 if (TREE_CODE (TREE_OPERAND (*from_p, 0)) == CALL_EXPR)
4530 *from_p = TREE_OPERAND (*from_p, 0);
4531 /* We don't change ret in this case because the
4532 WITH_SIZE_EXPR might have been added in
4533 gimplify_modify_expr, so returning GS_OK would lead to an
4534 infinite loop. */
4535 changed = true;
4537 break;
4539 /* If we're initializing from a container, push the initialization
4540 inside it. */
4541 case CLEANUP_POINT_EXPR:
4542 case BIND_EXPR:
4543 case STATEMENT_LIST:
4545 tree wrap = *from_p;
4546 tree t;
4548 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_min_lval,
4549 fb_lvalue);
4550 if (ret != GS_ERROR)
4551 ret = GS_OK;
4553 t = voidify_wrapper_expr (wrap, *expr_p);
4554 gcc_assert (t == *expr_p);
4556 if (want_value)
4558 gimplify_and_add (wrap, pre_p);
4559 *expr_p = unshare_expr (*to_p);
4561 else
4562 *expr_p = wrap;
4563 return GS_OK;
4566 case COMPOUND_LITERAL_EXPR:
4568 tree complit = TREE_OPERAND (*expr_p, 1);
4569 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (complit);
4570 tree decl = DECL_EXPR_DECL (decl_s);
4571 tree init = DECL_INITIAL (decl);
4573 /* struct T x = (struct T) { 0, 1, 2 } can be optimized
4574 into struct T x = { 0, 1, 2 } if the address of the
4575 compound literal has never been taken. */
4576 if (!TREE_ADDRESSABLE (complit)
4577 && !TREE_ADDRESSABLE (decl)
4578 && init)
4580 *expr_p = copy_node (*expr_p);
4581 TREE_OPERAND (*expr_p, 1) = init;
4582 return GS_OK;
4586 default:
4587 break;
4590 while (changed);
4592 return ret;
4596 /* Return true if T looks like a valid GIMPLE statement. */
4598 static bool
4599 is_gimple_stmt (tree t)
4601 const enum tree_code code = TREE_CODE (t);
4603 switch (code)
4605 case NOP_EXPR:
4606 /* The only valid NOP_EXPR is the empty statement. */
4607 return IS_EMPTY_STMT (t);
4609 case BIND_EXPR:
4610 case COND_EXPR:
4611 /* These are only valid if they're void. */
4612 return TREE_TYPE (t) == NULL || VOID_TYPE_P (TREE_TYPE (t));
4614 case SWITCH_EXPR:
4615 case GOTO_EXPR:
4616 case RETURN_EXPR:
4617 case LABEL_EXPR:
4618 case CASE_LABEL_EXPR:
4619 case TRY_CATCH_EXPR:
4620 case TRY_FINALLY_EXPR:
4621 case EH_FILTER_EXPR:
4622 case CATCH_EXPR:
4623 case ASM_EXPR:
4624 case STATEMENT_LIST:
4625 case OACC_PARALLEL:
4626 case OACC_KERNELS:
4627 case OACC_DATA:
4628 case OACC_HOST_DATA:
4629 case OACC_DECLARE:
4630 case OACC_UPDATE:
4631 case OACC_ENTER_DATA:
4632 case OACC_EXIT_DATA:
4633 case OACC_CACHE:
4634 case OMP_PARALLEL:
4635 case OMP_FOR:
4636 case OMP_SIMD:
4637 case CILK_SIMD:
4638 case OMP_DISTRIBUTE:
4639 case OACC_LOOP:
4640 case OMP_SECTIONS:
4641 case OMP_SECTION:
4642 case OMP_SINGLE:
4643 case OMP_MASTER:
4644 case OMP_TASKGROUP:
4645 case OMP_ORDERED:
4646 case OMP_CRITICAL:
4647 case OMP_TASK:
4648 case OMP_TARGET:
4649 case OMP_TARGET_DATA:
4650 case OMP_TARGET_UPDATE:
4651 case OMP_TARGET_ENTER_DATA:
4652 case OMP_TARGET_EXIT_DATA:
4653 case OMP_TASKLOOP:
4654 case OMP_TEAMS:
4655 /* These are always void. */
4656 return true;
4658 case CALL_EXPR:
4659 case MODIFY_EXPR:
4660 case PREDICT_EXPR:
4661 /* These are valid regardless of their type. */
4662 return true;
4664 default:
4665 return false;
4670 /* Promote partial stores to COMPLEX variables to total stores. *EXPR_P is
4671 a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a variable with
4672 DECL_GIMPLE_REG_P set.
4674 IMPORTANT NOTE: This promotion is performed by introducing a load of the
4675 other, unmodified part of the complex object just before the total store.
4676 As a consequence, if the object is still uninitialized, an undefined value
4677 will be loaded into a register, which may result in a spurious exception
4678 if the register is floating-point and the value happens to be a signaling
4679 NaN for example. Then the fully-fledged complex operations lowering pass
4680 followed by a DCE pass are necessary in order to fix things up. */
4682 static enum gimplify_status
4683 gimplify_modify_expr_complex_part (tree *expr_p, gimple_seq *pre_p,
4684 bool want_value)
4686 enum tree_code code, ocode;
4687 tree lhs, rhs, new_rhs, other, realpart, imagpart;
4689 lhs = TREE_OPERAND (*expr_p, 0);
4690 rhs = TREE_OPERAND (*expr_p, 1);
4691 code = TREE_CODE (lhs);
4692 lhs = TREE_OPERAND (lhs, 0);
4694 ocode = code == REALPART_EXPR ? IMAGPART_EXPR : REALPART_EXPR;
4695 other = build1 (ocode, TREE_TYPE (rhs), lhs);
4696 TREE_NO_WARNING (other) = 1;
4697 other = get_formal_tmp_var (other, pre_p);
4699 realpart = code == REALPART_EXPR ? rhs : other;
4700 imagpart = code == REALPART_EXPR ? other : rhs;
4702 if (TREE_CONSTANT (realpart) && TREE_CONSTANT (imagpart))
4703 new_rhs = build_complex (TREE_TYPE (lhs), realpart, imagpart);
4704 else
4705 new_rhs = build2 (COMPLEX_EXPR, TREE_TYPE (lhs), realpart, imagpart);
4707 gimplify_seq_add_stmt (pre_p, gimple_build_assign (lhs, new_rhs));
4708 *expr_p = (want_value) ? rhs : NULL_TREE;
4710 return GS_ALL_DONE;
4713 /* Gimplify the MODIFY_EXPR node pointed to by EXPR_P.
4715 modify_expr
4716 : varname '=' rhs
4717 | '*' ID '=' rhs
4719 PRE_P points to the list where side effects that must happen before
4720 *EXPR_P should be stored.
4722 POST_P points to the list where side effects that must happen after
4723 *EXPR_P should be stored.
4725 WANT_VALUE is nonzero iff we want to use the value of this expression
4726 in another expression. */
4728 static enum gimplify_status
4729 gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
4730 bool want_value)
4732 tree *from_p = &TREE_OPERAND (*expr_p, 1);
4733 tree *to_p = &TREE_OPERAND (*expr_p, 0);
4734 enum gimplify_status ret = GS_UNHANDLED;
4735 gimple *assign;
4736 location_t loc = EXPR_LOCATION (*expr_p);
4737 gimple_stmt_iterator gsi;
4739 gcc_assert (TREE_CODE (*expr_p) == MODIFY_EXPR
4740 || TREE_CODE (*expr_p) == INIT_EXPR);
4742 /* Trying to simplify a clobber using normal logic doesn't work,
4743 so handle it here. */
4744 if (TREE_CLOBBER_P (*from_p))
4746 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
4747 if (ret == GS_ERROR)
4748 return ret;
4749 gcc_assert (!want_value
4750 && (TREE_CODE (*to_p) == VAR_DECL
4751 || TREE_CODE (*to_p) == MEM_REF));
4752 gimplify_seq_add_stmt (pre_p, gimple_build_assign (*to_p, *from_p));
4753 *expr_p = NULL;
4754 return GS_ALL_DONE;
4757 /* Insert pointer conversions required by the middle-end that are not
4758 required by the frontend. This fixes middle-end type checking for
4759 for example gcc.dg/redecl-6.c. */
4760 if (POINTER_TYPE_P (TREE_TYPE (*to_p)))
4762 STRIP_USELESS_TYPE_CONVERSION (*from_p);
4763 if (!useless_type_conversion_p (TREE_TYPE (*to_p), TREE_TYPE (*from_p)))
4764 *from_p = fold_convert_loc (loc, TREE_TYPE (*to_p), *from_p);
4767 /* See if any simplifications can be done based on what the RHS is. */
4768 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
4769 want_value);
4770 if (ret != GS_UNHANDLED)
4771 return ret;
4773 /* For zero sized types only gimplify the left hand side and right hand
4774 side as statements and throw away the assignment. Do this after
4775 gimplify_modify_expr_rhs so we handle TARGET_EXPRs of addressable
4776 types properly. */
4777 if (zero_sized_type (TREE_TYPE (*from_p)) && !want_value)
4779 gimplify_stmt (from_p, pre_p);
4780 gimplify_stmt (to_p, pre_p);
4781 *expr_p = NULL_TREE;
4782 return GS_ALL_DONE;
4785 /* If the value being copied is of variable width, compute the length
4786 of the copy into a WITH_SIZE_EXPR. Note that we need to do this
4787 before gimplifying any of the operands so that we can resolve any
4788 PLACEHOLDER_EXPRs in the size. Also note that the RTL expander uses
4789 the size of the expression to be copied, not of the destination, so
4790 that is what we must do here. */
4791 maybe_with_size_expr (from_p);
4793 /* As a special case, we have to temporarily allow for assignments
4794 with a CALL_EXPR on the RHS. Since in GIMPLE a function call is
4795 a toplevel statement, when gimplifying the GENERIC expression
4796 MODIFY_EXPR <a, CALL_EXPR <foo>>, we cannot create the tuple
4797 GIMPLE_ASSIGN <a, GIMPLE_CALL <foo>>.
4799 Instead, we need to create the tuple GIMPLE_CALL <a, foo>. To
4800 prevent gimplify_expr from trying to create a new temporary for
4801 foo's LHS, we tell it that it should only gimplify until it
4802 reaches the CALL_EXPR. On return from gimplify_expr, the newly
4803 created GIMPLE_CALL <foo> will be the last statement in *PRE_P
4804 and all we need to do here is set 'a' to be its LHS. */
4806 /* Gimplify the RHS first for C++17 and bug 71104. */
4807 gimple_predicate initial_pred = initial_rhs_predicate_for (*to_p);
4808 ret = gimplify_expr (from_p, pre_p, post_p, initial_pred, fb_rvalue);
4809 if (ret == GS_ERROR)
4810 return ret;
4812 /* Then gimplify the LHS. */
4813 /* If we gimplified the RHS to a CALL_EXPR and that call may return
4814 twice we have to make sure to gimplify into non-SSA as otherwise
4815 the abnormal edge added later will make those defs not dominate
4816 their uses.
4817 ??? Technically this applies only to the registers used in the
4818 resulting non-register *TO_P. */
4819 bool saved_into_ssa = gimplify_ctxp->into_ssa;
4820 if (saved_into_ssa
4821 && TREE_CODE (*from_p) == CALL_EXPR
4822 && call_expr_flags (*from_p) & ECF_RETURNS_TWICE)
4823 gimplify_ctxp->into_ssa = false;
4824 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
4825 gimplify_ctxp->into_ssa = saved_into_ssa;
4826 if (ret == GS_ERROR)
4827 return ret;
4829 /* Now that the LHS is gimplified, re-gimplify the RHS if our initial
4830 guess for the predicate was wrong. */
4831 gimple_predicate final_pred = rhs_predicate_for (*to_p);
4832 if (final_pred != initial_pred)
4834 ret = gimplify_expr (from_p, pre_p, post_p, final_pred, fb_rvalue);
4835 if (ret == GS_ERROR)
4836 return ret;
4839 /* In case of va_arg internal fn wrappped in a WITH_SIZE_EXPR, add the type
4840 size as argument to the call. */
4841 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
4843 tree call = TREE_OPERAND (*from_p, 0);
4844 tree vlasize = TREE_OPERAND (*from_p, 1);
4846 if (TREE_CODE (call) == CALL_EXPR
4847 && CALL_EXPR_IFN (call) == IFN_VA_ARG)
4849 int nargs = call_expr_nargs (call);
4850 tree type = TREE_TYPE (call);
4851 tree ap = CALL_EXPR_ARG (call, 0);
4852 tree tag = CALL_EXPR_ARG (call, 1);
4853 tree aptag = CALL_EXPR_ARG (call, 2);
4854 tree newcall = build_call_expr_internal_loc (EXPR_LOCATION (call),
4855 IFN_VA_ARG, type,
4856 nargs + 1, ap, tag,
4857 aptag, vlasize);
4858 TREE_OPERAND (*from_p, 0) = newcall;
4862 /* Now see if the above changed *from_p to something we handle specially. */
4863 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
4864 want_value);
4865 if (ret != GS_UNHANDLED)
4866 return ret;
4868 /* If we've got a variable sized assignment between two lvalues (i.e. does
4869 not involve a call), then we can make things a bit more straightforward
4870 by converting the assignment to memcpy or memset. */
4871 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
4873 tree from = TREE_OPERAND (*from_p, 0);
4874 tree size = TREE_OPERAND (*from_p, 1);
4876 if (TREE_CODE (from) == CONSTRUCTOR)
4877 return gimplify_modify_expr_to_memset (expr_p, size, want_value, pre_p);
4879 if (is_gimple_addressable (from))
4881 *from_p = from;
4882 return gimplify_modify_expr_to_memcpy (expr_p, size, want_value,
4883 pre_p);
4887 /* Transform partial stores to non-addressable complex variables into
4888 total stores. This allows us to use real instead of virtual operands
4889 for these variables, which improves optimization. */
4890 if ((TREE_CODE (*to_p) == REALPART_EXPR
4891 || TREE_CODE (*to_p) == IMAGPART_EXPR)
4892 && is_gimple_reg (TREE_OPERAND (*to_p, 0)))
4893 return gimplify_modify_expr_complex_part (expr_p, pre_p, want_value);
4895 /* Try to alleviate the effects of the gimplification creating artificial
4896 temporaries (see for example is_gimple_reg_rhs) on the debug info, but
4897 make sure not to create DECL_DEBUG_EXPR links across functions. */
4898 if (!gimplify_ctxp->into_ssa
4899 && TREE_CODE (*from_p) == VAR_DECL
4900 && DECL_IGNORED_P (*from_p)
4901 && DECL_P (*to_p)
4902 && !DECL_IGNORED_P (*to_p)
4903 && decl_function_context (*to_p) == current_function_decl)
4905 if (!DECL_NAME (*from_p) && DECL_NAME (*to_p))
4906 DECL_NAME (*from_p)
4907 = create_tmp_var_name (IDENTIFIER_POINTER (DECL_NAME (*to_p)));
4908 DECL_HAS_DEBUG_EXPR_P (*from_p) = 1;
4909 SET_DECL_DEBUG_EXPR (*from_p, *to_p);
4912 if (want_value && TREE_THIS_VOLATILE (*to_p))
4913 *from_p = get_initialized_tmp_var (*from_p, pre_p, post_p);
4915 if (TREE_CODE (*from_p) == CALL_EXPR)
4917 /* Since the RHS is a CALL_EXPR, we need to create a GIMPLE_CALL
4918 instead of a GIMPLE_ASSIGN. */
4919 gcall *call_stmt;
4920 if (CALL_EXPR_FN (*from_p) == NULL_TREE)
4922 /* Gimplify internal functions created in the FEs. */
4923 int nargs = call_expr_nargs (*from_p), i;
4924 enum internal_fn ifn = CALL_EXPR_IFN (*from_p);
4925 auto_vec<tree> vargs (nargs);
4927 for (i = 0; i < nargs; i++)
4929 gimplify_arg (&CALL_EXPR_ARG (*from_p, i), pre_p,
4930 EXPR_LOCATION (*from_p));
4931 vargs.quick_push (CALL_EXPR_ARG (*from_p, i));
4933 call_stmt = gimple_build_call_internal_vec (ifn, vargs);
4934 gimple_set_location (call_stmt, EXPR_LOCATION (*expr_p));
4936 else
4938 tree fnptrtype = TREE_TYPE (CALL_EXPR_FN (*from_p));
4939 CALL_EXPR_FN (*from_p) = TREE_OPERAND (CALL_EXPR_FN (*from_p), 0);
4940 STRIP_USELESS_TYPE_CONVERSION (CALL_EXPR_FN (*from_p));
4941 tree fndecl = get_callee_fndecl (*from_p);
4942 if (fndecl
4943 && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
4944 && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT
4945 && call_expr_nargs (*from_p) == 3)
4946 call_stmt = gimple_build_call_internal (IFN_BUILTIN_EXPECT, 3,
4947 CALL_EXPR_ARG (*from_p, 0),
4948 CALL_EXPR_ARG (*from_p, 1),
4949 CALL_EXPR_ARG (*from_p, 2));
4950 else
4952 call_stmt = gimple_build_call_from_tree (*from_p);
4953 gimple_call_set_fntype (call_stmt, TREE_TYPE (fnptrtype));
4956 notice_special_calls (call_stmt);
4957 if (!gimple_call_noreturn_p (call_stmt) || !should_remove_lhs_p (*to_p))
4958 gimple_call_set_lhs (call_stmt, *to_p);
4959 else if (TREE_CODE (*to_p) == SSA_NAME)
4960 /* The above is somewhat premature, avoid ICEing later for a
4961 SSA name w/o a definition. We may have uses in the GIMPLE IL.
4962 ??? This doesn't make it a default-def. */
4963 SSA_NAME_DEF_STMT (*to_p) = gimple_build_nop ();
4964 assign = call_stmt;
4966 else
4968 assign = gimple_build_assign (*to_p, *from_p);
4969 gimple_set_location (assign, EXPR_LOCATION (*expr_p));
4970 if (COMPARISON_CLASS_P (*from_p))
4971 gimple_set_no_warning (assign, TREE_NO_WARNING (*from_p));
4974 if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p))
4976 /* We should have got an SSA name from the start. */
4977 gcc_assert (TREE_CODE (*to_p) == SSA_NAME
4978 || ! gimple_in_ssa_p (cfun));
4981 gimplify_seq_add_stmt (pre_p, assign);
4982 gsi = gsi_last (*pre_p);
4983 maybe_fold_stmt (&gsi);
4985 if (want_value)
4987 *expr_p = TREE_THIS_VOLATILE (*to_p) ? *from_p : unshare_expr (*to_p);
4988 return GS_OK;
4990 else
4991 *expr_p = NULL;
4993 return GS_ALL_DONE;
4996 /* Gimplify a comparison between two variable-sized objects. Do this
4997 with a call to BUILT_IN_MEMCMP. */
4999 static enum gimplify_status
5000 gimplify_variable_sized_compare (tree *expr_p)
5002 location_t loc = EXPR_LOCATION (*expr_p);
5003 tree op0 = TREE_OPERAND (*expr_p, 0);
5004 tree op1 = TREE_OPERAND (*expr_p, 1);
5005 tree t, arg, dest, src, expr;
5007 arg = TYPE_SIZE_UNIT (TREE_TYPE (op0));
5008 arg = unshare_expr (arg);
5009 arg = SUBSTITUTE_PLACEHOLDER_IN_EXPR (arg, op0);
5010 src = build_fold_addr_expr_loc (loc, op1);
5011 dest = build_fold_addr_expr_loc (loc, op0);
5012 t = builtin_decl_implicit (BUILT_IN_MEMCMP);
5013 t = build_call_expr_loc (loc, t, 3, dest, src, arg);
5015 expr
5016 = build2 (TREE_CODE (*expr_p), TREE_TYPE (*expr_p), t, integer_zero_node);
5017 SET_EXPR_LOCATION (expr, loc);
5018 *expr_p = expr;
5020 return GS_OK;
5023 /* Gimplify a comparison between two aggregate objects of integral scalar
5024 mode as a comparison between the bitwise equivalent scalar values. */
5026 static enum gimplify_status
5027 gimplify_scalar_mode_aggregate_compare (tree *expr_p)
5029 location_t loc = EXPR_LOCATION (*expr_p);
5030 tree op0 = TREE_OPERAND (*expr_p, 0);
5031 tree op1 = TREE_OPERAND (*expr_p, 1);
5033 tree type = TREE_TYPE (op0);
5034 tree scalar_type = lang_hooks.types.type_for_mode (TYPE_MODE (type), 1);
5036 op0 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op0);
5037 op1 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op1);
5039 *expr_p
5040 = fold_build2_loc (loc, TREE_CODE (*expr_p), TREE_TYPE (*expr_p), op0, op1);
5042 return GS_OK;
5045 /* Gimplify an expression sequence. This function gimplifies each
5046 expression and rewrites the original expression with the last
5047 expression of the sequence in GIMPLE form.
5049 PRE_P points to the list where the side effects for all the
5050 expressions in the sequence will be emitted.
5052 WANT_VALUE is true when the result of the last COMPOUND_EXPR is used. */
5054 static enum gimplify_status
5055 gimplify_compound_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
5057 tree t = *expr_p;
5061 tree *sub_p = &TREE_OPERAND (t, 0);
5063 if (TREE_CODE (*sub_p) == COMPOUND_EXPR)
5064 gimplify_compound_expr (sub_p, pre_p, false);
5065 else
5066 gimplify_stmt (sub_p, pre_p);
5068 t = TREE_OPERAND (t, 1);
5070 while (TREE_CODE (t) == COMPOUND_EXPR);
5072 *expr_p = t;
5073 if (want_value)
5074 return GS_OK;
5075 else
5077 gimplify_stmt (expr_p, pre_p);
5078 return GS_ALL_DONE;
5082 /* Gimplify a SAVE_EXPR node. EXPR_P points to the expression to
5083 gimplify. After gimplification, EXPR_P will point to a new temporary
5084 that holds the original value of the SAVE_EXPR node.
5086 PRE_P points to the list where side effects that must happen before
5087 *EXPR_P should be stored. */
5089 static enum gimplify_status
5090 gimplify_save_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
5092 enum gimplify_status ret = GS_ALL_DONE;
5093 tree val;
5095 gcc_assert (TREE_CODE (*expr_p) == SAVE_EXPR);
5096 val = TREE_OPERAND (*expr_p, 0);
5098 /* If the SAVE_EXPR has not been resolved, then evaluate it once. */
5099 if (!SAVE_EXPR_RESOLVED_P (*expr_p))
5101 /* The operand may be a void-valued expression such as SAVE_EXPRs
5102 generated by the Java frontend for class initialization. It is
5103 being executed only for its side-effects. */
5104 if (TREE_TYPE (val) == void_type_node)
5106 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
5107 is_gimple_stmt, fb_none);
5108 val = NULL;
5110 else
5111 /* The temporary may not be an SSA name as later abnormal and EH
5112 control flow may invalidate use/def domination. */
5113 val = get_initialized_tmp_var (val, pre_p, post_p, false);
5115 TREE_OPERAND (*expr_p, 0) = val;
5116 SAVE_EXPR_RESOLVED_P (*expr_p) = 1;
5119 *expr_p = val;
5121 return ret;
5124 /* Rewrite the ADDR_EXPR node pointed to by EXPR_P
5126 unary_expr
5127 : ...
5128 | '&' varname
5131 PRE_P points to the list where side effects that must happen before
5132 *EXPR_P should be stored.
5134 POST_P points to the list where side effects that must happen after
5135 *EXPR_P should be stored. */
5137 static enum gimplify_status
5138 gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
5140 tree expr = *expr_p;
5141 tree op0 = TREE_OPERAND (expr, 0);
5142 enum gimplify_status ret;
5143 location_t loc = EXPR_LOCATION (*expr_p);
5145 switch (TREE_CODE (op0))
5147 case INDIRECT_REF:
5148 do_indirect_ref:
5149 /* Check if we are dealing with an expression of the form '&*ptr'.
5150 While the front end folds away '&*ptr' into 'ptr', these
5151 expressions may be generated internally by the compiler (e.g.,
5152 builtins like __builtin_va_end). */
5153 /* Caution: the silent array decomposition semantics we allow for
5154 ADDR_EXPR means we can't always discard the pair. */
5155 /* Gimplification of the ADDR_EXPR operand may drop
5156 cv-qualification conversions, so make sure we add them if
5157 needed. */
5159 tree op00 = TREE_OPERAND (op0, 0);
5160 tree t_expr = TREE_TYPE (expr);
5161 tree t_op00 = TREE_TYPE (op00);
5163 if (!useless_type_conversion_p (t_expr, t_op00))
5164 op00 = fold_convert_loc (loc, TREE_TYPE (expr), op00);
5165 *expr_p = op00;
5166 ret = GS_OK;
5168 break;
5170 case VIEW_CONVERT_EXPR:
5171 /* Take the address of our operand and then convert it to the type of
5172 this ADDR_EXPR.
5174 ??? The interactions of VIEW_CONVERT_EXPR and aliasing is not at
5175 all clear. The impact of this transformation is even less clear. */
5177 /* If the operand is a useless conversion, look through it. Doing so
5178 guarantees that the ADDR_EXPR and its operand will remain of the
5179 same type. */
5180 if (tree_ssa_useless_type_conversion (TREE_OPERAND (op0, 0)))
5181 op0 = TREE_OPERAND (op0, 0);
5183 *expr_p = fold_convert_loc (loc, TREE_TYPE (expr),
5184 build_fold_addr_expr_loc (loc,
5185 TREE_OPERAND (op0, 0)));
5186 ret = GS_OK;
5187 break;
5189 case MEM_REF:
5190 if (integer_zerop (TREE_OPERAND (op0, 1)))
5191 goto do_indirect_ref;
5193 /* fall through */
5195 default:
5196 /* If we see a call to a declared builtin or see its address
5197 being taken (we can unify those cases here) then we can mark
5198 the builtin for implicit generation by GCC. */
5199 if (TREE_CODE (op0) == FUNCTION_DECL
5200 && DECL_BUILT_IN_CLASS (op0) == BUILT_IN_NORMAL
5201 && builtin_decl_declared_p (DECL_FUNCTION_CODE (op0)))
5202 set_builtin_decl_implicit_p (DECL_FUNCTION_CODE (op0), true);
5204 /* We use fb_either here because the C frontend sometimes takes
5205 the address of a call that returns a struct; see
5206 gcc.dg/c99-array-lval-1.c. The gimplifier will correctly make
5207 the implied temporary explicit. */
5209 /* Make the operand addressable. */
5210 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, post_p,
5211 is_gimple_addressable, fb_either);
5212 if (ret == GS_ERROR)
5213 break;
5215 /* Then mark it. Beware that it may not be possible to do so directly
5216 if a temporary has been created by the gimplification. */
5217 prepare_gimple_addressable (&TREE_OPERAND (expr, 0), pre_p);
5219 op0 = TREE_OPERAND (expr, 0);
5221 /* For various reasons, the gimplification of the expression
5222 may have made a new INDIRECT_REF. */
5223 if (TREE_CODE (op0) == INDIRECT_REF)
5224 goto do_indirect_ref;
5226 mark_addressable (TREE_OPERAND (expr, 0));
5228 /* The FEs may end up building ADDR_EXPRs early on a decl with
5229 an incomplete type. Re-build ADDR_EXPRs in canonical form
5230 here. */
5231 if (!types_compatible_p (TREE_TYPE (op0), TREE_TYPE (TREE_TYPE (expr))))
5232 *expr_p = build_fold_addr_expr (op0);
5234 /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly. */
5235 recompute_tree_invariant_for_addr_expr (*expr_p);
5237 /* If we re-built the ADDR_EXPR add a conversion to the original type
5238 if required. */
5239 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
5240 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
5242 break;
5245 return ret;
5248 /* Gimplify the operands of an ASM_EXPR. Input operands should be a gimple
5249 value; output operands should be a gimple lvalue. */
5251 static enum gimplify_status
5252 gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
5254 tree expr;
5255 int noutputs;
5256 const char **oconstraints;
5257 int i;
5258 tree link;
5259 const char *constraint;
5260 bool allows_mem, allows_reg, is_inout;
5261 enum gimplify_status ret, tret;
5262 gasm *stmt;
5263 vec<tree, va_gc> *inputs;
5264 vec<tree, va_gc> *outputs;
5265 vec<tree, va_gc> *clobbers;
5266 vec<tree, va_gc> *labels;
5267 tree link_next;
5269 expr = *expr_p;
5270 noutputs = list_length (ASM_OUTPUTS (expr));
5271 oconstraints = (const char **) alloca ((noutputs) * sizeof (const char *));
5273 inputs = NULL;
5274 outputs = NULL;
5275 clobbers = NULL;
5276 labels = NULL;
5278 ret = GS_ALL_DONE;
5279 link_next = NULL_TREE;
5280 for (i = 0, link = ASM_OUTPUTS (expr); link; ++i, link = link_next)
5282 bool ok;
5283 size_t constraint_len;
5285 link_next = TREE_CHAIN (link);
5287 oconstraints[i]
5288 = constraint
5289 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
5290 constraint_len = strlen (constraint);
5291 if (constraint_len == 0)
5292 continue;
5294 ok = parse_output_constraint (&constraint, i, 0, 0,
5295 &allows_mem, &allows_reg, &is_inout);
5296 if (!ok)
5298 ret = GS_ERROR;
5299 is_inout = false;
5302 if (!allows_reg && allows_mem)
5303 mark_addressable (TREE_VALUE (link));
5305 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
5306 is_inout ? is_gimple_min_lval : is_gimple_lvalue,
5307 fb_lvalue | fb_mayfail);
5308 if (tret == GS_ERROR)
5310 error ("invalid lvalue in asm output %d", i);
5311 ret = tret;
5314 /* If the constraint does not allow memory make sure we gimplify
5315 it to a register if it is not already but its base is. This
5316 happens for complex and vector components. */
5317 if (!allows_mem)
5319 tree op = TREE_VALUE (link);
5320 if (! is_gimple_val (op)
5321 && is_gimple_reg_type (TREE_TYPE (op))
5322 && is_gimple_reg (get_base_address (op)))
5324 tree tem = create_tmp_reg (TREE_TYPE (op));
5325 tree ass;
5326 if (is_inout)
5328 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem),
5329 tem, unshare_expr (op));
5330 gimplify_and_add (ass, pre_p);
5332 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem), op, tem);
5333 gimplify_and_add (ass, post_p);
5335 TREE_VALUE (link) = tem;
5336 tret = GS_OK;
5340 vec_safe_push (outputs, link);
5341 TREE_CHAIN (link) = NULL_TREE;
5343 if (is_inout)
5345 /* An input/output operand. To give the optimizers more
5346 flexibility, split it into separate input and output
5347 operands. */
5348 tree input;
5349 char buf[10];
5351 /* Turn the in/out constraint into an output constraint. */
5352 char *p = xstrdup (constraint);
5353 p[0] = '=';
5354 TREE_VALUE (TREE_PURPOSE (link)) = build_string (constraint_len, p);
5356 /* And add a matching input constraint. */
5357 if (allows_reg)
5359 sprintf (buf, "%d", i);
5361 /* If there are multiple alternatives in the constraint,
5362 handle each of them individually. Those that allow register
5363 will be replaced with operand number, the others will stay
5364 unchanged. */
5365 if (strchr (p, ',') != NULL)
5367 size_t len = 0, buflen = strlen (buf);
5368 char *beg, *end, *str, *dst;
5370 for (beg = p + 1;;)
5372 end = strchr (beg, ',');
5373 if (end == NULL)
5374 end = strchr (beg, '\0');
5375 if ((size_t) (end - beg) < buflen)
5376 len += buflen + 1;
5377 else
5378 len += end - beg + 1;
5379 if (*end)
5380 beg = end + 1;
5381 else
5382 break;
5385 str = (char *) alloca (len);
5386 for (beg = p + 1, dst = str;;)
5388 const char *tem;
5389 bool mem_p, reg_p, inout_p;
5391 end = strchr (beg, ',');
5392 if (end)
5393 *end = '\0';
5394 beg[-1] = '=';
5395 tem = beg - 1;
5396 parse_output_constraint (&tem, i, 0, 0,
5397 &mem_p, &reg_p, &inout_p);
5398 if (dst != str)
5399 *dst++ = ',';
5400 if (reg_p)
5402 memcpy (dst, buf, buflen);
5403 dst += buflen;
5405 else
5407 if (end)
5408 len = end - beg;
5409 else
5410 len = strlen (beg);
5411 memcpy (dst, beg, len);
5412 dst += len;
5414 if (end)
5415 beg = end + 1;
5416 else
5417 break;
5419 *dst = '\0';
5420 input = build_string (dst - str, str);
5422 else
5423 input = build_string (strlen (buf), buf);
5425 else
5426 input = build_string (constraint_len - 1, constraint + 1);
5428 free (p);
5430 input = build_tree_list (build_tree_list (NULL_TREE, input),
5431 unshare_expr (TREE_VALUE (link)));
5432 ASM_INPUTS (expr) = chainon (ASM_INPUTS (expr), input);
5436 link_next = NULL_TREE;
5437 for (link = ASM_INPUTS (expr); link; ++i, link = link_next)
5439 link_next = TREE_CHAIN (link);
5440 constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
5441 parse_input_constraint (&constraint, 0, 0, noutputs, 0,
5442 oconstraints, &allows_mem, &allows_reg);
5444 /* If we can't make copies, we can only accept memory. */
5445 if (TREE_ADDRESSABLE (TREE_TYPE (TREE_VALUE (link))))
5447 if (allows_mem)
5448 allows_reg = 0;
5449 else
5451 error ("impossible constraint in %<asm%>");
5452 error ("non-memory input %d must stay in memory", i);
5453 return GS_ERROR;
5457 /* If the operand is a memory input, it should be an lvalue. */
5458 if (!allows_reg && allows_mem)
5460 tree inputv = TREE_VALUE (link);
5461 STRIP_NOPS (inputv);
5462 if (TREE_CODE (inputv) == PREDECREMENT_EXPR
5463 || TREE_CODE (inputv) == PREINCREMENT_EXPR
5464 || TREE_CODE (inputv) == POSTDECREMENT_EXPR
5465 || TREE_CODE (inputv) == POSTINCREMENT_EXPR
5466 || TREE_CODE (inputv) == MODIFY_EXPR)
5467 TREE_VALUE (link) = error_mark_node;
5468 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
5469 is_gimple_lvalue, fb_lvalue | fb_mayfail);
5470 if (tret != GS_ERROR)
5472 /* Unlike output operands, memory inputs are not guaranteed
5473 to be lvalues by the FE, and while the expressions are
5474 marked addressable there, if it is e.g. a statement
5475 expression, temporaries in it might not end up being
5476 addressable. They might be already used in the IL and thus
5477 it is too late to make them addressable now though. */
5478 tree x = TREE_VALUE (link);
5479 while (handled_component_p (x))
5480 x = TREE_OPERAND (x, 0);
5481 if (TREE_CODE (x) == MEM_REF
5482 && TREE_CODE (TREE_OPERAND (x, 0)) == ADDR_EXPR)
5483 x = TREE_OPERAND (TREE_OPERAND (x, 0), 0);
5484 if ((TREE_CODE (x) == VAR_DECL
5485 || TREE_CODE (x) == PARM_DECL
5486 || TREE_CODE (x) == RESULT_DECL)
5487 && !TREE_ADDRESSABLE (x)
5488 && is_gimple_reg (x))
5490 warning_at (EXPR_LOC_OR_LOC (TREE_VALUE (link),
5491 input_location), 0,
5492 "memory input %d is not directly addressable",
5494 prepare_gimple_addressable (&TREE_VALUE (link), pre_p);
5497 mark_addressable (TREE_VALUE (link));
5498 if (tret == GS_ERROR)
5500 error_at (EXPR_LOC_OR_LOC (TREE_VALUE (link), input_location),
5501 "memory input %d is not directly addressable", i);
5502 ret = tret;
5505 else
5507 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
5508 is_gimple_asm_val, fb_rvalue);
5509 if (tret == GS_ERROR)
5510 ret = tret;
5513 TREE_CHAIN (link) = NULL_TREE;
5514 vec_safe_push (inputs, link);
5517 link_next = NULL_TREE;
5518 for (link = ASM_CLOBBERS (expr); link; ++i, link = link_next)
5520 link_next = TREE_CHAIN (link);
5521 TREE_CHAIN (link) = NULL_TREE;
5522 vec_safe_push (clobbers, link);
5525 link_next = NULL_TREE;
5526 for (link = ASM_LABELS (expr); link; ++i, link = link_next)
5528 link_next = TREE_CHAIN (link);
5529 TREE_CHAIN (link) = NULL_TREE;
5530 vec_safe_push (labels, link);
5533 /* Do not add ASMs with errors to the gimple IL stream. */
5534 if (ret != GS_ERROR)
5536 stmt = gimple_build_asm_vec (TREE_STRING_POINTER (ASM_STRING (expr)),
5537 inputs, outputs, clobbers, labels);
5539 gimple_asm_set_volatile (stmt, ASM_VOLATILE_P (expr) || noutputs == 0);
5540 gimple_asm_set_input (stmt, ASM_INPUT_P (expr));
5542 gimplify_seq_add_stmt (pre_p, stmt);
5545 return ret;
5548 /* Gimplify a CLEANUP_POINT_EXPR. Currently this works by adding
5549 GIMPLE_WITH_CLEANUP_EXPRs to the prequeue as we encounter cleanups while
5550 gimplifying the body, and converting them to TRY_FINALLY_EXPRs when we
5551 return to this function.
5553 FIXME should we complexify the prequeue handling instead? Or use flags
5554 for all the cleanups and let the optimizer tighten them up? The current
5555 code seems pretty fragile; it will break on a cleanup within any
5556 non-conditional nesting. But any such nesting would be broken, anyway;
5557 we can't write a TRY_FINALLY_EXPR that starts inside a nesting construct
5558 and continues out of it. We can do that at the RTL level, though, so
5559 having an optimizer to tighten up try/finally regions would be a Good
5560 Thing. */
5562 static enum gimplify_status
5563 gimplify_cleanup_point_expr (tree *expr_p, gimple_seq *pre_p)
5565 gimple_stmt_iterator iter;
5566 gimple_seq body_sequence = NULL;
5568 tree temp = voidify_wrapper_expr (*expr_p, NULL);
5570 /* We only care about the number of conditions between the innermost
5571 CLEANUP_POINT_EXPR and the cleanup. So save and reset the count and
5572 any cleanups collected outside the CLEANUP_POINT_EXPR. */
5573 int old_conds = gimplify_ctxp->conditions;
5574 gimple_seq old_cleanups = gimplify_ctxp->conditional_cleanups;
5575 bool old_in_cleanup_point_expr = gimplify_ctxp->in_cleanup_point_expr;
5576 gimplify_ctxp->conditions = 0;
5577 gimplify_ctxp->conditional_cleanups = NULL;
5578 gimplify_ctxp->in_cleanup_point_expr = true;
5580 gimplify_stmt (&TREE_OPERAND (*expr_p, 0), &body_sequence);
5582 gimplify_ctxp->conditions = old_conds;
5583 gimplify_ctxp->conditional_cleanups = old_cleanups;
5584 gimplify_ctxp->in_cleanup_point_expr = old_in_cleanup_point_expr;
5586 for (iter = gsi_start (body_sequence); !gsi_end_p (iter); )
5588 gimple *wce = gsi_stmt (iter);
5590 if (gimple_code (wce) == GIMPLE_WITH_CLEANUP_EXPR)
5592 if (gsi_one_before_end_p (iter))
5594 /* Note that gsi_insert_seq_before and gsi_remove do not
5595 scan operands, unlike some other sequence mutators. */
5596 if (!gimple_wce_cleanup_eh_only (wce))
5597 gsi_insert_seq_before_without_update (&iter,
5598 gimple_wce_cleanup (wce),
5599 GSI_SAME_STMT);
5600 gsi_remove (&iter, true);
5601 break;
5603 else
5605 gtry *gtry;
5606 gimple_seq seq;
5607 enum gimple_try_flags kind;
5609 if (gimple_wce_cleanup_eh_only (wce))
5610 kind = GIMPLE_TRY_CATCH;
5611 else
5612 kind = GIMPLE_TRY_FINALLY;
5613 seq = gsi_split_seq_after (iter);
5615 gtry = gimple_build_try (seq, gimple_wce_cleanup (wce), kind);
5616 /* Do not use gsi_replace here, as it may scan operands.
5617 We want to do a simple structural modification only. */
5618 gsi_set_stmt (&iter, gtry);
5619 iter = gsi_start (gtry->eval);
5622 else
5623 gsi_next (&iter);
5626 gimplify_seq_add_seq (pre_p, body_sequence);
5627 if (temp)
5629 *expr_p = temp;
5630 return GS_OK;
5632 else
5634 *expr_p = NULL;
5635 return GS_ALL_DONE;
5639 /* Insert a cleanup marker for gimplify_cleanup_point_expr. CLEANUP
5640 is the cleanup action required. EH_ONLY is true if the cleanup should
5641 only be executed if an exception is thrown, not on normal exit. */
5643 static void
5644 gimple_push_cleanup (tree var, tree cleanup, bool eh_only, gimple_seq *pre_p)
5646 gimple *wce;
5647 gimple_seq cleanup_stmts = NULL;
5649 /* Errors can result in improperly nested cleanups. Which results in
5650 confusion when trying to resolve the GIMPLE_WITH_CLEANUP_EXPR. */
5651 if (seen_error ())
5652 return;
5654 if (gimple_conditional_context ())
5656 /* If we're in a conditional context, this is more complex. We only
5657 want to run the cleanup if we actually ran the initialization that
5658 necessitates it, but we want to run it after the end of the
5659 conditional context. So we wrap the try/finally around the
5660 condition and use a flag to determine whether or not to actually
5661 run the destructor. Thus
5663 test ? f(A()) : 0
5665 becomes (approximately)
5667 flag = 0;
5668 try {
5669 if (test) { A::A(temp); flag = 1; val = f(temp); }
5670 else { val = 0; }
5671 } finally {
5672 if (flag) A::~A(temp);
5676 tree flag = create_tmp_var (boolean_type_node, "cleanup");
5677 gassign *ffalse = gimple_build_assign (flag, boolean_false_node);
5678 gassign *ftrue = gimple_build_assign (flag, boolean_true_node);
5680 cleanup = build3 (COND_EXPR, void_type_node, flag, cleanup, NULL);
5681 gimplify_stmt (&cleanup, &cleanup_stmts);
5682 wce = gimple_build_wce (cleanup_stmts);
5684 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, ffalse);
5685 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
5686 gimplify_seq_add_stmt (pre_p, ftrue);
5688 /* Because of this manipulation, and the EH edges that jump
5689 threading cannot redirect, the temporary (VAR) will appear
5690 to be used uninitialized. Don't warn. */
5691 TREE_NO_WARNING (var) = 1;
5693 else
5695 gimplify_stmt (&cleanup, &cleanup_stmts);
5696 wce = gimple_build_wce (cleanup_stmts);
5697 gimple_wce_set_cleanup_eh_only (wce, eh_only);
5698 gimplify_seq_add_stmt (pre_p, wce);
5702 /* Gimplify a TARGET_EXPR which doesn't appear on the rhs of an INIT_EXPR. */
5704 static enum gimplify_status
5705 gimplify_target_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
5707 tree targ = *expr_p;
5708 tree temp = TARGET_EXPR_SLOT (targ);
5709 tree init = TARGET_EXPR_INITIAL (targ);
5710 enum gimplify_status ret;
5712 if (init)
5714 tree cleanup = NULL_TREE;
5716 /* TARGET_EXPR temps aren't part of the enclosing block, so add it
5717 to the temps list. Handle also variable length TARGET_EXPRs. */
5718 if (TREE_CODE (DECL_SIZE (temp)) != INTEGER_CST)
5720 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (temp)))
5721 gimplify_type_sizes (TREE_TYPE (temp), pre_p);
5722 gimplify_vla_decl (temp, pre_p);
5724 else
5725 gimple_add_tmp_var (temp);
5727 /* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the
5728 expression is supposed to initialize the slot. */
5729 if (VOID_TYPE_P (TREE_TYPE (init)))
5730 ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
5731 else
5733 tree init_expr = build2 (INIT_EXPR, void_type_node, temp, init);
5734 init = init_expr;
5735 ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
5736 init = NULL;
5737 ggc_free (init_expr);
5739 if (ret == GS_ERROR)
5741 /* PR c++/28266 Make sure this is expanded only once. */
5742 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
5743 return GS_ERROR;
5745 if (init)
5746 gimplify_and_add (init, pre_p);
5748 /* If needed, push the cleanup for the temp. */
5749 if (TARGET_EXPR_CLEANUP (targ))
5751 if (CLEANUP_EH_ONLY (targ))
5752 gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ),
5753 CLEANUP_EH_ONLY (targ), pre_p);
5754 else
5755 cleanup = TARGET_EXPR_CLEANUP (targ);
5758 /* Add a clobber for the temporary going out of scope, like
5759 gimplify_bind_expr. */
5760 if (gimplify_ctxp->in_cleanup_point_expr
5761 && needs_to_live_in_memory (temp)
5762 && flag_stack_reuse == SR_ALL)
5764 tree clobber = build_constructor (TREE_TYPE (temp),
5765 NULL);
5766 TREE_THIS_VOLATILE (clobber) = true;
5767 clobber = build2 (MODIFY_EXPR, TREE_TYPE (temp), temp, clobber);
5768 if (cleanup)
5769 cleanup = build2 (COMPOUND_EXPR, void_type_node, cleanup,
5770 clobber);
5771 else
5772 cleanup = clobber;
5775 if (cleanup)
5776 gimple_push_cleanup (temp, cleanup, false, pre_p);
5778 /* Only expand this once. */
5779 TREE_OPERAND (targ, 3) = init;
5780 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
5782 else
5783 /* We should have expanded this before. */
5784 gcc_assert (DECL_SEEN_IN_BIND_EXPR_P (temp));
5786 *expr_p = temp;
5787 return GS_OK;
5790 /* Gimplification of expression trees. */
5792 /* Gimplify an expression which appears at statement context. The
5793 corresponding GIMPLE statements are added to *SEQ_P. If *SEQ_P is
5794 NULL, a new sequence is allocated.
5796 Return true if we actually added a statement to the queue. */
5798 bool
5799 gimplify_stmt (tree *stmt_p, gimple_seq *seq_p)
5801 gimple_seq_node last;
5803 last = gimple_seq_last (*seq_p);
5804 gimplify_expr (stmt_p, seq_p, NULL, is_gimple_stmt, fb_none);
5805 return last != gimple_seq_last (*seq_p);
5808 /* Add FIRSTPRIVATE entries for DECL in the OpenMP the surrounding parallels
5809 to CTX. If entries already exist, force them to be some flavor of private.
5810 If there is no enclosing parallel, do nothing. */
5812 void
5813 omp_firstprivatize_variable (struct gimplify_omp_ctx *ctx, tree decl)
5815 splay_tree_node n;
5817 if (decl == NULL || !DECL_P (decl) || ctx->region_type == ORT_NONE)
5818 return;
5822 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
5823 if (n != NULL)
5825 if (n->value & GOVD_SHARED)
5826 n->value = GOVD_FIRSTPRIVATE | (n->value & GOVD_SEEN);
5827 else if (n->value & GOVD_MAP)
5828 n->value |= GOVD_MAP_TO_ONLY;
5829 else
5830 return;
5832 else if ((ctx->region_type & ORT_TARGET) != 0)
5834 if (ctx->target_map_scalars_firstprivate)
5835 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
5836 else
5837 omp_add_variable (ctx, decl, GOVD_MAP | GOVD_MAP_TO_ONLY);
5839 else if (ctx->region_type != ORT_WORKSHARE
5840 && ctx->region_type != ORT_SIMD
5841 && ctx->region_type != ORT_ACC
5842 && !(ctx->region_type & ORT_TARGET_DATA))
5843 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
5845 ctx = ctx->outer_context;
5847 while (ctx);
5850 /* Similarly for each of the type sizes of TYPE. */
5852 static void
5853 omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type)
5855 if (type == NULL || type == error_mark_node)
5856 return;
5857 type = TYPE_MAIN_VARIANT (type);
5859 if (ctx->privatized_types->add (type))
5860 return;
5862 switch (TREE_CODE (type))
5864 case INTEGER_TYPE:
5865 case ENUMERAL_TYPE:
5866 case BOOLEAN_TYPE:
5867 case REAL_TYPE:
5868 case FIXED_POINT_TYPE:
5869 omp_firstprivatize_variable (ctx, TYPE_MIN_VALUE (type));
5870 omp_firstprivatize_variable (ctx, TYPE_MAX_VALUE (type));
5871 break;
5873 case ARRAY_TYPE:
5874 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
5875 omp_firstprivatize_type_sizes (ctx, TYPE_DOMAIN (type));
5876 break;
5878 case RECORD_TYPE:
5879 case UNION_TYPE:
5880 case QUAL_UNION_TYPE:
5882 tree field;
5883 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
5884 if (TREE_CODE (field) == FIELD_DECL)
5886 omp_firstprivatize_variable (ctx, DECL_FIELD_OFFSET (field));
5887 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (field));
5890 break;
5892 case POINTER_TYPE:
5893 case REFERENCE_TYPE:
5894 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
5895 break;
5897 default:
5898 break;
5901 omp_firstprivatize_variable (ctx, TYPE_SIZE (type));
5902 omp_firstprivatize_variable (ctx, TYPE_SIZE_UNIT (type));
5903 lang_hooks.types.omp_firstprivatize_type_sizes (ctx, type);
5906 /* Add an entry for DECL in the OMP context CTX with FLAGS. */
5908 static void
5909 omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
5911 splay_tree_node n;
5912 unsigned int nflags;
5913 tree t;
5915 if (error_operand_p (decl) || ctx->region_type == ORT_NONE)
5916 return;
5918 /* Never elide decls whose type has TREE_ADDRESSABLE set. This means
5919 there are constructors involved somewhere. */
5920 if (TREE_ADDRESSABLE (TREE_TYPE (decl))
5921 || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
5922 flags |= GOVD_SEEN;
5924 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
5925 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
5927 /* We shouldn't be re-adding the decl with the same data
5928 sharing class. */
5929 gcc_assert ((n->value & GOVD_DATA_SHARE_CLASS & flags) == 0);
5930 nflags = n->value | flags;
5931 /* The only combination of data sharing classes we should see is
5932 FIRSTPRIVATE and LASTPRIVATE. However, OpenACC permits
5933 reduction variables to be used in data sharing clauses. */
5934 gcc_assert ((ctx->region_type & ORT_ACC) != 0
5935 || ((nflags & GOVD_DATA_SHARE_CLASS)
5936 == (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE))
5937 || (flags & GOVD_DATA_SHARE_CLASS) == 0);
5938 n->value = nflags;
5939 return;
5942 /* When adding a variable-sized variable, we have to handle all sorts
5943 of additional bits of data: the pointer replacement variable, and
5944 the parameters of the type. */
5945 if (DECL_SIZE (decl) && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
5947 /* Add the pointer replacement variable as PRIVATE if the variable
5948 replacement is private, else FIRSTPRIVATE since we'll need the
5949 address of the original variable either for SHARED, or for the
5950 copy into or out of the context. */
5951 if (!(flags & GOVD_LOCAL))
5953 if (flags & GOVD_MAP)
5954 nflags = GOVD_MAP | GOVD_MAP_TO_ONLY | GOVD_EXPLICIT;
5955 else if (flags & GOVD_PRIVATE)
5956 nflags = GOVD_PRIVATE;
5957 else if ((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
5958 && (flags & GOVD_FIRSTPRIVATE))
5959 nflags = GOVD_PRIVATE | GOVD_EXPLICIT;
5960 else
5961 nflags = GOVD_FIRSTPRIVATE;
5962 nflags |= flags & GOVD_SEEN;
5963 t = DECL_VALUE_EXPR (decl);
5964 gcc_assert (TREE_CODE (t) == INDIRECT_REF);
5965 t = TREE_OPERAND (t, 0);
5966 gcc_assert (DECL_P (t));
5967 omp_add_variable (ctx, t, nflags);
5970 /* Add all of the variable and type parameters (which should have
5971 been gimplified to a formal temporary) as FIRSTPRIVATE. */
5972 omp_firstprivatize_variable (ctx, DECL_SIZE_UNIT (decl));
5973 omp_firstprivatize_variable (ctx, DECL_SIZE (decl));
5974 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
5976 /* The variable-sized variable itself is never SHARED, only some form
5977 of PRIVATE. The sharing would take place via the pointer variable
5978 which we remapped above. */
5979 if (flags & GOVD_SHARED)
5980 flags = GOVD_PRIVATE | GOVD_DEBUG_PRIVATE
5981 | (flags & (GOVD_SEEN | GOVD_EXPLICIT));
5983 /* We're going to make use of the TYPE_SIZE_UNIT at least in the
5984 alloca statement we generate for the variable, so make sure it
5985 is available. This isn't automatically needed for the SHARED
5986 case, since we won't be allocating local storage then.
5987 For local variables TYPE_SIZE_UNIT might not be gimplified yet,
5988 in this case omp_notice_variable will be called later
5989 on when it is gimplified. */
5990 else if (! (flags & (GOVD_LOCAL | GOVD_MAP))
5991 && DECL_P (TYPE_SIZE_UNIT (TREE_TYPE (decl))))
5992 omp_notice_variable (ctx, TYPE_SIZE_UNIT (TREE_TYPE (decl)), true);
5994 else if ((flags & (GOVD_MAP | GOVD_LOCAL)) == 0
5995 && lang_hooks.decls.omp_privatize_by_reference (decl))
5997 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
5999 /* Similar to the direct variable sized case above, we'll need the
6000 size of references being privatized. */
6001 if ((flags & GOVD_SHARED) == 0)
6003 t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
6004 if (DECL_P (t))
6005 omp_notice_variable (ctx, t, true);
6009 if (n != NULL)
6010 n->value |= flags;
6011 else
6012 splay_tree_insert (ctx->variables, (splay_tree_key)decl, flags);
6014 /* For reductions clauses in OpenACC loop directives, by default create a
6015 copy clause on the enclosing parallel construct for carrying back the
6016 results. */
6017 if (ctx->region_type == ORT_ACC && (flags & GOVD_REDUCTION))
6019 struct gimplify_omp_ctx *outer_ctx = ctx->outer_context;
6020 while (outer_ctx)
6022 n = splay_tree_lookup (outer_ctx->variables, (splay_tree_key)decl);
6023 if (n != NULL)
6025 /* Ignore local variables and explicitly declared clauses. */
6026 if (n->value & (GOVD_LOCAL | GOVD_EXPLICIT))
6027 break;
6028 else if (outer_ctx->region_type == ORT_ACC_KERNELS)
6030 /* According to the OpenACC spec, such a reduction variable
6031 should already have a copy map on a kernels construct,
6032 verify that here. */
6033 gcc_assert (!(n->value & GOVD_FIRSTPRIVATE)
6034 && (n->value & GOVD_MAP));
6036 else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
6038 /* Remove firstprivate and make it a copy map. */
6039 n->value &= ~GOVD_FIRSTPRIVATE;
6040 n->value |= GOVD_MAP;
6043 else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
6045 splay_tree_insert (outer_ctx->variables, (splay_tree_key)decl,
6046 GOVD_MAP | GOVD_SEEN);
6047 break;
6049 outer_ctx = outer_ctx->outer_context;
6054 /* Notice a threadprivate variable DECL used in OMP context CTX.
6055 This just prints out diagnostics about threadprivate variable uses
6056 in untied tasks. If DECL2 is non-NULL, prevent this warning
6057 on that variable. */
6059 static bool
6060 omp_notice_threadprivate_variable (struct gimplify_omp_ctx *ctx, tree decl,
6061 tree decl2)
6063 splay_tree_node n;
6064 struct gimplify_omp_ctx *octx;
6066 for (octx = ctx; octx; octx = octx->outer_context)
6067 if ((octx->region_type & ORT_TARGET) != 0)
6069 n = splay_tree_lookup (octx->variables, (splay_tree_key)decl);
6070 if (n == NULL)
6072 error ("threadprivate variable %qE used in target region",
6073 DECL_NAME (decl));
6074 error_at (octx->location, "enclosing target region");
6075 splay_tree_insert (octx->variables, (splay_tree_key)decl, 0);
6077 if (decl2)
6078 splay_tree_insert (octx->variables, (splay_tree_key)decl2, 0);
6081 if (ctx->region_type != ORT_UNTIED_TASK)
6082 return false;
6083 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
6084 if (n == NULL)
6086 error ("threadprivate variable %qE used in untied task",
6087 DECL_NAME (decl));
6088 error_at (ctx->location, "enclosing task");
6089 splay_tree_insert (ctx->variables, (splay_tree_key)decl, 0);
6091 if (decl2)
6092 splay_tree_insert (ctx->variables, (splay_tree_key)decl2, 0);
6093 return false;
6096 /* Return true if global var DECL is device resident. */
6098 static bool
6099 device_resident_p (tree decl)
6101 tree attr = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (decl));
6103 if (!attr)
6104 return false;
6106 for (tree t = TREE_VALUE (attr); t; t = TREE_PURPOSE (t))
6108 tree c = TREE_VALUE (t);
6109 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DEVICE_RESIDENT)
6110 return true;
6113 return false;
6116 /* Determine outer default flags for DECL mentioned in an OMP region
6117 but not declared in an enclosing clause.
6119 ??? Some compiler-generated variables (like SAVE_EXPRs) could be
6120 remapped firstprivate instead of shared. To some extent this is
6121 addressed in omp_firstprivatize_type_sizes, but not
6122 effectively. */
6124 static unsigned
6125 omp_default_clause (struct gimplify_omp_ctx *ctx, tree decl,
6126 bool in_code, unsigned flags)
6128 enum omp_clause_default_kind default_kind = ctx->default_kind;
6129 enum omp_clause_default_kind kind;
6131 kind = lang_hooks.decls.omp_predetermined_sharing (decl);
6132 if (kind != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
6133 default_kind = kind;
6135 switch (default_kind)
6137 case OMP_CLAUSE_DEFAULT_NONE:
6139 const char *rtype;
6141 if (ctx->region_type & ORT_PARALLEL)
6142 rtype = "parallel";
6143 else if (ctx->region_type & ORT_TASK)
6144 rtype = "task";
6145 else if (ctx->region_type & ORT_TEAMS)
6146 rtype = "teams";
6147 else
6148 gcc_unreachable ();
6150 error ("%qE not specified in enclosing %s",
6151 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rtype);
6152 error_at (ctx->location, "enclosing %s", rtype);
6154 /* FALLTHRU */
6155 case OMP_CLAUSE_DEFAULT_SHARED:
6156 flags |= GOVD_SHARED;
6157 break;
6158 case OMP_CLAUSE_DEFAULT_PRIVATE:
6159 flags |= GOVD_PRIVATE;
6160 break;
6161 case OMP_CLAUSE_DEFAULT_FIRSTPRIVATE:
6162 flags |= GOVD_FIRSTPRIVATE;
6163 break;
6164 case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
6165 /* decl will be either GOVD_FIRSTPRIVATE or GOVD_SHARED. */
6166 gcc_assert ((ctx->region_type & ORT_TASK) != 0);
6167 if (struct gimplify_omp_ctx *octx = ctx->outer_context)
6169 omp_notice_variable (octx, decl, in_code);
6170 for (; octx; octx = octx->outer_context)
6172 splay_tree_node n2;
6174 n2 = splay_tree_lookup (octx->variables, (splay_tree_key) decl);
6175 if ((octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)) != 0
6176 && (n2 == NULL || (n2->value & GOVD_DATA_SHARE_CLASS) == 0))
6177 continue;
6178 if (n2 && (n2->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED)
6180 flags |= GOVD_FIRSTPRIVATE;
6181 goto found_outer;
6183 if ((octx->region_type & (ORT_PARALLEL | ORT_TEAMS)) != 0)
6185 flags |= GOVD_SHARED;
6186 goto found_outer;
6191 if (TREE_CODE (decl) == PARM_DECL
6192 || (!is_global_var (decl)
6193 && DECL_CONTEXT (decl) == current_function_decl))
6194 flags |= GOVD_FIRSTPRIVATE;
6195 else
6196 flags |= GOVD_SHARED;
6197 found_outer:
6198 break;
6200 default:
6201 gcc_unreachable ();
6204 return flags;
6208 /* Determine outer default flags for DECL mentioned in an OACC region
6209 but not declared in an enclosing clause. */
6211 static unsigned
6212 oacc_default_clause (struct gimplify_omp_ctx *ctx, tree decl, unsigned flags)
6214 const char *rkind;
6215 bool on_device = false;
6216 tree type = TREE_TYPE (decl);
6218 if (lang_hooks.decls.omp_privatize_by_reference (decl))
6219 type = TREE_TYPE (type);
6221 if ((ctx->region_type & (ORT_ACC_PARALLEL | ORT_ACC_KERNELS)) != 0
6222 && is_global_var (decl)
6223 && device_resident_p (decl))
6225 on_device = true;
6226 flags |= GOVD_MAP_TO_ONLY;
6229 switch (ctx->region_type)
6231 default:
6232 gcc_unreachable ();
6234 case ORT_ACC_KERNELS:
6235 /* Scalars are default 'copy' under kernels, non-scalars are default
6236 'present_or_copy'. */
6237 flags |= GOVD_MAP;
6238 if (!AGGREGATE_TYPE_P (type))
6239 flags |= GOVD_MAP_FORCE;
6241 rkind = "kernels";
6242 break;
6244 case ORT_ACC_PARALLEL:
6246 if (on_device || AGGREGATE_TYPE_P (type))
6247 /* Aggregates default to 'present_or_copy'. */
6248 flags |= GOVD_MAP;
6249 else
6250 /* Scalars default to 'firstprivate'. */
6251 flags |= GOVD_FIRSTPRIVATE;
6252 rkind = "parallel";
6254 break;
6257 if (DECL_ARTIFICIAL (decl))
6258 ; /* We can get compiler-generated decls, and should not complain
6259 about them. */
6260 else if (ctx->default_kind == OMP_CLAUSE_DEFAULT_NONE)
6262 error ("%qE not specified in enclosing OpenACC %qs construct",
6263 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rkind);
6264 inform (ctx->location, "enclosing OpenACC %qs construct", rkind);
6266 else
6267 gcc_checking_assert (ctx->default_kind == OMP_CLAUSE_DEFAULT_SHARED);
6269 return flags;
6272 /* Record the fact that DECL was used within the OMP context CTX.
6273 IN_CODE is true when real code uses DECL, and false when we should
6274 merely emit default(none) errors. Return true if DECL is going to
6275 be remapped and thus DECL shouldn't be gimplified into its
6276 DECL_VALUE_EXPR (if any). */
6278 static bool
6279 omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
6281 splay_tree_node n;
6282 unsigned flags = in_code ? GOVD_SEEN : 0;
6283 bool ret = false, shared;
6285 if (error_operand_p (decl))
6286 return false;
6288 if (ctx->region_type == ORT_NONE)
6289 return lang_hooks.decls.omp_disregard_value_expr (decl, false);
6291 if (is_global_var (decl))
6293 /* Threadprivate variables are predetermined. */
6294 if (DECL_THREAD_LOCAL_P (decl))
6295 return omp_notice_threadprivate_variable (ctx, decl, NULL_TREE);
6297 if (DECL_HAS_VALUE_EXPR_P (decl))
6299 tree value = get_base_address (DECL_VALUE_EXPR (decl));
6301 if (value && DECL_P (value) && DECL_THREAD_LOCAL_P (value))
6302 return omp_notice_threadprivate_variable (ctx, decl, value);
6305 if (gimplify_omp_ctxp->outer_context == NULL
6306 && VAR_P (decl)
6307 && get_oacc_fn_attrib (current_function_decl))
6309 location_t loc = DECL_SOURCE_LOCATION (decl);
6311 if (lookup_attribute ("omp declare target link",
6312 DECL_ATTRIBUTES (decl)))
6314 error_at (loc,
6315 "%qE with %<link%> clause used in %<routine%> function",
6316 DECL_NAME (decl));
6317 return false;
6319 else if (!lookup_attribute ("omp declare target",
6320 DECL_ATTRIBUTES (decl)))
6322 error_at (loc,
6323 "%qE requires a %<declare%> directive for use "
6324 "in a %<routine%> function", DECL_NAME (decl));
6325 return false;
6330 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
6331 if ((ctx->region_type & ORT_TARGET) != 0)
6333 ret = lang_hooks.decls.omp_disregard_value_expr (decl, true);
6334 if (n == NULL)
6336 unsigned nflags = flags;
6337 if (ctx->target_map_pointers_as_0len_arrays
6338 || ctx->target_map_scalars_firstprivate)
6340 bool is_declare_target = false;
6341 bool is_scalar = false;
6342 if (is_global_var (decl)
6343 && varpool_node::get_create (decl)->offloadable)
6345 struct gimplify_omp_ctx *octx;
6346 for (octx = ctx->outer_context;
6347 octx; octx = octx->outer_context)
6349 n = splay_tree_lookup (octx->variables,
6350 (splay_tree_key)decl);
6351 if (n
6352 && (n->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED
6353 && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
6354 break;
6356 is_declare_target = octx == NULL;
6358 if (!is_declare_target && ctx->target_map_scalars_firstprivate)
6360 tree type = TREE_TYPE (decl);
6361 if (TREE_CODE (type) == REFERENCE_TYPE)
6362 type = TREE_TYPE (type);
6363 if (TREE_CODE (type) == COMPLEX_TYPE)
6364 type = TREE_TYPE (type);
6365 if (INTEGRAL_TYPE_P (type)
6366 || SCALAR_FLOAT_TYPE_P (type)
6367 || TREE_CODE (type) == POINTER_TYPE)
6368 is_scalar = true;
6370 if (is_declare_target)
6372 else if (ctx->target_map_pointers_as_0len_arrays
6373 && (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
6374 || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
6375 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
6376 == POINTER_TYPE)))
6377 nflags |= GOVD_MAP | GOVD_MAP_0LEN_ARRAY;
6378 else if (is_scalar)
6379 nflags |= GOVD_FIRSTPRIVATE;
6382 struct gimplify_omp_ctx *octx = ctx->outer_context;
6383 if ((ctx->region_type & ORT_ACC) && octx)
6385 /* Look in outer OpenACC contexts, to see if there's a
6386 data attribute for this variable. */
6387 omp_notice_variable (octx, decl, in_code);
6389 for (; octx; octx = octx->outer_context)
6391 if (!(octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)))
6392 break;
6393 splay_tree_node n2
6394 = splay_tree_lookup (octx->variables,
6395 (splay_tree_key) decl);
6396 if (n2)
6398 if (octx->region_type == ORT_ACC_HOST_DATA)
6399 error ("variable %qE declared in enclosing "
6400 "%<host_data%> region", DECL_NAME (decl));
6401 nflags |= GOVD_MAP;
6402 if (octx->region_type == ORT_ACC_DATA
6403 && (n2->value & GOVD_MAP_0LEN_ARRAY))
6404 nflags |= GOVD_MAP_0LEN_ARRAY;
6405 goto found_outer;
6411 tree type = TREE_TYPE (decl);
6413 if (nflags == flags
6414 && gimplify_omp_ctxp->target_firstprivatize_array_bases
6415 && lang_hooks.decls.omp_privatize_by_reference (decl))
6416 type = TREE_TYPE (type);
6417 if (nflags == flags
6418 && !lang_hooks.types.omp_mappable_type (type))
6420 error ("%qD referenced in target region does not have "
6421 "a mappable type", decl);
6422 nflags |= GOVD_MAP | GOVD_EXPLICIT;
6424 else if (nflags == flags)
6426 if ((ctx->region_type & ORT_ACC) != 0)
6427 nflags = oacc_default_clause (ctx, decl, flags);
6428 else
6429 nflags |= GOVD_MAP;
6432 found_outer:
6433 omp_add_variable (ctx, decl, nflags);
6435 else
6437 /* If nothing changed, there's nothing left to do. */
6438 if ((n->value & flags) == flags)
6439 return ret;
6440 flags |= n->value;
6441 n->value = flags;
6443 goto do_outer;
6446 if (n == NULL)
6448 if (ctx->region_type == ORT_WORKSHARE
6449 || ctx->region_type == ORT_SIMD
6450 || ctx->region_type == ORT_ACC
6451 || (ctx->region_type & ORT_TARGET_DATA) != 0)
6452 goto do_outer;
6454 flags = omp_default_clause (ctx, decl, in_code, flags);
6456 if ((flags & GOVD_PRIVATE)
6457 && lang_hooks.decls.omp_private_outer_ref (decl))
6458 flags |= GOVD_PRIVATE_OUTER_REF;
6460 omp_add_variable (ctx, decl, flags);
6462 shared = (flags & GOVD_SHARED) != 0;
6463 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
6464 goto do_outer;
6467 if ((n->value & (GOVD_SEEN | GOVD_LOCAL)) == 0
6468 && (flags & (GOVD_SEEN | GOVD_LOCAL)) == GOVD_SEEN
6469 && DECL_SIZE (decl))
6471 if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
6473 splay_tree_node n2;
6474 tree t = DECL_VALUE_EXPR (decl);
6475 gcc_assert (TREE_CODE (t) == INDIRECT_REF);
6476 t = TREE_OPERAND (t, 0);
6477 gcc_assert (DECL_P (t));
6478 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
6479 n2->value |= GOVD_SEEN;
6481 else if (lang_hooks.decls.omp_privatize_by_reference (decl)
6482 && TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)))
6483 && (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))))
6484 != INTEGER_CST))
6486 splay_tree_node n2;
6487 tree t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
6488 gcc_assert (DECL_P (t));
6489 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
6490 if (n2)
6491 n2->value |= GOVD_SEEN;
6495 shared = ((flags | n->value) & GOVD_SHARED) != 0;
6496 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
6498 /* If nothing changed, there's nothing left to do. */
6499 if ((n->value & flags) == flags)
6500 return ret;
6501 flags |= n->value;
6502 n->value = flags;
6504 do_outer:
6505 /* If the variable is private in the current context, then we don't
6506 need to propagate anything to an outer context. */
6507 if ((flags & GOVD_PRIVATE) && !(flags & GOVD_PRIVATE_OUTER_REF))
6508 return ret;
6509 if ((flags & (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
6510 == (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
6511 return ret;
6512 if ((flags & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
6513 | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
6514 == (GOVD_LASTPRIVATE | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
6515 return ret;
6516 if (ctx->outer_context
6517 && omp_notice_variable (ctx->outer_context, decl, in_code))
6518 return true;
6519 return ret;
6522 /* Verify that DECL is private within CTX. If there's specific information
6523 to the contrary in the innermost scope, generate an error. */
6525 static bool
6526 omp_is_private (struct gimplify_omp_ctx *ctx, tree decl, int simd)
6528 splay_tree_node n;
6530 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
6531 if (n != NULL)
6533 if (n->value & GOVD_SHARED)
6535 if (ctx == gimplify_omp_ctxp)
6537 if (simd)
6538 error ("iteration variable %qE is predetermined linear",
6539 DECL_NAME (decl));
6540 else
6541 error ("iteration variable %qE should be private",
6542 DECL_NAME (decl));
6543 n->value = GOVD_PRIVATE;
6544 return true;
6546 else
6547 return false;
6549 else if ((n->value & GOVD_EXPLICIT) != 0
6550 && (ctx == gimplify_omp_ctxp
6551 || (ctx->region_type == ORT_COMBINED_PARALLEL
6552 && gimplify_omp_ctxp->outer_context == ctx)))
6554 if ((n->value & GOVD_FIRSTPRIVATE) != 0)
6555 error ("iteration variable %qE should not be firstprivate",
6556 DECL_NAME (decl));
6557 else if ((n->value & GOVD_REDUCTION) != 0)
6558 error ("iteration variable %qE should not be reduction",
6559 DECL_NAME (decl));
6560 else if (simd == 0 && (n->value & GOVD_LINEAR) != 0)
6561 error ("iteration variable %qE should not be linear",
6562 DECL_NAME (decl));
6563 else if (simd == 1 && (n->value & GOVD_LASTPRIVATE) != 0)
6564 error ("iteration variable %qE should not be lastprivate",
6565 DECL_NAME (decl));
6566 else if (simd && (n->value & GOVD_PRIVATE) != 0)
6567 error ("iteration variable %qE should not be private",
6568 DECL_NAME (decl));
6569 else if (simd == 2 && (n->value & GOVD_LINEAR) != 0)
6570 error ("iteration variable %qE is predetermined linear",
6571 DECL_NAME (decl));
6573 return (ctx == gimplify_omp_ctxp
6574 || (ctx->region_type == ORT_COMBINED_PARALLEL
6575 && gimplify_omp_ctxp->outer_context == ctx));
6578 if (ctx->region_type != ORT_WORKSHARE
6579 && ctx->region_type != ORT_SIMD
6580 && ctx->region_type != ORT_ACC)
6581 return false;
6582 else if (ctx->outer_context)
6583 return omp_is_private (ctx->outer_context, decl, simd);
6584 return false;
6587 /* Return true if DECL is private within a parallel region
6588 that binds to the current construct's context or in parallel
6589 region's REDUCTION clause. */
6591 static bool
6592 omp_check_private (struct gimplify_omp_ctx *ctx, tree decl, bool copyprivate)
6594 splay_tree_node n;
6598 ctx = ctx->outer_context;
6599 if (ctx == NULL)
6601 if (is_global_var (decl))
6602 return false;
6604 /* References might be private, but might be shared too,
6605 when checking for copyprivate, assume they might be
6606 private, otherwise assume they might be shared. */
6607 if (copyprivate)
6608 return true;
6610 if (lang_hooks.decls.omp_privatize_by_reference (decl))
6611 return false;
6613 /* Treat C++ privatized non-static data members outside
6614 of the privatization the same. */
6615 if (omp_member_access_dummy_var (decl))
6616 return false;
6618 return true;
6621 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
6623 if ((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
6624 && (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0))
6625 continue;
6627 if (n != NULL)
6629 if ((n->value & GOVD_LOCAL) != 0
6630 && omp_member_access_dummy_var (decl))
6631 return false;
6632 return (n->value & GOVD_SHARED) == 0;
6635 while (ctx->region_type == ORT_WORKSHARE
6636 || ctx->region_type == ORT_SIMD
6637 || ctx->region_type == ORT_ACC);
6638 return false;
6641 /* Return true if the CTX is combined with distribute and thus
6642 lastprivate can't be supported. */
6644 static bool
6645 omp_no_lastprivate (struct gimplify_omp_ctx *ctx)
6649 if (ctx->outer_context == NULL)
6650 return false;
6651 ctx = ctx->outer_context;
6652 switch (ctx->region_type)
6654 case ORT_WORKSHARE:
6655 if (!ctx->combined_loop)
6656 return false;
6657 if (ctx->distribute)
6658 return lang_GNU_Fortran ();
6659 break;
6660 case ORT_COMBINED_PARALLEL:
6661 break;
6662 case ORT_COMBINED_TEAMS:
6663 return lang_GNU_Fortran ();
6664 default:
6665 return false;
6668 while (1);
6671 /* Callback for walk_tree to find a DECL_EXPR for the given DECL. */
6673 static tree
6674 find_decl_expr (tree *tp, int *walk_subtrees, void *data)
6676 tree t = *tp;
6678 /* If this node has been visited, unmark it and keep looking. */
6679 if (TREE_CODE (t) == DECL_EXPR && DECL_EXPR_DECL (t) == (tree) data)
6680 return t;
6682 if (IS_TYPE_OR_DECL_P (t))
6683 *walk_subtrees = 0;
6684 return NULL_TREE;
6687 /* Scan the OMP clauses in *LIST_P, installing mappings into a new
6688 and previous omp contexts. */
6690 static void
6691 gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
6692 enum omp_region_type region_type,
6693 enum tree_code code)
6695 struct gimplify_omp_ctx *ctx, *outer_ctx;
6696 tree c;
6697 hash_map<tree, tree> *struct_map_to_clause = NULL;
6698 tree *prev_list_p = NULL;
6700 ctx = new_omp_context (region_type);
6701 outer_ctx = ctx->outer_context;
6702 if (code == OMP_TARGET && !lang_GNU_Fortran ())
6704 ctx->target_map_pointers_as_0len_arrays = true;
6705 /* FIXME: For Fortran we want to set this too, when
6706 the Fortran FE is updated to OpenMP 4.5. */
6707 ctx->target_map_scalars_firstprivate = true;
6709 if (!lang_GNU_Fortran ())
6710 switch (code)
6712 case OMP_TARGET:
6713 case OMP_TARGET_DATA:
6714 case OMP_TARGET_ENTER_DATA:
6715 case OMP_TARGET_EXIT_DATA:
6716 case OACC_HOST_DATA:
6717 ctx->target_firstprivatize_array_bases = true;
6718 default:
6719 break;
6722 while ((c = *list_p) != NULL)
6724 bool remove = false;
6725 bool notice_outer = true;
6726 const char *check_non_private = NULL;
6727 unsigned int flags;
6728 tree decl;
6730 switch (OMP_CLAUSE_CODE (c))
6732 case OMP_CLAUSE_PRIVATE:
6733 flags = GOVD_PRIVATE | GOVD_EXPLICIT;
6734 if (lang_hooks.decls.omp_private_outer_ref (OMP_CLAUSE_DECL (c)))
6736 flags |= GOVD_PRIVATE_OUTER_REF;
6737 OMP_CLAUSE_PRIVATE_OUTER_REF (c) = 1;
6739 else
6740 notice_outer = false;
6741 goto do_add;
6742 case OMP_CLAUSE_SHARED:
6743 flags = GOVD_SHARED | GOVD_EXPLICIT;
6744 goto do_add;
6745 case OMP_CLAUSE_FIRSTPRIVATE:
6746 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
6747 check_non_private = "firstprivate";
6748 goto do_add;
6749 case OMP_CLAUSE_LASTPRIVATE:
6750 flags = GOVD_LASTPRIVATE | GOVD_SEEN | GOVD_EXPLICIT;
6751 check_non_private = "lastprivate";
6752 decl = OMP_CLAUSE_DECL (c);
6753 if (omp_no_lastprivate (ctx))
6755 notice_outer = false;
6756 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
6758 else if (error_operand_p (decl))
6759 goto do_add;
6760 else if (outer_ctx
6761 && (outer_ctx->region_type == ORT_COMBINED_PARALLEL
6762 || outer_ctx->region_type == ORT_COMBINED_TEAMS)
6763 && splay_tree_lookup (outer_ctx->variables,
6764 (splay_tree_key) decl) == NULL)
6766 omp_add_variable (outer_ctx, decl, GOVD_SHARED | GOVD_SEEN);
6767 if (outer_ctx->outer_context)
6768 omp_notice_variable (outer_ctx->outer_context, decl, true);
6770 else if (outer_ctx
6771 && (outer_ctx->region_type & ORT_TASK) != 0
6772 && outer_ctx->combined_loop
6773 && splay_tree_lookup (outer_ctx->variables,
6774 (splay_tree_key) decl) == NULL)
6776 omp_add_variable (outer_ctx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
6777 if (outer_ctx->outer_context)
6778 omp_notice_variable (outer_ctx->outer_context, decl, true);
6780 else if (outer_ctx
6781 && (outer_ctx->region_type == ORT_WORKSHARE
6782 || outer_ctx->region_type == ORT_ACC)
6783 && outer_ctx->combined_loop
6784 && splay_tree_lookup (outer_ctx->variables,
6785 (splay_tree_key) decl) == NULL
6786 && !omp_check_private (outer_ctx, decl, false))
6788 omp_add_variable (outer_ctx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
6789 if (outer_ctx->outer_context
6790 && (outer_ctx->outer_context->region_type
6791 == ORT_COMBINED_PARALLEL)
6792 && splay_tree_lookup (outer_ctx->outer_context->variables,
6793 (splay_tree_key) decl) == NULL)
6795 struct gimplify_omp_ctx *octx = outer_ctx->outer_context;
6796 omp_add_variable (octx, decl, GOVD_SHARED | GOVD_SEEN);
6797 if (octx->outer_context)
6798 omp_notice_variable (octx->outer_context, decl, true);
6800 else if (outer_ctx->outer_context)
6801 omp_notice_variable (outer_ctx->outer_context, decl, true);
6803 goto do_add;
6804 case OMP_CLAUSE_REDUCTION:
6805 flags = GOVD_REDUCTION | GOVD_SEEN | GOVD_EXPLICIT;
6806 /* OpenACC permits reductions on private variables. */
6807 if (!(region_type & ORT_ACC))
6808 check_non_private = "reduction";
6809 decl = OMP_CLAUSE_DECL (c);
6810 if (TREE_CODE (decl) == MEM_REF)
6812 tree type = TREE_TYPE (decl);
6813 if (gimplify_expr (&TYPE_MAX_VALUE (TYPE_DOMAIN (type)), pre_p,
6814 NULL, is_gimple_val, fb_rvalue, false)
6815 == GS_ERROR)
6817 remove = true;
6818 break;
6820 tree v = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
6821 if (DECL_P (v))
6823 omp_firstprivatize_variable (ctx, v);
6824 omp_notice_variable (ctx, v, true);
6826 decl = TREE_OPERAND (decl, 0);
6827 if (TREE_CODE (decl) == POINTER_PLUS_EXPR)
6829 if (gimplify_expr (&TREE_OPERAND (decl, 1), pre_p,
6830 NULL, is_gimple_val, fb_rvalue, false)
6831 == GS_ERROR)
6833 remove = true;
6834 break;
6836 v = TREE_OPERAND (decl, 1);
6837 if (DECL_P (v))
6839 omp_firstprivatize_variable (ctx, v);
6840 omp_notice_variable (ctx, v, true);
6842 decl = TREE_OPERAND (decl, 0);
6844 if (TREE_CODE (decl) == ADDR_EXPR
6845 || TREE_CODE (decl) == INDIRECT_REF)
6846 decl = TREE_OPERAND (decl, 0);
6848 goto do_add_decl;
6849 case OMP_CLAUSE_LINEAR:
6850 if (gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c), pre_p, NULL,
6851 is_gimple_val, fb_rvalue) == GS_ERROR)
6853 remove = true;
6854 break;
6856 else
6858 if (code == OMP_SIMD
6859 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
6861 struct gimplify_omp_ctx *octx = outer_ctx;
6862 if (octx
6863 && octx->region_type == ORT_WORKSHARE
6864 && octx->combined_loop
6865 && !octx->distribute)
6867 if (octx->outer_context
6868 && (octx->outer_context->region_type
6869 == ORT_COMBINED_PARALLEL))
6870 octx = octx->outer_context->outer_context;
6871 else
6872 octx = octx->outer_context;
6874 if (octx
6875 && octx->region_type == ORT_WORKSHARE
6876 && octx->combined_loop
6877 && octx->distribute
6878 && !lang_GNU_Fortran ())
6880 error_at (OMP_CLAUSE_LOCATION (c),
6881 "%<linear%> clause for variable other than "
6882 "loop iterator specified on construct "
6883 "combined with %<distribute%>");
6884 remove = true;
6885 break;
6888 /* For combined #pragma omp parallel for simd, need to put
6889 lastprivate and perhaps firstprivate too on the
6890 parallel. Similarly for #pragma omp for simd. */
6891 struct gimplify_omp_ctx *octx = outer_ctx;
6892 decl = NULL_TREE;
6893 if (omp_no_lastprivate (ctx))
6894 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
6897 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
6898 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
6899 break;
6900 decl = OMP_CLAUSE_DECL (c);
6901 if (error_operand_p (decl))
6903 decl = NULL_TREE;
6904 break;
6906 flags = GOVD_SEEN;
6907 if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c))
6908 flags |= GOVD_FIRSTPRIVATE;
6909 if (!OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
6910 flags |= GOVD_LASTPRIVATE;
6911 if (octx
6912 && octx->region_type == ORT_WORKSHARE
6913 && octx->combined_loop)
6915 if (octx->outer_context
6916 && (octx->outer_context->region_type
6917 == ORT_COMBINED_PARALLEL))
6918 octx = octx->outer_context;
6919 else if (omp_check_private (octx, decl, false))
6920 break;
6922 else if (octx
6923 && (octx->region_type & ORT_TASK) != 0
6924 && octx->combined_loop)
6926 else if (octx
6927 && octx->region_type == ORT_COMBINED_PARALLEL
6928 && ctx->region_type == ORT_WORKSHARE
6929 && octx == outer_ctx)
6930 flags = GOVD_SEEN | GOVD_SHARED;
6931 else if (octx
6932 && octx->region_type == ORT_COMBINED_TEAMS)
6933 flags = GOVD_SEEN | GOVD_SHARED;
6934 else if (octx
6935 && octx->region_type == ORT_COMBINED_TARGET)
6937 flags &= ~GOVD_LASTPRIVATE;
6938 if (flags == GOVD_SEEN)
6939 break;
6941 else
6942 break;
6943 splay_tree_node on
6944 = splay_tree_lookup (octx->variables,
6945 (splay_tree_key) decl);
6946 if (on && (on->value & GOVD_DATA_SHARE_CLASS) != 0)
6948 octx = NULL;
6949 break;
6951 omp_add_variable (octx, decl, flags);
6952 if (octx->outer_context == NULL)
6953 break;
6954 octx = octx->outer_context;
6956 while (1);
6957 if (octx
6958 && decl
6959 && (!OMP_CLAUSE_LINEAR_NO_COPYIN (c)
6960 || !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
6961 omp_notice_variable (octx, decl, true);
6963 flags = GOVD_LINEAR | GOVD_EXPLICIT;
6964 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
6965 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
6967 notice_outer = false;
6968 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
6970 goto do_add;
6972 case OMP_CLAUSE_MAP:
6973 decl = OMP_CLAUSE_DECL (c);
6974 if (error_operand_p (decl))
6975 remove = true;
6976 switch (code)
6978 case OMP_TARGET:
6979 break;
6980 case OACC_DATA:
6981 if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
6982 break;
6983 /* FALLTHRU */
6984 case OMP_TARGET_DATA:
6985 case OMP_TARGET_ENTER_DATA:
6986 case OMP_TARGET_EXIT_DATA:
6987 case OACC_ENTER_DATA:
6988 case OACC_EXIT_DATA:
6989 case OACC_HOST_DATA:
6990 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
6991 || (OMP_CLAUSE_MAP_KIND (c)
6992 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
6993 /* For target {,enter ,exit }data only the array slice is
6994 mapped, but not the pointer to it. */
6995 remove = true;
6996 break;
6997 default:
6998 break;
7000 if (remove)
7001 break;
7002 if (DECL_P (decl) && outer_ctx && (region_type & ORT_ACC))
7004 struct gimplify_omp_ctx *octx;
7005 for (octx = outer_ctx; octx; octx = octx->outer_context)
7007 if (octx->region_type != ORT_ACC_HOST_DATA)
7008 break;
7009 splay_tree_node n2
7010 = splay_tree_lookup (octx->variables,
7011 (splay_tree_key) decl);
7012 if (n2)
7013 error_at (OMP_CLAUSE_LOCATION (c), "variable %qE "
7014 "declared in enclosing %<host_data%> region",
7015 DECL_NAME (decl));
7018 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
7019 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
7020 : TYPE_SIZE_UNIT (TREE_TYPE (decl));
7021 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
7022 NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
7024 remove = true;
7025 break;
7027 else if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
7028 || (OMP_CLAUSE_MAP_KIND (c)
7029 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
7030 && TREE_CODE (OMP_CLAUSE_SIZE (c)) != INTEGER_CST)
7032 OMP_CLAUSE_SIZE (c)
7033 = get_initialized_tmp_var (OMP_CLAUSE_SIZE (c), pre_p, NULL,
7034 false);
7035 omp_add_variable (ctx, OMP_CLAUSE_SIZE (c),
7036 GOVD_FIRSTPRIVATE | GOVD_SEEN);
7038 if (!DECL_P (decl))
7040 tree d = decl, *pd;
7041 if (TREE_CODE (d) == ARRAY_REF)
7043 while (TREE_CODE (d) == ARRAY_REF)
7044 d = TREE_OPERAND (d, 0);
7045 if (TREE_CODE (d) == COMPONENT_REF
7046 && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE)
7047 decl = d;
7049 pd = &OMP_CLAUSE_DECL (c);
7050 if (d == decl
7051 && TREE_CODE (decl) == INDIRECT_REF
7052 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
7053 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
7054 == REFERENCE_TYPE))
7056 pd = &TREE_OPERAND (decl, 0);
7057 decl = TREE_OPERAND (decl, 0);
7059 if (TREE_CODE (decl) == COMPONENT_REF)
7061 while (TREE_CODE (decl) == COMPONENT_REF)
7062 decl = TREE_OPERAND (decl, 0);
7063 if (TREE_CODE (decl) == INDIRECT_REF
7064 && DECL_P (TREE_OPERAND (decl, 0))
7065 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
7066 == REFERENCE_TYPE))
7067 decl = TREE_OPERAND (decl, 0);
7069 if (gimplify_expr (pd, pre_p, NULL, is_gimple_lvalue, fb_lvalue)
7070 == GS_ERROR)
7072 remove = true;
7073 break;
7075 if (DECL_P (decl))
7077 if (error_operand_p (decl))
7079 remove = true;
7080 break;
7083 tree stype = TREE_TYPE (decl);
7084 if (TREE_CODE (stype) == REFERENCE_TYPE)
7085 stype = TREE_TYPE (stype);
7086 if (TYPE_SIZE_UNIT (stype) == NULL
7087 || TREE_CODE (TYPE_SIZE_UNIT (stype)) != INTEGER_CST)
7089 error_at (OMP_CLAUSE_LOCATION (c),
7090 "mapping field %qE of variable length "
7091 "structure", OMP_CLAUSE_DECL (c));
7092 remove = true;
7093 break;
7096 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER)
7098 /* Error recovery. */
7099 if (prev_list_p == NULL)
7101 remove = true;
7102 break;
7104 if (OMP_CLAUSE_CHAIN (*prev_list_p) != c)
7106 tree ch = OMP_CLAUSE_CHAIN (*prev_list_p);
7107 if (ch == NULL_TREE || OMP_CLAUSE_CHAIN (ch) != c)
7109 remove = true;
7110 break;
7115 tree offset;
7116 HOST_WIDE_INT bitsize, bitpos;
7117 machine_mode mode;
7118 int unsignedp, reversep, volatilep = 0;
7119 tree base = OMP_CLAUSE_DECL (c);
7120 while (TREE_CODE (base) == ARRAY_REF)
7121 base = TREE_OPERAND (base, 0);
7122 if (TREE_CODE (base) == INDIRECT_REF)
7123 base = TREE_OPERAND (base, 0);
7124 base = get_inner_reference (base, &bitsize, &bitpos, &offset,
7125 &mode, &unsignedp, &reversep,
7126 &volatilep);
7127 tree orig_base = base;
7128 if ((TREE_CODE (base) == INDIRECT_REF
7129 || (TREE_CODE (base) == MEM_REF
7130 && integer_zerop (TREE_OPERAND (base, 1))))
7131 && DECL_P (TREE_OPERAND (base, 0))
7132 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0)))
7133 == REFERENCE_TYPE))
7134 base = TREE_OPERAND (base, 0);
7135 gcc_assert (base == decl
7136 && (offset == NULL_TREE
7137 || TREE_CODE (offset) == INTEGER_CST));
7139 splay_tree_node n
7140 = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7141 bool ptr = (OMP_CLAUSE_MAP_KIND (c)
7142 == GOMP_MAP_ALWAYS_POINTER);
7143 if (n == NULL || (n->value & GOVD_MAP) == 0)
7145 tree l = build_omp_clause (OMP_CLAUSE_LOCATION (c),
7146 OMP_CLAUSE_MAP);
7147 OMP_CLAUSE_SET_MAP_KIND (l, GOMP_MAP_STRUCT);
7148 if (orig_base != base)
7149 OMP_CLAUSE_DECL (l) = unshare_expr (orig_base);
7150 else
7151 OMP_CLAUSE_DECL (l) = decl;
7152 OMP_CLAUSE_SIZE (l) = size_int (1);
7153 if (struct_map_to_clause == NULL)
7154 struct_map_to_clause = new hash_map<tree, tree>;
7155 struct_map_to_clause->put (decl, l);
7156 if (ptr)
7158 enum gomp_map_kind mkind
7159 = code == OMP_TARGET_EXIT_DATA
7160 ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
7161 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
7162 OMP_CLAUSE_MAP);
7163 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
7164 OMP_CLAUSE_DECL (c2)
7165 = unshare_expr (OMP_CLAUSE_DECL (c));
7166 OMP_CLAUSE_CHAIN (c2) = *prev_list_p;
7167 OMP_CLAUSE_SIZE (c2)
7168 = TYPE_SIZE_UNIT (ptr_type_node);
7169 OMP_CLAUSE_CHAIN (l) = c2;
7170 if (OMP_CLAUSE_CHAIN (*prev_list_p) != c)
7172 tree c4 = OMP_CLAUSE_CHAIN (*prev_list_p);
7173 tree c3
7174 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
7175 OMP_CLAUSE_MAP);
7176 OMP_CLAUSE_SET_MAP_KIND (c3, mkind);
7177 OMP_CLAUSE_DECL (c3)
7178 = unshare_expr (OMP_CLAUSE_DECL (c4));
7179 OMP_CLAUSE_SIZE (c3)
7180 = TYPE_SIZE_UNIT (ptr_type_node);
7181 OMP_CLAUSE_CHAIN (c3) = *prev_list_p;
7182 OMP_CLAUSE_CHAIN (c2) = c3;
7184 *prev_list_p = l;
7185 prev_list_p = NULL;
7187 else
7189 OMP_CLAUSE_CHAIN (l) = c;
7190 *list_p = l;
7191 list_p = &OMP_CLAUSE_CHAIN (l);
7193 if (orig_base != base && code == OMP_TARGET)
7195 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
7196 OMP_CLAUSE_MAP);
7197 enum gomp_map_kind mkind
7198 = GOMP_MAP_FIRSTPRIVATE_REFERENCE;
7199 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
7200 OMP_CLAUSE_DECL (c2) = decl;
7201 OMP_CLAUSE_SIZE (c2) = size_zero_node;
7202 OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (l);
7203 OMP_CLAUSE_CHAIN (l) = c2;
7205 flags = GOVD_MAP | GOVD_EXPLICIT;
7206 if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) || ptr)
7207 flags |= GOVD_SEEN;
7208 goto do_add_decl;
7210 else
7212 tree *osc = struct_map_to_clause->get (decl);
7213 tree *sc = NULL, *scp = NULL;
7214 if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) || ptr)
7215 n->value |= GOVD_SEEN;
7216 offset_int o1, o2;
7217 if (offset)
7218 o1 = wi::to_offset (offset);
7219 else
7220 o1 = 0;
7221 if (bitpos)
7222 o1 = o1 + bitpos / BITS_PER_UNIT;
7223 sc = &OMP_CLAUSE_CHAIN (*osc);
7224 if (*sc != c
7225 && (OMP_CLAUSE_MAP_KIND (*sc)
7226 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
7227 sc = &OMP_CLAUSE_CHAIN (*sc);
7228 for (; *sc != c; sc = &OMP_CLAUSE_CHAIN (*sc))
7229 if (ptr && sc == prev_list_p)
7230 break;
7231 else if (TREE_CODE (OMP_CLAUSE_DECL (*sc))
7232 != COMPONENT_REF
7233 && (TREE_CODE (OMP_CLAUSE_DECL (*sc))
7234 != INDIRECT_REF)
7235 && (TREE_CODE (OMP_CLAUSE_DECL (*sc))
7236 != ARRAY_REF))
7237 break;
7238 else
7240 tree offset2;
7241 HOST_WIDE_INT bitsize2, bitpos2;
7242 base = OMP_CLAUSE_DECL (*sc);
7243 if (TREE_CODE (base) == ARRAY_REF)
7245 while (TREE_CODE (base) == ARRAY_REF)
7246 base = TREE_OPERAND (base, 0);
7247 if (TREE_CODE (base) != COMPONENT_REF
7248 || (TREE_CODE (TREE_TYPE (base))
7249 != ARRAY_TYPE))
7250 break;
7252 else if (TREE_CODE (base) == INDIRECT_REF
7253 && (TREE_CODE (TREE_OPERAND (base, 0))
7254 == COMPONENT_REF)
7255 && (TREE_CODE (TREE_TYPE
7256 (TREE_OPERAND (base, 0)))
7257 == REFERENCE_TYPE))
7258 base = TREE_OPERAND (base, 0);
7259 base = get_inner_reference (base, &bitsize2,
7260 &bitpos2, &offset2,
7261 &mode, &unsignedp,
7262 &reversep, &volatilep);
7263 if ((TREE_CODE (base) == INDIRECT_REF
7264 || (TREE_CODE (base) == MEM_REF
7265 && integer_zerop (TREE_OPERAND (base,
7266 1))))
7267 && DECL_P (TREE_OPERAND (base, 0))
7268 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (base,
7269 0)))
7270 == REFERENCE_TYPE))
7271 base = TREE_OPERAND (base, 0);
7272 if (base != decl)
7273 break;
7274 if (scp)
7275 continue;
7276 gcc_assert (offset == NULL_TREE
7277 || TREE_CODE (offset) == INTEGER_CST);
7278 tree d1 = OMP_CLAUSE_DECL (*sc);
7279 tree d2 = OMP_CLAUSE_DECL (c);
7280 while (TREE_CODE (d1) == ARRAY_REF)
7281 d1 = TREE_OPERAND (d1, 0);
7282 while (TREE_CODE (d2) == ARRAY_REF)
7283 d2 = TREE_OPERAND (d2, 0);
7284 if (TREE_CODE (d1) == INDIRECT_REF)
7285 d1 = TREE_OPERAND (d1, 0);
7286 if (TREE_CODE (d2) == INDIRECT_REF)
7287 d2 = TREE_OPERAND (d2, 0);
7288 while (TREE_CODE (d1) == COMPONENT_REF)
7289 if (TREE_CODE (d2) == COMPONENT_REF
7290 && TREE_OPERAND (d1, 1)
7291 == TREE_OPERAND (d2, 1))
7293 d1 = TREE_OPERAND (d1, 0);
7294 d2 = TREE_OPERAND (d2, 0);
7296 else
7297 break;
7298 if (d1 == d2)
7300 error_at (OMP_CLAUSE_LOCATION (c),
7301 "%qE appears more than once in map "
7302 "clauses", OMP_CLAUSE_DECL (c));
7303 remove = true;
7304 break;
7306 if (offset2)
7307 o2 = wi::to_offset (offset2);
7308 else
7309 o2 = 0;
7310 if (bitpos2)
7311 o2 = o2 + bitpos2 / BITS_PER_UNIT;
7312 if (wi::ltu_p (o1, o2)
7313 || (wi::eq_p (o1, o2) && bitpos < bitpos2))
7315 if (ptr)
7316 scp = sc;
7317 else
7318 break;
7321 if (remove)
7322 break;
7323 OMP_CLAUSE_SIZE (*osc)
7324 = size_binop (PLUS_EXPR, OMP_CLAUSE_SIZE (*osc),
7325 size_one_node);
7326 if (ptr)
7328 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
7329 OMP_CLAUSE_MAP);
7330 tree cl = NULL_TREE;
7331 enum gomp_map_kind mkind
7332 = code == OMP_TARGET_EXIT_DATA
7333 ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
7334 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
7335 OMP_CLAUSE_DECL (c2)
7336 = unshare_expr (OMP_CLAUSE_DECL (c));
7337 OMP_CLAUSE_CHAIN (c2) = scp ? *scp : *prev_list_p;
7338 OMP_CLAUSE_SIZE (c2)
7339 = TYPE_SIZE_UNIT (ptr_type_node);
7340 cl = scp ? *prev_list_p : c2;
7341 if (OMP_CLAUSE_CHAIN (*prev_list_p) != c)
7343 tree c4 = OMP_CLAUSE_CHAIN (*prev_list_p);
7344 tree c3
7345 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
7346 OMP_CLAUSE_MAP);
7347 OMP_CLAUSE_SET_MAP_KIND (c3, mkind);
7348 OMP_CLAUSE_DECL (c3)
7349 = unshare_expr (OMP_CLAUSE_DECL (c4));
7350 OMP_CLAUSE_SIZE (c3)
7351 = TYPE_SIZE_UNIT (ptr_type_node);
7352 OMP_CLAUSE_CHAIN (c3) = *prev_list_p;
7353 if (!scp)
7354 OMP_CLAUSE_CHAIN (c2) = c3;
7355 else
7356 cl = c3;
7358 if (scp)
7359 *scp = c2;
7360 if (sc == prev_list_p)
7362 *sc = cl;
7363 prev_list_p = NULL;
7365 else
7367 *prev_list_p = OMP_CLAUSE_CHAIN (c);
7368 list_p = prev_list_p;
7369 prev_list_p = NULL;
7370 OMP_CLAUSE_CHAIN (c) = *sc;
7371 *sc = cl;
7372 continue;
7375 else if (*sc != c)
7377 *list_p = OMP_CLAUSE_CHAIN (c);
7378 OMP_CLAUSE_CHAIN (c) = *sc;
7379 *sc = c;
7380 continue;
7384 if (!remove
7385 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_POINTER
7386 && OMP_CLAUSE_CHAIN (c)
7387 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (c)) == OMP_CLAUSE_MAP
7388 && (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
7389 == GOMP_MAP_ALWAYS_POINTER))
7390 prev_list_p = list_p;
7391 break;
7393 flags = GOVD_MAP | GOVD_EXPLICIT;
7394 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TO
7395 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TOFROM)
7396 flags |= GOVD_MAP_ALWAYS_TO;
7397 goto do_add;
7399 case OMP_CLAUSE_DEPEND:
7400 if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK
7401 || OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
7403 /* Nothing to do. OMP_CLAUSE_DECL will be lowered in
7404 omp-low.c. */
7405 break;
7407 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
7409 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
7410 NULL, is_gimple_val, fb_rvalue);
7411 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
7413 if (error_operand_p (OMP_CLAUSE_DECL (c)))
7415 remove = true;
7416 break;
7418 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
7419 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
7420 is_gimple_val, fb_rvalue) == GS_ERROR)
7422 remove = true;
7423 break;
7425 break;
7427 case OMP_CLAUSE_TO:
7428 case OMP_CLAUSE_FROM:
7429 case OMP_CLAUSE__CACHE_:
7430 decl = OMP_CLAUSE_DECL (c);
7431 if (error_operand_p (decl))
7433 remove = true;
7434 break;
7436 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
7437 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
7438 : TYPE_SIZE_UNIT (TREE_TYPE (decl));
7439 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
7440 NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
7442 remove = true;
7443 break;
7445 if (!DECL_P (decl))
7447 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p,
7448 NULL, is_gimple_lvalue, fb_lvalue)
7449 == GS_ERROR)
7451 remove = true;
7452 break;
7454 break;
7456 goto do_notice;
7458 case OMP_CLAUSE_USE_DEVICE_PTR:
7459 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
7460 goto do_add;
7461 case OMP_CLAUSE_IS_DEVICE_PTR:
7462 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
7463 goto do_add;
7465 do_add:
7466 decl = OMP_CLAUSE_DECL (c);
7467 do_add_decl:
7468 if (error_operand_p (decl))
7470 remove = true;
7471 break;
7473 if (DECL_NAME (decl) == NULL_TREE && (flags & GOVD_SHARED) == 0)
7475 tree t = omp_member_access_dummy_var (decl);
7476 if (t)
7478 tree v = DECL_VALUE_EXPR (decl);
7479 DECL_NAME (decl) = DECL_NAME (TREE_OPERAND (v, 1));
7480 if (outer_ctx)
7481 omp_notice_variable (outer_ctx, t, true);
7484 if (code == OACC_DATA
7485 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
7486 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
7487 flags |= GOVD_MAP_0LEN_ARRAY;
7488 omp_add_variable (ctx, decl, flags);
7489 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
7490 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
7492 omp_add_variable (ctx, OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
7493 GOVD_LOCAL | GOVD_SEEN);
7494 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
7495 && walk_tree (&OMP_CLAUSE_REDUCTION_INIT (c),
7496 find_decl_expr,
7497 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
7498 NULL) == NULL_TREE)
7499 omp_add_variable (ctx,
7500 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
7501 GOVD_LOCAL | GOVD_SEEN);
7502 gimplify_omp_ctxp = ctx;
7503 push_gimplify_context ();
7505 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
7506 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
7508 gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c),
7509 &OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c));
7510 pop_gimplify_context
7511 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c)));
7512 push_gimplify_context ();
7513 gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c),
7514 &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
7515 pop_gimplify_context
7516 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c)));
7517 OMP_CLAUSE_REDUCTION_INIT (c) = NULL_TREE;
7518 OMP_CLAUSE_REDUCTION_MERGE (c) = NULL_TREE;
7520 gimplify_omp_ctxp = outer_ctx;
7522 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
7523 && OMP_CLAUSE_LASTPRIVATE_STMT (c))
7525 gimplify_omp_ctxp = ctx;
7526 push_gimplify_context ();
7527 if (TREE_CODE (OMP_CLAUSE_LASTPRIVATE_STMT (c)) != BIND_EXPR)
7529 tree bind = build3 (BIND_EXPR, void_type_node, NULL,
7530 NULL, NULL);
7531 TREE_SIDE_EFFECTS (bind) = 1;
7532 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LASTPRIVATE_STMT (c);
7533 OMP_CLAUSE_LASTPRIVATE_STMT (c) = bind;
7535 gimplify_and_add (OMP_CLAUSE_LASTPRIVATE_STMT (c),
7536 &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
7537 pop_gimplify_context
7538 (gimple_seq_first_stmt (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c)));
7539 OMP_CLAUSE_LASTPRIVATE_STMT (c) = NULL_TREE;
7541 gimplify_omp_ctxp = outer_ctx;
7543 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
7544 && OMP_CLAUSE_LINEAR_STMT (c))
7546 gimplify_omp_ctxp = ctx;
7547 push_gimplify_context ();
7548 if (TREE_CODE (OMP_CLAUSE_LINEAR_STMT (c)) != BIND_EXPR)
7550 tree bind = build3 (BIND_EXPR, void_type_node, NULL,
7551 NULL, NULL);
7552 TREE_SIDE_EFFECTS (bind) = 1;
7553 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LINEAR_STMT (c);
7554 OMP_CLAUSE_LINEAR_STMT (c) = bind;
7556 gimplify_and_add (OMP_CLAUSE_LINEAR_STMT (c),
7557 &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c));
7558 pop_gimplify_context
7559 (gimple_seq_first_stmt (OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c)));
7560 OMP_CLAUSE_LINEAR_STMT (c) = NULL_TREE;
7562 gimplify_omp_ctxp = outer_ctx;
7564 if (notice_outer)
7565 goto do_notice;
7566 break;
7568 case OMP_CLAUSE_COPYIN:
7569 case OMP_CLAUSE_COPYPRIVATE:
7570 decl = OMP_CLAUSE_DECL (c);
7571 if (error_operand_p (decl))
7573 remove = true;
7574 break;
7576 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_COPYPRIVATE
7577 && !remove
7578 && !omp_check_private (ctx, decl, true))
7580 remove = true;
7581 if (is_global_var (decl))
7583 if (DECL_THREAD_LOCAL_P (decl))
7584 remove = false;
7585 else if (DECL_HAS_VALUE_EXPR_P (decl))
7587 tree value = get_base_address (DECL_VALUE_EXPR (decl));
7589 if (value
7590 && DECL_P (value)
7591 && DECL_THREAD_LOCAL_P (value))
7592 remove = false;
7595 if (remove)
7596 error_at (OMP_CLAUSE_LOCATION (c),
7597 "copyprivate variable %qE is not threadprivate"
7598 " or private in outer context", DECL_NAME (decl));
7600 do_notice:
7601 if (outer_ctx)
7602 omp_notice_variable (outer_ctx, decl, true);
7603 if (check_non_private
7604 && region_type == ORT_WORKSHARE
7605 && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
7606 || decl == OMP_CLAUSE_DECL (c)
7607 || (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
7608 && (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
7609 == ADDR_EXPR
7610 || (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
7611 == POINTER_PLUS_EXPR
7612 && (TREE_CODE (TREE_OPERAND (TREE_OPERAND
7613 (OMP_CLAUSE_DECL (c), 0), 0))
7614 == ADDR_EXPR)))))
7615 && omp_check_private (ctx, decl, false))
7617 error ("%s variable %qE is private in outer context",
7618 check_non_private, DECL_NAME (decl));
7619 remove = true;
7621 break;
7623 case OMP_CLAUSE_IF:
7624 if (OMP_CLAUSE_IF_MODIFIER (c) != ERROR_MARK
7625 && OMP_CLAUSE_IF_MODIFIER (c) != code)
7627 const char *p[2];
7628 for (int i = 0; i < 2; i++)
7629 switch (i ? OMP_CLAUSE_IF_MODIFIER (c) : code)
7631 case OMP_PARALLEL: p[i] = "parallel"; break;
7632 case OMP_TASK: p[i] = "task"; break;
7633 case OMP_TASKLOOP: p[i] = "taskloop"; break;
7634 case OMP_TARGET_DATA: p[i] = "target data"; break;
7635 case OMP_TARGET: p[i] = "target"; break;
7636 case OMP_TARGET_UPDATE: p[i] = "target update"; break;
7637 case OMP_TARGET_ENTER_DATA:
7638 p[i] = "target enter data"; break;
7639 case OMP_TARGET_EXIT_DATA: p[i] = "target exit data"; break;
7640 default: gcc_unreachable ();
7642 error_at (OMP_CLAUSE_LOCATION (c),
7643 "expected %qs %<if%> clause modifier rather than %qs",
7644 p[0], p[1]);
7645 remove = true;
7647 /* Fall through. */
7649 case OMP_CLAUSE_FINAL:
7650 OMP_CLAUSE_OPERAND (c, 0)
7651 = gimple_boolify (OMP_CLAUSE_OPERAND (c, 0));
7652 /* Fall through. */
7654 case OMP_CLAUSE_SCHEDULE:
7655 case OMP_CLAUSE_NUM_THREADS:
7656 case OMP_CLAUSE_NUM_TEAMS:
7657 case OMP_CLAUSE_THREAD_LIMIT:
7658 case OMP_CLAUSE_DIST_SCHEDULE:
7659 case OMP_CLAUSE_DEVICE:
7660 case OMP_CLAUSE_PRIORITY:
7661 case OMP_CLAUSE_GRAINSIZE:
7662 case OMP_CLAUSE_NUM_TASKS:
7663 case OMP_CLAUSE_HINT:
7664 case OMP_CLAUSE__CILK_FOR_COUNT_:
7665 case OMP_CLAUSE_ASYNC:
7666 case OMP_CLAUSE_WAIT:
7667 case OMP_CLAUSE_NUM_GANGS:
7668 case OMP_CLAUSE_NUM_WORKERS:
7669 case OMP_CLAUSE_VECTOR_LENGTH:
7670 case OMP_CLAUSE_WORKER:
7671 case OMP_CLAUSE_VECTOR:
7672 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
7673 is_gimple_val, fb_rvalue) == GS_ERROR)
7674 remove = true;
7675 break;
7677 case OMP_CLAUSE_GANG:
7678 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
7679 is_gimple_val, fb_rvalue) == GS_ERROR)
7680 remove = true;
7681 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 1), pre_p, NULL,
7682 is_gimple_val, fb_rvalue) == GS_ERROR)
7683 remove = true;
7684 break;
7686 case OMP_CLAUSE_TILE:
7687 for (tree list = OMP_CLAUSE_TILE_LIST (c); !remove && list;
7688 list = TREE_CHAIN (list))
7690 if (gimplify_expr (&TREE_VALUE (list), pre_p, NULL,
7691 is_gimple_val, fb_rvalue) == GS_ERROR)
7692 remove = true;
7694 break;
7696 case OMP_CLAUSE_NOWAIT:
7697 case OMP_CLAUSE_ORDERED:
7698 case OMP_CLAUSE_UNTIED:
7699 case OMP_CLAUSE_COLLAPSE:
7700 case OMP_CLAUSE_AUTO:
7701 case OMP_CLAUSE_SEQ:
7702 case OMP_CLAUSE_INDEPENDENT:
7703 case OMP_CLAUSE_MERGEABLE:
7704 case OMP_CLAUSE_PROC_BIND:
7705 case OMP_CLAUSE_SAFELEN:
7706 case OMP_CLAUSE_SIMDLEN:
7707 case OMP_CLAUSE_NOGROUP:
7708 case OMP_CLAUSE_THREADS:
7709 case OMP_CLAUSE_SIMD:
7710 break;
7712 case OMP_CLAUSE_DEFAULTMAP:
7713 ctx->target_map_scalars_firstprivate = false;
7714 break;
7716 case OMP_CLAUSE_ALIGNED:
7717 decl = OMP_CLAUSE_DECL (c);
7718 if (error_operand_p (decl))
7720 remove = true;
7721 break;
7723 if (gimplify_expr (&OMP_CLAUSE_ALIGNED_ALIGNMENT (c), pre_p, NULL,
7724 is_gimple_val, fb_rvalue) == GS_ERROR)
7726 remove = true;
7727 break;
7729 if (!is_global_var (decl)
7730 && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
7731 omp_add_variable (ctx, decl, GOVD_ALIGNED);
7732 break;
7734 case OMP_CLAUSE_DEFAULT:
7735 ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
7736 break;
7738 default:
7739 gcc_unreachable ();
7742 if (code == OACC_DATA
7743 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
7744 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
7745 remove = true;
7746 if (remove)
7747 *list_p = OMP_CLAUSE_CHAIN (c);
7748 else
7749 list_p = &OMP_CLAUSE_CHAIN (c);
7752 gimplify_omp_ctxp = ctx;
7753 if (struct_map_to_clause)
7754 delete struct_map_to_clause;
7757 /* Return true if DECL is a candidate for shared to firstprivate
7758 optimization. We only consider non-addressable scalars, not
7759 too big, and not references. */
7761 static bool
7762 omp_shared_to_firstprivate_optimizable_decl_p (tree decl)
7764 if (TREE_ADDRESSABLE (decl))
7765 return false;
7766 tree type = TREE_TYPE (decl);
7767 if (!is_gimple_reg_type (type)
7768 || TREE_CODE (type) == REFERENCE_TYPE
7769 || TREE_ADDRESSABLE (type))
7770 return false;
7771 /* Don't optimize too large decls, as each thread/task will have
7772 its own. */
7773 HOST_WIDE_INT len = int_size_in_bytes (type);
7774 if (len == -1 || len > 4 * POINTER_SIZE / BITS_PER_UNIT)
7775 return false;
7776 if (lang_hooks.decls.omp_privatize_by_reference (decl))
7777 return false;
7778 return true;
7781 /* Helper function of omp_find_stores_op and gimplify_adjust_omp_clauses*.
7782 For omp_shared_to_firstprivate_optimizable_decl_p decl mark it as
7783 GOVD_WRITTEN in outer contexts. */
7785 static void
7786 omp_mark_stores (struct gimplify_omp_ctx *ctx, tree decl)
7788 for (; ctx; ctx = ctx->outer_context)
7790 splay_tree_node n = splay_tree_lookup (ctx->variables,
7791 (splay_tree_key) decl);
7792 if (n == NULL)
7793 continue;
7794 else if (n->value & GOVD_SHARED)
7796 n->value |= GOVD_WRITTEN;
7797 return;
7799 else if (n->value & GOVD_DATA_SHARE_CLASS)
7800 return;
7804 /* Helper callback for walk_gimple_seq to discover possible stores
7805 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
7806 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
7807 for those. */
7809 static tree
7810 omp_find_stores_op (tree *tp, int *walk_subtrees, void *data)
7812 struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
7814 *walk_subtrees = 0;
7815 if (!wi->is_lhs)
7816 return NULL_TREE;
7818 tree op = *tp;
7821 if (handled_component_p (op))
7822 op = TREE_OPERAND (op, 0);
7823 else if ((TREE_CODE (op) == MEM_REF || TREE_CODE (op) == TARGET_MEM_REF)
7824 && TREE_CODE (TREE_OPERAND (op, 0)) == ADDR_EXPR)
7825 op = TREE_OPERAND (TREE_OPERAND (op, 0), 0);
7826 else
7827 break;
7829 while (1);
7830 if (!DECL_P (op) || !omp_shared_to_firstprivate_optimizable_decl_p (op))
7831 return NULL_TREE;
7833 omp_mark_stores (gimplify_omp_ctxp, op);
7834 return NULL_TREE;
7837 /* Helper callback for walk_gimple_seq to discover possible stores
7838 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
7839 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
7840 for those. */
7842 static tree
7843 omp_find_stores_stmt (gimple_stmt_iterator *gsi_p,
7844 bool *handled_ops_p,
7845 struct walk_stmt_info *wi)
7847 gimple *stmt = gsi_stmt (*gsi_p);
7848 switch (gimple_code (stmt))
7850 /* Don't recurse on OpenMP constructs for which
7851 gimplify_adjust_omp_clauses already handled the bodies,
7852 except handle gimple_omp_for_pre_body. */
7853 case GIMPLE_OMP_FOR:
7854 *handled_ops_p = true;
7855 if (gimple_omp_for_pre_body (stmt))
7856 walk_gimple_seq (gimple_omp_for_pre_body (stmt),
7857 omp_find_stores_stmt, omp_find_stores_op, wi);
7858 break;
7859 case GIMPLE_OMP_PARALLEL:
7860 case GIMPLE_OMP_TASK:
7861 case GIMPLE_OMP_SECTIONS:
7862 case GIMPLE_OMP_SINGLE:
7863 case GIMPLE_OMP_TARGET:
7864 case GIMPLE_OMP_TEAMS:
7865 case GIMPLE_OMP_CRITICAL:
7866 *handled_ops_p = true;
7867 break;
7868 default:
7869 break;
7871 return NULL_TREE;
7874 struct gimplify_adjust_omp_clauses_data
7876 tree *list_p;
7877 gimple_seq *pre_p;
7880 /* For all variables that were not actually used within the context,
7881 remove PRIVATE, SHARED, and FIRSTPRIVATE clauses. */
7883 static int
7884 gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
7886 tree *list_p = ((struct gimplify_adjust_omp_clauses_data *) data)->list_p;
7887 gimple_seq *pre_p
7888 = ((struct gimplify_adjust_omp_clauses_data *) data)->pre_p;
7889 tree decl = (tree) n->key;
7890 unsigned flags = n->value;
7891 enum omp_clause_code code;
7892 tree clause;
7893 bool private_debug;
7895 if (flags & (GOVD_EXPLICIT | GOVD_LOCAL))
7896 return 0;
7897 if ((flags & GOVD_SEEN) == 0)
7898 return 0;
7899 if (flags & GOVD_DEBUG_PRIVATE)
7901 gcc_assert ((flags & GOVD_DATA_SHARE_CLASS) == GOVD_PRIVATE);
7902 private_debug = true;
7904 else if (flags & GOVD_MAP)
7905 private_debug = false;
7906 else
7907 private_debug
7908 = lang_hooks.decls.omp_private_debug_clause (decl,
7909 !!(flags & GOVD_SHARED));
7910 if (private_debug)
7911 code = OMP_CLAUSE_PRIVATE;
7912 else if (flags & GOVD_MAP)
7913 code = OMP_CLAUSE_MAP;
7914 else if (flags & GOVD_SHARED)
7916 if (is_global_var (decl))
7918 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
7919 while (ctx != NULL)
7921 splay_tree_node on
7922 = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
7923 if (on && (on->value & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
7924 | GOVD_PRIVATE | GOVD_REDUCTION
7925 | GOVD_LINEAR | GOVD_MAP)) != 0)
7926 break;
7927 ctx = ctx->outer_context;
7929 if (ctx == NULL)
7930 return 0;
7932 code = OMP_CLAUSE_SHARED;
7934 else if (flags & GOVD_PRIVATE)
7935 code = OMP_CLAUSE_PRIVATE;
7936 else if (flags & GOVD_FIRSTPRIVATE)
7937 code = OMP_CLAUSE_FIRSTPRIVATE;
7938 else if (flags & GOVD_LASTPRIVATE)
7939 code = OMP_CLAUSE_LASTPRIVATE;
7940 else if (flags & GOVD_ALIGNED)
7941 return 0;
7942 else
7943 gcc_unreachable ();
7945 if (((flags & GOVD_LASTPRIVATE)
7946 || (code == OMP_CLAUSE_SHARED && (flags & GOVD_WRITTEN)))
7947 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
7948 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
7950 clause = build_omp_clause (input_location, code);
7951 OMP_CLAUSE_DECL (clause) = decl;
7952 OMP_CLAUSE_CHAIN (clause) = *list_p;
7953 if (private_debug)
7954 OMP_CLAUSE_PRIVATE_DEBUG (clause) = 1;
7955 else if (code == OMP_CLAUSE_PRIVATE && (flags & GOVD_PRIVATE_OUTER_REF))
7956 OMP_CLAUSE_PRIVATE_OUTER_REF (clause) = 1;
7957 else if (code == OMP_CLAUSE_SHARED
7958 && (flags & GOVD_WRITTEN) == 0
7959 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
7960 OMP_CLAUSE_SHARED_READONLY (clause) = 1;
7961 else if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_EXPLICIT) == 0)
7962 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (clause) = 1;
7963 else if (code == OMP_CLAUSE_MAP && (flags & GOVD_MAP_0LEN_ARRAY) != 0)
7965 tree nc = build_omp_clause (input_location, OMP_CLAUSE_MAP);
7966 OMP_CLAUSE_DECL (nc) = decl;
7967 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
7968 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == POINTER_TYPE)
7969 OMP_CLAUSE_DECL (clause)
7970 = build_simple_mem_ref_loc (input_location, decl);
7971 OMP_CLAUSE_DECL (clause)
7972 = build2 (MEM_REF, char_type_node, OMP_CLAUSE_DECL (clause),
7973 build_int_cst (build_pointer_type (char_type_node), 0));
7974 OMP_CLAUSE_SIZE (clause) = size_zero_node;
7975 OMP_CLAUSE_SIZE (nc) = size_zero_node;
7976 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_ALLOC);
7977 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (clause) = 1;
7978 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
7979 OMP_CLAUSE_CHAIN (nc) = *list_p;
7980 OMP_CLAUSE_CHAIN (clause) = nc;
7981 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
7982 gimplify_omp_ctxp = ctx->outer_context;
7983 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (clause), 0),
7984 pre_p, NULL, is_gimple_val, fb_rvalue);
7985 gimplify_omp_ctxp = ctx;
7987 else if (code == OMP_CLAUSE_MAP)
7989 int kind = (flags & GOVD_MAP_TO_ONLY
7990 ? GOMP_MAP_TO
7991 : GOMP_MAP_TOFROM);
7992 if (flags & GOVD_MAP_FORCE)
7993 kind |= GOMP_MAP_FLAG_FORCE;
7994 OMP_CLAUSE_SET_MAP_KIND (clause, kind);
7995 if (DECL_SIZE (decl)
7996 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
7998 tree decl2 = DECL_VALUE_EXPR (decl);
7999 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
8000 decl2 = TREE_OPERAND (decl2, 0);
8001 gcc_assert (DECL_P (decl2));
8002 tree mem = build_simple_mem_ref (decl2);
8003 OMP_CLAUSE_DECL (clause) = mem;
8004 OMP_CLAUSE_SIZE (clause) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
8005 if (gimplify_omp_ctxp->outer_context)
8007 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
8008 omp_notice_variable (ctx, decl2, true);
8009 omp_notice_variable (ctx, OMP_CLAUSE_SIZE (clause), true);
8011 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
8012 OMP_CLAUSE_MAP);
8013 OMP_CLAUSE_DECL (nc) = decl;
8014 OMP_CLAUSE_SIZE (nc) = size_zero_node;
8015 if (gimplify_omp_ctxp->target_firstprivatize_array_bases)
8016 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
8017 else
8018 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
8019 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
8020 OMP_CLAUSE_CHAIN (clause) = nc;
8022 else if (gimplify_omp_ctxp->target_firstprivatize_array_bases
8023 && lang_hooks.decls.omp_privatize_by_reference (decl))
8025 OMP_CLAUSE_DECL (clause) = build_simple_mem_ref (decl);
8026 OMP_CLAUSE_SIZE (clause)
8027 = unshare_expr (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))));
8028 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
8029 gimplify_omp_ctxp = ctx->outer_context;
8030 gimplify_expr (&OMP_CLAUSE_SIZE (clause),
8031 pre_p, NULL, is_gimple_val, fb_rvalue);
8032 gimplify_omp_ctxp = ctx;
8033 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
8034 OMP_CLAUSE_MAP);
8035 OMP_CLAUSE_DECL (nc) = decl;
8036 OMP_CLAUSE_SIZE (nc) = size_zero_node;
8037 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_REFERENCE);
8038 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
8039 OMP_CLAUSE_CHAIN (clause) = nc;
8041 else
8042 OMP_CLAUSE_SIZE (clause) = DECL_SIZE_UNIT (decl);
8044 if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_LASTPRIVATE) != 0)
8046 tree nc = build_omp_clause (input_location, OMP_CLAUSE_LASTPRIVATE);
8047 OMP_CLAUSE_DECL (nc) = decl;
8048 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (nc) = 1;
8049 OMP_CLAUSE_CHAIN (nc) = *list_p;
8050 OMP_CLAUSE_CHAIN (clause) = nc;
8051 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
8052 gimplify_omp_ctxp = ctx->outer_context;
8053 lang_hooks.decls.omp_finish_clause (nc, pre_p);
8054 gimplify_omp_ctxp = ctx;
8056 *list_p = clause;
8057 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
8058 gimplify_omp_ctxp = ctx->outer_context;
8059 lang_hooks.decls.omp_finish_clause (clause, pre_p);
8060 gimplify_omp_ctxp = ctx;
8061 return 0;
8064 static void
8065 gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
8066 enum tree_code code)
8068 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
8069 tree c, decl;
8071 if (body)
8073 struct gimplify_omp_ctx *octx;
8074 for (octx = ctx; octx; octx = octx->outer_context)
8075 if ((octx->region_type & (ORT_PARALLEL | ORT_TASK | ORT_TEAMS)) != 0)
8076 break;
8077 if (octx)
8079 struct walk_stmt_info wi;
8080 memset (&wi, 0, sizeof (wi));
8081 walk_gimple_seq (body, omp_find_stores_stmt,
8082 omp_find_stores_op, &wi);
8085 while ((c = *list_p) != NULL)
8087 splay_tree_node n;
8088 bool remove = false;
8090 switch (OMP_CLAUSE_CODE (c))
8092 case OMP_CLAUSE_PRIVATE:
8093 case OMP_CLAUSE_SHARED:
8094 case OMP_CLAUSE_FIRSTPRIVATE:
8095 case OMP_CLAUSE_LINEAR:
8096 decl = OMP_CLAUSE_DECL (c);
8097 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
8098 remove = !(n->value & GOVD_SEEN);
8099 if (! remove)
8101 bool shared = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED;
8102 if ((n->value & GOVD_DEBUG_PRIVATE)
8103 || lang_hooks.decls.omp_private_debug_clause (decl, shared))
8105 gcc_assert ((n->value & GOVD_DEBUG_PRIVATE) == 0
8106 || ((n->value & GOVD_DATA_SHARE_CLASS)
8107 == GOVD_PRIVATE));
8108 OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_PRIVATE);
8109 OMP_CLAUSE_PRIVATE_DEBUG (c) = 1;
8111 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
8112 && (n->value & GOVD_WRITTEN) == 0
8113 && DECL_P (decl)
8114 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
8115 OMP_CLAUSE_SHARED_READONLY (c) = 1;
8116 else if (DECL_P (decl)
8117 && ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
8118 && (n->value & GOVD_WRITTEN) != 1)
8119 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
8120 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
8121 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
8122 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
8124 break;
8126 case OMP_CLAUSE_LASTPRIVATE:
8127 /* Make sure OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE is set to
8128 accurately reflect the presence of a FIRSTPRIVATE clause. */
8129 decl = OMP_CLAUSE_DECL (c);
8130 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
8131 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c)
8132 = (n->value & GOVD_FIRSTPRIVATE) != 0;
8133 if (omp_no_lastprivate (ctx))
8135 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
8136 remove = true;
8137 else
8138 OMP_CLAUSE_CODE (c) = OMP_CLAUSE_PRIVATE;
8140 else if (code == OMP_DISTRIBUTE
8141 && OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
8143 remove = true;
8144 error_at (OMP_CLAUSE_LOCATION (c),
8145 "same variable used in %<firstprivate%> and "
8146 "%<lastprivate%> clauses on %<distribute%> "
8147 "construct");
8149 if (!remove
8150 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
8151 && DECL_P (decl)
8152 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
8153 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
8154 break;
8156 case OMP_CLAUSE_ALIGNED:
8157 decl = OMP_CLAUSE_DECL (c);
8158 if (!is_global_var (decl))
8160 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
8161 remove = n == NULL || !(n->value & GOVD_SEEN);
8162 if (!remove && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
8164 struct gimplify_omp_ctx *octx;
8165 if (n != NULL
8166 && (n->value & (GOVD_DATA_SHARE_CLASS
8167 & ~GOVD_FIRSTPRIVATE)))
8168 remove = true;
8169 else
8170 for (octx = ctx->outer_context; octx;
8171 octx = octx->outer_context)
8173 n = splay_tree_lookup (octx->variables,
8174 (splay_tree_key) decl);
8175 if (n == NULL)
8176 continue;
8177 if (n->value & GOVD_LOCAL)
8178 break;
8179 /* We have to avoid assigning a shared variable
8180 to itself when trying to add
8181 __builtin_assume_aligned. */
8182 if (n->value & GOVD_SHARED)
8184 remove = true;
8185 break;
8190 else if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
8192 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
8193 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
8194 remove = true;
8196 break;
8198 case OMP_CLAUSE_MAP:
8199 if (code == OMP_TARGET_EXIT_DATA
8200 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER)
8202 remove = true;
8203 break;
8205 decl = OMP_CLAUSE_DECL (c);
8206 /* Data clauses associated with acc parallel reductions must be
8207 compatible with present_or_copy. Warn and adjust the clause
8208 if that is not the case. */
8209 if (ctx->region_type == ORT_ACC_PARALLEL)
8211 tree t = DECL_P (decl) ? decl : TREE_OPERAND (decl, 0);
8212 n = NULL;
8214 if (DECL_P (t))
8215 n = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
8217 if (n && (n->value & GOVD_REDUCTION))
8219 enum gomp_map_kind kind = OMP_CLAUSE_MAP_KIND (c);
8221 OMP_CLAUSE_MAP_IN_REDUCTION (c) = 1;
8222 if ((kind & GOMP_MAP_TOFROM) != GOMP_MAP_TOFROM
8223 && kind != GOMP_MAP_FORCE_PRESENT
8224 && kind != GOMP_MAP_POINTER)
8226 warning_at (OMP_CLAUSE_LOCATION (c), 0,
8227 "incompatible data clause with reduction "
8228 "on %qE; promoting to present_or_copy",
8229 DECL_NAME (t));
8230 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TOFROM);
8234 if (!DECL_P (decl))
8236 if ((ctx->region_type & ORT_TARGET) != 0
8237 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
8239 if (TREE_CODE (decl) == INDIRECT_REF
8240 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
8241 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
8242 == REFERENCE_TYPE))
8243 decl = TREE_OPERAND (decl, 0);
8244 if (TREE_CODE (decl) == COMPONENT_REF)
8246 while (TREE_CODE (decl) == COMPONENT_REF)
8247 decl = TREE_OPERAND (decl, 0);
8248 if (DECL_P (decl))
8250 n = splay_tree_lookup (ctx->variables,
8251 (splay_tree_key) decl);
8252 if (!(n->value & GOVD_SEEN))
8253 remove = true;
8257 break;
8259 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
8260 if ((ctx->region_type & ORT_TARGET) != 0
8261 && !(n->value & GOVD_SEEN)
8262 && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) == 0
8263 && !lookup_attribute ("omp declare target link",
8264 DECL_ATTRIBUTES (decl)))
8266 remove = true;
8267 /* For struct element mapping, if struct is never referenced
8268 in target block and none of the mapping has always modifier,
8269 remove all the struct element mappings, which immediately
8270 follow the GOMP_MAP_STRUCT map clause. */
8271 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT)
8273 HOST_WIDE_INT cnt = tree_to_shwi (OMP_CLAUSE_SIZE (c));
8274 while (cnt--)
8275 OMP_CLAUSE_CHAIN (c)
8276 = OMP_CLAUSE_CHAIN (OMP_CLAUSE_CHAIN (c));
8279 else if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT
8280 && code == OMP_TARGET_EXIT_DATA)
8281 remove = true;
8282 else if (DECL_SIZE (decl)
8283 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST
8284 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_POINTER
8285 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_POINTER
8286 && (OMP_CLAUSE_MAP_KIND (c)
8287 != GOMP_MAP_FIRSTPRIVATE_REFERENCE))
8289 /* For GOMP_MAP_FORCE_DEVICEPTR, we'll never enter here, because
8290 for these, TREE_CODE (DECL_SIZE (decl)) will always be
8291 INTEGER_CST. */
8292 gcc_assert (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FORCE_DEVICEPTR);
8294 tree decl2 = DECL_VALUE_EXPR (decl);
8295 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
8296 decl2 = TREE_OPERAND (decl2, 0);
8297 gcc_assert (DECL_P (decl2));
8298 tree mem = build_simple_mem_ref (decl2);
8299 OMP_CLAUSE_DECL (c) = mem;
8300 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
8301 if (ctx->outer_context)
8303 omp_notice_variable (ctx->outer_context, decl2, true);
8304 omp_notice_variable (ctx->outer_context,
8305 OMP_CLAUSE_SIZE (c), true);
8307 if (((ctx->region_type & ORT_TARGET) != 0
8308 || !ctx->target_firstprivatize_array_bases)
8309 && ((n->value & GOVD_SEEN) == 0
8310 || (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) == 0))
8312 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
8313 OMP_CLAUSE_MAP);
8314 OMP_CLAUSE_DECL (nc) = decl;
8315 OMP_CLAUSE_SIZE (nc) = size_zero_node;
8316 if (ctx->target_firstprivatize_array_bases)
8317 OMP_CLAUSE_SET_MAP_KIND (nc,
8318 GOMP_MAP_FIRSTPRIVATE_POINTER);
8319 else
8320 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
8321 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
8322 OMP_CLAUSE_CHAIN (c) = nc;
8323 c = nc;
8326 else
8328 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
8329 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
8330 gcc_assert ((n->value & GOVD_SEEN) == 0
8331 || ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
8332 == 0));
8334 break;
8336 case OMP_CLAUSE_TO:
8337 case OMP_CLAUSE_FROM:
8338 case OMP_CLAUSE__CACHE_:
8339 decl = OMP_CLAUSE_DECL (c);
8340 if (!DECL_P (decl))
8341 break;
8342 if (DECL_SIZE (decl)
8343 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
8345 tree decl2 = DECL_VALUE_EXPR (decl);
8346 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
8347 decl2 = TREE_OPERAND (decl2, 0);
8348 gcc_assert (DECL_P (decl2));
8349 tree mem = build_simple_mem_ref (decl2);
8350 OMP_CLAUSE_DECL (c) = mem;
8351 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
8352 if (ctx->outer_context)
8354 omp_notice_variable (ctx->outer_context, decl2, true);
8355 omp_notice_variable (ctx->outer_context,
8356 OMP_CLAUSE_SIZE (c), true);
8359 else if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
8360 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
8361 break;
8363 case OMP_CLAUSE_REDUCTION:
8364 decl = OMP_CLAUSE_DECL (c);
8365 /* OpenACC reductions need a present_or_copy data clause.
8366 Add one if necessary. Error is the reduction is private. */
8367 if (ctx->region_type == ORT_ACC_PARALLEL)
8369 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
8370 if (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
8371 error_at (OMP_CLAUSE_LOCATION (c), "invalid private "
8372 "reduction on %qE", DECL_NAME (decl));
8373 else if ((n->value & GOVD_MAP) == 0)
8375 tree next = OMP_CLAUSE_CHAIN (c);
8376 tree nc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_MAP);
8377 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_TOFROM);
8378 OMP_CLAUSE_DECL (nc) = decl;
8379 OMP_CLAUSE_CHAIN (c) = nc;
8380 lang_hooks.decls.omp_finish_clause (nc, pre_p);
8381 while (1)
8383 OMP_CLAUSE_MAP_IN_REDUCTION (nc) = 1;
8384 if (OMP_CLAUSE_CHAIN (nc) == NULL)
8385 break;
8386 nc = OMP_CLAUSE_CHAIN (nc);
8388 OMP_CLAUSE_CHAIN (nc) = next;
8389 n->value |= GOVD_MAP;
8392 if (DECL_P (decl)
8393 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
8394 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
8395 break;
8396 case OMP_CLAUSE_COPYIN:
8397 case OMP_CLAUSE_COPYPRIVATE:
8398 case OMP_CLAUSE_IF:
8399 case OMP_CLAUSE_NUM_THREADS:
8400 case OMP_CLAUSE_NUM_TEAMS:
8401 case OMP_CLAUSE_THREAD_LIMIT:
8402 case OMP_CLAUSE_DIST_SCHEDULE:
8403 case OMP_CLAUSE_DEVICE:
8404 case OMP_CLAUSE_SCHEDULE:
8405 case OMP_CLAUSE_NOWAIT:
8406 case OMP_CLAUSE_ORDERED:
8407 case OMP_CLAUSE_DEFAULT:
8408 case OMP_CLAUSE_UNTIED:
8409 case OMP_CLAUSE_COLLAPSE:
8410 case OMP_CLAUSE_FINAL:
8411 case OMP_CLAUSE_MERGEABLE:
8412 case OMP_CLAUSE_PROC_BIND:
8413 case OMP_CLAUSE_SAFELEN:
8414 case OMP_CLAUSE_SIMDLEN:
8415 case OMP_CLAUSE_DEPEND:
8416 case OMP_CLAUSE_PRIORITY:
8417 case OMP_CLAUSE_GRAINSIZE:
8418 case OMP_CLAUSE_NUM_TASKS:
8419 case OMP_CLAUSE_NOGROUP:
8420 case OMP_CLAUSE_THREADS:
8421 case OMP_CLAUSE_SIMD:
8422 case OMP_CLAUSE_HINT:
8423 case OMP_CLAUSE_DEFAULTMAP:
8424 case OMP_CLAUSE_USE_DEVICE_PTR:
8425 case OMP_CLAUSE_IS_DEVICE_PTR:
8426 case OMP_CLAUSE__CILK_FOR_COUNT_:
8427 case OMP_CLAUSE_ASYNC:
8428 case OMP_CLAUSE_WAIT:
8429 case OMP_CLAUSE_INDEPENDENT:
8430 case OMP_CLAUSE_NUM_GANGS:
8431 case OMP_CLAUSE_NUM_WORKERS:
8432 case OMP_CLAUSE_VECTOR_LENGTH:
8433 case OMP_CLAUSE_GANG:
8434 case OMP_CLAUSE_WORKER:
8435 case OMP_CLAUSE_VECTOR:
8436 case OMP_CLAUSE_AUTO:
8437 case OMP_CLAUSE_SEQ:
8438 break;
8440 case OMP_CLAUSE_TILE:
8441 /* We're not yet making use of the information provided by OpenACC
8442 tile clauses. Discard these here, to simplify later middle end
8443 processing. */
8444 remove = true;
8445 break;
8447 default:
8448 gcc_unreachable ();
8451 if (remove)
8452 *list_p = OMP_CLAUSE_CHAIN (c);
8453 else
8454 list_p = &OMP_CLAUSE_CHAIN (c);
8457 /* Add in any implicit data sharing. */
8458 struct gimplify_adjust_omp_clauses_data data;
8459 data.list_p = list_p;
8460 data.pre_p = pre_p;
8461 splay_tree_foreach (ctx->variables, gimplify_adjust_omp_clauses_1, &data);
8463 gimplify_omp_ctxp = ctx->outer_context;
8464 delete_omp_context (ctx);
8467 /* Gimplify OACC_CACHE. */
8469 static void
8470 gimplify_oacc_cache (tree *expr_p, gimple_seq *pre_p)
8472 tree expr = *expr_p;
8474 gimplify_scan_omp_clauses (&OACC_CACHE_CLAUSES (expr), pre_p, ORT_ACC,
8475 OACC_CACHE);
8476 gimplify_adjust_omp_clauses (pre_p, NULL, &OACC_CACHE_CLAUSES (expr),
8477 OACC_CACHE);
8479 /* TODO: Do something sensible with this information. */
8481 *expr_p = NULL_TREE;
8484 /* Helper function of gimplify_oacc_declare. The helper's purpose is to,
8485 if required, translate 'kind' in CLAUSE into an 'entry' kind and 'exit'
8486 kind. The entry kind will replace the one in CLAUSE, while the exit
8487 kind will be used in a new omp_clause and returned to the caller. */
8489 static tree
8490 gimplify_oacc_declare_1 (tree clause)
8492 HOST_WIDE_INT kind, new_op;
8493 bool ret = false;
8494 tree c = NULL;
8496 kind = OMP_CLAUSE_MAP_KIND (clause);
8498 switch (kind)
8500 case GOMP_MAP_ALLOC:
8501 case GOMP_MAP_FORCE_ALLOC:
8502 case GOMP_MAP_FORCE_TO:
8503 new_op = GOMP_MAP_DELETE;
8504 ret = true;
8505 break;
8507 case GOMP_MAP_FORCE_FROM:
8508 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_FORCE_ALLOC);
8509 new_op = GOMP_MAP_FORCE_FROM;
8510 ret = true;
8511 break;
8513 case GOMP_MAP_FORCE_TOFROM:
8514 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_FORCE_TO);
8515 new_op = GOMP_MAP_FORCE_FROM;
8516 ret = true;
8517 break;
8519 case GOMP_MAP_FROM:
8520 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_FORCE_ALLOC);
8521 new_op = GOMP_MAP_FROM;
8522 ret = true;
8523 break;
8525 case GOMP_MAP_TOFROM:
8526 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_TO);
8527 new_op = GOMP_MAP_FROM;
8528 ret = true;
8529 break;
8531 case GOMP_MAP_DEVICE_RESIDENT:
8532 case GOMP_MAP_FORCE_DEVICEPTR:
8533 case GOMP_MAP_FORCE_PRESENT:
8534 case GOMP_MAP_LINK:
8535 case GOMP_MAP_POINTER:
8536 case GOMP_MAP_TO:
8537 break;
8539 default:
8540 gcc_unreachable ();
8541 break;
8544 if (ret)
8546 c = build_omp_clause (OMP_CLAUSE_LOCATION (clause), OMP_CLAUSE_MAP);
8547 OMP_CLAUSE_SET_MAP_KIND (c, new_op);
8548 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clause);
8551 return c;
8554 /* Gimplify OACC_DECLARE. */
8556 static void
8557 gimplify_oacc_declare (tree *expr_p, gimple_seq *pre_p)
8559 tree expr = *expr_p;
8560 gomp_target *stmt;
8561 tree clauses, t;
8563 clauses = OACC_DECLARE_CLAUSES (expr);
8565 gimplify_scan_omp_clauses (&clauses, pre_p, ORT_TARGET_DATA, OACC_DECLARE);
8567 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
8569 tree decl = OMP_CLAUSE_DECL (t);
8571 if (TREE_CODE (decl) == MEM_REF)
8572 continue;
8574 if (TREE_CODE (decl) == VAR_DECL
8575 && !is_global_var (decl)
8576 && DECL_CONTEXT (decl) == current_function_decl)
8578 tree c = gimplify_oacc_declare_1 (t);
8579 if (c)
8581 if (oacc_declare_returns == NULL)
8582 oacc_declare_returns = new hash_map<tree, tree>;
8584 oacc_declare_returns->put (decl, c);
8588 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_SEEN);
8591 stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
8592 clauses);
8594 gimplify_seq_add_stmt (pre_p, stmt);
8596 *expr_p = NULL_TREE;
8599 /* Gimplify the contents of an OMP_PARALLEL statement. This involves
8600 gimplification of the body, as well as scanning the body for used
8601 variables. We need to do this scan now, because variable-sized
8602 decls will be decomposed during gimplification. */
8604 static void
8605 gimplify_omp_parallel (tree *expr_p, gimple_seq *pre_p)
8607 tree expr = *expr_p;
8608 gimple *g;
8609 gimple_seq body = NULL;
8611 gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr), pre_p,
8612 OMP_PARALLEL_COMBINED (expr)
8613 ? ORT_COMBINED_PARALLEL
8614 : ORT_PARALLEL, OMP_PARALLEL);
8616 push_gimplify_context ();
8618 g = gimplify_and_return_first (OMP_PARALLEL_BODY (expr), &body);
8619 if (gimple_code (g) == GIMPLE_BIND)
8620 pop_gimplify_context (g);
8621 else
8622 pop_gimplify_context (NULL);
8624 gimplify_adjust_omp_clauses (pre_p, body, &OMP_PARALLEL_CLAUSES (expr),
8625 OMP_PARALLEL);
8627 g = gimple_build_omp_parallel (body,
8628 OMP_PARALLEL_CLAUSES (expr),
8629 NULL_TREE, NULL_TREE);
8630 if (OMP_PARALLEL_COMBINED (expr))
8631 gimple_omp_set_subcode (g, GF_OMP_PARALLEL_COMBINED);
8632 gimplify_seq_add_stmt (pre_p, g);
8633 *expr_p = NULL_TREE;
8636 /* Gimplify the contents of an OMP_TASK statement. This involves
8637 gimplification of the body, as well as scanning the body for used
8638 variables. We need to do this scan now, because variable-sized
8639 decls will be decomposed during gimplification. */
8641 static void
8642 gimplify_omp_task (tree *expr_p, gimple_seq *pre_p)
8644 tree expr = *expr_p;
8645 gimple *g;
8646 gimple_seq body = NULL;
8648 gimplify_scan_omp_clauses (&OMP_TASK_CLAUSES (expr), pre_p,
8649 find_omp_clause (OMP_TASK_CLAUSES (expr),
8650 OMP_CLAUSE_UNTIED)
8651 ? ORT_UNTIED_TASK : ORT_TASK, OMP_TASK);
8653 push_gimplify_context ();
8655 g = gimplify_and_return_first (OMP_TASK_BODY (expr), &body);
8656 if (gimple_code (g) == GIMPLE_BIND)
8657 pop_gimplify_context (g);
8658 else
8659 pop_gimplify_context (NULL);
8661 gimplify_adjust_omp_clauses (pre_p, body, &OMP_TASK_CLAUSES (expr),
8662 OMP_TASK);
8664 g = gimple_build_omp_task (body,
8665 OMP_TASK_CLAUSES (expr),
8666 NULL_TREE, NULL_TREE,
8667 NULL_TREE, NULL_TREE, NULL_TREE);
8668 gimplify_seq_add_stmt (pre_p, g);
8669 *expr_p = NULL_TREE;
8672 /* Helper function of gimplify_omp_for, find OMP_FOR resp. OMP_SIMD
8673 with non-NULL OMP_FOR_INIT. */
8675 static tree
8676 find_combined_omp_for (tree *tp, int *walk_subtrees, void *)
8678 *walk_subtrees = 0;
8679 switch (TREE_CODE (*tp))
8681 case OMP_FOR:
8682 *walk_subtrees = 1;
8683 /* FALLTHRU */
8684 case OMP_SIMD:
8685 if (OMP_FOR_INIT (*tp) != NULL_TREE)
8686 return *tp;
8687 break;
8688 case BIND_EXPR:
8689 case STATEMENT_LIST:
8690 case OMP_PARALLEL:
8691 *walk_subtrees = 1;
8692 break;
8693 default:
8694 break;
8696 return NULL_TREE;
8699 /* Gimplify the gross structure of an OMP_FOR statement. */
8701 static enum gimplify_status
8702 gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
8704 tree for_stmt, orig_for_stmt, inner_for_stmt = NULL_TREE, decl, var, t;
8705 enum gimplify_status ret = GS_ALL_DONE;
8706 enum gimplify_status tret;
8707 gomp_for *gfor;
8708 gimple_seq for_body, for_pre_body;
8709 int i;
8710 bitmap has_decl_expr = NULL;
8711 enum omp_region_type ort = ORT_WORKSHARE;
8713 orig_for_stmt = for_stmt = *expr_p;
8715 switch (TREE_CODE (for_stmt))
8717 case OMP_FOR:
8718 case CILK_FOR:
8719 case OMP_DISTRIBUTE:
8720 break;
8721 case OACC_LOOP:
8722 ort = ORT_ACC;
8723 break;
8724 case OMP_TASKLOOP:
8725 if (find_omp_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_UNTIED))
8726 ort = ORT_UNTIED_TASK;
8727 else
8728 ort = ORT_TASK;
8729 break;
8730 case OMP_SIMD:
8731 case CILK_SIMD:
8732 ort = ORT_SIMD;
8733 break;
8734 default:
8735 gcc_unreachable ();
8738 /* Set OMP_CLAUSE_LINEAR_NO_COPYIN flag on explicit linear
8739 clause for the IV. */
8740 if (ort == ORT_SIMD && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
8742 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), 0);
8743 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
8744 decl = TREE_OPERAND (t, 0);
8745 for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
8746 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
8747 && OMP_CLAUSE_DECL (c) == decl)
8749 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
8750 break;
8754 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
8756 gcc_assert (TREE_CODE (for_stmt) != OACC_LOOP);
8757 inner_for_stmt = walk_tree (&OMP_FOR_BODY (for_stmt),
8758 find_combined_omp_for, NULL, NULL);
8759 if (inner_for_stmt == NULL_TREE)
8761 gcc_assert (seen_error ());
8762 *expr_p = NULL_TREE;
8763 return GS_ERROR;
8767 if (TREE_CODE (for_stmt) != OMP_TASKLOOP)
8768 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p, ort,
8769 TREE_CODE (for_stmt));
8771 if (TREE_CODE (for_stmt) == OMP_DISTRIBUTE)
8772 gimplify_omp_ctxp->distribute = true;
8774 /* Handle OMP_FOR_INIT. */
8775 for_pre_body = NULL;
8776 if (ort == ORT_SIMD && OMP_FOR_PRE_BODY (for_stmt))
8778 has_decl_expr = BITMAP_ALLOC (NULL);
8779 if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == DECL_EXPR
8780 && TREE_CODE (DECL_EXPR_DECL (OMP_FOR_PRE_BODY (for_stmt)))
8781 == VAR_DECL)
8783 t = OMP_FOR_PRE_BODY (for_stmt);
8784 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
8786 else if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == STATEMENT_LIST)
8788 tree_stmt_iterator si;
8789 for (si = tsi_start (OMP_FOR_PRE_BODY (for_stmt)); !tsi_end_p (si);
8790 tsi_next (&si))
8792 t = tsi_stmt (si);
8793 if (TREE_CODE (t) == DECL_EXPR
8794 && TREE_CODE (DECL_EXPR_DECL (t)) == VAR_DECL)
8795 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
8799 if (OMP_FOR_PRE_BODY (for_stmt))
8801 if (TREE_CODE (for_stmt) != OMP_TASKLOOP || gimplify_omp_ctxp)
8802 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
8803 else
8805 struct gimplify_omp_ctx ctx;
8806 memset (&ctx, 0, sizeof (ctx));
8807 ctx.region_type = ORT_NONE;
8808 gimplify_omp_ctxp = &ctx;
8809 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
8810 gimplify_omp_ctxp = NULL;
8813 OMP_FOR_PRE_BODY (for_stmt) = NULL_TREE;
8815 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
8816 for_stmt = inner_for_stmt;
8818 /* For taskloop, need to gimplify the start, end and step before the
8819 taskloop, outside of the taskloop omp context. */
8820 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
8822 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
8824 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
8825 if (!is_gimple_constant (TREE_OPERAND (t, 1)))
8827 TREE_OPERAND (t, 1)
8828 = get_initialized_tmp_var (TREE_OPERAND (t, 1),
8829 pre_p, NULL, false);
8830 tree c = build_omp_clause (input_location,
8831 OMP_CLAUSE_FIRSTPRIVATE);
8832 OMP_CLAUSE_DECL (c) = TREE_OPERAND (t, 1);
8833 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
8834 OMP_FOR_CLAUSES (orig_for_stmt) = c;
8837 /* Handle OMP_FOR_COND. */
8838 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
8839 if (!is_gimple_constant (TREE_OPERAND (t, 1)))
8841 TREE_OPERAND (t, 1)
8842 = get_initialized_tmp_var (TREE_OPERAND (t, 1),
8843 gimple_seq_empty_p (for_pre_body)
8844 ? pre_p : &for_pre_body, NULL,
8845 false);
8846 tree c = build_omp_clause (input_location,
8847 OMP_CLAUSE_FIRSTPRIVATE);
8848 OMP_CLAUSE_DECL (c) = TREE_OPERAND (t, 1);
8849 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
8850 OMP_FOR_CLAUSES (orig_for_stmt) = c;
8853 /* Handle OMP_FOR_INCR. */
8854 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
8855 if (TREE_CODE (t) == MODIFY_EXPR)
8857 decl = TREE_OPERAND (t, 0);
8858 t = TREE_OPERAND (t, 1);
8859 tree *tp = &TREE_OPERAND (t, 1);
8860 if (TREE_CODE (t) == PLUS_EXPR && *tp == decl)
8861 tp = &TREE_OPERAND (t, 0);
8863 if (!is_gimple_constant (*tp))
8865 gimple_seq *seq = gimple_seq_empty_p (for_pre_body)
8866 ? pre_p : &for_pre_body;
8867 *tp = get_initialized_tmp_var (*tp, seq, NULL, false);
8868 tree c = build_omp_clause (input_location,
8869 OMP_CLAUSE_FIRSTPRIVATE);
8870 OMP_CLAUSE_DECL (c) = *tp;
8871 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
8872 OMP_FOR_CLAUSES (orig_for_stmt) = c;
8877 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (orig_for_stmt), pre_p, ort,
8878 OMP_TASKLOOP);
8881 if (orig_for_stmt != for_stmt)
8882 gimplify_omp_ctxp->combined_loop = true;
8884 for_body = NULL;
8885 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
8886 == TREE_VEC_LENGTH (OMP_FOR_COND (for_stmt)));
8887 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
8888 == TREE_VEC_LENGTH (OMP_FOR_INCR (for_stmt)));
8890 tree c = find_omp_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED);
8891 bool is_doacross = false;
8892 if (c && OMP_CLAUSE_ORDERED_EXPR (c))
8894 is_doacross = true;
8895 gimplify_omp_ctxp->loop_iter_var.create (TREE_VEC_LENGTH
8896 (OMP_FOR_INIT (for_stmt))
8897 * 2);
8899 int collapse = 1;
8900 c = find_omp_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_COLLAPSE);
8901 if (c)
8902 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (c));
8903 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
8905 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
8906 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
8907 decl = TREE_OPERAND (t, 0);
8908 gcc_assert (DECL_P (decl));
8909 gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl))
8910 || POINTER_TYPE_P (TREE_TYPE (decl)));
8911 if (is_doacross)
8913 if (TREE_CODE (for_stmt) == OMP_FOR && OMP_FOR_ORIG_DECLS (for_stmt))
8914 gimplify_omp_ctxp->loop_iter_var.quick_push
8915 (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i));
8916 else
8917 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
8918 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
8921 /* Make sure the iteration variable is private. */
8922 tree c = NULL_TREE;
8923 tree c2 = NULL_TREE;
8924 if (orig_for_stmt != for_stmt)
8925 /* Do this only on innermost construct for combined ones. */;
8926 else if (ort == ORT_SIMD)
8928 splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
8929 (splay_tree_key) decl);
8930 omp_is_private (gimplify_omp_ctxp, decl,
8931 1 + (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
8932 != 1));
8933 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
8934 omp_notice_variable (gimplify_omp_ctxp, decl, true);
8935 else if (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
8937 c = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
8938 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
8939 unsigned int flags = GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN;
8940 if ((has_decl_expr
8941 && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
8942 || omp_no_lastprivate (gimplify_omp_ctxp))
8944 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
8945 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
8947 struct gimplify_omp_ctx *outer
8948 = gimplify_omp_ctxp->outer_context;
8949 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
8951 if (outer->region_type == ORT_WORKSHARE
8952 && outer->combined_loop)
8954 n = splay_tree_lookup (outer->variables,
8955 (splay_tree_key)decl);
8956 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
8958 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
8959 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
8961 else
8963 struct gimplify_omp_ctx *octx = outer->outer_context;
8964 if (octx
8965 && octx->region_type == ORT_COMBINED_PARALLEL
8966 && octx->outer_context
8967 && (octx->outer_context->region_type
8968 == ORT_WORKSHARE)
8969 && octx->outer_context->combined_loop)
8971 octx = octx->outer_context;
8972 n = splay_tree_lookup (octx->variables,
8973 (splay_tree_key)decl);
8974 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
8976 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
8977 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
8984 OMP_CLAUSE_DECL (c) = decl;
8985 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
8986 OMP_FOR_CLAUSES (for_stmt) = c;
8987 omp_add_variable (gimplify_omp_ctxp, decl, flags);
8988 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
8990 if (outer->region_type == ORT_WORKSHARE
8991 && outer->combined_loop)
8993 if (outer->outer_context
8994 && (outer->outer_context->region_type
8995 == ORT_COMBINED_PARALLEL))
8996 outer = outer->outer_context;
8997 else if (omp_check_private (outer, decl, false))
8998 outer = NULL;
9000 else if (((outer->region_type & ORT_TASK) != 0)
9001 && outer->combined_loop
9002 && !omp_check_private (gimplify_omp_ctxp,
9003 decl, false))
9005 else if (outer->region_type != ORT_COMBINED_PARALLEL)
9007 omp_notice_variable (outer, decl, true);
9008 outer = NULL;
9010 if (outer)
9012 n = splay_tree_lookup (outer->variables,
9013 (splay_tree_key)decl);
9014 if (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
9016 omp_add_variable (outer, decl,
9017 GOVD_LASTPRIVATE | GOVD_SEEN);
9018 if (outer->region_type == ORT_COMBINED_PARALLEL
9019 && outer->outer_context
9020 && (outer->outer_context->region_type
9021 == ORT_WORKSHARE)
9022 && outer->outer_context->combined_loop)
9024 outer = outer->outer_context;
9025 n = splay_tree_lookup (outer->variables,
9026 (splay_tree_key)decl);
9027 if (omp_check_private (outer, decl, false))
9028 outer = NULL;
9029 else if (n == NULL
9030 || ((n->value & GOVD_DATA_SHARE_CLASS)
9031 == 0))
9032 omp_add_variable (outer, decl,
9033 GOVD_LASTPRIVATE
9034 | GOVD_SEEN);
9035 else
9036 outer = NULL;
9038 if (outer && outer->outer_context
9039 && (outer->outer_context->region_type
9040 == ORT_COMBINED_TEAMS))
9042 outer = outer->outer_context;
9043 n = splay_tree_lookup (outer->variables,
9044 (splay_tree_key)decl);
9045 if (n == NULL
9046 || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
9047 omp_add_variable (outer, decl,
9048 GOVD_SHARED | GOVD_SEEN);
9049 else
9050 outer = NULL;
9052 if (outer && outer->outer_context)
9053 omp_notice_variable (outer->outer_context, decl,
9054 true);
9059 else
9061 bool lastprivate
9062 = (!has_decl_expr
9063 || !bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
9064 && !omp_no_lastprivate (gimplify_omp_ctxp);
9065 struct gimplify_omp_ctx *outer
9066 = gimplify_omp_ctxp->outer_context;
9067 if (outer && lastprivate)
9069 if (outer->region_type == ORT_WORKSHARE
9070 && outer->combined_loop)
9072 n = splay_tree_lookup (outer->variables,
9073 (splay_tree_key)decl);
9074 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
9076 lastprivate = false;
9077 outer = NULL;
9079 else if (outer->outer_context
9080 && (outer->outer_context->region_type
9081 == ORT_COMBINED_PARALLEL))
9082 outer = outer->outer_context;
9083 else if (omp_check_private (outer, decl, false))
9084 outer = NULL;
9086 else if (((outer->region_type & ORT_TASK) != 0)
9087 && outer->combined_loop
9088 && !omp_check_private (gimplify_omp_ctxp,
9089 decl, false))
9091 else if (outer->region_type != ORT_COMBINED_PARALLEL)
9093 omp_notice_variable (outer, decl, true);
9094 outer = NULL;
9096 if (outer)
9098 n = splay_tree_lookup (outer->variables,
9099 (splay_tree_key)decl);
9100 if (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
9102 omp_add_variable (outer, decl,
9103 GOVD_LASTPRIVATE | GOVD_SEEN);
9104 if (outer->region_type == ORT_COMBINED_PARALLEL
9105 && outer->outer_context
9106 && (outer->outer_context->region_type
9107 == ORT_WORKSHARE)
9108 && outer->outer_context->combined_loop)
9110 outer = outer->outer_context;
9111 n = splay_tree_lookup (outer->variables,
9112 (splay_tree_key)decl);
9113 if (omp_check_private (outer, decl, false))
9114 outer = NULL;
9115 else if (n == NULL
9116 || ((n->value & GOVD_DATA_SHARE_CLASS)
9117 == 0))
9118 omp_add_variable (outer, decl,
9119 GOVD_LASTPRIVATE
9120 | GOVD_SEEN);
9121 else
9122 outer = NULL;
9124 if (outer && outer->outer_context
9125 && (outer->outer_context->region_type
9126 == ORT_COMBINED_TEAMS))
9128 outer = outer->outer_context;
9129 n = splay_tree_lookup (outer->variables,
9130 (splay_tree_key)decl);
9131 if (n == NULL
9132 || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
9133 omp_add_variable (outer, decl,
9134 GOVD_SHARED | GOVD_SEEN);
9135 else
9136 outer = NULL;
9138 if (outer && outer->outer_context)
9139 omp_notice_variable (outer->outer_context, decl,
9140 true);
9145 c = build_omp_clause (input_location,
9146 lastprivate ? OMP_CLAUSE_LASTPRIVATE
9147 : OMP_CLAUSE_PRIVATE);
9148 OMP_CLAUSE_DECL (c) = decl;
9149 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
9150 OMP_FOR_CLAUSES (for_stmt) = c;
9151 omp_add_variable (gimplify_omp_ctxp, decl,
9152 (lastprivate ? GOVD_LASTPRIVATE : GOVD_PRIVATE)
9153 | GOVD_EXPLICIT | GOVD_SEEN);
9154 c = NULL_TREE;
9157 else if (omp_is_private (gimplify_omp_ctxp, decl, 0))
9158 omp_notice_variable (gimplify_omp_ctxp, decl, true);
9159 else
9160 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN);
9162 /* If DECL is not a gimple register, create a temporary variable to act
9163 as an iteration counter. This is valid, since DECL cannot be
9164 modified in the body of the loop. Similarly for any iteration vars
9165 in simd with collapse > 1 where the iterator vars must be
9166 lastprivate. */
9167 if (orig_for_stmt != for_stmt)
9168 var = decl;
9169 else if (!is_gimple_reg (decl)
9170 || (ort == ORT_SIMD
9171 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) > 1))
9173 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
9174 /* Make sure omp_add_variable is not called on it prematurely.
9175 We call it ourselves a few lines later. */
9176 gimplify_omp_ctxp = NULL;
9177 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
9178 gimplify_omp_ctxp = ctx;
9179 TREE_OPERAND (t, 0) = var;
9181 gimplify_seq_add_stmt (&for_body, gimple_build_assign (decl, var));
9183 if (ort == ORT_SIMD
9184 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
9186 c2 = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
9187 OMP_CLAUSE_LINEAR_NO_COPYIN (c2) = 1;
9188 OMP_CLAUSE_LINEAR_NO_COPYOUT (c2) = 1;
9189 OMP_CLAUSE_DECL (c2) = var;
9190 OMP_CLAUSE_CHAIN (c2) = OMP_FOR_CLAUSES (for_stmt);
9191 OMP_FOR_CLAUSES (for_stmt) = c2;
9192 omp_add_variable (gimplify_omp_ctxp, var,
9193 GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN);
9194 if (c == NULL_TREE)
9196 c = c2;
9197 c2 = NULL_TREE;
9200 else
9201 omp_add_variable (gimplify_omp_ctxp, var,
9202 GOVD_PRIVATE | GOVD_SEEN);
9204 else
9205 var = decl;
9207 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
9208 is_gimple_val, fb_rvalue, false);
9209 ret = MIN (ret, tret);
9210 if (ret == GS_ERROR)
9211 return ret;
9213 /* Handle OMP_FOR_COND. */
9214 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
9215 gcc_assert (COMPARISON_CLASS_P (t));
9216 gcc_assert (TREE_OPERAND (t, 0) == decl);
9218 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
9219 is_gimple_val, fb_rvalue, false);
9220 ret = MIN (ret, tret);
9222 /* Handle OMP_FOR_INCR. */
9223 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
9224 switch (TREE_CODE (t))
9226 case PREINCREMENT_EXPR:
9227 case POSTINCREMENT_EXPR:
9229 tree decl = TREE_OPERAND (t, 0);
9230 /* c_omp_for_incr_canonicalize_ptr() should have been
9231 called to massage things appropriately. */
9232 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
9234 if (orig_for_stmt != for_stmt)
9235 break;
9236 t = build_int_cst (TREE_TYPE (decl), 1);
9237 if (c)
9238 OMP_CLAUSE_LINEAR_STEP (c) = t;
9239 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
9240 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
9241 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
9242 break;
9245 case PREDECREMENT_EXPR:
9246 case POSTDECREMENT_EXPR:
9247 /* c_omp_for_incr_canonicalize_ptr() should have been
9248 called to massage things appropriately. */
9249 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
9250 if (orig_for_stmt != for_stmt)
9251 break;
9252 t = build_int_cst (TREE_TYPE (decl), -1);
9253 if (c)
9254 OMP_CLAUSE_LINEAR_STEP (c) = t;
9255 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
9256 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
9257 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
9258 break;
9260 case MODIFY_EXPR:
9261 gcc_assert (TREE_OPERAND (t, 0) == decl);
9262 TREE_OPERAND (t, 0) = var;
9264 t = TREE_OPERAND (t, 1);
9265 switch (TREE_CODE (t))
9267 case PLUS_EXPR:
9268 if (TREE_OPERAND (t, 1) == decl)
9270 TREE_OPERAND (t, 1) = TREE_OPERAND (t, 0);
9271 TREE_OPERAND (t, 0) = var;
9272 break;
9275 /* Fallthru. */
9276 case MINUS_EXPR:
9277 case POINTER_PLUS_EXPR:
9278 gcc_assert (TREE_OPERAND (t, 0) == decl);
9279 TREE_OPERAND (t, 0) = var;
9280 break;
9281 default:
9282 gcc_unreachable ();
9285 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
9286 is_gimple_val, fb_rvalue, false);
9287 ret = MIN (ret, tret);
9288 if (c)
9290 tree step = TREE_OPERAND (t, 1);
9291 tree stept = TREE_TYPE (decl);
9292 if (POINTER_TYPE_P (stept))
9293 stept = sizetype;
9294 step = fold_convert (stept, step);
9295 if (TREE_CODE (t) == MINUS_EXPR)
9296 step = fold_build1 (NEGATE_EXPR, stept, step);
9297 OMP_CLAUSE_LINEAR_STEP (c) = step;
9298 if (step != TREE_OPERAND (t, 1))
9300 tret = gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c),
9301 &for_pre_body, NULL,
9302 is_gimple_val, fb_rvalue, false);
9303 ret = MIN (ret, tret);
9306 break;
9308 default:
9309 gcc_unreachable ();
9312 if (c2)
9314 gcc_assert (c);
9315 OMP_CLAUSE_LINEAR_STEP (c2) = OMP_CLAUSE_LINEAR_STEP (c);
9318 if ((var != decl || collapse > 1) && orig_for_stmt == for_stmt)
9320 for (c = OMP_FOR_CLAUSES (for_stmt); c ; c = OMP_CLAUSE_CHAIN (c))
9321 if (((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
9322 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) == NULL)
9323 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
9324 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)
9325 && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c) == NULL))
9326 && OMP_CLAUSE_DECL (c) == decl)
9328 if (is_doacross && (collapse == 1 || i >= collapse))
9329 t = var;
9330 else
9332 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
9333 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
9334 gcc_assert (TREE_OPERAND (t, 0) == var);
9335 t = TREE_OPERAND (t, 1);
9336 gcc_assert (TREE_CODE (t) == PLUS_EXPR
9337 || TREE_CODE (t) == MINUS_EXPR
9338 || TREE_CODE (t) == POINTER_PLUS_EXPR);
9339 gcc_assert (TREE_OPERAND (t, 0) == var);
9340 t = build2 (TREE_CODE (t), TREE_TYPE (decl),
9341 is_doacross ? var : decl,
9342 TREE_OPERAND (t, 1));
9344 gimple_seq *seq;
9345 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
9346 seq = &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c);
9347 else
9348 seq = &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c);
9349 gimplify_assign (decl, t, seq);
9354 BITMAP_FREE (has_decl_expr);
9356 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
9358 push_gimplify_context ();
9359 if (TREE_CODE (OMP_FOR_BODY (orig_for_stmt)) != BIND_EXPR)
9361 OMP_FOR_BODY (orig_for_stmt)
9362 = build3 (BIND_EXPR, void_type_node, NULL,
9363 OMP_FOR_BODY (orig_for_stmt), NULL);
9364 TREE_SIDE_EFFECTS (OMP_FOR_BODY (orig_for_stmt)) = 1;
9368 gimple *g = gimplify_and_return_first (OMP_FOR_BODY (orig_for_stmt),
9369 &for_body);
9371 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
9373 if (gimple_code (g) == GIMPLE_BIND)
9374 pop_gimplify_context (g);
9375 else
9376 pop_gimplify_context (NULL);
9379 if (orig_for_stmt != for_stmt)
9380 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
9382 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
9383 decl = TREE_OPERAND (t, 0);
9384 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
9385 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
9386 gimplify_omp_ctxp = ctx->outer_context;
9387 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
9388 gimplify_omp_ctxp = ctx;
9389 omp_add_variable (gimplify_omp_ctxp, var, GOVD_PRIVATE | GOVD_SEEN);
9390 TREE_OPERAND (t, 0) = var;
9391 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
9392 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
9393 TREE_OPERAND (TREE_OPERAND (t, 1), 0) = var;
9396 gimplify_adjust_omp_clauses (pre_p, for_body,
9397 &OMP_FOR_CLAUSES (orig_for_stmt),
9398 TREE_CODE (orig_for_stmt));
9400 int kind;
9401 switch (TREE_CODE (orig_for_stmt))
9403 case OMP_FOR: kind = GF_OMP_FOR_KIND_FOR; break;
9404 case OMP_SIMD: kind = GF_OMP_FOR_KIND_SIMD; break;
9405 case CILK_SIMD: kind = GF_OMP_FOR_KIND_CILKSIMD; break;
9406 case CILK_FOR: kind = GF_OMP_FOR_KIND_CILKFOR; break;
9407 case OMP_DISTRIBUTE: kind = GF_OMP_FOR_KIND_DISTRIBUTE; break;
9408 case OMP_TASKLOOP: kind = GF_OMP_FOR_KIND_TASKLOOP; break;
9409 case OACC_LOOP: kind = GF_OMP_FOR_KIND_OACC_LOOP; break;
9410 default:
9411 gcc_unreachable ();
9413 gfor = gimple_build_omp_for (for_body, kind, OMP_FOR_CLAUSES (orig_for_stmt),
9414 TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)),
9415 for_pre_body);
9416 if (orig_for_stmt != for_stmt)
9417 gimple_omp_for_set_combined_p (gfor, true);
9418 if (gimplify_omp_ctxp
9419 && (gimplify_omp_ctxp->combined_loop
9420 || (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
9421 && gimplify_omp_ctxp->outer_context
9422 && gimplify_omp_ctxp->outer_context->combined_loop)))
9424 gimple_omp_for_set_combined_into_p (gfor, true);
9425 if (gimplify_omp_ctxp->combined_loop)
9426 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_SIMD);
9427 else
9428 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_FOR);
9431 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
9433 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
9434 gimple_omp_for_set_index (gfor, i, TREE_OPERAND (t, 0));
9435 gimple_omp_for_set_initial (gfor, i, TREE_OPERAND (t, 1));
9436 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
9437 gimple_omp_for_set_cond (gfor, i, TREE_CODE (t));
9438 gimple_omp_for_set_final (gfor, i, TREE_OPERAND (t, 1));
9439 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
9440 gimple_omp_for_set_incr (gfor, i, TREE_OPERAND (t, 1));
9443 /* OMP_TASKLOOP is gimplified as two GIMPLE_OMP_FOR taskloop
9444 constructs with GIMPLE_OMP_TASK sandwiched in between them.
9445 The outer taskloop stands for computing the number of iterations,
9446 counts for collapsed loops and holding taskloop specific clauses.
9447 The task construct stands for the effect of data sharing on the
9448 explicit task it creates and the inner taskloop stands for expansion
9449 of the static loop inside of the explicit task construct. */
9450 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
9452 tree *gfor_clauses_ptr = gimple_omp_for_clauses_ptr (gfor);
9453 tree task_clauses = NULL_TREE;
9454 tree c = *gfor_clauses_ptr;
9455 tree *gtask_clauses_ptr = &task_clauses;
9456 tree outer_for_clauses = NULL_TREE;
9457 tree *gforo_clauses_ptr = &outer_for_clauses;
9458 for (; c; c = OMP_CLAUSE_CHAIN (c))
9459 switch (OMP_CLAUSE_CODE (c))
9461 /* These clauses are allowed on task, move them there. */
9462 case OMP_CLAUSE_SHARED:
9463 case OMP_CLAUSE_FIRSTPRIVATE:
9464 case OMP_CLAUSE_DEFAULT:
9465 case OMP_CLAUSE_IF:
9466 case OMP_CLAUSE_UNTIED:
9467 case OMP_CLAUSE_FINAL:
9468 case OMP_CLAUSE_MERGEABLE:
9469 case OMP_CLAUSE_PRIORITY:
9470 *gtask_clauses_ptr = c;
9471 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
9472 break;
9473 case OMP_CLAUSE_PRIVATE:
9474 if (OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c))
9476 /* We want private on outer for and firstprivate
9477 on task. */
9478 *gtask_clauses_ptr
9479 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9480 OMP_CLAUSE_FIRSTPRIVATE);
9481 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
9482 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL);
9483 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
9484 *gforo_clauses_ptr = c;
9485 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
9487 else
9489 *gtask_clauses_ptr = c;
9490 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
9492 break;
9493 /* These clauses go into outer taskloop clauses. */
9494 case OMP_CLAUSE_GRAINSIZE:
9495 case OMP_CLAUSE_NUM_TASKS:
9496 case OMP_CLAUSE_NOGROUP:
9497 *gforo_clauses_ptr = c;
9498 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
9499 break;
9500 /* Taskloop clause we duplicate on both taskloops. */
9501 case OMP_CLAUSE_COLLAPSE:
9502 *gfor_clauses_ptr = c;
9503 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
9504 *gforo_clauses_ptr = copy_node (c);
9505 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
9506 break;
9507 /* For lastprivate, keep the clause on inner taskloop, and add
9508 a shared clause on task. If the same decl is also firstprivate,
9509 add also firstprivate clause on the inner taskloop. */
9510 case OMP_CLAUSE_LASTPRIVATE:
9511 if (OMP_CLAUSE_LASTPRIVATE_TASKLOOP_IV (c))
9513 /* For taskloop C++ lastprivate IVs, we want:
9514 1) private on outer taskloop
9515 2) firstprivate and shared on task
9516 3) lastprivate on inner taskloop */
9517 *gtask_clauses_ptr
9518 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9519 OMP_CLAUSE_FIRSTPRIVATE);
9520 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
9521 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL);
9522 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
9523 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c) = 1;
9524 *gforo_clauses_ptr = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9525 OMP_CLAUSE_PRIVATE);
9526 OMP_CLAUSE_DECL (*gforo_clauses_ptr) = OMP_CLAUSE_DECL (c);
9527 OMP_CLAUSE_PRIVATE_TASKLOOP_IV (*gforo_clauses_ptr) = 1;
9528 TREE_TYPE (*gforo_clauses_ptr) = TREE_TYPE (c);
9529 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
9531 *gfor_clauses_ptr = c;
9532 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
9533 *gtask_clauses_ptr
9534 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_SHARED);
9535 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
9536 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
9537 OMP_CLAUSE_SHARED_FIRSTPRIVATE (*gtask_clauses_ptr) = 1;
9538 gtask_clauses_ptr
9539 = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
9540 break;
9541 default:
9542 gcc_unreachable ();
9544 *gfor_clauses_ptr = NULL_TREE;
9545 *gtask_clauses_ptr = NULL_TREE;
9546 *gforo_clauses_ptr = NULL_TREE;
9547 g = gimple_build_bind (NULL_TREE, gfor, NULL_TREE);
9548 g = gimple_build_omp_task (g, task_clauses, NULL_TREE, NULL_TREE,
9549 NULL_TREE, NULL_TREE, NULL_TREE);
9550 gimple_omp_task_set_taskloop_p (g, true);
9551 g = gimple_build_bind (NULL_TREE, g, NULL_TREE);
9552 gomp_for *gforo
9553 = gimple_build_omp_for (g, GF_OMP_FOR_KIND_TASKLOOP, outer_for_clauses,
9554 gimple_omp_for_collapse (gfor),
9555 gimple_omp_for_pre_body (gfor));
9556 gimple_omp_for_set_pre_body (gfor, NULL);
9557 gimple_omp_for_set_combined_p (gforo, true);
9558 gimple_omp_for_set_combined_into_p (gfor, true);
9559 for (i = 0; i < (int) gimple_omp_for_collapse (gfor); i++)
9561 t = unshare_expr (gimple_omp_for_index (gfor, i));
9562 gimple_omp_for_set_index (gforo, i, t);
9563 t = unshare_expr (gimple_omp_for_initial (gfor, i));
9564 gimple_omp_for_set_initial (gforo, i, t);
9565 gimple_omp_for_set_cond (gforo, i,
9566 gimple_omp_for_cond (gfor, i));
9567 t = unshare_expr (gimple_omp_for_final (gfor, i));
9568 gimple_omp_for_set_final (gforo, i, t);
9569 t = unshare_expr (gimple_omp_for_incr (gfor, i));
9570 gimple_omp_for_set_incr (gforo, i, t);
9572 gimplify_seq_add_stmt (pre_p, gforo);
9574 else
9575 gimplify_seq_add_stmt (pre_p, gfor);
9576 if (ret != GS_ALL_DONE)
9577 return GS_ERROR;
9578 *expr_p = NULL_TREE;
9579 return GS_ALL_DONE;
9582 /* Helper function of optimize_target_teams, find OMP_TEAMS inside
9583 of OMP_TARGET's body. */
9585 static tree
9586 find_omp_teams (tree *tp, int *walk_subtrees, void *)
9588 *walk_subtrees = 0;
9589 switch (TREE_CODE (*tp))
9591 case OMP_TEAMS:
9592 return *tp;
9593 case BIND_EXPR:
9594 case STATEMENT_LIST:
9595 *walk_subtrees = 1;
9596 break;
9597 default:
9598 break;
9600 return NULL_TREE;
9603 /* Helper function of optimize_target_teams, determine if the expression
9604 can be computed safely before the target construct on the host. */
9606 static tree
9607 computable_teams_clause (tree *tp, int *walk_subtrees, void *)
9609 splay_tree_node n;
9611 if (TYPE_P (*tp))
9613 *walk_subtrees = 0;
9614 return NULL_TREE;
9616 switch (TREE_CODE (*tp))
9618 case VAR_DECL:
9619 case PARM_DECL:
9620 case RESULT_DECL:
9621 *walk_subtrees = 0;
9622 if (error_operand_p (*tp)
9623 || !INTEGRAL_TYPE_P (TREE_TYPE (*tp))
9624 || DECL_HAS_VALUE_EXPR_P (*tp)
9625 || DECL_THREAD_LOCAL_P (*tp)
9626 || TREE_SIDE_EFFECTS (*tp)
9627 || TREE_THIS_VOLATILE (*tp))
9628 return *tp;
9629 if (is_global_var (*tp)
9630 && (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (*tp))
9631 || lookup_attribute ("omp declare target link",
9632 DECL_ATTRIBUTES (*tp))))
9633 return *tp;
9634 n = splay_tree_lookup (gimplify_omp_ctxp->variables,
9635 (splay_tree_key) *tp);
9636 if (n == NULL)
9638 if (gimplify_omp_ctxp->target_map_scalars_firstprivate)
9639 return NULL_TREE;
9640 return *tp;
9642 else if (n->value & GOVD_LOCAL)
9643 return *tp;
9644 else if (n->value & GOVD_FIRSTPRIVATE)
9645 return NULL_TREE;
9646 else if ((n->value & (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
9647 == (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
9648 return NULL_TREE;
9649 return *tp;
9650 case INTEGER_CST:
9651 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
9652 return *tp;
9653 return NULL_TREE;
9654 case TARGET_EXPR:
9655 if (TARGET_EXPR_INITIAL (*tp)
9656 || TREE_CODE (TARGET_EXPR_SLOT (*tp)) != VAR_DECL)
9657 return *tp;
9658 return computable_teams_clause (&TARGET_EXPR_SLOT (*tp),
9659 walk_subtrees, NULL);
9660 /* Allow some reasonable subset of integral arithmetics. */
9661 case PLUS_EXPR:
9662 case MINUS_EXPR:
9663 case MULT_EXPR:
9664 case TRUNC_DIV_EXPR:
9665 case CEIL_DIV_EXPR:
9666 case FLOOR_DIV_EXPR:
9667 case ROUND_DIV_EXPR:
9668 case TRUNC_MOD_EXPR:
9669 case CEIL_MOD_EXPR:
9670 case FLOOR_MOD_EXPR:
9671 case ROUND_MOD_EXPR:
9672 case RDIV_EXPR:
9673 case EXACT_DIV_EXPR:
9674 case MIN_EXPR:
9675 case MAX_EXPR:
9676 case LSHIFT_EXPR:
9677 case RSHIFT_EXPR:
9678 case BIT_IOR_EXPR:
9679 case BIT_XOR_EXPR:
9680 case BIT_AND_EXPR:
9681 case NEGATE_EXPR:
9682 case ABS_EXPR:
9683 case BIT_NOT_EXPR:
9684 case NON_LVALUE_EXPR:
9685 CASE_CONVERT:
9686 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
9687 return *tp;
9688 return NULL_TREE;
9689 /* And disallow anything else, except for comparisons. */
9690 default:
9691 if (COMPARISON_CLASS_P (*tp))
9692 return NULL_TREE;
9693 return *tp;
9697 /* Try to determine if the num_teams and/or thread_limit expressions
9698 can have their values determined already before entering the
9699 target construct.
9700 INTEGER_CSTs trivially are,
9701 integral decls that are firstprivate (explicitly or implicitly)
9702 or explicitly map(always, to:) or map(always, tofrom:) on the target
9703 region too, and expressions involving simple arithmetics on those
9704 too, function calls are not ok, dereferencing something neither etc.
9705 Add NUM_TEAMS and THREAD_LIMIT clauses to the OMP_CLAUSES of
9706 EXPR based on what we find:
9707 0 stands for clause not specified at all, use implementation default
9708 -1 stands for value that can't be determined easily before entering
9709 the target construct.
9710 If teams construct is not present at all, use 1 for num_teams
9711 and 0 for thread_limit (only one team is involved, and the thread
9712 limit is implementation defined. */
9714 static void
9715 optimize_target_teams (tree target, gimple_seq *pre_p)
9717 tree body = OMP_BODY (target);
9718 tree teams = walk_tree (&body, find_omp_teams, NULL, NULL);
9719 tree num_teams = integer_zero_node;
9720 tree thread_limit = integer_zero_node;
9721 location_t num_teams_loc = EXPR_LOCATION (target);
9722 location_t thread_limit_loc = EXPR_LOCATION (target);
9723 tree c, *p, expr;
9724 struct gimplify_omp_ctx *target_ctx = gimplify_omp_ctxp;
9726 if (teams == NULL_TREE)
9727 num_teams = integer_one_node;
9728 else
9729 for (c = OMP_TEAMS_CLAUSES (teams); c; c = OMP_CLAUSE_CHAIN (c))
9731 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS)
9733 p = &num_teams;
9734 num_teams_loc = OMP_CLAUSE_LOCATION (c);
9736 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
9738 p = &thread_limit;
9739 thread_limit_loc = OMP_CLAUSE_LOCATION (c);
9741 else
9742 continue;
9743 expr = OMP_CLAUSE_OPERAND (c, 0);
9744 if (TREE_CODE (expr) == INTEGER_CST)
9746 *p = expr;
9747 continue;
9749 if (walk_tree (&expr, computable_teams_clause, NULL, NULL))
9751 *p = integer_minus_one_node;
9752 continue;
9754 *p = expr;
9755 gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
9756 if (gimplify_expr (p, pre_p, NULL, is_gimple_val, fb_rvalue, false)
9757 == GS_ERROR)
9759 gimplify_omp_ctxp = target_ctx;
9760 *p = integer_minus_one_node;
9761 continue;
9763 gimplify_omp_ctxp = target_ctx;
9764 if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR)
9765 OMP_CLAUSE_OPERAND (c, 0) = *p;
9767 c = build_omp_clause (thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
9768 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = thread_limit;
9769 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
9770 OMP_TARGET_CLAUSES (target) = c;
9771 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
9772 OMP_CLAUSE_NUM_TEAMS_EXPR (c) = num_teams;
9773 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
9774 OMP_TARGET_CLAUSES (target) = c;
9777 /* Gimplify the gross structure of several OMP constructs. */
9779 static void
9780 gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
9782 tree expr = *expr_p;
9783 gimple *stmt;
9784 gimple_seq body = NULL;
9785 enum omp_region_type ort;
9787 switch (TREE_CODE (expr))
9789 case OMP_SECTIONS:
9790 case OMP_SINGLE:
9791 ort = ORT_WORKSHARE;
9792 break;
9793 case OMP_TARGET:
9794 ort = OMP_TARGET_COMBINED (expr) ? ORT_COMBINED_TARGET : ORT_TARGET;
9795 break;
9796 case OACC_KERNELS:
9797 ort = ORT_ACC_KERNELS;
9798 break;
9799 case OACC_PARALLEL:
9800 ort = ORT_ACC_PARALLEL;
9801 break;
9802 case OACC_DATA:
9803 ort = ORT_ACC_DATA;
9804 break;
9805 case OMP_TARGET_DATA:
9806 ort = ORT_TARGET_DATA;
9807 break;
9808 case OMP_TEAMS:
9809 ort = OMP_TEAMS_COMBINED (expr) ? ORT_COMBINED_TEAMS : ORT_TEAMS;
9810 break;
9811 case OACC_HOST_DATA:
9812 ort = ORT_ACC_HOST_DATA;
9813 break;
9814 default:
9815 gcc_unreachable ();
9817 gimplify_scan_omp_clauses (&OMP_CLAUSES (expr), pre_p, ort,
9818 TREE_CODE (expr));
9819 if (TREE_CODE (expr) == OMP_TARGET)
9820 optimize_target_teams (expr, pre_p);
9821 if ((ort & (ORT_TARGET | ORT_TARGET_DATA)) != 0)
9823 push_gimplify_context ();
9824 gimple *g = gimplify_and_return_first (OMP_BODY (expr), &body);
9825 if (gimple_code (g) == GIMPLE_BIND)
9826 pop_gimplify_context (g);
9827 else
9828 pop_gimplify_context (NULL);
9829 if ((ort & ORT_TARGET_DATA) != 0)
9831 enum built_in_function end_ix;
9832 switch (TREE_CODE (expr))
9834 case OACC_DATA:
9835 case OACC_HOST_DATA:
9836 end_ix = BUILT_IN_GOACC_DATA_END;
9837 break;
9838 case OMP_TARGET_DATA:
9839 end_ix = BUILT_IN_GOMP_TARGET_END_DATA;
9840 break;
9841 default:
9842 gcc_unreachable ();
9844 tree fn = builtin_decl_explicit (end_ix);
9845 g = gimple_build_call (fn, 0);
9846 gimple_seq cleanup = NULL;
9847 gimple_seq_add_stmt (&cleanup, g);
9848 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
9849 body = NULL;
9850 gimple_seq_add_stmt (&body, g);
9853 else
9854 gimplify_and_add (OMP_BODY (expr), &body);
9855 gimplify_adjust_omp_clauses (pre_p, body, &OMP_CLAUSES (expr),
9856 TREE_CODE (expr));
9858 switch (TREE_CODE (expr))
9860 case OACC_DATA:
9861 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_DATA,
9862 OMP_CLAUSES (expr));
9863 break;
9864 case OACC_KERNELS:
9865 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_KERNELS,
9866 OMP_CLAUSES (expr));
9867 break;
9868 case OACC_HOST_DATA:
9869 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_HOST_DATA,
9870 OMP_CLAUSES (expr));
9871 break;
9872 case OACC_PARALLEL:
9873 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_PARALLEL,
9874 OMP_CLAUSES (expr));
9875 break;
9876 case OMP_SECTIONS:
9877 stmt = gimple_build_omp_sections (body, OMP_CLAUSES (expr));
9878 break;
9879 case OMP_SINGLE:
9880 stmt = gimple_build_omp_single (body, OMP_CLAUSES (expr));
9881 break;
9882 case OMP_TARGET:
9883 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_REGION,
9884 OMP_CLAUSES (expr));
9885 break;
9886 case OMP_TARGET_DATA:
9887 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_DATA,
9888 OMP_CLAUSES (expr));
9889 break;
9890 case OMP_TEAMS:
9891 stmt = gimple_build_omp_teams (body, OMP_CLAUSES (expr));
9892 break;
9893 default:
9894 gcc_unreachable ();
9897 gimplify_seq_add_stmt (pre_p, stmt);
9898 *expr_p = NULL_TREE;
9901 /* Gimplify the gross structure of OpenACC enter/exit data, update, and OpenMP
9902 target update constructs. */
9904 static void
9905 gimplify_omp_target_update (tree *expr_p, gimple_seq *pre_p)
9907 tree expr = *expr_p;
9908 int kind;
9909 gomp_target *stmt;
9910 enum omp_region_type ort = ORT_WORKSHARE;
9912 switch (TREE_CODE (expr))
9914 case OACC_ENTER_DATA:
9915 case OACC_EXIT_DATA:
9916 kind = GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA;
9917 ort = ORT_ACC;
9918 break;
9919 case OACC_UPDATE:
9920 kind = GF_OMP_TARGET_KIND_OACC_UPDATE;
9921 ort = ORT_ACC;
9922 break;
9923 case OMP_TARGET_UPDATE:
9924 kind = GF_OMP_TARGET_KIND_UPDATE;
9925 break;
9926 case OMP_TARGET_ENTER_DATA:
9927 kind = GF_OMP_TARGET_KIND_ENTER_DATA;
9928 break;
9929 case OMP_TARGET_EXIT_DATA:
9930 kind = GF_OMP_TARGET_KIND_EXIT_DATA;
9931 break;
9932 default:
9933 gcc_unreachable ();
9935 gimplify_scan_omp_clauses (&OMP_STANDALONE_CLAUSES (expr), pre_p,
9936 ort, TREE_CODE (expr));
9937 gimplify_adjust_omp_clauses (pre_p, NULL, &OMP_STANDALONE_CLAUSES (expr),
9938 TREE_CODE (expr));
9939 stmt = gimple_build_omp_target (NULL, kind, OMP_STANDALONE_CLAUSES (expr));
9941 gimplify_seq_add_stmt (pre_p, stmt);
9942 *expr_p = NULL_TREE;
9945 /* A subroutine of gimplify_omp_atomic. The front end is supposed to have
9946 stabilized the lhs of the atomic operation as *ADDR. Return true if
9947 EXPR is this stabilized form. */
9949 static bool
9950 goa_lhs_expr_p (tree expr, tree addr)
9952 /* Also include casts to other type variants. The C front end is fond
9953 of adding these for e.g. volatile variables. This is like
9954 STRIP_TYPE_NOPS but includes the main variant lookup. */
9955 STRIP_USELESS_TYPE_CONVERSION (expr);
9957 if (TREE_CODE (expr) == INDIRECT_REF)
9959 expr = TREE_OPERAND (expr, 0);
9960 while (expr != addr
9961 && (CONVERT_EXPR_P (expr)
9962 || TREE_CODE (expr) == NON_LVALUE_EXPR)
9963 && TREE_CODE (expr) == TREE_CODE (addr)
9964 && types_compatible_p (TREE_TYPE (expr), TREE_TYPE (addr)))
9966 expr = TREE_OPERAND (expr, 0);
9967 addr = TREE_OPERAND (addr, 0);
9969 if (expr == addr)
9970 return true;
9971 return (TREE_CODE (addr) == ADDR_EXPR
9972 && TREE_CODE (expr) == ADDR_EXPR
9973 && TREE_OPERAND (addr, 0) == TREE_OPERAND (expr, 0));
9975 if (TREE_CODE (addr) == ADDR_EXPR && expr == TREE_OPERAND (addr, 0))
9976 return true;
9977 return false;
9980 /* Walk *EXPR_P and replace appearances of *LHS_ADDR with LHS_VAR. If an
9981 expression does not involve the lhs, evaluate it into a temporary.
9982 Return 1 if the lhs appeared as a subexpression, 0 if it did not,
9983 or -1 if an error was encountered. */
9985 static int
9986 goa_stabilize_expr (tree *expr_p, gimple_seq *pre_p, tree lhs_addr,
9987 tree lhs_var)
9989 tree expr = *expr_p;
9990 int saw_lhs;
9992 if (goa_lhs_expr_p (expr, lhs_addr))
9994 *expr_p = lhs_var;
9995 return 1;
9997 if (is_gimple_val (expr))
9998 return 0;
10000 saw_lhs = 0;
10001 switch (TREE_CODE_CLASS (TREE_CODE (expr)))
10003 case tcc_binary:
10004 case tcc_comparison:
10005 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p, lhs_addr,
10006 lhs_var);
10007 /* FALLTHRU */
10008 case tcc_unary:
10009 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p, lhs_addr,
10010 lhs_var);
10011 break;
10012 case tcc_expression:
10013 switch (TREE_CODE (expr))
10015 case TRUTH_ANDIF_EXPR:
10016 case TRUTH_ORIF_EXPR:
10017 case TRUTH_AND_EXPR:
10018 case TRUTH_OR_EXPR:
10019 case TRUTH_XOR_EXPR:
10020 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
10021 lhs_addr, lhs_var);
10022 /* FALLTHRU */
10023 case TRUTH_NOT_EXPR:
10024 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
10025 lhs_addr, lhs_var);
10026 break;
10027 case COMPOUND_EXPR:
10028 /* Break out any preevaluations from cp_build_modify_expr. */
10029 for (; TREE_CODE (expr) == COMPOUND_EXPR;
10030 expr = TREE_OPERAND (expr, 1))
10031 gimplify_stmt (&TREE_OPERAND (expr, 0), pre_p);
10032 *expr_p = expr;
10033 return goa_stabilize_expr (expr_p, pre_p, lhs_addr, lhs_var);
10034 default:
10035 break;
10037 break;
10038 default:
10039 break;
10042 if (saw_lhs == 0)
10044 enum gimplify_status gs;
10045 gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_val, fb_rvalue);
10046 if (gs != GS_ALL_DONE)
10047 saw_lhs = -1;
10050 return saw_lhs;
10053 /* Gimplify an OMP_ATOMIC statement. */
10055 static enum gimplify_status
10056 gimplify_omp_atomic (tree *expr_p, gimple_seq *pre_p)
10058 tree addr = TREE_OPERAND (*expr_p, 0);
10059 tree rhs = TREE_CODE (*expr_p) == OMP_ATOMIC_READ
10060 ? NULL : TREE_OPERAND (*expr_p, 1);
10061 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
10062 tree tmp_load;
10063 gomp_atomic_load *loadstmt;
10064 gomp_atomic_store *storestmt;
10066 tmp_load = create_tmp_reg (type);
10067 if (rhs && goa_stabilize_expr (&rhs, pre_p, addr, tmp_load) < 0)
10068 return GS_ERROR;
10070 if (gimplify_expr (&addr, pre_p, NULL, is_gimple_val, fb_rvalue)
10071 != GS_ALL_DONE)
10072 return GS_ERROR;
10074 loadstmt = gimple_build_omp_atomic_load (tmp_load, addr);
10075 gimplify_seq_add_stmt (pre_p, loadstmt);
10076 if (rhs && gimplify_expr (&rhs, pre_p, NULL, is_gimple_val, fb_rvalue)
10077 != GS_ALL_DONE)
10078 return GS_ERROR;
10080 if (TREE_CODE (*expr_p) == OMP_ATOMIC_READ)
10081 rhs = tmp_load;
10082 storestmt = gimple_build_omp_atomic_store (rhs);
10083 gimplify_seq_add_stmt (pre_p, storestmt);
10084 if (OMP_ATOMIC_SEQ_CST (*expr_p))
10086 gimple_omp_atomic_set_seq_cst (loadstmt);
10087 gimple_omp_atomic_set_seq_cst (storestmt);
10089 switch (TREE_CODE (*expr_p))
10091 case OMP_ATOMIC_READ:
10092 case OMP_ATOMIC_CAPTURE_OLD:
10093 *expr_p = tmp_load;
10094 gimple_omp_atomic_set_need_value (loadstmt);
10095 break;
10096 case OMP_ATOMIC_CAPTURE_NEW:
10097 *expr_p = rhs;
10098 gimple_omp_atomic_set_need_value (storestmt);
10099 break;
10100 default:
10101 *expr_p = NULL;
10102 break;
10105 return GS_ALL_DONE;
10108 /* Gimplify a TRANSACTION_EXPR. This involves gimplification of the
10109 body, and adding some EH bits. */
10111 static enum gimplify_status
10112 gimplify_transaction (tree *expr_p, gimple_seq *pre_p)
10114 tree expr = *expr_p, temp, tbody = TRANSACTION_EXPR_BODY (expr);
10115 gimple *body_stmt;
10116 gtransaction *trans_stmt;
10117 gimple_seq body = NULL;
10118 int subcode = 0;
10120 /* Wrap the transaction body in a BIND_EXPR so we have a context
10121 where to put decls for OMP. */
10122 if (TREE_CODE (tbody) != BIND_EXPR)
10124 tree bind = build3 (BIND_EXPR, void_type_node, NULL, tbody, NULL);
10125 TREE_SIDE_EFFECTS (bind) = 1;
10126 SET_EXPR_LOCATION (bind, EXPR_LOCATION (tbody));
10127 TRANSACTION_EXPR_BODY (expr) = bind;
10130 push_gimplify_context ();
10131 temp = voidify_wrapper_expr (*expr_p, NULL);
10133 body_stmt = gimplify_and_return_first (TRANSACTION_EXPR_BODY (expr), &body);
10134 pop_gimplify_context (body_stmt);
10136 trans_stmt = gimple_build_transaction (body);
10137 if (TRANSACTION_EXPR_OUTER (expr))
10138 subcode = GTMA_IS_OUTER;
10139 else if (TRANSACTION_EXPR_RELAXED (expr))
10140 subcode = GTMA_IS_RELAXED;
10141 gimple_transaction_set_subcode (trans_stmt, subcode);
10143 gimplify_seq_add_stmt (pre_p, trans_stmt);
10145 if (temp)
10147 *expr_p = temp;
10148 return GS_OK;
10151 *expr_p = NULL_TREE;
10152 return GS_ALL_DONE;
10155 /* Gimplify an OMP_ORDERED construct. EXPR is the tree version. BODY
10156 is the OMP_BODY of the original EXPR (which has already been
10157 gimplified so it's not present in the EXPR).
10159 Return the gimplified GIMPLE_OMP_ORDERED tuple. */
10161 static gimple *
10162 gimplify_omp_ordered (tree expr, gimple_seq body)
10164 tree c, decls;
10165 int failures = 0;
10166 unsigned int i;
10167 tree source_c = NULL_TREE;
10168 tree sink_c = NULL_TREE;
10170 if (gimplify_omp_ctxp)
10172 for (c = OMP_ORDERED_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
10173 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
10174 && gimplify_omp_ctxp->loop_iter_var.is_empty ()
10175 && (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK
10176 || OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE))
10178 error_at (OMP_CLAUSE_LOCATION (c),
10179 "%<ordered%> construct with %<depend%> clause must be "
10180 "closely nested inside a loop with %<ordered%> clause "
10181 "with a parameter");
10182 failures++;
10184 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
10185 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
10187 bool fail = false;
10188 for (decls = OMP_CLAUSE_DECL (c), i = 0;
10189 decls && TREE_CODE (decls) == TREE_LIST;
10190 decls = TREE_CHAIN (decls), ++i)
10191 if (i >= gimplify_omp_ctxp->loop_iter_var.length () / 2)
10192 continue;
10193 else if (TREE_VALUE (decls)
10194 != gimplify_omp_ctxp->loop_iter_var[2 * i])
10196 error_at (OMP_CLAUSE_LOCATION (c),
10197 "variable %qE is not an iteration "
10198 "of outermost loop %d, expected %qE",
10199 TREE_VALUE (decls), i + 1,
10200 gimplify_omp_ctxp->loop_iter_var[2 * i]);
10201 fail = true;
10202 failures++;
10204 else
10205 TREE_VALUE (decls)
10206 = gimplify_omp_ctxp->loop_iter_var[2 * i + 1];
10207 if (!fail && i != gimplify_omp_ctxp->loop_iter_var.length () / 2)
10209 error_at (OMP_CLAUSE_LOCATION (c),
10210 "number of variables in %<depend(sink)%> "
10211 "clause does not match number of "
10212 "iteration variables");
10213 failures++;
10215 sink_c = c;
10217 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
10218 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
10220 if (source_c)
10222 error_at (OMP_CLAUSE_LOCATION (c),
10223 "more than one %<depend(source)%> clause on an "
10224 "%<ordered%> construct");
10225 failures++;
10227 else
10228 source_c = c;
10231 if (source_c && sink_c)
10233 error_at (OMP_CLAUSE_LOCATION (source_c),
10234 "%<depend(source)%> clause specified together with "
10235 "%<depend(sink:)%> clauses on the same construct");
10236 failures++;
10239 if (failures)
10240 return gimple_build_nop ();
10241 return gimple_build_omp_ordered (body, OMP_ORDERED_CLAUSES (expr));
10244 /* Convert the GENERIC expression tree *EXPR_P to GIMPLE. If the
10245 expression produces a value to be used as an operand inside a GIMPLE
10246 statement, the value will be stored back in *EXPR_P. This value will
10247 be a tree of class tcc_declaration, tcc_constant, tcc_reference or
10248 an SSA_NAME. The corresponding sequence of GIMPLE statements is
10249 emitted in PRE_P and POST_P.
10251 Additionally, this process may overwrite parts of the input
10252 expression during gimplification. Ideally, it should be
10253 possible to do non-destructive gimplification.
10255 EXPR_P points to the GENERIC expression to convert to GIMPLE. If
10256 the expression needs to evaluate to a value to be used as
10257 an operand in a GIMPLE statement, this value will be stored in
10258 *EXPR_P on exit. This happens when the caller specifies one
10259 of fb_lvalue or fb_rvalue fallback flags.
10261 PRE_P will contain the sequence of GIMPLE statements corresponding
10262 to the evaluation of EXPR and all the side-effects that must
10263 be executed before the main expression. On exit, the last
10264 statement of PRE_P is the core statement being gimplified. For
10265 instance, when gimplifying 'if (++a)' the last statement in
10266 PRE_P will be 'if (t.1)' where t.1 is the result of
10267 pre-incrementing 'a'.
10269 POST_P will contain the sequence of GIMPLE statements corresponding
10270 to the evaluation of all the side-effects that must be executed
10271 after the main expression. If this is NULL, the post
10272 side-effects are stored at the end of PRE_P.
10274 The reason why the output is split in two is to handle post
10275 side-effects explicitly. In some cases, an expression may have
10276 inner and outer post side-effects which need to be emitted in
10277 an order different from the one given by the recursive
10278 traversal. For instance, for the expression (*p--)++ the post
10279 side-effects of '--' must actually occur *after* the post
10280 side-effects of '++'. However, gimplification will first visit
10281 the inner expression, so if a separate POST sequence was not
10282 used, the resulting sequence would be:
10284 1 t.1 = *p
10285 2 p = p - 1
10286 3 t.2 = t.1 + 1
10287 4 *p = t.2
10289 However, the post-decrement operation in line #2 must not be
10290 evaluated until after the store to *p at line #4, so the
10291 correct sequence should be:
10293 1 t.1 = *p
10294 2 t.2 = t.1 + 1
10295 3 *p = t.2
10296 4 p = p - 1
10298 So, by specifying a separate post queue, it is possible
10299 to emit the post side-effects in the correct order.
10300 If POST_P is NULL, an internal queue will be used. Before
10301 returning to the caller, the sequence POST_P is appended to
10302 the main output sequence PRE_P.
10304 GIMPLE_TEST_F points to a function that takes a tree T and
10305 returns nonzero if T is in the GIMPLE form requested by the
10306 caller. The GIMPLE predicates are in gimple.c.
10308 FALLBACK tells the function what sort of a temporary we want if
10309 gimplification cannot produce an expression that complies with
10310 GIMPLE_TEST_F.
10312 fb_none means that no temporary should be generated
10313 fb_rvalue means that an rvalue is OK to generate
10314 fb_lvalue means that an lvalue is OK to generate
10315 fb_either means that either is OK, but an lvalue is preferable.
10316 fb_mayfail means that gimplification may fail (in which case
10317 GS_ERROR will be returned)
10319 The return value is either GS_ERROR or GS_ALL_DONE, since this
10320 function iterates until EXPR is completely gimplified or an error
10321 occurs. */
10323 enum gimplify_status
10324 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
10325 bool (*gimple_test_f) (tree), fallback_t fallback)
10327 tree tmp;
10328 gimple_seq internal_pre = NULL;
10329 gimple_seq internal_post = NULL;
10330 tree save_expr;
10331 bool is_statement;
10332 location_t saved_location;
10333 enum gimplify_status ret;
10334 gimple_stmt_iterator pre_last_gsi, post_last_gsi;
10336 save_expr = *expr_p;
10337 if (save_expr == NULL_TREE)
10338 return GS_ALL_DONE;
10340 /* If we are gimplifying a top-level statement, PRE_P must be valid. */
10341 is_statement = gimple_test_f == is_gimple_stmt;
10342 if (is_statement)
10343 gcc_assert (pre_p);
10345 /* Consistency checks. */
10346 if (gimple_test_f == is_gimple_reg)
10347 gcc_assert (fallback & (fb_rvalue | fb_lvalue));
10348 else if (gimple_test_f == is_gimple_val
10349 || gimple_test_f == is_gimple_call_addr
10350 || gimple_test_f == is_gimple_condexpr
10351 || gimple_test_f == is_gimple_mem_rhs
10352 || gimple_test_f == is_gimple_mem_rhs_or_call
10353 || gimple_test_f == is_gimple_reg_rhs
10354 || gimple_test_f == is_gimple_reg_rhs_or_call
10355 || gimple_test_f == is_gimple_asm_val
10356 || gimple_test_f == is_gimple_mem_ref_addr)
10357 gcc_assert (fallback & fb_rvalue);
10358 else if (gimple_test_f == is_gimple_min_lval
10359 || gimple_test_f == is_gimple_lvalue)
10360 gcc_assert (fallback & fb_lvalue);
10361 else if (gimple_test_f == is_gimple_addressable)
10362 gcc_assert (fallback & fb_either);
10363 else if (gimple_test_f == is_gimple_stmt)
10364 gcc_assert (fallback == fb_none);
10365 else
10367 /* We should have recognized the GIMPLE_TEST_F predicate to
10368 know what kind of fallback to use in case a temporary is
10369 needed to hold the value or address of *EXPR_P. */
10370 gcc_unreachable ();
10373 /* We used to check the predicate here and return immediately if it
10374 succeeds. This is wrong; the design is for gimplification to be
10375 idempotent, and for the predicates to only test for valid forms, not
10376 whether they are fully simplified. */
10377 if (pre_p == NULL)
10378 pre_p = &internal_pre;
10380 if (post_p == NULL)
10381 post_p = &internal_post;
10383 /* Remember the last statements added to PRE_P and POST_P. Every
10384 new statement added by the gimplification helpers needs to be
10385 annotated with location information. To centralize the
10386 responsibility, we remember the last statement that had been
10387 added to both queues before gimplifying *EXPR_P. If
10388 gimplification produces new statements in PRE_P and POST_P, those
10389 statements will be annotated with the same location information
10390 as *EXPR_P. */
10391 pre_last_gsi = gsi_last (*pre_p);
10392 post_last_gsi = gsi_last (*post_p);
10394 saved_location = input_location;
10395 if (save_expr != error_mark_node
10396 && EXPR_HAS_LOCATION (*expr_p))
10397 input_location = EXPR_LOCATION (*expr_p);
10399 /* Loop over the specific gimplifiers until the toplevel node
10400 remains the same. */
10403 /* Strip away as many useless type conversions as possible
10404 at the toplevel. */
10405 STRIP_USELESS_TYPE_CONVERSION (*expr_p);
10407 /* Remember the expr. */
10408 save_expr = *expr_p;
10410 /* Die, die, die, my darling. */
10411 if (save_expr == error_mark_node
10412 || (TREE_TYPE (save_expr)
10413 && TREE_TYPE (save_expr) == error_mark_node))
10415 ret = GS_ERROR;
10416 break;
10419 /* Do any language-specific gimplification. */
10420 ret = ((enum gimplify_status)
10421 lang_hooks.gimplify_expr (expr_p, pre_p, post_p));
10422 if (ret == GS_OK)
10424 if (*expr_p == NULL_TREE)
10425 break;
10426 if (*expr_p != save_expr)
10427 continue;
10429 else if (ret != GS_UNHANDLED)
10430 break;
10432 /* Make sure that all the cases set 'ret' appropriately. */
10433 ret = GS_UNHANDLED;
10434 switch (TREE_CODE (*expr_p))
10436 /* First deal with the special cases. */
10438 case POSTINCREMENT_EXPR:
10439 case POSTDECREMENT_EXPR:
10440 case PREINCREMENT_EXPR:
10441 case PREDECREMENT_EXPR:
10442 ret = gimplify_self_mod_expr (expr_p, pre_p, post_p,
10443 fallback != fb_none,
10444 TREE_TYPE (*expr_p));
10445 break;
10447 case VIEW_CONVERT_EXPR:
10448 if (is_gimple_reg_type (TREE_TYPE (*expr_p))
10449 && is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0))))
10451 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
10452 post_p, is_gimple_val, fb_rvalue);
10453 recalculate_side_effects (*expr_p);
10454 break;
10456 /* Fallthru. */
10458 case ARRAY_REF:
10459 case ARRAY_RANGE_REF:
10460 case REALPART_EXPR:
10461 case IMAGPART_EXPR:
10462 case COMPONENT_REF:
10463 ret = gimplify_compound_lval (expr_p, pre_p, post_p,
10464 fallback ? fallback : fb_rvalue);
10465 break;
10467 case COND_EXPR:
10468 ret = gimplify_cond_expr (expr_p, pre_p, fallback);
10470 /* C99 code may assign to an array in a structure value of a
10471 conditional expression, and this has undefined behavior
10472 only on execution, so create a temporary if an lvalue is
10473 required. */
10474 if (fallback == fb_lvalue)
10476 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
10477 mark_addressable (*expr_p);
10478 ret = GS_OK;
10480 break;
10482 case CALL_EXPR:
10483 ret = gimplify_call_expr (expr_p, pre_p, fallback != fb_none);
10485 /* C99 code may assign to an array in a structure returned
10486 from a function, and this has undefined behavior only on
10487 execution, so create a temporary if an lvalue is
10488 required. */
10489 if (fallback == fb_lvalue)
10491 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
10492 mark_addressable (*expr_p);
10493 ret = GS_OK;
10495 break;
10497 case TREE_LIST:
10498 gcc_unreachable ();
10500 case COMPOUND_EXPR:
10501 ret = gimplify_compound_expr (expr_p, pre_p, fallback != fb_none);
10502 break;
10504 case COMPOUND_LITERAL_EXPR:
10505 ret = gimplify_compound_literal_expr (expr_p, pre_p,
10506 gimple_test_f, fallback);
10507 break;
10509 case MODIFY_EXPR:
10510 case INIT_EXPR:
10511 ret = gimplify_modify_expr (expr_p, pre_p, post_p,
10512 fallback != fb_none);
10513 break;
10515 case TRUTH_ANDIF_EXPR:
10516 case TRUTH_ORIF_EXPR:
10518 /* Preserve the original type of the expression and the
10519 source location of the outer expression. */
10520 tree org_type = TREE_TYPE (*expr_p);
10521 *expr_p = gimple_boolify (*expr_p);
10522 *expr_p = build3_loc (input_location, COND_EXPR,
10523 org_type, *expr_p,
10524 fold_convert_loc
10525 (input_location,
10526 org_type, boolean_true_node),
10527 fold_convert_loc
10528 (input_location,
10529 org_type, boolean_false_node));
10530 ret = GS_OK;
10531 break;
10534 case TRUTH_NOT_EXPR:
10536 tree type = TREE_TYPE (*expr_p);
10537 /* The parsers are careful to generate TRUTH_NOT_EXPR
10538 only with operands that are always zero or one.
10539 We do not fold here but handle the only interesting case
10540 manually, as fold may re-introduce the TRUTH_NOT_EXPR. */
10541 *expr_p = gimple_boolify (*expr_p);
10542 if (TYPE_PRECISION (TREE_TYPE (*expr_p)) == 1)
10543 *expr_p = build1_loc (input_location, BIT_NOT_EXPR,
10544 TREE_TYPE (*expr_p),
10545 TREE_OPERAND (*expr_p, 0));
10546 else
10547 *expr_p = build2_loc (input_location, BIT_XOR_EXPR,
10548 TREE_TYPE (*expr_p),
10549 TREE_OPERAND (*expr_p, 0),
10550 build_int_cst (TREE_TYPE (*expr_p), 1));
10551 if (!useless_type_conversion_p (type, TREE_TYPE (*expr_p)))
10552 *expr_p = fold_convert_loc (input_location, type, *expr_p);
10553 ret = GS_OK;
10554 break;
10557 case ADDR_EXPR:
10558 ret = gimplify_addr_expr (expr_p, pre_p, post_p);
10559 break;
10561 case ANNOTATE_EXPR:
10563 tree cond = TREE_OPERAND (*expr_p, 0);
10564 tree kind = TREE_OPERAND (*expr_p, 1);
10565 tree type = TREE_TYPE (cond);
10566 if (!INTEGRAL_TYPE_P (type))
10568 *expr_p = cond;
10569 ret = GS_OK;
10570 break;
10572 tree tmp = create_tmp_var (type);
10573 gimplify_arg (&cond, pre_p, EXPR_LOCATION (*expr_p));
10574 gcall *call
10575 = gimple_build_call_internal (IFN_ANNOTATE, 2, cond, kind);
10576 gimple_call_set_lhs (call, tmp);
10577 gimplify_seq_add_stmt (pre_p, call);
10578 *expr_p = tmp;
10579 ret = GS_ALL_DONE;
10580 break;
10583 case VA_ARG_EXPR:
10584 ret = gimplify_va_arg_expr (expr_p, pre_p, post_p);
10585 break;
10587 CASE_CONVERT:
10588 if (IS_EMPTY_STMT (*expr_p))
10590 ret = GS_ALL_DONE;
10591 break;
10594 if (VOID_TYPE_P (TREE_TYPE (*expr_p))
10595 || fallback == fb_none)
10597 /* Just strip a conversion to void (or in void context) and
10598 try again. */
10599 *expr_p = TREE_OPERAND (*expr_p, 0);
10600 ret = GS_OK;
10601 break;
10604 ret = gimplify_conversion (expr_p);
10605 if (ret == GS_ERROR)
10606 break;
10607 if (*expr_p != save_expr)
10608 break;
10609 /* FALLTHRU */
10611 case FIX_TRUNC_EXPR:
10612 /* unary_expr: ... | '(' cast ')' val | ... */
10613 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
10614 is_gimple_val, fb_rvalue);
10615 recalculate_side_effects (*expr_p);
10616 break;
10618 case INDIRECT_REF:
10620 bool volatilep = TREE_THIS_VOLATILE (*expr_p);
10621 bool notrap = TREE_THIS_NOTRAP (*expr_p);
10622 tree saved_ptr_type = TREE_TYPE (TREE_OPERAND (*expr_p, 0));
10624 *expr_p = fold_indirect_ref_loc (input_location, *expr_p);
10625 if (*expr_p != save_expr)
10627 ret = GS_OK;
10628 break;
10631 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
10632 is_gimple_reg, fb_rvalue);
10633 if (ret == GS_ERROR)
10634 break;
10636 recalculate_side_effects (*expr_p);
10637 *expr_p = fold_build2_loc (input_location, MEM_REF,
10638 TREE_TYPE (*expr_p),
10639 TREE_OPERAND (*expr_p, 0),
10640 build_int_cst (saved_ptr_type, 0));
10641 TREE_THIS_VOLATILE (*expr_p) = volatilep;
10642 TREE_THIS_NOTRAP (*expr_p) = notrap;
10643 ret = GS_OK;
10644 break;
10647 /* We arrive here through the various re-gimplifcation paths. */
10648 case MEM_REF:
10649 /* First try re-folding the whole thing. */
10650 tmp = fold_binary (MEM_REF, TREE_TYPE (*expr_p),
10651 TREE_OPERAND (*expr_p, 0),
10652 TREE_OPERAND (*expr_p, 1));
10653 if (tmp)
10655 REF_REVERSE_STORAGE_ORDER (tmp)
10656 = REF_REVERSE_STORAGE_ORDER (*expr_p);
10657 *expr_p = tmp;
10658 recalculate_side_effects (*expr_p);
10659 ret = GS_OK;
10660 break;
10662 /* Avoid re-gimplifying the address operand if it is already
10663 in suitable form. Re-gimplifying would mark the address
10664 operand addressable. Always gimplify when not in SSA form
10665 as we still may have to gimplify decls with value-exprs. */
10666 if (!gimplify_ctxp || !gimple_in_ssa_p (cfun)
10667 || !is_gimple_mem_ref_addr (TREE_OPERAND (*expr_p, 0)))
10669 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
10670 is_gimple_mem_ref_addr, fb_rvalue);
10671 if (ret == GS_ERROR)
10672 break;
10674 recalculate_side_effects (*expr_p);
10675 ret = GS_ALL_DONE;
10676 break;
10678 /* Constants need not be gimplified. */
10679 case INTEGER_CST:
10680 case REAL_CST:
10681 case FIXED_CST:
10682 case STRING_CST:
10683 case COMPLEX_CST:
10684 case VECTOR_CST:
10685 /* Drop the overflow flag on constants, we do not want
10686 that in the GIMPLE IL. */
10687 if (TREE_OVERFLOW_P (*expr_p))
10688 *expr_p = drop_tree_overflow (*expr_p);
10689 ret = GS_ALL_DONE;
10690 break;
10692 case CONST_DECL:
10693 /* If we require an lvalue, such as for ADDR_EXPR, retain the
10694 CONST_DECL node. Otherwise the decl is replaceable by its
10695 value. */
10696 /* ??? Should be == fb_lvalue, but ADDR_EXPR passes fb_either. */
10697 if (fallback & fb_lvalue)
10698 ret = GS_ALL_DONE;
10699 else
10701 *expr_p = DECL_INITIAL (*expr_p);
10702 ret = GS_OK;
10704 break;
10706 case DECL_EXPR:
10707 ret = gimplify_decl_expr (expr_p, pre_p);
10708 break;
10710 case BIND_EXPR:
10711 ret = gimplify_bind_expr (expr_p, pre_p);
10712 break;
10714 case LOOP_EXPR:
10715 ret = gimplify_loop_expr (expr_p, pre_p);
10716 break;
10718 case SWITCH_EXPR:
10719 ret = gimplify_switch_expr (expr_p, pre_p);
10720 break;
10722 case EXIT_EXPR:
10723 ret = gimplify_exit_expr (expr_p);
10724 break;
10726 case GOTO_EXPR:
10727 /* If the target is not LABEL, then it is a computed jump
10728 and the target needs to be gimplified. */
10729 if (TREE_CODE (GOTO_DESTINATION (*expr_p)) != LABEL_DECL)
10731 ret = gimplify_expr (&GOTO_DESTINATION (*expr_p), pre_p,
10732 NULL, is_gimple_val, fb_rvalue);
10733 if (ret == GS_ERROR)
10734 break;
10736 gimplify_seq_add_stmt (pre_p,
10737 gimple_build_goto (GOTO_DESTINATION (*expr_p)));
10738 ret = GS_ALL_DONE;
10739 break;
10741 case PREDICT_EXPR:
10742 gimplify_seq_add_stmt (pre_p,
10743 gimple_build_predict (PREDICT_EXPR_PREDICTOR (*expr_p),
10744 PREDICT_EXPR_OUTCOME (*expr_p)));
10745 ret = GS_ALL_DONE;
10746 break;
10748 case LABEL_EXPR:
10749 ret = GS_ALL_DONE;
10750 gcc_assert (decl_function_context (LABEL_EXPR_LABEL (*expr_p))
10751 == current_function_decl);
10752 gimplify_seq_add_stmt (pre_p,
10753 gimple_build_label (LABEL_EXPR_LABEL (*expr_p)));
10754 break;
10756 case CASE_LABEL_EXPR:
10757 ret = gimplify_case_label_expr (expr_p, pre_p);
10758 break;
10760 case RETURN_EXPR:
10761 ret = gimplify_return_expr (*expr_p, pre_p);
10762 break;
10764 case CONSTRUCTOR:
10765 /* Don't reduce this in place; let gimplify_init_constructor work its
10766 magic. Buf if we're just elaborating this for side effects, just
10767 gimplify any element that has side-effects. */
10768 if (fallback == fb_none)
10770 unsigned HOST_WIDE_INT ix;
10771 tree val;
10772 tree temp = NULL_TREE;
10773 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (*expr_p), ix, val)
10774 if (TREE_SIDE_EFFECTS (val))
10775 append_to_statement_list (val, &temp);
10777 *expr_p = temp;
10778 ret = temp ? GS_OK : GS_ALL_DONE;
10780 /* C99 code may assign to an array in a constructed
10781 structure or union, and this has undefined behavior only
10782 on execution, so create a temporary if an lvalue is
10783 required. */
10784 else if (fallback == fb_lvalue)
10786 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
10787 mark_addressable (*expr_p);
10788 ret = GS_OK;
10790 else
10791 ret = GS_ALL_DONE;
10792 break;
10794 /* The following are special cases that are not handled by the
10795 original GIMPLE grammar. */
10797 /* SAVE_EXPR nodes are converted into a GIMPLE identifier and
10798 eliminated. */
10799 case SAVE_EXPR:
10800 ret = gimplify_save_expr (expr_p, pre_p, post_p);
10801 break;
10803 case BIT_FIELD_REF:
10804 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
10805 post_p, is_gimple_lvalue, fb_either);
10806 recalculate_side_effects (*expr_p);
10807 break;
10809 case TARGET_MEM_REF:
10811 enum gimplify_status r0 = GS_ALL_DONE, r1 = GS_ALL_DONE;
10813 if (TMR_BASE (*expr_p))
10814 r0 = gimplify_expr (&TMR_BASE (*expr_p), pre_p,
10815 post_p, is_gimple_mem_ref_addr, fb_either);
10816 if (TMR_INDEX (*expr_p))
10817 r1 = gimplify_expr (&TMR_INDEX (*expr_p), pre_p,
10818 post_p, is_gimple_val, fb_rvalue);
10819 if (TMR_INDEX2 (*expr_p))
10820 r1 = gimplify_expr (&TMR_INDEX2 (*expr_p), pre_p,
10821 post_p, is_gimple_val, fb_rvalue);
10822 /* TMR_STEP and TMR_OFFSET are always integer constants. */
10823 ret = MIN (r0, r1);
10825 break;
10827 case NON_LVALUE_EXPR:
10828 /* This should have been stripped above. */
10829 gcc_unreachable ();
10831 case ASM_EXPR:
10832 ret = gimplify_asm_expr (expr_p, pre_p, post_p);
10833 break;
10835 case TRY_FINALLY_EXPR:
10836 case TRY_CATCH_EXPR:
10838 gimple_seq eval, cleanup;
10839 gtry *try_;
10841 /* Calls to destructors are generated automatically in FINALLY/CATCH
10842 block. They should have location as UNKNOWN_LOCATION. However,
10843 gimplify_call_expr will reset these call stmts to input_location
10844 if it finds stmt's location is unknown. To prevent resetting for
10845 destructors, we set the input_location to unknown.
10846 Note that this only affects the destructor calls in FINALLY/CATCH
10847 block, and will automatically reset to its original value by the
10848 end of gimplify_expr. */
10849 input_location = UNKNOWN_LOCATION;
10850 eval = cleanup = NULL;
10851 gimplify_and_add (TREE_OPERAND (*expr_p, 0), &eval);
10852 gimplify_and_add (TREE_OPERAND (*expr_p, 1), &cleanup);
10853 /* Don't create bogus GIMPLE_TRY with empty cleanup. */
10854 if (gimple_seq_empty_p (cleanup))
10856 gimple_seq_add_seq (pre_p, eval);
10857 ret = GS_ALL_DONE;
10858 break;
10860 try_ = gimple_build_try (eval, cleanup,
10861 TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
10862 ? GIMPLE_TRY_FINALLY
10863 : GIMPLE_TRY_CATCH);
10864 if (EXPR_HAS_LOCATION (save_expr))
10865 gimple_set_location (try_, EXPR_LOCATION (save_expr));
10866 else if (LOCATION_LOCUS (saved_location) != UNKNOWN_LOCATION)
10867 gimple_set_location (try_, saved_location);
10868 if (TREE_CODE (*expr_p) == TRY_CATCH_EXPR)
10869 gimple_try_set_catch_is_cleanup (try_,
10870 TRY_CATCH_IS_CLEANUP (*expr_p));
10871 gimplify_seq_add_stmt (pre_p, try_);
10872 ret = GS_ALL_DONE;
10873 break;
10876 case CLEANUP_POINT_EXPR:
10877 ret = gimplify_cleanup_point_expr (expr_p, pre_p);
10878 break;
10880 case TARGET_EXPR:
10881 ret = gimplify_target_expr (expr_p, pre_p, post_p);
10882 break;
10884 case CATCH_EXPR:
10886 gimple *c;
10887 gimple_seq handler = NULL;
10888 gimplify_and_add (CATCH_BODY (*expr_p), &handler);
10889 c = gimple_build_catch (CATCH_TYPES (*expr_p), handler);
10890 gimplify_seq_add_stmt (pre_p, c);
10891 ret = GS_ALL_DONE;
10892 break;
10895 case EH_FILTER_EXPR:
10897 gimple *ehf;
10898 gimple_seq failure = NULL;
10900 gimplify_and_add (EH_FILTER_FAILURE (*expr_p), &failure);
10901 ehf = gimple_build_eh_filter (EH_FILTER_TYPES (*expr_p), failure);
10902 gimple_set_no_warning (ehf, TREE_NO_WARNING (*expr_p));
10903 gimplify_seq_add_stmt (pre_p, ehf);
10904 ret = GS_ALL_DONE;
10905 break;
10908 case OBJ_TYPE_REF:
10910 enum gimplify_status r0, r1;
10911 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p,
10912 post_p, is_gimple_val, fb_rvalue);
10913 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p,
10914 post_p, is_gimple_val, fb_rvalue);
10915 TREE_SIDE_EFFECTS (*expr_p) = 0;
10916 ret = MIN (r0, r1);
10918 break;
10920 case LABEL_DECL:
10921 /* We get here when taking the address of a label. We mark
10922 the label as "forced"; meaning it can never be removed and
10923 it is a potential target for any computed goto. */
10924 FORCED_LABEL (*expr_p) = 1;
10925 ret = GS_ALL_DONE;
10926 break;
10928 case STATEMENT_LIST:
10929 ret = gimplify_statement_list (expr_p, pre_p);
10930 break;
10932 case WITH_SIZE_EXPR:
10934 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
10935 post_p == &internal_post ? NULL : post_p,
10936 gimple_test_f, fallback);
10937 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
10938 is_gimple_val, fb_rvalue);
10939 ret = GS_ALL_DONE;
10941 break;
10943 case VAR_DECL:
10944 case PARM_DECL:
10945 ret = gimplify_var_or_parm_decl (expr_p);
10946 break;
10948 case RESULT_DECL:
10949 /* When within an OMP context, notice uses of variables. */
10950 if (gimplify_omp_ctxp)
10951 omp_notice_variable (gimplify_omp_ctxp, *expr_p, true);
10952 ret = GS_ALL_DONE;
10953 break;
10955 case SSA_NAME:
10956 /* Allow callbacks into the gimplifier during optimization. */
10957 ret = GS_ALL_DONE;
10958 break;
10960 case OMP_PARALLEL:
10961 gimplify_omp_parallel (expr_p, pre_p);
10962 ret = GS_ALL_DONE;
10963 break;
10965 case OMP_TASK:
10966 gimplify_omp_task (expr_p, pre_p);
10967 ret = GS_ALL_DONE;
10968 break;
10970 case OMP_FOR:
10971 case OMP_SIMD:
10972 case CILK_SIMD:
10973 case CILK_FOR:
10974 case OMP_DISTRIBUTE:
10975 case OMP_TASKLOOP:
10976 case OACC_LOOP:
10977 ret = gimplify_omp_for (expr_p, pre_p);
10978 break;
10980 case OACC_CACHE:
10981 gimplify_oacc_cache (expr_p, pre_p);
10982 ret = GS_ALL_DONE;
10983 break;
10985 case OACC_DECLARE:
10986 gimplify_oacc_declare (expr_p, pre_p);
10987 ret = GS_ALL_DONE;
10988 break;
10990 case OACC_HOST_DATA:
10991 case OACC_DATA:
10992 case OACC_KERNELS:
10993 case OACC_PARALLEL:
10994 case OMP_SECTIONS:
10995 case OMP_SINGLE:
10996 case OMP_TARGET:
10997 case OMP_TARGET_DATA:
10998 case OMP_TEAMS:
10999 gimplify_omp_workshare (expr_p, pre_p);
11000 ret = GS_ALL_DONE;
11001 break;
11003 case OACC_ENTER_DATA:
11004 case OACC_EXIT_DATA:
11005 case OACC_UPDATE:
11006 case OMP_TARGET_UPDATE:
11007 case OMP_TARGET_ENTER_DATA:
11008 case OMP_TARGET_EXIT_DATA:
11009 gimplify_omp_target_update (expr_p, pre_p);
11010 ret = GS_ALL_DONE;
11011 break;
11013 case OMP_SECTION:
11014 case OMP_MASTER:
11015 case OMP_TASKGROUP:
11016 case OMP_ORDERED:
11017 case OMP_CRITICAL:
11019 gimple_seq body = NULL;
11020 gimple *g;
11022 gimplify_and_add (OMP_BODY (*expr_p), &body);
11023 switch (TREE_CODE (*expr_p))
11025 case OMP_SECTION:
11026 g = gimple_build_omp_section (body);
11027 break;
11028 case OMP_MASTER:
11029 g = gimple_build_omp_master (body);
11030 break;
11031 case OMP_TASKGROUP:
11033 gimple_seq cleanup = NULL;
11034 tree fn
11035 = builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_END);
11036 g = gimple_build_call (fn, 0);
11037 gimple_seq_add_stmt (&cleanup, g);
11038 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
11039 body = NULL;
11040 gimple_seq_add_stmt (&body, g);
11041 g = gimple_build_omp_taskgroup (body);
11043 break;
11044 case OMP_ORDERED:
11045 g = gimplify_omp_ordered (*expr_p, body);
11046 break;
11047 case OMP_CRITICAL:
11048 gimplify_scan_omp_clauses (&OMP_CRITICAL_CLAUSES (*expr_p),
11049 pre_p, ORT_WORKSHARE, OMP_CRITICAL);
11050 gimplify_adjust_omp_clauses (pre_p, body,
11051 &OMP_CRITICAL_CLAUSES (*expr_p),
11052 OMP_CRITICAL);
11053 g = gimple_build_omp_critical (body,
11054 OMP_CRITICAL_NAME (*expr_p),
11055 OMP_CRITICAL_CLAUSES (*expr_p));
11056 break;
11057 default:
11058 gcc_unreachable ();
11060 gimplify_seq_add_stmt (pre_p, g);
11061 ret = GS_ALL_DONE;
11062 break;
11065 case OMP_ATOMIC:
11066 case OMP_ATOMIC_READ:
11067 case OMP_ATOMIC_CAPTURE_OLD:
11068 case OMP_ATOMIC_CAPTURE_NEW:
11069 ret = gimplify_omp_atomic (expr_p, pre_p);
11070 break;
11072 case TRANSACTION_EXPR:
11073 ret = gimplify_transaction (expr_p, pre_p);
11074 break;
11076 case TRUTH_AND_EXPR:
11077 case TRUTH_OR_EXPR:
11078 case TRUTH_XOR_EXPR:
11080 tree orig_type = TREE_TYPE (*expr_p);
11081 tree new_type, xop0, xop1;
11082 *expr_p = gimple_boolify (*expr_p);
11083 new_type = TREE_TYPE (*expr_p);
11084 if (!useless_type_conversion_p (orig_type, new_type))
11086 *expr_p = fold_convert_loc (input_location, orig_type, *expr_p);
11087 ret = GS_OK;
11088 break;
11091 /* Boolified binary truth expressions are semantically equivalent
11092 to bitwise binary expressions. Canonicalize them to the
11093 bitwise variant. */
11094 switch (TREE_CODE (*expr_p))
11096 case TRUTH_AND_EXPR:
11097 TREE_SET_CODE (*expr_p, BIT_AND_EXPR);
11098 break;
11099 case TRUTH_OR_EXPR:
11100 TREE_SET_CODE (*expr_p, BIT_IOR_EXPR);
11101 break;
11102 case TRUTH_XOR_EXPR:
11103 TREE_SET_CODE (*expr_p, BIT_XOR_EXPR);
11104 break;
11105 default:
11106 break;
11108 /* Now make sure that operands have compatible type to
11109 expression's new_type. */
11110 xop0 = TREE_OPERAND (*expr_p, 0);
11111 xop1 = TREE_OPERAND (*expr_p, 1);
11112 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop0)))
11113 TREE_OPERAND (*expr_p, 0) = fold_convert_loc (input_location,
11114 new_type,
11115 xop0);
11116 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop1)))
11117 TREE_OPERAND (*expr_p, 1) = fold_convert_loc (input_location,
11118 new_type,
11119 xop1);
11120 /* Continue classified as tcc_binary. */
11121 goto expr_2;
11124 case VEC_COND_EXPR:
11126 enum gimplify_status r0, r1, r2;
11128 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
11129 post_p, is_gimple_condexpr, fb_rvalue);
11130 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
11131 post_p, is_gimple_val, fb_rvalue);
11132 r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p,
11133 post_p, is_gimple_val, fb_rvalue);
11135 ret = MIN (MIN (r0, r1), r2);
11136 recalculate_side_effects (*expr_p);
11138 break;
11140 case FMA_EXPR:
11141 case VEC_PERM_EXPR:
11142 /* Classified as tcc_expression. */
11143 goto expr_3;
11145 case BIT_INSERT_EXPR:
11146 /* Argument 3 is a constant. */
11147 goto expr_2;
11149 case POINTER_PLUS_EXPR:
11151 enum gimplify_status r0, r1;
11152 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
11153 post_p, is_gimple_val, fb_rvalue);
11154 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
11155 post_p, is_gimple_val, fb_rvalue);
11156 recalculate_side_effects (*expr_p);
11157 ret = MIN (r0, r1);
11158 break;
11161 case CILK_SYNC_STMT:
11163 if (!fn_contains_cilk_spawn_p (cfun))
11165 error_at (EXPR_LOCATION (*expr_p),
11166 "expected %<_Cilk_spawn%> before %<_Cilk_sync%>");
11167 ret = GS_ERROR;
11169 else
11171 gimplify_cilk_sync (expr_p, pre_p);
11172 ret = GS_ALL_DONE;
11174 break;
11177 default:
11178 switch (TREE_CODE_CLASS (TREE_CODE (*expr_p)))
11180 case tcc_comparison:
11181 /* Handle comparison of objects of non scalar mode aggregates
11182 with a call to memcmp. It would be nice to only have to do
11183 this for variable-sized objects, but then we'd have to allow
11184 the same nest of reference nodes we allow for MODIFY_EXPR and
11185 that's too complex.
11187 Compare scalar mode aggregates as scalar mode values. Using
11188 memcmp for them would be very inefficient at best, and is
11189 plain wrong if bitfields are involved. */
11191 tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 1));
11193 /* Vector comparisons need no boolification. */
11194 if (TREE_CODE (type) == VECTOR_TYPE)
11195 goto expr_2;
11196 else if (!AGGREGATE_TYPE_P (type))
11198 tree org_type = TREE_TYPE (*expr_p);
11199 *expr_p = gimple_boolify (*expr_p);
11200 if (!useless_type_conversion_p (org_type,
11201 TREE_TYPE (*expr_p)))
11203 *expr_p = fold_convert_loc (input_location,
11204 org_type, *expr_p);
11205 ret = GS_OK;
11207 else
11208 goto expr_2;
11210 else if (TYPE_MODE (type) != BLKmode)
11211 ret = gimplify_scalar_mode_aggregate_compare (expr_p);
11212 else
11213 ret = gimplify_variable_sized_compare (expr_p);
11215 break;
11218 /* If *EXPR_P does not need to be special-cased, handle it
11219 according to its class. */
11220 case tcc_unary:
11221 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
11222 post_p, is_gimple_val, fb_rvalue);
11223 break;
11225 case tcc_binary:
11226 expr_2:
11228 enum gimplify_status r0, r1;
11230 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
11231 post_p, is_gimple_val, fb_rvalue);
11232 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
11233 post_p, is_gimple_val, fb_rvalue);
11235 ret = MIN (r0, r1);
11236 break;
11239 expr_3:
11241 enum gimplify_status r0, r1, r2;
11243 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
11244 post_p, is_gimple_val, fb_rvalue);
11245 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
11246 post_p, is_gimple_val, fb_rvalue);
11247 r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p,
11248 post_p, is_gimple_val, fb_rvalue);
11250 ret = MIN (MIN (r0, r1), r2);
11251 break;
11254 case tcc_declaration:
11255 case tcc_constant:
11256 ret = GS_ALL_DONE;
11257 goto dont_recalculate;
11259 default:
11260 gcc_unreachable ();
11263 recalculate_side_effects (*expr_p);
11265 dont_recalculate:
11266 break;
11269 gcc_assert (*expr_p || ret != GS_OK);
11271 while (ret == GS_OK);
11273 /* If we encountered an error_mark somewhere nested inside, either
11274 stub out the statement or propagate the error back out. */
11275 if (ret == GS_ERROR)
11277 if (is_statement)
11278 *expr_p = NULL;
11279 goto out;
11282 /* This was only valid as a return value from the langhook, which
11283 we handled. Make sure it doesn't escape from any other context. */
11284 gcc_assert (ret != GS_UNHANDLED);
11286 if (fallback == fb_none && *expr_p && !is_gimple_stmt (*expr_p))
11288 /* We aren't looking for a value, and we don't have a valid
11289 statement. If it doesn't have side-effects, throw it away. */
11290 if (!TREE_SIDE_EFFECTS (*expr_p))
11291 *expr_p = NULL;
11292 else if (!TREE_THIS_VOLATILE (*expr_p))
11294 /* This is probably a _REF that contains something nested that
11295 has side effects. Recurse through the operands to find it. */
11296 enum tree_code code = TREE_CODE (*expr_p);
11298 switch (code)
11300 case COMPONENT_REF:
11301 case REALPART_EXPR:
11302 case IMAGPART_EXPR:
11303 case VIEW_CONVERT_EXPR:
11304 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
11305 gimple_test_f, fallback);
11306 break;
11308 case ARRAY_REF:
11309 case ARRAY_RANGE_REF:
11310 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
11311 gimple_test_f, fallback);
11312 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
11313 gimple_test_f, fallback);
11314 break;
11316 default:
11317 /* Anything else with side-effects must be converted to
11318 a valid statement before we get here. */
11319 gcc_unreachable ();
11322 *expr_p = NULL;
11324 else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p))
11325 && TYPE_MODE (TREE_TYPE (*expr_p)) != BLKmode)
11327 /* Historically, the compiler has treated a bare reference
11328 to a non-BLKmode volatile lvalue as forcing a load. */
11329 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p));
11331 /* Normally, we do not want to create a temporary for a
11332 TREE_ADDRESSABLE type because such a type should not be
11333 copied by bitwise-assignment. However, we make an
11334 exception here, as all we are doing here is ensuring that
11335 we read the bytes that make up the type. We use
11336 create_tmp_var_raw because create_tmp_var will abort when
11337 given a TREE_ADDRESSABLE type. */
11338 tree tmp = create_tmp_var_raw (type, "vol");
11339 gimple_add_tmp_var (tmp);
11340 gimplify_assign (tmp, *expr_p, pre_p);
11341 *expr_p = NULL;
11343 else
11344 /* We can't do anything useful with a volatile reference to
11345 an incomplete type, so just throw it away. Likewise for
11346 a BLKmode type, since any implicit inner load should
11347 already have been turned into an explicit one by the
11348 gimplification process. */
11349 *expr_p = NULL;
11352 /* If we are gimplifying at the statement level, we're done. Tack
11353 everything together and return. */
11354 if (fallback == fb_none || is_statement)
11356 /* Since *EXPR_P has been converted into a GIMPLE tuple, clear
11357 it out for GC to reclaim it. */
11358 *expr_p = NULL_TREE;
11360 if (!gimple_seq_empty_p (internal_pre)
11361 || !gimple_seq_empty_p (internal_post))
11363 gimplify_seq_add_seq (&internal_pre, internal_post);
11364 gimplify_seq_add_seq (pre_p, internal_pre);
11367 /* The result of gimplifying *EXPR_P is going to be the last few
11368 statements in *PRE_P and *POST_P. Add location information
11369 to all the statements that were added by the gimplification
11370 helpers. */
11371 if (!gimple_seq_empty_p (*pre_p))
11372 annotate_all_with_location_after (*pre_p, pre_last_gsi, input_location);
11374 if (!gimple_seq_empty_p (*post_p))
11375 annotate_all_with_location_after (*post_p, post_last_gsi,
11376 input_location);
11378 goto out;
11381 #ifdef ENABLE_GIMPLE_CHECKING
11382 if (*expr_p)
11384 enum tree_code code = TREE_CODE (*expr_p);
11385 /* These expressions should already be in gimple IR form. */
11386 gcc_assert (code != MODIFY_EXPR
11387 && code != ASM_EXPR
11388 && code != BIND_EXPR
11389 && code != CATCH_EXPR
11390 && (code != COND_EXPR || gimplify_ctxp->allow_rhs_cond_expr)
11391 && code != EH_FILTER_EXPR
11392 && code != GOTO_EXPR
11393 && code != LABEL_EXPR
11394 && code != LOOP_EXPR
11395 && code != SWITCH_EXPR
11396 && code != TRY_FINALLY_EXPR
11397 && code != OACC_PARALLEL
11398 && code != OACC_KERNELS
11399 && code != OACC_DATA
11400 && code != OACC_HOST_DATA
11401 && code != OACC_DECLARE
11402 && code != OACC_UPDATE
11403 && code != OACC_ENTER_DATA
11404 && code != OACC_EXIT_DATA
11405 && code != OACC_CACHE
11406 && code != OMP_CRITICAL
11407 && code != OMP_FOR
11408 && code != OACC_LOOP
11409 && code != OMP_MASTER
11410 && code != OMP_TASKGROUP
11411 && code != OMP_ORDERED
11412 && code != OMP_PARALLEL
11413 && code != OMP_SECTIONS
11414 && code != OMP_SECTION
11415 && code != OMP_SINGLE);
11417 #endif
11419 /* Otherwise we're gimplifying a subexpression, so the resulting
11420 value is interesting. If it's a valid operand that matches
11421 GIMPLE_TEST_F, we're done. Unless we are handling some
11422 post-effects internally; if that's the case, we need to copy into
11423 a temporary before adding the post-effects to POST_P. */
11424 if (gimple_seq_empty_p (internal_post) && (*gimple_test_f) (*expr_p))
11425 goto out;
11427 /* Otherwise, we need to create a new temporary for the gimplified
11428 expression. */
11430 /* We can't return an lvalue if we have an internal postqueue. The
11431 object the lvalue refers to would (probably) be modified by the
11432 postqueue; we need to copy the value out first, which means an
11433 rvalue. */
11434 if ((fallback & fb_lvalue)
11435 && gimple_seq_empty_p (internal_post)
11436 && is_gimple_addressable (*expr_p))
11438 /* An lvalue will do. Take the address of the expression, store it
11439 in a temporary, and replace the expression with an INDIRECT_REF of
11440 that temporary. */
11441 tmp = build_fold_addr_expr_loc (input_location, *expr_p);
11442 gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue);
11443 *expr_p = build_simple_mem_ref (tmp);
11445 else if ((fallback & fb_rvalue) && is_gimple_reg_rhs_or_call (*expr_p))
11447 /* An rvalue will do. Assign the gimplified expression into a
11448 new temporary TMP and replace the original expression with
11449 TMP. First, make sure that the expression has a type so that
11450 it can be assigned into a temporary. */
11451 gcc_assert (!VOID_TYPE_P (TREE_TYPE (*expr_p)));
11452 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
11454 else
11456 #ifdef ENABLE_GIMPLE_CHECKING
11457 if (!(fallback & fb_mayfail))
11459 fprintf (stderr, "gimplification failed:\n");
11460 print_generic_expr (stderr, *expr_p, 0);
11461 debug_tree (*expr_p);
11462 internal_error ("gimplification failed");
11464 #endif
11465 gcc_assert (fallback & fb_mayfail);
11467 /* If this is an asm statement, and the user asked for the
11468 impossible, don't die. Fail and let gimplify_asm_expr
11469 issue an error. */
11470 ret = GS_ERROR;
11471 goto out;
11474 /* Make sure the temporary matches our predicate. */
11475 gcc_assert ((*gimple_test_f) (*expr_p));
11477 if (!gimple_seq_empty_p (internal_post))
11479 annotate_all_with_location (internal_post, input_location);
11480 gimplify_seq_add_seq (pre_p, internal_post);
11483 out:
11484 input_location = saved_location;
11485 return ret;
11488 /* Like gimplify_expr but make sure the gimplified result is not itself
11489 a SSA name (but a decl if it were). Temporaries required by
11490 evaluating *EXPR_P may be still SSA names. */
11492 static enum gimplify_status
11493 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
11494 bool (*gimple_test_f) (tree), fallback_t fallback,
11495 bool allow_ssa)
11497 bool was_ssa_name_p = TREE_CODE (*expr_p) == SSA_NAME;
11498 enum gimplify_status ret = gimplify_expr (expr_p, pre_p, post_p,
11499 gimple_test_f, fallback);
11500 if (! allow_ssa
11501 && TREE_CODE (*expr_p) == SSA_NAME)
11503 tree name = *expr_p;
11504 if (was_ssa_name_p)
11505 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, NULL, false);
11506 else
11508 /* Avoid the extra copy if possible. */
11509 *expr_p = create_tmp_reg (TREE_TYPE (name));
11510 gimple_set_lhs (SSA_NAME_DEF_STMT (name), *expr_p);
11511 release_ssa_name (name);
11514 return ret;
11517 /* Look through TYPE for variable-sized objects and gimplify each such
11518 size that we find. Add to LIST_P any statements generated. */
11520 void
11521 gimplify_type_sizes (tree type, gimple_seq *list_p)
11523 tree field, t;
11525 if (type == NULL || type == error_mark_node)
11526 return;
11528 /* We first do the main variant, then copy into any other variants. */
11529 type = TYPE_MAIN_VARIANT (type);
11531 /* Avoid infinite recursion. */
11532 if (TYPE_SIZES_GIMPLIFIED (type))
11533 return;
11535 TYPE_SIZES_GIMPLIFIED (type) = 1;
11537 switch (TREE_CODE (type))
11539 case INTEGER_TYPE:
11540 case ENUMERAL_TYPE:
11541 case BOOLEAN_TYPE:
11542 case REAL_TYPE:
11543 case FIXED_POINT_TYPE:
11544 gimplify_one_sizepos (&TYPE_MIN_VALUE (type), list_p);
11545 gimplify_one_sizepos (&TYPE_MAX_VALUE (type), list_p);
11547 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
11549 TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type);
11550 TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type);
11552 break;
11554 case ARRAY_TYPE:
11555 /* These types may not have declarations, so handle them here. */
11556 gimplify_type_sizes (TREE_TYPE (type), list_p);
11557 gimplify_type_sizes (TYPE_DOMAIN (type), list_p);
11558 /* Ensure VLA bounds aren't removed, for -O0 they should be variables
11559 with assigned stack slots, for -O1+ -g they should be tracked
11560 by VTA. */
11561 if (!(TYPE_NAME (type)
11562 && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
11563 && DECL_IGNORED_P (TYPE_NAME (type)))
11564 && TYPE_DOMAIN (type)
11565 && INTEGRAL_TYPE_P (TYPE_DOMAIN (type)))
11567 t = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
11568 if (t && TREE_CODE (t) == VAR_DECL && DECL_ARTIFICIAL (t))
11569 DECL_IGNORED_P (t) = 0;
11570 t = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
11571 if (t && TREE_CODE (t) == VAR_DECL && DECL_ARTIFICIAL (t))
11572 DECL_IGNORED_P (t) = 0;
11574 break;
11576 case RECORD_TYPE:
11577 case UNION_TYPE:
11578 case QUAL_UNION_TYPE:
11579 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
11580 if (TREE_CODE (field) == FIELD_DECL)
11582 gimplify_one_sizepos (&DECL_FIELD_OFFSET (field), list_p);
11583 gimplify_one_sizepos (&DECL_SIZE (field), list_p);
11584 gimplify_one_sizepos (&DECL_SIZE_UNIT (field), list_p);
11585 gimplify_type_sizes (TREE_TYPE (field), list_p);
11587 break;
11589 case POINTER_TYPE:
11590 case REFERENCE_TYPE:
11591 /* We used to recurse on the pointed-to type here, which turned out to
11592 be incorrect because its definition might refer to variables not
11593 yet initialized at this point if a forward declaration is involved.
11595 It was actually useful for anonymous pointed-to types to ensure
11596 that the sizes evaluation dominates every possible later use of the
11597 values. Restricting to such types here would be safe since there
11598 is no possible forward declaration around, but would introduce an
11599 undesirable middle-end semantic to anonymity. We then defer to
11600 front-ends the responsibility of ensuring that the sizes are
11601 evaluated both early and late enough, e.g. by attaching artificial
11602 type declarations to the tree. */
11603 break;
11605 default:
11606 break;
11609 gimplify_one_sizepos (&TYPE_SIZE (type), list_p);
11610 gimplify_one_sizepos (&TYPE_SIZE_UNIT (type), list_p);
11612 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
11614 TYPE_SIZE (t) = TYPE_SIZE (type);
11615 TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (type);
11616 TYPE_SIZES_GIMPLIFIED (t) = 1;
11620 /* A subroutine of gimplify_type_sizes to make sure that *EXPR_P,
11621 a size or position, has had all of its SAVE_EXPRs evaluated.
11622 We add any required statements to *STMT_P. */
11624 void
11625 gimplify_one_sizepos (tree *expr_p, gimple_seq *stmt_p)
11627 tree expr = *expr_p;
11629 /* We don't do anything if the value isn't there, is constant, or contains
11630 A PLACEHOLDER_EXPR. We also don't want to do anything if it's already
11631 a VAR_DECL. If it's a VAR_DECL from another function, the gimplifier
11632 will want to replace it with a new variable, but that will cause problems
11633 if this type is from outside the function. It's OK to have that here. */
11634 if (is_gimple_sizepos (expr))
11635 return;
11637 *expr_p = unshare_expr (expr);
11639 /* SSA names in decl/type fields are a bad idea - they'll get reclaimed
11640 if the def vanishes. */
11641 gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue, false);
11644 /* Gimplify the body of statements of FNDECL and return a GIMPLE_BIND node
11645 containing the sequence of corresponding GIMPLE statements. If DO_PARMS
11646 is true, also gimplify the parameters. */
11648 gbind *
11649 gimplify_body (tree fndecl, bool do_parms)
11651 location_t saved_location = input_location;
11652 gimple_seq parm_stmts, seq;
11653 gimple *outer_stmt;
11654 gbind *outer_bind;
11655 struct cgraph_node *cgn;
11657 timevar_push (TV_TREE_GIMPLIFY);
11659 init_tree_ssa (cfun);
11661 /* Initialize for optimize_insn_for_s{ize,peed}_p possibly called during
11662 gimplification. */
11663 default_rtl_profile ();
11665 gcc_assert (gimplify_ctxp == NULL);
11666 push_gimplify_context (true);
11668 if (flag_openacc || flag_openmp)
11670 gcc_assert (gimplify_omp_ctxp == NULL);
11671 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (fndecl)))
11672 gimplify_omp_ctxp = new_omp_context (ORT_TARGET);
11675 /* Unshare most shared trees in the body and in that of any nested functions.
11676 It would seem we don't have to do this for nested functions because
11677 they are supposed to be output and then the outer function gimplified
11678 first, but the g++ front end doesn't always do it that way. */
11679 unshare_body (fndecl);
11680 unvisit_body (fndecl);
11682 cgn = cgraph_node::get (fndecl);
11683 if (cgn && cgn->origin)
11684 nonlocal_vlas = new hash_set<tree>;
11686 /* Make sure input_location isn't set to something weird. */
11687 input_location = DECL_SOURCE_LOCATION (fndecl);
11689 /* Resolve callee-copies. This has to be done before processing
11690 the body so that DECL_VALUE_EXPR gets processed correctly. */
11691 parm_stmts = do_parms ? gimplify_parameters () : NULL;
11693 /* Gimplify the function's body. */
11694 seq = NULL;
11695 gimplify_stmt (&DECL_SAVED_TREE (fndecl), &seq);
11696 outer_stmt = gimple_seq_first_stmt (seq);
11697 if (!outer_stmt)
11699 outer_stmt = gimple_build_nop ();
11700 gimplify_seq_add_stmt (&seq, outer_stmt);
11703 /* The body must contain exactly one statement, a GIMPLE_BIND. If this is
11704 not the case, wrap everything in a GIMPLE_BIND to make it so. */
11705 if (gimple_code (outer_stmt) == GIMPLE_BIND
11706 && gimple_seq_first (seq) == gimple_seq_last (seq))
11707 outer_bind = as_a <gbind *> (outer_stmt);
11708 else
11709 outer_bind = gimple_build_bind (NULL_TREE, seq, NULL);
11711 DECL_SAVED_TREE (fndecl) = NULL_TREE;
11713 /* If we had callee-copies statements, insert them at the beginning
11714 of the function and clear DECL_VALUE_EXPR_P on the parameters. */
11715 if (!gimple_seq_empty_p (parm_stmts))
11717 tree parm;
11719 gimplify_seq_add_seq (&parm_stmts, gimple_bind_body (outer_bind));
11720 gimple_bind_set_body (outer_bind, parm_stmts);
11722 for (parm = DECL_ARGUMENTS (current_function_decl);
11723 parm; parm = DECL_CHAIN (parm))
11724 if (DECL_HAS_VALUE_EXPR_P (parm))
11726 DECL_HAS_VALUE_EXPR_P (parm) = 0;
11727 DECL_IGNORED_P (parm) = 0;
11731 if (nonlocal_vlas)
11733 if (nonlocal_vla_vars)
11735 /* tree-nested.c may later on call declare_vars (..., true);
11736 which relies on BLOCK_VARS chain to be the tail of the
11737 gimple_bind_vars chain. Ensure we don't violate that
11738 assumption. */
11739 if (gimple_bind_block (outer_bind)
11740 == DECL_INITIAL (current_function_decl))
11741 declare_vars (nonlocal_vla_vars, outer_bind, true);
11742 else
11743 BLOCK_VARS (DECL_INITIAL (current_function_decl))
11744 = chainon (BLOCK_VARS (DECL_INITIAL (current_function_decl)),
11745 nonlocal_vla_vars);
11746 nonlocal_vla_vars = NULL_TREE;
11748 delete nonlocal_vlas;
11749 nonlocal_vlas = NULL;
11752 if ((flag_openacc || flag_openmp || flag_openmp_simd)
11753 && gimplify_omp_ctxp)
11755 delete_omp_context (gimplify_omp_ctxp);
11756 gimplify_omp_ctxp = NULL;
11759 pop_gimplify_context (outer_bind);
11760 gcc_assert (gimplify_ctxp == NULL);
11762 if (flag_checking && !seen_error ())
11763 verify_gimple_in_seq (gimple_bind_body (outer_bind));
11765 timevar_pop (TV_TREE_GIMPLIFY);
11766 input_location = saved_location;
11768 return outer_bind;
11771 typedef char *char_p; /* For DEF_VEC_P. */
11773 /* Return whether we should exclude FNDECL from instrumentation. */
11775 static bool
11776 flag_instrument_functions_exclude_p (tree fndecl)
11778 vec<char_p> *v;
11780 v = (vec<char_p> *) flag_instrument_functions_exclude_functions;
11781 if (v && v->length () > 0)
11783 const char *name;
11784 int i;
11785 char *s;
11787 name = lang_hooks.decl_printable_name (fndecl, 0);
11788 FOR_EACH_VEC_ELT (*v, i, s)
11789 if (strstr (name, s) != NULL)
11790 return true;
11793 v = (vec<char_p> *) flag_instrument_functions_exclude_files;
11794 if (v && v->length () > 0)
11796 const char *name;
11797 int i;
11798 char *s;
11800 name = DECL_SOURCE_FILE (fndecl);
11801 FOR_EACH_VEC_ELT (*v, i, s)
11802 if (strstr (name, s) != NULL)
11803 return true;
11806 return false;
11809 /* Entry point to the gimplification pass. FNDECL is the FUNCTION_DECL
11810 node for the function we want to gimplify.
11812 Return the sequence of GIMPLE statements corresponding to the body
11813 of FNDECL. */
11815 void
11816 gimplify_function_tree (tree fndecl)
11818 tree parm, ret;
11819 gimple_seq seq;
11820 gbind *bind;
11822 gcc_assert (!gimple_body (fndecl));
11824 if (DECL_STRUCT_FUNCTION (fndecl))
11825 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
11826 else
11827 push_struct_function (fndecl);
11829 /* Tentatively set PROP_gimple_lva here, and reset it in gimplify_va_arg_expr
11830 if necessary. */
11831 cfun->curr_properties |= PROP_gimple_lva;
11833 for (parm = DECL_ARGUMENTS (fndecl); parm ; parm = DECL_CHAIN (parm))
11835 /* Preliminarily mark non-addressed complex variables as eligible
11836 for promotion to gimple registers. We'll transform their uses
11837 as we find them. */
11838 if ((TREE_CODE (TREE_TYPE (parm)) == COMPLEX_TYPE
11839 || TREE_CODE (TREE_TYPE (parm)) == VECTOR_TYPE)
11840 && !TREE_THIS_VOLATILE (parm)
11841 && !needs_to_live_in_memory (parm))
11842 DECL_GIMPLE_REG_P (parm) = 1;
11845 ret = DECL_RESULT (fndecl);
11846 if ((TREE_CODE (TREE_TYPE (ret)) == COMPLEX_TYPE
11847 || TREE_CODE (TREE_TYPE (ret)) == VECTOR_TYPE)
11848 && !needs_to_live_in_memory (ret))
11849 DECL_GIMPLE_REG_P (ret) = 1;
11851 bind = gimplify_body (fndecl, true);
11853 /* The tree body of the function is no longer needed, replace it
11854 with the new GIMPLE body. */
11855 seq = NULL;
11856 gimple_seq_add_stmt (&seq, bind);
11857 gimple_set_body (fndecl, seq);
11859 /* If we're instrumenting function entry/exit, then prepend the call to
11860 the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to
11861 catch the exit hook. */
11862 /* ??? Add some way to ignore exceptions for this TFE. */
11863 if (flag_instrument_function_entry_exit
11864 && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl)
11865 && !flag_instrument_functions_exclude_p (fndecl))
11867 tree x;
11868 gbind *new_bind;
11869 gimple *tf;
11870 gimple_seq cleanup = NULL, body = NULL;
11871 tree tmp_var;
11872 gcall *call;
11874 x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
11875 call = gimple_build_call (x, 1, integer_zero_node);
11876 tmp_var = create_tmp_var (ptr_type_node, "return_addr");
11877 gimple_call_set_lhs (call, tmp_var);
11878 gimplify_seq_add_stmt (&cleanup, call);
11879 x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_EXIT);
11880 call = gimple_build_call (x, 2,
11881 build_fold_addr_expr (current_function_decl),
11882 tmp_var);
11883 gimplify_seq_add_stmt (&cleanup, call);
11884 tf = gimple_build_try (seq, cleanup, GIMPLE_TRY_FINALLY);
11886 x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
11887 call = gimple_build_call (x, 1, integer_zero_node);
11888 tmp_var = create_tmp_var (ptr_type_node, "return_addr");
11889 gimple_call_set_lhs (call, tmp_var);
11890 gimplify_seq_add_stmt (&body, call);
11891 x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_ENTER);
11892 call = gimple_build_call (x, 2,
11893 build_fold_addr_expr (current_function_decl),
11894 tmp_var);
11895 gimplify_seq_add_stmt (&body, call);
11896 gimplify_seq_add_stmt (&body, tf);
11897 new_bind = gimple_build_bind (NULL, body, gimple_bind_block (bind));
11898 /* Clear the block for BIND, since it is no longer directly inside
11899 the function, but within a try block. */
11900 gimple_bind_set_block (bind, NULL);
11902 /* Replace the current function body with the body
11903 wrapped in the try/finally TF. */
11904 seq = NULL;
11905 gimple_seq_add_stmt (&seq, new_bind);
11906 gimple_set_body (fndecl, seq);
11907 bind = new_bind;
11910 if ((flag_sanitize & SANITIZE_THREAD) != 0
11911 && !lookup_attribute ("no_sanitize_thread", DECL_ATTRIBUTES (fndecl)))
11913 gcall *call = gimple_build_call_internal (IFN_TSAN_FUNC_EXIT, 0);
11914 gimple *tf = gimple_build_try (seq, call, GIMPLE_TRY_FINALLY);
11915 gbind *new_bind = gimple_build_bind (NULL, tf, gimple_bind_block (bind));
11916 /* Clear the block for BIND, since it is no longer directly inside
11917 the function, but within a try block. */
11918 gimple_bind_set_block (bind, NULL);
11919 /* Replace the current function body with the body
11920 wrapped in the try/finally TF. */
11921 seq = NULL;
11922 gimple_seq_add_stmt (&seq, new_bind);
11923 gimple_set_body (fndecl, seq);
11926 DECL_SAVED_TREE (fndecl) = NULL_TREE;
11927 cfun->curr_properties |= PROP_gimple_any;
11929 pop_cfun ();
11931 dump_function (TDI_generic, fndecl);
11934 /* Return a dummy expression of type TYPE in order to keep going after an
11935 error. */
11937 static tree
11938 dummy_object (tree type)
11940 tree t = build_int_cst (build_pointer_type (type), 0);
11941 return build2 (MEM_REF, type, t, t);
11944 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
11945 builtin function, but a very special sort of operator. */
11947 enum gimplify_status
11948 gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p,
11949 gimple_seq *post_p ATTRIBUTE_UNUSED)
11951 tree promoted_type, have_va_type;
11952 tree valist = TREE_OPERAND (*expr_p, 0);
11953 tree type = TREE_TYPE (*expr_p);
11954 tree t, tag, aptag;
11955 location_t loc = EXPR_LOCATION (*expr_p);
11957 /* Verify that valist is of the proper type. */
11958 have_va_type = TREE_TYPE (valist);
11959 if (have_va_type == error_mark_node)
11960 return GS_ERROR;
11961 have_va_type = targetm.canonical_va_list_type (have_va_type);
11963 if (have_va_type == NULL_TREE)
11965 error_at (loc, "first argument to %<va_arg%> not of type %<va_list%>");
11966 return GS_ERROR;
11969 /* Generate a diagnostic for requesting data of a type that cannot
11970 be passed through `...' due to type promotion at the call site. */
11971 if ((promoted_type = lang_hooks.types.type_promotes_to (type))
11972 != type)
11974 static bool gave_help;
11975 bool warned;
11976 /* Use the expansion point to handle cases such as passing bool (defined
11977 in a system header) through `...'. */
11978 source_location xloc
11979 = expansion_point_location_if_in_system_header (loc);
11981 /* Unfortunately, this is merely undefined, rather than a constraint
11982 violation, so we cannot make this an error. If this call is never
11983 executed, the program is still strictly conforming. */
11984 warned = warning_at (xloc, 0,
11985 "%qT is promoted to %qT when passed through %<...%>",
11986 type, promoted_type);
11987 if (!gave_help && warned)
11989 gave_help = true;
11990 inform (xloc, "(so you should pass %qT not %qT to %<va_arg%>)",
11991 promoted_type, type);
11994 /* We can, however, treat "undefined" any way we please.
11995 Call abort to encourage the user to fix the program. */
11996 if (warned)
11997 inform (xloc, "if this code is reached, the program will abort");
11998 /* Before the abort, allow the evaluation of the va_list
11999 expression to exit or longjmp. */
12000 gimplify_and_add (valist, pre_p);
12001 t = build_call_expr_loc (loc,
12002 builtin_decl_implicit (BUILT_IN_TRAP), 0);
12003 gimplify_and_add (t, pre_p);
12005 /* This is dead code, but go ahead and finish so that the
12006 mode of the result comes out right. */
12007 *expr_p = dummy_object (type);
12008 return GS_ALL_DONE;
12011 tag = build_int_cst (build_pointer_type (type), 0);
12012 aptag = build_int_cst (TREE_TYPE (valist), 0);
12014 *expr_p = build_call_expr_internal_loc (loc, IFN_VA_ARG, type, 3,
12015 valist, tag, aptag);
12017 /* Clear the tentatively set PROP_gimple_lva, to indicate that IFN_VA_ARG
12018 needs to be expanded. */
12019 cfun->curr_properties &= ~PROP_gimple_lva;
12021 return GS_OK;
12024 /* Build a new GIMPLE_ASSIGN tuple and append it to the end of *SEQ_P.
12026 DST/SRC are the destination and source respectively. You can pass
12027 ungimplified trees in DST or SRC, in which case they will be
12028 converted to a gimple operand if necessary.
12030 This function returns the newly created GIMPLE_ASSIGN tuple. */
12032 gimple *
12033 gimplify_assign (tree dst, tree src, gimple_seq *seq_p)
12035 tree t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
12036 gimplify_and_add (t, seq_p);
12037 ggc_free (t);
12038 return gimple_seq_last_stmt (*seq_p);
12041 inline hashval_t
12042 gimplify_hasher::hash (const elt_t *p)
12044 tree t = p->val;
12045 return iterative_hash_expr (t, 0);
12048 inline bool
12049 gimplify_hasher::equal (const elt_t *p1, const elt_t *p2)
12051 tree t1 = p1->val;
12052 tree t2 = p2->val;
12053 enum tree_code code = TREE_CODE (t1);
12055 if (TREE_CODE (t2) != code
12056 || TREE_TYPE (t1) != TREE_TYPE (t2))
12057 return false;
12059 if (!operand_equal_p (t1, t2, 0))
12060 return false;
12062 /* Only allow them to compare equal if they also hash equal; otherwise
12063 results are nondeterminate, and we fail bootstrap comparison. */
12064 gcc_checking_assert (hash (p1) == hash (p2));
12066 return true;