1 /* Tree lowering pass. This pass converts the GENERIC functions-as-trees
2 tree representation into the GIMPLE form.
3 Copyright (C) 2002-2023 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
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
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/>. */
25 #include "coretypes.h"
33 #include "gimple-predict.h"
34 #include "tree-pass.h" /* FIXME: only for PROP_gimple_any */
37 #include "tree-pretty-print.h"
38 #include "diagnostic-core.h"
39 #include "diagnostic.h" /* For errorcount. */
41 #include "fold-const.h"
46 #include "gimple-iterator.h"
47 #include "gimple-fold.h"
50 #include "stor-layout.h"
51 #include "print-tree.h"
52 #include "tree-iterator.h"
53 #include "tree-inline.h"
54 #include "langhooks.h"
57 #include "tree-hash-traits.h"
58 #include "omp-general.h"
60 #include "gimple-low.h"
61 #include "gomp-constants.h"
62 #include "splay-tree.h"
63 #include "gimple-walk.h"
64 #include "langhooks-def.h" /* FIXME: for lhd_set_decl_assembler_name */
66 #include "stringpool.h"
70 #include "omp-offload.h"
72 #include "tree-nested.h"
74 /* Hash set of poisoned variables in a bind expr. */
75 static hash_set
<tree
> *asan_poisoned_variables
= NULL
;
77 enum gimplify_omp_var_data
80 GOVD_EXPLICIT
= 0x000002,
81 GOVD_SHARED
= 0x000004,
82 GOVD_PRIVATE
= 0x000008,
83 GOVD_FIRSTPRIVATE
= 0x000010,
84 GOVD_LASTPRIVATE
= 0x000020,
85 GOVD_REDUCTION
= 0x000040,
88 GOVD_DEBUG_PRIVATE
= 0x000200,
89 GOVD_PRIVATE_OUTER_REF
= 0x000400,
90 GOVD_LINEAR
= 0x000800,
91 GOVD_ALIGNED
= 0x001000,
93 /* Flag for GOVD_MAP: don't copy back. */
94 GOVD_MAP_TO_ONLY
= 0x002000,
96 /* Flag for GOVD_LINEAR or GOVD_LASTPRIVATE: no outer reference. */
97 GOVD_LINEAR_LASTPRIVATE_NO_OUTER
= 0x004000,
99 GOVD_MAP_0LEN_ARRAY
= 0x008000,
101 /* Flag for GOVD_MAP, if it is always, to or always, tofrom mapping. */
102 GOVD_MAP_ALWAYS_TO
= 0x010000,
104 /* Flag for shared vars that are or might be stored to in the region. */
105 GOVD_WRITTEN
= 0x020000,
107 /* Flag for GOVD_MAP, if it is a forced mapping. */
108 GOVD_MAP_FORCE
= 0x040000,
110 /* Flag for GOVD_MAP: must be present already. */
111 GOVD_MAP_FORCE_PRESENT
= 0x080000,
113 /* Flag for GOVD_MAP: only allocate. */
114 GOVD_MAP_ALLOC_ONLY
= 0x100000,
116 /* Flag for GOVD_MAP: only copy back. */
117 GOVD_MAP_FROM_ONLY
= 0x200000,
119 GOVD_NONTEMPORAL
= 0x400000,
121 /* Flag for GOVD_LASTPRIVATE: conditional modifier. */
122 GOVD_LASTPRIVATE_CONDITIONAL
= 0x800000,
124 GOVD_CONDTEMP
= 0x1000000,
126 /* Flag for GOVD_REDUCTION: inscan seen in {in,ex}clusive clause. */
127 GOVD_REDUCTION_INSCAN
= 0x2000000,
129 /* Flag for GOVD_FIRSTPRIVATE: OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT. */
130 GOVD_FIRSTPRIVATE_IMPLICIT
= 0x4000000,
132 GOVD_DATA_SHARE_CLASS
= (GOVD_SHARED
| GOVD_PRIVATE
| GOVD_FIRSTPRIVATE
133 | GOVD_LASTPRIVATE
| GOVD_REDUCTION
| GOVD_LINEAR
140 ORT_WORKSHARE
= 0x00,
141 ORT_TASKGROUP
= 0x01,
145 ORT_COMBINED_PARALLEL
= ORT_PARALLEL
| 1,
148 ORT_UNTIED_TASK
= ORT_TASK
| 1,
149 ORT_TASKLOOP
= ORT_TASK
| 2,
150 ORT_UNTIED_TASKLOOP
= ORT_UNTIED_TASK
| 2,
153 ORT_COMBINED_TEAMS
= ORT_TEAMS
| 1,
154 ORT_HOST_TEAMS
= ORT_TEAMS
| 2,
155 ORT_COMBINED_HOST_TEAMS
= ORT_COMBINED_TEAMS
| 2,
158 ORT_TARGET_DATA
= 0x40,
160 /* Data region with offloading. */
162 ORT_COMBINED_TARGET
= ORT_TARGET
| 1,
163 ORT_IMPLICIT_TARGET
= ORT_TARGET
| 2,
165 /* OpenACC variants. */
166 ORT_ACC
= 0x100, /* A generic OpenACC region. */
167 ORT_ACC_DATA
= ORT_ACC
| ORT_TARGET_DATA
, /* Data construct. */
168 ORT_ACC_PARALLEL
= ORT_ACC
| ORT_TARGET
, /* Parallel construct */
169 ORT_ACC_KERNELS
= ORT_ACC
| ORT_TARGET
| 2, /* Kernels construct. */
170 ORT_ACC_SERIAL
= ORT_ACC
| ORT_TARGET
| 4, /* Serial construct. */
171 ORT_ACC_HOST_DATA
= ORT_ACC
| ORT_TARGET_DATA
| 2, /* Host data. */
173 /* Dummy OpenMP region, used to disable expansion of
174 DECL_VALUE_EXPRs in taskloop pre body. */
178 /* Gimplify hashtable helper. */
180 struct gimplify_hasher
: free_ptr_hash
<elt_t
>
182 static inline hashval_t
hash (const elt_t
*);
183 static inline bool equal (const elt_t
*, const elt_t
*);
188 struct gimplify_ctx
*prev_context
;
190 vec
<gbind
*> bind_expr_stack
;
192 gimple_seq conditional_cleanups
;
196 vec
<tree
> case_labels
;
197 hash_set
<tree
> *live_switch_vars
;
198 /* The formal temporary table. Should this be persistent? */
199 hash_table
<gimplify_hasher
> *temp_htab
;
202 unsigned into_ssa
: 1;
203 unsigned allow_rhs_cond_expr
: 1;
204 unsigned in_cleanup_point_expr
: 1;
205 unsigned keep_stack
: 1;
206 unsigned save_stack
: 1;
207 unsigned in_switch_expr
: 1;
210 enum gimplify_defaultmap_kind
213 GDMK_SCALAR_TARGET
, /* w/ Fortran's target attr, implicit mapping, only. */
219 struct gimplify_omp_ctx
221 struct gimplify_omp_ctx
*outer_context
;
222 splay_tree variables
;
223 hash_set
<tree
> *privatized_types
;
225 /* Iteration variables in an OMP_FOR. */
226 vec
<tree
> loop_iter_var
;
228 enum omp_clause_default_kind default_kind
;
229 enum omp_region_type region_type
;
233 bool target_firstprivatize_array_bases
;
235 bool order_concurrent
;
241 static struct gimplify_ctx
*gimplify_ctxp
;
242 static struct gimplify_omp_ctx
*gimplify_omp_ctxp
;
243 static bool in_omp_construct
;
245 /* Forward declaration. */
246 static enum gimplify_status
gimplify_compound_expr (tree
*, gimple_seq
*, bool);
247 static hash_map
<tree
, tree
> *oacc_declare_returns
;
248 static enum gimplify_status
gimplify_expr (tree
*, gimple_seq
*, gimple_seq
*,
249 bool (*) (tree
), fallback_t
, bool);
250 static void prepare_gimple_addressable (tree
*, gimple_seq
*);
252 /* Shorter alias name for the above function for use in gimplify.cc
256 gimplify_seq_add_stmt (gimple_seq
*seq_p
, gimple
*gs
)
258 gimple_seq_add_stmt_without_update (seq_p
, gs
);
261 /* Append sequence SRC to the end of sequence *DST_P. If *DST_P is
262 NULL, a new sequence is allocated. This function is
263 similar to gimple_seq_add_seq, but does not scan the operands.
264 During gimplification, we need to manipulate statement sequences
265 before the def/use vectors have been constructed. */
268 gimplify_seq_add_seq (gimple_seq
*dst_p
, gimple_seq src
)
270 gimple_stmt_iterator si
;
275 si
= gsi_last (*dst_p
);
276 gsi_insert_seq_after_without_update (&si
, src
, GSI_NEW_STMT
);
280 /* Pointer to a list of allocated gimplify_ctx structs to be used for pushing
281 and popping gimplify contexts. */
283 static struct gimplify_ctx
*ctx_pool
= NULL
;
285 /* Return a gimplify context struct from the pool. */
287 static inline struct gimplify_ctx
*
290 struct gimplify_ctx
* c
= ctx_pool
;
293 ctx_pool
= c
->prev_context
;
295 c
= XNEW (struct gimplify_ctx
);
297 memset (c
, '\0', sizeof (*c
));
301 /* Put gimplify context C back into the pool. */
304 ctx_free (struct gimplify_ctx
*c
)
306 c
->prev_context
= ctx_pool
;
310 /* Free allocated ctx stack memory. */
313 free_gimplify_stack (void)
315 struct gimplify_ctx
*c
;
317 while ((c
= ctx_pool
))
319 ctx_pool
= c
->prev_context
;
325 /* Set up a context for the gimplifier. */
328 push_gimplify_context (bool in_ssa
, bool rhs_cond_ok
)
330 struct gimplify_ctx
*c
= ctx_alloc ();
332 c
->prev_context
= gimplify_ctxp
;
334 gimplify_ctxp
->into_ssa
= in_ssa
;
335 gimplify_ctxp
->allow_rhs_cond_expr
= rhs_cond_ok
;
338 /* Tear down a context for the gimplifier. If BODY is non-null, then
339 put the temporaries into the outer BIND_EXPR. Otherwise, put them
342 BODY is not a sequence, but the first tuple in a sequence. */
345 pop_gimplify_context (gimple
*body
)
347 struct gimplify_ctx
*c
= gimplify_ctxp
;
350 && (!c
->bind_expr_stack
.exists ()
351 || c
->bind_expr_stack
.is_empty ()));
352 c
->bind_expr_stack
.release ();
353 gimplify_ctxp
= c
->prev_context
;
356 declare_vars (c
->temps
, body
, false);
358 record_vars (c
->temps
);
365 /* Push a GIMPLE_BIND tuple onto the stack of bindings. */
368 gimple_push_bind_expr (gbind
*bind_stmt
)
370 gimplify_ctxp
->bind_expr_stack
.reserve (8);
371 gimplify_ctxp
->bind_expr_stack
.safe_push (bind_stmt
);
374 /* Pop the first element off the stack of bindings. */
377 gimple_pop_bind_expr (void)
379 gimplify_ctxp
->bind_expr_stack
.pop ();
382 /* Return the first element of the stack of bindings. */
385 gimple_current_bind_expr (void)
387 return gimplify_ctxp
->bind_expr_stack
.last ();
390 /* Return the stack of bindings created during gimplification. */
393 gimple_bind_expr_stack (void)
395 return gimplify_ctxp
->bind_expr_stack
;
398 /* Return true iff there is a COND_EXPR between us and the innermost
399 CLEANUP_POINT_EXPR. This info is used by gimple_push_cleanup. */
402 gimple_conditional_context (void)
404 return gimplify_ctxp
->conditions
> 0;
407 /* Note that we've entered a COND_EXPR. */
410 gimple_push_condition (void)
412 #ifdef ENABLE_GIMPLE_CHECKING
413 if (gimplify_ctxp
->conditions
== 0)
414 gcc_assert (gimple_seq_empty_p (gimplify_ctxp
->conditional_cleanups
));
416 ++(gimplify_ctxp
->conditions
);
419 /* Note that we've left a COND_EXPR. If we're back at unconditional scope
420 now, add any conditional cleanups we've seen to the prequeue. */
423 gimple_pop_condition (gimple_seq
*pre_p
)
425 int conds
= --(gimplify_ctxp
->conditions
);
427 gcc_assert (conds
>= 0);
430 gimplify_seq_add_seq (pre_p
, gimplify_ctxp
->conditional_cleanups
);
431 gimplify_ctxp
->conditional_cleanups
= NULL
;
435 /* A stable comparison routine for use with splay trees and DECLs. */
438 splay_tree_compare_decl_uid (splay_tree_key xa
, splay_tree_key xb
)
443 return DECL_UID (a
) - DECL_UID (b
);
446 /* Create a new omp construct that deals with variable remapping. */
448 static struct gimplify_omp_ctx
*
449 new_omp_context (enum omp_region_type region_type
)
451 struct gimplify_omp_ctx
*c
;
453 c
= XCNEW (struct gimplify_omp_ctx
);
454 c
->outer_context
= gimplify_omp_ctxp
;
455 c
->variables
= splay_tree_new (splay_tree_compare_decl_uid
, 0, 0);
456 c
->privatized_types
= new hash_set
<tree
>;
457 c
->location
= input_location
;
458 c
->region_type
= region_type
;
459 if ((region_type
& ORT_TASK
) == 0)
460 c
->default_kind
= OMP_CLAUSE_DEFAULT_SHARED
;
462 c
->default_kind
= OMP_CLAUSE_DEFAULT_UNSPECIFIED
;
463 c
->defaultmap
[GDMK_SCALAR
] = GOVD_MAP
;
464 c
->defaultmap
[GDMK_SCALAR_TARGET
] = GOVD_MAP
;
465 c
->defaultmap
[GDMK_AGGREGATE
] = GOVD_MAP
;
466 c
->defaultmap
[GDMK_ALLOCATABLE
] = GOVD_MAP
;
467 c
->defaultmap
[GDMK_POINTER
] = GOVD_MAP
;
472 /* Destroy an omp construct that deals with variable remapping. */
475 delete_omp_context (struct gimplify_omp_ctx
*c
)
477 splay_tree_delete (c
->variables
);
478 delete c
->privatized_types
;
479 c
->loop_iter_var
.release ();
483 static void omp_add_variable (struct gimplify_omp_ctx
*, tree
, unsigned int);
484 static bool omp_notice_variable (struct gimplify_omp_ctx
*, tree
, bool);
486 /* Both gimplify the statement T and append it to *SEQ_P. This function
487 behaves exactly as gimplify_stmt, but you don't have to pass T as a
491 gimplify_and_add (tree t
, gimple_seq
*seq_p
)
493 gimplify_stmt (&t
, seq_p
);
496 /* Gimplify statement T into sequence *SEQ_P, and return the first
497 tuple in the sequence of generated tuples for this statement.
498 Return NULL if gimplifying T produced no tuples. */
501 gimplify_and_return_first (tree t
, gimple_seq
*seq_p
)
503 gimple_stmt_iterator last
= gsi_last (*seq_p
);
505 gimplify_and_add (t
, seq_p
);
507 if (!gsi_end_p (last
))
510 return gsi_stmt (last
);
513 return gimple_seq_first_stmt (*seq_p
);
516 /* Returns true iff T is a valid RHS for an assignment to an un-renamed
517 LHS, or for a call argument. */
520 is_gimple_mem_rhs (tree t
)
522 /* If we're dealing with a renamable type, either source or dest must be
523 a renamed variable. */
524 if (is_gimple_reg_type (TREE_TYPE (t
)))
525 return is_gimple_val (t
);
527 return is_gimple_val (t
) || is_gimple_lvalue (t
);
530 /* Return true if T is a CALL_EXPR or an expression that can be
531 assigned to a temporary. Note that this predicate should only be
532 used during gimplification. See the rationale for this in
533 gimplify_modify_expr. */
536 is_gimple_reg_rhs_or_call (tree t
)
538 return (get_gimple_rhs_class (TREE_CODE (t
)) != GIMPLE_INVALID_RHS
539 || TREE_CODE (t
) == CALL_EXPR
);
542 /* Return true if T is a valid memory RHS or a CALL_EXPR. Note that
543 this predicate should only be used during gimplification. See the
544 rationale for this in gimplify_modify_expr. */
547 is_gimple_mem_rhs_or_call (tree t
)
549 /* If we're dealing with a renamable type, either source or dest must be
550 a renamed variable. */
551 if (is_gimple_reg_type (TREE_TYPE (t
)))
552 return is_gimple_val (t
);
554 return (is_gimple_val (t
)
555 || is_gimple_lvalue (t
)
556 || TREE_CLOBBER_P (t
)
557 || TREE_CODE (t
) == CALL_EXPR
);
560 /* Create a temporary with a name derived from VAL. Subroutine of
561 lookup_tmp_var; nobody else should call this function. */
564 create_tmp_from_val (tree val
)
566 /* Drop all qualifiers and address-space information from the value type. */
567 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (val
));
568 tree var
= create_tmp_var (type
, get_name (val
));
572 /* Create a temporary to hold the value of VAL. If IS_FORMAL, try to reuse
573 an existing expression temporary. If NOT_GIMPLE_REG, mark it as such. */
576 lookup_tmp_var (tree val
, bool is_formal
, bool not_gimple_reg
)
580 /* We cannot mark a formal temporary with DECL_NOT_GIMPLE_REG_P. */
581 gcc_assert (!is_formal
|| !not_gimple_reg
);
583 /* If not optimizing, never really reuse a temporary. local-alloc
584 won't allocate any variable that is used in more than one basic
585 block, which means it will go into memory, causing much extra
586 work in reload and final and poorer code generation, outweighing
587 the extra memory allocation here. */
588 if (!optimize
|| !is_formal
|| TREE_SIDE_EFFECTS (val
))
590 ret
= create_tmp_from_val (val
);
591 DECL_NOT_GIMPLE_REG_P (ret
) = not_gimple_reg
;
599 if (!gimplify_ctxp
->temp_htab
)
600 gimplify_ctxp
->temp_htab
= new hash_table
<gimplify_hasher
> (1000);
601 slot
= gimplify_ctxp
->temp_htab
->find_slot (&elt
, INSERT
);
604 elt_p
= XNEW (elt_t
);
606 elt_p
->temp
= ret
= create_tmp_from_val (val
);
619 /* Helper for get_formal_tmp_var and get_initialized_tmp_var. */
622 internal_get_tmp_var (tree val
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
623 bool is_formal
, bool allow_ssa
, bool not_gimple_reg
)
627 /* Notice that we explicitly allow VAL to be a CALL_EXPR so that we
628 can create an INIT_EXPR and convert it into a GIMPLE_CALL below. */
629 gimplify_expr (&val
, pre_p
, post_p
, is_gimple_reg_rhs_or_call
,
633 && gimplify_ctxp
->into_ssa
634 && is_gimple_reg_type (TREE_TYPE (val
)))
636 t
= make_ssa_name (TYPE_MAIN_VARIANT (TREE_TYPE (val
)));
637 if (! gimple_in_ssa_p (cfun
))
639 const char *name
= get_name (val
);
641 SET_SSA_NAME_VAR_OR_IDENTIFIER (t
, create_tmp_var_name (name
));
645 t
= lookup_tmp_var (val
, is_formal
, not_gimple_reg
);
647 mod
= build2 (INIT_EXPR
, TREE_TYPE (t
), t
, unshare_expr (val
));
649 SET_EXPR_LOCATION (mod
, EXPR_LOC_OR_LOC (val
, input_location
));
651 /* gimplify_modify_expr might want to reduce this further. */
652 gimplify_and_add (mod
, pre_p
);
658 /* Return a formal temporary variable initialized with VAL. PRE_P is as
659 in gimplify_expr. Only use this function if:
661 1) The value of the unfactored expression represented by VAL will not
662 change between the initialization and use of the temporary, and
663 2) The temporary will not be otherwise modified.
665 For instance, #1 means that this is inappropriate for SAVE_EXPR temps,
666 and #2 means it is inappropriate for && temps.
668 For other cases, use get_initialized_tmp_var instead. */
671 get_formal_tmp_var (tree val
, gimple_seq
*pre_p
)
673 return internal_get_tmp_var (val
, pre_p
, NULL
, true, true, false);
676 /* Return a temporary variable initialized with VAL. PRE_P and POST_P
677 are as in gimplify_expr. */
680 get_initialized_tmp_var (tree val
, gimple_seq
*pre_p
,
681 gimple_seq
*post_p
/* = NULL */,
682 bool allow_ssa
/* = true */)
684 return internal_get_tmp_var (val
, pre_p
, post_p
, false, allow_ssa
, false);
687 /* Declare all the variables in VARS in SCOPE. If DEBUG_INFO is true,
688 generate debug info for them; otherwise don't. */
691 declare_vars (tree vars
, gimple
*gs
, bool debug_info
)
698 gbind
*scope
= as_a
<gbind
*> (gs
);
700 temps
= nreverse (last
);
702 block
= gimple_bind_block (scope
);
703 gcc_assert (!block
|| TREE_CODE (block
) == BLOCK
);
704 if (!block
|| !debug_info
)
706 DECL_CHAIN (last
) = gimple_bind_vars (scope
);
707 gimple_bind_set_vars (scope
, temps
);
711 /* We need to attach the nodes both to the BIND_EXPR and to its
712 associated BLOCK for debugging purposes. The key point here
713 is that the BLOCK_VARS of the BIND_EXPR_BLOCK of a BIND_EXPR
714 is a subchain of the BIND_EXPR_VARS of the BIND_EXPR. */
715 if (BLOCK_VARS (block
))
716 BLOCK_VARS (block
) = chainon (BLOCK_VARS (block
), temps
);
719 gimple_bind_set_vars (scope
,
720 chainon (gimple_bind_vars (scope
), temps
));
721 BLOCK_VARS (block
) = temps
;
727 /* For VAR a VAR_DECL of variable size, try to find a constant upper bound
728 for the size and adjust DECL_SIZE/DECL_SIZE_UNIT accordingly. Abort if
729 no such upper bound can be obtained. */
732 force_constant_size (tree var
)
734 /* The only attempt we make is by querying the maximum size of objects
735 of the variable's type. */
737 HOST_WIDE_INT max_size
;
739 gcc_assert (VAR_P (var
));
741 max_size
= max_int_size_in_bytes (TREE_TYPE (var
));
743 gcc_assert (max_size
>= 0);
746 = build_int_cst (TREE_TYPE (DECL_SIZE_UNIT (var
)), max_size
);
748 = build_int_cst (TREE_TYPE (DECL_SIZE (var
)), max_size
* BITS_PER_UNIT
);
751 /* Push the temporary variable TMP into the current binding. */
754 gimple_add_tmp_var_fn (struct function
*fn
, tree tmp
)
756 gcc_assert (!DECL_CHAIN (tmp
) && !DECL_SEEN_IN_BIND_EXPR_P (tmp
));
758 /* Later processing assumes that the object size is constant, which might
759 not be true at this point. Force the use of a constant upper bound in
761 if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp
)))
762 force_constant_size (tmp
);
764 DECL_CONTEXT (tmp
) = fn
->decl
;
765 DECL_SEEN_IN_BIND_EXPR_P (tmp
) = 1;
767 record_vars_into (tmp
, fn
->decl
);
770 /* Push the temporary variable TMP into the current binding. */
773 gimple_add_tmp_var (tree tmp
)
775 gcc_assert (!DECL_CHAIN (tmp
) && !DECL_SEEN_IN_BIND_EXPR_P (tmp
));
777 /* Later processing assumes that the object size is constant, which might
778 not be true at this point. Force the use of a constant upper bound in
780 if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp
)))
781 force_constant_size (tmp
);
783 DECL_CONTEXT (tmp
) = current_function_decl
;
784 DECL_SEEN_IN_BIND_EXPR_P (tmp
) = 1;
788 DECL_CHAIN (tmp
) = gimplify_ctxp
->temps
;
789 gimplify_ctxp
->temps
= tmp
;
791 /* Mark temporaries local within the nearest enclosing parallel. */
792 if (gimplify_omp_ctxp
)
794 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
795 int flag
= GOVD_LOCAL
| GOVD_SEEN
;
797 && (ctx
->region_type
== ORT_WORKSHARE
798 || ctx
->region_type
== ORT_TASKGROUP
799 || ctx
->region_type
== ORT_SIMD
800 || ctx
->region_type
== ORT_ACC
))
802 if (ctx
->region_type
== ORT_SIMD
803 && TREE_ADDRESSABLE (tmp
)
804 && !TREE_STATIC (tmp
))
806 if (TREE_CODE (DECL_SIZE_UNIT (tmp
)) != INTEGER_CST
)
807 ctx
->add_safelen1
= true;
808 else if (ctx
->in_for_exprs
)
811 flag
= GOVD_PRIVATE
| GOVD_SEEN
;
814 ctx
= ctx
->outer_context
;
817 omp_add_variable (ctx
, tmp
, flag
);
826 /* This case is for nested functions. We need to expose the locals
828 body_seq
= gimple_body (current_function_decl
);
829 declare_vars (tmp
, gimple_seq_first_stmt (body_seq
), false);
835 /* This page contains routines to unshare tree nodes, i.e. to duplicate tree
836 nodes that are referenced more than once in GENERIC functions. This is
837 necessary because gimplification (translation into GIMPLE) is performed
838 by modifying tree nodes in-place, so gimplication of a shared node in a
839 first context could generate an invalid GIMPLE form in a second context.
841 This is achieved with a simple mark/copy/unmark algorithm that walks the
842 GENERIC representation top-down, marks nodes with TREE_VISITED the first
843 time it encounters them, duplicates them if they already have TREE_VISITED
844 set, and finally removes the TREE_VISITED marks it has set.
846 The algorithm works only at the function level, i.e. it generates a GENERIC
847 representation of a function with no nodes shared within the function when
848 passed a GENERIC function (except for nodes that are allowed to be shared).
850 At the global level, it is also necessary to unshare tree nodes that are
851 referenced in more than one function, for the same aforementioned reason.
852 This requires some cooperation from the front-end. There are 2 strategies:
854 1. Manual unsharing. The front-end needs to call unshare_expr on every
855 expression that might end up being shared across functions.
857 2. Deep unsharing. This is an extension of regular unsharing. Instead
858 of calling unshare_expr on expressions that might be shared across
859 functions, the front-end pre-marks them with TREE_VISITED. This will
860 ensure that they are unshared on the first reference within functions
861 when the regular unsharing algorithm runs. The counterpart is that
862 this algorithm must look deeper than for manual unsharing, which is
863 specified by LANG_HOOKS_DEEP_UNSHARING.
865 If there are only few specific cases of node sharing across functions, it is
866 probably easier for a front-end to unshare the expressions manually. On the
867 contrary, if the expressions generated at the global level are as widespread
868 as expressions generated within functions, deep unsharing is very likely the
871 /* Similar to copy_tree_r but do not copy SAVE_EXPR or TARGET_EXPR nodes.
872 These nodes model computations that must be done once. If we were to
873 unshare something like SAVE_EXPR(i++), the gimplification process would
874 create wrong code. However, if DATA is non-null, it must hold a pointer
875 set that is used to unshare the subtrees of these nodes. */
878 mostly_copy_tree_r (tree
*tp
, int *walk_subtrees
, void *data
)
881 enum tree_code code
= TREE_CODE (t
);
883 /* Do not copy SAVE_EXPR, TARGET_EXPR or BIND_EXPR nodes themselves, but
884 copy their subtrees if we can make sure to do it only once. */
885 if (code
== SAVE_EXPR
|| code
== TARGET_EXPR
|| code
== BIND_EXPR
)
887 if (data
&& !((hash_set
<tree
> *)data
)->add (t
))
893 /* Stop at types, decls, constants like copy_tree_r. */
894 else if (TREE_CODE_CLASS (code
) == tcc_type
895 || TREE_CODE_CLASS (code
) == tcc_declaration
896 || TREE_CODE_CLASS (code
) == tcc_constant
)
899 /* Cope with the statement expression extension. */
900 else if (code
== STATEMENT_LIST
)
903 /* Leave the bulk of the work to copy_tree_r itself. */
905 copy_tree_r (tp
, walk_subtrees
, NULL
);
910 /* Callback for walk_tree to unshare most of the shared trees rooted at *TP.
911 If *TP has been visited already, then *TP is deeply copied by calling
912 mostly_copy_tree_r. DATA is passed to mostly_copy_tree_r unmodified. */
915 copy_if_shared_r (tree
*tp
, int *walk_subtrees
, void *data
)
918 enum tree_code code
= TREE_CODE (t
);
920 /* Skip types, decls, and constants. But we do want to look at their
921 types and the bounds of types. Mark them as visited so we properly
922 unmark their subtrees on the unmark pass. If we've already seen them,
923 don't look down further. */
924 if (TREE_CODE_CLASS (code
) == tcc_type
925 || TREE_CODE_CLASS (code
) == tcc_declaration
926 || TREE_CODE_CLASS (code
) == tcc_constant
)
928 if (TREE_VISITED (t
))
931 TREE_VISITED (t
) = 1;
934 /* If this node has been visited already, unshare it and don't look
936 else if (TREE_VISITED (t
))
938 walk_tree (tp
, mostly_copy_tree_r
, data
, NULL
);
942 /* Otherwise, mark the node as visited and keep looking. */
944 TREE_VISITED (t
) = 1;
949 /* Unshare most of the shared trees rooted at *TP. DATA is passed to the
950 copy_if_shared_r callback unmodified. */
953 copy_if_shared (tree
*tp
, void *data
)
955 walk_tree (tp
, copy_if_shared_r
, data
, NULL
);
958 /* Unshare all the trees in the body of FNDECL, as well as in the bodies of
959 any nested functions. */
962 unshare_body (tree fndecl
)
964 struct cgraph_node
*cgn
= cgraph_node::get (fndecl
);
965 /* If the language requires deep unsharing, we need a pointer set to make
966 sure we don't repeatedly unshare subtrees of unshareable nodes. */
967 hash_set
<tree
> *visited
968 = lang_hooks
.deep_unsharing
? new hash_set
<tree
> : NULL
;
970 copy_if_shared (&DECL_SAVED_TREE (fndecl
), visited
);
971 copy_if_shared (&DECL_SIZE (DECL_RESULT (fndecl
)), visited
);
972 copy_if_shared (&DECL_SIZE_UNIT (DECL_RESULT (fndecl
)), visited
);
977 for (cgn
= first_nested_function (cgn
); cgn
;
978 cgn
= next_nested_function (cgn
))
979 unshare_body (cgn
->decl
);
982 /* Callback for walk_tree to unmark the visited trees rooted at *TP.
983 Subtrees are walked until the first unvisited node is encountered. */
986 unmark_visited_r (tree
*tp
, int *walk_subtrees
, void *data ATTRIBUTE_UNUSED
)
990 /* If this node has been visited, unmark it and keep looking. */
991 if (TREE_VISITED (t
))
992 TREE_VISITED (t
) = 0;
994 /* Otherwise, don't look any deeper. */
1001 /* Unmark the visited trees rooted at *TP. */
1004 unmark_visited (tree
*tp
)
1006 walk_tree (tp
, unmark_visited_r
, NULL
, NULL
);
1009 /* Likewise, but mark all trees as not visited. */
1012 unvisit_body (tree fndecl
)
1014 struct cgraph_node
*cgn
= cgraph_node::get (fndecl
);
1016 unmark_visited (&DECL_SAVED_TREE (fndecl
));
1017 unmark_visited (&DECL_SIZE (DECL_RESULT (fndecl
)));
1018 unmark_visited (&DECL_SIZE_UNIT (DECL_RESULT (fndecl
)));
1021 for (cgn
= first_nested_function (cgn
);
1022 cgn
; cgn
= next_nested_function (cgn
))
1023 unvisit_body (cgn
->decl
);
1026 /* Unconditionally make an unshared copy of EXPR. This is used when using
1027 stored expressions which span multiple functions, such as BINFO_VTABLE,
1028 as the normal unsharing process can't tell that they're shared. */
1031 unshare_expr (tree expr
)
1033 walk_tree (&expr
, mostly_copy_tree_r
, NULL
, NULL
);
1037 /* Worker for unshare_expr_without_location. */
1040 prune_expr_location (tree
*tp
, int *walk_subtrees
, void *)
1043 SET_EXPR_LOCATION (*tp
, UNKNOWN_LOCATION
);
1049 /* Similar to unshare_expr but also prune all expression locations
1053 unshare_expr_without_location (tree expr
)
1055 walk_tree (&expr
, mostly_copy_tree_r
, NULL
, NULL
);
1057 walk_tree (&expr
, prune_expr_location
, NULL
, NULL
);
1061 /* Return the EXPR_LOCATION of EXPR, if it (maybe recursively) has
1062 one, OR_ELSE otherwise. The location of a STATEMENT_LISTs
1063 comprising at least one DEBUG_BEGIN_STMT followed by exactly one
1064 EXPR is the location of the EXPR. */
1067 rexpr_location (tree expr
, location_t or_else
= UNKNOWN_LOCATION
)
1072 if (EXPR_HAS_LOCATION (expr
))
1073 return EXPR_LOCATION (expr
);
1075 if (TREE_CODE (expr
) != STATEMENT_LIST
)
1078 tree_stmt_iterator i
= tsi_start (expr
);
1081 while (!tsi_end_p (i
) && TREE_CODE (tsi_stmt (i
)) == DEBUG_BEGIN_STMT
)
1087 if (!found
|| !tsi_one_before_end_p (i
))
1090 return rexpr_location (tsi_stmt (i
), or_else
);
1093 /* Return TRUE iff EXPR (maybe recursively) has a location; see
1094 rexpr_location for the potential recursion. */
1097 rexpr_has_location (tree expr
)
1099 return rexpr_location (expr
) != UNKNOWN_LOCATION
;
1103 /* WRAPPER is a code such as BIND_EXPR or CLEANUP_POINT_EXPR which can both
1104 contain statements and have a value. Assign its value to a temporary
1105 and give it void_type_node. Return the temporary, or NULL_TREE if
1106 WRAPPER was already void. */
1109 voidify_wrapper_expr (tree wrapper
, tree temp
)
1111 tree type
= TREE_TYPE (wrapper
);
1112 if (type
&& !VOID_TYPE_P (type
))
1116 /* Set p to point to the body of the wrapper. Loop until we find
1117 something that isn't a wrapper. */
1118 for (p
= &wrapper
; p
&& *p
; )
1120 switch (TREE_CODE (*p
))
1123 TREE_SIDE_EFFECTS (*p
) = 1;
1124 TREE_TYPE (*p
) = void_type_node
;
1125 /* For a BIND_EXPR, the body is operand 1. */
1126 p
= &BIND_EXPR_BODY (*p
);
1129 case CLEANUP_POINT_EXPR
:
1130 case TRY_FINALLY_EXPR
:
1131 case TRY_CATCH_EXPR
:
1132 TREE_SIDE_EFFECTS (*p
) = 1;
1133 TREE_TYPE (*p
) = void_type_node
;
1134 p
= &TREE_OPERAND (*p
, 0);
1137 case STATEMENT_LIST
:
1139 tree_stmt_iterator i
= tsi_last (*p
);
1140 TREE_SIDE_EFFECTS (*p
) = 1;
1141 TREE_TYPE (*p
) = void_type_node
;
1142 p
= tsi_end_p (i
) ? NULL
: tsi_stmt_ptr (i
);
1147 /* Advance to the last statement. Set all container types to
1149 for (; TREE_CODE (*p
) == COMPOUND_EXPR
; p
= &TREE_OPERAND (*p
, 1))
1151 TREE_SIDE_EFFECTS (*p
) = 1;
1152 TREE_TYPE (*p
) = void_type_node
;
1156 case TRANSACTION_EXPR
:
1157 TREE_SIDE_EFFECTS (*p
) = 1;
1158 TREE_TYPE (*p
) = void_type_node
;
1159 p
= &TRANSACTION_EXPR_BODY (*p
);
1163 /* Assume that any tree upon which voidify_wrapper_expr is
1164 directly called is a wrapper, and that its body is op0. */
1167 TREE_SIDE_EFFECTS (*p
) = 1;
1168 TREE_TYPE (*p
) = void_type_node
;
1169 p
= &TREE_OPERAND (*p
, 0);
1177 if (p
== NULL
|| IS_EMPTY_STMT (*p
))
1181 /* The wrapper is on the RHS of an assignment that we're pushing
1183 gcc_assert (TREE_CODE (temp
) == INIT_EXPR
1184 || TREE_CODE (temp
) == MODIFY_EXPR
);
1185 TREE_OPERAND (temp
, 1) = *p
;
1190 temp
= create_tmp_var (type
, "retval");
1191 *p
= build2 (INIT_EXPR
, type
, temp
, *p
);
1200 /* Prepare calls to builtins to SAVE and RESTORE the stack as well as
1201 a temporary through which they communicate. */
1204 build_stack_save_restore (gcall
**save
, gcall
**restore
)
1208 *save
= gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_SAVE
), 0);
1209 tmp_var
= create_tmp_var (ptr_type_node
, "saved_stack");
1210 gimple_call_set_lhs (*save
, tmp_var
);
1213 = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_RESTORE
),
1217 /* Generate IFN_ASAN_MARK call that poisons shadow of a for DECL variable. */
1220 build_asan_poison_call_expr (tree decl
)
1222 /* Do not poison variables that have size equal to zero. */
1223 tree unit_size
= DECL_SIZE_UNIT (decl
);
1224 if (zerop (unit_size
))
1227 tree base
= build_fold_addr_expr (decl
);
1229 return build_call_expr_internal_loc (UNKNOWN_LOCATION
, IFN_ASAN_MARK
,
1231 build_int_cst (integer_type_node
,
1236 /* Generate IFN_ASAN_MARK call that would poison or unpoison, depending
1237 on POISON flag, shadow memory of a DECL variable. The call will be
1238 put on location identified by IT iterator, where BEFORE flag drives
1239 position where the stmt will be put. */
1242 asan_poison_variable (tree decl
, bool poison
, gimple_stmt_iterator
*it
,
1245 tree unit_size
= DECL_SIZE_UNIT (decl
);
1246 tree base
= build_fold_addr_expr (decl
);
1248 /* Do not poison variables that have size equal to zero. */
1249 if (zerop (unit_size
))
1252 /* It's necessary to have all stack variables aligned to ASAN granularity
1254 gcc_assert (!hwasan_sanitize_p () || hwasan_sanitize_stack_p ());
1255 unsigned shadow_granularity
1256 = hwasan_sanitize_p () ? HWASAN_TAG_GRANULE_SIZE
: ASAN_SHADOW_GRANULARITY
;
1257 if (DECL_ALIGN_UNIT (decl
) <= shadow_granularity
)
1258 SET_DECL_ALIGN (decl
, BITS_PER_UNIT
* shadow_granularity
);
1260 HOST_WIDE_INT flags
= poison
? ASAN_MARK_POISON
: ASAN_MARK_UNPOISON
;
1263 = gimple_build_call_internal (IFN_ASAN_MARK
, 3,
1264 build_int_cst (integer_type_node
, flags
),
1268 gsi_insert_before (it
, g
, GSI_NEW_STMT
);
1270 gsi_insert_after (it
, g
, GSI_NEW_STMT
);
1273 /* Generate IFN_ASAN_MARK internal call that depending on POISON flag
1274 either poisons or unpoisons a DECL. Created statement is appended
1275 to SEQ_P gimple sequence. */
1278 asan_poison_variable (tree decl
, bool poison
, gimple_seq
*seq_p
)
1280 gimple_stmt_iterator it
= gsi_last (*seq_p
);
1281 bool before
= false;
1286 asan_poison_variable (decl
, poison
, &it
, before
);
1289 /* Sort pair of VAR_DECLs A and B by DECL_UID. */
1292 sort_by_decl_uid (const void *a
, const void *b
)
1294 const tree
*t1
= (const tree
*)a
;
1295 const tree
*t2
= (const tree
*)b
;
1297 int uid1
= DECL_UID (*t1
);
1298 int uid2
= DECL_UID (*t2
);
1302 else if (uid1
> uid2
)
1308 /* Generate IFN_ASAN_MARK internal call for all VARIABLES
1309 depending on POISON flag. Created statement is appended
1310 to SEQ_P gimple sequence. */
1313 asan_poison_variables (hash_set
<tree
> *variables
, bool poison
, gimple_seq
*seq_p
)
1315 unsigned c
= variables
->elements ();
1319 auto_vec
<tree
> sorted_variables (c
);
1321 for (hash_set
<tree
>::iterator it
= variables
->begin ();
1322 it
!= variables
->end (); ++it
)
1323 sorted_variables
.safe_push (*it
);
1325 sorted_variables
.qsort (sort_by_decl_uid
);
1329 FOR_EACH_VEC_ELT (sorted_variables
, i
, var
)
1331 asan_poison_variable (var
, poison
, seq_p
);
1333 /* Add use_after_scope_memory attribute for the variable in order
1334 to prevent re-written into SSA. */
1335 if (!lookup_attribute (ASAN_USE_AFTER_SCOPE_ATTRIBUTE
,
1336 DECL_ATTRIBUTES (var
)))
1337 DECL_ATTRIBUTES (var
)
1338 = tree_cons (get_identifier (ASAN_USE_AFTER_SCOPE_ATTRIBUTE
),
1340 DECL_ATTRIBUTES (var
));
1344 /* Gimplify a BIND_EXPR. Just voidify and recurse. */
1346 static enum gimplify_status
1347 gimplify_bind_expr (tree
*expr_p
, gimple_seq
*pre_p
)
1349 tree bind_expr
= *expr_p
;
1350 bool old_keep_stack
= gimplify_ctxp
->keep_stack
;
1351 bool old_save_stack
= gimplify_ctxp
->save_stack
;
1354 gimple_seq body
, cleanup
;
1356 location_t start_locus
= 0, end_locus
= 0;
1357 tree ret_clauses
= NULL
;
1359 tree temp
= voidify_wrapper_expr (bind_expr
, NULL
);
1361 /* Mark variables seen in this bind expr. */
1362 for (t
= BIND_EXPR_VARS (bind_expr
); t
; t
= DECL_CHAIN (t
))
1366 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
1370 && !is_global_var (t
)
1371 && DECL_CONTEXT (t
) == current_function_decl
1373 && (attr
= lookup_attribute ("omp allocate", DECL_ATTRIBUTES (t
)))
1376 gcc_assert (!DECL_HAS_VALUE_EXPR_P (t
));
1377 tree alloc
= TREE_PURPOSE (TREE_VALUE (attr
));
1378 tree align
= TREE_VALUE (TREE_VALUE (attr
));
1379 /* Allocate directives that appear in a target region must specify
1380 an allocator clause unless a requires directive with the
1381 dynamic_allocators clause is present in the same compilation
1383 bool missing_dyn_alloc
= false;
1384 if (alloc
== NULL_TREE
1385 && ((omp_requires_mask
& OMP_REQUIRES_DYNAMIC_ALLOCATORS
)
1388 /* This comes too early for omp_discover_declare_target...,
1389 but should at least catch the most common cases. */
1391 = cgraph_node::get (current_function_decl
)->offloadable
;
1392 for (struct gimplify_omp_ctx
*ctx2
= ctx
;
1393 ctx2
&& !missing_dyn_alloc
; ctx2
= ctx2
->outer_context
)
1394 if (ctx2
->code
== OMP_TARGET
)
1395 missing_dyn_alloc
= true;
1397 if (missing_dyn_alloc
)
1398 error_at (DECL_SOURCE_LOCATION (t
),
1399 "%<allocate%> directive for %qD inside a target "
1400 "region must specify an %<allocator%> clause", t
);
1401 /* Skip for omp_default_mem_alloc (= 1),
1402 unless align is present. */
1403 else if (!errorcount
1404 && (align
!= NULL_TREE
1405 || alloc
== NULL_TREE
1406 || !integer_onep (alloc
)))
1408 tree tmp
= build_pointer_type (TREE_TYPE (t
));
1409 tree v
= create_tmp_var (tmp
, get_name (t
));
1410 DECL_IGNORED_P (v
) = 0;
1411 tmp
= remove_attribute ("omp allocate", DECL_ATTRIBUTES (t
));
1413 = tree_cons (get_identifier ("omp allocate var"),
1414 build_tree_list (NULL_TREE
, t
), tmp
);
1415 tmp
= build_fold_indirect_ref (v
);
1416 TREE_THIS_NOTRAP (tmp
) = 1;
1417 SET_DECL_VALUE_EXPR (t
, tmp
);
1418 DECL_HAS_VALUE_EXPR_P (t
) = 1;
1419 tree sz
= TYPE_SIZE_UNIT (TREE_TYPE (t
));
1420 if (alloc
== NULL_TREE
)
1421 alloc
= build_zero_cst (ptr_type_node
);
1422 if (align
== NULL_TREE
)
1423 align
= build_int_cst (size_type_node
, DECL_ALIGN_UNIT (t
));
1425 align
= build_int_cst (size_type_node
,
1426 MAX (tree_to_uhwi (align
),
1427 DECL_ALIGN_UNIT (t
)));
1428 tmp
= builtin_decl_explicit (BUILT_IN_GOMP_ALLOC
);
1429 tmp
= build_call_expr_loc (DECL_SOURCE_LOCATION (t
), tmp
,
1430 3, align
, sz
, alloc
);
1431 tmp
= fold_build2_loc (DECL_SOURCE_LOCATION (t
), MODIFY_EXPR
,
1433 fold_convert (TREE_TYPE (v
), tmp
));
1434 gcc_assert (BIND_EXPR_BODY (bind_expr
) != NULL_TREE
1435 && (TREE_CODE (BIND_EXPR_BODY (bind_expr
))
1436 == STATEMENT_LIST
));
1437 tree_stmt_iterator e
= tsi_start (BIND_EXPR_BODY (bind_expr
));
1438 while (!tsi_end_p (e
))
1440 if ((TREE_CODE (*e
) == DECL_EXPR
1441 && TREE_OPERAND (*e
, 0) == t
)
1442 || (TREE_CODE (*e
) == CLEANUP_POINT_EXPR
1443 && TREE_CODE (TREE_OPERAND (*e
, 0)) == DECL_EXPR
1444 && TREE_OPERAND (TREE_OPERAND (*e
, 0), 0) == t
))
1448 gcc_assert (!tsi_end_p (e
));
1449 tsi_link_before (&e
, tmp
, TSI_SAME_STMT
);
1453 /* Mark variable as local. */
1454 if (ctx
&& ctx
->region_type
!= ORT_NONE
&& !DECL_EXTERNAL (t
))
1456 if (! DECL_SEEN_IN_BIND_EXPR_P (t
)
1457 || splay_tree_lookup (ctx
->variables
,
1458 (splay_tree_key
) t
) == NULL
)
1460 int flag
= GOVD_LOCAL
;
1461 if (ctx
->region_type
== ORT_SIMD
1462 && TREE_ADDRESSABLE (t
)
1463 && !TREE_STATIC (t
))
1465 if (TREE_CODE (DECL_SIZE_UNIT (t
)) != INTEGER_CST
)
1466 ctx
->add_safelen1
= true;
1468 flag
= GOVD_PRIVATE
;
1470 omp_add_variable (ctx
, t
, flag
| GOVD_SEEN
);
1472 /* Static locals inside of target construct or offloaded
1473 routines need to be "omp declare target". */
1474 if (TREE_STATIC (t
))
1475 for (; ctx
; ctx
= ctx
->outer_context
)
1476 if ((ctx
->region_type
& ORT_TARGET
) != 0)
1478 if (!lookup_attribute ("omp declare target",
1479 DECL_ATTRIBUTES (t
)))
1481 tree id
= get_identifier ("omp declare target");
1483 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
1484 varpool_node
*node
= varpool_node::get (t
);
1487 node
->offloadable
= 1;
1488 if (ENABLE_OFFLOADING
&& !DECL_EXTERNAL (t
))
1490 g
->have_offload
= true;
1492 vec_safe_push (offload_vars
, t
);
1500 DECL_SEEN_IN_BIND_EXPR_P (t
) = 1;
1502 if (DECL_HARD_REGISTER (t
) && !is_global_var (t
) && cfun
)
1503 cfun
->has_local_explicit_reg_vars
= true;
1507 bind_stmt
= gimple_build_bind (BIND_EXPR_VARS (bind_expr
), NULL
,
1508 BIND_EXPR_BLOCK (bind_expr
));
1509 gimple_push_bind_expr (bind_stmt
);
1511 gimplify_ctxp
->keep_stack
= false;
1512 gimplify_ctxp
->save_stack
= false;
1514 /* Gimplify the body into the GIMPLE_BIND tuple's body. */
1516 gimplify_stmt (&BIND_EXPR_BODY (bind_expr
), &body
);
1517 gimple_bind_set_body (bind_stmt
, body
);
1519 /* Source location wise, the cleanup code (stack_restore and clobbers)
1520 belongs to the end of the block, so propagate what we have. The
1521 stack_save operation belongs to the beginning of block, which we can
1522 infer from the bind_expr directly if the block has no explicit
1524 if (BIND_EXPR_BLOCK (bind_expr
))
1526 end_locus
= BLOCK_SOURCE_END_LOCATION (BIND_EXPR_BLOCK (bind_expr
));
1527 start_locus
= BLOCK_SOURCE_LOCATION (BIND_EXPR_BLOCK (bind_expr
));
1529 if (start_locus
== 0)
1530 start_locus
= EXPR_LOCATION (bind_expr
);
1535 /* Add clobbers for all variables that go out of scope. */
1536 for (t
= BIND_EXPR_VARS (bind_expr
); t
; t
= DECL_CHAIN (t
))
1539 && !is_global_var (t
)
1540 && DECL_CONTEXT (t
) == current_function_decl
)
1543 && DECL_HAS_VALUE_EXPR_P (t
)
1545 && lookup_attribute ("omp allocate", DECL_ATTRIBUTES (t
)))
1547 tree tmp
= builtin_decl_explicit (BUILT_IN_GOMP_FREE
);
1548 tmp
= build_call_expr_loc (end_locus
, tmp
, 2,
1549 TREE_OPERAND (DECL_VALUE_EXPR (t
), 0),
1550 build_zero_cst (ptr_type_node
));
1551 gimplify_and_add (tmp
, &cleanup
);
1553 if (!DECL_HARD_REGISTER (t
)
1554 && !TREE_THIS_VOLATILE (t
)
1555 && !DECL_HAS_VALUE_EXPR_P (t
)
1556 /* Only care for variables that have to be in memory. Others
1557 will be rewritten into SSA names, hence moved to the
1559 && !is_gimple_reg (t
)
1560 && flag_stack_reuse
!= SR_NONE
)
1562 tree clobber
= build_clobber (TREE_TYPE (t
), CLOBBER_EOL
);
1563 gimple
*clobber_stmt
;
1564 clobber_stmt
= gimple_build_assign (t
, clobber
);
1565 gimple_set_location (clobber_stmt
, end_locus
);
1566 gimplify_seq_add_stmt (&cleanup
, clobber_stmt
);
1569 if (flag_openacc
&& oacc_declare_returns
!= NULL
)
1572 if (DECL_HAS_VALUE_EXPR_P (key
))
1574 key
= DECL_VALUE_EXPR (key
);
1575 if (INDIRECT_REF_P (key
))
1576 key
= TREE_OPERAND (key
, 0);
1578 tree
*c
= oacc_declare_returns
->get (key
);
1582 OMP_CLAUSE_CHAIN (*c
) = ret_clauses
;
1584 ret_clauses
= unshare_expr (*c
);
1586 oacc_declare_returns
->remove (key
);
1588 if (oacc_declare_returns
->is_empty ())
1590 delete oacc_declare_returns
;
1591 oacc_declare_returns
= NULL
;
1597 if (asan_poisoned_variables
!= NULL
1598 && asan_poisoned_variables
->contains (t
))
1600 asan_poisoned_variables
->remove (t
);
1601 asan_poison_variable (t
, true, &cleanup
);
1604 if (gimplify_ctxp
->live_switch_vars
!= NULL
1605 && gimplify_ctxp
->live_switch_vars
->contains (t
))
1606 gimplify_ctxp
->live_switch_vars
->remove (t
);
1609 /* If the code both contains VLAs and calls alloca, then we cannot reclaim
1610 the stack space allocated to the VLAs. */
1611 if (gimplify_ctxp
->save_stack
&& !gimplify_ctxp
->keep_stack
)
1613 gcall
*stack_restore
;
1615 /* Save stack on entry and restore it on exit. Add a try_finally
1616 block to achieve this. */
1617 build_stack_save_restore (&stack_save
, &stack_restore
);
1619 gimple_set_location (stack_save
, start_locus
);
1620 gimple_set_location (stack_restore
, end_locus
);
1622 gimplify_seq_add_stmt (&cleanup
, stack_restore
);
1628 gimple_stmt_iterator si
= gsi_start (cleanup
);
1630 stmt
= gimple_build_omp_target (NULL
, GF_OMP_TARGET_KIND_OACC_DECLARE
,
1632 gsi_insert_seq_before_without_update (&si
, stmt
, GSI_NEW_STMT
);
1638 gimple_seq new_body
;
1641 gs
= gimple_build_try (gimple_bind_body (bind_stmt
), cleanup
,
1642 GIMPLE_TRY_FINALLY
);
1645 gimplify_seq_add_stmt (&new_body
, stack_save
);
1646 gimplify_seq_add_stmt (&new_body
, gs
);
1647 gimple_bind_set_body (bind_stmt
, new_body
);
1650 /* keep_stack propagates all the way up to the outermost BIND_EXPR. */
1651 if (!gimplify_ctxp
->keep_stack
)
1652 gimplify_ctxp
->keep_stack
= old_keep_stack
;
1653 gimplify_ctxp
->save_stack
= old_save_stack
;
1655 gimple_pop_bind_expr ();
1657 gimplify_seq_add_stmt (pre_p
, bind_stmt
);
1665 *expr_p
= NULL_TREE
;
1669 /* Maybe add early return predict statement to PRE_P sequence. */
1672 maybe_add_early_return_predict_stmt (gimple_seq
*pre_p
)
1674 /* If we are not in a conditional context, add PREDICT statement. */
1675 if (gimple_conditional_context ())
1677 gimple
*predict
= gimple_build_predict (PRED_TREE_EARLY_RETURN
,
1679 gimplify_seq_add_stmt (pre_p
, predict
);
1683 /* Gimplify a RETURN_EXPR. If the expression to be returned is not a
1684 GIMPLE value, it is assigned to a new temporary and the statement is
1685 re-written to return the temporary.
1687 PRE_P points to the sequence where side effects that must happen before
1688 STMT should be stored. */
1690 static enum gimplify_status
1691 gimplify_return_expr (tree stmt
, gimple_seq
*pre_p
)
1694 tree ret_expr
= TREE_OPERAND (stmt
, 0);
1695 tree result_decl
, result
;
1697 if (ret_expr
== error_mark_node
)
1701 || TREE_CODE (ret_expr
) == RESULT_DECL
)
1703 maybe_add_early_return_predict_stmt (pre_p
);
1704 greturn
*ret
= gimple_build_return (ret_expr
);
1705 copy_warning (ret
, stmt
);
1706 gimplify_seq_add_stmt (pre_p
, ret
);
1710 if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl
))))
1711 result_decl
= NULL_TREE
;
1712 else if (TREE_CODE (ret_expr
) == COMPOUND_EXPR
)
1714 /* Used in C++ for handling EH cleanup of the return value if a local
1715 cleanup throws. Assume the front-end knows what it's doing. */
1716 result_decl
= DECL_RESULT (current_function_decl
);
1717 /* But crash if we end up trying to modify ret_expr below. */
1718 ret_expr
= NULL_TREE
;
1722 result_decl
= TREE_OPERAND (ret_expr
, 0);
1724 /* See through a return by reference. */
1725 if (INDIRECT_REF_P (result_decl
))
1726 result_decl
= TREE_OPERAND (result_decl
, 0);
1728 gcc_assert ((TREE_CODE (ret_expr
) == MODIFY_EXPR
1729 || TREE_CODE (ret_expr
) == INIT_EXPR
)
1730 && TREE_CODE (result_decl
) == RESULT_DECL
);
1733 /* If aggregate_value_p is true, then we can return the bare RESULT_DECL.
1734 Recall that aggregate_value_p is FALSE for any aggregate type that is
1735 returned in registers. If we're returning values in registers, then
1736 we don't want to extend the lifetime of the RESULT_DECL, particularly
1737 across another call. In addition, for those aggregates for which
1738 hard_function_value generates a PARALLEL, we'll die during normal
1739 expansion of structure assignments; there's special code in expand_return
1740 to handle this case that does not exist in expand_expr. */
1743 else if (aggregate_value_p (result_decl
, TREE_TYPE (current_function_decl
)))
1745 if (!poly_int_tree_p (DECL_SIZE (result_decl
)))
1747 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (result_decl
)))
1748 gimplify_type_sizes (TREE_TYPE (result_decl
), pre_p
);
1749 /* Note that we don't use gimplify_vla_decl because the RESULT_DECL
1750 should be effectively allocated by the caller, i.e. all calls to
1751 this function must be subject to the Return Slot Optimization. */
1752 gimplify_one_sizepos (&DECL_SIZE (result_decl
), pre_p
);
1753 gimplify_one_sizepos (&DECL_SIZE_UNIT (result_decl
), pre_p
);
1755 result
= result_decl
;
1757 else if (gimplify_ctxp
->return_temp
)
1758 result
= gimplify_ctxp
->return_temp
;
1761 result
= create_tmp_reg (TREE_TYPE (result_decl
));
1763 /* ??? With complex control flow (usually involving abnormal edges),
1764 we can wind up warning about an uninitialized value for this. Due
1765 to how this variable is constructed and initialized, this is never
1766 true. Give up and never warn. */
1767 suppress_warning (result
, OPT_Wuninitialized
);
1769 gimplify_ctxp
->return_temp
= result
;
1772 /* Smash the lhs of the MODIFY_EXPR to the temporary we plan to use.
1773 Then gimplify the whole thing. */
1774 if (result
!= result_decl
)
1775 TREE_OPERAND (ret_expr
, 0) = result
;
1777 gimplify_and_add (TREE_OPERAND (stmt
, 0), pre_p
);
1779 maybe_add_early_return_predict_stmt (pre_p
);
1780 ret
= gimple_build_return (result
);
1781 copy_warning (ret
, stmt
);
1782 gimplify_seq_add_stmt (pre_p
, ret
);
1787 /* Gimplify a variable-length array DECL. */
1790 gimplify_vla_decl (tree decl
, gimple_seq
*seq_p
)
1792 /* This is a variable-sized decl. Simplify its size and mark it
1793 for deferred expansion. */
1794 tree t
, addr
, ptr_type
;
1796 gimplify_one_sizepos (&DECL_SIZE (decl
), seq_p
);
1797 gimplify_one_sizepos (&DECL_SIZE_UNIT (decl
), seq_p
);
1799 /* Don't mess with a DECL_VALUE_EXPR set by the front-end. */
1800 if (DECL_HAS_VALUE_EXPR_P (decl
))
1803 /* All occurrences of this decl in final gimplified code will be
1804 replaced by indirection. Setting DECL_VALUE_EXPR does two
1805 things: First, it lets the rest of the gimplifier know what
1806 replacement to use. Second, it lets the debug info know
1807 where to find the value. */
1808 ptr_type
= build_pointer_type (TREE_TYPE (decl
));
1809 addr
= create_tmp_var (ptr_type
, get_name (decl
));
1810 DECL_IGNORED_P (addr
) = 0;
1811 t
= build_fold_indirect_ref (addr
);
1812 TREE_THIS_NOTRAP (t
) = 1;
1813 SET_DECL_VALUE_EXPR (decl
, t
);
1814 DECL_HAS_VALUE_EXPR_P (decl
) = 1;
1816 t
= build_alloca_call_expr (DECL_SIZE_UNIT (decl
), DECL_ALIGN (decl
),
1817 max_int_size_in_bytes (TREE_TYPE (decl
)));
1818 /* The call has been built for a variable-sized object. */
1819 CALL_ALLOCA_FOR_VAR_P (t
) = 1;
1820 t
= fold_convert (ptr_type
, t
);
1821 t
= build2 (MODIFY_EXPR
, TREE_TYPE (addr
), addr
, t
);
1823 gimplify_and_add (t
, seq_p
);
1825 /* Record the dynamic allocation associated with DECL if requested. */
1826 if (flag_callgraph_info
& CALLGRAPH_INFO_DYNAMIC_ALLOC
)
1827 record_dynamic_alloc (decl
);
1830 /* A helper function to be called via walk_tree. Mark all labels under *TP
1831 as being forced. To be called for DECL_INITIAL of static variables. */
1834 force_labels_r (tree
*tp
, int *walk_subtrees
, void *data ATTRIBUTE_UNUSED
)
1838 if (TREE_CODE (*tp
) == LABEL_DECL
)
1840 FORCED_LABEL (*tp
) = 1;
1841 cfun
->has_forced_label_in_static
= 1;
1847 /* Generate an initialization to automatic variable DECL based on INIT_TYPE.
1848 Build a call to internal const function DEFERRED_INIT:
1849 1st argument: SIZE of the DECL;
1850 2nd argument: INIT_TYPE;
1851 3rd argument: NAME of the DECL;
1853 as LHS = DEFERRED_INIT (SIZE of the DECL, INIT_TYPE, NAME of the DECL). */
1856 gimple_add_init_for_auto_var (tree decl
,
1857 enum auto_init_type init_type
,
1860 gcc_assert (auto_var_p (decl
));
1861 gcc_assert (init_type
> AUTO_INIT_UNINITIALIZED
);
1862 location_t loc
= EXPR_LOCATION (decl
);
1863 tree decl_size
= TYPE_SIZE_UNIT (TREE_TYPE (decl
));
1866 = build_int_cst (integer_type_node
, (int) init_type
);
1868 tree decl_name
= NULL_TREE
;
1869 if (DECL_NAME (decl
))
1871 decl_name
= build_string_literal (DECL_NAME (decl
));
1875 char decl_name_anonymous
[3 + (HOST_BITS_PER_INT
+ 2) / 3];
1876 sprintf (decl_name_anonymous
, "D.%u", DECL_UID (decl
));
1877 decl_name
= build_string_literal (decl_name_anonymous
);
1880 tree call
= build_call_expr_internal_loc (loc
, IFN_DEFERRED_INIT
,
1881 TREE_TYPE (decl
), 3,
1882 decl_size
, init_type_node
,
1885 gimplify_assign (decl
, call
, seq_p
);
1888 /* Generate padding initialization for automatic vairable DECL.
1889 C guarantees that brace-init with fewer initializers than members
1890 aggregate will initialize the rest of the aggregate as-if it were
1891 static initialization. In turn static initialization guarantees
1892 that padding is initialized to zero. So, we always initialize paddings
1893 to zeroes regardless INIT_TYPE.
1894 To do the padding initialization, we insert a call to
1895 __builtin_clear_padding (&decl, 0, for_auto_init = true).
1896 Note, we add an additional dummy argument for __builtin_clear_padding,
1897 'for_auto_init' to distinguish whether this call is for automatic
1898 variable initialization or not.
1901 gimple_add_padding_init_for_auto_var (tree decl
, bool is_vla
,
1904 tree addr_of_decl
= NULL_TREE
;
1905 tree fn
= builtin_decl_explicit (BUILT_IN_CLEAR_PADDING
);
1909 /* The temporary address variable for this vla should be
1910 created in gimplify_vla_decl. */
1911 gcc_assert (DECL_HAS_VALUE_EXPR_P (decl
));
1912 gcc_assert (INDIRECT_REF_P (DECL_VALUE_EXPR (decl
)));
1913 addr_of_decl
= TREE_OPERAND (DECL_VALUE_EXPR (decl
), 0);
1917 mark_addressable (decl
);
1918 addr_of_decl
= build_fold_addr_expr (decl
);
1921 gimple
*call
= gimple_build_call (fn
, 2, addr_of_decl
,
1922 build_one_cst (TREE_TYPE (addr_of_decl
)));
1923 gimplify_seq_add_stmt (seq_p
, call
);
1926 /* Return true if the DECL need to be automaticly initialized by the
1929 is_var_need_auto_init (tree decl
)
1931 if (auto_var_p (decl
)
1932 && (TREE_CODE (decl
) != VAR_DECL
1933 || !DECL_HARD_REGISTER (decl
))
1934 && (flag_auto_var_init
> AUTO_INIT_UNINITIALIZED
)
1935 && (!lookup_attribute ("uninitialized", DECL_ATTRIBUTES (decl
)))
1936 && !OPAQUE_TYPE_P (TREE_TYPE (decl
))
1937 && !is_empty_type (TREE_TYPE (decl
)))
1942 /* Gimplify a DECL_EXPR node *STMT_P by making any necessary allocation
1943 and initialization explicit. */
1945 static enum gimplify_status
1946 gimplify_decl_expr (tree
*stmt_p
, gimple_seq
*seq_p
)
1948 tree stmt
= *stmt_p
;
1949 tree decl
= DECL_EXPR_DECL (stmt
);
1951 *stmt_p
= NULL_TREE
;
1953 if (TREE_TYPE (decl
) == error_mark_node
)
1956 if ((TREE_CODE (decl
) == TYPE_DECL
1958 && !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl
)))
1960 gimplify_type_sizes (TREE_TYPE (decl
), seq_p
);
1961 if (TREE_CODE (TREE_TYPE (decl
)) == REFERENCE_TYPE
)
1962 gimplify_type_sizes (TREE_TYPE (TREE_TYPE (decl
)), seq_p
);
1965 /* ??? DECL_ORIGINAL_TYPE is streamed for LTO so it needs to be gimplified
1966 in case its size expressions contain problematic nodes like CALL_EXPR. */
1967 if (TREE_CODE (decl
) == TYPE_DECL
1968 && DECL_ORIGINAL_TYPE (decl
)
1969 && !TYPE_SIZES_GIMPLIFIED (DECL_ORIGINAL_TYPE (decl
)))
1971 gimplify_type_sizes (DECL_ORIGINAL_TYPE (decl
), seq_p
);
1972 if (TREE_CODE (DECL_ORIGINAL_TYPE (decl
)) == REFERENCE_TYPE
)
1973 gimplify_type_sizes (TREE_TYPE (DECL_ORIGINAL_TYPE (decl
)), seq_p
);
1976 if (VAR_P (decl
) && !DECL_EXTERNAL (decl
))
1978 tree init
= DECL_INITIAL (decl
);
1979 bool is_vla
= false;
1980 /* Check whether a decl has FE created VALUE_EXPR here BEFORE
1981 gimplify_vla_decl creates VALUE_EXPR for a vla decl.
1982 If the decl has VALUE_EXPR that was created by FE (usually
1983 C++FE), it's a proxy varaible, and FE already initialized
1984 the VALUE_EXPR of it, we should not initialize it anymore. */
1985 bool decl_had_value_expr_p
= DECL_HAS_VALUE_EXPR_P (decl
);
1988 if (!poly_int_tree_p (DECL_SIZE_UNIT (decl
), &size
)
1989 || (!TREE_STATIC (decl
)
1990 && flag_stack_check
== GENERIC_STACK_CHECK
1992 (unsigned HOST_WIDE_INT
) STACK_CHECK_MAX_VAR_SIZE
)))
1994 gimplify_vla_decl (decl
, seq_p
);
1998 if (asan_poisoned_variables
2000 && TREE_ADDRESSABLE (decl
)
2001 && !TREE_STATIC (decl
)
2002 && !DECL_HAS_VALUE_EXPR_P (decl
)
2003 && DECL_ALIGN (decl
) <= MAX_SUPPORTED_STACK_ALIGNMENT
2004 && dbg_cnt (asan_use_after_scope
)
2005 && !gimplify_omp_ctxp
2006 /* GNAT introduces temporaries to hold return values of calls in
2007 initializers of variables defined in other units, so the
2008 declaration of the variable is discarded completely. We do not
2009 want to issue poison calls for such dropped variables. */
2010 && (DECL_SEEN_IN_BIND_EXPR_P (decl
)
2011 || (DECL_ARTIFICIAL (decl
) && DECL_NAME (decl
) == NULL_TREE
)))
2013 asan_poisoned_variables
->add (decl
);
2014 asan_poison_variable (decl
, false, seq_p
);
2015 if (!DECL_ARTIFICIAL (decl
) && gimplify_ctxp
->live_switch_vars
)
2016 gimplify_ctxp
->live_switch_vars
->add (decl
);
2019 /* Some front ends do not explicitly declare all anonymous
2020 artificial variables. We compensate here by declaring the
2021 variables, though it would be better if the front ends would
2022 explicitly declare them. */
2023 if (!DECL_SEEN_IN_BIND_EXPR_P (decl
)
2024 && DECL_ARTIFICIAL (decl
) && DECL_NAME (decl
) == NULL_TREE
)
2025 gimple_add_tmp_var (decl
);
2027 if (init
&& init
!= error_mark_node
)
2029 if (!TREE_STATIC (decl
))
2031 DECL_INITIAL (decl
) = NULL_TREE
;
2032 init
= build2 (INIT_EXPR
, void_type_node
, decl
, init
);
2033 gimplify_and_add (init
, seq_p
);
2035 /* Clear TREE_READONLY if we really have an initialization. */
2036 if (!DECL_INITIAL (decl
)
2037 && !omp_privatize_by_reference (decl
))
2038 TREE_READONLY (decl
) = 0;
2041 /* We must still examine initializers for static variables
2042 as they may contain a label address. */
2043 walk_tree (&init
, force_labels_r
, NULL
, NULL
);
2045 /* When there is no explicit initializer, if the user requested,
2046 We should insert an artifical initializer for this automatic
2048 else if (is_var_need_auto_init (decl
)
2049 && !decl_had_value_expr_p
)
2051 gimple_add_init_for_auto_var (decl
,
2054 /* The expanding of a call to the above .DEFERRED_INIT will apply
2055 block initialization to the whole space covered by this variable.
2056 As a result, all the paddings will be initialized to zeroes
2057 for zero initialization and 0xFE byte-repeatable patterns for
2058 pattern initialization.
2059 In order to make the paddings as zeroes for pattern init, We
2060 should add a call to __builtin_clear_padding to clear the
2061 paddings to zero in compatiple with CLANG.
2062 We cannot insert this call if the variable is a gimple register
2063 since __builtin_clear_padding will take the address of the
2064 variable. As a result, if a long double/_Complex long double
2065 variable will spilled into stack later, its padding is 0XFE. */
2066 if (flag_auto_var_init
== AUTO_INIT_PATTERN
2067 && !is_gimple_reg (decl
)
2068 && clear_padding_type_may_have_padding_p (TREE_TYPE (decl
)))
2069 gimple_add_padding_init_for_auto_var (decl
, is_vla
, seq_p
);
2076 /* Gimplify a LOOP_EXPR. Normally this just involves gimplifying the body
2077 and replacing the LOOP_EXPR with goto, but if the loop contains an
2078 EXIT_EXPR, we need to append a label for it to jump to. */
2080 static enum gimplify_status
2081 gimplify_loop_expr (tree
*expr_p
, gimple_seq
*pre_p
)
2083 tree saved_label
= gimplify_ctxp
->exit_label
;
2084 tree start_label
= create_artificial_label (UNKNOWN_LOCATION
);
2086 gimplify_seq_add_stmt (pre_p
, gimple_build_label (start_label
));
2088 gimplify_ctxp
->exit_label
= NULL_TREE
;
2090 gimplify_and_add (LOOP_EXPR_BODY (*expr_p
), pre_p
);
2092 gimplify_seq_add_stmt (pre_p
, gimple_build_goto (start_label
));
2094 if (gimplify_ctxp
->exit_label
)
2095 gimplify_seq_add_stmt (pre_p
,
2096 gimple_build_label (gimplify_ctxp
->exit_label
));
2098 gimplify_ctxp
->exit_label
= saved_label
;
2104 /* Gimplify a statement list onto a sequence. These may be created either
2105 by an enlightened front-end, or by shortcut_cond_expr. */
2107 static enum gimplify_status
2108 gimplify_statement_list (tree
*expr_p
, gimple_seq
*pre_p
)
2110 tree temp
= voidify_wrapper_expr (*expr_p
, NULL
);
2112 tree_stmt_iterator i
= tsi_start (*expr_p
);
2114 while (!tsi_end_p (i
))
2116 gimplify_stmt (tsi_stmt_ptr (i
), pre_p
);
2130 /* Emit warning for the unreachable statment STMT if needed.
2131 Return the gimple itself when the warning is emitted, otherwise
2134 emit_warn_switch_unreachable (gimple
*stmt
)
2136 if (gimple_code (stmt
) == GIMPLE_GOTO
2137 && TREE_CODE (gimple_goto_dest (stmt
)) == LABEL_DECL
2138 && DECL_ARTIFICIAL (gimple_goto_dest (stmt
)))
2139 /* Don't warn for compiler-generated gotos. These occur
2140 in Duff's devices, for example. */
2142 else if ((flag_auto_var_init
> AUTO_INIT_UNINITIALIZED
)
2143 && ((gimple_call_internal_p (stmt
, IFN_DEFERRED_INIT
))
2144 || (gimple_call_builtin_p (stmt
, BUILT_IN_CLEAR_PADDING
)
2145 && (bool) TREE_INT_CST_LOW (gimple_call_arg (stmt
, 1)))
2146 || (is_gimple_assign (stmt
)
2147 && gimple_assign_single_p (stmt
)
2148 && (TREE_CODE (gimple_assign_rhs1 (stmt
)) == SSA_NAME
)
2149 && gimple_call_internal_p (
2150 SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt
)),
2151 IFN_DEFERRED_INIT
))))
2152 /* Don't warn for compiler-generated initializations for
2153 -ftrivial-auto-var-init.
2155 case 1: a call to .DEFERRED_INIT;
2156 case 2: a call to __builtin_clear_padding with the 2nd argument is
2157 present and non-zero;
2158 case 3: a gimple assign store right after the call to .DEFERRED_INIT
2159 that has the LHS of .DEFERRED_INIT as the RHS as following:
2160 _1 = .DEFERRED_INIT (4, 2, &"i1"[0]);
2164 warning_at (gimple_location (stmt
), OPT_Wswitch_unreachable
,
2165 "statement will never be executed");
2169 /* Callback for walk_gimple_seq. */
2172 warn_switch_unreachable_and_auto_init_r (gimple_stmt_iterator
*gsi_p
,
2173 bool *handled_ops_p
,
2174 struct walk_stmt_info
*wi
)
2176 gimple
*stmt
= gsi_stmt (*gsi_p
);
2177 bool unreachable_issued
= wi
->info
!= NULL
;
2179 *handled_ops_p
= true;
2180 switch (gimple_code (stmt
))
2183 /* A compiler-generated cleanup or a user-written try block.
2184 If it's empty, don't dive into it--that would result in
2185 worse location info. */
2186 if (gimple_try_eval (stmt
) == NULL
)
2188 if (warn_switch_unreachable
&& !unreachable_issued
)
2189 wi
->info
= emit_warn_switch_unreachable (stmt
);
2191 /* Stop when auto var init warning is not on. */
2192 if (!warn_trivial_auto_var_init
)
2193 return integer_zero_node
;
2198 case GIMPLE_EH_FILTER
:
2199 case GIMPLE_TRANSACTION
:
2200 /* Walk the sub-statements. */
2201 *handled_ops_p
= false;
2205 /* Ignore these. We may generate them before declarations that
2206 are never executed. If there's something to warn about,
2207 there will be non-debug stmts too, and we'll catch those. */
2211 /* Stop till the first Label. */
2212 return integer_zero_node
;
2214 if (gimple_call_internal_p (stmt
, IFN_ASAN_MARK
))
2216 *handled_ops_p
= false;
2219 if (warn_trivial_auto_var_init
2220 && flag_auto_var_init
> AUTO_INIT_UNINITIALIZED
2221 && gimple_call_internal_p (stmt
, IFN_DEFERRED_INIT
))
2223 /* Get the variable name from the 3rd argument of call. */
2224 tree var_name
= gimple_call_arg (stmt
, 2);
2225 var_name
= TREE_OPERAND (TREE_OPERAND (var_name
, 0), 0);
2226 const char *var_name_str
= TREE_STRING_POINTER (var_name
);
2228 warning_at (gimple_location (stmt
), OPT_Wtrivial_auto_var_init
,
2229 "%qs cannot be initialized with"
2230 "%<-ftrivial-auto-var_init%>",
2237 /* check the first "real" statement (not a decl/lexical scope/...), issue
2238 warning if needed. */
2239 if (warn_switch_unreachable
&& !unreachable_issued
)
2240 wi
->info
= emit_warn_switch_unreachable (stmt
);
2241 /* Stop when auto var init warning is not on. */
2242 if (!warn_trivial_auto_var_init
)
2243 return integer_zero_node
;
2250 /* Possibly warn about unreachable statements between switch's controlling
2251 expression and the first case. Also warn about -ftrivial-auto-var-init
2252 cannot initialize the auto variable under such situation.
2253 SEQ is the body of a switch expression. */
2256 maybe_warn_switch_unreachable_and_auto_init (gimple_seq seq
)
2258 if ((!warn_switch_unreachable
&& !warn_trivial_auto_var_init
)
2259 /* This warning doesn't play well with Fortran when optimizations
2261 || lang_GNU_Fortran ()
2265 struct walk_stmt_info wi
;
2267 memset (&wi
, 0, sizeof (wi
));
2268 walk_gimple_seq (seq
, warn_switch_unreachable_and_auto_init_r
, NULL
, &wi
);
2272 /* A label entry that pairs label and a location. */
2279 /* Find LABEL in vector of label entries VEC. */
2281 static struct label_entry
*
2282 find_label_entry (const auto_vec
<struct label_entry
> *vec
, tree label
)
2285 struct label_entry
*l
;
2287 FOR_EACH_VEC_ELT (*vec
, i
, l
)
2288 if (l
->label
== label
)
2293 /* Return true if LABEL, a LABEL_DECL, represents a case label
2294 in a vector of labels CASES. */
2297 case_label_p (const vec
<tree
> *cases
, tree label
)
2302 FOR_EACH_VEC_ELT (*cases
, i
, l
)
2303 if (CASE_LABEL (l
) == label
)
2308 /* Find the last nondebug statement in a scope STMT. */
2311 last_stmt_in_scope (gimple
*stmt
)
2316 switch (gimple_code (stmt
))
2320 gbind
*bind
= as_a
<gbind
*> (stmt
);
2321 stmt
= gimple_seq_last_nondebug_stmt (gimple_bind_body (bind
));
2322 return last_stmt_in_scope (stmt
);
2327 gtry
*try_stmt
= as_a
<gtry
*> (stmt
);
2328 stmt
= gimple_seq_last_nondebug_stmt (gimple_try_eval (try_stmt
));
2329 gimple
*last_eval
= last_stmt_in_scope (stmt
);
2330 if (gimple_stmt_may_fallthru (last_eval
)
2331 && (last_eval
== NULL
2332 || !gimple_call_internal_p (last_eval
, IFN_FALLTHROUGH
))
2333 && gimple_try_kind (try_stmt
) == GIMPLE_TRY_FINALLY
)
2335 stmt
= gimple_seq_last_nondebug_stmt (gimple_try_cleanup (try_stmt
));
2336 return last_stmt_in_scope (stmt
);
2350 /* Collect labels that may fall through into LABELS and return the statement
2351 preceding another case label, or a user-defined label. Store a location
2352 useful to give warnings at *PREVLOC (usually the location of the returned
2353 statement or of its surrounding scope). */
2356 collect_fallthrough_labels (gimple_stmt_iterator
*gsi_p
,
2357 auto_vec
<struct label_entry
> *labels
,
2358 location_t
*prevloc
)
2360 gimple
*prev
= NULL
;
2362 *prevloc
= UNKNOWN_LOCATION
;
2365 if (gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_BIND
)
2367 /* Recognize the special GIMPLE_BIND added by gimplify_switch_expr,
2368 which starts on a GIMPLE_SWITCH and ends with a break label.
2369 Handle that as a single statement that can fall through. */
2370 gbind
*bind
= as_a
<gbind
*> (gsi_stmt (*gsi_p
));
2371 gimple
*first
= gimple_seq_first_stmt (gimple_bind_body (bind
));
2372 gimple
*last
= gimple_seq_last_stmt (gimple_bind_body (bind
));
2374 && gimple_code (first
) == GIMPLE_SWITCH
2375 && gimple_code (last
) == GIMPLE_LABEL
)
2377 tree label
= gimple_label_label (as_a
<glabel
*> (last
));
2378 if (SWITCH_BREAK_LABEL_P (label
))
2386 if (gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_BIND
2387 || gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_TRY
)
2389 /* Nested scope. Only look at the last statement of
2390 the innermost scope. */
2391 location_t bind_loc
= gimple_location (gsi_stmt (*gsi_p
));
2392 gimple
*last
= last_stmt_in_scope (gsi_stmt (*gsi_p
));
2396 /* It might be a label without a location. Use the
2397 location of the scope then. */
2398 if (!gimple_has_location (prev
))
2399 *prevloc
= bind_loc
;
2405 /* Ifs are tricky. */
2406 if (gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_COND
)
2408 gcond
*cond_stmt
= as_a
<gcond
*> (gsi_stmt (*gsi_p
));
2409 tree false_lab
= gimple_cond_false_label (cond_stmt
);
2410 location_t if_loc
= gimple_location (cond_stmt
);
2413 if (i > 1) goto <D.2259>; else goto D;
2414 we can't do much with the else-branch. */
2415 if (!DECL_ARTIFICIAL (false_lab
))
2418 /* Go on until the false label, then one step back. */
2419 for (; !gsi_end_p (*gsi_p
); gsi_next (gsi_p
))
2421 gimple
*stmt
= gsi_stmt (*gsi_p
);
2422 if (gimple_code (stmt
) == GIMPLE_LABEL
2423 && gimple_label_label (as_a
<glabel
*> (stmt
)) == false_lab
)
2427 /* Not found? Oops. */
2428 if (gsi_end_p (*gsi_p
))
2431 /* A dead label can't fall through. */
2432 if (!UNUSED_LABEL_P (false_lab
))
2434 struct label_entry l
= { false_lab
, if_loc
};
2435 labels
->safe_push (l
);
2438 /* Go to the last statement of the then branch. */
2441 /* if (i != 0) goto <D.1759>; else goto <D.1760>;
2447 if (gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_GOTO
2448 && !gimple_has_location (gsi_stmt (*gsi_p
)))
2450 /* Look at the statement before, it might be
2451 attribute fallthrough, in which case don't warn. */
2453 bool fallthru_before_dest
2454 = gimple_call_internal_p (gsi_stmt (*gsi_p
), IFN_FALLTHROUGH
);
2456 tree goto_dest
= gimple_goto_dest (gsi_stmt (*gsi_p
));
2457 if (!fallthru_before_dest
)
2459 struct label_entry l
= { goto_dest
, if_loc
};
2460 labels
->safe_push (l
);
2463 /* This case is about
2464 if (1 != 0) goto <D.2022>; else goto <D.2023>;
2469 where #2 is UNUSED_LABEL_P and we want to warn about #1 falling
2470 through to #3. So set PREV to #1. */
2471 else if (UNUSED_LABEL_P (false_lab
))
2472 prev
= gsi_stmt (*gsi_p
);
2474 /* And move back. */
2478 /* Remember the last statement. Skip labels that are of no interest
2480 if (gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_LABEL
)
2482 tree label
= gimple_label_label (as_a
<glabel
*> (gsi_stmt (*gsi_p
)));
2483 if (find_label_entry (labels
, label
))
2484 prev
= gsi_stmt (*gsi_p
);
2486 else if (gimple_call_internal_p (gsi_stmt (*gsi_p
), IFN_ASAN_MARK
))
2488 else if (gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_PREDICT
)
2490 else if (!is_gimple_debug (gsi_stmt (*gsi_p
)))
2491 prev
= gsi_stmt (*gsi_p
);
2494 while (!gsi_end_p (*gsi_p
)
2495 /* Stop if we find a case or a user-defined label. */
2496 && (gimple_code (gsi_stmt (*gsi_p
)) != GIMPLE_LABEL
2497 || !gimple_has_location (gsi_stmt (*gsi_p
))));
2499 if (prev
&& gimple_has_location (prev
))
2500 *prevloc
= gimple_location (prev
);
2504 /* Return true if the switch fallthough warning should occur. LABEL is
2505 the label statement that we're falling through to. */
2508 should_warn_for_implicit_fallthrough (gimple_stmt_iterator
*gsi_p
, tree label
)
2510 gimple_stmt_iterator gsi
= *gsi_p
;
2512 /* Don't warn if the label is marked with a "falls through" comment. */
2513 if (FALLTHROUGH_LABEL_P (label
))
2516 /* Don't warn for non-case labels followed by a statement:
2521 as these are likely intentional. */
2522 if (!case_label_p (&gimplify_ctxp
->case_labels
, label
))
2525 while (!gsi_end_p (gsi
)
2526 && gimple_code (gsi_stmt (gsi
)) == GIMPLE_LABEL
2527 && (l
= gimple_label_label (as_a
<glabel
*> (gsi_stmt (gsi
))))
2528 && !case_label_p (&gimplify_ctxp
->case_labels
, l
))
2529 gsi_next_nondebug (&gsi
);
2530 if (gsi_end_p (gsi
) || gimple_code (gsi_stmt (gsi
)) != GIMPLE_LABEL
)
2534 /* Don't warn for terminated branches, i.e. when the subsequent case labels
2535 immediately breaks. */
2538 /* Skip all immediately following labels. */
2539 while (!gsi_end_p (gsi
)
2540 && (gimple_code (gsi_stmt (gsi
)) == GIMPLE_LABEL
2541 || gimple_code (gsi_stmt (gsi
)) == GIMPLE_PREDICT
))
2542 gsi_next_nondebug (&gsi
);
2544 /* { ... something; default:; } */
2546 /* { ... something; default: break; } or
2547 { ... something; default: goto L; } */
2548 || gimple_code (gsi_stmt (gsi
)) == GIMPLE_GOTO
2549 /* { ... something; default: return; } */
2550 || gimple_code (gsi_stmt (gsi
)) == GIMPLE_RETURN
)
2556 /* Callback for walk_gimple_seq. */
2559 warn_implicit_fallthrough_r (gimple_stmt_iterator
*gsi_p
, bool *handled_ops_p
,
2560 struct walk_stmt_info
*)
2562 gimple
*stmt
= gsi_stmt (*gsi_p
);
2564 *handled_ops_p
= true;
2565 switch (gimple_code (stmt
))
2570 case GIMPLE_EH_FILTER
:
2571 case GIMPLE_TRANSACTION
:
2572 /* Walk the sub-statements. */
2573 *handled_ops_p
= false;
2576 /* Find a sequence of form:
2583 and possibly warn. */
2586 /* Found a label. Skip all immediately following labels. */
2587 while (!gsi_end_p (*gsi_p
)
2588 && gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_LABEL
)
2589 gsi_next_nondebug (gsi_p
);
2591 /* There might be no more statements. */
2592 if (gsi_end_p (*gsi_p
))
2593 return integer_zero_node
;
2595 /* Vector of labels that fall through. */
2596 auto_vec
<struct label_entry
> labels
;
2598 gimple
*prev
= collect_fallthrough_labels (gsi_p
, &labels
, &prevloc
);
2600 /* There might be no more statements. */
2601 if (gsi_end_p (*gsi_p
))
2602 return integer_zero_node
;
2604 gimple
*next
= gsi_stmt (*gsi_p
);
2606 /* If what follows is a label, then we may have a fallthrough. */
2607 if (gimple_code (next
) == GIMPLE_LABEL
2608 && gimple_has_location (next
)
2609 && (label
= gimple_label_label (as_a
<glabel
*> (next
)))
2612 struct label_entry
*l
;
2613 bool warned_p
= false;
2614 auto_diagnostic_group d
;
2615 if (!should_warn_for_implicit_fallthrough (gsi_p
, label
))
2617 else if (gimple_code (prev
) == GIMPLE_LABEL
2618 && (label
= gimple_label_label (as_a
<glabel
*> (prev
)))
2619 && (l
= find_label_entry (&labels
, label
)))
2620 warned_p
= warning_at (l
->loc
, OPT_Wimplicit_fallthrough_
,
2621 "this statement may fall through");
2622 else if (!gimple_call_internal_p (prev
, IFN_FALLTHROUGH
)
2623 /* Try to be clever and don't warn when the statement
2624 can't actually fall through. */
2625 && gimple_stmt_may_fallthru (prev
)
2626 && prevloc
!= UNKNOWN_LOCATION
)
2627 warned_p
= warning_at (prevloc
,
2628 OPT_Wimplicit_fallthrough_
,
2629 "this statement may fall through");
2631 inform (gimple_location (next
), "here");
2633 /* Mark this label as processed so as to prevent multiple
2634 warnings in nested switches. */
2635 FALLTHROUGH_LABEL_P (label
) = true;
2637 /* So that next warn_implicit_fallthrough_r will start looking for
2638 a new sequence starting with this label. */
2649 /* Warn when a switch case falls through. */
2652 maybe_warn_implicit_fallthrough (gimple_seq seq
)
2654 if (!warn_implicit_fallthrough
)
2657 /* This warning is meant for C/C++/ObjC/ObjC++ only. */
2660 || lang_GNU_OBJC ()))
2663 struct walk_stmt_info wi
;
2664 memset (&wi
, 0, sizeof (wi
));
2665 walk_gimple_seq (seq
, warn_implicit_fallthrough_r
, NULL
, &wi
);
2668 /* Callback for walk_gimple_seq. */
2671 expand_FALLTHROUGH_r (gimple_stmt_iterator
*gsi_p
, bool *handled_ops_p
,
2672 struct walk_stmt_info
*wi
)
2674 gimple
*stmt
= gsi_stmt (*gsi_p
);
2676 *handled_ops_p
= true;
2677 switch (gimple_code (stmt
))
2682 case GIMPLE_EH_FILTER
:
2683 case GIMPLE_TRANSACTION
:
2684 /* Walk the sub-statements. */
2685 *handled_ops_p
= false;
2688 if (gimple_call_internal_p (stmt
, IFN_FALLTHROUGH
))
2690 gsi_remove (gsi_p
, true);
2691 if (gsi_end_p (*gsi_p
))
2693 *static_cast<location_t
*>(wi
->info
) = gimple_location (stmt
);
2694 return integer_zero_node
;
2698 location_t loc
= gimple_location (stmt
);
2700 gimple_stmt_iterator gsi2
= *gsi_p
;
2701 stmt
= gsi_stmt (gsi2
);
2702 if (gimple_code (stmt
) == GIMPLE_GOTO
&& !gimple_has_location (stmt
))
2704 /* Go on until the artificial label. */
2705 tree goto_dest
= gimple_goto_dest (stmt
);
2706 for (; !gsi_end_p (gsi2
); gsi_next (&gsi2
))
2708 if (gimple_code (gsi_stmt (gsi2
)) == GIMPLE_LABEL
2709 && gimple_label_label (as_a
<glabel
*> (gsi_stmt (gsi2
)))
2714 /* Not found? Stop. */
2715 if (gsi_end_p (gsi2
))
2718 /* Look one past it. */
2722 /* We're looking for a case label or default label here. */
2723 while (!gsi_end_p (gsi2
))
2725 stmt
= gsi_stmt (gsi2
);
2726 if (gimple_code (stmt
) == GIMPLE_LABEL
)
2728 tree label
= gimple_label_label (as_a
<glabel
*> (stmt
));
2729 if (gimple_has_location (stmt
) && DECL_ARTIFICIAL (label
))
2735 else if (gimple_call_internal_p (stmt
, IFN_ASAN_MARK
))
2737 else if (!is_gimple_debug (stmt
))
2738 /* Anything else is not expected. */
2743 pedwarn (loc
, 0, "attribute %<fallthrough%> not preceding "
2744 "a case label or default label");
2753 /* Expand all FALLTHROUGH () calls in SEQ. */
2756 expand_FALLTHROUGH (gimple_seq
*seq_p
)
2758 struct walk_stmt_info wi
;
2760 memset (&wi
, 0, sizeof (wi
));
2761 wi
.info
= (void *) &loc
;
2762 walk_gimple_seq_mod (seq_p
, expand_FALLTHROUGH_r
, NULL
, &wi
);
2763 if (wi
.callback_result
== integer_zero_node
)
2764 /* We've found [[fallthrough]]; at the end of a switch, which the C++
2765 standard says is ill-formed; see [dcl.attr.fallthrough]. */
2766 pedwarn (loc
, 0, "attribute %<fallthrough%> not preceding "
2767 "a case label or default label");
2771 /* Gimplify a SWITCH_EXPR, and collect the vector of labels it can
2774 static enum gimplify_status
2775 gimplify_switch_expr (tree
*expr_p
, gimple_seq
*pre_p
)
2777 tree switch_expr
= *expr_p
;
2778 gimple_seq switch_body_seq
= NULL
;
2779 enum gimplify_status ret
;
2780 tree index_type
= TREE_TYPE (switch_expr
);
2781 if (index_type
== NULL_TREE
)
2782 index_type
= TREE_TYPE (SWITCH_COND (switch_expr
));
2784 ret
= gimplify_expr (&SWITCH_COND (switch_expr
), pre_p
, NULL
, is_gimple_val
,
2786 if (ret
== GS_ERROR
|| ret
== GS_UNHANDLED
)
2789 if (SWITCH_BODY (switch_expr
))
2792 vec
<tree
> saved_labels
;
2793 hash_set
<tree
> *saved_live_switch_vars
= NULL
;
2794 tree default_case
= NULL_TREE
;
2795 gswitch
*switch_stmt
;
2797 /* Save old labels, get new ones from body, then restore the old
2798 labels. Save all the things from the switch body to append after. */
2799 saved_labels
= gimplify_ctxp
->case_labels
;
2800 gimplify_ctxp
->case_labels
.create (8);
2802 /* Do not create live_switch_vars if SWITCH_BODY is not a BIND_EXPR. */
2803 saved_live_switch_vars
= gimplify_ctxp
->live_switch_vars
;
2804 tree_code body_type
= TREE_CODE (SWITCH_BODY (switch_expr
));
2805 if (body_type
== BIND_EXPR
|| body_type
== STATEMENT_LIST
)
2806 gimplify_ctxp
->live_switch_vars
= new hash_set
<tree
> (4);
2808 gimplify_ctxp
->live_switch_vars
= NULL
;
2810 bool old_in_switch_expr
= gimplify_ctxp
->in_switch_expr
;
2811 gimplify_ctxp
->in_switch_expr
= true;
2813 gimplify_stmt (&SWITCH_BODY (switch_expr
), &switch_body_seq
);
2815 gimplify_ctxp
->in_switch_expr
= old_in_switch_expr
;
2816 maybe_warn_switch_unreachable_and_auto_init (switch_body_seq
);
2817 maybe_warn_implicit_fallthrough (switch_body_seq
);
2818 /* Only do this for the outermost GIMPLE_SWITCH. */
2819 if (!gimplify_ctxp
->in_switch_expr
)
2820 expand_FALLTHROUGH (&switch_body_seq
);
2822 labels
= gimplify_ctxp
->case_labels
;
2823 gimplify_ctxp
->case_labels
= saved_labels
;
2825 if (gimplify_ctxp
->live_switch_vars
)
2827 gcc_assert (gimplify_ctxp
->live_switch_vars
->is_empty ());
2828 delete gimplify_ctxp
->live_switch_vars
;
2830 gimplify_ctxp
->live_switch_vars
= saved_live_switch_vars
;
2832 preprocess_case_label_vec_for_gimple (labels
, index_type
,
2835 bool add_bind
= false;
2838 glabel
*new_default
;
2841 = build_case_label (NULL_TREE
, NULL_TREE
,
2842 create_artificial_label (UNKNOWN_LOCATION
));
2843 if (old_in_switch_expr
)
2845 SWITCH_BREAK_LABEL_P (CASE_LABEL (default_case
)) = 1;
2848 new_default
= gimple_build_label (CASE_LABEL (default_case
));
2849 gimplify_seq_add_stmt (&switch_body_seq
, new_default
);
2851 else if (old_in_switch_expr
)
2853 gimple
*last
= gimple_seq_last_stmt (switch_body_seq
);
2854 if (last
&& gimple_code (last
) == GIMPLE_LABEL
)
2856 tree label
= gimple_label_label (as_a
<glabel
*> (last
));
2857 if (SWITCH_BREAK_LABEL_P (label
))
2862 switch_stmt
= gimple_build_switch (SWITCH_COND (switch_expr
),
2863 default_case
, labels
);
2864 /* For the benefit of -Wimplicit-fallthrough, if switch_body_seq
2865 ends with a GIMPLE_LABEL holding SWITCH_BREAK_LABEL_P LABEL_DECL,
2866 wrap the GIMPLE_SWITCH up to that GIMPLE_LABEL into a GIMPLE_BIND,
2867 so that we can easily find the start and end of the switch
2871 gimple_seq bind_body
= NULL
;
2872 gimplify_seq_add_stmt (&bind_body
, switch_stmt
);
2873 gimple_seq_add_seq (&bind_body
, switch_body_seq
);
2874 gbind
*bind
= gimple_build_bind (NULL_TREE
, bind_body
, NULL_TREE
);
2875 gimple_set_location (bind
, EXPR_LOCATION (switch_expr
));
2876 gimplify_seq_add_stmt (pre_p
, bind
);
2880 gimplify_seq_add_stmt (pre_p
, switch_stmt
);
2881 gimplify_seq_add_seq (pre_p
, switch_body_seq
);
2891 /* Gimplify the LABEL_EXPR pointed to by EXPR_P. */
2893 static enum gimplify_status
2894 gimplify_label_expr (tree
*expr_p
, gimple_seq
*pre_p
)
2896 gcc_assert (decl_function_context (LABEL_EXPR_LABEL (*expr_p
))
2897 == current_function_decl
);
2899 tree label
= LABEL_EXPR_LABEL (*expr_p
);
2900 glabel
*label_stmt
= gimple_build_label (label
);
2901 gimple_set_location (label_stmt
, EXPR_LOCATION (*expr_p
));
2902 gimplify_seq_add_stmt (pre_p
, label_stmt
);
2904 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label
)))
2905 gimple_seq_add_stmt (pre_p
, gimple_build_predict (PRED_COLD_LABEL
,
2907 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label
)))
2908 gimple_seq_add_stmt (pre_p
, gimple_build_predict (PRED_HOT_LABEL
,
2914 /* Gimplify the CASE_LABEL_EXPR pointed to by EXPR_P. */
2916 static enum gimplify_status
2917 gimplify_case_label_expr (tree
*expr_p
, gimple_seq
*pre_p
)
2919 struct gimplify_ctx
*ctxp
;
2922 /* Invalid programs can play Duff's Device type games with, for example,
2923 #pragma omp parallel. At least in the C front end, we don't
2924 detect such invalid branches until after gimplification, in the
2925 diagnose_omp_blocks pass. */
2926 for (ctxp
= gimplify_ctxp
; ; ctxp
= ctxp
->prev_context
)
2927 if (ctxp
->case_labels
.exists ())
2930 tree label
= CASE_LABEL (*expr_p
);
2931 label_stmt
= gimple_build_label (label
);
2932 gimple_set_location (label_stmt
, EXPR_LOCATION (*expr_p
));
2933 ctxp
->case_labels
.safe_push (*expr_p
);
2934 gimplify_seq_add_stmt (pre_p
, label_stmt
);
2936 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label
)))
2937 gimple_seq_add_stmt (pre_p
, gimple_build_predict (PRED_COLD_LABEL
,
2939 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label
)))
2940 gimple_seq_add_stmt (pre_p
, gimple_build_predict (PRED_HOT_LABEL
,
2946 /* Build a GOTO to the LABEL_DECL pointed to by LABEL_P, building it first
2950 build_and_jump (tree
*label_p
)
2952 if (label_p
== NULL
)
2953 /* If there's nowhere to jump, just fall through. */
2956 if (*label_p
== NULL_TREE
)
2958 tree label
= create_artificial_label (UNKNOWN_LOCATION
);
2962 return build1 (GOTO_EXPR
, void_type_node
, *label_p
);
2965 /* Gimplify an EXIT_EXPR by converting to a GOTO_EXPR inside a COND_EXPR.
2966 This also involves building a label to jump to and communicating it to
2967 gimplify_loop_expr through gimplify_ctxp->exit_label. */
2969 static enum gimplify_status
2970 gimplify_exit_expr (tree
*expr_p
)
2972 tree cond
= TREE_OPERAND (*expr_p
, 0);
2975 expr
= build_and_jump (&gimplify_ctxp
->exit_label
);
2976 expr
= build3 (COND_EXPR
, void_type_node
, cond
, expr
, NULL_TREE
);
2982 /* *EXPR_P is a COMPONENT_REF being used as an rvalue. If its type is
2983 different from its canonical type, wrap the whole thing inside a
2984 NOP_EXPR and force the type of the COMPONENT_REF to be the canonical
2987 The canonical type of a COMPONENT_REF is the type of the field being
2988 referenced--unless the field is a bit-field which can be read directly
2989 in a smaller mode, in which case the canonical type is the
2990 sign-appropriate type corresponding to that mode. */
2993 canonicalize_component_ref (tree
*expr_p
)
2995 tree expr
= *expr_p
;
2998 gcc_assert (TREE_CODE (expr
) == COMPONENT_REF
);
3000 if (INTEGRAL_TYPE_P (TREE_TYPE (expr
)))
3001 type
= TREE_TYPE (get_unwidened (expr
, NULL_TREE
));
3003 type
= TREE_TYPE (TREE_OPERAND (expr
, 1));
3005 /* One could argue that all the stuff below is not necessary for
3006 the non-bitfield case and declare it a FE error if type
3007 adjustment would be needed. */
3008 if (TREE_TYPE (expr
) != type
)
3010 #ifdef ENABLE_TYPES_CHECKING
3011 tree old_type
= TREE_TYPE (expr
);
3015 /* We need to preserve qualifiers and propagate them from
3017 type_quals
= TYPE_QUALS (type
)
3018 | TYPE_QUALS (TREE_TYPE (TREE_OPERAND (expr
, 0)));
3019 if (TYPE_QUALS (type
) != type_quals
)
3020 type
= build_qualified_type (TYPE_MAIN_VARIANT (type
), type_quals
);
3022 /* Set the type of the COMPONENT_REF to the underlying type. */
3023 TREE_TYPE (expr
) = type
;
3025 #ifdef ENABLE_TYPES_CHECKING
3026 /* It is now a FE error, if the conversion from the canonical
3027 type to the original expression type is not useless. */
3028 gcc_assert (useless_type_conversion_p (old_type
, type
));
3033 /* If a NOP conversion is changing a pointer to array of foo to a pointer
3034 to foo, embed that change in the ADDR_EXPR by converting
3039 where L is the lower bound. For simplicity, only do this for constant
3041 The constraint is that the type of &array[L] is trivially convertible
3045 canonicalize_addr_expr (tree
*expr_p
)
3047 tree expr
= *expr_p
;
3048 tree addr_expr
= TREE_OPERAND (expr
, 0);
3049 tree datype
, ddatype
, pddatype
;
3051 /* We simplify only conversions from an ADDR_EXPR to a pointer type. */
3052 if (!POINTER_TYPE_P (TREE_TYPE (expr
))
3053 || TREE_CODE (addr_expr
) != ADDR_EXPR
)
3056 /* The addr_expr type should be a pointer to an array. */
3057 datype
= TREE_TYPE (TREE_TYPE (addr_expr
));
3058 if (TREE_CODE (datype
) != ARRAY_TYPE
)
3061 /* The pointer to element type shall be trivially convertible to
3062 the expression pointer type. */
3063 ddatype
= TREE_TYPE (datype
);
3064 pddatype
= build_pointer_type (ddatype
);
3065 if (!useless_type_conversion_p (TYPE_MAIN_VARIANT (TREE_TYPE (expr
)),
3069 /* The lower bound and element sizes must be constant. */
3070 if (!TYPE_SIZE_UNIT (ddatype
)
3071 || TREE_CODE (TYPE_SIZE_UNIT (ddatype
)) != INTEGER_CST
3072 || !TYPE_DOMAIN (datype
) || !TYPE_MIN_VALUE (TYPE_DOMAIN (datype
))
3073 || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (datype
))) != INTEGER_CST
)
3076 /* All checks succeeded. Build a new node to merge the cast. */
3077 *expr_p
= build4 (ARRAY_REF
, ddatype
, TREE_OPERAND (addr_expr
, 0),
3078 TYPE_MIN_VALUE (TYPE_DOMAIN (datype
)),
3079 NULL_TREE
, NULL_TREE
);
3080 *expr_p
= build1 (ADDR_EXPR
, pddatype
, *expr_p
);
3082 /* We can have stripped a required restrict qualifier above. */
3083 if (!useless_type_conversion_p (TREE_TYPE (expr
), TREE_TYPE (*expr_p
)))
3084 *expr_p
= fold_convert (TREE_TYPE (expr
), *expr_p
);
3087 /* *EXPR_P is a NOP_EXPR or CONVERT_EXPR. Remove it and/or other conversions
3088 underneath as appropriate. */
3090 static enum gimplify_status
3091 gimplify_conversion (tree
*expr_p
)
3093 location_t loc
= EXPR_LOCATION (*expr_p
);
3094 gcc_assert (CONVERT_EXPR_P (*expr_p
));
3096 /* Then strip away all but the outermost conversion. */
3097 STRIP_SIGN_NOPS (TREE_OPERAND (*expr_p
, 0));
3099 /* And remove the outermost conversion if it's useless. */
3100 if (tree_ssa_useless_type_conversion (*expr_p
))
3101 *expr_p
= TREE_OPERAND (*expr_p
, 0);
3103 /* If we still have a conversion at the toplevel,
3104 then canonicalize some constructs. */
3105 if (CONVERT_EXPR_P (*expr_p
))
3107 tree sub
= TREE_OPERAND (*expr_p
, 0);
3109 /* If a NOP conversion is changing the type of a COMPONENT_REF
3110 expression, then canonicalize its type now in order to expose more
3111 redundant conversions. */
3112 if (TREE_CODE (sub
) == COMPONENT_REF
)
3113 canonicalize_component_ref (&TREE_OPERAND (*expr_p
, 0));
3115 /* If a NOP conversion is changing a pointer to array of foo
3116 to a pointer to foo, embed that change in the ADDR_EXPR. */
3117 else if (TREE_CODE (sub
) == ADDR_EXPR
)
3118 canonicalize_addr_expr (expr_p
);
3121 /* If we have a conversion to a non-register type force the
3122 use of a VIEW_CONVERT_EXPR instead. */
3123 if (CONVERT_EXPR_P (*expr_p
) && !is_gimple_reg_type (TREE_TYPE (*expr_p
)))
3124 *expr_p
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, TREE_TYPE (*expr_p
),
3125 TREE_OPERAND (*expr_p
, 0));
3127 /* Canonicalize CONVERT_EXPR to NOP_EXPR. */
3128 if (TREE_CODE (*expr_p
) == CONVERT_EXPR
)
3129 TREE_SET_CODE (*expr_p
, NOP_EXPR
);
3134 /* Gimplify a VAR_DECL or PARM_DECL. Return GS_OK if we expanded a
3135 DECL_VALUE_EXPR, and it's worth re-examining things. */
3137 static enum gimplify_status
3138 gimplify_var_or_parm_decl (tree
*expr_p
)
3140 tree decl
= *expr_p
;
3142 /* ??? If this is a local variable, and it has not been seen in any
3143 outer BIND_EXPR, then it's probably the result of a duplicate
3144 declaration, for which we've already issued an error. It would
3145 be really nice if the front end wouldn't leak these at all.
3146 Currently the only known culprit is C++ destructors, as seen
3147 in g++.old-deja/g++.jason/binding.C.
3148 Another possible culpit are size expressions for variably modified
3149 types which are lost in the FE or not gimplified correctly. */
3151 && !DECL_SEEN_IN_BIND_EXPR_P (decl
)
3152 && !TREE_STATIC (decl
) && !DECL_EXTERNAL (decl
)
3153 && decl_function_context (decl
) == current_function_decl
)
3155 gcc_assert (seen_error ());
3159 /* When within an OMP context, notice uses of variables. */
3160 if (gimplify_omp_ctxp
&& omp_notice_variable (gimplify_omp_ctxp
, decl
, true))
3163 /* If the decl is an alias for another expression, substitute it now. */
3164 if (DECL_HAS_VALUE_EXPR_P (decl
))
3166 *expr_p
= unshare_expr (DECL_VALUE_EXPR (decl
));
3173 /* Recalculate the value of the TREE_SIDE_EFFECTS flag for T. */
3176 recalculate_side_effects (tree t
)
3178 enum tree_code code
= TREE_CODE (t
);
3179 int len
= TREE_OPERAND_LENGTH (t
);
3182 switch (TREE_CODE_CLASS (code
))
3184 case tcc_expression
:
3190 case PREDECREMENT_EXPR
:
3191 case PREINCREMENT_EXPR
:
3192 case POSTDECREMENT_EXPR
:
3193 case POSTINCREMENT_EXPR
:
3194 /* All of these have side-effects, no matter what their
3203 case tcc_comparison
: /* a comparison expression */
3204 case tcc_unary
: /* a unary arithmetic expression */
3205 case tcc_binary
: /* a binary arithmetic expression */
3206 case tcc_reference
: /* a reference */
3207 case tcc_vl_exp
: /* a function call */
3208 TREE_SIDE_EFFECTS (t
) = TREE_THIS_VOLATILE (t
);
3209 for (i
= 0; i
< len
; ++i
)
3211 tree op
= TREE_OPERAND (t
, i
);
3212 if (op
&& TREE_SIDE_EFFECTS (op
))
3213 TREE_SIDE_EFFECTS (t
) = 1;
3218 /* No side-effects. */
3226 /* Gimplify the COMPONENT_REF, ARRAY_REF, REALPART_EXPR or IMAGPART_EXPR
3230 : min_lval '[' val ']'
3232 | compound_lval '[' val ']'
3233 | compound_lval '.' ID
3235 This is not part of the original SIMPLE definition, which separates
3236 array and member references, but it seems reasonable to handle them
3237 together. Also, this way we don't run into problems with union
3238 aliasing; gcc requires that for accesses through a union to alias, the
3239 union reference must be explicit, which was not always the case when we
3240 were splitting up array and member refs.
3242 PRE_P points to the sequence where side effects that must happen before
3243 *EXPR_P should be stored.
3245 POST_P points to the sequence where side effects that must happen after
3246 *EXPR_P should be stored. */
3248 static enum gimplify_status
3249 gimplify_compound_lval (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
3250 fallback_t fallback
)
3253 enum gimplify_status ret
= GS_ALL_DONE
, tret
;
3255 location_t loc
= EXPR_LOCATION (*expr_p
);
3256 tree expr
= *expr_p
;
3258 /* Create a stack of the subexpressions so later we can walk them in
3259 order from inner to outer. */
3260 auto_vec
<tree
, 10> expr_stack
;
3262 /* We can handle anything that get_inner_reference can deal with. */
3263 for (p
= expr_p
; ; p
= &TREE_OPERAND (*p
, 0))
3266 /* Fold INDIRECT_REFs now to turn them into ARRAY_REFs. */
3267 if (TREE_CODE (*p
) == INDIRECT_REF
)
3268 *p
= fold_indirect_ref_loc (loc
, *p
);
3270 if (handled_component_p (*p
))
3272 /* Expand DECL_VALUE_EXPR now. In some cases that may expose
3273 additional COMPONENT_REFs. */
3274 else if ((VAR_P (*p
) || TREE_CODE (*p
) == PARM_DECL
)
3275 && gimplify_var_or_parm_decl (p
) == GS_OK
)
3280 expr_stack
.safe_push (*p
);
3283 gcc_assert (expr_stack
.length ());
3285 /* Now EXPR_STACK is a stack of pointers to all the refs we've
3286 walked through and P points to the innermost expression.
3288 Java requires that we elaborated nodes in source order. That
3289 means we must gimplify the inner expression followed by each of
3290 the indices, in order. But we can't gimplify the inner
3291 expression until we deal with any variable bounds, sizes, or
3292 positions in order to deal with PLACEHOLDER_EXPRs.
3294 The base expression may contain a statement expression that
3295 has declarations used in size expressions, so has to be
3296 gimplified before gimplifying the size expressions.
3298 So we do this in three steps. First we deal with variable
3299 bounds, sizes, and positions, then we gimplify the base and
3300 ensure it is memory if needed, then we deal with the annotations
3301 for any variables in the components and any indices, from left
3304 bool need_non_reg
= false;
3305 for (i
= expr_stack
.length () - 1; i
>= 0; i
--)
3307 tree t
= expr_stack
[i
];
3309 if (error_operand_p (TREE_OPERAND (t
, 0)))
3312 if (TREE_CODE (t
) == ARRAY_REF
|| TREE_CODE (t
) == ARRAY_RANGE_REF
)
3314 /* Deal with the low bound and element type size and put them into
3315 the ARRAY_REF. If these values are set, they have already been
3317 if (TREE_OPERAND (t
, 2) == NULL_TREE
)
3319 tree low
= unshare_expr (array_ref_low_bound (t
));
3320 if (!is_gimple_min_invariant (low
))
3322 TREE_OPERAND (t
, 2) = low
;
3326 if (TREE_OPERAND (t
, 3) == NULL_TREE
)
3328 tree elmt_size
= array_ref_element_size (t
);
3329 if (!is_gimple_min_invariant (elmt_size
))
3331 elmt_size
= unshare_expr (elmt_size
);
3332 tree elmt_type
= TREE_TYPE (TREE_TYPE (TREE_OPERAND (t
, 0)));
3333 tree factor
= size_int (TYPE_ALIGN_UNIT (elmt_type
));
3335 /* Divide the element size by the alignment of the element
3337 elmt_size
= size_binop_loc (loc
, EXACT_DIV_EXPR
,
3340 TREE_OPERAND (t
, 3) = elmt_size
;
3343 need_non_reg
= true;
3345 else if (TREE_CODE (t
) == COMPONENT_REF
)
3347 /* Set the field offset into T and gimplify it. */
3348 if (TREE_OPERAND (t
, 2) == NULL_TREE
)
3350 tree offset
= component_ref_field_offset (t
);
3351 if (!is_gimple_min_invariant (offset
))
3353 offset
= unshare_expr (offset
);
3354 tree field
= TREE_OPERAND (t
, 1);
3356 = size_int (DECL_OFFSET_ALIGN (field
) / BITS_PER_UNIT
);
3358 /* Divide the offset by its alignment. */
3359 offset
= size_binop_loc (loc
, EXACT_DIV_EXPR
,
3362 TREE_OPERAND (t
, 2) = offset
;
3365 need_non_reg
= true;
3367 else if (!is_gimple_reg_type (TREE_TYPE (t
)))
3368 /* When the result of an operation, in particular a VIEW_CONVERT_EXPR
3369 is a non-register type then require the base object to be a
3370 non-register as well. */
3371 need_non_reg
= true;
3374 /* Step 2 is to gimplify the base expression. Make sure lvalue is set
3375 so as to match the min_lval predicate. Failure to do so may result
3376 in the creation of large aggregate temporaries. */
3377 tret
= gimplify_expr (p
, pre_p
, post_p
, is_gimple_min_lval
,
3378 fallback
| fb_lvalue
);
3379 ret
= MIN (ret
, tret
);
3380 if (ret
== GS_ERROR
)
3383 /* Step 2a: if we have component references we do not support on
3384 registers then make sure the base isn't a register. Of course
3385 we can only do so if an rvalue is OK. */
3386 if (need_non_reg
&& (fallback
& fb_rvalue
))
3387 prepare_gimple_addressable (p
, pre_p
);
3390 /* Step 3: gimplify size expressions and the indices and operands of
3391 ARRAY_REF. During this loop we also remove any useless conversions.
3392 If we operate on a register also make sure to properly gimplify
3393 to individual operations. */
3395 bool reg_operations
= is_gimple_reg (*p
);
3396 for (; expr_stack
.length () > 0; )
3398 tree t
= expr_stack
.pop ();
3400 if (TREE_CODE (t
) == ARRAY_REF
|| TREE_CODE (t
) == ARRAY_RANGE_REF
)
3402 gcc_assert (!reg_operations
);
3404 /* Gimplify the low bound and element type size. */
3405 tret
= gimplify_expr (&TREE_OPERAND (t
, 2), pre_p
, post_p
,
3406 is_gimple_reg
, fb_rvalue
);
3407 ret
= MIN (ret
, tret
);
3409 tret
= gimplify_expr (&TREE_OPERAND (t
, 3), pre_p
, post_p
,
3410 is_gimple_reg
, fb_rvalue
);
3411 ret
= MIN (ret
, tret
);
3413 /* Gimplify the dimension. */
3414 tret
= gimplify_expr (&TREE_OPERAND (t
, 1), pre_p
, post_p
,
3415 is_gimple_val
, fb_rvalue
);
3416 ret
= MIN (ret
, tret
);
3418 else if (TREE_CODE (t
) == COMPONENT_REF
)
3420 gcc_assert (!reg_operations
);
3422 tret
= gimplify_expr (&TREE_OPERAND (t
, 2), pre_p
, post_p
,
3423 is_gimple_reg
, fb_rvalue
);
3424 ret
= MIN (ret
, tret
);
3426 else if (reg_operations
)
3428 tret
= gimplify_expr (&TREE_OPERAND (t
, 0), pre_p
, post_p
,
3429 is_gimple_val
, fb_rvalue
);
3430 ret
= MIN (ret
, tret
);
3433 STRIP_USELESS_TYPE_CONVERSION (TREE_OPERAND (t
, 0));
3435 /* The innermost expression P may have originally had
3436 TREE_SIDE_EFFECTS set which would have caused all the outer
3437 expressions in *EXPR_P leading to P to also have had
3438 TREE_SIDE_EFFECTS set. */
3439 recalculate_side_effects (t
);
3442 /* If the outermost expression is a COMPONENT_REF, canonicalize its type. */
3443 if ((fallback
& fb_rvalue
) && TREE_CODE (*expr_p
) == COMPONENT_REF
)
3445 canonicalize_component_ref (expr_p
);
3448 expr_stack
.release ();
3450 gcc_assert (*expr_p
== expr
|| ret
!= GS_ALL_DONE
);
3455 /* Gimplify the self modifying expression pointed to by EXPR_P
3458 PRE_P points to the list where side effects that must happen before
3459 *EXPR_P should be stored.
3461 POST_P points to the list where side effects that must happen after
3462 *EXPR_P should be stored.
3464 WANT_VALUE is nonzero iff we want to use the value of this expression
3465 in another expression.
3467 ARITH_TYPE is the type the computation should be performed in. */
3469 enum gimplify_status
3470 gimplify_self_mod_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
3471 bool want_value
, tree arith_type
)
3473 enum tree_code code
;
3474 tree lhs
, lvalue
, rhs
, t1
;
3475 gimple_seq post
= NULL
, *orig_post_p
= post_p
;
3477 enum tree_code arith_code
;
3478 enum gimplify_status ret
;
3479 location_t loc
= EXPR_LOCATION (*expr_p
);
3481 code
= TREE_CODE (*expr_p
);
3483 gcc_assert (code
== POSTINCREMENT_EXPR
|| code
== POSTDECREMENT_EXPR
3484 || code
== PREINCREMENT_EXPR
|| code
== PREDECREMENT_EXPR
);
3486 /* Prefix or postfix? */
3487 if (code
== POSTINCREMENT_EXPR
|| code
== POSTDECREMENT_EXPR
)
3488 /* Faster to treat as prefix if result is not used. */
3489 postfix
= want_value
;
3493 /* For postfix, make sure the inner expression's post side effects
3494 are executed after side effects from this expression. */
3498 /* Add or subtract? */
3499 if (code
== PREINCREMENT_EXPR
|| code
== POSTINCREMENT_EXPR
)
3500 arith_code
= PLUS_EXPR
;
3502 arith_code
= MINUS_EXPR
;
3504 /* Gimplify the LHS into a GIMPLE lvalue. */
3505 lvalue
= TREE_OPERAND (*expr_p
, 0);
3506 ret
= gimplify_expr (&lvalue
, pre_p
, post_p
, is_gimple_lvalue
, fb_lvalue
);
3507 if (ret
== GS_ERROR
)
3510 /* Extract the operands to the arithmetic operation. */
3512 rhs
= TREE_OPERAND (*expr_p
, 1);
3514 /* For postfix operator, we evaluate the LHS to an rvalue and then use
3515 that as the result value and in the postqueue operation. */
3518 ret
= gimplify_expr (&lhs
, pre_p
, post_p
, is_gimple_val
, fb_rvalue
);
3519 if (ret
== GS_ERROR
)
3522 lhs
= get_initialized_tmp_var (lhs
, pre_p
);
3525 /* For POINTERs increment, use POINTER_PLUS_EXPR. */
3526 if (POINTER_TYPE_P (TREE_TYPE (lhs
)))
3528 rhs
= convert_to_ptrofftype_loc (loc
, rhs
);
3529 if (arith_code
== MINUS_EXPR
)
3530 rhs
= fold_build1_loc (loc
, NEGATE_EXPR
, TREE_TYPE (rhs
), rhs
);
3531 t1
= fold_build2 (POINTER_PLUS_EXPR
, TREE_TYPE (*expr_p
), lhs
, rhs
);
3534 t1
= fold_convert (TREE_TYPE (*expr_p
),
3535 fold_build2 (arith_code
, arith_type
,
3536 fold_convert (arith_type
, lhs
),
3537 fold_convert (arith_type
, rhs
)));
3541 gimplify_assign (lvalue
, t1
, pre_p
);
3542 gimplify_seq_add_seq (orig_post_p
, post
);
3548 *expr_p
= build2 (MODIFY_EXPR
, TREE_TYPE (lvalue
), lvalue
, t1
);
3553 /* If *EXPR_P has a variable sized type, wrap it in a WITH_SIZE_EXPR. */
3556 maybe_with_size_expr (tree
*expr_p
)
3558 tree expr
= *expr_p
;
3559 tree type
= TREE_TYPE (expr
);
3562 /* If we've already wrapped this or the type is error_mark_node, we can't do
3564 if (TREE_CODE (expr
) == WITH_SIZE_EXPR
3565 || type
== error_mark_node
)
3568 /* If the size isn't known or is a constant, we have nothing to do. */
3569 size
= TYPE_SIZE_UNIT (type
);
3570 if (!size
|| poly_int_tree_p (size
))
3573 /* Otherwise, make a WITH_SIZE_EXPR. */
3574 size
= unshare_expr (size
);
3575 size
= SUBSTITUTE_PLACEHOLDER_IN_EXPR (size
, expr
);
3576 *expr_p
= build2 (WITH_SIZE_EXPR
, type
, expr
, size
);
3579 /* Helper for gimplify_call_expr. Gimplify a single argument *ARG_P
3580 Store any side-effects in PRE_P. CALL_LOCATION is the location of
3581 the CALL_EXPR. If ALLOW_SSA is set the actual parameter may be
3582 gimplified to an SSA name. */
3584 enum gimplify_status
3585 gimplify_arg (tree
*arg_p
, gimple_seq
*pre_p
, location_t call_location
,
3588 bool (*test
) (tree
);
3591 /* In general, we allow lvalues for function arguments to avoid
3592 extra overhead of copying large aggregates out of even larger
3593 aggregates into temporaries only to copy the temporaries to
3594 the argument list. Make optimizers happy by pulling out to
3595 temporaries those types that fit in registers. */
3596 if (is_gimple_reg_type (TREE_TYPE (*arg_p
)))
3597 test
= is_gimple_val
, fb
= fb_rvalue
;
3600 test
= is_gimple_lvalue
, fb
= fb_either
;
3601 /* Also strip a TARGET_EXPR that would force an extra copy. */
3602 if (TREE_CODE (*arg_p
) == TARGET_EXPR
)
3604 tree init
= TARGET_EXPR_INITIAL (*arg_p
);
3606 && !VOID_TYPE_P (TREE_TYPE (init
)))
3611 /* If this is a variable sized type, we must remember the size. */
3612 maybe_with_size_expr (arg_p
);
3614 /* FIXME diagnostics: This will mess up gcc.dg/Warray-bounds.c. */
3615 /* Make sure arguments have the same location as the function call
3617 protected_set_expr_location (*arg_p
, call_location
);
3619 /* There is a sequence point before a function call. Side effects in
3620 the argument list must occur before the actual call. So, when
3621 gimplifying arguments, force gimplify_expr to use an internal
3622 post queue which is then appended to the end of PRE_P. */
3623 return gimplify_expr (arg_p
, pre_p
, NULL
, test
, fb
, allow_ssa
);
3626 /* Don't fold inside offloading or taskreg regions: it can break code by
3627 adding decl references that weren't in the source. We'll do it during
3628 omplower pass instead. */
3631 maybe_fold_stmt (gimple_stmt_iterator
*gsi
)
3633 struct gimplify_omp_ctx
*ctx
;
3634 for (ctx
= gimplify_omp_ctxp
; ctx
; ctx
= ctx
->outer_context
)
3635 if ((ctx
->region_type
& (ORT_TARGET
| ORT_PARALLEL
| ORT_TASK
)) != 0)
3637 else if ((ctx
->region_type
& ORT_HOST_TEAMS
) == ORT_HOST_TEAMS
)
3639 /* Delay folding of builtins until the IL is in consistent state
3640 so the diagnostic machinery can do a better job. */
3641 if (gimple_call_builtin_p (gsi_stmt (*gsi
)))
3643 return fold_stmt (gsi
);
3646 /* Gimplify the CALL_EXPR node *EXPR_P into the GIMPLE sequence PRE_P.
3647 WANT_VALUE is true if the result of the call is desired. */
3649 static enum gimplify_status
3650 gimplify_call_expr (tree
*expr_p
, gimple_seq
*pre_p
, bool want_value
)
3652 tree fndecl
, parms
, p
, fnptrtype
;
3653 enum gimplify_status ret
;
3656 bool builtin_va_start_p
= false;
3657 location_t loc
= EXPR_LOCATION (*expr_p
);
3659 gcc_assert (TREE_CODE (*expr_p
) == CALL_EXPR
);
3661 /* For reliable diagnostics during inlining, it is necessary that
3662 every call_expr be annotated with file and line. */
3663 if (! EXPR_HAS_LOCATION (*expr_p
))
3664 SET_EXPR_LOCATION (*expr_p
, input_location
);
3666 /* Gimplify internal functions created in the FEs. */
3667 if (CALL_EXPR_FN (*expr_p
) == NULL_TREE
)
3672 nargs
= call_expr_nargs (*expr_p
);
3673 enum internal_fn ifn
= CALL_EXPR_IFN (*expr_p
);
3674 auto_vec
<tree
> vargs (nargs
);
3676 if (ifn
== IFN_ASSUME
)
3678 if (simple_condition_p (CALL_EXPR_ARG (*expr_p
, 0)))
3680 /* If the [[assume (cond)]]; condition is simple
3681 enough and can be evaluated unconditionally
3682 without side-effects, expand it as
3683 if (!cond) __builtin_unreachable (); */
3684 tree fndecl
= builtin_decl_explicit (BUILT_IN_UNREACHABLE
);
3685 *expr_p
= build3 (COND_EXPR
, void_type_node
,
3686 CALL_EXPR_ARG (*expr_p
, 0), void_node
,
3687 build_call_expr_loc (EXPR_LOCATION (*expr_p
),
3691 /* If not optimizing, ignore the assumptions. */
3692 if (!optimize
|| seen_error ())
3694 *expr_p
= NULL_TREE
;
3697 /* Temporarily, until gimple lowering, transform
3704 such that gimple lowering can outline the condition into
3705 a separate function easily. */
3706 tree guard
= create_tmp_var (boolean_type_node
);
3707 *expr_p
= build2 (MODIFY_EXPR
, void_type_node
, guard
,
3708 gimple_boolify (CALL_EXPR_ARG (*expr_p
, 0)));
3709 *expr_p
= build3 (BIND_EXPR
, void_type_node
, NULL
, *expr_p
, NULL
);
3710 push_gimplify_context ();
3711 gimple_seq body
= NULL
;
3712 gimple
*g
= gimplify_and_return_first (*expr_p
, &body
);
3713 pop_gimplify_context (g
);
3714 g
= gimple_build_assume (guard
, body
);
3715 gimple_set_location (g
, loc
);
3716 gimplify_seq_add_stmt (pre_p
, g
);
3717 *expr_p
= NULL_TREE
;
3721 for (i
= 0; i
< nargs
; i
++)
3723 gimplify_arg (&CALL_EXPR_ARG (*expr_p
, i
), pre_p
,
3724 EXPR_LOCATION (*expr_p
));
3725 vargs
.quick_push (CALL_EXPR_ARG (*expr_p
, i
));
3728 gcall
*call
= gimple_build_call_internal_vec (ifn
, vargs
);
3729 gimple_call_set_nothrow (call
, TREE_NOTHROW (*expr_p
));
3730 gimplify_seq_add_stmt (pre_p
, call
);
3734 /* This may be a call to a builtin function.
3736 Builtin function calls may be transformed into different
3737 (and more efficient) builtin function calls under certain
3738 circumstances. Unfortunately, gimplification can muck things
3739 up enough that the builtin expanders are not aware that certain
3740 transformations are still valid.
3742 So we attempt transformation/gimplification of the call before
3743 we gimplify the CALL_EXPR. At this time we do not manage to
3744 transform all calls in the same manner as the expanders do, but
3745 we do transform most of them. */
3746 fndecl
= get_callee_fndecl (*expr_p
);
3747 if (fndecl
&& fndecl_built_in_p (fndecl
, BUILT_IN_NORMAL
))
3748 switch (DECL_FUNCTION_CODE (fndecl
))
3750 CASE_BUILT_IN_ALLOCA
:
3751 /* If the call has been built for a variable-sized object, then we
3752 want to restore the stack level when the enclosing BIND_EXPR is
3753 exited to reclaim the allocated space; otherwise, we precisely
3754 need to do the opposite and preserve the latest stack level. */
3755 if (CALL_ALLOCA_FOR_VAR_P (*expr_p
))
3756 gimplify_ctxp
->save_stack
= true;
3758 gimplify_ctxp
->keep_stack
= true;
3761 case BUILT_IN_VA_START
:
3763 builtin_va_start_p
= true;
3764 if (call_expr_nargs (*expr_p
) < 2)
3766 error ("too few arguments to function %<va_start%>");
3767 *expr_p
= build_empty_stmt (EXPR_LOCATION (*expr_p
));
3771 if (fold_builtin_next_arg (*expr_p
, true))
3773 *expr_p
= build_empty_stmt (EXPR_LOCATION (*expr_p
));
3779 case BUILT_IN_EH_RETURN
:
3780 cfun
->calls_eh_return
= true;
3783 case BUILT_IN_CLEAR_PADDING
:
3784 if (call_expr_nargs (*expr_p
) == 1)
3786 /* Remember the original type of the argument in an internal
3787 dummy second argument, as in GIMPLE pointer conversions are
3788 useless. Also mark this call as not for automatic
3789 initialization in the internal dummy third argument. */
3790 p
= CALL_EXPR_ARG (*expr_p
, 0);
3792 = build_call_expr_loc (EXPR_LOCATION (*expr_p
), fndecl
, 2, p
,
3793 build_zero_cst (TREE_TYPE (p
)));
3801 if (fndecl
&& fndecl_built_in_p (fndecl
))
3803 tree new_tree
= fold_call_expr (input_location
, *expr_p
, !want_value
);
3804 if (new_tree
&& new_tree
!= *expr_p
)
3806 /* There was a transformation of this call which computes the
3807 same value, but in a more efficient way. Return and try
3814 /* Remember the original function pointer type. */
3815 fnptrtype
= TREE_TYPE (CALL_EXPR_FN (*expr_p
));
3820 && (cfun
->curr_properties
& PROP_gimple_any
) == 0)
3822 tree variant
= omp_resolve_declare_variant (fndecl
);
3823 if (variant
!= fndecl
)
3824 CALL_EXPR_FN (*expr_p
) = build1 (ADDR_EXPR
, fnptrtype
, variant
);
3827 /* There is a sequence point before the call, so any side effects in
3828 the calling expression must occur before the actual call. Force
3829 gimplify_expr to use an internal post queue. */
3830 ret
= gimplify_expr (&CALL_EXPR_FN (*expr_p
), pre_p
, NULL
,
3831 is_gimple_call_addr
, fb_rvalue
);
3833 if (ret
== GS_ERROR
)
3836 nargs
= call_expr_nargs (*expr_p
);
3838 /* Get argument types for verification. */
3839 fndecl
= get_callee_fndecl (*expr_p
);
3842 parms
= TYPE_ARG_TYPES (TREE_TYPE (fndecl
));
3844 parms
= TYPE_ARG_TYPES (TREE_TYPE (fnptrtype
));
3846 if (fndecl
&& DECL_ARGUMENTS (fndecl
))
3847 p
= DECL_ARGUMENTS (fndecl
);
3852 for (i
= 0; i
< nargs
&& p
; i
++, p
= TREE_CHAIN (p
))
3855 /* If the last argument is __builtin_va_arg_pack () and it is not
3856 passed as a named argument, decrease the number of CALL_EXPR
3857 arguments and set instead the CALL_EXPR_VA_ARG_PACK flag. */
3860 && TREE_CODE (CALL_EXPR_ARG (*expr_p
, nargs
- 1)) == CALL_EXPR
)
3862 tree last_arg
= CALL_EXPR_ARG (*expr_p
, nargs
- 1);
3863 tree last_arg_fndecl
= get_callee_fndecl (last_arg
);
3866 && fndecl_built_in_p (last_arg_fndecl
, BUILT_IN_VA_ARG_PACK
))
3868 tree call
= *expr_p
;
3871 *expr_p
= build_call_array_loc (loc
, TREE_TYPE (call
),
3872 CALL_EXPR_FN (call
),
3873 nargs
, CALL_EXPR_ARGP (call
));
3875 /* Copy all CALL_EXPR flags, location and block, except
3876 CALL_EXPR_VA_ARG_PACK flag. */
3877 CALL_EXPR_STATIC_CHAIN (*expr_p
) = CALL_EXPR_STATIC_CHAIN (call
);
3878 CALL_EXPR_TAILCALL (*expr_p
) = CALL_EXPR_TAILCALL (call
);
3879 CALL_EXPR_RETURN_SLOT_OPT (*expr_p
)
3880 = CALL_EXPR_RETURN_SLOT_OPT (call
);
3881 CALL_FROM_THUNK_P (*expr_p
) = CALL_FROM_THUNK_P (call
);
3882 SET_EXPR_LOCATION (*expr_p
, EXPR_LOCATION (call
));
3884 /* Set CALL_EXPR_VA_ARG_PACK. */
3885 CALL_EXPR_VA_ARG_PACK (*expr_p
) = 1;
3889 /* If the call returns twice then after building the CFG the call
3890 argument computations will no longer dominate the call because
3891 we add an abnormal incoming edge to the call. So do not use SSA
3893 bool returns_twice
= call_expr_flags (*expr_p
) & ECF_RETURNS_TWICE
;
3895 /* Gimplify the function arguments. */
3898 for (i
= (PUSH_ARGS_REVERSED
? nargs
- 1 : 0);
3899 PUSH_ARGS_REVERSED
? i
>= 0 : i
< nargs
;
3900 PUSH_ARGS_REVERSED
? i
-- : i
++)
3902 enum gimplify_status t
;
3904 /* Avoid gimplifying the second argument to va_start, which needs to
3905 be the plain PARM_DECL. */
3906 if ((i
!= 1) || !builtin_va_start_p
)
3908 t
= gimplify_arg (&CALL_EXPR_ARG (*expr_p
, i
), pre_p
,
3909 EXPR_LOCATION (*expr_p
), ! returns_twice
);
3917 /* Gimplify the static chain. */
3918 if (CALL_EXPR_STATIC_CHAIN (*expr_p
))
3920 if (fndecl
&& !DECL_STATIC_CHAIN (fndecl
))
3921 CALL_EXPR_STATIC_CHAIN (*expr_p
) = NULL
;
3924 enum gimplify_status t
;
3925 t
= gimplify_arg (&CALL_EXPR_STATIC_CHAIN (*expr_p
), pre_p
,
3926 EXPR_LOCATION (*expr_p
), ! returns_twice
);
3932 /* Verify the function result. */
3933 if (want_value
&& fndecl
3934 && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fnptrtype
))))
3936 error_at (loc
, "using result of function returning %<void%>");
3940 /* Try this again in case gimplification exposed something. */
3941 if (ret
!= GS_ERROR
)
3943 tree new_tree
= fold_call_expr (input_location
, *expr_p
, !want_value
);
3945 if (new_tree
&& new_tree
!= *expr_p
)
3947 /* There was a transformation of this call which computes the
3948 same value, but in a more efficient way. Return and try
3956 *expr_p
= error_mark_node
;
3960 /* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its
3961 decl. This allows us to eliminate redundant or useless
3962 calls to "const" functions. */
3963 if (TREE_CODE (*expr_p
) == CALL_EXPR
)
3965 int flags
= call_expr_flags (*expr_p
);
3966 if (flags
& (ECF_CONST
| ECF_PURE
)
3967 /* An infinite loop is considered a side effect. */
3968 && !(flags
& (ECF_LOOPING_CONST_OR_PURE
)))
3969 TREE_SIDE_EFFECTS (*expr_p
) = 0;
3972 /* If the value is not needed by the caller, emit a new GIMPLE_CALL
3973 and clear *EXPR_P. Otherwise, leave *EXPR_P in its gimplified
3974 form and delegate the creation of a GIMPLE_CALL to
3975 gimplify_modify_expr. This is always possible because when
3976 WANT_VALUE is true, the caller wants the result of this call into
3977 a temporary, which means that we will emit an INIT_EXPR in
3978 internal_get_tmp_var which will then be handled by
3979 gimplify_modify_expr. */
3982 /* The CALL_EXPR in *EXPR_P is already in GIMPLE form, so all we
3983 have to do is replicate it as a GIMPLE_CALL tuple. */
3984 gimple_stmt_iterator gsi
;
3985 call
= gimple_build_call_from_tree (*expr_p
, fnptrtype
);
3986 notice_special_calls (call
);
3987 gimplify_seq_add_stmt (pre_p
, call
);
3988 gsi
= gsi_last (*pre_p
);
3989 maybe_fold_stmt (&gsi
);
3990 *expr_p
= NULL_TREE
;
3993 /* Remember the original function type. */
3994 CALL_EXPR_FN (*expr_p
) = build1 (NOP_EXPR
, fnptrtype
,
3995 CALL_EXPR_FN (*expr_p
));
4000 /* Handle shortcut semantics in the predicate operand of a COND_EXPR by
4001 rewriting it into multiple COND_EXPRs, and possibly GOTO_EXPRs.
4003 TRUE_LABEL_P and FALSE_LABEL_P point to the labels to jump to if the
4004 condition is true or false, respectively. If null, we should generate
4005 our own to skip over the evaluation of this specific expression.
4007 LOCUS is the source location of the COND_EXPR.
4009 This function is the tree equivalent of do_jump.
4011 shortcut_cond_r should only be called by shortcut_cond_expr. */
4014 shortcut_cond_r (tree pred
, tree
*true_label_p
, tree
*false_label_p
,
4017 tree local_label
= NULL_TREE
;
4018 tree t
, expr
= NULL
;
4020 /* OK, it's not a simple case; we need to pull apart the COND_EXPR to
4021 retain the shortcut semantics. Just insert the gotos here;
4022 shortcut_cond_expr will append the real blocks later. */
4023 if (TREE_CODE (pred
) == TRUTH_ANDIF_EXPR
)
4025 location_t new_locus
;
4027 /* Turn if (a && b) into
4029 if (a); else goto no;
4030 if (b) goto yes; else goto no;
4033 if (false_label_p
== NULL
)
4034 false_label_p
= &local_label
;
4036 /* Keep the original source location on the first 'if'. */
4037 t
= shortcut_cond_r (TREE_OPERAND (pred
, 0), NULL
, false_label_p
, locus
);
4038 append_to_statement_list (t
, &expr
);
4040 /* Set the source location of the && on the second 'if'. */
4041 new_locus
= rexpr_location (pred
, locus
);
4042 t
= shortcut_cond_r (TREE_OPERAND (pred
, 1), true_label_p
, false_label_p
,
4044 append_to_statement_list (t
, &expr
);
4046 else if (TREE_CODE (pred
) == TRUTH_ORIF_EXPR
)
4048 location_t new_locus
;
4050 /* Turn if (a || b) into
4053 if (b) goto yes; else goto no;
4056 if (true_label_p
== NULL
)
4057 true_label_p
= &local_label
;
4059 /* Keep the original source location on the first 'if'. */
4060 t
= shortcut_cond_r (TREE_OPERAND (pred
, 0), true_label_p
, NULL
, locus
);
4061 append_to_statement_list (t
, &expr
);
4063 /* Set the source location of the || on the second 'if'. */
4064 new_locus
= rexpr_location (pred
, locus
);
4065 t
= shortcut_cond_r (TREE_OPERAND (pred
, 1), true_label_p
, false_label_p
,
4067 append_to_statement_list (t
, &expr
);
4069 else if (TREE_CODE (pred
) == COND_EXPR
4070 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred
, 1)))
4071 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred
, 2))))
4073 location_t new_locus
;
4075 /* As long as we're messing with gotos, turn if (a ? b : c) into
4077 if (b) goto yes; else goto no;
4079 if (c) goto yes; else goto no;
4081 Don't do this if one of the arms has void type, which can happen
4082 in C++ when the arm is throw. */
4084 /* Keep the original source location on the first 'if'. Set the source
4085 location of the ? on the second 'if'. */
4086 new_locus
= rexpr_location (pred
, locus
);
4087 expr
= build3 (COND_EXPR
, void_type_node
, TREE_OPERAND (pred
, 0),
4088 shortcut_cond_r (TREE_OPERAND (pred
, 1), true_label_p
,
4089 false_label_p
, locus
),
4090 shortcut_cond_r (TREE_OPERAND (pred
, 2), true_label_p
,
4091 false_label_p
, new_locus
));
4095 expr
= build3 (COND_EXPR
, void_type_node
, pred
,
4096 build_and_jump (true_label_p
),
4097 build_and_jump (false_label_p
));
4098 SET_EXPR_LOCATION (expr
, locus
);
4103 t
= build1 (LABEL_EXPR
, void_type_node
, local_label
);
4104 append_to_statement_list (t
, &expr
);
4110 /* If EXPR is a GOTO_EXPR, return it. If it is a STATEMENT_LIST, skip
4111 any of its leading DEBUG_BEGIN_STMTS and recurse on the subsequent
4112 statement, if it is the last one. Otherwise, return NULL. */
4115 find_goto (tree expr
)
4120 if (TREE_CODE (expr
) == GOTO_EXPR
)
4123 if (TREE_CODE (expr
) != STATEMENT_LIST
)
4126 tree_stmt_iterator i
= tsi_start (expr
);
4128 while (!tsi_end_p (i
) && TREE_CODE (tsi_stmt (i
)) == DEBUG_BEGIN_STMT
)
4131 if (!tsi_one_before_end_p (i
))
4134 return find_goto (tsi_stmt (i
));
4137 /* Same as find_goto, except that it returns NULL if the destination
4138 is not a LABEL_DECL. */
4141 find_goto_label (tree expr
)
4143 tree dest
= find_goto (expr
);
4144 if (dest
&& TREE_CODE (GOTO_DESTINATION (dest
)) == LABEL_DECL
)
4149 /* Given a conditional expression EXPR with short-circuit boolean
4150 predicates using TRUTH_ANDIF_EXPR or TRUTH_ORIF_EXPR, break the
4151 predicate apart into the equivalent sequence of conditionals. */
4154 shortcut_cond_expr (tree expr
)
4156 tree pred
= TREE_OPERAND (expr
, 0);
4157 tree then_
= TREE_OPERAND (expr
, 1);
4158 tree else_
= TREE_OPERAND (expr
, 2);
4159 tree true_label
, false_label
, end_label
, t
;
4161 tree
*false_label_p
;
4162 bool emit_end
, emit_false
, jump_over_else
;
4163 bool then_se
= then_
&& TREE_SIDE_EFFECTS (then_
);
4164 bool else_se
= else_
&& TREE_SIDE_EFFECTS (else_
);
4166 /* First do simple transformations. */
4169 /* If there is no 'else', turn
4172 if (a) if (b) then c. */
4173 while (TREE_CODE (pred
) == TRUTH_ANDIF_EXPR
)
4175 /* Keep the original source location on the first 'if'. */
4176 location_t locus
= EXPR_LOC_OR_LOC (expr
, input_location
);
4177 TREE_OPERAND (expr
, 0) = TREE_OPERAND (pred
, 1);
4178 /* Set the source location of the && on the second 'if'. */
4179 if (rexpr_has_location (pred
))
4180 SET_EXPR_LOCATION (expr
, rexpr_location (pred
));
4181 then_
= shortcut_cond_expr (expr
);
4182 then_se
= then_
&& TREE_SIDE_EFFECTS (then_
);
4183 pred
= TREE_OPERAND (pred
, 0);
4184 expr
= build3 (COND_EXPR
, void_type_node
, pred
, then_
, NULL_TREE
);
4185 SET_EXPR_LOCATION (expr
, locus
);
4191 /* If there is no 'then', turn
4194 if (a); else if (b); else d. */
4195 while (TREE_CODE (pred
) == TRUTH_ORIF_EXPR
)
4197 /* Keep the original source location on the first 'if'. */
4198 location_t locus
= EXPR_LOC_OR_LOC (expr
, input_location
);
4199 TREE_OPERAND (expr
, 0) = TREE_OPERAND (pred
, 1);
4200 /* Set the source location of the || on the second 'if'. */
4201 if (rexpr_has_location (pred
))
4202 SET_EXPR_LOCATION (expr
, rexpr_location (pred
));
4203 else_
= shortcut_cond_expr (expr
);
4204 else_se
= else_
&& TREE_SIDE_EFFECTS (else_
);
4205 pred
= TREE_OPERAND (pred
, 0);
4206 expr
= build3 (COND_EXPR
, void_type_node
, pred
, NULL_TREE
, else_
);
4207 SET_EXPR_LOCATION (expr
, locus
);
4211 /* If we're done, great. */
4212 if (TREE_CODE (pred
) != TRUTH_ANDIF_EXPR
4213 && TREE_CODE (pred
) != TRUTH_ORIF_EXPR
)
4216 /* Otherwise we need to mess with gotos. Change
4219 if (a); else goto no;
4222 and recursively gimplify the condition. */
4224 true_label
= false_label
= end_label
= NULL_TREE
;
4226 /* If our arms just jump somewhere, hijack those labels so we don't
4227 generate jumps to jumps. */
4229 if (tree then_goto
= find_goto_label (then_
))
4231 true_label
= GOTO_DESTINATION (then_goto
);
4236 if (tree else_goto
= find_goto_label (else_
))
4238 false_label
= GOTO_DESTINATION (else_goto
);
4243 /* If we aren't hijacking a label for the 'then' branch, it falls through. */
4245 true_label_p
= &true_label
;
4247 true_label_p
= NULL
;
4249 /* The 'else' branch also needs a label if it contains interesting code. */
4250 if (false_label
|| else_se
)
4251 false_label_p
= &false_label
;
4253 false_label_p
= NULL
;
4255 /* If there was nothing else in our arms, just forward the label(s). */
4256 if (!then_se
&& !else_se
)
4257 return shortcut_cond_r (pred
, true_label_p
, false_label_p
,
4258 EXPR_LOC_OR_LOC (expr
, input_location
));
4260 /* If our last subexpression already has a terminal label, reuse it. */
4262 t
= expr_last (else_
);
4264 t
= expr_last (then_
);
4267 if (t
&& TREE_CODE (t
) == LABEL_EXPR
)
4268 end_label
= LABEL_EXPR_LABEL (t
);
4270 /* If we don't care about jumping to the 'else' branch, jump to the end
4271 if the condition is false. */
4273 false_label_p
= &end_label
;
4275 /* We only want to emit these labels if we aren't hijacking them. */
4276 emit_end
= (end_label
== NULL_TREE
);
4277 emit_false
= (false_label
== NULL_TREE
);
4279 /* We only emit the jump over the else clause if we have to--if the
4280 then clause may fall through. Otherwise we can wind up with a
4281 useless jump and a useless label at the end of gimplified code,
4282 which will cause us to think that this conditional as a whole
4283 falls through even if it doesn't. If we then inline a function
4284 which ends with such a condition, that can cause us to issue an
4285 inappropriate warning about control reaching the end of a
4286 non-void function. */
4287 jump_over_else
= block_may_fallthru (then_
);
4289 pred
= shortcut_cond_r (pred
, true_label_p
, false_label_p
,
4290 EXPR_LOC_OR_LOC (expr
, input_location
));
4293 append_to_statement_list (pred
, &expr
);
4295 append_to_statement_list (then_
, &expr
);
4300 tree last
= expr_last (expr
);
4301 t
= build_and_jump (&end_label
);
4302 if (rexpr_has_location (last
))
4303 SET_EXPR_LOCATION (t
, rexpr_location (last
));
4304 append_to_statement_list (t
, &expr
);
4308 t
= build1 (LABEL_EXPR
, void_type_node
, false_label
);
4309 append_to_statement_list (t
, &expr
);
4311 append_to_statement_list (else_
, &expr
);
4313 if (emit_end
&& end_label
)
4315 t
= build1 (LABEL_EXPR
, void_type_node
, end_label
);
4316 append_to_statement_list (t
, &expr
);
4322 /* EXPR is used in a boolean context; make sure it has BOOLEAN_TYPE. */
4325 gimple_boolify (tree expr
)
4327 tree type
= TREE_TYPE (expr
);
4328 location_t loc
= EXPR_LOCATION (expr
);
4330 if (TREE_CODE (expr
) == NE_EXPR
4331 && TREE_CODE (TREE_OPERAND (expr
, 0)) == CALL_EXPR
4332 && integer_zerop (TREE_OPERAND (expr
, 1)))
4334 tree call
= TREE_OPERAND (expr
, 0);
4335 tree fn
= get_callee_fndecl (call
);
4337 /* For __builtin_expect ((long) (x), y) recurse into x as well
4338 if x is truth_value_p. */
4340 && fndecl_built_in_p (fn
, BUILT_IN_EXPECT
)
4341 && call_expr_nargs (call
) == 2)
4343 tree arg
= CALL_EXPR_ARG (call
, 0);
4346 if (TREE_CODE (arg
) == NOP_EXPR
4347 && TREE_TYPE (arg
) == TREE_TYPE (call
))
4348 arg
= TREE_OPERAND (arg
, 0);
4349 if (truth_value_p (TREE_CODE (arg
)))
4351 arg
= gimple_boolify (arg
);
4352 CALL_EXPR_ARG (call
, 0)
4353 = fold_convert_loc (loc
, TREE_TYPE (call
), arg
);
4359 switch (TREE_CODE (expr
))
4361 case TRUTH_AND_EXPR
:
4363 case TRUTH_XOR_EXPR
:
4364 case TRUTH_ANDIF_EXPR
:
4365 case TRUTH_ORIF_EXPR
:
4366 /* Also boolify the arguments of truth exprs. */
4367 TREE_OPERAND (expr
, 1) = gimple_boolify (TREE_OPERAND (expr
, 1));
4370 case TRUTH_NOT_EXPR
:
4371 TREE_OPERAND (expr
, 0) = gimple_boolify (TREE_OPERAND (expr
, 0));
4373 /* These expressions always produce boolean results. */
4374 if (TREE_CODE (type
) != BOOLEAN_TYPE
)
4375 TREE_TYPE (expr
) = boolean_type_node
;
4379 switch ((enum annot_expr_kind
) TREE_INT_CST_LOW (TREE_OPERAND (expr
, 1)))
4381 case annot_expr_ivdep_kind
:
4382 case annot_expr_unroll_kind
:
4383 case annot_expr_no_vector_kind
:
4384 case annot_expr_vector_kind
:
4385 case annot_expr_parallel_kind
:
4386 TREE_OPERAND (expr
, 0) = gimple_boolify (TREE_OPERAND (expr
, 0));
4387 if (TREE_CODE (type
) != BOOLEAN_TYPE
)
4388 TREE_TYPE (expr
) = boolean_type_node
;
4395 if (COMPARISON_CLASS_P (expr
))
4397 /* These expressions always produce boolean results. */
4398 if (TREE_CODE (type
) != BOOLEAN_TYPE
)
4399 TREE_TYPE (expr
) = boolean_type_node
;
4402 /* Other expressions that get here must have boolean values, but
4403 might need to be converted to the appropriate mode. */
4404 if (TREE_CODE (type
) == BOOLEAN_TYPE
)
4406 return fold_convert_loc (loc
, boolean_type_node
, expr
);
4410 /* Given a conditional expression *EXPR_P without side effects, gimplify
4411 its operands. New statements are inserted to PRE_P. */
4413 static enum gimplify_status
4414 gimplify_pure_cond_expr (tree
*expr_p
, gimple_seq
*pre_p
)
4416 tree expr
= *expr_p
, cond
;
4417 enum gimplify_status ret
, tret
;
4418 enum tree_code code
;
4420 cond
= gimple_boolify (COND_EXPR_COND (expr
));
4422 /* We need to handle && and || specially, as their gimplification
4423 creates pure cond_expr, thus leading to an infinite cycle otherwise. */
4424 code
= TREE_CODE (cond
);
4425 if (code
== TRUTH_ANDIF_EXPR
)
4426 TREE_SET_CODE (cond
, TRUTH_AND_EXPR
);
4427 else if (code
== TRUTH_ORIF_EXPR
)
4428 TREE_SET_CODE (cond
, TRUTH_OR_EXPR
);
4429 ret
= gimplify_expr (&cond
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
4430 COND_EXPR_COND (*expr_p
) = cond
;
4432 tret
= gimplify_expr (&COND_EXPR_THEN (expr
), pre_p
, NULL
,
4433 is_gimple_val
, fb_rvalue
);
4434 ret
= MIN (ret
, tret
);
4435 tret
= gimplify_expr (&COND_EXPR_ELSE (expr
), pre_p
, NULL
,
4436 is_gimple_val
, fb_rvalue
);
4438 return MIN (ret
, tret
);
4441 /* Return true if evaluating EXPR could trap.
4442 EXPR is GENERIC, while tree_could_trap_p can be called
4446 generic_expr_could_trap_p (tree expr
)
4450 if (!expr
|| is_gimple_val (expr
))
4453 if (!EXPR_P (expr
) || tree_could_trap_p (expr
))
4456 n
= TREE_OPERAND_LENGTH (expr
);
4457 for (i
= 0; i
< n
; i
++)
4458 if (generic_expr_could_trap_p (TREE_OPERAND (expr
, i
)))
4464 /* Convert the conditional expression pointed to by EXPR_P '(p) ? a : b;'
4473 The second form is used when *EXPR_P is of type void.
4475 PRE_P points to the list where side effects that must happen before
4476 *EXPR_P should be stored. */
4478 static enum gimplify_status
4479 gimplify_cond_expr (tree
*expr_p
, gimple_seq
*pre_p
, fallback_t fallback
)
4481 tree expr
= *expr_p
;
4482 tree type
= TREE_TYPE (expr
);
4483 location_t loc
= EXPR_LOCATION (expr
);
4484 tree tmp
, arm1
, arm2
;
4485 enum gimplify_status ret
;
4486 tree label_true
, label_false
, label_cont
;
4487 bool have_then_clause_p
, have_else_clause_p
;
4489 enum tree_code pred_code
;
4490 gimple_seq seq
= NULL
;
4492 /* If this COND_EXPR has a value, copy the values into a temporary within
4494 if (!VOID_TYPE_P (type
))
4496 tree then_
= TREE_OPERAND (expr
, 1), else_
= TREE_OPERAND (expr
, 2);
4499 /* If either an rvalue is ok or we do not require an lvalue, create the
4500 temporary. But we cannot do that if the type is addressable. */
4501 if (((fallback
& fb_rvalue
) || !(fallback
& fb_lvalue
))
4502 && !TREE_ADDRESSABLE (type
))
4504 if (gimplify_ctxp
->allow_rhs_cond_expr
4505 /* If either branch has side effects or could trap, it can't be
4506 evaluated unconditionally. */
4507 && !TREE_SIDE_EFFECTS (then_
)
4508 && !generic_expr_could_trap_p (then_
)
4509 && !TREE_SIDE_EFFECTS (else_
)
4510 && !generic_expr_could_trap_p (else_
))
4511 return gimplify_pure_cond_expr (expr_p
, pre_p
);
4513 tmp
= create_tmp_var (type
, "iftmp");
4517 /* Otherwise, only create and copy references to the values. */
4520 type
= build_pointer_type (type
);
4522 if (!VOID_TYPE_P (TREE_TYPE (then_
)))
4523 then_
= build_fold_addr_expr_loc (loc
, then_
);
4525 if (!VOID_TYPE_P (TREE_TYPE (else_
)))
4526 else_
= build_fold_addr_expr_loc (loc
, else_
);
4529 = build3 (COND_EXPR
, type
, TREE_OPERAND (expr
, 0), then_
, else_
);
4531 tmp
= create_tmp_var (type
, "iftmp");
4532 result
= build_simple_mem_ref_loc (loc
, tmp
);
4535 /* Build the new then clause, `tmp = then_;'. But don't build the
4536 assignment if the value is void; in C++ it can be if it's a throw. */
4537 if (!VOID_TYPE_P (TREE_TYPE (then_
)))
4538 TREE_OPERAND (expr
, 1) = build2 (INIT_EXPR
, type
, tmp
, then_
);
4540 /* Similarly, build the new else clause, `tmp = else_;'. */
4541 if (!VOID_TYPE_P (TREE_TYPE (else_
)))
4542 TREE_OPERAND (expr
, 2) = build2 (INIT_EXPR
, type
, tmp
, else_
);
4544 TREE_TYPE (expr
) = void_type_node
;
4545 recalculate_side_effects (expr
);
4547 /* Move the COND_EXPR to the prequeue. */
4548 gimplify_stmt (&expr
, pre_p
);
4554 /* Remove any COMPOUND_EXPR so the following cases will be caught. */
4555 STRIP_TYPE_NOPS (TREE_OPERAND (expr
, 0));
4556 if (TREE_CODE (TREE_OPERAND (expr
, 0)) == COMPOUND_EXPR
)
4557 gimplify_compound_expr (&TREE_OPERAND (expr
, 0), pre_p
, true);
4559 /* Make sure the condition has BOOLEAN_TYPE. */
4560 TREE_OPERAND (expr
, 0) = gimple_boolify (TREE_OPERAND (expr
, 0));
4562 /* Break apart && and || conditions. */
4563 if (TREE_CODE (TREE_OPERAND (expr
, 0)) == TRUTH_ANDIF_EXPR
4564 || TREE_CODE (TREE_OPERAND (expr
, 0)) == TRUTH_ORIF_EXPR
)
4566 expr
= shortcut_cond_expr (expr
);
4568 if (expr
!= *expr_p
)
4572 /* We can't rely on gimplify_expr to re-gimplify the expanded
4573 form properly, as cleanups might cause the target labels to be
4574 wrapped in a TRY_FINALLY_EXPR. To prevent that, we need to
4575 set up a conditional context. */
4576 gimple_push_condition ();
4577 gimplify_stmt (expr_p
, &seq
);
4578 gimple_pop_condition (pre_p
);
4579 gimple_seq_add_seq (pre_p
, seq
);
4585 /* Now do the normal gimplification. */
4587 /* Gimplify condition. */
4588 ret
= gimplify_expr (&TREE_OPERAND (expr
, 0), pre_p
, NULL
,
4589 is_gimple_condexpr_for_cond
, fb_rvalue
);
4590 if (ret
== GS_ERROR
)
4592 gcc_assert (TREE_OPERAND (expr
, 0) != NULL_TREE
);
4594 gimple_push_condition ();
4596 have_then_clause_p
= have_else_clause_p
= false;
4597 label_true
= find_goto_label (TREE_OPERAND (expr
, 1));
4599 && DECL_CONTEXT (GOTO_DESTINATION (label_true
)) == current_function_decl
4600 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4601 have different locations, otherwise we end up with incorrect
4602 location information on the branches. */
4604 || !EXPR_HAS_LOCATION (expr
)
4605 || !rexpr_has_location (label_true
)
4606 || EXPR_LOCATION (expr
) == rexpr_location (label_true
)))
4608 have_then_clause_p
= true;
4609 label_true
= GOTO_DESTINATION (label_true
);
4612 label_true
= create_artificial_label (UNKNOWN_LOCATION
);
4613 label_false
= find_goto_label (TREE_OPERAND (expr
, 2));
4615 && DECL_CONTEXT (GOTO_DESTINATION (label_false
)) == current_function_decl
4616 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4617 have different locations, otherwise we end up with incorrect
4618 location information on the branches. */
4620 || !EXPR_HAS_LOCATION (expr
)
4621 || !rexpr_has_location (label_false
)
4622 || EXPR_LOCATION (expr
) == rexpr_location (label_false
)))
4624 have_else_clause_p
= true;
4625 label_false
= GOTO_DESTINATION (label_false
);
4628 label_false
= create_artificial_label (UNKNOWN_LOCATION
);
4630 gimple_cond_get_ops_from_tree (COND_EXPR_COND (expr
), &pred_code
, &arm1
,
4632 cond_stmt
= gimple_build_cond (pred_code
, arm1
, arm2
, label_true
,
4634 gimple_set_location (cond_stmt
, EXPR_LOCATION (expr
));
4635 copy_warning (cond_stmt
, COND_EXPR_COND (expr
));
4636 gimplify_seq_add_stmt (&seq
, cond_stmt
);
4637 gimple_stmt_iterator gsi
= gsi_last (seq
);
4638 maybe_fold_stmt (&gsi
);
4640 label_cont
= NULL_TREE
;
4641 if (!have_then_clause_p
)
4643 /* For if (...) {} else { code; } put label_true after
4645 if (TREE_OPERAND (expr
, 1) == NULL_TREE
4646 && !have_else_clause_p
4647 && TREE_OPERAND (expr
, 2) != NULL_TREE
)
4649 /* For if (0) {} else { code; } tell -Wimplicit-fallthrough
4650 handling that label_cont == label_true can be only reached
4651 through fallthrough from { code; }. */
4652 if (integer_zerop (COND_EXPR_COND (expr
)))
4653 UNUSED_LABEL_P (label_true
) = 1;
4654 label_cont
= label_true
;
4658 bool then_side_effects
4659 = (TREE_OPERAND (expr
, 1)
4660 && TREE_SIDE_EFFECTS (TREE_OPERAND (expr
, 1)));
4661 gimplify_seq_add_stmt (&seq
, gimple_build_label (label_true
));
4662 have_then_clause_p
= gimplify_stmt (&TREE_OPERAND (expr
, 1), &seq
);
4663 /* For if (...) { code; } else {} or
4664 if (...) { code; } else goto label; or
4665 if (...) { code; return; } else { ... }
4666 label_cont isn't needed. */
4667 if (!have_else_clause_p
4668 && TREE_OPERAND (expr
, 2) != NULL_TREE
4669 && gimple_seq_may_fallthru (seq
))
4672 label_cont
= create_artificial_label (UNKNOWN_LOCATION
);
4674 /* For if (0) { non-side-effect-code } else { code }
4675 tell -Wimplicit-fallthrough handling that label_cont can
4676 be only reached through fallthrough from { code }. */
4677 if (integer_zerop (COND_EXPR_COND (expr
)))
4679 UNUSED_LABEL_P (label_true
) = 1;
4680 if (!then_side_effects
)
4681 UNUSED_LABEL_P (label_cont
) = 1;
4684 g
= gimple_build_goto (label_cont
);
4686 /* GIMPLE_COND's are very low level; they have embedded
4687 gotos. This particular embedded goto should not be marked
4688 with the location of the original COND_EXPR, as it would
4689 correspond to the COND_EXPR's condition, not the ELSE or the
4690 THEN arms. To avoid marking it with the wrong location, flag
4691 it as "no location". */
4692 gimple_set_do_not_emit_location (g
);
4694 gimplify_seq_add_stmt (&seq
, g
);
4698 if (!have_else_clause_p
)
4700 /* For if (1) { code } or if (1) { code } else { non-side-effect-code }
4701 tell -Wimplicit-fallthrough handling that label_false can be only
4702 reached through fallthrough from { code }. */
4703 if (integer_nonzerop (COND_EXPR_COND (expr
))
4704 && (TREE_OPERAND (expr
, 2) == NULL_TREE
4705 || !TREE_SIDE_EFFECTS (TREE_OPERAND (expr
, 2))))
4706 UNUSED_LABEL_P (label_false
) = 1;
4707 gimplify_seq_add_stmt (&seq
, gimple_build_label (label_false
));
4708 have_else_clause_p
= gimplify_stmt (&TREE_OPERAND (expr
, 2), &seq
);
4711 gimplify_seq_add_stmt (&seq
, gimple_build_label (label_cont
));
4713 gimple_pop_condition (pre_p
);
4714 gimple_seq_add_seq (pre_p
, seq
);
4716 if (ret
== GS_ERROR
)
4718 else if (have_then_clause_p
|| have_else_clause_p
)
4722 /* Both arms are empty; replace the COND_EXPR with its predicate. */
4723 expr
= TREE_OPERAND (expr
, 0);
4724 gimplify_stmt (&expr
, pre_p
);
4731 /* Prepare the node pointed to by EXPR_P, an is_gimple_addressable expression,
4732 to be marked addressable.
4734 We cannot rely on such an expression being directly markable if a temporary
4735 has been created by the gimplification. In this case, we create another
4736 temporary and initialize it with a copy, which will become a store after we
4737 mark it addressable. This can happen if the front-end passed us something
4738 that it could not mark addressable yet, like a Fortran pass-by-reference
4739 parameter (int) floatvar. */
4742 prepare_gimple_addressable (tree
*expr_p
, gimple_seq
*seq_p
)
4744 while (handled_component_p (*expr_p
))
4745 expr_p
= &TREE_OPERAND (*expr_p
, 0);
4747 /* Do not allow an SSA name as the temporary. */
4748 if (is_gimple_reg (*expr_p
))
4749 *expr_p
= internal_get_tmp_var (*expr_p
, seq_p
, NULL
, false, false, true);
4752 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4753 a call to __builtin_memcpy. */
4755 static enum gimplify_status
4756 gimplify_modify_expr_to_memcpy (tree
*expr_p
, tree size
, bool want_value
,
4759 tree t
, to
, to_ptr
, from
, from_ptr
;
4761 location_t loc
= EXPR_LOCATION (*expr_p
);
4763 to
= TREE_OPERAND (*expr_p
, 0);
4764 from
= TREE_OPERAND (*expr_p
, 1);
4766 /* Mark the RHS addressable. Beware that it may not be possible to do so
4767 directly if a temporary has been created by the gimplification. */
4768 prepare_gimple_addressable (&from
, seq_p
);
4770 mark_addressable (from
);
4771 from_ptr
= build_fold_addr_expr_loc (loc
, from
);
4772 gimplify_arg (&from_ptr
, seq_p
, loc
);
4774 mark_addressable (to
);
4775 to_ptr
= build_fold_addr_expr_loc (loc
, to
);
4776 gimplify_arg (&to_ptr
, seq_p
, loc
);
4778 t
= builtin_decl_implicit (BUILT_IN_MEMCPY
);
4780 gs
= gimple_build_call (t
, 3, to_ptr
, from_ptr
, size
);
4781 gimple_call_set_alloca_for_var (gs
, true);
4785 /* tmp = memcpy() */
4786 t
= create_tmp_var (TREE_TYPE (to_ptr
));
4787 gimple_call_set_lhs (gs
, t
);
4788 gimplify_seq_add_stmt (seq_p
, gs
);
4790 *expr_p
= build_simple_mem_ref (t
);
4794 gimplify_seq_add_stmt (seq_p
, gs
);
4799 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4800 a call to __builtin_memset. In this case we know that the RHS is
4801 a CONSTRUCTOR with an empty element list. */
4803 static enum gimplify_status
4804 gimplify_modify_expr_to_memset (tree
*expr_p
, tree size
, bool want_value
,
4807 tree t
, from
, to
, to_ptr
;
4809 location_t loc
= EXPR_LOCATION (*expr_p
);
4811 /* Assert our assumptions, to abort instead of producing wrong code
4812 silently if they are not met. Beware that the RHS CONSTRUCTOR might
4813 not be immediately exposed. */
4814 from
= TREE_OPERAND (*expr_p
, 1);
4815 if (TREE_CODE (from
) == WITH_SIZE_EXPR
)
4816 from
= TREE_OPERAND (from
, 0);
4818 gcc_assert (TREE_CODE (from
) == CONSTRUCTOR
4819 && vec_safe_is_empty (CONSTRUCTOR_ELTS (from
)));
4822 to
= TREE_OPERAND (*expr_p
, 0);
4824 to_ptr
= build_fold_addr_expr_loc (loc
, to
);
4825 gimplify_arg (&to_ptr
, seq_p
, loc
);
4826 t
= builtin_decl_implicit (BUILT_IN_MEMSET
);
4828 gs
= gimple_build_call (t
, 3, to_ptr
, integer_zero_node
, size
);
4832 /* tmp = memset() */
4833 t
= create_tmp_var (TREE_TYPE (to_ptr
));
4834 gimple_call_set_lhs (gs
, t
);
4835 gimplify_seq_add_stmt (seq_p
, gs
);
4837 *expr_p
= build1 (INDIRECT_REF
, TREE_TYPE (to
), t
);
4841 gimplify_seq_add_stmt (seq_p
, gs
);
4846 /* A subroutine of gimplify_init_ctor_preeval. Called via walk_tree,
4847 determine, cautiously, if a CONSTRUCTOR overlaps the lhs of an
4848 assignment. Return non-null if we detect a potential overlap. */
4850 struct gimplify_init_ctor_preeval_data
4852 /* The base decl of the lhs object. May be NULL, in which case we
4853 have to assume the lhs is indirect. */
4856 /* The alias set of the lhs object. */
4857 alias_set_type lhs_alias_set
;
4861 gimplify_init_ctor_preeval_1 (tree
*tp
, int *walk_subtrees
, void *xdata
)
4863 struct gimplify_init_ctor_preeval_data
*data
4864 = (struct gimplify_init_ctor_preeval_data
*) xdata
;
4867 /* If we find the base object, obviously we have overlap. */
4868 if (data
->lhs_base_decl
== t
)
4871 /* If the constructor component is indirect, determine if we have a
4872 potential overlap with the lhs. The only bits of information we
4873 have to go on at this point are addressability and alias sets. */
4874 if ((INDIRECT_REF_P (t
)
4875 || TREE_CODE (t
) == MEM_REF
)
4876 && (!data
->lhs_base_decl
|| TREE_ADDRESSABLE (data
->lhs_base_decl
))
4877 && alias_sets_conflict_p (data
->lhs_alias_set
, get_alias_set (t
)))
4880 /* If the constructor component is a call, determine if it can hide a
4881 potential overlap with the lhs through an INDIRECT_REF like above.
4882 ??? Ugh - this is completely broken. In fact this whole analysis
4883 doesn't look conservative. */
4884 if (TREE_CODE (t
) == CALL_EXPR
)
4886 tree type
, fntype
= TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (t
)));
4888 for (type
= TYPE_ARG_TYPES (fntype
); type
; type
= TREE_CHAIN (type
))
4889 if (POINTER_TYPE_P (TREE_VALUE (type
))
4890 && (!data
->lhs_base_decl
|| TREE_ADDRESSABLE (data
->lhs_base_decl
))
4891 && alias_sets_conflict_p (data
->lhs_alias_set
,
4893 (TREE_TYPE (TREE_VALUE (type
)))))
4897 if (IS_TYPE_OR_DECL_P (t
))
4902 /* A subroutine of gimplify_init_constructor. Pre-evaluate EXPR,
4903 force values that overlap with the lhs (as described by *DATA)
4904 into temporaries. */
4907 gimplify_init_ctor_preeval (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
4908 struct gimplify_init_ctor_preeval_data
*data
)
4910 enum gimplify_status one
;
4912 /* If the value is constant, then there's nothing to pre-evaluate. */
4913 if (TREE_CONSTANT (*expr_p
))
4915 /* Ensure it does not have side effects, it might contain a reference to
4916 the object we're initializing. */
4917 gcc_assert (!TREE_SIDE_EFFECTS (*expr_p
));
4921 /* If the type has non-trivial constructors, we can't pre-evaluate. */
4922 if (TREE_ADDRESSABLE (TREE_TYPE (*expr_p
)))
4925 /* Recurse for nested constructors. */
4926 if (TREE_CODE (*expr_p
) == CONSTRUCTOR
)
4928 unsigned HOST_WIDE_INT ix
;
4929 constructor_elt
*ce
;
4930 vec
<constructor_elt
, va_gc
> *v
= CONSTRUCTOR_ELTS (*expr_p
);
4932 FOR_EACH_VEC_SAFE_ELT (v
, ix
, ce
)
4933 gimplify_init_ctor_preeval (&ce
->value
, pre_p
, post_p
, data
);
4938 /* If this is a variable sized type, we must remember the size. */
4939 maybe_with_size_expr (expr_p
);
4941 /* Gimplify the constructor element to something appropriate for the rhs
4942 of a MODIFY_EXPR. Given that we know the LHS is an aggregate, we know
4943 the gimplifier will consider this a store to memory. Doing this
4944 gimplification now means that we won't have to deal with complicated
4945 language-specific trees, nor trees like SAVE_EXPR that can induce
4946 exponential search behavior. */
4947 one
= gimplify_expr (expr_p
, pre_p
, post_p
, is_gimple_mem_rhs
, fb_rvalue
);
4948 if (one
== GS_ERROR
)
4954 /* If we gimplified to a bare decl, we can be sure that it doesn't overlap
4955 with the lhs, since "a = { .x=a }" doesn't make sense. This will
4956 always be true for all scalars, since is_gimple_mem_rhs insists on a
4957 temporary variable for them. */
4958 if (DECL_P (*expr_p
))
4961 /* If this is of variable size, we have no choice but to assume it doesn't
4962 overlap since we can't make a temporary for it. */
4963 if (TREE_CODE (TYPE_SIZE (TREE_TYPE (*expr_p
))) != INTEGER_CST
)
4966 /* Otherwise, we must search for overlap ... */
4967 if (!walk_tree (expr_p
, gimplify_init_ctor_preeval_1
, data
, NULL
))
4970 /* ... and if found, force the value into a temporary. */
4971 *expr_p
= get_formal_tmp_var (*expr_p
, pre_p
);
4974 /* A subroutine of gimplify_init_ctor_eval. Create a loop for
4975 a RANGE_EXPR in a CONSTRUCTOR for an array.
4979 object[var] = value;
4986 We increment var _after_ the loop exit check because we might otherwise
4987 fail if upper == TYPE_MAX_VALUE (type for upper).
4989 Note that we never have to deal with SAVE_EXPRs here, because this has
4990 already been taken care of for us, in gimplify_init_ctor_preeval(). */
4992 static void gimplify_init_ctor_eval (tree
, vec
<constructor_elt
, va_gc
> *,
4993 gimple_seq
*, bool);
4996 gimplify_init_ctor_eval_range (tree object
, tree lower
, tree upper
,
4997 tree value
, tree array_elt_type
,
4998 gimple_seq
*pre_p
, bool cleared
)
5000 tree loop_entry_label
, loop_exit_label
, fall_thru_label
;
5001 tree var
, var_type
, cref
, tmp
;
5003 loop_entry_label
= create_artificial_label (UNKNOWN_LOCATION
);
5004 loop_exit_label
= create_artificial_label (UNKNOWN_LOCATION
);
5005 fall_thru_label
= create_artificial_label (UNKNOWN_LOCATION
);
5007 /* Create and initialize the index variable. */
5008 var_type
= TREE_TYPE (upper
);
5009 var
= create_tmp_var (var_type
);
5010 gimplify_seq_add_stmt (pre_p
, gimple_build_assign (var
, lower
));
5012 /* Add the loop entry label. */
5013 gimplify_seq_add_stmt (pre_p
, gimple_build_label (loop_entry_label
));
5015 /* Build the reference. */
5016 cref
= build4 (ARRAY_REF
, array_elt_type
, unshare_expr (object
),
5017 var
, NULL_TREE
, NULL_TREE
);
5019 /* If we are a constructor, just call gimplify_init_ctor_eval to do
5020 the store. Otherwise just assign value to the reference. */
5022 if (TREE_CODE (value
) == CONSTRUCTOR
)
5023 /* NB we might have to call ourself recursively through
5024 gimplify_init_ctor_eval if the value is a constructor. */
5025 gimplify_init_ctor_eval (cref
, CONSTRUCTOR_ELTS (value
),
5029 if (gimplify_expr (&value
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
)
5031 gimplify_seq_add_stmt (pre_p
, gimple_build_assign (cref
, value
));
5034 /* We exit the loop when the index var is equal to the upper bound. */
5035 gimplify_seq_add_stmt (pre_p
,
5036 gimple_build_cond (EQ_EXPR
, var
, upper
,
5037 loop_exit_label
, fall_thru_label
));
5039 gimplify_seq_add_stmt (pre_p
, gimple_build_label (fall_thru_label
));
5041 /* Otherwise, increment the index var... */
5042 tmp
= build2 (PLUS_EXPR
, var_type
, var
,
5043 fold_convert (var_type
, integer_one_node
));
5044 gimplify_seq_add_stmt (pre_p
, gimple_build_assign (var
, tmp
));
5046 /* ...and jump back to the loop entry. */
5047 gimplify_seq_add_stmt (pre_p
, gimple_build_goto (loop_entry_label
));
5049 /* Add the loop exit label. */
5050 gimplify_seq_add_stmt (pre_p
, gimple_build_label (loop_exit_label
));
5053 /* A subroutine of gimplify_init_constructor. Generate individual
5054 MODIFY_EXPRs for a CONSTRUCTOR. OBJECT is the LHS against which the
5055 assignments should happen. ELTS is the CONSTRUCTOR_ELTS of the
5056 CONSTRUCTOR. CLEARED is true if the entire LHS object has been
5060 gimplify_init_ctor_eval (tree object
, vec
<constructor_elt
, va_gc
> *elts
,
5061 gimple_seq
*pre_p
, bool cleared
)
5063 tree array_elt_type
= NULL
;
5064 unsigned HOST_WIDE_INT ix
;
5065 tree purpose
, value
;
5067 if (TREE_CODE (TREE_TYPE (object
)) == ARRAY_TYPE
)
5068 array_elt_type
= TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (object
)));
5070 FOR_EACH_CONSTRUCTOR_ELT (elts
, ix
, purpose
, value
)
5074 /* NULL values are created above for gimplification errors. */
5078 if (cleared
&& initializer_zerop (value
))
5081 /* ??? Here's to hoping the front end fills in all of the indices,
5082 so we don't have to figure out what's missing ourselves. */
5083 gcc_assert (purpose
);
5085 /* Skip zero-sized fields, unless value has side-effects. This can
5086 happen with calls to functions returning a empty type, which
5087 we shouldn't discard. As a number of downstream passes don't
5088 expect sets of empty type fields, we rely on the gimplification of
5089 the MODIFY_EXPR we make below to drop the assignment statement. */
5090 if (!TREE_SIDE_EFFECTS (value
)
5091 && TREE_CODE (purpose
) == FIELD_DECL
5092 && is_empty_type (TREE_TYPE (purpose
)))
5095 /* If we have a RANGE_EXPR, we have to build a loop to assign the
5097 if (TREE_CODE (purpose
) == RANGE_EXPR
)
5099 tree lower
= TREE_OPERAND (purpose
, 0);
5100 tree upper
= TREE_OPERAND (purpose
, 1);
5102 /* If the lower bound is equal to upper, just treat it as if
5103 upper was the index. */
5104 if (simple_cst_equal (lower
, upper
))
5108 gimplify_init_ctor_eval_range (object
, lower
, upper
, value
,
5109 array_elt_type
, pre_p
, cleared
);
5116 /* Do not use bitsizetype for ARRAY_REF indices. */
5117 if (TYPE_DOMAIN (TREE_TYPE (object
)))
5119 = fold_convert (TREE_TYPE (TYPE_DOMAIN (TREE_TYPE (object
))),
5121 cref
= build4 (ARRAY_REF
, array_elt_type
, unshare_expr (object
),
5122 purpose
, NULL_TREE
, NULL_TREE
);
5126 gcc_assert (TREE_CODE (purpose
) == FIELD_DECL
);
5127 cref
= build3 (COMPONENT_REF
, TREE_TYPE (purpose
),
5128 unshare_expr (object
), purpose
, NULL_TREE
);
5131 if (TREE_CODE (value
) == CONSTRUCTOR
5132 && TREE_CODE (TREE_TYPE (value
)) != VECTOR_TYPE
)
5133 gimplify_init_ctor_eval (cref
, CONSTRUCTOR_ELTS (value
),
5137 tree init
= build2 (INIT_EXPR
, TREE_TYPE (cref
), cref
, value
);
5138 gimplify_and_add (init
, pre_p
);
5144 /* Return the appropriate RHS predicate for this LHS. */
5147 rhs_predicate_for (tree lhs
)
5149 if (is_gimple_reg (lhs
))
5150 return is_gimple_reg_rhs_or_call
;
5152 return is_gimple_mem_rhs_or_call
;
5155 /* Return the initial guess for an appropriate RHS predicate for this LHS,
5156 before the LHS has been gimplified. */
5158 static gimple_predicate
5159 initial_rhs_predicate_for (tree lhs
)
5161 if (is_gimple_reg_type (TREE_TYPE (lhs
)))
5162 return is_gimple_reg_rhs_or_call
;
5164 return is_gimple_mem_rhs_or_call
;
5167 /* Gimplify a C99 compound literal expression. This just means adding
5168 the DECL_EXPR before the current statement and using its anonymous
5171 static enum gimplify_status
5172 gimplify_compound_literal_expr (tree
*expr_p
, gimple_seq
*pre_p
,
5173 bool (*gimple_test_f
) (tree
),
5174 fallback_t fallback
)
5176 tree decl_s
= COMPOUND_LITERAL_EXPR_DECL_EXPR (*expr_p
);
5177 tree decl
= DECL_EXPR_DECL (decl_s
);
5178 tree init
= DECL_INITIAL (decl
);
5179 /* Mark the decl as addressable if the compound literal
5180 expression is addressable now, otherwise it is marked too late
5181 after we gimplify the initialization expression. */
5182 if (TREE_ADDRESSABLE (*expr_p
))
5183 TREE_ADDRESSABLE (decl
) = 1;
5184 /* Otherwise, if we don't need an lvalue and have a literal directly
5185 substitute it. Check if it matches the gimple predicate, as
5186 otherwise we'd generate a new temporary, and we can as well just
5187 use the decl we already have. */
5188 else if (!TREE_ADDRESSABLE (decl
)
5189 && !TREE_THIS_VOLATILE (decl
)
5191 && (fallback
& fb_lvalue
) == 0
5192 && gimple_test_f (init
))
5198 /* If the decl is not addressable, then it is being used in some
5199 expression or on the right hand side of a statement, and it can
5200 be put into a readonly data section. */
5201 if (!TREE_ADDRESSABLE (decl
) && (fallback
& fb_lvalue
) == 0)
5202 TREE_READONLY (decl
) = 1;
5204 /* This decl isn't mentioned in the enclosing block, so add it to the
5205 list of temps. FIXME it seems a bit of a kludge to say that
5206 anonymous artificial vars aren't pushed, but everything else is. */
5207 if (DECL_NAME (decl
) == NULL_TREE
&& !DECL_SEEN_IN_BIND_EXPR_P (decl
))
5208 gimple_add_tmp_var (decl
);
5210 gimplify_and_add (decl_s
, pre_p
);
5215 /* Optimize embedded COMPOUND_LITERAL_EXPRs within a CONSTRUCTOR,
5216 return a new CONSTRUCTOR if something changed. */
5219 optimize_compound_literals_in_ctor (tree orig_ctor
)
5221 tree ctor
= orig_ctor
;
5222 vec
<constructor_elt
, va_gc
> *elts
= CONSTRUCTOR_ELTS (ctor
);
5223 unsigned int idx
, num
= vec_safe_length (elts
);
5225 for (idx
= 0; idx
< num
; idx
++)
5227 tree value
= (*elts
)[idx
].value
;
5228 tree newval
= value
;
5229 if (TREE_CODE (value
) == CONSTRUCTOR
)
5230 newval
= optimize_compound_literals_in_ctor (value
);
5231 else if (TREE_CODE (value
) == COMPOUND_LITERAL_EXPR
)
5233 tree decl_s
= COMPOUND_LITERAL_EXPR_DECL_EXPR (value
);
5234 tree decl
= DECL_EXPR_DECL (decl_s
);
5235 tree init
= DECL_INITIAL (decl
);
5237 if (!TREE_ADDRESSABLE (value
)
5238 && !TREE_ADDRESSABLE (decl
)
5240 && TREE_CODE (init
) == CONSTRUCTOR
)
5241 newval
= optimize_compound_literals_in_ctor (init
);
5243 if (newval
== value
)
5246 if (ctor
== orig_ctor
)
5248 ctor
= copy_node (orig_ctor
);
5249 CONSTRUCTOR_ELTS (ctor
) = vec_safe_copy (elts
);
5250 elts
= CONSTRUCTOR_ELTS (ctor
);
5252 (*elts
)[idx
].value
= newval
;
5257 /* A subroutine of gimplify_modify_expr. Break out elements of a
5258 CONSTRUCTOR used as an initializer into separate MODIFY_EXPRs.
5260 Note that we still need to clear any elements that don't have explicit
5261 initializers, so if not all elements are initialized we keep the
5262 original MODIFY_EXPR, we just remove all of the constructor elements.
5264 If NOTIFY_TEMP_CREATION is true, do not gimplify, just return
5265 GS_ERROR if we would have to create a temporary when gimplifying
5266 this constructor. Otherwise, return GS_OK.
5268 If NOTIFY_TEMP_CREATION is false, just do the gimplification. */
5270 static enum gimplify_status
5271 gimplify_init_constructor (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
5272 bool want_value
, bool notify_temp_creation
)
5274 tree object
, ctor
, type
;
5275 enum gimplify_status ret
;
5276 vec
<constructor_elt
, va_gc
> *elts
;
5277 bool cleared
= false;
5278 bool is_empty_ctor
= false;
5279 bool is_init_expr
= (TREE_CODE (*expr_p
) == INIT_EXPR
);
5281 gcc_assert (TREE_CODE (TREE_OPERAND (*expr_p
, 1)) == CONSTRUCTOR
);
5283 if (!notify_temp_creation
)
5285 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
5286 is_gimple_lvalue
, fb_lvalue
);
5287 if (ret
== GS_ERROR
)
5291 object
= TREE_OPERAND (*expr_p
, 0);
5292 ctor
= TREE_OPERAND (*expr_p
, 1)
5293 = optimize_compound_literals_in_ctor (TREE_OPERAND (*expr_p
, 1));
5294 type
= TREE_TYPE (ctor
);
5295 elts
= CONSTRUCTOR_ELTS (ctor
);
5298 switch (TREE_CODE (type
))
5302 case QUAL_UNION_TYPE
:
5305 /* Use readonly data for initializers of this or smaller size
5306 regardless of the num_nonzero_elements / num_unique_nonzero_elements
5308 const HOST_WIDE_INT min_unique_size
= 64;
5309 /* If num_nonzero_elements / num_unique_nonzero_elements ratio
5310 is smaller than this, use readonly data. */
5311 const int unique_nonzero_ratio
= 8;
5312 /* True if a single access of the object must be ensured. This is the
5313 case if the target is volatile, the type is non-addressable and more
5314 than one field need to be assigned. */
5315 const bool ensure_single_access
5316 = TREE_THIS_VOLATILE (object
)
5317 && !TREE_ADDRESSABLE (type
)
5318 && vec_safe_length (elts
) > 1;
5319 struct gimplify_init_ctor_preeval_data preeval_data
;
5320 HOST_WIDE_INT num_ctor_elements
, num_nonzero_elements
;
5321 HOST_WIDE_INT num_unique_nonzero_elements
;
5322 bool complete_p
, valid_const_initializer
;
5324 /* Aggregate types must lower constructors to initialization of
5325 individual elements. The exception is that a CONSTRUCTOR node
5326 with no elements indicates zero-initialization of the whole. */
5327 if (vec_safe_is_empty (elts
))
5329 if (notify_temp_creation
)
5332 /* The var will be initialized and so appear on lhs of
5333 assignment, it can't be TREE_READONLY anymore. */
5335 TREE_READONLY (object
) = 0;
5337 is_empty_ctor
= true;
5341 /* Fetch information about the constructor to direct later processing.
5342 We might want to make static versions of it in various cases, and
5343 can only do so if it known to be a valid constant initializer. */
5344 valid_const_initializer
5345 = categorize_ctor_elements (ctor
, &num_nonzero_elements
,
5346 &num_unique_nonzero_elements
,
5347 &num_ctor_elements
, &complete_p
);
5349 /* If a const aggregate variable is being initialized, then it
5350 should never be a lose to promote the variable to be static. */
5351 if (valid_const_initializer
5352 && num_nonzero_elements
> 1
5353 && TREE_READONLY (object
)
5355 && !DECL_REGISTER (object
)
5356 && (flag_merge_constants
>= 2 || !TREE_ADDRESSABLE (object
)
5357 || DECL_MERGEABLE (object
))
5358 /* For ctors that have many repeated nonzero elements
5359 represented through RANGE_EXPRs, prefer initializing
5360 those through runtime loops over copies of large amounts
5361 of data from readonly data section. */
5362 && (num_unique_nonzero_elements
5363 > num_nonzero_elements
/ unique_nonzero_ratio
5364 || ((unsigned HOST_WIDE_INT
) int_size_in_bytes (type
)
5365 <= (unsigned HOST_WIDE_INT
) min_unique_size
)))
5367 if (notify_temp_creation
)
5370 DECL_INITIAL (object
) = ctor
;
5371 TREE_STATIC (object
) = 1;
5372 if (!DECL_NAME (object
))
5373 DECL_NAME (object
) = create_tmp_var_name ("C");
5374 walk_tree (&DECL_INITIAL (object
), force_labels_r
, NULL
, NULL
);
5376 /* ??? C++ doesn't automatically append a .<number> to the
5377 assembler name, and even when it does, it looks at FE private
5378 data structures to figure out what that number should be,
5379 which are not set for this variable. I suppose this is
5380 important for local statics for inline functions, which aren't
5381 "local" in the object file sense. So in order to get a unique
5382 TU-local symbol, we must invoke the lhd version now. */
5383 lhd_set_decl_assembler_name (object
);
5385 *expr_p
= NULL_TREE
;
5389 /* The var will be initialized and so appear on lhs of
5390 assignment, it can't be TREE_READONLY anymore. */
5391 if (VAR_P (object
) && !notify_temp_creation
)
5392 TREE_READONLY (object
) = 0;
5394 /* If there are "lots" of initialized elements, even discounting
5395 those that are not address constants (and thus *must* be
5396 computed at runtime), then partition the constructor into
5397 constant and non-constant parts. Block copy the constant
5398 parts in, then generate code for the non-constant parts. */
5399 /* TODO. There's code in cp/typeck.cc to do this. */
5401 if (int_size_in_bytes (TREE_TYPE (ctor
)) < 0)
5402 /* store_constructor will ignore the clearing of variable-sized
5403 objects. Initializers for such objects must explicitly set
5404 every field that needs to be set. */
5406 else if (!complete_p
)
5407 /* If the constructor isn't complete, clear the whole object
5408 beforehand, unless CONSTRUCTOR_NO_CLEARING is set on it.
5410 ??? This ought not to be needed. For any element not present
5411 in the initializer, we should simply set them to zero. Except
5412 we'd need to *find* the elements that are not present, and that
5413 requires trickery to avoid quadratic compile-time behavior in
5414 large cases or excessive memory use in small cases. */
5415 cleared
= !CONSTRUCTOR_NO_CLEARING (ctor
);
5416 else if (num_ctor_elements
- num_nonzero_elements
5417 > CLEAR_RATIO (optimize_function_for_speed_p (cfun
))
5418 && num_nonzero_elements
< num_ctor_elements
/ 4)
5419 /* If there are "lots" of zeros, it's more efficient to clear
5420 the memory and then set the nonzero elements. */
5422 else if (ensure_single_access
&& num_nonzero_elements
== 0)
5423 /* If a single access to the target must be ensured and all elements
5424 are zero, then it's optimal to clear whatever their number. */
5429 /* If there are "lots" of initialized elements, and all of them
5430 are valid address constants, then the entire initializer can
5431 be dropped to memory, and then memcpy'd out. Don't do this
5432 for sparse arrays, though, as it's more efficient to follow
5433 the standard CONSTRUCTOR behavior of memset followed by
5434 individual element initialization. Also don't do this for small
5435 all-zero initializers (which aren't big enough to merit
5436 clearing), and don't try to make bitwise copies of
5437 TREE_ADDRESSABLE types. */
5438 if (valid_const_initializer
5440 && !(cleared
|| num_nonzero_elements
== 0)
5441 && !TREE_ADDRESSABLE (type
))
5443 HOST_WIDE_INT size
= int_size_in_bytes (type
);
5446 /* ??? We can still get unbounded array types, at least
5447 from the C++ front end. This seems wrong, but attempt
5448 to work around it for now. */
5451 size
= int_size_in_bytes (TREE_TYPE (object
));
5453 TREE_TYPE (ctor
) = type
= TREE_TYPE (object
);
5456 /* Find the maximum alignment we can assume for the object. */
5457 /* ??? Make use of DECL_OFFSET_ALIGN. */
5458 if (DECL_P (object
))
5459 align
= DECL_ALIGN (object
);
5461 align
= TYPE_ALIGN (type
);
5463 /* Do a block move either if the size is so small as to make
5464 each individual move a sub-unit move on average, or if it
5465 is so large as to make individual moves inefficient. */
5467 && num_nonzero_elements
> 1
5468 /* For ctors that have many repeated nonzero elements
5469 represented through RANGE_EXPRs, prefer initializing
5470 those through runtime loops over copies of large amounts
5471 of data from readonly data section. */
5472 && (num_unique_nonzero_elements
5473 > num_nonzero_elements
/ unique_nonzero_ratio
5474 || size
<= min_unique_size
)
5475 && (size
< num_nonzero_elements
5476 || !can_move_by_pieces (size
, align
)))
5478 if (notify_temp_creation
)
5481 walk_tree (&ctor
, force_labels_r
, NULL
, NULL
);
5482 ctor
= tree_output_constant_def (ctor
);
5483 if (!useless_type_conversion_p (type
, TREE_TYPE (ctor
)))
5484 ctor
= build1 (VIEW_CONVERT_EXPR
, type
, ctor
);
5485 TREE_OPERAND (*expr_p
, 1) = ctor
;
5487 /* This is no longer an assignment of a CONSTRUCTOR, but
5488 we still may have processing to do on the LHS. So
5489 pretend we didn't do anything here to let that happen. */
5490 return GS_UNHANDLED
;
5494 /* If a single access to the target must be ensured and there are
5495 nonzero elements or the zero elements are not assigned en masse,
5496 initialize the target from a temporary. */
5497 if (ensure_single_access
&& (num_nonzero_elements
> 0 || !cleared
))
5499 if (notify_temp_creation
)
5502 tree temp
= create_tmp_var (TYPE_MAIN_VARIANT (type
));
5503 TREE_OPERAND (*expr_p
, 0) = temp
;
5504 *expr_p
= build2 (COMPOUND_EXPR
, TREE_TYPE (*expr_p
),
5506 build2 (MODIFY_EXPR
, void_type_node
,
5511 if (notify_temp_creation
)
5514 /* If there are nonzero elements and if needed, pre-evaluate to capture
5515 elements overlapping with the lhs into temporaries. We must do this
5516 before clearing to fetch the values before they are zeroed-out. */
5517 if (num_nonzero_elements
> 0 && TREE_CODE (*expr_p
) != INIT_EXPR
)
5519 preeval_data
.lhs_base_decl
= get_base_address (object
);
5520 if (!DECL_P (preeval_data
.lhs_base_decl
))
5521 preeval_data
.lhs_base_decl
= NULL
;
5522 preeval_data
.lhs_alias_set
= get_alias_set (object
);
5524 gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p
, 1),
5525 pre_p
, post_p
, &preeval_data
);
5528 bool ctor_has_side_effects_p
5529 = TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p
, 1));
5533 /* Zap the CONSTRUCTOR element list, which simplifies this case.
5534 Note that we still have to gimplify, in order to handle the
5535 case of variable sized types. Avoid shared tree structures. */
5536 CONSTRUCTOR_ELTS (ctor
) = NULL
;
5537 TREE_SIDE_EFFECTS (ctor
) = 0;
5538 object
= unshare_expr (object
);
5539 gimplify_stmt (expr_p
, pre_p
);
5542 /* If we have not block cleared the object, or if there are nonzero
5543 elements in the constructor, or if the constructor has side effects,
5544 add assignments to the individual scalar fields of the object. */
5546 || num_nonzero_elements
> 0
5547 || ctor_has_side_effects_p
)
5548 gimplify_init_ctor_eval (object
, elts
, pre_p
, cleared
);
5550 *expr_p
= NULL_TREE
;
5558 if (notify_temp_creation
)
5561 /* Extract the real and imaginary parts out of the ctor. */
5562 gcc_assert (elts
->length () == 2);
5563 r
= (*elts
)[0].value
;
5564 i
= (*elts
)[1].value
;
5565 if (r
== NULL
|| i
== NULL
)
5567 tree zero
= build_zero_cst (TREE_TYPE (type
));
5574 /* Complex types have either COMPLEX_CST or COMPLEX_EXPR to
5575 represent creation of a complex value. */
5576 if (TREE_CONSTANT (r
) && TREE_CONSTANT (i
))
5578 ctor
= build_complex (type
, r
, i
);
5579 TREE_OPERAND (*expr_p
, 1) = ctor
;
5583 ctor
= build2 (COMPLEX_EXPR
, type
, r
, i
);
5584 TREE_OPERAND (*expr_p
, 1) = ctor
;
5585 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 1),
5588 rhs_predicate_for (TREE_OPERAND (*expr_p
, 0)),
5596 unsigned HOST_WIDE_INT ix
;
5597 constructor_elt
*ce
;
5599 if (notify_temp_creation
)
5602 /* Vector types use CONSTRUCTOR all the way through gimple
5603 compilation as a general initializer. */
5604 FOR_EACH_VEC_SAFE_ELT (elts
, ix
, ce
)
5606 enum gimplify_status tret
;
5607 tret
= gimplify_expr (&ce
->value
, pre_p
, post_p
, is_gimple_val
,
5609 if (tret
== GS_ERROR
)
5611 else if (TREE_STATIC (ctor
)
5612 && !initializer_constant_valid_p (ce
->value
,
5613 TREE_TYPE (ce
->value
)))
5614 TREE_STATIC (ctor
) = 0;
5616 recompute_constructor_flags (ctor
);
5618 /* Go ahead and simplify constant constructors to VECTOR_CST. */
5619 if (TREE_CONSTANT (ctor
))
5621 bool constant_p
= true;
5624 /* Even when ctor is constant, it might contain non-*_CST
5625 elements, such as addresses or trapping values like
5626 1.0/0.0 - 1.0/0.0. Such expressions don't belong
5627 in VECTOR_CST nodes. */
5628 FOR_EACH_CONSTRUCTOR_VALUE (elts
, ix
, value
)
5629 if (!CONSTANT_CLASS_P (value
))
5637 TREE_OPERAND (*expr_p
, 1) = build_vector_from_ctor (type
, elts
);
5642 if (!is_gimple_reg (TREE_OPERAND (*expr_p
, 0)))
5643 TREE_OPERAND (*expr_p
, 1) = get_formal_tmp_var (ctor
, pre_p
);
5648 /* So how did we get a CONSTRUCTOR for a scalar type? */
5652 if (ret
== GS_ERROR
)
5654 /* If we have gimplified both sides of the initializer but have
5655 not emitted an assignment, do so now. */
5657 /* If the type is an empty type, we don't need to emit the
5659 && !is_empty_type (TREE_TYPE (TREE_OPERAND (*expr_p
, 0))))
5661 tree lhs
= TREE_OPERAND (*expr_p
, 0);
5662 tree rhs
= TREE_OPERAND (*expr_p
, 1);
5663 if (want_value
&& object
== lhs
)
5664 lhs
= unshare_expr (lhs
);
5665 gassign
*init
= gimple_build_assign (lhs
, rhs
);
5666 gimplify_seq_add_stmt (pre_p
, init
);
5679 /* If the user requests to initialize automatic variables, we
5680 should initialize paddings inside the variable. Add a call to
5681 __builtin_clear_pading (&object, 0, for_auto_init = true) to
5682 initialize paddings of object always to zero regardless of
5683 INIT_TYPE. Note, we will not insert this call if the aggregate
5684 variable has be completely cleared already or it's initialized
5685 with an empty constructor. We cannot insert this call if the
5686 variable is a gimple register since __builtin_clear_padding will take
5687 the address of the variable. As a result, if a long double/_Complex long
5688 double variable will be spilled into stack later, its padding cannot
5689 be cleared with __builtin_clear_padding. We should clear its padding
5690 when it is spilled into memory. */
5692 && !is_gimple_reg (object
)
5693 && clear_padding_type_may_have_padding_p (type
)
5694 && ((AGGREGATE_TYPE_P (type
) && !cleared
&& !is_empty_ctor
)
5695 || !AGGREGATE_TYPE_P (type
))
5696 && is_var_need_auto_init (object
))
5697 gimple_add_padding_init_for_auto_var (object
, false, pre_p
);
5702 /* Given a pointer value OP0, return a simplified version of an
5703 indirection through OP0, or NULL_TREE if no simplification is
5704 possible. This may only be applied to a rhs of an expression.
5705 Note that the resulting type may be different from the type pointed
5706 to in the sense that it is still compatible from the langhooks
5710 gimple_fold_indirect_ref_rhs (tree t
)
5712 return gimple_fold_indirect_ref (t
);
5715 /* Subroutine of gimplify_modify_expr to do simplifications of
5716 MODIFY_EXPRs based on the code of the RHS. We loop for as long as
5717 something changes. */
5719 static enum gimplify_status
5720 gimplify_modify_expr_rhs (tree
*expr_p
, tree
*from_p
, tree
*to_p
,
5721 gimple_seq
*pre_p
, gimple_seq
*post_p
,
5724 enum gimplify_status ret
= GS_UNHANDLED
;
5730 switch (TREE_CODE (*from_p
))
5733 /* If we're assigning from a read-only variable initialized with
5734 a constructor and not volatile, do the direct assignment from
5735 the constructor, but only if the target is not volatile either
5736 since this latter assignment might end up being done on a per
5737 field basis. However, if the target is volatile and the type
5738 is aggregate and non-addressable, gimplify_init_constructor
5739 knows that it needs to ensure a single access to the target
5740 and it will return GS_OK only in this case. */
5741 if (TREE_READONLY (*from_p
)
5742 && DECL_INITIAL (*from_p
)
5743 && TREE_CODE (DECL_INITIAL (*from_p
)) == CONSTRUCTOR
5744 && !TREE_THIS_VOLATILE (*from_p
)
5745 && (!TREE_THIS_VOLATILE (*to_p
)
5746 || (AGGREGATE_TYPE_P (TREE_TYPE (*to_p
))
5747 && !TREE_ADDRESSABLE (TREE_TYPE (*to_p
)))))
5749 tree old_from
= *from_p
;
5750 enum gimplify_status subret
;
5752 /* Move the constructor into the RHS. */
5753 *from_p
= unshare_expr (DECL_INITIAL (*from_p
));
5755 /* Let's see if gimplify_init_constructor will need to put
5757 subret
= gimplify_init_constructor (expr_p
, NULL
, NULL
,
5759 if (subret
== GS_ERROR
)
5761 /* If so, revert the change. */
5772 if (!TREE_ADDRESSABLE (TREE_TYPE (*from_p
)))
5773 /* If we have code like
5777 where the type of "x" is a (possibly cv-qualified variant
5778 of "A"), treat the entire expression as identical to "x".
5779 This kind of code arises in C++ when an object is bound
5780 to a const reference, and if "x" is a TARGET_EXPR we want
5781 to take advantage of the optimization below. But not if
5782 the type is TREE_ADDRESSABLE; then C++17 says that the
5783 TARGET_EXPR needs to be a temporary. */
5785 = gimple_fold_indirect_ref_rhs (TREE_OPERAND (*from_p
, 0)))
5787 bool volatile_p
= TREE_THIS_VOLATILE (*from_p
);
5788 if (TREE_THIS_VOLATILE (t
) != volatile_p
)
5791 t
= build_simple_mem_ref_loc (EXPR_LOCATION (*from_p
),
5792 build_fold_addr_expr (t
));
5793 if (REFERENCE_CLASS_P (t
))
5794 TREE_THIS_VOLATILE (t
) = volatile_p
;
5804 /* If we are initializing something from a TARGET_EXPR, strip the
5805 TARGET_EXPR and initialize it directly, if possible. This can't
5806 be done if the initializer is void, since that implies that the
5807 temporary is set in some non-trivial way.
5809 ??? What about code that pulls out the temp and uses it
5810 elsewhere? I think that such code never uses the TARGET_EXPR as
5811 an initializer. If I'm wrong, we'll die because the temp won't
5812 have any RTL. In that case, I guess we'll need to replace
5813 references somehow. */
5814 tree init
= TARGET_EXPR_INITIAL (*from_p
);
5817 && (TREE_CODE (*expr_p
) != MODIFY_EXPR
5818 || !TARGET_EXPR_NO_ELIDE (*from_p
))
5819 && !VOID_TYPE_P (TREE_TYPE (init
)))
5829 /* Remove any COMPOUND_EXPR in the RHS so the following cases will be
5831 gimplify_compound_expr (from_p
, pre_p
, true);
5837 /* If we already made some changes, let the front end have a
5838 crack at this before we break it down. */
5839 if (ret
!= GS_UNHANDLED
)
5842 /* If we're initializing from a CONSTRUCTOR, break this into
5843 individual MODIFY_EXPRs. */
5844 ret
= gimplify_init_constructor (expr_p
, pre_p
, post_p
, want_value
,
5849 /* If we're assigning to a non-register type, push the assignment
5850 down into the branches. This is mandatory for ADDRESSABLE types,
5851 since we cannot generate temporaries for such, but it saves a
5852 copy in other cases as well. */
5853 if (!is_gimple_reg_type (TREE_TYPE (*from_p
)))
5855 /* This code should mirror the code in gimplify_cond_expr. */
5856 enum tree_code code
= TREE_CODE (*expr_p
);
5857 tree cond
= *from_p
;
5858 tree result
= *to_p
;
5860 ret
= gimplify_expr (&result
, pre_p
, post_p
,
5861 is_gimple_lvalue
, fb_lvalue
);
5862 if (ret
!= GS_ERROR
)
5865 /* If we are going to write RESULT more than once, clear
5866 TREE_READONLY flag, otherwise we might incorrectly promote
5867 the variable to static const and initialize it at compile
5868 time in one of the branches. */
5870 && TREE_TYPE (TREE_OPERAND (cond
, 1)) != void_type_node
5871 && TREE_TYPE (TREE_OPERAND (cond
, 2)) != void_type_node
)
5872 TREE_READONLY (result
) = 0;
5873 if (TREE_TYPE (TREE_OPERAND (cond
, 1)) != void_type_node
)
5874 TREE_OPERAND (cond
, 1)
5875 = build2 (code
, void_type_node
, result
,
5876 TREE_OPERAND (cond
, 1));
5877 if (TREE_TYPE (TREE_OPERAND (cond
, 2)) != void_type_node
)
5878 TREE_OPERAND (cond
, 2)
5879 = build2 (code
, void_type_node
, unshare_expr (result
),
5880 TREE_OPERAND (cond
, 2));
5882 TREE_TYPE (cond
) = void_type_node
;
5883 recalculate_side_effects (cond
);
5887 gimplify_and_add (cond
, pre_p
);
5888 *expr_p
= unshare_expr (result
);
5897 /* For calls that return in memory, give *to_p as the CALL_EXPR's
5898 return slot so that we don't generate a temporary. */
5899 if (!CALL_EXPR_RETURN_SLOT_OPT (*from_p
)
5900 && aggregate_value_p (*from_p
, *from_p
))
5904 if (!(rhs_predicate_for (*to_p
))(*from_p
))
5905 /* If we need a temporary, *to_p isn't accurate. */
5907 /* It's OK to use the return slot directly unless it's an NRV. */
5908 else if (TREE_CODE (*to_p
) == RESULT_DECL
5909 && DECL_NAME (*to_p
) == NULL_TREE
5910 && needs_to_live_in_memory (*to_p
))
5912 else if (is_gimple_reg_type (TREE_TYPE (*to_p
))
5913 || (DECL_P (*to_p
) && DECL_REGISTER (*to_p
)))
5914 /* Don't force regs into memory. */
5916 else if (TREE_CODE (*expr_p
) == INIT_EXPR
)
5917 /* It's OK to use the target directly if it's being
5920 else if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p
)))
5922 /* Always use the target and thus RSO for variable-sized types.
5923 GIMPLE cannot deal with a variable-sized assignment
5924 embedded in a call statement. */
5926 else if (TREE_CODE (*to_p
) != SSA_NAME
5927 && (!is_gimple_variable (*to_p
)
5928 || needs_to_live_in_memory (*to_p
)))
5929 /* Don't use the original target if it's already addressable;
5930 if its address escapes, and the called function uses the
5931 NRV optimization, a conforming program could see *to_p
5932 change before the called function returns; see c++/19317.
5933 When optimizing, the return_slot pass marks more functions
5934 as safe after we have escape info. */
5941 CALL_EXPR_RETURN_SLOT_OPT (*from_p
) = 1;
5942 mark_addressable (*to_p
);
5947 case WITH_SIZE_EXPR
:
5948 /* Likewise for calls that return an aggregate of non-constant size,
5949 since we would not be able to generate a temporary at all. */
5950 if (TREE_CODE (TREE_OPERAND (*from_p
, 0)) == CALL_EXPR
)
5952 *from_p
= TREE_OPERAND (*from_p
, 0);
5953 /* We don't change ret in this case because the
5954 WITH_SIZE_EXPR might have been added in
5955 gimplify_modify_expr, so returning GS_OK would lead to an
5961 /* If we're initializing from a container, push the initialization
5963 case CLEANUP_POINT_EXPR
:
5965 case STATEMENT_LIST
:
5967 tree wrap
= *from_p
;
5970 ret
= gimplify_expr (to_p
, pre_p
, post_p
, is_gimple_min_lval
,
5972 if (ret
!= GS_ERROR
)
5975 t
= voidify_wrapper_expr (wrap
, *expr_p
);
5976 gcc_assert (t
== *expr_p
);
5980 gimplify_and_add (wrap
, pre_p
);
5981 *expr_p
= unshare_expr (*to_p
);
5989 /* Pull out compound literal expressions from a NOP_EXPR.
5990 Those are created in the C FE to drop qualifiers during
5991 lvalue conversion. */
5992 if ((TREE_CODE (TREE_OPERAND (*from_p
, 0)) == COMPOUND_LITERAL_EXPR
)
5993 && tree_ssa_useless_type_conversion (*from_p
))
5995 *from_p
= TREE_OPERAND (*from_p
, 0);
6001 case COMPOUND_LITERAL_EXPR
:
6003 tree complit
= TREE_OPERAND (*expr_p
, 1);
6004 tree decl_s
= COMPOUND_LITERAL_EXPR_DECL_EXPR (complit
);
6005 tree decl
= DECL_EXPR_DECL (decl_s
);
6006 tree init
= DECL_INITIAL (decl
);
6008 /* struct T x = (struct T) { 0, 1, 2 } can be optimized
6009 into struct T x = { 0, 1, 2 } if the address of the
6010 compound literal has never been taken. */
6011 if (!TREE_ADDRESSABLE (complit
)
6012 && !TREE_ADDRESSABLE (decl
)
6015 *expr_p
= copy_node (*expr_p
);
6016 TREE_OPERAND (*expr_p
, 1) = init
;
6031 /* Return true if T looks like a valid GIMPLE statement. */
6034 is_gimple_stmt (tree t
)
6036 const enum tree_code code
= TREE_CODE (t
);
6041 /* The only valid NOP_EXPR is the empty statement. */
6042 return IS_EMPTY_STMT (t
);
6046 /* These are only valid if they're void. */
6047 return TREE_TYPE (t
) == NULL
|| VOID_TYPE_P (TREE_TYPE (t
));
6053 case CASE_LABEL_EXPR
:
6054 case TRY_CATCH_EXPR
:
6055 case TRY_FINALLY_EXPR
:
6056 case EH_FILTER_EXPR
:
6059 case STATEMENT_LIST
:
6064 case OACC_HOST_DATA
:
6067 case OACC_ENTER_DATA
:
6068 case OACC_EXIT_DATA
:
6073 case OMP_DISTRIBUTE
:
6080 case OMP_STRUCTURED_BLOCK
:
6089 case OMP_TARGET_DATA
:
6090 case OMP_TARGET_UPDATE
:
6091 case OMP_TARGET_ENTER_DATA
:
6092 case OMP_TARGET_EXIT_DATA
:
6095 /* These are always void. */
6101 /* These are valid regardless of their type. */
6110 /* Promote partial stores to COMPLEX variables to total stores. *EXPR_P is
6111 a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a gimple register.
6113 IMPORTANT NOTE: This promotion is performed by introducing a load of the
6114 other, unmodified part of the complex object just before the total store.
6115 As a consequence, if the object is still uninitialized, an undefined value
6116 will be loaded into a register, which may result in a spurious exception
6117 if the register is floating-point and the value happens to be a signaling
6118 NaN for example. Then the fully-fledged complex operations lowering pass
6119 followed by a DCE pass are necessary in order to fix things up. */
6121 static enum gimplify_status
6122 gimplify_modify_expr_complex_part (tree
*expr_p
, gimple_seq
*pre_p
,
6125 enum tree_code code
, ocode
;
6126 tree lhs
, rhs
, new_rhs
, other
, realpart
, imagpart
;
6128 lhs
= TREE_OPERAND (*expr_p
, 0);
6129 rhs
= TREE_OPERAND (*expr_p
, 1);
6130 code
= TREE_CODE (lhs
);
6131 lhs
= TREE_OPERAND (lhs
, 0);
6133 ocode
= code
== REALPART_EXPR
? IMAGPART_EXPR
: REALPART_EXPR
;
6134 other
= build1 (ocode
, TREE_TYPE (rhs
), lhs
);
6135 suppress_warning (other
);
6136 other
= get_formal_tmp_var (other
, pre_p
);
6138 realpart
= code
== REALPART_EXPR
? rhs
: other
;
6139 imagpart
= code
== REALPART_EXPR
? other
: rhs
;
6141 if (TREE_CONSTANT (realpart
) && TREE_CONSTANT (imagpart
))
6142 new_rhs
= build_complex (TREE_TYPE (lhs
), realpart
, imagpart
);
6144 new_rhs
= build2 (COMPLEX_EXPR
, TREE_TYPE (lhs
), realpart
, imagpart
);
6146 gimplify_seq_add_stmt (pre_p
, gimple_build_assign (lhs
, new_rhs
));
6147 *expr_p
= (want_value
) ? rhs
: NULL_TREE
;
6152 /* Gimplify the MODIFY_EXPR node pointed to by EXPR_P.
6158 PRE_P points to the list where side effects that must happen before
6159 *EXPR_P should be stored.
6161 POST_P points to the list where side effects that must happen after
6162 *EXPR_P should be stored.
6164 WANT_VALUE is nonzero iff we want to use the value of this expression
6165 in another expression. */
6167 static enum gimplify_status
6168 gimplify_modify_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
6171 tree
*from_p
= &TREE_OPERAND (*expr_p
, 1);
6172 tree
*to_p
= &TREE_OPERAND (*expr_p
, 0);
6173 enum gimplify_status ret
= GS_UNHANDLED
;
6175 location_t loc
= EXPR_LOCATION (*expr_p
);
6176 gimple_stmt_iterator gsi
;
6178 if (error_operand_p (*from_p
) || error_operand_p (*to_p
))
6181 gcc_assert (TREE_CODE (*expr_p
) == MODIFY_EXPR
6182 || TREE_CODE (*expr_p
) == INIT_EXPR
);
6184 /* Trying to simplify a clobber using normal logic doesn't work,
6185 so handle it here. */
6186 if (TREE_CLOBBER_P (*from_p
))
6188 ret
= gimplify_expr (to_p
, pre_p
, post_p
, is_gimple_lvalue
, fb_lvalue
);
6189 if (ret
== GS_ERROR
)
6191 gcc_assert (!want_value
);
6192 if (!VAR_P (*to_p
) && TREE_CODE (*to_p
) != MEM_REF
)
6194 tree addr
= get_initialized_tmp_var (build_fold_addr_expr (*to_p
),
6196 *to_p
= build_simple_mem_ref_loc (EXPR_LOCATION (*to_p
), addr
);
6198 gimplify_seq_add_stmt (pre_p
, gimple_build_assign (*to_p
, *from_p
));
6203 /* Convert initialization from an empty variable-size CONSTRUCTOR to
6205 if (TREE_TYPE (*from_p
) != error_mark_node
6206 && TYPE_SIZE_UNIT (TREE_TYPE (*from_p
))
6207 && !poly_int_tree_p (TYPE_SIZE_UNIT (TREE_TYPE (*from_p
)))
6208 && TREE_CODE (*from_p
) == CONSTRUCTOR
6209 && CONSTRUCTOR_NELTS (*from_p
) == 0)
6211 maybe_with_size_expr (from_p
);
6212 gcc_assert (TREE_CODE (*from_p
) == WITH_SIZE_EXPR
);
6213 return gimplify_modify_expr_to_memset (expr_p
,
6214 TREE_OPERAND (*from_p
, 1),
6218 /* Insert pointer conversions required by the middle-end that are not
6219 required by the frontend. This fixes middle-end type checking for
6220 for example gcc.dg/redecl-6.c. */
6221 if (POINTER_TYPE_P (TREE_TYPE (*to_p
)))
6223 STRIP_USELESS_TYPE_CONVERSION (*from_p
);
6224 if (!useless_type_conversion_p (TREE_TYPE (*to_p
), TREE_TYPE (*from_p
)))
6225 *from_p
= fold_convert_loc (loc
, TREE_TYPE (*to_p
), *from_p
);
6228 /* See if any simplifications can be done based on what the RHS is. */
6229 ret
= gimplify_modify_expr_rhs (expr_p
, from_p
, to_p
, pre_p
, post_p
,
6231 if (ret
!= GS_UNHANDLED
)
6234 /* For empty types only gimplify the left hand side and right hand
6235 side as statements and throw away the assignment. Do this after
6236 gimplify_modify_expr_rhs so we handle TARGET_EXPRs of addressable
6238 if (is_empty_type (TREE_TYPE (*from_p
))
6240 /* Don't do this for calls that return addressable types, expand_call
6241 relies on those having a lhs. */
6242 && !(TREE_ADDRESSABLE (TREE_TYPE (*from_p
))
6243 && TREE_CODE (*from_p
) == CALL_EXPR
))
6245 gimplify_stmt (from_p
, pre_p
);
6246 gimplify_stmt (to_p
, pre_p
);
6247 *expr_p
= NULL_TREE
;
6251 /* If the value being copied is of variable width, compute the length
6252 of the copy into a WITH_SIZE_EXPR. Note that we need to do this
6253 before gimplifying any of the operands so that we can resolve any
6254 PLACEHOLDER_EXPRs in the size. Also note that the RTL expander uses
6255 the size of the expression to be copied, not of the destination, so
6256 that is what we must do here. */
6257 maybe_with_size_expr (from_p
);
6259 /* As a special case, we have to temporarily allow for assignments
6260 with a CALL_EXPR on the RHS. Since in GIMPLE a function call is
6261 a toplevel statement, when gimplifying the GENERIC expression
6262 MODIFY_EXPR <a, CALL_EXPR <foo>>, we cannot create the tuple
6263 GIMPLE_ASSIGN <a, GIMPLE_CALL <foo>>.
6265 Instead, we need to create the tuple GIMPLE_CALL <a, foo>. To
6266 prevent gimplify_expr from trying to create a new temporary for
6267 foo's LHS, we tell it that it should only gimplify until it
6268 reaches the CALL_EXPR. On return from gimplify_expr, the newly
6269 created GIMPLE_CALL <foo> will be the last statement in *PRE_P
6270 and all we need to do here is set 'a' to be its LHS. */
6272 /* Gimplify the RHS first for C++17 and bug 71104. */
6273 gimple_predicate initial_pred
= initial_rhs_predicate_for (*to_p
);
6274 ret
= gimplify_expr (from_p
, pre_p
, post_p
, initial_pred
, fb_rvalue
);
6275 if (ret
== GS_ERROR
)
6278 /* Then gimplify the LHS. */
6279 /* If we gimplified the RHS to a CALL_EXPR and that call may return
6280 twice we have to make sure to gimplify into non-SSA as otherwise
6281 the abnormal edge added later will make those defs not dominate
6283 ??? Technically this applies only to the registers used in the
6284 resulting non-register *TO_P. */
6285 bool saved_into_ssa
= gimplify_ctxp
->into_ssa
;
6287 && TREE_CODE (*from_p
) == CALL_EXPR
6288 && call_expr_flags (*from_p
) & ECF_RETURNS_TWICE
)
6289 gimplify_ctxp
->into_ssa
= false;
6290 ret
= gimplify_expr (to_p
, pre_p
, post_p
, is_gimple_lvalue
, fb_lvalue
);
6291 gimplify_ctxp
->into_ssa
= saved_into_ssa
;
6292 if (ret
== GS_ERROR
)
6295 /* Now that the LHS is gimplified, re-gimplify the RHS if our initial
6296 guess for the predicate was wrong. */
6297 gimple_predicate final_pred
= rhs_predicate_for (*to_p
);
6298 if (final_pred
!= initial_pred
)
6300 ret
= gimplify_expr (from_p
, pre_p
, post_p
, final_pred
, fb_rvalue
);
6301 if (ret
== GS_ERROR
)
6305 /* In case of va_arg internal fn wrappped in a WITH_SIZE_EXPR, add the type
6306 size as argument to the call. */
6307 if (TREE_CODE (*from_p
) == WITH_SIZE_EXPR
)
6309 tree call
= TREE_OPERAND (*from_p
, 0);
6310 tree vlasize
= TREE_OPERAND (*from_p
, 1);
6312 if (TREE_CODE (call
) == CALL_EXPR
6313 && CALL_EXPR_IFN (call
) == IFN_VA_ARG
)
6315 int nargs
= call_expr_nargs (call
);
6316 tree type
= TREE_TYPE (call
);
6317 tree ap
= CALL_EXPR_ARG (call
, 0);
6318 tree tag
= CALL_EXPR_ARG (call
, 1);
6319 tree aptag
= CALL_EXPR_ARG (call
, 2);
6320 tree newcall
= build_call_expr_internal_loc (EXPR_LOCATION (call
),
6324 TREE_OPERAND (*from_p
, 0) = newcall
;
6328 /* Now see if the above changed *from_p to something we handle specially. */
6329 ret
= gimplify_modify_expr_rhs (expr_p
, from_p
, to_p
, pre_p
, post_p
,
6331 if (ret
!= GS_UNHANDLED
)
6334 /* If we've got a variable sized assignment between two lvalues (i.e. does
6335 not involve a call), then we can make things a bit more straightforward
6336 by converting the assignment to memcpy or memset. */
6337 if (TREE_CODE (*from_p
) == WITH_SIZE_EXPR
)
6339 tree from
= TREE_OPERAND (*from_p
, 0);
6340 tree size
= TREE_OPERAND (*from_p
, 1);
6342 if (TREE_CODE (from
) == CONSTRUCTOR
)
6343 return gimplify_modify_expr_to_memset (expr_p
, size
, want_value
, pre_p
);
6345 if (is_gimple_addressable (from
))
6348 return gimplify_modify_expr_to_memcpy (expr_p
, size
, want_value
,
6353 /* Transform partial stores to non-addressable complex variables into
6354 total stores. This allows us to use real instead of virtual operands
6355 for these variables, which improves optimization. */
6356 if ((TREE_CODE (*to_p
) == REALPART_EXPR
6357 || TREE_CODE (*to_p
) == IMAGPART_EXPR
)
6358 && is_gimple_reg (TREE_OPERAND (*to_p
, 0)))
6359 return gimplify_modify_expr_complex_part (expr_p
, pre_p
, want_value
);
6361 /* Try to alleviate the effects of the gimplification creating artificial
6362 temporaries (see for example is_gimple_reg_rhs) on the debug info, but
6363 make sure not to create DECL_DEBUG_EXPR links across functions. */
6364 if (!gimplify_ctxp
->into_ssa
6366 && DECL_IGNORED_P (*from_p
)
6368 && !DECL_IGNORED_P (*to_p
)
6369 && decl_function_context (*to_p
) == current_function_decl
6370 && decl_function_context (*from_p
) == current_function_decl
)
6372 if (!DECL_NAME (*from_p
) && DECL_NAME (*to_p
))
6374 = create_tmp_var_name (IDENTIFIER_POINTER (DECL_NAME (*to_p
)));
6375 DECL_HAS_DEBUG_EXPR_P (*from_p
) = 1;
6376 SET_DECL_DEBUG_EXPR (*from_p
, *to_p
);
6379 if (want_value
&& TREE_THIS_VOLATILE (*to_p
))
6380 *from_p
= get_initialized_tmp_var (*from_p
, pre_p
, post_p
);
6382 if (TREE_CODE (*from_p
) == CALL_EXPR
)
6384 /* Since the RHS is a CALL_EXPR, we need to create a GIMPLE_CALL
6385 instead of a GIMPLE_ASSIGN. */
6387 if (CALL_EXPR_FN (*from_p
) == NULL_TREE
)
6389 /* Gimplify internal functions created in the FEs. */
6390 int nargs
= call_expr_nargs (*from_p
), i
;
6391 enum internal_fn ifn
= CALL_EXPR_IFN (*from_p
);
6392 auto_vec
<tree
> vargs (nargs
);
6394 for (i
= 0; i
< nargs
; i
++)
6396 gimplify_arg (&CALL_EXPR_ARG (*from_p
, i
), pre_p
,
6397 EXPR_LOCATION (*from_p
));
6398 vargs
.quick_push (CALL_EXPR_ARG (*from_p
, i
));
6400 call_stmt
= gimple_build_call_internal_vec (ifn
, vargs
);
6401 gimple_call_set_nothrow (call_stmt
, TREE_NOTHROW (*from_p
));
6402 gimple_set_location (call_stmt
, EXPR_LOCATION (*expr_p
));
6406 tree fnptrtype
= TREE_TYPE (CALL_EXPR_FN (*from_p
));
6407 CALL_EXPR_FN (*from_p
) = TREE_OPERAND (CALL_EXPR_FN (*from_p
), 0);
6408 STRIP_USELESS_TYPE_CONVERSION (CALL_EXPR_FN (*from_p
));
6409 tree fndecl
= get_callee_fndecl (*from_p
);
6411 && fndecl_built_in_p (fndecl
, BUILT_IN_EXPECT
)
6412 && call_expr_nargs (*from_p
) == 3)
6413 call_stmt
= gimple_build_call_internal (IFN_BUILTIN_EXPECT
, 3,
6414 CALL_EXPR_ARG (*from_p
, 0),
6415 CALL_EXPR_ARG (*from_p
, 1),
6416 CALL_EXPR_ARG (*from_p
, 2));
6419 call_stmt
= gimple_build_call_from_tree (*from_p
, fnptrtype
);
6422 notice_special_calls (call_stmt
);
6423 if (!gimple_call_noreturn_p (call_stmt
) || !should_remove_lhs_p (*to_p
))
6424 gimple_call_set_lhs (call_stmt
, *to_p
);
6425 else if (TREE_CODE (*to_p
) == SSA_NAME
)
6426 /* The above is somewhat premature, avoid ICEing later for a
6427 SSA name w/o a definition. We may have uses in the GIMPLE IL.
6428 ??? This doesn't make it a default-def. */
6429 SSA_NAME_DEF_STMT (*to_p
) = gimple_build_nop ();
6435 assign
= gimple_build_assign (*to_p
, *from_p
);
6436 gimple_set_location (assign
, EXPR_LOCATION (*expr_p
));
6437 if (COMPARISON_CLASS_P (*from_p
))
6438 copy_warning (assign
, *from_p
);
6441 if (gimplify_ctxp
->into_ssa
&& is_gimple_reg (*to_p
))
6443 /* We should have got an SSA name from the start. */
6444 gcc_assert (TREE_CODE (*to_p
) == SSA_NAME
6445 || ! gimple_in_ssa_p (cfun
));
6448 gimplify_seq_add_stmt (pre_p
, assign
);
6449 gsi
= gsi_last (*pre_p
);
6450 maybe_fold_stmt (&gsi
);
6454 *expr_p
= TREE_THIS_VOLATILE (*to_p
) ? *from_p
: unshare_expr (*to_p
);
6463 /* Gimplify a comparison between two variable-sized objects. Do this
6464 with a call to BUILT_IN_MEMCMP. */
6466 static enum gimplify_status
6467 gimplify_variable_sized_compare (tree
*expr_p
)
6469 location_t loc
= EXPR_LOCATION (*expr_p
);
6470 tree op0
= TREE_OPERAND (*expr_p
, 0);
6471 tree op1
= TREE_OPERAND (*expr_p
, 1);
6472 tree t
, arg
, dest
, src
, expr
;
6474 arg
= TYPE_SIZE_UNIT (TREE_TYPE (op0
));
6475 arg
= unshare_expr (arg
);
6476 arg
= SUBSTITUTE_PLACEHOLDER_IN_EXPR (arg
, op0
);
6477 src
= build_fold_addr_expr_loc (loc
, op1
);
6478 dest
= build_fold_addr_expr_loc (loc
, op0
);
6479 t
= builtin_decl_implicit (BUILT_IN_MEMCMP
);
6480 t
= build_call_expr_loc (loc
, t
, 3, dest
, src
, arg
);
6483 = build2 (TREE_CODE (*expr_p
), TREE_TYPE (*expr_p
), t
, integer_zero_node
);
6484 SET_EXPR_LOCATION (expr
, loc
);
6490 /* Gimplify a comparison between two aggregate objects of integral scalar
6491 mode as a comparison between the bitwise equivalent scalar values. */
6493 static enum gimplify_status
6494 gimplify_scalar_mode_aggregate_compare (tree
*expr_p
)
6496 location_t loc
= EXPR_LOCATION (*expr_p
);
6497 tree op0
= TREE_OPERAND (*expr_p
, 0);
6498 tree op1
= TREE_OPERAND (*expr_p
, 1);
6500 tree type
= TREE_TYPE (op0
);
6501 tree scalar_type
= lang_hooks
.types
.type_for_mode (TYPE_MODE (type
), 1);
6503 op0
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, scalar_type
, op0
);
6504 op1
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, scalar_type
, op1
);
6507 = fold_build2_loc (loc
, TREE_CODE (*expr_p
), TREE_TYPE (*expr_p
), op0
, op1
);
6512 /* Gimplify an expression sequence. This function gimplifies each
6513 expression and rewrites the original expression with the last
6514 expression of the sequence in GIMPLE form.
6516 PRE_P points to the list where the side effects for all the
6517 expressions in the sequence will be emitted.
6519 WANT_VALUE is true when the result of the last COMPOUND_EXPR is used. */
6521 static enum gimplify_status
6522 gimplify_compound_expr (tree
*expr_p
, gimple_seq
*pre_p
, bool want_value
)
6528 tree
*sub_p
= &TREE_OPERAND (t
, 0);
6530 if (TREE_CODE (*sub_p
) == COMPOUND_EXPR
)
6531 gimplify_compound_expr (sub_p
, pre_p
, false);
6533 gimplify_stmt (sub_p
, pre_p
);
6535 t
= TREE_OPERAND (t
, 1);
6537 while (TREE_CODE (t
) == COMPOUND_EXPR
);
6544 gimplify_stmt (expr_p
, pre_p
);
6549 /* Gimplify a SAVE_EXPR node. EXPR_P points to the expression to
6550 gimplify. After gimplification, EXPR_P will point to a new temporary
6551 that holds the original value of the SAVE_EXPR node.
6553 PRE_P points to the list where side effects that must happen before
6554 *EXPR_P should be stored. */
6556 static enum gimplify_status
6557 gimplify_save_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
)
6559 enum gimplify_status ret
= GS_ALL_DONE
;
6562 gcc_assert (TREE_CODE (*expr_p
) == SAVE_EXPR
);
6563 val
= TREE_OPERAND (*expr_p
, 0);
6565 if (val
&& TREE_TYPE (val
) == error_mark_node
)
6568 /* If the SAVE_EXPR has not been resolved, then evaluate it once. */
6569 if (!SAVE_EXPR_RESOLVED_P (*expr_p
))
6571 /* The operand may be a void-valued expression. It is
6572 being executed only for its side-effects. */
6573 if (TREE_TYPE (val
) == void_type_node
)
6575 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
6576 is_gimple_stmt
, fb_none
);
6580 /* The temporary may not be an SSA name as later abnormal and EH
6581 control flow may invalidate use/def domination. When in SSA
6582 form then assume there are no such issues and SAVE_EXPRs only
6583 appear via GENERIC foldings. */
6584 val
= get_initialized_tmp_var (val
, pre_p
, post_p
,
6585 gimple_in_ssa_p (cfun
));
6587 TREE_OPERAND (*expr_p
, 0) = val
;
6588 SAVE_EXPR_RESOLVED_P (*expr_p
) = 1;
6596 /* Rewrite the ADDR_EXPR node pointed to by EXPR_P
6603 PRE_P points to the list where side effects that must happen before
6604 *EXPR_P should be stored.
6606 POST_P points to the list where side effects that must happen after
6607 *EXPR_P should be stored. */
6609 static enum gimplify_status
6610 gimplify_addr_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
)
6612 tree expr
= *expr_p
;
6613 tree op0
= TREE_OPERAND (expr
, 0);
6614 enum gimplify_status ret
;
6615 location_t loc
= EXPR_LOCATION (*expr_p
);
6617 switch (TREE_CODE (op0
))
6621 /* Check if we are dealing with an expression of the form '&*ptr'.
6622 While the front end folds away '&*ptr' into 'ptr', these
6623 expressions may be generated internally by the compiler (e.g.,
6624 builtins like __builtin_va_end). */
6625 /* Caution: the silent array decomposition semantics we allow for
6626 ADDR_EXPR means we can't always discard the pair. */
6627 /* Gimplification of the ADDR_EXPR operand may drop
6628 cv-qualification conversions, so make sure we add them if
6631 tree op00
= TREE_OPERAND (op0
, 0);
6632 tree t_expr
= TREE_TYPE (expr
);
6633 tree t_op00
= TREE_TYPE (op00
);
6635 if (!useless_type_conversion_p (t_expr
, t_op00
))
6636 op00
= fold_convert_loc (loc
, TREE_TYPE (expr
), op00
);
6642 case VIEW_CONVERT_EXPR
:
6643 /* Take the address of our operand and then convert it to the type of
6646 ??? The interactions of VIEW_CONVERT_EXPR and aliasing is not at
6647 all clear. The impact of this transformation is even less clear. */
6649 /* If the operand is a useless conversion, look through it. Doing so
6650 guarantees that the ADDR_EXPR and its operand will remain of the
6652 if (tree_ssa_useless_type_conversion (TREE_OPERAND (op0
, 0)))
6653 op0
= TREE_OPERAND (op0
, 0);
6655 *expr_p
= fold_convert_loc (loc
, TREE_TYPE (expr
),
6656 build_fold_addr_expr_loc (loc
,
6657 TREE_OPERAND (op0
, 0)));
6662 if (integer_zerop (TREE_OPERAND (op0
, 1)))
6663 goto do_indirect_ref
;
6668 /* If we see a call to a declared builtin or see its address
6669 being taken (we can unify those cases here) then we can mark
6670 the builtin for implicit generation by GCC. */
6671 if (TREE_CODE (op0
) == FUNCTION_DECL
6672 && fndecl_built_in_p (op0
, BUILT_IN_NORMAL
)
6673 && builtin_decl_declared_p (DECL_FUNCTION_CODE (op0
)))
6674 set_builtin_decl_implicit_p (DECL_FUNCTION_CODE (op0
), true);
6676 /* We use fb_either here because the C frontend sometimes takes
6677 the address of a call that returns a struct; see
6678 gcc.dg/c99-array-lval-1.c. The gimplifier will correctly make
6679 the implied temporary explicit. */
6681 /* Make the operand addressable. */
6682 ret
= gimplify_expr (&TREE_OPERAND (expr
, 0), pre_p
, post_p
,
6683 is_gimple_addressable
, fb_either
);
6684 if (ret
== GS_ERROR
)
6687 /* Then mark it. Beware that it may not be possible to do so directly
6688 if a temporary has been created by the gimplification. */
6689 prepare_gimple_addressable (&TREE_OPERAND (expr
, 0), pre_p
);
6691 op0
= TREE_OPERAND (expr
, 0);
6693 /* For various reasons, the gimplification of the expression
6694 may have made a new INDIRECT_REF. */
6695 if (INDIRECT_REF_P (op0
)
6696 || (TREE_CODE (op0
) == MEM_REF
6697 && integer_zerop (TREE_OPERAND (op0
, 1))))
6698 goto do_indirect_ref
;
6700 mark_addressable (TREE_OPERAND (expr
, 0));
6702 /* The FEs may end up building ADDR_EXPRs early on a decl with
6703 an incomplete type. Re-build ADDR_EXPRs in canonical form
6705 if (!types_compatible_p (TREE_TYPE (op0
), TREE_TYPE (TREE_TYPE (expr
))))
6706 *expr_p
= build_fold_addr_expr (op0
);
6708 /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly. */
6709 recompute_tree_invariant_for_addr_expr (*expr_p
);
6711 /* If we re-built the ADDR_EXPR add a conversion to the original type
6713 if (!useless_type_conversion_p (TREE_TYPE (expr
), TREE_TYPE (*expr_p
)))
6714 *expr_p
= fold_convert (TREE_TYPE (expr
), *expr_p
);
6722 /* Gimplify the operands of an ASM_EXPR. Input operands should be a gimple
6723 value; output operands should be a gimple lvalue. */
6725 static enum gimplify_status
6726 gimplify_asm_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
)
6730 const char **oconstraints
;
6733 const char *constraint
;
6734 bool allows_mem
, allows_reg
, is_inout
;
6735 enum gimplify_status ret
, tret
;
6737 vec
<tree
, va_gc
> *inputs
;
6738 vec
<tree
, va_gc
> *outputs
;
6739 vec
<tree
, va_gc
> *clobbers
;
6740 vec
<tree
, va_gc
> *labels
;
6744 noutputs
= list_length (ASM_OUTPUTS (expr
));
6745 oconstraints
= (const char **) alloca ((noutputs
) * sizeof (const char *));
6753 link_next
= NULL_TREE
;
6754 for (i
= 0, link
= ASM_OUTPUTS (expr
); link
; ++i
, link
= link_next
)
6757 size_t constraint_len
;
6759 link_next
= TREE_CHAIN (link
);
6763 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link
)));
6764 constraint_len
= strlen (constraint
);
6765 if (constraint_len
== 0)
6768 ok
= parse_output_constraint (&constraint
, i
, 0, 0,
6769 &allows_mem
, &allows_reg
, &is_inout
);
6776 /* If we can't make copies, we can only accept memory.
6777 Similarly for VLAs. */
6778 tree outtype
= TREE_TYPE (TREE_VALUE (link
));
6779 if (outtype
!= error_mark_node
6780 && (TREE_ADDRESSABLE (outtype
)
6781 || !COMPLETE_TYPE_P (outtype
)
6782 || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (outtype
))))
6788 error ("impossible constraint in %<asm%>");
6789 error ("non-memory output %d must stay in memory", i
);
6794 if (!allows_reg
&& allows_mem
)
6795 mark_addressable (TREE_VALUE (link
));
6797 tree orig
= TREE_VALUE (link
);
6798 tret
= gimplify_expr (&TREE_VALUE (link
), pre_p
, post_p
,
6799 is_inout
? is_gimple_min_lval
: is_gimple_lvalue
,
6800 fb_lvalue
| fb_mayfail
);
6801 if (tret
== GS_ERROR
)
6803 if (orig
!= error_mark_node
)
6804 error ("invalid lvalue in %<asm%> output %d", i
);
6808 /* If the constraint does not allow memory make sure we gimplify
6809 it to a register if it is not already but its base is. This
6810 happens for complex and vector components. */
6813 tree op
= TREE_VALUE (link
);
6814 if (! is_gimple_val (op
)
6815 && is_gimple_reg_type (TREE_TYPE (op
))
6816 && is_gimple_reg (get_base_address (op
)))
6818 tree tem
= create_tmp_reg (TREE_TYPE (op
));
6822 ass
= build2 (MODIFY_EXPR
, TREE_TYPE (tem
),
6823 tem
, unshare_expr (op
));
6824 gimplify_and_add (ass
, pre_p
);
6826 ass
= build2 (MODIFY_EXPR
, TREE_TYPE (tem
), op
, tem
);
6827 gimplify_and_add (ass
, post_p
);
6829 TREE_VALUE (link
) = tem
;
6834 vec_safe_push (outputs
, link
);
6835 TREE_CHAIN (link
) = NULL_TREE
;
6839 /* An input/output operand. To give the optimizers more
6840 flexibility, split it into separate input and output
6843 /* Buffer big enough to format a 32-bit UINT_MAX into. */
6846 /* Turn the in/out constraint into an output constraint. */
6847 char *p
= xstrdup (constraint
);
6849 TREE_VALUE (TREE_PURPOSE (link
)) = build_string (constraint_len
, p
);
6851 /* And add a matching input constraint. */
6854 sprintf (buf
, "%u", i
);
6856 /* If there are multiple alternatives in the constraint,
6857 handle each of them individually. Those that allow register
6858 will be replaced with operand number, the others will stay
6860 if (strchr (p
, ',') != NULL
)
6862 size_t len
= 0, buflen
= strlen (buf
);
6863 char *beg
, *end
, *str
, *dst
;
6867 end
= strchr (beg
, ',');
6869 end
= strchr (beg
, '\0');
6870 if ((size_t) (end
- beg
) < buflen
)
6873 len
+= end
- beg
+ 1;
6880 str
= (char *) alloca (len
);
6881 for (beg
= p
+ 1, dst
= str
;;)
6884 bool mem_p
, reg_p
, inout_p
;
6886 end
= strchr (beg
, ',');
6891 parse_output_constraint (&tem
, i
, 0, 0,
6892 &mem_p
, ®_p
, &inout_p
);
6897 memcpy (dst
, buf
, buflen
);
6906 memcpy (dst
, beg
, len
);
6915 input
= build_string (dst
- str
, str
);
6918 input
= build_string (strlen (buf
), buf
);
6921 input
= build_string (constraint_len
- 1, constraint
+ 1);
6925 input
= build_tree_list (build_tree_list (NULL_TREE
, input
),
6926 unshare_expr (TREE_VALUE (link
)));
6927 ASM_INPUTS (expr
) = chainon (ASM_INPUTS (expr
), input
);
6931 link_next
= NULL_TREE
;
6932 for (link
= ASM_INPUTS (expr
); link
; ++i
, link
= link_next
)
6934 link_next
= TREE_CHAIN (link
);
6935 constraint
= TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link
)));
6936 parse_input_constraint (&constraint
, 0, 0, noutputs
, 0,
6937 oconstraints
, &allows_mem
, &allows_reg
);
6939 /* If we can't make copies, we can only accept memory. */
6940 tree intype
= TREE_TYPE (TREE_VALUE (link
));
6941 if (intype
!= error_mark_node
6942 && (TREE_ADDRESSABLE (intype
)
6943 || !COMPLETE_TYPE_P (intype
)
6944 || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (intype
))))
6950 error ("impossible constraint in %<asm%>");
6951 error ("non-memory input %d must stay in memory", i
);
6956 /* If the operand is a memory input, it should be an lvalue. */
6957 if (!allows_reg
&& allows_mem
)
6959 tree inputv
= TREE_VALUE (link
);
6960 STRIP_NOPS (inputv
);
6961 if (TREE_CODE (inputv
) == PREDECREMENT_EXPR
6962 || TREE_CODE (inputv
) == PREINCREMENT_EXPR
6963 || TREE_CODE (inputv
) == POSTDECREMENT_EXPR
6964 || TREE_CODE (inputv
) == POSTINCREMENT_EXPR
6965 || TREE_CODE (inputv
) == MODIFY_EXPR
)
6966 TREE_VALUE (link
) = error_mark_node
;
6967 tret
= gimplify_expr (&TREE_VALUE (link
), pre_p
, post_p
,
6968 is_gimple_lvalue
, fb_lvalue
| fb_mayfail
);
6969 if (tret
!= GS_ERROR
)
6971 /* Unlike output operands, memory inputs are not guaranteed
6972 to be lvalues by the FE, and while the expressions are
6973 marked addressable there, if it is e.g. a statement
6974 expression, temporaries in it might not end up being
6975 addressable. They might be already used in the IL and thus
6976 it is too late to make them addressable now though. */
6977 tree x
= TREE_VALUE (link
);
6978 while (handled_component_p (x
))
6979 x
= TREE_OPERAND (x
, 0);
6980 if (TREE_CODE (x
) == MEM_REF
6981 && TREE_CODE (TREE_OPERAND (x
, 0)) == ADDR_EXPR
)
6982 x
= TREE_OPERAND (TREE_OPERAND (x
, 0), 0);
6984 || TREE_CODE (x
) == PARM_DECL
6985 || TREE_CODE (x
) == RESULT_DECL
)
6986 && !TREE_ADDRESSABLE (x
)
6987 && is_gimple_reg (x
))
6989 warning_at (EXPR_LOC_OR_LOC (TREE_VALUE (link
),
6991 "memory input %d is not directly addressable",
6993 prepare_gimple_addressable (&TREE_VALUE (link
), pre_p
);
6996 mark_addressable (TREE_VALUE (link
));
6997 if (tret
== GS_ERROR
)
6999 if (inputv
!= error_mark_node
)
7000 error_at (EXPR_LOC_OR_LOC (TREE_VALUE (link
), input_location
),
7001 "memory input %d is not directly addressable", i
);
7007 tret
= gimplify_expr (&TREE_VALUE (link
), pre_p
, post_p
,
7008 is_gimple_asm_val
, fb_rvalue
);
7009 if (tret
== GS_ERROR
)
7013 TREE_CHAIN (link
) = NULL_TREE
;
7014 vec_safe_push (inputs
, link
);
7017 link_next
= NULL_TREE
;
7018 for (link
= ASM_CLOBBERS (expr
); link
; ++i
, link
= link_next
)
7020 link_next
= TREE_CHAIN (link
);
7021 TREE_CHAIN (link
) = NULL_TREE
;
7022 vec_safe_push (clobbers
, link
);
7025 link_next
= NULL_TREE
;
7026 for (link
= ASM_LABELS (expr
); link
; ++i
, link
= link_next
)
7028 link_next
= TREE_CHAIN (link
);
7029 TREE_CHAIN (link
) = NULL_TREE
;
7030 vec_safe_push (labels
, link
);
7033 /* Do not add ASMs with errors to the gimple IL stream. */
7034 if (ret
!= GS_ERROR
)
7036 stmt
= gimple_build_asm_vec (TREE_STRING_POINTER (ASM_STRING (expr
)),
7037 inputs
, outputs
, clobbers
, labels
);
7039 /* asm is volatile if it was marked by the user as volatile or
7040 there are no outputs or this is an asm goto. */
7041 gimple_asm_set_volatile (stmt
,
7042 ASM_VOLATILE_P (expr
)
7045 gimple_asm_set_input (stmt
, ASM_INPUT_P (expr
));
7046 gimple_asm_set_inline (stmt
, ASM_INLINE_P (expr
));
7048 gimplify_seq_add_stmt (pre_p
, stmt
);
7054 /* Gimplify a CLEANUP_POINT_EXPR. Currently this works by adding
7055 GIMPLE_WITH_CLEANUP_EXPRs to the prequeue as we encounter cleanups while
7056 gimplifying the body, and converting them to TRY_FINALLY_EXPRs when we
7057 return to this function.
7059 FIXME should we complexify the prequeue handling instead? Or use flags
7060 for all the cleanups and let the optimizer tighten them up? The current
7061 code seems pretty fragile; it will break on a cleanup within any
7062 non-conditional nesting. But any such nesting would be broken, anyway;
7063 we can't write a TRY_FINALLY_EXPR that starts inside a nesting construct
7064 and continues out of it. We can do that at the RTL level, though, so
7065 having an optimizer to tighten up try/finally regions would be a Good
7068 static enum gimplify_status
7069 gimplify_cleanup_point_expr (tree
*expr_p
, gimple_seq
*pre_p
)
7071 gimple_stmt_iterator iter
;
7072 gimple_seq body_sequence
= NULL
;
7074 tree temp
= voidify_wrapper_expr (*expr_p
, NULL
);
7076 /* We only care about the number of conditions between the innermost
7077 CLEANUP_POINT_EXPR and the cleanup. So save and reset the count and
7078 any cleanups collected outside the CLEANUP_POINT_EXPR. */
7079 int old_conds
= gimplify_ctxp
->conditions
;
7080 gimple_seq old_cleanups
= gimplify_ctxp
->conditional_cleanups
;
7081 bool old_in_cleanup_point_expr
= gimplify_ctxp
->in_cleanup_point_expr
;
7082 gimplify_ctxp
->conditions
= 0;
7083 gimplify_ctxp
->conditional_cleanups
= NULL
;
7084 gimplify_ctxp
->in_cleanup_point_expr
= true;
7086 gimplify_stmt (&TREE_OPERAND (*expr_p
, 0), &body_sequence
);
7088 gimplify_ctxp
->conditions
= old_conds
;
7089 gimplify_ctxp
->conditional_cleanups
= old_cleanups
;
7090 gimplify_ctxp
->in_cleanup_point_expr
= old_in_cleanup_point_expr
;
7092 for (iter
= gsi_start (body_sequence
); !gsi_end_p (iter
); )
7094 gimple
*wce
= gsi_stmt (iter
);
7096 if (gimple_code (wce
) == GIMPLE_WITH_CLEANUP_EXPR
)
7098 if (gsi_one_before_end_p (iter
))
7100 /* Note that gsi_insert_seq_before and gsi_remove do not
7101 scan operands, unlike some other sequence mutators. */
7102 if (!gimple_wce_cleanup_eh_only (wce
))
7103 gsi_insert_seq_before_without_update (&iter
,
7104 gimple_wce_cleanup (wce
),
7106 gsi_remove (&iter
, true);
7113 enum gimple_try_flags kind
;
7115 if (gimple_wce_cleanup_eh_only (wce
))
7116 kind
= GIMPLE_TRY_CATCH
;
7118 kind
= GIMPLE_TRY_FINALLY
;
7119 seq
= gsi_split_seq_after (iter
);
7121 gtry
= gimple_build_try (seq
, gimple_wce_cleanup (wce
), kind
);
7122 /* Do not use gsi_replace here, as it may scan operands.
7123 We want to do a simple structural modification only. */
7124 gsi_set_stmt (&iter
, gtry
);
7125 iter
= gsi_start (gtry
->eval
);
7132 gimplify_seq_add_seq (pre_p
, body_sequence
);
7145 /* Insert a cleanup marker for gimplify_cleanup_point_expr. CLEANUP
7146 is the cleanup action required. EH_ONLY is true if the cleanup should
7147 only be executed if an exception is thrown, not on normal exit.
7148 If FORCE_UNCOND is true perform the cleanup unconditionally; this is
7149 only valid for clobbers. */
7152 gimple_push_cleanup (tree var
, tree cleanup
, bool eh_only
, gimple_seq
*pre_p
,
7153 bool force_uncond
= false)
7156 gimple_seq cleanup_stmts
= NULL
;
7158 /* Errors can result in improperly nested cleanups. Which results in
7159 confusion when trying to resolve the GIMPLE_WITH_CLEANUP_EXPR. */
7163 if (gimple_conditional_context ())
7165 /* If we're in a conditional context, this is more complex. We only
7166 want to run the cleanup if we actually ran the initialization that
7167 necessitates it, but we want to run it after the end of the
7168 conditional context. So we wrap the try/finally around the
7169 condition and use a flag to determine whether or not to actually
7170 run the destructor. Thus
7174 becomes (approximately)
7178 if (test) { A::A(temp); flag = 1; val = f(temp); }
7181 if (flag) A::~A(temp);
7187 gimplify_stmt (&cleanup
, &cleanup_stmts
);
7188 wce
= gimple_build_wce (cleanup_stmts
);
7189 gimplify_seq_add_stmt (&gimplify_ctxp
->conditional_cleanups
, wce
);
7193 tree flag
= create_tmp_var (boolean_type_node
, "cleanup");
7194 gassign
*ffalse
= gimple_build_assign (flag
, boolean_false_node
);
7195 gassign
*ftrue
= gimple_build_assign (flag
, boolean_true_node
);
7197 cleanup
= build3 (COND_EXPR
, void_type_node
, flag
, cleanup
, NULL
);
7198 gimplify_stmt (&cleanup
, &cleanup_stmts
);
7199 wce
= gimple_build_wce (cleanup_stmts
);
7200 gimple_wce_set_cleanup_eh_only (wce
, eh_only
);
7202 gimplify_seq_add_stmt (&gimplify_ctxp
->conditional_cleanups
, ffalse
);
7203 gimplify_seq_add_stmt (&gimplify_ctxp
->conditional_cleanups
, wce
);
7204 gimplify_seq_add_stmt (pre_p
, ftrue
);
7206 /* Because of this manipulation, and the EH edges that jump
7207 threading cannot redirect, the temporary (VAR) will appear
7208 to be used uninitialized. Don't warn. */
7209 suppress_warning (var
, OPT_Wuninitialized
);
7214 gimplify_stmt (&cleanup
, &cleanup_stmts
);
7215 wce
= gimple_build_wce (cleanup_stmts
);
7216 gimple_wce_set_cleanup_eh_only (wce
, eh_only
);
7217 gimplify_seq_add_stmt (pre_p
, wce
);
7221 /* Gimplify a TARGET_EXPR which doesn't appear on the rhs of an INIT_EXPR. */
7223 static enum gimplify_status
7224 gimplify_target_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
)
7226 tree targ
= *expr_p
;
7227 tree temp
= TARGET_EXPR_SLOT (targ
);
7228 tree init
= TARGET_EXPR_INITIAL (targ
);
7229 enum gimplify_status ret
;
7231 bool unpoison_empty_seq
= false;
7232 gimple_stmt_iterator unpoison_it
;
7236 gimple_seq init_pre_p
= NULL
;
7238 /* TARGET_EXPR temps aren't part of the enclosing block, so add it
7239 to the temps list. Handle also variable length TARGET_EXPRs. */
7240 if (!poly_int_tree_p (DECL_SIZE (temp
)))
7242 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (temp
)))
7243 gimplify_type_sizes (TREE_TYPE (temp
), &init_pre_p
);
7244 /* FIXME: this is correct only when the size of the type does
7245 not depend on expressions evaluated in init. */
7246 gimplify_vla_decl (temp
, &init_pre_p
);
7250 /* Save location where we need to place unpoisoning. It's possible
7251 that a variable will be converted to needs_to_live_in_memory. */
7252 unpoison_it
= gsi_last (*pre_p
);
7253 unpoison_empty_seq
= gsi_end_p (unpoison_it
);
7255 gimple_add_tmp_var (temp
);
7258 /* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the
7259 expression is supposed to initialize the slot. */
7260 if (VOID_TYPE_P (TREE_TYPE (init
)))
7261 ret
= gimplify_expr (&init
, &init_pre_p
, post_p
, is_gimple_stmt
,
7265 tree init_expr
= build2 (INIT_EXPR
, void_type_node
, temp
, init
);
7267 ret
= gimplify_expr (&init
, &init_pre_p
, post_p
, is_gimple_stmt
,
7270 ggc_free (init_expr
);
7272 if (ret
== GS_ERROR
)
7274 /* PR c++/28266 Make sure this is expanded only once. */
7275 TARGET_EXPR_INITIAL (targ
) = NULL_TREE
;
7280 gimplify_and_add (init
, &init_pre_p
);
7282 /* Add a clobber for the temporary going out of scope, like
7283 gimplify_bind_expr. But only if we did not promote the
7284 temporary to static storage. */
7285 if (gimplify_ctxp
->in_cleanup_point_expr
7286 && !TREE_STATIC (temp
)
7287 && needs_to_live_in_memory (temp
))
7289 if (flag_stack_reuse
== SR_ALL
)
7291 tree clobber
= build_clobber (TREE_TYPE (temp
), CLOBBER_EOL
);
7292 clobber
= build2 (MODIFY_EXPR
, TREE_TYPE (temp
), temp
, clobber
);
7293 gimple_push_cleanup (temp
, clobber
, false, pre_p
, true);
7295 if (asan_poisoned_variables
7296 && DECL_ALIGN (temp
) <= MAX_SUPPORTED_STACK_ALIGNMENT
7297 && !TREE_STATIC (temp
)
7298 && dbg_cnt (asan_use_after_scope
)
7299 && !gimplify_omp_ctxp
)
7301 tree asan_cleanup
= build_asan_poison_call_expr (temp
);
7304 if (unpoison_empty_seq
)
7305 unpoison_it
= gsi_start (*pre_p
);
7307 asan_poison_variable (temp
, false, &unpoison_it
,
7308 unpoison_empty_seq
);
7309 gimple_push_cleanup (temp
, asan_cleanup
, false, pre_p
);
7314 gimple_seq_add_seq (pre_p
, init_pre_p
);
7316 /* If needed, push the cleanup for the temp. */
7317 if (TARGET_EXPR_CLEANUP (targ
))
7318 gimple_push_cleanup (temp
, TARGET_EXPR_CLEANUP (targ
),
7319 CLEANUP_EH_ONLY (targ
), pre_p
);
7321 /* Only expand this once. */
7322 TREE_OPERAND (targ
, 3) = init
;
7323 TARGET_EXPR_INITIAL (targ
) = NULL_TREE
;
7326 /* We should have expanded this before. */
7327 gcc_assert (DECL_SEEN_IN_BIND_EXPR_P (temp
));
7333 /* Gimplification of expression trees. */
7335 /* Gimplify an expression which appears at statement context. The
7336 corresponding GIMPLE statements are added to *SEQ_P. If *SEQ_P is
7337 NULL, a new sequence is allocated.
7339 Return true if we actually added a statement to the queue. */
7342 gimplify_stmt (tree
*stmt_p
, gimple_seq
*seq_p
)
7344 gimple_seq_node last
;
7346 last
= gimple_seq_last (*seq_p
);
7347 gimplify_expr (stmt_p
, seq_p
, NULL
, is_gimple_stmt
, fb_none
);
7348 return last
!= gimple_seq_last (*seq_p
);
7351 /* Add FIRSTPRIVATE entries for DECL in the OpenMP the surrounding parallels
7352 to CTX. If entries already exist, force them to be some flavor of private.
7353 If there is no enclosing parallel, do nothing. */
7356 omp_firstprivatize_variable (struct gimplify_omp_ctx
*ctx
, tree decl
)
7360 if (decl
== NULL
|| !DECL_P (decl
) || ctx
->region_type
== ORT_NONE
)
7365 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
)decl
);
7368 if (n
->value
& GOVD_SHARED
)
7369 n
->value
= GOVD_FIRSTPRIVATE
| (n
->value
& GOVD_SEEN
);
7370 else if (n
->value
& GOVD_MAP
)
7371 n
->value
|= GOVD_MAP_TO_ONLY
;
7375 else if ((ctx
->region_type
& ORT_TARGET
) != 0)
7377 if (ctx
->defaultmap
[GDMK_SCALAR
] & GOVD_FIRSTPRIVATE
)
7378 omp_add_variable (ctx
, decl
, GOVD_FIRSTPRIVATE
);
7380 omp_add_variable (ctx
, decl
, GOVD_MAP
| GOVD_MAP_TO_ONLY
);
7382 else if (ctx
->region_type
!= ORT_WORKSHARE
7383 && ctx
->region_type
!= ORT_TASKGROUP
7384 && ctx
->region_type
!= ORT_SIMD
7385 && ctx
->region_type
!= ORT_ACC
7386 && !(ctx
->region_type
& ORT_TARGET_DATA
))
7387 omp_add_variable (ctx
, decl
, GOVD_FIRSTPRIVATE
);
7389 ctx
= ctx
->outer_context
;
7394 /* Similarly for each of the type sizes of TYPE. */
7397 omp_firstprivatize_type_sizes (struct gimplify_omp_ctx
*ctx
, tree type
)
7399 if (type
== NULL
|| type
== error_mark_node
)
7401 type
= TYPE_MAIN_VARIANT (type
);
7403 if (ctx
->privatized_types
->add (type
))
7406 switch (TREE_CODE (type
))
7412 case FIXED_POINT_TYPE
:
7413 omp_firstprivatize_variable (ctx
, TYPE_MIN_VALUE (type
));
7414 omp_firstprivatize_variable (ctx
, TYPE_MAX_VALUE (type
));
7418 omp_firstprivatize_type_sizes (ctx
, TREE_TYPE (type
));
7419 omp_firstprivatize_type_sizes (ctx
, TYPE_DOMAIN (type
));
7424 case QUAL_UNION_TYPE
:
7427 for (field
= TYPE_FIELDS (type
); field
; field
= DECL_CHAIN (field
))
7428 if (TREE_CODE (field
) == FIELD_DECL
)
7430 omp_firstprivatize_variable (ctx
, DECL_FIELD_OFFSET (field
));
7431 omp_firstprivatize_type_sizes (ctx
, TREE_TYPE (field
));
7437 case REFERENCE_TYPE
:
7438 omp_firstprivatize_type_sizes (ctx
, TREE_TYPE (type
));
7445 omp_firstprivatize_variable (ctx
, TYPE_SIZE (type
));
7446 omp_firstprivatize_variable (ctx
, TYPE_SIZE_UNIT (type
));
7447 lang_hooks
.types
.omp_firstprivatize_type_sizes (ctx
, type
);
7450 /* Add an entry for DECL in the OMP context CTX with FLAGS. */
7453 omp_add_variable (struct gimplify_omp_ctx
*ctx
, tree decl
, unsigned int flags
)
7456 unsigned int nflags
;
7459 if (error_operand_p (decl
) || ctx
->region_type
== ORT_NONE
)
7462 /* Never elide decls whose type has TREE_ADDRESSABLE set. This means
7463 there are constructors involved somewhere. Exception is a shared clause,
7464 there is nothing privatized in that case. */
7465 if ((flags
& GOVD_SHARED
) == 0
7466 && (TREE_ADDRESSABLE (TREE_TYPE (decl
))
7467 || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl
))))
7470 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
)decl
);
7471 if (n
!= NULL
&& (n
->value
& GOVD_DATA_SHARE_CLASS
) != 0)
7473 /* We shouldn't be re-adding the decl with the same data
7475 gcc_assert ((n
->value
& GOVD_DATA_SHARE_CLASS
& flags
) == 0);
7476 nflags
= n
->value
| flags
;
7477 /* The only combination of data sharing classes we should see is
7478 FIRSTPRIVATE and LASTPRIVATE. However, OpenACC permits
7479 reduction variables to be used in data sharing clauses. */
7480 gcc_assert ((ctx
->region_type
& ORT_ACC
) != 0
7481 || ((nflags
& GOVD_DATA_SHARE_CLASS
)
7482 == (GOVD_FIRSTPRIVATE
| GOVD_LASTPRIVATE
))
7483 || (flags
& GOVD_DATA_SHARE_CLASS
) == 0);
7488 /* When adding a variable-sized variable, we have to handle all sorts
7489 of additional bits of data: the pointer replacement variable, and
7490 the parameters of the type. */
7491 if (DECL_SIZE (decl
) && TREE_CODE (DECL_SIZE (decl
)) != INTEGER_CST
)
7493 /* Add the pointer replacement variable as PRIVATE if the variable
7494 replacement is private, else FIRSTPRIVATE since we'll need the
7495 address of the original variable either for SHARED, or for the
7496 copy into or out of the context. */
7497 if (!(flags
& GOVD_LOCAL
) && ctx
->region_type
!= ORT_TASKGROUP
)
7499 if (flags
& GOVD_MAP
)
7500 nflags
= GOVD_MAP
| GOVD_MAP_TO_ONLY
| GOVD_EXPLICIT
;
7501 else if (flags
& GOVD_PRIVATE
)
7502 nflags
= GOVD_PRIVATE
;
7503 else if (((ctx
->region_type
& (ORT_TARGET
| ORT_TARGET_DATA
)) != 0
7504 && (flags
& GOVD_FIRSTPRIVATE
))
7505 || (ctx
->region_type
== ORT_TARGET_DATA
7506 && (flags
& GOVD_DATA_SHARE_CLASS
) == 0))
7507 nflags
= GOVD_PRIVATE
| GOVD_EXPLICIT
;
7509 nflags
= GOVD_FIRSTPRIVATE
;
7510 nflags
|= flags
& GOVD_SEEN
;
7511 t
= DECL_VALUE_EXPR (decl
);
7512 gcc_assert (INDIRECT_REF_P (t
));
7513 t
= TREE_OPERAND (t
, 0);
7514 gcc_assert (DECL_P (t
));
7515 omp_add_variable (ctx
, t
, nflags
);
7518 /* Add all of the variable and type parameters (which should have
7519 been gimplified to a formal temporary) as FIRSTPRIVATE. */
7520 omp_firstprivatize_variable (ctx
, DECL_SIZE_UNIT (decl
));
7521 omp_firstprivatize_variable (ctx
, DECL_SIZE (decl
));
7522 omp_firstprivatize_type_sizes (ctx
, TREE_TYPE (decl
));
7524 /* The variable-sized variable itself is never SHARED, only some form
7525 of PRIVATE. The sharing would take place via the pointer variable
7526 which we remapped above. */
7527 if (flags
& GOVD_SHARED
)
7528 flags
= GOVD_SHARED
| GOVD_DEBUG_PRIVATE
7529 | (flags
& (GOVD_SEEN
| GOVD_EXPLICIT
));
7531 /* We're going to make use of the TYPE_SIZE_UNIT at least in the
7532 alloca statement we generate for the variable, so make sure it
7533 is available. This isn't automatically needed for the SHARED
7534 case, since we won't be allocating local storage then.
7535 For local variables TYPE_SIZE_UNIT might not be gimplified yet,
7536 in this case omp_notice_variable will be called later
7537 on when it is gimplified. */
7538 else if (! (flags
& (GOVD_LOCAL
| GOVD_MAP
))
7539 && DECL_P (TYPE_SIZE_UNIT (TREE_TYPE (decl
))))
7540 omp_notice_variable (ctx
, TYPE_SIZE_UNIT (TREE_TYPE (decl
)), true);
7542 else if ((flags
& (GOVD_MAP
| GOVD_LOCAL
)) == 0
7543 && omp_privatize_by_reference (decl
))
7545 omp_firstprivatize_type_sizes (ctx
, TREE_TYPE (decl
));
7547 /* Similar to the direct variable sized case above, we'll need the
7548 size of references being privatized. */
7549 if ((flags
& GOVD_SHARED
) == 0)
7551 t
= TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl
)));
7552 if (t
&& DECL_P (t
))
7553 omp_notice_variable (ctx
, t
, true);
7560 splay_tree_insert (ctx
->variables
, (splay_tree_key
)decl
, flags
);
7562 /* For reductions clauses in OpenACC loop directives, by default create a
7563 copy clause on the enclosing parallel construct for carrying back the
7565 if (ctx
->region_type
== ORT_ACC
&& (flags
& GOVD_REDUCTION
))
7567 struct gimplify_omp_ctx
*outer_ctx
= ctx
->outer_context
;
7570 n
= splay_tree_lookup (outer_ctx
->variables
, (splay_tree_key
)decl
);
7573 /* Ignore local variables and explicitly declared clauses. */
7574 if (n
->value
& (GOVD_LOCAL
| GOVD_EXPLICIT
))
7576 else if (outer_ctx
->region_type
== ORT_ACC_KERNELS
)
7578 /* According to the OpenACC spec, such a reduction variable
7579 should already have a copy map on a kernels construct,
7580 verify that here. */
7581 gcc_assert (!(n
->value
& GOVD_FIRSTPRIVATE
)
7582 && (n
->value
& GOVD_MAP
));
7584 else if (outer_ctx
->region_type
== ORT_ACC_PARALLEL
)
7586 /* Remove firstprivate and make it a copy map. */
7587 n
->value
&= ~GOVD_FIRSTPRIVATE
;
7588 n
->value
|= GOVD_MAP
;
7591 else if (outer_ctx
->region_type
== ORT_ACC_PARALLEL
)
7593 splay_tree_insert (outer_ctx
->variables
, (splay_tree_key
)decl
,
7594 GOVD_MAP
| GOVD_SEEN
);
7597 outer_ctx
= outer_ctx
->outer_context
;
7602 /* Notice a threadprivate variable DECL used in OMP context CTX.
7603 This just prints out diagnostics about threadprivate variable uses
7604 in untied tasks. If DECL2 is non-NULL, prevent this warning
7605 on that variable. */
7608 omp_notice_threadprivate_variable (struct gimplify_omp_ctx
*ctx
, tree decl
,
7612 struct gimplify_omp_ctx
*octx
;
7614 for (octx
= ctx
; octx
; octx
= octx
->outer_context
)
7615 if ((octx
->region_type
& ORT_TARGET
) != 0
7616 || octx
->order_concurrent
)
7618 n
= splay_tree_lookup (octx
->variables
, (splay_tree_key
)decl
);
7621 if (octx
->order_concurrent
)
7623 error ("threadprivate variable %qE used in a region with"
7624 " %<order(concurrent)%> clause", DECL_NAME (decl
));
7625 inform (octx
->location
, "enclosing region");
7629 error ("threadprivate variable %qE used in target region",
7631 inform (octx
->location
, "enclosing target region");
7633 splay_tree_insert (octx
->variables
, (splay_tree_key
)decl
, 0);
7636 splay_tree_insert (octx
->variables
, (splay_tree_key
)decl2
, 0);
7639 if (ctx
->region_type
!= ORT_UNTIED_TASK
)
7641 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
)decl
);
7644 error ("threadprivate variable %qE used in untied task",
7646 inform (ctx
->location
, "enclosing task");
7647 splay_tree_insert (ctx
->variables
, (splay_tree_key
)decl
, 0);
7650 splay_tree_insert (ctx
->variables
, (splay_tree_key
)decl2
, 0);
7654 /* Return true if global var DECL is device resident. */
7657 device_resident_p (tree decl
)
7659 tree attr
= lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (decl
));
7664 for (tree t
= TREE_VALUE (attr
); t
; t
= TREE_PURPOSE (t
))
7666 tree c
= TREE_VALUE (t
);
7667 if (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_DEVICE_RESIDENT
)
7674 /* Return true if DECL has an ACC DECLARE attribute. */
7677 is_oacc_declared (tree decl
)
7679 tree t
= TREE_CODE (decl
) == MEM_REF
? TREE_OPERAND (decl
, 0) : decl
;
7680 tree declared
= lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (t
));
7681 return declared
!= NULL_TREE
;
7684 /* Determine outer default flags for DECL mentioned in an OMP region
7685 but not declared in an enclosing clause.
7687 ??? Some compiler-generated variables (like SAVE_EXPRs) could be
7688 remapped firstprivate instead of shared. To some extent this is
7689 addressed in omp_firstprivatize_type_sizes, but not
7693 omp_default_clause (struct gimplify_omp_ctx
*ctx
, tree decl
,
7694 bool in_code
, unsigned flags
)
7696 enum omp_clause_default_kind default_kind
= ctx
->default_kind
;
7697 enum omp_clause_default_kind kind
;
7699 kind
= lang_hooks
.decls
.omp_predetermined_sharing (decl
);
7700 if (ctx
->region_type
& ORT_TASK
)
7702 tree detach_clause
= omp_find_clause (ctx
->clauses
, OMP_CLAUSE_DETACH
);
7704 /* The event-handle specified by a detach clause should always be firstprivate,
7705 regardless of the current default. */
7706 if (detach_clause
&& OMP_CLAUSE_DECL (detach_clause
) == decl
)
7707 kind
= OMP_CLAUSE_DEFAULT_FIRSTPRIVATE
;
7709 if (kind
!= OMP_CLAUSE_DEFAULT_UNSPECIFIED
)
7710 default_kind
= kind
;
7711 else if (VAR_P (decl
) && TREE_STATIC (decl
) && DECL_IN_CONSTANT_POOL (decl
))
7712 default_kind
= OMP_CLAUSE_DEFAULT_SHARED
;
7713 /* For C/C++ default({,first}private), variables with static storage duration
7714 declared in a namespace or global scope and referenced in construct
7715 must be explicitly specified, i.e. acts as default(none). */
7716 else if ((default_kind
== OMP_CLAUSE_DEFAULT_PRIVATE
7717 || default_kind
== OMP_CLAUSE_DEFAULT_FIRSTPRIVATE
)
7719 && is_global_var (decl
)
7720 && (DECL_FILE_SCOPE_P (decl
)
7721 || (DECL_CONTEXT (decl
)
7722 && TREE_CODE (DECL_CONTEXT (decl
)) == NAMESPACE_DECL
))
7723 && !lang_GNU_Fortran ())
7724 default_kind
= OMP_CLAUSE_DEFAULT_NONE
;
7726 switch (default_kind
)
7728 case OMP_CLAUSE_DEFAULT_NONE
:
7732 if (ctx
->region_type
& ORT_PARALLEL
)
7734 else if ((ctx
->region_type
& ORT_TASKLOOP
) == ORT_TASKLOOP
)
7736 else if (ctx
->region_type
& ORT_TASK
)
7738 else if (ctx
->region_type
& ORT_TEAMS
)
7743 error ("%qE not specified in enclosing %qs",
7744 DECL_NAME (lang_hooks
.decls
.omp_report_decl (decl
)), rtype
);
7745 inform (ctx
->location
, "enclosing %qs", rtype
);
7748 case OMP_CLAUSE_DEFAULT_SHARED
:
7749 flags
|= GOVD_SHARED
;
7751 case OMP_CLAUSE_DEFAULT_PRIVATE
:
7752 flags
|= GOVD_PRIVATE
;
7754 case OMP_CLAUSE_DEFAULT_FIRSTPRIVATE
:
7755 flags
|= GOVD_FIRSTPRIVATE
;
7757 case OMP_CLAUSE_DEFAULT_UNSPECIFIED
:
7758 /* decl will be either GOVD_FIRSTPRIVATE or GOVD_SHARED. */
7759 gcc_assert ((ctx
->region_type
& ORT_TASK
) != 0);
7760 if (struct gimplify_omp_ctx
*octx
= ctx
->outer_context
)
7762 omp_notice_variable (octx
, decl
, in_code
);
7763 for (; octx
; octx
= octx
->outer_context
)
7767 n2
= splay_tree_lookup (octx
->variables
, (splay_tree_key
) decl
);
7768 if ((octx
->region_type
& (ORT_TARGET_DATA
| ORT_TARGET
)) != 0
7769 && (n2
== NULL
|| (n2
->value
& GOVD_DATA_SHARE_CLASS
) == 0))
7771 if (n2
&& (n2
->value
& GOVD_DATA_SHARE_CLASS
) != GOVD_SHARED
)
7773 flags
|= GOVD_FIRSTPRIVATE
;
7776 if ((octx
->region_type
& (ORT_PARALLEL
| ORT_TEAMS
)) != 0)
7778 flags
|= GOVD_SHARED
;
7784 if (TREE_CODE (decl
) == PARM_DECL
7785 || (!is_global_var (decl
)
7786 && DECL_CONTEXT (decl
) == current_function_decl
))
7787 flags
|= GOVD_FIRSTPRIVATE
;
7789 flags
|= GOVD_SHARED
;
7800 /* Return string name for types of OpenACC constructs from ORT_* values. */
7803 oacc_region_type_name (enum omp_region_type region_type
)
7805 switch (region_type
)
7809 case ORT_ACC_PARALLEL
:
7811 case ORT_ACC_KERNELS
:
7813 case ORT_ACC_SERIAL
:
7820 /* Determine outer default flags for DECL mentioned in an OACC region
7821 but not declared in an enclosing clause. */
7824 oacc_default_clause (struct gimplify_omp_ctx
*ctx
, tree decl
, unsigned flags
)
7826 struct gimplify_omp_ctx
*ctx_default
= ctx
;
7827 /* If no 'default' clause appears on this compute construct... */
7828 if (ctx_default
->default_kind
== OMP_CLAUSE_DEFAULT_SHARED
)
7830 /* ..., see if one appears on a lexically containing 'data'
7832 while ((ctx_default
= ctx_default
->outer_context
))
7834 if (ctx_default
->region_type
== ORT_ACC_DATA
7835 && ctx_default
->default_kind
!= OMP_CLAUSE_DEFAULT_SHARED
)
7838 /* If not, reset. */
7843 bool on_device
= false;
7844 bool is_private
= false;
7845 bool declared
= is_oacc_declared (decl
);
7846 tree type
= TREE_TYPE (decl
);
7848 if (omp_privatize_by_reference (decl
))
7849 type
= TREE_TYPE (type
);
7851 /* For Fortran COMMON blocks, only used variables in those blocks are
7852 transfered and remapped. The block itself will have a private clause to
7853 avoid transfering the data twice.
7854 The hook evaluates to false by default. For a variable in Fortran's COMMON
7855 or EQUIVALENCE block, returns 'true' (as we have shared=false) - as only
7856 the variables in such a COMMON/EQUIVALENCE block shall be privatized not
7857 the whole block. For C++ and Fortran, it can also be true under certain
7858 other conditions, if DECL_HAS_VALUE_EXPR. */
7859 if (RECORD_OR_UNION_TYPE_P (type
))
7860 is_private
= lang_hooks
.decls
.omp_disregard_value_expr (decl
, false);
7862 if ((ctx
->region_type
& (ORT_ACC_PARALLEL
| ORT_ACC_KERNELS
)) != 0
7863 && is_global_var (decl
)
7864 && device_resident_p (decl
)
7868 flags
|= GOVD_MAP_TO_ONLY
;
7871 switch (ctx
->region_type
)
7873 case ORT_ACC_KERNELS
:
7875 flags
|= GOVD_FIRSTPRIVATE
;
7876 else if (AGGREGATE_TYPE_P (type
))
7878 /* Aggregates default to 'present_or_copy', or 'present'. */
7879 if (ctx_default
->default_kind
!= OMP_CLAUSE_DEFAULT_PRESENT
)
7882 flags
|= GOVD_MAP
| GOVD_MAP_FORCE_PRESENT
;
7885 /* Scalars default to 'copy'. */
7886 flags
|= GOVD_MAP
| GOVD_MAP_FORCE
;
7890 case ORT_ACC_PARALLEL
:
7891 case ORT_ACC_SERIAL
:
7893 flags
|= GOVD_FIRSTPRIVATE
;
7894 else if (on_device
|| declared
)
7896 else if (AGGREGATE_TYPE_P (type
))
7898 /* Aggregates default to 'present_or_copy', or 'present'. */
7899 if (ctx_default
->default_kind
!= OMP_CLAUSE_DEFAULT_PRESENT
)
7902 flags
|= GOVD_MAP
| GOVD_MAP_FORCE_PRESENT
;
7905 /* Scalars default to 'firstprivate'. */
7906 flags
|= GOVD_FIRSTPRIVATE
;
7914 if (DECL_ARTIFICIAL (decl
))
7915 ; /* We can get compiler-generated decls, and should not complain
7917 else if (ctx_default
->default_kind
== OMP_CLAUSE_DEFAULT_NONE
)
7919 error ("%qE not specified in enclosing OpenACC %qs construct",
7920 DECL_NAME (lang_hooks
.decls
.omp_report_decl (decl
)),
7921 oacc_region_type_name (ctx
->region_type
));
7922 if (ctx_default
!= ctx
)
7923 inform (ctx
->location
, "enclosing OpenACC %qs construct and",
7924 oacc_region_type_name (ctx
->region_type
));
7925 inform (ctx_default
->location
,
7926 "enclosing OpenACC %qs construct with %qs clause",
7927 oacc_region_type_name (ctx_default
->region_type
),
7930 else if (ctx_default
->default_kind
== OMP_CLAUSE_DEFAULT_PRESENT
)
7931 ; /* Handled above. */
7933 gcc_checking_assert (ctx_default
->default_kind
== OMP_CLAUSE_DEFAULT_SHARED
);
7938 /* Record the fact that DECL was used within the OMP context CTX.
7939 IN_CODE is true when real code uses DECL, and false when we should
7940 merely emit default(none) errors. Return true if DECL is going to
7941 be remapped and thus DECL shouldn't be gimplified into its
7942 DECL_VALUE_EXPR (if any). */
7945 omp_notice_variable (struct gimplify_omp_ctx
*ctx
, tree decl
, bool in_code
)
7948 unsigned flags
= in_code
? GOVD_SEEN
: 0;
7949 bool ret
= false, shared
;
7951 if (error_operand_p (decl
))
7954 if (DECL_ARTIFICIAL (decl
))
7956 tree attr
= lookup_attribute ("omp allocate var", DECL_ATTRIBUTES (decl
));
7958 decl
= TREE_VALUE (TREE_VALUE (attr
));
7961 if (ctx
->region_type
== ORT_NONE
)
7962 return lang_hooks
.decls
.omp_disregard_value_expr (decl
, false);
7964 if (is_global_var (decl
))
7966 /* Threadprivate variables are predetermined. */
7967 if (DECL_THREAD_LOCAL_P (decl
))
7968 return omp_notice_threadprivate_variable (ctx
, decl
, NULL_TREE
);
7970 if (DECL_HAS_VALUE_EXPR_P (decl
))
7972 if (ctx
->region_type
& ORT_ACC
)
7973 /* For OpenACC, defer expansion of value to avoid transfering
7974 privatized common block data instead of im-/explicitly transfered
7975 variables which are in common blocks. */
7979 tree value
= get_base_address (DECL_VALUE_EXPR (decl
));
7981 if (value
&& DECL_P (value
) && DECL_THREAD_LOCAL_P (value
))
7982 return omp_notice_threadprivate_variable (ctx
, decl
, value
);
7986 if (gimplify_omp_ctxp
->outer_context
== NULL
7988 && oacc_get_fn_attrib (current_function_decl
))
7990 location_t loc
= DECL_SOURCE_LOCATION (decl
);
7992 if (lookup_attribute ("omp declare target link",
7993 DECL_ATTRIBUTES (decl
)))
7996 "%qE with %<link%> clause used in %<routine%> function",
8000 else if (!lookup_attribute ("omp declare target",
8001 DECL_ATTRIBUTES (decl
)))
8004 "%qE requires a %<declare%> directive for use "
8005 "in a %<routine%> function", DECL_NAME (decl
));
8011 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
)decl
);
8012 if ((ctx
->region_type
& ORT_TARGET
) != 0)
8014 if (ctx
->region_type
& ORT_ACC
)
8015 /* For OpenACC, as remarked above, defer expansion. */
8020 ret
= lang_hooks
.decls
.omp_disregard_value_expr (decl
, shared
);
8023 unsigned nflags
= flags
;
8024 if ((ctx
->region_type
& ORT_ACC
) == 0)
8026 bool is_declare_target
= false;
8027 if (is_global_var (decl
)
8028 && varpool_node::get_create (decl
)->offloadable
)
8030 struct gimplify_omp_ctx
*octx
;
8031 for (octx
= ctx
->outer_context
;
8032 octx
; octx
= octx
->outer_context
)
8034 n
= splay_tree_lookup (octx
->variables
,
8035 (splay_tree_key
)decl
);
8037 && (n
->value
& GOVD_DATA_SHARE_CLASS
) != GOVD_SHARED
8038 && (n
->value
& GOVD_DATA_SHARE_CLASS
) != 0)
8041 is_declare_target
= octx
== NULL
;
8043 if (!is_declare_target
)
8046 enum omp_clause_defaultmap_kind kind
;
8047 if (lang_hooks
.decls
.omp_allocatable_p (decl
))
8048 gdmk
= GDMK_ALLOCATABLE
;
8049 else if (lang_hooks
.decls
.omp_scalar_target_p (decl
))
8050 gdmk
= GDMK_SCALAR_TARGET
;
8051 else if (lang_hooks
.decls
.omp_scalar_p (decl
, false))
8053 else if (TREE_CODE (TREE_TYPE (decl
)) == POINTER_TYPE
8054 || (TREE_CODE (TREE_TYPE (decl
)) == REFERENCE_TYPE
8055 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl
)))
8057 gdmk
= GDMK_POINTER
;
8059 gdmk
= GDMK_AGGREGATE
;
8060 kind
= lang_hooks
.decls
.omp_predetermined_mapping (decl
);
8061 if (kind
!= OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
)
8063 if (kind
== OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE
)
8064 nflags
|= GOVD_FIRSTPRIVATE
;
8065 else if (kind
== OMP_CLAUSE_DEFAULTMAP_TO
)
8066 nflags
|= GOVD_MAP
| GOVD_MAP_TO_ONLY
;
8070 else if (ctx
->defaultmap
[gdmk
] == 0)
8072 tree d
= lang_hooks
.decls
.omp_report_decl (decl
);
8073 error ("%qE not specified in enclosing %<target%>",
8075 inform (ctx
->location
, "enclosing %<target%>");
8077 else if (ctx
->defaultmap
[gdmk
]
8078 & (GOVD_MAP_0LEN_ARRAY
| GOVD_FIRSTPRIVATE
))
8079 nflags
|= ctx
->defaultmap
[gdmk
];
8080 else if (ctx
->defaultmap
[gdmk
] & GOVD_MAP_FORCE_PRESENT
)
8082 gcc_assert (ctx
->defaultmap
[gdmk
] & GOVD_MAP
);
8083 nflags
|= ctx
->defaultmap
[gdmk
] | GOVD_MAP_ALLOC_ONLY
;
8087 gcc_assert (ctx
->defaultmap
[gdmk
] & GOVD_MAP
);
8088 nflags
|= ctx
->defaultmap
[gdmk
] & ~GOVD_MAP
;
8093 struct gimplify_omp_ctx
*octx
= ctx
->outer_context
;
8094 if ((ctx
->region_type
& ORT_ACC
) && octx
)
8096 /* Look in outer OpenACC contexts, to see if there's a
8097 data attribute for this variable. */
8098 omp_notice_variable (octx
, decl
, in_code
);
8100 for (; octx
; octx
= octx
->outer_context
)
8102 if (!(octx
->region_type
& (ORT_TARGET_DATA
| ORT_TARGET
)))
8105 = splay_tree_lookup (octx
->variables
,
8106 (splay_tree_key
) decl
);
8109 if (octx
->region_type
== ORT_ACC_HOST_DATA
)
8110 error ("variable %qE declared in enclosing "
8111 "%<host_data%> region", DECL_NAME (decl
));
8113 if (octx
->region_type
== ORT_ACC_DATA
8114 && (n2
->value
& GOVD_MAP_0LEN_ARRAY
))
8115 nflags
|= GOVD_MAP_0LEN_ARRAY
;
8121 if ((nflags
& ~(GOVD_MAP_TO_ONLY
| GOVD_MAP_FROM_ONLY
8122 | GOVD_MAP_ALLOC_ONLY
)) == flags
)
8124 tree type
= TREE_TYPE (decl
);
8126 if (gimplify_omp_ctxp
->target_firstprivatize_array_bases
8127 && omp_privatize_by_reference (decl
))
8128 type
= TREE_TYPE (type
);
8129 if (!omp_mappable_type (type
))
8131 error ("%qD referenced in target region does not have "
8132 "a mappable type", decl
);
8133 nflags
|= GOVD_MAP
| GOVD_EXPLICIT
;
8137 if ((ctx
->region_type
& ORT_ACC
) != 0)
8138 nflags
= oacc_default_clause (ctx
, decl
, flags
);
8144 omp_add_variable (ctx
, decl
, nflags
);
8148 /* If nothing changed, there's nothing left to do. */
8149 if ((n
->value
& flags
) == flags
)
8159 if (ctx
->region_type
== ORT_WORKSHARE
8160 || ctx
->region_type
== ORT_TASKGROUP
8161 || ctx
->region_type
== ORT_SIMD
8162 || ctx
->region_type
== ORT_ACC
8163 || (ctx
->region_type
& ORT_TARGET_DATA
) != 0)
8166 flags
= omp_default_clause (ctx
, decl
, in_code
, flags
);
8168 if ((flags
& GOVD_PRIVATE
)
8169 && lang_hooks
.decls
.omp_private_outer_ref (decl
))
8170 flags
|= GOVD_PRIVATE_OUTER_REF
;
8172 omp_add_variable (ctx
, decl
, flags
);
8174 shared
= (flags
& GOVD_SHARED
) != 0;
8175 ret
= lang_hooks
.decls
.omp_disregard_value_expr (decl
, shared
);
8179 /* Don't mark as GOVD_SEEN addressable temporaries seen only in simd
8180 lb, b or incr expressions, those shouldn't be turned into simd arrays. */
8181 if (ctx
->region_type
== ORT_SIMD
8182 && ctx
->in_for_exprs
8183 && ((n
->value
& (GOVD_PRIVATE
| GOVD_SEEN
| GOVD_EXPLICIT
))
8185 flags
&= ~GOVD_SEEN
;
8187 if ((n
->value
& (GOVD_SEEN
| GOVD_LOCAL
)) == 0
8188 && (flags
& (GOVD_SEEN
| GOVD_LOCAL
)) == GOVD_SEEN
8189 && DECL_SIZE (decl
))
8191 if (TREE_CODE (DECL_SIZE (decl
)) != INTEGER_CST
)
8194 tree t
= DECL_VALUE_EXPR (decl
);
8195 gcc_assert (INDIRECT_REF_P (t
));
8196 t
= TREE_OPERAND (t
, 0);
8197 gcc_assert (DECL_P (t
));
8198 n2
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) t
);
8199 n2
->value
|= GOVD_SEEN
;
8201 else if (omp_privatize_by_reference (decl
)
8202 && TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl
)))
8203 && (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl
))))
8207 tree t
= TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl
)));
8208 gcc_assert (DECL_P (t
));
8209 n2
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) t
);
8211 omp_notice_variable (ctx
, t
, true);
8215 if (ctx
->region_type
& ORT_ACC
)
8216 /* For OpenACC, as remarked above, defer expansion. */
8219 shared
= ((flags
| n
->value
) & GOVD_SHARED
) != 0;
8220 ret
= lang_hooks
.decls
.omp_disregard_value_expr (decl
, shared
);
8222 /* If nothing changed, there's nothing left to do. */
8223 if ((n
->value
& flags
) == flags
)
8229 /* If the variable is private in the current context, then we don't
8230 need to propagate anything to an outer context. */
8231 if ((flags
& GOVD_PRIVATE
) && !(flags
& GOVD_PRIVATE_OUTER_REF
))
8233 if ((flags
& (GOVD_LINEAR
| GOVD_LINEAR_LASTPRIVATE_NO_OUTER
))
8234 == (GOVD_LINEAR
| GOVD_LINEAR_LASTPRIVATE_NO_OUTER
))
8236 if ((flags
& (GOVD_FIRSTPRIVATE
| GOVD_LASTPRIVATE
8237 | GOVD_LINEAR_LASTPRIVATE_NO_OUTER
))
8238 == (GOVD_LASTPRIVATE
| GOVD_LINEAR_LASTPRIVATE_NO_OUTER
))
8240 if (ctx
->outer_context
8241 && omp_notice_variable (ctx
->outer_context
, decl
, in_code
))
8246 /* Verify that DECL is private within CTX. If there's specific information
8247 to the contrary in the innermost scope, generate an error. */
8250 omp_is_private (struct gimplify_omp_ctx
*ctx
, tree decl
, int simd
)
8254 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
)decl
);
8257 if (n
->value
& GOVD_SHARED
)
8259 if (ctx
== gimplify_omp_ctxp
)
8262 error ("iteration variable %qE is predetermined linear",
8265 error ("iteration variable %qE should be private",
8267 n
->value
= GOVD_PRIVATE
;
8273 else if ((n
->value
& GOVD_EXPLICIT
) != 0
8274 && (ctx
== gimplify_omp_ctxp
8275 || (ctx
->region_type
== ORT_COMBINED_PARALLEL
8276 && gimplify_omp_ctxp
->outer_context
== ctx
)))
8278 if ((n
->value
& GOVD_FIRSTPRIVATE
) != 0)
8279 error ("iteration variable %qE should not be firstprivate",
8281 else if ((n
->value
& GOVD_REDUCTION
) != 0)
8282 error ("iteration variable %qE should not be reduction",
8284 else if (simd
!= 1 && (n
->value
& GOVD_LINEAR
) != 0)
8285 error ("iteration variable %qE should not be linear",
8288 return (ctx
== gimplify_omp_ctxp
8289 || (ctx
->region_type
== ORT_COMBINED_PARALLEL
8290 && gimplify_omp_ctxp
->outer_context
== ctx
));
8293 if (ctx
->region_type
!= ORT_WORKSHARE
8294 && ctx
->region_type
!= ORT_TASKGROUP
8295 && ctx
->region_type
!= ORT_SIMD
8296 && ctx
->region_type
!= ORT_ACC
)
8298 else if (ctx
->outer_context
)
8299 return omp_is_private (ctx
->outer_context
, decl
, simd
);
8303 /* Return true if DECL is private within a parallel region
8304 that binds to the current construct's context or in parallel
8305 region's REDUCTION clause. */
8308 omp_check_private (struct gimplify_omp_ctx
*ctx
, tree decl
, bool copyprivate
)
8314 ctx
= ctx
->outer_context
;
8317 if (is_global_var (decl
))
8320 /* References might be private, but might be shared too,
8321 when checking for copyprivate, assume they might be
8322 private, otherwise assume they might be shared. */
8326 if (omp_privatize_by_reference (decl
))
8329 /* Treat C++ privatized non-static data members outside
8330 of the privatization the same. */
8331 if (omp_member_access_dummy_var (decl
))
8337 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
8339 if ((ctx
->region_type
& (ORT_TARGET
| ORT_TARGET_DATA
)) != 0
8340 && (n
== NULL
|| (n
->value
& GOVD_DATA_SHARE_CLASS
) == 0))
8342 if ((ctx
->region_type
& ORT_TARGET_DATA
) != 0
8344 || (n
->value
& GOVD_MAP
) == 0)
8351 if ((n
->value
& GOVD_LOCAL
) != 0
8352 && omp_member_access_dummy_var (decl
))
8354 return (n
->value
& GOVD_SHARED
) == 0;
8357 if (ctx
->region_type
== ORT_WORKSHARE
8358 || ctx
->region_type
== ORT_TASKGROUP
8359 || ctx
->region_type
== ORT_SIMD
8360 || ctx
->region_type
== ORT_ACC
)
8369 /* Callback for walk_tree to find a DECL_EXPR for the given DECL. */
8372 find_decl_expr (tree
*tp
, int *walk_subtrees
, void *data
)
8376 /* If this node has been visited, unmark it and keep looking. */
8377 if (TREE_CODE (t
) == DECL_EXPR
&& DECL_EXPR_DECL (t
) == (tree
) data
)
8380 if (IS_TYPE_OR_DECL_P (t
))
8386 /* Gimplify the affinity clause but effectively ignore it.
8389 if ((step > 1) ? var <= end : var > end)
8390 locatator_var_expr; */
8393 gimplify_omp_affinity (tree
*list_p
, gimple_seq
*pre_p
)
8395 tree last_iter
= NULL_TREE
;
8396 tree last_bind
= NULL_TREE
;
8397 tree label
= NULL_TREE
;
8398 tree
*last_body
= NULL
;
8399 for (tree c
= *list_p
; c
; c
= OMP_CLAUSE_CHAIN (c
))
8400 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_AFFINITY
)
8402 tree t
= OMP_CLAUSE_DECL (c
);
8403 if (TREE_CODE (t
) == TREE_LIST
8405 && TREE_CODE (TREE_PURPOSE (t
)) == TREE_VEC
)
8407 if (TREE_VALUE (t
) == null_pointer_node
)
8409 if (TREE_PURPOSE (t
) != last_iter
)
8413 append_to_statement_list (label
, last_body
);
8414 gimplify_and_add (last_bind
, pre_p
);
8415 last_bind
= NULL_TREE
;
8417 for (tree it
= TREE_PURPOSE (t
); it
; it
= TREE_CHAIN (it
))
8419 if (gimplify_expr (&TREE_VEC_ELT (it
, 1), pre_p
, NULL
,
8420 is_gimple_val
, fb_rvalue
) == GS_ERROR
8421 || gimplify_expr (&TREE_VEC_ELT (it
, 2), pre_p
, NULL
,
8422 is_gimple_val
, fb_rvalue
) == GS_ERROR
8423 || gimplify_expr (&TREE_VEC_ELT (it
, 3), pre_p
, NULL
,
8424 is_gimple_val
, fb_rvalue
) == GS_ERROR
8425 || (gimplify_expr (&TREE_VEC_ELT (it
, 4), pre_p
, NULL
,
8426 is_gimple_val
, fb_rvalue
)
8430 last_iter
= TREE_PURPOSE (t
);
8431 tree block
= TREE_VEC_ELT (TREE_PURPOSE (t
), 5);
8432 last_bind
= build3 (BIND_EXPR
, void_type_node
, BLOCK_VARS (block
),
8434 last_body
= &BIND_EXPR_BODY (last_bind
);
8435 tree cond
= NULL_TREE
;
8436 location_t loc
= OMP_CLAUSE_LOCATION (c
);
8437 for (tree it
= TREE_PURPOSE (t
); it
; it
= TREE_CHAIN (it
))
8439 tree var
= TREE_VEC_ELT (it
, 0);
8440 tree begin
= TREE_VEC_ELT (it
, 1);
8441 tree end
= TREE_VEC_ELT (it
, 2);
8442 tree step
= TREE_VEC_ELT (it
, 3);
8443 loc
= DECL_SOURCE_LOCATION (var
);
8444 tree tem
= build2_loc (loc
, MODIFY_EXPR
, void_type_node
,
8446 append_to_statement_list_force (tem
, last_body
);
8448 tree cond1
= fold_build2_loc (loc
, GT_EXPR
, boolean_type_node
,
8449 step
, build_zero_cst (TREE_TYPE (step
)));
8450 tree cond2
= fold_build2_loc (loc
, LE_EXPR
, boolean_type_node
,
8452 tree cond3
= fold_build2_loc (loc
, GT_EXPR
, boolean_type_node
,
8454 cond1
= fold_build3_loc (loc
, COND_EXPR
, boolean_type_node
,
8455 cond1
, cond2
, cond3
);
8457 cond
= fold_build2_loc (loc
, TRUTH_AND_EXPR
,
8458 boolean_type_node
, cond
, cond1
);
8462 tree cont_label
= create_artificial_label (loc
);
8463 label
= build1 (LABEL_EXPR
, void_type_node
, cont_label
);
8464 tree tem
= fold_build3_loc (loc
, COND_EXPR
, void_type_node
, cond
,
8466 build_and_jump (&cont_label
));
8467 append_to_statement_list_force (tem
, last_body
);
8469 if (TREE_CODE (TREE_VALUE (t
)) == COMPOUND_EXPR
)
8471 append_to_statement_list (TREE_OPERAND (TREE_VALUE (t
), 0),
8473 TREE_VALUE (t
) = TREE_OPERAND (TREE_VALUE (t
), 1);
8475 if (error_operand_p (TREE_VALUE (t
)))
8477 append_to_statement_list_force (TREE_VALUE (t
), last_body
);
8478 TREE_VALUE (t
) = null_pointer_node
;
8484 append_to_statement_list (label
, last_body
);
8485 gimplify_and_add (last_bind
, pre_p
);
8486 last_bind
= NULL_TREE
;
8488 if (TREE_CODE (OMP_CLAUSE_DECL (c
)) == COMPOUND_EXPR
)
8490 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c
), 0), pre_p
,
8491 NULL
, is_gimple_val
, fb_rvalue
);
8492 OMP_CLAUSE_DECL (c
) = TREE_OPERAND (OMP_CLAUSE_DECL (c
), 1);
8494 if (error_operand_p (OMP_CLAUSE_DECL (c
)))
8496 if (gimplify_expr (&OMP_CLAUSE_DECL (c
), pre_p
, NULL
,
8497 is_gimple_lvalue
, fb_lvalue
) == GS_ERROR
)
8499 gimplify_and_add (OMP_CLAUSE_DECL (c
), pre_p
);
8504 append_to_statement_list (label
, last_body
);
8505 gimplify_and_add (last_bind
, pre_p
);
8510 /* If *LIST_P contains any OpenMP depend clauses with iterators,
8511 lower all the depend clauses by populating corresponding depend
8512 array. Returns 0 if there are no such depend clauses, or
8513 2 if all depend clauses should be removed, 1 otherwise. */
8516 gimplify_omp_depend (tree
*list_p
, gimple_seq
*pre_p
)
8520 size_t n
[5] = { 0, 0, 0, 0, 0 };
8522 tree counts
[5] = { NULL_TREE
, NULL_TREE
, NULL_TREE
, NULL_TREE
, NULL_TREE
};
8523 tree last_iter
= NULL_TREE
, last_count
= NULL_TREE
;
8525 location_t first_loc
= UNKNOWN_LOCATION
;
8527 for (c
= *list_p
; c
; c
= OMP_CLAUSE_CHAIN (c
))
8528 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEPEND
)
8530 switch (OMP_CLAUSE_DEPEND_KIND (c
))
8532 case OMP_CLAUSE_DEPEND_IN
:
8535 case OMP_CLAUSE_DEPEND_OUT
:
8536 case OMP_CLAUSE_DEPEND_INOUT
:
8539 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET
:
8542 case OMP_CLAUSE_DEPEND_DEPOBJ
:
8545 case OMP_CLAUSE_DEPEND_INOUTSET
:
8551 tree t
= OMP_CLAUSE_DECL (c
);
8552 if (first_loc
== UNKNOWN_LOCATION
)
8553 first_loc
= OMP_CLAUSE_LOCATION (c
);
8554 if (TREE_CODE (t
) == TREE_LIST
8556 && TREE_CODE (TREE_PURPOSE (t
)) == TREE_VEC
)
8558 if (TREE_PURPOSE (t
) != last_iter
)
8560 tree tcnt
= size_one_node
;
8561 for (tree it
= TREE_PURPOSE (t
); it
; it
= TREE_CHAIN (it
))
8563 if (gimplify_expr (&TREE_VEC_ELT (it
, 1), pre_p
, NULL
,
8564 is_gimple_val
, fb_rvalue
) == GS_ERROR
8565 || gimplify_expr (&TREE_VEC_ELT (it
, 2), pre_p
, NULL
,
8566 is_gimple_val
, fb_rvalue
) == GS_ERROR
8567 || gimplify_expr (&TREE_VEC_ELT (it
, 3), pre_p
, NULL
,
8568 is_gimple_val
, fb_rvalue
) == GS_ERROR
8569 || (gimplify_expr (&TREE_VEC_ELT (it
, 4), pre_p
, NULL
,
8570 is_gimple_val
, fb_rvalue
)
8573 tree var
= TREE_VEC_ELT (it
, 0);
8574 tree begin
= TREE_VEC_ELT (it
, 1);
8575 tree end
= TREE_VEC_ELT (it
, 2);
8576 tree step
= TREE_VEC_ELT (it
, 3);
8577 tree orig_step
= TREE_VEC_ELT (it
, 4);
8578 tree type
= TREE_TYPE (var
);
8579 tree stype
= TREE_TYPE (step
);
8580 location_t loc
= DECL_SOURCE_LOCATION (var
);
8582 /* Compute count for this iterator as
8584 ? (begin < end ? (end - begin + (step - 1)) / step : 0)
8585 : (begin > end ? (end - begin + (step + 1)) / step : 0)
8586 and compute product of those for the entire depend
8588 if (POINTER_TYPE_P (type
))
8589 endmbegin
= fold_build2_loc (loc
, POINTER_DIFF_EXPR
,
8592 endmbegin
= fold_build2_loc (loc
, MINUS_EXPR
, type
,
8594 tree stepm1
= fold_build2_loc (loc
, MINUS_EXPR
, stype
,
8596 build_int_cst (stype
, 1));
8597 tree stepp1
= fold_build2_loc (loc
, PLUS_EXPR
, stype
, step
,
8598 build_int_cst (stype
, 1));
8599 tree pos
= fold_build2_loc (loc
, PLUS_EXPR
, stype
,
8600 unshare_expr (endmbegin
),
8602 pos
= fold_build2_loc (loc
, TRUNC_DIV_EXPR
, stype
,
8604 tree neg
= fold_build2_loc (loc
, PLUS_EXPR
, stype
,
8606 if (TYPE_UNSIGNED (stype
))
8608 neg
= fold_build1_loc (loc
, NEGATE_EXPR
, stype
, neg
);
8609 step
= fold_build1_loc (loc
, NEGATE_EXPR
, stype
, step
);
8611 neg
= fold_build2_loc (loc
, TRUNC_DIV_EXPR
, stype
,
8614 tree cond
= fold_build2_loc (loc
, LT_EXPR
,
8617 pos
= fold_build3_loc (loc
, COND_EXPR
, stype
, cond
, pos
,
8618 build_int_cst (stype
, 0));
8619 cond
= fold_build2_loc (loc
, LT_EXPR
, boolean_type_node
,
8621 neg
= fold_build3_loc (loc
, COND_EXPR
, stype
, cond
, neg
,
8622 build_int_cst (stype
, 0));
8623 tree osteptype
= TREE_TYPE (orig_step
);
8624 cond
= fold_build2_loc (loc
, GT_EXPR
, boolean_type_node
,
8626 build_int_cst (osteptype
, 0));
8627 tree cnt
= fold_build3_loc (loc
, COND_EXPR
, stype
,
8629 cnt
= fold_convert_loc (loc
, sizetype
, cnt
);
8630 if (gimplify_expr (&cnt
, pre_p
, NULL
, is_gimple_val
,
8631 fb_rvalue
) == GS_ERROR
)
8633 tcnt
= size_binop_loc (loc
, MULT_EXPR
, tcnt
, cnt
);
8635 if (gimplify_expr (&tcnt
, pre_p
, NULL
, is_gimple_val
,
8636 fb_rvalue
) == GS_ERROR
)
8638 last_iter
= TREE_PURPOSE (t
);
8641 if (counts
[i
] == NULL_TREE
)
8642 counts
[i
] = last_count
;
8644 counts
[i
] = size_binop_loc (OMP_CLAUSE_LOCATION (c
),
8645 PLUS_EXPR
, counts
[i
], last_count
);
8650 for (i
= 0; i
< 5; i
++)
8656 tree total
= size_zero_node
;
8657 for (i
= 0; i
< 5; i
++)
8659 unused
[i
] = counts
[i
] == NULL_TREE
&& n
[i
] == 0;
8660 if (counts
[i
] == NULL_TREE
)
8661 counts
[i
] = size_zero_node
;
8663 counts
[i
] = size_binop (PLUS_EXPR
, counts
[i
], size_int (n
[i
]));
8664 if (gimplify_expr (&counts
[i
], pre_p
, NULL
, is_gimple_val
,
8665 fb_rvalue
) == GS_ERROR
)
8667 total
= size_binop (PLUS_EXPR
, total
, counts
[i
]);
8670 if (gimplify_expr (&total
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
)
8673 bool is_old
= unused
[1] && unused
[3] && unused
[4];
8674 tree totalpx
= size_binop (PLUS_EXPR
, unshare_expr (total
),
8675 size_int (is_old
? 1 : 4));
8677 totalpx
= size_binop (PLUS_EXPR
, totalpx
,
8678 size_binop (MULT_EXPR
, counts
[4], size_int (2)));
8679 tree type
= build_array_type (ptr_type_node
, build_index_type (totalpx
));
8680 tree array
= create_tmp_var_raw (type
);
8681 TREE_ADDRESSABLE (array
) = 1;
8682 if (!poly_int_tree_p (totalpx
))
8684 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (array
)))
8685 gimplify_type_sizes (TREE_TYPE (array
), pre_p
);
8686 if (gimplify_omp_ctxp
)
8688 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
8690 && (ctx
->region_type
== ORT_WORKSHARE
8691 || ctx
->region_type
== ORT_TASKGROUP
8692 || ctx
->region_type
== ORT_SIMD
8693 || ctx
->region_type
== ORT_ACC
))
8694 ctx
= ctx
->outer_context
;
8696 omp_add_variable (ctx
, array
, GOVD_LOCAL
| GOVD_SEEN
);
8698 gimplify_vla_decl (array
, pre_p
);
8701 gimple_add_tmp_var (array
);
8702 tree r
= build4 (ARRAY_REF
, ptr_type_node
, array
, size_int (0), NULL_TREE
,
8707 tem
= build2 (MODIFY_EXPR
, void_type_node
, r
,
8708 build_int_cst (ptr_type_node
, 0));
8709 gimplify_and_add (tem
, pre_p
);
8710 r
= build4 (ARRAY_REF
, ptr_type_node
, array
, size_int (1), NULL_TREE
,
8713 tem
= build2 (MODIFY_EXPR
, void_type_node
, r
,
8714 fold_convert (ptr_type_node
, total
));
8715 gimplify_and_add (tem
, pre_p
);
8716 for (i
= 1; i
< (is_old
? 2 : 4); i
++)
8718 r
= build4 (ARRAY_REF
, ptr_type_node
, array
, size_int (i
+ !is_old
),
8719 NULL_TREE
, NULL_TREE
);
8720 tem
= build2 (MODIFY_EXPR
, void_type_node
, r
, counts
[i
- 1]);
8721 gimplify_and_add (tem
, pre_p
);
8728 for (i
= 0; i
< 5; i
++)
8730 if (i
&& (i
>= j
|| unused
[i
- 1]))
8732 cnts
[i
] = cnts
[i
- 1];
8735 cnts
[i
] = create_tmp_var (sizetype
);
8737 g
= gimple_build_assign (cnts
[i
], size_int (is_old
? 2 : 5));
8742 t
= size_binop (PLUS_EXPR
, counts
[0], size_int (2));
8744 t
= size_binop (PLUS_EXPR
, cnts
[i
- 1], counts
[i
- 1]);
8745 if (gimplify_expr (&t
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
)
8748 g
= gimple_build_assign (cnts
[i
], t
);
8750 gimple_seq_add_stmt (pre_p
, g
);
8753 cnts
[5] = NULL_TREE
;
8756 tree t
= size_binop (PLUS_EXPR
, total
, size_int (5));
8757 cnts
[5] = create_tmp_var (sizetype
);
8758 g
= gimple_build_assign (cnts
[i
], t
);
8759 gimple_seq_add_stmt (pre_p
, g
);
8762 last_iter
= NULL_TREE
;
8763 tree last_bind
= NULL_TREE
;
8764 tree
*last_body
= NULL
;
8765 for (c
= *list_p
; c
; c
= OMP_CLAUSE_CHAIN (c
))
8766 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEPEND
)
8768 switch (OMP_CLAUSE_DEPEND_KIND (c
))
8770 case OMP_CLAUSE_DEPEND_IN
:
8773 case OMP_CLAUSE_DEPEND_OUT
:
8774 case OMP_CLAUSE_DEPEND_INOUT
:
8777 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET
:
8780 case OMP_CLAUSE_DEPEND_DEPOBJ
:
8783 case OMP_CLAUSE_DEPEND_INOUTSET
:
8789 tree t
= OMP_CLAUSE_DECL (c
);
8790 if (TREE_CODE (t
) == TREE_LIST
8792 && TREE_CODE (TREE_PURPOSE (t
)) == TREE_VEC
)
8794 if (TREE_PURPOSE (t
) != last_iter
)
8797 gimplify_and_add (last_bind
, pre_p
);
8798 tree block
= TREE_VEC_ELT (TREE_PURPOSE (t
), 5);
8799 last_bind
= build3 (BIND_EXPR
, void_type_node
,
8800 BLOCK_VARS (block
), NULL
, block
);
8801 TREE_SIDE_EFFECTS (last_bind
) = 1;
8802 SET_EXPR_LOCATION (last_bind
, OMP_CLAUSE_LOCATION (c
));
8803 tree
*p
= &BIND_EXPR_BODY (last_bind
);
8804 for (tree it
= TREE_PURPOSE (t
); it
; it
= TREE_CHAIN (it
))
8806 tree var
= TREE_VEC_ELT (it
, 0);
8807 tree begin
= TREE_VEC_ELT (it
, 1);
8808 tree end
= TREE_VEC_ELT (it
, 2);
8809 tree step
= TREE_VEC_ELT (it
, 3);
8810 tree orig_step
= TREE_VEC_ELT (it
, 4);
8811 tree type
= TREE_TYPE (var
);
8812 location_t loc
= DECL_SOURCE_LOCATION (var
);
8820 if (orig_step > 0) {
8821 if (var < end) goto beg_label;
8823 if (var > end) goto beg_label;
8825 for each iterator, with inner iterators added to
8827 tree beg_label
= create_artificial_label (loc
);
8828 tree cond_label
= NULL_TREE
;
8829 tem
= build2_loc (loc
, MODIFY_EXPR
, void_type_node
,
8831 append_to_statement_list_force (tem
, p
);
8832 tem
= build_and_jump (&cond_label
);
8833 append_to_statement_list_force (tem
, p
);
8834 tem
= build1 (LABEL_EXPR
, void_type_node
, beg_label
);
8835 append_to_statement_list (tem
, p
);
8836 tree bind
= build3 (BIND_EXPR
, void_type_node
, NULL_TREE
,
8837 NULL_TREE
, NULL_TREE
);
8838 TREE_SIDE_EFFECTS (bind
) = 1;
8839 SET_EXPR_LOCATION (bind
, loc
);
8840 append_to_statement_list_force (bind
, p
);
8841 if (POINTER_TYPE_P (type
))
8842 tem
= build2_loc (loc
, POINTER_PLUS_EXPR
, type
,
8843 var
, fold_convert_loc (loc
, sizetype
,
8846 tem
= build2_loc (loc
, PLUS_EXPR
, type
, var
, step
);
8847 tem
= build2_loc (loc
, MODIFY_EXPR
, void_type_node
,
8849 append_to_statement_list_force (tem
, p
);
8850 tem
= build1 (LABEL_EXPR
, void_type_node
, cond_label
);
8851 append_to_statement_list (tem
, p
);
8852 tree cond
= fold_build2_loc (loc
, LT_EXPR
,
8856 = fold_build3_loc (loc
, COND_EXPR
, void_type_node
,
8857 cond
, build_and_jump (&beg_label
),
8859 cond
= fold_build2_loc (loc
, GT_EXPR
, boolean_type_node
,
8862 = fold_build3_loc (loc
, COND_EXPR
, void_type_node
,
8863 cond
, build_and_jump (&beg_label
),
8865 tree osteptype
= TREE_TYPE (orig_step
);
8866 cond
= fold_build2_loc (loc
, GT_EXPR
, boolean_type_node
,
8868 build_int_cst (osteptype
, 0));
8869 tem
= fold_build3_loc (loc
, COND_EXPR
, void_type_node
,
8871 append_to_statement_list_force (tem
, p
);
8872 p
= &BIND_EXPR_BODY (bind
);
8876 last_iter
= TREE_PURPOSE (t
);
8877 if (TREE_CODE (TREE_VALUE (t
)) == COMPOUND_EXPR
)
8879 append_to_statement_list (TREE_OPERAND (TREE_VALUE (t
),
8881 TREE_VALUE (t
) = TREE_OPERAND (TREE_VALUE (t
), 1);
8883 if (error_operand_p (TREE_VALUE (t
)))
8885 if (TREE_VALUE (t
) != null_pointer_node
)
8886 TREE_VALUE (t
) = build_fold_addr_expr (TREE_VALUE (t
));
8889 r
= build4 (ARRAY_REF
, ptr_type_node
, array
, cnts
[i
],
8890 NULL_TREE
, NULL_TREE
);
8891 tree r2
= build4 (ARRAY_REF
, ptr_type_node
, array
, cnts
[5],
8892 NULL_TREE
, NULL_TREE
);
8893 r2
= build_fold_addr_expr_with_type (r2
, ptr_type_node
);
8894 tem
= build2_loc (OMP_CLAUSE_LOCATION (c
), MODIFY_EXPR
,
8895 void_type_node
, r
, r2
);
8896 append_to_statement_list_force (tem
, last_body
);
8897 tem
= build2_loc (OMP_CLAUSE_LOCATION (c
), MODIFY_EXPR
,
8898 void_type_node
, cnts
[i
],
8899 size_binop (PLUS_EXPR
, cnts
[i
],
8901 append_to_statement_list_force (tem
, last_body
);
8904 r
= build4 (ARRAY_REF
, ptr_type_node
, array
, cnts
[i
],
8905 NULL_TREE
, NULL_TREE
);
8906 tem
= build2_loc (OMP_CLAUSE_LOCATION (c
), MODIFY_EXPR
,
8907 void_type_node
, r
, TREE_VALUE (t
));
8908 append_to_statement_list_force (tem
, last_body
);
8911 r
= build4 (ARRAY_REF
, ptr_type_node
, array
,
8912 size_binop (PLUS_EXPR
, cnts
[i
], size_int (1)),
8913 NULL_TREE
, NULL_TREE
);
8914 tem
= build_int_cst (ptr_type_node
, GOMP_DEPEND_INOUTSET
);
8915 tem
= build2_loc (OMP_CLAUSE_LOCATION (c
), MODIFY_EXPR
,
8916 void_type_node
, r
, tem
);
8917 append_to_statement_list_force (tem
, last_body
);
8919 tem
= build2_loc (OMP_CLAUSE_LOCATION (c
), MODIFY_EXPR
,
8920 void_type_node
, cnts
[i
],
8921 size_binop (PLUS_EXPR
, cnts
[i
],
8922 size_int (1 + (i
== 5))));
8923 append_to_statement_list_force (tem
, last_body
);
8924 TREE_VALUE (t
) = null_pointer_node
;
8930 gimplify_and_add (last_bind
, pre_p
);
8931 last_bind
= NULL_TREE
;
8933 if (TREE_CODE (OMP_CLAUSE_DECL (c
)) == COMPOUND_EXPR
)
8935 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c
), 0), pre_p
,
8936 NULL
, is_gimple_val
, fb_rvalue
);
8937 OMP_CLAUSE_DECL (c
) = TREE_OPERAND (OMP_CLAUSE_DECL (c
), 1);
8939 if (error_operand_p (OMP_CLAUSE_DECL (c
)))
8941 if (OMP_CLAUSE_DECL (c
) != null_pointer_node
)
8942 OMP_CLAUSE_DECL (c
) = build_fold_addr_expr (OMP_CLAUSE_DECL (c
));
8943 if (gimplify_expr (&OMP_CLAUSE_DECL (c
), pre_p
, NULL
,
8944 is_gimple_val
, fb_rvalue
) == GS_ERROR
)
8948 r
= build4 (ARRAY_REF
, ptr_type_node
, array
, cnts
[i
],
8949 NULL_TREE
, NULL_TREE
);
8950 tree r2
= build4 (ARRAY_REF
, ptr_type_node
, array
, cnts
[5],
8951 NULL_TREE
, NULL_TREE
);
8952 r2
= build_fold_addr_expr_with_type (r2
, ptr_type_node
);
8953 tem
= build2 (MODIFY_EXPR
, void_type_node
, r
, r2
);
8954 gimplify_and_add (tem
, pre_p
);
8955 g
= gimple_build_assign (cnts
[i
], size_binop (PLUS_EXPR
,
8958 gimple_seq_add_stmt (pre_p
, g
);
8961 r
= build4 (ARRAY_REF
, ptr_type_node
, array
, cnts
[i
],
8962 NULL_TREE
, NULL_TREE
);
8963 tem
= build2 (MODIFY_EXPR
, void_type_node
, r
, OMP_CLAUSE_DECL (c
));
8964 gimplify_and_add (tem
, pre_p
);
8967 r
= build4 (ARRAY_REF
, ptr_type_node
, array
,
8968 size_binop (PLUS_EXPR
, cnts
[i
], size_int (1)),
8969 NULL_TREE
, NULL_TREE
);
8970 tem
= build_int_cst (ptr_type_node
, GOMP_DEPEND_INOUTSET
);
8971 tem
= build2 (MODIFY_EXPR
, void_type_node
, r
, tem
);
8972 append_to_statement_list_force (tem
, last_body
);
8973 gimplify_and_add (tem
, pre_p
);
8975 g
= gimple_build_assign (cnts
[i
],
8976 size_binop (PLUS_EXPR
, cnts
[i
],
8977 size_int (1 + (i
== 5))));
8978 gimple_seq_add_stmt (pre_p
, g
);
8982 gimplify_and_add (last_bind
, pre_p
);
8983 tree cond
= boolean_false_node
;
8987 cond
= build2_loc (first_loc
, NE_EXPR
, boolean_type_node
, cnts
[0],
8988 size_binop_loc (first_loc
, PLUS_EXPR
, counts
[0],
8991 cond
= build2_loc (first_loc
, TRUTH_OR_EXPR
, boolean_type_node
, cond
,
8992 build2_loc (first_loc
, NE_EXPR
, boolean_type_node
,
8994 size_binop_loc (first_loc
, PLUS_EXPR
,
9000 tree prev
= size_int (5);
9001 for (i
= 0; i
< 5; i
++)
9005 prev
= size_binop_loc (first_loc
, PLUS_EXPR
, counts
[i
], prev
);
9006 cond
= build2_loc (first_loc
, TRUTH_OR_EXPR
, boolean_type_node
, cond
,
9007 build2_loc (first_loc
, NE_EXPR
, boolean_type_node
,
9008 cnts
[i
], unshare_expr (prev
)));
9011 tem
= build3_loc (first_loc
, COND_EXPR
, void_type_node
, cond
,
9012 build_call_expr_loc (first_loc
,
9013 builtin_decl_explicit (BUILT_IN_TRAP
),
9015 gimplify_and_add (tem
, pre_p
);
9016 c
= build_omp_clause (UNKNOWN_LOCATION
, OMP_CLAUSE_DEPEND
);
9017 OMP_CLAUSE_DEPEND_KIND (c
) = OMP_CLAUSE_DEPEND_LAST
;
9018 OMP_CLAUSE_DECL (c
) = build_fold_addr_expr (array
);
9019 OMP_CLAUSE_CHAIN (c
) = *list_p
;
9024 /* For a set of mappings describing an array section pointed to by a struct
9025 (or derived type, etc.) component, create an "alloc" or "release" node to
9026 insert into a list following a GOMP_MAP_STRUCT node. For some types of
9027 mapping (e.g. Fortran arrays with descriptors), an additional mapping may
9028 be created that is inserted into the list of mapping nodes attached to the
9029 directive being processed -- not part of the sorted list of nodes after
9032 CODE is the code of the directive being processed. GRP_START and GRP_END
9033 are the first and last of two or three nodes representing this array section
9034 mapping (e.g. a data movement node like GOMP_MAP_{TO,FROM}, optionally a
9035 GOMP_MAP_TO_PSET, and finally a GOMP_MAP_ALWAYS_POINTER). EXTRA_NODE is
9036 filled with the additional node described above, if needed.
9038 This function does not add the new nodes to any lists itself. It is the
9039 responsibility of the caller to do that. */
9042 build_omp_struct_comp_nodes (enum tree_code code
, tree grp_start
, tree grp_end
,
9045 enum gomp_map_kind mkind
9046 = (code
== OMP_TARGET_EXIT_DATA
|| code
== OACC_EXIT_DATA
)
9047 ? GOMP_MAP_RELEASE
: GOMP_MAP_ALLOC
;
9049 gcc_assert (grp_start
!= grp_end
);
9051 tree c2
= build_omp_clause (OMP_CLAUSE_LOCATION (grp_end
), OMP_CLAUSE_MAP
);
9052 OMP_CLAUSE_SET_MAP_KIND (c2
, mkind
);
9053 OMP_CLAUSE_DECL (c2
) = unshare_expr (OMP_CLAUSE_DECL (grp_end
));
9054 OMP_CLAUSE_CHAIN (c2
) = NULL_TREE
;
9055 tree grp_mid
= NULL_TREE
;
9056 if (OMP_CLAUSE_CHAIN (grp_start
) != grp_end
)
9057 grp_mid
= OMP_CLAUSE_CHAIN (grp_start
);
9060 && OMP_CLAUSE_CODE (grp_mid
) == OMP_CLAUSE_MAP
9061 && OMP_CLAUSE_MAP_KIND (grp_mid
) == GOMP_MAP_TO_PSET
)
9062 OMP_CLAUSE_SIZE (c2
) = OMP_CLAUSE_SIZE (grp_mid
);
9064 OMP_CLAUSE_SIZE (c2
) = TYPE_SIZE_UNIT (ptr_type_node
);
9067 && OMP_CLAUSE_CODE (grp_mid
) == OMP_CLAUSE_MAP
9068 && (OMP_CLAUSE_MAP_KIND (grp_mid
) == GOMP_MAP_ALWAYS_POINTER
9069 || OMP_CLAUSE_MAP_KIND (grp_mid
) == GOMP_MAP_ATTACH_DETACH
))
9072 = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end
), OMP_CLAUSE_MAP
);
9073 OMP_CLAUSE_SET_MAP_KIND (c3
, mkind
);
9074 OMP_CLAUSE_DECL (c3
) = unshare_expr (OMP_CLAUSE_DECL (grp_mid
));
9075 OMP_CLAUSE_SIZE (c3
) = TYPE_SIZE_UNIT (ptr_type_node
);
9076 OMP_CLAUSE_CHAIN (c3
) = NULL_TREE
;
9081 *extra_node
= NULL_TREE
;
9086 /* Strip ARRAY_REFS or an indirect ref off BASE, find the containing object,
9087 and set *BITPOSP and *POFFSETP to the bit offset of the access.
9088 If BASE_REF is non-NULL and the containing object is a reference, set
9089 *BASE_REF to that reference before dereferencing the object.
9090 If BASE_REF is NULL, check that the containing object is a COMPONENT_REF or
9091 has array type, else return NULL. */
9094 extract_base_bit_offset (tree base
, poly_int64
*bitposp
,
9095 poly_offset_int
*poffsetp
)
9098 poly_int64 bitsize
, bitpos
;
9100 int unsignedp
, reversep
, volatilep
= 0;
9101 poly_offset_int poffset
;
9105 base
= get_inner_reference (base
, &bitsize
, &bitpos
, &offset
, &mode
,
9106 &unsignedp
, &reversep
, &volatilep
);
9110 if (offset
&& poly_int_tree_p (offset
))
9112 poffset
= wi::to_poly_offset (offset
);
9118 if (maybe_ne (bitpos
, 0))
9119 poffset
+= bits_to_bytes_round_down (bitpos
);
9122 *poffsetp
= poffset
;
9127 /* Used for topological sorting of mapping groups. UNVISITED means we haven't
9128 started processing the group yet. The TEMPORARY mark is used when we first
9129 encounter a group on a depth-first traversal, and the PERMANENT mark is used
9130 when we have processed all the group's children (i.e. all the base pointers
9131 referred to by the group's mapping nodes, recursively). */
9133 enum omp_tsort_mark
{
9139 /* Hash for trees based on operand_equal_p. Like tree_operand_hash
9140 but ignores side effects in the equality comparisons. */
9142 struct tree_operand_hash_no_se
: tree_operand_hash
9144 static inline bool equal (const value_type
&,
9145 const compare_type
&);
9149 tree_operand_hash_no_se::equal (const value_type
&t1
,
9150 const compare_type
&t2
)
9152 return operand_equal_p (t1
, t2
, OEP_MATCH_SIDE_EFFECTS
);
9155 /* A group of OMP_CLAUSE_MAP nodes that correspond to a single "map"
9158 struct omp_mapping_group
{
9161 omp_tsort_mark mark
;
9162 /* If we've removed the group but need to reindex, mark the group as
9165 struct omp_mapping_group
*sibling
;
9166 struct omp_mapping_group
*next
;
9170 debug_mapping_group (omp_mapping_group
*grp
)
9172 tree tmp
= OMP_CLAUSE_CHAIN (grp
->grp_end
);
9173 OMP_CLAUSE_CHAIN (grp
->grp_end
) = NULL
;
9174 debug_generic_expr (*grp
->grp_start
);
9175 OMP_CLAUSE_CHAIN (grp
->grp_end
) = tmp
;
9178 /* Return the OpenMP "base pointer" of an expression EXPR, or NULL if there
9182 omp_get_base_pointer (tree expr
)
9184 while (TREE_CODE (expr
) == ARRAY_REF
9185 || TREE_CODE (expr
) == COMPONENT_REF
)
9186 expr
= TREE_OPERAND (expr
, 0);
9188 if (INDIRECT_REF_P (expr
)
9189 || (TREE_CODE (expr
) == MEM_REF
9190 && integer_zerop (TREE_OPERAND (expr
, 1))))
9192 expr
= TREE_OPERAND (expr
, 0);
9193 while (TREE_CODE (expr
) == COMPOUND_EXPR
)
9194 expr
= TREE_OPERAND (expr
, 1);
9195 if (TREE_CODE (expr
) == POINTER_PLUS_EXPR
)
9196 expr
= TREE_OPERAND (expr
, 0);
9197 if (TREE_CODE (expr
) == SAVE_EXPR
)
9198 expr
= TREE_OPERAND (expr
, 0);
9206 /* Remove COMPONENT_REFS and indirections from EXPR. */
9209 omp_strip_components_and_deref (tree expr
)
9211 while (TREE_CODE (expr
) == COMPONENT_REF
9212 || INDIRECT_REF_P (expr
)
9213 || (TREE_CODE (expr
) == MEM_REF
9214 && integer_zerop (TREE_OPERAND (expr
, 1)))
9215 || TREE_CODE (expr
) == POINTER_PLUS_EXPR
9216 || TREE_CODE (expr
) == COMPOUND_EXPR
)
9217 if (TREE_CODE (expr
) == COMPOUND_EXPR
)
9218 expr
= TREE_OPERAND (expr
, 1);
9220 expr
= TREE_OPERAND (expr
, 0);
9228 omp_strip_indirections (tree expr
)
9230 while (INDIRECT_REF_P (expr
)
9231 || (TREE_CODE (expr
) == MEM_REF
9232 && integer_zerop (TREE_OPERAND (expr
, 1))))
9233 expr
= TREE_OPERAND (expr
, 0);
9238 /* An attach or detach operation depends directly on the address being
9239 attached/detached. Return that address, or none if there are no
9240 attachments/detachments. */
9243 omp_get_attachment (omp_mapping_group
*grp
)
9245 tree node
= *grp
->grp_start
;
9247 switch (OMP_CLAUSE_MAP_KIND (node
))
9251 case GOMP_MAP_TOFROM
:
9252 case GOMP_MAP_ALWAYS_FROM
:
9253 case GOMP_MAP_ALWAYS_TO
:
9254 case GOMP_MAP_ALWAYS_TOFROM
:
9255 case GOMP_MAP_FORCE_FROM
:
9256 case GOMP_MAP_FORCE_TO
:
9257 case GOMP_MAP_FORCE_TOFROM
:
9258 case GOMP_MAP_FORCE_PRESENT
:
9259 case GOMP_MAP_PRESENT_ALLOC
:
9260 case GOMP_MAP_PRESENT_FROM
:
9261 case GOMP_MAP_PRESENT_TO
:
9262 case GOMP_MAP_PRESENT_TOFROM
:
9263 case GOMP_MAP_ALWAYS_PRESENT_FROM
:
9264 case GOMP_MAP_ALWAYS_PRESENT_TO
:
9265 case GOMP_MAP_ALWAYS_PRESENT_TOFROM
:
9266 case GOMP_MAP_ALLOC
:
9267 case GOMP_MAP_RELEASE
:
9268 case GOMP_MAP_DELETE
:
9269 case GOMP_MAP_FORCE_ALLOC
:
9270 if (node
== grp
->grp_end
)
9273 node
= OMP_CLAUSE_CHAIN (node
);
9274 if (node
&& OMP_CLAUSE_MAP_KIND (node
) == GOMP_MAP_TO_PSET
)
9276 gcc_assert (node
!= grp
->grp_end
);
9277 node
= OMP_CLAUSE_CHAIN (node
);
9280 switch (OMP_CLAUSE_MAP_KIND (node
))
9282 case GOMP_MAP_POINTER
:
9283 case GOMP_MAP_ALWAYS_POINTER
:
9284 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
9285 case GOMP_MAP_FIRSTPRIVATE_REFERENCE
:
9286 case GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION
:
9289 case GOMP_MAP_ATTACH_DETACH
:
9290 case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION
:
9291 return OMP_CLAUSE_DECL (node
);
9294 internal_error ("unexpected mapping node");
9296 return error_mark_node
;
9298 case GOMP_MAP_TO_PSET
:
9299 gcc_assert (node
!= grp
->grp_end
);
9300 node
= OMP_CLAUSE_CHAIN (node
);
9301 if (OMP_CLAUSE_MAP_KIND (node
) == GOMP_MAP_ATTACH
9302 || OMP_CLAUSE_MAP_KIND (node
) == GOMP_MAP_DETACH
)
9303 return OMP_CLAUSE_DECL (node
);
9305 internal_error ("unexpected mapping node");
9306 return error_mark_node
;
9308 case GOMP_MAP_ATTACH
:
9309 case GOMP_MAP_DETACH
:
9310 node
= OMP_CLAUSE_CHAIN (node
);
9311 if (!node
|| *grp
->grp_start
== grp
->grp_end
)
9312 return OMP_CLAUSE_DECL (*grp
->grp_start
);
9313 if (OMP_CLAUSE_MAP_KIND (node
) == GOMP_MAP_FIRSTPRIVATE_POINTER
9314 || OMP_CLAUSE_MAP_KIND (node
) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
)
9315 return OMP_CLAUSE_DECL (*grp
->grp_start
);
9317 internal_error ("unexpected mapping node");
9318 return error_mark_node
;
9320 case GOMP_MAP_STRUCT
:
9321 case GOMP_MAP_FORCE_DEVICEPTR
:
9322 case GOMP_MAP_DEVICE_RESIDENT
:
9324 case GOMP_MAP_IF_PRESENT
:
9325 case GOMP_MAP_FIRSTPRIVATE
:
9326 case GOMP_MAP_FIRSTPRIVATE_INT
:
9327 case GOMP_MAP_USE_DEVICE_PTR
:
9328 case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION
:
9332 internal_error ("unexpected mapping node");
9335 return error_mark_node
;
9338 /* Given a pointer START_P to the start of a group of related (e.g. pointer)
9339 mappings, return the chain pointer to the end of that group in the list. */
9342 omp_group_last (tree
*start_p
)
9344 tree c
= *start_p
, nc
, *grp_last_p
= start_p
;
9346 gcc_assert (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_MAP
);
9348 nc
= OMP_CLAUSE_CHAIN (c
);
9350 if (!nc
|| OMP_CLAUSE_CODE (nc
) != OMP_CLAUSE_MAP
)
9353 switch (OMP_CLAUSE_MAP_KIND (c
))
9357 && OMP_CLAUSE_CODE (nc
) == OMP_CLAUSE_MAP
9358 && (OMP_CLAUSE_MAP_KIND (nc
) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
9359 || OMP_CLAUSE_MAP_KIND (nc
) == GOMP_MAP_FIRSTPRIVATE_POINTER
9360 || OMP_CLAUSE_MAP_KIND (nc
) == GOMP_MAP_ATTACH_DETACH
9361 || OMP_CLAUSE_MAP_KIND (nc
) == GOMP_MAP_POINTER
9362 || (OMP_CLAUSE_MAP_KIND (nc
)
9363 == GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION
)
9364 || (OMP_CLAUSE_MAP_KIND (nc
)
9365 == GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION
)
9366 || OMP_CLAUSE_MAP_KIND (nc
) == GOMP_MAP_ALWAYS_POINTER
9367 || OMP_CLAUSE_MAP_KIND (nc
) == GOMP_MAP_TO_PSET
))
9369 grp_last_p
= &OMP_CLAUSE_CHAIN (c
);
9371 tree nc2
= OMP_CLAUSE_CHAIN (nc
);
9373 && OMP_CLAUSE_CODE (nc2
) == OMP_CLAUSE_MAP
9374 && (OMP_CLAUSE_MAP_KIND (nc
)
9375 == GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION
)
9376 && OMP_CLAUSE_MAP_KIND (nc2
) == GOMP_MAP_ATTACH
)
9378 grp_last_p
= &OMP_CLAUSE_CHAIN (nc
);
9380 nc2
= OMP_CLAUSE_CHAIN (nc2
);
9386 case GOMP_MAP_ATTACH
:
9387 case GOMP_MAP_DETACH
:
9388 /* This is a weird artifact of how directives are parsed: bare attach or
9389 detach clauses get a subsequent (meaningless) FIRSTPRIVATE_POINTER or
9390 FIRSTPRIVATE_REFERENCE node. FIXME. */
9392 && OMP_CLAUSE_CODE (nc
) == OMP_CLAUSE_MAP
9393 && (OMP_CLAUSE_MAP_KIND (nc
) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
9394 || OMP_CLAUSE_MAP_KIND (nc
) == GOMP_MAP_FIRSTPRIVATE_POINTER
))
9395 grp_last_p
= &OMP_CLAUSE_CHAIN (c
);
9398 case GOMP_MAP_TO_PSET
:
9399 if (OMP_CLAUSE_CODE (nc
) == OMP_CLAUSE_MAP
9400 && (OMP_CLAUSE_MAP_KIND (nc
) == GOMP_MAP_ATTACH
9401 || OMP_CLAUSE_MAP_KIND (nc
) == GOMP_MAP_DETACH
))
9402 grp_last_p
= &OMP_CLAUSE_CHAIN (c
);
9405 case GOMP_MAP_STRUCT
:
9407 unsigned HOST_WIDE_INT num_mappings
9408 = tree_to_uhwi (OMP_CLAUSE_SIZE (c
));
9409 if (OMP_CLAUSE_MAP_KIND (nc
) == GOMP_MAP_FIRSTPRIVATE_POINTER
9410 || OMP_CLAUSE_MAP_KIND (nc
) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
9411 || OMP_CLAUSE_MAP_KIND (nc
) == GOMP_MAP_ATTACH_DETACH
)
9412 grp_last_p
= &OMP_CLAUSE_CHAIN (*grp_last_p
);
9413 for (unsigned i
= 0; i
< num_mappings
; i
++)
9414 grp_last_p
= &OMP_CLAUSE_CHAIN (*grp_last_p
);
9422 /* Walk through LIST_P, and return a list of groups of mappings found (e.g.
9423 OMP_CLAUSE_MAP with GOMP_MAP_{TO/FROM/TOFROM} followed by one or two
9424 associated GOMP_MAP_POINTER mappings). Return a vector of omp_mapping_group
9425 if we have more than one such group, else return NULL. */
9428 omp_gather_mapping_groups_1 (tree
*list_p
, vec
<omp_mapping_group
> *groups
,
9429 tree gather_sentinel
)
9431 for (tree
*cp
= list_p
;
9432 *cp
&& *cp
!= gather_sentinel
;
9433 cp
= &OMP_CLAUSE_CHAIN (*cp
))
9435 if (OMP_CLAUSE_CODE (*cp
) != OMP_CLAUSE_MAP
)
9438 tree
*grp_last_p
= omp_group_last (cp
);
9439 omp_mapping_group grp
;
9442 grp
.grp_end
= *grp_last_p
;
9443 grp
.mark
= UNVISITED
;
9445 grp
.deleted
= false;
9447 groups
->safe_push (grp
);
9453 static vec
<omp_mapping_group
> *
9454 omp_gather_mapping_groups (tree
*list_p
)
9456 vec
<omp_mapping_group
> *groups
= new vec
<omp_mapping_group
> ();
9458 omp_gather_mapping_groups_1 (list_p
, groups
, NULL_TREE
);
9460 if (groups
->length () > 0)
9469 /* A pointer mapping group GRP may define a block of memory starting at some
9470 base address, and maybe also define a firstprivate pointer or firstprivate
9471 reference that points to that block. The return value is a node containing
9472 the former, and the *FIRSTPRIVATE pointer is set if we have the latter.
9473 If we define several base pointers, i.e. for a GOMP_MAP_STRUCT mapping,
9474 return the number of consecutive chained nodes in CHAINED. */
9477 omp_group_base (omp_mapping_group
*grp
, unsigned int *chained
,
9480 tree node
= *grp
->grp_start
;
9482 *firstprivate
= NULL_TREE
;
9485 switch (OMP_CLAUSE_MAP_KIND (node
))
9489 case GOMP_MAP_TOFROM
:
9490 case GOMP_MAP_ALWAYS_FROM
:
9491 case GOMP_MAP_ALWAYS_TO
:
9492 case GOMP_MAP_ALWAYS_TOFROM
:
9493 case GOMP_MAP_FORCE_FROM
:
9494 case GOMP_MAP_FORCE_TO
:
9495 case GOMP_MAP_FORCE_TOFROM
:
9496 case GOMP_MAP_FORCE_PRESENT
:
9497 case GOMP_MAP_PRESENT_ALLOC
:
9498 case GOMP_MAP_PRESENT_FROM
:
9499 case GOMP_MAP_PRESENT_TO
:
9500 case GOMP_MAP_PRESENT_TOFROM
:
9501 case GOMP_MAP_ALWAYS_PRESENT_FROM
:
9502 case GOMP_MAP_ALWAYS_PRESENT_TO
:
9503 case GOMP_MAP_ALWAYS_PRESENT_TOFROM
:
9504 case GOMP_MAP_ALLOC
:
9505 case GOMP_MAP_RELEASE
:
9506 case GOMP_MAP_DELETE
:
9507 case GOMP_MAP_FORCE_ALLOC
:
9508 case GOMP_MAP_IF_PRESENT
:
9509 if (node
== grp
->grp_end
)
9512 node
= OMP_CLAUSE_CHAIN (node
);
9513 if (node
&& OMP_CLAUSE_MAP_KIND (node
) == GOMP_MAP_TO_PSET
)
9515 if (node
== grp
->grp_end
)
9516 return *grp
->grp_start
;
9517 node
= OMP_CLAUSE_CHAIN (node
);
9520 switch (OMP_CLAUSE_MAP_KIND (node
))
9522 case GOMP_MAP_POINTER
:
9523 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
9524 case GOMP_MAP_FIRSTPRIVATE_REFERENCE
:
9525 case GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION
:
9526 *firstprivate
= OMP_CLAUSE_DECL (node
);
9527 return *grp
->grp_start
;
9529 case GOMP_MAP_ALWAYS_POINTER
:
9530 case GOMP_MAP_ATTACH_DETACH
:
9531 case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION
:
9532 return *grp
->grp_start
;
9535 internal_error ("unexpected mapping node");
9538 internal_error ("unexpected mapping node");
9539 return error_mark_node
;
9541 case GOMP_MAP_TO_PSET
:
9542 gcc_assert (node
!= grp
->grp_end
);
9543 node
= OMP_CLAUSE_CHAIN (node
);
9544 if (OMP_CLAUSE_MAP_KIND (node
) == GOMP_MAP_ATTACH
9545 || OMP_CLAUSE_MAP_KIND (node
) == GOMP_MAP_DETACH
)
9548 internal_error ("unexpected mapping node");
9549 return error_mark_node
;
9551 case GOMP_MAP_ATTACH
:
9552 case GOMP_MAP_DETACH
:
9553 node
= OMP_CLAUSE_CHAIN (node
);
9554 if (!node
|| *grp
->grp_start
== grp
->grp_end
)
9556 if (OMP_CLAUSE_MAP_KIND (node
) == GOMP_MAP_FIRSTPRIVATE_POINTER
9557 || OMP_CLAUSE_MAP_KIND (node
) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
)
9559 /* We're mapping the base pointer itself in a bare attach or detach
9560 node. This is a side effect of how parsing works, and the mapping
9561 will be removed anyway (at least for enter/exit data directives).
9562 We should ignore the mapping here. FIXME. */
9566 internal_error ("unexpected mapping node");
9567 return error_mark_node
;
9569 case GOMP_MAP_STRUCT
:
9571 unsigned HOST_WIDE_INT num_mappings
9572 = tree_to_uhwi (OMP_CLAUSE_SIZE (node
));
9573 node
= OMP_CLAUSE_CHAIN (node
);
9574 if (OMP_CLAUSE_MAP_KIND (node
) == GOMP_MAP_FIRSTPRIVATE_POINTER
9575 || OMP_CLAUSE_MAP_KIND (node
) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
)
9577 *firstprivate
= OMP_CLAUSE_DECL (node
);
9578 node
= OMP_CLAUSE_CHAIN (node
);
9580 *chained
= num_mappings
;
9584 case GOMP_MAP_FORCE_DEVICEPTR
:
9585 case GOMP_MAP_DEVICE_RESIDENT
:
9587 case GOMP_MAP_FIRSTPRIVATE
:
9588 case GOMP_MAP_FIRSTPRIVATE_INT
:
9589 case GOMP_MAP_USE_DEVICE_PTR
:
9590 case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION
:
9593 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
9594 case GOMP_MAP_FIRSTPRIVATE_REFERENCE
:
9595 case GOMP_MAP_POINTER
:
9596 case GOMP_MAP_ALWAYS_POINTER
:
9597 case GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION
:
9598 /* These shouldn't appear by themselves. */
9600 internal_error ("unexpected pointer mapping node");
9601 return error_mark_node
;
9607 return error_mark_node
;
9610 /* Given a vector of omp_mapping_groups, build a hash table so we can look up
9611 nodes by tree_operand_hash_no_se. */
9614 omp_index_mapping_groups_1 (hash_map
<tree_operand_hash_no_se
,
9615 omp_mapping_group
*> *grpmap
,
9616 vec
<omp_mapping_group
> *groups
,
9617 tree reindex_sentinel
)
9619 omp_mapping_group
*grp
;
9621 bool reindexing
= reindex_sentinel
!= NULL_TREE
, above_hwm
= false;
9623 FOR_EACH_VEC_ELT (*groups
, i
, grp
)
9625 if (reindexing
&& *grp
->grp_start
== reindex_sentinel
)
9628 if (reindexing
&& !above_hwm
)
9632 unsigned int chained
;
9633 tree node
= omp_group_base (grp
, &chained
, &fpp
);
9635 if (node
== error_mark_node
|| (!node
&& !fpp
))
9638 for (unsigned j
= 0;
9639 node
&& j
< chained
;
9640 node
= OMP_CLAUSE_CHAIN (node
), j
++)
9642 tree decl
= OMP_CLAUSE_DECL (node
);
9643 /* Sometimes we see zero-offset MEM_REF instead of INDIRECT_REF,
9644 meaning node-hash lookups don't work. This is a workaround for
9645 that, but ideally we should just create the INDIRECT_REF at
9646 source instead. FIXME. */
9647 if (TREE_CODE (decl
) == MEM_REF
9648 && integer_zerop (TREE_OPERAND (decl
, 1)))
9649 decl
= build_fold_indirect_ref (TREE_OPERAND (decl
, 0));
9651 omp_mapping_group
**prev
= grpmap
->get (decl
);
9653 if (prev
&& *prev
== grp
)
9657 /* Mapping the same thing twice is normally diagnosed as an error,
9658 but can happen under some circumstances, e.g. in pr99928-16.c,
9661 #pragma omp target simd reduction(+:a[:3]) \
9662 map(always, tofrom: a[:6])
9665 will result in two "a[0]" mappings (of different sizes). */
9667 grp
->sibling
= (*prev
)->sibling
;
9668 (*prev
)->sibling
= grp
;
9671 grpmap
->put (decl
, grp
);
9677 omp_mapping_group
**prev
= grpmap
->get (fpp
);
9678 if (prev
&& *prev
!= grp
)
9680 grp
->sibling
= (*prev
)->sibling
;
9681 (*prev
)->sibling
= grp
;
9684 grpmap
->put (fpp
, grp
);
9688 static hash_map
<tree_operand_hash_no_se
, omp_mapping_group
*> *
9689 omp_index_mapping_groups (vec
<omp_mapping_group
> *groups
)
9691 hash_map
<tree_operand_hash_no_se
, omp_mapping_group
*> *grpmap
9692 = new hash_map
<tree_operand_hash_no_se
, omp_mapping_group
*>;
9694 omp_index_mapping_groups_1 (grpmap
, groups
, NULL_TREE
);
9699 /* Rebuild group map from partially-processed clause list (during
9700 omp_build_struct_sibling_lists). We have already processed nodes up until
9701 a high-water mark (HWM). This is a bit tricky because the list is being
9702 reordered as it is scanned, but we know:
9704 1. The list after HWM has not been touched yet, so we can reindex it safely.
9706 2. The list before and including HWM has been altered, but remains
9707 well-formed throughout the sibling-list building operation.
9709 so, we can do the reindex operation in two parts, on the processed and
9710 then the unprocessed halves of the list. */
9712 static hash_map
<tree_operand_hash_no_se
, omp_mapping_group
*> *
9713 omp_reindex_mapping_groups (tree
*list_p
,
9714 vec
<omp_mapping_group
> *groups
,
9715 vec
<omp_mapping_group
> *processed_groups
,
9718 hash_map
<tree_operand_hash_no_se
, omp_mapping_group
*> *grpmap
9719 = new hash_map
<tree_operand_hash_no_se
, omp_mapping_group
*>;
9721 processed_groups
->truncate (0);
9723 omp_gather_mapping_groups_1 (list_p
, processed_groups
, sentinel
);
9724 omp_index_mapping_groups_1 (grpmap
, processed_groups
, NULL_TREE
);
9726 omp_index_mapping_groups_1 (grpmap
, groups
, sentinel
);
9731 /* Find the immediately-containing struct for a component ref (etc.)
9735 omp_containing_struct (tree expr
)
9741 /* Note: don't strip NOPs unless we're also stripping off array refs or a
9743 if (TREE_CODE (expr
) != ARRAY_REF
&& TREE_CODE (expr
) != COMPONENT_REF
)
9746 while (TREE_CODE (expr
) == ARRAY_REF
)
9747 expr
= TREE_OPERAND (expr
, 0);
9749 if (TREE_CODE (expr
) == COMPONENT_REF
)
9750 expr
= TREE_OPERAND (expr
, 0);
9755 /* Return TRUE if DECL describes a component that is part of a whole structure
9756 that is mapped elsewhere in GRPMAP. *MAPPED_BY_GROUP is set to the group
9757 that maps that structure, if present. */
9760 omp_mapped_by_containing_struct (hash_map
<tree_operand_hash_no_se
,
9761 omp_mapping_group
*> *grpmap
,
9763 omp_mapping_group
**mapped_by_group
)
9765 tree wsdecl
= NULL_TREE
;
9767 *mapped_by_group
= NULL
;
9771 wsdecl
= omp_containing_struct (decl
);
9774 omp_mapping_group
**wholestruct
= grpmap
->get (wsdecl
);
9776 && TREE_CODE (wsdecl
) == MEM_REF
9777 && integer_zerop (TREE_OPERAND (wsdecl
, 1)))
9779 tree deref
= TREE_OPERAND (wsdecl
, 0);
9780 deref
= build_fold_indirect_ref (deref
);
9781 wholestruct
= grpmap
->get (deref
);
9785 *mapped_by_group
= *wholestruct
;
9794 /* Helper function for omp_tsort_mapping_groups. Returns TRUE on success, or
9798 omp_tsort_mapping_groups_1 (omp_mapping_group
***outlist
,
9799 vec
<omp_mapping_group
> *groups
,
9800 hash_map
<tree_operand_hash_no_se
,
9801 omp_mapping_group
*> *grpmap
,
9802 omp_mapping_group
*grp
)
9804 if (grp
->mark
== PERMANENT
)
9806 if (grp
->mark
== TEMPORARY
)
9808 fprintf (stderr
, "when processing group:\n");
9809 debug_mapping_group (grp
);
9810 internal_error ("base pointer cycle detected");
9813 grp
->mark
= TEMPORARY
;
9815 tree attaches_to
= omp_get_attachment (grp
);
9819 omp_mapping_group
**basep
= grpmap
->get (attaches_to
);
9821 if (basep
&& *basep
!= grp
)
9823 for (omp_mapping_group
*w
= *basep
; w
; w
= w
->sibling
)
9824 if (!omp_tsort_mapping_groups_1 (outlist
, groups
, grpmap
, w
))
9829 tree decl
= OMP_CLAUSE_DECL (*grp
->grp_start
);
9833 tree base
= omp_get_base_pointer (decl
);
9838 omp_mapping_group
**innerp
= grpmap
->get (base
);
9839 omp_mapping_group
*wholestruct
;
9841 /* We should treat whole-structure mappings as if all (pointer, in this
9842 case) members are mapped as individual list items. Check if we have
9843 such a whole-structure mapping, if we don't have an explicit reference
9844 to the pointer member itself. */
9846 && TREE_CODE (base
) == COMPONENT_REF
9847 && omp_mapped_by_containing_struct (grpmap
, base
, &wholestruct
))
9848 innerp
= &wholestruct
;
9850 if (innerp
&& *innerp
!= grp
)
9852 for (omp_mapping_group
*w
= *innerp
; w
; w
= w
->sibling
)
9853 if (!omp_tsort_mapping_groups_1 (outlist
, groups
, grpmap
, w
))
9861 grp
->mark
= PERMANENT
;
9863 /* Emit grp to output list. */
9866 *outlist
= &grp
->next
;
9871 /* Topologically sort GROUPS, so that OMP 5.0-defined base pointers come
9872 before mappings that use those pointers. This is an implementation of the
9873 depth-first search algorithm, described e.g. at:
9875 https://en.wikipedia.org/wiki/Topological_sorting
9878 static omp_mapping_group
*
9879 omp_tsort_mapping_groups (vec
<omp_mapping_group
> *groups
,
9880 hash_map
<tree_operand_hash_no_se
, omp_mapping_group
*>
9883 omp_mapping_group
*grp
, *outlist
= NULL
, **cursor
;
9888 FOR_EACH_VEC_ELT (*groups
, i
, grp
)
9890 if (grp
->mark
!= PERMANENT
)
9891 if (!omp_tsort_mapping_groups_1 (&cursor
, groups
, grpmap
, grp
))
9898 /* Split INLIST into two parts, moving groups corresponding to
9899 ALLOC/RELEASE/DELETE mappings to one list, and other mappings to another.
9900 The former list is then appended to the latter. Each sub-list retains the
9901 order of the original list.
9902 Note that ATTACH nodes are later moved to the end of the list in
9903 gimplify_adjust_omp_clauses, for target regions. */
9905 static omp_mapping_group
*
9906 omp_segregate_mapping_groups (omp_mapping_group
*inlist
)
9908 omp_mapping_group
*ard_groups
= NULL
, *tf_groups
= NULL
;
9909 omp_mapping_group
**ard_tail
= &ard_groups
, **tf_tail
= &tf_groups
;
9911 for (omp_mapping_group
*w
= inlist
; w
;)
9913 tree c
= *w
->grp_start
;
9914 omp_mapping_group
*next
= w
->next
;
9916 gcc_assert (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_MAP
);
9918 switch (OMP_CLAUSE_MAP_KIND (c
))
9920 case GOMP_MAP_ALLOC
:
9921 case GOMP_MAP_RELEASE
:
9922 case GOMP_MAP_DELETE
:
9925 ard_tail
= &w
->next
;
9937 /* Now splice the lists together... */
9938 *tf_tail
= ard_groups
;
9943 /* Given a list LIST_P containing groups of mappings given by GROUPS, reorder
9944 those groups based on the output list of omp_tsort_mapping_groups --
9945 singly-linked, threaded through each element's NEXT pointer starting at
9946 HEAD. Each list element appears exactly once in that linked list.
9948 Each element of GROUPS may correspond to one or several mapping nodes.
9949 Node groups are kept together, and in the reordered list, the positions of
9950 the original groups are reused for the positions of the reordered list.
9951 Hence if we have e.g.
9953 {to ptr ptr} firstprivate {tofrom ptr} ...
9955 first group non-"map" second group
9957 and say the second group contains a base pointer for the first so must be
9958 moved before it, the resulting list will contain:
9960 {tofrom ptr} firstprivate {to ptr ptr} ...
9961 ^ prev. second group ^ prev. first group
9965 omp_reorder_mapping_groups (vec
<omp_mapping_group
> *groups
,
9966 omp_mapping_group
*head
,
9969 omp_mapping_group
*grp
;
9971 unsigned numgroups
= groups
->length ();
9972 auto_vec
<tree
> old_heads (numgroups
);
9973 auto_vec
<tree
*> old_headps (numgroups
);
9974 auto_vec
<tree
> new_heads (numgroups
);
9975 auto_vec
<tree
> old_succs (numgroups
);
9976 bool map_at_start
= (list_p
== (*groups
)[0].grp_start
);
9978 tree
*new_grp_tail
= NULL
;
9980 /* Stash the start & end nodes of each mapping group before we start
9981 modifying the list. */
9982 FOR_EACH_VEC_ELT (*groups
, i
, grp
)
9984 old_headps
.quick_push (grp
->grp_start
);
9985 old_heads
.quick_push (*grp
->grp_start
);
9986 old_succs
.quick_push (OMP_CLAUSE_CHAIN (grp
->grp_end
));
9989 /* And similarly, the heads of the groups in the order we want to rearrange
9991 for (omp_mapping_group
*w
= head
; w
; w
= w
->next
)
9992 new_heads
.quick_push (*w
->grp_start
);
9994 FOR_EACH_VEC_ELT (*groups
, i
, grp
)
9998 if (new_grp_tail
&& old_succs
[i
- 1] == old_heads
[i
])
10000 /* a {b c d} {e f g} h i j (original)
10002 a {k l m} {e f g} h i j (inserted new group on last iter)
10004 a {k l m} {n o p} h i j (this time, chain last group to new one)
10007 *new_grp_tail
= new_heads
[i
];
10009 else if (new_grp_tail
)
10011 /* a {b c d} e {f g h} i j k (original)
10013 a {l m n} e {f g h} i j k (gap after last iter's group)
10015 a {l m n} e {o p q} h i j (chain last group to old successor)
10018 *new_grp_tail
= old_succs
[i
- 1];
10019 *old_headps
[i
] = new_heads
[i
];
10023 /* The first inserted group -- point to new group, and leave end
10029 *grp
->grp_start
= new_heads
[i
];
10032 new_grp_tail
= &OMP_CLAUSE_CHAIN (head
->grp_end
);
10038 *new_grp_tail
= old_succs
[numgroups
- 1];
10040 gcc_assert (!head
);
10042 return map_at_start
? (*groups
)[0].grp_start
: list_p
;
10045 /* DECL is supposed to have lastprivate semantics in the outer contexts
10046 of combined/composite constructs, starting with OCTX.
10047 Add needed lastprivate, shared or map clause if no data sharing or
10048 mapping clause are present. IMPLICIT_P is true if it is an implicit
10049 clause (IV on simd), in which case the lastprivate will not be
10050 copied to some constructs. */
10053 omp_lastprivate_for_combined_outer_constructs (struct gimplify_omp_ctx
*octx
,
10054 tree decl
, bool implicit_p
)
10056 struct gimplify_omp_ctx
*orig_octx
= octx
;
10057 for (; octx
; octx
= octx
->outer_context
)
10059 if ((octx
->region_type
== ORT_COMBINED_PARALLEL
10060 || (octx
->region_type
& ORT_COMBINED_TEAMS
) == ORT_COMBINED_TEAMS
)
10061 && splay_tree_lookup (octx
->variables
,
10062 (splay_tree_key
) decl
) == NULL
)
10064 omp_add_variable (octx
, decl
, GOVD_SHARED
| GOVD_SEEN
);
10067 if ((octx
->region_type
& ORT_TASK
) != 0
10068 && octx
->combined_loop
10069 && splay_tree_lookup (octx
->variables
,
10070 (splay_tree_key
) decl
) == NULL
)
10072 omp_add_variable (octx
, decl
, GOVD_LASTPRIVATE
| GOVD_SEEN
);
10076 && octx
->region_type
== ORT_WORKSHARE
10077 && octx
->combined_loop
10078 && splay_tree_lookup (octx
->variables
,
10079 (splay_tree_key
) decl
) == NULL
10080 && octx
->outer_context
10081 && octx
->outer_context
->region_type
== ORT_COMBINED_PARALLEL
10082 && splay_tree_lookup (octx
->outer_context
->variables
,
10083 (splay_tree_key
) decl
) == NULL
)
10085 octx
= octx
->outer_context
;
10086 omp_add_variable (octx
, decl
, GOVD_LASTPRIVATE
| GOVD_SEEN
);
10089 if ((octx
->region_type
== ORT_WORKSHARE
|| octx
->region_type
== ORT_ACC
)
10090 && octx
->combined_loop
10091 && splay_tree_lookup (octx
->variables
,
10092 (splay_tree_key
) decl
) == NULL
10093 && !omp_check_private (octx
, decl
, false))
10095 omp_add_variable (octx
, decl
, GOVD_LASTPRIVATE
| GOVD_SEEN
);
10098 if (octx
->region_type
== ORT_COMBINED_TARGET
)
10100 splay_tree_node n
= splay_tree_lookup (octx
->variables
,
10101 (splay_tree_key
) decl
);
10104 omp_add_variable (octx
, decl
, GOVD_MAP
| GOVD_SEEN
);
10105 octx
= octx
->outer_context
;
10107 else if (!implicit_p
10108 && (n
->value
& GOVD_FIRSTPRIVATE_IMPLICIT
))
10110 n
->value
&= ~(GOVD_FIRSTPRIVATE
10111 | GOVD_FIRSTPRIVATE_IMPLICIT
10113 omp_add_variable (octx
, decl
, GOVD_MAP
| GOVD_SEEN
);
10114 octx
= octx
->outer_context
;
10119 if (octx
&& (implicit_p
|| octx
!= orig_octx
))
10120 omp_notice_variable (octx
, decl
, true);
10123 /* If we have mappings INNER and OUTER, where INNER is a component access and
10124 OUTER is a mapping of the whole containing struct, check that the mappings
10125 are compatible. We'll be deleting the inner mapping, so we need to make
10126 sure the outer mapping does (at least) the same transfers to/from the device
10127 as the inner mapping. */
10130 omp_check_mapping_compatibility (location_t loc
,
10131 omp_mapping_group
*outer
,
10132 omp_mapping_group
*inner
)
10134 tree first_outer
= *outer
->grp_start
, first_inner
= *inner
->grp_start
;
10136 gcc_assert (OMP_CLAUSE_CODE (first_outer
) == OMP_CLAUSE_MAP
);
10137 gcc_assert (OMP_CLAUSE_CODE (first_inner
) == OMP_CLAUSE_MAP
);
10139 enum gomp_map_kind outer_kind
= OMP_CLAUSE_MAP_KIND (first_outer
);
10140 enum gomp_map_kind inner_kind
= OMP_CLAUSE_MAP_KIND (first_inner
);
10142 if (outer_kind
== inner_kind
)
10145 switch (outer_kind
)
10147 case GOMP_MAP_ALWAYS_TO
:
10148 if (inner_kind
== GOMP_MAP_FORCE_PRESENT
10149 || inner_kind
== GOMP_MAP_ALLOC
10150 || inner_kind
== GOMP_MAP_TO
)
10154 case GOMP_MAP_ALWAYS_FROM
:
10155 if (inner_kind
== GOMP_MAP_FORCE_PRESENT
10156 || inner_kind
== GOMP_MAP_ALLOC
10157 || inner_kind
== GOMP_MAP_FROM
)
10162 case GOMP_MAP_FROM
:
10163 if (inner_kind
== GOMP_MAP_FORCE_PRESENT
10164 || inner_kind
== GOMP_MAP_ALLOC
)
10168 case GOMP_MAP_ALWAYS_TOFROM
:
10169 case GOMP_MAP_TOFROM
:
10170 if (inner_kind
== GOMP_MAP_FORCE_PRESENT
10171 || inner_kind
== GOMP_MAP_ALLOC
10172 || inner_kind
== GOMP_MAP_TO
10173 || inner_kind
== GOMP_MAP_FROM
10174 || inner_kind
== GOMP_MAP_TOFROM
)
10182 error_at (loc
, "data movement for component %qE is not compatible with "
10183 "movement for struct %qE", OMP_CLAUSE_DECL (first_inner
),
10184 OMP_CLAUSE_DECL (first_outer
));
10189 /* Similar to omp_resolve_clause_dependencies, but for OpenACC. The only
10190 clause dependencies we handle for now are struct element mappings and
10191 whole-struct mappings on the same directive, and duplicate clause
10195 oacc_resolve_clause_dependencies (vec
<omp_mapping_group
> *groups
,
10196 hash_map
<tree_operand_hash_no_se
,
10197 omp_mapping_group
*> *grpmap
)
10200 omp_mapping_group
*grp
;
10201 hash_set
<tree_operand_hash
> *seen_components
= NULL
;
10202 hash_set
<tree_operand_hash
> *shown_error
= NULL
;
10204 FOR_EACH_VEC_ELT (*groups
, i
, grp
)
10206 tree grp_end
= grp
->grp_end
;
10207 tree decl
= OMP_CLAUSE_DECL (grp_end
);
10209 gcc_assert (OMP_CLAUSE_CODE (grp_end
) == OMP_CLAUSE_MAP
);
10211 if (DECL_P (grp_end
))
10214 tree c
= OMP_CLAUSE_DECL (*grp
->grp_start
);
10215 while (TREE_CODE (c
) == ARRAY_REF
)
10216 c
= TREE_OPERAND (c
, 0);
10217 if (TREE_CODE (c
) != COMPONENT_REF
)
10219 if (!seen_components
)
10220 seen_components
= new hash_set
<tree_operand_hash
> ();
10222 shown_error
= new hash_set
<tree_operand_hash
> ();
10223 if (seen_components
->contains (c
)
10224 && !shown_error
->contains (c
))
10226 error_at (OMP_CLAUSE_LOCATION (grp_end
),
10227 "%qE appears more than once in map clauses",
10228 OMP_CLAUSE_DECL (grp_end
));
10229 shown_error
->add (c
);
10232 seen_components
->add (c
);
10234 omp_mapping_group
*struct_group
;
10235 if (omp_mapped_by_containing_struct (grpmap
, decl
, &struct_group
)
10236 && *grp
->grp_start
== grp_end
)
10238 omp_check_mapping_compatibility (OMP_CLAUSE_LOCATION (grp_end
),
10239 struct_group
, grp
);
10240 /* Remove the whole of this mapping -- redundant. */
10241 grp
->deleted
= true;
10245 if (seen_components
)
10246 delete seen_components
;
10248 delete shown_error
;
10251 /* Link node NEWNODE so it is pointed to by chain INSERT_AT. NEWNODE's chain
10252 is linked to the previous node pointed to by INSERT_AT. */
10255 omp_siblist_insert_node_after (tree newnode
, tree
*insert_at
)
10257 OMP_CLAUSE_CHAIN (newnode
) = *insert_at
;
10258 *insert_at
= newnode
;
10259 return &OMP_CLAUSE_CHAIN (newnode
);
10262 /* Move NODE (which is currently pointed to by the chain OLD_POS) so it is
10263 pointed to by chain MOVE_AFTER instead. */
10266 omp_siblist_move_node_after (tree node
, tree
*old_pos
, tree
*move_after
)
10268 gcc_assert (node
== *old_pos
);
10269 *old_pos
= OMP_CLAUSE_CHAIN (node
);
10270 OMP_CLAUSE_CHAIN (node
) = *move_after
;
10271 *move_after
= node
;
10274 /* Move nodes from FIRST_PTR (pointed to by previous node's chain) to
10275 LAST_NODE to after MOVE_AFTER chain. Similar to below function, but no
10276 new nodes are prepended to the list before splicing into the new position.
10277 Return the position we should continue scanning the list at, or NULL to
10278 stay where we were. */
10281 omp_siblist_move_nodes_after (tree
*first_ptr
, tree last_node
,
10284 if (first_ptr
== move_after
)
10287 tree tmp
= *first_ptr
;
10288 *first_ptr
= OMP_CLAUSE_CHAIN (last_node
);
10289 OMP_CLAUSE_CHAIN (last_node
) = *move_after
;
10295 /* Concatenate two lists described by [FIRST_NEW, LAST_NEW_TAIL] and
10296 [FIRST_PTR, LAST_NODE], and insert them in the OMP clause list after chain
10297 pointer MOVE_AFTER.
10299 The latter list was previously part of the OMP clause list, and the former
10300 (prepended) part is comprised of new nodes.
10302 We start with a list of nodes starting with a struct mapping node. We
10303 rearrange the list so that new nodes starting from FIRST_NEW and whose last
10304 node's chain is LAST_NEW_TAIL comes directly after MOVE_AFTER, followed by
10305 the group of mapping nodes we are currently processing (from the chain
10306 FIRST_PTR to LAST_NODE). The return value is the pointer to the next chain
10307 we should continue processing from, or NULL to stay where we were.
10309 The transformation (in the case where MOVE_AFTER and FIRST_PTR are
10310 different) is worked through below. Here we are processing LAST_NODE, and
10311 FIRST_PTR points at the preceding mapping clause:
10313 #. mapping node chain
10314 ---------------------------------------------------
10315 A. struct_node [->B]
10317 C. comp_2 [->D (move_after)]
10319 E. attach_3 [->F (first_ptr)]
10320 F. map_to_4 [->G (continue_at)]
10321 G. attach_4 (last_node) [->H]
10324 *last_new_tail = *first_ptr;
10326 I. new_node (first_new) [->F (last_new_tail)]
10328 *first_ptr = OMP_CLAUSE_CHAIN (last_node)
10330 #. mapping node chain
10331 ----------------------------------------------------
10332 A. struct_node [->B]
10334 C. comp_2 [->D (move_after)]
10336 E. attach_3 [->H (first_ptr)]
10337 F. map_to_4 [->G (continue_at)]
10338 G. attach_4 (last_node) [->H]
10341 I. new_node (first_new) [->F (last_new_tail)]
10343 OMP_CLAUSE_CHAIN (last_node) = *move_after;
10345 #. mapping node chain
10346 ---------------------------------------------------
10347 A. struct_node [->B]
10349 C. comp_2 [->D (move_after)]
10351 E. attach_3 [->H (continue_at)]
10353 G. attach_4 (last_node) [->D]
10356 I. new_node (first_new) [->F (last_new_tail)]
10358 *move_after = first_new;
10360 #. mapping node chain
10361 ---------------------------------------------------
10362 A. struct_node [->B]
10364 C. comp_2 [->I (move_after)]
10366 E. attach_3 [->H (continue_at)]
10368 G. attach_4 (last_node) [->D]
10370 I. new_node (first_new) [->F (last_new_tail)]
10374 #. mapping node chain
10375 ---------------------------------------------------
10376 A. struct_node [->B]
10378 C. comp_2 [->I (move_after)]
10379 I. new_node (first_new) [->F (last_new_tail)]
10381 G. attach_4 (last_node) [->D]
10383 E. attach_3 [->H (continue_at)]
10388 omp_siblist_move_concat_nodes_after (tree first_new
, tree
*last_new_tail
,
10389 tree
*first_ptr
, tree last_node
,
10392 tree
*continue_at
= NULL
;
10393 *last_new_tail
= *first_ptr
;
10394 if (first_ptr
== move_after
)
10395 *move_after
= first_new
;
10398 *first_ptr
= OMP_CLAUSE_CHAIN (last_node
);
10399 continue_at
= first_ptr
;
10400 OMP_CLAUSE_CHAIN (last_node
) = *move_after
;
10401 *move_after
= first_new
;
10403 return continue_at
;
10406 /* Mapping struct members causes an additional set of nodes to be created,
10407 starting with GOMP_MAP_STRUCT followed by a number of mappings equal to the
10408 number of members being mapped, in order of ascending position (address or
10411 We scan through the list of mapping clauses, calling this function for each
10412 struct member mapping we find, and build up the list of mappings after the
10413 initial GOMP_MAP_STRUCT node. For pointer members, these will be
10414 newly-created ALLOC nodes. For non-pointer members, the existing mapping is
10415 moved into place in the sorted list.
10424 #pragma (acc|omp directive) copy(struct.a[0:n], struct.b[0:n], struct.c,
10427 GOMP_MAP_STRUCT (4)
10428 [GOMP_MAP_FIRSTPRIVATE_REFERENCE -- for refs to structs]
10429 GOMP_MAP_ALLOC (struct.a)
10430 GOMP_MAP_ALLOC (struct.b)
10431 GOMP_MAP_TO (struct.c)
10432 GOMP_MAP_ALLOC (struct.d)
10435 In the case where we are mapping references to pointers, or in Fortran if
10436 we are mapping an array with a descriptor, additional nodes may be created
10437 after the struct node list also.
10439 The return code is either a pointer to the next node to process (if the
10440 list has been rearranged), else NULL to continue with the next node in the
10444 omp_accumulate_sibling_list (enum omp_region_type region_type
,
10445 enum tree_code code
,
10446 hash_map
<tree_operand_hash
, tree
>
10447 *&struct_map_to_clause
, tree
*grp_start_p
,
10448 tree grp_end
, tree
*inner
)
10450 poly_offset_int coffset
;
10451 poly_int64 cbitpos
;
10452 tree ocd
= OMP_CLAUSE_DECL (grp_end
);
10453 bool openmp
= !(region_type
& ORT_ACC
);
10454 tree
*continue_at
= NULL
;
10456 while (TREE_CODE (ocd
) == ARRAY_REF
)
10457 ocd
= TREE_OPERAND (ocd
, 0);
10459 if (INDIRECT_REF_P (ocd
))
10460 ocd
= TREE_OPERAND (ocd
, 0);
10462 tree base
= extract_base_bit_offset (ocd
, &cbitpos
, &coffset
);
10464 bool ptr
= (OMP_CLAUSE_MAP_KIND (grp_end
) == GOMP_MAP_ALWAYS_POINTER
);
10465 bool attach_detach
= ((OMP_CLAUSE_MAP_KIND (grp_end
)
10466 == GOMP_MAP_ATTACH_DETACH
)
10467 || (OMP_CLAUSE_MAP_KIND (grp_end
)
10468 == GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION
));
10469 bool attach
= (OMP_CLAUSE_MAP_KIND (grp_end
) == GOMP_MAP_ATTACH
10470 || OMP_CLAUSE_MAP_KIND (grp_end
) == GOMP_MAP_DETACH
);
10472 /* FIXME: If we're not mapping the base pointer in some other clause on this
10473 directive, I think we want to create ALLOC/RELEASE here -- i.e. not
10475 if (openmp
&& attach_detach
)
10478 if (!struct_map_to_clause
|| struct_map_to_clause
->get (base
) == NULL
)
10480 tree l
= build_omp_clause (OMP_CLAUSE_LOCATION (grp_end
), OMP_CLAUSE_MAP
);
10481 gomp_map_kind k
= attach
? GOMP_MAP_FORCE_PRESENT
: GOMP_MAP_STRUCT
;
10483 OMP_CLAUSE_SET_MAP_KIND (l
, k
);
10485 OMP_CLAUSE_DECL (l
) = unshare_expr (base
);
10487 OMP_CLAUSE_SIZE (l
)
10488 = (!attach
? size_int (1)
10489 : (DECL_P (OMP_CLAUSE_DECL (l
))
10490 ? DECL_SIZE_UNIT (OMP_CLAUSE_DECL (l
))
10491 : TYPE_SIZE_UNIT (TREE_TYPE (OMP_CLAUSE_DECL (l
)))));
10492 if (struct_map_to_clause
== NULL
)
10493 struct_map_to_clause
= new hash_map
<tree_operand_hash
, tree
>;
10494 struct_map_to_clause
->put (base
, l
);
10496 if (ptr
|| attach_detach
)
10500 = build_omp_struct_comp_nodes (code
, *grp_start_p
, grp_end
,
10502 OMP_CLAUSE_CHAIN (l
) = alloc_node
;
10504 tree
*insert_node_pos
= grp_start_p
;
10508 OMP_CLAUSE_CHAIN (extra_node
) = *insert_node_pos
;
10509 OMP_CLAUSE_CHAIN (alloc_node
) = extra_node
;
10512 OMP_CLAUSE_CHAIN (alloc_node
) = *insert_node_pos
;
10514 *insert_node_pos
= l
;
10518 gcc_assert (*grp_start_p
== grp_end
);
10519 grp_start_p
= omp_siblist_insert_node_after (l
, grp_start_p
);
10522 tree noind
= omp_strip_indirections (base
);
10525 && (region_type
& ORT_TARGET
)
10526 && TREE_CODE (noind
) == COMPONENT_REF
)
10528 /* The base for this component access is a struct component access
10529 itself. Insert a node to be processed on the next iteration of
10530 our caller's loop, which will subsequently be turned into a new,
10531 inner GOMP_MAP_STRUCT mapping.
10533 We need to do this else the non-DECL_P base won't be
10534 rewritten correctly in the offloaded region. */
10535 tree c2
= build_omp_clause (OMP_CLAUSE_LOCATION (grp_end
),
10537 OMP_CLAUSE_SET_MAP_KIND (c2
, GOMP_MAP_FORCE_PRESENT
);
10538 OMP_CLAUSE_DECL (c2
) = unshare_expr (noind
);
10539 OMP_CLAUSE_SIZE (c2
) = TYPE_SIZE_UNIT (TREE_TYPE (noind
));
10544 tree sdecl
= omp_strip_components_and_deref (base
);
10546 if (POINTER_TYPE_P (TREE_TYPE (sdecl
)) && (region_type
& ORT_TARGET
))
10548 tree c2
= build_omp_clause (OMP_CLAUSE_LOCATION (grp_end
),
10551 = (INDIRECT_REF_P (base
)
10552 && ((TREE_CODE (TREE_TYPE (TREE_OPERAND (base
, 0)))
10554 || (INDIRECT_REF_P (TREE_OPERAND (base
, 0))
10555 && (TREE_CODE (TREE_TYPE (TREE_OPERAND
10556 (TREE_OPERAND (base
, 0), 0)))
10557 == REFERENCE_TYPE
))));
10558 enum gomp_map_kind mkind
= base_ref
? GOMP_MAP_FIRSTPRIVATE_REFERENCE
10559 : GOMP_MAP_FIRSTPRIVATE_POINTER
;
10560 OMP_CLAUSE_SET_MAP_KIND (c2
, mkind
);
10561 OMP_CLAUSE_DECL (c2
) = sdecl
;
10562 tree baddr
= build_fold_addr_expr (base
);
10563 baddr
= fold_convert_loc (OMP_CLAUSE_LOCATION (grp_end
),
10564 ptrdiff_type_node
, baddr
);
10565 /* This isn't going to be good enough when we add support for more
10566 complicated lvalue expressions. FIXME. */
10567 if (TREE_CODE (TREE_TYPE (sdecl
)) == REFERENCE_TYPE
10568 && TREE_CODE (TREE_TYPE (TREE_TYPE (sdecl
))) == POINTER_TYPE
)
10569 sdecl
= build_simple_mem_ref (sdecl
);
10570 tree decladdr
= fold_convert_loc (OMP_CLAUSE_LOCATION (grp_end
),
10571 ptrdiff_type_node
, sdecl
);
10572 OMP_CLAUSE_SIZE (c2
)
10573 = fold_build2_loc (OMP_CLAUSE_LOCATION (grp_end
), MINUS_EXPR
,
10574 ptrdiff_type_node
, baddr
, decladdr
);
10575 /* Insert after struct node. */
10576 OMP_CLAUSE_CHAIN (c2
) = OMP_CLAUSE_CHAIN (l
);
10577 OMP_CLAUSE_CHAIN (l
) = c2
;
10582 else if (struct_map_to_clause
)
10584 tree
*osc
= struct_map_to_clause
->get (base
);
10585 tree
*sc
= NULL
, *scp
= NULL
;
10586 sc
= &OMP_CLAUSE_CHAIN (*osc
);
10587 /* The struct mapping might be immediately followed by a
10588 FIRSTPRIVATE_POINTER and/or FIRSTPRIVATE_REFERENCE -- if it's an
10589 indirect access or a reference, or both. (This added node is removed
10590 in omp-low.c after it has been processed there.) */
10592 && (OMP_CLAUSE_MAP_KIND (*sc
) == GOMP_MAP_FIRSTPRIVATE_POINTER
10593 || OMP_CLAUSE_MAP_KIND (*sc
) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
))
10594 sc
= &OMP_CLAUSE_CHAIN (*sc
);
10595 for (; *sc
!= grp_end
; sc
= &OMP_CLAUSE_CHAIN (*sc
))
10596 if ((ptr
|| attach_detach
) && sc
== grp_start_p
)
10598 else if (TREE_CODE (OMP_CLAUSE_DECL (*sc
)) != COMPONENT_REF
10599 && TREE_CODE (OMP_CLAUSE_DECL (*sc
)) != INDIRECT_REF
10600 && TREE_CODE (OMP_CLAUSE_DECL (*sc
)) != ARRAY_REF
)
10604 tree sc_decl
= OMP_CLAUSE_DECL (*sc
);
10605 poly_offset_int offset
;
10608 if (TREE_CODE (sc_decl
) == ARRAY_REF
)
10610 while (TREE_CODE (sc_decl
) == ARRAY_REF
)
10611 sc_decl
= TREE_OPERAND (sc_decl
, 0);
10612 if (TREE_CODE (sc_decl
) != COMPONENT_REF
10613 || TREE_CODE (TREE_TYPE (sc_decl
)) != ARRAY_TYPE
)
10616 else if (INDIRECT_REF_P (sc_decl
)
10617 && TREE_CODE (TREE_OPERAND (sc_decl
, 0)) == COMPONENT_REF
10618 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (sc_decl
, 0)))
10619 == REFERENCE_TYPE
))
10620 sc_decl
= TREE_OPERAND (sc_decl
, 0);
10622 tree base2
= extract_base_bit_offset (sc_decl
, &bitpos
, &offset
);
10623 if (!base2
|| !operand_equal_p (base2
, base
, 0))
10627 if (maybe_lt (coffset
, offset
)
10628 || (known_eq (coffset
, offset
)
10629 && maybe_lt (cbitpos
, bitpos
)))
10631 if (ptr
|| attach_detach
)
10639 OMP_CLAUSE_SIZE (*osc
)
10640 = size_binop (PLUS_EXPR
, OMP_CLAUSE_SIZE (*osc
), size_one_node
);
10641 if (ptr
|| attach_detach
)
10643 tree cl
= NULL_TREE
, extra_node
;
10644 tree alloc_node
= build_omp_struct_comp_nodes (code
, *grp_start_p
,
10645 grp_end
, &extra_node
);
10646 tree
*tail_chain
= NULL
;
10650 grp_end : the last (or only) node in this group.
10651 grp_start_p : pointer to the first node in a pointer mapping group
10652 up to and including GRP_END.
10653 sc : pointer to the chain for the end of the struct component
10655 scp : pointer to the chain for the sorted position at which we
10656 should insert in the middle of the struct component list
10657 (else NULL to insert at end).
10658 alloc_node : the "alloc" node for the structure (pointer-type)
10659 component. We insert at SCP (if present), else SC
10660 (the end of the struct component list).
10661 extra_node : a newly-synthesized node for an additional indirect
10662 pointer mapping or a Fortran pointer set, if needed.
10663 cl : first node to prepend before grp_start_p.
10664 tail_chain : pointer to chain of last prepended node.
10666 The general idea is we move the nodes for this struct mapping
10667 together: the alloc node goes into the sorted list directly after
10668 the struct mapping, and any extra nodes (together with the nodes
10669 mapping arrays pointed to by struct components) get moved after
10670 that list. When SCP is NULL, we insert the nodes at SC, i.e. at
10671 the end of the struct component mapping list. It's important that
10672 the alloc_node comes first in that case because it's part of the
10673 sorted component mapping list (but subsequent nodes are not!). */
10676 omp_siblist_insert_node_after (alloc_node
, scp
);
10678 /* Make [cl,tail_chain] a list of the alloc node (if we haven't
10679 already inserted it) and the extra_node (if it is present). The
10680 list can be empty if we added alloc_node above and there is no
10682 if (scp
&& extra_node
)
10685 tail_chain
= &OMP_CLAUSE_CHAIN (extra_node
);
10687 else if (extra_node
)
10689 OMP_CLAUSE_CHAIN (alloc_node
) = extra_node
;
10691 tail_chain
= &OMP_CLAUSE_CHAIN (extra_node
);
10696 tail_chain
= &OMP_CLAUSE_CHAIN (alloc_node
);
10700 = cl
? omp_siblist_move_concat_nodes_after (cl
, tail_chain
,
10701 grp_start_p
, grp_end
,
10703 : omp_siblist_move_nodes_after (grp_start_p
, grp_end
, sc
);
10705 else if (*sc
!= grp_end
)
10707 gcc_assert (*grp_start_p
== grp_end
);
10709 /* We are moving the current node back to a previous struct node:
10710 the node that used to point to the current node will now point to
10712 continue_at
= grp_start_p
;
10713 /* In the non-pointer case, the mapping clause itself is moved into
10714 the correct position in the struct component list, which in this
10715 case is just SC. */
10716 omp_siblist_move_node_after (*grp_start_p
, grp_start_p
, sc
);
10719 return continue_at
;
10722 /* Scan through GROUPS, and create sorted structure sibling lists without
10726 omp_build_struct_sibling_lists (enum tree_code code
,
10727 enum omp_region_type region_type
,
10728 vec
<omp_mapping_group
> *groups
,
10729 hash_map
<tree_operand_hash_no_se
,
10730 omp_mapping_group
*> **grpmap
,
10734 omp_mapping_group
*grp
;
10735 hash_map
<tree_operand_hash
, tree
> *struct_map_to_clause
= NULL
;
10736 bool success
= true;
10737 tree
*new_next
= NULL
;
10738 tree
*tail
= &OMP_CLAUSE_CHAIN ((*groups
)[groups
->length () - 1].grp_end
);
10739 auto_vec
<omp_mapping_group
> pre_hwm_groups
;
10741 FOR_EACH_VEC_ELT (*groups
, i
, grp
)
10743 tree c
= grp
->grp_end
;
10744 tree decl
= OMP_CLAUSE_DECL (c
);
10745 tree grp_end
= grp
->grp_end
;
10746 tree sentinel
= OMP_CLAUSE_CHAIN (grp_end
);
10749 grp
->grp_start
= new_next
;
10753 tree
*grp_start_p
= grp
->grp_start
;
10758 /* Skip groups we marked for deletion in
10759 oacc_resolve_clause_dependencies. */
10763 if (OMP_CLAUSE_CHAIN (*grp_start_p
)
10764 && OMP_CLAUSE_CHAIN (*grp_start_p
) != grp_end
)
10766 /* Don't process an array descriptor that isn't inside a derived type
10767 as a struct (the GOMP_MAP_POINTER following will have the form
10768 "var.data", but such mappings are handled specially). */
10769 tree grpmid
= OMP_CLAUSE_CHAIN (*grp_start_p
);
10770 if (OMP_CLAUSE_CODE (grpmid
) == OMP_CLAUSE_MAP
10771 && OMP_CLAUSE_MAP_KIND (grpmid
) == GOMP_MAP_TO_PSET
10772 && DECL_P (OMP_CLAUSE_DECL (grpmid
)))
10777 if (TREE_CODE (d
) == ARRAY_REF
)
10779 while (TREE_CODE (d
) == ARRAY_REF
)
10780 d
= TREE_OPERAND (d
, 0);
10781 if (TREE_CODE (d
) == COMPONENT_REF
10782 && TREE_CODE (TREE_TYPE (d
)) == ARRAY_TYPE
)
10786 && INDIRECT_REF_P (decl
)
10787 && TREE_CODE (TREE_OPERAND (decl
, 0)) == COMPONENT_REF
10788 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl
, 0)))
10790 && (OMP_CLAUSE_MAP_KIND (c
)
10791 != GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION
))
10792 decl
= TREE_OPERAND (decl
, 0);
10796 if (TREE_CODE (decl
) != COMPONENT_REF
)
10799 /* If we're mapping the whole struct in another node, skip adding this
10800 node to a sibling list. */
10801 omp_mapping_group
*wholestruct
;
10802 if (omp_mapped_by_containing_struct (*grpmap
, OMP_CLAUSE_DECL (c
),
10805 if (!(region_type
& ORT_ACC
)
10806 && *grp_start_p
== grp_end
)
10807 /* Remove the whole of this mapping -- redundant. */
10808 grp
->deleted
= true;
10813 if (OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_TO_PSET
10814 && OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_ATTACH
10815 && OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_DETACH
10816 && code
!= OACC_UPDATE
10817 && code
!= OMP_TARGET_UPDATE
)
10819 if (error_operand_p (decl
))
10825 tree stype
= TREE_TYPE (decl
);
10826 if (TREE_CODE (stype
) == REFERENCE_TYPE
)
10827 stype
= TREE_TYPE (stype
);
10828 if (TYPE_SIZE_UNIT (stype
) == NULL
10829 || TREE_CODE (TYPE_SIZE_UNIT (stype
)) != INTEGER_CST
)
10831 error_at (OMP_CLAUSE_LOCATION (c
),
10832 "mapping field %qE of variable length "
10833 "structure", OMP_CLAUSE_DECL (c
));
10838 tree inner
= NULL_TREE
;
10841 = omp_accumulate_sibling_list (region_type
, code
,
10842 struct_map_to_clause
, grp_start_p
,
10847 if (new_next
&& *new_next
== NULL_TREE
)
10852 OMP_CLAUSE_CHAIN (inner
) = NULL_TREE
;
10853 omp_mapping_group newgrp
;
10854 newgrp
.grp_start
= new_next
? new_next
: tail
;
10855 newgrp
.grp_end
= inner
;
10856 newgrp
.mark
= UNVISITED
;
10857 newgrp
.sibling
= NULL
;
10858 newgrp
.deleted
= false;
10859 newgrp
.next
= NULL
;
10860 groups
->safe_push (newgrp
);
10862 /* !!! Growing GROUPS might invalidate the pointers in the group
10863 map. Rebuild it here. This is a bit inefficient, but
10864 shouldn't happen very often. */
10867 = omp_reindex_mapping_groups (list_p
, groups
, &pre_hwm_groups
,
10870 tail
= &OMP_CLAUSE_CHAIN (inner
);
10875 /* Delete groups marked for deletion above. At this point the order of the
10876 groups may no longer correspond to the order of the underlying list,
10877 which complicates this a little. First clear out OMP_CLAUSE_DECL for
10878 deleted nodes... */
10880 FOR_EACH_VEC_ELT (*groups
, i
, grp
)
10882 for (tree d
= *grp
->grp_start
;
10883 d
!= OMP_CLAUSE_CHAIN (grp
->grp_end
);
10884 d
= OMP_CLAUSE_CHAIN (d
))
10885 OMP_CLAUSE_DECL (d
) = NULL_TREE
;
10887 /* ...then sweep through the list removing the now-empty nodes. */
10892 if (OMP_CLAUSE_CODE (*tail
) == OMP_CLAUSE_MAP
10893 && OMP_CLAUSE_DECL (*tail
) == NULL_TREE
)
10894 *tail
= OMP_CLAUSE_CHAIN (*tail
);
10896 tail
= &OMP_CLAUSE_CHAIN (*tail
);
10900 if (struct_map_to_clause
)
10901 delete struct_map_to_clause
;
10906 /* Scan the OMP clauses in *LIST_P, installing mappings into a new
10907 and previous omp contexts. */
10910 gimplify_scan_omp_clauses (tree
*list_p
, gimple_seq
*pre_p
,
10911 enum omp_region_type region_type
,
10912 enum tree_code code
)
10914 struct gimplify_omp_ctx
*ctx
, *outer_ctx
;
10916 tree
*orig_list_p
= list_p
;
10917 int handled_depend_iterators
= -1;
10920 ctx
= new_omp_context (region_type
);
10922 outer_ctx
= ctx
->outer_context
;
10923 if (code
== OMP_TARGET
)
10925 if (!lang_GNU_Fortran ())
10926 ctx
->defaultmap
[GDMK_POINTER
] = GOVD_MAP
| GOVD_MAP_0LEN_ARRAY
;
10927 ctx
->defaultmap
[GDMK_SCALAR
] = GOVD_FIRSTPRIVATE
;
10928 ctx
->defaultmap
[GDMK_SCALAR_TARGET
] = (lang_GNU_Fortran ()
10929 ? GOVD_MAP
: GOVD_FIRSTPRIVATE
);
10931 if (!lang_GNU_Fortran ())
10935 case OMP_TARGET_DATA
:
10936 case OMP_TARGET_ENTER_DATA
:
10937 case OMP_TARGET_EXIT_DATA
:
10939 case OACC_HOST_DATA
:
10940 case OACC_PARALLEL
:
10942 ctx
->target_firstprivatize_array_bases
= true;
10947 if (code
== OMP_TARGET
10948 || code
== OMP_TARGET_DATA
10949 || code
== OMP_TARGET_ENTER_DATA
10950 || code
== OMP_TARGET_EXIT_DATA
)
10952 vec
<omp_mapping_group
> *groups
;
10953 groups
= omp_gather_mapping_groups (list_p
);
10956 hash_map
<tree_operand_hash_no_se
, omp_mapping_group
*> *grpmap
;
10957 grpmap
= omp_index_mapping_groups (groups
);
10959 omp_build_struct_sibling_lists (code
, region_type
, groups
, &grpmap
,
10962 omp_mapping_group
*outlist
= NULL
;
10964 /* Topological sorting may fail if we have duplicate nodes, which
10965 we should have detected and shown an error for already. Skip
10966 sorting in that case. */
10973 /* Rebuild now we have struct sibling lists. */
10974 groups
= omp_gather_mapping_groups (list_p
);
10975 grpmap
= omp_index_mapping_groups (groups
);
10977 outlist
= omp_tsort_mapping_groups (groups
, grpmap
);
10978 outlist
= omp_segregate_mapping_groups (outlist
);
10979 list_p
= omp_reorder_mapping_groups (groups
, outlist
, list_p
);
10986 /* OpenMP map clauses with 'present' need to go in front of those
10988 tree present_map_head
= NULL
;
10989 tree
*present_map_tail_p
= &present_map_head
;
10990 tree
*first_map_clause_p
= NULL
;
10992 for (tree
*c_p
= list_p
; *c_p
; )
10995 tree
*next_c_p
= &OMP_CLAUSE_CHAIN (c
);
10997 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_MAP
)
10999 if (!first_map_clause_p
)
11000 first_map_clause_p
= c_p
;
11001 switch (OMP_CLAUSE_MAP_KIND (c
))
11003 case GOMP_MAP_PRESENT_ALLOC
:
11004 case GOMP_MAP_PRESENT_FROM
:
11005 case GOMP_MAP_PRESENT_TO
:
11006 case GOMP_MAP_PRESENT_TOFROM
:
11008 *c_p
= OMP_CLAUSE_CHAIN (c
);
11010 OMP_CLAUSE_CHAIN (c
) = NULL
;
11011 *present_map_tail_p
= c
;
11012 present_map_tail_p
= &OMP_CLAUSE_CHAIN (c
);
11023 if (first_map_clause_p
&& present_map_head
)
11025 tree next
= *first_map_clause_p
;
11026 *first_map_clause_p
= present_map_head
;
11027 *present_map_tail_p
= next
;
11030 else if (region_type
& ORT_ACC
)
11032 vec
<omp_mapping_group
> *groups
;
11033 groups
= omp_gather_mapping_groups (list_p
);
11036 hash_map
<tree_operand_hash_no_se
, omp_mapping_group
*> *grpmap
;
11037 grpmap
= omp_index_mapping_groups (groups
);
11039 oacc_resolve_clause_dependencies (groups
, grpmap
);
11040 omp_build_struct_sibling_lists (code
, region_type
, groups
, &grpmap
,
11048 while ((c
= *list_p
) != NULL
)
11050 bool remove
= false;
11051 bool notice_outer
= true;
11052 const char *check_non_private
= NULL
;
11053 unsigned int flags
;
11056 switch (OMP_CLAUSE_CODE (c
))
11058 case OMP_CLAUSE_PRIVATE
:
11059 flags
= GOVD_PRIVATE
| GOVD_EXPLICIT
;
11060 if (lang_hooks
.decls
.omp_private_outer_ref (OMP_CLAUSE_DECL (c
)))
11062 flags
|= GOVD_PRIVATE_OUTER_REF
;
11063 OMP_CLAUSE_PRIVATE_OUTER_REF (c
) = 1;
11066 notice_outer
= false;
11068 case OMP_CLAUSE_SHARED
:
11069 flags
= GOVD_SHARED
| GOVD_EXPLICIT
;
11071 case OMP_CLAUSE_FIRSTPRIVATE
:
11072 flags
= GOVD_FIRSTPRIVATE
| GOVD_EXPLICIT
;
11073 check_non_private
= "firstprivate";
11074 if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c
))
11076 gcc_assert (code
== OMP_TARGET
);
11077 flags
|= GOVD_FIRSTPRIVATE_IMPLICIT
;
11080 case OMP_CLAUSE_LASTPRIVATE
:
11081 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
))
11084 case OMP_DISTRIBUTE
:
11085 error_at (OMP_CLAUSE_LOCATION (c
),
11086 "conditional %<lastprivate%> clause on "
11087 "%qs construct", "distribute");
11088 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
) = 0;
11091 error_at (OMP_CLAUSE_LOCATION (c
),
11092 "conditional %<lastprivate%> clause on "
11093 "%qs construct", "taskloop");
11094 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
) = 0;
11099 flags
= GOVD_LASTPRIVATE
| GOVD_SEEN
| GOVD_EXPLICIT
;
11100 if (code
!= OMP_LOOP
)
11101 check_non_private
= "lastprivate";
11102 decl
= OMP_CLAUSE_DECL (c
);
11103 if (error_operand_p (decl
))
11105 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
)
11106 && !lang_hooks
.decls
.omp_scalar_p (decl
, true))
11108 error_at (OMP_CLAUSE_LOCATION (c
),
11109 "non-scalar variable %qD in conditional "
11110 "%<lastprivate%> clause", decl
);
11111 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
) = 0;
11113 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
))
11114 flags
|= GOVD_LASTPRIVATE_CONDITIONAL
;
11115 omp_lastprivate_for_combined_outer_constructs (outer_ctx
, decl
,
11118 case OMP_CLAUSE_REDUCTION
:
11119 if (OMP_CLAUSE_REDUCTION_TASK (c
))
11121 if (region_type
== ORT_WORKSHARE
|| code
== OMP_SCOPE
)
11124 nowait
= omp_find_clause (*list_p
,
11125 OMP_CLAUSE_NOWAIT
) != NULL_TREE
;
11127 && (outer_ctx
== NULL
11128 || outer_ctx
->region_type
!= ORT_COMBINED_PARALLEL
))
11130 error_at (OMP_CLAUSE_LOCATION (c
),
11131 "%<task%> reduction modifier on a construct "
11132 "with a %<nowait%> clause");
11133 OMP_CLAUSE_REDUCTION_TASK (c
) = 0;
11136 else if ((region_type
& ORT_PARALLEL
) != ORT_PARALLEL
)
11138 error_at (OMP_CLAUSE_LOCATION (c
),
11139 "invalid %<task%> reduction modifier on construct "
11140 "other than %<parallel%>, %qs, %<sections%> or "
11141 "%<scope%>", lang_GNU_Fortran () ? "do" : "for");
11142 OMP_CLAUSE_REDUCTION_TASK (c
) = 0;
11145 if (OMP_CLAUSE_REDUCTION_INSCAN (c
))
11149 error_at (OMP_CLAUSE_LOCATION (c
),
11150 "%<inscan%> %<reduction%> clause on "
11151 "%qs construct", "sections");
11152 OMP_CLAUSE_REDUCTION_INSCAN (c
) = 0;
11155 error_at (OMP_CLAUSE_LOCATION (c
),
11156 "%<inscan%> %<reduction%> clause on "
11157 "%qs construct", "parallel");
11158 OMP_CLAUSE_REDUCTION_INSCAN (c
) = 0;
11161 error_at (OMP_CLAUSE_LOCATION (c
),
11162 "%<inscan%> %<reduction%> clause on "
11163 "%qs construct", "teams");
11164 OMP_CLAUSE_REDUCTION_INSCAN (c
) = 0;
11167 error_at (OMP_CLAUSE_LOCATION (c
),
11168 "%<inscan%> %<reduction%> clause on "
11169 "%qs construct", "taskloop");
11170 OMP_CLAUSE_REDUCTION_INSCAN (c
) = 0;
11173 error_at (OMP_CLAUSE_LOCATION (c
),
11174 "%<inscan%> %<reduction%> clause on "
11175 "%qs construct", "scope");
11176 OMP_CLAUSE_REDUCTION_INSCAN (c
) = 0;
11182 case OMP_CLAUSE_IN_REDUCTION
:
11183 case OMP_CLAUSE_TASK_REDUCTION
:
11184 flags
= GOVD_REDUCTION
| GOVD_SEEN
| GOVD_EXPLICIT
;
11185 /* OpenACC permits reductions on private variables. */
11186 if (!(region_type
& ORT_ACC
)
11187 /* taskgroup is actually not a worksharing region. */
11188 && code
!= OMP_TASKGROUP
)
11189 check_non_private
= omp_clause_code_name
[OMP_CLAUSE_CODE (c
)];
11190 decl
= OMP_CLAUSE_DECL (c
);
11191 if (TREE_CODE (decl
) == MEM_REF
)
11193 tree type
= TREE_TYPE (decl
);
11194 bool saved_into_ssa
= gimplify_ctxp
->into_ssa
;
11195 gimplify_ctxp
->into_ssa
= false;
11196 if (gimplify_expr (&TYPE_MAX_VALUE (TYPE_DOMAIN (type
)), pre_p
,
11197 NULL
, is_gimple_val
, fb_rvalue
, false)
11200 gimplify_ctxp
->into_ssa
= saved_into_ssa
;
11204 gimplify_ctxp
->into_ssa
= saved_into_ssa
;
11205 tree v
= TYPE_MAX_VALUE (TYPE_DOMAIN (type
));
11208 omp_firstprivatize_variable (ctx
, v
);
11209 omp_notice_variable (ctx
, v
, true);
11211 decl
= TREE_OPERAND (decl
, 0);
11212 if (TREE_CODE (decl
) == POINTER_PLUS_EXPR
)
11214 gimplify_ctxp
->into_ssa
= false;
11215 if (gimplify_expr (&TREE_OPERAND (decl
, 1), pre_p
,
11216 NULL
, is_gimple_val
, fb_rvalue
, false)
11219 gimplify_ctxp
->into_ssa
= saved_into_ssa
;
11223 gimplify_ctxp
->into_ssa
= saved_into_ssa
;
11224 v
= TREE_OPERAND (decl
, 1);
11227 omp_firstprivatize_variable (ctx
, v
);
11228 omp_notice_variable (ctx
, v
, true);
11230 decl
= TREE_OPERAND (decl
, 0);
11232 if (TREE_CODE (decl
) == ADDR_EXPR
11233 || TREE_CODE (decl
) == INDIRECT_REF
)
11234 decl
= TREE_OPERAND (decl
, 0);
11237 case OMP_CLAUSE_LINEAR
:
11238 if (gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c
), pre_p
, NULL
,
11239 is_gimple_val
, fb_rvalue
) == GS_ERROR
)
11246 if (code
== OMP_SIMD
11247 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c
))
11249 struct gimplify_omp_ctx
*octx
= outer_ctx
;
11251 && octx
->region_type
== ORT_WORKSHARE
11252 && octx
->combined_loop
11253 && !octx
->distribute
)
11255 if (octx
->outer_context
11256 && (octx
->outer_context
->region_type
11257 == ORT_COMBINED_PARALLEL
))
11258 octx
= octx
->outer_context
->outer_context
;
11260 octx
= octx
->outer_context
;
11263 && octx
->region_type
== ORT_WORKSHARE
11264 && octx
->combined_loop
11265 && octx
->distribute
)
11267 error_at (OMP_CLAUSE_LOCATION (c
),
11268 "%<linear%> clause for variable other than "
11269 "loop iterator specified on construct "
11270 "combined with %<distribute%>");
11275 /* For combined #pragma omp parallel for simd, need to put
11276 lastprivate and perhaps firstprivate too on the
11277 parallel. Similarly for #pragma omp for simd. */
11278 struct gimplify_omp_ctx
*octx
= outer_ctx
;
11279 bool taskloop_seen
= false;
11283 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c
)
11284 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c
))
11286 decl
= OMP_CLAUSE_DECL (c
);
11287 if (error_operand_p (decl
))
11293 if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c
))
11294 flags
|= GOVD_FIRSTPRIVATE
;
11295 if (!OMP_CLAUSE_LINEAR_NO_COPYOUT (c
))
11296 flags
|= GOVD_LASTPRIVATE
;
11298 && octx
->region_type
== ORT_WORKSHARE
11299 && octx
->combined_loop
)
11301 if (octx
->outer_context
11302 && (octx
->outer_context
->region_type
11303 == ORT_COMBINED_PARALLEL
))
11304 octx
= octx
->outer_context
;
11305 else if (omp_check_private (octx
, decl
, false))
11309 && (octx
->region_type
& ORT_TASK
) != 0
11310 && octx
->combined_loop
)
11311 taskloop_seen
= true;
11313 && octx
->region_type
== ORT_COMBINED_PARALLEL
11314 && ((ctx
->region_type
== ORT_WORKSHARE
11315 && octx
== outer_ctx
)
11317 flags
= GOVD_SEEN
| GOVD_SHARED
;
11319 && ((octx
->region_type
& ORT_COMBINED_TEAMS
)
11320 == ORT_COMBINED_TEAMS
))
11321 flags
= GOVD_SEEN
| GOVD_SHARED
;
11323 && octx
->region_type
== ORT_COMBINED_TARGET
)
11325 if (flags
& GOVD_LASTPRIVATE
)
11326 flags
= GOVD_SEEN
| GOVD_MAP
;
11331 = splay_tree_lookup (octx
->variables
,
11332 (splay_tree_key
) decl
);
11333 if (on
&& (on
->value
& GOVD_DATA_SHARE_CLASS
) != 0)
11338 omp_add_variable (octx
, decl
, flags
);
11339 if (octx
->outer_context
== NULL
)
11341 octx
= octx
->outer_context
;
11346 && (!OMP_CLAUSE_LINEAR_NO_COPYIN (c
)
11347 || !OMP_CLAUSE_LINEAR_NO_COPYOUT (c
)))
11348 omp_notice_variable (octx
, decl
, true);
11350 flags
= GOVD_LINEAR
| GOVD_EXPLICIT
;
11351 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c
)
11352 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c
))
11354 notice_outer
= false;
11355 flags
|= GOVD_LINEAR_LASTPRIVATE_NO_OUTER
;
11359 case OMP_CLAUSE_MAP
:
11360 decl
= OMP_CLAUSE_DECL (c
);
11361 if (error_operand_p (decl
))
11368 if (TREE_CODE (TREE_TYPE (decl
)) != ARRAY_TYPE
)
11371 case OMP_TARGET_DATA
:
11372 case OMP_TARGET_ENTER_DATA
:
11373 case OMP_TARGET_EXIT_DATA
:
11374 case OACC_ENTER_DATA
:
11375 case OACC_EXIT_DATA
:
11376 case OACC_HOST_DATA
:
11377 if (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_FIRSTPRIVATE_POINTER
11378 || (OMP_CLAUSE_MAP_KIND (c
)
11379 == GOMP_MAP_FIRSTPRIVATE_REFERENCE
))
11380 /* For target {,enter ,exit }data only the array slice is
11381 mapped, but not the pointer to it. */
11389 if (DECL_P (decl
) && outer_ctx
&& (region_type
& ORT_ACC
))
11391 struct gimplify_omp_ctx
*octx
;
11392 for (octx
= outer_ctx
; octx
; octx
= octx
->outer_context
)
11394 if (octx
->region_type
!= ORT_ACC_HOST_DATA
)
11397 = splay_tree_lookup (octx
->variables
,
11398 (splay_tree_key
) decl
);
11400 error_at (OMP_CLAUSE_LOCATION (c
), "variable %qE "
11401 "declared in enclosing %<host_data%> region",
11405 if (OMP_CLAUSE_SIZE (c
) == NULL_TREE
)
11406 OMP_CLAUSE_SIZE (c
) = DECL_P (decl
) ? DECL_SIZE_UNIT (decl
)
11407 : TYPE_SIZE_UNIT (TREE_TYPE (decl
));
11408 if (gimplify_expr (&OMP_CLAUSE_SIZE (c
), pre_p
,
11409 NULL
, is_gimple_val
, fb_rvalue
) == GS_ERROR
)
11414 else if ((OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_FIRSTPRIVATE_POINTER
11415 || (OMP_CLAUSE_MAP_KIND (c
)
11416 == GOMP_MAP_FIRSTPRIVATE_REFERENCE
)
11417 || OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ATTACH_DETACH
)
11418 && TREE_CODE (OMP_CLAUSE_SIZE (c
)) != INTEGER_CST
)
11420 OMP_CLAUSE_SIZE (c
)
11421 = get_initialized_tmp_var (OMP_CLAUSE_SIZE (c
), pre_p
, NULL
,
11423 if ((region_type
& ORT_TARGET
) != 0)
11424 omp_add_variable (ctx
, OMP_CLAUSE_SIZE (c
),
11425 GOVD_FIRSTPRIVATE
| GOVD_SEEN
);
11428 if (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_STRUCT
)
11430 tree base
= omp_strip_components_and_deref (decl
);
11435 = splay_tree_lookup (ctx
->variables
,
11436 (splay_tree_key
) decl
);
11439 && (n
->value
& (GOVD_MAP
| GOVD_FIRSTPRIVATE
)) != 0)
11444 flags
= GOVD_MAP
| GOVD_EXPLICIT
;
11450 if (TREE_CODE (decl
) == TARGET_EXPR
)
11452 if (gimplify_expr (&OMP_CLAUSE_DECL (c
), pre_p
, NULL
,
11453 is_gimple_lvalue
, fb_lvalue
)
11457 else if (!DECL_P (decl
))
11459 tree d
= decl
, *pd
;
11460 if (TREE_CODE (d
) == ARRAY_REF
)
11462 while (TREE_CODE (d
) == ARRAY_REF
)
11463 d
= TREE_OPERAND (d
, 0);
11464 if (TREE_CODE (d
) == COMPONENT_REF
11465 && TREE_CODE (TREE_TYPE (d
)) == ARRAY_TYPE
)
11468 pd
= &OMP_CLAUSE_DECL (c
);
11470 && TREE_CODE (decl
) == INDIRECT_REF
11471 && TREE_CODE (TREE_OPERAND (decl
, 0)) == COMPONENT_REF
11472 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl
, 0)))
11474 && (OMP_CLAUSE_MAP_KIND (c
)
11475 != GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION
))
11477 pd
= &TREE_OPERAND (decl
, 0);
11478 decl
= TREE_OPERAND (decl
, 0);
11480 /* An "attach/detach" operation on an update directive should
11481 behave as a GOMP_MAP_ALWAYS_POINTER. Beware that
11482 unlike attach or detach map kinds, GOMP_MAP_ALWAYS_POINTER
11483 depends on the previous mapping. */
11484 if (code
== OACC_UPDATE
11485 && OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ATTACH_DETACH
)
11486 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_ALWAYS_POINTER
);
11488 if (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ATTACH_DETACH
)
11490 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c
)))
11495 gomp_map_kind k
= ((code
== OACC_EXIT_DATA
11496 || code
== OMP_TARGET_EXIT_DATA
)
11497 ? GOMP_MAP_DETACH
: GOMP_MAP_ATTACH
);
11498 OMP_CLAUSE_SET_MAP_KIND (c
, k
);
11504 while (TREE_CODE (cref
) == ARRAY_REF
)
11505 cref
= TREE_OPERAND (cref
, 0);
11507 if (TREE_CODE (cref
) == INDIRECT_REF
)
11508 cref
= TREE_OPERAND (cref
, 0);
11510 if (TREE_CODE (cref
) == COMPONENT_REF
)
11513 while (base
&& !DECL_P (base
))
11515 tree innerbase
= omp_get_base_pointer (base
);
11522 && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c
))
11523 && POINTER_TYPE_P (TREE_TYPE (base
)))
11526 = splay_tree_lookup (ctx
->variables
,
11527 (splay_tree_key
) base
);
11528 n
->value
|= GOVD_SEEN
;
11532 if (code
== OMP_TARGET
&& OMP_CLAUSE_MAP_IN_REDUCTION (c
))
11534 /* Don't gimplify *pd fully at this point, as the base
11535 will need to be adjusted during omp lowering. */
11536 auto_vec
<tree
, 10> expr_stack
;
11538 while (handled_component_p (*p
)
11539 || TREE_CODE (*p
) == INDIRECT_REF
11540 || TREE_CODE (*p
) == ADDR_EXPR
11541 || TREE_CODE (*p
) == MEM_REF
11542 || TREE_CODE (*p
) == NON_LVALUE_EXPR
)
11544 expr_stack
.safe_push (*p
);
11545 p
= &TREE_OPERAND (*p
, 0);
11547 for (int i
= expr_stack
.length () - 1; i
>= 0; i
--)
11549 tree t
= expr_stack
[i
];
11550 if (TREE_CODE (t
) == ARRAY_REF
11551 || TREE_CODE (t
) == ARRAY_RANGE_REF
)
11553 if (TREE_OPERAND (t
, 2) == NULL_TREE
)
11555 tree low
= unshare_expr (array_ref_low_bound (t
));
11556 if (!is_gimple_min_invariant (low
))
11558 TREE_OPERAND (t
, 2) = low
;
11559 if (gimplify_expr (&TREE_OPERAND (t
, 2),
11562 fb_rvalue
) == GS_ERROR
)
11566 else if (gimplify_expr (&TREE_OPERAND (t
, 2), pre_p
,
11567 NULL
, is_gimple_reg
,
11568 fb_rvalue
) == GS_ERROR
)
11570 if (TREE_OPERAND (t
, 3) == NULL_TREE
)
11572 tree elmt_size
= array_ref_element_size (t
);
11573 if (!is_gimple_min_invariant (elmt_size
))
11575 elmt_size
= unshare_expr (elmt_size
);
11577 = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t
,
11580 = size_int (TYPE_ALIGN_UNIT (elmt_type
));
11582 = size_binop (EXACT_DIV_EXPR
, elmt_size
,
11584 TREE_OPERAND (t
, 3) = elmt_size
;
11585 if (gimplify_expr (&TREE_OPERAND (t
, 3),
11588 fb_rvalue
) == GS_ERROR
)
11592 else if (gimplify_expr (&TREE_OPERAND (t
, 3), pre_p
,
11593 NULL
, is_gimple_reg
,
11594 fb_rvalue
) == GS_ERROR
)
11597 else if (TREE_CODE (t
) == COMPONENT_REF
)
11599 if (TREE_OPERAND (t
, 2) == NULL_TREE
)
11601 tree offset
= component_ref_field_offset (t
);
11602 if (!is_gimple_min_invariant (offset
))
11604 offset
= unshare_expr (offset
);
11605 tree field
= TREE_OPERAND (t
, 1);
11607 = size_int (DECL_OFFSET_ALIGN (field
)
11609 offset
= size_binop (EXACT_DIV_EXPR
, offset
,
11611 TREE_OPERAND (t
, 2) = offset
;
11612 if (gimplify_expr (&TREE_OPERAND (t
, 2),
11615 fb_rvalue
) == GS_ERROR
)
11619 else if (gimplify_expr (&TREE_OPERAND (t
, 2), pre_p
,
11620 NULL
, is_gimple_reg
,
11621 fb_rvalue
) == GS_ERROR
)
11625 for (; expr_stack
.length () > 0; )
11627 tree t
= expr_stack
.pop ();
11629 if (TREE_CODE (t
) == ARRAY_REF
11630 || TREE_CODE (t
) == ARRAY_RANGE_REF
)
11632 if (!is_gimple_min_invariant (TREE_OPERAND (t
, 1))
11633 && gimplify_expr (&TREE_OPERAND (t
, 1), pre_p
,
11634 NULL
, is_gimple_val
,
11635 fb_rvalue
) == GS_ERROR
)
11640 else if (gimplify_expr (pd
, pre_p
, NULL
, is_gimple_lvalue
,
11641 fb_lvalue
) == GS_ERROR
)
11648 flags
= GOVD_MAP
| GOVD_EXPLICIT
;
11649 if (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ALWAYS_TO
11650 || OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ALWAYS_TOFROM
)
11651 flags
|= GOVD_MAP_ALWAYS_TO
;
11653 if ((code
== OMP_TARGET
11654 || code
== OMP_TARGET_DATA
11655 || code
== OMP_TARGET_ENTER_DATA
11656 || code
== OMP_TARGET_EXIT_DATA
)
11657 && OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ATTACH_DETACH
)
11659 for (struct gimplify_omp_ctx
*octx
= outer_ctx
; octx
;
11660 octx
= octx
->outer_context
)
11663 = splay_tree_lookup (octx
->variables
,
11664 (splay_tree_key
) OMP_CLAUSE_DECL (c
));
11665 /* If this is contained in an outer OpenMP region as a
11666 firstprivate value, remove the attach/detach. */
11667 if (n
&& (n
->value
& GOVD_FIRSTPRIVATE
))
11669 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_FIRSTPRIVATE_POINTER
);
11674 enum gomp_map_kind map_kind
= (code
== OMP_TARGET_EXIT_DATA
11676 : GOMP_MAP_ATTACH
);
11677 OMP_CLAUSE_SET_MAP_KIND (c
, map_kind
);
11682 case OMP_CLAUSE_AFFINITY
:
11683 gimplify_omp_affinity (list_p
, pre_p
);
11686 case OMP_CLAUSE_DOACROSS
:
11687 if (OMP_CLAUSE_DOACROSS_KIND (c
) == OMP_CLAUSE_DOACROSS_SINK
)
11689 tree deps
= OMP_CLAUSE_DECL (c
);
11690 while (deps
&& TREE_CODE (deps
) == TREE_LIST
)
11692 if (TREE_CODE (TREE_PURPOSE (deps
)) == TRUNC_DIV_EXPR
11693 && DECL_P (TREE_OPERAND (TREE_PURPOSE (deps
), 1)))
11694 gimplify_expr (&TREE_OPERAND (TREE_PURPOSE (deps
), 1),
11695 pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
11696 deps
= TREE_CHAIN (deps
);
11700 gcc_assert (OMP_CLAUSE_DOACROSS_KIND (c
)
11701 == OMP_CLAUSE_DOACROSS_SOURCE
);
11703 case OMP_CLAUSE_DEPEND
:
11704 if (handled_depend_iterators
== -1)
11705 handled_depend_iterators
= gimplify_omp_depend (list_p
, pre_p
);
11706 if (handled_depend_iterators
)
11708 if (handled_depend_iterators
== 2)
11712 if (TREE_CODE (OMP_CLAUSE_DECL (c
)) == COMPOUND_EXPR
)
11714 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c
), 0), pre_p
,
11715 NULL
, is_gimple_val
, fb_rvalue
);
11716 OMP_CLAUSE_DECL (c
) = TREE_OPERAND (OMP_CLAUSE_DECL (c
), 1);
11718 if (error_operand_p (OMP_CLAUSE_DECL (c
)))
11723 if (OMP_CLAUSE_DECL (c
) != null_pointer_node
)
11725 OMP_CLAUSE_DECL (c
) = build_fold_addr_expr (OMP_CLAUSE_DECL (c
));
11726 if (gimplify_expr (&OMP_CLAUSE_DECL (c
), pre_p
, NULL
,
11727 is_gimple_val
, fb_rvalue
) == GS_ERROR
)
11733 if (code
== OMP_TASK
)
11734 ctx
->has_depend
= true;
11737 case OMP_CLAUSE_TO
:
11738 case OMP_CLAUSE_FROM
:
11739 case OMP_CLAUSE__CACHE_
:
11740 decl
= OMP_CLAUSE_DECL (c
);
11741 if (error_operand_p (decl
))
11746 if (OMP_CLAUSE_SIZE (c
) == NULL_TREE
)
11747 OMP_CLAUSE_SIZE (c
) = DECL_P (decl
) ? DECL_SIZE_UNIT (decl
)
11748 : TYPE_SIZE_UNIT (TREE_TYPE (decl
));
11749 if (gimplify_expr (&OMP_CLAUSE_SIZE (c
), pre_p
,
11750 NULL
, is_gimple_val
, fb_rvalue
) == GS_ERROR
)
11755 if (!DECL_P (decl
))
11757 if (gimplify_expr (&OMP_CLAUSE_DECL (c
), pre_p
,
11758 NULL
, is_gimple_lvalue
, fb_lvalue
)
11768 case OMP_CLAUSE_USE_DEVICE_PTR
:
11769 case OMP_CLAUSE_USE_DEVICE_ADDR
:
11770 flags
= GOVD_EXPLICIT
;
11773 case OMP_CLAUSE_HAS_DEVICE_ADDR
:
11774 decl
= OMP_CLAUSE_DECL (c
);
11775 while (TREE_CODE (decl
) == INDIRECT_REF
11776 || TREE_CODE (decl
) == ARRAY_REF
)
11777 decl
= TREE_OPERAND (decl
, 0);
11778 flags
= GOVD_EXPLICIT
;
11781 case OMP_CLAUSE_IS_DEVICE_PTR
:
11782 flags
= GOVD_FIRSTPRIVATE
| GOVD_EXPLICIT
;
11786 decl
= OMP_CLAUSE_DECL (c
);
11788 if (error_operand_p (decl
))
11793 if (DECL_NAME (decl
) == NULL_TREE
&& (flags
& GOVD_SHARED
) == 0)
11795 tree t
= omp_member_access_dummy_var (decl
);
11798 tree v
= DECL_VALUE_EXPR (decl
);
11799 DECL_NAME (decl
) = DECL_NAME (TREE_OPERAND (v
, 1));
11801 omp_notice_variable (outer_ctx
, t
, true);
11804 if (code
== OACC_DATA
11805 && OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_MAP
11806 && OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_FIRSTPRIVATE_POINTER
)
11807 flags
|= GOVD_MAP_0LEN_ARRAY
;
11808 omp_add_variable (ctx
, decl
, flags
);
11809 if ((OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
11810 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_IN_REDUCTION
11811 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_TASK_REDUCTION
)
11812 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
))
11814 struct gimplify_omp_ctx
*pctx
11815 = code
== OMP_TARGET
? outer_ctx
: ctx
;
11817 omp_add_variable (pctx
, OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
),
11818 GOVD_LOCAL
| GOVD_SEEN
);
11820 && OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c
)
11821 && walk_tree (&OMP_CLAUSE_REDUCTION_INIT (c
),
11823 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c
),
11824 NULL
) == NULL_TREE
)
11825 omp_add_variable (pctx
,
11826 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c
),
11827 GOVD_LOCAL
| GOVD_SEEN
);
11828 gimplify_omp_ctxp
= pctx
;
11829 push_gimplify_context ();
11831 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c
) = NULL
;
11832 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c
) = NULL
;
11834 gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c
),
11835 &OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c
));
11836 pop_gimplify_context
11837 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c
)));
11838 push_gimplify_context ();
11839 gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c
),
11840 &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c
));
11841 pop_gimplify_context
11842 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c
)));
11843 OMP_CLAUSE_REDUCTION_INIT (c
) = NULL_TREE
;
11844 OMP_CLAUSE_REDUCTION_MERGE (c
) = NULL_TREE
;
11846 gimplify_omp_ctxp
= outer_ctx
;
11848 else if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
11849 && OMP_CLAUSE_LASTPRIVATE_STMT (c
))
11851 gimplify_omp_ctxp
= ctx
;
11852 push_gimplify_context ();
11853 if (TREE_CODE (OMP_CLAUSE_LASTPRIVATE_STMT (c
)) != BIND_EXPR
)
11855 tree bind
= build3 (BIND_EXPR
, void_type_node
, NULL
,
11857 TREE_SIDE_EFFECTS (bind
) = 1;
11858 BIND_EXPR_BODY (bind
) = OMP_CLAUSE_LASTPRIVATE_STMT (c
);
11859 OMP_CLAUSE_LASTPRIVATE_STMT (c
) = bind
;
11861 gimplify_and_add (OMP_CLAUSE_LASTPRIVATE_STMT (c
),
11862 &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
));
11863 pop_gimplify_context
11864 (gimple_seq_first_stmt (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
)));
11865 OMP_CLAUSE_LASTPRIVATE_STMT (c
) = NULL_TREE
;
11867 gimplify_omp_ctxp
= outer_ctx
;
11869 else if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINEAR
11870 && OMP_CLAUSE_LINEAR_STMT (c
))
11872 gimplify_omp_ctxp
= ctx
;
11873 push_gimplify_context ();
11874 if (TREE_CODE (OMP_CLAUSE_LINEAR_STMT (c
)) != BIND_EXPR
)
11876 tree bind
= build3 (BIND_EXPR
, void_type_node
, NULL
,
11878 TREE_SIDE_EFFECTS (bind
) = 1;
11879 BIND_EXPR_BODY (bind
) = OMP_CLAUSE_LINEAR_STMT (c
);
11880 OMP_CLAUSE_LINEAR_STMT (c
) = bind
;
11882 gimplify_and_add (OMP_CLAUSE_LINEAR_STMT (c
),
11883 &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c
));
11884 pop_gimplify_context
11885 (gimple_seq_first_stmt (OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c
)));
11886 OMP_CLAUSE_LINEAR_STMT (c
) = NULL_TREE
;
11888 gimplify_omp_ctxp
= outer_ctx
;
11894 case OMP_CLAUSE_COPYIN
:
11895 case OMP_CLAUSE_COPYPRIVATE
:
11896 decl
= OMP_CLAUSE_DECL (c
);
11897 if (error_operand_p (decl
))
11902 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_COPYPRIVATE
11904 && !omp_check_private (ctx
, decl
, true))
11907 if (is_global_var (decl
))
11909 if (DECL_THREAD_LOCAL_P (decl
))
11911 else if (DECL_HAS_VALUE_EXPR_P (decl
))
11913 tree value
= get_base_address (DECL_VALUE_EXPR (decl
));
11917 && DECL_THREAD_LOCAL_P (value
))
11922 error_at (OMP_CLAUSE_LOCATION (c
),
11923 "copyprivate variable %qE is not threadprivate"
11924 " or private in outer context", DECL_NAME (decl
));
11927 if ((OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
11928 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_FIRSTPRIVATE
11929 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
)
11931 && ((region_type
& ORT_TASKLOOP
) == ORT_TASKLOOP
11932 || (region_type
== ORT_WORKSHARE
11933 && OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
11934 && (OMP_CLAUSE_REDUCTION_INSCAN (c
)
11935 || code
== OMP_LOOP
)))
11936 && (outer_ctx
->region_type
== ORT_COMBINED_PARALLEL
11937 || (code
== OMP_LOOP
11938 && OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
11939 && ((outer_ctx
->region_type
& ORT_COMBINED_TEAMS
)
11940 == ORT_COMBINED_TEAMS
))))
11943 = splay_tree_lookup (outer_ctx
->variables
,
11944 (splay_tree_key
)decl
);
11945 if (on
== NULL
|| (on
->value
& GOVD_DATA_SHARE_CLASS
) == 0)
11947 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
11948 && TREE_CODE (OMP_CLAUSE_DECL (c
)) == MEM_REF
11949 && (TREE_CODE (TREE_TYPE (decl
)) == POINTER_TYPE
11950 || (TREE_CODE (TREE_TYPE (decl
)) == REFERENCE_TYPE
11951 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl
)))
11952 == POINTER_TYPE
))))
11953 omp_firstprivatize_variable (outer_ctx
, decl
);
11956 omp_add_variable (outer_ctx
, decl
,
11957 GOVD_SEEN
| GOVD_SHARED
);
11958 if (outer_ctx
->outer_context
)
11959 omp_notice_variable (outer_ctx
->outer_context
, decl
,
11965 omp_notice_variable (outer_ctx
, decl
, true);
11966 if (check_non_private
11967 && (region_type
== ORT_WORKSHARE
|| code
== OMP_SCOPE
)
11968 && (OMP_CLAUSE_CODE (c
) != OMP_CLAUSE_REDUCTION
11969 || decl
== OMP_CLAUSE_DECL (c
)
11970 || (TREE_CODE (OMP_CLAUSE_DECL (c
)) == MEM_REF
11971 && (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c
), 0))
11973 || (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c
), 0))
11974 == POINTER_PLUS_EXPR
11975 && (TREE_CODE (TREE_OPERAND (TREE_OPERAND
11976 (OMP_CLAUSE_DECL (c
), 0), 0))
11978 && omp_check_private (ctx
, decl
, false))
11980 error ("%s variable %qE is private in outer context",
11981 check_non_private
, DECL_NAME (decl
));
11986 case OMP_CLAUSE_DETACH
:
11987 flags
= GOVD_FIRSTPRIVATE
| GOVD_SEEN
;
11990 case OMP_CLAUSE_IF
:
11991 if (OMP_CLAUSE_IF_MODIFIER (c
) != ERROR_MARK
11992 && OMP_CLAUSE_IF_MODIFIER (c
) != code
)
11995 for (int i
= 0; i
< 2; i
++)
11996 switch (i
? OMP_CLAUSE_IF_MODIFIER (c
) : code
)
11998 case VOID_CST
: p
[i
] = "cancel"; break;
11999 case OMP_PARALLEL
: p
[i
] = "parallel"; break;
12000 case OMP_SIMD
: p
[i
] = "simd"; break;
12001 case OMP_TASK
: p
[i
] = "task"; break;
12002 case OMP_TASKLOOP
: p
[i
] = "taskloop"; break;
12003 case OMP_TARGET_DATA
: p
[i
] = "target data"; break;
12004 case OMP_TARGET
: p
[i
] = "target"; break;
12005 case OMP_TARGET_UPDATE
: p
[i
] = "target update"; break;
12006 case OMP_TARGET_ENTER_DATA
:
12007 p
[i
] = "target enter data"; break;
12008 case OMP_TARGET_EXIT_DATA
: p
[i
] = "target exit data"; break;
12009 default: gcc_unreachable ();
12011 error_at (OMP_CLAUSE_LOCATION (c
),
12012 "expected %qs %<if%> clause modifier rather than %qs",
12016 /* Fall through. */
12018 case OMP_CLAUSE_FINAL
:
12019 OMP_CLAUSE_OPERAND (c
, 0)
12020 = gimple_boolify (OMP_CLAUSE_OPERAND (c
, 0));
12021 /* Fall through. */
12023 case OMP_CLAUSE_NUM_TEAMS
:
12024 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_NUM_TEAMS
12025 && OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c
)
12026 && !is_gimple_min_invariant (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c
)))
12028 if (error_operand_p (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c
)))
12033 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c
)
12034 = get_initialized_tmp_var (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c
),
12035 pre_p
, NULL
, true);
12037 /* Fall through. */
12039 case OMP_CLAUSE_SCHEDULE
:
12040 case OMP_CLAUSE_NUM_THREADS
:
12041 case OMP_CLAUSE_THREAD_LIMIT
:
12042 case OMP_CLAUSE_DIST_SCHEDULE
:
12043 case OMP_CLAUSE_DEVICE
:
12044 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEVICE
12045 && OMP_CLAUSE_DEVICE_ANCESTOR (c
))
12047 if (code
!= OMP_TARGET
)
12049 error_at (OMP_CLAUSE_LOCATION (c
),
12050 "%<device%> clause with %<ancestor%> is only "
12051 "allowed on %<target%> construct");
12056 tree clauses
= *orig_list_p
;
12057 for (; clauses
; clauses
= OMP_CLAUSE_CHAIN (clauses
))
12058 if (OMP_CLAUSE_CODE (clauses
) != OMP_CLAUSE_DEVICE
12059 && OMP_CLAUSE_CODE (clauses
) != OMP_CLAUSE_FIRSTPRIVATE
12060 && OMP_CLAUSE_CODE (clauses
) != OMP_CLAUSE_PRIVATE
12061 && OMP_CLAUSE_CODE (clauses
) != OMP_CLAUSE_DEFAULTMAP
12062 && OMP_CLAUSE_CODE (clauses
) != OMP_CLAUSE_MAP
12065 error_at (OMP_CLAUSE_LOCATION (c
),
12066 "with %<ancestor%>, only the %<device%>, "
12067 "%<firstprivate%>, %<private%>, %<defaultmap%>, "
12068 "and %<map%> clauses may appear on the "
12074 /* Fall through. */
12076 case OMP_CLAUSE_PRIORITY
:
12077 case OMP_CLAUSE_GRAINSIZE
:
12078 case OMP_CLAUSE_NUM_TASKS
:
12079 case OMP_CLAUSE_FILTER
:
12080 case OMP_CLAUSE_HINT
:
12081 case OMP_CLAUSE_ASYNC
:
12082 case OMP_CLAUSE_WAIT
:
12083 case OMP_CLAUSE_NUM_GANGS
:
12084 case OMP_CLAUSE_NUM_WORKERS
:
12085 case OMP_CLAUSE_VECTOR_LENGTH
:
12086 case OMP_CLAUSE_WORKER
:
12087 case OMP_CLAUSE_VECTOR
:
12088 if (OMP_CLAUSE_OPERAND (c
, 0)
12089 && !is_gimple_min_invariant (OMP_CLAUSE_OPERAND (c
, 0)))
12091 if (error_operand_p (OMP_CLAUSE_OPERAND (c
, 0)))
12096 /* All these clauses care about value, not a particular decl,
12097 so try to force it into a SSA_NAME or fresh temporary. */
12098 OMP_CLAUSE_OPERAND (c
, 0)
12099 = get_initialized_tmp_var (OMP_CLAUSE_OPERAND (c
, 0),
12100 pre_p
, NULL
, true);
12104 case OMP_CLAUSE_GANG
:
12105 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c
, 0), pre_p
, NULL
,
12106 is_gimple_val
, fb_rvalue
) == GS_ERROR
)
12108 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c
, 1), pre_p
, NULL
,
12109 is_gimple_val
, fb_rvalue
) == GS_ERROR
)
12113 case OMP_CLAUSE_NOWAIT
:
12117 case OMP_CLAUSE_ORDERED
:
12118 case OMP_CLAUSE_UNTIED
:
12119 case OMP_CLAUSE_COLLAPSE
:
12120 case OMP_CLAUSE_TILE
:
12121 case OMP_CLAUSE_AUTO
:
12122 case OMP_CLAUSE_SEQ
:
12123 case OMP_CLAUSE_INDEPENDENT
:
12124 case OMP_CLAUSE_MERGEABLE
:
12125 case OMP_CLAUSE_PROC_BIND
:
12126 case OMP_CLAUSE_SAFELEN
:
12127 case OMP_CLAUSE_SIMDLEN
:
12128 case OMP_CLAUSE_NOGROUP
:
12129 case OMP_CLAUSE_THREADS
:
12130 case OMP_CLAUSE_SIMD
:
12131 case OMP_CLAUSE_BIND
:
12132 case OMP_CLAUSE_IF_PRESENT
:
12133 case OMP_CLAUSE_FINALIZE
:
12136 case OMP_CLAUSE_ORDER
:
12137 ctx
->order_concurrent
= true;
12140 case OMP_CLAUSE_DEFAULTMAP
:
12141 enum gimplify_defaultmap_kind gdmkmin
, gdmkmax
;
12142 switch (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
))
12144 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
:
12145 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL
:
12146 gdmkmin
= GDMK_SCALAR
;
12147 gdmkmax
= GDMK_POINTER
;
12149 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR
:
12150 gdmkmin
= GDMK_SCALAR
;
12151 gdmkmax
= GDMK_SCALAR_TARGET
;
12153 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE
:
12154 gdmkmin
= gdmkmax
= GDMK_AGGREGATE
;
12156 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALLOCATABLE
:
12157 gdmkmin
= gdmkmax
= GDMK_ALLOCATABLE
;
12159 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER
:
12160 gdmkmin
= gdmkmax
= GDMK_POINTER
;
12163 gcc_unreachable ();
12165 for (int gdmk
= gdmkmin
; gdmk
<= gdmkmax
; gdmk
++)
12166 switch (OMP_CLAUSE_DEFAULTMAP_BEHAVIOR (c
))
12168 case OMP_CLAUSE_DEFAULTMAP_ALLOC
:
12169 ctx
->defaultmap
[gdmk
] = GOVD_MAP
| GOVD_MAP_ALLOC_ONLY
;
12171 case OMP_CLAUSE_DEFAULTMAP_TO
:
12172 ctx
->defaultmap
[gdmk
] = GOVD_MAP
| GOVD_MAP_TO_ONLY
;
12174 case OMP_CLAUSE_DEFAULTMAP_FROM
:
12175 ctx
->defaultmap
[gdmk
] = GOVD_MAP
| GOVD_MAP_FROM_ONLY
;
12177 case OMP_CLAUSE_DEFAULTMAP_TOFROM
:
12178 ctx
->defaultmap
[gdmk
] = GOVD_MAP
;
12180 case OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE
:
12181 ctx
->defaultmap
[gdmk
] = GOVD_FIRSTPRIVATE
;
12183 case OMP_CLAUSE_DEFAULTMAP_NONE
:
12184 ctx
->defaultmap
[gdmk
] = 0;
12186 case OMP_CLAUSE_DEFAULTMAP_PRESENT
:
12187 ctx
->defaultmap
[gdmk
] = GOVD_MAP
| GOVD_MAP_FORCE_PRESENT
;
12189 case OMP_CLAUSE_DEFAULTMAP_DEFAULT
:
12193 ctx
->defaultmap
[gdmk
] = GOVD_FIRSTPRIVATE
;
12195 case GDMK_SCALAR_TARGET
:
12196 ctx
->defaultmap
[gdmk
] = (lang_GNU_Fortran ()
12197 ? GOVD_MAP
: GOVD_FIRSTPRIVATE
);
12199 case GDMK_AGGREGATE
:
12200 case GDMK_ALLOCATABLE
:
12201 ctx
->defaultmap
[gdmk
] = GOVD_MAP
;
12204 ctx
->defaultmap
[gdmk
] = GOVD_MAP
;
12205 if (!lang_GNU_Fortran ())
12206 ctx
->defaultmap
[gdmk
] |= GOVD_MAP_0LEN_ARRAY
;
12209 gcc_unreachable ();
12213 gcc_unreachable ();
12217 case OMP_CLAUSE_ALIGNED
:
12218 decl
= OMP_CLAUSE_DECL (c
);
12219 if (error_operand_p (decl
))
12224 if (gimplify_expr (&OMP_CLAUSE_ALIGNED_ALIGNMENT (c
), pre_p
, NULL
,
12225 is_gimple_val
, fb_rvalue
) == GS_ERROR
)
12230 if (!is_global_var (decl
)
12231 && TREE_CODE (TREE_TYPE (decl
)) == POINTER_TYPE
)
12232 omp_add_variable (ctx
, decl
, GOVD_ALIGNED
);
12235 case OMP_CLAUSE_NONTEMPORAL
:
12236 decl
= OMP_CLAUSE_DECL (c
);
12237 if (error_operand_p (decl
))
12242 omp_add_variable (ctx
, decl
, GOVD_NONTEMPORAL
);
12245 case OMP_CLAUSE_ALLOCATE
:
12246 decl
= OMP_CLAUSE_DECL (c
);
12247 if (error_operand_p (decl
))
12252 if (gimplify_expr (&OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
), pre_p
, NULL
,
12253 is_gimple_val
, fb_rvalue
) == GS_ERROR
)
12258 else if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
) == NULL_TREE
12259 || (TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
))
12262 else if (code
== OMP_TASKLOOP
12263 || !DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
)))
12264 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
)
12265 = get_initialized_tmp_var (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
),
12266 pre_p
, NULL
, false);
12269 case OMP_CLAUSE_DEFAULT
:
12270 ctx
->default_kind
= OMP_CLAUSE_DEFAULT_KIND (c
);
12273 case OMP_CLAUSE_INCLUSIVE
:
12274 case OMP_CLAUSE_EXCLUSIVE
:
12275 decl
= OMP_CLAUSE_DECL (c
);
12277 splay_tree_node n
= splay_tree_lookup (outer_ctx
->variables
,
12278 (splay_tree_key
) decl
);
12279 if (n
== NULL
|| (n
->value
& GOVD_REDUCTION
) == 0)
12281 error_at (OMP_CLAUSE_LOCATION (c
),
12282 "%qD specified in %qs clause but not in %<inscan%> "
12283 "%<reduction%> clause on the containing construct",
12284 decl
, omp_clause_code_name
[OMP_CLAUSE_CODE (c
)]);
12289 n
->value
|= GOVD_REDUCTION_INSCAN
;
12290 if (outer_ctx
->region_type
== ORT_SIMD
12291 && outer_ctx
->outer_context
12292 && outer_ctx
->outer_context
->region_type
== ORT_WORKSHARE
)
12294 n
= splay_tree_lookup (outer_ctx
->outer_context
->variables
,
12295 (splay_tree_key
) decl
);
12296 if (n
&& (n
->value
& GOVD_REDUCTION
) != 0)
12297 n
->value
|= GOVD_REDUCTION_INSCAN
;
12303 case OMP_CLAUSE_NOHOST
:
12305 gcc_unreachable ();
12308 if (code
== OACC_DATA
12309 && OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_MAP
12310 && (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_FIRSTPRIVATE_POINTER
12311 || OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
))
12314 *list_p
= OMP_CLAUSE_CHAIN (c
);
12316 list_p
= &OMP_CLAUSE_CHAIN (c
);
12319 ctx
->clauses
= *orig_list_p
;
12320 gimplify_omp_ctxp
= ctx
;
12323 /* Return true if DECL is a candidate for shared to firstprivate
12324 optimization. We only consider non-addressable scalars, not
12325 too big, and not references. */
12328 omp_shared_to_firstprivate_optimizable_decl_p (tree decl
)
12330 if (TREE_ADDRESSABLE (decl
))
12332 tree type
= TREE_TYPE (decl
);
12333 if (!is_gimple_reg_type (type
)
12334 || TREE_CODE (type
) == REFERENCE_TYPE
12335 || TREE_ADDRESSABLE (type
))
12337 /* Don't optimize too large decls, as each thread/task will have
12339 HOST_WIDE_INT len
= int_size_in_bytes (type
);
12340 if (len
== -1 || len
> 4 * POINTER_SIZE
/ BITS_PER_UNIT
)
12342 if (omp_privatize_by_reference (decl
))
12347 /* Helper function of omp_find_stores_op and gimplify_adjust_omp_clauses*.
12348 For omp_shared_to_firstprivate_optimizable_decl_p decl mark it as
12349 GOVD_WRITTEN in outer contexts. */
12352 omp_mark_stores (struct gimplify_omp_ctx
*ctx
, tree decl
)
12354 for (; ctx
; ctx
= ctx
->outer_context
)
12356 splay_tree_node n
= splay_tree_lookup (ctx
->variables
,
12357 (splay_tree_key
) decl
);
12360 else if (n
->value
& GOVD_SHARED
)
12362 n
->value
|= GOVD_WRITTEN
;
12365 else if (n
->value
& GOVD_DATA_SHARE_CLASS
)
12370 /* Helper callback for walk_gimple_seq to discover possible stores
12371 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
12372 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
12376 omp_find_stores_op (tree
*tp
, int *walk_subtrees
, void *data
)
12378 struct walk_stmt_info
*wi
= (struct walk_stmt_info
*) data
;
12380 *walk_subtrees
= 0;
12387 if (handled_component_p (op
))
12388 op
= TREE_OPERAND (op
, 0);
12389 else if ((TREE_CODE (op
) == MEM_REF
|| TREE_CODE (op
) == TARGET_MEM_REF
)
12390 && TREE_CODE (TREE_OPERAND (op
, 0)) == ADDR_EXPR
)
12391 op
= TREE_OPERAND (TREE_OPERAND (op
, 0), 0);
12396 if (!DECL_P (op
) || !omp_shared_to_firstprivate_optimizable_decl_p (op
))
12399 omp_mark_stores (gimplify_omp_ctxp
, op
);
12403 /* Helper callback for walk_gimple_seq to discover possible stores
12404 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
12405 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
12409 omp_find_stores_stmt (gimple_stmt_iterator
*gsi_p
,
12410 bool *handled_ops_p
,
12411 struct walk_stmt_info
*wi
)
12413 gimple
*stmt
= gsi_stmt (*gsi_p
);
12414 switch (gimple_code (stmt
))
12416 /* Don't recurse on OpenMP constructs for which
12417 gimplify_adjust_omp_clauses already handled the bodies,
12418 except handle gimple_omp_for_pre_body. */
12419 case GIMPLE_OMP_FOR
:
12420 *handled_ops_p
= true;
12421 if (gimple_omp_for_pre_body (stmt
))
12422 walk_gimple_seq (gimple_omp_for_pre_body (stmt
),
12423 omp_find_stores_stmt
, omp_find_stores_op
, wi
);
12425 case GIMPLE_OMP_PARALLEL
:
12426 case GIMPLE_OMP_TASK
:
12427 case GIMPLE_OMP_SECTIONS
:
12428 case GIMPLE_OMP_SINGLE
:
12429 case GIMPLE_OMP_SCOPE
:
12430 case GIMPLE_OMP_TARGET
:
12431 case GIMPLE_OMP_TEAMS
:
12432 case GIMPLE_OMP_CRITICAL
:
12433 *handled_ops_p
= true;
12441 struct gimplify_adjust_omp_clauses_data
12447 /* For all variables that were not actually used within the context,
12448 remove PRIVATE, SHARED, and FIRSTPRIVATE clauses. */
12451 gimplify_adjust_omp_clauses_1 (splay_tree_node n
, void *data
)
12453 tree
*list_p
= ((struct gimplify_adjust_omp_clauses_data
*) data
)->list_p
;
12455 = ((struct gimplify_adjust_omp_clauses_data
*) data
)->pre_p
;
12456 tree decl
= (tree
) n
->key
;
12457 unsigned flags
= n
->value
;
12458 enum omp_clause_code code
;
12460 bool private_debug
;
12462 if (gimplify_omp_ctxp
->region_type
== ORT_COMBINED_PARALLEL
12463 && (flags
& GOVD_LASTPRIVATE_CONDITIONAL
) != 0)
12464 flags
= GOVD_SHARED
| GOVD_SEEN
| GOVD_WRITTEN
;
12465 if (flags
& (GOVD_EXPLICIT
| GOVD_LOCAL
))
12467 if ((flags
& GOVD_SEEN
) == 0)
12469 if (flags
& GOVD_DEBUG_PRIVATE
)
12471 gcc_assert ((flags
& GOVD_DATA_SHARE_CLASS
) == GOVD_SHARED
);
12472 private_debug
= true;
12474 else if (flags
& GOVD_MAP
)
12475 private_debug
= false;
12478 = lang_hooks
.decls
.omp_private_debug_clause (decl
,
12479 !!(flags
& GOVD_SHARED
));
12481 code
= OMP_CLAUSE_PRIVATE
;
12482 else if (flags
& GOVD_MAP
)
12484 code
= OMP_CLAUSE_MAP
;
12485 if ((gimplify_omp_ctxp
->region_type
& ORT_ACC
) == 0
12486 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl
))))
12488 error ("%<_Atomic%> %qD in implicit %<map%> clause", decl
);
12492 && DECL_IN_CONSTANT_POOL (decl
)
12493 && !lookup_attribute ("omp declare target",
12494 DECL_ATTRIBUTES (decl
)))
12496 tree id
= get_identifier ("omp declare target");
12497 DECL_ATTRIBUTES (decl
)
12498 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (decl
));
12499 varpool_node
*node
= varpool_node::get (decl
);
12502 node
->offloadable
= 1;
12503 if (ENABLE_OFFLOADING
)
12504 g
->have_offload
= true;
12508 else if (flags
& GOVD_SHARED
)
12510 if (is_global_var (decl
))
12512 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
->outer_context
;
12513 while (ctx
!= NULL
)
12516 = splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
12517 if (on
&& (on
->value
& (GOVD_FIRSTPRIVATE
| GOVD_LASTPRIVATE
12518 | GOVD_PRIVATE
| GOVD_REDUCTION
12519 | GOVD_LINEAR
| GOVD_MAP
)) != 0)
12521 ctx
= ctx
->outer_context
;
12526 code
= OMP_CLAUSE_SHARED
;
12527 /* Don't optimize shared into firstprivate for read-only vars
12528 on tasks with depend clause, we shouldn't try to copy them
12529 until the dependencies are satisfied. */
12530 if (gimplify_omp_ctxp
->has_depend
)
12531 flags
|= GOVD_WRITTEN
;
12533 else if (flags
& GOVD_PRIVATE
)
12534 code
= OMP_CLAUSE_PRIVATE
;
12535 else if (flags
& GOVD_FIRSTPRIVATE
)
12537 code
= OMP_CLAUSE_FIRSTPRIVATE
;
12538 if ((gimplify_omp_ctxp
->region_type
& ORT_TARGET
)
12539 && (gimplify_omp_ctxp
->region_type
& ORT_ACC
) == 0
12540 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl
))))
12542 error ("%<_Atomic%> %qD in implicit %<firstprivate%> clause on "
12543 "%<target%> construct", decl
);
12547 else if (flags
& GOVD_LASTPRIVATE
)
12548 code
= OMP_CLAUSE_LASTPRIVATE
;
12549 else if (flags
& (GOVD_ALIGNED
| GOVD_NONTEMPORAL
))
12551 else if (flags
& GOVD_CONDTEMP
)
12553 code
= OMP_CLAUSE__CONDTEMP_
;
12554 gimple_add_tmp_var (decl
);
12557 gcc_unreachable ();
12559 if (((flags
& GOVD_LASTPRIVATE
)
12560 || (code
== OMP_CLAUSE_SHARED
&& (flags
& GOVD_WRITTEN
)))
12561 && omp_shared_to_firstprivate_optimizable_decl_p (decl
))
12562 omp_mark_stores (gimplify_omp_ctxp
->outer_context
, decl
);
12564 tree chain
= *list_p
;
12565 clause
= build_omp_clause (input_location
, code
);
12566 OMP_CLAUSE_DECL (clause
) = decl
;
12567 OMP_CLAUSE_CHAIN (clause
) = chain
;
12569 OMP_CLAUSE_PRIVATE_DEBUG (clause
) = 1;
12570 else if (code
== OMP_CLAUSE_PRIVATE
&& (flags
& GOVD_PRIVATE_OUTER_REF
))
12571 OMP_CLAUSE_PRIVATE_OUTER_REF (clause
) = 1;
12572 else if (code
== OMP_CLAUSE_SHARED
12573 && (flags
& GOVD_WRITTEN
) == 0
12574 && omp_shared_to_firstprivate_optimizable_decl_p (decl
))
12575 OMP_CLAUSE_SHARED_READONLY (clause
) = 1;
12576 else if (code
== OMP_CLAUSE_FIRSTPRIVATE
&& (flags
& GOVD_EXPLICIT
) == 0)
12577 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (clause
) = 1;
12578 else if (code
== OMP_CLAUSE_MAP
&& (flags
& GOVD_MAP_0LEN_ARRAY
) != 0)
12580 tree nc
= build_omp_clause (input_location
, OMP_CLAUSE_MAP
);
12581 OMP_CLAUSE_DECL (nc
) = decl
;
12582 if (TREE_CODE (TREE_TYPE (decl
)) == REFERENCE_TYPE
12583 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl
))) == POINTER_TYPE
)
12584 OMP_CLAUSE_DECL (clause
)
12585 = build_simple_mem_ref_loc (input_location
, decl
);
12586 OMP_CLAUSE_DECL (clause
)
12587 = build2 (MEM_REF
, char_type_node
, OMP_CLAUSE_DECL (clause
),
12588 build_int_cst (build_pointer_type (char_type_node
), 0));
12589 OMP_CLAUSE_SIZE (clause
) = size_zero_node
;
12590 OMP_CLAUSE_SIZE (nc
) = size_zero_node
;
12591 OMP_CLAUSE_SET_MAP_KIND (clause
, GOMP_MAP_ALLOC
);
12592 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (clause
) = 1;
12593 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_FIRSTPRIVATE_POINTER
);
12594 OMP_CLAUSE_CHAIN (nc
) = chain
;
12595 OMP_CLAUSE_CHAIN (clause
) = nc
;
12596 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
12597 gimplify_omp_ctxp
= ctx
->outer_context
;
12598 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (clause
), 0),
12599 pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
12600 gimplify_omp_ctxp
= ctx
;
12602 else if (code
== OMP_CLAUSE_MAP
)
12605 /* Not all combinations of these GOVD_MAP flags are actually valid. */
12606 switch (flags
& (GOVD_MAP_TO_ONLY
12608 | GOVD_MAP_FORCE_PRESENT
12609 | GOVD_MAP_ALLOC_ONLY
12610 | GOVD_MAP_FROM_ONLY
))
12613 kind
= GOMP_MAP_TOFROM
;
12615 case GOVD_MAP_FORCE
:
12616 kind
= GOMP_MAP_TOFROM
| GOMP_MAP_FLAG_FORCE
;
12618 case GOVD_MAP_TO_ONLY
:
12619 kind
= GOMP_MAP_TO
;
12621 case GOVD_MAP_FROM_ONLY
:
12622 kind
= GOMP_MAP_FROM
;
12624 case GOVD_MAP_ALLOC_ONLY
:
12625 kind
= GOMP_MAP_ALLOC
;
12627 case GOVD_MAP_TO_ONLY
| GOVD_MAP_FORCE
:
12628 kind
= GOMP_MAP_TO
| GOMP_MAP_FLAG_FORCE
;
12630 case GOVD_MAP_FORCE_PRESENT
:
12631 kind
= GOMP_MAP_FORCE_PRESENT
;
12633 case GOVD_MAP_FORCE_PRESENT
| GOVD_MAP_ALLOC_ONLY
:
12634 kind
= GOMP_MAP_FORCE_PRESENT
;
12637 gcc_unreachable ();
12639 OMP_CLAUSE_SET_MAP_KIND (clause
, kind
);
12640 /* Setting of the implicit flag for the runtime is currently disabled for
12642 if ((gimplify_omp_ctxp
->region_type
& ORT_ACC
) == 0)
12643 OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (clause
) = 1;
12644 if (DECL_SIZE (decl
)
12645 && TREE_CODE (DECL_SIZE (decl
)) != INTEGER_CST
)
12647 tree decl2
= DECL_VALUE_EXPR (decl
);
12648 gcc_assert (INDIRECT_REF_P (decl2
));
12649 decl2
= TREE_OPERAND (decl2
, 0);
12650 gcc_assert (DECL_P (decl2
));
12651 tree mem
= build_simple_mem_ref (decl2
);
12652 OMP_CLAUSE_DECL (clause
) = mem
;
12653 OMP_CLAUSE_SIZE (clause
) = TYPE_SIZE_UNIT (TREE_TYPE (decl
));
12654 if (gimplify_omp_ctxp
->outer_context
)
12656 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
->outer_context
;
12657 omp_notice_variable (ctx
, decl2
, true);
12658 omp_notice_variable (ctx
, OMP_CLAUSE_SIZE (clause
), true);
12660 tree nc
= build_omp_clause (OMP_CLAUSE_LOCATION (clause
),
12662 OMP_CLAUSE_DECL (nc
) = decl
;
12663 OMP_CLAUSE_SIZE (nc
) = size_zero_node
;
12664 if (gimplify_omp_ctxp
->target_firstprivatize_array_bases
)
12665 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_FIRSTPRIVATE_POINTER
);
12667 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_POINTER
);
12668 OMP_CLAUSE_CHAIN (nc
) = OMP_CLAUSE_CHAIN (clause
);
12669 OMP_CLAUSE_CHAIN (clause
) = nc
;
12671 else if (gimplify_omp_ctxp
->target_firstprivatize_array_bases
12672 && omp_privatize_by_reference (decl
))
12674 OMP_CLAUSE_DECL (clause
) = build_simple_mem_ref (decl
);
12675 OMP_CLAUSE_SIZE (clause
)
12676 = unshare_expr (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl
))));
12677 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
12678 gimplify_omp_ctxp
= ctx
->outer_context
;
12679 gimplify_expr (&OMP_CLAUSE_SIZE (clause
),
12680 pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
12681 gimplify_omp_ctxp
= ctx
;
12682 tree nc
= build_omp_clause (OMP_CLAUSE_LOCATION (clause
),
12684 OMP_CLAUSE_DECL (nc
) = decl
;
12685 OMP_CLAUSE_SIZE (nc
) = size_zero_node
;
12686 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_FIRSTPRIVATE_REFERENCE
);
12687 OMP_CLAUSE_CHAIN (nc
) = OMP_CLAUSE_CHAIN (clause
);
12688 OMP_CLAUSE_CHAIN (clause
) = nc
;
12691 OMP_CLAUSE_SIZE (clause
) = DECL_SIZE_UNIT (decl
);
12693 if (code
== OMP_CLAUSE_FIRSTPRIVATE
&& (flags
& GOVD_LASTPRIVATE
) != 0)
12695 tree nc
= build_omp_clause (input_location
, OMP_CLAUSE_LASTPRIVATE
);
12696 OMP_CLAUSE_DECL (nc
) = decl
;
12697 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (nc
) = 1;
12698 OMP_CLAUSE_CHAIN (nc
) = chain
;
12699 OMP_CLAUSE_CHAIN (clause
) = nc
;
12700 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
12701 gimplify_omp_ctxp
= ctx
->outer_context
;
12702 lang_hooks
.decls
.omp_finish_clause (nc
, pre_p
,
12703 (ctx
->region_type
& ORT_ACC
) != 0);
12704 gimplify_omp_ctxp
= ctx
;
12707 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
12708 gimplify_omp_ctxp
= ctx
->outer_context
;
12709 /* Don't call omp_finish_clause on implicitly added OMP_CLAUSE_PRIVATE
12710 in simd. Those are only added for the local vars inside of simd body
12711 and they don't need to be e.g. default constructible. */
12712 if (code
!= OMP_CLAUSE_PRIVATE
|| ctx
->region_type
!= ORT_SIMD
)
12713 lang_hooks
.decls
.omp_finish_clause (clause
, pre_p
,
12714 (ctx
->region_type
& ORT_ACC
) != 0);
12715 if (gimplify_omp_ctxp
)
12716 for (; clause
!= chain
; clause
= OMP_CLAUSE_CHAIN (clause
))
12717 if (OMP_CLAUSE_CODE (clause
) == OMP_CLAUSE_MAP
12718 && DECL_P (OMP_CLAUSE_SIZE (clause
)))
12719 omp_notice_variable (gimplify_omp_ctxp
, OMP_CLAUSE_SIZE (clause
),
12721 gimplify_omp_ctxp
= ctx
;
12726 gimplify_adjust_omp_clauses (gimple_seq
*pre_p
, gimple_seq body
, tree
*list_p
,
12727 enum tree_code code
)
12729 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
12730 tree
*orig_list_p
= list_p
;
12732 bool has_inscan_reductions
= false;
12736 struct gimplify_omp_ctx
*octx
;
12737 for (octx
= ctx
; octx
; octx
= octx
->outer_context
)
12738 if ((octx
->region_type
& (ORT_PARALLEL
| ORT_TASK
| ORT_TEAMS
)) != 0)
12742 struct walk_stmt_info wi
;
12743 memset (&wi
, 0, sizeof (wi
));
12744 walk_gimple_seq (body
, omp_find_stores_stmt
,
12745 omp_find_stores_op
, &wi
);
12749 if (ctx
->add_safelen1
)
12751 /* If there are VLAs in the body of simd loop, prevent
12753 gcc_assert (ctx
->region_type
== ORT_SIMD
);
12754 c
= build_omp_clause (UNKNOWN_LOCATION
, OMP_CLAUSE_SAFELEN
);
12755 OMP_CLAUSE_SAFELEN_EXPR (c
) = integer_one_node
;
12756 OMP_CLAUSE_CHAIN (c
) = *list_p
;
12758 list_p
= &OMP_CLAUSE_CHAIN (c
);
12761 if (ctx
->region_type
== ORT_WORKSHARE
12762 && ctx
->outer_context
12763 && ctx
->outer_context
->region_type
== ORT_COMBINED_PARALLEL
)
12765 for (c
= ctx
->outer_context
->clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
12766 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
12767 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
))
12769 decl
= OMP_CLAUSE_DECL (c
);
12771 = splay_tree_lookup (ctx
->outer_context
->variables
,
12772 (splay_tree_key
) decl
);
12773 gcc_checking_assert (!splay_tree_lookup (ctx
->variables
,
12774 (splay_tree_key
) decl
));
12775 omp_add_variable (ctx
, decl
, n
->value
);
12776 tree c2
= copy_node (c
);
12777 OMP_CLAUSE_CHAIN (c2
) = *list_p
;
12779 if ((n
->value
& GOVD_FIRSTPRIVATE
) == 0)
12781 c2
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
12782 OMP_CLAUSE_FIRSTPRIVATE
);
12783 OMP_CLAUSE_DECL (c2
) = decl
;
12784 OMP_CLAUSE_CHAIN (c2
) = *list_p
;
12789 tree attach_list
= NULL_TREE
;
12790 tree
*attach_tail
= &attach_list
;
12792 while ((c
= *list_p
) != NULL
)
12795 bool remove
= false;
12796 bool move_attach
= false;
12798 switch (OMP_CLAUSE_CODE (c
))
12800 case OMP_CLAUSE_FIRSTPRIVATE
:
12801 if ((ctx
->region_type
& ORT_TARGET
)
12802 && (ctx
->region_type
& ORT_ACC
) == 0
12803 && TYPE_ATOMIC (strip_array_types
12804 (TREE_TYPE (OMP_CLAUSE_DECL (c
)))))
12806 error_at (OMP_CLAUSE_LOCATION (c
),
12807 "%<_Atomic%> %qD in %<firstprivate%> clause on "
12808 "%<target%> construct", OMP_CLAUSE_DECL (c
));
12812 if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c
))
12814 decl
= OMP_CLAUSE_DECL (c
);
12815 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
12816 if ((n
->value
& GOVD_MAP
) != 0)
12821 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT_TARGET (c
) = 0;
12822 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c
) = 0;
12825 case OMP_CLAUSE_PRIVATE
:
12826 case OMP_CLAUSE_SHARED
:
12827 case OMP_CLAUSE_LINEAR
:
12828 decl
= OMP_CLAUSE_DECL (c
);
12829 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
12830 remove
= !(n
->value
& GOVD_SEEN
);
12831 if ((n
->value
& GOVD_LASTPRIVATE_CONDITIONAL
) != 0
12832 && code
== OMP_PARALLEL
12833 && OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_FIRSTPRIVATE
)
12837 bool shared
= OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_SHARED
;
12838 if ((n
->value
& GOVD_DEBUG_PRIVATE
)
12839 || lang_hooks
.decls
.omp_private_debug_clause (decl
, shared
))
12841 gcc_assert ((n
->value
& GOVD_DEBUG_PRIVATE
) == 0
12842 || ((n
->value
& GOVD_DATA_SHARE_CLASS
)
12844 OMP_CLAUSE_SET_CODE (c
, OMP_CLAUSE_PRIVATE
);
12845 OMP_CLAUSE_PRIVATE_DEBUG (c
) = 1;
12847 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_SHARED
12850 n
->value
|= GOVD_WRITTEN
;
12851 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_SHARED
12852 && (n
->value
& GOVD_WRITTEN
) == 0
12854 && omp_shared_to_firstprivate_optimizable_decl_p (decl
))
12855 OMP_CLAUSE_SHARED_READONLY (c
) = 1;
12856 else if (DECL_P (decl
)
12857 && ((OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_SHARED
12858 && (n
->value
& GOVD_WRITTEN
) != 0)
12859 || (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINEAR
12860 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c
)))
12861 && omp_shared_to_firstprivate_optimizable_decl_p (decl
))
12862 omp_mark_stores (gimplify_omp_ctxp
->outer_context
, decl
);
12865 n
->value
&= ~GOVD_EXPLICIT
;
12868 case OMP_CLAUSE_LASTPRIVATE
:
12869 /* Make sure OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE is set to
12870 accurately reflect the presence of a FIRSTPRIVATE clause. */
12871 decl
= OMP_CLAUSE_DECL (c
);
12872 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
12873 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
)
12874 = (n
->value
& GOVD_FIRSTPRIVATE
) != 0;
12875 if (code
== OMP_DISTRIBUTE
12876 && OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
))
12879 error_at (OMP_CLAUSE_LOCATION (c
),
12880 "same variable used in %<firstprivate%> and "
12881 "%<lastprivate%> clauses on %<distribute%> "
12885 && OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
12887 && omp_shared_to_firstprivate_optimizable_decl_p (decl
))
12888 omp_mark_stores (gimplify_omp_ctxp
->outer_context
, decl
);
12889 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
) && code
== OMP_PARALLEL
)
12893 case OMP_CLAUSE_ALIGNED
:
12894 decl
= OMP_CLAUSE_DECL (c
);
12895 if (!is_global_var (decl
))
12897 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
12898 remove
= n
== NULL
|| !(n
->value
& GOVD_SEEN
);
12899 if (!remove
&& TREE_CODE (TREE_TYPE (decl
)) == POINTER_TYPE
)
12901 struct gimplify_omp_ctx
*octx
;
12903 && (n
->value
& (GOVD_DATA_SHARE_CLASS
12904 & ~GOVD_FIRSTPRIVATE
)))
12907 for (octx
= ctx
->outer_context
; octx
;
12908 octx
= octx
->outer_context
)
12910 n
= splay_tree_lookup (octx
->variables
,
12911 (splay_tree_key
) decl
);
12914 if (n
->value
& GOVD_LOCAL
)
12916 /* We have to avoid assigning a shared variable
12917 to itself when trying to add
12918 __builtin_assume_aligned. */
12919 if (n
->value
& GOVD_SHARED
)
12927 else if (TREE_CODE (TREE_TYPE (decl
)) == ARRAY_TYPE
)
12929 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
12930 if (n
!= NULL
&& (n
->value
& GOVD_DATA_SHARE_CLASS
) != 0)
12935 case OMP_CLAUSE_HAS_DEVICE_ADDR
:
12936 decl
= OMP_CLAUSE_DECL (c
);
12937 while (INDIRECT_REF_P (decl
)
12938 || TREE_CODE (decl
) == ARRAY_REF
)
12939 decl
= TREE_OPERAND (decl
, 0);
12940 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
12941 remove
= n
== NULL
|| !(n
->value
& GOVD_SEEN
);
12944 case OMP_CLAUSE_IS_DEVICE_PTR
:
12945 case OMP_CLAUSE_NONTEMPORAL
:
12946 decl
= OMP_CLAUSE_DECL (c
);
12947 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
12948 remove
= n
== NULL
|| !(n
->value
& GOVD_SEEN
);
12951 case OMP_CLAUSE_MAP
:
12952 switch (OMP_CLAUSE_MAP_KIND (c
))
12954 case GOMP_MAP_PRESENT_ALLOC
:
12955 case GOMP_MAP_PRESENT_TO
:
12956 case GOMP_MAP_PRESENT_FROM
:
12957 case GOMP_MAP_PRESENT_TOFROM
:
12958 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_FORCE_PRESENT
);
12963 if (code
== OMP_TARGET_EXIT_DATA
12964 && OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ALWAYS_POINTER
)
12969 /* If we have a target region, we can push all the attaches to the
12970 end of the list (we may have standalone "attach" operations
12971 synthesized for GOMP_MAP_STRUCT nodes that must be processed after
12972 the attachment point AND the pointed-to block have been mapped).
12973 If we have something else, e.g. "enter data", we need to keep
12974 "attach" nodes together with the previous node they attach to so
12975 that separate "exit data" operations work properly (see
12976 libgomp/target.c). */
12977 if ((ctx
->region_type
& ORT_TARGET
) != 0
12978 && (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ATTACH
12979 || (OMP_CLAUSE_MAP_KIND (c
)
12980 == GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION
)))
12981 move_attach
= true;
12982 decl
= OMP_CLAUSE_DECL (c
);
12983 /* Data clauses associated with reductions must be
12984 compatible with present_or_copy. Warn and adjust the clause
12985 if that is not the case. */
12986 if (ctx
->region_type
== ORT_ACC_PARALLEL
12987 || ctx
->region_type
== ORT_ACC_SERIAL
)
12989 tree t
= DECL_P (decl
) ? decl
: TREE_OPERAND (decl
, 0);
12993 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) t
);
12995 if (n
&& (n
->value
& GOVD_REDUCTION
))
12997 enum gomp_map_kind kind
= OMP_CLAUSE_MAP_KIND (c
);
12999 OMP_CLAUSE_MAP_IN_REDUCTION (c
) = 1;
13000 if ((kind
& GOMP_MAP_TOFROM
) != GOMP_MAP_TOFROM
13001 && kind
!= GOMP_MAP_FORCE_PRESENT
13002 && kind
!= GOMP_MAP_POINTER
)
13004 warning_at (OMP_CLAUSE_LOCATION (c
), 0,
13005 "incompatible data clause with reduction "
13006 "on %qE; promoting to %<present_or_copy%>",
13008 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_TOFROM
);
13012 if (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_STRUCT
13013 && (code
== OMP_TARGET_EXIT_DATA
|| code
== OACC_EXIT_DATA
))
13018 if (!DECL_P (decl
))
13020 if ((ctx
->region_type
& ORT_TARGET
) != 0
13021 && OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_FIRSTPRIVATE_POINTER
)
13023 if (INDIRECT_REF_P (decl
)
13024 && TREE_CODE (TREE_OPERAND (decl
, 0)) == COMPONENT_REF
13025 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl
, 0)))
13026 == REFERENCE_TYPE
))
13027 decl
= TREE_OPERAND (decl
, 0);
13028 if (TREE_CODE (decl
) == COMPONENT_REF
)
13030 while (TREE_CODE (decl
) == COMPONENT_REF
)
13031 decl
= TREE_OPERAND (decl
, 0);
13034 n
= splay_tree_lookup (ctx
->variables
,
13035 (splay_tree_key
) decl
);
13036 if (!(n
->value
& GOVD_SEEN
))
13043 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
13044 if ((ctx
->region_type
& ORT_TARGET
) != 0
13045 && !(n
->value
& GOVD_SEEN
)
13046 && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c
)) == 0
13047 && (!is_global_var (decl
)
13048 || !lookup_attribute ("omp declare target link",
13049 DECL_ATTRIBUTES (decl
))))
13052 /* For struct element mapping, if struct is never referenced
13053 in target block and none of the mapping has always modifier,
13054 remove all the struct element mappings, which immediately
13055 follow the GOMP_MAP_STRUCT map clause. */
13056 if (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_STRUCT
)
13058 HOST_WIDE_INT cnt
= tree_to_shwi (OMP_CLAUSE_SIZE (c
));
13060 OMP_CLAUSE_CHAIN (c
)
13061 = OMP_CLAUSE_CHAIN (OMP_CLAUSE_CHAIN (c
));
13064 else if (DECL_SIZE (decl
)
13065 && TREE_CODE (DECL_SIZE (decl
)) != INTEGER_CST
13066 && OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_POINTER
13067 && OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_FIRSTPRIVATE_POINTER
13068 && (OMP_CLAUSE_MAP_KIND (c
)
13069 != GOMP_MAP_FIRSTPRIVATE_REFERENCE
))
13071 /* For GOMP_MAP_FORCE_DEVICEPTR, we'll never enter here, because
13072 for these, TREE_CODE (DECL_SIZE (decl)) will always be
13074 gcc_assert (OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_FORCE_DEVICEPTR
);
13076 tree decl2
= DECL_VALUE_EXPR (decl
);
13077 gcc_assert (INDIRECT_REF_P (decl2
));
13078 decl2
= TREE_OPERAND (decl2
, 0);
13079 gcc_assert (DECL_P (decl2
));
13080 tree mem
= build_simple_mem_ref (decl2
);
13081 OMP_CLAUSE_DECL (c
) = mem
;
13082 OMP_CLAUSE_SIZE (c
) = TYPE_SIZE_UNIT (TREE_TYPE (decl
));
13083 if (ctx
->outer_context
)
13085 omp_notice_variable (ctx
->outer_context
, decl2
, true);
13086 omp_notice_variable (ctx
->outer_context
,
13087 OMP_CLAUSE_SIZE (c
), true);
13089 if (((ctx
->region_type
& ORT_TARGET
) != 0
13090 || !ctx
->target_firstprivatize_array_bases
)
13091 && ((n
->value
& GOVD_SEEN
) == 0
13092 || (n
->value
& (GOVD_PRIVATE
| GOVD_FIRSTPRIVATE
)) == 0))
13094 tree nc
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
13096 OMP_CLAUSE_DECL (nc
) = decl
;
13097 OMP_CLAUSE_SIZE (nc
) = size_zero_node
;
13098 if (ctx
->target_firstprivatize_array_bases
)
13099 OMP_CLAUSE_SET_MAP_KIND (nc
,
13100 GOMP_MAP_FIRSTPRIVATE_POINTER
);
13102 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_POINTER
);
13103 OMP_CLAUSE_CHAIN (nc
) = OMP_CLAUSE_CHAIN (c
);
13104 OMP_CLAUSE_CHAIN (c
) = nc
;
13110 if (OMP_CLAUSE_SIZE (c
) == NULL_TREE
)
13111 OMP_CLAUSE_SIZE (c
) = DECL_SIZE_UNIT (decl
);
13112 gcc_assert ((n
->value
& GOVD_SEEN
) == 0
13113 || ((n
->value
& (GOVD_PRIVATE
| GOVD_FIRSTPRIVATE
))
13118 case OMP_CLAUSE_TO
:
13119 case OMP_CLAUSE_FROM
:
13120 case OMP_CLAUSE__CACHE_
:
13121 decl
= OMP_CLAUSE_DECL (c
);
13122 if (!DECL_P (decl
))
13124 if (DECL_SIZE (decl
)
13125 && TREE_CODE (DECL_SIZE (decl
)) != INTEGER_CST
)
13127 tree decl2
= DECL_VALUE_EXPR (decl
);
13128 gcc_assert (INDIRECT_REF_P (decl2
));
13129 decl2
= TREE_OPERAND (decl2
, 0);
13130 gcc_assert (DECL_P (decl2
));
13131 tree mem
= build_simple_mem_ref (decl2
);
13132 OMP_CLAUSE_DECL (c
) = mem
;
13133 OMP_CLAUSE_SIZE (c
) = TYPE_SIZE_UNIT (TREE_TYPE (decl
));
13134 if (ctx
->outer_context
)
13136 omp_notice_variable (ctx
->outer_context
, decl2
, true);
13137 omp_notice_variable (ctx
->outer_context
,
13138 OMP_CLAUSE_SIZE (c
), true);
13141 else if (OMP_CLAUSE_SIZE (c
) == NULL_TREE
)
13142 OMP_CLAUSE_SIZE (c
) = DECL_SIZE_UNIT (decl
);
13145 case OMP_CLAUSE_REDUCTION
:
13146 if (OMP_CLAUSE_REDUCTION_INSCAN (c
))
13148 decl
= OMP_CLAUSE_DECL (c
);
13149 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
13150 if ((n
->value
& GOVD_REDUCTION_INSCAN
) == 0)
13153 error_at (OMP_CLAUSE_LOCATION (c
),
13154 "%qD specified in %<inscan%> %<reduction%> clause "
13155 "but not in %<scan%> directive clause", decl
);
13158 has_inscan_reductions
= true;
13161 case OMP_CLAUSE_IN_REDUCTION
:
13162 case OMP_CLAUSE_TASK_REDUCTION
:
13163 decl
= OMP_CLAUSE_DECL (c
);
13164 /* OpenACC reductions need a present_or_copy data clause.
13165 Add one if necessary. Emit error when the reduction is private. */
13166 if (ctx
->region_type
== ORT_ACC_PARALLEL
13167 || ctx
->region_type
== ORT_ACC_SERIAL
)
13169 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
13170 if (n
->value
& (GOVD_PRIVATE
| GOVD_FIRSTPRIVATE
))
13173 error_at (OMP_CLAUSE_LOCATION (c
), "invalid private "
13174 "reduction on %qE", DECL_NAME (decl
));
13176 else if ((n
->value
& GOVD_MAP
) == 0)
13178 tree next
= OMP_CLAUSE_CHAIN (c
);
13179 tree nc
= build_omp_clause (UNKNOWN_LOCATION
, OMP_CLAUSE_MAP
);
13180 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_TOFROM
);
13181 OMP_CLAUSE_DECL (nc
) = decl
;
13182 OMP_CLAUSE_CHAIN (c
) = nc
;
13183 lang_hooks
.decls
.omp_finish_clause (nc
, pre_p
,
13188 OMP_CLAUSE_MAP_IN_REDUCTION (nc
) = 1;
13189 if (OMP_CLAUSE_CHAIN (nc
) == NULL
)
13191 nc
= OMP_CLAUSE_CHAIN (nc
);
13193 OMP_CLAUSE_CHAIN (nc
) = next
;
13194 n
->value
|= GOVD_MAP
;
13198 && omp_shared_to_firstprivate_optimizable_decl_p (decl
))
13199 omp_mark_stores (gimplify_omp_ctxp
->outer_context
, decl
);
13202 case OMP_CLAUSE_ALLOCATE
:
13203 decl
= OMP_CLAUSE_DECL (c
);
13204 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
13205 if (n
!= NULL
&& !(n
->value
& GOVD_SEEN
))
13207 if ((n
->value
& (GOVD_PRIVATE
| GOVD_FIRSTPRIVATE
| GOVD_LINEAR
))
13209 && (n
->value
& (GOVD_REDUCTION
| GOVD_LASTPRIVATE
)) == 0)
13213 && OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
)
13214 && TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
)) != INTEGER_CST
13215 && ((ctx
->region_type
& (ORT_PARALLEL
| ORT_TARGET
)) != 0
13216 || (ctx
->region_type
& ORT_TASKLOOP
) == ORT_TASK
13217 || (ctx
->region_type
& ORT_HOST_TEAMS
) == ORT_HOST_TEAMS
))
13219 tree allocator
= OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
);
13220 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) allocator
);
13223 enum omp_clause_default_kind default_kind
13224 = ctx
->default_kind
;
13225 ctx
->default_kind
= OMP_CLAUSE_DEFAULT_FIRSTPRIVATE
;
13226 omp_notice_variable (ctx
, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
),
13228 ctx
->default_kind
= default_kind
;
13231 omp_notice_variable (ctx
, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
),
13236 case OMP_CLAUSE_COPYIN
:
13237 case OMP_CLAUSE_COPYPRIVATE
:
13238 case OMP_CLAUSE_IF
:
13239 case OMP_CLAUSE_NUM_THREADS
:
13240 case OMP_CLAUSE_NUM_TEAMS
:
13241 case OMP_CLAUSE_THREAD_LIMIT
:
13242 case OMP_CLAUSE_DIST_SCHEDULE
:
13243 case OMP_CLAUSE_DEVICE
:
13244 case OMP_CLAUSE_SCHEDULE
:
13245 case OMP_CLAUSE_NOWAIT
:
13246 case OMP_CLAUSE_ORDERED
:
13247 case OMP_CLAUSE_DEFAULT
:
13248 case OMP_CLAUSE_UNTIED
:
13249 case OMP_CLAUSE_COLLAPSE
:
13250 case OMP_CLAUSE_FINAL
:
13251 case OMP_CLAUSE_MERGEABLE
:
13252 case OMP_CLAUSE_PROC_BIND
:
13253 case OMP_CLAUSE_SAFELEN
:
13254 case OMP_CLAUSE_SIMDLEN
:
13255 case OMP_CLAUSE_DEPEND
:
13256 case OMP_CLAUSE_DOACROSS
:
13257 case OMP_CLAUSE_PRIORITY
:
13258 case OMP_CLAUSE_GRAINSIZE
:
13259 case OMP_CLAUSE_NUM_TASKS
:
13260 case OMP_CLAUSE_NOGROUP
:
13261 case OMP_CLAUSE_THREADS
:
13262 case OMP_CLAUSE_SIMD
:
13263 case OMP_CLAUSE_FILTER
:
13264 case OMP_CLAUSE_HINT
:
13265 case OMP_CLAUSE_DEFAULTMAP
:
13266 case OMP_CLAUSE_ORDER
:
13267 case OMP_CLAUSE_BIND
:
13268 case OMP_CLAUSE_DETACH
:
13269 case OMP_CLAUSE_USE_DEVICE_PTR
:
13270 case OMP_CLAUSE_USE_DEVICE_ADDR
:
13271 case OMP_CLAUSE_ASYNC
:
13272 case OMP_CLAUSE_WAIT
:
13273 case OMP_CLAUSE_INDEPENDENT
:
13274 case OMP_CLAUSE_NUM_GANGS
:
13275 case OMP_CLAUSE_NUM_WORKERS
:
13276 case OMP_CLAUSE_VECTOR_LENGTH
:
13277 case OMP_CLAUSE_GANG
:
13278 case OMP_CLAUSE_WORKER
:
13279 case OMP_CLAUSE_VECTOR
:
13280 case OMP_CLAUSE_AUTO
:
13281 case OMP_CLAUSE_SEQ
:
13282 case OMP_CLAUSE_TILE
:
13283 case OMP_CLAUSE_IF_PRESENT
:
13284 case OMP_CLAUSE_FINALIZE
:
13285 case OMP_CLAUSE_INCLUSIVE
:
13286 case OMP_CLAUSE_EXCLUSIVE
:
13289 case OMP_CLAUSE_NOHOST
:
13291 gcc_unreachable ();
13295 *list_p
= OMP_CLAUSE_CHAIN (c
);
13296 else if (move_attach
)
13298 /* Remove attach node from here, separate out into its own list. */
13300 *list_p
= OMP_CLAUSE_CHAIN (c
);
13301 OMP_CLAUSE_CHAIN (c
) = NULL_TREE
;
13302 attach_tail
= &OMP_CLAUSE_CHAIN (c
);
13305 list_p
= &OMP_CLAUSE_CHAIN (c
);
13308 /* Splice attach nodes at the end of the list. */
13311 *list_p
= attach_list
;
13312 list_p
= attach_tail
;
13315 /* Add in any implicit data sharing. */
13316 struct gimplify_adjust_omp_clauses_data data
;
13317 if ((gimplify_omp_ctxp
->region_type
& ORT_ACC
) == 0)
13319 /* OpenMP. Implicit clauses are added at the start of the clause list,
13320 but after any non-map clauses. */
13321 tree
*implicit_add_list_p
= orig_list_p
;
13322 while (*implicit_add_list_p
13323 && OMP_CLAUSE_CODE (*implicit_add_list_p
) != OMP_CLAUSE_MAP
)
13324 implicit_add_list_p
= &OMP_CLAUSE_CHAIN (*implicit_add_list_p
);
13325 data
.list_p
= implicit_add_list_p
;
13329 data
.list_p
= list_p
;
13330 data
.pre_p
= pre_p
;
13331 splay_tree_foreach (ctx
->variables
, gimplify_adjust_omp_clauses_1
, &data
);
13333 if (has_inscan_reductions
)
13334 for (c
= *orig_list_p
; c
; c
= OMP_CLAUSE_CHAIN (c
))
13335 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINEAR
13336 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c
))
13338 error_at (OMP_CLAUSE_LOCATION (c
),
13339 "%<inscan%> %<reduction%> clause used together with "
13340 "%<linear%> clause for a variable other than loop "
13345 gimplify_omp_ctxp
= ctx
->outer_context
;
13346 delete_omp_context (ctx
);
13349 /* Return 0 if CONSTRUCTS selectors don't match the OpenMP context,
13350 -1 if unknown yet (simd is involved, won't be known until vectorization)
13351 and 1 if they do. If SCORES is non-NULL, it should point to an array
13352 of at least 2*NCONSTRUCTS+2 ints, and will be filled with the positions
13353 of the CONSTRUCTS (position -1 if it will never match) followed by
13354 number of constructs in the OpenMP context construct trait. If the
13355 score depends on whether it will be in a declare simd clone or not,
13356 the function returns 2 and there will be two sets of the scores, the first
13357 one for the case that it is not in a declare simd clone, the other
13358 that it is in a declare simd clone. */
13361 omp_construct_selector_matches (enum tree_code
*constructs
, int nconstructs
,
13364 int matched
= 0, cnt
= 0;
13365 bool simd_seen
= false;
13366 bool target_seen
= false;
13367 int declare_simd_cnt
= -1;
13368 auto_vec
<enum tree_code
, 16> codes
;
13369 for (struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
; ctx
;)
13371 if (((ctx
->region_type
& ORT_PARALLEL
) && ctx
->code
== OMP_PARALLEL
)
13372 || ((ctx
->region_type
& (ORT_TARGET
| ORT_IMPLICIT_TARGET
| ORT_ACC
))
13373 == ORT_TARGET
&& ctx
->code
== OMP_TARGET
)
13374 || ((ctx
->region_type
& ORT_TEAMS
) && ctx
->code
== OMP_TEAMS
)
13375 || (ctx
->region_type
== ORT_WORKSHARE
&& ctx
->code
== OMP_FOR
)
13376 || (ctx
->region_type
== ORT_SIMD
13377 && ctx
->code
== OMP_SIMD
13378 && !omp_find_clause (ctx
->clauses
, OMP_CLAUSE_BIND
)))
13382 codes
.safe_push (ctx
->code
);
13383 else if (matched
< nconstructs
&& ctx
->code
== constructs
[matched
])
13385 if (ctx
->code
== OMP_SIMD
)
13393 if (ctx
->code
== OMP_TARGET
)
13395 if (scores
== NULL
)
13396 return matched
< nconstructs
? 0 : simd_seen
? -1 : 1;
13397 target_seen
= true;
13401 else if (ctx
->region_type
== ORT_WORKSHARE
13402 && ctx
->code
== OMP_LOOP
13403 && ctx
->outer_context
13404 && ctx
->outer_context
->region_type
== ORT_COMBINED_PARALLEL
13405 && ctx
->outer_context
->outer_context
13406 && ctx
->outer_context
->outer_context
->code
== OMP_LOOP
13407 && ctx
->outer_context
->outer_context
->distribute
)
13408 ctx
= ctx
->outer_context
->outer_context
;
13409 ctx
= ctx
->outer_context
;
13412 && lookup_attribute ("omp declare simd",
13413 DECL_ATTRIBUTES (current_function_decl
)))
13415 /* Declare simd is a maybe case, it is supposed to be added only to the
13416 omp-simd-clone.cc added clones and not to the base function. */
13417 declare_simd_cnt
= cnt
++;
13419 codes
.safe_push (OMP_SIMD
);
13421 && constructs
[0] == OMP_SIMD
)
13423 gcc_assert (matched
== 0);
13425 if (++matched
== nconstructs
)
13429 if (tree attr
= lookup_attribute ("omp declare variant variant",
13430 DECL_ATTRIBUTES (current_function_decl
)))
13432 enum tree_code variant_constructs
[5];
13433 int variant_nconstructs
= 0;
13435 variant_nconstructs
13436 = omp_constructor_traits_to_codes (TREE_VALUE (attr
),
13437 variant_constructs
);
13438 for (int i
= 0; i
< variant_nconstructs
; i
++)
13442 codes
.safe_push (variant_constructs
[i
]);
13443 else if (matched
< nconstructs
13444 && variant_constructs
[i
] == constructs
[matched
])
13446 if (variant_constructs
[i
] == OMP_SIMD
)
13457 && lookup_attribute ("omp declare target block",
13458 DECL_ATTRIBUTES (current_function_decl
)))
13461 codes
.safe_push (OMP_TARGET
);
13462 else if (matched
< nconstructs
&& constructs
[matched
] == OMP_TARGET
)
13467 for (int pass
= 0; pass
< (declare_simd_cnt
== -1 ? 1 : 2); pass
++)
13469 int j
= codes
.length () - 1;
13470 for (int i
= nconstructs
- 1; i
>= 0; i
--)
13473 && (pass
!= 0 || declare_simd_cnt
!= j
)
13474 && constructs
[i
] != codes
[j
])
13476 if (pass
== 0 && declare_simd_cnt
!= -1 && j
> declare_simd_cnt
)
13481 *scores
++ = ((pass
== 0 && declare_simd_cnt
!= -1)
13482 ? codes
.length () - 1 : codes
.length ());
13484 return declare_simd_cnt
== -1 ? 1 : 2;
13486 if (matched
== nconstructs
)
13487 return simd_seen
? -1 : 1;
13491 /* Gimplify OACC_CACHE. */
13494 gimplify_oacc_cache (tree
*expr_p
, gimple_seq
*pre_p
)
13496 tree expr
= *expr_p
;
13498 gimplify_scan_omp_clauses (&OACC_CACHE_CLAUSES (expr
), pre_p
, ORT_ACC
,
13500 gimplify_adjust_omp_clauses (pre_p
, NULL
, &OACC_CACHE_CLAUSES (expr
),
13503 /* TODO: Do something sensible with this information. */
13505 *expr_p
= NULL_TREE
;
13508 /* Helper function of gimplify_oacc_declare. The helper's purpose is to,
13509 if required, translate 'kind' in CLAUSE into an 'entry' kind and 'exit'
13510 kind. The entry kind will replace the one in CLAUSE, while the exit
13511 kind will be used in a new omp_clause and returned to the caller. */
13514 gimplify_oacc_declare_1 (tree clause
)
13516 HOST_WIDE_INT kind
, new_op
;
13520 kind
= OMP_CLAUSE_MAP_KIND (clause
);
13524 case GOMP_MAP_ALLOC
:
13525 new_op
= GOMP_MAP_RELEASE
;
13529 case GOMP_MAP_FROM
:
13530 OMP_CLAUSE_SET_MAP_KIND (clause
, GOMP_MAP_FORCE_ALLOC
);
13531 new_op
= GOMP_MAP_FROM
;
13535 case GOMP_MAP_TOFROM
:
13536 OMP_CLAUSE_SET_MAP_KIND (clause
, GOMP_MAP_TO
);
13537 new_op
= GOMP_MAP_FROM
;
13541 case GOMP_MAP_DEVICE_RESIDENT
:
13542 case GOMP_MAP_FORCE_DEVICEPTR
:
13543 case GOMP_MAP_FORCE_PRESENT
:
13544 case GOMP_MAP_LINK
:
13545 case GOMP_MAP_POINTER
:
13550 gcc_unreachable ();
13556 c
= build_omp_clause (OMP_CLAUSE_LOCATION (clause
), OMP_CLAUSE_MAP
);
13557 OMP_CLAUSE_SET_MAP_KIND (c
, new_op
);
13558 OMP_CLAUSE_DECL (c
) = OMP_CLAUSE_DECL (clause
);
13564 /* Gimplify OACC_DECLARE. */
13567 gimplify_oacc_declare (tree
*expr_p
, gimple_seq
*pre_p
)
13569 tree expr
= *expr_p
;
13571 tree clauses
, t
, decl
;
13573 clauses
= OACC_DECLARE_CLAUSES (expr
);
13575 gimplify_scan_omp_clauses (&clauses
, pre_p
, ORT_TARGET_DATA
, OACC_DECLARE
);
13576 gimplify_adjust_omp_clauses (pre_p
, NULL
, &clauses
, OACC_DECLARE
);
13578 for (t
= clauses
; t
; t
= OMP_CLAUSE_CHAIN (t
))
13580 decl
= OMP_CLAUSE_DECL (t
);
13582 if (TREE_CODE (decl
) == MEM_REF
)
13583 decl
= TREE_OPERAND (decl
, 0);
13585 if (VAR_P (decl
) && !is_oacc_declared (decl
))
13587 tree attr
= get_identifier ("oacc declare target");
13588 DECL_ATTRIBUTES (decl
) = tree_cons (attr
, NULL_TREE
,
13589 DECL_ATTRIBUTES (decl
));
13593 && !is_global_var (decl
)
13594 && DECL_CONTEXT (decl
) == current_function_decl
)
13596 tree c
= gimplify_oacc_declare_1 (t
);
13599 if (oacc_declare_returns
== NULL
)
13600 oacc_declare_returns
= new hash_map
<tree
, tree
>;
13602 oacc_declare_returns
->put (decl
, c
);
13606 if (gimplify_omp_ctxp
)
13607 omp_add_variable (gimplify_omp_ctxp
, decl
, GOVD_SEEN
);
13610 stmt
= gimple_build_omp_target (NULL
, GF_OMP_TARGET_KIND_OACC_DECLARE
,
13613 gimplify_seq_add_stmt (pre_p
, stmt
);
13615 *expr_p
= NULL_TREE
;
13618 /* Gimplify the contents of an OMP_PARALLEL statement. This involves
13619 gimplification of the body, as well as scanning the body for used
13620 variables. We need to do this scan now, because variable-sized
13621 decls will be decomposed during gimplification. */
13624 gimplify_omp_parallel (tree
*expr_p
, gimple_seq
*pre_p
)
13626 tree expr
= *expr_p
;
13628 gimple_seq body
= NULL
;
13630 gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr
), pre_p
,
13631 OMP_PARALLEL_COMBINED (expr
)
13632 ? ORT_COMBINED_PARALLEL
13633 : ORT_PARALLEL
, OMP_PARALLEL
);
13635 push_gimplify_context ();
13637 g
= gimplify_and_return_first (OMP_PARALLEL_BODY (expr
), &body
);
13638 if (gimple_code (g
) == GIMPLE_BIND
)
13639 pop_gimplify_context (g
);
13641 pop_gimplify_context (NULL
);
13643 gimplify_adjust_omp_clauses (pre_p
, body
, &OMP_PARALLEL_CLAUSES (expr
),
13646 g
= gimple_build_omp_parallel (body
,
13647 OMP_PARALLEL_CLAUSES (expr
),
13648 NULL_TREE
, NULL_TREE
);
13649 if (OMP_PARALLEL_COMBINED (expr
))
13650 gimple_omp_set_subcode (g
, GF_OMP_PARALLEL_COMBINED
);
13651 gimplify_seq_add_stmt (pre_p
, g
);
13652 *expr_p
= NULL_TREE
;
13655 /* Gimplify the contents of an OMP_TASK statement. This involves
13656 gimplification of the body, as well as scanning the body for used
13657 variables. We need to do this scan now, because variable-sized
13658 decls will be decomposed during gimplification. */
13661 gimplify_omp_task (tree
*expr_p
, gimple_seq
*pre_p
)
13663 tree expr
= *expr_p
;
13665 gimple_seq body
= NULL
;
13666 bool nowait
= false;
13667 bool has_depend
= false;
13669 if (OMP_TASK_BODY (expr
) == NULL_TREE
)
13671 for (tree c
= OMP_TASK_CLAUSES (expr
); c
; c
= OMP_CLAUSE_CHAIN (c
))
13672 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEPEND
)
13675 if (OMP_CLAUSE_DEPEND_KIND (c
) == OMP_CLAUSE_DEPEND_MUTEXINOUTSET
)
13677 error_at (OMP_CLAUSE_LOCATION (c
),
13678 "%<mutexinoutset%> kind in %<depend%> clause on a "
13679 "%<taskwait%> construct");
13683 else if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_NOWAIT
)
13685 if (nowait
&& !has_depend
)
13687 error_at (EXPR_LOCATION (expr
),
13688 "%<taskwait%> construct with %<nowait%> clause but no "
13689 "%<depend%> clauses");
13690 *expr_p
= NULL_TREE
;
13695 gimplify_scan_omp_clauses (&OMP_TASK_CLAUSES (expr
), pre_p
,
13696 omp_find_clause (OMP_TASK_CLAUSES (expr
),
13698 ? ORT_UNTIED_TASK
: ORT_TASK
, OMP_TASK
);
13700 if (OMP_TASK_BODY (expr
))
13702 push_gimplify_context ();
13704 g
= gimplify_and_return_first (OMP_TASK_BODY (expr
), &body
);
13705 if (gimple_code (g
) == GIMPLE_BIND
)
13706 pop_gimplify_context (g
);
13708 pop_gimplify_context (NULL
);
13711 gimplify_adjust_omp_clauses (pre_p
, body
, &OMP_TASK_CLAUSES (expr
),
13714 g
= gimple_build_omp_task (body
,
13715 OMP_TASK_CLAUSES (expr
),
13716 NULL_TREE
, NULL_TREE
,
13717 NULL_TREE
, NULL_TREE
, NULL_TREE
);
13718 if (OMP_TASK_BODY (expr
) == NULL_TREE
)
13719 gimple_omp_task_set_taskwait_p (g
, true);
13720 gimplify_seq_add_stmt (pre_p
, g
);
13721 *expr_p
= NULL_TREE
;
13724 /* Helper function for gimplify_omp_for. If *TP is not a gimple constant,
13725 force it into a temporary initialized in PRE_P and add firstprivate clause
13726 to ORIG_FOR_STMT. */
13729 gimplify_omp_taskloop_expr (tree type
, tree
*tp
, gimple_seq
*pre_p
,
13730 tree orig_for_stmt
)
13732 if (*tp
== NULL
|| is_gimple_constant (*tp
))
13735 *tp
= get_initialized_tmp_var (*tp
, pre_p
, NULL
, false);
13736 /* Reference to pointer conversion is considered useless,
13737 but is significant for firstprivate clause. Force it
13740 && TREE_CODE (type
) == POINTER_TYPE
13741 && TREE_CODE (TREE_TYPE (*tp
)) == REFERENCE_TYPE
)
13743 tree v
= create_tmp_var (TYPE_MAIN_VARIANT (type
));
13744 tree m
= build2 (INIT_EXPR
, TREE_TYPE (v
), v
, *tp
);
13745 gimplify_and_add (m
, pre_p
);
13749 tree c
= build_omp_clause (input_location
, OMP_CLAUSE_FIRSTPRIVATE
);
13750 OMP_CLAUSE_DECL (c
) = *tp
;
13751 OMP_CLAUSE_CHAIN (c
) = OMP_FOR_CLAUSES (orig_for_stmt
);
13752 OMP_FOR_CLAUSES (orig_for_stmt
) = c
;
13755 /* Helper function of gimplify_omp_for, find OMP_ORDERED with
13756 null OMP_ORDERED_BODY inside of OMP_FOR's body. */
13759 find_standalone_omp_ordered (tree
*tp
, int *walk_subtrees
, void *)
13761 switch (TREE_CODE (*tp
))
13764 if (OMP_ORDERED_BODY (*tp
) == NULL_TREE
)
13770 *walk_subtrees
= 0;
13778 /* Gimplify the gross structure of an OMP_FOR statement. */
13780 static enum gimplify_status
13781 gimplify_omp_for (tree
*expr_p
, gimple_seq
*pre_p
)
13783 tree for_stmt
, orig_for_stmt
, inner_for_stmt
= NULL_TREE
, decl
, var
, t
;
13784 enum gimplify_status ret
= GS_ALL_DONE
;
13785 enum gimplify_status tret
;
13787 gimple_seq for_body
, for_pre_body
;
13789 bitmap has_decl_expr
= NULL
;
13790 enum omp_region_type ort
= ORT_WORKSHARE
;
13791 bool openacc
= TREE_CODE (*expr_p
) == OACC_LOOP
;
13793 orig_for_stmt
= for_stmt
= *expr_p
;
13795 bool loop_p
= (omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_BIND
)
13797 if (OMP_FOR_INIT (for_stmt
) == NULL_TREE
)
13799 tree
*data
[4] = { NULL
, NULL
, NULL
, NULL
};
13800 gcc_assert (TREE_CODE (for_stmt
) != OACC_LOOP
);
13801 inner_for_stmt
= walk_tree (&OMP_FOR_BODY (for_stmt
),
13802 find_combined_omp_for
, data
, NULL
);
13803 if (inner_for_stmt
== NULL_TREE
)
13805 gcc_assert (seen_error ());
13806 *expr_p
= NULL_TREE
;
13809 if (data
[2] && OMP_FOR_PRE_BODY (*data
[2]))
13811 append_to_statement_list_force (OMP_FOR_PRE_BODY (*data
[2]),
13812 &OMP_FOR_PRE_BODY (for_stmt
));
13813 OMP_FOR_PRE_BODY (*data
[2]) = NULL_TREE
;
13815 if (OMP_FOR_PRE_BODY (inner_for_stmt
))
13817 append_to_statement_list_force (OMP_FOR_PRE_BODY (inner_for_stmt
),
13818 &OMP_FOR_PRE_BODY (for_stmt
));
13819 OMP_FOR_PRE_BODY (inner_for_stmt
) = NULL_TREE
;
13824 /* We have some statements or variable declarations in between
13825 the composite construct directives. Move them around the
13828 for (i
= 0; i
< 3; i
++)
13832 if (i
< 2 && data
[i
+ 1] == &OMP_BODY (t
))
13833 data
[i
+ 1] = data
[i
];
13834 *data
[i
] = OMP_BODY (t
);
13835 tree body
= build3 (BIND_EXPR
, void_type_node
, NULL_TREE
,
13836 NULL_TREE
, make_node (BLOCK
));
13837 OMP_BODY (t
) = body
;
13838 append_to_statement_list_force (inner_for_stmt
,
13839 &BIND_EXPR_BODY (body
));
13841 data
[3] = tsi_stmt_ptr (tsi_start (BIND_EXPR_BODY (body
)));
13842 gcc_assert (*data
[3] == inner_for_stmt
);
13847 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt
)); i
++)
13849 && OMP_FOR_ORIG_DECLS (inner_for_stmt
)
13850 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
),
13852 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
),
13855 tree orig
= TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
), i
);
13856 /* Class iterators aren't allowed on OMP_SIMD, so the only
13857 case we need to solve is distribute parallel for. They are
13858 allowed on the loop construct, but that is already handled
13859 in gimplify_omp_loop. */
13860 gcc_assert (TREE_CODE (inner_for_stmt
) == OMP_FOR
13861 && TREE_CODE (for_stmt
) == OMP_DISTRIBUTE
13863 tree orig_decl
= TREE_PURPOSE (orig
);
13864 tree last
= TREE_VALUE (orig
);
13866 for (pc
= &OMP_FOR_CLAUSES (inner_for_stmt
);
13867 *pc
; pc
= &OMP_CLAUSE_CHAIN (*pc
))
13868 if ((OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_PRIVATE
13869 || OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_LASTPRIVATE
)
13870 && OMP_CLAUSE_DECL (*pc
) == orig_decl
)
13872 if (*pc
== NULL_TREE
)
13875 for (spc
= &OMP_PARALLEL_CLAUSES (*data
[1]);
13876 *spc
; spc
= &OMP_CLAUSE_CHAIN (*spc
))
13877 if (OMP_CLAUSE_CODE (*spc
) == OMP_CLAUSE_PRIVATE
13878 && OMP_CLAUSE_DECL (*spc
) == orig_decl
)
13883 *spc
= OMP_CLAUSE_CHAIN (c
);
13884 OMP_CLAUSE_CHAIN (c
) = NULL_TREE
;
13888 if (*pc
== NULL_TREE
)
13890 else if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_PRIVATE
)
13892 /* private clause will appear only on inner_for_stmt.
13893 Change it into firstprivate, and add private clause
13895 tree c
= copy_node (*pc
);
13896 OMP_CLAUSE_CHAIN (c
) = OMP_FOR_CLAUSES (for_stmt
);
13897 OMP_FOR_CLAUSES (for_stmt
) = c
;
13898 OMP_CLAUSE_CODE (*pc
) = OMP_CLAUSE_FIRSTPRIVATE
;
13899 lang_hooks
.decls
.omp_finish_clause (*pc
, pre_p
, openacc
);
13903 /* lastprivate clause will appear on both inner_for_stmt
13904 and for_stmt. Add firstprivate clause to
13906 tree c
= build_omp_clause (OMP_CLAUSE_LOCATION (*pc
),
13907 OMP_CLAUSE_FIRSTPRIVATE
);
13908 OMP_CLAUSE_DECL (c
) = OMP_CLAUSE_DECL (*pc
);
13909 OMP_CLAUSE_CHAIN (c
) = *pc
;
13911 lang_hooks
.decls
.omp_finish_clause (*pc
, pre_p
, openacc
);
13913 tree c
= build_omp_clause (UNKNOWN_LOCATION
,
13914 OMP_CLAUSE_FIRSTPRIVATE
);
13915 OMP_CLAUSE_DECL (c
) = last
;
13916 OMP_CLAUSE_CHAIN (c
) = OMP_PARALLEL_CLAUSES (*data
[1]);
13917 OMP_PARALLEL_CLAUSES (*data
[1]) = c
;
13918 c
= build_omp_clause (UNKNOWN_LOCATION
,
13919 *pc
? OMP_CLAUSE_SHARED
13920 : OMP_CLAUSE_FIRSTPRIVATE
);
13921 OMP_CLAUSE_DECL (c
) = orig_decl
;
13922 OMP_CLAUSE_CHAIN (c
) = OMP_PARALLEL_CLAUSES (*data
[1]);
13923 OMP_PARALLEL_CLAUSES (*data
[1]) = c
;
13925 /* Similarly, take care of C++ range for temporaries, those should
13926 be firstprivate on OMP_PARALLEL if any. */
13928 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt
)); i
++)
13929 if (OMP_FOR_ORIG_DECLS (inner_for_stmt
)
13930 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
),
13932 && TREE_CHAIN (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
),
13936 = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
), i
);
13937 tree v
= TREE_CHAIN (orig
);
13938 tree c
= build_omp_clause (UNKNOWN_LOCATION
,
13939 OMP_CLAUSE_FIRSTPRIVATE
);
13940 /* First add firstprivate clause for the __for_end artificial
13942 OMP_CLAUSE_DECL (c
) = TREE_VEC_ELT (v
, 1);
13943 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c
)))
13945 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c
) = 1;
13946 OMP_CLAUSE_CHAIN (c
) = OMP_PARALLEL_CLAUSES (*data
[1]);
13947 OMP_PARALLEL_CLAUSES (*data
[1]) = c
;
13948 if (TREE_VEC_ELT (v
, 0))
13950 /* And now the same for __for_range artificial decl if it
13952 c
= build_omp_clause (UNKNOWN_LOCATION
,
13953 OMP_CLAUSE_FIRSTPRIVATE
);
13954 OMP_CLAUSE_DECL (c
) = TREE_VEC_ELT (v
, 0);
13955 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c
)))
13957 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c
) = 1;
13958 OMP_CLAUSE_CHAIN (c
) = OMP_PARALLEL_CLAUSES (*data
[1]);
13959 OMP_PARALLEL_CLAUSES (*data
[1]) = c
;
13964 switch (TREE_CODE (for_stmt
))
13967 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt
? inner_for_stmt
: for_stmt
))
13969 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt
),
13970 OMP_CLAUSE_SCHEDULE
))
13971 error_at (EXPR_LOCATION (for_stmt
),
13972 "%qs clause may not appear on non-rectangular %qs",
13973 "schedule", lang_GNU_Fortran () ? "do" : "for");
13974 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_ORDERED
))
13975 error_at (EXPR_LOCATION (for_stmt
),
13976 "%qs clause may not appear on non-rectangular %qs",
13977 "ordered", lang_GNU_Fortran () ? "do" : "for");
13980 case OMP_DISTRIBUTE
:
13981 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt
? inner_for_stmt
: for_stmt
)
13982 && omp_find_clause (OMP_FOR_CLAUSES (for_stmt
),
13983 OMP_CLAUSE_DIST_SCHEDULE
))
13984 error_at (EXPR_LOCATION (for_stmt
),
13985 "%qs clause may not appear on non-rectangular %qs",
13986 "dist_schedule", "distribute");
13992 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt
? inner_for_stmt
: for_stmt
))
13994 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt
),
13995 OMP_CLAUSE_GRAINSIZE
))
13996 error_at (EXPR_LOCATION (for_stmt
),
13997 "%qs clause may not appear on non-rectangular %qs",
13998 "grainsize", "taskloop");
13999 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt
),
14000 OMP_CLAUSE_NUM_TASKS
))
14001 error_at (EXPR_LOCATION (for_stmt
),
14002 "%qs clause may not appear on non-rectangular %qs",
14003 "num_tasks", "taskloop");
14005 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_UNTIED
))
14006 ort
= ORT_UNTIED_TASKLOOP
;
14008 ort
= ORT_TASKLOOP
;
14014 gcc_unreachable ();
14017 /* Set OMP_CLAUSE_LINEAR_NO_COPYIN flag on explicit linear
14018 clause for the IV. */
14019 if (ort
== ORT_SIMD
&& TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)) == 1)
14021 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), 0);
14022 gcc_assert (TREE_CODE (t
) == MODIFY_EXPR
);
14023 decl
= TREE_OPERAND (t
, 0);
14024 for (tree c
= OMP_FOR_CLAUSES (for_stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
14025 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINEAR
14026 && OMP_CLAUSE_DECL (c
) == decl
)
14028 OMP_CLAUSE_LINEAR_NO_COPYIN (c
) = 1;
14033 if (TREE_CODE (for_stmt
) != OMP_TASKLOOP
)
14034 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt
), pre_p
, ort
,
14035 loop_p
&& TREE_CODE (for_stmt
) != OMP_SIMD
14036 ? OMP_LOOP
: TREE_CODE (for_stmt
));
14038 if (TREE_CODE (for_stmt
) == OMP_DISTRIBUTE
)
14039 gimplify_omp_ctxp
->distribute
= true;
14041 /* Handle OMP_FOR_INIT. */
14042 for_pre_body
= NULL
;
14043 if ((ort
== ORT_SIMD
14044 || (inner_for_stmt
&& TREE_CODE (inner_for_stmt
) == OMP_SIMD
))
14045 && OMP_FOR_PRE_BODY (for_stmt
))
14047 has_decl_expr
= BITMAP_ALLOC (NULL
);
14048 if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt
)) == DECL_EXPR
14049 && VAR_P (DECL_EXPR_DECL (OMP_FOR_PRE_BODY (for_stmt
))))
14051 t
= OMP_FOR_PRE_BODY (for_stmt
);
14052 bitmap_set_bit (has_decl_expr
, DECL_UID (DECL_EXPR_DECL (t
)));
14054 else if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt
)) == STATEMENT_LIST
)
14056 tree_stmt_iterator si
;
14057 for (si
= tsi_start (OMP_FOR_PRE_BODY (for_stmt
)); !tsi_end_p (si
);
14061 if (TREE_CODE (t
) == DECL_EXPR
14062 && VAR_P (DECL_EXPR_DECL (t
)))
14063 bitmap_set_bit (has_decl_expr
, DECL_UID (DECL_EXPR_DECL (t
)));
14067 if (OMP_FOR_PRE_BODY (for_stmt
))
14069 if (TREE_CODE (for_stmt
) != OMP_TASKLOOP
|| gimplify_omp_ctxp
)
14070 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt
), &for_pre_body
);
14073 struct gimplify_omp_ctx ctx
;
14074 memset (&ctx
, 0, sizeof (ctx
));
14075 ctx
.region_type
= ORT_NONE
;
14076 gimplify_omp_ctxp
= &ctx
;
14077 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt
), &for_pre_body
);
14078 gimplify_omp_ctxp
= NULL
;
14081 OMP_FOR_PRE_BODY (for_stmt
) = NULL_TREE
;
14083 if (OMP_FOR_INIT (for_stmt
) == NULL_TREE
)
14084 for_stmt
= inner_for_stmt
;
14086 /* For taskloop, need to gimplify the start, end and step before the
14087 taskloop, outside of the taskloop omp context. */
14088 if (TREE_CODE (orig_for_stmt
) == OMP_TASKLOOP
)
14090 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
14092 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), i
);
14093 gimple_seq
*for_pre_p
= (gimple_seq_empty_p (for_pre_body
)
14094 ? pre_p
: &for_pre_body
);
14095 tree type
= TREE_TYPE (TREE_OPERAND (t
, 0));
14096 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
)
14098 tree v
= TREE_OPERAND (t
, 1);
14099 gimplify_omp_taskloop_expr (type
, &TREE_VEC_ELT (v
, 1),
14100 for_pre_p
, orig_for_stmt
);
14101 gimplify_omp_taskloop_expr (type
, &TREE_VEC_ELT (v
, 2),
14102 for_pre_p
, orig_for_stmt
);
14105 gimplify_omp_taskloop_expr (type
, &TREE_OPERAND (t
, 1), for_pre_p
,
14108 /* Handle OMP_FOR_COND. */
14109 t
= TREE_VEC_ELT (OMP_FOR_COND (for_stmt
), i
);
14110 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
)
14112 tree v
= TREE_OPERAND (t
, 1);
14113 gimplify_omp_taskloop_expr (type
, &TREE_VEC_ELT (v
, 1),
14114 for_pre_p
, orig_for_stmt
);
14115 gimplify_omp_taskloop_expr (type
, &TREE_VEC_ELT (v
, 2),
14116 for_pre_p
, orig_for_stmt
);
14119 gimplify_omp_taskloop_expr (type
, &TREE_OPERAND (t
, 1), for_pre_p
,
14122 /* Handle OMP_FOR_INCR. */
14123 t
= TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
);
14124 if (TREE_CODE (t
) == MODIFY_EXPR
)
14126 decl
= TREE_OPERAND (t
, 0);
14127 t
= TREE_OPERAND (t
, 1);
14128 tree
*tp
= &TREE_OPERAND (t
, 1);
14129 if (TREE_CODE (t
) == PLUS_EXPR
&& *tp
== decl
)
14130 tp
= &TREE_OPERAND (t
, 0);
14132 gimplify_omp_taskloop_expr (NULL_TREE
, tp
, for_pre_p
,
14137 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (orig_for_stmt
), pre_p
, ort
,
14141 if (orig_for_stmt
!= for_stmt
)
14142 gimplify_omp_ctxp
->combined_loop
= true;
14145 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
))
14146 == TREE_VEC_LENGTH (OMP_FOR_COND (for_stmt
)));
14147 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
))
14148 == TREE_VEC_LENGTH (OMP_FOR_INCR (for_stmt
)));
14150 tree c
= omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_ORDERED
);
14151 bool is_doacross
= false;
14152 if (c
&& walk_tree_without_duplicates (&OMP_FOR_BODY (for_stmt
),
14153 find_standalone_omp_ordered
, NULL
))
14155 OMP_CLAUSE_ORDERED_DOACROSS (c
) = 1;
14156 is_doacross
= true;
14157 int len
= TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
));
14158 gimplify_omp_ctxp
->loop_iter_var
.create (len
* 2);
14159 for (tree
*pc
= &OMP_FOR_CLAUSES (for_stmt
); *pc
; )
14160 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_LINEAR
)
14162 error_at (OMP_CLAUSE_LOCATION (*pc
),
14163 "%<linear%> clause may not be specified together "
14164 "with %<ordered%> clause if stand-alone %<ordered%> "
14165 "construct is nested in it");
14166 *pc
= OMP_CLAUSE_CHAIN (*pc
);
14169 pc
= &OMP_CLAUSE_CHAIN (*pc
);
14171 int collapse
= 1, tile
= 0;
14172 c
= omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_COLLAPSE
);
14174 collapse
= tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (c
));
14175 c
= omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_TILE
);
14177 tile
= list_length (OMP_CLAUSE_TILE_LIST (c
));
14178 c
= omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_ALLOCATE
);
14179 hash_set
<tree
> *allocate_uids
= NULL
;
14182 allocate_uids
= new hash_set
<tree
>;
14183 for (; c
; c
= OMP_CLAUSE_CHAIN (c
))
14184 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_ALLOCATE
)
14185 allocate_uids
->add (OMP_CLAUSE_DECL (c
));
14187 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
14189 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), i
);
14190 gcc_assert (TREE_CODE (t
) == MODIFY_EXPR
);
14191 decl
= TREE_OPERAND (t
, 0);
14192 gcc_assert (DECL_P (decl
));
14193 gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl
))
14194 || POINTER_TYPE_P (TREE_TYPE (decl
)));
14197 if (TREE_CODE (for_stmt
) == OMP_FOR
&& OMP_FOR_ORIG_DECLS (for_stmt
))
14199 tree orig_decl
= TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
), i
);
14200 if (TREE_CODE (orig_decl
) == TREE_LIST
)
14202 orig_decl
= TREE_PURPOSE (orig_decl
);
14206 gimplify_omp_ctxp
->loop_iter_var
.quick_push (orig_decl
);
14209 gimplify_omp_ctxp
->loop_iter_var
.quick_push (decl
);
14210 gimplify_omp_ctxp
->loop_iter_var
.quick_push (decl
);
14213 if (for_stmt
== orig_for_stmt
)
14215 tree orig_decl
= decl
;
14216 if (OMP_FOR_ORIG_DECLS (for_stmt
))
14218 tree orig_decl
= TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
), i
);
14219 if (TREE_CODE (orig_decl
) == TREE_LIST
)
14221 orig_decl
= TREE_PURPOSE (orig_decl
);
14226 if (is_global_var (orig_decl
) && DECL_THREAD_LOCAL_P (orig_decl
))
14227 error_at (EXPR_LOCATION (for_stmt
),
14228 "threadprivate iteration variable %qD", orig_decl
);
14231 /* Make sure the iteration variable is private. */
14232 tree c
= NULL_TREE
;
14233 tree c2
= NULL_TREE
;
14234 if (orig_for_stmt
!= for_stmt
)
14236 /* Preserve this information until we gimplify the inner simd. */
14238 && bitmap_bit_p (has_decl_expr
, DECL_UID (decl
)))
14239 TREE_PRIVATE (t
) = 1;
14241 else if (ort
== ORT_SIMD
)
14243 splay_tree_node n
= splay_tree_lookup (gimplify_omp_ctxp
->variables
,
14244 (splay_tree_key
) decl
);
14245 omp_is_private (gimplify_omp_ctxp
, decl
,
14246 1 + (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
))
14248 if (n
!= NULL
&& (n
->value
& GOVD_DATA_SHARE_CLASS
) != 0)
14250 omp_notice_variable (gimplify_omp_ctxp
, decl
, true);
14251 if (n
->value
& GOVD_LASTPRIVATE_CONDITIONAL
)
14252 for (tree c3
= omp_find_clause (OMP_FOR_CLAUSES (for_stmt
),
14253 OMP_CLAUSE_LASTPRIVATE
);
14254 c3
; c3
= omp_find_clause (OMP_CLAUSE_CHAIN (c3
),
14255 OMP_CLAUSE_LASTPRIVATE
))
14256 if (OMP_CLAUSE_DECL (c3
) == decl
)
14258 warning_at (OMP_CLAUSE_LOCATION (c3
), 0,
14259 "conditional %<lastprivate%> on loop "
14260 "iterator %qD ignored", decl
);
14261 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3
) = 0;
14262 n
->value
&= ~GOVD_LASTPRIVATE_CONDITIONAL
;
14265 else if (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)) == 1 && !loop_p
)
14267 c
= build_omp_clause (input_location
, OMP_CLAUSE_LINEAR
);
14268 OMP_CLAUSE_LINEAR_NO_COPYIN (c
) = 1;
14269 unsigned int flags
= GOVD_LINEAR
| GOVD_EXPLICIT
| GOVD_SEEN
;
14271 && bitmap_bit_p (has_decl_expr
, DECL_UID (decl
)))
14272 || TREE_PRIVATE (t
))
14274 OMP_CLAUSE_LINEAR_NO_COPYOUT (c
) = 1;
14275 flags
|= GOVD_LINEAR_LASTPRIVATE_NO_OUTER
;
14277 struct gimplify_omp_ctx
*outer
14278 = gimplify_omp_ctxp
->outer_context
;
14279 if (outer
&& !OMP_CLAUSE_LINEAR_NO_COPYOUT (c
))
14281 if (outer
->region_type
== ORT_WORKSHARE
14282 && outer
->combined_loop
)
14284 n
= splay_tree_lookup (outer
->variables
,
14285 (splay_tree_key
)decl
);
14286 if (n
!= NULL
&& (n
->value
& GOVD_LOCAL
) != 0)
14288 OMP_CLAUSE_LINEAR_NO_COPYOUT (c
) = 1;
14289 flags
|= GOVD_LINEAR_LASTPRIVATE_NO_OUTER
;
14293 struct gimplify_omp_ctx
*octx
= outer
->outer_context
;
14295 && octx
->region_type
== ORT_COMBINED_PARALLEL
14296 && octx
->outer_context
14297 && (octx
->outer_context
->region_type
14299 && octx
->outer_context
->combined_loop
)
14301 octx
= octx
->outer_context
;
14302 n
= splay_tree_lookup (octx
->variables
,
14303 (splay_tree_key
)decl
);
14304 if (n
!= NULL
&& (n
->value
& GOVD_LOCAL
) != 0)
14306 OMP_CLAUSE_LINEAR_NO_COPYOUT (c
) = 1;
14307 flags
|= GOVD_LINEAR_LASTPRIVATE_NO_OUTER
;
14314 OMP_CLAUSE_DECL (c
) = decl
;
14315 OMP_CLAUSE_CHAIN (c
) = OMP_FOR_CLAUSES (for_stmt
);
14316 OMP_FOR_CLAUSES (for_stmt
) = c
;
14317 omp_add_variable (gimplify_omp_ctxp
, decl
, flags
);
14318 if (outer
&& !OMP_CLAUSE_LINEAR_NO_COPYOUT (c
))
14319 omp_lastprivate_for_combined_outer_constructs (outer
, decl
,
14326 || !bitmap_bit_p (has_decl_expr
, DECL_UID (decl
)));
14327 if (TREE_PRIVATE (t
))
14328 lastprivate
= false;
14329 if (loop_p
&& OMP_FOR_ORIG_DECLS (for_stmt
))
14331 tree elt
= TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
), i
);
14332 if (TREE_CODE (elt
) == TREE_LIST
&& TREE_PURPOSE (elt
))
14333 lastprivate
= false;
14336 struct gimplify_omp_ctx
*outer
14337 = gimplify_omp_ctxp
->outer_context
;
14338 if (outer
&& lastprivate
)
14339 omp_lastprivate_for_combined_outer_constructs (outer
, decl
,
14342 c
= build_omp_clause (input_location
,
14343 lastprivate
? OMP_CLAUSE_LASTPRIVATE
14344 : OMP_CLAUSE_PRIVATE
);
14345 OMP_CLAUSE_DECL (c
) = decl
;
14346 OMP_CLAUSE_CHAIN (c
) = OMP_FOR_CLAUSES (for_stmt
);
14347 OMP_FOR_CLAUSES (for_stmt
) = c
;
14348 omp_add_variable (gimplify_omp_ctxp
, decl
,
14349 (lastprivate
? GOVD_LASTPRIVATE
: GOVD_PRIVATE
)
14350 | GOVD_EXPLICIT
| GOVD_SEEN
);
14354 else if (omp_is_private (gimplify_omp_ctxp
, decl
, 0))
14356 omp_notice_variable (gimplify_omp_ctxp
, decl
, true);
14357 splay_tree_node n
= splay_tree_lookup (gimplify_omp_ctxp
->variables
,
14358 (splay_tree_key
) decl
);
14359 if (n
&& (n
->value
& GOVD_LASTPRIVATE_CONDITIONAL
))
14360 for (tree c3
= omp_find_clause (OMP_FOR_CLAUSES (for_stmt
),
14361 OMP_CLAUSE_LASTPRIVATE
);
14362 c3
; c3
= omp_find_clause (OMP_CLAUSE_CHAIN (c3
),
14363 OMP_CLAUSE_LASTPRIVATE
))
14364 if (OMP_CLAUSE_DECL (c3
) == decl
)
14366 warning_at (OMP_CLAUSE_LOCATION (c3
), 0,
14367 "conditional %<lastprivate%> on loop "
14368 "iterator %qD ignored", decl
);
14369 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3
) = 0;
14370 n
->value
&= ~GOVD_LASTPRIVATE_CONDITIONAL
;
14374 omp_add_variable (gimplify_omp_ctxp
, decl
, GOVD_PRIVATE
| GOVD_SEEN
);
14376 /* If DECL is not a gimple register, create a temporary variable to act
14377 as an iteration counter. This is valid, since DECL cannot be
14378 modified in the body of the loop. Similarly for any iteration vars
14379 in simd with collapse > 1 where the iterator vars must be
14380 lastprivate. And similarly for vars mentioned in allocate clauses. */
14381 if (orig_for_stmt
!= for_stmt
)
14383 else if (!is_gimple_reg (decl
)
14384 || (ort
== ORT_SIMD
14385 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)) > 1)
14386 || (allocate_uids
&& allocate_uids
->contains (decl
)))
14388 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
14389 /* Make sure omp_add_variable is not called on it prematurely.
14390 We call it ourselves a few lines later. */
14391 gimplify_omp_ctxp
= NULL
;
14392 var
= create_tmp_var (TREE_TYPE (decl
), get_name (decl
));
14393 gimplify_omp_ctxp
= ctx
;
14394 TREE_OPERAND (t
, 0) = var
;
14396 gimplify_seq_add_stmt (&for_body
, gimple_build_assign (decl
, var
));
14398 if (ort
== ORT_SIMD
14399 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)) == 1)
14401 c2
= build_omp_clause (input_location
, OMP_CLAUSE_LINEAR
);
14402 OMP_CLAUSE_LINEAR_NO_COPYIN (c2
) = 1;
14403 OMP_CLAUSE_LINEAR_NO_COPYOUT (c2
) = 1;
14404 OMP_CLAUSE_DECL (c2
) = var
;
14405 OMP_CLAUSE_CHAIN (c2
) = OMP_FOR_CLAUSES (for_stmt
);
14406 OMP_FOR_CLAUSES (for_stmt
) = c2
;
14407 omp_add_variable (gimplify_omp_ctxp
, var
,
14408 GOVD_LINEAR
| GOVD_EXPLICIT
| GOVD_SEEN
);
14409 if (c
== NULL_TREE
)
14416 omp_add_variable (gimplify_omp_ctxp
, var
,
14417 GOVD_PRIVATE
| GOVD_SEEN
);
14422 gimplify_omp_ctxp
->in_for_exprs
= true;
14423 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
)
14425 tree lb
= TREE_OPERAND (t
, 1);
14426 tret
= gimplify_expr (&TREE_VEC_ELT (lb
, 1), &for_pre_body
, NULL
,
14427 is_gimple_val
, fb_rvalue
, false);
14428 ret
= MIN (ret
, tret
);
14429 tret
= gimplify_expr (&TREE_VEC_ELT (lb
, 2), &for_pre_body
, NULL
,
14430 is_gimple_val
, fb_rvalue
, false);
14433 tret
= gimplify_expr (&TREE_OPERAND (t
, 1), &for_pre_body
, NULL
,
14434 is_gimple_val
, fb_rvalue
, false);
14435 gimplify_omp_ctxp
->in_for_exprs
= false;
14436 ret
= MIN (ret
, tret
);
14437 if (ret
== GS_ERROR
)
14440 /* Handle OMP_FOR_COND. */
14441 t
= TREE_VEC_ELT (OMP_FOR_COND (for_stmt
), i
);
14442 gcc_assert (COMPARISON_CLASS_P (t
));
14443 gcc_assert (TREE_OPERAND (t
, 0) == decl
);
14445 gimplify_omp_ctxp
->in_for_exprs
= true;
14446 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
)
14448 tree ub
= TREE_OPERAND (t
, 1);
14449 tret
= gimplify_expr (&TREE_VEC_ELT (ub
, 1), &for_pre_body
, NULL
,
14450 is_gimple_val
, fb_rvalue
, false);
14451 ret
= MIN (ret
, tret
);
14452 tret
= gimplify_expr (&TREE_VEC_ELT (ub
, 2), &for_pre_body
, NULL
,
14453 is_gimple_val
, fb_rvalue
, false);
14456 tret
= gimplify_expr (&TREE_OPERAND (t
, 1), &for_pre_body
, NULL
,
14457 is_gimple_val
, fb_rvalue
, false);
14458 gimplify_omp_ctxp
->in_for_exprs
= false;
14459 ret
= MIN (ret
, tret
);
14461 /* Handle OMP_FOR_INCR. */
14462 t
= TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
);
14463 switch (TREE_CODE (t
))
14465 case PREINCREMENT_EXPR
:
14466 case POSTINCREMENT_EXPR
:
14468 tree decl
= TREE_OPERAND (t
, 0);
14469 /* c_omp_for_incr_canonicalize_ptr() should have been
14470 called to massage things appropriately. */
14471 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl
)));
14473 if (orig_for_stmt
!= for_stmt
)
14475 t
= build_int_cst (TREE_TYPE (decl
), 1);
14477 OMP_CLAUSE_LINEAR_STEP (c
) = t
;
14478 t
= build2 (PLUS_EXPR
, TREE_TYPE (decl
), var
, t
);
14479 t
= build2 (MODIFY_EXPR
, TREE_TYPE (var
), var
, t
);
14480 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
) = t
;
14484 case PREDECREMENT_EXPR
:
14485 case POSTDECREMENT_EXPR
:
14486 /* c_omp_for_incr_canonicalize_ptr() should have been
14487 called to massage things appropriately. */
14488 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl
)));
14489 if (orig_for_stmt
!= for_stmt
)
14491 t
= build_int_cst (TREE_TYPE (decl
), -1);
14493 OMP_CLAUSE_LINEAR_STEP (c
) = t
;
14494 t
= build2 (PLUS_EXPR
, TREE_TYPE (decl
), var
, t
);
14495 t
= build2 (MODIFY_EXPR
, TREE_TYPE (var
), var
, t
);
14496 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
) = t
;
14500 gcc_assert (TREE_OPERAND (t
, 0) == decl
);
14501 TREE_OPERAND (t
, 0) = var
;
14503 t
= TREE_OPERAND (t
, 1);
14504 switch (TREE_CODE (t
))
14507 if (TREE_OPERAND (t
, 1) == decl
)
14509 TREE_OPERAND (t
, 1) = TREE_OPERAND (t
, 0);
14510 TREE_OPERAND (t
, 0) = var
;
14516 case POINTER_PLUS_EXPR
:
14517 gcc_assert (TREE_OPERAND (t
, 0) == decl
);
14518 TREE_OPERAND (t
, 0) = var
;
14521 gcc_unreachable ();
14524 gimplify_omp_ctxp
->in_for_exprs
= true;
14525 tret
= gimplify_expr (&TREE_OPERAND (t
, 1), &for_pre_body
, NULL
,
14526 is_gimple_val
, fb_rvalue
, false);
14527 ret
= MIN (ret
, tret
);
14530 tree step
= TREE_OPERAND (t
, 1);
14531 tree stept
= TREE_TYPE (decl
);
14532 if (POINTER_TYPE_P (stept
))
14534 step
= fold_convert (stept
, step
);
14535 if (TREE_CODE (t
) == MINUS_EXPR
)
14536 step
= fold_build1 (NEGATE_EXPR
, stept
, step
);
14537 OMP_CLAUSE_LINEAR_STEP (c
) = step
;
14538 if (step
!= TREE_OPERAND (t
, 1))
14540 tret
= gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c
),
14541 &for_pre_body
, NULL
,
14542 is_gimple_val
, fb_rvalue
, false);
14543 ret
= MIN (ret
, tret
);
14546 gimplify_omp_ctxp
->in_for_exprs
= false;
14550 gcc_unreachable ();
14556 OMP_CLAUSE_LINEAR_STEP (c2
) = OMP_CLAUSE_LINEAR_STEP (c
);
14559 if ((var
!= decl
|| collapse
> 1 || tile
) && orig_for_stmt
== for_stmt
)
14561 for (c
= OMP_FOR_CLAUSES (for_stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
14562 if (((OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
14563 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
) == NULL
)
14564 || (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINEAR
14565 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c
)
14566 && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c
) == NULL
))
14567 && OMP_CLAUSE_DECL (c
) == decl
)
14569 if (is_doacross
&& (collapse
== 1 || i
>= collapse
))
14573 t
= TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
);
14574 gcc_assert (TREE_CODE (t
) == MODIFY_EXPR
);
14575 gcc_assert (TREE_OPERAND (t
, 0) == var
);
14576 t
= TREE_OPERAND (t
, 1);
14577 gcc_assert (TREE_CODE (t
) == PLUS_EXPR
14578 || TREE_CODE (t
) == MINUS_EXPR
14579 || TREE_CODE (t
) == POINTER_PLUS_EXPR
);
14580 gcc_assert (TREE_OPERAND (t
, 0) == var
);
14581 t
= build2 (TREE_CODE (t
), TREE_TYPE (decl
),
14582 is_doacross
? var
: decl
,
14583 TREE_OPERAND (t
, 1));
14586 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
)
14587 seq
= &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
);
14589 seq
= &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c
);
14590 push_gimplify_context ();
14591 gimplify_assign (decl
, t
, seq
);
14592 gimple
*bind
= NULL
;
14593 if (gimplify_ctxp
->temps
)
14595 bind
= gimple_build_bind (NULL_TREE
, *seq
, NULL_TREE
);
14597 gimplify_seq_add_stmt (seq
, bind
);
14599 pop_gimplify_context (bind
);
14602 if (OMP_FOR_NON_RECTANGULAR (for_stmt
) && var
!= decl
)
14603 for (int j
= i
+ 1; j
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); j
++)
14605 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), j
);
14606 gcc_assert (TREE_CODE (t
) == MODIFY_EXPR
);
14607 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
14608 && TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) == decl
)
14609 TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) = var
;
14610 t
= TREE_VEC_ELT (OMP_FOR_COND (for_stmt
), j
);
14611 gcc_assert (COMPARISON_CLASS_P (t
));
14612 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
14613 && TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) == decl
)
14614 TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) = var
;
14618 BITMAP_FREE (has_decl_expr
);
14619 delete allocate_uids
;
14621 if (TREE_CODE (orig_for_stmt
) == OMP_TASKLOOP
14622 || (loop_p
&& orig_for_stmt
== for_stmt
))
14624 push_gimplify_context ();
14625 if (TREE_CODE (OMP_FOR_BODY (orig_for_stmt
)) != BIND_EXPR
)
14627 OMP_FOR_BODY (orig_for_stmt
)
14628 = build3 (BIND_EXPR
, void_type_node
, NULL
,
14629 OMP_FOR_BODY (orig_for_stmt
), NULL
);
14630 TREE_SIDE_EFFECTS (OMP_FOR_BODY (orig_for_stmt
)) = 1;
14634 gimple
*g
= gimplify_and_return_first (OMP_FOR_BODY (orig_for_stmt
),
14637 if (TREE_CODE (orig_for_stmt
) == OMP_TASKLOOP
14638 || (loop_p
&& orig_for_stmt
== for_stmt
))
14640 if (gimple_code (g
) == GIMPLE_BIND
)
14641 pop_gimplify_context (g
);
14643 pop_gimplify_context (NULL
);
14646 if (orig_for_stmt
!= for_stmt
)
14647 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
14649 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), i
);
14650 decl
= TREE_OPERAND (t
, 0);
14651 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
14652 if (TREE_CODE (orig_for_stmt
) == OMP_TASKLOOP
)
14653 gimplify_omp_ctxp
= ctx
->outer_context
;
14654 var
= create_tmp_var (TREE_TYPE (decl
), get_name (decl
));
14655 gimplify_omp_ctxp
= ctx
;
14656 omp_add_variable (gimplify_omp_ctxp
, var
, GOVD_PRIVATE
| GOVD_SEEN
);
14657 TREE_OPERAND (t
, 0) = var
;
14658 t
= TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
);
14659 TREE_OPERAND (t
, 1) = copy_node (TREE_OPERAND (t
, 1));
14660 TREE_OPERAND (TREE_OPERAND (t
, 1), 0) = var
;
14661 if (OMP_FOR_NON_RECTANGULAR (for_stmt
))
14662 for (int j
= i
+ 1;
14663 j
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); j
++)
14665 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), j
);
14666 gcc_assert (TREE_CODE (t
) == MODIFY_EXPR
);
14667 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
14668 && TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) == decl
)
14670 TREE_OPERAND (t
, 1) = copy_node (TREE_OPERAND (t
, 1));
14671 TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) = var
;
14673 t
= TREE_VEC_ELT (OMP_FOR_COND (for_stmt
), j
);
14674 gcc_assert (COMPARISON_CLASS_P (t
));
14675 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
14676 && TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) == decl
)
14678 TREE_OPERAND (t
, 1) = copy_node (TREE_OPERAND (t
, 1));
14679 TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) = var
;
14684 gimplify_adjust_omp_clauses (pre_p
, for_body
,
14685 &OMP_FOR_CLAUSES (orig_for_stmt
),
14686 TREE_CODE (orig_for_stmt
));
14689 switch (TREE_CODE (orig_for_stmt
))
14691 case OMP_FOR
: kind
= GF_OMP_FOR_KIND_FOR
; break;
14692 case OMP_SIMD
: kind
= GF_OMP_FOR_KIND_SIMD
; break;
14693 case OMP_DISTRIBUTE
: kind
= GF_OMP_FOR_KIND_DISTRIBUTE
; break;
14694 case OMP_TASKLOOP
: kind
= GF_OMP_FOR_KIND_TASKLOOP
; break;
14695 case OACC_LOOP
: kind
= GF_OMP_FOR_KIND_OACC_LOOP
; break;
14697 gcc_unreachable ();
14699 if (loop_p
&& kind
== GF_OMP_FOR_KIND_SIMD
)
14701 gimplify_seq_add_seq (pre_p
, for_pre_body
);
14702 for_pre_body
= NULL
;
14704 gfor
= gimple_build_omp_for (for_body
, kind
, OMP_FOR_CLAUSES (orig_for_stmt
),
14705 TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)),
14707 if (orig_for_stmt
!= for_stmt
)
14708 gimple_omp_for_set_combined_p (gfor
, true);
14709 if (gimplify_omp_ctxp
14710 && (gimplify_omp_ctxp
->combined_loop
14711 || (gimplify_omp_ctxp
->region_type
== ORT_COMBINED_PARALLEL
14712 && gimplify_omp_ctxp
->outer_context
14713 && gimplify_omp_ctxp
->outer_context
->combined_loop
)))
14715 gimple_omp_for_set_combined_into_p (gfor
, true);
14716 if (gimplify_omp_ctxp
->combined_loop
)
14717 gcc_assert (TREE_CODE (orig_for_stmt
) == OMP_SIMD
);
14719 gcc_assert (TREE_CODE (orig_for_stmt
) == OMP_FOR
);
14722 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
14724 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), i
);
14725 gimple_omp_for_set_index (gfor
, i
, TREE_OPERAND (t
, 0));
14726 gimple_omp_for_set_initial (gfor
, i
, TREE_OPERAND (t
, 1));
14727 t
= TREE_VEC_ELT (OMP_FOR_COND (for_stmt
), i
);
14728 gimple_omp_for_set_cond (gfor
, i
, TREE_CODE (t
));
14729 gimple_omp_for_set_final (gfor
, i
, TREE_OPERAND (t
, 1));
14730 t
= TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
);
14731 gimple_omp_for_set_incr (gfor
, i
, TREE_OPERAND (t
, 1));
14734 /* OMP_TASKLOOP is gimplified as two GIMPLE_OMP_FOR taskloop
14735 constructs with GIMPLE_OMP_TASK sandwiched in between them.
14736 The outer taskloop stands for computing the number of iterations,
14737 counts for collapsed loops and holding taskloop specific clauses.
14738 The task construct stands for the effect of data sharing on the
14739 explicit task it creates and the inner taskloop stands for expansion
14740 of the static loop inside of the explicit task construct. */
14741 if (TREE_CODE (orig_for_stmt
) == OMP_TASKLOOP
)
14743 tree
*gfor_clauses_ptr
= gimple_omp_for_clauses_ptr (gfor
);
14744 tree task_clauses
= NULL_TREE
;
14745 tree c
= *gfor_clauses_ptr
;
14746 tree
*gtask_clauses_ptr
= &task_clauses
;
14747 tree outer_for_clauses
= NULL_TREE
;
14748 tree
*gforo_clauses_ptr
= &outer_for_clauses
;
14749 bitmap lastprivate_uids
= NULL
;
14750 if (omp_find_clause (c
, OMP_CLAUSE_ALLOCATE
))
14752 c
= omp_find_clause (c
, OMP_CLAUSE_LASTPRIVATE
);
14755 lastprivate_uids
= BITMAP_ALLOC (NULL
);
14756 for (; c
; c
= omp_find_clause (OMP_CLAUSE_CHAIN (c
),
14757 OMP_CLAUSE_LASTPRIVATE
))
14758 bitmap_set_bit (lastprivate_uids
,
14759 DECL_UID (OMP_CLAUSE_DECL (c
)));
14761 c
= *gfor_clauses_ptr
;
14763 for (; c
; c
= OMP_CLAUSE_CHAIN (c
))
14764 switch (OMP_CLAUSE_CODE (c
))
14766 /* These clauses are allowed on task, move them there. */
14767 case OMP_CLAUSE_SHARED
:
14768 case OMP_CLAUSE_FIRSTPRIVATE
:
14769 case OMP_CLAUSE_DEFAULT
:
14770 case OMP_CLAUSE_IF
:
14771 case OMP_CLAUSE_UNTIED
:
14772 case OMP_CLAUSE_FINAL
:
14773 case OMP_CLAUSE_MERGEABLE
:
14774 case OMP_CLAUSE_PRIORITY
:
14775 case OMP_CLAUSE_REDUCTION
:
14776 case OMP_CLAUSE_IN_REDUCTION
:
14777 *gtask_clauses_ptr
= c
;
14778 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
14780 case OMP_CLAUSE_PRIVATE
:
14781 if (OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c
))
14783 /* We want private on outer for and firstprivate
14786 = build_omp_clause (OMP_CLAUSE_LOCATION (c
),
14787 OMP_CLAUSE_FIRSTPRIVATE
);
14788 OMP_CLAUSE_DECL (*gtask_clauses_ptr
) = OMP_CLAUSE_DECL (c
);
14789 lang_hooks
.decls
.omp_finish_clause (*gtask_clauses_ptr
, NULL
,
14791 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr
);
14792 *gforo_clauses_ptr
= c
;
14793 gforo_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
14797 *gtask_clauses_ptr
= c
;
14798 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
14801 /* These clauses go into outer taskloop clauses. */
14802 case OMP_CLAUSE_GRAINSIZE
:
14803 case OMP_CLAUSE_NUM_TASKS
:
14804 case OMP_CLAUSE_NOGROUP
:
14805 *gforo_clauses_ptr
= c
;
14806 gforo_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
14808 /* Collapse clause we duplicate on both taskloops. */
14809 case OMP_CLAUSE_COLLAPSE
:
14810 *gfor_clauses_ptr
= c
;
14811 gfor_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
14812 *gforo_clauses_ptr
= copy_node (c
);
14813 gforo_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr
);
14815 /* For lastprivate, keep the clause on inner taskloop, and add
14816 a shared clause on task. If the same decl is also firstprivate,
14817 add also firstprivate clause on the inner taskloop. */
14818 case OMP_CLAUSE_LASTPRIVATE
:
14819 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c
))
14821 /* For taskloop C++ lastprivate IVs, we want:
14822 1) private on outer taskloop
14823 2) firstprivate and shared on task
14824 3) lastprivate on inner taskloop */
14826 = build_omp_clause (OMP_CLAUSE_LOCATION (c
),
14827 OMP_CLAUSE_FIRSTPRIVATE
);
14828 OMP_CLAUSE_DECL (*gtask_clauses_ptr
) = OMP_CLAUSE_DECL (c
);
14829 lang_hooks
.decls
.omp_finish_clause (*gtask_clauses_ptr
, NULL
,
14831 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr
);
14832 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
) = 1;
14833 *gforo_clauses_ptr
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
14834 OMP_CLAUSE_PRIVATE
);
14835 OMP_CLAUSE_DECL (*gforo_clauses_ptr
) = OMP_CLAUSE_DECL (c
);
14836 OMP_CLAUSE_PRIVATE_TASKLOOP_IV (*gforo_clauses_ptr
) = 1;
14837 TREE_TYPE (*gforo_clauses_ptr
) = TREE_TYPE (c
);
14838 gforo_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr
);
14840 *gfor_clauses_ptr
= c
;
14841 gfor_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
14843 = build_omp_clause (OMP_CLAUSE_LOCATION (c
), OMP_CLAUSE_SHARED
);
14844 OMP_CLAUSE_DECL (*gtask_clauses_ptr
) = OMP_CLAUSE_DECL (c
);
14845 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
))
14846 OMP_CLAUSE_SHARED_FIRSTPRIVATE (*gtask_clauses_ptr
) = 1;
14848 = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr
);
14850 /* Allocate clause we duplicate on task and inner taskloop
14851 if the decl is lastprivate, otherwise just put on task. */
14852 case OMP_CLAUSE_ALLOCATE
:
14853 if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
)
14854 && DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
)))
14856 /* Additionally, put firstprivate clause on task
14857 for the allocator if it is not constant. */
14859 = build_omp_clause (OMP_CLAUSE_LOCATION (c
),
14860 OMP_CLAUSE_FIRSTPRIVATE
);
14861 OMP_CLAUSE_DECL (*gtask_clauses_ptr
)
14862 = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
);
14863 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr
);
14865 if (lastprivate_uids
14866 && bitmap_bit_p (lastprivate_uids
,
14867 DECL_UID (OMP_CLAUSE_DECL (c
))))
14869 *gfor_clauses_ptr
= c
;
14870 gfor_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
14871 *gtask_clauses_ptr
= copy_node (c
);
14872 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr
);
14876 *gtask_clauses_ptr
= c
;
14877 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
14881 gcc_unreachable ();
14883 *gfor_clauses_ptr
= NULL_TREE
;
14884 *gtask_clauses_ptr
= NULL_TREE
;
14885 *gforo_clauses_ptr
= NULL_TREE
;
14886 BITMAP_FREE (lastprivate_uids
);
14887 gimple_set_location (gfor
, input_location
);
14888 g
= gimple_build_bind (NULL_TREE
, gfor
, NULL_TREE
);
14889 g
= gimple_build_omp_task (g
, task_clauses
, NULL_TREE
, NULL_TREE
,
14890 NULL_TREE
, NULL_TREE
, NULL_TREE
);
14891 gimple_set_location (g
, input_location
);
14892 gimple_omp_task_set_taskloop_p (g
, true);
14893 g
= gimple_build_bind (NULL_TREE
, g
, NULL_TREE
);
14895 = gimple_build_omp_for (g
, GF_OMP_FOR_KIND_TASKLOOP
, outer_for_clauses
,
14896 gimple_omp_for_collapse (gfor
),
14897 gimple_omp_for_pre_body (gfor
));
14898 gimple_omp_for_set_pre_body (gfor
, NULL
);
14899 gimple_omp_for_set_combined_p (gforo
, true);
14900 gimple_omp_for_set_combined_into_p (gfor
, true);
14901 for (i
= 0; i
< (int) gimple_omp_for_collapse (gfor
); i
++)
14903 tree type
= TREE_TYPE (gimple_omp_for_index (gfor
, i
));
14904 tree v
= create_tmp_var (type
);
14905 gimple_omp_for_set_index (gforo
, i
, v
);
14906 t
= unshare_expr (gimple_omp_for_initial (gfor
, i
));
14907 gimple_omp_for_set_initial (gforo
, i
, t
);
14908 gimple_omp_for_set_cond (gforo
, i
,
14909 gimple_omp_for_cond (gfor
, i
));
14910 t
= unshare_expr (gimple_omp_for_final (gfor
, i
));
14911 gimple_omp_for_set_final (gforo
, i
, t
);
14912 t
= unshare_expr (gimple_omp_for_incr (gfor
, i
));
14913 gcc_assert (TREE_OPERAND (t
, 0) == gimple_omp_for_index (gfor
, i
));
14914 TREE_OPERAND (t
, 0) = v
;
14915 gimple_omp_for_set_incr (gforo
, i
, t
);
14916 t
= build_omp_clause (input_location
, OMP_CLAUSE_PRIVATE
);
14917 OMP_CLAUSE_DECL (t
) = v
;
14918 OMP_CLAUSE_CHAIN (t
) = gimple_omp_for_clauses (gforo
);
14919 gimple_omp_for_set_clauses (gforo
, t
);
14920 if (OMP_FOR_NON_RECTANGULAR (for_stmt
))
14922 tree
*p1
= NULL
, *p2
= NULL
;
14923 t
= gimple_omp_for_initial (gforo
, i
);
14924 if (TREE_CODE (t
) == TREE_VEC
)
14925 p1
= &TREE_VEC_ELT (t
, 0);
14926 t
= gimple_omp_for_final (gforo
, i
);
14927 if (TREE_CODE (t
) == TREE_VEC
)
14930 p2
= &TREE_VEC_ELT (t
, 0);
14932 p1
= &TREE_VEC_ELT (t
, 0);
14937 for (j
= 0; j
< i
; j
++)
14938 if (*p1
== gimple_omp_for_index (gfor
, j
))
14940 *p1
= gimple_omp_for_index (gforo
, j
);
14945 gcc_assert (j
< i
);
14949 gimplify_seq_add_stmt (pre_p
, gforo
);
14952 gimplify_seq_add_stmt (pre_p
, gfor
);
14954 if (TREE_CODE (orig_for_stmt
) == OMP_FOR
)
14956 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
14957 unsigned lastprivate_conditional
= 0;
14959 && (ctx
->region_type
== ORT_TARGET_DATA
14960 || ctx
->region_type
== ORT_TASKGROUP
))
14961 ctx
= ctx
->outer_context
;
14962 if (ctx
&& (ctx
->region_type
& ORT_PARALLEL
) != 0)
14963 for (tree c
= gimple_omp_for_clauses (gfor
);
14964 c
; c
= OMP_CLAUSE_CHAIN (c
))
14965 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
14966 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
))
14967 ++lastprivate_conditional
;
14968 if (lastprivate_conditional
)
14970 struct omp_for_data fd
;
14971 omp_extract_for_data (gfor
, &fd
, NULL
);
14972 tree type
= build_array_type_nelts (unsigned_type_for (fd
.iter_type
),
14973 lastprivate_conditional
);
14974 tree var
= create_tmp_var_raw (type
);
14975 tree c
= build_omp_clause (UNKNOWN_LOCATION
, OMP_CLAUSE__CONDTEMP_
);
14976 OMP_CLAUSE_DECL (c
) = var
;
14977 OMP_CLAUSE_CHAIN (c
) = gimple_omp_for_clauses (gfor
);
14978 gimple_omp_for_set_clauses (gfor
, c
);
14979 omp_add_variable (ctx
, var
, GOVD_CONDTEMP
| GOVD_SEEN
);
14982 else if (TREE_CODE (orig_for_stmt
) == OMP_SIMD
)
14984 unsigned lastprivate_conditional
= 0;
14985 for (tree c
= gimple_omp_for_clauses (gfor
); c
; c
= OMP_CLAUSE_CHAIN (c
))
14986 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
14987 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
))
14988 ++lastprivate_conditional
;
14989 if (lastprivate_conditional
)
14991 struct omp_for_data fd
;
14992 omp_extract_for_data (gfor
, &fd
, NULL
);
14993 tree type
= unsigned_type_for (fd
.iter_type
);
14994 while (lastprivate_conditional
--)
14996 tree c
= build_omp_clause (UNKNOWN_LOCATION
,
14997 OMP_CLAUSE__CONDTEMP_
);
14998 OMP_CLAUSE_DECL (c
) = create_tmp_var (type
);
14999 OMP_CLAUSE_CHAIN (c
) = gimple_omp_for_clauses (gfor
);
15000 gimple_omp_for_set_clauses (gfor
, c
);
15005 if (ret
!= GS_ALL_DONE
)
15007 *expr_p
= NULL_TREE
;
15008 return GS_ALL_DONE
;
15011 /* Helper for gimplify_omp_loop, called through walk_tree. */
15014 note_no_context_vars (tree
*tp
, int *, void *data
)
15017 && DECL_CONTEXT (*tp
) == NULL_TREE
15018 && !is_global_var (*tp
))
15020 vec
<tree
> *d
= (vec
<tree
> *) data
;
15021 d
->safe_push (*tp
);
15022 DECL_CONTEXT (*tp
) = current_function_decl
;
15027 /* Gimplify the gross structure of an OMP_LOOP statement. */
15029 static enum gimplify_status
15030 gimplify_omp_loop (tree
*expr_p
, gimple_seq
*pre_p
)
15032 tree for_stmt
= *expr_p
;
15033 tree clauses
= OMP_FOR_CLAUSES (for_stmt
);
15034 struct gimplify_omp_ctx
*octx
= gimplify_omp_ctxp
;
15035 enum omp_clause_bind_kind kind
= OMP_CLAUSE_BIND_THREAD
;
15038 /* If order is not present, the behavior is as if order(concurrent)
15040 tree order
= omp_find_clause (clauses
, OMP_CLAUSE_ORDER
);
15041 if (order
== NULL_TREE
)
15043 order
= build_omp_clause (UNKNOWN_LOCATION
, OMP_CLAUSE_ORDER
);
15044 OMP_CLAUSE_CHAIN (order
) = clauses
;
15045 OMP_FOR_CLAUSES (for_stmt
) = clauses
= order
;
15048 tree bind
= omp_find_clause (clauses
, OMP_CLAUSE_BIND
);
15049 if (bind
== NULL_TREE
)
15051 if (!flag_openmp
) /* flag_openmp_simd */
15053 else if (octx
&& (octx
->region_type
& ORT_TEAMS
) != 0)
15054 kind
= OMP_CLAUSE_BIND_TEAMS
;
15055 else if (octx
&& (octx
->region_type
& ORT_PARALLEL
) != 0)
15056 kind
= OMP_CLAUSE_BIND_PARALLEL
;
15059 for (; octx
; octx
= octx
->outer_context
)
15061 if ((octx
->region_type
& ORT_ACC
) != 0
15062 || octx
->region_type
== ORT_NONE
15063 || octx
->region_type
== ORT_IMPLICIT_TARGET
)
15067 if (octx
== NULL
&& !in_omp_construct
)
15068 error_at (EXPR_LOCATION (for_stmt
),
15069 "%<bind%> clause not specified on a %<loop%> "
15070 "construct not nested inside another OpenMP construct");
15072 bind
= build_omp_clause (UNKNOWN_LOCATION
, OMP_CLAUSE_BIND
);
15073 OMP_CLAUSE_CHAIN (bind
) = clauses
;
15074 OMP_CLAUSE_BIND_KIND (bind
) = kind
;
15075 OMP_FOR_CLAUSES (for_stmt
) = bind
;
15078 switch (OMP_CLAUSE_BIND_KIND (bind
))
15080 case OMP_CLAUSE_BIND_THREAD
:
15082 case OMP_CLAUSE_BIND_PARALLEL
:
15083 if (!flag_openmp
) /* flag_openmp_simd */
15085 OMP_CLAUSE_BIND_KIND (bind
) = OMP_CLAUSE_BIND_THREAD
;
15088 for (; octx
; octx
= octx
->outer_context
)
15089 if (octx
->region_type
== ORT_SIMD
15090 && omp_find_clause (octx
->clauses
, OMP_CLAUSE_BIND
) == NULL_TREE
)
15092 error_at (EXPR_LOCATION (for_stmt
),
15093 "%<bind(parallel)%> on a %<loop%> construct nested "
15094 "inside %<simd%> construct");
15095 OMP_CLAUSE_BIND_KIND (bind
) = OMP_CLAUSE_BIND_THREAD
;
15098 kind
= OMP_CLAUSE_BIND_PARALLEL
;
15100 case OMP_CLAUSE_BIND_TEAMS
:
15101 if (!flag_openmp
) /* flag_openmp_simd */
15103 OMP_CLAUSE_BIND_KIND (bind
) = OMP_CLAUSE_BIND_THREAD
;
15107 && octx
->region_type
!= ORT_IMPLICIT_TARGET
15108 && octx
->region_type
!= ORT_NONE
15109 && (octx
->region_type
& ORT_TEAMS
) == 0)
15110 || in_omp_construct
)
15112 error_at (EXPR_LOCATION (for_stmt
),
15113 "%<bind(teams)%> on a %<loop%> region not strictly "
15114 "nested inside of a %<teams%> region");
15115 OMP_CLAUSE_BIND_KIND (bind
) = OMP_CLAUSE_BIND_THREAD
;
15118 kind
= OMP_CLAUSE_BIND_TEAMS
;
15121 gcc_unreachable ();
15124 for (tree
*pc
= &OMP_FOR_CLAUSES (for_stmt
); *pc
; )
15125 switch (OMP_CLAUSE_CODE (*pc
))
15127 case OMP_CLAUSE_REDUCTION
:
15128 if (OMP_CLAUSE_REDUCTION_INSCAN (*pc
))
15130 error_at (OMP_CLAUSE_LOCATION (*pc
),
15131 "%<inscan%> %<reduction%> clause on "
15132 "%qs construct", "loop");
15133 OMP_CLAUSE_REDUCTION_INSCAN (*pc
) = 0;
15135 if (OMP_CLAUSE_REDUCTION_TASK (*pc
))
15137 error_at (OMP_CLAUSE_LOCATION (*pc
),
15138 "invalid %<task%> reduction modifier on construct "
15139 "other than %<parallel%>, %qs or %<sections%>",
15140 lang_GNU_Fortran () ? "do" : "for");
15141 OMP_CLAUSE_REDUCTION_TASK (*pc
) = 0;
15143 pc
= &OMP_CLAUSE_CHAIN (*pc
);
15145 case OMP_CLAUSE_LASTPRIVATE
:
15146 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
15148 tree t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), i
);
15149 gcc_assert (TREE_CODE (t
) == MODIFY_EXPR
);
15150 if (OMP_CLAUSE_DECL (*pc
) == TREE_OPERAND (t
, 0))
15152 if (OMP_FOR_ORIG_DECLS (for_stmt
)
15153 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
),
15155 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
),
15158 tree orig
= TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
), i
);
15159 if (OMP_CLAUSE_DECL (*pc
) == TREE_PURPOSE (orig
))
15163 if (i
== TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)))
15165 error_at (OMP_CLAUSE_LOCATION (*pc
),
15166 "%<lastprivate%> clause on a %<loop%> construct refers "
15167 "to a variable %qD which is not the loop iterator",
15168 OMP_CLAUSE_DECL (*pc
));
15169 *pc
= OMP_CLAUSE_CHAIN (*pc
);
15172 pc
= &OMP_CLAUSE_CHAIN (*pc
);
15175 pc
= &OMP_CLAUSE_CHAIN (*pc
);
15179 TREE_SET_CODE (for_stmt
, OMP_SIMD
);
15184 case OMP_CLAUSE_BIND_THREAD
: last
= 0; break;
15185 case OMP_CLAUSE_BIND_PARALLEL
: last
= 1; break;
15186 case OMP_CLAUSE_BIND_TEAMS
: last
= 2; break;
15188 for (int pass
= 1; pass
<= last
; pass
++)
15192 tree bind
= build3 (BIND_EXPR
, void_type_node
, NULL
, NULL
,
15193 make_node (BLOCK
));
15194 append_to_statement_list (*expr_p
, &BIND_EXPR_BODY (bind
));
15195 *expr_p
= make_node (OMP_PARALLEL
);
15196 TREE_TYPE (*expr_p
) = void_type_node
;
15197 OMP_PARALLEL_BODY (*expr_p
) = bind
;
15198 OMP_PARALLEL_COMBINED (*expr_p
) = 1;
15199 SET_EXPR_LOCATION (*expr_p
, EXPR_LOCATION (for_stmt
));
15200 tree
*pc
= &OMP_PARALLEL_CLAUSES (*expr_p
);
15201 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
15202 if (OMP_FOR_ORIG_DECLS (for_stmt
)
15203 && (TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
), i
))
15206 tree elt
= TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
), i
);
15207 if (TREE_PURPOSE (elt
) && TREE_VALUE (elt
))
15209 *pc
= build_omp_clause (UNKNOWN_LOCATION
,
15210 OMP_CLAUSE_FIRSTPRIVATE
);
15211 OMP_CLAUSE_DECL (*pc
) = TREE_VALUE (elt
);
15212 pc
= &OMP_CLAUSE_CHAIN (*pc
);
15216 tree t
= make_node (pass
== 2 ? OMP_DISTRIBUTE
: OMP_FOR
);
15217 tree
*pc
= &OMP_FOR_CLAUSES (t
);
15218 TREE_TYPE (t
) = void_type_node
;
15219 OMP_FOR_BODY (t
) = *expr_p
;
15220 SET_EXPR_LOCATION (t
, EXPR_LOCATION (for_stmt
));
15221 for (tree c
= OMP_FOR_CLAUSES (for_stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
15222 switch (OMP_CLAUSE_CODE (c
))
15224 case OMP_CLAUSE_BIND
:
15225 case OMP_CLAUSE_ORDER
:
15226 case OMP_CLAUSE_COLLAPSE
:
15227 *pc
= copy_node (c
);
15228 pc
= &OMP_CLAUSE_CHAIN (*pc
);
15230 case OMP_CLAUSE_PRIVATE
:
15231 case OMP_CLAUSE_FIRSTPRIVATE
:
15232 /* Only needed on innermost. */
15234 case OMP_CLAUSE_LASTPRIVATE
:
15235 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c
) && pass
!= last
)
15237 *pc
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
15238 OMP_CLAUSE_FIRSTPRIVATE
);
15239 OMP_CLAUSE_DECL (*pc
) = OMP_CLAUSE_DECL (c
);
15240 lang_hooks
.decls
.omp_finish_clause (*pc
, NULL
, false);
15241 pc
= &OMP_CLAUSE_CHAIN (*pc
);
15243 *pc
= copy_node (c
);
15244 OMP_CLAUSE_LASTPRIVATE_STMT (*pc
) = NULL_TREE
;
15245 TREE_TYPE (*pc
) = unshare_expr (TREE_TYPE (c
));
15246 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c
))
15249 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (*pc
) = 1;
15251 lang_hooks
.decls
.omp_finish_clause (*pc
, NULL
, false);
15252 OMP_CLAUSE_LASTPRIVATE_LOOP_IV (*pc
) = 0;
15254 pc
= &OMP_CLAUSE_CHAIN (*pc
);
15256 case OMP_CLAUSE_REDUCTION
:
15257 *pc
= copy_node (c
);
15258 OMP_CLAUSE_DECL (*pc
) = unshare_expr (OMP_CLAUSE_DECL (c
));
15259 TREE_TYPE (*pc
) = unshare_expr (TREE_TYPE (c
));
15260 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc
))
15262 auto_vec
<tree
> no_context_vars
;
15263 int walk_subtrees
= 0;
15264 note_no_context_vars (&OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
),
15265 &walk_subtrees
, &no_context_vars
);
15266 if (tree p
= OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c
))
15267 note_no_context_vars (&p
, &walk_subtrees
, &no_context_vars
);
15268 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_INIT (c
),
15269 note_no_context_vars
,
15271 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_MERGE (c
),
15272 note_no_context_vars
,
15275 OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc
)
15276 = copy_node (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
));
15277 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc
))
15278 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc
)
15279 = copy_node (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c
));
15281 hash_map
<tree
, tree
> decl_map
;
15282 decl_map
.put (OMP_CLAUSE_DECL (c
), OMP_CLAUSE_DECL (c
));
15283 decl_map
.put (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
),
15284 OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc
));
15285 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc
))
15286 decl_map
.put (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c
),
15287 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc
));
15290 memset (&id
, 0, sizeof (id
));
15291 id
.src_fn
= current_function_decl
;
15292 id
.dst_fn
= current_function_decl
;
15293 id
.src_cfun
= cfun
;
15294 id
.decl_map
= &decl_map
;
15295 id
.copy_decl
= copy_decl_no_change
;
15296 id
.transform_call_graph_edges
= CB_CGE_DUPLICATE
;
15297 id
.transform_new_cfg
= true;
15298 id
.transform_return_to_modify
= false;
15300 walk_tree (&OMP_CLAUSE_REDUCTION_INIT (*pc
), copy_tree_body_r
,
15302 walk_tree (&OMP_CLAUSE_REDUCTION_MERGE (*pc
), copy_tree_body_r
,
15305 for (tree d
: no_context_vars
)
15307 DECL_CONTEXT (d
) = NULL_TREE
;
15308 DECL_CONTEXT (*decl_map
.get (d
)) = NULL_TREE
;
15313 OMP_CLAUSE_REDUCTION_INIT (*pc
)
15314 = unshare_expr (OMP_CLAUSE_REDUCTION_INIT (c
));
15315 OMP_CLAUSE_REDUCTION_MERGE (*pc
)
15316 = unshare_expr (OMP_CLAUSE_REDUCTION_MERGE (c
));
15318 pc
= &OMP_CLAUSE_CHAIN (*pc
);
15321 gcc_unreachable ();
15326 return gimplify_expr (expr_p
, pre_p
, NULL
, is_gimple_stmt
, fb_none
);
15330 /* Helper function of optimize_target_teams, find OMP_TEAMS inside
15331 of OMP_TARGET's body. */
15334 find_omp_teams (tree
*tp
, int *walk_subtrees
, void *)
15336 *walk_subtrees
= 0;
15337 switch (TREE_CODE (*tp
))
15342 case STATEMENT_LIST
:
15343 *walk_subtrees
= 1;
15351 /* Helper function of optimize_target_teams, determine if the expression
15352 can be computed safely before the target construct on the host. */
15355 computable_teams_clause (tree
*tp
, int *walk_subtrees
, void *)
15361 *walk_subtrees
= 0;
15364 switch (TREE_CODE (*tp
))
15369 *walk_subtrees
= 0;
15370 if (error_operand_p (*tp
)
15371 || !INTEGRAL_TYPE_P (TREE_TYPE (*tp
))
15372 || DECL_HAS_VALUE_EXPR_P (*tp
)
15373 || DECL_THREAD_LOCAL_P (*tp
)
15374 || TREE_SIDE_EFFECTS (*tp
)
15375 || TREE_THIS_VOLATILE (*tp
))
15377 if (is_global_var (*tp
)
15378 && (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (*tp
))
15379 || lookup_attribute ("omp declare target link",
15380 DECL_ATTRIBUTES (*tp
))))
15383 && !DECL_SEEN_IN_BIND_EXPR_P (*tp
)
15384 && !is_global_var (*tp
)
15385 && decl_function_context (*tp
) == current_function_decl
)
15387 n
= splay_tree_lookup (gimplify_omp_ctxp
->variables
,
15388 (splay_tree_key
) *tp
);
15391 if (gimplify_omp_ctxp
->defaultmap
[GDMK_SCALAR
] & GOVD_FIRSTPRIVATE
)
15395 else if (n
->value
& GOVD_LOCAL
)
15397 else if (n
->value
& GOVD_FIRSTPRIVATE
)
15399 else if ((n
->value
& (GOVD_MAP
| GOVD_MAP_ALWAYS_TO
))
15400 == (GOVD_MAP
| GOVD_MAP_ALWAYS_TO
))
15404 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp
)))
15408 if (TARGET_EXPR_INITIAL (*tp
)
15409 || TREE_CODE (TARGET_EXPR_SLOT (*tp
)) != VAR_DECL
)
15411 return computable_teams_clause (&TARGET_EXPR_SLOT (*tp
),
15412 walk_subtrees
, NULL
);
15413 /* Allow some reasonable subset of integral arithmetics. */
15417 case TRUNC_DIV_EXPR
:
15418 case CEIL_DIV_EXPR
:
15419 case FLOOR_DIV_EXPR
:
15420 case ROUND_DIV_EXPR
:
15421 case TRUNC_MOD_EXPR
:
15422 case CEIL_MOD_EXPR
:
15423 case FLOOR_MOD_EXPR
:
15424 case ROUND_MOD_EXPR
:
15426 case EXACT_DIV_EXPR
:
15437 case NON_LVALUE_EXPR
:
15439 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp
)))
15442 /* And disallow anything else, except for comparisons. */
15444 if (COMPARISON_CLASS_P (*tp
))
15450 /* Try to determine if the num_teams and/or thread_limit expressions
15451 can have their values determined already before entering the
15453 INTEGER_CSTs trivially are,
15454 integral decls that are firstprivate (explicitly or implicitly)
15455 or explicitly map(always, to:) or map(always, tofrom:) on the target
15456 region too, and expressions involving simple arithmetics on those
15457 too, function calls are not ok, dereferencing something neither etc.
15458 Add NUM_TEAMS and THREAD_LIMIT clauses to the OMP_CLAUSES of
15459 EXPR based on what we find:
15460 0 stands for clause not specified at all, use implementation default
15461 -1 stands for value that can't be determined easily before entering
15462 the target construct.
15463 -2 means that no explicit teams construct was specified
15464 If teams construct is not present at all, use 1 for num_teams
15465 and 0 for thread_limit (only one team is involved, and the thread
15466 limit is implementation defined. */
15469 optimize_target_teams (tree target
, gimple_seq
*pre_p
)
15471 tree body
= OMP_BODY (target
);
15472 tree teams
= walk_tree (&body
, find_omp_teams
, NULL
, NULL
);
15473 tree num_teams_lower
= NULL_TREE
;
15474 tree num_teams_upper
= integer_zero_node
;
15475 tree thread_limit
= integer_zero_node
;
15476 location_t num_teams_loc
= EXPR_LOCATION (target
);
15477 location_t thread_limit_loc
= EXPR_LOCATION (target
);
15479 struct gimplify_omp_ctx
*target_ctx
= gimplify_omp_ctxp
;
15481 if (teams
== NULL_TREE
)
15482 num_teams_upper
= build_int_cst (integer_type_node
, -2);
15484 for (c
= OMP_TEAMS_CLAUSES (teams
); c
; c
= OMP_CLAUSE_CHAIN (c
))
15486 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_NUM_TEAMS
)
15488 p
= &num_teams_upper
;
15489 num_teams_loc
= OMP_CLAUSE_LOCATION (c
);
15490 if (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c
))
15492 expr
= OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c
);
15493 if (TREE_CODE (expr
) == INTEGER_CST
)
15494 num_teams_lower
= expr
;
15495 else if (walk_tree (&expr
, computable_teams_clause
,
15497 num_teams_lower
= integer_minus_one_node
;
15500 num_teams_lower
= expr
;
15501 gimplify_omp_ctxp
= gimplify_omp_ctxp
->outer_context
;
15502 if (gimplify_expr (&num_teams_lower
, pre_p
, NULL
,
15503 is_gimple_val
, fb_rvalue
, false)
15506 gimplify_omp_ctxp
= target_ctx
;
15507 num_teams_lower
= integer_minus_one_node
;
15511 gimplify_omp_ctxp
= target_ctx
;
15512 if (!DECL_P (expr
) && TREE_CODE (expr
) != TARGET_EXPR
)
15513 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c
)
15519 else if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_THREAD_LIMIT
)
15522 thread_limit_loc
= OMP_CLAUSE_LOCATION (c
);
15526 expr
= OMP_CLAUSE_OPERAND (c
, 0);
15527 if (TREE_CODE (expr
) == INTEGER_CST
)
15532 if (walk_tree (&expr
, computable_teams_clause
, NULL
, NULL
))
15534 *p
= integer_minus_one_node
;
15538 gimplify_omp_ctxp
= gimplify_omp_ctxp
->outer_context
;
15539 if (gimplify_expr (p
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
, false)
15542 gimplify_omp_ctxp
= target_ctx
;
15543 *p
= integer_minus_one_node
;
15546 gimplify_omp_ctxp
= target_ctx
;
15547 if (!DECL_P (expr
) && TREE_CODE (expr
) != TARGET_EXPR
)
15548 OMP_CLAUSE_OPERAND (c
, 0) = *p
;
15550 if (!omp_find_clause (OMP_TARGET_CLAUSES (target
), OMP_CLAUSE_THREAD_LIMIT
))
15552 c
= build_omp_clause (thread_limit_loc
, OMP_CLAUSE_THREAD_LIMIT
);
15553 OMP_CLAUSE_THREAD_LIMIT_EXPR (c
) = thread_limit
;
15554 OMP_CLAUSE_CHAIN (c
) = OMP_TARGET_CLAUSES (target
);
15555 OMP_TARGET_CLAUSES (target
) = c
;
15557 c
= build_omp_clause (num_teams_loc
, OMP_CLAUSE_NUM_TEAMS
);
15558 OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c
) = num_teams_upper
;
15559 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c
) = num_teams_lower
;
15560 OMP_CLAUSE_CHAIN (c
) = OMP_TARGET_CLAUSES (target
);
15561 OMP_TARGET_CLAUSES (target
) = c
;
15564 /* Gimplify the gross structure of several OMP constructs. */
15567 gimplify_omp_workshare (tree
*expr_p
, gimple_seq
*pre_p
)
15569 tree expr
= *expr_p
;
15571 gimple_seq body
= NULL
;
15572 enum omp_region_type ort
;
15574 switch (TREE_CODE (expr
))
15578 ort
= ORT_WORKSHARE
;
15581 ort
= ORT_TASKGROUP
;
15584 ort
= OMP_TARGET_COMBINED (expr
) ? ORT_COMBINED_TARGET
: ORT_TARGET
;
15587 ort
= ORT_ACC_KERNELS
;
15589 case OACC_PARALLEL
:
15590 ort
= ORT_ACC_PARALLEL
;
15593 ort
= ORT_ACC_SERIAL
;
15596 ort
= ORT_ACC_DATA
;
15598 case OMP_TARGET_DATA
:
15599 ort
= ORT_TARGET_DATA
;
15602 ort
= OMP_TEAMS_COMBINED (expr
) ? ORT_COMBINED_TEAMS
: ORT_TEAMS
;
15603 if (gimplify_omp_ctxp
== NULL
15604 || gimplify_omp_ctxp
->region_type
== ORT_IMPLICIT_TARGET
)
15605 ort
= (enum omp_region_type
) (ort
| ORT_HOST_TEAMS
);
15607 case OACC_HOST_DATA
:
15608 ort
= ORT_ACC_HOST_DATA
;
15611 gcc_unreachable ();
15614 bool save_in_omp_construct
= in_omp_construct
;
15615 if ((ort
& ORT_ACC
) == 0)
15616 in_omp_construct
= false;
15617 gimplify_scan_omp_clauses (&OMP_CLAUSES (expr
), pre_p
, ort
,
15619 if (TREE_CODE (expr
) == OMP_TARGET
)
15620 optimize_target_teams (expr
, pre_p
);
15621 if ((ort
& (ORT_TARGET
| ORT_TARGET_DATA
)) != 0
15622 || (ort
& ORT_HOST_TEAMS
) == ORT_HOST_TEAMS
)
15624 push_gimplify_context ();
15625 gimple
*g
= gimplify_and_return_first (OMP_BODY (expr
), &body
);
15626 if (gimple_code (g
) == GIMPLE_BIND
)
15627 pop_gimplify_context (g
);
15629 pop_gimplify_context (NULL
);
15630 if ((ort
& ORT_TARGET_DATA
) != 0)
15632 enum built_in_function end_ix
;
15633 switch (TREE_CODE (expr
))
15636 case OACC_HOST_DATA
:
15637 end_ix
= BUILT_IN_GOACC_DATA_END
;
15639 case OMP_TARGET_DATA
:
15640 end_ix
= BUILT_IN_GOMP_TARGET_END_DATA
;
15643 gcc_unreachable ();
15645 tree fn
= builtin_decl_explicit (end_ix
);
15646 g
= gimple_build_call (fn
, 0);
15647 gimple_seq cleanup
= NULL
;
15648 gimple_seq_add_stmt (&cleanup
, g
);
15649 g
= gimple_build_try (body
, cleanup
, GIMPLE_TRY_FINALLY
);
15651 gimple_seq_add_stmt (&body
, g
);
15655 gimplify_and_add (OMP_BODY (expr
), &body
);
15656 gimplify_adjust_omp_clauses (pre_p
, body
, &OMP_CLAUSES (expr
),
15658 in_omp_construct
= save_in_omp_construct
;
15660 switch (TREE_CODE (expr
))
15663 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_OACC_DATA
,
15664 OMP_CLAUSES (expr
));
15666 case OACC_HOST_DATA
:
15667 if (omp_find_clause (OMP_CLAUSES (expr
), OMP_CLAUSE_IF_PRESENT
))
15669 for (tree c
= OMP_CLAUSES (expr
); c
; c
= OMP_CLAUSE_CHAIN (c
))
15670 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_USE_DEVICE_PTR
)
15671 OMP_CLAUSE_USE_DEVICE_PTR_IF_PRESENT (c
) = 1;
15674 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_OACC_HOST_DATA
,
15675 OMP_CLAUSES (expr
));
15678 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_OACC_KERNELS
,
15679 OMP_CLAUSES (expr
));
15681 case OACC_PARALLEL
:
15682 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_OACC_PARALLEL
,
15683 OMP_CLAUSES (expr
));
15686 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_OACC_SERIAL
,
15687 OMP_CLAUSES (expr
));
15690 stmt
= gimple_build_omp_sections (body
, OMP_CLAUSES (expr
));
15693 stmt
= gimple_build_omp_single (body
, OMP_CLAUSES (expr
));
15696 stmt
= gimple_build_omp_scope (body
, OMP_CLAUSES (expr
));
15699 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_REGION
,
15700 OMP_CLAUSES (expr
));
15702 case OMP_TARGET_DATA
:
15703 /* Put use_device_{ptr,addr} clauses last, as map clauses are supposed
15704 to be evaluated before the use_device_{ptr,addr} clauses if they
15705 refer to the same variables. */
15707 tree use_device_clauses
;
15708 tree
*pc
, *uc
= &use_device_clauses
;
15709 for (pc
= &OMP_CLAUSES (expr
); *pc
; )
15710 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_USE_DEVICE_PTR
15711 || OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_USE_DEVICE_ADDR
)
15714 *pc
= OMP_CLAUSE_CHAIN (*pc
);
15715 uc
= &OMP_CLAUSE_CHAIN (*uc
);
15718 pc
= &OMP_CLAUSE_CHAIN (*pc
);
15720 *pc
= use_device_clauses
;
15721 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_DATA
,
15722 OMP_CLAUSES (expr
));
15726 stmt
= gimple_build_omp_teams (body
, OMP_CLAUSES (expr
));
15727 if ((ort
& ORT_HOST_TEAMS
) == ORT_HOST_TEAMS
)
15728 gimple_omp_teams_set_host (as_a
<gomp_teams
*> (stmt
), true);
15731 gcc_unreachable ();
15734 gimplify_seq_add_stmt (pre_p
, stmt
);
15735 *expr_p
= NULL_TREE
;
15738 /* Gimplify the gross structure of OpenACC enter/exit data, update, and OpenMP
15739 target update constructs. */
15742 gimplify_omp_target_update (tree
*expr_p
, gimple_seq
*pre_p
)
15744 tree expr
= *expr_p
;
15747 enum omp_region_type ort
= ORT_WORKSHARE
;
15749 switch (TREE_CODE (expr
))
15751 case OACC_ENTER_DATA
:
15752 kind
= GF_OMP_TARGET_KIND_OACC_ENTER_DATA
;
15755 case OACC_EXIT_DATA
:
15756 kind
= GF_OMP_TARGET_KIND_OACC_EXIT_DATA
;
15760 kind
= GF_OMP_TARGET_KIND_OACC_UPDATE
;
15763 case OMP_TARGET_UPDATE
:
15764 kind
= GF_OMP_TARGET_KIND_UPDATE
;
15766 case OMP_TARGET_ENTER_DATA
:
15767 kind
= GF_OMP_TARGET_KIND_ENTER_DATA
;
15769 case OMP_TARGET_EXIT_DATA
:
15770 kind
= GF_OMP_TARGET_KIND_EXIT_DATA
;
15773 gcc_unreachable ();
15775 gimplify_scan_omp_clauses (&OMP_STANDALONE_CLAUSES (expr
), pre_p
,
15776 ort
, TREE_CODE (expr
));
15777 gimplify_adjust_omp_clauses (pre_p
, NULL
, &OMP_STANDALONE_CLAUSES (expr
),
15779 if (TREE_CODE (expr
) == OACC_UPDATE
15780 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr
),
15781 OMP_CLAUSE_IF_PRESENT
))
15783 /* The runtime uses GOMP_MAP_{TO,FROM} to denote the if_present
15785 for (tree c
= OMP_STANDALONE_CLAUSES (expr
); c
; c
= OMP_CLAUSE_CHAIN (c
))
15786 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_MAP
)
15787 switch (OMP_CLAUSE_MAP_KIND (c
))
15789 case GOMP_MAP_FORCE_TO
:
15790 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_TO
);
15792 case GOMP_MAP_FORCE_FROM
:
15793 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_FROM
);
15799 else if (TREE_CODE (expr
) == OACC_EXIT_DATA
15800 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr
),
15801 OMP_CLAUSE_FINALIZE
))
15803 /* Use GOMP_MAP_DELETE/GOMP_MAP_FORCE_FROM to denote "finalize"
15805 bool have_clause
= false;
15806 for (tree c
= OMP_STANDALONE_CLAUSES (expr
); c
; c
= OMP_CLAUSE_CHAIN (c
))
15807 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_MAP
)
15808 switch (OMP_CLAUSE_MAP_KIND (c
))
15810 case GOMP_MAP_FROM
:
15811 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_FORCE_FROM
);
15812 have_clause
= true;
15814 case GOMP_MAP_RELEASE
:
15815 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_DELETE
);
15816 have_clause
= true;
15818 case GOMP_MAP_TO_PSET
:
15819 /* Fortran arrays with descriptors must map that descriptor when
15820 doing standalone "attach" operations (in OpenACC). In that
15821 case GOMP_MAP_TO_PSET appears by itself with no preceding
15822 clause (see trans-openmp.cc:gfc_trans_omp_clauses). */
15824 case GOMP_MAP_POINTER
:
15825 /* TODO PR92929: we may see these here, but they'll always follow
15826 one of the clauses above, and will be handled by libgomp as
15827 one group, so no handling required here. */
15828 gcc_assert (have_clause
);
15830 case GOMP_MAP_DETACH
:
15831 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_FORCE_DETACH
);
15832 have_clause
= false;
15834 case GOMP_MAP_STRUCT
:
15835 have_clause
= false;
15838 gcc_unreachable ();
15841 stmt
= gimple_build_omp_target (NULL
, kind
, OMP_STANDALONE_CLAUSES (expr
));
15843 gimplify_seq_add_stmt (pre_p
, stmt
);
15844 *expr_p
= NULL_TREE
;
15847 /* A subroutine of gimplify_omp_atomic. The front end is supposed to have
15848 stabilized the lhs of the atomic operation as *ADDR. Return true if
15849 EXPR is this stabilized form. */
15852 goa_lhs_expr_p (tree expr
, tree addr
)
15854 /* Also include casts to other type variants. The C front end is fond
15855 of adding these for e.g. volatile variables. This is like
15856 STRIP_TYPE_NOPS but includes the main variant lookup. */
15857 STRIP_USELESS_TYPE_CONVERSION (expr
);
15859 if (INDIRECT_REF_P (expr
))
15861 expr
= TREE_OPERAND (expr
, 0);
15862 while (expr
!= addr
15863 && (CONVERT_EXPR_P (expr
)
15864 || TREE_CODE (expr
) == NON_LVALUE_EXPR
)
15865 && TREE_CODE (expr
) == TREE_CODE (addr
)
15866 && types_compatible_p (TREE_TYPE (expr
), TREE_TYPE (addr
)))
15868 expr
= TREE_OPERAND (expr
, 0);
15869 addr
= TREE_OPERAND (addr
, 0);
15873 return (TREE_CODE (addr
) == ADDR_EXPR
15874 && TREE_CODE (expr
) == ADDR_EXPR
15875 && TREE_OPERAND (addr
, 0) == TREE_OPERAND (expr
, 0));
15877 if (TREE_CODE (addr
) == ADDR_EXPR
&& expr
== TREE_OPERAND (addr
, 0))
15882 /* Walk *EXPR_P and replace appearances of *LHS_ADDR with LHS_VAR. If an
15883 expression does not involve the lhs, evaluate it into a temporary.
15884 Return 1 if the lhs appeared as a subexpression, 0 if it did not,
15885 or -1 if an error was encountered. */
15888 goa_stabilize_expr (tree
*expr_p
, gimple_seq
*pre_p
, tree lhs_addr
,
15889 tree lhs_var
, tree
&target_expr
, bool rhs
, int depth
)
15891 tree expr
= *expr_p
;
15894 if (goa_lhs_expr_p (expr
, lhs_addr
))
15900 if (is_gimple_val (expr
))
15903 /* Maximum depth of lhs in expression is for the
15904 __builtin_clear_padding (...), __builtin_clear_padding (...),
15905 __builtin_memcmp (&TARGET_EXPR <lhs, >, ...) == 0 ? ... : lhs; */
15909 switch (TREE_CODE_CLASS (TREE_CODE (expr
)))
15912 case tcc_comparison
:
15913 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 1), pre_p
, lhs_addr
,
15914 lhs_var
, target_expr
, true, depth
);
15917 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 0), pre_p
, lhs_addr
,
15918 lhs_var
, target_expr
, true, depth
);
15920 case tcc_expression
:
15921 switch (TREE_CODE (expr
))
15923 case TRUTH_ANDIF_EXPR
:
15924 case TRUTH_ORIF_EXPR
:
15925 case TRUTH_AND_EXPR
:
15926 case TRUTH_OR_EXPR
:
15927 case TRUTH_XOR_EXPR
:
15928 case BIT_INSERT_EXPR
:
15929 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 1), pre_p
,
15930 lhs_addr
, lhs_var
, target_expr
, true,
15933 case TRUTH_NOT_EXPR
:
15934 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 0), pre_p
,
15935 lhs_addr
, lhs_var
, target_expr
, true,
15939 if (pre_p
&& !goa_stabilize_expr (expr_p
, NULL
, lhs_addr
, lhs_var
,
15940 target_expr
, true, depth
))
15942 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 1), pre_p
,
15943 lhs_addr
, lhs_var
, target_expr
, true,
15945 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 0), pre_p
,
15946 lhs_addr
, lhs_var
, target_expr
, false,
15951 if (pre_p
&& !goa_stabilize_expr (expr_p
, NULL
, lhs_addr
, lhs_var
,
15952 target_expr
, true, depth
))
15954 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 0), pre_p
,
15955 lhs_addr
, lhs_var
, target_expr
, false,
15958 case COMPOUND_EXPR
:
15959 /* Break out any preevaluations from cp_build_modify_expr. */
15960 for (; TREE_CODE (expr
) == COMPOUND_EXPR
;
15961 expr
= TREE_OPERAND (expr
, 1))
15963 /* Special-case __builtin_clear_padding call before
15964 __builtin_memcmp. */
15965 if (TREE_CODE (TREE_OPERAND (expr
, 0)) == CALL_EXPR
)
15967 tree fndecl
= get_callee_fndecl (TREE_OPERAND (expr
, 0));
15969 && fndecl_built_in_p (fndecl
, BUILT_IN_CLEAR_PADDING
)
15970 && VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (expr
, 0)))
15972 || goa_stabilize_expr (&TREE_OPERAND (expr
, 0), NULL
,
15974 target_expr
, true, depth
)))
15978 saw_lhs
= goa_stabilize_expr (&TREE_OPERAND (expr
, 0),
15979 pre_p
, lhs_addr
, lhs_var
,
15980 target_expr
, true, depth
);
15981 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 1),
15982 pre_p
, lhs_addr
, lhs_var
,
15983 target_expr
, rhs
, depth
);
15989 gimplify_stmt (&TREE_OPERAND (expr
, 0), pre_p
);
15992 return goa_stabilize_expr (&expr
, pre_p
, lhs_addr
, lhs_var
,
15993 target_expr
, rhs
, depth
);
15995 return goa_stabilize_expr (expr_p
, pre_p
, lhs_addr
, lhs_var
,
15996 target_expr
, rhs
, depth
);
15998 if (!goa_stabilize_expr (&TREE_OPERAND (expr
, 0), NULL
, lhs_addr
,
15999 lhs_var
, target_expr
, true, depth
))
16001 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 0), pre_p
,
16002 lhs_addr
, lhs_var
, target_expr
, true,
16004 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 1), pre_p
,
16005 lhs_addr
, lhs_var
, target_expr
, true,
16007 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 2), pre_p
,
16008 lhs_addr
, lhs_var
, target_expr
, true,
16012 if (TARGET_EXPR_INITIAL (expr
))
16014 if (pre_p
&& !goa_stabilize_expr (expr_p
, NULL
, lhs_addr
,
16015 lhs_var
, target_expr
, true,
16018 if (expr
== target_expr
)
16022 saw_lhs
= goa_stabilize_expr (&TARGET_EXPR_INITIAL (expr
),
16023 pre_p
, lhs_addr
, lhs_var
,
16024 target_expr
, true, depth
);
16025 if (saw_lhs
&& target_expr
== NULL_TREE
&& pre_p
)
16026 target_expr
= expr
;
16034 case tcc_reference
:
16035 if (TREE_CODE (expr
) == BIT_FIELD_REF
16036 || TREE_CODE (expr
) == VIEW_CONVERT_EXPR
)
16037 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 0), pre_p
,
16038 lhs_addr
, lhs_var
, target_expr
, true,
16042 if (TREE_CODE (expr
) == CALL_EXPR
)
16044 if (tree fndecl
= get_callee_fndecl (expr
))
16045 if (fndecl_built_in_p (fndecl
, BUILT_IN_CLEAR_PADDING
,
16048 int nargs
= call_expr_nargs (expr
);
16049 for (int i
= 0; i
< nargs
; i
++)
16050 saw_lhs
|= goa_stabilize_expr (&CALL_EXPR_ARG (expr
, i
),
16051 pre_p
, lhs_addr
, lhs_var
,
16052 target_expr
, true, depth
);
16061 if (saw_lhs
== 0 && pre_p
)
16063 enum gimplify_status gs
;
16064 if (TREE_CODE (expr
) == CALL_EXPR
&& VOID_TYPE_P (TREE_TYPE (expr
)))
16066 gimplify_stmt (&expr
, pre_p
);
16070 gs
= gimplify_expr (expr_p
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
16072 gs
= gimplify_expr (expr_p
, pre_p
, NULL
, is_gimple_lvalue
, fb_lvalue
);
16073 if (gs
!= GS_ALL_DONE
)
16080 /* Gimplify an OMP_ATOMIC statement. */
16082 static enum gimplify_status
16083 gimplify_omp_atomic (tree
*expr_p
, gimple_seq
*pre_p
)
16085 tree addr
= TREE_OPERAND (*expr_p
, 0);
16086 tree rhs
= TREE_CODE (*expr_p
) == OMP_ATOMIC_READ
16087 ? NULL
: TREE_OPERAND (*expr_p
, 1);
16088 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr
)));
16090 gomp_atomic_load
*loadstmt
;
16091 gomp_atomic_store
*storestmt
;
16092 tree target_expr
= NULL_TREE
;
16094 tmp_load
= create_tmp_reg (type
);
16096 && goa_stabilize_expr (&rhs
, pre_p
, addr
, tmp_load
, target_expr
,
16100 if (gimplify_expr (&addr
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
)
16104 loadstmt
= gimple_build_omp_atomic_load (tmp_load
, addr
,
16105 OMP_ATOMIC_MEMORY_ORDER (*expr_p
));
16106 gimplify_seq_add_stmt (pre_p
, loadstmt
);
16109 /* BIT_INSERT_EXPR is not valid for non-integral bitfield
16110 representatives. Use BIT_FIELD_REF on the lhs instead. */
16112 if (TREE_CODE (rhs
) == COND_EXPR
)
16113 rhsarg
= TREE_OPERAND (rhs
, 1);
16114 if (TREE_CODE (rhsarg
) == BIT_INSERT_EXPR
16115 && !INTEGRAL_TYPE_P (TREE_TYPE (tmp_load
)))
16117 tree bitpos
= TREE_OPERAND (rhsarg
, 2);
16118 tree op1
= TREE_OPERAND (rhsarg
, 1);
16120 tree tmp_store
= tmp_load
;
16121 if (TREE_CODE (*expr_p
) == OMP_ATOMIC_CAPTURE_OLD
)
16122 tmp_store
= get_initialized_tmp_var (tmp_load
, pre_p
);
16123 if (INTEGRAL_TYPE_P (TREE_TYPE (op1
)))
16124 bitsize
= bitsize_int (TYPE_PRECISION (TREE_TYPE (op1
)));
16126 bitsize
= TYPE_SIZE (TREE_TYPE (op1
));
16127 gcc_assert (TREE_OPERAND (rhsarg
, 0) == tmp_load
);
16128 tree t
= build2_loc (EXPR_LOCATION (rhsarg
),
16129 MODIFY_EXPR
, void_type_node
,
16130 build3_loc (EXPR_LOCATION (rhsarg
),
16131 BIT_FIELD_REF
, TREE_TYPE (op1
),
16132 tmp_store
, bitsize
, bitpos
), op1
);
16133 if (TREE_CODE (rhs
) == COND_EXPR
)
16134 t
= build3_loc (EXPR_LOCATION (rhs
), COND_EXPR
, void_type_node
,
16135 TREE_OPERAND (rhs
, 0), t
, void_node
);
16136 gimplify_and_add (t
, pre_p
);
16139 bool save_allow_rhs_cond_expr
= gimplify_ctxp
->allow_rhs_cond_expr
;
16140 if (TREE_CODE (rhs
) == COND_EXPR
)
16141 gimplify_ctxp
->allow_rhs_cond_expr
= true;
16142 enum gimplify_status gs
= gimplify_expr (&rhs
, pre_p
, NULL
,
16143 is_gimple_val
, fb_rvalue
);
16144 gimplify_ctxp
->allow_rhs_cond_expr
= save_allow_rhs_cond_expr
;
16145 if (gs
!= GS_ALL_DONE
)
16149 if (TREE_CODE (*expr_p
) == OMP_ATOMIC_READ
)
16152 = gimple_build_omp_atomic_store (rhs
, OMP_ATOMIC_MEMORY_ORDER (*expr_p
));
16153 if (TREE_CODE (*expr_p
) != OMP_ATOMIC_READ
&& OMP_ATOMIC_WEAK (*expr_p
))
16155 gimple_omp_atomic_set_weak (loadstmt
);
16156 gimple_omp_atomic_set_weak (storestmt
);
16158 gimplify_seq_add_stmt (pre_p
, storestmt
);
16159 switch (TREE_CODE (*expr_p
))
16161 case OMP_ATOMIC_READ
:
16162 case OMP_ATOMIC_CAPTURE_OLD
:
16163 *expr_p
= tmp_load
;
16164 gimple_omp_atomic_set_need_value (loadstmt
);
16166 case OMP_ATOMIC_CAPTURE_NEW
:
16168 gimple_omp_atomic_set_need_value (storestmt
);
16175 return GS_ALL_DONE
;
16178 /* Gimplify a TRANSACTION_EXPR. This involves gimplification of the
16179 body, and adding some EH bits. */
16181 static enum gimplify_status
16182 gimplify_transaction (tree
*expr_p
, gimple_seq
*pre_p
)
16184 tree expr
= *expr_p
, temp
, tbody
= TRANSACTION_EXPR_BODY (expr
);
16186 gtransaction
*trans_stmt
;
16187 gimple_seq body
= NULL
;
16190 /* Wrap the transaction body in a BIND_EXPR so we have a context
16191 where to put decls for OMP. */
16192 if (TREE_CODE (tbody
) != BIND_EXPR
)
16194 tree bind
= build3 (BIND_EXPR
, void_type_node
, NULL
, tbody
, NULL
);
16195 TREE_SIDE_EFFECTS (bind
) = 1;
16196 SET_EXPR_LOCATION (bind
, EXPR_LOCATION (tbody
));
16197 TRANSACTION_EXPR_BODY (expr
) = bind
;
16200 push_gimplify_context ();
16201 temp
= voidify_wrapper_expr (*expr_p
, NULL
);
16203 body_stmt
= gimplify_and_return_first (TRANSACTION_EXPR_BODY (expr
), &body
);
16204 pop_gimplify_context (body_stmt
);
16206 trans_stmt
= gimple_build_transaction (body
);
16207 if (TRANSACTION_EXPR_OUTER (expr
))
16208 subcode
= GTMA_IS_OUTER
;
16209 else if (TRANSACTION_EXPR_RELAXED (expr
))
16210 subcode
= GTMA_IS_RELAXED
;
16211 gimple_transaction_set_subcode (trans_stmt
, subcode
);
16213 gimplify_seq_add_stmt (pre_p
, trans_stmt
);
16221 *expr_p
= NULL_TREE
;
16222 return GS_ALL_DONE
;
16225 /* Gimplify an OMP_ORDERED construct. EXPR is the tree version. BODY
16226 is the OMP_BODY of the original EXPR (which has already been
16227 gimplified so it's not present in the EXPR).
16229 Return the gimplified GIMPLE_OMP_ORDERED tuple. */
16232 gimplify_omp_ordered (tree expr
, gimple_seq body
)
16237 tree source_c
= NULL_TREE
;
16238 tree sink_c
= NULL_TREE
;
16240 if (gimplify_omp_ctxp
)
16242 for (c
= OMP_ORDERED_CLAUSES (expr
); c
; c
= OMP_CLAUSE_CHAIN (c
))
16243 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DOACROSS
16244 && gimplify_omp_ctxp
->loop_iter_var
.is_empty ())
16246 error_at (OMP_CLAUSE_LOCATION (c
),
16247 "%<ordered%> construct with %qs clause must be "
16248 "closely nested inside a loop with %<ordered%> clause",
16249 OMP_CLAUSE_DOACROSS_DEPEND (c
) ? "depend" : "doacross");
16252 else if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DOACROSS
16253 && OMP_CLAUSE_DOACROSS_KIND (c
) == OMP_CLAUSE_DOACROSS_SINK
)
16257 if (OMP_CLAUSE_DECL (c
) == NULL_TREE
)
16258 continue; /* omp_cur_iteration - 1 */
16259 for (decls
= OMP_CLAUSE_DECL (c
), i
= 0;
16260 decls
&& TREE_CODE (decls
) == TREE_LIST
;
16261 decls
= TREE_CHAIN (decls
), ++i
)
16262 if (i
>= gimplify_omp_ctxp
->loop_iter_var
.length () / 2)
16264 else if (TREE_VALUE (decls
)
16265 != gimplify_omp_ctxp
->loop_iter_var
[2 * i
])
16267 error_at (OMP_CLAUSE_LOCATION (c
),
16268 "variable %qE is not an iteration "
16269 "of outermost loop %d, expected %qE",
16270 TREE_VALUE (decls
), i
+ 1,
16271 gimplify_omp_ctxp
->loop_iter_var
[2 * i
]);
16277 = gimplify_omp_ctxp
->loop_iter_var
[2 * i
+ 1];
16278 if (!fail
&& i
!= gimplify_omp_ctxp
->loop_iter_var
.length () / 2)
16280 error_at (OMP_CLAUSE_LOCATION (c
),
16281 "number of variables in %qs clause with "
16282 "%<sink%> modifier does not match number of "
16283 "iteration variables",
16284 OMP_CLAUSE_DOACROSS_DEPEND (c
)
16285 ? "depend" : "doacross");
16289 else if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DOACROSS
16290 && OMP_CLAUSE_DOACROSS_KIND (c
) == OMP_CLAUSE_DOACROSS_SOURCE
)
16294 error_at (OMP_CLAUSE_LOCATION (c
),
16295 "more than one %qs clause with %<source%> "
16296 "modifier on an %<ordered%> construct",
16297 OMP_CLAUSE_DOACROSS_DEPEND (source_c
)
16298 ? "depend" : "doacross");
16305 if (source_c
&& sink_c
)
16307 error_at (OMP_CLAUSE_LOCATION (source_c
),
16308 "%qs clause with %<source%> modifier specified "
16309 "together with %qs clauses with %<sink%> modifier "
16310 "on the same construct",
16311 OMP_CLAUSE_DOACROSS_DEPEND (source_c
) ? "depend" : "doacross",
16312 OMP_CLAUSE_DOACROSS_DEPEND (sink_c
) ? "depend" : "doacross");
16317 return gimple_build_nop ();
16318 return gimple_build_omp_ordered (body
, OMP_ORDERED_CLAUSES (expr
));
16321 /* Convert the GENERIC expression tree *EXPR_P to GIMPLE. If the
16322 expression produces a value to be used as an operand inside a GIMPLE
16323 statement, the value will be stored back in *EXPR_P. This value will
16324 be a tree of class tcc_declaration, tcc_constant, tcc_reference or
16325 an SSA_NAME. The corresponding sequence of GIMPLE statements is
16326 emitted in PRE_P and POST_P.
16328 Additionally, this process may overwrite parts of the input
16329 expression during gimplification. Ideally, it should be
16330 possible to do non-destructive gimplification.
16332 EXPR_P points to the GENERIC expression to convert to GIMPLE. If
16333 the expression needs to evaluate to a value to be used as
16334 an operand in a GIMPLE statement, this value will be stored in
16335 *EXPR_P on exit. This happens when the caller specifies one
16336 of fb_lvalue or fb_rvalue fallback flags.
16338 PRE_P will contain the sequence of GIMPLE statements corresponding
16339 to the evaluation of EXPR and all the side-effects that must
16340 be executed before the main expression. On exit, the last
16341 statement of PRE_P is the core statement being gimplified. For
16342 instance, when gimplifying 'if (++a)' the last statement in
16343 PRE_P will be 'if (t.1)' where t.1 is the result of
16344 pre-incrementing 'a'.
16346 POST_P will contain the sequence of GIMPLE statements corresponding
16347 to the evaluation of all the side-effects that must be executed
16348 after the main expression. If this is NULL, the post
16349 side-effects are stored at the end of PRE_P.
16351 The reason why the output is split in two is to handle post
16352 side-effects explicitly. In some cases, an expression may have
16353 inner and outer post side-effects which need to be emitted in
16354 an order different from the one given by the recursive
16355 traversal. For instance, for the expression (*p--)++ the post
16356 side-effects of '--' must actually occur *after* the post
16357 side-effects of '++'. However, gimplification will first visit
16358 the inner expression, so if a separate POST sequence was not
16359 used, the resulting sequence would be:
16366 However, the post-decrement operation in line #2 must not be
16367 evaluated until after the store to *p at line #4, so the
16368 correct sequence should be:
16375 So, by specifying a separate post queue, it is possible
16376 to emit the post side-effects in the correct order.
16377 If POST_P is NULL, an internal queue will be used. Before
16378 returning to the caller, the sequence POST_P is appended to
16379 the main output sequence PRE_P.
16381 GIMPLE_TEST_F points to a function that takes a tree T and
16382 returns nonzero if T is in the GIMPLE form requested by the
16383 caller. The GIMPLE predicates are in gimple.cc.
16385 FALLBACK tells the function what sort of a temporary we want if
16386 gimplification cannot produce an expression that complies with
16389 fb_none means that no temporary should be generated
16390 fb_rvalue means that an rvalue is OK to generate
16391 fb_lvalue means that an lvalue is OK to generate
16392 fb_either means that either is OK, but an lvalue is preferable.
16393 fb_mayfail means that gimplification may fail (in which case
16394 GS_ERROR will be returned)
16396 The return value is either GS_ERROR or GS_ALL_DONE, since this
16397 function iterates until EXPR is completely gimplified or an error
16400 enum gimplify_status
16401 gimplify_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
16402 bool (*gimple_test_f
) (tree
), fallback_t fallback
)
16405 gimple_seq internal_pre
= NULL
;
16406 gimple_seq internal_post
= NULL
;
16409 location_t saved_location
;
16410 enum gimplify_status ret
;
16411 gimple_stmt_iterator pre_last_gsi
, post_last_gsi
;
16414 save_expr
= *expr_p
;
16415 if (save_expr
== NULL_TREE
)
16416 return GS_ALL_DONE
;
16418 /* If we are gimplifying a top-level statement, PRE_P must be valid. */
16419 is_statement
= gimple_test_f
== is_gimple_stmt
;
16421 gcc_assert (pre_p
);
16423 /* Consistency checks. */
16424 if (gimple_test_f
== is_gimple_reg
)
16425 gcc_assert (fallback
& (fb_rvalue
| fb_lvalue
));
16426 else if (gimple_test_f
== is_gimple_val
16427 || gimple_test_f
== is_gimple_call_addr
16428 || gimple_test_f
== is_gimple_condexpr_for_cond
16429 || gimple_test_f
== is_gimple_mem_rhs
16430 || gimple_test_f
== is_gimple_mem_rhs_or_call
16431 || gimple_test_f
== is_gimple_reg_rhs
16432 || gimple_test_f
== is_gimple_reg_rhs_or_call
16433 || gimple_test_f
== is_gimple_asm_val
16434 || gimple_test_f
== is_gimple_mem_ref_addr
)
16435 gcc_assert (fallback
& fb_rvalue
);
16436 else if (gimple_test_f
== is_gimple_min_lval
16437 || gimple_test_f
== is_gimple_lvalue
)
16438 gcc_assert (fallback
& fb_lvalue
);
16439 else if (gimple_test_f
== is_gimple_addressable
)
16440 gcc_assert (fallback
& fb_either
);
16441 else if (gimple_test_f
== is_gimple_stmt
)
16442 gcc_assert (fallback
== fb_none
);
16445 /* We should have recognized the GIMPLE_TEST_F predicate to
16446 know what kind of fallback to use in case a temporary is
16447 needed to hold the value or address of *EXPR_P. */
16448 gcc_unreachable ();
16451 /* We used to check the predicate here and return immediately if it
16452 succeeds. This is wrong; the design is for gimplification to be
16453 idempotent, and for the predicates to only test for valid forms, not
16454 whether they are fully simplified. */
16456 pre_p
= &internal_pre
;
16458 if (post_p
== NULL
)
16459 post_p
= &internal_post
;
16461 /* Remember the last statements added to PRE_P and POST_P. Every
16462 new statement added by the gimplification helpers needs to be
16463 annotated with location information. To centralize the
16464 responsibility, we remember the last statement that had been
16465 added to both queues before gimplifying *EXPR_P. If
16466 gimplification produces new statements in PRE_P and POST_P, those
16467 statements will be annotated with the same location information
16469 pre_last_gsi
= gsi_last (*pre_p
);
16470 post_last_gsi
= gsi_last (*post_p
);
16472 saved_location
= input_location
;
16473 if (save_expr
!= error_mark_node
16474 && EXPR_HAS_LOCATION (*expr_p
))
16475 input_location
= EXPR_LOCATION (*expr_p
);
16477 /* Loop over the specific gimplifiers until the toplevel node
16478 remains the same. */
16481 /* Strip away as many useless type conversions as possible
16482 at the toplevel. */
16483 STRIP_USELESS_TYPE_CONVERSION (*expr_p
);
16485 /* Remember the expr. */
16486 save_expr
= *expr_p
;
16488 /* Die, die, die, my darling. */
16489 if (error_operand_p (save_expr
))
16495 /* Do any language-specific gimplification. */
16496 ret
= ((enum gimplify_status
)
16497 lang_hooks
.gimplify_expr (expr_p
, pre_p
, post_p
));
16500 if (*expr_p
== NULL_TREE
)
16502 if (*expr_p
!= save_expr
)
16505 else if (ret
!= GS_UNHANDLED
)
16508 /* Make sure that all the cases set 'ret' appropriately. */
16509 ret
= GS_UNHANDLED
;
16510 switch (TREE_CODE (*expr_p
))
16512 /* First deal with the special cases. */
16514 case POSTINCREMENT_EXPR
:
16515 case POSTDECREMENT_EXPR
:
16516 case PREINCREMENT_EXPR
:
16517 case PREDECREMENT_EXPR
:
16518 ret
= gimplify_self_mod_expr (expr_p
, pre_p
, post_p
,
16519 fallback
!= fb_none
,
16520 TREE_TYPE (*expr_p
));
16523 case VIEW_CONVERT_EXPR
:
16524 if ((fallback
& fb_rvalue
)
16525 && is_gimple_reg_type (TREE_TYPE (*expr_p
))
16526 && is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (*expr_p
, 0))))
16528 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
16529 post_p
, is_gimple_val
, fb_rvalue
);
16530 recalculate_side_effects (*expr_p
);
16536 case ARRAY_RANGE_REF
:
16537 case REALPART_EXPR
:
16538 case IMAGPART_EXPR
:
16539 case COMPONENT_REF
:
16540 ret
= gimplify_compound_lval (expr_p
, pre_p
, post_p
,
16541 fallback
? fallback
: fb_rvalue
);
16545 ret
= gimplify_cond_expr (expr_p
, pre_p
, fallback
);
16547 /* C99 code may assign to an array in a structure value of a
16548 conditional expression, and this has undefined behavior
16549 only on execution, so create a temporary if an lvalue is
16551 if (fallback
== fb_lvalue
)
16553 *expr_p
= get_initialized_tmp_var (*expr_p
, pre_p
, post_p
, false);
16554 mark_addressable (*expr_p
);
16560 ret
= gimplify_call_expr (expr_p
, pre_p
, fallback
!= fb_none
);
16562 /* C99 code may assign to an array in a structure returned
16563 from a function, and this has undefined behavior only on
16564 execution, so create a temporary if an lvalue is
16566 if (fallback
== fb_lvalue
)
16568 *expr_p
= get_initialized_tmp_var (*expr_p
, pre_p
, post_p
, false);
16569 mark_addressable (*expr_p
);
16575 gcc_unreachable ();
16577 case COMPOUND_EXPR
:
16578 ret
= gimplify_compound_expr (expr_p
, pre_p
, fallback
!= fb_none
);
16581 case COMPOUND_LITERAL_EXPR
:
16582 ret
= gimplify_compound_literal_expr (expr_p
, pre_p
,
16583 gimple_test_f
, fallback
);
16588 ret
= gimplify_modify_expr (expr_p
, pre_p
, post_p
,
16589 fallback
!= fb_none
);
16592 case TRUTH_ANDIF_EXPR
:
16593 case TRUTH_ORIF_EXPR
:
16595 /* Preserve the original type of the expression and the
16596 source location of the outer expression. */
16597 tree org_type
= TREE_TYPE (*expr_p
);
16598 *expr_p
= gimple_boolify (*expr_p
);
16599 *expr_p
= build3_loc (input_location
, COND_EXPR
,
16603 org_type
, boolean_true_node
),
16606 org_type
, boolean_false_node
));
16611 case TRUTH_NOT_EXPR
:
16613 tree type
= TREE_TYPE (*expr_p
);
16614 /* The parsers are careful to generate TRUTH_NOT_EXPR
16615 only with operands that are always zero or one.
16616 We do not fold here but handle the only interesting case
16617 manually, as fold may re-introduce the TRUTH_NOT_EXPR. */
16618 *expr_p
= gimple_boolify (*expr_p
);
16619 if (TYPE_PRECISION (TREE_TYPE (*expr_p
)) == 1)
16620 *expr_p
= build1_loc (input_location
, BIT_NOT_EXPR
,
16621 TREE_TYPE (*expr_p
),
16622 TREE_OPERAND (*expr_p
, 0));
16624 *expr_p
= build2_loc (input_location
, BIT_XOR_EXPR
,
16625 TREE_TYPE (*expr_p
),
16626 TREE_OPERAND (*expr_p
, 0),
16627 build_int_cst (TREE_TYPE (*expr_p
), 1));
16628 if (!useless_type_conversion_p (type
, TREE_TYPE (*expr_p
)))
16629 *expr_p
= fold_convert_loc (input_location
, type
, *expr_p
);
16635 ret
= gimplify_addr_expr (expr_p
, pre_p
, post_p
);
16638 case ANNOTATE_EXPR
:
16640 tree cond
= TREE_OPERAND (*expr_p
, 0);
16641 tree kind
= TREE_OPERAND (*expr_p
, 1);
16642 tree data
= TREE_OPERAND (*expr_p
, 2);
16643 tree type
= TREE_TYPE (cond
);
16644 if (!INTEGRAL_TYPE_P (type
))
16650 tree tmp
= create_tmp_var (type
);
16651 gimplify_arg (&cond
, pre_p
, EXPR_LOCATION (*expr_p
));
16653 = gimple_build_call_internal (IFN_ANNOTATE
, 3, cond
, kind
, data
);
16654 gimple_call_set_lhs (call
, tmp
);
16655 gimplify_seq_add_stmt (pre_p
, call
);
16662 ret
= gimplify_va_arg_expr (expr_p
, pre_p
, post_p
);
16666 if (IS_EMPTY_STMT (*expr_p
))
16672 if (VOID_TYPE_P (TREE_TYPE (*expr_p
))
16673 || fallback
== fb_none
)
16675 /* Just strip a conversion to void (or in void context) and
16677 *expr_p
= TREE_OPERAND (*expr_p
, 0);
16682 ret
= gimplify_conversion (expr_p
);
16683 if (ret
== GS_ERROR
)
16685 if (*expr_p
!= save_expr
)
16689 case FIX_TRUNC_EXPR
:
16690 /* unary_expr: ... | '(' cast ')' val | ... */
16691 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
16692 is_gimple_val
, fb_rvalue
);
16693 recalculate_side_effects (*expr_p
);
16698 bool volatilep
= TREE_THIS_VOLATILE (*expr_p
);
16699 bool notrap
= TREE_THIS_NOTRAP (*expr_p
);
16700 tree saved_ptr_type
= TREE_TYPE (TREE_OPERAND (*expr_p
, 0));
16702 *expr_p
= fold_indirect_ref_loc (input_location
, *expr_p
);
16703 if (*expr_p
!= save_expr
)
16709 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
16710 is_gimple_reg
, fb_rvalue
);
16711 if (ret
== GS_ERROR
)
16714 recalculate_side_effects (*expr_p
);
16715 *expr_p
= fold_build2_loc (input_location
, MEM_REF
,
16716 TREE_TYPE (*expr_p
),
16717 TREE_OPERAND (*expr_p
, 0),
16718 build_int_cst (saved_ptr_type
, 0));
16719 TREE_THIS_VOLATILE (*expr_p
) = volatilep
;
16720 TREE_THIS_NOTRAP (*expr_p
) = notrap
;
16725 /* We arrive here through the various re-gimplifcation paths. */
16727 /* First try re-folding the whole thing. */
16728 tmp
= fold_binary (MEM_REF
, TREE_TYPE (*expr_p
),
16729 TREE_OPERAND (*expr_p
, 0),
16730 TREE_OPERAND (*expr_p
, 1));
16733 REF_REVERSE_STORAGE_ORDER (tmp
)
16734 = REF_REVERSE_STORAGE_ORDER (*expr_p
);
16736 recalculate_side_effects (*expr_p
);
16740 /* Avoid re-gimplifying the address operand if it is already
16741 in suitable form. Re-gimplifying would mark the address
16742 operand addressable. Always gimplify when not in SSA form
16743 as we still may have to gimplify decls with value-exprs. */
16744 if (!gimplify_ctxp
|| !gimple_in_ssa_p (cfun
)
16745 || !is_gimple_mem_ref_addr (TREE_OPERAND (*expr_p
, 0)))
16747 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
16748 is_gimple_mem_ref_addr
, fb_rvalue
);
16749 if (ret
== GS_ERROR
)
16752 recalculate_side_effects (*expr_p
);
16756 /* Constants need not be gimplified. */
16763 /* Drop the overflow flag on constants, we do not want
16764 that in the GIMPLE IL. */
16765 if (TREE_OVERFLOW_P (*expr_p
))
16766 *expr_p
= drop_tree_overflow (*expr_p
);
16771 /* If we require an lvalue, such as for ADDR_EXPR, retain the
16772 CONST_DECL node. Otherwise the decl is replaceable by its
16774 /* ??? Should be == fb_lvalue, but ADDR_EXPR passes fb_either. */
16775 if (fallback
& fb_lvalue
)
16779 *expr_p
= DECL_INITIAL (*expr_p
);
16785 ret
= gimplify_decl_expr (expr_p
, pre_p
);
16789 ret
= gimplify_bind_expr (expr_p
, pre_p
);
16793 ret
= gimplify_loop_expr (expr_p
, pre_p
);
16797 ret
= gimplify_switch_expr (expr_p
, pre_p
);
16801 ret
= gimplify_exit_expr (expr_p
);
16805 /* If the target is not LABEL, then it is a computed jump
16806 and the target needs to be gimplified. */
16807 if (TREE_CODE (GOTO_DESTINATION (*expr_p
)) != LABEL_DECL
)
16809 ret
= gimplify_expr (&GOTO_DESTINATION (*expr_p
), pre_p
,
16810 NULL
, is_gimple_val
, fb_rvalue
);
16811 if (ret
== GS_ERROR
)
16814 gimplify_seq_add_stmt (pre_p
,
16815 gimple_build_goto (GOTO_DESTINATION (*expr_p
)));
16820 gimplify_seq_add_stmt (pre_p
,
16821 gimple_build_predict (PREDICT_EXPR_PREDICTOR (*expr_p
),
16822 PREDICT_EXPR_OUTCOME (*expr_p
)));
16827 ret
= gimplify_label_expr (expr_p
, pre_p
);
16828 label
= LABEL_EXPR_LABEL (*expr_p
);
16829 gcc_assert (decl_function_context (label
) == current_function_decl
);
16831 /* If the label is used in a goto statement, or address of the label
16832 is taken, we need to unpoison all variables that were seen so far.
16833 Doing so would prevent us from reporting a false positives. */
16834 if (asan_poisoned_variables
16835 && asan_used_labels
!= NULL
16836 && asan_used_labels
->contains (label
)
16837 && !gimplify_omp_ctxp
)
16838 asan_poison_variables (asan_poisoned_variables
, false, pre_p
);
16841 case CASE_LABEL_EXPR
:
16842 ret
= gimplify_case_label_expr (expr_p
, pre_p
);
16844 if (gimplify_ctxp
->live_switch_vars
)
16845 asan_poison_variables (gimplify_ctxp
->live_switch_vars
, false,
16850 ret
= gimplify_return_expr (*expr_p
, pre_p
);
16854 /* Don't reduce this in place; let gimplify_init_constructor work its
16855 magic. Buf if we're just elaborating this for side effects, just
16856 gimplify any element that has side-effects. */
16857 if (fallback
== fb_none
)
16859 unsigned HOST_WIDE_INT ix
;
16861 tree temp
= NULL_TREE
;
16862 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (*expr_p
), ix
, val
)
16863 if (TREE_SIDE_EFFECTS (val
))
16864 append_to_statement_list (val
, &temp
);
16867 ret
= temp
? GS_OK
: GS_ALL_DONE
;
16869 /* C99 code may assign to an array in a constructed
16870 structure or union, and this has undefined behavior only
16871 on execution, so create a temporary if an lvalue is
16873 else if (fallback
== fb_lvalue
)
16875 *expr_p
= get_initialized_tmp_var (*expr_p
, pre_p
, post_p
, false);
16876 mark_addressable (*expr_p
);
16883 /* The following are special cases that are not handled by the
16884 original GIMPLE grammar. */
16886 /* SAVE_EXPR nodes are converted into a GIMPLE identifier and
16889 ret
= gimplify_save_expr (expr_p
, pre_p
, post_p
);
16892 case BIT_FIELD_REF
:
16893 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
16894 post_p
, is_gimple_lvalue
, fb_either
);
16895 recalculate_side_effects (*expr_p
);
16898 case TARGET_MEM_REF
:
16900 enum gimplify_status r0
= GS_ALL_DONE
, r1
= GS_ALL_DONE
;
16902 if (TMR_BASE (*expr_p
))
16903 r0
= gimplify_expr (&TMR_BASE (*expr_p
), pre_p
,
16904 post_p
, is_gimple_mem_ref_addr
, fb_either
);
16905 if (TMR_INDEX (*expr_p
))
16906 r1
= gimplify_expr (&TMR_INDEX (*expr_p
), pre_p
,
16907 post_p
, is_gimple_val
, fb_rvalue
);
16908 if (TMR_INDEX2 (*expr_p
))
16909 r1
= gimplify_expr (&TMR_INDEX2 (*expr_p
), pre_p
,
16910 post_p
, is_gimple_val
, fb_rvalue
);
16911 /* TMR_STEP and TMR_OFFSET are always integer constants. */
16912 ret
= MIN (r0
, r1
);
16916 case NON_LVALUE_EXPR
:
16917 /* This should have been stripped above. */
16918 gcc_unreachable ();
16921 ret
= gimplify_asm_expr (expr_p
, pre_p
, post_p
);
16924 case TRY_FINALLY_EXPR
:
16925 case TRY_CATCH_EXPR
:
16927 gimple_seq eval
, cleanup
;
16930 /* Calls to destructors are generated automatically in FINALLY/CATCH
16931 block. They should have location as UNKNOWN_LOCATION. However,
16932 gimplify_call_expr will reset these call stmts to input_location
16933 if it finds stmt's location is unknown. To prevent resetting for
16934 destructors, we set the input_location to unknown.
16935 Note that this only affects the destructor calls in FINALLY/CATCH
16936 block, and will automatically reset to its original value by the
16937 end of gimplify_expr. */
16938 input_location
= UNKNOWN_LOCATION
;
16939 eval
= cleanup
= NULL
;
16940 gimplify_and_add (TREE_OPERAND (*expr_p
, 0), &eval
);
16941 if (TREE_CODE (*expr_p
) == TRY_FINALLY_EXPR
16942 && TREE_CODE (TREE_OPERAND (*expr_p
, 1)) == EH_ELSE_EXPR
)
16944 gimple_seq n
= NULL
, e
= NULL
;
16945 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p
, 1),
16947 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p
, 1),
16949 if (!gimple_seq_empty_p (n
) && !gimple_seq_empty_p (e
))
16951 geh_else
*stmt
= gimple_build_eh_else (n
, e
);
16952 gimple_seq_add_stmt (&cleanup
, stmt
);
16956 gimplify_and_add (TREE_OPERAND (*expr_p
, 1), &cleanup
);
16957 /* Don't create bogus GIMPLE_TRY with empty cleanup. */
16958 if (gimple_seq_empty_p (cleanup
))
16960 gimple_seq_add_seq (pre_p
, eval
);
16964 try_
= gimple_build_try (eval
, cleanup
,
16965 TREE_CODE (*expr_p
) == TRY_FINALLY_EXPR
16966 ? GIMPLE_TRY_FINALLY
16967 : GIMPLE_TRY_CATCH
);
16968 if (EXPR_HAS_LOCATION (save_expr
))
16969 gimple_set_location (try_
, EXPR_LOCATION (save_expr
));
16970 else if (LOCATION_LOCUS (saved_location
) != UNKNOWN_LOCATION
)
16971 gimple_set_location (try_
, saved_location
);
16972 if (TREE_CODE (*expr_p
) == TRY_CATCH_EXPR
)
16973 gimple_try_set_catch_is_cleanup (try_
,
16974 TRY_CATCH_IS_CLEANUP (*expr_p
));
16975 gimplify_seq_add_stmt (pre_p
, try_
);
16980 case CLEANUP_POINT_EXPR
:
16981 ret
= gimplify_cleanup_point_expr (expr_p
, pre_p
);
16985 ret
= gimplify_target_expr (expr_p
, pre_p
, post_p
);
16991 gimple_seq handler
= NULL
;
16992 gimplify_and_add (CATCH_BODY (*expr_p
), &handler
);
16993 c
= gimple_build_catch (CATCH_TYPES (*expr_p
), handler
);
16994 gimplify_seq_add_stmt (pre_p
, c
);
16999 case EH_FILTER_EXPR
:
17002 gimple_seq failure
= NULL
;
17004 gimplify_and_add (EH_FILTER_FAILURE (*expr_p
), &failure
);
17005 ehf
= gimple_build_eh_filter (EH_FILTER_TYPES (*expr_p
), failure
);
17006 copy_warning (ehf
, *expr_p
);
17007 gimplify_seq_add_stmt (pre_p
, ehf
);
17014 enum gimplify_status r0
, r1
;
17015 r0
= gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p
), pre_p
,
17016 post_p
, is_gimple_val
, fb_rvalue
);
17017 r1
= gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p
), pre_p
,
17018 post_p
, is_gimple_val
, fb_rvalue
);
17019 TREE_SIDE_EFFECTS (*expr_p
) = 0;
17020 ret
= MIN (r0
, r1
);
17025 /* We get here when taking the address of a label. We mark
17026 the label as "forced"; meaning it can never be removed and
17027 it is a potential target for any computed goto. */
17028 FORCED_LABEL (*expr_p
) = 1;
17032 case STATEMENT_LIST
:
17033 ret
= gimplify_statement_list (expr_p
, pre_p
);
17036 case WITH_SIZE_EXPR
:
17038 gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
17039 post_p
== &internal_post
? NULL
: post_p
,
17040 gimple_test_f
, fallback
);
17041 gimplify_expr (&TREE_OPERAND (*expr_p
, 1), pre_p
, post_p
,
17042 is_gimple_val
, fb_rvalue
);
17049 ret
= gimplify_var_or_parm_decl (expr_p
);
17053 /* When within an OMP context, notice uses of variables. */
17054 if (gimplify_omp_ctxp
)
17055 omp_notice_variable (gimplify_omp_ctxp
, *expr_p
, true);
17059 case DEBUG_EXPR_DECL
:
17060 gcc_unreachable ();
17062 case DEBUG_BEGIN_STMT
:
17063 gimplify_seq_add_stmt (pre_p
,
17064 gimple_build_debug_begin_stmt
17065 (TREE_BLOCK (*expr_p
),
17066 EXPR_LOCATION (*expr_p
)));
17072 /* Allow callbacks into the gimplifier during optimization. */
17077 gimplify_omp_parallel (expr_p
, pre_p
);
17082 gimplify_omp_task (expr_p
, pre_p
);
17088 /* Temporarily disable into_ssa, as scan_omp_simd
17089 which calls copy_gimple_seq_and_replace_locals can't deal
17090 with SSA_NAMEs defined outside of the body properly. */
17091 bool saved_into_ssa
= gimplify_ctxp
->into_ssa
;
17092 gimplify_ctxp
->into_ssa
= false;
17093 ret
= gimplify_omp_for (expr_p
, pre_p
);
17094 gimplify_ctxp
->into_ssa
= saved_into_ssa
;
17099 case OMP_DISTRIBUTE
:
17102 ret
= gimplify_omp_for (expr_p
, pre_p
);
17106 ret
= gimplify_omp_loop (expr_p
, pre_p
);
17110 gimplify_oacc_cache (expr_p
, pre_p
);
17115 gimplify_oacc_declare (expr_p
, pre_p
);
17119 case OACC_HOST_DATA
:
17122 case OACC_PARALLEL
:
17128 case OMP_TARGET_DATA
:
17130 gimplify_omp_workshare (expr_p
, pre_p
);
17134 case OACC_ENTER_DATA
:
17135 case OACC_EXIT_DATA
:
17137 case OMP_TARGET_UPDATE
:
17138 case OMP_TARGET_ENTER_DATA
:
17139 case OMP_TARGET_EXIT_DATA
:
17140 gimplify_omp_target_update (expr_p
, pre_p
);
17145 case OMP_STRUCTURED_BLOCK
:
17152 gimple_seq body
= NULL
;
17154 bool saved_in_omp_construct
= in_omp_construct
;
17156 in_omp_construct
= true;
17157 gimplify_and_add (OMP_BODY (*expr_p
), &body
);
17158 in_omp_construct
= saved_in_omp_construct
;
17159 switch (TREE_CODE (*expr_p
))
17162 g
= gimple_build_omp_section (body
);
17164 case OMP_STRUCTURED_BLOCK
:
17165 g
= gimple_build_omp_structured_block (body
);
17168 g
= gimple_build_omp_master (body
);
17171 g
= gimplify_omp_ordered (*expr_p
, body
);
17172 if (OMP_BODY (*expr_p
) == NULL_TREE
17173 && gimple_code (g
) == GIMPLE_OMP_ORDERED
)
17174 gimple_omp_ordered_standalone (g
);
17177 gimplify_scan_omp_clauses (&OMP_MASKED_CLAUSES (*expr_p
),
17178 pre_p
, ORT_WORKSHARE
, OMP_MASKED
);
17179 gimplify_adjust_omp_clauses (pre_p
, body
,
17180 &OMP_MASKED_CLAUSES (*expr_p
),
17182 g
= gimple_build_omp_masked (body
,
17183 OMP_MASKED_CLAUSES (*expr_p
));
17186 gimplify_scan_omp_clauses (&OMP_CRITICAL_CLAUSES (*expr_p
),
17187 pre_p
, ORT_WORKSHARE
, OMP_CRITICAL
);
17188 gimplify_adjust_omp_clauses (pre_p
, body
,
17189 &OMP_CRITICAL_CLAUSES (*expr_p
),
17191 g
= gimple_build_omp_critical (body
,
17192 OMP_CRITICAL_NAME (*expr_p
),
17193 OMP_CRITICAL_CLAUSES (*expr_p
));
17196 gimplify_scan_omp_clauses (&OMP_SCAN_CLAUSES (*expr_p
),
17197 pre_p
, ORT_WORKSHARE
, OMP_SCAN
);
17198 gimplify_adjust_omp_clauses (pre_p
, body
,
17199 &OMP_SCAN_CLAUSES (*expr_p
),
17201 g
= gimple_build_omp_scan (body
, OMP_SCAN_CLAUSES (*expr_p
));
17204 gcc_unreachable ();
17206 gimplify_seq_add_stmt (pre_p
, g
);
17211 case OMP_TASKGROUP
:
17213 gimple_seq body
= NULL
;
17215 tree
*pclauses
= &OMP_TASKGROUP_CLAUSES (*expr_p
);
17216 bool saved_in_omp_construct
= in_omp_construct
;
17217 gimplify_scan_omp_clauses (pclauses
, pre_p
, ORT_TASKGROUP
,
17219 gimplify_adjust_omp_clauses (pre_p
, NULL
, pclauses
, OMP_TASKGROUP
);
17221 in_omp_construct
= true;
17222 gimplify_and_add (OMP_BODY (*expr_p
), &body
);
17223 in_omp_construct
= saved_in_omp_construct
;
17224 gimple_seq cleanup
= NULL
;
17225 tree fn
= builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_END
);
17226 gimple
*g
= gimple_build_call (fn
, 0);
17227 gimple_seq_add_stmt (&cleanup
, g
);
17228 g
= gimple_build_try (body
, cleanup
, GIMPLE_TRY_FINALLY
);
17230 gimple_seq_add_stmt (&body
, g
);
17231 g
= gimple_build_omp_taskgroup (body
, *pclauses
);
17232 gimplify_seq_add_stmt (pre_p
, g
);
17238 case OMP_ATOMIC_READ
:
17239 case OMP_ATOMIC_CAPTURE_OLD
:
17240 case OMP_ATOMIC_CAPTURE_NEW
:
17241 ret
= gimplify_omp_atomic (expr_p
, pre_p
);
17244 case TRANSACTION_EXPR
:
17245 ret
= gimplify_transaction (expr_p
, pre_p
);
17248 case TRUTH_AND_EXPR
:
17249 case TRUTH_OR_EXPR
:
17250 case TRUTH_XOR_EXPR
:
17252 tree orig_type
= TREE_TYPE (*expr_p
);
17253 tree new_type
, xop0
, xop1
;
17254 *expr_p
= gimple_boolify (*expr_p
);
17255 new_type
= TREE_TYPE (*expr_p
);
17256 if (!useless_type_conversion_p (orig_type
, new_type
))
17258 *expr_p
= fold_convert_loc (input_location
, orig_type
, *expr_p
);
17263 /* Boolified binary truth expressions are semantically equivalent
17264 to bitwise binary expressions. Canonicalize them to the
17265 bitwise variant. */
17266 switch (TREE_CODE (*expr_p
))
17268 case TRUTH_AND_EXPR
:
17269 TREE_SET_CODE (*expr_p
, BIT_AND_EXPR
);
17271 case TRUTH_OR_EXPR
:
17272 TREE_SET_CODE (*expr_p
, BIT_IOR_EXPR
);
17274 case TRUTH_XOR_EXPR
:
17275 TREE_SET_CODE (*expr_p
, BIT_XOR_EXPR
);
17280 /* Now make sure that operands have compatible type to
17281 expression's new_type. */
17282 xop0
= TREE_OPERAND (*expr_p
, 0);
17283 xop1
= TREE_OPERAND (*expr_p
, 1);
17284 if (!useless_type_conversion_p (new_type
, TREE_TYPE (xop0
)))
17285 TREE_OPERAND (*expr_p
, 0) = fold_convert_loc (input_location
,
17288 if (!useless_type_conversion_p (new_type
, TREE_TYPE (xop1
)))
17289 TREE_OPERAND (*expr_p
, 1) = fold_convert_loc (input_location
,
17292 /* Continue classified as tcc_binary. */
17296 case VEC_COND_EXPR
:
17299 case VEC_PERM_EXPR
:
17300 /* Classified as tcc_expression. */
17303 case BIT_INSERT_EXPR
:
17304 /* Argument 3 is a constant. */
17307 case POINTER_PLUS_EXPR
:
17309 enum gimplify_status r0
, r1
;
17310 r0
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
17311 post_p
, is_gimple_val
, fb_rvalue
);
17312 r1
= gimplify_expr (&TREE_OPERAND (*expr_p
, 1), pre_p
,
17313 post_p
, is_gimple_val
, fb_rvalue
);
17314 recalculate_side_effects (*expr_p
);
17315 ret
= MIN (r0
, r1
);
17320 switch (TREE_CODE_CLASS (TREE_CODE (*expr_p
)))
17322 case tcc_comparison
:
17323 /* Handle comparison of objects of non scalar mode aggregates
17324 with a call to memcmp. It would be nice to only have to do
17325 this for variable-sized objects, but then we'd have to allow
17326 the same nest of reference nodes we allow for MODIFY_EXPR and
17327 that's too complex.
17329 Compare scalar mode aggregates as scalar mode values. Using
17330 memcmp for them would be very inefficient at best, and is
17331 plain wrong if bitfields are involved. */
17332 if (error_operand_p (TREE_OPERAND (*expr_p
, 1)))
17336 tree type
= TREE_TYPE (TREE_OPERAND (*expr_p
, 1));
17338 /* Vector comparisons need no boolification. */
17339 if (TREE_CODE (type
) == VECTOR_TYPE
)
17341 else if (!AGGREGATE_TYPE_P (type
))
17343 tree org_type
= TREE_TYPE (*expr_p
);
17344 *expr_p
= gimple_boolify (*expr_p
);
17345 if (!useless_type_conversion_p (org_type
,
17346 TREE_TYPE (*expr_p
)))
17348 *expr_p
= fold_convert_loc (input_location
,
17349 org_type
, *expr_p
);
17355 else if (TYPE_MODE (type
) != BLKmode
)
17356 ret
= gimplify_scalar_mode_aggregate_compare (expr_p
);
17358 ret
= gimplify_variable_sized_compare (expr_p
);
17362 /* If *EXPR_P does not need to be special-cased, handle it
17363 according to its class. */
17365 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
17366 post_p
, is_gimple_val
, fb_rvalue
);
17372 enum gimplify_status r0
, r1
;
17374 r0
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
17375 post_p
, is_gimple_val
, fb_rvalue
);
17376 r1
= gimplify_expr (&TREE_OPERAND (*expr_p
, 1), pre_p
,
17377 post_p
, is_gimple_val
, fb_rvalue
);
17379 ret
= MIN (r0
, r1
);
17385 enum gimplify_status r0
, r1
, r2
;
17387 r0
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
17388 post_p
, is_gimple_val
, fb_rvalue
);
17389 r1
= gimplify_expr (&TREE_OPERAND (*expr_p
, 1), pre_p
,
17390 post_p
, is_gimple_val
, fb_rvalue
);
17391 r2
= gimplify_expr (&TREE_OPERAND (*expr_p
, 2), pre_p
,
17392 post_p
, is_gimple_val
, fb_rvalue
);
17394 ret
= MIN (MIN (r0
, r1
), r2
);
17398 case tcc_declaration
:
17401 goto dont_recalculate
;
17404 gcc_unreachable ();
17407 recalculate_side_effects (*expr_p
);
17413 gcc_assert (*expr_p
|| ret
!= GS_OK
);
17415 while (ret
== GS_OK
);
17417 /* If we encountered an error_mark somewhere nested inside, either
17418 stub out the statement or propagate the error back out. */
17419 if (ret
== GS_ERROR
)
17426 /* This was only valid as a return value from the langhook, which
17427 we handled. Make sure it doesn't escape from any other context. */
17428 gcc_assert (ret
!= GS_UNHANDLED
);
17430 if (fallback
== fb_none
&& *expr_p
&& !is_gimple_stmt (*expr_p
))
17432 /* We aren't looking for a value, and we don't have a valid
17433 statement. If it doesn't have side-effects, throw it away.
17434 We can also get here with code such as "*&&L;", where L is
17435 a LABEL_DECL that is marked as FORCED_LABEL. */
17436 if (TREE_CODE (*expr_p
) == LABEL_DECL
17437 || !TREE_SIDE_EFFECTS (*expr_p
))
17439 else if (!TREE_THIS_VOLATILE (*expr_p
))
17441 /* This is probably a _REF that contains something nested that
17442 has side effects. Recurse through the operands to find it. */
17443 enum tree_code code
= TREE_CODE (*expr_p
);
17447 case COMPONENT_REF
:
17448 case REALPART_EXPR
:
17449 case IMAGPART_EXPR
:
17450 case VIEW_CONVERT_EXPR
:
17451 gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
17452 gimple_test_f
, fallback
);
17456 case ARRAY_RANGE_REF
:
17457 gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
17458 gimple_test_f
, fallback
);
17459 gimplify_expr (&TREE_OPERAND (*expr_p
, 1), pre_p
, post_p
,
17460 gimple_test_f
, fallback
);
17464 /* Anything else with side-effects must be converted to
17465 a valid statement before we get here. */
17466 gcc_unreachable ();
17471 else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p
))
17472 && TYPE_MODE (TREE_TYPE (*expr_p
)) != BLKmode
17473 && !is_empty_type (TREE_TYPE (*expr_p
)))
17475 /* Historically, the compiler has treated a bare reference
17476 to a non-BLKmode volatile lvalue as forcing a load. */
17477 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p
));
17479 /* Normally, we do not want to create a temporary for a
17480 TREE_ADDRESSABLE type because such a type should not be
17481 copied by bitwise-assignment. However, we make an
17482 exception here, as all we are doing here is ensuring that
17483 we read the bytes that make up the type. We use
17484 create_tmp_var_raw because create_tmp_var will abort when
17485 given a TREE_ADDRESSABLE type. */
17486 tree tmp
= create_tmp_var_raw (type
, "vol");
17487 gimple_add_tmp_var (tmp
);
17488 gimplify_assign (tmp
, *expr_p
, pre_p
);
17492 /* We can't do anything useful with a volatile reference to
17493 an incomplete type, so just throw it away. Likewise for
17494 a BLKmode type, since any implicit inner load should
17495 already have been turned into an explicit one by the
17496 gimplification process. */
17500 /* If we are gimplifying at the statement level, we're done. Tack
17501 everything together and return. */
17502 if (fallback
== fb_none
|| is_statement
)
17504 /* Since *EXPR_P has been converted into a GIMPLE tuple, clear
17505 it out for GC to reclaim it. */
17506 *expr_p
= NULL_TREE
;
17508 if (!gimple_seq_empty_p (internal_pre
)
17509 || !gimple_seq_empty_p (internal_post
))
17511 gimplify_seq_add_seq (&internal_pre
, internal_post
);
17512 gimplify_seq_add_seq (pre_p
, internal_pre
);
17515 /* The result of gimplifying *EXPR_P is going to be the last few
17516 statements in *PRE_P and *POST_P. Add location information
17517 to all the statements that were added by the gimplification
17519 if (!gimple_seq_empty_p (*pre_p
))
17520 annotate_all_with_location_after (*pre_p
, pre_last_gsi
, input_location
);
17522 if (!gimple_seq_empty_p (*post_p
))
17523 annotate_all_with_location_after (*post_p
, post_last_gsi
,
17529 #ifdef ENABLE_GIMPLE_CHECKING
17532 enum tree_code code
= TREE_CODE (*expr_p
);
17533 /* These expressions should already be in gimple IR form. */
17534 gcc_assert (code
!= MODIFY_EXPR
17535 && code
!= ASM_EXPR
17536 && code
!= BIND_EXPR
17537 && code
!= CATCH_EXPR
17538 && (code
!= COND_EXPR
|| gimplify_ctxp
->allow_rhs_cond_expr
)
17539 && code
!= EH_FILTER_EXPR
17540 && code
!= GOTO_EXPR
17541 && code
!= LABEL_EXPR
17542 && code
!= LOOP_EXPR
17543 && code
!= SWITCH_EXPR
17544 && code
!= TRY_FINALLY_EXPR
17545 && code
!= EH_ELSE_EXPR
17546 && code
!= OACC_PARALLEL
17547 && code
!= OACC_KERNELS
17548 && code
!= OACC_SERIAL
17549 && code
!= OACC_DATA
17550 && code
!= OACC_HOST_DATA
17551 && code
!= OACC_DECLARE
17552 && code
!= OACC_UPDATE
17553 && code
!= OACC_ENTER_DATA
17554 && code
!= OACC_EXIT_DATA
17555 && code
!= OACC_CACHE
17556 && code
!= OMP_CRITICAL
17558 && code
!= OACC_LOOP
17559 && code
!= OMP_MASTER
17560 && code
!= OMP_MASKED
17561 && code
!= OMP_TASKGROUP
17562 && code
!= OMP_ORDERED
17563 && code
!= OMP_PARALLEL
17564 && code
!= OMP_SCAN
17565 && code
!= OMP_SECTIONS
17566 && code
!= OMP_SECTION
17567 && code
!= OMP_STRUCTURED_BLOCK
17568 && code
!= OMP_SINGLE
17569 && code
!= OMP_SCOPE
);
17573 /* Otherwise we're gimplifying a subexpression, so the resulting
17574 value is interesting. If it's a valid operand that matches
17575 GIMPLE_TEST_F, we're done. Unless we are handling some
17576 post-effects internally; if that's the case, we need to copy into
17577 a temporary before adding the post-effects to POST_P. */
17578 if (gimple_seq_empty_p (internal_post
) && (*gimple_test_f
) (*expr_p
))
17581 /* Otherwise, we need to create a new temporary for the gimplified
17584 /* We can't return an lvalue if we have an internal postqueue. The
17585 object the lvalue refers to would (probably) be modified by the
17586 postqueue; we need to copy the value out first, which means an
17588 if ((fallback
& fb_lvalue
)
17589 && gimple_seq_empty_p (internal_post
)
17590 && is_gimple_addressable (*expr_p
))
17592 /* An lvalue will do. Take the address of the expression, store it
17593 in a temporary, and replace the expression with an INDIRECT_REF of
17595 tree ref_alias_type
= reference_alias_ptr_type (*expr_p
);
17596 unsigned int ref_align
= get_object_alignment (*expr_p
);
17597 tree ref_type
= TREE_TYPE (*expr_p
);
17598 tmp
= build_fold_addr_expr_loc (input_location
, *expr_p
);
17599 gimplify_expr (&tmp
, pre_p
, post_p
, is_gimple_reg
, fb_rvalue
);
17600 if (TYPE_ALIGN (ref_type
) != ref_align
)
17601 ref_type
= build_aligned_type (ref_type
, ref_align
);
17602 *expr_p
= build2 (MEM_REF
, ref_type
,
17603 tmp
, build_zero_cst (ref_alias_type
));
17605 else if ((fallback
& fb_rvalue
) && is_gimple_reg_rhs_or_call (*expr_p
))
17607 /* An rvalue will do. Assign the gimplified expression into a
17608 new temporary TMP and replace the original expression with
17609 TMP. First, make sure that the expression has a type so that
17610 it can be assigned into a temporary. */
17611 gcc_assert (!VOID_TYPE_P (TREE_TYPE (*expr_p
)));
17612 *expr_p
= get_formal_tmp_var (*expr_p
, pre_p
);
17616 #ifdef ENABLE_GIMPLE_CHECKING
17617 if (!(fallback
& fb_mayfail
))
17619 fprintf (stderr
, "gimplification failed:\n");
17620 print_generic_expr (stderr
, *expr_p
);
17621 debug_tree (*expr_p
);
17622 internal_error ("gimplification failed");
17625 gcc_assert (fallback
& fb_mayfail
);
17627 /* If this is an asm statement, and the user asked for the
17628 impossible, don't die. Fail and let gimplify_asm_expr
17634 /* Make sure the temporary matches our predicate. */
17635 gcc_assert ((*gimple_test_f
) (*expr_p
));
17637 if (!gimple_seq_empty_p (internal_post
))
17639 annotate_all_with_location (internal_post
, input_location
);
17640 gimplify_seq_add_seq (pre_p
, internal_post
);
17644 input_location
= saved_location
;
17648 /* Like gimplify_expr but make sure the gimplified result is not itself
17649 a SSA name (but a decl if it were). Temporaries required by
17650 evaluating *EXPR_P may be still SSA names. */
17652 static enum gimplify_status
17653 gimplify_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
17654 bool (*gimple_test_f
) (tree
), fallback_t fallback
,
17657 enum gimplify_status ret
= gimplify_expr (expr_p
, pre_p
, post_p
,
17658 gimple_test_f
, fallback
);
17660 && TREE_CODE (*expr_p
) == SSA_NAME
)
17661 *expr_p
= get_initialized_tmp_var (*expr_p
, pre_p
, NULL
, false);
17665 /* Look through TYPE for variable-sized objects and gimplify each such
17666 size that we find. Add to LIST_P any statements generated. */
17669 gimplify_type_sizes (tree type
, gimple_seq
*list_p
)
17671 if (type
== NULL
|| type
== error_mark_node
)
17674 const bool ignored_p
17676 && TREE_CODE (TYPE_NAME (type
)) == TYPE_DECL
17677 && DECL_IGNORED_P (TYPE_NAME (type
));
17680 /* We first do the main variant, then copy into any other variants. */
17681 type
= TYPE_MAIN_VARIANT (type
);
17683 /* Avoid infinite recursion. */
17684 if (TYPE_SIZES_GIMPLIFIED (type
))
17687 TYPE_SIZES_GIMPLIFIED (type
) = 1;
17689 switch (TREE_CODE (type
))
17692 case ENUMERAL_TYPE
:
17695 case FIXED_POINT_TYPE
:
17696 gimplify_one_sizepos (&TYPE_MIN_VALUE (type
), list_p
);
17697 gimplify_one_sizepos (&TYPE_MAX_VALUE (type
), list_p
);
17699 for (t
= TYPE_NEXT_VARIANT (type
); t
; t
= TYPE_NEXT_VARIANT (t
))
17701 TYPE_MIN_VALUE (t
) = TYPE_MIN_VALUE (type
);
17702 TYPE_MAX_VALUE (t
) = TYPE_MAX_VALUE (type
);
17707 /* These types may not have declarations, so handle them here. */
17708 gimplify_type_sizes (TREE_TYPE (type
), list_p
);
17709 gimplify_type_sizes (TYPE_DOMAIN (type
), list_p
);
17710 /* Ensure VLA bounds aren't removed, for -O0 they should be variables
17711 with assigned stack slots, for -O1+ -g they should be tracked
17714 && TYPE_DOMAIN (type
)
17715 && INTEGRAL_TYPE_P (TYPE_DOMAIN (type
)))
17717 t
= TYPE_MIN_VALUE (TYPE_DOMAIN (type
));
17718 if (t
&& VAR_P (t
) && DECL_ARTIFICIAL (t
))
17719 DECL_IGNORED_P (t
) = 0;
17720 t
= TYPE_MAX_VALUE (TYPE_DOMAIN (type
));
17721 if (t
&& VAR_P (t
) && DECL_ARTIFICIAL (t
))
17722 DECL_IGNORED_P (t
) = 0;
17728 case QUAL_UNION_TYPE
:
17729 for (tree field
= TYPE_FIELDS (type
); field
; field
= DECL_CHAIN (field
))
17730 if (TREE_CODE (field
) == FIELD_DECL
)
17732 gimplify_one_sizepos (&DECL_FIELD_OFFSET (field
), list_p
);
17733 /* Likewise, ensure variable offsets aren't removed. */
17735 && (t
= DECL_FIELD_OFFSET (field
))
17737 && DECL_ARTIFICIAL (t
))
17738 DECL_IGNORED_P (t
) = 0;
17739 gimplify_one_sizepos (&DECL_SIZE (field
), list_p
);
17740 gimplify_one_sizepos (&DECL_SIZE_UNIT (field
), list_p
);
17741 gimplify_type_sizes (TREE_TYPE (field
), list_p
);
17746 case REFERENCE_TYPE
:
17747 /* We used to recurse on the pointed-to type here, which turned out to
17748 be incorrect because its definition might refer to variables not
17749 yet initialized at this point if a forward declaration is involved.
17751 It was actually useful for anonymous pointed-to types to ensure
17752 that the sizes evaluation dominates every possible later use of the
17753 values. Restricting to such types here would be safe since there
17754 is no possible forward declaration around, but would introduce an
17755 undesirable middle-end semantic to anonymity. We then defer to
17756 front-ends the responsibility of ensuring that the sizes are
17757 evaluated both early and late enough, e.g. by attaching artificial
17758 type declarations to the tree. */
17765 gimplify_one_sizepos (&TYPE_SIZE (type
), list_p
);
17766 gimplify_one_sizepos (&TYPE_SIZE_UNIT (type
), list_p
);
17768 for (t
= TYPE_NEXT_VARIANT (type
); t
; t
= TYPE_NEXT_VARIANT (t
))
17770 TYPE_SIZE (t
) = TYPE_SIZE (type
);
17771 TYPE_SIZE_UNIT (t
) = TYPE_SIZE_UNIT (type
);
17772 TYPE_SIZES_GIMPLIFIED (t
) = 1;
17776 /* A subroutine of gimplify_type_sizes to make sure that *EXPR_P,
17777 a size or position, has had all of its SAVE_EXPRs evaluated.
17778 We add any required statements to *STMT_P. */
17781 gimplify_one_sizepos (tree
*expr_p
, gimple_seq
*stmt_p
)
17783 tree expr
= *expr_p
;
17785 /* We don't do anything if the value isn't there, is constant, or contains
17786 A PLACEHOLDER_EXPR. We also don't want to do anything if it's already
17787 a VAR_DECL. If it's a VAR_DECL from another function, the gimplifier
17788 will want to replace it with a new variable, but that will cause problems
17789 if this type is from outside the function. It's OK to have that here. */
17790 if (expr
== NULL_TREE
17791 || is_gimple_constant (expr
)
17793 || CONTAINS_PLACEHOLDER_P (expr
))
17796 *expr_p
= unshare_expr (expr
);
17798 /* SSA names in decl/type fields are a bad idea - they'll get reclaimed
17799 if the def vanishes. */
17800 gimplify_expr (expr_p
, stmt_p
, NULL
, is_gimple_val
, fb_rvalue
, false);
17802 /* If expr wasn't already is_gimple_sizepos or is_gimple_constant from the
17803 FE, ensure that it is a VAR_DECL, otherwise we might handle some decls
17804 as gimplify_vla_decl even when they would have all sizes INTEGER_CSTs. */
17805 if (is_gimple_constant (*expr_p
))
17806 *expr_p
= get_initialized_tmp_var (*expr_p
, stmt_p
, NULL
, false);
17809 /* Gimplify the body of statements of FNDECL and return a GIMPLE_BIND node
17810 containing the sequence of corresponding GIMPLE statements. If DO_PARMS
17811 is true, also gimplify the parameters. */
17814 gimplify_body (tree fndecl
, bool do_parms
)
17816 location_t saved_location
= input_location
;
17817 gimple_seq parm_stmts
, parm_cleanup
= NULL
, seq
;
17818 gimple
*outer_stmt
;
17821 timevar_push (TV_TREE_GIMPLIFY
);
17823 init_tree_ssa (cfun
);
17825 /* Initialize for optimize_insn_for_s{ize,peed}_p possibly called during
17827 default_rtl_profile ();
17829 gcc_assert (gimplify_ctxp
== NULL
);
17830 push_gimplify_context (true);
17832 if (flag_openacc
|| flag_openmp
)
17834 gcc_assert (gimplify_omp_ctxp
== NULL
);
17835 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (fndecl
)))
17836 gimplify_omp_ctxp
= new_omp_context (ORT_IMPLICIT_TARGET
);
17839 /* Unshare most shared trees in the body and in that of any nested functions.
17840 It would seem we don't have to do this for nested functions because
17841 they are supposed to be output and then the outer function gimplified
17842 first, but the g++ front end doesn't always do it that way. */
17843 unshare_body (fndecl
);
17844 unvisit_body (fndecl
);
17846 /* Make sure input_location isn't set to something weird. */
17847 input_location
= DECL_SOURCE_LOCATION (fndecl
);
17849 /* Resolve callee-copies. This has to be done before processing
17850 the body so that DECL_VALUE_EXPR gets processed correctly. */
17851 parm_stmts
= do_parms
? gimplify_parameters (&parm_cleanup
) : NULL
;
17853 /* Gimplify the function's body. */
17855 gimplify_stmt (&DECL_SAVED_TREE (fndecl
), &seq
);
17856 outer_stmt
= gimple_seq_first_nondebug_stmt (seq
);
17859 outer_stmt
= gimple_build_nop ();
17860 gimplify_seq_add_stmt (&seq
, outer_stmt
);
17863 /* The body must contain exactly one statement, a GIMPLE_BIND. If this is
17864 not the case, wrap everything in a GIMPLE_BIND to make it so. */
17865 if (gimple_code (outer_stmt
) == GIMPLE_BIND
17866 && (gimple_seq_first_nondebug_stmt (seq
)
17867 == gimple_seq_last_nondebug_stmt (seq
)))
17869 outer_bind
= as_a
<gbind
*> (outer_stmt
);
17870 if (gimple_seq_first_stmt (seq
) != outer_stmt
17871 || gimple_seq_last_stmt (seq
) != outer_stmt
)
17873 /* If there are debug stmts before or after outer_stmt, move them
17874 inside of outer_bind body. */
17875 gimple_stmt_iterator gsi
= gsi_for_stmt (outer_stmt
, &seq
);
17876 gimple_seq second_seq
= NULL
;
17877 if (gimple_seq_first_stmt (seq
) != outer_stmt
17878 && gimple_seq_last_stmt (seq
) != outer_stmt
)
17880 second_seq
= gsi_split_seq_after (gsi
);
17881 gsi_remove (&gsi
, false);
17883 else if (gimple_seq_first_stmt (seq
) != outer_stmt
)
17884 gsi_remove (&gsi
, false);
17887 gsi_remove (&gsi
, false);
17891 gimple_seq_add_seq_without_update (&seq
,
17892 gimple_bind_body (outer_bind
));
17893 gimple_seq_add_seq_without_update (&seq
, second_seq
);
17894 gimple_bind_set_body (outer_bind
, seq
);
17898 outer_bind
= gimple_build_bind (NULL_TREE
, seq
, NULL
);
17900 DECL_SAVED_TREE (fndecl
) = NULL_TREE
;
17902 /* If we had callee-copies statements, insert them at the beginning
17903 of the function and clear DECL_VALUE_EXPR_P on the parameters. */
17904 if (!gimple_seq_empty_p (parm_stmts
))
17908 gimplify_seq_add_seq (&parm_stmts
, gimple_bind_body (outer_bind
));
17911 gtry
*g
= gimple_build_try (parm_stmts
, parm_cleanup
,
17912 GIMPLE_TRY_FINALLY
);
17914 gimple_seq_add_stmt (&parm_stmts
, g
);
17916 gimple_bind_set_body (outer_bind
, parm_stmts
);
17918 for (parm
= DECL_ARGUMENTS (current_function_decl
);
17919 parm
; parm
= DECL_CHAIN (parm
))
17920 if (DECL_HAS_VALUE_EXPR_P (parm
))
17922 DECL_HAS_VALUE_EXPR_P (parm
) = 0;
17923 DECL_IGNORED_P (parm
) = 0;
17927 if ((flag_openacc
|| flag_openmp
|| flag_openmp_simd
)
17928 && gimplify_omp_ctxp
)
17930 delete_omp_context (gimplify_omp_ctxp
);
17931 gimplify_omp_ctxp
= NULL
;
17934 pop_gimplify_context (outer_bind
);
17935 gcc_assert (gimplify_ctxp
== NULL
);
17937 if (flag_checking
&& !seen_error ())
17938 verify_gimple_in_seq (gimple_bind_body (outer_bind
));
17940 timevar_pop (TV_TREE_GIMPLIFY
);
17941 input_location
= saved_location
;
17946 typedef char *char_p
; /* For DEF_VEC_P. */
17948 /* Return whether we should exclude FNDECL from instrumentation. */
17951 flag_instrument_functions_exclude_p (tree fndecl
)
17955 v
= (vec
<char_p
> *) flag_instrument_functions_exclude_functions
;
17956 if (v
&& v
->length () > 0)
17962 name
= lang_hooks
.decl_printable_name (fndecl
, 1);
17963 FOR_EACH_VEC_ELT (*v
, i
, s
)
17964 if (strstr (name
, s
) != NULL
)
17968 v
= (vec
<char_p
> *) flag_instrument_functions_exclude_files
;
17969 if (v
&& v
->length () > 0)
17975 name
= DECL_SOURCE_FILE (fndecl
);
17976 FOR_EACH_VEC_ELT (*v
, i
, s
)
17977 if (strstr (name
, s
) != NULL
)
17984 /* Build a call to the instrumentation function FNCODE and add it to SEQ.
17985 If COND_VAR is not NULL, it is a boolean variable guarding the call to
17986 the instrumentation function. IF STMT is not NULL, it is a statement
17987 to be executed just before the call to the instrumentation function. */
17990 build_instrumentation_call (gimple_seq
*seq
, enum built_in_function fncode
,
17991 tree cond_var
, gimple
*stmt
)
17993 /* The instrumentation hooks aren't going to call the instrumented
17994 function and the address they receive is expected to be matchable
17995 against symbol addresses. Make sure we don't create a trampoline,
17996 in case the current function is nested. */
17997 tree this_fn_addr
= build_fold_addr_expr (current_function_decl
);
17998 TREE_NO_TRAMPOLINE (this_fn_addr
) = 1;
18000 tree label_true
, label_false
;
18003 label_true
= create_artificial_label (UNKNOWN_LOCATION
);
18004 label_false
= create_artificial_label (UNKNOWN_LOCATION
);
18005 gcond
*cond
= gimple_build_cond (EQ_EXPR
, cond_var
, boolean_false_node
,
18006 label_true
, label_false
);
18007 gimplify_seq_add_stmt (seq
, cond
);
18008 gimplify_seq_add_stmt (seq
, gimple_build_label (label_true
));
18009 gimplify_seq_add_stmt (seq
, gimple_build_predict (PRED_COLD_LABEL
,
18014 gimplify_seq_add_stmt (seq
, stmt
);
18016 tree x
= builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS
);
18017 gcall
*call
= gimple_build_call (x
, 1, integer_zero_node
);
18018 tree tmp_var
= create_tmp_var (ptr_type_node
, "return_addr");
18019 gimple_call_set_lhs (call
, tmp_var
);
18020 gimplify_seq_add_stmt (seq
, call
);
18021 x
= builtin_decl_implicit (fncode
);
18022 call
= gimple_build_call (x
, 2, this_fn_addr
, tmp_var
);
18023 gimplify_seq_add_stmt (seq
, call
);
18026 gimplify_seq_add_stmt (seq
, gimple_build_label (label_false
));
18029 /* Entry point to the gimplification pass. FNDECL is the FUNCTION_DECL
18030 node for the function we want to gimplify.
18032 Return the sequence of GIMPLE statements corresponding to the body
18036 gimplify_function_tree (tree fndecl
)
18041 gcc_assert (!gimple_body (fndecl
));
18043 if (DECL_STRUCT_FUNCTION (fndecl
))
18044 push_cfun (DECL_STRUCT_FUNCTION (fndecl
));
18046 push_struct_function (fndecl
);
18048 /* Tentatively set PROP_gimple_lva here, and reset it in gimplify_va_arg_expr
18050 cfun
->curr_properties
|= PROP_gimple_lva
;
18052 if (asan_sanitize_use_after_scope ())
18053 asan_poisoned_variables
= new hash_set
<tree
> ();
18054 bind
= gimplify_body (fndecl
, true);
18055 if (asan_poisoned_variables
)
18057 delete asan_poisoned_variables
;
18058 asan_poisoned_variables
= NULL
;
18061 /* The tree body of the function is no longer needed, replace it
18062 with the new GIMPLE body. */
18064 gimple_seq_add_stmt (&seq
, bind
);
18065 gimple_set_body (fndecl
, seq
);
18067 /* If we're instrumenting function entry/exit, then prepend the call to
18068 the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to
18069 catch the exit hook. */
18070 /* ??? Add some way to ignore exceptions for this TFE. */
18071 if (flag_instrument_function_entry_exit
18072 && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl
)
18073 /* Do not instrument extern inline functions. */
18074 && !(DECL_DECLARED_INLINE_P (fndecl
)
18075 && DECL_EXTERNAL (fndecl
)
18076 && DECL_DISREGARD_INLINE_LIMITS (fndecl
))
18077 && !flag_instrument_functions_exclude_p (fndecl
))
18079 gimple_seq body
= NULL
, cleanup
= NULL
;
18083 /* If -finstrument-functions-once is specified, generate:
18085 static volatile bool C.0 = false;
18092 [call profiling enter function]
18095 without specific protection for data races. */
18096 if (flag_instrument_function_entry_exit
> 1)
18099 = build_decl (DECL_SOURCE_LOCATION (current_function_decl
),
18101 create_tmp_var_name ("C"),
18102 boolean_type_node
);
18103 DECL_ARTIFICIAL (first_var
) = 1;
18104 DECL_IGNORED_P (first_var
) = 1;
18105 TREE_STATIC (first_var
) = 1;
18106 TREE_THIS_VOLATILE (first_var
) = 1;
18107 TREE_USED (first_var
) = 1;
18108 DECL_INITIAL (first_var
) = boolean_false_node
;
18109 varpool_node::add (first_var
);
18111 cond_var
= create_tmp_var (boolean_type_node
, "tmp_called");
18112 assign
= gimple_build_assign (cond_var
, first_var
);
18113 gimplify_seq_add_stmt (&body
, assign
);
18115 assign
= gimple_build_assign (first_var
, boolean_true_node
);
18120 cond_var
= NULL_TREE
;
18124 build_instrumentation_call (&body
, BUILT_IN_PROFILE_FUNC_ENTER
,
18127 /* If -finstrument-functions-once is specified, generate:
18130 [call profiling exit function]
18132 without specific protection for data races. */
18133 build_instrumentation_call (&cleanup
, BUILT_IN_PROFILE_FUNC_EXIT
,
18136 gimple
*tf
= gimple_build_try (seq
, cleanup
, GIMPLE_TRY_FINALLY
);
18137 gimplify_seq_add_stmt (&body
, tf
);
18138 gbind
*new_bind
= gimple_build_bind (NULL
, body
, NULL
);
18140 /* Replace the current function body with the body
18141 wrapped in the try/finally TF. */
18143 gimple_seq_add_stmt (&seq
, new_bind
);
18144 gimple_set_body (fndecl
, seq
);
18148 if (sanitize_flags_p (SANITIZE_THREAD
)
18149 && param_tsan_instrument_func_entry_exit
)
18151 gcall
*call
= gimple_build_call_internal (IFN_TSAN_FUNC_EXIT
, 0);
18152 gimple
*tf
= gimple_build_try (seq
, call
, GIMPLE_TRY_FINALLY
);
18153 gbind
*new_bind
= gimple_build_bind (NULL
, tf
, NULL
);
18154 /* Replace the current function body with the body
18155 wrapped in the try/finally TF. */
18157 gimple_seq_add_stmt (&seq
, new_bind
);
18158 gimple_set_body (fndecl
, seq
);
18161 DECL_SAVED_TREE (fndecl
) = NULL_TREE
;
18162 cfun
->curr_properties
|= PROP_gimple_any
;
18166 dump_function (TDI_gimple
, fndecl
);
18169 /* Return a dummy expression of type TYPE in order to keep going after an
18173 dummy_object (tree type
)
18175 tree t
= build_int_cst (build_pointer_type (type
), 0);
18176 return build2 (MEM_REF
, type
, t
, t
);
18179 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
18180 builtin function, but a very special sort of operator. */
18182 enum gimplify_status
18183 gimplify_va_arg_expr (tree
*expr_p
, gimple_seq
*pre_p
,
18184 gimple_seq
*post_p ATTRIBUTE_UNUSED
)
18186 tree promoted_type
, have_va_type
;
18187 tree valist
= TREE_OPERAND (*expr_p
, 0);
18188 tree type
= TREE_TYPE (*expr_p
);
18189 tree t
, tag
, aptag
;
18190 location_t loc
= EXPR_LOCATION (*expr_p
);
18192 /* Verify that valist is of the proper type. */
18193 have_va_type
= TREE_TYPE (valist
);
18194 if (have_va_type
== error_mark_node
)
18196 have_va_type
= targetm
.canonical_va_list_type (have_va_type
);
18197 if (have_va_type
== NULL_TREE
18198 && POINTER_TYPE_P (TREE_TYPE (valist
)))
18199 /* Handle 'Case 1: Not an array type' from c-common.cc/build_va_arg. */
18201 = targetm
.canonical_va_list_type (TREE_TYPE (TREE_TYPE (valist
)));
18202 gcc_assert (have_va_type
!= NULL_TREE
);
18204 /* Generate a diagnostic for requesting data of a type that cannot
18205 be passed through `...' due to type promotion at the call site. */
18206 if ((promoted_type
= lang_hooks
.types
.type_promotes_to (type
))
18209 static bool gave_help
;
18211 /* Use the expansion point to handle cases such as passing bool (defined
18212 in a system header) through `...'. */
18214 = expansion_point_location_if_in_system_header (loc
);
18216 /* Unfortunately, this is merely undefined, rather than a constraint
18217 violation, so we cannot make this an error. If this call is never
18218 executed, the program is still strictly conforming. */
18219 auto_diagnostic_group d
;
18220 warned
= warning_at (xloc
, 0,
18221 "%qT is promoted to %qT when passed through %<...%>",
18222 type
, promoted_type
);
18223 if (!gave_help
&& warned
)
18226 inform (xloc
, "(so you should pass %qT not %qT to %<va_arg%>)",
18227 promoted_type
, type
);
18230 /* We can, however, treat "undefined" any way we please.
18231 Call abort to encourage the user to fix the program. */
18233 inform (xloc
, "if this code is reached, the program will abort");
18234 /* Before the abort, allow the evaluation of the va_list
18235 expression to exit or longjmp. */
18236 gimplify_and_add (valist
, pre_p
);
18237 t
= build_call_expr_loc (loc
,
18238 builtin_decl_implicit (BUILT_IN_TRAP
), 0);
18239 gimplify_and_add (t
, pre_p
);
18241 /* This is dead code, but go ahead and finish so that the
18242 mode of the result comes out right. */
18243 *expr_p
= dummy_object (type
);
18244 return GS_ALL_DONE
;
18247 tag
= build_int_cst (build_pointer_type (type
), 0);
18248 aptag
= build_int_cst (TREE_TYPE (valist
), 0);
18250 *expr_p
= build_call_expr_internal_loc (loc
, IFN_VA_ARG
, type
, 3,
18251 valist
, tag
, aptag
);
18253 /* Clear the tentatively set PROP_gimple_lva, to indicate that IFN_VA_ARG
18254 needs to be expanded. */
18255 cfun
->curr_properties
&= ~PROP_gimple_lva
;
18260 /* Build a new GIMPLE_ASSIGN tuple and append it to the end of *SEQ_P.
18262 DST/SRC are the destination and source respectively. You can pass
18263 ungimplified trees in DST or SRC, in which case they will be
18264 converted to a gimple operand if necessary.
18266 This function returns the newly created GIMPLE_ASSIGN tuple. */
18269 gimplify_assign (tree dst
, tree src
, gimple_seq
*seq_p
)
18271 tree t
= build2 (MODIFY_EXPR
, TREE_TYPE (dst
), dst
, src
);
18272 gimplify_and_add (t
, seq_p
);
18274 return gimple_seq_last_stmt (*seq_p
);
18278 gimplify_hasher::hash (const elt_t
*p
)
18281 return iterative_hash_expr (t
, 0);
18285 gimplify_hasher::equal (const elt_t
*p1
, const elt_t
*p2
)
18289 enum tree_code code
= TREE_CODE (t1
);
18291 if (TREE_CODE (t2
) != code
18292 || TREE_TYPE (t1
) != TREE_TYPE (t2
))
18295 if (!operand_equal_p (t1
, t2
, 0))
18298 /* Only allow them to compare equal if they also hash equal; otherwise
18299 results are nondeterminate, and we fail bootstrap comparison. */
18300 gcc_checking_assert (hash (p1
) == hash (p2
));