Skip gcc.dg/guality/example.c on hppa-linux.
[official-gcc.git] / gcc / gimplify.c
blobb118c72f62c43d3cd67f1c6ba36e3786529acb12
1 /* Tree lowering pass. This pass converts the GENERIC functions-as-trees
2 tree representation into the GIMPLE form.
3 Copyright (C) 2002-2021 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 "memmodel.h"
31 #include "tm_p.h"
32 #include "gimple.h"
33 #include "gimple-predict.h"
34 #include "tree-pass.h" /* FIXME: only for PROP_gimple_any */
35 #include "ssa.h"
36 #include "cgraph.h"
37 #include "tree-pretty-print.h"
38 #include "diagnostic-core.h"
39 #include "alias.h"
40 #include "fold-const.h"
41 #include "calls.h"
42 #include "varasm.h"
43 #include "stmt.h"
44 #include "expr.h"
45 #include "gimple-fold.h"
46 #include "tree-eh.h"
47 #include "gimplify.h"
48 #include "gimple-iterator.h"
49 #include "stor-layout.h"
50 #include "print-tree.h"
51 #include "tree-iterator.h"
52 #include "tree-inline.h"
53 #include "langhooks.h"
54 #include "tree-cfg.h"
55 #include "tree-ssa.h"
56 #include "tree-hash-traits.h"
57 #include "omp-general.h"
58 #include "omp-low.h"
59 #include "gimple-low.h"
60 #include "gomp-constants.h"
61 #include "splay-tree.h"
62 #include "gimple-walk.h"
63 #include "langhooks-def.h" /* FIXME: for lhd_set_decl_assembler_name */
64 #include "builtins.h"
65 #include "stringpool.h"
66 #include "attribs.h"
67 #include "asan.h"
68 #include "dbgcnt.h"
69 #include "omp-offload.h"
70 #include "context.h"
71 #include "tree-nested.h"
73 /* Hash set of poisoned variables in a bind expr. */
74 static hash_set<tree> *asan_poisoned_variables = NULL;
76 enum gimplify_omp_var_data
78 GOVD_SEEN = 0x000001,
79 GOVD_EXPLICIT = 0x000002,
80 GOVD_SHARED = 0x000004,
81 GOVD_PRIVATE = 0x000008,
82 GOVD_FIRSTPRIVATE = 0x000010,
83 GOVD_LASTPRIVATE = 0x000020,
84 GOVD_REDUCTION = 0x000040,
85 GOVD_LOCAL = 0x00080,
86 GOVD_MAP = 0x000100,
87 GOVD_DEBUG_PRIVATE = 0x000200,
88 GOVD_PRIVATE_OUTER_REF = 0x000400,
89 GOVD_LINEAR = 0x000800,
90 GOVD_ALIGNED = 0x001000,
92 /* Flag for GOVD_MAP: don't copy back. */
93 GOVD_MAP_TO_ONLY = 0x002000,
95 /* Flag for GOVD_LINEAR or GOVD_LASTPRIVATE: no outer reference. */
96 GOVD_LINEAR_LASTPRIVATE_NO_OUTER = 0x004000,
98 GOVD_MAP_0LEN_ARRAY = 0x008000,
100 /* Flag for GOVD_MAP, if it is always, to or always, tofrom mapping. */
101 GOVD_MAP_ALWAYS_TO = 0x010000,
103 /* Flag for shared vars that are or might be stored to in the region. */
104 GOVD_WRITTEN = 0x020000,
106 /* Flag for GOVD_MAP, if it is a forced mapping. */
107 GOVD_MAP_FORCE = 0x040000,
109 /* Flag for GOVD_MAP: must be present already. */
110 GOVD_MAP_FORCE_PRESENT = 0x080000,
112 /* Flag for GOVD_MAP: only allocate. */
113 GOVD_MAP_ALLOC_ONLY = 0x100000,
115 /* Flag for GOVD_MAP: only copy back. */
116 GOVD_MAP_FROM_ONLY = 0x200000,
118 GOVD_NONTEMPORAL = 0x400000,
120 /* Flag for GOVD_LASTPRIVATE: conditional modifier. */
121 GOVD_LASTPRIVATE_CONDITIONAL = 0x800000,
123 GOVD_CONDTEMP = 0x1000000,
125 /* Flag for GOVD_REDUCTION: inscan seen in {in,ex}clusive clause. */
126 GOVD_REDUCTION_INSCAN = 0x2000000,
128 /* Flag for GOVD_MAP: (struct) vars that have pointer attachments for
129 fields. */
130 GOVD_MAP_HAS_ATTACHMENTS = 0x4000000,
132 /* Flag for GOVD_FIRSTPRIVATE: OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT. */
133 GOVD_FIRSTPRIVATE_IMPLICIT = 0x8000000,
135 GOVD_DATA_SHARE_CLASS = (GOVD_SHARED | GOVD_PRIVATE | GOVD_FIRSTPRIVATE
136 | GOVD_LASTPRIVATE | GOVD_REDUCTION | GOVD_LINEAR
137 | GOVD_LOCAL)
141 enum omp_region_type
143 ORT_WORKSHARE = 0x00,
144 ORT_TASKGROUP = 0x01,
145 ORT_SIMD = 0x04,
147 ORT_PARALLEL = 0x08,
148 ORT_COMBINED_PARALLEL = ORT_PARALLEL | 1,
150 ORT_TASK = 0x10,
151 ORT_UNTIED_TASK = ORT_TASK | 1,
152 ORT_TASKLOOP = ORT_TASK | 2,
153 ORT_UNTIED_TASKLOOP = ORT_UNTIED_TASK | 2,
155 ORT_TEAMS = 0x20,
156 ORT_COMBINED_TEAMS = ORT_TEAMS | 1,
157 ORT_HOST_TEAMS = ORT_TEAMS | 2,
158 ORT_COMBINED_HOST_TEAMS = ORT_COMBINED_TEAMS | 2,
160 /* Data region. */
161 ORT_TARGET_DATA = 0x40,
163 /* Data region with offloading. */
164 ORT_TARGET = 0x80,
165 ORT_COMBINED_TARGET = ORT_TARGET | 1,
166 ORT_IMPLICIT_TARGET = ORT_TARGET | 2,
168 /* OpenACC variants. */
169 ORT_ACC = 0x100, /* A generic OpenACC region. */
170 ORT_ACC_DATA = ORT_ACC | ORT_TARGET_DATA, /* Data construct. */
171 ORT_ACC_PARALLEL = ORT_ACC | ORT_TARGET, /* Parallel construct */
172 ORT_ACC_KERNELS = ORT_ACC | ORT_TARGET | 2, /* Kernels construct. */
173 ORT_ACC_SERIAL = ORT_ACC | ORT_TARGET | 4, /* Serial construct. */
174 ORT_ACC_HOST_DATA = ORT_ACC | ORT_TARGET_DATA | 2, /* Host data. */
176 /* Dummy OpenMP region, used to disable expansion of
177 DECL_VALUE_EXPRs in taskloop pre body. */
178 ORT_NONE = 0x200
181 /* Gimplify hashtable helper. */
183 struct gimplify_hasher : free_ptr_hash <elt_t>
185 static inline hashval_t hash (const elt_t *);
186 static inline bool equal (const elt_t *, const elt_t *);
189 struct gimplify_ctx
191 struct gimplify_ctx *prev_context;
193 vec<gbind *> bind_expr_stack;
194 tree temps;
195 gimple_seq conditional_cleanups;
196 tree exit_label;
197 tree return_temp;
199 vec<tree> case_labels;
200 hash_set<tree> *live_switch_vars;
201 /* The formal temporary table. Should this be persistent? */
202 hash_table<gimplify_hasher> *temp_htab;
204 int conditions;
205 unsigned into_ssa : 1;
206 unsigned allow_rhs_cond_expr : 1;
207 unsigned in_cleanup_point_expr : 1;
208 unsigned keep_stack : 1;
209 unsigned save_stack : 1;
210 unsigned in_switch_expr : 1;
213 enum gimplify_defaultmap_kind
215 GDMK_SCALAR,
216 GDMK_SCALAR_TARGET, /* w/ Fortran's target attr, implicit mapping, only. */
217 GDMK_AGGREGATE,
218 GDMK_ALLOCATABLE,
219 GDMK_POINTER
222 struct gimplify_omp_ctx
224 struct gimplify_omp_ctx *outer_context;
225 splay_tree variables;
226 hash_set<tree> *privatized_types;
227 tree clauses;
228 /* Iteration variables in an OMP_FOR. */
229 vec<tree> loop_iter_var;
230 location_t location;
231 enum omp_clause_default_kind default_kind;
232 enum omp_region_type region_type;
233 enum tree_code code;
234 bool combined_loop;
235 bool distribute;
236 bool target_firstprivatize_array_bases;
237 bool add_safelen1;
238 bool order_concurrent;
239 bool has_depend;
240 bool in_for_exprs;
241 int defaultmap[5];
244 static struct gimplify_ctx *gimplify_ctxp;
245 static struct gimplify_omp_ctx *gimplify_omp_ctxp;
246 static bool in_omp_construct;
248 /* Forward declaration. */
249 static enum gimplify_status gimplify_compound_expr (tree *, gimple_seq *, bool);
250 static hash_map<tree, tree> *oacc_declare_returns;
251 static enum gimplify_status gimplify_expr (tree *, gimple_seq *, gimple_seq *,
252 bool (*) (tree), fallback_t, bool);
254 /* Shorter alias name for the above function for use in gimplify.c
255 only. */
257 static inline void
258 gimplify_seq_add_stmt (gimple_seq *seq_p, gimple *gs)
260 gimple_seq_add_stmt_without_update (seq_p, gs);
263 /* Append sequence SRC to the end of sequence *DST_P. If *DST_P is
264 NULL, a new sequence is allocated. This function is
265 similar to gimple_seq_add_seq, but does not scan the operands.
266 During gimplification, we need to manipulate statement sequences
267 before the def/use vectors have been constructed. */
269 static void
270 gimplify_seq_add_seq (gimple_seq *dst_p, gimple_seq src)
272 gimple_stmt_iterator si;
274 if (src == NULL)
275 return;
277 si = gsi_last (*dst_p);
278 gsi_insert_seq_after_without_update (&si, src, GSI_NEW_STMT);
282 /* Pointer to a list of allocated gimplify_ctx structs to be used for pushing
283 and popping gimplify contexts. */
285 static struct gimplify_ctx *ctx_pool = NULL;
287 /* Return a gimplify context struct from the pool. */
289 static inline struct gimplify_ctx *
290 ctx_alloc (void)
292 struct gimplify_ctx * c = ctx_pool;
294 if (c)
295 ctx_pool = c->prev_context;
296 else
297 c = XNEW (struct gimplify_ctx);
299 memset (c, '\0', sizeof (*c));
300 return c;
303 /* Put gimplify context C back into the pool. */
305 static inline void
306 ctx_free (struct gimplify_ctx *c)
308 c->prev_context = ctx_pool;
309 ctx_pool = c;
312 /* Free allocated ctx stack memory. */
314 void
315 free_gimplify_stack (void)
317 struct gimplify_ctx *c;
319 while ((c = ctx_pool))
321 ctx_pool = c->prev_context;
322 free (c);
327 /* Set up a context for the gimplifier. */
329 void
330 push_gimplify_context (bool in_ssa, bool rhs_cond_ok)
332 struct gimplify_ctx *c = ctx_alloc ();
334 c->prev_context = gimplify_ctxp;
335 gimplify_ctxp = c;
336 gimplify_ctxp->into_ssa = in_ssa;
337 gimplify_ctxp->allow_rhs_cond_expr = rhs_cond_ok;
340 /* Tear down a context for the gimplifier. If BODY is non-null, then
341 put the temporaries into the outer BIND_EXPR. Otherwise, put them
342 in the local_decls.
344 BODY is not a sequence, but the first tuple in a sequence. */
346 void
347 pop_gimplify_context (gimple *body)
349 struct gimplify_ctx *c = gimplify_ctxp;
351 gcc_assert (c
352 && (!c->bind_expr_stack.exists ()
353 || c->bind_expr_stack.is_empty ()));
354 c->bind_expr_stack.release ();
355 gimplify_ctxp = c->prev_context;
357 if (body)
358 declare_vars (c->temps, body, false);
359 else
360 record_vars (c->temps);
362 delete c->temp_htab;
363 c->temp_htab = NULL;
364 ctx_free (c);
367 /* Push a GIMPLE_BIND tuple onto the stack of bindings. */
369 static void
370 gimple_push_bind_expr (gbind *bind_stmt)
372 gimplify_ctxp->bind_expr_stack.reserve (8);
373 gimplify_ctxp->bind_expr_stack.safe_push (bind_stmt);
376 /* Pop the first element off the stack of bindings. */
378 static void
379 gimple_pop_bind_expr (void)
381 gimplify_ctxp->bind_expr_stack.pop ();
384 /* Return the first element of the stack of bindings. */
386 gbind *
387 gimple_current_bind_expr (void)
389 return gimplify_ctxp->bind_expr_stack.last ();
392 /* Return the stack of bindings created during gimplification. */
394 vec<gbind *>
395 gimple_bind_expr_stack (void)
397 return gimplify_ctxp->bind_expr_stack;
400 /* Return true iff there is a COND_EXPR between us and the innermost
401 CLEANUP_POINT_EXPR. This info is used by gimple_push_cleanup. */
403 static bool
404 gimple_conditional_context (void)
406 return gimplify_ctxp->conditions > 0;
409 /* Note that we've entered a COND_EXPR. */
411 static void
412 gimple_push_condition (void)
414 #ifdef ENABLE_GIMPLE_CHECKING
415 if (gimplify_ctxp->conditions == 0)
416 gcc_assert (gimple_seq_empty_p (gimplify_ctxp->conditional_cleanups));
417 #endif
418 ++(gimplify_ctxp->conditions);
421 /* Note that we've left a COND_EXPR. If we're back at unconditional scope
422 now, add any conditional cleanups we've seen to the prequeue. */
424 static void
425 gimple_pop_condition (gimple_seq *pre_p)
427 int conds = --(gimplify_ctxp->conditions);
429 gcc_assert (conds >= 0);
430 if (conds == 0)
432 gimplify_seq_add_seq (pre_p, gimplify_ctxp->conditional_cleanups);
433 gimplify_ctxp->conditional_cleanups = NULL;
437 /* A stable comparison routine for use with splay trees and DECLs. */
439 static int
440 splay_tree_compare_decl_uid (splay_tree_key xa, splay_tree_key xb)
442 tree a = (tree) xa;
443 tree b = (tree) xb;
445 return DECL_UID (a) - DECL_UID (b);
448 /* Create a new omp construct that deals with variable remapping. */
450 static struct gimplify_omp_ctx *
451 new_omp_context (enum omp_region_type region_type)
453 struct gimplify_omp_ctx *c;
455 c = XCNEW (struct gimplify_omp_ctx);
456 c->outer_context = gimplify_omp_ctxp;
457 c->variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0);
458 c->privatized_types = new hash_set<tree>;
459 c->location = input_location;
460 c->region_type = region_type;
461 if ((region_type & ORT_TASK) == 0)
462 c->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
463 else
464 c->default_kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
465 c->defaultmap[GDMK_SCALAR] = GOVD_MAP;
466 c->defaultmap[GDMK_SCALAR_TARGET] = GOVD_MAP;
467 c->defaultmap[GDMK_AGGREGATE] = GOVD_MAP;
468 c->defaultmap[GDMK_ALLOCATABLE] = GOVD_MAP;
469 c->defaultmap[GDMK_POINTER] = GOVD_MAP;
471 return c;
474 /* Destroy an omp construct that deals with variable remapping. */
476 static void
477 delete_omp_context (struct gimplify_omp_ctx *c)
479 splay_tree_delete (c->variables);
480 delete c->privatized_types;
481 c->loop_iter_var.release ();
482 XDELETE (c);
485 static void omp_add_variable (struct gimplify_omp_ctx *, tree, unsigned int);
486 static bool omp_notice_variable (struct gimplify_omp_ctx *, tree, bool);
488 /* Both gimplify the statement T and append it to *SEQ_P. This function
489 behaves exactly as gimplify_stmt, but you don't have to pass T as a
490 reference. */
492 void
493 gimplify_and_add (tree t, gimple_seq *seq_p)
495 gimplify_stmt (&t, seq_p);
498 /* Gimplify statement T into sequence *SEQ_P, and return the first
499 tuple in the sequence of generated tuples for this statement.
500 Return NULL if gimplifying T produced no tuples. */
502 static gimple *
503 gimplify_and_return_first (tree t, gimple_seq *seq_p)
505 gimple_stmt_iterator last = gsi_last (*seq_p);
507 gimplify_and_add (t, seq_p);
509 if (!gsi_end_p (last))
511 gsi_next (&last);
512 return gsi_stmt (last);
514 else
515 return gimple_seq_first_stmt (*seq_p);
518 /* Returns true iff T is a valid RHS for an assignment to an un-renamed
519 LHS, or for a call argument. */
521 static bool
522 is_gimple_mem_rhs (tree t)
524 /* If we're dealing with a renamable type, either source or dest must be
525 a renamed variable. */
526 if (is_gimple_reg_type (TREE_TYPE (t)))
527 return is_gimple_val (t);
528 else
529 return is_gimple_val (t) || is_gimple_lvalue (t);
532 /* Return true if T is a CALL_EXPR or an expression that can be
533 assigned to a temporary. Note that this predicate should only be
534 used during gimplification. See the rationale for this in
535 gimplify_modify_expr. */
537 static bool
538 is_gimple_reg_rhs_or_call (tree t)
540 return (get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS
541 || TREE_CODE (t) == CALL_EXPR);
544 /* Return true if T is a valid memory RHS or a CALL_EXPR. Note that
545 this predicate should only be used during gimplification. See the
546 rationale for this in gimplify_modify_expr. */
548 static bool
549 is_gimple_mem_rhs_or_call (tree t)
551 /* If we're dealing with a renamable type, either source or dest must be
552 a renamed variable. */
553 if (is_gimple_reg_type (TREE_TYPE (t)))
554 return is_gimple_val (t);
555 else
556 return (is_gimple_val (t)
557 || is_gimple_lvalue (t)
558 || TREE_CLOBBER_P (t)
559 || TREE_CODE (t) == CALL_EXPR);
562 /* Create a temporary with a name derived from VAL. Subroutine of
563 lookup_tmp_var; nobody else should call this function. */
565 static inline tree
566 create_tmp_from_val (tree val)
568 /* Drop all qualifiers and address-space information from the value type. */
569 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (val));
570 tree var = create_tmp_var (type, get_name (val));
571 return var;
574 /* Create a temporary to hold the value of VAL. If IS_FORMAL, try to reuse
575 an existing expression temporary. */
577 static tree
578 lookup_tmp_var (tree val, bool is_formal)
580 tree ret;
582 /* If not optimizing, never really reuse a temporary. local-alloc
583 won't allocate any variable that is used in more than one basic
584 block, which means it will go into memory, causing much extra
585 work in reload and final and poorer code generation, outweighing
586 the extra memory allocation here. */
587 if (!optimize || !is_formal || TREE_SIDE_EFFECTS (val))
588 ret = create_tmp_from_val (val);
589 else
591 elt_t elt, *elt_p;
592 elt_t **slot;
594 elt.val = val;
595 if (!gimplify_ctxp->temp_htab)
596 gimplify_ctxp->temp_htab = new hash_table<gimplify_hasher> (1000);
597 slot = gimplify_ctxp->temp_htab->find_slot (&elt, INSERT);
598 if (*slot == NULL)
600 elt_p = XNEW (elt_t);
601 elt_p->val = val;
602 elt_p->temp = ret = create_tmp_from_val (val);
603 *slot = elt_p;
605 else
607 elt_p = *slot;
608 ret = elt_p->temp;
612 return ret;
615 /* Helper for get_formal_tmp_var and get_initialized_tmp_var. */
617 static tree
618 internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
619 bool is_formal, bool allow_ssa)
621 tree t, mod;
623 /* Notice that we explicitly allow VAL to be a CALL_EXPR so that we
624 can create an INIT_EXPR and convert it into a GIMPLE_CALL below. */
625 gimplify_expr (&val, pre_p, post_p, is_gimple_reg_rhs_or_call,
626 fb_rvalue);
628 if (allow_ssa
629 && gimplify_ctxp->into_ssa
630 && is_gimple_reg_type (TREE_TYPE (val)))
632 t = make_ssa_name (TYPE_MAIN_VARIANT (TREE_TYPE (val)));
633 if (! gimple_in_ssa_p (cfun))
635 const char *name = get_name (val);
636 if (name)
637 SET_SSA_NAME_VAR_OR_IDENTIFIER (t, create_tmp_var_name (name));
640 else
641 t = lookup_tmp_var (val, is_formal);
643 mod = build2 (INIT_EXPR, TREE_TYPE (t), t, unshare_expr (val));
645 SET_EXPR_LOCATION (mod, EXPR_LOC_OR_LOC (val, input_location));
647 /* gimplify_modify_expr might want to reduce this further. */
648 gimplify_and_add (mod, pre_p);
649 ggc_free (mod);
651 return t;
654 /* Return a formal temporary variable initialized with VAL. PRE_P is as
655 in gimplify_expr. Only use this function if:
657 1) The value of the unfactored expression represented by VAL will not
658 change between the initialization and use of the temporary, and
659 2) The temporary will not be otherwise modified.
661 For instance, #1 means that this is inappropriate for SAVE_EXPR temps,
662 and #2 means it is inappropriate for && temps.
664 For other cases, use get_initialized_tmp_var instead. */
666 tree
667 get_formal_tmp_var (tree val, gimple_seq *pre_p)
669 return internal_get_tmp_var (val, pre_p, NULL, true, true);
672 /* Return a temporary variable initialized with VAL. PRE_P and POST_P
673 are as in gimplify_expr. */
675 tree
676 get_initialized_tmp_var (tree val, gimple_seq *pre_p,
677 gimple_seq *post_p /* = NULL */,
678 bool allow_ssa /* = true */)
680 return internal_get_tmp_var (val, pre_p, post_p, false, allow_ssa);
683 /* Declare all the variables in VARS in SCOPE. If DEBUG_INFO is true,
684 generate debug info for them; otherwise don't. */
686 void
687 declare_vars (tree vars, gimple *gs, bool debug_info)
689 tree last = vars;
690 if (last)
692 tree temps, block;
694 gbind *scope = as_a <gbind *> (gs);
696 temps = nreverse (last);
698 block = gimple_bind_block (scope);
699 gcc_assert (!block || TREE_CODE (block) == BLOCK);
700 if (!block || !debug_info)
702 DECL_CHAIN (last) = gimple_bind_vars (scope);
703 gimple_bind_set_vars (scope, temps);
705 else
707 /* We need to attach the nodes both to the BIND_EXPR and to its
708 associated BLOCK for debugging purposes. The key point here
709 is that the BLOCK_VARS of the BIND_EXPR_BLOCK of a BIND_EXPR
710 is a subchain of the BIND_EXPR_VARS of the BIND_EXPR. */
711 if (BLOCK_VARS (block))
712 BLOCK_VARS (block) = chainon (BLOCK_VARS (block), temps);
713 else
715 gimple_bind_set_vars (scope,
716 chainon (gimple_bind_vars (scope), temps));
717 BLOCK_VARS (block) = temps;
723 /* For VAR a VAR_DECL of variable size, try to find a constant upper bound
724 for the size and adjust DECL_SIZE/DECL_SIZE_UNIT accordingly. Abort if
725 no such upper bound can be obtained. */
727 static void
728 force_constant_size (tree var)
730 /* The only attempt we make is by querying the maximum size of objects
731 of the variable's type. */
733 HOST_WIDE_INT max_size;
735 gcc_assert (VAR_P (var));
737 max_size = max_int_size_in_bytes (TREE_TYPE (var));
739 gcc_assert (max_size >= 0);
741 DECL_SIZE_UNIT (var)
742 = build_int_cst (TREE_TYPE (DECL_SIZE_UNIT (var)), max_size);
743 DECL_SIZE (var)
744 = build_int_cst (TREE_TYPE (DECL_SIZE (var)), max_size * BITS_PER_UNIT);
747 /* Push the temporary variable TMP into the current binding. */
749 void
750 gimple_add_tmp_var_fn (struct function *fn, tree tmp)
752 gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
754 /* Later processing assumes that the object size is constant, which might
755 not be true at this point. Force the use of a constant upper bound in
756 this case. */
757 if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp)))
758 force_constant_size (tmp);
760 DECL_CONTEXT (tmp) = fn->decl;
761 DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
763 record_vars_into (tmp, fn->decl);
766 /* Push the temporary variable TMP into the current binding. */
768 void
769 gimple_add_tmp_var (tree tmp)
771 gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
773 /* Later processing assumes that the object size is constant, which might
774 not be true at this point. Force the use of a constant upper bound in
775 this case. */
776 if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp)))
777 force_constant_size (tmp);
779 DECL_CONTEXT (tmp) = current_function_decl;
780 DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
782 if (gimplify_ctxp)
784 DECL_CHAIN (tmp) = gimplify_ctxp->temps;
785 gimplify_ctxp->temps = tmp;
787 /* Mark temporaries local within the nearest enclosing parallel. */
788 if (gimplify_omp_ctxp)
790 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
791 int flag = GOVD_LOCAL | GOVD_SEEN;
792 while (ctx
793 && (ctx->region_type == ORT_WORKSHARE
794 || ctx->region_type == ORT_TASKGROUP
795 || ctx->region_type == ORT_SIMD
796 || ctx->region_type == ORT_ACC))
798 if (ctx->region_type == ORT_SIMD
799 && TREE_ADDRESSABLE (tmp)
800 && !TREE_STATIC (tmp))
802 if (TREE_CODE (DECL_SIZE_UNIT (tmp)) != INTEGER_CST)
803 ctx->add_safelen1 = true;
804 else if (ctx->in_for_exprs)
805 flag = GOVD_PRIVATE;
806 else
807 flag = GOVD_PRIVATE | GOVD_SEEN;
808 break;
810 ctx = ctx->outer_context;
812 if (ctx)
813 omp_add_variable (ctx, tmp, flag);
816 else if (cfun)
817 record_vars (tmp);
818 else
820 gimple_seq body_seq;
822 /* This case is for nested functions. We need to expose the locals
823 they create. */
824 body_seq = gimple_body (current_function_decl);
825 declare_vars (tmp, gimple_seq_first_stmt (body_seq), false);
831 /* This page contains routines to unshare tree nodes, i.e. to duplicate tree
832 nodes that are referenced more than once in GENERIC functions. This is
833 necessary because gimplification (translation into GIMPLE) is performed
834 by modifying tree nodes in-place, so gimplication of a shared node in a
835 first context could generate an invalid GIMPLE form in a second context.
837 This is achieved with a simple mark/copy/unmark algorithm that walks the
838 GENERIC representation top-down, marks nodes with TREE_VISITED the first
839 time it encounters them, duplicates them if they already have TREE_VISITED
840 set, and finally removes the TREE_VISITED marks it has set.
842 The algorithm works only at the function level, i.e. it generates a GENERIC
843 representation of a function with no nodes shared within the function when
844 passed a GENERIC function (except for nodes that are allowed to be shared).
846 At the global level, it is also necessary to unshare tree nodes that are
847 referenced in more than one function, for the same aforementioned reason.
848 This requires some cooperation from the front-end. There are 2 strategies:
850 1. Manual unsharing. The front-end needs to call unshare_expr on every
851 expression that might end up being shared across functions.
853 2. Deep unsharing. This is an extension of regular unsharing. Instead
854 of calling unshare_expr on expressions that might be shared across
855 functions, the front-end pre-marks them with TREE_VISITED. This will
856 ensure that they are unshared on the first reference within functions
857 when the regular unsharing algorithm runs. The counterpart is that
858 this algorithm must look deeper than for manual unsharing, which is
859 specified by LANG_HOOKS_DEEP_UNSHARING.
861 If there are only few specific cases of node sharing across functions, it is
862 probably easier for a front-end to unshare the expressions manually. On the
863 contrary, if the expressions generated at the global level are as widespread
864 as expressions generated within functions, deep unsharing is very likely the
865 way to go. */
867 /* Similar to copy_tree_r but do not copy SAVE_EXPR or TARGET_EXPR nodes.
868 These nodes model computations that must be done once. If we were to
869 unshare something like SAVE_EXPR(i++), the gimplification process would
870 create wrong code. However, if DATA is non-null, it must hold a pointer
871 set that is used to unshare the subtrees of these nodes. */
873 static tree
874 mostly_copy_tree_r (tree *tp, int *walk_subtrees, void *data)
876 tree t = *tp;
877 enum tree_code code = TREE_CODE (t);
879 /* Do not copy SAVE_EXPR, TARGET_EXPR or BIND_EXPR nodes themselves, but
880 copy their subtrees if we can make sure to do it only once. */
881 if (code == SAVE_EXPR || code == TARGET_EXPR || code == BIND_EXPR)
883 if (data && !((hash_set<tree> *)data)->add (t))
885 else
886 *walk_subtrees = 0;
889 /* Stop at types, decls, constants like copy_tree_r. */
890 else if (TREE_CODE_CLASS (code) == tcc_type
891 || TREE_CODE_CLASS (code) == tcc_declaration
892 || TREE_CODE_CLASS (code) == tcc_constant)
893 *walk_subtrees = 0;
895 /* Cope with the statement expression extension. */
896 else if (code == STATEMENT_LIST)
899 /* Leave the bulk of the work to copy_tree_r itself. */
900 else
901 copy_tree_r (tp, walk_subtrees, NULL);
903 return NULL_TREE;
906 /* Callback for walk_tree to unshare most of the shared trees rooted at *TP.
907 If *TP has been visited already, then *TP is deeply copied by calling
908 mostly_copy_tree_r. DATA is passed to mostly_copy_tree_r unmodified. */
910 static tree
911 copy_if_shared_r (tree *tp, int *walk_subtrees, void *data)
913 tree t = *tp;
914 enum tree_code code = TREE_CODE (t);
916 /* Skip types, decls, and constants. But we do want to look at their
917 types and the bounds of types. Mark them as visited so we properly
918 unmark their subtrees on the unmark pass. If we've already seen them,
919 don't look down further. */
920 if (TREE_CODE_CLASS (code) == tcc_type
921 || TREE_CODE_CLASS (code) == tcc_declaration
922 || TREE_CODE_CLASS (code) == tcc_constant)
924 if (TREE_VISITED (t))
925 *walk_subtrees = 0;
926 else
927 TREE_VISITED (t) = 1;
930 /* If this node has been visited already, unshare it and don't look
931 any deeper. */
932 else if (TREE_VISITED (t))
934 walk_tree (tp, mostly_copy_tree_r, data, NULL);
935 *walk_subtrees = 0;
938 /* Otherwise, mark the node as visited and keep looking. */
939 else
940 TREE_VISITED (t) = 1;
942 return NULL_TREE;
945 /* Unshare most of the shared trees rooted at *TP. DATA is passed to the
946 copy_if_shared_r callback unmodified. */
948 void
949 copy_if_shared (tree *tp, void *data)
951 walk_tree (tp, copy_if_shared_r, data, NULL);
954 /* Unshare all the trees in the body of FNDECL, as well as in the bodies of
955 any nested functions. */
957 static void
958 unshare_body (tree fndecl)
960 struct cgraph_node *cgn = cgraph_node::get (fndecl);
961 /* If the language requires deep unsharing, we need a pointer set to make
962 sure we don't repeatedly unshare subtrees of unshareable nodes. */
963 hash_set<tree> *visited
964 = lang_hooks.deep_unsharing ? new hash_set<tree> : NULL;
966 copy_if_shared (&DECL_SAVED_TREE (fndecl), visited);
967 copy_if_shared (&DECL_SIZE (DECL_RESULT (fndecl)), visited);
968 copy_if_shared (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)), visited);
970 delete visited;
972 if (cgn)
973 for (cgn = first_nested_function (cgn); cgn;
974 cgn = next_nested_function (cgn))
975 unshare_body (cgn->decl);
978 /* Callback for walk_tree to unmark the visited trees rooted at *TP.
979 Subtrees are walked until the first unvisited node is encountered. */
981 static tree
982 unmark_visited_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
984 tree t = *tp;
986 /* If this node has been visited, unmark it and keep looking. */
987 if (TREE_VISITED (t))
988 TREE_VISITED (t) = 0;
990 /* Otherwise, don't look any deeper. */
991 else
992 *walk_subtrees = 0;
994 return NULL_TREE;
997 /* Unmark the visited trees rooted at *TP. */
999 static inline void
1000 unmark_visited (tree *tp)
1002 walk_tree (tp, unmark_visited_r, NULL, NULL);
1005 /* Likewise, but mark all trees as not visited. */
1007 static void
1008 unvisit_body (tree fndecl)
1010 struct cgraph_node *cgn = cgraph_node::get (fndecl);
1012 unmark_visited (&DECL_SAVED_TREE (fndecl));
1013 unmark_visited (&DECL_SIZE (DECL_RESULT (fndecl)));
1014 unmark_visited (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)));
1016 if (cgn)
1017 for (cgn = first_nested_function (cgn);
1018 cgn; cgn = next_nested_function (cgn))
1019 unvisit_body (cgn->decl);
1022 /* Unconditionally make an unshared copy of EXPR. This is used when using
1023 stored expressions which span multiple functions, such as BINFO_VTABLE,
1024 as the normal unsharing process can't tell that they're shared. */
1026 tree
1027 unshare_expr (tree expr)
1029 walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
1030 return expr;
1033 /* Worker for unshare_expr_without_location. */
1035 static tree
1036 prune_expr_location (tree *tp, int *walk_subtrees, void *)
1038 if (EXPR_P (*tp))
1039 SET_EXPR_LOCATION (*tp, UNKNOWN_LOCATION);
1040 else
1041 *walk_subtrees = 0;
1042 return NULL_TREE;
1045 /* Similar to unshare_expr but also prune all expression locations
1046 from EXPR. */
1048 tree
1049 unshare_expr_without_location (tree expr)
1051 walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
1052 if (EXPR_P (expr))
1053 walk_tree (&expr, prune_expr_location, NULL, NULL);
1054 return expr;
1057 /* Return the EXPR_LOCATION of EXPR, if it (maybe recursively) has
1058 one, OR_ELSE otherwise. The location of a STATEMENT_LISTs
1059 comprising at least one DEBUG_BEGIN_STMT followed by exactly one
1060 EXPR is the location of the EXPR. */
1062 static location_t
1063 rexpr_location (tree expr, location_t or_else = UNKNOWN_LOCATION)
1065 if (!expr)
1066 return or_else;
1068 if (EXPR_HAS_LOCATION (expr))
1069 return EXPR_LOCATION (expr);
1071 if (TREE_CODE (expr) != STATEMENT_LIST)
1072 return or_else;
1074 tree_stmt_iterator i = tsi_start (expr);
1076 bool found = false;
1077 while (!tsi_end_p (i) && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT)
1079 found = true;
1080 tsi_next (&i);
1083 if (!found || !tsi_one_before_end_p (i))
1084 return or_else;
1086 return rexpr_location (tsi_stmt (i), or_else);
1089 /* Return TRUE iff EXPR (maybe recursively) has a location; see
1090 rexpr_location for the potential recursion. */
1092 static inline bool
1093 rexpr_has_location (tree expr)
1095 return rexpr_location (expr) != UNKNOWN_LOCATION;
1099 /* WRAPPER is a code such as BIND_EXPR or CLEANUP_POINT_EXPR which can both
1100 contain statements and have a value. Assign its value to a temporary
1101 and give it void_type_node. Return the temporary, or NULL_TREE if
1102 WRAPPER was already void. */
1104 tree
1105 voidify_wrapper_expr (tree wrapper, tree temp)
1107 tree type = TREE_TYPE (wrapper);
1108 if (type && !VOID_TYPE_P (type))
1110 tree *p;
1112 /* Set p to point to the body of the wrapper. Loop until we find
1113 something that isn't a wrapper. */
1114 for (p = &wrapper; p && *p; )
1116 switch (TREE_CODE (*p))
1118 case BIND_EXPR:
1119 TREE_SIDE_EFFECTS (*p) = 1;
1120 TREE_TYPE (*p) = void_type_node;
1121 /* For a BIND_EXPR, the body is operand 1. */
1122 p = &BIND_EXPR_BODY (*p);
1123 break;
1125 case CLEANUP_POINT_EXPR:
1126 case TRY_FINALLY_EXPR:
1127 case TRY_CATCH_EXPR:
1128 TREE_SIDE_EFFECTS (*p) = 1;
1129 TREE_TYPE (*p) = void_type_node;
1130 p = &TREE_OPERAND (*p, 0);
1131 break;
1133 case STATEMENT_LIST:
1135 tree_stmt_iterator i = tsi_last (*p);
1136 TREE_SIDE_EFFECTS (*p) = 1;
1137 TREE_TYPE (*p) = void_type_node;
1138 p = tsi_end_p (i) ? NULL : tsi_stmt_ptr (i);
1140 break;
1142 case COMPOUND_EXPR:
1143 /* Advance to the last statement. Set all container types to
1144 void. */
1145 for (; TREE_CODE (*p) == COMPOUND_EXPR; p = &TREE_OPERAND (*p, 1))
1147 TREE_SIDE_EFFECTS (*p) = 1;
1148 TREE_TYPE (*p) = void_type_node;
1150 break;
1152 case TRANSACTION_EXPR:
1153 TREE_SIDE_EFFECTS (*p) = 1;
1154 TREE_TYPE (*p) = void_type_node;
1155 p = &TRANSACTION_EXPR_BODY (*p);
1156 break;
1158 default:
1159 /* Assume that any tree upon which voidify_wrapper_expr is
1160 directly called is a wrapper, and that its body is op0. */
1161 if (p == &wrapper)
1163 TREE_SIDE_EFFECTS (*p) = 1;
1164 TREE_TYPE (*p) = void_type_node;
1165 p = &TREE_OPERAND (*p, 0);
1166 break;
1168 goto out;
1172 out:
1173 if (p == NULL || IS_EMPTY_STMT (*p))
1174 temp = NULL_TREE;
1175 else if (temp)
1177 /* The wrapper is on the RHS of an assignment that we're pushing
1178 down. */
1179 gcc_assert (TREE_CODE (temp) == INIT_EXPR
1180 || TREE_CODE (temp) == MODIFY_EXPR);
1181 TREE_OPERAND (temp, 1) = *p;
1182 *p = temp;
1184 else
1186 temp = create_tmp_var (type, "retval");
1187 *p = build2 (INIT_EXPR, type, temp, *p);
1190 return temp;
1193 return NULL_TREE;
1196 /* Prepare calls to builtins to SAVE and RESTORE the stack as well as
1197 a temporary through which they communicate. */
1199 static void
1200 build_stack_save_restore (gcall **save, gcall **restore)
1202 tree tmp_var;
1204 *save = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_SAVE), 0);
1205 tmp_var = create_tmp_var (ptr_type_node, "saved_stack");
1206 gimple_call_set_lhs (*save, tmp_var);
1208 *restore
1209 = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_RESTORE),
1210 1, tmp_var);
1213 /* Generate IFN_ASAN_MARK call that poisons shadow of a for DECL variable. */
1215 static tree
1216 build_asan_poison_call_expr (tree decl)
1218 /* Do not poison variables that have size equal to zero. */
1219 tree unit_size = DECL_SIZE_UNIT (decl);
1220 if (zerop (unit_size))
1221 return NULL_TREE;
1223 tree base = build_fold_addr_expr (decl);
1225 return build_call_expr_internal_loc (UNKNOWN_LOCATION, IFN_ASAN_MARK,
1226 void_type_node, 3,
1227 build_int_cst (integer_type_node,
1228 ASAN_MARK_POISON),
1229 base, unit_size);
1232 /* Generate IFN_ASAN_MARK call that would poison or unpoison, depending
1233 on POISON flag, shadow memory of a DECL variable. The call will be
1234 put on location identified by IT iterator, where BEFORE flag drives
1235 position where the stmt will be put. */
1237 static void
1238 asan_poison_variable (tree decl, bool poison, gimple_stmt_iterator *it,
1239 bool before)
1241 tree unit_size = DECL_SIZE_UNIT (decl);
1242 tree base = build_fold_addr_expr (decl);
1244 /* Do not poison variables that have size equal to zero. */
1245 if (zerop (unit_size))
1246 return;
1248 /* It's necessary to have all stack variables aligned to ASAN granularity
1249 bytes. */
1250 gcc_assert (!hwasan_sanitize_p () || hwasan_sanitize_stack_p ());
1251 unsigned shadow_granularity
1252 = hwasan_sanitize_p () ? HWASAN_TAG_GRANULE_SIZE : ASAN_SHADOW_GRANULARITY;
1253 if (DECL_ALIGN_UNIT (decl) <= shadow_granularity)
1254 SET_DECL_ALIGN (decl, BITS_PER_UNIT * shadow_granularity);
1256 HOST_WIDE_INT flags = poison ? ASAN_MARK_POISON : ASAN_MARK_UNPOISON;
1258 gimple *g
1259 = gimple_build_call_internal (IFN_ASAN_MARK, 3,
1260 build_int_cst (integer_type_node, flags),
1261 base, unit_size);
1263 if (before)
1264 gsi_insert_before (it, g, GSI_NEW_STMT);
1265 else
1266 gsi_insert_after (it, g, GSI_NEW_STMT);
1269 /* Generate IFN_ASAN_MARK internal call that depending on POISON flag
1270 either poisons or unpoisons a DECL. Created statement is appended
1271 to SEQ_P gimple sequence. */
1273 static void
1274 asan_poison_variable (tree decl, bool poison, gimple_seq *seq_p)
1276 gimple_stmt_iterator it = gsi_last (*seq_p);
1277 bool before = false;
1279 if (gsi_end_p (it))
1280 before = true;
1282 asan_poison_variable (decl, poison, &it, before);
1285 /* Sort pair of VAR_DECLs A and B by DECL_UID. */
1287 static int
1288 sort_by_decl_uid (const void *a, const void *b)
1290 const tree *t1 = (const tree *)a;
1291 const tree *t2 = (const tree *)b;
1293 int uid1 = DECL_UID (*t1);
1294 int uid2 = DECL_UID (*t2);
1296 if (uid1 < uid2)
1297 return -1;
1298 else if (uid1 > uid2)
1299 return 1;
1300 else
1301 return 0;
1304 /* Generate IFN_ASAN_MARK internal call for all VARIABLES
1305 depending on POISON flag. Created statement is appended
1306 to SEQ_P gimple sequence. */
1308 static void
1309 asan_poison_variables (hash_set<tree> *variables, bool poison, gimple_seq *seq_p)
1311 unsigned c = variables->elements ();
1312 if (c == 0)
1313 return;
1315 auto_vec<tree> sorted_variables (c);
1317 for (hash_set<tree>::iterator it = variables->begin ();
1318 it != variables->end (); ++it)
1319 sorted_variables.safe_push (*it);
1321 sorted_variables.qsort (sort_by_decl_uid);
1323 unsigned i;
1324 tree var;
1325 FOR_EACH_VEC_ELT (sorted_variables, i, var)
1327 asan_poison_variable (var, poison, seq_p);
1329 /* Add use_after_scope_memory attribute for the variable in order
1330 to prevent re-written into SSA. */
1331 if (!lookup_attribute (ASAN_USE_AFTER_SCOPE_ATTRIBUTE,
1332 DECL_ATTRIBUTES (var)))
1333 DECL_ATTRIBUTES (var)
1334 = tree_cons (get_identifier (ASAN_USE_AFTER_SCOPE_ATTRIBUTE),
1335 integer_one_node,
1336 DECL_ATTRIBUTES (var));
1340 /* Gimplify a BIND_EXPR. Just voidify and recurse. */
1342 static enum gimplify_status
1343 gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p)
1345 tree bind_expr = *expr_p;
1346 bool old_keep_stack = gimplify_ctxp->keep_stack;
1347 bool old_save_stack = gimplify_ctxp->save_stack;
1348 tree t;
1349 gbind *bind_stmt;
1350 gimple_seq body, cleanup;
1351 gcall *stack_save;
1352 location_t start_locus = 0, end_locus = 0;
1353 tree ret_clauses = NULL;
1355 tree temp = voidify_wrapper_expr (bind_expr, NULL);
1357 /* Mark variables seen in this bind expr. */
1358 for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t))
1360 if (VAR_P (t))
1362 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
1364 /* Mark variable as local. */
1365 if (ctx && ctx->region_type != ORT_NONE && !DECL_EXTERNAL (t))
1367 if (! DECL_SEEN_IN_BIND_EXPR_P (t)
1368 || splay_tree_lookup (ctx->variables,
1369 (splay_tree_key) t) == NULL)
1371 int flag = GOVD_LOCAL;
1372 if (ctx->region_type == ORT_SIMD
1373 && TREE_ADDRESSABLE (t)
1374 && !TREE_STATIC (t))
1376 if (TREE_CODE (DECL_SIZE_UNIT (t)) != INTEGER_CST)
1377 ctx->add_safelen1 = true;
1378 else
1379 flag = GOVD_PRIVATE;
1381 omp_add_variable (ctx, t, flag | GOVD_SEEN);
1383 /* Static locals inside of target construct or offloaded
1384 routines need to be "omp declare target". */
1385 if (TREE_STATIC (t))
1386 for (; ctx; ctx = ctx->outer_context)
1387 if ((ctx->region_type & ORT_TARGET) != 0)
1389 if (!lookup_attribute ("omp declare target",
1390 DECL_ATTRIBUTES (t)))
1392 tree id = get_identifier ("omp declare target");
1393 DECL_ATTRIBUTES (t)
1394 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
1395 varpool_node *node = varpool_node::get (t);
1396 if (node)
1398 node->offloadable = 1;
1399 if (ENABLE_OFFLOADING && !DECL_EXTERNAL (t))
1401 g->have_offload = true;
1402 if (!in_lto_p)
1403 vec_safe_push (offload_vars, t);
1407 break;
1411 DECL_SEEN_IN_BIND_EXPR_P (t) = 1;
1413 if (DECL_HARD_REGISTER (t) && !is_global_var (t) && cfun)
1414 cfun->has_local_explicit_reg_vars = true;
1418 bind_stmt = gimple_build_bind (BIND_EXPR_VARS (bind_expr), NULL,
1419 BIND_EXPR_BLOCK (bind_expr));
1420 gimple_push_bind_expr (bind_stmt);
1422 gimplify_ctxp->keep_stack = false;
1423 gimplify_ctxp->save_stack = false;
1425 /* Gimplify the body into the GIMPLE_BIND tuple's body. */
1426 body = NULL;
1427 gimplify_stmt (&BIND_EXPR_BODY (bind_expr), &body);
1428 gimple_bind_set_body (bind_stmt, body);
1430 /* Source location wise, the cleanup code (stack_restore and clobbers)
1431 belongs to the end of the block, so propagate what we have. The
1432 stack_save operation belongs to the beginning of block, which we can
1433 infer from the bind_expr directly if the block has no explicit
1434 assignment. */
1435 if (BIND_EXPR_BLOCK (bind_expr))
1437 end_locus = BLOCK_SOURCE_END_LOCATION (BIND_EXPR_BLOCK (bind_expr));
1438 start_locus = BLOCK_SOURCE_LOCATION (BIND_EXPR_BLOCK (bind_expr));
1440 if (start_locus == 0)
1441 start_locus = EXPR_LOCATION (bind_expr);
1443 cleanup = NULL;
1444 stack_save = NULL;
1446 /* If the code both contains VLAs and calls alloca, then we cannot reclaim
1447 the stack space allocated to the VLAs. */
1448 if (gimplify_ctxp->save_stack && !gimplify_ctxp->keep_stack)
1450 gcall *stack_restore;
1452 /* Save stack on entry and restore it on exit. Add a try_finally
1453 block to achieve this. */
1454 build_stack_save_restore (&stack_save, &stack_restore);
1456 gimple_set_location (stack_save, start_locus);
1457 gimple_set_location (stack_restore, end_locus);
1459 gimplify_seq_add_stmt (&cleanup, stack_restore);
1462 /* Add clobbers for all variables that go out of scope. */
1463 for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t))
1465 if (VAR_P (t)
1466 && !is_global_var (t)
1467 && DECL_CONTEXT (t) == current_function_decl)
1469 if (!DECL_HARD_REGISTER (t)
1470 && !TREE_THIS_VOLATILE (t)
1471 && !DECL_HAS_VALUE_EXPR_P (t)
1472 /* Only care for variables that have to be in memory. Others
1473 will be rewritten into SSA names, hence moved to the
1474 top-level. */
1475 && !is_gimple_reg (t)
1476 && flag_stack_reuse != SR_NONE)
1478 tree clobber = build_clobber (TREE_TYPE (t));
1479 gimple *clobber_stmt;
1480 clobber_stmt = gimple_build_assign (t, clobber);
1481 gimple_set_location (clobber_stmt, end_locus);
1482 gimplify_seq_add_stmt (&cleanup, clobber_stmt);
1485 if (flag_openacc && oacc_declare_returns != NULL)
1487 tree key = t;
1488 if (DECL_HAS_VALUE_EXPR_P (key))
1490 key = DECL_VALUE_EXPR (key);
1491 if (TREE_CODE (key) == INDIRECT_REF)
1492 key = TREE_OPERAND (key, 0);
1494 tree *c = oacc_declare_returns->get (key);
1495 if (c != NULL)
1497 if (ret_clauses)
1498 OMP_CLAUSE_CHAIN (*c) = ret_clauses;
1500 ret_clauses = unshare_expr (*c);
1502 oacc_declare_returns->remove (key);
1504 if (oacc_declare_returns->is_empty ())
1506 delete oacc_declare_returns;
1507 oacc_declare_returns = NULL;
1513 if (asan_poisoned_variables != NULL
1514 && asan_poisoned_variables->contains (t))
1516 asan_poisoned_variables->remove (t);
1517 asan_poison_variable (t, true, &cleanup);
1520 if (gimplify_ctxp->live_switch_vars != NULL
1521 && gimplify_ctxp->live_switch_vars->contains (t))
1522 gimplify_ctxp->live_switch_vars->remove (t);
1525 if (ret_clauses)
1527 gomp_target *stmt;
1528 gimple_stmt_iterator si = gsi_start (cleanup);
1530 stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
1531 ret_clauses);
1532 gsi_insert_seq_before_without_update (&si, stmt, GSI_NEW_STMT);
1535 if (cleanup)
1537 gtry *gs;
1538 gimple_seq new_body;
1540 new_body = NULL;
1541 gs = gimple_build_try (gimple_bind_body (bind_stmt), cleanup,
1542 GIMPLE_TRY_FINALLY);
1544 if (stack_save)
1545 gimplify_seq_add_stmt (&new_body, stack_save);
1546 gimplify_seq_add_stmt (&new_body, gs);
1547 gimple_bind_set_body (bind_stmt, new_body);
1550 /* keep_stack propagates all the way up to the outermost BIND_EXPR. */
1551 if (!gimplify_ctxp->keep_stack)
1552 gimplify_ctxp->keep_stack = old_keep_stack;
1553 gimplify_ctxp->save_stack = old_save_stack;
1555 gimple_pop_bind_expr ();
1557 gimplify_seq_add_stmt (pre_p, bind_stmt);
1559 if (temp)
1561 *expr_p = temp;
1562 return GS_OK;
1565 *expr_p = NULL_TREE;
1566 return GS_ALL_DONE;
1569 /* Maybe add early return predict statement to PRE_P sequence. */
1571 static void
1572 maybe_add_early_return_predict_stmt (gimple_seq *pre_p)
1574 /* If we are not in a conditional context, add PREDICT statement. */
1575 if (gimple_conditional_context ())
1577 gimple *predict = gimple_build_predict (PRED_TREE_EARLY_RETURN,
1578 NOT_TAKEN);
1579 gimplify_seq_add_stmt (pre_p, predict);
1583 /* Gimplify a RETURN_EXPR. If the expression to be returned is not a
1584 GIMPLE value, it is assigned to a new temporary and the statement is
1585 re-written to return the temporary.
1587 PRE_P points to the sequence where side effects that must happen before
1588 STMT should be stored. */
1590 static enum gimplify_status
1591 gimplify_return_expr (tree stmt, gimple_seq *pre_p)
1593 greturn *ret;
1594 tree ret_expr = TREE_OPERAND (stmt, 0);
1595 tree result_decl, result;
1597 if (ret_expr == error_mark_node)
1598 return GS_ERROR;
1600 if (!ret_expr
1601 || TREE_CODE (ret_expr) == RESULT_DECL)
1603 maybe_add_early_return_predict_stmt (pre_p);
1604 greturn *ret = gimple_build_return (ret_expr);
1605 copy_warning (ret, stmt);
1606 gimplify_seq_add_stmt (pre_p, ret);
1607 return GS_ALL_DONE;
1610 if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))))
1611 result_decl = NULL_TREE;
1612 else if (TREE_CODE (ret_expr) == COMPOUND_EXPR)
1614 /* Used in C++ for handling EH cleanup of the return value if a local
1615 cleanup throws. Assume the front-end knows what it's doing. */
1616 result_decl = DECL_RESULT (current_function_decl);
1617 /* But crash if we end up trying to modify ret_expr below. */
1618 ret_expr = NULL_TREE;
1620 else
1622 result_decl = TREE_OPERAND (ret_expr, 0);
1624 /* See through a return by reference. */
1625 if (TREE_CODE (result_decl) == INDIRECT_REF)
1626 result_decl = TREE_OPERAND (result_decl, 0);
1628 gcc_assert ((TREE_CODE (ret_expr) == MODIFY_EXPR
1629 || TREE_CODE (ret_expr) == INIT_EXPR)
1630 && TREE_CODE (result_decl) == RESULT_DECL);
1633 /* If aggregate_value_p is true, then we can return the bare RESULT_DECL.
1634 Recall that aggregate_value_p is FALSE for any aggregate type that is
1635 returned in registers. If we're returning values in registers, then
1636 we don't want to extend the lifetime of the RESULT_DECL, particularly
1637 across another call. In addition, for those aggregates for which
1638 hard_function_value generates a PARALLEL, we'll die during normal
1639 expansion of structure assignments; there's special code in expand_return
1640 to handle this case that does not exist in expand_expr. */
1641 if (!result_decl)
1642 result = NULL_TREE;
1643 else if (aggregate_value_p (result_decl, TREE_TYPE (current_function_decl)))
1645 if (!poly_int_tree_p (DECL_SIZE (result_decl)))
1647 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (result_decl)))
1648 gimplify_type_sizes (TREE_TYPE (result_decl), pre_p);
1649 /* Note that we don't use gimplify_vla_decl because the RESULT_DECL
1650 should be effectively allocated by the caller, i.e. all calls to
1651 this function must be subject to the Return Slot Optimization. */
1652 gimplify_one_sizepos (&DECL_SIZE (result_decl), pre_p);
1653 gimplify_one_sizepos (&DECL_SIZE_UNIT (result_decl), pre_p);
1655 result = result_decl;
1657 else if (gimplify_ctxp->return_temp)
1658 result = gimplify_ctxp->return_temp;
1659 else
1661 result = create_tmp_reg (TREE_TYPE (result_decl));
1663 /* ??? With complex control flow (usually involving abnormal edges),
1664 we can wind up warning about an uninitialized value for this. Due
1665 to how this variable is constructed and initialized, this is never
1666 true. Give up and never warn. */
1667 suppress_warning (result, OPT_Wuninitialized);
1669 gimplify_ctxp->return_temp = result;
1672 /* Smash the lhs of the MODIFY_EXPR to the temporary we plan to use.
1673 Then gimplify the whole thing. */
1674 if (result != result_decl)
1675 TREE_OPERAND (ret_expr, 0) = result;
1677 gimplify_and_add (TREE_OPERAND (stmt, 0), pre_p);
1679 maybe_add_early_return_predict_stmt (pre_p);
1680 ret = gimple_build_return (result);
1681 copy_warning (ret, stmt);
1682 gimplify_seq_add_stmt (pre_p, ret);
1684 return GS_ALL_DONE;
1687 /* Gimplify a variable-length array DECL. */
1689 static void
1690 gimplify_vla_decl (tree decl, gimple_seq *seq_p)
1692 /* This is a variable-sized decl. Simplify its size and mark it
1693 for deferred expansion. */
1694 tree t, addr, ptr_type;
1696 gimplify_one_sizepos (&DECL_SIZE (decl), seq_p);
1697 gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), seq_p);
1699 /* Don't mess with a DECL_VALUE_EXPR set by the front-end. */
1700 if (DECL_HAS_VALUE_EXPR_P (decl))
1701 return;
1703 /* All occurrences of this decl in final gimplified code will be
1704 replaced by indirection. Setting DECL_VALUE_EXPR does two
1705 things: First, it lets the rest of the gimplifier know what
1706 replacement to use. Second, it lets the debug info know
1707 where to find the value. */
1708 ptr_type = build_pointer_type (TREE_TYPE (decl));
1709 addr = create_tmp_var (ptr_type, get_name (decl));
1710 DECL_IGNORED_P (addr) = 0;
1711 t = build_fold_indirect_ref (addr);
1712 TREE_THIS_NOTRAP (t) = 1;
1713 SET_DECL_VALUE_EXPR (decl, t);
1714 DECL_HAS_VALUE_EXPR_P (decl) = 1;
1716 t = build_alloca_call_expr (DECL_SIZE_UNIT (decl), DECL_ALIGN (decl),
1717 max_int_size_in_bytes (TREE_TYPE (decl)));
1718 /* The call has been built for a variable-sized object. */
1719 CALL_ALLOCA_FOR_VAR_P (t) = 1;
1720 t = fold_convert (ptr_type, t);
1721 t = build2 (MODIFY_EXPR, TREE_TYPE (addr), addr, t);
1723 gimplify_and_add (t, seq_p);
1725 /* Record the dynamic allocation associated with DECL if requested. */
1726 if (flag_callgraph_info & CALLGRAPH_INFO_DYNAMIC_ALLOC)
1727 record_dynamic_alloc (decl);
1730 /* A helper function to be called via walk_tree. Mark all labels under *TP
1731 as being forced. To be called for DECL_INITIAL of static variables. */
1733 static tree
1734 force_labels_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
1736 if (TYPE_P (*tp))
1737 *walk_subtrees = 0;
1738 if (TREE_CODE (*tp) == LABEL_DECL)
1740 FORCED_LABEL (*tp) = 1;
1741 cfun->has_forced_label_in_static = 1;
1744 return NULL_TREE;
1747 /* Generate an initialization to automatic variable DECL based on INIT_TYPE.
1748 Build a call to internal const function DEFERRED_INIT:
1749 1st argument: SIZE of the DECL;
1750 2nd argument: INIT_TYPE;
1751 3rd argument: IS_VLA, 0 NO, 1 YES;
1753 as LHS = DEFERRED_INIT (SIZE of the DECL, INIT_TYPE, IS_VLA)
1754 if IS_VLA is false, the LHS is the DECL itself,
1755 if IS_VLA is true, the LHS is a MEM_REF whose address is the pointer
1756 to this DECL. */
1757 static void
1758 gimple_add_init_for_auto_var (tree decl,
1759 enum auto_init_type init_type,
1760 bool is_vla,
1761 gimple_seq *seq_p)
1763 gcc_assert (auto_var_p (decl));
1764 gcc_assert (init_type > AUTO_INIT_UNINITIALIZED);
1765 location_t loc = EXPR_LOCATION (decl);
1766 tree decl_size = TYPE_SIZE_UNIT (TREE_TYPE (decl));
1768 tree init_type_node
1769 = build_int_cst (integer_type_node, (int) init_type);
1770 tree is_vla_node
1771 = build_int_cst (integer_type_node, (int) is_vla);
1773 tree call = build_call_expr_internal_loc (loc, IFN_DEFERRED_INIT,
1774 TREE_TYPE (decl), 3,
1775 decl_size, init_type_node,
1776 is_vla_node);
1778 gimplify_assign (decl, call, seq_p);
1781 /* Generate padding initialization for automatic vairable DECL.
1782 C guarantees that brace-init with fewer initializers than members
1783 aggregate will initialize the rest of the aggregate as-if it were
1784 static initialization. In turn static initialization guarantees
1785 that padding is initialized to zero. So, we always initialize paddings
1786 to zeroes regardless INIT_TYPE.
1787 To do the padding initialization, we insert a call to
1788 __builtin_clear_padding (&decl, 0, for_auto_init = true).
1789 Note, we add an additional dummy argument for __builtin_clear_padding,
1790 'for_auto_init' to distinguish whether this call is for automatic
1791 variable initialization or not.
1793 static void
1794 gimple_add_padding_init_for_auto_var (tree decl, bool is_vla,
1795 gimple_seq *seq_p)
1797 tree addr_of_decl = NULL_TREE;
1798 bool for_auto_init = true;
1799 tree fn = builtin_decl_explicit (BUILT_IN_CLEAR_PADDING);
1801 if (is_vla)
1803 /* The temporary address variable for this vla should be
1804 created in gimplify_vla_decl. */
1805 gcc_assert (DECL_HAS_VALUE_EXPR_P (decl));
1806 gcc_assert (TREE_CODE (DECL_VALUE_EXPR (decl)) == INDIRECT_REF);
1807 addr_of_decl = TREE_OPERAND (DECL_VALUE_EXPR (decl), 0);
1809 else
1811 mark_addressable (decl);
1812 addr_of_decl = build_fold_addr_expr (decl);
1815 gimple *call = gimple_build_call (fn,
1816 3, addr_of_decl,
1817 build_zero_cst (TREE_TYPE (addr_of_decl)),
1818 build_int_cst (integer_type_node,
1819 (int) for_auto_init));
1820 gimplify_seq_add_stmt (seq_p, call);
1823 /* Return true if the DECL need to be automaticly initialized by the
1824 compiler. */
1825 static bool
1826 is_var_need_auto_init (tree decl)
1828 if (auto_var_p (decl)
1829 && (TREE_CODE (decl) != VAR_DECL
1830 || !DECL_HARD_REGISTER (decl))
1831 && (flag_auto_var_init > AUTO_INIT_UNINITIALIZED)
1832 && (!lookup_attribute ("uninitialized", DECL_ATTRIBUTES (decl)))
1833 && !OPAQUE_TYPE_P (TREE_TYPE (decl))
1834 && !is_empty_type (TREE_TYPE (decl)))
1835 return true;
1836 return false;
1839 /* Gimplify a DECL_EXPR node *STMT_P by making any necessary allocation
1840 and initialization explicit. */
1842 static enum gimplify_status
1843 gimplify_decl_expr (tree *stmt_p, gimple_seq *seq_p)
1845 tree stmt = *stmt_p;
1846 tree decl = DECL_EXPR_DECL (stmt);
1848 *stmt_p = NULL_TREE;
1850 if (TREE_TYPE (decl) == error_mark_node)
1851 return GS_ERROR;
1853 if ((TREE_CODE (decl) == TYPE_DECL
1854 || VAR_P (decl))
1855 && !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl)))
1857 gimplify_type_sizes (TREE_TYPE (decl), seq_p);
1858 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
1859 gimplify_type_sizes (TREE_TYPE (TREE_TYPE (decl)), seq_p);
1862 /* ??? DECL_ORIGINAL_TYPE is streamed for LTO so it needs to be gimplified
1863 in case its size expressions contain problematic nodes like CALL_EXPR. */
1864 if (TREE_CODE (decl) == TYPE_DECL
1865 && DECL_ORIGINAL_TYPE (decl)
1866 && !TYPE_SIZES_GIMPLIFIED (DECL_ORIGINAL_TYPE (decl)))
1868 gimplify_type_sizes (DECL_ORIGINAL_TYPE (decl), seq_p);
1869 if (TREE_CODE (DECL_ORIGINAL_TYPE (decl)) == REFERENCE_TYPE)
1870 gimplify_type_sizes (TREE_TYPE (DECL_ORIGINAL_TYPE (decl)), seq_p);
1873 if (VAR_P (decl) && !DECL_EXTERNAL (decl))
1875 tree init = DECL_INITIAL (decl);
1876 bool is_vla = false;
1877 /* Check whether a decl has FE created VALUE_EXPR here BEFORE
1878 gimplify_vla_decl creates VALUE_EXPR for a vla decl.
1879 If the decl has VALUE_EXPR that was created by FE (usually
1880 C++FE), it's a proxy varaible, and FE already initialized
1881 the VALUE_EXPR of it, we should not initialize it anymore. */
1882 bool decl_had_value_expr_p = DECL_HAS_VALUE_EXPR_P (decl);
1884 poly_uint64 size;
1885 if (!poly_int_tree_p (DECL_SIZE_UNIT (decl), &size)
1886 || (!TREE_STATIC (decl)
1887 && flag_stack_check == GENERIC_STACK_CHECK
1888 && maybe_gt (size,
1889 (unsigned HOST_WIDE_INT) STACK_CHECK_MAX_VAR_SIZE)))
1891 gimplify_vla_decl (decl, seq_p);
1892 is_vla = true;
1895 if (asan_poisoned_variables
1896 && !is_vla
1897 && TREE_ADDRESSABLE (decl)
1898 && !TREE_STATIC (decl)
1899 && !DECL_HAS_VALUE_EXPR_P (decl)
1900 && DECL_ALIGN (decl) <= MAX_SUPPORTED_STACK_ALIGNMENT
1901 && dbg_cnt (asan_use_after_scope)
1902 && !gimplify_omp_ctxp
1903 /* GNAT introduces temporaries to hold return values of calls in
1904 initializers of variables defined in other units, so the
1905 declaration of the variable is discarded completely. We do not
1906 want to issue poison calls for such dropped variables. */
1907 && (DECL_SEEN_IN_BIND_EXPR_P (decl)
1908 || (DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)))
1910 asan_poisoned_variables->add (decl);
1911 asan_poison_variable (decl, false, seq_p);
1912 if (!DECL_ARTIFICIAL (decl) && gimplify_ctxp->live_switch_vars)
1913 gimplify_ctxp->live_switch_vars->add (decl);
1916 /* Some front ends do not explicitly declare all anonymous
1917 artificial variables. We compensate here by declaring the
1918 variables, though it would be better if the front ends would
1919 explicitly declare them. */
1920 if (!DECL_SEEN_IN_BIND_EXPR_P (decl)
1921 && DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
1922 gimple_add_tmp_var (decl);
1924 if (init && init != error_mark_node)
1926 if (!TREE_STATIC (decl))
1928 DECL_INITIAL (decl) = NULL_TREE;
1929 init = build2 (INIT_EXPR, void_type_node, decl, init);
1930 gimplify_and_add (init, seq_p);
1931 ggc_free (init);
1932 /* Clear TREE_READONLY if we really have an initialization. */
1933 if (!DECL_INITIAL (decl)
1934 && !omp_privatize_by_reference (decl))
1935 TREE_READONLY (decl) = 0;
1937 else
1938 /* We must still examine initializers for static variables
1939 as they may contain a label address. */
1940 walk_tree (&init, force_labels_r, NULL, NULL);
1942 /* When there is no explicit initializer, if the user requested,
1943 We should insert an artifical initializer for this automatic
1944 variable. */
1945 else if (is_var_need_auto_init (decl)
1946 && !decl_had_value_expr_p)
1948 gimple_add_init_for_auto_var (decl,
1949 flag_auto_var_init,
1950 is_vla,
1951 seq_p);
1952 /* The expanding of a call to the above .DEFERRED_INIT will apply
1953 block initialization to the whole space covered by this variable.
1954 As a result, all the paddings will be initialized to zeroes
1955 for zero initialization and 0xFE byte-repeatable patterns for
1956 pattern initialization.
1957 In order to make the paddings as zeroes for pattern init, We
1958 should add a call to __builtin_clear_padding to clear the
1959 paddings to zero in compatiple with CLANG.
1960 We cannot insert this call if the variable is a gimple register
1961 since __builtin_clear_padding will take the address of the
1962 variable. As a result, if a long double/_Complex long double
1963 variable will spilled into stack later, its padding is 0XFE. */
1964 if (flag_auto_var_init == AUTO_INIT_PATTERN
1965 && !is_gimple_reg (decl)
1966 && clear_padding_type_may_have_padding_p (TREE_TYPE (decl)))
1967 gimple_add_padding_init_for_auto_var (decl, is_vla, seq_p);
1971 return GS_ALL_DONE;
1974 /* Gimplify a LOOP_EXPR. Normally this just involves gimplifying the body
1975 and replacing the LOOP_EXPR with goto, but if the loop contains an
1976 EXIT_EXPR, we need to append a label for it to jump to. */
1978 static enum gimplify_status
1979 gimplify_loop_expr (tree *expr_p, gimple_seq *pre_p)
1981 tree saved_label = gimplify_ctxp->exit_label;
1982 tree start_label = create_artificial_label (UNKNOWN_LOCATION);
1984 gimplify_seq_add_stmt (pre_p, gimple_build_label (start_label));
1986 gimplify_ctxp->exit_label = NULL_TREE;
1988 gimplify_and_add (LOOP_EXPR_BODY (*expr_p), pre_p);
1990 gimplify_seq_add_stmt (pre_p, gimple_build_goto (start_label));
1992 if (gimplify_ctxp->exit_label)
1993 gimplify_seq_add_stmt (pre_p,
1994 gimple_build_label (gimplify_ctxp->exit_label));
1996 gimplify_ctxp->exit_label = saved_label;
1998 *expr_p = NULL;
1999 return GS_ALL_DONE;
2002 /* Gimplify a statement list onto a sequence. These may be created either
2003 by an enlightened front-end, or by shortcut_cond_expr. */
2005 static enum gimplify_status
2006 gimplify_statement_list (tree *expr_p, gimple_seq *pre_p)
2008 tree temp = voidify_wrapper_expr (*expr_p, NULL);
2010 tree_stmt_iterator i = tsi_start (*expr_p);
2012 while (!tsi_end_p (i))
2014 gimplify_stmt (tsi_stmt_ptr (i), pre_p);
2015 tsi_delink (&i);
2018 if (temp)
2020 *expr_p = temp;
2021 return GS_OK;
2024 return GS_ALL_DONE;
2027 /* Callback for walk_gimple_seq. */
2029 static tree
2030 warn_switch_unreachable_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
2031 struct walk_stmt_info *wi)
2033 gimple *stmt = gsi_stmt (*gsi_p);
2035 *handled_ops_p = true;
2036 switch (gimple_code (stmt))
2038 case GIMPLE_TRY:
2039 /* A compiler-generated cleanup or a user-written try block.
2040 If it's empty, don't dive into it--that would result in
2041 worse location info. */
2042 if (gimple_try_eval (stmt) == NULL)
2044 wi->info = stmt;
2045 return integer_zero_node;
2047 /* Fall through. */
2048 case GIMPLE_BIND:
2049 case GIMPLE_CATCH:
2050 case GIMPLE_EH_FILTER:
2051 case GIMPLE_TRANSACTION:
2052 /* Walk the sub-statements. */
2053 *handled_ops_p = false;
2054 break;
2056 case GIMPLE_DEBUG:
2057 /* Ignore these. We may generate them before declarations that
2058 are never executed. If there's something to warn about,
2059 there will be non-debug stmts too, and we'll catch those. */
2060 break;
2062 case GIMPLE_CALL:
2063 if (gimple_call_internal_p (stmt, IFN_ASAN_MARK))
2065 *handled_ops_p = false;
2066 break;
2068 /* Fall through. */
2069 default:
2070 /* Save the first "real" statement (not a decl/lexical scope/...). */
2071 wi->info = stmt;
2072 return integer_zero_node;
2074 return NULL_TREE;
2077 /* Possibly warn about unreachable statements between switch's controlling
2078 expression and the first case. SEQ is the body of a switch expression. */
2080 static void
2081 maybe_warn_switch_unreachable (gimple_seq seq)
2083 if (!warn_switch_unreachable
2084 /* This warning doesn't play well with Fortran when optimizations
2085 are on. */
2086 || lang_GNU_Fortran ()
2087 || seq == NULL)
2088 return;
2090 struct walk_stmt_info wi;
2091 memset (&wi, 0, sizeof (wi));
2092 walk_gimple_seq (seq, warn_switch_unreachable_r, NULL, &wi);
2093 gimple *stmt = (gimple *) wi.info;
2095 if (stmt && gimple_code (stmt) != GIMPLE_LABEL)
2097 if (gimple_code (stmt) == GIMPLE_GOTO
2098 && TREE_CODE (gimple_goto_dest (stmt)) == LABEL_DECL
2099 && DECL_ARTIFICIAL (gimple_goto_dest (stmt)))
2100 /* Don't warn for compiler-generated gotos. These occur
2101 in Duff's devices, for example. */;
2102 else
2103 warning_at (gimple_location (stmt), OPT_Wswitch_unreachable,
2104 "statement will never be executed");
2109 /* A label entry that pairs label and a location. */
2110 struct label_entry
2112 tree label;
2113 location_t loc;
2116 /* Find LABEL in vector of label entries VEC. */
2118 static struct label_entry *
2119 find_label_entry (const auto_vec<struct label_entry> *vec, tree label)
2121 unsigned int i;
2122 struct label_entry *l;
2124 FOR_EACH_VEC_ELT (*vec, i, l)
2125 if (l->label == label)
2126 return l;
2127 return NULL;
2130 /* Return true if LABEL, a LABEL_DECL, represents a case label
2131 in a vector of labels CASES. */
2133 static bool
2134 case_label_p (const vec<tree> *cases, tree label)
2136 unsigned int i;
2137 tree l;
2139 FOR_EACH_VEC_ELT (*cases, i, l)
2140 if (CASE_LABEL (l) == label)
2141 return true;
2142 return false;
2145 /* Find the last nondebug statement in a scope STMT. */
2147 static gimple *
2148 last_stmt_in_scope (gimple *stmt)
2150 if (!stmt)
2151 return NULL;
2153 switch (gimple_code (stmt))
2155 case GIMPLE_BIND:
2157 gbind *bind = as_a <gbind *> (stmt);
2158 stmt = gimple_seq_last_nondebug_stmt (gimple_bind_body (bind));
2159 return last_stmt_in_scope (stmt);
2162 case GIMPLE_TRY:
2164 gtry *try_stmt = as_a <gtry *> (stmt);
2165 stmt = gimple_seq_last_nondebug_stmt (gimple_try_eval (try_stmt));
2166 gimple *last_eval = last_stmt_in_scope (stmt);
2167 if (gimple_stmt_may_fallthru (last_eval)
2168 && (last_eval == NULL
2169 || !gimple_call_internal_p (last_eval, IFN_FALLTHROUGH))
2170 && gimple_try_kind (try_stmt) == GIMPLE_TRY_FINALLY)
2172 stmt = gimple_seq_last_nondebug_stmt (gimple_try_cleanup (try_stmt));
2173 return last_stmt_in_scope (stmt);
2175 else
2176 return last_eval;
2179 case GIMPLE_DEBUG:
2180 gcc_unreachable ();
2182 default:
2183 return stmt;
2187 /* Collect interesting labels in LABELS and return the statement preceding
2188 another case label, or a user-defined label. Store a location useful
2189 to give warnings at *PREVLOC (usually the location of the returned
2190 statement or of its surrounding scope). */
2192 static gimple *
2193 collect_fallthrough_labels (gimple_stmt_iterator *gsi_p,
2194 auto_vec <struct label_entry> *labels,
2195 location_t *prevloc)
2197 gimple *prev = NULL;
2199 *prevloc = UNKNOWN_LOCATION;
2202 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND)
2204 /* Recognize the special GIMPLE_BIND added by gimplify_switch_expr,
2205 which starts on a GIMPLE_SWITCH and ends with a break label.
2206 Handle that as a single statement that can fall through. */
2207 gbind *bind = as_a <gbind *> (gsi_stmt (*gsi_p));
2208 gimple *first = gimple_seq_first_stmt (gimple_bind_body (bind));
2209 gimple *last = gimple_seq_last_stmt (gimple_bind_body (bind));
2210 if (last
2211 && gimple_code (first) == GIMPLE_SWITCH
2212 && gimple_code (last) == GIMPLE_LABEL)
2214 tree label = gimple_label_label (as_a <glabel *> (last));
2215 if (SWITCH_BREAK_LABEL_P (label))
2217 prev = bind;
2218 gsi_next (gsi_p);
2219 continue;
2223 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND
2224 || gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_TRY)
2226 /* Nested scope. Only look at the last statement of
2227 the innermost scope. */
2228 location_t bind_loc = gimple_location (gsi_stmt (*gsi_p));
2229 gimple *last = last_stmt_in_scope (gsi_stmt (*gsi_p));
2230 if (last)
2232 prev = last;
2233 /* It might be a label without a location. Use the
2234 location of the scope then. */
2235 if (!gimple_has_location (prev))
2236 *prevloc = bind_loc;
2238 gsi_next (gsi_p);
2239 continue;
2242 /* Ifs are tricky. */
2243 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_COND)
2245 gcond *cond_stmt = as_a <gcond *> (gsi_stmt (*gsi_p));
2246 tree false_lab = gimple_cond_false_label (cond_stmt);
2247 location_t if_loc = gimple_location (cond_stmt);
2249 /* If we have e.g.
2250 if (i > 1) goto <D.2259>; else goto D;
2251 we can't do much with the else-branch. */
2252 if (!DECL_ARTIFICIAL (false_lab))
2253 break;
2255 /* Go on until the false label, then one step back. */
2256 for (; !gsi_end_p (*gsi_p); gsi_next (gsi_p))
2258 gimple *stmt = gsi_stmt (*gsi_p);
2259 if (gimple_code (stmt) == GIMPLE_LABEL
2260 && gimple_label_label (as_a <glabel *> (stmt)) == false_lab)
2261 break;
2264 /* Not found? Oops. */
2265 if (gsi_end_p (*gsi_p))
2266 break;
2268 struct label_entry l = { false_lab, if_loc };
2269 labels->safe_push (l);
2271 /* Go to the last statement of the then branch. */
2272 gsi_prev (gsi_p);
2274 /* if (i != 0) goto <D.1759>; else goto <D.1760>;
2275 <D.1759>:
2276 <stmt>;
2277 goto <D.1761>;
2278 <D.1760>:
2280 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_GOTO
2281 && !gimple_has_location (gsi_stmt (*gsi_p)))
2283 /* Look at the statement before, it might be
2284 attribute fallthrough, in which case don't warn. */
2285 gsi_prev (gsi_p);
2286 bool fallthru_before_dest
2287 = gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_FALLTHROUGH);
2288 gsi_next (gsi_p);
2289 tree goto_dest = gimple_goto_dest (gsi_stmt (*gsi_p));
2290 if (!fallthru_before_dest)
2292 struct label_entry l = { goto_dest, if_loc };
2293 labels->safe_push (l);
2296 /* And move back. */
2297 gsi_next (gsi_p);
2300 /* Remember the last statement. Skip labels that are of no interest
2301 to us. */
2302 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
2304 tree label = gimple_label_label (as_a <glabel *> (gsi_stmt (*gsi_p)));
2305 if (find_label_entry (labels, label))
2306 prev = gsi_stmt (*gsi_p);
2308 else if (gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_ASAN_MARK))
2310 else if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_PREDICT)
2312 else if (!is_gimple_debug (gsi_stmt (*gsi_p)))
2313 prev = gsi_stmt (*gsi_p);
2314 gsi_next (gsi_p);
2316 while (!gsi_end_p (*gsi_p)
2317 /* Stop if we find a case or a user-defined label. */
2318 && (gimple_code (gsi_stmt (*gsi_p)) != GIMPLE_LABEL
2319 || !gimple_has_location (gsi_stmt (*gsi_p))));
2321 if (prev && gimple_has_location (prev))
2322 *prevloc = gimple_location (prev);
2323 return prev;
2326 /* Return true if the switch fallthough warning should occur. LABEL is
2327 the label statement that we're falling through to. */
2329 static bool
2330 should_warn_for_implicit_fallthrough (gimple_stmt_iterator *gsi_p, tree label)
2332 gimple_stmt_iterator gsi = *gsi_p;
2334 /* Don't warn if the label is marked with a "falls through" comment. */
2335 if (FALLTHROUGH_LABEL_P (label))
2336 return false;
2338 /* Don't warn for non-case labels followed by a statement:
2339 case 0:
2340 foo ();
2341 label:
2342 bar ();
2343 as these are likely intentional. */
2344 if (!case_label_p (&gimplify_ctxp->case_labels, label))
2346 tree l;
2347 while (!gsi_end_p (gsi)
2348 && gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
2349 && (l = gimple_label_label (as_a <glabel *> (gsi_stmt (gsi))))
2350 && !case_label_p (&gimplify_ctxp->case_labels, l))
2351 gsi_next_nondebug (&gsi);
2352 if (gsi_end_p (gsi) || gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL)
2353 return false;
2356 /* Don't warn for terminated branches, i.e. when the subsequent case labels
2357 immediately breaks. */
2358 gsi = *gsi_p;
2360 /* Skip all immediately following labels. */
2361 while (!gsi_end_p (gsi)
2362 && (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
2363 || gimple_code (gsi_stmt (gsi)) == GIMPLE_PREDICT))
2364 gsi_next_nondebug (&gsi);
2366 /* { ... something; default:; } */
2367 if (gsi_end_p (gsi)
2368 /* { ... something; default: break; } or
2369 { ... something; default: goto L; } */
2370 || gimple_code (gsi_stmt (gsi)) == GIMPLE_GOTO
2371 /* { ... something; default: return; } */
2372 || gimple_code (gsi_stmt (gsi)) == GIMPLE_RETURN)
2373 return false;
2375 return true;
2378 /* Callback for walk_gimple_seq. */
2380 static tree
2381 warn_implicit_fallthrough_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
2382 struct walk_stmt_info *)
2384 gimple *stmt = gsi_stmt (*gsi_p);
2386 *handled_ops_p = true;
2387 switch (gimple_code (stmt))
2389 case GIMPLE_TRY:
2390 case GIMPLE_BIND:
2391 case GIMPLE_CATCH:
2392 case GIMPLE_EH_FILTER:
2393 case GIMPLE_TRANSACTION:
2394 /* Walk the sub-statements. */
2395 *handled_ops_p = false;
2396 break;
2398 /* Find a sequence of form:
2400 GIMPLE_LABEL
2401 [...]
2402 <may fallthru stmt>
2403 GIMPLE_LABEL
2405 and possibly warn. */
2406 case GIMPLE_LABEL:
2408 /* Found a label. Skip all immediately following labels. */
2409 while (!gsi_end_p (*gsi_p)
2410 && gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
2411 gsi_next_nondebug (gsi_p);
2413 /* There might be no more statements. */
2414 if (gsi_end_p (*gsi_p))
2415 return integer_zero_node;
2417 /* Vector of labels that fall through. */
2418 auto_vec <struct label_entry> labels;
2419 location_t prevloc;
2420 gimple *prev = collect_fallthrough_labels (gsi_p, &labels, &prevloc);
2422 /* There might be no more statements. */
2423 if (gsi_end_p (*gsi_p))
2424 return integer_zero_node;
2426 gimple *next = gsi_stmt (*gsi_p);
2427 tree label;
2428 /* If what follows is a label, then we may have a fallthrough. */
2429 if (gimple_code (next) == GIMPLE_LABEL
2430 && gimple_has_location (next)
2431 && (label = gimple_label_label (as_a <glabel *> (next)))
2432 && prev != NULL)
2434 struct label_entry *l;
2435 bool warned_p = false;
2436 auto_diagnostic_group d;
2437 if (!should_warn_for_implicit_fallthrough (gsi_p, label))
2438 /* Quiet. */;
2439 else if (gimple_code (prev) == GIMPLE_LABEL
2440 && (label = gimple_label_label (as_a <glabel *> (prev)))
2441 && (l = find_label_entry (&labels, label)))
2442 warned_p = warning_at (l->loc, OPT_Wimplicit_fallthrough_,
2443 "this statement may fall through");
2444 else if (!gimple_call_internal_p (prev, IFN_FALLTHROUGH)
2445 /* Try to be clever and don't warn when the statement
2446 can't actually fall through. */
2447 && gimple_stmt_may_fallthru (prev)
2448 && prevloc != UNKNOWN_LOCATION)
2449 warned_p = warning_at (prevloc,
2450 OPT_Wimplicit_fallthrough_,
2451 "this statement may fall through");
2452 if (warned_p)
2453 inform (gimple_location (next), "here");
2455 /* Mark this label as processed so as to prevent multiple
2456 warnings in nested switches. */
2457 FALLTHROUGH_LABEL_P (label) = true;
2459 /* So that next warn_implicit_fallthrough_r will start looking for
2460 a new sequence starting with this label. */
2461 gsi_prev (gsi_p);
2464 break;
2465 default:
2466 break;
2468 return NULL_TREE;
2471 /* Warn when a switch case falls through. */
2473 static void
2474 maybe_warn_implicit_fallthrough (gimple_seq seq)
2476 if (!warn_implicit_fallthrough)
2477 return;
2479 /* This warning is meant for C/C++/ObjC/ObjC++ only. */
2480 if (!(lang_GNU_C ()
2481 || lang_GNU_CXX ()
2482 || lang_GNU_OBJC ()))
2483 return;
2485 struct walk_stmt_info wi;
2486 memset (&wi, 0, sizeof (wi));
2487 walk_gimple_seq (seq, warn_implicit_fallthrough_r, NULL, &wi);
2490 /* Callback for walk_gimple_seq. */
2492 static tree
2493 expand_FALLTHROUGH_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
2494 struct walk_stmt_info *wi)
2496 gimple *stmt = gsi_stmt (*gsi_p);
2498 *handled_ops_p = true;
2499 switch (gimple_code (stmt))
2501 case GIMPLE_TRY:
2502 case GIMPLE_BIND:
2503 case GIMPLE_CATCH:
2504 case GIMPLE_EH_FILTER:
2505 case GIMPLE_TRANSACTION:
2506 /* Walk the sub-statements. */
2507 *handled_ops_p = false;
2508 break;
2509 case GIMPLE_CALL:
2510 if (gimple_call_internal_p (stmt, IFN_FALLTHROUGH))
2512 gsi_remove (gsi_p, true);
2513 if (gsi_end_p (*gsi_p))
2515 *static_cast<location_t *>(wi->info) = gimple_location (stmt);
2516 return integer_zero_node;
2519 bool found = false;
2520 location_t loc = gimple_location (stmt);
2522 gimple_stmt_iterator gsi2 = *gsi_p;
2523 stmt = gsi_stmt (gsi2);
2524 if (gimple_code (stmt) == GIMPLE_GOTO && !gimple_has_location (stmt))
2526 /* Go on until the artificial label. */
2527 tree goto_dest = gimple_goto_dest (stmt);
2528 for (; !gsi_end_p (gsi2); gsi_next (&gsi2))
2530 if (gimple_code (gsi_stmt (gsi2)) == GIMPLE_LABEL
2531 && gimple_label_label (as_a <glabel *> (gsi_stmt (gsi2)))
2532 == goto_dest)
2533 break;
2536 /* Not found? Stop. */
2537 if (gsi_end_p (gsi2))
2538 break;
2540 /* Look one past it. */
2541 gsi_next (&gsi2);
2544 /* We're looking for a case label or default label here. */
2545 while (!gsi_end_p (gsi2))
2547 stmt = gsi_stmt (gsi2);
2548 if (gimple_code (stmt) == GIMPLE_LABEL)
2550 tree label = gimple_label_label (as_a <glabel *> (stmt));
2551 if (gimple_has_location (stmt) && DECL_ARTIFICIAL (label))
2553 found = true;
2554 break;
2557 else if (gimple_call_internal_p (stmt, IFN_ASAN_MARK))
2559 else if (!is_gimple_debug (stmt))
2560 /* Anything else is not expected. */
2561 break;
2562 gsi_next (&gsi2);
2564 if (!found)
2565 pedwarn (loc, 0, "attribute %<fallthrough%> not preceding "
2566 "a case label or default label");
2568 break;
2569 default:
2570 break;
2572 return NULL_TREE;
2575 /* Expand all FALLTHROUGH () calls in SEQ. */
2577 static void
2578 expand_FALLTHROUGH (gimple_seq *seq_p)
2580 struct walk_stmt_info wi;
2581 location_t loc;
2582 memset (&wi, 0, sizeof (wi));
2583 wi.info = (void *) &loc;
2584 walk_gimple_seq_mod (seq_p, expand_FALLTHROUGH_r, NULL, &wi);
2585 if (wi.callback_result == integer_zero_node)
2586 /* We've found [[fallthrough]]; at the end of a switch, which the C++
2587 standard says is ill-formed; see [dcl.attr.fallthrough]. */
2588 pedwarn (loc, 0, "attribute %<fallthrough%> not preceding "
2589 "a case label or default label");
2593 /* Gimplify a SWITCH_EXPR, and collect the vector of labels it can
2594 branch to. */
2596 static enum gimplify_status
2597 gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p)
2599 tree switch_expr = *expr_p;
2600 gimple_seq switch_body_seq = NULL;
2601 enum gimplify_status ret;
2602 tree index_type = TREE_TYPE (switch_expr);
2603 if (index_type == NULL_TREE)
2604 index_type = TREE_TYPE (SWITCH_COND (switch_expr));
2606 ret = gimplify_expr (&SWITCH_COND (switch_expr), pre_p, NULL, is_gimple_val,
2607 fb_rvalue);
2608 if (ret == GS_ERROR || ret == GS_UNHANDLED)
2609 return ret;
2611 if (SWITCH_BODY (switch_expr))
2613 vec<tree> labels;
2614 vec<tree> saved_labels;
2615 hash_set<tree> *saved_live_switch_vars = NULL;
2616 tree default_case = NULL_TREE;
2617 gswitch *switch_stmt;
2619 /* Save old labels, get new ones from body, then restore the old
2620 labels. Save all the things from the switch body to append after. */
2621 saved_labels = gimplify_ctxp->case_labels;
2622 gimplify_ctxp->case_labels.create (8);
2624 /* Do not create live_switch_vars if SWITCH_BODY is not a BIND_EXPR. */
2625 saved_live_switch_vars = gimplify_ctxp->live_switch_vars;
2626 tree_code body_type = TREE_CODE (SWITCH_BODY (switch_expr));
2627 if (body_type == BIND_EXPR || body_type == STATEMENT_LIST)
2628 gimplify_ctxp->live_switch_vars = new hash_set<tree> (4);
2629 else
2630 gimplify_ctxp->live_switch_vars = NULL;
2632 bool old_in_switch_expr = gimplify_ctxp->in_switch_expr;
2633 gimplify_ctxp->in_switch_expr = true;
2635 gimplify_stmt (&SWITCH_BODY (switch_expr), &switch_body_seq);
2637 gimplify_ctxp->in_switch_expr = old_in_switch_expr;
2638 maybe_warn_switch_unreachable (switch_body_seq);
2639 maybe_warn_implicit_fallthrough (switch_body_seq);
2640 /* Only do this for the outermost GIMPLE_SWITCH. */
2641 if (!gimplify_ctxp->in_switch_expr)
2642 expand_FALLTHROUGH (&switch_body_seq);
2644 labels = gimplify_ctxp->case_labels;
2645 gimplify_ctxp->case_labels = saved_labels;
2647 if (gimplify_ctxp->live_switch_vars)
2649 gcc_assert (gimplify_ctxp->live_switch_vars->is_empty ());
2650 delete gimplify_ctxp->live_switch_vars;
2652 gimplify_ctxp->live_switch_vars = saved_live_switch_vars;
2654 preprocess_case_label_vec_for_gimple (labels, index_type,
2655 &default_case);
2657 bool add_bind = false;
2658 if (!default_case)
2660 glabel *new_default;
2662 default_case
2663 = build_case_label (NULL_TREE, NULL_TREE,
2664 create_artificial_label (UNKNOWN_LOCATION));
2665 if (old_in_switch_expr)
2667 SWITCH_BREAK_LABEL_P (CASE_LABEL (default_case)) = 1;
2668 add_bind = true;
2670 new_default = gimple_build_label (CASE_LABEL (default_case));
2671 gimplify_seq_add_stmt (&switch_body_seq, new_default);
2673 else if (old_in_switch_expr)
2675 gimple *last = gimple_seq_last_stmt (switch_body_seq);
2676 if (last && gimple_code (last) == GIMPLE_LABEL)
2678 tree label = gimple_label_label (as_a <glabel *> (last));
2679 if (SWITCH_BREAK_LABEL_P (label))
2680 add_bind = true;
2684 switch_stmt = gimple_build_switch (SWITCH_COND (switch_expr),
2685 default_case, labels);
2686 /* For the benefit of -Wimplicit-fallthrough, if switch_body_seq
2687 ends with a GIMPLE_LABEL holding SWITCH_BREAK_LABEL_P LABEL_DECL,
2688 wrap the GIMPLE_SWITCH up to that GIMPLE_LABEL into a GIMPLE_BIND,
2689 so that we can easily find the start and end of the switch
2690 statement. */
2691 if (add_bind)
2693 gimple_seq bind_body = NULL;
2694 gimplify_seq_add_stmt (&bind_body, switch_stmt);
2695 gimple_seq_add_seq (&bind_body, switch_body_seq);
2696 gbind *bind = gimple_build_bind (NULL_TREE, bind_body, NULL_TREE);
2697 gimple_set_location (bind, EXPR_LOCATION (switch_expr));
2698 gimplify_seq_add_stmt (pre_p, bind);
2700 else
2702 gimplify_seq_add_stmt (pre_p, switch_stmt);
2703 gimplify_seq_add_seq (pre_p, switch_body_seq);
2705 labels.release ();
2707 else
2708 gcc_unreachable ();
2710 return GS_ALL_DONE;
2713 /* Gimplify the LABEL_EXPR pointed to by EXPR_P. */
2715 static enum gimplify_status
2716 gimplify_label_expr (tree *expr_p, gimple_seq *pre_p)
2718 gcc_assert (decl_function_context (LABEL_EXPR_LABEL (*expr_p))
2719 == current_function_decl);
2721 tree label = LABEL_EXPR_LABEL (*expr_p);
2722 glabel *label_stmt = gimple_build_label (label);
2723 gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
2724 gimplify_seq_add_stmt (pre_p, label_stmt);
2726 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label)))
2727 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_COLD_LABEL,
2728 NOT_TAKEN));
2729 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label)))
2730 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_HOT_LABEL,
2731 TAKEN));
2733 return GS_ALL_DONE;
2736 /* Gimplify the CASE_LABEL_EXPR pointed to by EXPR_P. */
2738 static enum gimplify_status
2739 gimplify_case_label_expr (tree *expr_p, gimple_seq *pre_p)
2741 struct gimplify_ctx *ctxp;
2742 glabel *label_stmt;
2744 /* Invalid programs can play Duff's Device type games with, for example,
2745 #pragma omp parallel. At least in the C front end, we don't
2746 detect such invalid branches until after gimplification, in the
2747 diagnose_omp_blocks pass. */
2748 for (ctxp = gimplify_ctxp; ; ctxp = ctxp->prev_context)
2749 if (ctxp->case_labels.exists ())
2750 break;
2752 tree label = CASE_LABEL (*expr_p);
2753 label_stmt = gimple_build_label (label);
2754 gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
2755 ctxp->case_labels.safe_push (*expr_p);
2756 gimplify_seq_add_stmt (pre_p, label_stmt);
2758 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label)))
2759 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_COLD_LABEL,
2760 NOT_TAKEN));
2761 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label)))
2762 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_HOT_LABEL,
2763 TAKEN));
2765 return GS_ALL_DONE;
2768 /* Build a GOTO to the LABEL_DECL pointed to by LABEL_P, building it first
2769 if necessary. */
2771 tree
2772 build_and_jump (tree *label_p)
2774 if (label_p == NULL)
2775 /* If there's nowhere to jump, just fall through. */
2776 return NULL_TREE;
2778 if (*label_p == NULL_TREE)
2780 tree label = create_artificial_label (UNKNOWN_LOCATION);
2781 *label_p = label;
2784 return build1 (GOTO_EXPR, void_type_node, *label_p);
2787 /* Gimplify an EXIT_EXPR by converting to a GOTO_EXPR inside a COND_EXPR.
2788 This also involves building a label to jump to and communicating it to
2789 gimplify_loop_expr through gimplify_ctxp->exit_label. */
2791 static enum gimplify_status
2792 gimplify_exit_expr (tree *expr_p)
2794 tree cond = TREE_OPERAND (*expr_p, 0);
2795 tree expr;
2797 expr = build_and_jump (&gimplify_ctxp->exit_label);
2798 expr = build3 (COND_EXPR, void_type_node, cond, expr, NULL_TREE);
2799 *expr_p = expr;
2801 return GS_OK;
2804 /* *EXPR_P is a COMPONENT_REF being used as an rvalue. If its type is
2805 different from its canonical type, wrap the whole thing inside a
2806 NOP_EXPR and force the type of the COMPONENT_REF to be the canonical
2807 type.
2809 The canonical type of a COMPONENT_REF is the type of the field being
2810 referenced--unless the field is a bit-field which can be read directly
2811 in a smaller mode, in which case the canonical type is the
2812 sign-appropriate type corresponding to that mode. */
2814 static void
2815 canonicalize_component_ref (tree *expr_p)
2817 tree expr = *expr_p;
2818 tree type;
2820 gcc_assert (TREE_CODE (expr) == COMPONENT_REF);
2822 if (INTEGRAL_TYPE_P (TREE_TYPE (expr)))
2823 type = TREE_TYPE (get_unwidened (expr, NULL_TREE));
2824 else
2825 type = TREE_TYPE (TREE_OPERAND (expr, 1));
2827 /* One could argue that all the stuff below is not necessary for
2828 the non-bitfield case and declare it a FE error if type
2829 adjustment would be needed. */
2830 if (TREE_TYPE (expr) != type)
2832 #ifdef ENABLE_TYPES_CHECKING
2833 tree old_type = TREE_TYPE (expr);
2834 #endif
2835 int type_quals;
2837 /* We need to preserve qualifiers and propagate them from
2838 operand 0. */
2839 type_quals = TYPE_QUALS (type)
2840 | TYPE_QUALS (TREE_TYPE (TREE_OPERAND (expr, 0)));
2841 if (TYPE_QUALS (type) != type_quals)
2842 type = build_qualified_type (TYPE_MAIN_VARIANT (type), type_quals);
2844 /* Set the type of the COMPONENT_REF to the underlying type. */
2845 TREE_TYPE (expr) = type;
2847 #ifdef ENABLE_TYPES_CHECKING
2848 /* It is now a FE error, if the conversion from the canonical
2849 type to the original expression type is not useless. */
2850 gcc_assert (useless_type_conversion_p (old_type, type));
2851 #endif
2855 /* If a NOP conversion is changing a pointer to array of foo to a pointer
2856 to foo, embed that change in the ADDR_EXPR by converting
2857 T array[U];
2858 (T *)&array
2860 &array[L]
2861 where L is the lower bound. For simplicity, only do this for constant
2862 lower bound.
2863 The constraint is that the type of &array[L] is trivially convertible
2864 to T *. */
2866 static void
2867 canonicalize_addr_expr (tree *expr_p)
2869 tree expr = *expr_p;
2870 tree addr_expr = TREE_OPERAND (expr, 0);
2871 tree datype, ddatype, pddatype;
2873 /* We simplify only conversions from an ADDR_EXPR to a pointer type. */
2874 if (!POINTER_TYPE_P (TREE_TYPE (expr))
2875 || TREE_CODE (addr_expr) != ADDR_EXPR)
2876 return;
2878 /* The addr_expr type should be a pointer to an array. */
2879 datype = TREE_TYPE (TREE_TYPE (addr_expr));
2880 if (TREE_CODE (datype) != ARRAY_TYPE)
2881 return;
2883 /* The pointer to element type shall be trivially convertible to
2884 the expression pointer type. */
2885 ddatype = TREE_TYPE (datype);
2886 pddatype = build_pointer_type (ddatype);
2887 if (!useless_type_conversion_p (TYPE_MAIN_VARIANT (TREE_TYPE (expr)),
2888 pddatype))
2889 return;
2891 /* The lower bound and element sizes must be constant. */
2892 if (!TYPE_SIZE_UNIT (ddatype)
2893 || TREE_CODE (TYPE_SIZE_UNIT (ddatype)) != INTEGER_CST
2894 || !TYPE_DOMAIN (datype) || !TYPE_MIN_VALUE (TYPE_DOMAIN (datype))
2895 || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (datype))) != INTEGER_CST)
2896 return;
2898 /* All checks succeeded. Build a new node to merge the cast. */
2899 *expr_p = build4 (ARRAY_REF, ddatype, TREE_OPERAND (addr_expr, 0),
2900 TYPE_MIN_VALUE (TYPE_DOMAIN (datype)),
2901 NULL_TREE, NULL_TREE);
2902 *expr_p = build1 (ADDR_EXPR, pddatype, *expr_p);
2904 /* We can have stripped a required restrict qualifier above. */
2905 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
2906 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
2909 /* *EXPR_P is a NOP_EXPR or CONVERT_EXPR. Remove it and/or other conversions
2910 underneath as appropriate. */
2912 static enum gimplify_status
2913 gimplify_conversion (tree *expr_p)
2915 location_t loc = EXPR_LOCATION (*expr_p);
2916 gcc_assert (CONVERT_EXPR_P (*expr_p));
2918 /* Then strip away all but the outermost conversion. */
2919 STRIP_SIGN_NOPS (TREE_OPERAND (*expr_p, 0));
2921 /* And remove the outermost conversion if it's useless. */
2922 if (tree_ssa_useless_type_conversion (*expr_p))
2923 *expr_p = TREE_OPERAND (*expr_p, 0);
2925 /* If we still have a conversion at the toplevel,
2926 then canonicalize some constructs. */
2927 if (CONVERT_EXPR_P (*expr_p))
2929 tree sub = TREE_OPERAND (*expr_p, 0);
2931 /* If a NOP conversion is changing the type of a COMPONENT_REF
2932 expression, then canonicalize its type now in order to expose more
2933 redundant conversions. */
2934 if (TREE_CODE (sub) == COMPONENT_REF)
2935 canonicalize_component_ref (&TREE_OPERAND (*expr_p, 0));
2937 /* If a NOP conversion is changing a pointer to array of foo
2938 to a pointer to foo, embed that change in the ADDR_EXPR. */
2939 else if (TREE_CODE (sub) == ADDR_EXPR)
2940 canonicalize_addr_expr (expr_p);
2943 /* If we have a conversion to a non-register type force the
2944 use of a VIEW_CONVERT_EXPR instead. */
2945 if (CONVERT_EXPR_P (*expr_p) && !is_gimple_reg_type (TREE_TYPE (*expr_p)))
2946 *expr_p = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (*expr_p),
2947 TREE_OPERAND (*expr_p, 0));
2949 /* Canonicalize CONVERT_EXPR to NOP_EXPR. */
2950 if (TREE_CODE (*expr_p) == CONVERT_EXPR)
2951 TREE_SET_CODE (*expr_p, NOP_EXPR);
2953 return GS_OK;
2956 /* Gimplify a VAR_DECL or PARM_DECL. Return GS_OK if we expanded a
2957 DECL_VALUE_EXPR, and it's worth re-examining things. */
2959 static enum gimplify_status
2960 gimplify_var_or_parm_decl (tree *expr_p)
2962 tree decl = *expr_p;
2964 /* ??? If this is a local variable, and it has not been seen in any
2965 outer BIND_EXPR, then it's probably the result of a duplicate
2966 declaration, for which we've already issued an error. It would
2967 be really nice if the front end wouldn't leak these at all.
2968 Currently the only known culprit is C++ destructors, as seen
2969 in g++.old-deja/g++.jason/binding.C.
2970 Another possible culpit are size expressions for variably modified
2971 types which are lost in the FE or not gimplified correctly. */
2972 if (VAR_P (decl)
2973 && !DECL_SEEN_IN_BIND_EXPR_P (decl)
2974 && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl)
2975 && decl_function_context (decl) == current_function_decl)
2977 gcc_assert (seen_error ());
2978 return GS_ERROR;
2981 /* When within an OMP context, notice uses of variables. */
2982 if (gimplify_omp_ctxp && omp_notice_variable (gimplify_omp_ctxp, decl, true))
2983 return GS_ALL_DONE;
2985 /* If the decl is an alias for another expression, substitute it now. */
2986 if (DECL_HAS_VALUE_EXPR_P (decl))
2988 *expr_p = unshare_expr (DECL_VALUE_EXPR (decl));
2989 return GS_OK;
2992 return GS_ALL_DONE;
2995 /* Recalculate the value of the TREE_SIDE_EFFECTS flag for T. */
2997 static void
2998 recalculate_side_effects (tree t)
3000 enum tree_code code = TREE_CODE (t);
3001 int len = TREE_OPERAND_LENGTH (t);
3002 int i;
3004 switch (TREE_CODE_CLASS (code))
3006 case tcc_expression:
3007 switch (code)
3009 case INIT_EXPR:
3010 case MODIFY_EXPR:
3011 case VA_ARG_EXPR:
3012 case PREDECREMENT_EXPR:
3013 case PREINCREMENT_EXPR:
3014 case POSTDECREMENT_EXPR:
3015 case POSTINCREMENT_EXPR:
3016 /* All of these have side-effects, no matter what their
3017 operands are. */
3018 return;
3020 default:
3021 break;
3023 /* Fall through. */
3025 case tcc_comparison: /* a comparison expression */
3026 case tcc_unary: /* a unary arithmetic expression */
3027 case tcc_binary: /* a binary arithmetic expression */
3028 case tcc_reference: /* a reference */
3029 case tcc_vl_exp: /* a function call */
3030 TREE_SIDE_EFFECTS (t) = TREE_THIS_VOLATILE (t);
3031 for (i = 0; i < len; ++i)
3033 tree op = TREE_OPERAND (t, i);
3034 if (op && TREE_SIDE_EFFECTS (op))
3035 TREE_SIDE_EFFECTS (t) = 1;
3037 break;
3039 case tcc_constant:
3040 /* No side-effects. */
3041 return;
3043 default:
3044 gcc_unreachable ();
3048 /* Gimplify the COMPONENT_REF, ARRAY_REF, REALPART_EXPR or IMAGPART_EXPR
3049 node *EXPR_P.
3051 compound_lval
3052 : min_lval '[' val ']'
3053 | min_lval '.' ID
3054 | compound_lval '[' val ']'
3055 | compound_lval '.' ID
3057 This is not part of the original SIMPLE definition, which separates
3058 array and member references, but it seems reasonable to handle them
3059 together. Also, this way we don't run into problems with union
3060 aliasing; gcc requires that for accesses through a union to alias, the
3061 union reference must be explicit, which was not always the case when we
3062 were splitting up array and member refs.
3064 PRE_P points to the sequence where side effects that must happen before
3065 *EXPR_P should be stored.
3067 POST_P points to the sequence where side effects that must happen after
3068 *EXPR_P should be stored. */
3070 static enum gimplify_status
3071 gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
3072 fallback_t fallback)
3074 tree *p;
3075 enum gimplify_status ret = GS_ALL_DONE, tret;
3076 int i;
3077 location_t loc = EXPR_LOCATION (*expr_p);
3078 tree expr = *expr_p;
3080 /* Create a stack of the subexpressions so later we can walk them in
3081 order from inner to outer. */
3082 auto_vec<tree, 10> expr_stack;
3084 /* We can handle anything that get_inner_reference can deal with. */
3085 for (p = expr_p; ; p = &TREE_OPERAND (*p, 0))
3087 restart:
3088 /* Fold INDIRECT_REFs now to turn them into ARRAY_REFs. */
3089 if (TREE_CODE (*p) == INDIRECT_REF)
3090 *p = fold_indirect_ref_loc (loc, *p);
3092 if (handled_component_p (*p))
3094 /* Expand DECL_VALUE_EXPR now. In some cases that may expose
3095 additional COMPONENT_REFs. */
3096 else if ((VAR_P (*p) || TREE_CODE (*p) == PARM_DECL)
3097 && gimplify_var_or_parm_decl (p) == GS_OK)
3098 goto restart;
3099 else
3100 break;
3102 expr_stack.safe_push (*p);
3105 gcc_assert (expr_stack.length ());
3107 /* Now EXPR_STACK is a stack of pointers to all the refs we've
3108 walked through and P points to the innermost expression.
3110 Java requires that we elaborated nodes in source order. That
3111 means we must gimplify the inner expression followed by each of
3112 the indices, in order. But we can't gimplify the inner
3113 expression until we deal with any variable bounds, sizes, or
3114 positions in order to deal with PLACEHOLDER_EXPRs.
3116 The base expression may contain a statement expression that
3117 has declarations used in size expressions, so has to be
3118 gimplified before gimplifying the size expressions.
3120 So we do this in three steps. First we deal with variable
3121 bounds, sizes, and positions, then we gimplify the base,
3122 then we deal with the annotations for any variables in the
3123 components and any indices, from left to right. */
3125 for (i = expr_stack.length () - 1; i >= 0; i--)
3127 tree t = expr_stack[i];
3129 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
3131 /* Deal with the low bound and element type size and put them into
3132 the ARRAY_REF. If these values are set, they have already been
3133 gimplified. */
3134 if (TREE_OPERAND (t, 2) == NULL_TREE)
3136 tree low = unshare_expr (array_ref_low_bound (t));
3137 if (!is_gimple_min_invariant (low))
3139 TREE_OPERAND (t, 2) = low;
3143 if (TREE_OPERAND (t, 3) == NULL_TREE)
3145 tree elmt_size = array_ref_element_size (t);
3146 if (!is_gimple_min_invariant (elmt_size))
3148 elmt_size = unshare_expr (elmt_size);
3149 tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0)));
3150 tree factor = size_int (TYPE_ALIGN_UNIT (elmt_type));
3152 /* Divide the element size by the alignment of the element
3153 type (above). */
3154 elmt_size = size_binop_loc (loc, EXACT_DIV_EXPR,
3155 elmt_size, factor);
3157 TREE_OPERAND (t, 3) = elmt_size;
3161 else if (TREE_CODE (t) == COMPONENT_REF)
3163 /* Set the field offset into T and gimplify it. */
3164 if (TREE_OPERAND (t, 2) == NULL_TREE)
3166 tree offset = component_ref_field_offset (t);
3167 if (!is_gimple_min_invariant (offset))
3169 offset = unshare_expr (offset);
3170 tree field = TREE_OPERAND (t, 1);
3171 tree factor
3172 = size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT);
3174 /* Divide the offset by its alignment. */
3175 offset = size_binop_loc (loc, EXACT_DIV_EXPR,
3176 offset, factor);
3178 TREE_OPERAND (t, 2) = offset;
3184 /* Step 2 is to gimplify the base expression. Make sure lvalue is set
3185 so as to match the min_lval predicate. Failure to do so may result
3186 in the creation of large aggregate temporaries. */
3187 tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval,
3188 fallback | fb_lvalue);
3189 ret = MIN (ret, tret);
3191 /* Step 3: gimplify size expressions and the indices and operands of
3192 ARRAY_REF. During this loop we also remove any useless conversions. */
3194 for (; expr_stack.length () > 0; )
3196 tree t = expr_stack.pop ();
3198 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
3200 /* Gimplify the low bound and element type size. */
3201 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
3202 is_gimple_reg, fb_rvalue);
3203 ret = MIN (ret, tret);
3205 tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p, post_p,
3206 is_gimple_reg, fb_rvalue);
3207 ret = MIN (ret, tret);
3209 /* Gimplify the dimension. */
3210 tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
3211 is_gimple_val, fb_rvalue);
3212 ret = MIN (ret, tret);
3214 else if (TREE_CODE (t) == COMPONENT_REF)
3216 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
3217 is_gimple_reg, fb_rvalue);
3218 ret = MIN (ret, tret);
3221 STRIP_USELESS_TYPE_CONVERSION (TREE_OPERAND (t, 0));
3223 /* The innermost expression P may have originally had
3224 TREE_SIDE_EFFECTS set which would have caused all the outer
3225 expressions in *EXPR_P leading to P to also have had
3226 TREE_SIDE_EFFECTS set. */
3227 recalculate_side_effects (t);
3230 /* If the outermost expression is a COMPONENT_REF, canonicalize its type. */
3231 if ((fallback & fb_rvalue) && TREE_CODE (*expr_p) == COMPONENT_REF)
3233 canonicalize_component_ref (expr_p);
3236 expr_stack.release ();
3238 gcc_assert (*expr_p == expr || ret != GS_ALL_DONE);
3240 return ret;
3243 /* Gimplify the self modifying expression pointed to by EXPR_P
3244 (++, --, +=, -=).
3246 PRE_P points to the list where side effects that must happen before
3247 *EXPR_P should be stored.
3249 POST_P points to the list where side effects that must happen after
3250 *EXPR_P should be stored.
3252 WANT_VALUE is nonzero iff we want to use the value of this expression
3253 in another expression.
3255 ARITH_TYPE is the type the computation should be performed in. */
3257 enum gimplify_status
3258 gimplify_self_mod_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
3259 bool want_value, tree arith_type)
3261 enum tree_code code;
3262 tree lhs, lvalue, rhs, t1;
3263 gimple_seq post = NULL, *orig_post_p = post_p;
3264 bool postfix;
3265 enum tree_code arith_code;
3266 enum gimplify_status ret;
3267 location_t loc = EXPR_LOCATION (*expr_p);
3269 code = TREE_CODE (*expr_p);
3271 gcc_assert (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR
3272 || code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR);
3274 /* Prefix or postfix? */
3275 if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
3276 /* Faster to treat as prefix if result is not used. */
3277 postfix = want_value;
3278 else
3279 postfix = false;
3281 /* For postfix, make sure the inner expression's post side effects
3282 are executed after side effects from this expression. */
3283 if (postfix)
3284 post_p = &post;
3286 /* Add or subtract? */
3287 if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
3288 arith_code = PLUS_EXPR;
3289 else
3290 arith_code = MINUS_EXPR;
3292 /* Gimplify the LHS into a GIMPLE lvalue. */
3293 lvalue = TREE_OPERAND (*expr_p, 0);
3294 ret = gimplify_expr (&lvalue, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
3295 if (ret == GS_ERROR)
3296 return ret;
3298 /* Extract the operands to the arithmetic operation. */
3299 lhs = lvalue;
3300 rhs = TREE_OPERAND (*expr_p, 1);
3302 /* For postfix operator, we evaluate the LHS to an rvalue and then use
3303 that as the result value and in the postqueue operation. */
3304 if (postfix)
3306 ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue);
3307 if (ret == GS_ERROR)
3308 return ret;
3310 lhs = get_initialized_tmp_var (lhs, pre_p);
3313 /* For POINTERs increment, use POINTER_PLUS_EXPR. */
3314 if (POINTER_TYPE_P (TREE_TYPE (lhs)))
3316 rhs = convert_to_ptrofftype_loc (loc, rhs);
3317 if (arith_code == MINUS_EXPR)
3318 rhs = fold_build1_loc (loc, NEGATE_EXPR, TREE_TYPE (rhs), rhs);
3319 t1 = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (*expr_p), lhs, rhs);
3321 else
3322 t1 = fold_convert (TREE_TYPE (*expr_p),
3323 fold_build2 (arith_code, arith_type,
3324 fold_convert (arith_type, lhs),
3325 fold_convert (arith_type, rhs)));
3327 if (postfix)
3329 gimplify_assign (lvalue, t1, pre_p);
3330 gimplify_seq_add_seq (orig_post_p, post);
3331 *expr_p = lhs;
3332 return GS_ALL_DONE;
3334 else
3336 *expr_p = build2 (MODIFY_EXPR, TREE_TYPE (lvalue), lvalue, t1);
3337 return GS_OK;
3341 /* If *EXPR_P has a variable sized type, wrap it in a WITH_SIZE_EXPR. */
3343 static void
3344 maybe_with_size_expr (tree *expr_p)
3346 tree expr = *expr_p;
3347 tree type = TREE_TYPE (expr);
3348 tree size;
3350 /* If we've already wrapped this or the type is error_mark_node, we can't do
3351 anything. */
3352 if (TREE_CODE (expr) == WITH_SIZE_EXPR
3353 || type == error_mark_node)
3354 return;
3356 /* If the size isn't known or is a constant, we have nothing to do. */
3357 size = TYPE_SIZE_UNIT (type);
3358 if (!size || poly_int_tree_p (size))
3359 return;
3361 /* Otherwise, make a WITH_SIZE_EXPR. */
3362 size = unshare_expr (size);
3363 size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, expr);
3364 *expr_p = build2 (WITH_SIZE_EXPR, type, expr, size);
3367 /* Helper for gimplify_call_expr. Gimplify a single argument *ARG_P
3368 Store any side-effects in PRE_P. CALL_LOCATION is the location of
3369 the CALL_EXPR. If ALLOW_SSA is set the actual parameter may be
3370 gimplified to an SSA name. */
3372 enum gimplify_status
3373 gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location,
3374 bool allow_ssa)
3376 bool (*test) (tree);
3377 fallback_t fb;
3379 /* In general, we allow lvalues for function arguments to avoid
3380 extra overhead of copying large aggregates out of even larger
3381 aggregates into temporaries only to copy the temporaries to
3382 the argument list. Make optimizers happy by pulling out to
3383 temporaries those types that fit in registers. */
3384 if (is_gimple_reg_type (TREE_TYPE (*arg_p)))
3385 test = is_gimple_val, fb = fb_rvalue;
3386 else
3388 test = is_gimple_lvalue, fb = fb_either;
3389 /* Also strip a TARGET_EXPR that would force an extra copy. */
3390 if (TREE_CODE (*arg_p) == TARGET_EXPR)
3392 tree init = TARGET_EXPR_INITIAL (*arg_p);
3393 if (init
3394 && !VOID_TYPE_P (TREE_TYPE (init)))
3395 *arg_p = init;
3399 /* If this is a variable sized type, we must remember the size. */
3400 maybe_with_size_expr (arg_p);
3402 /* FIXME diagnostics: This will mess up gcc.dg/Warray-bounds.c. */
3403 /* Make sure arguments have the same location as the function call
3404 itself. */
3405 protected_set_expr_location (*arg_p, call_location);
3407 /* There is a sequence point before a function call. Side effects in
3408 the argument list must occur before the actual call. So, when
3409 gimplifying arguments, force gimplify_expr to use an internal
3410 post queue which is then appended to the end of PRE_P. */
3411 return gimplify_expr (arg_p, pre_p, NULL, test, fb, allow_ssa);
3414 /* Don't fold inside offloading or taskreg regions: it can break code by
3415 adding decl references that weren't in the source. We'll do it during
3416 omplower pass instead. */
3418 static bool
3419 maybe_fold_stmt (gimple_stmt_iterator *gsi)
3421 struct gimplify_omp_ctx *ctx;
3422 for (ctx = gimplify_omp_ctxp; ctx; ctx = ctx->outer_context)
3423 if ((ctx->region_type & (ORT_TARGET | ORT_PARALLEL | ORT_TASK)) != 0)
3424 return false;
3425 else if ((ctx->region_type & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
3426 return false;
3427 /* Delay folding of builtins until the IL is in consistent state
3428 so the diagnostic machinery can do a better job. */
3429 if (gimple_call_builtin_p (gsi_stmt (*gsi)))
3430 return false;
3431 return fold_stmt (gsi);
3434 /* Gimplify the CALL_EXPR node *EXPR_P into the GIMPLE sequence PRE_P.
3435 WANT_VALUE is true if the result of the call is desired. */
3437 static enum gimplify_status
3438 gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
3440 tree fndecl, parms, p, fnptrtype;
3441 enum gimplify_status ret;
3442 int i, nargs;
3443 gcall *call;
3444 bool builtin_va_start_p = false;
3445 location_t loc = EXPR_LOCATION (*expr_p);
3447 gcc_assert (TREE_CODE (*expr_p) == CALL_EXPR);
3449 /* For reliable diagnostics during inlining, it is necessary that
3450 every call_expr be annotated with file and line. */
3451 if (! EXPR_HAS_LOCATION (*expr_p))
3452 SET_EXPR_LOCATION (*expr_p, input_location);
3454 /* Gimplify internal functions created in the FEs. */
3455 if (CALL_EXPR_FN (*expr_p) == NULL_TREE)
3457 if (want_value)
3458 return GS_ALL_DONE;
3460 nargs = call_expr_nargs (*expr_p);
3461 enum internal_fn ifn = CALL_EXPR_IFN (*expr_p);
3462 auto_vec<tree> vargs (nargs);
3464 for (i = 0; i < nargs; i++)
3466 gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
3467 EXPR_LOCATION (*expr_p));
3468 vargs.quick_push (CALL_EXPR_ARG (*expr_p, i));
3471 gcall *call = gimple_build_call_internal_vec (ifn, vargs);
3472 gimple_call_set_nothrow (call, TREE_NOTHROW (*expr_p));
3473 gimplify_seq_add_stmt (pre_p, call);
3474 return GS_ALL_DONE;
3477 /* This may be a call to a builtin function.
3479 Builtin function calls may be transformed into different
3480 (and more efficient) builtin function calls under certain
3481 circumstances. Unfortunately, gimplification can muck things
3482 up enough that the builtin expanders are not aware that certain
3483 transformations are still valid.
3485 So we attempt transformation/gimplification of the call before
3486 we gimplify the CALL_EXPR. At this time we do not manage to
3487 transform all calls in the same manner as the expanders do, but
3488 we do transform most of them. */
3489 fndecl = get_callee_fndecl (*expr_p);
3490 if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
3491 switch (DECL_FUNCTION_CODE (fndecl))
3493 CASE_BUILT_IN_ALLOCA:
3494 /* If the call has been built for a variable-sized object, then we
3495 want to restore the stack level when the enclosing BIND_EXPR is
3496 exited to reclaim the allocated space; otherwise, we precisely
3497 need to do the opposite and preserve the latest stack level. */
3498 if (CALL_ALLOCA_FOR_VAR_P (*expr_p))
3499 gimplify_ctxp->save_stack = true;
3500 else
3501 gimplify_ctxp->keep_stack = true;
3502 break;
3504 case BUILT_IN_VA_START:
3506 builtin_va_start_p = TRUE;
3507 if (call_expr_nargs (*expr_p) < 2)
3509 error ("too few arguments to function %<va_start%>");
3510 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
3511 return GS_OK;
3514 if (fold_builtin_next_arg (*expr_p, true))
3516 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
3517 return GS_OK;
3519 break;
3522 case BUILT_IN_EH_RETURN:
3523 cfun->calls_eh_return = true;
3524 break;
3526 case BUILT_IN_CLEAR_PADDING:
3527 if (call_expr_nargs (*expr_p) == 1)
3529 /* Remember the original type of the argument in an internal
3530 dummy second argument, as in GIMPLE pointer conversions are
3531 useless. also mark this call as not for automatic initialization
3532 in the internal dummy third argument. */
3533 p = CALL_EXPR_ARG (*expr_p, 0);
3534 bool for_auto_init = false;
3535 *expr_p
3536 = build_call_expr_loc (EXPR_LOCATION (*expr_p), fndecl, 3, p,
3537 build_zero_cst (TREE_TYPE (p)),
3538 build_int_cst (integer_type_node,
3539 (int) for_auto_init));
3540 return GS_OK;
3542 break;
3544 default:
3547 if (fndecl && fndecl_built_in_p (fndecl))
3549 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
3550 if (new_tree && new_tree != *expr_p)
3552 /* There was a transformation of this call which computes the
3553 same value, but in a more efficient way. Return and try
3554 again. */
3555 *expr_p = new_tree;
3556 return GS_OK;
3560 /* Remember the original function pointer type. */
3561 fnptrtype = TREE_TYPE (CALL_EXPR_FN (*expr_p));
3563 if (flag_openmp
3564 && fndecl
3565 && cfun
3566 && (cfun->curr_properties & PROP_gimple_any) == 0)
3568 tree variant = omp_resolve_declare_variant (fndecl);
3569 if (variant != fndecl)
3570 CALL_EXPR_FN (*expr_p) = build1 (ADDR_EXPR, fnptrtype, variant);
3573 /* There is a sequence point before the call, so any side effects in
3574 the calling expression must occur before the actual call. Force
3575 gimplify_expr to use an internal post queue. */
3576 ret = gimplify_expr (&CALL_EXPR_FN (*expr_p), pre_p, NULL,
3577 is_gimple_call_addr, fb_rvalue);
3579 nargs = call_expr_nargs (*expr_p);
3581 /* Get argument types for verification. */
3582 fndecl = get_callee_fndecl (*expr_p);
3583 parms = NULL_TREE;
3584 if (fndecl)
3585 parms = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
3586 else
3587 parms = TYPE_ARG_TYPES (TREE_TYPE (fnptrtype));
3589 if (fndecl && DECL_ARGUMENTS (fndecl))
3590 p = DECL_ARGUMENTS (fndecl);
3591 else if (parms)
3592 p = parms;
3593 else
3594 p = NULL_TREE;
3595 for (i = 0; i < nargs && p; i++, p = TREE_CHAIN (p))
3598 /* If the last argument is __builtin_va_arg_pack () and it is not
3599 passed as a named argument, decrease the number of CALL_EXPR
3600 arguments and set instead the CALL_EXPR_VA_ARG_PACK flag. */
3601 if (!p
3602 && i < nargs
3603 && TREE_CODE (CALL_EXPR_ARG (*expr_p, nargs - 1)) == CALL_EXPR)
3605 tree last_arg = CALL_EXPR_ARG (*expr_p, nargs - 1);
3606 tree last_arg_fndecl = get_callee_fndecl (last_arg);
3608 if (last_arg_fndecl
3609 && fndecl_built_in_p (last_arg_fndecl, BUILT_IN_VA_ARG_PACK))
3611 tree call = *expr_p;
3613 --nargs;
3614 *expr_p = build_call_array_loc (loc, TREE_TYPE (call),
3615 CALL_EXPR_FN (call),
3616 nargs, CALL_EXPR_ARGP (call));
3618 /* Copy all CALL_EXPR flags, location and block, except
3619 CALL_EXPR_VA_ARG_PACK flag. */
3620 CALL_EXPR_STATIC_CHAIN (*expr_p) = CALL_EXPR_STATIC_CHAIN (call);
3621 CALL_EXPR_TAILCALL (*expr_p) = CALL_EXPR_TAILCALL (call);
3622 CALL_EXPR_RETURN_SLOT_OPT (*expr_p)
3623 = CALL_EXPR_RETURN_SLOT_OPT (call);
3624 CALL_FROM_THUNK_P (*expr_p) = CALL_FROM_THUNK_P (call);
3625 SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (call));
3627 /* Set CALL_EXPR_VA_ARG_PACK. */
3628 CALL_EXPR_VA_ARG_PACK (*expr_p) = 1;
3632 /* If the call returns twice then after building the CFG the call
3633 argument computations will no longer dominate the call because
3634 we add an abnormal incoming edge to the call. So do not use SSA
3635 vars there. */
3636 bool returns_twice = call_expr_flags (*expr_p) & ECF_RETURNS_TWICE;
3638 /* Gimplify the function arguments. */
3639 if (nargs > 0)
3641 for (i = (PUSH_ARGS_REVERSED ? nargs - 1 : 0);
3642 PUSH_ARGS_REVERSED ? i >= 0 : i < nargs;
3643 PUSH_ARGS_REVERSED ? i-- : i++)
3645 enum gimplify_status t;
3647 /* Avoid gimplifying the second argument to va_start, which needs to
3648 be the plain PARM_DECL. */
3649 if ((i != 1) || !builtin_va_start_p)
3651 t = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
3652 EXPR_LOCATION (*expr_p), ! returns_twice);
3654 if (t == GS_ERROR)
3655 ret = GS_ERROR;
3660 /* Gimplify the static chain. */
3661 if (CALL_EXPR_STATIC_CHAIN (*expr_p))
3663 if (fndecl && !DECL_STATIC_CHAIN (fndecl))
3664 CALL_EXPR_STATIC_CHAIN (*expr_p) = NULL;
3665 else
3667 enum gimplify_status t;
3668 t = gimplify_arg (&CALL_EXPR_STATIC_CHAIN (*expr_p), pre_p,
3669 EXPR_LOCATION (*expr_p), ! returns_twice);
3670 if (t == GS_ERROR)
3671 ret = GS_ERROR;
3675 /* Verify the function result. */
3676 if (want_value && fndecl
3677 && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fnptrtype))))
3679 error_at (loc, "using result of function returning %<void%>");
3680 ret = GS_ERROR;
3683 /* Try this again in case gimplification exposed something. */
3684 if (ret != GS_ERROR)
3686 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
3688 if (new_tree && new_tree != *expr_p)
3690 /* There was a transformation of this call which computes the
3691 same value, but in a more efficient way. Return and try
3692 again. */
3693 *expr_p = new_tree;
3694 return GS_OK;
3697 else
3699 *expr_p = error_mark_node;
3700 return GS_ERROR;
3703 /* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its
3704 decl. This allows us to eliminate redundant or useless
3705 calls to "const" functions. */
3706 if (TREE_CODE (*expr_p) == CALL_EXPR)
3708 int flags = call_expr_flags (*expr_p);
3709 if (flags & (ECF_CONST | ECF_PURE)
3710 /* An infinite loop is considered a side effect. */
3711 && !(flags & (ECF_LOOPING_CONST_OR_PURE)))
3712 TREE_SIDE_EFFECTS (*expr_p) = 0;
3715 /* If the value is not needed by the caller, emit a new GIMPLE_CALL
3716 and clear *EXPR_P. Otherwise, leave *EXPR_P in its gimplified
3717 form and delegate the creation of a GIMPLE_CALL to
3718 gimplify_modify_expr. This is always possible because when
3719 WANT_VALUE is true, the caller wants the result of this call into
3720 a temporary, which means that we will emit an INIT_EXPR in
3721 internal_get_tmp_var which will then be handled by
3722 gimplify_modify_expr. */
3723 if (!want_value)
3725 /* The CALL_EXPR in *EXPR_P is already in GIMPLE form, so all we
3726 have to do is replicate it as a GIMPLE_CALL tuple. */
3727 gimple_stmt_iterator gsi;
3728 call = gimple_build_call_from_tree (*expr_p, fnptrtype);
3729 notice_special_calls (call);
3730 gimplify_seq_add_stmt (pre_p, call);
3731 gsi = gsi_last (*pre_p);
3732 maybe_fold_stmt (&gsi);
3733 *expr_p = NULL_TREE;
3735 else
3736 /* Remember the original function type. */
3737 CALL_EXPR_FN (*expr_p) = build1 (NOP_EXPR, fnptrtype,
3738 CALL_EXPR_FN (*expr_p));
3740 return ret;
3743 /* Handle shortcut semantics in the predicate operand of a COND_EXPR by
3744 rewriting it into multiple COND_EXPRs, and possibly GOTO_EXPRs.
3746 TRUE_LABEL_P and FALSE_LABEL_P point to the labels to jump to if the
3747 condition is true or false, respectively. If null, we should generate
3748 our own to skip over the evaluation of this specific expression.
3750 LOCUS is the source location of the COND_EXPR.
3752 This function is the tree equivalent of do_jump.
3754 shortcut_cond_r should only be called by shortcut_cond_expr. */
3756 static tree
3757 shortcut_cond_r (tree pred, tree *true_label_p, tree *false_label_p,
3758 location_t locus)
3760 tree local_label = NULL_TREE;
3761 tree t, expr = NULL;
3763 /* OK, it's not a simple case; we need to pull apart the COND_EXPR to
3764 retain the shortcut semantics. Just insert the gotos here;
3765 shortcut_cond_expr will append the real blocks later. */
3766 if (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
3768 location_t new_locus;
3770 /* Turn if (a && b) into
3772 if (a); else goto no;
3773 if (b) goto yes; else goto no;
3774 (no:) */
3776 if (false_label_p == NULL)
3777 false_label_p = &local_label;
3779 /* Keep the original source location on the first 'if'. */
3780 t = shortcut_cond_r (TREE_OPERAND (pred, 0), NULL, false_label_p, locus);
3781 append_to_statement_list (t, &expr);
3783 /* Set the source location of the && on the second 'if'. */
3784 new_locus = rexpr_location (pred, locus);
3785 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
3786 new_locus);
3787 append_to_statement_list (t, &expr);
3789 else if (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
3791 location_t new_locus;
3793 /* Turn if (a || b) into
3795 if (a) goto yes;
3796 if (b) goto yes; else goto no;
3797 (yes:) */
3799 if (true_label_p == NULL)
3800 true_label_p = &local_label;
3802 /* Keep the original source location on the first 'if'. */
3803 t = shortcut_cond_r (TREE_OPERAND (pred, 0), true_label_p, NULL, locus);
3804 append_to_statement_list (t, &expr);
3806 /* Set the source location of the || on the second 'if'. */
3807 new_locus = rexpr_location (pred, locus);
3808 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
3809 new_locus);
3810 append_to_statement_list (t, &expr);
3812 else if (TREE_CODE (pred) == COND_EXPR
3813 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 1)))
3814 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 2))))
3816 location_t new_locus;
3818 /* As long as we're messing with gotos, turn if (a ? b : c) into
3819 if (a)
3820 if (b) goto yes; else goto no;
3821 else
3822 if (c) goto yes; else goto no;
3824 Don't do this if one of the arms has void type, which can happen
3825 in C++ when the arm is throw. */
3827 /* Keep the original source location on the first 'if'. Set the source
3828 location of the ? on the second 'if'. */
3829 new_locus = rexpr_location (pred, locus);
3830 expr = build3 (COND_EXPR, void_type_node, TREE_OPERAND (pred, 0),
3831 shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p,
3832 false_label_p, locus),
3833 shortcut_cond_r (TREE_OPERAND (pred, 2), true_label_p,
3834 false_label_p, new_locus));
3836 else
3838 expr = build3 (COND_EXPR, void_type_node, pred,
3839 build_and_jump (true_label_p),
3840 build_and_jump (false_label_p));
3841 SET_EXPR_LOCATION (expr, locus);
3844 if (local_label)
3846 t = build1 (LABEL_EXPR, void_type_node, local_label);
3847 append_to_statement_list (t, &expr);
3850 return expr;
3853 /* If EXPR is a GOTO_EXPR, return it. If it is a STATEMENT_LIST, skip
3854 any of its leading DEBUG_BEGIN_STMTS and recurse on the subsequent
3855 statement, if it is the last one. Otherwise, return NULL. */
3857 static tree
3858 find_goto (tree expr)
3860 if (!expr)
3861 return NULL_TREE;
3863 if (TREE_CODE (expr) == GOTO_EXPR)
3864 return expr;
3866 if (TREE_CODE (expr) != STATEMENT_LIST)
3867 return NULL_TREE;
3869 tree_stmt_iterator i = tsi_start (expr);
3871 while (!tsi_end_p (i) && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT)
3872 tsi_next (&i);
3874 if (!tsi_one_before_end_p (i))
3875 return NULL_TREE;
3877 return find_goto (tsi_stmt (i));
3880 /* Same as find_goto, except that it returns NULL if the destination
3881 is not a LABEL_DECL. */
3883 static inline tree
3884 find_goto_label (tree expr)
3886 tree dest = find_goto (expr);
3887 if (dest && TREE_CODE (GOTO_DESTINATION (dest)) == LABEL_DECL)
3888 return dest;
3889 return NULL_TREE;
3892 /* Given a conditional expression EXPR with short-circuit boolean
3893 predicates using TRUTH_ANDIF_EXPR or TRUTH_ORIF_EXPR, break the
3894 predicate apart into the equivalent sequence of conditionals. */
3896 static tree
3897 shortcut_cond_expr (tree expr)
3899 tree pred = TREE_OPERAND (expr, 0);
3900 tree then_ = TREE_OPERAND (expr, 1);
3901 tree else_ = TREE_OPERAND (expr, 2);
3902 tree true_label, false_label, end_label, t;
3903 tree *true_label_p;
3904 tree *false_label_p;
3905 bool emit_end, emit_false, jump_over_else;
3906 bool then_se = then_ && TREE_SIDE_EFFECTS (then_);
3907 bool else_se = else_ && TREE_SIDE_EFFECTS (else_);
3909 /* First do simple transformations. */
3910 if (!else_se)
3912 /* If there is no 'else', turn
3913 if (a && b) then c
3914 into
3915 if (a) if (b) then c. */
3916 while (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
3918 /* Keep the original source location on the first 'if'. */
3919 location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
3920 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
3921 /* Set the source location of the && on the second 'if'. */
3922 if (rexpr_has_location (pred))
3923 SET_EXPR_LOCATION (expr, rexpr_location (pred));
3924 then_ = shortcut_cond_expr (expr);
3925 then_se = then_ && TREE_SIDE_EFFECTS (then_);
3926 pred = TREE_OPERAND (pred, 0);
3927 expr = build3 (COND_EXPR, void_type_node, pred, then_, NULL_TREE);
3928 SET_EXPR_LOCATION (expr, locus);
3932 if (!then_se)
3934 /* If there is no 'then', turn
3935 if (a || b); else d
3936 into
3937 if (a); else if (b); else d. */
3938 while (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
3940 /* Keep the original source location on the first 'if'. */
3941 location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
3942 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
3943 /* Set the source location of the || on the second 'if'. */
3944 if (rexpr_has_location (pred))
3945 SET_EXPR_LOCATION (expr, rexpr_location (pred));
3946 else_ = shortcut_cond_expr (expr);
3947 else_se = else_ && TREE_SIDE_EFFECTS (else_);
3948 pred = TREE_OPERAND (pred, 0);
3949 expr = build3 (COND_EXPR, void_type_node, pred, NULL_TREE, else_);
3950 SET_EXPR_LOCATION (expr, locus);
3954 /* If we're done, great. */
3955 if (TREE_CODE (pred) != TRUTH_ANDIF_EXPR
3956 && TREE_CODE (pred) != TRUTH_ORIF_EXPR)
3957 return expr;
3959 /* Otherwise we need to mess with gotos. Change
3960 if (a) c; else d;
3962 if (a); else goto no;
3963 c; goto end;
3964 no: d; end:
3965 and recursively gimplify the condition. */
3967 true_label = false_label = end_label = NULL_TREE;
3969 /* If our arms just jump somewhere, hijack those labels so we don't
3970 generate jumps to jumps. */
3972 if (tree then_goto = find_goto_label (then_))
3974 true_label = GOTO_DESTINATION (then_goto);
3975 then_ = NULL;
3976 then_se = false;
3979 if (tree else_goto = find_goto_label (else_))
3981 false_label = GOTO_DESTINATION (else_goto);
3982 else_ = NULL;
3983 else_se = false;
3986 /* If we aren't hijacking a label for the 'then' branch, it falls through. */
3987 if (true_label)
3988 true_label_p = &true_label;
3989 else
3990 true_label_p = NULL;
3992 /* The 'else' branch also needs a label if it contains interesting code. */
3993 if (false_label || else_se)
3994 false_label_p = &false_label;
3995 else
3996 false_label_p = NULL;
3998 /* If there was nothing else in our arms, just forward the label(s). */
3999 if (!then_se && !else_se)
4000 return shortcut_cond_r (pred, true_label_p, false_label_p,
4001 EXPR_LOC_OR_LOC (expr, input_location));
4003 /* If our last subexpression already has a terminal label, reuse it. */
4004 if (else_se)
4005 t = expr_last (else_);
4006 else if (then_se)
4007 t = expr_last (then_);
4008 else
4009 t = NULL;
4010 if (t && TREE_CODE (t) == LABEL_EXPR)
4011 end_label = LABEL_EXPR_LABEL (t);
4013 /* If we don't care about jumping to the 'else' branch, jump to the end
4014 if the condition is false. */
4015 if (!false_label_p)
4016 false_label_p = &end_label;
4018 /* We only want to emit these labels if we aren't hijacking them. */
4019 emit_end = (end_label == NULL_TREE);
4020 emit_false = (false_label == NULL_TREE);
4022 /* We only emit the jump over the else clause if we have to--if the
4023 then clause may fall through. Otherwise we can wind up with a
4024 useless jump and a useless label at the end of gimplified code,
4025 which will cause us to think that this conditional as a whole
4026 falls through even if it doesn't. If we then inline a function
4027 which ends with such a condition, that can cause us to issue an
4028 inappropriate warning about control reaching the end of a
4029 non-void function. */
4030 jump_over_else = block_may_fallthru (then_);
4032 pred = shortcut_cond_r (pred, true_label_p, false_label_p,
4033 EXPR_LOC_OR_LOC (expr, input_location));
4035 expr = NULL;
4036 append_to_statement_list (pred, &expr);
4038 append_to_statement_list (then_, &expr);
4039 if (else_se)
4041 if (jump_over_else)
4043 tree last = expr_last (expr);
4044 t = build_and_jump (&end_label);
4045 if (rexpr_has_location (last))
4046 SET_EXPR_LOCATION (t, rexpr_location (last));
4047 append_to_statement_list (t, &expr);
4049 if (emit_false)
4051 t = build1 (LABEL_EXPR, void_type_node, false_label);
4052 append_to_statement_list (t, &expr);
4054 append_to_statement_list (else_, &expr);
4056 if (emit_end && end_label)
4058 t = build1 (LABEL_EXPR, void_type_node, end_label);
4059 append_to_statement_list (t, &expr);
4062 return expr;
4065 /* EXPR is used in a boolean context; make sure it has BOOLEAN_TYPE. */
4067 tree
4068 gimple_boolify (tree expr)
4070 tree type = TREE_TYPE (expr);
4071 location_t loc = EXPR_LOCATION (expr);
4073 if (TREE_CODE (expr) == NE_EXPR
4074 && TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR
4075 && integer_zerop (TREE_OPERAND (expr, 1)))
4077 tree call = TREE_OPERAND (expr, 0);
4078 tree fn = get_callee_fndecl (call);
4080 /* For __builtin_expect ((long) (x), y) recurse into x as well
4081 if x is truth_value_p. */
4082 if (fn
4083 && fndecl_built_in_p (fn, BUILT_IN_EXPECT)
4084 && call_expr_nargs (call) == 2)
4086 tree arg = CALL_EXPR_ARG (call, 0);
4087 if (arg)
4089 if (TREE_CODE (arg) == NOP_EXPR
4090 && TREE_TYPE (arg) == TREE_TYPE (call))
4091 arg = TREE_OPERAND (arg, 0);
4092 if (truth_value_p (TREE_CODE (arg)))
4094 arg = gimple_boolify (arg);
4095 CALL_EXPR_ARG (call, 0)
4096 = fold_convert_loc (loc, TREE_TYPE (call), arg);
4102 switch (TREE_CODE (expr))
4104 case TRUTH_AND_EXPR:
4105 case TRUTH_OR_EXPR:
4106 case TRUTH_XOR_EXPR:
4107 case TRUTH_ANDIF_EXPR:
4108 case TRUTH_ORIF_EXPR:
4109 /* Also boolify the arguments of truth exprs. */
4110 TREE_OPERAND (expr, 1) = gimple_boolify (TREE_OPERAND (expr, 1));
4111 /* FALLTHRU */
4113 case TRUTH_NOT_EXPR:
4114 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
4116 /* These expressions always produce boolean results. */
4117 if (TREE_CODE (type) != BOOLEAN_TYPE)
4118 TREE_TYPE (expr) = boolean_type_node;
4119 return expr;
4121 case ANNOTATE_EXPR:
4122 switch ((enum annot_expr_kind) TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)))
4124 case annot_expr_ivdep_kind:
4125 case annot_expr_unroll_kind:
4126 case annot_expr_no_vector_kind:
4127 case annot_expr_vector_kind:
4128 case annot_expr_parallel_kind:
4129 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
4130 if (TREE_CODE (type) != BOOLEAN_TYPE)
4131 TREE_TYPE (expr) = boolean_type_node;
4132 return expr;
4133 default:
4134 gcc_unreachable ();
4137 default:
4138 if (COMPARISON_CLASS_P (expr))
4140 /* There expressions always prduce boolean results. */
4141 if (TREE_CODE (type) != BOOLEAN_TYPE)
4142 TREE_TYPE (expr) = boolean_type_node;
4143 return expr;
4145 /* Other expressions that get here must have boolean values, but
4146 might need to be converted to the appropriate mode. */
4147 if (TREE_CODE (type) == BOOLEAN_TYPE)
4148 return expr;
4149 return fold_convert_loc (loc, boolean_type_node, expr);
4153 /* Given a conditional expression *EXPR_P without side effects, gimplify
4154 its operands. New statements are inserted to PRE_P. */
4156 static enum gimplify_status
4157 gimplify_pure_cond_expr (tree *expr_p, gimple_seq *pre_p)
4159 tree expr = *expr_p, cond;
4160 enum gimplify_status ret, tret;
4161 enum tree_code code;
4163 cond = gimple_boolify (COND_EXPR_COND (expr));
4165 /* We need to handle && and || specially, as their gimplification
4166 creates pure cond_expr, thus leading to an infinite cycle otherwise. */
4167 code = TREE_CODE (cond);
4168 if (code == TRUTH_ANDIF_EXPR)
4169 TREE_SET_CODE (cond, TRUTH_AND_EXPR);
4170 else if (code == TRUTH_ORIF_EXPR)
4171 TREE_SET_CODE (cond, TRUTH_OR_EXPR);
4172 ret = gimplify_expr (&cond, pre_p, NULL, is_gimple_condexpr, fb_rvalue);
4173 COND_EXPR_COND (*expr_p) = cond;
4175 tret = gimplify_expr (&COND_EXPR_THEN (expr), pre_p, NULL,
4176 is_gimple_val, fb_rvalue);
4177 ret = MIN (ret, tret);
4178 tret = gimplify_expr (&COND_EXPR_ELSE (expr), pre_p, NULL,
4179 is_gimple_val, fb_rvalue);
4181 return MIN (ret, tret);
4184 /* Return true if evaluating EXPR could trap.
4185 EXPR is GENERIC, while tree_could_trap_p can be called
4186 only on GIMPLE. */
4188 bool
4189 generic_expr_could_trap_p (tree expr)
4191 unsigned i, n;
4193 if (!expr || is_gimple_val (expr))
4194 return false;
4196 if (!EXPR_P (expr) || tree_could_trap_p (expr))
4197 return true;
4199 n = TREE_OPERAND_LENGTH (expr);
4200 for (i = 0; i < n; i++)
4201 if (generic_expr_could_trap_p (TREE_OPERAND (expr, i)))
4202 return true;
4204 return false;
4207 /* Convert the conditional expression pointed to by EXPR_P '(p) ? a : b;'
4208 into
4210 if (p) if (p)
4211 t1 = a; a;
4212 else or else
4213 t1 = b; b;
4216 The second form is used when *EXPR_P is of type void.
4218 PRE_P points to the list where side effects that must happen before
4219 *EXPR_P should be stored. */
4221 static enum gimplify_status
4222 gimplify_cond_expr (tree *expr_p, gimple_seq *pre_p, fallback_t fallback)
4224 tree expr = *expr_p;
4225 tree type = TREE_TYPE (expr);
4226 location_t loc = EXPR_LOCATION (expr);
4227 tree tmp, arm1, arm2;
4228 enum gimplify_status ret;
4229 tree label_true, label_false, label_cont;
4230 bool have_then_clause_p, have_else_clause_p;
4231 gcond *cond_stmt;
4232 enum tree_code pred_code;
4233 gimple_seq seq = NULL;
4235 /* If this COND_EXPR has a value, copy the values into a temporary within
4236 the arms. */
4237 if (!VOID_TYPE_P (type))
4239 tree then_ = TREE_OPERAND (expr, 1), else_ = TREE_OPERAND (expr, 2);
4240 tree result;
4242 /* If either an rvalue is ok or we do not require an lvalue, create the
4243 temporary. But we cannot do that if the type is addressable. */
4244 if (((fallback & fb_rvalue) || !(fallback & fb_lvalue))
4245 && !TREE_ADDRESSABLE (type))
4247 if (gimplify_ctxp->allow_rhs_cond_expr
4248 /* If either branch has side effects or could trap, it can't be
4249 evaluated unconditionally. */
4250 && !TREE_SIDE_EFFECTS (then_)
4251 && !generic_expr_could_trap_p (then_)
4252 && !TREE_SIDE_EFFECTS (else_)
4253 && !generic_expr_could_trap_p (else_))
4254 return gimplify_pure_cond_expr (expr_p, pre_p);
4256 tmp = create_tmp_var (type, "iftmp");
4257 result = tmp;
4260 /* Otherwise, only create and copy references to the values. */
4261 else
4263 type = build_pointer_type (type);
4265 if (!VOID_TYPE_P (TREE_TYPE (then_)))
4266 then_ = build_fold_addr_expr_loc (loc, then_);
4268 if (!VOID_TYPE_P (TREE_TYPE (else_)))
4269 else_ = build_fold_addr_expr_loc (loc, else_);
4271 expr
4272 = build3 (COND_EXPR, type, TREE_OPERAND (expr, 0), then_, else_);
4274 tmp = create_tmp_var (type, "iftmp");
4275 result = build_simple_mem_ref_loc (loc, tmp);
4278 /* Build the new then clause, `tmp = then_;'. But don't build the
4279 assignment if the value is void; in C++ it can be if it's a throw. */
4280 if (!VOID_TYPE_P (TREE_TYPE (then_)))
4281 TREE_OPERAND (expr, 1) = build2 (INIT_EXPR, type, tmp, then_);
4283 /* Similarly, build the new else clause, `tmp = else_;'. */
4284 if (!VOID_TYPE_P (TREE_TYPE (else_)))
4285 TREE_OPERAND (expr, 2) = build2 (INIT_EXPR, type, tmp, else_);
4287 TREE_TYPE (expr) = void_type_node;
4288 recalculate_side_effects (expr);
4290 /* Move the COND_EXPR to the prequeue. */
4291 gimplify_stmt (&expr, pre_p);
4293 *expr_p = result;
4294 return GS_ALL_DONE;
4297 /* Remove any COMPOUND_EXPR so the following cases will be caught. */
4298 STRIP_TYPE_NOPS (TREE_OPERAND (expr, 0));
4299 if (TREE_CODE (TREE_OPERAND (expr, 0)) == COMPOUND_EXPR)
4300 gimplify_compound_expr (&TREE_OPERAND (expr, 0), pre_p, true);
4302 /* Make sure the condition has BOOLEAN_TYPE. */
4303 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
4305 /* Break apart && and || conditions. */
4306 if (TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ANDIF_EXPR
4307 || TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ORIF_EXPR)
4309 expr = shortcut_cond_expr (expr);
4311 if (expr != *expr_p)
4313 *expr_p = expr;
4315 /* We can't rely on gimplify_expr to re-gimplify the expanded
4316 form properly, as cleanups might cause the target labels to be
4317 wrapped in a TRY_FINALLY_EXPR. To prevent that, we need to
4318 set up a conditional context. */
4319 gimple_push_condition ();
4320 gimplify_stmt (expr_p, &seq);
4321 gimple_pop_condition (pre_p);
4322 gimple_seq_add_seq (pre_p, seq);
4324 return GS_ALL_DONE;
4328 /* Now do the normal gimplification. */
4330 /* Gimplify condition. */
4331 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL,
4332 is_gimple_condexpr_for_cond, fb_rvalue);
4333 if (ret == GS_ERROR)
4334 return GS_ERROR;
4335 gcc_assert (TREE_OPERAND (expr, 0) != NULL_TREE);
4337 gimple_push_condition ();
4339 have_then_clause_p = have_else_clause_p = false;
4340 label_true = find_goto_label (TREE_OPERAND (expr, 1));
4341 if (label_true
4342 && DECL_CONTEXT (GOTO_DESTINATION (label_true)) == current_function_decl
4343 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4344 have different locations, otherwise we end up with incorrect
4345 location information on the branches. */
4346 && (optimize
4347 || !EXPR_HAS_LOCATION (expr)
4348 || !rexpr_has_location (label_true)
4349 || EXPR_LOCATION (expr) == rexpr_location (label_true)))
4351 have_then_clause_p = true;
4352 label_true = GOTO_DESTINATION (label_true);
4354 else
4355 label_true = create_artificial_label (UNKNOWN_LOCATION);
4356 label_false = find_goto_label (TREE_OPERAND (expr, 2));
4357 if (label_false
4358 && DECL_CONTEXT (GOTO_DESTINATION (label_false)) == current_function_decl
4359 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4360 have different locations, otherwise we end up with incorrect
4361 location information on the branches. */
4362 && (optimize
4363 || !EXPR_HAS_LOCATION (expr)
4364 || !rexpr_has_location (label_false)
4365 || EXPR_LOCATION (expr) == rexpr_location (label_false)))
4367 have_else_clause_p = true;
4368 label_false = GOTO_DESTINATION (label_false);
4370 else
4371 label_false = create_artificial_label (UNKNOWN_LOCATION);
4373 gimple_cond_get_ops_from_tree (COND_EXPR_COND (expr), &pred_code, &arm1,
4374 &arm2);
4375 cond_stmt = gimple_build_cond (pred_code, arm1, arm2, label_true,
4376 label_false);
4377 gimple_set_location (cond_stmt, EXPR_LOCATION (expr));
4378 copy_warning (cond_stmt, COND_EXPR_COND (expr));
4379 gimplify_seq_add_stmt (&seq, cond_stmt);
4380 gimple_stmt_iterator gsi = gsi_last (seq);
4381 maybe_fold_stmt (&gsi);
4383 label_cont = NULL_TREE;
4384 if (!have_then_clause_p)
4386 /* For if (...) {} else { code; } put label_true after
4387 the else block. */
4388 if (TREE_OPERAND (expr, 1) == NULL_TREE
4389 && !have_else_clause_p
4390 && TREE_OPERAND (expr, 2) != NULL_TREE)
4391 label_cont = label_true;
4392 else
4394 gimplify_seq_add_stmt (&seq, gimple_build_label (label_true));
4395 have_then_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 1), &seq);
4396 /* For if (...) { code; } else {} or
4397 if (...) { code; } else goto label; or
4398 if (...) { code; return; } else { ... }
4399 label_cont isn't needed. */
4400 if (!have_else_clause_p
4401 && TREE_OPERAND (expr, 2) != NULL_TREE
4402 && gimple_seq_may_fallthru (seq))
4404 gimple *g;
4405 label_cont = create_artificial_label (UNKNOWN_LOCATION);
4407 g = gimple_build_goto (label_cont);
4409 /* GIMPLE_COND's are very low level; they have embedded
4410 gotos. This particular embedded goto should not be marked
4411 with the location of the original COND_EXPR, as it would
4412 correspond to the COND_EXPR's condition, not the ELSE or the
4413 THEN arms. To avoid marking it with the wrong location, flag
4414 it as "no location". */
4415 gimple_set_do_not_emit_location (g);
4417 gimplify_seq_add_stmt (&seq, g);
4421 if (!have_else_clause_p)
4423 gimplify_seq_add_stmt (&seq, gimple_build_label (label_false));
4424 have_else_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 2), &seq);
4426 if (label_cont)
4427 gimplify_seq_add_stmt (&seq, gimple_build_label (label_cont));
4429 gimple_pop_condition (pre_p);
4430 gimple_seq_add_seq (pre_p, seq);
4432 if (ret == GS_ERROR)
4433 ; /* Do nothing. */
4434 else if (have_then_clause_p || have_else_clause_p)
4435 ret = GS_ALL_DONE;
4436 else
4438 /* Both arms are empty; replace the COND_EXPR with its predicate. */
4439 expr = TREE_OPERAND (expr, 0);
4440 gimplify_stmt (&expr, pre_p);
4443 *expr_p = NULL;
4444 return ret;
4447 /* Prepare the node pointed to by EXPR_P, an is_gimple_addressable expression,
4448 to be marked addressable.
4450 We cannot rely on such an expression being directly markable if a temporary
4451 has been created by the gimplification. In this case, we create another
4452 temporary and initialize it with a copy, which will become a store after we
4453 mark it addressable. This can happen if the front-end passed us something
4454 that it could not mark addressable yet, like a Fortran pass-by-reference
4455 parameter (int) floatvar. */
4457 static void
4458 prepare_gimple_addressable (tree *expr_p, gimple_seq *seq_p)
4460 while (handled_component_p (*expr_p))
4461 expr_p = &TREE_OPERAND (*expr_p, 0);
4462 if (is_gimple_reg (*expr_p))
4464 /* Do not allow an SSA name as the temporary. */
4465 tree var = get_initialized_tmp_var (*expr_p, seq_p, NULL, false);
4466 DECL_NOT_GIMPLE_REG_P (var) = 1;
4467 *expr_p = var;
4471 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4472 a call to __builtin_memcpy. */
4474 static enum gimplify_status
4475 gimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value,
4476 gimple_seq *seq_p)
4478 tree t, to, to_ptr, from, from_ptr;
4479 gcall *gs;
4480 location_t loc = EXPR_LOCATION (*expr_p);
4482 to = TREE_OPERAND (*expr_p, 0);
4483 from = TREE_OPERAND (*expr_p, 1);
4485 /* Mark the RHS addressable. Beware that it may not be possible to do so
4486 directly if a temporary has been created by the gimplification. */
4487 prepare_gimple_addressable (&from, seq_p);
4489 mark_addressable (from);
4490 from_ptr = build_fold_addr_expr_loc (loc, from);
4491 gimplify_arg (&from_ptr, seq_p, loc);
4493 mark_addressable (to);
4494 to_ptr = build_fold_addr_expr_loc (loc, to);
4495 gimplify_arg (&to_ptr, seq_p, loc);
4497 t = builtin_decl_implicit (BUILT_IN_MEMCPY);
4499 gs = gimple_build_call (t, 3, to_ptr, from_ptr, size);
4500 gimple_call_set_alloca_for_var (gs, true);
4502 if (want_value)
4504 /* tmp = memcpy() */
4505 t = create_tmp_var (TREE_TYPE (to_ptr));
4506 gimple_call_set_lhs (gs, t);
4507 gimplify_seq_add_stmt (seq_p, gs);
4509 *expr_p = build_simple_mem_ref (t);
4510 return GS_ALL_DONE;
4513 gimplify_seq_add_stmt (seq_p, gs);
4514 *expr_p = NULL;
4515 return GS_ALL_DONE;
4518 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4519 a call to __builtin_memset. In this case we know that the RHS is
4520 a CONSTRUCTOR with an empty element list. */
4522 static enum gimplify_status
4523 gimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value,
4524 gimple_seq *seq_p)
4526 tree t, from, to, to_ptr;
4527 gcall *gs;
4528 location_t loc = EXPR_LOCATION (*expr_p);
4530 /* Assert our assumptions, to abort instead of producing wrong code
4531 silently if they are not met. Beware that the RHS CONSTRUCTOR might
4532 not be immediately exposed. */
4533 from = TREE_OPERAND (*expr_p, 1);
4534 if (TREE_CODE (from) == WITH_SIZE_EXPR)
4535 from = TREE_OPERAND (from, 0);
4537 gcc_assert (TREE_CODE (from) == CONSTRUCTOR
4538 && vec_safe_is_empty (CONSTRUCTOR_ELTS (from)));
4540 /* Now proceed. */
4541 to = TREE_OPERAND (*expr_p, 0);
4543 to_ptr = build_fold_addr_expr_loc (loc, to);
4544 gimplify_arg (&to_ptr, seq_p, loc);
4545 t = builtin_decl_implicit (BUILT_IN_MEMSET);
4547 gs = gimple_build_call (t, 3, to_ptr, integer_zero_node, size);
4549 if (want_value)
4551 /* tmp = memset() */
4552 t = create_tmp_var (TREE_TYPE (to_ptr));
4553 gimple_call_set_lhs (gs, t);
4554 gimplify_seq_add_stmt (seq_p, gs);
4556 *expr_p = build1 (INDIRECT_REF, TREE_TYPE (to), t);
4557 return GS_ALL_DONE;
4560 gimplify_seq_add_stmt (seq_p, gs);
4561 *expr_p = NULL;
4562 return GS_ALL_DONE;
4565 /* A subroutine of gimplify_init_ctor_preeval. Called via walk_tree,
4566 determine, cautiously, if a CONSTRUCTOR overlaps the lhs of an
4567 assignment. Return non-null if we detect a potential overlap. */
4569 struct gimplify_init_ctor_preeval_data
4571 /* The base decl of the lhs object. May be NULL, in which case we
4572 have to assume the lhs is indirect. */
4573 tree lhs_base_decl;
4575 /* The alias set of the lhs object. */
4576 alias_set_type lhs_alias_set;
4579 static tree
4580 gimplify_init_ctor_preeval_1 (tree *tp, int *walk_subtrees, void *xdata)
4582 struct gimplify_init_ctor_preeval_data *data
4583 = (struct gimplify_init_ctor_preeval_data *) xdata;
4584 tree t = *tp;
4586 /* If we find the base object, obviously we have overlap. */
4587 if (data->lhs_base_decl == t)
4588 return t;
4590 /* If the constructor component is indirect, determine if we have a
4591 potential overlap with the lhs. The only bits of information we
4592 have to go on at this point are addressability and alias sets. */
4593 if ((INDIRECT_REF_P (t)
4594 || TREE_CODE (t) == MEM_REF)
4595 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
4596 && alias_sets_conflict_p (data->lhs_alias_set, get_alias_set (t)))
4597 return t;
4599 /* If the constructor component is a call, determine if it can hide a
4600 potential overlap with the lhs through an INDIRECT_REF like above.
4601 ??? Ugh - this is completely broken. In fact this whole analysis
4602 doesn't look conservative. */
4603 if (TREE_CODE (t) == CALL_EXPR)
4605 tree type, fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (t)));
4607 for (type = TYPE_ARG_TYPES (fntype); type; type = TREE_CHAIN (type))
4608 if (POINTER_TYPE_P (TREE_VALUE (type))
4609 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
4610 && alias_sets_conflict_p (data->lhs_alias_set,
4611 get_alias_set
4612 (TREE_TYPE (TREE_VALUE (type)))))
4613 return t;
4616 if (IS_TYPE_OR_DECL_P (t))
4617 *walk_subtrees = 0;
4618 return NULL;
4621 /* A subroutine of gimplify_init_constructor. Pre-evaluate EXPR,
4622 force values that overlap with the lhs (as described by *DATA)
4623 into temporaries. */
4625 static void
4626 gimplify_init_ctor_preeval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
4627 struct gimplify_init_ctor_preeval_data *data)
4629 enum gimplify_status one;
4631 /* If the value is constant, then there's nothing to pre-evaluate. */
4632 if (TREE_CONSTANT (*expr_p))
4634 /* Ensure it does not have side effects, it might contain a reference to
4635 the object we're initializing. */
4636 gcc_assert (!TREE_SIDE_EFFECTS (*expr_p));
4637 return;
4640 /* If the type has non-trivial constructors, we can't pre-evaluate. */
4641 if (TREE_ADDRESSABLE (TREE_TYPE (*expr_p)))
4642 return;
4644 /* Recurse for nested constructors. */
4645 if (TREE_CODE (*expr_p) == CONSTRUCTOR)
4647 unsigned HOST_WIDE_INT ix;
4648 constructor_elt *ce;
4649 vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (*expr_p);
4651 FOR_EACH_VEC_SAFE_ELT (v, ix, ce)
4652 gimplify_init_ctor_preeval (&ce->value, pre_p, post_p, data);
4654 return;
4657 /* If this is a variable sized type, we must remember the size. */
4658 maybe_with_size_expr (expr_p);
4660 /* Gimplify the constructor element to something appropriate for the rhs
4661 of a MODIFY_EXPR. Given that we know the LHS is an aggregate, we know
4662 the gimplifier will consider this a store to memory. Doing this
4663 gimplification now means that we won't have to deal with complicated
4664 language-specific trees, nor trees like SAVE_EXPR that can induce
4665 exponential search behavior. */
4666 one = gimplify_expr (expr_p, pre_p, post_p, is_gimple_mem_rhs, fb_rvalue);
4667 if (one == GS_ERROR)
4669 *expr_p = NULL;
4670 return;
4673 /* If we gimplified to a bare decl, we can be sure that it doesn't overlap
4674 with the lhs, since "a = { .x=a }" doesn't make sense. This will
4675 always be true for all scalars, since is_gimple_mem_rhs insists on a
4676 temporary variable for them. */
4677 if (DECL_P (*expr_p))
4678 return;
4680 /* If this is of variable size, we have no choice but to assume it doesn't
4681 overlap since we can't make a temporary for it. */
4682 if (TREE_CODE (TYPE_SIZE (TREE_TYPE (*expr_p))) != INTEGER_CST)
4683 return;
4685 /* Otherwise, we must search for overlap ... */
4686 if (!walk_tree (expr_p, gimplify_init_ctor_preeval_1, data, NULL))
4687 return;
4689 /* ... and if found, force the value into a temporary. */
4690 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
4693 /* A subroutine of gimplify_init_ctor_eval. Create a loop for
4694 a RANGE_EXPR in a CONSTRUCTOR for an array.
4696 var = lower;
4697 loop_entry:
4698 object[var] = value;
4699 if (var == upper)
4700 goto loop_exit;
4701 var = var + 1;
4702 goto loop_entry;
4703 loop_exit:
4705 We increment var _after_ the loop exit check because we might otherwise
4706 fail if upper == TYPE_MAX_VALUE (type for upper).
4708 Note that we never have to deal with SAVE_EXPRs here, because this has
4709 already been taken care of for us, in gimplify_init_ctor_preeval(). */
4711 static void gimplify_init_ctor_eval (tree, vec<constructor_elt, va_gc> *,
4712 gimple_seq *, bool);
4714 static void
4715 gimplify_init_ctor_eval_range (tree object, tree lower, tree upper,
4716 tree value, tree array_elt_type,
4717 gimple_seq *pre_p, bool cleared)
4719 tree loop_entry_label, loop_exit_label, fall_thru_label;
4720 tree var, var_type, cref, tmp;
4722 loop_entry_label = create_artificial_label (UNKNOWN_LOCATION);
4723 loop_exit_label = create_artificial_label (UNKNOWN_LOCATION);
4724 fall_thru_label = create_artificial_label (UNKNOWN_LOCATION);
4726 /* Create and initialize the index variable. */
4727 var_type = TREE_TYPE (upper);
4728 var = create_tmp_var (var_type);
4729 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, lower));
4731 /* Add the loop entry label. */
4732 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_entry_label));
4734 /* Build the reference. */
4735 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
4736 var, NULL_TREE, NULL_TREE);
4738 /* If we are a constructor, just call gimplify_init_ctor_eval to do
4739 the store. Otherwise just assign value to the reference. */
4741 if (TREE_CODE (value) == CONSTRUCTOR)
4742 /* NB we might have to call ourself recursively through
4743 gimplify_init_ctor_eval if the value is a constructor. */
4744 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
4745 pre_p, cleared);
4746 else
4748 if (gimplify_expr (&value, pre_p, NULL, is_gimple_val, fb_rvalue)
4749 != GS_ERROR)
4750 gimplify_seq_add_stmt (pre_p, gimple_build_assign (cref, value));
4753 /* We exit the loop when the index var is equal to the upper bound. */
4754 gimplify_seq_add_stmt (pre_p,
4755 gimple_build_cond (EQ_EXPR, var, upper,
4756 loop_exit_label, fall_thru_label));
4758 gimplify_seq_add_stmt (pre_p, gimple_build_label (fall_thru_label));
4760 /* Otherwise, increment the index var... */
4761 tmp = build2 (PLUS_EXPR, var_type, var,
4762 fold_convert (var_type, integer_one_node));
4763 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, tmp));
4765 /* ...and jump back to the loop entry. */
4766 gimplify_seq_add_stmt (pre_p, gimple_build_goto (loop_entry_label));
4768 /* Add the loop exit label. */
4769 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_exit_label));
4772 /* A subroutine of gimplify_init_constructor. Generate individual
4773 MODIFY_EXPRs for a CONSTRUCTOR. OBJECT is the LHS against which the
4774 assignments should happen. ELTS is the CONSTRUCTOR_ELTS of the
4775 CONSTRUCTOR. CLEARED is true if the entire LHS object has been
4776 zeroed first. */
4778 static void
4779 gimplify_init_ctor_eval (tree object, vec<constructor_elt, va_gc> *elts,
4780 gimple_seq *pre_p, bool cleared)
4782 tree array_elt_type = NULL;
4783 unsigned HOST_WIDE_INT ix;
4784 tree purpose, value;
4786 if (TREE_CODE (TREE_TYPE (object)) == ARRAY_TYPE)
4787 array_elt_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (object)));
4789 FOR_EACH_CONSTRUCTOR_ELT (elts, ix, purpose, value)
4791 tree cref;
4793 /* NULL values are created above for gimplification errors. */
4794 if (value == NULL)
4795 continue;
4797 if (cleared && initializer_zerop (value))
4798 continue;
4800 /* ??? Here's to hoping the front end fills in all of the indices,
4801 so we don't have to figure out what's missing ourselves. */
4802 gcc_assert (purpose);
4804 /* Skip zero-sized fields, unless value has side-effects. This can
4805 happen with calls to functions returning a empty type, which
4806 we shouldn't discard. As a number of downstream passes don't
4807 expect sets of empty type fields, we rely on the gimplification of
4808 the MODIFY_EXPR we make below to drop the assignment statement. */
4809 if (!TREE_SIDE_EFFECTS (value)
4810 && TREE_CODE (purpose) == FIELD_DECL
4811 && is_empty_type (TREE_TYPE (purpose)))
4812 continue;
4814 /* If we have a RANGE_EXPR, we have to build a loop to assign the
4815 whole range. */
4816 if (TREE_CODE (purpose) == RANGE_EXPR)
4818 tree lower = TREE_OPERAND (purpose, 0);
4819 tree upper = TREE_OPERAND (purpose, 1);
4821 /* If the lower bound is equal to upper, just treat it as if
4822 upper was the index. */
4823 if (simple_cst_equal (lower, upper))
4824 purpose = upper;
4825 else
4827 gimplify_init_ctor_eval_range (object, lower, upper, value,
4828 array_elt_type, pre_p, cleared);
4829 continue;
4833 if (array_elt_type)
4835 /* Do not use bitsizetype for ARRAY_REF indices. */
4836 if (TYPE_DOMAIN (TREE_TYPE (object)))
4837 purpose
4838 = fold_convert (TREE_TYPE (TYPE_DOMAIN (TREE_TYPE (object))),
4839 purpose);
4840 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
4841 purpose, NULL_TREE, NULL_TREE);
4843 else
4845 gcc_assert (TREE_CODE (purpose) == FIELD_DECL);
4846 cref = build3 (COMPONENT_REF, TREE_TYPE (purpose),
4847 unshare_expr (object), purpose, NULL_TREE);
4850 if (TREE_CODE (value) == CONSTRUCTOR
4851 && TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE)
4852 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
4853 pre_p, cleared);
4854 else
4856 tree init = build2 (INIT_EXPR, TREE_TYPE (cref), cref, value);
4857 gimplify_and_add (init, pre_p);
4858 ggc_free (init);
4863 /* Return the appropriate RHS predicate for this LHS. */
4865 gimple_predicate
4866 rhs_predicate_for (tree lhs)
4868 if (is_gimple_reg (lhs))
4869 return is_gimple_reg_rhs_or_call;
4870 else
4871 return is_gimple_mem_rhs_or_call;
4874 /* Return the initial guess for an appropriate RHS predicate for this LHS,
4875 before the LHS has been gimplified. */
4877 static gimple_predicate
4878 initial_rhs_predicate_for (tree lhs)
4880 if (is_gimple_reg_type (TREE_TYPE (lhs)))
4881 return is_gimple_reg_rhs_or_call;
4882 else
4883 return is_gimple_mem_rhs_or_call;
4886 /* Gimplify a C99 compound literal expression. This just means adding
4887 the DECL_EXPR before the current statement and using its anonymous
4888 decl instead. */
4890 static enum gimplify_status
4891 gimplify_compound_literal_expr (tree *expr_p, gimple_seq *pre_p,
4892 bool (*gimple_test_f) (tree),
4893 fallback_t fallback)
4895 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (*expr_p);
4896 tree decl = DECL_EXPR_DECL (decl_s);
4897 tree init = DECL_INITIAL (decl);
4898 /* Mark the decl as addressable if the compound literal
4899 expression is addressable now, otherwise it is marked too late
4900 after we gimplify the initialization expression. */
4901 if (TREE_ADDRESSABLE (*expr_p))
4902 TREE_ADDRESSABLE (decl) = 1;
4903 /* Otherwise, if we don't need an lvalue and have a literal directly
4904 substitute it. Check if it matches the gimple predicate, as
4905 otherwise we'd generate a new temporary, and we can as well just
4906 use the decl we already have. */
4907 else if (!TREE_ADDRESSABLE (decl)
4908 && !TREE_THIS_VOLATILE (decl)
4909 && init
4910 && (fallback & fb_lvalue) == 0
4911 && gimple_test_f (init))
4913 *expr_p = init;
4914 return GS_OK;
4917 /* If the decl is not addressable, then it is being used in some
4918 expression or on the right hand side of a statement, and it can
4919 be put into a readonly data section. */
4920 if (!TREE_ADDRESSABLE (decl) && (fallback & fb_lvalue) == 0)
4921 TREE_READONLY (decl) = 1;
4923 /* This decl isn't mentioned in the enclosing block, so add it to the
4924 list of temps. FIXME it seems a bit of a kludge to say that
4925 anonymous artificial vars aren't pushed, but everything else is. */
4926 if (DECL_NAME (decl) == NULL_TREE && !DECL_SEEN_IN_BIND_EXPR_P (decl))
4927 gimple_add_tmp_var (decl);
4929 gimplify_and_add (decl_s, pre_p);
4930 *expr_p = decl;
4931 return GS_OK;
4934 /* Optimize embedded COMPOUND_LITERAL_EXPRs within a CONSTRUCTOR,
4935 return a new CONSTRUCTOR if something changed. */
4937 static tree
4938 optimize_compound_literals_in_ctor (tree orig_ctor)
4940 tree ctor = orig_ctor;
4941 vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ctor);
4942 unsigned int idx, num = vec_safe_length (elts);
4944 for (idx = 0; idx < num; idx++)
4946 tree value = (*elts)[idx].value;
4947 tree newval = value;
4948 if (TREE_CODE (value) == CONSTRUCTOR)
4949 newval = optimize_compound_literals_in_ctor (value);
4950 else if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR)
4952 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (value);
4953 tree decl = DECL_EXPR_DECL (decl_s);
4954 tree init = DECL_INITIAL (decl);
4956 if (!TREE_ADDRESSABLE (value)
4957 && !TREE_ADDRESSABLE (decl)
4958 && init
4959 && TREE_CODE (init) == CONSTRUCTOR)
4960 newval = optimize_compound_literals_in_ctor (init);
4962 if (newval == value)
4963 continue;
4965 if (ctor == orig_ctor)
4967 ctor = copy_node (orig_ctor);
4968 CONSTRUCTOR_ELTS (ctor) = vec_safe_copy (elts);
4969 elts = CONSTRUCTOR_ELTS (ctor);
4971 (*elts)[idx].value = newval;
4973 return ctor;
4976 /* A subroutine of gimplify_modify_expr. Break out elements of a
4977 CONSTRUCTOR used as an initializer into separate MODIFY_EXPRs.
4979 Note that we still need to clear any elements that don't have explicit
4980 initializers, so if not all elements are initialized we keep the
4981 original MODIFY_EXPR, we just remove all of the constructor elements.
4983 If NOTIFY_TEMP_CREATION is true, do not gimplify, just return
4984 GS_ERROR if we would have to create a temporary when gimplifying
4985 this constructor. Otherwise, return GS_OK.
4987 If NOTIFY_TEMP_CREATION is false, just do the gimplification. */
4989 static enum gimplify_status
4990 gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
4991 bool want_value, bool notify_temp_creation)
4993 tree object, ctor, type;
4994 enum gimplify_status ret;
4995 vec<constructor_elt, va_gc> *elts;
4996 bool cleared = false;
4997 bool is_empty_ctor = false;
4998 bool is_init_expr = (TREE_CODE (*expr_p) == INIT_EXPR);
5000 gcc_assert (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == CONSTRUCTOR);
5002 if (!notify_temp_creation)
5004 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
5005 is_gimple_lvalue, fb_lvalue);
5006 if (ret == GS_ERROR)
5007 return ret;
5010 object = TREE_OPERAND (*expr_p, 0);
5011 ctor = TREE_OPERAND (*expr_p, 1)
5012 = optimize_compound_literals_in_ctor (TREE_OPERAND (*expr_p, 1));
5013 type = TREE_TYPE (ctor);
5014 elts = CONSTRUCTOR_ELTS (ctor);
5015 ret = GS_ALL_DONE;
5017 switch (TREE_CODE (type))
5019 case RECORD_TYPE:
5020 case UNION_TYPE:
5021 case QUAL_UNION_TYPE:
5022 case ARRAY_TYPE:
5024 /* Use readonly data for initializers of this or smaller size
5025 regardless of the num_nonzero_elements / num_unique_nonzero_elements
5026 ratio. */
5027 const HOST_WIDE_INT min_unique_size = 64;
5028 /* If num_nonzero_elements / num_unique_nonzero_elements ratio
5029 is smaller than this, use readonly data. */
5030 const int unique_nonzero_ratio = 8;
5031 /* True if a single access of the object must be ensured. This is the
5032 case if the target is volatile, the type is non-addressable and more
5033 than one field need to be assigned. */
5034 const bool ensure_single_access
5035 = TREE_THIS_VOLATILE (object)
5036 && !TREE_ADDRESSABLE (type)
5037 && vec_safe_length (elts) > 1;
5038 struct gimplify_init_ctor_preeval_data preeval_data;
5039 HOST_WIDE_INT num_ctor_elements, num_nonzero_elements;
5040 HOST_WIDE_INT num_unique_nonzero_elements;
5041 bool complete_p, valid_const_initializer;
5043 /* Aggregate types must lower constructors to initialization of
5044 individual elements. The exception is that a CONSTRUCTOR node
5045 with no elements indicates zero-initialization of the whole. */
5046 if (vec_safe_is_empty (elts))
5048 if (notify_temp_creation)
5049 return GS_OK;
5050 is_empty_ctor = true;
5051 break;
5054 /* Fetch information about the constructor to direct later processing.
5055 We might want to make static versions of it in various cases, and
5056 can only do so if it known to be a valid constant initializer. */
5057 valid_const_initializer
5058 = categorize_ctor_elements (ctor, &num_nonzero_elements,
5059 &num_unique_nonzero_elements,
5060 &num_ctor_elements, &complete_p);
5062 /* If a const aggregate variable is being initialized, then it
5063 should never be a lose to promote the variable to be static. */
5064 if (valid_const_initializer
5065 && num_nonzero_elements > 1
5066 && TREE_READONLY (object)
5067 && VAR_P (object)
5068 && !DECL_REGISTER (object)
5069 && (flag_merge_constants >= 2 || !TREE_ADDRESSABLE (object))
5070 /* For ctors that have many repeated nonzero elements
5071 represented through RANGE_EXPRs, prefer initializing
5072 those through runtime loops over copies of large amounts
5073 of data from readonly data section. */
5074 && (num_unique_nonzero_elements
5075 > num_nonzero_elements / unique_nonzero_ratio
5076 || ((unsigned HOST_WIDE_INT) int_size_in_bytes (type)
5077 <= (unsigned HOST_WIDE_INT) min_unique_size)))
5079 if (notify_temp_creation)
5080 return GS_ERROR;
5082 DECL_INITIAL (object) = ctor;
5083 TREE_STATIC (object) = 1;
5084 if (!DECL_NAME (object))
5085 DECL_NAME (object) = create_tmp_var_name ("C");
5086 walk_tree (&DECL_INITIAL (object), force_labels_r, NULL, NULL);
5088 /* ??? C++ doesn't automatically append a .<number> to the
5089 assembler name, and even when it does, it looks at FE private
5090 data structures to figure out what that number should be,
5091 which are not set for this variable. I suppose this is
5092 important for local statics for inline functions, which aren't
5093 "local" in the object file sense. So in order to get a unique
5094 TU-local symbol, we must invoke the lhd version now. */
5095 lhd_set_decl_assembler_name (object);
5097 *expr_p = NULL_TREE;
5098 break;
5101 /* If there are "lots" of initialized elements, even discounting
5102 those that are not address constants (and thus *must* be
5103 computed at runtime), then partition the constructor into
5104 constant and non-constant parts. Block copy the constant
5105 parts in, then generate code for the non-constant parts. */
5106 /* TODO. There's code in cp/typeck.c to do this. */
5108 if (int_size_in_bytes (TREE_TYPE (ctor)) < 0)
5109 /* store_constructor will ignore the clearing of variable-sized
5110 objects. Initializers for such objects must explicitly set
5111 every field that needs to be set. */
5112 cleared = false;
5113 else if (!complete_p)
5114 /* If the constructor isn't complete, clear the whole object
5115 beforehand, unless CONSTRUCTOR_NO_CLEARING is set on it.
5117 ??? This ought not to be needed. For any element not present
5118 in the initializer, we should simply set them to zero. Except
5119 we'd need to *find* the elements that are not present, and that
5120 requires trickery to avoid quadratic compile-time behavior in
5121 large cases or excessive memory use in small cases. */
5122 cleared = !CONSTRUCTOR_NO_CLEARING (ctor);
5123 else if (num_ctor_elements - num_nonzero_elements
5124 > CLEAR_RATIO (optimize_function_for_speed_p (cfun))
5125 && num_nonzero_elements < num_ctor_elements / 4)
5126 /* If there are "lots" of zeros, it's more efficient to clear
5127 the memory and then set the nonzero elements. */
5128 cleared = true;
5129 else if (ensure_single_access && num_nonzero_elements == 0)
5130 /* If a single access to the target must be ensured and all elements
5131 are zero, then it's optimal to clear whatever their number. */
5132 cleared = true;
5133 else
5134 cleared = false;
5136 /* If there are "lots" of initialized elements, and all of them
5137 are valid address constants, then the entire initializer can
5138 be dropped to memory, and then memcpy'd out. Don't do this
5139 for sparse arrays, though, as it's more efficient to follow
5140 the standard CONSTRUCTOR behavior of memset followed by
5141 individual element initialization. Also don't do this for small
5142 all-zero initializers (which aren't big enough to merit
5143 clearing), and don't try to make bitwise copies of
5144 TREE_ADDRESSABLE types. */
5145 if (valid_const_initializer
5146 && complete_p
5147 && !(cleared || num_nonzero_elements == 0)
5148 && !TREE_ADDRESSABLE (type))
5150 HOST_WIDE_INT size = int_size_in_bytes (type);
5151 unsigned int align;
5153 /* ??? We can still get unbounded array types, at least
5154 from the C++ front end. This seems wrong, but attempt
5155 to work around it for now. */
5156 if (size < 0)
5158 size = int_size_in_bytes (TREE_TYPE (object));
5159 if (size >= 0)
5160 TREE_TYPE (ctor) = type = TREE_TYPE (object);
5163 /* Find the maximum alignment we can assume for the object. */
5164 /* ??? Make use of DECL_OFFSET_ALIGN. */
5165 if (DECL_P (object))
5166 align = DECL_ALIGN (object);
5167 else
5168 align = TYPE_ALIGN (type);
5170 /* Do a block move either if the size is so small as to make
5171 each individual move a sub-unit move on average, or if it
5172 is so large as to make individual moves inefficient. */
5173 if (size > 0
5174 && num_nonzero_elements > 1
5175 /* For ctors that have many repeated nonzero elements
5176 represented through RANGE_EXPRs, prefer initializing
5177 those through runtime loops over copies of large amounts
5178 of data from readonly data section. */
5179 && (num_unique_nonzero_elements
5180 > num_nonzero_elements / unique_nonzero_ratio
5181 || size <= min_unique_size)
5182 && (size < num_nonzero_elements
5183 || !can_move_by_pieces (size, align)))
5185 if (notify_temp_creation)
5186 return GS_ERROR;
5188 walk_tree (&ctor, force_labels_r, NULL, NULL);
5189 ctor = tree_output_constant_def (ctor);
5190 if (!useless_type_conversion_p (type, TREE_TYPE (ctor)))
5191 ctor = build1 (VIEW_CONVERT_EXPR, type, ctor);
5192 TREE_OPERAND (*expr_p, 1) = ctor;
5194 /* This is no longer an assignment of a CONSTRUCTOR, but
5195 we still may have processing to do on the LHS. So
5196 pretend we didn't do anything here to let that happen. */
5197 return GS_UNHANDLED;
5201 /* If a single access to the target must be ensured and there are
5202 nonzero elements or the zero elements are not assigned en masse,
5203 initialize the target from a temporary. */
5204 if (ensure_single_access && (num_nonzero_elements > 0 || !cleared))
5206 if (notify_temp_creation)
5207 return GS_ERROR;
5209 tree temp = create_tmp_var (TYPE_MAIN_VARIANT (type));
5210 TREE_OPERAND (*expr_p, 0) = temp;
5211 *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p),
5212 *expr_p,
5213 build2 (MODIFY_EXPR, void_type_node,
5214 object, temp));
5215 return GS_OK;
5218 if (notify_temp_creation)
5219 return GS_OK;
5221 /* If there are nonzero elements and if needed, pre-evaluate to capture
5222 elements overlapping with the lhs into temporaries. We must do this
5223 before clearing to fetch the values before they are zeroed-out. */
5224 if (num_nonzero_elements > 0 && TREE_CODE (*expr_p) != INIT_EXPR)
5226 preeval_data.lhs_base_decl = get_base_address (object);
5227 if (!DECL_P (preeval_data.lhs_base_decl))
5228 preeval_data.lhs_base_decl = NULL;
5229 preeval_data.lhs_alias_set = get_alias_set (object);
5231 gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p, 1),
5232 pre_p, post_p, &preeval_data);
5235 bool ctor_has_side_effects_p
5236 = TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p, 1));
5238 if (cleared)
5240 /* Zap the CONSTRUCTOR element list, which simplifies this case.
5241 Note that we still have to gimplify, in order to handle the
5242 case of variable sized types. Avoid shared tree structures. */
5243 CONSTRUCTOR_ELTS (ctor) = NULL;
5244 TREE_SIDE_EFFECTS (ctor) = 0;
5245 object = unshare_expr (object);
5246 gimplify_stmt (expr_p, pre_p);
5249 /* If we have not block cleared the object, or if there are nonzero
5250 elements in the constructor, or if the constructor has side effects,
5251 add assignments to the individual scalar fields of the object. */
5252 if (!cleared
5253 || num_nonzero_elements > 0
5254 || ctor_has_side_effects_p)
5255 gimplify_init_ctor_eval (object, elts, pre_p, cleared);
5257 *expr_p = NULL_TREE;
5259 break;
5261 case COMPLEX_TYPE:
5263 tree r, i;
5265 if (notify_temp_creation)
5266 return GS_OK;
5268 /* Extract the real and imaginary parts out of the ctor. */
5269 gcc_assert (elts->length () == 2);
5270 r = (*elts)[0].value;
5271 i = (*elts)[1].value;
5272 if (r == NULL || i == NULL)
5274 tree zero = build_zero_cst (TREE_TYPE (type));
5275 if (r == NULL)
5276 r = zero;
5277 if (i == NULL)
5278 i = zero;
5281 /* Complex types have either COMPLEX_CST or COMPLEX_EXPR to
5282 represent creation of a complex value. */
5283 if (TREE_CONSTANT (r) && TREE_CONSTANT (i))
5285 ctor = build_complex (type, r, i);
5286 TREE_OPERAND (*expr_p, 1) = ctor;
5288 else
5290 ctor = build2 (COMPLEX_EXPR, type, r, i);
5291 TREE_OPERAND (*expr_p, 1) = ctor;
5292 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 1),
5293 pre_p,
5294 post_p,
5295 rhs_predicate_for (TREE_OPERAND (*expr_p, 0)),
5296 fb_rvalue);
5299 break;
5301 case VECTOR_TYPE:
5303 unsigned HOST_WIDE_INT ix;
5304 constructor_elt *ce;
5306 if (notify_temp_creation)
5307 return GS_OK;
5309 /* Go ahead and simplify constant constructors to VECTOR_CST. */
5310 if (TREE_CONSTANT (ctor))
5312 bool constant_p = true;
5313 tree value;
5315 /* Even when ctor is constant, it might contain non-*_CST
5316 elements, such as addresses or trapping values like
5317 1.0/0.0 - 1.0/0.0. Such expressions don't belong
5318 in VECTOR_CST nodes. */
5319 FOR_EACH_CONSTRUCTOR_VALUE (elts, ix, value)
5320 if (!CONSTANT_CLASS_P (value))
5322 constant_p = false;
5323 break;
5326 if (constant_p)
5328 TREE_OPERAND (*expr_p, 1) = build_vector_from_ctor (type, elts);
5329 break;
5332 TREE_CONSTANT (ctor) = 0;
5335 /* Vector types use CONSTRUCTOR all the way through gimple
5336 compilation as a general initializer. */
5337 FOR_EACH_VEC_SAFE_ELT (elts, ix, ce)
5339 enum gimplify_status tret;
5340 tret = gimplify_expr (&ce->value, pre_p, post_p, is_gimple_val,
5341 fb_rvalue);
5342 if (tret == GS_ERROR)
5343 ret = GS_ERROR;
5344 else if (TREE_STATIC (ctor)
5345 && !initializer_constant_valid_p (ce->value,
5346 TREE_TYPE (ce->value)))
5347 TREE_STATIC (ctor) = 0;
5349 recompute_constructor_flags (ctor);
5350 if (!is_gimple_reg (TREE_OPERAND (*expr_p, 0)))
5351 TREE_OPERAND (*expr_p, 1) = get_formal_tmp_var (ctor, pre_p);
5353 break;
5355 default:
5356 /* So how did we get a CONSTRUCTOR for a scalar type? */
5357 gcc_unreachable ();
5360 if (ret == GS_ERROR)
5361 return GS_ERROR;
5362 /* If we have gimplified both sides of the initializer but have
5363 not emitted an assignment, do so now. */
5364 if (*expr_p)
5366 tree lhs = TREE_OPERAND (*expr_p, 0);
5367 tree rhs = TREE_OPERAND (*expr_p, 1);
5368 if (want_value && object == lhs)
5369 lhs = unshare_expr (lhs);
5370 gassign *init = gimple_build_assign (lhs, rhs);
5371 gimplify_seq_add_stmt (pre_p, init);
5373 if (want_value)
5375 *expr_p = object;
5376 ret = GS_OK;
5378 else
5380 *expr_p = NULL;
5381 ret = GS_ALL_DONE;
5384 /* If the user requests to initialize automatic variables, we
5385 should initialize paddings inside the variable. Add a call to
5386 __builtin_clear_pading (&object, 0, for_auto_init = true) to
5387 initialize paddings of object always to zero regardless of
5388 INIT_TYPE. Note, we will not insert this call if the aggregate
5389 variable has be completely cleared already or it's initialized
5390 with an empty constructor. We cannot insert this call if the
5391 variable is a gimple register since __builtin_clear_padding will take
5392 the address of the variable. As a result, if a long double/_Complex long
5393 double variable will be spilled into stack later, its padding cannot
5394 be cleared with __builtin_clear_padding. We should clear its padding
5395 when it is spilled into memory. */
5396 if (is_init_expr
5397 && !is_gimple_reg (object)
5398 && clear_padding_type_may_have_padding_p (type)
5399 && ((AGGREGATE_TYPE_P (type) && !cleared && !is_empty_ctor)
5400 || !AGGREGATE_TYPE_P (type))
5401 && is_var_need_auto_init (object))
5402 gimple_add_padding_init_for_auto_var (object, false, pre_p);
5404 return ret;
5407 /* Given a pointer value OP0, return a simplified version of an
5408 indirection through OP0, or NULL_TREE if no simplification is
5409 possible. This may only be applied to a rhs of an expression.
5410 Note that the resulting type may be different from the type pointed
5411 to in the sense that it is still compatible from the langhooks
5412 point of view. */
5414 static tree
5415 gimple_fold_indirect_ref_rhs (tree t)
5417 return gimple_fold_indirect_ref (t);
5420 /* Subroutine of gimplify_modify_expr to do simplifications of
5421 MODIFY_EXPRs based on the code of the RHS. We loop for as long as
5422 something changes. */
5424 static enum gimplify_status
5425 gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p,
5426 gimple_seq *pre_p, gimple_seq *post_p,
5427 bool want_value)
5429 enum gimplify_status ret = GS_UNHANDLED;
5430 bool changed;
5434 changed = false;
5435 switch (TREE_CODE (*from_p))
5437 case VAR_DECL:
5438 /* If we're assigning from a read-only variable initialized with
5439 a constructor and not volatile, do the direct assignment from
5440 the constructor, but only if the target is not volatile either
5441 since this latter assignment might end up being done on a per
5442 field basis. However, if the target is volatile and the type
5443 is aggregate and non-addressable, gimplify_init_constructor
5444 knows that it needs to ensure a single access to the target
5445 and it will return GS_OK only in this case. */
5446 if (TREE_READONLY (*from_p)
5447 && DECL_INITIAL (*from_p)
5448 && TREE_CODE (DECL_INITIAL (*from_p)) == CONSTRUCTOR
5449 && !TREE_THIS_VOLATILE (*from_p)
5450 && (!TREE_THIS_VOLATILE (*to_p)
5451 || (AGGREGATE_TYPE_P (TREE_TYPE (*to_p))
5452 && !TREE_ADDRESSABLE (TREE_TYPE (*to_p)))))
5454 tree old_from = *from_p;
5455 enum gimplify_status subret;
5457 /* Move the constructor into the RHS. */
5458 *from_p = unshare_expr (DECL_INITIAL (*from_p));
5460 /* Let's see if gimplify_init_constructor will need to put
5461 it in memory. */
5462 subret = gimplify_init_constructor (expr_p, NULL, NULL,
5463 false, true);
5464 if (subret == GS_ERROR)
5466 /* If so, revert the change. */
5467 *from_p = old_from;
5469 else
5471 ret = GS_OK;
5472 changed = true;
5475 break;
5476 case INDIRECT_REF:
5478 /* If we have code like
5480 *(const A*)(A*)&x
5482 where the type of "x" is a (possibly cv-qualified variant
5483 of "A"), treat the entire expression as identical to "x".
5484 This kind of code arises in C++ when an object is bound
5485 to a const reference, and if "x" is a TARGET_EXPR we want
5486 to take advantage of the optimization below. */
5487 bool volatile_p = TREE_THIS_VOLATILE (*from_p);
5488 tree t = gimple_fold_indirect_ref_rhs (TREE_OPERAND (*from_p, 0));
5489 if (t)
5491 if (TREE_THIS_VOLATILE (t) != volatile_p)
5493 if (DECL_P (t))
5494 t = build_simple_mem_ref_loc (EXPR_LOCATION (*from_p),
5495 build_fold_addr_expr (t));
5496 if (REFERENCE_CLASS_P (t))
5497 TREE_THIS_VOLATILE (t) = volatile_p;
5499 *from_p = t;
5500 ret = GS_OK;
5501 changed = true;
5503 break;
5506 case TARGET_EXPR:
5508 /* If we are initializing something from a TARGET_EXPR, strip the
5509 TARGET_EXPR and initialize it directly, if possible. This can't
5510 be done if the initializer is void, since that implies that the
5511 temporary is set in some non-trivial way.
5513 ??? What about code that pulls out the temp and uses it
5514 elsewhere? I think that such code never uses the TARGET_EXPR as
5515 an initializer. If I'm wrong, we'll die because the temp won't
5516 have any RTL. In that case, I guess we'll need to replace
5517 references somehow. */
5518 tree init = TARGET_EXPR_INITIAL (*from_p);
5520 if (init
5521 && (TREE_CODE (*expr_p) != MODIFY_EXPR
5522 || !TARGET_EXPR_NO_ELIDE (*from_p))
5523 && !VOID_TYPE_P (TREE_TYPE (init)))
5525 *from_p = init;
5526 ret = GS_OK;
5527 changed = true;
5530 break;
5532 case COMPOUND_EXPR:
5533 /* Remove any COMPOUND_EXPR in the RHS so the following cases will be
5534 caught. */
5535 gimplify_compound_expr (from_p, pre_p, true);
5536 ret = GS_OK;
5537 changed = true;
5538 break;
5540 case CONSTRUCTOR:
5541 /* If we already made some changes, let the front end have a
5542 crack at this before we break it down. */
5543 if (ret != GS_UNHANDLED)
5544 break;
5546 /* If we're initializing from a CONSTRUCTOR, break this into
5547 individual MODIFY_EXPRs. */
5548 ret = gimplify_init_constructor (expr_p, pre_p, post_p, want_value,
5549 false);
5550 return ret;
5552 case COND_EXPR:
5553 /* If we're assigning to a non-register type, push the assignment
5554 down into the branches. This is mandatory for ADDRESSABLE types,
5555 since we cannot generate temporaries for such, but it saves a
5556 copy in other cases as well. */
5557 if (!is_gimple_reg_type (TREE_TYPE (*from_p)))
5559 /* This code should mirror the code in gimplify_cond_expr. */
5560 enum tree_code code = TREE_CODE (*expr_p);
5561 tree cond = *from_p;
5562 tree result = *to_p;
5564 ret = gimplify_expr (&result, pre_p, post_p,
5565 is_gimple_lvalue, fb_lvalue);
5566 if (ret != GS_ERROR)
5567 ret = GS_OK;
5569 /* If we are going to write RESULT more than once, clear
5570 TREE_READONLY flag, otherwise we might incorrectly promote
5571 the variable to static const and initialize it at compile
5572 time in one of the branches. */
5573 if (VAR_P (result)
5574 && TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node
5575 && TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
5576 TREE_READONLY (result) = 0;
5577 if (TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node)
5578 TREE_OPERAND (cond, 1)
5579 = build2 (code, void_type_node, result,
5580 TREE_OPERAND (cond, 1));
5581 if (TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
5582 TREE_OPERAND (cond, 2)
5583 = build2 (code, void_type_node, unshare_expr (result),
5584 TREE_OPERAND (cond, 2));
5586 TREE_TYPE (cond) = void_type_node;
5587 recalculate_side_effects (cond);
5589 if (want_value)
5591 gimplify_and_add (cond, pre_p);
5592 *expr_p = unshare_expr (result);
5594 else
5595 *expr_p = cond;
5596 return ret;
5598 break;
5600 case CALL_EXPR:
5601 /* For calls that return in memory, give *to_p as the CALL_EXPR's
5602 return slot so that we don't generate a temporary. */
5603 if (!CALL_EXPR_RETURN_SLOT_OPT (*from_p)
5604 && aggregate_value_p (*from_p, *from_p))
5606 bool use_target;
5608 if (!(rhs_predicate_for (*to_p))(*from_p))
5609 /* If we need a temporary, *to_p isn't accurate. */
5610 use_target = false;
5611 /* It's OK to use the return slot directly unless it's an NRV. */
5612 else if (TREE_CODE (*to_p) == RESULT_DECL
5613 && DECL_NAME (*to_p) == NULL_TREE
5614 && needs_to_live_in_memory (*to_p))
5615 use_target = true;
5616 else if (is_gimple_reg_type (TREE_TYPE (*to_p))
5617 || (DECL_P (*to_p) && DECL_REGISTER (*to_p)))
5618 /* Don't force regs into memory. */
5619 use_target = false;
5620 else if (TREE_CODE (*expr_p) == INIT_EXPR)
5621 /* It's OK to use the target directly if it's being
5622 initialized. */
5623 use_target = true;
5624 else if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p)))
5625 != INTEGER_CST)
5626 /* Always use the target and thus RSO for variable-sized types.
5627 GIMPLE cannot deal with a variable-sized assignment
5628 embedded in a call statement. */
5629 use_target = true;
5630 else if (TREE_CODE (*to_p) != SSA_NAME
5631 && (!is_gimple_variable (*to_p)
5632 || needs_to_live_in_memory (*to_p)))
5633 /* Don't use the original target if it's already addressable;
5634 if its address escapes, and the called function uses the
5635 NRV optimization, a conforming program could see *to_p
5636 change before the called function returns; see c++/19317.
5637 When optimizing, the return_slot pass marks more functions
5638 as safe after we have escape info. */
5639 use_target = false;
5640 else
5641 use_target = true;
5643 if (use_target)
5645 CALL_EXPR_RETURN_SLOT_OPT (*from_p) = 1;
5646 mark_addressable (*to_p);
5649 break;
5651 case WITH_SIZE_EXPR:
5652 /* Likewise for calls that return an aggregate of non-constant size,
5653 since we would not be able to generate a temporary at all. */
5654 if (TREE_CODE (TREE_OPERAND (*from_p, 0)) == CALL_EXPR)
5656 *from_p = TREE_OPERAND (*from_p, 0);
5657 /* We don't change ret in this case because the
5658 WITH_SIZE_EXPR might have been added in
5659 gimplify_modify_expr, so returning GS_OK would lead to an
5660 infinite loop. */
5661 changed = true;
5663 break;
5665 /* If we're initializing from a container, push the initialization
5666 inside it. */
5667 case CLEANUP_POINT_EXPR:
5668 case BIND_EXPR:
5669 case STATEMENT_LIST:
5671 tree wrap = *from_p;
5672 tree t;
5674 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_min_lval,
5675 fb_lvalue);
5676 if (ret != GS_ERROR)
5677 ret = GS_OK;
5679 t = voidify_wrapper_expr (wrap, *expr_p);
5680 gcc_assert (t == *expr_p);
5682 if (want_value)
5684 gimplify_and_add (wrap, pre_p);
5685 *expr_p = unshare_expr (*to_p);
5687 else
5688 *expr_p = wrap;
5689 return GS_OK;
5692 case NOP_EXPR:
5693 /* Pull out compound literal expressions from a NOP_EXPR.
5694 Those are created in the C FE to drop qualifiers during
5695 lvalue conversion. */
5696 if ((TREE_CODE (TREE_OPERAND (*from_p, 0)) == COMPOUND_LITERAL_EXPR)
5697 && tree_ssa_useless_type_conversion (*from_p))
5699 *from_p = TREE_OPERAND (*from_p, 0);
5700 ret = GS_OK;
5701 changed = true;
5703 break;
5705 case COMPOUND_LITERAL_EXPR:
5707 tree complit = TREE_OPERAND (*expr_p, 1);
5708 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (complit);
5709 tree decl = DECL_EXPR_DECL (decl_s);
5710 tree init = DECL_INITIAL (decl);
5712 /* struct T x = (struct T) { 0, 1, 2 } can be optimized
5713 into struct T x = { 0, 1, 2 } if the address of the
5714 compound literal has never been taken. */
5715 if (!TREE_ADDRESSABLE (complit)
5716 && !TREE_ADDRESSABLE (decl)
5717 && init)
5719 *expr_p = copy_node (*expr_p);
5720 TREE_OPERAND (*expr_p, 1) = init;
5721 return GS_OK;
5725 default:
5726 break;
5729 while (changed);
5731 return ret;
5735 /* Return true if T looks like a valid GIMPLE statement. */
5737 static bool
5738 is_gimple_stmt (tree t)
5740 const enum tree_code code = TREE_CODE (t);
5742 switch (code)
5744 case NOP_EXPR:
5745 /* The only valid NOP_EXPR is the empty statement. */
5746 return IS_EMPTY_STMT (t);
5748 case BIND_EXPR:
5749 case COND_EXPR:
5750 /* These are only valid if they're void. */
5751 return TREE_TYPE (t) == NULL || VOID_TYPE_P (TREE_TYPE (t));
5753 case SWITCH_EXPR:
5754 case GOTO_EXPR:
5755 case RETURN_EXPR:
5756 case LABEL_EXPR:
5757 case CASE_LABEL_EXPR:
5758 case TRY_CATCH_EXPR:
5759 case TRY_FINALLY_EXPR:
5760 case EH_FILTER_EXPR:
5761 case CATCH_EXPR:
5762 case ASM_EXPR:
5763 case STATEMENT_LIST:
5764 case OACC_PARALLEL:
5765 case OACC_KERNELS:
5766 case OACC_SERIAL:
5767 case OACC_DATA:
5768 case OACC_HOST_DATA:
5769 case OACC_DECLARE:
5770 case OACC_UPDATE:
5771 case OACC_ENTER_DATA:
5772 case OACC_EXIT_DATA:
5773 case OACC_CACHE:
5774 case OMP_PARALLEL:
5775 case OMP_FOR:
5776 case OMP_SIMD:
5777 case OMP_DISTRIBUTE:
5778 case OMP_LOOP:
5779 case OACC_LOOP:
5780 case OMP_SCAN:
5781 case OMP_SCOPE:
5782 case OMP_SECTIONS:
5783 case OMP_SECTION:
5784 case OMP_SINGLE:
5785 case OMP_MASTER:
5786 case OMP_MASKED:
5787 case OMP_TASKGROUP:
5788 case OMP_ORDERED:
5789 case OMP_CRITICAL:
5790 case OMP_TASK:
5791 case OMP_TARGET:
5792 case OMP_TARGET_DATA:
5793 case OMP_TARGET_UPDATE:
5794 case OMP_TARGET_ENTER_DATA:
5795 case OMP_TARGET_EXIT_DATA:
5796 case OMP_TASKLOOP:
5797 case OMP_TEAMS:
5798 /* These are always void. */
5799 return true;
5801 case CALL_EXPR:
5802 case MODIFY_EXPR:
5803 case PREDICT_EXPR:
5804 /* These are valid regardless of their type. */
5805 return true;
5807 default:
5808 return false;
5813 /* Promote partial stores to COMPLEX variables to total stores. *EXPR_P is
5814 a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a gimple register.
5816 IMPORTANT NOTE: This promotion is performed by introducing a load of the
5817 other, unmodified part of the complex object just before the total store.
5818 As a consequence, if the object is still uninitialized, an undefined value
5819 will be loaded into a register, which may result in a spurious exception
5820 if the register is floating-point and the value happens to be a signaling
5821 NaN for example. Then the fully-fledged complex operations lowering pass
5822 followed by a DCE pass are necessary in order to fix things up. */
5824 static enum gimplify_status
5825 gimplify_modify_expr_complex_part (tree *expr_p, gimple_seq *pre_p,
5826 bool want_value)
5828 enum tree_code code, ocode;
5829 tree lhs, rhs, new_rhs, other, realpart, imagpart;
5831 lhs = TREE_OPERAND (*expr_p, 0);
5832 rhs = TREE_OPERAND (*expr_p, 1);
5833 code = TREE_CODE (lhs);
5834 lhs = TREE_OPERAND (lhs, 0);
5836 ocode = code == REALPART_EXPR ? IMAGPART_EXPR : REALPART_EXPR;
5837 other = build1 (ocode, TREE_TYPE (rhs), lhs);
5838 suppress_warning (other);
5839 other = get_formal_tmp_var (other, pre_p);
5841 realpart = code == REALPART_EXPR ? rhs : other;
5842 imagpart = code == REALPART_EXPR ? other : rhs;
5844 if (TREE_CONSTANT (realpart) && TREE_CONSTANT (imagpart))
5845 new_rhs = build_complex (TREE_TYPE (lhs), realpart, imagpart);
5846 else
5847 new_rhs = build2 (COMPLEX_EXPR, TREE_TYPE (lhs), realpart, imagpart);
5849 gimplify_seq_add_stmt (pre_p, gimple_build_assign (lhs, new_rhs));
5850 *expr_p = (want_value) ? rhs : NULL_TREE;
5852 return GS_ALL_DONE;
5855 /* Gimplify the MODIFY_EXPR node pointed to by EXPR_P.
5857 modify_expr
5858 : varname '=' rhs
5859 | '*' ID '=' rhs
5861 PRE_P points to the list where side effects that must happen before
5862 *EXPR_P should be stored.
5864 POST_P points to the list where side effects that must happen after
5865 *EXPR_P should be stored.
5867 WANT_VALUE is nonzero iff we want to use the value of this expression
5868 in another expression. */
5870 static enum gimplify_status
5871 gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
5872 bool want_value)
5874 tree *from_p = &TREE_OPERAND (*expr_p, 1);
5875 tree *to_p = &TREE_OPERAND (*expr_p, 0);
5876 enum gimplify_status ret = GS_UNHANDLED;
5877 gimple *assign;
5878 location_t loc = EXPR_LOCATION (*expr_p);
5879 gimple_stmt_iterator gsi;
5881 gcc_assert (TREE_CODE (*expr_p) == MODIFY_EXPR
5882 || TREE_CODE (*expr_p) == INIT_EXPR);
5884 /* Trying to simplify a clobber using normal logic doesn't work,
5885 so handle it here. */
5886 if (TREE_CLOBBER_P (*from_p))
5888 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
5889 if (ret == GS_ERROR)
5890 return ret;
5891 gcc_assert (!want_value);
5892 if (!VAR_P (*to_p) && TREE_CODE (*to_p) != MEM_REF)
5894 tree addr = get_initialized_tmp_var (build_fold_addr_expr (*to_p),
5895 pre_p, post_p);
5896 *to_p = build_simple_mem_ref_loc (EXPR_LOCATION (*to_p), addr);
5898 gimplify_seq_add_stmt (pre_p, gimple_build_assign (*to_p, *from_p));
5899 *expr_p = NULL;
5900 return GS_ALL_DONE;
5903 /* Insert pointer conversions required by the middle-end that are not
5904 required by the frontend. This fixes middle-end type checking for
5905 for example gcc.dg/redecl-6.c. */
5906 if (POINTER_TYPE_P (TREE_TYPE (*to_p)))
5908 STRIP_USELESS_TYPE_CONVERSION (*from_p);
5909 if (!useless_type_conversion_p (TREE_TYPE (*to_p), TREE_TYPE (*from_p)))
5910 *from_p = fold_convert_loc (loc, TREE_TYPE (*to_p), *from_p);
5913 /* See if any simplifications can be done based on what the RHS is. */
5914 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
5915 want_value);
5916 if (ret != GS_UNHANDLED)
5917 return ret;
5919 /* For empty types only gimplify the left hand side and right hand
5920 side as statements and throw away the assignment. Do this after
5921 gimplify_modify_expr_rhs so we handle TARGET_EXPRs of addressable
5922 types properly. */
5923 if (is_empty_type (TREE_TYPE (*from_p))
5924 && !want_value
5925 /* Don't do this for calls that return addressable types, expand_call
5926 relies on those having a lhs. */
5927 && !(TREE_ADDRESSABLE (TREE_TYPE (*from_p))
5928 && TREE_CODE (*from_p) == CALL_EXPR))
5930 gimplify_stmt (from_p, pre_p);
5931 gimplify_stmt (to_p, pre_p);
5932 *expr_p = NULL_TREE;
5933 return GS_ALL_DONE;
5936 /* If the value being copied is of variable width, compute the length
5937 of the copy into a WITH_SIZE_EXPR. Note that we need to do this
5938 before gimplifying any of the operands so that we can resolve any
5939 PLACEHOLDER_EXPRs in the size. Also note that the RTL expander uses
5940 the size of the expression to be copied, not of the destination, so
5941 that is what we must do here. */
5942 maybe_with_size_expr (from_p);
5944 /* As a special case, we have to temporarily allow for assignments
5945 with a CALL_EXPR on the RHS. Since in GIMPLE a function call is
5946 a toplevel statement, when gimplifying the GENERIC expression
5947 MODIFY_EXPR <a, CALL_EXPR <foo>>, we cannot create the tuple
5948 GIMPLE_ASSIGN <a, GIMPLE_CALL <foo>>.
5950 Instead, we need to create the tuple GIMPLE_CALL <a, foo>. To
5951 prevent gimplify_expr from trying to create a new temporary for
5952 foo's LHS, we tell it that it should only gimplify until it
5953 reaches the CALL_EXPR. On return from gimplify_expr, the newly
5954 created GIMPLE_CALL <foo> will be the last statement in *PRE_P
5955 and all we need to do here is set 'a' to be its LHS. */
5957 /* Gimplify the RHS first for C++17 and bug 71104. */
5958 gimple_predicate initial_pred = initial_rhs_predicate_for (*to_p);
5959 ret = gimplify_expr (from_p, pre_p, post_p, initial_pred, fb_rvalue);
5960 if (ret == GS_ERROR)
5961 return ret;
5963 /* Then gimplify the LHS. */
5964 /* If we gimplified the RHS to a CALL_EXPR and that call may return
5965 twice we have to make sure to gimplify into non-SSA as otherwise
5966 the abnormal edge added later will make those defs not dominate
5967 their uses.
5968 ??? Technically this applies only to the registers used in the
5969 resulting non-register *TO_P. */
5970 bool saved_into_ssa = gimplify_ctxp->into_ssa;
5971 if (saved_into_ssa
5972 && TREE_CODE (*from_p) == CALL_EXPR
5973 && call_expr_flags (*from_p) & ECF_RETURNS_TWICE)
5974 gimplify_ctxp->into_ssa = false;
5975 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
5976 gimplify_ctxp->into_ssa = saved_into_ssa;
5977 if (ret == GS_ERROR)
5978 return ret;
5980 /* Now that the LHS is gimplified, re-gimplify the RHS if our initial
5981 guess for the predicate was wrong. */
5982 gimple_predicate final_pred = rhs_predicate_for (*to_p);
5983 if (final_pred != initial_pred)
5985 ret = gimplify_expr (from_p, pre_p, post_p, final_pred, fb_rvalue);
5986 if (ret == GS_ERROR)
5987 return ret;
5990 /* In case of va_arg internal fn wrappped in a WITH_SIZE_EXPR, add the type
5991 size as argument to the call. */
5992 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
5994 tree call = TREE_OPERAND (*from_p, 0);
5995 tree vlasize = TREE_OPERAND (*from_p, 1);
5997 if (TREE_CODE (call) == CALL_EXPR
5998 && CALL_EXPR_IFN (call) == IFN_VA_ARG)
6000 int nargs = call_expr_nargs (call);
6001 tree type = TREE_TYPE (call);
6002 tree ap = CALL_EXPR_ARG (call, 0);
6003 tree tag = CALL_EXPR_ARG (call, 1);
6004 tree aptag = CALL_EXPR_ARG (call, 2);
6005 tree newcall = build_call_expr_internal_loc (EXPR_LOCATION (call),
6006 IFN_VA_ARG, type,
6007 nargs + 1, ap, tag,
6008 aptag, vlasize);
6009 TREE_OPERAND (*from_p, 0) = newcall;
6013 /* Now see if the above changed *from_p to something we handle specially. */
6014 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
6015 want_value);
6016 if (ret != GS_UNHANDLED)
6017 return ret;
6019 /* If we've got a variable sized assignment between two lvalues (i.e. does
6020 not involve a call), then we can make things a bit more straightforward
6021 by converting the assignment to memcpy or memset. */
6022 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
6024 tree from = TREE_OPERAND (*from_p, 0);
6025 tree size = TREE_OPERAND (*from_p, 1);
6027 if (TREE_CODE (from) == CONSTRUCTOR)
6028 return gimplify_modify_expr_to_memset (expr_p, size, want_value, pre_p);
6030 if (is_gimple_addressable (from))
6032 *from_p = from;
6033 return gimplify_modify_expr_to_memcpy (expr_p, size, want_value,
6034 pre_p);
6038 /* Transform partial stores to non-addressable complex variables into
6039 total stores. This allows us to use real instead of virtual operands
6040 for these variables, which improves optimization. */
6041 if ((TREE_CODE (*to_p) == REALPART_EXPR
6042 || TREE_CODE (*to_p) == IMAGPART_EXPR)
6043 && is_gimple_reg (TREE_OPERAND (*to_p, 0)))
6044 return gimplify_modify_expr_complex_part (expr_p, pre_p, want_value);
6046 /* Try to alleviate the effects of the gimplification creating artificial
6047 temporaries (see for example is_gimple_reg_rhs) on the debug info, but
6048 make sure not to create DECL_DEBUG_EXPR links across functions. */
6049 if (!gimplify_ctxp->into_ssa
6050 && VAR_P (*from_p)
6051 && DECL_IGNORED_P (*from_p)
6052 && DECL_P (*to_p)
6053 && !DECL_IGNORED_P (*to_p)
6054 && decl_function_context (*to_p) == current_function_decl
6055 && decl_function_context (*from_p) == current_function_decl)
6057 if (!DECL_NAME (*from_p) && DECL_NAME (*to_p))
6058 DECL_NAME (*from_p)
6059 = create_tmp_var_name (IDENTIFIER_POINTER (DECL_NAME (*to_p)));
6060 DECL_HAS_DEBUG_EXPR_P (*from_p) = 1;
6061 SET_DECL_DEBUG_EXPR (*from_p, *to_p);
6064 if (want_value && TREE_THIS_VOLATILE (*to_p))
6065 *from_p = get_initialized_tmp_var (*from_p, pre_p, post_p);
6067 if (TREE_CODE (*from_p) == CALL_EXPR)
6069 /* Since the RHS is a CALL_EXPR, we need to create a GIMPLE_CALL
6070 instead of a GIMPLE_ASSIGN. */
6071 gcall *call_stmt;
6072 if (CALL_EXPR_FN (*from_p) == NULL_TREE)
6074 /* Gimplify internal functions created in the FEs. */
6075 int nargs = call_expr_nargs (*from_p), i;
6076 enum internal_fn ifn = CALL_EXPR_IFN (*from_p);
6077 auto_vec<tree> vargs (nargs);
6079 for (i = 0; i < nargs; i++)
6081 gimplify_arg (&CALL_EXPR_ARG (*from_p, i), pre_p,
6082 EXPR_LOCATION (*from_p));
6083 vargs.quick_push (CALL_EXPR_ARG (*from_p, i));
6085 call_stmt = gimple_build_call_internal_vec (ifn, vargs);
6086 gimple_call_set_nothrow (call_stmt, TREE_NOTHROW (*from_p));
6087 gimple_set_location (call_stmt, EXPR_LOCATION (*expr_p));
6089 else
6091 tree fnptrtype = TREE_TYPE (CALL_EXPR_FN (*from_p));
6092 CALL_EXPR_FN (*from_p) = TREE_OPERAND (CALL_EXPR_FN (*from_p), 0);
6093 STRIP_USELESS_TYPE_CONVERSION (CALL_EXPR_FN (*from_p));
6094 tree fndecl = get_callee_fndecl (*from_p);
6095 if (fndecl
6096 && fndecl_built_in_p (fndecl, BUILT_IN_EXPECT)
6097 && call_expr_nargs (*from_p) == 3)
6098 call_stmt = gimple_build_call_internal (IFN_BUILTIN_EXPECT, 3,
6099 CALL_EXPR_ARG (*from_p, 0),
6100 CALL_EXPR_ARG (*from_p, 1),
6101 CALL_EXPR_ARG (*from_p, 2));
6102 else
6104 call_stmt = gimple_build_call_from_tree (*from_p, fnptrtype);
6107 notice_special_calls (call_stmt);
6108 if (!gimple_call_noreturn_p (call_stmt) || !should_remove_lhs_p (*to_p))
6109 gimple_call_set_lhs (call_stmt, *to_p);
6110 else if (TREE_CODE (*to_p) == SSA_NAME)
6111 /* The above is somewhat premature, avoid ICEing later for a
6112 SSA name w/o a definition. We may have uses in the GIMPLE IL.
6113 ??? This doesn't make it a default-def. */
6114 SSA_NAME_DEF_STMT (*to_p) = gimple_build_nop ();
6116 assign = call_stmt;
6118 else
6120 assign = gimple_build_assign (*to_p, *from_p);
6121 gimple_set_location (assign, EXPR_LOCATION (*expr_p));
6122 if (COMPARISON_CLASS_P (*from_p))
6123 copy_warning (assign, *from_p);
6126 if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p))
6128 /* We should have got an SSA name from the start. */
6129 gcc_assert (TREE_CODE (*to_p) == SSA_NAME
6130 || ! gimple_in_ssa_p (cfun));
6133 gimplify_seq_add_stmt (pre_p, assign);
6134 gsi = gsi_last (*pre_p);
6135 maybe_fold_stmt (&gsi);
6137 if (want_value)
6139 *expr_p = TREE_THIS_VOLATILE (*to_p) ? *from_p : unshare_expr (*to_p);
6140 return GS_OK;
6142 else
6143 *expr_p = NULL;
6145 return GS_ALL_DONE;
6148 /* Gimplify a comparison between two variable-sized objects. Do this
6149 with a call to BUILT_IN_MEMCMP. */
6151 static enum gimplify_status
6152 gimplify_variable_sized_compare (tree *expr_p)
6154 location_t loc = EXPR_LOCATION (*expr_p);
6155 tree op0 = TREE_OPERAND (*expr_p, 0);
6156 tree op1 = TREE_OPERAND (*expr_p, 1);
6157 tree t, arg, dest, src, expr;
6159 arg = TYPE_SIZE_UNIT (TREE_TYPE (op0));
6160 arg = unshare_expr (arg);
6161 arg = SUBSTITUTE_PLACEHOLDER_IN_EXPR (arg, op0);
6162 src = build_fold_addr_expr_loc (loc, op1);
6163 dest = build_fold_addr_expr_loc (loc, op0);
6164 t = builtin_decl_implicit (BUILT_IN_MEMCMP);
6165 t = build_call_expr_loc (loc, t, 3, dest, src, arg);
6167 expr
6168 = build2 (TREE_CODE (*expr_p), TREE_TYPE (*expr_p), t, integer_zero_node);
6169 SET_EXPR_LOCATION (expr, loc);
6170 *expr_p = expr;
6172 return GS_OK;
6175 /* Gimplify a comparison between two aggregate objects of integral scalar
6176 mode as a comparison between the bitwise equivalent scalar values. */
6178 static enum gimplify_status
6179 gimplify_scalar_mode_aggregate_compare (tree *expr_p)
6181 location_t loc = EXPR_LOCATION (*expr_p);
6182 tree op0 = TREE_OPERAND (*expr_p, 0);
6183 tree op1 = TREE_OPERAND (*expr_p, 1);
6185 tree type = TREE_TYPE (op0);
6186 tree scalar_type = lang_hooks.types.type_for_mode (TYPE_MODE (type), 1);
6188 op0 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op0);
6189 op1 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op1);
6191 *expr_p
6192 = fold_build2_loc (loc, TREE_CODE (*expr_p), TREE_TYPE (*expr_p), op0, op1);
6194 return GS_OK;
6197 /* Gimplify an expression sequence. This function gimplifies each
6198 expression and rewrites the original expression with the last
6199 expression of the sequence in GIMPLE form.
6201 PRE_P points to the list where the side effects for all the
6202 expressions in the sequence will be emitted.
6204 WANT_VALUE is true when the result of the last COMPOUND_EXPR is used. */
6206 static enum gimplify_status
6207 gimplify_compound_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
6209 tree t = *expr_p;
6213 tree *sub_p = &TREE_OPERAND (t, 0);
6215 if (TREE_CODE (*sub_p) == COMPOUND_EXPR)
6216 gimplify_compound_expr (sub_p, pre_p, false);
6217 else
6218 gimplify_stmt (sub_p, pre_p);
6220 t = TREE_OPERAND (t, 1);
6222 while (TREE_CODE (t) == COMPOUND_EXPR);
6224 *expr_p = t;
6225 if (want_value)
6226 return GS_OK;
6227 else
6229 gimplify_stmt (expr_p, pre_p);
6230 return GS_ALL_DONE;
6234 /* Gimplify a SAVE_EXPR node. EXPR_P points to the expression to
6235 gimplify. After gimplification, EXPR_P will point to a new temporary
6236 that holds the original value of the SAVE_EXPR node.
6238 PRE_P points to the list where side effects that must happen before
6239 *EXPR_P should be stored. */
6241 static enum gimplify_status
6242 gimplify_save_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6244 enum gimplify_status ret = GS_ALL_DONE;
6245 tree val;
6247 gcc_assert (TREE_CODE (*expr_p) == SAVE_EXPR);
6248 val = TREE_OPERAND (*expr_p, 0);
6250 if (TREE_TYPE (val) == error_mark_node)
6251 return GS_ERROR;
6253 /* If the SAVE_EXPR has not been resolved, then evaluate it once. */
6254 if (!SAVE_EXPR_RESOLVED_P (*expr_p))
6256 /* The operand may be a void-valued expression. It is
6257 being executed only for its side-effects. */
6258 if (TREE_TYPE (val) == void_type_node)
6260 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
6261 is_gimple_stmt, fb_none);
6262 val = NULL;
6264 else
6265 /* The temporary may not be an SSA name as later abnormal and EH
6266 control flow may invalidate use/def domination. When in SSA
6267 form then assume there are no such issues and SAVE_EXPRs only
6268 appear via GENERIC foldings. */
6269 val = get_initialized_tmp_var (val, pre_p, post_p,
6270 gimple_in_ssa_p (cfun));
6272 TREE_OPERAND (*expr_p, 0) = val;
6273 SAVE_EXPR_RESOLVED_P (*expr_p) = 1;
6276 *expr_p = val;
6278 return ret;
6281 /* Rewrite the ADDR_EXPR node pointed to by EXPR_P
6283 unary_expr
6284 : ...
6285 | '&' varname
6288 PRE_P points to the list where side effects that must happen before
6289 *EXPR_P should be stored.
6291 POST_P points to the list where side effects that must happen after
6292 *EXPR_P should be stored. */
6294 static enum gimplify_status
6295 gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6297 tree expr = *expr_p;
6298 tree op0 = TREE_OPERAND (expr, 0);
6299 enum gimplify_status ret;
6300 location_t loc = EXPR_LOCATION (*expr_p);
6302 switch (TREE_CODE (op0))
6304 case INDIRECT_REF:
6305 do_indirect_ref:
6306 /* Check if we are dealing with an expression of the form '&*ptr'.
6307 While the front end folds away '&*ptr' into 'ptr', these
6308 expressions may be generated internally by the compiler (e.g.,
6309 builtins like __builtin_va_end). */
6310 /* Caution: the silent array decomposition semantics we allow for
6311 ADDR_EXPR means we can't always discard the pair. */
6312 /* Gimplification of the ADDR_EXPR operand may drop
6313 cv-qualification conversions, so make sure we add them if
6314 needed. */
6316 tree op00 = TREE_OPERAND (op0, 0);
6317 tree t_expr = TREE_TYPE (expr);
6318 tree t_op00 = TREE_TYPE (op00);
6320 if (!useless_type_conversion_p (t_expr, t_op00))
6321 op00 = fold_convert_loc (loc, TREE_TYPE (expr), op00);
6322 *expr_p = op00;
6323 ret = GS_OK;
6325 break;
6327 case VIEW_CONVERT_EXPR:
6328 /* Take the address of our operand and then convert it to the type of
6329 this ADDR_EXPR.
6331 ??? The interactions of VIEW_CONVERT_EXPR and aliasing is not at
6332 all clear. The impact of this transformation is even less clear. */
6334 /* If the operand is a useless conversion, look through it. Doing so
6335 guarantees that the ADDR_EXPR and its operand will remain of the
6336 same type. */
6337 if (tree_ssa_useless_type_conversion (TREE_OPERAND (op0, 0)))
6338 op0 = TREE_OPERAND (op0, 0);
6340 *expr_p = fold_convert_loc (loc, TREE_TYPE (expr),
6341 build_fold_addr_expr_loc (loc,
6342 TREE_OPERAND (op0, 0)));
6343 ret = GS_OK;
6344 break;
6346 case MEM_REF:
6347 if (integer_zerop (TREE_OPERAND (op0, 1)))
6348 goto do_indirect_ref;
6350 /* fall through */
6352 default:
6353 /* If we see a call to a declared builtin or see its address
6354 being taken (we can unify those cases here) then we can mark
6355 the builtin for implicit generation by GCC. */
6356 if (TREE_CODE (op0) == FUNCTION_DECL
6357 && fndecl_built_in_p (op0, BUILT_IN_NORMAL)
6358 && builtin_decl_declared_p (DECL_FUNCTION_CODE (op0)))
6359 set_builtin_decl_implicit_p (DECL_FUNCTION_CODE (op0), true);
6361 /* We use fb_either here because the C frontend sometimes takes
6362 the address of a call that returns a struct; see
6363 gcc.dg/c99-array-lval-1.c. The gimplifier will correctly make
6364 the implied temporary explicit. */
6366 /* Make the operand addressable. */
6367 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, post_p,
6368 is_gimple_addressable, fb_either);
6369 if (ret == GS_ERROR)
6370 break;
6372 /* Then mark it. Beware that it may not be possible to do so directly
6373 if a temporary has been created by the gimplification. */
6374 prepare_gimple_addressable (&TREE_OPERAND (expr, 0), pre_p);
6376 op0 = TREE_OPERAND (expr, 0);
6378 /* For various reasons, the gimplification of the expression
6379 may have made a new INDIRECT_REF. */
6380 if (TREE_CODE (op0) == INDIRECT_REF
6381 || (TREE_CODE (op0) == MEM_REF
6382 && integer_zerop (TREE_OPERAND (op0, 1))))
6383 goto do_indirect_ref;
6385 mark_addressable (TREE_OPERAND (expr, 0));
6387 /* The FEs may end up building ADDR_EXPRs early on a decl with
6388 an incomplete type. Re-build ADDR_EXPRs in canonical form
6389 here. */
6390 if (!types_compatible_p (TREE_TYPE (op0), TREE_TYPE (TREE_TYPE (expr))))
6391 *expr_p = build_fold_addr_expr (op0);
6393 /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly. */
6394 recompute_tree_invariant_for_addr_expr (*expr_p);
6396 /* If we re-built the ADDR_EXPR add a conversion to the original type
6397 if required. */
6398 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
6399 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
6401 break;
6404 return ret;
6407 /* Gimplify the operands of an ASM_EXPR. Input operands should be a gimple
6408 value; output operands should be a gimple lvalue. */
6410 static enum gimplify_status
6411 gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6413 tree expr;
6414 int noutputs;
6415 const char **oconstraints;
6416 int i;
6417 tree link;
6418 const char *constraint;
6419 bool allows_mem, allows_reg, is_inout;
6420 enum gimplify_status ret, tret;
6421 gasm *stmt;
6422 vec<tree, va_gc> *inputs;
6423 vec<tree, va_gc> *outputs;
6424 vec<tree, va_gc> *clobbers;
6425 vec<tree, va_gc> *labels;
6426 tree link_next;
6428 expr = *expr_p;
6429 noutputs = list_length (ASM_OUTPUTS (expr));
6430 oconstraints = (const char **) alloca ((noutputs) * sizeof (const char *));
6432 inputs = NULL;
6433 outputs = NULL;
6434 clobbers = NULL;
6435 labels = NULL;
6437 ret = GS_ALL_DONE;
6438 link_next = NULL_TREE;
6439 for (i = 0, link = ASM_OUTPUTS (expr); link; ++i, link = link_next)
6441 bool ok;
6442 size_t constraint_len;
6444 link_next = TREE_CHAIN (link);
6446 oconstraints[i]
6447 = constraint
6448 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
6449 constraint_len = strlen (constraint);
6450 if (constraint_len == 0)
6451 continue;
6453 ok = parse_output_constraint (&constraint, i, 0, 0,
6454 &allows_mem, &allows_reg, &is_inout);
6455 if (!ok)
6457 ret = GS_ERROR;
6458 is_inout = false;
6461 /* If we can't make copies, we can only accept memory.
6462 Similarly for VLAs. */
6463 tree outtype = TREE_TYPE (TREE_VALUE (link));
6464 if (outtype != error_mark_node
6465 && (TREE_ADDRESSABLE (outtype)
6466 || !COMPLETE_TYPE_P (outtype)
6467 || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (outtype))))
6469 if (allows_mem)
6470 allows_reg = 0;
6471 else
6473 error ("impossible constraint in %<asm%>");
6474 error ("non-memory output %d must stay in memory", i);
6475 return GS_ERROR;
6479 if (!allows_reg && allows_mem)
6480 mark_addressable (TREE_VALUE (link));
6482 tree orig = TREE_VALUE (link);
6483 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6484 is_inout ? is_gimple_min_lval : is_gimple_lvalue,
6485 fb_lvalue | fb_mayfail);
6486 if (tret == GS_ERROR)
6488 if (orig != error_mark_node)
6489 error ("invalid lvalue in %<asm%> output %d", i);
6490 ret = tret;
6493 /* If the constraint does not allow memory make sure we gimplify
6494 it to a register if it is not already but its base is. This
6495 happens for complex and vector components. */
6496 if (!allows_mem)
6498 tree op = TREE_VALUE (link);
6499 if (! is_gimple_val (op)
6500 && is_gimple_reg_type (TREE_TYPE (op))
6501 && is_gimple_reg (get_base_address (op)))
6503 tree tem = create_tmp_reg (TREE_TYPE (op));
6504 tree ass;
6505 if (is_inout)
6507 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem),
6508 tem, unshare_expr (op));
6509 gimplify_and_add (ass, pre_p);
6511 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem), op, tem);
6512 gimplify_and_add (ass, post_p);
6514 TREE_VALUE (link) = tem;
6515 tret = GS_OK;
6519 vec_safe_push (outputs, link);
6520 TREE_CHAIN (link) = NULL_TREE;
6522 if (is_inout)
6524 /* An input/output operand. To give the optimizers more
6525 flexibility, split it into separate input and output
6526 operands. */
6527 tree input;
6528 /* Buffer big enough to format a 32-bit UINT_MAX into. */
6529 char buf[11];
6531 /* Turn the in/out constraint into an output constraint. */
6532 char *p = xstrdup (constraint);
6533 p[0] = '=';
6534 TREE_VALUE (TREE_PURPOSE (link)) = build_string (constraint_len, p);
6536 /* And add a matching input constraint. */
6537 if (allows_reg)
6539 sprintf (buf, "%u", i);
6541 /* If there are multiple alternatives in the constraint,
6542 handle each of them individually. Those that allow register
6543 will be replaced with operand number, the others will stay
6544 unchanged. */
6545 if (strchr (p, ',') != NULL)
6547 size_t len = 0, buflen = strlen (buf);
6548 char *beg, *end, *str, *dst;
6550 for (beg = p + 1;;)
6552 end = strchr (beg, ',');
6553 if (end == NULL)
6554 end = strchr (beg, '\0');
6555 if ((size_t) (end - beg) < buflen)
6556 len += buflen + 1;
6557 else
6558 len += end - beg + 1;
6559 if (*end)
6560 beg = end + 1;
6561 else
6562 break;
6565 str = (char *) alloca (len);
6566 for (beg = p + 1, dst = str;;)
6568 const char *tem;
6569 bool mem_p, reg_p, inout_p;
6571 end = strchr (beg, ',');
6572 if (end)
6573 *end = '\0';
6574 beg[-1] = '=';
6575 tem = beg - 1;
6576 parse_output_constraint (&tem, i, 0, 0,
6577 &mem_p, &reg_p, &inout_p);
6578 if (dst != str)
6579 *dst++ = ',';
6580 if (reg_p)
6582 memcpy (dst, buf, buflen);
6583 dst += buflen;
6585 else
6587 if (end)
6588 len = end - beg;
6589 else
6590 len = strlen (beg);
6591 memcpy (dst, beg, len);
6592 dst += len;
6594 if (end)
6595 beg = end + 1;
6596 else
6597 break;
6599 *dst = '\0';
6600 input = build_string (dst - str, str);
6602 else
6603 input = build_string (strlen (buf), buf);
6605 else
6606 input = build_string (constraint_len - 1, constraint + 1);
6608 free (p);
6610 input = build_tree_list (build_tree_list (NULL_TREE, input),
6611 unshare_expr (TREE_VALUE (link)));
6612 ASM_INPUTS (expr) = chainon (ASM_INPUTS (expr), input);
6616 link_next = NULL_TREE;
6617 for (link = ASM_INPUTS (expr); link; ++i, link = link_next)
6619 link_next = TREE_CHAIN (link);
6620 constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
6621 parse_input_constraint (&constraint, 0, 0, noutputs, 0,
6622 oconstraints, &allows_mem, &allows_reg);
6624 /* If we can't make copies, we can only accept memory. */
6625 tree intype = TREE_TYPE (TREE_VALUE (link));
6626 if (intype != error_mark_node
6627 && (TREE_ADDRESSABLE (intype)
6628 || !COMPLETE_TYPE_P (intype)
6629 || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (intype))))
6631 if (allows_mem)
6632 allows_reg = 0;
6633 else
6635 error ("impossible constraint in %<asm%>");
6636 error ("non-memory input %d must stay in memory", i);
6637 return GS_ERROR;
6641 /* If the operand is a memory input, it should be an lvalue. */
6642 if (!allows_reg && allows_mem)
6644 tree inputv = TREE_VALUE (link);
6645 STRIP_NOPS (inputv);
6646 if (TREE_CODE (inputv) == PREDECREMENT_EXPR
6647 || TREE_CODE (inputv) == PREINCREMENT_EXPR
6648 || TREE_CODE (inputv) == POSTDECREMENT_EXPR
6649 || TREE_CODE (inputv) == POSTINCREMENT_EXPR
6650 || TREE_CODE (inputv) == MODIFY_EXPR)
6651 TREE_VALUE (link) = error_mark_node;
6652 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6653 is_gimple_lvalue, fb_lvalue | fb_mayfail);
6654 if (tret != GS_ERROR)
6656 /* Unlike output operands, memory inputs are not guaranteed
6657 to be lvalues by the FE, and while the expressions are
6658 marked addressable there, if it is e.g. a statement
6659 expression, temporaries in it might not end up being
6660 addressable. They might be already used in the IL and thus
6661 it is too late to make them addressable now though. */
6662 tree x = TREE_VALUE (link);
6663 while (handled_component_p (x))
6664 x = TREE_OPERAND (x, 0);
6665 if (TREE_CODE (x) == MEM_REF
6666 && TREE_CODE (TREE_OPERAND (x, 0)) == ADDR_EXPR)
6667 x = TREE_OPERAND (TREE_OPERAND (x, 0), 0);
6668 if ((VAR_P (x)
6669 || TREE_CODE (x) == PARM_DECL
6670 || TREE_CODE (x) == RESULT_DECL)
6671 && !TREE_ADDRESSABLE (x)
6672 && is_gimple_reg (x))
6674 warning_at (EXPR_LOC_OR_LOC (TREE_VALUE (link),
6675 input_location), 0,
6676 "memory input %d is not directly addressable",
6678 prepare_gimple_addressable (&TREE_VALUE (link), pre_p);
6681 mark_addressable (TREE_VALUE (link));
6682 if (tret == GS_ERROR)
6684 if (inputv != error_mark_node)
6685 error_at (EXPR_LOC_OR_LOC (TREE_VALUE (link), input_location),
6686 "memory input %d is not directly addressable", i);
6687 ret = tret;
6690 else
6692 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6693 is_gimple_asm_val, fb_rvalue);
6694 if (tret == GS_ERROR)
6695 ret = tret;
6698 TREE_CHAIN (link) = NULL_TREE;
6699 vec_safe_push (inputs, link);
6702 link_next = NULL_TREE;
6703 for (link = ASM_CLOBBERS (expr); link; ++i, link = link_next)
6705 link_next = TREE_CHAIN (link);
6706 TREE_CHAIN (link) = NULL_TREE;
6707 vec_safe_push (clobbers, link);
6710 link_next = NULL_TREE;
6711 for (link = ASM_LABELS (expr); link; ++i, link = link_next)
6713 link_next = TREE_CHAIN (link);
6714 TREE_CHAIN (link) = NULL_TREE;
6715 vec_safe_push (labels, link);
6718 /* Do not add ASMs with errors to the gimple IL stream. */
6719 if (ret != GS_ERROR)
6721 stmt = gimple_build_asm_vec (TREE_STRING_POINTER (ASM_STRING (expr)),
6722 inputs, outputs, clobbers, labels);
6724 gimple_asm_set_volatile (stmt, ASM_VOLATILE_P (expr) || noutputs == 0);
6725 gimple_asm_set_input (stmt, ASM_INPUT_P (expr));
6726 gimple_asm_set_inline (stmt, ASM_INLINE_P (expr));
6728 gimplify_seq_add_stmt (pre_p, stmt);
6731 return ret;
6734 /* Gimplify a CLEANUP_POINT_EXPR. Currently this works by adding
6735 GIMPLE_WITH_CLEANUP_EXPRs to the prequeue as we encounter cleanups while
6736 gimplifying the body, and converting them to TRY_FINALLY_EXPRs when we
6737 return to this function.
6739 FIXME should we complexify the prequeue handling instead? Or use flags
6740 for all the cleanups and let the optimizer tighten them up? The current
6741 code seems pretty fragile; it will break on a cleanup within any
6742 non-conditional nesting. But any such nesting would be broken, anyway;
6743 we can't write a TRY_FINALLY_EXPR that starts inside a nesting construct
6744 and continues out of it. We can do that at the RTL level, though, so
6745 having an optimizer to tighten up try/finally regions would be a Good
6746 Thing. */
6748 static enum gimplify_status
6749 gimplify_cleanup_point_expr (tree *expr_p, gimple_seq *pre_p)
6751 gimple_stmt_iterator iter;
6752 gimple_seq body_sequence = NULL;
6754 tree temp = voidify_wrapper_expr (*expr_p, NULL);
6756 /* We only care about the number of conditions between the innermost
6757 CLEANUP_POINT_EXPR and the cleanup. So save and reset the count and
6758 any cleanups collected outside the CLEANUP_POINT_EXPR. */
6759 int old_conds = gimplify_ctxp->conditions;
6760 gimple_seq old_cleanups = gimplify_ctxp->conditional_cleanups;
6761 bool old_in_cleanup_point_expr = gimplify_ctxp->in_cleanup_point_expr;
6762 gimplify_ctxp->conditions = 0;
6763 gimplify_ctxp->conditional_cleanups = NULL;
6764 gimplify_ctxp->in_cleanup_point_expr = true;
6766 gimplify_stmt (&TREE_OPERAND (*expr_p, 0), &body_sequence);
6768 gimplify_ctxp->conditions = old_conds;
6769 gimplify_ctxp->conditional_cleanups = old_cleanups;
6770 gimplify_ctxp->in_cleanup_point_expr = old_in_cleanup_point_expr;
6772 for (iter = gsi_start (body_sequence); !gsi_end_p (iter); )
6774 gimple *wce = gsi_stmt (iter);
6776 if (gimple_code (wce) == GIMPLE_WITH_CLEANUP_EXPR)
6778 if (gsi_one_before_end_p (iter))
6780 /* Note that gsi_insert_seq_before and gsi_remove do not
6781 scan operands, unlike some other sequence mutators. */
6782 if (!gimple_wce_cleanup_eh_only (wce))
6783 gsi_insert_seq_before_without_update (&iter,
6784 gimple_wce_cleanup (wce),
6785 GSI_SAME_STMT);
6786 gsi_remove (&iter, true);
6787 break;
6789 else
6791 gtry *gtry;
6792 gimple_seq seq;
6793 enum gimple_try_flags kind;
6795 if (gimple_wce_cleanup_eh_only (wce))
6796 kind = GIMPLE_TRY_CATCH;
6797 else
6798 kind = GIMPLE_TRY_FINALLY;
6799 seq = gsi_split_seq_after (iter);
6801 gtry = gimple_build_try (seq, gimple_wce_cleanup (wce), kind);
6802 /* Do not use gsi_replace here, as it may scan operands.
6803 We want to do a simple structural modification only. */
6804 gsi_set_stmt (&iter, gtry);
6805 iter = gsi_start (gtry->eval);
6808 else
6809 gsi_next (&iter);
6812 gimplify_seq_add_seq (pre_p, body_sequence);
6813 if (temp)
6815 *expr_p = temp;
6816 return GS_OK;
6818 else
6820 *expr_p = NULL;
6821 return GS_ALL_DONE;
6825 /* Insert a cleanup marker for gimplify_cleanup_point_expr. CLEANUP
6826 is the cleanup action required. EH_ONLY is true if the cleanup should
6827 only be executed if an exception is thrown, not on normal exit.
6828 If FORCE_UNCOND is true perform the cleanup unconditionally; this is
6829 only valid for clobbers. */
6831 static void
6832 gimple_push_cleanup (tree var, tree cleanup, bool eh_only, gimple_seq *pre_p,
6833 bool force_uncond = false)
6835 gimple *wce;
6836 gimple_seq cleanup_stmts = NULL;
6838 /* Errors can result in improperly nested cleanups. Which results in
6839 confusion when trying to resolve the GIMPLE_WITH_CLEANUP_EXPR. */
6840 if (seen_error ())
6841 return;
6843 if (gimple_conditional_context ())
6845 /* If we're in a conditional context, this is more complex. We only
6846 want to run the cleanup if we actually ran the initialization that
6847 necessitates it, but we want to run it after the end of the
6848 conditional context. So we wrap the try/finally around the
6849 condition and use a flag to determine whether or not to actually
6850 run the destructor. Thus
6852 test ? f(A()) : 0
6854 becomes (approximately)
6856 flag = 0;
6857 try {
6858 if (test) { A::A(temp); flag = 1; val = f(temp); }
6859 else { val = 0; }
6860 } finally {
6861 if (flag) A::~A(temp);
6865 if (force_uncond)
6867 gimplify_stmt (&cleanup, &cleanup_stmts);
6868 wce = gimple_build_wce (cleanup_stmts);
6869 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
6871 else
6873 tree flag = create_tmp_var (boolean_type_node, "cleanup");
6874 gassign *ffalse = gimple_build_assign (flag, boolean_false_node);
6875 gassign *ftrue = gimple_build_assign (flag, boolean_true_node);
6877 cleanup = build3 (COND_EXPR, void_type_node, flag, cleanup, NULL);
6878 gimplify_stmt (&cleanup, &cleanup_stmts);
6879 wce = gimple_build_wce (cleanup_stmts);
6881 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, ffalse);
6882 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
6883 gimplify_seq_add_stmt (pre_p, ftrue);
6885 /* Because of this manipulation, and the EH edges that jump
6886 threading cannot redirect, the temporary (VAR) will appear
6887 to be used uninitialized. Don't warn. */
6888 suppress_warning (var, OPT_Wuninitialized);
6891 else
6893 gimplify_stmt (&cleanup, &cleanup_stmts);
6894 wce = gimple_build_wce (cleanup_stmts);
6895 gimple_wce_set_cleanup_eh_only (wce, eh_only);
6896 gimplify_seq_add_stmt (pre_p, wce);
6900 /* Gimplify a TARGET_EXPR which doesn't appear on the rhs of an INIT_EXPR. */
6902 static enum gimplify_status
6903 gimplify_target_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6905 tree targ = *expr_p;
6906 tree temp = TARGET_EXPR_SLOT (targ);
6907 tree init = TARGET_EXPR_INITIAL (targ);
6908 enum gimplify_status ret;
6910 bool unpoison_empty_seq = false;
6911 gimple_stmt_iterator unpoison_it;
6913 if (init)
6915 tree cleanup = NULL_TREE;
6917 /* TARGET_EXPR temps aren't part of the enclosing block, so add it
6918 to the temps list. Handle also variable length TARGET_EXPRs. */
6919 if (!poly_int_tree_p (DECL_SIZE (temp)))
6921 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (temp)))
6922 gimplify_type_sizes (TREE_TYPE (temp), pre_p);
6923 /* FIXME: this is correct only when the size of the type does
6924 not depend on expressions evaluated in init. */
6925 gimplify_vla_decl (temp, pre_p);
6927 else
6929 /* Save location where we need to place unpoisoning. It's possible
6930 that a variable will be converted to needs_to_live_in_memory. */
6931 unpoison_it = gsi_last (*pre_p);
6932 unpoison_empty_seq = gsi_end_p (unpoison_it);
6934 gimple_add_tmp_var (temp);
6937 /* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the
6938 expression is supposed to initialize the slot. */
6939 if (VOID_TYPE_P (TREE_TYPE (init)))
6940 ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
6941 else
6943 tree init_expr = build2 (INIT_EXPR, void_type_node, temp, init);
6944 init = init_expr;
6945 ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
6946 init = NULL;
6947 ggc_free (init_expr);
6949 if (ret == GS_ERROR)
6951 /* PR c++/28266 Make sure this is expanded only once. */
6952 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
6953 return GS_ERROR;
6955 if (init)
6956 gimplify_and_add (init, pre_p);
6958 /* If needed, push the cleanup for the temp. */
6959 if (TARGET_EXPR_CLEANUP (targ))
6961 if (CLEANUP_EH_ONLY (targ))
6962 gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ),
6963 CLEANUP_EH_ONLY (targ), pre_p);
6964 else
6965 cleanup = TARGET_EXPR_CLEANUP (targ);
6968 /* Add a clobber for the temporary going out of scope, like
6969 gimplify_bind_expr. */
6970 if (gimplify_ctxp->in_cleanup_point_expr
6971 && needs_to_live_in_memory (temp))
6973 if (flag_stack_reuse == SR_ALL)
6975 tree clobber = build_clobber (TREE_TYPE (temp));
6976 clobber = build2 (MODIFY_EXPR, TREE_TYPE (temp), temp, clobber);
6977 gimple_push_cleanup (temp, clobber, false, pre_p, true);
6979 if (asan_poisoned_variables
6980 && DECL_ALIGN (temp) <= MAX_SUPPORTED_STACK_ALIGNMENT
6981 && !TREE_STATIC (temp)
6982 && dbg_cnt (asan_use_after_scope)
6983 && !gimplify_omp_ctxp)
6985 tree asan_cleanup = build_asan_poison_call_expr (temp);
6986 if (asan_cleanup)
6988 if (unpoison_empty_seq)
6989 unpoison_it = gsi_start (*pre_p);
6991 asan_poison_variable (temp, false, &unpoison_it,
6992 unpoison_empty_seq);
6993 gimple_push_cleanup (temp, asan_cleanup, false, pre_p);
6997 if (cleanup)
6998 gimple_push_cleanup (temp, cleanup, false, pre_p);
7000 /* Only expand this once. */
7001 TREE_OPERAND (targ, 3) = init;
7002 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
7004 else
7005 /* We should have expanded this before. */
7006 gcc_assert (DECL_SEEN_IN_BIND_EXPR_P (temp));
7008 *expr_p = temp;
7009 return GS_OK;
7012 /* Gimplification of expression trees. */
7014 /* Gimplify an expression which appears at statement context. The
7015 corresponding GIMPLE statements are added to *SEQ_P. If *SEQ_P is
7016 NULL, a new sequence is allocated.
7018 Return true if we actually added a statement to the queue. */
7020 bool
7021 gimplify_stmt (tree *stmt_p, gimple_seq *seq_p)
7023 gimple_seq_node last;
7025 last = gimple_seq_last (*seq_p);
7026 gimplify_expr (stmt_p, seq_p, NULL, is_gimple_stmt, fb_none);
7027 return last != gimple_seq_last (*seq_p);
7030 /* Add FIRSTPRIVATE entries for DECL in the OpenMP the surrounding parallels
7031 to CTX. If entries already exist, force them to be some flavor of private.
7032 If there is no enclosing parallel, do nothing. */
7034 void
7035 omp_firstprivatize_variable (struct gimplify_omp_ctx *ctx, tree decl)
7037 splay_tree_node n;
7039 if (decl == NULL || !DECL_P (decl) || ctx->region_type == ORT_NONE)
7040 return;
7044 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7045 if (n != NULL)
7047 if (n->value & GOVD_SHARED)
7048 n->value = GOVD_FIRSTPRIVATE | (n->value & GOVD_SEEN);
7049 else if (n->value & GOVD_MAP)
7050 n->value |= GOVD_MAP_TO_ONLY;
7051 else
7052 return;
7054 else if ((ctx->region_type & ORT_TARGET) != 0)
7056 if (ctx->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE)
7057 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
7058 else
7059 omp_add_variable (ctx, decl, GOVD_MAP | GOVD_MAP_TO_ONLY);
7061 else if (ctx->region_type != ORT_WORKSHARE
7062 && ctx->region_type != ORT_TASKGROUP
7063 && ctx->region_type != ORT_SIMD
7064 && ctx->region_type != ORT_ACC
7065 && !(ctx->region_type & ORT_TARGET_DATA))
7066 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
7068 ctx = ctx->outer_context;
7070 while (ctx);
7073 /* Similarly for each of the type sizes of TYPE. */
7075 static void
7076 omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type)
7078 if (type == NULL || type == error_mark_node)
7079 return;
7080 type = TYPE_MAIN_VARIANT (type);
7082 if (ctx->privatized_types->add (type))
7083 return;
7085 switch (TREE_CODE (type))
7087 case INTEGER_TYPE:
7088 case ENUMERAL_TYPE:
7089 case BOOLEAN_TYPE:
7090 case REAL_TYPE:
7091 case FIXED_POINT_TYPE:
7092 omp_firstprivatize_variable (ctx, TYPE_MIN_VALUE (type));
7093 omp_firstprivatize_variable (ctx, TYPE_MAX_VALUE (type));
7094 break;
7096 case ARRAY_TYPE:
7097 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
7098 omp_firstprivatize_type_sizes (ctx, TYPE_DOMAIN (type));
7099 break;
7101 case RECORD_TYPE:
7102 case UNION_TYPE:
7103 case QUAL_UNION_TYPE:
7105 tree field;
7106 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
7107 if (TREE_CODE (field) == FIELD_DECL)
7109 omp_firstprivatize_variable (ctx, DECL_FIELD_OFFSET (field));
7110 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (field));
7113 break;
7115 case POINTER_TYPE:
7116 case REFERENCE_TYPE:
7117 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
7118 break;
7120 default:
7121 break;
7124 omp_firstprivatize_variable (ctx, TYPE_SIZE (type));
7125 omp_firstprivatize_variable (ctx, TYPE_SIZE_UNIT (type));
7126 lang_hooks.types.omp_firstprivatize_type_sizes (ctx, type);
7129 /* Add an entry for DECL in the OMP context CTX with FLAGS. */
7131 static void
7132 omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
7134 splay_tree_node n;
7135 unsigned int nflags;
7136 tree t;
7138 if (error_operand_p (decl) || ctx->region_type == ORT_NONE)
7139 return;
7141 /* Never elide decls whose type has TREE_ADDRESSABLE set. This means
7142 there are constructors involved somewhere. Exception is a shared clause,
7143 there is nothing privatized in that case. */
7144 if ((flags & GOVD_SHARED) == 0
7145 && (TREE_ADDRESSABLE (TREE_TYPE (decl))
7146 || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))))
7147 flags |= GOVD_SEEN;
7149 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7150 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
7152 /* We shouldn't be re-adding the decl with the same data
7153 sharing class. */
7154 gcc_assert ((n->value & GOVD_DATA_SHARE_CLASS & flags) == 0);
7155 nflags = n->value | flags;
7156 /* The only combination of data sharing classes we should see is
7157 FIRSTPRIVATE and LASTPRIVATE. However, OpenACC permits
7158 reduction variables to be used in data sharing clauses. */
7159 gcc_assert ((ctx->region_type & ORT_ACC) != 0
7160 || ((nflags & GOVD_DATA_SHARE_CLASS)
7161 == (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE))
7162 || (flags & GOVD_DATA_SHARE_CLASS) == 0);
7163 n->value = nflags;
7164 return;
7167 /* When adding a variable-sized variable, we have to handle all sorts
7168 of additional bits of data: the pointer replacement variable, and
7169 the parameters of the type. */
7170 if (DECL_SIZE (decl) && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
7172 /* Add the pointer replacement variable as PRIVATE if the variable
7173 replacement is private, else FIRSTPRIVATE since we'll need the
7174 address of the original variable either for SHARED, or for the
7175 copy into or out of the context. */
7176 if (!(flags & GOVD_LOCAL) && ctx->region_type != ORT_TASKGROUP)
7178 if (flags & GOVD_MAP)
7179 nflags = GOVD_MAP | GOVD_MAP_TO_ONLY | GOVD_EXPLICIT;
7180 else if (flags & GOVD_PRIVATE)
7181 nflags = GOVD_PRIVATE;
7182 else if (((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
7183 && (flags & GOVD_FIRSTPRIVATE))
7184 || (ctx->region_type == ORT_TARGET_DATA
7185 && (flags & GOVD_DATA_SHARE_CLASS) == 0))
7186 nflags = GOVD_PRIVATE | GOVD_EXPLICIT;
7187 else
7188 nflags = GOVD_FIRSTPRIVATE;
7189 nflags |= flags & GOVD_SEEN;
7190 t = DECL_VALUE_EXPR (decl);
7191 gcc_assert (TREE_CODE (t) == INDIRECT_REF);
7192 t = TREE_OPERAND (t, 0);
7193 gcc_assert (DECL_P (t));
7194 omp_add_variable (ctx, t, nflags);
7197 /* Add all of the variable and type parameters (which should have
7198 been gimplified to a formal temporary) as FIRSTPRIVATE. */
7199 omp_firstprivatize_variable (ctx, DECL_SIZE_UNIT (decl));
7200 omp_firstprivatize_variable (ctx, DECL_SIZE (decl));
7201 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
7203 /* The variable-sized variable itself is never SHARED, only some form
7204 of PRIVATE. The sharing would take place via the pointer variable
7205 which we remapped above. */
7206 if (flags & GOVD_SHARED)
7207 flags = GOVD_SHARED | GOVD_DEBUG_PRIVATE
7208 | (flags & (GOVD_SEEN | GOVD_EXPLICIT));
7210 /* We're going to make use of the TYPE_SIZE_UNIT at least in the
7211 alloca statement we generate for the variable, so make sure it
7212 is available. This isn't automatically needed for the SHARED
7213 case, since we won't be allocating local storage then.
7214 For local variables TYPE_SIZE_UNIT might not be gimplified yet,
7215 in this case omp_notice_variable will be called later
7216 on when it is gimplified. */
7217 else if (! (flags & (GOVD_LOCAL | GOVD_MAP))
7218 && DECL_P (TYPE_SIZE_UNIT (TREE_TYPE (decl))))
7219 omp_notice_variable (ctx, TYPE_SIZE_UNIT (TREE_TYPE (decl)), true);
7221 else if ((flags & (GOVD_MAP | GOVD_LOCAL)) == 0
7222 && omp_privatize_by_reference (decl))
7224 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
7226 /* Similar to the direct variable sized case above, we'll need the
7227 size of references being privatized. */
7228 if ((flags & GOVD_SHARED) == 0)
7230 t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
7231 if (t && DECL_P (t))
7232 omp_notice_variable (ctx, t, true);
7236 if (n != NULL)
7237 n->value |= flags;
7238 else
7239 splay_tree_insert (ctx->variables, (splay_tree_key)decl, flags);
7241 /* For reductions clauses in OpenACC loop directives, by default create a
7242 copy clause on the enclosing parallel construct for carrying back the
7243 results. */
7244 if (ctx->region_type == ORT_ACC && (flags & GOVD_REDUCTION))
7246 struct gimplify_omp_ctx *outer_ctx = ctx->outer_context;
7247 while (outer_ctx)
7249 n = splay_tree_lookup (outer_ctx->variables, (splay_tree_key)decl);
7250 if (n != NULL)
7252 /* Ignore local variables and explicitly declared clauses. */
7253 if (n->value & (GOVD_LOCAL | GOVD_EXPLICIT))
7254 break;
7255 else if (outer_ctx->region_type == ORT_ACC_KERNELS)
7257 /* According to the OpenACC spec, such a reduction variable
7258 should already have a copy map on a kernels construct,
7259 verify that here. */
7260 gcc_assert (!(n->value & GOVD_FIRSTPRIVATE)
7261 && (n->value & GOVD_MAP));
7263 else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
7265 /* Remove firstprivate and make it a copy map. */
7266 n->value &= ~GOVD_FIRSTPRIVATE;
7267 n->value |= GOVD_MAP;
7270 else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
7272 splay_tree_insert (outer_ctx->variables, (splay_tree_key)decl,
7273 GOVD_MAP | GOVD_SEEN);
7274 break;
7276 outer_ctx = outer_ctx->outer_context;
7281 /* Notice a threadprivate variable DECL used in OMP context CTX.
7282 This just prints out diagnostics about threadprivate variable uses
7283 in untied tasks. If DECL2 is non-NULL, prevent this warning
7284 on that variable. */
7286 static bool
7287 omp_notice_threadprivate_variable (struct gimplify_omp_ctx *ctx, tree decl,
7288 tree decl2)
7290 splay_tree_node n;
7291 struct gimplify_omp_ctx *octx;
7293 for (octx = ctx; octx; octx = octx->outer_context)
7294 if ((octx->region_type & ORT_TARGET) != 0
7295 || octx->order_concurrent)
7297 n = splay_tree_lookup (octx->variables, (splay_tree_key)decl);
7298 if (n == NULL)
7300 if (octx->order_concurrent)
7302 error ("threadprivate variable %qE used in a region with"
7303 " %<order(concurrent)%> clause", DECL_NAME (decl));
7304 inform (octx->location, "enclosing region");
7306 else
7308 error ("threadprivate variable %qE used in target region",
7309 DECL_NAME (decl));
7310 inform (octx->location, "enclosing target region");
7312 splay_tree_insert (octx->variables, (splay_tree_key)decl, 0);
7314 if (decl2)
7315 splay_tree_insert (octx->variables, (splay_tree_key)decl2, 0);
7318 if (ctx->region_type != ORT_UNTIED_TASK)
7319 return false;
7320 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7321 if (n == NULL)
7323 error ("threadprivate variable %qE used in untied task",
7324 DECL_NAME (decl));
7325 inform (ctx->location, "enclosing task");
7326 splay_tree_insert (ctx->variables, (splay_tree_key)decl, 0);
7328 if (decl2)
7329 splay_tree_insert (ctx->variables, (splay_tree_key)decl2, 0);
7330 return false;
7333 /* Return true if global var DECL is device resident. */
7335 static bool
7336 device_resident_p (tree decl)
7338 tree attr = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (decl));
7340 if (!attr)
7341 return false;
7343 for (tree t = TREE_VALUE (attr); t; t = TREE_PURPOSE (t))
7345 tree c = TREE_VALUE (t);
7346 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DEVICE_RESIDENT)
7347 return true;
7350 return false;
7353 /* Return true if DECL has an ACC DECLARE attribute. */
7355 static bool
7356 is_oacc_declared (tree decl)
7358 tree t = TREE_CODE (decl) == MEM_REF ? TREE_OPERAND (decl, 0) : decl;
7359 tree declared = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (t));
7360 return declared != NULL_TREE;
7363 /* Determine outer default flags for DECL mentioned in an OMP region
7364 but not declared in an enclosing clause.
7366 ??? Some compiler-generated variables (like SAVE_EXPRs) could be
7367 remapped firstprivate instead of shared. To some extent this is
7368 addressed in omp_firstprivatize_type_sizes, but not
7369 effectively. */
7371 static unsigned
7372 omp_default_clause (struct gimplify_omp_ctx *ctx, tree decl,
7373 bool in_code, unsigned flags)
7375 enum omp_clause_default_kind default_kind = ctx->default_kind;
7376 enum omp_clause_default_kind kind;
7378 kind = lang_hooks.decls.omp_predetermined_sharing (decl);
7379 if (ctx->region_type & ORT_TASK)
7381 tree detach_clause = omp_find_clause (ctx->clauses, OMP_CLAUSE_DETACH);
7383 /* The event-handle specified by a detach clause should always be firstprivate,
7384 regardless of the current default. */
7385 if (detach_clause && OMP_CLAUSE_DECL (detach_clause) == decl)
7386 kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
7388 if (kind != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
7389 default_kind = kind;
7390 else if (VAR_P (decl) && TREE_STATIC (decl) && DECL_IN_CONSTANT_POOL (decl))
7391 default_kind = OMP_CLAUSE_DEFAULT_SHARED;
7392 /* For C/C++ default({,first}private), variables with static storage duration
7393 declared in a namespace or global scope and referenced in construct
7394 must be explicitly specified, i.e. acts as default(none). */
7395 else if ((default_kind == OMP_CLAUSE_DEFAULT_PRIVATE
7396 || default_kind == OMP_CLAUSE_DEFAULT_FIRSTPRIVATE)
7397 && VAR_P (decl)
7398 && is_global_var (decl)
7399 && (DECL_FILE_SCOPE_P (decl)
7400 || (DECL_CONTEXT (decl)
7401 && TREE_CODE (DECL_CONTEXT (decl)) == NAMESPACE_DECL))
7402 && !lang_GNU_Fortran ())
7403 default_kind = OMP_CLAUSE_DEFAULT_NONE;
7405 switch (default_kind)
7407 case OMP_CLAUSE_DEFAULT_NONE:
7409 const char *rtype;
7411 if (ctx->region_type & ORT_PARALLEL)
7412 rtype = "parallel";
7413 else if ((ctx->region_type & ORT_TASKLOOP) == ORT_TASKLOOP)
7414 rtype = "taskloop";
7415 else if (ctx->region_type & ORT_TASK)
7416 rtype = "task";
7417 else if (ctx->region_type & ORT_TEAMS)
7418 rtype = "teams";
7419 else
7420 gcc_unreachable ();
7422 error ("%qE not specified in enclosing %qs",
7423 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rtype);
7424 inform (ctx->location, "enclosing %qs", rtype);
7426 /* FALLTHRU */
7427 case OMP_CLAUSE_DEFAULT_SHARED:
7428 flags |= GOVD_SHARED;
7429 break;
7430 case OMP_CLAUSE_DEFAULT_PRIVATE:
7431 flags |= GOVD_PRIVATE;
7432 break;
7433 case OMP_CLAUSE_DEFAULT_FIRSTPRIVATE:
7434 flags |= GOVD_FIRSTPRIVATE;
7435 break;
7436 case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
7437 /* decl will be either GOVD_FIRSTPRIVATE or GOVD_SHARED. */
7438 gcc_assert ((ctx->region_type & ORT_TASK) != 0);
7439 if (struct gimplify_omp_ctx *octx = ctx->outer_context)
7441 omp_notice_variable (octx, decl, in_code);
7442 for (; octx; octx = octx->outer_context)
7444 splay_tree_node n2;
7446 n2 = splay_tree_lookup (octx->variables, (splay_tree_key) decl);
7447 if ((octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)) != 0
7448 && (n2 == NULL || (n2->value & GOVD_DATA_SHARE_CLASS) == 0))
7449 continue;
7450 if (n2 && (n2->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED)
7452 flags |= GOVD_FIRSTPRIVATE;
7453 goto found_outer;
7455 if ((octx->region_type & (ORT_PARALLEL | ORT_TEAMS)) != 0)
7457 flags |= GOVD_SHARED;
7458 goto found_outer;
7463 if (TREE_CODE (decl) == PARM_DECL
7464 || (!is_global_var (decl)
7465 && DECL_CONTEXT (decl) == current_function_decl))
7466 flags |= GOVD_FIRSTPRIVATE;
7467 else
7468 flags |= GOVD_SHARED;
7469 found_outer:
7470 break;
7472 default:
7473 gcc_unreachable ();
7476 return flags;
7480 /* Determine outer default flags for DECL mentioned in an OACC region
7481 but not declared in an enclosing clause. */
7483 static unsigned
7484 oacc_default_clause (struct gimplify_omp_ctx *ctx, tree decl, unsigned flags)
7486 const char *rkind;
7487 bool on_device = false;
7488 bool is_private = false;
7489 bool declared = is_oacc_declared (decl);
7490 tree type = TREE_TYPE (decl);
7492 if (omp_privatize_by_reference (decl))
7493 type = TREE_TYPE (type);
7495 /* For Fortran COMMON blocks, only used variables in those blocks are
7496 transfered and remapped. The block itself will have a private clause to
7497 avoid transfering the data twice.
7498 The hook evaluates to false by default. For a variable in Fortran's COMMON
7499 or EQUIVALENCE block, returns 'true' (as we have shared=false) - as only
7500 the variables in such a COMMON/EQUIVALENCE block shall be privatized not
7501 the whole block. For C++ and Fortran, it can also be true under certain
7502 other conditions, if DECL_HAS_VALUE_EXPR. */
7503 if (RECORD_OR_UNION_TYPE_P (type))
7504 is_private = lang_hooks.decls.omp_disregard_value_expr (decl, false);
7506 if ((ctx->region_type & (ORT_ACC_PARALLEL | ORT_ACC_KERNELS)) != 0
7507 && is_global_var (decl)
7508 && device_resident_p (decl)
7509 && !is_private)
7511 on_device = true;
7512 flags |= GOVD_MAP_TO_ONLY;
7515 switch (ctx->region_type)
7517 case ORT_ACC_KERNELS:
7518 rkind = "kernels";
7520 if (is_private)
7521 flags |= GOVD_FIRSTPRIVATE;
7522 else if (AGGREGATE_TYPE_P (type))
7524 /* Aggregates default to 'present_or_copy', or 'present'. */
7525 if (ctx->default_kind != OMP_CLAUSE_DEFAULT_PRESENT)
7526 flags |= GOVD_MAP;
7527 else
7528 flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
7530 else
7531 /* Scalars default to 'copy'. */
7532 flags |= GOVD_MAP | GOVD_MAP_FORCE;
7534 break;
7536 case ORT_ACC_PARALLEL:
7537 case ORT_ACC_SERIAL:
7538 rkind = ctx->region_type == ORT_ACC_PARALLEL ? "parallel" : "serial";
7540 if (is_private)
7541 flags |= GOVD_FIRSTPRIVATE;
7542 else if (on_device || declared)
7543 flags |= GOVD_MAP;
7544 else if (AGGREGATE_TYPE_P (type))
7546 /* Aggregates default to 'present_or_copy', or 'present'. */
7547 if (ctx->default_kind != OMP_CLAUSE_DEFAULT_PRESENT)
7548 flags |= GOVD_MAP;
7549 else
7550 flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
7552 else
7553 /* Scalars default to 'firstprivate'. */
7554 flags |= GOVD_FIRSTPRIVATE;
7556 break;
7558 default:
7559 gcc_unreachable ();
7562 if (DECL_ARTIFICIAL (decl))
7563 ; /* We can get compiler-generated decls, and should not complain
7564 about them. */
7565 else if (ctx->default_kind == OMP_CLAUSE_DEFAULT_NONE)
7567 error ("%qE not specified in enclosing OpenACC %qs construct",
7568 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rkind);
7569 inform (ctx->location, "enclosing OpenACC %qs construct", rkind);
7571 else if (ctx->default_kind == OMP_CLAUSE_DEFAULT_PRESENT)
7572 ; /* Handled above. */
7573 else
7574 gcc_checking_assert (ctx->default_kind == OMP_CLAUSE_DEFAULT_SHARED);
7576 return flags;
7579 /* Record the fact that DECL was used within the OMP context CTX.
7580 IN_CODE is true when real code uses DECL, and false when we should
7581 merely emit default(none) errors. Return true if DECL is going to
7582 be remapped and thus DECL shouldn't be gimplified into its
7583 DECL_VALUE_EXPR (if any). */
7585 static bool
7586 omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
7588 splay_tree_node n;
7589 unsigned flags = in_code ? GOVD_SEEN : 0;
7590 bool ret = false, shared;
7592 if (error_operand_p (decl))
7593 return false;
7595 if (ctx->region_type == ORT_NONE)
7596 return lang_hooks.decls.omp_disregard_value_expr (decl, false);
7598 if (is_global_var (decl))
7600 /* Threadprivate variables are predetermined. */
7601 if (DECL_THREAD_LOCAL_P (decl))
7602 return omp_notice_threadprivate_variable (ctx, decl, NULL_TREE);
7604 if (DECL_HAS_VALUE_EXPR_P (decl))
7606 if (ctx->region_type & ORT_ACC)
7607 /* For OpenACC, defer expansion of value to avoid transfering
7608 privatized common block data instead of im-/explicitly transfered
7609 variables which are in common blocks. */
7611 else
7613 tree value = get_base_address (DECL_VALUE_EXPR (decl));
7615 if (value && DECL_P (value) && DECL_THREAD_LOCAL_P (value))
7616 return omp_notice_threadprivate_variable (ctx, decl, value);
7620 if (gimplify_omp_ctxp->outer_context == NULL
7621 && VAR_P (decl)
7622 && oacc_get_fn_attrib (current_function_decl))
7624 location_t loc = DECL_SOURCE_LOCATION (decl);
7626 if (lookup_attribute ("omp declare target link",
7627 DECL_ATTRIBUTES (decl)))
7629 error_at (loc,
7630 "%qE with %<link%> clause used in %<routine%> function",
7631 DECL_NAME (decl));
7632 return false;
7634 else if (!lookup_attribute ("omp declare target",
7635 DECL_ATTRIBUTES (decl)))
7637 error_at (loc,
7638 "%qE requires a %<declare%> directive for use "
7639 "in a %<routine%> function", DECL_NAME (decl));
7640 return false;
7645 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7646 if ((ctx->region_type & ORT_TARGET) != 0)
7648 if (ctx->region_type & ORT_ACC)
7649 /* For OpenACC, as remarked above, defer expansion. */
7650 shared = false;
7651 else
7652 shared = true;
7654 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7655 if (n == NULL)
7657 unsigned nflags = flags;
7658 if ((ctx->region_type & ORT_ACC) == 0)
7660 bool is_declare_target = false;
7661 if (is_global_var (decl)
7662 && varpool_node::get_create (decl)->offloadable)
7664 struct gimplify_omp_ctx *octx;
7665 for (octx = ctx->outer_context;
7666 octx; octx = octx->outer_context)
7668 n = splay_tree_lookup (octx->variables,
7669 (splay_tree_key)decl);
7670 if (n
7671 && (n->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED
7672 && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
7673 break;
7675 is_declare_target = octx == NULL;
7677 if (!is_declare_target)
7679 int gdmk;
7680 enum omp_clause_defaultmap_kind kind;
7681 if (lang_hooks.decls.omp_allocatable_p (decl))
7682 gdmk = GDMK_ALLOCATABLE;
7683 else if (lang_hooks.decls.omp_scalar_target_p (decl))
7684 gdmk = GDMK_SCALAR_TARGET;
7685 else if (lang_hooks.decls.omp_scalar_p (decl, false))
7686 gdmk = GDMK_SCALAR;
7687 else if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
7688 || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
7689 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
7690 == POINTER_TYPE)))
7691 gdmk = GDMK_POINTER;
7692 else
7693 gdmk = GDMK_AGGREGATE;
7694 kind = lang_hooks.decls.omp_predetermined_mapping (decl);
7695 if (kind != OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
7697 if (kind == OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE)
7698 nflags |= GOVD_FIRSTPRIVATE;
7699 else if (kind == OMP_CLAUSE_DEFAULTMAP_TO)
7700 nflags |= GOVD_MAP | GOVD_MAP_TO_ONLY;
7701 else
7702 gcc_unreachable ();
7704 else if (ctx->defaultmap[gdmk] == 0)
7706 tree d = lang_hooks.decls.omp_report_decl (decl);
7707 error ("%qE not specified in enclosing %<target%>",
7708 DECL_NAME (d));
7709 inform (ctx->location, "enclosing %<target%>");
7711 else if (ctx->defaultmap[gdmk]
7712 & (GOVD_MAP_0LEN_ARRAY | GOVD_FIRSTPRIVATE))
7713 nflags |= ctx->defaultmap[gdmk];
7714 else
7716 gcc_assert (ctx->defaultmap[gdmk] & GOVD_MAP);
7717 nflags |= ctx->defaultmap[gdmk] & ~GOVD_MAP;
7722 struct gimplify_omp_ctx *octx = ctx->outer_context;
7723 if ((ctx->region_type & ORT_ACC) && octx)
7725 /* Look in outer OpenACC contexts, to see if there's a
7726 data attribute for this variable. */
7727 omp_notice_variable (octx, decl, in_code);
7729 for (; octx; octx = octx->outer_context)
7731 if (!(octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)))
7732 break;
7733 splay_tree_node n2
7734 = splay_tree_lookup (octx->variables,
7735 (splay_tree_key) decl);
7736 if (n2)
7738 if (octx->region_type == ORT_ACC_HOST_DATA)
7739 error ("variable %qE declared in enclosing "
7740 "%<host_data%> region", DECL_NAME (decl));
7741 nflags |= GOVD_MAP;
7742 if (octx->region_type == ORT_ACC_DATA
7743 && (n2->value & GOVD_MAP_0LEN_ARRAY))
7744 nflags |= GOVD_MAP_0LEN_ARRAY;
7745 goto found_outer;
7750 if ((nflags & ~(GOVD_MAP_TO_ONLY | GOVD_MAP_FROM_ONLY
7751 | GOVD_MAP_ALLOC_ONLY)) == flags)
7753 tree type = TREE_TYPE (decl);
7755 if (gimplify_omp_ctxp->target_firstprivatize_array_bases
7756 && omp_privatize_by_reference (decl))
7757 type = TREE_TYPE (type);
7758 if (!lang_hooks.types.omp_mappable_type (type))
7760 error ("%qD referenced in target region does not have "
7761 "a mappable type", decl);
7762 nflags |= GOVD_MAP | GOVD_EXPLICIT;
7764 else
7766 if ((ctx->region_type & ORT_ACC) != 0)
7767 nflags = oacc_default_clause (ctx, decl, flags);
7768 else
7769 nflags |= GOVD_MAP;
7772 found_outer:
7773 omp_add_variable (ctx, decl, nflags);
7775 else
7777 /* If nothing changed, there's nothing left to do. */
7778 if ((n->value & flags) == flags)
7779 return ret;
7780 flags |= n->value;
7781 n->value = flags;
7783 goto do_outer;
7786 if (n == NULL)
7788 if (ctx->region_type == ORT_WORKSHARE
7789 || ctx->region_type == ORT_TASKGROUP
7790 || ctx->region_type == ORT_SIMD
7791 || ctx->region_type == ORT_ACC
7792 || (ctx->region_type & ORT_TARGET_DATA) != 0)
7793 goto do_outer;
7795 flags = omp_default_clause (ctx, decl, in_code, flags);
7797 if ((flags & GOVD_PRIVATE)
7798 && lang_hooks.decls.omp_private_outer_ref (decl))
7799 flags |= GOVD_PRIVATE_OUTER_REF;
7801 omp_add_variable (ctx, decl, flags);
7803 shared = (flags & GOVD_SHARED) != 0;
7804 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7805 goto do_outer;
7808 /* Don't mark as GOVD_SEEN addressable temporaries seen only in simd
7809 lb, b or incr expressions, those shouldn't be turned into simd arrays. */
7810 if (ctx->region_type == ORT_SIMD
7811 && ctx->in_for_exprs
7812 && ((n->value & (GOVD_PRIVATE | GOVD_SEEN | GOVD_EXPLICIT))
7813 == GOVD_PRIVATE))
7814 flags &= ~GOVD_SEEN;
7816 if ((n->value & (GOVD_SEEN | GOVD_LOCAL)) == 0
7817 && (flags & (GOVD_SEEN | GOVD_LOCAL)) == GOVD_SEEN
7818 && DECL_SIZE (decl))
7820 if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
7822 splay_tree_node n2;
7823 tree t = DECL_VALUE_EXPR (decl);
7824 gcc_assert (TREE_CODE (t) == INDIRECT_REF);
7825 t = TREE_OPERAND (t, 0);
7826 gcc_assert (DECL_P (t));
7827 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
7828 n2->value |= GOVD_SEEN;
7830 else if (omp_privatize_by_reference (decl)
7831 && TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)))
7832 && (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))))
7833 != INTEGER_CST))
7835 splay_tree_node n2;
7836 tree t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
7837 gcc_assert (DECL_P (t));
7838 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
7839 if (n2)
7840 omp_notice_variable (ctx, t, true);
7844 if (ctx->region_type & ORT_ACC)
7845 /* For OpenACC, as remarked above, defer expansion. */
7846 shared = false;
7847 else
7848 shared = ((flags | n->value) & GOVD_SHARED) != 0;
7849 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7851 /* If nothing changed, there's nothing left to do. */
7852 if ((n->value & flags) == flags)
7853 return ret;
7854 flags |= n->value;
7855 n->value = flags;
7857 do_outer:
7858 /* If the variable is private in the current context, then we don't
7859 need to propagate anything to an outer context. */
7860 if ((flags & GOVD_PRIVATE) && !(flags & GOVD_PRIVATE_OUTER_REF))
7861 return ret;
7862 if ((flags & (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7863 == (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7864 return ret;
7865 if ((flags & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
7866 | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7867 == (GOVD_LASTPRIVATE | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7868 return ret;
7869 if (ctx->outer_context
7870 && omp_notice_variable (ctx->outer_context, decl, in_code))
7871 return true;
7872 return ret;
7875 /* Verify that DECL is private within CTX. If there's specific information
7876 to the contrary in the innermost scope, generate an error. */
7878 static bool
7879 omp_is_private (struct gimplify_omp_ctx *ctx, tree decl, int simd)
7881 splay_tree_node n;
7883 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7884 if (n != NULL)
7886 if (n->value & GOVD_SHARED)
7888 if (ctx == gimplify_omp_ctxp)
7890 if (simd)
7891 error ("iteration variable %qE is predetermined linear",
7892 DECL_NAME (decl));
7893 else
7894 error ("iteration variable %qE should be private",
7895 DECL_NAME (decl));
7896 n->value = GOVD_PRIVATE;
7897 return true;
7899 else
7900 return false;
7902 else if ((n->value & GOVD_EXPLICIT) != 0
7903 && (ctx == gimplify_omp_ctxp
7904 || (ctx->region_type == ORT_COMBINED_PARALLEL
7905 && gimplify_omp_ctxp->outer_context == ctx)))
7907 if ((n->value & GOVD_FIRSTPRIVATE) != 0)
7908 error ("iteration variable %qE should not be firstprivate",
7909 DECL_NAME (decl));
7910 else if ((n->value & GOVD_REDUCTION) != 0)
7911 error ("iteration variable %qE should not be reduction",
7912 DECL_NAME (decl));
7913 else if (simd != 1 && (n->value & GOVD_LINEAR) != 0)
7914 error ("iteration variable %qE should not be linear",
7915 DECL_NAME (decl));
7917 return (ctx == gimplify_omp_ctxp
7918 || (ctx->region_type == ORT_COMBINED_PARALLEL
7919 && gimplify_omp_ctxp->outer_context == ctx));
7922 if (ctx->region_type != ORT_WORKSHARE
7923 && ctx->region_type != ORT_TASKGROUP
7924 && ctx->region_type != ORT_SIMD
7925 && ctx->region_type != ORT_ACC)
7926 return false;
7927 else if (ctx->outer_context)
7928 return omp_is_private (ctx->outer_context, decl, simd);
7929 return false;
7932 /* Return true if DECL is private within a parallel region
7933 that binds to the current construct's context or in parallel
7934 region's REDUCTION clause. */
7936 static bool
7937 omp_check_private (struct gimplify_omp_ctx *ctx, tree decl, bool copyprivate)
7939 splay_tree_node n;
7943 ctx = ctx->outer_context;
7944 if (ctx == NULL)
7946 if (is_global_var (decl))
7947 return false;
7949 /* References might be private, but might be shared too,
7950 when checking for copyprivate, assume they might be
7951 private, otherwise assume they might be shared. */
7952 if (copyprivate)
7953 return true;
7955 if (omp_privatize_by_reference (decl))
7956 return false;
7958 /* Treat C++ privatized non-static data members outside
7959 of the privatization the same. */
7960 if (omp_member_access_dummy_var (decl))
7961 return false;
7963 return true;
7966 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
7968 if ((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
7969 && (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0))
7971 if ((ctx->region_type & ORT_TARGET_DATA) != 0
7972 || n == NULL
7973 || (n->value & GOVD_MAP) == 0)
7974 continue;
7975 return false;
7978 if (n != NULL)
7980 if ((n->value & GOVD_LOCAL) != 0
7981 && omp_member_access_dummy_var (decl))
7982 return false;
7983 return (n->value & GOVD_SHARED) == 0;
7986 if (ctx->region_type == ORT_WORKSHARE
7987 || ctx->region_type == ORT_TASKGROUP
7988 || ctx->region_type == ORT_SIMD
7989 || ctx->region_type == ORT_ACC)
7990 continue;
7992 break;
7994 while (1);
7995 return false;
7998 /* Callback for walk_tree to find a DECL_EXPR for the given DECL. */
8000 static tree
8001 find_decl_expr (tree *tp, int *walk_subtrees, void *data)
8003 tree t = *tp;
8005 /* If this node has been visited, unmark it and keep looking. */
8006 if (TREE_CODE (t) == DECL_EXPR && DECL_EXPR_DECL (t) == (tree) data)
8007 return t;
8009 if (IS_TYPE_OR_DECL_P (t))
8010 *walk_subtrees = 0;
8011 return NULL_TREE;
8015 /* Gimplify the affinity clause but effectively ignore it.
8016 Generate:
8017 var = begin;
8018 if ((step > 1) ? var <= end : var > end)
8019 locatator_var_expr; */
8021 static void
8022 gimplify_omp_affinity (tree *list_p, gimple_seq *pre_p)
8024 tree last_iter = NULL_TREE;
8025 tree last_bind = NULL_TREE;
8026 tree label = NULL_TREE;
8027 tree *last_body = NULL;
8028 for (tree c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
8029 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY)
8031 tree t = OMP_CLAUSE_DECL (c);
8032 if (TREE_CODE (t) == TREE_LIST
8033 && TREE_PURPOSE (t)
8034 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
8036 if (TREE_VALUE (t) == null_pointer_node)
8037 continue;
8038 if (TREE_PURPOSE (t) != last_iter)
8040 if (last_bind)
8042 append_to_statement_list (label, last_body);
8043 gimplify_and_add (last_bind, pre_p);
8044 last_bind = NULL_TREE;
8046 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8048 if (gimplify_expr (&TREE_VEC_ELT (it, 1), pre_p, NULL,
8049 is_gimple_val, fb_rvalue) == GS_ERROR
8050 || gimplify_expr (&TREE_VEC_ELT (it, 2), pre_p, NULL,
8051 is_gimple_val, fb_rvalue) == GS_ERROR
8052 || gimplify_expr (&TREE_VEC_ELT (it, 3), pre_p, NULL,
8053 is_gimple_val, fb_rvalue) == GS_ERROR
8054 || (gimplify_expr (&TREE_VEC_ELT (it, 4), pre_p, NULL,
8055 is_gimple_val, fb_rvalue)
8056 == GS_ERROR))
8057 return;
8059 last_iter = TREE_PURPOSE (t);
8060 tree block = TREE_VEC_ELT (TREE_PURPOSE (t), 5);
8061 last_bind = build3 (BIND_EXPR, void_type_node, BLOCK_VARS (block),
8062 NULL, block);
8063 last_body = &BIND_EXPR_BODY (last_bind);
8064 tree cond = NULL_TREE;
8065 location_t loc = OMP_CLAUSE_LOCATION (c);
8066 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8068 tree var = TREE_VEC_ELT (it, 0);
8069 tree begin = TREE_VEC_ELT (it, 1);
8070 tree end = TREE_VEC_ELT (it, 2);
8071 tree step = TREE_VEC_ELT (it, 3);
8072 loc = DECL_SOURCE_LOCATION (var);
8073 tree tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
8074 var, begin);
8075 append_to_statement_list_force (tem, last_body);
8077 tree cond1 = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8078 step, build_zero_cst (TREE_TYPE (step)));
8079 tree cond2 = fold_build2_loc (loc, LE_EXPR, boolean_type_node,
8080 var, end);
8081 tree cond3 = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8082 var, end);
8083 cond1 = fold_build3_loc (loc, COND_EXPR, boolean_type_node,
8084 cond1, cond2, cond3);
8085 if (cond)
8086 cond = fold_build2_loc (loc, TRUTH_AND_EXPR,
8087 boolean_type_node, cond, cond1);
8088 else
8089 cond = cond1;
8091 tree cont_label = create_artificial_label (loc);
8092 label = build1 (LABEL_EXPR, void_type_node, cont_label);
8093 tree tem = fold_build3_loc (loc, COND_EXPR, void_type_node, cond,
8094 void_node,
8095 build_and_jump (&cont_label));
8096 append_to_statement_list_force (tem, last_body);
8098 if (TREE_CODE (TREE_VALUE (t)) == COMPOUND_EXPR)
8100 append_to_statement_list (TREE_OPERAND (TREE_VALUE (t), 0),
8101 last_body);
8102 TREE_VALUE (t) = TREE_OPERAND (TREE_VALUE (t), 1);
8104 if (error_operand_p (TREE_VALUE (t)))
8105 return;
8106 append_to_statement_list_force (TREE_VALUE (t), last_body);
8107 TREE_VALUE (t) = null_pointer_node;
8109 else
8111 if (last_bind)
8113 append_to_statement_list (label, last_body);
8114 gimplify_and_add (last_bind, pre_p);
8115 last_bind = NULL_TREE;
8117 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
8119 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
8120 NULL, is_gimple_val, fb_rvalue);
8121 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
8123 if (error_operand_p (OMP_CLAUSE_DECL (c)))
8124 return;
8125 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
8126 is_gimple_val, fb_rvalue) == GS_ERROR)
8127 return;
8128 gimplify_and_add (OMP_CLAUSE_DECL (c), pre_p);
8131 if (last_bind)
8133 append_to_statement_list (label, last_body);
8134 gimplify_and_add (last_bind, pre_p);
8136 return;
8139 /* If *LIST_P contains any OpenMP depend clauses with iterators,
8140 lower all the depend clauses by populating corresponding depend
8141 array. Returns 0 if there are no such depend clauses, or
8142 2 if all depend clauses should be removed, 1 otherwise. */
8144 static int
8145 gimplify_omp_depend (tree *list_p, gimple_seq *pre_p)
8147 tree c;
8148 gimple *g;
8149 size_t n[4] = { 0, 0, 0, 0 };
8150 bool unused[4];
8151 tree counts[4] = { NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE };
8152 tree last_iter = NULL_TREE, last_count = NULL_TREE;
8153 size_t i, j;
8154 location_t first_loc = UNKNOWN_LOCATION;
8156 for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
8157 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
8159 switch (OMP_CLAUSE_DEPEND_KIND (c))
8161 case OMP_CLAUSE_DEPEND_IN:
8162 i = 2;
8163 break;
8164 case OMP_CLAUSE_DEPEND_OUT:
8165 case OMP_CLAUSE_DEPEND_INOUT:
8166 i = 0;
8167 break;
8168 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
8169 i = 1;
8170 break;
8171 case OMP_CLAUSE_DEPEND_DEPOBJ:
8172 i = 3;
8173 break;
8174 case OMP_CLAUSE_DEPEND_SOURCE:
8175 case OMP_CLAUSE_DEPEND_SINK:
8176 continue;
8177 default:
8178 gcc_unreachable ();
8180 tree t = OMP_CLAUSE_DECL (c);
8181 if (first_loc == UNKNOWN_LOCATION)
8182 first_loc = OMP_CLAUSE_LOCATION (c);
8183 if (TREE_CODE (t) == TREE_LIST
8184 && TREE_PURPOSE (t)
8185 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
8187 if (TREE_PURPOSE (t) != last_iter)
8189 tree tcnt = size_one_node;
8190 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8192 if (gimplify_expr (&TREE_VEC_ELT (it, 1), pre_p, NULL,
8193 is_gimple_val, fb_rvalue) == GS_ERROR
8194 || gimplify_expr (&TREE_VEC_ELT (it, 2), pre_p, NULL,
8195 is_gimple_val, fb_rvalue) == GS_ERROR
8196 || gimplify_expr (&TREE_VEC_ELT (it, 3), pre_p, NULL,
8197 is_gimple_val, fb_rvalue) == GS_ERROR
8198 || (gimplify_expr (&TREE_VEC_ELT (it, 4), pre_p, NULL,
8199 is_gimple_val, fb_rvalue)
8200 == GS_ERROR))
8201 return 2;
8202 tree var = TREE_VEC_ELT (it, 0);
8203 tree begin = TREE_VEC_ELT (it, 1);
8204 tree end = TREE_VEC_ELT (it, 2);
8205 tree step = TREE_VEC_ELT (it, 3);
8206 tree orig_step = TREE_VEC_ELT (it, 4);
8207 tree type = TREE_TYPE (var);
8208 tree stype = TREE_TYPE (step);
8209 location_t loc = DECL_SOURCE_LOCATION (var);
8210 tree endmbegin;
8211 /* Compute count for this iterator as
8212 orig_step > 0
8213 ? (begin < end ? (end - begin + (step - 1)) / step : 0)
8214 : (begin > end ? (end - begin + (step + 1)) / step : 0)
8215 and compute product of those for the entire depend
8216 clause. */
8217 if (POINTER_TYPE_P (type))
8218 endmbegin = fold_build2_loc (loc, POINTER_DIFF_EXPR,
8219 stype, end, begin);
8220 else
8221 endmbegin = fold_build2_loc (loc, MINUS_EXPR, type,
8222 end, begin);
8223 tree stepm1 = fold_build2_loc (loc, MINUS_EXPR, stype,
8224 step,
8225 build_int_cst (stype, 1));
8226 tree stepp1 = fold_build2_loc (loc, PLUS_EXPR, stype, step,
8227 build_int_cst (stype, 1));
8228 tree pos = fold_build2_loc (loc, PLUS_EXPR, stype,
8229 unshare_expr (endmbegin),
8230 stepm1);
8231 pos = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype,
8232 pos, step);
8233 tree neg = fold_build2_loc (loc, PLUS_EXPR, stype,
8234 endmbegin, stepp1);
8235 if (TYPE_UNSIGNED (stype))
8237 neg = fold_build1_loc (loc, NEGATE_EXPR, stype, neg);
8238 step = fold_build1_loc (loc, NEGATE_EXPR, stype, step);
8240 neg = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype,
8241 neg, step);
8242 step = NULL_TREE;
8243 tree cond = fold_build2_loc (loc, LT_EXPR,
8244 boolean_type_node,
8245 begin, end);
8246 pos = fold_build3_loc (loc, COND_EXPR, stype, cond, pos,
8247 build_int_cst (stype, 0));
8248 cond = fold_build2_loc (loc, LT_EXPR, boolean_type_node,
8249 end, begin);
8250 neg = fold_build3_loc (loc, COND_EXPR, stype, cond, neg,
8251 build_int_cst (stype, 0));
8252 tree osteptype = TREE_TYPE (orig_step);
8253 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8254 orig_step,
8255 build_int_cst (osteptype, 0));
8256 tree cnt = fold_build3_loc (loc, COND_EXPR, stype,
8257 cond, pos, neg);
8258 cnt = fold_convert_loc (loc, sizetype, cnt);
8259 if (gimplify_expr (&cnt, pre_p, NULL, is_gimple_val,
8260 fb_rvalue) == GS_ERROR)
8261 return 2;
8262 tcnt = size_binop_loc (loc, MULT_EXPR, tcnt, cnt);
8264 if (gimplify_expr (&tcnt, pre_p, NULL, is_gimple_val,
8265 fb_rvalue) == GS_ERROR)
8266 return 2;
8267 last_iter = TREE_PURPOSE (t);
8268 last_count = tcnt;
8270 if (counts[i] == NULL_TREE)
8271 counts[i] = last_count;
8272 else
8273 counts[i] = size_binop_loc (OMP_CLAUSE_LOCATION (c),
8274 PLUS_EXPR, counts[i], last_count);
8276 else
8277 n[i]++;
8279 for (i = 0; i < 4; i++)
8280 if (counts[i])
8281 break;
8282 if (i == 4)
8283 return 0;
8285 tree total = size_zero_node;
8286 for (i = 0; i < 4; i++)
8288 unused[i] = counts[i] == NULL_TREE && n[i] == 0;
8289 if (counts[i] == NULL_TREE)
8290 counts[i] = size_zero_node;
8291 if (n[i])
8292 counts[i] = size_binop (PLUS_EXPR, counts[i], size_int (n[i]));
8293 if (gimplify_expr (&counts[i], pre_p, NULL, is_gimple_val,
8294 fb_rvalue) == GS_ERROR)
8295 return 2;
8296 total = size_binop (PLUS_EXPR, total, counts[i]);
8299 if (gimplify_expr (&total, pre_p, NULL, is_gimple_val, fb_rvalue)
8300 == GS_ERROR)
8301 return 2;
8302 bool is_old = unused[1] && unused[3];
8303 tree totalpx = size_binop (PLUS_EXPR, unshare_expr (total),
8304 size_int (is_old ? 1 : 4));
8305 tree type = build_array_type (ptr_type_node, build_index_type (totalpx));
8306 tree array = create_tmp_var_raw (type);
8307 TREE_ADDRESSABLE (array) = 1;
8308 if (!poly_int_tree_p (totalpx))
8310 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (array)))
8311 gimplify_type_sizes (TREE_TYPE (array), pre_p);
8312 if (gimplify_omp_ctxp)
8314 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
8315 while (ctx
8316 && (ctx->region_type == ORT_WORKSHARE
8317 || ctx->region_type == ORT_TASKGROUP
8318 || ctx->region_type == ORT_SIMD
8319 || ctx->region_type == ORT_ACC))
8320 ctx = ctx->outer_context;
8321 if (ctx)
8322 omp_add_variable (ctx, array, GOVD_LOCAL | GOVD_SEEN);
8324 gimplify_vla_decl (array, pre_p);
8326 else
8327 gimple_add_tmp_var (array);
8328 tree r = build4 (ARRAY_REF, ptr_type_node, array, size_int (0), NULL_TREE,
8329 NULL_TREE);
8330 tree tem;
8331 if (!is_old)
8333 tem = build2 (MODIFY_EXPR, void_type_node, r,
8334 build_int_cst (ptr_type_node, 0));
8335 gimplify_and_add (tem, pre_p);
8336 r = build4 (ARRAY_REF, ptr_type_node, array, size_int (1), NULL_TREE,
8337 NULL_TREE);
8339 tem = build2 (MODIFY_EXPR, void_type_node, r,
8340 fold_convert (ptr_type_node, total));
8341 gimplify_and_add (tem, pre_p);
8342 for (i = 1; i < (is_old ? 2 : 4); i++)
8344 r = build4 (ARRAY_REF, ptr_type_node, array, size_int (i + !is_old),
8345 NULL_TREE, NULL_TREE);
8346 tem = build2 (MODIFY_EXPR, void_type_node, r, counts[i - 1]);
8347 gimplify_and_add (tem, pre_p);
8350 tree cnts[4];
8351 for (j = 4; j; j--)
8352 if (!unused[j - 1])
8353 break;
8354 for (i = 0; i < 4; i++)
8356 if (i && (i >= j || unused[i - 1]))
8358 cnts[i] = cnts[i - 1];
8359 continue;
8361 cnts[i] = create_tmp_var (sizetype);
8362 if (i == 0)
8363 g = gimple_build_assign (cnts[i], size_int (is_old ? 2 : 5));
8364 else
8366 tree t;
8367 if (is_old)
8368 t = size_binop (PLUS_EXPR, counts[0], size_int (2));
8369 else
8370 t = size_binop (PLUS_EXPR, cnts[i - 1], counts[i - 1]);
8371 if (gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue)
8372 == GS_ERROR)
8373 return 2;
8374 g = gimple_build_assign (cnts[i], t);
8376 gimple_seq_add_stmt (pre_p, g);
8379 last_iter = NULL_TREE;
8380 tree last_bind = NULL_TREE;
8381 tree *last_body = NULL;
8382 for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
8383 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
8385 switch (OMP_CLAUSE_DEPEND_KIND (c))
8387 case OMP_CLAUSE_DEPEND_IN:
8388 i = 2;
8389 break;
8390 case OMP_CLAUSE_DEPEND_OUT:
8391 case OMP_CLAUSE_DEPEND_INOUT:
8392 i = 0;
8393 break;
8394 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
8395 i = 1;
8396 break;
8397 case OMP_CLAUSE_DEPEND_DEPOBJ:
8398 i = 3;
8399 break;
8400 case OMP_CLAUSE_DEPEND_SOURCE:
8401 case OMP_CLAUSE_DEPEND_SINK:
8402 continue;
8403 default:
8404 gcc_unreachable ();
8406 tree t = OMP_CLAUSE_DECL (c);
8407 if (TREE_CODE (t) == TREE_LIST
8408 && TREE_PURPOSE (t)
8409 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
8411 if (TREE_PURPOSE (t) != last_iter)
8413 if (last_bind)
8414 gimplify_and_add (last_bind, pre_p);
8415 tree block = TREE_VEC_ELT (TREE_PURPOSE (t), 5);
8416 last_bind = build3 (BIND_EXPR, void_type_node,
8417 BLOCK_VARS (block), NULL, block);
8418 TREE_SIDE_EFFECTS (last_bind) = 1;
8419 SET_EXPR_LOCATION (last_bind, OMP_CLAUSE_LOCATION (c));
8420 tree *p = &BIND_EXPR_BODY (last_bind);
8421 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8423 tree var = TREE_VEC_ELT (it, 0);
8424 tree begin = TREE_VEC_ELT (it, 1);
8425 tree end = TREE_VEC_ELT (it, 2);
8426 tree step = TREE_VEC_ELT (it, 3);
8427 tree orig_step = TREE_VEC_ELT (it, 4);
8428 tree type = TREE_TYPE (var);
8429 location_t loc = DECL_SOURCE_LOCATION (var);
8430 /* Emit:
8431 var = begin;
8432 goto cond_label;
8433 beg_label:
8435 var = var + step;
8436 cond_label:
8437 if (orig_step > 0) {
8438 if (var < end) goto beg_label;
8439 } else {
8440 if (var > end) goto beg_label;
8442 for each iterator, with inner iterators added to
8443 the ... above. */
8444 tree beg_label = create_artificial_label (loc);
8445 tree cond_label = NULL_TREE;
8446 tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
8447 var, begin);
8448 append_to_statement_list_force (tem, p);
8449 tem = build_and_jump (&cond_label);
8450 append_to_statement_list_force (tem, p);
8451 tem = build1 (LABEL_EXPR, void_type_node, beg_label);
8452 append_to_statement_list (tem, p);
8453 tree bind = build3 (BIND_EXPR, void_type_node, NULL_TREE,
8454 NULL_TREE, NULL_TREE);
8455 TREE_SIDE_EFFECTS (bind) = 1;
8456 SET_EXPR_LOCATION (bind, loc);
8457 append_to_statement_list_force (bind, p);
8458 if (POINTER_TYPE_P (type))
8459 tem = build2_loc (loc, POINTER_PLUS_EXPR, type,
8460 var, fold_convert_loc (loc, sizetype,
8461 step));
8462 else
8463 tem = build2_loc (loc, PLUS_EXPR, type, var, step);
8464 tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
8465 var, tem);
8466 append_to_statement_list_force (tem, p);
8467 tem = build1 (LABEL_EXPR, void_type_node, cond_label);
8468 append_to_statement_list (tem, p);
8469 tree cond = fold_build2_loc (loc, LT_EXPR,
8470 boolean_type_node,
8471 var, end);
8472 tree pos
8473 = fold_build3_loc (loc, COND_EXPR, void_type_node,
8474 cond, build_and_jump (&beg_label),
8475 void_node);
8476 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8477 var, end);
8478 tree neg
8479 = fold_build3_loc (loc, COND_EXPR, void_type_node,
8480 cond, build_and_jump (&beg_label),
8481 void_node);
8482 tree osteptype = TREE_TYPE (orig_step);
8483 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8484 orig_step,
8485 build_int_cst (osteptype, 0));
8486 tem = fold_build3_loc (loc, COND_EXPR, void_type_node,
8487 cond, pos, neg);
8488 append_to_statement_list_force (tem, p);
8489 p = &BIND_EXPR_BODY (bind);
8491 last_body = p;
8493 last_iter = TREE_PURPOSE (t);
8494 if (TREE_CODE (TREE_VALUE (t)) == COMPOUND_EXPR)
8496 append_to_statement_list (TREE_OPERAND (TREE_VALUE (t),
8497 0), last_body);
8498 TREE_VALUE (t) = TREE_OPERAND (TREE_VALUE (t), 1);
8500 if (error_operand_p (TREE_VALUE (t)))
8501 return 2;
8502 TREE_VALUE (t) = build_fold_addr_expr (TREE_VALUE (t));
8503 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
8504 NULL_TREE, NULL_TREE);
8505 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
8506 void_type_node, r, TREE_VALUE (t));
8507 append_to_statement_list_force (tem, last_body);
8508 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
8509 void_type_node, cnts[i],
8510 size_binop (PLUS_EXPR, cnts[i], size_int (1)));
8511 append_to_statement_list_force (tem, last_body);
8512 TREE_VALUE (t) = null_pointer_node;
8514 else
8516 if (last_bind)
8518 gimplify_and_add (last_bind, pre_p);
8519 last_bind = NULL_TREE;
8521 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
8523 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
8524 NULL, is_gimple_val, fb_rvalue);
8525 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
8527 if (error_operand_p (OMP_CLAUSE_DECL (c)))
8528 return 2;
8529 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
8530 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
8531 is_gimple_val, fb_rvalue) == GS_ERROR)
8532 return 2;
8533 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
8534 NULL_TREE, NULL_TREE);
8535 tem = build2 (MODIFY_EXPR, void_type_node, r, OMP_CLAUSE_DECL (c));
8536 gimplify_and_add (tem, pre_p);
8537 g = gimple_build_assign (cnts[i], size_binop (PLUS_EXPR, cnts[i],
8538 size_int (1)));
8539 gimple_seq_add_stmt (pre_p, g);
8542 if (last_bind)
8543 gimplify_and_add (last_bind, pre_p);
8544 tree cond = boolean_false_node;
8545 if (is_old)
8547 if (!unused[0])
8548 cond = build2_loc (first_loc, NE_EXPR, boolean_type_node, cnts[0],
8549 size_binop_loc (first_loc, PLUS_EXPR, counts[0],
8550 size_int (2)));
8551 if (!unused[2])
8552 cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond,
8553 build2_loc (first_loc, NE_EXPR, boolean_type_node,
8554 cnts[2],
8555 size_binop_loc (first_loc, PLUS_EXPR,
8556 totalpx,
8557 size_int (1))));
8559 else
8561 tree prev = size_int (5);
8562 for (i = 0; i < 4; i++)
8564 if (unused[i])
8565 continue;
8566 prev = size_binop_loc (first_loc, PLUS_EXPR, counts[i], prev);
8567 cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond,
8568 build2_loc (first_loc, NE_EXPR, boolean_type_node,
8569 cnts[i], unshare_expr (prev)));
8572 tem = build3_loc (first_loc, COND_EXPR, void_type_node, cond,
8573 build_call_expr_loc (first_loc,
8574 builtin_decl_explicit (BUILT_IN_TRAP),
8575 0), void_node);
8576 gimplify_and_add (tem, pre_p);
8577 c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_DEPEND);
8578 OMP_CLAUSE_DEPEND_KIND (c) = OMP_CLAUSE_DEPEND_LAST;
8579 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (array);
8580 OMP_CLAUSE_CHAIN (c) = *list_p;
8581 *list_p = c;
8582 return 1;
8585 /* Insert a GOMP_MAP_ALLOC or GOMP_MAP_RELEASE node following a
8586 GOMP_MAP_STRUCT mapping. C is an always_pointer mapping. STRUCT_NODE is
8587 the struct node to insert the new mapping after (when the struct node is
8588 initially created). PREV_NODE is the first of two or three mappings for a
8589 pointer, and is either:
8590 - the node before C, when a pair of mappings is used, e.g. for a C/C++
8591 array section.
8592 - not the node before C. This is true when we have a reference-to-pointer
8593 type (with a mapping for the reference and for the pointer), or for
8594 Fortran derived-type mappings with a GOMP_MAP_TO_PSET.
8595 If SCP is non-null, the new node is inserted before *SCP.
8596 if SCP is null, the new node is inserted before PREV_NODE.
8597 The return type is:
8598 - PREV_NODE, if SCP is non-null.
8599 - The newly-created ALLOC or RELEASE node, if SCP is null.
8600 - The second newly-created ALLOC or RELEASE node, if we are mapping a
8601 reference to a pointer. */
8603 static tree
8604 insert_struct_comp_map (enum tree_code code, tree c, tree struct_node,
8605 tree prev_node, tree *scp)
8607 enum gomp_map_kind mkind
8608 = (code == OMP_TARGET_EXIT_DATA || code == OACC_EXIT_DATA)
8609 ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
8611 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
8612 tree cl = scp ? prev_node : c2;
8613 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
8614 OMP_CLAUSE_DECL (c2) = unshare_expr (OMP_CLAUSE_DECL (c));
8615 OMP_CLAUSE_CHAIN (c2) = scp ? *scp : prev_node;
8616 if (OMP_CLAUSE_CHAIN (prev_node) != c
8617 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (prev_node)) == OMP_CLAUSE_MAP
8618 && (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node))
8619 == GOMP_MAP_TO_PSET))
8620 OMP_CLAUSE_SIZE (c2) = OMP_CLAUSE_SIZE (OMP_CLAUSE_CHAIN (prev_node));
8621 else
8622 OMP_CLAUSE_SIZE (c2) = TYPE_SIZE_UNIT (ptr_type_node);
8623 if (struct_node)
8624 OMP_CLAUSE_CHAIN (struct_node) = c2;
8626 /* We might need to create an additional mapping if we have a reference to a
8627 pointer (in C++). Don't do this if we have something other than a
8628 GOMP_MAP_ALWAYS_POINTER though, i.e. a GOMP_MAP_TO_PSET. */
8629 if (OMP_CLAUSE_CHAIN (prev_node) != c
8630 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (prev_node)) == OMP_CLAUSE_MAP
8631 && ((OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node))
8632 == GOMP_MAP_ALWAYS_POINTER)
8633 || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node))
8634 == GOMP_MAP_ATTACH_DETACH)))
8636 tree c4 = OMP_CLAUSE_CHAIN (prev_node);
8637 tree c3 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
8638 OMP_CLAUSE_SET_MAP_KIND (c3, mkind);
8639 OMP_CLAUSE_DECL (c3) = unshare_expr (OMP_CLAUSE_DECL (c4));
8640 OMP_CLAUSE_SIZE (c3) = TYPE_SIZE_UNIT (ptr_type_node);
8641 OMP_CLAUSE_CHAIN (c3) = prev_node;
8642 if (!scp)
8643 OMP_CLAUSE_CHAIN (c2) = c3;
8644 else
8645 cl = c3;
8648 if (scp)
8649 *scp = c2;
8651 return cl;
8654 /* Strip ARRAY_REFS or an indirect ref off BASE, find the containing object,
8655 and set *BITPOSP and *POFFSETP to the bit offset of the access.
8656 If BASE_REF is non-NULL and the containing object is a reference, set
8657 *BASE_REF to that reference before dereferencing the object.
8658 If BASE_REF is NULL, check that the containing object is a COMPONENT_REF or
8659 has array type, else return NULL. */
8661 static tree
8662 extract_base_bit_offset (tree base, tree *base_ref, poly_int64 *bitposp,
8663 poly_offset_int *poffsetp, tree *offsetp)
8665 tree offset;
8666 poly_int64 bitsize, bitpos;
8667 machine_mode mode;
8668 int unsignedp, reversep, volatilep = 0;
8669 poly_offset_int poffset;
8671 if (base_ref)
8673 *base_ref = NULL_TREE;
8675 while (TREE_CODE (base) == ARRAY_REF)
8676 base = TREE_OPERAND (base, 0);
8678 if (TREE_CODE (base) == INDIRECT_REF)
8679 base = TREE_OPERAND (base, 0);
8681 else
8683 if (TREE_CODE (base) == ARRAY_REF)
8685 while (TREE_CODE (base) == ARRAY_REF)
8686 base = TREE_OPERAND (base, 0);
8687 if (TREE_CODE (base) != COMPONENT_REF
8688 || TREE_CODE (TREE_TYPE (base)) != ARRAY_TYPE)
8689 return NULL_TREE;
8691 else if (TREE_CODE (base) == INDIRECT_REF
8692 && TREE_CODE (TREE_OPERAND (base, 0)) == COMPONENT_REF
8693 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0)))
8694 == REFERENCE_TYPE))
8695 base = TREE_OPERAND (base, 0);
8698 base = get_inner_reference (base, &bitsize, &bitpos, &offset, &mode,
8699 &unsignedp, &reversep, &volatilep);
8701 tree orig_base = base;
8703 if ((TREE_CODE (base) == INDIRECT_REF
8704 || (TREE_CODE (base) == MEM_REF
8705 && integer_zerop (TREE_OPERAND (base, 1))))
8706 && DECL_P (TREE_OPERAND (base, 0))
8707 && TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0))) == REFERENCE_TYPE)
8708 base = TREE_OPERAND (base, 0);
8710 if (offset && poly_int_tree_p (offset))
8712 poffset = wi::to_poly_offset (offset);
8713 offset = NULL_TREE;
8715 else
8716 poffset = 0;
8718 if (maybe_ne (bitpos, 0))
8719 poffset += bits_to_bytes_round_down (bitpos);
8721 *bitposp = bitpos;
8722 *poffsetp = poffset;
8723 *offsetp = offset;
8725 /* Set *BASE_REF if BASE was a dereferenced reference variable. */
8726 if (base_ref && orig_base != base)
8727 *base_ref = orig_base;
8729 return base;
8732 /* Returns true if EXPR is or contains (as a sub-component) BASE_PTR. */
8734 static bool
8735 is_or_contains_p (tree expr, tree base_ptr)
8737 if ((TREE_CODE (expr) == INDIRECT_REF && TREE_CODE (base_ptr) == MEM_REF)
8738 || (TREE_CODE (expr) == MEM_REF && TREE_CODE (base_ptr) == INDIRECT_REF))
8739 return operand_equal_p (TREE_OPERAND (expr, 0),
8740 TREE_OPERAND (base_ptr, 0));
8741 while (!operand_equal_p (expr, base_ptr))
8743 if (TREE_CODE (base_ptr) == COMPOUND_EXPR)
8744 base_ptr = TREE_OPERAND (base_ptr, 1);
8745 if (TREE_CODE (base_ptr) == COMPONENT_REF
8746 || TREE_CODE (base_ptr) == POINTER_PLUS_EXPR
8747 || TREE_CODE (base_ptr) == SAVE_EXPR)
8748 base_ptr = TREE_OPERAND (base_ptr, 0);
8749 else
8750 break;
8752 return operand_equal_p (expr, base_ptr);
8755 /* Implement OpenMP 5.x map ordering rules for target directives. There are
8756 several rules, and with some level of ambiguity, hopefully we can at least
8757 collect the complexity here in one place. */
8759 static void
8760 omp_target_reorder_clauses (tree *list_p)
8762 /* Collect refs to alloc/release/delete maps. */
8763 auto_vec<tree, 32> ard;
8764 tree *cp = list_p;
8765 while (*cp != NULL_TREE)
8766 if (OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP
8767 && (OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_ALLOC
8768 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_RELEASE
8769 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_DELETE))
8771 /* Unlink cp and push to ard. */
8772 tree c = *cp;
8773 tree nc = OMP_CLAUSE_CHAIN (c);
8774 *cp = nc;
8775 ard.safe_push (c);
8777 /* Any associated pointer type maps should also move along. */
8778 while (*cp != NULL_TREE
8779 && OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP
8780 && (OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
8781 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_FIRSTPRIVATE_POINTER
8782 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_ATTACH_DETACH
8783 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_POINTER
8784 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_ALWAYS_POINTER
8785 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_TO_PSET))
8787 c = *cp;
8788 nc = OMP_CLAUSE_CHAIN (c);
8789 *cp = nc;
8790 ard.safe_push (c);
8793 else
8794 cp = &OMP_CLAUSE_CHAIN (*cp);
8796 /* Link alloc/release/delete maps to the end of list. */
8797 for (unsigned int i = 0; i < ard.length (); i++)
8799 *cp = ard[i];
8800 cp = &OMP_CLAUSE_CHAIN (ard[i]);
8802 *cp = NULL_TREE;
8804 /* OpenMP 5.0 requires that pointer variables are mapped before
8805 its use as a base-pointer. */
8806 auto_vec<tree *, 32> atf;
8807 for (tree *cp = list_p; *cp; cp = &OMP_CLAUSE_CHAIN (*cp))
8808 if (OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP)
8810 /* Collect alloc, to, from, to/from clause tree pointers. */
8811 gomp_map_kind k = OMP_CLAUSE_MAP_KIND (*cp);
8812 if (k == GOMP_MAP_ALLOC
8813 || k == GOMP_MAP_TO
8814 || k == GOMP_MAP_FROM
8815 || k == GOMP_MAP_TOFROM
8816 || k == GOMP_MAP_ALWAYS_TO
8817 || k == GOMP_MAP_ALWAYS_FROM
8818 || k == GOMP_MAP_ALWAYS_TOFROM)
8819 atf.safe_push (cp);
8822 for (unsigned int i = 0; i < atf.length (); i++)
8823 if (atf[i])
8825 tree *cp = atf[i];
8826 tree decl = OMP_CLAUSE_DECL (*cp);
8827 if (TREE_CODE (decl) == INDIRECT_REF || TREE_CODE (decl) == MEM_REF)
8829 tree base_ptr = TREE_OPERAND (decl, 0);
8830 STRIP_TYPE_NOPS (base_ptr);
8831 for (unsigned int j = i + 1; j < atf.length (); j++)
8832 if (atf[j])
8834 tree *cp2 = atf[j];
8835 tree decl2 = OMP_CLAUSE_DECL (*cp2);
8837 decl2 = OMP_CLAUSE_DECL (*cp2);
8838 if (is_or_contains_p (decl2, base_ptr))
8840 /* Move *cp2 to before *cp. */
8841 tree c = *cp2;
8842 *cp2 = OMP_CLAUSE_CHAIN (c);
8843 OMP_CLAUSE_CHAIN (c) = *cp;
8844 *cp = c;
8846 if (*cp2 != NULL_TREE
8847 && OMP_CLAUSE_CODE (*cp2) == OMP_CLAUSE_MAP
8848 && OMP_CLAUSE_MAP_KIND (*cp2) == GOMP_MAP_ALWAYS_POINTER)
8850 tree c2 = *cp2;
8851 *cp2 = OMP_CLAUSE_CHAIN (c2);
8852 OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (c);
8853 OMP_CLAUSE_CHAIN (c) = c2;
8856 atf[j] = NULL;
8862 /* For attach_detach map clauses, if there is another map that maps the
8863 attached/detached pointer, make sure that map is ordered before the
8864 attach_detach. */
8865 atf.truncate (0);
8866 for (tree *cp = list_p; *cp; cp = &OMP_CLAUSE_CHAIN (*cp))
8867 if (OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP)
8869 /* Collect alloc, to, from, to/from clauses, and
8870 always_pointer/attach_detach clauses. */
8871 gomp_map_kind k = OMP_CLAUSE_MAP_KIND (*cp);
8872 if (k == GOMP_MAP_ALLOC
8873 || k == GOMP_MAP_TO
8874 || k == GOMP_MAP_FROM
8875 || k == GOMP_MAP_TOFROM
8876 || k == GOMP_MAP_ALWAYS_TO
8877 || k == GOMP_MAP_ALWAYS_FROM
8878 || k == GOMP_MAP_ALWAYS_TOFROM
8879 || k == GOMP_MAP_ATTACH_DETACH
8880 || k == GOMP_MAP_ALWAYS_POINTER)
8881 atf.safe_push (cp);
8884 for (unsigned int i = 0; i < atf.length (); i++)
8885 if (atf[i])
8887 tree *cp = atf[i];
8888 tree ptr = OMP_CLAUSE_DECL (*cp);
8889 STRIP_TYPE_NOPS (ptr);
8890 if (OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_ATTACH_DETACH)
8891 for (unsigned int j = i + 1; j < atf.length (); j++)
8893 tree *cp2 = atf[j];
8894 tree decl2 = OMP_CLAUSE_DECL (*cp2);
8895 if (OMP_CLAUSE_MAP_KIND (*cp2) != GOMP_MAP_ATTACH_DETACH
8896 && OMP_CLAUSE_MAP_KIND (*cp2) != GOMP_MAP_ALWAYS_POINTER
8897 && is_or_contains_p (decl2, ptr))
8899 /* Move *cp2 to before *cp. */
8900 tree c = *cp2;
8901 *cp2 = OMP_CLAUSE_CHAIN (c);
8902 OMP_CLAUSE_CHAIN (c) = *cp;
8903 *cp = c;
8904 atf[j] = NULL;
8906 /* If decl2 is of the form '*decl2_opnd0', and followed by an
8907 ALWAYS_POINTER or ATTACH_DETACH of 'decl2_opnd0', move the
8908 pointer operation along with *cp2. This can happen for C++
8909 reference sequences. */
8910 if (j + 1 < atf.length ()
8911 && (TREE_CODE (decl2) == INDIRECT_REF
8912 || TREE_CODE (decl2) == MEM_REF))
8914 tree *cp3 = atf[j + 1];
8915 tree decl3 = OMP_CLAUSE_DECL (*cp3);
8916 tree decl2_opnd0 = TREE_OPERAND (decl2, 0);
8917 if ((OMP_CLAUSE_MAP_KIND (*cp3) == GOMP_MAP_ALWAYS_POINTER
8918 || OMP_CLAUSE_MAP_KIND (*cp3) == GOMP_MAP_ATTACH_DETACH)
8919 && operand_equal_p (decl3, decl2_opnd0))
8921 /* Also move *cp3 to before *cp. */
8922 c = *cp3;
8923 *cp2 = OMP_CLAUSE_CHAIN (c);
8924 OMP_CLAUSE_CHAIN (c) = *cp;
8925 *cp = c;
8926 atf[j + 1] = NULL;
8927 j += 1;
8935 /* DECL is supposed to have lastprivate semantics in the outer contexts
8936 of combined/composite constructs, starting with OCTX.
8937 Add needed lastprivate, shared or map clause if no data sharing or
8938 mapping clause are present. IMPLICIT_P is true if it is an implicit
8939 clause (IV on simd), in which case the lastprivate will not be
8940 copied to some constructs. */
8942 static void
8943 omp_lastprivate_for_combined_outer_constructs (struct gimplify_omp_ctx *octx,
8944 tree decl, bool implicit_p)
8946 struct gimplify_omp_ctx *orig_octx = octx;
8947 for (; octx; octx = octx->outer_context)
8949 if ((octx->region_type == ORT_COMBINED_PARALLEL
8950 || (octx->region_type & ORT_COMBINED_TEAMS) == ORT_COMBINED_TEAMS)
8951 && splay_tree_lookup (octx->variables,
8952 (splay_tree_key) decl) == NULL)
8954 omp_add_variable (octx, decl, GOVD_SHARED | GOVD_SEEN);
8955 continue;
8957 if ((octx->region_type & ORT_TASK) != 0
8958 && octx->combined_loop
8959 && splay_tree_lookup (octx->variables,
8960 (splay_tree_key) decl) == NULL)
8962 omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
8963 continue;
8965 if (implicit_p
8966 && octx->region_type == ORT_WORKSHARE
8967 && octx->combined_loop
8968 && splay_tree_lookup (octx->variables,
8969 (splay_tree_key) decl) == NULL
8970 && octx->outer_context
8971 && octx->outer_context->region_type == ORT_COMBINED_PARALLEL
8972 && splay_tree_lookup (octx->outer_context->variables,
8973 (splay_tree_key) decl) == NULL)
8975 octx = octx->outer_context;
8976 omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
8977 continue;
8979 if ((octx->region_type == ORT_WORKSHARE || octx->region_type == ORT_ACC)
8980 && octx->combined_loop
8981 && splay_tree_lookup (octx->variables,
8982 (splay_tree_key) decl) == NULL
8983 && !omp_check_private (octx, decl, false))
8985 omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
8986 continue;
8988 if (octx->region_type == ORT_COMBINED_TARGET)
8990 splay_tree_node n = splay_tree_lookup (octx->variables,
8991 (splay_tree_key) decl);
8992 if (n == NULL)
8994 omp_add_variable (octx, decl, GOVD_MAP | GOVD_SEEN);
8995 octx = octx->outer_context;
8997 else if (!implicit_p
8998 && (n->value & GOVD_FIRSTPRIVATE_IMPLICIT))
9000 n->value &= ~(GOVD_FIRSTPRIVATE
9001 | GOVD_FIRSTPRIVATE_IMPLICIT
9002 | GOVD_EXPLICIT);
9003 omp_add_variable (octx, decl, GOVD_MAP | GOVD_SEEN);
9004 octx = octx->outer_context;
9007 break;
9009 if (octx && (implicit_p || octx != orig_octx))
9010 omp_notice_variable (octx, decl, true);
9013 /* Scan the OMP clauses in *LIST_P, installing mappings into a new
9014 and previous omp contexts. */
9016 static void
9017 gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
9018 enum omp_region_type region_type,
9019 enum tree_code code)
9021 struct gimplify_omp_ctx *ctx, *outer_ctx;
9022 tree c;
9023 hash_map<tree_operand_hash, tree> *struct_map_to_clause = NULL;
9024 hash_map<tree_operand_hash, tree *> *struct_seen_clause = NULL;
9025 hash_set<tree> *struct_deref_set = NULL;
9026 tree *prev_list_p = NULL, *orig_list_p = list_p;
9027 int handled_depend_iterators = -1;
9028 int nowait = -1;
9030 ctx = new_omp_context (region_type);
9031 ctx->code = code;
9032 outer_ctx = ctx->outer_context;
9033 if (code == OMP_TARGET)
9035 if (!lang_GNU_Fortran ())
9036 ctx->defaultmap[GDMK_POINTER] = GOVD_MAP | GOVD_MAP_0LEN_ARRAY;
9037 ctx->defaultmap[GDMK_SCALAR] = GOVD_FIRSTPRIVATE;
9038 ctx->defaultmap[GDMK_SCALAR_TARGET] = (lang_GNU_Fortran ()
9039 ? GOVD_MAP : GOVD_FIRSTPRIVATE);
9041 if (!lang_GNU_Fortran ())
9042 switch (code)
9044 case OMP_TARGET:
9045 case OMP_TARGET_DATA:
9046 case OMP_TARGET_ENTER_DATA:
9047 case OMP_TARGET_EXIT_DATA:
9048 case OACC_DECLARE:
9049 case OACC_HOST_DATA:
9050 case OACC_PARALLEL:
9051 case OACC_KERNELS:
9052 ctx->target_firstprivatize_array_bases = true;
9053 default:
9054 break;
9057 if (code == OMP_TARGET
9058 || code == OMP_TARGET_DATA
9059 || code == OMP_TARGET_ENTER_DATA
9060 || code == OMP_TARGET_EXIT_DATA)
9061 omp_target_reorder_clauses (list_p);
9063 while ((c = *list_p) != NULL)
9065 bool remove = false;
9066 bool notice_outer = true;
9067 const char *check_non_private = NULL;
9068 unsigned int flags;
9069 tree decl;
9071 switch (OMP_CLAUSE_CODE (c))
9073 case OMP_CLAUSE_PRIVATE:
9074 flags = GOVD_PRIVATE | GOVD_EXPLICIT;
9075 if (lang_hooks.decls.omp_private_outer_ref (OMP_CLAUSE_DECL (c)))
9077 flags |= GOVD_PRIVATE_OUTER_REF;
9078 OMP_CLAUSE_PRIVATE_OUTER_REF (c) = 1;
9080 else
9081 notice_outer = false;
9082 goto do_add;
9083 case OMP_CLAUSE_SHARED:
9084 flags = GOVD_SHARED | GOVD_EXPLICIT;
9085 goto do_add;
9086 case OMP_CLAUSE_FIRSTPRIVATE:
9087 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
9088 check_non_private = "firstprivate";
9089 if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c))
9091 gcc_assert (code == OMP_TARGET);
9092 flags |= GOVD_FIRSTPRIVATE_IMPLICIT;
9094 goto do_add;
9095 case OMP_CLAUSE_LASTPRIVATE:
9096 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
9097 switch (code)
9099 case OMP_DISTRIBUTE:
9100 error_at (OMP_CLAUSE_LOCATION (c),
9101 "conditional %<lastprivate%> clause on "
9102 "%qs construct", "distribute");
9103 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
9104 break;
9105 case OMP_TASKLOOP:
9106 error_at (OMP_CLAUSE_LOCATION (c),
9107 "conditional %<lastprivate%> clause on "
9108 "%qs construct", "taskloop");
9109 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
9110 break;
9111 default:
9112 break;
9114 flags = GOVD_LASTPRIVATE | GOVD_SEEN | GOVD_EXPLICIT;
9115 if (code != OMP_LOOP)
9116 check_non_private = "lastprivate";
9117 decl = OMP_CLAUSE_DECL (c);
9118 if (error_operand_p (decl))
9119 goto do_add;
9120 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)
9121 && !lang_hooks.decls.omp_scalar_p (decl, true))
9123 error_at (OMP_CLAUSE_LOCATION (c),
9124 "non-scalar variable %qD in conditional "
9125 "%<lastprivate%> clause", decl);
9126 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
9128 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
9129 flags |= GOVD_LASTPRIVATE_CONDITIONAL;
9130 omp_lastprivate_for_combined_outer_constructs (outer_ctx, decl,
9131 false);
9132 goto do_add;
9133 case OMP_CLAUSE_REDUCTION:
9134 if (OMP_CLAUSE_REDUCTION_TASK (c))
9136 if (region_type == ORT_WORKSHARE || code == OMP_SCOPE)
9138 if (nowait == -1)
9139 nowait = omp_find_clause (*list_p,
9140 OMP_CLAUSE_NOWAIT) != NULL_TREE;
9141 if (nowait
9142 && (outer_ctx == NULL
9143 || outer_ctx->region_type != ORT_COMBINED_PARALLEL))
9145 error_at (OMP_CLAUSE_LOCATION (c),
9146 "%<task%> reduction modifier on a construct "
9147 "with a %<nowait%> clause");
9148 OMP_CLAUSE_REDUCTION_TASK (c) = 0;
9151 else if ((region_type & ORT_PARALLEL) != ORT_PARALLEL)
9153 error_at (OMP_CLAUSE_LOCATION (c),
9154 "invalid %<task%> reduction modifier on construct "
9155 "other than %<parallel%>, %qs, %<sections%> or "
9156 "%<scope%>", lang_GNU_Fortran () ? "do" : "for");
9157 OMP_CLAUSE_REDUCTION_TASK (c) = 0;
9160 if (OMP_CLAUSE_REDUCTION_INSCAN (c))
9161 switch (code)
9163 case OMP_SECTIONS:
9164 error_at (OMP_CLAUSE_LOCATION (c),
9165 "%<inscan%> %<reduction%> clause on "
9166 "%qs construct", "sections");
9167 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
9168 break;
9169 case OMP_PARALLEL:
9170 error_at (OMP_CLAUSE_LOCATION (c),
9171 "%<inscan%> %<reduction%> clause on "
9172 "%qs construct", "parallel");
9173 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
9174 break;
9175 case OMP_TEAMS:
9176 error_at (OMP_CLAUSE_LOCATION (c),
9177 "%<inscan%> %<reduction%> clause on "
9178 "%qs construct", "teams");
9179 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
9180 break;
9181 case OMP_TASKLOOP:
9182 error_at (OMP_CLAUSE_LOCATION (c),
9183 "%<inscan%> %<reduction%> clause on "
9184 "%qs construct", "taskloop");
9185 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
9186 break;
9187 case OMP_SCOPE:
9188 error_at (OMP_CLAUSE_LOCATION (c),
9189 "%<inscan%> %<reduction%> clause on "
9190 "%qs construct", "scope");
9191 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
9192 break;
9193 default:
9194 break;
9196 /* FALLTHRU */
9197 case OMP_CLAUSE_IN_REDUCTION:
9198 case OMP_CLAUSE_TASK_REDUCTION:
9199 flags = GOVD_REDUCTION | GOVD_SEEN | GOVD_EXPLICIT;
9200 /* OpenACC permits reductions on private variables. */
9201 if (!(region_type & ORT_ACC)
9202 /* taskgroup is actually not a worksharing region. */
9203 && code != OMP_TASKGROUP)
9204 check_non_private = omp_clause_code_name[OMP_CLAUSE_CODE (c)];
9205 decl = OMP_CLAUSE_DECL (c);
9206 if (TREE_CODE (decl) == MEM_REF)
9208 tree type = TREE_TYPE (decl);
9209 bool saved_into_ssa = gimplify_ctxp->into_ssa;
9210 gimplify_ctxp->into_ssa = false;
9211 if (gimplify_expr (&TYPE_MAX_VALUE (TYPE_DOMAIN (type)), pre_p,
9212 NULL, is_gimple_val, fb_rvalue, false)
9213 == GS_ERROR)
9215 gimplify_ctxp->into_ssa = saved_into_ssa;
9216 remove = true;
9217 break;
9219 gimplify_ctxp->into_ssa = saved_into_ssa;
9220 tree v = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
9221 if (DECL_P (v))
9223 omp_firstprivatize_variable (ctx, v);
9224 omp_notice_variable (ctx, v, true);
9226 decl = TREE_OPERAND (decl, 0);
9227 if (TREE_CODE (decl) == POINTER_PLUS_EXPR)
9229 gimplify_ctxp->into_ssa = false;
9230 if (gimplify_expr (&TREE_OPERAND (decl, 1), pre_p,
9231 NULL, is_gimple_val, fb_rvalue, false)
9232 == GS_ERROR)
9234 gimplify_ctxp->into_ssa = saved_into_ssa;
9235 remove = true;
9236 break;
9238 gimplify_ctxp->into_ssa = saved_into_ssa;
9239 v = TREE_OPERAND (decl, 1);
9240 if (DECL_P (v))
9242 omp_firstprivatize_variable (ctx, v);
9243 omp_notice_variable (ctx, v, true);
9245 decl = TREE_OPERAND (decl, 0);
9247 if (TREE_CODE (decl) == ADDR_EXPR
9248 || TREE_CODE (decl) == INDIRECT_REF)
9249 decl = TREE_OPERAND (decl, 0);
9251 goto do_add_decl;
9252 case OMP_CLAUSE_LINEAR:
9253 if (gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c), pre_p, NULL,
9254 is_gimple_val, fb_rvalue) == GS_ERROR)
9256 remove = true;
9257 break;
9259 else
9261 if (code == OMP_SIMD
9262 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
9264 struct gimplify_omp_ctx *octx = outer_ctx;
9265 if (octx
9266 && octx->region_type == ORT_WORKSHARE
9267 && octx->combined_loop
9268 && !octx->distribute)
9270 if (octx->outer_context
9271 && (octx->outer_context->region_type
9272 == ORT_COMBINED_PARALLEL))
9273 octx = octx->outer_context->outer_context;
9274 else
9275 octx = octx->outer_context;
9277 if (octx
9278 && octx->region_type == ORT_WORKSHARE
9279 && octx->combined_loop
9280 && octx->distribute)
9282 error_at (OMP_CLAUSE_LOCATION (c),
9283 "%<linear%> clause for variable other than "
9284 "loop iterator specified on construct "
9285 "combined with %<distribute%>");
9286 remove = true;
9287 break;
9290 /* For combined #pragma omp parallel for simd, need to put
9291 lastprivate and perhaps firstprivate too on the
9292 parallel. Similarly for #pragma omp for simd. */
9293 struct gimplify_omp_ctx *octx = outer_ctx;
9294 bool taskloop_seen = false;
9295 decl = NULL_TREE;
9298 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
9299 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
9300 break;
9301 decl = OMP_CLAUSE_DECL (c);
9302 if (error_operand_p (decl))
9304 decl = NULL_TREE;
9305 break;
9307 flags = GOVD_SEEN;
9308 if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c))
9309 flags |= GOVD_FIRSTPRIVATE;
9310 if (!OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
9311 flags |= GOVD_LASTPRIVATE;
9312 if (octx
9313 && octx->region_type == ORT_WORKSHARE
9314 && octx->combined_loop)
9316 if (octx->outer_context
9317 && (octx->outer_context->region_type
9318 == ORT_COMBINED_PARALLEL))
9319 octx = octx->outer_context;
9320 else if (omp_check_private (octx, decl, false))
9321 break;
9323 else if (octx
9324 && (octx->region_type & ORT_TASK) != 0
9325 && octx->combined_loop)
9326 taskloop_seen = true;
9327 else if (octx
9328 && octx->region_type == ORT_COMBINED_PARALLEL
9329 && ((ctx->region_type == ORT_WORKSHARE
9330 && octx == outer_ctx)
9331 || taskloop_seen))
9332 flags = GOVD_SEEN | GOVD_SHARED;
9333 else if (octx
9334 && ((octx->region_type & ORT_COMBINED_TEAMS)
9335 == ORT_COMBINED_TEAMS))
9336 flags = GOVD_SEEN | GOVD_SHARED;
9337 else if (octx
9338 && octx->region_type == ORT_COMBINED_TARGET)
9340 if (flags & GOVD_LASTPRIVATE)
9341 flags = GOVD_SEEN | GOVD_MAP;
9343 else
9344 break;
9345 splay_tree_node on
9346 = splay_tree_lookup (octx->variables,
9347 (splay_tree_key) decl);
9348 if (on && (on->value & GOVD_DATA_SHARE_CLASS) != 0)
9350 octx = NULL;
9351 break;
9353 omp_add_variable (octx, decl, flags);
9354 if (octx->outer_context == NULL)
9355 break;
9356 octx = octx->outer_context;
9358 while (1);
9359 if (octx
9360 && decl
9361 && (!OMP_CLAUSE_LINEAR_NO_COPYIN (c)
9362 || !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
9363 omp_notice_variable (octx, decl, true);
9365 flags = GOVD_LINEAR | GOVD_EXPLICIT;
9366 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
9367 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
9369 notice_outer = false;
9370 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
9372 goto do_add;
9374 case OMP_CLAUSE_MAP:
9375 decl = OMP_CLAUSE_DECL (c);
9376 if (error_operand_p (decl))
9377 remove = true;
9378 switch (code)
9380 case OMP_TARGET:
9381 break;
9382 case OACC_DATA:
9383 if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
9384 break;
9385 /* FALLTHRU */
9386 case OMP_TARGET_DATA:
9387 case OMP_TARGET_ENTER_DATA:
9388 case OMP_TARGET_EXIT_DATA:
9389 case OACC_ENTER_DATA:
9390 case OACC_EXIT_DATA:
9391 case OACC_HOST_DATA:
9392 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
9393 || (OMP_CLAUSE_MAP_KIND (c)
9394 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
9395 /* For target {,enter ,exit }data only the array slice is
9396 mapped, but not the pointer to it. */
9397 remove = true;
9398 break;
9399 default:
9400 break;
9402 /* For Fortran, not only the pointer to the data is mapped but also
9403 the address of the pointer, the array descriptor etc.; for
9404 'exit data' - and in particular for 'delete:' - having an 'alloc:'
9405 does not make sense. Likewise, for 'update' only transferring the
9406 data itself is needed as the rest has been handled in previous
9407 directives. However, for 'exit data', the array descriptor needs
9408 to be delete; hence, we turn the MAP_TO_PSET into a MAP_DELETE.
9410 NOTE: Generally, it is not safe to perform "enter data" operations
9411 on arrays where the data *or the descriptor* may go out of scope
9412 before a corresponding "exit data" operation -- and such a
9413 descriptor may be synthesized temporarily, e.g. to pass an
9414 explicit-shape array to a function expecting an assumed-shape
9415 argument. Performing "enter data" inside the called function
9416 would thus be problematic. */
9417 if (code == OMP_TARGET_EXIT_DATA
9418 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_TO_PSET)
9419 OMP_CLAUSE_SET_MAP_KIND (c, OMP_CLAUSE_MAP_KIND (*prev_list_p)
9420 == GOMP_MAP_DELETE
9421 ? GOMP_MAP_DELETE : GOMP_MAP_RELEASE);
9422 else if ((code == OMP_TARGET_EXIT_DATA || code == OMP_TARGET_UPDATE)
9423 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
9424 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_TO_PSET))
9425 remove = true;
9427 if (remove)
9428 break;
9429 if (DECL_P (decl) && outer_ctx && (region_type & ORT_ACC))
9431 struct gimplify_omp_ctx *octx;
9432 for (octx = outer_ctx; octx; octx = octx->outer_context)
9434 if (octx->region_type != ORT_ACC_HOST_DATA)
9435 break;
9436 splay_tree_node n2
9437 = splay_tree_lookup (octx->variables,
9438 (splay_tree_key) decl);
9439 if (n2)
9440 error_at (OMP_CLAUSE_LOCATION (c), "variable %qE "
9441 "declared in enclosing %<host_data%> region",
9442 DECL_NAME (decl));
9445 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
9446 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
9447 : TYPE_SIZE_UNIT (TREE_TYPE (decl));
9448 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
9449 NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
9451 remove = true;
9452 break;
9454 else if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
9455 || (OMP_CLAUSE_MAP_KIND (c)
9456 == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
9457 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
9458 && TREE_CODE (OMP_CLAUSE_SIZE (c)) != INTEGER_CST)
9460 OMP_CLAUSE_SIZE (c)
9461 = get_initialized_tmp_var (OMP_CLAUSE_SIZE (c), pre_p, NULL,
9462 false);
9463 if ((region_type & ORT_TARGET) != 0)
9464 omp_add_variable (ctx, OMP_CLAUSE_SIZE (c),
9465 GOVD_FIRSTPRIVATE | GOVD_SEEN);
9468 if (TREE_CODE (decl) == TARGET_EXPR)
9470 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
9471 is_gimple_lvalue, fb_lvalue)
9472 == GS_ERROR)
9473 remove = true;
9475 else if (!DECL_P (decl))
9477 tree d = decl, *pd;
9478 if (TREE_CODE (d) == ARRAY_REF)
9480 while (TREE_CODE (d) == ARRAY_REF)
9481 d = TREE_OPERAND (d, 0);
9482 if (TREE_CODE (d) == COMPONENT_REF
9483 && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE)
9484 decl = d;
9486 pd = &OMP_CLAUSE_DECL (c);
9487 if (d == decl
9488 && TREE_CODE (decl) == INDIRECT_REF
9489 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
9490 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
9491 == REFERENCE_TYPE)
9492 && (OMP_CLAUSE_MAP_KIND (c)
9493 != GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION))
9495 pd = &TREE_OPERAND (decl, 0);
9496 decl = TREE_OPERAND (decl, 0);
9498 bool indir_p = false;
9499 bool component_ref_p = false;
9500 tree indir_base = NULL_TREE;
9501 tree orig_decl = decl;
9502 tree decl_ref = NULL_TREE;
9503 if ((region_type & (ORT_ACC | ORT_TARGET | ORT_TARGET_DATA)) != 0
9504 && TREE_CODE (*pd) == COMPONENT_REF
9505 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH
9506 && code != OACC_UPDATE)
9508 while (TREE_CODE (decl) == COMPONENT_REF)
9510 decl = TREE_OPERAND (decl, 0);
9511 component_ref_p = true;
9512 if (((TREE_CODE (decl) == MEM_REF
9513 && integer_zerop (TREE_OPERAND (decl, 1)))
9514 || INDIRECT_REF_P (decl))
9515 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
9516 == POINTER_TYPE))
9518 indir_p = true;
9519 indir_base = decl;
9520 decl = TREE_OPERAND (decl, 0);
9521 STRIP_NOPS (decl);
9523 if (TREE_CODE (decl) == INDIRECT_REF
9524 && DECL_P (TREE_OPERAND (decl, 0))
9525 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
9526 == REFERENCE_TYPE))
9528 decl_ref = decl;
9529 decl = TREE_OPERAND (decl, 0);
9533 else if (TREE_CODE (decl) == COMPONENT_REF
9534 && (OMP_CLAUSE_MAP_KIND (c)
9535 != GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION))
9537 component_ref_p = true;
9538 while (TREE_CODE (decl) == COMPONENT_REF)
9539 decl = TREE_OPERAND (decl, 0);
9540 if (TREE_CODE (decl) == INDIRECT_REF
9541 && DECL_P (TREE_OPERAND (decl, 0))
9542 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
9543 == REFERENCE_TYPE))
9544 decl = TREE_OPERAND (decl, 0);
9546 if (decl != orig_decl && DECL_P (decl) && indir_p)
9548 gomp_map_kind k
9549 = ((code == OACC_EXIT_DATA || code == OMP_TARGET_EXIT_DATA)
9550 ? GOMP_MAP_DETACH : GOMP_MAP_ATTACH);
9551 /* We have a dereference of a struct member. Make this an
9552 attach/detach operation, and ensure the base pointer is
9553 mapped as a FIRSTPRIVATE_POINTER. */
9554 OMP_CLAUSE_SET_MAP_KIND (c, k);
9555 flags = GOVD_MAP | GOVD_SEEN | GOVD_EXPLICIT;
9556 tree next_clause = OMP_CLAUSE_CHAIN (c);
9557 if (k == GOMP_MAP_ATTACH
9558 && code != OACC_ENTER_DATA
9559 && code != OMP_TARGET_ENTER_DATA
9560 && (!next_clause
9561 || (OMP_CLAUSE_CODE (next_clause) != OMP_CLAUSE_MAP)
9562 || (OMP_CLAUSE_MAP_KIND (next_clause)
9563 != GOMP_MAP_POINTER)
9564 || OMP_CLAUSE_DECL (next_clause) != decl)
9565 && (!struct_deref_set
9566 || !struct_deref_set->contains (decl))
9567 && (!struct_map_to_clause
9568 || !struct_map_to_clause->get (indir_base)))
9570 if (!struct_deref_set)
9571 struct_deref_set = new hash_set<tree> ();
9572 /* As well as the attach, we also need a
9573 FIRSTPRIVATE_POINTER clause to properly map the
9574 pointer to the struct base. */
9575 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9576 OMP_CLAUSE_MAP);
9577 OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_ALLOC);
9578 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (c2)
9579 = 1;
9580 tree charptr_zero
9581 = build_int_cst (build_pointer_type (char_type_node),
9583 OMP_CLAUSE_DECL (c2)
9584 = build2 (MEM_REF, char_type_node,
9585 decl_ref ? decl_ref : decl, charptr_zero);
9586 OMP_CLAUSE_SIZE (c2) = size_zero_node;
9587 tree c3 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9588 OMP_CLAUSE_MAP);
9589 OMP_CLAUSE_SET_MAP_KIND (c3,
9590 GOMP_MAP_FIRSTPRIVATE_POINTER);
9591 OMP_CLAUSE_DECL (c3) = decl;
9592 OMP_CLAUSE_SIZE (c3) = size_zero_node;
9593 tree mapgrp = *prev_list_p;
9594 *prev_list_p = c2;
9595 OMP_CLAUSE_CHAIN (c3) = mapgrp;
9596 OMP_CLAUSE_CHAIN (c2) = c3;
9598 struct_deref_set->add (decl);
9600 goto do_add_decl;
9602 /* An "attach/detach" operation on an update directive should
9603 behave as a GOMP_MAP_ALWAYS_POINTER. Beware that
9604 unlike attach or detach map kinds, GOMP_MAP_ALWAYS_POINTER
9605 depends on the previous mapping. */
9606 if (code == OACC_UPDATE
9607 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
9608 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_ALWAYS_POINTER);
9609 if ((DECL_P (decl)
9610 || (component_ref_p
9611 && (INDIRECT_REF_P (decl)
9612 || TREE_CODE (decl) == MEM_REF
9613 || TREE_CODE (decl) == ARRAY_REF)))
9614 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_TO_PSET
9615 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH
9616 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_DETACH
9617 && code != OACC_UPDATE
9618 && code != OMP_TARGET_UPDATE)
9620 if (error_operand_p (decl))
9622 remove = true;
9623 break;
9626 tree stype = TREE_TYPE (decl);
9627 if (TREE_CODE (stype) == REFERENCE_TYPE)
9628 stype = TREE_TYPE (stype);
9629 if (TYPE_SIZE_UNIT (stype) == NULL
9630 || TREE_CODE (TYPE_SIZE_UNIT (stype)) != INTEGER_CST)
9632 error_at (OMP_CLAUSE_LOCATION (c),
9633 "mapping field %qE of variable length "
9634 "structure", OMP_CLAUSE_DECL (c));
9635 remove = true;
9636 break;
9639 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER
9640 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
9642 /* Error recovery. */
9643 if (prev_list_p == NULL)
9645 remove = true;
9646 break;
9649 /* The below prev_list_p based error recovery code is
9650 currently no longer valid for OpenMP. */
9651 if (code != OMP_TARGET
9652 && code != OMP_TARGET_DATA
9653 && code != OMP_TARGET_UPDATE
9654 && code != OMP_TARGET_ENTER_DATA
9655 && code != OMP_TARGET_EXIT_DATA
9656 && OMP_CLAUSE_CHAIN (*prev_list_p) != c)
9658 tree ch = OMP_CLAUSE_CHAIN (*prev_list_p);
9659 if (ch == NULL_TREE || OMP_CLAUSE_CHAIN (ch) != c)
9661 remove = true;
9662 break;
9667 poly_offset_int offset1;
9668 poly_int64 bitpos1;
9669 tree tree_offset1;
9670 tree base_ref;
9672 tree base
9673 = extract_base_bit_offset (OMP_CLAUSE_DECL (c), &base_ref,
9674 &bitpos1, &offset1,
9675 &tree_offset1);
9677 bool do_map_struct = (base == decl && !tree_offset1);
9679 splay_tree_node n
9680 = (DECL_P (decl)
9681 ? splay_tree_lookup (ctx->variables,
9682 (splay_tree_key) decl)
9683 : NULL);
9684 bool ptr = (OMP_CLAUSE_MAP_KIND (c)
9685 == GOMP_MAP_ALWAYS_POINTER);
9686 bool attach_detach = (OMP_CLAUSE_MAP_KIND (c)
9687 == GOMP_MAP_ATTACH_DETACH);
9688 bool attach = OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
9689 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH;
9690 bool has_attachments = false;
9691 /* For OpenACC, pointers in structs should trigger an
9692 attach action. */
9693 if (attach_detach
9694 && ((region_type & (ORT_ACC | ORT_TARGET | ORT_TARGET_DATA))
9695 || code == OMP_TARGET_ENTER_DATA
9696 || code == OMP_TARGET_EXIT_DATA))
9699 /* Turn a GOMP_MAP_ATTACH_DETACH clause into a
9700 GOMP_MAP_ATTACH or GOMP_MAP_DETACH clause after we
9701 have detected a case that needs a GOMP_MAP_STRUCT
9702 mapping added. */
9703 gomp_map_kind k
9704 = ((code == OACC_EXIT_DATA || code == OMP_TARGET_EXIT_DATA)
9705 ? GOMP_MAP_DETACH : GOMP_MAP_ATTACH);
9706 OMP_CLAUSE_SET_MAP_KIND (c, k);
9707 has_attachments = true;
9710 /* We currently don't handle non-constant offset accesses wrt to
9711 GOMP_MAP_STRUCT elements. */
9712 if (!do_map_struct)
9713 goto skip_map_struct;
9715 /* Nor for attach_detach for OpenMP. */
9716 if ((code == OMP_TARGET
9717 || code == OMP_TARGET_DATA
9718 || code == OMP_TARGET_UPDATE
9719 || code == OMP_TARGET_ENTER_DATA
9720 || code == OMP_TARGET_EXIT_DATA)
9721 && attach_detach)
9723 if (DECL_P (decl))
9725 if (struct_seen_clause == NULL)
9726 struct_seen_clause
9727 = new hash_map<tree_operand_hash, tree *>;
9728 if (!struct_seen_clause->get (decl))
9729 struct_seen_clause->put (decl, list_p);
9732 goto skip_map_struct;
9735 if ((DECL_P (decl)
9736 && (n == NULL || (n->value & GOVD_MAP) == 0))
9737 || (!DECL_P (decl)
9738 && (!struct_map_to_clause
9739 || struct_map_to_clause->get (decl) == NULL)))
9741 tree l = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9742 OMP_CLAUSE_MAP);
9743 gomp_map_kind k = attach ? GOMP_MAP_FORCE_PRESENT
9744 : GOMP_MAP_STRUCT;
9746 OMP_CLAUSE_SET_MAP_KIND (l, k);
9747 if (base_ref)
9748 OMP_CLAUSE_DECL (l) = unshare_expr (base_ref);
9749 else
9751 OMP_CLAUSE_DECL (l) = unshare_expr (decl);
9752 if (!DECL_P (OMP_CLAUSE_DECL (l))
9753 && (gimplify_expr (&OMP_CLAUSE_DECL (l),
9754 pre_p, NULL, is_gimple_lvalue,
9755 fb_lvalue)
9756 == GS_ERROR))
9758 remove = true;
9759 break;
9762 OMP_CLAUSE_SIZE (l)
9763 = (!attach
9764 ? size_int (1)
9765 : DECL_P (OMP_CLAUSE_DECL (l))
9766 ? DECL_SIZE_UNIT (OMP_CLAUSE_DECL (l))
9767 : TYPE_SIZE_UNIT (TREE_TYPE (OMP_CLAUSE_DECL (l))));
9768 if (struct_map_to_clause == NULL)
9769 struct_map_to_clause
9770 = new hash_map<tree_operand_hash, tree>;
9771 struct_map_to_clause->put (decl, l);
9772 if (ptr || attach_detach)
9774 tree **sc = (struct_seen_clause
9775 ? struct_seen_clause->get (decl)
9776 : NULL);
9777 tree *insert_node_pos = sc ? *sc : prev_list_p;
9779 insert_struct_comp_map (code, c, l, *insert_node_pos,
9780 NULL);
9781 *insert_node_pos = l;
9782 prev_list_p = NULL;
9784 else
9786 OMP_CLAUSE_CHAIN (l) = c;
9787 *list_p = l;
9788 list_p = &OMP_CLAUSE_CHAIN (l);
9790 if (base_ref && code == OMP_TARGET)
9792 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9793 OMP_CLAUSE_MAP);
9794 enum gomp_map_kind mkind
9795 = GOMP_MAP_FIRSTPRIVATE_REFERENCE;
9796 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
9797 OMP_CLAUSE_DECL (c2) = decl;
9798 OMP_CLAUSE_SIZE (c2) = size_zero_node;
9799 OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (l);
9800 OMP_CLAUSE_CHAIN (l) = c2;
9802 flags = GOVD_MAP | GOVD_EXPLICIT;
9803 if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c))
9804 || ptr
9805 || attach_detach)
9806 flags |= GOVD_SEEN;
9807 if (has_attachments)
9808 flags |= GOVD_MAP_HAS_ATTACHMENTS;
9810 /* If this is a *pointer-to-struct expression, make sure a
9811 firstprivate map of the base-pointer exists. */
9812 if (component_ref_p
9813 && ((TREE_CODE (decl) == MEM_REF
9814 && integer_zerop (TREE_OPERAND (decl, 1)))
9815 || INDIRECT_REF_P (decl))
9816 && DECL_P (TREE_OPERAND (decl, 0))
9817 && !splay_tree_lookup (ctx->variables,
9818 ((splay_tree_key)
9819 TREE_OPERAND (decl, 0))))
9821 decl = TREE_OPERAND (decl, 0);
9822 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9823 OMP_CLAUSE_MAP);
9824 enum gomp_map_kind mkind
9825 = GOMP_MAP_FIRSTPRIVATE_POINTER;
9826 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
9827 OMP_CLAUSE_DECL (c2) = decl;
9828 OMP_CLAUSE_SIZE (c2) = size_zero_node;
9829 OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (c);
9830 OMP_CLAUSE_CHAIN (c) = c2;
9833 if (DECL_P (decl))
9834 goto do_add_decl;
9836 else if (struct_map_to_clause)
9838 tree *osc = struct_map_to_clause->get (decl);
9839 tree *sc = NULL, *scp = NULL;
9840 if (n != NULL
9841 && (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c))
9842 || ptr
9843 || attach_detach))
9844 n->value |= GOVD_SEEN;
9845 sc = &OMP_CLAUSE_CHAIN (*osc);
9846 if (*sc != c
9847 && (OMP_CLAUSE_MAP_KIND (*sc)
9848 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
9849 sc = &OMP_CLAUSE_CHAIN (*sc);
9850 /* Here "prev_list_p" is the end of the inserted
9851 alloc/release nodes after the struct node, OSC. */
9852 for (; *sc != c; sc = &OMP_CLAUSE_CHAIN (*sc))
9853 if ((ptr || attach_detach) && sc == prev_list_p)
9854 break;
9855 else if (TREE_CODE (OMP_CLAUSE_DECL (*sc))
9856 != COMPONENT_REF
9857 && (TREE_CODE (OMP_CLAUSE_DECL (*sc))
9858 != INDIRECT_REF)
9859 && (TREE_CODE (OMP_CLAUSE_DECL (*sc))
9860 != ARRAY_REF))
9861 break;
9862 else
9864 tree sc_decl = OMP_CLAUSE_DECL (*sc);
9865 poly_offset_int offsetn;
9866 poly_int64 bitposn;
9867 tree tree_offsetn;
9868 tree base
9869 = extract_base_bit_offset (sc_decl, NULL,
9870 &bitposn, &offsetn,
9871 &tree_offsetn);
9872 if (base != decl)
9873 break;
9874 if (scp)
9875 continue;
9876 if ((region_type & ORT_ACC) != 0)
9878 /* This duplicate checking code is currently only
9879 enabled for OpenACC. */
9880 tree d1 = OMP_CLAUSE_DECL (*sc);
9881 tree d2 = OMP_CLAUSE_DECL (c);
9882 while (TREE_CODE (d1) == ARRAY_REF)
9883 d1 = TREE_OPERAND (d1, 0);
9884 while (TREE_CODE (d2) == ARRAY_REF)
9885 d2 = TREE_OPERAND (d2, 0);
9886 if (TREE_CODE (d1) == INDIRECT_REF)
9887 d1 = TREE_OPERAND (d1, 0);
9888 if (TREE_CODE (d2) == INDIRECT_REF)
9889 d2 = TREE_OPERAND (d2, 0);
9890 while (TREE_CODE (d1) == COMPONENT_REF)
9891 if (TREE_CODE (d2) == COMPONENT_REF
9892 && TREE_OPERAND (d1, 1)
9893 == TREE_OPERAND (d2, 1))
9895 d1 = TREE_OPERAND (d1, 0);
9896 d2 = TREE_OPERAND (d2, 0);
9898 else
9899 break;
9900 if (d1 == d2)
9902 error_at (OMP_CLAUSE_LOCATION (c),
9903 "%qE appears more than once in map "
9904 "clauses", OMP_CLAUSE_DECL (c));
9905 remove = true;
9906 break;
9909 if (maybe_lt (offset1, offsetn)
9910 || (known_eq (offset1, offsetn)
9911 && maybe_lt (bitpos1, bitposn)))
9913 if (ptr || attach_detach)
9914 scp = sc;
9915 else
9916 break;
9919 if (remove)
9920 break;
9921 if (!attach)
9922 OMP_CLAUSE_SIZE (*osc)
9923 = size_binop (PLUS_EXPR, OMP_CLAUSE_SIZE (*osc),
9924 size_one_node);
9925 if (ptr || attach_detach)
9927 tree cl = insert_struct_comp_map (code, c, NULL,
9928 *prev_list_p, scp);
9929 if (sc == prev_list_p)
9931 *sc = cl;
9932 prev_list_p = NULL;
9934 else
9936 *prev_list_p = OMP_CLAUSE_CHAIN (c);
9937 list_p = prev_list_p;
9938 prev_list_p = NULL;
9939 OMP_CLAUSE_CHAIN (c) = *sc;
9940 *sc = cl;
9941 continue;
9944 else if (*sc != c)
9946 if (gimplify_expr (pd, pre_p, NULL, is_gimple_lvalue,
9947 fb_lvalue)
9948 == GS_ERROR)
9950 remove = true;
9951 break;
9953 *list_p = OMP_CLAUSE_CHAIN (c);
9954 OMP_CLAUSE_CHAIN (c) = *sc;
9955 *sc = c;
9956 continue;
9959 skip_map_struct:
9962 else if ((code == OACC_ENTER_DATA
9963 || code == OACC_EXIT_DATA
9964 || code == OACC_DATA
9965 || code == OACC_PARALLEL
9966 || code == OACC_KERNELS
9967 || code == OACC_SERIAL
9968 || code == OMP_TARGET_ENTER_DATA
9969 || code == OMP_TARGET_EXIT_DATA)
9970 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
9972 gomp_map_kind k = ((code == OACC_EXIT_DATA
9973 || code == OMP_TARGET_EXIT_DATA)
9974 ? GOMP_MAP_DETACH : GOMP_MAP_ATTACH);
9975 OMP_CLAUSE_SET_MAP_KIND (c, k);
9978 if (code == OMP_TARGET && OMP_CLAUSE_MAP_IN_REDUCTION (c))
9980 /* Don't gimplify *pd fully at this point, as the base
9981 will need to be adjusted during omp lowering. */
9982 auto_vec<tree, 10> expr_stack;
9983 tree *p = pd;
9984 while (handled_component_p (*p)
9985 || TREE_CODE (*p) == INDIRECT_REF
9986 || TREE_CODE (*p) == ADDR_EXPR
9987 || TREE_CODE (*p) == MEM_REF
9988 || TREE_CODE (*p) == NON_LVALUE_EXPR)
9990 expr_stack.safe_push (*p);
9991 p = &TREE_OPERAND (*p, 0);
9993 for (int i = expr_stack.length () - 1; i >= 0; i--)
9995 tree t = expr_stack[i];
9996 if (TREE_CODE (t) == ARRAY_REF
9997 || TREE_CODE (t) == ARRAY_RANGE_REF)
9999 if (TREE_OPERAND (t, 2) == NULL_TREE)
10001 tree low = unshare_expr (array_ref_low_bound (t));
10002 if (!is_gimple_min_invariant (low))
10004 TREE_OPERAND (t, 2) = low;
10005 if (gimplify_expr (&TREE_OPERAND (t, 2),
10006 pre_p, NULL,
10007 is_gimple_reg,
10008 fb_rvalue) == GS_ERROR)
10009 remove = true;
10012 else if (gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
10013 NULL, is_gimple_reg,
10014 fb_rvalue) == GS_ERROR)
10015 remove = true;
10016 if (TREE_OPERAND (t, 3) == NULL_TREE)
10018 tree elmt_size = array_ref_element_size (t);
10019 if (!is_gimple_min_invariant (elmt_size))
10021 elmt_size = unshare_expr (elmt_size);
10022 tree elmt_type
10023 = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t,
10024 0)));
10025 tree factor
10026 = size_int (TYPE_ALIGN_UNIT (elmt_type));
10027 elmt_size
10028 = size_binop (EXACT_DIV_EXPR, elmt_size,
10029 factor);
10030 TREE_OPERAND (t, 3) = elmt_size;
10031 if (gimplify_expr (&TREE_OPERAND (t, 3),
10032 pre_p, NULL,
10033 is_gimple_reg,
10034 fb_rvalue) == GS_ERROR)
10035 remove = true;
10038 else if (gimplify_expr (&TREE_OPERAND (t, 3), pre_p,
10039 NULL, is_gimple_reg,
10040 fb_rvalue) == GS_ERROR)
10041 remove = true;
10043 else if (TREE_CODE (t) == COMPONENT_REF)
10045 if (TREE_OPERAND (t, 2) == NULL_TREE)
10047 tree offset = component_ref_field_offset (t);
10048 if (!is_gimple_min_invariant (offset))
10050 offset = unshare_expr (offset);
10051 tree field = TREE_OPERAND (t, 1);
10052 tree factor
10053 = size_int (DECL_OFFSET_ALIGN (field)
10054 / BITS_PER_UNIT);
10055 offset = size_binop (EXACT_DIV_EXPR, offset,
10056 factor);
10057 TREE_OPERAND (t, 2) = offset;
10058 if (gimplify_expr (&TREE_OPERAND (t, 2),
10059 pre_p, NULL,
10060 is_gimple_reg,
10061 fb_rvalue) == GS_ERROR)
10062 remove = true;
10065 else if (gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
10066 NULL, is_gimple_reg,
10067 fb_rvalue) == GS_ERROR)
10068 remove = true;
10071 for (; expr_stack.length () > 0; )
10073 tree t = expr_stack.pop ();
10075 if (TREE_CODE (t) == ARRAY_REF
10076 || TREE_CODE (t) == ARRAY_RANGE_REF)
10078 if (!is_gimple_min_invariant (TREE_OPERAND (t, 1))
10079 && gimplify_expr (&TREE_OPERAND (t, 1), pre_p,
10080 NULL, is_gimple_val,
10081 fb_rvalue) == GS_ERROR)
10082 remove = true;
10086 else if (gimplify_expr (pd, pre_p, NULL, is_gimple_lvalue,
10087 fb_lvalue) == GS_ERROR)
10089 remove = true;
10090 break;
10093 /* If this was of the form map(*pointer_to_struct), then the
10094 'pointer_to_struct' DECL should be considered deref'ed. */
10095 if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALLOC
10096 || GOMP_MAP_COPY_TO_P (OMP_CLAUSE_MAP_KIND (c))
10097 || GOMP_MAP_COPY_FROM_P (OMP_CLAUSE_MAP_KIND (c)))
10098 && INDIRECT_REF_P (orig_decl)
10099 && DECL_P (TREE_OPERAND (orig_decl, 0))
10100 && TREE_CODE (TREE_TYPE (orig_decl)) == RECORD_TYPE)
10102 tree ptr = TREE_OPERAND (orig_decl, 0);
10103 if (!struct_deref_set || !struct_deref_set->contains (ptr))
10105 if (!struct_deref_set)
10106 struct_deref_set = new hash_set<tree> ();
10107 struct_deref_set->add (ptr);
10111 if (!remove
10112 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_POINTER
10113 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH_DETACH
10114 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_TO_PSET
10115 && OMP_CLAUSE_CHAIN (c)
10116 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (c)) == OMP_CLAUSE_MAP
10117 && ((OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
10118 == GOMP_MAP_ALWAYS_POINTER)
10119 || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
10120 == GOMP_MAP_ATTACH_DETACH)
10121 || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
10122 == GOMP_MAP_TO_PSET)))
10123 prev_list_p = list_p;
10125 break;
10127 else
10129 /* DECL_P (decl) == true */
10130 tree *sc;
10131 if (struct_map_to_clause
10132 && (sc = struct_map_to_clause->get (decl)) != NULL
10133 && OMP_CLAUSE_MAP_KIND (*sc) == GOMP_MAP_STRUCT
10134 && decl == OMP_CLAUSE_DECL (*sc))
10136 /* We have found a map of the whole structure after a
10137 leading GOMP_MAP_STRUCT has been created, so refill the
10138 leading clause into a map of the whole structure
10139 variable, and remove the current one.
10140 TODO: we should be able to remove some maps of the
10141 following structure element maps if they are of
10142 compatible TO/FROM/ALLOC type. */
10143 OMP_CLAUSE_SET_MAP_KIND (*sc, OMP_CLAUSE_MAP_KIND (c));
10144 OMP_CLAUSE_SIZE (*sc) = unshare_expr (OMP_CLAUSE_SIZE (c));
10145 remove = true;
10146 break;
10149 flags = GOVD_MAP | GOVD_EXPLICIT;
10150 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TO
10151 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TOFROM)
10152 flags |= GOVD_MAP_ALWAYS_TO;
10154 if ((code == OMP_TARGET
10155 || code == OMP_TARGET_DATA
10156 || code == OMP_TARGET_ENTER_DATA
10157 || code == OMP_TARGET_EXIT_DATA)
10158 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
10160 for (struct gimplify_omp_ctx *octx = outer_ctx; octx;
10161 octx = octx->outer_context)
10163 splay_tree_node n
10164 = splay_tree_lookup (octx->variables,
10165 (splay_tree_key) OMP_CLAUSE_DECL (c));
10166 /* If this is contained in an outer OpenMP region as a
10167 firstprivate value, remove the attach/detach. */
10168 if (n && (n->value & GOVD_FIRSTPRIVATE))
10170 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FIRSTPRIVATE_POINTER);
10171 goto do_add;
10175 enum gomp_map_kind map_kind = (code == OMP_TARGET_EXIT_DATA
10176 ? GOMP_MAP_DETACH
10177 : GOMP_MAP_ATTACH);
10178 OMP_CLAUSE_SET_MAP_KIND (c, map_kind);
10181 goto do_add;
10183 case OMP_CLAUSE_AFFINITY:
10184 gimplify_omp_affinity (list_p, pre_p);
10185 remove = true;
10186 break;
10187 case OMP_CLAUSE_DEPEND:
10188 if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
10190 tree deps = OMP_CLAUSE_DECL (c);
10191 while (deps && TREE_CODE (deps) == TREE_LIST)
10193 if (TREE_CODE (TREE_PURPOSE (deps)) == TRUNC_DIV_EXPR
10194 && DECL_P (TREE_OPERAND (TREE_PURPOSE (deps), 1)))
10195 gimplify_expr (&TREE_OPERAND (TREE_PURPOSE (deps), 1),
10196 pre_p, NULL, is_gimple_val, fb_rvalue);
10197 deps = TREE_CHAIN (deps);
10199 break;
10201 else if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
10202 break;
10203 if (handled_depend_iterators == -1)
10204 handled_depend_iterators = gimplify_omp_depend (list_p, pre_p);
10205 if (handled_depend_iterators)
10207 if (handled_depend_iterators == 2)
10208 remove = true;
10209 break;
10211 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
10213 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
10214 NULL, is_gimple_val, fb_rvalue);
10215 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
10217 if (error_operand_p (OMP_CLAUSE_DECL (c)))
10219 remove = true;
10220 break;
10222 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
10223 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
10224 is_gimple_val, fb_rvalue) == GS_ERROR)
10226 remove = true;
10227 break;
10229 if (code == OMP_TASK)
10230 ctx->has_depend = true;
10231 break;
10233 case OMP_CLAUSE_TO:
10234 case OMP_CLAUSE_FROM:
10235 case OMP_CLAUSE__CACHE_:
10236 decl = OMP_CLAUSE_DECL (c);
10237 if (error_operand_p (decl))
10239 remove = true;
10240 break;
10242 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
10243 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
10244 : TYPE_SIZE_UNIT (TREE_TYPE (decl));
10245 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
10246 NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
10248 remove = true;
10249 break;
10251 if (!DECL_P (decl))
10253 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p,
10254 NULL, is_gimple_lvalue, fb_lvalue)
10255 == GS_ERROR)
10257 remove = true;
10258 break;
10260 break;
10262 goto do_notice;
10264 case OMP_CLAUSE_USE_DEVICE_PTR:
10265 case OMP_CLAUSE_USE_DEVICE_ADDR:
10266 flags = GOVD_EXPLICIT;
10267 goto do_add;
10269 case OMP_CLAUSE_IS_DEVICE_PTR:
10270 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
10271 goto do_add;
10273 do_add:
10274 decl = OMP_CLAUSE_DECL (c);
10275 do_add_decl:
10276 if (error_operand_p (decl))
10278 remove = true;
10279 break;
10281 if (DECL_NAME (decl) == NULL_TREE && (flags & GOVD_SHARED) == 0)
10283 tree t = omp_member_access_dummy_var (decl);
10284 if (t)
10286 tree v = DECL_VALUE_EXPR (decl);
10287 DECL_NAME (decl) = DECL_NAME (TREE_OPERAND (v, 1));
10288 if (outer_ctx)
10289 omp_notice_variable (outer_ctx, t, true);
10292 if (code == OACC_DATA
10293 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
10294 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
10295 flags |= GOVD_MAP_0LEN_ARRAY;
10296 omp_add_variable (ctx, decl, flags);
10297 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10298 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
10299 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
10300 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
10302 struct gimplify_omp_ctx *pctx
10303 = code == OMP_TARGET ? outer_ctx : ctx;
10304 if (pctx)
10305 omp_add_variable (pctx, OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
10306 GOVD_LOCAL | GOVD_SEEN);
10307 if (pctx
10308 && OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
10309 && walk_tree (&OMP_CLAUSE_REDUCTION_INIT (c),
10310 find_decl_expr,
10311 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
10312 NULL) == NULL_TREE)
10313 omp_add_variable (pctx,
10314 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
10315 GOVD_LOCAL | GOVD_SEEN);
10316 gimplify_omp_ctxp = pctx;
10317 push_gimplify_context ();
10319 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
10320 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
10322 gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c),
10323 &OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c));
10324 pop_gimplify_context
10325 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c)));
10326 push_gimplify_context ();
10327 gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c),
10328 &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
10329 pop_gimplify_context
10330 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c)));
10331 OMP_CLAUSE_REDUCTION_INIT (c) = NULL_TREE;
10332 OMP_CLAUSE_REDUCTION_MERGE (c) = NULL_TREE;
10334 gimplify_omp_ctxp = outer_ctx;
10336 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
10337 && OMP_CLAUSE_LASTPRIVATE_STMT (c))
10339 gimplify_omp_ctxp = ctx;
10340 push_gimplify_context ();
10341 if (TREE_CODE (OMP_CLAUSE_LASTPRIVATE_STMT (c)) != BIND_EXPR)
10343 tree bind = build3 (BIND_EXPR, void_type_node, NULL,
10344 NULL, NULL);
10345 TREE_SIDE_EFFECTS (bind) = 1;
10346 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LASTPRIVATE_STMT (c);
10347 OMP_CLAUSE_LASTPRIVATE_STMT (c) = bind;
10349 gimplify_and_add (OMP_CLAUSE_LASTPRIVATE_STMT (c),
10350 &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
10351 pop_gimplify_context
10352 (gimple_seq_first_stmt (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c)));
10353 OMP_CLAUSE_LASTPRIVATE_STMT (c) = NULL_TREE;
10355 gimplify_omp_ctxp = outer_ctx;
10357 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
10358 && OMP_CLAUSE_LINEAR_STMT (c))
10360 gimplify_omp_ctxp = ctx;
10361 push_gimplify_context ();
10362 if (TREE_CODE (OMP_CLAUSE_LINEAR_STMT (c)) != BIND_EXPR)
10364 tree bind = build3 (BIND_EXPR, void_type_node, NULL,
10365 NULL, NULL);
10366 TREE_SIDE_EFFECTS (bind) = 1;
10367 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LINEAR_STMT (c);
10368 OMP_CLAUSE_LINEAR_STMT (c) = bind;
10370 gimplify_and_add (OMP_CLAUSE_LINEAR_STMT (c),
10371 &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c));
10372 pop_gimplify_context
10373 (gimple_seq_first_stmt (OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c)));
10374 OMP_CLAUSE_LINEAR_STMT (c) = NULL_TREE;
10376 gimplify_omp_ctxp = outer_ctx;
10378 if (notice_outer)
10379 goto do_notice;
10380 break;
10382 case OMP_CLAUSE_COPYIN:
10383 case OMP_CLAUSE_COPYPRIVATE:
10384 decl = OMP_CLAUSE_DECL (c);
10385 if (error_operand_p (decl))
10387 remove = true;
10388 break;
10390 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_COPYPRIVATE
10391 && !remove
10392 && !omp_check_private (ctx, decl, true))
10394 remove = true;
10395 if (is_global_var (decl))
10397 if (DECL_THREAD_LOCAL_P (decl))
10398 remove = false;
10399 else if (DECL_HAS_VALUE_EXPR_P (decl))
10401 tree value = get_base_address (DECL_VALUE_EXPR (decl));
10403 if (value
10404 && DECL_P (value)
10405 && DECL_THREAD_LOCAL_P (value))
10406 remove = false;
10409 if (remove)
10410 error_at (OMP_CLAUSE_LOCATION (c),
10411 "copyprivate variable %qE is not threadprivate"
10412 " or private in outer context", DECL_NAME (decl));
10414 do_notice:
10415 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10416 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
10417 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
10418 && outer_ctx
10419 && ((region_type & ORT_TASKLOOP) == ORT_TASKLOOP
10420 || (region_type == ORT_WORKSHARE
10421 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10422 && (OMP_CLAUSE_REDUCTION_INSCAN (c)
10423 || code == OMP_LOOP)))
10424 && (outer_ctx->region_type == ORT_COMBINED_PARALLEL
10425 || (code == OMP_LOOP
10426 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10427 && ((outer_ctx->region_type & ORT_COMBINED_TEAMS)
10428 == ORT_COMBINED_TEAMS))))
10430 splay_tree_node on
10431 = splay_tree_lookup (outer_ctx->variables,
10432 (splay_tree_key)decl);
10433 if (on == NULL || (on->value & GOVD_DATA_SHARE_CLASS) == 0)
10435 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10436 && TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
10437 && (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
10438 || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
10439 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
10440 == POINTER_TYPE))))
10441 omp_firstprivatize_variable (outer_ctx, decl);
10442 else
10444 omp_add_variable (outer_ctx, decl,
10445 GOVD_SEEN | GOVD_SHARED);
10446 if (outer_ctx->outer_context)
10447 omp_notice_variable (outer_ctx->outer_context, decl,
10448 true);
10452 if (outer_ctx)
10453 omp_notice_variable (outer_ctx, decl, true);
10454 if (check_non_private
10455 && (region_type == ORT_WORKSHARE || code == OMP_SCOPE)
10456 && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
10457 || decl == OMP_CLAUSE_DECL (c)
10458 || (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
10459 && (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
10460 == ADDR_EXPR
10461 || (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
10462 == POINTER_PLUS_EXPR
10463 && (TREE_CODE (TREE_OPERAND (TREE_OPERAND
10464 (OMP_CLAUSE_DECL (c), 0), 0))
10465 == ADDR_EXPR)))))
10466 && omp_check_private (ctx, decl, false))
10468 error ("%s variable %qE is private in outer context",
10469 check_non_private, DECL_NAME (decl));
10470 remove = true;
10472 break;
10474 case OMP_CLAUSE_DETACH:
10475 flags = GOVD_FIRSTPRIVATE | GOVD_SEEN;
10476 goto do_add;
10478 case OMP_CLAUSE_IF:
10479 if (OMP_CLAUSE_IF_MODIFIER (c) != ERROR_MARK
10480 && OMP_CLAUSE_IF_MODIFIER (c) != code)
10482 const char *p[2];
10483 for (int i = 0; i < 2; i++)
10484 switch (i ? OMP_CLAUSE_IF_MODIFIER (c) : code)
10486 case VOID_CST: p[i] = "cancel"; break;
10487 case OMP_PARALLEL: p[i] = "parallel"; break;
10488 case OMP_SIMD: p[i] = "simd"; break;
10489 case OMP_TASK: p[i] = "task"; break;
10490 case OMP_TASKLOOP: p[i] = "taskloop"; break;
10491 case OMP_TARGET_DATA: p[i] = "target data"; break;
10492 case OMP_TARGET: p[i] = "target"; break;
10493 case OMP_TARGET_UPDATE: p[i] = "target update"; break;
10494 case OMP_TARGET_ENTER_DATA:
10495 p[i] = "target enter data"; break;
10496 case OMP_TARGET_EXIT_DATA: p[i] = "target exit data"; break;
10497 default: gcc_unreachable ();
10499 error_at (OMP_CLAUSE_LOCATION (c),
10500 "expected %qs %<if%> clause modifier rather than %qs",
10501 p[0], p[1]);
10502 remove = true;
10504 /* Fall through. */
10506 case OMP_CLAUSE_FINAL:
10507 OMP_CLAUSE_OPERAND (c, 0)
10508 = gimple_boolify (OMP_CLAUSE_OPERAND (c, 0));
10509 /* Fall through. */
10511 case OMP_CLAUSE_NUM_TEAMS:
10512 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
10513 && OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
10514 && !is_gimple_min_invariant (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)))
10516 if (error_operand_p (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)))
10518 remove = true;
10519 break;
10521 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
10522 = get_initialized_tmp_var (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c),
10523 pre_p, NULL, true);
10525 /* Fall through. */
10527 case OMP_CLAUSE_SCHEDULE:
10528 case OMP_CLAUSE_NUM_THREADS:
10529 case OMP_CLAUSE_THREAD_LIMIT:
10530 case OMP_CLAUSE_DIST_SCHEDULE:
10531 case OMP_CLAUSE_DEVICE:
10532 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE
10533 && OMP_CLAUSE_DEVICE_ANCESTOR (c))
10535 if (code != OMP_TARGET)
10537 error_at (OMP_CLAUSE_LOCATION (c),
10538 "%<device%> clause with %<ancestor%> is only "
10539 "allowed on %<target%> construct");
10540 remove = true;
10541 break;
10544 tree clauses = *orig_list_p;
10545 for (; clauses ; clauses = OMP_CLAUSE_CHAIN (clauses))
10546 if (OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_DEVICE
10547 && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_FIRSTPRIVATE
10548 && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_PRIVATE
10549 && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_DEFAULTMAP
10550 && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_MAP
10553 error_at (OMP_CLAUSE_LOCATION (c),
10554 "with %<ancestor%>, only the %<device%>, "
10555 "%<firstprivate%>, %<private%>, %<defaultmap%>, "
10556 "and %<map%> clauses may appear on the "
10557 "construct");
10558 remove = true;
10559 break;
10562 /* Fall through. */
10564 case OMP_CLAUSE_PRIORITY:
10565 case OMP_CLAUSE_GRAINSIZE:
10566 case OMP_CLAUSE_NUM_TASKS:
10567 case OMP_CLAUSE_FILTER:
10568 case OMP_CLAUSE_HINT:
10569 case OMP_CLAUSE_ASYNC:
10570 case OMP_CLAUSE_WAIT:
10571 case OMP_CLAUSE_NUM_GANGS:
10572 case OMP_CLAUSE_NUM_WORKERS:
10573 case OMP_CLAUSE_VECTOR_LENGTH:
10574 case OMP_CLAUSE_WORKER:
10575 case OMP_CLAUSE_VECTOR:
10576 if (OMP_CLAUSE_OPERAND (c, 0)
10577 && !is_gimple_min_invariant (OMP_CLAUSE_OPERAND (c, 0)))
10579 if (error_operand_p (OMP_CLAUSE_OPERAND (c, 0)))
10581 remove = true;
10582 break;
10584 /* All these clauses care about value, not a particular decl,
10585 so try to force it into a SSA_NAME or fresh temporary. */
10586 OMP_CLAUSE_OPERAND (c, 0)
10587 = get_initialized_tmp_var (OMP_CLAUSE_OPERAND (c, 0),
10588 pre_p, NULL, true);
10590 break;
10592 case OMP_CLAUSE_GANG:
10593 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
10594 is_gimple_val, fb_rvalue) == GS_ERROR)
10595 remove = true;
10596 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 1), pre_p, NULL,
10597 is_gimple_val, fb_rvalue) == GS_ERROR)
10598 remove = true;
10599 break;
10601 case OMP_CLAUSE_NOWAIT:
10602 nowait = 1;
10603 break;
10605 case OMP_CLAUSE_ORDERED:
10606 case OMP_CLAUSE_UNTIED:
10607 case OMP_CLAUSE_COLLAPSE:
10608 case OMP_CLAUSE_TILE:
10609 case OMP_CLAUSE_AUTO:
10610 case OMP_CLAUSE_SEQ:
10611 case OMP_CLAUSE_INDEPENDENT:
10612 case OMP_CLAUSE_MERGEABLE:
10613 case OMP_CLAUSE_PROC_BIND:
10614 case OMP_CLAUSE_SAFELEN:
10615 case OMP_CLAUSE_SIMDLEN:
10616 case OMP_CLAUSE_NOGROUP:
10617 case OMP_CLAUSE_THREADS:
10618 case OMP_CLAUSE_SIMD:
10619 case OMP_CLAUSE_BIND:
10620 case OMP_CLAUSE_IF_PRESENT:
10621 case OMP_CLAUSE_FINALIZE:
10622 break;
10624 case OMP_CLAUSE_ORDER:
10625 ctx->order_concurrent = true;
10626 break;
10628 case OMP_CLAUSE_DEFAULTMAP:
10629 enum gimplify_defaultmap_kind gdmkmin, gdmkmax;
10630 switch (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c))
10632 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
10633 gdmkmin = GDMK_SCALAR;
10634 gdmkmax = GDMK_POINTER;
10635 break;
10636 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
10637 gdmkmin = GDMK_SCALAR;
10638 gdmkmax = GDMK_SCALAR_TARGET;
10639 break;
10640 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
10641 gdmkmin = gdmkmax = GDMK_AGGREGATE;
10642 break;
10643 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALLOCATABLE:
10644 gdmkmin = gdmkmax = GDMK_ALLOCATABLE;
10645 break;
10646 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
10647 gdmkmin = gdmkmax = GDMK_POINTER;
10648 break;
10649 default:
10650 gcc_unreachable ();
10652 for (int gdmk = gdmkmin; gdmk <= gdmkmax; gdmk++)
10653 switch (OMP_CLAUSE_DEFAULTMAP_BEHAVIOR (c))
10655 case OMP_CLAUSE_DEFAULTMAP_ALLOC:
10656 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_ALLOC_ONLY;
10657 break;
10658 case OMP_CLAUSE_DEFAULTMAP_TO:
10659 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_TO_ONLY;
10660 break;
10661 case OMP_CLAUSE_DEFAULTMAP_FROM:
10662 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_FROM_ONLY;
10663 break;
10664 case OMP_CLAUSE_DEFAULTMAP_TOFROM:
10665 ctx->defaultmap[gdmk] = GOVD_MAP;
10666 break;
10667 case OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE:
10668 ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE;
10669 break;
10670 case OMP_CLAUSE_DEFAULTMAP_NONE:
10671 ctx->defaultmap[gdmk] = 0;
10672 break;
10673 case OMP_CLAUSE_DEFAULTMAP_DEFAULT:
10674 switch (gdmk)
10676 case GDMK_SCALAR:
10677 ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE;
10678 break;
10679 case GDMK_SCALAR_TARGET:
10680 ctx->defaultmap[gdmk] = (lang_GNU_Fortran ()
10681 ? GOVD_MAP : GOVD_FIRSTPRIVATE);
10682 break;
10683 case GDMK_AGGREGATE:
10684 case GDMK_ALLOCATABLE:
10685 ctx->defaultmap[gdmk] = GOVD_MAP;
10686 break;
10687 case GDMK_POINTER:
10688 ctx->defaultmap[gdmk] = GOVD_MAP;
10689 if (!lang_GNU_Fortran ())
10690 ctx->defaultmap[gdmk] |= GOVD_MAP_0LEN_ARRAY;
10691 break;
10692 default:
10693 gcc_unreachable ();
10695 break;
10696 default:
10697 gcc_unreachable ();
10699 break;
10701 case OMP_CLAUSE_ALIGNED:
10702 decl = OMP_CLAUSE_DECL (c);
10703 if (error_operand_p (decl))
10705 remove = true;
10706 break;
10708 if (gimplify_expr (&OMP_CLAUSE_ALIGNED_ALIGNMENT (c), pre_p, NULL,
10709 is_gimple_val, fb_rvalue) == GS_ERROR)
10711 remove = true;
10712 break;
10714 if (!is_global_var (decl)
10715 && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
10716 omp_add_variable (ctx, decl, GOVD_ALIGNED);
10717 break;
10719 case OMP_CLAUSE_NONTEMPORAL:
10720 decl = OMP_CLAUSE_DECL (c);
10721 if (error_operand_p (decl))
10723 remove = true;
10724 break;
10726 omp_add_variable (ctx, decl, GOVD_NONTEMPORAL);
10727 break;
10729 case OMP_CLAUSE_ALLOCATE:
10730 decl = OMP_CLAUSE_DECL (c);
10731 if (error_operand_p (decl))
10733 remove = true;
10734 break;
10736 if (gimplify_expr (&OMP_CLAUSE_ALLOCATE_ALLOCATOR (c), pre_p, NULL,
10737 is_gimple_val, fb_rvalue) == GS_ERROR)
10739 remove = true;
10740 break;
10742 else if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) == NULL_TREE
10743 || (TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c))
10744 == INTEGER_CST))
10746 else if (code == OMP_TASKLOOP
10747 || !DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)))
10748 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
10749 = get_initialized_tmp_var (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
10750 pre_p, NULL, false);
10751 break;
10753 case OMP_CLAUSE_DEFAULT:
10754 ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
10755 break;
10757 case OMP_CLAUSE_INCLUSIVE:
10758 case OMP_CLAUSE_EXCLUSIVE:
10759 decl = OMP_CLAUSE_DECL (c);
10761 splay_tree_node n = splay_tree_lookup (outer_ctx->variables,
10762 (splay_tree_key) decl);
10763 if (n == NULL || (n->value & GOVD_REDUCTION) == 0)
10765 error_at (OMP_CLAUSE_LOCATION (c),
10766 "%qD specified in %qs clause but not in %<inscan%> "
10767 "%<reduction%> clause on the containing construct",
10768 decl, omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
10769 remove = true;
10771 else
10773 n->value |= GOVD_REDUCTION_INSCAN;
10774 if (outer_ctx->region_type == ORT_SIMD
10775 && outer_ctx->outer_context
10776 && outer_ctx->outer_context->region_type == ORT_WORKSHARE)
10778 n = splay_tree_lookup (outer_ctx->outer_context->variables,
10779 (splay_tree_key) decl);
10780 if (n && (n->value & GOVD_REDUCTION) != 0)
10781 n->value |= GOVD_REDUCTION_INSCAN;
10785 break;
10787 case OMP_CLAUSE_NOHOST:
10788 default:
10789 gcc_unreachable ();
10792 if (code == OACC_DATA
10793 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
10794 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
10795 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
10796 remove = true;
10797 if (remove)
10798 *list_p = OMP_CLAUSE_CHAIN (c);
10799 else
10800 list_p = &OMP_CLAUSE_CHAIN (c);
10803 ctx->clauses = *orig_list_p;
10804 gimplify_omp_ctxp = ctx;
10805 if (struct_seen_clause)
10806 delete struct_seen_clause;
10807 if (struct_map_to_clause)
10808 delete struct_map_to_clause;
10809 if (struct_deref_set)
10810 delete struct_deref_set;
10813 /* Return true if DECL is a candidate for shared to firstprivate
10814 optimization. We only consider non-addressable scalars, not
10815 too big, and not references. */
10817 static bool
10818 omp_shared_to_firstprivate_optimizable_decl_p (tree decl)
10820 if (TREE_ADDRESSABLE (decl))
10821 return false;
10822 tree type = TREE_TYPE (decl);
10823 if (!is_gimple_reg_type (type)
10824 || TREE_CODE (type) == REFERENCE_TYPE
10825 || TREE_ADDRESSABLE (type))
10826 return false;
10827 /* Don't optimize too large decls, as each thread/task will have
10828 its own. */
10829 HOST_WIDE_INT len = int_size_in_bytes (type);
10830 if (len == -1 || len > 4 * POINTER_SIZE / BITS_PER_UNIT)
10831 return false;
10832 if (omp_privatize_by_reference (decl))
10833 return false;
10834 return true;
10837 /* Helper function of omp_find_stores_op and gimplify_adjust_omp_clauses*.
10838 For omp_shared_to_firstprivate_optimizable_decl_p decl mark it as
10839 GOVD_WRITTEN in outer contexts. */
10841 static void
10842 omp_mark_stores (struct gimplify_omp_ctx *ctx, tree decl)
10844 for (; ctx; ctx = ctx->outer_context)
10846 splay_tree_node n = splay_tree_lookup (ctx->variables,
10847 (splay_tree_key) decl);
10848 if (n == NULL)
10849 continue;
10850 else if (n->value & GOVD_SHARED)
10852 n->value |= GOVD_WRITTEN;
10853 return;
10855 else if (n->value & GOVD_DATA_SHARE_CLASS)
10856 return;
10860 /* Helper callback for walk_gimple_seq to discover possible stores
10861 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
10862 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
10863 for those. */
10865 static tree
10866 omp_find_stores_op (tree *tp, int *walk_subtrees, void *data)
10868 struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
10870 *walk_subtrees = 0;
10871 if (!wi->is_lhs)
10872 return NULL_TREE;
10874 tree op = *tp;
10877 if (handled_component_p (op))
10878 op = TREE_OPERAND (op, 0);
10879 else if ((TREE_CODE (op) == MEM_REF || TREE_CODE (op) == TARGET_MEM_REF)
10880 && TREE_CODE (TREE_OPERAND (op, 0)) == ADDR_EXPR)
10881 op = TREE_OPERAND (TREE_OPERAND (op, 0), 0);
10882 else
10883 break;
10885 while (1);
10886 if (!DECL_P (op) || !omp_shared_to_firstprivate_optimizable_decl_p (op))
10887 return NULL_TREE;
10889 omp_mark_stores (gimplify_omp_ctxp, op);
10890 return NULL_TREE;
10893 /* Helper callback for walk_gimple_seq to discover possible stores
10894 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
10895 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
10896 for those. */
10898 static tree
10899 omp_find_stores_stmt (gimple_stmt_iterator *gsi_p,
10900 bool *handled_ops_p,
10901 struct walk_stmt_info *wi)
10903 gimple *stmt = gsi_stmt (*gsi_p);
10904 switch (gimple_code (stmt))
10906 /* Don't recurse on OpenMP constructs for which
10907 gimplify_adjust_omp_clauses already handled the bodies,
10908 except handle gimple_omp_for_pre_body. */
10909 case GIMPLE_OMP_FOR:
10910 *handled_ops_p = true;
10911 if (gimple_omp_for_pre_body (stmt))
10912 walk_gimple_seq (gimple_omp_for_pre_body (stmt),
10913 omp_find_stores_stmt, omp_find_stores_op, wi);
10914 break;
10915 case GIMPLE_OMP_PARALLEL:
10916 case GIMPLE_OMP_TASK:
10917 case GIMPLE_OMP_SECTIONS:
10918 case GIMPLE_OMP_SINGLE:
10919 case GIMPLE_OMP_SCOPE:
10920 case GIMPLE_OMP_TARGET:
10921 case GIMPLE_OMP_TEAMS:
10922 case GIMPLE_OMP_CRITICAL:
10923 *handled_ops_p = true;
10924 break;
10925 default:
10926 break;
10928 return NULL_TREE;
10931 struct gimplify_adjust_omp_clauses_data
10933 tree *list_p;
10934 gimple_seq *pre_p;
10937 /* For all variables that were not actually used within the context,
10938 remove PRIVATE, SHARED, and FIRSTPRIVATE clauses. */
10940 static int
10941 gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
10943 tree *list_p = ((struct gimplify_adjust_omp_clauses_data *) data)->list_p;
10944 gimple_seq *pre_p
10945 = ((struct gimplify_adjust_omp_clauses_data *) data)->pre_p;
10946 tree decl = (tree) n->key;
10947 unsigned flags = n->value;
10948 enum omp_clause_code code;
10949 tree clause;
10950 bool private_debug;
10952 if (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
10953 && (flags & GOVD_LASTPRIVATE_CONDITIONAL) != 0)
10954 flags = GOVD_SHARED | GOVD_SEEN | GOVD_WRITTEN;
10955 if (flags & (GOVD_EXPLICIT | GOVD_LOCAL))
10956 return 0;
10957 if ((flags & GOVD_SEEN) == 0)
10958 return 0;
10959 if ((flags & GOVD_MAP_HAS_ATTACHMENTS) != 0)
10960 return 0;
10961 if (flags & GOVD_DEBUG_PRIVATE)
10963 gcc_assert ((flags & GOVD_DATA_SHARE_CLASS) == GOVD_SHARED);
10964 private_debug = true;
10966 else if (flags & GOVD_MAP)
10967 private_debug = false;
10968 else
10969 private_debug
10970 = lang_hooks.decls.omp_private_debug_clause (decl,
10971 !!(flags & GOVD_SHARED));
10972 if (private_debug)
10973 code = OMP_CLAUSE_PRIVATE;
10974 else if (flags & GOVD_MAP)
10976 code = OMP_CLAUSE_MAP;
10977 if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0
10978 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
10980 error ("%<_Atomic%> %qD in implicit %<map%> clause", decl);
10981 return 0;
10983 if (VAR_P (decl)
10984 && DECL_IN_CONSTANT_POOL (decl)
10985 && !lookup_attribute ("omp declare target",
10986 DECL_ATTRIBUTES (decl)))
10988 tree id = get_identifier ("omp declare target");
10989 DECL_ATTRIBUTES (decl)
10990 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
10991 varpool_node *node = varpool_node::get (decl);
10992 if (node)
10994 node->offloadable = 1;
10995 if (ENABLE_OFFLOADING)
10996 g->have_offload = true;
11000 else if (flags & GOVD_SHARED)
11002 if (is_global_var (decl))
11004 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
11005 while (ctx != NULL)
11007 splay_tree_node on
11008 = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11009 if (on && (on->value & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
11010 | GOVD_PRIVATE | GOVD_REDUCTION
11011 | GOVD_LINEAR | GOVD_MAP)) != 0)
11012 break;
11013 ctx = ctx->outer_context;
11015 if (ctx == NULL)
11016 return 0;
11018 code = OMP_CLAUSE_SHARED;
11019 /* Don't optimize shared into firstprivate for read-only vars
11020 on tasks with depend clause, we shouldn't try to copy them
11021 until the dependencies are satisfied. */
11022 if (gimplify_omp_ctxp->has_depend)
11023 flags |= GOVD_WRITTEN;
11025 else if (flags & GOVD_PRIVATE)
11026 code = OMP_CLAUSE_PRIVATE;
11027 else if (flags & GOVD_FIRSTPRIVATE)
11029 code = OMP_CLAUSE_FIRSTPRIVATE;
11030 if ((gimplify_omp_ctxp->region_type & ORT_TARGET)
11031 && (gimplify_omp_ctxp->region_type & ORT_ACC) == 0
11032 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
11034 error ("%<_Atomic%> %qD in implicit %<firstprivate%> clause on "
11035 "%<target%> construct", decl);
11036 return 0;
11039 else if (flags & GOVD_LASTPRIVATE)
11040 code = OMP_CLAUSE_LASTPRIVATE;
11041 else if (flags & (GOVD_ALIGNED | GOVD_NONTEMPORAL))
11042 return 0;
11043 else if (flags & GOVD_CONDTEMP)
11045 code = OMP_CLAUSE__CONDTEMP_;
11046 gimple_add_tmp_var (decl);
11048 else
11049 gcc_unreachable ();
11051 if (((flags & GOVD_LASTPRIVATE)
11052 || (code == OMP_CLAUSE_SHARED && (flags & GOVD_WRITTEN)))
11053 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
11054 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
11056 tree chain = *list_p;
11057 clause = build_omp_clause (input_location, code);
11058 OMP_CLAUSE_DECL (clause) = decl;
11059 OMP_CLAUSE_CHAIN (clause) = chain;
11060 if (private_debug)
11061 OMP_CLAUSE_PRIVATE_DEBUG (clause) = 1;
11062 else if (code == OMP_CLAUSE_PRIVATE && (flags & GOVD_PRIVATE_OUTER_REF))
11063 OMP_CLAUSE_PRIVATE_OUTER_REF (clause) = 1;
11064 else if (code == OMP_CLAUSE_SHARED
11065 && (flags & GOVD_WRITTEN) == 0
11066 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
11067 OMP_CLAUSE_SHARED_READONLY (clause) = 1;
11068 else if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_EXPLICIT) == 0)
11069 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (clause) = 1;
11070 else if (code == OMP_CLAUSE_MAP && (flags & GOVD_MAP_0LEN_ARRAY) != 0)
11072 tree nc = build_omp_clause (input_location, OMP_CLAUSE_MAP);
11073 OMP_CLAUSE_DECL (nc) = decl;
11074 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
11075 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == POINTER_TYPE)
11076 OMP_CLAUSE_DECL (clause)
11077 = build_simple_mem_ref_loc (input_location, decl);
11078 OMP_CLAUSE_DECL (clause)
11079 = build2 (MEM_REF, char_type_node, OMP_CLAUSE_DECL (clause),
11080 build_int_cst (build_pointer_type (char_type_node), 0));
11081 OMP_CLAUSE_SIZE (clause) = size_zero_node;
11082 OMP_CLAUSE_SIZE (nc) = size_zero_node;
11083 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_ALLOC);
11084 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (clause) = 1;
11085 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
11086 OMP_CLAUSE_CHAIN (nc) = chain;
11087 OMP_CLAUSE_CHAIN (clause) = nc;
11088 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
11089 gimplify_omp_ctxp = ctx->outer_context;
11090 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (clause), 0),
11091 pre_p, NULL, is_gimple_val, fb_rvalue);
11092 gimplify_omp_ctxp = ctx;
11094 else if (code == OMP_CLAUSE_MAP)
11096 int kind;
11097 /* Not all combinations of these GOVD_MAP flags are actually valid. */
11098 switch (flags & (GOVD_MAP_TO_ONLY
11099 | GOVD_MAP_FORCE
11100 | GOVD_MAP_FORCE_PRESENT
11101 | GOVD_MAP_ALLOC_ONLY
11102 | GOVD_MAP_FROM_ONLY))
11104 case 0:
11105 kind = GOMP_MAP_TOFROM;
11106 break;
11107 case GOVD_MAP_FORCE:
11108 kind = GOMP_MAP_TOFROM | GOMP_MAP_FLAG_FORCE;
11109 break;
11110 case GOVD_MAP_TO_ONLY:
11111 kind = GOMP_MAP_TO;
11112 break;
11113 case GOVD_MAP_FROM_ONLY:
11114 kind = GOMP_MAP_FROM;
11115 break;
11116 case GOVD_MAP_ALLOC_ONLY:
11117 kind = GOMP_MAP_ALLOC;
11118 break;
11119 case GOVD_MAP_TO_ONLY | GOVD_MAP_FORCE:
11120 kind = GOMP_MAP_TO | GOMP_MAP_FLAG_FORCE;
11121 break;
11122 case GOVD_MAP_FORCE_PRESENT:
11123 kind = GOMP_MAP_FORCE_PRESENT;
11124 break;
11125 default:
11126 gcc_unreachable ();
11128 OMP_CLAUSE_SET_MAP_KIND (clause, kind);
11129 /* Setting of the implicit flag for the runtime is currently disabled for
11130 OpenACC. */
11131 if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0)
11132 OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (clause) = 1;
11133 if (DECL_SIZE (decl)
11134 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
11136 tree decl2 = DECL_VALUE_EXPR (decl);
11137 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
11138 decl2 = TREE_OPERAND (decl2, 0);
11139 gcc_assert (DECL_P (decl2));
11140 tree mem = build_simple_mem_ref (decl2);
11141 OMP_CLAUSE_DECL (clause) = mem;
11142 OMP_CLAUSE_SIZE (clause) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
11143 if (gimplify_omp_ctxp->outer_context)
11145 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
11146 omp_notice_variable (ctx, decl2, true);
11147 omp_notice_variable (ctx, OMP_CLAUSE_SIZE (clause), true);
11149 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
11150 OMP_CLAUSE_MAP);
11151 OMP_CLAUSE_DECL (nc) = decl;
11152 OMP_CLAUSE_SIZE (nc) = size_zero_node;
11153 if (gimplify_omp_ctxp->target_firstprivatize_array_bases)
11154 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
11155 else
11156 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
11157 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
11158 OMP_CLAUSE_CHAIN (clause) = nc;
11160 else if (gimplify_omp_ctxp->target_firstprivatize_array_bases
11161 && omp_privatize_by_reference (decl))
11163 OMP_CLAUSE_DECL (clause) = build_simple_mem_ref (decl);
11164 OMP_CLAUSE_SIZE (clause)
11165 = unshare_expr (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))));
11166 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
11167 gimplify_omp_ctxp = ctx->outer_context;
11168 gimplify_expr (&OMP_CLAUSE_SIZE (clause),
11169 pre_p, NULL, is_gimple_val, fb_rvalue);
11170 gimplify_omp_ctxp = ctx;
11171 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
11172 OMP_CLAUSE_MAP);
11173 OMP_CLAUSE_DECL (nc) = decl;
11174 OMP_CLAUSE_SIZE (nc) = size_zero_node;
11175 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_REFERENCE);
11176 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
11177 OMP_CLAUSE_CHAIN (clause) = nc;
11179 else
11180 OMP_CLAUSE_SIZE (clause) = DECL_SIZE_UNIT (decl);
11182 if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_LASTPRIVATE) != 0)
11184 tree nc = build_omp_clause (input_location, OMP_CLAUSE_LASTPRIVATE);
11185 OMP_CLAUSE_DECL (nc) = decl;
11186 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (nc) = 1;
11187 OMP_CLAUSE_CHAIN (nc) = chain;
11188 OMP_CLAUSE_CHAIN (clause) = nc;
11189 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
11190 gimplify_omp_ctxp = ctx->outer_context;
11191 lang_hooks.decls.omp_finish_clause (nc, pre_p,
11192 (ctx->region_type & ORT_ACC) != 0);
11193 gimplify_omp_ctxp = ctx;
11195 *list_p = clause;
11196 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
11197 gimplify_omp_ctxp = ctx->outer_context;
11198 /* Don't call omp_finish_clause on implicitly added OMP_CLAUSE_PRIVATE
11199 in simd. Those are only added for the local vars inside of simd body
11200 and they don't need to be e.g. default constructible. */
11201 if (code != OMP_CLAUSE_PRIVATE || ctx->region_type != ORT_SIMD)
11202 lang_hooks.decls.omp_finish_clause (clause, pre_p,
11203 (ctx->region_type & ORT_ACC) != 0);
11204 if (gimplify_omp_ctxp)
11205 for (; clause != chain; clause = OMP_CLAUSE_CHAIN (clause))
11206 if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_MAP
11207 && DECL_P (OMP_CLAUSE_SIZE (clause)))
11208 omp_notice_variable (gimplify_omp_ctxp, OMP_CLAUSE_SIZE (clause),
11209 true);
11210 gimplify_omp_ctxp = ctx;
11211 return 0;
11214 static void
11215 gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
11216 enum tree_code code)
11218 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
11219 tree *orig_list_p = list_p;
11220 tree c, decl;
11221 bool has_inscan_reductions = false;
11223 if (body)
11225 struct gimplify_omp_ctx *octx;
11226 for (octx = ctx; octx; octx = octx->outer_context)
11227 if ((octx->region_type & (ORT_PARALLEL | ORT_TASK | ORT_TEAMS)) != 0)
11228 break;
11229 if (octx)
11231 struct walk_stmt_info wi;
11232 memset (&wi, 0, sizeof (wi));
11233 walk_gimple_seq (body, omp_find_stores_stmt,
11234 omp_find_stores_op, &wi);
11238 if (ctx->add_safelen1)
11240 /* If there are VLAs in the body of simd loop, prevent
11241 vectorization. */
11242 gcc_assert (ctx->region_type == ORT_SIMD);
11243 c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_SAFELEN);
11244 OMP_CLAUSE_SAFELEN_EXPR (c) = integer_one_node;
11245 OMP_CLAUSE_CHAIN (c) = *list_p;
11246 *list_p = c;
11247 list_p = &OMP_CLAUSE_CHAIN (c);
11250 if (ctx->region_type == ORT_WORKSHARE
11251 && ctx->outer_context
11252 && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL)
11254 for (c = ctx->outer_context->clauses; c; c = OMP_CLAUSE_CHAIN (c))
11255 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
11256 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
11258 decl = OMP_CLAUSE_DECL (c);
11259 splay_tree_node n
11260 = splay_tree_lookup (ctx->outer_context->variables,
11261 (splay_tree_key) decl);
11262 gcc_checking_assert (!splay_tree_lookup (ctx->variables,
11263 (splay_tree_key) decl));
11264 omp_add_variable (ctx, decl, n->value);
11265 tree c2 = copy_node (c);
11266 OMP_CLAUSE_CHAIN (c2) = *list_p;
11267 *list_p = c2;
11268 if ((n->value & GOVD_FIRSTPRIVATE) == 0)
11269 continue;
11270 c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
11271 OMP_CLAUSE_FIRSTPRIVATE);
11272 OMP_CLAUSE_DECL (c2) = decl;
11273 OMP_CLAUSE_CHAIN (c2) = *list_p;
11274 *list_p = c2;
11277 while ((c = *list_p) != NULL)
11279 splay_tree_node n;
11280 bool remove = false;
11282 switch (OMP_CLAUSE_CODE (c))
11284 case OMP_CLAUSE_FIRSTPRIVATE:
11285 if ((ctx->region_type & ORT_TARGET)
11286 && (ctx->region_type & ORT_ACC) == 0
11287 && TYPE_ATOMIC (strip_array_types
11288 (TREE_TYPE (OMP_CLAUSE_DECL (c)))))
11290 error_at (OMP_CLAUSE_LOCATION (c),
11291 "%<_Atomic%> %qD in %<firstprivate%> clause on "
11292 "%<target%> construct", OMP_CLAUSE_DECL (c));
11293 remove = true;
11294 break;
11296 if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c))
11298 decl = OMP_CLAUSE_DECL (c);
11299 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11300 if ((n->value & GOVD_MAP) != 0)
11302 remove = true;
11303 break;
11305 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT_TARGET (c) = 0;
11306 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c) = 0;
11308 /* FALLTHRU */
11309 case OMP_CLAUSE_PRIVATE:
11310 case OMP_CLAUSE_SHARED:
11311 case OMP_CLAUSE_LINEAR:
11312 decl = OMP_CLAUSE_DECL (c);
11313 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11314 remove = !(n->value & GOVD_SEEN);
11315 if ((n->value & GOVD_LASTPRIVATE_CONDITIONAL) != 0
11316 && code == OMP_PARALLEL
11317 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
11318 remove = true;
11319 if (! remove)
11321 bool shared = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED;
11322 if ((n->value & GOVD_DEBUG_PRIVATE)
11323 || lang_hooks.decls.omp_private_debug_clause (decl, shared))
11325 gcc_assert ((n->value & GOVD_DEBUG_PRIVATE) == 0
11326 || ((n->value & GOVD_DATA_SHARE_CLASS)
11327 == GOVD_SHARED));
11328 OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_PRIVATE);
11329 OMP_CLAUSE_PRIVATE_DEBUG (c) = 1;
11331 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
11332 && ctx->has_depend
11333 && DECL_P (decl))
11334 n->value |= GOVD_WRITTEN;
11335 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
11336 && (n->value & GOVD_WRITTEN) == 0
11337 && DECL_P (decl)
11338 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
11339 OMP_CLAUSE_SHARED_READONLY (c) = 1;
11340 else if (DECL_P (decl)
11341 && ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
11342 && (n->value & GOVD_WRITTEN) != 0)
11343 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
11344 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
11345 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
11346 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
11348 else
11349 n->value &= ~GOVD_EXPLICIT;
11350 break;
11352 case OMP_CLAUSE_LASTPRIVATE:
11353 /* Make sure OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE is set to
11354 accurately reflect the presence of a FIRSTPRIVATE clause. */
11355 decl = OMP_CLAUSE_DECL (c);
11356 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11357 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c)
11358 = (n->value & GOVD_FIRSTPRIVATE) != 0;
11359 if (code == OMP_DISTRIBUTE
11360 && OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
11362 remove = true;
11363 error_at (OMP_CLAUSE_LOCATION (c),
11364 "same variable used in %<firstprivate%> and "
11365 "%<lastprivate%> clauses on %<distribute%> "
11366 "construct");
11368 if (!remove
11369 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
11370 && DECL_P (decl)
11371 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
11372 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
11373 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) && code == OMP_PARALLEL)
11374 remove = true;
11375 break;
11377 case OMP_CLAUSE_ALIGNED:
11378 decl = OMP_CLAUSE_DECL (c);
11379 if (!is_global_var (decl))
11381 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11382 remove = n == NULL || !(n->value & GOVD_SEEN);
11383 if (!remove && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
11385 struct gimplify_omp_ctx *octx;
11386 if (n != NULL
11387 && (n->value & (GOVD_DATA_SHARE_CLASS
11388 & ~GOVD_FIRSTPRIVATE)))
11389 remove = true;
11390 else
11391 for (octx = ctx->outer_context; octx;
11392 octx = octx->outer_context)
11394 n = splay_tree_lookup (octx->variables,
11395 (splay_tree_key) decl);
11396 if (n == NULL)
11397 continue;
11398 if (n->value & GOVD_LOCAL)
11399 break;
11400 /* We have to avoid assigning a shared variable
11401 to itself when trying to add
11402 __builtin_assume_aligned. */
11403 if (n->value & GOVD_SHARED)
11405 remove = true;
11406 break;
11411 else if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
11413 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11414 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
11415 remove = true;
11417 break;
11419 case OMP_CLAUSE_NONTEMPORAL:
11420 decl = OMP_CLAUSE_DECL (c);
11421 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11422 remove = n == NULL || !(n->value & GOVD_SEEN);
11423 break;
11425 case OMP_CLAUSE_MAP:
11426 if (code == OMP_TARGET_EXIT_DATA
11427 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER)
11429 remove = true;
11430 break;
11432 decl = OMP_CLAUSE_DECL (c);
11433 /* Data clauses associated with reductions must be
11434 compatible with present_or_copy. Warn and adjust the clause
11435 if that is not the case. */
11436 if (ctx->region_type == ORT_ACC_PARALLEL
11437 || ctx->region_type == ORT_ACC_SERIAL)
11439 tree t = DECL_P (decl) ? decl : TREE_OPERAND (decl, 0);
11440 n = NULL;
11442 if (DECL_P (t))
11443 n = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
11445 if (n && (n->value & GOVD_REDUCTION))
11447 enum gomp_map_kind kind = OMP_CLAUSE_MAP_KIND (c);
11449 OMP_CLAUSE_MAP_IN_REDUCTION (c) = 1;
11450 if ((kind & GOMP_MAP_TOFROM) != GOMP_MAP_TOFROM
11451 && kind != GOMP_MAP_FORCE_PRESENT
11452 && kind != GOMP_MAP_POINTER)
11454 warning_at (OMP_CLAUSE_LOCATION (c), 0,
11455 "incompatible data clause with reduction "
11456 "on %qE; promoting to %<present_or_copy%>",
11457 DECL_NAME (t));
11458 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TOFROM);
11462 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT
11463 && (code == OMP_TARGET_EXIT_DATA || code == OACC_EXIT_DATA))
11465 remove = true;
11466 break;
11468 if (!DECL_P (decl))
11470 if ((ctx->region_type & ORT_TARGET) != 0
11471 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
11473 if (TREE_CODE (decl) == INDIRECT_REF
11474 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
11475 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
11476 == REFERENCE_TYPE))
11477 decl = TREE_OPERAND (decl, 0);
11478 if (TREE_CODE (decl) == COMPONENT_REF)
11480 while (TREE_CODE (decl) == COMPONENT_REF)
11481 decl = TREE_OPERAND (decl, 0);
11482 if (DECL_P (decl))
11484 n = splay_tree_lookup (ctx->variables,
11485 (splay_tree_key) decl);
11486 if (!(n->value & GOVD_SEEN))
11487 remove = true;
11491 break;
11493 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11494 if ((ctx->region_type & ORT_TARGET) != 0
11495 && !(n->value & GOVD_SEEN)
11496 && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) == 0
11497 && (!is_global_var (decl)
11498 || !lookup_attribute ("omp declare target link",
11499 DECL_ATTRIBUTES (decl))))
11501 remove = true;
11502 /* For struct element mapping, if struct is never referenced
11503 in target block and none of the mapping has always modifier,
11504 remove all the struct element mappings, which immediately
11505 follow the GOMP_MAP_STRUCT map clause. */
11506 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT)
11508 HOST_WIDE_INT cnt = tree_to_shwi (OMP_CLAUSE_SIZE (c));
11509 while (cnt--)
11510 OMP_CLAUSE_CHAIN (c)
11511 = OMP_CLAUSE_CHAIN (OMP_CLAUSE_CHAIN (c));
11514 else if (DECL_SIZE (decl)
11515 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST
11516 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_POINTER
11517 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_POINTER
11518 && (OMP_CLAUSE_MAP_KIND (c)
11519 != GOMP_MAP_FIRSTPRIVATE_REFERENCE))
11521 /* For GOMP_MAP_FORCE_DEVICEPTR, we'll never enter here, because
11522 for these, TREE_CODE (DECL_SIZE (decl)) will always be
11523 INTEGER_CST. */
11524 gcc_assert (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FORCE_DEVICEPTR);
11526 tree decl2 = DECL_VALUE_EXPR (decl);
11527 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
11528 decl2 = TREE_OPERAND (decl2, 0);
11529 gcc_assert (DECL_P (decl2));
11530 tree mem = build_simple_mem_ref (decl2);
11531 OMP_CLAUSE_DECL (c) = mem;
11532 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
11533 if (ctx->outer_context)
11535 omp_notice_variable (ctx->outer_context, decl2, true);
11536 omp_notice_variable (ctx->outer_context,
11537 OMP_CLAUSE_SIZE (c), true);
11539 if (((ctx->region_type & ORT_TARGET) != 0
11540 || !ctx->target_firstprivatize_array_bases)
11541 && ((n->value & GOVD_SEEN) == 0
11542 || (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) == 0))
11544 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
11545 OMP_CLAUSE_MAP);
11546 OMP_CLAUSE_DECL (nc) = decl;
11547 OMP_CLAUSE_SIZE (nc) = size_zero_node;
11548 if (ctx->target_firstprivatize_array_bases)
11549 OMP_CLAUSE_SET_MAP_KIND (nc,
11550 GOMP_MAP_FIRSTPRIVATE_POINTER);
11551 else
11552 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
11553 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
11554 OMP_CLAUSE_CHAIN (c) = nc;
11555 c = nc;
11558 else
11560 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
11561 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
11562 gcc_assert ((n->value & GOVD_SEEN) == 0
11563 || ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
11564 == 0));
11566 break;
11568 case OMP_CLAUSE_TO:
11569 case OMP_CLAUSE_FROM:
11570 case OMP_CLAUSE__CACHE_:
11571 decl = OMP_CLAUSE_DECL (c);
11572 if (!DECL_P (decl))
11573 break;
11574 if (DECL_SIZE (decl)
11575 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
11577 tree decl2 = DECL_VALUE_EXPR (decl);
11578 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
11579 decl2 = TREE_OPERAND (decl2, 0);
11580 gcc_assert (DECL_P (decl2));
11581 tree mem = build_simple_mem_ref (decl2);
11582 OMP_CLAUSE_DECL (c) = mem;
11583 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
11584 if (ctx->outer_context)
11586 omp_notice_variable (ctx->outer_context, decl2, true);
11587 omp_notice_variable (ctx->outer_context,
11588 OMP_CLAUSE_SIZE (c), true);
11591 else if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
11592 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
11593 break;
11595 case OMP_CLAUSE_REDUCTION:
11596 if (OMP_CLAUSE_REDUCTION_INSCAN (c))
11598 decl = OMP_CLAUSE_DECL (c);
11599 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11600 if ((n->value & GOVD_REDUCTION_INSCAN) == 0)
11602 remove = true;
11603 error_at (OMP_CLAUSE_LOCATION (c),
11604 "%qD specified in %<inscan%> %<reduction%> clause "
11605 "but not in %<scan%> directive clause", decl);
11606 break;
11608 has_inscan_reductions = true;
11610 /* FALLTHRU */
11611 case OMP_CLAUSE_IN_REDUCTION:
11612 case OMP_CLAUSE_TASK_REDUCTION:
11613 decl = OMP_CLAUSE_DECL (c);
11614 /* OpenACC reductions need a present_or_copy data clause.
11615 Add one if necessary. Emit error when the reduction is private. */
11616 if (ctx->region_type == ORT_ACC_PARALLEL
11617 || ctx->region_type == ORT_ACC_SERIAL)
11619 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11620 if (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
11622 remove = true;
11623 error_at (OMP_CLAUSE_LOCATION (c), "invalid private "
11624 "reduction on %qE", DECL_NAME (decl));
11626 else if ((n->value & GOVD_MAP) == 0)
11628 tree next = OMP_CLAUSE_CHAIN (c);
11629 tree nc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_MAP);
11630 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_TOFROM);
11631 OMP_CLAUSE_DECL (nc) = decl;
11632 OMP_CLAUSE_CHAIN (c) = nc;
11633 lang_hooks.decls.omp_finish_clause (nc, pre_p,
11634 (ctx->region_type
11635 & ORT_ACC) != 0);
11636 while (1)
11638 OMP_CLAUSE_MAP_IN_REDUCTION (nc) = 1;
11639 if (OMP_CLAUSE_CHAIN (nc) == NULL)
11640 break;
11641 nc = OMP_CLAUSE_CHAIN (nc);
11643 OMP_CLAUSE_CHAIN (nc) = next;
11644 n->value |= GOVD_MAP;
11647 if (DECL_P (decl)
11648 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
11649 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
11650 break;
11652 case OMP_CLAUSE_ALLOCATE:
11653 decl = OMP_CLAUSE_DECL (c);
11654 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11655 if (n != NULL && !(n->value & GOVD_SEEN))
11657 if ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE | GOVD_LINEAR))
11658 != 0
11659 && (n->value & (GOVD_REDUCTION | GOVD_LASTPRIVATE)) == 0)
11660 remove = true;
11662 if (!remove
11663 && OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
11664 && TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)) != INTEGER_CST
11665 && ((ctx->region_type & (ORT_PARALLEL | ORT_TARGET)) != 0
11666 || (ctx->region_type & ORT_TASKLOOP) == ORT_TASK
11667 || (ctx->region_type & ORT_HOST_TEAMS) == ORT_HOST_TEAMS))
11669 tree allocator = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
11670 n = splay_tree_lookup (ctx->variables, (splay_tree_key) allocator);
11671 if (n == NULL)
11673 enum omp_clause_default_kind default_kind
11674 = ctx->default_kind;
11675 ctx->default_kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
11676 omp_notice_variable (ctx, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
11677 true);
11678 ctx->default_kind = default_kind;
11680 else
11681 omp_notice_variable (ctx, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
11682 true);
11684 break;
11686 case OMP_CLAUSE_COPYIN:
11687 case OMP_CLAUSE_COPYPRIVATE:
11688 case OMP_CLAUSE_IF:
11689 case OMP_CLAUSE_NUM_THREADS:
11690 case OMP_CLAUSE_NUM_TEAMS:
11691 case OMP_CLAUSE_THREAD_LIMIT:
11692 case OMP_CLAUSE_DIST_SCHEDULE:
11693 case OMP_CLAUSE_DEVICE:
11694 case OMP_CLAUSE_SCHEDULE:
11695 case OMP_CLAUSE_NOWAIT:
11696 case OMP_CLAUSE_ORDERED:
11697 case OMP_CLAUSE_DEFAULT:
11698 case OMP_CLAUSE_UNTIED:
11699 case OMP_CLAUSE_COLLAPSE:
11700 case OMP_CLAUSE_FINAL:
11701 case OMP_CLAUSE_MERGEABLE:
11702 case OMP_CLAUSE_PROC_BIND:
11703 case OMP_CLAUSE_SAFELEN:
11704 case OMP_CLAUSE_SIMDLEN:
11705 case OMP_CLAUSE_DEPEND:
11706 case OMP_CLAUSE_PRIORITY:
11707 case OMP_CLAUSE_GRAINSIZE:
11708 case OMP_CLAUSE_NUM_TASKS:
11709 case OMP_CLAUSE_NOGROUP:
11710 case OMP_CLAUSE_THREADS:
11711 case OMP_CLAUSE_SIMD:
11712 case OMP_CLAUSE_FILTER:
11713 case OMP_CLAUSE_HINT:
11714 case OMP_CLAUSE_DEFAULTMAP:
11715 case OMP_CLAUSE_ORDER:
11716 case OMP_CLAUSE_BIND:
11717 case OMP_CLAUSE_DETACH:
11718 case OMP_CLAUSE_USE_DEVICE_PTR:
11719 case OMP_CLAUSE_USE_DEVICE_ADDR:
11720 case OMP_CLAUSE_IS_DEVICE_PTR:
11721 case OMP_CLAUSE_ASYNC:
11722 case OMP_CLAUSE_WAIT:
11723 case OMP_CLAUSE_INDEPENDENT:
11724 case OMP_CLAUSE_NUM_GANGS:
11725 case OMP_CLAUSE_NUM_WORKERS:
11726 case OMP_CLAUSE_VECTOR_LENGTH:
11727 case OMP_CLAUSE_GANG:
11728 case OMP_CLAUSE_WORKER:
11729 case OMP_CLAUSE_VECTOR:
11730 case OMP_CLAUSE_AUTO:
11731 case OMP_CLAUSE_SEQ:
11732 case OMP_CLAUSE_TILE:
11733 case OMP_CLAUSE_IF_PRESENT:
11734 case OMP_CLAUSE_FINALIZE:
11735 case OMP_CLAUSE_INCLUSIVE:
11736 case OMP_CLAUSE_EXCLUSIVE:
11737 break;
11739 case OMP_CLAUSE_NOHOST:
11740 default:
11741 gcc_unreachable ();
11744 if (remove)
11745 *list_p = OMP_CLAUSE_CHAIN (c);
11746 else
11747 list_p = &OMP_CLAUSE_CHAIN (c);
11750 /* Add in any implicit data sharing. */
11751 struct gimplify_adjust_omp_clauses_data data;
11752 if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0)
11754 /* OpenMP. Implicit clauses are added at the start of the clause list,
11755 but after any non-map clauses. */
11756 tree *implicit_add_list_p = orig_list_p;
11757 while (*implicit_add_list_p
11758 && OMP_CLAUSE_CODE (*implicit_add_list_p) != OMP_CLAUSE_MAP)
11759 implicit_add_list_p = &OMP_CLAUSE_CHAIN (*implicit_add_list_p);
11760 data.list_p = implicit_add_list_p;
11762 else
11763 /* OpenACC. */
11764 data.list_p = list_p;
11765 data.pre_p = pre_p;
11766 splay_tree_foreach (ctx->variables, gimplify_adjust_omp_clauses_1, &data);
11768 if (has_inscan_reductions)
11769 for (c = *orig_list_p; c; c = OMP_CLAUSE_CHAIN (c))
11770 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
11771 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
11773 error_at (OMP_CLAUSE_LOCATION (c),
11774 "%<inscan%> %<reduction%> clause used together with "
11775 "%<linear%> clause for a variable other than loop "
11776 "iterator");
11777 break;
11780 gimplify_omp_ctxp = ctx->outer_context;
11781 delete_omp_context (ctx);
11784 /* Return 0 if CONSTRUCTS selectors don't match the OpenMP context,
11785 -1 if unknown yet (simd is involved, won't be known until vectorization)
11786 and 1 if they do. If SCORES is non-NULL, it should point to an array
11787 of at least 2*NCONSTRUCTS+2 ints, and will be filled with the positions
11788 of the CONSTRUCTS (position -1 if it will never match) followed by
11789 number of constructs in the OpenMP context construct trait. If the
11790 score depends on whether it will be in a declare simd clone or not,
11791 the function returns 2 and there will be two sets of the scores, the first
11792 one for the case that it is not in a declare simd clone, the other
11793 that it is in a declare simd clone. */
11796 omp_construct_selector_matches (enum tree_code *constructs, int nconstructs,
11797 int *scores)
11799 int matched = 0, cnt = 0;
11800 bool simd_seen = false;
11801 bool target_seen = false;
11802 int declare_simd_cnt = -1;
11803 auto_vec<enum tree_code, 16> codes;
11804 for (struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; ctx;)
11806 if (((ctx->region_type & ORT_PARALLEL) && ctx->code == OMP_PARALLEL)
11807 || ((ctx->region_type & (ORT_TARGET | ORT_IMPLICIT_TARGET | ORT_ACC))
11808 == ORT_TARGET && ctx->code == OMP_TARGET)
11809 || ((ctx->region_type & ORT_TEAMS) && ctx->code == OMP_TEAMS)
11810 || (ctx->region_type == ORT_WORKSHARE && ctx->code == OMP_FOR)
11811 || (ctx->region_type == ORT_SIMD
11812 && ctx->code == OMP_SIMD
11813 && !omp_find_clause (ctx->clauses, OMP_CLAUSE_BIND)))
11815 ++cnt;
11816 if (scores)
11817 codes.safe_push (ctx->code);
11818 else if (matched < nconstructs && ctx->code == constructs[matched])
11820 if (ctx->code == OMP_SIMD)
11822 if (matched)
11823 return 0;
11824 simd_seen = true;
11826 ++matched;
11828 if (ctx->code == OMP_TARGET)
11830 if (scores == NULL)
11831 return matched < nconstructs ? 0 : simd_seen ? -1 : 1;
11832 target_seen = true;
11833 break;
11836 else if (ctx->region_type == ORT_WORKSHARE
11837 && ctx->code == OMP_LOOP
11838 && ctx->outer_context
11839 && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL
11840 && ctx->outer_context->outer_context
11841 && ctx->outer_context->outer_context->code == OMP_LOOP
11842 && ctx->outer_context->outer_context->distribute)
11843 ctx = ctx->outer_context->outer_context;
11844 ctx = ctx->outer_context;
11846 if (!target_seen
11847 && lookup_attribute ("omp declare simd",
11848 DECL_ATTRIBUTES (current_function_decl)))
11850 /* Declare simd is a maybe case, it is supposed to be added only to the
11851 omp-simd-clone.c added clones and not to the base function. */
11852 declare_simd_cnt = cnt++;
11853 if (scores)
11854 codes.safe_push (OMP_SIMD);
11855 else if (cnt == 0
11856 && constructs[0] == OMP_SIMD)
11858 gcc_assert (matched == 0);
11859 simd_seen = true;
11860 if (++matched == nconstructs)
11861 return -1;
11864 if (tree attr = lookup_attribute ("omp declare variant variant",
11865 DECL_ATTRIBUTES (current_function_decl)))
11867 enum tree_code variant_constructs[5];
11868 int variant_nconstructs = 0;
11869 if (!target_seen)
11870 variant_nconstructs
11871 = omp_constructor_traits_to_codes (TREE_VALUE (attr),
11872 variant_constructs);
11873 for (int i = 0; i < variant_nconstructs; i++)
11875 ++cnt;
11876 if (scores)
11877 codes.safe_push (variant_constructs[i]);
11878 else if (matched < nconstructs
11879 && variant_constructs[i] == constructs[matched])
11881 if (variant_constructs[i] == OMP_SIMD)
11883 if (matched)
11884 return 0;
11885 simd_seen = true;
11887 ++matched;
11891 if (!target_seen
11892 && lookup_attribute ("omp declare target block",
11893 DECL_ATTRIBUTES (current_function_decl)))
11895 if (scores)
11896 codes.safe_push (OMP_TARGET);
11897 else if (matched < nconstructs && constructs[matched] == OMP_TARGET)
11898 ++matched;
11900 if (scores)
11902 for (int pass = 0; pass < (declare_simd_cnt == -1 ? 1 : 2); pass++)
11904 int j = codes.length () - 1;
11905 for (int i = nconstructs - 1; i >= 0; i--)
11907 while (j >= 0
11908 && (pass != 0 || declare_simd_cnt != j)
11909 && constructs[i] != codes[j])
11910 --j;
11911 if (pass == 0 && declare_simd_cnt != -1 && j > declare_simd_cnt)
11912 *scores++ = j - 1;
11913 else
11914 *scores++ = j;
11916 *scores++ = ((pass == 0 && declare_simd_cnt != -1)
11917 ? codes.length () - 1 : codes.length ());
11919 return declare_simd_cnt == -1 ? 1 : 2;
11921 if (matched == nconstructs)
11922 return simd_seen ? -1 : 1;
11923 return 0;
11926 /* Gimplify OACC_CACHE. */
11928 static void
11929 gimplify_oacc_cache (tree *expr_p, gimple_seq *pre_p)
11931 tree expr = *expr_p;
11933 gimplify_scan_omp_clauses (&OACC_CACHE_CLAUSES (expr), pre_p, ORT_ACC,
11934 OACC_CACHE);
11935 gimplify_adjust_omp_clauses (pre_p, NULL, &OACC_CACHE_CLAUSES (expr),
11936 OACC_CACHE);
11938 /* TODO: Do something sensible with this information. */
11940 *expr_p = NULL_TREE;
11943 /* Helper function of gimplify_oacc_declare. The helper's purpose is to,
11944 if required, translate 'kind' in CLAUSE into an 'entry' kind and 'exit'
11945 kind. The entry kind will replace the one in CLAUSE, while the exit
11946 kind will be used in a new omp_clause and returned to the caller. */
11948 static tree
11949 gimplify_oacc_declare_1 (tree clause)
11951 HOST_WIDE_INT kind, new_op;
11952 bool ret = false;
11953 tree c = NULL;
11955 kind = OMP_CLAUSE_MAP_KIND (clause);
11957 switch (kind)
11959 case GOMP_MAP_ALLOC:
11960 new_op = GOMP_MAP_RELEASE;
11961 ret = true;
11962 break;
11964 case GOMP_MAP_FROM:
11965 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_FORCE_ALLOC);
11966 new_op = GOMP_MAP_FROM;
11967 ret = true;
11968 break;
11970 case GOMP_MAP_TOFROM:
11971 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_TO);
11972 new_op = GOMP_MAP_FROM;
11973 ret = true;
11974 break;
11976 case GOMP_MAP_DEVICE_RESIDENT:
11977 case GOMP_MAP_FORCE_DEVICEPTR:
11978 case GOMP_MAP_FORCE_PRESENT:
11979 case GOMP_MAP_LINK:
11980 case GOMP_MAP_POINTER:
11981 case GOMP_MAP_TO:
11982 break;
11984 default:
11985 gcc_unreachable ();
11986 break;
11989 if (ret)
11991 c = build_omp_clause (OMP_CLAUSE_LOCATION (clause), OMP_CLAUSE_MAP);
11992 OMP_CLAUSE_SET_MAP_KIND (c, new_op);
11993 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clause);
11996 return c;
11999 /* Gimplify OACC_DECLARE. */
12001 static void
12002 gimplify_oacc_declare (tree *expr_p, gimple_seq *pre_p)
12004 tree expr = *expr_p;
12005 gomp_target *stmt;
12006 tree clauses, t, decl;
12008 clauses = OACC_DECLARE_CLAUSES (expr);
12010 gimplify_scan_omp_clauses (&clauses, pre_p, ORT_TARGET_DATA, OACC_DECLARE);
12011 gimplify_adjust_omp_clauses (pre_p, NULL, &clauses, OACC_DECLARE);
12013 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
12015 decl = OMP_CLAUSE_DECL (t);
12017 if (TREE_CODE (decl) == MEM_REF)
12018 decl = TREE_OPERAND (decl, 0);
12020 if (VAR_P (decl) && !is_oacc_declared (decl))
12022 tree attr = get_identifier ("oacc declare target");
12023 DECL_ATTRIBUTES (decl) = tree_cons (attr, NULL_TREE,
12024 DECL_ATTRIBUTES (decl));
12027 if (VAR_P (decl)
12028 && !is_global_var (decl)
12029 && DECL_CONTEXT (decl) == current_function_decl)
12031 tree c = gimplify_oacc_declare_1 (t);
12032 if (c)
12034 if (oacc_declare_returns == NULL)
12035 oacc_declare_returns = new hash_map<tree, tree>;
12037 oacc_declare_returns->put (decl, c);
12041 if (gimplify_omp_ctxp)
12042 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_SEEN);
12045 stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
12046 clauses);
12048 gimplify_seq_add_stmt (pre_p, stmt);
12050 *expr_p = NULL_TREE;
12053 /* Gimplify the contents of an OMP_PARALLEL statement. This involves
12054 gimplification of the body, as well as scanning the body for used
12055 variables. We need to do this scan now, because variable-sized
12056 decls will be decomposed during gimplification. */
12058 static void
12059 gimplify_omp_parallel (tree *expr_p, gimple_seq *pre_p)
12061 tree expr = *expr_p;
12062 gimple *g;
12063 gimple_seq body = NULL;
12065 gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr), pre_p,
12066 OMP_PARALLEL_COMBINED (expr)
12067 ? ORT_COMBINED_PARALLEL
12068 : ORT_PARALLEL, OMP_PARALLEL);
12070 push_gimplify_context ();
12072 g = gimplify_and_return_first (OMP_PARALLEL_BODY (expr), &body);
12073 if (gimple_code (g) == GIMPLE_BIND)
12074 pop_gimplify_context (g);
12075 else
12076 pop_gimplify_context (NULL);
12078 gimplify_adjust_omp_clauses (pre_p, body, &OMP_PARALLEL_CLAUSES (expr),
12079 OMP_PARALLEL);
12081 g = gimple_build_omp_parallel (body,
12082 OMP_PARALLEL_CLAUSES (expr),
12083 NULL_TREE, NULL_TREE);
12084 if (OMP_PARALLEL_COMBINED (expr))
12085 gimple_omp_set_subcode (g, GF_OMP_PARALLEL_COMBINED);
12086 gimplify_seq_add_stmt (pre_p, g);
12087 *expr_p = NULL_TREE;
12090 /* Gimplify the contents of an OMP_TASK statement. This involves
12091 gimplification of the body, as well as scanning the body for used
12092 variables. We need to do this scan now, because variable-sized
12093 decls will be decomposed during gimplification. */
12095 static void
12096 gimplify_omp_task (tree *expr_p, gimple_seq *pre_p)
12098 tree expr = *expr_p;
12099 gimple *g;
12100 gimple_seq body = NULL;
12102 if (OMP_TASK_BODY (expr) == NULL_TREE)
12103 for (tree c = OMP_TASK_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
12104 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
12105 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_MUTEXINOUTSET)
12107 error_at (OMP_CLAUSE_LOCATION (c),
12108 "%<mutexinoutset%> kind in %<depend%> clause on a "
12109 "%<taskwait%> construct");
12110 break;
12113 gimplify_scan_omp_clauses (&OMP_TASK_CLAUSES (expr), pre_p,
12114 omp_find_clause (OMP_TASK_CLAUSES (expr),
12115 OMP_CLAUSE_UNTIED)
12116 ? ORT_UNTIED_TASK : ORT_TASK, OMP_TASK);
12118 if (OMP_TASK_BODY (expr))
12120 push_gimplify_context ();
12122 g = gimplify_and_return_first (OMP_TASK_BODY (expr), &body);
12123 if (gimple_code (g) == GIMPLE_BIND)
12124 pop_gimplify_context (g);
12125 else
12126 pop_gimplify_context (NULL);
12129 gimplify_adjust_omp_clauses (pre_p, body, &OMP_TASK_CLAUSES (expr),
12130 OMP_TASK);
12132 g = gimple_build_omp_task (body,
12133 OMP_TASK_CLAUSES (expr),
12134 NULL_TREE, NULL_TREE,
12135 NULL_TREE, NULL_TREE, NULL_TREE);
12136 if (OMP_TASK_BODY (expr) == NULL_TREE)
12137 gimple_omp_task_set_taskwait_p (g, true);
12138 gimplify_seq_add_stmt (pre_p, g);
12139 *expr_p = NULL_TREE;
12142 /* Helper function for gimplify_omp_for. If *TP is not a gimple constant,
12143 force it into a temporary initialized in PRE_P and add firstprivate clause
12144 to ORIG_FOR_STMT. */
12146 static void
12147 gimplify_omp_taskloop_expr (tree type, tree *tp, gimple_seq *pre_p,
12148 tree orig_for_stmt)
12150 if (*tp == NULL || is_gimple_constant (*tp))
12151 return;
12153 *tp = get_initialized_tmp_var (*tp, pre_p, NULL, false);
12154 /* Reference to pointer conversion is considered useless,
12155 but is significant for firstprivate clause. Force it
12156 here. */
12157 if (type
12158 && TREE_CODE (type) == POINTER_TYPE
12159 && TREE_CODE (TREE_TYPE (*tp)) == REFERENCE_TYPE)
12161 tree v = create_tmp_var (TYPE_MAIN_VARIANT (type));
12162 tree m = build2 (INIT_EXPR, TREE_TYPE (v), v, *tp);
12163 gimplify_and_add (m, pre_p);
12164 *tp = v;
12167 tree c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
12168 OMP_CLAUSE_DECL (c) = *tp;
12169 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
12170 OMP_FOR_CLAUSES (orig_for_stmt) = c;
12173 /* Gimplify the gross structure of an OMP_FOR statement. */
12175 static enum gimplify_status
12176 gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
12178 tree for_stmt, orig_for_stmt, inner_for_stmt = NULL_TREE, decl, var, t;
12179 enum gimplify_status ret = GS_ALL_DONE;
12180 enum gimplify_status tret;
12181 gomp_for *gfor;
12182 gimple_seq for_body, for_pre_body;
12183 int i;
12184 bitmap has_decl_expr = NULL;
12185 enum omp_region_type ort = ORT_WORKSHARE;
12186 bool openacc = TREE_CODE (*expr_p) == OACC_LOOP;
12188 orig_for_stmt = for_stmt = *expr_p;
12190 bool loop_p = (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_BIND)
12191 != NULL_TREE);
12192 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
12194 tree *data[4] = { NULL, NULL, NULL, NULL };
12195 gcc_assert (TREE_CODE (for_stmt) != OACC_LOOP);
12196 inner_for_stmt = walk_tree (&OMP_FOR_BODY (for_stmt),
12197 find_combined_omp_for, data, NULL);
12198 if (inner_for_stmt == NULL_TREE)
12200 gcc_assert (seen_error ());
12201 *expr_p = NULL_TREE;
12202 return GS_ERROR;
12204 if (data[2] && OMP_FOR_PRE_BODY (*data[2]))
12206 append_to_statement_list_force (OMP_FOR_PRE_BODY (*data[2]),
12207 &OMP_FOR_PRE_BODY (for_stmt));
12208 OMP_FOR_PRE_BODY (*data[2]) = NULL_TREE;
12210 if (OMP_FOR_PRE_BODY (inner_for_stmt))
12212 append_to_statement_list_force (OMP_FOR_PRE_BODY (inner_for_stmt),
12213 &OMP_FOR_PRE_BODY (for_stmt));
12214 OMP_FOR_PRE_BODY (inner_for_stmt) = NULL_TREE;
12217 if (data[0])
12219 /* We have some statements or variable declarations in between
12220 the composite construct directives. Move them around the
12221 inner_for_stmt. */
12222 data[0] = expr_p;
12223 for (i = 0; i < 3; i++)
12224 if (data[i])
12226 tree t = *data[i];
12227 if (i < 2 && data[i + 1] == &OMP_BODY (t))
12228 data[i + 1] = data[i];
12229 *data[i] = OMP_BODY (t);
12230 tree body = build3 (BIND_EXPR, void_type_node, NULL_TREE,
12231 NULL_TREE, make_node (BLOCK));
12232 OMP_BODY (t) = body;
12233 append_to_statement_list_force (inner_for_stmt,
12234 &BIND_EXPR_BODY (body));
12235 *data[3] = t;
12236 data[3] = tsi_stmt_ptr (tsi_start (BIND_EXPR_BODY (body)));
12237 gcc_assert (*data[3] == inner_for_stmt);
12239 return GS_OK;
12242 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
12243 if (!loop_p
12244 && OMP_FOR_ORIG_DECLS (inner_for_stmt)
12245 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
12246 i)) == TREE_LIST
12247 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
12248 i)))
12250 tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
12251 /* Class iterators aren't allowed on OMP_SIMD, so the only
12252 case we need to solve is distribute parallel for. They are
12253 allowed on the loop construct, but that is already handled
12254 in gimplify_omp_loop. */
12255 gcc_assert (TREE_CODE (inner_for_stmt) == OMP_FOR
12256 && TREE_CODE (for_stmt) == OMP_DISTRIBUTE
12257 && data[1]);
12258 tree orig_decl = TREE_PURPOSE (orig);
12259 tree last = TREE_VALUE (orig);
12260 tree *pc;
12261 for (pc = &OMP_FOR_CLAUSES (inner_for_stmt);
12262 *pc; pc = &OMP_CLAUSE_CHAIN (*pc))
12263 if ((OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE
12264 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LASTPRIVATE)
12265 && OMP_CLAUSE_DECL (*pc) == orig_decl)
12266 break;
12267 if (*pc == NULL_TREE)
12269 tree *spc;
12270 for (spc = &OMP_PARALLEL_CLAUSES (*data[1]);
12271 *spc; spc = &OMP_CLAUSE_CHAIN (*spc))
12272 if (OMP_CLAUSE_CODE (*spc) == OMP_CLAUSE_PRIVATE
12273 && OMP_CLAUSE_DECL (*spc) == orig_decl)
12274 break;
12275 if (*spc)
12277 tree c = *spc;
12278 *spc = OMP_CLAUSE_CHAIN (c);
12279 OMP_CLAUSE_CHAIN (c) = NULL_TREE;
12280 *pc = c;
12283 if (*pc == NULL_TREE)
12285 else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE)
12287 /* private clause will appear only on inner_for_stmt.
12288 Change it into firstprivate, and add private clause
12289 on for_stmt. */
12290 tree c = copy_node (*pc);
12291 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
12292 OMP_FOR_CLAUSES (for_stmt) = c;
12293 OMP_CLAUSE_CODE (*pc) = OMP_CLAUSE_FIRSTPRIVATE;
12294 lang_hooks.decls.omp_finish_clause (*pc, pre_p, openacc);
12296 else
12298 /* lastprivate clause will appear on both inner_for_stmt
12299 and for_stmt. Add firstprivate clause to
12300 inner_for_stmt. */
12301 tree c = build_omp_clause (OMP_CLAUSE_LOCATION (*pc),
12302 OMP_CLAUSE_FIRSTPRIVATE);
12303 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (*pc);
12304 OMP_CLAUSE_CHAIN (c) = *pc;
12305 *pc = c;
12306 lang_hooks.decls.omp_finish_clause (*pc, pre_p, openacc);
12308 tree c = build_omp_clause (UNKNOWN_LOCATION,
12309 OMP_CLAUSE_FIRSTPRIVATE);
12310 OMP_CLAUSE_DECL (c) = last;
12311 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
12312 OMP_PARALLEL_CLAUSES (*data[1]) = c;
12313 c = build_omp_clause (UNKNOWN_LOCATION,
12314 *pc ? OMP_CLAUSE_SHARED
12315 : OMP_CLAUSE_FIRSTPRIVATE);
12316 OMP_CLAUSE_DECL (c) = orig_decl;
12317 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
12318 OMP_PARALLEL_CLAUSES (*data[1]) = c;
12320 /* Similarly, take care of C++ range for temporaries, those should
12321 be firstprivate on OMP_PARALLEL if any. */
12322 if (data[1])
12323 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
12324 if (OMP_FOR_ORIG_DECLS (inner_for_stmt)
12325 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
12326 i)) == TREE_LIST
12327 && TREE_CHAIN (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
12328 i)))
12330 tree orig
12331 = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
12332 tree v = TREE_CHAIN (orig);
12333 tree c = build_omp_clause (UNKNOWN_LOCATION,
12334 OMP_CLAUSE_FIRSTPRIVATE);
12335 /* First add firstprivate clause for the __for_end artificial
12336 decl. */
12337 OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 1);
12338 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
12339 == REFERENCE_TYPE)
12340 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
12341 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
12342 OMP_PARALLEL_CLAUSES (*data[1]) = c;
12343 if (TREE_VEC_ELT (v, 0))
12345 /* And now the same for __for_range artificial decl if it
12346 exists. */
12347 c = build_omp_clause (UNKNOWN_LOCATION,
12348 OMP_CLAUSE_FIRSTPRIVATE);
12349 OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 0);
12350 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
12351 == REFERENCE_TYPE)
12352 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
12353 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
12354 OMP_PARALLEL_CLAUSES (*data[1]) = c;
12359 switch (TREE_CODE (for_stmt))
12361 case OMP_FOR:
12362 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt))
12364 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
12365 OMP_CLAUSE_SCHEDULE))
12366 error_at (EXPR_LOCATION (for_stmt),
12367 "%qs clause may not appear on non-rectangular %qs",
12368 "schedule", "for");
12369 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED))
12370 error_at (EXPR_LOCATION (for_stmt),
12371 "%qs clause may not appear on non-rectangular %qs",
12372 "ordered", "for");
12374 break;
12375 case OMP_DISTRIBUTE:
12376 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt)
12377 && omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
12378 OMP_CLAUSE_DIST_SCHEDULE))
12379 error_at (EXPR_LOCATION (for_stmt),
12380 "%qs clause may not appear on non-rectangular %qs",
12381 "dist_schedule", "distribute");
12382 break;
12383 case OACC_LOOP:
12384 ort = ORT_ACC;
12385 break;
12386 case OMP_TASKLOOP:
12387 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_UNTIED))
12388 ort = ORT_UNTIED_TASKLOOP;
12389 else
12390 ort = ORT_TASKLOOP;
12391 break;
12392 case OMP_SIMD:
12393 ort = ORT_SIMD;
12394 break;
12395 default:
12396 gcc_unreachable ();
12399 /* Set OMP_CLAUSE_LINEAR_NO_COPYIN flag on explicit linear
12400 clause for the IV. */
12401 if (ort == ORT_SIMD && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
12403 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), 0);
12404 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
12405 decl = TREE_OPERAND (t, 0);
12406 for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
12407 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
12408 && OMP_CLAUSE_DECL (c) == decl)
12410 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
12411 break;
12415 if (TREE_CODE (for_stmt) != OMP_TASKLOOP)
12416 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p, ort,
12417 loop_p && TREE_CODE (for_stmt) != OMP_SIMD
12418 ? OMP_LOOP : TREE_CODE (for_stmt));
12420 if (TREE_CODE (for_stmt) == OMP_DISTRIBUTE)
12421 gimplify_omp_ctxp->distribute = true;
12423 /* Handle OMP_FOR_INIT. */
12424 for_pre_body = NULL;
12425 if ((ort == ORT_SIMD
12426 || (inner_for_stmt && TREE_CODE (inner_for_stmt) == OMP_SIMD))
12427 && OMP_FOR_PRE_BODY (for_stmt))
12429 has_decl_expr = BITMAP_ALLOC (NULL);
12430 if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == DECL_EXPR
12431 && TREE_CODE (DECL_EXPR_DECL (OMP_FOR_PRE_BODY (for_stmt)))
12432 == VAR_DECL)
12434 t = OMP_FOR_PRE_BODY (for_stmt);
12435 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
12437 else if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == STATEMENT_LIST)
12439 tree_stmt_iterator si;
12440 for (si = tsi_start (OMP_FOR_PRE_BODY (for_stmt)); !tsi_end_p (si);
12441 tsi_next (&si))
12443 t = tsi_stmt (si);
12444 if (TREE_CODE (t) == DECL_EXPR
12445 && TREE_CODE (DECL_EXPR_DECL (t)) == VAR_DECL)
12446 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
12450 if (OMP_FOR_PRE_BODY (for_stmt))
12452 if (TREE_CODE (for_stmt) != OMP_TASKLOOP || gimplify_omp_ctxp)
12453 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
12454 else
12456 struct gimplify_omp_ctx ctx;
12457 memset (&ctx, 0, sizeof (ctx));
12458 ctx.region_type = ORT_NONE;
12459 gimplify_omp_ctxp = &ctx;
12460 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
12461 gimplify_omp_ctxp = NULL;
12464 OMP_FOR_PRE_BODY (for_stmt) = NULL_TREE;
12466 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
12467 for_stmt = inner_for_stmt;
12469 /* For taskloop, need to gimplify the start, end and step before the
12470 taskloop, outside of the taskloop omp context. */
12471 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
12473 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
12475 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
12476 gimple_seq *for_pre_p = (gimple_seq_empty_p (for_pre_body)
12477 ? pre_p : &for_pre_body);
12478 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
12479 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
12481 tree v = TREE_OPERAND (t, 1);
12482 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 1),
12483 for_pre_p, orig_for_stmt);
12484 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 2),
12485 for_pre_p, orig_for_stmt);
12487 else
12488 gimplify_omp_taskloop_expr (type, &TREE_OPERAND (t, 1), for_pre_p,
12489 orig_for_stmt);
12491 /* Handle OMP_FOR_COND. */
12492 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
12493 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
12495 tree v = TREE_OPERAND (t, 1);
12496 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 1),
12497 for_pre_p, orig_for_stmt);
12498 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 2),
12499 for_pre_p, orig_for_stmt);
12501 else
12502 gimplify_omp_taskloop_expr (type, &TREE_OPERAND (t, 1), for_pre_p,
12503 orig_for_stmt);
12505 /* Handle OMP_FOR_INCR. */
12506 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
12507 if (TREE_CODE (t) == MODIFY_EXPR)
12509 decl = TREE_OPERAND (t, 0);
12510 t = TREE_OPERAND (t, 1);
12511 tree *tp = &TREE_OPERAND (t, 1);
12512 if (TREE_CODE (t) == PLUS_EXPR && *tp == decl)
12513 tp = &TREE_OPERAND (t, 0);
12515 gimplify_omp_taskloop_expr (NULL_TREE, tp, for_pre_p,
12516 orig_for_stmt);
12520 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (orig_for_stmt), pre_p, ort,
12521 OMP_TASKLOOP);
12524 if (orig_for_stmt != for_stmt)
12525 gimplify_omp_ctxp->combined_loop = true;
12527 for_body = NULL;
12528 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
12529 == TREE_VEC_LENGTH (OMP_FOR_COND (for_stmt)));
12530 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
12531 == TREE_VEC_LENGTH (OMP_FOR_INCR (for_stmt)));
12533 tree c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED);
12534 bool is_doacross = false;
12535 if (c && OMP_CLAUSE_ORDERED_EXPR (c))
12537 is_doacross = true;
12538 gimplify_omp_ctxp->loop_iter_var.create (TREE_VEC_LENGTH
12539 (OMP_FOR_INIT (for_stmt))
12540 * 2);
12542 int collapse = 1, tile = 0;
12543 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_COLLAPSE);
12544 if (c)
12545 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (c));
12546 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_TILE);
12547 if (c)
12548 tile = list_length (OMP_CLAUSE_TILE_LIST (c));
12549 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ALLOCATE);
12550 hash_set<tree> *allocate_uids = NULL;
12551 if (c)
12553 allocate_uids = new hash_set<tree>;
12554 for (; c; c = OMP_CLAUSE_CHAIN (c))
12555 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ALLOCATE)
12556 allocate_uids->add (OMP_CLAUSE_DECL (c));
12558 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
12560 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
12561 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
12562 decl = TREE_OPERAND (t, 0);
12563 gcc_assert (DECL_P (decl));
12564 gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl))
12565 || POINTER_TYPE_P (TREE_TYPE (decl)));
12566 if (is_doacross)
12568 if (TREE_CODE (for_stmt) == OMP_FOR && OMP_FOR_ORIG_DECLS (for_stmt))
12570 tree orig_decl = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
12571 if (TREE_CODE (orig_decl) == TREE_LIST)
12573 orig_decl = TREE_PURPOSE (orig_decl);
12574 if (!orig_decl)
12575 orig_decl = decl;
12577 gimplify_omp_ctxp->loop_iter_var.quick_push (orig_decl);
12579 else
12580 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
12581 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
12584 if (for_stmt == orig_for_stmt)
12586 tree orig_decl = decl;
12587 if (OMP_FOR_ORIG_DECLS (for_stmt))
12589 tree orig_decl = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
12590 if (TREE_CODE (orig_decl) == TREE_LIST)
12592 orig_decl = TREE_PURPOSE (orig_decl);
12593 if (!orig_decl)
12594 orig_decl = decl;
12597 if (is_global_var (orig_decl) && DECL_THREAD_LOCAL_P (orig_decl))
12598 error_at (EXPR_LOCATION (for_stmt),
12599 "threadprivate iteration variable %qD", orig_decl);
12602 /* Make sure the iteration variable is private. */
12603 tree c = NULL_TREE;
12604 tree c2 = NULL_TREE;
12605 if (orig_for_stmt != for_stmt)
12607 /* Preserve this information until we gimplify the inner simd. */
12608 if (has_decl_expr
12609 && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
12610 TREE_PRIVATE (t) = 1;
12612 else if (ort == ORT_SIMD)
12614 splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
12615 (splay_tree_key) decl);
12616 omp_is_private (gimplify_omp_ctxp, decl,
12617 1 + (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
12618 != 1));
12619 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
12621 omp_notice_variable (gimplify_omp_ctxp, decl, true);
12622 if (n->value & GOVD_LASTPRIVATE_CONDITIONAL)
12623 for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
12624 OMP_CLAUSE_LASTPRIVATE);
12625 c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
12626 OMP_CLAUSE_LASTPRIVATE))
12627 if (OMP_CLAUSE_DECL (c3) == decl)
12629 warning_at (OMP_CLAUSE_LOCATION (c3), 0,
12630 "conditional %<lastprivate%> on loop "
12631 "iterator %qD ignored", decl);
12632 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
12633 n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
12636 else if (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1 && !loop_p)
12638 c = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
12639 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
12640 unsigned int flags = GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN;
12641 if ((has_decl_expr
12642 && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
12643 || TREE_PRIVATE (t))
12645 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
12646 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
12648 struct gimplify_omp_ctx *outer
12649 = gimplify_omp_ctxp->outer_context;
12650 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
12652 if (outer->region_type == ORT_WORKSHARE
12653 && outer->combined_loop)
12655 n = splay_tree_lookup (outer->variables,
12656 (splay_tree_key)decl);
12657 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
12659 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
12660 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
12662 else
12664 struct gimplify_omp_ctx *octx = outer->outer_context;
12665 if (octx
12666 && octx->region_type == ORT_COMBINED_PARALLEL
12667 && octx->outer_context
12668 && (octx->outer_context->region_type
12669 == ORT_WORKSHARE)
12670 && octx->outer_context->combined_loop)
12672 octx = octx->outer_context;
12673 n = splay_tree_lookup (octx->variables,
12674 (splay_tree_key)decl);
12675 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
12677 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
12678 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
12685 OMP_CLAUSE_DECL (c) = decl;
12686 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
12687 OMP_FOR_CLAUSES (for_stmt) = c;
12688 omp_add_variable (gimplify_omp_ctxp, decl, flags);
12689 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
12690 omp_lastprivate_for_combined_outer_constructs (outer, decl,
12691 true);
12693 else
12695 bool lastprivate
12696 = (!has_decl_expr
12697 || !bitmap_bit_p (has_decl_expr, DECL_UID (decl)));
12698 if (TREE_PRIVATE (t))
12699 lastprivate = false;
12700 if (loop_p && OMP_FOR_ORIG_DECLS (for_stmt))
12702 tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
12703 if (TREE_CODE (elt) == TREE_LIST && TREE_PURPOSE (elt))
12704 lastprivate = false;
12707 struct gimplify_omp_ctx *outer
12708 = gimplify_omp_ctxp->outer_context;
12709 if (outer && lastprivate)
12710 omp_lastprivate_for_combined_outer_constructs (outer, decl,
12711 true);
12713 c = build_omp_clause (input_location,
12714 lastprivate ? OMP_CLAUSE_LASTPRIVATE
12715 : OMP_CLAUSE_PRIVATE);
12716 OMP_CLAUSE_DECL (c) = decl;
12717 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
12718 OMP_FOR_CLAUSES (for_stmt) = c;
12719 omp_add_variable (gimplify_omp_ctxp, decl,
12720 (lastprivate ? GOVD_LASTPRIVATE : GOVD_PRIVATE)
12721 | GOVD_EXPLICIT | GOVD_SEEN);
12722 c = NULL_TREE;
12725 else if (omp_is_private (gimplify_omp_ctxp, decl, 0))
12727 omp_notice_variable (gimplify_omp_ctxp, decl, true);
12728 splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
12729 (splay_tree_key) decl);
12730 if (n && (n->value & GOVD_LASTPRIVATE_CONDITIONAL))
12731 for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
12732 OMP_CLAUSE_LASTPRIVATE);
12733 c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
12734 OMP_CLAUSE_LASTPRIVATE))
12735 if (OMP_CLAUSE_DECL (c3) == decl)
12737 warning_at (OMP_CLAUSE_LOCATION (c3), 0,
12738 "conditional %<lastprivate%> on loop "
12739 "iterator %qD ignored", decl);
12740 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
12741 n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
12744 else
12745 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN);
12747 /* If DECL is not a gimple register, create a temporary variable to act
12748 as an iteration counter. This is valid, since DECL cannot be
12749 modified in the body of the loop. Similarly for any iteration vars
12750 in simd with collapse > 1 where the iterator vars must be
12751 lastprivate. And similarly for vars mentioned in allocate clauses. */
12752 if (orig_for_stmt != for_stmt)
12753 var = decl;
12754 else if (!is_gimple_reg (decl)
12755 || (ort == ORT_SIMD
12756 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) > 1)
12757 || (allocate_uids && allocate_uids->contains (decl)))
12759 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
12760 /* Make sure omp_add_variable is not called on it prematurely.
12761 We call it ourselves a few lines later. */
12762 gimplify_omp_ctxp = NULL;
12763 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
12764 gimplify_omp_ctxp = ctx;
12765 TREE_OPERAND (t, 0) = var;
12767 gimplify_seq_add_stmt (&for_body, gimple_build_assign (decl, var));
12769 if (ort == ORT_SIMD
12770 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
12772 c2 = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
12773 OMP_CLAUSE_LINEAR_NO_COPYIN (c2) = 1;
12774 OMP_CLAUSE_LINEAR_NO_COPYOUT (c2) = 1;
12775 OMP_CLAUSE_DECL (c2) = var;
12776 OMP_CLAUSE_CHAIN (c2) = OMP_FOR_CLAUSES (for_stmt);
12777 OMP_FOR_CLAUSES (for_stmt) = c2;
12778 omp_add_variable (gimplify_omp_ctxp, var,
12779 GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN);
12780 if (c == NULL_TREE)
12782 c = c2;
12783 c2 = NULL_TREE;
12786 else
12787 omp_add_variable (gimplify_omp_ctxp, var,
12788 GOVD_PRIVATE | GOVD_SEEN);
12790 else
12791 var = decl;
12793 gimplify_omp_ctxp->in_for_exprs = true;
12794 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
12796 tree lb = TREE_OPERAND (t, 1);
12797 tret = gimplify_expr (&TREE_VEC_ELT (lb, 1), &for_pre_body, NULL,
12798 is_gimple_val, fb_rvalue, false);
12799 ret = MIN (ret, tret);
12800 tret = gimplify_expr (&TREE_VEC_ELT (lb, 2), &for_pre_body, NULL,
12801 is_gimple_val, fb_rvalue, false);
12803 else
12804 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
12805 is_gimple_val, fb_rvalue, false);
12806 gimplify_omp_ctxp->in_for_exprs = false;
12807 ret = MIN (ret, tret);
12808 if (ret == GS_ERROR)
12809 return ret;
12811 /* Handle OMP_FOR_COND. */
12812 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
12813 gcc_assert (COMPARISON_CLASS_P (t));
12814 gcc_assert (TREE_OPERAND (t, 0) == decl);
12816 gimplify_omp_ctxp->in_for_exprs = true;
12817 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
12819 tree ub = TREE_OPERAND (t, 1);
12820 tret = gimplify_expr (&TREE_VEC_ELT (ub, 1), &for_pre_body, NULL,
12821 is_gimple_val, fb_rvalue, false);
12822 ret = MIN (ret, tret);
12823 tret = gimplify_expr (&TREE_VEC_ELT (ub, 2), &for_pre_body, NULL,
12824 is_gimple_val, fb_rvalue, false);
12826 else
12827 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
12828 is_gimple_val, fb_rvalue, false);
12829 gimplify_omp_ctxp->in_for_exprs = false;
12830 ret = MIN (ret, tret);
12832 /* Handle OMP_FOR_INCR. */
12833 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
12834 switch (TREE_CODE (t))
12836 case PREINCREMENT_EXPR:
12837 case POSTINCREMENT_EXPR:
12839 tree decl = TREE_OPERAND (t, 0);
12840 /* c_omp_for_incr_canonicalize_ptr() should have been
12841 called to massage things appropriately. */
12842 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
12844 if (orig_for_stmt != for_stmt)
12845 break;
12846 t = build_int_cst (TREE_TYPE (decl), 1);
12847 if (c)
12848 OMP_CLAUSE_LINEAR_STEP (c) = t;
12849 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
12850 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
12851 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
12852 break;
12855 case PREDECREMENT_EXPR:
12856 case POSTDECREMENT_EXPR:
12857 /* c_omp_for_incr_canonicalize_ptr() should have been
12858 called to massage things appropriately. */
12859 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
12860 if (orig_for_stmt != for_stmt)
12861 break;
12862 t = build_int_cst (TREE_TYPE (decl), -1);
12863 if (c)
12864 OMP_CLAUSE_LINEAR_STEP (c) = t;
12865 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
12866 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
12867 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
12868 break;
12870 case MODIFY_EXPR:
12871 gcc_assert (TREE_OPERAND (t, 0) == decl);
12872 TREE_OPERAND (t, 0) = var;
12874 t = TREE_OPERAND (t, 1);
12875 switch (TREE_CODE (t))
12877 case PLUS_EXPR:
12878 if (TREE_OPERAND (t, 1) == decl)
12880 TREE_OPERAND (t, 1) = TREE_OPERAND (t, 0);
12881 TREE_OPERAND (t, 0) = var;
12882 break;
12885 /* Fallthru. */
12886 case MINUS_EXPR:
12887 case POINTER_PLUS_EXPR:
12888 gcc_assert (TREE_OPERAND (t, 0) == decl);
12889 TREE_OPERAND (t, 0) = var;
12890 break;
12891 default:
12892 gcc_unreachable ();
12895 gimplify_omp_ctxp->in_for_exprs = true;
12896 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
12897 is_gimple_val, fb_rvalue, false);
12898 ret = MIN (ret, tret);
12899 if (c)
12901 tree step = TREE_OPERAND (t, 1);
12902 tree stept = TREE_TYPE (decl);
12903 if (POINTER_TYPE_P (stept))
12904 stept = sizetype;
12905 step = fold_convert (stept, step);
12906 if (TREE_CODE (t) == MINUS_EXPR)
12907 step = fold_build1 (NEGATE_EXPR, stept, step);
12908 OMP_CLAUSE_LINEAR_STEP (c) = step;
12909 if (step != TREE_OPERAND (t, 1))
12911 tret = gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c),
12912 &for_pre_body, NULL,
12913 is_gimple_val, fb_rvalue, false);
12914 ret = MIN (ret, tret);
12917 gimplify_omp_ctxp->in_for_exprs = false;
12918 break;
12920 default:
12921 gcc_unreachable ();
12924 if (c2)
12926 gcc_assert (c);
12927 OMP_CLAUSE_LINEAR_STEP (c2) = OMP_CLAUSE_LINEAR_STEP (c);
12930 if ((var != decl || collapse > 1 || tile) && orig_for_stmt == for_stmt)
12932 for (c = OMP_FOR_CLAUSES (for_stmt); c ; c = OMP_CLAUSE_CHAIN (c))
12933 if (((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
12934 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) == NULL)
12935 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
12936 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)
12937 && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c) == NULL))
12938 && OMP_CLAUSE_DECL (c) == decl)
12940 if (is_doacross && (collapse == 1 || i >= collapse))
12941 t = var;
12942 else
12944 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
12945 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
12946 gcc_assert (TREE_OPERAND (t, 0) == var);
12947 t = TREE_OPERAND (t, 1);
12948 gcc_assert (TREE_CODE (t) == PLUS_EXPR
12949 || TREE_CODE (t) == MINUS_EXPR
12950 || TREE_CODE (t) == POINTER_PLUS_EXPR);
12951 gcc_assert (TREE_OPERAND (t, 0) == var);
12952 t = build2 (TREE_CODE (t), TREE_TYPE (decl),
12953 is_doacross ? var : decl,
12954 TREE_OPERAND (t, 1));
12956 gimple_seq *seq;
12957 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
12958 seq = &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c);
12959 else
12960 seq = &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c);
12961 push_gimplify_context ();
12962 gimplify_assign (decl, t, seq);
12963 gimple *bind = NULL;
12964 if (gimplify_ctxp->temps)
12966 bind = gimple_build_bind (NULL_TREE, *seq, NULL_TREE);
12967 *seq = NULL;
12968 gimplify_seq_add_stmt (seq, bind);
12970 pop_gimplify_context (bind);
12973 if (OMP_FOR_NON_RECTANGULAR (for_stmt) && var != decl)
12974 for (int j = i + 1; j < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); j++)
12976 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), j);
12977 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
12978 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
12979 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
12980 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
12981 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), j);
12982 gcc_assert (COMPARISON_CLASS_P (t));
12983 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
12984 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
12985 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
12989 BITMAP_FREE (has_decl_expr);
12990 delete allocate_uids;
12992 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP
12993 || (loop_p && orig_for_stmt == for_stmt))
12995 push_gimplify_context ();
12996 if (TREE_CODE (OMP_FOR_BODY (orig_for_stmt)) != BIND_EXPR)
12998 OMP_FOR_BODY (orig_for_stmt)
12999 = build3 (BIND_EXPR, void_type_node, NULL,
13000 OMP_FOR_BODY (orig_for_stmt), NULL);
13001 TREE_SIDE_EFFECTS (OMP_FOR_BODY (orig_for_stmt)) = 1;
13005 gimple *g = gimplify_and_return_first (OMP_FOR_BODY (orig_for_stmt),
13006 &for_body);
13008 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP
13009 || (loop_p && orig_for_stmt == for_stmt))
13011 if (gimple_code (g) == GIMPLE_BIND)
13012 pop_gimplify_context (g);
13013 else
13014 pop_gimplify_context (NULL);
13017 if (orig_for_stmt != for_stmt)
13018 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
13020 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
13021 decl = TREE_OPERAND (t, 0);
13022 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
13023 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
13024 gimplify_omp_ctxp = ctx->outer_context;
13025 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
13026 gimplify_omp_ctxp = ctx;
13027 omp_add_variable (gimplify_omp_ctxp, var, GOVD_PRIVATE | GOVD_SEEN);
13028 TREE_OPERAND (t, 0) = var;
13029 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
13030 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
13031 TREE_OPERAND (TREE_OPERAND (t, 1), 0) = var;
13032 if (OMP_FOR_NON_RECTANGULAR (for_stmt))
13033 for (int j = i + 1;
13034 j < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); j++)
13036 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), j);
13037 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
13038 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
13039 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
13041 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
13042 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
13044 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), j);
13045 gcc_assert (COMPARISON_CLASS_P (t));
13046 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
13047 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
13049 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
13050 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
13055 gimplify_adjust_omp_clauses (pre_p, for_body,
13056 &OMP_FOR_CLAUSES (orig_for_stmt),
13057 TREE_CODE (orig_for_stmt));
13059 int kind;
13060 switch (TREE_CODE (orig_for_stmt))
13062 case OMP_FOR: kind = GF_OMP_FOR_KIND_FOR; break;
13063 case OMP_SIMD: kind = GF_OMP_FOR_KIND_SIMD; break;
13064 case OMP_DISTRIBUTE: kind = GF_OMP_FOR_KIND_DISTRIBUTE; break;
13065 case OMP_TASKLOOP: kind = GF_OMP_FOR_KIND_TASKLOOP; break;
13066 case OACC_LOOP: kind = GF_OMP_FOR_KIND_OACC_LOOP; break;
13067 default:
13068 gcc_unreachable ();
13070 if (loop_p && kind == GF_OMP_FOR_KIND_SIMD)
13072 gimplify_seq_add_seq (pre_p, for_pre_body);
13073 for_pre_body = NULL;
13075 gfor = gimple_build_omp_for (for_body, kind, OMP_FOR_CLAUSES (orig_for_stmt),
13076 TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)),
13077 for_pre_body);
13078 if (orig_for_stmt != for_stmt)
13079 gimple_omp_for_set_combined_p (gfor, true);
13080 if (gimplify_omp_ctxp
13081 && (gimplify_omp_ctxp->combined_loop
13082 || (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
13083 && gimplify_omp_ctxp->outer_context
13084 && gimplify_omp_ctxp->outer_context->combined_loop)))
13086 gimple_omp_for_set_combined_into_p (gfor, true);
13087 if (gimplify_omp_ctxp->combined_loop)
13088 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_SIMD);
13089 else
13090 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_FOR);
13093 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
13095 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
13096 gimple_omp_for_set_index (gfor, i, TREE_OPERAND (t, 0));
13097 gimple_omp_for_set_initial (gfor, i, TREE_OPERAND (t, 1));
13098 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
13099 gimple_omp_for_set_cond (gfor, i, TREE_CODE (t));
13100 gimple_omp_for_set_final (gfor, i, TREE_OPERAND (t, 1));
13101 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
13102 gimple_omp_for_set_incr (gfor, i, TREE_OPERAND (t, 1));
13105 /* OMP_TASKLOOP is gimplified as two GIMPLE_OMP_FOR taskloop
13106 constructs with GIMPLE_OMP_TASK sandwiched in between them.
13107 The outer taskloop stands for computing the number of iterations,
13108 counts for collapsed loops and holding taskloop specific clauses.
13109 The task construct stands for the effect of data sharing on the
13110 explicit task it creates and the inner taskloop stands for expansion
13111 of the static loop inside of the explicit task construct. */
13112 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
13114 tree *gfor_clauses_ptr = gimple_omp_for_clauses_ptr (gfor);
13115 tree task_clauses = NULL_TREE;
13116 tree c = *gfor_clauses_ptr;
13117 tree *gtask_clauses_ptr = &task_clauses;
13118 tree outer_for_clauses = NULL_TREE;
13119 tree *gforo_clauses_ptr = &outer_for_clauses;
13120 bitmap lastprivate_uids = NULL;
13121 if (omp_find_clause (c, OMP_CLAUSE_ALLOCATE))
13123 c = omp_find_clause (c, OMP_CLAUSE_LASTPRIVATE);
13124 if (c)
13126 lastprivate_uids = BITMAP_ALLOC (NULL);
13127 for (; c; c = omp_find_clause (OMP_CLAUSE_CHAIN (c),
13128 OMP_CLAUSE_LASTPRIVATE))
13129 bitmap_set_bit (lastprivate_uids,
13130 DECL_UID (OMP_CLAUSE_DECL (c)));
13132 c = *gfor_clauses_ptr;
13134 for (; c; c = OMP_CLAUSE_CHAIN (c))
13135 switch (OMP_CLAUSE_CODE (c))
13137 /* These clauses are allowed on task, move them there. */
13138 case OMP_CLAUSE_SHARED:
13139 case OMP_CLAUSE_FIRSTPRIVATE:
13140 case OMP_CLAUSE_DEFAULT:
13141 case OMP_CLAUSE_IF:
13142 case OMP_CLAUSE_UNTIED:
13143 case OMP_CLAUSE_FINAL:
13144 case OMP_CLAUSE_MERGEABLE:
13145 case OMP_CLAUSE_PRIORITY:
13146 case OMP_CLAUSE_REDUCTION:
13147 case OMP_CLAUSE_IN_REDUCTION:
13148 *gtask_clauses_ptr = c;
13149 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13150 break;
13151 case OMP_CLAUSE_PRIVATE:
13152 if (OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c))
13154 /* We want private on outer for and firstprivate
13155 on task. */
13156 *gtask_clauses_ptr
13157 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
13158 OMP_CLAUSE_FIRSTPRIVATE);
13159 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
13160 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL,
13161 openacc);
13162 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
13163 *gforo_clauses_ptr = c;
13164 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13166 else
13168 *gtask_clauses_ptr = c;
13169 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13171 break;
13172 /* These clauses go into outer taskloop clauses. */
13173 case OMP_CLAUSE_GRAINSIZE:
13174 case OMP_CLAUSE_NUM_TASKS:
13175 case OMP_CLAUSE_NOGROUP:
13176 *gforo_clauses_ptr = c;
13177 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13178 break;
13179 /* Collapse clause we duplicate on both taskloops. */
13180 case OMP_CLAUSE_COLLAPSE:
13181 *gfor_clauses_ptr = c;
13182 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13183 *gforo_clauses_ptr = copy_node (c);
13184 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
13185 break;
13186 /* For lastprivate, keep the clause on inner taskloop, and add
13187 a shared clause on task. If the same decl is also firstprivate,
13188 add also firstprivate clause on the inner taskloop. */
13189 case OMP_CLAUSE_LASTPRIVATE:
13190 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
13192 /* For taskloop C++ lastprivate IVs, we want:
13193 1) private on outer taskloop
13194 2) firstprivate and shared on task
13195 3) lastprivate on inner taskloop */
13196 *gtask_clauses_ptr
13197 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
13198 OMP_CLAUSE_FIRSTPRIVATE);
13199 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
13200 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL,
13201 openacc);
13202 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
13203 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c) = 1;
13204 *gforo_clauses_ptr = build_omp_clause (OMP_CLAUSE_LOCATION (c),
13205 OMP_CLAUSE_PRIVATE);
13206 OMP_CLAUSE_DECL (*gforo_clauses_ptr) = OMP_CLAUSE_DECL (c);
13207 OMP_CLAUSE_PRIVATE_TASKLOOP_IV (*gforo_clauses_ptr) = 1;
13208 TREE_TYPE (*gforo_clauses_ptr) = TREE_TYPE (c);
13209 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
13211 *gfor_clauses_ptr = c;
13212 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13213 *gtask_clauses_ptr
13214 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_SHARED);
13215 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
13216 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
13217 OMP_CLAUSE_SHARED_FIRSTPRIVATE (*gtask_clauses_ptr) = 1;
13218 gtask_clauses_ptr
13219 = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
13220 break;
13221 /* Allocate clause we duplicate on task and inner taskloop
13222 if the decl is lastprivate, otherwise just put on task. */
13223 case OMP_CLAUSE_ALLOCATE:
13224 if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
13225 && DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)))
13227 /* Additionally, put firstprivate clause on task
13228 for the allocator if it is not constant. */
13229 *gtask_clauses_ptr
13230 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
13231 OMP_CLAUSE_FIRSTPRIVATE);
13232 OMP_CLAUSE_DECL (*gtask_clauses_ptr)
13233 = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
13234 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
13236 if (lastprivate_uids
13237 && bitmap_bit_p (lastprivate_uids,
13238 DECL_UID (OMP_CLAUSE_DECL (c))))
13240 *gfor_clauses_ptr = c;
13241 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13242 *gtask_clauses_ptr = copy_node (c);
13243 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
13245 else
13247 *gtask_clauses_ptr = c;
13248 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13250 break;
13251 default:
13252 gcc_unreachable ();
13254 *gfor_clauses_ptr = NULL_TREE;
13255 *gtask_clauses_ptr = NULL_TREE;
13256 *gforo_clauses_ptr = NULL_TREE;
13257 BITMAP_FREE (lastprivate_uids);
13258 g = gimple_build_bind (NULL_TREE, gfor, NULL_TREE);
13259 g = gimple_build_omp_task (g, task_clauses, NULL_TREE, NULL_TREE,
13260 NULL_TREE, NULL_TREE, NULL_TREE);
13261 gimple_omp_task_set_taskloop_p (g, true);
13262 g = gimple_build_bind (NULL_TREE, g, NULL_TREE);
13263 gomp_for *gforo
13264 = gimple_build_omp_for (g, GF_OMP_FOR_KIND_TASKLOOP, outer_for_clauses,
13265 gimple_omp_for_collapse (gfor),
13266 gimple_omp_for_pre_body (gfor));
13267 gimple_omp_for_set_pre_body (gfor, NULL);
13268 gimple_omp_for_set_combined_p (gforo, true);
13269 gimple_omp_for_set_combined_into_p (gfor, true);
13270 for (i = 0; i < (int) gimple_omp_for_collapse (gfor); i++)
13272 tree type = TREE_TYPE (gimple_omp_for_index (gfor, i));
13273 tree v = create_tmp_var (type);
13274 gimple_omp_for_set_index (gforo, i, v);
13275 t = unshare_expr (gimple_omp_for_initial (gfor, i));
13276 gimple_omp_for_set_initial (gforo, i, t);
13277 gimple_omp_for_set_cond (gforo, i,
13278 gimple_omp_for_cond (gfor, i));
13279 t = unshare_expr (gimple_omp_for_final (gfor, i));
13280 gimple_omp_for_set_final (gforo, i, t);
13281 t = unshare_expr (gimple_omp_for_incr (gfor, i));
13282 gcc_assert (TREE_OPERAND (t, 0) == gimple_omp_for_index (gfor, i));
13283 TREE_OPERAND (t, 0) = v;
13284 gimple_omp_for_set_incr (gforo, i, t);
13285 t = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
13286 OMP_CLAUSE_DECL (t) = v;
13287 OMP_CLAUSE_CHAIN (t) = gimple_omp_for_clauses (gforo);
13288 gimple_omp_for_set_clauses (gforo, t);
13289 if (OMP_FOR_NON_RECTANGULAR (for_stmt))
13291 tree *p1 = NULL, *p2 = NULL;
13292 t = gimple_omp_for_initial (gforo, i);
13293 if (TREE_CODE (t) == TREE_VEC)
13294 p1 = &TREE_VEC_ELT (t, 0);
13295 t = gimple_omp_for_final (gforo, i);
13296 if (TREE_CODE (t) == TREE_VEC)
13298 if (p1)
13299 p2 = &TREE_VEC_ELT (t, 0);
13300 else
13301 p1 = &TREE_VEC_ELT (t, 0);
13303 if (p1)
13305 int j;
13306 for (j = 0; j < i; j++)
13307 if (*p1 == gimple_omp_for_index (gfor, j))
13309 *p1 = gimple_omp_for_index (gforo, j);
13310 if (p2)
13311 *p2 = *p1;
13312 break;
13314 gcc_assert (j < i);
13318 gimplify_seq_add_stmt (pre_p, gforo);
13320 else
13321 gimplify_seq_add_stmt (pre_p, gfor);
13323 if (TREE_CODE (orig_for_stmt) == OMP_FOR)
13325 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
13326 unsigned lastprivate_conditional = 0;
13327 while (ctx
13328 && (ctx->region_type == ORT_TARGET_DATA
13329 || ctx->region_type == ORT_TASKGROUP))
13330 ctx = ctx->outer_context;
13331 if (ctx && (ctx->region_type & ORT_PARALLEL) != 0)
13332 for (tree c = gimple_omp_for_clauses (gfor);
13333 c; c = OMP_CLAUSE_CHAIN (c))
13334 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
13335 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
13336 ++lastprivate_conditional;
13337 if (lastprivate_conditional)
13339 struct omp_for_data fd;
13340 omp_extract_for_data (gfor, &fd, NULL);
13341 tree type = build_array_type_nelts (unsigned_type_for (fd.iter_type),
13342 lastprivate_conditional);
13343 tree var = create_tmp_var_raw (type);
13344 tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__CONDTEMP_);
13345 OMP_CLAUSE_DECL (c) = var;
13346 OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor);
13347 gimple_omp_for_set_clauses (gfor, c);
13348 omp_add_variable (ctx, var, GOVD_CONDTEMP | GOVD_SEEN);
13351 else if (TREE_CODE (orig_for_stmt) == OMP_SIMD)
13353 unsigned lastprivate_conditional = 0;
13354 for (tree c = gimple_omp_for_clauses (gfor); c; c = OMP_CLAUSE_CHAIN (c))
13355 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
13356 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
13357 ++lastprivate_conditional;
13358 if (lastprivate_conditional)
13360 struct omp_for_data fd;
13361 omp_extract_for_data (gfor, &fd, NULL);
13362 tree type = unsigned_type_for (fd.iter_type);
13363 while (lastprivate_conditional--)
13365 tree c = build_omp_clause (UNKNOWN_LOCATION,
13366 OMP_CLAUSE__CONDTEMP_);
13367 OMP_CLAUSE_DECL (c) = create_tmp_var (type);
13368 OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor);
13369 gimple_omp_for_set_clauses (gfor, c);
13374 if (ret != GS_ALL_DONE)
13375 return GS_ERROR;
13376 *expr_p = NULL_TREE;
13377 return GS_ALL_DONE;
13380 /* Helper for gimplify_omp_loop, called through walk_tree. */
13382 static tree
13383 note_no_context_vars (tree *tp, int *, void *data)
13385 if (VAR_P (*tp)
13386 && DECL_CONTEXT (*tp) == NULL_TREE
13387 && !is_global_var (*tp))
13389 vec<tree> *d = (vec<tree> *) data;
13390 d->safe_push (*tp);
13391 DECL_CONTEXT (*tp) = current_function_decl;
13393 return NULL_TREE;
13396 /* Gimplify the gross structure of an OMP_LOOP statement. */
13398 static enum gimplify_status
13399 gimplify_omp_loop (tree *expr_p, gimple_seq *pre_p)
13401 tree for_stmt = *expr_p;
13402 tree clauses = OMP_FOR_CLAUSES (for_stmt);
13403 struct gimplify_omp_ctx *octx = gimplify_omp_ctxp;
13404 enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
13405 int i;
13407 /* If order is not present, the behavior is as if order(concurrent)
13408 appeared. */
13409 tree order = omp_find_clause (clauses, OMP_CLAUSE_ORDER);
13410 if (order == NULL_TREE)
13412 order = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_ORDER);
13413 OMP_CLAUSE_CHAIN (order) = clauses;
13414 OMP_FOR_CLAUSES (for_stmt) = clauses = order;
13417 tree bind = omp_find_clause (clauses, OMP_CLAUSE_BIND);
13418 if (bind == NULL_TREE)
13420 if (!flag_openmp) /* flag_openmp_simd */
13422 else if (octx && (octx->region_type & ORT_TEAMS) != 0)
13423 kind = OMP_CLAUSE_BIND_TEAMS;
13424 else if (octx && (octx->region_type & ORT_PARALLEL) != 0)
13425 kind = OMP_CLAUSE_BIND_PARALLEL;
13426 else
13428 for (; octx; octx = octx->outer_context)
13430 if ((octx->region_type & ORT_ACC) != 0
13431 || octx->region_type == ORT_NONE
13432 || octx->region_type == ORT_IMPLICIT_TARGET)
13433 continue;
13434 break;
13436 if (octx == NULL && !in_omp_construct)
13437 error_at (EXPR_LOCATION (for_stmt),
13438 "%<bind%> clause not specified on a %<loop%> "
13439 "construct not nested inside another OpenMP construct");
13441 bind = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_BIND);
13442 OMP_CLAUSE_CHAIN (bind) = clauses;
13443 OMP_CLAUSE_BIND_KIND (bind) = kind;
13444 OMP_FOR_CLAUSES (for_stmt) = bind;
13446 else
13447 switch (OMP_CLAUSE_BIND_KIND (bind))
13449 case OMP_CLAUSE_BIND_THREAD:
13450 break;
13451 case OMP_CLAUSE_BIND_PARALLEL:
13452 if (!flag_openmp) /* flag_openmp_simd */
13454 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
13455 break;
13457 for (; octx; octx = octx->outer_context)
13458 if (octx->region_type == ORT_SIMD
13459 && omp_find_clause (octx->clauses, OMP_CLAUSE_BIND) == NULL_TREE)
13461 error_at (EXPR_LOCATION (for_stmt),
13462 "%<bind(parallel)%> on a %<loop%> construct nested "
13463 "inside %<simd%> construct");
13464 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
13465 break;
13467 kind = OMP_CLAUSE_BIND_PARALLEL;
13468 break;
13469 case OMP_CLAUSE_BIND_TEAMS:
13470 if (!flag_openmp) /* flag_openmp_simd */
13472 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
13473 break;
13475 if ((octx
13476 && octx->region_type != ORT_IMPLICIT_TARGET
13477 && octx->region_type != ORT_NONE
13478 && (octx->region_type & ORT_TEAMS) == 0)
13479 || in_omp_construct)
13481 error_at (EXPR_LOCATION (for_stmt),
13482 "%<bind(teams)%> on a %<loop%> region not strictly "
13483 "nested inside of a %<teams%> region");
13484 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
13485 break;
13487 kind = OMP_CLAUSE_BIND_TEAMS;
13488 break;
13489 default:
13490 gcc_unreachable ();
13493 for (tree *pc = &OMP_FOR_CLAUSES (for_stmt); *pc; )
13494 switch (OMP_CLAUSE_CODE (*pc))
13496 case OMP_CLAUSE_REDUCTION:
13497 if (OMP_CLAUSE_REDUCTION_INSCAN (*pc))
13499 error_at (OMP_CLAUSE_LOCATION (*pc),
13500 "%<inscan%> %<reduction%> clause on "
13501 "%qs construct", "loop");
13502 OMP_CLAUSE_REDUCTION_INSCAN (*pc) = 0;
13504 if (OMP_CLAUSE_REDUCTION_TASK (*pc))
13506 error_at (OMP_CLAUSE_LOCATION (*pc),
13507 "invalid %<task%> reduction modifier on construct "
13508 "other than %<parallel%>, %qs or %<sections%>",
13509 lang_GNU_Fortran () ? "do" : "for");
13510 OMP_CLAUSE_REDUCTION_TASK (*pc) = 0;
13512 pc = &OMP_CLAUSE_CHAIN (*pc);
13513 break;
13514 case OMP_CLAUSE_LASTPRIVATE:
13515 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
13517 tree t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
13518 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
13519 if (OMP_CLAUSE_DECL (*pc) == TREE_OPERAND (t, 0))
13520 break;
13521 if (OMP_FOR_ORIG_DECLS (for_stmt)
13522 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt),
13523 i)) == TREE_LIST
13524 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt),
13525 i)))
13527 tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
13528 if (OMP_CLAUSE_DECL (*pc) == TREE_PURPOSE (orig))
13529 break;
13532 if (i == TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)))
13534 error_at (OMP_CLAUSE_LOCATION (*pc),
13535 "%<lastprivate%> clause on a %<loop%> construct refers "
13536 "to a variable %qD which is not the loop iterator",
13537 OMP_CLAUSE_DECL (*pc));
13538 *pc = OMP_CLAUSE_CHAIN (*pc);
13539 break;
13541 pc = &OMP_CLAUSE_CHAIN (*pc);
13542 break;
13543 default:
13544 pc = &OMP_CLAUSE_CHAIN (*pc);
13545 break;
13548 TREE_SET_CODE (for_stmt, OMP_SIMD);
13550 int last;
13551 switch (kind)
13553 case OMP_CLAUSE_BIND_THREAD: last = 0; break;
13554 case OMP_CLAUSE_BIND_PARALLEL: last = 1; break;
13555 case OMP_CLAUSE_BIND_TEAMS: last = 2; break;
13557 for (int pass = 1; pass <= last; pass++)
13559 if (pass == 2)
13561 tree bind = build3 (BIND_EXPR, void_type_node, NULL, NULL,
13562 make_node (BLOCK));
13563 append_to_statement_list (*expr_p, &BIND_EXPR_BODY (bind));
13564 *expr_p = make_node (OMP_PARALLEL);
13565 TREE_TYPE (*expr_p) = void_type_node;
13566 OMP_PARALLEL_BODY (*expr_p) = bind;
13567 OMP_PARALLEL_COMBINED (*expr_p) = 1;
13568 SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (for_stmt));
13569 tree *pc = &OMP_PARALLEL_CLAUSES (*expr_p);
13570 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
13571 if (OMP_FOR_ORIG_DECLS (for_stmt)
13572 && (TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i))
13573 == TREE_LIST))
13575 tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
13576 if (TREE_PURPOSE (elt) && TREE_VALUE (elt))
13578 *pc = build_omp_clause (UNKNOWN_LOCATION,
13579 OMP_CLAUSE_FIRSTPRIVATE);
13580 OMP_CLAUSE_DECL (*pc) = TREE_VALUE (elt);
13581 pc = &OMP_CLAUSE_CHAIN (*pc);
13585 tree t = make_node (pass == 2 ? OMP_DISTRIBUTE : OMP_FOR);
13586 tree *pc = &OMP_FOR_CLAUSES (t);
13587 TREE_TYPE (t) = void_type_node;
13588 OMP_FOR_BODY (t) = *expr_p;
13589 SET_EXPR_LOCATION (t, EXPR_LOCATION (for_stmt));
13590 for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
13591 switch (OMP_CLAUSE_CODE (c))
13593 case OMP_CLAUSE_BIND:
13594 case OMP_CLAUSE_ORDER:
13595 case OMP_CLAUSE_COLLAPSE:
13596 *pc = copy_node (c);
13597 pc = &OMP_CLAUSE_CHAIN (*pc);
13598 break;
13599 case OMP_CLAUSE_PRIVATE:
13600 case OMP_CLAUSE_FIRSTPRIVATE:
13601 /* Only needed on innermost. */
13602 break;
13603 case OMP_CLAUSE_LASTPRIVATE:
13604 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c) && pass != last)
13606 *pc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
13607 OMP_CLAUSE_FIRSTPRIVATE);
13608 OMP_CLAUSE_DECL (*pc) = OMP_CLAUSE_DECL (c);
13609 lang_hooks.decls.omp_finish_clause (*pc, NULL, false);
13610 pc = &OMP_CLAUSE_CHAIN (*pc);
13612 *pc = copy_node (c);
13613 OMP_CLAUSE_LASTPRIVATE_STMT (*pc) = NULL_TREE;
13614 TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
13615 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
13617 if (pass != last)
13618 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (*pc) = 1;
13619 else
13620 lang_hooks.decls.omp_finish_clause (*pc, NULL, false);
13621 OMP_CLAUSE_LASTPRIVATE_LOOP_IV (*pc) = 0;
13623 pc = &OMP_CLAUSE_CHAIN (*pc);
13624 break;
13625 case OMP_CLAUSE_REDUCTION:
13626 *pc = copy_node (c);
13627 OMP_CLAUSE_DECL (*pc) = unshare_expr (OMP_CLAUSE_DECL (c));
13628 TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
13629 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc))
13631 auto_vec<tree> no_context_vars;
13632 int walk_subtrees = 0;
13633 note_no_context_vars (&OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
13634 &walk_subtrees, &no_context_vars);
13635 if (tree p = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c))
13636 note_no_context_vars (&p, &walk_subtrees, &no_context_vars);
13637 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_INIT (c),
13638 note_no_context_vars,
13639 &no_context_vars);
13640 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_MERGE (c),
13641 note_no_context_vars,
13642 &no_context_vars);
13644 OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc)
13645 = copy_node (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c));
13646 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc))
13647 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc)
13648 = copy_node (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c));
13650 hash_map<tree, tree> decl_map;
13651 decl_map.put (OMP_CLAUSE_DECL (c), OMP_CLAUSE_DECL (c));
13652 decl_map.put (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
13653 OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc));
13654 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc))
13655 decl_map.put (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
13656 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc));
13658 copy_body_data id;
13659 memset (&id, 0, sizeof (id));
13660 id.src_fn = current_function_decl;
13661 id.dst_fn = current_function_decl;
13662 id.src_cfun = cfun;
13663 id.decl_map = &decl_map;
13664 id.copy_decl = copy_decl_no_change;
13665 id.transform_call_graph_edges = CB_CGE_DUPLICATE;
13666 id.transform_new_cfg = true;
13667 id.transform_return_to_modify = false;
13668 id.eh_lp_nr = 0;
13669 walk_tree (&OMP_CLAUSE_REDUCTION_INIT (*pc), copy_tree_body_r,
13670 &id, NULL);
13671 walk_tree (&OMP_CLAUSE_REDUCTION_MERGE (*pc), copy_tree_body_r,
13672 &id, NULL);
13674 for (tree d : no_context_vars)
13676 DECL_CONTEXT (d) = NULL_TREE;
13677 DECL_CONTEXT (*decl_map.get (d)) = NULL_TREE;
13680 else
13682 OMP_CLAUSE_REDUCTION_INIT (*pc)
13683 = unshare_expr (OMP_CLAUSE_REDUCTION_INIT (c));
13684 OMP_CLAUSE_REDUCTION_MERGE (*pc)
13685 = unshare_expr (OMP_CLAUSE_REDUCTION_MERGE (c));
13687 pc = &OMP_CLAUSE_CHAIN (*pc);
13688 break;
13689 default:
13690 gcc_unreachable ();
13692 *pc = NULL_TREE;
13693 *expr_p = t;
13695 return gimplify_omp_for (expr_p, pre_p);
13699 /* Helper function of optimize_target_teams, find OMP_TEAMS inside
13700 of OMP_TARGET's body. */
13702 static tree
13703 find_omp_teams (tree *tp, int *walk_subtrees, void *)
13705 *walk_subtrees = 0;
13706 switch (TREE_CODE (*tp))
13708 case OMP_TEAMS:
13709 return *tp;
13710 case BIND_EXPR:
13711 case STATEMENT_LIST:
13712 *walk_subtrees = 1;
13713 break;
13714 default:
13715 break;
13717 return NULL_TREE;
13720 /* Helper function of optimize_target_teams, determine if the expression
13721 can be computed safely before the target construct on the host. */
13723 static tree
13724 computable_teams_clause (tree *tp, int *walk_subtrees, void *)
13726 splay_tree_node n;
13728 if (TYPE_P (*tp))
13730 *walk_subtrees = 0;
13731 return NULL_TREE;
13733 switch (TREE_CODE (*tp))
13735 case VAR_DECL:
13736 case PARM_DECL:
13737 case RESULT_DECL:
13738 *walk_subtrees = 0;
13739 if (error_operand_p (*tp)
13740 || !INTEGRAL_TYPE_P (TREE_TYPE (*tp))
13741 || DECL_HAS_VALUE_EXPR_P (*tp)
13742 || DECL_THREAD_LOCAL_P (*tp)
13743 || TREE_SIDE_EFFECTS (*tp)
13744 || TREE_THIS_VOLATILE (*tp))
13745 return *tp;
13746 if (is_global_var (*tp)
13747 && (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (*tp))
13748 || lookup_attribute ("omp declare target link",
13749 DECL_ATTRIBUTES (*tp))))
13750 return *tp;
13751 if (VAR_P (*tp)
13752 && !DECL_SEEN_IN_BIND_EXPR_P (*tp)
13753 && !is_global_var (*tp)
13754 && decl_function_context (*tp) == current_function_decl)
13755 return *tp;
13756 n = splay_tree_lookup (gimplify_omp_ctxp->variables,
13757 (splay_tree_key) *tp);
13758 if (n == NULL)
13760 if (gimplify_omp_ctxp->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE)
13761 return NULL_TREE;
13762 return *tp;
13764 else if (n->value & GOVD_LOCAL)
13765 return *tp;
13766 else if (n->value & GOVD_FIRSTPRIVATE)
13767 return NULL_TREE;
13768 else if ((n->value & (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
13769 == (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
13770 return NULL_TREE;
13771 return *tp;
13772 case INTEGER_CST:
13773 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
13774 return *tp;
13775 return NULL_TREE;
13776 case TARGET_EXPR:
13777 if (TARGET_EXPR_INITIAL (*tp)
13778 || TREE_CODE (TARGET_EXPR_SLOT (*tp)) != VAR_DECL)
13779 return *tp;
13780 return computable_teams_clause (&TARGET_EXPR_SLOT (*tp),
13781 walk_subtrees, NULL);
13782 /* Allow some reasonable subset of integral arithmetics. */
13783 case PLUS_EXPR:
13784 case MINUS_EXPR:
13785 case MULT_EXPR:
13786 case TRUNC_DIV_EXPR:
13787 case CEIL_DIV_EXPR:
13788 case FLOOR_DIV_EXPR:
13789 case ROUND_DIV_EXPR:
13790 case TRUNC_MOD_EXPR:
13791 case CEIL_MOD_EXPR:
13792 case FLOOR_MOD_EXPR:
13793 case ROUND_MOD_EXPR:
13794 case RDIV_EXPR:
13795 case EXACT_DIV_EXPR:
13796 case MIN_EXPR:
13797 case MAX_EXPR:
13798 case LSHIFT_EXPR:
13799 case RSHIFT_EXPR:
13800 case BIT_IOR_EXPR:
13801 case BIT_XOR_EXPR:
13802 case BIT_AND_EXPR:
13803 case NEGATE_EXPR:
13804 case ABS_EXPR:
13805 case BIT_NOT_EXPR:
13806 case NON_LVALUE_EXPR:
13807 CASE_CONVERT:
13808 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
13809 return *tp;
13810 return NULL_TREE;
13811 /* And disallow anything else, except for comparisons. */
13812 default:
13813 if (COMPARISON_CLASS_P (*tp))
13814 return NULL_TREE;
13815 return *tp;
13819 /* Try to determine if the num_teams and/or thread_limit expressions
13820 can have their values determined already before entering the
13821 target construct.
13822 INTEGER_CSTs trivially are,
13823 integral decls that are firstprivate (explicitly or implicitly)
13824 or explicitly map(always, to:) or map(always, tofrom:) on the target
13825 region too, and expressions involving simple arithmetics on those
13826 too, function calls are not ok, dereferencing something neither etc.
13827 Add NUM_TEAMS and THREAD_LIMIT clauses to the OMP_CLAUSES of
13828 EXPR based on what we find:
13829 0 stands for clause not specified at all, use implementation default
13830 -1 stands for value that can't be determined easily before entering
13831 the target construct.
13832 If teams construct is not present at all, use 1 for num_teams
13833 and 0 for thread_limit (only one team is involved, and the thread
13834 limit is implementation defined. */
13836 static void
13837 optimize_target_teams (tree target, gimple_seq *pre_p)
13839 tree body = OMP_BODY (target);
13840 tree teams = walk_tree (&body, find_omp_teams, NULL, NULL);
13841 tree num_teams_lower = NULL_TREE;
13842 tree num_teams_upper = integer_zero_node;
13843 tree thread_limit = integer_zero_node;
13844 location_t num_teams_loc = EXPR_LOCATION (target);
13845 location_t thread_limit_loc = EXPR_LOCATION (target);
13846 tree c, *p, expr;
13847 struct gimplify_omp_ctx *target_ctx = gimplify_omp_ctxp;
13849 if (teams == NULL_TREE)
13850 num_teams_upper = integer_one_node;
13851 else
13852 for (c = OMP_TEAMS_CLAUSES (teams); c; c = OMP_CLAUSE_CHAIN (c))
13854 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS)
13856 p = &num_teams_upper;
13857 num_teams_loc = OMP_CLAUSE_LOCATION (c);
13858 if (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c))
13860 expr = OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c);
13861 if (TREE_CODE (expr) == INTEGER_CST)
13862 num_teams_lower = expr;
13863 else if (walk_tree (&expr, computable_teams_clause,
13864 NULL, NULL))
13865 num_teams_lower = integer_minus_one_node;
13866 else
13868 num_teams_lower = expr;
13869 gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
13870 if (gimplify_expr (&num_teams_lower, pre_p, NULL,
13871 is_gimple_val, fb_rvalue, false)
13872 == GS_ERROR)
13874 gimplify_omp_ctxp = target_ctx;
13875 num_teams_lower = integer_minus_one_node;
13877 else
13879 gimplify_omp_ctxp = target_ctx;
13880 if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR)
13881 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
13882 = num_teams_lower;
13887 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
13889 p = &thread_limit;
13890 thread_limit_loc = OMP_CLAUSE_LOCATION (c);
13892 else
13893 continue;
13894 expr = OMP_CLAUSE_OPERAND (c, 0);
13895 if (TREE_CODE (expr) == INTEGER_CST)
13897 *p = expr;
13898 continue;
13900 if (walk_tree (&expr, computable_teams_clause, NULL, NULL))
13902 *p = integer_minus_one_node;
13903 continue;
13905 *p = expr;
13906 gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
13907 if (gimplify_expr (p, pre_p, NULL, is_gimple_val, fb_rvalue, false)
13908 == GS_ERROR)
13910 gimplify_omp_ctxp = target_ctx;
13911 *p = integer_minus_one_node;
13912 continue;
13914 gimplify_omp_ctxp = target_ctx;
13915 if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR)
13916 OMP_CLAUSE_OPERAND (c, 0) = *p;
13918 if (!omp_find_clause (OMP_TARGET_CLAUSES (target), OMP_CLAUSE_THREAD_LIMIT))
13920 c = build_omp_clause (thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
13921 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = thread_limit;
13922 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
13923 OMP_TARGET_CLAUSES (target) = c;
13925 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
13926 OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c) = num_teams_upper;
13927 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) = num_teams_lower;
13928 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
13929 OMP_TARGET_CLAUSES (target) = c;
13932 /* Gimplify the gross structure of several OMP constructs. */
13934 static void
13935 gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
13937 tree expr = *expr_p;
13938 gimple *stmt;
13939 gimple_seq body = NULL;
13940 enum omp_region_type ort;
13942 switch (TREE_CODE (expr))
13944 case OMP_SECTIONS:
13945 case OMP_SINGLE:
13946 ort = ORT_WORKSHARE;
13947 break;
13948 case OMP_SCOPE:
13949 ort = ORT_TASKGROUP;
13950 break;
13951 case OMP_TARGET:
13952 ort = OMP_TARGET_COMBINED (expr) ? ORT_COMBINED_TARGET : ORT_TARGET;
13953 break;
13954 case OACC_KERNELS:
13955 ort = ORT_ACC_KERNELS;
13956 break;
13957 case OACC_PARALLEL:
13958 ort = ORT_ACC_PARALLEL;
13959 break;
13960 case OACC_SERIAL:
13961 ort = ORT_ACC_SERIAL;
13962 break;
13963 case OACC_DATA:
13964 ort = ORT_ACC_DATA;
13965 break;
13966 case OMP_TARGET_DATA:
13967 ort = ORT_TARGET_DATA;
13968 break;
13969 case OMP_TEAMS:
13970 ort = OMP_TEAMS_COMBINED (expr) ? ORT_COMBINED_TEAMS : ORT_TEAMS;
13971 if (gimplify_omp_ctxp == NULL
13972 || gimplify_omp_ctxp->region_type == ORT_IMPLICIT_TARGET)
13973 ort = (enum omp_region_type) (ort | ORT_HOST_TEAMS);
13974 break;
13975 case OACC_HOST_DATA:
13976 ort = ORT_ACC_HOST_DATA;
13977 break;
13978 default:
13979 gcc_unreachable ();
13982 bool save_in_omp_construct = in_omp_construct;
13983 if ((ort & ORT_ACC) == 0)
13984 in_omp_construct = false;
13985 gimplify_scan_omp_clauses (&OMP_CLAUSES (expr), pre_p, ort,
13986 TREE_CODE (expr));
13987 if (TREE_CODE (expr) == OMP_TARGET)
13988 optimize_target_teams (expr, pre_p);
13989 if ((ort & (ORT_TARGET | ORT_TARGET_DATA)) != 0
13990 || (ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
13992 push_gimplify_context ();
13993 gimple *g = gimplify_and_return_first (OMP_BODY (expr), &body);
13994 if (gimple_code (g) == GIMPLE_BIND)
13995 pop_gimplify_context (g);
13996 else
13997 pop_gimplify_context (NULL);
13998 if ((ort & ORT_TARGET_DATA) != 0)
14000 enum built_in_function end_ix;
14001 switch (TREE_CODE (expr))
14003 case OACC_DATA:
14004 case OACC_HOST_DATA:
14005 end_ix = BUILT_IN_GOACC_DATA_END;
14006 break;
14007 case OMP_TARGET_DATA:
14008 end_ix = BUILT_IN_GOMP_TARGET_END_DATA;
14009 break;
14010 default:
14011 gcc_unreachable ();
14013 tree fn = builtin_decl_explicit (end_ix);
14014 g = gimple_build_call (fn, 0);
14015 gimple_seq cleanup = NULL;
14016 gimple_seq_add_stmt (&cleanup, g);
14017 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
14018 body = NULL;
14019 gimple_seq_add_stmt (&body, g);
14022 else
14023 gimplify_and_add (OMP_BODY (expr), &body);
14024 gimplify_adjust_omp_clauses (pre_p, body, &OMP_CLAUSES (expr),
14025 TREE_CODE (expr));
14026 in_omp_construct = save_in_omp_construct;
14028 switch (TREE_CODE (expr))
14030 case OACC_DATA:
14031 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_DATA,
14032 OMP_CLAUSES (expr));
14033 break;
14034 case OACC_HOST_DATA:
14035 if (omp_find_clause (OMP_CLAUSES (expr), OMP_CLAUSE_IF_PRESENT))
14037 for (tree c = OMP_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
14038 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_PTR)
14039 OMP_CLAUSE_USE_DEVICE_PTR_IF_PRESENT (c) = 1;
14042 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_HOST_DATA,
14043 OMP_CLAUSES (expr));
14044 break;
14045 case OACC_KERNELS:
14046 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_KERNELS,
14047 OMP_CLAUSES (expr));
14048 break;
14049 case OACC_PARALLEL:
14050 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_PARALLEL,
14051 OMP_CLAUSES (expr));
14052 break;
14053 case OACC_SERIAL:
14054 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_SERIAL,
14055 OMP_CLAUSES (expr));
14056 break;
14057 case OMP_SECTIONS:
14058 stmt = gimple_build_omp_sections (body, OMP_CLAUSES (expr));
14059 break;
14060 case OMP_SINGLE:
14061 stmt = gimple_build_omp_single (body, OMP_CLAUSES (expr));
14062 break;
14063 case OMP_SCOPE:
14064 stmt = gimple_build_omp_scope (body, OMP_CLAUSES (expr));
14065 break;
14066 case OMP_TARGET:
14067 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_REGION,
14068 OMP_CLAUSES (expr));
14069 break;
14070 case OMP_TARGET_DATA:
14071 /* Put use_device_{ptr,addr} clauses last, as map clauses are supposed
14072 to be evaluated before the use_device_{ptr,addr} clauses if they
14073 refer to the same variables. */
14075 tree use_device_clauses;
14076 tree *pc, *uc = &use_device_clauses;
14077 for (pc = &OMP_CLAUSES (expr); *pc; )
14078 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
14079 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
14081 *uc = *pc;
14082 *pc = OMP_CLAUSE_CHAIN (*pc);
14083 uc = &OMP_CLAUSE_CHAIN (*uc);
14085 else
14086 pc = &OMP_CLAUSE_CHAIN (*pc);
14087 *uc = NULL_TREE;
14088 *pc = use_device_clauses;
14089 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_DATA,
14090 OMP_CLAUSES (expr));
14092 break;
14093 case OMP_TEAMS:
14094 stmt = gimple_build_omp_teams (body, OMP_CLAUSES (expr));
14095 if ((ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
14096 gimple_omp_teams_set_host (as_a <gomp_teams *> (stmt), true);
14097 break;
14098 default:
14099 gcc_unreachable ();
14102 gimplify_seq_add_stmt (pre_p, stmt);
14103 *expr_p = NULL_TREE;
14106 /* Gimplify the gross structure of OpenACC enter/exit data, update, and OpenMP
14107 target update constructs. */
14109 static void
14110 gimplify_omp_target_update (tree *expr_p, gimple_seq *pre_p)
14112 tree expr = *expr_p;
14113 int kind;
14114 gomp_target *stmt;
14115 enum omp_region_type ort = ORT_WORKSHARE;
14117 switch (TREE_CODE (expr))
14119 case OACC_ENTER_DATA:
14120 kind = GF_OMP_TARGET_KIND_OACC_ENTER_DATA;
14121 ort = ORT_ACC;
14122 break;
14123 case OACC_EXIT_DATA:
14124 kind = GF_OMP_TARGET_KIND_OACC_EXIT_DATA;
14125 ort = ORT_ACC;
14126 break;
14127 case OACC_UPDATE:
14128 kind = GF_OMP_TARGET_KIND_OACC_UPDATE;
14129 ort = ORT_ACC;
14130 break;
14131 case OMP_TARGET_UPDATE:
14132 kind = GF_OMP_TARGET_KIND_UPDATE;
14133 break;
14134 case OMP_TARGET_ENTER_DATA:
14135 kind = GF_OMP_TARGET_KIND_ENTER_DATA;
14136 break;
14137 case OMP_TARGET_EXIT_DATA:
14138 kind = GF_OMP_TARGET_KIND_EXIT_DATA;
14139 break;
14140 default:
14141 gcc_unreachable ();
14143 gimplify_scan_omp_clauses (&OMP_STANDALONE_CLAUSES (expr), pre_p,
14144 ort, TREE_CODE (expr));
14145 gimplify_adjust_omp_clauses (pre_p, NULL, &OMP_STANDALONE_CLAUSES (expr),
14146 TREE_CODE (expr));
14147 if (TREE_CODE (expr) == OACC_UPDATE
14148 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
14149 OMP_CLAUSE_IF_PRESENT))
14151 /* The runtime uses GOMP_MAP_{TO,FROM} to denote the if_present
14152 clause. */
14153 for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
14154 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
14155 switch (OMP_CLAUSE_MAP_KIND (c))
14157 case GOMP_MAP_FORCE_TO:
14158 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TO);
14159 break;
14160 case GOMP_MAP_FORCE_FROM:
14161 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FROM);
14162 break;
14163 default:
14164 break;
14167 else if (TREE_CODE (expr) == OACC_EXIT_DATA
14168 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
14169 OMP_CLAUSE_FINALIZE))
14171 /* Use GOMP_MAP_DELETE/GOMP_MAP_FORCE_FROM to denote "finalize"
14172 semantics. */
14173 bool have_clause = false;
14174 for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
14175 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
14176 switch (OMP_CLAUSE_MAP_KIND (c))
14178 case GOMP_MAP_FROM:
14179 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_FROM);
14180 have_clause = true;
14181 break;
14182 case GOMP_MAP_RELEASE:
14183 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_DELETE);
14184 have_clause = true;
14185 break;
14186 case GOMP_MAP_TO_PSET:
14187 /* Fortran arrays with descriptors must map that descriptor when
14188 doing standalone "attach" operations (in OpenACC). In that
14189 case GOMP_MAP_TO_PSET appears by itself with no preceding
14190 clause (see trans-openmp.c:gfc_trans_omp_clauses). */
14191 break;
14192 case GOMP_MAP_POINTER:
14193 /* TODO PR92929: we may see these here, but they'll always follow
14194 one of the clauses above, and will be handled by libgomp as
14195 one group, so no handling required here. */
14196 gcc_assert (have_clause);
14197 break;
14198 case GOMP_MAP_DETACH:
14199 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_DETACH);
14200 have_clause = false;
14201 break;
14202 case GOMP_MAP_STRUCT:
14203 have_clause = false;
14204 break;
14205 default:
14206 gcc_unreachable ();
14209 stmt = gimple_build_omp_target (NULL, kind, OMP_STANDALONE_CLAUSES (expr));
14211 gimplify_seq_add_stmt (pre_p, stmt);
14212 *expr_p = NULL_TREE;
14215 /* A subroutine of gimplify_omp_atomic. The front end is supposed to have
14216 stabilized the lhs of the atomic operation as *ADDR. Return true if
14217 EXPR is this stabilized form. */
14219 static bool
14220 goa_lhs_expr_p (tree expr, tree addr)
14222 /* Also include casts to other type variants. The C front end is fond
14223 of adding these for e.g. volatile variables. This is like
14224 STRIP_TYPE_NOPS but includes the main variant lookup. */
14225 STRIP_USELESS_TYPE_CONVERSION (expr);
14227 if (TREE_CODE (expr) == INDIRECT_REF)
14229 expr = TREE_OPERAND (expr, 0);
14230 while (expr != addr
14231 && (CONVERT_EXPR_P (expr)
14232 || TREE_CODE (expr) == NON_LVALUE_EXPR)
14233 && TREE_CODE (expr) == TREE_CODE (addr)
14234 && types_compatible_p (TREE_TYPE (expr), TREE_TYPE (addr)))
14236 expr = TREE_OPERAND (expr, 0);
14237 addr = TREE_OPERAND (addr, 0);
14239 if (expr == addr)
14240 return true;
14241 return (TREE_CODE (addr) == ADDR_EXPR
14242 && TREE_CODE (expr) == ADDR_EXPR
14243 && TREE_OPERAND (addr, 0) == TREE_OPERAND (expr, 0));
14245 if (TREE_CODE (addr) == ADDR_EXPR && expr == TREE_OPERAND (addr, 0))
14246 return true;
14247 return false;
14250 /* Walk *EXPR_P and replace appearances of *LHS_ADDR with LHS_VAR. If an
14251 expression does not involve the lhs, evaluate it into a temporary.
14252 Return 1 if the lhs appeared as a subexpression, 0 if it did not,
14253 or -1 if an error was encountered. */
14255 static int
14256 goa_stabilize_expr (tree *expr_p, gimple_seq *pre_p, tree lhs_addr,
14257 tree lhs_var, tree &target_expr, bool rhs, int depth)
14259 tree expr = *expr_p;
14260 int saw_lhs = 0;
14262 if (goa_lhs_expr_p (expr, lhs_addr))
14264 if (pre_p)
14265 *expr_p = lhs_var;
14266 return 1;
14268 if (is_gimple_val (expr))
14269 return 0;
14271 /* Maximum depth of lhs in expression is for the
14272 __builtin_clear_padding (...), __builtin_clear_padding (...),
14273 __builtin_memcmp (&TARGET_EXPR <lhs, >, ...) == 0 ? ... : lhs; */
14274 if (++depth > 7)
14275 goto finish;
14277 switch (TREE_CODE_CLASS (TREE_CODE (expr)))
14279 case tcc_binary:
14280 case tcc_comparison:
14281 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p, lhs_addr,
14282 lhs_var, target_expr, true, depth);
14283 /* FALLTHRU */
14284 case tcc_unary:
14285 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p, lhs_addr,
14286 lhs_var, target_expr, true, depth);
14287 break;
14288 case tcc_expression:
14289 switch (TREE_CODE (expr))
14291 case TRUTH_ANDIF_EXPR:
14292 case TRUTH_ORIF_EXPR:
14293 case TRUTH_AND_EXPR:
14294 case TRUTH_OR_EXPR:
14295 case TRUTH_XOR_EXPR:
14296 case BIT_INSERT_EXPR:
14297 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
14298 lhs_addr, lhs_var, target_expr, true,
14299 depth);
14300 /* FALLTHRU */
14301 case TRUTH_NOT_EXPR:
14302 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
14303 lhs_addr, lhs_var, target_expr, true,
14304 depth);
14305 break;
14306 case MODIFY_EXPR:
14307 if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr, lhs_var,
14308 target_expr, true, depth))
14309 break;
14310 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
14311 lhs_addr, lhs_var, target_expr, true,
14312 depth);
14313 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
14314 lhs_addr, lhs_var, target_expr, false,
14315 depth);
14316 break;
14317 /* FALLTHRU */
14318 case ADDR_EXPR:
14319 if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr, lhs_var,
14320 target_expr, true, depth))
14321 break;
14322 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
14323 lhs_addr, lhs_var, target_expr, false,
14324 depth);
14325 break;
14326 case COMPOUND_EXPR:
14327 /* Break out any preevaluations from cp_build_modify_expr. */
14328 for (; TREE_CODE (expr) == COMPOUND_EXPR;
14329 expr = TREE_OPERAND (expr, 1))
14331 /* Special-case __builtin_clear_padding call before
14332 __builtin_memcmp. */
14333 if (TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR)
14335 tree fndecl = get_callee_fndecl (TREE_OPERAND (expr, 0));
14336 if (fndecl
14337 && fndecl_built_in_p (fndecl, BUILT_IN_CLEAR_PADDING)
14338 && VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 0)))
14339 && (!pre_p
14340 || goa_stabilize_expr (&TREE_OPERAND (expr, 0), NULL,
14341 lhs_addr, lhs_var,
14342 target_expr, true, depth)))
14344 if (pre_p)
14345 *expr_p = expr;
14346 saw_lhs = goa_stabilize_expr (&TREE_OPERAND (expr, 0),
14347 pre_p, lhs_addr, lhs_var,
14348 target_expr, true, depth);
14349 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1),
14350 pre_p, lhs_addr, lhs_var,
14351 target_expr, rhs, depth);
14352 return saw_lhs;
14356 if (pre_p)
14357 gimplify_stmt (&TREE_OPERAND (expr, 0), pre_p);
14359 if (!pre_p)
14360 return goa_stabilize_expr (&expr, pre_p, lhs_addr, lhs_var,
14361 target_expr, rhs, depth);
14362 *expr_p = expr;
14363 return goa_stabilize_expr (expr_p, pre_p, lhs_addr, lhs_var,
14364 target_expr, rhs, depth);
14365 case COND_EXPR:
14366 if (!goa_stabilize_expr (&TREE_OPERAND (expr, 0), NULL, lhs_addr,
14367 lhs_var, target_expr, true, depth))
14368 break;
14369 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
14370 lhs_addr, lhs_var, target_expr, true,
14371 depth);
14372 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
14373 lhs_addr, lhs_var, target_expr, true,
14374 depth);
14375 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 2), pre_p,
14376 lhs_addr, lhs_var, target_expr, true,
14377 depth);
14378 break;
14379 case TARGET_EXPR:
14380 if (TARGET_EXPR_INITIAL (expr))
14382 if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr,
14383 lhs_var, target_expr, true,
14384 depth))
14385 break;
14386 if (expr == target_expr)
14387 saw_lhs = 1;
14388 else
14390 saw_lhs = goa_stabilize_expr (&TARGET_EXPR_INITIAL (expr),
14391 pre_p, lhs_addr, lhs_var,
14392 target_expr, true, depth);
14393 if (saw_lhs && target_expr == NULL_TREE && pre_p)
14394 target_expr = expr;
14397 break;
14398 default:
14399 break;
14401 break;
14402 case tcc_reference:
14403 if (TREE_CODE (expr) == BIT_FIELD_REF
14404 || TREE_CODE (expr) == VIEW_CONVERT_EXPR)
14405 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
14406 lhs_addr, lhs_var, target_expr, true,
14407 depth);
14408 break;
14409 case tcc_vl_exp:
14410 if (TREE_CODE (expr) == CALL_EXPR)
14412 if (tree fndecl = get_callee_fndecl (expr))
14413 if (fndecl_built_in_p (fndecl, BUILT_IN_CLEAR_PADDING)
14414 || fndecl_built_in_p (fndecl, BUILT_IN_MEMCMP))
14416 int nargs = call_expr_nargs (expr);
14417 for (int i = 0; i < nargs; i++)
14418 saw_lhs |= goa_stabilize_expr (&CALL_EXPR_ARG (expr, i),
14419 pre_p, lhs_addr, lhs_var,
14420 target_expr, true, depth);
14423 break;
14424 default:
14425 break;
14428 finish:
14429 if (saw_lhs == 0 && pre_p)
14431 enum gimplify_status gs;
14432 if (TREE_CODE (expr) == CALL_EXPR && VOID_TYPE_P (TREE_TYPE (expr)))
14434 gimplify_stmt (&expr, pre_p);
14435 return saw_lhs;
14437 else if (rhs)
14438 gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_val, fb_rvalue);
14439 else
14440 gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_lvalue, fb_lvalue);
14441 if (gs != GS_ALL_DONE)
14442 saw_lhs = -1;
14445 return saw_lhs;
14448 /* Gimplify an OMP_ATOMIC statement. */
14450 static enum gimplify_status
14451 gimplify_omp_atomic (tree *expr_p, gimple_seq *pre_p)
14453 tree addr = TREE_OPERAND (*expr_p, 0);
14454 tree rhs = TREE_CODE (*expr_p) == OMP_ATOMIC_READ
14455 ? NULL : TREE_OPERAND (*expr_p, 1);
14456 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
14457 tree tmp_load;
14458 gomp_atomic_load *loadstmt;
14459 gomp_atomic_store *storestmt;
14460 tree target_expr = NULL_TREE;
14462 tmp_load = create_tmp_reg (type);
14463 if (rhs
14464 && goa_stabilize_expr (&rhs, pre_p, addr, tmp_load, target_expr,
14465 true, 0) < 0)
14466 return GS_ERROR;
14468 if (gimplify_expr (&addr, pre_p, NULL, is_gimple_val, fb_rvalue)
14469 != GS_ALL_DONE)
14470 return GS_ERROR;
14472 loadstmt = gimple_build_omp_atomic_load (tmp_load, addr,
14473 OMP_ATOMIC_MEMORY_ORDER (*expr_p));
14474 gimplify_seq_add_stmt (pre_p, loadstmt);
14475 if (rhs)
14477 /* BIT_INSERT_EXPR is not valid for non-integral bitfield
14478 representatives. Use BIT_FIELD_REF on the lhs instead. */
14479 tree rhsarg = rhs;
14480 if (TREE_CODE (rhs) == COND_EXPR)
14481 rhsarg = TREE_OPERAND (rhs, 1);
14482 if (TREE_CODE (rhsarg) == BIT_INSERT_EXPR
14483 && !INTEGRAL_TYPE_P (TREE_TYPE (tmp_load)))
14485 tree bitpos = TREE_OPERAND (rhsarg, 2);
14486 tree op1 = TREE_OPERAND (rhsarg, 1);
14487 tree bitsize;
14488 tree tmp_store = tmp_load;
14489 if (TREE_CODE (*expr_p) == OMP_ATOMIC_CAPTURE_OLD)
14490 tmp_store = get_initialized_tmp_var (tmp_load, pre_p);
14491 if (INTEGRAL_TYPE_P (TREE_TYPE (op1)))
14492 bitsize = bitsize_int (TYPE_PRECISION (TREE_TYPE (op1)));
14493 else
14494 bitsize = TYPE_SIZE (TREE_TYPE (op1));
14495 gcc_assert (TREE_OPERAND (rhsarg, 0) == tmp_load);
14496 tree t = build2_loc (EXPR_LOCATION (rhsarg),
14497 MODIFY_EXPR, void_type_node,
14498 build3_loc (EXPR_LOCATION (rhsarg),
14499 BIT_FIELD_REF, TREE_TYPE (op1),
14500 tmp_store, bitsize, bitpos), op1);
14501 if (TREE_CODE (rhs) == COND_EXPR)
14502 t = build3_loc (EXPR_LOCATION (rhs), COND_EXPR, void_type_node,
14503 TREE_OPERAND (rhs, 0), t, void_node);
14504 gimplify_and_add (t, pre_p);
14505 rhs = tmp_store;
14507 bool save_allow_rhs_cond_expr = gimplify_ctxp->allow_rhs_cond_expr;
14508 if (TREE_CODE (rhs) == COND_EXPR)
14509 gimplify_ctxp->allow_rhs_cond_expr = true;
14510 enum gimplify_status gs = gimplify_expr (&rhs, pre_p, NULL,
14511 is_gimple_val, fb_rvalue);
14512 gimplify_ctxp->allow_rhs_cond_expr = save_allow_rhs_cond_expr;
14513 if (gs != GS_ALL_DONE)
14514 return GS_ERROR;
14517 if (TREE_CODE (*expr_p) == OMP_ATOMIC_READ)
14518 rhs = tmp_load;
14519 storestmt
14520 = gimple_build_omp_atomic_store (rhs, OMP_ATOMIC_MEMORY_ORDER (*expr_p));
14521 if (TREE_CODE (*expr_p) != OMP_ATOMIC_READ && OMP_ATOMIC_WEAK (*expr_p))
14523 gimple_omp_atomic_set_weak (loadstmt);
14524 gimple_omp_atomic_set_weak (storestmt);
14526 gimplify_seq_add_stmt (pre_p, storestmt);
14527 switch (TREE_CODE (*expr_p))
14529 case OMP_ATOMIC_READ:
14530 case OMP_ATOMIC_CAPTURE_OLD:
14531 *expr_p = tmp_load;
14532 gimple_omp_atomic_set_need_value (loadstmt);
14533 break;
14534 case OMP_ATOMIC_CAPTURE_NEW:
14535 *expr_p = rhs;
14536 gimple_omp_atomic_set_need_value (storestmt);
14537 break;
14538 default:
14539 *expr_p = NULL;
14540 break;
14543 return GS_ALL_DONE;
14546 /* Gimplify a TRANSACTION_EXPR. This involves gimplification of the
14547 body, and adding some EH bits. */
14549 static enum gimplify_status
14550 gimplify_transaction (tree *expr_p, gimple_seq *pre_p)
14552 tree expr = *expr_p, temp, tbody = TRANSACTION_EXPR_BODY (expr);
14553 gimple *body_stmt;
14554 gtransaction *trans_stmt;
14555 gimple_seq body = NULL;
14556 int subcode = 0;
14558 /* Wrap the transaction body in a BIND_EXPR so we have a context
14559 where to put decls for OMP. */
14560 if (TREE_CODE (tbody) != BIND_EXPR)
14562 tree bind = build3 (BIND_EXPR, void_type_node, NULL, tbody, NULL);
14563 TREE_SIDE_EFFECTS (bind) = 1;
14564 SET_EXPR_LOCATION (bind, EXPR_LOCATION (tbody));
14565 TRANSACTION_EXPR_BODY (expr) = bind;
14568 push_gimplify_context ();
14569 temp = voidify_wrapper_expr (*expr_p, NULL);
14571 body_stmt = gimplify_and_return_first (TRANSACTION_EXPR_BODY (expr), &body);
14572 pop_gimplify_context (body_stmt);
14574 trans_stmt = gimple_build_transaction (body);
14575 if (TRANSACTION_EXPR_OUTER (expr))
14576 subcode = GTMA_IS_OUTER;
14577 else if (TRANSACTION_EXPR_RELAXED (expr))
14578 subcode = GTMA_IS_RELAXED;
14579 gimple_transaction_set_subcode (trans_stmt, subcode);
14581 gimplify_seq_add_stmt (pre_p, trans_stmt);
14583 if (temp)
14585 *expr_p = temp;
14586 return GS_OK;
14589 *expr_p = NULL_TREE;
14590 return GS_ALL_DONE;
14593 /* Gimplify an OMP_ORDERED construct. EXPR is the tree version. BODY
14594 is the OMP_BODY of the original EXPR (which has already been
14595 gimplified so it's not present in the EXPR).
14597 Return the gimplified GIMPLE_OMP_ORDERED tuple. */
14599 static gimple *
14600 gimplify_omp_ordered (tree expr, gimple_seq body)
14602 tree c, decls;
14603 int failures = 0;
14604 unsigned int i;
14605 tree source_c = NULL_TREE;
14606 tree sink_c = NULL_TREE;
14608 if (gimplify_omp_ctxp)
14610 for (c = OMP_ORDERED_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
14611 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
14612 && gimplify_omp_ctxp->loop_iter_var.is_empty ()
14613 && (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK
14614 || OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE))
14616 error_at (OMP_CLAUSE_LOCATION (c),
14617 "%<ordered%> construct with %<depend%> clause must be "
14618 "closely nested inside a loop with %<ordered%> clause "
14619 "with a parameter");
14620 failures++;
14622 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
14623 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
14625 bool fail = false;
14626 for (decls = OMP_CLAUSE_DECL (c), i = 0;
14627 decls && TREE_CODE (decls) == TREE_LIST;
14628 decls = TREE_CHAIN (decls), ++i)
14629 if (i >= gimplify_omp_ctxp->loop_iter_var.length () / 2)
14630 continue;
14631 else if (TREE_VALUE (decls)
14632 != gimplify_omp_ctxp->loop_iter_var[2 * i])
14634 error_at (OMP_CLAUSE_LOCATION (c),
14635 "variable %qE is not an iteration "
14636 "of outermost loop %d, expected %qE",
14637 TREE_VALUE (decls), i + 1,
14638 gimplify_omp_ctxp->loop_iter_var[2 * i]);
14639 fail = true;
14640 failures++;
14642 else
14643 TREE_VALUE (decls)
14644 = gimplify_omp_ctxp->loop_iter_var[2 * i + 1];
14645 if (!fail && i != gimplify_omp_ctxp->loop_iter_var.length () / 2)
14647 error_at (OMP_CLAUSE_LOCATION (c),
14648 "number of variables in %<depend%> clause with "
14649 "%<sink%> modifier does not match number of "
14650 "iteration variables");
14651 failures++;
14653 sink_c = c;
14655 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
14656 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
14658 if (source_c)
14660 error_at (OMP_CLAUSE_LOCATION (c),
14661 "more than one %<depend%> clause with %<source%> "
14662 "modifier on an %<ordered%> construct");
14663 failures++;
14665 else
14666 source_c = c;
14669 if (source_c && sink_c)
14671 error_at (OMP_CLAUSE_LOCATION (source_c),
14672 "%<depend%> clause with %<source%> modifier specified "
14673 "together with %<depend%> clauses with %<sink%> modifier "
14674 "on the same construct");
14675 failures++;
14678 if (failures)
14679 return gimple_build_nop ();
14680 return gimple_build_omp_ordered (body, OMP_ORDERED_CLAUSES (expr));
14683 /* Convert the GENERIC expression tree *EXPR_P to GIMPLE. If the
14684 expression produces a value to be used as an operand inside a GIMPLE
14685 statement, the value will be stored back in *EXPR_P. This value will
14686 be a tree of class tcc_declaration, tcc_constant, tcc_reference or
14687 an SSA_NAME. The corresponding sequence of GIMPLE statements is
14688 emitted in PRE_P and POST_P.
14690 Additionally, this process may overwrite parts of the input
14691 expression during gimplification. Ideally, it should be
14692 possible to do non-destructive gimplification.
14694 EXPR_P points to the GENERIC expression to convert to GIMPLE. If
14695 the expression needs to evaluate to a value to be used as
14696 an operand in a GIMPLE statement, this value will be stored in
14697 *EXPR_P on exit. This happens when the caller specifies one
14698 of fb_lvalue or fb_rvalue fallback flags.
14700 PRE_P will contain the sequence of GIMPLE statements corresponding
14701 to the evaluation of EXPR and all the side-effects that must
14702 be executed before the main expression. On exit, the last
14703 statement of PRE_P is the core statement being gimplified. For
14704 instance, when gimplifying 'if (++a)' the last statement in
14705 PRE_P will be 'if (t.1)' where t.1 is the result of
14706 pre-incrementing 'a'.
14708 POST_P will contain the sequence of GIMPLE statements corresponding
14709 to the evaluation of all the side-effects that must be executed
14710 after the main expression. If this is NULL, the post
14711 side-effects are stored at the end of PRE_P.
14713 The reason why the output is split in two is to handle post
14714 side-effects explicitly. In some cases, an expression may have
14715 inner and outer post side-effects which need to be emitted in
14716 an order different from the one given by the recursive
14717 traversal. For instance, for the expression (*p--)++ the post
14718 side-effects of '--' must actually occur *after* the post
14719 side-effects of '++'. However, gimplification will first visit
14720 the inner expression, so if a separate POST sequence was not
14721 used, the resulting sequence would be:
14723 1 t.1 = *p
14724 2 p = p - 1
14725 3 t.2 = t.1 + 1
14726 4 *p = t.2
14728 However, the post-decrement operation in line #2 must not be
14729 evaluated until after the store to *p at line #4, so the
14730 correct sequence should be:
14732 1 t.1 = *p
14733 2 t.2 = t.1 + 1
14734 3 *p = t.2
14735 4 p = p - 1
14737 So, by specifying a separate post queue, it is possible
14738 to emit the post side-effects in the correct order.
14739 If POST_P is NULL, an internal queue will be used. Before
14740 returning to the caller, the sequence POST_P is appended to
14741 the main output sequence PRE_P.
14743 GIMPLE_TEST_F points to a function that takes a tree T and
14744 returns nonzero if T is in the GIMPLE form requested by the
14745 caller. The GIMPLE predicates are in gimple.c.
14747 FALLBACK tells the function what sort of a temporary we want if
14748 gimplification cannot produce an expression that complies with
14749 GIMPLE_TEST_F.
14751 fb_none means that no temporary should be generated
14752 fb_rvalue means that an rvalue is OK to generate
14753 fb_lvalue means that an lvalue is OK to generate
14754 fb_either means that either is OK, but an lvalue is preferable.
14755 fb_mayfail means that gimplification may fail (in which case
14756 GS_ERROR will be returned)
14758 The return value is either GS_ERROR or GS_ALL_DONE, since this
14759 function iterates until EXPR is completely gimplified or an error
14760 occurs. */
14762 enum gimplify_status
14763 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
14764 bool (*gimple_test_f) (tree), fallback_t fallback)
14766 tree tmp;
14767 gimple_seq internal_pre = NULL;
14768 gimple_seq internal_post = NULL;
14769 tree save_expr;
14770 bool is_statement;
14771 location_t saved_location;
14772 enum gimplify_status ret;
14773 gimple_stmt_iterator pre_last_gsi, post_last_gsi;
14774 tree label;
14776 save_expr = *expr_p;
14777 if (save_expr == NULL_TREE)
14778 return GS_ALL_DONE;
14780 /* If we are gimplifying a top-level statement, PRE_P must be valid. */
14781 is_statement = gimple_test_f == is_gimple_stmt;
14782 if (is_statement)
14783 gcc_assert (pre_p);
14785 /* Consistency checks. */
14786 if (gimple_test_f == is_gimple_reg)
14787 gcc_assert (fallback & (fb_rvalue | fb_lvalue));
14788 else if (gimple_test_f == is_gimple_val
14789 || gimple_test_f == is_gimple_call_addr
14790 || gimple_test_f == is_gimple_condexpr
14791 || gimple_test_f == is_gimple_condexpr_for_cond
14792 || gimple_test_f == is_gimple_mem_rhs
14793 || gimple_test_f == is_gimple_mem_rhs_or_call
14794 || gimple_test_f == is_gimple_reg_rhs
14795 || gimple_test_f == is_gimple_reg_rhs_or_call
14796 || gimple_test_f == is_gimple_asm_val
14797 || gimple_test_f == is_gimple_mem_ref_addr)
14798 gcc_assert (fallback & fb_rvalue);
14799 else if (gimple_test_f == is_gimple_min_lval
14800 || gimple_test_f == is_gimple_lvalue)
14801 gcc_assert (fallback & fb_lvalue);
14802 else if (gimple_test_f == is_gimple_addressable)
14803 gcc_assert (fallback & fb_either);
14804 else if (gimple_test_f == is_gimple_stmt)
14805 gcc_assert (fallback == fb_none);
14806 else
14808 /* We should have recognized the GIMPLE_TEST_F predicate to
14809 know what kind of fallback to use in case a temporary is
14810 needed to hold the value or address of *EXPR_P. */
14811 gcc_unreachable ();
14814 /* We used to check the predicate here and return immediately if it
14815 succeeds. This is wrong; the design is for gimplification to be
14816 idempotent, and for the predicates to only test for valid forms, not
14817 whether they are fully simplified. */
14818 if (pre_p == NULL)
14819 pre_p = &internal_pre;
14821 if (post_p == NULL)
14822 post_p = &internal_post;
14824 /* Remember the last statements added to PRE_P and POST_P. Every
14825 new statement added by the gimplification helpers needs to be
14826 annotated with location information. To centralize the
14827 responsibility, we remember the last statement that had been
14828 added to both queues before gimplifying *EXPR_P. If
14829 gimplification produces new statements in PRE_P and POST_P, those
14830 statements will be annotated with the same location information
14831 as *EXPR_P. */
14832 pre_last_gsi = gsi_last (*pre_p);
14833 post_last_gsi = gsi_last (*post_p);
14835 saved_location = input_location;
14836 if (save_expr != error_mark_node
14837 && EXPR_HAS_LOCATION (*expr_p))
14838 input_location = EXPR_LOCATION (*expr_p);
14840 /* Loop over the specific gimplifiers until the toplevel node
14841 remains the same. */
14844 /* Strip away as many useless type conversions as possible
14845 at the toplevel. */
14846 STRIP_USELESS_TYPE_CONVERSION (*expr_p);
14848 /* Remember the expr. */
14849 save_expr = *expr_p;
14851 /* Die, die, die, my darling. */
14852 if (error_operand_p (save_expr))
14854 ret = GS_ERROR;
14855 break;
14858 /* Do any language-specific gimplification. */
14859 ret = ((enum gimplify_status)
14860 lang_hooks.gimplify_expr (expr_p, pre_p, post_p));
14861 if (ret == GS_OK)
14863 if (*expr_p == NULL_TREE)
14864 break;
14865 if (*expr_p != save_expr)
14866 continue;
14868 else if (ret != GS_UNHANDLED)
14869 break;
14871 /* Make sure that all the cases set 'ret' appropriately. */
14872 ret = GS_UNHANDLED;
14873 switch (TREE_CODE (*expr_p))
14875 /* First deal with the special cases. */
14877 case POSTINCREMENT_EXPR:
14878 case POSTDECREMENT_EXPR:
14879 case PREINCREMENT_EXPR:
14880 case PREDECREMENT_EXPR:
14881 ret = gimplify_self_mod_expr (expr_p, pre_p, post_p,
14882 fallback != fb_none,
14883 TREE_TYPE (*expr_p));
14884 break;
14886 case VIEW_CONVERT_EXPR:
14887 if ((fallback & fb_rvalue)
14888 && is_gimple_reg_type (TREE_TYPE (*expr_p))
14889 && is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0))))
14891 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
14892 post_p, is_gimple_val, fb_rvalue);
14893 recalculate_side_effects (*expr_p);
14894 break;
14896 /* Fallthru. */
14898 case ARRAY_REF:
14899 case ARRAY_RANGE_REF:
14900 case REALPART_EXPR:
14901 case IMAGPART_EXPR:
14902 case COMPONENT_REF:
14903 ret = gimplify_compound_lval (expr_p, pre_p, post_p,
14904 fallback ? fallback : fb_rvalue);
14905 break;
14907 case COND_EXPR:
14908 ret = gimplify_cond_expr (expr_p, pre_p, fallback);
14910 /* C99 code may assign to an array in a structure value of a
14911 conditional expression, and this has undefined behavior
14912 only on execution, so create a temporary if an lvalue is
14913 required. */
14914 if (fallback == fb_lvalue)
14916 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
14917 mark_addressable (*expr_p);
14918 ret = GS_OK;
14920 break;
14922 case CALL_EXPR:
14923 ret = gimplify_call_expr (expr_p, pre_p, fallback != fb_none);
14925 /* C99 code may assign to an array in a structure returned
14926 from a function, and this has undefined behavior only on
14927 execution, so create a temporary if an lvalue is
14928 required. */
14929 if (fallback == fb_lvalue)
14931 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
14932 mark_addressable (*expr_p);
14933 ret = GS_OK;
14935 break;
14937 case TREE_LIST:
14938 gcc_unreachable ();
14940 case COMPOUND_EXPR:
14941 ret = gimplify_compound_expr (expr_p, pre_p, fallback != fb_none);
14942 break;
14944 case COMPOUND_LITERAL_EXPR:
14945 ret = gimplify_compound_literal_expr (expr_p, pre_p,
14946 gimple_test_f, fallback);
14947 break;
14949 case MODIFY_EXPR:
14950 case INIT_EXPR:
14951 ret = gimplify_modify_expr (expr_p, pre_p, post_p,
14952 fallback != fb_none);
14953 break;
14955 case TRUTH_ANDIF_EXPR:
14956 case TRUTH_ORIF_EXPR:
14958 /* Preserve the original type of the expression and the
14959 source location of the outer expression. */
14960 tree org_type = TREE_TYPE (*expr_p);
14961 *expr_p = gimple_boolify (*expr_p);
14962 *expr_p = build3_loc (input_location, COND_EXPR,
14963 org_type, *expr_p,
14964 fold_convert_loc
14965 (input_location,
14966 org_type, boolean_true_node),
14967 fold_convert_loc
14968 (input_location,
14969 org_type, boolean_false_node));
14970 ret = GS_OK;
14971 break;
14974 case TRUTH_NOT_EXPR:
14976 tree type = TREE_TYPE (*expr_p);
14977 /* The parsers are careful to generate TRUTH_NOT_EXPR
14978 only with operands that are always zero or one.
14979 We do not fold here but handle the only interesting case
14980 manually, as fold may re-introduce the TRUTH_NOT_EXPR. */
14981 *expr_p = gimple_boolify (*expr_p);
14982 if (TYPE_PRECISION (TREE_TYPE (*expr_p)) == 1)
14983 *expr_p = build1_loc (input_location, BIT_NOT_EXPR,
14984 TREE_TYPE (*expr_p),
14985 TREE_OPERAND (*expr_p, 0));
14986 else
14987 *expr_p = build2_loc (input_location, BIT_XOR_EXPR,
14988 TREE_TYPE (*expr_p),
14989 TREE_OPERAND (*expr_p, 0),
14990 build_int_cst (TREE_TYPE (*expr_p), 1));
14991 if (!useless_type_conversion_p (type, TREE_TYPE (*expr_p)))
14992 *expr_p = fold_convert_loc (input_location, type, *expr_p);
14993 ret = GS_OK;
14994 break;
14997 case ADDR_EXPR:
14998 ret = gimplify_addr_expr (expr_p, pre_p, post_p);
14999 break;
15001 case ANNOTATE_EXPR:
15003 tree cond = TREE_OPERAND (*expr_p, 0);
15004 tree kind = TREE_OPERAND (*expr_p, 1);
15005 tree data = TREE_OPERAND (*expr_p, 2);
15006 tree type = TREE_TYPE (cond);
15007 if (!INTEGRAL_TYPE_P (type))
15009 *expr_p = cond;
15010 ret = GS_OK;
15011 break;
15013 tree tmp = create_tmp_var (type);
15014 gimplify_arg (&cond, pre_p, EXPR_LOCATION (*expr_p));
15015 gcall *call
15016 = gimple_build_call_internal (IFN_ANNOTATE, 3, cond, kind, data);
15017 gimple_call_set_lhs (call, tmp);
15018 gimplify_seq_add_stmt (pre_p, call);
15019 *expr_p = tmp;
15020 ret = GS_ALL_DONE;
15021 break;
15024 case VA_ARG_EXPR:
15025 ret = gimplify_va_arg_expr (expr_p, pre_p, post_p);
15026 break;
15028 CASE_CONVERT:
15029 if (IS_EMPTY_STMT (*expr_p))
15031 ret = GS_ALL_DONE;
15032 break;
15035 if (VOID_TYPE_P (TREE_TYPE (*expr_p))
15036 || fallback == fb_none)
15038 /* Just strip a conversion to void (or in void context) and
15039 try again. */
15040 *expr_p = TREE_OPERAND (*expr_p, 0);
15041 ret = GS_OK;
15042 break;
15045 ret = gimplify_conversion (expr_p);
15046 if (ret == GS_ERROR)
15047 break;
15048 if (*expr_p != save_expr)
15049 break;
15050 /* FALLTHRU */
15052 case FIX_TRUNC_EXPR:
15053 /* unary_expr: ... | '(' cast ')' val | ... */
15054 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
15055 is_gimple_val, fb_rvalue);
15056 recalculate_side_effects (*expr_p);
15057 break;
15059 case INDIRECT_REF:
15061 bool volatilep = TREE_THIS_VOLATILE (*expr_p);
15062 bool notrap = TREE_THIS_NOTRAP (*expr_p);
15063 tree saved_ptr_type = TREE_TYPE (TREE_OPERAND (*expr_p, 0));
15065 *expr_p = fold_indirect_ref_loc (input_location, *expr_p);
15066 if (*expr_p != save_expr)
15068 ret = GS_OK;
15069 break;
15072 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
15073 is_gimple_reg, fb_rvalue);
15074 if (ret == GS_ERROR)
15075 break;
15077 recalculate_side_effects (*expr_p);
15078 *expr_p = fold_build2_loc (input_location, MEM_REF,
15079 TREE_TYPE (*expr_p),
15080 TREE_OPERAND (*expr_p, 0),
15081 build_int_cst (saved_ptr_type, 0));
15082 TREE_THIS_VOLATILE (*expr_p) = volatilep;
15083 TREE_THIS_NOTRAP (*expr_p) = notrap;
15084 ret = GS_OK;
15085 break;
15088 /* We arrive here through the various re-gimplifcation paths. */
15089 case MEM_REF:
15090 /* First try re-folding the whole thing. */
15091 tmp = fold_binary (MEM_REF, TREE_TYPE (*expr_p),
15092 TREE_OPERAND (*expr_p, 0),
15093 TREE_OPERAND (*expr_p, 1));
15094 if (tmp)
15096 REF_REVERSE_STORAGE_ORDER (tmp)
15097 = REF_REVERSE_STORAGE_ORDER (*expr_p);
15098 *expr_p = tmp;
15099 recalculate_side_effects (*expr_p);
15100 ret = GS_OK;
15101 break;
15103 /* Avoid re-gimplifying the address operand if it is already
15104 in suitable form. Re-gimplifying would mark the address
15105 operand addressable. Always gimplify when not in SSA form
15106 as we still may have to gimplify decls with value-exprs. */
15107 if (!gimplify_ctxp || !gimple_in_ssa_p (cfun)
15108 || !is_gimple_mem_ref_addr (TREE_OPERAND (*expr_p, 0)))
15110 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
15111 is_gimple_mem_ref_addr, fb_rvalue);
15112 if (ret == GS_ERROR)
15113 break;
15115 recalculate_side_effects (*expr_p);
15116 ret = GS_ALL_DONE;
15117 break;
15119 /* Constants need not be gimplified. */
15120 case INTEGER_CST:
15121 case REAL_CST:
15122 case FIXED_CST:
15123 case STRING_CST:
15124 case COMPLEX_CST:
15125 case VECTOR_CST:
15126 /* Drop the overflow flag on constants, we do not want
15127 that in the GIMPLE IL. */
15128 if (TREE_OVERFLOW_P (*expr_p))
15129 *expr_p = drop_tree_overflow (*expr_p);
15130 ret = GS_ALL_DONE;
15131 break;
15133 case CONST_DECL:
15134 /* If we require an lvalue, such as for ADDR_EXPR, retain the
15135 CONST_DECL node. Otherwise the decl is replaceable by its
15136 value. */
15137 /* ??? Should be == fb_lvalue, but ADDR_EXPR passes fb_either. */
15138 if (fallback & fb_lvalue)
15139 ret = GS_ALL_DONE;
15140 else
15142 *expr_p = DECL_INITIAL (*expr_p);
15143 ret = GS_OK;
15145 break;
15147 case DECL_EXPR:
15148 ret = gimplify_decl_expr (expr_p, pre_p);
15149 break;
15151 case BIND_EXPR:
15152 ret = gimplify_bind_expr (expr_p, pre_p);
15153 break;
15155 case LOOP_EXPR:
15156 ret = gimplify_loop_expr (expr_p, pre_p);
15157 break;
15159 case SWITCH_EXPR:
15160 ret = gimplify_switch_expr (expr_p, pre_p);
15161 break;
15163 case EXIT_EXPR:
15164 ret = gimplify_exit_expr (expr_p);
15165 break;
15167 case GOTO_EXPR:
15168 /* If the target is not LABEL, then it is a computed jump
15169 and the target needs to be gimplified. */
15170 if (TREE_CODE (GOTO_DESTINATION (*expr_p)) != LABEL_DECL)
15172 ret = gimplify_expr (&GOTO_DESTINATION (*expr_p), pre_p,
15173 NULL, is_gimple_val, fb_rvalue);
15174 if (ret == GS_ERROR)
15175 break;
15177 gimplify_seq_add_stmt (pre_p,
15178 gimple_build_goto (GOTO_DESTINATION (*expr_p)));
15179 ret = GS_ALL_DONE;
15180 break;
15182 case PREDICT_EXPR:
15183 gimplify_seq_add_stmt (pre_p,
15184 gimple_build_predict (PREDICT_EXPR_PREDICTOR (*expr_p),
15185 PREDICT_EXPR_OUTCOME (*expr_p)));
15186 ret = GS_ALL_DONE;
15187 break;
15189 case LABEL_EXPR:
15190 ret = gimplify_label_expr (expr_p, pre_p);
15191 label = LABEL_EXPR_LABEL (*expr_p);
15192 gcc_assert (decl_function_context (label) == current_function_decl);
15194 /* If the label is used in a goto statement, or address of the label
15195 is taken, we need to unpoison all variables that were seen so far.
15196 Doing so would prevent us from reporting a false positives. */
15197 if (asan_poisoned_variables
15198 && asan_used_labels != NULL
15199 && asan_used_labels->contains (label)
15200 && !gimplify_omp_ctxp)
15201 asan_poison_variables (asan_poisoned_variables, false, pre_p);
15202 break;
15204 case CASE_LABEL_EXPR:
15205 ret = gimplify_case_label_expr (expr_p, pre_p);
15207 if (gimplify_ctxp->live_switch_vars)
15208 asan_poison_variables (gimplify_ctxp->live_switch_vars, false,
15209 pre_p);
15210 break;
15212 case RETURN_EXPR:
15213 ret = gimplify_return_expr (*expr_p, pre_p);
15214 break;
15216 case CONSTRUCTOR:
15217 /* Don't reduce this in place; let gimplify_init_constructor work its
15218 magic. Buf if we're just elaborating this for side effects, just
15219 gimplify any element that has side-effects. */
15220 if (fallback == fb_none)
15222 unsigned HOST_WIDE_INT ix;
15223 tree val;
15224 tree temp = NULL_TREE;
15225 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (*expr_p), ix, val)
15226 if (TREE_SIDE_EFFECTS (val))
15227 append_to_statement_list (val, &temp);
15229 *expr_p = temp;
15230 ret = temp ? GS_OK : GS_ALL_DONE;
15232 /* C99 code may assign to an array in a constructed
15233 structure or union, and this has undefined behavior only
15234 on execution, so create a temporary if an lvalue is
15235 required. */
15236 else if (fallback == fb_lvalue)
15238 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
15239 mark_addressable (*expr_p);
15240 ret = GS_OK;
15242 else
15243 ret = GS_ALL_DONE;
15244 break;
15246 /* The following are special cases that are not handled by the
15247 original GIMPLE grammar. */
15249 /* SAVE_EXPR nodes are converted into a GIMPLE identifier and
15250 eliminated. */
15251 case SAVE_EXPR:
15252 ret = gimplify_save_expr (expr_p, pre_p, post_p);
15253 break;
15255 case BIT_FIELD_REF:
15256 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15257 post_p, is_gimple_lvalue, fb_either);
15258 recalculate_side_effects (*expr_p);
15259 break;
15261 case TARGET_MEM_REF:
15263 enum gimplify_status r0 = GS_ALL_DONE, r1 = GS_ALL_DONE;
15265 if (TMR_BASE (*expr_p))
15266 r0 = gimplify_expr (&TMR_BASE (*expr_p), pre_p,
15267 post_p, is_gimple_mem_ref_addr, fb_either);
15268 if (TMR_INDEX (*expr_p))
15269 r1 = gimplify_expr (&TMR_INDEX (*expr_p), pre_p,
15270 post_p, is_gimple_val, fb_rvalue);
15271 if (TMR_INDEX2 (*expr_p))
15272 r1 = gimplify_expr (&TMR_INDEX2 (*expr_p), pre_p,
15273 post_p, is_gimple_val, fb_rvalue);
15274 /* TMR_STEP and TMR_OFFSET are always integer constants. */
15275 ret = MIN (r0, r1);
15277 break;
15279 case NON_LVALUE_EXPR:
15280 /* This should have been stripped above. */
15281 gcc_unreachable ();
15283 case ASM_EXPR:
15284 ret = gimplify_asm_expr (expr_p, pre_p, post_p);
15285 break;
15287 case TRY_FINALLY_EXPR:
15288 case TRY_CATCH_EXPR:
15290 gimple_seq eval, cleanup;
15291 gtry *try_;
15293 /* Calls to destructors are generated automatically in FINALLY/CATCH
15294 block. They should have location as UNKNOWN_LOCATION. However,
15295 gimplify_call_expr will reset these call stmts to input_location
15296 if it finds stmt's location is unknown. To prevent resetting for
15297 destructors, we set the input_location to unknown.
15298 Note that this only affects the destructor calls in FINALLY/CATCH
15299 block, and will automatically reset to its original value by the
15300 end of gimplify_expr. */
15301 input_location = UNKNOWN_LOCATION;
15302 eval = cleanup = NULL;
15303 gimplify_and_add (TREE_OPERAND (*expr_p, 0), &eval);
15304 if (TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
15305 && TREE_CODE (TREE_OPERAND (*expr_p, 1)) == EH_ELSE_EXPR)
15307 gimple_seq n = NULL, e = NULL;
15308 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1),
15309 0), &n);
15310 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1),
15311 1), &e);
15312 if (!gimple_seq_empty_p (n) && !gimple_seq_empty_p (e))
15314 geh_else *stmt = gimple_build_eh_else (n, e);
15315 gimple_seq_add_stmt (&cleanup, stmt);
15318 else
15319 gimplify_and_add (TREE_OPERAND (*expr_p, 1), &cleanup);
15320 /* Don't create bogus GIMPLE_TRY with empty cleanup. */
15321 if (gimple_seq_empty_p (cleanup))
15323 gimple_seq_add_seq (pre_p, eval);
15324 ret = GS_ALL_DONE;
15325 break;
15327 try_ = gimple_build_try (eval, cleanup,
15328 TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
15329 ? GIMPLE_TRY_FINALLY
15330 : GIMPLE_TRY_CATCH);
15331 if (EXPR_HAS_LOCATION (save_expr))
15332 gimple_set_location (try_, EXPR_LOCATION (save_expr));
15333 else if (LOCATION_LOCUS (saved_location) != UNKNOWN_LOCATION)
15334 gimple_set_location (try_, saved_location);
15335 if (TREE_CODE (*expr_p) == TRY_CATCH_EXPR)
15336 gimple_try_set_catch_is_cleanup (try_,
15337 TRY_CATCH_IS_CLEANUP (*expr_p));
15338 gimplify_seq_add_stmt (pre_p, try_);
15339 ret = GS_ALL_DONE;
15340 break;
15343 case CLEANUP_POINT_EXPR:
15344 ret = gimplify_cleanup_point_expr (expr_p, pre_p);
15345 break;
15347 case TARGET_EXPR:
15348 ret = gimplify_target_expr (expr_p, pre_p, post_p);
15349 break;
15351 case CATCH_EXPR:
15353 gimple *c;
15354 gimple_seq handler = NULL;
15355 gimplify_and_add (CATCH_BODY (*expr_p), &handler);
15356 c = gimple_build_catch (CATCH_TYPES (*expr_p), handler);
15357 gimplify_seq_add_stmt (pre_p, c);
15358 ret = GS_ALL_DONE;
15359 break;
15362 case EH_FILTER_EXPR:
15364 gimple *ehf;
15365 gimple_seq failure = NULL;
15367 gimplify_and_add (EH_FILTER_FAILURE (*expr_p), &failure);
15368 ehf = gimple_build_eh_filter (EH_FILTER_TYPES (*expr_p), failure);
15369 copy_warning (ehf, *expr_p);
15370 gimplify_seq_add_stmt (pre_p, ehf);
15371 ret = GS_ALL_DONE;
15372 break;
15375 case OBJ_TYPE_REF:
15377 enum gimplify_status r0, r1;
15378 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p,
15379 post_p, is_gimple_val, fb_rvalue);
15380 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p,
15381 post_p, is_gimple_val, fb_rvalue);
15382 TREE_SIDE_EFFECTS (*expr_p) = 0;
15383 ret = MIN (r0, r1);
15385 break;
15387 case LABEL_DECL:
15388 /* We get here when taking the address of a label. We mark
15389 the label as "forced"; meaning it can never be removed and
15390 it is a potential target for any computed goto. */
15391 FORCED_LABEL (*expr_p) = 1;
15392 ret = GS_ALL_DONE;
15393 break;
15395 case STATEMENT_LIST:
15396 ret = gimplify_statement_list (expr_p, pre_p);
15397 break;
15399 case WITH_SIZE_EXPR:
15401 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15402 post_p == &internal_post ? NULL : post_p,
15403 gimple_test_f, fallback);
15404 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
15405 is_gimple_val, fb_rvalue);
15406 ret = GS_ALL_DONE;
15408 break;
15410 case VAR_DECL:
15411 case PARM_DECL:
15412 ret = gimplify_var_or_parm_decl (expr_p);
15413 break;
15415 case RESULT_DECL:
15416 /* When within an OMP context, notice uses of variables. */
15417 if (gimplify_omp_ctxp)
15418 omp_notice_variable (gimplify_omp_ctxp, *expr_p, true);
15419 ret = GS_ALL_DONE;
15420 break;
15422 case DEBUG_EXPR_DECL:
15423 gcc_unreachable ();
15425 case DEBUG_BEGIN_STMT:
15426 gimplify_seq_add_stmt (pre_p,
15427 gimple_build_debug_begin_stmt
15428 (TREE_BLOCK (*expr_p),
15429 EXPR_LOCATION (*expr_p)));
15430 ret = GS_ALL_DONE;
15431 *expr_p = NULL;
15432 break;
15434 case SSA_NAME:
15435 /* Allow callbacks into the gimplifier during optimization. */
15436 ret = GS_ALL_DONE;
15437 break;
15439 case OMP_PARALLEL:
15440 gimplify_omp_parallel (expr_p, pre_p);
15441 ret = GS_ALL_DONE;
15442 break;
15444 case OMP_TASK:
15445 gimplify_omp_task (expr_p, pre_p);
15446 ret = GS_ALL_DONE;
15447 break;
15449 case OMP_FOR:
15450 case OMP_SIMD:
15451 case OMP_DISTRIBUTE:
15452 case OMP_TASKLOOP:
15453 case OACC_LOOP:
15454 ret = gimplify_omp_for (expr_p, pre_p);
15455 break;
15457 case OMP_LOOP:
15458 ret = gimplify_omp_loop (expr_p, pre_p);
15459 break;
15461 case OACC_CACHE:
15462 gimplify_oacc_cache (expr_p, pre_p);
15463 ret = GS_ALL_DONE;
15464 break;
15466 case OACC_DECLARE:
15467 gimplify_oacc_declare (expr_p, pre_p);
15468 ret = GS_ALL_DONE;
15469 break;
15471 case OACC_HOST_DATA:
15472 case OACC_DATA:
15473 case OACC_KERNELS:
15474 case OACC_PARALLEL:
15475 case OACC_SERIAL:
15476 case OMP_SCOPE:
15477 case OMP_SECTIONS:
15478 case OMP_SINGLE:
15479 case OMP_TARGET:
15480 case OMP_TARGET_DATA:
15481 case OMP_TEAMS:
15482 gimplify_omp_workshare (expr_p, pre_p);
15483 ret = GS_ALL_DONE;
15484 break;
15486 case OACC_ENTER_DATA:
15487 case OACC_EXIT_DATA:
15488 case OACC_UPDATE:
15489 case OMP_TARGET_UPDATE:
15490 case OMP_TARGET_ENTER_DATA:
15491 case OMP_TARGET_EXIT_DATA:
15492 gimplify_omp_target_update (expr_p, pre_p);
15493 ret = GS_ALL_DONE;
15494 break;
15496 case OMP_SECTION:
15497 case OMP_MASTER:
15498 case OMP_MASKED:
15499 case OMP_ORDERED:
15500 case OMP_CRITICAL:
15501 case OMP_SCAN:
15503 gimple_seq body = NULL;
15504 gimple *g;
15505 bool saved_in_omp_construct = in_omp_construct;
15507 in_omp_construct = true;
15508 gimplify_and_add (OMP_BODY (*expr_p), &body);
15509 in_omp_construct = saved_in_omp_construct;
15510 switch (TREE_CODE (*expr_p))
15512 case OMP_SECTION:
15513 g = gimple_build_omp_section (body);
15514 break;
15515 case OMP_MASTER:
15516 g = gimple_build_omp_master (body);
15517 break;
15518 case OMP_ORDERED:
15519 g = gimplify_omp_ordered (*expr_p, body);
15520 break;
15521 case OMP_MASKED:
15522 gimplify_scan_omp_clauses (&OMP_MASKED_CLAUSES (*expr_p),
15523 pre_p, ORT_WORKSHARE, OMP_MASKED);
15524 gimplify_adjust_omp_clauses (pre_p, body,
15525 &OMP_MASKED_CLAUSES (*expr_p),
15526 OMP_MASKED);
15527 g = gimple_build_omp_masked (body,
15528 OMP_MASKED_CLAUSES (*expr_p));
15529 break;
15530 case OMP_CRITICAL:
15531 gimplify_scan_omp_clauses (&OMP_CRITICAL_CLAUSES (*expr_p),
15532 pre_p, ORT_WORKSHARE, OMP_CRITICAL);
15533 gimplify_adjust_omp_clauses (pre_p, body,
15534 &OMP_CRITICAL_CLAUSES (*expr_p),
15535 OMP_CRITICAL);
15536 g = gimple_build_omp_critical (body,
15537 OMP_CRITICAL_NAME (*expr_p),
15538 OMP_CRITICAL_CLAUSES (*expr_p));
15539 break;
15540 case OMP_SCAN:
15541 gimplify_scan_omp_clauses (&OMP_SCAN_CLAUSES (*expr_p),
15542 pre_p, ORT_WORKSHARE, OMP_SCAN);
15543 gimplify_adjust_omp_clauses (pre_p, body,
15544 &OMP_SCAN_CLAUSES (*expr_p),
15545 OMP_SCAN);
15546 g = gimple_build_omp_scan (body, OMP_SCAN_CLAUSES (*expr_p));
15547 break;
15548 default:
15549 gcc_unreachable ();
15551 gimplify_seq_add_stmt (pre_p, g);
15552 ret = GS_ALL_DONE;
15553 break;
15556 case OMP_TASKGROUP:
15558 gimple_seq body = NULL;
15560 tree *pclauses = &OMP_TASKGROUP_CLAUSES (*expr_p);
15561 bool saved_in_omp_construct = in_omp_construct;
15562 gimplify_scan_omp_clauses (pclauses, pre_p, ORT_TASKGROUP,
15563 OMP_TASKGROUP);
15564 gimplify_adjust_omp_clauses (pre_p, NULL, pclauses, OMP_TASKGROUP);
15566 in_omp_construct = true;
15567 gimplify_and_add (OMP_BODY (*expr_p), &body);
15568 in_omp_construct = saved_in_omp_construct;
15569 gimple_seq cleanup = NULL;
15570 tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_END);
15571 gimple *g = gimple_build_call (fn, 0);
15572 gimple_seq_add_stmt (&cleanup, g);
15573 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
15574 body = NULL;
15575 gimple_seq_add_stmt (&body, g);
15576 g = gimple_build_omp_taskgroup (body, *pclauses);
15577 gimplify_seq_add_stmt (pre_p, g);
15578 ret = GS_ALL_DONE;
15579 break;
15582 case OMP_ATOMIC:
15583 case OMP_ATOMIC_READ:
15584 case OMP_ATOMIC_CAPTURE_OLD:
15585 case OMP_ATOMIC_CAPTURE_NEW:
15586 ret = gimplify_omp_atomic (expr_p, pre_p);
15587 break;
15589 case TRANSACTION_EXPR:
15590 ret = gimplify_transaction (expr_p, pre_p);
15591 break;
15593 case TRUTH_AND_EXPR:
15594 case TRUTH_OR_EXPR:
15595 case TRUTH_XOR_EXPR:
15597 tree orig_type = TREE_TYPE (*expr_p);
15598 tree new_type, xop0, xop1;
15599 *expr_p = gimple_boolify (*expr_p);
15600 new_type = TREE_TYPE (*expr_p);
15601 if (!useless_type_conversion_p (orig_type, new_type))
15603 *expr_p = fold_convert_loc (input_location, orig_type, *expr_p);
15604 ret = GS_OK;
15605 break;
15608 /* Boolified binary truth expressions are semantically equivalent
15609 to bitwise binary expressions. Canonicalize them to the
15610 bitwise variant. */
15611 switch (TREE_CODE (*expr_p))
15613 case TRUTH_AND_EXPR:
15614 TREE_SET_CODE (*expr_p, BIT_AND_EXPR);
15615 break;
15616 case TRUTH_OR_EXPR:
15617 TREE_SET_CODE (*expr_p, BIT_IOR_EXPR);
15618 break;
15619 case TRUTH_XOR_EXPR:
15620 TREE_SET_CODE (*expr_p, BIT_XOR_EXPR);
15621 break;
15622 default:
15623 break;
15625 /* Now make sure that operands have compatible type to
15626 expression's new_type. */
15627 xop0 = TREE_OPERAND (*expr_p, 0);
15628 xop1 = TREE_OPERAND (*expr_p, 1);
15629 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop0)))
15630 TREE_OPERAND (*expr_p, 0) = fold_convert_loc (input_location,
15631 new_type,
15632 xop0);
15633 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop1)))
15634 TREE_OPERAND (*expr_p, 1) = fold_convert_loc (input_location,
15635 new_type,
15636 xop1);
15637 /* Continue classified as tcc_binary. */
15638 goto expr_2;
15641 case VEC_COND_EXPR:
15642 goto expr_3;
15644 case VEC_PERM_EXPR:
15645 /* Classified as tcc_expression. */
15646 goto expr_3;
15648 case BIT_INSERT_EXPR:
15649 /* Argument 3 is a constant. */
15650 goto expr_2;
15652 case POINTER_PLUS_EXPR:
15654 enum gimplify_status r0, r1;
15655 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15656 post_p, is_gimple_val, fb_rvalue);
15657 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
15658 post_p, is_gimple_val, fb_rvalue);
15659 recalculate_side_effects (*expr_p);
15660 ret = MIN (r0, r1);
15661 break;
15664 default:
15665 switch (TREE_CODE_CLASS (TREE_CODE (*expr_p)))
15667 case tcc_comparison:
15668 /* Handle comparison of objects of non scalar mode aggregates
15669 with a call to memcmp. It would be nice to only have to do
15670 this for variable-sized objects, but then we'd have to allow
15671 the same nest of reference nodes we allow for MODIFY_EXPR and
15672 that's too complex.
15674 Compare scalar mode aggregates as scalar mode values. Using
15675 memcmp for them would be very inefficient at best, and is
15676 plain wrong if bitfields are involved. */
15678 tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 1));
15680 /* Vector comparisons need no boolification. */
15681 if (TREE_CODE (type) == VECTOR_TYPE)
15682 goto expr_2;
15683 else if (!AGGREGATE_TYPE_P (type))
15685 tree org_type = TREE_TYPE (*expr_p);
15686 *expr_p = gimple_boolify (*expr_p);
15687 if (!useless_type_conversion_p (org_type,
15688 TREE_TYPE (*expr_p)))
15690 *expr_p = fold_convert_loc (input_location,
15691 org_type, *expr_p);
15692 ret = GS_OK;
15694 else
15695 goto expr_2;
15697 else if (TYPE_MODE (type) != BLKmode)
15698 ret = gimplify_scalar_mode_aggregate_compare (expr_p);
15699 else
15700 ret = gimplify_variable_sized_compare (expr_p);
15702 break;
15705 /* If *EXPR_P does not need to be special-cased, handle it
15706 according to its class. */
15707 case tcc_unary:
15708 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15709 post_p, is_gimple_val, fb_rvalue);
15710 break;
15712 case tcc_binary:
15713 expr_2:
15715 enum gimplify_status r0, r1;
15717 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15718 post_p, is_gimple_val, fb_rvalue);
15719 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
15720 post_p, is_gimple_val, fb_rvalue);
15722 ret = MIN (r0, r1);
15723 break;
15726 expr_3:
15728 enum gimplify_status r0, r1, r2;
15730 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15731 post_p, is_gimple_val, fb_rvalue);
15732 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
15733 post_p, is_gimple_val, fb_rvalue);
15734 r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p,
15735 post_p, is_gimple_val, fb_rvalue);
15737 ret = MIN (MIN (r0, r1), r2);
15738 break;
15741 case tcc_declaration:
15742 case tcc_constant:
15743 ret = GS_ALL_DONE;
15744 goto dont_recalculate;
15746 default:
15747 gcc_unreachable ();
15750 recalculate_side_effects (*expr_p);
15752 dont_recalculate:
15753 break;
15756 gcc_assert (*expr_p || ret != GS_OK);
15758 while (ret == GS_OK);
15760 /* If we encountered an error_mark somewhere nested inside, either
15761 stub out the statement or propagate the error back out. */
15762 if (ret == GS_ERROR)
15764 if (is_statement)
15765 *expr_p = NULL;
15766 goto out;
15769 /* This was only valid as a return value from the langhook, which
15770 we handled. Make sure it doesn't escape from any other context. */
15771 gcc_assert (ret != GS_UNHANDLED);
15773 if (fallback == fb_none && *expr_p && !is_gimple_stmt (*expr_p))
15775 /* We aren't looking for a value, and we don't have a valid
15776 statement. If it doesn't have side-effects, throw it away.
15777 We can also get here with code such as "*&&L;", where L is
15778 a LABEL_DECL that is marked as FORCED_LABEL. */
15779 if (TREE_CODE (*expr_p) == LABEL_DECL
15780 || !TREE_SIDE_EFFECTS (*expr_p))
15781 *expr_p = NULL;
15782 else if (!TREE_THIS_VOLATILE (*expr_p))
15784 /* This is probably a _REF that contains something nested that
15785 has side effects. Recurse through the operands to find it. */
15786 enum tree_code code = TREE_CODE (*expr_p);
15788 switch (code)
15790 case COMPONENT_REF:
15791 case REALPART_EXPR:
15792 case IMAGPART_EXPR:
15793 case VIEW_CONVERT_EXPR:
15794 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
15795 gimple_test_f, fallback);
15796 break;
15798 case ARRAY_REF:
15799 case ARRAY_RANGE_REF:
15800 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
15801 gimple_test_f, fallback);
15802 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
15803 gimple_test_f, fallback);
15804 break;
15806 default:
15807 /* Anything else with side-effects must be converted to
15808 a valid statement before we get here. */
15809 gcc_unreachable ();
15812 *expr_p = NULL;
15814 else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p))
15815 && TYPE_MODE (TREE_TYPE (*expr_p)) != BLKmode
15816 && !is_empty_type (TREE_TYPE (*expr_p)))
15818 /* Historically, the compiler has treated a bare reference
15819 to a non-BLKmode volatile lvalue as forcing a load. */
15820 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p));
15822 /* Normally, we do not want to create a temporary for a
15823 TREE_ADDRESSABLE type because such a type should not be
15824 copied by bitwise-assignment. However, we make an
15825 exception here, as all we are doing here is ensuring that
15826 we read the bytes that make up the type. We use
15827 create_tmp_var_raw because create_tmp_var will abort when
15828 given a TREE_ADDRESSABLE type. */
15829 tree tmp = create_tmp_var_raw (type, "vol");
15830 gimple_add_tmp_var (tmp);
15831 gimplify_assign (tmp, *expr_p, pre_p);
15832 *expr_p = NULL;
15834 else
15835 /* We can't do anything useful with a volatile reference to
15836 an incomplete type, so just throw it away. Likewise for
15837 a BLKmode type, since any implicit inner load should
15838 already have been turned into an explicit one by the
15839 gimplification process. */
15840 *expr_p = NULL;
15843 /* If we are gimplifying at the statement level, we're done. Tack
15844 everything together and return. */
15845 if (fallback == fb_none || is_statement)
15847 /* Since *EXPR_P has been converted into a GIMPLE tuple, clear
15848 it out for GC to reclaim it. */
15849 *expr_p = NULL_TREE;
15851 if (!gimple_seq_empty_p (internal_pre)
15852 || !gimple_seq_empty_p (internal_post))
15854 gimplify_seq_add_seq (&internal_pre, internal_post);
15855 gimplify_seq_add_seq (pre_p, internal_pre);
15858 /* The result of gimplifying *EXPR_P is going to be the last few
15859 statements in *PRE_P and *POST_P. Add location information
15860 to all the statements that were added by the gimplification
15861 helpers. */
15862 if (!gimple_seq_empty_p (*pre_p))
15863 annotate_all_with_location_after (*pre_p, pre_last_gsi, input_location);
15865 if (!gimple_seq_empty_p (*post_p))
15866 annotate_all_with_location_after (*post_p, post_last_gsi,
15867 input_location);
15869 goto out;
15872 #ifdef ENABLE_GIMPLE_CHECKING
15873 if (*expr_p)
15875 enum tree_code code = TREE_CODE (*expr_p);
15876 /* These expressions should already be in gimple IR form. */
15877 gcc_assert (code != MODIFY_EXPR
15878 && code != ASM_EXPR
15879 && code != BIND_EXPR
15880 && code != CATCH_EXPR
15881 && (code != COND_EXPR || gimplify_ctxp->allow_rhs_cond_expr)
15882 && code != EH_FILTER_EXPR
15883 && code != GOTO_EXPR
15884 && code != LABEL_EXPR
15885 && code != LOOP_EXPR
15886 && code != SWITCH_EXPR
15887 && code != TRY_FINALLY_EXPR
15888 && code != EH_ELSE_EXPR
15889 && code != OACC_PARALLEL
15890 && code != OACC_KERNELS
15891 && code != OACC_SERIAL
15892 && code != OACC_DATA
15893 && code != OACC_HOST_DATA
15894 && code != OACC_DECLARE
15895 && code != OACC_UPDATE
15896 && code != OACC_ENTER_DATA
15897 && code != OACC_EXIT_DATA
15898 && code != OACC_CACHE
15899 && code != OMP_CRITICAL
15900 && code != OMP_FOR
15901 && code != OACC_LOOP
15902 && code != OMP_MASTER
15903 && code != OMP_MASKED
15904 && code != OMP_TASKGROUP
15905 && code != OMP_ORDERED
15906 && code != OMP_PARALLEL
15907 && code != OMP_SCAN
15908 && code != OMP_SECTIONS
15909 && code != OMP_SECTION
15910 && code != OMP_SINGLE
15911 && code != OMP_SCOPE);
15913 #endif
15915 /* Otherwise we're gimplifying a subexpression, so the resulting
15916 value is interesting. If it's a valid operand that matches
15917 GIMPLE_TEST_F, we're done. Unless we are handling some
15918 post-effects internally; if that's the case, we need to copy into
15919 a temporary before adding the post-effects to POST_P. */
15920 if (gimple_seq_empty_p (internal_post) && (*gimple_test_f) (*expr_p))
15921 goto out;
15923 /* Otherwise, we need to create a new temporary for the gimplified
15924 expression. */
15926 /* We can't return an lvalue if we have an internal postqueue. The
15927 object the lvalue refers to would (probably) be modified by the
15928 postqueue; we need to copy the value out first, which means an
15929 rvalue. */
15930 if ((fallback & fb_lvalue)
15931 && gimple_seq_empty_p (internal_post)
15932 && is_gimple_addressable (*expr_p))
15934 /* An lvalue will do. Take the address of the expression, store it
15935 in a temporary, and replace the expression with an INDIRECT_REF of
15936 that temporary. */
15937 tree ref_alias_type = reference_alias_ptr_type (*expr_p);
15938 unsigned int ref_align = get_object_alignment (*expr_p);
15939 tree ref_type = TREE_TYPE (*expr_p);
15940 tmp = build_fold_addr_expr_loc (input_location, *expr_p);
15941 gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue);
15942 if (TYPE_ALIGN (ref_type) != ref_align)
15943 ref_type = build_aligned_type (ref_type, ref_align);
15944 *expr_p = build2 (MEM_REF, ref_type,
15945 tmp, build_zero_cst (ref_alias_type));
15947 else if ((fallback & fb_rvalue) && is_gimple_reg_rhs_or_call (*expr_p))
15949 /* An rvalue will do. Assign the gimplified expression into a
15950 new temporary TMP and replace the original expression with
15951 TMP. First, make sure that the expression has a type so that
15952 it can be assigned into a temporary. */
15953 gcc_assert (!VOID_TYPE_P (TREE_TYPE (*expr_p)));
15954 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
15956 else
15958 #ifdef ENABLE_GIMPLE_CHECKING
15959 if (!(fallback & fb_mayfail))
15961 fprintf (stderr, "gimplification failed:\n");
15962 print_generic_expr (stderr, *expr_p);
15963 debug_tree (*expr_p);
15964 internal_error ("gimplification failed");
15966 #endif
15967 gcc_assert (fallback & fb_mayfail);
15969 /* If this is an asm statement, and the user asked for the
15970 impossible, don't die. Fail and let gimplify_asm_expr
15971 issue an error. */
15972 ret = GS_ERROR;
15973 goto out;
15976 /* Make sure the temporary matches our predicate. */
15977 gcc_assert ((*gimple_test_f) (*expr_p));
15979 if (!gimple_seq_empty_p (internal_post))
15981 annotate_all_with_location (internal_post, input_location);
15982 gimplify_seq_add_seq (pre_p, internal_post);
15985 out:
15986 input_location = saved_location;
15987 return ret;
15990 /* Like gimplify_expr but make sure the gimplified result is not itself
15991 a SSA name (but a decl if it were). Temporaries required by
15992 evaluating *EXPR_P may be still SSA names. */
15994 static enum gimplify_status
15995 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
15996 bool (*gimple_test_f) (tree), fallback_t fallback,
15997 bool allow_ssa)
15999 enum gimplify_status ret = gimplify_expr (expr_p, pre_p, post_p,
16000 gimple_test_f, fallback);
16001 if (! allow_ssa
16002 && TREE_CODE (*expr_p) == SSA_NAME)
16003 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, NULL, false);
16004 return ret;
16007 /* Look through TYPE for variable-sized objects and gimplify each such
16008 size that we find. Add to LIST_P any statements generated. */
16010 void
16011 gimplify_type_sizes (tree type, gimple_seq *list_p)
16013 if (type == NULL || type == error_mark_node)
16014 return;
16016 const bool ignored_p
16017 = TYPE_NAME (type)
16018 && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
16019 && DECL_IGNORED_P (TYPE_NAME (type));
16020 tree t;
16022 /* We first do the main variant, then copy into any other variants. */
16023 type = TYPE_MAIN_VARIANT (type);
16025 /* Avoid infinite recursion. */
16026 if (TYPE_SIZES_GIMPLIFIED (type))
16027 return;
16029 TYPE_SIZES_GIMPLIFIED (type) = 1;
16031 switch (TREE_CODE (type))
16033 case INTEGER_TYPE:
16034 case ENUMERAL_TYPE:
16035 case BOOLEAN_TYPE:
16036 case REAL_TYPE:
16037 case FIXED_POINT_TYPE:
16038 gimplify_one_sizepos (&TYPE_MIN_VALUE (type), list_p);
16039 gimplify_one_sizepos (&TYPE_MAX_VALUE (type), list_p);
16041 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
16043 TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type);
16044 TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type);
16046 break;
16048 case ARRAY_TYPE:
16049 /* These types may not have declarations, so handle them here. */
16050 gimplify_type_sizes (TREE_TYPE (type), list_p);
16051 gimplify_type_sizes (TYPE_DOMAIN (type), list_p);
16052 /* Ensure VLA bounds aren't removed, for -O0 they should be variables
16053 with assigned stack slots, for -O1+ -g they should be tracked
16054 by VTA. */
16055 if (!ignored_p
16056 && TYPE_DOMAIN (type)
16057 && INTEGRAL_TYPE_P (TYPE_DOMAIN (type)))
16059 t = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
16060 if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
16061 DECL_IGNORED_P (t) = 0;
16062 t = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
16063 if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
16064 DECL_IGNORED_P (t) = 0;
16066 break;
16068 case RECORD_TYPE:
16069 case UNION_TYPE:
16070 case QUAL_UNION_TYPE:
16071 for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
16072 if (TREE_CODE (field) == FIELD_DECL)
16074 gimplify_one_sizepos (&DECL_FIELD_OFFSET (field), list_p);
16075 /* Likewise, ensure variable offsets aren't removed. */
16076 if (!ignored_p
16077 && (t = DECL_FIELD_OFFSET (field))
16078 && VAR_P (t)
16079 && DECL_ARTIFICIAL (t))
16080 DECL_IGNORED_P (t) = 0;
16081 gimplify_one_sizepos (&DECL_SIZE (field), list_p);
16082 gimplify_one_sizepos (&DECL_SIZE_UNIT (field), list_p);
16083 gimplify_type_sizes (TREE_TYPE (field), list_p);
16085 break;
16087 case POINTER_TYPE:
16088 case REFERENCE_TYPE:
16089 /* We used to recurse on the pointed-to type here, which turned out to
16090 be incorrect because its definition might refer to variables not
16091 yet initialized at this point if a forward declaration is involved.
16093 It was actually useful for anonymous pointed-to types to ensure
16094 that the sizes evaluation dominates every possible later use of the
16095 values. Restricting to such types here would be safe since there
16096 is no possible forward declaration around, but would introduce an
16097 undesirable middle-end semantic to anonymity. We then defer to
16098 front-ends the responsibility of ensuring that the sizes are
16099 evaluated both early and late enough, e.g. by attaching artificial
16100 type declarations to the tree. */
16101 break;
16103 default:
16104 break;
16107 gimplify_one_sizepos (&TYPE_SIZE (type), list_p);
16108 gimplify_one_sizepos (&TYPE_SIZE_UNIT (type), list_p);
16110 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
16112 TYPE_SIZE (t) = TYPE_SIZE (type);
16113 TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (type);
16114 TYPE_SIZES_GIMPLIFIED (t) = 1;
16118 /* A subroutine of gimplify_type_sizes to make sure that *EXPR_P,
16119 a size or position, has had all of its SAVE_EXPRs evaluated.
16120 We add any required statements to *STMT_P. */
16122 void
16123 gimplify_one_sizepos (tree *expr_p, gimple_seq *stmt_p)
16125 tree expr = *expr_p;
16127 /* We don't do anything if the value isn't there, is constant, or contains
16128 A PLACEHOLDER_EXPR. We also don't want to do anything if it's already
16129 a VAR_DECL. If it's a VAR_DECL from another function, the gimplifier
16130 will want to replace it with a new variable, but that will cause problems
16131 if this type is from outside the function. It's OK to have that here. */
16132 if (expr == NULL_TREE
16133 || is_gimple_constant (expr)
16134 || TREE_CODE (expr) == VAR_DECL
16135 || CONTAINS_PLACEHOLDER_P (expr))
16136 return;
16138 *expr_p = unshare_expr (expr);
16140 /* SSA names in decl/type fields are a bad idea - they'll get reclaimed
16141 if the def vanishes. */
16142 gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue, false);
16144 /* If expr wasn't already is_gimple_sizepos or is_gimple_constant from the
16145 FE, ensure that it is a VAR_DECL, otherwise we might handle some decls
16146 as gimplify_vla_decl even when they would have all sizes INTEGER_CSTs. */
16147 if (is_gimple_constant (*expr_p))
16148 *expr_p = get_initialized_tmp_var (*expr_p, stmt_p, NULL, false);
16151 /* Gimplify the body of statements of FNDECL and return a GIMPLE_BIND node
16152 containing the sequence of corresponding GIMPLE statements. If DO_PARMS
16153 is true, also gimplify the parameters. */
16155 gbind *
16156 gimplify_body (tree fndecl, bool do_parms)
16158 location_t saved_location = input_location;
16159 gimple_seq parm_stmts, parm_cleanup = NULL, seq;
16160 gimple *outer_stmt;
16161 gbind *outer_bind;
16163 timevar_push (TV_TREE_GIMPLIFY);
16165 init_tree_ssa (cfun);
16167 /* Initialize for optimize_insn_for_s{ize,peed}_p possibly called during
16168 gimplification. */
16169 default_rtl_profile ();
16171 gcc_assert (gimplify_ctxp == NULL);
16172 push_gimplify_context (true);
16174 if (flag_openacc || flag_openmp)
16176 gcc_assert (gimplify_omp_ctxp == NULL);
16177 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (fndecl)))
16178 gimplify_omp_ctxp = new_omp_context (ORT_IMPLICIT_TARGET);
16181 /* Unshare most shared trees in the body and in that of any nested functions.
16182 It would seem we don't have to do this for nested functions because
16183 they are supposed to be output and then the outer function gimplified
16184 first, but the g++ front end doesn't always do it that way. */
16185 unshare_body (fndecl);
16186 unvisit_body (fndecl);
16188 /* Make sure input_location isn't set to something weird. */
16189 input_location = DECL_SOURCE_LOCATION (fndecl);
16191 /* Resolve callee-copies. This has to be done before processing
16192 the body so that DECL_VALUE_EXPR gets processed correctly. */
16193 parm_stmts = do_parms ? gimplify_parameters (&parm_cleanup) : NULL;
16195 /* Gimplify the function's body. */
16196 seq = NULL;
16197 gimplify_stmt (&DECL_SAVED_TREE (fndecl), &seq);
16198 outer_stmt = gimple_seq_first_nondebug_stmt (seq);
16199 if (!outer_stmt)
16201 outer_stmt = gimple_build_nop ();
16202 gimplify_seq_add_stmt (&seq, outer_stmt);
16205 /* The body must contain exactly one statement, a GIMPLE_BIND. If this is
16206 not the case, wrap everything in a GIMPLE_BIND to make it so. */
16207 if (gimple_code (outer_stmt) == GIMPLE_BIND
16208 && (gimple_seq_first_nondebug_stmt (seq)
16209 == gimple_seq_last_nondebug_stmt (seq)))
16211 outer_bind = as_a <gbind *> (outer_stmt);
16212 if (gimple_seq_first_stmt (seq) != outer_stmt
16213 || gimple_seq_last_stmt (seq) != outer_stmt)
16215 /* If there are debug stmts before or after outer_stmt, move them
16216 inside of outer_bind body. */
16217 gimple_stmt_iterator gsi = gsi_for_stmt (outer_stmt, &seq);
16218 gimple_seq second_seq = NULL;
16219 if (gimple_seq_first_stmt (seq) != outer_stmt
16220 && gimple_seq_last_stmt (seq) != outer_stmt)
16222 second_seq = gsi_split_seq_after (gsi);
16223 gsi_remove (&gsi, false);
16225 else if (gimple_seq_first_stmt (seq) != outer_stmt)
16226 gsi_remove (&gsi, false);
16227 else
16229 gsi_remove (&gsi, false);
16230 second_seq = seq;
16231 seq = NULL;
16233 gimple_seq_add_seq_without_update (&seq,
16234 gimple_bind_body (outer_bind));
16235 gimple_seq_add_seq_without_update (&seq, second_seq);
16236 gimple_bind_set_body (outer_bind, seq);
16239 else
16240 outer_bind = gimple_build_bind (NULL_TREE, seq, NULL);
16242 DECL_SAVED_TREE (fndecl) = NULL_TREE;
16244 /* If we had callee-copies statements, insert them at the beginning
16245 of the function and clear DECL_VALUE_EXPR_P on the parameters. */
16246 if (!gimple_seq_empty_p (parm_stmts))
16248 tree parm;
16250 gimplify_seq_add_seq (&parm_stmts, gimple_bind_body (outer_bind));
16251 if (parm_cleanup)
16253 gtry *g = gimple_build_try (parm_stmts, parm_cleanup,
16254 GIMPLE_TRY_FINALLY);
16255 parm_stmts = NULL;
16256 gimple_seq_add_stmt (&parm_stmts, g);
16258 gimple_bind_set_body (outer_bind, parm_stmts);
16260 for (parm = DECL_ARGUMENTS (current_function_decl);
16261 parm; parm = DECL_CHAIN (parm))
16262 if (DECL_HAS_VALUE_EXPR_P (parm))
16264 DECL_HAS_VALUE_EXPR_P (parm) = 0;
16265 DECL_IGNORED_P (parm) = 0;
16269 if ((flag_openacc || flag_openmp || flag_openmp_simd)
16270 && gimplify_omp_ctxp)
16272 delete_omp_context (gimplify_omp_ctxp);
16273 gimplify_omp_ctxp = NULL;
16276 pop_gimplify_context (outer_bind);
16277 gcc_assert (gimplify_ctxp == NULL);
16279 if (flag_checking && !seen_error ())
16280 verify_gimple_in_seq (gimple_bind_body (outer_bind));
16282 timevar_pop (TV_TREE_GIMPLIFY);
16283 input_location = saved_location;
16285 return outer_bind;
16288 typedef char *char_p; /* For DEF_VEC_P. */
16290 /* Return whether we should exclude FNDECL from instrumentation. */
16292 static bool
16293 flag_instrument_functions_exclude_p (tree fndecl)
16295 vec<char_p> *v;
16297 v = (vec<char_p> *) flag_instrument_functions_exclude_functions;
16298 if (v && v->length () > 0)
16300 const char *name;
16301 int i;
16302 char *s;
16304 name = lang_hooks.decl_printable_name (fndecl, 1);
16305 FOR_EACH_VEC_ELT (*v, i, s)
16306 if (strstr (name, s) != NULL)
16307 return true;
16310 v = (vec<char_p> *) flag_instrument_functions_exclude_files;
16311 if (v && v->length () > 0)
16313 const char *name;
16314 int i;
16315 char *s;
16317 name = DECL_SOURCE_FILE (fndecl);
16318 FOR_EACH_VEC_ELT (*v, i, s)
16319 if (strstr (name, s) != NULL)
16320 return true;
16323 return false;
16326 /* Entry point to the gimplification pass. FNDECL is the FUNCTION_DECL
16327 node for the function we want to gimplify.
16329 Return the sequence of GIMPLE statements corresponding to the body
16330 of FNDECL. */
16332 void
16333 gimplify_function_tree (tree fndecl)
16335 gimple_seq seq;
16336 gbind *bind;
16338 gcc_assert (!gimple_body (fndecl));
16340 if (DECL_STRUCT_FUNCTION (fndecl))
16341 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
16342 else
16343 push_struct_function (fndecl);
16345 /* Tentatively set PROP_gimple_lva here, and reset it in gimplify_va_arg_expr
16346 if necessary. */
16347 cfun->curr_properties |= PROP_gimple_lva;
16349 if (asan_sanitize_use_after_scope ())
16350 asan_poisoned_variables = new hash_set<tree> ();
16351 bind = gimplify_body (fndecl, true);
16352 if (asan_poisoned_variables)
16354 delete asan_poisoned_variables;
16355 asan_poisoned_variables = NULL;
16358 /* The tree body of the function is no longer needed, replace it
16359 with the new GIMPLE body. */
16360 seq = NULL;
16361 gimple_seq_add_stmt (&seq, bind);
16362 gimple_set_body (fndecl, seq);
16364 /* If we're instrumenting function entry/exit, then prepend the call to
16365 the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to
16366 catch the exit hook. */
16367 /* ??? Add some way to ignore exceptions for this TFE. */
16368 if (flag_instrument_function_entry_exit
16369 && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl)
16370 /* Do not instrument extern inline functions. */
16371 && !(DECL_DECLARED_INLINE_P (fndecl)
16372 && DECL_EXTERNAL (fndecl)
16373 && DECL_DISREGARD_INLINE_LIMITS (fndecl))
16374 && !flag_instrument_functions_exclude_p (fndecl))
16376 tree x;
16377 gbind *new_bind;
16378 gimple *tf;
16379 gimple_seq cleanup = NULL, body = NULL;
16380 tree tmp_var, this_fn_addr;
16381 gcall *call;
16383 /* The instrumentation hooks aren't going to call the instrumented
16384 function and the address they receive is expected to be matchable
16385 against symbol addresses. Make sure we don't create a trampoline,
16386 in case the current function is nested. */
16387 this_fn_addr = build_fold_addr_expr (current_function_decl);
16388 TREE_NO_TRAMPOLINE (this_fn_addr) = 1;
16390 x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
16391 call = gimple_build_call (x, 1, integer_zero_node);
16392 tmp_var = create_tmp_var (ptr_type_node, "return_addr");
16393 gimple_call_set_lhs (call, tmp_var);
16394 gimplify_seq_add_stmt (&cleanup, call);
16395 x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_EXIT);
16396 call = gimple_build_call (x, 2, this_fn_addr, tmp_var);
16397 gimplify_seq_add_stmt (&cleanup, call);
16398 tf = gimple_build_try (seq, cleanup, GIMPLE_TRY_FINALLY);
16400 x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
16401 call = gimple_build_call (x, 1, integer_zero_node);
16402 tmp_var = create_tmp_var (ptr_type_node, "return_addr");
16403 gimple_call_set_lhs (call, tmp_var);
16404 gimplify_seq_add_stmt (&body, call);
16405 x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_ENTER);
16406 call = gimple_build_call (x, 2, this_fn_addr, tmp_var);
16407 gimplify_seq_add_stmt (&body, call);
16408 gimplify_seq_add_stmt (&body, tf);
16409 new_bind = gimple_build_bind (NULL, body, NULL);
16411 /* Replace the current function body with the body
16412 wrapped in the try/finally TF. */
16413 seq = NULL;
16414 gimple_seq_add_stmt (&seq, new_bind);
16415 gimple_set_body (fndecl, seq);
16416 bind = new_bind;
16419 if (sanitize_flags_p (SANITIZE_THREAD)
16420 && param_tsan_instrument_func_entry_exit)
16422 gcall *call = gimple_build_call_internal (IFN_TSAN_FUNC_EXIT, 0);
16423 gimple *tf = gimple_build_try (seq, call, GIMPLE_TRY_FINALLY);
16424 gbind *new_bind = gimple_build_bind (NULL, tf, NULL);
16425 /* Replace the current function body with the body
16426 wrapped in the try/finally TF. */
16427 seq = NULL;
16428 gimple_seq_add_stmt (&seq, new_bind);
16429 gimple_set_body (fndecl, seq);
16432 DECL_SAVED_TREE (fndecl) = NULL_TREE;
16433 cfun->curr_properties |= PROP_gimple_any;
16435 pop_cfun ();
16437 dump_function (TDI_gimple, fndecl);
16440 /* Return a dummy expression of type TYPE in order to keep going after an
16441 error. */
16443 static tree
16444 dummy_object (tree type)
16446 tree t = build_int_cst (build_pointer_type (type), 0);
16447 return build2 (MEM_REF, type, t, t);
16450 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
16451 builtin function, but a very special sort of operator. */
16453 enum gimplify_status
16454 gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p,
16455 gimple_seq *post_p ATTRIBUTE_UNUSED)
16457 tree promoted_type, have_va_type;
16458 tree valist = TREE_OPERAND (*expr_p, 0);
16459 tree type = TREE_TYPE (*expr_p);
16460 tree t, tag, aptag;
16461 location_t loc = EXPR_LOCATION (*expr_p);
16463 /* Verify that valist is of the proper type. */
16464 have_va_type = TREE_TYPE (valist);
16465 if (have_va_type == error_mark_node)
16466 return GS_ERROR;
16467 have_va_type = targetm.canonical_va_list_type (have_va_type);
16468 if (have_va_type == NULL_TREE
16469 && POINTER_TYPE_P (TREE_TYPE (valist)))
16470 /* Handle 'Case 1: Not an array type' from c-common.c/build_va_arg. */
16471 have_va_type
16472 = targetm.canonical_va_list_type (TREE_TYPE (TREE_TYPE (valist)));
16473 gcc_assert (have_va_type != NULL_TREE);
16475 /* Generate a diagnostic for requesting data of a type that cannot
16476 be passed through `...' due to type promotion at the call site. */
16477 if ((promoted_type = lang_hooks.types.type_promotes_to (type))
16478 != type)
16480 static bool gave_help;
16481 bool warned;
16482 /* Use the expansion point to handle cases such as passing bool (defined
16483 in a system header) through `...'. */
16484 location_t xloc
16485 = expansion_point_location_if_in_system_header (loc);
16487 /* Unfortunately, this is merely undefined, rather than a constraint
16488 violation, so we cannot make this an error. If this call is never
16489 executed, the program is still strictly conforming. */
16490 auto_diagnostic_group d;
16491 warned = warning_at (xloc, 0,
16492 "%qT is promoted to %qT when passed through %<...%>",
16493 type, promoted_type);
16494 if (!gave_help && warned)
16496 gave_help = true;
16497 inform (xloc, "(so you should pass %qT not %qT to %<va_arg%>)",
16498 promoted_type, type);
16501 /* We can, however, treat "undefined" any way we please.
16502 Call abort to encourage the user to fix the program. */
16503 if (warned)
16504 inform (xloc, "if this code is reached, the program will abort");
16505 /* Before the abort, allow the evaluation of the va_list
16506 expression to exit or longjmp. */
16507 gimplify_and_add (valist, pre_p);
16508 t = build_call_expr_loc (loc,
16509 builtin_decl_implicit (BUILT_IN_TRAP), 0);
16510 gimplify_and_add (t, pre_p);
16512 /* This is dead code, but go ahead and finish so that the
16513 mode of the result comes out right. */
16514 *expr_p = dummy_object (type);
16515 return GS_ALL_DONE;
16518 tag = build_int_cst (build_pointer_type (type), 0);
16519 aptag = build_int_cst (TREE_TYPE (valist), 0);
16521 *expr_p = build_call_expr_internal_loc (loc, IFN_VA_ARG, type, 3,
16522 valist, tag, aptag);
16524 /* Clear the tentatively set PROP_gimple_lva, to indicate that IFN_VA_ARG
16525 needs to be expanded. */
16526 cfun->curr_properties &= ~PROP_gimple_lva;
16528 return GS_OK;
16531 /* Build a new GIMPLE_ASSIGN tuple and append it to the end of *SEQ_P.
16533 DST/SRC are the destination and source respectively. You can pass
16534 ungimplified trees in DST or SRC, in which case they will be
16535 converted to a gimple operand if necessary.
16537 This function returns the newly created GIMPLE_ASSIGN tuple. */
16539 gimple *
16540 gimplify_assign (tree dst, tree src, gimple_seq *seq_p)
16542 tree t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
16543 gimplify_and_add (t, seq_p);
16544 ggc_free (t);
16545 return gimple_seq_last_stmt (*seq_p);
16548 inline hashval_t
16549 gimplify_hasher::hash (const elt_t *p)
16551 tree t = p->val;
16552 return iterative_hash_expr (t, 0);
16555 inline bool
16556 gimplify_hasher::equal (const elt_t *p1, const elt_t *p2)
16558 tree t1 = p1->val;
16559 tree t2 = p2->val;
16560 enum tree_code code = TREE_CODE (t1);
16562 if (TREE_CODE (t2) != code
16563 || TREE_TYPE (t1) != TREE_TYPE (t2))
16564 return false;
16566 if (!operand_equal_p (t1, t2, 0))
16567 return false;
16569 /* Only allow them to compare equal if they also hash equal; otherwise
16570 results are nondeterminate, and we fail bootstrap comparison. */
16571 gcc_checking_assert (hash (p1) == hash (p2));
16573 return true;