1 /* Tree lowering pass. This pass converts the GENERIC functions-as-trees
2 tree representation into the GIMPLE form.
3 Copyright (C) 2002-2021 Free Software Foundation, Inc.
4 Major work done by Sebastian Pop <s.pop@laposte.net>,
5 Diego Novillo <dnovillo@redhat.com> and Jason Merrill <jason@redhat.com>.
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
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"
40 #include "fold-const.h"
45 #include "gimple-fold.h"
48 #include "gimple-iterator.h"
49 #include "stor-layout.h"
50 #include "print-tree.h"
51 #include "tree-iterator.h"
52 #include "tree-inline.h"
53 #include "langhooks.h"
56 #include "omp-general.h"
58 #include "gimple-low.h"
59 #include "gomp-constants.h"
60 #include "splay-tree.h"
61 #include "gimple-walk.h"
62 #include "langhooks-def.h" /* FIXME: for lhd_set_decl_assembler_name */
64 #include "stringpool.h"
68 #include "omp-offload.h"
70 #include "tree-nested.h"
72 /* Hash set of poisoned variables in a bind expr. */
73 static hash_set
<tree
> *asan_poisoned_variables
= NULL
;
75 enum gimplify_omp_var_data
78 GOVD_EXPLICIT
= 0x000002,
79 GOVD_SHARED
= 0x000004,
80 GOVD_PRIVATE
= 0x000008,
81 GOVD_FIRSTPRIVATE
= 0x000010,
82 GOVD_LASTPRIVATE
= 0x000020,
83 GOVD_REDUCTION
= 0x000040,
86 GOVD_DEBUG_PRIVATE
= 0x000200,
87 GOVD_PRIVATE_OUTER_REF
= 0x000400,
88 GOVD_LINEAR
= 0x000800,
89 GOVD_ALIGNED
= 0x001000,
91 /* Flag for GOVD_MAP: don't copy back. */
92 GOVD_MAP_TO_ONLY
= 0x002000,
94 /* Flag for GOVD_LINEAR or GOVD_LASTPRIVATE: no outer reference. */
95 GOVD_LINEAR_LASTPRIVATE_NO_OUTER
= 0x004000,
97 GOVD_MAP_0LEN_ARRAY
= 0x008000,
99 /* Flag for GOVD_MAP, if it is always, to or always, tofrom mapping. */
100 GOVD_MAP_ALWAYS_TO
= 0x010000,
102 /* Flag for shared vars that are or might be stored to in the region. */
103 GOVD_WRITTEN
= 0x020000,
105 /* Flag for GOVD_MAP, if it is a forced mapping. */
106 GOVD_MAP_FORCE
= 0x040000,
108 /* Flag for GOVD_MAP: must be present already. */
109 GOVD_MAP_FORCE_PRESENT
= 0x080000,
111 /* Flag for GOVD_MAP: only allocate. */
112 GOVD_MAP_ALLOC_ONLY
= 0x100000,
114 /* Flag for GOVD_MAP: only copy back. */
115 GOVD_MAP_FROM_ONLY
= 0x200000,
117 GOVD_NONTEMPORAL
= 0x400000,
119 /* Flag for GOVD_LASTPRIVATE: conditional modifier. */
120 GOVD_LASTPRIVATE_CONDITIONAL
= 0x800000,
122 GOVD_CONDTEMP
= 0x1000000,
124 /* Flag for GOVD_REDUCTION: inscan seen in {in,ex}clusive clause. */
125 GOVD_REDUCTION_INSCAN
= 0x2000000,
127 /* Flag for GOVD_MAP: (struct) vars that have pointer attachments for
129 GOVD_MAP_HAS_ATTACHMENTS
= 0x4000000,
131 /* Flag for GOVD_FIRSTPRIVATE: OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT. */
132 GOVD_FIRSTPRIVATE_IMPLICIT
= 0x8000000,
134 GOVD_DATA_SHARE_CLASS
= (GOVD_SHARED
| GOVD_PRIVATE
| GOVD_FIRSTPRIVATE
135 | GOVD_LASTPRIVATE
| GOVD_REDUCTION
| GOVD_LINEAR
142 ORT_WORKSHARE
= 0x00,
143 ORT_TASKGROUP
= 0x01,
147 ORT_COMBINED_PARALLEL
= ORT_PARALLEL
| 1,
150 ORT_UNTIED_TASK
= ORT_TASK
| 1,
151 ORT_TASKLOOP
= ORT_TASK
| 2,
152 ORT_UNTIED_TASKLOOP
= ORT_UNTIED_TASK
| 2,
155 ORT_COMBINED_TEAMS
= ORT_TEAMS
| 1,
156 ORT_HOST_TEAMS
= ORT_TEAMS
| 2,
157 ORT_COMBINED_HOST_TEAMS
= ORT_COMBINED_TEAMS
| 2,
160 ORT_TARGET_DATA
= 0x40,
162 /* Data region with offloading. */
164 ORT_COMBINED_TARGET
= ORT_TARGET
| 1,
165 ORT_IMPLICIT_TARGET
= ORT_TARGET
| 2,
167 /* OpenACC variants. */
168 ORT_ACC
= 0x100, /* A generic OpenACC region. */
169 ORT_ACC_DATA
= ORT_ACC
| ORT_TARGET_DATA
, /* Data construct. */
170 ORT_ACC_PARALLEL
= ORT_ACC
| ORT_TARGET
, /* Parallel construct */
171 ORT_ACC_KERNELS
= ORT_ACC
| ORT_TARGET
| 2, /* Kernels construct. */
172 ORT_ACC_SERIAL
= ORT_ACC
| ORT_TARGET
| 4, /* Serial construct. */
173 ORT_ACC_HOST_DATA
= ORT_ACC
| ORT_TARGET_DATA
| 2, /* Host data. */
175 /* Dummy OpenMP region, used to disable expansion of
176 DECL_VALUE_EXPRs in taskloop pre body. */
180 /* Gimplify hashtable helper. */
182 struct gimplify_hasher
: free_ptr_hash
<elt_t
>
184 static inline hashval_t
hash (const elt_t
*);
185 static inline bool equal (const elt_t
*, const elt_t
*);
190 struct gimplify_ctx
*prev_context
;
192 vec
<gbind
*> bind_expr_stack
;
194 gimple_seq conditional_cleanups
;
198 vec
<tree
> case_labels
;
199 hash_set
<tree
> *live_switch_vars
;
200 /* The formal temporary table. Should this be persistent? */
201 hash_table
<gimplify_hasher
> *temp_htab
;
204 unsigned into_ssa
: 1;
205 unsigned allow_rhs_cond_expr
: 1;
206 unsigned in_cleanup_point_expr
: 1;
207 unsigned keep_stack
: 1;
208 unsigned save_stack
: 1;
209 unsigned in_switch_expr
: 1;
212 enum gimplify_defaultmap_kind
215 GDMK_SCALAR_TARGET
, /* w/ Fortran's target attr, implicit mapping, only. */
221 struct gimplify_omp_ctx
223 struct gimplify_omp_ctx
*outer_context
;
224 splay_tree variables
;
225 hash_set
<tree
> *privatized_types
;
227 /* Iteration variables in an OMP_FOR. */
228 vec
<tree
> loop_iter_var
;
230 enum omp_clause_default_kind default_kind
;
231 enum omp_region_type region_type
;
235 bool target_firstprivatize_array_bases
;
237 bool order_concurrent
;
243 static struct gimplify_ctx
*gimplify_ctxp
;
244 static struct gimplify_omp_ctx
*gimplify_omp_ctxp
;
245 static bool in_omp_construct
;
247 /* Forward declaration. */
248 static enum gimplify_status
gimplify_compound_expr (tree
*, gimple_seq
*, bool);
249 static hash_map
<tree
, tree
> *oacc_declare_returns
;
250 static enum gimplify_status
gimplify_expr (tree
*, gimple_seq
*, gimple_seq
*,
251 bool (*) (tree
), fallback_t
, bool);
253 /* Shorter alias name for the above function for use in gimplify.c
257 gimplify_seq_add_stmt (gimple_seq
*seq_p
, gimple
*gs
)
259 gimple_seq_add_stmt_without_update (seq_p
, gs
);
262 /* Append sequence SRC to the end of sequence *DST_P. If *DST_P is
263 NULL, a new sequence is allocated. This function is
264 similar to gimple_seq_add_seq, but does not scan the operands.
265 During gimplification, we need to manipulate statement sequences
266 before the def/use vectors have been constructed. */
269 gimplify_seq_add_seq (gimple_seq
*dst_p
, gimple_seq src
)
271 gimple_stmt_iterator si
;
276 si
= gsi_last (*dst_p
);
277 gsi_insert_seq_after_without_update (&si
, src
, GSI_NEW_STMT
);
281 /* Pointer to a list of allocated gimplify_ctx structs to be used for pushing
282 and popping gimplify contexts. */
284 static struct gimplify_ctx
*ctx_pool
= NULL
;
286 /* Return a gimplify context struct from the pool. */
288 static inline struct gimplify_ctx
*
291 struct gimplify_ctx
* c
= ctx_pool
;
294 ctx_pool
= c
->prev_context
;
296 c
= XNEW (struct gimplify_ctx
);
298 memset (c
, '\0', sizeof (*c
));
302 /* Put gimplify context C back into the pool. */
305 ctx_free (struct gimplify_ctx
*c
)
307 c
->prev_context
= ctx_pool
;
311 /* Free allocated ctx stack memory. */
314 free_gimplify_stack (void)
316 struct gimplify_ctx
*c
;
318 while ((c
= ctx_pool
))
320 ctx_pool
= c
->prev_context
;
326 /* Set up a context for the gimplifier. */
329 push_gimplify_context (bool in_ssa
, bool rhs_cond_ok
)
331 struct gimplify_ctx
*c
= ctx_alloc ();
333 c
->prev_context
= gimplify_ctxp
;
335 gimplify_ctxp
->into_ssa
= in_ssa
;
336 gimplify_ctxp
->allow_rhs_cond_expr
= rhs_cond_ok
;
339 /* Tear down a context for the gimplifier. If BODY is non-null, then
340 put the temporaries into the outer BIND_EXPR. Otherwise, put them
343 BODY is not a sequence, but the first tuple in a sequence. */
346 pop_gimplify_context (gimple
*body
)
348 struct gimplify_ctx
*c
= gimplify_ctxp
;
351 && (!c
->bind_expr_stack
.exists ()
352 || c
->bind_expr_stack
.is_empty ()));
353 c
->bind_expr_stack
.release ();
354 gimplify_ctxp
= c
->prev_context
;
357 declare_vars (c
->temps
, body
, false);
359 record_vars (c
->temps
);
366 /* Push a GIMPLE_BIND tuple onto the stack of bindings. */
369 gimple_push_bind_expr (gbind
*bind_stmt
)
371 gimplify_ctxp
->bind_expr_stack
.reserve (8);
372 gimplify_ctxp
->bind_expr_stack
.safe_push (bind_stmt
);
375 /* Pop the first element off the stack of bindings. */
378 gimple_pop_bind_expr (void)
380 gimplify_ctxp
->bind_expr_stack
.pop ();
383 /* Return the first element of the stack of bindings. */
386 gimple_current_bind_expr (void)
388 return gimplify_ctxp
->bind_expr_stack
.last ();
391 /* Return the stack of bindings created during gimplification. */
394 gimple_bind_expr_stack (void)
396 return gimplify_ctxp
->bind_expr_stack
;
399 /* Return true iff there is a COND_EXPR between us and the innermost
400 CLEANUP_POINT_EXPR. This info is used by gimple_push_cleanup. */
403 gimple_conditional_context (void)
405 return gimplify_ctxp
->conditions
> 0;
408 /* Note that we've entered a COND_EXPR. */
411 gimple_push_condition (void)
413 #ifdef ENABLE_GIMPLE_CHECKING
414 if (gimplify_ctxp
->conditions
== 0)
415 gcc_assert (gimple_seq_empty_p (gimplify_ctxp
->conditional_cleanups
));
417 ++(gimplify_ctxp
->conditions
);
420 /* Note that we've left a COND_EXPR. If we're back at unconditional scope
421 now, add any conditional cleanups we've seen to the prequeue. */
424 gimple_pop_condition (gimple_seq
*pre_p
)
426 int conds
= --(gimplify_ctxp
->conditions
);
428 gcc_assert (conds
>= 0);
431 gimplify_seq_add_seq (pre_p
, gimplify_ctxp
->conditional_cleanups
);
432 gimplify_ctxp
->conditional_cleanups
= NULL
;
436 /* A stable comparison routine for use with splay trees and DECLs. */
439 splay_tree_compare_decl_uid (splay_tree_key xa
, splay_tree_key xb
)
444 return DECL_UID (a
) - DECL_UID (b
);
447 /* Create a new omp construct that deals with variable remapping. */
449 static struct gimplify_omp_ctx
*
450 new_omp_context (enum omp_region_type region_type
)
452 struct gimplify_omp_ctx
*c
;
454 c
= XCNEW (struct gimplify_omp_ctx
);
455 c
->outer_context
= gimplify_omp_ctxp
;
456 c
->variables
= splay_tree_new (splay_tree_compare_decl_uid
, 0, 0);
457 c
->privatized_types
= new hash_set
<tree
>;
458 c
->location
= input_location
;
459 c
->region_type
= region_type
;
460 if ((region_type
& ORT_TASK
) == 0)
461 c
->default_kind
= OMP_CLAUSE_DEFAULT_SHARED
;
463 c
->default_kind
= OMP_CLAUSE_DEFAULT_UNSPECIFIED
;
464 c
->defaultmap
[GDMK_SCALAR
] = GOVD_MAP
;
465 c
->defaultmap
[GDMK_SCALAR_TARGET
] = GOVD_MAP
;
466 c
->defaultmap
[GDMK_AGGREGATE
] = GOVD_MAP
;
467 c
->defaultmap
[GDMK_ALLOCATABLE
] = GOVD_MAP
;
468 c
->defaultmap
[GDMK_POINTER
] = GOVD_MAP
;
473 /* Destroy an omp construct that deals with variable remapping. */
476 delete_omp_context (struct gimplify_omp_ctx
*c
)
478 splay_tree_delete (c
->variables
);
479 delete c
->privatized_types
;
480 c
->loop_iter_var
.release ();
484 static void omp_add_variable (struct gimplify_omp_ctx
*, tree
, unsigned int);
485 static bool omp_notice_variable (struct gimplify_omp_ctx
*, tree
, bool);
487 /* Both gimplify the statement T and append it to *SEQ_P. This function
488 behaves exactly as gimplify_stmt, but you don't have to pass T as a
492 gimplify_and_add (tree t
, gimple_seq
*seq_p
)
494 gimplify_stmt (&t
, seq_p
);
497 /* Gimplify statement T into sequence *SEQ_P, and return the first
498 tuple in the sequence of generated tuples for this statement.
499 Return NULL if gimplifying T produced no tuples. */
502 gimplify_and_return_first (tree t
, gimple_seq
*seq_p
)
504 gimple_stmt_iterator last
= gsi_last (*seq_p
);
506 gimplify_and_add (t
, seq_p
);
508 if (!gsi_end_p (last
))
511 return gsi_stmt (last
);
514 return gimple_seq_first_stmt (*seq_p
);
517 /* Returns true iff T is a valid RHS for an assignment to an un-renamed
518 LHS, or for a call argument. */
521 is_gimple_mem_rhs (tree t
)
523 /* If we're dealing with a renamable type, either source or dest must be
524 a renamed variable. */
525 if (is_gimple_reg_type (TREE_TYPE (t
)))
526 return is_gimple_val (t
);
528 return is_gimple_val (t
) || is_gimple_lvalue (t
);
531 /* Return true if T is a CALL_EXPR or an expression that can be
532 assigned to a temporary. Note that this predicate should only be
533 used during gimplification. See the rationale for this in
534 gimplify_modify_expr. */
537 is_gimple_reg_rhs_or_call (tree t
)
539 return (get_gimple_rhs_class (TREE_CODE (t
)) != GIMPLE_INVALID_RHS
540 || TREE_CODE (t
) == CALL_EXPR
);
543 /* Return true if T is a valid memory RHS or a CALL_EXPR. Note that
544 this predicate should only be used during gimplification. See the
545 rationale for this in gimplify_modify_expr. */
548 is_gimple_mem_rhs_or_call (tree t
)
550 /* If we're dealing with a renamable type, either source or dest must be
551 a renamed variable. */
552 if (is_gimple_reg_type (TREE_TYPE (t
)))
553 return is_gimple_val (t
);
555 return (is_gimple_val (t
)
556 || is_gimple_lvalue (t
)
557 || TREE_CLOBBER_P (t
)
558 || TREE_CODE (t
) == CALL_EXPR
);
561 /* Create a temporary with a name derived from VAL. Subroutine of
562 lookup_tmp_var; nobody else should call this function. */
565 create_tmp_from_val (tree val
)
567 /* Drop all qualifiers and address-space information from the value type. */
568 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (val
));
569 tree var
= create_tmp_var (type
, get_name (val
));
573 /* Create a temporary to hold the value of VAL. If IS_FORMAL, try to reuse
574 an existing expression temporary. */
577 lookup_tmp_var (tree val
, bool is_formal
)
581 /* If not optimizing, never really reuse a temporary. local-alloc
582 won't allocate any variable that is used in more than one basic
583 block, which means it will go into memory, causing much extra
584 work in reload and final and poorer code generation, outweighing
585 the extra memory allocation here. */
586 if (!optimize
|| !is_formal
|| TREE_SIDE_EFFECTS (val
))
587 ret
= create_tmp_from_val (val
);
594 if (!gimplify_ctxp
->temp_htab
)
595 gimplify_ctxp
->temp_htab
= new hash_table
<gimplify_hasher
> (1000);
596 slot
= gimplify_ctxp
->temp_htab
->find_slot (&elt
, INSERT
);
599 elt_p
= XNEW (elt_t
);
601 elt_p
->temp
= ret
= create_tmp_from_val (val
);
614 /* Helper for get_formal_tmp_var and get_initialized_tmp_var. */
617 internal_get_tmp_var (tree val
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
618 bool is_formal
, bool allow_ssa
)
622 /* Notice that we explicitly allow VAL to be a CALL_EXPR so that we
623 can create an INIT_EXPR and convert it into a GIMPLE_CALL below. */
624 gimplify_expr (&val
, pre_p
, post_p
, is_gimple_reg_rhs_or_call
,
628 && gimplify_ctxp
->into_ssa
629 && is_gimple_reg_type (TREE_TYPE (val
)))
631 t
= make_ssa_name (TYPE_MAIN_VARIANT (TREE_TYPE (val
)));
632 if (! gimple_in_ssa_p (cfun
))
634 const char *name
= get_name (val
);
636 SET_SSA_NAME_VAR_OR_IDENTIFIER (t
, create_tmp_var_name (name
));
640 t
= lookup_tmp_var (val
, is_formal
);
642 mod
= build2 (INIT_EXPR
, TREE_TYPE (t
), t
, unshare_expr (val
));
644 SET_EXPR_LOCATION (mod
, EXPR_LOC_OR_LOC (val
, input_location
));
646 /* gimplify_modify_expr might want to reduce this further. */
647 gimplify_and_add (mod
, pre_p
);
653 /* Return a formal temporary variable initialized with VAL. PRE_P is as
654 in gimplify_expr. Only use this function if:
656 1) The value of the unfactored expression represented by VAL will not
657 change between the initialization and use of the temporary, and
658 2) The temporary will not be otherwise modified.
660 For instance, #1 means that this is inappropriate for SAVE_EXPR temps,
661 and #2 means it is inappropriate for && temps.
663 For other cases, use get_initialized_tmp_var instead. */
666 get_formal_tmp_var (tree val
, gimple_seq
*pre_p
)
668 return internal_get_tmp_var (val
, pre_p
, NULL
, true, true);
671 /* Return a temporary variable initialized with VAL. PRE_P and POST_P
672 are as in gimplify_expr. */
675 get_initialized_tmp_var (tree val
, gimple_seq
*pre_p
,
676 gimple_seq
*post_p
/* = NULL */,
677 bool allow_ssa
/* = true */)
679 return internal_get_tmp_var (val
, pre_p
, post_p
, false, allow_ssa
);
682 /* Declare all the variables in VARS in SCOPE. If DEBUG_INFO is true,
683 generate debug info for them; otherwise don't. */
686 declare_vars (tree vars
, gimple
*gs
, bool debug_info
)
693 gbind
*scope
= as_a
<gbind
*> (gs
);
695 temps
= nreverse (last
);
697 block
= gimple_bind_block (scope
);
698 gcc_assert (!block
|| TREE_CODE (block
) == BLOCK
);
699 if (!block
|| !debug_info
)
701 DECL_CHAIN (last
) = gimple_bind_vars (scope
);
702 gimple_bind_set_vars (scope
, temps
);
706 /* We need to attach the nodes both to the BIND_EXPR and to its
707 associated BLOCK for debugging purposes. The key point here
708 is that the BLOCK_VARS of the BIND_EXPR_BLOCK of a BIND_EXPR
709 is a subchain of the BIND_EXPR_VARS of the BIND_EXPR. */
710 if (BLOCK_VARS (block
))
711 BLOCK_VARS (block
) = chainon (BLOCK_VARS (block
), temps
);
714 gimple_bind_set_vars (scope
,
715 chainon (gimple_bind_vars (scope
), temps
));
716 BLOCK_VARS (block
) = temps
;
722 /* For VAR a VAR_DECL of variable size, try to find a constant upper bound
723 for the size and adjust DECL_SIZE/DECL_SIZE_UNIT accordingly. Abort if
724 no such upper bound can be obtained. */
727 force_constant_size (tree var
)
729 /* The only attempt we make is by querying the maximum size of objects
730 of the variable's type. */
732 HOST_WIDE_INT max_size
;
734 gcc_assert (VAR_P (var
));
736 max_size
= max_int_size_in_bytes (TREE_TYPE (var
));
738 gcc_assert (max_size
>= 0);
741 = build_int_cst (TREE_TYPE (DECL_SIZE_UNIT (var
)), max_size
);
743 = build_int_cst (TREE_TYPE (DECL_SIZE (var
)), max_size
* BITS_PER_UNIT
);
746 /* Push the temporary variable TMP into the current binding. */
749 gimple_add_tmp_var_fn (struct function
*fn
, tree tmp
)
751 gcc_assert (!DECL_CHAIN (tmp
) && !DECL_SEEN_IN_BIND_EXPR_P (tmp
));
753 /* Later processing assumes that the object size is constant, which might
754 not be true at this point. Force the use of a constant upper bound in
756 if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp
)))
757 force_constant_size (tmp
);
759 DECL_CONTEXT (tmp
) = fn
->decl
;
760 DECL_SEEN_IN_BIND_EXPR_P (tmp
) = 1;
762 record_vars_into (tmp
, fn
->decl
);
765 /* Push the temporary variable TMP into the current binding. */
768 gimple_add_tmp_var (tree tmp
)
770 gcc_assert (!DECL_CHAIN (tmp
) && !DECL_SEEN_IN_BIND_EXPR_P (tmp
));
772 /* Later processing assumes that the object size is constant, which might
773 not be true at this point. Force the use of a constant upper bound in
775 if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp
)))
776 force_constant_size (tmp
);
778 DECL_CONTEXT (tmp
) = current_function_decl
;
779 DECL_SEEN_IN_BIND_EXPR_P (tmp
) = 1;
783 DECL_CHAIN (tmp
) = gimplify_ctxp
->temps
;
784 gimplify_ctxp
->temps
= tmp
;
786 /* Mark temporaries local within the nearest enclosing parallel. */
787 if (gimplify_omp_ctxp
)
789 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
790 int flag
= GOVD_LOCAL
| GOVD_SEEN
;
792 && (ctx
->region_type
== ORT_WORKSHARE
793 || ctx
->region_type
== ORT_TASKGROUP
794 || ctx
->region_type
== ORT_SIMD
795 || ctx
->region_type
== ORT_ACC
))
797 if (ctx
->region_type
== ORT_SIMD
798 && TREE_ADDRESSABLE (tmp
)
799 && !TREE_STATIC (tmp
))
801 if (TREE_CODE (DECL_SIZE_UNIT (tmp
)) != INTEGER_CST
)
802 ctx
->add_safelen1
= true;
803 else if (ctx
->in_for_exprs
)
806 flag
= GOVD_PRIVATE
| GOVD_SEEN
;
809 ctx
= ctx
->outer_context
;
812 omp_add_variable (ctx
, tmp
, flag
);
821 /* This case is for nested functions. We need to expose the locals
823 body_seq
= gimple_body (current_function_decl
);
824 declare_vars (tmp
, gimple_seq_first_stmt (body_seq
), false);
830 /* This page contains routines to unshare tree nodes, i.e. to duplicate tree
831 nodes that are referenced more than once in GENERIC functions. This is
832 necessary because gimplification (translation into GIMPLE) is performed
833 by modifying tree nodes in-place, so gimplication of a shared node in a
834 first context could generate an invalid GIMPLE form in a second context.
836 This is achieved with a simple mark/copy/unmark algorithm that walks the
837 GENERIC representation top-down, marks nodes with TREE_VISITED the first
838 time it encounters them, duplicates them if they already have TREE_VISITED
839 set, and finally removes the TREE_VISITED marks it has set.
841 The algorithm works only at the function level, i.e. it generates a GENERIC
842 representation of a function with no nodes shared within the function when
843 passed a GENERIC function (except for nodes that are allowed to be shared).
845 At the global level, it is also necessary to unshare tree nodes that are
846 referenced in more than one function, for the same aforementioned reason.
847 This requires some cooperation from the front-end. There are 2 strategies:
849 1. Manual unsharing. The front-end needs to call unshare_expr on every
850 expression that might end up being shared across functions.
852 2. Deep unsharing. This is an extension of regular unsharing. Instead
853 of calling unshare_expr on expressions that might be shared across
854 functions, the front-end pre-marks them with TREE_VISITED. This will
855 ensure that they are unshared on the first reference within functions
856 when the regular unsharing algorithm runs. The counterpart is that
857 this algorithm must look deeper than for manual unsharing, which is
858 specified by LANG_HOOKS_DEEP_UNSHARING.
860 If there are only few specific cases of node sharing across functions, it is
861 probably easier for a front-end to unshare the expressions manually. On the
862 contrary, if the expressions generated at the global level are as widespread
863 as expressions generated within functions, deep unsharing is very likely the
866 /* Similar to copy_tree_r but do not copy SAVE_EXPR or TARGET_EXPR nodes.
867 These nodes model computations that must be done once. If we were to
868 unshare something like SAVE_EXPR(i++), the gimplification process would
869 create wrong code. However, if DATA is non-null, it must hold a pointer
870 set that is used to unshare the subtrees of these nodes. */
873 mostly_copy_tree_r (tree
*tp
, int *walk_subtrees
, void *data
)
876 enum tree_code code
= TREE_CODE (t
);
878 /* Do not copy SAVE_EXPR, TARGET_EXPR or BIND_EXPR nodes themselves, but
879 copy their subtrees if we can make sure to do it only once. */
880 if (code
== SAVE_EXPR
|| code
== TARGET_EXPR
|| code
== BIND_EXPR
)
882 if (data
&& !((hash_set
<tree
> *)data
)->add (t
))
888 /* Stop at types, decls, constants like copy_tree_r. */
889 else if (TREE_CODE_CLASS (code
) == tcc_type
890 || TREE_CODE_CLASS (code
) == tcc_declaration
891 || TREE_CODE_CLASS (code
) == tcc_constant
)
894 /* Cope with the statement expression extension. */
895 else if (code
== STATEMENT_LIST
)
898 /* Leave the bulk of the work to copy_tree_r itself. */
900 copy_tree_r (tp
, walk_subtrees
, NULL
);
905 /* Callback for walk_tree to unshare most of the shared trees rooted at *TP.
906 If *TP has been visited already, then *TP is deeply copied by calling
907 mostly_copy_tree_r. DATA is passed to mostly_copy_tree_r unmodified. */
910 copy_if_shared_r (tree
*tp
, int *walk_subtrees
, void *data
)
913 enum tree_code code
= TREE_CODE (t
);
915 /* Skip types, decls, and constants. But we do want to look at their
916 types and the bounds of types. Mark them as visited so we properly
917 unmark their subtrees on the unmark pass. If we've already seen them,
918 don't look down further. */
919 if (TREE_CODE_CLASS (code
) == tcc_type
920 || TREE_CODE_CLASS (code
) == tcc_declaration
921 || TREE_CODE_CLASS (code
) == tcc_constant
)
923 if (TREE_VISITED (t
))
926 TREE_VISITED (t
) = 1;
929 /* If this node has been visited already, unshare it and don't look
931 else if (TREE_VISITED (t
))
933 walk_tree (tp
, mostly_copy_tree_r
, data
, NULL
);
937 /* Otherwise, mark the node as visited and keep looking. */
939 TREE_VISITED (t
) = 1;
944 /* Unshare most of the shared trees rooted at *TP. DATA is passed to the
945 copy_if_shared_r callback unmodified. */
948 copy_if_shared (tree
*tp
, void *data
)
950 walk_tree (tp
, copy_if_shared_r
, data
, NULL
);
953 /* Unshare all the trees in the body of FNDECL, as well as in the bodies of
954 any nested functions. */
957 unshare_body (tree fndecl
)
959 struct cgraph_node
*cgn
= cgraph_node::get (fndecl
);
960 /* If the language requires deep unsharing, we need a pointer set to make
961 sure we don't repeatedly unshare subtrees of unshareable nodes. */
962 hash_set
<tree
> *visited
963 = lang_hooks
.deep_unsharing
? new hash_set
<tree
> : NULL
;
965 copy_if_shared (&DECL_SAVED_TREE (fndecl
), visited
);
966 copy_if_shared (&DECL_SIZE (DECL_RESULT (fndecl
)), visited
);
967 copy_if_shared (&DECL_SIZE_UNIT (DECL_RESULT (fndecl
)), visited
);
972 for (cgn
= first_nested_function (cgn
); cgn
;
973 cgn
= next_nested_function (cgn
))
974 unshare_body (cgn
->decl
);
977 /* Callback for walk_tree to unmark the visited trees rooted at *TP.
978 Subtrees are walked until the first unvisited node is encountered. */
981 unmark_visited_r (tree
*tp
, int *walk_subtrees
, void *data ATTRIBUTE_UNUSED
)
985 /* If this node has been visited, unmark it and keep looking. */
986 if (TREE_VISITED (t
))
987 TREE_VISITED (t
) = 0;
989 /* Otherwise, don't look any deeper. */
996 /* Unmark the visited trees rooted at *TP. */
999 unmark_visited (tree
*tp
)
1001 walk_tree (tp
, unmark_visited_r
, NULL
, NULL
);
1004 /* Likewise, but mark all trees as not visited. */
1007 unvisit_body (tree fndecl
)
1009 struct cgraph_node
*cgn
= cgraph_node::get (fndecl
);
1011 unmark_visited (&DECL_SAVED_TREE (fndecl
));
1012 unmark_visited (&DECL_SIZE (DECL_RESULT (fndecl
)));
1013 unmark_visited (&DECL_SIZE_UNIT (DECL_RESULT (fndecl
)));
1016 for (cgn
= first_nested_function (cgn
);
1017 cgn
; cgn
= next_nested_function (cgn
))
1018 unvisit_body (cgn
->decl
);
1021 /* Unconditionally make an unshared copy of EXPR. This is used when using
1022 stored expressions which span multiple functions, such as BINFO_VTABLE,
1023 as the normal unsharing process can't tell that they're shared. */
1026 unshare_expr (tree expr
)
1028 walk_tree (&expr
, mostly_copy_tree_r
, NULL
, NULL
);
1032 /* Worker for unshare_expr_without_location. */
1035 prune_expr_location (tree
*tp
, int *walk_subtrees
, void *)
1038 SET_EXPR_LOCATION (*tp
, UNKNOWN_LOCATION
);
1044 /* Similar to unshare_expr but also prune all expression locations
1048 unshare_expr_without_location (tree expr
)
1050 walk_tree (&expr
, mostly_copy_tree_r
, NULL
, NULL
);
1052 walk_tree (&expr
, prune_expr_location
, NULL
, NULL
);
1056 /* Return the EXPR_LOCATION of EXPR, if it (maybe recursively) has
1057 one, OR_ELSE otherwise. The location of a STATEMENT_LISTs
1058 comprising at least one DEBUG_BEGIN_STMT followed by exactly one
1059 EXPR is the location of the EXPR. */
1062 rexpr_location (tree expr
, location_t or_else
= UNKNOWN_LOCATION
)
1067 if (EXPR_HAS_LOCATION (expr
))
1068 return EXPR_LOCATION (expr
);
1070 if (TREE_CODE (expr
) != STATEMENT_LIST
)
1073 tree_stmt_iterator i
= tsi_start (expr
);
1076 while (!tsi_end_p (i
) && TREE_CODE (tsi_stmt (i
)) == DEBUG_BEGIN_STMT
)
1082 if (!found
|| !tsi_one_before_end_p (i
))
1085 return rexpr_location (tsi_stmt (i
), or_else
);
1088 /* Return TRUE iff EXPR (maybe recursively) has a location; see
1089 rexpr_location for the potential recursion. */
1092 rexpr_has_location (tree expr
)
1094 return rexpr_location (expr
) != UNKNOWN_LOCATION
;
1098 /* WRAPPER is a code such as BIND_EXPR or CLEANUP_POINT_EXPR which can both
1099 contain statements and have a value. Assign its value to a temporary
1100 and give it void_type_node. Return the temporary, or NULL_TREE if
1101 WRAPPER was already void. */
1104 voidify_wrapper_expr (tree wrapper
, tree temp
)
1106 tree type
= TREE_TYPE (wrapper
);
1107 if (type
&& !VOID_TYPE_P (type
))
1111 /* Set p to point to the body of the wrapper. Loop until we find
1112 something that isn't a wrapper. */
1113 for (p
= &wrapper
; p
&& *p
; )
1115 switch (TREE_CODE (*p
))
1118 TREE_SIDE_EFFECTS (*p
) = 1;
1119 TREE_TYPE (*p
) = void_type_node
;
1120 /* For a BIND_EXPR, the body is operand 1. */
1121 p
= &BIND_EXPR_BODY (*p
);
1124 case CLEANUP_POINT_EXPR
:
1125 case TRY_FINALLY_EXPR
:
1126 case TRY_CATCH_EXPR
:
1127 TREE_SIDE_EFFECTS (*p
) = 1;
1128 TREE_TYPE (*p
) = void_type_node
;
1129 p
= &TREE_OPERAND (*p
, 0);
1132 case STATEMENT_LIST
:
1134 tree_stmt_iterator i
= tsi_last (*p
);
1135 TREE_SIDE_EFFECTS (*p
) = 1;
1136 TREE_TYPE (*p
) = void_type_node
;
1137 p
= tsi_end_p (i
) ? NULL
: tsi_stmt_ptr (i
);
1142 /* Advance to the last statement. Set all container types to
1144 for (; TREE_CODE (*p
) == COMPOUND_EXPR
; p
= &TREE_OPERAND (*p
, 1))
1146 TREE_SIDE_EFFECTS (*p
) = 1;
1147 TREE_TYPE (*p
) = void_type_node
;
1151 case TRANSACTION_EXPR
:
1152 TREE_SIDE_EFFECTS (*p
) = 1;
1153 TREE_TYPE (*p
) = void_type_node
;
1154 p
= &TRANSACTION_EXPR_BODY (*p
);
1158 /* Assume that any tree upon which voidify_wrapper_expr is
1159 directly called is a wrapper, and that its body is op0. */
1162 TREE_SIDE_EFFECTS (*p
) = 1;
1163 TREE_TYPE (*p
) = void_type_node
;
1164 p
= &TREE_OPERAND (*p
, 0);
1172 if (p
== NULL
|| IS_EMPTY_STMT (*p
))
1176 /* The wrapper is on the RHS of an assignment that we're pushing
1178 gcc_assert (TREE_CODE (temp
) == INIT_EXPR
1179 || TREE_CODE (temp
) == MODIFY_EXPR
);
1180 TREE_OPERAND (temp
, 1) = *p
;
1185 temp
= create_tmp_var (type
, "retval");
1186 *p
= build2 (INIT_EXPR
, type
, temp
, *p
);
1195 /* Prepare calls to builtins to SAVE and RESTORE the stack as well as
1196 a temporary through which they communicate. */
1199 build_stack_save_restore (gcall
**save
, gcall
**restore
)
1203 *save
= gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_SAVE
), 0);
1204 tmp_var
= create_tmp_var (ptr_type_node
, "saved_stack");
1205 gimple_call_set_lhs (*save
, tmp_var
);
1208 = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_RESTORE
),
1212 /* Generate IFN_ASAN_MARK call that poisons shadow of a for DECL variable. */
1215 build_asan_poison_call_expr (tree decl
)
1217 /* Do not poison variables that have size equal to zero. */
1218 tree unit_size
= DECL_SIZE_UNIT (decl
);
1219 if (zerop (unit_size
))
1222 tree base
= build_fold_addr_expr (decl
);
1224 return build_call_expr_internal_loc (UNKNOWN_LOCATION
, IFN_ASAN_MARK
,
1226 build_int_cst (integer_type_node
,
1231 /* Generate IFN_ASAN_MARK call that would poison or unpoison, depending
1232 on POISON flag, shadow memory of a DECL variable. The call will be
1233 put on location identified by IT iterator, where BEFORE flag drives
1234 position where the stmt will be put. */
1237 asan_poison_variable (tree decl
, bool poison
, gimple_stmt_iterator
*it
,
1240 tree unit_size
= DECL_SIZE_UNIT (decl
);
1241 tree base
= build_fold_addr_expr (decl
);
1243 /* Do not poison variables that have size equal to zero. */
1244 if (zerop (unit_size
))
1247 /* It's necessary to have all stack variables aligned to ASAN granularity
1249 gcc_assert (!hwasan_sanitize_p () || hwasan_sanitize_stack_p ());
1250 unsigned shadow_granularity
1251 = hwasan_sanitize_p () ? HWASAN_TAG_GRANULE_SIZE
: ASAN_SHADOW_GRANULARITY
;
1252 if (DECL_ALIGN_UNIT (decl
) <= shadow_granularity
)
1253 SET_DECL_ALIGN (decl
, BITS_PER_UNIT
* shadow_granularity
);
1255 HOST_WIDE_INT flags
= poison
? ASAN_MARK_POISON
: ASAN_MARK_UNPOISON
;
1258 = gimple_build_call_internal (IFN_ASAN_MARK
, 3,
1259 build_int_cst (integer_type_node
, flags
),
1263 gsi_insert_before (it
, g
, GSI_NEW_STMT
);
1265 gsi_insert_after (it
, g
, GSI_NEW_STMT
);
1268 /* Generate IFN_ASAN_MARK internal call that depending on POISON flag
1269 either poisons or unpoisons a DECL. Created statement is appended
1270 to SEQ_P gimple sequence. */
1273 asan_poison_variable (tree decl
, bool poison
, gimple_seq
*seq_p
)
1275 gimple_stmt_iterator it
= gsi_last (*seq_p
);
1276 bool before
= false;
1281 asan_poison_variable (decl
, poison
, &it
, before
);
1284 /* Sort pair of VAR_DECLs A and B by DECL_UID. */
1287 sort_by_decl_uid (const void *a
, const void *b
)
1289 const tree
*t1
= (const tree
*)a
;
1290 const tree
*t2
= (const tree
*)b
;
1292 int uid1
= DECL_UID (*t1
);
1293 int uid2
= DECL_UID (*t2
);
1297 else if (uid1
> uid2
)
1303 /* Generate IFN_ASAN_MARK internal call for all VARIABLES
1304 depending on POISON flag. Created statement is appended
1305 to SEQ_P gimple sequence. */
1308 asan_poison_variables (hash_set
<tree
> *variables
, bool poison
, gimple_seq
*seq_p
)
1310 unsigned c
= variables
->elements ();
1314 auto_vec
<tree
> sorted_variables (c
);
1316 for (hash_set
<tree
>::iterator it
= variables
->begin ();
1317 it
!= variables
->end (); ++it
)
1318 sorted_variables
.safe_push (*it
);
1320 sorted_variables
.qsort (sort_by_decl_uid
);
1324 FOR_EACH_VEC_ELT (sorted_variables
, i
, var
)
1326 asan_poison_variable (var
, poison
, seq_p
);
1328 /* Add use_after_scope_memory attribute for the variable in order
1329 to prevent re-written into SSA. */
1330 if (!lookup_attribute (ASAN_USE_AFTER_SCOPE_ATTRIBUTE
,
1331 DECL_ATTRIBUTES (var
)))
1332 DECL_ATTRIBUTES (var
)
1333 = tree_cons (get_identifier (ASAN_USE_AFTER_SCOPE_ATTRIBUTE
),
1335 DECL_ATTRIBUTES (var
));
1339 /* Gimplify a BIND_EXPR. Just voidify and recurse. */
1341 static enum gimplify_status
1342 gimplify_bind_expr (tree
*expr_p
, gimple_seq
*pre_p
)
1344 tree bind_expr
= *expr_p
;
1345 bool old_keep_stack
= gimplify_ctxp
->keep_stack
;
1346 bool old_save_stack
= gimplify_ctxp
->save_stack
;
1349 gimple_seq body
, cleanup
;
1351 location_t start_locus
= 0, end_locus
= 0;
1352 tree ret_clauses
= NULL
;
1354 tree temp
= voidify_wrapper_expr (bind_expr
, NULL
);
1356 /* Mark variables seen in this bind expr. */
1357 for (t
= BIND_EXPR_VARS (bind_expr
); t
; t
= DECL_CHAIN (t
))
1361 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
1363 /* Mark variable as local. */
1364 if (ctx
&& ctx
->region_type
!= ORT_NONE
&& !DECL_EXTERNAL (t
))
1366 if (! DECL_SEEN_IN_BIND_EXPR_P (t
)
1367 || splay_tree_lookup (ctx
->variables
,
1368 (splay_tree_key
) t
) == NULL
)
1370 int flag
= GOVD_LOCAL
;
1371 if (ctx
->region_type
== ORT_SIMD
1372 && TREE_ADDRESSABLE (t
)
1373 && !TREE_STATIC (t
))
1375 if (TREE_CODE (DECL_SIZE_UNIT (t
)) != INTEGER_CST
)
1376 ctx
->add_safelen1
= true;
1378 flag
= GOVD_PRIVATE
;
1380 omp_add_variable (ctx
, t
, flag
| GOVD_SEEN
);
1382 /* Static locals inside of target construct or offloaded
1383 routines need to be "omp declare target". */
1384 if (TREE_STATIC (t
))
1385 for (; ctx
; ctx
= ctx
->outer_context
)
1386 if ((ctx
->region_type
& ORT_TARGET
) != 0)
1388 if (!lookup_attribute ("omp declare target",
1389 DECL_ATTRIBUTES (t
)))
1391 tree id
= get_identifier ("omp declare target");
1393 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
1394 varpool_node
*node
= varpool_node::get (t
);
1397 node
->offloadable
= 1;
1398 if (ENABLE_OFFLOADING
&& !DECL_EXTERNAL (t
))
1400 g
->have_offload
= true;
1402 vec_safe_push (offload_vars
, t
);
1410 DECL_SEEN_IN_BIND_EXPR_P (t
) = 1;
1412 if (DECL_HARD_REGISTER (t
) && !is_global_var (t
) && cfun
)
1413 cfun
->has_local_explicit_reg_vars
= true;
1417 bind_stmt
= gimple_build_bind (BIND_EXPR_VARS (bind_expr
), NULL
,
1418 BIND_EXPR_BLOCK (bind_expr
));
1419 gimple_push_bind_expr (bind_stmt
);
1421 gimplify_ctxp
->keep_stack
= false;
1422 gimplify_ctxp
->save_stack
= false;
1424 /* Gimplify the body into the GIMPLE_BIND tuple's body. */
1426 gimplify_stmt (&BIND_EXPR_BODY (bind_expr
), &body
);
1427 gimple_bind_set_body (bind_stmt
, body
);
1429 /* Source location wise, the cleanup code (stack_restore and clobbers)
1430 belongs to the end of the block, so propagate what we have. The
1431 stack_save operation belongs to the beginning of block, which we can
1432 infer from the bind_expr directly if the block has no explicit
1434 if (BIND_EXPR_BLOCK (bind_expr
))
1436 end_locus
= BLOCK_SOURCE_END_LOCATION (BIND_EXPR_BLOCK (bind_expr
));
1437 start_locus
= BLOCK_SOURCE_LOCATION (BIND_EXPR_BLOCK (bind_expr
));
1439 if (start_locus
== 0)
1440 start_locus
= EXPR_LOCATION (bind_expr
);
1445 /* If the code both contains VLAs and calls alloca, then we cannot reclaim
1446 the stack space allocated to the VLAs. */
1447 if (gimplify_ctxp
->save_stack
&& !gimplify_ctxp
->keep_stack
)
1449 gcall
*stack_restore
;
1451 /* Save stack on entry and restore it on exit. Add a try_finally
1452 block to achieve this. */
1453 build_stack_save_restore (&stack_save
, &stack_restore
);
1455 gimple_set_location (stack_save
, start_locus
);
1456 gimple_set_location (stack_restore
, end_locus
);
1458 gimplify_seq_add_stmt (&cleanup
, stack_restore
);
1461 /* Add clobbers for all variables that go out of scope. */
1462 for (t
= BIND_EXPR_VARS (bind_expr
); t
; t
= DECL_CHAIN (t
))
1465 && !is_global_var (t
)
1466 && DECL_CONTEXT (t
) == current_function_decl
)
1468 if (!DECL_HARD_REGISTER (t
)
1469 && !TREE_THIS_VOLATILE (t
)
1470 && !DECL_HAS_VALUE_EXPR_P (t
)
1471 /* Only care for variables that have to be in memory. Others
1472 will be rewritten into SSA names, hence moved to the
1474 && !is_gimple_reg (t
)
1475 && flag_stack_reuse
!= SR_NONE
)
1477 tree clobber
= build_clobber (TREE_TYPE (t
));
1478 gimple
*clobber_stmt
;
1479 clobber_stmt
= gimple_build_assign (t
, clobber
);
1480 gimple_set_location (clobber_stmt
, end_locus
);
1481 gimplify_seq_add_stmt (&cleanup
, clobber_stmt
);
1484 if (flag_openacc
&& oacc_declare_returns
!= NULL
)
1487 if (DECL_HAS_VALUE_EXPR_P (key
))
1489 key
= DECL_VALUE_EXPR (key
);
1490 if (TREE_CODE (key
) == INDIRECT_REF
)
1491 key
= TREE_OPERAND (key
, 0);
1493 tree
*c
= oacc_declare_returns
->get (key
);
1497 OMP_CLAUSE_CHAIN (*c
) = ret_clauses
;
1499 ret_clauses
= unshare_expr (*c
);
1501 oacc_declare_returns
->remove (key
);
1503 if (oacc_declare_returns
->is_empty ())
1505 delete oacc_declare_returns
;
1506 oacc_declare_returns
= NULL
;
1512 if (asan_poisoned_variables
!= NULL
1513 && asan_poisoned_variables
->contains (t
))
1515 asan_poisoned_variables
->remove (t
);
1516 asan_poison_variable (t
, true, &cleanup
);
1519 if (gimplify_ctxp
->live_switch_vars
!= NULL
1520 && gimplify_ctxp
->live_switch_vars
->contains (t
))
1521 gimplify_ctxp
->live_switch_vars
->remove (t
);
1527 gimple_stmt_iterator si
= gsi_start (cleanup
);
1529 stmt
= gimple_build_omp_target (NULL
, GF_OMP_TARGET_KIND_OACC_DECLARE
,
1531 gsi_insert_seq_before_without_update (&si
, stmt
, GSI_NEW_STMT
);
1537 gimple_seq new_body
;
1540 gs
= gimple_build_try (gimple_bind_body (bind_stmt
), cleanup
,
1541 GIMPLE_TRY_FINALLY
);
1544 gimplify_seq_add_stmt (&new_body
, stack_save
);
1545 gimplify_seq_add_stmt (&new_body
, gs
);
1546 gimple_bind_set_body (bind_stmt
, new_body
);
1549 /* keep_stack propagates all the way up to the outermost BIND_EXPR. */
1550 if (!gimplify_ctxp
->keep_stack
)
1551 gimplify_ctxp
->keep_stack
= old_keep_stack
;
1552 gimplify_ctxp
->save_stack
= old_save_stack
;
1554 gimple_pop_bind_expr ();
1556 gimplify_seq_add_stmt (pre_p
, bind_stmt
);
1564 *expr_p
= NULL_TREE
;
1568 /* Maybe add early return predict statement to PRE_P sequence. */
1571 maybe_add_early_return_predict_stmt (gimple_seq
*pre_p
)
1573 /* If we are not in a conditional context, add PREDICT statement. */
1574 if (gimple_conditional_context ())
1576 gimple
*predict
= gimple_build_predict (PRED_TREE_EARLY_RETURN
,
1578 gimplify_seq_add_stmt (pre_p
, predict
);
1582 /* Gimplify a RETURN_EXPR. If the expression to be returned is not a
1583 GIMPLE value, it is assigned to a new temporary and the statement is
1584 re-written to return the temporary.
1586 PRE_P points to the sequence where side effects that must happen before
1587 STMT should be stored. */
1589 static enum gimplify_status
1590 gimplify_return_expr (tree stmt
, gimple_seq
*pre_p
)
1593 tree ret_expr
= TREE_OPERAND (stmt
, 0);
1594 tree result_decl
, result
;
1596 if (ret_expr
== error_mark_node
)
1600 || TREE_CODE (ret_expr
) == RESULT_DECL
)
1602 maybe_add_early_return_predict_stmt (pre_p
);
1603 greturn
*ret
= gimple_build_return (ret_expr
);
1604 copy_warning (ret
, stmt
);
1605 gimplify_seq_add_stmt (pre_p
, ret
);
1609 if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl
))))
1610 result_decl
= NULL_TREE
;
1611 else if (TREE_CODE (ret_expr
) == COMPOUND_EXPR
)
1613 /* Used in C++ for handling EH cleanup of the return value if a local
1614 cleanup throws. Assume the front-end knows what it's doing. */
1615 result_decl
= DECL_RESULT (current_function_decl
);
1616 /* But crash if we end up trying to modify ret_expr below. */
1617 ret_expr
= NULL_TREE
;
1621 result_decl
= TREE_OPERAND (ret_expr
, 0);
1623 /* See through a return by reference. */
1624 if (TREE_CODE (result_decl
) == INDIRECT_REF
)
1625 result_decl
= TREE_OPERAND (result_decl
, 0);
1627 gcc_assert ((TREE_CODE (ret_expr
) == MODIFY_EXPR
1628 || TREE_CODE (ret_expr
) == INIT_EXPR
)
1629 && TREE_CODE (result_decl
) == RESULT_DECL
);
1632 /* If aggregate_value_p is true, then we can return the bare RESULT_DECL.
1633 Recall that aggregate_value_p is FALSE for any aggregate type that is
1634 returned in registers. If we're returning values in registers, then
1635 we don't want to extend the lifetime of the RESULT_DECL, particularly
1636 across another call. In addition, for those aggregates for which
1637 hard_function_value generates a PARALLEL, we'll die during normal
1638 expansion of structure assignments; there's special code in expand_return
1639 to handle this case that does not exist in expand_expr. */
1642 else if (aggregate_value_p (result_decl
, TREE_TYPE (current_function_decl
)))
1644 if (!poly_int_tree_p (DECL_SIZE (result_decl
)))
1646 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (result_decl
)))
1647 gimplify_type_sizes (TREE_TYPE (result_decl
), pre_p
);
1648 /* Note that we don't use gimplify_vla_decl because the RESULT_DECL
1649 should be effectively allocated by the caller, i.e. all calls to
1650 this function must be subject to the Return Slot Optimization. */
1651 gimplify_one_sizepos (&DECL_SIZE (result_decl
), pre_p
);
1652 gimplify_one_sizepos (&DECL_SIZE_UNIT (result_decl
), pre_p
);
1654 result
= result_decl
;
1656 else if (gimplify_ctxp
->return_temp
)
1657 result
= gimplify_ctxp
->return_temp
;
1660 result
= create_tmp_reg (TREE_TYPE (result_decl
));
1662 /* ??? With complex control flow (usually involving abnormal edges),
1663 we can wind up warning about an uninitialized value for this. Due
1664 to how this variable is constructed and initialized, this is never
1665 true. Give up and never warn. */
1666 suppress_warning (result
, OPT_Wuninitialized
);
1668 gimplify_ctxp
->return_temp
= result
;
1671 /* Smash the lhs of the MODIFY_EXPR to the temporary we plan to use.
1672 Then gimplify the whole thing. */
1673 if (result
!= result_decl
)
1674 TREE_OPERAND (ret_expr
, 0) = result
;
1676 gimplify_and_add (TREE_OPERAND (stmt
, 0), pre_p
);
1678 maybe_add_early_return_predict_stmt (pre_p
);
1679 ret
= gimple_build_return (result
);
1680 copy_warning (ret
, stmt
);
1681 gimplify_seq_add_stmt (pre_p
, ret
);
1686 /* Gimplify a variable-length array DECL. */
1689 gimplify_vla_decl (tree decl
, gimple_seq
*seq_p
)
1691 /* This is a variable-sized decl. Simplify its size and mark it
1692 for deferred expansion. */
1693 tree t
, addr
, ptr_type
;
1695 gimplify_one_sizepos (&DECL_SIZE (decl
), seq_p
);
1696 gimplify_one_sizepos (&DECL_SIZE_UNIT (decl
), seq_p
);
1698 /* Don't mess with a DECL_VALUE_EXPR set by the front-end. */
1699 if (DECL_HAS_VALUE_EXPR_P (decl
))
1702 /* All occurrences of this decl in final gimplified code will be
1703 replaced by indirection. Setting DECL_VALUE_EXPR does two
1704 things: First, it lets the rest of the gimplifier know what
1705 replacement to use. Second, it lets the debug info know
1706 where to find the value. */
1707 ptr_type
= build_pointer_type (TREE_TYPE (decl
));
1708 addr
= create_tmp_var (ptr_type
, get_name (decl
));
1709 DECL_IGNORED_P (addr
) = 0;
1710 t
= build_fold_indirect_ref (addr
);
1711 TREE_THIS_NOTRAP (t
) = 1;
1712 SET_DECL_VALUE_EXPR (decl
, t
);
1713 DECL_HAS_VALUE_EXPR_P (decl
) = 1;
1715 t
= build_alloca_call_expr (DECL_SIZE_UNIT (decl
), DECL_ALIGN (decl
),
1716 max_int_size_in_bytes (TREE_TYPE (decl
)));
1717 /* The call has been built for a variable-sized object. */
1718 CALL_ALLOCA_FOR_VAR_P (t
) = 1;
1719 t
= fold_convert (ptr_type
, t
);
1720 t
= build2 (MODIFY_EXPR
, TREE_TYPE (addr
), addr
, t
);
1722 gimplify_and_add (t
, seq_p
);
1724 /* Record the dynamic allocation associated with DECL if requested. */
1725 if (flag_callgraph_info
& CALLGRAPH_INFO_DYNAMIC_ALLOC
)
1726 record_dynamic_alloc (decl
);
1729 /* A helper function to be called via walk_tree. Mark all labels under *TP
1730 as being forced. To be called for DECL_INITIAL of static variables. */
1733 force_labels_r (tree
*tp
, int *walk_subtrees
, void *data ATTRIBUTE_UNUSED
)
1737 if (TREE_CODE (*tp
) == LABEL_DECL
)
1739 FORCED_LABEL (*tp
) = 1;
1740 cfun
->has_forced_label_in_static
= 1;
1746 /* Gimplify a DECL_EXPR node *STMT_P by making any necessary allocation
1747 and initialization explicit. */
1749 static enum gimplify_status
1750 gimplify_decl_expr (tree
*stmt_p
, gimple_seq
*seq_p
)
1752 tree stmt
= *stmt_p
;
1753 tree decl
= DECL_EXPR_DECL (stmt
);
1755 *stmt_p
= NULL_TREE
;
1757 if (TREE_TYPE (decl
) == error_mark_node
)
1760 if ((TREE_CODE (decl
) == TYPE_DECL
1762 && !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl
)))
1764 gimplify_type_sizes (TREE_TYPE (decl
), seq_p
);
1765 if (TREE_CODE (TREE_TYPE (decl
)) == REFERENCE_TYPE
)
1766 gimplify_type_sizes (TREE_TYPE (TREE_TYPE (decl
)), seq_p
);
1769 /* ??? DECL_ORIGINAL_TYPE is streamed for LTO so it needs to be gimplified
1770 in case its size expressions contain problematic nodes like CALL_EXPR. */
1771 if (TREE_CODE (decl
) == TYPE_DECL
1772 && DECL_ORIGINAL_TYPE (decl
)
1773 && !TYPE_SIZES_GIMPLIFIED (DECL_ORIGINAL_TYPE (decl
)))
1775 gimplify_type_sizes (DECL_ORIGINAL_TYPE (decl
), seq_p
);
1776 if (TREE_CODE (DECL_ORIGINAL_TYPE (decl
)) == REFERENCE_TYPE
)
1777 gimplify_type_sizes (TREE_TYPE (DECL_ORIGINAL_TYPE (decl
)), seq_p
);
1780 if (VAR_P (decl
) && !DECL_EXTERNAL (decl
))
1782 tree init
= DECL_INITIAL (decl
);
1783 bool is_vla
= false;
1786 if (!poly_int_tree_p (DECL_SIZE_UNIT (decl
), &size
)
1787 || (!TREE_STATIC (decl
)
1788 && flag_stack_check
== GENERIC_STACK_CHECK
1790 (unsigned HOST_WIDE_INT
) STACK_CHECK_MAX_VAR_SIZE
)))
1792 gimplify_vla_decl (decl
, seq_p
);
1796 if (asan_poisoned_variables
1798 && TREE_ADDRESSABLE (decl
)
1799 && !TREE_STATIC (decl
)
1800 && !DECL_HAS_VALUE_EXPR_P (decl
)
1801 && DECL_ALIGN (decl
) <= MAX_SUPPORTED_STACK_ALIGNMENT
1802 && dbg_cnt (asan_use_after_scope
)
1803 && !gimplify_omp_ctxp
1804 /* GNAT introduces temporaries to hold return values of calls in
1805 initializers of variables defined in other units, so the
1806 declaration of the variable is discarded completely. We do not
1807 want to issue poison calls for such dropped variables. */
1808 && (DECL_SEEN_IN_BIND_EXPR_P (decl
)
1809 || (DECL_ARTIFICIAL (decl
) && DECL_NAME (decl
) == NULL_TREE
)))
1811 asan_poisoned_variables
->add (decl
);
1812 asan_poison_variable (decl
, false, seq_p
);
1813 if (!DECL_ARTIFICIAL (decl
) && gimplify_ctxp
->live_switch_vars
)
1814 gimplify_ctxp
->live_switch_vars
->add (decl
);
1817 /* Some front ends do not explicitly declare all anonymous
1818 artificial variables. We compensate here by declaring the
1819 variables, though it would be better if the front ends would
1820 explicitly declare them. */
1821 if (!DECL_SEEN_IN_BIND_EXPR_P (decl
)
1822 && DECL_ARTIFICIAL (decl
) && DECL_NAME (decl
) == NULL_TREE
)
1823 gimple_add_tmp_var (decl
);
1825 if (init
&& init
!= error_mark_node
)
1827 if (!TREE_STATIC (decl
))
1829 DECL_INITIAL (decl
) = NULL_TREE
;
1830 init
= build2 (INIT_EXPR
, void_type_node
, decl
, init
);
1831 gimplify_and_add (init
, seq_p
);
1833 /* Clear TREE_READONLY if we really have an initialization. */
1834 if (!DECL_INITIAL (decl
) && !omp_is_reference (decl
))
1835 TREE_READONLY (decl
) = 0;
1838 /* We must still examine initializers for static variables
1839 as they may contain a label address. */
1840 walk_tree (&init
, force_labels_r
, NULL
, NULL
);
1847 /* Gimplify a LOOP_EXPR. Normally this just involves gimplifying the body
1848 and replacing the LOOP_EXPR with goto, but if the loop contains an
1849 EXIT_EXPR, we need to append a label for it to jump to. */
1851 static enum gimplify_status
1852 gimplify_loop_expr (tree
*expr_p
, gimple_seq
*pre_p
)
1854 tree saved_label
= gimplify_ctxp
->exit_label
;
1855 tree start_label
= create_artificial_label (UNKNOWN_LOCATION
);
1857 gimplify_seq_add_stmt (pre_p
, gimple_build_label (start_label
));
1859 gimplify_ctxp
->exit_label
= NULL_TREE
;
1861 gimplify_and_add (LOOP_EXPR_BODY (*expr_p
), pre_p
);
1863 gimplify_seq_add_stmt (pre_p
, gimple_build_goto (start_label
));
1865 if (gimplify_ctxp
->exit_label
)
1866 gimplify_seq_add_stmt (pre_p
,
1867 gimple_build_label (gimplify_ctxp
->exit_label
));
1869 gimplify_ctxp
->exit_label
= saved_label
;
1875 /* Gimplify a statement list onto a sequence. These may be created either
1876 by an enlightened front-end, or by shortcut_cond_expr. */
1878 static enum gimplify_status
1879 gimplify_statement_list (tree
*expr_p
, gimple_seq
*pre_p
)
1881 tree temp
= voidify_wrapper_expr (*expr_p
, NULL
);
1883 tree_stmt_iterator i
= tsi_start (*expr_p
);
1885 while (!tsi_end_p (i
))
1887 gimplify_stmt (tsi_stmt_ptr (i
), pre_p
);
1900 /* Callback for walk_gimple_seq. */
1903 warn_switch_unreachable_r (gimple_stmt_iterator
*gsi_p
, bool *handled_ops_p
,
1904 struct walk_stmt_info
*wi
)
1906 gimple
*stmt
= gsi_stmt (*gsi_p
);
1908 *handled_ops_p
= true;
1909 switch (gimple_code (stmt
))
1912 /* A compiler-generated cleanup or a user-written try block.
1913 If it's empty, don't dive into it--that would result in
1914 worse location info. */
1915 if (gimple_try_eval (stmt
) == NULL
)
1918 return integer_zero_node
;
1923 case GIMPLE_EH_FILTER
:
1924 case GIMPLE_TRANSACTION
:
1925 /* Walk the sub-statements. */
1926 *handled_ops_p
= false;
1930 /* Ignore these. We may generate them before declarations that
1931 are never executed. If there's something to warn about,
1932 there will be non-debug stmts too, and we'll catch those. */
1936 if (gimple_call_internal_p (stmt
, IFN_ASAN_MARK
))
1938 *handled_ops_p
= false;
1943 /* Save the first "real" statement (not a decl/lexical scope/...). */
1945 return integer_zero_node
;
1950 /* Possibly warn about unreachable statements between switch's controlling
1951 expression and the first case. SEQ is the body of a switch expression. */
1954 maybe_warn_switch_unreachable (gimple_seq seq
)
1956 if (!warn_switch_unreachable
1957 /* This warning doesn't play well with Fortran when optimizations
1959 || lang_GNU_Fortran ()
1963 struct walk_stmt_info wi
;
1964 memset (&wi
, 0, sizeof (wi
));
1965 walk_gimple_seq (seq
, warn_switch_unreachable_r
, NULL
, &wi
);
1966 gimple
*stmt
= (gimple
*) wi
.info
;
1968 if (stmt
&& gimple_code (stmt
) != GIMPLE_LABEL
)
1970 if (gimple_code (stmt
) == GIMPLE_GOTO
1971 && TREE_CODE (gimple_goto_dest (stmt
)) == LABEL_DECL
1972 && DECL_ARTIFICIAL (gimple_goto_dest (stmt
)))
1973 /* Don't warn for compiler-generated gotos. These occur
1974 in Duff's devices, for example. */;
1976 warning_at (gimple_location (stmt
), OPT_Wswitch_unreachable
,
1977 "statement will never be executed");
1982 /* A label entry that pairs label and a location. */
1989 /* Find LABEL in vector of label entries VEC. */
1991 static struct label_entry
*
1992 find_label_entry (const auto_vec
<struct label_entry
> *vec
, tree label
)
1995 struct label_entry
*l
;
1997 FOR_EACH_VEC_ELT (*vec
, i
, l
)
1998 if (l
->label
== label
)
2003 /* Return true if LABEL, a LABEL_DECL, represents a case label
2004 in a vector of labels CASES. */
2007 case_label_p (const vec
<tree
> *cases
, tree label
)
2012 FOR_EACH_VEC_ELT (*cases
, i
, l
)
2013 if (CASE_LABEL (l
) == label
)
2018 /* Find the last nondebug statement in a scope STMT. */
2021 last_stmt_in_scope (gimple
*stmt
)
2026 switch (gimple_code (stmt
))
2030 gbind
*bind
= as_a
<gbind
*> (stmt
);
2031 stmt
= gimple_seq_last_nondebug_stmt (gimple_bind_body (bind
));
2032 return last_stmt_in_scope (stmt
);
2037 gtry
*try_stmt
= as_a
<gtry
*> (stmt
);
2038 stmt
= gimple_seq_last_nondebug_stmt (gimple_try_eval (try_stmt
));
2039 gimple
*last_eval
= last_stmt_in_scope (stmt
);
2040 if (gimple_stmt_may_fallthru (last_eval
)
2041 && (last_eval
== NULL
2042 || !gimple_call_internal_p (last_eval
, IFN_FALLTHROUGH
))
2043 && gimple_try_kind (try_stmt
) == GIMPLE_TRY_FINALLY
)
2045 stmt
= gimple_seq_last_nondebug_stmt (gimple_try_cleanup (try_stmt
));
2046 return last_stmt_in_scope (stmt
);
2060 /* Collect interesting labels in LABELS and return the statement preceding
2061 another case label, or a user-defined label. Store a location useful
2062 to give warnings at *PREVLOC (usually the location of the returned
2063 statement or of its surrounding scope). */
2066 collect_fallthrough_labels (gimple_stmt_iterator
*gsi_p
,
2067 auto_vec
<struct label_entry
> *labels
,
2068 location_t
*prevloc
)
2070 gimple
*prev
= NULL
;
2072 *prevloc
= UNKNOWN_LOCATION
;
2075 if (gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_BIND
)
2077 /* Recognize the special GIMPLE_BIND added by gimplify_switch_expr,
2078 which starts on a GIMPLE_SWITCH and ends with a break label.
2079 Handle that as a single statement that can fall through. */
2080 gbind
*bind
= as_a
<gbind
*> (gsi_stmt (*gsi_p
));
2081 gimple
*first
= gimple_seq_first_stmt (gimple_bind_body (bind
));
2082 gimple
*last
= gimple_seq_last_stmt (gimple_bind_body (bind
));
2084 && gimple_code (first
) == GIMPLE_SWITCH
2085 && gimple_code (last
) == GIMPLE_LABEL
)
2087 tree label
= gimple_label_label (as_a
<glabel
*> (last
));
2088 if (SWITCH_BREAK_LABEL_P (label
))
2096 if (gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_BIND
2097 || gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_TRY
)
2099 /* Nested scope. Only look at the last statement of
2100 the innermost scope. */
2101 location_t bind_loc
= gimple_location (gsi_stmt (*gsi_p
));
2102 gimple
*last
= last_stmt_in_scope (gsi_stmt (*gsi_p
));
2106 /* It might be a label without a location. Use the
2107 location of the scope then. */
2108 if (!gimple_has_location (prev
))
2109 *prevloc
= bind_loc
;
2115 /* Ifs are tricky. */
2116 if (gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_COND
)
2118 gcond
*cond_stmt
= as_a
<gcond
*> (gsi_stmt (*gsi_p
));
2119 tree false_lab
= gimple_cond_false_label (cond_stmt
);
2120 location_t if_loc
= gimple_location (cond_stmt
);
2123 if (i > 1) goto <D.2259>; else goto D;
2124 we can't do much with the else-branch. */
2125 if (!DECL_ARTIFICIAL (false_lab
))
2128 /* Go on until the false label, then one step back. */
2129 for (; !gsi_end_p (*gsi_p
); gsi_next (gsi_p
))
2131 gimple
*stmt
= gsi_stmt (*gsi_p
);
2132 if (gimple_code (stmt
) == GIMPLE_LABEL
2133 && gimple_label_label (as_a
<glabel
*> (stmt
)) == false_lab
)
2137 /* Not found? Oops. */
2138 if (gsi_end_p (*gsi_p
))
2141 struct label_entry l
= { false_lab
, if_loc
};
2142 labels
->safe_push (l
);
2144 /* Go to the last statement of the then branch. */
2147 /* if (i != 0) goto <D.1759>; else goto <D.1760>;
2153 if (gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_GOTO
2154 && !gimple_has_location (gsi_stmt (*gsi_p
)))
2156 /* Look at the statement before, it might be
2157 attribute fallthrough, in which case don't warn. */
2159 bool fallthru_before_dest
2160 = gimple_call_internal_p (gsi_stmt (*gsi_p
), IFN_FALLTHROUGH
);
2162 tree goto_dest
= gimple_goto_dest (gsi_stmt (*gsi_p
));
2163 if (!fallthru_before_dest
)
2165 struct label_entry l
= { goto_dest
, if_loc
};
2166 labels
->safe_push (l
);
2169 /* And move back. */
2173 /* Remember the last statement. Skip labels that are of no interest
2175 if (gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_LABEL
)
2177 tree label
= gimple_label_label (as_a
<glabel
*> (gsi_stmt (*gsi_p
)));
2178 if (find_label_entry (labels
, label
))
2179 prev
= gsi_stmt (*gsi_p
);
2181 else if (gimple_call_internal_p (gsi_stmt (*gsi_p
), IFN_ASAN_MARK
))
2183 else if (gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_PREDICT
)
2185 else if (!is_gimple_debug (gsi_stmt (*gsi_p
)))
2186 prev
= gsi_stmt (*gsi_p
);
2189 while (!gsi_end_p (*gsi_p
)
2190 /* Stop if we find a case or a user-defined label. */
2191 && (gimple_code (gsi_stmt (*gsi_p
)) != GIMPLE_LABEL
2192 || !gimple_has_location (gsi_stmt (*gsi_p
))));
2194 if (prev
&& gimple_has_location (prev
))
2195 *prevloc
= gimple_location (prev
);
2199 /* Return true if the switch fallthough warning should occur. LABEL is
2200 the label statement that we're falling through to. */
2203 should_warn_for_implicit_fallthrough (gimple_stmt_iterator
*gsi_p
, tree label
)
2205 gimple_stmt_iterator gsi
= *gsi_p
;
2207 /* Don't warn if the label is marked with a "falls through" comment. */
2208 if (FALLTHROUGH_LABEL_P (label
))
2211 /* Don't warn for non-case labels followed by a statement:
2216 as these are likely intentional. */
2217 if (!case_label_p (&gimplify_ctxp
->case_labels
, label
))
2220 while (!gsi_end_p (gsi
)
2221 && gimple_code (gsi_stmt (gsi
)) == GIMPLE_LABEL
2222 && (l
= gimple_label_label (as_a
<glabel
*> (gsi_stmt (gsi
))))
2223 && !case_label_p (&gimplify_ctxp
->case_labels
, l
))
2224 gsi_next_nondebug (&gsi
);
2225 if (gsi_end_p (gsi
) || gimple_code (gsi_stmt (gsi
)) != GIMPLE_LABEL
)
2229 /* Don't warn for terminated branches, i.e. when the subsequent case labels
2230 immediately breaks. */
2233 /* Skip all immediately following labels. */
2234 while (!gsi_end_p (gsi
)
2235 && (gimple_code (gsi_stmt (gsi
)) == GIMPLE_LABEL
2236 || gimple_code (gsi_stmt (gsi
)) == GIMPLE_PREDICT
))
2237 gsi_next_nondebug (&gsi
);
2239 /* { ... something; default:; } */
2241 /* { ... something; default: break; } or
2242 { ... something; default: goto L; } */
2243 || gimple_code (gsi_stmt (gsi
)) == GIMPLE_GOTO
2244 /* { ... something; default: return; } */
2245 || gimple_code (gsi_stmt (gsi
)) == GIMPLE_RETURN
)
2251 /* Callback for walk_gimple_seq. */
2254 warn_implicit_fallthrough_r (gimple_stmt_iterator
*gsi_p
, bool *handled_ops_p
,
2255 struct walk_stmt_info
*)
2257 gimple
*stmt
= gsi_stmt (*gsi_p
);
2259 *handled_ops_p
= true;
2260 switch (gimple_code (stmt
))
2265 case GIMPLE_EH_FILTER
:
2266 case GIMPLE_TRANSACTION
:
2267 /* Walk the sub-statements. */
2268 *handled_ops_p
= false;
2271 /* Find a sequence of form:
2278 and possibly warn. */
2281 /* Found a label. Skip all immediately following labels. */
2282 while (!gsi_end_p (*gsi_p
)
2283 && gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_LABEL
)
2284 gsi_next_nondebug (gsi_p
);
2286 /* There might be no more statements. */
2287 if (gsi_end_p (*gsi_p
))
2288 return integer_zero_node
;
2290 /* Vector of labels that fall through. */
2291 auto_vec
<struct label_entry
> labels
;
2293 gimple
*prev
= collect_fallthrough_labels (gsi_p
, &labels
, &prevloc
);
2295 /* There might be no more statements. */
2296 if (gsi_end_p (*gsi_p
))
2297 return integer_zero_node
;
2299 gimple
*next
= gsi_stmt (*gsi_p
);
2301 /* If what follows is a label, then we may have a fallthrough. */
2302 if (gimple_code (next
) == GIMPLE_LABEL
2303 && gimple_has_location (next
)
2304 && (label
= gimple_label_label (as_a
<glabel
*> (next
)))
2307 struct label_entry
*l
;
2308 bool warned_p
= false;
2309 auto_diagnostic_group d
;
2310 if (!should_warn_for_implicit_fallthrough (gsi_p
, label
))
2312 else if (gimple_code (prev
) == GIMPLE_LABEL
2313 && (label
= gimple_label_label (as_a
<glabel
*> (prev
)))
2314 && (l
= find_label_entry (&labels
, label
)))
2315 warned_p
= warning_at (l
->loc
, OPT_Wimplicit_fallthrough_
,
2316 "this statement may fall through");
2317 else if (!gimple_call_internal_p (prev
, IFN_FALLTHROUGH
)
2318 /* Try to be clever and don't warn when the statement
2319 can't actually fall through. */
2320 && gimple_stmt_may_fallthru (prev
)
2321 && prevloc
!= UNKNOWN_LOCATION
)
2322 warned_p
= warning_at (prevloc
,
2323 OPT_Wimplicit_fallthrough_
,
2324 "this statement may fall through");
2326 inform (gimple_location (next
), "here");
2328 /* Mark this label as processed so as to prevent multiple
2329 warnings in nested switches. */
2330 FALLTHROUGH_LABEL_P (label
) = true;
2332 /* So that next warn_implicit_fallthrough_r will start looking for
2333 a new sequence starting with this label. */
2344 /* Warn when a switch case falls through. */
2347 maybe_warn_implicit_fallthrough (gimple_seq seq
)
2349 if (!warn_implicit_fallthrough
)
2352 /* This warning is meant for C/C++/ObjC/ObjC++ only. */
2355 || lang_GNU_OBJC ()))
2358 struct walk_stmt_info wi
;
2359 memset (&wi
, 0, sizeof (wi
));
2360 walk_gimple_seq (seq
, warn_implicit_fallthrough_r
, NULL
, &wi
);
2363 /* Callback for walk_gimple_seq. */
2366 expand_FALLTHROUGH_r (gimple_stmt_iterator
*gsi_p
, bool *handled_ops_p
,
2367 struct walk_stmt_info
*wi
)
2369 gimple
*stmt
= gsi_stmt (*gsi_p
);
2371 *handled_ops_p
= true;
2372 switch (gimple_code (stmt
))
2377 case GIMPLE_EH_FILTER
:
2378 case GIMPLE_TRANSACTION
:
2379 /* Walk the sub-statements. */
2380 *handled_ops_p
= false;
2383 if (gimple_call_internal_p (stmt
, IFN_FALLTHROUGH
))
2385 gsi_remove (gsi_p
, true);
2386 if (gsi_end_p (*gsi_p
))
2388 *static_cast<location_t
*>(wi
->info
) = gimple_location (stmt
);
2389 return integer_zero_node
;
2393 location_t loc
= gimple_location (stmt
);
2395 gimple_stmt_iterator gsi2
= *gsi_p
;
2396 stmt
= gsi_stmt (gsi2
);
2397 if (gimple_code (stmt
) == GIMPLE_GOTO
&& !gimple_has_location (stmt
))
2399 /* Go on until the artificial label. */
2400 tree goto_dest
= gimple_goto_dest (stmt
);
2401 for (; !gsi_end_p (gsi2
); gsi_next (&gsi2
))
2403 if (gimple_code (gsi_stmt (gsi2
)) == GIMPLE_LABEL
2404 && gimple_label_label (as_a
<glabel
*> (gsi_stmt (gsi2
)))
2409 /* Not found? Stop. */
2410 if (gsi_end_p (gsi2
))
2413 /* Look one past it. */
2417 /* We're looking for a case label or default label here. */
2418 while (!gsi_end_p (gsi2
))
2420 stmt
= gsi_stmt (gsi2
);
2421 if (gimple_code (stmt
) == GIMPLE_LABEL
)
2423 tree label
= gimple_label_label (as_a
<glabel
*> (stmt
));
2424 if (gimple_has_location (stmt
) && DECL_ARTIFICIAL (label
))
2430 else if (gimple_call_internal_p (stmt
, IFN_ASAN_MARK
))
2432 else if (!is_gimple_debug (stmt
))
2433 /* Anything else is not expected. */
2438 pedwarn (loc
, 0, "attribute %<fallthrough%> not preceding "
2439 "a case label or default label");
2448 /* Expand all FALLTHROUGH () calls in SEQ. */
2451 expand_FALLTHROUGH (gimple_seq
*seq_p
)
2453 struct walk_stmt_info wi
;
2455 memset (&wi
, 0, sizeof (wi
));
2456 wi
.info
= (void *) &loc
;
2457 walk_gimple_seq_mod (seq_p
, expand_FALLTHROUGH_r
, NULL
, &wi
);
2458 if (wi
.callback_result
== integer_zero_node
)
2459 /* We've found [[fallthrough]]; at the end of a switch, which the C++
2460 standard says is ill-formed; see [dcl.attr.fallthrough]. */
2461 pedwarn (loc
, 0, "attribute %<fallthrough%> not preceding "
2462 "a case label or default label");
2466 /* Gimplify a SWITCH_EXPR, and collect the vector of labels it can
2469 static enum gimplify_status
2470 gimplify_switch_expr (tree
*expr_p
, gimple_seq
*pre_p
)
2472 tree switch_expr
= *expr_p
;
2473 gimple_seq switch_body_seq
= NULL
;
2474 enum gimplify_status ret
;
2475 tree index_type
= TREE_TYPE (switch_expr
);
2476 if (index_type
== NULL_TREE
)
2477 index_type
= TREE_TYPE (SWITCH_COND (switch_expr
));
2479 ret
= gimplify_expr (&SWITCH_COND (switch_expr
), pre_p
, NULL
, is_gimple_val
,
2481 if (ret
== GS_ERROR
|| ret
== GS_UNHANDLED
)
2484 if (SWITCH_BODY (switch_expr
))
2487 vec
<tree
> saved_labels
;
2488 hash_set
<tree
> *saved_live_switch_vars
= NULL
;
2489 tree default_case
= NULL_TREE
;
2490 gswitch
*switch_stmt
;
2492 /* Save old labels, get new ones from body, then restore the old
2493 labels. Save all the things from the switch body to append after. */
2494 saved_labels
= gimplify_ctxp
->case_labels
;
2495 gimplify_ctxp
->case_labels
.create (8);
2497 /* Do not create live_switch_vars if SWITCH_BODY is not a BIND_EXPR. */
2498 saved_live_switch_vars
= gimplify_ctxp
->live_switch_vars
;
2499 tree_code body_type
= TREE_CODE (SWITCH_BODY (switch_expr
));
2500 if (body_type
== BIND_EXPR
|| body_type
== STATEMENT_LIST
)
2501 gimplify_ctxp
->live_switch_vars
= new hash_set
<tree
> (4);
2503 gimplify_ctxp
->live_switch_vars
= NULL
;
2505 bool old_in_switch_expr
= gimplify_ctxp
->in_switch_expr
;
2506 gimplify_ctxp
->in_switch_expr
= true;
2508 gimplify_stmt (&SWITCH_BODY (switch_expr
), &switch_body_seq
);
2510 gimplify_ctxp
->in_switch_expr
= old_in_switch_expr
;
2511 maybe_warn_switch_unreachable (switch_body_seq
);
2512 maybe_warn_implicit_fallthrough (switch_body_seq
);
2513 /* Only do this for the outermost GIMPLE_SWITCH. */
2514 if (!gimplify_ctxp
->in_switch_expr
)
2515 expand_FALLTHROUGH (&switch_body_seq
);
2517 labels
= gimplify_ctxp
->case_labels
;
2518 gimplify_ctxp
->case_labels
= saved_labels
;
2520 if (gimplify_ctxp
->live_switch_vars
)
2522 gcc_assert (gimplify_ctxp
->live_switch_vars
->is_empty ());
2523 delete gimplify_ctxp
->live_switch_vars
;
2525 gimplify_ctxp
->live_switch_vars
= saved_live_switch_vars
;
2527 preprocess_case_label_vec_for_gimple (labels
, index_type
,
2530 bool add_bind
= false;
2533 glabel
*new_default
;
2536 = build_case_label (NULL_TREE
, NULL_TREE
,
2537 create_artificial_label (UNKNOWN_LOCATION
));
2538 if (old_in_switch_expr
)
2540 SWITCH_BREAK_LABEL_P (CASE_LABEL (default_case
)) = 1;
2543 new_default
= gimple_build_label (CASE_LABEL (default_case
));
2544 gimplify_seq_add_stmt (&switch_body_seq
, new_default
);
2546 else if (old_in_switch_expr
)
2548 gimple
*last
= gimple_seq_last_stmt (switch_body_seq
);
2549 if (last
&& gimple_code (last
) == GIMPLE_LABEL
)
2551 tree label
= gimple_label_label (as_a
<glabel
*> (last
));
2552 if (SWITCH_BREAK_LABEL_P (label
))
2557 switch_stmt
= gimple_build_switch (SWITCH_COND (switch_expr
),
2558 default_case
, labels
);
2559 /* For the benefit of -Wimplicit-fallthrough, if switch_body_seq
2560 ends with a GIMPLE_LABEL holding SWITCH_BREAK_LABEL_P LABEL_DECL,
2561 wrap the GIMPLE_SWITCH up to that GIMPLE_LABEL into a GIMPLE_BIND,
2562 so that we can easily find the start and end of the switch
2566 gimple_seq bind_body
= NULL
;
2567 gimplify_seq_add_stmt (&bind_body
, switch_stmt
);
2568 gimple_seq_add_seq (&bind_body
, switch_body_seq
);
2569 gbind
*bind
= gimple_build_bind (NULL_TREE
, bind_body
, NULL_TREE
);
2570 gimple_set_location (bind
, EXPR_LOCATION (switch_expr
));
2571 gimplify_seq_add_stmt (pre_p
, bind
);
2575 gimplify_seq_add_stmt (pre_p
, switch_stmt
);
2576 gimplify_seq_add_seq (pre_p
, switch_body_seq
);
2586 /* Gimplify the LABEL_EXPR pointed to by EXPR_P. */
2588 static enum gimplify_status
2589 gimplify_label_expr (tree
*expr_p
, gimple_seq
*pre_p
)
2591 gcc_assert (decl_function_context (LABEL_EXPR_LABEL (*expr_p
))
2592 == current_function_decl
);
2594 tree label
= LABEL_EXPR_LABEL (*expr_p
);
2595 glabel
*label_stmt
= gimple_build_label (label
);
2596 gimple_set_location (label_stmt
, EXPR_LOCATION (*expr_p
));
2597 gimplify_seq_add_stmt (pre_p
, label_stmt
);
2599 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label
)))
2600 gimple_seq_add_stmt (pre_p
, gimple_build_predict (PRED_COLD_LABEL
,
2602 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label
)))
2603 gimple_seq_add_stmt (pre_p
, gimple_build_predict (PRED_HOT_LABEL
,
2609 /* Gimplify the CASE_LABEL_EXPR pointed to by EXPR_P. */
2611 static enum gimplify_status
2612 gimplify_case_label_expr (tree
*expr_p
, gimple_seq
*pre_p
)
2614 struct gimplify_ctx
*ctxp
;
2617 /* Invalid programs can play Duff's Device type games with, for example,
2618 #pragma omp parallel. At least in the C front end, we don't
2619 detect such invalid branches until after gimplification, in the
2620 diagnose_omp_blocks pass. */
2621 for (ctxp
= gimplify_ctxp
; ; ctxp
= ctxp
->prev_context
)
2622 if (ctxp
->case_labels
.exists ())
2625 tree label
= CASE_LABEL (*expr_p
);
2626 label_stmt
= gimple_build_label (label
);
2627 gimple_set_location (label_stmt
, EXPR_LOCATION (*expr_p
));
2628 ctxp
->case_labels
.safe_push (*expr_p
);
2629 gimplify_seq_add_stmt (pre_p
, label_stmt
);
2631 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label
)))
2632 gimple_seq_add_stmt (pre_p
, gimple_build_predict (PRED_COLD_LABEL
,
2634 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label
)))
2635 gimple_seq_add_stmt (pre_p
, gimple_build_predict (PRED_HOT_LABEL
,
2641 /* Build a GOTO to the LABEL_DECL pointed to by LABEL_P, building it first
2645 build_and_jump (tree
*label_p
)
2647 if (label_p
== NULL
)
2648 /* If there's nowhere to jump, just fall through. */
2651 if (*label_p
== NULL_TREE
)
2653 tree label
= create_artificial_label (UNKNOWN_LOCATION
);
2657 return build1 (GOTO_EXPR
, void_type_node
, *label_p
);
2660 /* Gimplify an EXIT_EXPR by converting to a GOTO_EXPR inside a COND_EXPR.
2661 This also involves building a label to jump to and communicating it to
2662 gimplify_loop_expr through gimplify_ctxp->exit_label. */
2664 static enum gimplify_status
2665 gimplify_exit_expr (tree
*expr_p
)
2667 tree cond
= TREE_OPERAND (*expr_p
, 0);
2670 expr
= build_and_jump (&gimplify_ctxp
->exit_label
);
2671 expr
= build3 (COND_EXPR
, void_type_node
, cond
, expr
, NULL_TREE
);
2677 /* *EXPR_P is a COMPONENT_REF being used as an rvalue. If its type is
2678 different from its canonical type, wrap the whole thing inside a
2679 NOP_EXPR and force the type of the COMPONENT_REF to be the canonical
2682 The canonical type of a COMPONENT_REF is the type of the field being
2683 referenced--unless the field is a bit-field which can be read directly
2684 in a smaller mode, in which case the canonical type is the
2685 sign-appropriate type corresponding to that mode. */
2688 canonicalize_component_ref (tree
*expr_p
)
2690 tree expr
= *expr_p
;
2693 gcc_assert (TREE_CODE (expr
) == COMPONENT_REF
);
2695 if (INTEGRAL_TYPE_P (TREE_TYPE (expr
)))
2696 type
= TREE_TYPE (get_unwidened (expr
, NULL_TREE
));
2698 type
= TREE_TYPE (TREE_OPERAND (expr
, 1));
2700 /* One could argue that all the stuff below is not necessary for
2701 the non-bitfield case and declare it a FE error if type
2702 adjustment would be needed. */
2703 if (TREE_TYPE (expr
) != type
)
2705 #ifdef ENABLE_TYPES_CHECKING
2706 tree old_type
= TREE_TYPE (expr
);
2710 /* We need to preserve qualifiers and propagate them from
2712 type_quals
= TYPE_QUALS (type
)
2713 | TYPE_QUALS (TREE_TYPE (TREE_OPERAND (expr
, 0)));
2714 if (TYPE_QUALS (type
) != type_quals
)
2715 type
= build_qualified_type (TYPE_MAIN_VARIANT (type
), type_quals
);
2717 /* Set the type of the COMPONENT_REF to the underlying type. */
2718 TREE_TYPE (expr
) = type
;
2720 #ifdef ENABLE_TYPES_CHECKING
2721 /* It is now a FE error, if the conversion from the canonical
2722 type to the original expression type is not useless. */
2723 gcc_assert (useless_type_conversion_p (old_type
, type
));
2728 /* If a NOP conversion is changing a pointer to array of foo to a pointer
2729 to foo, embed that change in the ADDR_EXPR by converting
2734 where L is the lower bound. For simplicity, only do this for constant
2736 The constraint is that the type of &array[L] is trivially convertible
2740 canonicalize_addr_expr (tree
*expr_p
)
2742 tree expr
= *expr_p
;
2743 tree addr_expr
= TREE_OPERAND (expr
, 0);
2744 tree datype
, ddatype
, pddatype
;
2746 /* We simplify only conversions from an ADDR_EXPR to a pointer type. */
2747 if (!POINTER_TYPE_P (TREE_TYPE (expr
))
2748 || TREE_CODE (addr_expr
) != ADDR_EXPR
)
2751 /* The addr_expr type should be a pointer to an array. */
2752 datype
= TREE_TYPE (TREE_TYPE (addr_expr
));
2753 if (TREE_CODE (datype
) != ARRAY_TYPE
)
2756 /* The pointer to element type shall be trivially convertible to
2757 the expression pointer type. */
2758 ddatype
= TREE_TYPE (datype
);
2759 pddatype
= build_pointer_type (ddatype
);
2760 if (!useless_type_conversion_p (TYPE_MAIN_VARIANT (TREE_TYPE (expr
)),
2764 /* The lower bound and element sizes must be constant. */
2765 if (!TYPE_SIZE_UNIT (ddatype
)
2766 || TREE_CODE (TYPE_SIZE_UNIT (ddatype
)) != INTEGER_CST
2767 || !TYPE_DOMAIN (datype
) || !TYPE_MIN_VALUE (TYPE_DOMAIN (datype
))
2768 || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (datype
))) != INTEGER_CST
)
2771 /* All checks succeeded. Build a new node to merge the cast. */
2772 *expr_p
= build4 (ARRAY_REF
, ddatype
, TREE_OPERAND (addr_expr
, 0),
2773 TYPE_MIN_VALUE (TYPE_DOMAIN (datype
)),
2774 NULL_TREE
, NULL_TREE
);
2775 *expr_p
= build1 (ADDR_EXPR
, pddatype
, *expr_p
);
2777 /* We can have stripped a required restrict qualifier above. */
2778 if (!useless_type_conversion_p (TREE_TYPE (expr
), TREE_TYPE (*expr_p
)))
2779 *expr_p
= fold_convert (TREE_TYPE (expr
), *expr_p
);
2782 /* *EXPR_P is a NOP_EXPR or CONVERT_EXPR. Remove it and/or other conversions
2783 underneath as appropriate. */
2785 static enum gimplify_status
2786 gimplify_conversion (tree
*expr_p
)
2788 location_t loc
= EXPR_LOCATION (*expr_p
);
2789 gcc_assert (CONVERT_EXPR_P (*expr_p
));
2791 /* Then strip away all but the outermost conversion. */
2792 STRIP_SIGN_NOPS (TREE_OPERAND (*expr_p
, 0));
2794 /* And remove the outermost conversion if it's useless. */
2795 if (tree_ssa_useless_type_conversion (*expr_p
))
2796 *expr_p
= TREE_OPERAND (*expr_p
, 0);
2798 /* If we still have a conversion at the toplevel,
2799 then canonicalize some constructs. */
2800 if (CONVERT_EXPR_P (*expr_p
))
2802 tree sub
= TREE_OPERAND (*expr_p
, 0);
2804 /* If a NOP conversion is changing the type of a COMPONENT_REF
2805 expression, then canonicalize its type now in order to expose more
2806 redundant conversions. */
2807 if (TREE_CODE (sub
) == COMPONENT_REF
)
2808 canonicalize_component_ref (&TREE_OPERAND (*expr_p
, 0));
2810 /* If a NOP conversion is changing a pointer to array of foo
2811 to a pointer to foo, embed that change in the ADDR_EXPR. */
2812 else if (TREE_CODE (sub
) == ADDR_EXPR
)
2813 canonicalize_addr_expr (expr_p
);
2816 /* If we have a conversion to a non-register type force the
2817 use of a VIEW_CONVERT_EXPR instead. */
2818 if (CONVERT_EXPR_P (*expr_p
) && !is_gimple_reg_type (TREE_TYPE (*expr_p
)))
2819 *expr_p
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, TREE_TYPE (*expr_p
),
2820 TREE_OPERAND (*expr_p
, 0));
2822 /* Canonicalize CONVERT_EXPR to NOP_EXPR. */
2823 if (TREE_CODE (*expr_p
) == CONVERT_EXPR
)
2824 TREE_SET_CODE (*expr_p
, NOP_EXPR
);
2829 /* Gimplify a VAR_DECL or PARM_DECL. Return GS_OK if we expanded a
2830 DECL_VALUE_EXPR, and it's worth re-examining things. */
2832 static enum gimplify_status
2833 gimplify_var_or_parm_decl (tree
*expr_p
)
2835 tree decl
= *expr_p
;
2837 /* ??? If this is a local variable, and it has not been seen in any
2838 outer BIND_EXPR, then it's probably the result of a duplicate
2839 declaration, for which we've already issued an error. It would
2840 be really nice if the front end wouldn't leak these at all.
2841 Currently the only known culprit is C++ destructors, as seen
2842 in g++.old-deja/g++.jason/binding.C. */
2844 && !DECL_SEEN_IN_BIND_EXPR_P (decl
)
2845 && !TREE_STATIC (decl
) && !DECL_EXTERNAL (decl
)
2846 && decl_function_context (decl
) == current_function_decl
)
2848 gcc_assert (seen_error ());
2852 /* When within an OMP context, notice uses of variables. */
2853 if (gimplify_omp_ctxp
&& omp_notice_variable (gimplify_omp_ctxp
, decl
, true))
2856 /* If the decl is an alias for another expression, substitute it now. */
2857 if (DECL_HAS_VALUE_EXPR_P (decl
))
2859 *expr_p
= unshare_expr (DECL_VALUE_EXPR (decl
));
2866 /* Recalculate the value of the TREE_SIDE_EFFECTS flag for T. */
2869 recalculate_side_effects (tree t
)
2871 enum tree_code code
= TREE_CODE (t
);
2872 int len
= TREE_OPERAND_LENGTH (t
);
2875 switch (TREE_CODE_CLASS (code
))
2877 case tcc_expression
:
2883 case PREDECREMENT_EXPR
:
2884 case PREINCREMENT_EXPR
:
2885 case POSTDECREMENT_EXPR
:
2886 case POSTINCREMENT_EXPR
:
2887 /* All of these have side-effects, no matter what their
2896 case tcc_comparison
: /* a comparison expression */
2897 case tcc_unary
: /* a unary arithmetic expression */
2898 case tcc_binary
: /* a binary arithmetic expression */
2899 case tcc_reference
: /* a reference */
2900 case tcc_vl_exp
: /* a function call */
2901 TREE_SIDE_EFFECTS (t
) = TREE_THIS_VOLATILE (t
);
2902 for (i
= 0; i
< len
; ++i
)
2904 tree op
= TREE_OPERAND (t
, i
);
2905 if (op
&& TREE_SIDE_EFFECTS (op
))
2906 TREE_SIDE_EFFECTS (t
) = 1;
2911 /* No side-effects. */
2919 /* Gimplify the COMPONENT_REF, ARRAY_REF, REALPART_EXPR or IMAGPART_EXPR
2923 : min_lval '[' val ']'
2925 | compound_lval '[' val ']'
2926 | compound_lval '.' ID
2928 This is not part of the original SIMPLE definition, which separates
2929 array and member references, but it seems reasonable to handle them
2930 together. Also, this way we don't run into problems with union
2931 aliasing; gcc requires that for accesses through a union to alias, the
2932 union reference must be explicit, which was not always the case when we
2933 were splitting up array and member refs.
2935 PRE_P points to the sequence where side effects that must happen before
2936 *EXPR_P should be stored.
2938 POST_P points to the sequence where side effects that must happen after
2939 *EXPR_P should be stored. */
2941 static enum gimplify_status
2942 gimplify_compound_lval (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
2943 fallback_t fallback
)
2946 enum gimplify_status ret
= GS_ALL_DONE
, tret
;
2948 location_t loc
= EXPR_LOCATION (*expr_p
);
2949 tree expr
= *expr_p
;
2951 /* Create a stack of the subexpressions so later we can walk them in
2952 order from inner to outer. */
2953 auto_vec
<tree
, 10> expr_stack
;
2955 /* We can handle anything that get_inner_reference can deal with. */
2956 for (p
= expr_p
; ; p
= &TREE_OPERAND (*p
, 0))
2959 /* Fold INDIRECT_REFs now to turn them into ARRAY_REFs. */
2960 if (TREE_CODE (*p
) == INDIRECT_REF
)
2961 *p
= fold_indirect_ref_loc (loc
, *p
);
2963 if (handled_component_p (*p
))
2965 /* Expand DECL_VALUE_EXPR now. In some cases that may expose
2966 additional COMPONENT_REFs. */
2967 else if ((VAR_P (*p
) || TREE_CODE (*p
) == PARM_DECL
)
2968 && gimplify_var_or_parm_decl (p
) == GS_OK
)
2973 expr_stack
.safe_push (*p
);
2976 gcc_assert (expr_stack
.length ());
2978 /* Now EXPR_STACK is a stack of pointers to all the refs we've
2979 walked through and P points to the innermost expression.
2981 Java requires that we elaborated nodes in source order. That
2982 means we must gimplify the inner expression followed by each of
2983 the indices, in order. But we can't gimplify the inner
2984 expression until we deal with any variable bounds, sizes, or
2985 positions in order to deal with PLACEHOLDER_EXPRs.
2987 So we do this in three steps. First we deal with the annotations
2988 for any variables in the components, then we gimplify the base,
2989 then we gimplify any indices, from left to right. */
2990 for (i
= expr_stack
.length () - 1; i
>= 0; i
--)
2992 tree t
= expr_stack
[i
];
2994 if (TREE_CODE (t
) == ARRAY_REF
|| TREE_CODE (t
) == ARRAY_RANGE_REF
)
2996 /* Gimplify the low bound and element type size and put them into
2997 the ARRAY_REF. If these values are set, they have already been
2999 if (TREE_OPERAND (t
, 2) == NULL_TREE
)
3001 tree low
= unshare_expr (array_ref_low_bound (t
));
3002 if (!is_gimple_min_invariant (low
))
3004 TREE_OPERAND (t
, 2) = low
;
3005 tret
= gimplify_expr (&TREE_OPERAND (t
, 2), pre_p
,
3006 post_p
, is_gimple_reg
,
3008 ret
= MIN (ret
, tret
);
3013 tret
= gimplify_expr (&TREE_OPERAND (t
, 2), pre_p
, post_p
,
3014 is_gimple_reg
, fb_rvalue
);
3015 ret
= MIN (ret
, tret
);
3018 if (TREE_OPERAND (t
, 3) == NULL_TREE
)
3020 tree elmt_size
= array_ref_element_size (t
);
3021 if (!is_gimple_min_invariant (elmt_size
))
3023 elmt_size
= unshare_expr (elmt_size
);
3024 tree elmt_type
= TREE_TYPE (TREE_TYPE (TREE_OPERAND (t
, 0)));
3025 tree factor
= size_int (TYPE_ALIGN_UNIT (elmt_type
));
3027 /* Divide the element size by the alignment of the element
3029 elmt_size
= size_binop_loc (loc
, EXACT_DIV_EXPR
,
3032 TREE_OPERAND (t
, 3) = elmt_size
;
3033 tret
= gimplify_expr (&TREE_OPERAND (t
, 3), pre_p
,
3034 post_p
, is_gimple_reg
,
3036 ret
= MIN (ret
, tret
);
3041 tret
= gimplify_expr (&TREE_OPERAND (t
, 3), pre_p
, post_p
,
3042 is_gimple_reg
, fb_rvalue
);
3043 ret
= MIN (ret
, tret
);
3046 else if (TREE_CODE (t
) == COMPONENT_REF
)
3048 /* Set the field offset into T and gimplify it. */
3049 if (TREE_OPERAND (t
, 2) == NULL_TREE
)
3051 tree offset
= component_ref_field_offset (t
);
3052 if (!is_gimple_min_invariant (offset
))
3054 offset
= unshare_expr (offset
);
3055 tree field
= TREE_OPERAND (t
, 1);
3057 = size_int (DECL_OFFSET_ALIGN (field
) / BITS_PER_UNIT
);
3059 /* Divide the offset by its alignment. */
3060 offset
= size_binop_loc (loc
, EXACT_DIV_EXPR
,
3063 TREE_OPERAND (t
, 2) = offset
;
3064 tret
= gimplify_expr (&TREE_OPERAND (t
, 2), pre_p
,
3065 post_p
, is_gimple_reg
,
3067 ret
= MIN (ret
, tret
);
3072 tret
= gimplify_expr (&TREE_OPERAND (t
, 2), pre_p
, post_p
,
3073 is_gimple_reg
, fb_rvalue
);
3074 ret
= MIN (ret
, tret
);
3079 /* Step 2 is to gimplify the base expression. Make sure lvalue is set
3080 so as to match the min_lval predicate. Failure to do so may result
3081 in the creation of large aggregate temporaries. */
3082 tret
= gimplify_expr (p
, pre_p
, post_p
, is_gimple_min_lval
,
3083 fallback
| fb_lvalue
);
3084 ret
= MIN (ret
, tret
);
3086 /* And finally, the indices and operands of ARRAY_REF. During this
3087 loop we also remove any useless conversions. */
3088 for (; expr_stack
.length () > 0; )
3090 tree t
= expr_stack
.pop ();
3092 if (TREE_CODE (t
) == ARRAY_REF
|| TREE_CODE (t
) == ARRAY_RANGE_REF
)
3094 /* Gimplify the dimension. */
3095 if (!is_gimple_min_invariant (TREE_OPERAND (t
, 1)))
3097 tret
= gimplify_expr (&TREE_OPERAND (t
, 1), pre_p
, post_p
,
3098 is_gimple_val
, fb_rvalue
);
3099 ret
= MIN (ret
, tret
);
3103 STRIP_USELESS_TYPE_CONVERSION (TREE_OPERAND (t
, 0));
3105 /* The innermost expression P may have originally had
3106 TREE_SIDE_EFFECTS set which would have caused all the outer
3107 expressions in *EXPR_P leading to P to also have had
3108 TREE_SIDE_EFFECTS set. */
3109 recalculate_side_effects (t
);
3112 /* If the outermost expression is a COMPONENT_REF, canonicalize its type. */
3113 if ((fallback
& fb_rvalue
) && TREE_CODE (*expr_p
) == COMPONENT_REF
)
3115 canonicalize_component_ref (expr_p
);
3118 expr_stack
.release ();
3120 gcc_assert (*expr_p
== expr
|| ret
!= GS_ALL_DONE
);
3125 /* Gimplify the self modifying expression pointed to by EXPR_P
3128 PRE_P points to the list where side effects that must happen before
3129 *EXPR_P should be stored.
3131 POST_P points to the list where side effects that must happen after
3132 *EXPR_P should be stored.
3134 WANT_VALUE is nonzero iff we want to use the value of this expression
3135 in another expression.
3137 ARITH_TYPE is the type the computation should be performed in. */
3139 enum gimplify_status
3140 gimplify_self_mod_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
3141 bool want_value
, tree arith_type
)
3143 enum tree_code code
;
3144 tree lhs
, lvalue
, rhs
, t1
;
3145 gimple_seq post
= NULL
, *orig_post_p
= post_p
;
3147 enum tree_code arith_code
;
3148 enum gimplify_status ret
;
3149 location_t loc
= EXPR_LOCATION (*expr_p
);
3151 code
= TREE_CODE (*expr_p
);
3153 gcc_assert (code
== POSTINCREMENT_EXPR
|| code
== POSTDECREMENT_EXPR
3154 || code
== PREINCREMENT_EXPR
|| code
== PREDECREMENT_EXPR
);
3156 /* Prefix or postfix? */
3157 if (code
== POSTINCREMENT_EXPR
|| code
== POSTDECREMENT_EXPR
)
3158 /* Faster to treat as prefix if result is not used. */
3159 postfix
= want_value
;
3163 /* For postfix, make sure the inner expression's post side effects
3164 are executed after side effects from this expression. */
3168 /* Add or subtract? */
3169 if (code
== PREINCREMENT_EXPR
|| code
== POSTINCREMENT_EXPR
)
3170 arith_code
= PLUS_EXPR
;
3172 arith_code
= MINUS_EXPR
;
3174 /* Gimplify the LHS into a GIMPLE lvalue. */
3175 lvalue
= TREE_OPERAND (*expr_p
, 0);
3176 ret
= gimplify_expr (&lvalue
, pre_p
, post_p
, is_gimple_lvalue
, fb_lvalue
);
3177 if (ret
== GS_ERROR
)
3180 /* Extract the operands to the arithmetic operation. */
3182 rhs
= TREE_OPERAND (*expr_p
, 1);
3184 /* For postfix operator, we evaluate the LHS to an rvalue and then use
3185 that as the result value and in the postqueue operation. */
3188 ret
= gimplify_expr (&lhs
, pre_p
, post_p
, is_gimple_val
, fb_rvalue
);
3189 if (ret
== GS_ERROR
)
3192 lhs
= get_initialized_tmp_var (lhs
, pre_p
);
3195 /* For POINTERs increment, use POINTER_PLUS_EXPR. */
3196 if (POINTER_TYPE_P (TREE_TYPE (lhs
)))
3198 rhs
= convert_to_ptrofftype_loc (loc
, rhs
);
3199 if (arith_code
== MINUS_EXPR
)
3200 rhs
= fold_build1_loc (loc
, NEGATE_EXPR
, TREE_TYPE (rhs
), rhs
);
3201 t1
= fold_build2 (POINTER_PLUS_EXPR
, TREE_TYPE (*expr_p
), lhs
, rhs
);
3204 t1
= fold_convert (TREE_TYPE (*expr_p
),
3205 fold_build2 (arith_code
, arith_type
,
3206 fold_convert (arith_type
, lhs
),
3207 fold_convert (arith_type
, rhs
)));
3211 gimplify_assign (lvalue
, t1
, pre_p
);
3212 gimplify_seq_add_seq (orig_post_p
, post
);
3218 *expr_p
= build2 (MODIFY_EXPR
, TREE_TYPE (lvalue
), lvalue
, t1
);
3223 /* If *EXPR_P has a variable sized type, wrap it in a WITH_SIZE_EXPR. */
3226 maybe_with_size_expr (tree
*expr_p
)
3228 tree expr
= *expr_p
;
3229 tree type
= TREE_TYPE (expr
);
3232 /* If we've already wrapped this or the type is error_mark_node, we can't do
3234 if (TREE_CODE (expr
) == WITH_SIZE_EXPR
3235 || type
== error_mark_node
)
3238 /* If the size isn't known or is a constant, we have nothing to do. */
3239 size
= TYPE_SIZE_UNIT (type
);
3240 if (!size
|| poly_int_tree_p (size
))
3243 /* Otherwise, make a WITH_SIZE_EXPR. */
3244 size
= unshare_expr (size
);
3245 size
= SUBSTITUTE_PLACEHOLDER_IN_EXPR (size
, expr
);
3246 *expr_p
= build2 (WITH_SIZE_EXPR
, type
, expr
, size
);
3249 /* Helper for gimplify_call_expr. Gimplify a single argument *ARG_P
3250 Store any side-effects in PRE_P. CALL_LOCATION is the location of
3251 the CALL_EXPR. If ALLOW_SSA is set the actual parameter may be
3252 gimplified to an SSA name. */
3254 enum gimplify_status
3255 gimplify_arg (tree
*arg_p
, gimple_seq
*pre_p
, location_t call_location
,
3258 bool (*test
) (tree
);
3261 /* In general, we allow lvalues for function arguments to avoid
3262 extra overhead of copying large aggregates out of even larger
3263 aggregates into temporaries only to copy the temporaries to
3264 the argument list. Make optimizers happy by pulling out to
3265 temporaries those types that fit in registers. */
3266 if (is_gimple_reg_type (TREE_TYPE (*arg_p
)))
3267 test
= is_gimple_val
, fb
= fb_rvalue
;
3270 test
= is_gimple_lvalue
, fb
= fb_either
;
3271 /* Also strip a TARGET_EXPR that would force an extra copy. */
3272 if (TREE_CODE (*arg_p
) == TARGET_EXPR
)
3274 tree init
= TARGET_EXPR_INITIAL (*arg_p
);
3276 && !VOID_TYPE_P (TREE_TYPE (init
)))
3281 /* If this is a variable sized type, we must remember the size. */
3282 maybe_with_size_expr (arg_p
);
3284 /* FIXME diagnostics: This will mess up gcc.dg/Warray-bounds.c. */
3285 /* Make sure arguments have the same location as the function call
3287 protected_set_expr_location (*arg_p
, call_location
);
3289 /* There is a sequence point before a function call. Side effects in
3290 the argument list must occur before the actual call. So, when
3291 gimplifying arguments, force gimplify_expr to use an internal
3292 post queue which is then appended to the end of PRE_P. */
3293 return gimplify_expr (arg_p
, pre_p
, NULL
, test
, fb
, allow_ssa
);
3296 /* Don't fold inside offloading or taskreg regions: it can break code by
3297 adding decl references that weren't in the source. We'll do it during
3298 omplower pass instead. */
3301 maybe_fold_stmt (gimple_stmt_iterator
*gsi
)
3303 struct gimplify_omp_ctx
*ctx
;
3304 for (ctx
= gimplify_omp_ctxp
; ctx
; ctx
= ctx
->outer_context
)
3305 if ((ctx
->region_type
& (ORT_TARGET
| ORT_PARALLEL
| ORT_TASK
)) != 0)
3307 else if ((ctx
->region_type
& ORT_HOST_TEAMS
) == ORT_HOST_TEAMS
)
3309 /* Delay folding of builtins until the IL is in consistent state
3310 so the diagnostic machinery can do a better job. */
3311 if (gimple_call_builtin_p (gsi_stmt (*gsi
)))
3313 return fold_stmt (gsi
);
3316 /* Gimplify the CALL_EXPR node *EXPR_P into the GIMPLE sequence PRE_P.
3317 WANT_VALUE is true if the result of the call is desired. */
3319 static enum gimplify_status
3320 gimplify_call_expr (tree
*expr_p
, gimple_seq
*pre_p
, bool want_value
)
3322 tree fndecl
, parms
, p
, fnptrtype
;
3323 enum gimplify_status ret
;
3326 bool builtin_va_start_p
= false;
3327 location_t loc
= EXPR_LOCATION (*expr_p
);
3329 gcc_assert (TREE_CODE (*expr_p
) == CALL_EXPR
);
3331 /* For reliable diagnostics during inlining, it is necessary that
3332 every call_expr be annotated with file and line. */
3333 if (! EXPR_HAS_LOCATION (*expr_p
))
3334 SET_EXPR_LOCATION (*expr_p
, input_location
);
3336 /* Gimplify internal functions created in the FEs. */
3337 if (CALL_EXPR_FN (*expr_p
) == NULL_TREE
)
3342 nargs
= call_expr_nargs (*expr_p
);
3343 enum internal_fn ifn
= CALL_EXPR_IFN (*expr_p
);
3344 auto_vec
<tree
> vargs (nargs
);
3346 for (i
= 0; i
< nargs
; i
++)
3348 gimplify_arg (&CALL_EXPR_ARG (*expr_p
, i
), pre_p
,
3349 EXPR_LOCATION (*expr_p
));
3350 vargs
.quick_push (CALL_EXPR_ARG (*expr_p
, i
));
3353 gcall
*call
= gimple_build_call_internal_vec (ifn
, vargs
);
3354 gimple_call_set_nothrow (call
, TREE_NOTHROW (*expr_p
));
3355 gimplify_seq_add_stmt (pre_p
, call
);
3359 /* This may be a call to a builtin function.
3361 Builtin function calls may be transformed into different
3362 (and more efficient) builtin function calls under certain
3363 circumstances. Unfortunately, gimplification can muck things
3364 up enough that the builtin expanders are not aware that certain
3365 transformations are still valid.
3367 So we attempt transformation/gimplification of the call before
3368 we gimplify the CALL_EXPR. At this time we do not manage to
3369 transform all calls in the same manner as the expanders do, but
3370 we do transform most of them. */
3371 fndecl
= get_callee_fndecl (*expr_p
);
3372 if (fndecl
&& fndecl_built_in_p (fndecl
, BUILT_IN_NORMAL
))
3373 switch (DECL_FUNCTION_CODE (fndecl
))
3375 CASE_BUILT_IN_ALLOCA
:
3376 /* If the call has been built for a variable-sized object, then we
3377 want to restore the stack level when the enclosing BIND_EXPR is
3378 exited to reclaim the allocated space; otherwise, we precisely
3379 need to do the opposite and preserve the latest stack level. */
3380 if (CALL_ALLOCA_FOR_VAR_P (*expr_p
))
3381 gimplify_ctxp
->save_stack
= true;
3383 gimplify_ctxp
->keep_stack
= true;
3386 case BUILT_IN_VA_START
:
3388 builtin_va_start_p
= TRUE
;
3389 if (call_expr_nargs (*expr_p
) < 2)
3391 error ("too few arguments to function %<va_start%>");
3392 *expr_p
= build_empty_stmt (EXPR_LOCATION (*expr_p
));
3396 if (fold_builtin_next_arg (*expr_p
, true))
3398 *expr_p
= build_empty_stmt (EXPR_LOCATION (*expr_p
));
3404 case BUILT_IN_EH_RETURN
:
3405 cfun
->calls_eh_return
= true;
3408 case BUILT_IN_CLEAR_PADDING
:
3409 if (call_expr_nargs (*expr_p
) == 1)
3411 /* Remember the original type of the argument in an internal
3412 dummy second argument, as in GIMPLE pointer conversions are
3414 p
= CALL_EXPR_ARG (*expr_p
, 0);
3416 = build_call_expr_loc (EXPR_LOCATION (*expr_p
), fndecl
, 2, p
,
3417 build_zero_cst (TREE_TYPE (p
)));
3425 if (fndecl
&& fndecl_built_in_p (fndecl
))
3427 tree new_tree
= fold_call_expr (input_location
, *expr_p
, !want_value
);
3428 if (new_tree
&& new_tree
!= *expr_p
)
3430 /* There was a transformation of this call which computes the
3431 same value, but in a more efficient way. Return and try
3438 /* Remember the original function pointer type. */
3439 fnptrtype
= TREE_TYPE (CALL_EXPR_FN (*expr_p
));
3444 && (cfun
->curr_properties
& PROP_gimple_any
) == 0)
3446 tree variant
= omp_resolve_declare_variant (fndecl
);
3447 if (variant
!= fndecl
)
3448 CALL_EXPR_FN (*expr_p
) = build1 (ADDR_EXPR
, fnptrtype
, variant
);
3451 /* There is a sequence point before the call, so any side effects in
3452 the calling expression must occur before the actual call. Force
3453 gimplify_expr to use an internal post queue. */
3454 ret
= gimplify_expr (&CALL_EXPR_FN (*expr_p
), pre_p
, NULL
,
3455 is_gimple_call_addr
, fb_rvalue
);
3457 nargs
= call_expr_nargs (*expr_p
);
3459 /* Get argument types for verification. */
3460 fndecl
= get_callee_fndecl (*expr_p
);
3463 parms
= TYPE_ARG_TYPES (TREE_TYPE (fndecl
));
3465 parms
= TYPE_ARG_TYPES (TREE_TYPE (fnptrtype
));
3467 if (fndecl
&& DECL_ARGUMENTS (fndecl
))
3468 p
= DECL_ARGUMENTS (fndecl
);
3473 for (i
= 0; i
< nargs
&& p
; i
++, p
= TREE_CHAIN (p
))
3476 /* If the last argument is __builtin_va_arg_pack () and it is not
3477 passed as a named argument, decrease the number of CALL_EXPR
3478 arguments and set instead the CALL_EXPR_VA_ARG_PACK flag. */
3481 && TREE_CODE (CALL_EXPR_ARG (*expr_p
, nargs
- 1)) == CALL_EXPR
)
3483 tree last_arg
= CALL_EXPR_ARG (*expr_p
, nargs
- 1);
3484 tree last_arg_fndecl
= get_callee_fndecl (last_arg
);
3487 && fndecl_built_in_p (last_arg_fndecl
, BUILT_IN_VA_ARG_PACK
))
3489 tree call
= *expr_p
;
3492 *expr_p
= build_call_array_loc (loc
, TREE_TYPE (call
),
3493 CALL_EXPR_FN (call
),
3494 nargs
, CALL_EXPR_ARGP (call
));
3496 /* Copy all CALL_EXPR flags, location and block, except
3497 CALL_EXPR_VA_ARG_PACK flag. */
3498 CALL_EXPR_STATIC_CHAIN (*expr_p
) = CALL_EXPR_STATIC_CHAIN (call
);
3499 CALL_EXPR_TAILCALL (*expr_p
) = CALL_EXPR_TAILCALL (call
);
3500 CALL_EXPR_RETURN_SLOT_OPT (*expr_p
)
3501 = CALL_EXPR_RETURN_SLOT_OPT (call
);
3502 CALL_FROM_THUNK_P (*expr_p
) = CALL_FROM_THUNK_P (call
);
3503 SET_EXPR_LOCATION (*expr_p
, EXPR_LOCATION (call
));
3505 /* Set CALL_EXPR_VA_ARG_PACK. */
3506 CALL_EXPR_VA_ARG_PACK (*expr_p
) = 1;
3510 /* If the call returns twice then after building the CFG the call
3511 argument computations will no longer dominate the call because
3512 we add an abnormal incoming edge to the call. So do not use SSA
3514 bool returns_twice
= call_expr_flags (*expr_p
) & ECF_RETURNS_TWICE
;
3516 /* Gimplify the function arguments. */
3519 for (i
= (PUSH_ARGS_REVERSED
? nargs
- 1 : 0);
3520 PUSH_ARGS_REVERSED
? i
>= 0 : i
< nargs
;
3521 PUSH_ARGS_REVERSED
? i
-- : i
++)
3523 enum gimplify_status t
;
3525 /* Avoid gimplifying the second argument to va_start, which needs to
3526 be the plain PARM_DECL. */
3527 if ((i
!= 1) || !builtin_va_start_p
)
3529 t
= gimplify_arg (&CALL_EXPR_ARG (*expr_p
, i
), pre_p
,
3530 EXPR_LOCATION (*expr_p
), ! returns_twice
);
3538 /* Gimplify the static chain. */
3539 if (CALL_EXPR_STATIC_CHAIN (*expr_p
))
3541 if (fndecl
&& !DECL_STATIC_CHAIN (fndecl
))
3542 CALL_EXPR_STATIC_CHAIN (*expr_p
) = NULL
;
3545 enum gimplify_status t
;
3546 t
= gimplify_arg (&CALL_EXPR_STATIC_CHAIN (*expr_p
), pre_p
,
3547 EXPR_LOCATION (*expr_p
), ! returns_twice
);
3553 /* Verify the function result. */
3554 if (want_value
&& fndecl
3555 && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fnptrtype
))))
3557 error_at (loc
, "using result of function returning %<void%>");
3561 /* Try this again in case gimplification exposed something. */
3562 if (ret
!= GS_ERROR
)
3564 tree new_tree
= fold_call_expr (input_location
, *expr_p
, !want_value
);
3566 if (new_tree
&& new_tree
!= *expr_p
)
3568 /* There was a transformation of this call which computes the
3569 same value, but in a more efficient way. Return and try
3577 *expr_p
= error_mark_node
;
3581 /* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its
3582 decl. This allows us to eliminate redundant or useless
3583 calls to "const" functions. */
3584 if (TREE_CODE (*expr_p
) == CALL_EXPR
)
3586 int flags
= call_expr_flags (*expr_p
);
3587 if (flags
& (ECF_CONST
| ECF_PURE
)
3588 /* An infinite loop is considered a side effect. */
3589 && !(flags
& (ECF_LOOPING_CONST_OR_PURE
)))
3590 TREE_SIDE_EFFECTS (*expr_p
) = 0;
3593 /* If the value is not needed by the caller, emit a new GIMPLE_CALL
3594 and clear *EXPR_P. Otherwise, leave *EXPR_P in its gimplified
3595 form and delegate the creation of a GIMPLE_CALL to
3596 gimplify_modify_expr. This is always possible because when
3597 WANT_VALUE is true, the caller wants the result of this call into
3598 a temporary, which means that we will emit an INIT_EXPR in
3599 internal_get_tmp_var which will then be handled by
3600 gimplify_modify_expr. */
3603 /* The CALL_EXPR in *EXPR_P is already in GIMPLE form, so all we
3604 have to do is replicate it as a GIMPLE_CALL tuple. */
3605 gimple_stmt_iterator gsi
;
3606 call
= gimple_build_call_from_tree (*expr_p
, fnptrtype
);
3607 notice_special_calls (call
);
3608 gimplify_seq_add_stmt (pre_p
, call
);
3609 gsi
= gsi_last (*pre_p
);
3610 maybe_fold_stmt (&gsi
);
3611 *expr_p
= NULL_TREE
;
3614 /* Remember the original function type. */
3615 CALL_EXPR_FN (*expr_p
) = build1 (NOP_EXPR
, fnptrtype
,
3616 CALL_EXPR_FN (*expr_p
));
3621 /* Handle shortcut semantics in the predicate operand of a COND_EXPR by
3622 rewriting it into multiple COND_EXPRs, and possibly GOTO_EXPRs.
3624 TRUE_LABEL_P and FALSE_LABEL_P point to the labels to jump to if the
3625 condition is true or false, respectively. If null, we should generate
3626 our own to skip over the evaluation of this specific expression.
3628 LOCUS is the source location of the COND_EXPR.
3630 This function is the tree equivalent of do_jump.
3632 shortcut_cond_r should only be called by shortcut_cond_expr. */
3635 shortcut_cond_r (tree pred
, tree
*true_label_p
, tree
*false_label_p
,
3638 tree local_label
= NULL_TREE
;
3639 tree t
, expr
= NULL
;
3641 /* OK, it's not a simple case; we need to pull apart the COND_EXPR to
3642 retain the shortcut semantics. Just insert the gotos here;
3643 shortcut_cond_expr will append the real blocks later. */
3644 if (TREE_CODE (pred
) == TRUTH_ANDIF_EXPR
)
3646 location_t new_locus
;
3648 /* Turn if (a && b) into
3650 if (a); else goto no;
3651 if (b) goto yes; else goto no;
3654 if (false_label_p
== NULL
)
3655 false_label_p
= &local_label
;
3657 /* Keep the original source location on the first 'if'. */
3658 t
= shortcut_cond_r (TREE_OPERAND (pred
, 0), NULL
, false_label_p
, locus
);
3659 append_to_statement_list (t
, &expr
);
3661 /* Set the source location of the && on the second 'if'. */
3662 new_locus
= rexpr_location (pred
, locus
);
3663 t
= shortcut_cond_r (TREE_OPERAND (pred
, 1), true_label_p
, false_label_p
,
3665 append_to_statement_list (t
, &expr
);
3667 else if (TREE_CODE (pred
) == TRUTH_ORIF_EXPR
)
3669 location_t new_locus
;
3671 /* Turn if (a || b) into
3674 if (b) goto yes; else goto no;
3677 if (true_label_p
== NULL
)
3678 true_label_p
= &local_label
;
3680 /* Keep the original source location on the first 'if'. */
3681 t
= shortcut_cond_r (TREE_OPERAND (pred
, 0), true_label_p
, NULL
, locus
);
3682 append_to_statement_list (t
, &expr
);
3684 /* Set the source location of the || on the second 'if'. */
3685 new_locus
= rexpr_location (pred
, locus
);
3686 t
= shortcut_cond_r (TREE_OPERAND (pred
, 1), true_label_p
, false_label_p
,
3688 append_to_statement_list (t
, &expr
);
3690 else if (TREE_CODE (pred
) == COND_EXPR
3691 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred
, 1)))
3692 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred
, 2))))
3694 location_t new_locus
;
3696 /* As long as we're messing with gotos, turn if (a ? b : c) into
3698 if (b) goto yes; else goto no;
3700 if (c) goto yes; else goto no;
3702 Don't do this if one of the arms has void type, which can happen
3703 in C++ when the arm is throw. */
3705 /* Keep the original source location on the first 'if'. Set the source
3706 location of the ? on the second 'if'. */
3707 new_locus
= rexpr_location (pred
, locus
);
3708 expr
= build3 (COND_EXPR
, void_type_node
, TREE_OPERAND (pred
, 0),
3709 shortcut_cond_r (TREE_OPERAND (pred
, 1), true_label_p
,
3710 false_label_p
, locus
),
3711 shortcut_cond_r (TREE_OPERAND (pred
, 2), true_label_p
,
3712 false_label_p
, new_locus
));
3716 expr
= build3 (COND_EXPR
, void_type_node
, pred
,
3717 build_and_jump (true_label_p
),
3718 build_and_jump (false_label_p
));
3719 SET_EXPR_LOCATION (expr
, locus
);
3724 t
= build1 (LABEL_EXPR
, void_type_node
, local_label
);
3725 append_to_statement_list (t
, &expr
);
3731 /* If EXPR is a GOTO_EXPR, return it. If it is a STATEMENT_LIST, skip
3732 any of its leading DEBUG_BEGIN_STMTS and recurse on the subsequent
3733 statement, if it is the last one. Otherwise, return NULL. */
3736 find_goto (tree expr
)
3741 if (TREE_CODE (expr
) == GOTO_EXPR
)
3744 if (TREE_CODE (expr
) != STATEMENT_LIST
)
3747 tree_stmt_iterator i
= tsi_start (expr
);
3749 while (!tsi_end_p (i
) && TREE_CODE (tsi_stmt (i
)) == DEBUG_BEGIN_STMT
)
3752 if (!tsi_one_before_end_p (i
))
3755 return find_goto (tsi_stmt (i
));
3758 /* Same as find_goto, except that it returns NULL if the destination
3759 is not a LABEL_DECL. */
3762 find_goto_label (tree expr
)
3764 tree dest
= find_goto (expr
);
3765 if (dest
&& TREE_CODE (GOTO_DESTINATION (dest
)) == LABEL_DECL
)
3770 /* Given a conditional expression EXPR with short-circuit boolean
3771 predicates using TRUTH_ANDIF_EXPR or TRUTH_ORIF_EXPR, break the
3772 predicate apart into the equivalent sequence of conditionals. */
3775 shortcut_cond_expr (tree expr
)
3777 tree pred
= TREE_OPERAND (expr
, 0);
3778 tree then_
= TREE_OPERAND (expr
, 1);
3779 tree else_
= TREE_OPERAND (expr
, 2);
3780 tree true_label
, false_label
, end_label
, t
;
3782 tree
*false_label_p
;
3783 bool emit_end
, emit_false
, jump_over_else
;
3784 bool then_se
= then_
&& TREE_SIDE_EFFECTS (then_
);
3785 bool else_se
= else_
&& TREE_SIDE_EFFECTS (else_
);
3787 /* First do simple transformations. */
3790 /* If there is no 'else', turn
3793 if (a) if (b) then c. */
3794 while (TREE_CODE (pred
) == TRUTH_ANDIF_EXPR
)
3796 /* Keep the original source location on the first 'if'. */
3797 location_t locus
= EXPR_LOC_OR_LOC (expr
, input_location
);
3798 TREE_OPERAND (expr
, 0) = TREE_OPERAND (pred
, 1);
3799 /* Set the source location of the && on the second 'if'. */
3800 if (rexpr_has_location (pred
))
3801 SET_EXPR_LOCATION (expr
, rexpr_location (pred
));
3802 then_
= shortcut_cond_expr (expr
);
3803 then_se
= then_
&& TREE_SIDE_EFFECTS (then_
);
3804 pred
= TREE_OPERAND (pred
, 0);
3805 expr
= build3 (COND_EXPR
, void_type_node
, pred
, then_
, NULL_TREE
);
3806 SET_EXPR_LOCATION (expr
, locus
);
3812 /* If there is no 'then', turn
3815 if (a); else if (b); else d. */
3816 while (TREE_CODE (pred
) == TRUTH_ORIF_EXPR
)
3818 /* Keep the original source location on the first 'if'. */
3819 location_t locus
= EXPR_LOC_OR_LOC (expr
, input_location
);
3820 TREE_OPERAND (expr
, 0) = TREE_OPERAND (pred
, 1);
3821 /* Set the source location of the || on the second 'if'. */
3822 if (rexpr_has_location (pred
))
3823 SET_EXPR_LOCATION (expr
, rexpr_location (pred
));
3824 else_
= shortcut_cond_expr (expr
);
3825 else_se
= else_
&& TREE_SIDE_EFFECTS (else_
);
3826 pred
= TREE_OPERAND (pred
, 0);
3827 expr
= build3 (COND_EXPR
, void_type_node
, pred
, NULL_TREE
, else_
);
3828 SET_EXPR_LOCATION (expr
, locus
);
3832 /* If we're done, great. */
3833 if (TREE_CODE (pred
) != TRUTH_ANDIF_EXPR
3834 && TREE_CODE (pred
) != TRUTH_ORIF_EXPR
)
3837 /* Otherwise we need to mess with gotos. Change
3840 if (a); else goto no;
3843 and recursively gimplify the condition. */
3845 true_label
= false_label
= end_label
= NULL_TREE
;
3847 /* If our arms just jump somewhere, hijack those labels so we don't
3848 generate jumps to jumps. */
3850 if (tree then_goto
= find_goto_label (then_
))
3852 true_label
= GOTO_DESTINATION (then_goto
);
3857 if (tree else_goto
= find_goto_label (else_
))
3859 false_label
= GOTO_DESTINATION (else_goto
);
3864 /* If we aren't hijacking a label for the 'then' branch, it falls through. */
3866 true_label_p
= &true_label
;
3868 true_label_p
= NULL
;
3870 /* The 'else' branch also needs a label if it contains interesting code. */
3871 if (false_label
|| else_se
)
3872 false_label_p
= &false_label
;
3874 false_label_p
= NULL
;
3876 /* If there was nothing else in our arms, just forward the label(s). */
3877 if (!then_se
&& !else_se
)
3878 return shortcut_cond_r (pred
, true_label_p
, false_label_p
,
3879 EXPR_LOC_OR_LOC (expr
, input_location
));
3881 /* If our last subexpression already has a terminal label, reuse it. */
3883 t
= expr_last (else_
);
3885 t
= expr_last (then_
);
3888 if (t
&& TREE_CODE (t
) == LABEL_EXPR
)
3889 end_label
= LABEL_EXPR_LABEL (t
);
3891 /* If we don't care about jumping to the 'else' branch, jump to the end
3892 if the condition is false. */
3894 false_label_p
= &end_label
;
3896 /* We only want to emit these labels if we aren't hijacking them. */
3897 emit_end
= (end_label
== NULL_TREE
);
3898 emit_false
= (false_label
== NULL_TREE
);
3900 /* We only emit the jump over the else clause if we have to--if the
3901 then clause may fall through. Otherwise we can wind up with a
3902 useless jump and a useless label at the end of gimplified code,
3903 which will cause us to think that this conditional as a whole
3904 falls through even if it doesn't. If we then inline a function
3905 which ends with such a condition, that can cause us to issue an
3906 inappropriate warning about control reaching the end of a
3907 non-void function. */
3908 jump_over_else
= block_may_fallthru (then_
);
3910 pred
= shortcut_cond_r (pred
, true_label_p
, false_label_p
,
3911 EXPR_LOC_OR_LOC (expr
, input_location
));
3914 append_to_statement_list (pred
, &expr
);
3916 append_to_statement_list (then_
, &expr
);
3921 tree last
= expr_last (expr
);
3922 t
= build_and_jump (&end_label
);
3923 if (rexpr_has_location (last
))
3924 SET_EXPR_LOCATION (t
, rexpr_location (last
));
3925 append_to_statement_list (t
, &expr
);
3929 t
= build1 (LABEL_EXPR
, void_type_node
, false_label
);
3930 append_to_statement_list (t
, &expr
);
3932 append_to_statement_list (else_
, &expr
);
3934 if (emit_end
&& end_label
)
3936 t
= build1 (LABEL_EXPR
, void_type_node
, end_label
);
3937 append_to_statement_list (t
, &expr
);
3943 /* EXPR is used in a boolean context; make sure it has BOOLEAN_TYPE. */
3946 gimple_boolify (tree expr
)
3948 tree type
= TREE_TYPE (expr
);
3949 location_t loc
= EXPR_LOCATION (expr
);
3951 if (TREE_CODE (expr
) == NE_EXPR
3952 && TREE_CODE (TREE_OPERAND (expr
, 0)) == CALL_EXPR
3953 && integer_zerop (TREE_OPERAND (expr
, 1)))
3955 tree call
= TREE_OPERAND (expr
, 0);
3956 tree fn
= get_callee_fndecl (call
);
3958 /* For __builtin_expect ((long) (x), y) recurse into x as well
3959 if x is truth_value_p. */
3961 && fndecl_built_in_p (fn
, BUILT_IN_EXPECT
)
3962 && call_expr_nargs (call
) == 2)
3964 tree arg
= CALL_EXPR_ARG (call
, 0);
3967 if (TREE_CODE (arg
) == NOP_EXPR
3968 && TREE_TYPE (arg
) == TREE_TYPE (call
))
3969 arg
= TREE_OPERAND (arg
, 0);
3970 if (truth_value_p (TREE_CODE (arg
)))
3972 arg
= gimple_boolify (arg
);
3973 CALL_EXPR_ARG (call
, 0)
3974 = fold_convert_loc (loc
, TREE_TYPE (call
), arg
);
3980 switch (TREE_CODE (expr
))
3982 case TRUTH_AND_EXPR
:
3984 case TRUTH_XOR_EXPR
:
3985 case TRUTH_ANDIF_EXPR
:
3986 case TRUTH_ORIF_EXPR
:
3987 /* Also boolify the arguments of truth exprs. */
3988 TREE_OPERAND (expr
, 1) = gimple_boolify (TREE_OPERAND (expr
, 1));
3991 case TRUTH_NOT_EXPR
:
3992 TREE_OPERAND (expr
, 0) = gimple_boolify (TREE_OPERAND (expr
, 0));
3994 /* These expressions always produce boolean results. */
3995 if (TREE_CODE (type
) != BOOLEAN_TYPE
)
3996 TREE_TYPE (expr
) = boolean_type_node
;
4000 switch ((enum annot_expr_kind
) TREE_INT_CST_LOW (TREE_OPERAND (expr
, 1)))
4002 case annot_expr_ivdep_kind
:
4003 case annot_expr_unroll_kind
:
4004 case annot_expr_no_vector_kind
:
4005 case annot_expr_vector_kind
:
4006 case annot_expr_parallel_kind
:
4007 TREE_OPERAND (expr
, 0) = gimple_boolify (TREE_OPERAND (expr
, 0));
4008 if (TREE_CODE (type
) != BOOLEAN_TYPE
)
4009 TREE_TYPE (expr
) = boolean_type_node
;
4016 if (COMPARISON_CLASS_P (expr
))
4018 /* There expressions always prduce boolean results. */
4019 if (TREE_CODE (type
) != BOOLEAN_TYPE
)
4020 TREE_TYPE (expr
) = boolean_type_node
;
4023 /* Other expressions that get here must have boolean values, but
4024 might need to be converted to the appropriate mode. */
4025 if (TREE_CODE (type
) == BOOLEAN_TYPE
)
4027 return fold_convert_loc (loc
, boolean_type_node
, expr
);
4031 /* Given a conditional expression *EXPR_P without side effects, gimplify
4032 its operands. New statements are inserted to PRE_P. */
4034 static enum gimplify_status
4035 gimplify_pure_cond_expr (tree
*expr_p
, gimple_seq
*pre_p
)
4037 tree expr
= *expr_p
, cond
;
4038 enum gimplify_status ret
, tret
;
4039 enum tree_code code
;
4041 cond
= gimple_boolify (COND_EXPR_COND (expr
));
4043 /* We need to handle && and || specially, as their gimplification
4044 creates pure cond_expr, thus leading to an infinite cycle otherwise. */
4045 code
= TREE_CODE (cond
);
4046 if (code
== TRUTH_ANDIF_EXPR
)
4047 TREE_SET_CODE (cond
, TRUTH_AND_EXPR
);
4048 else if (code
== TRUTH_ORIF_EXPR
)
4049 TREE_SET_CODE (cond
, TRUTH_OR_EXPR
);
4050 ret
= gimplify_expr (&cond
, pre_p
, NULL
, is_gimple_condexpr
, fb_rvalue
);
4051 COND_EXPR_COND (*expr_p
) = cond
;
4053 tret
= gimplify_expr (&COND_EXPR_THEN (expr
), pre_p
, NULL
,
4054 is_gimple_val
, fb_rvalue
);
4055 ret
= MIN (ret
, tret
);
4056 tret
= gimplify_expr (&COND_EXPR_ELSE (expr
), pre_p
, NULL
,
4057 is_gimple_val
, fb_rvalue
);
4059 return MIN (ret
, tret
);
4062 /* Return true if evaluating EXPR could trap.
4063 EXPR is GENERIC, while tree_could_trap_p can be called
4067 generic_expr_could_trap_p (tree expr
)
4071 if (!expr
|| is_gimple_val (expr
))
4074 if (!EXPR_P (expr
) || tree_could_trap_p (expr
))
4077 n
= TREE_OPERAND_LENGTH (expr
);
4078 for (i
= 0; i
< n
; i
++)
4079 if (generic_expr_could_trap_p (TREE_OPERAND (expr
, i
)))
4085 /* Convert the conditional expression pointed to by EXPR_P '(p) ? a : b;'
4094 The second form is used when *EXPR_P is of type void.
4096 PRE_P points to the list where side effects that must happen before
4097 *EXPR_P should be stored. */
4099 static enum gimplify_status
4100 gimplify_cond_expr (tree
*expr_p
, gimple_seq
*pre_p
, fallback_t fallback
)
4102 tree expr
= *expr_p
;
4103 tree type
= TREE_TYPE (expr
);
4104 location_t loc
= EXPR_LOCATION (expr
);
4105 tree tmp
, arm1
, arm2
;
4106 enum gimplify_status ret
;
4107 tree label_true
, label_false
, label_cont
;
4108 bool have_then_clause_p
, have_else_clause_p
;
4110 enum tree_code pred_code
;
4111 gimple_seq seq
= NULL
;
4113 /* If this COND_EXPR has a value, copy the values into a temporary within
4115 if (!VOID_TYPE_P (type
))
4117 tree then_
= TREE_OPERAND (expr
, 1), else_
= TREE_OPERAND (expr
, 2);
4120 /* If either an rvalue is ok or we do not require an lvalue, create the
4121 temporary. But we cannot do that if the type is addressable. */
4122 if (((fallback
& fb_rvalue
) || !(fallback
& fb_lvalue
))
4123 && !TREE_ADDRESSABLE (type
))
4125 if (gimplify_ctxp
->allow_rhs_cond_expr
4126 /* If either branch has side effects or could trap, it can't be
4127 evaluated unconditionally. */
4128 && !TREE_SIDE_EFFECTS (then_
)
4129 && !generic_expr_could_trap_p (then_
)
4130 && !TREE_SIDE_EFFECTS (else_
)
4131 && !generic_expr_could_trap_p (else_
))
4132 return gimplify_pure_cond_expr (expr_p
, pre_p
);
4134 tmp
= create_tmp_var (type
, "iftmp");
4138 /* Otherwise, only create and copy references to the values. */
4141 type
= build_pointer_type (type
);
4143 if (!VOID_TYPE_P (TREE_TYPE (then_
)))
4144 then_
= build_fold_addr_expr_loc (loc
, then_
);
4146 if (!VOID_TYPE_P (TREE_TYPE (else_
)))
4147 else_
= build_fold_addr_expr_loc (loc
, else_
);
4150 = build3 (COND_EXPR
, type
, TREE_OPERAND (expr
, 0), then_
, else_
);
4152 tmp
= create_tmp_var (type
, "iftmp");
4153 result
= build_simple_mem_ref_loc (loc
, tmp
);
4156 /* Build the new then clause, `tmp = then_;'. But don't build the
4157 assignment if the value is void; in C++ it can be if it's a throw. */
4158 if (!VOID_TYPE_P (TREE_TYPE (then_
)))
4159 TREE_OPERAND (expr
, 1) = build2 (INIT_EXPR
, type
, tmp
, then_
);
4161 /* Similarly, build the new else clause, `tmp = else_;'. */
4162 if (!VOID_TYPE_P (TREE_TYPE (else_
)))
4163 TREE_OPERAND (expr
, 2) = build2 (INIT_EXPR
, type
, tmp
, else_
);
4165 TREE_TYPE (expr
) = void_type_node
;
4166 recalculate_side_effects (expr
);
4168 /* Move the COND_EXPR to the prequeue. */
4169 gimplify_stmt (&expr
, pre_p
);
4175 /* Remove any COMPOUND_EXPR so the following cases will be caught. */
4176 STRIP_TYPE_NOPS (TREE_OPERAND (expr
, 0));
4177 if (TREE_CODE (TREE_OPERAND (expr
, 0)) == COMPOUND_EXPR
)
4178 gimplify_compound_expr (&TREE_OPERAND (expr
, 0), pre_p
, true);
4180 /* Make sure the condition has BOOLEAN_TYPE. */
4181 TREE_OPERAND (expr
, 0) = gimple_boolify (TREE_OPERAND (expr
, 0));
4183 /* Break apart && and || conditions. */
4184 if (TREE_CODE (TREE_OPERAND (expr
, 0)) == TRUTH_ANDIF_EXPR
4185 || TREE_CODE (TREE_OPERAND (expr
, 0)) == TRUTH_ORIF_EXPR
)
4187 expr
= shortcut_cond_expr (expr
);
4189 if (expr
!= *expr_p
)
4193 /* We can't rely on gimplify_expr to re-gimplify the expanded
4194 form properly, as cleanups might cause the target labels to be
4195 wrapped in a TRY_FINALLY_EXPR. To prevent that, we need to
4196 set up a conditional context. */
4197 gimple_push_condition ();
4198 gimplify_stmt (expr_p
, &seq
);
4199 gimple_pop_condition (pre_p
);
4200 gimple_seq_add_seq (pre_p
, seq
);
4206 /* Now do the normal gimplification. */
4208 /* Gimplify condition. */
4209 ret
= gimplify_expr (&TREE_OPERAND (expr
, 0), pre_p
, NULL
,
4210 is_gimple_condexpr_for_cond
, fb_rvalue
);
4211 if (ret
== GS_ERROR
)
4213 gcc_assert (TREE_OPERAND (expr
, 0) != NULL_TREE
);
4215 gimple_push_condition ();
4217 have_then_clause_p
= have_else_clause_p
= false;
4218 label_true
= find_goto_label (TREE_OPERAND (expr
, 1));
4220 && DECL_CONTEXT (GOTO_DESTINATION (label_true
)) == current_function_decl
4221 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4222 have different locations, otherwise we end up with incorrect
4223 location information on the branches. */
4225 || !EXPR_HAS_LOCATION (expr
)
4226 || !rexpr_has_location (label_true
)
4227 || EXPR_LOCATION (expr
) == rexpr_location (label_true
)))
4229 have_then_clause_p
= true;
4230 label_true
= GOTO_DESTINATION (label_true
);
4233 label_true
= create_artificial_label (UNKNOWN_LOCATION
);
4234 label_false
= find_goto_label (TREE_OPERAND (expr
, 2));
4236 && DECL_CONTEXT (GOTO_DESTINATION (label_false
)) == current_function_decl
4237 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4238 have different locations, otherwise we end up with incorrect
4239 location information on the branches. */
4241 || !EXPR_HAS_LOCATION (expr
)
4242 || !rexpr_has_location (label_false
)
4243 || EXPR_LOCATION (expr
) == rexpr_location (label_false
)))
4245 have_else_clause_p
= true;
4246 label_false
= GOTO_DESTINATION (label_false
);
4249 label_false
= create_artificial_label (UNKNOWN_LOCATION
);
4251 gimple_cond_get_ops_from_tree (COND_EXPR_COND (expr
), &pred_code
, &arm1
,
4253 cond_stmt
= gimple_build_cond (pred_code
, arm1
, arm2
, label_true
,
4255 gimple_set_location (cond_stmt
, EXPR_LOCATION (expr
));
4256 copy_warning (cond_stmt
, COND_EXPR_COND (expr
));
4257 gimplify_seq_add_stmt (&seq
, cond_stmt
);
4258 gimple_stmt_iterator gsi
= gsi_last (seq
);
4259 maybe_fold_stmt (&gsi
);
4261 label_cont
= NULL_TREE
;
4262 if (!have_then_clause_p
)
4264 /* For if (...) {} else { code; } put label_true after
4266 if (TREE_OPERAND (expr
, 1) == NULL_TREE
4267 && !have_else_clause_p
4268 && TREE_OPERAND (expr
, 2) != NULL_TREE
)
4269 label_cont
= label_true
;
4272 gimplify_seq_add_stmt (&seq
, gimple_build_label (label_true
));
4273 have_then_clause_p
= gimplify_stmt (&TREE_OPERAND (expr
, 1), &seq
);
4274 /* For if (...) { code; } else {} or
4275 if (...) { code; } else goto label; or
4276 if (...) { code; return; } else { ... }
4277 label_cont isn't needed. */
4278 if (!have_else_clause_p
4279 && TREE_OPERAND (expr
, 2) != NULL_TREE
4280 && gimple_seq_may_fallthru (seq
))
4283 label_cont
= create_artificial_label (UNKNOWN_LOCATION
);
4285 g
= gimple_build_goto (label_cont
);
4287 /* GIMPLE_COND's are very low level; they have embedded
4288 gotos. This particular embedded goto should not be marked
4289 with the location of the original COND_EXPR, as it would
4290 correspond to the COND_EXPR's condition, not the ELSE or the
4291 THEN arms. To avoid marking it with the wrong location, flag
4292 it as "no location". */
4293 gimple_set_do_not_emit_location (g
);
4295 gimplify_seq_add_stmt (&seq
, g
);
4299 if (!have_else_clause_p
)
4301 gimplify_seq_add_stmt (&seq
, gimple_build_label (label_false
));
4302 have_else_clause_p
= gimplify_stmt (&TREE_OPERAND (expr
, 2), &seq
);
4305 gimplify_seq_add_stmt (&seq
, gimple_build_label (label_cont
));
4307 gimple_pop_condition (pre_p
);
4308 gimple_seq_add_seq (pre_p
, seq
);
4310 if (ret
== GS_ERROR
)
4312 else if (have_then_clause_p
|| have_else_clause_p
)
4316 /* Both arms are empty; replace the COND_EXPR with its predicate. */
4317 expr
= TREE_OPERAND (expr
, 0);
4318 gimplify_stmt (&expr
, pre_p
);
4325 /* Prepare the node pointed to by EXPR_P, an is_gimple_addressable expression,
4326 to be marked addressable.
4328 We cannot rely on such an expression being directly markable if a temporary
4329 has been created by the gimplification. In this case, we create another
4330 temporary and initialize it with a copy, which will become a store after we
4331 mark it addressable. This can happen if the front-end passed us something
4332 that it could not mark addressable yet, like a Fortran pass-by-reference
4333 parameter (int) floatvar. */
4336 prepare_gimple_addressable (tree
*expr_p
, gimple_seq
*seq_p
)
4338 while (handled_component_p (*expr_p
))
4339 expr_p
= &TREE_OPERAND (*expr_p
, 0);
4340 if (is_gimple_reg (*expr_p
))
4342 /* Do not allow an SSA name as the temporary. */
4343 tree var
= get_initialized_tmp_var (*expr_p
, seq_p
, NULL
, false);
4344 DECL_NOT_GIMPLE_REG_P (var
) = 1;
4349 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4350 a call to __builtin_memcpy. */
4352 static enum gimplify_status
4353 gimplify_modify_expr_to_memcpy (tree
*expr_p
, tree size
, bool want_value
,
4356 tree t
, to
, to_ptr
, from
, from_ptr
;
4358 location_t loc
= EXPR_LOCATION (*expr_p
);
4360 to
= TREE_OPERAND (*expr_p
, 0);
4361 from
= TREE_OPERAND (*expr_p
, 1);
4363 /* Mark the RHS addressable. Beware that it may not be possible to do so
4364 directly if a temporary has been created by the gimplification. */
4365 prepare_gimple_addressable (&from
, seq_p
);
4367 mark_addressable (from
);
4368 from_ptr
= build_fold_addr_expr_loc (loc
, from
);
4369 gimplify_arg (&from_ptr
, seq_p
, loc
);
4371 mark_addressable (to
);
4372 to_ptr
= build_fold_addr_expr_loc (loc
, to
);
4373 gimplify_arg (&to_ptr
, seq_p
, loc
);
4375 t
= builtin_decl_implicit (BUILT_IN_MEMCPY
);
4377 gs
= gimple_build_call (t
, 3, to_ptr
, from_ptr
, size
);
4378 gimple_call_set_alloca_for_var (gs
, true);
4382 /* tmp = memcpy() */
4383 t
= create_tmp_var (TREE_TYPE (to_ptr
));
4384 gimple_call_set_lhs (gs
, t
);
4385 gimplify_seq_add_stmt (seq_p
, gs
);
4387 *expr_p
= build_simple_mem_ref (t
);
4391 gimplify_seq_add_stmt (seq_p
, gs
);
4396 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4397 a call to __builtin_memset. In this case we know that the RHS is
4398 a CONSTRUCTOR with an empty element list. */
4400 static enum gimplify_status
4401 gimplify_modify_expr_to_memset (tree
*expr_p
, tree size
, bool want_value
,
4404 tree t
, from
, to
, to_ptr
;
4406 location_t loc
= EXPR_LOCATION (*expr_p
);
4408 /* Assert our assumptions, to abort instead of producing wrong code
4409 silently if they are not met. Beware that the RHS CONSTRUCTOR might
4410 not be immediately exposed. */
4411 from
= TREE_OPERAND (*expr_p
, 1);
4412 if (TREE_CODE (from
) == WITH_SIZE_EXPR
)
4413 from
= TREE_OPERAND (from
, 0);
4415 gcc_assert (TREE_CODE (from
) == CONSTRUCTOR
4416 && vec_safe_is_empty (CONSTRUCTOR_ELTS (from
)));
4419 to
= TREE_OPERAND (*expr_p
, 0);
4421 to_ptr
= build_fold_addr_expr_loc (loc
, to
);
4422 gimplify_arg (&to_ptr
, seq_p
, loc
);
4423 t
= builtin_decl_implicit (BUILT_IN_MEMSET
);
4425 gs
= gimple_build_call (t
, 3, to_ptr
, integer_zero_node
, size
);
4429 /* tmp = memset() */
4430 t
= create_tmp_var (TREE_TYPE (to_ptr
));
4431 gimple_call_set_lhs (gs
, t
);
4432 gimplify_seq_add_stmt (seq_p
, gs
);
4434 *expr_p
= build1 (INDIRECT_REF
, TREE_TYPE (to
), t
);
4438 gimplify_seq_add_stmt (seq_p
, gs
);
4443 /* A subroutine of gimplify_init_ctor_preeval. Called via walk_tree,
4444 determine, cautiously, if a CONSTRUCTOR overlaps the lhs of an
4445 assignment. Return non-null if we detect a potential overlap. */
4447 struct gimplify_init_ctor_preeval_data
4449 /* The base decl of the lhs object. May be NULL, in which case we
4450 have to assume the lhs is indirect. */
4453 /* The alias set of the lhs object. */
4454 alias_set_type lhs_alias_set
;
4458 gimplify_init_ctor_preeval_1 (tree
*tp
, int *walk_subtrees
, void *xdata
)
4460 struct gimplify_init_ctor_preeval_data
*data
4461 = (struct gimplify_init_ctor_preeval_data
*) xdata
;
4464 /* If we find the base object, obviously we have overlap. */
4465 if (data
->lhs_base_decl
== t
)
4468 /* If the constructor component is indirect, determine if we have a
4469 potential overlap with the lhs. The only bits of information we
4470 have to go on at this point are addressability and alias sets. */
4471 if ((INDIRECT_REF_P (t
)
4472 || TREE_CODE (t
) == MEM_REF
)
4473 && (!data
->lhs_base_decl
|| TREE_ADDRESSABLE (data
->lhs_base_decl
))
4474 && alias_sets_conflict_p (data
->lhs_alias_set
, get_alias_set (t
)))
4477 /* If the constructor component is a call, determine if it can hide a
4478 potential overlap with the lhs through an INDIRECT_REF like above.
4479 ??? Ugh - this is completely broken. In fact this whole analysis
4480 doesn't look conservative. */
4481 if (TREE_CODE (t
) == CALL_EXPR
)
4483 tree type
, fntype
= TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (t
)));
4485 for (type
= TYPE_ARG_TYPES (fntype
); type
; type
= TREE_CHAIN (type
))
4486 if (POINTER_TYPE_P (TREE_VALUE (type
))
4487 && (!data
->lhs_base_decl
|| TREE_ADDRESSABLE (data
->lhs_base_decl
))
4488 && alias_sets_conflict_p (data
->lhs_alias_set
,
4490 (TREE_TYPE (TREE_VALUE (type
)))))
4494 if (IS_TYPE_OR_DECL_P (t
))
4499 /* A subroutine of gimplify_init_constructor. Pre-evaluate EXPR,
4500 force values that overlap with the lhs (as described by *DATA)
4501 into temporaries. */
4504 gimplify_init_ctor_preeval (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
4505 struct gimplify_init_ctor_preeval_data
*data
)
4507 enum gimplify_status one
;
4509 /* If the value is constant, then there's nothing to pre-evaluate. */
4510 if (TREE_CONSTANT (*expr_p
))
4512 /* Ensure it does not have side effects, it might contain a reference to
4513 the object we're initializing. */
4514 gcc_assert (!TREE_SIDE_EFFECTS (*expr_p
));
4518 /* If the type has non-trivial constructors, we can't pre-evaluate. */
4519 if (TREE_ADDRESSABLE (TREE_TYPE (*expr_p
)))
4522 /* Recurse for nested constructors. */
4523 if (TREE_CODE (*expr_p
) == CONSTRUCTOR
)
4525 unsigned HOST_WIDE_INT ix
;
4526 constructor_elt
*ce
;
4527 vec
<constructor_elt
, va_gc
> *v
= CONSTRUCTOR_ELTS (*expr_p
);
4529 FOR_EACH_VEC_SAFE_ELT (v
, ix
, ce
)
4530 gimplify_init_ctor_preeval (&ce
->value
, pre_p
, post_p
, data
);
4535 /* If this is a variable sized type, we must remember the size. */
4536 maybe_with_size_expr (expr_p
);
4538 /* Gimplify the constructor element to something appropriate for the rhs
4539 of a MODIFY_EXPR. Given that we know the LHS is an aggregate, we know
4540 the gimplifier will consider this a store to memory. Doing this
4541 gimplification now means that we won't have to deal with complicated
4542 language-specific trees, nor trees like SAVE_EXPR that can induce
4543 exponential search behavior. */
4544 one
= gimplify_expr (expr_p
, pre_p
, post_p
, is_gimple_mem_rhs
, fb_rvalue
);
4545 if (one
== GS_ERROR
)
4551 /* If we gimplified to a bare decl, we can be sure that it doesn't overlap
4552 with the lhs, since "a = { .x=a }" doesn't make sense. This will
4553 always be true for all scalars, since is_gimple_mem_rhs insists on a
4554 temporary variable for them. */
4555 if (DECL_P (*expr_p
))
4558 /* If this is of variable size, we have no choice but to assume it doesn't
4559 overlap since we can't make a temporary for it. */
4560 if (TREE_CODE (TYPE_SIZE (TREE_TYPE (*expr_p
))) != INTEGER_CST
)
4563 /* Otherwise, we must search for overlap ... */
4564 if (!walk_tree (expr_p
, gimplify_init_ctor_preeval_1
, data
, NULL
))
4567 /* ... and if found, force the value into a temporary. */
4568 *expr_p
= get_formal_tmp_var (*expr_p
, pre_p
);
4571 /* A subroutine of gimplify_init_ctor_eval. Create a loop for
4572 a RANGE_EXPR in a CONSTRUCTOR for an array.
4576 object[var] = value;
4583 We increment var _after_ the loop exit check because we might otherwise
4584 fail if upper == TYPE_MAX_VALUE (type for upper).
4586 Note that we never have to deal with SAVE_EXPRs here, because this has
4587 already been taken care of for us, in gimplify_init_ctor_preeval(). */
4589 static void gimplify_init_ctor_eval (tree
, vec
<constructor_elt
, va_gc
> *,
4590 gimple_seq
*, bool);
4593 gimplify_init_ctor_eval_range (tree object
, tree lower
, tree upper
,
4594 tree value
, tree array_elt_type
,
4595 gimple_seq
*pre_p
, bool cleared
)
4597 tree loop_entry_label
, loop_exit_label
, fall_thru_label
;
4598 tree var
, var_type
, cref
, tmp
;
4600 loop_entry_label
= create_artificial_label (UNKNOWN_LOCATION
);
4601 loop_exit_label
= create_artificial_label (UNKNOWN_LOCATION
);
4602 fall_thru_label
= create_artificial_label (UNKNOWN_LOCATION
);
4604 /* Create and initialize the index variable. */
4605 var_type
= TREE_TYPE (upper
);
4606 var
= create_tmp_var (var_type
);
4607 gimplify_seq_add_stmt (pre_p
, gimple_build_assign (var
, lower
));
4609 /* Add the loop entry label. */
4610 gimplify_seq_add_stmt (pre_p
, gimple_build_label (loop_entry_label
));
4612 /* Build the reference. */
4613 cref
= build4 (ARRAY_REF
, array_elt_type
, unshare_expr (object
),
4614 var
, NULL_TREE
, NULL_TREE
);
4616 /* If we are a constructor, just call gimplify_init_ctor_eval to do
4617 the store. Otherwise just assign value to the reference. */
4619 if (TREE_CODE (value
) == CONSTRUCTOR
)
4620 /* NB we might have to call ourself recursively through
4621 gimplify_init_ctor_eval if the value is a constructor. */
4622 gimplify_init_ctor_eval (cref
, CONSTRUCTOR_ELTS (value
),
4626 if (gimplify_expr (&value
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
)
4628 gimplify_seq_add_stmt (pre_p
, gimple_build_assign (cref
, value
));
4631 /* We exit the loop when the index var is equal to the upper bound. */
4632 gimplify_seq_add_stmt (pre_p
,
4633 gimple_build_cond (EQ_EXPR
, var
, upper
,
4634 loop_exit_label
, fall_thru_label
));
4636 gimplify_seq_add_stmt (pre_p
, gimple_build_label (fall_thru_label
));
4638 /* Otherwise, increment the index var... */
4639 tmp
= build2 (PLUS_EXPR
, var_type
, var
,
4640 fold_convert (var_type
, integer_one_node
));
4641 gimplify_seq_add_stmt (pre_p
, gimple_build_assign (var
, tmp
));
4643 /* ...and jump back to the loop entry. */
4644 gimplify_seq_add_stmt (pre_p
, gimple_build_goto (loop_entry_label
));
4646 /* Add the loop exit label. */
4647 gimplify_seq_add_stmt (pre_p
, gimple_build_label (loop_exit_label
));
4650 /* A subroutine of gimplify_init_constructor. Generate individual
4651 MODIFY_EXPRs for a CONSTRUCTOR. OBJECT is the LHS against which the
4652 assignments should happen. ELTS is the CONSTRUCTOR_ELTS of the
4653 CONSTRUCTOR. CLEARED is true if the entire LHS object has been
4657 gimplify_init_ctor_eval (tree object
, vec
<constructor_elt
, va_gc
> *elts
,
4658 gimple_seq
*pre_p
, bool cleared
)
4660 tree array_elt_type
= NULL
;
4661 unsigned HOST_WIDE_INT ix
;
4662 tree purpose
, value
;
4664 if (TREE_CODE (TREE_TYPE (object
)) == ARRAY_TYPE
)
4665 array_elt_type
= TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (object
)));
4667 FOR_EACH_CONSTRUCTOR_ELT (elts
, ix
, purpose
, value
)
4671 /* NULL values are created above for gimplification errors. */
4675 if (cleared
&& initializer_zerop (value
))
4678 /* ??? Here's to hoping the front end fills in all of the indices,
4679 so we don't have to figure out what's missing ourselves. */
4680 gcc_assert (purpose
);
4682 /* Skip zero-sized fields, unless value has side-effects. This can
4683 happen with calls to functions returning a empty type, which
4684 we shouldn't discard. As a number of downstream passes don't
4685 expect sets of empty type fields, we rely on the gimplification of
4686 the MODIFY_EXPR we make below to drop the assignment statement. */
4687 if (!TREE_SIDE_EFFECTS (value
)
4688 && TREE_CODE (purpose
) == FIELD_DECL
4689 && is_empty_type (TREE_TYPE (purpose
)))
4692 /* If we have a RANGE_EXPR, we have to build a loop to assign the
4694 if (TREE_CODE (purpose
) == RANGE_EXPR
)
4696 tree lower
= TREE_OPERAND (purpose
, 0);
4697 tree upper
= TREE_OPERAND (purpose
, 1);
4699 /* If the lower bound is equal to upper, just treat it as if
4700 upper was the index. */
4701 if (simple_cst_equal (lower
, upper
))
4705 gimplify_init_ctor_eval_range (object
, lower
, upper
, value
,
4706 array_elt_type
, pre_p
, cleared
);
4713 /* Do not use bitsizetype for ARRAY_REF indices. */
4714 if (TYPE_DOMAIN (TREE_TYPE (object
)))
4716 = fold_convert (TREE_TYPE (TYPE_DOMAIN (TREE_TYPE (object
))),
4718 cref
= build4 (ARRAY_REF
, array_elt_type
, unshare_expr (object
),
4719 purpose
, NULL_TREE
, NULL_TREE
);
4723 gcc_assert (TREE_CODE (purpose
) == FIELD_DECL
);
4724 cref
= build3 (COMPONENT_REF
, TREE_TYPE (purpose
),
4725 unshare_expr (object
), purpose
, NULL_TREE
);
4728 if (TREE_CODE (value
) == CONSTRUCTOR
4729 && TREE_CODE (TREE_TYPE (value
)) != VECTOR_TYPE
)
4730 gimplify_init_ctor_eval (cref
, CONSTRUCTOR_ELTS (value
),
4734 tree init
= build2 (INIT_EXPR
, TREE_TYPE (cref
), cref
, value
);
4735 gimplify_and_add (init
, pre_p
);
4741 /* Return the appropriate RHS predicate for this LHS. */
4744 rhs_predicate_for (tree lhs
)
4746 if (is_gimple_reg (lhs
))
4747 return is_gimple_reg_rhs_or_call
;
4749 return is_gimple_mem_rhs_or_call
;
4752 /* Return the initial guess for an appropriate RHS predicate for this LHS,
4753 before the LHS has been gimplified. */
4755 static gimple_predicate
4756 initial_rhs_predicate_for (tree lhs
)
4758 if (is_gimple_reg_type (TREE_TYPE (lhs
)))
4759 return is_gimple_reg_rhs_or_call
;
4761 return is_gimple_mem_rhs_or_call
;
4764 /* Gimplify a C99 compound literal expression. This just means adding
4765 the DECL_EXPR before the current statement and using its anonymous
4768 static enum gimplify_status
4769 gimplify_compound_literal_expr (tree
*expr_p
, gimple_seq
*pre_p
,
4770 bool (*gimple_test_f
) (tree
),
4771 fallback_t fallback
)
4773 tree decl_s
= COMPOUND_LITERAL_EXPR_DECL_EXPR (*expr_p
);
4774 tree decl
= DECL_EXPR_DECL (decl_s
);
4775 tree init
= DECL_INITIAL (decl
);
4776 /* Mark the decl as addressable if the compound literal
4777 expression is addressable now, otherwise it is marked too late
4778 after we gimplify the initialization expression. */
4779 if (TREE_ADDRESSABLE (*expr_p
))
4780 TREE_ADDRESSABLE (decl
) = 1;
4781 /* Otherwise, if we don't need an lvalue and have a literal directly
4782 substitute it. Check if it matches the gimple predicate, as
4783 otherwise we'd generate a new temporary, and we can as well just
4784 use the decl we already have. */
4785 else if (!TREE_ADDRESSABLE (decl
)
4786 && !TREE_THIS_VOLATILE (decl
)
4788 && (fallback
& fb_lvalue
) == 0
4789 && gimple_test_f (init
))
4795 /* If the decl is not addressable, then it is being used in some
4796 expression or on the right hand side of a statement, and it can
4797 be put into a readonly data section. */
4798 if (!TREE_ADDRESSABLE (decl
) && (fallback
& fb_lvalue
) == 0)
4799 TREE_READONLY (decl
) = 1;
4801 /* This decl isn't mentioned in the enclosing block, so add it to the
4802 list of temps. FIXME it seems a bit of a kludge to say that
4803 anonymous artificial vars aren't pushed, but everything else is. */
4804 if (DECL_NAME (decl
) == NULL_TREE
&& !DECL_SEEN_IN_BIND_EXPR_P (decl
))
4805 gimple_add_tmp_var (decl
);
4807 gimplify_and_add (decl_s
, pre_p
);
4812 /* Optimize embedded COMPOUND_LITERAL_EXPRs within a CONSTRUCTOR,
4813 return a new CONSTRUCTOR if something changed. */
4816 optimize_compound_literals_in_ctor (tree orig_ctor
)
4818 tree ctor
= orig_ctor
;
4819 vec
<constructor_elt
, va_gc
> *elts
= CONSTRUCTOR_ELTS (ctor
);
4820 unsigned int idx
, num
= vec_safe_length (elts
);
4822 for (idx
= 0; idx
< num
; idx
++)
4824 tree value
= (*elts
)[idx
].value
;
4825 tree newval
= value
;
4826 if (TREE_CODE (value
) == CONSTRUCTOR
)
4827 newval
= optimize_compound_literals_in_ctor (value
);
4828 else if (TREE_CODE (value
) == COMPOUND_LITERAL_EXPR
)
4830 tree decl_s
= COMPOUND_LITERAL_EXPR_DECL_EXPR (value
);
4831 tree decl
= DECL_EXPR_DECL (decl_s
);
4832 tree init
= DECL_INITIAL (decl
);
4834 if (!TREE_ADDRESSABLE (value
)
4835 && !TREE_ADDRESSABLE (decl
)
4837 && TREE_CODE (init
) == CONSTRUCTOR
)
4838 newval
= optimize_compound_literals_in_ctor (init
);
4840 if (newval
== value
)
4843 if (ctor
== orig_ctor
)
4845 ctor
= copy_node (orig_ctor
);
4846 CONSTRUCTOR_ELTS (ctor
) = vec_safe_copy (elts
);
4847 elts
= CONSTRUCTOR_ELTS (ctor
);
4849 (*elts
)[idx
].value
= newval
;
4854 /* A subroutine of gimplify_modify_expr. Break out elements of a
4855 CONSTRUCTOR used as an initializer into separate MODIFY_EXPRs.
4857 Note that we still need to clear any elements that don't have explicit
4858 initializers, so if not all elements are initialized we keep the
4859 original MODIFY_EXPR, we just remove all of the constructor elements.
4861 If NOTIFY_TEMP_CREATION is true, do not gimplify, just return
4862 GS_ERROR if we would have to create a temporary when gimplifying
4863 this constructor. Otherwise, return GS_OK.
4865 If NOTIFY_TEMP_CREATION is false, just do the gimplification. */
4867 static enum gimplify_status
4868 gimplify_init_constructor (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
4869 bool want_value
, bool notify_temp_creation
)
4871 tree object
, ctor
, type
;
4872 enum gimplify_status ret
;
4873 vec
<constructor_elt
, va_gc
> *elts
;
4875 gcc_assert (TREE_CODE (TREE_OPERAND (*expr_p
, 1)) == CONSTRUCTOR
);
4877 if (!notify_temp_creation
)
4879 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
4880 is_gimple_lvalue
, fb_lvalue
);
4881 if (ret
== GS_ERROR
)
4885 object
= TREE_OPERAND (*expr_p
, 0);
4886 ctor
= TREE_OPERAND (*expr_p
, 1)
4887 = optimize_compound_literals_in_ctor (TREE_OPERAND (*expr_p
, 1));
4888 type
= TREE_TYPE (ctor
);
4889 elts
= CONSTRUCTOR_ELTS (ctor
);
4892 switch (TREE_CODE (type
))
4896 case QUAL_UNION_TYPE
:
4899 /* Use readonly data for initializers of this or smaller size
4900 regardless of the num_nonzero_elements / num_unique_nonzero_elements
4902 const HOST_WIDE_INT min_unique_size
= 64;
4903 /* If num_nonzero_elements / num_unique_nonzero_elements ratio
4904 is smaller than this, use readonly data. */
4905 const int unique_nonzero_ratio
= 8;
4906 /* True if a single access of the object must be ensured. This is the
4907 case if the target is volatile, the type is non-addressable and more
4908 than one field need to be assigned. */
4909 const bool ensure_single_access
4910 = TREE_THIS_VOLATILE (object
)
4911 && !TREE_ADDRESSABLE (type
)
4912 && vec_safe_length (elts
) > 1;
4913 struct gimplify_init_ctor_preeval_data preeval_data
;
4914 HOST_WIDE_INT num_ctor_elements
, num_nonzero_elements
;
4915 HOST_WIDE_INT num_unique_nonzero_elements
;
4916 bool cleared
, complete_p
, valid_const_initializer
;
4918 /* Aggregate types must lower constructors to initialization of
4919 individual elements. The exception is that a CONSTRUCTOR node
4920 with no elements indicates zero-initialization of the whole. */
4921 if (vec_safe_is_empty (elts
))
4923 if (notify_temp_creation
)
4928 /* Fetch information about the constructor to direct later processing.
4929 We might want to make static versions of it in various cases, and
4930 can only do so if it known to be a valid constant initializer. */
4931 valid_const_initializer
4932 = categorize_ctor_elements (ctor
, &num_nonzero_elements
,
4933 &num_unique_nonzero_elements
,
4934 &num_ctor_elements
, &complete_p
);
4936 /* If a const aggregate variable is being initialized, then it
4937 should never be a lose to promote the variable to be static. */
4938 if (valid_const_initializer
4939 && num_nonzero_elements
> 1
4940 && TREE_READONLY (object
)
4942 && !DECL_REGISTER (object
)
4943 && (flag_merge_constants
>= 2 || !TREE_ADDRESSABLE (object
))
4944 /* For ctors that have many repeated nonzero elements
4945 represented through RANGE_EXPRs, prefer initializing
4946 those through runtime loops over copies of large amounts
4947 of data from readonly data section. */
4948 && (num_unique_nonzero_elements
4949 > num_nonzero_elements
/ unique_nonzero_ratio
4950 || ((unsigned HOST_WIDE_INT
) int_size_in_bytes (type
)
4951 <= (unsigned HOST_WIDE_INT
) min_unique_size
)))
4953 if (notify_temp_creation
)
4956 DECL_INITIAL (object
) = ctor
;
4957 TREE_STATIC (object
) = 1;
4958 if (!DECL_NAME (object
))
4959 DECL_NAME (object
) = create_tmp_var_name ("C");
4960 walk_tree (&DECL_INITIAL (object
), force_labels_r
, NULL
, NULL
);
4962 /* ??? C++ doesn't automatically append a .<number> to the
4963 assembler name, and even when it does, it looks at FE private
4964 data structures to figure out what that number should be,
4965 which are not set for this variable. I suppose this is
4966 important for local statics for inline functions, which aren't
4967 "local" in the object file sense. So in order to get a unique
4968 TU-local symbol, we must invoke the lhd version now. */
4969 lhd_set_decl_assembler_name (object
);
4971 *expr_p
= NULL_TREE
;
4975 /* If there are "lots" of initialized elements, even discounting
4976 those that are not address constants (and thus *must* be
4977 computed at runtime), then partition the constructor into
4978 constant and non-constant parts. Block copy the constant
4979 parts in, then generate code for the non-constant parts. */
4980 /* TODO. There's code in cp/typeck.c to do this. */
4982 if (int_size_in_bytes (TREE_TYPE (ctor
)) < 0)
4983 /* store_constructor will ignore the clearing of variable-sized
4984 objects. Initializers for such objects must explicitly set
4985 every field that needs to be set. */
4987 else if (!complete_p
)
4988 /* If the constructor isn't complete, clear the whole object
4989 beforehand, unless CONSTRUCTOR_NO_CLEARING is set on it.
4991 ??? This ought not to be needed. For any element not present
4992 in the initializer, we should simply set them to zero. Except
4993 we'd need to *find* the elements that are not present, and that
4994 requires trickery to avoid quadratic compile-time behavior in
4995 large cases or excessive memory use in small cases. */
4996 cleared
= !CONSTRUCTOR_NO_CLEARING (ctor
);
4997 else if (num_ctor_elements
- num_nonzero_elements
4998 > CLEAR_RATIO (optimize_function_for_speed_p (cfun
))
4999 && num_nonzero_elements
< num_ctor_elements
/ 4)
5000 /* If there are "lots" of zeros, it's more efficient to clear
5001 the memory and then set the nonzero elements. */
5003 else if (ensure_single_access
&& num_nonzero_elements
== 0)
5004 /* If a single access to the target must be ensured and all elements
5005 are zero, then it's optimal to clear whatever their number. */
5010 /* If there are "lots" of initialized elements, and all of them
5011 are valid address constants, then the entire initializer can
5012 be dropped to memory, and then memcpy'd out. Don't do this
5013 for sparse arrays, though, as it's more efficient to follow
5014 the standard CONSTRUCTOR behavior of memset followed by
5015 individual element initialization. Also don't do this for small
5016 all-zero initializers (which aren't big enough to merit
5017 clearing), and don't try to make bitwise copies of
5018 TREE_ADDRESSABLE types. */
5019 if (valid_const_initializer
5021 && !(cleared
|| num_nonzero_elements
== 0)
5022 && !TREE_ADDRESSABLE (type
))
5024 HOST_WIDE_INT size
= int_size_in_bytes (type
);
5027 /* ??? We can still get unbounded array types, at least
5028 from the C++ front end. This seems wrong, but attempt
5029 to work around it for now. */
5032 size
= int_size_in_bytes (TREE_TYPE (object
));
5034 TREE_TYPE (ctor
) = type
= TREE_TYPE (object
);
5037 /* Find the maximum alignment we can assume for the object. */
5038 /* ??? Make use of DECL_OFFSET_ALIGN. */
5039 if (DECL_P (object
))
5040 align
= DECL_ALIGN (object
);
5042 align
= TYPE_ALIGN (type
);
5044 /* Do a block move either if the size is so small as to make
5045 each individual move a sub-unit move on average, or if it
5046 is so large as to make individual moves inefficient. */
5048 && num_nonzero_elements
> 1
5049 /* For ctors that have many repeated nonzero elements
5050 represented through RANGE_EXPRs, prefer initializing
5051 those through runtime loops over copies of large amounts
5052 of data from readonly data section. */
5053 && (num_unique_nonzero_elements
5054 > num_nonzero_elements
/ unique_nonzero_ratio
5055 || size
<= min_unique_size
)
5056 && (size
< num_nonzero_elements
5057 || !can_move_by_pieces (size
, align
)))
5059 if (notify_temp_creation
)
5062 walk_tree (&ctor
, force_labels_r
, NULL
, NULL
);
5063 ctor
= tree_output_constant_def (ctor
);
5064 if (!useless_type_conversion_p (type
, TREE_TYPE (ctor
)))
5065 ctor
= build1 (VIEW_CONVERT_EXPR
, type
, ctor
);
5066 TREE_OPERAND (*expr_p
, 1) = ctor
;
5068 /* This is no longer an assignment of a CONSTRUCTOR, but
5069 we still may have processing to do on the LHS. So
5070 pretend we didn't do anything here to let that happen. */
5071 return GS_UNHANDLED
;
5075 /* If a single access to the target must be ensured and there are
5076 nonzero elements or the zero elements are not assigned en masse,
5077 initialize the target from a temporary. */
5078 if (ensure_single_access
&& (num_nonzero_elements
> 0 || !cleared
))
5080 if (notify_temp_creation
)
5083 tree temp
= create_tmp_var (TYPE_MAIN_VARIANT (type
));
5084 TREE_OPERAND (*expr_p
, 0) = temp
;
5085 *expr_p
= build2 (COMPOUND_EXPR
, TREE_TYPE (*expr_p
),
5087 build2 (MODIFY_EXPR
, void_type_node
,
5092 if (notify_temp_creation
)
5095 /* If there are nonzero elements and if needed, pre-evaluate to capture
5096 elements overlapping with the lhs into temporaries. We must do this
5097 before clearing to fetch the values before they are zeroed-out. */
5098 if (num_nonzero_elements
> 0 && TREE_CODE (*expr_p
) != INIT_EXPR
)
5100 preeval_data
.lhs_base_decl
= get_base_address (object
);
5101 if (!DECL_P (preeval_data
.lhs_base_decl
))
5102 preeval_data
.lhs_base_decl
= NULL
;
5103 preeval_data
.lhs_alias_set
= get_alias_set (object
);
5105 gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p
, 1),
5106 pre_p
, post_p
, &preeval_data
);
5109 bool ctor_has_side_effects_p
5110 = TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p
, 1));
5114 /* Zap the CONSTRUCTOR element list, which simplifies this case.
5115 Note that we still have to gimplify, in order to handle the
5116 case of variable sized types. Avoid shared tree structures. */
5117 CONSTRUCTOR_ELTS (ctor
) = NULL
;
5118 TREE_SIDE_EFFECTS (ctor
) = 0;
5119 object
= unshare_expr (object
);
5120 gimplify_stmt (expr_p
, pre_p
);
5123 /* If we have not block cleared the object, or if there are nonzero
5124 elements in the constructor, or if the constructor has side effects,
5125 add assignments to the individual scalar fields of the object. */
5127 || num_nonzero_elements
> 0
5128 || ctor_has_side_effects_p
)
5129 gimplify_init_ctor_eval (object
, elts
, pre_p
, cleared
);
5131 *expr_p
= NULL_TREE
;
5139 if (notify_temp_creation
)
5142 /* Extract the real and imaginary parts out of the ctor. */
5143 gcc_assert (elts
->length () == 2);
5144 r
= (*elts
)[0].value
;
5145 i
= (*elts
)[1].value
;
5146 if (r
== NULL
|| i
== NULL
)
5148 tree zero
= build_zero_cst (TREE_TYPE (type
));
5155 /* Complex types have either COMPLEX_CST or COMPLEX_EXPR to
5156 represent creation of a complex value. */
5157 if (TREE_CONSTANT (r
) && TREE_CONSTANT (i
))
5159 ctor
= build_complex (type
, r
, i
);
5160 TREE_OPERAND (*expr_p
, 1) = ctor
;
5164 ctor
= build2 (COMPLEX_EXPR
, type
, r
, i
);
5165 TREE_OPERAND (*expr_p
, 1) = ctor
;
5166 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 1),
5169 rhs_predicate_for (TREE_OPERAND (*expr_p
, 0)),
5177 unsigned HOST_WIDE_INT ix
;
5178 constructor_elt
*ce
;
5180 if (notify_temp_creation
)
5183 /* Go ahead and simplify constant constructors to VECTOR_CST. */
5184 if (TREE_CONSTANT (ctor
))
5186 bool constant_p
= true;
5189 /* Even when ctor is constant, it might contain non-*_CST
5190 elements, such as addresses or trapping values like
5191 1.0/0.0 - 1.0/0.0. Such expressions don't belong
5192 in VECTOR_CST nodes. */
5193 FOR_EACH_CONSTRUCTOR_VALUE (elts
, ix
, value
)
5194 if (!CONSTANT_CLASS_P (value
))
5202 TREE_OPERAND (*expr_p
, 1) = build_vector_from_ctor (type
, elts
);
5206 TREE_CONSTANT (ctor
) = 0;
5209 /* Vector types use CONSTRUCTOR all the way through gimple
5210 compilation as a general initializer. */
5211 FOR_EACH_VEC_SAFE_ELT (elts
, ix
, ce
)
5213 enum gimplify_status tret
;
5214 tret
= gimplify_expr (&ce
->value
, pre_p
, post_p
, is_gimple_val
,
5216 if (tret
== GS_ERROR
)
5218 else if (TREE_STATIC (ctor
)
5219 && !initializer_constant_valid_p (ce
->value
,
5220 TREE_TYPE (ce
->value
)))
5221 TREE_STATIC (ctor
) = 0;
5223 recompute_constructor_flags (ctor
);
5224 if (!is_gimple_reg (TREE_OPERAND (*expr_p
, 0)))
5225 TREE_OPERAND (*expr_p
, 1) = get_formal_tmp_var (ctor
, pre_p
);
5230 /* So how did we get a CONSTRUCTOR for a scalar type? */
5234 if (ret
== GS_ERROR
)
5236 /* If we have gimplified both sides of the initializer but have
5237 not emitted an assignment, do so now. */
5240 tree lhs
= TREE_OPERAND (*expr_p
, 0);
5241 tree rhs
= TREE_OPERAND (*expr_p
, 1);
5242 if (want_value
&& object
== lhs
)
5243 lhs
= unshare_expr (lhs
);
5244 gassign
*init
= gimple_build_assign (lhs
, rhs
);
5245 gimplify_seq_add_stmt (pre_p
, init
);
5259 /* Given a pointer value OP0, return a simplified version of an
5260 indirection through OP0, or NULL_TREE if no simplification is
5261 possible. This may only be applied to a rhs of an expression.
5262 Note that the resulting type may be different from the type pointed
5263 to in the sense that it is still compatible from the langhooks
5267 gimple_fold_indirect_ref_rhs (tree t
)
5269 return gimple_fold_indirect_ref (t
);
5272 /* Subroutine of gimplify_modify_expr to do simplifications of
5273 MODIFY_EXPRs based on the code of the RHS. We loop for as long as
5274 something changes. */
5276 static enum gimplify_status
5277 gimplify_modify_expr_rhs (tree
*expr_p
, tree
*from_p
, tree
*to_p
,
5278 gimple_seq
*pre_p
, gimple_seq
*post_p
,
5281 enum gimplify_status ret
= GS_UNHANDLED
;
5287 switch (TREE_CODE (*from_p
))
5290 /* If we're assigning from a read-only variable initialized with
5291 a constructor and not volatile, do the direct assignment from
5292 the constructor, but only if the target is not volatile either
5293 since this latter assignment might end up being done on a per
5294 field basis. However, if the target is volatile and the type
5295 is aggregate and non-addressable, gimplify_init_constructor
5296 knows that it needs to ensure a single access to the target
5297 and it will return GS_OK only in this case. */
5298 if (TREE_READONLY (*from_p
)
5299 && DECL_INITIAL (*from_p
)
5300 && TREE_CODE (DECL_INITIAL (*from_p
)) == CONSTRUCTOR
5301 && !TREE_THIS_VOLATILE (*from_p
)
5302 && (!TREE_THIS_VOLATILE (*to_p
)
5303 || (AGGREGATE_TYPE_P (TREE_TYPE (*to_p
))
5304 && !TREE_ADDRESSABLE (TREE_TYPE (*to_p
)))))
5306 tree old_from
= *from_p
;
5307 enum gimplify_status subret
;
5309 /* Move the constructor into the RHS. */
5310 *from_p
= unshare_expr (DECL_INITIAL (*from_p
));
5312 /* Let's see if gimplify_init_constructor will need to put
5314 subret
= gimplify_init_constructor (expr_p
, NULL
, NULL
,
5316 if (subret
== GS_ERROR
)
5318 /* If so, revert the change. */
5330 /* If we have code like
5334 where the type of "x" is a (possibly cv-qualified variant
5335 of "A"), treat the entire expression as identical to "x".
5336 This kind of code arises in C++ when an object is bound
5337 to a const reference, and if "x" is a TARGET_EXPR we want
5338 to take advantage of the optimization below. */
5339 bool volatile_p
= TREE_THIS_VOLATILE (*from_p
);
5340 tree t
= gimple_fold_indirect_ref_rhs (TREE_OPERAND (*from_p
, 0));
5343 if (TREE_THIS_VOLATILE (t
) != volatile_p
)
5346 t
= build_simple_mem_ref_loc (EXPR_LOCATION (*from_p
),
5347 build_fold_addr_expr (t
));
5348 if (REFERENCE_CLASS_P (t
))
5349 TREE_THIS_VOLATILE (t
) = volatile_p
;
5360 /* If we are initializing something from a TARGET_EXPR, strip the
5361 TARGET_EXPR and initialize it directly, if possible. This can't
5362 be done if the initializer is void, since that implies that the
5363 temporary is set in some non-trivial way.
5365 ??? What about code that pulls out the temp and uses it
5366 elsewhere? I think that such code never uses the TARGET_EXPR as
5367 an initializer. If I'm wrong, we'll die because the temp won't
5368 have any RTL. In that case, I guess we'll need to replace
5369 references somehow. */
5370 tree init
= TARGET_EXPR_INITIAL (*from_p
);
5373 && (TREE_CODE (*expr_p
) != MODIFY_EXPR
5374 || !TARGET_EXPR_NO_ELIDE (*from_p
))
5375 && !VOID_TYPE_P (TREE_TYPE (init
)))
5385 /* Remove any COMPOUND_EXPR in the RHS so the following cases will be
5387 gimplify_compound_expr (from_p
, pre_p
, true);
5393 /* If we already made some changes, let the front end have a
5394 crack at this before we break it down. */
5395 if (ret
!= GS_UNHANDLED
)
5397 /* If we're initializing from a CONSTRUCTOR, break this into
5398 individual MODIFY_EXPRs. */
5399 return gimplify_init_constructor (expr_p
, pre_p
, post_p
, want_value
,
5403 /* If we're assigning to a non-register type, push the assignment
5404 down into the branches. This is mandatory for ADDRESSABLE types,
5405 since we cannot generate temporaries for such, but it saves a
5406 copy in other cases as well. */
5407 if (!is_gimple_reg_type (TREE_TYPE (*from_p
)))
5409 /* This code should mirror the code in gimplify_cond_expr. */
5410 enum tree_code code
= TREE_CODE (*expr_p
);
5411 tree cond
= *from_p
;
5412 tree result
= *to_p
;
5414 ret
= gimplify_expr (&result
, pre_p
, post_p
,
5415 is_gimple_lvalue
, fb_lvalue
);
5416 if (ret
!= GS_ERROR
)
5419 /* If we are going to write RESULT more than once, clear
5420 TREE_READONLY flag, otherwise we might incorrectly promote
5421 the variable to static const and initialize it at compile
5422 time in one of the branches. */
5424 && TREE_TYPE (TREE_OPERAND (cond
, 1)) != void_type_node
5425 && TREE_TYPE (TREE_OPERAND (cond
, 2)) != void_type_node
)
5426 TREE_READONLY (result
) = 0;
5427 if (TREE_TYPE (TREE_OPERAND (cond
, 1)) != void_type_node
)
5428 TREE_OPERAND (cond
, 1)
5429 = build2 (code
, void_type_node
, result
,
5430 TREE_OPERAND (cond
, 1));
5431 if (TREE_TYPE (TREE_OPERAND (cond
, 2)) != void_type_node
)
5432 TREE_OPERAND (cond
, 2)
5433 = build2 (code
, void_type_node
, unshare_expr (result
),
5434 TREE_OPERAND (cond
, 2));
5436 TREE_TYPE (cond
) = void_type_node
;
5437 recalculate_side_effects (cond
);
5441 gimplify_and_add (cond
, pre_p
);
5442 *expr_p
= unshare_expr (result
);
5451 /* For calls that return in memory, give *to_p as the CALL_EXPR's
5452 return slot so that we don't generate a temporary. */
5453 if (!CALL_EXPR_RETURN_SLOT_OPT (*from_p
)
5454 && aggregate_value_p (*from_p
, *from_p
))
5458 if (!(rhs_predicate_for (*to_p
))(*from_p
))
5459 /* If we need a temporary, *to_p isn't accurate. */
5461 /* It's OK to use the return slot directly unless it's an NRV. */
5462 else if (TREE_CODE (*to_p
) == RESULT_DECL
5463 && DECL_NAME (*to_p
) == NULL_TREE
5464 && needs_to_live_in_memory (*to_p
))
5466 else if (is_gimple_reg_type (TREE_TYPE (*to_p
))
5467 || (DECL_P (*to_p
) && DECL_REGISTER (*to_p
)))
5468 /* Don't force regs into memory. */
5470 else if (TREE_CODE (*expr_p
) == INIT_EXPR
)
5471 /* It's OK to use the target directly if it's being
5474 else if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p
)))
5476 /* Always use the target and thus RSO for variable-sized types.
5477 GIMPLE cannot deal with a variable-sized assignment
5478 embedded in a call statement. */
5480 else if (TREE_CODE (*to_p
) != SSA_NAME
5481 && (!is_gimple_variable (*to_p
)
5482 || needs_to_live_in_memory (*to_p
)))
5483 /* Don't use the original target if it's already addressable;
5484 if its address escapes, and the called function uses the
5485 NRV optimization, a conforming program could see *to_p
5486 change before the called function returns; see c++/19317.
5487 When optimizing, the return_slot pass marks more functions
5488 as safe after we have escape info. */
5495 CALL_EXPR_RETURN_SLOT_OPT (*from_p
) = 1;
5496 mark_addressable (*to_p
);
5501 case WITH_SIZE_EXPR
:
5502 /* Likewise for calls that return an aggregate of non-constant size,
5503 since we would not be able to generate a temporary at all. */
5504 if (TREE_CODE (TREE_OPERAND (*from_p
, 0)) == CALL_EXPR
)
5506 *from_p
= TREE_OPERAND (*from_p
, 0);
5507 /* We don't change ret in this case because the
5508 WITH_SIZE_EXPR might have been added in
5509 gimplify_modify_expr, so returning GS_OK would lead to an
5515 /* If we're initializing from a container, push the initialization
5517 case CLEANUP_POINT_EXPR
:
5519 case STATEMENT_LIST
:
5521 tree wrap
= *from_p
;
5524 ret
= gimplify_expr (to_p
, pre_p
, post_p
, is_gimple_min_lval
,
5526 if (ret
!= GS_ERROR
)
5529 t
= voidify_wrapper_expr (wrap
, *expr_p
);
5530 gcc_assert (t
== *expr_p
);
5534 gimplify_and_add (wrap
, pre_p
);
5535 *expr_p
= unshare_expr (*to_p
);
5543 /* Pull out compound literal expressions from a NOP_EXPR.
5544 Those are created in the C FE to drop qualifiers during
5545 lvalue conversion. */
5546 if ((TREE_CODE (TREE_OPERAND (*from_p
, 0)) == COMPOUND_LITERAL_EXPR
)
5547 && tree_ssa_useless_type_conversion (*from_p
))
5549 *from_p
= TREE_OPERAND (*from_p
, 0);
5555 case COMPOUND_LITERAL_EXPR
:
5557 tree complit
= TREE_OPERAND (*expr_p
, 1);
5558 tree decl_s
= COMPOUND_LITERAL_EXPR_DECL_EXPR (complit
);
5559 tree decl
= DECL_EXPR_DECL (decl_s
);
5560 tree init
= DECL_INITIAL (decl
);
5562 /* struct T x = (struct T) { 0, 1, 2 } can be optimized
5563 into struct T x = { 0, 1, 2 } if the address of the
5564 compound literal has never been taken. */
5565 if (!TREE_ADDRESSABLE (complit
)
5566 && !TREE_ADDRESSABLE (decl
)
5569 *expr_p
= copy_node (*expr_p
);
5570 TREE_OPERAND (*expr_p
, 1) = init
;
5585 /* Return true if T looks like a valid GIMPLE statement. */
5588 is_gimple_stmt (tree t
)
5590 const enum tree_code code
= TREE_CODE (t
);
5595 /* The only valid NOP_EXPR is the empty statement. */
5596 return IS_EMPTY_STMT (t
);
5600 /* These are only valid if they're void. */
5601 return TREE_TYPE (t
) == NULL
|| VOID_TYPE_P (TREE_TYPE (t
));
5607 case CASE_LABEL_EXPR
:
5608 case TRY_CATCH_EXPR
:
5609 case TRY_FINALLY_EXPR
:
5610 case EH_FILTER_EXPR
:
5613 case STATEMENT_LIST
:
5618 case OACC_HOST_DATA
:
5621 case OACC_ENTER_DATA
:
5622 case OACC_EXIT_DATA
:
5627 case OMP_DISTRIBUTE
:
5642 case OMP_TARGET_DATA
:
5643 case OMP_TARGET_UPDATE
:
5644 case OMP_TARGET_ENTER_DATA
:
5645 case OMP_TARGET_EXIT_DATA
:
5648 /* These are always void. */
5654 /* These are valid regardless of their type. */
5663 /* Promote partial stores to COMPLEX variables to total stores. *EXPR_P is
5664 a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a gimple register.
5666 IMPORTANT NOTE: This promotion is performed by introducing a load of the
5667 other, unmodified part of the complex object just before the total store.
5668 As a consequence, if the object is still uninitialized, an undefined value
5669 will be loaded into a register, which may result in a spurious exception
5670 if the register is floating-point and the value happens to be a signaling
5671 NaN for example. Then the fully-fledged complex operations lowering pass
5672 followed by a DCE pass are necessary in order to fix things up. */
5674 static enum gimplify_status
5675 gimplify_modify_expr_complex_part (tree
*expr_p
, gimple_seq
*pre_p
,
5678 enum tree_code code
, ocode
;
5679 tree lhs
, rhs
, new_rhs
, other
, realpart
, imagpart
;
5681 lhs
= TREE_OPERAND (*expr_p
, 0);
5682 rhs
= TREE_OPERAND (*expr_p
, 1);
5683 code
= TREE_CODE (lhs
);
5684 lhs
= TREE_OPERAND (lhs
, 0);
5686 ocode
= code
== REALPART_EXPR
? IMAGPART_EXPR
: REALPART_EXPR
;
5687 other
= build1 (ocode
, TREE_TYPE (rhs
), lhs
);
5688 suppress_warning (other
);
5689 other
= get_formal_tmp_var (other
, pre_p
);
5691 realpart
= code
== REALPART_EXPR
? rhs
: other
;
5692 imagpart
= code
== REALPART_EXPR
? other
: rhs
;
5694 if (TREE_CONSTANT (realpart
) && TREE_CONSTANT (imagpart
))
5695 new_rhs
= build_complex (TREE_TYPE (lhs
), realpart
, imagpart
);
5697 new_rhs
= build2 (COMPLEX_EXPR
, TREE_TYPE (lhs
), realpart
, imagpart
);
5699 gimplify_seq_add_stmt (pre_p
, gimple_build_assign (lhs
, new_rhs
));
5700 *expr_p
= (want_value
) ? rhs
: NULL_TREE
;
5705 /* Gimplify the MODIFY_EXPR node pointed to by EXPR_P.
5711 PRE_P points to the list where side effects that must happen before
5712 *EXPR_P should be stored.
5714 POST_P points to the list where side effects that must happen after
5715 *EXPR_P should be stored.
5717 WANT_VALUE is nonzero iff we want to use the value of this expression
5718 in another expression. */
5720 static enum gimplify_status
5721 gimplify_modify_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
5724 tree
*from_p
= &TREE_OPERAND (*expr_p
, 1);
5725 tree
*to_p
= &TREE_OPERAND (*expr_p
, 0);
5726 enum gimplify_status ret
= GS_UNHANDLED
;
5728 location_t loc
= EXPR_LOCATION (*expr_p
);
5729 gimple_stmt_iterator gsi
;
5731 gcc_assert (TREE_CODE (*expr_p
) == MODIFY_EXPR
5732 || TREE_CODE (*expr_p
) == INIT_EXPR
);
5734 /* Trying to simplify a clobber using normal logic doesn't work,
5735 so handle it here. */
5736 if (TREE_CLOBBER_P (*from_p
))
5738 ret
= gimplify_expr (to_p
, pre_p
, post_p
, is_gimple_lvalue
, fb_lvalue
);
5739 if (ret
== GS_ERROR
)
5741 gcc_assert (!want_value
);
5742 if (!VAR_P (*to_p
) && TREE_CODE (*to_p
) != MEM_REF
)
5744 tree addr
= get_initialized_tmp_var (build_fold_addr_expr (*to_p
),
5746 *to_p
= build_simple_mem_ref_loc (EXPR_LOCATION (*to_p
), addr
);
5748 gimplify_seq_add_stmt (pre_p
, gimple_build_assign (*to_p
, *from_p
));
5753 /* Insert pointer conversions required by the middle-end that are not
5754 required by the frontend. This fixes middle-end type checking for
5755 for example gcc.dg/redecl-6.c. */
5756 if (POINTER_TYPE_P (TREE_TYPE (*to_p
)))
5758 STRIP_USELESS_TYPE_CONVERSION (*from_p
);
5759 if (!useless_type_conversion_p (TREE_TYPE (*to_p
), TREE_TYPE (*from_p
)))
5760 *from_p
= fold_convert_loc (loc
, TREE_TYPE (*to_p
), *from_p
);
5763 /* See if any simplifications can be done based on what the RHS is. */
5764 ret
= gimplify_modify_expr_rhs (expr_p
, from_p
, to_p
, pre_p
, post_p
,
5766 if (ret
!= GS_UNHANDLED
)
5769 /* For empty types only gimplify the left hand side and right hand
5770 side as statements and throw away the assignment. Do this after
5771 gimplify_modify_expr_rhs so we handle TARGET_EXPRs of addressable
5773 if (is_empty_type (TREE_TYPE (*from_p
))
5775 /* Don't do this for calls that return addressable types, expand_call
5776 relies on those having a lhs. */
5777 && !(TREE_ADDRESSABLE (TREE_TYPE (*from_p
))
5778 && TREE_CODE (*from_p
) == CALL_EXPR
))
5780 gimplify_stmt (from_p
, pre_p
);
5781 gimplify_stmt (to_p
, pre_p
);
5782 *expr_p
= NULL_TREE
;
5786 /* If the value being copied is of variable width, compute the length
5787 of the copy into a WITH_SIZE_EXPR. Note that we need to do this
5788 before gimplifying any of the operands so that we can resolve any
5789 PLACEHOLDER_EXPRs in the size. Also note that the RTL expander uses
5790 the size of the expression to be copied, not of the destination, so
5791 that is what we must do here. */
5792 maybe_with_size_expr (from_p
);
5794 /* As a special case, we have to temporarily allow for assignments
5795 with a CALL_EXPR on the RHS. Since in GIMPLE a function call is
5796 a toplevel statement, when gimplifying the GENERIC expression
5797 MODIFY_EXPR <a, CALL_EXPR <foo>>, we cannot create the tuple
5798 GIMPLE_ASSIGN <a, GIMPLE_CALL <foo>>.
5800 Instead, we need to create the tuple GIMPLE_CALL <a, foo>. To
5801 prevent gimplify_expr from trying to create a new temporary for
5802 foo's LHS, we tell it that it should only gimplify until it
5803 reaches the CALL_EXPR. On return from gimplify_expr, the newly
5804 created GIMPLE_CALL <foo> will be the last statement in *PRE_P
5805 and all we need to do here is set 'a' to be its LHS. */
5807 /* Gimplify the RHS first for C++17 and bug 71104. */
5808 gimple_predicate initial_pred
= initial_rhs_predicate_for (*to_p
);
5809 ret
= gimplify_expr (from_p
, pre_p
, post_p
, initial_pred
, fb_rvalue
);
5810 if (ret
== GS_ERROR
)
5813 /* Then gimplify the LHS. */
5814 /* If we gimplified the RHS to a CALL_EXPR and that call may return
5815 twice we have to make sure to gimplify into non-SSA as otherwise
5816 the abnormal edge added later will make those defs not dominate
5818 ??? Technically this applies only to the registers used in the
5819 resulting non-register *TO_P. */
5820 bool saved_into_ssa
= gimplify_ctxp
->into_ssa
;
5822 && TREE_CODE (*from_p
) == CALL_EXPR
5823 && call_expr_flags (*from_p
) & ECF_RETURNS_TWICE
)
5824 gimplify_ctxp
->into_ssa
= false;
5825 ret
= gimplify_expr (to_p
, pre_p
, post_p
, is_gimple_lvalue
, fb_lvalue
);
5826 gimplify_ctxp
->into_ssa
= saved_into_ssa
;
5827 if (ret
== GS_ERROR
)
5830 /* Now that the LHS is gimplified, re-gimplify the RHS if our initial
5831 guess for the predicate was wrong. */
5832 gimple_predicate final_pred
= rhs_predicate_for (*to_p
);
5833 if (final_pred
!= initial_pred
)
5835 ret
= gimplify_expr (from_p
, pre_p
, post_p
, final_pred
, fb_rvalue
);
5836 if (ret
== GS_ERROR
)
5840 /* In case of va_arg internal fn wrappped in a WITH_SIZE_EXPR, add the type
5841 size as argument to the call. */
5842 if (TREE_CODE (*from_p
) == WITH_SIZE_EXPR
)
5844 tree call
= TREE_OPERAND (*from_p
, 0);
5845 tree vlasize
= TREE_OPERAND (*from_p
, 1);
5847 if (TREE_CODE (call
) == CALL_EXPR
5848 && CALL_EXPR_IFN (call
) == IFN_VA_ARG
)
5850 int nargs
= call_expr_nargs (call
);
5851 tree type
= TREE_TYPE (call
);
5852 tree ap
= CALL_EXPR_ARG (call
, 0);
5853 tree tag
= CALL_EXPR_ARG (call
, 1);
5854 tree aptag
= CALL_EXPR_ARG (call
, 2);
5855 tree newcall
= build_call_expr_internal_loc (EXPR_LOCATION (call
),
5859 TREE_OPERAND (*from_p
, 0) = newcall
;
5863 /* Now see if the above changed *from_p to something we handle specially. */
5864 ret
= gimplify_modify_expr_rhs (expr_p
, from_p
, to_p
, pre_p
, post_p
,
5866 if (ret
!= GS_UNHANDLED
)
5869 /* If we've got a variable sized assignment between two lvalues (i.e. does
5870 not involve a call), then we can make things a bit more straightforward
5871 by converting the assignment to memcpy or memset. */
5872 if (TREE_CODE (*from_p
) == WITH_SIZE_EXPR
)
5874 tree from
= TREE_OPERAND (*from_p
, 0);
5875 tree size
= TREE_OPERAND (*from_p
, 1);
5877 if (TREE_CODE (from
) == CONSTRUCTOR
)
5878 return gimplify_modify_expr_to_memset (expr_p
, size
, want_value
, pre_p
);
5880 if (is_gimple_addressable (from
))
5883 return gimplify_modify_expr_to_memcpy (expr_p
, size
, want_value
,
5888 /* Transform partial stores to non-addressable complex variables into
5889 total stores. This allows us to use real instead of virtual operands
5890 for these variables, which improves optimization. */
5891 if ((TREE_CODE (*to_p
) == REALPART_EXPR
5892 || TREE_CODE (*to_p
) == IMAGPART_EXPR
)
5893 && is_gimple_reg (TREE_OPERAND (*to_p
, 0)))
5894 return gimplify_modify_expr_complex_part (expr_p
, pre_p
, want_value
);
5896 /* Try to alleviate the effects of the gimplification creating artificial
5897 temporaries (see for example is_gimple_reg_rhs) on the debug info, but
5898 make sure not to create DECL_DEBUG_EXPR links across functions. */
5899 if (!gimplify_ctxp
->into_ssa
5901 && DECL_IGNORED_P (*from_p
)
5903 && !DECL_IGNORED_P (*to_p
)
5904 && decl_function_context (*to_p
) == current_function_decl
5905 && decl_function_context (*from_p
) == current_function_decl
)
5907 if (!DECL_NAME (*from_p
) && DECL_NAME (*to_p
))
5909 = create_tmp_var_name (IDENTIFIER_POINTER (DECL_NAME (*to_p
)));
5910 DECL_HAS_DEBUG_EXPR_P (*from_p
) = 1;
5911 SET_DECL_DEBUG_EXPR (*from_p
, *to_p
);
5914 if (want_value
&& TREE_THIS_VOLATILE (*to_p
))
5915 *from_p
= get_initialized_tmp_var (*from_p
, pre_p
, post_p
);
5917 if (TREE_CODE (*from_p
) == CALL_EXPR
)
5919 /* Since the RHS is a CALL_EXPR, we need to create a GIMPLE_CALL
5920 instead of a GIMPLE_ASSIGN. */
5922 if (CALL_EXPR_FN (*from_p
) == NULL_TREE
)
5924 /* Gimplify internal functions created in the FEs. */
5925 int nargs
= call_expr_nargs (*from_p
), i
;
5926 enum internal_fn ifn
= CALL_EXPR_IFN (*from_p
);
5927 auto_vec
<tree
> vargs (nargs
);
5929 for (i
= 0; i
< nargs
; i
++)
5931 gimplify_arg (&CALL_EXPR_ARG (*from_p
, i
), pre_p
,
5932 EXPR_LOCATION (*from_p
));
5933 vargs
.quick_push (CALL_EXPR_ARG (*from_p
, i
));
5935 call_stmt
= gimple_build_call_internal_vec (ifn
, vargs
);
5936 gimple_call_set_nothrow (call_stmt
, TREE_NOTHROW (*from_p
));
5937 gimple_set_location (call_stmt
, EXPR_LOCATION (*expr_p
));
5941 tree fnptrtype
= TREE_TYPE (CALL_EXPR_FN (*from_p
));
5942 CALL_EXPR_FN (*from_p
) = TREE_OPERAND (CALL_EXPR_FN (*from_p
), 0);
5943 STRIP_USELESS_TYPE_CONVERSION (CALL_EXPR_FN (*from_p
));
5944 tree fndecl
= get_callee_fndecl (*from_p
);
5946 && fndecl_built_in_p (fndecl
, BUILT_IN_EXPECT
)
5947 && call_expr_nargs (*from_p
) == 3)
5948 call_stmt
= gimple_build_call_internal (IFN_BUILTIN_EXPECT
, 3,
5949 CALL_EXPR_ARG (*from_p
, 0),
5950 CALL_EXPR_ARG (*from_p
, 1),
5951 CALL_EXPR_ARG (*from_p
, 2));
5954 call_stmt
= gimple_build_call_from_tree (*from_p
, fnptrtype
);
5957 notice_special_calls (call_stmt
);
5958 if (!gimple_call_noreturn_p (call_stmt
) || !should_remove_lhs_p (*to_p
))
5959 gimple_call_set_lhs (call_stmt
, *to_p
);
5960 else if (TREE_CODE (*to_p
) == SSA_NAME
)
5961 /* The above is somewhat premature, avoid ICEing later for a
5962 SSA name w/o a definition. We may have uses in the GIMPLE IL.
5963 ??? This doesn't make it a default-def. */
5964 SSA_NAME_DEF_STMT (*to_p
) = gimple_build_nop ();
5970 assign
= gimple_build_assign (*to_p
, *from_p
);
5971 gimple_set_location (assign
, EXPR_LOCATION (*expr_p
));
5972 if (COMPARISON_CLASS_P (*from_p
))
5973 copy_warning (assign
, *from_p
);
5976 if (gimplify_ctxp
->into_ssa
&& is_gimple_reg (*to_p
))
5978 /* We should have got an SSA name from the start. */
5979 gcc_assert (TREE_CODE (*to_p
) == SSA_NAME
5980 || ! gimple_in_ssa_p (cfun
));
5983 gimplify_seq_add_stmt (pre_p
, assign
);
5984 gsi
= gsi_last (*pre_p
);
5985 maybe_fold_stmt (&gsi
);
5989 *expr_p
= TREE_THIS_VOLATILE (*to_p
) ? *from_p
: unshare_expr (*to_p
);
5998 /* Gimplify a comparison between two variable-sized objects. Do this
5999 with a call to BUILT_IN_MEMCMP. */
6001 static enum gimplify_status
6002 gimplify_variable_sized_compare (tree
*expr_p
)
6004 location_t loc
= EXPR_LOCATION (*expr_p
);
6005 tree op0
= TREE_OPERAND (*expr_p
, 0);
6006 tree op1
= TREE_OPERAND (*expr_p
, 1);
6007 tree t
, arg
, dest
, src
, expr
;
6009 arg
= TYPE_SIZE_UNIT (TREE_TYPE (op0
));
6010 arg
= unshare_expr (arg
);
6011 arg
= SUBSTITUTE_PLACEHOLDER_IN_EXPR (arg
, op0
);
6012 src
= build_fold_addr_expr_loc (loc
, op1
);
6013 dest
= build_fold_addr_expr_loc (loc
, op0
);
6014 t
= builtin_decl_implicit (BUILT_IN_MEMCMP
);
6015 t
= build_call_expr_loc (loc
, t
, 3, dest
, src
, arg
);
6018 = build2 (TREE_CODE (*expr_p
), TREE_TYPE (*expr_p
), t
, integer_zero_node
);
6019 SET_EXPR_LOCATION (expr
, loc
);
6025 /* Gimplify a comparison between two aggregate objects of integral scalar
6026 mode as a comparison between the bitwise equivalent scalar values. */
6028 static enum gimplify_status
6029 gimplify_scalar_mode_aggregate_compare (tree
*expr_p
)
6031 location_t loc
= EXPR_LOCATION (*expr_p
);
6032 tree op0
= TREE_OPERAND (*expr_p
, 0);
6033 tree op1
= TREE_OPERAND (*expr_p
, 1);
6035 tree type
= TREE_TYPE (op0
);
6036 tree scalar_type
= lang_hooks
.types
.type_for_mode (TYPE_MODE (type
), 1);
6038 op0
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, scalar_type
, op0
);
6039 op1
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, scalar_type
, op1
);
6042 = fold_build2_loc (loc
, TREE_CODE (*expr_p
), TREE_TYPE (*expr_p
), op0
, op1
);
6047 /* Gimplify an expression sequence. This function gimplifies each
6048 expression and rewrites the original expression with the last
6049 expression of the sequence in GIMPLE form.
6051 PRE_P points to the list where the side effects for all the
6052 expressions in the sequence will be emitted.
6054 WANT_VALUE is true when the result of the last COMPOUND_EXPR is used. */
6056 static enum gimplify_status
6057 gimplify_compound_expr (tree
*expr_p
, gimple_seq
*pre_p
, bool want_value
)
6063 tree
*sub_p
= &TREE_OPERAND (t
, 0);
6065 if (TREE_CODE (*sub_p
) == COMPOUND_EXPR
)
6066 gimplify_compound_expr (sub_p
, pre_p
, false);
6068 gimplify_stmt (sub_p
, pre_p
);
6070 t
= TREE_OPERAND (t
, 1);
6072 while (TREE_CODE (t
) == COMPOUND_EXPR
);
6079 gimplify_stmt (expr_p
, pre_p
);
6084 /* Gimplify a SAVE_EXPR node. EXPR_P points to the expression to
6085 gimplify. After gimplification, EXPR_P will point to a new temporary
6086 that holds the original value of the SAVE_EXPR node.
6088 PRE_P points to the list where side effects that must happen before
6089 *EXPR_P should be stored. */
6091 static enum gimplify_status
6092 gimplify_save_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
)
6094 enum gimplify_status ret
= GS_ALL_DONE
;
6097 gcc_assert (TREE_CODE (*expr_p
) == SAVE_EXPR
);
6098 val
= TREE_OPERAND (*expr_p
, 0);
6100 /* If the SAVE_EXPR has not been resolved, then evaluate it once. */
6101 if (!SAVE_EXPR_RESOLVED_P (*expr_p
))
6103 /* The operand may be a void-valued expression. It is
6104 being executed only for its side-effects. */
6105 if (TREE_TYPE (val
) == void_type_node
)
6107 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
6108 is_gimple_stmt
, fb_none
);
6112 /* The temporary may not be an SSA name as later abnormal and EH
6113 control flow may invalidate use/def domination. When in SSA
6114 form then assume there are no such issues and SAVE_EXPRs only
6115 appear via GENERIC foldings. */
6116 val
= get_initialized_tmp_var (val
, pre_p
, post_p
,
6117 gimple_in_ssa_p (cfun
));
6119 TREE_OPERAND (*expr_p
, 0) = val
;
6120 SAVE_EXPR_RESOLVED_P (*expr_p
) = 1;
6128 /* Rewrite the ADDR_EXPR node pointed to by EXPR_P
6135 PRE_P points to the list where side effects that must happen before
6136 *EXPR_P should be stored.
6138 POST_P points to the list where side effects that must happen after
6139 *EXPR_P should be stored. */
6141 static enum gimplify_status
6142 gimplify_addr_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
)
6144 tree expr
= *expr_p
;
6145 tree op0
= TREE_OPERAND (expr
, 0);
6146 enum gimplify_status ret
;
6147 location_t loc
= EXPR_LOCATION (*expr_p
);
6149 switch (TREE_CODE (op0
))
6153 /* Check if we are dealing with an expression of the form '&*ptr'.
6154 While the front end folds away '&*ptr' into 'ptr', these
6155 expressions may be generated internally by the compiler (e.g.,
6156 builtins like __builtin_va_end). */
6157 /* Caution: the silent array decomposition semantics we allow for
6158 ADDR_EXPR means we can't always discard the pair. */
6159 /* Gimplification of the ADDR_EXPR operand may drop
6160 cv-qualification conversions, so make sure we add them if
6163 tree op00
= TREE_OPERAND (op0
, 0);
6164 tree t_expr
= TREE_TYPE (expr
);
6165 tree t_op00
= TREE_TYPE (op00
);
6167 if (!useless_type_conversion_p (t_expr
, t_op00
))
6168 op00
= fold_convert_loc (loc
, TREE_TYPE (expr
), op00
);
6174 case VIEW_CONVERT_EXPR
:
6175 /* Take the address of our operand and then convert it to the type of
6178 ??? The interactions of VIEW_CONVERT_EXPR and aliasing is not at
6179 all clear. The impact of this transformation is even less clear. */
6181 /* If the operand is a useless conversion, look through it. Doing so
6182 guarantees that the ADDR_EXPR and its operand will remain of the
6184 if (tree_ssa_useless_type_conversion (TREE_OPERAND (op0
, 0)))
6185 op0
= TREE_OPERAND (op0
, 0);
6187 *expr_p
= fold_convert_loc (loc
, TREE_TYPE (expr
),
6188 build_fold_addr_expr_loc (loc
,
6189 TREE_OPERAND (op0
, 0)));
6194 if (integer_zerop (TREE_OPERAND (op0
, 1)))
6195 goto do_indirect_ref
;
6200 /* If we see a call to a declared builtin or see its address
6201 being taken (we can unify those cases here) then we can mark
6202 the builtin for implicit generation by GCC. */
6203 if (TREE_CODE (op0
) == FUNCTION_DECL
6204 && fndecl_built_in_p (op0
, BUILT_IN_NORMAL
)
6205 && builtin_decl_declared_p (DECL_FUNCTION_CODE (op0
)))
6206 set_builtin_decl_implicit_p (DECL_FUNCTION_CODE (op0
), true);
6208 /* We use fb_either here because the C frontend sometimes takes
6209 the address of a call that returns a struct; see
6210 gcc.dg/c99-array-lval-1.c. The gimplifier will correctly make
6211 the implied temporary explicit. */
6213 /* Make the operand addressable. */
6214 ret
= gimplify_expr (&TREE_OPERAND (expr
, 0), pre_p
, post_p
,
6215 is_gimple_addressable
, fb_either
);
6216 if (ret
== GS_ERROR
)
6219 /* Then mark it. Beware that it may not be possible to do so directly
6220 if a temporary has been created by the gimplification. */
6221 prepare_gimple_addressable (&TREE_OPERAND (expr
, 0), pre_p
);
6223 op0
= TREE_OPERAND (expr
, 0);
6225 /* For various reasons, the gimplification of the expression
6226 may have made a new INDIRECT_REF. */
6227 if (TREE_CODE (op0
) == INDIRECT_REF
6228 || (TREE_CODE (op0
) == MEM_REF
6229 && integer_zerop (TREE_OPERAND (op0
, 1))))
6230 goto do_indirect_ref
;
6232 mark_addressable (TREE_OPERAND (expr
, 0));
6234 /* The FEs may end up building ADDR_EXPRs early on a decl with
6235 an incomplete type. Re-build ADDR_EXPRs in canonical form
6237 if (!types_compatible_p (TREE_TYPE (op0
), TREE_TYPE (TREE_TYPE (expr
))))
6238 *expr_p
= build_fold_addr_expr (op0
);
6240 /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly. */
6241 recompute_tree_invariant_for_addr_expr (*expr_p
);
6243 /* If we re-built the ADDR_EXPR add a conversion to the original type
6245 if (!useless_type_conversion_p (TREE_TYPE (expr
), TREE_TYPE (*expr_p
)))
6246 *expr_p
= fold_convert (TREE_TYPE (expr
), *expr_p
);
6254 /* Gimplify the operands of an ASM_EXPR. Input operands should be a gimple
6255 value; output operands should be a gimple lvalue. */
6257 static enum gimplify_status
6258 gimplify_asm_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
)
6262 const char **oconstraints
;
6265 const char *constraint
;
6266 bool allows_mem
, allows_reg
, is_inout
;
6267 enum gimplify_status ret
, tret
;
6269 vec
<tree
, va_gc
> *inputs
;
6270 vec
<tree
, va_gc
> *outputs
;
6271 vec
<tree
, va_gc
> *clobbers
;
6272 vec
<tree
, va_gc
> *labels
;
6276 noutputs
= list_length (ASM_OUTPUTS (expr
));
6277 oconstraints
= (const char **) alloca ((noutputs
) * sizeof (const char *));
6285 link_next
= NULL_TREE
;
6286 for (i
= 0, link
= ASM_OUTPUTS (expr
); link
; ++i
, link
= link_next
)
6289 size_t constraint_len
;
6291 link_next
= TREE_CHAIN (link
);
6295 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link
)));
6296 constraint_len
= strlen (constraint
);
6297 if (constraint_len
== 0)
6300 ok
= parse_output_constraint (&constraint
, i
, 0, 0,
6301 &allows_mem
, &allows_reg
, &is_inout
);
6308 /* If we can't make copies, we can only accept memory.
6309 Similarly for VLAs. */
6310 tree outtype
= TREE_TYPE (TREE_VALUE (link
));
6311 if (outtype
!= error_mark_node
6312 && (TREE_ADDRESSABLE (outtype
)
6313 || !COMPLETE_TYPE_P (outtype
)
6314 || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (outtype
))))
6320 error ("impossible constraint in %<asm%>");
6321 error ("non-memory output %d must stay in memory", i
);
6326 if (!allows_reg
&& allows_mem
)
6327 mark_addressable (TREE_VALUE (link
));
6329 tree orig
= TREE_VALUE (link
);
6330 tret
= gimplify_expr (&TREE_VALUE (link
), pre_p
, post_p
,
6331 is_inout
? is_gimple_min_lval
: is_gimple_lvalue
,
6332 fb_lvalue
| fb_mayfail
);
6333 if (tret
== GS_ERROR
)
6335 if (orig
!= error_mark_node
)
6336 error ("invalid lvalue in %<asm%> output %d", i
);
6340 /* If the constraint does not allow memory make sure we gimplify
6341 it to a register if it is not already but its base is. This
6342 happens for complex and vector components. */
6345 tree op
= TREE_VALUE (link
);
6346 if (! is_gimple_val (op
)
6347 && is_gimple_reg_type (TREE_TYPE (op
))
6348 && is_gimple_reg (get_base_address (op
)))
6350 tree tem
= create_tmp_reg (TREE_TYPE (op
));
6354 ass
= build2 (MODIFY_EXPR
, TREE_TYPE (tem
),
6355 tem
, unshare_expr (op
));
6356 gimplify_and_add (ass
, pre_p
);
6358 ass
= build2 (MODIFY_EXPR
, TREE_TYPE (tem
), op
, tem
);
6359 gimplify_and_add (ass
, post_p
);
6361 TREE_VALUE (link
) = tem
;
6366 vec_safe_push (outputs
, link
);
6367 TREE_CHAIN (link
) = NULL_TREE
;
6371 /* An input/output operand. To give the optimizers more
6372 flexibility, split it into separate input and output
6375 /* Buffer big enough to format a 32-bit UINT_MAX into. */
6378 /* Turn the in/out constraint into an output constraint. */
6379 char *p
= xstrdup (constraint
);
6381 TREE_VALUE (TREE_PURPOSE (link
)) = build_string (constraint_len
, p
);
6383 /* And add a matching input constraint. */
6386 sprintf (buf
, "%u", i
);
6388 /* If there are multiple alternatives in the constraint,
6389 handle each of them individually. Those that allow register
6390 will be replaced with operand number, the others will stay
6392 if (strchr (p
, ',') != NULL
)
6394 size_t len
= 0, buflen
= strlen (buf
);
6395 char *beg
, *end
, *str
, *dst
;
6399 end
= strchr (beg
, ',');
6401 end
= strchr (beg
, '\0');
6402 if ((size_t) (end
- beg
) < buflen
)
6405 len
+= end
- beg
+ 1;
6412 str
= (char *) alloca (len
);
6413 for (beg
= p
+ 1, dst
= str
;;)
6416 bool mem_p
, reg_p
, inout_p
;
6418 end
= strchr (beg
, ',');
6423 parse_output_constraint (&tem
, i
, 0, 0,
6424 &mem_p
, ®_p
, &inout_p
);
6429 memcpy (dst
, buf
, buflen
);
6438 memcpy (dst
, beg
, len
);
6447 input
= build_string (dst
- str
, str
);
6450 input
= build_string (strlen (buf
), buf
);
6453 input
= build_string (constraint_len
- 1, constraint
+ 1);
6457 input
= build_tree_list (build_tree_list (NULL_TREE
, input
),
6458 unshare_expr (TREE_VALUE (link
)));
6459 ASM_INPUTS (expr
) = chainon (ASM_INPUTS (expr
), input
);
6463 link_next
= NULL_TREE
;
6464 for (link
= ASM_INPUTS (expr
); link
; ++i
, link
= link_next
)
6466 link_next
= TREE_CHAIN (link
);
6467 constraint
= TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link
)));
6468 parse_input_constraint (&constraint
, 0, 0, noutputs
, 0,
6469 oconstraints
, &allows_mem
, &allows_reg
);
6471 /* If we can't make copies, we can only accept memory. */
6472 tree intype
= TREE_TYPE (TREE_VALUE (link
));
6473 if (intype
!= error_mark_node
6474 && (TREE_ADDRESSABLE (intype
)
6475 || !COMPLETE_TYPE_P (intype
)
6476 || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (intype
))))
6482 error ("impossible constraint in %<asm%>");
6483 error ("non-memory input %d must stay in memory", i
);
6488 /* If the operand is a memory input, it should be an lvalue. */
6489 if (!allows_reg
&& allows_mem
)
6491 tree inputv
= TREE_VALUE (link
);
6492 STRIP_NOPS (inputv
);
6493 if (TREE_CODE (inputv
) == PREDECREMENT_EXPR
6494 || TREE_CODE (inputv
) == PREINCREMENT_EXPR
6495 || TREE_CODE (inputv
) == POSTDECREMENT_EXPR
6496 || TREE_CODE (inputv
) == POSTINCREMENT_EXPR
6497 || TREE_CODE (inputv
) == MODIFY_EXPR
)
6498 TREE_VALUE (link
) = error_mark_node
;
6499 tret
= gimplify_expr (&TREE_VALUE (link
), pre_p
, post_p
,
6500 is_gimple_lvalue
, fb_lvalue
| fb_mayfail
);
6501 if (tret
!= GS_ERROR
)
6503 /* Unlike output operands, memory inputs are not guaranteed
6504 to be lvalues by the FE, and while the expressions are
6505 marked addressable there, if it is e.g. a statement
6506 expression, temporaries in it might not end up being
6507 addressable. They might be already used in the IL and thus
6508 it is too late to make them addressable now though. */
6509 tree x
= TREE_VALUE (link
);
6510 while (handled_component_p (x
))
6511 x
= TREE_OPERAND (x
, 0);
6512 if (TREE_CODE (x
) == MEM_REF
6513 && TREE_CODE (TREE_OPERAND (x
, 0)) == ADDR_EXPR
)
6514 x
= TREE_OPERAND (TREE_OPERAND (x
, 0), 0);
6516 || TREE_CODE (x
) == PARM_DECL
6517 || TREE_CODE (x
) == RESULT_DECL
)
6518 && !TREE_ADDRESSABLE (x
)
6519 && is_gimple_reg (x
))
6521 warning_at (EXPR_LOC_OR_LOC (TREE_VALUE (link
),
6523 "memory input %d is not directly addressable",
6525 prepare_gimple_addressable (&TREE_VALUE (link
), pre_p
);
6528 mark_addressable (TREE_VALUE (link
));
6529 if (tret
== GS_ERROR
)
6531 if (inputv
!= error_mark_node
)
6532 error_at (EXPR_LOC_OR_LOC (TREE_VALUE (link
), input_location
),
6533 "memory input %d is not directly addressable", i
);
6539 tret
= gimplify_expr (&TREE_VALUE (link
), pre_p
, post_p
,
6540 is_gimple_asm_val
, fb_rvalue
);
6541 if (tret
== GS_ERROR
)
6545 TREE_CHAIN (link
) = NULL_TREE
;
6546 vec_safe_push (inputs
, link
);
6549 link_next
= NULL_TREE
;
6550 for (link
= ASM_CLOBBERS (expr
); link
; ++i
, link
= link_next
)
6552 link_next
= TREE_CHAIN (link
);
6553 TREE_CHAIN (link
) = NULL_TREE
;
6554 vec_safe_push (clobbers
, link
);
6557 link_next
= NULL_TREE
;
6558 for (link
= ASM_LABELS (expr
); link
; ++i
, link
= link_next
)
6560 link_next
= TREE_CHAIN (link
);
6561 TREE_CHAIN (link
) = NULL_TREE
;
6562 vec_safe_push (labels
, link
);
6565 /* Do not add ASMs with errors to the gimple IL stream. */
6566 if (ret
!= GS_ERROR
)
6568 stmt
= gimple_build_asm_vec (TREE_STRING_POINTER (ASM_STRING (expr
)),
6569 inputs
, outputs
, clobbers
, labels
);
6571 gimple_asm_set_volatile (stmt
, ASM_VOLATILE_P (expr
) || noutputs
== 0);
6572 gimple_asm_set_input (stmt
, ASM_INPUT_P (expr
));
6573 gimple_asm_set_inline (stmt
, ASM_INLINE_P (expr
));
6575 gimplify_seq_add_stmt (pre_p
, stmt
);
6581 /* Gimplify a CLEANUP_POINT_EXPR. Currently this works by adding
6582 GIMPLE_WITH_CLEANUP_EXPRs to the prequeue as we encounter cleanups while
6583 gimplifying the body, and converting them to TRY_FINALLY_EXPRs when we
6584 return to this function.
6586 FIXME should we complexify the prequeue handling instead? Or use flags
6587 for all the cleanups and let the optimizer tighten them up? The current
6588 code seems pretty fragile; it will break on a cleanup within any
6589 non-conditional nesting. But any such nesting would be broken, anyway;
6590 we can't write a TRY_FINALLY_EXPR that starts inside a nesting construct
6591 and continues out of it. We can do that at the RTL level, though, so
6592 having an optimizer to tighten up try/finally regions would be a Good
6595 static enum gimplify_status
6596 gimplify_cleanup_point_expr (tree
*expr_p
, gimple_seq
*pre_p
)
6598 gimple_stmt_iterator iter
;
6599 gimple_seq body_sequence
= NULL
;
6601 tree temp
= voidify_wrapper_expr (*expr_p
, NULL
);
6603 /* We only care about the number of conditions between the innermost
6604 CLEANUP_POINT_EXPR and the cleanup. So save and reset the count and
6605 any cleanups collected outside the CLEANUP_POINT_EXPR. */
6606 int old_conds
= gimplify_ctxp
->conditions
;
6607 gimple_seq old_cleanups
= gimplify_ctxp
->conditional_cleanups
;
6608 bool old_in_cleanup_point_expr
= gimplify_ctxp
->in_cleanup_point_expr
;
6609 gimplify_ctxp
->conditions
= 0;
6610 gimplify_ctxp
->conditional_cleanups
= NULL
;
6611 gimplify_ctxp
->in_cleanup_point_expr
= true;
6613 gimplify_stmt (&TREE_OPERAND (*expr_p
, 0), &body_sequence
);
6615 gimplify_ctxp
->conditions
= old_conds
;
6616 gimplify_ctxp
->conditional_cleanups
= old_cleanups
;
6617 gimplify_ctxp
->in_cleanup_point_expr
= old_in_cleanup_point_expr
;
6619 for (iter
= gsi_start (body_sequence
); !gsi_end_p (iter
); )
6621 gimple
*wce
= gsi_stmt (iter
);
6623 if (gimple_code (wce
) == GIMPLE_WITH_CLEANUP_EXPR
)
6625 if (gsi_one_before_end_p (iter
))
6627 /* Note that gsi_insert_seq_before and gsi_remove do not
6628 scan operands, unlike some other sequence mutators. */
6629 if (!gimple_wce_cleanup_eh_only (wce
))
6630 gsi_insert_seq_before_without_update (&iter
,
6631 gimple_wce_cleanup (wce
),
6633 gsi_remove (&iter
, true);
6640 enum gimple_try_flags kind
;
6642 if (gimple_wce_cleanup_eh_only (wce
))
6643 kind
= GIMPLE_TRY_CATCH
;
6645 kind
= GIMPLE_TRY_FINALLY
;
6646 seq
= gsi_split_seq_after (iter
);
6648 gtry
= gimple_build_try (seq
, gimple_wce_cleanup (wce
), kind
);
6649 /* Do not use gsi_replace here, as it may scan operands.
6650 We want to do a simple structural modification only. */
6651 gsi_set_stmt (&iter
, gtry
);
6652 iter
= gsi_start (gtry
->eval
);
6659 gimplify_seq_add_seq (pre_p
, body_sequence
);
6672 /* Insert a cleanup marker for gimplify_cleanup_point_expr. CLEANUP
6673 is the cleanup action required. EH_ONLY is true if the cleanup should
6674 only be executed if an exception is thrown, not on normal exit.
6675 If FORCE_UNCOND is true perform the cleanup unconditionally; this is
6676 only valid for clobbers. */
6679 gimple_push_cleanup (tree var
, tree cleanup
, bool eh_only
, gimple_seq
*pre_p
,
6680 bool force_uncond
= false)
6683 gimple_seq cleanup_stmts
= NULL
;
6685 /* Errors can result in improperly nested cleanups. Which results in
6686 confusion when trying to resolve the GIMPLE_WITH_CLEANUP_EXPR. */
6690 if (gimple_conditional_context ())
6692 /* If we're in a conditional context, this is more complex. We only
6693 want to run the cleanup if we actually ran the initialization that
6694 necessitates it, but we want to run it after the end of the
6695 conditional context. So we wrap the try/finally around the
6696 condition and use a flag to determine whether or not to actually
6697 run the destructor. Thus
6701 becomes (approximately)
6705 if (test) { A::A(temp); flag = 1; val = f(temp); }
6708 if (flag) A::~A(temp);
6714 gimplify_stmt (&cleanup
, &cleanup_stmts
);
6715 wce
= gimple_build_wce (cleanup_stmts
);
6716 gimplify_seq_add_stmt (&gimplify_ctxp
->conditional_cleanups
, wce
);
6720 tree flag
= create_tmp_var (boolean_type_node
, "cleanup");
6721 gassign
*ffalse
= gimple_build_assign (flag
, boolean_false_node
);
6722 gassign
*ftrue
= gimple_build_assign (flag
, boolean_true_node
);
6724 cleanup
= build3 (COND_EXPR
, void_type_node
, flag
, cleanup
, NULL
);
6725 gimplify_stmt (&cleanup
, &cleanup_stmts
);
6726 wce
= gimple_build_wce (cleanup_stmts
);
6728 gimplify_seq_add_stmt (&gimplify_ctxp
->conditional_cleanups
, ffalse
);
6729 gimplify_seq_add_stmt (&gimplify_ctxp
->conditional_cleanups
, wce
);
6730 gimplify_seq_add_stmt (pre_p
, ftrue
);
6732 /* Because of this manipulation, and the EH edges that jump
6733 threading cannot redirect, the temporary (VAR) will appear
6734 to be used uninitialized. Don't warn. */
6735 suppress_warning (var
, OPT_Wuninitialized
);
6740 gimplify_stmt (&cleanup
, &cleanup_stmts
);
6741 wce
= gimple_build_wce (cleanup_stmts
);
6742 gimple_wce_set_cleanup_eh_only (wce
, eh_only
);
6743 gimplify_seq_add_stmt (pre_p
, wce
);
6747 /* Gimplify a TARGET_EXPR which doesn't appear on the rhs of an INIT_EXPR. */
6749 static enum gimplify_status
6750 gimplify_target_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
)
6752 tree targ
= *expr_p
;
6753 tree temp
= TARGET_EXPR_SLOT (targ
);
6754 tree init
= TARGET_EXPR_INITIAL (targ
);
6755 enum gimplify_status ret
;
6757 bool unpoison_empty_seq
= false;
6758 gimple_stmt_iterator unpoison_it
;
6762 tree cleanup
= NULL_TREE
;
6764 /* TARGET_EXPR temps aren't part of the enclosing block, so add it
6765 to the temps list. Handle also variable length TARGET_EXPRs. */
6766 if (!poly_int_tree_p (DECL_SIZE (temp
)))
6768 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (temp
)))
6769 gimplify_type_sizes (TREE_TYPE (temp
), pre_p
);
6770 gimplify_vla_decl (temp
, pre_p
);
6774 /* Save location where we need to place unpoisoning. It's possible
6775 that a variable will be converted to needs_to_live_in_memory. */
6776 unpoison_it
= gsi_last (*pre_p
);
6777 unpoison_empty_seq
= gsi_end_p (unpoison_it
);
6779 gimple_add_tmp_var (temp
);
6782 /* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the
6783 expression is supposed to initialize the slot. */
6784 if (VOID_TYPE_P (TREE_TYPE (init
)))
6785 ret
= gimplify_expr (&init
, pre_p
, post_p
, is_gimple_stmt
, fb_none
);
6788 tree init_expr
= build2 (INIT_EXPR
, void_type_node
, temp
, init
);
6790 ret
= gimplify_expr (&init
, pre_p
, post_p
, is_gimple_stmt
, fb_none
);
6792 ggc_free (init_expr
);
6794 if (ret
== GS_ERROR
)
6796 /* PR c++/28266 Make sure this is expanded only once. */
6797 TARGET_EXPR_INITIAL (targ
) = NULL_TREE
;
6801 gimplify_and_add (init
, pre_p
);
6803 /* If needed, push the cleanup for the temp. */
6804 if (TARGET_EXPR_CLEANUP (targ
))
6806 if (CLEANUP_EH_ONLY (targ
))
6807 gimple_push_cleanup (temp
, TARGET_EXPR_CLEANUP (targ
),
6808 CLEANUP_EH_ONLY (targ
), pre_p
);
6810 cleanup
= TARGET_EXPR_CLEANUP (targ
);
6813 /* Add a clobber for the temporary going out of scope, like
6814 gimplify_bind_expr. */
6815 if (gimplify_ctxp
->in_cleanup_point_expr
6816 && needs_to_live_in_memory (temp
))
6818 if (flag_stack_reuse
== SR_ALL
)
6820 tree clobber
= build_clobber (TREE_TYPE (temp
));
6821 clobber
= build2 (MODIFY_EXPR
, TREE_TYPE (temp
), temp
, clobber
);
6822 gimple_push_cleanup (temp
, clobber
, false, pre_p
, true);
6824 if (asan_poisoned_variables
6825 && DECL_ALIGN (temp
) <= MAX_SUPPORTED_STACK_ALIGNMENT
6826 && !TREE_STATIC (temp
)
6827 && dbg_cnt (asan_use_after_scope
)
6828 && !gimplify_omp_ctxp
)
6830 tree asan_cleanup
= build_asan_poison_call_expr (temp
);
6833 if (unpoison_empty_seq
)
6834 unpoison_it
= gsi_start (*pre_p
);
6836 asan_poison_variable (temp
, false, &unpoison_it
,
6837 unpoison_empty_seq
);
6838 gimple_push_cleanup (temp
, asan_cleanup
, false, pre_p
);
6843 gimple_push_cleanup (temp
, cleanup
, false, pre_p
);
6845 /* Only expand this once. */
6846 TREE_OPERAND (targ
, 3) = init
;
6847 TARGET_EXPR_INITIAL (targ
) = NULL_TREE
;
6850 /* We should have expanded this before. */
6851 gcc_assert (DECL_SEEN_IN_BIND_EXPR_P (temp
));
6857 /* Gimplification of expression trees. */
6859 /* Gimplify an expression which appears at statement context. The
6860 corresponding GIMPLE statements are added to *SEQ_P. If *SEQ_P is
6861 NULL, a new sequence is allocated.
6863 Return true if we actually added a statement to the queue. */
6866 gimplify_stmt (tree
*stmt_p
, gimple_seq
*seq_p
)
6868 gimple_seq_node last
;
6870 last
= gimple_seq_last (*seq_p
);
6871 gimplify_expr (stmt_p
, seq_p
, NULL
, is_gimple_stmt
, fb_none
);
6872 return last
!= gimple_seq_last (*seq_p
);
6875 /* Add FIRSTPRIVATE entries for DECL in the OpenMP the surrounding parallels
6876 to CTX. If entries already exist, force them to be some flavor of private.
6877 If there is no enclosing parallel, do nothing. */
6880 omp_firstprivatize_variable (struct gimplify_omp_ctx
*ctx
, tree decl
)
6884 if (decl
== NULL
|| !DECL_P (decl
) || ctx
->region_type
== ORT_NONE
)
6889 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
)decl
);
6892 if (n
->value
& GOVD_SHARED
)
6893 n
->value
= GOVD_FIRSTPRIVATE
| (n
->value
& GOVD_SEEN
);
6894 else if (n
->value
& GOVD_MAP
)
6895 n
->value
|= GOVD_MAP_TO_ONLY
;
6899 else if ((ctx
->region_type
& ORT_TARGET
) != 0)
6901 if (ctx
->defaultmap
[GDMK_SCALAR
] & GOVD_FIRSTPRIVATE
)
6902 omp_add_variable (ctx
, decl
, GOVD_FIRSTPRIVATE
);
6904 omp_add_variable (ctx
, decl
, GOVD_MAP
| GOVD_MAP_TO_ONLY
);
6906 else if (ctx
->region_type
!= ORT_WORKSHARE
6907 && ctx
->region_type
!= ORT_TASKGROUP
6908 && ctx
->region_type
!= ORT_SIMD
6909 && ctx
->region_type
!= ORT_ACC
6910 && !(ctx
->region_type
& ORT_TARGET_DATA
))
6911 omp_add_variable (ctx
, decl
, GOVD_FIRSTPRIVATE
);
6913 ctx
= ctx
->outer_context
;
6918 /* Similarly for each of the type sizes of TYPE. */
6921 omp_firstprivatize_type_sizes (struct gimplify_omp_ctx
*ctx
, tree type
)
6923 if (type
== NULL
|| type
== error_mark_node
)
6925 type
= TYPE_MAIN_VARIANT (type
);
6927 if (ctx
->privatized_types
->add (type
))
6930 switch (TREE_CODE (type
))
6936 case FIXED_POINT_TYPE
:
6937 omp_firstprivatize_variable (ctx
, TYPE_MIN_VALUE (type
));
6938 omp_firstprivatize_variable (ctx
, TYPE_MAX_VALUE (type
));
6942 omp_firstprivatize_type_sizes (ctx
, TREE_TYPE (type
));
6943 omp_firstprivatize_type_sizes (ctx
, TYPE_DOMAIN (type
));
6948 case QUAL_UNION_TYPE
:
6951 for (field
= TYPE_FIELDS (type
); field
; field
= DECL_CHAIN (field
))
6952 if (TREE_CODE (field
) == FIELD_DECL
)
6954 omp_firstprivatize_variable (ctx
, DECL_FIELD_OFFSET (field
));
6955 omp_firstprivatize_type_sizes (ctx
, TREE_TYPE (field
));
6961 case REFERENCE_TYPE
:
6962 omp_firstprivatize_type_sizes (ctx
, TREE_TYPE (type
));
6969 omp_firstprivatize_variable (ctx
, TYPE_SIZE (type
));
6970 omp_firstprivatize_variable (ctx
, TYPE_SIZE_UNIT (type
));
6971 lang_hooks
.types
.omp_firstprivatize_type_sizes (ctx
, type
);
6974 /* Add an entry for DECL in the OMP context CTX with FLAGS. */
6977 omp_add_variable (struct gimplify_omp_ctx
*ctx
, tree decl
, unsigned int flags
)
6980 unsigned int nflags
;
6983 if (error_operand_p (decl
) || ctx
->region_type
== ORT_NONE
)
6986 /* Never elide decls whose type has TREE_ADDRESSABLE set. This means
6987 there are constructors involved somewhere. Exception is a shared clause,
6988 there is nothing privatized in that case. */
6989 if ((flags
& GOVD_SHARED
) == 0
6990 && (TREE_ADDRESSABLE (TREE_TYPE (decl
))
6991 || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl
))))
6994 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
)decl
);
6995 if (n
!= NULL
&& (n
->value
& GOVD_DATA_SHARE_CLASS
) != 0)
6997 /* We shouldn't be re-adding the decl with the same data
6999 gcc_assert ((n
->value
& GOVD_DATA_SHARE_CLASS
& flags
) == 0);
7000 nflags
= n
->value
| flags
;
7001 /* The only combination of data sharing classes we should see is
7002 FIRSTPRIVATE and LASTPRIVATE. However, OpenACC permits
7003 reduction variables to be used in data sharing clauses. */
7004 gcc_assert ((ctx
->region_type
& ORT_ACC
) != 0
7005 || ((nflags
& GOVD_DATA_SHARE_CLASS
)
7006 == (GOVD_FIRSTPRIVATE
| GOVD_LASTPRIVATE
))
7007 || (flags
& GOVD_DATA_SHARE_CLASS
) == 0);
7012 /* When adding a variable-sized variable, we have to handle all sorts
7013 of additional bits of data: the pointer replacement variable, and
7014 the parameters of the type. */
7015 if (DECL_SIZE (decl
) && TREE_CODE (DECL_SIZE (decl
)) != INTEGER_CST
)
7017 /* Add the pointer replacement variable as PRIVATE if the variable
7018 replacement is private, else FIRSTPRIVATE since we'll need the
7019 address of the original variable either for SHARED, or for the
7020 copy into or out of the context. */
7021 if (!(flags
& GOVD_LOCAL
) && ctx
->region_type
!= ORT_TASKGROUP
)
7023 if (flags
& GOVD_MAP
)
7024 nflags
= GOVD_MAP
| GOVD_MAP_TO_ONLY
| GOVD_EXPLICIT
;
7025 else if (flags
& GOVD_PRIVATE
)
7026 nflags
= GOVD_PRIVATE
;
7027 else if (((ctx
->region_type
& (ORT_TARGET
| ORT_TARGET_DATA
)) != 0
7028 && (flags
& GOVD_FIRSTPRIVATE
))
7029 || (ctx
->region_type
== ORT_TARGET_DATA
7030 && (flags
& GOVD_DATA_SHARE_CLASS
) == 0))
7031 nflags
= GOVD_PRIVATE
| GOVD_EXPLICIT
;
7033 nflags
= GOVD_FIRSTPRIVATE
;
7034 nflags
|= flags
& GOVD_SEEN
;
7035 t
= DECL_VALUE_EXPR (decl
);
7036 gcc_assert (TREE_CODE (t
) == INDIRECT_REF
);
7037 t
= TREE_OPERAND (t
, 0);
7038 gcc_assert (DECL_P (t
));
7039 omp_add_variable (ctx
, t
, nflags
);
7042 /* Add all of the variable and type parameters (which should have
7043 been gimplified to a formal temporary) as FIRSTPRIVATE. */
7044 omp_firstprivatize_variable (ctx
, DECL_SIZE_UNIT (decl
));
7045 omp_firstprivatize_variable (ctx
, DECL_SIZE (decl
));
7046 omp_firstprivatize_type_sizes (ctx
, TREE_TYPE (decl
));
7048 /* The variable-sized variable itself is never SHARED, only some form
7049 of PRIVATE. The sharing would take place via the pointer variable
7050 which we remapped above. */
7051 if (flags
& GOVD_SHARED
)
7052 flags
= GOVD_SHARED
| GOVD_DEBUG_PRIVATE
7053 | (flags
& (GOVD_SEEN
| GOVD_EXPLICIT
));
7055 /* We're going to make use of the TYPE_SIZE_UNIT at least in the
7056 alloca statement we generate for the variable, so make sure it
7057 is available. This isn't automatically needed for the SHARED
7058 case, since we won't be allocating local storage then.
7059 For local variables TYPE_SIZE_UNIT might not be gimplified yet,
7060 in this case omp_notice_variable will be called later
7061 on when it is gimplified. */
7062 else if (! (flags
& (GOVD_LOCAL
| GOVD_MAP
))
7063 && DECL_P (TYPE_SIZE_UNIT (TREE_TYPE (decl
))))
7064 omp_notice_variable (ctx
, TYPE_SIZE_UNIT (TREE_TYPE (decl
)), true);
7066 else if ((flags
& (GOVD_MAP
| GOVD_LOCAL
)) == 0
7067 && lang_hooks
.decls
.omp_privatize_by_reference (decl
))
7069 omp_firstprivatize_type_sizes (ctx
, TREE_TYPE (decl
));
7071 /* Similar to the direct variable sized case above, we'll need the
7072 size of references being privatized. */
7073 if ((flags
& GOVD_SHARED
) == 0)
7075 t
= TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl
)));
7076 if (t
&& DECL_P (t
))
7077 omp_notice_variable (ctx
, t
, true);
7084 splay_tree_insert (ctx
->variables
, (splay_tree_key
)decl
, flags
);
7086 /* For reductions clauses in OpenACC loop directives, by default create a
7087 copy clause on the enclosing parallel construct for carrying back the
7089 if (ctx
->region_type
== ORT_ACC
&& (flags
& GOVD_REDUCTION
))
7091 struct gimplify_omp_ctx
*outer_ctx
= ctx
->outer_context
;
7094 n
= splay_tree_lookup (outer_ctx
->variables
, (splay_tree_key
)decl
);
7097 /* Ignore local variables and explicitly declared clauses. */
7098 if (n
->value
& (GOVD_LOCAL
| GOVD_EXPLICIT
))
7100 else if (outer_ctx
->region_type
== ORT_ACC_KERNELS
)
7102 /* According to the OpenACC spec, such a reduction variable
7103 should already have a copy map on a kernels construct,
7104 verify that here. */
7105 gcc_assert (!(n
->value
& GOVD_FIRSTPRIVATE
)
7106 && (n
->value
& GOVD_MAP
));
7108 else if (outer_ctx
->region_type
== ORT_ACC_PARALLEL
)
7110 /* Remove firstprivate and make it a copy map. */
7111 n
->value
&= ~GOVD_FIRSTPRIVATE
;
7112 n
->value
|= GOVD_MAP
;
7115 else if (outer_ctx
->region_type
== ORT_ACC_PARALLEL
)
7117 splay_tree_insert (outer_ctx
->variables
, (splay_tree_key
)decl
,
7118 GOVD_MAP
| GOVD_SEEN
);
7121 outer_ctx
= outer_ctx
->outer_context
;
7126 /* Notice a threadprivate variable DECL used in OMP context CTX.
7127 This just prints out diagnostics about threadprivate variable uses
7128 in untied tasks. If DECL2 is non-NULL, prevent this warning
7129 on that variable. */
7132 omp_notice_threadprivate_variable (struct gimplify_omp_ctx
*ctx
, tree decl
,
7136 struct gimplify_omp_ctx
*octx
;
7138 for (octx
= ctx
; octx
; octx
= octx
->outer_context
)
7139 if ((octx
->region_type
& ORT_TARGET
) != 0
7140 || octx
->order_concurrent
)
7142 n
= splay_tree_lookup (octx
->variables
, (splay_tree_key
)decl
);
7145 if (octx
->order_concurrent
)
7147 error ("threadprivate variable %qE used in a region with"
7148 " %<order(concurrent)%> clause", DECL_NAME (decl
));
7149 inform (octx
->location
, "enclosing region");
7153 error ("threadprivate variable %qE used in target region",
7155 inform (octx
->location
, "enclosing target region");
7157 splay_tree_insert (octx
->variables
, (splay_tree_key
)decl
, 0);
7160 splay_tree_insert (octx
->variables
, (splay_tree_key
)decl2
, 0);
7163 if (ctx
->region_type
!= ORT_UNTIED_TASK
)
7165 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
)decl
);
7168 error ("threadprivate variable %qE used in untied task",
7170 inform (ctx
->location
, "enclosing task");
7171 splay_tree_insert (ctx
->variables
, (splay_tree_key
)decl
, 0);
7174 splay_tree_insert (ctx
->variables
, (splay_tree_key
)decl2
, 0);
7178 /* Return true if global var DECL is device resident. */
7181 device_resident_p (tree decl
)
7183 tree attr
= lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (decl
));
7188 for (tree t
= TREE_VALUE (attr
); t
; t
= TREE_PURPOSE (t
))
7190 tree c
= TREE_VALUE (t
);
7191 if (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_DEVICE_RESIDENT
)
7198 /* Return true if DECL has an ACC DECLARE attribute. */
7201 is_oacc_declared (tree decl
)
7203 tree t
= TREE_CODE (decl
) == MEM_REF
? TREE_OPERAND (decl
, 0) : decl
;
7204 tree declared
= lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (t
));
7205 return declared
!= NULL_TREE
;
7208 /* Determine outer default flags for DECL mentioned in an OMP region
7209 but not declared in an enclosing clause.
7211 ??? Some compiler-generated variables (like SAVE_EXPRs) could be
7212 remapped firstprivate instead of shared. To some extent this is
7213 addressed in omp_firstprivatize_type_sizes, but not
7217 omp_default_clause (struct gimplify_omp_ctx
*ctx
, tree decl
,
7218 bool in_code
, unsigned flags
)
7220 enum omp_clause_default_kind default_kind
= ctx
->default_kind
;
7221 enum omp_clause_default_kind kind
;
7223 kind
= lang_hooks
.decls
.omp_predetermined_sharing (decl
);
7224 if (ctx
->region_type
& ORT_TASK
)
7226 tree detach_clause
= omp_find_clause (ctx
->clauses
, OMP_CLAUSE_DETACH
);
7228 /* The event-handle specified by a detach clause should always be firstprivate,
7229 regardless of the current default. */
7230 if (detach_clause
&& OMP_CLAUSE_DECL (detach_clause
) == decl
)
7231 kind
= OMP_CLAUSE_DEFAULT_FIRSTPRIVATE
;
7233 if (kind
!= OMP_CLAUSE_DEFAULT_UNSPECIFIED
)
7234 default_kind
= kind
;
7235 else if (VAR_P (decl
) && TREE_STATIC (decl
) && DECL_IN_CONSTANT_POOL (decl
))
7236 default_kind
= OMP_CLAUSE_DEFAULT_SHARED
;
7238 switch (default_kind
)
7240 case OMP_CLAUSE_DEFAULT_NONE
:
7244 if (ctx
->region_type
& ORT_PARALLEL
)
7246 else if ((ctx
->region_type
& ORT_TASKLOOP
) == ORT_TASKLOOP
)
7248 else if (ctx
->region_type
& ORT_TASK
)
7250 else if (ctx
->region_type
& ORT_TEAMS
)
7255 error ("%qE not specified in enclosing %qs",
7256 DECL_NAME (lang_hooks
.decls
.omp_report_decl (decl
)), rtype
);
7257 inform (ctx
->location
, "enclosing %qs", rtype
);
7260 case OMP_CLAUSE_DEFAULT_SHARED
:
7261 flags
|= GOVD_SHARED
;
7263 case OMP_CLAUSE_DEFAULT_PRIVATE
:
7264 flags
|= GOVD_PRIVATE
;
7266 case OMP_CLAUSE_DEFAULT_FIRSTPRIVATE
:
7267 flags
|= GOVD_FIRSTPRIVATE
;
7269 case OMP_CLAUSE_DEFAULT_UNSPECIFIED
:
7270 /* decl will be either GOVD_FIRSTPRIVATE or GOVD_SHARED. */
7271 gcc_assert ((ctx
->region_type
& ORT_TASK
) != 0);
7272 if (struct gimplify_omp_ctx
*octx
= ctx
->outer_context
)
7274 omp_notice_variable (octx
, decl
, in_code
);
7275 for (; octx
; octx
= octx
->outer_context
)
7279 n2
= splay_tree_lookup (octx
->variables
, (splay_tree_key
) decl
);
7280 if ((octx
->region_type
& (ORT_TARGET_DATA
| ORT_TARGET
)) != 0
7281 && (n2
== NULL
|| (n2
->value
& GOVD_DATA_SHARE_CLASS
) == 0))
7283 if (n2
&& (n2
->value
& GOVD_DATA_SHARE_CLASS
) != GOVD_SHARED
)
7285 flags
|= GOVD_FIRSTPRIVATE
;
7288 if ((octx
->region_type
& (ORT_PARALLEL
| ORT_TEAMS
)) != 0)
7290 flags
|= GOVD_SHARED
;
7296 if (TREE_CODE (decl
) == PARM_DECL
7297 || (!is_global_var (decl
)
7298 && DECL_CONTEXT (decl
) == current_function_decl
))
7299 flags
|= GOVD_FIRSTPRIVATE
;
7301 flags
|= GOVD_SHARED
;
7313 /* Determine outer default flags for DECL mentioned in an OACC region
7314 but not declared in an enclosing clause. */
7317 oacc_default_clause (struct gimplify_omp_ctx
*ctx
, tree decl
, unsigned flags
)
7320 bool on_device
= false;
7321 bool is_private
= false;
7322 bool declared
= is_oacc_declared (decl
);
7323 tree type
= TREE_TYPE (decl
);
7325 if (lang_hooks
.decls
.omp_privatize_by_reference (decl
))
7326 type
= TREE_TYPE (type
);
7328 /* For Fortran COMMON blocks, only used variables in those blocks are
7329 transfered and remapped. The block itself will have a private clause to
7330 avoid transfering the data twice.
7331 The hook evaluates to false by default. For a variable in Fortran's COMMON
7332 or EQUIVALENCE block, returns 'true' (as we have shared=false) - as only
7333 the variables in such a COMMON/EQUIVALENCE block shall be privatized not
7334 the whole block. For C++ and Fortran, it can also be true under certain
7335 other conditions, if DECL_HAS_VALUE_EXPR. */
7336 if (RECORD_OR_UNION_TYPE_P (type
))
7337 is_private
= lang_hooks
.decls
.omp_disregard_value_expr (decl
, false);
7339 if ((ctx
->region_type
& (ORT_ACC_PARALLEL
| ORT_ACC_KERNELS
)) != 0
7340 && is_global_var (decl
)
7341 && device_resident_p (decl
)
7345 flags
|= GOVD_MAP_TO_ONLY
;
7348 switch (ctx
->region_type
)
7350 case ORT_ACC_KERNELS
:
7354 flags
|= GOVD_FIRSTPRIVATE
;
7355 else if (AGGREGATE_TYPE_P (type
))
7357 /* Aggregates default to 'present_or_copy', or 'present'. */
7358 if (ctx
->default_kind
!= OMP_CLAUSE_DEFAULT_PRESENT
)
7361 flags
|= GOVD_MAP
| GOVD_MAP_FORCE_PRESENT
;
7364 /* Scalars default to 'copy'. */
7365 flags
|= GOVD_MAP
| GOVD_MAP_FORCE
;
7369 case ORT_ACC_PARALLEL
:
7370 case ORT_ACC_SERIAL
:
7371 rkind
= ctx
->region_type
== ORT_ACC_PARALLEL
? "parallel" : "serial";
7374 flags
|= GOVD_FIRSTPRIVATE
;
7375 else if (on_device
|| declared
)
7377 else if (AGGREGATE_TYPE_P (type
))
7379 /* Aggregates default to 'present_or_copy', or 'present'. */
7380 if (ctx
->default_kind
!= OMP_CLAUSE_DEFAULT_PRESENT
)
7383 flags
|= GOVD_MAP
| GOVD_MAP_FORCE_PRESENT
;
7386 /* Scalars default to 'firstprivate'. */
7387 flags
|= GOVD_FIRSTPRIVATE
;
7395 if (DECL_ARTIFICIAL (decl
))
7396 ; /* We can get compiler-generated decls, and should not complain
7398 else if (ctx
->default_kind
== OMP_CLAUSE_DEFAULT_NONE
)
7400 error ("%qE not specified in enclosing OpenACC %qs construct",
7401 DECL_NAME (lang_hooks
.decls
.omp_report_decl (decl
)), rkind
);
7402 inform (ctx
->location
, "enclosing OpenACC %qs construct", rkind
);
7404 else if (ctx
->default_kind
== OMP_CLAUSE_DEFAULT_PRESENT
)
7405 ; /* Handled above. */
7407 gcc_checking_assert (ctx
->default_kind
== OMP_CLAUSE_DEFAULT_SHARED
);
7412 /* Record the fact that DECL was used within the OMP context CTX.
7413 IN_CODE is true when real code uses DECL, and false when we should
7414 merely emit default(none) errors. Return true if DECL is going to
7415 be remapped and thus DECL shouldn't be gimplified into its
7416 DECL_VALUE_EXPR (if any). */
7419 omp_notice_variable (struct gimplify_omp_ctx
*ctx
, tree decl
, bool in_code
)
7422 unsigned flags
= in_code
? GOVD_SEEN
: 0;
7423 bool ret
= false, shared
;
7425 if (error_operand_p (decl
))
7428 if (ctx
->region_type
== ORT_NONE
)
7429 return lang_hooks
.decls
.omp_disregard_value_expr (decl
, false);
7431 if (is_global_var (decl
))
7433 /* Threadprivate variables are predetermined. */
7434 if (DECL_THREAD_LOCAL_P (decl
))
7435 return omp_notice_threadprivate_variable (ctx
, decl
, NULL_TREE
);
7437 if (DECL_HAS_VALUE_EXPR_P (decl
))
7439 if (ctx
->region_type
& ORT_ACC
)
7440 /* For OpenACC, defer expansion of value to avoid transfering
7441 privatized common block data instead of im-/explicitly transfered
7442 variables which are in common blocks. */
7446 tree value
= get_base_address (DECL_VALUE_EXPR (decl
));
7448 if (value
&& DECL_P (value
) && DECL_THREAD_LOCAL_P (value
))
7449 return omp_notice_threadprivate_variable (ctx
, decl
, value
);
7453 if (gimplify_omp_ctxp
->outer_context
== NULL
7455 && oacc_get_fn_attrib (current_function_decl
))
7457 location_t loc
= DECL_SOURCE_LOCATION (decl
);
7459 if (lookup_attribute ("omp declare target link",
7460 DECL_ATTRIBUTES (decl
)))
7463 "%qE with %<link%> clause used in %<routine%> function",
7467 else if (!lookup_attribute ("omp declare target",
7468 DECL_ATTRIBUTES (decl
)))
7471 "%qE requires a %<declare%> directive for use "
7472 "in a %<routine%> function", DECL_NAME (decl
));
7478 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
)decl
);
7479 if ((ctx
->region_type
& ORT_TARGET
) != 0)
7481 if (ctx
->region_type
& ORT_ACC
)
7482 /* For OpenACC, as remarked above, defer expansion. */
7487 ret
= lang_hooks
.decls
.omp_disregard_value_expr (decl
, shared
);
7490 unsigned nflags
= flags
;
7491 if ((ctx
->region_type
& ORT_ACC
) == 0)
7493 bool is_declare_target
= false;
7494 if (is_global_var (decl
)
7495 && varpool_node::get_create (decl
)->offloadable
)
7497 struct gimplify_omp_ctx
*octx
;
7498 for (octx
= ctx
->outer_context
;
7499 octx
; octx
= octx
->outer_context
)
7501 n
= splay_tree_lookup (octx
->variables
,
7502 (splay_tree_key
)decl
);
7504 && (n
->value
& GOVD_DATA_SHARE_CLASS
) != GOVD_SHARED
7505 && (n
->value
& GOVD_DATA_SHARE_CLASS
) != 0)
7508 is_declare_target
= octx
== NULL
;
7510 if (!is_declare_target
)
7513 enum omp_clause_defaultmap_kind kind
;
7514 if (lang_hooks
.decls
.omp_allocatable_p (decl
))
7515 gdmk
= GDMK_ALLOCATABLE
;
7516 else if (lang_hooks
.decls
.omp_scalar_target_p (decl
))
7517 gdmk
= GDMK_SCALAR_TARGET
;
7518 else if (lang_hooks
.decls
.omp_scalar_p (decl
, false))
7520 else if (TREE_CODE (TREE_TYPE (decl
)) == POINTER_TYPE
7521 || (TREE_CODE (TREE_TYPE (decl
)) == REFERENCE_TYPE
7522 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl
)))
7524 gdmk
= GDMK_POINTER
;
7526 gdmk
= GDMK_AGGREGATE
;
7527 kind
= lang_hooks
.decls
.omp_predetermined_mapping (decl
);
7528 if (kind
!= OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
)
7530 if (kind
== OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE
)
7531 nflags
|= GOVD_FIRSTPRIVATE
;
7532 else if (kind
== OMP_CLAUSE_DEFAULTMAP_TO
)
7533 nflags
|= GOVD_MAP
| GOVD_MAP_TO_ONLY
;
7537 else if (ctx
->defaultmap
[gdmk
] == 0)
7539 tree d
= lang_hooks
.decls
.omp_report_decl (decl
);
7540 error ("%qE not specified in enclosing %<target%>",
7542 inform (ctx
->location
, "enclosing %<target%>");
7544 else if (ctx
->defaultmap
[gdmk
]
7545 & (GOVD_MAP_0LEN_ARRAY
| GOVD_FIRSTPRIVATE
))
7546 nflags
|= ctx
->defaultmap
[gdmk
];
7549 gcc_assert (ctx
->defaultmap
[gdmk
] & GOVD_MAP
);
7550 nflags
|= ctx
->defaultmap
[gdmk
] & ~GOVD_MAP
;
7555 struct gimplify_omp_ctx
*octx
= ctx
->outer_context
;
7556 if ((ctx
->region_type
& ORT_ACC
) && octx
)
7558 /* Look in outer OpenACC contexts, to see if there's a
7559 data attribute for this variable. */
7560 omp_notice_variable (octx
, decl
, in_code
);
7562 for (; octx
; octx
= octx
->outer_context
)
7564 if (!(octx
->region_type
& (ORT_TARGET_DATA
| ORT_TARGET
)))
7567 = splay_tree_lookup (octx
->variables
,
7568 (splay_tree_key
) decl
);
7571 if (octx
->region_type
== ORT_ACC_HOST_DATA
)
7572 error ("variable %qE declared in enclosing "
7573 "%<host_data%> region", DECL_NAME (decl
));
7575 if (octx
->region_type
== ORT_ACC_DATA
7576 && (n2
->value
& GOVD_MAP_0LEN_ARRAY
))
7577 nflags
|= GOVD_MAP_0LEN_ARRAY
;
7583 if ((nflags
& ~(GOVD_MAP_TO_ONLY
| GOVD_MAP_FROM_ONLY
7584 | GOVD_MAP_ALLOC_ONLY
)) == flags
)
7586 tree type
= TREE_TYPE (decl
);
7588 if (gimplify_omp_ctxp
->target_firstprivatize_array_bases
7589 && lang_hooks
.decls
.omp_privatize_by_reference (decl
))
7590 type
= TREE_TYPE (type
);
7591 if (!lang_hooks
.types
.omp_mappable_type (type
))
7593 error ("%qD referenced in target region does not have "
7594 "a mappable type", decl
);
7595 nflags
|= GOVD_MAP
| GOVD_EXPLICIT
;
7599 if ((ctx
->region_type
& ORT_ACC
) != 0)
7600 nflags
= oacc_default_clause (ctx
, decl
, flags
);
7606 omp_add_variable (ctx
, decl
, nflags
);
7610 /* If nothing changed, there's nothing left to do. */
7611 if ((n
->value
& flags
) == flags
)
7621 if (ctx
->region_type
== ORT_WORKSHARE
7622 || ctx
->region_type
== ORT_TASKGROUP
7623 || ctx
->region_type
== ORT_SIMD
7624 || ctx
->region_type
== ORT_ACC
7625 || (ctx
->region_type
& ORT_TARGET_DATA
) != 0)
7628 flags
= omp_default_clause (ctx
, decl
, in_code
, flags
);
7630 if ((flags
& GOVD_PRIVATE
)
7631 && lang_hooks
.decls
.omp_private_outer_ref (decl
))
7632 flags
|= GOVD_PRIVATE_OUTER_REF
;
7634 omp_add_variable (ctx
, decl
, flags
);
7636 shared
= (flags
& GOVD_SHARED
) != 0;
7637 ret
= lang_hooks
.decls
.omp_disregard_value_expr (decl
, shared
);
7641 /* Don't mark as GOVD_SEEN addressable temporaries seen only in simd
7642 lb, b or incr expressions, those shouldn't be turned into simd arrays. */
7643 if (ctx
->region_type
== ORT_SIMD
7644 && ctx
->in_for_exprs
7645 && ((n
->value
& (GOVD_PRIVATE
| GOVD_SEEN
| GOVD_EXPLICIT
))
7647 flags
&= ~GOVD_SEEN
;
7649 if ((n
->value
& (GOVD_SEEN
| GOVD_LOCAL
)) == 0
7650 && (flags
& (GOVD_SEEN
| GOVD_LOCAL
)) == GOVD_SEEN
7651 && DECL_SIZE (decl
))
7653 if (TREE_CODE (DECL_SIZE (decl
)) != INTEGER_CST
)
7656 tree t
= DECL_VALUE_EXPR (decl
);
7657 gcc_assert (TREE_CODE (t
) == INDIRECT_REF
);
7658 t
= TREE_OPERAND (t
, 0);
7659 gcc_assert (DECL_P (t
));
7660 n2
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) t
);
7661 n2
->value
|= GOVD_SEEN
;
7663 else if (lang_hooks
.decls
.omp_privatize_by_reference (decl
)
7664 && TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl
)))
7665 && (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl
))))
7669 tree t
= TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl
)));
7670 gcc_assert (DECL_P (t
));
7671 n2
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) t
);
7673 omp_notice_variable (ctx
, t
, true);
7677 if (ctx
->region_type
& ORT_ACC
)
7678 /* For OpenACC, as remarked above, defer expansion. */
7681 shared
= ((flags
| n
->value
) & GOVD_SHARED
) != 0;
7682 ret
= lang_hooks
.decls
.omp_disregard_value_expr (decl
, shared
);
7684 /* If nothing changed, there's nothing left to do. */
7685 if ((n
->value
& flags
) == flags
)
7691 /* If the variable is private in the current context, then we don't
7692 need to propagate anything to an outer context. */
7693 if ((flags
& GOVD_PRIVATE
) && !(flags
& GOVD_PRIVATE_OUTER_REF
))
7695 if ((flags
& (GOVD_LINEAR
| GOVD_LINEAR_LASTPRIVATE_NO_OUTER
))
7696 == (GOVD_LINEAR
| GOVD_LINEAR_LASTPRIVATE_NO_OUTER
))
7698 if ((flags
& (GOVD_FIRSTPRIVATE
| GOVD_LASTPRIVATE
7699 | GOVD_LINEAR_LASTPRIVATE_NO_OUTER
))
7700 == (GOVD_LASTPRIVATE
| GOVD_LINEAR_LASTPRIVATE_NO_OUTER
))
7702 if (ctx
->outer_context
7703 && omp_notice_variable (ctx
->outer_context
, decl
, in_code
))
7708 /* Verify that DECL is private within CTX. If there's specific information
7709 to the contrary in the innermost scope, generate an error. */
7712 omp_is_private (struct gimplify_omp_ctx
*ctx
, tree decl
, int simd
)
7716 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
)decl
);
7719 if (n
->value
& GOVD_SHARED
)
7721 if (ctx
== gimplify_omp_ctxp
)
7724 error ("iteration variable %qE is predetermined linear",
7727 error ("iteration variable %qE should be private",
7729 n
->value
= GOVD_PRIVATE
;
7735 else if ((n
->value
& GOVD_EXPLICIT
) != 0
7736 && (ctx
== gimplify_omp_ctxp
7737 || (ctx
->region_type
== ORT_COMBINED_PARALLEL
7738 && gimplify_omp_ctxp
->outer_context
== ctx
)))
7740 if ((n
->value
& GOVD_FIRSTPRIVATE
) != 0)
7741 error ("iteration variable %qE should not be firstprivate",
7743 else if ((n
->value
& GOVD_REDUCTION
) != 0)
7744 error ("iteration variable %qE should not be reduction",
7746 else if (simd
!= 1 && (n
->value
& GOVD_LINEAR
) != 0)
7747 error ("iteration variable %qE should not be linear",
7750 return (ctx
== gimplify_omp_ctxp
7751 || (ctx
->region_type
== ORT_COMBINED_PARALLEL
7752 && gimplify_omp_ctxp
->outer_context
== ctx
));
7755 if (ctx
->region_type
!= ORT_WORKSHARE
7756 && ctx
->region_type
!= ORT_TASKGROUP
7757 && ctx
->region_type
!= ORT_SIMD
7758 && ctx
->region_type
!= ORT_ACC
)
7760 else if (ctx
->outer_context
)
7761 return omp_is_private (ctx
->outer_context
, decl
, simd
);
7765 /* Return true if DECL is private within a parallel region
7766 that binds to the current construct's context or in parallel
7767 region's REDUCTION clause. */
7770 omp_check_private (struct gimplify_omp_ctx
*ctx
, tree decl
, bool copyprivate
)
7776 ctx
= ctx
->outer_context
;
7779 if (is_global_var (decl
))
7782 /* References might be private, but might be shared too,
7783 when checking for copyprivate, assume they might be
7784 private, otherwise assume they might be shared. */
7788 if (lang_hooks
.decls
.omp_privatize_by_reference (decl
))
7791 /* Treat C++ privatized non-static data members outside
7792 of the privatization the same. */
7793 if (omp_member_access_dummy_var (decl
))
7799 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
7801 if ((ctx
->region_type
& (ORT_TARGET
| ORT_TARGET_DATA
)) != 0
7802 && (n
== NULL
|| (n
->value
& GOVD_DATA_SHARE_CLASS
) == 0))
7804 if ((ctx
->region_type
& ORT_TARGET_DATA
) != 0
7806 || (n
->value
& GOVD_MAP
) == 0)
7813 if ((n
->value
& GOVD_LOCAL
) != 0
7814 && omp_member_access_dummy_var (decl
))
7816 return (n
->value
& GOVD_SHARED
) == 0;
7819 if (ctx
->region_type
== ORT_WORKSHARE
7820 || ctx
->region_type
== ORT_TASKGROUP
7821 || ctx
->region_type
== ORT_SIMD
7822 || ctx
->region_type
== ORT_ACC
)
7831 /* Callback for walk_tree to find a DECL_EXPR for the given DECL. */
7834 find_decl_expr (tree
*tp
, int *walk_subtrees
, void *data
)
7838 /* If this node has been visited, unmark it and keep looking. */
7839 if (TREE_CODE (t
) == DECL_EXPR
&& DECL_EXPR_DECL (t
) == (tree
) data
)
7842 if (IS_TYPE_OR_DECL_P (t
))
7848 /* Gimplify the affinity clause but effectively ignore it.
7851 if ((step > 1) ? var <= end : var > end)
7852 locatator_var_expr; */
7855 gimplify_omp_affinity (tree
*list_p
, gimple_seq
*pre_p
)
7857 tree last_iter
= NULL_TREE
;
7858 tree last_bind
= NULL_TREE
;
7859 tree label
= NULL_TREE
;
7860 tree
*last_body
= NULL
;
7861 for (tree c
= *list_p
; c
; c
= OMP_CLAUSE_CHAIN (c
))
7862 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_AFFINITY
)
7864 tree t
= OMP_CLAUSE_DECL (c
);
7865 if (TREE_CODE (t
) == TREE_LIST
7867 && TREE_CODE (TREE_PURPOSE (t
)) == TREE_VEC
)
7869 if (TREE_VALUE (t
) == null_pointer_node
)
7871 if (TREE_PURPOSE (t
) != last_iter
)
7875 append_to_statement_list (label
, last_body
);
7876 gimplify_and_add (last_bind
, pre_p
);
7877 last_bind
= NULL_TREE
;
7879 for (tree it
= TREE_PURPOSE (t
); it
; it
= TREE_CHAIN (it
))
7881 if (gimplify_expr (&TREE_VEC_ELT (it
, 1), pre_p
, NULL
,
7882 is_gimple_val
, fb_rvalue
) == GS_ERROR
7883 || gimplify_expr (&TREE_VEC_ELT (it
, 2), pre_p
, NULL
,
7884 is_gimple_val
, fb_rvalue
) == GS_ERROR
7885 || gimplify_expr (&TREE_VEC_ELT (it
, 3), pre_p
, NULL
,
7886 is_gimple_val
, fb_rvalue
) == GS_ERROR
7887 || (gimplify_expr (&TREE_VEC_ELT (it
, 4), pre_p
, NULL
,
7888 is_gimple_val
, fb_rvalue
)
7892 last_iter
= TREE_PURPOSE (t
);
7893 tree block
= TREE_VEC_ELT (TREE_PURPOSE (t
), 5);
7894 last_bind
= build3 (BIND_EXPR
, void_type_node
, BLOCK_VARS (block
),
7896 last_body
= &BIND_EXPR_BODY (last_bind
);
7897 tree cond
= NULL_TREE
;
7898 location_t loc
= OMP_CLAUSE_LOCATION (c
);
7899 for (tree it
= TREE_PURPOSE (t
); it
; it
= TREE_CHAIN (it
))
7901 tree var
= TREE_VEC_ELT (it
, 0);
7902 tree begin
= TREE_VEC_ELT (it
, 1);
7903 tree end
= TREE_VEC_ELT (it
, 2);
7904 tree step
= TREE_VEC_ELT (it
, 3);
7905 loc
= DECL_SOURCE_LOCATION (var
);
7906 tree tem
= build2_loc (loc
, MODIFY_EXPR
, void_type_node
,
7908 append_to_statement_list_force (tem
, last_body
);
7910 tree cond1
= fold_build2_loc (loc
, GT_EXPR
, boolean_type_node
,
7911 step
, build_zero_cst (TREE_TYPE (step
)));
7912 tree cond2
= fold_build2_loc (loc
, LE_EXPR
, boolean_type_node
,
7914 tree cond3
= fold_build2_loc (loc
, GT_EXPR
, boolean_type_node
,
7916 cond1
= fold_build3_loc (loc
, COND_EXPR
, boolean_type_node
,
7917 cond1
, cond2
, cond3
);
7919 cond
= fold_build2_loc (loc
, TRUTH_AND_EXPR
,
7920 boolean_type_node
, cond
, cond1
);
7924 tree cont_label
= create_artificial_label (loc
);
7925 label
= build1 (LABEL_EXPR
, void_type_node
, cont_label
);
7926 tree tem
= fold_build3_loc (loc
, COND_EXPR
, void_type_node
, cond
,
7928 build_and_jump (&cont_label
));
7929 append_to_statement_list_force (tem
, last_body
);
7931 if (TREE_CODE (TREE_VALUE (t
)) == COMPOUND_EXPR
)
7933 append_to_statement_list (TREE_OPERAND (TREE_VALUE (t
), 0),
7935 TREE_VALUE (t
) = TREE_OPERAND (TREE_VALUE (t
), 1);
7937 if (error_operand_p (TREE_VALUE (t
)))
7939 append_to_statement_list_force (TREE_VALUE (t
), last_body
);
7940 TREE_VALUE (t
) = null_pointer_node
;
7946 append_to_statement_list (label
, last_body
);
7947 gimplify_and_add (last_bind
, pre_p
);
7948 last_bind
= NULL_TREE
;
7950 if (TREE_CODE (OMP_CLAUSE_DECL (c
)) == COMPOUND_EXPR
)
7952 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c
), 0), pre_p
,
7953 NULL
, is_gimple_val
, fb_rvalue
);
7954 OMP_CLAUSE_DECL (c
) = TREE_OPERAND (OMP_CLAUSE_DECL (c
), 1);
7956 if (error_operand_p (OMP_CLAUSE_DECL (c
)))
7958 if (gimplify_expr (&OMP_CLAUSE_DECL (c
), pre_p
, NULL
,
7959 is_gimple_val
, fb_rvalue
) == GS_ERROR
)
7961 gimplify_and_add (OMP_CLAUSE_DECL (c
), pre_p
);
7966 append_to_statement_list (label
, last_body
);
7967 gimplify_and_add (last_bind
, pre_p
);
7972 /* If *LIST_P contains any OpenMP depend clauses with iterators,
7973 lower all the depend clauses by populating corresponding depend
7974 array. Returns 0 if there are no such depend clauses, or
7975 2 if all depend clauses should be removed, 1 otherwise. */
7978 gimplify_omp_depend (tree
*list_p
, gimple_seq
*pre_p
)
7982 size_t n
[4] = { 0, 0, 0, 0 };
7984 tree counts
[4] = { NULL_TREE
, NULL_TREE
, NULL_TREE
, NULL_TREE
};
7985 tree last_iter
= NULL_TREE
, last_count
= NULL_TREE
;
7987 location_t first_loc
= UNKNOWN_LOCATION
;
7989 for (c
= *list_p
; c
; c
= OMP_CLAUSE_CHAIN (c
))
7990 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEPEND
)
7992 switch (OMP_CLAUSE_DEPEND_KIND (c
))
7994 case OMP_CLAUSE_DEPEND_IN
:
7997 case OMP_CLAUSE_DEPEND_OUT
:
7998 case OMP_CLAUSE_DEPEND_INOUT
:
8001 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET
:
8004 case OMP_CLAUSE_DEPEND_DEPOBJ
:
8007 case OMP_CLAUSE_DEPEND_SOURCE
:
8008 case OMP_CLAUSE_DEPEND_SINK
:
8013 tree t
= OMP_CLAUSE_DECL (c
);
8014 if (first_loc
== UNKNOWN_LOCATION
)
8015 first_loc
= OMP_CLAUSE_LOCATION (c
);
8016 if (TREE_CODE (t
) == TREE_LIST
8018 && TREE_CODE (TREE_PURPOSE (t
)) == TREE_VEC
)
8020 if (TREE_PURPOSE (t
) != last_iter
)
8022 tree tcnt
= size_one_node
;
8023 for (tree it
= TREE_PURPOSE (t
); it
; it
= TREE_CHAIN (it
))
8025 if (gimplify_expr (&TREE_VEC_ELT (it
, 1), pre_p
, NULL
,
8026 is_gimple_val
, fb_rvalue
) == GS_ERROR
8027 || gimplify_expr (&TREE_VEC_ELT (it
, 2), pre_p
, NULL
,
8028 is_gimple_val
, fb_rvalue
) == GS_ERROR
8029 || gimplify_expr (&TREE_VEC_ELT (it
, 3), pre_p
, NULL
,
8030 is_gimple_val
, fb_rvalue
) == GS_ERROR
8031 || (gimplify_expr (&TREE_VEC_ELT (it
, 4), pre_p
, NULL
,
8032 is_gimple_val
, fb_rvalue
)
8035 tree var
= TREE_VEC_ELT (it
, 0);
8036 tree begin
= TREE_VEC_ELT (it
, 1);
8037 tree end
= TREE_VEC_ELT (it
, 2);
8038 tree step
= TREE_VEC_ELT (it
, 3);
8039 tree orig_step
= TREE_VEC_ELT (it
, 4);
8040 tree type
= TREE_TYPE (var
);
8041 tree stype
= TREE_TYPE (step
);
8042 location_t loc
= DECL_SOURCE_LOCATION (var
);
8044 /* Compute count for this iterator as
8046 ? (begin < end ? (end - begin + (step - 1)) / step : 0)
8047 : (begin > end ? (end - begin + (step + 1)) / step : 0)
8048 and compute product of those for the entire depend
8050 if (POINTER_TYPE_P (type
))
8051 endmbegin
= fold_build2_loc (loc
, POINTER_DIFF_EXPR
,
8054 endmbegin
= fold_build2_loc (loc
, MINUS_EXPR
, type
,
8056 tree stepm1
= fold_build2_loc (loc
, MINUS_EXPR
, stype
,
8058 build_int_cst (stype
, 1));
8059 tree stepp1
= fold_build2_loc (loc
, PLUS_EXPR
, stype
, step
,
8060 build_int_cst (stype
, 1));
8061 tree pos
= fold_build2_loc (loc
, PLUS_EXPR
, stype
,
8062 unshare_expr (endmbegin
),
8064 pos
= fold_build2_loc (loc
, TRUNC_DIV_EXPR
, stype
,
8066 tree neg
= fold_build2_loc (loc
, PLUS_EXPR
, stype
,
8068 if (TYPE_UNSIGNED (stype
))
8070 neg
= fold_build1_loc (loc
, NEGATE_EXPR
, stype
, neg
);
8071 step
= fold_build1_loc (loc
, NEGATE_EXPR
, stype
, step
);
8073 neg
= fold_build2_loc (loc
, TRUNC_DIV_EXPR
, stype
,
8076 tree cond
= fold_build2_loc (loc
, LT_EXPR
,
8079 pos
= fold_build3_loc (loc
, COND_EXPR
, stype
, cond
, pos
,
8080 build_int_cst (stype
, 0));
8081 cond
= fold_build2_loc (loc
, LT_EXPR
, boolean_type_node
,
8083 neg
= fold_build3_loc (loc
, COND_EXPR
, stype
, cond
, neg
,
8084 build_int_cst (stype
, 0));
8085 tree osteptype
= TREE_TYPE (orig_step
);
8086 cond
= fold_build2_loc (loc
, GT_EXPR
, boolean_type_node
,
8088 build_int_cst (osteptype
, 0));
8089 tree cnt
= fold_build3_loc (loc
, COND_EXPR
, stype
,
8091 cnt
= fold_convert_loc (loc
, sizetype
, cnt
);
8092 if (gimplify_expr (&cnt
, pre_p
, NULL
, is_gimple_val
,
8093 fb_rvalue
) == GS_ERROR
)
8095 tcnt
= size_binop_loc (loc
, MULT_EXPR
, tcnt
, cnt
);
8097 if (gimplify_expr (&tcnt
, pre_p
, NULL
, is_gimple_val
,
8098 fb_rvalue
) == GS_ERROR
)
8100 last_iter
= TREE_PURPOSE (t
);
8103 if (counts
[i
] == NULL_TREE
)
8104 counts
[i
] = last_count
;
8106 counts
[i
] = size_binop_loc (OMP_CLAUSE_LOCATION (c
),
8107 PLUS_EXPR
, counts
[i
], last_count
);
8112 for (i
= 0; i
< 4; i
++)
8118 tree total
= size_zero_node
;
8119 for (i
= 0; i
< 4; i
++)
8121 unused
[i
] = counts
[i
] == NULL_TREE
&& n
[i
] == 0;
8122 if (counts
[i
] == NULL_TREE
)
8123 counts
[i
] = size_zero_node
;
8125 counts
[i
] = size_binop (PLUS_EXPR
, counts
[i
], size_int (n
[i
]));
8126 if (gimplify_expr (&counts
[i
], pre_p
, NULL
, is_gimple_val
,
8127 fb_rvalue
) == GS_ERROR
)
8129 total
= size_binop (PLUS_EXPR
, total
, counts
[i
]);
8132 if (gimplify_expr (&total
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
)
8135 bool is_old
= unused
[1] && unused
[3];
8136 tree totalpx
= size_binop (PLUS_EXPR
, unshare_expr (total
),
8137 size_int (is_old
? 1 : 4));
8138 tree type
= build_array_type (ptr_type_node
, build_index_type (totalpx
));
8139 tree array
= create_tmp_var_raw (type
);
8140 TREE_ADDRESSABLE (array
) = 1;
8141 if (!poly_int_tree_p (totalpx
))
8143 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (array
)))
8144 gimplify_type_sizes (TREE_TYPE (array
), pre_p
);
8145 if (gimplify_omp_ctxp
)
8147 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
8149 && (ctx
->region_type
== ORT_WORKSHARE
8150 || ctx
->region_type
== ORT_TASKGROUP
8151 || ctx
->region_type
== ORT_SIMD
8152 || ctx
->region_type
== ORT_ACC
))
8153 ctx
= ctx
->outer_context
;
8155 omp_add_variable (ctx
, array
, GOVD_LOCAL
| GOVD_SEEN
);
8157 gimplify_vla_decl (array
, pre_p
);
8160 gimple_add_tmp_var (array
);
8161 tree r
= build4 (ARRAY_REF
, ptr_type_node
, array
, size_int (0), NULL_TREE
,
8166 tem
= build2 (MODIFY_EXPR
, void_type_node
, r
,
8167 build_int_cst (ptr_type_node
, 0));
8168 gimplify_and_add (tem
, pre_p
);
8169 r
= build4 (ARRAY_REF
, ptr_type_node
, array
, size_int (1), NULL_TREE
,
8172 tem
= build2 (MODIFY_EXPR
, void_type_node
, r
,
8173 fold_convert (ptr_type_node
, total
));
8174 gimplify_and_add (tem
, pre_p
);
8175 for (i
= 1; i
< (is_old
? 2 : 4); i
++)
8177 r
= build4 (ARRAY_REF
, ptr_type_node
, array
, size_int (i
+ !is_old
),
8178 NULL_TREE
, NULL_TREE
);
8179 tem
= build2 (MODIFY_EXPR
, void_type_node
, r
, counts
[i
- 1]);
8180 gimplify_and_add (tem
, pre_p
);
8187 for (i
= 0; i
< 4; i
++)
8189 if (i
&& (i
>= j
|| unused
[i
- 1]))
8191 cnts
[i
] = cnts
[i
- 1];
8194 cnts
[i
] = create_tmp_var (sizetype
);
8196 g
= gimple_build_assign (cnts
[i
], size_int (is_old
? 2 : 5));
8201 t
= size_binop (PLUS_EXPR
, counts
[0], size_int (2));
8203 t
= size_binop (PLUS_EXPR
, cnts
[i
- 1], counts
[i
- 1]);
8204 if (gimplify_expr (&t
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
)
8207 g
= gimple_build_assign (cnts
[i
], t
);
8209 gimple_seq_add_stmt (pre_p
, g
);
8212 last_iter
= NULL_TREE
;
8213 tree last_bind
= NULL_TREE
;
8214 tree
*last_body
= NULL
;
8215 for (c
= *list_p
; c
; c
= OMP_CLAUSE_CHAIN (c
))
8216 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEPEND
)
8218 switch (OMP_CLAUSE_DEPEND_KIND (c
))
8220 case OMP_CLAUSE_DEPEND_IN
:
8223 case OMP_CLAUSE_DEPEND_OUT
:
8224 case OMP_CLAUSE_DEPEND_INOUT
:
8227 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET
:
8230 case OMP_CLAUSE_DEPEND_DEPOBJ
:
8233 case OMP_CLAUSE_DEPEND_SOURCE
:
8234 case OMP_CLAUSE_DEPEND_SINK
:
8239 tree t
= OMP_CLAUSE_DECL (c
);
8240 if (TREE_CODE (t
) == TREE_LIST
8242 && TREE_CODE (TREE_PURPOSE (t
)) == TREE_VEC
)
8244 if (TREE_PURPOSE (t
) != last_iter
)
8247 gimplify_and_add (last_bind
, pre_p
);
8248 tree block
= TREE_VEC_ELT (TREE_PURPOSE (t
), 5);
8249 last_bind
= build3 (BIND_EXPR
, void_type_node
,
8250 BLOCK_VARS (block
), NULL
, block
);
8251 TREE_SIDE_EFFECTS (last_bind
) = 1;
8252 SET_EXPR_LOCATION (last_bind
, OMP_CLAUSE_LOCATION (c
));
8253 tree
*p
= &BIND_EXPR_BODY (last_bind
);
8254 for (tree it
= TREE_PURPOSE (t
); it
; it
= TREE_CHAIN (it
))
8256 tree var
= TREE_VEC_ELT (it
, 0);
8257 tree begin
= TREE_VEC_ELT (it
, 1);
8258 tree end
= TREE_VEC_ELT (it
, 2);
8259 tree step
= TREE_VEC_ELT (it
, 3);
8260 tree orig_step
= TREE_VEC_ELT (it
, 4);
8261 tree type
= TREE_TYPE (var
);
8262 location_t loc
= DECL_SOURCE_LOCATION (var
);
8270 if (orig_step > 0) {
8271 if (var < end) goto beg_label;
8273 if (var > end) goto beg_label;
8275 for each iterator, with inner iterators added to
8277 tree beg_label
= create_artificial_label (loc
);
8278 tree cond_label
= NULL_TREE
;
8279 tem
= build2_loc (loc
, MODIFY_EXPR
, void_type_node
,
8281 append_to_statement_list_force (tem
, p
);
8282 tem
= build_and_jump (&cond_label
);
8283 append_to_statement_list_force (tem
, p
);
8284 tem
= build1 (LABEL_EXPR
, void_type_node
, beg_label
);
8285 append_to_statement_list (tem
, p
);
8286 tree bind
= build3 (BIND_EXPR
, void_type_node
, NULL_TREE
,
8287 NULL_TREE
, NULL_TREE
);
8288 TREE_SIDE_EFFECTS (bind
) = 1;
8289 SET_EXPR_LOCATION (bind
, loc
);
8290 append_to_statement_list_force (bind
, p
);
8291 if (POINTER_TYPE_P (type
))
8292 tem
= build2_loc (loc
, POINTER_PLUS_EXPR
, type
,
8293 var
, fold_convert_loc (loc
, sizetype
,
8296 tem
= build2_loc (loc
, PLUS_EXPR
, type
, var
, step
);
8297 tem
= build2_loc (loc
, MODIFY_EXPR
, void_type_node
,
8299 append_to_statement_list_force (tem
, p
);
8300 tem
= build1 (LABEL_EXPR
, void_type_node
, cond_label
);
8301 append_to_statement_list (tem
, p
);
8302 tree cond
= fold_build2_loc (loc
, LT_EXPR
,
8306 = fold_build3_loc (loc
, COND_EXPR
, void_type_node
,
8307 cond
, build_and_jump (&beg_label
),
8309 cond
= fold_build2_loc (loc
, GT_EXPR
, boolean_type_node
,
8312 = fold_build3_loc (loc
, COND_EXPR
, void_type_node
,
8313 cond
, build_and_jump (&beg_label
),
8315 tree osteptype
= TREE_TYPE (orig_step
);
8316 cond
= fold_build2_loc (loc
, GT_EXPR
, boolean_type_node
,
8318 build_int_cst (osteptype
, 0));
8319 tem
= fold_build3_loc (loc
, COND_EXPR
, void_type_node
,
8321 append_to_statement_list_force (tem
, p
);
8322 p
= &BIND_EXPR_BODY (bind
);
8326 last_iter
= TREE_PURPOSE (t
);
8327 if (TREE_CODE (TREE_VALUE (t
)) == COMPOUND_EXPR
)
8329 append_to_statement_list (TREE_OPERAND (TREE_VALUE (t
),
8331 TREE_VALUE (t
) = TREE_OPERAND (TREE_VALUE (t
), 1);
8333 if (error_operand_p (TREE_VALUE (t
)))
8335 TREE_VALUE (t
) = build_fold_addr_expr (TREE_VALUE (t
));
8336 r
= build4 (ARRAY_REF
, ptr_type_node
, array
, cnts
[i
],
8337 NULL_TREE
, NULL_TREE
);
8338 tem
= build2_loc (OMP_CLAUSE_LOCATION (c
), MODIFY_EXPR
,
8339 void_type_node
, r
, TREE_VALUE (t
));
8340 append_to_statement_list_force (tem
, last_body
);
8341 tem
= build2_loc (OMP_CLAUSE_LOCATION (c
), MODIFY_EXPR
,
8342 void_type_node
, cnts
[i
],
8343 size_binop (PLUS_EXPR
, cnts
[i
], size_int (1)));
8344 append_to_statement_list_force (tem
, last_body
);
8345 TREE_VALUE (t
) = null_pointer_node
;
8351 gimplify_and_add (last_bind
, pre_p
);
8352 last_bind
= NULL_TREE
;
8354 if (TREE_CODE (OMP_CLAUSE_DECL (c
)) == COMPOUND_EXPR
)
8356 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c
), 0), pre_p
,
8357 NULL
, is_gimple_val
, fb_rvalue
);
8358 OMP_CLAUSE_DECL (c
) = TREE_OPERAND (OMP_CLAUSE_DECL (c
), 1);
8360 if (error_operand_p (OMP_CLAUSE_DECL (c
)))
8362 OMP_CLAUSE_DECL (c
) = build_fold_addr_expr (OMP_CLAUSE_DECL (c
));
8363 if (gimplify_expr (&OMP_CLAUSE_DECL (c
), pre_p
, NULL
,
8364 is_gimple_val
, fb_rvalue
) == GS_ERROR
)
8366 r
= build4 (ARRAY_REF
, ptr_type_node
, array
, cnts
[i
],
8367 NULL_TREE
, NULL_TREE
);
8368 tem
= build2 (MODIFY_EXPR
, void_type_node
, r
, OMP_CLAUSE_DECL (c
));
8369 gimplify_and_add (tem
, pre_p
);
8370 g
= gimple_build_assign (cnts
[i
], size_binop (PLUS_EXPR
, cnts
[i
],
8372 gimple_seq_add_stmt (pre_p
, g
);
8376 gimplify_and_add (last_bind
, pre_p
);
8377 tree cond
= boolean_false_node
;
8381 cond
= build2_loc (first_loc
, NE_EXPR
, boolean_type_node
, cnts
[0],
8382 size_binop_loc (first_loc
, PLUS_EXPR
, counts
[0],
8385 cond
= build2_loc (first_loc
, TRUTH_OR_EXPR
, boolean_type_node
, cond
,
8386 build2_loc (first_loc
, NE_EXPR
, boolean_type_node
,
8388 size_binop_loc (first_loc
, PLUS_EXPR
,
8394 tree prev
= size_int (5);
8395 for (i
= 0; i
< 4; i
++)
8399 prev
= size_binop_loc (first_loc
, PLUS_EXPR
, counts
[i
], prev
);
8400 cond
= build2_loc (first_loc
, TRUTH_OR_EXPR
, boolean_type_node
, cond
,
8401 build2_loc (first_loc
, NE_EXPR
, boolean_type_node
,
8402 cnts
[i
], unshare_expr (prev
)));
8405 tem
= build3_loc (first_loc
, COND_EXPR
, void_type_node
, cond
,
8406 build_call_expr_loc (first_loc
,
8407 builtin_decl_explicit (BUILT_IN_TRAP
),
8409 gimplify_and_add (tem
, pre_p
);
8410 c
= build_omp_clause (UNKNOWN_LOCATION
, OMP_CLAUSE_DEPEND
);
8411 OMP_CLAUSE_DEPEND_KIND (c
) = OMP_CLAUSE_DEPEND_LAST
;
8412 OMP_CLAUSE_DECL (c
) = build_fold_addr_expr (array
);
8413 OMP_CLAUSE_CHAIN (c
) = *list_p
;
8418 /* Insert a GOMP_MAP_ALLOC or GOMP_MAP_RELEASE node following a
8419 GOMP_MAP_STRUCT mapping. C is an always_pointer mapping. STRUCT_NODE is
8420 the struct node to insert the new mapping after (when the struct node is
8421 initially created). PREV_NODE is the first of two or three mappings for a
8422 pointer, and is either:
8423 - the node before C, when a pair of mappings is used, e.g. for a C/C++
8425 - not the node before C. This is true when we have a reference-to-pointer
8426 type (with a mapping for the reference and for the pointer), or for
8427 Fortran derived-type mappings with a GOMP_MAP_TO_PSET.
8428 If SCP is non-null, the new node is inserted before *SCP.
8429 if SCP is null, the new node is inserted before PREV_NODE.
8431 - PREV_NODE, if SCP is non-null.
8432 - The newly-created ALLOC or RELEASE node, if SCP is null.
8433 - The second newly-created ALLOC or RELEASE node, if we are mapping a
8434 reference to a pointer. */
8437 insert_struct_comp_map (enum tree_code code
, tree c
, tree struct_node
,
8438 tree prev_node
, tree
*scp
)
8440 enum gomp_map_kind mkind
8441 = (code
== OMP_TARGET_EXIT_DATA
|| code
== OACC_EXIT_DATA
)
8442 ? GOMP_MAP_RELEASE
: GOMP_MAP_ALLOC
;
8444 tree c2
= build_omp_clause (OMP_CLAUSE_LOCATION (c
), OMP_CLAUSE_MAP
);
8445 tree cl
= scp
? prev_node
: c2
;
8446 OMP_CLAUSE_SET_MAP_KIND (c2
, mkind
);
8447 OMP_CLAUSE_DECL (c2
) = unshare_expr (OMP_CLAUSE_DECL (c
));
8448 OMP_CLAUSE_CHAIN (c2
) = scp
? *scp
: prev_node
;
8449 if (OMP_CLAUSE_CHAIN (prev_node
) != c
8450 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (prev_node
)) == OMP_CLAUSE_MAP
8451 && (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node
))
8452 == GOMP_MAP_TO_PSET
))
8453 OMP_CLAUSE_SIZE (c2
) = OMP_CLAUSE_SIZE (OMP_CLAUSE_CHAIN (prev_node
));
8455 OMP_CLAUSE_SIZE (c2
) = TYPE_SIZE_UNIT (ptr_type_node
);
8457 OMP_CLAUSE_CHAIN (struct_node
) = c2
;
8459 /* We might need to create an additional mapping if we have a reference to a
8460 pointer (in C++). Don't do this if we have something other than a
8461 GOMP_MAP_ALWAYS_POINTER though, i.e. a GOMP_MAP_TO_PSET. */
8462 if (OMP_CLAUSE_CHAIN (prev_node
) != c
8463 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (prev_node
)) == OMP_CLAUSE_MAP
8464 && ((OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node
))
8465 == GOMP_MAP_ALWAYS_POINTER
)
8466 || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node
))
8467 == GOMP_MAP_ATTACH_DETACH
)))
8469 tree c4
= OMP_CLAUSE_CHAIN (prev_node
);
8470 tree c3
= build_omp_clause (OMP_CLAUSE_LOCATION (c
), OMP_CLAUSE_MAP
);
8471 OMP_CLAUSE_SET_MAP_KIND (c3
, mkind
);
8472 OMP_CLAUSE_DECL (c3
) = unshare_expr (OMP_CLAUSE_DECL (c4
));
8473 OMP_CLAUSE_SIZE (c3
) = TYPE_SIZE_UNIT (ptr_type_node
);
8474 OMP_CLAUSE_CHAIN (c3
) = prev_node
;
8476 OMP_CLAUSE_CHAIN (c2
) = c3
;
8487 /* Strip ARRAY_REFS or an indirect ref off BASE, find the containing object,
8488 and set *BITPOSP and *POFFSETP to the bit offset of the access.
8489 If BASE_REF is non-NULL and the containing object is a reference, set
8490 *BASE_REF to that reference before dereferencing the object.
8491 If BASE_REF is NULL, check that the containing object is a COMPONENT_REF or
8492 has array type, else return NULL. */
8495 extract_base_bit_offset (tree base
, tree
*base_ref
, poly_int64
*bitposp
,
8496 poly_offset_int
*poffsetp
)
8499 poly_int64 bitsize
, bitpos
;
8501 int unsignedp
, reversep
, volatilep
= 0;
8502 poly_offset_int poffset
;
8506 *base_ref
= NULL_TREE
;
8508 while (TREE_CODE (base
) == ARRAY_REF
)
8509 base
= TREE_OPERAND (base
, 0);
8511 if (TREE_CODE (base
) == INDIRECT_REF
)
8512 base
= TREE_OPERAND (base
, 0);
8516 if (TREE_CODE (base
) == ARRAY_REF
)
8518 while (TREE_CODE (base
) == ARRAY_REF
)
8519 base
= TREE_OPERAND (base
, 0);
8520 if (TREE_CODE (base
) != COMPONENT_REF
8521 || TREE_CODE (TREE_TYPE (base
)) != ARRAY_TYPE
)
8524 else if (TREE_CODE (base
) == INDIRECT_REF
8525 && TREE_CODE (TREE_OPERAND (base
, 0)) == COMPONENT_REF
8526 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (base
, 0)))
8528 base
= TREE_OPERAND (base
, 0);
8531 base
= get_inner_reference (base
, &bitsize
, &bitpos
, &offset
, &mode
,
8532 &unsignedp
, &reversep
, &volatilep
);
8534 tree orig_base
= base
;
8536 if ((TREE_CODE (base
) == INDIRECT_REF
8537 || (TREE_CODE (base
) == MEM_REF
8538 && integer_zerop (TREE_OPERAND (base
, 1))))
8539 && DECL_P (TREE_OPERAND (base
, 0))
8540 && TREE_CODE (TREE_TYPE (TREE_OPERAND (base
, 0))) == REFERENCE_TYPE
)
8541 base
= TREE_OPERAND (base
, 0);
8543 gcc_assert (offset
== NULL_TREE
|| poly_int_tree_p (offset
));
8546 poffset
= wi::to_poly_offset (offset
);
8550 if (maybe_ne (bitpos
, 0))
8551 poffset
+= bits_to_bytes_round_down (bitpos
);
8554 *poffsetp
= poffset
;
8556 /* Set *BASE_REF if BASE was a dereferenced reference variable. */
8557 if (base_ref
&& orig_base
!= base
)
8558 *base_ref
= orig_base
;
8563 /* Returns true if EXPR is or contains (as a sub-component) BASE_PTR. */
8566 is_or_contains_p (tree expr
, tree base_ptr
)
8568 while (expr
!= base_ptr
)
8569 if (TREE_CODE (base_ptr
) == COMPONENT_REF
)
8570 base_ptr
= TREE_OPERAND (base_ptr
, 0);
8573 return expr
== base_ptr
;
8576 /* Implement OpenMP 5.x map ordering rules for target directives. There are
8577 several rules, and with some level of ambiguity, hopefully we can at least
8578 collect the complexity here in one place. */
8581 omp_target_reorder_clauses (tree
*list_p
)
8583 /* Collect refs to alloc/release/delete maps. */
8584 auto_vec
<tree
, 32> ard
;
8586 while (*cp
!= NULL_TREE
)
8587 if (OMP_CLAUSE_CODE (*cp
) == OMP_CLAUSE_MAP
8588 && (OMP_CLAUSE_MAP_KIND (*cp
) == GOMP_MAP_ALLOC
8589 || OMP_CLAUSE_MAP_KIND (*cp
) == GOMP_MAP_RELEASE
8590 || OMP_CLAUSE_MAP_KIND (*cp
) == GOMP_MAP_DELETE
))
8592 /* Unlink cp and push to ard. */
8594 tree nc
= OMP_CLAUSE_CHAIN (c
);
8598 /* Any associated pointer type maps should also move along. */
8599 while (*cp
!= NULL_TREE
8600 && OMP_CLAUSE_CODE (*cp
) == OMP_CLAUSE_MAP
8601 && (OMP_CLAUSE_MAP_KIND (*cp
) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
8602 || OMP_CLAUSE_MAP_KIND (*cp
) == GOMP_MAP_FIRSTPRIVATE_POINTER
8603 || OMP_CLAUSE_MAP_KIND (*cp
) == GOMP_MAP_ATTACH_DETACH
8604 || OMP_CLAUSE_MAP_KIND (*cp
) == GOMP_MAP_POINTER
8605 || OMP_CLAUSE_MAP_KIND (*cp
) == GOMP_MAP_ALWAYS_POINTER
8606 || OMP_CLAUSE_MAP_KIND (*cp
) == GOMP_MAP_TO_PSET
))
8609 nc
= OMP_CLAUSE_CHAIN (c
);
8615 cp
= &OMP_CLAUSE_CHAIN (*cp
);
8617 /* Link alloc/release/delete maps to the end of list. */
8618 for (unsigned int i
= 0; i
< ard
.length (); i
++)
8621 cp
= &OMP_CLAUSE_CHAIN (ard
[i
]);
8625 /* OpenMP 5.0 requires that pointer variables are mapped before
8626 its use as a base-pointer. */
8627 auto_vec
<tree
*, 32> atf
;
8628 for (tree
*cp
= list_p
; *cp
; cp
= &OMP_CLAUSE_CHAIN (*cp
))
8629 if (OMP_CLAUSE_CODE (*cp
) == OMP_CLAUSE_MAP
)
8631 /* Collect alloc, to, from, to/from clause tree pointers. */
8632 gomp_map_kind k
= OMP_CLAUSE_MAP_KIND (*cp
);
8633 if (k
== GOMP_MAP_ALLOC
8635 || k
== GOMP_MAP_FROM
8636 || k
== GOMP_MAP_TOFROM
8637 || k
== GOMP_MAP_ALWAYS_TO
8638 || k
== GOMP_MAP_ALWAYS_FROM
8639 || k
== GOMP_MAP_ALWAYS_TOFROM
)
8643 for (unsigned int i
= 0; i
< atf
.length (); i
++)
8647 tree decl
= OMP_CLAUSE_DECL (*cp
);
8648 if (TREE_CODE (decl
) == INDIRECT_REF
|| TREE_CODE (decl
) == MEM_REF
)
8650 tree base_ptr
= TREE_OPERAND (decl
, 0);
8651 STRIP_TYPE_NOPS (base_ptr
);
8652 for (unsigned int j
= i
+ 1; j
< atf
.length (); j
++)
8655 tree decl2
= OMP_CLAUSE_DECL (*cp2
);
8656 if (is_or_contains_p (decl2
, base_ptr
))
8658 /* Move *cp2 to before *cp. */
8660 *cp2
= OMP_CLAUSE_CHAIN (c
);
8661 OMP_CLAUSE_CHAIN (c
) = *cp
;
8670 /* DECL is supposed to have lastprivate semantics in the outer contexts
8671 of combined/composite constructs, starting with OCTX.
8672 Add needed lastprivate, shared or map clause if no data sharing or
8673 mapping clause are present. IMPLICIT_P is true if it is an implicit
8674 clause (IV on simd), in which case the lastprivate will not be
8675 copied to some constructs. */
8678 omp_lastprivate_for_combined_outer_constructs (struct gimplify_omp_ctx
*octx
,
8679 tree decl
, bool implicit_p
)
8681 struct gimplify_omp_ctx
*orig_octx
= octx
;
8682 for (; octx
; octx
= octx
->outer_context
)
8684 if ((octx
->region_type
== ORT_COMBINED_PARALLEL
8685 || (octx
->region_type
& ORT_COMBINED_TEAMS
) == ORT_COMBINED_TEAMS
)
8686 && splay_tree_lookup (octx
->variables
,
8687 (splay_tree_key
) decl
) == NULL
)
8689 omp_add_variable (octx
, decl
, GOVD_SHARED
| GOVD_SEEN
);
8692 if ((octx
->region_type
& ORT_TASK
) != 0
8693 && octx
->combined_loop
8694 && splay_tree_lookup (octx
->variables
,
8695 (splay_tree_key
) decl
) == NULL
)
8697 omp_add_variable (octx
, decl
, GOVD_LASTPRIVATE
| GOVD_SEEN
);
8701 && octx
->region_type
== ORT_WORKSHARE
8702 && octx
->combined_loop
8703 && splay_tree_lookup (octx
->variables
,
8704 (splay_tree_key
) decl
) == NULL
8705 && octx
->outer_context
8706 && octx
->outer_context
->region_type
== ORT_COMBINED_PARALLEL
8707 && splay_tree_lookup (octx
->outer_context
->variables
,
8708 (splay_tree_key
) decl
) == NULL
)
8710 octx
= octx
->outer_context
;
8711 omp_add_variable (octx
, decl
, GOVD_LASTPRIVATE
| GOVD_SEEN
);
8714 if ((octx
->region_type
== ORT_WORKSHARE
|| octx
->region_type
== ORT_ACC
)
8715 && octx
->combined_loop
8716 && splay_tree_lookup (octx
->variables
,
8717 (splay_tree_key
) decl
) == NULL
8718 && !omp_check_private (octx
, decl
, false))
8720 omp_add_variable (octx
, decl
, GOVD_LASTPRIVATE
| GOVD_SEEN
);
8723 if (octx
->region_type
== ORT_COMBINED_TARGET
)
8725 splay_tree_node n
= splay_tree_lookup (octx
->variables
,
8726 (splay_tree_key
) decl
);
8729 omp_add_variable (octx
, decl
, GOVD_MAP
| GOVD_SEEN
);
8730 octx
= octx
->outer_context
;
8732 else if (!implicit_p
8733 && (n
->value
& GOVD_FIRSTPRIVATE_IMPLICIT
))
8735 n
->value
&= ~(GOVD_FIRSTPRIVATE
8736 | GOVD_FIRSTPRIVATE_IMPLICIT
8738 omp_add_variable (octx
, decl
, GOVD_MAP
| GOVD_SEEN
);
8739 octx
= octx
->outer_context
;
8744 if (octx
&& (implicit_p
|| octx
!= orig_octx
))
8745 omp_notice_variable (octx
, decl
, true);
8748 /* Scan the OMP clauses in *LIST_P, installing mappings into a new
8749 and previous omp contexts. */
8752 gimplify_scan_omp_clauses (tree
*list_p
, gimple_seq
*pre_p
,
8753 enum omp_region_type region_type
,
8754 enum tree_code code
)
8756 struct gimplify_omp_ctx
*ctx
, *outer_ctx
;
8758 hash_map
<tree
, tree
> *struct_map_to_clause
= NULL
;
8759 hash_set
<tree
> *struct_deref_set
= NULL
;
8760 tree
*prev_list_p
= NULL
, *orig_list_p
= list_p
;
8761 int handled_depend_iterators
= -1;
8764 ctx
= new_omp_context (region_type
);
8766 outer_ctx
= ctx
->outer_context
;
8767 if (code
== OMP_TARGET
)
8769 if (!lang_GNU_Fortran ())
8770 ctx
->defaultmap
[GDMK_POINTER
] = GOVD_MAP
| GOVD_MAP_0LEN_ARRAY
;
8771 ctx
->defaultmap
[GDMK_SCALAR
] = GOVD_FIRSTPRIVATE
;
8772 ctx
->defaultmap
[GDMK_SCALAR_TARGET
] = (lang_GNU_Fortran ()
8773 ? GOVD_MAP
: GOVD_FIRSTPRIVATE
);
8775 if (!lang_GNU_Fortran ())
8779 case OMP_TARGET_DATA
:
8780 case OMP_TARGET_ENTER_DATA
:
8781 case OMP_TARGET_EXIT_DATA
:
8783 case OACC_HOST_DATA
:
8786 ctx
->target_firstprivatize_array_bases
= true;
8791 if (code
== OMP_TARGET
8792 || code
== OMP_TARGET_DATA
8793 || code
== OMP_TARGET_ENTER_DATA
8794 || code
== OMP_TARGET_EXIT_DATA
)
8795 omp_target_reorder_clauses (list_p
);
8797 while ((c
= *list_p
) != NULL
)
8799 bool remove
= false;
8800 bool notice_outer
= true;
8801 const char *check_non_private
= NULL
;
8805 switch (OMP_CLAUSE_CODE (c
))
8807 case OMP_CLAUSE_PRIVATE
:
8808 flags
= GOVD_PRIVATE
| GOVD_EXPLICIT
;
8809 if (lang_hooks
.decls
.omp_private_outer_ref (OMP_CLAUSE_DECL (c
)))
8811 flags
|= GOVD_PRIVATE_OUTER_REF
;
8812 OMP_CLAUSE_PRIVATE_OUTER_REF (c
) = 1;
8815 notice_outer
= false;
8817 case OMP_CLAUSE_SHARED
:
8818 flags
= GOVD_SHARED
| GOVD_EXPLICIT
;
8820 case OMP_CLAUSE_FIRSTPRIVATE
:
8821 flags
= GOVD_FIRSTPRIVATE
| GOVD_EXPLICIT
;
8822 check_non_private
= "firstprivate";
8823 if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c
))
8825 gcc_assert (code
== OMP_TARGET
);
8826 flags
|= GOVD_FIRSTPRIVATE_IMPLICIT
;
8829 case OMP_CLAUSE_LASTPRIVATE
:
8830 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
))
8833 case OMP_DISTRIBUTE
:
8834 error_at (OMP_CLAUSE_LOCATION (c
),
8835 "conditional %<lastprivate%> clause on "
8836 "%qs construct", "distribute");
8837 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
) = 0;
8840 error_at (OMP_CLAUSE_LOCATION (c
),
8841 "conditional %<lastprivate%> clause on "
8842 "%qs construct", "taskloop");
8843 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
) = 0;
8848 flags
= GOVD_LASTPRIVATE
| GOVD_SEEN
| GOVD_EXPLICIT
;
8849 if (code
!= OMP_LOOP
)
8850 check_non_private
= "lastprivate";
8851 decl
= OMP_CLAUSE_DECL (c
);
8852 if (error_operand_p (decl
))
8854 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
)
8855 && !lang_hooks
.decls
.omp_scalar_p (decl
, true))
8857 error_at (OMP_CLAUSE_LOCATION (c
),
8858 "non-scalar variable %qD in conditional "
8859 "%<lastprivate%> clause", decl
);
8860 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
) = 0;
8862 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
))
8863 flags
|= GOVD_LASTPRIVATE_CONDITIONAL
;
8864 omp_lastprivate_for_combined_outer_constructs (outer_ctx
, decl
,
8867 case OMP_CLAUSE_REDUCTION
:
8868 if (OMP_CLAUSE_REDUCTION_TASK (c
))
8870 if (region_type
== ORT_WORKSHARE
|| code
== OMP_SCOPE
)
8873 nowait
= omp_find_clause (*list_p
,
8874 OMP_CLAUSE_NOWAIT
) != NULL_TREE
;
8876 && (outer_ctx
== NULL
8877 || outer_ctx
->region_type
!= ORT_COMBINED_PARALLEL
))
8879 error_at (OMP_CLAUSE_LOCATION (c
),
8880 "%<task%> reduction modifier on a construct "
8881 "with a %<nowait%> clause");
8882 OMP_CLAUSE_REDUCTION_TASK (c
) = 0;
8885 else if ((region_type
& ORT_PARALLEL
) != ORT_PARALLEL
)
8887 error_at (OMP_CLAUSE_LOCATION (c
),
8888 "invalid %<task%> reduction modifier on construct "
8889 "other than %<parallel%>, %qs, %<sections%> or "
8890 "%<scope%>", lang_GNU_Fortran () ? "do" : "for");
8891 OMP_CLAUSE_REDUCTION_TASK (c
) = 0;
8894 if (OMP_CLAUSE_REDUCTION_INSCAN (c
))
8898 error_at (OMP_CLAUSE_LOCATION (c
),
8899 "%<inscan%> %<reduction%> clause on "
8900 "%qs construct", "sections");
8901 OMP_CLAUSE_REDUCTION_INSCAN (c
) = 0;
8904 error_at (OMP_CLAUSE_LOCATION (c
),
8905 "%<inscan%> %<reduction%> clause on "
8906 "%qs construct", "parallel");
8907 OMP_CLAUSE_REDUCTION_INSCAN (c
) = 0;
8910 error_at (OMP_CLAUSE_LOCATION (c
),
8911 "%<inscan%> %<reduction%> clause on "
8912 "%qs construct", "teams");
8913 OMP_CLAUSE_REDUCTION_INSCAN (c
) = 0;
8916 error_at (OMP_CLAUSE_LOCATION (c
),
8917 "%<inscan%> %<reduction%> clause on "
8918 "%qs construct", "taskloop");
8919 OMP_CLAUSE_REDUCTION_INSCAN (c
) = 0;
8922 error_at (OMP_CLAUSE_LOCATION (c
),
8923 "%<inscan%> %<reduction%> clause on "
8924 "%qs construct", "scope");
8925 OMP_CLAUSE_REDUCTION_INSCAN (c
) = 0;
8931 case OMP_CLAUSE_IN_REDUCTION
:
8932 case OMP_CLAUSE_TASK_REDUCTION
:
8933 flags
= GOVD_REDUCTION
| GOVD_SEEN
| GOVD_EXPLICIT
;
8934 /* OpenACC permits reductions on private variables. */
8935 if (!(region_type
& ORT_ACC
)
8936 /* taskgroup is actually not a worksharing region. */
8937 && code
!= OMP_TASKGROUP
)
8938 check_non_private
= omp_clause_code_name
[OMP_CLAUSE_CODE (c
)];
8939 decl
= OMP_CLAUSE_DECL (c
);
8940 if (TREE_CODE (decl
) == MEM_REF
)
8942 tree type
= TREE_TYPE (decl
);
8943 bool saved_into_ssa
= gimplify_ctxp
->into_ssa
;
8944 gimplify_ctxp
->into_ssa
= false;
8945 if (gimplify_expr (&TYPE_MAX_VALUE (TYPE_DOMAIN (type
)), pre_p
,
8946 NULL
, is_gimple_val
, fb_rvalue
, false)
8949 gimplify_ctxp
->into_ssa
= saved_into_ssa
;
8953 gimplify_ctxp
->into_ssa
= saved_into_ssa
;
8954 tree v
= TYPE_MAX_VALUE (TYPE_DOMAIN (type
));
8957 omp_firstprivatize_variable (ctx
, v
);
8958 omp_notice_variable (ctx
, v
, true);
8960 decl
= TREE_OPERAND (decl
, 0);
8961 if (TREE_CODE (decl
) == POINTER_PLUS_EXPR
)
8963 gimplify_ctxp
->into_ssa
= false;
8964 if (gimplify_expr (&TREE_OPERAND (decl
, 1), pre_p
,
8965 NULL
, is_gimple_val
, fb_rvalue
, false)
8968 gimplify_ctxp
->into_ssa
= saved_into_ssa
;
8972 gimplify_ctxp
->into_ssa
= saved_into_ssa
;
8973 v
= TREE_OPERAND (decl
, 1);
8976 omp_firstprivatize_variable (ctx
, v
);
8977 omp_notice_variable (ctx
, v
, true);
8979 decl
= TREE_OPERAND (decl
, 0);
8981 if (TREE_CODE (decl
) == ADDR_EXPR
8982 || TREE_CODE (decl
) == INDIRECT_REF
)
8983 decl
= TREE_OPERAND (decl
, 0);
8986 case OMP_CLAUSE_LINEAR
:
8987 if (gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c
), pre_p
, NULL
,
8988 is_gimple_val
, fb_rvalue
) == GS_ERROR
)
8995 if (code
== OMP_SIMD
8996 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c
))
8998 struct gimplify_omp_ctx
*octx
= outer_ctx
;
9000 && octx
->region_type
== ORT_WORKSHARE
9001 && octx
->combined_loop
9002 && !octx
->distribute
)
9004 if (octx
->outer_context
9005 && (octx
->outer_context
->region_type
9006 == ORT_COMBINED_PARALLEL
))
9007 octx
= octx
->outer_context
->outer_context
;
9009 octx
= octx
->outer_context
;
9012 && octx
->region_type
== ORT_WORKSHARE
9013 && octx
->combined_loop
9014 && octx
->distribute
)
9016 error_at (OMP_CLAUSE_LOCATION (c
),
9017 "%<linear%> clause for variable other than "
9018 "loop iterator specified on construct "
9019 "combined with %<distribute%>");
9024 /* For combined #pragma omp parallel for simd, need to put
9025 lastprivate and perhaps firstprivate too on the
9026 parallel. Similarly for #pragma omp for simd. */
9027 struct gimplify_omp_ctx
*octx
= outer_ctx
;
9028 bool taskloop_seen
= false;
9032 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c
)
9033 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c
))
9035 decl
= OMP_CLAUSE_DECL (c
);
9036 if (error_operand_p (decl
))
9042 if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c
))
9043 flags
|= GOVD_FIRSTPRIVATE
;
9044 if (!OMP_CLAUSE_LINEAR_NO_COPYOUT (c
))
9045 flags
|= GOVD_LASTPRIVATE
;
9047 && octx
->region_type
== ORT_WORKSHARE
9048 && octx
->combined_loop
)
9050 if (octx
->outer_context
9051 && (octx
->outer_context
->region_type
9052 == ORT_COMBINED_PARALLEL
))
9053 octx
= octx
->outer_context
;
9054 else if (omp_check_private (octx
, decl
, false))
9058 && (octx
->region_type
& ORT_TASK
) != 0
9059 && octx
->combined_loop
)
9060 taskloop_seen
= true;
9062 && octx
->region_type
== ORT_COMBINED_PARALLEL
9063 && ((ctx
->region_type
== ORT_WORKSHARE
9064 && octx
== outer_ctx
)
9066 flags
= GOVD_SEEN
| GOVD_SHARED
;
9068 && ((octx
->region_type
& ORT_COMBINED_TEAMS
)
9069 == ORT_COMBINED_TEAMS
))
9070 flags
= GOVD_SEEN
| GOVD_SHARED
;
9072 && octx
->region_type
== ORT_COMBINED_TARGET
)
9074 if (flags
& GOVD_LASTPRIVATE
)
9075 flags
= GOVD_SEEN
| GOVD_MAP
;
9080 = splay_tree_lookup (octx
->variables
,
9081 (splay_tree_key
) decl
);
9082 if (on
&& (on
->value
& GOVD_DATA_SHARE_CLASS
) != 0)
9087 omp_add_variable (octx
, decl
, flags
);
9088 if (octx
->outer_context
== NULL
)
9090 octx
= octx
->outer_context
;
9095 && (!OMP_CLAUSE_LINEAR_NO_COPYIN (c
)
9096 || !OMP_CLAUSE_LINEAR_NO_COPYOUT (c
)))
9097 omp_notice_variable (octx
, decl
, true);
9099 flags
= GOVD_LINEAR
| GOVD_EXPLICIT
;
9100 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c
)
9101 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c
))
9103 notice_outer
= false;
9104 flags
|= GOVD_LINEAR_LASTPRIVATE_NO_OUTER
;
9108 case OMP_CLAUSE_MAP
:
9109 decl
= OMP_CLAUSE_DECL (c
);
9110 if (error_operand_p (decl
))
9117 if (TREE_CODE (TREE_TYPE (decl
)) != ARRAY_TYPE
)
9120 case OMP_TARGET_DATA
:
9121 case OMP_TARGET_ENTER_DATA
:
9122 case OMP_TARGET_EXIT_DATA
:
9123 case OACC_ENTER_DATA
:
9124 case OACC_EXIT_DATA
:
9125 case OACC_HOST_DATA
:
9126 if (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_FIRSTPRIVATE_POINTER
9127 || (OMP_CLAUSE_MAP_KIND (c
)
9128 == GOMP_MAP_FIRSTPRIVATE_REFERENCE
))
9129 /* For target {,enter ,exit }data only the array slice is
9130 mapped, but not the pointer to it. */
9136 /* For Fortran, not only the pointer to the data is mapped but also
9137 the address of the pointer, the array descriptor etc.; for
9138 'exit data' - and in particular for 'delete:' - having an 'alloc:'
9139 does not make sense. Likewise, for 'update' only transferring the
9140 data itself is needed as the rest has been handled in previous
9141 directives. However, for 'exit data', the array descriptor needs
9142 to be delete; hence, we turn the MAP_TO_PSET into a MAP_DELETE.
9144 NOTE: Generally, it is not safe to perform "enter data" operations
9145 on arrays where the data *or the descriptor* may go out of scope
9146 before a corresponding "exit data" operation -- and such a
9147 descriptor may be synthesized temporarily, e.g. to pass an
9148 explicit-shape array to a function expecting an assumed-shape
9149 argument. Performing "enter data" inside the called function
9150 would thus be problematic. */
9151 if (code
== OMP_TARGET_EXIT_DATA
9152 && OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_TO_PSET
)
9153 OMP_CLAUSE_SET_MAP_KIND (c
, OMP_CLAUSE_MAP_KIND (*prev_list_p
)
9155 ? GOMP_MAP_DELETE
: GOMP_MAP_RELEASE
);
9156 else if ((code
== OMP_TARGET_EXIT_DATA
|| code
== OMP_TARGET_UPDATE
)
9157 && (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_POINTER
9158 || OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_TO_PSET
))
9163 if (DECL_P (decl
) && outer_ctx
&& (region_type
& ORT_ACC
))
9165 struct gimplify_omp_ctx
*octx
;
9166 for (octx
= outer_ctx
; octx
; octx
= octx
->outer_context
)
9168 if (octx
->region_type
!= ORT_ACC_HOST_DATA
)
9171 = splay_tree_lookup (octx
->variables
,
9172 (splay_tree_key
) decl
);
9174 error_at (OMP_CLAUSE_LOCATION (c
), "variable %qE "
9175 "declared in enclosing %<host_data%> region",
9179 if (OMP_CLAUSE_SIZE (c
) == NULL_TREE
)
9180 OMP_CLAUSE_SIZE (c
) = DECL_P (decl
) ? DECL_SIZE_UNIT (decl
)
9181 : TYPE_SIZE_UNIT (TREE_TYPE (decl
));
9182 if (gimplify_expr (&OMP_CLAUSE_SIZE (c
), pre_p
,
9183 NULL
, is_gimple_val
, fb_rvalue
) == GS_ERROR
)
9188 else if ((OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_FIRSTPRIVATE_POINTER
9189 || (OMP_CLAUSE_MAP_KIND (c
)
9190 == GOMP_MAP_FIRSTPRIVATE_REFERENCE
)
9191 || OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ATTACH_DETACH
)
9192 && TREE_CODE (OMP_CLAUSE_SIZE (c
)) != INTEGER_CST
)
9195 = get_initialized_tmp_var (OMP_CLAUSE_SIZE (c
), pre_p
, NULL
,
9197 if ((region_type
& ORT_TARGET
) != 0)
9198 omp_add_variable (ctx
, OMP_CLAUSE_SIZE (c
),
9199 GOVD_FIRSTPRIVATE
| GOVD_SEEN
);
9205 if (TREE_CODE (d
) == ARRAY_REF
)
9207 while (TREE_CODE (d
) == ARRAY_REF
)
9208 d
= TREE_OPERAND (d
, 0);
9209 if (TREE_CODE (d
) == COMPONENT_REF
9210 && TREE_CODE (TREE_TYPE (d
)) == ARRAY_TYPE
)
9213 pd
= &OMP_CLAUSE_DECL (c
);
9215 && TREE_CODE (decl
) == INDIRECT_REF
9216 && TREE_CODE (TREE_OPERAND (decl
, 0)) == COMPONENT_REF
9217 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl
, 0)))
9220 pd
= &TREE_OPERAND (decl
, 0);
9221 decl
= TREE_OPERAND (decl
, 0);
9223 bool indir_p
= false;
9224 tree orig_decl
= decl
;
9225 tree decl_ref
= NULL_TREE
;
9226 if ((region_type
& (ORT_ACC
| ORT_TARGET
| ORT_TARGET_DATA
)) != 0
9227 && TREE_CODE (*pd
) == COMPONENT_REF
9228 && OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ATTACH_DETACH
9229 && code
!= OACC_UPDATE
)
9231 while (TREE_CODE (decl
) == COMPONENT_REF
)
9233 decl
= TREE_OPERAND (decl
, 0);
9234 if (((TREE_CODE (decl
) == MEM_REF
9235 && integer_zerop (TREE_OPERAND (decl
, 1)))
9236 || INDIRECT_REF_P (decl
))
9237 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl
, 0)))
9241 decl
= TREE_OPERAND (decl
, 0);
9243 if (TREE_CODE (decl
) == INDIRECT_REF
9244 && DECL_P (TREE_OPERAND (decl
, 0))
9245 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl
, 0)))
9249 decl
= TREE_OPERAND (decl
, 0);
9253 else if (TREE_CODE (decl
) == COMPONENT_REF
)
9255 while (TREE_CODE (decl
) == COMPONENT_REF
)
9256 decl
= TREE_OPERAND (decl
, 0);
9257 if (TREE_CODE (decl
) == INDIRECT_REF
9258 && DECL_P (TREE_OPERAND (decl
, 0))
9259 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl
, 0)))
9261 decl
= TREE_OPERAND (decl
, 0);
9263 if (decl
!= orig_decl
&& DECL_P (decl
) && indir_p
)
9266 = ((code
== OACC_EXIT_DATA
|| code
== OMP_TARGET_EXIT_DATA
)
9267 ? GOMP_MAP_DETACH
: GOMP_MAP_ATTACH
);
9268 /* We have a dereference of a struct member. Make this an
9269 attach/detach operation, and ensure the base pointer is
9270 mapped as a FIRSTPRIVATE_POINTER. */
9271 OMP_CLAUSE_SET_MAP_KIND (c
, k
);
9272 flags
= GOVD_MAP
| GOVD_SEEN
| GOVD_EXPLICIT
;
9273 tree next_clause
= OMP_CLAUSE_CHAIN (c
);
9274 if (k
== GOMP_MAP_ATTACH
9275 && code
!= OACC_ENTER_DATA
9276 && code
!= OMP_TARGET_ENTER_DATA
9278 || (OMP_CLAUSE_CODE (next_clause
) != OMP_CLAUSE_MAP
)
9279 || (OMP_CLAUSE_MAP_KIND (next_clause
)
9280 != GOMP_MAP_POINTER
)
9281 || OMP_CLAUSE_DECL (next_clause
) != decl
)
9282 && (!struct_deref_set
9283 || !struct_deref_set
->contains (decl
)))
9285 if (!struct_deref_set
)
9286 struct_deref_set
= new hash_set
<tree
> ();
9287 /* As well as the attach, we also need a
9288 FIRSTPRIVATE_POINTER clause to properly map the
9289 pointer to the struct base. */
9290 tree c2
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
9292 OMP_CLAUSE_SET_MAP_KIND (c2
, GOMP_MAP_ALLOC
);
9293 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (c2
)
9296 = build_int_cst (build_pointer_type (char_type_node
),
9298 OMP_CLAUSE_DECL (c2
)
9299 = build2 (MEM_REF
, char_type_node
,
9300 decl_ref
? decl_ref
: decl
, charptr_zero
);
9301 OMP_CLAUSE_SIZE (c2
) = size_zero_node
;
9302 tree c3
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
9304 OMP_CLAUSE_SET_MAP_KIND (c3
,
9305 GOMP_MAP_FIRSTPRIVATE_POINTER
);
9306 OMP_CLAUSE_DECL (c3
) = decl
;
9307 OMP_CLAUSE_SIZE (c3
) = size_zero_node
;
9308 tree mapgrp
= *prev_list_p
;
9310 OMP_CLAUSE_CHAIN (c3
) = mapgrp
;
9311 OMP_CLAUSE_CHAIN (c2
) = c3
;
9313 struct_deref_set
->add (decl
);
9317 /* An "attach/detach" operation on an update directive should
9318 behave as a GOMP_MAP_ALWAYS_POINTER. Beware that
9319 unlike attach or detach map kinds, GOMP_MAP_ALWAYS_POINTER
9320 depends on the previous mapping. */
9321 if (code
== OACC_UPDATE
9322 && OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ATTACH_DETACH
)
9323 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_ALWAYS_POINTER
);
9325 && OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_TO_PSET
9326 && OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_ATTACH
9327 && OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_DETACH
9328 && code
!= OACC_UPDATE
9329 && code
!= OMP_TARGET_UPDATE
)
9331 if (error_operand_p (decl
))
9337 tree stype
= TREE_TYPE (decl
);
9338 if (TREE_CODE (stype
) == REFERENCE_TYPE
)
9339 stype
= TREE_TYPE (stype
);
9340 if (TYPE_SIZE_UNIT (stype
) == NULL
9341 || TREE_CODE (TYPE_SIZE_UNIT (stype
)) != INTEGER_CST
)
9343 error_at (OMP_CLAUSE_LOCATION (c
),
9344 "mapping field %qE of variable length "
9345 "structure", OMP_CLAUSE_DECL (c
));
9350 if (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ALWAYS_POINTER
9351 || OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ATTACH_DETACH
)
9353 /* Error recovery. */
9354 if (prev_list_p
== NULL
)
9359 if (OMP_CLAUSE_CHAIN (*prev_list_p
) != c
)
9361 tree ch
= OMP_CLAUSE_CHAIN (*prev_list_p
);
9362 if (ch
== NULL_TREE
|| OMP_CLAUSE_CHAIN (ch
) != c
)
9370 poly_offset_int offset1
;
9375 = extract_base_bit_offset (OMP_CLAUSE_DECL (c
), &base_ref
,
9376 &bitpos1
, &offset1
);
9378 gcc_assert (base
== decl
);
9381 = splay_tree_lookup (ctx
->variables
, (splay_tree_key
)decl
);
9382 bool ptr
= (OMP_CLAUSE_MAP_KIND (c
)
9383 == GOMP_MAP_ALWAYS_POINTER
);
9384 bool attach_detach
= (OMP_CLAUSE_MAP_KIND (c
)
9385 == GOMP_MAP_ATTACH_DETACH
);
9386 bool attach
= OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ATTACH
9387 || OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_DETACH
;
9388 bool has_attachments
= false;
9389 /* For OpenACC, pointers in structs should trigger an
9392 && ((region_type
& (ORT_ACC
| ORT_TARGET
| ORT_TARGET_DATA
))
9393 || code
== OMP_TARGET_ENTER_DATA
9394 || code
== OMP_TARGET_EXIT_DATA
))
9397 /* Turn a GOMP_MAP_ATTACH_DETACH clause into a
9398 GOMP_MAP_ATTACH or GOMP_MAP_DETACH clause after we
9399 have detected a case that needs a GOMP_MAP_STRUCT
9402 = ((code
== OACC_EXIT_DATA
|| code
== OMP_TARGET_EXIT_DATA
)
9403 ? GOMP_MAP_DETACH
: GOMP_MAP_ATTACH
);
9404 OMP_CLAUSE_SET_MAP_KIND (c
, k
);
9405 has_attachments
= true;
9407 if (n
== NULL
|| (n
->value
& GOVD_MAP
) == 0)
9409 tree l
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
9411 gomp_map_kind k
= attach
? GOMP_MAP_FORCE_PRESENT
9414 OMP_CLAUSE_SET_MAP_KIND (l
, k
);
9416 OMP_CLAUSE_DECL (l
) = unshare_expr (base_ref
);
9418 OMP_CLAUSE_DECL (l
) = decl
;
9422 : DECL_P (OMP_CLAUSE_DECL (l
))
9423 ? DECL_SIZE_UNIT (OMP_CLAUSE_DECL (l
))
9424 : TYPE_SIZE_UNIT (TREE_TYPE (OMP_CLAUSE_DECL (l
))));
9425 if (struct_map_to_clause
== NULL
)
9426 struct_map_to_clause
= new hash_map
<tree
, tree
>;
9427 struct_map_to_clause
->put (decl
, l
);
9428 if (ptr
|| attach_detach
)
9430 insert_struct_comp_map (code
, c
, l
, *prev_list_p
,
9437 OMP_CLAUSE_CHAIN (l
) = c
;
9439 list_p
= &OMP_CLAUSE_CHAIN (l
);
9441 if (base_ref
&& code
== OMP_TARGET
)
9443 tree c2
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
9445 enum gomp_map_kind mkind
9446 = GOMP_MAP_FIRSTPRIVATE_REFERENCE
;
9447 OMP_CLAUSE_SET_MAP_KIND (c2
, mkind
);
9448 OMP_CLAUSE_DECL (c2
) = decl
;
9449 OMP_CLAUSE_SIZE (c2
) = size_zero_node
;
9450 OMP_CLAUSE_CHAIN (c2
) = OMP_CLAUSE_CHAIN (l
);
9451 OMP_CLAUSE_CHAIN (l
) = c2
;
9453 flags
= GOVD_MAP
| GOVD_EXPLICIT
;
9454 if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c
))
9458 if (has_attachments
)
9459 flags
|= GOVD_MAP_HAS_ATTACHMENTS
;
9462 else if (struct_map_to_clause
)
9464 tree
*osc
= struct_map_to_clause
->get (decl
);
9465 tree
*sc
= NULL
, *scp
= NULL
;
9466 if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c
))
9469 n
->value
|= GOVD_SEEN
;
9470 sc
= &OMP_CLAUSE_CHAIN (*osc
);
9472 && (OMP_CLAUSE_MAP_KIND (*sc
)
9473 == GOMP_MAP_FIRSTPRIVATE_REFERENCE
))
9474 sc
= &OMP_CLAUSE_CHAIN (*sc
);
9475 /* Here "prev_list_p" is the end of the inserted
9476 alloc/release nodes after the struct node, OSC. */
9477 for (; *sc
!= c
; sc
= &OMP_CLAUSE_CHAIN (*sc
))
9478 if ((ptr
|| attach_detach
) && sc
== prev_list_p
)
9480 else if (TREE_CODE (OMP_CLAUSE_DECL (*sc
))
9482 && (TREE_CODE (OMP_CLAUSE_DECL (*sc
))
9484 && (TREE_CODE (OMP_CLAUSE_DECL (*sc
))
9489 tree sc_decl
= OMP_CLAUSE_DECL (*sc
);
9490 poly_offset_int offsetn
;
9493 = extract_base_bit_offset (sc_decl
, NULL
,
9494 &bitposn
, &offsetn
);
9499 if ((region_type
& ORT_ACC
) != 0)
9501 /* This duplicate checking code is currently only
9502 enabled for OpenACC. */
9503 tree d1
= OMP_CLAUSE_DECL (*sc
);
9504 tree d2
= OMP_CLAUSE_DECL (c
);
9505 while (TREE_CODE (d1
) == ARRAY_REF
)
9506 d1
= TREE_OPERAND (d1
, 0);
9507 while (TREE_CODE (d2
) == ARRAY_REF
)
9508 d2
= TREE_OPERAND (d2
, 0);
9509 if (TREE_CODE (d1
) == INDIRECT_REF
)
9510 d1
= TREE_OPERAND (d1
, 0);
9511 if (TREE_CODE (d2
) == INDIRECT_REF
)
9512 d2
= TREE_OPERAND (d2
, 0);
9513 while (TREE_CODE (d1
) == COMPONENT_REF
)
9514 if (TREE_CODE (d2
) == COMPONENT_REF
9515 && TREE_OPERAND (d1
, 1)
9516 == TREE_OPERAND (d2
, 1))
9518 d1
= TREE_OPERAND (d1
, 0);
9519 d2
= TREE_OPERAND (d2
, 0);
9525 error_at (OMP_CLAUSE_LOCATION (c
),
9526 "%qE appears more than once in map "
9527 "clauses", OMP_CLAUSE_DECL (c
));
9532 if (maybe_lt (offset1
, offsetn
)
9533 || (known_eq (offset1
, offsetn
)
9534 && maybe_lt (bitpos1
, bitposn
)))
9536 if (ptr
|| attach_detach
)
9545 OMP_CLAUSE_SIZE (*osc
)
9546 = size_binop (PLUS_EXPR
, OMP_CLAUSE_SIZE (*osc
),
9548 if (ptr
|| attach_detach
)
9550 tree cl
= insert_struct_comp_map (code
, c
, NULL
,
9552 if (sc
== prev_list_p
)
9559 *prev_list_p
= OMP_CLAUSE_CHAIN (c
);
9560 list_p
= prev_list_p
;
9562 OMP_CLAUSE_CHAIN (c
) = *sc
;
9569 *list_p
= OMP_CLAUSE_CHAIN (c
);
9570 OMP_CLAUSE_CHAIN (c
) = *sc
;
9576 else if ((code
== OACC_ENTER_DATA
9577 || code
== OACC_EXIT_DATA
9578 || code
== OACC_DATA
9579 || code
== OACC_PARALLEL
9580 || code
== OACC_KERNELS
9581 || code
== OACC_SERIAL
)
9582 && OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ATTACH_DETACH
)
9584 gomp_map_kind k
= (code
== OACC_EXIT_DATA
9585 ? GOMP_MAP_DETACH
: GOMP_MAP_ATTACH
);
9586 OMP_CLAUSE_SET_MAP_KIND (c
, k
);
9589 if (code
== OMP_TARGET
&& OMP_CLAUSE_MAP_IN_REDUCTION (c
))
9591 /* Don't gimplify *pd fully at this point, as the base
9592 will need to be adjusted during omp lowering. */
9593 auto_vec
<tree
, 10> expr_stack
;
9595 while (handled_component_p (*p
)
9596 || TREE_CODE (*p
) == INDIRECT_REF
9597 || TREE_CODE (*p
) == ADDR_EXPR
9598 || TREE_CODE (*p
) == MEM_REF
9599 || TREE_CODE (*p
) == NON_LVALUE_EXPR
)
9601 expr_stack
.safe_push (*p
);
9602 p
= &TREE_OPERAND (*p
, 0);
9604 for (int i
= expr_stack
.length () - 1; i
>= 0; i
--)
9606 tree t
= expr_stack
[i
];
9607 if (TREE_CODE (t
) == ARRAY_REF
9608 || TREE_CODE (t
) == ARRAY_RANGE_REF
)
9610 if (TREE_OPERAND (t
, 2) == NULL_TREE
)
9612 tree low
= unshare_expr (array_ref_low_bound (t
));
9613 if (!is_gimple_min_invariant (low
))
9615 TREE_OPERAND (t
, 2) = low
;
9616 if (gimplify_expr (&TREE_OPERAND (t
, 2),
9619 fb_rvalue
) == GS_ERROR
)
9623 else if (gimplify_expr (&TREE_OPERAND (t
, 2), pre_p
,
9624 NULL
, is_gimple_reg
,
9625 fb_rvalue
) == GS_ERROR
)
9627 if (TREE_OPERAND (t
, 3) == NULL_TREE
)
9629 tree elmt_size
= array_ref_element_size (t
);
9630 if (!is_gimple_min_invariant (elmt_size
))
9632 elmt_size
= unshare_expr (elmt_size
);
9634 = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t
,
9637 = size_int (TYPE_ALIGN_UNIT (elmt_type
));
9639 = size_binop (EXACT_DIV_EXPR
, elmt_size
,
9641 TREE_OPERAND (t
, 3) = elmt_size
;
9642 if (gimplify_expr (&TREE_OPERAND (t
, 3),
9645 fb_rvalue
) == GS_ERROR
)
9649 else if (gimplify_expr (&TREE_OPERAND (t
, 3), pre_p
,
9650 NULL
, is_gimple_reg
,
9651 fb_rvalue
) == GS_ERROR
)
9654 else if (TREE_CODE (t
) == COMPONENT_REF
)
9656 if (TREE_OPERAND (t
, 2) == NULL_TREE
)
9658 tree offset
= component_ref_field_offset (t
);
9659 if (!is_gimple_min_invariant (offset
))
9661 offset
= unshare_expr (offset
);
9662 tree field
= TREE_OPERAND (t
, 1);
9664 = size_int (DECL_OFFSET_ALIGN (field
)
9666 offset
= size_binop (EXACT_DIV_EXPR
, offset
,
9668 TREE_OPERAND (t
, 2) = offset
;
9669 if (gimplify_expr (&TREE_OPERAND (t
, 2),
9672 fb_rvalue
) == GS_ERROR
)
9676 else if (gimplify_expr (&TREE_OPERAND (t
, 2), pre_p
,
9677 NULL
, is_gimple_reg
,
9678 fb_rvalue
) == GS_ERROR
)
9682 for (; expr_stack
.length () > 0; )
9684 tree t
= expr_stack
.pop ();
9686 if (TREE_CODE (t
) == ARRAY_REF
9687 || TREE_CODE (t
) == ARRAY_RANGE_REF
)
9689 if (!is_gimple_min_invariant (TREE_OPERAND (t
, 1))
9690 && gimplify_expr (&TREE_OPERAND (t
, 1), pre_p
,
9691 NULL
, is_gimple_val
,
9692 fb_rvalue
) == GS_ERROR
)
9697 else if (gimplify_expr (pd
, pre_p
, NULL
, is_gimple_lvalue
,
9698 fb_lvalue
) == GS_ERROR
)
9705 && OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_ALWAYS_POINTER
9706 && OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_ATTACH_DETACH
9707 && OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_TO_PSET
9708 && OMP_CLAUSE_CHAIN (c
)
9709 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (c
)) == OMP_CLAUSE_MAP
9710 && ((OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c
))
9711 == GOMP_MAP_ALWAYS_POINTER
)
9712 || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c
))
9713 == GOMP_MAP_ATTACH_DETACH
)
9714 || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c
))
9715 == GOMP_MAP_TO_PSET
)))
9716 prev_list_p
= list_p
;
9722 /* DECL_P (decl) == true */
9724 if (struct_map_to_clause
9725 && (sc
= struct_map_to_clause
->get (decl
)) != NULL
9726 && OMP_CLAUSE_MAP_KIND (*sc
) == GOMP_MAP_STRUCT
9727 && decl
== OMP_CLAUSE_DECL (*sc
))
9729 /* We have found a map of the whole structure after a
9730 leading GOMP_MAP_STRUCT has been created, so refill the
9731 leading clause into a map of the whole structure
9732 variable, and remove the current one.
9733 TODO: we should be able to remove some maps of the
9734 following structure element maps if they are of
9735 compatible TO/FROM/ALLOC type. */
9736 OMP_CLAUSE_SET_MAP_KIND (*sc
, OMP_CLAUSE_MAP_KIND (c
));
9737 OMP_CLAUSE_SIZE (*sc
) = unshare_expr (OMP_CLAUSE_SIZE (c
));
9742 flags
= GOVD_MAP
| GOVD_EXPLICIT
;
9743 if (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ALWAYS_TO
9744 || OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ALWAYS_TOFROM
)
9745 flags
|= GOVD_MAP_ALWAYS_TO
;
9747 if ((code
== OMP_TARGET
9748 || code
== OMP_TARGET_DATA
9749 || code
== OMP_TARGET_ENTER_DATA
9750 || code
== OMP_TARGET_EXIT_DATA
)
9751 && OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ATTACH_DETACH
)
9753 for (struct gimplify_omp_ctx
*octx
= outer_ctx
; octx
;
9754 octx
= octx
->outer_context
)
9757 = splay_tree_lookup (octx
->variables
,
9758 (splay_tree_key
) OMP_CLAUSE_DECL (c
));
9759 /* If this is contained in an outer OpenMP region as a
9760 firstprivate value, remove the attach/detach. */
9761 if (n
&& (n
->value
& GOVD_FIRSTPRIVATE
))
9763 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_FIRSTPRIVATE_POINTER
);
9768 enum gomp_map_kind map_kind
= (code
== OMP_TARGET_EXIT_DATA
9771 OMP_CLAUSE_SET_MAP_KIND (c
, map_kind
);
9776 case OMP_CLAUSE_AFFINITY
:
9777 gimplify_omp_affinity (list_p
, pre_p
);
9780 case OMP_CLAUSE_DEPEND
:
9781 if (OMP_CLAUSE_DEPEND_KIND (c
) == OMP_CLAUSE_DEPEND_SINK
)
9783 tree deps
= OMP_CLAUSE_DECL (c
);
9784 while (deps
&& TREE_CODE (deps
) == TREE_LIST
)
9786 if (TREE_CODE (TREE_PURPOSE (deps
)) == TRUNC_DIV_EXPR
9787 && DECL_P (TREE_OPERAND (TREE_PURPOSE (deps
), 1)))
9788 gimplify_expr (&TREE_OPERAND (TREE_PURPOSE (deps
), 1),
9789 pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
9790 deps
= TREE_CHAIN (deps
);
9794 else if (OMP_CLAUSE_DEPEND_KIND (c
) == OMP_CLAUSE_DEPEND_SOURCE
)
9796 if (handled_depend_iterators
== -1)
9797 handled_depend_iterators
= gimplify_omp_depend (list_p
, pre_p
);
9798 if (handled_depend_iterators
)
9800 if (handled_depend_iterators
== 2)
9804 if (TREE_CODE (OMP_CLAUSE_DECL (c
)) == COMPOUND_EXPR
)
9806 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c
), 0), pre_p
,
9807 NULL
, is_gimple_val
, fb_rvalue
);
9808 OMP_CLAUSE_DECL (c
) = TREE_OPERAND (OMP_CLAUSE_DECL (c
), 1);
9810 if (error_operand_p (OMP_CLAUSE_DECL (c
)))
9815 OMP_CLAUSE_DECL (c
) = build_fold_addr_expr (OMP_CLAUSE_DECL (c
));
9816 if (gimplify_expr (&OMP_CLAUSE_DECL (c
), pre_p
, NULL
,
9817 is_gimple_val
, fb_rvalue
) == GS_ERROR
)
9822 if (code
== OMP_TASK
)
9823 ctx
->has_depend
= true;
9827 case OMP_CLAUSE_FROM
:
9828 case OMP_CLAUSE__CACHE_
:
9829 decl
= OMP_CLAUSE_DECL (c
);
9830 if (error_operand_p (decl
))
9835 if (OMP_CLAUSE_SIZE (c
) == NULL_TREE
)
9836 OMP_CLAUSE_SIZE (c
) = DECL_P (decl
) ? DECL_SIZE_UNIT (decl
)
9837 : TYPE_SIZE_UNIT (TREE_TYPE (decl
));
9838 if (gimplify_expr (&OMP_CLAUSE_SIZE (c
), pre_p
,
9839 NULL
, is_gimple_val
, fb_rvalue
) == GS_ERROR
)
9846 if (gimplify_expr (&OMP_CLAUSE_DECL (c
), pre_p
,
9847 NULL
, is_gimple_lvalue
, fb_lvalue
)
9857 case OMP_CLAUSE_USE_DEVICE_PTR
:
9858 case OMP_CLAUSE_USE_DEVICE_ADDR
:
9859 flags
= GOVD_EXPLICIT
;
9862 case OMP_CLAUSE_IS_DEVICE_PTR
:
9863 flags
= GOVD_FIRSTPRIVATE
| GOVD_EXPLICIT
;
9867 decl
= OMP_CLAUSE_DECL (c
);
9869 if (error_operand_p (decl
))
9874 if (DECL_NAME (decl
) == NULL_TREE
&& (flags
& GOVD_SHARED
) == 0)
9876 tree t
= omp_member_access_dummy_var (decl
);
9879 tree v
= DECL_VALUE_EXPR (decl
);
9880 DECL_NAME (decl
) = DECL_NAME (TREE_OPERAND (v
, 1));
9882 omp_notice_variable (outer_ctx
, t
, true);
9885 if (code
== OACC_DATA
9886 && OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_MAP
9887 && OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_FIRSTPRIVATE_POINTER
)
9888 flags
|= GOVD_MAP_0LEN_ARRAY
;
9889 omp_add_variable (ctx
, decl
, flags
);
9890 if ((OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
9891 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_IN_REDUCTION
9892 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_TASK_REDUCTION
)
9893 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
))
9895 struct gimplify_omp_ctx
*pctx
9896 = code
== OMP_TARGET
? outer_ctx
: ctx
;
9898 omp_add_variable (pctx
, OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
),
9899 GOVD_LOCAL
| GOVD_SEEN
);
9901 && OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c
)
9902 && walk_tree (&OMP_CLAUSE_REDUCTION_INIT (c
),
9904 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c
),
9906 omp_add_variable (pctx
,
9907 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c
),
9908 GOVD_LOCAL
| GOVD_SEEN
);
9909 gimplify_omp_ctxp
= pctx
;
9910 push_gimplify_context ();
9912 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c
) = NULL
;
9913 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c
) = NULL
;
9915 gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c
),
9916 &OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c
));
9917 pop_gimplify_context
9918 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c
)));
9919 push_gimplify_context ();
9920 gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c
),
9921 &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c
));
9922 pop_gimplify_context
9923 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c
)));
9924 OMP_CLAUSE_REDUCTION_INIT (c
) = NULL_TREE
;
9925 OMP_CLAUSE_REDUCTION_MERGE (c
) = NULL_TREE
;
9927 gimplify_omp_ctxp
= outer_ctx
;
9929 else if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
9930 && OMP_CLAUSE_LASTPRIVATE_STMT (c
))
9932 gimplify_omp_ctxp
= ctx
;
9933 push_gimplify_context ();
9934 if (TREE_CODE (OMP_CLAUSE_LASTPRIVATE_STMT (c
)) != BIND_EXPR
)
9936 tree bind
= build3 (BIND_EXPR
, void_type_node
, NULL
,
9938 TREE_SIDE_EFFECTS (bind
) = 1;
9939 BIND_EXPR_BODY (bind
) = OMP_CLAUSE_LASTPRIVATE_STMT (c
);
9940 OMP_CLAUSE_LASTPRIVATE_STMT (c
) = bind
;
9942 gimplify_and_add (OMP_CLAUSE_LASTPRIVATE_STMT (c
),
9943 &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
));
9944 pop_gimplify_context
9945 (gimple_seq_first_stmt (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
)));
9946 OMP_CLAUSE_LASTPRIVATE_STMT (c
) = NULL_TREE
;
9948 gimplify_omp_ctxp
= outer_ctx
;
9950 else if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINEAR
9951 && OMP_CLAUSE_LINEAR_STMT (c
))
9953 gimplify_omp_ctxp
= ctx
;
9954 push_gimplify_context ();
9955 if (TREE_CODE (OMP_CLAUSE_LINEAR_STMT (c
)) != BIND_EXPR
)
9957 tree bind
= build3 (BIND_EXPR
, void_type_node
, NULL
,
9959 TREE_SIDE_EFFECTS (bind
) = 1;
9960 BIND_EXPR_BODY (bind
) = OMP_CLAUSE_LINEAR_STMT (c
);
9961 OMP_CLAUSE_LINEAR_STMT (c
) = bind
;
9963 gimplify_and_add (OMP_CLAUSE_LINEAR_STMT (c
),
9964 &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c
));
9965 pop_gimplify_context
9966 (gimple_seq_first_stmt (OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c
)));
9967 OMP_CLAUSE_LINEAR_STMT (c
) = NULL_TREE
;
9969 gimplify_omp_ctxp
= outer_ctx
;
9975 case OMP_CLAUSE_COPYIN
:
9976 case OMP_CLAUSE_COPYPRIVATE
:
9977 decl
= OMP_CLAUSE_DECL (c
);
9978 if (error_operand_p (decl
))
9983 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_COPYPRIVATE
9985 && !omp_check_private (ctx
, decl
, true))
9988 if (is_global_var (decl
))
9990 if (DECL_THREAD_LOCAL_P (decl
))
9992 else if (DECL_HAS_VALUE_EXPR_P (decl
))
9994 tree value
= get_base_address (DECL_VALUE_EXPR (decl
));
9998 && DECL_THREAD_LOCAL_P (value
))
10003 error_at (OMP_CLAUSE_LOCATION (c
),
10004 "copyprivate variable %qE is not threadprivate"
10005 " or private in outer context", DECL_NAME (decl
));
10008 if ((OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
10009 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_FIRSTPRIVATE
10010 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
)
10012 && ((region_type
& ORT_TASKLOOP
) == ORT_TASKLOOP
10013 || (region_type
== ORT_WORKSHARE
10014 && OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
10015 && (OMP_CLAUSE_REDUCTION_INSCAN (c
)
10016 || code
== OMP_LOOP
)))
10017 && (outer_ctx
->region_type
== ORT_COMBINED_PARALLEL
10018 || (code
== OMP_LOOP
10019 && OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
10020 && ((outer_ctx
->region_type
& ORT_COMBINED_TEAMS
)
10021 == ORT_COMBINED_TEAMS
))))
10024 = splay_tree_lookup (outer_ctx
->variables
,
10025 (splay_tree_key
)decl
);
10026 if (on
== NULL
|| (on
->value
& GOVD_DATA_SHARE_CLASS
) == 0)
10028 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
10029 && TREE_CODE (OMP_CLAUSE_DECL (c
)) == MEM_REF
10030 && (TREE_CODE (TREE_TYPE (decl
)) == POINTER_TYPE
10031 || (TREE_CODE (TREE_TYPE (decl
)) == REFERENCE_TYPE
10032 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl
)))
10033 == POINTER_TYPE
))))
10034 omp_firstprivatize_variable (outer_ctx
, decl
);
10037 omp_add_variable (outer_ctx
, decl
,
10038 GOVD_SEEN
| GOVD_SHARED
);
10039 if (outer_ctx
->outer_context
)
10040 omp_notice_variable (outer_ctx
->outer_context
, decl
,
10046 omp_notice_variable (outer_ctx
, decl
, true);
10047 if (check_non_private
10048 && region_type
== ORT_WORKSHARE
10049 && (OMP_CLAUSE_CODE (c
) != OMP_CLAUSE_REDUCTION
10050 || decl
== OMP_CLAUSE_DECL (c
)
10051 || (TREE_CODE (OMP_CLAUSE_DECL (c
)) == MEM_REF
10052 && (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c
), 0))
10054 || (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c
), 0))
10055 == POINTER_PLUS_EXPR
10056 && (TREE_CODE (TREE_OPERAND (TREE_OPERAND
10057 (OMP_CLAUSE_DECL (c
), 0), 0))
10059 && omp_check_private (ctx
, decl
, false))
10061 error ("%s variable %qE is private in outer context",
10062 check_non_private
, DECL_NAME (decl
));
10067 case OMP_CLAUSE_DETACH
:
10068 flags
= GOVD_FIRSTPRIVATE
| GOVD_SEEN
;
10071 case OMP_CLAUSE_IF
:
10072 if (OMP_CLAUSE_IF_MODIFIER (c
) != ERROR_MARK
10073 && OMP_CLAUSE_IF_MODIFIER (c
) != code
)
10076 for (int i
= 0; i
< 2; i
++)
10077 switch (i
? OMP_CLAUSE_IF_MODIFIER (c
) : code
)
10079 case VOID_CST
: p
[i
] = "cancel"; break;
10080 case OMP_PARALLEL
: p
[i
] = "parallel"; break;
10081 case OMP_SIMD
: p
[i
] = "simd"; break;
10082 case OMP_TASK
: p
[i
] = "task"; break;
10083 case OMP_TASKLOOP
: p
[i
] = "taskloop"; break;
10084 case OMP_TARGET_DATA
: p
[i
] = "target data"; break;
10085 case OMP_TARGET
: p
[i
] = "target"; break;
10086 case OMP_TARGET_UPDATE
: p
[i
] = "target update"; break;
10087 case OMP_TARGET_ENTER_DATA
:
10088 p
[i
] = "target enter data"; break;
10089 case OMP_TARGET_EXIT_DATA
: p
[i
] = "target exit data"; break;
10090 default: gcc_unreachable ();
10092 error_at (OMP_CLAUSE_LOCATION (c
),
10093 "expected %qs %<if%> clause modifier rather than %qs",
10097 /* Fall through. */
10099 case OMP_CLAUSE_FINAL
:
10100 OMP_CLAUSE_OPERAND (c
, 0)
10101 = gimple_boolify (OMP_CLAUSE_OPERAND (c
, 0));
10102 /* Fall through. */
10104 case OMP_CLAUSE_SCHEDULE
:
10105 case OMP_CLAUSE_NUM_THREADS
:
10106 case OMP_CLAUSE_NUM_TEAMS
:
10107 case OMP_CLAUSE_THREAD_LIMIT
:
10108 case OMP_CLAUSE_DIST_SCHEDULE
:
10109 case OMP_CLAUSE_DEVICE
:
10110 case OMP_CLAUSE_PRIORITY
:
10111 case OMP_CLAUSE_GRAINSIZE
:
10112 case OMP_CLAUSE_NUM_TASKS
:
10113 case OMP_CLAUSE_FILTER
:
10114 case OMP_CLAUSE_HINT
:
10115 case OMP_CLAUSE_ASYNC
:
10116 case OMP_CLAUSE_WAIT
:
10117 case OMP_CLAUSE_NUM_GANGS
:
10118 case OMP_CLAUSE_NUM_WORKERS
:
10119 case OMP_CLAUSE_VECTOR_LENGTH
:
10120 case OMP_CLAUSE_WORKER
:
10121 case OMP_CLAUSE_VECTOR
:
10122 if (OMP_CLAUSE_OPERAND (c
, 0)
10123 && !is_gimple_min_invariant (OMP_CLAUSE_OPERAND (c
, 0)))
10125 if (error_operand_p (OMP_CLAUSE_OPERAND (c
, 0)))
10130 /* All these clauses care about value, not a particular decl,
10131 so try to force it into a SSA_NAME or fresh temporary. */
10132 OMP_CLAUSE_OPERAND (c
, 0)
10133 = get_initialized_tmp_var (OMP_CLAUSE_OPERAND (c
, 0),
10134 pre_p
, NULL
, true);
10138 case OMP_CLAUSE_GANG
:
10139 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c
, 0), pre_p
, NULL
,
10140 is_gimple_val
, fb_rvalue
) == GS_ERROR
)
10142 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c
, 1), pre_p
, NULL
,
10143 is_gimple_val
, fb_rvalue
) == GS_ERROR
)
10147 case OMP_CLAUSE_NOWAIT
:
10151 case OMP_CLAUSE_ORDERED
:
10152 case OMP_CLAUSE_UNTIED
:
10153 case OMP_CLAUSE_COLLAPSE
:
10154 case OMP_CLAUSE_TILE
:
10155 case OMP_CLAUSE_AUTO
:
10156 case OMP_CLAUSE_SEQ
:
10157 case OMP_CLAUSE_INDEPENDENT
:
10158 case OMP_CLAUSE_MERGEABLE
:
10159 case OMP_CLAUSE_PROC_BIND
:
10160 case OMP_CLAUSE_SAFELEN
:
10161 case OMP_CLAUSE_SIMDLEN
:
10162 case OMP_CLAUSE_NOGROUP
:
10163 case OMP_CLAUSE_THREADS
:
10164 case OMP_CLAUSE_SIMD
:
10165 case OMP_CLAUSE_BIND
:
10166 case OMP_CLAUSE_IF_PRESENT
:
10167 case OMP_CLAUSE_FINALIZE
:
10170 case OMP_CLAUSE_ORDER
:
10171 ctx
->order_concurrent
= true;
10174 case OMP_CLAUSE_DEFAULTMAP
:
10175 enum gimplify_defaultmap_kind gdmkmin
, gdmkmax
;
10176 switch (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
))
10178 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
:
10179 gdmkmin
= GDMK_SCALAR
;
10180 gdmkmax
= GDMK_POINTER
;
10182 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR
:
10183 gdmkmin
= GDMK_SCALAR
;
10184 gdmkmax
= GDMK_SCALAR_TARGET
;
10186 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE
:
10187 gdmkmin
= gdmkmax
= GDMK_AGGREGATE
;
10189 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALLOCATABLE
:
10190 gdmkmin
= gdmkmax
= GDMK_ALLOCATABLE
;
10192 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER
:
10193 gdmkmin
= gdmkmax
= GDMK_POINTER
;
10196 gcc_unreachable ();
10198 for (int gdmk
= gdmkmin
; gdmk
<= gdmkmax
; gdmk
++)
10199 switch (OMP_CLAUSE_DEFAULTMAP_BEHAVIOR (c
))
10201 case OMP_CLAUSE_DEFAULTMAP_ALLOC
:
10202 ctx
->defaultmap
[gdmk
] = GOVD_MAP
| GOVD_MAP_ALLOC_ONLY
;
10204 case OMP_CLAUSE_DEFAULTMAP_TO
:
10205 ctx
->defaultmap
[gdmk
] = GOVD_MAP
| GOVD_MAP_TO_ONLY
;
10207 case OMP_CLAUSE_DEFAULTMAP_FROM
:
10208 ctx
->defaultmap
[gdmk
] = GOVD_MAP
| GOVD_MAP_FROM_ONLY
;
10210 case OMP_CLAUSE_DEFAULTMAP_TOFROM
:
10211 ctx
->defaultmap
[gdmk
] = GOVD_MAP
;
10213 case OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE
:
10214 ctx
->defaultmap
[gdmk
] = GOVD_FIRSTPRIVATE
;
10216 case OMP_CLAUSE_DEFAULTMAP_NONE
:
10217 ctx
->defaultmap
[gdmk
] = 0;
10219 case OMP_CLAUSE_DEFAULTMAP_DEFAULT
:
10223 ctx
->defaultmap
[gdmk
] = GOVD_FIRSTPRIVATE
;
10225 case GDMK_SCALAR_TARGET
:
10226 ctx
->defaultmap
[gdmk
] = (lang_GNU_Fortran ()
10227 ? GOVD_MAP
: GOVD_FIRSTPRIVATE
);
10229 case GDMK_AGGREGATE
:
10230 case GDMK_ALLOCATABLE
:
10231 ctx
->defaultmap
[gdmk
] = GOVD_MAP
;
10234 ctx
->defaultmap
[gdmk
] = GOVD_MAP
;
10235 if (!lang_GNU_Fortran ())
10236 ctx
->defaultmap
[gdmk
] |= GOVD_MAP_0LEN_ARRAY
;
10239 gcc_unreachable ();
10243 gcc_unreachable ();
10247 case OMP_CLAUSE_ALIGNED
:
10248 decl
= OMP_CLAUSE_DECL (c
);
10249 if (error_operand_p (decl
))
10254 if (gimplify_expr (&OMP_CLAUSE_ALIGNED_ALIGNMENT (c
), pre_p
, NULL
,
10255 is_gimple_val
, fb_rvalue
) == GS_ERROR
)
10260 if (!is_global_var (decl
)
10261 && TREE_CODE (TREE_TYPE (decl
)) == POINTER_TYPE
)
10262 omp_add_variable (ctx
, decl
, GOVD_ALIGNED
);
10265 case OMP_CLAUSE_NONTEMPORAL
:
10266 decl
= OMP_CLAUSE_DECL (c
);
10267 if (error_operand_p (decl
))
10272 omp_add_variable (ctx
, decl
, GOVD_NONTEMPORAL
);
10275 case OMP_CLAUSE_ALLOCATE
:
10276 decl
= OMP_CLAUSE_DECL (c
);
10277 if (error_operand_p (decl
))
10282 if (gimplify_expr (&OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
), pre_p
, NULL
,
10283 is_gimple_val
, fb_rvalue
) == GS_ERROR
)
10288 else if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
) == NULL_TREE
10289 || (TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
))
10292 else if (code
== OMP_TASKLOOP
10293 || !DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
)))
10294 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
)
10295 = get_initialized_tmp_var (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
),
10296 pre_p
, NULL
, false);
10299 case OMP_CLAUSE_DEFAULT
:
10300 ctx
->default_kind
= OMP_CLAUSE_DEFAULT_KIND (c
);
10303 case OMP_CLAUSE_INCLUSIVE
:
10304 case OMP_CLAUSE_EXCLUSIVE
:
10305 decl
= OMP_CLAUSE_DECL (c
);
10307 splay_tree_node n
= splay_tree_lookup (outer_ctx
->variables
,
10308 (splay_tree_key
) decl
);
10309 if (n
== NULL
|| (n
->value
& GOVD_REDUCTION
) == 0)
10311 error_at (OMP_CLAUSE_LOCATION (c
),
10312 "%qD specified in %qs clause but not in %<inscan%> "
10313 "%<reduction%> clause on the containing construct",
10314 decl
, omp_clause_code_name
[OMP_CLAUSE_CODE (c
)]);
10319 n
->value
|= GOVD_REDUCTION_INSCAN
;
10320 if (outer_ctx
->region_type
== ORT_SIMD
10321 && outer_ctx
->outer_context
10322 && outer_ctx
->outer_context
->region_type
== ORT_WORKSHARE
)
10324 n
= splay_tree_lookup (outer_ctx
->outer_context
->variables
,
10325 (splay_tree_key
) decl
);
10326 if (n
&& (n
->value
& GOVD_REDUCTION
) != 0)
10327 n
->value
|= GOVD_REDUCTION_INSCAN
;
10333 case OMP_CLAUSE_NOHOST
:
10335 gcc_unreachable ();
10338 if (code
== OACC_DATA
10339 && OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_MAP
10340 && (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_FIRSTPRIVATE_POINTER
10341 || OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
))
10344 *list_p
= OMP_CLAUSE_CHAIN (c
);
10346 list_p
= &OMP_CLAUSE_CHAIN (c
);
10349 ctx
->clauses
= *orig_list_p
;
10350 gimplify_omp_ctxp
= ctx
;
10351 if (struct_map_to_clause
)
10352 delete struct_map_to_clause
;
10353 if (struct_deref_set
)
10354 delete struct_deref_set
;
10357 /* Return true if DECL is a candidate for shared to firstprivate
10358 optimization. We only consider non-addressable scalars, not
10359 too big, and not references. */
10362 omp_shared_to_firstprivate_optimizable_decl_p (tree decl
)
10364 if (TREE_ADDRESSABLE (decl
))
10366 tree type
= TREE_TYPE (decl
);
10367 if (!is_gimple_reg_type (type
)
10368 || TREE_CODE (type
) == REFERENCE_TYPE
10369 || TREE_ADDRESSABLE (type
))
10371 /* Don't optimize too large decls, as each thread/task will have
10373 HOST_WIDE_INT len
= int_size_in_bytes (type
);
10374 if (len
== -1 || len
> 4 * POINTER_SIZE
/ BITS_PER_UNIT
)
10376 if (lang_hooks
.decls
.omp_privatize_by_reference (decl
))
10381 /* Helper function of omp_find_stores_op and gimplify_adjust_omp_clauses*.
10382 For omp_shared_to_firstprivate_optimizable_decl_p decl mark it as
10383 GOVD_WRITTEN in outer contexts. */
10386 omp_mark_stores (struct gimplify_omp_ctx
*ctx
, tree decl
)
10388 for (; ctx
; ctx
= ctx
->outer_context
)
10390 splay_tree_node n
= splay_tree_lookup (ctx
->variables
,
10391 (splay_tree_key
) decl
);
10394 else if (n
->value
& GOVD_SHARED
)
10396 n
->value
|= GOVD_WRITTEN
;
10399 else if (n
->value
& GOVD_DATA_SHARE_CLASS
)
10404 /* Helper callback for walk_gimple_seq to discover possible stores
10405 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
10406 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
10410 omp_find_stores_op (tree
*tp
, int *walk_subtrees
, void *data
)
10412 struct walk_stmt_info
*wi
= (struct walk_stmt_info
*) data
;
10414 *walk_subtrees
= 0;
10421 if (handled_component_p (op
))
10422 op
= TREE_OPERAND (op
, 0);
10423 else if ((TREE_CODE (op
) == MEM_REF
|| TREE_CODE (op
) == TARGET_MEM_REF
)
10424 && TREE_CODE (TREE_OPERAND (op
, 0)) == ADDR_EXPR
)
10425 op
= TREE_OPERAND (TREE_OPERAND (op
, 0), 0);
10430 if (!DECL_P (op
) || !omp_shared_to_firstprivate_optimizable_decl_p (op
))
10433 omp_mark_stores (gimplify_omp_ctxp
, op
);
10437 /* Helper callback for walk_gimple_seq to discover possible stores
10438 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
10439 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
10443 omp_find_stores_stmt (gimple_stmt_iterator
*gsi_p
,
10444 bool *handled_ops_p
,
10445 struct walk_stmt_info
*wi
)
10447 gimple
*stmt
= gsi_stmt (*gsi_p
);
10448 switch (gimple_code (stmt
))
10450 /* Don't recurse on OpenMP constructs for which
10451 gimplify_adjust_omp_clauses already handled the bodies,
10452 except handle gimple_omp_for_pre_body. */
10453 case GIMPLE_OMP_FOR
:
10454 *handled_ops_p
= true;
10455 if (gimple_omp_for_pre_body (stmt
))
10456 walk_gimple_seq (gimple_omp_for_pre_body (stmt
),
10457 omp_find_stores_stmt
, omp_find_stores_op
, wi
);
10459 case GIMPLE_OMP_PARALLEL
:
10460 case GIMPLE_OMP_TASK
:
10461 case GIMPLE_OMP_SECTIONS
:
10462 case GIMPLE_OMP_SINGLE
:
10463 case GIMPLE_OMP_SCOPE
:
10464 case GIMPLE_OMP_TARGET
:
10465 case GIMPLE_OMP_TEAMS
:
10466 case GIMPLE_OMP_CRITICAL
:
10467 *handled_ops_p
= true;
10475 struct gimplify_adjust_omp_clauses_data
10481 /* For all variables that were not actually used within the context,
10482 remove PRIVATE, SHARED, and FIRSTPRIVATE clauses. */
10485 gimplify_adjust_omp_clauses_1 (splay_tree_node n
, void *data
)
10487 tree
*list_p
= ((struct gimplify_adjust_omp_clauses_data
*) data
)->list_p
;
10489 = ((struct gimplify_adjust_omp_clauses_data
*) data
)->pre_p
;
10490 tree decl
= (tree
) n
->key
;
10491 unsigned flags
= n
->value
;
10492 enum omp_clause_code code
;
10494 bool private_debug
;
10496 if (gimplify_omp_ctxp
->region_type
== ORT_COMBINED_PARALLEL
10497 && (flags
& GOVD_LASTPRIVATE_CONDITIONAL
) != 0)
10498 flags
= GOVD_SHARED
| GOVD_SEEN
| GOVD_WRITTEN
;
10499 if (flags
& (GOVD_EXPLICIT
| GOVD_LOCAL
))
10501 if ((flags
& GOVD_SEEN
) == 0)
10503 if ((flags
& GOVD_MAP_HAS_ATTACHMENTS
) != 0)
10505 if (flags
& GOVD_DEBUG_PRIVATE
)
10507 gcc_assert ((flags
& GOVD_DATA_SHARE_CLASS
) == GOVD_SHARED
);
10508 private_debug
= true;
10510 else if (flags
& GOVD_MAP
)
10511 private_debug
= false;
10514 = lang_hooks
.decls
.omp_private_debug_clause (decl
,
10515 !!(flags
& GOVD_SHARED
));
10517 code
= OMP_CLAUSE_PRIVATE
;
10518 else if (flags
& GOVD_MAP
)
10520 code
= OMP_CLAUSE_MAP
;
10521 if ((gimplify_omp_ctxp
->region_type
& ORT_ACC
) == 0
10522 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl
))))
10524 error ("%<_Atomic%> %qD in implicit %<map%> clause", decl
);
10528 && DECL_IN_CONSTANT_POOL (decl
)
10529 && !lookup_attribute ("omp declare target",
10530 DECL_ATTRIBUTES (decl
)))
10532 tree id
= get_identifier ("omp declare target");
10533 DECL_ATTRIBUTES (decl
)
10534 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (decl
));
10535 varpool_node
*node
= varpool_node::get (decl
);
10538 node
->offloadable
= 1;
10539 if (ENABLE_OFFLOADING
)
10540 g
->have_offload
= true;
10544 else if (flags
& GOVD_SHARED
)
10546 if (is_global_var (decl
))
10548 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
->outer_context
;
10549 while (ctx
!= NULL
)
10552 = splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
10553 if (on
&& (on
->value
& (GOVD_FIRSTPRIVATE
| GOVD_LASTPRIVATE
10554 | GOVD_PRIVATE
| GOVD_REDUCTION
10555 | GOVD_LINEAR
| GOVD_MAP
)) != 0)
10557 ctx
= ctx
->outer_context
;
10562 code
= OMP_CLAUSE_SHARED
;
10563 /* Don't optimize shared into firstprivate for read-only vars
10564 on tasks with depend clause, we shouldn't try to copy them
10565 until the dependencies are satisfied. */
10566 if (gimplify_omp_ctxp
->has_depend
)
10567 flags
|= GOVD_WRITTEN
;
10569 else if (flags
& GOVD_PRIVATE
)
10570 code
= OMP_CLAUSE_PRIVATE
;
10571 else if (flags
& GOVD_FIRSTPRIVATE
)
10573 code
= OMP_CLAUSE_FIRSTPRIVATE
;
10574 if ((gimplify_omp_ctxp
->region_type
& ORT_TARGET
)
10575 && (gimplify_omp_ctxp
->region_type
& ORT_ACC
) == 0
10576 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl
))))
10578 error ("%<_Atomic%> %qD in implicit %<firstprivate%> clause on "
10579 "%<target%> construct", decl
);
10583 else if (flags
& GOVD_LASTPRIVATE
)
10584 code
= OMP_CLAUSE_LASTPRIVATE
;
10585 else if (flags
& (GOVD_ALIGNED
| GOVD_NONTEMPORAL
))
10587 else if (flags
& GOVD_CONDTEMP
)
10589 code
= OMP_CLAUSE__CONDTEMP_
;
10590 gimple_add_tmp_var (decl
);
10593 gcc_unreachable ();
10595 if (((flags
& GOVD_LASTPRIVATE
)
10596 || (code
== OMP_CLAUSE_SHARED
&& (flags
& GOVD_WRITTEN
)))
10597 && omp_shared_to_firstprivate_optimizable_decl_p (decl
))
10598 omp_mark_stores (gimplify_omp_ctxp
->outer_context
, decl
);
10600 tree chain
= *list_p
;
10601 clause
= build_omp_clause (input_location
, code
);
10602 OMP_CLAUSE_DECL (clause
) = decl
;
10603 OMP_CLAUSE_CHAIN (clause
) = chain
;
10605 OMP_CLAUSE_PRIVATE_DEBUG (clause
) = 1;
10606 else if (code
== OMP_CLAUSE_PRIVATE
&& (flags
& GOVD_PRIVATE_OUTER_REF
))
10607 OMP_CLAUSE_PRIVATE_OUTER_REF (clause
) = 1;
10608 else if (code
== OMP_CLAUSE_SHARED
10609 && (flags
& GOVD_WRITTEN
) == 0
10610 && omp_shared_to_firstprivate_optimizable_decl_p (decl
))
10611 OMP_CLAUSE_SHARED_READONLY (clause
) = 1;
10612 else if (code
== OMP_CLAUSE_FIRSTPRIVATE
&& (flags
& GOVD_EXPLICIT
) == 0)
10613 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (clause
) = 1;
10614 else if (code
== OMP_CLAUSE_MAP
&& (flags
& GOVD_MAP_0LEN_ARRAY
) != 0)
10616 tree nc
= build_omp_clause (input_location
, OMP_CLAUSE_MAP
);
10617 OMP_CLAUSE_DECL (nc
) = decl
;
10618 if (TREE_CODE (TREE_TYPE (decl
)) == REFERENCE_TYPE
10619 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl
))) == POINTER_TYPE
)
10620 OMP_CLAUSE_DECL (clause
)
10621 = build_simple_mem_ref_loc (input_location
, decl
);
10622 OMP_CLAUSE_DECL (clause
)
10623 = build2 (MEM_REF
, char_type_node
, OMP_CLAUSE_DECL (clause
),
10624 build_int_cst (build_pointer_type (char_type_node
), 0));
10625 OMP_CLAUSE_SIZE (clause
) = size_zero_node
;
10626 OMP_CLAUSE_SIZE (nc
) = size_zero_node
;
10627 OMP_CLAUSE_SET_MAP_KIND (clause
, GOMP_MAP_ALLOC
);
10628 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (clause
) = 1;
10629 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_FIRSTPRIVATE_POINTER
);
10630 OMP_CLAUSE_CHAIN (nc
) = chain
;
10631 OMP_CLAUSE_CHAIN (clause
) = nc
;
10632 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
10633 gimplify_omp_ctxp
= ctx
->outer_context
;
10634 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (clause
), 0),
10635 pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
10636 gimplify_omp_ctxp
= ctx
;
10638 else if (code
== OMP_CLAUSE_MAP
)
10641 /* Not all combinations of these GOVD_MAP flags are actually valid. */
10642 switch (flags
& (GOVD_MAP_TO_ONLY
10644 | GOVD_MAP_FORCE_PRESENT
10645 | GOVD_MAP_ALLOC_ONLY
10646 | GOVD_MAP_FROM_ONLY
))
10649 kind
= GOMP_MAP_TOFROM
;
10651 case GOVD_MAP_FORCE
:
10652 kind
= GOMP_MAP_TOFROM
| GOMP_MAP_FLAG_FORCE
;
10654 case GOVD_MAP_TO_ONLY
:
10655 kind
= GOMP_MAP_TO
;
10657 case GOVD_MAP_FROM_ONLY
:
10658 kind
= GOMP_MAP_FROM
;
10660 case GOVD_MAP_ALLOC_ONLY
:
10661 kind
= GOMP_MAP_ALLOC
;
10663 case GOVD_MAP_TO_ONLY
| GOVD_MAP_FORCE
:
10664 kind
= GOMP_MAP_TO
| GOMP_MAP_FLAG_FORCE
;
10666 case GOVD_MAP_FORCE_PRESENT
:
10667 kind
= GOMP_MAP_FORCE_PRESENT
;
10670 gcc_unreachable ();
10672 OMP_CLAUSE_SET_MAP_KIND (clause
, kind
);
10673 if (DECL_SIZE (decl
)
10674 && TREE_CODE (DECL_SIZE (decl
)) != INTEGER_CST
)
10676 tree decl2
= DECL_VALUE_EXPR (decl
);
10677 gcc_assert (TREE_CODE (decl2
) == INDIRECT_REF
);
10678 decl2
= TREE_OPERAND (decl2
, 0);
10679 gcc_assert (DECL_P (decl2
));
10680 tree mem
= build_simple_mem_ref (decl2
);
10681 OMP_CLAUSE_DECL (clause
) = mem
;
10682 OMP_CLAUSE_SIZE (clause
) = TYPE_SIZE_UNIT (TREE_TYPE (decl
));
10683 if (gimplify_omp_ctxp
->outer_context
)
10685 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
->outer_context
;
10686 omp_notice_variable (ctx
, decl2
, true);
10687 omp_notice_variable (ctx
, OMP_CLAUSE_SIZE (clause
), true);
10689 tree nc
= build_omp_clause (OMP_CLAUSE_LOCATION (clause
),
10691 OMP_CLAUSE_DECL (nc
) = decl
;
10692 OMP_CLAUSE_SIZE (nc
) = size_zero_node
;
10693 if (gimplify_omp_ctxp
->target_firstprivatize_array_bases
)
10694 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_FIRSTPRIVATE_POINTER
);
10696 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_POINTER
);
10697 OMP_CLAUSE_CHAIN (nc
) = OMP_CLAUSE_CHAIN (clause
);
10698 OMP_CLAUSE_CHAIN (clause
) = nc
;
10700 else if (gimplify_omp_ctxp
->target_firstprivatize_array_bases
10701 && lang_hooks
.decls
.omp_privatize_by_reference (decl
))
10703 OMP_CLAUSE_DECL (clause
) = build_simple_mem_ref (decl
);
10704 OMP_CLAUSE_SIZE (clause
)
10705 = unshare_expr (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl
))));
10706 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
10707 gimplify_omp_ctxp
= ctx
->outer_context
;
10708 gimplify_expr (&OMP_CLAUSE_SIZE (clause
),
10709 pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
10710 gimplify_omp_ctxp
= ctx
;
10711 tree nc
= build_omp_clause (OMP_CLAUSE_LOCATION (clause
),
10713 OMP_CLAUSE_DECL (nc
) = decl
;
10714 OMP_CLAUSE_SIZE (nc
) = size_zero_node
;
10715 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_FIRSTPRIVATE_REFERENCE
);
10716 OMP_CLAUSE_CHAIN (nc
) = OMP_CLAUSE_CHAIN (clause
);
10717 OMP_CLAUSE_CHAIN (clause
) = nc
;
10720 OMP_CLAUSE_SIZE (clause
) = DECL_SIZE_UNIT (decl
);
10722 if (code
== OMP_CLAUSE_FIRSTPRIVATE
&& (flags
& GOVD_LASTPRIVATE
) != 0)
10724 tree nc
= build_omp_clause (input_location
, OMP_CLAUSE_LASTPRIVATE
);
10725 OMP_CLAUSE_DECL (nc
) = decl
;
10726 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (nc
) = 1;
10727 OMP_CLAUSE_CHAIN (nc
) = chain
;
10728 OMP_CLAUSE_CHAIN (clause
) = nc
;
10729 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
10730 gimplify_omp_ctxp
= ctx
->outer_context
;
10731 lang_hooks
.decls
.omp_finish_clause (nc
, pre_p
,
10732 (ctx
->region_type
& ORT_ACC
) != 0);
10733 gimplify_omp_ctxp
= ctx
;
10736 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
10737 gimplify_omp_ctxp
= ctx
->outer_context
;
10738 lang_hooks
.decls
.omp_finish_clause (clause
, pre_p
,
10739 (ctx
->region_type
& ORT_ACC
) != 0);
10740 if (gimplify_omp_ctxp
)
10741 for (; clause
!= chain
; clause
= OMP_CLAUSE_CHAIN (clause
))
10742 if (OMP_CLAUSE_CODE (clause
) == OMP_CLAUSE_MAP
10743 && DECL_P (OMP_CLAUSE_SIZE (clause
)))
10744 omp_notice_variable (gimplify_omp_ctxp
, OMP_CLAUSE_SIZE (clause
),
10746 gimplify_omp_ctxp
= ctx
;
10751 gimplify_adjust_omp_clauses (gimple_seq
*pre_p
, gimple_seq body
, tree
*list_p
,
10752 enum tree_code code
)
10754 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
10755 tree
*orig_list_p
= list_p
;
10757 bool has_inscan_reductions
= false;
10761 struct gimplify_omp_ctx
*octx
;
10762 for (octx
= ctx
; octx
; octx
= octx
->outer_context
)
10763 if ((octx
->region_type
& (ORT_PARALLEL
| ORT_TASK
| ORT_TEAMS
)) != 0)
10767 struct walk_stmt_info wi
;
10768 memset (&wi
, 0, sizeof (wi
));
10769 walk_gimple_seq (body
, omp_find_stores_stmt
,
10770 omp_find_stores_op
, &wi
);
10774 if (ctx
->add_safelen1
)
10776 /* If there are VLAs in the body of simd loop, prevent
10778 gcc_assert (ctx
->region_type
== ORT_SIMD
);
10779 c
= build_omp_clause (UNKNOWN_LOCATION
, OMP_CLAUSE_SAFELEN
);
10780 OMP_CLAUSE_SAFELEN_EXPR (c
) = integer_one_node
;
10781 OMP_CLAUSE_CHAIN (c
) = *list_p
;
10783 list_p
= &OMP_CLAUSE_CHAIN (c
);
10786 if (ctx
->region_type
== ORT_WORKSHARE
10787 && ctx
->outer_context
10788 && ctx
->outer_context
->region_type
== ORT_COMBINED_PARALLEL
)
10790 for (c
= ctx
->outer_context
->clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
10791 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
10792 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
))
10794 decl
= OMP_CLAUSE_DECL (c
);
10796 = splay_tree_lookup (ctx
->outer_context
->variables
,
10797 (splay_tree_key
) decl
);
10798 gcc_checking_assert (!splay_tree_lookup (ctx
->variables
,
10799 (splay_tree_key
) decl
));
10800 omp_add_variable (ctx
, decl
, n
->value
);
10801 tree c2
= copy_node (c
);
10802 OMP_CLAUSE_CHAIN (c2
) = *list_p
;
10804 if ((n
->value
& GOVD_FIRSTPRIVATE
) == 0)
10806 c2
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
10807 OMP_CLAUSE_FIRSTPRIVATE
);
10808 OMP_CLAUSE_DECL (c2
) = decl
;
10809 OMP_CLAUSE_CHAIN (c2
) = *list_p
;
10813 while ((c
= *list_p
) != NULL
)
10816 bool remove
= false;
10818 switch (OMP_CLAUSE_CODE (c
))
10820 case OMP_CLAUSE_FIRSTPRIVATE
:
10821 if ((ctx
->region_type
& ORT_TARGET
)
10822 && (ctx
->region_type
& ORT_ACC
) == 0
10823 && TYPE_ATOMIC (strip_array_types
10824 (TREE_TYPE (OMP_CLAUSE_DECL (c
)))))
10826 error_at (OMP_CLAUSE_LOCATION (c
),
10827 "%<_Atomic%> %qD in %<firstprivate%> clause on "
10828 "%<target%> construct", OMP_CLAUSE_DECL (c
));
10832 if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c
))
10834 decl
= OMP_CLAUSE_DECL (c
);
10835 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
10836 if ((n
->value
& GOVD_MAP
) != 0)
10841 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT_TARGET (c
) = 0;
10842 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c
) = 0;
10845 case OMP_CLAUSE_PRIVATE
:
10846 case OMP_CLAUSE_SHARED
:
10847 case OMP_CLAUSE_LINEAR
:
10848 decl
= OMP_CLAUSE_DECL (c
);
10849 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
10850 remove
= !(n
->value
& GOVD_SEEN
);
10851 if ((n
->value
& GOVD_LASTPRIVATE_CONDITIONAL
) != 0
10852 && code
== OMP_PARALLEL
10853 && OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_FIRSTPRIVATE
)
10857 bool shared
= OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_SHARED
;
10858 if ((n
->value
& GOVD_DEBUG_PRIVATE
)
10859 || lang_hooks
.decls
.omp_private_debug_clause (decl
, shared
))
10861 gcc_assert ((n
->value
& GOVD_DEBUG_PRIVATE
) == 0
10862 || ((n
->value
& GOVD_DATA_SHARE_CLASS
)
10864 OMP_CLAUSE_SET_CODE (c
, OMP_CLAUSE_PRIVATE
);
10865 OMP_CLAUSE_PRIVATE_DEBUG (c
) = 1;
10867 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_SHARED
10870 n
->value
|= GOVD_WRITTEN
;
10871 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_SHARED
10872 && (n
->value
& GOVD_WRITTEN
) == 0
10874 && omp_shared_to_firstprivate_optimizable_decl_p (decl
))
10875 OMP_CLAUSE_SHARED_READONLY (c
) = 1;
10876 else if (DECL_P (decl
)
10877 && ((OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_SHARED
10878 && (n
->value
& GOVD_WRITTEN
) != 0)
10879 || (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINEAR
10880 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c
)))
10881 && omp_shared_to_firstprivate_optimizable_decl_p (decl
))
10882 omp_mark_stores (gimplify_omp_ctxp
->outer_context
, decl
);
10885 n
->value
&= ~GOVD_EXPLICIT
;
10888 case OMP_CLAUSE_LASTPRIVATE
:
10889 /* Make sure OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE is set to
10890 accurately reflect the presence of a FIRSTPRIVATE clause. */
10891 decl
= OMP_CLAUSE_DECL (c
);
10892 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
10893 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
)
10894 = (n
->value
& GOVD_FIRSTPRIVATE
) != 0;
10895 if (code
== OMP_DISTRIBUTE
10896 && OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
))
10899 error_at (OMP_CLAUSE_LOCATION (c
),
10900 "same variable used in %<firstprivate%> and "
10901 "%<lastprivate%> clauses on %<distribute%> "
10905 && OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
10907 && omp_shared_to_firstprivate_optimizable_decl_p (decl
))
10908 omp_mark_stores (gimplify_omp_ctxp
->outer_context
, decl
);
10909 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
) && code
== OMP_PARALLEL
)
10913 case OMP_CLAUSE_ALIGNED
:
10914 decl
= OMP_CLAUSE_DECL (c
);
10915 if (!is_global_var (decl
))
10917 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
10918 remove
= n
== NULL
|| !(n
->value
& GOVD_SEEN
);
10919 if (!remove
&& TREE_CODE (TREE_TYPE (decl
)) == POINTER_TYPE
)
10921 struct gimplify_omp_ctx
*octx
;
10923 && (n
->value
& (GOVD_DATA_SHARE_CLASS
10924 & ~GOVD_FIRSTPRIVATE
)))
10927 for (octx
= ctx
->outer_context
; octx
;
10928 octx
= octx
->outer_context
)
10930 n
= splay_tree_lookup (octx
->variables
,
10931 (splay_tree_key
) decl
);
10934 if (n
->value
& GOVD_LOCAL
)
10936 /* We have to avoid assigning a shared variable
10937 to itself when trying to add
10938 __builtin_assume_aligned. */
10939 if (n
->value
& GOVD_SHARED
)
10947 else if (TREE_CODE (TREE_TYPE (decl
)) == ARRAY_TYPE
)
10949 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
10950 if (n
!= NULL
&& (n
->value
& GOVD_DATA_SHARE_CLASS
) != 0)
10955 case OMP_CLAUSE_NONTEMPORAL
:
10956 decl
= OMP_CLAUSE_DECL (c
);
10957 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
10958 remove
= n
== NULL
|| !(n
->value
& GOVD_SEEN
);
10961 case OMP_CLAUSE_MAP
:
10962 if (code
== OMP_TARGET_EXIT_DATA
10963 && OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ALWAYS_POINTER
)
10968 decl
= OMP_CLAUSE_DECL (c
);
10969 /* Data clauses associated with reductions must be
10970 compatible with present_or_copy. Warn and adjust the clause
10971 if that is not the case. */
10972 if (ctx
->region_type
== ORT_ACC_PARALLEL
10973 || ctx
->region_type
== ORT_ACC_SERIAL
)
10975 tree t
= DECL_P (decl
) ? decl
: TREE_OPERAND (decl
, 0);
10979 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) t
);
10981 if (n
&& (n
->value
& GOVD_REDUCTION
))
10983 enum gomp_map_kind kind
= OMP_CLAUSE_MAP_KIND (c
);
10985 OMP_CLAUSE_MAP_IN_REDUCTION (c
) = 1;
10986 if ((kind
& GOMP_MAP_TOFROM
) != GOMP_MAP_TOFROM
10987 && kind
!= GOMP_MAP_FORCE_PRESENT
10988 && kind
!= GOMP_MAP_POINTER
)
10990 warning_at (OMP_CLAUSE_LOCATION (c
), 0,
10991 "incompatible data clause with reduction "
10992 "on %qE; promoting to %<present_or_copy%>",
10994 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_TOFROM
);
10998 if (!DECL_P (decl
))
11000 if ((ctx
->region_type
& ORT_TARGET
) != 0
11001 && OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_FIRSTPRIVATE_POINTER
)
11003 if (TREE_CODE (decl
) == INDIRECT_REF
11004 && TREE_CODE (TREE_OPERAND (decl
, 0)) == COMPONENT_REF
11005 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl
, 0)))
11006 == REFERENCE_TYPE
))
11007 decl
= TREE_OPERAND (decl
, 0);
11008 if (TREE_CODE (decl
) == COMPONENT_REF
)
11010 while (TREE_CODE (decl
) == COMPONENT_REF
)
11011 decl
= TREE_OPERAND (decl
, 0);
11014 n
= splay_tree_lookup (ctx
->variables
,
11015 (splay_tree_key
) decl
);
11016 if (!(n
->value
& GOVD_SEEN
))
11023 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
11024 if ((ctx
->region_type
& ORT_TARGET
) != 0
11025 && !(n
->value
& GOVD_SEEN
)
11026 && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c
)) == 0
11027 && (!is_global_var (decl
)
11028 || !lookup_attribute ("omp declare target link",
11029 DECL_ATTRIBUTES (decl
))))
11032 /* For struct element mapping, if struct is never referenced
11033 in target block and none of the mapping has always modifier,
11034 remove all the struct element mappings, which immediately
11035 follow the GOMP_MAP_STRUCT map clause. */
11036 if (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_STRUCT
)
11038 HOST_WIDE_INT cnt
= tree_to_shwi (OMP_CLAUSE_SIZE (c
));
11040 OMP_CLAUSE_CHAIN (c
)
11041 = OMP_CLAUSE_CHAIN (OMP_CLAUSE_CHAIN (c
));
11044 else if (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_STRUCT
11045 && (code
== OMP_TARGET_EXIT_DATA
11046 || code
== OACC_EXIT_DATA
))
11048 else if (DECL_SIZE (decl
)
11049 && TREE_CODE (DECL_SIZE (decl
)) != INTEGER_CST
11050 && OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_POINTER
11051 && OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_FIRSTPRIVATE_POINTER
11052 && (OMP_CLAUSE_MAP_KIND (c
)
11053 != GOMP_MAP_FIRSTPRIVATE_REFERENCE
))
11055 /* For GOMP_MAP_FORCE_DEVICEPTR, we'll never enter here, because
11056 for these, TREE_CODE (DECL_SIZE (decl)) will always be
11058 gcc_assert (OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_FORCE_DEVICEPTR
);
11060 tree decl2
= DECL_VALUE_EXPR (decl
);
11061 gcc_assert (TREE_CODE (decl2
) == INDIRECT_REF
);
11062 decl2
= TREE_OPERAND (decl2
, 0);
11063 gcc_assert (DECL_P (decl2
));
11064 tree mem
= build_simple_mem_ref (decl2
);
11065 OMP_CLAUSE_DECL (c
) = mem
;
11066 OMP_CLAUSE_SIZE (c
) = TYPE_SIZE_UNIT (TREE_TYPE (decl
));
11067 if (ctx
->outer_context
)
11069 omp_notice_variable (ctx
->outer_context
, decl2
, true);
11070 omp_notice_variable (ctx
->outer_context
,
11071 OMP_CLAUSE_SIZE (c
), true);
11073 if (((ctx
->region_type
& ORT_TARGET
) != 0
11074 || !ctx
->target_firstprivatize_array_bases
)
11075 && ((n
->value
& GOVD_SEEN
) == 0
11076 || (n
->value
& (GOVD_PRIVATE
| GOVD_FIRSTPRIVATE
)) == 0))
11078 tree nc
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
11080 OMP_CLAUSE_DECL (nc
) = decl
;
11081 OMP_CLAUSE_SIZE (nc
) = size_zero_node
;
11082 if (ctx
->target_firstprivatize_array_bases
)
11083 OMP_CLAUSE_SET_MAP_KIND (nc
,
11084 GOMP_MAP_FIRSTPRIVATE_POINTER
);
11086 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_POINTER
);
11087 OMP_CLAUSE_CHAIN (nc
) = OMP_CLAUSE_CHAIN (c
);
11088 OMP_CLAUSE_CHAIN (c
) = nc
;
11094 if (OMP_CLAUSE_SIZE (c
) == NULL_TREE
)
11095 OMP_CLAUSE_SIZE (c
) = DECL_SIZE_UNIT (decl
);
11096 gcc_assert ((n
->value
& GOVD_SEEN
) == 0
11097 || ((n
->value
& (GOVD_PRIVATE
| GOVD_FIRSTPRIVATE
))
11102 case OMP_CLAUSE_TO
:
11103 case OMP_CLAUSE_FROM
:
11104 case OMP_CLAUSE__CACHE_
:
11105 decl
= OMP_CLAUSE_DECL (c
);
11106 if (!DECL_P (decl
))
11108 if (DECL_SIZE (decl
)
11109 && TREE_CODE (DECL_SIZE (decl
)) != INTEGER_CST
)
11111 tree decl2
= DECL_VALUE_EXPR (decl
);
11112 gcc_assert (TREE_CODE (decl2
) == INDIRECT_REF
);
11113 decl2
= TREE_OPERAND (decl2
, 0);
11114 gcc_assert (DECL_P (decl2
));
11115 tree mem
= build_simple_mem_ref (decl2
);
11116 OMP_CLAUSE_DECL (c
) = mem
;
11117 OMP_CLAUSE_SIZE (c
) = TYPE_SIZE_UNIT (TREE_TYPE (decl
));
11118 if (ctx
->outer_context
)
11120 omp_notice_variable (ctx
->outer_context
, decl2
, true);
11121 omp_notice_variable (ctx
->outer_context
,
11122 OMP_CLAUSE_SIZE (c
), true);
11125 else if (OMP_CLAUSE_SIZE (c
) == NULL_TREE
)
11126 OMP_CLAUSE_SIZE (c
) = DECL_SIZE_UNIT (decl
);
11129 case OMP_CLAUSE_REDUCTION
:
11130 if (OMP_CLAUSE_REDUCTION_INSCAN (c
))
11132 decl
= OMP_CLAUSE_DECL (c
);
11133 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
11134 if ((n
->value
& GOVD_REDUCTION_INSCAN
) == 0)
11137 error_at (OMP_CLAUSE_LOCATION (c
),
11138 "%qD specified in %<inscan%> %<reduction%> clause "
11139 "but not in %<scan%> directive clause", decl
);
11142 has_inscan_reductions
= true;
11145 case OMP_CLAUSE_IN_REDUCTION
:
11146 case OMP_CLAUSE_TASK_REDUCTION
:
11147 decl
= OMP_CLAUSE_DECL (c
);
11148 /* OpenACC reductions need a present_or_copy data clause.
11149 Add one if necessary. Emit error when the reduction is private. */
11150 if (ctx
->region_type
== ORT_ACC_PARALLEL
11151 || ctx
->region_type
== ORT_ACC_SERIAL
)
11153 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
11154 if (n
->value
& (GOVD_PRIVATE
| GOVD_FIRSTPRIVATE
))
11157 error_at (OMP_CLAUSE_LOCATION (c
), "invalid private "
11158 "reduction on %qE", DECL_NAME (decl
));
11160 else if ((n
->value
& GOVD_MAP
) == 0)
11162 tree next
= OMP_CLAUSE_CHAIN (c
);
11163 tree nc
= build_omp_clause (UNKNOWN_LOCATION
, OMP_CLAUSE_MAP
);
11164 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_TOFROM
);
11165 OMP_CLAUSE_DECL (nc
) = decl
;
11166 OMP_CLAUSE_CHAIN (c
) = nc
;
11167 lang_hooks
.decls
.omp_finish_clause (nc
, pre_p
,
11172 OMP_CLAUSE_MAP_IN_REDUCTION (nc
) = 1;
11173 if (OMP_CLAUSE_CHAIN (nc
) == NULL
)
11175 nc
= OMP_CLAUSE_CHAIN (nc
);
11177 OMP_CLAUSE_CHAIN (nc
) = next
;
11178 n
->value
|= GOVD_MAP
;
11182 && omp_shared_to_firstprivate_optimizable_decl_p (decl
))
11183 omp_mark_stores (gimplify_omp_ctxp
->outer_context
, decl
);
11186 case OMP_CLAUSE_ALLOCATE
:
11187 decl
= OMP_CLAUSE_DECL (c
);
11188 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
11189 if (n
!= NULL
&& !(n
->value
& GOVD_SEEN
))
11191 if ((n
->value
& (GOVD_PRIVATE
| GOVD_FIRSTPRIVATE
| GOVD_LINEAR
))
11193 && (n
->value
& (GOVD_REDUCTION
| GOVD_LASTPRIVATE
)) == 0)
11197 && OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
)
11198 && TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
)) != INTEGER_CST
11199 && ((ctx
->region_type
& (ORT_PARALLEL
| ORT_TARGET
)) != 0
11200 || (ctx
->region_type
& ORT_TASKLOOP
) == ORT_TASK
11201 || (ctx
->region_type
& ORT_HOST_TEAMS
) == ORT_HOST_TEAMS
))
11203 tree allocator
= OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
);
11204 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) allocator
);
11207 enum omp_clause_default_kind default_kind
11208 = ctx
->default_kind
;
11209 ctx
->default_kind
= OMP_CLAUSE_DEFAULT_FIRSTPRIVATE
;
11210 omp_notice_variable (ctx
, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
),
11212 ctx
->default_kind
= default_kind
;
11215 omp_notice_variable (ctx
, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
),
11220 case OMP_CLAUSE_COPYIN
:
11221 case OMP_CLAUSE_COPYPRIVATE
:
11222 case OMP_CLAUSE_IF
:
11223 case OMP_CLAUSE_NUM_THREADS
:
11224 case OMP_CLAUSE_NUM_TEAMS
:
11225 case OMP_CLAUSE_THREAD_LIMIT
:
11226 case OMP_CLAUSE_DIST_SCHEDULE
:
11227 case OMP_CLAUSE_DEVICE
:
11228 case OMP_CLAUSE_SCHEDULE
:
11229 case OMP_CLAUSE_NOWAIT
:
11230 case OMP_CLAUSE_ORDERED
:
11231 case OMP_CLAUSE_DEFAULT
:
11232 case OMP_CLAUSE_UNTIED
:
11233 case OMP_CLAUSE_COLLAPSE
:
11234 case OMP_CLAUSE_FINAL
:
11235 case OMP_CLAUSE_MERGEABLE
:
11236 case OMP_CLAUSE_PROC_BIND
:
11237 case OMP_CLAUSE_SAFELEN
:
11238 case OMP_CLAUSE_SIMDLEN
:
11239 case OMP_CLAUSE_DEPEND
:
11240 case OMP_CLAUSE_PRIORITY
:
11241 case OMP_CLAUSE_GRAINSIZE
:
11242 case OMP_CLAUSE_NUM_TASKS
:
11243 case OMP_CLAUSE_NOGROUP
:
11244 case OMP_CLAUSE_THREADS
:
11245 case OMP_CLAUSE_SIMD
:
11246 case OMP_CLAUSE_FILTER
:
11247 case OMP_CLAUSE_HINT
:
11248 case OMP_CLAUSE_DEFAULTMAP
:
11249 case OMP_CLAUSE_ORDER
:
11250 case OMP_CLAUSE_BIND
:
11251 case OMP_CLAUSE_DETACH
:
11252 case OMP_CLAUSE_USE_DEVICE_PTR
:
11253 case OMP_CLAUSE_USE_DEVICE_ADDR
:
11254 case OMP_CLAUSE_IS_DEVICE_PTR
:
11255 case OMP_CLAUSE_ASYNC
:
11256 case OMP_CLAUSE_WAIT
:
11257 case OMP_CLAUSE_INDEPENDENT
:
11258 case OMP_CLAUSE_NUM_GANGS
:
11259 case OMP_CLAUSE_NUM_WORKERS
:
11260 case OMP_CLAUSE_VECTOR_LENGTH
:
11261 case OMP_CLAUSE_GANG
:
11262 case OMP_CLAUSE_WORKER
:
11263 case OMP_CLAUSE_VECTOR
:
11264 case OMP_CLAUSE_AUTO
:
11265 case OMP_CLAUSE_SEQ
:
11266 case OMP_CLAUSE_TILE
:
11267 case OMP_CLAUSE_IF_PRESENT
:
11268 case OMP_CLAUSE_FINALIZE
:
11269 case OMP_CLAUSE_INCLUSIVE
:
11270 case OMP_CLAUSE_EXCLUSIVE
:
11273 case OMP_CLAUSE_NOHOST
:
11275 gcc_unreachable ();
11279 *list_p
= OMP_CLAUSE_CHAIN (c
);
11281 list_p
= &OMP_CLAUSE_CHAIN (c
);
11284 /* Add in any implicit data sharing. */
11285 struct gimplify_adjust_omp_clauses_data data
;
11286 data
.list_p
= list_p
;
11287 data
.pre_p
= pre_p
;
11288 splay_tree_foreach (ctx
->variables
, gimplify_adjust_omp_clauses_1
, &data
);
11290 if (has_inscan_reductions
)
11291 for (c
= *orig_list_p
; c
; c
= OMP_CLAUSE_CHAIN (c
))
11292 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINEAR
11293 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c
))
11295 error_at (OMP_CLAUSE_LOCATION (c
),
11296 "%<inscan%> %<reduction%> clause used together with "
11297 "%<linear%> clause for a variable other than loop "
11302 gimplify_omp_ctxp
= ctx
->outer_context
;
11303 delete_omp_context (ctx
);
11306 /* Return 0 if CONSTRUCTS selectors don't match the OpenMP context,
11307 -1 if unknown yet (simd is involved, won't be known until vectorization)
11308 and 1 if they do. If SCORES is non-NULL, it should point to an array
11309 of at least 2*NCONSTRUCTS+2 ints, and will be filled with the positions
11310 of the CONSTRUCTS (position -1 if it will never match) followed by
11311 number of constructs in the OpenMP context construct trait. If the
11312 score depends on whether it will be in a declare simd clone or not,
11313 the function returns 2 and there will be two sets of the scores, the first
11314 one for the case that it is not in a declare simd clone, the other
11315 that it is in a declare simd clone. */
11318 omp_construct_selector_matches (enum tree_code
*constructs
, int nconstructs
,
11321 int matched
= 0, cnt
= 0;
11322 bool simd_seen
= false;
11323 bool target_seen
= false;
11324 int declare_simd_cnt
= -1;
11325 auto_vec
<enum tree_code
, 16> codes
;
11326 for (struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
; ctx
;)
11328 if (((ctx
->region_type
& ORT_PARALLEL
) && ctx
->code
== OMP_PARALLEL
)
11329 || ((ctx
->region_type
& (ORT_TARGET
| ORT_IMPLICIT_TARGET
| ORT_ACC
))
11330 == ORT_TARGET
&& ctx
->code
== OMP_TARGET
)
11331 || ((ctx
->region_type
& ORT_TEAMS
) && ctx
->code
== OMP_TEAMS
)
11332 || (ctx
->region_type
== ORT_WORKSHARE
&& ctx
->code
== OMP_FOR
)
11333 || (ctx
->region_type
== ORT_SIMD
11334 && ctx
->code
== OMP_SIMD
11335 && !omp_find_clause (ctx
->clauses
, OMP_CLAUSE_BIND
)))
11339 codes
.safe_push (ctx
->code
);
11340 else if (matched
< nconstructs
&& ctx
->code
== constructs
[matched
])
11342 if (ctx
->code
== OMP_SIMD
)
11350 if (ctx
->code
== OMP_TARGET
)
11352 if (scores
== NULL
)
11353 return matched
< nconstructs
? 0 : simd_seen
? -1 : 1;
11354 target_seen
= true;
11358 else if (ctx
->region_type
== ORT_WORKSHARE
11359 && ctx
->code
== OMP_LOOP
11360 && ctx
->outer_context
11361 && ctx
->outer_context
->region_type
== ORT_COMBINED_PARALLEL
11362 && ctx
->outer_context
->outer_context
11363 && ctx
->outer_context
->outer_context
->code
== OMP_LOOP
11364 && ctx
->outer_context
->outer_context
->distribute
)
11365 ctx
= ctx
->outer_context
->outer_context
;
11366 ctx
= ctx
->outer_context
;
11369 && lookup_attribute ("omp declare simd",
11370 DECL_ATTRIBUTES (current_function_decl
)))
11372 /* Declare simd is a maybe case, it is supposed to be added only to the
11373 omp-simd-clone.c added clones and not to the base function. */
11374 declare_simd_cnt
= cnt
++;
11376 codes
.safe_push (OMP_SIMD
);
11378 && constructs
[0] == OMP_SIMD
)
11380 gcc_assert (matched
== 0);
11382 if (++matched
== nconstructs
)
11386 if (tree attr
= lookup_attribute ("omp declare variant variant",
11387 DECL_ATTRIBUTES (current_function_decl
)))
11389 enum tree_code variant_constructs
[5];
11390 int variant_nconstructs
= 0;
11392 variant_nconstructs
11393 = omp_constructor_traits_to_codes (TREE_VALUE (attr
),
11394 variant_constructs
);
11395 for (int i
= 0; i
< variant_nconstructs
; i
++)
11399 codes
.safe_push (variant_constructs
[i
]);
11400 else if (matched
< nconstructs
11401 && variant_constructs
[i
] == constructs
[matched
])
11403 if (variant_constructs
[i
] == OMP_SIMD
)
11414 && lookup_attribute ("omp declare target block",
11415 DECL_ATTRIBUTES (current_function_decl
)))
11418 codes
.safe_push (OMP_TARGET
);
11419 else if (matched
< nconstructs
&& constructs
[matched
] == OMP_TARGET
)
11424 for (int pass
= 0; pass
< (declare_simd_cnt
== -1 ? 1 : 2); pass
++)
11426 int j
= codes
.length () - 1;
11427 for (int i
= nconstructs
- 1; i
>= 0; i
--)
11430 && (pass
!= 0 || declare_simd_cnt
!= j
)
11431 && constructs
[i
] != codes
[j
])
11433 if (pass
== 0 && declare_simd_cnt
!= -1 && j
> declare_simd_cnt
)
11438 *scores
++ = ((pass
== 0 && declare_simd_cnt
!= -1)
11439 ? codes
.length () - 1 : codes
.length ());
11441 return declare_simd_cnt
== -1 ? 1 : 2;
11443 if (matched
== nconstructs
)
11444 return simd_seen
? -1 : 1;
11448 /* Gimplify OACC_CACHE. */
11451 gimplify_oacc_cache (tree
*expr_p
, gimple_seq
*pre_p
)
11453 tree expr
= *expr_p
;
11455 gimplify_scan_omp_clauses (&OACC_CACHE_CLAUSES (expr
), pre_p
, ORT_ACC
,
11457 gimplify_adjust_omp_clauses (pre_p
, NULL
, &OACC_CACHE_CLAUSES (expr
),
11460 /* TODO: Do something sensible with this information. */
11462 *expr_p
= NULL_TREE
;
11465 /* Helper function of gimplify_oacc_declare. The helper's purpose is to,
11466 if required, translate 'kind' in CLAUSE into an 'entry' kind and 'exit'
11467 kind. The entry kind will replace the one in CLAUSE, while the exit
11468 kind will be used in a new omp_clause and returned to the caller. */
11471 gimplify_oacc_declare_1 (tree clause
)
11473 HOST_WIDE_INT kind
, new_op
;
11477 kind
= OMP_CLAUSE_MAP_KIND (clause
);
11481 case GOMP_MAP_ALLOC
:
11482 new_op
= GOMP_MAP_RELEASE
;
11486 case GOMP_MAP_FROM
:
11487 OMP_CLAUSE_SET_MAP_KIND (clause
, GOMP_MAP_FORCE_ALLOC
);
11488 new_op
= GOMP_MAP_FROM
;
11492 case GOMP_MAP_TOFROM
:
11493 OMP_CLAUSE_SET_MAP_KIND (clause
, GOMP_MAP_TO
);
11494 new_op
= GOMP_MAP_FROM
;
11498 case GOMP_MAP_DEVICE_RESIDENT
:
11499 case GOMP_MAP_FORCE_DEVICEPTR
:
11500 case GOMP_MAP_FORCE_PRESENT
:
11501 case GOMP_MAP_LINK
:
11502 case GOMP_MAP_POINTER
:
11507 gcc_unreachable ();
11513 c
= build_omp_clause (OMP_CLAUSE_LOCATION (clause
), OMP_CLAUSE_MAP
);
11514 OMP_CLAUSE_SET_MAP_KIND (c
, new_op
);
11515 OMP_CLAUSE_DECL (c
) = OMP_CLAUSE_DECL (clause
);
11521 /* Gimplify OACC_DECLARE. */
11524 gimplify_oacc_declare (tree
*expr_p
, gimple_seq
*pre_p
)
11526 tree expr
= *expr_p
;
11528 tree clauses
, t
, decl
;
11530 clauses
= OACC_DECLARE_CLAUSES (expr
);
11532 gimplify_scan_omp_clauses (&clauses
, pre_p
, ORT_TARGET_DATA
, OACC_DECLARE
);
11533 gimplify_adjust_omp_clauses (pre_p
, NULL
, &clauses
, OACC_DECLARE
);
11535 for (t
= clauses
; t
; t
= OMP_CLAUSE_CHAIN (t
))
11537 decl
= OMP_CLAUSE_DECL (t
);
11539 if (TREE_CODE (decl
) == MEM_REF
)
11540 decl
= TREE_OPERAND (decl
, 0);
11542 if (VAR_P (decl
) && !is_oacc_declared (decl
))
11544 tree attr
= get_identifier ("oacc declare target");
11545 DECL_ATTRIBUTES (decl
) = tree_cons (attr
, NULL_TREE
,
11546 DECL_ATTRIBUTES (decl
));
11550 && !is_global_var (decl
)
11551 && DECL_CONTEXT (decl
) == current_function_decl
)
11553 tree c
= gimplify_oacc_declare_1 (t
);
11556 if (oacc_declare_returns
== NULL
)
11557 oacc_declare_returns
= new hash_map
<tree
, tree
>;
11559 oacc_declare_returns
->put (decl
, c
);
11563 if (gimplify_omp_ctxp
)
11564 omp_add_variable (gimplify_omp_ctxp
, decl
, GOVD_SEEN
);
11567 stmt
= gimple_build_omp_target (NULL
, GF_OMP_TARGET_KIND_OACC_DECLARE
,
11570 gimplify_seq_add_stmt (pre_p
, stmt
);
11572 *expr_p
= NULL_TREE
;
11575 /* Gimplify the contents of an OMP_PARALLEL statement. This involves
11576 gimplification of the body, as well as scanning the body for used
11577 variables. We need to do this scan now, because variable-sized
11578 decls will be decomposed during gimplification. */
11581 gimplify_omp_parallel (tree
*expr_p
, gimple_seq
*pre_p
)
11583 tree expr
= *expr_p
;
11585 gimple_seq body
= NULL
;
11587 gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr
), pre_p
,
11588 OMP_PARALLEL_COMBINED (expr
)
11589 ? ORT_COMBINED_PARALLEL
11590 : ORT_PARALLEL
, OMP_PARALLEL
);
11592 push_gimplify_context ();
11594 g
= gimplify_and_return_first (OMP_PARALLEL_BODY (expr
), &body
);
11595 if (gimple_code (g
) == GIMPLE_BIND
)
11596 pop_gimplify_context (g
);
11598 pop_gimplify_context (NULL
);
11600 gimplify_adjust_omp_clauses (pre_p
, body
, &OMP_PARALLEL_CLAUSES (expr
),
11603 g
= gimple_build_omp_parallel (body
,
11604 OMP_PARALLEL_CLAUSES (expr
),
11605 NULL_TREE
, NULL_TREE
);
11606 if (OMP_PARALLEL_COMBINED (expr
))
11607 gimple_omp_set_subcode (g
, GF_OMP_PARALLEL_COMBINED
);
11608 gimplify_seq_add_stmt (pre_p
, g
);
11609 *expr_p
= NULL_TREE
;
11612 /* Gimplify the contents of an OMP_TASK statement. This involves
11613 gimplification of the body, as well as scanning the body for used
11614 variables. We need to do this scan now, because variable-sized
11615 decls will be decomposed during gimplification. */
11618 gimplify_omp_task (tree
*expr_p
, gimple_seq
*pre_p
)
11620 tree expr
= *expr_p
;
11622 gimple_seq body
= NULL
;
11624 if (OMP_TASK_BODY (expr
) == NULL_TREE
)
11625 for (tree c
= OMP_TASK_CLAUSES (expr
); c
; c
= OMP_CLAUSE_CHAIN (c
))
11626 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEPEND
11627 && OMP_CLAUSE_DEPEND_KIND (c
) == OMP_CLAUSE_DEPEND_MUTEXINOUTSET
)
11629 error_at (OMP_CLAUSE_LOCATION (c
),
11630 "%<mutexinoutset%> kind in %<depend%> clause on a "
11631 "%<taskwait%> construct");
11635 gimplify_scan_omp_clauses (&OMP_TASK_CLAUSES (expr
), pre_p
,
11636 omp_find_clause (OMP_TASK_CLAUSES (expr
),
11638 ? ORT_UNTIED_TASK
: ORT_TASK
, OMP_TASK
);
11640 if (OMP_TASK_BODY (expr
))
11642 push_gimplify_context ();
11644 g
= gimplify_and_return_first (OMP_TASK_BODY (expr
), &body
);
11645 if (gimple_code (g
) == GIMPLE_BIND
)
11646 pop_gimplify_context (g
);
11648 pop_gimplify_context (NULL
);
11651 gimplify_adjust_omp_clauses (pre_p
, body
, &OMP_TASK_CLAUSES (expr
),
11654 g
= gimple_build_omp_task (body
,
11655 OMP_TASK_CLAUSES (expr
),
11656 NULL_TREE
, NULL_TREE
,
11657 NULL_TREE
, NULL_TREE
, NULL_TREE
);
11658 if (OMP_TASK_BODY (expr
) == NULL_TREE
)
11659 gimple_omp_task_set_taskwait_p (g
, true);
11660 gimplify_seq_add_stmt (pre_p
, g
);
11661 *expr_p
= NULL_TREE
;
11664 /* Helper function for gimplify_omp_for. If *TP is not a gimple constant,
11665 force it into a temporary initialized in PRE_P and add firstprivate clause
11666 to ORIG_FOR_STMT. */
11669 gimplify_omp_taskloop_expr (tree type
, tree
*tp
, gimple_seq
*pre_p
,
11670 tree orig_for_stmt
)
11672 if (*tp
== NULL
|| is_gimple_constant (*tp
))
11675 *tp
= get_initialized_tmp_var (*tp
, pre_p
, NULL
, false);
11676 /* Reference to pointer conversion is considered useless,
11677 but is significant for firstprivate clause. Force it
11680 && TREE_CODE (type
) == POINTER_TYPE
11681 && TREE_CODE (TREE_TYPE (*tp
)) == REFERENCE_TYPE
)
11683 tree v
= create_tmp_var (TYPE_MAIN_VARIANT (type
));
11684 tree m
= build2 (INIT_EXPR
, TREE_TYPE (v
), v
, *tp
);
11685 gimplify_and_add (m
, pre_p
);
11689 tree c
= build_omp_clause (input_location
, OMP_CLAUSE_FIRSTPRIVATE
);
11690 OMP_CLAUSE_DECL (c
) = *tp
;
11691 OMP_CLAUSE_CHAIN (c
) = OMP_FOR_CLAUSES (orig_for_stmt
);
11692 OMP_FOR_CLAUSES (orig_for_stmt
) = c
;
11695 /* Gimplify the gross structure of an OMP_FOR statement. */
11697 static enum gimplify_status
11698 gimplify_omp_for (tree
*expr_p
, gimple_seq
*pre_p
)
11700 tree for_stmt
, orig_for_stmt
, inner_for_stmt
= NULL_TREE
, decl
, var
, t
;
11701 enum gimplify_status ret
= GS_ALL_DONE
;
11702 enum gimplify_status tret
;
11704 gimple_seq for_body
, for_pre_body
;
11706 bitmap has_decl_expr
= NULL
;
11707 enum omp_region_type ort
= ORT_WORKSHARE
;
11708 bool openacc
= TREE_CODE (*expr_p
) == OACC_LOOP
;
11710 orig_for_stmt
= for_stmt
= *expr_p
;
11712 bool loop_p
= (omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_BIND
)
11714 if (OMP_FOR_INIT (for_stmt
) == NULL_TREE
)
11716 tree
*data
[4] = { NULL
, NULL
, NULL
, NULL
};
11717 gcc_assert (TREE_CODE (for_stmt
) != OACC_LOOP
);
11718 inner_for_stmt
= walk_tree (&OMP_FOR_BODY (for_stmt
),
11719 find_combined_omp_for
, data
, NULL
);
11720 if (inner_for_stmt
== NULL_TREE
)
11722 gcc_assert (seen_error ());
11723 *expr_p
= NULL_TREE
;
11726 if (data
[2] && OMP_FOR_PRE_BODY (*data
[2]))
11728 append_to_statement_list_force (OMP_FOR_PRE_BODY (*data
[2]),
11729 &OMP_FOR_PRE_BODY (for_stmt
));
11730 OMP_FOR_PRE_BODY (*data
[2]) = NULL_TREE
;
11732 if (OMP_FOR_PRE_BODY (inner_for_stmt
))
11734 append_to_statement_list_force (OMP_FOR_PRE_BODY (inner_for_stmt
),
11735 &OMP_FOR_PRE_BODY (for_stmt
));
11736 OMP_FOR_PRE_BODY (inner_for_stmt
) = NULL_TREE
;
11741 /* We have some statements or variable declarations in between
11742 the composite construct directives. Move them around the
11745 for (i
= 0; i
< 3; i
++)
11749 if (i
< 2 && data
[i
+ 1] == &OMP_BODY (t
))
11750 data
[i
+ 1] = data
[i
];
11751 *data
[i
] = OMP_BODY (t
);
11752 tree body
= build3 (BIND_EXPR
, void_type_node
, NULL_TREE
,
11753 NULL_TREE
, make_node (BLOCK
));
11754 OMP_BODY (t
) = body
;
11755 append_to_statement_list_force (inner_for_stmt
,
11756 &BIND_EXPR_BODY (body
));
11758 data
[3] = tsi_stmt_ptr (tsi_start (BIND_EXPR_BODY (body
)));
11759 gcc_assert (*data
[3] == inner_for_stmt
);
11764 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt
)); i
++)
11766 && OMP_FOR_ORIG_DECLS (inner_for_stmt
)
11767 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
),
11769 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
),
11772 tree orig
= TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
), i
);
11773 /* Class iterators aren't allowed on OMP_SIMD, so the only
11774 case we need to solve is distribute parallel for. They are
11775 allowed on the loop construct, but that is already handled
11776 in gimplify_omp_loop. */
11777 gcc_assert (TREE_CODE (inner_for_stmt
) == OMP_FOR
11778 && TREE_CODE (for_stmt
) == OMP_DISTRIBUTE
11780 tree orig_decl
= TREE_PURPOSE (orig
);
11781 tree last
= TREE_VALUE (orig
);
11783 for (pc
= &OMP_FOR_CLAUSES (inner_for_stmt
);
11784 *pc
; pc
= &OMP_CLAUSE_CHAIN (*pc
))
11785 if ((OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_PRIVATE
11786 || OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_LASTPRIVATE
)
11787 && OMP_CLAUSE_DECL (*pc
) == orig_decl
)
11789 if (*pc
== NULL_TREE
)
11792 for (spc
= &OMP_PARALLEL_CLAUSES (*data
[1]);
11793 *spc
; spc
= &OMP_CLAUSE_CHAIN (*spc
))
11794 if (OMP_CLAUSE_CODE (*spc
) == OMP_CLAUSE_PRIVATE
11795 && OMP_CLAUSE_DECL (*spc
) == orig_decl
)
11800 *spc
= OMP_CLAUSE_CHAIN (c
);
11801 OMP_CLAUSE_CHAIN (c
) = NULL_TREE
;
11805 if (*pc
== NULL_TREE
)
11807 else if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_PRIVATE
)
11809 /* private clause will appear only on inner_for_stmt.
11810 Change it into firstprivate, and add private clause
11812 tree c
= copy_node (*pc
);
11813 OMP_CLAUSE_CHAIN (c
) = OMP_FOR_CLAUSES (for_stmt
);
11814 OMP_FOR_CLAUSES (for_stmt
) = c
;
11815 OMP_CLAUSE_CODE (*pc
) = OMP_CLAUSE_FIRSTPRIVATE
;
11816 lang_hooks
.decls
.omp_finish_clause (*pc
, pre_p
, openacc
);
11820 /* lastprivate clause will appear on both inner_for_stmt
11821 and for_stmt. Add firstprivate clause to
11823 tree c
= build_omp_clause (OMP_CLAUSE_LOCATION (*pc
),
11824 OMP_CLAUSE_FIRSTPRIVATE
);
11825 OMP_CLAUSE_DECL (c
) = OMP_CLAUSE_DECL (*pc
);
11826 OMP_CLAUSE_CHAIN (c
) = *pc
;
11828 lang_hooks
.decls
.omp_finish_clause (*pc
, pre_p
, openacc
);
11830 tree c
= build_omp_clause (UNKNOWN_LOCATION
,
11831 OMP_CLAUSE_FIRSTPRIVATE
);
11832 OMP_CLAUSE_DECL (c
) = last
;
11833 OMP_CLAUSE_CHAIN (c
) = OMP_PARALLEL_CLAUSES (*data
[1]);
11834 OMP_PARALLEL_CLAUSES (*data
[1]) = c
;
11835 c
= build_omp_clause (UNKNOWN_LOCATION
,
11836 *pc
? OMP_CLAUSE_SHARED
11837 : OMP_CLAUSE_FIRSTPRIVATE
);
11838 OMP_CLAUSE_DECL (c
) = orig_decl
;
11839 OMP_CLAUSE_CHAIN (c
) = OMP_PARALLEL_CLAUSES (*data
[1]);
11840 OMP_PARALLEL_CLAUSES (*data
[1]) = c
;
11842 /* Similarly, take care of C++ range for temporaries, those should
11843 be firstprivate on OMP_PARALLEL if any. */
11845 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt
)); i
++)
11846 if (OMP_FOR_ORIG_DECLS (inner_for_stmt
)
11847 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
),
11849 && TREE_CHAIN (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
),
11853 = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
), i
);
11854 tree v
= TREE_CHAIN (orig
);
11855 tree c
= build_omp_clause (UNKNOWN_LOCATION
,
11856 OMP_CLAUSE_FIRSTPRIVATE
);
11857 /* First add firstprivate clause for the __for_end artificial
11859 OMP_CLAUSE_DECL (c
) = TREE_VEC_ELT (v
, 1);
11860 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c
)))
11862 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c
) = 1;
11863 OMP_CLAUSE_CHAIN (c
) = OMP_PARALLEL_CLAUSES (*data
[1]);
11864 OMP_PARALLEL_CLAUSES (*data
[1]) = c
;
11865 if (TREE_VEC_ELT (v
, 0))
11867 /* And now the same for __for_range artificial decl if it
11869 c
= build_omp_clause (UNKNOWN_LOCATION
,
11870 OMP_CLAUSE_FIRSTPRIVATE
);
11871 OMP_CLAUSE_DECL (c
) = TREE_VEC_ELT (v
, 0);
11872 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c
)))
11874 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c
) = 1;
11875 OMP_CLAUSE_CHAIN (c
) = OMP_PARALLEL_CLAUSES (*data
[1]);
11876 OMP_PARALLEL_CLAUSES (*data
[1]) = c
;
11881 switch (TREE_CODE (for_stmt
))
11884 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt
? inner_for_stmt
: for_stmt
))
11886 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt
),
11887 OMP_CLAUSE_SCHEDULE
))
11888 error_at (EXPR_LOCATION (for_stmt
),
11889 "%qs clause may not appear on non-rectangular %qs",
11890 "schedule", "for");
11891 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_ORDERED
))
11892 error_at (EXPR_LOCATION (for_stmt
),
11893 "%qs clause may not appear on non-rectangular %qs",
11897 case OMP_DISTRIBUTE
:
11898 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt
? inner_for_stmt
: for_stmt
)
11899 && omp_find_clause (OMP_FOR_CLAUSES (for_stmt
),
11900 OMP_CLAUSE_DIST_SCHEDULE
))
11901 error_at (EXPR_LOCATION (for_stmt
),
11902 "%qs clause may not appear on non-rectangular %qs",
11903 "dist_schedule", "distribute");
11909 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_UNTIED
))
11910 ort
= ORT_UNTIED_TASKLOOP
;
11912 ort
= ORT_TASKLOOP
;
11918 gcc_unreachable ();
11921 /* Set OMP_CLAUSE_LINEAR_NO_COPYIN flag on explicit linear
11922 clause for the IV. */
11923 if (ort
== ORT_SIMD
&& TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)) == 1)
11925 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), 0);
11926 gcc_assert (TREE_CODE (t
) == MODIFY_EXPR
);
11927 decl
= TREE_OPERAND (t
, 0);
11928 for (tree c
= OMP_FOR_CLAUSES (for_stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
11929 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINEAR
11930 && OMP_CLAUSE_DECL (c
) == decl
)
11932 OMP_CLAUSE_LINEAR_NO_COPYIN (c
) = 1;
11937 if (TREE_CODE (for_stmt
) != OMP_TASKLOOP
)
11938 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt
), pre_p
, ort
,
11939 loop_p
&& TREE_CODE (for_stmt
) != OMP_SIMD
11940 ? OMP_LOOP
: TREE_CODE (for_stmt
));
11942 if (TREE_CODE (for_stmt
) == OMP_DISTRIBUTE
)
11943 gimplify_omp_ctxp
->distribute
= true;
11945 /* Handle OMP_FOR_INIT. */
11946 for_pre_body
= NULL
;
11947 if ((ort
== ORT_SIMD
11948 || (inner_for_stmt
&& TREE_CODE (inner_for_stmt
) == OMP_SIMD
))
11949 && OMP_FOR_PRE_BODY (for_stmt
))
11951 has_decl_expr
= BITMAP_ALLOC (NULL
);
11952 if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt
)) == DECL_EXPR
11953 && TREE_CODE (DECL_EXPR_DECL (OMP_FOR_PRE_BODY (for_stmt
)))
11956 t
= OMP_FOR_PRE_BODY (for_stmt
);
11957 bitmap_set_bit (has_decl_expr
, DECL_UID (DECL_EXPR_DECL (t
)));
11959 else if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt
)) == STATEMENT_LIST
)
11961 tree_stmt_iterator si
;
11962 for (si
= tsi_start (OMP_FOR_PRE_BODY (for_stmt
)); !tsi_end_p (si
);
11966 if (TREE_CODE (t
) == DECL_EXPR
11967 && TREE_CODE (DECL_EXPR_DECL (t
)) == VAR_DECL
)
11968 bitmap_set_bit (has_decl_expr
, DECL_UID (DECL_EXPR_DECL (t
)));
11972 if (OMP_FOR_PRE_BODY (for_stmt
))
11974 if (TREE_CODE (for_stmt
) != OMP_TASKLOOP
|| gimplify_omp_ctxp
)
11975 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt
), &for_pre_body
);
11978 struct gimplify_omp_ctx ctx
;
11979 memset (&ctx
, 0, sizeof (ctx
));
11980 ctx
.region_type
= ORT_NONE
;
11981 gimplify_omp_ctxp
= &ctx
;
11982 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt
), &for_pre_body
);
11983 gimplify_omp_ctxp
= NULL
;
11986 OMP_FOR_PRE_BODY (for_stmt
) = NULL_TREE
;
11988 if (OMP_FOR_INIT (for_stmt
) == NULL_TREE
)
11989 for_stmt
= inner_for_stmt
;
11991 /* For taskloop, need to gimplify the start, end and step before the
11992 taskloop, outside of the taskloop omp context. */
11993 if (TREE_CODE (orig_for_stmt
) == OMP_TASKLOOP
)
11995 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
11997 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), i
);
11998 gimple_seq
*for_pre_p
= (gimple_seq_empty_p (for_pre_body
)
11999 ? pre_p
: &for_pre_body
);
12000 tree type
= TREE_TYPE (TREE_OPERAND (t
, 0));
12001 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
)
12003 tree v
= TREE_OPERAND (t
, 1);
12004 gimplify_omp_taskloop_expr (type
, &TREE_VEC_ELT (v
, 1),
12005 for_pre_p
, orig_for_stmt
);
12006 gimplify_omp_taskloop_expr (type
, &TREE_VEC_ELT (v
, 2),
12007 for_pre_p
, orig_for_stmt
);
12010 gimplify_omp_taskloop_expr (type
, &TREE_OPERAND (t
, 1), for_pre_p
,
12013 /* Handle OMP_FOR_COND. */
12014 t
= TREE_VEC_ELT (OMP_FOR_COND (for_stmt
), i
);
12015 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
)
12017 tree v
= TREE_OPERAND (t
, 1);
12018 gimplify_omp_taskloop_expr (type
, &TREE_VEC_ELT (v
, 1),
12019 for_pre_p
, orig_for_stmt
);
12020 gimplify_omp_taskloop_expr (type
, &TREE_VEC_ELT (v
, 2),
12021 for_pre_p
, orig_for_stmt
);
12024 gimplify_omp_taskloop_expr (type
, &TREE_OPERAND (t
, 1), for_pre_p
,
12027 /* Handle OMP_FOR_INCR. */
12028 t
= TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
);
12029 if (TREE_CODE (t
) == MODIFY_EXPR
)
12031 decl
= TREE_OPERAND (t
, 0);
12032 t
= TREE_OPERAND (t
, 1);
12033 tree
*tp
= &TREE_OPERAND (t
, 1);
12034 if (TREE_CODE (t
) == PLUS_EXPR
&& *tp
== decl
)
12035 tp
= &TREE_OPERAND (t
, 0);
12037 gimplify_omp_taskloop_expr (NULL_TREE
, tp
, for_pre_p
,
12042 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (orig_for_stmt
), pre_p
, ort
,
12046 if (orig_for_stmt
!= for_stmt
)
12047 gimplify_omp_ctxp
->combined_loop
= true;
12050 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
))
12051 == TREE_VEC_LENGTH (OMP_FOR_COND (for_stmt
)));
12052 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
))
12053 == TREE_VEC_LENGTH (OMP_FOR_INCR (for_stmt
)));
12055 tree c
= omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_ORDERED
);
12056 bool is_doacross
= false;
12057 if (c
&& OMP_CLAUSE_ORDERED_EXPR (c
))
12059 is_doacross
= true;
12060 gimplify_omp_ctxp
->loop_iter_var
.create (TREE_VEC_LENGTH
12061 (OMP_FOR_INIT (for_stmt
))
12064 int collapse
= 1, tile
= 0;
12065 c
= omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_COLLAPSE
);
12067 collapse
= tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (c
));
12068 c
= omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_TILE
);
12070 tile
= list_length (OMP_CLAUSE_TILE_LIST (c
));
12071 c
= omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_ALLOCATE
);
12072 hash_set
<tree
> *allocate_uids
= NULL
;
12075 allocate_uids
= new hash_set
<tree
>;
12076 for (; c
; c
= OMP_CLAUSE_CHAIN (c
))
12077 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_ALLOCATE
)
12078 allocate_uids
->add (OMP_CLAUSE_DECL (c
));
12080 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
12082 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), i
);
12083 gcc_assert (TREE_CODE (t
) == MODIFY_EXPR
);
12084 decl
= TREE_OPERAND (t
, 0);
12085 gcc_assert (DECL_P (decl
));
12086 gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl
))
12087 || POINTER_TYPE_P (TREE_TYPE (decl
)));
12090 if (TREE_CODE (for_stmt
) == OMP_FOR
&& OMP_FOR_ORIG_DECLS (for_stmt
))
12092 tree orig_decl
= TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
), i
);
12093 if (TREE_CODE (orig_decl
) == TREE_LIST
)
12095 orig_decl
= TREE_PURPOSE (orig_decl
);
12099 gimplify_omp_ctxp
->loop_iter_var
.quick_push (orig_decl
);
12102 gimplify_omp_ctxp
->loop_iter_var
.quick_push (decl
);
12103 gimplify_omp_ctxp
->loop_iter_var
.quick_push (decl
);
12106 /* Make sure the iteration variable is private. */
12107 tree c
= NULL_TREE
;
12108 tree c2
= NULL_TREE
;
12109 if (orig_for_stmt
!= for_stmt
)
12111 /* Preserve this information until we gimplify the inner simd. */
12113 && bitmap_bit_p (has_decl_expr
, DECL_UID (decl
)))
12114 TREE_PRIVATE (t
) = 1;
12116 else if (ort
== ORT_SIMD
)
12118 splay_tree_node n
= splay_tree_lookup (gimplify_omp_ctxp
->variables
,
12119 (splay_tree_key
) decl
);
12120 omp_is_private (gimplify_omp_ctxp
, decl
,
12121 1 + (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
))
12123 if (n
!= NULL
&& (n
->value
& GOVD_DATA_SHARE_CLASS
) != 0)
12125 omp_notice_variable (gimplify_omp_ctxp
, decl
, true);
12126 if (n
->value
& GOVD_LASTPRIVATE_CONDITIONAL
)
12127 for (tree c3
= omp_find_clause (OMP_FOR_CLAUSES (for_stmt
),
12128 OMP_CLAUSE_LASTPRIVATE
);
12129 c3
; c3
= omp_find_clause (OMP_CLAUSE_CHAIN (c3
),
12130 OMP_CLAUSE_LASTPRIVATE
))
12131 if (OMP_CLAUSE_DECL (c3
) == decl
)
12133 warning_at (OMP_CLAUSE_LOCATION (c3
), 0,
12134 "conditional %<lastprivate%> on loop "
12135 "iterator %qD ignored", decl
);
12136 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3
) = 0;
12137 n
->value
&= ~GOVD_LASTPRIVATE_CONDITIONAL
;
12140 else if (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)) == 1 && !loop_p
)
12142 c
= build_omp_clause (input_location
, OMP_CLAUSE_LINEAR
);
12143 OMP_CLAUSE_LINEAR_NO_COPYIN (c
) = 1;
12144 unsigned int flags
= GOVD_LINEAR
| GOVD_EXPLICIT
| GOVD_SEEN
;
12146 && bitmap_bit_p (has_decl_expr
, DECL_UID (decl
)))
12147 || TREE_PRIVATE (t
))
12149 OMP_CLAUSE_LINEAR_NO_COPYOUT (c
) = 1;
12150 flags
|= GOVD_LINEAR_LASTPRIVATE_NO_OUTER
;
12152 struct gimplify_omp_ctx
*outer
12153 = gimplify_omp_ctxp
->outer_context
;
12154 if (outer
&& !OMP_CLAUSE_LINEAR_NO_COPYOUT (c
))
12156 if (outer
->region_type
== ORT_WORKSHARE
12157 && outer
->combined_loop
)
12159 n
= splay_tree_lookup (outer
->variables
,
12160 (splay_tree_key
)decl
);
12161 if (n
!= NULL
&& (n
->value
& GOVD_LOCAL
) != 0)
12163 OMP_CLAUSE_LINEAR_NO_COPYOUT (c
) = 1;
12164 flags
|= GOVD_LINEAR_LASTPRIVATE_NO_OUTER
;
12168 struct gimplify_omp_ctx
*octx
= outer
->outer_context
;
12170 && octx
->region_type
== ORT_COMBINED_PARALLEL
12171 && octx
->outer_context
12172 && (octx
->outer_context
->region_type
12174 && octx
->outer_context
->combined_loop
)
12176 octx
= octx
->outer_context
;
12177 n
= splay_tree_lookup (octx
->variables
,
12178 (splay_tree_key
)decl
);
12179 if (n
!= NULL
&& (n
->value
& GOVD_LOCAL
) != 0)
12181 OMP_CLAUSE_LINEAR_NO_COPYOUT (c
) = 1;
12182 flags
|= GOVD_LINEAR_LASTPRIVATE_NO_OUTER
;
12189 OMP_CLAUSE_DECL (c
) = decl
;
12190 OMP_CLAUSE_CHAIN (c
) = OMP_FOR_CLAUSES (for_stmt
);
12191 OMP_FOR_CLAUSES (for_stmt
) = c
;
12192 omp_add_variable (gimplify_omp_ctxp
, decl
, flags
);
12193 if (outer
&& !OMP_CLAUSE_LINEAR_NO_COPYOUT (c
))
12194 omp_lastprivate_for_combined_outer_constructs (outer
, decl
,
12201 || !bitmap_bit_p (has_decl_expr
, DECL_UID (decl
)));
12202 if (TREE_PRIVATE (t
))
12203 lastprivate
= false;
12204 if (loop_p
&& OMP_FOR_ORIG_DECLS (for_stmt
))
12206 tree elt
= TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
), i
);
12207 if (TREE_CODE (elt
) == TREE_LIST
&& TREE_PURPOSE (elt
))
12208 lastprivate
= false;
12211 struct gimplify_omp_ctx
*outer
12212 = gimplify_omp_ctxp
->outer_context
;
12213 if (outer
&& lastprivate
)
12214 omp_lastprivate_for_combined_outer_constructs (outer
, decl
,
12217 c
= build_omp_clause (input_location
,
12218 lastprivate
? OMP_CLAUSE_LASTPRIVATE
12219 : OMP_CLAUSE_PRIVATE
);
12220 OMP_CLAUSE_DECL (c
) = decl
;
12221 OMP_CLAUSE_CHAIN (c
) = OMP_FOR_CLAUSES (for_stmt
);
12222 OMP_FOR_CLAUSES (for_stmt
) = c
;
12223 omp_add_variable (gimplify_omp_ctxp
, decl
,
12224 (lastprivate
? GOVD_LASTPRIVATE
: GOVD_PRIVATE
)
12225 | GOVD_EXPLICIT
| GOVD_SEEN
);
12229 else if (omp_is_private (gimplify_omp_ctxp
, decl
, 0))
12231 omp_notice_variable (gimplify_omp_ctxp
, decl
, true);
12232 splay_tree_node n
= splay_tree_lookup (gimplify_omp_ctxp
->variables
,
12233 (splay_tree_key
) decl
);
12234 if (n
&& (n
->value
& GOVD_LASTPRIVATE_CONDITIONAL
))
12235 for (tree c3
= omp_find_clause (OMP_FOR_CLAUSES (for_stmt
),
12236 OMP_CLAUSE_LASTPRIVATE
);
12237 c3
; c3
= omp_find_clause (OMP_CLAUSE_CHAIN (c3
),
12238 OMP_CLAUSE_LASTPRIVATE
))
12239 if (OMP_CLAUSE_DECL (c3
) == decl
)
12241 warning_at (OMP_CLAUSE_LOCATION (c3
), 0,
12242 "conditional %<lastprivate%> on loop "
12243 "iterator %qD ignored", decl
);
12244 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3
) = 0;
12245 n
->value
&= ~GOVD_LASTPRIVATE_CONDITIONAL
;
12249 omp_add_variable (gimplify_omp_ctxp
, decl
, GOVD_PRIVATE
| GOVD_SEEN
);
12251 /* If DECL is not a gimple register, create a temporary variable to act
12252 as an iteration counter. This is valid, since DECL cannot be
12253 modified in the body of the loop. Similarly for any iteration vars
12254 in simd with collapse > 1 where the iterator vars must be
12255 lastprivate. And similarly for vars mentioned in allocate clauses. */
12256 if (orig_for_stmt
!= for_stmt
)
12258 else if (!is_gimple_reg (decl
)
12259 || (ort
== ORT_SIMD
12260 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)) > 1)
12261 || (allocate_uids
&& allocate_uids
->contains (decl
)))
12263 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
12264 /* Make sure omp_add_variable is not called on it prematurely.
12265 We call it ourselves a few lines later. */
12266 gimplify_omp_ctxp
= NULL
;
12267 var
= create_tmp_var (TREE_TYPE (decl
), get_name (decl
));
12268 gimplify_omp_ctxp
= ctx
;
12269 TREE_OPERAND (t
, 0) = var
;
12271 gimplify_seq_add_stmt (&for_body
, gimple_build_assign (decl
, var
));
12273 if (ort
== ORT_SIMD
12274 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)) == 1)
12276 c2
= build_omp_clause (input_location
, OMP_CLAUSE_LINEAR
);
12277 OMP_CLAUSE_LINEAR_NO_COPYIN (c2
) = 1;
12278 OMP_CLAUSE_LINEAR_NO_COPYOUT (c2
) = 1;
12279 OMP_CLAUSE_DECL (c2
) = var
;
12280 OMP_CLAUSE_CHAIN (c2
) = OMP_FOR_CLAUSES (for_stmt
);
12281 OMP_FOR_CLAUSES (for_stmt
) = c2
;
12282 omp_add_variable (gimplify_omp_ctxp
, var
,
12283 GOVD_LINEAR
| GOVD_EXPLICIT
| GOVD_SEEN
);
12284 if (c
== NULL_TREE
)
12291 omp_add_variable (gimplify_omp_ctxp
, var
,
12292 GOVD_PRIVATE
| GOVD_SEEN
);
12297 gimplify_omp_ctxp
->in_for_exprs
= true;
12298 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
)
12300 tree lb
= TREE_OPERAND (t
, 1);
12301 tret
= gimplify_expr (&TREE_VEC_ELT (lb
, 1), &for_pre_body
, NULL
,
12302 is_gimple_val
, fb_rvalue
, false);
12303 ret
= MIN (ret
, tret
);
12304 tret
= gimplify_expr (&TREE_VEC_ELT (lb
, 2), &for_pre_body
, NULL
,
12305 is_gimple_val
, fb_rvalue
, false);
12308 tret
= gimplify_expr (&TREE_OPERAND (t
, 1), &for_pre_body
, NULL
,
12309 is_gimple_val
, fb_rvalue
, false);
12310 gimplify_omp_ctxp
->in_for_exprs
= false;
12311 ret
= MIN (ret
, tret
);
12312 if (ret
== GS_ERROR
)
12315 /* Handle OMP_FOR_COND. */
12316 t
= TREE_VEC_ELT (OMP_FOR_COND (for_stmt
), i
);
12317 gcc_assert (COMPARISON_CLASS_P (t
));
12318 gcc_assert (TREE_OPERAND (t
, 0) == decl
);
12320 gimplify_omp_ctxp
->in_for_exprs
= true;
12321 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
)
12323 tree ub
= TREE_OPERAND (t
, 1);
12324 tret
= gimplify_expr (&TREE_VEC_ELT (ub
, 1), &for_pre_body
, NULL
,
12325 is_gimple_val
, fb_rvalue
, false);
12326 ret
= MIN (ret
, tret
);
12327 tret
= gimplify_expr (&TREE_VEC_ELT (ub
, 2), &for_pre_body
, NULL
,
12328 is_gimple_val
, fb_rvalue
, false);
12331 tret
= gimplify_expr (&TREE_OPERAND (t
, 1), &for_pre_body
, NULL
,
12332 is_gimple_val
, fb_rvalue
, false);
12333 gimplify_omp_ctxp
->in_for_exprs
= false;
12334 ret
= MIN (ret
, tret
);
12336 /* Handle OMP_FOR_INCR. */
12337 t
= TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
);
12338 switch (TREE_CODE (t
))
12340 case PREINCREMENT_EXPR
:
12341 case POSTINCREMENT_EXPR
:
12343 tree decl
= TREE_OPERAND (t
, 0);
12344 /* c_omp_for_incr_canonicalize_ptr() should have been
12345 called to massage things appropriately. */
12346 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl
)));
12348 if (orig_for_stmt
!= for_stmt
)
12350 t
= build_int_cst (TREE_TYPE (decl
), 1);
12352 OMP_CLAUSE_LINEAR_STEP (c
) = t
;
12353 t
= build2 (PLUS_EXPR
, TREE_TYPE (decl
), var
, t
);
12354 t
= build2 (MODIFY_EXPR
, TREE_TYPE (var
), var
, t
);
12355 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
) = t
;
12359 case PREDECREMENT_EXPR
:
12360 case POSTDECREMENT_EXPR
:
12361 /* c_omp_for_incr_canonicalize_ptr() should have been
12362 called to massage things appropriately. */
12363 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl
)));
12364 if (orig_for_stmt
!= for_stmt
)
12366 t
= build_int_cst (TREE_TYPE (decl
), -1);
12368 OMP_CLAUSE_LINEAR_STEP (c
) = t
;
12369 t
= build2 (PLUS_EXPR
, TREE_TYPE (decl
), var
, t
);
12370 t
= build2 (MODIFY_EXPR
, TREE_TYPE (var
), var
, t
);
12371 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
) = t
;
12375 gcc_assert (TREE_OPERAND (t
, 0) == decl
);
12376 TREE_OPERAND (t
, 0) = var
;
12378 t
= TREE_OPERAND (t
, 1);
12379 switch (TREE_CODE (t
))
12382 if (TREE_OPERAND (t
, 1) == decl
)
12384 TREE_OPERAND (t
, 1) = TREE_OPERAND (t
, 0);
12385 TREE_OPERAND (t
, 0) = var
;
12391 case POINTER_PLUS_EXPR
:
12392 gcc_assert (TREE_OPERAND (t
, 0) == decl
);
12393 TREE_OPERAND (t
, 0) = var
;
12396 gcc_unreachable ();
12399 gimplify_omp_ctxp
->in_for_exprs
= true;
12400 tret
= gimplify_expr (&TREE_OPERAND (t
, 1), &for_pre_body
, NULL
,
12401 is_gimple_val
, fb_rvalue
, false);
12402 ret
= MIN (ret
, tret
);
12405 tree step
= TREE_OPERAND (t
, 1);
12406 tree stept
= TREE_TYPE (decl
);
12407 if (POINTER_TYPE_P (stept
))
12409 step
= fold_convert (stept
, step
);
12410 if (TREE_CODE (t
) == MINUS_EXPR
)
12411 step
= fold_build1 (NEGATE_EXPR
, stept
, step
);
12412 OMP_CLAUSE_LINEAR_STEP (c
) = step
;
12413 if (step
!= TREE_OPERAND (t
, 1))
12415 tret
= gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c
),
12416 &for_pre_body
, NULL
,
12417 is_gimple_val
, fb_rvalue
, false);
12418 ret
= MIN (ret
, tret
);
12421 gimplify_omp_ctxp
->in_for_exprs
= false;
12425 gcc_unreachable ();
12431 OMP_CLAUSE_LINEAR_STEP (c2
) = OMP_CLAUSE_LINEAR_STEP (c
);
12434 if ((var
!= decl
|| collapse
> 1 || tile
) && orig_for_stmt
== for_stmt
)
12436 for (c
= OMP_FOR_CLAUSES (for_stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
12437 if (((OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
12438 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
) == NULL
)
12439 || (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINEAR
12440 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c
)
12441 && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c
) == NULL
))
12442 && OMP_CLAUSE_DECL (c
) == decl
)
12444 if (is_doacross
&& (collapse
== 1 || i
>= collapse
))
12448 t
= TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
);
12449 gcc_assert (TREE_CODE (t
) == MODIFY_EXPR
);
12450 gcc_assert (TREE_OPERAND (t
, 0) == var
);
12451 t
= TREE_OPERAND (t
, 1);
12452 gcc_assert (TREE_CODE (t
) == PLUS_EXPR
12453 || TREE_CODE (t
) == MINUS_EXPR
12454 || TREE_CODE (t
) == POINTER_PLUS_EXPR
);
12455 gcc_assert (TREE_OPERAND (t
, 0) == var
);
12456 t
= build2 (TREE_CODE (t
), TREE_TYPE (decl
),
12457 is_doacross
? var
: decl
,
12458 TREE_OPERAND (t
, 1));
12461 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
)
12462 seq
= &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
);
12464 seq
= &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c
);
12465 push_gimplify_context ();
12466 gimplify_assign (decl
, t
, seq
);
12467 gimple
*bind
= NULL
;
12468 if (gimplify_ctxp
->temps
)
12470 bind
= gimple_build_bind (NULL_TREE
, *seq
, NULL_TREE
);
12472 gimplify_seq_add_stmt (seq
, bind
);
12474 pop_gimplify_context (bind
);
12477 if (OMP_FOR_NON_RECTANGULAR (for_stmt
) && var
!= decl
)
12478 for (int j
= i
+ 1; j
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); j
++)
12480 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), j
);
12481 gcc_assert (TREE_CODE (t
) == MODIFY_EXPR
);
12482 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
12483 && TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) == decl
)
12484 TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) = var
;
12485 t
= TREE_VEC_ELT (OMP_FOR_COND (for_stmt
), j
);
12486 gcc_assert (COMPARISON_CLASS_P (t
));
12487 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
12488 && TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) == decl
)
12489 TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) = var
;
12493 BITMAP_FREE (has_decl_expr
);
12494 delete allocate_uids
;
12496 if (TREE_CODE (orig_for_stmt
) == OMP_TASKLOOP
12497 || (loop_p
&& orig_for_stmt
== for_stmt
))
12499 push_gimplify_context ();
12500 if (TREE_CODE (OMP_FOR_BODY (orig_for_stmt
)) != BIND_EXPR
)
12502 OMP_FOR_BODY (orig_for_stmt
)
12503 = build3 (BIND_EXPR
, void_type_node
, NULL
,
12504 OMP_FOR_BODY (orig_for_stmt
), NULL
);
12505 TREE_SIDE_EFFECTS (OMP_FOR_BODY (orig_for_stmt
)) = 1;
12509 gimple
*g
= gimplify_and_return_first (OMP_FOR_BODY (orig_for_stmt
),
12512 if (TREE_CODE (orig_for_stmt
) == OMP_TASKLOOP
12513 || (loop_p
&& orig_for_stmt
== for_stmt
))
12515 if (gimple_code (g
) == GIMPLE_BIND
)
12516 pop_gimplify_context (g
);
12518 pop_gimplify_context (NULL
);
12521 if (orig_for_stmt
!= for_stmt
)
12522 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
12524 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), i
);
12525 decl
= TREE_OPERAND (t
, 0);
12526 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
12527 if (TREE_CODE (orig_for_stmt
) == OMP_TASKLOOP
)
12528 gimplify_omp_ctxp
= ctx
->outer_context
;
12529 var
= create_tmp_var (TREE_TYPE (decl
), get_name (decl
));
12530 gimplify_omp_ctxp
= ctx
;
12531 omp_add_variable (gimplify_omp_ctxp
, var
, GOVD_PRIVATE
| GOVD_SEEN
);
12532 TREE_OPERAND (t
, 0) = var
;
12533 t
= TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
);
12534 TREE_OPERAND (t
, 1) = copy_node (TREE_OPERAND (t
, 1));
12535 TREE_OPERAND (TREE_OPERAND (t
, 1), 0) = var
;
12536 if (OMP_FOR_NON_RECTANGULAR (for_stmt
))
12537 for (int j
= i
+ 1;
12538 j
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); j
++)
12540 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), j
);
12541 gcc_assert (TREE_CODE (t
) == MODIFY_EXPR
);
12542 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
12543 && TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) == decl
)
12545 TREE_OPERAND (t
, 1) = copy_node (TREE_OPERAND (t
, 1));
12546 TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) = var
;
12548 t
= TREE_VEC_ELT (OMP_FOR_COND (for_stmt
), j
);
12549 gcc_assert (COMPARISON_CLASS_P (t
));
12550 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
12551 && TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) == decl
)
12553 TREE_OPERAND (t
, 1) = copy_node (TREE_OPERAND (t
, 1));
12554 TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) = var
;
12559 gimplify_adjust_omp_clauses (pre_p
, for_body
,
12560 &OMP_FOR_CLAUSES (orig_for_stmt
),
12561 TREE_CODE (orig_for_stmt
));
12564 switch (TREE_CODE (orig_for_stmt
))
12566 case OMP_FOR
: kind
= GF_OMP_FOR_KIND_FOR
; break;
12567 case OMP_SIMD
: kind
= GF_OMP_FOR_KIND_SIMD
; break;
12568 case OMP_DISTRIBUTE
: kind
= GF_OMP_FOR_KIND_DISTRIBUTE
; break;
12569 case OMP_TASKLOOP
: kind
= GF_OMP_FOR_KIND_TASKLOOP
; break;
12570 case OACC_LOOP
: kind
= GF_OMP_FOR_KIND_OACC_LOOP
; break;
12572 gcc_unreachable ();
12574 if (loop_p
&& kind
== GF_OMP_FOR_KIND_SIMD
)
12576 gimplify_seq_add_seq (pre_p
, for_pre_body
);
12577 for_pre_body
= NULL
;
12579 gfor
= gimple_build_omp_for (for_body
, kind
, OMP_FOR_CLAUSES (orig_for_stmt
),
12580 TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)),
12582 if (orig_for_stmt
!= for_stmt
)
12583 gimple_omp_for_set_combined_p (gfor
, true);
12584 if (gimplify_omp_ctxp
12585 && (gimplify_omp_ctxp
->combined_loop
12586 || (gimplify_omp_ctxp
->region_type
== ORT_COMBINED_PARALLEL
12587 && gimplify_omp_ctxp
->outer_context
12588 && gimplify_omp_ctxp
->outer_context
->combined_loop
)))
12590 gimple_omp_for_set_combined_into_p (gfor
, true);
12591 if (gimplify_omp_ctxp
->combined_loop
)
12592 gcc_assert (TREE_CODE (orig_for_stmt
) == OMP_SIMD
);
12594 gcc_assert (TREE_CODE (orig_for_stmt
) == OMP_FOR
);
12597 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
12599 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), i
);
12600 gimple_omp_for_set_index (gfor
, i
, TREE_OPERAND (t
, 0));
12601 gimple_omp_for_set_initial (gfor
, i
, TREE_OPERAND (t
, 1));
12602 t
= TREE_VEC_ELT (OMP_FOR_COND (for_stmt
), i
);
12603 gimple_omp_for_set_cond (gfor
, i
, TREE_CODE (t
));
12604 gimple_omp_for_set_final (gfor
, i
, TREE_OPERAND (t
, 1));
12605 t
= TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
);
12606 gimple_omp_for_set_incr (gfor
, i
, TREE_OPERAND (t
, 1));
12609 /* OMP_TASKLOOP is gimplified as two GIMPLE_OMP_FOR taskloop
12610 constructs with GIMPLE_OMP_TASK sandwiched in between them.
12611 The outer taskloop stands for computing the number of iterations,
12612 counts for collapsed loops and holding taskloop specific clauses.
12613 The task construct stands for the effect of data sharing on the
12614 explicit task it creates and the inner taskloop stands for expansion
12615 of the static loop inside of the explicit task construct. */
12616 if (TREE_CODE (orig_for_stmt
) == OMP_TASKLOOP
)
12618 tree
*gfor_clauses_ptr
= gimple_omp_for_clauses_ptr (gfor
);
12619 tree task_clauses
= NULL_TREE
;
12620 tree c
= *gfor_clauses_ptr
;
12621 tree
*gtask_clauses_ptr
= &task_clauses
;
12622 tree outer_for_clauses
= NULL_TREE
;
12623 tree
*gforo_clauses_ptr
= &outer_for_clauses
;
12624 bitmap lastprivate_uids
= NULL
;
12625 if (omp_find_clause (c
, OMP_CLAUSE_ALLOCATE
))
12627 c
= omp_find_clause (c
, OMP_CLAUSE_LASTPRIVATE
);
12630 lastprivate_uids
= BITMAP_ALLOC (NULL
);
12631 for (; c
; c
= omp_find_clause (OMP_CLAUSE_CHAIN (c
),
12632 OMP_CLAUSE_LASTPRIVATE
))
12633 bitmap_set_bit (lastprivate_uids
,
12634 DECL_UID (OMP_CLAUSE_DECL (c
)));
12636 c
= *gfor_clauses_ptr
;
12638 for (; c
; c
= OMP_CLAUSE_CHAIN (c
))
12639 switch (OMP_CLAUSE_CODE (c
))
12641 /* These clauses are allowed on task, move them there. */
12642 case OMP_CLAUSE_SHARED
:
12643 case OMP_CLAUSE_FIRSTPRIVATE
:
12644 case OMP_CLAUSE_DEFAULT
:
12645 case OMP_CLAUSE_IF
:
12646 case OMP_CLAUSE_UNTIED
:
12647 case OMP_CLAUSE_FINAL
:
12648 case OMP_CLAUSE_MERGEABLE
:
12649 case OMP_CLAUSE_PRIORITY
:
12650 case OMP_CLAUSE_REDUCTION
:
12651 case OMP_CLAUSE_IN_REDUCTION
:
12652 *gtask_clauses_ptr
= c
;
12653 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
12655 case OMP_CLAUSE_PRIVATE
:
12656 if (OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c
))
12658 /* We want private on outer for and firstprivate
12661 = build_omp_clause (OMP_CLAUSE_LOCATION (c
),
12662 OMP_CLAUSE_FIRSTPRIVATE
);
12663 OMP_CLAUSE_DECL (*gtask_clauses_ptr
) = OMP_CLAUSE_DECL (c
);
12664 lang_hooks
.decls
.omp_finish_clause (*gtask_clauses_ptr
, NULL
,
12666 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr
);
12667 *gforo_clauses_ptr
= c
;
12668 gforo_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
12672 *gtask_clauses_ptr
= c
;
12673 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
12676 /* These clauses go into outer taskloop clauses. */
12677 case OMP_CLAUSE_GRAINSIZE
:
12678 case OMP_CLAUSE_NUM_TASKS
:
12679 case OMP_CLAUSE_NOGROUP
:
12680 *gforo_clauses_ptr
= c
;
12681 gforo_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
12683 /* Collapse clause we duplicate on both taskloops. */
12684 case OMP_CLAUSE_COLLAPSE
:
12685 *gfor_clauses_ptr
= c
;
12686 gfor_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
12687 *gforo_clauses_ptr
= copy_node (c
);
12688 gforo_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr
);
12690 /* For lastprivate, keep the clause on inner taskloop, and add
12691 a shared clause on task. If the same decl is also firstprivate,
12692 add also firstprivate clause on the inner taskloop. */
12693 case OMP_CLAUSE_LASTPRIVATE
:
12694 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c
))
12696 /* For taskloop C++ lastprivate IVs, we want:
12697 1) private on outer taskloop
12698 2) firstprivate and shared on task
12699 3) lastprivate on inner taskloop */
12701 = build_omp_clause (OMP_CLAUSE_LOCATION (c
),
12702 OMP_CLAUSE_FIRSTPRIVATE
);
12703 OMP_CLAUSE_DECL (*gtask_clauses_ptr
) = OMP_CLAUSE_DECL (c
);
12704 lang_hooks
.decls
.omp_finish_clause (*gtask_clauses_ptr
, NULL
,
12706 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr
);
12707 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
) = 1;
12708 *gforo_clauses_ptr
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
12709 OMP_CLAUSE_PRIVATE
);
12710 OMP_CLAUSE_DECL (*gforo_clauses_ptr
) = OMP_CLAUSE_DECL (c
);
12711 OMP_CLAUSE_PRIVATE_TASKLOOP_IV (*gforo_clauses_ptr
) = 1;
12712 TREE_TYPE (*gforo_clauses_ptr
) = TREE_TYPE (c
);
12713 gforo_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr
);
12715 *gfor_clauses_ptr
= c
;
12716 gfor_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
12718 = build_omp_clause (OMP_CLAUSE_LOCATION (c
), OMP_CLAUSE_SHARED
);
12719 OMP_CLAUSE_DECL (*gtask_clauses_ptr
) = OMP_CLAUSE_DECL (c
);
12720 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
))
12721 OMP_CLAUSE_SHARED_FIRSTPRIVATE (*gtask_clauses_ptr
) = 1;
12723 = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr
);
12725 /* Allocate clause we duplicate on task and inner taskloop
12726 if the decl is lastprivate, otherwise just put on task. */
12727 case OMP_CLAUSE_ALLOCATE
:
12728 if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
)
12729 && DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
)))
12731 /* Additionally, put firstprivate clause on task
12732 for the allocator if it is not constant. */
12734 = build_omp_clause (OMP_CLAUSE_LOCATION (c
),
12735 OMP_CLAUSE_FIRSTPRIVATE
);
12736 OMP_CLAUSE_DECL (*gtask_clauses_ptr
)
12737 = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
);
12738 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr
);
12740 if (lastprivate_uids
12741 && bitmap_bit_p (lastprivate_uids
,
12742 DECL_UID (OMP_CLAUSE_DECL (c
))))
12744 *gfor_clauses_ptr
= c
;
12745 gfor_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
12746 *gtask_clauses_ptr
= copy_node (c
);
12747 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr
);
12751 *gtask_clauses_ptr
= c
;
12752 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
12756 gcc_unreachable ();
12758 *gfor_clauses_ptr
= NULL_TREE
;
12759 *gtask_clauses_ptr
= NULL_TREE
;
12760 *gforo_clauses_ptr
= NULL_TREE
;
12761 BITMAP_FREE (lastprivate_uids
);
12762 g
= gimple_build_bind (NULL_TREE
, gfor
, NULL_TREE
);
12763 g
= gimple_build_omp_task (g
, task_clauses
, NULL_TREE
, NULL_TREE
,
12764 NULL_TREE
, NULL_TREE
, NULL_TREE
);
12765 gimple_omp_task_set_taskloop_p (g
, true);
12766 g
= gimple_build_bind (NULL_TREE
, g
, NULL_TREE
);
12768 = gimple_build_omp_for (g
, GF_OMP_FOR_KIND_TASKLOOP
, outer_for_clauses
,
12769 gimple_omp_for_collapse (gfor
),
12770 gimple_omp_for_pre_body (gfor
));
12771 gimple_omp_for_set_pre_body (gfor
, NULL
);
12772 gimple_omp_for_set_combined_p (gforo
, true);
12773 gimple_omp_for_set_combined_into_p (gfor
, true);
12774 for (i
= 0; i
< (int) gimple_omp_for_collapse (gfor
); i
++)
12776 tree type
= TREE_TYPE (gimple_omp_for_index (gfor
, i
));
12777 tree v
= create_tmp_var (type
);
12778 gimple_omp_for_set_index (gforo
, i
, v
);
12779 t
= unshare_expr (gimple_omp_for_initial (gfor
, i
));
12780 gimple_omp_for_set_initial (gforo
, i
, t
);
12781 gimple_omp_for_set_cond (gforo
, i
,
12782 gimple_omp_for_cond (gfor
, i
));
12783 t
= unshare_expr (gimple_omp_for_final (gfor
, i
));
12784 gimple_omp_for_set_final (gforo
, i
, t
);
12785 t
= unshare_expr (gimple_omp_for_incr (gfor
, i
));
12786 gcc_assert (TREE_OPERAND (t
, 0) == gimple_omp_for_index (gfor
, i
));
12787 TREE_OPERAND (t
, 0) = v
;
12788 gimple_omp_for_set_incr (gforo
, i
, t
);
12789 t
= build_omp_clause (input_location
, OMP_CLAUSE_PRIVATE
);
12790 OMP_CLAUSE_DECL (t
) = v
;
12791 OMP_CLAUSE_CHAIN (t
) = gimple_omp_for_clauses (gforo
);
12792 gimple_omp_for_set_clauses (gforo
, t
);
12793 if (OMP_FOR_NON_RECTANGULAR (for_stmt
))
12795 tree
*p1
= NULL
, *p2
= NULL
;
12796 t
= gimple_omp_for_initial (gforo
, i
);
12797 if (TREE_CODE (t
) == TREE_VEC
)
12798 p1
= &TREE_VEC_ELT (t
, 0);
12799 t
= gimple_omp_for_final (gforo
, i
);
12800 if (TREE_CODE (t
) == TREE_VEC
)
12803 p2
= &TREE_VEC_ELT (t
, 0);
12805 p1
= &TREE_VEC_ELT (t
, 0);
12810 for (j
= 0; j
< i
; j
++)
12811 if (*p1
== gimple_omp_for_index (gfor
, j
))
12813 *p1
= gimple_omp_for_index (gforo
, j
);
12818 gcc_assert (j
< i
);
12822 gimplify_seq_add_stmt (pre_p
, gforo
);
12825 gimplify_seq_add_stmt (pre_p
, gfor
);
12827 if (TREE_CODE (orig_for_stmt
) == OMP_FOR
)
12829 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
12830 unsigned lastprivate_conditional
= 0;
12832 && (ctx
->region_type
== ORT_TARGET_DATA
12833 || ctx
->region_type
== ORT_TASKGROUP
))
12834 ctx
= ctx
->outer_context
;
12835 if (ctx
&& (ctx
->region_type
& ORT_PARALLEL
) != 0)
12836 for (tree c
= gimple_omp_for_clauses (gfor
);
12837 c
; c
= OMP_CLAUSE_CHAIN (c
))
12838 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
12839 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
))
12840 ++lastprivate_conditional
;
12841 if (lastprivate_conditional
)
12843 struct omp_for_data fd
;
12844 omp_extract_for_data (gfor
, &fd
, NULL
);
12845 tree type
= build_array_type_nelts (unsigned_type_for (fd
.iter_type
),
12846 lastprivate_conditional
);
12847 tree var
= create_tmp_var_raw (type
);
12848 tree c
= build_omp_clause (UNKNOWN_LOCATION
, OMP_CLAUSE__CONDTEMP_
);
12849 OMP_CLAUSE_DECL (c
) = var
;
12850 OMP_CLAUSE_CHAIN (c
) = gimple_omp_for_clauses (gfor
);
12851 gimple_omp_for_set_clauses (gfor
, c
);
12852 omp_add_variable (ctx
, var
, GOVD_CONDTEMP
| GOVD_SEEN
);
12855 else if (TREE_CODE (orig_for_stmt
) == OMP_SIMD
)
12857 unsigned lastprivate_conditional
= 0;
12858 for (tree c
= gimple_omp_for_clauses (gfor
); c
; c
= OMP_CLAUSE_CHAIN (c
))
12859 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
12860 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
))
12861 ++lastprivate_conditional
;
12862 if (lastprivate_conditional
)
12864 struct omp_for_data fd
;
12865 omp_extract_for_data (gfor
, &fd
, NULL
);
12866 tree type
= unsigned_type_for (fd
.iter_type
);
12867 while (lastprivate_conditional
--)
12869 tree c
= build_omp_clause (UNKNOWN_LOCATION
,
12870 OMP_CLAUSE__CONDTEMP_
);
12871 OMP_CLAUSE_DECL (c
) = create_tmp_var (type
);
12872 OMP_CLAUSE_CHAIN (c
) = gimple_omp_for_clauses (gfor
);
12873 gimple_omp_for_set_clauses (gfor
, c
);
12878 if (ret
!= GS_ALL_DONE
)
12880 *expr_p
= NULL_TREE
;
12881 return GS_ALL_DONE
;
12884 /* Helper for gimplify_omp_loop, called through walk_tree. */
12887 replace_reduction_placeholders (tree
*tp
, int *walk_subtrees
, void *data
)
12891 tree
*d
= (tree
*) data
;
12892 if (*tp
== OMP_CLAUSE_REDUCTION_PLACEHOLDER (d
[0]))
12894 *tp
= OMP_CLAUSE_REDUCTION_PLACEHOLDER (d
[1]);
12895 *walk_subtrees
= 0;
12897 else if (*tp
== OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (d
[0]))
12899 *tp
= OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (d
[1]);
12900 *walk_subtrees
= 0;
12906 /* Gimplify the gross structure of an OMP_LOOP statement. */
12908 static enum gimplify_status
12909 gimplify_omp_loop (tree
*expr_p
, gimple_seq
*pre_p
)
12911 tree for_stmt
= *expr_p
;
12912 tree clauses
= OMP_FOR_CLAUSES (for_stmt
);
12913 struct gimplify_omp_ctx
*octx
= gimplify_omp_ctxp
;
12914 enum omp_clause_bind_kind kind
= OMP_CLAUSE_BIND_THREAD
;
12917 /* If order is not present, the behavior is as if order(concurrent)
12919 tree order
= omp_find_clause (clauses
, OMP_CLAUSE_ORDER
);
12920 if (order
== NULL_TREE
)
12922 order
= build_omp_clause (UNKNOWN_LOCATION
, OMP_CLAUSE_ORDER
);
12923 OMP_CLAUSE_CHAIN (order
) = clauses
;
12924 OMP_FOR_CLAUSES (for_stmt
) = clauses
= order
;
12927 tree bind
= omp_find_clause (clauses
, OMP_CLAUSE_BIND
);
12928 if (bind
== NULL_TREE
)
12930 if (!flag_openmp
) /* flag_openmp_simd */
12932 else if (octx
&& (octx
->region_type
& ORT_TEAMS
) != 0)
12933 kind
= OMP_CLAUSE_BIND_TEAMS
;
12934 else if (octx
&& (octx
->region_type
& ORT_PARALLEL
) != 0)
12935 kind
= OMP_CLAUSE_BIND_PARALLEL
;
12938 for (; octx
; octx
= octx
->outer_context
)
12940 if ((octx
->region_type
& ORT_ACC
) != 0
12941 || octx
->region_type
== ORT_NONE
12942 || octx
->region_type
== ORT_IMPLICIT_TARGET
)
12946 if (octx
== NULL
&& !in_omp_construct
)
12947 error_at (EXPR_LOCATION (for_stmt
),
12948 "%<bind%> clause not specified on a %<loop%> "
12949 "construct not nested inside another OpenMP construct");
12951 bind
= build_omp_clause (UNKNOWN_LOCATION
, OMP_CLAUSE_BIND
);
12952 OMP_CLAUSE_CHAIN (bind
) = clauses
;
12953 OMP_CLAUSE_BIND_KIND (bind
) = kind
;
12954 OMP_FOR_CLAUSES (for_stmt
) = bind
;
12957 switch (OMP_CLAUSE_BIND_KIND (bind
))
12959 case OMP_CLAUSE_BIND_THREAD
:
12961 case OMP_CLAUSE_BIND_PARALLEL
:
12962 if (!flag_openmp
) /* flag_openmp_simd */
12964 OMP_CLAUSE_BIND_KIND (bind
) = OMP_CLAUSE_BIND_THREAD
;
12967 for (; octx
; octx
= octx
->outer_context
)
12968 if (octx
->region_type
== ORT_SIMD
12969 && omp_find_clause (octx
->clauses
, OMP_CLAUSE_BIND
) == NULL_TREE
)
12971 error_at (EXPR_LOCATION (for_stmt
),
12972 "%<bind(parallel)%> on a %<loop%> construct nested "
12973 "inside %<simd%> construct");
12974 OMP_CLAUSE_BIND_KIND (bind
) = OMP_CLAUSE_BIND_THREAD
;
12977 kind
= OMP_CLAUSE_BIND_PARALLEL
;
12979 case OMP_CLAUSE_BIND_TEAMS
:
12980 if (!flag_openmp
) /* flag_openmp_simd */
12982 OMP_CLAUSE_BIND_KIND (bind
) = OMP_CLAUSE_BIND_THREAD
;
12986 && octx
->region_type
!= ORT_IMPLICIT_TARGET
12987 && octx
->region_type
!= ORT_NONE
12988 && (octx
->region_type
& ORT_TEAMS
) == 0)
12989 || in_omp_construct
)
12991 error_at (EXPR_LOCATION (for_stmt
),
12992 "%<bind(teams)%> on a %<loop%> region not strictly "
12993 "nested inside of a %<teams%> region");
12994 OMP_CLAUSE_BIND_KIND (bind
) = OMP_CLAUSE_BIND_THREAD
;
12997 kind
= OMP_CLAUSE_BIND_TEAMS
;
13000 gcc_unreachable ();
13003 for (tree
*pc
= &OMP_FOR_CLAUSES (for_stmt
); *pc
; )
13004 switch (OMP_CLAUSE_CODE (*pc
))
13006 case OMP_CLAUSE_REDUCTION
:
13007 if (OMP_CLAUSE_REDUCTION_INSCAN (*pc
))
13009 error_at (OMP_CLAUSE_LOCATION (*pc
),
13010 "%<inscan%> %<reduction%> clause on "
13011 "%qs construct", "loop");
13012 OMP_CLAUSE_REDUCTION_INSCAN (*pc
) = 0;
13014 if (OMP_CLAUSE_REDUCTION_TASK (*pc
))
13016 error_at (OMP_CLAUSE_LOCATION (*pc
),
13017 "invalid %<task%> reduction modifier on construct "
13018 "other than %<parallel%>, %qs or %<sections%>",
13019 lang_GNU_Fortran () ? "do" : "for");
13020 OMP_CLAUSE_REDUCTION_TASK (*pc
) = 0;
13022 pc
= &OMP_CLAUSE_CHAIN (*pc
);
13024 case OMP_CLAUSE_LASTPRIVATE
:
13025 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
13027 tree t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), i
);
13028 gcc_assert (TREE_CODE (t
) == MODIFY_EXPR
);
13029 if (OMP_CLAUSE_DECL (*pc
) == TREE_OPERAND (t
, 0))
13031 if (OMP_FOR_ORIG_DECLS (for_stmt
)
13032 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
),
13034 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
),
13037 tree orig
= TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
), i
);
13038 if (OMP_CLAUSE_DECL (*pc
) == TREE_PURPOSE (orig
))
13042 if (i
== TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)))
13044 error_at (OMP_CLAUSE_LOCATION (*pc
),
13045 "%<lastprivate%> clause on a %<loop%> construct refers "
13046 "to a variable %qD which is not the loop iterator",
13047 OMP_CLAUSE_DECL (*pc
));
13048 *pc
= OMP_CLAUSE_CHAIN (*pc
);
13051 pc
= &OMP_CLAUSE_CHAIN (*pc
);
13054 pc
= &OMP_CLAUSE_CHAIN (*pc
);
13058 TREE_SET_CODE (for_stmt
, OMP_SIMD
);
13063 case OMP_CLAUSE_BIND_THREAD
: last
= 0; break;
13064 case OMP_CLAUSE_BIND_PARALLEL
: last
= 1; break;
13065 case OMP_CLAUSE_BIND_TEAMS
: last
= 2; break;
13067 for (int pass
= 1; pass
<= last
; pass
++)
13071 tree bind
= build3 (BIND_EXPR
, void_type_node
, NULL
, NULL
, NULL
);
13072 append_to_statement_list (*expr_p
, &BIND_EXPR_BODY (bind
));
13073 *expr_p
= make_node (OMP_PARALLEL
);
13074 TREE_TYPE (*expr_p
) = void_type_node
;
13075 OMP_PARALLEL_BODY (*expr_p
) = bind
;
13076 OMP_PARALLEL_COMBINED (*expr_p
) = 1;
13077 SET_EXPR_LOCATION (*expr_p
, EXPR_LOCATION (for_stmt
));
13078 tree
*pc
= &OMP_PARALLEL_CLAUSES (*expr_p
);
13079 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
13080 if (OMP_FOR_ORIG_DECLS (for_stmt
)
13081 && (TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
), i
))
13084 tree elt
= TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
), i
);
13085 if (TREE_PURPOSE (elt
) && TREE_VALUE (elt
))
13087 *pc
= build_omp_clause (UNKNOWN_LOCATION
,
13088 OMP_CLAUSE_FIRSTPRIVATE
);
13089 OMP_CLAUSE_DECL (*pc
) = TREE_VALUE (elt
);
13090 pc
= &OMP_CLAUSE_CHAIN (*pc
);
13094 tree t
= make_node (pass
== 2 ? OMP_DISTRIBUTE
: OMP_FOR
);
13095 tree
*pc
= &OMP_FOR_CLAUSES (t
);
13096 TREE_TYPE (t
) = void_type_node
;
13097 OMP_FOR_BODY (t
) = *expr_p
;
13098 SET_EXPR_LOCATION (t
, EXPR_LOCATION (for_stmt
));
13099 for (tree c
= OMP_FOR_CLAUSES (for_stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
13100 switch (OMP_CLAUSE_CODE (c
))
13102 case OMP_CLAUSE_BIND
:
13103 case OMP_CLAUSE_ORDER
:
13104 case OMP_CLAUSE_COLLAPSE
:
13105 *pc
= copy_node (c
);
13106 pc
= &OMP_CLAUSE_CHAIN (*pc
);
13108 case OMP_CLAUSE_PRIVATE
:
13109 case OMP_CLAUSE_FIRSTPRIVATE
:
13110 /* Only needed on innermost. */
13112 case OMP_CLAUSE_LASTPRIVATE
:
13113 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c
) && pass
!= last
)
13115 *pc
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
13116 OMP_CLAUSE_FIRSTPRIVATE
);
13117 OMP_CLAUSE_DECL (*pc
) = OMP_CLAUSE_DECL (c
);
13118 lang_hooks
.decls
.omp_finish_clause (*pc
, NULL
, false);
13119 pc
= &OMP_CLAUSE_CHAIN (*pc
);
13121 *pc
= copy_node (c
);
13122 OMP_CLAUSE_LASTPRIVATE_STMT (*pc
) = NULL_TREE
;
13123 TREE_TYPE (*pc
) = unshare_expr (TREE_TYPE (c
));
13124 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c
))
13127 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (*pc
) = 1;
13129 lang_hooks
.decls
.omp_finish_clause (*pc
, NULL
, false);
13130 OMP_CLAUSE_LASTPRIVATE_LOOP_IV (*pc
) = 0;
13132 pc
= &OMP_CLAUSE_CHAIN (*pc
);
13134 case OMP_CLAUSE_REDUCTION
:
13135 *pc
= copy_node (c
);
13136 OMP_CLAUSE_DECL (*pc
) = unshare_expr (OMP_CLAUSE_DECL (c
));
13137 TREE_TYPE (*pc
) = unshare_expr (TREE_TYPE (c
));
13138 OMP_CLAUSE_REDUCTION_INIT (*pc
)
13139 = unshare_expr (OMP_CLAUSE_REDUCTION_INIT (c
));
13140 OMP_CLAUSE_REDUCTION_MERGE (*pc
)
13141 = unshare_expr (OMP_CLAUSE_REDUCTION_MERGE (c
));
13142 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc
))
13144 OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc
)
13145 = copy_node (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
));
13146 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc
))
13147 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc
)
13148 = copy_node (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c
));
13150 tree data
[2] = { c
, nc
};
13151 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_INIT (nc
),
13152 replace_reduction_placeholders
,
13154 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_MERGE (nc
),
13155 replace_reduction_placeholders
,
13158 pc
= &OMP_CLAUSE_CHAIN (*pc
);
13161 gcc_unreachable ();
13166 return gimplify_omp_for (expr_p
, pre_p
);
13170 /* Helper function of optimize_target_teams, find OMP_TEAMS inside
13171 of OMP_TARGET's body. */
13174 find_omp_teams (tree
*tp
, int *walk_subtrees
, void *)
13176 *walk_subtrees
= 0;
13177 switch (TREE_CODE (*tp
))
13182 case STATEMENT_LIST
:
13183 *walk_subtrees
= 1;
13191 /* Helper function of optimize_target_teams, determine if the expression
13192 can be computed safely before the target construct on the host. */
13195 computable_teams_clause (tree
*tp
, int *walk_subtrees
, void *)
13201 *walk_subtrees
= 0;
13204 switch (TREE_CODE (*tp
))
13209 *walk_subtrees
= 0;
13210 if (error_operand_p (*tp
)
13211 || !INTEGRAL_TYPE_P (TREE_TYPE (*tp
))
13212 || DECL_HAS_VALUE_EXPR_P (*tp
)
13213 || DECL_THREAD_LOCAL_P (*tp
)
13214 || TREE_SIDE_EFFECTS (*tp
)
13215 || TREE_THIS_VOLATILE (*tp
))
13217 if (is_global_var (*tp
)
13218 && (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (*tp
))
13219 || lookup_attribute ("omp declare target link",
13220 DECL_ATTRIBUTES (*tp
))))
13223 && !DECL_SEEN_IN_BIND_EXPR_P (*tp
)
13224 && !is_global_var (*tp
)
13225 && decl_function_context (*tp
) == current_function_decl
)
13227 n
= splay_tree_lookup (gimplify_omp_ctxp
->variables
,
13228 (splay_tree_key
) *tp
);
13231 if (gimplify_omp_ctxp
->defaultmap
[GDMK_SCALAR
] & GOVD_FIRSTPRIVATE
)
13235 else if (n
->value
& GOVD_LOCAL
)
13237 else if (n
->value
& GOVD_FIRSTPRIVATE
)
13239 else if ((n
->value
& (GOVD_MAP
| GOVD_MAP_ALWAYS_TO
))
13240 == (GOVD_MAP
| GOVD_MAP_ALWAYS_TO
))
13244 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp
)))
13248 if (TARGET_EXPR_INITIAL (*tp
)
13249 || TREE_CODE (TARGET_EXPR_SLOT (*tp
)) != VAR_DECL
)
13251 return computable_teams_clause (&TARGET_EXPR_SLOT (*tp
),
13252 walk_subtrees
, NULL
);
13253 /* Allow some reasonable subset of integral arithmetics. */
13257 case TRUNC_DIV_EXPR
:
13258 case CEIL_DIV_EXPR
:
13259 case FLOOR_DIV_EXPR
:
13260 case ROUND_DIV_EXPR
:
13261 case TRUNC_MOD_EXPR
:
13262 case CEIL_MOD_EXPR
:
13263 case FLOOR_MOD_EXPR
:
13264 case ROUND_MOD_EXPR
:
13266 case EXACT_DIV_EXPR
:
13277 case NON_LVALUE_EXPR
:
13279 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp
)))
13282 /* And disallow anything else, except for comparisons. */
13284 if (COMPARISON_CLASS_P (*tp
))
13290 /* Try to determine if the num_teams and/or thread_limit expressions
13291 can have their values determined already before entering the
13293 INTEGER_CSTs trivially are,
13294 integral decls that are firstprivate (explicitly or implicitly)
13295 or explicitly map(always, to:) or map(always, tofrom:) on the target
13296 region too, and expressions involving simple arithmetics on those
13297 too, function calls are not ok, dereferencing something neither etc.
13298 Add NUM_TEAMS and THREAD_LIMIT clauses to the OMP_CLAUSES of
13299 EXPR based on what we find:
13300 0 stands for clause not specified at all, use implementation default
13301 -1 stands for value that can't be determined easily before entering
13302 the target construct.
13303 If teams construct is not present at all, use 1 for num_teams
13304 and 0 for thread_limit (only one team is involved, and the thread
13305 limit is implementation defined. */
13308 optimize_target_teams (tree target
, gimple_seq
*pre_p
)
13310 tree body
= OMP_BODY (target
);
13311 tree teams
= walk_tree (&body
, find_omp_teams
, NULL
, NULL
);
13312 tree num_teams
= integer_zero_node
;
13313 tree thread_limit
= integer_zero_node
;
13314 location_t num_teams_loc
= EXPR_LOCATION (target
);
13315 location_t thread_limit_loc
= EXPR_LOCATION (target
);
13317 struct gimplify_omp_ctx
*target_ctx
= gimplify_omp_ctxp
;
13319 if (teams
== NULL_TREE
)
13320 num_teams
= integer_one_node
;
13322 for (c
= OMP_TEAMS_CLAUSES (teams
); c
; c
= OMP_CLAUSE_CHAIN (c
))
13324 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_NUM_TEAMS
)
13327 num_teams_loc
= OMP_CLAUSE_LOCATION (c
);
13329 else if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_THREAD_LIMIT
)
13332 thread_limit_loc
= OMP_CLAUSE_LOCATION (c
);
13336 expr
= OMP_CLAUSE_OPERAND (c
, 0);
13337 if (TREE_CODE (expr
) == INTEGER_CST
)
13342 if (walk_tree (&expr
, computable_teams_clause
, NULL
, NULL
))
13344 *p
= integer_minus_one_node
;
13348 gimplify_omp_ctxp
= gimplify_omp_ctxp
->outer_context
;
13349 if (gimplify_expr (p
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
, false)
13352 gimplify_omp_ctxp
= target_ctx
;
13353 *p
= integer_minus_one_node
;
13356 gimplify_omp_ctxp
= target_ctx
;
13357 if (!DECL_P (expr
) && TREE_CODE (expr
) != TARGET_EXPR
)
13358 OMP_CLAUSE_OPERAND (c
, 0) = *p
;
13360 c
= build_omp_clause (thread_limit_loc
, OMP_CLAUSE_THREAD_LIMIT
);
13361 OMP_CLAUSE_THREAD_LIMIT_EXPR (c
) = thread_limit
;
13362 OMP_CLAUSE_CHAIN (c
) = OMP_TARGET_CLAUSES (target
);
13363 OMP_TARGET_CLAUSES (target
) = c
;
13364 c
= build_omp_clause (num_teams_loc
, OMP_CLAUSE_NUM_TEAMS
);
13365 OMP_CLAUSE_NUM_TEAMS_EXPR (c
) = num_teams
;
13366 OMP_CLAUSE_CHAIN (c
) = OMP_TARGET_CLAUSES (target
);
13367 OMP_TARGET_CLAUSES (target
) = c
;
13370 /* Gimplify the gross structure of several OMP constructs. */
13373 gimplify_omp_workshare (tree
*expr_p
, gimple_seq
*pre_p
)
13375 tree expr
= *expr_p
;
13377 gimple_seq body
= NULL
;
13378 enum omp_region_type ort
;
13380 switch (TREE_CODE (expr
))
13384 ort
= ORT_WORKSHARE
;
13387 ort
= ORT_TASKGROUP
;
13390 ort
= OMP_TARGET_COMBINED (expr
) ? ORT_COMBINED_TARGET
: ORT_TARGET
;
13393 ort
= ORT_ACC_KERNELS
;
13395 case OACC_PARALLEL
:
13396 ort
= ORT_ACC_PARALLEL
;
13399 ort
= ORT_ACC_SERIAL
;
13402 ort
= ORT_ACC_DATA
;
13404 case OMP_TARGET_DATA
:
13405 ort
= ORT_TARGET_DATA
;
13408 ort
= OMP_TEAMS_COMBINED (expr
) ? ORT_COMBINED_TEAMS
: ORT_TEAMS
;
13409 if (gimplify_omp_ctxp
== NULL
13410 || gimplify_omp_ctxp
->region_type
== ORT_IMPLICIT_TARGET
)
13411 ort
= (enum omp_region_type
) (ort
| ORT_HOST_TEAMS
);
13413 case OACC_HOST_DATA
:
13414 ort
= ORT_ACC_HOST_DATA
;
13417 gcc_unreachable ();
13420 bool save_in_omp_construct
= in_omp_construct
;
13421 if ((ort
& ORT_ACC
) == 0)
13422 in_omp_construct
= false;
13423 gimplify_scan_omp_clauses (&OMP_CLAUSES (expr
), pre_p
, ort
,
13425 if (TREE_CODE (expr
) == OMP_TARGET
)
13426 optimize_target_teams (expr
, pre_p
);
13427 if ((ort
& (ORT_TARGET
| ORT_TARGET_DATA
)) != 0
13428 || (ort
& ORT_HOST_TEAMS
) == ORT_HOST_TEAMS
)
13430 push_gimplify_context ();
13431 gimple
*g
= gimplify_and_return_first (OMP_BODY (expr
), &body
);
13432 if (gimple_code (g
) == GIMPLE_BIND
)
13433 pop_gimplify_context (g
);
13435 pop_gimplify_context (NULL
);
13436 if ((ort
& ORT_TARGET_DATA
) != 0)
13438 enum built_in_function end_ix
;
13439 switch (TREE_CODE (expr
))
13442 case OACC_HOST_DATA
:
13443 end_ix
= BUILT_IN_GOACC_DATA_END
;
13445 case OMP_TARGET_DATA
:
13446 end_ix
= BUILT_IN_GOMP_TARGET_END_DATA
;
13449 gcc_unreachable ();
13451 tree fn
= builtin_decl_explicit (end_ix
);
13452 g
= gimple_build_call (fn
, 0);
13453 gimple_seq cleanup
= NULL
;
13454 gimple_seq_add_stmt (&cleanup
, g
);
13455 g
= gimple_build_try (body
, cleanup
, GIMPLE_TRY_FINALLY
);
13457 gimple_seq_add_stmt (&body
, g
);
13461 gimplify_and_add (OMP_BODY (expr
), &body
);
13462 gimplify_adjust_omp_clauses (pre_p
, body
, &OMP_CLAUSES (expr
),
13464 in_omp_construct
= save_in_omp_construct
;
13466 switch (TREE_CODE (expr
))
13469 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_OACC_DATA
,
13470 OMP_CLAUSES (expr
));
13472 case OACC_HOST_DATA
:
13473 if (omp_find_clause (OMP_CLAUSES (expr
), OMP_CLAUSE_IF_PRESENT
))
13475 for (tree c
= OMP_CLAUSES (expr
); c
; c
= OMP_CLAUSE_CHAIN (c
))
13476 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_USE_DEVICE_PTR
)
13477 OMP_CLAUSE_USE_DEVICE_PTR_IF_PRESENT (c
) = 1;
13480 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_OACC_HOST_DATA
,
13481 OMP_CLAUSES (expr
));
13484 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_OACC_KERNELS
,
13485 OMP_CLAUSES (expr
));
13487 case OACC_PARALLEL
:
13488 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_OACC_PARALLEL
,
13489 OMP_CLAUSES (expr
));
13492 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_OACC_SERIAL
,
13493 OMP_CLAUSES (expr
));
13496 stmt
= gimple_build_omp_sections (body
, OMP_CLAUSES (expr
));
13499 stmt
= gimple_build_omp_single (body
, OMP_CLAUSES (expr
));
13502 stmt
= gimple_build_omp_scope (body
, OMP_CLAUSES (expr
));
13505 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_REGION
,
13506 OMP_CLAUSES (expr
));
13508 case OMP_TARGET_DATA
:
13509 /* Put use_device_{ptr,addr} clauses last, as map clauses are supposed
13510 to be evaluated before the use_device_{ptr,addr} clauses if they
13511 refer to the same variables. */
13513 tree use_device_clauses
;
13514 tree
*pc
, *uc
= &use_device_clauses
;
13515 for (pc
= &OMP_CLAUSES (expr
); *pc
; )
13516 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_USE_DEVICE_PTR
13517 || OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_USE_DEVICE_ADDR
)
13520 *pc
= OMP_CLAUSE_CHAIN (*pc
);
13521 uc
= &OMP_CLAUSE_CHAIN (*uc
);
13524 pc
= &OMP_CLAUSE_CHAIN (*pc
);
13526 *pc
= use_device_clauses
;
13527 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_DATA
,
13528 OMP_CLAUSES (expr
));
13532 stmt
= gimple_build_omp_teams (body
, OMP_CLAUSES (expr
));
13533 if ((ort
& ORT_HOST_TEAMS
) == ORT_HOST_TEAMS
)
13534 gimple_omp_teams_set_host (as_a
<gomp_teams
*> (stmt
), true);
13537 gcc_unreachable ();
13540 gimplify_seq_add_stmt (pre_p
, stmt
);
13541 *expr_p
= NULL_TREE
;
13544 /* Gimplify the gross structure of OpenACC enter/exit data, update, and OpenMP
13545 target update constructs. */
13548 gimplify_omp_target_update (tree
*expr_p
, gimple_seq
*pre_p
)
13550 tree expr
= *expr_p
;
13553 enum omp_region_type ort
= ORT_WORKSHARE
;
13555 switch (TREE_CODE (expr
))
13557 case OACC_ENTER_DATA
:
13558 kind
= GF_OMP_TARGET_KIND_OACC_ENTER_DATA
;
13561 case OACC_EXIT_DATA
:
13562 kind
= GF_OMP_TARGET_KIND_OACC_EXIT_DATA
;
13566 kind
= GF_OMP_TARGET_KIND_OACC_UPDATE
;
13569 case OMP_TARGET_UPDATE
:
13570 kind
= GF_OMP_TARGET_KIND_UPDATE
;
13572 case OMP_TARGET_ENTER_DATA
:
13573 kind
= GF_OMP_TARGET_KIND_ENTER_DATA
;
13575 case OMP_TARGET_EXIT_DATA
:
13576 kind
= GF_OMP_TARGET_KIND_EXIT_DATA
;
13579 gcc_unreachable ();
13581 gimplify_scan_omp_clauses (&OMP_STANDALONE_CLAUSES (expr
), pre_p
,
13582 ort
, TREE_CODE (expr
));
13583 gimplify_adjust_omp_clauses (pre_p
, NULL
, &OMP_STANDALONE_CLAUSES (expr
),
13585 if (TREE_CODE (expr
) == OACC_UPDATE
13586 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr
),
13587 OMP_CLAUSE_IF_PRESENT
))
13589 /* The runtime uses GOMP_MAP_{TO,FROM} to denote the if_present
13591 for (tree c
= OMP_STANDALONE_CLAUSES (expr
); c
; c
= OMP_CLAUSE_CHAIN (c
))
13592 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_MAP
)
13593 switch (OMP_CLAUSE_MAP_KIND (c
))
13595 case GOMP_MAP_FORCE_TO
:
13596 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_TO
);
13598 case GOMP_MAP_FORCE_FROM
:
13599 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_FROM
);
13605 else if (TREE_CODE (expr
) == OACC_EXIT_DATA
13606 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr
),
13607 OMP_CLAUSE_FINALIZE
))
13609 /* Use GOMP_MAP_DELETE/GOMP_MAP_FORCE_FROM to denote "finalize"
13611 bool have_clause
= false;
13612 for (tree c
= OMP_STANDALONE_CLAUSES (expr
); c
; c
= OMP_CLAUSE_CHAIN (c
))
13613 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_MAP
)
13614 switch (OMP_CLAUSE_MAP_KIND (c
))
13616 case GOMP_MAP_FROM
:
13617 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_FORCE_FROM
);
13618 have_clause
= true;
13620 case GOMP_MAP_RELEASE
:
13621 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_DELETE
);
13622 have_clause
= true;
13624 case GOMP_MAP_TO_PSET
:
13625 /* Fortran arrays with descriptors must map that descriptor when
13626 doing standalone "attach" operations (in OpenACC). In that
13627 case GOMP_MAP_TO_PSET appears by itself with no preceding
13628 clause (see trans-openmp.c:gfc_trans_omp_clauses). */
13630 case GOMP_MAP_POINTER
:
13631 /* TODO PR92929: we may see these here, but they'll always follow
13632 one of the clauses above, and will be handled by libgomp as
13633 one group, so no handling required here. */
13634 gcc_assert (have_clause
);
13636 case GOMP_MAP_DETACH
:
13637 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_FORCE_DETACH
);
13638 have_clause
= false;
13640 case GOMP_MAP_STRUCT
:
13641 have_clause
= false;
13644 gcc_unreachable ();
13647 stmt
= gimple_build_omp_target (NULL
, kind
, OMP_STANDALONE_CLAUSES (expr
));
13649 gimplify_seq_add_stmt (pre_p
, stmt
);
13650 *expr_p
= NULL_TREE
;
13653 /* A subroutine of gimplify_omp_atomic. The front end is supposed to have
13654 stabilized the lhs of the atomic operation as *ADDR. Return true if
13655 EXPR is this stabilized form. */
13658 goa_lhs_expr_p (tree expr
, tree addr
)
13660 /* Also include casts to other type variants. The C front end is fond
13661 of adding these for e.g. volatile variables. This is like
13662 STRIP_TYPE_NOPS but includes the main variant lookup. */
13663 STRIP_USELESS_TYPE_CONVERSION (expr
);
13665 if (TREE_CODE (expr
) == INDIRECT_REF
)
13667 expr
= TREE_OPERAND (expr
, 0);
13668 while (expr
!= addr
13669 && (CONVERT_EXPR_P (expr
)
13670 || TREE_CODE (expr
) == NON_LVALUE_EXPR
)
13671 && TREE_CODE (expr
) == TREE_CODE (addr
)
13672 && types_compatible_p (TREE_TYPE (expr
), TREE_TYPE (addr
)))
13674 expr
= TREE_OPERAND (expr
, 0);
13675 addr
= TREE_OPERAND (addr
, 0);
13679 return (TREE_CODE (addr
) == ADDR_EXPR
13680 && TREE_CODE (expr
) == ADDR_EXPR
13681 && TREE_OPERAND (addr
, 0) == TREE_OPERAND (expr
, 0));
13683 if (TREE_CODE (addr
) == ADDR_EXPR
&& expr
== TREE_OPERAND (addr
, 0))
13688 /* Walk *EXPR_P and replace appearances of *LHS_ADDR with LHS_VAR. If an
13689 expression does not involve the lhs, evaluate it into a temporary.
13690 Return 1 if the lhs appeared as a subexpression, 0 if it did not,
13691 or -1 if an error was encountered. */
13694 goa_stabilize_expr (tree
*expr_p
, gimple_seq
*pre_p
, tree lhs_addr
,
13697 tree expr
= *expr_p
;
13700 if (goa_lhs_expr_p (expr
, lhs_addr
))
13705 if (is_gimple_val (expr
))
13709 switch (TREE_CODE_CLASS (TREE_CODE (expr
)))
13712 case tcc_comparison
:
13713 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 1), pre_p
, lhs_addr
,
13717 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 0), pre_p
, lhs_addr
,
13720 case tcc_expression
:
13721 switch (TREE_CODE (expr
))
13723 case TRUTH_ANDIF_EXPR
:
13724 case TRUTH_ORIF_EXPR
:
13725 case TRUTH_AND_EXPR
:
13726 case TRUTH_OR_EXPR
:
13727 case TRUTH_XOR_EXPR
:
13728 case BIT_INSERT_EXPR
:
13729 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 1), pre_p
,
13730 lhs_addr
, lhs_var
);
13732 case TRUTH_NOT_EXPR
:
13733 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 0), pre_p
,
13734 lhs_addr
, lhs_var
);
13736 case COMPOUND_EXPR
:
13737 /* Break out any preevaluations from cp_build_modify_expr. */
13738 for (; TREE_CODE (expr
) == COMPOUND_EXPR
;
13739 expr
= TREE_OPERAND (expr
, 1))
13740 gimplify_stmt (&TREE_OPERAND (expr
, 0), pre_p
);
13742 return goa_stabilize_expr (expr_p
, pre_p
, lhs_addr
, lhs_var
);
13747 case tcc_reference
:
13748 if (TREE_CODE (expr
) == BIT_FIELD_REF
)
13749 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 0), pre_p
,
13750 lhs_addr
, lhs_var
);
13758 enum gimplify_status gs
;
13759 gs
= gimplify_expr (expr_p
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
13760 if (gs
!= GS_ALL_DONE
)
13767 /* Gimplify an OMP_ATOMIC statement. */
13769 static enum gimplify_status
13770 gimplify_omp_atomic (tree
*expr_p
, gimple_seq
*pre_p
)
13772 tree addr
= TREE_OPERAND (*expr_p
, 0);
13773 tree rhs
= TREE_CODE (*expr_p
) == OMP_ATOMIC_READ
13774 ? NULL
: TREE_OPERAND (*expr_p
, 1);
13775 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr
)));
13777 gomp_atomic_load
*loadstmt
;
13778 gomp_atomic_store
*storestmt
;
13780 tmp_load
= create_tmp_reg (type
);
13781 if (rhs
&& goa_stabilize_expr (&rhs
, pre_p
, addr
, tmp_load
) < 0)
13784 if (gimplify_expr (&addr
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
)
13788 loadstmt
= gimple_build_omp_atomic_load (tmp_load
, addr
,
13789 OMP_ATOMIC_MEMORY_ORDER (*expr_p
));
13790 gimplify_seq_add_stmt (pre_p
, loadstmt
);
13793 /* BIT_INSERT_EXPR is not valid for non-integral bitfield
13794 representatives. Use BIT_FIELD_REF on the lhs instead. */
13795 if (TREE_CODE (rhs
) == BIT_INSERT_EXPR
13796 && !INTEGRAL_TYPE_P (TREE_TYPE (tmp_load
)))
13798 tree bitpos
= TREE_OPERAND (rhs
, 2);
13799 tree op1
= TREE_OPERAND (rhs
, 1);
13801 tree tmp_store
= tmp_load
;
13802 if (TREE_CODE (*expr_p
) == OMP_ATOMIC_CAPTURE_OLD
)
13803 tmp_store
= get_initialized_tmp_var (tmp_load
, pre_p
);
13804 if (INTEGRAL_TYPE_P (TREE_TYPE (op1
)))
13805 bitsize
= bitsize_int (TYPE_PRECISION (TREE_TYPE (op1
)));
13807 bitsize
= TYPE_SIZE (TREE_TYPE (op1
));
13808 gcc_assert (TREE_OPERAND (rhs
, 0) == tmp_load
);
13809 tree t
= build2_loc (EXPR_LOCATION (rhs
),
13810 MODIFY_EXPR
, void_type_node
,
13811 build3_loc (EXPR_LOCATION (rhs
), BIT_FIELD_REF
,
13812 TREE_TYPE (op1
), tmp_store
, bitsize
,
13814 gimplify_and_add (t
, pre_p
);
13817 if (gimplify_expr (&rhs
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
)
13822 if (TREE_CODE (*expr_p
) == OMP_ATOMIC_READ
)
13825 = gimple_build_omp_atomic_store (rhs
, OMP_ATOMIC_MEMORY_ORDER (*expr_p
));
13826 gimplify_seq_add_stmt (pre_p
, storestmt
);
13827 switch (TREE_CODE (*expr_p
))
13829 case OMP_ATOMIC_READ
:
13830 case OMP_ATOMIC_CAPTURE_OLD
:
13831 *expr_p
= tmp_load
;
13832 gimple_omp_atomic_set_need_value (loadstmt
);
13834 case OMP_ATOMIC_CAPTURE_NEW
:
13836 gimple_omp_atomic_set_need_value (storestmt
);
13843 return GS_ALL_DONE
;
13846 /* Gimplify a TRANSACTION_EXPR. This involves gimplification of the
13847 body, and adding some EH bits. */
13849 static enum gimplify_status
13850 gimplify_transaction (tree
*expr_p
, gimple_seq
*pre_p
)
13852 tree expr
= *expr_p
, temp
, tbody
= TRANSACTION_EXPR_BODY (expr
);
13854 gtransaction
*trans_stmt
;
13855 gimple_seq body
= NULL
;
13858 /* Wrap the transaction body in a BIND_EXPR so we have a context
13859 where to put decls for OMP. */
13860 if (TREE_CODE (tbody
) != BIND_EXPR
)
13862 tree bind
= build3 (BIND_EXPR
, void_type_node
, NULL
, tbody
, NULL
);
13863 TREE_SIDE_EFFECTS (bind
) = 1;
13864 SET_EXPR_LOCATION (bind
, EXPR_LOCATION (tbody
));
13865 TRANSACTION_EXPR_BODY (expr
) = bind
;
13868 push_gimplify_context ();
13869 temp
= voidify_wrapper_expr (*expr_p
, NULL
);
13871 body_stmt
= gimplify_and_return_first (TRANSACTION_EXPR_BODY (expr
), &body
);
13872 pop_gimplify_context (body_stmt
);
13874 trans_stmt
= gimple_build_transaction (body
);
13875 if (TRANSACTION_EXPR_OUTER (expr
))
13876 subcode
= GTMA_IS_OUTER
;
13877 else if (TRANSACTION_EXPR_RELAXED (expr
))
13878 subcode
= GTMA_IS_RELAXED
;
13879 gimple_transaction_set_subcode (trans_stmt
, subcode
);
13881 gimplify_seq_add_stmt (pre_p
, trans_stmt
);
13889 *expr_p
= NULL_TREE
;
13890 return GS_ALL_DONE
;
13893 /* Gimplify an OMP_ORDERED construct. EXPR is the tree version. BODY
13894 is the OMP_BODY of the original EXPR (which has already been
13895 gimplified so it's not present in the EXPR).
13897 Return the gimplified GIMPLE_OMP_ORDERED tuple. */
13900 gimplify_omp_ordered (tree expr
, gimple_seq body
)
13905 tree source_c
= NULL_TREE
;
13906 tree sink_c
= NULL_TREE
;
13908 if (gimplify_omp_ctxp
)
13910 for (c
= OMP_ORDERED_CLAUSES (expr
); c
; c
= OMP_CLAUSE_CHAIN (c
))
13911 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEPEND
13912 && gimplify_omp_ctxp
->loop_iter_var
.is_empty ()
13913 && (OMP_CLAUSE_DEPEND_KIND (c
) == OMP_CLAUSE_DEPEND_SINK
13914 || OMP_CLAUSE_DEPEND_KIND (c
) == OMP_CLAUSE_DEPEND_SOURCE
))
13916 error_at (OMP_CLAUSE_LOCATION (c
),
13917 "%<ordered%> construct with %<depend%> clause must be "
13918 "closely nested inside a loop with %<ordered%> clause "
13919 "with a parameter");
13922 else if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEPEND
13923 && OMP_CLAUSE_DEPEND_KIND (c
) == OMP_CLAUSE_DEPEND_SINK
)
13926 for (decls
= OMP_CLAUSE_DECL (c
), i
= 0;
13927 decls
&& TREE_CODE (decls
) == TREE_LIST
;
13928 decls
= TREE_CHAIN (decls
), ++i
)
13929 if (i
>= gimplify_omp_ctxp
->loop_iter_var
.length () / 2)
13931 else if (TREE_VALUE (decls
)
13932 != gimplify_omp_ctxp
->loop_iter_var
[2 * i
])
13934 error_at (OMP_CLAUSE_LOCATION (c
),
13935 "variable %qE is not an iteration "
13936 "of outermost loop %d, expected %qE",
13937 TREE_VALUE (decls
), i
+ 1,
13938 gimplify_omp_ctxp
->loop_iter_var
[2 * i
]);
13944 = gimplify_omp_ctxp
->loop_iter_var
[2 * i
+ 1];
13945 if (!fail
&& i
!= gimplify_omp_ctxp
->loop_iter_var
.length () / 2)
13947 error_at (OMP_CLAUSE_LOCATION (c
),
13948 "number of variables in %<depend%> clause with "
13949 "%<sink%> modifier does not match number of "
13950 "iteration variables");
13955 else if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEPEND
13956 && OMP_CLAUSE_DEPEND_KIND (c
) == OMP_CLAUSE_DEPEND_SOURCE
)
13960 error_at (OMP_CLAUSE_LOCATION (c
),
13961 "more than one %<depend%> clause with %<source%> "
13962 "modifier on an %<ordered%> construct");
13969 if (source_c
&& sink_c
)
13971 error_at (OMP_CLAUSE_LOCATION (source_c
),
13972 "%<depend%> clause with %<source%> modifier specified "
13973 "together with %<depend%> clauses with %<sink%> modifier "
13974 "on the same construct");
13979 return gimple_build_nop ();
13980 return gimple_build_omp_ordered (body
, OMP_ORDERED_CLAUSES (expr
));
13983 /* Convert the GENERIC expression tree *EXPR_P to GIMPLE. If the
13984 expression produces a value to be used as an operand inside a GIMPLE
13985 statement, the value will be stored back in *EXPR_P. This value will
13986 be a tree of class tcc_declaration, tcc_constant, tcc_reference or
13987 an SSA_NAME. The corresponding sequence of GIMPLE statements is
13988 emitted in PRE_P and POST_P.
13990 Additionally, this process may overwrite parts of the input
13991 expression during gimplification. Ideally, it should be
13992 possible to do non-destructive gimplification.
13994 EXPR_P points to the GENERIC expression to convert to GIMPLE. If
13995 the expression needs to evaluate to a value to be used as
13996 an operand in a GIMPLE statement, this value will be stored in
13997 *EXPR_P on exit. This happens when the caller specifies one
13998 of fb_lvalue or fb_rvalue fallback flags.
14000 PRE_P will contain the sequence of GIMPLE statements corresponding
14001 to the evaluation of EXPR and all the side-effects that must
14002 be executed before the main expression. On exit, the last
14003 statement of PRE_P is the core statement being gimplified. For
14004 instance, when gimplifying 'if (++a)' the last statement in
14005 PRE_P will be 'if (t.1)' where t.1 is the result of
14006 pre-incrementing 'a'.
14008 POST_P will contain the sequence of GIMPLE statements corresponding
14009 to the evaluation of all the side-effects that must be executed
14010 after the main expression. If this is NULL, the post
14011 side-effects are stored at the end of PRE_P.
14013 The reason why the output is split in two is to handle post
14014 side-effects explicitly. In some cases, an expression may have
14015 inner and outer post side-effects which need to be emitted in
14016 an order different from the one given by the recursive
14017 traversal. For instance, for the expression (*p--)++ the post
14018 side-effects of '--' must actually occur *after* the post
14019 side-effects of '++'. However, gimplification will first visit
14020 the inner expression, so if a separate POST sequence was not
14021 used, the resulting sequence would be:
14028 However, the post-decrement operation in line #2 must not be
14029 evaluated until after the store to *p at line #4, so the
14030 correct sequence should be:
14037 So, by specifying a separate post queue, it is possible
14038 to emit the post side-effects in the correct order.
14039 If POST_P is NULL, an internal queue will be used. Before
14040 returning to the caller, the sequence POST_P is appended to
14041 the main output sequence PRE_P.
14043 GIMPLE_TEST_F points to a function that takes a tree T and
14044 returns nonzero if T is in the GIMPLE form requested by the
14045 caller. The GIMPLE predicates are in gimple.c.
14047 FALLBACK tells the function what sort of a temporary we want if
14048 gimplification cannot produce an expression that complies with
14051 fb_none means that no temporary should be generated
14052 fb_rvalue means that an rvalue is OK to generate
14053 fb_lvalue means that an lvalue is OK to generate
14054 fb_either means that either is OK, but an lvalue is preferable.
14055 fb_mayfail means that gimplification may fail (in which case
14056 GS_ERROR will be returned)
14058 The return value is either GS_ERROR or GS_ALL_DONE, since this
14059 function iterates until EXPR is completely gimplified or an error
14062 enum gimplify_status
14063 gimplify_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
14064 bool (*gimple_test_f
) (tree
), fallback_t fallback
)
14067 gimple_seq internal_pre
= NULL
;
14068 gimple_seq internal_post
= NULL
;
14071 location_t saved_location
;
14072 enum gimplify_status ret
;
14073 gimple_stmt_iterator pre_last_gsi
, post_last_gsi
;
14076 save_expr
= *expr_p
;
14077 if (save_expr
== NULL_TREE
)
14078 return GS_ALL_DONE
;
14080 /* If we are gimplifying a top-level statement, PRE_P must be valid. */
14081 is_statement
= gimple_test_f
== is_gimple_stmt
;
14083 gcc_assert (pre_p
);
14085 /* Consistency checks. */
14086 if (gimple_test_f
== is_gimple_reg
)
14087 gcc_assert (fallback
& (fb_rvalue
| fb_lvalue
));
14088 else if (gimple_test_f
== is_gimple_val
14089 || gimple_test_f
== is_gimple_call_addr
14090 || gimple_test_f
== is_gimple_condexpr
14091 || gimple_test_f
== is_gimple_condexpr_for_cond
14092 || gimple_test_f
== is_gimple_mem_rhs
14093 || gimple_test_f
== is_gimple_mem_rhs_or_call
14094 || gimple_test_f
== is_gimple_reg_rhs
14095 || gimple_test_f
== is_gimple_reg_rhs_or_call
14096 || gimple_test_f
== is_gimple_asm_val
14097 || gimple_test_f
== is_gimple_mem_ref_addr
)
14098 gcc_assert (fallback
& fb_rvalue
);
14099 else if (gimple_test_f
== is_gimple_min_lval
14100 || gimple_test_f
== is_gimple_lvalue
)
14101 gcc_assert (fallback
& fb_lvalue
);
14102 else if (gimple_test_f
== is_gimple_addressable
)
14103 gcc_assert (fallback
& fb_either
);
14104 else if (gimple_test_f
== is_gimple_stmt
)
14105 gcc_assert (fallback
== fb_none
);
14108 /* We should have recognized the GIMPLE_TEST_F predicate to
14109 know what kind of fallback to use in case a temporary is
14110 needed to hold the value or address of *EXPR_P. */
14111 gcc_unreachable ();
14114 /* We used to check the predicate here and return immediately if it
14115 succeeds. This is wrong; the design is for gimplification to be
14116 idempotent, and for the predicates to only test for valid forms, not
14117 whether they are fully simplified. */
14119 pre_p
= &internal_pre
;
14121 if (post_p
== NULL
)
14122 post_p
= &internal_post
;
14124 /* Remember the last statements added to PRE_P and POST_P. Every
14125 new statement added by the gimplification helpers needs to be
14126 annotated with location information. To centralize the
14127 responsibility, we remember the last statement that had been
14128 added to both queues before gimplifying *EXPR_P. If
14129 gimplification produces new statements in PRE_P and POST_P, those
14130 statements will be annotated with the same location information
14132 pre_last_gsi
= gsi_last (*pre_p
);
14133 post_last_gsi
= gsi_last (*post_p
);
14135 saved_location
= input_location
;
14136 if (save_expr
!= error_mark_node
14137 && EXPR_HAS_LOCATION (*expr_p
))
14138 input_location
= EXPR_LOCATION (*expr_p
);
14140 /* Loop over the specific gimplifiers until the toplevel node
14141 remains the same. */
14144 /* Strip away as many useless type conversions as possible
14145 at the toplevel. */
14146 STRIP_USELESS_TYPE_CONVERSION (*expr_p
);
14148 /* Remember the expr. */
14149 save_expr
= *expr_p
;
14151 /* Die, die, die, my darling. */
14152 if (error_operand_p (save_expr
))
14158 /* Do any language-specific gimplification. */
14159 ret
= ((enum gimplify_status
)
14160 lang_hooks
.gimplify_expr (expr_p
, pre_p
, post_p
));
14163 if (*expr_p
== NULL_TREE
)
14165 if (*expr_p
!= save_expr
)
14168 else if (ret
!= GS_UNHANDLED
)
14171 /* Make sure that all the cases set 'ret' appropriately. */
14172 ret
= GS_UNHANDLED
;
14173 switch (TREE_CODE (*expr_p
))
14175 /* First deal with the special cases. */
14177 case POSTINCREMENT_EXPR
:
14178 case POSTDECREMENT_EXPR
:
14179 case PREINCREMENT_EXPR
:
14180 case PREDECREMENT_EXPR
:
14181 ret
= gimplify_self_mod_expr (expr_p
, pre_p
, post_p
,
14182 fallback
!= fb_none
,
14183 TREE_TYPE (*expr_p
));
14186 case VIEW_CONVERT_EXPR
:
14187 if ((fallback
& fb_rvalue
)
14188 && is_gimple_reg_type (TREE_TYPE (*expr_p
))
14189 && is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (*expr_p
, 0))))
14191 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
14192 post_p
, is_gimple_val
, fb_rvalue
);
14193 recalculate_side_effects (*expr_p
);
14199 case ARRAY_RANGE_REF
:
14200 case REALPART_EXPR
:
14201 case IMAGPART_EXPR
:
14202 case COMPONENT_REF
:
14203 ret
= gimplify_compound_lval (expr_p
, pre_p
, post_p
,
14204 fallback
? fallback
: fb_rvalue
);
14208 ret
= gimplify_cond_expr (expr_p
, pre_p
, fallback
);
14210 /* C99 code may assign to an array in a structure value of a
14211 conditional expression, and this has undefined behavior
14212 only on execution, so create a temporary if an lvalue is
14214 if (fallback
== fb_lvalue
)
14216 *expr_p
= get_initialized_tmp_var (*expr_p
, pre_p
, post_p
, false);
14217 mark_addressable (*expr_p
);
14223 ret
= gimplify_call_expr (expr_p
, pre_p
, fallback
!= fb_none
);
14225 /* C99 code may assign to an array in a structure returned
14226 from a function, and this has undefined behavior only on
14227 execution, so create a temporary if an lvalue is
14229 if (fallback
== fb_lvalue
)
14231 *expr_p
= get_initialized_tmp_var (*expr_p
, pre_p
, post_p
, false);
14232 mark_addressable (*expr_p
);
14238 gcc_unreachable ();
14240 case COMPOUND_EXPR
:
14241 ret
= gimplify_compound_expr (expr_p
, pre_p
, fallback
!= fb_none
);
14244 case COMPOUND_LITERAL_EXPR
:
14245 ret
= gimplify_compound_literal_expr (expr_p
, pre_p
,
14246 gimple_test_f
, fallback
);
14251 ret
= gimplify_modify_expr (expr_p
, pre_p
, post_p
,
14252 fallback
!= fb_none
);
14255 case TRUTH_ANDIF_EXPR
:
14256 case TRUTH_ORIF_EXPR
:
14258 /* Preserve the original type of the expression and the
14259 source location of the outer expression. */
14260 tree org_type
= TREE_TYPE (*expr_p
);
14261 *expr_p
= gimple_boolify (*expr_p
);
14262 *expr_p
= build3_loc (input_location
, COND_EXPR
,
14266 org_type
, boolean_true_node
),
14269 org_type
, boolean_false_node
));
14274 case TRUTH_NOT_EXPR
:
14276 tree type
= TREE_TYPE (*expr_p
);
14277 /* The parsers are careful to generate TRUTH_NOT_EXPR
14278 only with operands that are always zero or one.
14279 We do not fold here but handle the only interesting case
14280 manually, as fold may re-introduce the TRUTH_NOT_EXPR. */
14281 *expr_p
= gimple_boolify (*expr_p
);
14282 if (TYPE_PRECISION (TREE_TYPE (*expr_p
)) == 1)
14283 *expr_p
= build1_loc (input_location
, BIT_NOT_EXPR
,
14284 TREE_TYPE (*expr_p
),
14285 TREE_OPERAND (*expr_p
, 0));
14287 *expr_p
= build2_loc (input_location
, BIT_XOR_EXPR
,
14288 TREE_TYPE (*expr_p
),
14289 TREE_OPERAND (*expr_p
, 0),
14290 build_int_cst (TREE_TYPE (*expr_p
), 1));
14291 if (!useless_type_conversion_p (type
, TREE_TYPE (*expr_p
)))
14292 *expr_p
= fold_convert_loc (input_location
, type
, *expr_p
);
14298 ret
= gimplify_addr_expr (expr_p
, pre_p
, post_p
);
14301 case ANNOTATE_EXPR
:
14303 tree cond
= TREE_OPERAND (*expr_p
, 0);
14304 tree kind
= TREE_OPERAND (*expr_p
, 1);
14305 tree data
= TREE_OPERAND (*expr_p
, 2);
14306 tree type
= TREE_TYPE (cond
);
14307 if (!INTEGRAL_TYPE_P (type
))
14313 tree tmp
= create_tmp_var (type
);
14314 gimplify_arg (&cond
, pre_p
, EXPR_LOCATION (*expr_p
));
14316 = gimple_build_call_internal (IFN_ANNOTATE
, 3, cond
, kind
, data
);
14317 gimple_call_set_lhs (call
, tmp
);
14318 gimplify_seq_add_stmt (pre_p
, call
);
14325 ret
= gimplify_va_arg_expr (expr_p
, pre_p
, post_p
);
14329 if (IS_EMPTY_STMT (*expr_p
))
14335 if (VOID_TYPE_P (TREE_TYPE (*expr_p
))
14336 || fallback
== fb_none
)
14338 /* Just strip a conversion to void (or in void context) and
14340 *expr_p
= TREE_OPERAND (*expr_p
, 0);
14345 ret
= gimplify_conversion (expr_p
);
14346 if (ret
== GS_ERROR
)
14348 if (*expr_p
!= save_expr
)
14352 case FIX_TRUNC_EXPR
:
14353 /* unary_expr: ... | '(' cast ')' val | ... */
14354 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
14355 is_gimple_val
, fb_rvalue
);
14356 recalculate_side_effects (*expr_p
);
14361 bool volatilep
= TREE_THIS_VOLATILE (*expr_p
);
14362 bool notrap
= TREE_THIS_NOTRAP (*expr_p
);
14363 tree saved_ptr_type
= TREE_TYPE (TREE_OPERAND (*expr_p
, 0));
14365 *expr_p
= fold_indirect_ref_loc (input_location
, *expr_p
);
14366 if (*expr_p
!= save_expr
)
14372 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
14373 is_gimple_reg
, fb_rvalue
);
14374 if (ret
== GS_ERROR
)
14377 recalculate_side_effects (*expr_p
);
14378 *expr_p
= fold_build2_loc (input_location
, MEM_REF
,
14379 TREE_TYPE (*expr_p
),
14380 TREE_OPERAND (*expr_p
, 0),
14381 build_int_cst (saved_ptr_type
, 0));
14382 TREE_THIS_VOLATILE (*expr_p
) = volatilep
;
14383 TREE_THIS_NOTRAP (*expr_p
) = notrap
;
14388 /* We arrive here through the various re-gimplifcation paths. */
14390 /* First try re-folding the whole thing. */
14391 tmp
= fold_binary (MEM_REF
, TREE_TYPE (*expr_p
),
14392 TREE_OPERAND (*expr_p
, 0),
14393 TREE_OPERAND (*expr_p
, 1));
14396 REF_REVERSE_STORAGE_ORDER (tmp
)
14397 = REF_REVERSE_STORAGE_ORDER (*expr_p
);
14399 recalculate_side_effects (*expr_p
);
14403 /* Avoid re-gimplifying the address operand if it is already
14404 in suitable form. Re-gimplifying would mark the address
14405 operand addressable. Always gimplify when not in SSA form
14406 as we still may have to gimplify decls with value-exprs. */
14407 if (!gimplify_ctxp
|| !gimple_in_ssa_p (cfun
)
14408 || !is_gimple_mem_ref_addr (TREE_OPERAND (*expr_p
, 0)))
14410 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
14411 is_gimple_mem_ref_addr
, fb_rvalue
);
14412 if (ret
== GS_ERROR
)
14415 recalculate_side_effects (*expr_p
);
14419 /* Constants need not be gimplified. */
14426 /* Drop the overflow flag on constants, we do not want
14427 that in the GIMPLE IL. */
14428 if (TREE_OVERFLOW_P (*expr_p
))
14429 *expr_p
= drop_tree_overflow (*expr_p
);
14434 /* If we require an lvalue, such as for ADDR_EXPR, retain the
14435 CONST_DECL node. Otherwise the decl is replaceable by its
14437 /* ??? Should be == fb_lvalue, but ADDR_EXPR passes fb_either. */
14438 if (fallback
& fb_lvalue
)
14442 *expr_p
= DECL_INITIAL (*expr_p
);
14448 ret
= gimplify_decl_expr (expr_p
, pre_p
);
14452 ret
= gimplify_bind_expr (expr_p
, pre_p
);
14456 ret
= gimplify_loop_expr (expr_p
, pre_p
);
14460 ret
= gimplify_switch_expr (expr_p
, pre_p
);
14464 ret
= gimplify_exit_expr (expr_p
);
14468 /* If the target is not LABEL, then it is a computed jump
14469 and the target needs to be gimplified. */
14470 if (TREE_CODE (GOTO_DESTINATION (*expr_p
)) != LABEL_DECL
)
14472 ret
= gimplify_expr (&GOTO_DESTINATION (*expr_p
), pre_p
,
14473 NULL
, is_gimple_val
, fb_rvalue
);
14474 if (ret
== GS_ERROR
)
14477 gimplify_seq_add_stmt (pre_p
,
14478 gimple_build_goto (GOTO_DESTINATION (*expr_p
)));
14483 gimplify_seq_add_stmt (pre_p
,
14484 gimple_build_predict (PREDICT_EXPR_PREDICTOR (*expr_p
),
14485 PREDICT_EXPR_OUTCOME (*expr_p
)));
14490 ret
= gimplify_label_expr (expr_p
, pre_p
);
14491 label
= LABEL_EXPR_LABEL (*expr_p
);
14492 gcc_assert (decl_function_context (label
) == current_function_decl
);
14494 /* If the label is used in a goto statement, or address of the label
14495 is taken, we need to unpoison all variables that were seen so far.
14496 Doing so would prevent us from reporting a false positives. */
14497 if (asan_poisoned_variables
14498 && asan_used_labels
!= NULL
14499 && asan_used_labels
->contains (label
)
14500 && !gimplify_omp_ctxp
)
14501 asan_poison_variables (asan_poisoned_variables
, false, pre_p
);
14504 case CASE_LABEL_EXPR
:
14505 ret
= gimplify_case_label_expr (expr_p
, pre_p
);
14507 if (gimplify_ctxp
->live_switch_vars
)
14508 asan_poison_variables (gimplify_ctxp
->live_switch_vars
, false,
14513 ret
= gimplify_return_expr (*expr_p
, pre_p
);
14517 /* Don't reduce this in place; let gimplify_init_constructor work its
14518 magic. Buf if we're just elaborating this for side effects, just
14519 gimplify any element that has side-effects. */
14520 if (fallback
== fb_none
)
14522 unsigned HOST_WIDE_INT ix
;
14524 tree temp
= NULL_TREE
;
14525 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (*expr_p
), ix
, val
)
14526 if (TREE_SIDE_EFFECTS (val
))
14527 append_to_statement_list (val
, &temp
);
14530 ret
= temp
? GS_OK
: GS_ALL_DONE
;
14532 /* C99 code may assign to an array in a constructed
14533 structure or union, and this has undefined behavior only
14534 on execution, so create a temporary if an lvalue is
14536 else if (fallback
== fb_lvalue
)
14538 *expr_p
= get_initialized_tmp_var (*expr_p
, pre_p
, post_p
, false);
14539 mark_addressable (*expr_p
);
14546 /* The following are special cases that are not handled by the
14547 original GIMPLE grammar. */
14549 /* SAVE_EXPR nodes are converted into a GIMPLE identifier and
14552 ret
= gimplify_save_expr (expr_p
, pre_p
, post_p
);
14555 case BIT_FIELD_REF
:
14556 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
14557 post_p
, is_gimple_lvalue
, fb_either
);
14558 recalculate_side_effects (*expr_p
);
14561 case TARGET_MEM_REF
:
14563 enum gimplify_status r0
= GS_ALL_DONE
, r1
= GS_ALL_DONE
;
14565 if (TMR_BASE (*expr_p
))
14566 r0
= gimplify_expr (&TMR_BASE (*expr_p
), pre_p
,
14567 post_p
, is_gimple_mem_ref_addr
, fb_either
);
14568 if (TMR_INDEX (*expr_p
))
14569 r1
= gimplify_expr (&TMR_INDEX (*expr_p
), pre_p
,
14570 post_p
, is_gimple_val
, fb_rvalue
);
14571 if (TMR_INDEX2 (*expr_p
))
14572 r1
= gimplify_expr (&TMR_INDEX2 (*expr_p
), pre_p
,
14573 post_p
, is_gimple_val
, fb_rvalue
);
14574 /* TMR_STEP and TMR_OFFSET are always integer constants. */
14575 ret
= MIN (r0
, r1
);
14579 case NON_LVALUE_EXPR
:
14580 /* This should have been stripped above. */
14581 gcc_unreachable ();
14584 ret
= gimplify_asm_expr (expr_p
, pre_p
, post_p
);
14587 case TRY_FINALLY_EXPR
:
14588 case TRY_CATCH_EXPR
:
14590 gimple_seq eval
, cleanup
;
14593 /* Calls to destructors are generated automatically in FINALLY/CATCH
14594 block. They should have location as UNKNOWN_LOCATION. However,
14595 gimplify_call_expr will reset these call stmts to input_location
14596 if it finds stmt's location is unknown. To prevent resetting for
14597 destructors, we set the input_location to unknown.
14598 Note that this only affects the destructor calls in FINALLY/CATCH
14599 block, and will automatically reset to its original value by the
14600 end of gimplify_expr. */
14601 input_location
= UNKNOWN_LOCATION
;
14602 eval
= cleanup
= NULL
;
14603 gimplify_and_add (TREE_OPERAND (*expr_p
, 0), &eval
);
14604 if (TREE_CODE (*expr_p
) == TRY_FINALLY_EXPR
14605 && TREE_CODE (TREE_OPERAND (*expr_p
, 1)) == EH_ELSE_EXPR
)
14607 gimple_seq n
= NULL
, e
= NULL
;
14608 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p
, 1),
14610 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p
, 1),
14612 if (!gimple_seq_empty_p (n
) && !gimple_seq_empty_p (e
))
14614 geh_else
*stmt
= gimple_build_eh_else (n
, e
);
14615 gimple_seq_add_stmt (&cleanup
, stmt
);
14619 gimplify_and_add (TREE_OPERAND (*expr_p
, 1), &cleanup
);
14620 /* Don't create bogus GIMPLE_TRY with empty cleanup. */
14621 if (gimple_seq_empty_p (cleanup
))
14623 gimple_seq_add_seq (pre_p
, eval
);
14627 try_
= gimple_build_try (eval
, cleanup
,
14628 TREE_CODE (*expr_p
) == TRY_FINALLY_EXPR
14629 ? GIMPLE_TRY_FINALLY
14630 : GIMPLE_TRY_CATCH
);
14631 if (EXPR_HAS_LOCATION (save_expr
))
14632 gimple_set_location (try_
, EXPR_LOCATION (save_expr
));
14633 else if (LOCATION_LOCUS (saved_location
) != UNKNOWN_LOCATION
)
14634 gimple_set_location (try_
, saved_location
);
14635 if (TREE_CODE (*expr_p
) == TRY_CATCH_EXPR
)
14636 gimple_try_set_catch_is_cleanup (try_
,
14637 TRY_CATCH_IS_CLEANUP (*expr_p
));
14638 gimplify_seq_add_stmt (pre_p
, try_
);
14643 case CLEANUP_POINT_EXPR
:
14644 ret
= gimplify_cleanup_point_expr (expr_p
, pre_p
);
14648 ret
= gimplify_target_expr (expr_p
, pre_p
, post_p
);
14654 gimple_seq handler
= NULL
;
14655 gimplify_and_add (CATCH_BODY (*expr_p
), &handler
);
14656 c
= gimple_build_catch (CATCH_TYPES (*expr_p
), handler
);
14657 gimplify_seq_add_stmt (pre_p
, c
);
14662 case EH_FILTER_EXPR
:
14665 gimple_seq failure
= NULL
;
14667 gimplify_and_add (EH_FILTER_FAILURE (*expr_p
), &failure
);
14668 ehf
= gimple_build_eh_filter (EH_FILTER_TYPES (*expr_p
), failure
);
14669 copy_warning (ehf
, *expr_p
);
14670 gimplify_seq_add_stmt (pre_p
, ehf
);
14677 enum gimplify_status r0
, r1
;
14678 r0
= gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p
), pre_p
,
14679 post_p
, is_gimple_val
, fb_rvalue
);
14680 r1
= gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p
), pre_p
,
14681 post_p
, is_gimple_val
, fb_rvalue
);
14682 TREE_SIDE_EFFECTS (*expr_p
) = 0;
14683 ret
= MIN (r0
, r1
);
14688 /* We get here when taking the address of a label. We mark
14689 the label as "forced"; meaning it can never be removed and
14690 it is a potential target for any computed goto. */
14691 FORCED_LABEL (*expr_p
) = 1;
14695 case STATEMENT_LIST
:
14696 ret
= gimplify_statement_list (expr_p
, pre_p
);
14699 case WITH_SIZE_EXPR
:
14701 gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
14702 post_p
== &internal_post
? NULL
: post_p
,
14703 gimple_test_f
, fallback
);
14704 gimplify_expr (&TREE_OPERAND (*expr_p
, 1), pre_p
, post_p
,
14705 is_gimple_val
, fb_rvalue
);
14712 ret
= gimplify_var_or_parm_decl (expr_p
);
14716 /* When within an OMP context, notice uses of variables. */
14717 if (gimplify_omp_ctxp
)
14718 omp_notice_variable (gimplify_omp_ctxp
, *expr_p
, true);
14722 case DEBUG_EXPR_DECL
:
14723 gcc_unreachable ();
14725 case DEBUG_BEGIN_STMT
:
14726 gimplify_seq_add_stmt (pre_p
,
14727 gimple_build_debug_begin_stmt
14728 (TREE_BLOCK (*expr_p
),
14729 EXPR_LOCATION (*expr_p
)));
14735 /* Allow callbacks into the gimplifier during optimization. */
14740 gimplify_omp_parallel (expr_p
, pre_p
);
14745 gimplify_omp_task (expr_p
, pre_p
);
14751 case OMP_DISTRIBUTE
:
14754 ret
= gimplify_omp_for (expr_p
, pre_p
);
14758 ret
= gimplify_omp_loop (expr_p
, pre_p
);
14762 gimplify_oacc_cache (expr_p
, pre_p
);
14767 gimplify_oacc_declare (expr_p
, pre_p
);
14771 case OACC_HOST_DATA
:
14774 case OACC_PARALLEL
:
14780 case OMP_TARGET_DATA
:
14782 gimplify_omp_workshare (expr_p
, pre_p
);
14786 case OACC_ENTER_DATA
:
14787 case OACC_EXIT_DATA
:
14789 case OMP_TARGET_UPDATE
:
14790 case OMP_TARGET_ENTER_DATA
:
14791 case OMP_TARGET_EXIT_DATA
:
14792 gimplify_omp_target_update (expr_p
, pre_p
);
14803 gimple_seq body
= NULL
;
14805 bool saved_in_omp_construct
= in_omp_construct
;
14807 in_omp_construct
= true;
14808 gimplify_and_add (OMP_BODY (*expr_p
), &body
);
14809 in_omp_construct
= saved_in_omp_construct
;
14810 switch (TREE_CODE (*expr_p
))
14813 g
= gimple_build_omp_section (body
);
14816 g
= gimple_build_omp_master (body
);
14819 g
= gimplify_omp_ordered (*expr_p
, body
);
14822 gimplify_scan_omp_clauses (&OMP_MASKED_CLAUSES (*expr_p
),
14823 pre_p
, ORT_WORKSHARE
, OMP_MASKED
);
14824 gimplify_adjust_omp_clauses (pre_p
, body
,
14825 &OMP_MASKED_CLAUSES (*expr_p
),
14827 g
= gimple_build_omp_masked (body
,
14828 OMP_MASKED_CLAUSES (*expr_p
));
14831 gimplify_scan_omp_clauses (&OMP_CRITICAL_CLAUSES (*expr_p
),
14832 pre_p
, ORT_WORKSHARE
, OMP_CRITICAL
);
14833 gimplify_adjust_omp_clauses (pre_p
, body
,
14834 &OMP_CRITICAL_CLAUSES (*expr_p
),
14836 g
= gimple_build_omp_critical (body
,
14837 OMP_CRITICAL_NAME (*expr_p
),
14838 OMP_CRITICAL_CLAUSES (*expr_p
));
14841 gimplify_scan_omp_clauses (&OMP_SCAN_CLAUSES (*expr_p
),
14842 pre_p
, ORT_WORKSHARE
, OMP_SCAN
);
14843 gimplify_adjust_omp_clauses (pre_p
, body
,
14844 &OMP_SCAN_CLAUSES (*expr_p
),
14846 g
= gimple_build_omp_scan (body
, OMP_SCAN_CLAUSES (*expr_p
));
14849 gcc_unreachable ();
14851 gimplify_seq_add_stmt (pre_p
, g
);
14856 case OMP_TASKGROUP
:
14858 gimple_seq body
= NULL
;
14860 tree
*pclauses
= &OMP_TASKGROUP_CLAUSES (*expr_p
);
14861 bool saved_in_omp_construct
= in_omp_construct
;
14862 gimplify_scan_omp_clauses (pclauses
, pre_p
, ORT_TASKGROUP
,
14864 gimplify_adjust_omp_clauses (pre_p
, NULL
, pclauses
, OMP_TASKGROUP
);
14866 in_omp_construct
= true;
14867 gimplify_and_add (OMP_BODY (*expr_p
), &body
);
14868 in_omp_construct
= saved_in_omp_construct
;
14869 gimple_seq cleanup
= NULL
;
14870 tree fn
= builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_END
);
14871 gimple
*g
= gimple_build_call (fn
, 0);
14872 gimple_seq_add_stmt (&cleanup
, g
);
14873 g
= gimple_build_try (body
, cleanup
, GIMPLE_TRY_FINALLY
);
14875 gimple_seq_add_stmt (&body
, g
);
14876 g
= gimple_build_omp_taskgroup (body
, *pclauses
);
14877 gimplify_seq_add_stmt (pre_p
, g
);
14883 case OMP_ATOMIC_READ
:
14884 case OMP_ATOMIC_CAPTURE_OLD
:
14885 case OMP_ATOMIC_CAPTURE_NEW
:
14886 ret
= gimplify_omp_atomic (expr_p
, pre_p
);
14889 case TRANSACTION_EXPR
:
14890 ret
= gimplify_transaction (expr_p
, pre_p
);
14893 case TRUTH_AND_EXPR
:
14894 case TRUTH_OR_EXPR
:
14895 case TRUTH_XOR_EXPR
:
14897 tree orig_type
= TREE_TYPE (*expr_p
);
14898 tree new_type
, xop0
, xop1
;
14899 *expr_p
= gimple_boolify (*expr_p
);
14900 new_type
= TREE_TYPE (*expr_p
);
14901 if (!useless_type_conversion_p (orig_type
, new_type
))
14903 *expr_p
= fold_convert_loc (input_location
, orig_type
, *expr_p
);
14908 /* Boolified binary truth expressions are semantically equivalent
14909 to bitwise binary expressions. Canonicalize them to the
14910 bitwise variant. */
14911 switch (TREE_CODE (*expr_p
))
14913 case TRUTH_AND_EXPR
:
14914 TREE_SET_CODE (*expr_p
, BIT_AND_EXPR
);
14916 case TRUTH_OR_EXPR
:
14917 TREE_SET_CODE (*expr_p
, BIT_IOR_EXPR
);
14919 case TRUTH_XOR_EXPR
:
14920 TREE_SET_CODE (*expr_p
, BIT_XOR_EXPR
);
14925 /* Now make sure that operands have compatible type to
14926 expression's new_type. */
14927 xop0
= TREE_OPERAND (*expr_p
, 0);
14928 xop1
= TREE_OPERAND (*expr_p
, 1);
14929 if (!useless_type_conversion_p (new_type
, TREE_TYPE (xop0
)))
14930 TREE_OPERAND (*expr_p
, 0) = fold_convert_loc (input_location
,
14933 if (!useless_type_conversion_p (new_type
, TREE_TYPE (xop1
)))
14934 TREE_OPERAND (*expr_p
, 1) = fold_convert_loc (input_location
,
14937 /* Continue classified as tcc_binary. */
14941 case VEC_COND_EXPR
:
14944 case VEC_PERM_EXPR
:
14945 /* Classified as tcc_expression. */
14948 case BIT_INSERT_EXPR
:
14949 /* Argument 3 is a constant. */
14952 case POINTER_PLUS_EXPR
:
14954 enum gimplify_status r0
, r1
;
14955 r0
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
14956 post_p
, is_gimple_val
, fb_rvalue
);
14957 r1
= gimplify_expr (&TREE_OPERAND (*expr_p
, 1), pre_p
,
14958 post_p
, is_gimple_val
, fb_rvalue
);
14959 recalculate_side_effects (*expr_p
);
14960 ret
= MIN (r0
, r1
);
14965 switch (TREE_CODE_CLASS (TREE_CODE (*expr_p
)))
14967 case tcc_comparison
:
14968 /* Handle comparison of objects of non scalar mode aggregates
14969 with a call to memcmp. It would be nice to only have to do
14970 this for variable-sized objects, but then we'd have to allow
14971 the same nest of reference nodes we allow for MODIFY_EXPR and
14972 that's too complex.
14974 Compare scalar mode aggregates as scalar mode values. Using
14975 memcmp for them would be very inefficient at best, and is
14976 plain wrong if bitfields are involved. */
14978 tree type
= TREE_TYPE (TREE_OPERAND (*expr_p
, 1));
14980 /* Vector comparisons need no boolification. */
14981 if (TREE_CODE (type
) == VECTOR_TYPE
)
14983 else if (!AGGREGATE_TYPE_P (type
))
14985 tree org_type
= TREE_TYPE (*expr_p
);
14986 *expr_p
= gimple_boolify (*expr_p
);
14987 if (!useless_type_conversion_p (org_type
,
14988 TREE_TYPE (*expr_p
)))
14990 *expr_p
= fold_convert_loc (input_location
,
14991 org_type
, *expr_p
);
14997 else if (TYPE_MODE (type
) != BLKmode
)
14998 ret
= gimplify_scalar_mode_aggregate_compare (expr_p
);
15000 ret
= gimplify_variable_sized_compare (expr_p
);
15005 /* If *EXPR_P does not need to be special-cased, handle it
15006 according to its class. */
15008 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
15009 post_p
, is_gimple_val
, fb_rvalue
);
15015 enum gimplify_status r0
, r1
;
15017 r0
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
15018 post_p
, is_gimple_val
, fb_rvalue
);
15019 r1
= gimplify_expr (&TREE_OPERAND (*expr_p
, 1), pre_p
,
15020 post_p
, is_gimple_val
, fb_rvalue
);
15022 ret
= MIN (r0
, r1
);
15028 enum gimplify_status r0
, r1
, r2
;
15030 r0
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
15031 post_p
, is_gimple_val
, fb_rvalue
);
15032 r1
= gimplify_expr (&TREE_OPERAND (*expr_p
, 1), pre_p
,
15033 post_p
, is_gimple_val
, fb_rvalue
);
15034 r2
= gimplify_expr (&TREE_OPERAND (*expr_p
, 2), pre_p
,
15035 post_p
, is_gimple_val
, fb_rvalue
);
15037 ret
= MIN (MIN (r0
, r1
), r2
);
15041 case tcc_declaration
:
15044 goto dont_recalculate
;
15047 gcc_unreachable ();
15050 recalculate_side_effects (*expr_p
);
15056 gcc_assert (*expr_p
|| ret
!= GS_OK
);
15058 while (ret
== GS_OK
);
15060 /* If we encountered an error_mark somewhere nested inside, either
15061 stub out the statement or propagate the error back out. */
15062 if (ret
== GS_ERROR
)
15069 /* This was only valid as a return value from the langhook, which
15070 we handled. Make sure it doesn't escape from any other context. */
15071 gcc_assert (ret
!= GS_UNHANDLED
);
15073 if (fallback
== fb_none
&& *expr_p
&& !is_gimple_stmt (*expr_p
))
15075 /* We aren't looking for a value, and we don't have a valid
15076 statement. If it doesn't have side-effects, throw it away.
15077 We can also get here with code such as "*&&L;", where L is
15078 a LABEL_DECL that is marked as FORCED_LABEL. */
15079 if (TREE_CODE (*expr_p
) == LABEL_DECL
15080 || !TREE_SIDE_EFFECTS (*expr_p
))
15082 else if (!TREE_THIS_VOLATILE (*expr_p
))
15084 /* This is probably a _REF that contains something nested that
15085 has side effects. Recurse through the operands to find it. */
15086 enum tree_code code
= TREE_CODE (*expr_p
);
15090 case COMPONENT_REF
:
15091 case REALPART_EXPR
:
15092 case IMAGPART_EXPR
:
15093 case VIEW_CONVERT_EXPR
:
15094 gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
15095 gimple_test_f
, fallback
);
15099 case ARRAY_RANGE_REF
:
15100 gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
15101 gimple_test_f
, fallback
);
15102 gimplify_expr (&TREE_OPERAND (*expr_p
, 1), pre_p
, post_p
,
15103 gimple_test_f
, fallback
);
15107 /* Anything else with side-effects must be converted to
15108 a valid statement before we get here. */
15109 gcc_unreachable ();
15114 else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p
))
15115 && TYPE_MODE (TREE_TYPE (*expr_p
)) != BLKmode
15116 && !is_empty_type (TREE_TYPE (*expr_p
)))
15118 /* Historically, the compiler has treated a bare reference
15119 to a non-BLKmode volatile lvalue as forcing a load. */
15120 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p
));
15122 /* Normally, we do not want to create a temporary for a
15123 TREE_ADDRESSABLE type because such a type should not be
15124 copied by bitwise-assignment. However, we make an
15125 exception here, as all we are doing here is ensuring that
15126 we read the bytes that make up the type. We use
15127 create_tmp_var_raw because create_tmp_var will abort when
15128 given a TREE_ADDRESSABLE type. */
15129 tree tmp
= create_tmp_var_raw (type
, "vol");
15130 gimple_add_tmp_var (tmp
);
15131 gimplify_assign (tmp
, *expr_p
, pre_p
);
15135 /* We can't do anything useful with a volatile reference to
15136 an incomplete type, so just throw it away. Likewise for
15137 a BLKmode type, since any implicit inner load should
15138 already have been turned into an explicit one by the
15139 gimplification process. */
15143 /* If we are gimplifying at the statement level, we're done. Tack
15144 everything together and return. */
15145 if (fallback
== fb_none
|| is_statement
)
15147 /* Since *EXPR_P has been converted into a GIMPLE tuple, clear
15148 it out for GC to reclaim it. */
15149 *expr_p
= NULL_TREE
;
15151 if (!gimple_seq_empty_p (internal_pre
)
15152 || !gimple_seq_empty_p (internal_post
))
15154 gimplify_seq_add_seq (&internal_pre
, internal_post
);
15155 gimplify_seq_add_seq (pre_p
, internal_pre
);
15158 /* The result of gimplifying *EXPR_P is going to be the last few
15159 statements in *PRE_P and *POST_P. Add location information
15160 to all the statements that were added by the gimplification
15162 if (!gimple_seq_empty_p (*pre_p
))
15163 annotate_all_with_location_after (*pre_p
, pre_last_gsi
, input_location
);
15165 if (!gimple_seq_empty_p (*post_p
))
15166 annotate_all_with_location_after (*post_p
, post_last_gsi
,
15172 #ifdef ENABLE_GIMPLE_CHECKING
15175 enum tree_code code
= TREE_CODE (*expr_p
);
15176 /* These expressions should already be in gimple IR form. */
15177 gcc_assert (code
!= MODIFY_EXPR
15178 && code
!= ASM_EXPR
15179 && code
!= BIND_EXPR
15180 && code
!= CATCH_EXPR
15181 && (code
!= COND_EXPR
|| gimplify_ctxp
->allow_rhs_cond_expr
)
15182 && code
!= EH_FILTER_EXPR
15183 && code
!= GOTO_EXPR
15184 && code
!= LABEL_EXPR
15185 && code
!= LOOP_EXPR
15186 && code
!= SWITCH_EXPR
15187 && code
!= TRY_FINALLY_EXPR
15188 && code
!= EH_ELSE_EXPR
15189 && code
!= OACC_PARALLEL
15190 && code
!= OACC_KERNELS
15191 && code
!= OACC_SERIAL
15192 && code
!= OACC_DATA
15193 && code
!= OACC_HOST_DATA
15194 && code
!= OACC_DECLARE
15195 && code
!= OACC_UPDATE
15196 && code
!= OACC_ENTER_DATA
15197 && code
!= OACC_EXIT_DATA
15198 && code
!= OACC_CACHE
15199 && code
!= OMP_CRITICAL
15201 && code
!= OACC_LOOP
15202 && code
!= OMP_MASTER
15203 && code
!= OMP_MASKED
15204 && code
!= OMP_TASKGROUP
15205 && code
!= OMP_ORDERED
15206 && code
!= OMP_PARALLEL
15207 && code
!= OMP_SCAN
15208 && code
!= OMP_SECTIONS
15209 && code
!= OMP_SECTION
15210 && code
!= OMP_SINGLE
15211 && code
!= OMP_SCOPE
);
15215 /* Otherwise we're gimplifying a subexpression, so the resulting
15216 value is interesting. If it's a valid operand that matches
15217 GIMPLE_TEST_F, we're done. Unless we are handling some
15218 post-effects internally; if that's the case, we need to copy into
15219 a temporary before adding the post-effects to POST_P. */
15220 if (gimple_seq_empty_p (internal_post
) && (*gimple_test_f
) (*expr_p
))
15223 /* Otherwise, we need to create a new temporary for the gimplified
15226 /* We can't return an lvalue if we have an internal postqueue. The
15227 object the lvalue refers to would (probably) be modified by the
15228 postqueue; we need to copy the value out first, which means an
15230 if ((fallback
& fb_lvalue
)
15231 && gimple_seq_empty_p (internal_post
)
15232 && is_gimple_addressable (*expr_p
))
15234 /* An lvalue will do. Take the address of the expression, store it
15235 in a temporary, and replace the expression with an INDIRECT_REF of
15237 tree ref_alias_type
= reference_alias_ptr_type (*expr_p
);
15238 unsigned int ref_align
= get_object_alignment (*expr_p
);
15239 tree ref_type
= TREE_TYPE (*expr_p
);
15240 tmp
= build_fold_addr_expr_loc (input_location
, *expr_p
);
15241 gimplify_expr (&tmp
, pre_p
, post_p
, is_gimple_reg
, fb_rvalue
);
15242 if (TYPE_ALIGN (ref_type
) != ref_align
)
15243 ref_type
= build_aligned_type (ref_type
, ref_align
);
15244 *expr_p
= build2 (MEM_REF
, ref_type
,
15245 tmp
, build_zero_cst (ref_alias_type
));
15247 else if ((fallback
& fb_rvalue
) && is_gimple_reg_rhs_or_call (*expr_p
))
15249 /* An rvalue will do. Assign the gimplified expression into a
15250 new temporary TMP and replace the original expression with
15251 TMP. First, make sure that the expression has a type so that
15252 it can be assigned into a temporary. */
15253 gcc_assert (!VOID_TYPE_P (TREE_TYPE (*expr_p
)));
15254 *expr_p
= get_formal_tmp_var (*expr_p
, pre_p
);
15258 #ifdef ENABLE_GIMPLE_CHECKING
15259 if (!(fallback
& fb_mayfail
))
15261 fprintf (stderr
, "gimplification failed:\n");
15262 print_generic_expr (stderr
, *expr_p
);
15263 debug_tree (*expr_p
);
15264 internal_error ("gimplification failed");
15267 gcc_assert (fallback
& fb_mayfail
);
15269 /* If this is an asm statement, and the user asked for the
15270 impossible, don't die. Fail and let gimplify_asm_expr
15276 /* Make sure the temporary matches our predicate. */
15277 gcc_assert ((*gimple_test_f
) (*expr_p
));
15279 if (!gimple_seq_empty_p (internal_post
))
15281 annotate_all_with_location (internal_post
, input_location
);
15282 gimplify_seq_add_seq (pre_p
, internal_post
);
15286 input_location
= saved_location
;
15290 /* Like gimplify_expr but make sure the gimplified result is not itself
15291 a SSA name (but a decl if it were). Temporaries required by
15292 evaluating *EXPR_P may be still SSA names. */
15294 static enum gimplify_status
15295 gimplify_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
15296 bool (*gimple_test_f
) (tree
), fallback_t fallback
,
15299 enum gimplify_status ret
= gimplify_expr (expr_p
, pre_p
, post_p
,
15300 gimple_test_f
, fallback
);
15302 && TREE_CODE (*expr_p
) == SSA_NAME
)
15303 *expr_p
= get_initialized_tmp_var (*expr_p
, pre_p
, NULL
, false);
15307 /* Look through TYPE for variable-sized objects and gimplify each such
15308 size that we find. Add to LIST_P any statements generated. */
15311 gimplify_type_sizes (tree type
, gimple_seq
*list_p
)
15313 if (type
== NULL
|| type
== error_mark_node
)
15316 const bool ignored_p
15318 && TREE_CODE (TYPE_NAME (type
)) == TYPE_DECL
15319 && DECL_IGNORED_P (TYPE_NAME (type
));
15322 /* We first do the main variant, then copy into any other variants. */
15323 type
= TYPE_MAIN_VARIANT (type
);
15325 /* Avoid infinite recursion. */
15326 if (TYPE_SIZES_GIMPLIFIED (type
))
15329 TYPE_SIZES_GIMPLIFIED (type
) = 1;
15331 switch (TREE_CODE (type
))
15334 case ENUMERAL_TYPE
:
15337 case FIXED_POINT_TYPE
:
15338 gimplify_one_sizepos (&TYPE_MIN_VALUE (type
), list_p
);
15339 gimplify_one_sizepos (&TYPE_MAX_VALUE (type
), list_p
);
15341 for (t
= TYPE_NEXT_VARIANT (type
); t
; t
= TYPE_NEXT_VARIANT (t
))
15343 TYPE_MIN_VALUE (t
) = TYPE_MIN_VALUE (type
);
15344 TYPE_MAX_VALUE (t
) = TYPE_MAX_VALUE (type
);
15349 /* These types may not have declarations, so handle them here. */
15350 gimplify_type_sizes (TREE_TYPE (type
), list_p
);
15351 gimplify_type_sizes (TYPE_DOMAIN (type
), list_p
);
15352 /* Ensure VLA bounds aren't removed, for -O0 they should be variables
15353 with assigned stack slots, for -O1+ -g they should be tracked
15356 && TYPE_DOMAIN (type
)
15357 && INTEGRAL_TYPE_P (TYPE_DOMAIN (type
)))
15359 t
= TYPE_MIN_VALUE (TYPE_DOMAIN (type
));
15360 if (t
&& VAR_P (t
) && DECL_ARTIFICIAL (t
))
15361 DECL_IGNORED_P (t
) = 0;
15362 t
= TYPE_MAX_VALUE (TYPE_DOMAIN (type
));
15363 if (t
&& VAR_P (t
) && DECL_ARTIFICIAL (t
))
15364 DECL_IGNORED_P (t
) = 0;
15370 case QUAL_UNION_TYPE
:
15371 for (tree field
= TYPE_FIELDS (type
); field
; field
= DECL_CHAIN (field
))
15372 if (TREE_CODE (field
) == FIELD_DECL
)
15374 gimplify_one_sizepos (&DECL_FIELD_OFFSET (field
), list_p
);
15375 /* Likewise, ensure variable offsets aren't removed. */
15377 && (t
= DECL_FIELD_OFFSET (field
))
15379 && DECL_ARTIFICIAL (t
))
15380 DECL_IGNORED_P (t
) = 0;
15381 gimplify_one_sizepos (&DECL_SIZE (field
), list_p
);
15382 gimplify_one_sizepos (&DECL_SIZE_UNIT (field
), list_p
);
15383 gimplify_type_sizes (TREE_TYPE (field
), list_p
);
15388 case REFERENCE_TYPE
:
15389 /* We used to recurse on the pointed-to type here, which turned out to
15390 be incorrect because its definition might refer to variables not
15391 yet initialized at this point if a forward declaration is involved.
15393 It was actually useful for anonymous pointed-to types to ensure
15394 that the sizes evaluation dominates every possible later use of the
15395 values. Restricting to such types here would be safe since there
15396 is no possible forward declaration around, but would introduce an
15397 undesirable middle-end semantic to anonymity. We then defer to
15398 front-ends the responsibility of ensuring that the sizes are
15399 evaluated both early and late enough, e.g. by attaching artificial
15400 type declarations to the tree. */
15407 gimplify_one_sizepos (&TYPE_SIZE (type
), list_p
);
15408 gimplify_one_sizepos (&TYPE_SIZE_UNIT (type
), list_p
);
15410 for (t
= TYPE_NEXT_VARIANT (type
); t
; t
= TYPE_NEXT_VARIANT (t
))
15412 TYPE_SIZE (t
) = TYPE_SIZE (type
);
15413 TYPE_SIZE_UNIT (t
) = TYPE_SIZE_UNIT (type
);
15414 TYPE_SIZES_GIMPLIFIED (t
) = 1;
15418 /* A subroutine of gimplify_type_sizes to make sure that *EXPR_P,
15419 a size or position, has had all of its SAVE_EXPRs evaluated.
15420 We add any required statements to *STMT_P. */
15423 gimplify_one_sizepos (tree
*expr_p
, gimple_seq
*stmt_p
)
15425 tree expr
= *expr_p
;
15427 /* We don't do anything if the value isn't there, is constant, or contains
15428 A PLACEHOLDER_EXPR. We also don't want to do anything if it's already
15429 a VAR_DECL. If it's a VAR_DECL from another function, the gimplifier
15430 will want to replace it with a new variable, but that will cause problems
15431 if this type is from outside the function. It's OK to have that here. */
15432 if (expr
== NULL_TREE
15433 || is_gimple_constant (expr
)
15434 || TREE_CODE (expr
) == VAR_DECL
15435 || CONTAINS_PLACEHOLDER_P (expr
))
15438 *expr_p
= unshare_expr (expr
);
15440 /* SSA names in decl/type fields are a bad idea - they'll get reclaimed
15441 if the def vanishes. */
15442 gimplify_expr (expr_p
, stmt_p
, NULL
, is_gimple_val
, fb_rvalue
, false);
15444 /* If expr wasn't already is_gimple_sizepos or is_gimple_constant from the
15445 FE, ensure that it is a VAR_DECL, otherwise we might handle some decls
15446 as gimplify_vla_decl even when they would have all sizes INTEGER_CSTs. */
15447 if (is_gimple_constant (*expr_p
))
15448 *expr_p
= get_initialized_tmp_var (*expr_p
, stmt_p
, NULL
, false);
15451 /* Gimplify the body of statements of FNDECL and return a GIMPLE_BIND node
15452 containing the sequence of corresponding GIMPLE statements. If DO_PARMS
15453 is true, also gimplify the parameters. */
15456 gimplify_body (tree fndecl
, bool do_parms
)
15458 location_t saved_location
= input_location
;
15459 gimple_seq parm_stmts
, parm_cleanup
= NULL
, seq
;
15460 gimple
*outer_stmt
;
15463 timevar_push (TV_TREE_GIMPLIFY
);
15465 init_tree_ssa (cfun
);
15467 /* Initialize for optimize_insn_for_s{ize,peed}_p possibly called during
15469 default_rtl_profile ();
15471 gcc_assert (gimplify_ctxp
== NULL
);
15472 push_gimplify_context (true);
15474 if (flag_openacc
|| flag_openmp
)
15476 gcc_assert (gimplify_omp_ctxp
== NULL
);
15477 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (fndecl
)))
15478 gimplify_omp_ctxp
= new_omp_context (ORT_IMPLICIT_TARGET
);
15481 /* Unshare most shared trees in the body and in that of any nested functions.
15482 It would seem we don't have to do this for nested functions because
15483 they are supposed to be output and then the outer function gimplified
15484 first, but the g++ front end doesn't always do it that way. */
15485 unshare_body (fndecl
);
15486 unvisit_body (fndecl
);
15488 /* Make sure input_location isn't set to something weird. */
15489 input_location
= DECL_SOURCE_LOCATION (fndecl
);
15491 /* Resolve callee-copies. This has to be done before processing
15492 the body so that DECL_VALUE_EXPR gets processed correctly. */
15493 parm_stmts
= do_parms
? gimplify_parameters (&parm_cleanup
) : NULL
;
15495 /* Gimplify the function's body. */
15497 gimplify_stmt (&DECL_SAVED_TREE (fndecl
), &seq
);
15498 outer_stmt
= gimple_seq_first_nondebug_stmt (seq
);
15501 outer_stmt
= gimple_build_nop ();
15502 gimplify_seq_add_stmt (&seq
, outer_stmt
);
15505 /* The body must contain exactly one statement, a GIMPLE_BIND. If this is
15506 not the case, wrap everything in a GIMPLE_BIND to make it so. */
15507 if (gimple_code (outer_stmt
) == GIMPLE_BIND
15508 && (gimple_seq_first_nondebug_stmt (seq
)
15509 == gimple_seq_last_nondebug_stmt (seq
)))
15511 outer_bind
= as_a
<gbind
*> (outer_stmt
);
15512 if (gimple_seq_first_stmt (seq
) != outer_stmt
15513 || gimple_seq_last_stmt (seq
) != outer_stmt
)
15515 /* If there are debug stmts before or after outer_stmt, move them
15516 inside of outer_bind body. */
15517 gimple_stmt_iterator gsi
= gsi_for_stmt (outer_stmt
, &seq
);
15518 gimple_seq second_seq
= NULL
;
15519 if (gimple_seq_first_stmt (seq
) != outer_stmt
15520 && gimple_seq_last_stmt (seq
) != outer_stmt
)
15522 second_seq
= gsi_split_seq_after (gsi
);
15523 gsi_remove (&gsi
, false);
15525 else if (gimple_seq_first_stmt (seq
) != outer_stmt
)
15526 gsi_remove (&gsi
, false);
15529 gsi_remove (&gsi
, false);
15533 gimple_seq_add_seq_without_update (&seq
,
15534 gimple_bind_body (outer_bind
));
15535 gimple_seq_add_seq_without_update (&seq
, second_seq
);
15536 gimple_bind_set_body (outer_bind
, seq
);
15540 outer_bind
= gimple_build_bind (NULL_TREE
, seq
, NULL
);
15542 DECL_SAVED_TREE (fndecl
) = NULL_TREE
;
15544 /* If we had callee-copies statements, insert them at the beginning
15545 of the function and clear DECL_VALUE_EXPR_P on the parameters. */
15546 if (!gimple_seq_empty_p (parm_stmts
))
15550 gimplify_seq_add_seq (&parm_stmts
, gimple_bind_body (outer_bind
));
15553 gtry
*g
= gimple_build_try (parm_stmts
, parm_cleanup
,
15554 GIMPLE_TRY_FINALLY
);
15556 gimple_seq_add_stmt (&parm_stmts
, g
);
15558 gimple_bind_set_body (outer_bind
, parm_stmts
);
15560 for (parm
= DECL_ARGUMENTS (current_function_decl
);
15561 parm
; parm
= DECL_CHAIN (parm
))
15562 if (DECL_HAS_VALUE_EXPR_P (parm
))
15564 DECL_HAS_VALUE_EXPR_P (parm
) = 0;
15565 DECL_IGNORED_P (parm
) = 0;
15569 if ((flag_openacc
|| flag_openmp
|| flag_openmp_simd
)
15570 && gimplify_omp_ctxp
)
15572 delete_omp_context (gimplify_omp_ctxp
);
15573 gimplify_omp_ctxp
= NULL
;
15576 pop_gimplify_context (outer_bind
);
15577 gcc_assert (gimplify_ctxp
== NULL
);
15579 if (flag_checking
&& !seen_error ())
15580 verify_gimple_in_seq (gimple_bind_body (outer_bind
));
15582 timevar_pop (TV_TREE_GIMPLIFY
);
15583 input_location
= saved_location
;
15588 typedef char *char_p
; /* For DEF_VEC_P. */
15590 /* Return whether we should exclude FNDECL from instrumentation. */
15593 flag_instrument_functions_exclude_p (tree fndecl
)
15597 v
= (vec
<char_p
> *) flag_instrument_functions_exclude_functions
;
15598 if (v
&& v
->length () > 0)
15604 name
= lang_hooks
.decl_printable_name (fndecl
, 1);
15605 FOR_EACH_VEC_ELT (*v
, i
, s
)
15606 if (strstr (name
, s
) != NULL
)
15610 v
= (vec
<char_p
> *) flag_instrument_functions_exclude_files
;
15611 if (v
&& v
->length () > 0)
15617 name
= DECL_SOURCE_FILE (fndecl
);
15618 FOR_EACH_VEC_ELT (*v
, i
, s
)
15619 if (strstr (name
, s
) != NULL
)
15626 /* Entry point to the gimplification pass. FNDECL is the FUNCTION_DECL
15627 node for the function we want to gimplify.
15629 Return the sequence of GIMPLE statements corresponding to the body
15633 gimplify_function_tree (tree fndecl
)
15638 gcc_assert (!gimple_body (fndecl
));
15640 if (DECL_STRUCT_FUNCTION (fndecl
))
15641 push_cfun (DECL_STRUCT_FUNCTION (fndecl
));
15643 push_struct_function (fndecl
);
15645 /* Tentatively set PROP_gimple_lva here, and reset it in gimplify_va_arg_expr
15647 cfun
->curr_properties
|= PROP_gimple_lva
;
15649 if (asan_sanitize_use_after_scope ())
15650 asan_poisoned_variables
= new hash_set
<tree
> ();
15651 bind
= gimplify_body (fndecl
, true);
15652 if (asan_poisoned_variables
)
15654 delete asan_poisoned_variables
;
15655 asan_poisoned_variables
= NULL
;
15658 /* The tree body of the function is no longer needed, replace it
15659 with the new GIMPLE body. */
15661 gimple_seq_add_stmt (&seq
, bind
);
15662 gimple_set_body (fndecl
, seq
);
15664 /* If we're instrumenting function entry/exit, then prepend the call to
15665 the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to
15666 catch the exit hook. */
15667 /* ??? Add some way to ignore exceptions for this TFE. */
15668 if (flag_instrument_function_entry_exit
15669 && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl
)
15670 /* Do not instrument extern inline functions. */
15671 && !(DECL_DECLARED_INLINE_P (fndecl
)
15672 && DECL_EXTERNAL (fndecl
)
15673 && DECL_DISREGARD_INLINE_LIMITS (fndecl
))
15674 && !flag_instrument_functions_exclude_p (fndecl
))
15679 gimple_seq cleanup
= NULL
, body
= NULL
;
15680 tree tmp_var
, this_fn_addr
;
15683 /* The instrumentation hooks aren't going to call the instrumented
15684 function and the address they receive is expected to be matchable
15685 against symbol addresses. Make sure we don't create a trampoline,
15686 in case the current function is nested. */
15687 this_fn_addr
= build_fold_addr_expr (current_function_decl
);
15688 TREE_NO_TRAMPOLINE (this_fn_addr
) = 1;
15690 x
= builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS
);
15691 call
= gimple_build_call (x
, 1, integer_zero_node
);
15692 tmp_var
= create_tmp_var (ptr_type_node
, "return_addr");
15693 gimple_call_set_lhs (call
, tmp_var
);
15694 gimplify_seq_add_stmt (&cleanup
, call
);
15695 x
= builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_EXIT
);
15696 call
= gimple_build_call (x
, 2, this_fn_addr
, tmp_var
);
15697 gimplify_seq_add_stmt (&cleanup
, call
);
15698 tf
= gimple_build_try (seq
, cleanup
, GIMPLE_TRY_FINALLY
);
15700 x
= builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS
);
15701 call
= gimple_build_call (x
, 1, integer_zero_node
);
15702 tmp_var
= create_tmp_var (ptr_type_node
, "return_addr");
15703 gimple_call_set_lhs (call
, tmp_var
);
15704 gimplify_seq_add_stmt (&body
, call
);
15705 x
= builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_ENTER
);
15706 call
= gimple_build_call (x
, 2, this_fn_addr
, tmp_var
);
15707 gimplify_seq_add_stmt (&body
, call
);
15708 gimplify_seq_add_stmt (&body
, tf
);
15709 new_bind
= gimple_build_bind (NULL
, body
, NULL
);
15711 /* Replace the current function body with the body
15712 wrapped in the try/finally TF. */
15714 gimple_seq_add_stmt (&seq
, new_bind
);
15715 gimple_set_body (fndecl
, seq
);
15719 if (sanitize_flags_p (SANITIZE_THREAD
)
15720 && param_tsan_instrument_func_entry_exit
)
15722 gcall
*call
= gimple_build_call_internal (IFN_TSAN_FUNC_EXIT
, 0);
15723 gimple
*tf
= gimple_build_try (seq
, call
, GIMPLE_TRY_FINALLY
);
15724 gbind
*new_bind
= gimple_build_bind (NULL
, tf
, NULL
);
15725 /* Replace the current function body with the body
15726 wrapped in the try/finally TF. */
15728 gimple_seq_add_stmt (&seq
, new_bind
);
15729 gimple_set_body (fndecl
, seq
);
15732 DECL_SAVED_TREE (fndecl
) = NULL_TREE
;
15733 cfun
->curr_properties
|= PROP_gimple_any
;
15737 dump_function (TDI_gimple
, fndecl
);
15740 /* Return a dummy expression of type TYPE in order to keep going after an
15744 dummy_object (tree type
)
15746 tree t
= build_int_cst (build_pointer_type (type
), 0);
15747 return build2 (MEM_REF
, type
, t
, t
);
15750 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
15751 builtin function, but a very special sort of operator. */
15753 enum gimplify_status
15754 gimplify_va_arg_expr (tree
*expr_p
, gimple_seq
*pre_p
,
15755 gimple_seq
*post_p ATTRIBUTE_UNUSED
)
15757 tree promoted_type
, have_va_type
;
15758 tree valist
= TREE_OPERAND (*expr_p
, 0);
15759 tree type
= TREE_TYPE (*expr_p
);
15760 tree t
, tag
, aptag
;
15761 location_t loc
= EXPR_LOCATION (*expr_p
);
15763 /* Verify that valist is of the proper type. */
15764 have_va_type
= TREE_TYPE (valist
);
15765 if (have_va_type
== error_mark_node
)
15767 have_va_type
= targetm
.canonical_va_list_type (have_va_type
);
15768 if (have_va_type
== NULL_TREE
15769 && POINTER_TYPE_P (TREE_TYPE (valist
)))
15770 /* Handle 'Case 1: Not an array type' from c-common.c/build_va_arg. */
15772 = targetm
.canonical_va_list_type (TREE_TYPE (TREE_TYPE (valist
)));
15773 gcc_assert (have_va_type
!= NULL_TREE
);
15775 /* Generate a diagnostic for requesting data of a type that cannot
15776 be passed through `...' due to type promotion at the call site. */
15777 if ((promoted_type
= lang_hooks
.types
.type_promotes_to (type
))
15780 static bool gave_help
;
15782 /* Use the expansion point to handle cases such as passing bool (defined
15783 in a system header) through `...'. */
15785 = expansion_point_location_if_in_system_header (loc
);
15787 /* Unfortunately, this is merely undefined, rather than a constraint
15788 violation, so we cannot make this an error. If this call is never
15789 executed, the program is still strictly conforming. */
15790 auto_diagnostic_group d
;
15791 warned
= warning_at (xloc
, 0,
15792 "%qT is promoted to %qT when passed through %<...%>",
15793 type
, promoted_type
);
15794 if (!gave_help
&& warned
)
15797 inform (xloc
, "(so you should pass %qT not %qT to %<va_arg%>)",
15798 promoted_type
, type
);
15801 /* We can, however, treat "undefined" any way we please.
15802 Call abort to encourage the user to fix the program. */
15804 inform (xloc
, "if this code is reached, the program will abort");
15805 /* Before the abort, allow the evaluation of the va_list
15806 expression to exit or longjmp. */
15807 gimplify_and_add (valist
, pre_p
);
15808 t
= build_call_expr_loc (loc
,
15809 builtin_decl_implicit (BUILT_IN_TRAP
), 0);
15810 gimplify_and_add (t
, pre_p
);
15812 /* This is dead code, but go ahead and finish so that the
15813 mode of the result comes out right. */
15814 *expr_p
= dummy_object (type
);
15815 return GS_ALL_DONE
;
15818 tag
= build_int_cst (build_pointer_type (type
), 0);
15819 aptag
= build_int_cst (TREE_TYPE (valist
), 0);
15821 *expr_p
= build_call_expr_internal_loc (loc
, IFN_VA_ARG
, type
, 3,
15822 valist
, tag
, aptag
);
15824 /* Clear the tentatively set PROP_gimple_lva, to indicate that IFN_VA_ARG
15825 needs to be expanded. */
15826 cfun
->curr_properties
&= ~PROP_gimple_lva
;
15831 /* Build a new GIMPLE_ASSIGN tuple and append it to the end of *SEQ_P.
15833 DST/SRC are the destination and source respectively. You can pass
15834 ungimplified trees in DST or SRC, in which case they will be
15835 converted to a gimple operand if necessary.
15837 This function returns the newly created GIMPLE_ASSIGN tuple. */
15840 gimplify_assign (tree dst
, tree src
, gimple_seq
*seq_p
)
15842 tree t
= build2 (MODIFY_EXPR
, TREE_TYPE (dst
), dst
, src
);
15843 gimplify_and_add (t
, seq_p
);
15845 return gimple_seq_last_stmt (*seq_p
);
15849 gimplify_hasher::hash (const elt_t
*p
)
15852 return iterative_hash_expr (t
, 0);
15856 gimplify_hasher::equal (const elt_t
*p1
, const elt_t
*p2
)
15860 enum tree_code code
= TREE_CODE (t1
);
15862 if (TREE_CODE (t2
) != code
15863 || TREE_TYPE (t1
) != TREE_TYPE (t2
))
15866 if (!operand_equal_p (t1
, t2
, 0))
15869 /* Only allow them to compare equal if they also hash equal; otherwise
15870 results are nondeterminate, and we fail bootstrap comparison. */
15871 gcc_checking_assert (hash (p1
) == hash (p2
));