1 /* Tree lowering pass. This pass converts the GENERIC functions-as-trees
2 tree representation into the GIMPLE form.
3 Copyright (C) 2002-2020 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
= 8388608,
131 GOVD_DATA_SHARE_CLASS
= (GOVD_SHARED
| GOVD_PRIVATE
| GOVD_FIRSTPRIVATE
132 | GOVD_LASTPRIVATE
| GOVD_REDUCTION
| GOVD_LINEAR
139 ORT_WORKSHARE
= 0x00,
140 ORT_TASKGROUP
= 0x01,
144 ORT_COMBINED_PARALLEL
= ORT_PARALLEL
| 1,
147 ORT_UNTIED_TASK
= ORT_TASK
| 1,
148 ORT_TASKLOOP
= ORT_TASK
| 2,
149 ORT_UNTIED_TASKLOOP
= ORT_UNTIED_TASK
| 2,
152 ORT_COMBINED_TEAMS
= ORT_TEAMS
| 1,
153 ORT_HOST_TEAMS
= ORT_TEAMS
| 2,
154 ORT_COMBINED_HOST_TEAMS
= ORT_COMBINED_TEAMS
| 2,
157 ORT_TARGET_DATA
= 0x40,
159 /* Data region with offloading. */
161 ORT_COMBINED_TARGET
= ORT_TARGET
| 1,
162 ORT_IMPLICIT_TARGET
= ORT_TARGET
| 2,
164 /* OpenACC variants. */
165 ORT_ACC
= 0x100, /* A generic OpenACC region. */
166 ORT_ACC_DATA
= ORT_ACC
| ORT_TARGET_DATA
, /* Data construct. */
167 ORT_ACC_PARALLEL
= ORT_ACC
| ORT_TARGET
, /* Parallel construct */
168 ORT_ACC_KERNELS
= ORT_ACC
| ORT_TARGET
| 2, /* Kernels construct. */
169 ORT_ACC_SERIAL
= ORT_ACC
| ORT_TARGET
| 4, /* Serial construct. */
170 ORT_ACC_HOST_DATA
= ORT_ACC
| ORT_TARGET_DATA
| 2, /* Host data. */
172 /* Dummy OpenMP region, used to disable expansion of
173 DECL_VALUE_EXPRs in taskloop pre body. */
177 /* Gimplify hashtable helper. */
179 struct gimplify_hasher
: free_ptr_hash
<elt_t
>
181 static inline hashval_t
hash (const elt_t
*);
182 static inline bool equal (const elt_t
*, const elt_t
*);
187 struct gimplify_ctx
*prev_context
;
189 vec
<gbind
*> bind_expr_stack
;
191 gimple_seq conditional_cleanups
;
195 vec
<tree
> case_labels
;
196 hash_set
<tree
> *live_switch_vars
;
197 /* The formal temporary table. Should this be persistent? */
198 hash_table
<gimplify_hasher
> *temp_htab
;
201 unsigned into_ssa
: 1;
202 unsigned allow_rhs_cond_expr
: 1;
203 unsigned in_cleanup_point_expr
: 1;
204 unsigned keep_stack
: 1;
205 unsigned save_stack
: 1;
206 unsigned in_switch_expr
: 1;
209 enum gimplify_defaultmap_kind
217 struct gimplify_omp_ctx
219 struct gimplify_omp_ctx
*outer_context
;
220 splay_tree variables
;
221 hash_set
<tree
> *privatized_types
;
223 /* Iteration variables in an OMP_FOR. */
224 vec
<tree
> loop_iter_var
;
226 enum omp_clause_default_kind default_kind
;
227 enum omp_region_type region_type
;
231 bool target_firstprivatize_array_bases
;
233 bool order_concurrent
;
237 static struct gimplify_ctx
*gimplify_ctxp
;
238 static struct gimplify_omp_ctx
*gimplify_omp_ctxp
;
239 static bool in_omp_construct
;
241 /* Forward declaration. */
242 static enum gimplify_status
gimplify_compound_expr (tree
*, gimple_seq
*, bool);
243 static hash_map
<tree
, tree
> *oacc_declare_returns
;
244 static enum gimplify_status
gimplify_expr (tree
*, gimple_seq
*, gimple_seq
*,
245 bool (*) (tree
), fallback_t
, bool);
247 /* Shorter alias name for the above function for use in gimplify.c
251 gimplify_seq_add_stmt (gimple_seq
*seq_p
, gimple
*gs
)
253 gimple_seq_add_stmt_without_update (seq_p
, gs
);
256 /* Append sequence SRC to the end of sequence *DST_P. If *DST_P is
257 NULL, a new sequence is allocated. This function is
258 similar to gimple_seq_add_seq, but does not scan the operands.
259 During gimplification, we need to manipulate statement sequences
260 before the def/use vectors have been constructed. */
263 gimplify_seq_add_seq (gimple_seq
*dst_p
, gimple_seq src
)
265 gimple_stmt_iterator si
;
270 si
= gsi_last (*dst_p
);
271 gsi_insert_seq_after_without_update (&si
, src
, GSI_NEW_STMT
);
275 /* Pointer to a list of allocated gimplify_ctx structs to be used for pushing
276 and popping gimplify contexts. */
278 static struct gimplify_ctx
*ctx_pool
= NULL
;
280 /* Return a gimplify context struct from the pool. */
282 static inline struct gimplify_ctx
*
285 struct gimplify_ctx
* c
= ctx_pool
;
288 ctx_pool
= c
->prev_context
;
290 c
= XNEW (struct gimplify_ctx
);
292 memset (c
, '\0', sizeof (*c
));
296 /* Put gimplify context C back into the pool. */
299 ctx_free (struct gimplify_ctx
*c
)
301 c
->prev_context
= ctx_pool
;
305 /* Free allocated ctx stack memory. */
308 free_gimplify_stack (void)
310 struct gimplify_ctx
*c
;
312 while ((c
= ctx_pool
))
314 ctx_pool
= c
->prev_context
;
320 /* Set up a context for the gimplifier. */
323 push_gimplify_context (bool in_ssa
, bool rhs_cond_ok
)
325 struct gimplify_ctx
*c
= ctx_alloc ();
327 c
->prev_context
= gimplify_ctxp
;
329 gimplify_ctxp
->into_ssa
= in_ssa
;
330 gimplify_ctxp
->allow_rhs_cond_expr
= rhs_cond_ok
;
333 /* Tear down a context for the gimplifier. If BODY is non-null, then
334 put the temporaries into the outer BIND_EXPR. Otherwise, put them
337 BODY is not a sequence, but the first tuple in a sequence. */
340 pop_gimplify_context (gimple
*body
)
342 struct gimplify_ctx
*c
= gimplify_ctxp
;
345 && (!c
->bind_expr_stack
.exists ()
346 || c
->bind_expr_stack
.is_empty ()));
347 c
->bind_expr_stack
.release ();
348 gimplify_ctxp
= c
->prev_context
;
351 declare_vars (c
->temps
, body
, false);
353 record_vars (c
->temps
);
360 /* Push a GIMPLE_BIND tuple onto the stack of bindings. */
363 gimple_push_bind_expr (gbind
*bind_stmt
)
365 gimplify_ctxp
->bind_expr_stack
.reserve (8);
366 gimplify_ctxp
->bind_expr_stack
.safe_push (bind_stmt
);
369 /* Pop the first element off the stack of bindings. */
372 gimple_pop_bind_expr (void)
374 gimplify_ctxp
->bind_expr_stack
.pop ();
377 /* Return the first element of the stack of bindings. */
380 gimple_current_bind_expr (void)
382 return gimplify_ctxp
->bind_expr_stack
.last ();
385 /* Return the stack of bindings created during gimplification. */
388 gimple_bind_expr_stack (void)
390 return gimplify_ctxp
->bind_expr_stack
;
393 /* Return true iff there is a COND_EXPR between us and the innermost
394 CLEANUP_POINT_EXPR. This info is used by gimple_push_cleanup. */
397 gimple_conditional_context (void)
399 return gimplify_ctxp
->conditions
> 0;
402 /* Note that we've entered a COND_EXPR. */
405 gimple_push_condition (void)
407 #ifdef ENABLE_GIMPLE_CHECKING
408 if (gimplify_ctxp
->conditions
== 0)
409 gcc_assert (gimple_seq_empty_p (gimplify_ctxp
->conditional_cleanups
));
411 ++(gimplify_ctxp
->conditions
);
414 /* Note that we've left a COND_EXPR. If we're back at unconditional scope
415 now, add any conditional cleanups we've seen to the prequeue. */
418 gimple_pop_condition (gimple_seq
*pre_p
)
420 int conds
= --(gimplify_ctxp
->conditions
);
422 gcc_assert (conds
>= 0);
425 gimplify_seq_add_seq (pre_p
, gimplify_ctxp
->conditional_cleanups
);
426 gimplify_ctxp
->conditional_cleanups
= NULL
;
430 /* A stable comparison routine for use with splay trees and DECLs. */
433 splay_tree_compare_decl_uid (splay_tree_key xa
, splay_tree_key xb
)
438 return DECL_UID (a
) - DECL_UID (b
);
441 /* Create a new omp construct that deals with variable remapping. */
443 static struct gimplify_omp_ctx
*
444 new_omp_context (enum omp_region_type region_type
)
446 struct gimplify_omp_ctx
*c
;
448 c
= XCNEW (struct gimplify_omp_ctx
);
449 c
->outer_context
= gimplify_omp_ctxp
;
450 c
->variables
= splay_tree_new (splay_tree_compare_decl_uid
, 0, 0);
451 c
->privatized_types
= new hash_set
<tree
>;
452 c
->location
= input_location
;
453 c
->region_type
= region_type
;
454 if ((region_type
& ORT_TASK
) == 0)
455 c
->default_kind
= OMP_CLAUSE_DEFAULT_SHARED
;
457 c
->default_kind
= OMP_CLAUSE_DEFAULT_UNSPECIFIED
;
458 c
->defaultmap
[GDMK_SCALAR
] = GOVD_MAP
;
459 c
->defaultmap
[GDMK_AGGREGATE
] = GOVD_MAP
;
460 c
->defaultmap
[GDMK_ALLOCATABLE
] = GOVD_MAP
;
461 c
->defaultmap
[GDMK_POINTER
] = GOVD_MAP
;
466 /* Destroy an omp construct that deals with variable remapping. */
469 delete_omp_context (struct gimplify_omp_ctx
*c
)
471 splay_tree_delete (c
->variables
);
472 delete c
->privatized_types
;
473 c
->loop_iter_var
.release ();
477 static void omp_add_variable (struct gimplify_omp_ctx
*, tree
, unsigned int);
478 static bool omp_notice_variable (struct gimplify_omp_ctx
*, tree
, bool);
480 /* Both gimplify the statement T and append it to *SEQ_P. This function
481 behaves exactly as gimplify_stmt, but you don't have to pass T as a
485 gimplify_and_add (tree t
, gimple_seq
*seq_p
)
487 gimplify_stmt (&t
, seq_p
);
490 /* Gimplify statement T into sequence *SEQ_P, and return the first
491 tuple in the sequence of generated tuples for this statement.
492 Return NULL if gimplifying T produced no tuples. */
495 gimplify_and_return_first (tree t
, gimple_seq
*seq_p
)
497 gimple_stmt_iterator last
= gsi_last (*seq_p
);
499 gimplify_and_add (t
, seq_p
);
501 if (!gsi_end_p (last
))
504 return gsi_stmt (last
);
507 return gimple_seq_first_stmt (*seq_p
);
510 /* Returns true iff T is a valid RHS for an assignment to an un-renamed
511 LHS, or for a call argument. */
514 is_gimple_mem_rhs (tree t
)
516 /* If we're dealing with a renamable type, either source or dest must be
517 a renamed variable. */
518 if (is_gimple_reg_type (TREE_TYPE (t
)))
519 return is_gimple_val (t
);
521 return is_gimple_val (t
) || is_gimple_lvalue (t
);
524 /* Return true if T is a CALL_EXPR or an expression that can be
525 assigned to a temporary. Note that this predicate should only be
526 used during gimplification. See the rationale for this in
527 gimplify_modify_expr. */
530 is_gimple_reg_rhs_or_call (tree t
)
532 return (get_gimple_rhs_class (TREE_CODE (t
)) != GIMPLE_INVALID_RHS
533 || TREE_CODE (t
) == CALL_EXPR
);
536 /* Return true if T is a valid memory RHS or a CALL_EXPR. Note that
537 this predicate should only be used during gimplification. See the
538 rationale for this in gimplify_modify_expr. */
541 is_gimple_mem_rhs_or_call (tree t
)
543 /* If we're dealing with a renamable type, either source or dest must be
544 a renamed variable. */
545 if (is_gimple_reg_type (TREE_TYPE (t
)))
546 return is_gimple_val (t
);
548 return (is_gimple_val (t
)
549 || is_gimple_lvalue (t
)
550 || TREE_CLOBBER_P (t
)
551 || TREE_CODE (t
) == CALL_EXPR
);
554 /* Create a temporary with a name derived from VAL. Subroutine of
555 lookup_tmp_var; nobody else should call this function. */
558 create_tmp_from_val (tree val
)
560 /* Drop all qualifiers and address-space information from the value type. */
561 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (val
));
562 tree var
= create_tmp_var (type
, get_name (val
));
566 /* Create a temporary to hold the value of VAL. If IS_FORMAL, try to reuse
567 an existing expression temporary. */
570 lookup_tmp_var (tree val
, bool is_formal
)
574 /* If not optimizing, never really reuse a temporary. local-alloc
575 won't allocate any variable that is used in more than one basic
576 block, which means it will go into memory, causing much extra
577 work in reload and final and poorer code generation, outweighing
578 the extra memory allocation here. */
579 if (!optimize
|| !is_formal
|| TREE_SIDE_EFFECTS (val
))
580 ret
= create_tmp_from_val (val
);
587 if (!gimplify_ctxp
->temp_htab
)
588 gimplify_ctxp
->temp_htab
= new hash_table
<gimplify_hasher
> (1000);
589 slot
= gimplify_ctxp
->temp_htab
->find_slot (&elt
, INSERT
);
592 elt_p
= XNEW (elt_t
);
594 elt_p
->temp
= ret
= create_tmp_from_val (val
);
607 /* Helper for get_formal_tmp_var and get_initialized_tmp_var. */
610 internal_get_tmp_var (tree val
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
611 bool is_formal
, bool allow_ssa
)
615 /* Notice that we explicitly allow VAL to be a CALL_EXPR so that we
616 can create an INIT_EXPR and convert it into a GIMPLE_CALL below. */
617 gimplify_expr (&val
, pre_p
, post_p
, is_gimple_reg_rhs_or_call
,
621 && gimplify_ctxp
->into_ssa
622 && is_gimple_reg_type (TREE_TYPE (val
)))
624 t
= make_ssa_name (TYPE_MAIN_VARIANT (TREE_TYPE (val
)));
625 if (! gimple_in_ssa_p (cfun
))
627 const char *name
= get_name (val
);
629 SET_SSA_NAME_VAR_OR_IDENTIFIER (t
, create_tmp_var_name (name
));
633 t
= lookup_tmp_var (val
, is_formal
);
635 mod
= build2 (INIT_EXPR
, TREE_TYPE (t
), t
, unshare_expr (val
));
637 SET_EXPR_LOCATION (mod
, EXPR_LOC_OR_LOC (val
, input_location
));
639 /* gimplify_modify_expr might want to reduce this further. */
640 gimplify_and_add (mod
, pre_p
);
646 /* Return a formal temporary variable initialized with VAL. PRE_P is as
647 in gimplify_expr. Only use this function if:
649 1) The value of the unfactored expression represented by VAL will not
650 change between the initialization and use of the temporary, and
651 2) The temporary will not be otherwise modified.
653 For instance, #1 means that this is inappropriate for SAVE_EXPR temps,
654 and #2 means it is inappropriate for && temps.
656 For other cases, use get_initialized_tmp_var instead. */
659 get_formal_tmp_var (tree val
, gimple_seq
*pre_p
)
661 return internal_get_tmp_var (val
, pre_p
, NULL
, true, true);
664 /* Return a temporary variable initialized with VAL. PRE_P and POST_P
665 are as in gimplify_expr. */
668 get_initialized_tmp_var (tree val
, gimple_seq
*pre_p
,
669 gimple_seq
*post_p
/* = NULL */,
670 bool allow_ssa
/* = true */)
672 return internal_get_tmp_var (val
, pre_p
, post_p
, false, allow_ssa
);
675 /* Declare all the variables in VARS in SCOPE. If DEBUG_INFO is true,
676 generate debug info for them; otherwise don't. */
679 declare_vars (tree vars
, gimple
*gs
, bool debug_info
)
686 gbind
*scope
= as_a
<gbind
*> (gs
);
688 temps
= nreverse (last
);
690 block
= gimple_bind_block (scope
);
691 gcc_assert (!block
|| TREE_CODE (block
) == BLOCK
);
692 if (!block
|| !debug_info
)
694 DECL_CHAIN (last
) = gimple_bind_vars (scope
);
695 gimple_bind_set_vars (scope
, temps
);
699 /* We need to attach the nodes both to the BIND_EXPR and to its
700 associated BLOCK for debugging purposes. The key point here
701 is that the BLOCK_VARS of the BIND_EXPR_BLOCK of a BIND_EXPR
702 is a subchain of the BIND_EXPR_VARS of the BIND_EXPR. */
703 if (BLOCK_VARS (block
))
704 BLOCK_VARS (block
) = chainon (BLOCK_VARS (block
), temps
);
707 gimple_bind_set_vars (scope
,
708 chainon (gimple_bind_vars (scope
), temps
));
709 BLOCK_VARS (block
) = temps
;
715 /* For VAR a VAR_DECL of variable size, try to find a constant upper bound
716 for the size and adjust DECL_SIZE/DECL_SIZE_UNIT accordingly. Abort if
717 no such upper bound can be obtained. */
720 force_constant_size (tree var
)
722 /* The only attempt we make is by querying the maximum size of objects
723 of the variable's type. */
725 HOST_WIDE_INT max_size
;
727 gcc_assert (VAR_P (var
));
729 max_size
= max_int_size_in_bytes (TREE_TYPE (var
));
731 gcc_assert (max_size
>= 0);
734 = build_int_cst (TREE_TYPE (DECL_SIZE_UNIT (var
)), max_size
);
736 = build_int_cst (TREE_TYPE (DECL_SIZE (var
)), max_size
* BITS_PER_UNIT
);
739 /* Push the temporary variable TMP into the current binding. */
742 gimple_add_tmp_var_fn (struct function
*fn
, tree tmp
)
744 gcc_assert (!DECL_CHAIN (tmp
) && !DECL_SEEN_IN_BIND_EXPR_P (tmp
));
746 /* Later processing assumes that the object size is constant, which might
747 not be true at this point. Force the use of a constant upper bound in
749 if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp
)))
750 force_constant_size (tmp
);
752 DECL_CONTEXT (tmp
) = fn
->decl
;
753 DECL_SEEN_IN_BIND_EXPR_P (tmp
) = 1;
755 record_vars_into (tmp
, fn
->decl
);
758 /* Push the temporary variable TMP into the current binding. */
761 gimple_add_tmp_var (tree tmp
)
763 gcc_assert (!DECL_CHAIN (tmp
) && !DECL_SEEN_IN_BIND_EXPR_P (tmp
));
765 /* Later processing assumes that the object size is constant, which might
766 not be true at this point. Force the use of a constant upper bound in
768 if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp
)))
769 force_constant_size (tmp
);
771 DECL_CONTEXT (tmp
) = current_function_decl
;
772 DECL_SEEN_IN_BIND_EXPR_P (tmp
) = 1;
776 DECL_CHAIN (tmp
) = gimplify_ctxp
->temps
;
777 gimplify_ctxp
->temps
= tmp
;
779 /* Mark temporaries local within the nearest enclosing parallel. */
780 if (gimplify_omp_ctxp
)
782 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
783 int flag
= GOVD_LOCAL
;
785 && (ctx
->region_type
== ORT_WORKSHARE
786 || ctx
->region_type
== ORT_TASKGROUP
787 || ctx
->region_type
== ORT_SIMD
788 || ctx
->region_type
== ORT_ACC
))
790 if (ctx
->region_type
== ORT_SIMD
791 && TREE_ADDRESSABLE (tmp
)
792 && !TREE_STATIC (tmp
))
794 if (TREE_CODE (DECL_SIZE_UNIT (tmp
)) != INTEGER_CST
)
795 ctx
->add_safelen1
= true;
800 ctx
= ctx
->outer_context
;
803 omp_add_variable (ctx
, tmp
, flag
| GOVD_SEEN
);
812 /* This case is for nested functions. We need to expose the locals
814 body_seq
= gimple_body (current_function_decl
);
815 declare_vars (tmp
, gimple_seq_first_stmt (body_seq
), false);
821 /* This page contains routines to unshare tree nodes, i.e. to duplicate tree
822 nodes that are referenced more than once in GENERIC functions. This is
823 necessary because gimplification (translation into GIMPLE) is performed
824 by modifying tree nodes in-place, so gimplication of a shared node in a
825 first context could generate an invalid GIMPLE form in a second context.
827 This is achieved with a simple mark/copy/unmark algorithm that walks the
828 GENERIC representation top-down, marks nodes with TREE_VISITED the first
829 time it encounters them, duplicates them if they already have TREE_VISITED
830 set, and finally removes the TREE_VISITED marks it has set.
832 The algorithm works only at the function level, i.e. it generates a GENERIC
833 representation of a function with no nodes shared within the function when
834 passed a GENERIC function (except for nodes that are allowed to be shared).
836 At the global level, it is also necessary to unshare tree nodes that are
837 referenced in more than one function, for the same aforementioned reason.
838 This requires some cooperation from the front-end. There are 2 strategies:
840 1. Manual unsharing. The front-end needs to call unshare_expr on every
841 expression that might end up being shared across functions.
843 2. Deep unsharing. This is an extension of regular unsharing. Instead
844 of calling unshare_expr on expressions that might be shared across
845 functions, the front-end pre-marks them with TREE_VISITED. This will
846 ensure that they are unshared on the first reference within functions
847 when the regular unsharing algorithm runs. The counterpart is that
848 this algorithm must look deeper than for manual unsharing, which is
849 specified by LANG_HOOKS_DEEP_UNSHARING.
851 If there are only few specific cases of node sharing across functions, it is
852 probably easier for a front-end to unshare the expressions manually. On the
853 contrary, if the expressions generated at the global level are as widespread
854 as expressions generated within functions, deep unsharing is very likely the
857 /* Similar to copy_tree_r but do not copy SAVE_EXPR or TARGET_EXPR nodes.
858 These nodes model computations that must be done once. If we were to
859 unshare something like SAVE_EXPR(i++), the gimplification process would
860 create wrong code. However, if DATA is non-null, it must hold a pointer
861 set that is used to unshare the subtrees of these nodes. */
864 mostly_copy_tree_r (tree
*tp
, int *walk_subtrees
, void *data
)
867 enum tree_code code
= TREE_CODE (t
);
869 /* Do not copy SAVE_EXPR, TARGET_EXPR or BIND_EXPR nodes themselves, but
870 copy their subtrees if we can make sure to do it only once. */
871 if (code
== SAVE_EXPR
|| code
== TARGET_EXPR
|| code
== BIND_EXPR
)
873 if (data
&& !((hash_set
<tree
> *)data
)->add (t
))
879 /* Stop at types, decls, constants like copy_tree_r. */
880 else if (TREE_CODE_CLASS (code
) == tcc_type
881 || TREE_CODE_CLASS (code
) == tcc_declaration
882 || TREE_CODE_CLASS (code
) == tcc_constant
)
885 /* Cope with the statement expression extension. */
886 else if (code
== STATEMENT_LIST
)
889 /* Leave the bulk of the work to copy_tree_r itself. */
891 copy_tree_r (tp
, walk_subtrees
, NULL
);
896 /* Callback for walk_tree to unshare most of the shared trees rooted at *TP.
897 If *TP has been visited already, then *TP is deeply copied by calling
898 mostly_copy_tree_r. DATA is passed to mostly_copy_tree_r unmodified. */
901 copy_if_shared_r (tree
*tp
, int *walk_subtrees
, void *data
)
904 enum tree_code code
= TREE_CODE (t
);
906 /* Skip types, decls, and constants. But we do want to look at their
907 types and the bounds of types. Mark them as visited so we properly
908 unmark their subtrees on the unmark pass. If we've already seen them,
909 don't look down further. */
910 if (TREE_CODE_CLASS (code
) == tcc_type
911 || TREE_CODE_CLASS (code
) == tcc_declaration
912 || TREE_CODE_CLASS (code
) == tcc_constant
)
914 if (TREE_VISITED (t
))
917 TREE_VISITED (t
) = 1;
920 /* If this node has been visited already, unshare it and don't look
922 else if (TREE_VISITED (t
))
924 walk_tree (tp
, mostly_copy_tree_r
, data
, NULL
);
928 /* Otherwise, mark the node as visited and keep looking. */
930 TREE_VISITED (t
) = 1;
935 /* Unshare most of the shared trees rooted at *TP. DATA is passed to the
936 copy_if_shared_r callback unmodified. */
939 copy_if_shared (tree
*tp
, void *data
)
941 walk_tree (tp
, copy_if_shared_r
, data
, NULL
);
944 /* Unshare all the trees in the body of FNDECL, as well as in the bodies of
945 any nested functions. */
948 unshare_body (tree fndecl
)
950 struct cgraph_node
*cgn
= cgraph_node::get (fndecl
);
951 /* If the language requires deep unsharing, we need a pointer set to make
952 sure we don't repeatedly unshare subtrees of unshareable nodes. */
953 hash_set
<tree
> *visited
954 = lang_hooks
.deep_unsharing
? new hash_set
<tree
> : NULL
;
956 copy_if_shared (&DECL_SAVED_TREE (fndecl
), visited
);
957 copy_if_shared (&DECL_SIZE (DECL_RESULT (fndecl
)), visited
);
958 copy_if_shared (&DECL_SIZE_UNIT (DECL_RESULT (fndecl
)), visited
);
963 for (cgn
= first_nested_function (cgn
); cgn
;
964 cgn
= next_nested_function (cgn
))
965 unshare_body (cgn
->decl
);
968 /* Callback for walk_tree to unmark the visited trees rooted at *TP.
969 Subtrees are walked until the first unvisited node is encountered. */
972 unmark_visited_r (tree
*tp
, int *walk_subtrees
, void *data ATTRIBUTE_UNUSED
)
976 /* If this node has been visited, unmark it and keep looking. */
977 if (TREE_VISITED (t
))
978 TREE_VISITED (t
) = 0;
980 /* Otherwise, don't look any deeper. */
987 /* Unmark the visited trees rooted at *TP. */
990 unmark_visited (tree
*tp
)
992 walk_tree (tp
, unmark_visited_r
, NULL
, NULL
);
995 /* Likewise, but mark all trees as not visited. */
998 unvisit_body (tree fndecl
)
1000 struct cgraph_node
*cgn
= cgraph_node::get (fndecl
);
1002 unmark_visited (&DECL_SAVED_TREE (fndecl
));
1003 unmark_visited (&DECL_SIZE (DECL_RESULT (fndecl
)));
1004 unmark_visited (&DECL_SIZE_UNIT (DECL_RESULT (fndecl
)));
1007 for (cgn
= first_nested_function (cgn
);
1008 cgn
; cgn
= next_nested_function (cgn
))
1009 unvisit_body (cgn
->decl
);
1012 /* Unconditionally make an unshared copy of EXPR. This is used when using
1013 stored expressions which span multiple functions, such as BINFO_VTABLE,
1014 as the normal unsharing process can't tell that they're shared. */
1017 unshare_expr (tree expr
)
1019 walk_tree (&expr
, mostly_copy_tree_r
, NULL
, NULL
);
1023 /* Worker for unshare_expr_without_location. */
1026 prune_expr_location (tree
*tp
, int *walk_subtrees
, void *)
1029 SET_EXPR_LOCATION (*tp
, UNKNOWN_LOCATION
);
1035 /* Similar to unshare_expr but also prune all expression locations
1039 unshare_expr_without_location (tree expr
)
1041 walk_tree (&expr
, mostly_copy_tree_r
, NULL
, NULL
);
1043 walk_tree (&expr
, prune_expr_location
, NULL
, NULL
);
1047 /* Return the EXPR_LOCATION of EXPR, if it (maybe recursively) has
1048 one, OR_ELSE otherwise. The location of a STATEMENT_LISTs
1049 comprising at least one DEBUG_BEGIN_STMT followed by exactly one
1050 EXPR is the location of the EXPR. */
1053 rexpr_location (tree expr
, location_t or_else
= UNKNOWN_LOCATION
)
1058 if (EXPR_HAS_LOCATION (expr
))
1059 return EXPR_LOCATION (expr
);
1061 if (TREE_CODE (expr
) != STATEMENT_LIST
)
1064 tree_stmt_iterator i
= tsi_start (expr
);
1067 while (!tsi_end_p (i
) && TREE_CODE (tsi_stmt (i
)) == DEBUG_BEGIN_STMT
)
1073 if (!found
|| !tsi_one_before_end_p (i
))
1076 return rexpr_location (tsi_stmt (i
), or_else
);
1079 /* Return TRUE iff EXPR (maybe recursively) has a location; see
1080 rexpr_location for the potential recursion. */
1083 rexpr_has_location (tree expr
)
1085 return rexpr_location (expr
) != UNKNOWN_LOCATION
;
1089 /* WRAPPER is a code such as BIND_EXPR or CLEANUP_POINT_EXPR which can both
1090 contain statements and have a value. Assign its value to a temporary
1091 and give it void_type_node. Return the temporary, or NULL_TREE if
1092 WRAPPER was already void. */
1095 voidify_wrapper_expr (tree wrapper
, tree temp
)
1097 tree type
= TREE_TYPE (wrapper
);
1098 if (type
&& !VOID_TYPE_P (type
))
1102 /* Set p to point to the body of the wrapper. Loop until we find
1103 something that isn't a wrapper. */
1104 for (p
= &wrapper
; p
&& *p
; )
1106 switch (TREE_CODE (*p
))
1109 TREE_SIDE_EFFECTS (*p
) = 1;
1110 TREE_TYPE (*p
) = void_type_node
;
1111 /* For a BIND_EXPR, the body is operand 1. */
1112 p
= &BIND_EXPR_BODY (*p
);
1115 case CLEANUP_POINT_EXPR
:
1116 case TRY_FINALLY_EXPR
:
1117 case TRY_CATCH_EXPR
:
1118 TREE_SIDE_EFFECTS (*p
) = 1;
1119 TREE_TYPE (*p
) = void_type_node
;
1120 p
= &TREE_OPERAND (*p
, 0);
1123 case STATEMENT_LIST
:
1125 tree_stmt_iterator i
= tsi_last (*p
);
1126 TREE_SIDE_EFFECTS (*p
) = 1;
1127 TREE_TYPE (*p
) = void_type_node
;
1128 p
= tsi_end_p (i
) ? NULL
: tsi_stmt_ptr (i
);
1133 /* Advance to the last statement. Set all container types to
1135 for (; TREE_CODE (*p
) == COMPOUND_EXPR
; p
= &TREE_OPERAND (*p
, 1))
1137 TREE_SIDE_EFFECTS (*p
) = 1;
1138 TREE_TYPE (*p
) = void_type_node
;
1142 case TRANSACTION_EXPR
:
1143 TREE_SIDE_EFFECTS (*p
) = 1;
1144 TREE_TYPE (*p
) = void_type_node
;
1145 p
= &TRANSACTION_EXPR_BODY (*p
);
1149 /* Assume that any tree upon which voidify_wrapper_expr is
1150 directly called is a wrapper, and that its body is op0. */
1153 TREE_SIDE_EFFECTS (*p
) = 1;
1154 TREE_TYPE (*p
) = void_type_node
;
1155 p
= &TREE_OPERAND (*p
, 0);
1163 if (p
== NULL
|| IS_EMPTY_STMT (*p
))
1167 /* The wrapper is on the RHS of an assignment that we're pushing
1169 gcc_assert (TREE_CODE (temp
) == INIT_EXPR
1170 || TREE_CODE (temp
) == MODIFY_EXPR
);
1171 TREE_OPERAND (temp
, 1) = *p
;
1176 temp
= create_tmp_var (type
, "retval");
1177 *p
= build2 (INIT_EXPR
, type
, temp
, *p
);
1186 /* Prepare calls to builtins to SAVE and RESTORE the stack as well as
1187 a temporary through which they communicate. */
1190 build_stack_save_restore (gcall
**save
, gcall
**restore
)
1194 *save
= gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_SAVE
), 0);
1195 tmp_var
= create_tmp_var (ptr_type_node
, "saved_stack");
1196 gimple_call_set_lhs (*save
, tmp_var
);
1199 = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_RESTORE
),
1203 /* Generate IFN_ASAN_MARK call that poisons shadow of a for DECL variable. */
1206 build_asan_poison_call_expr (tree decl
)
1208 /* Do not poison variables that have size equal to zero. */
1209 tree unit_size
= DECL_SIZE_UNIT (decl
);
1210 if (zerop (unit_size
))
1213 tree base
= build_fold_addr_expr (decl
);
1215 return build_call_expr_internal_loc (UNKNOWN_LOCATION
, IFN_ASAN_MARK
,
1217 build_int_cst (integer_type_node
,
1222 /* Generate IFN_ASAN_MARK call that would poison or unpoison, depending
1223 on POISON flag, shadow memory of a DECL variable. The call will be
1224 put on location identified by IT iterator, where BEFORE flag drives
1225 position where the stmt will be put. */
1228 asan_poison_variable (tree decl
, bool poison
, gimple_stmt_iterator
*it
,
1231 tree unit_size
= DECL_SIZE_UNIT (decl
);
1232 tree base
= build_fold_addr_expr (decl
);
1234 /* Do not poison variables that have size equal to zero. */
1235 if (zerop (unit_size
))
1238 /* It's necessary to have all stack variables aligned to ASAN granularity
1240 if (DECL_ALIGN_UNIT (decl
) <= ASAN_SHADOW_GRANULARITY
)
1241 SET_DECL_ALIGN (decl
, BITS_PER_UNIT
* ASAN_SHADOW_GRANULARITY
);
1243 HOST_WIDE_INT flags
= poison
? ASAN_MARK_POISON
: ASAN_MARK_UNPOISON
;
1246 = gimple_build_call_internal (IFN_ASAN_MARK
, 3,
1247 build_int_cst (integer_type_node
, flags
),
1251 gsi_insert_before (it
, g
, GSI_NEW_STMT
);
1253 gsi_insert_after (it
, g
, GSI_NEW_STMT
);
1256 /* Generate IFN_ASAN_MARK internal call that depending on POISON flag
1257 either poisons or unpoisons a DECL. Created statement is appended
1258 to SEQ_P gimple sequence. */
1261 asan_poison_variable (tree decl
, bool poison
, gimple_seq
*seq_p
)
1263 gimple_stmt_iterator it
= gsi_last (*seq_p
);
1264 bool before
= false;
1269 asan_poison_variable (decl
, poison
, &it
, before
);
1272 /* Sort pair of VAR_DECLs A and B by DECL_UID. */
1275 sort_by_decl_uid (const void *a
, const void *b
)
1277 const tree
*t1
= (const tree
*)a
;
1278 const tree
*t2
= (const tree
*)b
;
1280 int uid1
= DECL_UID (*t1
);
1281 int uid2
= DECL_UID (*t2
);
1285 else if (uid1
> uid2
)
1291 /* Generate IFN_ASAN_MARK internal call for all VARIABLES
1292 depending on POISON flag. Created statement is appended
1293 to SEQ_P gimple sequence. */
1296 asan_poison_variables (hash_set
<tree
> *variables
, bool poison
, gimple_seq
*seq_p
)
1298 unsigned c
= variables
->elements ();
1302 auto_vec
<tree
> sorted_variables (c
);
1304 for (hash_set
<tree
>::iterator it
= variables
->begin ();
1305 it
!= variables
->end (); ++it
)
1306 sorted_variables
.safe_push (*it
);
1308 sorted_variables
.qsort (sort_by_decl_uid
);
1312 FOR_EACH_VEC_ELT (sorted_variables
, i
, var
)
1314 asan_poison_variable (var
, poison
, seq_p
);
1316 /* Add use_after_scope_memory attribute for the variable in order
1317 to prevent re-written into SSA. */
1318 if (!lookup_attribute (ASAN_USE_AFTER_SCOPE_ATTRIBUTE
,
1319 DECL_ATTRIBUTES (var
)))
1320 DECL_ATTRIBUTES (var
)
1321 = tree_cons (get_identifier (ASAN_USE_AFTER_SCOPE_ATTRIBUTE
),
1323 DECL_ATTRIBUTES (var
));
1327 /* Gimplify a BIND_EXPR. Just voidify and recurse. */
1329 static enum gimplify_status
1330 gimplify_bind_expr (tree
*expr_p
, gimple_seq
*pre_p
)
1332 tree bind_expr
= *expr_p
;
1333 bool old_keep_stack
= gimplify_ctxp
->keep_stack
;
1334 bool old_save_stack
= gimplify_ctxp
->save_stack
;
1337 gimple_seq body
, cleanup
;
1339 location_t start_locus
= 0, end_locus
= 0;
1340 tree ret_clauses
= NULL
;
1342 tree temp
= voidify_wrapper_expr (bind_expr
, NULL
);
1344 /* Mark variables seen in this bind expr. */
1345 for (t
= BIND_EXPR_VARS (bind_expr
); t
; t
= DECL_CHAIN (t
))
1349 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
1351 /* Mark variable as local. */
1352 if (ctx
&& ctx
->region_type
!= ORT_NONE
&& !DECL_EXTERNAL (t
))
1354 if (! DECL_SEEN_IN_BIND_EXPR_P (t
)
1355 || splay_tree_lookup (ctx
->variables
,
1356 (splay_tree_key
) t
) == NULL
)
1358 int flag
= GOVD_LOCAL
;
1359 if (ctx
->region_type
== ORT_SIMD
1360 && TREE_ADDRESSABLE (t
)
1361 && !TREE_STATIC (t
))
1363 if (TREE_CODE (DECL_SIZE_UNIT (t
)) != INTEGER_CST
)
1364 ctx
->add_safelen1
= true;
1366 flag
= GOVD_PRIVATE
;
1368 omp_add_variable (ctx
, t
, flag
| GOVD_SEEN
);
1370 /* Static locals inside of target construct or offloaded
1371 routines need to be "omp declare target". */
1372 if (TREE_STATIC (t
))
1373 for (; ctx
; ctx
= ctx
->outer_context
)
1374 if ((ctx
->region_type
& ORT_TARGET
) != 0)
1376 if (!lookup_attribute ("omp declare target",
1377 DECL_ATTRIBUTES (t
)))
1379 tree id
= get_identifier ("omp declare target");
1381 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
1382 varpool_node
*node
= varpool_node::get (t
);
1385 node
->offloadable
= 1;
1386 if (ENABLE_OFFLOADING
&& !DECL_EXTERNAL (t
))
1388 g
->have_offload
= true;
1390 vec_safe_push (offload_vars
, t
);
1398 DECL_SEEN_IN_BIND_EXPR_P (t
) = 1;
1400 if (DECL_HARD_REGISTER (t
) && !is_global_var (t
) && cfun
)
1401 cfun
->has_local_explicit_reg_vars
= true;
1405 bind_stmt
= gimple_build_bind (BIND_EXPR_VARS (bind_expr
), NULL
,
1406 BIND_EXPR_BLOCK (bind_expr
));
1407 gimple_push_bind_expr (bind_stmt
);
1409 gimplify_ctxp
->keep_stack
= false;
1410 gimplify_ctxp
->save_stack
= false;
1412 /* Gimplify the body into the GIMPLE_BIND tuple's body. */
1414 gimplify_stmt (&BIND_EXPR_BODY (bind_expr
), &body
);
1415 gimple_bind_set_body (bind_stmt
, body
);
1417 /* Source location wise, the cleanup code (stack_restore and clobbers)
1418 belongs to the end of the block, so propagate what we have. The
1419 stack_save operation belongs to the beginning of block, which we can
1420 infer from the bind_expr directly if the block has no explicit
1422 if (BIND_EXPR_BLOCK (bind_expr
))
1424 end_locus
= BLOCK_SOURCE_END_LOCATION (BIND_EXPR_BLOCK (bind_expr
));
1425 start_locus
= BLOCK_SOURCE_LOCATION (BIND_EXPR_BLOCK (bind_expr
));
1427 if (start_locus
== 0)
1428 start_locus
= EXPR_LOCATION (bind_expr
);
1433 /* If the code both contains VLAs and calls alloca, then we cannot reclaim
1434 the stack space allocated to the VLAs. */
1435 if (gimplify_ctxp
->save_stack
&& !gimplify_ctxp
->keep_stack
)
1437 gcall
*stack_restore
;
1439 /* Save stack on entry and restore it on exit. Add a try_finally
1440 block to achieve this. */
1441 build_stack_save_restore (&stack_save
, &stack_restore
);
1443 gimple_set_location (stack_save
, start_locus
);
1444 gimple_set_location (stack_restore
, end_locus
);
1446 gimplify_seq_add_stmt (&cleanup
, stack_restore
);
1449 /* Add clobbers for all variables that go out of scope. */
1450 for (t
= BIND_EXPR_VARS (bind_expr
); t
; t
= DECL_CHAIN (t
))
1453 && !is_global_var (t
)
1454 && DECL_CONTEXT (t
) == current_function_decl
)
1456 if (!DECL_HARD_REGISTER (t
)
1457 && !TREE_THIS_VOLATILE (t
)
1458 && !DECL_HAS_VALUE_EXPR_P (t
)
1459 /* Only care for variables that have to be in memory. Others
1460 will be rewritten into SSA names, hence moved to the
1462 && !is_gimple_reg (t
)
1463 && flag_stack_reuse
!= SR_NONE
)
1465 tree clobber
= build_clobber (TREE_TYPE (t
));
1466 gimple
*clobber_stmt
;
1467 clobber_stmt
= gimple_build_assign (t
, clobber
);
1468 gimple_set_location (clobber_stmt
, end_locus
);
1469 gimplify_seq_add_stmt (&cleanup
, clobber_stmt
);
1472 if (flag_openacc
&& oacc_declare_returns
!= NULL
)
1475 if (DECL_HAS_VALUE_EXPR_P (key
))
1477 key
= DECL_VALUE_EXPR (key
);
1478 if (TREE_CODE (key
) == INDIRECT_REF
)
1479 key
= TREE_OPERAND (key
, 0);
1481 tree
*c
= oacc_declare_returns
->get (key
);
1485 OMP_CLAUSE_CHAIN (*c
) = ret_clauses
;
1487 ret_clauses
= unshare_expr (*c
);
1489 oacc_declare_returns
->remove (key
);
1491 if (oacc_declare_returns
->is_empty ())
1493 delete oacc_declare_returns
;
1494 oacc_declare_returns
= NULL
;
1500 if (asan_poisoned_variables
!= NULL
1501 && asan_poisoned_variables
->contains (t
))
1503 asan_poisoned_variables
->remove (t
);
1504 asan_poison_variable (t
, true, &cleanup
);
1507 if (gimplify_ctxp
->live_switch_vars
!= NULL
1508 && gimplify_ctxp
->live_switch_vars
->contains (t
))
1509 gimplify_ctxp
->live_switch_vars
->remove (t
);
1515 gimple_stmt_iterator si
= gsi_start (cleanup
);
1517 stmt
= gimple_build_omp_target (NULL
, GF_OMP_TARGET_KIND_OACC_DECLARE
,
1519 gsi_insert_seq_before_without_update (&si
, stmt
, GSI_NEW_STMT
);
1525 gimple_seq new_body
;
1528 gs
= gimple_build_try (gimple_bind_body (bind_stmt
), cleanup
,
1529 GIMPLE_TRY_FINALLY
);
1532 gimplify_seq_add_stmt (&new_body
, stack_save
);
1533 gimplify_seq_add_stmt (&new_body
, gs
);
1534 gimple_bind_set_body (bind_stmt
, new_body
);
1537 /* keep_stack propagates all the way up to the outermost BIND_EXPR. */
1538 if (!gimplify_ctxp
->keep_stack
)
1539 gimplify_ctxp
->keep_stack
= old_keep_stack
;
1540 gimplify_ctxp
->save_stack
= old_save_stack
;
1542 gimple_pop_bind_expr ();
1544 gimplify_seq_add_stmt (pre_p
, bind_stmt
);
1552 *expr_p
= NULL_TREE
;
1556 /* Maybe add early return predict statement to PRE_P sequence. */
1559 maybe_add_early_return_predict_stmt (gimple_seq
*pre_p
)
1561 /* If we are not in a conditional context, add PREDICT statement. */
1562 if (gimple_conditional_context ())
1564 gimple
*predict
= gimple_build_predict (PRED_TREE_EARLY_RETURN
,
1566 gimplify_seq_add_stmt (pre_p
, predict
);
1570 /* Gimplify a RETURN_EXPR. If the expression to be returned is not a
1571 GIMPLE value, it is assigned to a new temporary and the statement is
1572 re-written to return the temporary.
1574 PRE_P points to the sequence where side effects that must happen before
1575 STMT should be stored. */
1577 static enum gimplify_status
1578 gimplify_return_expr (tree stmt
, gimple_seq
*pre_p
)
1581 tree ret_expr
= TREE_OPERAND (stmt
, 0);
1582 tree result_decl
, result
;
1584 if (ret_expr
== error_mark_node
)
1588 || TREE_CODE (ret_expr
) == RESULT_DECL
)
1590 maybe_add_early_return_predict_stmt (pre_p
);
1591 greturn
*ret
= gimple_build_return (ret_expr
);
1592 gimple_set_no_warning (ret
, TREE_NO_WARNING (stmt
));
1593 gimplify_seq_add_stmt (pre_p
, ret
);
1597 if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl
))))
1598 result_decl
= NULL_TREE
;
1599 else if (TREE_CODE (ret_expr
) == COMPOUND_EXPR
)
1601 /* Used in C++ for handling EH cleanup of the return value if a local
1602 cleanup throws. Assume the front-end knows what it's doing. */
1603 result_decl
= DECL_RESULT (current_function_decl
);
1604 /* But crash if we end up trying to modify ret_expr below. */
1605 ret_expr
= NULL_TREE
;
1609 result_decl
= TREE_OPERAND (ret_expr
, 0);
1611 /* See through a return by reference. */
1612 if (TREE_CODE (result_decl
) == INDIRECT_REF
)
1613 result_decl
= TREE_OPERAND (result_decl
, 0);
1615 gcc_assert ((TREE_CODE (ret_expr
) == MODIFY_EXPR
1616 || TREE_CODE (ret_expr
) == INIT_EXPR
)
1617 && TREE_CODE (result_decl
) == RESULT_DECL
);
1620 /* If aggregate_value_p is true, then we can return the bare RESULT_DECL.
1621 Recall that aggregate_value_p is FALSE for any aggregate type that is
1622 returned in registers. If we're returning values in registers, then
1623 we don't want to extend the lifetime of the RESULT_DECL, particularly
1624 across another call. In addition, for those aggregates for which
1625 hard_function_value generates a PARALLEL, we'll die during normal
1626 expansion of structure assignments; there's special code in expand_return
1627 to handle this case that does not exist in expand_expr. */
1630 else if (aggregate_value_p (result_decl
, TREE_TYPE (current_function_decl
)))
1632 if (!poly_int_tree_p (DECL_SIZE (result_decl
)))
1634 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (result_decl
)))
1635 gimplify_type_sizes (TREE_TYPE (result_decl
), pre_p
);
1636 /* Note that we don't use gimplify_vla_decl because the RESULT_DECL
1637 should be effectively allocated by the caller, i.e. all calls to
1638 this function must be subject to the Return Slot Optimization. */
1639 gimplify_one_sizepos (&DECL_SIZE (result_decl
), pre_p
);
1640 gimplify_one_sizepos (&DECL_SIZE_UNIT (result_decl
), pre_p
);
1642 result
= result_decl
;
1644 else if (gimplify_ctxp
->return_temp
)
1645 result
= gimplify_ctxp
->return_temp
;
1648 result
= create_tmp_reg (TREE_TYPE (result_decl
));
1650 /* ??? With complex control flow (usually involving abnormal edges),
1651 we can wind up warning about an uninitialized value for this. Due
1652 to how this variable is constructed and initialized, this is never
1653 true. Give up and never warn. */
1654 TREE_NO_WARNING (result
) = 1;
1656 gimplify_ctxp
->return_temp
= result
;
1659 /* Smash the lhs of the MODIFY_EXPR to the temporary we plan to use.
1660 Then gimplify the whole thing. */
1661 if (result
!= result_decl
)
1662 TREE_OPERAND (ret_expr
, 0) = result
;
1664 gimplify_and_add (TREE_OPERAND (stmt
, 0), pre_p
);
1666 maybe_add_early_return_predict_stmt (pre_p
);
1667 ret
= gimple_build_return (result
);
1668 gimple_set_no_warning (ret
, TREE_NO_WARNING (stmt
));
1669 gimplify_seq_add_stmt (pre_p
, ret
);
1674 /* Gimplify a variable-length array DECL. */
1677 gimplify_vla_decl (tree decl
, gimple_seq
*seq_p
)
1679 /* This is a variable-sized decl. Simplify its size and mark it
1680 for deferred expansion. */
1681 tree t
, addr
, ptr_type
;
1683 gimplify_one_sizepos (&DECL_SIZE (decl
), seq_p
);
1684 gimplify_one_sizepos (&DECL_SIZE_UNIT (decl
), seq_p
);
1686 /* Don't mess with a DECL_VALUE_EXPR set by the front-end. */
1687 if (DECL_HAS_VALUE_EXPR_P (decl
))
1690 /* All occurrences of this decl in final gimplified code will be
1691 replaced by indirection. Setting DECL_VALUE_EXPR does two
1692 things: First, it lets the rest of the gimplifier know what
1693 replacement to use. Second, it lets the debug info know
1694 where to find the value. */
1695 ptr_type
= build_pointer_type (TREE_TYPE (decl
));
1696 addr
= create_tmp_var (ptr_type
, get_name (decl
));
1697 DECL_IGNORED_P (addr
) = 0;
1698 t
= build_fold_indirect_ref (addr
);
1699 TREE_THIS_NOTRAP (t
) = 1;
1700 SET_DECL_VALUE_EXPR (decl
, t
);
1701 DECL_HAS_VALUE_EXPR_P (decl
) = 1;
1703 t
= build_alloca_call_expr (DECL_SIZE_UNIT (decl
), DECL_ALIGN (decl
),
1704 max_int_size_in_bytes (TREE_TYPE (decl
)));
1705 /* The call has been built for a variable-sized object. */
1706 CALL_ALLOCA_FOR_VAR_P (t
) = 1;
1707 t
= fold_convert (ptr_type
, t
);
1708 t
= build2 (MODIFY_EXPR
, TREE_TYPE (addr
), addr
, t
);
1710 gimplify_and_add (t
, seq_p
);
1712 /* Record the dynamic allocation associated with DECL if requested. */
1713 if (flag_callgraph_info
& CALLGRAPH_INFO_DYNAMIC_ALLOC
)
1714 record_dynamic_alloc (decl
);
1717 /* A helper function to be called via walk_tree. Mark all labels under *TP
1718 as being forced. To be called for DECL_INITIAL of static variables. */
1721 force_labels_r (tree
*tp
, int *walk_subtrees
, void *data ATTRIBUTE_UNUSED
)
1725 if (TREE_CODE (*tp
) == LABEL_DECL
)
1727 FORCED_LABEL (*tp
) = 1;
1728 cfun
->has_forced_label_in_static
= 1;
1734 /* Gimplify a DECL_EXPR node *STMT_P by making any necessary allocation
1735 and initialization explicit. */
1737 static enum gimplify_status
1738 gimplify_decl_expr (tree
*stmt_p
, gimple_seq
*seq_p
)
1740 tree stmt
= *stmt_p
;
1741 tree decl
= DECL_EXPR_DECL (stmt
);
1743 *stmt_p
= NULL_TREE
;
1745 if (TREE_TYPE (decl
) == error_mark_node
)
1748 if ((TREE_CODE (decl
) == TYPE_DECL
1750 && !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl
)))
1752 gimplify_type_sizes (TREE_TYPE (decl
), seq_p
);
1753 if (TREE_CODE (TREE_TYPE (decl
)) == REFERENCE_TYPE
)
1754 gimplify_type_sizes (TREE_TYPE (TREE_TYPE (decl
)), seq_p
);
1757 /* ??? DECL_ORIGINAL_TYPE is streamed for LTO so it needs to be gimplified
1758 in case its size expressions contain problematic nodes like CALL_EXPR. */
1759 if (TREE_CODE (decl
) == TYPE_DECL
1760 && DECL_ORIGINAL_TYPE (decl
)
1761 && !TYPE_SIZES_GIMPLIFIED (DECL_ORIGINAL_TYPE (decl
)))
1763 gimplify_type_sizes (DECL_ORIGINAL_TYPE (decl
), seq_p
);
1764 if (TREE_CODE (DECL_ORIGINAL_TYPE (decl
)) == REFERENCE_TYPE
)
1765 gimplify_type_sizes (TREE_TYPE (DECL_ORIGINAL_TYPE (decl
)), seq_p
);
1768 if (VAR_P (decl
) && !DECL_EXTERNAL (decl
))
1770 tree init
= DECL_INITIAL (decl
);
1771 bool is_vla
= false;
1774 if (!poly_int_tree_p (DECL_SIZE_UNIT (decl
), &size
)
1775 || (!TREE_STATIC (decl
)
1776 && flag_stack_check
== GENERIC_STACK_CHECK
1778 (unsigned HOST_WIDE_INT
) STACK_CHECK_MAX_VAR_SIZE
)))
1780 gimplify_vla_decl (decl
, seq_p
);
1784 if (asan_poisoned_variables
1786 && TREE_ADDRESSABLE (decl
)
1787 && !TREE_STATIC (decl
)
1788 && !DECL_HAS_VALUE_EXPR_P (decl
)
1789 && DECL_ALIGN (decl
) <= MAX_SUPPORTED_STACK_ALIGNMENT
1790 && dbg_cnt (asan_use_after_scope
)
1791 && !gimplify_omp_ctxp
)
1793 asan_poisoned_variables
->add (decl
);
1794 asan_poison_variable (decl
, false, seq_p
);
1795 if (!DECL_ARTIFICIAL (decl
) && gimplify_ctxp
->live_switch_vars
)
1796 gimplify_ctxp
->live_switch_vars
->add (decl
);
1799 /* Some front ends do not explicitly declare all anonymous
1800 artificial variables. We compensate here by declaring the
1801 variables, though it would be better if the front ends would
1802 explicitly declare them. */
1803 if (!DECL_SEEN_IN_BIND_EXPR_P (decl
)
1804 && DECL_ARTIFICIAL (decl
) && DECL_NAME (decl
) == NULL_TREE
)
1805 gimple_add_tmp_var (decl
);
1807 if (init
&& init
!= error_mark_node
)
1809 if (!TREE_STATIC (decl
))
1811 DECL_INITIAL (decl
) = NULL_TREE
;
1812 init
= build2 (INIT_EXPR
, void_type_node
, decl
, init
);
1813 gimplify_and_add (init
, seq_p
);
1817 /* We must still examine initializers for static variables
1818 as they may contain a label address. */
1819 walk_tree (&init
, force_labels_r
, NULL
, NULL
);
1826 /* Gimplify a LOOP_EXPR. Normally this just involves gimplifying the body
1827 and replacing the LOOP_EXPR with goto, but if the loop contains an
1828 EXIT_EXPR, we need to append a label for it to jump to. */
1830 static enum gimplify_status
1831 gimplify_loop_expr (tree
*expr_p
, gimple_seq
*pre_p
)
1833 tree saved_label
= gimplify_ctxp
->exit_label
;
1834 tree start_label
= create_artificial_label (UNKNOWN_LOCATION
);
1836 gimplify_seq_add_stmt (pre_p
, gimple_build_label (start_label
));
1838 gimplify_ctxp
->exit_label
= NULL_TREE
;
1840 gimplify_and_add (LOOP_EXPR_BODY (*expr_p
), pre_p
);
1842 gimplify_seq_add_stmt (pre_p
, gimple_build_goto (start_label
));
1844 if (gimplify_ctxp
->exit_label
)
1845 gimplify_seq_add_stmt (pre_p
,
1846 gimple_build_label (gimplify_ctxp
->exit_label
));
1848 gimplify_ctxp
->exit_label
= saved_label
;
1854 /* Gimplify a statement list onto a sequence. These may be created either
1855 by an enlightened front-end, or by shortcut_cond_expr. */
1857 static enum gimplify_status
1858 gimplify_statement_list (tree
*expr_p
, gimple_seq
*pre_p
)
1860 tree temp
= voidify_wrapper_expr (*expr_p
, NULL
);
1862 tree_stmt_iterator i
= tsi_start (*expr_p
);
1864 while (!tsi_end_p (i
))
1866 gimplify_stmt (tsi_stmt_ptr (i
), pre_p
);
1879 /* Callback for walk_gimple_seq. */
1882 warn_switch_unreachable_r (gimple_stmt_iterator
*gsi_p
, bool *handled_ops_p
,
1883 struct walk_stmt_info
*wi
)
1885 gimple
*stmt
= gsi_stmt (*gsi_p
);
1887 *handled_ops_p
= true;
1888 switch (gimple_code (stmt
))
1891 /* A compiler-generated cleanup or a user-written try block.
1892 If it's empty, don't dive into it--that would result in
1893 worse location info. */
1894 if (gimple_try_eval (stmt
) == NULL
)
1897 return integer_zero_node
;
1902 case GIMPLE_EH_FILTER
:
1903 case GIMPLE_TRANSACTION
:
1904 /* Walk the sub-statements. */
1905 *handled_ops_p
= false;
1909 /* Ignore these. We may generate them before declarations that
1910 are never executed. If there's something to warn about,
1911 there will be non-debug stmts too, and we'll catch those. */
1915 if (gimple_call_internal_p (stmt
, IFN_ASAN_MARK
))
1917 *handled_ops_p
= false;
1922 /* Save the first "real" statement (not a decl/lexical scope/...). */
1924 return integer_zero_node
;
1929 /* Possibly warn about unreachable statements between switch's controlling
1930 expression and the first case. SEQ is the body of a switch expression. */
1933 maybe_warn_switch_unreachable (gimple_seq seq
)
1935 if (!warn_switch_unreachable
1936 /* This warning doesn't play well with Fortran when optimizations
1938 || lang_GNU_Fortran ()
1942 struct walk_stmt_info wi
;
1943 memset (&wi
, 0, sizeof (wi
));
1944 walk_gimple_seq (seq
, warn_switch_unreachable_r
, NULL
, &wi
);
1945 gimple
*stmt
= (gimple
*) wi
.info
;
1947 if (stmt
&& gimple_code (stmt
) != GIMPLE_LABEL
)
1949 if (gimple_code (stmt
) == GIMPLE_GOTO
1950 && TREE_CODE (gimple_goto_dest (stmt
)) == LABEL_DECL
1951 && DECL_ARTIFICIAL (gimple_goto_dest (stmt
)))
1952 /* Don't warn for compiler-generated gotos. These occur
1953 in Duff's devices, for example. */;
1955 warning_at (gimple_location (stmt
), OPT_Wswitch_unreachable
,
1956 "statement will never be executed");
1961 /* A label entry that pairs label and a location. */
1968 /* Find LABEL in vector of label entries VEC. */
1970 static struct label_entry
*
1971 find_label_entry (const auto_vec
<struct label_entry
> *vec
, tree label
)
1974 struct label_entry
*l
;
1976 FOR_EACH_VEC_ELT (*vec
, i
, l
)
1977 if (l
->label
== label
)
1982 /* Return true if LABEL, a LABEL_DECL, represents a case label
1983 in a vector of labels CASES. */
1986 case_label_p (const vec
<tree
> *cases
, tree label
)
1991 FOR_EACH_VEC_ELT (*cases
, i
, l
)
1992 if (CASE_LABEL (l
) == label
)
1997 /* Find the last nondebug statement in a scope STMT. */
2000 last_stmt_in_scope (gimple
*stmt
)
2005 switch (gimple_code (stmt
))
2009 gbind
*bind
= as_a
<gbind
*> (stmt
);
2010 stmt
= gimple_seq_last_nondebug_stmt (gimple_bind_body (bind
));
2011 return last_stmt_in_scope (stmt
);
2016 gtry
*try_stmt
= as_a
<gtry
*> (stmt
);
2017 stmt
= gimple_seq_last_nondebug_stmt (gimple_try_eval (try_stmt
));
2018 gimple
*last_eval
= last_stmt_in_scope (stmt
);
2019 if (gimple_stmt_may_fallthru (last_eval
)
2020 && (last_eval
== NULL
2021 || !gimple_call_internal_p (last_eval
, IFN_FALLTHROUGH
))
2022 && gimple_try_kind (try_stmt
) == GIMPLE_TRY_FINALLY
)
2024 stmt
= gimple_seq_last_nondebug_stmt (gimple_try_cleanup (try_stmt
));
2025 return last_stmt_in_scope (stmt
);
2039 /* Collect interesting labels in LABELS and return the statement preceding
2040 another case label, or a user-defined label. Store a location useful
2041 to give warnings at *PREVLOC (usually the location of the returned
2042 statement or of its surrounding scope). */
2045 collect_fallthrough_labels (gimple_stmt_iterator
*gsi_p
,
2046 auto_vec
<struct label_entry
> *labels
,
2047 location_t
*prevloc
)
2049 gimple
*prev
= NULL
;
2051 *prevloc
= UNKNOWN_LOCATION
;
2054 if (gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_BIND
)
2056 /* Recognize the special GIMPLE_BIND added by gimplify_switch_expr,
2057 which starts on a GIMPLE_SWITCH and ends with a break label.
2058 Handle that as a single statement that can fall through. */
2059 gbind
*bind
= as_a
<gbind
*> (gsi_stmt (*gsi_p
));
2060 gimple
*first
= gimple_seq_first_stmt (gimple_bind_body (bind
));
2061 gimple
*last
= gimple_seq_last_stmt (gimple_bind_body (bind
));
2063 && gimple_code (first
) == GIMPLE_SWITCH
2064 && gimple_code (last
) == GIMPLE_LABEL
)
2066 tree label
= gimple_label_label (as_a
<glabel
*> (last
));
2067 if (SWITCH_BREAK_LABEL_P (label
))
2075 if (gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_BIND
2076 || gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_TRY
)
2078 /* Nested scope. Only look at the last statement of
2079 the innermost scope. */
2080 location_t bind_loc
= gimple_location (gsi_stmt (*gsi_p
));
2081 gimple
*last
= last_stmt_in_scope (gsi_stmt (*gsi_p
));
2085 /* It might be a label without a location. Use the
2086 location of the scope then. */
2087 if (!gimple_has_location (prev
))
2088 *prevloc
= bind_loc
;
2094 /* Ifs are tricky. */
2095 if (gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_COND
)
2097 gcond
*cond_stmt
= as_a
<gcond
*> (gsi_stmt (*gsi_p
));
2098 tree false_lab
= gimple_cond_false_label (cond_stmt
);
2099 location_t if_loc
= gimple_location (cond_stmt
);
2102 if (i > 1) goto <D.2259>; else goto D;
2103 we can't do much with the else-branch. */
2104 if (!DECL_ARTIFICIAL (false_lab
))
2107 /* Go on until the false label, then one step back. */
2108 for (; !gsi_end_p (*gsi_p
); gsi_next (gsi_p
))
2110 gimple
*stmt
= gsi_stmt (*gsi_p
);
2111 if (gimple_code (stmt
) == GIMPLE_LABEL
2112 && gimple_label_label (as_a
<glabel
*> (stmt
)) == false_lab
)
2116 /* Not found? Oops. */
2117 if (gsi_end_p (*gsi_p
))
2120 struct label_entry l
= { false_lab
, if_loc
};
2121 labels
->safe_push (l
);
2123 /* Go to the last statement of the then branch. */
2126 /* if (i != 0) goto <D.1759>; else goto <D.1760>;
2132 if (gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_GOTO
2133 && !gimple_has_location (gsi_stmt (*gsi_p
)))
2135 /* Look at the statement before, it might be
2136 attribute fallthrough, in which case don't warn. */
2138 bool fallthru_before_dest
2139 = gimple_call_internal_p (gsi_stmt (*gsi_p
), IFN_FALLTHROUGH
);
2141 tree goto_dest
= gimple_goto_dest (gsi_stmt (*gsi_p
));
2142 if (!fallthru_before_dest
)
2144 struct label_entry l
= { goto_dest
, if_loc
};
2145 labels
->safe_push (l
);
2148 /* And move back. */
2152 /* Remember the last statement. Skip labels that are of no interest
2154 if (gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_LABEL
)
2156 tree label
= gimple_label_label (as_a
<glabel
*> (gsi_stmt (*gsi_p
)));
2157 if (find_label_entry (labels
, label
))
2158 prev
= gsi_stmt (*gsi_p
);
2160 else if (gimple_call_internal_p (gsi_stmt (*gsi_p
), IFN_ASAN_MARK
))
2162 else if (gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_PREDICT
)
2164 else if (!is_gimple_debug (gsi_stmt (*gsi_p
)))
2165 prev
= gsi_stmt (*gsi_p
);
2168 while (!gsi_end_p (*gsi_p
)
2169 /* Stop if we find a case or a user-defined label. */
2170 && (gimple_code (gsi_stmt (*gsi_p
)) != GIMPLE_LABEL
2171 || !gimple_has_location (gsi_stmt (*gsi_p
))));
2173 if (prev
&& gimple_has_location (prev
))
2174 *prevloc
= gimple_location (prev
);
2178 /* Return true if the switch fallthough warning should occur. LABEL is
2179 the label statement that we're falling through to. */
2182 should_warn_for_implicit_fallthrough (gimple_stmt_iterator
*gsi_p
, tree label
)
2184 gimple_stmt_iterator gsi
= *gsi_p
;
2186 /* Don't warn if the label is marked with a "falls through" comment. */
2187 if (FALLTHROUGH_LABEL_P (label
))
2190 /* Don't warn for non-case labels followed by a statement:
2195 as these are likely intentional. */
2196 if (!case_label_p (&gimplify_ctxp
->case_labels
, label
))
2199 while (!gsi_end_p (gsi
)
2200 && gimple_code (gsi_stmt (gsi
)) == GIMPLE_LABEL
2201 && (l
= gimple_label_label (as_a
<glabel
*> (gsi_stmt (gsi
))))
2202 && !case_label_p (&gimplify_ctxp
->case_labels
, l
))
2203 gsi_next_nondebug (&gsi
);
2204 if (gsi_end_p (gsi
) || gimple_code (gsi_stmt (gsi
)) != GIMPLE_LABEL
)
2208 /* Don't warn for terminated branches, i.e. when the subsequent case labels
2209 immediately breaks. */
2212 /* Skip all immediately following labels. */
2213 while (!gsi_end_p (gsi
)
2214 && (gimple_code (gsi_stmt (gsi
)) == GIMPLE_LABEL
2215 || gimple_code (gsi_stmt (gsi
)) == GIMPLE_PREDICT
))
2216 gsi_next_nondebug (&gsi
);
2218 /* { ... something; default:; } */
2220 /* { ... something; default: break; } or
2221 { ... something; default: goto L; } */
2222 || gimple_code (gsi_stmt (gsi
)) == GIMPLE_GOTO
2223 /* { ... something; default: return; } */
2224 || gimple_code (gsi_stmt (gsi
)) == GIMPLE_RETURN
)
2230 /* Callback for walk_gimple_seq. */
2233 warn_implicit_fallthrough_r (gimple_stmt_iterator
*gsi_p
, bool *handled_ops_p
,
2234 struct walk_stmt_info
*)
2236 gimple
*stmt
= gsi_stmt (*gsi_p
);
2238 *handled_ops_p
= true;
2239 switch (gimple_code (stmt
))
2244 case GIMPLE_EH_FILTER
:
2245 case GIMPLE_TRANSACTION
:
2246 /* Walk the sub-statements. */
2247 *handled_ops_p
= false;
2250 /* Find a sequence of form:
2257 and possibly warn. */
2260 /* Found a label. Skip all immediately following labels. */
2261 while (!gsi_end_p (*gsi_p
)
2262 && gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_LABEL
)
2263 gsi_next_nondebug (gsi_p
);
2265 /* There might be no more statements. */
2266 if (gsi_end_p (*gsi_p
))
2267 return integer_zero_node
;
2269 /* Vector of labels that fall through. */
2270 auto_vec
<struct label_entry
> labels
;
2272 gimple
*prev
= collect_fallthrough_labels (gsi_p
, &labels
, &prevloc
);
2274 /* There might be no more statements. */
2275 if (gsi_end_p (*gsi_p
))
2276 return integer_zero_node
;
2278 gimple
*next
= gsi_stmt (*gsi_p
);
2280 /* If what follows is a label, then we may have a fallthrough. */
2281 if (gimple_code (next
) == GIMPLE_LABEL
2282 && gimple_has_location (next
)
2283 && (label
= gimple_label_label (as_a
<glabel
*> (next
)))
2286 struct label_entry
*l
;
2287 bool warned_p
= false;
2288 auto_diagnostic_group d
;
2289 if (!should_warn_for_implicit_fallthrough (gsi_p
, label
))
2291 else if (gimple_code (prev
) == GIMPLE_LABEL
2292 && (label
= gimple_label_label (as_a
<glabel
*> (prev
)))
2293 && (l
= find_label_entry (&labels
, label
)))
2294 warned_p
= warning_at (l
->loc
, OPT_Wimplicit_fallthrough_
,
2295 "this statement may fall through");
2296 else if (!gimple_call_internal_p (prev
, IFN_FALLTHROUGH
)
2297 /* Try to be clever and don't warn when the statement
2298 can't actually fall through. */
2299 && gimple_stmt_may_fallthru (prev
)
2300 && prevloc
!= UNKNOWN_LOCATION
)
2301 warned_p
= warning_at (prevloc
,
2302 OPT_Wimplicit_fallthrough_
,
2303 "this statement may fall through");
2305 inform (gimple_location (next
), "here");
2307 /* Mark this label as processed so as to prevent multiple
2308 warnings in nested switches. */
2309 FALLTHROUGH_LABEL_P (label
) = true;
2311 /* So that next warn_implicit_fallthrough_r will start looking for
2312 a new sequence starting with this label. */
2323 /* Warn when a switch case falls through. */
2326 maybe_warn_implicit_fallthrough (gimple_seq seq
)
2328 if (!warn_implicit_fallthrough
)
2331 /* This warning is meant for C/C++/ObjC/ObjC++ only. */
2334 || lang_GNU_OBJC ()))
2337 struct walk_stmt_info wi
;
2338 memset (&wi
, 0, sizeof (wi
));
2339 walk_gimple_seq (seq
, warn_implicit_fallthrough_r
, NULL
, &wi
);
2342 /* Callback for walk_gimple_seq. */
2345 expand_FALLTHROUGH_r (gimple_stmt_iterator
*gsi_p
, bool *handled_ops_p
,
2346 struct walk_stmt_info
*wi
)
2348 gimple
*stmt
= gsi_stmt (*gsi_p
);
2350 *handled_ops_p
= true;
2351 switch (gimple_code (stmt
))
2356 case GIMPLE_EH_FILTER
:
2357 case GIMPLE_TRANSACTION
:
2358 /* Walk the sub-statements. */
2359 *handled_ops_p
= false;
2362 if (gimple_call_internal_p (stmt
, IFN_FALLTHROUGH
))
2364 gsi_remove (gsi_p
, true);
2365 if (gsi_end_p (*gsi_p
))
2367 *static_cast<location_t
*>(wi
->info
) = gimple_location (stmt
);
2368 return integer_zero_node
;
2372 location_t loc
= gimple_location (stmt
);
2374 gimple_stmt_iterator gsi2
= *gsi_p
;
2375 stmt
= gsi_stmt (gsi2
);
2376 if (gimple_code (stmt
) == GIMPLE_GOTO
&& !gimple_has_location (stmt
))
2378 /* Go on until the artificial label. */
2379 tree goto_dest
= gimple_goto_dest (stmt
);
2380 for (; !gsi_end_p (gsi2
); gsi_next (&gsi2
))
2382 if (gimple_code (gsi_stmt (gsi2
)) == GIMPLE_LABEL
2383 && gimple_label_label (as_a
<glabel
*> (gsi_stmt (gsi2
)))
2388 /* Not found? Stop. */
2389 if (gsi_end_p (gsi2
))
2392 /* Look one past it. */
2396 /* We're looking for a case label or default label here. */
2397 while (!gsi_end_p (gsi2
))
2399 stmt
= gsi_stmt (gsi2
);
2400 if (gimple_code (stmt
) == GIMPLE_LABEL
)
2402 tree label
= gimple_label_label (as_a
<glabel
*> (stmt
));
2403 if (gimple_has_location (stmt
) && DECL_ARTIFICIAL (label
))
2409 else if (gimple_call_internal_p (stmt
, IFN_ASAN_MARK
))
2411 else if (!is_gimple_debug (stmt
))
2412 /* Anything else is not expected. */
2417 pedwarn (loc
, 0, "attribute %<fallthrough%> not preceding "
2418 "a case label or default label");
2427 /* Expand all FALLTHROUGH () calls in SEQ. */
2430 expand_FALLTHROUGH (gimple_seq
*seq_p
)
2432 struct walk_stmt_info wi
;
2434 memset (&wi
, 0, sizeof (wi
));
2435 wi
.info
= (void *) &loc
;
2436 walk_gimple_seq_mod (seq_p
, expand_FALLTHROUGH_r
, NULL
, &wi
);
2437 if (wi
.callback_result
== integer_zero_node
)
2438 /* We've found [[fallthrough]]; at the end of a switch, which the C++
2439 standard says is ill-formed; see [dcl.attr.fallthrough]. */
2440 pedwarn (loc
, 0, "attribute %<fallthrough%> not preceding "
2441 "a case label or default label");
2445 /* Gimplify a SWITCH_EXPR, and collect the vector of labels it can
2448 static enum gimplify_status
2449 gimplify_switch_expr (tree
*expr_p
, gimple_seq
*pre_p
)
2451 tree switch_expr
= *expr_p
;
2452 gimple_seq switch_body_seq
= NULL
;
2453 enum gimplify_status ret
;
2454 tree index_type
= TREE_TYPE (switch_expr
);
2455 if (index_type
== NULL_TREE
)
2456 index_type
= TREE_TYPE (SWITCH_COND (switch_expr
));
2458 ret
= gimplify_expr (&SWITCH_COND (switch_expr
), pre_p
, NULL
, is_gimple_val
,
2460 if (ret
== GS_ERROR
|| ret
== GS_UNHANDLED
)
2463 if (SWITCH_BODY (switch_expr
))
2466 vec
<tree
> saved_labels
;
2467 hash_set
<tree
> *saved_live_switch_vars
= NULL
;
2468 tree default_case
= NULL_TREE
;
2469 gswitch
*switch_stmt
;
2471 /* Save old labels, get new ones from body, then restore the old
2472 labels. Save all the things from the switch body to append after. */
2473 saved_labels
= gimplify_ctxp
->case_labels
;
2474 gimplify_ctxp
->case_labels
.create (8);
2476 /* Do not create live_switch_vars if SWITCH_BODY is not a BIND_EXPR. */
2477 saved_live_switch_vars
= gimplify_ctxp
->live_switch_vars
;
2478 tree_code body_type
= TREE_CODE (SWITCH_BODY (switch_expr
));
2479 if (body_type
== BIND_EXPR
|| body_type
== STATEMENT_LIST
)
2480 gimplify_ctxp
->live_switch_vars
= new hash_set
<tree
> (4);
2482 gimplify_ctxp
->live_switch_vars
= NULL
;
2484 bool old_in_switch_expr
= gimplify_ctxp
->in_switch_expr
;
2485 gimplify_ctxp
->in_switch_expr
= true;
2487 gimplify_stmt (&SWITCH_BODY (switch_expr
), &switch_body_seq
);
2489 gimplify_ctxp
->in_switch_expr
= old_in_switch_expr
;
2490 maybe_warn_switch_unreachable (switch_body_seq
);
2491 maybe_warn_implicit_fallthrough (switch_body_seq
);
2492 /* Only do this for the outermost GIMPLE_SWITCH. */
2493 if (!gimplify_ctxp
->in_switch_expr
)
2494 expand_FALLTHROUGH (&switch_body_seq
);
2496 labels
= gimplify_ctxp
->case_labels
;
2497 gimplify_ctxp
->case_labels
= saved_labels
;
2499 if (gimplify_ctxp
->live_switch_vars
)
2501 gcc_assert (gimplify_ctxp
->live_switch_vars
->is_empty ());
2502 delete gimplify_ctxp
->live_switch_vars
;
2504 gimplify_ctxp
->live_switch_vars
= saved_live_switch_vars
;
2506 preprocess_case_label_vec_for_gimple (labels
, index_type
,
2509 bool add_bind
= false;
2512 glabel
*new_default
;
2515 = build_case_label (NULL_TREE
, NULL_TREE
,
2516 create_artificial_label (UNKNOWN_LOCATION
));
2517 if (old_in_switch_expr
)
2519 SWITCH_BREAK_LABEL_P (CASE_LABEL (default_case
)) = 1;
2522 new_default
= gimple_build_label (CASE_LABEL (default_case
));
2523 gimplify_seq_add_stmt (&switch_body_seq
, new_default
);
2525 else if (old_in_switch_expr
)
2527 gimple
*last
= gimple_seq_last_stmt (switch_body_seq
);
2528 if (last
&& gimple_code (last
) == GIMPLE_LABEL
)
2530 tree label
= gimple_label_label (as_a
<glabel
*> (last
));
2531 if (SWITCH_BREAK_LABEL_P (label
))
2536 switch_stmt
= gimple_build_switch (SWITCH_COND (switch_expr
),
2537 default_case
, labels
);
2538 /* For the benefit of -Wimplicit-fallthrough, if switch_body_seq
2539 ends with a GIMPLE_LABEL holding SWITCH_BREAK_LABEL_P LABEL_DECL,
2540 wrap the GIMPLE_SWITCH up to that GIMPLE_LABEL into a GIMPLE_BIND,
2541 so that we can easily find the start and end of the switch
2545 gimple_seq bind_body
= NULL
;
2546 gimplify_seq_add_stmt (&bind_body
, switch_stmt
);
2547 gimple_seq_add_seq (&bind_body
, switch_body_seq
);
2548 gbind
*bind
= gimple_build_bind (NULL_TREE
, bind_body
, NULL_TREE
);
2549 gimple_set_location (bind
, EXPR_LOCATION (switch_expr
));
2550 gimplify_seq_add_stmt (pre_p
, bind
);
2554 gimplify_seq_add_stmt (pre_p
, switch_stmt
);
2555 gimplify_seq_add_seq (pre_p
, switch_body_seq
);
2565 /* Gimplify the LABEL_EXPR pointed to by EXPR_P. */
2567 static enum gimplify_status
2568 gimplify_label_expr (tree
*expr_p
, gimple_seq
*pre_p
)
2570 gcc_assert (decl_function_context (LABEL_EXPR_LABEL (*expr_p
))
2571 == current_function_decl
);
2573 tree label
= LABEL_EXPR_LABEL (*expr_p
);
2574 glabel
*label_stmt
= gimple_build_label (label
);
2575 gimple_set_location (label_stmt
, EXPR_LOCATION (*expr_p
));
2576 gimplify_seq_add_stmt (pre_p
, label_stmt
);
2578 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label
)))
2579 gimple_seq_add_stmt (pre_p
, gimple_build_predict (PRED_COLD_LABEL
,
2581 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label
)))
2582 gimple_seq_add_stmt (pre_p
, gimple_build_predict (PRED_HOT_LABEL
,
2588 /* Gimplify the CASE_LABEL_EXPR pointed to by EXPR_P. */
2590 static enum gimplify_status
2591 gimplify_case_label_expr (tree
*expr_p
, gimple_seq
*pre_p
)
2593 struct gimplify_ctx
*ctxp
;
2596 /* Invalid programs can play Duff's Device type games with, for example,
2597 #pragma omp parallel. At least in the C front end, we don't
2598 detect such invalid branches until after gimplification, in the
2599 diagnose_omp_blocks pass. */
2600 for (ctxp
= gimplify_ctxp
; ; ctxp
= ctxp
->prev_context
)
2601 if (ctxp
->case_labels
.exists ())
2604 tree label
= CASE_LABEL (*expr_p
);
2605 label_stmt
= gimple_build_label (label
);
2606 gimple_set_location (label_stmt
, EXPR_LOCATION (*expr_p
));
2607 ctxp
->case_labels
.safe_push (*expr_p
);
2608 gimplify_seq_add_stmt (pre_p
, label_stmt
);
2610 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label
)))
2611 gimple_seq_add_stmt (pre_p
, gimple_build_predict (PRED_COLD_LABEL
,
2613 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label
)))
2614 gimple_seq_add_stmt (pre_p
, gimple_build_predict (PRED_HOT_LABEL
,
2620 /* Build a GOTO to the LABEL_DECL pointed to by LABEL_P, building it first
2624 build_and_jump (tree
*label_p
)
2626 if (label_p
== NULL
)
2627 /* If there's nowhere to jump, just fall through. */
2630 if (*label_p
== NULL_TREE
)
2632 tree label
= create_artificial_label (UNKNOWN_LOCATION
);
2636 return build1 (GOTO_EXPR
, void_type_node
, *label_p
);
2639 /* Gimplify an EXIT_EXPR by converting to a GOTO_EXPR inside a COND_EXPR.
2640 This also involves building a label to jump to and communicating it to
2641 gimplify_loop_expr through gimplify_ctxp->exit_label. */
2643 static enum gimplify_status
2644 gimplify_exit_expr (tree
*expr_p
)
2646 tree cond
= TREE_OPERAND (*expr_p
, 0);
2649 expr
= build_and_jump (&gimplify_ctxp
->exit_label
);
2650 expr
= build3 (COND_EXPR
, void_type_node
, cond
, expr
, NULL_TREE
);
2656 /* *EXPR_P is a COMPONENT_REF being used as an rvalue. If its type is
2657 different from its canonical type, wrap the whole thing inside a
2658 NOP_EXPR and force the type of the COMPONENT_REF to be the canonical
2661 The canonical type of a COMPONENT_REF is the type of the field being
2662 referenced--unless the field is a bit-field which can be read directly
2663 in a smaller mode, in which case the canonical type is the
2664 sign-appropriate type corresponding to that mode. */
2667 canonicalize_component_ref (tree
*expr_p
)
2669 tree expr
= *expr_p
;
2672 gcc_assert (TREE_CODE (expr
) == COMPONENT_REF
);
2674 if (INTEGRAL_TYPE_P (TREE_TYPE (expr
)))
2675 type
= TREE_TYPE (get_unwidened (expr
, NULL_TREE
));
2677 type
= TREE_TYPE (TREE_OPERAND (expr
, 1));
2679 /* One could argue that all the stuff below is not necessary for
2680 the non-bitfield case and declare it a FE error if type
2681 adjustment would be needed. */
2682 if (TREE_TYPE (expr
) != type
)
2684 #ifdef ENABLE_TYPES_CHECKING
2685 tree old_type
= TREE_TYPE (expr
);
2689 /* We need to preserve qualifiers and propagate them from
2691 type_quals
= TYPE_QUALS (type
)
2692 | TYPE_QUALS (TREE_TYPE (TREE_OPERAND (expr
, 0)));
2693 if (TYPE_QUALS (type
) != type_quals
)
2694 type
= build_qualified_type (TYPE_MAIN_VARIANT (type
), type_quals
);
2696 /* Set the type of the COMPONENT_REF to the underlying type. */
2697 TREE_TYPE (expr
) = type
;
2699 #ifdef ENABLE_TYPES_CHECKING
2700 /* It is now a FE error, if the conversion from the canonical
2701 type to the original expression type is not useless. */
2702 gcc_assert (useless_type_conversion_p (old_type
, type
));
2707 /* If a NOP conversion is changing a pointer to array of foo to a pointer
2708 to foo, embed that change in the ADDR_EXPR by converting
2713 where L is the lower bound. For simplicity, only do this for constant
2715 The constraint is that the type of &array[L] is trivially convertible
2719 canonicalize_addr_expr (tree
*expr_p
)
2721 tree expr
= *expr_p
;
2722 tree addr_expr
= TREE_OPERAND (expr
, 0);
2723 tree datype
, ddatype
, pddatype
;
2725 /* We simplify only conversions from an ADDR_EXPR to a pointer type. */
2726 if (!POINTER_TYPE_P (TREE_TYPE (expr
))
2727 || TREE_CODE (addr_expr
) != ADDR_EXPR
)
2730 /* The addr_expr type should be a pointer to an array. */
2731 datype
= TREE_TYPE (TREE_TYPE (addr_expr
));
2732 if (TREE_CODE (datype
) != ARRAY_TYPE
)
2735 /* The pointer to element type shall be trivially convertible to
2736 the expression pointer type. */
2737 ddatype
= TREE_TYPE (datype
);
2738 pddatype
= build_pointer_type (ddatype
);
2739 if (!useless_type_conversion_p (TYPE_MAIN_VARIANT (TREE_TYPE (expr
)),
2743 /* The lower bound and element sizes must be constant. */
2744 if (!TYPE_SIZE_UNIT (ddatype
)
2745 || TREE_CODE (TYPE_SIZE_UNIT (ddatype
)) != INTEGER_CST
2746 || !TYPE_DOMAIN (datype
) || !TYPE_MIN_VALUE (TYPE_DOMAIN (datype
))
2747 || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (datype
))) != INTEGER_CST
)
2750 /* All checks succeeded. Build a new node to merge the cast. */
2751 *expr_p
= build4 (ARRAY_REF
, ddatype
, TREE_OPERAND (addr_expr
, 0),
2752 TYPE_MIN_VALUE (TYPE_DOMAIN (datype
)),
2753 NULL_TREE
, NULL_TREE
);
2754 *expr_p
= build1 (ADDR_EXPR
, pddatype
, *expr_p
);
2756 /* We can have stripped a required restrict qualifier above. */
2757 if (!useless_type_conversion_p (TREE_TYPE (expr
), TREE_TYPE (*expr_p
)))
2758 *expr_p
= fold_convert (TREE_TYPE (expr
), *expr_p
);
2761 /* *EXPR_P is a NOP_EXPR or CONVERT_EXPR. Remove it and/or other conversions
2762 underneath as appropriate. */
2764 static enum gimplify_status
2765 gimplify_conversion (tree
*expr_p
)
2767 location_t loc
= EXPR_LOCATION (*expr_p
);
2768 gcc_assert (CONVERT_EXPR_P (*expr_p
));
2770 /* Then strip away all but the outermost conversion. */
2771 STRIP_SIGN_NOPS (TREE_OPERAND (*expr_p
, 0));
2773 /* And remove the outermost conversion if it's useless. */
2774 if (tree_ssa_useless_type_conversion (*expr_p
))
2775 *expr_p
= TREE_OPERAND (*expr_p
, 0);
2777 /* If we still have a conversion at the toplevel,
2778 then canonicalize some constructs. */
2779 if (CONVERT_EXPR_P (*expr_p
))
2781 tree sub
= TREE_OPERAND (*expr_p
, 0);
2783 /* If a NOP conversion is changing the type of a COMPONENT_REF
2784 expression, then canonicalize its type now in order to expose more
2785 redundant conversions. */
2786 if (TREE_CODE (sub
) == COMPONENT_REF
)
2787 canonicalize_component_ref (&TREE_OPERAND (*expr_p
, 0));
2789 /* If a NOP conversion is changing a pointer to array of foo
2790 to a pointer to foo, embed that change in the ADDR_EXPR. */
2791 else if (TREE_CODE (sub
) == ADDR_EXPR
)
2792 canonicalize_addr_expr (expr_p
);
2795 /* If we have a conversion to a non-register type force the
2796 use of a VIEW_CONVERT_EXPR instead. */
2797 if (CONVERT_EXPR_P (*expr_p
) && !is_gimple_reg_type (TREE_TYPE (*expr_p
)))
2798 *expr_p
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, TREE_TYPE (*expr_p
),
2799 TREE_OPERAND (*expr_p
, 0));
2801 /* Canonicalize CONVERT_EXPR to NOP_EXPR. */
2802 if (TREE_CODE (*expr_p
) == CONVERT_EXPR
)
2803 TREE_SET_CODE (*expr_p
, NOP_EXPR
);
2808 /* Gimplify a VAR_DECL or PARM_DECL. Return GS_OK if we expanded a
2809 DECL_VALUE_EXPR, and it's worth re-examining things. */
2811 static enum gimplify_status
2812 gimplify_var_or_parm_decl (tree
*expr_p
)
2814 tree decl
= *expr_p
;
2816 /* ??? If this is a local variable, and it has not been seen in any
2817 outer BIND_EXPR, then it's probably the result of a duplicate
2818 declaration, for which we've already issued an error. It would
2819 be really nice if the front end wouldn't leak these at all.
2820 Currently the only known culprit is C++ destructors, as seen
2821 in g++.old-deja/g++.jason/binding.C. */
2823 && !DECL_SEEN_IN_BIND_EXPR_P (decl
)
2824 && !TREE_STATIC (decl
) && !DECL_EXTERNAL (decl
)
2825 && decl_function_context (decl
) == current_function_decl
)
2827 gcc_assert (seen_error ());
2831 /* When within an OMP context, notice uses of variables. */
2832 if (gimplify_omp_ctxp
&& omp_notice_variable (gimplify_omp_ctxp
, decl
, true))
2835 /* If the decl is an alias for another expression, substitute it now. */
2836 if (DECL_HAS_VALUE_EXPR_P (decl
))
2838 *expr_p
= unshare_expr (DECL_VALUE_EXPR (decl
));
2845 /* Recalculate the value of the TREE_SIDE_EFFECTS flag for T. */
2848 recalculate_side_effects (tree t
)
2850 enum tree_code code
= TREE_CODE (t
);
2851 int len
= TREE_OPERAND_LENGTH (t
);
2854 switch (TREE_CODE_CLASS (code
))
2856 case tcc_expression
:
2862 case PREDECREMENT_EXPR
:
2863 case PREINCREMENT_EXPR
:
2864 case POSTDECREMENT_EXPR
:
2865 case POSTINCREMENT_EXPR
:
2866 /* All of these have side-effects, no matter what their
2875 case tcc_comparison
: /* a comparison expression */
2876 case tcc_unary
: /* a unary arithmetic expression */
2877 case tcc_binary
: /* a binary arithmetic expression */
2878 case tcc_reference
: /* a reference */
2879 case tcc_vl_exp
: /* a function call */
2880 TREE_SIDE_EFFECTS (t
) = TREE_THIS_VOLATILE (t
);
2881 for (i
= 0; i
< len
; ++i
)
2883 tree op
= TREE_OPERAND (t
, i
);
2884 if (op
&& TREE_SIDE_EFFECTS (op
))
2885 TREE_SIDE_EFFECTS (t
) = 1;
2890 /* No side-effects. */
2898 /* Gimplify the COMPONENT_REF, ARRAY_REF, REALPART_EXPR or IMAGPART_EXPR
2902 : min_lval '[' val ']'
2904 | compound_lval '[' val ']'
2905 | compound_lval '.' ID
2907 This is not part of the original SIMPLE definition, which separates
2908 array and member references, but it seems reasonable to handle them
2909 together. Also, this way we don't run into problems with union
2910 aliasing; gcc requires that for accesses through a union to alias, the
2911 union reference must be explicit, which was not always the case when we
2912 were splitting up array and member refs.
2914 PRE_P points to the sequence where side effects that must happen before
2915 *EXPR_P should be stored.
2917 POST_P points to the sequence where side effects that must happen after
2918 *EXPR_P should be stored. */
2920 static enum gimplify_status
2921 gimplify_compound_lval (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
2922 fallback_t fallback
)
2925 enum gimplify_status ret
= GS_ALL_DONE
, tret
;
2927 location_t loc
= EXPR_LOCATION (*expr_p
);
2928 tree expr
= *expr_p
;
2930 /* Create a stack of the subexpressions so later we can walk them in
2931 order from inner to outer. */
2932 auto_vec
<tree
, 10> expr_stack
;
2934 /* We can handle anything that get_inner_reference can deal with. */
2935 for (p
= expr_p
; ; p
= &TREE_OPERAND (*p
, 0))
2938 /* Fold INDIRECT_REFs now to turn them into ARRAY_REFs. */
2939 if (TREE_CODE (*p
) == INDIRECT_REF
)
2940 *p
= fold_indirect_ref_loc (loc
, *p
);
2942 if (handled_component_p (*p
))
2944 /* Expand DECL_VALUE_EXPR now. In some cases that may expose
2945 additional COMPONENT_REFs. */
2946 else if ((VAR_P (*p
) || TREE_CODE (*p
) == PARM_DECL
)
2947 && gimplify_var_or_parm_decl (p
) == GS_OK
)
2952 expr_stack
.safe_push (*p
);
2955 gcc_assert (expr_stack
.length ());
2957 /* Now EXPR_STACK is a stack of pointers to all the refs we've
2958 walked through and P points to the innermost expression.
2960 Java requires that we elaborated nodes in source order. That
2961 means we must gimplify the inner expression followed by each of
2962 the indices, in order. But we can't gimplify the inner
2963 expression until we deal with any variable bounds, sizes, or
2964 positions in order to deal with PLACEHOLDER_EXPRs.
2966 So we do this in three steps. First we deal with the annotations
2967 for any variables in the components, then we gimplify the base,
2968 then we gimplify any indices, from left to right. */
2969 for (i
= expr_stack
.length () - 1; i
>= 0; i
--)
2971 tree t
= expr_stack
[i
];
2973 if (TREE_CODE (t
) == ARRAY_REF
|| TREE_CODE (t
) == ARRAY_RANGE_REF
)
2975 /* Gimplify the low bound and element type size and put them into
2976 the ARRAY_REF. If these values are set, they have already been
2978 if (TREE_OPERAND (t
, 2) == NULL_TREE
)
2980 tree low
= unshare_expr (array_ref_low_bound (t
));
2981 if (!is_gimple_min_invariant (low
))
2983 TREE_OPERAND (t
, 2) = low
;
2984 tret
= gimplify_expr (&TREE_OPERAND (t
, 2), pre_p
,
2985 post_p
, is_gimple_reg
,
2987 ret
= MIN (ret
, tret
);
2992 tret
= gimplify_expr (&TREE_OPERAND (t
, 2), pre_p
, post_p
,
2993 is_gimple_reg
, fb_rvalue
);
2994 ret
= MIN (ret
, tret
);
2997 if (TREE_OPERAND (t
, 3) == NULL_TREE
)
2999 tree elmt_size
= array_ref_element_size (t
);
3000 if (!is_gimple_min_invariant (elmt_size
))
3002 elmt_size
= unshare_expr (elmt_size
);
3003 tree elmt_type
= TREE_TYPE (TREE_TYPE (TREE_OPERAND (t
, 0)));
3004 tree factor
= size_int (TYPE_ALIGN_UNIT (elmt_type
));
3006 /* Divide the element size by the alignment of the element
3008 elmt_size
= size_binop_loc (loc
, EXACT_DIV_EXPR
,
3011 TREE_OPERAND (t
, 3) = elmt_size
;
3012 tret
= gimplify_expr (&TREE_OPERAND (t
, 3), pre_p
,
3013 post_p
, is_gimple_reg
,
3015 ret
= MIN (ret
, tret
);
3020 tret
= gimplify_expr (&TREE_OPERAND (t
, 3), pre_p
, post_p
,
3021 is_gimple_reg
, fb_rvalue
);
3022 ret
= MIN (ret
, tret
);
3025 else if (TREE_CODE (t
) == COMPONENT_REF
)
3027 /* Set the field offset into T and gimplify it. */
3028 if (TREE_OPERAND (t
, 2) == NULL_TREE
)
3030 tree offset
= component_ref_field_offset (t
);
3031 if (!is_gimple_min_invariant (offset
))
3033 offset
= unshare_expr (offset
);
3034 tree field
= TREE_OPERAND (t
, 1);
3036 = size_int (DECL_OFFSET_ALIGN (field
) / BITS_PER_UNIT
);
3038 /* Divide the offset by its alignment. */
3039 offset
= size_binop_loc (loc
, EXACT_DIV_EXPR
,
3042 TREE_OPERAND (t
, 2) = offset
;
3043 tret
= gimplify_expr (&TREE_OPERAND (t
, 2), pre_p
,
3044 post_p
, is_gimple_reg
,
3046 ret
= MIN (ret
, tret
);
3051 tret
= gimplify_expr (&TREE_OPERAND (t
, 2), pre_p
, post_p
,
3052 is_gimple_reg
, fb_rvalue
);
3053 ret
= MIN (ret
, tret
);
3058 /* Step 2 is to gimplify the base expression. Make sure lvalue is set
3059 so as to match the min_lval predicate. Failure to do so may result
3060 in the creation of large aggregate temporaries. */
3061 tret
= gimplify_expr (p
, pre_p
, post_p
, is_gimple_min_lval
,
3062 fallback
| fb_lvalue
);
3063 ret
= MIN (ret
, tret
);
3065 /* And finally, the indices and operands of ARRAY_REF. During this
3066 loop we also remove any useless conversions. */
3067 for (; expr_stack
.length () > 0; )
3069 tree t
= expr_stack
.pop ();
3071 if (TREE_CODE (t
) == ARRAY_REF
|| TREE_CODE (t
) == ARRAY_RANGE_REF
)
3073 /* Gimplify the dimension. */
3074 if (!is_gimple_min_invariant (TREE_OPERAND (t
, 1)))
3076 tret
= gimplify_expr (&TREE_OPERAND (t
, 1), pre_p
, post_p
,
3077 is_gimple_val
, fb_rvalue
);
3078 ret
= MIN (ret
, tret
);
3082 STRIP_USELESS_TYPE_CONVERSION (TREE_OPERAND (t
, 0));
3084 /* The innermost expression P may have originally had
3085 TREE_SIDE_EFFECTS set which would have caused all the outer
3086 expressions in *EXPR_P leading to P to also have had
3087 TREE_SIDE_EFFECTS set. */
3088 recalculate_side_effects (t
);
3091 /* If the outermost expression is a COMPONENT_REF, canonicalize its type. */
3092 if ((fallback
& fb_rvalue
) && TREE_CODE (*expr_p
) == COMPONENT_REF
)
3094 canonicalize_component_ref (expr_p
);
3097 expr_stack
.release ();
3099 gcc_assert (*expr_p
== expr
|| ret
!= GS_ALL_DONE
);
3104 /* Gimplify the self modifying expression pointed to by EXPR_P
3107 PRE_P points to the list where side effects that must happen before
3108 *EXPR_P should be stored.
3110 POST_P points to the list where side effects that must happen after
3111 *EXPR_P should be stored.
3113 WANT_VALUE is nonzero iff we want to use the value of this expression
3114 in another expression.
3116 ARITH_TYPE is the type the computation should be performed in. */
3118 enum gimplify_status
3119 gimplify_self_mod_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
3120 bool want_value
, tree arith_type
)
3122 enum tree_code code
;
3123 tree lhs
, lvalue
, rhs
, t1
;
3124 gimple_seq post
= NULL
, *orig_post_p
= post_p
;
3126 enum tree_code arith_code
;
3127 enum gimplify_status ret
;
3128 location_t loc
= EXPR_LOCATION (*expr_p
);
3130 code
= TREE_CODE (*expr_p
);
3132 gcc_assert (code
== POSTINCREMENT_EXPR
|| code
== POSTDECREMENT_EXPR
3133 || code
== PREINCREMENT_EXPR
|| code
== PREDECREMENT_EXPR
);
3135 /* Prefix or postfix? */
3136 if (code
== POSTINCREMENT_EXPR
|| code
== POSTDECREMENT_EXPR
)
3137 /* Faster to treat as prefix if result is not used. */
3138 postfix
= want_value
;
3142 /* For postfix, make sure the inner expression's post side effects
3143 are executed after side effects from this expression. */
3147 /* Add or subtract? */
3148 if (code
== PREINCREMENT_EXPR
|| code
== POSTINCREMENT_EXPR
)
3149 arith_code
= PLUS_EXPR
;
3151 arith_code
= MINUS_EXPR
;
3153 /* Gimplify the LHS into a GIMPLE lvalue. */
3154 lvalue
= TREE_OPERAND (*expr_p
, 0);
3155 ret
= gimplify_expr (&lvalue
, pre_p
, post_p
, is_gimple_lvalue
, fb_lvalue
);
3156 if (ret
== GS_ERROR
)
3159 /* Extract the operands to the arithmetic operation. */
3161 rhs
= TREE_OPERAND (*expr_p
, 1);
3163 /* For postfix operator, we evaluate the LHS to an rvalue and then use
3164 that as the result value and in the postqueue operation. */
3167 ret
= gimplify_expr (&lhs
, pre_p
, post_p
, is_gimple_val
, fb_rvalue
);
3168 if (ret
== GS_ERROR
)
3171 lhs
= get_initialized_tmp_var (lhs
, pre_p
);
3174 /* For POINTERs increment, use POINTER_PLUS_EXPR. */
3175 if (POINTER_TYPE_P (TREE_TYPE (lhs
)))
3177 rhs
= convert_to_ptrofftype_loc (loc
, rhs
);
3178 if (arith_code
== MINUS_EXPR
)
3179 rhs
= fold_build1_loc (loc
, NEGATE_EXPR
, TREE_TYPE (rhs
), rhs
);
3180 t1
= fold_build2 (POINTER_PLUS_EXPR
, TREE_TYPE (*expr_p
), lhs
, rhs
);
3183 t1
= fold_convert (TREE_TYPE (*expr_p
),
3184 fold_build2 (arith_code
, arith_type
,
3185 fold_convert (arith_type
, lhs
),
3186 fold_convert (arith_type
, rhs
)));
3190 gimplify_assign (lvalue
, t1
, pre_p
);
3191 gimplify_seq_add_seq (orig_post_p
, post
);
3197 *expr_p
= build2 (MODIFY_EXPR
, TREE_TYPE (lvalue
), lvalue
, t1
);
3202 /* If *EXPR_P has a variable sized type, wrap it in a WITH_SIZE_EXPR. */
3205 maybe_with_size_expr (tree
*expr_p
)
3207 tree expr
= *expr_p
;
3208 tree type
= TREE_TYPE (expr
);
3211 /* If we've already wrapped this or the type is error_mark_node, we can't do
3213 if (TREE_CODE (expr
) == WITH_SIZE_EXPR
3214 || type
== error_mark_node
)
3217 /* If the size isn't known or is a constant, we have nothing to do. */
3218 size
= TYPE_SIZE_UNIT (type
);
3219 if (!size
|| poly_int_tree_p (size
))
3222 /* Otherwise, make a WITH_SIZE_EXPR. */
3223 size
= unshare_expr (size
);
3224 size
= SUBSTITUTE_PLACEHOLDER_IN_EXPR (size
, expr
);
3225 *expr_p
= build2 (WITH_SIZE_EXPR
, type
, expr
, size
);
3228 /* Helper for gimplify_call_expr. Gimplify a single argument *ARG_P
3229 Store any side-effects in PRE_P. CALL_LOCATION is the location of
3230 the CALL_EXPR. If ALLOW_SSA is set the actual parameter may be
3231 gimplified to an SSA name. */
3233 enum gimplify_status
3234 gimplify_arg (tree
*arg_p
, gimple_seq
*pre_p
, location_t call_location
,
3237 bool (*test
) (tree
);
3240 /* In general, we allow lvalues for function arguments to avoid
3241 extra overhead of copying large aggregates out of even larger
3242 aggregates into temporaries only to copy the temporaries to
3243 the argument list. Make optimizers happy by pulling out to
3244 temporaries those types that fit in registers. */
3245 if (is_gimple_reg_type (TREE_TYPE (*arg_p
)))
3246 test
= is_gimple_val
, fb
= fb_rvalue
;
3249 test
= is_gimple_lvalue
, fb
= fb_either
;
3250 /* Also strip a TARGET_EXPR that would force an extra copy. */
3251 if (TREE_CODE (*arg_p
) == TARGET_EXPR
)
3253 tree init
= TARGET_EXPR_INITIAL (*arg_p
);
3255 && !VOID_TYPE_P (TREE_TYPE (init
)))
3260 /* If this is a variable sized type, we must remember the size. */
3261 maybe_with_size_expr (arg_p
);
3263 /* FIXME diagnostics: This will mess up gcc.dg/Warray-bounds.c. */
3264 /* Make sure arguments have the same location as the function call
3266 protected_set_expr_location (*arg_p
, call_location
);
3268 /* There is a sequence point before a function call. Side effects in
3269 the argument list must occur before the actual call. So, when
3270 gimplifying arguments, force gimplify_expr to use an internal
3271 post queue which is then appended to the end of PRE_P. */
3272 return gimplify_expr (arg_p
, pre_p
, NULL
, test
, fb
, allow_ssa
);
3275 /* Don't fold inside offloading or taskreg regions: it can break code by
3276 adding decl references that weren't in the source. We'll do it during
3277 omplower pass instead. */
3280 maybe_fold_stmt (gimple_stmt_iterator
*gsi
)
3282 struct gimplify_omp_ctx
*ctx
;
3283 for (ctx
= gimplify_omp_ctxp
; ctx
; ctx
= ctx
->outer_context
)
3284 if ((ctx
->region_type
& (ORT_TARGET
| ORT_PARALLEL
| ORT_TASK
)) != 0)
3286 else if ((ctx
->region_type
& ORT_HOST_TEAMS
) == ORT_HOST_TEAMS
)
3288 /* Delay folding of builtins until the IL is in consistent state
3289 so the diagnostic machinery can do a better job. */
3290 if (gimple_call_builtin_p (gsi_stmt (*gsi
)))
3292 return fold_stmt (gsi
);
3295 /* Gimplify the CALL_EXPR node *EXPR_P into the GIMPLE sequence PRE_P.
3296 WANT_VALUE is true if the result of the call is desired. */
3298 static enum gimplify_status
3299 gimplify_call_expr (tree
*expr_p
, gimple_seq
*pre_p
, bool want_value
)
3301 tree fndecl
, parms
, p
, fnptrtype
;
3302 enum gimplify_status ret
;
3305 bool builtin_va_start_p
= false;
3306 location_t loc
= EXPR_LOCATION (*expr_p
);
3308 gcc_assert (TREE_CODE (*expr_p
) == CALL_EXPR
);
3310 /* For reliable diagnostics during inlining, it is necessary that
3311 every call_expr be annotated with file and line. */
3312 if (! EXPR_HAS_LOCATION (*expr_p
))
3313 SET_EXPR_LOCATION (*expr_p
, input_location
);
3315 /* Gimplify internal functions created in the FEs. */
3316 if (CALL_EXPR_FN (*expr_p
) == NULL_TREE
)
3321 nargs
= call_expr_nargs (*expr_p
);
3322 enum internal_fn ifn
= CALL_EXPR_IFN (*expr_p
);
3323 auto_vec
<tree
> vargs (nargs
);
3325 for (i
= 0; i
< nargs
; i
++)
3327 gimplify_arg (&CALL_EXPR_ARG (*expr_p
, i
), pre_p
,
3328 EXPR_LOCATION (*expr_p
));
3329 vargs
.quick_push (CALL_EXPR_ARG (*expr_p
, i
));
3332 gcall
*call
= gimple_build_call_internal_vec (ifn
, vargs
);
3333 gimple_call_set_nothrow (call
, TREE_NOTHROW (*expr_p
));
3334 gimplify_seq_add_stmt (pre_p
, call
);
3338 /* This may be a call to a builtin function.
3340 Builtin function calls may be transformed into different
3341 (and more efficient) builtin function calls under certain
3342 circumstances. Unfortunately, gimplification can muck things
3343 up enough that the builtin expanders are not aware that certain
3344 transformations are still valid.
3346 So we attempt transformation/gimplification of the call before
3347 we gimplify the CALL_EXPR. At this time we do not manage to
3348 transform all calls in the same manner as the expanders do, but
3349 we do transform most of them. */
3350 fndecl
= get_callee_fndecl (*expr_p
);
3351 if (fndecl
&& fndecl_built_in_p (fndecl
, BUILT_IN_NORMAL
))
3352 switch (DECL_FUNCTION_CODE (fndecl
))
3354 CASE_BUILT_IN_ALLOCA
:
3355 /* If the call has been built for a variable-sized object, then we
3356 want to restore the stack level when the enclosing BIND_EXPR is
3357 exited to reclaim the allocated space; otherwise, we precisely
3358 need to do the opposite and preserve the latest stack level. */
3359 if (CALL_ALLOCA_FOR_VAR_P (*expr_p
))
3360 gimplify_ctxp
->save_stack
= true;
3362 gimplify_ctxp
->keep_stack
= true;
3365 case BUILT_IN_VA_START
:
3367 builtin_va_start_p
= TRUE
;
3368 if (call_expr_nargs (*expr_p
) < 2)
3370 error ("too few arguments to function %<va_start%>");
3371 *expr_p
= build_empty_stmt (EXPR_LOCATION (*expr_p
));
3375 if (fold_builtin_next_arg (*expr_p
, true))
3377 *expr_p
= build_empty_stmt (EXPR_LOCATION (*expr_p
));
3383 case BUILT_IN_EH_RETURN
:
3384 cfun
->calls_eh_return
= true;
3390 if (fndecl
&& fndecl_built_in_p (fndecl
))
3392 tree new_tree
= fold_call_expr (input_location
, *expr_p
, !want_value
);
3393 if (new_tree
&& new_tree
!= *expr_p
)
3395 /* There was a transformation of this call which computes the
3396 same value, but in a more efficient way. Return and try
3403 /* Remember the original function pointer type. */
3404 fnptrtype
= TREE_TYPE (CALL_EXPR_FN (*expr_p
));
3409 && (cfun
->curr_properties
& PROP_gimple_any
) == 0)
3411 tree variant
= omp_resolve_declare_variant (fndecl
);
3412 if (variant
!= fndecl
)
3413 CALL_EXPR_FN (*expr_p
) = build1 (ADDR_EXPR
, fnptrtype
, variant
);
3416 /* There is a sequence point before the call, so any side effects in
3417 the calling expression must occur before the actual call. Force
3418 gimplify_expr to use an internal post queue. */
3419 ret
= gimplify_expr (&CALL_EXPR_FN (*expr_p
), pre_p
, NULL
,
3420 is_gimple_call_addr
, fb_rvalue
);
3422 nargs
= call_expr_nargs (*expr_p
);
3424 /* Get argument types for verification. */
3425 fndecl
= get_callee_fndecl (*expr_p
);
3428 parms
= TYPE_ARG_TYPES (TREE_TYPE (fndecl
));
3430 parms
= TYPE_ARG_TYPES (TREE_TYPE (fnptrtype
));
3432 if (fndecl
&& DECL_ARGUMENTS (fndecl
))
3433 p
= DECL_ARGUMENTS (fndecl
);
3438 for (i
= 0; i
< nargs
&& p
; i
++, p
= TREE_CHAIN (p
))
3441 /* If the last argument is __builtin_va_arg_pack () and it is not
3442 passed as a named argument, decrease the number of CALL_EXPR
3443 arguments and set instead the CALL_EXPR_VA_ARG_PACK flag. */
3446 && TREE_CODE (CALL_EXPR_ARG (*expr_p
, nargs
- 1)) == CALL_EXPR
)
3448 tree last_arg
= CALL_EXPR_ARG (*expr_p
, nargs
- 1);
3449 tree last_arg_fndecl
= get_callee_fndecl (last_arg
);
3452 && fndecl_built_in_p (last_arg_fndecl
, BUILT_IN_VA_ARG_PACK
))
3454 tree call
= *expr_p
;
3457 *expr_p
= build_call_array_loc (loc
, TREE_TYPE (call
),
3458 CALL_EXPR_FN (call
),
3459 nargs
, CALL_EXPR_ARGP (call
));
3461 /* Copy all CALL_EXPR flags, location and block, except
3462 CALL_EXPR_VA_ARG_PACK flag. */
3463 CALL_EXPR_STATIC_CHAIN (*expr_p
) = CALL_EXPR_STATIC_CHAIN (call
);
3464 CALL_EXPR_TAILCALL (*expr_p
) = CALL_EXPR_TAILCALL (call
);
3465 CALL_EXPR_RETURN_SLOT_OPT (*expr_p
)
3466 = CALL_EXPR_RETURN_SLOT_OPT (call
);
3467 CALL_FROM_THUNK_P (*expr_p
) = CALL_FROM_THUNK_P (call
);
3468 SET_EXPR_LOCATION (*expr_p
, EXPR_LOCATION (call
));
3470 /* Set CALL_EXPR_VA_ARG_PACK. */
3471 CALL_EXPR_VA_ARG_PACK (*expr_p
) = 1;
3475 /* If the call returns twice then after building the CFG the call
3476 argument computations will no longer dominate the call because
3477 we add an abnormal incoming edge to the call. So do not use SSA
3479 bool returns_twice
= call_expr_flags (*expr_p
) & ECF_RETURNS_TWICE
;
3481 /* Gimplify the function arguments. */
3484 for (i
= (PUSH_ARGS_REVERSED
? nargs
- 1 : 0);
3485 PUSH_ARGS_REVERSED
? i
>= 0 : i
< nargs
;
3486 PUSH_ARGS_REVERSED
? i
-- : i
++)
3488 enum gimplify_status t
;
3490 /* Avoid gimplifying the second argument to va_start, which needs to
3491 be the plain PARM_DECL. */
3492 if ((i
!= 1) || !builtin_va_start_p
)
3494 t
= gimplify_arg (&CALL_EXPR_ARG (*expr_p
, i
), pre_p
,
3495 EXPR_LOCATION (*expr_p
), ! returns_twice
);
3503 /* Gimplify the static chain. */
3504 if (CALL_EXPR_STATIC_CHAIN (*expr_p
))
3506 if (fndecl
&& !DECL_STATIC_CHAIN (fndecl
))
3507 CALL_EXPR_STATIC_CHAIN (*expr_p
) = NULL
;
3510 enum gimplify_status t
;
3511 t
= gimplify_arg (&CALL_EXPR_STATIC_CHAIN (*expr_p
), pre_p
,
3512 EXPR_LOCATION (*expr_p
), ! returns_twice
);
3518 /* Verify the function result. */
3519 if (want_value
&& fndecl
3520 && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fnptrtype
))))
3522 error_at (loc
, "using result of function returning %<void%>");
3526 /* Try this again in case gimplification exposed something. */
3527 if (ret
!= GS_ERROR
)
3529 tree new_tree
= fold_call_expr (input_location
, *expr_p
, !want_value
);
3531 if (new_tree
&& new_tree
!= *expr_p
)
3533 /* There was a transformation of this call which computes the
3534 same value, but in a more efficient way. Return and try
3542 *expr_p
= error_mark_node
;
3546 /* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its
3547 decl. This allows us to eliminate redundant or useless
3548 calls to "const" functions. */
3549 if (TREE_CODE (*expr_p
) == CALL_EXPR
)
3551 int flags
= call_expr_flags (*expr_p
);
3552 if (flags
& (ECF_CONST
| ECF_PURE
)
3553 /* An infinite loop is considered a side effect. */
3554 && !(flags
& (ECF_LOOPING_CONST_OR_PURE
)))
3555 TREE_SIDE_EFFECTS (*expr_p
) = 0;
3558 /* If the value is not needed by the caller, emit a new GIMPLE_CALL
3559 and clear *EXPR_P. Otherwise, leave *EXPR_P in its gimplified
3560 form and delegate the creation of a GIMPLE_CALL to
3561 gimplify_modify_expr. This is always possible because when
3562 WANT_VALUE is true, the caller wants the result of this call into
3563 a temporary, which means that we will emit an INIT_EXPR in
3564 internal_get_tmp_var which will then be handled by
3565 gimplify_modify_expr. */
3568 /* The CALL_EXPR in *EXPR_P is already in GIMPLE form, so all we
3569 have to do is replicate it as a GIMPLE_CALL tuple. */
3570 gimple_stmt_iterator gsi
;
3571 call
= gimple_build_call_from_tree (*expr_p
, fnptrtype
);
3572 notice_special_calls (call
);
3573 gimplify_seq_add_stmt (pre_p
, call
);
3574 gsi
= gsi_last (*pre_p
);
3575 maybe_fold_stmt (&gsi
);
3576 *expr_p
= NULL_TREE
;
3579 /* Remember the original function type. */
3580 CALL_EXPR_FN (*expr_p
) = build1 (NOP_EXPR
, fnptrtype
,
3581 CALL_EXPR_FN (*expr_p
));
3586 /* Handle shortcut semantics in the predicate operand of a COND_EXPR by
3587 rewriting it into multiple COND_EXPRs, and possibly GOTO_EXPRs.
3589 TRUE_LABEL_P and FALSE_LABEL_P point to the labels to jump to if the
3590 condition is true or false, respectively. If null, we should generate
3591 our own to skip over the evaluation of this specific expression.
3593 LOCUS is the source location of the COND_EXPR.
3595 This function is the tree equivalent of do_jump.
3597 shortcut_cond_r should only be called by shortcut_cond_expr. */
3600 shortcut_cond_r (tree pred
, tree
*true_label_p
, tree
*false_label_p
,
3603 tree local_label
= NULL_TREE
;
3604 tree t
, expr
= NULL
;
3606 /* OK, it's not a simple case; we need to pull apart the COND_EXPR to
3607 retain the shortcut semantics. Just insert the gotos here;
3608 shortcut_cond_expr will append the real blocks later. */
3609 if (TREE_CODE (pred
) == TRUTH_ANDIF_EXPR
)
3611 location_t new_locus
;
3613 /* Turn if (a && b) into
3615 if (a); else goto no;
3616 if (b) goto yes; else goto no;
3619 if (false_label_p
== NULL
)
3620 false_label_p
= &local_label
;
3622 /* Keep the original source location on the first 'if'. */
3623 t
= shortcut_cond_r (TREE_OPERAND (pred
, 0), NULL
, false_label_p
, locus
);
3624 append_to_statement_list (t
, &expr
);
3626 /* Set the source location of the && on the second 'if'. */
3627 new_locus
= rexpr_location (pred
, locus
);
3628 t
= shortcut_cond_r (TREE_OPERAND (pred
, 1), true_label_p
, false_label_p
,
3630 append_to_statement_list (t
, &expr
);
3632 else if (TREE_CODE (pred
) == TRUTH_ORIF_EXPR
)
3634 location_t new_locus
;
3636 /* Turn if (a || b) into
3639 if (b) goto yes; else goto no;
3642 if (true_label_p
== NULL
)
3643 true_label_p
= &local_label
;
3645 /* Keep the original source location on the first 'if'. */
3646 t
= shortcut_cond_r (TREE_OPERAND (pred
, 0), true_label_p
, NULL
, locus
);
3647 append_to_statement_list (t
, &expr
);
3649 /* Set the source location of the || on the second 'if'. */
3650 new_locus
= rexpr_location (pred
, locus
);
3651 t
= shortcut_cond_r (TREE_OPERAND (pred
, 1), true_label_p
, false_label_p
,
3653 append_to_statement_list (t
, &expr
);
3655 else if (TREE_CODE (pred
) == COND_EXPR
3656 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred
, 1)))
3657 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred
, 2))))
3659 location_t new_locus
;
3661 /* As long as we're messing with gotos, turn if (a ? b : c) into
3663 if (b) goto yes; else goto no;
3665 if (c) goto yes; else goto no;
3667 Don't do this if one of the arms has void type, which can happen
3668 in C++ when the arm is throw. */
3670 /* Keep the original source location on the first 'if'. Set the source
3671 location of the ? on the second 'if'. */
3672 new_locus
= rexpr_location (pred
, locus
);
3673 expr
= build3 (COND_EXPR
, void_type_node
, TREE_OPERAND (pred
, 0),
3674 shortcut_cond_r (TREE_OPERAND (pred
, 1), true_label_p
,
3675 false_label_p
, locus
),
3676 shortcut_cond_r (TREE_OPERAND (pred
, 2), true_label_p
,
3677 false_label_p
, new_locus
));
3681 expr
= build3 (COND_EXPR
, void_type_node
, pred
,
3682 build_and_jump (true_label_p
),
3683 build_and_jump (false_label_p
));
3684 SET_EXPR_LOCATION (expr
, locus
);
3689 t
= build1 (LABEL_EXPR
, void_type_node
, local_label
);
3690 append_to_statement_list (t
, &expr
);
3696 /* If EXPR is a GOTO_EXPR, return it. If it is a STATEMENT_LIST, skip
3697 any of its leading DEBUG_BEGIN_STMTS and recurse on the subsequent
3698 statement, if it is the last one. Otherwise, return NULL. */
3701 find_goto (tree expr
)
3706 if (TREE_CODE (expr
) == GOTO_EXPR
)
3709 if (TREE_CODE (expr
) != STATEMENT_LIST
)
3712 tree_stmt_iterator i
= tsi_start (expr
);
3714 while (!tsi_end_p (i
) && TREE_CODE (tsi_stmt (i
)) == DEBUG_BEGIN_STMT
)
3717 if (!tsi_one_before_end_p (i
))
3720 return find_goto (tsi_stmt (i
));
3723 /* Same as find_goto, except that it returns NULL if the destination
3724 is not a LABEL_DECL. */
3727 find_goto_label (tree expr
)
3729 tree dest
= find_goto (expr
);
3730 if (dest
&& TREE_CODE (GOTO_DESTINATION (dest
)) == LABEL_DECL
)
3735 /* Given a conditional expression EXPR with short-circuit boolean
3736 predicates using TRUTH_ANDIF_EXPR or TRUTH_ORIF_EXPR, break the
3737 predicate apart into the equivalent sequence of conditionals. */
3740 shortcut_cond_expr (tree expr
)
3742 tree pred
= TREE_OPERAND (expr
, 0);
3743 tree then_
= TREE_OPERAND (expr
, 1);
3744 tree else_
= TREE_OPERAND (expr
, 2);
3745 tree true_label
, false_label
, end_label
, t
;
3747 tree
*false_label_p
;
3748 bool emit_end
, emit_false
, jump_over_else
;
3749 bool then_se
= then_
&& TREE_SIDE_EFFECTS (then_
);
3750 bool else_se
= else_
&& TREE_SIDE_EFFECTS (else_
);
3752 /* First do simple transformations. */
3755 /* If there is no 'else', turn
3758 if (a) if (b) then c. */
3759 while (TREE_CODE (pred
) == TRUTH_ANDIF_EXPR
)
3761 /* Keep the original source location on the first 'if'. */
3762 location_t locus
= EXPR_LOC_OR_LOC (expr
, input_location
);
3763 TREE_OPERAND (expr
, 0) = TREE_OPERAND (pred
, 1);
3764 /* Set the source location of the && on the second 'if'. */
3765 if (rexpr_has_location (pred
))
3766 SET_EXPR_LOCATION (expr
, rexpr_location (pred
));
3767 then_
= shortcut_cond_expr (expr
);
3768 then_se
= then_
&& TREE_SIDE_EFFECTS (then_
);
3769 pred
= TREE_OPERAND (pred
, 0);
3770 expr
= build3 (COND_EXPR
, void_type_node
, pred
, then_
, NULL_TREE
);
3771 SET_EXPR_LOCATION (expr
, locus
);
3777 /* If there is no 'then', turn
3780 if (a); else if (b); else d. */
3781 while (TREE_CODE (pred
) == TRUTH_ORIF_EXPR
)
3783 /* Keep the original source location on the first 'if'. */
3784 location_t locus
= EXPR_LOC_OR_LOC (expr
, input_location
);
3785 TREE_OPERAND (expr
, 0) = TREE_OPERAND (pred
, 1);
3786 /* Set the source location of the || on the second 'if'. */
3787 if (rexpr_has_location (pred
))
3788 SET_EXPR_LOCATION (expr
, rexpr_location (pred
));
3789 else_
= shortcut_cond_expr (expr
);
3790 else_se
= else_
&& TREE_SIDE_EFFECTS (else_
);
3791 pred
= TREE_OPERAND (pred
, 0);
3792 expr
= build3 (COND_EXPR
, void_type_node
, pred
, NULL_TREE
, else_
);
3793 SET_EXPR_LOCATION (expr
, locus
);
3797 /* If we're done, great. */
3798 if (TREE_CODE (pred
) != TRUTH_ANDIF_EXPR
3799 && TREE_CODE (pred
) != TRUTH_ORIF_EXPR
)
3802 /* Otherwise we need to mess with gotos. Change
3805 if (a); else goto no;
3808 and recursively gimplify the condition. */
3810 true_label
= false_label
= end_label
= NULL_TREE
;
3812 /* If our arms just jump somewhere, hijack those labels so we don't
3813 generate jumps to jumps. */
3815 if (tree then_goto
= find_goto_label (then_
))
3817 true_label
= GOTO_DESTINATION (then_goto
);
3822 if (tree else_goto
= find_goto_label (else_
))
3824 false_label
= GOTO_DESTINATION (else_goto
);
3829 /* If we aren't hijacking a label for the 'then' branch, it falls through. */
3831 true_label_p
= &true_label
;
3833 true_label_p
= NULL
;
3835 /* The 'else' branch also needs a label if it contains interesting code. */
3836 if (false_label
|| else_se
)
3837 false_label_p
= &false_label
;
3839 false_label_p
= NULL
;
3841 /* If there was nothing else in our arms, just forward the label(s). */
3842 if (!then_se
&& !else_se
)
3843 return shortcut_cond_r (pred
, true_label_p
, false_label_p
,
3844 EXPR_LOC_OR_LOC (expr
, input_location
));
3846 /* If our last subexpression already has a terminal label, reuse it. */
3848 t
= expr_last (else_
);
3850 t
= expr_last (then_
);
3853 if (t
&& TREE_CODE (t
) == LABEL_EXPR
)
3854 end_label
= LABEL_EXPR_LABEL (t
);
3856 /* If we don't care about jumping to the 'else' branch, jump to the end
3857 if the condition is false. */
3859 false_label_p
= &end_label
;
3861 /* We only want to emit these labels if we aren't hijacking them. */
3862 emit_end
= (end_label
== NULL_TREE
);
3863 emit_false
= (false_label
== NULL_TREE
);
3865 /* We only emit the jump over the else clause if we have to--if the
3866 then clause may fall through. Otherwise we can wind up with a
3867 useless jump and a useless label at the end of gimplified code,
3868 which will cause us to think that this conditional as a whole
3869 falls through even if it doesn't. If we then inline a function
3870 which ends with such a condition, that can cause us to issue an
3871 inappropriate warning about control reaching the end of a
3872 non-void function. */
3873 jump_over_else
= block_may_fallthru (then_
);
3875 pred
= shortcut_cond_r (pred
, true_label_p
, false_label_p
,
3876 EXPR_LOC_OR_LOC (expr
, input_location
));
3879 append_to_statement_list (pred
, &expr
);
3881 append_to_statement_list (then_
, &expr
);
3886 tree last
= expr_last (expr
);
3887 t
= build_and_jump (&end_label
);
3888 if (rexpr_has_location (last
))
3889 SET_EXPR_LOCATION (t
, rexpr_location (last
));
3890 append_to_statement_list (t
, &expr
);
3894 t
= build1 (LABEL_EXPR
, void_type_node
, false_label
);
3895 append_to_statement_list (t
, &expr
);
3897 append_to_statement_list (else_
, &expr
);
3899 if (emit_end
&& end_label
)
3901 t
= build1 (LABEL_EXPR
, void_type_node
, end_label
);
3902 append_to_statement_list (t
, &expr
);
3908 /* EXPR is used in a boolean context; make sure it has BOOLEAN_TYPE. */
3911 gimple_boolify (tree expr
)
3913 tree type
= TREE_TYPE (expr
);
3914 location_t loc
= EXPR_LOCATION (expr
);
3916 if (TREE_CODE (expr
) == NE_EXPR
3917 && TREE_CODE (TREE_OPERAND (expr
, 0)) == CALL_EXPR
3918 && integer_zerop (TREE_OPERAND (expr
, 1)))
3920 tree call
= TREE_OPERAND (expr
, 0);
3921 tree fn
= get_callee_fndecl (call
);
3923 /* For __builtin_expect ((long) (x), y) recurse into x as well
3924 if x is truth_value_p. */
3926 && fndecl_built_in_p (fn
, BUILT_IN_EXPECT
)
3927 && call_expr_nargs (call
) == 2)
3929 tree arg
= CALL_EXPR_ARG (call
, 0);
3932 if (TREE_CODE (arg
) == NOP_EXPR
3933 && TREE_TYPE (arg
) == TREE_TYPE (call
))
3934 arg
= TREE_OPERAND (arg
, 0);
3935 if (truth_value_p (TREE_CODE (arg
)))
3937 arg
= gimple_boolify (arg
);
3938 CALL_EXPR_ARG (call
, 0)
3939 = fold_convert_loc (loc
, TREE_TYPE (call
), arg
);
3945 switch (TREE_CODE (expr
))
3947 case TRUTH_AND_EXPR
:
3949 case TRUTH_XOR_EXPR
:
3950 case TRUTH_ANDIF_EXPR
:
3951 case TRUTH_ORIF_EXPR
:
3952 /* Also boolify the arguments of truth exprs. */
3953 TREE_OPERAND (expr
, 1) = gimple_boolify (TREE_OPERAND (expr
, 1));
3956 case TRUTH_NOT_EXPR
:
3957 TREE_OPERAND (expr
, 0) = gimple_boolify (TREE_OPERAND (expr
, 0));
3959 /* These expressions always produce boolean results. */
3960 if (TREE_CODE (type
) != BOOLEAN_TYPE
)
3961 TREE_TYPE (expr
) = boolean_type_node
;
3965 switch ((enum annot_expr_kind
) TREE_INT_CST_LOW (TREE_OPERAND (expr
, 1)))
3967 case annot_expr_ivdep_kind
:
3968 case annot_expr_unroll_kind
:
3969 case annot_expr_no_vector_kind
:
3970 case annot_expr_vector_kind
:
3971 case annot_expr_parallel_kind
:
3972 TREE_OPERAND (expr
, 0) = gimple_boolify (TREE_OPERAND (expr
, 0));
3973 if (TREE_CODE (type
) != BOOLEAN_TYPE
)
3974 TREE_TYPE (expr
) = boolean_type_node
;
3981 if (COMPARISON_CLASS_P (expr
))
3983 /* There expressions always prduce boolean results. */
3984 if (TREE_CODE (type
) != BOOLEAN_TYPE
)
3985 TREE_TYPE (expr
) = boolean_type_node
;
3988 /* Other expressions that get here must have boolean values, but
3989 might need to be converted to the appropriate mode. */
3990 if (TREE_CODE (type
) == BOOLEAN_TYPE
)
3992 return fold_convert_loc (loc
, boolean_type_node
, expr
);
3996 /* Given a conditional expression *EXPR_P without side effects, gimplify
3997 its operands. New statements are inserted to PRE_P. */
3999 static enum gimplify_status
4000 gimplify_pure_cond_expr (tree
*expr_p
, gimple_seq
*pre_p
)
4002 tree expr
= *expr_p
, cond
;
4003 enum gimplify_status ret
, tret
;
4004 enum tree_code code
;
4006 cond
= gimple_boolify (COND_EXPR_COND (expr
));
4008 /* We need to handle && and || specially, as their gimplification
4009 creates pure cond_expr, thus leading to an infinite cycle otherwise. */
4010 code
= TREE_CODE (cond
);
4011 if (code
== TRUTH_ANDIF_EXPR
)
4012 TREE_SET_CODE (cond
, TRUTH_AND_EXPR
);
4013 else if (code
== TRUTH_ORIF_EXPR
)
4014 TREE_SET_CODE (cond
, TRUTH_OR_EXPR
);
4015 ret
= gimplify_expr (&cond
, pre_p
, NULL
, is_gimple_condexpr
, fb_rvalue
);
4016 COND_EXPR_COND (*expr_p
) = cond
;
4018 tret
= gimplify_expr (&COND_EXPR_THEN (expr
), pre_p
, NULL
,
4019 is_gimple_val
, fb_rvalue
);
4020 ret
= MIN (ret
, tret
);
4021 tret
= gimplify_expr (&COND_EXPR_ELSE (expr
), pre_p
, NULL
,
4022 is_gimple_val
, fb_rvalue
);
4024 return MIN (ret
, tret
);
4027 /* Return true if evaluating EXPR could trap.
4028 EXPR is GENERIC, while tree_could_trap_p can be called
4032 generic_expr_could_trap_p (tree expr
)
4036 if (!expr
|| is_gimple_val (expr
))
4039 if (!EXPR_P (expr
) || tree_could_trap_p (expr
))
4042 n
= TREE_OPERAND_LENGTH (expr
);
4043 for (i
= 0; i
< n
; i
++)
4044 if (generic_expr_could_trap_p (TREE_OPERAND (expr
, i
)))
4050 /* Convert the conditional expression pointed to by EXPR_P '(p) ? a : b;'
4059 The second form is used when *EXPR_P is of type void.
4061 PRE_P points to the list where side effects that must happen before
4062 *EXPR_P should be stored. */
4064 static enum gimplify_status
4065 gimplify_cond_expr (tree
*expr_p
, gimple_seq
*pre_p
, fallback_t fallback
)
4067 tree expr
= *expr_p
;
4068 tree type
= TREE_TYPE (expr
);
4069 location_t loc
= EXPR_LOCATION (expr
);
4070 tree tmp
, arm1
, arm2
;
4071 enum gimplify_status ret
;
4072 tree label_true
, label_false
, label_cont
;
4073 bool have_then_clause_p
, have_else_clause_p
;
4075 enum tree_code pred_code
;
4076 gimple_seq seq
= NULL
;
4078 /* If this COND_EXPR has a value, copy the values into a temporary within
4080 if (!VOID_TYPE_P (type
))
4082 tree then_
= TREE_OPERAND (expr
, 1), else_
= TREE_OPERAND (expr
, 2);
4085 /* If either an rvalue is ok or we do not require an lvalue, create the
4086 temporary. But we cannot do that if the type is addressable. */
4087 if (((fallback
& fb_rvalue
) || !(fallback
& fb_lvalue
))
4088 && !TREE_ADDRESSABLE (type
))
4090 if (gimplify_ctxp
->allow_rhs_cond_expr
4091 /* If either branch has side effects or could trap, it can't be
4092 evaluated unconditionally. */
4093 && !TREE_SIDE_EFFECTS (then_
)
4094 && !generic_expr_could_trap_p (then_
)
4095 && !TREE_SIDE_EFFECTS (else_
)
4096 && !generic_expr_could_trap_p (else_
))
4097 return gimplify_pure_cond_expr (expr_p
, pre_p
);
4099 tmp
= create_tmp_var (type
, "iftmp");
4103 /* Otherwise, only create and copy references to the values. */
4106 type
= build_pointer_type (type
);
4108 if (!VOID_TYPE_P (TREE_TYPE (then_
)))
4109 then_
= build_fold_addr_expr_loc (loc
, then_
);
4111 if (!VOID_TYPE_P (TREE_TYPE (else_
)))
4112 else_
= build_fold_addr_expr_loc (loc
, else_
);
4115 = build3 (COND_EXPR
, type
, TREE_OPERAND (expr
, 0), then_
, else_
);
4117 tmp
= create_tmp_var (type
, "iftmp");
4118 result
= build_simple_mem_ref_loc (loc
, tmp
);
4121 /* Build the new then clause, `tmp = then_;'. But don't build the
4122 assignment if the value is void; in C++ it can be if it's a throw. */
4123 if (!VOID_TYPE_P (TREE_TYPE (then_
)))
4124 TREE_OPERAND (expr
, 1) = build2 (INIT_EXPR
, type
, tmp
, then_
);
4126 /* Similarly, build the new else clause, `tmp = else_;'. */
4127 if (!VOID_TYPE_P (TREE_TYPE (else_
)))
4128 TREE_OPERAND (expr
, 2) = build2 (INIT_EXPR
, type
, tmp
, else_
);
4130 TREE_TYPE (expr
) = void_type_node
;
4131 recalculate_side_effects (expr
);
4133 /* Move the COND_EXPR to the prequeue. */
4134 gimplify_stmt (&expr
, pre_p
);
4140 /* Remove any COMPOUND_EXPR so the following cases will be caught. */
4141 STRIP_TYPE_NOPS (TREE_OPERAND (expr
, 0));
4142 if (TREE_CODE (TREE_OPERAND (expr
, 0)) == COMPOUND_EXPR
)
4143 gimplify_compound_expr (&TREE_OPERAND (expr
, 0), pre_p
, true);
4145 /* Make sure the condition has BOOLEAN_TYPE. */
4146 TREE_OPERAND (expr
, 0) = gimple_boolify (TREE_OPERAND (expr
, 0));
4148 /* Break apart && and || conditions. */
4149 if (TREE_CODE (TREE_OPERAND (expr
, 0)) == TRUTH_ANDIF_EXPR
4150 || TREE_CODE (TREE_OPERAND (expr
, 0)) == TRUTH_ORIF_EXPR
)
4152 expr
= shortcut_cond_expr (expr
);
4154 if (expr
!= *expr_p
)
4158 /* We can't rely on gimplify_expr to re-gimplify the expanded
4159 form properly, as cleanups might cause the target labels to be
4160 wrapped in a TRY_FINALLY_EXPR. To prevent that, we need to
4161 set up a conditional context. */
4162 gimple_push_condition ();
4163 gimplify_stmt (expr_p
, &seq
);
4164 gimple_pop_condition (pre_p
);
4165 gimple_seq_add_seq (pre_p
, seq
);
4171 /* Now do the normal gimplification. */
4173 /* Gimplify condition. */
4174 ret
= gimplify_expr (&TREE_OPERAND (expr
, 0), pre_p
, NULL
,
4175 is_gimple_condexpr_for_cond
, fb_rvalue
);
4176 if (ret
== GS_ERROR
)
4178 gcc_assert (TREE_OPERAND (expr
, 0) != NULL_TREE
);
4180 gimple_push_condition ();
4182 have_then_clause_p
= have_else_clause_p
= false;
4183 label_true
= find_goto_label (TREE_OPERAND (expr
, 1));
4185 && DECL_CONTEXT (GOTO_DESTINATION (label_true
)) == current_function_decl
4186 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4187 have different locations, otherwise we end up with incorrect
4188 location information on the branches. */
4190 || !EXPR_HAS_LOCATION (expr
)
4191 || !rexpr_has_location (label_true
)
4192 || EXPR_LOCATION (expr
) == rexpr_location (label_true
)))
4194 have_then_clause_p
= true;
4195 label_true
= GOTO_DESTINATION (label_true
);
4198 label_true
= create_artificial_label (UNKNOWN_LOCATION
);
4199 label_false
= find_goto_label (TREE_OPERAND (expr
, 2));
4201 && DECL_CONTEXT (GOTO_DESTINATION (label_false
)) == current_function_decl
4202 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4203 have different locations, otherwise we end up with incorrect
4204 location information on the branches. */
4206 || !EXPR_HAS_LOCATION (expr
)
4207 || !rexpr_has_location (label_false
)
4208 || EXPR_LOCATION (expr
) == rexpr_location (label_false
)))
4210 have_else_clause_p
= true;
4211 label_false
= GOTO_DESTINATION (label_false
);
4214 label_false
= create_artificial_label (UNKNOWN_LOCATION
);
4216 gimple_cond_get_ops_from_tree (COND_EXPR_COND (expr
), &pred_code
, &arm1
,
4218 cond_stmt
= gimple_build_cond (pred_code
, arm1
, arm2
, label_true
,
4220 gimple_set_no_warning (cond_stmt
, TREE_NO_WARNING (COND_EXPR_COND (expr
)));
4221 gimplify_seq_add_stmt (&seq
, cond_stmt
);
4222 gimple_stmt_iterator gsi
= gsi_last (seq
);
4223 maybe_fold_stmt (&gsi
);
4225 label_cont
= NULL_TREE
;
4226 if (!have_then_clause_p
)
4228 /* For if (...) {} else { code; } put label_true after
4230 if (TREE_OPERAND (expr
, 1) == NULL_TREE
4231 && !have_else_clause_p
4232 && TREE_OPERAND (expr
, 2) != NULL_TREE
)
4233 label_cont
= label_true
;
4236 gimplify_seq_add_stmt (&seq
, gimple_build_label (label_true
));
4237 have_then_clause_p
= gimplify_stmt (&TREE_OPERAND (expr
, 1), &seq
);
4238 /* For if (...) { code; } else {} or
4239 if (...) { code; } else goto label; or
4240 if (...) { code; return; } else { ... }
4241 label_cont isn't needed. */
4242 if (!have_else_clause_p
4243 && TREE_OPERAND (expr
, 2) != NULL_TREE
4244 && gimple_seq_may_fallthru (seq
))
4247 label_cont
= create_artificial_label (UNKNOWN_LOCATION
);
4249 g
= gimple_build_goto (label_cont
);
4251 /* GIMPLE_COND's are very low level; they have embedded
4252 gotos. This particular embedded goto should not be marked
4253 with the location of the original COND_EXPR, as it would
4254 correspond to the COND_EXPR's condition, not the ELSE or the
4255 THEN arms. To avoid marking it with the wrong location, flag
4256 it as "no location". */
4257 gimple_set_do_not_emit_location (g
);
4259 gimplify_seq_add_stmt (&seq
, g
);
4263 if (!have_else_clause_p
)
4265 gimplify_seq_add_stmt (&seq
, gimple_build_label (label_false
));
4266 have_else_clause_p
= gimplify_stmt (&TREE_OPERAND (expr
, 2), &seq
);
4269 gimplify_seq_add_stmt (&seq
, gimple_build_label (label_cont
));
4271 gimple_pop_condition (pre_p
);
4272 gimple_seq_add_seq (pre_p
, seq
);
4274 if (ret
== GS_ERROR
)
4276 else if (have_then_clause_p
|| have_else_clause_p
)
4280 /* Both arms are empty; replace the COND_EXPR with its predicate. */
4281 expr
= TREE_OPERAND (expr
, 0);
4282 gimplify_stmt (&expr
, pre_p
);
4289 /* Prepare the node pointed to by EXPR_P, an is_gimple_addressable expression,
4290 to be marked addressable.
4292 We cannot rely on such an expression being directly markable if a temporary
4293 has been created by the gimplification. In this case, we create another
4294 temporary and initialize it with a copy, which will become a store after we
4295 mark it addressable. This can happen if the front-end passed us something
4296 that it could not mark addressable yet, like a Fortran pass-by-reference
4297 parameter (int) floatvar. */
4300 prepare_gimple_addressable (tree
*expr_p
, gimple_seq
*seq_p
)
4302 while (handled_component_p (*expr_p
))
4303 expr_p
= &TREE_OPERAND (*expr_p
, 0);
4304 if (is_gimple_reg (*expr_p
))
4306 /* Do not allow an SSA name as the temporary. */
4307 tree var
= get_initialized_tmp_var (*expr_p
, seq_p
, NULL
, false);
4308 DECL_NOT_GIMPLE_REG_P (var
) = 1;
4313 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4314 a call to __builtin_memcpy. */
4316 static enum gimplify_status
4317 gimplify_modify_expr_to_memcpy (tree
*expr_p
, tree size
, bool want_value
,
4320 tree t
, to
, to_ptr
, from
, from_ptr
;
4322 location_t loc
= EXPR_LOCATION (*expr_p
);
4324 to
= TREE_OPERAND (*expr_p
, 0);
4325 from
= TREE_OPERAND (*expr_p
, 1);
4327 /* Mark the RHS addressable. Beware that it may not be possible to do so
4328 directly if a temporary has been created by the gimplification. */
4329 prepare_gimple_addressable (&from
, seq_p
);
4331 mark_addressable (from
);
4332 from_ptr
= build_fold_addr_expr_loc (loc
, from
);
4333 gimplify_arg (&from_ptr
, seq_p
, loc
);
4335 mark_addressable (to
);
4336 to_ptr
= build_fold_addr_expr_loc (loc
, to
);
4337 gimplify_arg (&to_ptr
, seq_p
, loc
);
4339 t
= builtin_decl_implicit (BUILT_IN_MEMCPY
);
4341 gs
= gimple_build_call (t
, 3, to_ptr
, from_ptr
, size
);
4342 gimple_call_set_alloca_for_var (gs
, true);
4346 /* tmp = memcpy() */
4347 t
= create_tmp_var (TREE_TYPE (to_ptr
));
4348 gimple_call_set_lhs (gs
, t
);
4349 gimplify_seq_add_stmt (seq_p
, gs
);
4351 *expr_p
= build_simple_mem_ref (t
);
4355 gimplify_seq_add_stmt (seq_p
, gs
);
4360 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4361 a call to __builtin_memset. In this case we know that the RHS is
4362 a CONSTRUCTOR with an empty element list. */
4364 static enum gimplify_status
4365 gimplify_modify_expr_to_memset (tree
*expr_p
, tree size
, bool want_value
,
4368 tree t
, from
, to
, to_ptr
;
4370 location_t loc
= EXPR_LOCATION (*expr_p
);
4372 /* Assert our assumptions, to abort instead of producing wrong code
4373 silently if they are not met. Beware that the RHS CONSTRUCTOR might
4374 not be immediately exposed. */
4375 from
= TREE_OPERAND (*expr_p
, 1);
4376 if (TREE_CODE (from
) == WITH_SIZE_EXPR
)
4377 from
= TREE_OPERAND (from
, 0);
4379 gcc_assert (TREE_CODE (from
) == CONSTRUCTOR
4380 && vec_safe_is_empty (CONSTRUCTOR_ELTS (from
)));
4383 to
= TREE_OPERAND (*expr_p
, 0);
4385 to_ptr
= build_fold_addr_expr_loc (loc
, to
);
4386 gimplify_arg (&to_ptr
, seq_p
, loc
);
4387 t
= builtin_decl_implicit (BUILT_IN_MEMSET
);
4389 gs
= gimple_build_call (t
, 3, to_ptr
, integer_zero_node
, size
);
4393 /* tmp = memset() */
4394 t
= create_tmp_var (TREE_TYPE (to_ptr
));
4395 gimple_call_set_lhs (gs
, t
);
4396 gimplify_seq_add_stmt (seq_p
, gs
);
4398 *expr_p
= build1 (INDIRECT_REF
, TREE_TYPE (to
), t
);
4402 gimplify_seq_add_stmt (seq_p
, gs
);
4407 /* A subroutine of gimplify_init_ctor_preeval. Called via walk_tree,
4408 determine, cautiously, if a CONSTRUCTOR overlaps the lhs of an
4409 assignment. Return non-null if we detect a potential overlap. */
4411 struct gimplify_init_ctor_preeval_data
4413 /* The base decl of the lhs object. May be NULL, in which case we
4414 have to assume the lhs is indirect. */
4417 /* The alias set of the lhs object. */
4418 alias_set_type lhs_alias_set
;
4422 gimplify_init_ctor_preeval_1 (tree
*tp
, int *walk_subtrees
, void *xdata
)
4424 struct gimplify_init_ctor_preeval_data
*data
4425 = (struct gimplify_init_ctor_preeval_data
*) xdata
;
4428 /* If we find the base object, obviously we have overlap. */
4429 if (data
->lhs_base_decl
== t
)
4432 /* If the constructor component is indirect, determine if we have a
4433 potential overlap with the lhs. The only bits of information we
4434 have to go on at this point are addressability and alias sets. */
4435 if ((INDIRECT_REF_P (t
)
4436 || TREE_CODE (t
) == MEM_REF
)
4437 && (!data
->lhs_base_decl
|| TREE_ADDRESSABLE (data
->lhs_base_decl
))
4438 && alias_sets_conflict_p (data
->lhs_alias_set
, get_alias_set (t
)))
4441 /* If the constructor component is a call, determine if it can hide a
4442 potential overlap with the lhs through an INDIRECT_REF like above.
4443 ??? Ugh - this is completely broken. In fact this whole analysis
4444 doesn't look conservative. */
4445 if (TREE_CODE (t
) == CALL_EXPR
)
4447 tree type
, fntype
= TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (t
)));
4449 for (type
= TYPE_ARG_TYPES (fntype
); type
; type
= TREE_CHAIN (type
))
4450 if (POINTER_TYPE_P (TREE_VALUE (type
))
4451 && (!data
->lhs_base_decl
|| TREE_ADDRESSABLE (data
->lhs_base_decl
))
4452 && alias_sets_conflict_p (data
->lhs_alias_set
,
4454 (TREE_TYPE (TREE_VALUE (type
)))))
4458 if (IS_TYPE_OR_DECL_P (t
))
4463 /* A subroutine of gimplify_init_constructor. Pre-evaluate EXPR,
4464 force values that overlap with the lhs (as described by *DATA)
4465 into temporaries. */
4468 gimplify_init_ctor_preeval (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
4469 struct gimplify_init_ctor_preeval_data
*data
)
4471 enum gimplify_status one
;
4473 /* If the value is constant, then there's nothing to pre-evaluate. */
4474 if (TREE_CONSTANT (*expr_p
))
4476 /* Ensure it does not have side effects, it might contain a reference to
4477 the object we're initializing. */
4478 gcc_assert (!TREE_SIDE_EFFECTS (*expr_p
));
4482 /* If the type has non-trivial constructors, we can't pre-evaluate. */
4483 if (TREE_ADDRESSABLE (TREE_TYPE (*expr_p
)))
4486 /* Recurse for nested constructors. */
4487 if (TREE_CODE (*expr_p
) == CONSTRUCTOR
)
4489 unsigned HOST_WIDE_INT ix
;
4490 constructor_elt
*ce
;
4491 vec
<constructor_elt
, va_gc
> *v
= CONSTRUCTOR_ELTS (*expr_p
);
4493 FOR_EACH_VEC_SAFE_ELT (v
, ix
, ce
)
4494 gimplify_init_ctor_preeval (&ce
->value
, pre_p
, post_p
, data
);
4499 /* If this is a variable sized type, we must remember the size. */
4500 maybe_with_size_expr (expr_p
);
4502 /* Gimplify the constructor element to something appropriate for the rhs
4503 of a MODIFY_EXPR. Given that we know the LHS is an aggregate, we know
4504 the gimplifier will consider this a store to memory. Doing this
4505 gimplification now means that we won't have to deal with complicated
4506 language-specific trees, nor trees like SAVE_EXPR that can induce
4507 exponential search behavior. */
4508 one
= gimplify_expr (expr_p
, pre_p
, post_p
, is_gimple_mem_rhs
, fb_rvalue
);
4509 if (one
== GS_ERROR
)
4515 /* If we gimplified to a bare decl, we can be sure that it doesn't overlap
4516 with the lhs, since "a = { .x=a }" doesn't make sense. This will
4517 always be true for all scalars, since is_gimple_mem_rhs insists on a
4518 temporary variable for them. */
4519 if (DECL_P (*expr_p
))
4522 /* If this is of variable size, we have no choice but to assume it doesn't
4523 overlap since we can't make a temporary for it. */
4524 if (TREE_CODE (TYPE_SIZE (TREE_TYPE (*expr_p
))) != INTEGER_CST
)
4527 /* Otherwise, we must search for overlap ... */
4528 if (!walk_tree (expr_p
, gimplify_init_ctor_preeval_1
, data
, NULL
))
4531 /* ... and if found, force the value into a temporary. */
4532 *expr_p
= get_formal_tmp_var (*expr_p
, pre_p
);
4535 /* A subroutine of gimplify_init_ctor_eval. Create a loop for
4536 a RANGE_EXPR in a CONSTRUCTOR for an array.
4540 object[var] = value;
4547 We increment var _after_ the loop exit check because we might otherwise
4548 fail if upper == TYPE_MAX_VALUE (type for upper).
4550 Note that we never have to deal with SAVE_EXPRs here, because this has
4551 already been taken care of for us, in gimplify_init_ctor_preeval(). */
4553 static void gimplify_init_ctor_eval (tree
, vec
<constructor_elt
, va_gc
> *,
4554 gimple_seq
*, bool);
4557 gimplify_init_ctor_eval_range (tree object
, tree lower
, tree upper
,
4558 tree value
, tree array_elt_type
,
4559 gimple_seq
*pre_p
, bool cleared
)
4561 tree loop_entry_label
, loop_exit_label
, fall_thru_label
;
4562 tree var
, var_type
, cref
, tmp
;
4564 loop_entry_label
= create_artificial_label (UNKNOWN_LOCATION
);
4565 loop_exit_label
= create_artificial_label (UNKNOWN_LOCATION
);
4566 fall_thru_label
= create_artificial_label (UNKNOWN_LOCATION
);
4568 /* Create and initialize the index variable. */
4569 var_type
= TREE_TYPE (upper
);
4570 var
= create_tmp_var (var_type
);
4571 gimplify_seq_add_stmt (pre_p
, gimple_build_assign (var
, lower
));
4573 /* Add the loop entry label. */
4574 gimplify_seq_add_stmt (pre_p
, gimple_build_label (loop_entry_label
));
4576 /* Build the reference. */
4577 cref
= build4 (ARRAY_REF
, array_elt_type
, unshare_expr (object
),
4578 var
, NULL_TREE
, NULL_TREE
);
4580 /* If we are a constructor, just call gimplify_init_ctor_eval to do
4581 the store. Otherwise just assign value to the reference. */
4583 if (TREE_CODE (value
) == CONSTRUCTOR
)
4584 /* NB we might have to call ourself recursively through
4585 gimplify_init_ctor_eval if the value is a constructor. */
4586 gimplify_init_ctor_eval (cref
, CONSTRUCTOR_ELTS (value
),
4589 gimplify_seq_add_stmt (pre_p
, gimple_build_assign (cref
, value
));
4591 /* We exit the loop when the index var is equal to the upper bound. */
4592 gimplify_seq_add_stmt (pre_p
,
4593 gimple_build_cond (EQ_EXPR
, var
, upper
,
4594 loop_exit_label
, fall_thru_label
));
4596 gimplify_seq_add_stmt (pre_p
, gimple_build_label (fall_thru_label
));
4598 /* Otherwise, increment the index var... */
4599 tmp
= build2 (PLUS_EXPR
, var_type
, var
,
4600 fold_convert (var_type
, integer_one_node
));
4601 gimplify_seq_add_stmt (pre_p
, gimple_build_assign (var
, tmp
));
4603 /* ...and jump back to the loop entry. */
4604 gimplify_seq_add_stmt (pre_p
, gimple_build_goto (loop_entry_label
));
4606 /* Add the loop exit label. */
4607 gimplify_seq_add_stmt (pre_p
, gimple_build_label (loop_exit_label
));
4610 /* Return true if FDECL is accessing a field that is zero sized. */
4613 zero_sized_field_decl (const_tree fdecl
)
4615 if (TREE_CODE (fdecl
) == FIELD_DECL
&& DECL_SIZE (fdecl
)
4616 && integer_zerop (DECL_SIZE (fdecl
)))
4621 /* Return true if TYPE is zero sized. */
4624 zero_sized_type (const_tree type
)
4626 if (AGGREGATE_TYPE_P (type
) && TYPE_SIZE (type
)
4627 && integer_zerop (TYPE_SIZE (type
)))
4632 /* A subroutine of gimplify_init_constructor. Generate individual
4633 MODIFY_EXPRs for a CONSTRUCTOR. OBJECT is the LHS against which the
4634 assignments should happen. ELTS is the CONSTRUCTOR_ELTS of the
4635 CONSTRUCTOR. CLEARED is true if the entire LHS object has been
4639 gimplify_init_ctor_eval (tree object
, vec
<constructor_elt
, va_gc
> *elts
,
4640 gimple_seq
*pre_p
, bool cleared
)
4642 tree array_elt_type
= NULL
;
4643 unsigned HOST_WIDE_INT ix
;
4644 tree purpose
, value
;
4646 if (TREE_CODE (TREE_TYPE (object
)) == ARRAY_TYPE
)
4647 array_elt_type
= TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (object
)));
4649 FOR_EACH_CONSTRUCTOR_ELT (elts
, ix
, purpose
, value
)
4653 /* NULL values are created above for gimplification errors. */
4657 if (cleared
&& initializer_zerop (value
))
4660 /* ??? Here's to hoping the front end fills in all of the indices,
4661 so we don't have to figure out what's missing ourselves. */
4662 gcc_assert (purpose
);
4664 /* Skip zero-sized fields, unless value has side-effects. This can
4665 happen with calls to functions returning a zero-sized type, which
4666 we shouldn't discard. As a number of downstream passes don't
4667 expect sets of zero-sized fields, we rely on the gimplification of
4668 the MODIFY_EXPR we make below to drop the assignment statement. */
4669 if (! TREE_SIDE_EFFECTS (value
) && zero_sized_field_decl (purpose
))
4672 /* If we have a RANGE_EXPR, we have to build a loop to assign the
4674 if (TREE_CODE (purpose
) == RANGE_EXPR
)
4676 tree lower
= TREE_OPERAND (purpose
, 0);
4677 tree upper
= TREE_OPERAND (purpose
, 1);
4679 /* If the lower bound is equal to upper, just treat it as if
4680 upper was the index. */
4681 if (simple_cst_equal (lower
, upper
))
4685 gimplify_init_ctor_eval_range (object
, lower
, upper
, value
,
4686 array_elt_type
, pre_p
, cleared
);
4693 /* Do not use bitsizetype for ARRAY_REF indices. */
4694 if (TYPE_DOMAIN (TREE_TYPE (object
)))
4696 = fold_convert (TREE_TYPE (TYPE_DOMAIN (TREE_TYPE (object
))),
4698 cref
= build4 (ARRAY_REF
, array_elt_type
, unshare_expr (object
),
4699 purpose
, NULL_TREE
, NULL_TREE
);
4703 gcc_assert (TREE_CODE (purpose
) == FIELD_DECL
);
4704 cref
= build3 (COMPONENT_REF
, TREE_TYPE (purpose
),
4705 unshare_expr (object
), purpose
, NULL_TREE
);
4708 if (TREE_CODE (value
) == CONSTRUCTOR
4709 && TREE_CODE (TREE_TYPE (value
)) != VECTOR_TYPE
)
4710 gimplify_init_ctor_eval (cref
, CONSTRUCTOR_ELTS (value
),
4714 tree init
= build2 (INIT_EXPR
, TREE_TYPE (cref
), cref
, value
);
4715 gimplify_and_add (init
, pre_p
);
4721 /* Return the appropriate RHS predicate for this LHS. */
4724 rhs_predicate_for (tree lhs
)
4726 if (is_gimple_reg (lhs
))
4727 return is_gimple_reg_rhs_or_call
;
4729 return is_gimple_mem_rhs_or_call
;
4732 /* Return the initial guess for an appropriate RHS predicate for this LHS,
4733 before the LHS has been gimplified. */
4735 static gimple_predicate
4736 initial_rhs_predicate_for (tree lhs
)
4738 if (is_gimple_reg_type (TREE_TYPE (lhs
)))
4739 return is_gimple_reg_rhs_or_call
;
4741 return is_gimple_mem_rhs_or_call
;
4744 /* Gimplify a C99 compound literal expression. This just means adding
4745 the DECL_EXPR before the current statement and using its anonymous
4748 static enum gimplify_status
4749 gimplify_compound_literal_expr (tree
*expr_p
, gimple_seq
*pre_p
,
4750 bool (*gimple_test_f
) (tree
),
4751 fallback_t fallback
)
4753 tree decl_s
= COMPOUND_LITERAL_EXPR_DECL_EXPR (*expr_p
);
4754 tree decl
= DECL_EXPR_DECL (decl_s
);
4755 tree init
= DECL_INITIAL (decl
);
4756 /* Mark the decl as addressable if the compound literal
4757 expression is addressable now, otherwise it is marked too late
4758 after we gimplify the initialization expression. */
4759 if (TREE_ADDRESSABLE (*expr_p
))
4760 TREE_ADDRESSABLE (decl
) = 1;
4761 /* Otherwise, if we don't need an lvalue and have a literal directly
4762 substitute it. Check if it matches the gimple predicate, as
4763 otherwise we'd generate a new temporary, and we can as well just
4764 use the decl we already have. */
4765 else if (!TREE_ADDRESSABLE (decl
)
4766 && !TREE_THIS_VOLATILE (decl
)
4768 && (fallback
& fb_lvalue
) == 0
4769 && gimple_test_f (init
))
4775 /* If the decl is not addressable, then it is being used in some
4776 expression or on the right hand side of a statement, and it can
4777 be put into a readonly data section. */
4778 if (!TREE_ADDRESSABLE (decl
) && (fallback
& fb_lvalue
) == 0)
4779 TREE_READONLY (decl
) = 1;
4781 /* This decl isn't mentioned in the enclosing block, so add it to the
4782 list of temps. FIXME it seems a bit of a kludge to say that
4783 anonymous artificial vars aren't pushed, but everything else is. */
4784 if (DECL_NAME (decl
) == NULL_TREE
&& !DECL_SEEN_IN_BIND_EXPR_P (decl
))
4785 gimple_add_tmp_var (decl
);
4787 gimplify_and_add (decl_s
, pre_p
);
4792 /* Optimize embedded COMPOUND_LITERAL_EXPRs within a CONSTRUCTOR,
4793 return a new CONSTRUCTOR if something changed. */
4796 optimize_compound_literals_in_ctor (tree orig_ctor
)
4798 tree ctor
= orig_ctor
;
4799 vec
<constructor_elt
, va_gc
> *elts
= CONSTRUCTOR_ELTS (ctor
);
4800 unsigned int idx
, num
= vec_safe_length (elts
);
4802 for (idx
= 0; idx
< num
; idx
++)
4804 tree value
= (*elts
)[idx
].value
;
4805 tree newval
= value
;
4806 if (TREE_CODE (value
) == CONSTRUCTOR
)
4807 newval
= optimize_compound_literals_in_ctor (value
);
4808 else if (TREE_CODE (value
) == COMPOUND_LITERAL_EXPR
)
4810 tree decl_s
= COMPOUND_LITERAL_EXPR_DECL_EXPR (value
);
4811 tree decl
= DECL_EXPR_DECL (decl_s
);
4812 tree init
= DECL_INITIAL (decl
);
4814 if (!TREE_ADDRESSABLE (value
)
4815 && !TREE_ADDRESSABLE (decl
)
4817 && TREE_CODE (init
) == CONSTRUCTOR
)
4818 newval
= optimize_compound_literals_in_ctor (init
);
4820 if (newval
== value
)
4823 if (ctor
== orig_ctor
)
4825 ctor
= copy_node (orig_ctor
);
4826 CONSTRUCTOR_ELTS (ctor
) = vec_safe_copy (elts
);
4827 elts
= CONSTRUCTOR_ELTS (ctor
);
4829 (*elts
)[idx
].value
= newval
;
4834 /* A subroutine of gimplify_modify_expr. Break out elements of a
4835 CONSTRUCTOR used as an initializer into separate MODIFY_EXPRs.
4837 Note that we still need to clear any elements that don't have explicit
4838 initializers, so if not all elements are initialized we keep the
4839 original MODIFY_EXPR, we just remove all of the constructor elements.
4841 If NOTIFY_TEMP_CREATION is true, do not gimplify, just return
4842 GS_ERROR if we would have to create a temporary when gimplifying
4843 this constructor. Otherwise, return GS_OK.
4845 If NOTIFY_TEMP_CREATION is false, just do the gimplification. */
4847 static enum gimplify_status
4848 gimplify_init_constructor (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
4849 bool want_value
, bool notify_temp_creation
)
4851 tree object
, ctor
, type
;
4852 enum gimplify_status ret
;
4853 vec
<constructor_elt
, va_gc
> *elts
;
4855 gcc_assert (TREE_CODE (TREE_OPERAND (*expr_p
, 1)) == CONSTRUCTOR
);
4857 if (!notify_temp_creation
)
4859 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
4860 is_gimple_lvalue
, fb_lvalue
);
4861 if (ret
== GS_ERROR
)
4865 object
= TREE_OPERAND (*expr_p
, 0);
4866 ctor
= TREE_OPERAND (*expr_p
, 1)
4867 = optimize_compound_literals_in_ctor (TREE_OPERAND (*expr_p
, 1));
4868 type
= TREE_TYPE (ctor
);
4869 elts
= CONSTRUCTOR_ELTS (ctor
);
4872 switch (TREE_CODE (type
))
4876 case QUAL_UNION_TYPE
:
4879 /* Use readonly data for initializers of this or smaller size
4880 regardless of the num_nonzero_elements / num_unique_nonzero_elements
4882 const HOST_WIDE_INT min_unique_size
= 64;
4883 /* If num_nonzero_elements / num_unique_nonzero_elements ratio
4884 is smaller than this, use readonly data. */
4885 const int unique_nonzero_ratio
= 8;
4886 /* True if a single access of the object must be ensured. This is the
4887 case if the target is volatile, the type is non-addressable and more
4888 than one field need to be assigned. */
4889 const bool ensure_single_access
4890 = TREE_THIS_VOLATILE (object
)
4891 && !TREE_ADDRESSABLE (type
)
4892 && vec_safe_length (elts
) > 1;
4893 struct gimplify_init_ctor_preeval_data preeval_data
;
4894 HOST_WIDE_INT num_ctor_elements
, num_nonzero_elements
;
4895 HOST_WIDE_INT num_unique_nonzero_elements
;
4896 bool cleared
, complete_p
, valid_const_initializer
;
4898 /* Aggregate types must lower constructors to initialization of
4899 individual elements. The exception is that a CONSTRUCTOR node
4900 with no elements indicates zero-initialization of the whole. */
4901 if (vec_safe_is_empty (elts
))
4903 if (notify_temp_creation
)
4908 /* Fetch information about the constructor to direct later processing.
4909 We might want to make static versions of it in various cases, and
4910 can only do so if it known to be a valid constant initializer. */
4911 valid_const_initializer
4912 = categorize_ctor_elements (ctor
, &num_nonzero_elements
,
4913 &num_unique_nonzero_elements
,
4914 &num_ctor_elements
, &complete_p
);
4916 /* If a const aggregate variable is being initialized, then it
4917 should never be a lose to promote the variable to be static. */
4918 if (valid_const_initializer
4919 && num_nonzero_elements
> 1
4920 && TREE_READONLY (object
)
4922 && !DECL_REGISTER (object
)
4923 && (flag_merge_constants
>= 2 || !TREE_ADDRESSABLE (object
))
4924 /* For ctors that have many repeated nonzero elements
4925 represented through RANGE_EXPRs, prefer initializing
4926 those through runtime loops over copies of large amounts
4927 of data from readonly data section. */
4928 && (num_unique_nonzero_elements
4929 > num_nonzero_elements
/ unique_nonzero_ratio
4930 || ((unsigned HOST_WIDE_INT
) int_size_in_bytes (type
)
4931 <= (unsigned HOST_WIDE_INT
) min_unique_size
)))
4933 if (notify_temp_creation
)
4936 DECL_INITIAL (object
) = ctor
;
4937 TREE_STATIC (object
) = 1;
4938 if (!DECL_NAME (object
))
4939 DECL_NAME (object
) = create_tmp_var_name ("C");
4940 walk_tree (&DECL_INITIAL (object
), force_labels_r
, NULL
, NULL
);
4942 /* ??? C++ doesn't automatically append a .<number> to the
4943 assembler name, and even when it does, it looks at FE private
4944 data structures to figure out what that number should be,
4945 which are not set for this variable. I suppose this is
4946 important for local statics for inline functions, which aren't
4947 "local" in the object file sense. So in order to get a unique
4948 TU-local symbol, we must invoke the lhd version now. */
4949 lhd_set_decl_assembler_name (object
);
4951 *expr_p
= NULL_TREE
;
4955 /* If there are "lots" of initialized elements, even discounting
4956 those that are not address constants (and thus *must* be
4957 computed at runtime), then partition the constructor into
4958 constant and non-constant parts. Block copy the constant
4959 parts in, then generate code for the non-constant parts. */
4960 /* TODO. There's code in cp/typeck.c to do this. */
4962 if (int_size_in_bytes (TREE_TYPE (ctor
)) < 0)
4963 /* store_constructor will ignore the clearing of variable-sized
4964 objects. Initializers for such objects must explicitly set
4965 every field that needs to be set. */
4967 else if (!complete_p
)
4968 /* If the constructor isn't complete, clear the whole object
4969 beforehand, unless CONSTRUCTOR_NO_CLEARING is set on it.
4971 ??? This ought not to be needed. For any element not present
4972 in the initializer, we should simply set them to zero. Except
4973 we'd need to *find* the elements that are not present, and that
4974 requires trickery to avoid quadratic compile-time behavior in
4975 large cases or excessive memory use in small cases. */
4976 cleared
= !CONSTRUCTOR_NO_CLEARING (ctor
);
4977 else if (num_ctor_elements
- num_nonzero_elements
4978 > CLEAR_RATIO (optimize_function_for_speed_p (cfun
))
4979 && num_nonzero_elements
< num_ctor_elements
/ 4)
4980 /* If there are "lots" of zeros, it's more efficient to clear
4981 the memory and then set the nonzero elements. */
4983 else if (ensure_single_access
&& num_nonzero_elements
== 0)
4984 /* If a single access to the target must be ensured and all elements
4985 are zero, then it's optimal to clear whatever their number. */
4990 /* If there are "lots" of initialized elements, and all of them
4991 are valid address constants, then the entire initializer can
4992 be dropped to memory, and then memcpy'd out. Don't do this
4993 for sparse arrays, though, as it's more efficient to follow
4994 the standard CONSTRUCTOR behavior of memset followed by
4995 individual element initialization. Also don't do this for small
4996 all-zero initializers (which aren't big enough to merit
4997 clearing), and don't try to make bitwise copies of
4998 TREE_ADDRESSABLE types. */
4999 if (valid_const_initializer
5001 && !(cleared
|| num_nonzero_elements
== 0)
5002 && !TREE_ADDRESSABLE (type
))
5004 HOST_WIDE_INT size
= int_size_in_bytes (type
);
5007 /* ??? We can still get unbounded array types, at least
5008 from the C++ front end. This seems wrong, but attempt
5009 to work around it for now. */
5012 size
= int_size_in_bytes (TREE_TYPE (object
));
5014 TREE_TYPE (ctor
) = type
= TREE_TYPE (object
);
5017 /* Find the maximum alignment we can assume for the object. */
5018 /* ??? Make use of DECL_OFFSET_ALIGN. */
5019 if (DECL_P (object
))
5020 align
= DECL_ALIGN (object
);
5022 align
= TYPE_ALIGN (type
);
5024 /* Do a block move either if the size is so small as to make
5025 each individual move a sub-unit move on average, or if it
5026 is so large as to make individual moves inefficient. */
5028 && num_nonzero_elements
> 1
5029 /* For ctors that have many repeated nonzero elements
5030 represented through RANGE_EXPRs, prefer initializing
5031 those through runtime loops over copies of large amounts
5032 of data from readonly data section. */
5033 && (num_unique_nonzero_elements
5034 > num_nonzero_elements
/ unique_nonzero_ratio
5035 || size
<= min_unique_size
)
5036 && (size
< num_nonzero_elements
5037 || !can_move_by_pieces (size
, align
)))
5039 if (notify_temp_creation
)
5042 walk_tree (&ctor
, force_labels_r
, NULL
, NULL
);
5043 ctor
= tree_output_constant_def (ctor
);
5044 if (!useless_type_conversion_p (type
, TREE_TYPE (ctor
)))
5045 ctor
= build1 (VIEW_CONVERT_EXPR
, type
, ctor
);
5046 TREE_OPERAND (*expr_p
, 1) = ctor
;
5048 /* This is no longer an assignment of a CONSTRUCTOR, but
5049 we still may have processing to do on the LHS. So
5050 pretend we didn't do anything here to let that happen. */
5051 return GS_UNHANDLED
;
5055 /* If a single access to the target must be ensured and there are
5056 nonzero elements or the zero elements are not assigned en masse,
5057 initialize the target from a temporary. */
5058 if (ensure_single_access
&& (num_nonzero_elements
> 0 || !cleared
))
5060 if (notify_temp_creation
)
5063 tree temp
= create_tmp_var (TYPE_MAIN_VARIANT (type
));
5064 TREE_OPERAND (*expr_p
, 0) = temp
;
5065 *expr_p
= build2 (COMPOUND_EXPR
, TREE_TYPE (*expr_p
),
5067 build2 (MODIFY_EXPR
, void_type_node
,
5072 if (notify_temp_creation
)
5075 /* If there are nonzero elements and if needed, pre-evaluate to capture
5076 elements overlapping with the lhs into temporaries. We must do this
5077 before clearing to fetch the values before they are zeroed-out. */
5078 if (num_nonzero_elements
> 0 && TREE_CODE (*expr_p
) != INIT_EXPR
)
5080 preeval_data
.lhs_base_decl
= get_base_address (object
);
5081 if (!DECL_P (preeval_data
.lhs_base_decl
))
5082 preeval_data
.lhs_base_decl
= NULL
;
5083 preeval_data
.lhs_alias_set
= get_alias_set (object
);
5085 gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p
, 1),
5086 pre_p
, post_p
, &preeval_data
);
5089 bool ctor_has_side_effects_p
5090 = TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p
, 1));
5094 /* Zap the CONSTRUCTOR element list, which simplifies this case.
5095 Note that we still have to gimplify, in order to handle the
5096 case of variable sized types. Avoid shared tree structures. */
5097 CONSTRUCTOR_ELTS (ctor
) = NULL
;
5098 TREE_SIDE_EFFECTS (ctor
) = 0;
5099 object
= unshare_expr (object
);
5100 gimplify_stmt (expr_p
, pre_p
);
5103 /* If we have not block cleared the object, or if there are nonzero
5104 elements in the constructor, or if the constructor has side effects,
5105 add assignments to the individual scalar fields of the object. */
5107 || num_nonzero_elements
> 0
5108 || ctor_has_side_effects_p
)
5109 gimplify_init_ctor_eval (object
, elts
, pre_p
, cleared
);
5111 *expr_p
= NULL_TREE
;
5119 if (notify_temp_creation
)
5122 /* Extract the real and imaginary parts out of the ctor. */
5123 gcc_assert (elts
->length () == 2);
5124 r
= (*elts
)[0].value
;
5125 i
= (*elts
)[1].value
;
5126 if (r
== NULL
|| i
== NULL
)
5128 tree zero
= build_zero_cst (TREE_TYPE (type
));
5135 /* Complex types have either COMPLEX_CST or COMPLEX_EXPR to
5136 represent creation of a complex value. */
5137 if (TREE_CONSTANT (r
) && TREE_CONSTANT (i
))
5139 ctor
= build_complex (type
, r
, i
);
5140 TREE_OPERAND (*expr_p
, 1) = ctor
;
5144 ctor
= build2 (COMPLEX_EXPR
, type
, r
, i
);
5145 TREE_OPERAND (*expr_p
, 1) = ctor
;
5146 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 1),
5149 rhs_predicate_for (TREE_OPERAND (*expr_p
, 0)),
5157 unsigned HOST_WIDE_INT ix
;
5158 constructor_elt
*ce
;
5160 if (notify_temp_creation
)
5163 /* Go ahead and simplify constant constructors to VECTOR_CST. */
5164 if (TREE_CONSTANT (ctor
))
5166 bool constant_p
= true;
5169 /* Even when ctor is constant, it might contain non-*_CST
5170 elements, such as addresses or trapping values like
5171 1.0/0.0 - 1.0/0.0. Such expressions don't belong
5172 in VECTOR_CST nodes. */
5173 FOR_EACH_CONSTRUCTOR_VALUE (elts
, ix
, value
)
5174 if (!CONSTANT_CLASS_P (value
))
5182 TREE_OPERAND (*expr_p
, 1) = build_vector_from_ctor (type
, elts
);
5186 TREE_CONSTANT (ctor
) = 0;
5189 /* Vector types use CONSTRUCTOR all the way through gimple
5190 compilation as a general initializer. */
5191 FOR_EACH_VEC_SAFE_ELT (elts
, ix
, ce
)
5193 enum gimplify_status tret
;
5194 tret
= gimplify_expr (&ce
->value
, pre_p
, post_p
, is_gimple_val
,
5196 if (tret
== GS_ERROR
)
5198 else if (TREE_STATIC (ctor
)
5199 && !initializer_constant_valid_p (ce
->value
,
5200 TREE_TYPE (ce
->value
)))
5201 TREE_STATIC (ctor
) = 0;
5203 if (!is_gimple_reg (TREE_OPERAND (*expr_p
, 0)))
5204 TREE_OPERAND (*expr_p
, 1) = get_formal_tmp_var (ctor
, pre_p
);
5209 /* So how did we get a CONSTRUCTOR for a scalar type? */
5213 if (ret
== GS_ERROR
)
5215 /* If we have gimplified both sides of the initializer but have
5216 not emitted an assignment, do so now. */
5219 tree lhs
= TREE_OPERAND (*expr_p
, 0);
5220 tree rhs
= TREE_OPERAND (*expr_p
, 1);
5221 if (want_value
&& object
== lhs
)
5222 lhs
= unshare_expr (lhs
);
5223 gassign
*init
= gimple_build_assign (lhs
, rhs
);
5224 gimplify_seq_add_stmt (pre_p
, init
);
5238 /* Given a pointer value OP0, return a simplified version of an
5239 indirection through OP0, or NULL_TREE if no simplification is
5240 possible. This may only be applied to a rhs of an expression.
5241 Note that the resulting type may be different from the type pointed
5242 to in the sense that it is still compatible from the langhooks
5246 gimple_fold_indirect_ref_rhs (tree t
)
5248 return gimple_fold_indirect_ref (t
);
5251 /* Subroutine of gimplify_modify_expr to do simplifications of
5252 MODIFY_EXPRs based on the code of the RHS. We loop for as long as
5253 something changes. */
5255 static enum gimplify_status
5256 gimplify_modify_expr_rhs (tree
*expr_p
, tree
*from_p
, tree
*to_p
,
5257 gimple_seq
*pre_p
, gimple_seq
*post_p
,
5260 enum gimplify_status ret
= GS_UNHANDLED
;
5266 switch (TREE_CODE (*from_p
))
5269 /* If we're assigning from a read-only variable initialized with
5270 a constructor and not volatile, do the direct assignment from
5271 the constructor, but only if the target is not volatile either
5272 since this latter assignment might end up being done on a per
5273 field basis. However, if the target is volatile and the type
5274 is aggregate and non-addressable, gimplify_init_constructor
5275 knows that it needs to ensure a single access to the target
5276 and it will return GS_OK only in this case. */
5277 if (TREE_READONLY (*from_p
)
5278 && DECL_INITIAL (*from_p
)
5279 && TREE_CODE (DECL_INITIAL (*from_p
)) == CONSTRUCTOR
5280 && !TREE_THIS_VOLATILE (*from_p
)
5281 && (!TREE_THIS_VOLATILE (*to_p
)
5282 || (AGGREGATE_TYPE_P (TREE_TYPE (*to_p
))
5283 && !TREE_ADDRESSABLE (TREE_TYPE (*to_p
)))))
5285 tree old_from
= *from_p
;
5286 enum gimplify_status subret
;
5288 /* Move the constructor into the RHS. */
5289 *from_p
= unshare_expr (DECL_INITIAL (*from_p
));
5291 /* Let's see if gimplify_init_constructor will need to put
5293 subret
= gimplify_init_constructor (expr_p
, NULL
, NULL
,
5295 if (subret
== GS_ERROR
)
5297 /* If so, revert the change. */
5309 /* If we have code like
5313 where the type of "x" is a (possibly cv-qualified variant
5314 of "A"), treat the entire expression as identical to "x".
5315 This kind of code arises in C++ when an object is bound
5316 to a const reference, and if "x" is a TARGET_EXPR we want
5317 to take advantage of the optimization below. */
5318 bool volatile_p
= TREE_THIS_VOLATILE (*from_p
);
5319 tree t
= gimple_fold_indirect_ref_rhs (TREE_OPERAND (*from_p
, 0));
5322 if (TREE_THIS_VOLATILE (t
) != volatile_p
)
5325 t
= build_simple_mem_ref_loc (EXPR_LOCATION (*from_p
),
5326 build_fold_addr_expr (t
));
5327 if (REFERENCE_CLASS_P (t
))
5328 TREE_THIS_VOLATILE (t
) = volatile_p
;
5339 /* If we are initializing something from a TARGET_EXPR, strip the
5340 TARGET_EXPR and initialize it directly, if possible. This can't
5341 be done if the initializer is void, since that implies that the
5342 temporary is set in some non-trivial way.
5344 ??? What about code that pulls out the temp and uses it
5345 elsewhere? I think that such code never uses the TARGET_EXPR as
5346 an initializer. If I'm wrong, we'll die because the temp won't
5347 have any RTL. In that case, I guess we'll need to replace
5348 references somehow. */
5349 tree init
= TARGET_EXPR_INITIAL (*from_p
);
5352 && (TREE_CODE (*expr_p
) != MODIFY_EXPR
5353 || !TARGET_EXPR_NO_ELIDE (*from_p
))
5354 && !VOID_TYPE_P (TREE_TYPE (init
)))
5364 /* Remove any COMPOUND_EXPR in the RHS so the following cases will be
5366 gimplify_compound_expr (from_p
, pre_p
, true);
5372 /* If we already made some changes, let the front end have a
5373 crack at this before we break it down. */
5374 if (ret
!= GS_UNHANDLED
)
5376 /* If we're initializing from a CONSTRUCTOR, break this into
5377 individual MODIFY_EXPRs. */
5378 return gimplify_init_constructor (expr_p
, pre_p
, post_p
, want_value
,
5382 /* If we're assigning to a non-register type, push the assignment
5383 down into the branches. This is mandatory for ADDRESSABLE types,
5384 since we cannot generate temporaries for such, but it saves a
5385 copy in other cases as well. */
5386 if (!is_gimple_reg_type (TREE_TYPE (*from_p
)))
5388 /* This code should mirror the code in gimplify_cond_expr. */
5389 enum tree_code code
= TREE_CODE (*expr_p
);
5390 tree cond
= *from_p
;
5391 tree result
= *to_p
;
5393 ret
= gimplify_expr (&result
, pre_p
, post_p
,
5394 is_gimple_lvalue
, fb_lvalue
);
5395 if (ret
!= GS_ERROR
)
5398 /* If we are going to write RESULT more than once, clear
5399 TREE_READONLY flag, otherwise we might incorrectly promote
5400 the variable to static const and initialize it at compile
5401 time in one of the branches. */
5403 && TREE_TYPE (TREE_OPERAND (cond
, 1)) != void_type_node
5404 && TREE_TYPE (TREE_OPERAND (cond
, 2)) != void_type_node
)
5405 TREE_READONLY (result
) = 0;
5406 if (TREE_TYPE (TREE_OPERAND (cond
, 1)) != void_type_node
)
5407 TREE_OPERAND (cond
, 1)
5408 = build2 (code
, void_type_node
, result
,
5409 TREE_OPERAND (cond
, 1));
5410 if (TREE_TYPE (TREE_OPERAND (cond
, 2)) != void_type_node
)
5411 TREE_OPERAND (cond
, 2)
5412 = build2 (code
, void_type_node
, unshare_expr (result
),
5413 TREE_OPERAND (cond
, 2));
5415 TREE_TYPE (cond
) = void_type_node
;
5416 recalculate_side_effects (cond
);
5420 gimplify_and_add (cond
, pre_p
);
5421 *expr_p
= unshare_expr (result
);
5430 /* For calls that return in memory, give *to_p as the CALL_EXPR's
5431 return slot so that we don't generate a temporary. */
5432 if (!CALL_EXPR_RETURN_SLOT_OPT (*from_p
)
5433 && aggregate_value_p (*from_p
, *from_p
))
5437 if (!(rhs_predicate_for (*to_p
))(*from_p
))
5438 /* If we need a temporary, *to_p isn't accurate. */
5440 /* It's OK to use the return slot directly unless it's an NRV. */
5441 else if (TREE_CODE (*to_p
) == RESULT_DECL
5442 && DECL_NAME (*to_p
) == NULL_TREE
5443 && needs_to_live_in_memory (*to_p
))
5445 else if (is_gimple_reg_type (TREE_TYPE (*to_p
))
5446 || (DECL_P (*to_p
) && DECL_REGISTER (*to_p
)))
5447 /* Don't force regs into memory. */
5449 else if (TREE_CODE (*expr_p
) == INIT_EXPR
)
5450 /* It's OK to use the target directly if it's being
5453 else if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p
)))
5455 /* Always use the target and thus RSO for variable-sized types.
5456 GIMPLE cannot deal with a variable-sized assignment
5457 embedded in a call statement. */
5459 else if (TREE_CODE (*to_p
) != SSA_NAME
5460 && (!is_gimple_variable (*to_p
)
5461 || needs_to_live_in_memory (*to_p
)))
5462 /* Don't use the original target if it's already addressable;
5463 if its address escapes, and the called function uses the
5464 NRV optimization, a conforming program could see *to_p
5465 change before the called function returns; see c++/19317.
5466 When optimizing, the return_slot pass marks more functions
5467 as safe after we have escape info. */
5474 CALL_EXPR_RETURN_SLOT_OPT (*from_p
) = 1;
5475 mark_addressable (*to_p
);
5480 case WITH_SIZE_EXPR
:
5481 /* Likewise for calls that return an aggregate of non-constant size,
5482 since we would not be able to generate a temporary at all. */
5483 if (TREE_CODE (TREE_OPERAND (*from_p
, 0)) == CALL_EXPR
)
5485 *from_p
= TREE_OPERAND (*from_p
, 0);
5486 /* We don't change ret in this case because the
5487 WITH_SIZE_EXPR might have been added in
5488 gimplify_modify_expr, so returning GS_OK would lead to an
5494 /* If we're initializing from a container, push the initialization
5496 case CLEANUP_POINT_EXPR
:
5498 case STATEMENT_LIST
:
5500 tree wrap
= *from_p
;
5503 ret
= gimplify_expr (to_p
, pre_p
, post_p
, is_gimple_min_lval
,
5505 if (ret
!= GS_ERROR
)
5508 t
= voidify_wrapper_expr (wrap
, *expr_p
);
5509 gcc_assert (t
== *expr_p
);
5513 gimplify_and_add (wrap
, pre_p
);
5514 *expr_p
= unshare_expr (*to_p
);
5521 case COMPOUND_LITERAL_EXPR
:
5523 tree complit
= TREE_OPERAND (*expr_p
, 1);
5524 tree decl_s
= COMPOUND_LITERAL_EXPR_DECL_EXPR (complit
);
5525 tree decl
= DECL_EXPR_DECL (decl_s
);
5526 tree init
= DECL_INITIAL (decl
);
5528 /* struct T x = (struct T) { 0, 1, 2 } can be optimized
5529 into struct T x = { 0, 1, 2 } if the address of the
5530 compound literal has never been taken. */
5531 if (!TREE_ADDRESSABLE (complit
)
5532 && !TREE_ADDRESSABLE (decl
)
5535 *expr_p
= copy_node (*expr_p
);
5536 TREE_OPERAND (*expr_p
, 1) = init
;
5551 /* Return true if T looks like a valid GIMPLE statement. */
5554 is_gimple_stmt (tree t
)
5556 const enum tree_code code
= TREE_CODE (t
);
5561 /* The only valid NOP_EXPR is the empty statement. */
5562 return IS_EMPTY_STMT (t
);
5566 /* These are only valid if they're void. */
5567 return TREE_TYPE (t
) == NULL
|| VOID_TYPE_P (TREE_TYPE (t
));
5573 case CASE_LABEL_EXPR
:
5574 case TRY_CATCH_EXPR
:
5575 case TRY_FINALLY_EXPR
:
5576 case EH_FILTER_EXPR
:
5579 case STATEMENT_LIST
:
5584 case OACC_HOST_DATA
:
5587 case OACC_ENTER_DATA
:
5588 case OACC_EXIT_DATA
:
5593 case OMP_DISTRIBUTE
:
5606 case OMP_TARGET_DATA
:
5607 case OMP_TARGET_UPDATE
:
5608 case OMP_TARGET_ENTER_DATA
:
5609 case OMP_TARGET_EXIT_DATA
:
5612 /* These are always void. */
5618 /* These are valid regardless of their type. */
5627 /* Promote partial stores to COMPLEX variables to total stores. *EXPR_P is
5628 a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a gimple register.
5630 IMPORTANT NOTE: This promotion is performed by introducing a load of the
5631 other, unmodified part of the complex object just before the total store.
5632 As a consequence, if the object is still uninitialized, an undefined value
5633 will be loaded into a register, which may result in a spurious exception
5634 if the register is floating-point and the value happens to be a signaling
5635 NaN for example. Then the fully-fledged complex operations lowering pass
5636 followed by a DCE pass are necessary in order to fix things up. */
5638 static enum gimplify_status
5639 gimplify_modify_expr_complex_part (tree
*expr_p
, gimple_seq
*pre_p
,
5642 enum tree_code code
, ocode
;
5643 tree lhs
, rhs
, new_rhs
, other
, realpart
, imagpart
;
5645 lhs
= TREE_OPERAND (*expr_p
, 0);
5646 rhs
= TREE_OPERAND (*expr_p
, 1);
5647 code
= TREE_CODE (lhs
);
5648 lhs
= TREE_OPERAND (lhs
, 0);
5650 ocode
= code
== REALPART_EXPR
? IMAGPART_EXPR
: REALPART_EXPR
;
5651 other
= build1 (ocode
, TREE_TYPE (rhs
), lhs
);
5652 TREE_NO_WARNING (other
) = 1;
5653 other
= get_formal_tmp_var (other
, pre_p
);
5655 realpart
= code
== REALPART_EXPR
? rhs
: other
;
5656 imagpart
= code
== REALPART_EXPR
? other
: rhs
;
5658 if (TREE_CONSTANT (realpart
) && TREE_CONSTANT (imagpart
))
5659 new_rhs
= build_complex (TREE_TYPE (lhs
), realpart
, imagpart
);
5661 new_rhs
= build2 (COMPLEX_EXPR
, TREE_TYPE (lhs
), realpart
, imagpart
);
5663 gimplify_seq_add_stmt (pre_p
, gimple_build_assign (lhs
, new_rhs
));
5664 *expr_p
= (want_value
) ? rhs
: NULL_TREE
;
5669 /* Gimplify the MODIFY_EXPR node pointed to by EXPR_P.
5675 PRE_P points to the list where side effects that must happen before
5676 *EXPR_P should be stored.
5678 POST_P points to the list where side effects that must happen after
5679 *EXPR_P should be stored.
5681 WANT_VALUE is nonzero iff we want to use the value of this expression
5682 in another expression. */
5684 static enum gimplify_status
5685 gimplify_modify_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
5688 tree
*from_p
= &TREE_OPERAND (*expr_p
, 1);
5689 tree
*to_p
= &TREE_OPERAND (*expr_p
, 0);
5690 enum gimplify_status ret
= GS_UNHANDLED
;
5692 location_t loc
= EXPR_LOCATION (*expr_p
);
5693 gimple_stmt_iterator gsi
;
5695 gcc_assert (TREE_CODE (*expr_p
) == MODIFY_EXPR
5696 || TREE_CODE (*expr_p
) == INIT_EXPR
);
5698 /* Trying to simplify a clobber using normal logic doesn't work,
5699 so handle it here. */
5700 if (TREE_CLOBBER_P (*from_p
))
5702 ret
= gimplify_expr (to_p
, pre_p
, post_p
, is_gimple_lvalue
, fb_lvalue
);
5703 if (ret
== GS_ERROR
)
5705 gcc_assert (!want_value
);
5706 if (!VAR_P (*to_p
) && TREE_CODE (*to_p
) != MEM_REF
)
5708 tree addr
= get_initialized_tmp_var (build_fold_addr_expr (*to_p
),
5710 *to_p
= build_simple_mem_ref_loc (EXPR_LOCATION (*to_p
), addr
);
5712 gimplify_seq_add_stmt (pre_p
, gimple_build_assign (*to_p
, *from_p
));
5717 /* Insert pointer conversions required by the middle-end that are not
5718 required by the frontend. This fixes middle-end type checking for
5719 for example gcc.dg/redecl-6.c. */
5720 if (POINTER_TYPE_P (TREE_TYPE (*to_p
)))
5722 STRIP_USELESS_TYPE_CONVERSION (*from_p
);
5723 if (!useless_type_conversion_p (TREE_TYPE (*to_p
), TREE_TYPE (*from_p
)))
5724 *from_p
= fold_convert_loc (loc
, TREE_TYPE (*to_p
), *from_p
);
5727 /* See if any simplifications can be done based on what the RHS is. */
5728 ret
= gimplify_modify_expr_rhs (expr_p
, from_p
, to_p
, pre_p
, post_p
,
5730 if (ret
!= GS_UNHANDLED
)
5733 /* For zero sized types only gimplify the left hand side and right hand
5734 side as statements and throw away the assignment. Do this after
5735 gimplify_modify_expr_rhs so we handle TARGET_EXPRs of addressable
5737 if (zero_sized_type (TREE_TYPE (*from_p
))
5739 /* Don't do this for calls that return addressable types, expand_call
5740 relies on those having a lhs. */
5741 && !(TREE_ADDRESSABLE (TREE_TYPE (*from_p
))
5742 && TREE_CODE (*from_p
) == CALL_EXPR
))
5744 gimplify_stmt (from_p
, pre_p
);
5745 gimplify_stmt (to_p
, pre_p
);
5746 *expr_p
= NULL_TREE
;
5750 /* If the value being copied is of variable width, compute the length
5751 of the copy into a WITH_SIZE_EXPR. Note that we need to do this
5752 before gimplifying any of the operands so that we can resolve any
5753 PLACEHOLDER_EXPRs in the size. Also note that the RTL expander uses
5754 the size of the expression to be copied, not of the destination, so
5755 that is what we must do here. */
5756 maybe_with_size_expr (from_p
);
5758 /* As a special case, we have to temporarily allow for assignments
5759 with a CALL_EXPR on the RHS. Since in GIMPLE a function call is
5760 a toplevel statement, when gimplifying the GENERIC expression
5761 MODIFY_EXPR <a, CALL_EXPR <foo>>, we cannot create the tuple
5762 GIMPLE_ASSIGN <a, GIMPLE_CALL <foo>>.
5764 Instead, we need to create the tuple GIMPLE_CALL <a, foo>. To
5765 prevent gimplify_expr from trying to create a new temporary for
5766 foo's LHS, we tell it that it should only gimplify until it
5767 reaches the CALL_EXPR. On return from gimplify_expr, the newly
5768 created GIMPLE_CALL <foo> will be the last statement in *PRE_P
5769 and all we need to do here is set 'a' to be its LHS. */
5771 /* Gimplify the RHS first for C++17 and bug 71104. */
5772 gimple_predicate initial_pred
= initial_rhs_predicate_for (*to_p
);
5773 ret
= gimplify_expr (from_p
, pre_p
, post_p
, initial_pred
, fb_rvalue
);
5774 if (ret
== GS_ERROR
)
5777 /* Then gimplify the LHS. */
5778 /* If we gimplified the RHS to a CALL_EXPR and that call may return
5779 twice we have to make sure to gimplify into non-SSA as otherwise
5780 the abnormal edge added later will make those defs not dominate
5782 ??? Technically this applies only to the registers used in the
5783 resulting non-register *TO_P. */
5784 bool saved_into_ssa
= gimplify_ctxp
->into_ssa
;
5786 && TREE_CODE (*from_p
) == CALL_EXPR
5787 && call_expr_flags (*from_p
) & ECF_RETURNS_TWICE
)
5788 gimplify_ctxp
->into_ssa
= false;
5789 ret
= gimplify_expr (to_p
, pre_p
, post_p
, is_gimple_lvalue
, fb_lvalue
);
5790 gimplify_ctxp
->into_ssa
= saved_into_ssa
;
5791 if (ret
== GS_ERROR
)
5794 /* Now that the LHS is gimplified, re-gimplify the RHS if our initial
5795 guess for the predicate was wrong. */
5796 gimple_predicate final_pred
= rhs_predicate_for (*to_p
);
5797 if (final_pred
!= initial_pred
)
5799 ret
= gimplify_expr (from_p
, pre_p
, post_p
, final_pred
, fb_rvalue
);
5800 if (ret
== GS_ERROR
)
5804 /* In case of va_arg internal fn wrappped in a WITH_SIZE_EXPR, add the type
5805 size as argument to the call. */
5806 if (TREE_CODE (*from_p
) == WITH_SIZE_EXPR
)
5808 tree call
= TREE_OPERAND (*from_p
, 0);
5809 tree vlasize
= TREE_OPERAND (*from_p
, 1);
5811 if (TREE_CODE (call
) == CALL_EXPR
5812 && CALL_EXPR_IFN (call
) == IFN_VA_ARG
)
5814 int nargs
= call_expr_nargs (call
);
5815 tree type
= TREE_TYPE (call
);
5816 tree ap
= CALL_EXPR_ARG (call
, 0);
5817 tree tag
= CALL_EXPR_ARG (call
, 1);
5818 tree aptag
= CALL_EXPR_ARG (call
, 2);
5819 tree newcall
= build_call_expr_internal_loc (EXPR_LOCATION (call
),
5823 TREE_OPERAND (*from_p
, 0) = newcall
;
5827 /* Now see if the above changed *from_p to something we handle specially. */
5828 ret
= gimplify_modify_expr_rhs (expr_p
, from_p
, to_p
, pre_p
, post_p
,
5830 if (ret
!= GS_UNHANDLED
)
5833 /* If we've got a variable sized assignment between two lvalues (i.e. does
5834 not involve a call), then we can make things a bit more straightforward
5835 by converting the assignment to memcpy or memset. */
5836 if (TREE_CODE (*from_p
) == WITH_SIZE_EXPR
)
5838 tree from
= TREE_OPERAND (*from_p
, 0);
5839 tree size
= TREE_OPERAND (*from_p
, 1);
5841 if (TREE_CODE (from
) == CONSTRUCTOR
)
5842 return gimplify_modify_expr_to_memset (expr_p
, size
, want_value
, pre_p
);
5844 if (is_gimple_addressable (from
))
5847 return gimplify_modify_expr_to_memcpy (expr_p
, size
, want_value
,
5852 /* Transform partial stores to non-addressable complex variables into
5853 total stores. This allows us to use real instead of virtual operands
5854 for these variables, which improves optimization. */
5855 if ((TREE_CODE (*to_p
) == REALPART_EXPR
5856 || TREE_CODE (*to_p
) == IMAGPART_EXPR
)
5857 && is_gimple_reg (TREE_OPERAND (*to_p
, 0)))
5858 return gimplify_modify_expr_complex_part (expr_p
, pre_p
, want_value
);
5860 /* Try to alleviate the effects of the gimplification creating artificial
5861 temporaries (see for example is_gimple_reg_rhs) on the debug info, but
5862 make sure not to create DECL_DEBUG_EXPR links across functions. */
5863 if (!gimplify_ctxp
->into_ssa
5865 && DECL_IGNORED_P (*from_p
)
5867 && !DECL_IGNORED_P (*to_p
)
5868 && decl_function_context (*to_p
) == current_function_decl
5869 && decl_function_context (*from_p
) == current_function_decl
)
5871 if (!DECL_NAME (*from_p
) && DECL_NAME (*to_p
))
5873 = create_tmp_var_name (IDENTIFIER_POINTER (DECL_NAME (*to_p
)));
5874 DECL_HAS_DEBUG_EXPR_P (*from_p
) = 1;
5875 SET_DECL_DEBUG_EXPR (*from_p
, *to_p
);
5878 if (want_value
&& TREE_THIS_VOLATILE (*to_p
))
5879 *from_p
= get_initialized_tmp_var (*from_p
, pre_p
, post_p
);
5881 if (TREE_CODE (*from_p
) == CALL_EXPR
)
5883 /* Since the RHS is a CALL_EXPR, we need to create a GIMPLE_CALL
5884 instead of a GIMPLE_ASSIGN. */
5886 if (CALL_EXPR_FN (*from_p
) == NULL_TREE
)
5888 /* Gimplify internal functions created in the FEs. */
5889 int nargs
= call_expr_nargs (*from_p
), i
;
5890 enum internal_fn ifn
= CALL_EXPR_IFN (*from_p
);
5891 auto_vec
<tree
> vargs (nargs
);
5893 for (i
= 0; i
< nargs
; i
++)
5895 gimplify_arg (&CALL_EXPR_ARG (*from_p
, i
), pre_p
,
5896 EXPR_LOCATION (*from_p
));
5897 vargs
.quick_push (CALL_EXPR_ARG (*from_p
, i
));
5899 call_stmt
= gimple_build_call_internal_vec (ifn
, vargs
);
5900 gimple_call_set_nothrow (call_stmt
, TREE_NOTHROW (*from_p
));
5901 gimple_set_location (call_stmt
, EXPR_LOCATION (*expr_p
));
5905 tree fnptrtype
= TREE_TYPE (CALL_EXPR_FN (*from_p
));
5906 CALL_EXPR_FN (*from_p
) = TREE_OPERAND (CALL_EXPR_FN (*from_p
), 0);
5907 STRIP_USELESS_TYPE_CONVERSION (CALL_EXPR_FN (*from_p
));
5908 tree fndecl
= get_callee_fndecl (*from_p
);
5910 && fndecl_built_in_p (fndecl
, BUILT_IN_EXPECT
)
5911 && call_expr_nargs (*from_p
) == 3)
5912 call_stmt
= gimple_build_call_internal (IFN_BUILTIN_EXPECT
, 3,
5913 CALL_EXPR_ARG (*from_p
, 0),
5914 CALL_EXPR_ARG (*from_p
, 1),
5915 CALL_EXPR_ARG (*from_p
, 2));
5918 call_stmt
= gimple_build_call_from_tree (*from_p
, fnptrtype
);
5921 notice_special_calls (call_stmt
);
5922 if (!gimple_call_noreturn_p (call_stmt
) || !should_remove_lhs_p (*to_p
))
5923 gimple_call_set_lhs (call_stmt
, *to_p
);
5924 else if (TREE_CODE (*to_p
) == SSA_NAME
)
5925 /* The above is somewhat premature, avoid ICEing later for a
5926 SSA name w/o a definition. We may have uses in the GIMPLE IL.
5927 ??? This doesn't make it a default-def. */
5928 SSA_NAME_DEF_STMT (*to_p
) = gimple_build_nop ();
5934 assign
= gimple_build_assign (*to_p
, *from_p
);
5935 gimple_set_location (assign
, EXPR_LOCATION (*expr_p
));
5936 if (COMPARISON_CLASS_P (*from_p
))
5937 gimple_set_no_warning (assign
, TREE_NO_WARNING (*from_p
));
5940 if (gimplify_ctxp
->into_ssa
&& is_gimple_reg (*to_p
))
5942 /* We should have got an SSA name from the start. */
5943 gcc_assert (TREE_CODE (*to_p
) == SSA_NAME
5944 || ! gimple_in_ssa_p (cfun
));
5947 gimplify_seq_add_stmt (pre_p
, assign
);
5948 gsi
= gsi_last (*pre_p
);
5949 maybe_fold_stmt (&gsi
);
5953 *expr_p
= TREE_THIS_VOLATILE (*to_p
) ? *from_p
: unshare_expr (*to_p
);
5962 /* Gimplify a comparison between two variable-sized objects. Do this
5963 with a call to BUILT_IN_MEMCMP. */
5965 static enum gimplify_status
5966 gimplify_variable_sized_compare (tree
*expr_p
)
5968 location_t loc
= EXPR_LOCATION (*expr_p
);
5969 tree op0
= TREE_OPERAND (*expr_p
, 0);
5970 tree op1
= TREE_OPERAND (*expr_p
, 1);
5971 tree t
, arg
, dest
, src
, expr
;
5973 arg
= TYPE_SIZE_UNIT (TREE_TYPE (op0
));
5974 arg
= unshare_expr (arg
);
5975 arg
= SUBSTITUTE_PLACEHOLDER_IN_EXPR (arg
, op0
);
5976 src
= build_fold_addr_expr_loc (loc
, op1
);
5977 dest
= build_fold_addr_expr_loc (loc
, op0
);
5978 t
= builtin_decl_implicit (BUILT_IN_MEMCMP
);
5979 t
= build_call_expr_loc (loc
, t
, 3, dest
, src
, arg
);
5982 = build2 (TREE_CODE (*expr_p
), TREE_TYPE (*expr_p
), t
, integer_zero_node
);
5983 SET_EXPR_LOCATION (expr
, loc
);
5989 /* Gimplify a comparison between two aggregate objects of integral scalar
5990 mode as a comparison between the bitwise equivalent scalar values. */
5992 static enum gimplify_status
5993 gimplify_scalar_mode_aggregate_compare (tree
*expr_p
)
5995 location_t loc
= EXPR_LOCATION (*expr_p
);
5996 tree op0
= TREE_OPERAND (*expr_p
, 0);
5997 tree op1
= TREE_OPERAND (*expr_p
, 1);
5999 tree type
= TREE_TYPE (op0
);
6000 tree scalar_type
= lang_hooks
.types
.type_for_mode (TYPE_MODE (type
), 1);
6002 op0
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, scalar_type
, op0
);
6003 op1
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, scalar_type
, op1
);
6006 = fold_build2_loc (loc
, TREE_CODE (*expr_p
), TREE_TYPE (*expr_p
), op0
, op1
);
6011 /* Gimplify an expression sequence. This function gimplifies each
6012 expression and rewrites the original expression with the last
6013 expression of the sequence in GIMPLE form.
6015 PRE_P points to the list where the side effects for all the
6016 expressions in the sequence will be emitted.
6018 WANT_VALUE is true when the result of the last COMPOUND_EXPR is used. */
6020 static enum gimplify_status
6021 gimplify_compound_expr (tree
*expr_p
, gimple_seq
*pre_p
, bool want_value
)
6027 tree
*sub_p
= &TREE_OPERAND (t
, 0);
6029 if (TREE_CODE (*sub_p
) == COMPOUND_EXPR
)
6030 gimplify_compound_expr (sub_p
, pre_p
, false);
6032 gimplify_stmt (sub_p
, pre_p
);
6034 t
= TREE_OPERAND (t
, 1);
6036 while (TREE_CODE (t
) == COMPOUND_EXPR
);
6043 gimplify_stmt (expr_p
, pre_p
);
6048 /* Gimplify a SAVE_EXPR node. EXPR_P points to the expression to
6049 gimplify. After gimplification, EXPR_P will point to a new temporary
6050 that holds the original value of the SAVE_EXPR node.
6052 PRE_P points to the list where side effects that must happen before
6053 *EXPR_P should be stored. */
6055 static enum gimplify_status
6056 gimplify_save_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
)
6058 enum gimplify_status ret
= GS_ALL_DONE
;
6061 gcc_assert (TREE_CODE (*expr_p
) == SAVE_EXPR
);
6062 val
= TREE_OPERAND (*expr_p
, 0);
6064 /* If the SAVE_EXPR has not been resolved, then evaluate it once. */
6065 if (!SAVE_EXPR_RESOLVED_P (*expr_p
))
6067 /* The operand may be a void-valued expression. It is
6068 being executed only for its side-effects. */
6069 if (TREE_TYPE (val
) == void_type_node
)
6071 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
6072 is_gimple_stmt
, fb_none
);
6076 /* The temporary may not be an SSA name as later abnormal and EH
6077 control flow may invalidate use/def domination. When in SSA
6078 form then assume there are no such issues and SAVE_EXPRs only
6079 appear via GENERIC foldings. */
6080 val
= get_initialized_tmp_var (val
, pre_p
, post_p
,
6081 gimple_in_ssa_p (cfun
));
6083 TREE_OPERAND (*expr_p
, 0) = val
;
6084 SAVE_EXPR_RESOLVED_P (*expr_p
) = 1;
6092 /* Rewrite the ADDR_EXPR node pointed to by EXPR_P
6099 PRE_P points to the list where side effects that must happen before
6100 *EXPR_P should be stored.
6102 POST_P points to the list where side effects that must happen after
6103 *EXPR_P should be stored. */
6105 static enum gimplify_status
6106 gimplify_addr_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
)
6108 tree expr
= *expr_p
;
6109 tree op0
= TREE_OPERAND (expr
, 0);
6110 enum gimplify_status ret
;
6111 location_t loc
= EXPR_LOCATION (*expr_p
);
6113 switch (TREE_CODE (op0
))
6117 /* Check if we are dealing with an expression of the form '&*ptr'.
6118 While the front end folds away '&*ptr' into 'ptr', these
6119 expressions may be generated internally by the compiler (e.g.,
6120 builtins like __builtin_va_end). */
6121 /* Caution: the silent array decomposition semantics we allow for
6122 ADDR_EXPR means we can't always discard the pair. */
6123 /* Gimplification of the ADDR_EXPR operand may drop
6124 cv-qualification conversions, so make sure we add them if
6127 tree op00
= TREE_OPERAND (op0
, 0);
6128 tree t_expr
= TREE_TYPE (expr
);
6129 tree t_op00
= TREE_TYPE (op00
);
6131 if (!useless_type_conversion_p (t_expr
, t_op00
))
6132 op00
= fold_convert_loc (loc
, TREE_TYPE (expr
), op00
);
6138 case VIEW_CONVERT_EXPR
:
6139 /* Take the address of our operand and then convert it to the type of
6142 ??? The interactions of VIEW_CONVERT_EXPR and aliasing is not at
6143 all clear. The impact of this transformation is even less clear. */
6145 /* If the operand is a useless conversion, look through it. Doing so
6146 guarantees that the ADDR_EXPR and its operand will remain of the
6148 if (tree_ssa_useless_type_conversion (TREE_OPERAND (op0
, 0)))
6149 op0
= TREE_OPERAND (op0
, 0);
6151 *expr_p
= fold_convert_loc (loc
, TREE_TYPE (expr
),
6152 build_fold_addr_expr_loc (loc
,
6153 TREE_OPERAND (op0
, 0)));
6158 if (integer_zerop (TREE_OPERAND (op0
, 1)))
6159 goto do_indirect_ref
;
6164 /* If we see a call to a declared builtin or see its address
6165 being taken (we can unify those cases here) then we can mark
6166 the builtin for implicit generation by GCC. */
6167 if (TREE_CODE (op0
) == FUNCTION_DECL
6168 && fndecl_built_in_p (op0
, BUILT_IN_NORMAL
)
6169 && builtin_decl_declared_p (DECL_FUNCTION_CODE (op0
)))
6170 set_builtin_decl_implicit_p (DECL_FUNCTION_CODE (op0
), true);
6172 /* We use fb_either here because the C frontend sometimes takes
6173 the address of a call that returns a struct; see
6174 gcc.dg/c99-array-lval-1.c. The gimplifier will correctly make
6175 the implied temporary explicit. */
6177 /* Make the operand addressable. */
6178 ret
= gimplify_expr (&TREE_OPERAND (expr
, 0), pre_p
, post_p
,
6179 is_gimple_addressable
, fb_either
);
6180 if (ret
== GS_ERROR
)
6183 /* Then mark it. Beware that it may not be possible to do so directly
6184 if a temporary has been created by the gimplification. */
6185 prepare_gimple_addressable (&TREE_OPERAND (expr
, 0), pre_p
);
6187 op0
= TREE_OPERAND (expr
, 0);
6189 /* For various reasons, the gimplification of the expression
6190 may have made a new INDIRECT_REF. */
6191 if (TREE_CODE (op0
) == INDIRECT_REF
6192 || (TREE_CODE (op0
) == MEM_REF
6193 && integer_zerop (TREE_OPERAND (op0
, 1))))
6194 goto do_indirect_ref
;
6196 mark_addressable (TREE_OPERAND (expr
, 0));
6198 /* The FEs may end up building ADDR_EXPRs early on a decl with
6199 an incomplete type. Re-build ADDR_EXPRs in canonical form
6201 if (!types_compatible_p (TREE_TYPE (op0
), TREE_TYPE (TREE_TYPE (expr
))))
6202 *expr_p
= build_fold_addr_expr (op0
);
6204 /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly. */
6205 recompute_tree_invariant_for_addr_expr (*expr_p
);
6207 /* If we re-built the ADDR_EXPR add a conversion to the original type
6209 if (!useless_type_conversion_p (TREE_TYPE (expr
), TREE_TYPE (*expr_p
)))
6210 *expr_p
= fold_convert (TREE_TYPE (expr
), *expr_p
);
6218 /* Gimplify the operands of an ASM_EXPR. Input operands should be a gimple
6219 value; output operands should be a gimple lvalue. */
6221 static enum gimplify_status
6222 gimplify_asm_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
)
6226 const char **oconstraints
;
6229 const char *constraint
;
6230 bool allows_mem
, allows_reg
, is_inout
;
6231 enum gimplify_status ret
, tret
;
6233 vec
<tree
, va_gc
> *inputs
;
6234 vec
<tree
, va_gc
> *outputs
;
6235 vec
<tree
, va_gc
> *clobbers
;
6236 vec
<tree
, va_gc
> *labels
;
6240 noutputs
= list_length (ASM_OUTPUTS (expr
));
6241 oconstraints
= (const char **) alloca ((noutputs
) * sizeof (const char *));
6249 link_next
= NULL_TREE
;
6250 for (i
= 0, link
= ASM_OUTPUTS (expr
); link
; ++i
, link
= link_next
)
6253 size_t constraint_len
;
6255 link_next
= TREE_CHAIN (link
);
6259 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link
)));
6260 constraint_len
= strlen (constraint
);
6261 if (constraint_len
== 0)
6264 ok
= parse_output_constraint (&constraint
, i
, 0, 0,
6265 &allows_mem
, &allows_reg
, &is_inout
);
6272 /* If we can't make copies, we can only accept memory.
6273 Similarly for VLAs. */
6274 tree outtype
= TREE_TYPE (TREE_VALUE (link
));
6275 if (outtype
!= error_mark_node
6276 && (TREE_ADDRESSABLE (outtype
)
6277 || !COMPLETE_TYPE_P (outtype
)
6278 || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (outtype
))))
6284 error ("impossible constraint in %<asm%>");
6285 error ("non-memory output %d must stay in memory", i
);
6290 if (!allows_reg
&& allows_mem
)
6291 mark_addressable (TREE_VALUE (link
));
6293 tret
= gimplify_expr (&TREE_VALUE (link
), pre_p
, post_p
,
6294 is_inout
? is_gimple_min_lval
: is_gimple_lvalue
,
6295 fb_lvalue
| fb_mayfail
);
6296 if (tret
== GS_ERROR
)
6298 error ("invalid lvalue in %<asm%> output %d", i
);
6302 /* If the constraint does not allow memory make sure we gimplify
6303 it to a register if it is not already but its base is. This
6304 happens for complex and vector components. */
6307 tree op
= TREE_VALUE (link
);
6308 if (! is_gimple_val (op
)
6309 && is_gimple_reg_type (TREE_TYPE (op
))
6310 && is_gimple_reg (get_base_address (op
)))
6312 tree tem
= create_tmp_reg (TREE_TYPE (op
));
6316 ass
= build2 (MODIFY_EXPR
, TREE_TYPE (tem
),
6317 tem
, unshare_expr (op
));
6318 gimplify_and_add (ass
, pre_p
);
6320 ass
= build2 (MODIFY_EXPR
, TREE_TYPE (tem
), op
, tem
);
6321 gimplify_and_add (ass
, post_p
);
6323 TREE_VALUE (link
) = tem
;
6328 vec_safe_push (outputs
, link
);
6329 TREE_CHAIN (link
) = NULL_TREE
;
6333 /* An input/output operand. To give the optimizers more
6334 flexibility, split it into separate input and output
6337 /* Buffer big enough to format a 32-bit UINT_MAX into. */
6340 /* Turn the in/out constraint into an output constraint. */
6341 char *p
= xstrdup (constraint
);
6343 TREE_VALUE (TREE_PURPOSE (link
)) = build_string (constraint_len
, p
);
6345 /* And add a matching input constraint. */
6348 sprintf (buf
, "%u", i
);
6350 /* If there are multiple alternatives in the constraint,
6351 handle each of them individually. Those that allow register
6352 will be replaced with operand number, the others will stay
6354 if (strchr (p
, ',') != NULL
)
6356 size_t len
= 0, buflen
= strlen (buf
);
6357 char *beg
, *end
, *str
, *dst
;
6361 end
= strchr (beg
, ',');
6363 end
= strchr (beg
, '\0');
6364 if ((size_t) (end
- beg
) < buflen
)
6367 len
+= end
- beg
+ 1;
6374 str
= (char *) alloca (len
);
6375 for (beg
= p
+ 1, dst
= str
;;)
6378 bool mem_p
, reg_p
, inout_p
;
6380 end
= strchr (beg
, ',');
6385 parse_output_constraint (&tem
, i
, 0, 0,
6386 &mem_p
, ®_p
, &inout_p
);
6391 memcpy (dst
, buf
, buflen
);
6400 memcpy (dst
, beg
, len
);
6409 input
= build_string (dst
- str
, str
);
6412 input
= build_string (strlen (buf
), buf
);
6415 input
= build_string (constraint_len
- 1, constraint
+ 1);
6419 input
= build_tree_list (build_tree_list (NULL_TREE
, input
),
6420 unshare_expr (TREE_VALUE (link
)));
6421 ASM_INPUTS (expr
) = chainon (ASM_INPUTS (expr
), input
);
6425 link_next
= NULL_TREE
;
6426 for (link
= ASM_INPUTS (expr
); link
; ++i
, link
= link_next
)
6428 link_next
= TREE_CHAIN (link
);
6429 constraint
= TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link
)));
6430 parse_input_constraint (&constraint
, 0, 0, noutputs
, 0,
6431 oconstraints
, &allows_mem
, &allows_reg
);
6433 /* If we can't make copies, we can only accept memory. */
6434 tree intype
= TREE_TYPE (TREE_VALUE (link
));
6435 if (intype
!= error_mark_node
6436 && (TREE_ADDRESSABLE (intype
)
6437 || !COMPLETE_TYPE_P (intype
)
6438 || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (intype
))))
6444 error ("impossible constraint in %<asm%>");
6445 error ("non-memory input %d must stay in memory", i
);
6450 /* If the operand is a memory input, it should be an lvalue. */
6451 if (!allows_reg
&& allows_mem
)
6453 tree inputv
= TREE_VALUE (link
);
6454 STRIP_NOPS (inputv
);
6455 if (TREE_CODE (inputv
) == PREDECREMENT_EXPR
6456 || TREE_CODE (inputv
) == PREINCREMENT_EXPR
6457 || TREE_CODE (inputv
) == POSTDECREMENT_EXPR
6458 || TREE_CODE (inputv
) == POSTINCREMENT_EXPR
6459 || TREE_CODE (inputv
) == MODIFY_EXPR
)
6460 TREE_VALUE (link
) = error_mark_node
;
6461 tret
= gimplify_expr (&TREE_VALUE (link
), pre_p
, post_p
,
6462 is_gimple_lvalue
, fb_lvalue
| fb_mayfail
);
6463 if (tret
!= GS_ERROR
)
6465 /* Unlike output operands, memory inputs are not guaranteed
6466 to be lvalues by the FE, and while the expressions are
6467 marked addressable there, if it is e.g. a statement
6468 expression, temporaries in it might not end up being
6469 addressable. They might be already used in the IL and thus
6470 it is too late to make them addressable now though. */
6471 tree x
= TREE_VALUE (link
);
6472 while (handled_component_p (x
))
6473 x
= TREE_OPERAND (x
, 0);
6474 if (TREE_CODE (x
) == MEM_REF
6475 && TREE_CODE (TREE_OPERAND (x
, 0)) == ADDR_EXPR
)
6476 x
= TREE_OPERAND (TREE_OPERAND (x
, 0), 0);
6478 || TREE_CODE (x
) == PARM_DECL
6479 || TREE_CODE (x
) == RESULT_DECL
)
6480 && !TREE_ADDRESSABLE (x
)
6481 && is_gimple_reg (x
))
6483 warning_at (EXPR_LOC_OR_LOC (TREE_VALUE (link
),
6485 "memory input %d is not directly addressable",
6487 prepare_gimple_addressable (&TREE_VALUE (link
), pre_p
);
6490 mark_addressable (TREE_VALUE (link
));
6491 if (tret
== GS_ERROR
)
6493 error_at (EXPR_LOC_OR_LOC (TREE_VALUE (link
), input_location
),
6494 "memory input %d is not directly addressable", i
);
6500 tret
= gimplify_expr (&TREE_VALUE (link
), pre_p
, post_p
,
6501 is_gimple_asm_val
, fb_rvalue
);
6502 if (tret
== GS_ERROR
)
6506 TREE_CHAIN (link
) = NULL_TREE
;
6507 vec_safe_push (inputs
, link
);
6510 link_next
= NULL_TREE
;
6511 for (link
= ASM_CLOBBERS (expr
); link
; ++i
, link
= link_next
)
6513 link_next
= TREE_CHAIN (link
);
6514 TREE_CHAIN (link
) = NULL_TREE
;
6515 vec_safe_push (clobbers
, link
);
6518 link_next
= NULL_TREE
;
6519 for (link
= ASM_LABELS (expr
); link
; ++i
, link
= link_next
)
6521 link_next
= TREE_CHAIN (link
);
6522 TREE_CHAIN (link
) = NULL_TREE
;
6523 vec_safe_push (labels
, link
);
6526 /* Do not add ASMs with errors to the gimple IL stream. */
6527 if (ret
!= GS_ERROR
)
6529 stmt
= gimple_build_asm_vec (TREE_STRING_POINTER (ASM_STRING (expr
)),
6530 inputs
, outputs
, clobbers
, labels
);
6532 gimple_asm_set_volatile (stmt
, ASM_VOLATILE_P (expr
) || noutputs
== 0);
6533 gimple_asm_set_input (stmt
, ASM_INPUT_P (expr
));
6534 gimple_asm_set_inline (stmt
, ASM_INLINE_P (expr
));
6536 gimplify_seq_add_stmt (pre_p
, stmt
);
6542 /* Gimplify a CLEANUP_POINT_EXPR. Currently this works by adding
6543 GIMPLE_WITH_CLEANUP_EXPRs to the prequeue as we encounter cleanups while
6544 gimplifying the body, and converting them to TRY_FINALLY_EXPRs when we
6545 return to this function.
6547 FIXME should we complexify the prequeue handling instead? Or use flags
6548 for all the cleanups and let the optimizer tighten them up? The current
6549 code seems pretty fragile; it will break on a cleanup within any
6550 non-conditional nesting. But any such nesting would be broken, anyway;
6551 we can't write a TRY_FINALLY_EXPR that starts inside a nesting construct
6552 and continues out of it. We can do that at the RTL level, though, so
6553 having an optimizer to tighten up try/finally regions would be a Good
6556 static enum gimplify_status
6557 gimplify_cleanup_point_expr (tree
*expr_p
, gimple_seq
*pre_p
)
6559 gimple_stmt_iterator iter
;
6560 gimple_seq body_sequence
= NULL
;
6562 tree temp
= voidify_wrapper_expr (*expr_p
, NULL
);
6564 /* We only care about the number of conditions between the innermost
6565 CLEANUP_POINT_EXPR and the cleanup. So save and reset the count and
6566 any cleanups collected outside the CLEANUP_POINT_EXPR. */
6567 int old_conds
= gimplify_ctxp
->conditions
;
6568 gimple_seq old_cleanups
= gimplify_ctxp
->conditional_cleanups
;
6569 bool old_in_cleanup_point_expr
= gimplify_ctxp
->in_cleanup_point_expr
;
6570 gimplify_ctxp
->conditions
= 0;
6571 gimplify_ctxp
->conditional_cleanups
= NULL
;
6572 gimplify_ctxp
->in_cleanup_point_expr
= true;
6574 gimplify_stmt (&TREE_OPERAND (*expr_p
, 0), &body_sequence
);
6576 gimplify_ctxp
->conditions
= old_conds
;
6577 gimplify_ctxp
->conditional_cleanups
= old_cleanups
;
6578 gimplify_ctxp
->in_cleanup_point_expr
= old_in_cleanup_point_expr
;
6580 for (iter
= gsi_start (body_sequence
); !gsi_end_p (iter
); )
6582 gimple
*wce
= gsi_stmt (iter
);
6584 if (gimple_code (wce
) == GIMPLE_WITH_CLEANUP_EXPR
)
6586 if (gsi_one_before_end_p (iter
))
6588 /* Note that gsi_insert_seq_before and gsi_remove do not
6589 scan operands, unlike some other sequence mutators. */
6590 if (!gimple_wce_cleanup_eh_only (wce
))
6591 gsi_insert_seq_before_without_update (&iter
,
6592 gimple_wce_cleanup (wce
),
6594 gsi_remove (&iter
, true);
6601 enum gimple_try_flags kind
;
6603 if (gimple_wce_cleanup_eh_only (wce
))
6604 kind
= GIMPLE_TRY_CATCH
;
6606 kind
= GIMPLE_TRY_FINALLY
;
6607 seq
= gsi_split_seq_after (iter
);
6609 gtry
= gimple_build_try (seq
, gimple_wce_cleanup (wce
), kind
);
6610 /* Do not use gsi_replace here, as it may scan operands.
6611 We want to do a simple structural modification only. */
6612 gsi_set_stmt (&iter
, gtry
);
6613 iter
= gsi_start (gtry
->eval
);
6620 gimplify_seq_add_seq (pre_p
, body_sequence
);
6633 /* Insert a cleanup marker for gimplify_cleanup_point_expr. CLEANUP
6634 is the cleanup action required. EH_ONLY is true if the cleanup should
6635 only be executed if an exception is thrown, not on normal exit.
6636 If FORCE_UNCOND is true perform the cleanup unconditionally; this is
6637 only valid for clobbers. */
6640 gimple_push_cleanup (tree var
, tree cleanup
, bool eh_only
, gimple_seq
*pre_p
,
6641 bool force_uncond
= false)
6644 gimple_seq cleanup_stmts
= NULL
;
6646 /* Errors can result in improperly nested cleanups. Which results in
6647 confusion when trying to resolve the GIMPLE_WITH_CLEANUP_EXPR. */
6651 if (gimple_conditional_context ())
6653 /* If we're in a conditional context, this is more complex. We only
6654 want to run the cleanup if we actually ran the initialization that
6655 necessitates it, but we want to run it after the end of the
6656 conditional context. So we wrap the try/finally around the
6657 condition and use a flag to determine whether or not to actually
6658 run the destructor. Thus
6662 becomes (approximately)
6666 if (test) { A::A(temp); flag = 1; val = f(temp); }
6669 if (flag) A::~A(temp);
6675 gimplify_stmt (&cleanup
, &cleanup_stmts
);
6676 wce
= gimple_build_wce (cleanup_stmts
);
6677 gimplify_seq_add_stmt (&gimplify_ctxp
->conditional_cleanups
, wce
);
6681 tree flag
= create_tmp_var (boolean_type_node
, "cleanup");
6682 gassign
*ffalse
= gimple_build_assign (flag
, boolean_false_node
);
6683 gassign
*ftrue
= gimple_build_assign (flag
, boolean_true_node
);
6685 cleanup
= build3 (COND_EXPR
, void_type_node
, flag
, cleanup
, NULL
);
6686 gimplify_stmt (&cleanup
, &cleanup_stmts
);
6687 wce
= gimple_build_wce (cleanup_stmts
);
6689 gimplify_seq_add_stmt (&gimplify_ctxp
->conditional_cleanups
, ffalse
);
6690 gimplify_seq_add_stmt (&gimplify_ctxp
->conditional_cleanups
, wce
);
6691 gimplify_seq_add_stmt (pre_p
, ftrue
);
6693 /* Because of this manipulation, and the EH edges that jump
6694 threading cannot redirect, the temporary (VAR) will appear
6695 to be used uninitialized. Don't warn. */
6696 TREE_NO_WARNING (var
) = 1;
6701 gimplify_stmt (&cleanup
, &cleanup_stmts
);
6702 wce
= gimple_build_wce (cleanup_stmts
);
6703 gimple_wce_set_cleanup_eh_only (wce
, eh_only
);
6704 gimplify_seq_add_stmt (pre_p
, wce
);
6708 /* Gimplify a TARGET_EXPR which doesn't appear on the rhs of an INIT_EXPR. */
6710 static enum gimplify_status
6711 gimplify_target_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
)
6713 tree targ
= *expr_p
;
6714 tree temp
= TARGET_EXPR_SLOT (targ
);
6715 tree init
= TARGET_EXPR_INITIAL (targ
);
6716 enum gimplify_status ret
;
6718 bool unpoison_empty_seq
= false;
6719 gimple_stmt_iterator unpoison_it
;
6723 tree cleanup
= NULL_TREE
;
6725 /* TARGET_EXPR temps aren't part of the enclosing block, so add it
6726 to the temps list. Handle also variable length TARGET_EXPRs. */
6727 if (!poly_int_tree_p (DECL_SIZE (temp
)))
6729 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (temp
)))
6730 gimplify_type_sizes (TREE_TYPE (temp
), pre_p
);
6731 gimplify_vla_decl (temp
, pre_p
);
6735 /* Save location where we need to place unpoisoning. It's possible
6736 that a variable will be converted to needs_to_live_in_memory. */
6737 unpoison_it
= gsi_last (*pre_p
);
6738 unpoison_empty_seq
= gsi_end_p (unpoison_it
);
6740 gimple_add_tmp_var (temp
);
6743 /* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the
6744 expression is supposed to initialize the slot. */
6745 if (VOID_TYPE_P (TREE_TYPE (init
)))
6746 ret
= gimplify_expr (&init
, pre_p
, post_p
, is_gimple_stmt
, fb_none
);
6749 tree init_expr
= build2 (INIT_EXPR
, void_type_node
, temp
, init
);
6751 ret
= gimplify_expr (&init
, pre_p
, post_p
, is_gimple_stmt
, fb_none
);
6753 ggc_free (init_expr
);
6755 if (ret
== GS_ERROR
)
6757 /* PR c++/28266 Make sure this is expanded only once. */
6758 TARGET_EXPR_INITIAL (targ
) = NULL_TREE
;
6762 gimplify_and_add (init
, pre_p
);
6764 /* If needed, push the cleanup for the temp. */
6765 if (TARGET_EXPR_CLEANUP (targ
))
6767 if (CLEANUP_EH_ONLY (targ
))
6768 gimple_push_cleanup (temp
, TARGET_EXPR_CLEANUP (targ
),
6769 CLEANUP_EH_ONLY (targ
), pre_p
);
6771 cleanup
= TARGET_EXPR_CLEANUP (targ
);
6774 /* Add a clobber for the temporary going out of scope, like
6775 gimplify_bind_expr. */
6776 if (gimplify_ctxp
->in_cleanup_point_expr
6777 && needs_to_live_in_memory (temp
))
6779 if (flag_stack_reuse
== SR_ALL
)
6781 tree clobber
= build_clobber (TREE_TYPE (temp
));
6782 clobber
= build2 (MODIFY_EXPR
, TREE_TYPE (temp
), temp
, clobber
);
6783 gimple_push_cleanup (temp
, clobber
, false, pre_p
, true);
6785 if (asan_poisoned_variables
6786 && DECL_ALIGN (temp
) <= MAX_SUPPORTED_STACK_ALIGNMENT
6787 && !TREE_STATIC (temp
)
6788 && dbg_cnt (asan_use_after_scope
)
6789 && !gimplify_omp_ctxp
)
6791 tree asan_cleanup
= build_asan_poison_call_expr (temp
);
6794 if (unpoison_empty_seq
)
6795 unpoison_it
= gsi_start (*pre_p
);
6797 asan_poison_variable (temp
, false, &unpoison_it
,
6798 unpoison_empty_seq
);
6799 gimple_push_cleanup (temp
, asan_cleanup
, false, pre_p
);
6804 gimple_push_cleanup (temp
, cleanup
, false, pre_p
);
6806 /* Only expand this once. */
6807 TREE_OPERAND (targ
, 3) = init
;
6808 TARGET_EXPR_INITIAL (targ
) = NULL_TREE
;
6811 /* We should have expanded this before. */
6812 gcc_assert (DECL_SEEN_IN_BIND_EXPR_P (temp
));
6818 /* Gimplification of expression trees. */
6820 /* Gimplify an expression which appears at statement context. The
6821 corresponding GIMPLE statements are added to *SEQ_P. If *SEQ_P is
6822 NULL, a new sequence is allocated.
6824 Return true if we actually added a statement to the queue. */
6827 gimplify_stmt (tree
*stmt_p
, gimple_seq
*seq_p
)
6829 gimple_seq_node last
;
6831 last
= gimple_seq_last (*seq_p
);
6832 gimplify_expr (stmt_p
, seq_p
, NULL
, is_gimple_stmt
, fb_none
);
6833 return last
!= gimple_seq_last (*seq_p
);
6836 /* Add FIRSTPRIVATE entries for DECL in the OpenMP the surrounding parallels
6837 to CTX. If entries already exist, force them to be some flavor of private.
6838 If there is no enclosing parallel, do nothing. */
6841 omp_firstprivatize_variable (struct gimplify_omp_ctx
*ctx
, tree decl
)
6845 if (decl
== NULL
|| !DECL_P (decl
) || ctx
->region_type
== ORT_NONE
)
6850 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
)decl
);
6853 if (n
->value
& GOVD_SHARED
)
6854 n
->value
= GOVD_FIRSTPRIVATE
| (n
->value
& GOVD_SEEN
);
6855 else if (n
->value
& GOVD_MAP
)
6856 n
->value
|= GOVD_MAP_TO_ONLY
;
6860 else if ((ctx
->region_type
& ORT_TARGET
) != 0)
6862 if (ctx
->defaultmap
[GDMK_SCALAR
] & GOVD_FIRSTPRIVATE
)
6863 omp_add_variable (ctx
, decl
, GOVD_FIRSTPRIVATE
);
6865 omp_add_variable (ctx
, decl
, GOVD_MAP
| GOVD_MAP_TO_ONLY
);
6867 else if (ctx
->region_type
!= ORT_WORKSHARE
6868 && ctx
->region_type
!= ORT_TASKGROUP
6869 && ctx
->region_type
!= ORT_SIMD
6870 && ctx
->region_type
!= ORT_ACC
6871 && !(ctx
->region_type
& ORT_TARGET_DATA
))
6872 omp_add_variable (ctx
, decl
, GOVD_FIRSTPRIVATE
);
6874 ctx
= ctx
->outer_context
;
6879 /* Similarly for each of the type sizes of TYPE. */
6882 omp_firstprivatize_type_sizes (struct gimplify_omp_ctx
*ctx
, tree type
)
6884 if (type
== NULL
|| type
== error_mark_node
)
6886 type
= TYPE_MAIN_VARIANT (type
);
6888 if (ctx
->privatized_types
->add (type
))
6891 switch (TREE_CODE (type
))
6897 case FIXED_POINT_TYPE
:
6898 omp_firstprivatize_variable (ctx
, TYPE_MIN_VALUE (type
));
6899 omp_firstprivatize_variable (ctx
, TYPE_MAX_VALUE (type
));
6903 omp_firstprivatize_type_sizes (ctx
, TREE_TYPE (type
));
6904 omp_firstprivatize_type_sizes (ctx
, TYPE_DOMAIN (type
));
6909 case QUAL_UNION_TYPE
:
6912 for (field
= TYPE_FIELDS (type
); field
; field
= DECL_CHAIN (field
))
6913 if (TREE_CODE (field
) == FIELD_DECL
)
6915 omp_firstprivatize_variable (ctx
, DECL_FIELD_OFFSET (field
));
6916 omp_firstprivatize_type_sizes (ctx
, TREE_TYPE (field
));
6922 case REFERENCE_TYPE
:
6923 omp_firstprivatize_type_sizes (ctx
, TREE_TYPE (type
));
6930 omp_firstprivatize_variable (ctx
, TYPE_SIZE (type
));
6931 omp_firstprivatize_variable (ctx
, TYPE_SIZE_UNIT (type
));
6932 lang_hooks
.types
.omp_firstprivatize_type_sizes (ctx
, type
);
6935 /* Add an entry for DECL in the OMP context CTX with FLAGS. */
6938 omp_add_variable (struct gimplify_omp_ctx
*ctx
, tree decl
, unsigned int flags
)
6941 unsigned int nflags
;
6944 if (error_operand_p (decl
) || ctx
->region_type
== ORT_NONE
)
6947 /* Never elide decls whose type has TREE_ADDRESSABLE set. This means
6948 there are constructors involved somewhere. Exception is a shared clause,
6949 there is nothing privatized in that case. */
6950 if ((flags
& GOVD_SHARED
) == 0
6951 && (TREE_ADDRESSABLE (TREE_TYPE (decl
))
6952 || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl
))))
6955 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
)decl
);
6956 if (n
!= NULL
&& (n
->value
& GOVD_DATA_SHARE_CLASS
) != 0)
6958 /* We shouldn't be re-adding the decl with the same data
6960 gcc_assert ((n
->value
& GOVD_DATA_SHARE_CLASS
& flags
) == 0);
6961 nflags
= n
->value
| flags
;
6962 /* The only combination of data sharing classes we should see is
6963 FIRSTPRIVATE and LASTPRIVATE. However, OpenACC permits
6964 reduction variables to be used in data sharing clauses. */
6965 gcc_assert ((ctx
->region_type
& ORT_ACC
) != 0
6966 || ((nflags
& GOVD_DATA_SHARE_CLASS
)
6967 == (GOVD_FIRSTPRIVATE
| GOVD_LASTPRIVATE
))
6968 || (flags
& GOVD_DATA_SHARE_CLASS
) == 0);
6973 /* When adding a variable-sized variable, we have to handle all sorts
6974 of additional bits of data: the pointer replacement variable, and
6975 the parameters of the type. */
6976 if (DECL_SIZE (decl
) && TREE_CODE (DECL_SIZE (decl
)) != INTEGER_CST
)
6978 /* Add the pointer replacement variable as PRIVATE if the variable
6979 replacement is private, else FIRSTPRIVATE since we'll need the
6980 address of the original variable either for SHARED, or for the
6981 copy into or out of the context. */
6982 if (!(flags
& GOVD_LOCAL
) && ctx
->region_type
!= ORT_TASKGROUP
)
6984 if (flags
& GOVD_MAP
)
6985 nflags
= GOVD_MAP
| GOVD_MAP_TO_ONLY
| GOVD_EXPLICIT
;
6986 else if (flags
& GOVD_PRIVATE
)
6987 nflags
= GOVD_PRIVATE
;
6988 else if (((ctx
->region_type
& (ORT_TARGET
| ORT_TARGET_DATA
)) != 0
6989 && (flags
& GOVD_FIRSTPRIVATE
))
6990 || (ctx
->region_type
== ORT_TARGET_DATA
6991 && (flags
& GOVD_DATA_SHARE_CLASS
) == 0))
6992 nflags
= GOVD_PRIVATE
| GOVD_EXPLICIT
;
6994 nflags
= GOVD_FIRSTPRIVATE
;
6995 nflags
|= flags
& GOVD_SEEN
;
6996 t
= DECL_VALUE_EXPR (decl
);
6997 gcc_assert (TREE_CODE (t
) == INDIRECT_REF
);
6998 t
= TREE_OPERAND (t
, 0);
6999 gcc_assert (DECL_P (t
));
7000 omp_add_variable (ctx
, t
, nflags
);
7003 /* Add all of the variable and type parameters (which should have
7004 been gimplified to a formal temporary) as FIRSTPRIVATE. */
7005 omp_firstprivatize_variable (ctx
, DECL_SIZE_UNIT (decl
));
7006 omp_firstprivatize_variable (ctx
, DECL_SIZE (decl
));
7007 omp_firstprivatize_type_sizes (ctx
, TREE_TYPE (decl
));
7009 /* The variable-sized variable itself is never SHARED, only some form
7010 of PRIVATE. The sharing would take place via the pointer variable
7011 which we remapped above. */
7012 if (flags
& GOVD_SHARED
)
7013 flags
= GOVD_SHARED
| GOVD_DEBUG_PRIVATE
7014 | (flags
& (GOVD_SEEN
| GOVD_EXPLICIT
));
7016 /* We're going to make use of the TYPE_SIZE_UNIT at least in the
7017 alloca statement we generate for the variable, so make sure it
7018 is available. This isn't automatically needed for the SHARED
7019 case, since we won't be allocating local storage then.
7020 For local variables TYPE_SIZE_UNIT might not be gimplified yet,
7021 in this case omp_notice_variable will be called later
7022 on when it is gimplified. */
7023 else if (! (flags
& (GOVD_LOCAL
| GOVD_MAP
))
7024 && DECL_P (TYPE_SIZE_UNIT (TREE_TYPE (decl
))))
7025 omp_notice_variable (ctx
, TYPE_SIZE_UNIT (TREE_TYPE (decl
)), true);
7027 else if ((flags
& (GOVD_MAP
| GOVD_LOCAL
)) == 0
7028 && lang_hooks
.decls
.omp_privatize_by_reference (decl
))
7030 omp_firstprivatize_type_sizes (ctx
, TREE_TYPE (decl
));
7032 /* Similar to the direct variable sized case above, we'll need the
7033 size of references being privatized. */
7034 if ((flags
& GOVD_SHARED
) == 0)
7036 t
= TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl
)));
7038 omp_notice_variable (ctx
, t
, true);
7045 splay_tree_insert (ctx
->variables
, (splay_tree_key
)decl
, flags
);
7047 /* For reductions clauses in OpenACC loop directives, by default create a
7048 copy clause on the enclosing parallel construct for carrying back the
7050 if (ctx
->region_type
== ORT_ACC
&& (flags
& GOVD_REDUCTION
))
7052 struct gimplify_omp_ctx
*outer_ctx
= ctx
->outer_context
;
7055 n
= splay_tree_lookup (outer_ctx
->variables
, (splay_tree_key
)decl
);
7058 /* Ignore local variables and explicitly declared clauses. */
7059 if (n
->value
& (GOVD_LOCAL
| GOVD_EXPLICIT
))
7061 else if (outer_ctx
->region_type
== ORT_ACC_KERNELS
)
7063 /* According to the OpenACC spec, such a reduction variable
7064 should already have a copy map on a kernels construct,
7065 verify that here. */
7066 gcc_assert (!(n
->value
& GOVD_FIRSTPRIVATE
)
7067 && (n
->value
& GOVD_MAP
));
7069 else if (outer_ctx
->region_type
== ORT_ACC_PARALLEL
)
7071 /* Remove firstprivate and make it a copy map. */
7072 n
->value
&= ~GOVD_FIRSTPRIVATE
;
7073 n
->value
|= GOVD_MAP
;
7076 else if (outer_ctx
->region_type
== ORT_ACC_PARALLEL
)
7078 splay_tree_insert (outer_ctx
->variables
, (splay_tree_key
)decl
,
7079 GOVD_MAP
| GOVD_SEEN
);
7082 outer_ctx
= outer_ctx
->outer_context
;
7087 /* Notice a threadprivate variable DECL used in OMP context CTX.
7088 This just prints out diagnostics about threadprivate variable uses
7089 in untied tasks. If DECL2 is non-NULL, prevent this warning
7090 on that variable. */
7093 omp_notice_threadprivate_variable (struct gimplify_omp_ctx
*ctx
, tree decl
,
7097 struct gimplify_omp_ctx
*octx
;
7099 for (octx
= ctx
; octx
; octx
= octx
->outer_context
)
7100 if ((octx
->region_type
& ORT_TARGET
) != 0
7101 || octx
->order_concurrent
)
7103 n
= splay_tree_lookup (octx
->variables
, (splay_tree_key
)decl
);
7106 if (octx
->order_concurrent
)
7108 error ("threadprivate variable %qE used in a region with"
7109 " %<order(concurrent)%> clause", DECL_NAME (decl
));
7110 inform (octx
->location
, "enclosing region");
7114 error ("threadprivate variable %qE used in target region",
7116 inform (octx
->location
, "enclosing target region");
7118 splay_tree_insert (octx
->variables
, (splay_tree_key
)decl
, 0);
7121 splay_tree_insert (octx
->variables
, (splay_tree_key
)decl2
, 0);
7124 if (ctx
->region_type
!= ORT_UNTIED_TASK
)
7126 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
)decl
);
7129 error ("threadprivate variable %qE used in untied task",
7131 inform (ctx
->location
, "enclosing task");
7132 splay_tree_insert (ctx
->variables
, (splay_tree_key
)decl
, 0);
7135 splay_tree_insert (ctx
->variables
, (splay_tree_key
)decl2
, 0);
7139 /* Return true if global var DECL is device resident. */
7142 device_resident_p (tree decl
)
7144 tree attr
= lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (decl
));
7149 for (tree t
= TREE_VALUE (attr
); t
; t
= TREE_PURPOSE (t
))
7151 tree c
= TREE_VALUE (t
);
7152 if (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_DEVICE_RESIDENT
)
7159 /* Return true if DECL has an ACC DECLARE attribute. */
7162 is_oacc_declared (tree decl
)
7164 tree t
= TREE_CODE (decl
) == MEM_REF
? TREE_OPERAND (decl
, 0) : decl
;
7165 tree declared
= lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (t
));
7166 return declared
!= NULL_TREE
;
7169 /* Determine outer default flags for DECL mentioned in an OMP region
7170 but not declared in an enclosing clause.
7172 ??? Some compiler-generated variables (like SAVE_EXPRs) could be
7173 remapped firstprivate instead of shared. To some extent this is
7174 addressed in omp_firstprivatize_type_sizes, but not
7178 omp_default_clause (struct gimplify_omp_ctx
*ctx
, tree decl
,
7179 bool in_code
, unsigned flags
)
7181 enum omp_clause_default_kind default_kind
= ctx
->default_kind
;
7182 enum omp_clause_default_kind kind
;
7184 kind
= lang_hooks
.decls
.omp_predetermined_sharing (decl
);
7185 if (kind
!= OMP_CLAUSE_DEFAULT_UNSPECIFIED
)
7186 default_kind
= kind
;
7187 else if (VAR_P (decl
) && TREE_STATIC (decl
) && DECL_IN_CONSTANT_POOL (decl
))
7188 default_kind
= OMP_CLAUSE_DEFAULT_SHARED
;
7190 switch (default_kind
)
7192 case OMP_CLAUSE_DEFAULT_NONE
:
7196 if (ctx
->region_type
& ORT_PARALLEL
)
7198 else if ((ctx
->region_type
& ORT_TASKLOOP
) == ORT_TASKLOOP
)
7200 else if (ctx
->region_type
& ORT_TASK
)
7202 else if (ctx
->region_type
& ORT_TEAMS
)
7207 error ("%qE not specified in enclosing %qs",
7208 DECL_NAME (lang_hooks
.decls
.omp_report_decl (decl
)), rtype
);
7209 inform (ctx
->location
, "enclosing %qs", rtype
);
7212 case OMP_CLAUSE_DEFAULT_SHARED
:
7213 flags
|= GOVD_SHARED
;
7215 case OMP_CLAUSE_DEFAULT_PRIVATE
:
7216 flags
|= GOVD_PRIVATE
;
7218 case OMP_CLAUSE_DEFAULT_FIRSTPRIVATE
:
7219 flags
|= GOVD_FIRSTPRIVATE
;
7221 case OMP_CLAUSE_DEFAULT_UNSPECIFIED
:
7222 /* decl will be either GOVD_FIRSTPRIVATE or GOVD_SHARED. */
7223 gcc_assert ((ctx
->region_type
& ORT_TASK
) != 0);
7224 if (struct gimplify_omp_ctx
*octx
= ctx
->outer_context
)
7226 omp_notice_variable (octx
, decl
, in_code
);
7227 for (; octx
; octx
= octx
->outer_context
)
7231 n2
= splay_tree_lookup (octx
->variables
, (splay_tree_key
) decl
);
7232 if ((octx
->region_type
& (ORT_TARGET_DATA
| ORT_TARGET
)) != 0
7233 && (n2
== NULL
|| (n2
->value
& GOVD_DATA_SHARE_CLASS
) == 0))
7235 if (n2
&& (n2
->value
& GOVD_DATA_SHARE_CLASS
) != GOVD_SHARED
)
7237 flags
|= GOVD_FIRSTPRIVATE
;
7240 if ((octx
->region_type
& (ORT_PARALLEL
| ORT_TEAMS
)) != 0)
7242 flags
|= GOVD_SHARED
;
7248 if (TREE_CODE (decl
) == PARM_DECL
7249 || (!is_global_var (decl
)
7250 && DECL_CONTEXT (decl
) == current_function_decl
))
7251 flags
|= GOVD_FIRSTPRIVATE
;
7253 flags
|= GOVD_SHARED
;
7265 /* Determine outer default flags for DECL mentioned in an OACC region
7266 but not declared in an enclosing clause. */
7269 oacc_default_clause (struct gimplify_omp_ctx
*ctx
, tree decl
, unsigned flags
)
7272 bool on_device
= false;
7273 bool is_private
= false;
7274 bool declared
= is_oacc_declared (decl
);
7275 tree type
= TREE_TYPE (decl
);
7277 if (lang_hooks
.decls
.omp_privatize_by_reference (decl
))
7278 type
= TREE_TYPE (type
);
7280 /* For Fortran COMMON blocks, only used variables in those blocks are
7281 transfered and remapped. The block itself will have a private clause to
7282 avoid transfering the data twice.
7283 The hook evaluates to false by default. For a variable in Fortran's COMMON
7284 or EQUIVALENCE block, returns 'true' (as we have shared=false) - as only
7285 the variables in such a COMMON/EQUIVALENCE block shall be privatized not
7286 the whole block. For C++ and Fortran, it can also be true under certain
7287 other conditions, if DECL_HAS_VALUE_EXPR. */
7288 if (RECORD_OR_UNION_TYPE_P (type
))
7289 is_private
= lang_hooks
.decls
.omp_disregard_value_expr (decl
, false);
7291 if ((ctx
->region_type
& (ORT_ACC_PARALLEL
| ORT_ACC_KERNELS
)) != 0
7292 && is_global_var (decl
)
7293 && device_resident_p (decl
)
7297 flags
|= GOVD_MAP_TO_ONLY
;
7300 switch (ctx
->region_type
)
7302 case ORT_ACC_KERNELS
:
7306 flags
|= GOVD_FIRSTPRIVATE
;
7307 else if (AGGREGATE_TYPE_P (type
))
7309 /* Aggregates default to 'present_or_copy', or 'present'. */
7310 if (ctx
->default_kind
!= OMP_CLAUSE_DEFAULT_PRESENT
)
7313 flags
|= GOVD_MAP
| GOVD_MAP_FORCE_PRESENT
;
7316 /* Scalars default to 'copy'. */
7317 flags
|= GOVD_MAP
| GOVD_MAP_FORCE
;
7321 case ORT_ACC_PARALLEL
:
7322 case ORT_ACC_SERIAL
:
7323 rkind
= ctx
->region_type
== ORT_ACC_PARALLEL
? "parallel" : "serial";
7326 flags
|= GOVD_FIRSTPRIVATE
;
7327 else if (on_device
|| declared
)
7329 else if (AGGREGATE_TYPE_P (type
))
7331 /* Aggregates default to 'present_or_copy', or 'present'. */
7332 if (ctx
->default_kind
!= OMP_CLAUSE_DEFAULT_PRESENT
)
7335 flags
|= GOVD_MAP
| GOVD_MAP_FORCE_PRESENT
;
7338 /* Scalars default to 'firstprivate'. */
7339 flags
|= GOVD_FIRSTPRIVATE
;
7347 if (DECL_ARTIFICIAL (decl
))
7348 ; /* We can get compiler-generated decls, and should not complain
7350 else if (ctx
->default_kind
== OMP_CLAUSE_DEFAULT_NONE
)
7352 error ("%qE not specified in enclosing OpenACC %qs construct",
7353 DECL_NAME (lang_hooks
.decls
.omp_report_decl (decl
)), rkind
);
7354 inform (ctx
->location
, "enclosing OpenACC %qs construct", rkind
);
7356 else if (ctx
->default_kind
== OMP_CLAUSE_DEFAULT_PRESENT
)
7357 ; /* Handled above. */
7359 gcc_checking_assert (ctx
->default_kind
== OMP_CLAUSE_DEFAULT_SHARED
);
7364 /* Record the fact that DECL was used within the OMP context CTX.
7365 IN_CODE is true when real code uses DECL, and false when we should
7366 merely emit default(none) errors. Return true if DECL is going to
7367 be remapped and thus DECL shouldn't be gimplified into its
7368 DECL_VALUE_EXPR (if any). */
7371 omp_notice_variable (struct gimplify_omp_ctx
*ctx
, tree decl
, bool in_code
)
7374 unsigned flags
= in_code
? GOVD_SEEN
: 0;
7375 bool ret
= false, shared
;
7377 if (error_operand_p (decl
))
7380 if (ctx
->region_type
== ORT_NONE
)
7381 return lang_hooks
.decls
.omp_disregard_value_expr (decl
, false);
7383 if (is_global_var (decl
))
7385 /* Threadprivate variables are predetermined. */
7386 if (DECL_THREAD_LOCAL_P (decl
))
7387 return omp_notice_threadprivate_variable (ctx
, decl
, NULL_TREE
);
7389 if (DECL_HAS_VALUE_EXPR_P (decl
))
7391 if (ctx
->region_type
& ORT_ACC
)
7392 /* For OpenACC, defer expansion of value to avoid transfering
7393 privatized common block data instead of im-/explicitly transfered
7394 variables which are in common blocks. */
7398 tree value
= get_base_address (DECL_VALUE_EXPR (decl
));
7400 if (value
&& DECL_P (value
) && DECL_THREAD_LOCAL_P (value
))
7401 return omp_notice_threadprivate_variable (ctx
, decl
, value
);
7405 if (gimplify_omp_ctxp
->outer_context
== NULL
7407 && oacc_get_fn_attrib (current_function_decl
))
7409 location_t loc
= DECL_SOURCE_LOCATION (decl
);
7411 if (lookup_attribute ("omp declare target link",
7412 DECL_ATTRIBUTES (decl
)))
7415 "%qE with %<link%> clause used in %<routine%> function",
7419 else if (!lookup_attribute ("omp declare target",
7420 DECL_ATTRIBUTES (decl
)))
7423 "%qE requires a %<declare%> directive for use "
7424 "in a %<routine%> function", DECL_NAME (decl
));
7430 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
)decl
);
7431 if ((ctx
->region_type
& ORT_TARGET
) != 0)
7433 if (ctx
->region_type
& ORT_ACC
)
7434 /* For OpenACC, as remarked above, defer expansion. */
7439 ret
= lang_hooks
.decls
.omp_disregard_value_expr (decl
, shared
);
7442 unsigned nflags
= flags
;
7443 if ((ctx
->region_type
& ORT_ACC
) == 0)
7445 bool is_declare_target
= false;
7446 if (is_global_var (decl
)
7447 && varpool_node::get_create (decl
)->offloadable
)
7449 struct gimplify_omp_ctx
*octx
;
7450 for (octx
= ctx
->outer_context
;
7451 octx
; octx
= octx
->outer_context
)
7453 n
= splay_tree_lookup (octx
->variables
,
7454 (splay_tree_key
)decl
);
7456 && (n
->value
& GOVD_DATA_SHARE_CLASS
) != GOVD_SHARED
7457 && (n
->value
& GOVD_DATA_SHARE_CLASS
) != 0)
7460 is_declare_target
= octx
== NULL
;
7462 if (!is_declare_target
)
7465 enum omp_clause_defaultmap_kind kind
;
7466 if (TREE_CODE (TREE_TYPE (decl
)) == POINTER_TYPE
7467 || (TREE_CODE (TREE_TYPE (decl
)) == REFERENCE_TYPE
7468 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl
)))
7470 gdmk
= GDMK_POINTER
;
7471 else if (lang_hooks
.decls
.omp_scalar_p (decl
))
7474 gdmk
= GDMK_AGGREGATE
;
7475 kind
= lang_hooks
.decls
.omp_predetermined_mapping (decl
);
7476 if (kind
!= OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
)
7478 if (kind
== OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE
)
7479 nflags
|= GOVD_FIRSTPRIVATE
;
7480 else if (kind
== OMP_CLAUSE_DEFAULTMAP_TO
)
7481 nflags
|= GOVD_MAP
| GOVD_MAP_TO_ONLY
;
7485 else if (ctx
->defaultmap
[gdmk
] == 0)
7487 tree d
= lang_hooks
.decls
.omp_report_decl (decl
);
7488 error ("%qE not specified in enclosing %<target%>",
7490 inform (ctx
->location
, "enclosing %<target%>");
7492 else if (ctx
->defaultmap
[gdmk
]
7493 & (GOVD_MAP_0LEN_ARRAY
| GOVD_FIRSTPRIVATE
))
7494 nflags
|= ctx
->defaultmap
[gdmk
];
7497 gcc_assert (ctx
->defaultmap
[gdmk
] & GOVD_MAP
);
7498 nflags
|= ctx
->defaultmap
[gdmk
] & ~GOVD_MAP
;
7503 struct gimplify_omp_ctx
*octx
= ctx
->outer_context
;
7504 if ((ctx
->region_type
& ORT_ACC
) && octx
)
7506 /* Look in outer OpenACC contexts, to see if there's a
7507 data attribute for this variable. */
7508 omp_notice_variable (octx
, decl
, in_code
);
7510 for (; octx
; octx
= octx
->outer_context
)
7512 if (!(octx
->region_type
& (ORT_TARGET_DATA
| ORT_TARGET
)))
7515 = splay_tree_lookup (octx
->variables
,
7516 (splay_tree_key
) decl
);
7519 if (octx
->region_type
== ORT_ACC_HOST_DATA
)
7520 error ("variable %qE declared in enclosing "
7521 "%<host_data%> region", DECL_NAME (decl
));
7523 if (octx
->region_type
== ORT_ACC_DATA
7524 && (n2
->value
& GOVD_MAP_0LEN_ARRAY
))
7525 nflags
|= GOVD_MAP_0LEN_ARRAY
;
7531 if ((nflags
& ~(GOVD_MAP_TO_ONLY
| GOVD_MAP_FROM_ONLY
7532 | GOVD_MAP_ALLOC_ONLY
)) == flags
)
7534 tree type
= TREE_TYPE (decl
);
7536 if (gimplify_omp_ctxp
->target_firstprivatize_array_bases
7537 && lang_hooks
.decls
.omp_privatize_by_reference (decl
))
7538 type
= TREE_TYPE (type
);
7539 if (!lang_hooks
.types
.omp_mappable_type (type
))
7541 error ("%qD referenced in target region does not have "
7542 "a mappable type", decl
);
7543 nflags
|= GOVD_MAP
| GOVD_EXPLICIT
;
7547 if ((ctx
->region_type
& ORT_ACC
) != 0)
7548 nflags
= oacc_default_clause (ctx
, decl
, flags
);
7554 omp_add_variable (ctx
, decl
, nflags
);
7558 /* If nothing changed, there's nothing left to do. */
7559 if ((n
->value
& flags
) == flags
)
7569 if (ctx
->region_type
== ORT_WORKSHARE
7570 || ctx
->region_type
== ORT_TASKGROUP
7571 || ctx
->region_type
== ORT_SIMD
7572 || ctx
->region_type
== ORT_ACC
7573 || (ctx
->region_type
& ORT_TARGET_DATA
) != 0)
7576 flags
= omp_default_clause (ctx
, decl
, in_code
, flags
);
7578 if ((flags
& GOVD_PRIVATE
)
7579 && lang_hooks
.decls
.omp_private_outer_ref (decl
))
7580 flags
|= GOVD_PRIVATE_OUTER_REF
;
7582 omp_add_variable (ctx
, decl
, flags
);
7584 shared
= (flags
& GOVD_SHARED
) != 0;
7585 ret
= lang_hooks
.decls
.omp_disregard_value_expr (decl
, shared
);
7589 if ((n
->value
& (GOVD_SEEN
| GOVD_LOCAL
)) == 0
7590 && (flags
& (GOVD_SEEN
| GOVD_LOCAL
)) == GOVD_SEEN
7591 && DECL_SIZE (decl
))
7593 if (TREE_CODE (DECL_SIZE (decl
)) != INTEGER_CST
)
7596 tree t
= DECL_VALUE_EXPR (decl
);
7597 gcc_assert (TREE_CODE (t
) == INDIRECT_REF
);
7598 t
= TREE_OPERAND (t
, 0);
7599 gcc_assert (DECL_P (t
));
7600 n2
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) t
);
7601 n2
->value
|= GOVD_SEEN
;
7603 else if (lang_hooks
.decls
.omp_privatize_by_reference (decl
)
7604 && TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl
)))
7605 && (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl
))))
7609 tree t
= TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl
)));
7610 gcc_assert (DECL_P (t
));
7611 n2
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) t
);
7613 omp_notice_variable (ctx
, t
, true);
7617 if (ctx
->region_type
& ORT_ACC
)
7618 /* For OpenACC, as remarked above, defer expansion. */
7621 shared
= ((flags
| n
->value
) & GOVD_SHARED
) != 0;
7622 ret
= lang_hooks
.decls
.omp_disregard_value_expr (decl
, shared
);
7624 /* If nothing changed, there's nothing left to do. */
7625 if ((n
->value
& flags
) == flags
)
7631 /* If the variable is private in the current context, then we don't
7632 need to propagate anything to an outer context. */
7633 if ((flags
& GOVD_PRIVATE
) && !(flags
& GOVD_PRIVATE_OUTER_REF
))
7635 if ((flags
& (GOVD_LINEAR
| GOVD_LINEAR_LASTPRIVATE_NO_OUTER
))
7636 == (GOVD_LINEAR
| GOVD_LINEAR_LASTPRIVATE_NO_OUTER
))
7638 if ((flags
& (GOVD_FIRSTPRIVATE
| GOVD_LASTPRIVATE
7639 | GOVD_LINEAR_LASTPRIVATE_NO_OUTER
))
7640 == (GOVD_LASTPRIVATE
| GOVD_LINEAR_LASTPRIVATE_NO_OUTER
))
7642 if (ctx
->outer_context
7643 && omp_notice_variable (ctx
->outer_context
, decl
, in_code
))
7648 /* Verify that DECL is private within CTX. If there's specific information
7649 to the contrary in the innermost scope, generate an error. */
7652 omp_is_private (struct gimplify_omp_ctx
*ctx
, tree decl
, int simd
)
7656 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
)decl
);
7659 if (n
->value
& GOVD_SHARED
)
7661 if (ctx
== gimplify_omp_ctxp
)
7664 error ("iteration variable %qE is predetermined linear",
7667 error ("iteration variable %qE should be private",
7669 n
->value
= GOVD_PRIVATE
;
7675 else if ((n
->value
& GOVD_EXPLICIT
) != 0
7676 && (ctx
== gimplify_omp_ctxp
7677 || (ctx
->region_type
== ORT_COMBINED_PARALLEL
7678 && gimplify_omp_ctxp
->outer_context
== ctx
)))
7680 if ((n
->value
& GOVD_FIRSTPRIVATE
) != 0)
7681 error ("iteration variable %qE should not be firstprivate",
7683 else if ((n
->value
& GOVD_REDUCTION
) != 0)
7684 error ("iteration variable %qE should not be reduction",
7686 else if (simd
!= 1 && (n
->value
& GOVD_LINEAR
) != 0)
7687 error ("iteration variable %qE should not be linear",
7690 return (ctx
== gimplify_omp_ctxp
7691 || (ctx
->region_type
== ORT_COMBINED_PARALLEL
7692 && gimplify_omp_ctxp
->outer_context
== ctx
));
7695 if (ctx
->region_type
!= ORT_WORKSHARE
7696 && ctx
->region_type
!= ORT_TASKGROUP
7697 && ctx
->region_type
!= ORT_SIMD
7698 && ctx
->region_type
!= ORT_ACC
)
7700 else if (ctx
->outer_context
)
7701 return omp_is_private (ctx
->outer_context
, decl
, simd
);
7705 /* Return true if DECL is private within a parallel region
7706 that binds to the current construct's context or in parallel
7707 region's REDUCTION clause. */
7710 omp_check_private (struct gimplify_omp_ctx
*ctx
, tree decl
, bool copyprivate
)
7716 ctx
= ctx
->outer_context
;
7719 if (is_global_var (decl
))
7722 /* References might be private, but might be shared too,
7723 when checking for copyprivate, assume they might be
7724 private, otherwise assume they might be shared. */
7728 if (lang_hooks
.decls
.omp_privatize_by_reference (decl
))
7731 /* Treat C++ privatized non-static data members outside
7732 of the privatization the same. */
7733 if (omp_member_access_dummy_var (decl
))
7739 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
7741 if ((ctx
->region_type
& (ORT_TARGET
| ORT_TARGET_DATA
)) != 0
7742 && (n
== NULL
|| (n
->value
& GOVD_DATA_SHARE_CLASS
) == 0))
7747 if ((n
->value
& GOVD_LOCAL
) != 0
7748 && omp_member_access_dummy_var (decl
))
7750 return (n
->value
& GOVD_SHARED
) == 0;
7753 while (ctx
->region_type
== ORT_WORKSHARE
7754 || ctx
->region_type
== ORT_TASKGROUP
7755 || ctx
->region_type
== ORT_SIMD
7756 || ctx
->region_type
== ORT_ACC
);
7760 /* Callback for walk_tree to find a DECL_EXPR for the given DECL. */
7763 find_decl_expr (tree
*tp
, int *walk_subtrees
, void *data
)
7767 /* If this node has been visited, unmark it and keep looking. */
7768 if (TREE_CODE (t
) == DECL_EXPR
&& DECL_EXPR_DECL (t
) == (tree
) data
)
7771 if (IS_TYPE_OR_DECL_P (t
))
7776 /* If *LIST_P contains any OpenMP depend clauses with iterators,
7777 lower all the depend clauses by populating corresponding depend
7778 array. Returns 0 if there are no such depend clauses, or
7779 2 if all depend clauses should be removed, 1 otherwise. */
7782 gimplify_omp_depend (tree
*list_p
, gimple_seq
*pre_p
)
7786 size_t n
[4] = { 0, 0, 0, 0 };
7788 tree counts
[4] = { NULL_TREE
, NULL_TREE
, NULL_TREE
, NULL_TREE
};
7789 tree last_iter
= NULL_TREE
, last_count
= NULL_TREE
;
7791 location_t first_loc
= UNKNOWN_LOCATION
;
7793 for (c
= *list_p
; c
; c
= OMP_CLAUSE_CHAIN (c
))
7794 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEPEND
)
7796 switch (OMP_CLAUSE_DEPEND_KIND (c
))
7798 case OMP_CLAUSE_DEPEND_IN
:
7801 case OMP_CLAUSE_DEPEND_OUT
:
7802 case OMP_CLAUSE_DEPEND_INOUT
:
7805 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET
:
7808 case OMP_CLAUSE_DEPEND_DEPOBJ
:
7811 case OMP_CLAUSE_DEPEND_SOURCE
:
7812 case OMP_CLAUSE_DEPEND_SINK
:
7817 tree t
= OMP_CLAUSE_DECL (c
);
7818 if (first_loc
== UNKNOWN_LOCATION
)
7819 first_loc
= OMP_CLAUSE_LOCATION (c
);
7820 if (TREE_CODE (t
) == TREE_LIST
7822 && TREE_CODE (TREE_PURPOSE (t
)) == TREE_VEC
)
7824 if (TREE_PURPOSE (t
) != last_iter
)
7826 tree tcnt
= size_one_node
;
7827 for (tree it
= TREE_PURPOSE (t
); it
; it
= TREE_CHAIN (it
))
7829 if (gimplify_expr (&TREE_VEC_ELT (it
, 1), pre_p
, NULL
,
7830 is_gimple_val
, fb_rvalue
) == GS_ERROR
7831 || gimplify_expr (&TREE_VEC_ELT (it
, 2), pre_p
, NULL
,
7832 is_gimple_val
, fb_rvalue
) == GS_ERROR
7833 || gimplify_expr (&TREE_VEC_ELT (it
, 3), pre_p
, NULL
,
7834 is_gimple_val
, fb_rvalue
) == GS_ERROR
7835 || (gimplify_expr (&TREE_VEC_ELT (it
, 4), pre_p
, NULL
,
7836 is_gimple_val
, fb_rvalue
)
7839 tree var
= TREE_VEC_ELT (it
, 0);
7840 tree begin
= TREE_VEC_ELT (it
, 1);
7841 tree end
= TREE_VEC_ELT (it
, 2);
7842 tree step
= TREE_VEC_ELT (it
, 3);
7843 tree orig_step
= TREE_VEC_ELT (it
, 4);
7844 tree type
= TREE_TYPE (var
);
7845 tree stype
= TREE_TYPE (step
);
7846 location_t loc
= DECL_SOURCE_LOCATION (var
);
7848 /* Compute count for this iterator as
7850 ? (begin < end ? (end - begin + (step - 1)) / step : 0)
7851 : (begin > end ? (end - begin + (step + 1)) / step : 0)
7852 and compute product of those for the entire depend
7854 if (POINTER_TYPE_P (type
))
7855 endmbegin
= fold_build2_loc (loc
, POINTER_DIFF_EXPR
,
7858 endmbegin
= fold_build2_loc (loc
, MINUS_EXPR
, type
,
7860 tree stepm1
= fold_build2_loc (loc
, MINUS_EXPR
, stype
,
7862 build_int_cst (stype
, 1));
7863 tree stepp1
= fold_build2_loc (loc
, PLUS_EXPR
, stype
, step
,
7864 build_int_cst (stype
, 1));
7865 tree pos
= fold_build2_loc (loc
, PLUS_EXPR
, stype
,
7866 unshare_expr (endmbegin
),
7868 pos
= fold_build2_loc (loc
, TRUNC_DIV_EXPR
, stype
,
7870 tree neg
= fold_build2_loc (loc
, PLUS_EXPR
, stype
,
7872 if (TYPE_UNSIGNED (stype
))
7874 neg
= fold_build1_loc (loc
, NEGATE_EXPR
, stype
, neg
);
7875 step
= fold_build1_loc (loc
, NEGATE_EXPR
, stype
, step
);
7877 neg
= fold_build2_loc (loc
, TRUNC_DIV_EXPR
, stype
,
7880 tree cond
= fold_build2_loc (loc
, LT_EXPR
,
7883 pos
= fold_build3_loc (loc
, COND_EXPR
, stype
, cond
, pos
,
7884 build_int_cst (stype
, 0));
7885 cond
= fold_build2_loc (loc
, LT_EXPR
, boolean_type_node
,
7887 neg
= fold_build3_loc (loc
, COND_EXPR
, stype
, cond
, neg
,
7888 build_int_cst (stype
, 0));
7889 tree osteptype
= TREE_TYPE (orig_step
);
7890 cond
= fold_build2_loc (loc
, GT_EXPR
, boolean_type_node
,
7892 build_int_cst (osteptype
, 0));
7893 tree cnt
= fold_build3_loc (loc
, COND_EXPR
, stype
,
7895 cnt
= fold_convert_loc (loc
, sizetype
, cnt
);
7896 if (gimplify_expr (&cnt
, pre_p
, NULL
, is_gimple_val
,
7897 fb_rvalue
) == GS_ERROR
)
7899 tcnt
= size_binop_loc (loc
, MULT_EXPR
, tcnt
, cnt
);
7901 if (gimplify_expr (&tcnt
, pre_p
, NULL
, is_gimple_val
,
7902 fb_rvalue
) == GS_ERROR
)
7904 last_iter
= TREE_PURPOSE (t
);
7907 if (counts
[i
] == NULL_TREE
)
7908 counts
[i
] = last_count
;
7910 counts
[i
] = size_binop_loc (OMP_CLAUSE_LOCATION (c
),
7911 PLUS_EXPR
, counts
[i
], last_count
);
7916 for (i
= 0; i
< 4; i
++)
7922 tree total
= size_zero_node
;
7923 for (i
= 0; i
< 4; i
++)
7925 unused
[i
] = counts
[i
] == NULL_TREE
&& n
[i
] == 0;
7926 if (counts
[i
] == NULL_TREE
)
7927 counts
[i
] = size_zero_node
;
7929 counts
[i
] = size_binop (PLUS_EXPR
, counts
[i
], size_int (n
[i
]));
7930 if (gimplify_expr (&counts
[i
], pre_p
, NULL
, is_gimple_val
,
7931 fb_rvalue
) == GS_ERROR
)
7933 total
= size_binop (PLUS_EXPR
, total
, counts
[i
]);
7936 if (gimplify_expr (&total
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
)
7939 bool is_old
= unused
[1] && unused
[3];
7940 tree totalpx
= size_binop (PLUS_EXPR
, unshare_expr (total
),
7941 size_int (is_old
? 1 : 4));
7942 tree type
= build_array_type (ptr_type_node
, build_index_type (totalpx
));
7943 tree array
= create_tmp_var_raw (type
);
7944 TREE_ADDRESSABLE (array
) = 1;
7945 if (!poly_int_tree_p (totalpx
))
7947 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (array
)))
7948 gimplify_type_sizes (TREE_TYPE (array
), pre_p
);
7949 if (gimplify_omp_ctxp
)
7951 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
7953 && (ctx
->region_type
== ORT_WORKSHARE
7954 || ctx
->region_type
== ORT_TASKGROUP
7955 || ctx
->region_type
== ORT_SIMD
7956 || ctx
->region_type
== ORT_ACC
))
7957 ctx
= ctx
->outer_context
;
7959 omp_add_variable (ctx
, array
, GOVD_LOCAL
| GOVD_SEEN
);
7961 gimplify_vla_decl (array
, pre_p
);
7964 gimple_add_tmp_var (array
);
7965 tree r
= build4 (ARRAY_REF
, ptr_type_node
, array
, size_int (0), NULL_TREE
,
7970 tem
= build2 (MODIFY_EXPR
, void_type_node
, r
,
7971 build_int_cst (ptr_type_node
, 0));
7972 gimplify_and_add (tem
, pre_p
);
7973 r
= build4 (ARRAY_REF
, ptr_type_node
, array
, size_int (1), NULL_TREE
,
7976 tem
= build2 (MODIFY_EXPR
, void_type_node
, r
,
7977 fold_convert (ptr_type_node
, total
));
7978 gimplify_and_add (tem
, pre_p
);
7979 for (i
= 1; i
< (is_old
? 2 : 4); i
++)
7981 r
= build4 (ARRAY_REF
, ptr_type_node
, array
, size_int (i
+ !is_old
),
7982 NULL_TREE
, NULL_TREE
);
7983 tem
= build2 (MODIFY_EXPR
, void_type_node
, r
, counts
[i
- 1]);
7984 gimplify_and_add (tem
, pre_p
);
7991 for (i
= 0; i
< 4; i
++)
7993 if (i
&& (i
>= j
|| unused
[i
- 1]))
7995 cnts
[i
] = cnts
[i
- 1];
7998 cnts
[i
] = create_tmp_var (sizetype
);
8000 g
= gimple_build_assign (cnts
[i
], size_int (is_old
? 2 : 5));
8005 t
= size_binop (PLUS_EXPR
, counts
[0], size_int (2));
8007 t
= size_binop (PLUS_EXPR
, cnts
[i
- 1], counts
[i
- 1]);
8008 if (gimplify_expr (&t
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
)
8011 g
= gimple_build_assign (cnts
[i
], t
);
8013 gimple_seq_add_stmt (pre_p
, g
);
8016 last_iter
= NULL_TREE
;
8017 tree last_bind
= NULL_TREE
;
8018 tree
*last_body
= NULL
;
8019 for (c
= *list_p
; c
; c
= OMP_CLAUSE_CHAIN (c
))
8020 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEPEND
)
8022 switch (OMP_CLAUSE_DEPEND_KIND (c
))
8024 case OMP_CLAUSE_DEPEND_IN
:
8027 case OMP_CLAUSE_DEPEND_OUT
:
8028 case OMP_CLAUSE_DEPEND_INOUT
:
8031 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET
:
8034 case OMP_CLAUSE_DEPEND_DEPOBJ
:
8037 case OMP_CLAUSE_DEPEND_SOURCE
:
8038 case OMP_CLAUSE_DEPEND_SINK
:
8043 tree t
= OMP_CLAUSE_DECL (c
);
8044 if (TREE_CODE (t
) == TREE_LIST
8046 && TREE_CODE (TREE_PURPOSE (t
)) == TREE_VEC
)
8048 if (TREE_PURPOSE (t
) != last_iter
)
8051 gimplify_and_add (last_bind
, pre_p
);
8052 tree block
= TREE_VEC_ELT (TREE_PURPOSE (t
), 5);
8053 last_bind
= build3 (BIND_EXPR
, void_type_node
,
8054 BLOCK_VARS (block
), NULL
, block
);
8055 TREE_SIDE_EFFECTS (last_bind
) = 1;
8056 SET_EXPR_LOCATION (last_bind
, OMP_CLAUSE_LOCATION (c
));
8057 tree
*p
= &BIND_EXPR_BODY (last_bind
);
8058 for (tree it
= TREE_PURPOSE (t
); it
; it
= TREE_CHAIN (it
))
8060 tree var
= TREE_VEC_ELT (it
, 0);
8061 tree begin
= TREE_VEC_ELT (it
, 1);
8062 tree end
= TREE_VEC_ELT (it
, 2);
8063 tree step
= TREE_VEC_ELT (it
, 3);
8064 tree orig_step
= TREE_VEC_ELT (it
, 4);
8065 tree type
= TREE_TYPE (var
);
8066 location_t loc
= DECL_SOURCE_LOCATION (var
);
8074 if (orig_step > 0) {
8075 if (var < end) goto beg_label;
8077 if (var > end) goto beg_label;
8079 for each iterator, with inner iterators added to
8081 tree beg_label
= create_artificial_label (loc
);
8082 tree cond_label
= NULL_TREE
;
8083 tem
= build2_loc (loc
, MODIFY_EXPR
, void_type_node
,
8085 append_to_statement_list_force (tem
, p
);
8086 tem
= build_and_jump (&cond_label
);
8087 append_to_statement_list_force (tem
, p
);
8088 tem
= build1 (LABEL_EXPR
, void_type_node
, beg_label
);
8089 append_to_statement_list (tem
, p
);
8090 tree bind
= build3 (BIND_EXPR
, void_type_node
, NULL_TREE
,
8091 NULL_TREE
, NULL_TREE
);
8092 TREE_SIDE_EFFECTS (bind
) = 1;
8093 SET_EXPR_LOCATION (bind
, loc
);
8094 append_to_statement_list_force (bind
, p
);
8095 if (POINTER_TYPE_P (type
))
8096 tem
= build2_loc (loc
, POINTER_PLUS_EXPR
, type
,
8097 var
, fold_convert_loc (loc
, sizetype
,
8100 tem
= build2_loc (loc
, PLUS_EXPR
, type
, var
, step
);
8101 tem
= build2_loc (loc
, MODIFY_EXPR
, void_type_node
,
8103 append_to_statement_list_force (tem
, p
);
8104 tem
= build1 (LABEL_EXPR
, void_type_node
, cond_label
);
8105 append_to_statement_list (tem
, p
);
8106 tree cond
= fold_build2_loc (loc
, LT_EXPR
,
8110 = fold_build3_loc (loc
, COND_EXPR
, void_type_node
,
8111 cond
, build_and_jump (&beg_label
),
8113 cond
= fold_build2_loc (loc
, GT_EXPR
, boolean_type_node
,
8116 = fold_build3_loc (loc
, COND_EXPR
, void_type_node
,
8117 cond
, build_and_jump (&beg_label
),
8119 tree osteptype
= TREE_TYPE (orig_step
);
8120 cond
= fold_build2_loc (loc
, GT_EXPR
, boolean_type_node
,
8122 build_int_cst (osteptype
, 0));
8123 tem
= fold_build3_loc (loc
, COND_EXPR
, void_type_node
,
8125 append_to_statement_list_force (tem
, p
);
8126 p
= &BIND_EXPR_BODY (bind
);
8130 last_iter
= TREE_PURPOSE (t
);
8131 if (TREE_CODE (TREE_VALUE (t
)) == COMPOUND_EXPR
)
8133 append_to_statement_list (TREE_OPERAND (TREE_VALUE (t
),
8135 TREE_VALUE (t
) = TREE_OPERAND (TREE_VALUE (t
), 1);
8137 if (error_operand_p (TREE_VALUE (t
)))
8139 TREE_VALUE (t
) = build_fold_addr_expr (TREE_VALUE (t
));
8140 r
= build4 (ARRAY_REF
, ptr_type_node
, array
, cnts
[i
],
8141 NULL_TREE
, NULL_TREE
);
8142 tem
= build2_loc (OMP_CLAUSE_LOCATION (c
), MODIFY_EXPR
,
8143 void_type_node
, r
, TREE_VALUE (t
));
8144 append_to_statement_list_force (tem
, last_body
);
8145 tem
= build2_loc (OMP_CLAUSE_LOCATION (c
), MODIFY_EXPR
,
8146 void_type_node
, cnts
[i
],
8147 size_binop (PLUS_EXPR
, cnts
[i
], size_int (1)));
8148 append_to_statement_list_force (tem
, last_body
);
8149 TREE_VALUE (t
) = null_pointer_node
;
8155 gimplify_and_add (last_bind
, pre_p
);
8156 last_bind
= NULL_TREE
;
8158 if (TREE_CODE (OMP_CLAUSE_DECL (c
)) == COMPOUND_EXPR
)
8160 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c
), 0), pre_p
,
8161 NULL
, is_gimple_val
, fb_rvalue
);
8162 OMP_CLAUSE_DECL (c
) = TREE_OPERAND (OMP_CLAUSE_DECL (c
), 1);
8164 if (error_operand_p (OMP_CLAUSE_DECL (c
)))
8166 OMP_CLAUSE_DECL (c
) = build_fold_addr_expr (OMP_CLAUSE_DECL (c
));
8167 if (gimplify_expr (&OMP_CLAUSE_DECL (c
), pre_p
, NULL
,
8168 is_gimple_val
, fb_rvalue
) == GS_ERROR
)
8170 r
= build4 (ARRAY_REF
, ptr_type_node
, array
, cnts
[i
],
8171 NULL_TREE
, NULL_TREE
);
8172 tem
= build2 (MODIFY_EXPR
, void_type_node
, r
, OMP_CLAUSE_DECL (c
));
8173 gimplify_and_add (tem
, pre_p
);
8174 g
= gimple_build_assign (cnts
[i
], size_binop (PLUS_EXPR
, cnts
[i
],
8176 gimple_seq_add_stmt (pre_p
, g
);
8180 gimplify_and_add (last_bind
, pre_p
);
8181 tree cond
= boolean_false_node
;
8185 cond
= build2_loc (first_loc
, NE_EXPR
, boolean_type_node
, cnts
[0],
8186 size_binop_loc (first_loc
, PLUS_EXPR
, counts
[0],
8189 cond
= build2_loc (first_loc
, TRUTH_OR_EXPR
, boolean_type_node
, cond
,
8190 build2_loc (first_loc
, NE_EXPR
, boolean_type_node
,
8192 size_binop_loc (first_loc
, PLUS_EXPR
,
8198 tree prev
= size_int (5);
8199 for (i
= 0; i
< 4; i
++)
8203 prev
= size_binop_loc (first_loc
, PLUS_EXPR
, counts
[i
], prev
);
8204 cond
= build2_loc (first_loc
, TRUTH_OR_EXPR
, boolean_type_node
, cond
,
8205 build2_loc (first_loc
, NE_EXPR
, boolean_type_node
,
8206 cnts
[i
], unshare_expr (prev
)));
8209 tem
= build3_loc (first_loc
, COND_EXPR
, void_type_node
, cond
,
8210 build_call_expr_loc (first_loc
,
8211 builtin_decl_explicit (BUILT_IN_TRAP
),
8213 gimplify_and_add (tem
, pre_p
);
8214 c
= build_omp_clause (UNKNOWN_LOCATION
, OMP_CLAUSE_DEPEND
);
8215 OMP_CLAUSE_DEPEND_KIND (c
) = OMP_CLAUSE_DEPEND_LAST
;
8216 OMP_CLAUSE_DECL (c
) = build_fold_addr_expr (array
);
8217 OMP_CLAUSE_CHAIN (c
) = *list_p
;
8222 /* Insert a GOMP_MAP_ALLOC or GOMP_MAP_RELEASE node following a
8223 GOMP_MAP_STRUCT mapping. C is an always_pointer mapping. STRUCT_NODE is
8224 the struct node to insert the new mapping after (when the struct node is
8225 initially created). PREV_NODE is the first of two or three mappings for a
8226 pointer, and is either:
8227 - the node before C, when a pair of mappings is used, e.g. for a C/C++
8229 - not the node before C. This is true when we have a reference-to-pointer
8230 type (with a mapping for the reference and for the pointer), or for
8231 Fortran derived-type mappings with a GOMP_MAP_TO_PSET.
8232 If SCP is non-null, the new node is inserted before *SCP.
8233 if SCP is null, the new node is inserted before PREV_NODE.
8235 - PREV_NODE, if SCP is non-null.
8236 - The newly-created ALLOC or RELEASE node, if SCP is null.
8237 - The second newly-created ALLOC or RELEASE node, if we are mapping a
8238 reference to a pointer. */
8241 insert_struct_comp_map (enum tree_code code
, tree c
, tree struct_node
,
8242 tree prev_node
, tree
*scp
)
8244 enum gomp_map_kind mkind
8245 = (code
== OMP_TARGET_EXIT_DATA
|| code
== OACC_EXIT_DATA
)
8246 ? GOMP_MAP_RELEASE
: GOMP_MAP_ALLOC
;
8248 tree c2
= build_omp_clause (OMP_CLAUSE_LOCATION (c
), OMP_CLAUSE_MAP
);
8249 tree cl
= scp
? prev_node
: c2
;
8250 OMP_CLAUSE_SET_MAP_KIND (c2
, mkind
);
8251 OMP_CLAUSE_DECL (c2
) = unshare_expr (OMP_CLAUSE_DECL (c
));
8252 OMP_CLAUSE_CHAIN (c2
) = scp
? *scp
: prev_node
;
8253 if (OMP_CLAUSE_CHAIN (prev_node
) != c
8254 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (prev_node
)) == OMP_CLAUSE_MAP
8255 && (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node
))
8256 == GOMP_MAP_TO_PSET
))
8257 OMP_CLAUSE_SIZE (c2
) = OMP_CLAUSE_SIZE (OMP_CLAUSE_CHAIN (prev_node
));
8259 OMP_CLAUSE_SIZE (c2
) = TYPE_SIZE_UNIT (ptr_type_node
);
8261 OMP_CLAUSE_CHAIN (struct_node
) = c2
;
8263 /* We might need to create an additional mapping if we have a reference to a
8264 pointer (in C++). Don't do this if we have something other than a
8265 GOMP_MAP_ALWAYS_POINTER though, i.e. a GOMP_MAP_TO_PSET. */
8266 if (OMP_CLAUSE_CHAIN (prev_node
) != c
8267 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (prev_node
)) == OMP_CLAUSE_MAP
8268 && ((OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node
))
8269 == GOMP_MAP_ALWAYS_POINTER
)
8270 || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node
))
8271 == GOMP_MAP_ATTACH_DETACH
)))
8273 tree c4
= OMP_CLAUSE_CHAIN (prev_node
);
8274 tree c3
= build_omp_clause (OMP_CLAUSE_LOCATION (c
), OMP_CLAUSE_MAP
);
8275 OMP_CLAUSE_SET_MAP_KIND (c3
, mkind
);
8276 OMP_CLAUSE_DECL (c3
) = unshare_expr (OMP_CLAUSE_DECL (c4
));
8277 OMP_CLAUSE_SIZE (c3
) = TYPE_SIZE_UNIT (ptr_type_node
);
8278 OMP_CLAUSE_CHAIN (c3
) = prev_node
;
8280 OMP_CLAUSE_CHAIN (c2
) = c3
;
8291 /* Strip ARRAY_REFS or an indirect ref off BASE, find the containing object,
8292 and set *BITPOSP and *POFFSETP to the bit offset of the access.
8293 If BASE_REF is non-NULL and the containing object is a reference, set
8294 *BASE_REF to that reference before dereferencing the object.
8295 If BASE_REF is NULL, check that the containing object is a COMPONENT_REF or
8296 has array type, else return NULL. */
8299 extract_base_bit_offset (tree base
, tree
*base_ref
, poly_int64
*bitposp
,
8300 poly_offset_int
*poffsetp
)
8303 poly_int64 bitsize
, bitpos
;
8305 int unsignedp
, reversep
, volatilep
= 0;
8306 poly_offset_int poffset
;
8310 *base_ref
= NULL_TREE
;
8312 while (TREE_CODE (base
) == ARRAY_REF
)
8313 base
= TREE_OPERAND (base
, 0);
8315 if (TREE_CODE (base
) == INDIRECT_REF
)
8316 base
= TREE_OPERAND (base
, 0);
8320 if (TREE_CODE (base
) == ARRAY_REF
)
8322 while (TREE_CODE (base
) == ARRAY_REF
)
8323 base
= TREE_OPERAND (base
, 0);
8324 if (TREE_CODE (base
) != COMPONENT_REF
8325 || TREE_CODE (TREE_TYPE (base
)) != ARRAY_TYPE
)
8328 else if (TREE_CODE (base
) == INDIRECT_REF
8329 && TREE_CODE (TREE_OPERAND (base
, 0)) == COMPONENT_REF
8330 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (base
, 0)))
8332 base
= TREE_OPERAND (base
, 0);
8335 base
= get_inner_reference (base
, &bitsize
, &bitpos
, &offset
, &mode
,
8336 &unsignedp
, &reversep
, &volatilep
);
8338 tree orig_base
= base
;
8340 if ((TREE_CODE (base
) == INDIRECT_REF
8341 || (TREE_CODE (base
) == MEM_REF
8342 && integer_zerop (TREE_OPERAND (base
, 1))))
8343 && DECL_P (TREE_OPERAND (base
, 0))
8344 && TREE_CODE (TREE_TYPE (TREE_OPERAND (base
, 0))) == REFERENCE_TYPE
)
8345 base
= TREE_OPERAND (base
, 0);
8347 gcc_assert (offset
== NULL_TREE
|| poly_int_tree_p (offset
));
8350 poffset
= wi::to_poly_offset (offset
);
8354 if (maybe_ne (bitpos
, 0))
8355 poffset
+= bits_to_bytes_round_down (bitpos
);
8358 *poffsetp
= poffset
;
8360 /* Set *BASE_REF if BASE was a dereferenced reference variable. */
8361 if (base_ref
&& orig_base
!= base
)
8362 *base_ref
= orig_base
;
8367 /* Returns true if EXPR is or contains (as a sub-component) BASE_PTR. */
8370 is_or_contains_p (tree expr
, tree base_ptr
)
8372 while (expr
!= base_ptr
)
8373 if (TREE_CODE (base_ptr
) == COMPONENT_REF
)
8374 base_ptr
= TREE_OPERAND (base_ptr
, 0);
8377 return expr
== base_ptr
;
8380 /* Implement OpenMP 5.x map ordering rules for target directives. There are
8381 several rules, and with some level of ambiguity, hopefully we can at least
8382 collect the complexity here in one place. */
8385 omp_target_reorder_clauses (tree
*list_p
)
8387 /* Collect refs to alloc/release/delete maps. */
8388 auto_vec
<tree
, 32> ard
;
8390 while (*cp
!= NULL_TREE
)
8391 if (OMP_CLAUSE_CODE (*cp
) == OMP_CLAUSE_MAP
8392 && (OMP_CLAUSE_MAP_KIND (*cp
) == GOMP_MAP_ALLOC
8393 || OMP_CLAUSE_MAP_KIND (*cp
) == GOMP_MAP_RELEASE
8394 || OMP_CLAUSE_MAP_KIND (*cp
) == GOMP_MAP_DELETE
))
8396 /* Unlink cp and push to ard. */
8398 tree nc
= OMP_CLAUSE_CHAIN (c
);
8402 /* Any associated pointer type maps should also move along. */
8403 while (*cp
!= NULL_TREE
8404 && OMP_CLAUSE_CODE (*cp
) == OMP_CLAUSE_MAP
8405 && (OMP_CLAUSE_MAP_KIND (*cp
) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
8406 || OMP_CLAUSE_MAP_KIND (*cp
) == GOMP_MAP_FIRSTPRIVATE_POINTER
8407 || OMP_CLAUSE_MAP_KIND (*cp
) == GOMP_MAP_ATTACH_DETACH
8408 || OMP_CLAUSE_MAP_KIND (*cp
) == GOMP_MAP_POINTER
8409 || OMP_CLAUSE_MAP_KIND (*cp
) == GOMP_MAP_ALWAYS_POINTER
8410 || OMP_CLAUSE_MAP_KIND (*cp
) == GOMP_MAP_TO_PSET
))
8413 nc
= OMP_CLAUSE_CHAIN (c
);
8419 cp
= &OMP_CLAUSE_CHAIN (*cp
);
8421 /* Link alloc/release/delete maps to the end of list. */
8422 for (unsigned int i
= 0; i
< ard
.length (); i
++)
8425 cp
= &OMP_CLAUSE_CHAIN (ard
[i
]);
8429 /* OpenMP 5.0 requires that pointer variables are mapped before
8430 its use as a base-pointer. */
8431 auto_vec
<tree
*, 32> atf
;
8432 for (tree
*cp
= list_p
; *cp
; cp
= &OMP_CLAUSE_CHAIN (*cp
))
8433 if (OMP_CLAUSE_CODE (*cp
) == OMP_CLAUSE_MAP
)
8435 /* Collect alloc, to, from, to/from clause tree pointers. */
8436 gomp_map_kind k
= OMP_CLAUSE_MAP_KIND (*cp
);
8437 if (k
== GOMP_MAP_ALLOC
8439 || k
== GOMP_MAP_FROM
8440 || k
== GOMP_MAP_TOFROM
8441 || k
== GOMP_MAP_ALWAYS_TO
8442 || k
== GOMP_MAP_ALWAYS_FROM
8443 || k
== GOMP_MAP_ALWAYS_TOFROM
)
8447 for (unsigned int i
= 0; i
< atf
.length (); i
++)
8451 tree decl
= OMP_CLAUSE_DECL (*cp
);
8452 if (TREE_CODE (decl
) == INDIRECT_REF
|| TREE_CODE (decl
) == MEM_REF
)
8454 tree base_ptr
= TREE_OPERAND (decl
, 0);
8455 STRIP_TYPE_NOPS (base_ptr
);
8456 for (unsigned int j
= i
+ 1; j
< atf
.length (); j
++)
8459 tree decl2
= OMP_CLAUSE_DECL (*cp2
);
8460 if (is_or_contains_p (decl2
, base_ptr
))
8462 /* Move *cp2 to before *cp. */
8464 *cp2
= OMP_CLAUSE_CHAIN (c
);
8465 OMP_CLAUSE_CHAIN (c
) = *cp
;
8474 /* Scan the OMP clauses in *LIST_P, installing mappings into a new
8475 and previous omp contexts. */
8478 gimplify_scan_omp_clauses (tree
*list_p
, gimple_seq
*pre_p
,
8479 enum omp_region_type region_type
,
8480 enum tree_code code
)
8482 struct gimplify_omp_ctx
*ctx
, *outer_ctx
;
8484 hash_map
<tree
, tree
> *struct_map_to_clause
= NULL
;
8485 hash_set
<tree
> *struct_deref_set
= NULL
;
8486 tree
*prev_list_p
= NULL
, *orig_list_p
= list_p
;
8487 int handled_depend_iterators
= -1;
8490 ctx
= new_omp_context (region_type
);
8492 outer_ctx
= ctx
->outer_context
;
8493 if (code
== OMP_TARGET
)
8495 if (!lang_GNU_Fortran ())
8496 ctx
->defaultmap
[GDMK_POINTER
] = GOVD_MAP
| GOVD_MAP_0LEN_ARRAY
;
8497 ctx
->defaultmap
[GDMK_SCALAR
] = GOVD_FIRSTPRIVATE
;
8499 if (!lang_GNU_Fortran ())
8503 case OMP_TARGET_DATA
:
8504 case OMP_TARGET_ENTER_DATA
:
8505 case OMP_TARGET_EXIT_DATA
:
8507 case OACC_HOST_DATA
:
8510 ctx
->target_firstprivatize_array_bases
= true;
8515 if (code
== OMP_TARGET
8516 || code
== OMP_TARGET_DATA
8517 || code
== OMP_TARGET_ENTER_DATA
8518 || code
== OMP_TARGET_EXIT_DATA
)
8519 omp_target_reorder_clauses (list_p
);
8521 while ((c
= *list_p
) != NULL
)
8523 bool remove
= false;
8524 bool notice_outer
= true;
8525 const char *check_non_private
= NULL
;
8529 switch (OMP_CLAUSE_CODE (c
))
8531 case OMP_CLAUSE_PRIVATE
:
8532 flags
= GOVD_PRIVATE
| GOVD_EXPLICIT
;
8533 if (lang_hooks
.decls
.omp_private_outer_ref (OMP_CLAUSE_DECL (c
)))
8535 flags
|= GOVD_PRIVATE_OUTER_REF
;
8536 OMP_CLAUSE_PRIVATE_OUTER_REF (c
) = 1;
8539 notice_outer
= false;
8541 case OMP_CLAUSE_SHARED
:
8542 flags
= GOVD_SHARED
| GOVD_EXPLICIT
;
8544 case OMP_CLAUSE_FIRSTPRIVATE
:
8545 flags
= GOVD_FIRSTPRIVATE
| GOVD_EXPLICIT
;
8546 check_non_private
= "firstprivate";
8548 case OMP_CLAUSE_LASTPRIVATE
:
8549 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
))
8552 case OMP_DISTRIBUTE
:
8553 error_at (OMP_CLAUSE_LOCATION (c
),
8554 "conditional %<lastprivate%> clause on "
8555 "%qs construct", "distribute");
8556 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
) = 0;
8559 error_at (OMP_CLAUSE_LOCATION (c
),
8560 "conditional %<lastprivate%> clause on "
8561 "%qs construct", "taskloop");
8562 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
) = 0;
8567 flags
= GOVD_LASTPRIVATE
| GOVD_SEEN
| GOVD_EXPLICIT
;
8568 if (code
!= OMP_LOOP
)
8569 check_non_private
= "lastprivate";
8570 decl
= OMP_CLAUSE_DECL (c
);
8571 if (error_operand_p (decl
))
8573 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
)
8574 && !lang_hooks
.decls
.omp_scalar_p (decl
))
8576 error_at (OMP_CLAUSE_LOCATION (c
),
8577 "non-scalar variable %qD in conditional "
8578 "%<lastprivate%> clause", decl
);
8579 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
) = 0;
8581 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
))
8582 flags
|= GOVD_LASTPRIVATE_CONDITIONAL
;
8584 && (outer_ctx
->region_type
== ORT_COMBINED_PARALLEL
8585 || ((outer_ctx
->region_type
& ORT_COMBINED_TEAMS
)
8586 == ORT_COMBINED_TEAMS
))
8587 && splay_tree_lookup (outer_ctx
->variables
,
8588 (splay_tree_key
) decl
) == NULL
)
8590 omp_add_variable (outer_ctx
, decl
, GOVD_SHARED
| GOVD_SEEN
);
8591 if (outer_ctx
->outer_context
)
8592 omp_notice_variable (outer_ctx
->outer_context
, decl
, true);
8595 && (outer_ctx
->region_type
& ORT_TASK
) != 0
8596 && outer_ctx
->combined_loop
8597 && splay_tree_lookup (outer_ctx
->variables
,
8598 (splay_tree_key
) decl
) == NULL
)
8600 omp_add_variable (outer_ctx
, decl
, GOVD_LASTPRIVATE
| GOVD_SEEN
);
8601 if (outer_ctx
->outer_context
)
8602 omp_notice_variable (outer_ctx
->outer_context
, decl
, true);
8605 && (outer_ctx
->region_type
== ORT_WORKSHARE
8606 || outer_ctx
->region_type
== ORT_ACC
)
8607 && outer_ctx
->combined_loop
8608 && splay_tree_lookup (outer_ctx
->variables
,
8609 (splay_tree_key
) decl
) == NULL
8610 && !omp_check_private (outer_ctx
, decl
, false))
8612 omp_add_variable (outer_ctx
, decl
, GOVD_LASTPRIVATE
| GOVD_SEEN
);
8613 if (outer_ctx
->outer_context
8614 && (outer_ctx
->outer_context
->region_type
8615 == ORT_COMBINED_PARALLEL
)
8616 && splay_tree_lookup (outer_ctx
->outer_context
->variables
,
8617 (splay_tree_key
) decl
) == NULL
)
8619 struct gimplify_omp_ctx
*octx
= outer_ctx
->outer_context
;
8620 omp_add_variable (octx
, decl
, GOVD_SHARED
| GOVD_SEEN
);
8621 if (octx
->outer_context
)
8623 octx
= octx
->outer_context
;
8624 if (octx
->region_type
== ORT_WORKSHARE
8625 && octx
->combined_loop
8626 && splay_tree_lookup (octx
->variables
,
8627 (splay_tree_key
) decl
) == NULL
8628 && !omp_check_private (octx
, decl
, false))
8630 omp_add_variable (octx
, decl
,
8631 GOVD_LASTPRIVATE
| GOVD_SEEN
);
8632 octx
= octx
->outer_context
;
8634 && ((octx
->region_type
& ORT_COMBINED_TEAMS
)
8635 == ORT_COMBINED_TEAMS
)
8636 && (splay_tree_lookup (octx
->variables
,
8637 (splay_tree_key
) decl
)
8640 omp_add_variable (octx
, decl
,
8641 GOVD_SHARED
| GOVD_SEEN
);
8642 octx
= octx
->outer_context
;
8646 omp_notice_variable (octx
, decl
, true);
8649 else if (outer_ctx
->outer_context
)
8650 omp_notice_variable (outer_ctx
->outer_context
, decl
, true);
8653 case OMP_CLAUSE_REDUCTION
:
8654 if (OMP_CLAUSE_REDUCTION_TASK (c
))
8656 if (region_type
== ORT_WORKSHARE
)
8659 nowait
= omp_find_clause (*list_p
,
8660 OMP_CLAUSE_NOWAIT
) != NULL_TREE
;
8662 && (outer_ctx
== NULL
8663 || outer_ctx
->region_type
!= ORT_COMBINED_PARALLEL
))
8665 error_at (OMP_CLAUSE_LOCATION (c
),
8666 "%<task%> reduction modifier on a construct "
8667 "with a %<nowait%> clause");
8668 OMP_CLAUSE_REDUCTION_TASK (c
) = 0;
8671 else if ((region_type
& ORT_PARALLEL
) != ORT_PARALLEL
)
8673 error_at (OMP_CLAUSE_LOCATION (c
),
8674 "invalid %<task%> reduction modifier on construct "
8675 "other than %<parallel%>, %qs or %<sections%>",
8676 lang_GNU_Fortran () ? "do" : "for");
8677 OMP_CLAUSE_REDUCTION_TASK (c
) = 0;
8680 if (OMP_CLAUSE_REDUCTION_INSCAN (c
))
8684 error_at (OMP_CLAUSE_LOCATION (c
),
8685 "%<inscan%> %<reduction%> clause on "
8686 "%qs construct", "sections");
8687 OMP_CLAUSE_REDUCTION_INSCAN (c
) = 0;
8690 error_at (OMP_CLAUSE_LOCATION (c
),
8691 "%<inscan%> %<reduction%> clause on "
8692 "%qs construct", "parallel");
8693 OMP_CLAUSE_REDUCTION_INSCAN (c
) = 0;
8696 error_at (OMP_CLAUSE_LOCATION (c
),
8697 "%<inscan%> %<reduction%> clause on "
8698 "%qs construct", "teams");
8699 OMP_CLAUSE_REDUCTION_INSCAN (c
) = 0;
8702 error_at (OMP_CLAUSE_LOCATION (c
),
8703 "%<inscan%> %<reduction%> clause on "
8704 "%qs construct", "taskloop");
8705 OMP_CLAUSE_REDUCTION_INSCAN (c
) = 0;
8711 case OMP_CLAUSE_IN_REDUCTION
:
8712 case OMP_CLAUSE_TASK_REDUCTION
:
8713 flags
= GOVD_REDUCTION
| GOVD_SEEN
| GOVD_EXPLICIT
;
8714 /* OpenACC permits reductions on private variables. */
8715 if (!(region_type
& ORT_ACC
)
8716 /* taskgroup is actually not a worksharing region. */
8717 && code
!= OMP_TASKGROUP
)
8718 check_non_private
= omp_clause_code_name
[OMP_CLAUSE_CODE (c
)];
8719 decl
= OMP_CLAUSE_DECL (c
);
8720 if (TREE_CODE (decl
) == MEM_REF
)
8722 tree type
= TREE_TYPE (decl
);
8723 if (gimplify_expr (&TYPE_MAX_VALUE (TYPE_DOMAIN (type
)), pre_p
,
8724 NULL
, is_gimple_val
, fb_rvalue
, false)
8730 tree v
= TYPE_MAX_VALUE (TYPE_DOMAIN (type
));
8733 omp_firstprivatize_variable (ctx
, v
);
8734 omp_notice_variable (ctx
, v
, true);
8736 decl
= TREE_OPERAND (decl
, 0);
8737 if (TREE_CODE (decl
) == POINTER_PLUS_EXPR
)
8739 if (gimplify_expr (&TREE_OPERAND (decl
, 1), pre_p
,
8740 NULL
, is_gimple_val
, fb_rvalue
, false)
8746 v
= TREE_OPERAND (decl
, 1);
8749 omp_firstprivatize_variable (ctx
, v
);
8750 omp_notice_variable (ctx
, v
, true);
8752 decl
= TREE_OPERAND (decl
, 0);
8754 if (TREE_CODE (decl
) == ADDR_EXPR
8755 || TREE_CODE (decl
) == INDIRECT_REF
)
8756 decl
= TREE_OPERAND (decl
, 0);
8759 case OMP_CLAUSE_LINEAR
:
8760 if (gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c
), pre_p
, NULL
,
8761 is_gimple_val
, fb_rvalue
) == GS_ERROR
)
8768 if (code
== OMP_SIMD
8769 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c
))
8771 struct gimplify_omp_ctx
*octx
= outer_ctx
;
8773 && octx
->region_type
== ORT_WORKSHARE
8774 && octx
->combined_loop
8775 && !octx
->distribute
)
8777 if (octx
->outer_context
8778 && (octx
->outer_context
->region_type
8779 == ORT_COMBINED_PARALLEL
))
8780 octx
= octx
->outer_context
->outer_context
;
8782 octx
= octx
->outer_context
;
8785 && octx
->region_type
== ORT_WORKSHARE
8786 && octx
->combined_loop
8787 && octx
->distribute
)
8789 error_at (OMP_CLAUSE_LOCATION (c
),
8790 "%<linear%> clause for variable other than "
8791 "loop iterator specified on construct "
8792 "combined with %<distribute%>");
8797 /* For combined #pragma omp parallel for simd, need to put
8798 lastprivate and perhaps firstprivate too on the
8799 parallel. Similarly for #pragma omp for simd. */
8800 struct gimplify_omp_ctx
*octx
= outer_ctx
;
8804 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c
)
8805 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c
))
8807 decl
= OMP_CLAUSE_DECL (c
);
8808 if (error_operand_p (decl
))
8814 if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c
))
8815 flags
|= GOVD_FIRSTPRIVATE
;
8816 if (!OMP_CLAUSE_LINEAR_NO_COPYOUT (c
))
8817 flags
|= GOVD_LASTPRIVATE
;
8819 && octx
->region_type
== ORT_WORKSHARE
8820 && octx
->combined_loop
)
8822 if (octx
->outer_context
8823 && (octx
->outer_context
->region_type
8824 == ORT_COMBINED_PARALLEL
))
8825 octx
= octx
->outer_context
;
8826 else if (omp_check_private (octx
, decl
, false))
8830 && (octx
->region_type
& ORT_TASK
) != 0
8831 && octx
->combined_loop
)
8834 && octx
->region_type
== ORT_COMBINED_PARALLEL
8835 && ctx
->region_type
== ORT_WORKSHARE
8836 && octx
== outer_ctx
)
8837 flags
= GOVD_SEEN
| GOVD_SHARED
;
8839 && ((octx
->region_type
& ORT_COMBINED_TEAMS
)
8840 == ORT_COMBINED_TEAMS
))
8841 flags
= GOVD_SEEN
| GOVD_SHARED
;
8843 && octx
->region_type
== ORT_COMBINED_TARGET
)
8845 flags
&= ~GOVD_LASTPRIVATE
;
8846 if (flags
== GOVD_SEEN
)
8852 = splay_tree_lookup (octx
->variables
,
8853 (splay_tree_key
) decl
);
8854 if (on
&& (on
->value
& GOVD_DATA_SHARE_CLASS
) != 0)
8859 omp_add_variable (octx
, decl
, flags
);
8860 if (octx
->outer_context
== NULL
)
8862 octx
= octx
->outer_context
;
8867 && (!OMP_CLAUSE_LINEAR_NO_COPYIN (c
)
8868 || !OMP_CLAUSE_LINEAR_NO_COPYOUT (c
)))
8869 omp_notice_variable (octx
, decl
, true);
8871 flags
= GOVD_LINEAR
| GOVD_EXPLICIT
;
8872 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c
)
8873 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c
))
8875 notice_outer
= false;
8876 flags
|= GOVD_LINEAR_LASTPRIVATE_NO_OUTER
;
8880 case OMP_CLAUSE_MAP
:
8881 decl
= OMP_CLAUSE_DECL (c
);
8882 if (error_operand_p (decl
))
8889 if (TREE_CODE (TREE_TYPE (decl
)) != ARRAY_TYPE
)
8892 case OMP_TARGET_DATA
:
8893 case OMP_TARGET_ENTER_DATA
:
8894 case OMP_TARGET_EXIT_DATA
:
8895 case OACC_ENTER_DATA
:
8896 case OACC_EXIT_DATA
:
8897 case OACC_HOST_DATA
:
8898 if (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_FIRSTPRIVATE_POINTER
8899 || (OMP_CLAUSE_MAP_KIND (c
)
8900 == GOMP_MAP_FIRSTPRIVATE_REFERENCE
))
8901 /* For target {,enter ,exit }data only the array slice is
8902 mapped, but not the pointer to it. */
8908 /* For Fortran, not only the pointer to the data is mapped but also
8909 the address of the pointer, the array descriptor etc.; for
8910 'exit data' - and in particular for 'delete:' - having an 'alloc:'
8911 does not make sense. Likewise, for 'update' only transferring the
8912 data itself is needed as the rest has been handled in previous
8913 directives. However, for 'exit data', the array descriptor needs
8914 to be delete; hence, we turn the MAP_TO_PSET into a MAP_DELETE.
8916 NOTE: Generally, it is not safe to perform "enter data" operations
8917 on arrays where the data *or the descriptor* may go out of scope
8918 before a corresponding "exit data" operation -- and such a
8919 descriptor may be synthesized temporarily, e.g. to pass an
8920 explicit-shape array to a function expecting an assumed-shape
8921 argument. Performing "enter data" inside the called function
8922 would thus be problematic. */
8923 if (code
== OMP_TARGET_EXIT_DATA
8924 && OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_TO_PSET
)
8925 OMP_CLAUSE_SET_MAP_KIND (c
, OMP_CLAUSE_MAP_KIND (*prev_list_p
)
8927 ? GOMP_MAP_DELETE
: GOMP_MAP_RELEASE
);
8928 else if ((code
== OMP_TARGET_EXIT_DATA
|| code
== OMP_TARGET_UPDATE
)
8929 && (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_POINTER
8930 || OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_TO_PSET
))
8935 if (DECL_P (decl
) && outer_ctx
&& (region_type
& ORT_ACC
))
8937 struct gimplify_omp_ctx
*octx
;
8938 for (octx
= outer_ctx
; octx
; octx
= octx
->outer_context
)
8940 if (octx
->region_type
!= ORT_ACC_HOST_DATA
)
8943 = splay_tree_lookup (octx
->variables
,
8944 (splay_tree_key
) decl
);
8946 error_at (OMP_CLAUSE_LOCATION (c
), "variable %qE "
8947 "declared in enclosing %<host_data%> region",
8951 if (OMP_CLAUSE_SIZE (c
) == NULL_TREE
)
8952 OMP_CLAUSE_SIZE (c
) = DECL_P (decl
) ? DECL_SIZE_UNIT (decl
)
8953 : TYPE_SIZE_UNIT (TREE_TYPE (decl
));
8954 if (gimplify_expr (&OMP_CLAUSE_SIZE (c
), pre_p
,
8955 NULL
, is_gimple_val
, fb_rvalue
) == GS_ERROR
)
8960 else if ((OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_FIRSTPRIVATE_POINTER
8961 || (OMP_CLAUSE_MAP_KIND (c
)
8962 == GOMP_MAP_FIRSTPRIVATE_REFERENCE
)
8963 || OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ATTACH_DETACH
)
8964 && TREE_CODE (OMP_CLAUSE_SIZE (c
)) != INTEGER_CST
)
8967 = get_initialized_tmp_var (OMP_CLAUSE_SIZE (c
), pre_p
, NULL
,
8969 if ((region_type
& ORT_TARGET
) != 0)
8970 omp_add_variable (ctx
, OMP_CLAUSE_SIZE (c
),
8971 GOVD_FIRSTPRIVATE
| GOVD_SEEN
);
8977 if (TREE_CODE (d
) == ARRAY_REF
)
8979 while (TREE_CODE (d
) == ARRAY_REF
)
8980 d
= TREE_OPERAND (d
, 0);
8981 if (TREE_CODE (d
) == COMPONENT_REF
8982 && TREE_CODE (TREE_TYPE (d
)) == ARRAY_TYPE
)
8985 pd
= &OMP_CLAUSE_DECL (c
);
8987 && TREE_CODE (decl
) == INDIRECT_REF
8988 && TREE_CODE (TREE_OPERAND (decl
, 0)) == COMPONENT_REF
8989 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl
, 0)))
8992 pd
= &TREE_OPERAND (decl
, 0);
8993 decl
= TREE_OPERAND (decl
, 0);
8995 bool indir_p
= false;
8996 tree orig_decl
= decl
;
8997 tree decl_ref
= NULL_TREE
;
8998 if ((region_type
& (ORT_ACC
| ORT_TARGET
| ORT_TARGET_DATA
)) != 0
8999 && TREE_CODE (*pd
) == COMPONENT_REF
9000 && OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ATTACH_DETACH
9001 && code
!= OACC_UPDATE
)
9003 while (TREE_CODE (decl
) == COMPONENT_REF
)
9005 decl
= TREE_OPERAND (decl
, 0);
9006 if (((TREE_CODE (decl
) == MEM_REF
9007 && integer_zerop (TREE_OPERAND (decl
, 1)))
9008 || INDIRECT_REF_P (decl
))
9009 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl
, 0)))
9013 decl
= TREE_OPERAND (decl
, 0);
9015 if (TREE_CODE (decl
) == INDIRECT_REF
9016 && DECL_P (TREE_OPERAND (decl
, 0))
9017 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl
, 0)))
9021 decl
= TREE_OPERAND (decl
, 0);
9025 else if (TREE_CODE (decl
) == COMPONENT_REF
)
9027 while (TREE_CODE (decl
) == COMPONENT_REF
)
9028 decl
= TREE_OPERAND (decl
, 0);
9029 if (TREE_CODE (decl
) == INDIRECT_REF
9030 && DECL_P (TREE_OPERAND (decl
, 0))
9031 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl
, 0)))
9033 decl
= TREE_OPERAND (decl
, 0);
9035 if (decl
!= orig_decl
&& DECL_P (decl
) && indir_p
)
9038 = ((code
== OACC_EXIT_DATA
|| code
== OMP_TARGET_EXIT_DATA
)
9039 ? GOMP_MAP_DETACH
: GOMP_MAP_ATTACH
);
9040 /* We have a dereference of a struct member. Make this an
9041 attach/detach operation, and ensure the base pointer is
9042 mapped as a FIRSTPRIVATE_POINTER. */
9043 OMP_CLAUSE_SET_MAP_KIND (c
, k
);
9044 flags
= GOVD_MAP
| GOVD_SEEN
| GOVD_EXPLICIT
;
9045 tree next_clause
= OMP_CLAUSE_CHAIN (c
);
9046 if (k
== GOMP_MAP_ATTACH
9047 && code
!= OACC_ENTER_DATA
9048 && code
!= OMP_TARGET_ENTER_DATA
9050 || (OMP_CLAUSE_CODE (next_clause
) != OMP_CLAUSE_MAP
)
9051 || (OMP_CLAUSE_MAP_KIND (next_clause
)
9052 != GOMP_MAP_POINTER
)
9053 || OMP_CLAUSE_DECL (next_clause
) != decl
)
9054 && (!struct_deref_set
9055 || !struct_deref_set
->contains (decl
)))
9057 if (!struct_deref_set
)
9058 struct_deref_set
= new hash_set
<tree
> ();
9059 /* As well as the attach, we also need a
9060 FIRSTPRIVATE_POINTER clause to properly map the
9061 pointer to the struct base. */
9062 tree c2
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
9064 OMP_CLAUSE_SET_MAP_KIND (c2
, GOMP_MAP_ALLOC
);
9065 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (c2
)
9068 = build_int_cst (build_pointer_type (char_type_node
),
9070 OMP_CLAUSE_DECL (c2
)
9071 = build2 (MEM_REF
, char_type_node
,
9072 decl_ref
? decl_ref
: decl
, charptr_zero
);
9073 OMP_CLAUSE_SIZE (c2
) = size_zero_node
;
9074 tree c3
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
9076 OMP_CLAUSE_SET_MAP_KIND (c3
,
9077 GOMP_MAP_FIRSTPRIVATE_POINTER
);
9078 OMP_CLAUSE_DECL (c3
) = decl
;
9079 OMP_CLAUSE_SIZE (c3
) = size_zero_node
;
9080 tree mapgrp
= *prev_list_p
;
9082 OMP_CLAUSE_CHAIN (c3
) = mapgrp
;
9083 OMP_CLAUSE_CHAIN (c2
) = c3
;
9085 struct_deref_set
->add (decl
);
9089 /* An "attach/detach" operation on an update directive should
9090 behave as a GOMP_MAP_ALWAYS_POINTER. Beware that
9091 unlike attach or detach map kinds, GOMP_MAP_ALWAYS_POINTER
9092 depends on the previous mapping. */
9093 if (code
== OACC_UPDATE
9094 && OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ATTACH_DETACH
)
9095 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_ALWAYS_POINTER
);
9097 && OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_TO_PSET
9098 && OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_ATTACH
9099 && OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_DETACH
9100 && code
!= OACC_UPDATE
9101 && code
!= OMP_TARGET_UPDATE
)
9103 if (error_operand_p (decl
))
9109 tree stype
= TREE_TYPE (decl
);
9110 if (TREE_CODE (stype
) == REFERENCE_TYPE
)
9111 stype
= TREE_TYPE (stype
);
9112 if (TYPE_SIZE_UNIT (stype
) == NULL
9113 || TREE_CODE (TYPE_SIZE_UNIT (stype
)) != INTEGER_CST
)
9115 error_at (OMP_CLAUSE_LOCATION (c
),
9116 "mapping field %qE of variable length "
9117 "structure", OMP_CLAUSE_DECL (c
));
9122 if (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ALWAYS_POINTER
9123 || OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ATTACH_DETACH
)
9125 /* Error recovery. */
9126 if (prev_list_p
== NULL
)
9131 if (OMP_CLAUSE_CHAIN (*prev_list_p
) != c
)
9133 tree ch
= OMP_CLAUSE_CHAIN (*prev_list_p
);
9134 if (ch
== NULL_TREE
|| OMP_CLAUSE_CHAIN (ch
) != c
)
9142 poly_offset_int offset1
;
9147 = extract_base_bit_offset (OMP_CLAUSE_DECL (c
), &base_ref
,
9148 &bitpos1
, &offset1
);
9150 gcc_assert (base
== decl
);
9153 = splay_tree_lookup (ctx
->variables
, (splay_tree_key
)decl
);
9154 bool ptr
= (OMP_CLAUSE_MAP_KIND (c
)
9155 == GOMP_MAP_ALWAYS_POINTER
);
9156 bool attach_detach
= (OMP_CLAUSE_MAP_KIND (c
)
9157 == GOMP_MAP_ATTACH_DETACH
);
9158 bool attach
= OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ATTACH
9159 || OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_DETACH
;
9160 bool has_attachments
= false;
9161 /* For OpenACC, pointers in structs should trigger an
9164 && ((region_type
& (ORT_ACC
| ORT_TARGET
| ORT_TARGET_DATA
))
9165 || code
== OMP_TARGET_ENTER_DATA
9166 || code
== OMP_TARGET_EXIT_DATA
))
9169 /* Turn a GOMP_MAP_ATTACH_DETACH clause into a
9170 GOMP_MAP_ATTACH or GOMP_MAP_DETACH clause after we
9171 have detected a case that needs a GOMP_MAP_STRUCT
9174 = ((code
== OACC_EXIT_DATA
|| code
== OMP_TARGET_EXIT_DATA
)
9175 ? GOMP_MAP_DETACH
: GOMP_MAP_ATTACH
);
9176 OMP_CLAUSE_SET_MAP_KIND (c
, k
);
9177 has_attachments
= true;
9179 if (n
== NULL
|| (n
->value
& GOVD_MAP
) == 0)
9181 tree l
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
9183 gomp_map_kind k
= attach
? GOMP_MAP_FORCE_PRESENT
9186 OMP_CLAUSE_SET_MAP_KIND (l
, k
);
9188 OMP_CLAUSE_DECL (l
) = unshare_expr (base_ref
);
9190 OMP_CLAUSE_DECL (l
) = decl
;
9194 : DECL_P (OMP_CLAUSE_DECL (l
))
9195 ? DECL_SIZE_UNIT (OMP_CLAUSE_DECL (l
))
9196 : TYPE_SIZE_UNIT (TREE_TYPE (OMP_CLAUSE_DECL (l
))));
9197 if (struct_map_to_clause
== NULL
)
9198 struct_map_to_clause
= new hash_map
<tree
, tree
>;
9199 struct_map_to_clause
->put (decl
, l
);
9200 if (ptr
|| attach_detach
)
9202 insert_struct_comp_map (code
, c
, l
, *prev_list_p
,
9209 OMP_CLAUSE_CHAIN (l
) = c
;
9211 list_p
= &OMP_CLAUSE_CHAIN (l
);
9213 if (base_ref
&& code
== OMP_TARGET
)
9215 tree c2
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
9217 enum gomp_map_kind mkind
9218 = GOMP_MAP_FIRSTPRIVATE_REFERENCE
;
9219 OMP_CLAUSE_SET_MAP_KIND (c2
, mkind
);
9220 OMP_CLAUSE_DECL (c2
) = decl
;
9221 OMP_CLAUSE_SIZE (c2
) = size_zero_node
;
9222 OMP_CLAUSE_CHAIN (c2
) = OMP_CLAUSE_CHAIN (l
);
9223 OMP_CLAUSE_CHAIN (l
) = c2
;
9225 flags
= GOVD_MAP
| GOVD_EXPLICIT
;
9226 if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c
))
9230 if (has_attachments
)
9231 flags
|= GOVD_MAP_HAS_ATTACHMENTS
;
9234 else if (struct_map_to_clause
)
9236 tree
*osc
= struct_map_to_clause
->get (decl
);
9237 tree
*sc
= NULL
, *scp
= NULL
;
9238 if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c
))
9241 n
->value
|= GOVD_SEEN
;
9242 sc
= &OMP_CLAUSE_CHAIN (*osc
);
9244 && (OMP_CLAUSE_MAP_KIND (*sc
)
9245 == GOMP_MAP_FIRSTPRIVATE_REFERENCE
))
9246 sc
= &OMP_CLAUSE_CHAIN (*sc
);
9247 /* Here "prev_list_p" is the end of the inserted
9248 alloc/release nodes after the struct node, OSC. */
9249 for (; *sc
!= c
; sc
= &OMP_CLAUSE_CHAIN (*sc
))
9250 if ((ptr
|| attach_detach
) && sc
== prev_list_p
)
9252 else if (TREE_CODE (OMP_CLAUSE_DECL (*sc
))
9254 && (TREE_CODE (OMP_CLAUSE_DECL (*sc
))
9256 && (TREE_CODE (OMP_CLAUSE_DECL (*sc
))
9261 tree sc_decl
= OMP_CLAUSE_DECL (*sc
);
9262 poly_offset_int offsetn
;
9265 = extract_base_bit_offset (sc_decl
, NULL
,
9266 &bitposn
, &offsetn
);
9271 if ((region_type
& ORT_ACC
) != 0)
9273 /* This duplicate checking code is currently only
9274 enabled for OpenACC. */
9275 tree d1
= OMP_CLAUSE_DECL (*sc
);
9276 tree d2
= OMP_CLAUSE_DECL (c
);
9277 while (TREE_CODE (d1
) == ARRAY_REF
)
9278 d1
= TREE_OPERAND (d1
, 0);
9279 while (TREE_CODE (d2
) == ARRAY_REF
)
9280 d2
= TREE_OPERAND (d2
, 0);
9281 if (TREE_CODE (d1
) == INDIRECT_REF
)
9282 d1
= TREE_OPERAND (d1
, 0);
9283 if (TREE_CODE (d2
) == INDIRECT_REF
)
9284 d2
= TREE_OPERAND (d2
, 0);
9285 while (TREE_CODE (d1
) == COMPONENT_REF
)
9286 if (TREE_CODE (d2
) == COMPONENT_REF
9287 && TREE_OPERAND (d1
, 1)
9288 == TREE_OPERAND (d2
, 1))
9290 d1
= TREE_OPERAND (d1
, 0);
9291 d2
= TREE_OPERAND (d2
, 0);
9297 error_at (OMP_CLAUSE_LOCATION (c
),
9298 "%qE appears more than once in map "
9299 "clauses", OMP_CLAUSE_DECL (c
));
9304 if (maybe_lt (offset1
, offsetn
)
9305 || (known_eq (offset1
, offsetn
)
9306 && maybe_lt (bitpos1
, bitposn
)))
9308 if (ptr
|| attach_detach
)
9317 OMP_CLAUSE_SIZE (*osc
)
9318 = size_binop (PLUS_EXPR
, OMP_CLAUSE_SIZE (*osc
),
9320 if (ptr
|| attach_detach
)
9322 tree cl
= insert_struct_comp_map (code
, c
, NULL
,
9324 if (sc
== prev_list_p
)
9331 *prev_list_p
= OMP_CLAUSE_CHAIN (c
);
9332 list_p
= prev_list_p
;
9334 OMP_CLAUSE_CHAIN (c
) = *sc
;
9341 *list_p
= OMP_CLAUSE_CHAIN (c
);
9342 OMP_CLAUSE_CHAIN (c
) = *sc
;
9349 if (gimplify_expr (pd
, pre_p
, NULL
, is_gimple_lvalue
, fb_lvalue
)
9357 && OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_ALWAYS_POINTER
9358 && OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_ATTACH_DETACH
9359 && OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_TO_PSET
9360 && OMP_CLAUSE_CHAIN (c
)
9361 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (c
)) == OMP_CLAUSE_MAP
9362 && ((OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c
))
9363 == GOMP_MAP_ALWAYS_POINTER
)
9364 || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c
))
9365 == GOMP_MAP_ATTACH_DETACH
)
9366 || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c
))
9367 == GOMP_MAP_TO_PSET
)))
9368 prev_list_p
= list_p
;
9374 /* DECL_P (decl) == true */
9376 if (struct_map_to_clause
9377 && (sc
= struct_map_to_clause
->get (decl
)) != NULL
9378 && OMP_CLAUSE_MAP_KIND (*sc
) == GOMP_MAP_STRUCT
9379 && decl
== OMP_CLAUSE_DECL (*sc
))
9381 /* We have found a map of the whole structure after a
9382 leading GOMP_MAP_STRUCT has been created, so refill the
9383 leading clause into a map of the whole structure
9384 variable, and remove the current one.
9385 TODO: we should be able to remove some maps of the
9386 following structure element maps if they are of
9387 compatible TO/FROM/ALLOC type. */
9388 OMP_CLAUSE_SET_MAP_KIND (*sc
, OMP_CLAUSE_MAP_KIND (c
));
9389 OMP_CLAUSE_SIZE (*sc
) = unshare_expr (OMP_CLAUSE_SIZE (c
));
9394 flags
= GOVD_MAP
| GOVD_EXPLICIT
;
9395 if (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ALWAYS_TO
9396 || OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ALWAYS_TOFROM
)
9397 flags
|= GOVD_MAP_ALWAYS_TO
;
9399 if ((code
== OMP_TARGET
9400 || code
== OMP_TARGET_DATA
9401 || code
== OMP_TARGET_ENTER_DATA
9402 || code
== OMP_TARGET_EXIT_DATA
)
9403 && OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ATTACH_DETACH
)
9405 for (struct gimplify_omp_ctx
*octx
= outer_ctx
; octx
;
9406 octx
= octx
->outer_context
)
9409 = splay_tree_lookup (octx
->variables
,
9410 (splay_tree_key
) OMP_CLAUSE_DECL (c
));
9411 /* If this is contained in an outer OpenMP region as a
9412 firstprivate value, remove the attach/detach. */
9413 if (n
&& (n
->value
& GOVD_FIRSTPRIVATE
))
9415 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_FIRSTPRIVATE_POINTER
);
9420 enum gomp_map_kind map_kind
= (code
== OMP_TARGET_EXIT_DATA
9423 OMP_CLAUSE_SET_MAP_KIND (c
, map_kind
);
9428 case OMP_CLAUSE_DEPEND
:
9429 if (OMP_CLAUSE_DEPEND_KIND (c
) == OMP_CLAUSE_DEPEND_SINK
)
9431 tree deps
= OMP_CLAUSE_DECL (c
);
9432 while (deps
&& TREE_CODE (deps
) == TREE_LIST
)
9434 if (TREE_CODE (TREE_PURPOSE (deps
)) == TRUNC_DIV_EXPR
9435 && DECL_P (TREE_OPERAND (TREE_PURPOSE (deps
), 1)))
9436 gimplify_expr (&TREE_OPERAND (TREE_PURPOSE (deps
), 1),
9437 pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
9438 deps
= TREE_CHAIN (deps
);
9442 else if (OMP_CLAUSE_DEPEND_KIND (c
) == OMP_CLAUSE_DEPEND_SOURCE
)
9444 if (handled_depend_iterators
== -1)
9445 handled_depend_iterators
= gimplify_omp_depend (list_p
, pre_p
);
9446 if (handled_depend_iterators
)
9448 if (handled_depend_iterators
== 2)
9452 if (TREE_CODE (OMP_CLAUSE_DECL (c
)) == COMPOUND_EXPR
)
9454 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c
), 0), pre_p
,
9455 NULL
, is_gimple_val
, fb_rvalue
);
9456 OMP_CLAUSE_DECL (c
) = TREE_OPERAND (OMP_CLAUSE_DECL (c
), 1);
9458 if (error_operand_p (OMP_CLAUSE_DECL (c
)))
9463 OMP_CLAUSE_DECL (c
) = build_fold_addr_expr (OMP_CLAUSE_DECL (c
));
9464 if (gimplify_expr (&OMP_CLAUSE_DECL (c
), pre_p
, NULL
,
9465 is_gimple_val
, fb_rvalue
) == GS_ERROR
)
9473 case OMP_CLAUSE_FROM
:
9474 case OMP_CLAUSE__CACHE_
:
9475 decl
= OMP_CLAUSE_DECL (c
);
9476 if (error_operand_p (decl
))
9481 if (OMP_CLAUSE_SIZE (c
) == NULL_TREE
)
9482 OMP_CLAUSE_SIZE (c
) = DECL_P (decl
) ? DECL_SIZE_UNIT (decl
)
9483 : TYPE_SIZE_UNIT (TREE_TYPE (decl
));
9484 if (gimplify_expr (&OMP_CLAUSE_SIZE (c
), pre_p
,
9485 NULL
, is_gimple_val
, fb_rvalue
) == GS_ERROR
)
9492 if (gimplify_expr (&OMP_CLAUSE_DECL (c
), pre_p
,
9493 NULL
, is_gimple_lvalue
, fb_lvalue
)
9503 case OMP_CLAUSE_USE_DEVICE_PTR
:
9504 case OMP_CLAUSE_USE_DEVICE_ADDR
:
9505 flags
= GOVD_EXPLICIT
;
9508 case OMP_CLAUSE_IS_DEVICE_PTR
:
9509 flags
= GOVD_FIRSTPRIVATE
| GOVD_EXPLICIT
;
9513 decl
= OMP_CLAUSE_DECL (c
);
9515 if (error_operand_p (decl
))
9520 if (DECL_NAME (decl
) == NULL_TREE
&& (flags
& GOVD_SHARED
) == 0)
9522 tree t
= omp_member_access_dummy_var (decl
);
9525 tree v
= DECL_VALUE_EXPR (decl
);
9526 DECL_NAME (decl
) = DECL_NAME (TREE_OPERAND (v
, 1));
9528 omp_notice_variable (outer_ctx
, t
, true);
9531 if (code
== OACC_DATA
9532 && OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_MAP
9533 && OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_FIRSTPRIVATE_POINTER
)
9534 flags
|= GOVD_MAP_0LEN_ARRAY
;
9535 omp_add_variable (ctx
, decl
, flags
);
9536 if ((OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
9537 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_IN_REDUCTION
9538 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_TASK_REDUCTION
)
9539 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
))
9541 omp_add_variable (ctx
, OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
),
9542 GOVD_LOCAL
| GOVD_SEEN
);
9543 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c
)
9544 && walk_tree (&OMP_CLAUSE_REDUCTION_INIT (c
),
9546 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c
),
9548 omp_add_variable (ctx
,
9549 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c
),
9550 GOVD_LOCAL
| GOVD_SEEN
);
9551 gimplify_omp_ctxp
= ctx
;
9552 push_gimplify_context ();
9554 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c
) = NULL
;
9555 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c
) = NULL
;
9557 gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c
),
9558 &OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c
));
9559 pop_gimplify_context
9560 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c
)));
9561 push_gimplify_context ();
9562 gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c
),
9563 &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c
));
9564 pop_gimplify_context
9565 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c
)));
9566 OMP_CLAUSE_REDUCTION_INIT (c
) = NULL_TREE
;
9567 OMP_CLAUSE_REDUCTION_MERGE (c
) = NULL_TREE
;
9569 gimplify_omp_ctxp
= outer_ctx
;
9571 else if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
9572 && OMP_CLAUSE_LASTPRIVATE_STMT (c
))
9574 gimplify_omp_ctxp
= ctx
;
9575 push_gimplify_context ();
9576 if (TREE_CODE (OMP_CLAUSE_LASTPRIVATE_STMT (c
)) != BIND_EXPR
)
9578 tree bind
= build3 (BIND_EXPR
, void_type_node
, NULL
,
9580 TREE_SIDE_EFFECTS (bind
) = 1;
9581 BIND_EXPR_BODY (bind
) = OMP_CLAUSE_LASTPRIVATE_STMT (c
);
9582 OMP_CLAUSE_LASTPRIVATE_STMT (c
) = bind
;
9584 gimplify_and_add (OMP_CLAUSE_LASTPRIVATE_STMT (c
),
9585 &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
));
9586 pop_gimplify_context
9587 (gimple_seq_first_stmt (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
)));
9588 OMP_CLAUSE_LASTPRIVATE_STMT (c
) = NULL_TREE
;
9590 gimplify_omp_ctxp
= outer_ctx
;
9592 else if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINEAR
9593 && OMP_CLAUSE_LINEAR_STMT (c
))
9595 gimplify_omp_ctxp
= ctx
;
9596 push_gimplify_context ();
9597 if (TREE_CODE (OMP_CLAUSE_LINEAR_STMT (c
)) != BIND_EXPR
)
9599 tree bind
= build3 (BIND_EXPR
, void_type_node
, NULL
,
9601 TREE_SIDE_EFFECTS (bind
) = 1;
9602 BIND_EXPR_BODY (bind
) = OMP_CLAUSE_LINEAR_STMT (c
);
9603 OMP_CLAUSE_LINEAR_STMT (c
) = bind
;
9605 gimplify_and_add (OMP_CLAUSE_LINEAR_STMT (c
),
9606 &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c
));
9607 pop_gimplify_context
9608 (gimple_seq_first_stmt (OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c
)));
9609 OMP_CLAUSE_LINEAR_STMT (c
) = NULL_TREE
;
9611 gimplify_omp_ctxp
= outer_ctx
;
9617 case OMP_CLAUSE_COPYIN
:
9618 case OMP_CLAUSE_COPYPRIVATE
:
9619 decl
= OMP_CLAUSE_DECL (c
);
9620 if (error_operand_p (decl
))
9625 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_COPYPRIVATE
9627 && !omp_check_private (ctx
, decl
, true))
9630 if (is_global_var (decl
))
9632 if (DECL_THREAD_LOCAL_P (decl
))
9634 else if (DECL_HAS_VALUE_EXPR_P (decl
))
9636 tree value
= get_base_address (DECL_VALUE_EXPR (decl
));
9640 && DECL_THREAD_LOCAL_P (value
))
9645 error_at (OMP_CLAUSE_LOCATION (c
),
9646 "copyprivate variable %qE is not threadprivate"
9647 " or private in outer context", DECL_NAME (decl
));
9650 if ((OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
9651 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_FIRSTPRIVATE
9652 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
)
9654 && ((region_type
& ORT_TASKLOOP
) == ORT_TASKLOOP
9655 || (region_type
== ORT_WORKSHARE
9656 && OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
9657 && (OMP_CLAUSE_REDUCTION_INSCAN (c
)
9658 || code
== OMP_LOOP
)))
9659 && (outer_ctx
->region_type
== ORT_COMBINED_PARALLEL
9660 || (code
== OMP_LOOP
9661 && OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
9662 && ((outer_ctx
->region_type
& ORT_COMBINED_TEAMS
)
9663 == ORT_COMBINED_TEAMS
))))
9666 = splay_tree_lookup (outer_ctx
->variables
,
9667 (splay_tree_key
)decl
);
9668 if (on
== NULL
|| (on
->value
& GOVD_DATA_SHARE_CLASS
) == 0)
9670 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
9671 && TREE_CODE (OMP_CLAUSE_DECL (c
)) == MEM_REF
9672 && (TREE_CODE (TREE_TYPE (decl
)) == POINTER_TYPE
9673 || (TREE_CODE (TREE_TYPE (decl
)) == REFERENCE_TYPE
9674 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl
)))
9676 omp_firstprivatize_variable (outer_ctx
, decl
);
9679 omp_add_variable (outer_ctx
, decl
,
9680 GOVD_SEEN
| GOVD_SHARED
);
9681 if (outer_ctx
->outer_context
)
9682 omp_notice_variable (outer_ctx
->outer_context
, decl
,
9688 omp_notice_variable (outer_ctx
, decl
, true);
9689 if (check_non_private
9690 && region_type
== ORT_WORKSHARE
9691 && (OMP_CLAUSE_CODE (c
) != OMP_CLAUSE_REDUCTION
9692 || decl
== OMP_CLAUSE_DECL (c
)
9693 || (TREE_CODE (OMP_CLAUSE_DECL (c
)) == MEM_REF
9694 && (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c
), 0))
9696 || (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c
), 0))
9697 == POINTER_PLUS_EXPR
9698 && (TREE_CODE (TREE_OPERAND (TREE_OPERAND
9699 (OMP_CLAUSE_DECL (c
), 0), 0))
9701 && omp_check_private (ctx
, decl
, false))
9703 error ("%s variable %qE is private in outer context",
9704 check_non_private
, DECL_NAME (decl
));
9710 if (OMP_CLAUSE_IF_MODIFIER (c
) != ERROR_MARK
9711 && OMP_CLAUSE_IF_MODIFIER (c
) != code
)
9714 for (int i
= 0; i
< 2; i
++)
9715 switch (i
? OMP_CLAUSE_IF_MODIFIER (c
) : code
)
9717 case VOID_CST
: p
[i
] = "cancel"; break;
9718 case OMP_PARALLEL
: p
[i
] = "parallel"; break;
9719 case OMP_SIMD
: p
[i
] = "simd"; break;
9720 case OMP_TASK
: p
[i
] = "task"; break;
9721 case OMP_TASKLOOP
: p
[i
] = "taskloop"; break;
9722 case OMP_TARGET_DATA
: p
[i
] = "target data"; break;
9723 case OMP_TARGET
: p
[i
] = "target"; break;
9724 case OMP_TARGET_UPDATE
: p
[i
] = "target update"; break;
9725 case OMP_TARGET_ENTER_DATA
:
9726 p
[i
] = "target enter data"; break;
9727 case OMP_TARGET_EXIT_DATA
: p
[i
] = "target exit data"; break;
9728 default: gcc_unreachable ();
9730 error_at (OMP_CLAUSE_LOCATION (c
),
9731 "expected %qs %<if%> clause modifier rather than %qs",
9737 case OMP_CLAUSE_FINAL
:
9738 OMP_CLAUSE_OPERAND (c
, 0)
9739 = gimple_boolify (OMP_CLAUSE_OPERAND (c
, 0));
9742 case OMP_CLAUSE_SCHEDULE
:
9743 case OMP_CLAUSE_NUM_THREADS
:
9744 case OMP_CLAUSE_NUM_TEAMS
:
9745 case OMP_CLAUSE_THREAD_LIMIT
:
9746 case OMP_CLAUSE_DIST_SCHEDULE
:
9747 case OMP_CLAUSE_DEVICE
:
9748 case OMP_CLAUSE_PRIORITY
:
9749 case OMP_CLAUSE_GRAINSIZE
:
9750 case OMP_CLAUSE_NUM_TASKS
:
9751 case OMP_CLAUSE_HINT
:
9752 case OMP_CLAUSE_ASYNC
:
9753 case OMP_CLAUSE_WAIT
:
9754 case OMP_CLAUSE_NUM_GANGS
:
9755 case OMP_CLAUSE_NUM_WORKERS
:
9756 case OMP_CLAUSE_VECTOR_LENGTH
:
9757 case OMP_CLAUSE_WORKER
:
9758 case OMP_CLAUSE_VECTOR
:
9759 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c
, 0), pre_p
, NULL
,
9760 is_gimple_val
, fb_rvalue
) == GS_ERROR
)
9764 case OMP_CLAUSE_GANG
:
9765 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c
, 0), pre_p
, NULL
,
9766 is_gimple_val
, fb_rvalue
) == GS_ERROR
)
9768 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c
, 1), pre_p
, NULL
,
9769 is_gimple_val
, fb_rvalue
) == GS_ERROR
)
9773 case OMP_CLAUSE_NOWAIT
:
9777 case OMP_CLAUSE_ORDERED
:
9778 case OMP_CLAUSE_UNTIED
:
9779 case OMP_CLAUSE_COLLAPSE
:
9780 case OMP_CLAUSE_TILE
:
9781 case OMP_CLAUSE_AUTO
:
9782 case OMP_CLAUSE_SEQ
:
9783 case OMP_CLAUSE_INDEPENDENT
:
9784 case OMP_CLAUSE_MERGEABLE
:
9785 case OMP_CLAUSE_PROC_BIND
:
9786 case OMP_CLAUSE_SAFELEN
:
9787 case OMP_CLAUSE_SIMDLEN
:
9788 case OMP_CLAUSE_NOGROUP
:
9789 case OMP_CLAUSE_THREADS
:
9790 case OMP_CLAUSE_SIMD
:
9791 case OMP_CLAUSE_BIND
:
9792 case OMP_CLAUSE_IF_PRESENT
:
9793 case OMP_CLAUSE_FINALIZE
:
9796 case OMP_CLAUSE_ORDER
:
9797 ctx
->order_concurrent
= true;
9800 case OMP_CLAUSE_DEFAULTMAP
:
9801 enum gimplify_defaultmap_kind gdmkmin
, gdmkmax
;
9802 switch (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
))
9804 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
:
9805 gdmkmin
= GDMK_SCALAR
;
9806 gdmkmax
= GDMK_POINTER
;
9808 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR
:
9809 gdmkmin
= gdmkmax
= GDMK_SCALAR
;
9811 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE
:
9812 gdmkmin
= gdmkmax
= GDMK_AGGREGATE
;
9814 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALLOCATABLE
:
9815 gdmkmin
= gdmkmax
= GDMK_ALLOCATABLE
;
9817 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER
:
9818 gdmkmin
= gdmkmax
= GDMK_POINTER
;
9823 for (int gdmk
= gdmkmin
; gdmk
<= gdmkmax
; gdmk
++)
9824 switch (OMP_CLAUSE_DEFAULTMAP_BEHAVIOR (c
))
9826 case OMP_CLAUSE_DEFAULTMAP_ALLOC
:
9827 ctx
->defaultmap
[gdmk
] = GOVD_MAP
| GOVD_MAP_ALLOC_ONLY
;
9829 case OMP_CLAUSE_DEFAULTMAP_TO
:
9830 ctx
->defaultmap
[gdmk
] = GOVD_MAP
| GOVD_MAP_TO_ONLY
;
9832 case OMP_CLAUSE_DEFAULTMAP_FROM
:
9833 ctx
->defaultmap
[gdmk
] = GOVD_MAP
| GOVD_MAP_FROM_ONLY
;
9835 case OMP_CLAUSE_DEFAULTMAP_TOFROM
:
9836 ctx
->defaultmap
[gdmk
] = GOVD_MAP
;
9838 case OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE
:
9839 ctx
->defaultmap
[gdmk
] = GOVD_FIRSTPRIVATE
;
9841 case OMP_CLAUSE_DEFAULTMAP_NONE
:
9842 ctx
->defaultmap
[gdmk
] = 0;
9844 case OMP_CLAUSE_DEFAULTMAP_DEFAULT
:
9848 ctx
->defaultmap
[gdmk
] = GOVD_FIRSTPRIVATE
;
9850 case GDMK_AGGREGATE
:
9851 case GDMK_ALLOCATABLE
:
9852 ctx
->defaultmap
[gdmk
] = GOVD_MAP
;
9855 ctx
->defaultmap
[gdmk
] = GOVD_MAP
| GOVD_MAP_0LEN_ARRAY
;
9866 case OMP_CLAUSE_ALIGNED
:
9867 decl
= OMP_CLAUSE_DECL (c
);
9868 if (error_operand_p (decl
))
9873 if (gimplify_expr (&OMP_CLAUSE_ALIGNED_ALIGNMENT (c
), pre_p
, NULL
,
9874 is_gimple_val
, fb_rvalue
) == GS_ERROR
)
9879 if (!is_global_var (decl
)
9880 && TREE_CODE (TREE_TYPE (decl
)) == POINTER_TYPE
)
9881 omp_add_variable (ctx
, decl
, GOVD_ALIGNED
);
9884 case OMP_CLAUSE_NONTEMPORAL
:
9885 decl
= OMP_CLAUSE_DECL (c
);
9886 if (error_operand_p (decl
))
9891 omp_add_variable (ctx
, decl
, GOVD_NONTEMPORAL
);
9894 case OMP_CLAUSE_ALLOCATE
:
9895 decl
= OMP_CLAUSE_DECL (c
);
9896 if (error_operand_p (decl
))
9901 if (gimplify_expr (&OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
), pre_p
, NULL
,
9902 is_gimple_val
, fb_rvalue
) == GS_ERROR
)
9907 else if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
) == NULL_TREE
9908 || (TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
))
9911 else if (code
== OMP_TASKLOOP
9912 || !DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
)))
9913 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
)
9914 = get_initialized_tmp_var (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
),
9915 pre_p
, NULL
, false);
9918 case OMP_CLAUSE_DEFAULT
:
9919 ctx
->default_kind
= OMP_CLAUSE_DEFAULT_KIND (c
);
9922 case OMP_CLAUSE_INCLUSIVE
:
9923 case OMP_CLAUSE_EXCLUSIVE
:
9924 decl
= OMP_CLAUSE_DECL (c
);
9926 splay_tree_node n
= splay_tree_lookup (outer_ctx
->variables
,
9927 (splay_tree_key
) decl
);
9928 if (n
== NULL
|| (n
->value
& GOVD_REDUCTION
) == 0)
9930 error_at (OMP_CLAUSE_LOCATION (c
),
9931 "%qD specified in %qs clause but not in %<inscan%> "
9932 "%<reduction%> clause on the containing construct",
9933 decl
, omp_clause_code_name
[OMP_CLAUSE_CODE (c
)]);
9938 n
->value
|= GOVD_REDUCTION_INSCAN
;
9939 if (outer_ctx
->region_type
== ORT_SIMD
9940 && outer_ctx
->outer_context
9941 && outer_ctx
->outer_context
->region_type
== ORT_WORKSHARE
)
9943 n
= splay_tree_lookup (outer_ctx
->outer_context
->variables
,
9944 (splay_tree_key
) decl
);
9945 if (n
&& (n
->value
& GOVD_REDUCTION
) != 0)
9946 n
->value
|= GOVD_REDUCTION_INSCAN
;
9956 if (code
== OACC_DATA
9957 && OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_MAP
9958 && (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_FIRSTPRIVATE_POINTER
9959 || OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
))
9962 *list_p
= OMP_CLAUSE_CHAIN (c
);
9964 list_p
= &OMP_CLAUSE_CHAIN (c
);
9967 ctx
->clauses
= *orig_list_p
;
9968 gimplify_omp_ctxp
= ctx
;
9969 if (struct_map_to_clause
)
9970 delete struct_map_to_clause
;
9971 if (struct_deref_set
)
9972 delete struct_deref_set
;
9975 /* Return true if DECL is a candidate for shared to firstprivate
9976 optimization. We only consider non-addressable scalars, not
9977 too big, and not references. */
9980 omp_shared_to_firstprivate_optimizable_decl_p (tree decl
)
9982 if (TREE_ADDRESSABLE (decl
))
9984 tree type
= TREE_TYPE (decl
);
9985 if (!is_gimple_reg_type (type
)
9986 || TREE_CODE (type
) == REFERENCE_TYPE
9987 || TREE_ADDRESSABLE (type
))
9989 /* Don't optimize too large decls, as each thread/task will have
9991 HOST_WIDE_INT len
= int_size_in_bytes (type
);
9992 if (len
== -1 || len
> 4 * POINTER_SIZE
/ BITS_PER_UNIT
)
9994 if (lang_hooks
.decls
.omp_privatize_by_reference (decl
))
9999 /* Helper function of omp_find_stores_op and gimplify_adjust_omp_clauses*.
10000 For omp_shared_to_firstprivate_optimizable_decl_p decl mark it as
10001 GOVD_WRITTEN in outer contexts. */
10004 omp_mark_stores (struct gimplify_omp_ctx
*ctx
, tree decl
)
10006 for (; ctx
; ctx
= ctx
->outer_context
)
10008 splay_tree_node n
= splay_tree_lookup (ctx
->variables
,
10009 (splay_tree_key
) decl
);
10012 else if (n
->value
& GOVD_SHARED
)
10014 n
->value
|= GOVD_WRITTEN
;
10017 else if (n
->value
& GOVD_DATA_SHARE_CLASS
)
10022 /* Helper callback for walk_gimple_seq to discover possible stores
10023 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
10024 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
10028 omp_find_stores_op (tree
*tp
, int *walk_subtrees
, void *data
)
10030 struct walk_stmt_info
*wi
= (struct walk_stmt_info
*) data
;
10032 *walk_subtrees
= 0;
10039 if (handled_component_p (op
))
10040 op
= TREE_OPERAND (op
, 0);
10041 else if ((TREE_CODE (op
) == MEM_REF
|| TREE_CODE (op
) == TARGET_MEM_REF
)
10042 && TREE_CODE (TREE_OPERAND (op
, 0)) == ADDR_EXPR
)
10043 op
= TREE_OPERAND (TREE_OPERAND (op
, 0), 0);
10048 if (!DECL_P (op
) || !omp_shared_to_firstprivate_optimizable_decl_p (op
))
10051 omp_mark_stores (gimplify_omp_ctxp
, op
);
10055 /* Helper callback for walk_gimple_seq to discover possible stores
10056 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
10057 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
10061 omp_find_stores_stmt (gimple_stmt_iterator
*gsi_p
,
10062 bool *handled_ops_p
,
10063 struct walk_stmt_info
*wi
)
10065 gimple
*stmt
= gsi_stmt (*gsi_p
);
10066 switch (gimple_code (stmt
))
10068 /* Don't recurse on OpenMP constructs for which
10069 gimplify_adjust_omp_clauses already handled the bodies,
10070 except handle gimple_omp_for_pre_body. */
10071 case GIMPLE_OMP_FOR
:
10072 *handled_ops_p
= true;
10073 if (gimple_omp_for_pre_body (stmt
))
10074 walk_gimple_seq (gimple_omp_for_pre_body (stmt
),
10075 omp_find_stores_stmt
, omp_find_stores_op
, wi
);
10077 case GIMPLE_OMP_PARALLEL
:
10078 case GIMPLE_OMP_TASK
:
10079 case GIMPLE_OMP_SECTIONS
:
10080 case GIMPLE_OMP_SINGLE
:
10081 case GIMPLE_OMP_TARGET
:
10082 case GIMPLE_OMP_TEAMS
:
10083 case GIMPLE_OMP_CRITICAL
:
10084 *handled_ops_p
= true;
10092 struct gimplify_adjust_omp_clauses_data
10098 /* For all variables that were not actually used within the context,
10099 remove PRIVATE, SHARED, and FIRSTPRIVATE clauses. */
10102 gimplify_adjust_omp_clauses_1 (splay_tree_node n
, void *data
)
10104 tree
*list_p
= ((struct gimplify_adjust_omp_clauses_data
*) data
)->list_p
;
10106 = ((struct gimplify_adjust_omp_clauses_data
*) data
)->pre_p
;
10107 tree decl
= (tree
) n
->key
;
10108 unsigned flags
= n
->value
;
10109 enum omp_clause_code code
;
10111 bool private_debug
;
10113 if (gimplify_omp_ctxp
->region_type
== ORT_COMBINED_PARALLEL
10114 && (flags
& GOVD_LASTPRIVATE_CONDITIONAL
) != 0)
10115 flags
= GOVD_SHARED
| GOVD_SEEN
| GOVD_WRITTEN
;
10116 if (flags
& (GOVD_EXPLICIT
| GOVD_LOCAL
))
10118 if ((flags
& GOVD_SEEN
) == 0)
10120 if ((flags
& GOVD_MAP_HAS_ATTACHMENTS
) != 0)
10122 if (flags
& GOVD_DEBUG_PRIVATE
)
10124 gcc_assert ((flags
& GOVD_DATA_SHARE_CLASS
) == GOVD_SHARED
);
10125 private_debug
= true;
10127 else if (flags
& GOVD_MAP
)
10128 private_debug
= false;
10131 = lang_hooks
.decls
.omp_private_debug_clause (decl
,
10132 !!(flags
& GOVD_SHARED
));
10134 code
= OMP_CLAUSE_PRIVATE
;
10135 else if (flags
& GOVD_MAP
)
10137 code
= OMP_CLAUSE_MAP
;
10138 if ((gimplify_omp_ctxp
->region_type
& ORT_ACC
) == 0
10139 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl
))))
10141 error ("%<_Atomic%> %qD in implicit %<map%> clause", decl
);
10145 && DECL_IN_CONSTANT_POOL (decl
)
10146 && !lookup_attribute ("omp declare target",
10147 DECL_ATTRIBUTES (decl
)))
10149 tree id
= get_identifier ("omp declare target");
10150 DECL_ATTRIBUTES (decl
)
10151 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (decl
));
10152 varpool_node
*node
= varpool_node::get (decl
);
10155 node
->offloadable
= 1;
10156 if (ENABLE_OFFLOADING
)
10157 g
->have_offload
= true;
10161 else if (flags
& GOVD_SHARED
)
10163 if (is_global_var (decl
))
10165 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
->outer_context
;
10166 while (ctx
!= NULL
)
10169 = splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
10170 if (on
&& (on
->value
& (GOVD_FIRSTPRIVATE
| GOVD_LASTPRIVATE
10171 | GOVD_PRIVATE
| GOVD_REDUCTION
10172 | GOVD_LINEAR
| GOVD_MAP
)) != 0)
10174 ctx
= ctx
->outer_context
;
10179 code
= OMP_CLAUSE_SHARED
;
10181 else if (flags
& GOVD_PRIVATE
)
10182 code
= OMP_CLAUSE_PRIVATE
;
10183 else if (flags
& GOVD_FIRSTPRIVATE
)
10185 code
= OMP_CLAUSE_FIRSTPRIVATE
;
10186 if ((gimplify_omp_ctxp
->region_type
& ORT_TARGET
)
10187 && (gimplify_omp_ctxp
->region_type
& ORT_ACC
) == 0
10188 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl
))))
10190 error ("%<_Atomic%> %qD in implicit %<firstprivate%> clause on "
10191 "%<target%> construct", decl
);
10195 else if (flags
& GOVD_LASTPRIVATE
)
10196 code
= OMP_CLAUSE_LASTPRIVATE
;
10197 else if (flags
& (GOVD_ALIGNED
| GOVD_NONTEMPORAL
))
10199 else if (flags
& GOVD_CONDTEMP
)
10201 code
= OMP_CLAUSE__CONDTEMP_
;
10202 gimple_add_tmp_var (decl
);
10205 gcc_unreachable ();
10207 if (((flags
& GOVD_LASTPRIVATE
)
10208 || (code
== OMP_CLAUSE_SHARED
&& (flags
& GOVD_WRITTEN
)))
10209 && omp_shared_to_firstprivate_optimizable_decl_p (decl
))
10210 omp_mark_stores (gimplify_omp_ctxp
->outer_context
, decl
);
10212 tree chain
= *list_p
;
10213 clause
= build_omp_clause (input_location
, code
);
10214 OMP_CLAUSE_DECL (clause
) = decl
;
10215 OMP_CLAUSE_CHAIN (clause
) = chain
;
10217 OMP_CLAUSE_PRIVATE_DEBUG (clause
) = 1;
10218 else if (code
== OMP_CLAUSE_PRIVATE
&& (flags
& GOVD_PRIVATE_OUTER_REF
))
10219 OMP_CLAUSE_PRIVATE_OUTER_REF (clause
) = 1;
10220 else if (code
== OMP_CLAUSE_SHARED
10221 && (flags
& GOVD_WRITTEN
) == 0
10222 && omp_shared_to_firstprivate_optimizable_decl_p (decl
))
10223 OMP_CLAUSE_SHARED_READONLY (clause
) = 1;
10224 else if (code
== OMP_CLAUSE_FIRSTPRIVATE
&& (flags
& GOVD_EXPLICIT
) == 0)
10225 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (clause
) = 1;
10226 else if (code
== OMP_CLAUSE_MAP
&& (flags
& GOVD_MAP_0LEN_ARRAY
) != 0)
10228 tree nc
= build_omp_clause (input_location
, OMP_CLAUSE_MAP
);
10229 OMP_CLAUSE_DECL (nc
) = decl
;
10230 if (TREE_CODE (TREE_TYPE (decl
)) == REFERENCE_TYPE
10231 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl
))) == POINTER_TYPE
)
10232 OMP_CLAUSE_DECL (clause
)
10233 = build_simple_mem_ref_loc (input_location
, decl
);
10234 OMP_CLAUSE_DECL (clause
)
10235 = build2 (MEM_REF
, char_type_node
, OMP_CLAUSE_DECL (clause
),
10236 build_int_cst (build_pointer_type (char_type_node
), 0));
10237 OMP_CLAUSE_SIZE (clause
) = size_zero_node
;
10238 OMP_CLAUSE_SIZE (nc
) = size_zero_node
;
10239 OMP_CLAUSE_SET_MAP_KIND (clause
, GOMP_MAP_ALLOC
);
10240 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (clause
) = 1;
10241 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_FIRSTPRIVATE_POINTER
);
10242 OMP_CLAUSE_CHAIN (nc
) = chain
;
10243 OMP_CLAUSE_CHAIN (clause
) = nc
;
10244 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
10245 gimplify_omp_ctxp
= ctx
->outer_context
;
10246 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (clause
), 0),
10247 pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
10248 gimplify_omp_ctxp
= ctx
;
10250 else if (code
== OMP_CLAUSE_MAP
)
10253 /* Not all combinations of these GOVD_MAP flags are actually valid. */
10254 switch (flags
& (GOVD_MAP_TO_ONLY
10256 | GOVD_MAP_FORCE_PRESENT
10257 | GOVD_MAP_ALLOC_ONLY
10258 | GOVD_MAP_FROM_ONLY
))
10261 kind
= GOMP_MAP_TOFROM
;
10263 case GOVD_MAP_FORCE
:
10264 kind
= GOMP_MAP_TOFROM
| GOMP_MAP_FLAG_FORCE
;
10266 case GOVD_MAP_TO_ONLY
:
10267 kind
= GOMP_MAP_TO
;
10269 case GOVD_MAP_FROM_ONLY
:
10270 kind
= GOMP_MAP_FROM
;
10272 case GOVD_MAP_ALLOC_ONLY
:
10273 kind
= GOMP_MAP_ALLOC
;
10275 case GOVD_MAP_TO_ONLY
| GOVD_MAP_FORCE
:
10276 kind
= GOMP_MAP_TO
| GOMP_MAP_FLAG_FORCE
;
10278 case GOVD_MAP_FORCE_PRESENT
:
10279 kind
= GOMP_MAP_FORCE_PRESENT
;
10282 gcc_unreachable ();
10284 OMP_CLAUSE_SET_MAP_KIND (clause
, kind
);
10285 if (DECL_SIZE (decl
)
10286 && TREE_CODE (DECL_SIZE (decl
)) != INTEGER_CST
)
10288 tree decl2
= DECL_VALUE_EXPR (decl
);
10289 gcc_assert (TREE_CODE (decl2
) == INDIRECT_REF
);
10290 decl2
= TREE_OPERAND (decl2
, 0);
10291 gcc_assert (DECL_P (decl2
));
10292 tree mem
= build_simple_mem_ref (decl2
);
10293 OMP_CLAUSE_DECL (clause
) = mem
;
10294 OMP_CLAUSE_SIZE (clause
) = TYPE_SIZE_UNIT (TREE_TYPE (decl
));
10295 if (gimplify_omp_ctxp
->outer_context
)
10297 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
->outer_context
;
10298 omp_notice_variable (ctx
, decl2
, true);
10299 omp_notice_variable (ctx
, OMP_CLAUSE_SIZE (clause
), true);
10301 tree nc
= build_omp_clause (OMP_CLAUSE_LOCATION (clause
),
10303 OMP_CLAUSE_DECL (nc
) = decl
;
10304 OMP_CLAUSE_SIZE (nc
) = size_zero_node
;
10305 if (gimplify_omp_ctxp
->target_firstprivatize_array_bases
)
10306 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_FIRSTPRIVATE_POINTER
);
10308 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_POINTER
);
10309 OMP_CLAUSE_CHAIN (nc
) = OMP_CLAUSE_CHAIN (clause
);
10310 OMP_CLAUSE_CHAIN (clause
) = nc
;
10312 else if (gimplify_omp_ctxp
->target_firstprivatize_array_bases
10313 && lang_hooks
.decls
.omp_privatize_by_reference (decl
))
10315 OMP_CLAUSE_DECL (clause
) = build_simple_mem_ref (decl
);
10316 OMP_CLAUSE_SIZE (clause
)
10317 = unshare_expr (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl
))));
10318 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
10319 gimplify_omp_ctxp
= ctx
->outer_context
;
10320 gimplify_expr (&OMP_CLAUSE_SIZE (clause
),
10321 pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
10322 gimplify_omp_ctxp
= ctx
;
10323 tree nc
= build_omp_clause (OMP_CLAUSE_LOCATION (clause
),
10325 OMP_CLAUSE_DECL (nc
) = decl
;
10326 OMP_CLAUSE_SIZE (nc
) = size_zero_node
;
10327 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_FIRSTPRIVATE_REFERENCE
);
10328 OMP_CLAUSE_CHAIN (nc
) = OMP_CLAUSE_CHAIN (clause
);
10329 OMP_CLAUSE_CHAIN (clause
) = nc
;
10332 OMP_CLAUSE_SIZE (clause
) = DECL_SIZE_UNIT (decl
);
10334 if (code
== OMP_CLAUSE_FIRSTPRIVATE
&& (flags
& GOVD_LASTPRIVATE
) != 0)
10336 tree nc
= build_omp_clause (input_location
, OMP_CLAUSE_LASTPRIVATE
);
10337 OMP_CLAUSE_DECL (nc
) = decl
;
10338 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (nc
) = 1;
10339 OMP_CLAUSE_CHAIN (nc
) = chain
;
10340 OMP_CLAUSE_CHAIN (clause
) = nc
;
10341 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
10342 gimplify_omp_ctxp
= ctx
->outer_context
;
10343 lang_hooks
.decls
.omp_finish_clause (nc
, pre_p
,
10344 (ctx
->region_type
& ORT_ACC
) != 0);
10345 gimplify_omp_ctxp
= ctx
;
10348 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
10349 gimplify_omp_ctxp
= ctx
->outer_context
;
10350 lang_hooks
.decls
.omp_finish_clause (clause
, pre_p
,
10351 (ctx
->region_type
& ORT_ACC
) != 0);
10352 if (gimplify_omp_ctxp
)
10353 for (; clause
!= chain
; clause
= OMP_CLAUSE_CHAIN (clause
))
10354 if (OMP_CLAUSE_CODE (clause
) == OMP_CLAUSE_MAP
10355 && DECL_P (OMP_CLAUSE_SIZE (clause
)))
10356 omp_notice_variable (gimplify_omp_ctxp
, OMP_CLAUSE_SIZE (clause
),
10358 gimplify_omp_ctxp
= ctx
;
10363 gimplify_adjust_omp_clauses (gimple_seq
*pre_p
, gimple_seq body
, tree
*list_p
,
10364 enum tree_code code
)
10366 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
10367 tree
*orig_list_p
= list_p
;
10369 bool has_inscan_reductions
= false;
10373 struct gimplify_omp_ctx
*octx
;
10374 for (octx
= ctx
; octx
; octx
= octx
->outer_context
)
10375 if ((octx
->region_type
& (ORT_PARALLEL
| ORT_TASK
| ORT_TEAMS
)) != 0)
10379 struct walk_stmt_info wi
;
10380 memset (&wi
, 0, sizeof (wi
));
10381 walk_gimple_seq (body
, omp_find_stores_stmt
,
10382 omp_find_stores_op
, &wi
);
10386 if (ctx
->add_safelen1
)
10388 /* If there are VLAs in the body of simd loop, prevent
10390 gcc_assert (ctx
->region_type
== ORT_SIMD
);
10391 c
= build_omp_clause (UNKNOWN_LOCATION
, OMP_CLAUSE_SAFELEN
);
10392 OMP_CLAUSE_SAFELEN_EXPR (c
) = integer_one_node
;
10393 OMP_CLAUSE_CHAIN (c
) = *list_p
;
10395 list_p
= &OMP_CLAUSE_CHAIN (c
);
10398 if (ctx
->region_type
== ORT_WORKSHARE
10399 && ctx
->outer_context
10400 && ctx
->outer_context
->region_type
== ORT_COMBINED_PARALLEL
)
10402 for (c
= ctx
->outer_context
->clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
10403 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
10404 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
))
10406 decl
= OMP_CLAUSE_DECL (c
);
10408 = splay_tree_lookup (ctx
->outer_context
->variables
,
10409 (splay_tree_key
) decl
);
10410 gcc_checking_assert (!splay_tree_lookup (ctx
->variables
,
10411 (splay_tree_key
) decl
));
10412 omp_add_variable (ctx
, decl
, n
->value
);
10413 tree c2
= copy_node (c
);
10414 OMP_CLAUSE_CHAIN (c2
) = *list_p
;
10416 if ((n
->value
& GOVD_FIRSTPRIVATE
) == 0)
10418 c2
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
10419 OMP_CLAUSE_FIRSTPRIVATE
);
10420 OMP_CLAUSE_DECL (c2
) = decl
;
10421 OMP_CLAUSE_CHAIN (c2
) = *list_p
;
10425 while ((c
= *list_p
) != NULL
)
10428 bool remove
= false;
10430 switch (OMP_CLAUSE_CODE (c
))
10432 case OMP_CLAUSE_FIRSTPRIVATE
:
10433 if ((ctx
->region_type
& ORT_TARGET
)
10434 && (ctx
->region_type
& ORT_ACC
) == 0
10435 && TYPE_ATOMIC (strip_array_types
10436 (TREE_TYPE (OMP_CLAUSE_DECL (c
)))))
10438 error_at (OMP_CLAUSE_LOCATION (c
),
10439 "%<_Atomic%> %qD in %<firstprivate%> clause on "
10440 "%<target%> construct", OMP_CLAUSE_DECL (c
));
10445 case OMP_CLAUSE_PRIVATE
:
10446 case OMP_CLAUSE_SHARED
:
10447 case OMP_CLAUSE_LINEAR
:
10448 decl
= OMP_CLAUSE_DECL (c
);
10449 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
10450 remove
= !(n
->value
& GOVD_SEEN
);
10451 if ((n
->value
& GOVD_LASTPRIVATE_CONDITIONAL
) != 0
10452 && code
== OMP_PARALLEL
10453 && OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_FIRSTPRIVATE
)
10457 bool shared
= OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_SHARED
;
10458 if ((n
->value
& GOVD_DEBUG_PRIVATE
)
10459 || lang_hooks
.decls
.omp_private_debug_clause (decl
, shared
))
10461 gcc_assert ((n
->value
& GOVD_DEBUG_PRIVATE
) == 0
10462 || ((n
->value
& GOVD_DATA_SHARE_CLASS
)
10464 OMP_CLAUSE_SET_CODE (c
, OMP_CLAUSE_PRIVATE
);
10465 OMP_CLAUSE_PRIVATE_DEBUG (c
) = 1;
10467 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_SHARED
10468 && (n
->value
& GOVD_WRITTEN
) == 0
10470 && omp_shared_to_firstprivate_optimizable_decl_p (decl
))
10471 OMP_CLAUSE_SHARED_READONLY (c
) = 1;
10472 else if (DECL_P (decl
)
10473 && ((OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_SHARED
10474 && (n
->value
& GOVD_WRITTEN
) != 0)
10475 || (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINEAR
10476 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c
)))
10477 && omp_shared_to_firstprivate_optimizable_decl_p (decl
))
10478 omp_mark_stores (gimplify_omp_ctxp
->outer_context
, decl
);
10481 n
->value
&= ~GOVD_EXPLICIT
;
10484 case OMP_CLAUSE_LASTPRIVATE
:
10485 /* Make sure OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE is set to
10486 accurately reflect the presence of a FIRSTPRIVATE clause. */
10487 decl
= OMP_CLAUSE_DECL (c
);
10488 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
10489 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
)
10490 = (n
->value
& GOVD_FIRSTPRIVATE
) != 0;
10491 if (code
== OMP_DISTRIBUTE
10492 && OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
))
10495 error_at (OMP_CLAUSE_LOCATION (c
),
10496 "same variable used in %<firstprivate%> and "
10497 "%<lastprivate%> clauses on %<distribute%> "
10501 && OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
10503 && omp_shared_to_firstprivate_optimizable_decl_p (decl
))
10504 omp_mark_stores (gimplify_omp_ctxp
->outer_context
, decl
);
10505 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
) && code
== OMP_PARALLEL
)
10509 case OMP_CLAUSE_ALIGNED
:
10510 decl
= OMP_CLAUSE_DECL (c
);
10511 if (!is_global_var (decl
))
10513 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
10514 remove
= n
== NULL
|| !(n
->value
& GOVD_SEEN
);
10515 if (!remove
&& TREE_CODE (TREE_TYPE (decl
)) == POINTER_TYPE
)
10517 struct gimplify_omp_ctx
*octx
;
10519 && (n
->value
& (GOVD_DATA_SHARE_CLASS
10520 & ~GOVD_FIRSTPRIVATE
)))
10523 for (octx
= ctx
->outer_context
; octx
;
10524 octx
= octx
->outer_context
)
10526 n
= splay_tree_lookup (octx
->variables
,
10527 (splay_tree_key
) decl
);
10530 if (n
->value
& GOVD_LOCAL
)
10532 /* We have to avoid assigning a shared variable
10533 to itself when trying to add
10534 __builtin_assume_aligned. */
10535 if (n
->value
& GOVD_SHARED
)
10543 else if (TREE_CODE (TREE_TYPE (decl
)) == ARRAY_TYPE
)
10545 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
10546 if (n
!= NULL
&& (n
->value
& GOVD_DATA_SHARE_CLASS
) != 0)
10551 case OMP_CLAUSE_NONTEMPORAL
:
10552 decl
= OMP_CLAUSE_DECL (c
);
10553 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
10554 remove
= n
== NULL
|| !(n
->value
& GOVD_SEEN
);
10557 case OMP_CLAUSE_MAP
:
10558 if (code
== OMP_TARGET_EXIT_DATA
10559 && OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ALWAYS_POINTER
)
10564 decl
= OMP_CLAUSE_DECL (c
);
10565 /* Data clauses associated with reductions must be
10566 compatible with present_or_copy. Warn and adjust the clause
10567 if that is not the case. */
10568 if (ctx
->region_type
== ORT_ACC_PARALLEL
10569 || ctx
->region_type
== ORT_ACC_SERIAL
)
10571 tree t
= DECL_P (decl
) ? decl
: TREE_OPERAND (decl
, 0);
10575 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) t
);
10577 if (n
&& (n
->value
& GOVD_REDUCTION
))
10579 enum gomp_map_kind kind
= OMP_CLAUSE_MAP_KIND (c
);
10581 OMP_CLAUSE_MAP_IN_REDUCTION (c
) = 1;
10582 if ((kind
& GOMP_MAP_TOFROM
) != GOMP_MAP_TOFROM
10583 && kind
!= GOMP_MAP_FORCE_PRESENT
10584 && kind
!= GOMP_MAP_POINTER
)
10586 warning_at (OMP_CLAUSE_LOCATION (c
), 0,
10587 "incompatible data clause with reduction "
10588 "on %qE; promoting to %<present_or_copy%>",
10590 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_TOFROM
);
10594 if (!DECL_P (decl
))
10596 if ((ctx
->region_type
& ORT_TARGET
) != 0
10597 && OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_FIRSTPRIVATE_POINTER
)
10599 if (TREE_CODE (decl
) == INDIRECT_REF
10600 && TREE_CODE (TREE_OPERAND (decl
, 0)) == COMPONENT_REF
10601 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl
, 0)))
10602 == REFERENCE_TYPE
))
10603 decl
= TREE_OPERAND (decl
, 0);
10604 if (TREE_CODE (decl
) == COMPONENT_REF
)
10606 while (TREE_CODE (decl
) == COMPONENT_REF
)
10607 decl
= TREE_OPERAND (decl
, 0);
10610 n
= splay_tree_lookup (ctx
->variables
,
10611 (splay_tree_key
) decl
);
10612 if (!(n
->value
& GOVD_SEEN
))
10619 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
10620 if ((ctx
->region_type
& ORT_TARGET
) != 0
10621 && !(n
->value
& GOVD_SEEN
)
10622 && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c
)) == 0
10623 && (!is_global_var (decl
)
10624 || !lookup_attribute ("omp declare target link",
10625 DECL_ATTRIBUTES (decl
))))
10628 /* For struct element mapping, if struct is never referenced
10629 in target block and none of the mapping has always modifier,
10630 remove all the struct element mappings, which immediately
10631 follow the GOMP_MAP_STRUCT map clause. */
10632 if (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_STRUCT
)
10634 HOST_WIDE_INT cnt
= tree_to_shwi (OMP_CLAUSE_SIZE (c
));
10636 OMP_CLAUSE_CHAIN (c
)
10637 = OMP_CLAUSE_CHAIN (OMP_CLAUSE_CHAIN (c
));
10640 else if (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_STRUCT
10641 && (code
== OMP_TARGET_EXIT_DATA
10642 || code
== OACC_EXIT_DATA
))
10644 else if (DECL_SIZE (decl
)
10645 && TREE_CODE (DECL_SIZE (decl
)) != INTEGER_CST
10646 && OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_POINTER
10647 && OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_FIRSTPRIVATE_POINTER
10648 && (OMP_CLAUSE_MAP_KIND (c
)
10649 != GOMP_MAP_FIRSTPRIVATE_REFERENCE
))
10651 /* For GOMP_MAP_FORCE_DEVICEPTR, we'll never enter here, because
10652 for these, TREE_CODE (DECL_SIZE (decl)) will always be
10654 gcc_assert (OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_FORCE_DEVICEPTR
);
10656 tree decl2
= DECL_VALUE_EXPR (decl
);
10657 gcc_assert (TREE_CODE (decl2
) == INDIRECT_REF
);
10658 decl2
= TREE_OPERAND (decl2
, 0);
10659 gcc_assert (DECL_P (decl2
));
10660 tree mem
= build_simple_mem_ref (decl2
);
10661 OMP_CLAUSE_DECL (c
) = mem
;
10662 OMP_CLAUSE_SIZE (c
) = TYPE_SIZE_UNIT (TREE_TYPE (decl
));
10663 if (ctx
->outer_context
)
10665 omp_notice_variable (ctx
->outer_context
, decl2
, true);
10666 omp_notice_variable (ctx
->outer_context
,
10667 OMP_CLAUSE_SIZE (c
), true);
10669 if (((ctx
->region_type
& ORT_TARGET
) != 0
10670 || !ctx
->target_firstprivatize_array_bases
)
10671 && ((n
->value
& GOVD_SEEN
) == 0
10672 || (n
->value
& (GOVD_PRIVATE
| GOVD_FIRSTPRIVATE
)) == 0))
10674 tree nc
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
10676 OMP_CLAUSE_DECL (nc
) = decl
;
10677 OMP_CLAUSE_SIZE (nc
) = size_zero_node
;
10678 if (ctx
->target_firstprivatize_array_bases
)
10679 OMP_CLAUSE_SET_MAP_KIND (nc
,
10680 GOMP_MAP_FIRSTPRIVATE_POINTER
);
10682 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_POINTER
);
10683 OMP_CLAUSE_CHAIN (nc
) = OMP_CLAUSE_CHAIN (c
);
10684 OMP_CLAUSE_CHAIN (c
) = nc
;
10690 if (OMP_CLAUSE_SIZE (c
) == NULL_TREE
)
10691 OMP_CLAUSE_SIZE (c
) = DECL_SIZE_UNIT (decl
);
10692 gcc_assert ((n
->value
& GOVD_SEEN
) == 0
10693 || ((n
->value
& (GOVD_PRIVATE
| GOVD_FIRSTPRIVATE
))
10698 case OMP_CLAUSE_TO
:
10699 case OMP_CLAUSE_FROM
:
10700 case OMP_CLAUSE__CACHE_
:
10701 decl
= OMP_CLAUSE_DECL (c
);
10702 if (!DECL_P (decl
))
10704 if (DECL_SIZE (decl
)
10705 && TREE_CODE (DECL_SIZE (decl
)) != INTEGER_CST
)
10707 tree decl2
= DECL_VALUE_EXPR (decl
);
10708 gcc_assert (TREE_CODE (decl2
) == INDIRECT_REF
);
10709 decl2
= TREE_OPERAND (decl2
, 0);
10710 gcc_assert (DECL_P (decl2
));
10711 tree mem
= build_simple_mem_ref (decl2
);
10712 OMP_CLAUSE_DECL (c
) = mem
;
10713 OMP_CLAUSE_SIZE (c
) = TYPE_SIZE_UNIT (TREE_TYPE (decl
));
10714 if (ctx
->outer_context
)
10716 omp_notice_variable (ctx
->outer_context
, decl2
, true);
10717 omp_notice_variable (ctx
->outer_context
,
10718 OMP_CLAUSE_SIZE (c
), true);
10721 else if (OMP_CLAUSE_SIZE (c
) == NULL_TREE
)
10722 OMP_CLAUSE_SIZE (c
) = DECL_SIZE_UNIT (decl
);
10725 case OMP_CLAUSE_REDUCTION
:
10726 if (OMP_CLAUSE_REDUCTION_INSCAN (c
))
10728 decl
= OMP_CLAUSE_DECL (c
);
10729 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
10730 if ((n
->value
& GOVD_REDUCTION_INSCAN
) == 0)
10733 error_at (OMP_CLAUSE_LOCATION (c
),
10734 "%qD specified in %<inscan%> %<reduction%> clause "
10735 "but not in %<scan%> directive clause", decl
);
10738 has_inscan_reductions
= true;
10741 case OMP_CLAUSE_IN_REDUCTION
:
10742 case OMP_CLAUSE_TASK_REDUCTION
:
10743 decl
= OMP_CLAUSE_DECL (c
);
10744 /* OpenACC reductions need a present_or_copy data clause.
10745 Add one if necessary. Emit error when the reduction is private. */
10746 if (ctx
->region_type
== ORT_ACC_PARALLEL
10747 || ctx
->region_type
== ORT_ACC_SERIAL
)
10749 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
10750 if (n
->value
& (GOVD_PRIVATE
| GOVD_FIRSTPRIVATE
))
10753 error_at (OMP_CLAUSE_LOCATION (c
), "invalid private "
10754 "reduction on %qE", DECL_NAME (decl
));
10756 else if ((n
->value
& GOVD_MAP
) == 0)
10758 tree next
= OMP_CLAUSE_CHAIN (c
);
10759 tree nc
= build_omp_clause (UNKNOWN_LOCATION
, OMP_CLAUSE_MAP
);
10760 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_TOFROM
);
10761 OMP_CLAUSE_DECL (nc
) = decl
;
10762 OMP_CLAUSE_CHAIN (c
) = nc
;
10763 lang_hooks
.decls
.omp_finish_clause (nc
, pre_p
,
10768 OMP_CLAUSE_MAP_IN_REDUCTION (nc
) = 1;
10769 if (OMP_CLAUSE_CHAIN (nc
) == NULL
)
10771 nc
= OMP_CLAUSE_CHAIN (nc
);
10773 OMP_CLAUSE_CHAIN (nc
) = next
;
10774 n
->value
|= GOVD_MAP
;
10778 && omp_shared_to_firstprivate_optimizable_decl_p (decl
))
10779 omp_mark_stores (gimplify_omp_ctxp
->outer_context
, decl
);
10782 case OMP_CLAUSE_ALLOCATE
:
10783 decl
= OMP_CLAUSE_DECL (c
);
10784 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
10785 if (n
!= NULL
&& !(n
->value
& GOVD_SEEN
))
10787 if ((n
->value
& (GOVD_PRIVATE
| GOVD_FIRSTPRIVATE
| GOVD_LINEAR
))
10789 && (n
->value
& (GOVD_REDUCTION
| GOVD_LASTPRIVATE
)) == 0)
10793 && OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
)
10794 && TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
)) != INTEGER_CST
10795 && ((ctx
->region_type
& (ORT_PARALLEL
| ORT_TARGET
)) != 0
10796 || (ctx
->region_type
& ORT_TASKLOOP
) == ORT_TASK
10797 || (ctx
->region_type
& ORT_HOST_TEAMS
) == ORT_HOST_TEAMS
))
10799 tree allocator
= OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
);
10800 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) allocator
);
10803 enum omp_clause_default_kind default_kind
10804 = ctx
->default_kind
;
10805 ctx
->default_kind
= OMP_CLAUSE_DEFAULT_FIRSTPRIVATE
;
10806 omp_notice_variable (ctx
, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
),
10808 ctx
->default_kind
= default_kind
;
10811 omp_notice_variable (ctx
, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
),
10816 case OMP_CLAUSE_COPYIN
:
10817 case OMP_CLAUSE_COPYPRIVATE
:
10818 case OMP_CLAUSE_IF
:
10819 case OMP_CLAUSE_NUM_THREADS
:
10820 case OMP_CLAUSE_NUM_TEAMS
:
10821 case OMP_CLAUSE_THREAD_LIMIT
:
10822 case OMP_CLAUSE_DIST_SCHEDULE
:
10823 case OMP_CLAUSE_DEVICE
:
10824 case OMP_CLAUSE_SCHEDULE
:
10825 case OMP_CLAUSE_NOWAIT
:
10826 case OMP_CLAUSE_ORDERED
:
10827 case OMP_CLAUSE_DEFAULT
:
10828 case OMP_CLAUSE_UNTIED
:
10829 case OMP_CLAUSE_COLLAPSE
:
10830 case OMP_CLAUSE_FINAL
:
10831 case OMP_CLAUSE_MERGEABLE
:
10832 case OMP_CLAUSE_PROC_BIND
:
10833 case OMP_CLAUSE_SAFELEN
:
10834 case OMP_CLAUSE_SIMDLEN
:
10835 case OMP_CLAUSE_DEPEND
:
10836 case OMP_CLAUSE_PRIORITY
:
10837 case OMP_CLAUSE_GRAINSIZE
:
10838 case OMP_CLAUSE_NUM_TASKS
:
10839 case OMP_CLAUSE_NOGROUP
:
10840 case OMP_CLAUSE_THREADS
:
10841 case OMP_CLAUSE_SIMD
:
10842 case OMP_CLAUSE_HINT
:
10843 case OMP_CLAUSE_DEFAULTMAP
:
10844 case OMP_CLAUSE_ORDER
:
10845 case OMP_CLAUSE_BIND
:
10846 case OMP_CLAUSE_USE_DEVICE_PTR
:
10847 case OMP_CLAUSE_USE_DEVICE_ADDR
:
10848 case OMP_CLAUSE_IS_DEVICE_PTR
:
10849 case OMP_CLAUSE_ASYNC
:
10850 case OMP_CLAUSE_WAIT
:
10851 case OMP_CLAUSE_INDEPENDENT
:
10852 case OMP_CLAUSE_NUM_GANGS
:
10853 case OMP_CLAUSE_NUM_WORKERS
:
10854 case OMP_CLAUSE_VECTOR_LENGTH
:
10855 case OMP_CLAUSE_GANG
:
10856 case OMP_CLAUSE_WORKER
:
10857 case OMP_CLAUSE_VECTOR
:
10858 case OMP_CLAUSE_AUTO
:
10859 case OMP_CLAUSE_SEQ
:
10860 case OMP_CLAUSE_TILE
:
10861 case OMP_CLAUSE_IF_PRESENT
:
10862 case OMP_CLAUSE_FINALIZE
:
10863 case OMP_CLAUSE_INCLUSIVE
:
10864 case OMP_CLAUSE_EXCLUSIVE
:
10868 gcc_unreachable ();
10872 *list_p
= OMP_CLAUSE_CHAIN (c
);
10874 list_p
= &OMP_CLAUSE_CHAIN (c
);
10877 /* Add in any implicit data sharing. */
10878 struct gimplify_adjust_omp_clauses_data data
;
10879 data
.list_p
= list_p
;
10880 data
.pre_p
= pre_p
;
10881 splay_tree_foreach (ctx
->variables
, gimplify_adjust_omp_clauses_1
, &data
);
10883 if (has_inscan_reductions
)
10884 for (c
= *orig_list_p
; c
; c
= OMP_CLAUSE_CHAIN (c
))
10885 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINEAR
10886 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c
))
10888 error_at (OMP_CLAUSE_LOCATION (c
),
10889 "%<inscan%> %<reduction%> clause used together with "
10890 "%<linear%> clause for a variable other than loop "
10895 gimplify_omp_ctxp
= ctx
->outer_context
;
10896 delete_omp_context (ctx
);
10899 /* Return 0 if CONSTRUCTS selectors don't match the OpenMP context,
10900 -1 if unknown yet (simd is involved, won't be known until vectorization)
10901 and 1 if they do. If SCORES is non-NULL, it should point to an array
10902 of at least 2*NCONSTRUCTS+2 ints, and will be filled with the positions
10903 of the CONSTRUCTS (position -1 if it will never match) followed by
10904 number of constructs in the OpenMP context construct trait. If the
10905 score depends on whether it will be in a declare simd clone or not,
10906 the function returns 2 and there will be two sets of the scores, the first
10907 one for the case that it is not in a declare simd clone, the other
10908 that it is in a declare simd clone. */
10911 omp_construct_selector_matches (enum tree_code
*constructs
, int nconstructs
,
10914 int matched
= 0, cnt
= 0;
10915 bool simd_seen
= false;
10916 bool target_seen
= false;
10917 int declare_simd_cnt
= -1;
10918 auto_vec
<enum tree_code
, 16> codes
;
10919 for (struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
; ctx
;)
10921 if (((ctx
->region_type
& ORT_PARALLEL
) && ctx
->code
== OMP_PARALLEL
)
10922 || ((ctx
->region_type
& (ORT_TARGET
| ORT_IMPLICIT_TARGET
| ORT_ACC
))
10923 == ORT_TARGET
&& ctx
->code
== OMP_TARGET
)
10924 || ((ctx
->region_type
& ORT_TEAMS
) && ctx
->code
== OMP_TEAMS
)
10925 || (ctx
->region_type
== ORT_WORKSHARE
&& ctx
->code
== OMP_FOR
)
10926 || (ctx
->region_type
== ORT_SIMD
10927 && ctx
->code
== OMP_SIMD
10928 && !omp_find_clause (ctx
->clauses
, OMP_CLAUSE_BIND
)))
10932 codes
.safe_push (ctx
->code
);
10933 else if (matched
< nconstructs
&& ctx
->code
== constructs
[matched
])
10935 if (ctx
->code
== OMP_SIMD
)
10943 if (ctx
->code
== OMP_TARGET
)
10945 if (scores
== NULL
)
10946 return matched
< nconstructs
? 0 : simd_seen
? -1 : 1;
10947 target_seen
= true;
10951 else if (ctx
->region_type
== ORT_WORKSHARE
10952 && ctx
->code
== OMP_LOOP
10953 && ctx
->outer_context
10954 && ctx
->outer_context
->region_type
== ORT_COMBINED_PARALLEL
10955 && ctx
->outer_context
->outer_context
10956 && ctx
->outer_context
->outer_context
->code
== OMP_LOOP
10957 && ctx
->outer_context
->outer_context
->distribute
)
10958 ctx
= ctx
->outer_context
->outer_context
;
10959 ctx
= ctx
->outer_context
;
10962 && lookup_attribute ("omp declare simd",
10963 DECL_ATTRIBUTES (current_function_decl
)))
10965 /* Declare simd is a maybe case, it is supposed to be added only to the
10966 omp-simd-clone.c added clones and not to the base function. */
10967 declare_simd_cnt
= cnt
++;
10969 codes
.safe_push (OMP_SIMD
);
10971 && constructs
[0] == OMP_SIMD
)
10973 gcc_assert (matched
== 0);
10975 if (++matched
== nconstructs
)
10979 if (tree attr
= lookup_attribute ("omp declare variant variant",
10980 DECL_ATTRIBUTES (current_function_decl
)))
10982 enum tree_code variant_constructs
[5];
10983 int variant_nconstructs
= 0;
10985 variant_nconstructs
10986 = omp_constructor_traits_to_codes (TREE_VALUE (attr
),
10987 variant_constructs
);
10988 for (int i
= 0; i
< variant_nconstructs
; i
++)
10992 codes
.safe_push (variant_constructs
[i
]);
10993 else if (matched
< nconstructs
10994 && variant_constructs
[i
] == constructs
[matched
])
10996 if (variant_constructs
[i
] == OMP_SIMD
)
11007 && lookup_attribute ("omp declare target block",
11008 DECL_ATTRIBUTES (current_function_decl
)))
11011 codes
.safe_push (OMP_TARGET
);
11012 else if (matched
< nconstructs
&& constructs
[matched
] == OMP_TARGET
)
11017 for (int pass
= 0; pass
< (declare_simd_cnt
== -1 ? 1 : 2); pass
++)
11019 int j
= codes
.length () - 1;
11020 for (int i
= nconstructs
- 1; i
>= 0; i
--)
11023 && (pass
!= 0 || declare_simd_cnt
!= j
)
11024 && constructs
[i
] != codes
[j
])
11026 if (pass
== 0 && declare_simd_cnt
!= -1 && j
> declare_simd_cnt
)
11031 *scores
++ = ((pass
== 0 && declare_simd_cnt
!= -1)
11032 ? codes
.length () - 1 : codes
.length ());
11034 return declare_simd_cnt
== -1 ? 1 : 2;
11036 if (matched
== nconstructs
)
11037 return simd_seen
? -1 : 1;
11041 /* Gimplify OACC_CACHE. */
11044 gimplify_oacc_cache (tree
*expr_p
, gimple_seq
*pre_p
)
11046 tree expr
= *expr_p
;
11048 gimplify_scan_omp_clauses (&OACC_CACHE_CLAUSES (expr
), pre_p
, ORT_ACC
,
11050 gimplify_adjust_omp_clauses (pre_p
, NULL
, &OACC_CACHE_CLAUSES (expr
),
11053 /* TODO: Do something sensible with this information. */
11055 *expr_p
= NULL_TREE
;
11058 /* Helper function of gimplify_oacc_declare. The helper's purpose is to,
11059 if required, translate 'kind' in CLAUSE into an 'entry' kind and 'exit'
11060 kind. The entry kind will replace the one in CLAUSE, while the exit
11061 kind will be used in a new omp_clause and returned to the caller. */
11064 gimplify_oacc_declare_1 (tree clause
)
11066 HOST_WIDE_INT kind
, new_op
;
11070 kind
= OMP_CLAUSE_MAP_KIND (clause
);
11074 case GOMP_MAP_ALLOC
:
11075 new_op
= GOMP_MAP_RELEASE
;
11079 case GOMP_MAP_FROM
:
11080 OMP_CLAUSE_SET_MAP_KIND (clause
, GOMP_MAP_FORCE_ALLOC
);
11081 new_op
= GOMP_MAP_FROM
;
11085 case GOMP_MAP_TOFROM
:
11086 OMP_CLAUSE_SET_MAP_KIND (clause
, GOMP_MAP_TO
);
11087 new_op
= GOMP_MAP_FROM
;
11091 case GOMP_MAP_DEVICE_RESIDENT
:
11092 case GOMP_MAP_FORCE_DEVICEPTR
:
11093 case GOMP_MAP_FORCE_PRESENT
:
11094 case GOMP_MAP_LINK
:
11095 case GOMP_MAP_POINTER
:
11100 gcc_unreachable ();
11106 c
= build_omp_clause (OMP_CLAUSE_LOCATION (clause
), OMP_CLAUSE_MAP
);
11107 OMP_CLAUSE_SET_MAP_KIND (c
, new_op
);
11108 OMP_CLAUSE_DECL (c
) = OMP_CLAUSE_DECL (clause
);
11114 /* Gimplify OACC_DECLARE. */
11117 gimplify_oacc_declare (tree
*expr_p
, gimple_seq
*pre_p
)
11119 tree expr
= *expr_p
;
11121 tree clauses
, t
, decl
;
11123 clauses
= OACC_DECLARE_CLAUSES (expr
);
11125 gimplify_scan_omp_clauses (&clauses
, pre_p
, ORT_TARGET_DATA
, OACC_DECLARE
);
11126 gimplify_adjust_omp_clauses (pre_p
, NULL
, &clauses
, OACC_DECLARE
);
11128 for (t
= clauses
; t
; t
= OMP_CLAUSE_CHAIN (t
))
11130 decl
= OMP_CLAUSE_DECL (t
);
11132 if (TREE_CODE (decl
) == MEM_REF
)
11133 decl
= TREE_OPERAND (decl
, 0);
11135 if (VAR_P (decl
) && !is_oacc_declared (decl
))
11137 tree attr
= get_identifier ("oacc declare target");
11138 DECL_ATTRIBUTES (decl
) = tree_cons (attr
, NULL_TREE
,
11139 DECL_ATTRIBUTES (decl
));
11143 && !is_global_var (decl
)
11144 && DECL_CONTEXT (decl
) == current_function_decl
)
11146 tree c
= gimplify_oacc_declare_1 (t
);
11149 if (oacc_declare_returns
== NULL
)
11150 oacc_declare_returns
= new hash_map
<tree
, tree
>;
11152 oacc_declare_returns
->put (decl
, c
);
11156 if (gimplify_omp_ctxp
)
11157 omp_add_variable (gimplify_omp_ctxp
, decl
, GOVD_SEEN
);
11160 stmt
= gimple_build_omp_target (NULL
, GF_OMP_TARGET_KIND_OACC_DECLARE
,
11163 gimplify_seq_add_stmt (pre_p
, stmt
);
11165 *expr_p
= NULL_TREE
;
11168 /* Gimplify the contents of an OMP_PARALLEL statement. This involves
11169 gimplification of the body, as well as scanning the body for used
11170 variables. We need to do this scan now, because variable-sized
11171 decls will be decomposed during gimplification. */
11174 gimplify_omp_parallel (tree
*expr_p
, gimple_seq
*pre_p
)
11176 tree expr
= *expr_p
;
11178 gimple_seq body
= NULL
;
11180 gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr
), pre_p
,
11181 OMP_PARALLEL_COMBINED (expr
)
11182 ? ORT_COMBINED_PARALLEL
11183 : ORT_PARALLEL
, OMP_PARALLEL
);
11185 push_gimplify_context ();
11187 g
= gimplify_and_return_first (OMP_PARALLEL_BODY (expr
), &body
);
11188 if (gimple_code (g
) == GIMPLE_BIND
)
11189 pop_gimplify_context (g
);
11191 pop_gimplify_context (NULL
);
11193 gimplify_adjust_omp_clauses (pre_p
, body
, &OMP_PARALLEL_CLAUSES (expr
),
11196 g
= gimple_build_omp_parallel (body
,
11197 OMP_PARALLEL_CLAUSES (expr
),
11198 NULL_TREE
, NULL_TREE
);
11199 if (OMP_PARALLEL_COMBINED (expr
))
11200 gimple_omp_set_subcode (g
, GF_OMP_PARALLEL_COMBINED
);
11201 gimplify_seq_add_stmt (pre_p
, g
);
11202 *expr_p
= NULL_TREE
;
11205 /* Gimplify the contents of an OMP_TASK statement. This involves
11206 gimplification of the body, as well as scanning the body for used
11207 variables. We need to do this scan now, because variable-sized
11208 decls will be decomposed during gimplification. */
11211 gimplify_omp_task (tree
*expr_p
, gimple_seq
*pre_p
)
11213 tree expr
= *expr_p
;
11215 gimple_seq body
= NULL
;
11217 if (OMP_TASK_BODY (expr
) == NULL_TREE
)
11218 for (tree c
= OMP_TASK_CLAUSES (expr
); c
; c
= OMP_CLAUSE_CHAIN (c
))
11219 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEPEND
11220 && OMP_CLAUSE_DEPEND_KIND (c
) == OMP_CLAUSE_DEPEND_MUTEXINOUTSET
)
11222 error_at (OMP_CLAUSE_LOCATION (c
),
11223 "%<mutexinoutset%> kind in %<depend%> clause on a "
11224 "%<taskwait%> construct");
11228 gimplify_scan_omp_clauses (&OMP_TASK_CLAUSES (expr
), pre_p
,
11229 omp_find_clause (OMP_TASK_CLAUSES (expr
),
11231 ? ORT_UNTIED_TASK
: ORT_TASK
, OMP_TASK
);
11233 if (OMP_TASK_BODY (expr
))
11235 push_gimplify_context ();
11237 g
= gimplify_and_return_first (OMP_TASK_BODY (expr
), &body
);
11238 if (gimple_code (g
) == GIMPLE_BIND
)
11239 pop_gimplify_context (g
);
11241 pop_gimplify_context (NULL
);
11244 gimplify_adjust_omp_clauses (pre_p
, body
, &OMP_TASK_CLAUSES (expr
),
11247 g
= gimple_build_omp_task (body
,
11248 OMP_TASK_CLAUSES (expr
),
11249 NULL_TREE
, NULL_TREE
,
11250 NULL_TREE
, NULL_TREE
, NULL_TREE
);
11251 if (OMP_TASK_BODY (expr
) == NULL_TREE
)
11252 gimple_omp_task_set_taskwait_p (g
, true);
11253 gimplify_seq_add_stmt (pre_p
, g
);
11254 *expr_p
= NULL_TREE
;
11257 /* Helper function for gimplify_omp_for. If *TP is not a gimple constant,
11258 force it into a temporary initialized in PRE_P and add firstprivate clause
11259 to ORIG_FOR_STMT. */
11262 gimplify_omp_taskloop_expr (tree type
, tree
*tp
, gimple_seq
*pre_p
,
11263 tree orig_for_stmt
)
11265 if (*tp
== NULL
|| is_gimple_constant (*tp
))
11268 *tp
= get_initialized_tmp_var (*tp
, pre_p
, NULL
, false);
11269 /* Reference to pointer conversion is considered useless,
11270 but is significant for firstprivate clause. Force it
11273 && TREE_CODE (type
) == POINTER_TYPE
11274 && TREE_CODE (TREE_TYPE (*tp
)) == REFERENCE_TYPE
)
11276 tree v
= create_tmp_var (TYPE_MAIN_VARIANT (type
));
11277 tree m
= build2 (INIT_EXPR
, TREE_TYPE (v
), v
, *tp
);
11278 gimplify_and_add (m
, pre_p
);
11282 tree c
= build_omp_clause (input_location
, OMP_CLAUSE_FIRSTPRIVATE
);
11283 OMP_CLAUSE_DECL (c
) = *tp
;
11284 OMP_CLAUSE_CHAIN (c
) = OMP_FOR_CLAUSES (orig_for_stmt
);
11285 OMP_FOR_CLAUSES (orig_for_stmt
) = c
;
11288 /* Gimplify the gross structure of an OMP_FOR statement. */
11290 static enum gimplify_status
11291 gimplify_omp_for (tree
*expr_p
, gimple_seq
*pre_p
)
11293 tree for_stmt
, orig_for_stmt
, inner_for_stmt
= NULL_TREE
, decl
, var
, t
;
11294 enum gimplify_status ret
= GS_ALL_DONE
;
11295 enum gimplify_status tret
;
11297 gimple_seq for_body
, for_pre_body
;
11299 bitmap has_decl_expr
= NULL
;
11300 enum omp_region_type ort
= ORT_WORKSHARE
;
11301 bool openacc
= TREE_CODE (*expr_p
) == OACC_LOOP
;
11303 orig_for_stmt
= for_stmt
= *expr_p
;
11305 bool loop_p
= (omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_BIND
)
11307 if (OMP_FOR_INIT (for_stmt
) == NULL_TREE
)
11309 tree
*data
[4] = { NULL
, NULL
, NULL
, NULL
};
11310 gcc_assert (TREE_CODE (for_stmt
) != OACC_LOOP
);
11311 inner_for_stmt
= walk_tree (&OMP_FOR_BODY (for_stmt
),
11312 find_combined_omp_for
, data
, NULL
);
11313 if (inner_for_stmt
== NULL_TREE
)
11315 gcc_assert (seen_error ());
11316 *expr_p
= NULL_TREE
;
11319 if (data
[2] && OMP_FOR_PRE_BODY (*data
[2]))
11321 append_to_statement_list_force (OMP_FOR_PRE_BODY (*data
[2]),
11322 &OMP_FOR_PRE_BODY (for_stmt
));
11323 OMP_FOR_PRE_BODY (*data
[2]) = NULL_TREE
;
11325 if (OMP_FOR_PRE_BODY (inner_for_stmt
))
11327 append_to_statement_list_force (OMP_FOR_PRE_BODY (inner_for_stmt
),
11328 &OMP_FOR_PRE_BODY (for_stmt
));
11329 OMP_FOR_PRE_BODY (inner_for_stmt
) = NULL_TREE
;
11334 /* We have some statements or variable declarations in between
11335 the composite construct directives. Move them around the
11338 for (i
= 0; i
< 3; i
++)
11342 if (i
< 2 && data
[i
+ 1] == &OMP_BODY (t
))
11343 data
[i
+ 1] = data
[i
];
11344 *data
[i
] = OMP_BODY (t
);
11345 tree body
= build3 (BIND_EXPR
, void_type_node
, NULL_TREE
,
11346 NULL_TREE
, make_node (BLOCK
));
11347 OMP_BODY (t
) = body
;
11348 append_to_statement_list_force (inner_for_stmt
,
11349 &BIND_EXPR_BODY (body
));
11351 data
[3] = tsi_stmt_ptr (tsi_start (BIND_EXPR_BODY (body
)));
11352 gcc_assert (*data
[3] == inner_for_stmt
);
11357 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt
)); i
++)
11359 && OMP_FOR_ORIG_DECLS (inner_for_stmt
)
11360 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
),
11362 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
),
11365 tree orig
= TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
), i
);
11366 /* Class iterators aren't allowed on OMP_SIMD, so the only
11367 case we need to solve is distribute parallel for. They are
11368 allowed on the loop construct, but that is already handled
11369 in gimplify_omp_loop. */
11370 gcc_assert (TREE_CODE (inner_for_stmt
) == OMP_FOR
11371 && TREE_CODE (for_stmt
) == OMP_DISTRIBUTE
11373 tree orig_decl
= TREE_PURPOSE (orig
);
11374 tree last
= TREE_VALUE (orig
);
11376 for (pc
= &OMP_FOR_CLAUSES (inner_for_stmt
);
11377 *pc
; pc
= &OMP_CLAUSE_CHAIN (*pc
))
11378 if ((OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_PRIVATE
11379 || OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_LASTPRIVATE
)
11380 && OMP_CLAUSE_DECL (*pc
) == orig_decl
)
11382 if (*pc
== NULL_TREE
)
11385 for (spc
= &OMP_PARALLEL_CLAUSES (*data
[1]);
11386 *spc
; spc
= &OMP_CLAUSE_CHAIN (*spc
))
11387 if (OMP_CLAUSE_CODE (*spc
) == OMP_CLAUSE_PRIVATE
11388 && OMP_CLAUSE_DECL (*spc
) == orig_decl
)
11393 *spc
= OMP_CLAUSE_CHAIN (c
);
11394 OMP_CLAUSE_CHAIN (c
) = NULL_TREE
;
11398 if (*pc
== NULL_TREE
)
11400 else if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_PRIVATE
)
11402 /* private clause will appear only on inner_for_stmt.
11403 Change it into firstprivate, and add private clause
11405 tree c
= copy_node (*pc
);
11406 OMP_CLAUSE_CHAIN (c
) = OMP_FOR_CLAUSES (for_stmt
);
11407 OMP_FOR_CLAUSES (for_stmt
) = c
;
11408 OMP_CLAUSE_CODE (*pc
) = OMP_CLAUSE_FIRSTPRIVATE
;
11409 lang_hooks
.decls
.omp_finish_clause (*pc
, pre_p
, openacc
);
11413 /* lastprivate clause will appear on both inner_for_stmt
11414 and for_stmt. Add firstprivate clause to
11416 tree c
= build_omp_clause (OMP_CLAUSE_LOCATION (*pc
),
11417 OMP_CLAUSE_FIRSTPRIVATE
);
11418 OMP_CLAUSE_DECL (c
) = OMP_CLAUSE_DECL (*pc
);
11419 OMP_CLAUSE_CHAIN (c
) = *pc
;
11421 lang_hooks
.decls
.omp_finish_clause (*pc
, pre_p
, openacc
);
11423 tree c
= build_omp_clause (UNKNOWN_LOCATION
,
11424 OMP_CLAUSE_FIRSTPRIVATE
);
11425 OMP_CLAUSE_DECL (c
) = last
;
11426 OMP_CLAUSE_CHAIN (c
) = OMP_PARALLEL_CLAUSES (*data
[1]);
11427 OMP_PARALLEL_CLAUSES (*data
[1]) = c
;
11428 c
= build_omp_clause (UNKNOWN_LOCATION
,
11429 *pc
? OMP_CLAUSE_SHARED
11430 : OMP_CLAUSE_FIRSTPRIVATE
);
11431 OMP_CLAUSE_DECL (c
) = orig_decl
;
11432 OMP_CLAUSE_CHAIN (c
) = OMP_PARALLEL_CLAUSES (*data
[1]);
11433 OMP_PARALLEL_CLAUSES (*data
[1]) = c
;
11435 /* Similarly, take care of C++ range for temporaries, those should
11436 be firstprivate on OMP_PARALLEL if any. */
11438 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt
)); i
++)
11439 if (OMP_FOR_ORIG_DECLS (inner_for_stmt
)
11440 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
),
11442 && TREE_CHAIN (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
),
11446 = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
), i
);
11447 tree v
= TREE_CHAIN (orig
);
11448 tree c
= build_omp_clause (UNKNOWN_LOCATION
,
11449 OMP_CLAUSE_FIRSTPRIVATE
);
11450 /* First add firstprivate clause for the __for_end artificial
11452 OMP_CLAUSE_DECL (c
) = TREE_VEC_ELT (v
, 1);
11453 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c
)))
11455 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c
) = 1;
11456 OMP_CLAUSE_CHAIN (c
) = OMP_PARALLEL_CLAUSES (*data
[1]);
11457 OMP_PARALLEL_CLAUSES (*data
[1]) = c
;
11458 if (TREE_VEC_ELT (v
, 0))
11460 /* And now the same for __for_range artificial decl if it
11462 c
= build_omp_clause (UNKNOWN_LOCATION
,
11463 OMP_CLAUSE_FIRSTPRIVATE
);
11464 OMP_CLAUSE_DECL (c
) = TREE_VEC_ELT (v
, 0);
11465 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c
)))
11467 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c
) = 1;
11468 OMP_CLAUSE_CHAIN (c
) = OMP_PARALLEL_CLAUSES (*data
[1]);
11469 OMP_PARALLEL_CLAUSES (*data
[1]) = c
;
11474 switch (TREE_CODE (for_stmt
))
11477 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt
? inner_for_stmt
: for_stmt
))
11479 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt
),
11480 OMP_CLAUSE_SCHEDULE
))
11481 error_at (EXPR_LOCATION (for_stmt
),
11482 "%qs clause may not appear on non-rectangular %qs",
11483 "schedule", "for");
11484 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_ORDERED
))
11485 error_at (EXPR_LOCATION (for_stmt
),
11486 "%qs clause may not appear on non-rectangular %qs",
11490 case OMP_DISTRIBUTE
:
11491 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt
? inner_for_stmt
: for_stmt
)
11492 && omp_find_clause (OMP_FOR_CLAUSES (for_stmt
),
11493 OMP_CLAUSE_DIST_SCHEDULE
))
11494 error_at (EXPR_LOCATION (for_stmt
),
11495 "%qs clause may not appear on non-rectangular %qs",
11496 "dist_schedule", "distribute");
11502 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_UNTIED
))
11503 ort
= ORT_UNTIED_TASKLOOP
;
11505 ort
= ORT_TASKLOOP
;
11511 gcc_unreachable ();
11514 /* Set OMP_CLAUSE_LINEAR_NO_COPYIN flag on explicit linear
11515 clause for the IV. */
11516 if (ort
== ORT_SIMD
&& TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)) == 1)
11518 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), 0);
11519 gcc_assert (TREE_CODE (t
) == MODIFY_EXPR
);
11520 decl
= TREE_OPERAND (t
, 0);
11521 for (tree c
= OMP_FOR_CLAUSES (for_stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
11522 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINEAR
11523 && OMP_CLAUSE_DECL (c
) == decl
)
11525 OMP_CLAUSE_LINEAR_NO_COPYIN (c
) = 1;
11530 if (TREE_CODE (for_stmt
) != OMP_TASKLOOP
)
11531 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt
), pre_p
, ort
,
11532 loop_p
&& TREE_CODE (for_stmt
) != OMP_SIMD
11533 ? OMP_LOOP
: TREE_CODE (for_stmt
));
11535 if (TREE_CODE (for_stmt
) == OMP_DISTRIBUTE
)
11536 gimplify_omp_ctxp
->distribute
= true;
11538 /* Handle OMP_FOR_INIT. */
11539 for_pre_body
= NULL
;
11540 if ((ort
== ORT_SIMD
11541 || (inner_for_stmt
&& TREE_CODE (inner_for_stmt
) == OMP_SIMD
))
11542 && OMP_FOR_PRE_BODY (for_stmt
))
11544 has_decl_expr
= BITMAP_ALLOC (NULL
);
11545 if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt
)) == DECL_EXPR
11546 && TREE_CODE (DECL_EXPR_DECL (OMP_FOR_PRE_BODY (for_stmt
)))
11549 t
= OMP_FOR_PRE_BODY (for_stmt
);
11550 bitmap_set_bit (has_decl_expr
, DECL_UID (DECL_EXPR_DECL (t
)));
11552 else if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt
)) == STATEMENT_LIST
)
11554 tree_stmt_iterator si
;
11555 for (si
= tsi_start (OMP_FOR_PRE_BODY (for_stmt
)); !tsi_end_p (si
);
11559 if (TREE_CODE (t
) == DECL_EXPR
11560 && TREE_CODE (DECL_EXPR_DECL (t
)) == VAR_DECL
)
11561 bitmap_set_bit (has_decl_expr
, DECL_UID (DECL_EXPR_DECL (t
)));
11565 if (OMP_FOR_PRE_BODY (for_stmt
))
11567 if (TREE_CODE (for_stmt
) != OMP_TASKLOOP
|| gimplify_omp_ctxp
)
11568 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt
), &for_pre_body
);
11571 struct gimplify_omp_ctx ctx
;
11572 memset (&ctx
, 0, sizeof (ctx
));
11573 ctx
.region_type
= ORT_NONE
;
11574 gimplify_omp_ctxp
= &ctx
;
11575 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt
), &for_pre_body
);
11576 gimplify_omp_ctxp
= NULL
;
11579 OMP_FOR_PRE_BODY (for_stmt
) = NULL_TREE
;
11581 if (OMP_FOR_INIT (for_stmt
) == NULL_TREE
)
11582 for_stmt
= inner_for_stmt
;
11584 /* For taskloop, need to gimplify the start, end and step before the
11585 taskloop, outside of the taskloop omp context. */
11586 if (TREE_CODE (orig_for_stmt
) == OMP_TASKLOOP
)
11588 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
11590 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), i
);
11591 gimple_seq
*for_pre_p
= (gimple_seq_empty_p (for_pre_body
)
11592 ? pre_p
: &for_pre_body
);
11593 tree type
= TREE_TYPE (TREE_OPERAND (t
, 0));
11594 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
)
11596 tree v
= TREE_OPERAND (t
, 1);
11597 gimplify_omp_taskloop_expr (type
, &TREE_VEC_ELT (v
, 1),
11598 for_pre_p
, orig_for_stmt
);
11599 gimplify_omp_taskloop_expr (type
, &TREE_VEC_ELT (v
, 2),
11600 for_pre_p
, orig_for_stmt
);
11603 gimplify_omp_taskloop_expr (type
, &TREE_OPERAND (t
, 1), for_pre_p
,
11606 /* Handle OMP_FOR_COND. */
11607 t
= TREE_VEC_ELT (OMP_FOR_COND (for_stmt
), i
);
11608 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
)
11610 tree v
= TREE_OPERAND (t
, 1);
11611 gimplify_omp_taskloop_expr (type
, &TREE_VEC_ELT (v
, 1),
11612 for_pre_p
, orig_for_stmt
);
11613 gimplify_omp_taskloop_expr (type
, &TREE_VEC_ELT (v
, 2),
11614 for_pre_p
, orig_for_stmt
);
11617 gimplify_omp_taskloop_expr (type
, &TREE_OPERAND (t
, 1), for_pre_p
,
11620 /* Handle OMP_FOR_INCR. */
11621 t
= TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
);
11622 if (TREE_CODE (t
) == MODIFY_EXPR
)
11624 decl
= TREE_OPERAND (t
, 0);
11625 t
= TREE_OPERAND (t
, 1);
11626 tree
*tp
= &TREE_OPERAND (t
, 1);
11627 if (TREE_CODE (t
) == PLUS_EXPR
&& *tp
== decl
)
11628 tp
= &TREE_OPERAND (t
, 0);
11630 gimplify_omp_taskloop_expr (NULL_TREE
, tp
, for_pre_p
,
11635 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (orig_for_stmt
), pre_p
, ort
,
11639 if (orig_for_stmt
!= for_stmt
)
11640 gimplify_omp_ctxp
->combined_loop
= true;
11643 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
))
11644 == TREE_VEC_LENGTH (OMP_FOR_COND (for_stmt
)));
11645 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
))
11646 == TREE_VEC_LENGTH (OMP_FOR_INCR (for_stmt
)));
11648 tree c
= omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_ORDERED
);
11649 bool is_doacross
= false;
11650 if (c
&& OMP_CLAUSE_ORDERED_EXPR (c
))
11652 is_doacross
= true;
11653 gimplify_omp_ctxp
->loop_iter_var
.create (TREE_VEC_LENGTH
11654 (OMP_FOR_INIT (for_stmt
))
11657 int collapse
= 1, tile
= 0;
11658 c
= omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_COLLAPSE
);
11660 collapse
= tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (c
));
11661 c
= omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_TILE
);
11663 tile
= list_length (OMP_CLAUSE_TILE_LIST (c
));
11664 c
= omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_ALLOCATE
);
11665 hash_set
<tree
> *allocate_uids
= NULL
;
11668 allocate_uids
= new hash_set
<tree
>;
11669 for (; c
; c
= OMP_CLAUSE_CHAIN (c
))
11670 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_ALLOCATE
)
11671 allocate_uids
->add (OMP_CLAUSE_DECL (c
));
11673 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
11675 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), i
);
11676 gcc_assert (TREE_CODE (t
) == MODIFY_EXPR
);
11677 decl
= TREE_OPERAND (t
, 0);
11678 gcc_assert (DECL_P (decl
));
11679 gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl
))
11680 || POINTER_TYPE_P (TREE_TYPE (decl
)));
11683 if (TREE_CODE (for_stmt
) == OMP_FOR
&& OMP_FOR_ORIG_DECLS (for_stmt
))
11685 tree orig_decl
= TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
), i
);
11686 if (TREE_CODE (orig_decl
) == TREE_LIST
)
11688 orig_decl
= TREE_PURPOSE (orig_decl
);
11692 gimplify_omp_ctxp
->loop_iter_var
.quick_push (orig_decl
);
11695 gimplify_omp_ctxp
->loop_iter_var
.quick_push (decl
);
11696 gimplify_omp_ctxp
->loop_iter_var
.quick_push (decl
);
11699 /* Make sure the iteration variable is private. */
11700 tree c
= NULL_TREE
;
11701 tree c2
= NULL_TREE
;
11702 if (orig_for_stmt
!= for_stmt
)
11704 /* Preserve this information until we gimplify the inner simd. */
11706 && bitmap_bit_p (has_decl_expr
, DECL_UID (decl
)))
11707 TREE_PRIVATE (t
) = 1;
11709 else if (ort
== ORT_SIMD
)
11711 splay_tree_node n
= splay_tree_lookup (gimplify_omp_ctxp
->variables
,
11712 (splay_tree_key
) decl
);
11713 omp_is_private (gimplify_omp_ctxp
, decl
,
11714 1 + (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
))
11716 if (n
!= NULL
&& (n
->value
& GOVD_DATA_SHARE_CLASS
) != 0)
11718 omp_notice_variable (gimplify_omp_ctxp
, decl
, true);
11719 if (n
->value
& GOVD_LASTPRIVATE_CONDITIONAL
)
11720 for (tree c3
= omp_find_clause (OMP_FOR_CLAUSES (for_stmt
),
11721 OMP_CLAUSE_LASTPRIVATE
);
11722 c3
; c3
= omp_find_clause (OMP_CLAUSE_CHAIN (c3
),
11723 OMP_CLAUSE_LASTPRIVATE
))
11724 if (OMP_CLAUSE_DECL (c3
) == decl
)
11726 warning_at (OMP_CLAUSE_LOCATION (c3
), 0,
11727 "conditional %<lastprivate%> on loop "
11728 "iterator %qD ignored", decl
);
11729 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3
) = 0;
11730 n
->value
&= ~GOVD_LASTPRIVATE_CONDITIONAL
;
11733 else if (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)) == 1 && !loop_p
)
11735 c
= build_omp_clause (input_location
, OMP_CLAUSE_LINEAR
);
11736 OMP_CLAUSE_LINEAR_NO_COPYIN (c
) = 1;
11737 unsigned int flags
= GOVD_LINEAR
| GOVD_EXPLICIT
| GOVD_SEEN
;
11739 && bitmap_bit_p (has_decl_expr
, DECL_UID (decl
)))
11740 || TREE_PRIVATE (t
))
11742 OMP_CLAUSE_LINEAR_NO_COPYOUT (c
) = 1;
11743 flags
|= GOVD_LINEAR_LASTPRIVATE_NO_OUTER
;
11745 struct gimplify_omp_ctx
*outer
11746 = gimplify_omp_ctxp
->outer_context
;
11747 if (outer
&& !OMP_CLAUSE_LINEAR_NO_COPYOUT (c
))
11749 if (outer
->region_type
== ORT_WORKSHARE
11750 && outer
->combined_loop
)
11752 n
= splay_tree_lookup (outer
->variables
,
11753 (splay_tree_key
)decl
);
11754 if (n
!= NULL
&& (n
->value
& GOVD_LOCAL
) != 0)
11756 OMP_CLAUSE_LINEAR_NO_COPYOUT (c
) = 1;
11757 flags
|= GOVD_LINEAR_LASTPRIVATE_NO_OUTER
;
11761 struct gimplify_omp_ctx
*octx
= outer
->outer_context
;
11763 && octx
->region_type
== ORT_COMBINED_PARALLEL
11764 && octx
->outer_context
11765 && (octx
->outer_context
->region_type
11767 && octx
->outer_context
->combined_loop
)
11769 octx
= octx
->outer_context
;
11770 n
= splay_tree_lookup (octx
->variables
,
11771 (splay_tree_key
)decl
);
11772 if (n
!= NULL
&& (n
->value
& GOVD_LOCAL
) != 0)
11774 OMP_CLAUSE_LINEAR_NO_COPYOUT (c
) = 1;
11775 flags
|= GOVD_LINEAR_LASTPRIVATE_NO_OUTER
;
11782 OMP_CLAUSE_DECL (c
) = decl
;
11783 OMP_CLAUSE_CHAIN (c
) = OMP_FOR_CLAUSES (for_stmt
);
11784 OMP_FOR_CLAUSES (for_stmt
) = c
;
11785 omp_add_variable (gimplify_omp_ctxp
, decl
, flags
);
11786 if (outer
&& !OMP_CLAUSE_LINEAR_NO_COPYOUT (c
))
11788 if (outer
->region_type
== ORT_WORKSHARE
11789 && outer
->combined_loop
)
11791 if (outer
->outer_context
11792 && (outer
->outer_context
->region_type
11793 == ORT_COMBINED_PARALLEL
))
11794 outer
= outer
->outer_context
;
11795 else if (omp_check_private (outer
, decl
, false))
11798 else if (((outer
->region_type
& ORT_TASKLOOP
)
11800 && outer
->combined_loop
11801 && !omp_check_private (gimplify_omp_ctxp
,
11804 else if (outer
->region_type
!= ORT_COMBINED_PARALLEL
)
11806 omp_notice_variable (outer
, decl
, true);
11811 n
= splay_tree_lookup (outer
->variables
,
11812 (splay_tree_key
)decl
);
11813 if (n
== NULL
|| (n
->value
& GOVD_DATA_SHARE_CLASS
) == 0)
11815 omp_add_variable (outer
, decl
,
11816 GOVD_LASTPRIVATE
| GOVD_SEEN
);
11817 if (outer
->region_type
== ORT_COMBINED_PARALLEL
11818 && outer
->outer_context
11819 && (outer
->outer_context
->region_type
11821 && outer
->outer_context
->combined_loop
)
11823 outer
= outer
->outer_context
;
11824 n
= splay_tree_lookup (outer
->variables
,
11825 (splay_tree_key
)decl
);
11826 if (omp_check_private (outer
, decl
, false))
11829 || ((n
->value
& GOVD_DATA_SHARE_CLASS
)
11831 omp_add_variable (outer
, decl
,
11837 if (outer
&& outer
->outer_context
11838 && ((outer
->outer_context
->region_type
11839 & ORT_COMBINED_TEAMS
) == ORT_COMBINED_TEAMS
11840 || (((outer
->region_type
& ORT_TASKLOOP
)
11842 && (outer
->outer_context
->region_type
11843 == ORT_COMBINED_PARALLEL
))))
11845 outer
= outer
->outer_context
;
11846 n
= splay_tree_lookup (outer
->variables
,
11847 (splay_tree_key
)decl
);
11849 || (n
->value
& GOVD_DATA_SHARE_CLASS
) == 0)
11850 omp_add_variable (outer
, decl
,
11851 GOVD_SHARED
| GOVD_SEEN
);
11855 if (outer
&& outer
->outer_context
)
11856 omp_notice_variable (outer
->outer_context
, decl
,
11866 || !bitmap_bit_p (has_decl_expr
, DECL_UID (decl
)));
11867 if (TREE_PRIVATE (t
))
11868 lastprivate
= false;
11869 if (loop_p
&& OMP_FOR_ORIG_DECLS (for_stmt
))
11871 tree elt
= TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
), i
);
11872 if (TREE_CODE (elt
) == TREE_LIST
&& TREE_PURPOSE (elt
))
11873 lastprivate
= false;
11876 struct gimplify_omp_ctx
*outer
11877 = gimplify_omp_ctxp
->outer_context
;
11878 if (outer
&& lastprivate
)
11880 if (outer
->region_type
== ORT_WORKSHARE
11881 && outer
->combined_loop
)
11883 n
= splay_tree_lookup (outer
->variables
,
11884 (splay_tree_key
)decl
);
11885 if (n
!= NULL
&& (n
->value
& GOVD_LOCAL
) != 0)
11887 lastprivate
= false;
11890 else if (outer
->outer_context
11891 && (outer
->outer_context
->region_type
11892 == ORT_COMBINED_PARALLEL
))
11893 outer
= outer
->outer_context
;
11894 else if (omp_check_private (outer
, decl
, false))
11897 else if (((outer
->region_type
& ORT_TASKLOOP
)
11899 && outer
->combined_loop
11900 && !omp_check_private (gimplify_omp_ctxp
,
11903 else if (outer
->region_type
!= ORT_COMBINED_PARALLEL
)
11905 omp_notice_variable (outer
, decl
, true);
11910 n
= splay_tree_lookup (outer
->variables
,
11911 (splay_tree_key
)decl
);
11912 if (n
== NULL
|| (n
->value
& GOVD_DATA_SHARE_CLASS
) == 0)
11914 omp_add_variable (outer
, decl
,
11915 GOVD_LASTPRIVATE
| GOVD_SEEN
);
11916 if (outer
->region_type
== ORT_COMBINED_PARALLEL
11917 && outer
->outer_context
11918 && (outer
->outer_context
->region_type
11920 && outer
->outer_context
->combined_loop
)
11922 outer
= outer
->outer_context
;
11923 n
= splay_tree_lookup (outer
->variables
,
11924 (splay_tree_key
)decl
);
11925 if (omp_check_private (outer
, decl
, false))
11928 || ((n
->value
& GOVD_DATA_SHARE_CLASS
)
11930 omp_add_variable (outer
, decl
,
11936 if (outer
&& outer
->outer_context
11937 && ((outer
->outer_context
->region_type
11938 & ORT_COMBINED_TEAMS
) == ORT_COMBINED_TEAMS
11939 || (((outer
->region_type
& ORT_TASKLOOP
)
11941 && (outer
->outer_context
->region_type
11942 == ORT_COMBINED_PARALLEL
))))
11944 outer
= outer
->outer_context
;
11945 n
= splay_tree_lookup (outer
->variables
,
11946 (splay_tree_key
)decl
);
11948 || (n
->value
& GOVD_DATA_SHARE_CLASS
) == 0)
11949 omp_add_variable (outer
, decl
,
11950 GOVD_SHARED
| GOVD_SEEN
);
11954 if (outer
&& outer
->outer_context
)
11955 omp_notice_variable (outer
->outer_context
, decl
,
11961 c
= build_omp_clause (input_location
,
11962 lastprivate
? OMP_CLAUSE_LASTPRIVATE
11963 : OMP_CLAUSE_PRIVATE
);
11964 OMP_CLAUSE_DECL (c
) = decl
;
11965 OMP_CLAUSE_CHAIN (c
) = OMP_FOR_CLAUSES (for_stmt
);
11966 OMP_FOR_CLAUSES (for_stmt
) = c
;
11967 omp_add_variable (gimplify_omp_ctxp
, decl
,
11968 (lastprivate
? GOVD_LASTPRIVATE
: GOVD_PRIVATE
)
11969 | GOVD_EXPLICIT
| GOVD_SEEN
);
11973 else if (omp_is_private (gimplify_omp_ctxp
, decl
, 0))
11975 omp_notice_variable (gimplify_omp_ctxp
, decl
, true);
11976 splay_tree_node n
= splay_tree_lookup (gimplify_omp_ctxp
->variables
,
11977 (splay_tree_key
) decl
);
11978 if (n
&& (n
->value
& GOVD_LASTPRIVATE_CONDITIONAL
))
11979 for (tree c3
= omp_find_clause (OMP_FOR_CLAUSES (for_stmt
),
11980 OMP_CLAUSE_LASTPRIVATE
);
11981 c3
; c3
= omp_find_clause (OMP_CLAUSE_CHAIN (c3
),
11982 OMP_CLAUSE_LASTPRIVATE
))
11983 if (OMP_CLAUSE_DECL (c3
) == decl
)
11985 warning_at (OMP_CLAUSE_LOCATION (c3
), 0,
11986 "conditional %<lastprivate%> on loop "
11987 "iterator %qD ignored", decl
);
11988 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3
) = 0;
11989 n
->value
&= ~GOVD_LASTPRIVATE_CONDITIONAL
;
11993 omp_add_variable (gimplify_omp_ctxp
, decl
, GOVD_PRIVATE
| GOVD_SEEN
);
11995 /* If DECL is not a gimple register, create a temporary variable to act
11996 as an iteration counter. This is valid, since DECL cannot be
11997 modified in the body of the loop. Similarly for any iteration vars
11998 in simd with collapse > 1 where the iterator vars must be
11999 lastprivate. And similarly for vars mentioned in allocate clauses. */
12000 if (orig_for_stmt
!= for_stmt
)
12002 else if (!is_gimple_reg (decl
)
12003 || (ort
== ORT_SIMD
12004 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)) > 1)
12005 || (allocate_uids
&& allocate_uids
->contains (decl
)))
12007 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
12008 /* Make sure omp_add_variable is not called on it prematurely.
12009 We call it ourselves a few lines later. */
12010 gimplify_omp_ctxp
= NULL
;
12011 var
= create_tmp_var (TREE_TYPE (decl
), get_name (decl
));
12012 gimplify_omp_ctxp
= ctx
;
12013 TREE_OPERAND (t
, 0) = var
;
12015 gimplify_seq_add_stmt (&for_body
, gimple_build_assign (decl
, var
));
12017 if (ort
== ORT_SIMD
12018 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)) == 1)
12020 c2
= build_omp_clause (input_location
, OMP_CLAUSE_LINEAR
);
12021 OMP_CLAUSE_LINEAR_NO_COPYIN (c2
) = 1;
12022 OMP_CLAUSE_LINEAR_NO_COPYOUT (c2
) = 1;
12023 OMP_CLAUSE_DECL (c2
) = var
;
12024 OMP_CLAUSE_CHAIN (c2
) = OMP_FOR_CLAUSES (for_stmt
);
12025 OMP_FOR_CLAUSES (for_stmt
) = c2
;
12026 omp_add_variable (gimplify_omp_ctxp
, var
,
12027 GOVD_LINEAR
| GOVD_EXPLICIT
| GOVD_SEEN
);
12028 if (c
== NULL_TREE
)
12035 omp_add_variable (gimplify_omp_ctxp
, var
,
12036 GOVD_PRIVATE
| GOVD_SEEN
);
12041 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
)
12043 tree lb
= TREE_OPERAND (t
, 1);
12044 tret
= gimplify_expr (&TREE_VEC_ELT (lb
, 1), &for_pre_body
, NULL
,
12045 is_gimple_val
, fb_rvalue
, false);
12046 ret
= MIN (ret
, tret
);
12047 tret
= gimplify_expr (&TREE_VEC_ELT (lb
, 2), &for_pre_body
, NULL
,
12048 is_gimple_val
, fb_rvalue
, false);
12051 tret
= gimplify_expr (&TREE_OPERAND (t
, 1), &for_pre_body
, NULL
,
12052 is_gimple_val
, fb_rvalue
, false);
12053 ret
= MIN (ret
, tret
);
12054 if (ret
== GS_ERROR
)
12057 /* Handle OMP_FOR_COND. */
12058 t
= TREE_VEC_ELT (OMP_FOR_COND (for_stmt
), i
);
12059 gcc_assert (COMPARISON_CLASS_P (t
));
12060 gcc_assert (TREE_OPERAND (t
, 0) == decl
);
12062 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
)
12064 tree ub
= TREE_OPERAND (t
, 1);
12065 tret
= gimplify_expr (&TREE_VEC_ELT (ub
, 1), &for_pre_body
, NULL
,
12066 is_gimple_val
, fb_rvalue
, false);
12067 ret
= MIN (ret
, tret
);
12068 tret
= gimplify_expr (&TREE_VEC_ELT (ub
, 2), &for_pre_body
, NULL
,
12069 is_gimple_val
, fb_rvalue
, false);
12072 tret
= gimplify_expr (&TREE_OPERAND (t
, 1), &for_pre_body
, NULL
,
12073 is_gimple_val
, fb_rvalue
, false);
12074 ret
= MIN (ret
, tret
);
12076 /* Handle OMP_FOR_INCR. */
12077 t
= TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
);
12078 switch (TREE_CODE (t
))
12080 case PREINCREMENT_EXPR
:
12081 case POSTINCREMENT_EXPR
:
12083 tree decl
= TREE_OPERAND (t
, 0);
12084 /* c_omp_for_incr_canonicalize_ptr() should have been
12085 called to massage things appropriately. */
12086 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl
)));
12088 if (orig_for_stmt
!= for_stmt
)
12090 t
= build_int_cst (TREE_TYPE (decl
), 1);
12092 OMP_CLAUSE_LINEAR_STEP (c
) = t
;
12093 t
= build2 (PLUS_EXPR
, TREE_TYPE (decl
), var
, t
);
12094 t
= build2 (MODIFY_EXPR
, TREE_TYPE (var
), var
, t
);
12095 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
) = t
;
12099 case PREDECREMENT_EXPR
:
12100 case POSTDECREMENT_EXPR
:
12101 /* c_omp_for_incr_canonicalize_ptr() should have been
12102 called to massage things appropriately. */
12103 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl
)));
12104 if (orig_for_stmt
!= for_stmt
)
12106 t
= build_int_cst (TREE_TYPE (decl
), -1);
12108 OMP_CLAUSE_LINEAR_STEP (c
) = t
;
12109 t
= build2 (PLUS_EXPR
, TREE_TYPE (decl
), var
, t
);
12110 t
= build2 (MODIFY_EXPR
, TREE_TYPE (var
), var
, t
);
12111 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
) = t
;
12115 gcc_assert (TREE_OPERAND (t
, 0) == decl
);
12116 TREE_OPERAND (t
, 0) = var
;
12118 t
= TREE_OPERAND (t
, 1);
12119 switch (TREE_CODE (t
))
12122 if (TREE_OPERAND (t
, 1) == decl
)
12124 TREE_OPERAND (t
, 1) = TREE_OPERAND (t
, 0);
12125 TREE_OPERAND (t
, 0) = var
;
12131 case POINTER_PLUS_EXPR
:
12132 gcc_assert (TREE_OPERAND (t
, 0) == decl
);
12133 TREE_OPERAND (t
, 0) = var
;
12136 gcc_unreachable ();
12139 tret
= gimplify_expr (&TREE_OPERAND (t
, 1), &for_pre_body
, NULL
,
12140 is_gimple_val
, fb_rvalue
, false);
12141 ret
= MIN (ret
, tret
);
12144 tree step
= TREE_OPERAND (t
, 1);
12145 tree stept
= TREE_TYPE (decl
);
12146 if (POINTER_TYPE_P (stept
))
12148 step
= fold_convert (stept
, step
);
12149 if (TREE_CODE (t
) == MINUS_EXPR
)
12150 step
= fold_build1 (NEGATE_EXPR
, stept
, step
);
12151 OMP_CLAUSE_LINEAR_STEP (c
) = step
;
12152 if (step
!= TREE_OPERAND (t
, 1))
12154 tret
= gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c
),
12155 &for_pre_body
, NULL
,
12156 is_gimple_val
, fb_rvalue
, false);
12157 ret
= MIN (ret
, tret
);
12163 gcc_unreachable ();
12169 OMP_CLAUSE_LINEAR_STEP (c2
) = OMP_CLAUSE_LINEAR_STEP (c
);
12172 if ((var
!= decl
|| collapse
> 1 || tile
) && orig_for_stmt
== for_stmt
)
12174 for (c
= OMP_FOR_CLAUSES (for_stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
12175 if (((OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
12176 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
) == NULL
)
12177 || (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINEAR
12178 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c
)
12179 && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c
) == NULL
))
12180 && OMP_CLAUSE_DECL (c
) == decl
)
12182 if (is_doacross
&& (collapse
== 1 || i
>= collapse
))
12186 t
= TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
);
12187 gcc_assert (TREE_CODE (t
) == MODIFY_EXPR
);
12188 gcc_assert (TREE_OPERAND (t
, 0) == var
);
12189 t
= TREE_OPERAND (t
, 1);
12190 gcc_assert (TREE_CODE (t
) == PLUS_EXPR
12191 || TREE_CODE (t
) == MINUS_EXPR
12192 || TREE_CODE (t
) == POINTER_PLUS_EXPR
);
12193 gcc_assert (TREE_OPERAND (t
, 0) == var
);
12194 t
= build2 (TREE_CODE (t
), TREE_TYPE (decl
),
12195 is_doacross
? var
: decl
,
12196 TREE_OPERAND (t
, 1));
12199 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
)
12200 seq
= &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
);
12202 seq
= &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c
);
12203 push_gimplify_context ();
12204 gimplify_assign (decl
, t
, seq
);
12205 gimple
*bind
= NULL
;
12206 if (gimplify_ctxp
->temps
)
12208 bind
= gimple_build_bind (NULL_TREE
, *seq
, NULL_TREE
);
12210 gimplify_seq_add_stmt (seq
, bind
);
12212 pop_gimplify_context (bind
);
12215 if (OMP_FOR_NON_RECTANGULAR (for_stmt
) && var
!= decl
)
12216 for (int j
= i
+ 1; j
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); j
++)
12218 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), j
);
12219 gcc_assert (TREE_CODE (t
) == MODIFY_EXPR
);
12220 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
12221 && TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) == decl
)
12222 TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) = var
;
12223 t
= TREE_VEC_ELT (OMP_FOR_COND (for_stmt
), j
);
12224 gcc_assert (COMPARISON_CLASS_P (t
));
12225 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
12226 && TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) == decl
)
12227 TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) = var
;
12231 BITMAP_FREE (has_decl_expr
);
12232 delete allocate_uids
;
12234 if (TREE_CODE (orig_for_stmt
) == OMP_TASKLOOP
12235 || (loop_p
&& orig_for_stmt
== for_stmt
))
12237 push_gimplify_context ();
12238 if (TREE_CODE (OMP_FOR_BODY (orig_for_stmt
)) != BIND_EXPR
)
12240 OMP_FOR_BODY (orig_for_stmt
)
12241 = build3 (BIND_EXPR
, void_type_node
, NULL
,
12242 OMP_FOR_BODY (orig_for_stmt
), NULL
);
12243 TREE_SIDE_EFFECTS (OMP_FOR_BODY (orig_for_stmt
)) = 1;
12247 gimple
*g
= gimplify_and_return_first (OMP_FOR_BODY (orig_for_stmt
),
12250 if (TREE_CODE (orig_for_stmt
) == OMP_TASKLOOP
12251 || (loop_p
&& orig_for_stmt
== for_stmt
))
12253 if (gimple_code (g
) == GIMPLE_BIND
)
12254 pop_gimplify_context (g
);
12256 pop_gimplify_context (NULL
);
12259 if (orig_for_stmt
!= for_stmt
)
12260 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
12262 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), i
);
12263 decl
= TREE_OPERAND (t
, 0);
12264 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
12265 if (TREE_CODE (orig_for_stmt
) == OMP_TASKLOOP
)
12266 gimplify_omp_ctxp
= ctx
->outer_context
;
12267 var
= create_tmp_var (TREE_TYPE (decl
), get_name (decl
));
12268 gimplify_omp_ctxp
= ctx
;
12269 omp_add_variable (gimplify_omp_ctxp
, var
, GOVD_PRIVATE
| GOVD_SEEN
);
12270 TREE_OPERAND (t
, 0) = var
;
12271 t
= TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
);
12272 TREE_OPERAND (t
, 1) = copy_node (TREE_OPERAND (t
, 1));
12273 TREE_OPERAND (TREE_OPERAND (t
, 1), 0) = var
;
12274 if (OMP_FOR_NON_RECTANGULAR (for_stmt
))
12275 for (int j
= i
+ 1;
12276 j
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); j
++)
12278 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), j
);
12279 gcc_assert (TREE_CODE (t
) == MODIFY_EXPR
);
12280 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
12281 && TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) == decl
)
12283 TREE_OPERAND (t
, 1) = copy_node (TREE_OPERAND (t
, 1));
12284 TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) = var
;
12286 t
= TREE_VEC_ELT (OMP_FOR_COND (for_stmt
), j
);
12287 gcc_assert (COMPARISON_CLASS_P (t
));
12288 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
12289 && TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) == decl
)
12291 TREE_OPERAND (t
, 1) = copy_node (TREE_OPERAND (t
, 1));
12292 TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) = var
;
12297 gimplify_adjust_omp_clauses (pre_p
, for_body
,
12298 &OMP_FOR_CLAUSES (orig_for_stmt
),
12299 TREE_CODE (orig_for_stmt
));
12302 switch (TREE_CODE (orig_for_stmt
))
12304 case OMP_FOR
: kind
= GF_OMP_FOR_KIND_FOR
; break;
12305 case OMP_SIMD
: kind
= GF_OMP_FOR_KIND_SIMD
; break;
12306 case OMP_DISTRIBUTE
: kind
= GF_OMP_FOR_KIND_DISTRIBUTE
; break;
12307 case OMP_TASKLOOP
: kind
= GF_OMP_FOR_KIND_TASKLOOP
; break;
12308 case OACC_LOOP
: kind
= GF_OMP_FOR_KIND_OACC_LOOP
; break;
12310 gcc_unreachable ();
12312 if (loop_p
&& kind
== GF_OMP_FOR_KIND_SIMD
)
12314 gimplify_seq_add_seq (pre_p
, for_pre_body
);
12315 for_pre_body
= NULL
;
12317 gfor
= gimple_build_omp_for (for_body
, kind
, OMP_FOR_CLAUSES (orig_for_stmt
),
12318 TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)),
12320 if (orig_for_stmt
!= for_stmt
)
12321 gimple_omp_for_set_combined_p (gfor
, true);
12322 if (gimplify_omp_ctxp
12323 && (gimplify_omp_ctxp
->combined_loop
12324 || (gimplify_omp_ctxp
->region_type
== ORT_COMBINED_PARALLEL
12325 && gimplify_omp_ctxp
->outer_context
12326 && gimplify_omp_ctxp
->outer_context
->combined_loop
)))
12328 gimple_omp_for_set_combined_into_p (gfor
, true);
12329 if (gimplify_omp_ctxp
->combined_loop
)
12330 gcc_assert (TREE_CODE (orig_for_stmt
) == OMP_SIMD
);
12332 gcc_assert (TREE_CODE (orig_for_stmt
) == OMP_FOR
);
12335 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
12337 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), i
);
12338 gimple_omp_for_set_index (gfor
, i
, TREE_OPERAND (t
, 0));
12339 gimple_omp_for_set_initial (gfor
, i
, TREE_OPERAND (t
, 1));
12340 t
= TREE_VEC_ELT (OMP_FOR_COND (for_stmt
), i
);
12341 gimple_omp_for_set_cond (gfor
, i
, TREE_CODE (t
));
12342 gimple_omp_for_set_final (gfor
, i
, TREE_OPERAND (t
, 1));
12343 t
= TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
);
12344 gimple_omp_for_set_incr (gfor
, i
, TREE_OPERAND (t
, 1));
12347 /* OMP_TASKLOOP is gimplified as two GIMPLE_OMP_FOR taskloop
12348 constructs with GIMPLE_OMP_TASK sandwiched in between them.
12349 The outer taskloop stands for computing the number of iterations,
12350 counts for collapsed loops and holding taskloop specific clauses.
12351 The task construct stands for the effect of data sharing on the
12352 explicit task it creates and the inner taskloop stands for expansion
12353 of the static loop inside of the explicit task construct. */
12354 if (TREE_CODE (orig_for_stmt
) == OMP_TASKLOOP
)
12356 tree
*gfor_clauses_ptr
= gimple_omp_for_clauses_ptr (gfor
);
12357 tree task_clauses
= NULL_TREE
;
12358 tree c
= *gfor_clauses_ptr
;
12359 tree
*gtask_clauses_ptr
= &task_clauses
;
12360 tree outer_for_clauses
= NULL_TREE
;
12361 tree
*gforo_clauses_ptr
= &outer_for_clauses
;
12362 bitmap lastprivate_uids
= NULL
;
12363 if (omp_find_clause (c
, OMP_CLAUSE_ALLOCATE
))
12365 c
= omp_find_clause (c
, OMP_CLAUSE_LASTPRIVATE
);
12368 lastprivate_uids
= BITMAP_ALLOC (NULL
);
12369 for (; c
; c
= omp_find_clause (OMP_CLAUSE_CHAIN (c
),
12370 OMP_CLAUSE_LASTPRIVATE
))
12371 bitmap_set_bit (lastprivate_uids
,
12372 DECL_UID (OMP_CLAUSE_DECL (c
)));
12374 c
= *gfor_clauses_ptr
;
12376 for (; c
; c
= OMP_CLAUSE_CHAIN (c
))
12377 switch (OMP_CLAUSE_CODE (c
))
12379 /* These clauses are allowed on task, move them there. */
12380 case OMP_CLAUSE_SHARED
:
12381 case OMP_CLAUSE_FIRSTPRIVATE
:
12382 case OMP_CLAUSE_DEFAULT
:
12383 case OMP_CLAUSE_IF
:
12384 case OMP_CLAUSE_UNTIED
:
12385 case OMP_CLAUSE_FINAL
:
12386 case OMP_CLAUSE_MERGEABLE
:
12387 case OMP_CLAUSE_PRIORITY
:
12388 case OMP_CLAUSE_REDUCTION
:
12389 case OMP_CLAUSE_IN_REDUCTION
:
12390 *gtask_clauses_ptr
= c
;
12391 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
12393 case OMP_CLAUSE_PRIVATE
:
12394 if (OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c
))
12396 /* We want private on outer for and firstprivate
12399 = build_omp_clause (OMP_CLAUSE_LOCATION (c
),
12400 OMP_CLAUSE_FIRSTPRIVATE
);
12401 OMP_CLAUSE_DECL (*gtask_clauses_ptr
) = OMP_CLAUSE_DECL (c
);
12402 lang_hooks
.decls
.omp_finish_clause (*gtask_clauses_ptr
, NULL
,
12404 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr
);
12405 *gforo_clauses_ptr
= c
;
12406 gforo_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
12410 *gtask_clauses_ptr
= c
;
12411 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
12414 /* These clauses go into outer taskloop clauses. */
12415 case OMP_CLAUSE_GRAINSIZE
:
12416 case OMP_CLAUSE_NUM_TASKS
:
12417 case OMP_CLAUSE_NOGROUP
:
12418 *gforo_clauses_ptr
= c
;
12419 gforo_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
12421 /* Collapse clause we duplicate on both taskloops. */
12422 case OMP_CLAUSE_COLLAPSE
:
12423 *gfor_clauses_ptr
= c
;
12424 gfor_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
12425 *gforo_clauses_ptr
= copy_node (c
);
12426 gforo_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr
);
12428 /* For lastprivate, keep the clause on inner taskloop, and add
12429 a shared clause on task. If the same decl is also firstprivate,
12430 add also firstprivate clause on the inner taskloop. */
12431 case OMP_CLAUSE_LASTPRIVATE
:
12432 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c
))
12434 /* For taskloop C++ lastprivate IVs, we want:
12435 1) private on outer taskloop
12436 2) firstprivate and shared on task
12437 3) lastprivate on inner taskloop */
12439 = build_omp_clause (OMP_CLAUSE_LOCATION (c
),
12440 OMP_CLAUSE_FIRSTPRIVATE
);
12441 OMP_CLAUSE_DECL (*gtask_clauses_ptr
) = OMP_CLAUSE_DECL (c
);
12442 lang_hooks
.decls
.omp_finish_clause (*gtask_clauses_ptr
, NULL
,
12444 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr
);
12445 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
) = 1;
12446 *gforo_clauses_ptr
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
12447 OMP_CLAUSE_PRIVATE
);
12448 OMP_CLAUSE_DECL (*gforo_clauses_ptr
) = OMP_CLAUSE_DECL (c
);
12449 OMP_CLAUSE_PRIVATE_TASKLOOP_IV (*gforo_clauses_ptr
) = 1;
12450 TREE_TYPE (*gforo_clauses_ptr
) = TREE_TYPE (c
);
12451 gforo_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr
);
12453 *gfor_clauses_ptr
= c
;
12454 gfor_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
12456 = build_omp_clause (OMP_CLAUSE_LOCATION (c
), OMP_CLAUSE_SHARED
);
12457 OMP_CLAUSE_DECL (*gtask_clauses_ptr
) = OMP_CLAUSE_DECL (c
);
12458 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
))
12459 OMP_CLAUSE_SHARED_FIRSTPRIVATE (*gtask_clauses_ptr
) = 1;
12461 = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr
);
12463 /* Allocate clause we duplicate on task and inner taskloop
12464 if the decl is lastprivate, otherwise just put on task. */
12465 case OMP_CLAUSE_ALLOCATE
:
12466 if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
)
12467 && DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
)))
12469 /* Additionally, put firstprivate clause on task
12470 for the allocator if it is not constant. */
12472 = build_omp_clause (OMP_CLAUSE_LOCATION (c
),
12473 OMP_CLAUSE_FIRSTPRIVATE
);
12474 OMP_CLAUSE_DECL (*gtask_clauses_ptr
)
12475 = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
);
12476 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr
);
12478 if (lastprivate_uids
12479 && bitmap_bit_p (lastprivate_uids
,
12480 DECL_UID (OMP_CLAUSE_DECL (c
))))
12482 *gfor_clauses_ptr
= c
;
12483 gfor_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
12484 *gtask_clauses_ptr
= copy_node (c
);
12485 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr
);
12489 *gtask_clauses_ptr
= c
;
12490 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
12494 gcc_unreachable ();
12496 *gfor_clauses_ptr
= NULL_TREE
;
12497 *gtask_clauses_ptr
= NULL_TREE
;
12498 *gforo_clauses_ptr
= NULL_TREE
;
12499 BITMAP_FREE (lastprivate_uids
);
12500 g
= gimple_build_bind (NULL_TREE
, gfor
, NULL_TREE
);
12501 g
= gimple_build_omp_task (g
, task_clauses
, NULL_TREE
, NULL_TREE
,
12502 NULL_TREE
, NULL_TREE
, NULL_TREE
);
12503 gimple_omp_task_set_taskloop_p (g
, true);
12504 g
= gimple_build_bind (NULL_TREE
, g
, NULL_TREE
);
12506 = gimple_build_omp_for (g
, GF_OMP_FOR_KIND_TASKLOOP
, outer_for_clauses
,
12507 gimple_omp_for_collapse (gfor
),
12508 gimple_omp_for_pre_body (gfor
));
12509 gimple_omp_for_set_pre_body (gfor
, NULL
);
12510 gimple_omp_for_set_combined_p (gforo
, true);
12511 gimple_omp_for_set_combined_into_p (gfor
, true);
12512 for (i
= 0; i
< (int) gimple_omp_for_collapse (gfor
); i
++)
12514 tree type
= TREE_TYPE (gimple_omp_for_index (gfor
, i
));
12515 tree v
= create_tmp_var (type
);
12516 gimple_omp_for_set_index (gforo
, i
, v
);
12517 t
= unshare_expr (gimple_omp_for_initial (gfor
, i
));
12518 gimple_omp_for_set_initial (gforo
, i
, t
);
12519 gimple_omp_for_set_cond (gforo
, i
,
12520 gimple_omp_for_cond (gfor
, i
));
12521 t
= unshare_expr (gimple_omp_for_final (gfor
, i
));
12522 gimple_omp_for_set_final (gforo
, i
, t
);
12523 t
= unshare_expr (gimple_omp_for_incr (gfor
, i
));
12524 gcc_assert (TREE_OPERAND (t
, 0) == gimple_omp_for_index (gfor
, i
));
12525 TREE_OPERAND (t
, 0) = v
;
12526 gimple_omp_for_set_incr (gforo
, i
, t
);
12527 t
= build_omp_clause (input_location
, OMP_CLAUSE_PRIVATE
);
12528 OMP_CLAUSE_DECL (t
) = v
;
12529 OMP_CLAUSE_CHAIN (t
) = gimple_omp_for_clauses (gforo
);
12530 gimple_omp_for_set_clauses (gforo
, t
);
12531 if (OMP_FOR_NON_RECTANGULAR (for_stmt
))
12533 tree
*p1
= NULL
, *p2
= NULL
;
12534 t
= gimple_omp_for_initial (gforo
, i
);
12535 if (TREE_CODE (t
) == TREE_VEC
)
12536 p1
= &TREE_VEC_ELT (t
, 0);
12537 t
= gimple_omp_for_final (gforo
, i
);
12538 if (TREE_CODE (t
) == TREE_VEC
)
12541 p2
= &TREE_VEC_ELT (t
, 0);
12543 p1
= &TREE_VEC_ELT (t
, 0);
12548 for (j
= 0; j
< i
; j
++)
12549 if (*p1
== gimple_omp_for_index (gfor
, j
))
12551 *p1
= gimple_omp_for_index (gforo
, j
);
12556 gcc_assert (j
< i
);
12560 gimplify_seq_add_stmt (pre_p
, gforo
);
12563 gimplify_seq_add_stmt (pre_p
, gfor
);
12565 if (TREE_CODE (orig_for_stmt
) == OMP_FOR
)
12567 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
12568 unsigned lastprivate_conditional
= 0;
12570 && (ctx
->region_type
== ORT_TARGET_DATA
12571 || ctx
->region_type
== ORT_TASKGROUP
))
12572 ctx
= ctx
->outer_context
;
12573 if (ctx
&& (ctx
->region_type
& ORT_PARALLEL
) != 0)
12574 for (tree c
= gimple_omp_for_clauses (gfor
);
12575 c
; c
= OMP_CLAUSE_CHAIN (c
))
12576 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
12577 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
))
12578 ++lastprivate_conditional
;
12579 if (lastprivate_conditional
)
12581 struct omp_for_data fd
;
12582 omp_extract_for_data (gfor
, &fd
, NULL
);
12583 tree type
= build_array_type_nelts (unsigned_type_for (fd
.iter_type
),
12584 lastprivate_conditional
);
12585 tree var
= create_tmp_var_raw (type
);
12586 tree c
= build_omp_clause (UNKNOWN_LOCATION
, OMP_CLAUSE__CONDTEMP_
);
12587 OMP_CLAUSE_DECL (c
) = var
;
12588 OMP_CLAUSE_CHAIN (c
) = gimple_omp_for_clauses (gfor
);
12589 gimple_omp_for_set_clauses (gfor
, c
);
12590 omp_add_variable (ctx
, var
, GOVD_CONDTEMP
| GOVD_SEEN
);
12593 else if (TREE_CODE (orig_for_stmt
) == OMP_SIMD
)
12595 unsigned lastprivate_conditional
= 0;
12596 for (tree c
= gimple_omp_for_clauses (gfor
); c
; c
= OMP_CLAUSE_CHAIN (c
))
12597 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
12598 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
))
12599 ++lastprivate_conditional
;
12600 if (lastprivate_conditional
)
12602 struct omp_for_data fd
;
12603 omp_extract_for_data (gfor
, &fd
, NULL
);
12604 tree type
= unsigned_type_for (fd
.iter_type
);
12605 while (lastprivate_conditional
--)
12607 tree c
= build_omp_clause (UNKNOWN_LOCATION
,
12608 OMP_CLAUSE__CONDTEMP_
);
12609 OMP_CLAUSE_DECL (c
) = create_tmp_var (type
);
12610 OMP_CLAUSE_CHAIN (c
) = gimple_omp_for_clauses (gfor
);
12611 gimple_omp_for_set_clauses (gfor
, c
);
12616 if (ret
!= GS_ALL_DONE
)
12618 *expr_p
= NULL_TREE
;
12619 return GS_ALL_DONE
;
12622 /* Helper for gimplify_omp_loop, called through walk_tree. */
12625 replace_reduction_placeholders (tree
*tp
, int *walk_subtrees
, void *data
)
12629 tree
*d
= (tree
*) data
;
12630 if (*tp
== OMP_CLAUSE_REDUCTION_PLACEHOLDER (d
[0]))
12632 *tp
= OMP_CLAUSE_REDUCTION_PLACEHOLDER (d
[1]);
12633 *walk_subtrees
= 0;
12635 else if (*tp
== OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (d
[0]))
12637 *tp
= OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (d
[1]);
12638 *walk_subtrees
= 0;
12644 /* Gimplify the gross structure of an OMP_LOOP statement. */
12646 static enum gimplify_status
12647 gimplify_omp_loop (tree
*expr_p
, gimple_seq
*pre_p
)
12649 tree for_stmt
= *expr_p
;
12650 tree clauses
= OMP_FOR_CLAUSES (for_stmt
);
12651 struct gimplify_omp_ctx
*octx
= gimplify_omp_ctxp
;
12652 enum omp_clause_bind_kind kind
= OMP_CLAUSE_BIND_THREAD
;
12655 /* If order is not present, the behavior is as if order(concurrent)
12657 tree order
= omp_find_clause (clauses
, OMP_CLAUSE_ORDER
);
12658 if (order
== NULL_TREE
)
12660 order
= build_omp_clause (UNKNOWN_LOCATION
, OMP_CLAUSE_ORDER
);
12661 OMP_CLAUSE_CHAIN (order
) = clauses
;
12662 OMP_FOR_CLAUSES (for_stmt
) = clauses
= order
;
12665 tree bind
= omp_find_clause (clauses
, OMP_CLAUSE_BIND
);
12666 if (bind
== NULL_TREE
)
12668 if (!flag_openmp
) /* flag_openmp_simd */
12670 else if (octx
&& (octx
->region_type
& ORT_TEAMS
) != 0)
12671 kind
= OMP_CLAUSE_BIND_TEAMS
;
12672 else if (octx
&& (octx
->region_type
& ORT_PARALLEL
) != 0)
12673 kind
= OMP_CLAUSE_BIND_PARALLEL
;
12676 for (; octx
; octx
= octx
->outer_context
)
12678 if ((octx
->region_type
& ORT_ACC
) != 0
12679 || octx
->region_type
== ORT_NONE
12680 || octx
->region_type
== ORT_IMPLICIT_TARGET
)
12684 if (octx
== NULL
&& !in_omp_construct
)
12685 error_at (EXPR_LOCATION (for_stmt
),
12686 "%<bind%> clause not specified on a %<loop%> "
12687 "construct not nested inside another OpenMP construct");
12689 bind
= build_omp_clause (UNKNOWN_LOCATION
, OMP_CLAUSE_BIND
);
12690 OMP_CLAUSE_CHAIN (bind
) = clauses
;
12691 OMP_CLAUSE_BIND_KIND (bind
) = kind
;
12692 OMP_FOR_CLAUSES (for_stmt
) = bind
;
12695 switch (OMP_CLAUSE_BIND_KIND (bind
))
12697 case OMP_CLAUSE_BIND_THREAD
:
12699 case OMP_CLAUSE_BIND_PARALLEL
:
12700 if (!flag_openmp
) /* flag_openmp_simd */
12702 OMP_CLAUSE_BIND_KIND (bind
) = OMP_CLAUSE_BIND_THREAD
;
12705 for (; octx
; octx
= octx
->outer_context
)
12706 if (octx
->region_type
== ORT_SIMD
12707 && omp_find_clause (octx
->clauses
, OMP_CLAUSE_BIND
) == NULL_TREE
)
12709 error_at (EXPR_LOCATION (for_stmt
),
12710 "%<bind(parallel)%> on a %<loop%> construct nested "
12711 "inside %<simd%> construct");
12712 OMP_CLAUSE_BIND_KIND (bind
) = OMP_CLAUSE_BIND_THREAD
;
12715 kind
= OMP_CLAUSE_BIND_PARALLEL
;
12717 case OMP_CLAUSE_BIND_TEAMS
:
12718 if (!flag_openmp
) /* flag_openmp_simd */
12720 OMP_CLAUSE_BIND_KIND (bind
) = OMP_CLAUSE_BIND_THREAD
;
12724 && octx
->region_type
!= ORT_IMPLICIT_TARGET
12725 && octx
->region_type
!= ORT_NONE
12726 && (octx
->region_type
& ORT_TEAMS
) == 0)
12727 || in_omp_construct
)
12729 error_at (EXPR_LOCATION (for_stmt
),
12730 "%<bind(teams)%> on a %<loop%> region not strictly "
12731 "nested inside of a %<teams%> region");
12732 OMP_CLAUSE_BIND_KIND (bind
) = OMP_CLAUSE_BIND_THREAD
;
12735 kind
= OMP_CLAUSE_BIND_TEAMS
;
12738 gcc_unreachable ();
12741 for (tree
*pc
= &OMP_FOR_CLAUSES (for_stmt
); *pc
; )
12742 switch (OMP_CLAUSE_CODE (*pc
))
12744 case OMP_CLAUSE_REDUCTION
:
12745 if (OMP_CLAUSE_REDUCTION_INSCAN (*pc
))
12747 error_at (OMP_CLAUSE_LOCATION (*pc
),
12748 "%<inscan%> %<reduction%> clause on "
12749 "%qs construct", "loop");
12750 OMP_CLAUSE_REDUCTION_INSCAN (*pc
) = 0;
12752 if (OMP_CLAUSE_REDUCTION_TASK (*pc
))
12754 error_at (OMP_CLAUSE_LOCATION (*pc
),
12755 "invalid %<task%> reduction modifier on construct "
12756 "other than %<parallel%>, %qs or %<sections%>",
12757 lang_GNU_Fortran () ? "do" : "for");
12758 OMP_CLAUSE_REDUCTION_TASK (*pc
) = 0;
12760 pc
= &OMP_CLAUSE_CHAIN (*pc
);
12762 case OMP_CLAUSE_LASTPRIVATE
:
12763 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
12765 tree t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), i
);
12766 gcc_assert (TREE_CODE (t
) == MODIFY_EXPR
);
12767 if (OMP_CLAUSE_DECL (*pc
) == TREE_OPERAND (t
, 0))
12769 if (OMP_FOR_ORIG_DECLS (for_stmt
)
12770 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
),
12772 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
),
12775 tree orig
= TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
), i
);
12776 if (OMP_CLAUSE_DECL (*pc
) == TREE_PURPOSE (orig
))
12780 if (i
== TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)))
12782 error_at (OMP_CLAUSE_LOCATION (*pc
),
12783 "%<lastprivate%> clause on a %<loop%> construct refers "
12784 "to a variable %qD which is not the loop iterator",
12785 OMP_CLAUSE_DECL (*pc
));
12786 *pc
= OMP_CLAUSE_CHAIN (*pc
);
12789 pc
= &OMP_CLAUSE_CHAIN (*pc
);
12792 pc
= &OMP_CLAUSE_CHAIN (*pc
);
12796 TREE_SET_CODE (for_stmt
, OMP_SIMD
);
12801 case OMP_CLAUSE_BIND_THREAD
: last
= 0; break;
12802 case OMP_CLAUSE_BIND_PARALLEL
: last
= 1; break;
12803 case OMP_CLAUSE_BIND_TEAMS
: last
= 2; break;
12805 for (int pass
= 1; pass
<= last
; pass
++)
12809 tree bind
= build3 (BIND_EXPR
, void_type_node
, NULL
, NULL
, NULL
);
12810 append_to_statement_list (*expr_p
, &BIND_EXPR_BODY (bind
));
12811 *expr_p
= make_node (OMP_PARALLEL
);
12812 TREE_TYPE (*expr_p
) = void_type_node
;
12813 OMP_PARALLEL_BODY (*expr_p
) = bind
;
12814 OMP_PARALLEL_COMBINED (*expr_p
) = 1;
12815 SET_EXPR_LOCATION (*expr_p
, EXPR_LOCATION (for_stmt
));
12816 tree
*pc
= &OMP_PARALLEL_CLAUSES (*expr_p
);
12817 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
12818 if (OMP_FOR_ORIG_DECLS (for_stmt
)
12819 && (TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
), i
))
12822 tree elt
= TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
), i
);
12823 if (TREE_PURPOSE (elt
) && TREE_VALUE (elt
))
12825 *pc
= build_omp_clause (UNKNOWN_LOCATION
,
12826 OMP_CLAUSE_FIRSTPRIVATE
);
12827 OMP_CLAUSE_DECL (*pc
) = TREE_VALUE (elt
);
12828 pc
= &OMP_CLAUSE_CHAIN (*pc
);
12832 tree t
= make_node (pass
== 2 ? OMP_DISTRIBUTE
: OMP_FOR
);
12833 tree
*pc
= &OMP_FOR_CLAUSES (t
);
12834 TREE_TYPE (t
) = void_type_node
;
12835 OMP_FOR_BODY (t
) = *expr_p
;
12836 SET_EXPR_LOCATION (t
, EXPR_LOCATION (for_stmt
));
12837 for (tree c
= OMP_FOR_CLAUSES (for_stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
12838 switch (OMP_CLAUSE_CODE (c
))
12840 case OMP_CLAUSE_BIND
:
12841 case OMP_CLAUSE_ORDER
:
12842 case OMP_CLAUSE_COLLAPSE
:
12843 *pc
= copy_node (c
);
12844 pc
= &OMP_CLAUSE_CHAIN (*pc
);
12846 case OMP_CLAUSE_PRIVATE
:
12847 case OMP_CLAUSE_FIRSTPRIVATE
:
12848 /* Only needed on innermost. */
12850 case OMP_CLAUSE_LASTPRIVATE
:
12851 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c
) && pass
!= last
)
12853 *pc
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
12854 OMP_CLAUSE_FIRSTPRIVATE
);
12855 OMP_CLAUSE_DECL (*pc
) = OMP_CLAUSE_DECL (c
);
12856 lang_hooks
.decls
.omp_finish_clause (*pc
, NULL
, false);
12857 pc
= &OMP_CLAUSE_CHAIN (*pc
);
12859 *pc
= copy_node (c
);
12860 OMP_CLAUSE_LASTPRIVATE_STMT (*pc
) = NULL_TREE
;
12861 TREE_TYPE (*pc
) = unshare_expr (TREE_TYPE (c
));
12862 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c
))
12865 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (*pc
) = 1;
12867 lang_hooks
.decls
.omp_finish_clause (*pc
, NULL
, false);
12868 OMP_CLAUSE_LASTPRIVATE_LOOP_IV (*pc
) = 0;
12870 pc
= &OMP_CLAUSE_CHAIN (*pc
);
12872 case OMP_CLAUSE_REDUCTION
:
12873 *pc
= copy_node (c
);
12874 OMP_CLAUSE_DECL (*pc
) = unshare_expr (OMP_CLAUSE_DECL (c
));
12875 TREE_TYPE (*pc
) = unshare_expr (TREE_TYPE (c
));
12876 OMP_CLAUSE_REDUCTION_INIT (*pc
)
12877 = unshare_expr (OMP_CLAUSE_REDUCTION_INIT (c
));
12878 OMP_CLAUSE_REDUCTION_MERGE (*pc
)
12879 = unshare_expr (OMP_CLAUSE_REDUCTION_MERGE (c
));
12880 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc
))
12882 OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc
)
12883 = copy_node (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
));
12884 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc
))
12885 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc
)
12886 = copy_node (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c
));
12888 tree data
[2] = { c
, nc
};
12889 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_INIT (nc
),
12890 replace_reduction_placeholders
,
12892 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_MERGE (nc
),
12893 replace_reduction_placeholders
,
12896 pc
= &OMP_CLAUSE_CHAIN (*pc
);
12899 gcc_unreachable ();
12904 return gimplify_omp_for (expr_p
, pre_p
);
12908 /* Helper function of optimize_target_teams, find OMP_TEAMS inside
12909 of OMP_TARGET's body. */
12912 find_omp_teams (tree
*tp
, int *walk_subtrees
, void *)
12914 *walk_subtrees
= 0;
12915 switch (TREE_CODE (*tp
))
12920 case STATEMENT_LIST
:
12921 *walk_subtrees
= 1;
12929 /* Helper function of optimize_target_teams, determine if the expression
12930 can be computed safely before the target construct on the host. */
12933 computable_teams_clause (tree
*tp
, int *walk_subtrees
, void *)
12939 *walk_subtrees
= 0;
12942 switch (TREE_CODE (*tp
))
12947 *walk_subtrees
= 0;
12948 if (error_operand_p (*tp
)
12949 || !INTEGRAL_TYPE_P (TREE_TYPE (*tp
))
12950 || DECL_HAS_VALUE_EXPR_P (*tp
)
12951 || DECL_THREAD_LOCAL_P (*tp
)
12952 || TREE_SIDE_EFFECTS (*tp
)
12953 || TREE_THIS_VOLATILE (*tp
))
12955 if (is_global_var (*tp
)
12956 && (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (*tp
))
12957 || lookup_attribute ("omp declare target link",
12958 DECL_ATTRIBUTES (*tp
))))
12961 && !DECL_SEEN_IN_BIND_EXPR_P (*tp
)
12962 && !is_global_var (*tp
)
12963 && decl_function_context (*tp
) == current_function_decl
)
12965 n
= splay_tree_lookup (gimplify_omp_ctxp
->variables
,
12966 (splay_tree_key
) *tp
);
12969 if (gimplify_omp_ctxp
->defaultmap
[GDMK_SCALAR
] & GOVD_FIRSTPRIVATE
)
12973 else if (n
->value
& GOVD_LOCAL
)
12975 else if (n
->value
& GOVD_FIRSTPRIVATE
)
12977 else if ((n
->value
& (GOVD_MAP
| GOVD_MAP_ALWAYS_TO
))
12978 == (GOVD_MAP
| GOVD_MAP_ALWAYS_TO
))
12982 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp
)))
12986 if (TARGET_EXPR_INITIAL (*tp
)
12987 || TREE_CODE (TARGET_EXPR_SLOT (*tp
)) != VAR_DECL
)
12989 return computable_teams_clause (&TARGET_EXPR_SLOT (*tp
),
12990 walk_subtrees
, NULL
);
12991 /* Allow some reasonable subset of integral arithmetics. */
12995 case TRUNC_DIV_EXPR
:
12996 case CEIL_DIV_EXPR
:
12997 case FLOOR_DIV_EXPR
:
12998 case ROUND_DIV_EXPR
:
12999 case TRUNC_MOD_EXPR
:
13000 case CEIL_MOD_EXPR
:
13001 case FLOOR_MOD_EXPR
:
13002 case ROUND_MOD_EXPR
:
13004 case EXACT_DIV_EXPR
:
13015 case NON_LVALUE_EXPR
:
13017 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp
)))
13020 /* And disallow anything else, except for comparisons. */
13022 if (COMPARISON_CLASS_P (*tp
))
13028 /* Try to determine if the num_teams and/or thread_limit expressions
13029 can have their values determined already before entering the
13031 INTEGER_CSTs trivially are,
13032 integral decls that are firstprivate (explicitly or implicitly)
13033 or explicitly map(always, to:) or map(always, tofrom:) on the target
13034 region too, and expressions involving simple arithmetics on those
13035 too, function calls are not ok, dereferencing something neither etc.
13036 Add NUM_TEAMS and THREAD_LIMIT clauses to the OMP_CLAUSES of
13037 EXPR based on what we find:
13038 0 stands for clause not specified at all, use implementation default
13039 -1 stands for value that can't be determined easily before entering
13040 the target construct.
13041 If teams construct is not present at all, use 1 for num_teams
13042 and 0 for thread_limit (only one team is involved, and the thread
13043 limit is implementation defined. */
13046 optimize_target_teams (tree target
, gimple_seq
*pre_p
)
13048 tree body
= OMP_BODY (target
);
13049 tree teams
= walk_tree (&body
, find_omp_teams
, NULL
, NULL
);
13050 tree num_teams
= integer_zero_node
;
13051 tree thread_limit
= integer_zero_node
;
13052 location_t num_teams_loc
= EXPR_LOCATION (target
);
13053 location_t thread_limit_loc
= EXPR_LOCATION (target
);
13055 struct gimplify_omp_ctx
*target_ctx
= gimplify_omp_ctxp
;
13057 if (teams
== NULL_TREE
)
13058 num_teams
= integer_one_node
;
13060 for (c
= OMP_TEAMS_CLAUSES (teams
); c
; c
= OMP_CLAUSE_CHAIN (c
))
13062 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_NUM_TEAMS
)
13065 num_teams_loc
= OMP_CLAUSE_LOCATION (c
);
13067 else if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_THREAD_LIMIT
)
13070 thread_limit_loc
= OMP_CLAUSE_LOCATION (c
);
13074 expr
= OMP_CLAUSE_OPERAND (c
, 0);
13075 if (TREE_CODE (expr
) == INTEGER_CST
)
13080 if (walk_tree (&expr
, computable_teams_clause
, NULL
, NULL
))
13082 *p
= integer_minus_one_node
;
13086 gimplify_omp_ctxp
= gimplify_omp_ctxp
->outer_context
;
13087 if (gimplify_expr (p
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
, false)
13090 gimplify_omp_ctxp
= target_ctx
;
13091 *p
= integer_minus_one_node
;
13094 gimplify_omp_ctxp
= target_ctx
;
13095 if (!DECL_P (expr
) && TREE_CODE (expr
) != TARGET_EXPR
)
13096 OMP_CLAUSE_OPERAND (c
, 0) = *p
;
13098 c
= build_omp_clause (thread_limit_loc
, OMP_CLAUSE_THREAD_LIMIT
);
13099 OMP_CLAUSE_THREAD_LIMIT_EXPR (c
) = thread_limit
;
13100 OMP_CLAUSE_CHAIN (c
) = OMP_TARGET_CLAUSES (target
);
13101 OMP_TARGET_CLAUSES (target
) = c
;
13102 c
= build_omp_clause (num_teams_loc
, OMP_CLAUSE_NUM_TEAMS
);
13103 OMP_CLAUSE_NUM_TEAMS_EXPR (c
) = num_teams
;
13104 OMP_CLAUSE_CHAIN (c
) = OMP_TARGET_CLAUSES (target
);
13105 OMP_TARGET_CLAUSES (target
) = c
;
13108 /* Gimplify the gross structure of several OMP constructs. */
13111 gimplify_omp_workshare (tree
*expr_p
, gimple_seq
*pre_p
)
13113 tree expr
= *expr_p
;
13115 gimple_seq body
= NULL
;
13116 enum omp_region_type ort
;
13118 switch (TREE_CODE (expr
))
13122 ort
= ORT_WORKSHARE
;
13125 ort
= OMP_TARGET_COMBINED (expr
) ? ORT_COMBINED_TARGET
: ORT_TARGET
;
13128 ort
= ORT_ACC_KERNELS
;
13130 case OACC_PARALLEL
:
13131 ort
= ORT_ACC_PARALLEL
;
13134 ort
= ORT_ACC_SERIAL
;
13137 ort
= ORT_ACC_DATA
;
13139 case OMP_TARGET_DATA
:
13140 ort
= ORT_TARGET_DATA
;
13143 ort
= OMP_TEAMS_COMBINED (expr
) ? ORT_COMBINED_TEAMS
: ORT_TEAMS
;
13144 if (gimplify_omp_ctxp
== NULL
13145 || gimplify_omp_ctxp
->region_type
== ORT_IMPLICIT_TARGET
)
13146 ort
= (enum omp_region_type
) (ort
| ORT_HOST_TEAMS
);
13148 case OACC_HOST_DATA
:
13149 ort
= ORT_ACC_HOST_DATA
;
13152 gcc_unreachable ();
13155 bool save_in_omp_construct
= in_omp_construct
;
13156 if ((ort
& ORT_ACC
) == 0)
13157 in_omp_construct
= false;
13158 gimplify_scan_omp_clauses (&OMP_CLAUSES (expr
), pre_p
, ort
,
13160 if (TREE_CODE (expr
) == OMP_TARGET
)
13161 optimize_target_teams (expr
, pre_p
);
13162 if ((ort
& (ORT_TARGET
| ORT_TARGET_DATA
)) != 0
13163 || (ort
& ORT_HOST_TEAMS
) == ORT_HOST_TEAMS
)
13165 push_gimplify_context ();
13166 gimple
*g
= gimplify_and_return_first (OMP_BODY (expr
), &body
);
13167 if (gimple_code (g
) == GIMPLE_BIND
)
13168 pop_gimplify_context (g
);
13170 pop_gimplify_context (NULL
);
13171 if ((ort
& ORT_TARGET_DATA
) != 0)
13173 enum built_in_function end_ix
;
13174 switch (TREE_CODE (expr
))
13177 case OACC_HOST_DATA
:
13178 end_ix
= BUILT_IN_GOACC_DATA_END
;
13180 case OMP_TARGET_DATA
:
13181 end_ix
= BUILT_IN_GOMP_TARGET_END_DATA
;
13184 gcc_unreachable ();
13186 tree fn
= builtin_decl_explicit (end_ix
);
13187 g
= gimple_build_call (fn
, 0);
13188 gimple_seq cleanup
= NULL
;
13189 gimple_seq_add_stmt (&cleanup
, g
);
13190 g
= gimple_build_try (body
, cleanup
, GIMPLE_TRY_FINALLY
);
13192 gimple_seq_add_stmt (&body
, g
);
13196 gimplify_and_add (OMP_BODY (expr
), &body
);
13197 gimplify_adjust_omp_clauses (pre_p
, body
, &OMP_CLAUSES (expr
),
13199 in_omp_construct
= save_in_omp_construct
;
13201 switch (TREE_CODE (expr
))
13204 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_OACC_DATA
,
13205 OMP_CLAUSES (expr
));
13207 case OACC_HOST_DATA
:
13208 if (omp_find_clause (OMP_CLAUSES (expr
), OMP_CLAUSE_IF_PRESENT
))
13210 for (tree c
= OMP_CLAUSES (expr
); c
; c
= OMP_CLAUSE_CHAIN (c
))
13211 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_USE_DEVICE_PTR
)
13212 OMP_CLAUSE_USE_DEVICE_PTR_IF_PRESENT (c
) = 1;
13215 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_OACC_HOST_DATA
,
13216 OMP_CLAUSES (expr
));
13219 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_OACC_KERNELS
,
13220 OMP_CLAUSES (expr
));
13222 case OACC_PARALLEL
:
13223 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_OACC_PARALLEL
,
13224 OMP_CLAUSES (expr
));
13227 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_OACC_SERIAL
,
13228 OMP_CLAUSES (expr
));
13231 stmt
= gimple_build_omp_sections (body
, OMP_CLAUSES (expr
));
13234 stmt
= gimple_build_omp_single (body
, OMP_CLAUSES (expr
));
13237 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_REGION
,
13238 OMP_CLAUSES (expr
));
13240 case OMP_TARGET_DATA
:
13241 /* Put use_device_{ptr,addr} clauses last, as map clauses are supposed
13242 to be evaluated before the use_device_{ptr,addr} clauses if they
13243 refer to the same variables. */
13245 tree use_device_clauses
;
13246 tree
*pc
, *uc
= &use_device_clauses
;
13247 for (pc
= &OMP_CLAUSES (expr
); *pc
; )
13248 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_USE_DEVICE_PTR
13249 || OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_USE_DEVICE_ADDR
)
13252 *pc
= OMP_CLAUSE_CHAIN (*pc
);
13253 uc
= &OMP_CLAUSE_CHAIN (*uc
);
13256 pc
= &OMP_CLAUSE_CHAIN (*pc
);
13258 *pc
= use_device_clauses
;
13259 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_DATA
,
13260 OMP_CLAUSES (expr
));
13264 stmt
= gimple_build_omp_teams (body
, OMP_CLAUSES (expr
));
13265 if ((ort
& ORT_HOST_TEAMS
) == ORT_HOST_TEAMS
)
13266 gimple_omp_teams_set_host (as_a
<gomp_teams
*> (stmt
), true);
13269 gcc_unreachable ();
13272 gimplify_seq_add_stmt (pre_p
, stmt
);
13273 *expr_p
= NULL_TREE
;
13276 /* Gimplify the gross structure of OpenACC enter/exit data, update, and OpenMP
13277 target update constructs. */
13280 gimplify_omp_target_update (tree
*expr_p
, gimple_seq
*pre_p
)
13282 tree expr
= *expr_p
;
13285 enum omp_region_type ort
= ORT_WORKSHARE
;
13287 switch (TREE_CODE (expr
))
13289 case OACC_ENTER_DATA
:
13290 case OACC_EXIT_DATA
:
13291 kind
= GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA
;
13295 kind
= GF_OMP_TARGET_KIND_OACC_UPDATE
;
13298 case OMP_TARGET_UPDATE
:
13299 kind
= GF_OMP_TARGET_KIND_UPDATE
;
13301 case OMP_TARGET_ENTER_DATA
:
13302 kind
= GF_OMP_TARGET_KIND_ENTER_DATA
;
13304 case OMP_TARGET_EXIT_DATA
:
13305 kind
= GF_OMP_TARGET_KIND_EXIT_DATA
;
13308 gcc_unreachable ();
13310 gimplify_scan_omp_clauses (&OMP_STANDALONE_CLAUSES (expr
), pre_p
,
13311 ort
, TREE_CODE (expr
));
13312 gimplify_adjust_omp_clauses (pre_p
, NULL
, &OMP_STANDALONE_CLAUSES (expr
),
13314 if (TREE_CODE (expr
) == OACC_UPDATE
13315 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr
),
13316 OMP_CLAUSE_IF_PRESENT
))
13318 /* The runtime uses GOMP_MAP_{TO,FROM} to denote the if_present
13320 for (tree c
= OMP_STANDALONE_CLAUSES (expr
); c
; c
= OMP_CLAUSE_CHAIN (c
))
13321 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_MAP
)
13322 switch (OMP_CLAUSE_MAP_KIND (c
))
13324 case GOMP_MAP_FORCE_TO
:
13325 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_TO
);
13327 case GOMP_MAP_FORCE_FROM
:
13328 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_FROM
);
13334 else if (TREE_CODE (expr
) == OACC_EXIT_DATA
13335 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr
),
13336 OMP_CLAUSE_FINALIZE
))
13338 /* Use GOMP_MAP_DELETE/GOMP_MAP_FORCE_FROM to denote "finalize"
13340 bool have_clause
= false;
13341 for (tree c
= OMP_STANDALONE_CLAUSES (expr
); c
; c
= OMP_CLAUSE_CHAIN (c
))
13342 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_MAP
)
13343 switch (OMP_CLAUSE_MAP_KIND (c
))
13345 case GOMP_MAP_FROM
:
13346 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_FORCE_FROM
);
13347 have_clause
= true;
13349 case GOMP_MAP_RELEASE
:
13350 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_DELETE
);
13351 have_clause
= true;
13353 case GOMP_MAP_TO_PSET
:
13354 /* Fortran arrays with descriptors must map that descriptor when
13355 doing standalone "attach" operations (in OpenACC). In that
13356 case GOMP_MAP_TO_PSET appears by itself with no preceding
13357 clause (see trans-openmp.c:gfc_trans_omp_clauses). */
13359 case GOMP_MAP_POINTER
:
13360 /* TODO PR92929: we may see these here, but they'll always follow
13361 one of the clauses above, and will be handled by libgomp as
13362 one group, so no handling required here. */
13363 gcc_assert (have_clause
);
13365 case GOMP_MAP_DETACH
:
13366 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_FORCE_DETACH
);
13367 have_clause
= false;
13369 case GOMP_MAP_STRUCT
:
13370 have_clause
= false;
13373 gcc_unreachable ();
13376 stmt
= gimple_build_omp_target (NULL
, kind
, OMP_STANDALONE_CLAUSES (expr
));
13378 gimplify_seq_add_stmt (pre_p
, stmt
);
13379 *expr_p
= NULL_TREE
;
13382 /* A subroutine of gimplify_omp_atomic. The front end is supposed to have
13383 stabilized the lhs of the atomic operation as *ADDR. Return true if
13384 EXPR is this stabilized form. */
13387 goa_lhs_expr_p (tree expr
, tree addr
)
13389 /* Also include casts to other type variants. The C front end is fond
13390 of adding these for e.g. volatile variables. This is like
13391 STRIP_TYPE_NOPS but includes the main variant lookup. */
13392 STRIP_USELESS_TYPE_CONVERSION (expr
);
13394 if (TREE_CODE (expr
) == INDIRECT_REF
)
13396 expr
= TREE_OPERAND (expr
, 0);
13397 while (expr
!= addr
13398 && (CONVERT_EXPR_P (expr
)
13399 || TREE_CODE (expr
) == NON_LVALUE_EXPR
)
13400 && TREE_CODE (expr
) == TREE_CODE (addr
)
13401 && types_compatible_p (TREE_TYPE (expr
), TREE_TYPE (addr
)))
13403 expr
= TREE_OPERAND (expr
, 0);
13404 addr
= TREE_OPERAND (addr
, 0);
13408 return (TREE_CODE (addr
) == ADDR_EXPR
13409 && TREE_CODE (expr
) == ADDR_EXPR
13410 && TREE_OPERAND (addr
, 0) == TREE_OPERAND (expr
, 0));
13412 if (TREE_CODE (addr
) == ADDR_EXPR
&& expr
== TREE_OPERAND (addr
, 0))
13417 /* Walk *EXPR_P and replace appearances of *LHS_ADDR with LHS_VAR. If an
13418 expression does not involve the lhs, evaluate it into a temporary.
13419 Return 1 if the lhs appeared as a subexpression, 0 if it did not,
13420 or -1 if an error was encountered. */
13423 goa_stabilize_expr (tree
*expr_p
, gimple_seq
*pre_p
, tree lhs_addr
,
13426 tree expr
= *expr_p
;
13429 if (goa_lhs_expr_p (expr
, lhs_addr
))
13434 if (is_gimple_val (expr
))
13438 switch (TREE_CODE_CLASS (TREE_CODE (expr
)))
13441 case tcc_comparison
:
13442 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 1), pre_p
, lhs_addr
,
13446 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 0), pre_p
, lhs_addr
,
13449 case tcc_expression
:
13450 switch (TREE_CODE (expr
))
13452 case TRUTH_ANDIF_EXPR
:
13453 case TRUTH_ORIF_EXPR
:
13454 case TRUTH_AND_EXPR
:
13455 case TRUTH_OR_EXPR
:
13456 case TRUTH_XOR_EXPR
:
13457 case BIT_INSERT_EXPR
:
13458 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 1), pre_p
,
13459 lhs_addr
, lhs_var
);
13461 case TRUTH_NOT_EXPR
:
13462 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 0), pre_p
,
13463 lhs_addr
, lhs_var
);
13465 case COMPOUND_EXPR
:
13466 /* Break out any preevaluations from cp_build_modify_expr. */
13467 for (; TREE_CODE (expr
) == COMPOUND_EXPR
;
13468 expr
= TREE_OPERAND (expr
, 1))
13469 gimplify_stmt (&TREE_OPERAND (expr
, 0), pre_p
);
13471 return goa_stabilize_expr (expr_p
, pre_p
, lhs_addr
, lhs_var
);
13476 case tcc_reference
:
13477 if (TREE_CODE (expr
) == BIT_FIELD_REF
)
13478 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 0), pre_p
,
13479 lhs_addr
, lhs_var
);
13487 enum gimplify_status gs
;
13488 gs
= gimplify_expr (expr_p
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
13489 if (gs
!= GS_ALL_DONE
)
13496 /* Gimplify an OMP_ATOMIC statement. */
13498 static enum gimplify_status
13499 gimplify_omp_atomic (tree
*expr_p
, gimple_seq
*pre_p
)
13501 tree addr
= TREE_OPERAND (*expr_p
, 0);
13502 tree rhs
= TREE_CODE (*expr_p
) == OMP_ATOMIC_READ
13503 ? NULL
: TREE_OPERAND (*expr_p
, 1);
13504 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr
)));
13506 gomp_atomic_load
*loadstmt
;
13507 gomp_atomic_store
*storestmt
;
13509 tmp_load
= create_tmp_reg (type
);
13510 if (rhs
&& goa_stabilize_expr (&rhs
, pre_p
, addr
, tmp_load
) < 0)
13513 if (gimplify_expr (&addr
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
)
13517 loadstmt
= gimple_build_omp_atomic_load (tmp_load
, addr
,
13518 OMP_ATOMIC_MEMORY_ORDER (*expr_p
));
13519 gimplify_seq_add_stmt (pre_p
, loadstmt
);
13522 /* BIT_INSERT_EXPR is not valid for non-integral bitfield
13523 representatives. Use BIT_FIELD_REF on the lhs instead. */
13524 if (TREE_CODE (rhs
) == BIT_INSERT_EXPR
13525 && !INTEGRAL_TYPE_P (TREE_TYPE (tmp_load
)))
13527 tree bitpos
= TREE_OPERAND (rhs
, 2);
13528 tree op1
= TREE_OPERAND (rhs
, 1);
13530 tree tmp_store
= tmp_load
;
13531 if (TREE_CODE (*expr_p
) == OMP_ATOMIC_CAPTURE_OLD
)
13532 tmp_store
= get_initialized_tmp_var (tmp_load
, pre_p
);
13533 if (INTEGRAL_TYPE_P (TREE_TYPE (op1
)))
13534 bitsize
= bitsize_int (TYPE_PRECISION (TREE_TYPE (op1
)));
13536 bitsize
= TYPE_SIZE (TREE_TYPE (op1
));
13537 gcc_assert (TREE_OPERAND (rhs
, 0) == tmp_load
);
13538 tree t
= build2_loc (EXPR_LOCATION (rhs
),
13539 MODIFY_EXPR
, void_type_node
,
13540 build3_loc (EXPR_LOCATION (rhs
), BIT_FIELD_REF
,
13541 TREE_TYPE (op1
), tmp_store
, bitsize
,
13543 gimplify_and_add (t
, pre_p
);
13546 if (gimplify_expr (&rhs
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
)
13551 if (TREE_CODE (*expr_p
) == OMP_ATOMIC_READ
)
13554 = gimple_build_omp_atomic_store (rhs
, OMP_ATOMIC_MEMORY_ORDER (*expr_p
));
13555 gimplify_seq_add_stmt (pre_p
, storestmt
);
13556 switch (TREE_CODE (*expr_p
))
13558 case OMP_ATOMIC_READ
:
13559 case OMP_ATOMIC_CAPTURE_OLD
:
13560 *expr_p
= tmp_load
;
13561 gimple_omp_atomic_set_need_value (loadstmt
);
13563 case OMP_ATOMIC_CAPTURE_NEW
:
13565 gimple_omp_atomic_set_need_value (storestmt
);
13572 return GS_ALL_DONE
;
13575 /* Gimplify a TRANSACTION_EXPR. This involves gimplification of the
13576 body, and adding some EH bits. */
13578 static enum gimplify_status
13579 gimplify_transaction (tree
*expr_p
, gimple_seq
*pre_p
)
13581 tree expr
= *expr_p
, temp
, tbody
= TRANSACTION_EXPR_BODY (expr
);
13583 gtransaction
*trans_stmt
;
13584 gimple_seq body
= NULL
;
13587 /* Wrap the transaction body in a BIND_EXPR so we have a context
13588 where to put decls for OMP. */
13589 if (TREE_CODE (tbody
) != BIND_EXPR
)
13591 tree bind
= build3 (BIND_EXPR
, void_type_node
, NULL
, tbody
, NULL
);
13592 TREE_SIDE_EFFECTS (bind
) = 1;
13593 SET_EXPR_LOCATION (bind
, EXPR_LOCATION (tbody
));
13594 TRANSACTION_EXPR_BODY (expr
) = bind
;
13597 push_gimplify_context ();
13598 temp
= voidify_wrapper_expr (*expr_p
, NULL
);
13600 body_stmt
= gimplify_and_return_first (TRANSACTION_EXPR_BODY (expr
), &body
);
13601 pop_gimplify_context (body_stmt
);
13603 trans_stmt
= gimple_build_transaction (body
);
13604 if (TRANSACTION_EXPR_OUTER (expr
))
13605 subcode
= GTMA_IS_OUTER
;
13606 else if (TRANSACTION_EXPR_RELAXED (expr
))
13607 subcode
= GTMA_IS_RELAXED
;
13608 gimple_transaction_set_subcode (trans_stmt
, subcode
);
13610 gimplify_seq_add_stmt (pre_p
, trans_stmt
);
13618 *expr_p
= NULL_TREE
;
13619 return GS_ALL_DONE
;
13622 /* Gimplify an OMP_ORDERED construct. EXPR is the tree version. BODY
13623 is the OMP_BODY of the original EXPR (which has already been
13624 gimplified so it's not present in the EXPR).
13626 Return the gimplified GIMPLE_OMP_ORDERED tuple. */
13629 gimplify_omp_ordered (tree expr
, gimple_seq body
)
13634 tree source_c
= NULL_TREE
;
13635 tree sink_c
= NULL_TREE
;
13637 if (gimplify_omp_ctxp
)
13639 for (c
= OMP_ORDERED_CLAUSES (expr
); c
; c
= OMP_CLAUSE_CHAIN (c
))
13640 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEPEND
13641 && gimplify_omp_ctxp
->loop_iter_var
.is_empty ()
13642 && (OMP_CLAUSE_DEPEND_KIND (c
) == OMP_CLAUSE_DEPEND_SINK
13643 || OMP_CLAUSE_DEPEND_KIND (c
) == OMP_CLAUSE_DEPEND_SOURCE
))
13645 error_at (OMP_CLAUSE_LOCATION (c
),
13646 "%<ordered%> construct with %<depend%> clause must be "
13647 "closely nested inside a loop with %<ordered%> clause "
13648 "with a parameter");
13651 else if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEPEND
13652 && OMP_CLAUSE_DEPEND_KIND (c
) == OMP_CLAUSE_DEPEND_SINK
)
13655 for (decls
= OMP_CLAUSE_DECL (c
), i
= 0;
13656 decls
&& TREE_CODE (decls
) == TREE_LIST
;
13657 decls
= TREE_CHAIN (decls
), ++i
)
13658 if (i
>= gimplify_omp_ctxp
->loop_iter_var
.length () / 2)
13660 else if (TREE_VALUE (decls
)
13661 != gimplify_omp_ctxp
->loop_iter_var
[2 * i
])
13663 error_at (OMP_CLAUSE_LOCATION (c
),
13664 "variable %qE is not an iteration "
13665 "of outermost loop %d, expected %qE",
13666 TREE_VALUE (decls
), i
+ 1,
13667 gimplify_omp_ctxp
->loop_iter_var
[2 * i
]);
13673 = gimplify_omp_ctxp
->loop_iter_var
[2 * i
+ 1];
13674 if (!fail
&& i
!= gimplify_omp_ctxp
->loop_iter_var
.length () / 2)
13676 error_at (OMP_CLAUSE_LOCATION (c
),
13677 "number of variables in %<depend%> clause with "
13678 "%<sink%> modifier does not match number of "
13679 "iteration variables");
13684 else if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEPEND
13685 && OMP_CLAUSE_DEPEND_KIND (c
) == OMP_CLAUSE_DEPEND_SOURCE
)
13689 error_at (OMP_CLAUSE_LOCATION (c
),
13690 "more than one %<depend%> clause with %<source%> "
13691 "modifier on an %<ordered%> construct");
13698 if (source_c
&& sink_c
)
13700 error_at (OMP_CLAUSE_LOCATION (source_c
),
13701 "%<depend%> clause with %<source%> modifier specified "
13702 "together with %<depend%> clauses with %<sink%> modifier "
13703 "on the same construct");
13708 return gimple_build_nop ();
13709 return gimple_build_omp_ordered (body
, OMP_ORDERED_CLAUSES (expr
));
13712 /* Convert the GENERIC expression tree *EXPR_P to GIMPLE. If the
13713 expression produces a value to be used as an operand inside a GIMPLE
13714 statement, the value will be stored back in *EXPR_P. This value will
13715 be a tree of class tcc_declaration, tcc_constant, tcc_reference or
13716 an SSA_NAME. The corresponding sequence of GIMPLE statements is
13717 emitted in PRE_P and POST_P.
13719 Additionally, this process may overwrite parts of the input
13720 expression during gimplification. Ideally, it should be
13721 possible to do non-destructive gimplification.
13723 EXPR_P points to the GENERIC expression to convert to GIMPLE. If
13724 the expression needs to evaluate to a value to be used as
13725 an operand in a GIMPLE statement, this value will be stored in
13726 *EXPR_P on exit. This happens when the caller specifies one
13727 of fb_lvalue or fb_rvalue fallback flags.
13729 PRE_P will contain the sequence of GIMPLE statements corresponding
13730 to the evaluation of EXPR and all the side-effects that must
13731 be executed before the main expression. On exit, the last
13732 statement of PRE_P is the core statement being gimplified. For
13733 instance, when gimplifying 'if (++a)' the last statement in
13734 PRE_P will be 'if (t.1)' where t.1 is the result of
13735 pre-incrementing 'a'.
13737 POST_P will contain the sequence of GIMPLE statements corresponding
13738 to the evaluation of all the side-effects that must be executed
13739 after the main expression. If this is NULL, the post
13740 side-effects are stored at the end of PRE_P.
13742 The reason why the output is split in two is to handle post
13743 side-effects explicitly. In some cases, an expression may have
13744 inner and outer post side-effects which need to be emitted in
13745 an order different from the one given by the recursive
13746 traversal. For instance, for the expression (*p--)++ the post
13747 side-effects of '--' must actually occur *after* the post
13748 side-effects of '++'. However, gimplification will first visit
13749 the inner expression, so if a separate POST sequence was not
13750 used, the resulting sequence would be:
13757 However, the post-decrement operation in line #2 must not be
13758 evaluated until after the store to *p at line #4, so the
13759 correct sequence should be:
13766 So, by specifying a separate post queue, it is possible
13767 to emit the post side-effects in the correct order.
13768 If POST_P is NULL, an internal queue will be used. Before
13769 returning to the caller, the sequence POST_P is appended to
13770 the main output sequence PRE_P.
13772 GIMPLE_TEST_F points to a function that takes a tree T and
13773 returns nonzero if T is in the GIMPLE form requested by the
13774 caller. The GIMPLE predicates are in gimple.c.
13776 FALLBACK tells the function what sort of a temporary we want if
13777 gimplification cannot produce an expression that complies with
13780 fb_none means that no temporary should be generated
13781 fb_rvalue means that an rvalue is OK to generate
13782 fb_lvalue means that an lvalue is OK to generate
13783 fb_either means that either is OK, but an lvalue is preferable.
13784 fb_mayfail means that gimplification may fail (in which case
13785 GS_ERROR will be returned)
13787 The return value is either GS_ERROR or GS_ALL_DONE, since this
13788 function iterates until EXPR is completely gimplified or an error
13791 enum gimplify_status
13792 gimplify_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
13793 bool (*gimple_test_f
) (tree
), fallback_t fallback
)
13796 gimple_seq internal_pre
= NULL
;
13797 gimple_seq internal_post
= NULL
;
13800 location_t saved_location
;
13801 enum gimplify_status ret
;
13802 gimple_stmt_iterator pre_last_gsi
, post_last_gsi
;
13805 save_expr
= *expr_p
;
13806 if (save_expr
== NULL_TREE
)
13807 return GS_ALL_DONE
;
13809 /* If we are gimplifying a top-level statement, PRE_P must be valid. */
13810 is_statement
= gimple_test_f
== is_gimple_stmt
;
13812 gcc_assert (pre_p
);
13814 /* Consistency checks. */
13815 if (gimple_test_f
== is_gimple_reg
)
13816 gcc_assert (fallback
& (fb_rvalue
| fb_lvalue
));
13817 else if (gimple_test_f
== is_gimple_val
13818 || gimple_test_f
== is_gimple_call_addr
13819 || gimple_test_f
== is_gimple_condexpr
13820 || gimple_test_f
== is_gimple_condexpr_for_cond
13821 || gimple_test_f
== is_gimple_mem_rhs
13822 || gimple_test_f
== is_gimple_mem_rhs_or_call
13823 || gimple_test_f
== is_gimple_reg_rhs
13824 || gimple_test_f
== is_gimple_reg_rhs_or_call
13825 || gimple_test_f
== is_gimple_asm_val
13826 || gimple_test_f
== is_gimple_mem_ref_addr
)
13827 gcc_assert (fallback
& fb_rvalue
);
13828 else if (gimple_test_f
== is_gimple_min_lval
13829 || gimple_test_f
== is_gimple_lvalue
)
13830 gcc_assert (fallback
& fb_lvalue
);
13831 else if (gimple_test_f
== is_gimple_addressable
)
13832 gcc_assert (fallback
& fb_either
);
13833 else if (gimple_test_f
== is_gimple_stmt
)
13834 gcc_assert (fallback
== fb_none
);
13837 /* We should have recognized the GIMPLE_TEST_F predicate to
13838 know what kind of fallback to use in case a temporary is
13839 needed to hold the value or address of *EXPR_P. */
13840 gcc_unreachable ();
13843 /* We used to check the predicate here and return immediately if it
13844 succeeds. This is wrong; the design is for gimplification to be
13845 idempotent, and for the predicates to only test for valid forms, not
13846 whether they are fully simplified. */
13848 pre_p
= &internal_pre
;
13850 if (post_p
== NULL
)
13851 post_p
= &internal_post
;
13853 /* Remember the last statements added to PRE_P and POST_P. Every
13854 new statement added by the gimplification helpers needs to be
13855 annotated with location information. To centralize the
13856 responsibility, we remember the last statement that had been
13857 added to both queues before gimplifying *EXPR_P. If
13858 gimplification produces new statements in PRE_P and POST_P, those
13859 statements will be annotated with the same location information
13861 pre_last_gsi
= gsi_last (*pre_p
);
13862 post_last_gsi
= gsi_last (*post_p
);
13864 saved_location
= input_location
;
13865 if (save_expr
!= error_mark_node
13866 && EXPR_HAS_LOCATION (*expr_p
))
13867 input_location
= EXPR_LOCATION (*expr_p
);
13869 /* Loop over the specific gimplifiers until the toplevel node
13870 remains the same. */
13873 /* Strip away as many useless type conversions as possible
13874 at the toplevel. */
13875 STRIP_USELESS_TYPE_CONVERSION (*expr_p
);
13877 /* Remember the expr. */
13878 save_expr
= *expr_p
;
13880 /* Die, die, die, my darling. */
13881 if (error_operand_p (save_expr
))
13887 /* Do any language-specific gimplification. */
13888 ret
= ((enum gimplify_status
)
13889 lang_hooks
.gimplify_expr (expr_p
, pre_p
, post_p
));
13892 if (*expr_p
== NULL_TREE
)
13894 if (*expr_p
!= save_expr
)
13897 else if (ret
!= GS_UNHANDLED
)
13900 /* Make sure that all the cases set 'ret' appropriately. */
13901 ret
= GS_UNHANDLED
;
13902 switch (TREE_CODE (*expr_p
))
13904 /* First deal with the special cases. */
13906 case POSTINCREMENT_EXPR
:
13907 case POSTDECREMENT_EXPR
:
13908 case PREINCREMENT_EXPR
:
13909 case PREDECREMENT_EXPR
:
13910 ret
= gimplify_self_mod_expr (expr_p
, pre_p
, post_p
,
13911 fallback
!= fb_none
,
13912 TREE_TYPE (*expr_p
));
13915 case VIEW_CONVERT_EXPR
:
13916 if ((fallback
& fb_rvalue
)
13917 && is_gimple_reg_type (TREE_TYPE (*expr_p
))
13918 && is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (*expr_p
, 0))))
13920 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
13921 post_p
, is_gimple_val
, fb_rvalue
);
13922 recalculate_side_effects (*expr_p
);
13928 case ARRAY_RANGE_REF
:
13929 case REALPART_EXPR
:
13930 case IMAGPART_EXPR
:
13931 case COMPONENT_REF
:
13932 ret
= gimplify_compound_lval (expr_p
, pre_p
, post_p
,
13933 fallback
? fallback
: fb_rvalue
);
13937 ret
= gimplify_cond_expr (expr_p
, pre_p
, fallback
);
13939 /* C99 code may assign to an array in a structure value of a
13940 conditional expression, and this has undefined behavior
13941 only on execution, so create a temporary if an lvalue is
13943 if (fallback
== fb_lvalue
)
13945 *expr_p
= get_initialized_tmp_var (*expr_p
, pre_p
, post_p
, false);
13946 mark_addressable (*expr_p
);
13952 ret
= gimplify_call_expr (expr_p
, pre_p
, fallback
!= fb_none
);
13954 /* C99 code may assign to an array in a structure returned
13955 from a function, and this has undefined behavior only on
13956 execution, so create a temporary if an lvalue is
13958 if (fallback
== fb_lvalue
)
13960 *expr_p
= get_initialized_tmp_var (*expr_p
, pre_p
, post_p
, false);
13961 mark_addressable (*expr_p
);
13967 gcc_unreachable ();
13969 case COMPOUND_EXPR
:
13970 ret
= gimplify_compound_expr (expr_p
, pre_p
, fallback
!= fb_none
);
13973 case COMPOUND_LITERAL_EXPR
:
13974 ret
= gimplify_compound_literal_expr (expr_p
, pre_p
,
13975 gimple_test_f
, fallback
);
13980 ret
= gimplify_modify_expr (expr_p
, pre_p
, post_p
,
13981 fallback
!= fb_none
);
13984 case TRUTH_ANDIF_EXPR
:
13985 case TRUTH_ORIF_EXPR
:
13987 /* Preserve the original type of the expression and the
13988 source location of the outer expression. */
13989 tree org_type
= TREE_TYPE (*expr_p
);
13990 *expr_p
= gimple_boolify (*expr_p
);
13991 *expr_p
= build3_loc (input_location
, COND_EXPR
,
13995 org_type
, boolean_true_node
),
13998 org_type
, boolean_false_node
));
14003 case TRUTH_NOT_EXPR
:
14005 tree type
= TREE_TYPE (*expr_p
);
14006 /* The parsers are careful to generate TRUTH_NOT_EXPR
14007 only with operands that are always zero or one.
14008 We do not fold here but handle the only interesting case
14009 manually, as fold may re-introduce the TRUTH_NOT_EXPR. */
14010 *expr_p
= gimple_boolify (*expr_p
);
14011 if (TYPE_PRECISION (TREE_TYPE (*expr_p
)) == 1)
14012 *expr_p
= build1_loc (input_location
, BIT_NOT_EXPR
,
14013 TREE_TYPE (*expr_p
),
14014 TREE_OPERAND (*expr_p
, 0));
14016 *expr_p
= build2_loc (input_location
, BIT_XOR_EXPR
,
14017 TREE_TYPE (*expr_p
),
14018 TREE_OPERAND (*expr_p
, 0),
14019 build_int_cst (TREE_TYPE (*expr_p
), 1));
14020 if (!useless_type_conversion_p (type
, TREE_TYPE (*expr_p
)))
14021 *expr_p
= fold_convert_loc (input_location
, type
, *expr_p
);
14027 ret
= gimplify_addr_expr (expr_p
, pre_p
, post_p
);
14030 case ANNOTATE_EXPR
:
14032 tree cond
= TREE_OPERAND (*expr_p
, 0);
14033 tree kind
= TREE_OPERAND (*expr_p
, 1);
14034 tree data
= TREE_OPERAND (*expr_p
, 2);
14035 tree type
= TREE_TYPE (cond
);
14036 if (!INTEGRAL_TYPE_P (type
))
14042 tree tmp
= create_tmp_var (type
);
14043 gimplify_arg (&cond
, pre_p
, EXPR_LOCATION (*expr_p
));
14045 = gimple_build_call_internal (IFN_ANNOTATE
, 3, cond
, kind
, data
);
14046 gimple_call_set_lhs (call
, tmp
);
14047 gimplify_seq_add_stmt (pre_p
, call
);
14054 ret
= gimplify_va_arg_expr (expr_p
, pre_p
, post_p
);
14058 if (IS_EMPTY_STMT (*expr_p
))
14064 if (VOID_TYPE_P (TREE_TYPE (*expr_p
))
14065 || fallback
== fb_none
)
14067 /* Just strip a conversion to void (or in void context) and
14069 *expr_p
= TREE_OPERAND (*expr_p
, 0);
14074 ret
= gimplify_conversion (expr_p
);
14075 if (ret
== GS_ERROR
)
14077 if (*expr_p
!= save_expr
)
14081 case FIX_TRUNC_EXPR
:
14082 /* unary_expr: ... | '(' cast ')' val | ... */
14083 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
14084 is_gimple_val
, fb_rvalue
);
14085 recalculate_side_effects (*expr_p
);
14090 bool volatilep
= TREE_THIS_VOLATILE (*expr_p
);
14091 bool notrap
= TREE_THIS_NOTRAP (*expr_p
);
14092 tree saved_ptr_type
= TREE_TYPE (TREE_OPERAND (*expr_p
, 0));
14094 *expr_p
= fold_indirect_ref_loc (input_location
, *expr_p
);
14095 if (*expr_p
!= save_expr
)
14101 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
14102 is_gimple_reg
, fb_rvalue
);
14103 if (ret
== GS_ERROR
)
14106 recalculate_side_effects (*expr_p
);
14107 *expr_p
= fold_build2_loc (input_location
, MEM_REF
,
14108 TREE_TYPE (*expr_p
),
14109 TREE_OPERAND (*expr_p
, 0),
14110 build_int_cst (saved_ptr_type
, 0));
14111 TREE_THIS_VOLATILE (*expr_p
) = volatilep
;
14112 TREE_THIS_NOTRAP (*expr_p
) = notrap
;
14117 /* We arrive here through the various re-gimplifcation paths. */
14119 /* First try re-folding the whole thing. */
14120 tmp
= fold_binary (MEM_REF
, TREE_TYPE (*expr_p
),
14121 TREE_OPERAND (*expr_p
, 0),
14122 TREE_OPERAND (*expr_p
, 1));
14125 REF_REVERSE_STORAGE_ORDER (tmp
)
14126 = REF_REVERSE_STORAGE_ORDER (*expr_p
);
14128 recalculate_side_effects (*expr_p
);
14132 /* Avoid re-gimplifying the address operand if it is already
14133 in suitable form. Re-gimplifying would mark the address
14134 operand addressable. Always gimplify when not in SSA form
14135 as we still may have to gimplify decls with value-exprs. */
14136 if (!gimplify_ctxp
|| !gimple_in_ssa_p (cfun
)
14137 || !is_gimple_mem_ref_addr (TREE_OPERAND (*expr_p
, 0)))
14139 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
14140 is_gimple_mem_ref_addr
, fb_rvalue
);
14141 if (ret
== GS_ERROR
)
14144 recalculate_side_effects (*expr_p
);
14148 /* Constants need not be gimplified. */
14155 /* Drop the overflow flag on constants, we do not want
14156 that in the GIMPLE IL. */
14157 if (TREE_OVERFLOW_P (*expr_p
))
14158 *expr_p
= drop_tree_overflow (*expr_p
);
14163 /* If we require an lvalue, such as for ADDR_EXPR, retain the
14164 CONST_DECL node. Otherwise the decl is replaceable by its
14166 /* ??? Should be == fb_lvalue, but ADDR_EXPR passes fb_either. */
14167 if (fallback
& fb_lvalue
)
14171 *expr_p
= DECL_INITIAL (*expr_p
);
14177 ret
= gimplify_decl_expr (expr_p
, pre_p
);
14181 ret
= gimplify_bind_expr (expr_p
, pre_p
);
14185 ret
= gimplify_loop_expr (expr_p
, pre_p
);
14189 ret
= gimplify_switch_expr (expr_p
, pre_p
);
14193 ret
= gimplify_exit_expr (expr_p
);
14197 /* If the target is not LABEL, then it is a computed jump
14198 and the target needs to be gimplified. */
14199 if (TREE_CODE (GOTO_DESTINATION (*expr_p
)) != LABEL_DECL
)
14201 ret
= gimplify_expr (&GOTO_DESTINATION (*expr_p
), pre_p
,
14202 NULL
, is_gimple_val
, fb_rvalue
);
14203 if (ret
== GS_ERROR
)
14206 gimplify_seq_add_stmt (pre_p
,
14207 gimple_build_goto (GOTO_DESTINATION (*expr_p
)));
14212 gimplify_seq_add_stmt (pre_p
,
14213 gimple_build_predict (PREDICT_EXPR_PREDICTOR (*expr_p
),
14214 PREDICT_EXPR_OUTCOME (*expr_p
)));
14219 ret
= gimplify_label_expr (expr_p
, pre_p
);
14220 label
= LABEL_EXPR_LABEL (*expr_p
);
14221 gcc_assert (decl_function_context (label
) == current_function_decl
);
14223 /* If the label is used in a goto statement, or address of the label
14224 is taken, we need to unpoison all variables that were seen so far.
14225 Doing so would prevent us from reporting a false positives. */
14226 if (asan_poisoned_variables
14227 && asan_used_labels
!= NULL
14228 && asan_used_labels
->contains (label
))
14229 asan_poison_variables (asan_poisoned_variables
, false, pre_p
);
14232 case CASE_LABEL_EXPR
:
14233 ret
= gimplify_case_label_expr (expr_p
, pre_p
);
14235 if (gimplify_ctxp
->live_switch_vars
)
14236 asan_poison_variables (gimplify_ctxp
->live_switch_vars
, false,
14241 ret
= gimplify_return_expr (*expr_p
, pre_p
);
14245 /* Don't reduce this in place; let gimplify_init_constructor work its
14246 magic. Buf if we're just elaborating this for side effects, just
14247 gimplify any element that has side-effects. */
14248 if (fallback
== fb_none
)
14250 unsigned HOST_WIDE_INT ix
;
14252 tree temp
= NULL_TREE
;
14253 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (*expr_p
), ix
, val
)
14254 if (TREE_SIDE_EFFECTS (val
))
14255 append_to_statement_list (val
, &temp
);
14258 ret
= temp
? GS_OK
: GS_ALL_DONE
;
14260 /* C99 code may assign to an array in a constructed
14261 structure or union, and this has undefined behavior only
14262 on execution, so create a temporary if an lvalue is
14264 else if (fallback
== fb_lvalue
)
14266 *expr_p
= get_initialized_tmp_var (*expr_p
, pre_p
, post_p
, false);
14267 mark_addressable (*expr_p
);
14274 /* The following are special cases that are not handled by the
14275 original GIMPLE grammar. */
14277 /* SAVE_EXPR nodes are converted into a GIMPLE identifier and
14280 ret
= gimplify_save_expr (expr_p
, pre_p
, post_p
);
14283 case BIT_FIELD_REF
:
14284 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
14285 post_p
, is_gimple_lvalue
, fb_either
);
14286 recalculate_side_effects (*expr_p
);
14289 case TARGET_MEM_REF
:
14291 enum gimplify_status r0
= GS_ALL_DONE
, r1
= GS_ALL_DONE
;
14293 if (TMR_BASE (*expr_p
))
14294 r0
= gimplify_expr (&TMR_BASE (*expr_p
), pre_p
,
14295 post_p
, is_gimple_mem_ref_addr
, fb_either
);
14296 if (TMR_INDEX (*expr_p
))
14297 r1
= gimplify_expr (&TMR_INDEX (*expr_p
), pre_p
,
14298 post_p
, is_gimple_val
, fb_rvalue
);
14299 if (TMR_INDEX2 (*expr_p
))
14300 r1
= gimplify_expr (&TMR_INDEX2 (*expr_p
), pre_p
,
14301 post_p
, is_gimple_val
, fb_rvalue
);
14302 /* TMR_STEP and TMR_OFFSET are always integer constants. */
14303 ret
= MIN (r0
, r1
);
14307 case NON_LVALUE_EXPR
:
14308 /* This should have been stripped above. */
14309 gcc_unreachable ();
14312 ret
= gimplify_asm_expr (expr_p
, pre_p
, post_p
);
14315 case TRY_FINALLY_EXPR
:
14316 case TRY_CATCH_EXPR
:
14318 gimple_seq eval
, cleanup
;
14321 /* Calls to destructors are generated automatically in FINALLY/CATCH
14322 block. They should have location as UNKNOWN_LOCATION. However,
14323 gimplify_call_expr will reset these call stmts to input_location
14324 if it finds stmt's location is unknown. To prevent resetting for
14325 destructors, we set the input_location to unknown.
14326 Note that this only affects the destructor calls in FINALLY/CATCH
14327 block, and will automatically reset to its original value by the
14328 end of gimplify_expr. */
14329 input_location
= UNKNOWN_LOCATION
;
14330 eval
= cleanup
= NULL
;
14331 gimplify_and_add (TREE_OPERAND (*expr_p
, 0), &eval
);
14332 if (TREE_CODE (*expr_p
) == TRY_FINALLY_EXPR
14333 && TREE_CODE (TREE_OPERAND (*expr_p
, 1)) == EH_ELSE_EXPR
)
14335 gimple_seq n
= NULL
, e
= NULL
;
14336 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p
, 1),
14338 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p
, 1),
14340 if (!gimple_seq_empty_p (n
) && !gimple_seq_empty_p (e
))
14342 geh_else
*stmt
= gimple_build_eh_else (n
, e
);
14343 gimple_seq_add_stmt (&cleanup
, stmt
);
14347 gimplify_and_add (TREE_OPERAND (*expr_p
, 1), &cleanup
);
14348 /* Don't create bogus GIMPLE_TRY with empty cleanup. */
14349 if (gimple_seq_empty_p (cleanup
))
14351 gimple_seq_add_seq (pre_p
, eval
);
14355 try_
= gimple_build_try (eval
, cleanup
,
14356 TREE_CODE (*expr_p
) == TRY_FINALLY_EXPR
14357 ? GIMPLE_TRY_FINALLY
14358 : GIMPLE_TRY_CATCH
);
14359 if (EXPR_HAS_LOCATION (save_expr
))
14360 gimple_set_location (try_
, EXPR_LOCATION (save_expr
));
14361 else if (LOCATION_LOCUS (saved_location
) != UNKNOWN_LOCATION
)
14362 gimple_set_location (try_
, saved_location
);
14363 if (TREE_CODE (*expr_p
) == TRY_CATCH_EXPR
)
14364 gimple_try_set_catch_is_cleanup (try_
,
14365 TRY_CATCH_IS_CLEANUP (*expr_p
));
14366 gimplify_seq_add_stmt (pre_p
, try_
);
14371 case CLEANUP_POINT_EXPR
:
14372 ret
= gimplify_cleanup_point_expr (expr_p
, pre_p
);
14376 ret
= gimplify_target_expr (expr_p
, pre_p
, post_p
);
14382 gimple_seq handler
= NULL
;
14383 gimplify_and_add (CATCH_BODY (*expr_p
), &handler
);
14384 c
= gimple_build_catch (CATCH_TYPES (*expr_p
), handler
);
14385 gimplify_seq_add_stmt (pre_p
, c
);
14390 case EH_FILTER_EXPR
:
14393 gimple_seq failure
= NULL
;
14395 gimplify_and_add (EH_FILTER_FAILURE (*expr_p
), &failure
);
14396 ehf
= gimple_build_eh_filter (EH_FILTER_TYPES (*expr_p
), failure
);
14397 gimple_set_no_warning (ehf
, TREE_NO_WARNING (*expr_p
));
14398 gimplify_seq_add_stmt (pre_p
, ehf
);
14405 enum gimplify_status r0
, r1
;
14406 r0
= gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p
), pre_p
,
14407 post_p
, is_gimple_val
, fb_rvalue
);
14408 r1
= gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p
), pre_p
,
14409 post_p
, is_gimple_val
, fb_rvalue
);
14410 TREE_SIDE_EFFECTS (*expr_p
) = 0;
14411 ret
= MIN (r0
, r1
);
14416 /* We get here when taking the address of a label. We mark
14417 the label as "forced"; meaning it can never be removed and
14418 it is a potential target for any computed goto. */
14419 FORCED_LABEL (*expr_p
) = 1;
14423 case STATEMENT_LIST
:
14424 ret
= gimplify_statement_list (expr_p
, pre_p
);
14427 case WITH_SIZE_EXPR
:
14429 gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
14430 post_p
== &internal_post
? NULL
: post_p
,
14431 gimple_test_f
, fallback
);
14432 gimplify_expr (&TREE_OPERAND (*expr_p
, 1), pre_p
, post_p
,
14433 is_gimple_val
, fb_rvalue
);
14440 ret
= gimplify_var_or_parm_decl (expr_p
);
14444 /* When within an OMP context, notice uses of variables. */
14445 if (gimplify_omp_ctxp
)
14446 omp_notice_variable (gimplify_omp_ctxp
, *expr_p
, true);
14450 case DEBUG_EXPR_DECL
:
14451 gcc_unreachable ();
14453 case DEBUG_BEGIN_STMT
:
14454 gimplify_seq_add_stmt (pre_p
,
14455 gimple_build_debug_begin_stmt
14456 (TREE_BLOCK (*expr_p
),
14457 EXPR_LOCATION (*expr_p
)));
14463 /* Allow callbacks into the gimplifier during optimization. */
14468 gimplify_omp_parallel (expr_p
, pre_p
);
14473 gimplify_omp_task (expr_p
, pre_p
);
14479 case OMP_DISTRIBUTE
:
14482 ret
= gimplify_omp_for (expr_p
, pre_p
);
14486 ret
= gimplify_omp_loop (expr_p
, pre_p
);
14490 gimplify_oacc_cache (expr_p
, pre_p
);
14495 gimplify_oacc_declare (expr_p
, pre_p
);
14499 case OACC_HOST_DATA
:
14502 case OACC_PARALLEL
:
14507 case OMP_TARGET_DATA
:
14509 gimplify_omp_workshare (expr_p
, pre_p
);
14513 case OACC_ENTER_DATA
:
14514 case OACC_EXIT_DATA
:
14516 case OMP_TARGET_UPDATE
:
14517 case OMP_TARGET_ENTER_DATA
:
14518 case OMP_TARGET_EXIT_DATA
:
14519 gimplify_omp_target_update (expr_p
, pre_p
);
14529 gimple_seq body
= NULL
;
14531 bool saved_in_omp_construct
= in_omp_construct
;
14533 in_omp_construct
= true;
14534 gimplify_and_add (OMP_BODY (*expr_p
), &body
);
14535 in_omp_construct
= saved_in_omp_construct
;
14536 switch (TREE_CODE (*expr_p
))
14539 g
= gimple_build_omp_section (body
);
14542 g
= gimple_build_omp_master (body
);
14545 g
= gimplify_omp_ordered (*expr_p
, body
);
14548 gimplify_scan_omp_clauses (&OMP_CRITICAL_CLAUSES (*expr_p
),
14549 pre_p
, ORT_WORKSHARE
, OMP_CRITICAL
);
14550 gimplify_adjust_omp_clauses (pre_p
, body
,
14551 &OMP_CRITICAL_CLAUSES (*expr_p
),
14553 g
= gimple_build_omp_critical (body
,
14554 OMP_CRITICAL_NAME (*expr_p
),
14555 OMP_CRITICAL_CLAUSES (*expr_p
));
14558 gimplify_scan_omp_clauses (&OMP_SCAN_CLAUSES (*expr_p
),
14559 pre_p
, ORT_WORKSHARE
, OMP_SCAN
);
14560 gimplify_adjust_omp_clauses (pre_p
, body
,
14561 &OMP_SCAN_CLAUSES (*expr_p
),
14563 g
= gimple_build_omp_scan (body
, OMP_SCAN_CLAUSES (*expr_p
));
14566 gcc_unreachable ();
14568 gimplify_seq_add_stmt (pre_p
, g
);
14573 case OMP_TASKGROUP
:
14575 gimple_seq body
= NULL
;
14577 tree
*pclauses
= &OMP_TASKGROUP_CLAUSES (*expr_p
);
14578 bool saved_in_omp_construct
= in_omp_construct
;
14579 gimplify_scan_omp_clauses (pclauses
, pre_p
, ORT_TASKGROUP
,
14581 gimplify_adjust_omp_clauses (pre_p
, NULL
, pclauses
, OMP_TASKGROUP
);
14583 in_omp_construct
= true;
14584 gimplify_and_add (OMP_BODY (*expr_p
), &body
);
14585 in_omp_construct
= saved_in_omp_construct
;
14586 gimple_seq cleanup
= NULL
;
14587 tree fn
= builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_END
);
14588 gimple
*g
= gimple_build_call (fn
, 0);
14589 gimple_seq_add_stmt (&cleanup
, g
);
14590 g
= gimple_build_try (body
, cleanup
, GIMPLE_TRY_FINALLY
);
14592 gimple_seq_add_stmt (&body
, g
);
14593 g
= gimple_build_omp_taskgroup (body
, *pclauses
);
14594 gimplify_seq_add_stmt (pre_p
, g
);
14600 case OMP_ATOMIC_READ
:
14601 case OMP_ATOMIC_CAPTURE_OLD
:
14602 case OMP_ATOMIC_CAPTURE_NEW
:
14603 ret
= gimplify_omp_atomic (expr_p
, pre_p
);
14606 case TRANSACTION_EXPR
:
14607 ret
= gimplify_transaction (expr_p
, pre_p
);
14610 case TRUTH_AND_EXPR
:
14611 case TRUTH_OR_EXPR
:
14612 case TRUTH_XOR_EXPR
:
14614 tree orig_type
= TREE_TYPE (*expr_p
);
14615 tree new_type
, xop0
, xop1
;
14616 *expr_p
= gimple_boolify (*expr_p
);
14617 new_type
= TREE_TYPE (*expr_p
);
14618 if (!useless_type_conversion_p (orig_type
, new_type
))
14620 *expr_p
= fold_convert_loc (input_location
, orig_type
, *expr_p
);
14625 /* Boolified binary truth expressions are semantically equivalent
14626 to bitwise binary expressions. Canonicalize them to the
14627 bitwise variant. */
14628 switch (TREE_CODE (*expr_p
))
14630 case TRUTH_AND_EXPR
:
14631 TREE_SET_CODE (*expr_p
, BIT_AND_EXPR
);
14633 case TRUTH_OR_EXPR
:
14634 TREE_SET_CODE (*expr_p
, BIT_IOR_EXPR
);
14636 case TRUTH_XOR_EXPR
:
14637 TREE_SET_CODE (*expr_p
, BIT_XOR_EXPR
);
14642 /* Now make sure that operands have compatible type to
14643 expression's new_type. */
14644 xop0
= TREE_OPERAND (*expr_p
, 0);
14645 xop1
= TREE_OPERAND (*expr_p
, 1);
14646 if (!useless_type_conversion_p (new_type
, TREE_TYPE (xop0
)))
14647 TREE_OPERAND (*expr_p
, 0) = fold_convert_loc (input_location
,
14650 if (!useless_type_conversion_p (new_type
, TREE_TYPE (xop1
)))
14651 TREE_OPERAND (*expr_p
, 1) = fold_convert_loc (input_location
,
14654 /* Continue classified as tcc_binary. */
14658 case VEC_COND_EXPR
:
14661 case VEC_PERM_EXPR
:
14662 /* Classified as tcc_expression. */
14665 case BIT_INSERT_EXPR
:
14666 /* Argument 3 is a constant. */
14669 case POINTER_PLUS_EXPR
:
14671 enum gimplify_status r0
, r1
;
14672 r0
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
14673 post_p
, is_gimple_val
, fb_rvalue
);
14674 r1
= gimplify_expr (&TREE_OPERAND (*expr_p
, 1), pre_p
,
14675 post_p
, is_gimple_val
, fb_rvalue
);
14676 recalculate_side_effects (*expr_p
);
14677 ret
= MIN (r0
, r1
);
14682 switch (TREE_CODE_CLASS (TREE_CODE (*expr_p
)))
14684 case tcc_comparison
:
14685 /* Handle comparison of objects of non scalar mode aggregates
14686 with a call to memcmp. It would be nice to only have to do
14687 this for variable-sized objects, but then we'd have to allow
14688 the same nest of reference nodes we allow for MODIFY_EXPR and
14689 that's too complex.
14691 Compare scalar mode aggregates as scalar mode values. Using
14692 memcmp for them would be very inefficient at best, and is
14693 plain wrong if bitfields are involved. */
14695 tree type
= TREE_TYPE (TREE_OPERAND (*expr_p
, 1));
14697 /* Vector comparisons need no boolification. */
14698 if (TREE_CODE (type
) == VECTOR_TYPE
)
14700 else if (!AGGREGATE_TYPE_P (type
))
14702 tree org_type
= TREE_TYPE (*expr_p
);
14703 *expr_p
= gimple_boolify (*expr_p
);
14704 if (!useless_type_conversion_p (org_type
,
14705 TREE_TYPE (*expr_p
)))
14707 *expr_p
= fold_convert_loc (input_location
,
14708 org_type
, *expr_p
);
14714 else if (TYPE_MODE (type
) != BLKmode
)
14715 ret
= gimplify_scalar_mode_aggregate_compare (expr_p
);
14717 ret
= gimplify_variable_sized_compare (expr_p
);
14722 /* If *EXPR_P does not need to be special-cased, handle it
14723 according to its class. */
14725 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
14726 post_p
, is_gimple_val
, fb_rvalue
);
14732 enum gimplify_status r0
, r1
;
14734 r0
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
14735 post_p
, is_gimple_val
, fb_rvalue
);
14736 r1
= gimplify_expr (&TREE_OPERAND (*expr_p
, 1), pre_p
,
14737 post_p
, is_gimple_val
, fb_rvalue
);
14739 ret
= MIN (r0
, r1
);
14745 enum gimplify_status r0
, r1
, r2
;
14747 r0
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
14748 post_p
, is_gimple_val
, fb_rvalue
);
14749 r1
= gimplify_expr (&TREE_OPERAND (*expr_p
, 1), pre_p
,
14750 post_p
, is_gimple_val
, fb_rvalue
);
14751 r2
= gimplify_expr (&TREE_OPERAND (*expr_p
, 2), pre_p
,
14752 post_p
, is_gimple_val
, fb_rvalue
);
14754 ret
= MIN (MIN (r0
, r1
), r2
);
14758 case tcc_declaration
:
14761 goto dont_recalculate
;
14764 gcc_unreachable ();
14767 recalculate_side_effects (*expr_p
);
14773 gcc_assert (*expr_p
|| ret
!= GS_OK
);
14775 while (ret
== GS_OK
);
14777 /* If we encountered an error_mark somewhere nested inside, either
14778 stub out the statement or propagate the error back out. */
14779 if (ret
== GS_ERROR
)
14786 /* This was only valid as a return value from the langhook, which
14787 we handled. Make sure it doesn't escape from any other context. */
14788 gcc_assert (ret
!= GS_UNHANDLED
);
14790 if (fallback
== fb_none
&& *expr_p
&& !is_gimple_stmt (*expr_p
))
14792 /* We aren't looking for a value, and we don't have a valid
14793 statement. If it doesn't have side-effects, throw it away.
14794 We can also get here with code such as "*&&L;", where L is
14795 a LABEL_DECL that is marked as FORCED_LABEL. */
14796 if (TREE_CODE (*expr_p
) == LABEL_DECL
14797 || !TREE_SIDE_EFFECTS (*expr_p
))
14799 else if (!TREE_THIS_VOLATILE (*expr_p
))
14801 /* This is probably a _REF that contains something nested that
14802 has side effects. Recurse through the operands to find it. */
14803 enum tree_code code
= TREE_CODE (*expr_p
);
14807 case COMPONENT_REF
:
14808 case REALPART_EXPR
:
14809 case IMAGPART_EXPR
:
14810 case VIEW_CONVERT_EXPR
:
14811 gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
14812 gimple_test_f
, fallback
);
14816 case ARRAY_RANGE_REF
:
14817 gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
14818 gimple_test_f
, fallback
);
14819 gimplify_expr (&TREE_OPERAND (*expr_p
, 1), pre_p
, post_p
,
14820 gimple_test_f
, fallback
);
14824 /* Anything else with side-effects must be converted to
14825 a valid statement before we get here. */
14826 gcc_unreachable ();
14831 else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p
))
14832 && TYPE_MODE (TREE_TYPE (*expr_p
)) != BLKmode
)
14834 /* Historically, the compiler has treated a bare reference
14835 to a non-BLKmode volatile lvalue as forcing a load. */
14836 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p
));
14838 /* Normally, we do not want to create a temporary for a
14839 TREE_ADDRESSABLE type because such a type should not be
14840 copied by bitwise-assignment. However, we make an
14841 exception here, as all we are doing here is ensuring that
14842 we read the bytes that make up the type. We use
14843 create_tmp_var_raw because create_tmp_var will abort when
14844 given a TREE_ADDRESSABLE type. */
14845 tree tmp
= create_tmp_var_raw (type
, "vol");
14846 gimple_add_tmp_var (tmp
);
14847 gimplify_assign (tmp
, *expr_p
, pre_p
);
14851 /* We can't do anything useful with a volatile reference to
14852 an incomplete type, so just throw it away. Likewise for
14853 a BLKmode type, since any implicit inner load should
14854 already have been turned into an explicit one by the
14855 gimplification process. */
14859 /* If we are gimplifying at the statement level, we're done. Tack
14860 everything together and return. */
14861 if (fallback
== fb_none
|| is_statement
)
14863 /* Since *EXPR_P has been converted into a GIMPLE tuple, clear
14864 it out for GC to reclaim it. */
14865 *expr_p
= NULL_TREE
;
14867 if (!gimple_seq_empty_p (internal_pre
)
14868 || !gimple_seq_empty_p (internal_post
))
14870 gimplify_seq_add_seq (&internal_pre
, internal_post
);
14871 gimplify_seq_add_seq (pre_p
, internal_pre
);
14874 /* The result of gimplifying *EXPR_P is going to be the last few
14875 statements in *PRE_P and *POST_P. Add location information
14876 to all the statements that were added by the gimplification
14878 if (!gimple_seq_empty_p (*pre_p
))
14879 annotate_all_with_location_after (*pre_p
, pre_last_gsi
, input_location
);
14881 if (!gimple_seq_empty_p (*post_p
))
14882 annotate_all_with_location_after (*post_p
, post_last_gsi
,
14888 #ifdef ENABLE_GIMPLE_CHECKING
14891 enum tree_code code
= TREE_CODE (*expr_p
);
14892 /* These expressions should already be in gimple IR form. */
14893 gcc_assert (code
!= MODIFY_EXPR
14894 && code
!= ASM_EXPR
14895 && code
!= BIND_EXPR
14896 && code
!= CATCH_EXPR
14897 && (code
!= COND_EXPR
|| gimplify_ctxp
->allow_rhs_cond_expr
)
14898 && code
!= EH_FILTER_EXPR
14899 && code
!= GOTO_EXPR
14900 && code
!= LABEL_EXPR
14901 && code
!= LOOP_EXPR
14902 && code
!= SWITCH_EXPR
14903 && code
!= TRY_FINALLY_EXPR
14904 && code
!= EH_ELSE_EXPR
14905 && code
!= OACC_PARALLEL
14906 && code
!= OACC_KERNELS
14907 && code
!= OACC_SERIAL
14908 && code
!= OACC_DATA
14909 && code
!= OACC_HOST_DATA
14910 && code
!= OACC_DECLARE
14911 && code
!= OACC_UPDATE
14912 && code
!= OACC_ENTER_DATA
14913 && code
!= OACC_EXIT_DATA
14914 && code
!= OACC_CACHE
14915 && code
!= OMP_CRITICAL
14917 && code
!= OACC_LOOP
14918 && code
!= OMP_MASTER
14919 && code
!= OMP_TASKGROUP
14920 && code
!= OMP_ORDERED
14921 && code
!= OMP_PARALLEL
14922 && code
!= OMP_SCAN
14923 && code
!= OMP_SECTIONS
14924 && code
!= OMP_SECTION
14925 && code
!= OMP_SINGLE
);
14929 /* Otherwise we're gimplifying a subexpression, so the resulting
14930 value is interesting. If it's a valid operand that matches
14931 GIMPLE_TEST_F, we're done. Unless we are handling some
14932 post-effects internally; if that's the case, we need to copy into
14933 a temporary before adding the post-effects to POST_P. */
14934 if (gimple_seq_empty_p (internal_post
) && (*gimple_test_f
) (*expr_p
))
14937 /* Otherwise, we need to create a new temporary for the gimplified
14940 /* We can't return an lvalue if we have an internal postqueue. The
14941 object the lvalue refers to would (probably) be modified by the
14942 postqueue; we need to copy the value out first, which means an
14944 if ((fallback
& fb_lvalue
)
14945 && gimple_seq_empty_p (internal_post
)
14946 && is_gimple_addressable (*expr_p
))
14948 /* An lvalue will do. Take the address of the expression, store it
14949 in a temporary, and replace the expression with an INDIRECT_REF of
14951 tree ref_alias_type
= reference_alias_ptr_type (*expr_p
);
14952 unsigned int ref_align
= get_object_alignment (*expr_p
);
14953 tree ref_type
= TREE_TYPE (*expr_p
);
14954 tmp
= build_fold_addr_expr_loc (input_location
, *expr_p
);
14955 gimplify_expr (&tmp
, pre_p
, post_p
, is_gimple_reg
, fb_rvalue
);
14956 if (TYPE_ALIGN (ref_type
) != ref_align
)
14957 ref_type
= build_aligned_type (ref_type
, ref_align
);
14958 *expr_p
= build2 (MEM_REF
, ref_type
,
14959 tmp
, build_zero_cst (ref_alias_type
));
14961 else if ((fallback
& fb_rvalue
) && is_gimple_reg_rhs_or_call (*expr_p
))
14963 /* An rvalue will do. Assign the gimplified expression into a
14964 new temporary TMP and replace the original expression with
14965 TMP. First, make sure that the expression has a type so that
14966 it can be assigned into a temporary. */
14967 gcc_assert (!VOID_TYPE_P (TREE_TYPE (*expr_p
)));
14968 *expr_p
= get_formal_tmp_var (*expr_p
, pre_p
);
14972 #ifdef ENABLE_GIMPLE_CHECKING
14973 if (!(fallback
& fb_mayfail
))
14975 fprintf (stderr
, "gimplification failed:\n");
14976 print_generic_expr (stderr
, *expr_p
);
14977 debug_tree (*expr_p
);
14978 internal_error ("gimplification failed");
14981 gcc_assert (fallback
& fb_mayfail
);
14983 /* If this is an asm statement, and the user asked for the
14984 impossible, don't die. Fail and let gimplify_asm_expr
14990 /* Make sure the temporary matches our predicate. */
14991 gcc_assert ((*gimple_test_f
) (*expr_p
));
14993 if (!gimple_seq_empty_p (internal_post
))
14995 annotate_all_with_location (internal_post
, input_location
);
14996 gimplify_seq_add_seq (pre_p
, internal_post
);
15000 input_location
= saved_location
;
15004 /* Like gimplify_expr but make sure the gimplified result is not itself
15005 a SSA name (but a decl if it were). Temporaries required by
15006 evaluating *EXPR_P may be still SSA names. */
15008 static enum gimplify_status
15009 gimplify_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
15010 bool (*gimple_test_f
) (tree
), fallback_t fallback
,
15013 bool was_ssa_name_p
= TREE_CODE (*expr_p
) == SSA_NAME
;
15014 enum gimplify_status ret
= gimplify_expr (expr_p
, pre_p
, post_p
,
15015 gimple_test_f
, fallback
);
15017 && TREE_CODE (*expr_p
) == SSA_NAME
)
15019 tree name
= *expr_p
;
15020 if (was_ssa_name_p
)
15021 *expr_p
= get_initialized_tmp_var (*expr_p
, pre_p
, NULL
, false);
15024 /* Avoid the extra copy if possible. */
15025 *expr_p
= create_tmp_reg (TREE_TYPE (name
));
15026 if (!gimple_nop_p (SSA_NAME_DEF_STMT (name
)))
15027 gimple_set_lhs (SSA_NAME_DEF_STMT (name
), *expr_p
);
15028 release_ssa_name (name
);
15034 /* Look through TYPE for variable-sized objects and gimplify each such
15035 size that we find. Add to LIST_P any statements generated. */
15038 gimplify_type_sizes (tree type
, gimple_seq
*list_p
)
15042 if (type
== NULL
|| type
== error_mark_node
)
15045 /* We first do the main variant, then copy into any other variants. */
15046 type
= TYPE_MAIN_VARIANT (type
);
15048 /* Avoid infinite recursion. */
15049 if (TYPE_SIZES_GIMPLIFIED (type
))
15052 TYPE_SIZES_GIMPLIFIED (type
) = 1;
15054 switch (TREE_CODE (type
))
15057 case ENUMERAL_TYPE
:
15060 case FIXED_POINT_TYPE
:
15061 gimplify_one_sizepos (&TYPE_MIN_VALUE (type
), list_p
);
15062 gimplify_one_sizepos (&TYPE_MAX_VALUE (type
), list_p
);
15064 for (t
= TYPE_NEXT_VARIANT (type
); t
; t
= TYPE_NEXT_VARIANT (t
))
15066 TYPE_MIN_VALUE (t
) = TYPE_MIN_VALUE (type
);
15067 TYPE_MAX_VALUE (t
) = TYPE_MAX_VALUE (type
);
15072 /* These types may not have declarations, so handle them here. */
15073 gimplify_type_sizes (TREE_TYPE (type
), list_p
);
15074 gimplify_type_sizes (TYPE_DOMAIN (type
), list_p
);
15075 /* Ensure VLA bounds aren't removed, for -O0 they should be variables
15076 with assigned stack slots, for -O1+ -g they should be tracked
15078 if (!(TYPE_NAME (type
)
15079 && TREE_CODE (TYPE_NAME (type
)) == TYPE_DECL
15080 && DECL_IGNORED_P (TYPE_NAME (type
)))
15081 && TYPE_DOMAIN (type
)
15082 && INTEGRAL_TYPE_P (TYPE_DOMAIN (type
)))
15084 t
= TYPE_MIN_VALUE (TYPE_DOMAIN (type
));
15085 if (t
&& VAR_P (t
) && DECL_ARTIFICIAL (t
))
15086 DECL_IGNORED_P (t
) = 0;
15087 t
= TYPE_MAX_VALUE (TYPE_DOMAIN (type
));
15088 if (t
&& VAR_P (t
) && DECL_ARTIFICIAL (t
))
15089 DECL_IGNORED_P (t
) = 0;
15095 case QUAL_UNION_TYPE
:
15096 for (field
= TYPE_FIELDS (type
); field
; field
= DECL_CHAIN (field
))
15097 if (TREE_CODE (field
) == FIELD_DECL
)
15099 gimplify_one_sizepos (&DECL_FIELD_OFFSET (field
), list_p
);
15100 gimplify_one_sizepos (&DECL_SIZE (field
), list_p
);
15101 gimplify_one_sizepos (&DECL_SIZE_UNIT (field
), list_p
);
15102 gimplify_type_sizes (TREE_TYPE (field
), list_p
);
15107 case REFERENCE_TYPE
:
15108 /* We used to recurse on the pointed-to type here, which turned out to
15109 be incorrect because its definition might refer to variables not
15110 yet initialized at this point if a forward declaration is involved.
15112 It was actually useful for anonymous pointed-to types to ensure
15113 that the sizes evaluation dominates every possible later use of the
15114 values. Restricting to such types here would be safe since there
15115 is no possible forward declaration around, but would introduce an
15116 undesirable middle-end semantic to anonymity. We then defer to
15117 front-ends the responsibility of ensuring that the sizes are
15118 evaluated both early and late enough, e.g. by attaching artificial
15119 type declarations to the tree. */
15126 gimplify_one_sizepos (&TYPE_SIZE (type
), list_p
);
15127 gimplify_one_sizepos (&TYPE_SIZE_UNIT (type
), list_p
);
15129 for (t
= TYPE_NEXT_VARIANT (type
); t
; t
= TYPE_NEXT_VARIANT (t
))
15131 TYPE_SIZE (t
) = TYPE_SIZE (type
);
15132 TYPE_SIZE_UNIT (t
) = TYPE_SIZE_UNIT (type
);
15133 TYPE_SIZES_GIMPLIFIED (t
) = 1;
15137 /* A subroutine of gimplify_type_sizes to make sure that *EXPR_P,
15138 a size or position, has had all of its SAVE_EXPRs evaluated.
15139 We add any required statements to *STMT_P. */
15142 gimplify_one_sizepos (tree
*expr_p
, gimple_seq
*stmt_p
)
15144 tree expr
= *expr_p
;
15146 /* We don't do anything if the value isn't there, is constant, or contains
15147 A PLACEHOLDER_EXPR. We also don't want to do anything if it's already
15148 a VAR_DECL. If it's a VAR_DECL from another function, the gimplifier
15149 will want to replace it with a new variable, but that will cause problems
15150 if this type is from outside the function. It's OK to have that here. */
15151 if (expr
== NULL_TREE
15152 || is_gimple_constant (expr
)
15153 || TREE_CODE (expr
) == VAR_DECL
15154 || CONTAINS_PLACEHOLDER_P (expr
))
15157 *expr_p
= unshare_expr (expr
);
15159 /* SSA names in decl/type fields are a bad idea - they'll get reclaimed
15160 if the def vanishes. */
15161 gimplify_expr (expr_p
, stmt_p
, NULL
, is_gimple_val
, fb_rvalue
, false);
15163 /* If expr wasn't already is_gimple_sizepos or is_gimple_constant from the
15164 FE, ensure that it is a VAR_DECL, otherwise we might handle some decls
15165 as gimplify_vla_decl even when they would have all sizes INTEGER_CSTs. */
15166 if (is_gimple_constant (*expr_p
))
15167 *expr_p
= get_initialized_tmp_var (*expr_p
, stmt_p
, NULL
, false);
15170 /* Gimplify the body of statements of FNDECL and return a GIMPLE_BIND node
15171 containing the sequence of corresponding GIMPLE statements. If DO_PARMS
15172 is true, also gimplify the parameters. */
15175 gimplify_body (tree fndecl
, bool do_parms
)
15177 location_t saved_location
= input_location
;
15178 gimple_seq parm_stmts
, parm_cleanup
= NULL
, seq
;
15179 gimple
*outer_stmt
;
15182 timevar_push (TV_TREE_GIMPLIFY
);
15184 init_tree_ssa (cfun
);
15186 /* Initialize for optimize_insn_for_s{ize,peed}_p possibly called during
15188 default_rtl_profile ();
15190 gcc_assert (gimplify_ctxp
== NULL
);
15191 push_gimplify_context (true);
15193 if (flag_openacc
|| flag_openmp
)
15195 gcc_assert (gimplify_omp_ctxp
== NULL
);
15196 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (fndecl
)))
15197 gimplify_omp_ctxp
= new_omp_context (ORT_IMPLICIT_TARGET
);
15200 /* Unshare most shared trees in the body and in that of any nested functions.
15201 It would seem we don't have to do this for nested functions because
15202 they are supposed to be output and then the outer function gimplified
15203 first, but the g++ front end doesn't always do it that way. */
15204 unshare_body (fndecl
);
15205 unvisit_body (fndecl
);
15207 /* Make sure input_location isn't set to something weird. */
15208 input_location
= DECL_SOURCE_LOCATION (fndecl
);
15210 /* Resolve callee-copies. This has to be done before processing
15211 the body so that DECL_VALUE_EXPR gets processed correctly. */
15212 parm_stmts
= do_parms
? gimplify_parameters (&parm_cleanup
) : NULL
;
15214 /* Gimplify the function's body. */
15216 gimplify_stmt (&DECL_SAVED_TREE (fndecl
), &seq
);
15217 outer_stmt
= gimple_seq_first_nondebug_stmt (seq
);
15220 outer_stmt
= gimple_build_nop ();
15221 gimplify_seq_add_stmt (&seq
, outer_stmt
);
15224 /* The body must contain exactly one statement, a GIMPLE_BIND. If this is
15225 not the case, wrap everything in a GIMPLE_BIND to make it so. */
15226 if (gimple_code (outer_stmt
) == GIMPLE_BIND
15227 && (gimple_seq_first_nondebug_stmt (seq
)
15228 == gimple_seq_last_nondebug_stmt (seq
)))
15230 outer_bind
= as_a
<gbind
*> (outer_stmt
);
15231 if (gimple_seq_first_stmt (seq
) != outer_stmt
15232 || gimple_seq_last_stmt (seq
) != outer_stmt
)
15234 /* If there are debug stmts before or after outer_stmt, move them
15235 inside of outer_bind body. */
15236 gimple_stmt_iterator gsi
= gsi_for_stmt (outer_stmt
, &seq
);
15237 gimple_seq second_seq
= NULL
;
15238 if (gimple_seq_first_stmt (seq
) != outer_stmt
15239 && gimple_seq_last_stmt (seq
) != outer_stmt
)
15241 second_seq
= gsi_split_seq_after (gsi
);
15242 gsi_remove (&gsi
, false);
15244 else if (gimple_seq_first_stmt (seq
) != outer_stmt
)
15245 gsi_remove (&gsi
, false);
15248 gsi_remove (&gsi
, false);
15252 gimple_seq_add_seq_without_update (&seq
,
15253 gimple_bind_body (outer_bind
));
15254 gimple_seq_add_seq_without_update (&seq
, second_seq
);
15255 gimple_bind_set_body (outer_bind
, seq
);
15259 outer_bind
= gimple_build_bind (NULL_TREE
, seq
, NULL
);
15261 DECL_SAVED_TREE (fndecl
) = NULL_TREE
;
15263 /* If we had callee-copies statements, insert them at the beginning
15264 of the function and clear DECL_VALUE_EXPR_P on the parameters. */
15265 if (!gimple_seq_empty_p (parm_stmts
))
15269 gimplify_seq_add_seq (&parm_stmts
, gimple_bind_body (outer_bind
));
15272 gtry
*g
= gimple_build_try (parm_stmts
, parm_cleanup
,
15273 GIMPLE_TRY_FINALLY
);
15275 gimple_seq_add_stmt (&parm_stmts
, g
);
15277 gimple_bind_set_body (outer_bind
, parm_stmts
);
15279 for (parm
= DECL_ARGUMENTS (current_function_decl
);
15280 parm
; parm
= DECL_CHAIN (parm
))
15281 if (DECL_HAS_VALUE_EXPR_P (parm
))
15283 DECL_HAS_VALUE_EXPR_P (parm
) = 0;
15284 DECL_IGNORED_P (parm
) = 0;
15288 if ((flag_openacc
|| flag_openmp
|| flag_openmp_simd
)
15289 && gimplify_omp_ctxp
)
15291 delete_omp_context (gimplify_omp_ctxp
);
15292 gimplify_omp_ctxp
= NULL
;
15295 pop_gimplify_context (outer_bind
);
15296 gcc_assert (gimplify_ctxp
== NULL
);
15298 if (flag_checking
&& !seen_error ())
15299 verify_gimple_in_seq (gimple_bind_body (outer_bind
));
15301 timevar_pop (TV_TREE_GIMPLIFY
);
15302 input_location
= saved_location
;
15307 typedef char *char_p
; /* For DEF_VEC_P. */
15309 /* Return whether we should exclude FNDECL from instrumentation. */
15312 flag_instrument_functions_exclude_p (tree fndecl
)
15316 v
= (vec
<char_p
> *) flag_instrument_functions_exclude_functions
;
15317 if (v
&& v
->length () > 0)
15323 name
= lang_hooks
.decl_printable_name (fndecl
, 1);
15324 FOR_EACH_VEC_ELT (*v
, i
, s
)
15325 if (strstr (name
, s
) != NULL
)
15329 v
= (vec
<char_p
> *) flag_instrument_functions_exclude_files
;
15330 if (v
&& v
->length () > 0)
15336 name
= DECL_SOURCE_FILE (fndecl
);
15337 FOR_EACH_VEC_ELT (*v
, i
, s
)
15338 if (strstr (name
, s
) != NULL
)
15345 /* Entry point to the gimplification pass. FNDECL is the FUNCTION_DECL
15346 node for the function we want to gimplify.
15348 Return the sequence of GIMPLE statements corresponding to the body
15352 gimplify_function_tree (tree fndecl
)
15357 gcc_assert (!gimple_body (fndecl
));
15359 if (DECL_STRUCT_FUNCTION (fndecl
))
15360 push_cfun (DECL_STRUCT_FUNCTION (fndecl
));
15362 push_struct_function (fndecl
);
15364 /* Tentatively set PROP_gimple_lva here, and reset it in gimplify_va_arg_expr
15366 cfun
->curr_properties
|= PROP_gimple_lva
;
15368 if (asan_sanitize_use_after_scope () && sanitize_flags_p (SANITIZE_ADDRESS
))
15369 asan_poisoned_variables
= new hash_set
<tree
> ();
15370 bind
= gimplify_body (fndecl
, true);
15371 if (asan_poisoned_variables
)
15373 delete asan_poisoned_variables
;
15374 asan_poisoned_variables
= NULL
;
15377 /* The tree body of the function is no longer needed, replace it
15378 with the new GIMPLE body. */
15380 gimple_seq_add_stmt (&seq
, bind
);
15381 gimple_set_body (fndecl
, seq
);
15383 /* If we're instrumenting function entry/exit, then prepend the call to
15384 the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to
15385 catch the exit hook. */
15386 /* ??? Add some way to ignore exceptions for this TFE. */
15387 if (flag_instrument_function_entry_exit
15388 && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl
)
15389 /* Do not instrument extern inline functions. */
15390 && !(DECL_DECLARED_INLINE_P (fndecl
)
15391 && DECL_EXTERNAL (fndecl
)
15392 && DECL_DISREGARD_INLINE_LIMITS (fndecl
))
15393 && !flag_instrument_functions_exclude_p (fndecl
))
15398 gimple_seq cleanup
= NULL
, body
= NULL
;
15399 tree tmp_var
, this_fn_addr
;
15402 /* The instrumentation hooks aren't going to call the instrumented
15403 function and the address they receive is expected to be matchable
15404 against symbol addresses. Make sure we don't create a trampoline,
15405 in case the current function is nested. */
15406 this_fn_addr
= build_fold_addr_expr (current_function_decl
);
15407 TREE_NO_TRAMPOLINE (this_fn_addr
) = 1;
15409 x
= builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS
);
15410 call
= gimple_build_call (x
, 1, integer_zero_node
);
15411 tmp_var
= create_tmp_var (ptr_type_node
, "return_addr");
15412 gimple_call_set_lhs (call
, tmp_var
);
15413 gimplify_seq_add_stmt (&cleanup
, call
);
15414 x
= builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_EXIT
);
15415 call
= gimple_build_call (x
, 2, this_fn_addr
, tmp_var
);
15416 gimplify_seq_add_stmt (&cleanup
, call
);
15417 tf
= gimple_build_try (seq
, cleanup
, GIMPLE_TRY_FINALLY
);
15419 x
= builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS
);
15420 call
= gimple_build_call (x
, 1, integer_zero_node
);
15421 tmp_var
= create_tmp_var (ptr_type_node
, "return_addr");
15422 gimple_call_set_lhs (call
, tmp_var
);
15423 gimplify_seq_add_stmt (&body
, call
);
15424 x
= builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_ENTER
);
15425 call
= gimple_build_call (x
, 2, this_fn_addr
, tmp_var
);
15426 gimplify_seq_add_stmt (&body
, call
);
15427 gimplify_seq_add_stmt (&body
, tf
);
15428 new_bind
= gimple_build_bind (NULL
, body
, NULL
);
15430 /* Replace the current function body with the body
15431 wrapped in the try/finally TF. */
15433 gimple_seq_add_stmt (&seq
, new_bind
);
15434 gimple_set_body (fndecl
, seq
);
15438 if (sanitize_flags_p (SANITIZE_THREAD
)
15439 && param_tsan_instrument_func_entry_exit
)
15441 gcall
*call
= gimple_build_call_internal (IFN_TSAN_FUNC_EXIT
, 0);
15442 gimple
*tf
= gimple_build_try (seq
, call
, GIMPLE_TRY_FINALLY
);
15443 gbind
*new_bind
= gimple_build_bind (NULL
, tf
, NULL
);
15444 /* Replace the current function body with the body
15445 wrapped in the try/finally TF. */
15447 gimple_seq_add_stmt (&seq
, new_bind
);
15448 gimple_set_body (fndecl
, seq
);
15451 DECL_SAVED_TREE (fndecl
) = NULL_TREE
;
15452 cfun
->curr_properties
|= PROP_gimple_any
;
15456 dump_function (TDI_gimple
, fndecl
);
15459 /* Return a dummy expression of type TYPE in order to keep going after an
15463 dummy_object (tree type
)
15465 tree t
= build_int_cst (build_pointer_type (type
), 0);
15466 return build2 (MEM_REF
, type
, t
, t
);
15469 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
15470 builtin function, but a very special sort of operator. */
15472 enum gimplify_status
15473 gimplify_va_arg_expr (tree
*expr_p
, gimple_seq
*pre_p
,
15474 gimple_seq
*post_p ATTRIBUTE_UNUSED
)
15476 tree promoted_type
, have_va_type
;
15477 tree valist
= TREE_OPERAND (*expr_p
, 0);
15478 tree type
= TREE_TYPE (*expr_p
);
15479 tree t
, tag
, aptag
;
15480 location_t loc
= EXPR_LOCATION (*expr_p
);
15482 /* Verify that valist is of the proper type. */
15483 have_va_type
= TREE_TYPE (valist
);
15484 if (have_va_type
== error_mark_node
)
15486 have_va_type
= targetm
.canonical_va_list_type (have_va_type
);
15487 if (have_va_type
== NULL_TREE
15488 && POINTER_TYPE_P (TREE_TYPE (valist
)))
15489 /* Handle 'Case 1: Not an array type' from c-common.c/build_va_arg. */
15491 = targetm
.canonical_va_list_type (TREE_TYPE (TREE_TYPE (valist
)));
15492 gcc_assert (have_va_type
!= NULL_TREE
);
15494 /* Generate a diagnostic for requesting data of a type that cannot
15495 be passed through `...' due to type promotion at the call site. */
15496 if ((promoted_type
= lang_hooks
.types
.type_promotes_to (type
))
15499 static bool gave_help
;
15501 /* Use the expansion point to handle cases such as passing bool (defined
15502 in a system header) through `...'. */
15504 = expansion_point_location_if_in_system_header (loc
);
15506 /* Unfortunately, this is merely undefined, rather than a constraint
15507 violation, so we cannot make this an error. If this call is never
15508 executed, the program is still strictly conforming. */
15509 auto_diagnostic_group d
;
15510 warned
= warning_at (xloc
, 0,
15511 "%qT is promoted to %qT when passed through %<...%>",
15512 type
, promoted_type
);
15513 if (!gave_help
&& warned
)
15516 inform (xloc
, "(so you should pass %qT not %qT to %<va_arg%>)",
15517 promoted_type
, type
);
15520 /* We can, however, treat "undefined" any way we please.
15521 Call abort to encourage the user to fix the program. */
15523 inform (xloc
, "if this code is reached, the program will abort");
15524 /* Before the abort, allow the evaluation of the va_list
15525 expression to exit or longjmp. */
15526 gimplify_and_add (valist
, pre_p
);
15527 t
= build_call_expr_loc (loc
,
15528 builtin_decl_implicit (BUILT_IN_TRAP
), 0);
15529 gimplify_and_add (t
, pre_p
);
15531 /* This is dead code, but go ahead and finish so that the
15532 mode of the result comes out right. */
15533 *expr_p
= dummy_object (type
);
15534 return GS_ALL_DONE
;
15537 tag
= build_int_cst (build_pointer_type (type
), 0);
15538 aptag
= build_int_cst (TREE_TYPE (valist
), 0);
15540 *expr_p
= build_call_expr_internal_loc (loc
, IFN_VA_ARG
, type
, 3,
15541 valist
, tag
, aptag
);
15543 /* Clear the tentatively set PROP_gimple_lva, to indicate that IFN_VA_ARG
15544 needs to be expanded. */
15545 cfun
->curr_properties
&= ~PROP_gimple_lva
;
15550 /* Build a new GIMPLE_ASSIGN tuple and append it to the end of *SEQ_P.
15552 DST/SRC are the destination and source respectively. You can pass
15553 ungimplified trees in DST or SRC, in which case they will be
15554 converted to a gimple operand if necessary.
15556 This function returns the newly created GIMPLE_ASSIGN tuple. */
15559 gimplify_assign (tree dst
, tree src
, gimple_seq
*seq_p
)
15561 tree t
= build2 (MODIFY_EXPR
, TREE_TYPE (dst
), dst
, src
);
15562 gimplify_and_add (t
, seq_p
);
15564 return gimple_seq_last_stmt (*seq_p
);
15568 gimplify_hasher::hash (const elt_t
*p
)
15571 return iterative_hash_expr (t
, 0);
15575 gimplify_hasher::equal (const elt_t
*p1
, const elt_t
*p2
)
15579 enum tree_code code
= TREE_CODE (t1
);
15581 if (TREE_CODE (t2
) != code
15582 || TREE_TYPE (t1
) != TREE_TYPE (t2
))
15585 if (!operand_equal_p (t1
, t2
, 0))
15588 /* Only allow them to compare equal if they also hash equal; otherwise
15589 results are nondeterminate, and we fail bootstrap comparison. */
15590 gcc_checking_assert (hash (p1
) == hash (p2
));