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 (code
== OMP_TASKLOOP
9908 && OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
)
9909 && (TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
))
9911 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
)
9912 = get_initialized_tmp_var (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
),
9913 pre_p
, NULL
, false);
9916 case OMP_CLAUSE_DEFAULT
:
9917 ctx
->default_kind
= OMP_CLAUSE_DEFAULT_KIND (c
);
9920 case OMP_CLAUSE_INCLUSIVE
:
9921 case OMP_CLAUSE_EXCLUSIVE
:
9922 decl
= OMP_CLAUSE_DECL (c
);
9924 splay_tree_node n
= splay_tree_lookup (outer_ctx
->variables
,
9925 (splay_tree_key
) decl
);
9926 if (n
== NULL
|| (n
->value
& GOVD_REDUCTION
) == 0)
9928 error_at (OMP_CLAUSE_LOCATION (c
),
9929 "%qD specified in %qs clause but not in %<inscan%> "
9930 "%<reduction%> clause on the containing construct",
9931 decl
, omp_clause_code_name
[OMP_CLAUSE_CODE (c
)]);
9936 n
->value
|= GOVD_REDUCTION_INSCAN
;
9937 if (outer_ctx
->region_type
== ORT_SIMD
9938 && outer_ctx
->outer_context
9939 && outer_ctx
->outer_context
->region_type
== ORT_WORKSHARE
)
9941 n
= splay_tree_lookup (outer_ctx
->outer_context
->variables
,
9942 (splay_tree_key
) decl
);
9943 if (n
&& (n
->value
& GOVD_REDUCTION
) != 0)
9944 n
->value
|= GOVD_REDUCTION_INSCAN
;
9954 if (code
== OACC_DATA
9955 && OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_MAP
9956 && (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_FIRSTPRIVATE_POINTER
9957 || OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
))
9960 *list_p
= OMP_CLAUSE_CHAIN (c
);
9962 list_p
= &OMP_CLAUSE_CHAIN (c
);
9965 ctx
->clauses
= *orig_list_p
;
9966 gimplify_omp_ctxp
= ctx
;
9967 if (struct_map_to_clause
)
9968 delete struct_map_to_clause
;
9969 if (struct_deref_set
)
9970 delete struct_deref_set
;
9973 /* Return true if DECL is a candidate for shared to firstprivate
9974 optimization. We only consider non-addressable scalars, not
9975 too big, and not references. */
9978 omp_shared_to_firstprivate_optimizable_decl_p (tree decl
)
9980 if (TREE_ADDRESSABLE (decl
))
9982 tree type
= TREE_TYPE (decl
);
9983 if (!is_gimple_reg_type (type
)
9984 || TREE_CODE (type
) == REFERENCE_TYPE
9985 || TREE_ADDRESSABLE (type
))
9987 /* Don't optimize too large decls, as each thread/task will have
9989 HOST_WIDE_INT len
= int_size_in_bytes (type
);
9990 if (len
== -1 || len
> 4 * POINTER_SIZE
/ BITS_PER_UNIT
)
9992 if (lang_hooks
.decls
.omp_privatize_by_reference (decl
))
9997 /* Helper function of omp_find_stores_op and gimplify_adjust_omp_clauses*.
9998 For omp_shared_to_firstprivate_optimizable_decl_p decl mark it as
9999 GOVD_WRITTEN in outer contexts. */
10002 omp_mark_stores (struct gimplify_omp_ctx
*ctx
, tree decl
)
10004 for (; ctx
; ctx
= ctx
->outer_context
)
10006 splay_tree_node n
= splay_tree_lookup (ctx
->variables
,
10007 (splay_tree_key
) decl
);
10010 else if (n
->value
& GOVD_SHARED
)
10012 n
->value
|= GOVD_WRITTEN
;
10015 else if (n
->value
& GOVD_DATA_SHARE_CLASS
)
10020 /* Helper callback for walk_gimple_seq to discover possible stores
10021 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
10022 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
10026 omp_find_stores_op (tree
*tp
, int *walk_subtrees
, void *data
)
10028 struct walk_stmt_info
*wi
= (struct walk_stmt_info
*) data
;
10030 *walk_subtrees
= 0;
10037 if (handled_component_p (op
))
10038 op
= TREE_OPERAND (op
, 0);
10039 else if ((TREE_CODE (op
) == MEM_REF
|| TREE_CODE (op
) == TARGET_MEM_REF
)
10040 && TREE_CODE (TREE_OPERAND (op
, 0)) == ADDR_EXPR
)
10041 op
= TREE_OPERAND (TREE_OPERAND (op
, 0), 0);
10046 if (!DECL_P (op
) || !omp_shared_to_firstprivate_optimizable_decl_p (op
))
10049 omp_mark_stores (gimplify_omp_ctxp
, op
);
10053 /* Helper callback for walk_gimple_seq to discover possible stores
10054 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
10055 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
10059 omp_find_stores_stmt (gimple_stmt_iterator
*gsi_p
,
10060 bool *handled_ops_p
,
10061 struct walk_stmt_info
*wi
)
10063 gimple
*stmt
= gsi_stmt (*gsi_p
);
10064 switch (gimple_code (stmt
))
10066 /* Don't recurse on OpenMP constructs for which
10067 gimplify_adjust_omp_clauses already handled the bodies,
10068 except handle gimple_omp_for_pre_body. */
10069 case GIMPLE_OMP_FOR
:
10070 *handled_ops_p
= true;
10071 if (gimple_omp_for_pre_body (stmt
))
10072 walk_gimple_seq (gimple_omp_for_pre_body (stmt
),
10073 omp_find_stores_stmt
, omp_find_stores_op
, wi
);
10075 case GIMPLE_OMP_PARALLEL
:
10076 case GIMPLE_OMP_TASK
:
10077 case GIMPLE_OMP_SECTIONS
:
10078 case GIMPLE_OMP_SINGLE
:
10079 case GIMPLE_OMP_TARGET
:
10080 case GIMPLE_OMP_TEAMS
:
10081 case GIMPLE_OMP_CRITICAL
:
10082 *handled_ops_p
= true;
10090 struct gimplify_adjust_omp_clauses_data
10096 /* For all variables that were not actually used within the context,
10097 remove PRIVATE, SHARED, and FIRSTPRIVATE clauses. */
10100 gimplify_adjust_omp_clauses_1 (splay_tree_node n
, void *data
)
10102 tree
*list_p
= ((struct gimplify_adjust_omp_clauses_data
*) data
)->list_p
;
10104 = ((struct gimplify_adjust_omp_clauses_data
*) data
)->pre_p
;
10105 tree decl
= (tree
) n
->key
;
10106 unsigned flags
= n
->value
;
10107 enum omp_clause_code code
;
10109 bool private_debug
;
10111 if (gimplify_omp_ctxp
->region_type
== ORT_COMBINED_PARALLEL
10112 && (flags
& GOVD_LASTPRIVATE_CONDITIONAL
) != 0)
10113 flags
= GOVD_SHARED
| GOVD_SEEN
| GOVD_WRITTEN
;
10114 if (flags
& (GOVD_EXPLICIT
| GOVD_LOCAL
))
10116 if ((flags
& GOVD_SEEN
) == 0)
10118 if ((flags
& GOVD_MAP_HAS_ATTACHMENTS
) != 0)
10120 if (flags
& GOVD_DEBUG_PRIVATE
)
10122 gcc_assert ((flags
& GOVD_DATA_SHARE_CLASS
) == GOVD_SHARED
);
10123 private_debug
= true;
10125 else if (flags
& GOVD_MAP
)
10126 private_debug
= false;
10129 = lang_hooks
.decls
.omp_private_debug_clause (decl
,
10130 !!(flags
& GOVD_SHARED
));
10132 code
= OMP_CLAUSE_PRIVATE
;
10133 else if (flags
& GOVD_MAP
)
10135 code
= OMP_CLAUSE_MAP
;
10136 if ((gimplify_omp_ctxp
->region_type
& ORT_ACC
) == 0
10137 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl
))))
10139 error ("%<_Atomic%> %qD in implicit %<map%> clause", decl
);
10143 && DECL_IN_CONSTANT_POOL (decl
)
10144 && !lookup_attribute ("omp declare target",
10145 DECL_ATTRIBUTES (decl
)))
10147 tree id
= get_identifier ("omp declare target");
10148 DECL_ATTRIBUTES (decl
)
10149 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (decl
));
10150 varpool_node
*node
= varpool_node::get (decl
);
10153 node
->offloadable
= 1;
10154 if (ENABLE_OFFLOADING
)
10155 g
->have_offload
= true;
10159 else if (flags
& GOVD_SHARED
)
10161 if (is_global_var (decl
))
10163 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
->outer_context
;
10164 while (ctx
!= NULL
)
10167 = splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
10168 if (on
&& (on
->value
& (GOVD_FIRSTPRIVATE
| GOVD_LASTPRIVATE
10169 | GOVD_PRIVATE
| GOVD_REDUCTION
10170 | GOVD_LINEAR
| GOVD_MAP
)) != 0)
10172 ctx
= ctx
->outer_context
;
10177 code
= OMP_CLAUSE_SHARED
;
10179 else if (flags
& GOVD_PRIVATE
)
10180 code
= OMP_CLAUSE_PRIVATE
;
10181 else if (flags
& GOVD_FIRSTPRIVATE
)
10183 code
= OMP_CLAUSE_FIRSTPRIVATE
;
10184 if ((gimplify_omp_ctxp
->region_type
& ORT_TARGET
)
10185 && (gimplify_omp_ctxp
->region_type
& ORT_ACC
) == 0
10186 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl
))))
10188 error ("%<_Atomic%> %qD in implicit %<firstprivate%> clause on "
10189 "%<target%> construct", decl
);
10193 else if (flags
& GOVD_LASTPRIVATE
)
10194 code
= OMP_CLAUSE_LASTPRIVATE
;
10195 else if (flags
& (GOVD_ALIGNED
| GOVD_NONTEMPORAL
))
10197 else if (flags
& GOVD_CONDTEMP
)
10199 code
= OMP_CLAUSE__CONDTEMP_
;
10200 gimple_add_tmp_var (decl
);
10203 gcc_unreachable ();
10205 if (((flags
& GOVD_LASTPRIVATE
)
10206 || (code
== OMP_CLAUSE_SHARED
&& (flags
& GOVD_WRITTEN
)))
10207 && omp_shared_to_firstprivate_optimizable_decl_p (decl
))
10208 omp_mark_stores (gimplify_omp_ctxp
->outer_context
, decl
);
10210 tree chain
= *list_p
;
10211 clause
= build_omp_clause (input_location
, code
);
10212 OMP_CLAUSE_DECL (clause
) = decl
;
10213 OMP_CLAUSE_CHAIN (clause
) = chain
;
10215 OMP_CLAUSE_PRIVATE_DEBUG (clause
) = 1;
10216 else if (code
== OMP_CLAUSE_PRIVATE
&& (flags
& GOVD_PRIVATE_OUTER_REF
))
10217 OMP_CLAUSE_PRIVATE_OUTER_REF (clause
) = 1;
10218 else if (code
== OMP_CLAUSE_SHARED
10219 && (flags
& GOVD_WRITTEN
) == 0
10220 && omp_shared_to_firstprivate_optimizable_decl_p (decl
))
10221 OMP_CLAUSE_SHARED_READONLY (clause
) = 1;
10222 else if (code
== OMP_CLAUSE_FIRSTPRIVATE
&& (flags
& GOVD_EXPLICIT
) == 0)
10223 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (clause
) = 1;
10224 else if (code
== OMP_CLAUSE_MAP
&& (flags
& GOVD_MAP_0LEN_ARRAY
) != 0)
10226 tree nc
= build_omp_clause (input_location
, OMP_CLAUSE_MAP
);
10227 OMP_CLAUSE_DECL (nc
) = decl
;
10228 if (TREE_CODE (TREE_TYPE (decl
)) == REFERENCE_TYPE
10229 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl
))) == POINTER_TYPE
)
10230 OMP_CLAUSE_DECL (clause
)
10231 = build_simple_mem_ref_loc (input_location
, decl
);
10232 OMP_CLAUSE_DECL (clause
)
10233 = build2 (MEM_REF
, char_type_node
, OMP_CLAUSE_DECL (clause
),
10234 build_int_cst (build_pointer_type (char_type_node
), 0));
10235 OMP_CLAUSE_SIZE (clause
) = size_zero_node
;
10236 OMP_CLAUSE_SIZE (nc
) = size_zero_node
;
10237 OMP_CLAUSE_SET_MAP_KIND (clause
, GOMP_MAP_ALLOC
);
10238 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (clause
) = 1;
10239 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_FIRSTPRIVATE_POINTER
);
10240 OMP_CLAUSE_CHAIN (nc
) = chain
;
10241 OMP_CLAUSE_CHAIN (clause
) = nc
;
10242 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
10243 gimplify_omp_ctxp
= ctx
->outer_context
;
10244 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (clause
), 0),
10245 pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
10246 gimplify_omp_ctxp
= ctx
;
10248 else if (code
== OMP_CLAUSE_MAP
)
10251 /* Not all combinations of these GOVD_MAP flags are actually valid. */
10252 switch (flags
& (GOVD_MAP_TO_ONLY
10254 | GOVD_MAP_FORCE_PRESENT
10255 | GOVD_MAP_ALLOC_ONLY
10256 | GOVD_MAP_FROM_ONLY
))
10259 kind
= GOMP_MAP_TOFROM
;
10261 case GOVD_MAP_FORCE
:
10262 kind
= GOMP_MAP_TOFROM
| GOMP_MAP_FLAG_FORCE
;
10264 case GOVD_MAP_TO_ONLY
:
10265 kind
= GOMP_MAP_TO
;
10267 case GOVD_MAP_FROM_ONLY
:
10268 kind
= GOMP_MAP_FROM
;
10270 case GOVD_MAP_ALLOC_ONLY
:
10271 kind
= GOMP_MAP_ALLOC
;
10273 case GOVD_MAP_TO_ONLY
| GOVD_MAP_FORCE
:
10274 kind
= GOMP_MAP_TO
| GOMP_MAP_FLAG_FORCE
;
10276 case GOVD_MAP_FORCE_PRESENT
:
10277 kind
= GOMP_MAP_FORCE_PRESENT
;
10280 gcc_unreachable ();
10282 OMP_CLAUSE_SET_MAP_KIND (clause
, kind
);
10283 if (DECL_SIZE (decl
)
10284 && TREE_CODE (DECL_SIZE (decl
)) != INTEGER_CST
)
10286 tree decl2
= DECL_VALUE_EXPR (decl
);
10287 gcc_assert (TREE_CODE (decl2
) == INDIRECT_REF
);
10288 decl2
= TREE_OPERAND (decl2
, 0);
10289 gcc_assert (DECL_P (decl2
));
10290 tree mem
= build_simple_mem_ref (decl2
);
10291 OMP_CLAUSE_DECL (clause
) = mem
;
10292 OMP_CLAUSE_SIZE (clause
) = TYPE_SIZE_UNIT (TREE_TYPE (decl
));
10293 if (gimplify_omp_ctxp
->outer_context
)
10295 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
->outer_context
;
10296 omp_notice_variable (ctx
, decl2
, true);
10297 omp_notice_variable (ctx
, OMP_CLAUSE_SIZE (clause
), true);
10299 tree nc
= build_omp_clause (OMP_CLAUSE_LOCATION (clause
),
10301 OMP_CLAUSE_DECL (nc
) = decl
;
10302 OMP_CLAUSE_SIZE (nc
) = size_zero_node
;
10303 if (gimplify_omp_ctxp
->target_firstprivatize_array_bases
)
10304 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_FIRSTPRIVATE_POINTER
);
10306 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_POINTER
);
10307 OMP_CLAUSE_CHAIN (nc
) = OMP_CLAUSE_CHAIN (clause
);
10308 OMP_CLAUSE_CHAIN (clause
) = nc
;
10310 else if (gimplify_omp_ctxp
->target_firstprivatize_array_bases
10311 && lang_hooks
.decls
.omp_privatize_by_reference (decl
))
10313 OMP_CLAUSE_DECL (clause
) = build_simple_mem_ref (decl
);
10314 OMP_CLAUSE_SIZE (clause
)
10315 = unshare_expr (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl
))));
10316 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
10317 gimplify_omp_ctxp
= ctx
->outer_context
;
10318 gimplify_expr (&OMP_CLAUSE_SIZE (clause
),
10319 pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
10320 gimplify_omp_ctxp
= ctx
;
10321 tree nc
= build_omp_clause (OMP_CLAUSE_LOCATION (clause
),
10323 OMP_CLAUSE_DECL (nc
) = decl
;
10324 OMP_CLAUSE_SIZE (nc
) = size_zero_node
;
10325 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_FIRSTPRIVATE_REFERENCE
);
10326 OMP_CLAUSE_CHAIN (nc
) = OMP_CLAUSE_CHAIN (clause
);
10327 OMP_CLAUSE_CHAIN (clause
) = nc
;
10330 OMP_CLAUSE_SIZE (clause
) = DECL_SIZE_UNIT (decl
);
10332 if (code
== OMP_CLAUSE_FIRSTPRIVATE
&& (flags
& GOVD_LASTPRIVATE
) != 0)
10334 tree nc
= build_omp_clause (input_location
, OMP_CLAUSE_LASTPRIVATE
);
10335 OMP_CLAUSE_DECL (nc
) = decl
;
10336 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (nc
) = 1;
10337 OMP_CLAUSE_CHAIN (nc
) = chain
;
10338 OMP_CLAUSE_CHAIN (clause
) = nc
;
10339 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
10340 gimplify_omp_ctxp
= ctx
->outer_context
;
10341 lang_hooks
.decls
.omp_finish_clause (nc
, pre_p
,
10342 (ctx
->region_type
& ORT_ACC
) != 0);
10343 gimplify_omp_ctxp
= ctx
;
10346 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
10347 gimplify_omp_ctxp
= ctx
->outer_context
;
10348 lang_hooks
.decls
.omp_finish_clause (clause
, pre_p
,
10349 (ctx
->region_type
& ORT_ACC
) != 0);
10350 if (gimplify_omp_ctxp
)
10351 for (; clause
!= chain
; clause
= OMP_CLAUSE_CHAIN (clause
))
10352 if (OMP_CLAUSE_CODE (clause
) == OMP_CLAUSE_MAP
10353 && DECL_P (OMP_CLAUSE_SIZE (clause
)))
10354 omp_notice_variable (gimplify_omp_ctxp
, OMP_CLAUSE_SIZE (clause
),
10356 gimplify_omp_ctxp
= ctx
;
10361 gimplify_adjust_omp_clauses (gimple_seq
*pre_p
, gimple_seq body
, tree
*list_p
,
10362 enum tree_code code
)
10364 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
10365 tree
*orig_list_p
= list_p
;
10367 bool has_inscan_reductions
= false;
10371 struct gimplify_omp_ctx
*octx
;
10372 for (octx
= ctx
; octx
; octx
= octx
->outer_context
)
10373 if ((octx
->region_type
& (ORT_PARALLEL
| ORT_TASK
| ORT_TEAMS
)) != 0)
10377 struct walk_stmt_info wi
;
10378 memset (&wi
, 0, sizeof (wi
));
10379 walk_gimple_seq (body
, omp_find_stores_stmt
,
10380 omp_find_stores_op
, &wi
);
10384 if (ctx
->add_safelen1
)
10386 /* If there are VLAs in the body of simd loop, prevent
10388 gcc_assert (ctx
->region_type
== ORT_SIMD
);
10389 c
= build_omp_clause (UNKNOWN_LOCATION
, OMP_CLAUSE_SAFELEN
);
10390 OMP_CLAUSE_SAFELEN_EXPR (c
) = integer_one_node
;
10391 OMP_CLAUSE_CHAIN (c
) = *list_p
;
10393 list_p
= &OMP_CLAUSE_CHAIN (c
);
10396 if (ctx
->region_type
== ORT_WORKSHARE
10397 && ctx
->outer_context
10398 && ctx
->outer_context
->region_type
== ORT_COMBINED_PARALLEL
)
10400 for (c
= ctx
->outer_context
->clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
10401 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
10402 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
))
10404 decl
= OMP_CLAUSE_DECL (c
);
10406 = splay_tree_lookup (ctx
->outer_context
->variables
,
10407 (splay_tree_key
) decl
);
10408 gcc_checking_assert (!splay_tree_lookup (ctx
->variables
,
10409 (splay_tree_key
) decl
));
10410 omp_add_variable (ctx
, decl
, n
->value
);
10411 tree c2
= copy_node (c
);
10412 OMP_CLAUSE_CHAIN (c2
) = *list_p
;
10414 if ((n
->value
& GOVD_FIRSTPRIVATE
) == 0)
10416 c2
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
10417 OMP_CLAUSE_FIRSTPRIVATE
);
10418 OMP_CLAUSE_DECL (c2
) = decl
;
10419 OMP_CLAUSE_CHAIN (c2
) = *list_p
;
10423 while ((c
= *list_p
) != NULL
)
10426 bool remove
= false;
10428 switch (OMP_CLAUSE_CODE (c
))
10430 case OMP_CLAUSE_FIRSTPRIVATE
:
10431 if ((ctx
->region_type
& ORT_TARGET
)
10432 && (ctx
->region_type
& ORT_ACC
) == 0
10433 && TYPE_ATOMIC (strip_array_types
10434 (TREE_TYPE (OMP_CLAUSE_DECL (c
)))))
10436 error_at (OMP_CLAUSE_LOCATION (c
),
10437 "%<_Atomic%> %qD in %<firstprivate%> clause on "
10438 "%<target%> construct", OMP_CLAUSE_DECL (c
));
10443 case OMP_CLAUSE_PRIVATE
:
10444 case OMP_CLAUSE_SHARED
:
10445 case OMP_CLAUSE_LINEAR
:
10446 decl
= OMP_CLAUSE_DECL (c
);
10447 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
10448 remove
= !(n
->value
& GOVD_SEEN
);
10449 if ((n
->value
& GOVD_LASTPRIVATE_CONDITIONAL
) != 0
10450 && code
== OMP_PARALLEL
10451 && OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_FIRSTPRIVATE
)
10455 bool shared
= OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_SHARED
;
10456 if ((n
->value
& GOVD_DEBUG_PRIVATE
)
10457 || lang_hooks
.decls
.omp_private_debug_clause (decl
, shared
))
10459 gcc_assert ((n
->value
& GOVD_DEBUG_PRIVATE
) == 0
10460 || ((n
->value
& GOVD_DATA_SHARE_CLASS
)
10462 OMP_CLAUSE_SET_CODE (c
, OMP_CLAUSE_PRIVATE
);
10463 OMP_CLAUSE_PRIVATE_DEBUG (c
) = 1;
10465 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_SHARED
10466 && (n
->value
& GOVD_WRITTEN
) == 0
10468 && omp_shared_to_firstprivate_optimizable_decl_p (decl
))
10469 OMP_CLAUSE_SHARED_READONLY (c
) = 1;
10470 else if (DECL_P (decl
)
10471 && ((OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_SHARED
10472 && (n
->value
& GOVD_WRITTEN
) != 0)
10473 || (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINEAR
10474 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c
)))
10475 && omp_shared_to_firstprivate_optimizable_decl_p (decl
))
10476 omp_mark_stores (gimplify_omp_ctxp
->outer_context
, decl
);
10480 case OMP_CLAUSE_LASTPRIVATE
:
10481 /* Make sure OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE is set to
10482 accurately reflect the presence of a FIRSTPRIVATE clause. */
10483 decl
= OMP_CLAUSE_DECL (c
);
10484 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
10485 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
)
10486 = (n
->value
& GOVD_FIRSTPRIVATE
) != 0;
10487 if (code
== OMP_DISTRIBUTE
10488 && OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
))
10491 error_at (OMP_CLAUSE_LOCATION (c
),
10492 "same variable used in %<firstprivate%> and "
10493 "%<lastprivate%> clauses on %<distribute%> "
10497 && OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
10499 && omp_shared_to_firstprivate_optimizable_decl_p (decl
))
10500 omp_mark_stores (gimplify_omp_ctxp
->outer_context
, decl
);
10501 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
) && code
== OMP_PARALLEL
)
10505 case OMP_CLAUSE_ALIGNED
:
10506 decl
= OMP_CLAUSE_DECL (c
);
10507 if (!is_global_var (decl
))
10509 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
10510 remove
= n
== NULL
|| !(n
->value
& GOVD_SEEN
);
10511 if (!remove
&& TREE_CODE (TREE_TYPE (decl
)) == POINTER_TYPE
)
10513 struct gimplify_omp_ctx
*octx
;
10515 && (n
->value
& (GOVD_DATA_SHARE_CLASS
10516 & ~GOVD_FIRSTPRIVATE
)))
10519 for (octx
= ctx
->outer_context
; octx
;
10520 octx
= octx
->outer_context
)
10522 n
= splay_tree_lookup (octx
->variables
,
10523 (splay_tree_key
) decl
);
10526 if (n
->value
& GOVD_LOCAL
)
10528 /* We have to avoid assigning a shared variable
10529 to itself when trying to add
10530 __builtin_assume_aligned. */
10531 if (n
->value
& GOVD_SHARED
)
10539 else if (TREE_CODE (TREE_TYPE (decl
)) == ARRAY_TYPE
)
10541 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
10542 if (n
!= NULL
&& (n
->value
& GOVD_DATA_SHARE_CLASS
) != 0)
10547 case OMP_CLAUSE_NONTEMPORAL
:
10548 decl
= OMP_CLAUSE_DECL (c
);
10549 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
10550 remove
= n
== NULL
|| !(n
->value
& GOVD_SEEN
);
10553 case OMP_CLAUSE_MAP
:
10554 if (code
== OMP_TARGET_EXIT_DATA
10555 && OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ALWAYS_POINTER
)
10560 decl
= OMP_CLAUSE_DECL (c
);
10561 /* Data clauses associated with reductions must be
10562 compatible with present_or_copy. Warn and adjust the clause
10563 if that is not the case. */
10564 if (ctx
->region_type
== ORT_ACC_PARALLEL
10565 || ctx
->region_type
== ORT_ACC_SERIAL
)
10567 tree t
= DECL_P (decl
) ? decl
: TREE_OPERAND (decl
, 0);
10571 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) t
);
10573 if (n
&& (n
->value
& GOVD_REDUCTION
))
10575 enum gomp_map_kind kind
= OMP_CLAUSE_MAP_KIND (c
);
10577 OMP_CLAUSE_MAP_IN_REDUCTION (c
) = 1;
10578 if ((kind
& GOMP_MAP_TOFROM
) != GOMP_MAP_TOFROM
10579 && kind
!= GOMP_MAP_FORCE_PRESENT
10580 && kind
!= GOMP_MAP_POINTER
)
10582 warning_at (OMP_CLAUSE_LOCATION (c
), 0,
10583 "incompatible data clause with reduction "
10584 "on %qE; promoting to %<present_or_copy%>",
10586 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_TOFROM
);
10590 if (!DECL_P (decl
))
10592 if ((ctx
->region_type
& ORT_TARGET
) != 0
10593 && OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_FIRSTPRIVATE_POINTER
)
10595 if (TREE_CODE (decl
) == INDIRECT_REF
10596 && TREE_CODE (TREE_OPERAND (decl
, 0)) == COMPONENT_REF
10597 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl
, 0)))
10598 == REFERENCE_TYPE
))
10599 decl
= TREE_OPERAND (decl
, 0);
10600 if (TREE_CODE (decl
) == COMPONENT_REF
)
10602 while (TREE_CODE (decl
) == COMPONENT_REF
)
10603 decl
= TREE_OPERAND (decl
, 0);
10606 n
= splay_tree_lookup (ctx
->variables
,
10607 (splay_tree_key
) decl
);
10608 if (!(n
->value
& GOVD_SEEN
))
10615 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
10616 if ((ctx
->region_type
& ORT_TARGET
) != 0
10617 && !(n
->value
& GOVD_SEEN
)
10618 && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c
)) == 0
10619 && (!is_global_var (decl
)
10620 || !lookup_attribute ("omp declare target link",
10621 DECL_ATTRIBUTES (decl
))))
10624 /* For struct element mapping, if struct is never referenced
10625 in target block and none of the mapping has always modifier,
10626 remove all the struct element mappings, which immediately
10627 follow the GOMP_MAP_STRUCT map clause. */
10628 if (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_STRUCT
)
10630 HOST_WIDE_INT cnt
= tree_to_shwi (OMP_CLAUSE_SIZE (c
));
10632 OMP_CLAUSE_CHAIN (c
)
10633 = OMP_CLAUSE_CHAIN (OMP_CLAUSE_CHAIN (c
));
10636 else if (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_STRUCT
10637 && (code
== OMP_TARGET_EXIT_DATA
10638 || code
== OACC_EXIT_DATA
))
10640 else if (DECL_SIZE (decl
)
10641 && TREE_CODE (DECL_SIZE (decl
)) != INTEGER_CST
10642 && OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_POINTER
10643 && OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_FIRSTPRIVATE_POINTER
10644 && (OMP_CLAUSE_MAP_KIND (c
)
10645 != GOMP_MAP_FIRSTPRIVATE_REFERENCE
))
10647 /* For GOMP_MAP_FORCE_DEVICEPTR, we'll never enter here, because
10648 for these, TREE_CODE (DECL_SIZE (decl)) will always be
10650 gcc_assert (OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_FORCE_DEVICEPTR
);
10652 tree decl2
= DECL_VALUE_EXPR (decl
);
10653 gcc_assert (TREE_CODE (decl2
) == INDIRECT_REF
);
10654 decl2
= TREE_OPERAND (decl2
, 0);
10655 gcc_assert (DECL_P (decl2
));
10656 tree mem
= build_simple_mem_ref (decl2
);
10657 OMP_CLAUSE_DECL (c
) = mem
;
10658 OMP_CLAUSE_SIZE (c
) = TYPE_SIZE_UNIT (TREE_TYPE (decl
));
10659 if (ctx
->outer_context
)
10661 omp_notice_variable (ctx
->outer_context
, decl2
, true);
10662 omp_notice_variable (ctx
->outer_context
,
10663 OMP_CLAUSE_SIZE (c
), true);
10665 if (((ctx
->region_type
& ORT_TARGET
) != 0
10666 || !ctx
->target_firstprivatize_array_bases
)
10667 && ((n
->value
& GOVD_SEEN
) == 0
10668 || (n
->value
& (GOVD_PRIVATE
| GOVD_FIRSTPRIVATE
)) == 0))
10670 tree nc
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
10672 OMP_CLAUSE_DECL (nc
) = decl
;
10673 OMP_CLAUSE_SIZE (nc
) = size_zero_node
;
10674 if (ctx
->target_firstprivatize_array_bases
)
10675 OMP_CLAUSE_SET_MAP_KIND (nc
,
10676 GOMP_MAP_FIRSTPRIVATE_POINTER
);
10678 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_POINTER
);
10679 OMP_CLAUSE_CHAIN (nc
) = OMP_CLAUSE_CHAIN (c
);
10680 OMP_CLAUSE_CHAIN (c
) = nc
;
10686 if (OMP_CLAUSE_SIZE (c
) == NULL_TREE
)
10687 OMP_CLAUSE_SIZE (c
) = DECL_SIZE_UNIT (decl
);
10688 gcc_assert ((n
->value
& GOVD_SEEN
) == 0
10689 || ((n
->value
& (GOVD_PRIVATE
| GOVD_FIRSTPRIVATE
))
10694 case OMP_CLAUSE_TO
:
10695 case OMP_CLAUSE_FROM
:
10696 case OMP_CLAUSE__CACHE_
:
10697 decl
= OMP_CLAUSE_DECL (c
);
10698 if (!DECL_P (decl
))
10700 if (DECL_SIZE (decl
)
10701 && TREE_CODE (DECL_SIZE (decl
)) != INTEGER_CST
)
10703 tree decl2
= DECL_VALUE_EXPR (decl
);
10704 gcc_assert (TREE_CODE (decl2
) == INDIRECT_REF
);
10705 decl2
= TREE_OPERAND (decl2
, 0);
10706 gcc_assert (DECL_P (decl2
));
10707 tree mem
= build_simple_mem_ref (decl2
);
10708 OMP_CLAUSE_DECL (c
) = mem
;
10709 OMP_CLAUSE_SIZE (c
) = TYPE_SIZE_UNIT (TREE_TYPE (decl
));
10710 if (ctx
->outer_context
)
10712 omp_notice_variable (ctx
->outer_context
, decl2
, true);
10713 omp_notice_variable (ctx
->outer_context
,
10714 OMP_CLAUSE_SIZE (c
), true);
10717 else if (OMP_CLAUSE_SIZE (c
) == NULL_TREE
)
10718 OMP_CLAUSE_SIZE (c
) = DECL_SIZE_UNIT (decl
);
10721 case OMP_CLAUSE_REDUCTION
:
10722 if (OMP_CLAUSE_REDUCTION_INSCAN (c
))
10724 decl
= OMP_CLAUSE_DECL (c
);
10725 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
10726 if ((n
->value
& GOVD_REDUCTION_INSCAN
) == 0)
10729 error_at (OMP_CLAUSE_LOCATION (c
),
10730 "%qD specified in %<inscan%> %<reduction%> clause "
10731 "but not in %<scan%> directive clause", decl
);
10734 has_inscan_reductions
= true;
10737 case OMP_CLAUSE_IN_REDUCTION
:
10738 case OMP_CLAUSE_TASK_REDUCTION
:
10739 decl
= OMP_CLAUSE_DECL (c
);
10740 /* OpenACC reductions need a present_or_copy data clause.
10741 Add one if necessary. Emit error when the reduction is private. */
10742 if (ctx
->region_type
== ORT_ACC_PARALLEL
10743 || ctx
->region_type
== ORT_ACC_SERIAL
)
10745 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
10746 if (n
->value
& (GOVD_PRIVATE
| GOVD_FIRSTPRIVATE
))
10749 error_at (OMP_CLAUSE_LOCATION (c
), "invalid private "
10750 "reduction on %qE", DECL_NAME (decl
));
10752 else if ((n
->value
& GOVD_MAP
) == 0)
10754 tree next
= OMP_CLAUSE_CHAIN (c
);
10755 tree nc
= build_omp_clause (UNKNOWN_LOCATION
, OMP_CLAUSE_MAP
);
10756 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_TOFROM
);
10757 OMP_CLAUSE_DECL (nc
) = decl
;
10758 OMP_CLAUSE_CHAIN (c
) = nc
;
10759 lang_hooks
.decls
.omp_finish_clause (nc
, pre_p
,
10764 OMP_CLAUSE_MAP_IN_REDUCTION (nc
) = 1;
10765 if (OMP_CLAUSE_CHAIN (nc
) == NULL
)
10767 nc
= OMP_CLAUSE_CHAIN (nc
);
10769 OMP_CLAUSE_CHAIN (nc
) = next
;
10770 n
->value
|= GOVD_MAP
;
10774 && omp_shared_to_firstprivate_optimizable_decl_p (decl
))
10775 omp_mark_stores (gimplify_omp_ctxp
->outer_context
, decl
);
10777 case OMP_CLAUSE_COPYIN
:
10778 case OMP_CLAUSE_COPYPRIVATE
:
10779 case OMP_CLAUSE_IF
:
10780 case OMP_CLAUSE_NUM_THREADS
:
10781 case OMP_CLAUSE_NUM_TEAMS
:
10782 case OMP_CLAUSE_THREAD_LIMIT
:
10783 case OMP_CLAUSE_DIST_SCHEDULE
:
10784 case OMP_CLAUSE_DEVICE
:
10785 case OMP_CLAUSE_SCHEDULE
:
10786 case OMP_CLAUSE_NOWAIT
:
10787 case OMP_CLAUSE_ORDERED
:
10788 case OMP_CLAUSE_DEFAULT
:
10789 case OMP_CLAUSE_UNTIED
:
10790 case OMP_CLAUSE_COLLAPSE
:
10791 case OMP_CLAUSE_FINAL
:
10792 case OMP_CLAUSE_MERGEABLE
:
10793 case OMP_CLAUSE_PROC_BIND
:
10794 case OMP_CLAUSE_SAFELEN
:
10795 case OMP_CLAUSE_SIMDLEN
:
10796 case OMP_CLAUSE_DEPEND
:
10797 case OMP_CLAUSE_PRIORITY
:
10798 case OMP_CLAUSE_GRAINSIZE
:
10799 case OMP_CLAUSE_NUM_TASKS
:
10800 case OMP_CLAUSE_NOGROUP
:
10801 case OMP_CLAUSE_THREADS
:
10802 case OMP_CLAUSE_SIMD
:
10803 case OMP_CLAUSE_HINT
:
10804 case OMP_CLAUSE_DEFAULTMAP
:
10805 case OMP_CLAUSE_ORDER
:
10806 case OMP_CLAUSE_BIND
:
10807 case OMP_CLAUSE_USE_DEVICE_PTR
:
10808 case OMP_CLAUSE_USE_DEVICE_ADDR
:
10809 case OMP_CLAUSE_IS_DEVICE_PTR
:
10810 case OMP_CLAUSE_ASYNC
:
10811 case OMP_CLAUSE_WAIT
:
10812 case OMP_CLAUSE_INDEPENDENT
:
10813 case OMP_CLAUSE_NUM_GANGS
:
10814 case OMP_CLAUSE_NUM_WORKERS
:
10815 case OMP_CLAUSE_VECTOR_LENGTH
:
10816 case OMP_CLAUSE_GANG
:
10817 case OMP_CLAUSE_WORKER
:
10818 case OMP_CLAUSE_VECTOR
:
10819 case OMP_CLAUSE_AUTO
:
10820 case OMP_CLAUSE_SEQ
:
10821 case OMP_CLAUSE_TILE
:
10822 case OMP_CLAUSE_IF_PRESENT
:
10823 case OMP_CLAUSE_FINALIZE
:
10824 case OMP_CLAUSE_INCLUSIVE
:
10825 case OMP_CLAUSE_EXCLUSIVE
:
10826 case OMP_CLAUSE_ALLOCATE
:
10830 gcc_unreachable ();
10834 *list_p
= OMP_CLAUSE_CHAIN (c
);
10836 list_p
= &OMP_CLAUSE_CHAIN (c
);
10839 /* Add in any implicit data sharing. */
10840 struct gimplify_adjust_omp_clauses_data data
;
10841 data
.list_p
= list_p
;
10842 data
.pre_p
= pre_p
;
10843 splay_tree_foreach (ctx
->variables
, gimplify_adjust_omp_clauses_1
, &data
);
10845 if (has_inscan_reductions
)
10846 for (c
= *orig_list_p
; c
; c
= OMP_CLAUSE_CHAIN (c
))
10847 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINEAR
10848 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c
))
10850 error_at (OMP_CLAUSE_LOCATION (c
),
10851 "%<inscan%> %<reduction%> clause used together with "
10852 "%<linear%> clause for a variable other than loop "
10857 gimplify_omp_ctxp
= ctx
->outer_context
;
10858 delete_omp_context (ctx
);
10861 /* Return 0 if CONSTRUCTS selectors don't match the OpenMP context,
10862 -1 if unknown yet (simd is involved, won't be known until vectorization)
10863 and 1 if they do. If SCORES is non-NULL, it should point to an array
10864 of at least 2*NCONSTRUCTS+2 ints, and will be filled with the positions
10865 of the CONSTRUCTS (position -1 if it will never match) followed by
10866 number of constructs in the OpenMP context construct trait. If the
10867 score depends on whether it will be in a declare simd clone or not,
10868 the function returns 2 and there will be two sets of the scores, the first
10869 one for the case that it is not in a declare simd clone, the other
10870 that it is in a declare simd clone. */
10873 omp_construct_selector_matches (enum tree_code
*constructs
, int nconstructs
,
10876 int matched
= 0, cnt
= 0;
10877 bool simd_seen
= false;
10878 bool target_seen
= false;
10879 int declare_simd_cnt
= -1;
10880 auto_vec
<enum tree_code
, 16> codes
;
10881 for (struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
; ctx
;)
10883 if (((ctx
->region_type
& ORT_PARALLEL
) && ctx
->code
== OMP_PARALLEL
)
10884 || ((ctx
->region_type
& (ORT_TARGET
| ORT_IMPLICIT_TARGET
| ORT_ACC
))
10885 == ORT_TARGET
&& ctx
->code
== OMP_TARGET
)
10886 || ((ctx
->region_type
& ORT_TEAMS
) && ctx
->code
== OMP_TEAMS
)
10887 || (ctx
->region_type
== ORT_WORKSHARE
&& ctx
->code
== OMP_FOR
)
10888 || (ctx
->region_type
== ORT_SIMD
10889 && ctx
->code
== OMP_SIMD
10890 && !omp_find_clause (ctx
->clauses
, OMP_CLAUSE_BIND
)))
10894 codes
.safe_push (ctx
->code
);
10895 else if (matched
< nconstructs
&& ctx
->code
== constructs
[matched
])
10897 if (ctx
->code
== OMP_SIMD
)
10905 if (ctx
->code
== OMP_TARGET
)
10907 if (scores
== NULL
)
10908 return matched
< nconstructs
? 0 : simd_seen
? -1 : 1;
10909 target_seen
= true;
10913 else if (ctx
->region_type
== ORT_WORKSHARE
10914 && ctx
->code
== OMP_LOOP
10915 && ctx
->outer_context
10916 && ctx
->outer_context
->region_type
== ORT_COMBINED_PARALLEL
10917 && ctx
->outer_context
->outer_context
10918 && ctx
->outer_context
->outer_context
->code
== OMP_LOOP
10919 && ctx
->outer_context
->outer_context
->distribute
)
10920 ctx
= ctx
->outer_context
->outer_context
;
10921 ctx
= ctx
->outer_context
;
10924 && lookup_attribute ("omp declare simd",
10925 DECL_ATTRIBUTES (current_function_decl
)))
10927 /* Declare simd is a maybe case, it is supposed to be added only to the
10928 omp-simd-clone.c added clones and not to the base function. */
10929 declare_simd_cnt
= cnt
++;
10931 codes
.safe_push (OMP_SIMD
);
10933 && constructs
[0] == OMP_SIMD
)
10935 gcc_assert (matched
== 0);
10937 if (++matched
== nconstructs
)
10941 if (tree attr
= lookup_attribute ("omp declare variant variant",
10942 DECL_ATTRIBUTES (current_function_decl
)))
10944 enum tree_code variant_constructs
[5];
10945 int variant_nconstructs
= 0;
10947 variant_nconstructs
10948 = omp_constructor_traits_to_codes (TREE_VALUE (attr
),
10949 variant_constructs
);
10950 for (int i
= 0; i
< variant_nconstructs
; i
++)
10954 codes
.safe_push (variant_constructs
[i
]);
10955 else if (matched
< nconstructs
10956 && variant_constructs
[i
] == constructs
[matched
])
10958 if (variant_constructs
[i
] == OMP_SIMD
)
10969 && lookup_attribute ("omp declare target block",
10970 DECL_ATTRIBUTES (current_function_decl
)))
10973 codes
.safe_push (OMP_TARGET
);
10974 else if (matched
< nconstructs
&& constructs
[matched
] == OMP_TARGET
)
10979 for (int pass
= 0; pass
< (declare_simd_cnt
== -1 ? 1 : 2); pass
++)
10981 int j
= codes
.length () - 1;
10982 for (int i
= nconstructs
- 1; i
>= 0; i
--)
10985 && (pass
!= 0 || declare_simd_cnt
!= j
)
10986 && constructs
[i
] != codes
[j
])
10988 if (pass
== 0 && declare_simd_cnt
!= -1 && j
> declare_simd_cnt
)
10993 *scores
++ = ((pass
== 0 && declare_simd_cnt
!= -1)
10994 ? codes
.length () - 1 : codes
.length ());
10996 return declare_simd_cnt
== -1 ? 1 : 2;
10998 if (matched
== nconstructs
)
10999 return simd_seen
? -1 : 1;
11003 /* Gimplify OACC_CACHE. */
11006 gimplify_oacc_cache (tree
*expr_p
, gimple_seq
*pre_p
)
11008 tree expr
= *expr_p
;
11010 gimplify_scan_omp_clauses (&OACC_CACHE_CLAUSES (expr
), pre_p
, ORT_ACC
,
11012 gimplify_adjust_omp_clauses (pre_p
, NULL
, &OACC_CACHE_CLAUSES (expr
),
11015 /* TODO: Do something sensible with this information. */
11017 *expr_p
= NULL_TREE
;
11020 /* Helper function of gimplify_oacc_declare. The helper's purpose is to,
11021 if required, translate 'kind' in CLAUSE into an 'entry' kind and 'exit'
11022 kind. The entry kind will replace the one in CLAUSE, while the exit
11023 kind will be used in a new omp_clause and returned to the caller. */
11026 gimplify_oacc_declare_1 (tree clause
)
11028 HOST_WIDE_INT kind
, new_op
;
11032 kind
= OMP_CLAUSE_MAP_KIND (clause
);
11036 case GOMP_MAP_ALLOC
:
11037 new_op
= GOMP_MAP_RELEASE
;
11041 case GOMP_MAP_FROM
:
11042 OMP_CLAUSE_SET_MAP_KIND (clause
, GOMP_MAP_FORCE_ALLOC
);
11043 new_op
= GOMP_MAP_FROM
;
11047 case GOMP_MAP_TOFROM
:
11048 OMP_CLAUSE_SET_MAP_KIND (clause
, GOMP_MAP_TO
);
11049 new_op
= GOMP_MAP_FROM
;
11053 case GOMP_MAP_DEVICE_RESIDENT
:
11054 case GOMP_MAP_FORCE_DEVICEPTR
:
11055 case GOMP_MAP_FORCE_PRESENT
:
11056 case GOMP_MAP_LINK
:
11057 case GOMP_MAP_POINTER
:
11062 gcc_unreachable ();
11068 c
= build_omp_clause (OMP_CLAUSE_LOCATION (clause
), OMP_CLAUSE_MAP
);
11069 OMP_CLAUSE_SET_MAP_KIND (c
, new_op
);
11070 OMP_CLAUSE_DECL (c
) = OMP_CLAUSE_DECL (clause
);
11076 /* Gimplify OACC_DECLARE. */
11079 gimplify_oacc_declare (tree
*expr_p
, gimple_seq
*pre_p
)
11081 tree expr
= *expr_p
;
11083 tree clauses
, t
, decl
;
11085 clauses
= OACC_DECLARE_CLAUSES (expr
);
11087 gimplify_scan_omp_clauses (&clauses
, pre_p
, ORT_TARGET_DATA
, OACC_DECLARE
);
11088 gimplify_adjust_omp_clauses (pre_p
, NULL
, &clauses
, OACC_DECLARE
);
11090 for (t
= clauses
; t
; t
= OMP_CLAUSE_CHAIN (t
))
11092 decl
= OMP_CLAUSE_DECL (t
);
11094 if (TREE_CODE (decl
) == MEM_REF
)
11095 decl
= TREE_OPERAND (decl
, 0);
11097 if (VAR_P (decl
) && !is_oacc_declared (decl
))
11099 tree attr
= get_identifier ("oacc declare target");
11100 DECL_ATTRIBUTES (decl
) = tree_cons (attr
, NULL_TREE
,
11101 DECL_ATTRIBUTES (decl
));
11105 && !is_global_var (decl
)
11106 && DECL_CONTEXT (decl
) == current_function_decl
)
11108 tree c
= gimplify_oacc_declare_1 (t
);
11111 if (oacc_declare_returns
== NULL
)
11112 oacc_declare_returns
= new hash_map
<tree
, tree
>;
11114 oacc_declare_returns
->put (decl
, c
);
11118 if (gimplify_omp_ctxp
)
11119 omp_add_variable (gimplify_omp_ctxp
, decl
, GOVD_SEEN
);
11122 stmt
= gimple_build_omp_target (NULL
, GF_OMP_TARGET_KIND_OACC_DECLARE
,
11125 gimplify_seq_add_stmt (pre_p
, stmt
);
11127 *expr_p
= NULL_TREE
;
11130 /* Gimplify the contents of an OMP_PARALLEL statement. This involves
11131 gimplification of the body, as well as scanning the body for used
11132 variables. We need to do this scan now, because variable-sized
11133 decls will be decomposed during gimplification. */
11136 gimplify_omp_parallel (tree
*expr_p
, gimple_seq
*pre_p
)
11138 tree expr
= *expr_p
;
11140 gimple_seq body
= NULL
;
11142 gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr
), pre_p
,
11143 OMP_PARALLEL_COMBINED (expr
)
11144 ? ORT_COMBINED_PARALLEL
11145 : ORT_PARALLEL
, OMP_PARALLEL
);
11147 push_gimplify_context ();
11149 g
= gimplify_and_return_first (OMP_PARALLEL_BODY (expr
), &body
);
11150 if (gimple_code (g
) == GIMPLE_BIND
)
11151 pop_gimplify_context (g
);
11153 pop_gimplify_context (NULL
);
11155 gimplify_adjust_omp_clauses (pre_p
, body
, &OMP_PARALLEL_CLAUSES (expr
),
11158 g
= gimple_build_omp_parallel (body
,
11159 OMP_PARALLEL_CLAUSES (expr
),
11160 NULL_TREE
, NULL_TREE
);
11161 if (OMP_PARALLEL_COMBINED (expr
))
11162 gimple_omp_set_subcode (g
, GF_OMP_PARALLEL_COMBINED
);
11163 gimplify_seq_add_stmt (pre_p
, g
);
11164 *expr_p
= NULL_TREE
;
11167 /* Gimplify the contents of an OMP_TASK statement. This involves
11168 gimplification of the body, as well as scanning the body for used
11169 variables. We need to do this scan now, because variable-sized
11170 decls will be decomposed during gimplification. */
11173 gimplify_omp_task (tree
*expr_p
, gimple_seq
*pre_p
)
11175 tree expr
= *expr_p
;
11177 gimple_seq body
= NULL
;
11179 if (OMP_TASK_BODY (expr
) == NULL_TREE
)
11180 for (tree c
= OMP_TASK_CLAUSES (expr
); c
; c
= OMP_CLAUSE_CHAIN (c
))
11181 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEPEND
11182 && OMP_CLAUSE_DEPEND_KIND (c
) == OMP_CLAUSE_DEPEND_MUTEXINOUTSET
)
11184 error_at (OMP_CLAUSE_LOCATION (c
),
11185 "%<mutexinoutset%> kind in %<depend%> clause on a "
11186 "%<taskwait%> construct");
11190 gimplify_scan_omp_clauses (&OMP_TASK_CLAUSES (expr
), pre_p
,
11191 omp_find_clause (OMP_TASK_CLAUSES (expr
),
11193 ? ORT_UNTIED_TASK
: ORT_TASK
, OMP_TASK
);
11195 if (OMP_TASK_BODY (expr
))
11197 push_gimplify_context ();
11199 g
= gimplify_and_return_first (OMP_TASK_BODY (expr
), &body
);
11200 if (gimple_code (g
) == GIMPLE_BIND
)
11201 pop_gimplify_context (g
);
11203 pop_gimplify_context (NULL
);
11206 gimplify_adjust_omp_clauses (pre_p
, body
, &OMP_TASK_CLAUSES (expr
),
11209 g
= gimple_build_omp_task (body
,
11210 OMP_TASK_CLAUSES (expr
),
11211 NULL_TREE
, NULL_TREE
,
11212 NULL_TREE
, NULL_TREE
, NULL_TREE
);
11213 if (OMP_TASK_BODY (expr
) == NULL_TREE
)
11214 gimple_omp_task_set_taskwait_p (g
, true);
11215 gimplify_seq_add_stmt (pre_p
, g
);
11216 *expr_p
= NULL_TREE
;
11219 /* Helper function for gimplify_omp_for. If *TP is not a gimple constant,
11220 force it into a temporary initialized in PRE_P and add firstprivate clause
11221 to ORIG_FOR_STMT. */
11224 gimplify_omp_taskloop_expr (tree type
, tree
*tp
, gimple_seq
*pre_p
,
11225 tree orig_for_stmt
)
11227 if (*tp
== NULL
|| is_gimple_constant (*tp
))
11230 *tp
= get_initialized_tmp_var (*tp
, pre_p
, NULL
, false);
11231 /* Reference to pointer conversion is considered useless,
11232 but is significant for firstprivate clause. Force it
11235 && TREE_CODE (type
) == POINTER_TYPE
11236 && TREE_CODE (TREE_TYPE (*tp
)) == REFERENCE_TYPE
)
11238 tree v
= create_tmp_var (TYPE_MAIN_VARIANT (type
));
11239 tree m
= build2 (INIT_EXPR
, TREE_TYPE (v
), v
, *tp
);
11240 gimplify_and_add (m
, pre_p
);
11244 tree c
= build_omp_clause (input_location
, OMP_CLAUSE_FIRSTPRIVATE
);
11245 OMP_CLAUSE_DECL (c
) = *tp
;
11246 OMP_CLAUSE_CHAIN (c
) = OMP_FOR_CLAUSES (orig_for_stmt
);
11247 OMP_FOR_CLAUSES (orig_for_stmt
) = c
;
11250 /* Gimplify the gross structure of an OMP_FOR statement. */
11252 static enum gimplify_status
11253 gimplify_omp_for (tree
*expr_p
, gimple_seq
*pre_p
)
11255 tree for_stmt
, orig_for_stmt
, inner_for_stmt
= NULL_TREE
, decl
, var
, t
;
11256 enum gimplify_status ret
= GS_ALL_DONE
;
11257 enum gimplify_status tret
;
11259 gimple_seq for_body
, for_pre_body
;
11261 bitmap has_decl_expr
= NULL
;
11262 enum omp_region_type ort
= ORT_WORKSHARE
;
11263 bool openacc
= TREE_CODE (*expr_p
) == OACC_LOOP
;
11265 orig_for_stmt
= for_stmt
= *expr_p
;
11267 bool loop_p
= (omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_BIND
)
11269 if (OMP_FOR_INIT (for_stmt
) == NULL_TREE
)
11271 tree
*data
[4] = { NULL
, NULL
, NULL
, NULL
};
11272 gcc_assert (TREE_CODE (for_stmt
) != OACC_LOOP
);
11273 inner_for_stmt
= walk_tree (&OMP_FOR_BODY (for_stmt
),
11274 find_combined_omp_for
, data
, NULL
);
11275 if (inner_for_stmt
== NULL_TREE
)
11277 gcc_assert (seen_error ());
11278 *expr_p
= NULL_TREE
;
11281 if (data
[2] && OMP_FOR_PRE_BODY (*data
[2]))
11283 append_to_statement_list_force (OMP_FOR_PRE_BODY (*data
[2]),
11284 &OMP_FOR_PRE_BODY (for_stmt
));
11285 OMP_FOR_PRE_BODY (*data
[2]) = NULL_TREE
;
11287 if (OMP_FOR_PRE_BODY (inner_for_stmt
))
11289 append_to_statement_list_force (OMP_FOR_PRE_BODY (inner_for_stmt
),
11290 &OMP_FOR_PRE_BODY (for_stmt
));
11291 OMP_FOR_PRE_BODY (inner_for_stmt
) = NULL_TREE
;
11296 /* We have some statements or variable declarations in between
11297 the composite construct directives. Move them around the
11300 for (i
= 0; i
< 3; i
++)
11304 if (i
< 2 && data
[i
+ 1] == &OMP_BODY (t
))
11305 data
[i
+ 1] = data
[i
];
11306 *data
[i
] = OMP_BODY (t
);
11307 tree body
= build3 (BIND_EXPR
, void_type_node
, NULL_TREE
,
11308 NULL_TREE
, make_node (BLOCK
));
11309 OMP_BODY (t
) = body
;
11310 append_to_statement_list_force (inner_for_stmt
,
11311 &BIND_EXPR_BODY (body
));
11313 data
[3] = tsi_stmt_ptr (tsi_start (BIND_EXPR_BODY (body
)));
11314 gcc_assert (*data
[3] == inner_for_stmt
);
11319 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt
)); i
++)
11321 && OMP_FOR_ORIG_DECLS (inner_for_stmt
)
11322 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
),
11324 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
),
11327 tree orig
= TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
), i
);
11328 /* Class iterators aren't allowed on OMP_SIMD, so the only
11329 case we need to solve is distribute parallel for. They are
11330 allowed on the loop construct, but that is already handled
11331 in gimplify_omp_loop. */
11332 gcc_assert (TREE_CODE (inner_for_stmt
) == OMP_FOR
11333 && TREE_CODE (for_stmt
) == OMP_DISTRIBUTE
11335 tree orig_decl
= TREE_PURPOSE (orig
);
11336 tree last
= TREE_VALUE (orig
);
11338 for (pc
= &OMP_FOR_CLAUSES (inner_for_stmt
);
11339 *pc
; pc
= &OMP_CLAUSE_CHAIN (*pc
))
11340 if ((OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_PRIVATE
11341 || OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_LASTPRIVATE
)
11342 && OMP_CLAUSE_DECL (*pc
) == orig_decl
)
11344 if (*pc
== NULL_TREE
)
11347 for (spc
= &OMP_PARALLEL_CLAUSES (*data
[1]);
11348 *spc
; spc
= &OMP_CLAUSE_CHAIN (*spc
))
11349 if (OMP_CLAUSE_CODE (*spc
) == OMP_CLAUSE_PRIVATE
11350 && OMP_CLAUSE_DECL (*spc
) == orig_decl
)
11355 *spc
= OMP_CLAUSE_CHAIN (c
);
11356 OMP_CLAUSE_CHAIN (c
) = NULL_TREE
;
11360 if (*pc
== NULL_TREE
)
11362 else if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_PRIVATE
)
11364 /* private clause will appear only on inner_for_stmt.
11365 Change it into firstprivate, and add private clause
11367 tree c
= copy_node (*pc
);
11368 OMP_CLAUSE_CHAIN (c
) = OMP_FOR_CLAUSES (for_stmt
);
11369 OMP_FOR_CLAUSES (for_stmt
) = c
;
11370 OMP_CLAUSE_CODE (*pc
) = OMP_CLAUSE_FIRSTPRIVATE
;
11371 lang_hooks
.decls
.omp_finish_clause (*pc
, pre_p
, openacc
);
11375 /* lastprivate clause will appear on both inner_for_stmt
11376 and for_stmt. Add firstprivate clause to
11378 tree c
= build_omp_clause (OMP_CLAUSE_LOCATION (*pc
),
11379 OMP_CLAUSE_FIRSTPRIVATE
);
11380 OMP_CLAUSE_DECL (c
) = OMP_CLAUSE_DECL (*pc
);
11381 OMP_CLAUSE_CHAIN (c
) = *pc
;
11383 lang_hooks
.decls
.omp_finish_clause (*pc
, pre_p
, openacc
);
11385 tree c
= build_omp_clause (UNKNOWN_LOCATION
,
11386 OMP_CLAUSE_FIRSTPRIVATE
);
11387 OMP_CLAUSE_DECL (c
) = last
;
11388 OMP_CLAUSE_CHAIN (c
) = OMP_PARALLEL_CLAUSES (*data
[1]);
11389 OMP_PARALLEL_CLAUSES (*data
[1]) = c
;
11390 c
= build_omp_clause (UNKNOWN_LOCATION
,
11391 *pc
? OMP_CLAUSE_SHARED
11392 : OMP_CLAUSE_FIRSTPRIVATE
);
11393 OMP_CLAUSE_DECL (c
) = orig_decl
;
11394 OMP_CLAUSE_CHAIN (c
) = OMP_PARALLEL_CLAUSES (*data
[1]);
11395 OMP_PARALLEL_CLAUSES (*data
[1]) = c
;
11397 /* Similarly, take care of C++ range for temporaries, those should
11398 be firstprivate on OMP_PARALLEL if any. */
11400 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt
)); i
++)
11401 if (OMP_FOR_ORIG_DECLS (inner_for_stmt
)
11402 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
),
11404 && TREE_CHAIN (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
),
11408 = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
), i
);
11409 tree v
= TREE_CHAIN (orig
);
11410 tree c
= build_omp_clause (UNKNOWN_LOCATION
,
11411 OMP_CLAUSE_FIRSTPRIVATE
);
11412 /* First add firstprivate clause for the __for_end artificial
11414 OMP_CLAUSE_DECL (c
) = TREE_VEC_ELT (v
, 1);
11415 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c
)))
11417 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c
) = 1;
11418 OMP_CLAUSE_CHAIN (c
) = OMP_PARALLEL_CLAUSES (*data
[1]);
11419 OMP_PARALLEL_CLAUSES (*data
[1]) = c
;
11420 if (TREE_VEC_ELT (v
, 0))
11422 /* And now the same for __for_range artificial decl if it
11424 c
= build_omp_clause (UNKNOWN_LOCATION
,
11425 OMP_CLAUSE_FIRSTPRIVATE
);
11426 OMP_CLAUSE_DECL (c
) = TREE_VEC_ELT (v
, 0);
11427 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c
)))
11429 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c
) = 1;
11430 OMP_CLAUSE_CHAIN (c
) = OMP_PARALLEL_CLAUSES (*data
[1]);
11431 OMP_PARALLEL_CLAUSES (*data
[1]) = c
;
11436 switch (TREE_CODE (for_stmt
))
11439 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt
? inner_for_stmt
: for_stmt
))
11441 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt
),
11442 OMP_CLAUSE_SCHEDULE
))
11443 error_at (EXPR_LOCATION (for_stmt
),
11444 "%qs clause may not appear on non-rectangular %qs",
11445 "schedule", "for");
11446 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_ORDERED
))
11447 error_at (EXPR_LOCATION (for_stmt
),
11448 "%qs clause may not appear on non-rectangular %qs",
11452 case OMP_DISTRIBUTE
:
11453 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt
? inner_for_stmt
: for_stmt
)
11454 && omp_find_clause (OMP_FOR_CLAUSES (for_stmt
),
11455 OMP_CLAUSE_DIST_SCHEDULE
))
11456 error_at (EXPR_LOCATION (for_stmt
),
11457 "%qs clause may not appear on non-rectangular %qs",
11458 "dist_schedule", "distribute");
11464 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_UNTIED
))
11465 ort
= ORT_UNTIED_TASKLOOP
;
11467 ort
= ORT_TASKLOOP
;
11473 gcc_unreachable ();
11476 /* Set OMP_CLAUSE_LINEAR_NO_COPYIN flag on explicit linear
11477 clause for the IV. */
11478 if (ort
== ORT_SIMD
&& TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)) == 1)
11480 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), 0);
11481 gcc_assert (TREE_CODE (t
) == MODIFY_EXPR
);
11482 decl
= TREE_OPERAND (t
, 0);
11483 for (tree c
= OMP_FOR_CLAUSES (for_stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
11484 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINEAR
11485 && OMP_CLAUSE_DECL (c
) == decl
)
11487 OMP_CLAUSE_LINEAR_NO_COPYIN (c
) = 1;
11492 if (TREE_CODE (for_stmt
) != OMP_TASKLOOP
)
11493 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt
), pre_p
, ort
,
11494 loop_p
&& TREE_CODE (for_stmt
) != OMP_SIMD
11495 ? OMP_LOOP
: TREE_CODE (for_stmt
));
11497 if (TREE_CODE (for_stmt
) == OMP_DISTRIBUTE
)
11498 gimplify_omp_ctxp
->distribute
= true;
11500 /* Handle OMP_FOR_INIT. */
11501 for_pre_body
= NULL
;
11502 if ((ort
== ORT_SIMD
11503 || (inner_for_stmt
&& TREE_CODE (inner_for_stmt
) == OMP_SIMD
))
11504 && OMP_FOR_PRE_BODY (for_stmt
))
11506 has_decl_expr
= BITMAP_ALLOC (NULL
);
11507 if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt
)) == DECL_EXPR
11508 && TREE_CODE (DECL_EXPR_DECL (OMP_FOR_PRE_BODY (for_stmt
)))
11511 t
= OMP_FOR_PRE_BODY (for_stmt
);
11512 bitmap_set_bit (has_decl_expr
, DECL_UID (DECL_EXPR_DECL (t
)));
11514 else if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt
)) == STATEMENT_LIST
)
11516 tree_stmt_iterator si
;
11517 for (si
= tsi_start (OMP_FOR_PRE_BODY (for_stmt
)); !tsi_end_p (si
);
11521 if (TREE_CODE (t
) == DECL_EXPR
11522 && TREE_CODE (DECL_EXPR_DECL (t
)) == VAR_DECL
)
11523 bitmap_set_bit (has_decl_expr
, DECL_UID (DECL_EXPR_DECL (t
)));
11527 if (OMP_FOR_PRE_BODY (for_stmt
))
11529 if (TREE_CODE (for_stmt
) != OMP_TASKLOOP
|| gimplify_omp_ctxp
)
11530 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt
), &for_pre_body
);
11533 struct gimplify_omp_ctx ctx
;
11534 memset (&ctx
, 0, sizeof (ctx
));
11535 ctx
.region_type
= ORT_NONE
;
11536 gimplify_omp_ctxp
= &ctx
;
11537 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt
), &for_pre_body
);
11538 gimplify_omp_ctxp
= NULL
;
11541 OMP_FOR_PRE_BODY (for_stmt
) = NULL_TREE
;
11543 if (OMP_FOR_INIT (for_stmt
) == NULL_TREE
)
11544 for_stmt
= inner_for_stmt
;
11546 /* For taskloop, need to gimplify the start, end and step before the
11547 taskloop, outside of the taskloop omp context. */
11548 if (TREE_CODE (orig_for_stmt
) == OMP_TASKLOOP
)
11550 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
11552 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), i
);
11553 gimple_seq
*for_pre_p
= (gimple_seq_empty_p (for_pre_body
)
11554 ? pre_p
: &for_pre_body
);
11555 tree type
= TREE_TYPE (TREE_OPERAND (t
, 0));
11556 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
)
11558 tree v
= TREE_OPERAND (t
, 1);
11559 gimplify_omp_taskloop_expr (type
, &TREE_VEC_ELT (v
, 1),
11560 for_pre_p
, orig_for_stmt
);
11561 gimplify_omp_taskloop_expr (type
, &TREE_VEC_ELT (v
, 2),
11562 for_pre_p
, orig_for_stmt
);
11565 gimplify_omp_taskloop_expr (type
, &TREE_OPERAND (t
, 1), for_pre_p
,
11568 /* Handle OMP_FOR_COND. */
11569 t
= TREE_VEC_ELT (OMP_FOR_COND (for_stmt
), i
);
11570 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
)
11572 tree v
= TREE_OPERAND (t
, 1);
11573 gimplify_omp_taskloop_expr (type
, &TREE_VEC_ELT (v
, 1),
11574 for_pre_p
, orig_for_stmt
);
11575 gimplify_omp_taskloop_expr (type
, &TREE_VEC_ELT (v
, 2),
11576 for_pre_p
, orig_for_stmt
);
11579 gimplify_omp_taskloop_expr (type
, &TREE_OPERAND (t
, 1), for_pre_p
,
11582 /* Handle OMP_FOR_INCR. */
11583 t
= TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
);
11584 if (TREE_CODE (t
) == MODIFY_EXPR
)
11586 decl
= TREE_OPERAND (t
, 0);
11587 t
= TREE_OPERAND (t
, 1);
11588 tree
*tp
= &TREE_OPERAND (t
, 1);
11589 if (TREE_CODE (t
) == PLUS_EXPR
&& *tp
== decl
)
11590 tp
= &TREE_OPERAND (t
, 0);
11592 gimplify_omp_taskloop_expr (NULL_TREE
, tp
, for_pre_p
,
11597 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (orig_for_stmt
), pre_p
, ort
,
11601 if (orig_for_stmt
!= for_stmt
)
11602 gimplify_omp_ctxp
->combined_loop
= true;
11605 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
))
11606 == TREE_VEC_LENGTH (OMP_FOR_COND (for_stmt
)));
11607 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
))
11608 == TREE_VEC_LENGTH (OMP_FOR_INCR (for_stmt
)));
11610 tree c
= omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_ORDERED
);
11611 bool is_doacross
= false;
11612 if (c
&& OMP_CLAUSE_ORDERED_EXPR (c
))
11614 is_doacross
= true;
11615 gimplify_omp_ctxp
->loop_iter_var
.create (TREE_VEC_LENGTH
11616 (OMP_FOR_INIT (for_stmt
))
11619 int collapse
= 1, tile
= 0;
11620 c
= omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_COLLAPSE
);
11622 collapse
= tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (c
));
11623 c
= omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_TILE
);
11625 tile
= list_length (OMP_CLAUSE_TILE_LIST (c
));
11626 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
11628 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), i
);
11629 gcc_assert (TREE_CODE (t
) == MODIFY_EXPR
);
11630 decl
= TREE_OPERAND (t
, 0);
11631 gcc_assert (DECL_P (decl
));
11632 gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl
))
11633 || POINTER_TYPE_P (TREE_TYPE (decl
)));
11636 if (TREE_CODE (for_stmt
) == OMP_FOR
&& OMP_FOR_ORIG_DECLS (for_stmt
))
11638 tree orig_decl
= TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
), i
);
11639 if (TREE_CODE (orig_decl
) == TREE_LIST
)
11641 orig_decl
= TREE_PURPOSE (orig_decl
);
11645 gimplify_omp_ctxp
->loop_iter_var
.quick_push (orig_decl
);
11648 gimplify_omp_ctxp
->loop_iter_var
.quick_push (decl
);
11649 gimplify_omp_ctxp
->loop_iter_var
.quick_push (decl
);
11652 /* Make sure the iteration variable is private. */
11653 tree c
= NULL_TREE
;
11654 tree c2
= NULL_TREE
;
11655 if (orig_for_stmt
!= for_stmt
)
11657 /* Preserve this information until we gimplify the inner simd. */
11659 && bitmap_bit_p (has_decl_expr
, DECL_UID (decl
)))
11660 TREE_PRIVATE (t
) = 1;
11662 else if (ort
== ORT_SIMD
)
11664 splay_tree_node n
= splay_tree_lookup (gimplify_omp_ctxp
->variables
,
11665 (splay_tree_key
) decl
);
11666 omp_is_private (gimplify_omp_ctxp
, decl
,
11667 1 + (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
))
11669 if (n
!= NULL
&& (n
->value
& GOVD_DATA_SHARE_CLASS
) != 0)
11671 omp_notice_variable (gimplify_omp_ctxp
, decl
, true);
11672 if (n
->value
& GOVD_LASTPRIVATE_CONDITIONAL
)
11673 for (tree c3
= omp_find_clause (OMP_FOR_CLAUSES (for_stmt
),
11674 OMP_CLAUSE_LASTPRIVATE
);
11675 c3
; c3
= omp_find_clause (OMP_CLAUSE_CHAIN (c3
),
11676 OMP_CLAUSE_LASTPRIVATE
))
11677 if (OMP_CLAUSE_DECL (c3
) == decl
)
11679 warning_at (OMP_CLAUSE_LOCATION (c3
), 0,
11680 "conditional %<lastprivate%> on loop "
11681 "iterator %qD ignored", decl
);
11682 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3
) = 0;
11683 n
->value
&= ~GOVD_LASTPRIVATE_CONDITIONAL
;
11686 else if (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)) == 1 && !loop_p
)
11688 c
= build_omp_clause (input_location
, OMP_CLAUSE_LINEAR
);
11689 OMP_CLAUSE_LINEAR_NO_COPYIN (c
) = 1;
11690 unsigned int flags
= GOVD_LINEAR
| GOVD_EXPLICIT
| GOVD_SEEN
;
11692 && bitmap_bit_p (has_decl_expr
, DECL_UID (decl
)))
11693 || TREE_PRIVATE (t
))
11695 OMP_CLAUSE_LINEAR_NO_COPYOUT (c
) = 1;
11696 flags
|= GOVD_LINEAR_LASTPRIVATE_NO_OUTER
;
11698 struct gimplify_omp_ctx
*outer
11699 = gimplify_omp_ctxp
->outer_context
;
11700 if (outer
&& !OMP_CLAUSE_LINEAR_NO_COPYOUT (c
))
11702 if (outer
->region_type
== ORT_WORKSHARE
11703 && outer
->combined_loop
)
11705 n
= splay_tree_lookup (outer
->variables
,
11706 (splay_tree_key
)decl
);
11707 if (n
!= NULL
&& (n
->value
& GOVD_LOCAL
) != 0)
11709 OMP_CLAUSE_LINEAR_NO_COPYOUT (c
) = 1;
11710 flags
|= GOVD_LINEAR_LASTPRIVATE_NO_OUTER
;
11714 struct gimplify_omp_ctx
*octx
= outer
->outer_context
;
11716 && octx
->region_type
== ORT_COMBINED_PARALLEL
11717 && octx
->outer_context
11718 && (octx
->outer_context
->region_type
11720 && octx
->outer_context
->combined_loop
)
11722 octx
= octx
->outer_context
;
11723 n
= splay_tree_lookup (octx
->variables
,
11724 (splay_tree_key
)decl
);
11725 if (n
!= NULL
&& (n
->value
& GOVD_LOCAL
) != 0)
11727 OMP_CLAUSE_LINEAR_NO_COPYOUT (c
) = 1;
11728 flags
|= GOVD_LINEAR_LASTPRIVATE_NO_OUTER
;
11735 OMP_CLAUSE_DECL (c
) = decl
;
11736 OMP_CLAUSE_CHAIN (c
) = OMP_FOR_CLAUSES (for_stmt
);
11737 OMP_FOR_CLAUSES (for_stmt
) = c
;
11738 omp_add_variable (gimplify_omp_ctxp
, decl
, flags
);
11739 if (outer
&& !OMP_CLAUSE_LINEAR_NO_COPYOUT (c
))
11741 if (outer
->region_type
== ORT_WORKSHARE
11742 && outer
->combined_loop
)
11744 if (outer
->outer_context
11745 && (outer
->outer_context
->region_type
11746 == ORT_COMBINED_PARALLEL
))
11747 outer
= outer
->outer_context
;
11748 else if (omp_check_private (outer
, decl
, false))
11751 else if (((outer
->region_type
& ORT_TASKLOOP
)
11753 && outer
->combined_loop
11754 && !omp_check_private (gimplify_omp_ctxp
,
11757 else if (outer
->region_type
!= ORT_COMBINED_PARALLEL
)
11759 omp_notice_variable (outer
, decl
, true);
11764 n
= splay_tree_lookup (outer
->variables
,
11765 (splay_tree_key
)decl
);
11766 if (n
== NULL
|| (n
->value
& GOVD_DATA_SHARE_CLASS
) == 0)
11768 omp_add_variable (outer
, decl
,
11769 GOVD_LASTPRIVATE
| GOVD_SEEN
);
11770 if (outer
->region_type
== ORT_COMBINED_PARALLEL
11771 && outer
->outer_context
11772 && (outer
->outer_context
->region_type
11774 && outer
->outer_context
->combined_loop
)
11776 outer
= outer
->outer_context
;
11777 n
= splay_tree_lookup (outer
->variables
,
11778 (splay_tree_key
)decl
);
11779 if (omp_check_private (outer
, decl
, false))
11782 || ((n
->value
& GOVD_DATA_SHARE_CLASS
)
11784 omp_add_variable (outer
, decl
,
11790 if (outer
&& outer
->outer_context
11791 && ((outer
->outer_context
->region_type
11792 & ORT_COMBINED_TEAMS
) == ORT_COMBINED_TEAMS
11793 || (((outer
->region_type
& ORT_TASKLOOP
)
11795 && (outer
->outer_context
->region_type
11796 == ORT_COMBINED_PARALLEL
))))
11798 outer
= outer
->outer_context
;
11799 n
= splay_tree_lookup (outer
->variables
,
11800 (splay_tree_key
)decl
);
11802 || (n
->value
& GOVD_DATA_SHARE_CLASS
) == 0)
11803 omp_add_variable (outer
, decl
,
11804 GOVD_SHARED
| GOVD_SEEN
);
11808 if (outer
&& outer
->outer_context
)
11809 omp_notice_variable (outer
->outer_context
, decl
,
11819 || !bitmap_bit_p (has_decl_expr
, DECL_UID (decl
)));
11820 if (TREE_PRIVATE (t
))
11821 lastprivate
= false;
11822 if (loop_p
&& OMP_FOR_ORIG_DECLS (for_stmt
))
11824 tree elt
= TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
), i
);
11825 if (TREE_CODE (elt
) == TREE_LIST
&& TREE_PURPOSE (elt
))
11826 lastprivate
= false;
11829 struct gimplify_omp_ctx
*outer
11830 = gimplify_omp_ctxp
->outer_context
;
11831 if (outer
&& lastprivate
)
11833 if (outer
->region_type
== ORT_WORKSHARE
11834 && outer
->combined_loop
)
11836 n
= splay_tree_lookup (outer
->variables
,
11837 (splay_tree_key
)decl
);
11838 if (n
!= NULL
&& (n
->value
& GOVD_LOCAL
) != 0)
11840 lastprivate
= false;
11843 else if (outer
->outer_context
11844 && (outer
->outer_context
->region_type
11845 == ORT_COMBINED_PARALLEL
))
11846 outer
= outer
->outer_context
;
11847 else if (omp_check_private (outer
, decl
, false))
11850 else if (((outer
->region_type
& ORT_TASKLOOP
)
11852 && outer
->combined_loop
11853 && !omp_check_private (gimplify_omp_ctxp
,
11856 else if (outer
->region_type
!= ORT_COMBINED_PARALLEL
)
11858 omp_notice_variable (outer
, decl
, true);
11863 n
= splay_tree_lookup (outer
->variables
,
11864 (splay_tree_key
)decl
);
11865 if (n
== NULL
|| (n
->value
& GOVD_DATA_SHARE_CLASS
) == 0)
11867 omp_add_variable (outer
, decl
,
11868 GOVD_LASTPRIVATE
| GOVD_SEEN
);
11869 if (outer
->region_type
== ORT_COMBINED_PARALLEL
11870 && outer
->outer_context
11871 && (outer
->outer_context
->region_type
11873 && outer
->outer_context
->combined_loop
)
11875 outer
= outer
->outer_context
;
11876 n
= splay_tree_lookup (outer
->variables
,
11877 (splay_tree_key
)decl
);
11878 if (omp_check_private (outer
, decl
, false))
11881 || ((n
->value
& GOVD_DATA_SHARE_CLASS
)
11883 omp_add_variable (outer
, decl
,
11889 if (outer
&& outer
->outer_context
11890 && ((outer
->outer_context
->region_type
11891 & ORT_COMBINED_TEAMS
) == ORT_COMBINED_TEAMS
11892 || (((outer
->region_type
& ORT_TASKLOOP
)
11894 && (outer
->outer_context
->region_type
11895 == ORT_COMBINED_PARALLEL
))))
11897 outer
= outer
->outer_context
;
11898 n
= splay_tree_lookup (outer
->variables
,
11899 (splay_tree_key
)decl
);
11901 || (n
->value
& GOVD_DATA_SHARE_CLASS
) == 0)
11902 omp_add_variable (outer
, decl
,
11903 GOVD_SHARED
| GOVD_SEEN
);
11907 if (outer
&& outer
->outer_context
)
11908 omp_notice_variable (outer
->outer_context
, decl
,
11914 c
= build_omp_clause (input_location
,
11915 lastprivate
? OMP_CLAUSE_LASTPRIVATE
11916 : OMP_CLAUSE_PRIVATE
);
11917 OMP_CLAUSE_DECL (c
) = decl
;
11918 OMP_CLAUSE_CHAIN (c
) = OMP_FOR_CLAUSES (for_stmt
);
11919 OMP_FOR_CLAUSES (for_stmt
) = c
;
11920 omp_add_variable (gimplify_omp_ctxp
, decl
,
11921 (lastprivate
? GOVD_LASTPRIVATE
: GOVD_PRIVATE
)
11922 | GOVD_EXPLICIT
| GOVD_SEEN
);
11926 else if (omp_is_private (gimplify_omp_ctxp
, decl
, 0))
11928 omp_notice_variable (gimplify_omp_ctxp
, decl
, true);
11929 splay_tree_node n
= splay_tree_lookup (gimplify_omp_ctxp
->variables
,
11930 (splay_tree_key
) decl
);
11931 if (n
&& (n
->value
& GOVD_LASTPRIVATE_CONDITIONAL
))
11932 for (tree c3
= omp_find_clause (OMP_FOR_CLAUSES (for_stmt
),
11933 OMP_CLAUSE_LASTPRIVATE
);
11934 c3
; c3
= omp_find_clause (OMP_CLAUSE_CHAIN (c3
),
11935 OMP_CLAUSE_LASTPRIVATE
))
11936 if (OMP_CLAUSE_DECL (c3
) == decl
)
11938 warning_at (OMP_CLAUSE_LOCATION (c3
), 0,
11939 "conditional %<lastprivate%> on loop "
11940 "iterator %qD ignored", decl
);
11941 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3
) = 0;
11942 n
->value
&= ~GOVD_LASTPRIVATE_CONDITIONAL
;
11946 omp_add_variable (gimplify_omp_ctxp
, decl
, GOVD_PRIVATE
| GOVD_SEEN
);
11948 /* If DECL is not a gimple register, create a temporary variable to act
11949 as an iteration counter. This is valid, since DECL cannot be
11950 modified in the body of the loop. Similarly for any iteration vars
11951 in simd with collapse > 1 where the iterator vars must be
11953 if (orig_for_stmt
!= for_stmt
)
11955 else if (!is_gimple_reg (decl
)
11956 || (ort
== ORT_SIMD
11957 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)) > 1))
11959 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
11960 /* Make sure omp_add_variable is not called on it prematurely.
11961 We call it ourselves a few lines later. */
11962 gimplify_omp_ctxp
= NULL
;
11963 var
= create_tmp_var (TREE_TYPE (decl
), get_name (decl
));
11964 gimplify_omp_ctxp
= ctx
;
11965 TREE_OPERAND (t
, 0) = var
;
11967 gimplify_seq_add_stmt (&for_body
, gimple_build_assign (decl
, var
));
11969 if (ort
== ORT_SIMD
11970 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)) == 1)
11972 c2
= build_omp_clause (input_location
, OMP_CLAUSE_LINEAR
);
11973 OMP_CLAUSE_LINEAR_NO_COPYIN (c2
) = 1;
11974 OMP_CLAUSE_LINEAR_NO_COPYOUT (c2
) = 1;
11975 OMP_CLAUSE_DECL (c2
) = var
;
11976 OMP_CLAUSE_CHAIN (c2
) = OMP_FOR_CLAUSES (for_stmt
);
11977 OMP_FOR_CLAUSES (for_stmt
) = c2
;
11978 omp_add_variable (gimplify_omp_ctxp
, var
,
11979 GOVD_LINEAR
| GOVD_EXPLICIT
| GOVD_SEEN
);
11980 if (c
== NULL_TREE
)
11987 omp_add_variable (gimplify_omp_ctxp
, var
,
11988 GOVD_PRIVATE
| GOVD_SEEN
);
11993 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
)
11995 tree lb
= TREE_OPERAND (t
, 1);
11996 tret
= gimplify_expr (&TREE_VEC_ELT (lb
, 1), &for_pre_body
, NULL
,
11997 is_gimple_val
, fb_rvalue
, false);
11998 ret
= MIN (ret
, tret
);
11999 tret
= gimplify_expr (&TREE_VEC_ELT (lb
, 2), &for_pre_body
, NULL
,
12000 is_gimple_val
, fb_rvalue
, false);
12003 tret
= gimplify_expr (&TREE_OPERAND (t
, 1), &for_pre_body
, NULL
,
12004 is_gimple_val
, fb_rvalue
, false);
12005 ret
= MIN (ret
, tret
);
12006 if (ret
== GS_ERROR
)
12009 /* Handle OMP_FOR_COND. */
12010 t
= TREE_VEC_ELT (OMP_FOR_COND (for_stmt
), i
);
12011 gcc_assert (COMPARISON_CLASS_P (t
));
12012 gcc_assert (TREE_OPERAND (t
, 0) == decl
);
12014 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
)
12016 tree ub
= TREE_OPERAND (t
, 1);
12017 tret
= gimplify_expr (&TREE_VEC_ELT (ub
, 1), &for_pre_body
, NULL
,
12018 is_gimple_val
, fb_rvalue
, false);
12019 ret
= MIN (ret
, tret
);
12020 tret
= gimplify_expr (&TREE_VEC_ELT (ub
, 2), &for_pre_body
, NULL
,
12021 is_gimple_val
, fb_rvalue
, false);
12024 tret
= gimplify_expr (&TREE_OPERAND (t
, 1), &for_pre_body
, NULL
,
12025 is_gimple_val
, fb_rvalue
, false);
12026 ret
= MIN (ret
, tret
);
12028 /* Handle OMP_FOR_INCR. */
12029 t
= TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
);
12030 switch (TREE_CODE (t
))
12032 case PREINCREMENT_EXPR
:
12033 case POSTINCREMENT_EXPR
:
12035 tree decl
= TREE_OPERAND (t
, 0);
12036 /* c_omp_for_incr_canonicalize_ptr() should have been
12037 called to massage things appropriately. */
12038 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl
)));
12040 if (orig_for_stmt
!= for_stmt
)
12042 t
= build_int_cst (TREE_TYPE (decl
), 1);
12044 OMP_CLAUSE_LINEAR_STEP (c
) = t
;
12045 t
= build2 (PLUS_EXPR
, TREE_TYPE (decl
), var
, t
);
12046 t
= build2 (MODIFY_EXPR
, TREE_TYPE (var
), var
, t
);
12047 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
) = t
;
12051 case PREDECREMENT_EXPR
:
12052 case POSTDECREMENT_EXPR
:
12053 /* c_omp_for_incr_canonicalize_ptr() should have been
12054 called to massage things appropriately. */
12055 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl
)));
12056 if (orig_for_stmt
!= for_stmt
)
12058 t
= build_int_cst (TREE_TYPE (decl
), -1);
12060 OMP_CLAUSE_LINEAR_STEP (c
) = t
;
12061 t
= build2 (PLUS_EXPR
, TREE_TYPE (decl
), var
, t
);
12062 t
= build2 (MODIFY_EXPR
, TREE_TYPE (var
), var
, t
);
12063 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
) = t
;
12067 gcc_assert (TREE_OPERAND (t
, 0) == decl
);
12068 TREE_OPERAND (t
, 0) = var
;
12070 t
= TREE_OPERAND (t
, 1);
12071 switch (TREE_CODE (t
))
12074 if (TREE_OPERAND (t
, 1) == decl
)
12076 TREE_OPERAND (t
, 1) = TREE_OPERAND (t
, 0);
12077 TREE_OPERAND (t
, 0) = var
;
12083 case POINTER_PLUS_EXPR
:
12084 gcc_assert (TREE_OPERAND (t
, 0) == decl
);
12085 TREE_OPERAND (t
, 0) = var
;
12088 gcc_unreachable ();
12091 tret
= gimplify_expr (&TREE_OPERAND (t
, 1), &for_pre_body
, NULL
,
12092 is_gimple_val
, fb_rvalue
, false);
12093 ret
= MIN (ret
, tret
);
12096 tree step
= TREE_OPERAND (t
, 1);
12097 tree stept
= TREE_TYPE (decl
);
12098 if (POINTER_TYPE_P (stept
))
12100 step
= fold_convert (stept
, step
);
12101 if (TREE_CODE (t
) == MINUS_EXPR
)
12102 step
= fold_build1 (NEGATE_EXPR
, stept
, step
);
12103 OMP_CLAUSE_LINEAR_STEP (c
) = step
;
12104 if (step
!= TREE_OPERAND (t
, 1))
12106 tret
= gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c
),
12107 &for_pre_body
, NULL
,
12108 is_gimple_val
, fb_rvalue
, false);
12109 ret
= MIN (ret
, tret
);
12115 gcc_unreachable ();
12121 OMP_CLAUSE_LINEAR_STEP (c2
) = OMP_CLAUSE_LINEAR_STEP (c
);
12124 if ((var
!= decl
|| collapse
> 1 || tile
) && orig_for_stmt
== for_stmt
)
12126 for (c
= OMP_FOR_CLAUSES (for_stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
12127 if (((OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
12128 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
) == NULL
)
12129 || (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINEAR
12130 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c
)
12131 && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c
) == NULL
))
12132 && OMP_CLAUSE_DECL (c
) == decl
)
12134 if (is_doacross
&& (collapse
== 1 || i
>= collapse
))
12138 t
= TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
);
12139 gcc_assert (TREE_CODE (t
) == MODIFY_EXPR
);
12140 gcc_assert (TREE_OPERAND (t
, 0) == var
);
12141 t
= TREE_OPERAND (t
, 1);
12142 gcc_assert (TREE_CODE (t
) == PLUS_EXPR
12143 || TREE_CODE (t
) == MINUS_EXPR
12144 || TREE_CODE (t
) == POINTER_PLUS_EXPR
);
12145 gcc_assert (TREE_OPERAND (t
, 0) == var
);
12146 t
= build2 (TREE_CODE (t
), TREE_TYPE (decl
),
12147 is_doacross
? var
: decl
,
12148 TREE_OPERAND (t
, 1));
12151 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
)
12152 seq
= &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
);
12154 seq
= &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c
);
12155 push_gimplify_context ();
12156 gimplify_assign (decl
, t
, seq
);
12157 gimple
*bind
= NULL
;
12158 if (gimplify_ctxp
->temps
)
12160 bind
= gimple_build_bind (NULL_TREE
, *seq
, NULL_TREE
);
12162 gimplify_seq_add_stmt (seq
, bind
);
12164 pop_gimplify_context (bind
);
12167 if (OMP_FOR_NON_RECTANGULAR (for_stmt
) && var
!= decl
)
12168 for (int j
= i
+ 1; j
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); j
++)
12170 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), j
);
12171 gcc_assert (TREE_CODE (t
) == MODIFY_EXPR
);
12172 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
12173 && TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) == decl
)
12174 TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) = var
;
12175 t
= TREE_VEC_ELT (OMP_FOR_COND (for_stmt
), j
);
12176 gcc_assert (COMPARISON_CLASS_P (t
));
12177 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
12178 && TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) == decl
)
12179 TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) = var
;
12183 BITMAP_FREE (has_decl_expr
);
12185 if (TREE_CODE (orig_for_stmt
) == OMP_TASKLOOP
12186 || (loop_p
&& orig_for_stmt
== for_stmt
))
12188 push_gimplify_context ();
12189 if (TREE_CODE (OMP_FOR_BODY (orig_for_stmt
)) != BIND_EXPR
)
12191 OMP_FOR_BODY (orig_for_stmt
)
12192 = build3 (BIND_EXPR
, void_type_node
, NULL
,
12193 OMP_FOR_BODY (orig_for_stmt
), NULL
);
12194 TREE_SIDE_EFFECTS (OMP_FOR_BODY (orig_for_stmt
)) = 1;
12198 gimple
*g
= gimplify_and_return_first (OMP_FOR_BODY (orig_for_stmt
),
12201 if (TREE_CODE (orig_for_stmt
) == OMP_TASKLOOP
12202 || (loop_p
&& orig_for_stmt
== for_stmt
))
12204 if (gimple_code (g
) == GIMPLE_BIND
)
12205 pop_gimplify_context (g
);
12207 pop_gimplify_context (NULL
);
12210 if (orig_for_stmt
!= for_stmt
)
12211 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
12213 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), i
);
12214 decl
= TREE_OPERAND (t
, 0);
12215 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
12216 if (TREE_CODE (orig_for_stmt
) == OMP_TASKLOOP
)
12217 gimplify_omp_ctxp
= ctx
->outer_context
;
12218 var
= create_tmp_var (TREE_TYPE (decl
), get_name (decl
));
12219 gimplify_omp_ctxp
= ctx
;
12220 omp_add_variable (gimplify_omp_ctxp
, var
, GOVD_PRIVATE
| GOVD_SEEN
);
12221 TREE_OPERAND (t
, 0) = var
;
12222 t
= TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
);
12223 TREE_OPERAND (t
, 1) = copy_node (TREE_OPERAND (t
, 1));
12224 TREE_OPERAND (TREE_OPERAND (t
, 1), 0) = var
;
12225 if (OMP_FOR_NON_RECTANGULAR (for_stmt
))
12226 for (int j
= i
+ 1;
12227 j
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); j
++)
12229 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), j
);
12230 gcc_assert (TREE_CODE (t
) == MODIFY_EXPR
);
12231 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
12232 && TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) == decl
)
12234 TREE_OPERAND (t
, 1) = copy_node (TREE_OPERAND (t
, 1));
12235 TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) = var
;
12237 t
= TREE_VEC_ELT (OMP_FOR_COND (for_stmt
), j
);
12238 gcc_assert (COMPARISON_CLASS_P (t
));
12239 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
12240 && TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) == decl
)
12242 TREE_OPERAND (t
, 1) = copy_node (TREE_OPERAND (t
, 1));
12243 TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) = var
;
12248 gimplify_adjust_omp_clauses (pre_p
, for_body
,
12249 &OMP_FOR_CLAUSES (orig_for_stmt
),
12250 TREE_CODE (orig_for_stmt
));
12253 switch (TREE_CODE (orig_for_stmt
))
12255 case OMP_FOR
: kind
= GF_OMP_FOR_KIND_FOR
; break;
12256 case OMP_SIMD
: kind
= GF_OMP_FOR_KIND_SIMD
; break;
12257 case OMP_DISTRIBUTE
: kind
= GF_OMP_FOR_KIND_DISTRIBUTE
; break;
12258 case OMP_TASKLOOP
: kind
= GF_OMP_FOR_KIND_TASKLOOP
; break;
12259 case OACC_LOOP
: kind
= GF_OMP_FOR_KIND_OACC_LOOP
; break;
12261 gcc_unreachable ();
12263 if (loop_p
&& kind
== GF_OMP_FOR_KIND_SIMD
)
12265 gimplify_seq_add_seq (pre_p
, for_pre_body
);
12266 for_pre_body
= NULL
;
12268 gfor
= gimple_build_omp_for (for_body
, kind
, OMP_FOR_CLAUSES (orig_for_stmt
),
12269 TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)),
12271 if (orig_for_stmt
!= for_stmt
)
12272 gimple_omp_for_set_combined_p (gfor
, true);
12273 if (gimplify_omp_ctxp
12274 && (gimplify_omp_ctxp
->combined_loop
12275 || (gimplify_omp_ctxp
->region_type
== ORT_COMBINED_PARALLEL
12276 && gimplify_omp_ctxp
->outer_context
12277 && gimplify_omp_ctxp
->outer_context
->combined_loop
)))
12279 gimple_omp_for_set_combined_into_p (gfor
, true);
12280 if (gimplify_omp_ctxp
->combined_loop
)
12281 gcc_assert (TREE_CODE (orig_for_stmt
) == OMP_SIMD
);
12283 gcc_assert (TREE_CODE (orig_for_stmt
) == OMP_FOR
);
12286 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
12288 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), i
);
12289 gimple_omp_for_set_index (gfor
, i
, TREE_OPERAND (t
, 0));
12290 gimple_omp_for_set_initial (gfor
, i
, TREE_OPERAND (t
, 1));
12291 t
= TREE_VEC_ELT (OMP_FOR_COND (for_stmt
), i
);
12292 gimple_omp_for_set_cond (gfor
, i
, TREE_CODE (t
));
12293 gimple_omp_for_set_final (gfor
, i
, TREE_OPERAND (t
, 1));
12294 t
= TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
);
12295 gimple_omp_for_set_incr (gfor
, i
, TREE_OPERAND (t
, 1));
12298 /* OMP_TASKLOOP is gimplified as two GIMPLE_OMP_FOR taskloop
12299 constructs with GIMPLE_OMP_TASK sandwiched in between them.
12300 The outer taskloop stands for computing the number of iterations,
12301 counts for collapsed loops and holding taskloop specific clauses.
12302 The task construct stands for the effect of data sharing on the
12303 explicit task it creates and the inner taskloop stands for expansion
12304 of the static loop inside of the explicit task construct. */
12305 if (TREE_CODE (orig_for_stmt
) == OMP_TASKLOOP
)
12307 tree
*gfor_clauses_ptr
= gimple_omp_for_clauses_ptr (gfor
);
12308 tree task_clauses
= NULL_TREE
;
12309 tree c
= *gfor_clauses_ptr
;
12310 tree
*gtask_clauses_ptr
= &task_clauses
;
12311 tree outer_for_clauses
= NULL_TREE
;
12312 tree
*gforo_clauses_ptr
= &outer_for_clauses
;
12313 bitmap lastprivate_uids
= NULL
;
12314 if (omp_find_clause (c
, OMP_CLAUSE_ALLOCATE
))
12316 c
= omp_find_clause (c
, OMP_CLAUSE_LASTPRIVATE
);
12319 lastprivate_uids
= BITMAP_ALLOC (NULL
);
12320 for (; c
; c
= omp_find_clause (OMP_CLAUSE_CHAIN (c
),
12321 OMP_CLAUSE_LASTPRIVATE
))
12322 bitmap_set_bit (lastprivate_uids
,
12323 DECL_UID (OMP_CLAUSE_DECL (c
)));
12325 c
= *gfor_clauses_ptr
;
12327 for (; c
; c
= OMP_CLAUSE_CHAIN (c
))
12328 switch (OMP_CLAUSE_CODE (c
))
12330 /* These clauses are allowed on task, move them there. */
12331 case OMP_CLAUSE_SHARED
:
12332 case OMP_CLAUSE_FIRSTPRIVATE
:
12333 case OMP_CLAUSE_DEFAULT
:
12334 case OMP_CLAUSE_IF
:
12335 case OMP_CLAUSE_UNTIED
:
12336 case OMP_CLAUSE_FINAL
:
12337 case OMP_CLAUSE_MERGEABLE
:
12338 case OMP_CLAUSE_PRIORITY
:
12339 case OMP_CLAUSE_REDUCTION
:
12340 case OMP_CLAUSE_IN_REDUCTION
:
12341 *gtask_clauses_ptr
= c
;
12342 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
12344 case OMP_CLAUSE_PRIVATE
:
12345 if (OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c
))
12347 /* We want private on outer for and firstprivate
12350 = build_omp_clause (OMP_CLAUSE_LOCATION (c
),
12351 OMP_CLAUSE_FIRSTPRIVATE
);
12352 OMP_CLAUSE_DECL (*gtask_clauses_ptr
) = OMP_CLAUSE_DECL (c
);
12353 lang_hooks
.decls
.omp_finish_clause (*gtask_clauses_ptr
, NULL
,
12355 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr
);
12356 *gforo_clauses_ptr
= c
;
12357 gforo_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
12361 *gtask_clauses_ptr
= c
;
12362 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
12365 /* These clauses go into outer taskloop clauses. */
12366 case OMP_CLAUSE_GRAINSIZE
:
12367 case OMP_CLAUSE_NUM_TASKS
:
12368 case OMP_CLAUSE_NOGROUP
:
12369 *gforo_clauses_ptr
= c
;
12370 gforo_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
12372 /* Collapse clause we duplicate on both taskloops. */
12373 case OMP_CLAUSE_COLLAPSE
:
12374 *gfor_clauses_ptr
= c
;
12375 gfor_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
12376 *gforo_clauses_ptr
= copy_node (c
);
12377 gforo_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr
);
12379 /* For lastprivate, keep the clause on inner taskloop, and add
12380 a shared clause on task. If the same decl is also firstprivate,
12381 add also firstprivate clause on the inner taskloop. */
12382 case OMP_CLAUSE_LASTPRIVATE
:
12383 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c
))
12385 /* For taskloop C++ lastprivate IVs, we want:
12386 1) private on outer taskloop
12387 2) firstprivate and shared on task
12388 3) lastprivate on inner taskloop */
12390 = build_omp_clause (OMP_CLAUSE_LOCATION (c
),
12391 OMP_CLAUSE_FIRSTPRIVATE
);
12392 OMP_CLAUSE_DECL (*gtask_clauses_ptr
) = OMP_CLAUSE_DECL (c
);
12393 lang_hooks
.decls
.omp_finish_clause (*gtask_clauses_ptr
, NULL
,
12395 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr
);
12396 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
) = 1;
12397 *gforo_clauses_ptr
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
12398 OMP_CLAUSE_PRIVATE
);
12399 OMP_CLAUSE_DECL (*gforo_clauses_ptr
) = OMP_CLAUSE_DECL (c
);
12400 OMP_CLAUSE_PRIVATE_TASKLOOP_IV (*gforo_clauses_ptr
) = 1;
12401 TREE_TYPE (*gforo_clauses_ptr
) = TREE_TYPE (c
);
12402 gforo_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr
);
12404 *gfor_clauses_ptr
= c
;
12405 gfor_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
12407 = build_omp_clause (OMP_CLAUSE_LOCATION (c
), OMP_CLAUSE_SHARED
);
12408 OMP_CLAUSE_DECL (*gtask_clauses_ptr
) = OMP_CLAUSE_DECL (c
);
12409 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
))
12410 OMP_CLAUSE_SHARED_FIRSTPRIVATE (*gtask_clauses_ptr
) = 1;
12412 = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr
);
12414 /* Allocate clause we duplicate on task and inner taskloop
12415 if the decl is lastprivate, otherwise just put on task. */
12416 case OMP_CLAUSE_ALLOCATE
:
12417 if (lastprivate_uids
12418 && bitmap_bit_p (lastprivate_uids
,
12419 DECL_UID (OMP_CLAUSE_DECL (c
))))
12421 if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
)
12422 && DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
)))
12424 /* Additionally, put firstprivate clause on task
12425 for the allocator if it is not constant. */
12427 = build_omp_clause (OMP_CLAUSE_LOCATION (c
),
12428 OMP_CLAUSE_FIRSTPRIVATE
);
12429 OMP_CLAUSE_DECL (*gtask_clauses_ptr
)
12430 = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
);
12431 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr
);
12433 *gfor_clauses_ptr
= c
;
12434 gfor_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
12435 *gtask_clauses_ptr
= copy_node (c
);
12436 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr
);
12440 *gtask_clauses_ptr
= c
;
12441 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
12445 gcc_unreachable ();
12447 *gfor_clauses_ptr
= NULL_TREE
;
12448 *gtask_clauses_ptr
= NULL_TREE
;
12449 *gforo_clauses_ptr
= NULL_TREE
;
12450 BITMAP_FREE (lastprivate_uids
);
12451 g
= gimple_build_bind (NULL_TREE
, gfor
, NULL_TREE
);
12452 g
= gimple_build_omp_task (g
, task_clauses
, NULL_TREE
, NULL_TREE
,
12453 NULL_TREE
, NULL_TREE
, NULL_TREE
);
12454 gimple_omp_task_set_taskloop_p (g
, true);
12455 g
= gimple_build_bind (NULL_TREE
, g
, NULL_TREE
);
12457 = gimple_build_omp_for (g
, GF_OMP_FOR_KIND_TASKLOOP
, outer_for_clauses
,
12458 gimple_omp_for_collapse (gfor
),
12459 gimple_omp_for_pre_body (gfor
));
12460 gimple_omp_for_set_pre_body (gfor
, NULL
);
12461 gimple_omp_for_set_combined_p (gforo
, true);
12462 gimple_omp_for_set_combined_into_p (gfor
, true);
12463 for (i
= 0; i
< (int) gimple_omp_for_collapse (gfor
); i
++)
12465 tree type
= TREE_TYPE (gimple_omp_for_index (gfor
, i
));
12466 tree v
= create_tmp_var (type
);
12467 gimple_omp_for_set_index (gforo
, i
, v
);
12468 t
= unshare_expr (gimple_omp_for_initial (gfor
, i
));
12469 gimple_omp_for_set_initial (gforo
, i
, t
);
12470 gimple_omp_for_set_cond (gforo
, i
,
12471 gimple_omp_for_cond (gfor
, i
));
12472 t
= unshare_expr (gimple_omp_for_final (gfor
, i
));
12473 gimple_omp_for_set_final (gforo
, i
, t
);
12474 t
= unshare_expr (gimple_omp_for_incr (gfor
, i
));
12475 gcc_assert (TREE_OPERAND (t
, 0) == gimple_omp_for_index (gfor
, i
));
12476 TREE_OPERAND (t
, 0) = v
;
12477 gimple_omp_for_set_incr (gforo
, i
, t
);
12478 t
= build_omp_clause (input_location
, OMP_CLAUSE_PRIVATE
);
12479 OMP_CLAUSE_DECL (t
) = v
;
12480 OMP_CLAUSE_CHAIN (t
) = gimple_omp_for_clauses (gforo
);
12481 gimple_omp_for_set_clauses (gforo
, t
);
12482 if (OMP_FOR_NON_RECTANGULAR (for_stmt
))
12484 tree
*p1
= NULL
, *p2
= NULL
;
12485 t
= gimple_omp_for_initial (gforo
, i
);
12486 if (TREE_CODE (t
) == TREE_VEC
)
12487 p1
= &TREE_VEC_ELT (t
, 0);
12488 t
= gimple_omp_for_final (gforo
, i
);
12489 if (TREE_CODE (t
) == TREE_VEC
)
12492 p2
= &TREE_VEC_ELT (t
, 0);
12494 p1
= &TREE_VEC_ELT (t
, 0);
12499 for (j
= 0; j
< i
; j
++)
12500 if (*p1
== gimple_omp_for_index (gfor
, j
))
12502 *p1
= gimple_omp_for_index (gforo
, j
);
12507 gcc_assert (j
< i
);
12511 gimplify_seq_add_stmt (pre_p
, gforo
);
12514 gimplify_seq_add_stmt (pre_p
, gfor
);
12516 if (TREE_CODE (orig_for_stmt
) == OMP_FOR
)
12518 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
12519 unsigned lastprivate_conditional
= 0;
12521 && (ctx
->region_type
== ORT_TARGET_DATA
12522 || ctx
->region_type
== ORT_TASKGROUP
))
12523 ctx
= ctx
->outer_context
;
12524 if (ctx
&& (ctx
->region_type
& ORT_PARALLEL
) != 0)
12525 for (tree c
= gimple_omp_for_clauses (gfor
);
12526 c
; c
= OMP_CLAUSE_CHAIN (c
))
12527 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
12528 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
))
12529 ++lastprivate_conditional
;
12530 if (lastprivate_conditional
)
12532 struct omp_for_data fd
;
12533 omp_extract_for_data (gfor
, &fd
, NULL
);
12534 tree type
= build_array_type_nelts (unsigned_type_for (fd
.iter_type
),
12535 lastprivate_conditional
);
12536 tree var
= create_tmp_var_raw (type
);
12537 tree c
= build_omp_clause (UNKNOWN_LOCATION
, OMP_CLAUSE__CONDTEMP_
);
12538 OMP_CLAUSE_DECL (c
) = var
;
12539 OMP_CLAUSE_CHAIN (c
) = gimple_omp_for_clauses (gfor
);
12540 gimple_omp_for_set_clauses (gfor
, c
);
12541 omp_add_variable (ctx
, var
, GOVD_CONDTEMP
| GOVD_SEEN
);
12544 else if (TREE_CODE (orig_for_stmt
) == OMP_SIMD
)
12546 unsigned lastprivate_conditional
= 0;
12547 for (tree c
= gimple_omp_for_clauses (gfor
); c
; c
= OMP_CLAUSE_CHAIN (c
))
12548 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
12549 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
))
12550 ++lastprivate_conditional
;
12551 if (lastprivate_conditional
)
12553 struct omp_for_data fd
;
12554 omp_extract_for_data (gfor
, &fd
, NULL
);
12555 tree type
= unsigned_type_for (fd
.iter_type
);
12556 while (lastprivate_conditional
--)
12558 tree c
= build_omp_clause (UNKNOWN_LOCATION
,
12559 OMP_CLAUSE__CONDTEMP_
);
12560 OMP_CLAUSE_DECL (c
) = create_tmp_var (type
);
12561 OMP_CLAUSE_CHAIN (c
) = gimple_omp_for_clauses (gfor
);
12562 gimple_omp_for_set_clauses (gfor
, c
);
12567 if (ret
!= GS_ALL_DONE
)
12569 *expr_p
= NULL_TREE
;
12570 return GS_ALL_DONE
;
12573 /* Helper for gimplify_omp_loop, called through walk_tree. */
12576 replace_reduction_placeholders (tree
*tp
, int *walk_subtrees
, void *data
)
12580 tree
*d
= (tree
*) data
;
12581 if (*tp
== OMP_CLAUSE_REDUCTION_PLACEHOLDER (d
[0]))
12583 *tp
= OMP_CLAUSE_REDUCTION_PLACEHOLDER (d
[1]);
12584 *walk_subtrees
= 0;
12586 else if (*tp
== OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (d
[0]))
12588 *tp
= OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (d
[1]);
12589 *walk_subtrees
= 0;
12595 /* Gimplify the gross structure of an OMP_LOOP statement. */
12597 static enum gimplify_status
12598 gimplify_omp_loop (tree
*expr_p
, gimple_seq
*pre_p
)
12600 tree for_stmt
= *expr_p
;
12601 tree clauses
= OMP_FOR_CLAUSES (for_stmt
);
12602 struct gimplify_omp_ctx
*octx
= gimplify_omp_ctxp
;
12603 enum omp_clause_bind_kind kind
= OMP_CLAUSE_BIND_THREAD
;
12606 /* If order is not present, the behavior is as if order(concurrent)
12608 tree order
= omp_find_clause (clauses
, OMP_CLAUSE_ORDER
);
12609 if (order
== NULL_TREE
)
12611 order
= build_omp_clause (UNKNOWN_LOCATION
, OMP_CLAUSE_ORDER
);
12612 OMP_CLAUSE_CHAIN (order
) = clauses
;
12613 OMP_FOR_CLAUSES (for_stmt
) = clauses
= order
;
12616 tree bind
= omp_find_clause (clauses
, OMP_CLAUSE_BIND
);
12617 if (bind
== NULL_TREE
)
12619 if (!flag_openmp
) /* flag_openmp_simd */
12621 else if (octx
&& (octx
->region_type
& ORT_TEAMS
) != 0)
12622 kind
= OMP_CLAUSE_BIND_TEAMS
;
12623 else if (octx
&& (octx
->region_type
& ORT_PARALLEL
) != 0)
12624 kind
= OMP_CLAUSE_BIND_PARALLEL
;
12627 for (; octx
; octx
= octx
->outer_context
)
12629 if ((octx
->region_type
& ORT_ACC
) != 0
12630 || octx
->region_type
== ORT_NONE
12631 || octx
->region_type
== ORT_IMPLICIT_TARGET
)
12635 if (octx
== NULL
&& !in_omp_construct
)
12636 error_at (EXPR_LOCATION (for_stmt
),
12637 "%<bind%> clause not specified on a %<loop%> "
12638 "construct not nested inside another OpenMP construct");
12640 bind
= build_omp_clause (UNKNOWN_LOCATION
, OMP_CLAUSE_BIND
);
12641 OMP_CLAUSE_CHAIN (bind
) = clauses
;
12642 OMP_CLAUSE_BIND_KIND (bind
) = kind
;
12643 OMP_FOR_CLAUSES (for_stmt
) = bind
;
12646 switch (OMP_CLAUSE_BIND_KIND (bind
))
12648 case OMP_CLAUSE_BIND_THREAD
:
12650 case OMP_CLAUSE_BIND_PARALLEL
:
12651 if (!flag_openmp
) /* flag_openmp_simd */
12653 OMP_CLAUSE_BIND_KIND (bind
) = OMP_CLAUSE_BIND_THREAD
;
12656 for (; octx
; octx
= octx
->outer_context
)
12657 if (octx
->region_type
== ORT_SIMD
12658 && omp_find_clause (octx
->clauses
, OMP_CLAUSE_BIND
) == NULL_TREE
)
12660 error_at (EXPR_LOCATION (for_stmt
),
12661 "%<bind(parallel)%> on a %<loop%> construct nested "
12662 "inside %<simd%> construct");
12663 OMP_CLAUSE_BIND_KIND (bind
) = OMP_CLAUSE_BIND_THREAD
;
12666 kind
= OMP_CLAUSE_BIND_PARALLEL
;
12668 case OMP_CLAUSE_BIND_TEAMS
:
12669 if (!flag_openmp
) /* flag_openmp_simd */
12671 OMP_CLAUSE_BIND_KIND (bind
) = OMP_CLAUSE_BIND_THREAD
;
12675 && octx
->region_type
!= ORT_IMPLICIT_TARGET
12676 && octx
->region_type
!= ORT_NONE
12677 && (octx
->region_type
& ORT_TEAMS
) == 0)
12678 || in_omp_construct
)
12680 error_at (EXPR_LOCATION (for_stmt
),
12681 "%<bind(teams)%> on a %<loop%> region not strictly "
12682 "nested inside of a %<teams%> region");
12683 OMP_CLAUSE_BIND_KIND (bind
) = OMP_CLAUSE_BIND_THREAD
;
12686 kind
= OMP_CLAUSE_BIND_TEAMS
;
12689 gcc_unreachable ();
12692 for (tree
*pc
= &OMP_FOR_CLAUSES (for_stmt
); *pc
; )
12693 switch (OMP_CLAUSE_CODE (*pc
))
12695 case OMP_CLAUSE_REDUCTION
:
12696 if (OMP_CLAUSE_REDUCTION_INSCAN (*pc
))
12698 error_at (OMP_CLAUSE_LOCATION (*pc
),
12699 "%<inscan%> %<reduction%> clause on "
12700 "%qs construct", "loop");
12701 OMP_CLAUSE_REDUCTION_INSCAN (*pc
) = 0;
12703 if (OMP_CLAUSE_REDUCTION_TASK (*pc
))
12705 error_at (OMP_CLAUSE_LOCATION (*pc
),
12706 "invalid %<task%> reduction modifier on construct "
12707 "other than %<parallel%>, %qs or %<sections%>",
12708 lang_GNU_Fortran () ? "do" : "for");
12709 OMP_CLAUSE_REDUCTION_TASK (*pc
) = 0;
12711 pc
= &OMP_CLAUSE_CHAIN (*pc
);
12713 case OMP_CLAUSE_LASTPRIVATE
:
12714 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
12716 tree t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), i
);
12717 gcc_assert (TREE_CODE (t
) == MODIFY_EXPR
);
12718 if (OMP_CLAUSE_DECL (*pc
) == TREE_OPERAND (t
, 0))
12720 if (OMP_FOR_ORIG_DECLS (for_stmt
)
12721 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
),
12723 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
),
12726 tree orig
= TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
), i
);
12727 if (OMP_CLAUSE_DECL (*pc
) == TREE_PURPOSE (orig
))
12731 if (i
== TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)))
12733 error_at (OMP_CLAUSE_LOCATION (*pc
),
12734 "%<lastprivate%> clause on a %<loop%> construct refers "
12735 "to a variable %qD which is not the loop iterator",
12736 OMP_CLAUSE_DECL (*pc
));
12737 *pc
= OMP_CLAUSE_CHAIN (*pc
);
12740 pc
= &OMP_CLAUSE_CHAIN (*pc
);
12743 pc
= &OMP_CLAUSE_CHAIN (*pc
);
12747 TREE_SET_CODE (for_stmt
, OMP_SIMD
);
12752 case OMP_CLAUSE_BIND_THREAD
: last
= 0; break;
12753 case OMP_CLAUSE_BIND_PARALLEL
: last
= 1; break;
12754 case OMP_CLAUSE_BIND_TEAMS
: last
= 2; break;
12756 for (int pass
= 1; pass
<= last
; pass
++)
12760 tree bind
= build3 (BIND_EXPR
, void_type_node
, NULL
, NULL
, NULL
);
12761 append_to_statement_list (*expr_p
, &BIND_EXPR_BODY (bind
));
12762 *expr_p
= make_node (OMP_PARALLEL
);
12763 TREE_TYPE (*expr_p
) = void_type_node
;
12764 OMP_PARALLEL_BODY (*expr_p
) = bind
;
12765 OMP_PARALLEL_COMBINED (*expr_p
) = 1;
12766 SET_EXPR_LOCATION (*expr_p
, EXPR_LOCATION (for_stmt
));
12767 tree
*pc
= &OMP_PARALLEL_CLAUSES (*expr_p
);
12768 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
12769 if (OMP_FOR_ORIG_DECLS (for_stmt
)
12770 && (TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
), i
))
12773 tree elt
= TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
), i
);
12774 if (TREE_PURPOSE (elt
) && TREE_VALUE (elt
))
12776 *pc
= build_omp_clause (UNKNOWN_LOCATION
,
12777 OMP_CLAUSE_FIRSTPRIVATE
);
12778 OMP_CLAUSE_DECL (*pc
) = TREE_VALUE (elt
);
12779 pc
= &OMP_CLAUSE_CHAIN (*pc
);
12783 tree t
= make_node (pass
== 2 ? OMP_DISTRIBUTE
: OMP_FOR
);
12784 tree
*pc
= &OMP_FOR_CLAUSES (t
);
12785 TREE_TYPE (t
) = void_type_node
;
12786 OMP_FOR_BODY (t
) = *expr_p
;
12787 SET_EXPR_LOCATION (t
, EXPR_LOCATION (for_stmt
));
12788 for (tree c
= OMP_FOR_CLAUSES (for_stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
12789 switch (OMP_CLAUSE_CODE (c
))
12791 case OMP_CLAUSE_BIND
:
12792 case OMP_CLAUSE_ORDER
:
12793 case OMP_CLAUSE_COLLAPSE
:
12794 *pc
= copy_node (c
);
12795 pc
= &OMP_CLAUSE_CHAIN (*pc
);
12797 case OMP_CLAUSE_PRIVATE
:
12798 case OMP_CLAUSE_FIRSTPRIVATE
:
12799 /* Only needed on innermost. */
12801 case OMP_CLAUSE_LASTPRIVATE
:
12802 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c
) && pass
!= last
)
12804 *pc
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
12805 OMP_CLAUSE_FIRSTPRIVATE
);
12806 OMP_CLAUSE_DECL (*pc
) = OMP_CLAUSE_DECL (c
);
12807 lang_hooks
.decls
.omp_finish_clause (*pc
, NULL
, false);
12808 pc
= &OMP_CLAUSE_CHAIN (*pc
);
12810 *pc
= copy_node (c
);
12811 OMP_CLAUSE_LASTPRIVATE_STMT (*pc
) = NULL_TREE
;
12812 TREE_TYPE (*pc
) = unshare_expr (TREE_TYPE (c
));
12813 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c
))
12816 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (*pc
) = 1;
12818 lang_hooks
.decls
.omp_finish_clause (*pc
, NULL
, false);
12819 OMP_CLAUSE_LASTPRIVATE_LOOP_IV (*pc
) = 0;
12821 pc
= &OMP_CLAUSE_CHAIN (*pc
);
12823 case OMP_CLAUSE_REDUCTION
:
12824 *pc
= copy_node (c
);
12825 OMP_CLAUSE_DECL (*pc
) = unshare_expr (OMP_CLAUSE_DECL (c
));
12826 TREE_TYPE (*pc
) = unshare_expr (TREE_TYPE (c
));
12827 OMP_CLAUSE_REDUCTION_INIT (*pc
)
12828 = unshare_expr (OMP_CLAUSE_REDUCTION_INIT (c
));
12829 OMP_CLAUSE_REDUCTION_MERGE (*pc
)
12830 = unshare_expr (OMP_CLAUSE_REDUCTION_MERGE (c
));
12831 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc
))
12833 OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc
)
12834 = copy_node (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
));
12835 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc
))
12836 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc
)
12837 = copy_node (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c
));
12839 tree data
[2] = { c
, nc
};
12840 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_INIT (nc
),
12841 replace_reduction_placeholders
,
12843 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_MERGE (nc
),
12844 replace_reduction_placeholders
,
12847 pc
= &OMP_CLAUSE_CHAIN (*pc
);
12850 gcc_unreachable ();
12855 return gimplify_omp_for (expr_p
, pre_p
);
12859 /* Helper function of optimize_target_teams, find OMP_TEAMS inside
12860 of OMP_TARGET's body. */
12863 find_omp_teams (tree
*tp
, int *walk_subtrees
, void *)
12865 *walk_subtrees
= 0;
12866 switch (TREE_CODE (*tp
))
12871 case STATEMENT_LIST
:
12872 *walk_subtrees
= 1;
12880 /* Helper function of optimize_target_teams, determine if the expression
12881 can be computed safely before the target construct on the host. */
12884 computable_teams_clause (tree
*tp
, int *walk_subtrees
, void *)
12890 *walk_subtrees
= 0;
12893 switch (TREE_CODE (*tp
))
12898 *walk_subtrees
= 0;
12899 if (error_operand_p (*tp
)
12900 || !INTEGRAL_TYPE_P (TREE_TYPE (*tp
))
12901 || DECL_HAS_VALUE_EXPR_P (*tp
)
12902 || DECL_THREAD_LOCAL_P (*tp
)
12903 || TREE_SIDE_EFFECTS (*tp
)
12904 || TREE_THIS_VOLATILE (*tp
))
12906 if (is_global_var (*tp
)
12907 && (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (*tp
))
12908 || lookup_attribute ("omp declare target link",
12909 DECL_ATTRIBUTES (*tp
))))
12912 && !DECL_SEEN_IN_BIND_EXPR_P (*tp
)
12913 && !is_global_var (*tp
)
12914 && decl_function_context (*tp
) == current_function_decl
)
12916 n
= splay_tree_lookup (gimplify_omp_ctxp
->variables
,
12917 (splay_tree_key
) *tp
);
12920 if (gimplify_omp_ctxp
->defaultmap
[GDMK_SCALAR
] & GOVD_FIRSTPRIVATE
)
12924 else if (n
->value
& GOVD_LOCAL
)
12926 else if (n
->value
& GOVD_FIRSTPRIVATE
)
12928 else if ((n
->value
& (GOVD_MAP
| GOVD_MAP_ALWAYS_TO
))
12929 == (GOVD_MAP
| GOVD_MAP_ALWAYS_TO
))
12933 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp
)))
12937 if (TARGET_EXPR_INITIAL (*tp
)
12938 || TREE_CODE (TARGET_EXPR_SLOT (*tp
)) != VAR_DECL
)
12940 return computable_teams_clause (&TARGET_EXPR_SLOT (*tp
),
12941 walk_subtrees
, NULL
);
12942 /* Allow some reasonable subset of integral arithmetics. */
12946 case TRUNC_DIV_EXPR
:
12947 case CEIL_DIV_EXPR
:
12948 case FLOOR_DIV_EXPR
:
12949 case ROUND_DIV_EXPR
:
12950 case TRUNC_MOD_EXPR
:
12951 case CEIL_MOD_EXPR
:
12952 case FLOOR_MOD_EXPR
:
12953 case ROUND_MOD_EXPR
:
12955 case EXACT_DIV_EXPR
:
12966 case NON_LVALUE_EXPR
:
12968 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp
)))
12971 /* And disallow anything else, except for comparisons. */
12973 if (COMPARISON_CLASS_P (*tp
))
12979 /* Try to determine if the num_teams and/or thread_limit expressions
12980 can have their values determined already before entering the
12982 INTEGER_CSTs trivially are,
12983 integral decls that are firstprivate (explicitly or implicitly)
12984 or explicitly map(always, to:) or map(always, tofrom:) on the target
12985 region too, and expressions involving simple arithmetics on those
12986 too, function calls are not ok, dereferencing something neither etc.
12987 Add NUM_TEAMS and THREAD_LIMIT clauses to the OMP_CLAUSES of
12988 EXPR based on what we find:
12989 0 stands for clause not specified at all, use implementation default
12990 -1 stands for value that can't be determined easily before entering
12991 the target construct.
12992 If teams construct is not present at all, use 1 for num_teams
12993 and 0 for thread_limit (only one team is involved, and the thread
12994 limit is implementation defined. */
12997 optimize_target_teams (tree target
, gimple_seq
*pre_p
)
12999 tree body
= OMP_BODY (target
);
13000 tree teams
= walk_tree (&body
, find_omp_teams
, NULL
, NULL
);
13001 tree num_teams
= integer_zero_node
;
13002 tree thread_limit
= integer_zero_node
;
13003 location_t num_teams_loc
= EXPR_LOCATION (target
);
13004 location_t thread_limit_loc
= EXPR_LOCATION (target
);
13006 struct gimplify_omp_ctx
*target_ctx
= gimplify_omp_ctxp
;
13008 if (teams
== NULL_TREE
)
13009 num_teams
= integer_one_node
;
13011 for (c
= OMP_TEAMS_CLAUSES (teams
); c
; c
= OMP_CLAUSE_CHAIN (c
))
13013 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_NUM_TEAMS
)
13016 num_teams_loc
= OMP_CLAUSE_LOCATION (c
);
13018 else if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_THREAD_LIMIT
)
13021 thread_limit_loc
= OMP_CLAUSE_LOCATION (c
);
13025 expr
= OMP_CLAUSE_OPERAND (c
, 0);
13026 if (TREE_CODE (expr
) == INTEGER_CST
)
13031 if (walk_tree (&expr
, computable_teams_clause
, NULL
, NULL
))
13033 *p
= integer_minus_one_node
;
13037 gimplify_omp_ctxp
= gimplify_omp_ctxp
->outer_context
;
13038 if (gimplify_expr (p
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
, false)
13041 gimplify_omp_ctxp
= target_ctx
;
13042 *p
= integer_minus_one_node
;
13045 gimplify_omp_ctxp
= target_ctx
;
13046 if (!DECL_P (expr
) && TREE_CODE (expr
) != TARGET_EXPR
)
13047 OMP_CLAUSE_OPERAND (c
, 0) = *p
;
13049 c
= build_omp_clause (thread_limit_loc
, OMP_CLAUSE_THREAD_LIMIT
);
13050 OMP_CLAUSE_THREAD_LIMIT_EXPR (c
) = thread_limit
;
13051 OMP_CLAUSE_CHAIN (c
) = OMP_TARGET_CLAUSES (target
);
13052 OMP_TARGET_CLAUSES (target
) = c
;
13053 c
= build_omp_clause (num_teams_loc
, OMP_CLAUSE_NUM_TEAMS
);
13054 OMP_CLAUSE_NUM_TEAMS_EXPR (c
) = num_teams
;
13055 OMP_CLAUSE_CHAIN (c
) = OMP_TARGET_CLAUSES (target
);
13056 OMP_TARGET_CLAUSES (target
) = c
;
13059 /* Gimplify the gross structure of several OMP constructs. */
13062 gimplify_omp_workshare (tree
*expr_p
, gimple_seq
*pre_p
)
13064 tree expr
= *expr_p
;
13066 gimple_seq body
= NULL
;
13067 enum omp_region_type ort
;
13069 switch (TREE_CODE (expr
))
13073 ort
= ORT_WORKSHARE
;
13076 ort
= OMP_TARGET_COMBINED (expr
) ? ORT_COMBINED_TARGET
: ORT_TARGET
;
13079 ort
= ORT_ACC_KERNELS
;
13081 case OACC_PARALLEL
:
13082 ort
= ORT_ACC_PARALLEL
;
13085 ort
= ORT_ACC_SERIAL
;
13088 ort
= ORT_ACC_DATA
;
13090 case OMP_TARGET_DATA
:
13091 ort
= ORT_TARGET_DATA
;
13094 ort
= OMP_TEAMS_COMBINED (expr
) ? ORT_COMBINED_TEAMS
: ORT_TEAMS
;
13095 if (gimplify_omp_ctxp
== NULL
13096 || gimplify_omp_ctxp
->region_type
== ORT_IMPLICIT_TARGET
)
13097 ort
= (enum omp_region_type
) (ort
| ORT_HOST_TEAMS
);
13099 case OACC_HOST_DATA
:
13100 ort
= ORT_ACC_HOST_DATA
;
13103 gcc_unreachable ();
13106 bool save_in_omp_construct
= in_omp_construct
;
13107 if ((ort
& ORT_ACC
) == 0)
13108 in_omp_construct
= false;
13109 gimplify_scan_omp_clauses (&OMP_CLAUSES (expr
), pre_p
, ort
,
13111 if (TREE_CODE (expr
) == OMP_TARGET
)
13112 optimize_target_teams (expr
, pre_p
);
13113 if ((ort
& (ORT_TARGET
| ORT_TARGET_DATA
)) != 0
13114 || (ort
& ORT_HOST_TEAMS
) == ORT_HOST_TEAMS
)
13116 push_gimplify_context ();
13117 gimple
*g
= gimplify_and_return_first (OMP_BODY (expr
), &body
);
13118 if (gimple_code (g
) == GIMPLE_BIND
)
13119 pop_gimplify_context (g
);
13121 pop_gimplify_context (NULL
);
13122 if ((ort
& ORT_TARGET_DATA
) != 0)
13124 enum built_in_function end_ix
;
13125 switch (TREE_CODE (expr
))
13128 case OACC_HOST_DATA
:
13129 end_ix
= BUILT_IN_GOACC_DATA_END
;
13131 case OMP_TARGET_DATA
:
13132 end_ix
= BUILT_IN_GOMP_TARGET_END_DATA
;
13135 gcc_unreachable ();
13137 tree fn
= builtin_decl_explicit (end_ix
);
13138 g
= gimple_build_call (fn
, 0);
13139 gimple_seq cleanup
= NULL
;
13140 gimple_seq_add_stmt (&cleanup
, g
);
13141 g
= gimple_build_try (body
, cleanup
, GIMPLE_TRY_FINALLY
);
13143 gimple_seq_add_stmt (&body
, g
);
13147 gimplify_and_add (OMP_BODY (expr
), &body
);
13148 gimplify_adjust_omp_clauses (pre_p
, body
, &OMP_CLAUSES (expr
),
13150 in_omp_construct
= save_in_omp_construct
;
13152 switch (TREE_CODE (expr
))
13155 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_OACC_DATA
,
13156 OMP_CLAUSES (expr
));
13158 case OACC_HOST_DATA
:
13159 if (omp_find_clause (OMP_CLAUSES (expr
), OMP_CLAUSE_IF_PRESENT
))
13161 for (tree c
= OMP_CLAUSES (expr
); c
; c
= OMP_CLAUSE_CHAIN (c
))
13162 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_USE_DEVICE_PTR
)
13163 OMP_CLAUSE_USE_DEVICE_PTR_IF_PRESENT (c
) = 1;
13166 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_OACC_HOST_DATA
,
13167 OMP_CLAUSES (expr
));
13170 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_OACC_KERNELS
,
13171 OMP_CLAUSES (expr
));
13173 case OACC_PARALLEL
:
13174 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_OACC_PARALLEL
,
13175 OMP_CLAUSES (expr
));
13178 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_OACC_SERIAL
,
13179 OMP_CLAUSES (expr
));
13182 stmt
= gimple_build_omp_sections (body
, OMP_CLAUSES (expr
));
13185 stmt
= gimple_build_omp_single (body
, OMP_CLAUSES (expr
));
13188 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_REGION
,
13189 OMP_CLAUSES (expr
));
13191 case OMP_TARGET_DATA
:
13192 /* Put use_device_{ptr,addr} clauses last, as map clauses are supposed
13193 to be evaluated before the use_device_{ptr,addr} clauses if they
13194 refer to the same variables. */
13196 tree use_device_clauses
;
13197 tree
*pc
, *uc
= &use_device_clauses
;
13198 for (pc
= &OMP_CLAUSES (expr
); *pc
; )
13199 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_USE_DEVICE_PTR
13200 || OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_USE_DEVICE_ADDR
)
13203 *pc
= OMP_CLAUSE_CHAIN (*pc
);
13204 uc
= &OMP_CLAUSE_CHAIN (*uc
);
13207 pc
= &OMP_CLAUSE_CHAIN (*pc
);
13209 *pc
= use_device_clauses
;
13210 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_DATA
,
13211 OMP_CLAUSES (expr
));
13215 stmt
= gimple_build_omp_teams (body
, OMP_CLAUSES (expr
));
13216 if ((ort
& ORT_HOST_TEAMS
) == ORT_HOST_TEAMS
)
13217 gimple_omp_teams_set_host (as_a
<gomp_teams
*> (stmt
), true);
13220 gcc_unreachable ();
13223 gimplify_seq_add_stmt (pre_p
, stmt
);
13224 *expr_p
= NULL_TREE
;
13227 /* Gimplify the gross structure of OpenACC enter/exit data, update, and OpenMP
13228 target update constructs. */
13231 gimplify_omp_target_update (tree
*expr_p
, gimple_seq
*pre_p
)
13233 tree expr
= *expr_p
;
13236 enum omp_region_type ort
= ORT_WORKSHARE
;
13238 switch (TREE_CODE (expr
))
13240 case OACC_ENTER_DATA
:
13241 case OACC_EXIT_DATA
:
13242 kind
= GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA
;
13246 kind
= GF_OMP_TARGET_KIND_OACC_UPDATE
;
13249 case OMP_TARGET_UPDATE
:
13250 kind
= GF_OMP_TARGET_KIND_UPDATE
;
13252 case OMP_TARGET_ENTER_DATA
:
13253 kind
= GF_OMP_TARGET_KIND_ENTER_DATA
;
13255 case OMP_TARGET_EXIT_DATA
:
13256 kind
= GF_OMP_TARGET_KIND_EXIT_DATA
;
13259 gcc_unreachable ();
13261 gimplify_scan_omp_clauses (&OMP_STANDALONE_CLAUSES (expr
), pre_p
,
13262 ort
, TREE_CODE (expr
));
13263 gimplify_adjust_omp_clauses (pre_p
, NULL
, &OMP_STANDALONE_CLAUSES (expr
),
13265 if (TREE_CODE (expr
) == OACC_UPDATE
13266 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr
),
13267 OMP_CLAUSE_IF_PRESENT
))
13269 /* The runtime uses GOMP_MAP_{TO,FROM} to denote the if_present
13271 for (tree c
= OMP_STANDALONE_CLAUSES (expr
); c
; c
= OMP_CLAUSE_CHAIN (c
))
13272 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_MAP
)
13273 switch (OMP_CLAUSE_MAP_KIND (c
))
13275 case GOMP_MAP_FORCE_TO
:
13276 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_TO
);
13278 case GOMP_MAP_FORCE_FROM
:
13279 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_FROM
);
13285 else if (TREE_CODE (expr
) == OACC_EXIT_DATA
13286 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr
),
13287 OMP_CLAUSE_FINALIZE
))
13289 /* Use GOMP_MAP_DELETE/GOMP_MAP_FORCE_FROM to denote "finalize"
13291 bool have_clause
= false;
13292 for (tree c
= OMP_STANDALONE_CLAUSES (expr
); c
; c
= OMP_CLAUSE_CHAIN (c
))
13293 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_MAP
)
13294 switch (OMP_CLAUSE_MAP_KIND (c
))
13296 case GOMP_MAP_FROM
:
13297 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_FORCE_FROM
);
13298 have_clause
= true;
13300 case GOMP_MAP_RELEASE
:
13301 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_DELETE
);
13302 have_clause
= true;
13304 case GOMP_MAP_TO_PSET
:
13305 /* Fortran arrays with descriptors must map that descriptor when
13306 doing standalone "attach" operations (in OpenACC). In that
13307 case GOMP_MAP_TO_PSET appears by itself with no preceding
13308 clause (see trans-openmp.c:gfc_trans_omp_clauses). */
13310 case GOMP_MAP_POINTER
:
13311 /* TODO PR92929: we may see these here, but they'll always follow
13312 one of the clauses above, and will be handled by libgomp as
13313 one group, so no handling required here. */
13314 gcc_assert (have_clause
);
13316 case GOMP_MAP_DETACH
:
13317 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_FORCE_DETACH
);
13318 have_clause
= false;
13320 case GOMP_MAP_STRUCT
:
13321 have_clause
= false;
13324 gcc_unreachable ();
13327 stmt
= gimple_build_omp_target (NULL
, kind
, OMP_STANDALONE_CLAUSES (expr
));
13329 gimplify_seq_add_stmt (pre_p
, stmt
);
13330 *expr_p
= NULL_TREE
;
13333 /* A subroutine of gimplify_omp_atomic. The front end is supposed to have
13334 stabilized the lhs of the atomic operation as *ADDR. Return true if
13335 EXPR is this stabilized form. */
13338 goa_lhs_expr_p (tree expr
, tree addr
)
13340 /* Also include casts to other type variants. The C front end is fond
13341 of adding these for e.g. volatile variables. This is like
13342 STRIP_TYPE_NOPS but includes the main variant lookup. */
13343 STRIP_USELESS_TYPE_CONVERSION (expr
);
13345 if (TREE_CODE (expr
) == INDIRECT_REF
)
13347 expr
= TREE_OPERAND (expr
, 0);
13348 while (expr
!= addr
13349 && (CONVERT_EXPR_P (expr
)
13350 || TREE_CODE (expr
) == NON_LVALUE_EXPR
)
13351 && TREE_CODE (expr
) == TREE_CODE (addr
)
13352 && types_compatible_p (TREE_TYPE (expr
), TREE_TYPE (addr
)))
13354 expr
= TREE_OPERAND (expr
, 0);
13355 addr
= TREE_OPERAND (addr
, 0);
13359 return (TREE_CODE (addr
) == ADDR_EXPR
13360 && TREE_CODE (expr
) == ADDR_EXPR
13361 && TREE_OPERAND (addr
, 0) == TREE_OPERAND (expr
, 0));
13363 if (TREE_CODE (addr
) == ADDR_EXPR
&& expr
== TREE_OPERAND (addr
, 0))
13368 /* Walk *EXPR_P and replace appearances of *LHS_ADDR with LHS_VAR. If an
13369 expression does not involve the lhs, evaluate it into a temporary.
13370 Return 1 if the lhs appeared as a subexpression, 0 if it did not,
13371 or -1 if an error was encountered. */
13374 goa_stabilize_expr (tree
*expr_p
, gimple_seq
*pre_p
, tree lhs_addr
,
13377 tree expr
= *expr_p
;
13380 if (goa_lhs_expr_p (expr
, lhs_addr
))
13385 if (is_gimple_val (expr
))
13389 switch (TREE_CODE_CLASS (TREE_CODE (expr
)))
13392 case tcc_comparison
:
13393 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 1), pre_p
, lhs_addr
,
13397 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 0), pre_p
, lhs_addr
,
13400 case tcc_expression
:
13401 switch (TREE_CODE (expr
))
13403 case TRUTH_ANDIF_EXPR
:
13404 case TRUTH_ORIF_EXPR
:
13405 case TRUTH_AND_EXPR
:
13406 case TRUTH_OR_EXPR
:
13407 case TRUTH_XOR_EXPR
:
13408 case BIT_INSERT_EXPR
:
13409 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 1), pre_p
,
13410 lhs_addr
, lhs_var
);
13412 case TRUTH_NOT_EXPR
:
13413 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 0), pre_p
,
13414 lhs_addr
, lhs_var
);
13416 case COMPOUND_EXPR
:
13417 /* Break out any preevaluations from cp_build_modify_expr. */
13418 for (; TREE_CODE (expr
) == COMPOUND_EXPR
;
13419 expr
= TREE_OPERAND (expr
, 1))
13420 gimplify_stmt (&TREE_OPERAND (expr
, 0), pre_p
);
13422 return goa_stabilize_expr (expr_p
, pre_p
, lhs_addr
, lhs_var
);
13427 case tcc_reference
:
13428 if (TREE_CODE (expr
) == BIT_FIELD_REF
)
13429 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 0), pre_p
,
13430 lhs_addr
, lhs_var
);
13438 enum gimplify_status gs
;
13439 gs
= gimplify_expr (expr_p
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
13440 if (gs
!= GS_ALL_DONE
)
13447 /* Gimplify an OMP_ATOMIC statement. */
13449 static enum gimplify_status
13450 gimplify_omp_atomic (tree
*expr_p
, gimple_seq
*pre_p
)
13452 tree addr
= TREE_OPERAND (*expr_p
, 0);
13453 tree rhs
= TREE_CODE (*expr_p
) == OMP_ATOMIC_READ
13454 ? NULL
: TREE_OPERAND (*expr_p
, 1);
13455 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr
)));
13457 gomp_atomic_load
*loadstmt
;
13458 gomp_atomic_store
*storestmt
;
13460 tmp_load
= create_tmp_reg (type
);
13461 if (rhs
&& goa_stabilize_expr (&rhs
, pre_p
, addr
, tmp_load
) < 0)
13464 if (gimplify_expr (&addr
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
)
13468 loadstmt
= gimple_build_omp_atomic_load (tmp_load
, addr
,
13469 OMP_ATOMIC_MEMORY_ORDER (*expr_p
));
13470 gimplify_seq_add_stmt (pre_p
, loadstmt
);
13473 /* BIT_INSERT_EXPR is not valid for non-integral bitfield
13474 representatives. Use BIT_FIELD_REF on the lhs instead. */
13475 if (TREE_CODE (rhs
) == BIT_INSERT_EXPR
13476 && !INTEGRAL_TYPE_P (TREE_TYPE (tmp_load
)))
13478 tree bitpos
= TREE_OPERAND (rhs
, 2);
13479 tree op1
= TREE_OPERAND (rhs
, 1);
13481 tree tmp_store
= tmp_load
;
13482 if (TREE_CODE (*expr_p
) == OMP_ATOMIC_CAPTURE_OLD
)
13483 tmp_store
= get_initialized_tmp_var (tmp_load
, pre_p
);
13484 if (INTEGRAL_TYPE_P (TREE_TYPE (op1
)))
13485 bitsize
= bitsize_int (TYPE_PRECISION (TREE_TYPE (op1
)));
13487 bitsize
= TYPE_SIZE (TREE_TYPE (op1
));
13488 gcc_assert (TREE_OPERAND (rhs
, 0) == tmp_load
);
13489 tree t
= build2_loc (EXPR_LOCATION (rhs
),
13490 MODIFY_EXPR
, void_type_node
,
13491 build3_loc (EXPR_LOCATION (rhs
), BIT_FIELD_REF
,
13492 TREE_TYPE (op1
), tmp_store
, bitsize
,
13494 gimplify_and_add (t
, pre_p
);
13497 if (gimplify_expr (&rhs
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
)
13502 if (TREE_CODE (*expr_p
) == OMP_ATOMIC_READ
)
13505 = gimple_build_omp_atomic_store (rhs
, OMP_ATOMIC_MEMORY_ORDER (*expr_p
));
13506 gimplify_seq_add_stmt (pre_p
, storestmt
);
13507 switch (TREE_CODE (*expr_p
))
13509 case OMP_ATOMIC_READ
:
13510 case OMP_ATOMIC_CAPTURE_OLD
:
13511 *expr_p
= tmp_load
;
13512 gimple_omp_atomic_set_need_value (loadstmt
);
13514 case OMP_ATOMIC_CAPTURE_NEW
:
13516 gimple_omp_atomic_set_need_value (storestmt
);
13523 return GS_ALL_DONE
;
13526 /* Gimplify a TRANSACTION_EXPR. This involves gimplification of the
13527 body, and adding some EH bits. */
13529 static enum gimplify_status
13530 gimplify_transaction (tree
*expr_p
, gimple_seq
*pre_p
)
13532 tree expr
= *expr_p
, temp
, tbody
= TRANSACTION_EXPR_BODY (expr
);
13534 gtransaction
*trans_stmt
;
13535 gimple_seq body
= NULL
;
13538 /* Wrap the transaction body in a BIND_EXPR so we have a context
13539 where to put decls for OMP. */
13540 if (TREE_CODE (tbody
) != BIND_EXPR
)
13542 tree bind
= build3 (BIND_EXPR
, void_type_node
, NULL
, tbody
, NULL
);
13543 TREE_SIDE_EFFECTS (bind
) = 1;
13544 SET_EXPR_LOCATION (bind
, EXPR_LOCATION (tbody
));
13545 TRANSACTION_EXPR_BODY (expr
) = bind
;
13548 push_gimplify_context ();
13549 temp
= voidify_wrapper_expr (*expr_p
, NULL
);
13551 body_stmt
= gimplify_and_return_first (TRANSACTION_EXPR_BODY (expr
), &body
);
13552 pop_gimplify_context (body_stmt
);
13554 trans_stmt
= gimple_build_transaction (body
);
13555 if (TRANSACTION_EXPR_OUTER (expr
))
13556 subcode
= GTMA_IS_OUTER
;
13557 else if (TRANSACTION_EXPR_RELAXED (expr
))
13558 subcode
= GTMA_IS_RELAXED
;
13559 gimple_transaction_set_subcode (trans_stmt
, subcode
);
13561 gimplify_seq_add_stmt (pre_p
, trans_stmt
);
13569 *expr_p
= NULL_TREE
;
13570 return GS_ALL_DONE
;
13573 /* Gimplify an OMP_ORDERED construct. EXPR is the tree version. BODY
13574 is the OMP_BODY of the original EXPR (which has already been
13575 gimplified so it's not present in the EXPR).
13577 Return the gimplified GIMPLE_OMP_ORDERED tuple. */
13580 gimplify_omp_ordered (tree expr
, gimple_seq body
)
13585 tree source_c
= NULL_TREE
;
13586 tree sink_c
= NULL_TREE
;
13588 if (gimplify_omp_ctxp
)
13590 for (c
= OMP_ORDERED_CLAUSES (expr
); c
; c
= OMP_CLAUSE_CHAIN (c
))
13591 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEPEND
13592 && gimplify_omp_ctxp
->loop_iter_var
.is_empty ()
13593 && (OMP_CLAUSE_DEPEND_KIND (c
) == OMP_CLAUSE_DEPEND_SINK
13594 || OMP_CLAUSE_DEPEND_KIND (c
) == OMP_CLAUSE_DEPEND_SOURCE
))
13596 error_at (OMP_CLAUSE_LOCATION (c
),
13597 "%<ordered%> construct with %<depend%> clause must be "
13598 "closely nested inside a loop with %<ordered%> clause "
13599 "with a parameter");
13602 else if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEPEND
13603 && OMP_CLAUSE_DEPEND_KIND (c
) == OMP_CLAUSE_DEPEND_SINK
)
13606 for (decls
= OMP_CLAUSE_DECL (c
), i
= 0;
13607 decls
&& TREE_CODE (decls
) == TREE_LIST
;
13608 decls
= TREE_CHAIN (decls
), ++i
)
13609 if (i
>= gimplify_omp_ctxp
->loop_iter_var
.length () / 2)
13611 else if (TREE_VALUE (decls
)
13612 != gimplify_omp_ctxp
->loop_iter_var
[2 * i
])
13614 error_at (OMP_CLAUSE_LOCATION (c
),
13615 "variable %qE is not an iteration "
13616 "of outermost loop %d, expected %qE",
13617 TREE_VALUE (decls
), i
+ 1,
13618 gimplify_omp_ctxp
->loop_iter_var
[2 * i
]);
13624 = gimplify_omp_ctxp
->loop_iter_var
[2 * i
+ 1];
13625 if (!fail
&& i
!= gimplify_omp_ctxp
->loop_iter_var
.length () / 2)
13627 error_at (OMP_CLAUSE_LOCATION (c
),
13628 "number of variables in %<depend%> clause with "
13629 "%<sink%> modifier does not match number of "
13630 "iteration variables");
13635 else if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEPEND
13636 && OMP_CLAUSE_DEPEND_KIND (c
) == OMP_CLAUSE_DEPEND_SOURCE
)
13640 error_at (OMP_CLAUSE_LOCATION (c
),
13641 "more than one %<depend%> clause with %<source%> "
13642 "modifier on an %<ordered%> construct");
13649 if (source_c
&& sink_c
)
13651 error_at (OMP_CLAUSE_LOCATION (source_c
),
13652 "%<depend%> clause with %<source%> modifier specified "
13653 "together with %<depend%> clauses with %<sink%> modifier "
13654 "on the same construct");
13659 return gimple_build_nop ();
13660 return gimple_build_omp_ordered (body
, OMP_ORDERED_CLAUSES (expr
));
13663 /* Convert the GENERIC expression tree *EXPR_P to GIMPLE. If the
13664 expression produces a value to be used as an operand inside a GIMPLE
13665 statement, the value will be stored back in *EXPR_P. This value will
13666 be a tree of class tcc_declaration, tcc_constant, tcc_reference or
13667 an SSA_NAME. The corresponding sequence of GIMPLE statements is
13668 emitted in PRE_P and POST_P.
13670 Additionally, this process may overwrite parts of the input
13671 expression during gimplification. Ideally, it should be
13672 possible to do non-destructive gimplification.
13674 EXPR_P points to the GENERIC expression to convert to GIMPLE. If
13675 the expression needs to evaluate to a value to be used as
13676 an operand in a GIMPLE statement, this value will be stored in
13677 *EXPR_P on exit. This happens when the caller specifies one
13678 of fb_lvalue or fb_rvalue fallback flags.
13680 PRE_P will contain the sequence of GIMPLE statements corresponding
13681 to the evaluation of EXPR and all the side-effects that must
13682 be executed before the main expression. On exit, the last
13683 statement of PRE_P is the core statement being gimplified. For
13684 instance, when gimplifying 'if (++a)' the last statement in
13685 PRE_P will be 'if (t.1)' where t.1 is the result of
13686 pre-incrementing 'a'.
13688 POST_P will contain the sequence of GIMPLE statements corresponding
13689 to the evaluation of all the side-effects that must be executed
13690 after the main expression. If this is NULL, the post
13691 side-effects are stored at the end of PRE_P.
13693 The reason why the output is split in two is to handle post
13694 side-effects explicitly. In some cases, an expression may have
13695 inner and outer post side-effects which need to be emitted in
13696 an order different from the one given by the recursive
13697 traversal. For instance, for the expression (*p--)++ the post
13698 side-effects of '--' must actually occur *after* the post
13699 side-effects of '++'. However, gimplification will first visit
13700 the inner expression, so if a separate POST sequence was not
13701 used, the resulting sequence would be:
13708 However, the post-decrement operation in line #2 must not be
13709 evaluated until after the store to *p at line #4, so the
13710 correct sequence should be:
13717 So, by specifying a separate post queue, it is possible
13718 to emit the post side-effects in the correct order.
13719 If POST_P is NULL, an internal queue will be used. Before
13720 returning to the caller, the sequence POST_P is appended to
13721 the main output sequence PRE_P.
13723 GIMPLE_TEST_F points to a function that takes a tree T and
13724 returns nonzero if T is in the GIMPLE form requested by the
13725 caller. The GIMPLE predicates are in gimple.c.
13727 FALLBACK tells the function what sort of a temporary we want if
13728 gimplification cannot produce an expression that complies with
13731 fb_none means that no temporary should be generated
13732 fb_rvalue means that an rvalue is OK to generate
13733 fb_lvalue means that an lvalue is OK to generate
13734 fb_either means that either is OK, but an lvalue is preferable.
13735 fb_mayfail means that gimplification may fail (in which case
13736 GS_ERROR will be returned)
13738 The return value is either GS_ERROR or GS_ALL_DONE, since this
13739 function iterates until EXPR is completely gimplified or an error
13742 enum gimplify_status
13743 gimplify_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
13744 bool (*gimple_test_f
) (tree
), fallback_t fallback
)
13747 gimple_seq internal_pre
= NULL
;
13748 gimple_seq internal_post
= NULL
;
13751 location_t saved_location
;
13752 enum gimplify_status ret
;
13753 gimple_stmt_iterator pre_last_gsi
, post_last_gsi
;
13756 save_expr
= *expr_p
;
13757 if (save_expr
== NULL_TREE
)
13758 return GS_ALL_DONE
;
13760 /* If we are gimplifying a top-level statement, PRE_P must be valid. */
13761 is_statement
= gimple_test_f
== is_gimple_stmt
;
13763 gcc_assert (pre_p
);
13765 /* Consistency checks. */
13766 if (gimple_test_f
== is_gimple_reg
)
13767 gcc_assert (fallback
& (fb_rvalue
| fb_lvalue
));
13768 else if (gimple_test_f
== is_gimple_val
13769 || gimple_test_f
== is_gimple_call_addr
13770 || gimple_test_f
== is_gimple_condexpr
13771 || gimple_test_f
== is_gimple_condexpr_for_cond
13772 || gimple_test_f
== is_gimple_mem_rhs
13773 || gimple_test_f
== is_gimple_mem_rhs_or_call
13774 || gimple_test_f
== is_gimple_reg_rhs
13775 || gimple_test_f
== is_gimple_reg_rhs_or_call
13776 || gimple_test_f
== is_gimple_asm_val
13777 || gimple_test_f
== is_gimple_mem_ref_addr
)
13778 gcc_assert (fallback
& fb_rvalue
);
13779 else if (gimple_test_f
== is_gimple_min_lval
13780 || gimple_test_f
== is_gimple_lvalue
)
13781 gcc_assert (fallback
& fb_lvalue
);
13782 else if (gimple_test_f
== is_gimple_addressable
)
13783 gcc_assert (fallback
& fb_either
);
13784 else if (gimple_test_f
== is_gimple_stmt
)
13785 gcc_assert (fallback
== fb_none
);
13788 /* We should have recognized the GIMPLE_TEST_F predicate to
13789 know what kind of fallback to use in case a temporary is
13790 needed to hold the value or address of *EXPR_P. */
13791 gcc_unreachable ();
13794 /* We used to check the predicate here and return immediately if it
13795 succeeds. This is wrong; the design is for gimplification to be
13796 idempotent, and for the predicates to only test for valid forms, not
13797 whether they are fully simplified. */
13799 pre_p
= &internal_pre
;
13801 if (post_p
== NULL
)
13802 post_p
= &internal_post
;
13804 /* Remember the last statements added to PRE_P and POST_P. Every
13805 new statement added by the gimplification helpers needs to be
13806 annotated with location information. To centralize the
13807 responsibility, we remember the last statement that had been
13808 added to both queues before gimplifying *EXPR_P. If
13809 gimplification produces new statements in PRE_P and POST_P, those
13810 statements will be annotated with the same location information
13812 pre_last_gsi
= gsi_last (*pre_p
);
13813 post_last_gsi
= gsi_last (*post_p
);
13815 saved_location
= input_location
;
13816 if (save_expr
!= error_mark_node
13817 && EXPR_HAS_LOCATION (*expr_p
))
13818 input_location
= EXPR_LOCATION (*expr_p
);
13820 /* Loop over the specific gimplifiers until the toplevel node
13821 remains the same. */
13824 /* Strip away as many useless type conversions as possible
13825 at the toplevel. */
13826 STRIP_USELESS_TYPE_CONVERSION (*expr_p
);
13828 /* Remember the expr. */
13829 save_expr
= *expr_p
;
13831 /* Die, die, die, my darling. */
13832 if (error_operand_p (save_expr
))
13838 /* Do any language-specific gimplification. */
13839 ret
= ((enum gimplify_status
)
13840 lang_hooks
.gimplify_expr (expr_p
, pre_p
, post_p
));
13843 if (*expr_p
== NULL_TREE
)
13845 if (*expr_p
!= save_expr
)
13848 else if (ret
!= GS_UNHANDLED
)
13851 /* Make sure that all the cases set 'ret' appropriately. */
13852 ret
= GS_UNHANDLED
;
13853 switch (TREE_CODE (*expr_p
))
13855 /* First deal with the special cases. */
13857 case POSTINCREMENT_EXPR
:
13858 case POSTDECREMENT_EXPR
:
13859 case PREINCREMENT_EXPR
:
13860 case PREDECREMENT_EXPR
:
13861 ret
= gimplify_self_mod_expr (expr_p
, pre_p
, post_p
,
13862 fallback
!= fb_none
,
13863 TREE_TYPE (*expr_p
));
13866 case VIEW_CONVERT_EXPR
:
13867 if ((fallback
& fb_rvalue
)
13868 && is_gimple_reg_type (TREE_TYPE (*expr_p
))
13869 && is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (*expr_p
, 0))))
13871 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
13872 post_p
, is_gimple_val
, fb_rvalue
);
13873 recalculate_side_effects (*expr_p
);
13879 case ARRAY_RANGE_REF
:
13880 case REALPART_EXPR
:
13881 case IMAGPART_EXPR
:
13882 case COMPONENT_REF
:
13883 ret
= gimplify_compound_lval (expr_p
, pre_p
, post_p
,
13884 fallback
? fallback
: fb_rvalue
);
13888 ret
= gimplify_cond_expr (expr_p
, pre_p
, fallback
);
13890 /* C99 code may assign to an array in a structure value of a
13891 conditional expression, and this has undefined behavior
13892 only on execution, so create a temporary if an lvalue is
13894 if (fallback
== fb_lvalue
)
13896 *expr_p
= get_initialized_tmp_var (*expr_p
, pre_p
, post_p
, false);
13897 mark_addressable (*expr_p
);
13903 ret
= gimplify_call_expr (expr_p
, pre_p
, fallback
!= fb_none
);
13905 /* C99 code may assign to an array in a structure returned
13906 from a function, and this has undefined behavior only on
13907 execution, so create a temporary if an lvalue is
13909 if (fallback
== fb_lvalue
)
13911 *expr_p
= get_initialized_tmp_var (*expr_p
, pre_p
, post_p
, false);
13912 mark_addressable (*expr_p
);
13918 gcc_unreachable ();
13920 case COMPOUND_EXPR
:
13921 ret
= gimplify_compound_expr (expr_p
, pre_p
, fallback
!= fb_none
);
13924 case COMPOUND_LITERAL_EXPR
:
13925 ret
= gimplify_compound_literal_expr (expr_p
, pre_p
,
13926 gimple_test_f
, fallback
);
13931 ret
= gimplify_modify_expr (expr_p
, pre_p
, post_p
,
13932 fallback
!= fb_none
);
13935 case TRUTH_ANDIF_EXPR
:
13936 case TRUTH_ORIF_EXPR
:
13938 /* Preserve the original type of the expression and the
13939 source location of the outer expression. */
13940 tree org_type
= TREE_TYPE (*expr_p
);
13941 *expr_p
= gimple_boolify (*expr_p
);
13942 *expr_p
= build3_loc (input_location
, COND_EXPR
,
13946 org_type
, boolean_true_node
),
13949 org_type
, boolean_false_node
));
13954 case TRUTH_NOT_EXPR
:
13956 tree type
= TREE_TYPE (*expr_p
);
13957 /* The parsers are careful to generate TRUTH_NOT_EXPR
13958 only with operands that are always zero or one.
13959 We do not fold here but handle the only interesting case
13960 manually, as fold may re-introduce the TRUTH_NOT_EXPR. */
13961 *expr_p
= gimple_boolify (*expr_p
);
13962 if (TYPE_PRECISION (TREE_TYPE (*expr_p
)) == 1)
13963 *expr_p
= build1_loc (input_location
, BIT_NOT_EXPR
,
13964 TREE_TYPE (*expr_p
),
13965 TREE_OPERAND (*expr_p
, 0));
13967 *expr_p
= build2_loc (input_location
, BIT_XOR_EXPR
,
13968 TREE_TYPE (*expr_p
),
13969 TREE_OPERAND (*expr_p
, 0),
13970 build_int_cst (TREE_TYPE (*expr_p
), 1));
13971 if (!useless_type_conversion_p (type
, TREE_TYPE (*expr_p
)))
13972 *expr_p
= fold_convert_loc (input_location
, type
, *expr_p
);
13978 ret
= gimplify_addr_expr (expr_p
, pre_p
, post_p
);
13981 case ANNOTATE_EXPR
:
13983 tree cond
= TREE_OPERAND (*expr_p
, 0);
13984 tree kind
= TREE_OPERAND (*expr_p
, 1);
13985 tree data
= TREE_OPERAND (*expr_p
, 2);
13986 tree type
= TREE_TYPE (cond
);
13987 if (!INTEGRAL_TYPE_P (type
))
13993 tree tmp
= create_tmp_var (type
);
13994 gimplify_arg (&cond
, pre_p
, EXPR_LOCATION (*expr_p
));
13996 = gimple_build_call_internal (IFN_ANNOTATE
, 3, cond
, kind
, data
);
13997 gimple_call_set_lhs (call
, tmp
);
13998 gimplify_seq_add_stmt (pre_p
, call
);
14005 ret
= gimplify_va_arg_expr (expr_p
, pre_p
, post_p
);
14009 if (IS_EMPTY_STMT (*expr_p
))
14015 if (VOID_TYPE_P (TREE_TYPE (*expr_p
))
14016 || fallback
== fb_none
)
14018 /* Just strip a conversion to void (or in void context) and
14020 *expr_p
= TREE_OPERAND (*expr_p
, 0);
14025 ret
= gimplify_conversion (expr_p
);
14026 if (ret
== GS_ERROR
)
14028 if (*expr_p
!= save_expr
)
14032 case FIX_TRUNC_EXPR
:
14033 /* unary_expr: ... | '(' cast ')' val | ... */
14034 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
14035 is_gimple_val
, fb_rvalue
);
14036 recalculate_side_effects (*expr_p
);
14041 bool volatilep
= TREE_THIS_VOLATILE (*expr_p
);
14042 bool notrap
= TREE_THIS_NOTRAP (*expr_p
);
14043 tree saved_ptr_type
= TREE_TYPE (TREE_OPERAND (*expr_p
, 0));
14045 *expr_p
= fold_indirect_ref_loc (input_location
, *expr_p
);
14046 if (*expr_p
!= save_expr
)
14052 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
14053 is_gimple_reg
, fb_rvalue
);
14054 if (ret
== GS_ERROR
)
14057 recalculate_side_effects (*expr_p
);
14058 *expr_p
= fold_build2_loc (input_location
, MEM_REF
,
14059 TREE_TYPE (*expr_p
),
14060 TREE_OPERAND (*expr_p
, 0),
14061 build_int_cst (saved_ptr_type
, 0));
14062 TREE_THIS_VOLATILE (*expr_p
) = volatilep
;
14063 TREE_THIS_NOTRAP (*expr_p
) = notrap
;
14068 /* We arrive here through the various re-gimplifcation paths. */
14070 /* First try re-folding the whole thing. */
14071 tmp
= fold_binary (MEM_REF
, TREE_TYPE (*expr_p
),
14072 TREE_OPERAND (*expr_p
, 0),
14073 TREE_OPERAND (*expr_p
, 1));
14076 REF_REVERSE_STORAGE_ORDER (tmp
)
14077 = REF_REVERSE_STORAGE_ORDER (*expr_p
);
14079 recalculate_side_effects (*expr_p
);
14083 /* Avoid re-gimplifying the address operand if it is already
14084 in suitable form. Re-gimplifying would mark the address
14085 operand addressable. Always gimplify when not in SSA form
14086 as we still may have to gimplify decls with value-exprs. */
14087 if (!gimplify_ctxp
|| !gimple_in_ssa_p (cfun
)
14088 || !is_gimple_mem_ref_addr (TREE_OPERAND (*expr_p
, 0)))
14090 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
14091 is_gimple_mem_ref_addr
, fb_rvalue
);
14092 if (ret
== GS_ERROR
)
14095 recalculate_side_effects (*expr_p
);
14099 /* Constants need not be gimplified. */
14106 /* Drop the overflow flag on constants, we do not want
14107 that in the GIMPLE IL. */
14108 if (TREE_OVERFLOW_P (*expr_p
))
14109 *expr_p
= drop_tree_overflow (*expr_p
);
14114 /* If we require an lvalue, such as for ADDR_EXPR, retain the
14115 CONST_DECL node. Otherwise the decl is replaceable by its
14117 /* ??? Should be == fb_lvalue, but ADDR_EXPR passes fb_either. */
14118 if (fallback
& fb_lvalue
)
14122 *expr_p
= DECL_INITIAL (*expr_p
);
14128 ret
= gimplify_decl_expr (expr_p
, pre_p
);
14132 ret
= gimplify_bind_expr (expr_p
, pre_p
);
14136 ret
= gimplify_loop_expr (expr_p
, pre_p
);
14140 ret
= gimplify_switch_expr (expr_p
, pre_p
);
14144 ret
= gimplify_exit_expr (expr_p
);
14148 /* If the target is not LABEL, then it is a computed jump
14149 and the target needs to be gimplified. */
14150 if (TREE_CODE (GOTO_DESTINATION (*expr_p
)) != LABEL_DECL
)
14152 ret
= gimplify_expr (&GOTO_DESTINATION (*expr_p
), pre_p
,
14153 NULL
, is_gimple_val
, fb_rvalue
);
14154 if (ret
== GS_ERROR
)
14157 gimplify_seq_add_stmt (pre_p
,
14158 gimple_build_goto (GOTO_DESTINATION (*expr_p
)));
14163 gimplify_seq_add_stmt (pre_p
,
14164 gimple_build_predict (PREDICT_EXPR_PREDICTOR (*expr_p
),
14165 PREDICT_EXPR_OUTCOME (*expr_p
)));
14170 ret
= gimplify_label_expr (expr_p
, pre_p
);
14171 label
= LABEL_EXPR_LABEL (*expr_p
);
14172 gcc_assert (decl_function_context (label
) == current_function_decl
);
14174 /* If the label is used in a goto statement, or address of the label
14175 is taken, we need to unpoison all variables that were seen so far.
14176 Doing so would prevent us from reporting a false positives. */
14177 if (asan_poisoned_variables
14178 && asan_used_labels
!= NULL
14179 && asan_used_labels
->contains (label
))
14180 asan_poison_variables (asan_poisoned_variables
, false, pre_p
);
14183 case CASE_LABEL_EXPR
:
14184 ret
= gimplify_case_label_expr (expr_p
, pre_p
);
14186 if (gimplify_ctxp
->live_switch_vars
)
14187 asan_poison_variables (gimplify_ctxp
->live_switch_vars
, false,
14192 ret
= gimplify_return_expr (*expr_p
, pre_p
);
14196 /* Don't reduce this in place; let gimplify_init_constructor work its
14197 magic. Buf if we're just elaborating this for side effects, just
14198 gimplify any element that has side-effects. */
14199 if (fallback
== fb_none
)
14201 unsigned HOST_WIDE_INT ix
;
14203 tree temp
= NULL_TREE
;
14204 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (*expr_p
), ix
, val
)
14205 if (TREE_SIDE_EFFECTS (val
))
14206 append_to_statement_list (val
, &temp
);
14209 ret
= temp
? GS_OK
: GS_ALL_DONE
;
14211 /* C99 code may assign to an array in a constructed
14212 structure or union, and this has undefined behavior only
14213 on execution, so create a temporary if an lvalue is
14215 else if (fallback
== fb_lvalue
)
14217 *expr_p
= get_initialized_tmp_var (*expr_p
, pre_p
, post_p
, false);
14218 mark_addressable (*expr_p
);
14225 /* The following are special cases that are not handled by the
14226 original GIMPLE grammar. */
14228 /* SAVE_EXPR nodes are converted into a GIMPLE identifier and
14231 ret
= gimplify_save_expr (expr_p
, pre_p
, post_p
);
14234 case BIT_FIELD_REF
:
14235 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
14236 post_p
, is_gimple_lvalue
, fb_either
);
14237 recalculate_side_effects (*expr_p
);
14240 case TARGET_MEM_REF
:
14242 enum gimplify_status r0
= GS_ALL_DONE
, r1
= GS_ALL_DONE
;
14244 if (TMR_BASE (*expr_p
))
14245 r0
= gimplify_expr (&TMR_BASE (*expr_p
), pre_p
,
14246 post_p
, is_gimple_mem_ref_addr
, fb_either
);
14247 if (TMR_INDEX (*expr_p
))
14248 r1
= gimplify_expr (&TMR_INDEX (*expr_p
), pre_p
,
14249 post_p
, is_gimple_val
, fb_rvalue
);
14250 if (TMR_INDEX2 (*expr_p
))
14251 r1
= gimplify_expr (&TMR_INDEX2 (*expr_p
), pre_p
,
14252 post_p
, is_gimple_val
, fb_rvalue
);
14253 /* TMR_STEP and TMR_OFFSET are always integer constants. */
14254 ret
= MIN (r0
, r1
);
14258 case NON_LVALUE_EXPR
:
14259 /* This should have been stripped above. */
14260 gcc_unreachable ();
14263 ret
= gimplify_asm_expr (expr_p
, pre_p
, post_p
);
14266 case TRY_FINALLY_EXPR
:
14267 case TRY_CATCH_EXPR
:
14269 gimple_seq eval
, cleanup
;
14272 /* Calls to destructors are generated automatically in FINALLY/CATCH
14273 block. They should have location as UNKNOWN_LOCATION. However,
14274 gimplify_call_expr will reset these call stmts to input_location
14275 if it finds stmt's location is unknown. To prevent resetting for
14276 destructors, we set the input_location to unknown.
14277 Note that this only affects the destructor calls in FINALLY/CATCH
14278 block, and will automatically reset to its original value by the
14279 end of gimplify_expr. */
14280 input_location
= UNKNOWN_LOCATION
;
14281 eval
= cleanup
= NULL
;
14282 gimplify_and_add (TREE_OPERAND (*expr_p
, 0), &eval
);
14283 if (TREE_CODE (*expr_p
) == TRY_FINALLY_EXPR
14284 && TREE_CODE (TREE_OPERAND (*expr_p
, 1)) == EH_ELSE_EXPR
)
14286 gimple_seq n
= NULL
, e
= NULL
;
14287 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p
, 1),
14289 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p
, 1),
14291 if (!gimple_seq_empty_p (n
) && !gimple_seq_empty_p (e
))
14293 geh_else
*stmt
= gimple_build_eh_else (n
, e
);
14294 gimple_seq_add_stmt (&cleanup
, stmt
);
14298 gimplify_and_add (TREE_OPERAND (*expr_p
, 1), &cleanup
);
14299 /* Don't create bogus GIMPLE_TRY with empty cleanup. */
14300 if (gimple_seq_empty_p (cleanup
))
14302 gimple_seq_add_seq (pre_p
, eval
);
14306 try_
= gimple_build_try (eval
, cleanup
,
14307 TREE_CODE (*expr_p
) == TRY_FINALLY_EXPR
14308 ? GIMPLE_TRY_FINALLY
14309 : GIMPLE_TRY_CATCH
);
14310 if (EXPR_HAS_LOCATION (save_expr
))
14311 gimple_set_location (try_
, EXPR_LOCATION (save_expr
));
14312 else if (LOCATION_LOCUS (saved_location
) != UNKNOWN_LOCATION
)
14313 gimple_set_location (try_
, saved_location
);
14314 if (TREE_CODE (*expr_p
) == TRY_CATCH_EXPR
)
14315 gimple_try_set_catch_is_cleanup (try_
,
14316 TRY_CATCH_IS_CLEANUP (*expr_p
));
14317 gimplify_seq_add_stmt (pre_p
, try_
);
14322 case CLEANUP_POINT_EXPR
:
14323 ret
= gimplify_cleanup_point_expr (expr_p
, pre_p
);
14327 ret
= gimplify_target_expr (expr_p
, pre_p
, post_p
);
14333 gimple_seq handler
= NULL
;
14334 gimplify_and_add (CATCH_BODY (*expr_p
), &handler
);
14335 c
= gimple_build_catch (CATCH_TYPES (*expr_p
), handler
);
14336 gimplify_seq_add_stmt (pre_p
, c
);
14341 case EH_FILTER_EXPR
:
14344 gimple_seq failure
= NULL
;
14346 gimplify_and_add (EH_FILTER_FAILURE (*expr_p
), &failure
);
14347 ehf
= gimple_build_eh_filter (EH_FILTER_TYPES (*expr_p
), failure
);
14348 gimple_set_no_warning (ehf
, TREE_NO_WARNING (*expr_p
));
14349 gimplify_seq_add_stmt (pre_p
, ehf
);
14356 enum gimplify_status r0
, r1
;
14357 r0
= gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p
), pre_p
,
14358 post_p
, is_gimple_val
, fb_rvalue
);
14359 r1
= gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p
), pre_p
,
14360 post_p
, is_gimple_val
, fb_rvalue
);
14361 TREE_SIDE_EFFECTS (*expr_p
) = 0;
14362 ret
= MIN (r0
, r1
);
14367 /* We get here when taking the address of a label. We mark
14368 the label as "forced"; meaning it can never be removed and
14369 it is a potential target for any computed goto. */
14370 FORCED_LABEL (*expr_p
) = 1;
14374 case STATEMENT_LIST
:
14375 ret
= gimplify_statement_list (expr_p
, pre_p
);
14378 case WITH_SIZE_EXPR
:
14380 gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
14381 post_p
== &internal_post
? NULL
: post_p
,
14382 gimple_test_f
, fallback
);
14383 gimplify_expr (&TREE_OPERAND (*expr_p
, 1), pre_p
, post_p
,
14384 is_gimple_val
, fb_rvalue
);
14391 ret
= gimplify_var_or_parm_decl (expr_p
);
14395 /* When within an OMP context, notice uses of variables. */
14396 if (gimplify_omp_ctxp
)
14397 omp_notice_variable (gimplify_omp_ctxp
, *expr_p
, true);
14401 case DEBUG_EXPR_DECL
:
14402 gcc_unreachable ();
14404 case DEBUG_BEGIN_STMT
:
14405 gimplify_seq_add_stmt (pre_p
,
14406 gimple_build_debug_begin_stmt
14407 (TREE_BLOCK (*expr_p
),
14408 EXPR_LOCATION (*expr_p
)));
14414 /* Allow callbacks into the gimplifier during optimization. */
14419 gimplify_omp_parallel (expr_p
, pre_p
);
14424 gimplify_omp_task (expr_p
, pre_p
);
14430 case OMP_DISTRIBUTE
:
14433 ret
= gimplify_omp_for (expr_p
, pre_p
);
14437 ret
= gimplify_omp_loop (expr_p
, pre_p
);
14441 gimplify_oacc_cache (expr_p
, pre_p
);
14446 gimplify_oacc_declare (expr_p
, pre_p
);
14450 case OACC_HOST_DATA
:
14453 case OACC_PARALLEL
:
14458 case OMP_TARGET_DATA
:
14460 gimplify_omp_workshare (expr_p
, pre_p
);
14464 case OACC_ENTER_DATA
:
14465 case OACC_EXIT_DATA
:
14467 case OMP_TARGET_UPDATE
:
14468 case OMP_TARGET_ENTER_DATA
:
14469 case OMP_TARGET_EXIT_DATA
:
14470 gimplify_omp_target_update (expr_p
, pre_p
);
14480 gimple_seq body
= NULL
;
14482 bool saved_in_omp_construct
= in_omp_construct
;
14484 in_omp_construct
= true;
14485 gimplify_and_add (OMP_BODY (*expr_p
), &body
);
14486 in_omp_construct
= saved_in_omp_construct
;
14487 switch (TREE_CODE (*expr_p
))
14490 g
= gimple_build_omp_section (body
);
14493 g
= gimple_build_omp_master (body
);
14496 g
= gimplify_omp_ordered (*expr_p
, body
);
14499 gimplify_scan_omp_clauses (&OMP_CRITICAL_CLAUSES (*expr_p
),
14500 pre_p
, ORT_WORKSHARE
, OMP_CRITICAL
);
14501 gimplify_adjust_omp_clauses (pre_p
, body
,
14502 &OMP_CRITICAL_CLAUSES (*expr_p
),
14504 g
= gimple_build_omp_critical (body
,
14505 OMP_CRITICAL_NAME (*expr_p
),
14506 OMP_CRITICAL_CLAUSES (*expr_p
));
14509 gimplify_scan_omp_clauses (&OMP_SCAN_CLAUSES (*expr_p
),
14510 pre_p
, ORT_WORKSHARE
, OMP_SCAN
);
14511 gimplify_adjust_omp_clauses (pre_p
, body
,
14512 &OMP_SCAN_CLAUSES (*expr_p
),
14514 g
= gimple_build_omp_scan (body
, OMP_SCAN_CLAUSES (*expr_p
));
14517 gcc_unreachable ();
14519 gimplify_seq_add_stmt (pre_p
, g
);
14524 case OMP_TASKGROUP
:
14526 gimple_seq body
= NULL
;
14528 tree
*pclauses
= &OMP_TASKGROUP_CLAUSES (*expr_p
);
14529 bool saved_in_omp_construct
= in_omp_construct
;
14530 gimplify_scan_omp_clauses (pclauses
, pre_p
, ORT_TASKGROUP
,
14532 gimplify_adjust_omp_clauses (pre_p
, NULL
, pclauses
, OMP_TASKGROUP
);
14534 in_omp_construct
= true;
14535 gimplify_and_add (OMP_BODY (*expr_p
), &body
);
14536 in_omp_construct
= saved_in_omp_construct
;
14537 gimple_seq cleanup
= NULL
;
14538 tree fn
= builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_END
);
14539 gimple
*g
= gimple_build_call (fn
, 0);
14540 gimple_seq_add_stmt (&cleanup
, g
);
14541 g
= gimple_build_try (body
, cleanup
, GIMPLE_TRY_FINALLY
);
14543 gimple_seq_add_stmt (&body
, g
);
14544 g
= gimple_build_omp_taskgroup (body
, *pclauses
);
14545 gimplify_seq_add_stmt (pre_p
, g
);
14551 case OMP_ATOMIC_READ
:
14552 case OMP_ATOMIC_CAPTURE_OLD
:
14553 case OMP_ATOMIC_CAPTURE_NEW
:
14554 ret
= gimplify_omp_atomic (expr_p
, pre_p
);
14557 case TRANSACTION_EXPR
:
14558 ret
= gimplify_transaction (expr_p
, pre_p
);
14561 case TRUTH_AND_EXPR
:
14562 case TRUTH_OR_EXPR
:
14563 case TRUTH_XOR_EXPR
:
14565 tree orig_type
= TREE_TYPE (*expr_p
);
14566 tree new_type
, xop0
, xop1
;
14567 *expr_p
= gimple_boolify (*expr_p
);
14568 new_type
= TREE_TYPE (*expr_p
);
14569 if (!useless_type_conversion_p (orig_type
, new_type
))
14571 *expr_p
= fold_convert_loc (input_location
, orig_type
, *expr_p
);
14576 /* Boolified binary truth expressions are semantically equivalent
14577 to bitwise binary expressions. Canonicalize them to the
14578 bitwise variant. */
14579 switch (TREE_CODE (*expr_p
))
14581 case TRUTH_AND_EXPR
:
14582 TREE_SET_CODE (*expr_p
, BIT_AND_EXPR
);
14584 case TRUTH_OR_EXPR
:
14585 TREE_SET_CODE (*expr_p
, BIT_IOR_EXPR
);
14587 case TRUTH_XOR_EXPR
:
14588 TREE_SET_CODE (*expr_p
, BIT_XOR_EXPR
);
14593 /* Now make sure that operands have compatible type to
14594 expression's new_type. */
14595 xop0
= TREE_OPERAND (*expr_p
, 0);
14596 xop1
= TREE_OPERAND (*expr_p
, 1);
14597 if (!useless_type_conversion_p (new_type
, TREE_TYPE (xop0
)))
14598 TREE_OPERAND (*expr_p
, 0) = fold_convert_loc (input_location
,
14601 if (!useless_type_conversion_p (new_type
, TREE_TYPE (xop1
)))
14602 TREE_OPERAND (*expr_p
, 1) = fold_convert_loc (input_location
,
14605 /* Continue classified as tcc_binary. */
14609 case VEC_COND_EXPR
:
14612 case VEC_PERM_EXPR
:
14613 /* Classified as tcc_expression. */
14616 case BIT_INSERT_EXPR
:
14617 /* Argument 3 is a constant. */
14620 case POINTER_PLUS_EXPR
:
14622 enum gimplify_status r0
, r1
;
14623 r0
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
14624 post_p
, is_gimple_val
, fb_rvalue
);
14625 r1
= gimplify_expr (&TREE_OPERAND (*expr_p
, 1), pre_p
,
14626 post_p
, is_gimple_val
, fb_rvalue
);
14627 recalculate_side_effects (*expr_p
);
14628 ret
= MIN (r0
, r1
);
14633 switch (TREE_CODE_CLASS (TREE_CODE (*expr_p
)))
14635 case tcc_comparison
:
14636 /* Handle comparison of objects of non scalar mode aggregates
14637 with a call to memcmp. It would be nice to only have to do
14638 this for variable-sized objects, but then we'd have to allow
14639 the same nest of reference nodes we allow for MODIFY_EXPR and
14640 that's too complex.
14642 Compare scalar mode aggregates as scalar mode values. Using
14643 memcmp for them would be very inefficient at best, and is
14644 plain wrong if bitfields are involved. */
14646 tree type
= TREE_TYPE (TREE_OPERAND (*expr_p
, 1));
14648 /* Vector comparisons need no boolification. */
14649 if (TREE_CODE (type
) == VECTOR_TYPE
)
14651 else if (!AGGREGATE_TYPE_P (type
))
14653 tree org_type
= TREE_TYPE (*expr_p
);
14654 *expr_p
= gimple_boolify (*expr_p
);
14655 if (!useless_type_conversion_p (org_type
,
14656 TREE_TYPE (*expr_p
)))
14658 *expr_p
= fold_convert_loc (input_location
,
14659 org_type
, *expr_p
);
14665 else if (TYPE_MODE (type
) != BLKmode
)
14666 ret
= gimplify_scalar_mode_aggregate_compare (expr_p
);
14668 ret
= gimplify_variable_sized_compare (expr_p
);
14673 /* If *EXPR_P does not need to be special-cased, handle it
14674 according to its class. */
14676 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
14677 post_p
, is_gimple_val
, fb_rvalue
);
14683 enum gimplify_status r0
, r1
;
14685 r0
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
14686 post_p
, is_gimple_val
, fb_rvalue
);
14687 r1
= gimplify_expr (&TREE_OPERAND (*expr_p
, 1), pre_p
,
14688 post_p
, is_gimple_val
, fb_rvalue
);
14690 ret
= MIN (r0
, r1
);
14696 enum gimplify_status r0
, r1
, r2
;
14698 r0
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
14699 post_p
, is_gimple_val
, fb_rvalue
);
14700 r1
= gimplify_expr (&TREE_OPERAND (*expr_p
, 1), pre_p
,
14701 post_p
, is_gimple_val
, fb_rvalue
);
14702 r2
= gimplify_expr (&TREE_OPERAND (*expr_p
, 2), pre_p
,
14703 post_p
, is_gimple_val
, fb_rvalue
);
14705 ret
= MIN (MIN (r0
, r1
), r2
);
14709 case tcc_declaration
:
14712 goto dont_recalculate
;
14715 gcc_unreachable ();
14718 recalculate_side_effects (*expr_p
);
14724 gcc_assert (*expr_p
|| ret
!= GS_OK
);
14726 while (ret
== GS_OK
);
14728 /* If we encountered an error_mark somewhere nested inside, either
14729 stub out the statement or propagate the error back out. */
14730 if (ret
== GS_ERROR
)
14737 /* This was only valid as a return value from the langhook, which
14738 we handled. Make sure it doesn't escape from any other context. */
14739 gcc_assert (ret
!= GS_UNHANDLED
);
14741 if (fallback
== fb_none
&& *expr_p
&& !is_gimple_stmt (*expr_p
))
14743 /* We aren't looking for a value, and we don't have a valid
14744 statement. If it doesn't have side-effects, throw it away.
14745 We can also get here with code such as "*&&L;", where L is
14746 a LABEL_DECL that is marked as FORCED_LABEL. */
14747 if (TREE_CODE (*expr_p
) == LABEL_DECL
14748 || !TREE_SIDE_EFFECTS (*expr_p
))
14750 else if (!TREE_THIS_VOLATILE (*expr_p
))
14752 /* This is probably a _REF that contains something nested that
14753 has side effects. Recurse through the operands to find it. */
14754 enum tree_code code
= TREE_CODE (*expr_p
);
14758 case COMPONENT_REF
:
14759 case REALPART_EXPR
:
14760 case IMAGPART_EXPR
:
14761 case VIEW_CONVERT_EXPR
:
14762 gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
14763 gimple_test_f
, fallback
);
14767 case ARRAY_RANGE_REF
:
14768 gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
14769 gimple_test_f
, fallback
);
14770 gimplify_expr (&TREE_OPERAND (*expr_p
, 1), pre_p
, post_p
,
14771 gimple_test_f
, fallback
);
14775 /* Anything else with side-effects must be converted to
14776 a valid statement before we get here. */
14777 gcc_unreachable ();
14782 else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p
))
14783 && TYPE_MODE (TREE_TYPE (*expr_p
)) != BLKmode
)
14785 /* Historically, the compiler has treated a bare reference
14786 to a non-BLKmode volatile lvalue as forcing a load. */
14787 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p
));
14789 /* Normally, we do not want to create a temporary for a
14790 TREE_ADDRESSABLE type because such a type should not be
14791 copied by bitwise-assignment. However, we make an
14792 exception here, as all we are doing here is ensuring that
14793 we read the bytes that make up the type. We use
14794 create_tmp_var_raw because create_tmp_var will abort when
14795 given a TREE_ADDRESSABLE type. */
14796 tree tmp
= create_tmp_var_raw (type
, "vol");
14797 gimple_add_tmp_var (tmp
);
14798 gimplify_assign (tmp
, *expr_p
, pre_p
);
14802 /* We can't do anything useful with a volatile reference to
14803 an incomplete type, so just throw it away. Likewise for
14804 a BLKmode type, since any implicit inner load should
14805 already have been turned into an explicit one by the
14806 gimplification process. */
14810 /* If we are gimplifying at the statement level, we're done. Tack
14811 everything together and return. */
14812 if (fallback
== fb_none
|| is_statement
)
14814 /* Since *EXPR_P has been converted into a GIMPLE tuple, clear
14815 it out for GC to reclaim it. */
14816 *expr_p
= NULL_TREE
;
14818 if (!gimple_seq_empty_p (internal_pre
)
14819 || !gimple_seq_empty_p (internal_post
))
14821 gimplify_seq_add_seq (&internal_pre
, internal_post
);
14822 gimplify_seq_add_seq (pre_p
, internal_pre
);
14825 /* The result of gimplifying *EXPR_P is going to be the last few
14826 statements in *PRE_P and *POST_P. Add location information
14827 to all the statements that were added by the gimplification
14829 if (!gimple_seq_empty_p (*pre_p
))
14830 annotate_all_with_location_after (*pre_p
, pre_last_gsi
, input_location
);
14832 if (!gimple_seq_empty_p (*post_p
))
14833 annotate_all_with_location_after (*post_p
, post_last_gsi
,
14839 #ifdef ENABLE_GIMPLE_CHECKING
14842 enum tree_code code
= TREE_CODE (*expr_p
);
14843 /* These expressions should already be in gimple IR form. */
14844 gcc_assert (code
!= MODIFY_EXPR
14845 && code
!= ASM_EXPR
14846 && code
!= BIND_EXPR
14847 && code
!= CATCH_EXPR
14848 && (code
!= COND_EXPR
|| gimplify_ctxp
->allow_rhs_cond_expr
)
14849 && code
!= EH_FILTER_EXPR
14850 && code
!= GOTO_EXPR
14851 && code
!= LABEL_EXPR
14852 && code
!= LOOP_EXPR
14853 && code
!= SWITCH_EXPR
14854 && code
!= TRY_FINALLY_EXPR
14855 && code
!= EH_ELSE_EXPR
14856 && code
!= OACC_PARALLEL
14857 && code
!= OACC_KERNELS
14858 && code
!= OACC_SERIAL
14859 && code
!= OACC_DATA
14860 && code
!= OACC_HOST_DATA
14861 && code
!= OACC_DECLARE
14862 && code
!= OACC_UPDATE
14863 && code
!= OACC_ENTER_DATA
14864 && code
!= OACC_EXIT_DATA
14865 && code
!= OACC_CACHE
14866 && code
!= OMP_CRITICAL
14868 && code
!= OACC_LOOP
14869 && code
!= OMP_MASTER
14870 && code
!= OMP_TASKGROUP
14871 && code
!= OMP_ORDERED
14872 && code
!= OMP_PARALLEL
14873 && code
!= OMP_SCAN
14874 && code
!= OMP_SECTIONS
14875 && code
!= OMP_SECTION
14876 && code
!= OMP_SINGLE
);
14880 /* Otherwise we're gimplifying a subexpression, so the resulting
14881 value is interesting. If it's a valid operand that matches
14882 GIMPLE_TEST_F, we're done. Unless we are handling some
14883 post-effects internally; if that's the case, we need to copy into
14884 a temporary before adding the post-effects to POST_P. */
14885 if (gimple_seq_empty_p (internal_post
) && (*gimple_test_f
) (*expr_p
))
14888 /* Otherwise, we need to create a new temporary for the gimplified
14891 /* We can't return an lvalue if we have an internal postqueue. The
14892 object the lvalue refers to would (probably) be modified by the
14893 postqueue; we need to copy the value out first, which means an
14895 if ((fallback
& fb_lvalue
)
14896 && gimple_seq_empty_p (internal_post
)
14897 && is_gimple_addressable (*expr_p
))
14899 /* An lvalue will do. Take the address of the expression, store it
14900 in a temporary, and replace the expression with an INDIRECT_REF of
14902 tree ref_alias_type
= reference_alias_ptr_type (*expr_p
);
14903 unsigned int ref_align
= get_object_alignment (*expr_p
);
14904 tree ref_type
= TREE_TYPE (*expr_p
);
14905 tmp
= build_fold_addr_expr_loc (input_location
, *expr_p
);
14906 gimplify_expr (&tmp
, pre_p
, post_p
, is_gimple_reg
, fb_rvalue
);
14907 if (TYPE_ALIGN (ref_type
) != ref_align
)
14908 ref_type
= build_aligned_type (ref_type
, ref_align
);
14909 *expr_p
= build2 (MEM_REF
, ref_type
,
14910 tmp
, build_zero_cst (ref_alias_type
));
14912 else if ((fallback
& fb_rvalue
) && is_gimple_reg_rhs_or_call (*expr_p
))
14914 /* An rvalue will do. Assign the gimplified expression into a
14915 new temporary TMP and replace the original expression with
14916 TMP. First, make sure that the expression has a type so that
14917 it can be assigned into a temporary. */
14918 gcc_assert (!VOID_TYPE_P (TREE_TYPE (*expr_p
)));
14919 *expr_p
= get_formal_tmp_var (*expr_p
, pre_p
);
14923 #ifdef ENABLE_GIMPLE_CHECKING
14924 if (!(fallback
& fb_mayfail
))
14926 fprintf (stderr
, "gimplification failed:\n");
14927 print_generic_expr (stderr
, *expr_p
);
14928 debug_tree (*expr_p
);
14929 internal_error ("gimplification failed");
14932 gcc_assert (fallback
& fb_mayfail
);
14934 /* If this is an asm statement, and the user asked for the
14935 impossible, don't die. Fail and let gimplify_asm_expr
14941 /* Make sure the temporary matches our predicate. */
14942 gcc_assert ((*gimple_test_f
) (*expr_p
));
14944 if (!gimple_seq_empty_p (internal_post
))
14946 annotate_all_with_location (internal_post
, input_location
);
14947 gimplify_seq_add_seq (pre_p
, internal_post
);
14951 input_location
= saved_location
;
14955 /* Like gimplify_expr but make sure the gimplified result is not itself
14956 a SSA name (but a decl if it were). Temporaries required by
14957 evaluating *EXPR_P may be still SSA names. */
14959 static enum gimplify_status
14960 gimplify_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
14961 bool (*gimple_test_f
) (tree
), fallback_t fallback
,
14964 bool was_ssa_name_p
= TREE_CODE (*expr_p
) == SSA_NAME
;
14965 enum gimplify_status ret
= gimplify_expr (expr_p
, pre_p
, post_p
,
14966 gimple_test_f
, fallback
);
14968 && TREE_CODE (*expr_p
) == SSA_NAME
)
14970 tree name
= *expr_p
;
14971 if (was_ssa_name_p
)
14972 *expr_p
= get_initialized_tmp_var (*expr_p
, pre_p
, NULL
, false);
14975 /* Avoid the extra copy if possible. */
14976 *expr_p
= create_tmp_reg (TREE_TYPE (name
));
14977 if (!gimple_nop_p (SSA_NAME_DEF_STMT (name
)))
14978 gimple_set_lhs (SSA_NAME_DEF_STMT (name
), *expr_p
);
14979 release_ssa_name (name
);
14985 /* Look through TYPE for variable-sized objects and gimplify each such
14986 size that we find. Add to LIST_P any statements generated. */
14989 gimplify_type_sizes (tree type
, gimple_seq
*list_p
)
14993 if (type
== NULL
|| type
== error_mark_node
)
14996 /* We first do the main variant, then copy into any other variants. */
14997 type
= TYPE_MAIN_VARIANT (type
);
14999 /* Avoid infinite recursion. */
15000 if (TYPE_SIZES_GIMPLIFIED (type
))
15003 TYPE_SIZES_GIMPLIFIED (type
) = 1;
15005 switch (TREE_CODE (type
))
15008 case ENUMERAL_TYPE
:
15011 case FIXED_POINT_TYPE
:
15012 gimplify_one_sizepos (&TYPE_MIN_VALUE (type
), list_p
);
15013 gimplify_one_sizepos (&TYPE_MAX_VALUE (type
), list_p
);
15015 for (t
= TYPE_NEXT_VARIANT (type
); t
; t
= TYPE_NEXT_VARIANT (t
))
15017 TYPE_MIN_VALUE (t
) = TYPE_MIN_VALUE (type
);
15018 TYPE_MAX_VALUE (t
) = TYPE_MAX_VALUE (type
);
15023 /* These types may not have declarations, so handle them here. */
15024 gimplify_type_sizes (TREE_TYPE (type
), list_p
);
15025 gimplify_type_sizes (TYPE_DOMAIN (type
), list_p
);
15026 /* Ensure VLA bounds aren't removed, for -O0 they should be variables
15027 with assigned stack slots, for -O1+ -g they should be tracked
15029 if (!(TYPE_NAME (type
)
15030 && TREE_CODE (TYPE_NAME (type
)) == TYPE_DECL
15031 && DECL_IGNORED_P (TYPE_NAME (type
)))
15032 && TYPE_DOMAIN (type
)
15033 && INTEGRAL_TYPE_P (TYPE_DOMAIN (type
)))
15035 t
= TYPE_MIN_VALUE (TYPE_DOMAIN (type
));
15036 if (t
&& VAR_P (t
) && DECL_ARTIFICIAL (t
))
15037 DECL_IGNORED_P (t
) = 0;
15038 t
= TYPE_MAX_VALUE (TYPE_DOMAIN (type
));
15039 if (t
&& VAR_P (t
) && DECL_ARTIFICIAL (t
))
15040 DECL_IGNORED_P (t
) = 0;
15046 case QUAL_UNION_TYPE
:
15047 for (field
= TYPE_FIELDS (type
); field
; field
= DECL_CHAIN (field
))
15048 if (TREE_CODE (field
) == FIELD_DECL
)
15050 gimplify_one_sizepos (&DECL_FIELD_OFFSET (field
), list_p
);
15051 gimplify_one_sizepos (&DECL_SIZE (field
), list_p
);
15052 gimplify_one_sizepos (&DECL_SIZE_UNIT (field
), list_p
);
15053 gimplify_type_sizes (TREE_TYPE (field
), list_p
);
15058 case REFERENCE_TYPE
:
15059 /* We used to recurse on the pointed-to type here, which turned out to
15060 be incorrect because its definition might refer to variables not
15061 yet initialized at this point if a forward declaration is involved.
15063 It was actually useful for anonymous pointed-to types to ensure
15064 that the sizes evaluation dominates every possible later use of the
15065 values. Restricting to such types here would be safe since there
15066 is no possible forward declaration around, but would introduce an
15067 undesirable middle-end semantic to anonymity. We then defer to
15068 front-ends the responsibility of ensuring that the sizes are
15069 evaluated both early and late enough, e.g. by attaching artificial
15070 type declarations to the tree. */
15077 gimplify_one_sizepos (&TYPE_SIZE (type
), list_p
);
15078 gimplify_one_sizepos (&TYPE_SIZE_UNIT (type
), list_p
);
15080 for (t
= TYPE_NEXT_VARIANT (type
); t
; t
= TYPE_NEXT_VARIANT (t
))
15082 TYPE_SIZE (t
) = TYPE_SIZE (type
);
15083 TYPE_SIZE_UNIT (t
) = TYPE_SIZE_UNIT (type
);
15084 TYPE_SIZES_GIMPLIFIED (t
) = 1;
15088 /* A subroutine of gimplify_type_sizes to make sure that *EXPR_P,
15089 a size or position, has had all of its SAVE_EXPRs evaluated.
15090 We add any required statements to *STMT_P. */
15093 gimplify_one_sizepos (tree
*expr_p
, gimple_seq
*stmt_p
)
15095 tree expr
= *expr_p
;
15097 /* We don't do anything if the value isn't there, is constant, or contains
15098 A PLACEHOLDER_EXPR. We also don't want to do anything if it's already
15099 a VAR_DECL. If it's a VAR_DECL from another function, the gimplifier
15100 will want to replace it with a new variable, but that will cause problems
15101 if this type is from outside the function. It's OK to have that here. */
15102 if (expr
== NULL_TREE
15103 || is_gimple_constant (expr
)
15104 || TREE_CODE (expr
) == VAR_DECL
15105 || CONTAINS_PLACEHOLDER_P (expr
))
15108 *expr_p
= unshare_expr (expr
);
15110 /* SSA names in decl/type fields are a bad idea - they'll get reclaimed
15111 if the def vanishes. */
15112 gimplify_expr (expr_p
, stmt_p
, NULL
, is_gimple_val
, fb_rvalue
, false);
15114 /* If expr wasn't already is_gimple_sizepos or is_gimple_constant from the
15115 FE, ensure that it is a VAR_DECL, otherwise we might handle some decls
15116 as gimplify_vla_decl even when they would have all sizes INTEGER_CSTs. */
15117 if (is_gimple_constant (*expr_p
))
15118 *expr_p
= get_initialized_tmp_var (*expr_p
, stmt_p
, NULL
, false);
15121 /* Gimplify the body of statements of FNDECL and return a GIMPLE_BIND node
15122 containing the sequence of corresponding GIMPLE statements. If DO_PARMS
15123 is true, also gimplify the parameters. */
15126 gimplify_body (tree fndecl
, bool do_parms
)
15128 location_t saved_location
= input_location
;
15129 gimple_seq parm_stmts
, parm_cleanup
= NULL
, seq
;
15130 gimple
*outer_stmt
;
15133 timevar_push (TV_TREE_GIMPLIFY
);
15135 init_tree_ssa (cfun
);
15137 /* Initialize for optimize_insn_for_s{ize,peed}_p possibly called during
15139 default_rtl_profile ();
15141 gcc_assert (gimplify_ctxp
== NULL
);
15142 push_gimplify_context (true);
15144 if (flag_openacc
|| flag_openmp
)
15146 gcc_assert (gimplify_omp_ctxp
== NULL
);
15147 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (fndecl
)))
15148 gimplify_omp_ctxp
= new_omp_context (ORT_IMPLICIT_TARGET
);
15151 /* Unshare most shared trees in the body and in that of any nested functions.
15152 It would seem we don't have to do this for nested functions because
15153 they are supposed to be output and then the outer function gimplified
15154 first, but the g++ front end doesn't always do it that way. */
15155 unshare_body (fndecl
);
15156 unvisit_body (fndecl
);
15158 /* Make sure input_location isn't set to something weird. */
15159 input_location
= DECL_SOURCE_LOCATION (fndecl
);
15161 /* Resolve callee-copies. This has to be done before processing
15162 the body so that DECL_VALUE_EXPR gets processed correctly. */
15163 parm_stmts
= do_parms
? gimplify_parameters (&parm_cleanup
) : NULL
;
15165 /* Gimplify the function's body. */
15167 gimplify_stmt (&DECL_SAVED_TREE (fndecl
), &seq
);
15168 outer_stmt
= gimple_seq_first_nondebug_stmt (seq
);
15171 outer_stmt
= gimple_build_nop ();
15172 gimplify_seq_add_stmt (&seq
, outer_stmt
);
15175 /* The body must contain exactly one statement, a GIMPLE_BIND. If this is
15176 not the case, wrap everything in a GIMPLE_BIND to make it so. */
15177 if (gimple_code (outer_stmt
) == GIMPLE_BIND
15178 && (gimple_seq_first_nondebug_stmt (seq
)
15179 == gimple_seq_last_nondebug_stmt (seq
)))
15181 outer_bind
= as_a
<gbind
*> (outer_stmt
);
15182 if (gimple_seq_first_stmt (seq
) != outer_stmt
15183 || gimple_seq_last_stmt (seq
) != outer_stmt
)
15185 /* If there are debug stmts before or after outer_stmt, move them
15186 inside of outer_bind body. */
15187 gimple_stmt_iterator gsi
= gsi_for_stmt (outer_stmt
, &seq
);
15188 gimple_seq second_seq
= NULL
;
15189 if (gimple_seq_first_stmt (seq
) != outer_stmt
15190 && gimple_seq_last_stmt (seq
) != outer_stmt
)
15192 second_seq
= gsi_split_seq_after (gsi
);
15193 gsi_remove (&gsi
, false);
15195 else if (gimple_seq_first_stmt (seq
) != outer_stmt
)
15196 gsi_remove (&gsi
, false);
15199 gsi_remove (&gsi
, false);
15203 gimple_seq_add_seq_without_update (&seq
,
15204 gimple_bind_body (outer_bind
));
15205 gimple_seq_add_seq_without_update (&seq
, second_seq
);
15206 gimple_bind_set_body (outer_bind
, seq
);
15210 outer_bind
= gimple_build_bind (NULL_TREE
, seq
, NULL
);
15212 DECL_SAVED_TREE (fndecl
) = NULL_TREE
;
15214 /* If we had callee-copies statements, insert them at the beginning
15215 of the function and clear DECL_VALUE_EXPR_P on the parameters. */
15216 if (!gimple_seq_empty_p (parm_stmts
))
15220 gimplify_seq_add_seq (&parm_stmts
, gimple_bind_body (outer_bind
));
15223 gtry
*g
= gimple_build_try (parm_stmts
, parm_cleanup
,
15224 GIMPLE_TRY_FINALLY
);
15226 gimple_seq_add_stmt (&parm_stmts
, g
);
15228 gimple_bind_set_body (outer_bind
, parm_stmts
);
15230 for (parm
= DECL_ARGUMENTS (current_function_decl
);
15231 parm
; parm
= DECL_CHAIN (parm
))
15232 if (DECL_HAS_VALUE_EXPR_P (parm
))
15234 DECL_HAS_VALUE_EXPR_P (parm
) = 0;
15235 DECL_IGNORED_P (parm
) = 0;
15239 if ((flag_openacc
|| flag_openmp
|| flag_openmp_simd
)
15240 && gimplify_omp_ctxp
)
15242 delete_omp_context (gimplify_omp_ctxp
);
15243 gimplify_omp_ctxp
= NULL
;
15246 pop_gimplify_context (outer_bind
);
15247 gcc_assert (gimplify_ctxp
== NULL
);
15249 if (flag_checking
&& !seen_error ())
15250 verify_gimple_in_seq (gimple_bind_body (outer_bind
));
15252 timevar_pop (TV_TREE_GIMPLIFY
);
15253 input_location
= saved_location
;
15258 typedef char *char_p
; /* For DEF_VEC_P. */
15260 /* Return whether we should exclude FNDECL from instrumentation. */
15263 flag_instrument_functions_exclude_p (tree fndecl
)
15267 v
= (vec
<char_p
> *) flag_instrument_functions_exclude_functions
;
15268 if (v
&& v
->length () > 0)
15274 name
= lang_hooks
.decl_printable_name (fndecl
, 1);
15275 FOR_EACH_VEC_ELT (*v
, i
, s
)
15276 if (strstr (name
, s
) != NULL
)
15280 v
= (vec
<char_p
> *) flag_instrument_functions_exclude_files
;
15281 if (v
&& v
->length () > 0)
15287 name
= DECL_SOURCE_FILE (fndecl
);
15288 FOR_EACH_VEC_ELT (*v
, i
, s
)
15289 if (strstr (name
, s
) != NULL
)
15296 /* Entry point to the gimplification pass. FNDECL is the FUNCTION_DECL
15297 node for the function we want to gimplify.
15299 Return the sequence of GIMPLE statements corresponding to the body
15303 gimplify_function_tree (tree fndecl
)
15308 gcc_assert (!gimple_body (fndecl
));
15310 if (DECL_STRUCT_FUNCTION (fndecl
))
15311 push_cfun (DECL_STRUCT_FUNCTION (fndecl
));
15313 push_struct_function (fndecl
);
15315 /* Tentatively set PROP_gimple_lva here, and reset it in gimplify_va_arg_expr
15317 cfun
->curr_properties
|= PROP_gimple_lva
;
15319 if (asan_sanitize_use_after_scope () && sanitize_flags_p (SANITIZE_ADDRESS
))
15320 asan_poisoned_variables
= new hash_set
<tree
> ();
15321 bind
= gimplify_body (fndecl
, true);
15322 if (asan_poisoned_variables
)
15324 delete asan_poisoned_variables
;
15325 asan_poisoned_variables
= NULL
;
15328 /* The tree body of the function is no longer needed, replace it
15329 with the new GIMPLE body. */
15331 gimple_seq_add_stmt (&seq
, bind
);
15332 gimple_set_body (fndecl
, seq
);
15334 /* If we're instrumenting function entry/exit, then prepend the call to
15335 the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to
15336 catch the exit hook. */
15337 /* ??? Add some way to ignore exceptions for this TFE. */
15338 if (flag_instrument_function_entry_exit
15339 && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl
)
15340 /* Do not instrument extern inline functions. */
15341 && !(DECL_DECLARED_INLINE_P (fndecl
)
15342 && DECL_EXTERNAL (fndecl
)
15343 && DECL_DISREGARD_INLINE_LIMITS (fndecl
))
15344 && !flag_instrument_functions_exclude_p (fndecl
))
15349 gimple_seq cleanup
= NULL
, body
= NULL
;
15350 tree tmp_var
, this_fn_addr
;
15353 /* The instrumentation hooks aren't going to call the instrumented
15354 function and the address they receive is expected to be matchable
15355 against symbol addresses. Make sure we don't create a trampoline,
15356 in case the current function is nested. */
15357 this_fn_addr
= build_fold_addr_expr (current_function_decl
);
15358 TREE_NO_TRAMPOLINE (this_fn_addr
) = 1;
15360 x
= builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS
);
15361 call
= gimple_build_call (x
, 1, integer_zero_node
);
15362 tmp_var
= create_tmp_var (ptr_type_node
, "return_addr");
15363 gimple_call_set_lhs (call
, tmp_var
);
15364 gimplify_seq_add_stmt (&cleanup
, call
);
15365 x
= builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_EXIT
);
15366 call
= gimple_build_call (x
, 2, this_fn_addr
, tmp_var
);
15367 gimplify_seq_add_stmt (&cleanup
, call
);
15368 tf
= gimple_build_try (seq
, cleanup
, GIMPLE_TRY_FINALLY
);
15370 x
= builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS
);
15371 call
= gimple_build_call (x
, 1, integer_zero_node
);
15372 tmp_var
= create_tmp_var (ptr_type_node
, "return_addr");
15373 gimple_call_set_lhs (call
, tmp_var
);
15374 gimplify_seq_add_stmt (&body
, call
);
15375 x
= builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_ENTER
);
15376 call
= gimple_build_call (x
, 2, this_fn_addr
, tmp_var
);
15377 gimplify_seq_add_stmt (&body
, call
);
15378 gimplify_seq_add_stmt (&body
, tf
);
15379 new_bind
= gimple_build_bind (NULL
, body
, NULL
);
15381 /* Replace the current function body with the body
15382 wrapped in the try/finally TF. */
15384 gimple_seq_add_stmt (&seq
, new_bind
);
15385 gimple_set_body (fndecl
, seq
);
15389 if (sanitize_flags_p (SANITIZE_THREAD
)
15390 && param_tsan_instrument_func_entry_exit
)
15392 gcall
*call
= gimple_build_call_internal (IFN_TSAN_FUNC_EXIT
, 0);
15393 gimple
*tf
= gimple_build_try (seq
, call
, GIMPLE_TRY_FINALLY
);
15394 gbind
*new_bind
= gimple_build_bind (NULL
, tf
, NULL
);
15395 /* Replace the current function body with the body
15396 wrapped in the try/finally TF. */
15398 gimple_seq_add_stmt (&seq
, new_bind
);
15399 gimple_set_body (fndecl
, seq
);
15402 DECL_SAVED_TREE (fndecl
) = NULL_TREE
;
15403 cfun
->curr_properties
|= PROP_gimple_any
;
15407 dump_function (TDI_gimple
, fndecl
);
15410 /* Return a dummy expression of type TYPE in order to keep going after an
15414 dummy_object (tree type
)
15416 tree t
= build_int_cst (build_pointer_type (type
), 0);
15417 return build2 (MEM_REF
, type
, t
, t
);
15420 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
15421 builtin function, but a very special sort of operator. */
15423 enum gimplify_status
15424 gimplify_va_arg_expr (tree
*expr_p
, gimple_seq
*pre_p
,
15425 gimple_seq
*post_p ATTRIBUTE_UNUSED
)
15427 tree promoted_type
, have_va_type
;
15428 tree valist
= TREE_OPERAND (*expr_p
, 0);
15429 tree type
= TREE_TYPE (*expr_p
);
15430 tree t
, tag
, aptag
;
15431 location_t loc
= EXPR_LOCATION (*expr_p
);
15433 /* Verify that valist is of the proper type. */
15434 have_va_type
= TREE_TYPE (valist
);
15435 if (have_va_type
== error_mark_node
)
15437 have_va_type
= targetm
.canonical_va_list_type (have_va_type
);
15438 if (have_va_type
== NULL_TREE
15439 && POINTER_TYPE_P (TREE_TYPE (valist
)))
15440 /* Handle 'Case 1: Not an array type' from c-common.c/build_va_arg. */
15442 = targetm
.canonical_va_list_type (TREE_TYPE (TREE_TYPE (valist
)));
15443 gcc_assert (have_va_type
!= NULL_TREE
);
15445 /* Generate a diagnostic for requesting data of a type that cannot
15446 be passed through `...' due to type promotion at the call site. */
15447 if ((promoted_type
= lang_hooks
.types
.type_promotes_to (type
))
15450 static bool gave_help
;
15452 /* Use the expansion point to handle cases such as passing bool (defined
15453 in a system header) through `...'. */
15455 = expansion_point_location_if_in_system_header (loc
);
15457 /* Unfortunately, this is merely undefined, rather than a constraint
15458 violation, so we cannot make this an error. If this call is never
15459 executed, the program is still strictly conforming. */
15460 auto_diagnostic_group d
;
15461 warned
= warning_at (xloc
, 0,
15462 "%qT is promoted to %qT when passed through %<...%>",
15463 type
, promoted_type
);
15464 if (!gave_help
&& warned
)
15467 inform (xloc
, "(so you should pass %qT not %qT to %<va_arg%>)",
15468 promoted_type
, type
);
15471 /* We can, however, treat "undefined" any way we please.
15472 Call abort to encourage the user to fix the program. */
15474 inform (xloc
, "if this code is reached, the program will abort");
15475 /* Before the abort, allow the evaluation of the va_list
15476 expression to exit or longjmp. */
15477 gimplify_and_add (valist
, pre_p
);
15478 t
= build_call_expr_loc (loc
,
15479 builtin_decl_implicit (BUILT_IN_TRAP
), 0);
15480 gimplify_and_add (t
, pre_p
);
15482 /* This is dead code, but go ahead and finish so that the
15483 mode of the result comes out right. */
15484 *expr_p
= dummy_object (type
);
15485 return GS_ALL_DONE
;
15488 tag
= build_int_cst (build_pointer_type (type
), 0);
15489 aptag
= build_int_cst (TREE_TYPE (valist
), 0);
15491 *expr_p
= build_call_expr_internal_loc (loc
, IFN_VA_ARG
, type
, 3,
15492 valist
, tag
, aptag
);
15494 /* Clear the tentatively set PROP_gimple_lva, to indicate that IFN_VA_ARG
15495 needs to be expanded. */
15496 cfun
->curr_properties
&= ~PROP_gimple_lva
;
15501 /* Build a new GIMPLE_ASSIGN tuple and append it to the end of *SEQ_P.
15503 DST/SRC are the destination and source respectively. You can pass
15504 ungimplified trees in DST or SRC, in which case they will be
15505 converted to a gimple operand if necessary.
15507 This function returns the newly created GIMPLE_ASSIGN tuple. */
15510 gimplify_assign (tree dst
, tree src
, gimple_seq
*seq_p
)
15512 tree t
= build2 (MODIFY_EXPR
, TREE_TYPE (dst
), dst
, src
);
15513 gimplify_and_add (t
, seq_p
);
15515 return gimple_seq_last_stmt (*seq_p
);
15519 gimplify_hasher::hash (const elt_t
*p
)
15522 return iterative_hash_expr (t
, 0);
15526 gimplify_hasher::equal (const elt_t
*p1
, const elt_t
*p2
)
15530 enum tree_code code
= TREE_CODE (t1
);
15532 if (TREE_CODE (t2
) != code
15533 || TREE_TYPE (t1
) != TREE_TYPE (t2
))
15536 if (!operand_equal_p (t1
, t2
, 0))
15539 /* Only allow them to compare equal if they also hash equal; otherwise
15540 results are nondeterminate, and we fail bootstrap comparison. */
15541 gcc_checking_assert (hash (p1
) == hash (p2
));