1 /* Tree lowering pass. This pass converts the GENERIC functions-as-trees
2 tree representation into the GIMPLE form.
3 Copyright (C) 2002-2021 Free Software Foundation, Inc.
4 Major work done by Sebastian Pop <s.pop@laposte.net>,
5 Diego Novillo <dnovillo@redhat.com> and Jason Merrill <jason@redhat.com>.
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
25 #include "coretypes.h"
33 #include "gimple-predict.h"
34 #include "tree-pass.h" /* FIXME: only for PROP_gimple_any */
37 #include "tree-pretty-print.h"
38 #include "diagnostic-core.h"
40 #include "fold-const.h"
45 #include "gimple-fold.h"
48 #include "gimple-iterator.h"
49 #include "stor-layout.h"
50 #include "print-tree.h"
51 #include "tree-iterator.h"
52 #include "tree-inline.h"
53 #include "langhooks.h"
56 #include "omp-general.h"
58 #include "gimple-low.h"
59 #include "gomp-constants.h"
60 #include "splay-tree.h"
61 #include "gimple-walk.h"
62 #include "langhooks-def.h" /* FIXME: for lhd_set_decl_assembler_name */
64 #include "stringpool.h"
68 #include "omp-offload.h"
70 #include "tree-nested.h"
72 /* Hash set of poisoned variables in a bind expr. */
73 static hash_set
<tree
> *asan_poisoned_variables
= NULL
;
75 enum gimplify_omp_var_data
78 GOVD_EXPLICIT
= 0x000002,
79 GOVD_SHARED
= 0x000004,
80 GOVD_PRIVATE
= 0x000008,
81 GOVD_FIRSTPRIVATE
= 0x000010,
82 GOVD_LASTPRIVATE
= 0x000020,
83 GOVD_REDUCTION
= 0x000040,
86 GOVD_DEBUG_PRIVATE
= 0x000200,
87 GOVD_PRIVATE_OUTER_REF
= 0x000400,
88 GOVD_LINEAR
= 0x000800,
89 GOVD_ALIGNED
= 0x001000,
91 /* Flag for GOVD_MAP: don't copy back. */
92 GOVD_MAP_TO_ONLY
= 0x002000,
94 /* Flag for GOVD_LINEAR or GOVD_LASTPRIVATE: no outer reference. */
95 GOVD_LINEAR_LASTPRIVATE_NO_OUTER
= 0x004000,
97 GOVD_MAP_0LEN_ARRAY
= 0x008000,
99 /* Flag for GOVD_MAP, if it is always, to or always, tofrom mapping. */
100 GOVD_MAP_ALWAYS_TO
= 0x010000,
102 /* Flag for shared vars that are or might be stored to in the region. */
103 GOVD_WRITTEN
= 0x020000,
105 /* Flag for GOVD_MAP, if it is a forced mapping. */
106 GOVD_MAP_FORCE
= 0x040000,
108 /* Flag for GOVD_MAP: must be present already. */
109 GOVD_MAP_FORCE_PRESENT
= 0x080000,
111 /* Flag for GOVD_MAP: only allocate. */
112 GOVD_MAP_ALLOC_ONLY
= 0x100000,
114 /* Flag for GOVD_MAP: only copy back. */
115 GOVD_MAP_FROM_ONLY
= 0x200000,
117 GOVD_NONTEMPORAL
= 0x400000,
119 /* Flag for GOVD_LASTPRIVATE: conditional modifier. */
120 GOVD_LASTPRIVATE_CONDITIONAL
= 0x800000,
122 GOVD_CONDTEMP
= 0x1000000,
124 /* Flag for GOVD_REDUCTION: inscan seen in {in,ex}clusive clause. */
125 GOVD_REDUCTION_INSCAN
= 0x2000000,
127 /* Flag for GOVD_MAP: (struct) vars that have pointer attachments for
129 GOVD_MAP_HAS_ATTACHMENTS
= 0x4000000,
131 /* Flag for GOVD_FIRSTPRIVATE: OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT. */
132 GOVD_FIRSTPRIVATE_IMPLICIT
= 0x8000000,
134 GOVD_DATA_SHARE_CLASS
= (GOVD_SHARED
| GOVD_PRIVATE
| GOVD_FIRSTPRIVATE
135 | GOVD_LASTPRIVATE
| GOVD_REDUCTION
| GOVD_LINEAR
142 ORT_WORKSHARE
= 0x00,
143 ORT_TASKGROUP
= 0x01,
147 ORT_COMBINED_PARALLEL
= ORT_PARALLEL
| 1,
150 ORT_UNTIED_TASK
= ORT_TASK
| 1,
151 ORT_TASKLOOP
= ORT_TASK
| 2,
152 ORT_UNTIED_TASKLOOP
= ORT_UNTIED_TASK
| 2,
155 ORT_COMBINED_TEAMS
= ORT_TEAMS
| 1,
156 ORT_HOST_TEAMS
= ORT_TEAMS
| 2,
157 ORT_COMBINED_HOST_TEAMS
= ORT_COMBINED_TEAMS
| 2,
160 ORT_TARGET_DATA
= 0x40,
162 /* Data region with offloading. */
164 ORT_COMBINED_TARGET
= ORT_TARGET
| 1,
165 ORT_IMPLICIT_TARGET
= ORT_TARGET
| 2,
167 /* OpenACC variants. */
168 ORT_ACC
= 0x100, /* A generic OpenACC region. */
169 ORT_ACC_DATA
= ORT_ACC
| ORT_TARGET_DATA
, /* Data construct. */
170 ORT_ACC_PARALLEL
= ORT_ACC
| ORT_TARGET
, /* Parallel construct */
171 ORT_ACC_KERNELS
= ORT_ACC
| ORT_TARGET
| 2, /* Kernels construct. */
172 ORT_ACC_SERIAL
= ORT_ACC
| ORT_TARGET
| 4, /* Serial construct. */
173 ORT_ACC_HOST_DATA
= ORT_ACC
| ORT_TARGET_DATA
| 2, /* Host data. */
175 /* Dummy OpenMP region, used to disable expansion of
176 DECL_VALUE_EXPRs in taskloop pre body. */
180 /* Gimplify hashtable helper. */
182 struct gimplify_hasher
: free_ptr_hash
<elt_t
>
184 static inline hashval_t
hash (const elt_t
*);
185 static inline bool equal (const elt_t
*, const elt_t
*);
190 struct gimplify_ctx
*prev_context
;
192 vec
<gbind
*> bind_expr_stack
;
194 gimple_seq conditional_cleanups
;
198 vec
<tree
> case_labels
;
199 hash_set
<tree
> *live_switch_vars
;
200 /* The formal temporary table. Should this be persistent? */
201 hash_table
<gimplify_hasher
> *temp_htab
;
204 unsigned into_ssa
: 1;
205 unsigned allow_rhs_cond_expr
: 1;
206 unsigned in_cleanup_point_expr
: 1;
207 unsigned keep_stack
: 1;
208 unsigned save_stack
: 1;
209 unsigned in_switch_expr
: 1;
212 enum gimplify_defaultmap_kind
215 GDMK_SCALAR_TARGET
, /* w/ Fortran's target attr, implicit mapping, only. */
221 struct gimplify_omp_ctx
223 struct gimplify_omp_ctx
*outer_context
;
224 splay_tree variables
;
225 hash_set
<tree
> *privatized_types
;
227 /* Iteration variables in an OMP_FOR. */
228 vec
<tree
> loop_iter_var
;
230 enum omp_clause_default_kind default_kind
;
231 enum omp_region_type region_type
;
235 bool target_firstprivatize_array_bases
;
237 bool order_concurrent
;
243 static struct gimplify_ctx
*gimplify_ctxp
;
244 static struct gimplify_omp_ctx
*gimplify_omp_ctxp
;
245 static bool in_omp_construct
;
247 /* Forward declaration. */
248 static enum gimplify_status
gimplify_compound_expr (tree
*, gimple_seq
*, bool);
249 static hash_map
<tree
, tree
> *oacc_declare_returns
;
250 static enum gimplify_status
gimplify_expr (tree
*, gimple_seq
*, gimple_seq
*,
251 bool (*) (tree
), fallback_t
, bool);
253 /* Shorter alias name for the above function for use in gimplify.c
257 gimplify_seq_add_stmt (gimple_seq
*seq_p
, gimple
*gs
)
259 gimple_seq_add_stmt_without_update (seq_p
, gs
);
262 /* Append sequence SRC to the end of sequence *DST_P. If *DST_P is
263 NULL, a new sequence is allocated. This function is
264 similar to gimple_seq_add_seq, but does not scan the operands.
265 During gimplification, we need to manipulate statement sequences
266 before the def/use vectors have been constructed. */
269 gimplify_seq_add_seq (gimple_seq
*dst_p
, gimple_seq src
)
271 gimple_stmt_iterator si
;
276 si
= gsi_last (*dst_p
);
277 gsi_insert_seq_after_without_update (&si
, src
, GSI_NEW_STMT
);
281 /* Pointer to a list of allocated gimplify_ctx structs to be used for pushing
282 and popping gimplify contexts. */
284 static struct gimplify_ctx
*ctx_pool
= NULL
;
286 /* Return a gimplify context struct from the pool. */
288 static inline struct gimplify_ctx
*
291 struct gimplify_ctx
* c
= ctx_pool
;
294 ctx_pool
= c
->prev_context
;
296 c
= XNEW (struct gimplify_ctx
);
298 memset (c
, '\0', sizeof (*c
));
302 /* Put gimplify context C back into the pool. */
305 ctx_free (struct gimplify_ctx
*c
)
307 c
->prev_context
= ctx_pool
;
311 /* Free allocated ctx stack memory. */
314 free_gimplify_stack (void)
316 struct gimplify_ctx
*c
;
318 while ((c
= ctx_pool
))
320 ctx_pool
= c
->prev_context
;
326 /* Set up a context for the gimplifier. */
329 push_gimplify_context (bool in_ssa
, bool rhs_cond_ok
)
331 struct gimplify_ctx
*c
= ctx_alloc ();
333 c
->prev_context
= gimplify_ctxp
;
335 gimplify_ctxp
->into_ssa
= in_ssa
;
336 gimplify_ctxp
->allow_rhs_cond_expr
= rhs_cond_ok
;
339 /* Tear down a context for the gimplifier. If BODY is non-null, then
340 put the temporaries into the outer BIND_EXPR. Otherwise, put them
343 BODY is not a sequence, but the first tuple in a sequence. */
346 pop_gimplify_context (gimple
*body
)
348 struct gimplify_ctx
*c
= gimplify_ctxp
;
351 && (!c
->bind_expr_stack
.exists ()
352 || c
->bind_expr_stack
.is_empty ()));
353 c
->bind_expr_stack
.release ();
354 gimplify_ctxp
= c
->prev_context
;
357 declare_vars (c
->temps
, body
, false);
359 record_vars (c
->temps
);
366 /* Push a GIMPLE_BIND tuple onto the stack of bindings. */
369 gimple_push_bind_expr (gbind
*bind_stmt
)
371 gimplify_ctxp
->bind_expr_stack
.reserve (8);
372 gimplify_ctxp
->bind_expr_stack
.safe_push (bind_stmt
);
375 /* Pop the first element off the stack of bindings. */
378 gimple_pop_bind_expr (void)
380 gimplify_ctxp
->bind_expr_stack
.pop ();
383 /* Return the first element of the stack of bindings. */
386 gimple_current_bind_expr (void)
388 return gimplify_ctxp
->bind_expr_stack
.last ();
391 /* Return the stack of bindings created during gimplification. */
394 gimple_bind_expr_stack (void)
396 return gimplify_ctxp
->bind_expr_stack
;
399 /* Return true iff there is a COND_EXPR between us and the innermost
400 CLEANUP_POINT_EXPR. This info is used by gimple_push_cleanup. */
403 gimple_conditional_context (void)
405 return gimplify_ctxp
->conditions
> 0;
408 /* Note that we've entered a COND_EXPR. */
411 gimple_push_condition (void)
413 #ifdef ENABLE_GIMPLE_CHECKING
414 if (gimplify_ctxp
->conditions
== 0)
415 gcc_assert (gimple_seq_empty_p (gimplify_ctxp
->conditional_cleanups
));
417 ++(gimplify_ctxp
->conditions
);
420 /* Note that we've left a COND_EXPR. If we're back at unconditional scope
421 now, add any conditional cleanups we've seen to the prequeue. */
424 gimple_pop_condition (gimple_seq
*pre_p
)
426 int conds
= --(gimplify_ctxp
->conditions
);
428 gcc_assert (conds
>= 0);
431 gimplify_seq_add_seq (pre_p
, gimplify_ctxp
->conditional_cleanups
);
432 gimplify_ctxp
->conditional_cleanups
= NULL
;
436 /* A stable comparison routine for use with splay trees and DECLs. */
439 splay_tree_compare_decl_uid (splay_tree_key xa
, splay_tree_key xb
)
444 return DECL_UID (a
) - DECL_UID (b
);
447 /* Create a new omp construct that deals with variable remapping. */
449 static struct gimplify_omp_ctx
*
450 new_omp_context (enum omp_region_type region_type
)
452 struct gimplify_omp_ctx
*c
;
454 c
= XCNEW (struct gimplify_omp_ctx
);
455 c
->outer_context
= gimplify_omp_ctxp
;
456 c
->variables
= splay_tree_new (splay_tree_compare_decl_uid
, 0, 0);
457 c
->privatized_types
= new hash_set
<tree
>;
458 c
->location
= input_location
;
459 c
->region_type
= region_type
;
460 if ((region_type
& ORT_TASK
) == 0)
461 c
->default_kind
= OMP_CLAUSE_DEFAULT_SHARED
;
463 c
->default_kind
= OMP_CLAUSE_DEFAULT_UNSPECIFIED
;
464 c
->defaultmap
[GDMK_SCALAR
] = GOVD_MAP
;
465 c
->defaultmap
[GDMK_SCALAR_TARGET
] = GOVD_MAP
;
466 c
->defaultmap
[GDMK_AGGREGATE
] = GOVD_MAP
;
467 c
->defaultmap
[GDMK_ALLOCATABLE
] = GOVD_MAP
;
468 c
->defaultmap
[GDMK_POINTER
] = GOVD_MAP
;
473 /* Destroy an omp construct that deals with variable remapping. */
476 delete_omp_context (struct gimplify_omp_ctx
*c
)
478 splay_tree_delete (c
->variables
);
479 delete c
->privatized_types
;
480 c
->loop_iter_var
.release ();
484 static void omp_add_variable (struct gimplify_omp_ctx
*, tree
, unsigned int);
485 static bool omp_notice_variable (struct gimplify_omp_ctx
*, tree
, bool);
487 /* Both gimplify the statement T and append it to *SEQ_P. This function
488 behaves exactly as gimplify_stmt, but you don't have to pass T as a
492 gimplify_and_add (tree t
, gimple_seq
*seq_p
)
494 gimplify_stmt (&t
, seq_p
);
497 /* Gimplify statement T into sequence *SEQ_P, and return the first
498 tuple in the sequence of generated tuples for this statement.
499 Return NULL if gimplifying T produced no tuples. */
502 gimplify_and_return_first (tree t
, gimple_seq
*seq_p
)
504 gimple_stmt_iterator last
= gsi_last (*seq_p
);
506 gimplify_and_add (t
, seq_p
);
508 if (!gsi_end_p (last
))
511 return gsi_stmt (last
);
514 return gimple_seq_first_stmt (*seq_p
);
517 /* Returns true iff T is a valid RHS for an assignment to an un-renamed
518 LHS, or for a call argument. */
521 is_gimple_mem_rhs (tree t
)
523 /* If we're dealing with a renamable type, either source or dest must be
524 a renamed variable. */
525 if (is_gimple_reg_type (TREE_TYPE (t
)))
526 return is_gimple_val (t
);
528 return is_gimple_val (t
) || is_gimple_lvalue (t
);
531 /* Return true if T is a CALL_EXPR or an expression that can be
532 assigned to a temporary. Note that this predicate should only be
533 used during gimplification. See the rationale for this in
534 gimplify_modify_expr. */
537 is_gimple_reg_rhs_or_call (tree t
)
539 return (get_gimple_rhs_class (TREE_CODE (t
)) != GIMPLE_INVALID_RHS
540 || TREE_CODE (t
) == CALL_EXPR
);
543 /* Return true if T is a valid memory RHS or a CALL_EXPR. Note that
544 this predicate should only be used during gimplification. See the
545 rationale for this in gimplify_modify_expr. */
548 is_gimple_mem_rhs_or_call (tree t
)
550 /* If we're dealing with a renamable type, either source or dest must be
551 a renamed variable. */
552 if (is_gimple_reg_type (TREE_TYPE (t
)))
553 return is_gimple_val (t
);
555 return (is_gimple_val (t
)
556 || is_gimple_lvalue (t
)
557 || TREE_CLOBBER_P (t
)
558 || TREE_CODE (t
) == CALL_EXPR
);
561 /* Create a temporary with a name derived from VAL. Subroutine of
562 lookup_tmp_var; nobody else should call this function. */
565 create_tmp_from_val (tree val
)
567 /* Drop all qualifiers and address-space information from the value type. */
568 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (val
));
569 tree var
= create_tmp_var (type
, get_name (val
));
573 /* Create a temporary to hold the value of VAL. If IS_FORMAL, try to reuse
574 an existing expression temporary. */
577 lookup_tmp_var (tree val
, bool is_formal
)
581 /* If not optimizing, never really reuse a temporary. local-alloc
582 won't allocate any variable that is used in more than one basic
583 block, which means it will go into memory, causing much extra
584 work in reload and final and poorer code generation, outweighing
585 the extra memory allocation here. */
586 if (!optimize
|| !is_formal
|| TREE_SIDE_EFFECTS (val
))
587 ret
= create_tmp_from_val (val
);
594 if (!gimplify_ctxp
->temp_htab
)
595 gimplify_ctxp
->temp_htab
= new hash_table
<gimplify_hasher
> (1000);
596 slot
= gimplify_ctxp
->temp_htab
->find_slot (&elt
, INSERT
);
599 elt_p
= XNEW (elt_t
);
601 elt_p
->temp
= ret
= create_tmp_from_val (val
);
614 /* Helper for get_formal_tmp_var and get_initialized_tmp_var. */
617 internal_get_tmp_var (tree val
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
618 bool is_formal
, bool allow_ssa
)
622 /* Notice that we explicitly allow VAL to be a CALL_EXPR so that we
623 can create an INIT_EXPR and convert it into a GIMPLE_CALL below. */
624 gimplify_expr (&val
, pre_p
, post_p
, is_gimple_reg_rhs_or_call
,
628 && gimplify_ctxp
->into_ssa
629 && is_gimple_reg_type (TREE_TYPE (val
)))
631 t
= make_ssa_name (TYPE_MAIN_VARIANT (TREE_TYPE (val
)));
632 if (! gimple_in_ssa_p (cfun
))
634 const char *name
= get_name (val
);
636 SET_SSA_NAME_VAR_OR_IDENTIFIER (t
, create_tmp_var_name (name
));
640 t
= lookup_tmp_var (val
, is_formal
);
642 mod
= build2 (INIT_EXPR
, TREE_TYPE (t
), t
, unshare_expr (val
));
644 SET_EXPR_LOCATION (mod
, EXPR_LOC_OR_LOC (val
, input_location
));
646 /* gimplify_modify_expr might want to reduce this further. */
647 gimplify_and_add (mod
, pre_p
);
653 /* Return a formal temporary variable initialized with VAL. PRE_P is as
654 in gimplify_expr. Only use this function if:
656 1) The value of the unfactored expression represented by VAL will not
657 change between the initialization and use of the temporary, and
658 2) The temporary will not be otherwise modified.
660 For instance, #1 means that this is inappropriate for SAVE_EXPR temps,
661 and #2 means it is inappropriate for && temps.
663 For other cases, use get_initialized_tmp_var instead. */
666 get_formal_tmp_var (tree val
, gimple_seq
*pre_p
)
668 return internal_get_tmp_var (val
, pre_p
, NULL
, true, true);
671 /* Return a temporary variable initialized with VAL. PRE_P and POST_P
672 are as in gimplify_expr. */
675 get_initialized_tmp_var (tree val
, gimple_seq
*pre_p
,
676 gimple_seq
*post_p
/* = NULL */,
677 bool allow_ssa
/* = true */)
679 return internal_get_tmp_var (val
, pre_p
, post_p
, false, allow_ssa
);
682 /* Declare all the variables in VARS in SCOPE. If DEBUG_INFO is true,
683 generate debug info for them; otherwise don't. */
686 declare_vars (tree vars
, gimple
*gs
, bool debug_info
)
693 gbind
*scope
= as_a
<gbind
*> (gs
);
695 temps
= nreverse (last
);
697 block
= gimple_bind_block (scope
);
698 gcc_assert (!block
|| TREE_CODE (block
) == BLOCK
);
699 if (!block
|| !debug_info
)
701 DECL_CHAIN (last
) = gimple_bind_vars (scope
);
702 gimple_bind_set_vars (scope
, temps
);
706 /* We need to attach the nodes both to the BIND_EXPR and to its
707 associated BLOCK for debugging purposes. The key point here
708 is that the BLOCK_VARS of the BIND_EXPR_BLOCK of a BIND_EXPR
709 is a subchain of the BIND_EXPR_VARS of the BIND_EXPR. */
710 if (BLOCK_VARS (block
))
711 BLOCK_VARS (block
) = chainon (BLOCK_VARS (block
), temps
);
714 gimple_bind_set_vars (scope
,
715 chainon (gimple_bind_vars (scope
), temps
));
716 BLOCK_VARS (block
) = temps
;
722 /* For VAR a VAR_DECL of variable size, try to find a constant upper bound
723 for the size and adjust DECL_SIZE/DECL_SIZE_UNIT accordingly. Abort if
724 no such upper bound can be obtained. */
727 force_constant_size (tree var
)
729 /* The only attempt we make is by querying the maximum size of objects
730 of the variable's type. */
732 HOST_WIDE_INT max_size
;
734 gcc_assert (VAR_P (var
));
736 max_size
= max_int_size_in_bytes (TREE_TYPE (var
));
738 gcc_assert (max_size
>= 0);
741 = build_int_cst (TREE_TYPE (DECL_SIZE_UNIT (var
)), max_size
);
743 = build_int_cst (TREE_TYPE (DECL_SIZE (var
)), max_size
* BITS_PER_UNIT
);
746 /* Push the temporary variable TMP into the current binding. */
749 gimple_add_tmp_var_fn (struct function
*fn
, tree tmp
)
751 gcc_assert (!DECL_CHAIN (tmp
) && !DECL_SEEN_IN_BIND_EXPR_P (tmp
));
753 /* Later processing assumes that the object size is constant, which might
754 not be true at this point. Force the use of a constant upper bound in
756 if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp
)))
757 force_constant_size (tmp
);
759 DECL_CONTEXT (tmp
) = fn
->decl
;
760 DECL_SEEN_IN_BIND_EXPR_P (tmp
) = 1;
762 record_vars_into (tmp
, fn
->decl
);
765 /* Push the temporary variable TMP into the current binding. */
768 gimple_add_tmp_var (tree tmp
)
770 gcc_assert (!DECL_CHAIN (tmp
) && !DECL_SEEN_IN_BIND_EXPR_P (tmp
));
772 /* Later processing assumes that the object size is constant, which might
773 not be true at this point. Force the use of a constant upper bound in
775 if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp
)))
776 force_constant_size (tmp
);
778 DECL_CONTEXT (tmp
) = current_function_decl
;
779 DECL_SEEN_IN_BIND_EXPR_P (tmp
) = 1;
783 DECL_CHAIN (tmp
) = gimplify_ctxp
->temps
;
784 gimplify_ctxp
->temps
= tmp
;
786 /* Mark temporaries local within the nearest enclosing parallel. */
787 if (gimplify_omp_ctxp
)
789 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
790 int flag
= GOVD_LOCAL
| GOVD_SEEN
;
792 && (ctx
->region_type
== ORT_WORKSHARE
793 || ctx
->region_type
== ORT_TASKGROUP
794 || ctx
->region_type
== ORT_SIMD
795 || ctx
->region_type
== ORT_ACC
))
797 if (ctx
->region_type
== ORT_SIMD
798 && TREE_ADDRESSABLE (tmp
)
799 && !TREE_STATIC (tmp
))
801 if (TREE_CODE (DECL_SIZE_UNIT (tmp
)) != INTEGER_CST
)
802 ctx
->add_safelen1
= true;
803 else if (ctx
->in_for_exprs
)
806 flag
= GOVD_PRIVATE
| GOVD_SEEN
;
809 ctx
= ctx
->outer_context
;
812 omp_add_variable (ctx
, tmp
, flag
);
821 /* This case is for nested functions. We need to expose the locals
823 body_seq
= gimple_body (current_function_decl
);
824 declare_vars (tmp
, gimple_seq_first_stmt (body_seq
), false);
830 /* This page contains routines to unshare tree nodes, i.e. to duplicate tree
831 nodes that are referenced more than once in GENERIC functions. This is
832 necessary because gimplification (translation into GIMPLE) is performed
833 by modifying tree nodes in-place, so gimplication of a shared node in a
834 first context could generate an invalid GIMPLE form in a second context.
836 This is achieved with a simple mark/copy/unmark algorithm that walks the
837 GENERIC representation top-down, marks nodes with TREE_VISITED the first
838 time it encounters them, duplicates them if they already have TREE_VISITED
839 set, and finally removes the TREE_VISITED marks it has set.
841 The algorithm works only at the function level, i.e. it generates a GENERIC
842 representation of a function with no nodes shared within the function when
843 passed a GENERIC function (except for nodes that are allowed to be shared).
845 At the global level, it is also necessary to unshare tree nodes that are
846 referenced in more than one function, for the same aforementioned reason.
847 This requires some cooperation from the front-end. There are 2 strategies:
849 1. Manual unsharing. The front-end needs to call unshare_expr on every
850 expression that might end up being shared across functions.
852 2. Deep unsharing. This is an extension of regular unsharing. Instead
853 of calling unshare_expr on expressions that might be shared across
854 functions, the front-end pre-marks them with TREE_VISITED. This will
855 ensure that they are unshared on the first reference within functions
856 when the regular unsharing algorithm runs. The counterpart is that
857 this algorithm must look deeper than for manual unsharing, which is
858 specified by LANG_HOOKS_DEEP_UNSHARING.
860 If there are only few specific cases of node sharing across functions, it is
861 probably easier for a front-end to unshare the expressions manually. On the
862 contrary, if the expressions generated at the global level are as widespread
863 as expressions generated within functions, deep unsharing is very likely the
866 /* Similar to copy_tree_r but do not copy SAVE_EXPR or TARGET_EXPR nodes.
867 These nodes model computations that must be done once. If we were to
868 unshare something like SAVE_EXPR(i++), the gimplification process would
869 create wrong code. However, if DATA is non-null, it must hold a pointer
870 set that is used to unshare the subtrees of these nodes. */
873 mostly_copy_tree_r (tree
*tp
, int *walk_subtrees
, void *data
)
876 enum tree_code code
= TREE_CODE (t
);
878 /* Do not copy SAVE_EXPR, TARGET_EXPR or BIND_EXPR nodes themselves, but
879 copy their subtrees if we can make sure to do it only once. */
880 if (code
== SAVE_EXPR
|| code
== TARGET_EXPR
|| code
== BIND_EXPR
)
882 if (data
&& !((hash_set
<tree
> *)data
)->add (t
))
888 /* Stop at types, decls, constants like copy_tree_r. */
889 else if (TREE_CODE_CLASS (code
) == tcc_type
890 || TREE_CODE_CLASS (code
) == tcc_declaration
891 || TREE_CODE_CLASS (code
) == tcc_constant
)
894 /* Cope with the statement expression extension. */
895 else if (code
== STATEMENT_LIST
)
898 /* Leave the bulk of the work to copy_tree_r itself. */
900 copy_tree_r (tp
, walk_subtrees
, NULL
);
905 /* Callback for walk_tree to unshare most of the shared trees rooted at *TP.
906 If *TP has been visited already, then *TP is deeply copied by calling
907 mostly_copy_tree_r. DATA is passed to mostly_copy_tree_r unmodified. */
910 copy_if_shared_r (tree
*tp
, int *walk_subtrees
, void *data
)
913 enum tree_code code
= TREE_CODE (t
);
915 /* Skip types, decls, and constants. But we do want to look at their
916 types and the bounds of types. Mark them as visited so we properly
917 unmark their subtrees on the unmark pass. If we've already seen them,
918 don't look down further. */
919 if (TREE_CODE_CLASS (code
) == tcc_type
920 || TREE_CODE_CLASS (code
) == tcc_declaration
921 || TREE_CODE_CLASS (code
) == tcc_constant
)
923 if (TREE_VISITED (t
))
926 TREE_VISITED (t
) = 1;
929 /* If this node has been visited already, unshare it and don't look
931 else if (TREE_VISITED (t
))
933 walk_tree (tp
, mostly_copy_tree_r
, data
, NULL
);
937 /* Otherwise, mark the node as visited and keep looking. */
939 TREE_VISITED (t
) = 1;
944 /* Unshare most of the shared trees rooted at *TP. DATA is passed to the
945 copy_if_shared_r callback unmodified. */
948 copy_if_shared (tree
*tp
, void *data
)
950 walk_tree (tp
, copy_if_shared_r
, data
, NULL
);
953 /* Unshare all the trees in the body of FNDECL, as well as in the bodies of
954 any nested functions. */
957 unshare_body (tree fndecl
)
959 struct cgraph_node
*cgn
= cgraph_node::get (fndecl
);
960 /* If the language requires deep unsharing, we need a pointer set to make
961 sure we don't repeatedly unshare subtrees of unshareable nodes. */
962 hash_set
<tree
> *visited
963 = lang_hooks
.deep_unsharing
? new hash_set
<tree
> : NULL
;
965 copy_if_shared (&DECL_SAVED_TREE (fndecl
), visited
);
966 copy_if_shared (&DECL_SIZE (DECL_RESULT (fndecl
)), visited
);
967 copy_if_shared (&DECL_SIZE_UNIT (DECL_RESULT (fndecl
)), visited
);
972 for (cgn
= first_nested_function (cgn
); cgn
;
973 cgn
= next_nested_function (cgn
))
974 unshare_body (cgn
->decl
);
977 /* Callback for walk_tree to unmark the visited trees rooted at *TP.
978 Subtrees are walked until the first unvisited node is encountered. */
981 unmark_visited_r (tree
*tp
, int *walk_subtrees
, void *data ATTRIBUTE_UNUSED
)
985 /* If this node has been visited, unmark it and keep looking. */
986 if (TREE_VISITED (t
))
987 TREE_VISITED (t
) = 0;
989 /* Otherwise, don't look any deeper. */
996 /* Unmark the visited trees rooted at *TP. */
999 unmark_visited (tree
*tp
)
1001 walk_tree (tp
, unmark_visited_r
, NULL
, NULL
);
1004 /* Likewise, but mark all trees as not visited. */
1007 unvisit_body (tree fndecl
)
1009 struct cgraph_node
*cgn
= cgraph_node::get (fndecl
);
1011 unmark_visited (&DECL_SAVED_TREE (fndecl
));
1012 unmark_visited (&DECL_SIZE (DECL_RESULT (fndecl
)));
1013 unmark_visited (&DECL_SIZE_UNIT (DECL_RESULT (fndecl
)));
1016 for (cgn
= first_nested_function (cgn
);
1017 cgn
; cgn
= next_nested_function (cgn
))
1018 unvisit_body (cgn
->decl
);
1021 /* Unconditionally make an unshared copy of EXPR. This is used when using
1022 stored expressions which span multiple functions, such as BINFO_VTABLE,
1023 as the normal unsharing process can't tell that they're shared. */
1026 unshare_expr (tree expr
)
1028 walk_tree (&expr
, mostly_copy_tree_r
, NULL
, NULL
);
1032 /* Worker for unshare_expr_without_location. */
1035 prune_expr_location (tree
*tp
, int *walk_subtrees
, void *)
1038 SET_EXPR_LOCATION (*tp
, UNKNOWN_LOCATION
);
1044 /* Similar to unshare_expr but also prune all expression locations
1048 unshare_expr_without_location (tree expr
)
1050 walk_tree (&expr
, mostly_copy_tree_r
, NULL
, NULL
);
1052 walk_tree (&expr
, prune_expr_location
, NULL
, NULL
);
1056 /* Return the EXPR_LOCATION of EXPR, if it (maybe recursively) has
1057 one, OR_ELSE otherwise. The location of a STATEMENT_LISTs
1058 comprising at least one DEBUG_BEGIN_STMT followed by exactly one
1059 EXPR is the location of the EXPR. */
1062 rexpr_location (tree expr
, location_t or_else
= UNKNOWN_LOCATION
)
1067 if (EXPR_HAS_LOCATION (expr
))
1068 return EXPR_LOCATION (expr
);
1070 if (TREE_CODE (expr
) != STATEMENT_LIST
)
1073 tree_stmt_iterator i
= tsi_start (expr
);
1076 while (!tsi_end_p (i
) && TREE_CODE (tsi_stmt (i
)) == DEBUG_BEGIN_STMT
)
1082 if (!found
|| !tsi_one_before_end_p (i
))
1085 return rexpr_location (tsi_stmt (i
), or_else
);
1088 /* Return TRUE iff EXPR (maybe recursively) has a location; see
1089 rexpr_location for the potential recursion. */
1092 rexpr_has_location (tree expr
)
1094 return rexpr_location (expr
) != UNKNOWN_LOCATION
;
1098 /* WRAPPER is a code such as BIND_EXPR or CLEANUP_POINT_EXPR which can both
1099 contain statements and have a value. Assign its value to a temporary
1100 and give it void_type_node. Return the temporary, or NULL_TREE if
1101 WRAPPER was already void. */
1104 voidify_wrapper_expr (tree wrapper
, tree temp
)
1106 tree type
= TREE_TYPE (wrapper
);
1107 if (type
&& !VOID_TYPE_P (type
))
1111 /* Set p to point to the body of the wrapper. Loop until we find
1112 something that isn't a wrapper. */
1113 for (p
= &wrapper
; p
&& *p
; )
1115 switch (TREE_CODE (*p
))
1118 TREE_SIDE_EFFECTS (*p
) = 1;
1119 TREE_TYPE (*p
) = void_type_node
;
1120 /* For a BIND_EXPR, the body is operand 1. */
1121 p
= &BIND_EXPR_BODY (*p
);
1124 case CLEANUP_POINT_EXPR
:
1125 case TRY_FINALLY_EXPR
:
1126 case TRY_CATCH_EXPR
:
1127 TREE_SIDE_EFFECTS (*p
) = 1;
1128 TREE_TYPE (*p
) = void_type_node
;
1129 p
= &TREE_OPERAND (*p
, 0);
1132 case STATEMENT_LIST
:
1134 tree_stmt_iterator i
= tsi_last (*p
);
1135 TREE_SIDE_EFFECTS (*p
) = 1;
1136 TREE_TYPE (*p
) = void_type_node
;
1137 p
= tsi_end_p (i
) ? NULL
: tsi_stmt_ptr (i
);
1142 /* Advance to the last statement. Set all container types to
1144 for (; TREE_CODE (*p
) == COMPOUND_EXPR
; p
= &TREE_OPERAND (*p
, 1))
1146 TREE_SIDE_EFFECTS (*p
) = 1;
1147 TREE_TYPE (*p
) = void_type_node
;
1151 case TRANSACTION_EXPR
:
1152 TREE_SIDE_EFFECTS (*p
) = 1;
1153 TREE_TYPE (*p
) = void_type_node
;
1154 p
= &TRANSACTION_EXPR_BODY (*p
);
1158 /* Assume that any tree upon which voidify_wrapper_expr is
1159 directly called is a wrapper, and that its body is op0. */
1162 TREE_SIDE_EFFECTS (*p
) = 1;
1163 TREE_TYPE (*p
) = void_type_node
;
1164 p
= &TREE_OPERAND (*p
, 0);
1172 if (p
== NULL
|| IS_EMPTY_STMT (*p
))
1176 /* The wrapper is on the RHS of an assignment that we're pushing
1178 gcc_assert (TREE_CODE (temp
) == INIT_EXPR
1179 || TREE_CODE (temp
) == MODIFY_EXPR
);
1180 TREE_OPERAND (temp
, 1) = *p
;
1185 temp
= create_tmp_var (type
, "retval");
1186 *p
= build2 (INIT_EXPR
, type
, temp
, *p
);
1195 /* Prepare calls to builtins to SAVE and RESTORE the stack as well as
1196 a temporary through which they communicate. */
1199 build_stack_save_restore (gcall
**save
, gcall
**restore
)
1203 *save
= gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_SAVE
), 0);
1204 tmp_var
= create_tmp_var (ptr_type_node
, "saved_stack");
1205 gimple_call_set_lhs (*save
, tmp_var
);
1208 = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_RESTORE
),
1212 /* Generate IFN_ASAN_MARK call that poisons shadow of a for DECL variable. */
1215 build_asan_poison_call_expr (tree decl
)
1217 /* Do not poison variables that have size equal to zero. */
1218 tree unit_size
= DECL_SIZE_UNIT (decl
);
1219 if (zerop (unit_size
))
1222 tree base
= build_fold_addr_expr (decl
);
1224 return build_call_expr_internal_loc (UNKNOWN_LOCATION
, IFN_ASAN_MARK
,
1226 build_int_cst (integer_type_node
,
1231 /* Generate IFN_ASAN_MARK call that would poison or unpoison, depending
1232 on POISON flag, shadow memory of a DECL variable. The call will be
1233 put on location identified by IT iterator, where BEFORE flag drives
1234 position where the stmt will be put. */
1237 asan_poison_variable (tree decl
, bool poison
, gimple_stmt_iterator
*it
,
1240 tree unit_size
= DECL_SIZE_UNIT (decl
);
1241 tree base
= build_fold_addr_expr (decl
);
1243 /* Do not poison variables that have size equal to zero. */
1244 if (zerop (unit_size
))
1247 /* It's necessary to have all stack variables aligned to ASAN granularity
1249 gcc_assert (!hwasan_sanitize_p () || hwasan_sanitize_stack_p ());
1250 unsigned shadow_granularity
1251 = hwasan_sanitize_p () ? HWASAN_TAG_GRANULE_SIZE
: ASAN_SHADOW_GRANULARITY
;
1252 if (DECL_ALIGN_UNIT (decl
) <= shadow_granularity
)
1253 SET_DECL_ALIGN (decl
, BITS_PER_UNIT
* shadow_granularity
);
1255 HOST_WIDE_INT flags
= poison
? ASAN_MARK_POISON
: ASAN_MARK_UNPOISON
;
1258 = gimple_build_call_internal (IFN_ASAN_MARK
, 3,
1259 build_int_cst (integer_type_node
, flags
),
1263 gsi_insert_before (it
, g
, GSI_NEW_STMT
);
1265 gsi_insert_after (it
, g
, GSI_NEW_STMT
);
1268 /* Generate IFN_ASAN_MARK internal call that depending on POISON flag
1269 either poisons or unpoisons a DECL. Created statement is appended
1270 to SEQ_P gimple sequence. */
1273 asan_poison_variable (tree decl
, bool poison
, gimple_seq
*seq_p
)
1275 gimple_stmt_iterator it
= gsi_last (*seq_p
);
1276 bool before
= false;
1281 asan_poison_variable (decl
, poison
, &it
, before
);
1284 /* Sort pair of VAR_DECLs A and B by DECL_UID. */
1287 sort_by_decl_uid (const void *a
, const void *b
)
1289 const tree
*t1
= (const tree
*)a
;
1290 const tree
*t2
= (const tree
*)b
;
1292 int uid1
= DECL_UID (*t1
);
1293 int uid2
= DECL_UID (*t2
);
1297 else if (uid1
> uid2
)
1303 /* Generate IFN_ASAN_MARK internal call for all VARIABLES
1304 depending on POISON flag. Created statement is appended
1305 to SEQ_P gimple sequence. */
1308 asan_poison_variables (hash_set
<tree
> *variables
, bool poison
, gimple_seq
*seq_p
)
1310 unsigned c
= variables
->elements ();
1314 auto_vec
<tree
> sorted_variables (c
);
1316 for (hash_set
<tree
>::iterator it
= variables
->begin ();
1317 it
!= variables
->end (); ++it
)
1318 sorted_variables
.safe_push (*it
);
1320 sorted_variables
.qsort (sort_by_decl_uid
);
1324 FOR_EACH_VEC_ELT (sorted_variables
, i
, var
)
1326 asan_poison_variable (var
, poison
, seq_p
);
1328 /* Add use_after_scope_memory attribute for the variable in order
1329 to prevent re-written into SSA. */
1330 if (!lookup_attribute (ASAN_USE_AFTER_SCOPE_ATTRIBUTE
,
1331 DECL_ATTRIBUTES (var
)))
1332 DECL_ATTRIBUTES (var
)
1333 = tree_cons (get_identifier (ASAN_USE_AFTER_SCOPE_ATTRIBUTE
),
1335 DECL_ATTRIBUTES (var
));
1339 /* Gimplify a BIND_EXPR. Just voidify and recurse. */
1341 static enum gimplify_status
1342 gimplify_bind_expr (tree
*expr_p
, gimple_seq
*pre_p
)
1344 tree bind_expr
= *expr_p
;
1345 bool old_keep_stack
= gimplify_ctxp
->keep_stack
;
1346 bool old_save_stack
= gimplify_ctxp
->save_stack
;
1349 gimple_seq body
, cleanup
;
1351 location_t start_locus
= 0, end_locus
= 0;
1352 tree ret_clauses
= NULL
;
1354 tree temp
= voidify_wrapper_expr (bind_expr
, NULL
);
1356 /* Mark variables seen in this bind expr. */
1357 for (t
= BIND_EXPR_VARS (bind_expr
); t
; t
= DECL_CHAIN (t
))
1361 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
1363 /* Mark variable as local. */
1364 if (ctx
&& ctx
->region_type
!= ORT_NONE
&& !DECL_EXTERNAL (t
))
1366 if (! DECL_SEEN_IN_BIND_EXPR_P (t
)
1367 || splay_tree_lookup (ctx
->variables
,
1368 (splay_tree_key
) t
) == NULL
)
1370 int flag
= GOVD_LOCAL
;
1371 if (ctx
->region_type
== ORT_SIMD
1372 && TREE_ADDRESSABLE (t
)
1373 && !TREE_STATIC (t
))
1375 if (TREE_CODE (DECL_SIZE_UNIT (t
)) != INTEGER_CST
)
1376 ctx
->add_safelen1
= true;
1378 flag
= GOVD_PRIVATE
;
1380 omp_add_variable (ctx
, t
, flag
| GOVD_SEEN
);
1382 /* Static locals inside of target construct or offloaded
1383 routines need to be "omp declare target". */
1384 if (TREE_STATIC (t
))
1385 for (; ctx
; ctx
= ctx
->outer_context
)
1386 if ((ctx
->region_type
& ORT_TARGET
) != 0)
1388 if (!lookup_attribute ("omp declare target",
1389 DECL_ATTRIBUTES (t
)))
1391 tree id
= get_identifier ("omp declare target");
1393 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
1394 varpool_node
*node
= varpool_node::get (t
);
1397 node
->offloadable
= 1;
1398 if (ENABLE_OFFLOADING
&& !DECL_EXTERNAL (t
))
1400 g
->have_offload
= true;
1402 vec_safe_push (offload_vars
, t
);
1410 DECL_SEEN_IN_BIND_EXPR_P (t
) = 1;
1412 if (DECL_HARD_REGISTER (t
) && !is_global_var (t
) && cfun
)
1413 cfun
->has_local_explicit_reg_vars
= true;
1417 bind_stmt
= gimple_build_bind (BIND_EXPR_VARS (bind_expr
), NULL
,
1418 BIND_EXPR_BLOCK (bind_expr
));
1419 gimple_push_bind_expr (bind_stmt
);
1421 gimplify_ctxp
->keep_stack
= false;
1422 gimplify_ctxp
->save_stack
= false;
1424 /* Gimplify the body into the GIMPLE_BIND tuple's body. */
1426 gimplify_stmt (&BIND_EXPR_BODY (bind_expr
), &body
);
1427 gimple_bind_set_body (bind_stmt
, body
);
1429 /* Source location wise, the cleanup code (stack_restore and clobbers)
1430 belongs to the end of the block, so propagate what we have. The
1431 stack_save operation belongs to the beginning of block, which we can
1432 infer from the bind_expr directly if the block has no explicit
1434 if (BIND_EXPR_BLOCK (bind_expr
))
1436 end_locus
= BLOCK_SOURCE_END_LOCATION (BIND_EXPR_BLOCK (bind_expr
));
1437 start_locus
= BLOCK_SOURCE_LOCATION (BIND_EXPR_BLOCK (bind_expr
));
1439 if (start_locus
== 0)
1440 start_locus
= EXPR_LOCATION (bind_expr
);
1445 /* If the code both contains VLAs and calls alloca, then we cannot reclaim
1446 the stack space allocated to the VLAs. */
1447 if (gimplify_ctxp
->save_stack
&& !gimplify_ctxp
->keep_stack
)
1449 gcall
*stack_restore
;
1451 /* Save stack on entry and restore it on exit. Add a try_finally
1452 block to achieve this. */
1453 build_stack_save_restore (&stack_save
, &stack_restore
);
1455 gimple_set_location (stack_save
, start_locus
);
1456 gimple_set_location (stack_restore
, end_locus
);
1458 gimplify_seq_add_stmt (&cleanup
, stack_restore
);
1461 /* Add clobbers for all variables that go out of scope. */
1462 for (t
= BIND_EXPR_VARS (bind_expr
); t
; t
= DECL_CHAIN (t
))
1465 && !is_global_var (t
)
1466 && DECL_CONTEXT (t
) == current_function_decl
)
1468 if (!DECL_HARD_REGISTER (t
)
1469 && !TREE_THIS_VOLATILE (t
)
1470 && !DECL_HAS_VALUE_EXPR_P (t
)
1471 /* Only care for variables that have to be in memory. Others
1472 will be rewritten into SSA names, hence moved to the
1474 && !is_gimple_reg (t
)
1475 && flag_stack_reuse
!= SR_NONE
)
1477 tree clobber
= build_clobber (TREE_TYPE (t
));
1478 gimple
*clobber_stmt
;
1479 clobber_stmt
= gimple_build_assign (t
, clobber
);
1480 gimple_set_location (clobber_stmt
, end_locus
);
1481 gimplify_seq_add_stmt (&cleanup
, clobber_stmt
);
1484 if (flag_openacc
&& oacc_declare_returns
!= NULL
)
1487 if (DECL_HAS_VALUE_EXPR_P (key
))
1489 key
= DECL_VALUE_EXPR (key
);
1490 if (TREE_CODE (key
) == INDIRECT_REF
)
1491 key
= TREE_OPERAND (key
, 0);
1493 tree
*c
= oacc_declare_returns
->get (key
);
1497 OMP_CLAUSE_CHAIN (*c
) = ret_clauses
;
1499 ret_clauses
= unshare_expr (*c
);
1501 oacc_declare_returns
->remove (key
);
1503 if (oacc_declare_returns
->is_empty ())
1505 delete oacc_declare_returns
;
1506 oacc_declare_returns
= NULL
;
1512 if (asan_poisoned_variables
!= NULL
1513 && asan_poisoned_variables
->contains (t
))
1515 asan_poisoned_variables
->remove (t
);
1516 asan_poison_variable (t
, true, &cleanup
);
1519 if (gimplify_ctxp
->live_switch_vars
!= NULL
1520 && gimplify_ctxp
->live_switch_vars
->contains (t
))
1521 gimplify_ctxp
->live_switch_vars
->remove (t
);
1527 gimple_stmt_iterator si
= gsi_start (cleanup
);
1529 stmt
= gimple_build_omp_target (NULL
, GF_OMP_TARGET_KIND_OACC_DECLARE
,
1531 gsi_insert_seq_before_without_update (&si
, stmt
, GSI_NEW_STMT
);
1537 gimple_seq new_body
;
1540 gs
= gimple_build_try (gimple_bind_body (bind_stmt
), cleanup
,
1541 GIMPLE_TRY_FINALLY
);
1544 gimplify_seq_add_stmt (&new_body
, stack_save
);
1545 gimplify_seq_add_stmt (&new_body
, gs
);
1546 gimple_bind_set_body (bind_stmt
, new_body
);
1549 /* keep_stack propagates all the way up to the outermost BIND_EXPR. */
1550 if (!gimplify_ctxp
->keep_stack
)
1551 gimplify_ctxp
->keep_stack
= old_keep_stack
;
1552 gimplify_ctxp
->save_stack
= old_save_stack
;
1554 gimple_pop_bind_expr ();
1556 gimplify_seq_add_stmt (pre_p
, bind_stmt
);
1564 *expr_p
= NULL_TREE
;
1568 /* Maybe add early return predict statement to PRE_P sequence. */
1571 maybe_add_early_return_predict_stmt (gimple_seq
*pre_p
)
1573 /* If we are not in a conditional context, add PREDICT statement. */
1574 if (gimple_conditional_context ())
1576 gimple
*predict
= gimple_build_predict (PRED_TREE_EARLY_RETURN
,
1578 gimplify_seq_add_stmt (pre_p
, predict
);
1582 /* Gimplify a RETURN_EXPR. If the expression to be returned is not a
1583 GIMPLE value, it is assigned to a new temporary and the statement is
1584 re-written to return the temporary.
1586 PRE_P points to the sequence where side effects that must happen before
1587 STMT should be stored. */
1589 static enum gimplify_status
1590 gimplify_return_expr (tree stmt
, gimple_seq
*pre_p
)
1593 tree ret_expr
= TREE_OPERAND (stmt
, 0);
1594 tree result_decl
, result
;
1596 if (ret_expr
== error_mark_node
)
1600 || TREE_CODE (ret_expr
) == RESULT_DECL
)
1602 maybe_add_early_return_predict_stmt (pre_p
);
1603 greturn
*ret
= gimple_build_return (ret_expr
);
1604 copy_warning (ret
, stmt
);
1605 gimplify_seq_add_stmt (pre_p
, ret
);
1609 if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl
))))
1610 result_decl
= NULL_TREE
;
1611 else if (TREE_CODE (ret_expr
) == COMPOUND_EXPR
)
1613 /* Used in C++ for handling EH cleanup of the return value if a local
1614 cleanup throws. Assume the front-end knows what it's doing. */
1615 result_decl
= DECL_RESULT (current_function_decl
);
1616 /* But crash if we end up trying to modify ret_expr below. */
1617 ret_expr
= NULL_TREE
;
1621 result_decl
= TREE_OPERAND (ret_expr
, 0);
1623 /* See through a return by reference. */
1624 if (TREE_CODE (result_decl
) == INDIRECT_REF
)
1625 result_decl
= TREE_OPERAND (result_decl
, 0);
1627 gcc_assert ((TREE_CODE (ret_expr
) == MODIFY_EXPR
1628 || TREE_CODE (ret_expr
) == INIT_EXPR
)
1629 && TREE_CODE (result_decl
) == RESULT_DECL
);
1632 /* If aggregate_value_p is true, then we can return the bare RESULT_DECL.
1633 Recall that aggregate_value_p is FALSE for any aggregate type that is
1634 returned in registers. If we're returning values in registers, then
1635 we don't want to extend the lifetime of the RESULT_DECL, particularly
1636 across another call. In addition, for those aggregates for which
1637 hard_function_value generates a PARALLEL, we'll die during normal
1638 expansion of structure assignments; there's special code in expand_return
1639 to handle this case that does not exist in expand_expr. */
1642 else if (aggregate_value_p (result_decl
, TREE_TYPE (current_function_decl
)))
1644 if (!poly_int_tree_p (DECL_SIZE (result_decl
)))
1646 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (result_decl
)))
1647 gimplify_type_sizes (TREE_TYPE (result_decl
), pre_p
);
1648 /* Note that we don't use gimplify_vla_decl because the RESULT_DECL
1649 should be effectively allocated by the caller, i.e. all calls to
1650 this function must be subject to the Return Slot Optimization. */
1651 gimplify_one_sizepos (&DECL_SIZE (result_decl
), pre_p
);
1652 gimplify_one_sizepos (&DECL_SIZE_UNIT (result_decl
), pre_p
);
1654 result
= result_decl
;
1656 else if (gimplify_ctxp
->return_temp
)
1657 result
= gimplify_ctxp
->return_temp
;
1660 result
= create_tmp_reg (TREE_TYPE (result_decl
));
1662 /* ??? With complex control flow (usually involving abnormal edges),
1663 we can wind up warning about an uninitialized value for this. Due
1664 to how this variable is constructed and initialized, this is never
1665 true. Give up and never warn. */
1666 suppress_warning (result
, OPT_Wuninitialized
);
1668 gimplify_ctxp
->return_temp
= result
;
1671 /* Smash the lhs of the MODIFY_EXPR to the temporary we plan to use.
1672 Then gimplify the whole thing. */
1673 if (result
!= result_decl
)
1674 TREE_OPERAND (ret_expr
, 0) = result
;
1676 gimplify_and_add (TREE_OPERAND (stmt
, 0), pre_p
);
1678 maybe_add_early_return_predict_stmt (pre_p
);
1679 ret
= gimple_build_return (result
);
1680 copy_warning (ret
, stmt
);
1681 gimplify_seq_add_stmt (pre_p
, ret
);
1686 /* Gimplify a variable-length array DECL. */
1689 gimplify_vla_decl (tree decl
, gimple_seq
*seq_p
)
1691 /* This is a variable-sized decl. Simplify its size and mark it
1692 for deferred expansion. */
1693 tree t
, addr
, ptr_type
;
1695 gimplify_one_sizepos (&DECL_SIZE (decl
), seq_p
);
1696 gimplify_one_sizepos (&DECL_SIZE_UNIT (decl
), seq_p
);
1698 /* Don't mess with a DECL_VALUE_EXPR set by the front-end. */
1699 if (DECL_HAS_VALUE_EXPR_P (decl
))
1702 /* All occurrences of this decl in final gimplified code will be
1703 replaced by indirection. Setting DECL_VALUE_EXPR does two
1704 things: First, it lets the rest of the gimplifier know what
1705 replacement to use. Second, it lets the debug info know
1706 where to find the value. */
1707 ptr_type
= build_pointer_type (TREE_TYPE (decl
));
1708 addr
= create_tmp_var (ptr_type
, get_name (decl
));
1709 DECL_IGNORED_P (addr
) = 0;
1710 t
= build_fold_indirect_ref (addr
);
1711 TREE_THIS_NOTRAP (t
) = 1;
1712 SET_DECL_VALUE_EXPR (decl
, t
);
1713 DECL_HAS_VALUE_EXPR_P (decl
) = 1;
1715 t
= build_alloca_call_expr (DECL_SIZE_UNIT (decl
), DECL_ALIGN (decl
),
1716 max_int_size_in_bytes (TREE_TYPE (decl
)));
1717 /* The call has been built for a variable-sized object. */
1718 CALL_ALLOCA_FOR_VAR_P (t
) = 1;
1719 t
= fold_convert (ptr_type
, t
);
1720 t
= build2 (MODIFY_EXPR
, TREE_TYPE (addr
), addr
, t
);
1722 gimplify_and_add (t
, seq_p
);
1724 /* Record the dynamic allocation associated with DECL if requested. */
1725 if (flag_callgraph_info
& CALLGRAPH_INFO_DYNAMIC_ALLOC
)
1726 record_dynamic_alloc (decl
);
1729 /* A helper function to be called via walk_tree. Mark all labels under *TP
1730 as being forced. To be called for DECL_INITIAL of static variables. */
1733 force_labels_r (tree
*tp
, int *walk_subtrees
, void *data ATTRIBUTE_UNUSED
)
1737 if (TREE_CODE (*tp
) == LABEL_DECL
)
1739 FORCED_LABEL (*tp
) = 1;
1740 cfun
->has_forced_label_in_static
= 1;
1746 /* Generate an initialization to automatic variable DECL based on INIT_TYPE.
1747 Build a call to internal const function DEFERRED_INIT:
1748 1st argument: SIZE of the DECL;
1749 2nd argument: INIT_TYPE;
1750 3rd argument: IS_VLA, 0 NO, 1 YES;
1752 as LHS = DEFERRED_INIT (SIZE of the DECL, INIT_TYPE, IS_VLA)
1753 if IS_VLA is false, the LHS is the DECL itself,
1754 if IS_VLA is true, the LHS is a MEM_REF whose address is the pointer
1757 gimple_add_init_for_auto_var (tree decl
,
1758 enum auto_init_type init_type
,
1762 gcc_assert (auto_var_p (decl
));
1763 gcc_assert (init_type
> AUTO_INIT_UNINITIALIZED
);
1764 location_t loc
= EXPR_LOCATION (decl
);
1765 tree decl_size
= TYPE_SIZE_UNIT (TREE_TYPE (decl
));
1768 = build_int_cst (integer_type_node
, (int) init_type
);
1770 = build_int_cst (integer_type_node
, (int) is_vla
);
1772 tree call
= build_call_expr_internal_loc (loc
, IFN_DEFERRED_INIT
,
1773 TREE_TYPE (decl
), 3,
1774 decl_size
, init_type_node
,
1777 gimplify_assign (decl
, call
, seq_p
);
1780 /* Generate padding initialization for automatic vairable DECL.
1781 C guarantees that brace-init with fewer initializers than members
1782 aggregate will initialize the rest of the aggregate as-if it were
1783 static initialization. In turn static initialization guarantees
1784 that padding is initialized to zero. So, we always initialize paddings
1785 to zeroes regardless INIT_TYPE.
1786 To do the padding initialization, we insert a call to
1787 __builtin_clear_padding (&decl, 0, for_auto_init = true).
1788 Note, we add an additional dummy argument for __builtin_clear_padding,
1789 'for_auto_init' to distinguish whether this call is for automatic
1790 variable initialization or not.
1793 gimple_add_padding_init_for_auto_var (tree decl
, bool is_vla
,
1796 tree addr_of_decl
= NULL_TREE
;
1797 bool for_auto_init
= true;
1798 tree fn
= builtin_decl_explicit (BUILT_IN_CLEAR_PADDING
);
1802 /* The temporary address variable for this vla should be
1803 created in gimplify_vla_decl. */
1804 gcc_assert (DECL_HAS_VALUE_EXPR_P (decl
));
1805 gcc_assert (TREE_CODE (DECL_VALUE_EXPR (decl
)) == INDIRECT_REF
);
1806 addr_of_decl
= TREE_OPERAND (DECL_VALUE_EXPR (decl
), 0);
1810 mark_addressable (decl
);
1811 addr_of_decl
= build_fold_addr_expr (decl
);
1814 gimple
*call
= gimple_build_call (fn
,
1816 build_zero_cst (TREE_TYPE (addr_of_decl
)),
1817 build_int_cst (integer_type_node
,
1818 (int) for_auto_init
));
1819 gimplify_seq_add_stmt (seq_p
, call
);
1822 /* Return true if the DECL need to be automaticly initialized by the
1825 is_var_need_auto_init (tree decl
)
1827 if (auto_var_p (decl
)
1828 && (TREE_CODE (decl
) != VAR_DECL
1829 || !DECL_HARD_REGISTER (decl
))
1830 && (flag_auto_var_init
> AUTO_INIT_UNINITIALIZED
)
1831 && (!lookup_attribute ("uninitialized", DECL_ATTRIBUTES (decl
)))
1832 && !is_empty_type (TREE_TYPE (decl
)))
1837 /* Gimplify a DECL_EXPR node *STMT_P by making any necessary allocation
1838 and initialization explicit. */
1840 static enum gimplify_status
1841 gimplify_decl_expr (tree
*stmt_p
, gimple_seq
*seq_p
)
1843 tree stmt
= *stmt_p
;
1844 tree decl
= DECL_EXPR_DECL (stmt
);
1846 *stmt_p
= NULL_TREE
;
1848 if (TREE_TYPE (decl
) == error_mark_node
)
1851 if ((TREE_CODE (decl
) == TYPE_DECL
1853 && !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl
)))
1855 gimplify_type_sizes (TREE_TYPE (decl
), seq_p
);
1856 if (TREE_CODE (TREE_TYPE (decl
)) == REFERENCE_TYPE
)
1857 gimplify_type_sizes (TREE_TYPE (TREE_TYPE (decl
)), seq_p
);
1860 /* ??? DECL_ORIGINAL_TYPE is streamed for LTO so it needs to be gimplified
1861 in case its size expressions contain problematic nodes like CALL_EXPR. */
1862 if (TREE_CODE (decl
) == TYPE_DECL
1863 && DECL_ORIGINAL_TYPE (decl
)
1864 && !TYPE_SIZES_GIMPLIFIED (DECL_ORIGINAL_TYPE (decl
)))
1866 gimplify_type_sizes (DECL_ORIGINAL_TYPE (decl
), seq_p
);
1867 if (TREE_CODE (DECL_ORIGINAL_TYPE (decl
)) == REFERENCE_TYPE
)
1868 gimplify_type_sizes (TREE_TYPE (DECL_ORIGINAL_TYPE (decl
)), seq_p
);
1871 if (VAR_P (decl
) && !DECL_EXTERNAL (decl
))
1873 tree init
= DECL_INITIAL (decl
);
1874 bool is_vla
= false;
1875 /* Check whether a decl has FE created VALUE_EXPR here BEFORE
1876 gimplify_vla_decl creates VALUE_EXPR for a vla decl.
1877 If the decl has VALUE_EXPR that was created by FE (usually
1878 C++FE), it's a proxy varaible, and FE already initialized
1879 the VALUE_EXPR of it, we should not initialize it anymore. */
1880 bool decl_had_value_expr_p
= DECL_HAS_VALUE_EXPR_P (decl
);
1883 if (!poly_int_tree_p (DECL_SIZE_UNIT (decl
), &size
)
1884 || (!TREE_STATIC (decl
)
1885 && flag_stack_check
== GENERIC_STACK_CHECK
1887 (unsigned HOST_WIDE_INT
) STACK_CHECK_MAX_VAR_SIZE
)))
1889 gimplify_vla_decl (decl
, seq_p
);
1893 if (asan_poisoned_variables
1895 && TREE_ADDRESSABLE (decl
)
1896 && !TREE_STATIC (decl
)
1897 && !DECL_HAS_VALUE_EXPR_P (decl
)
1898 && DECL_ALIGN (decl
) <= MAX_SUPPORTED_STACK_ALIGNMENT
1899 && dbg_cnt (asan_use_after_scope
)
1900 && !gimplify_omp_ctxp
1901 /* GNAT introduces temporaries to hold return values of calls in
1902 initializers of variables defined in other units, so the
1903 declaration of the variable is discarded completely. We do not
1904 want to issue poison calls for such dropped variables. */
1905 && (DECL_SEEN_IN_BIND_EXPR_P (decl
)
1906 || (DECL_ARTIFICIAL (decl
) && DECL_NAME (decl
) == NULL_TREE
)))
1908 asan_poisoned_variables
->add (decl
);
1909 asan_poison_variable (decl
, false, seq_p
);
1910 if (!DECL_ARTIFICIAL (decl
) && gimplify_ctxp
->live_switch_vars
)
1911 gimplify_ctxp
->live_switch_vars
->add (decl
);
1914 /* Some front ends do not explicitly declare all anonymous
1915 artificial variables. We compensate here by declaring the
1916 variables, though it would be better if the front ends would
1917 explicitly declare them. */
1918 if (!DECL_SEEN_IN_BIND_EXPR_P (decl
)
1919 && DECL_ARTIFICIAL (decl
) && DECL_NAME (decl
) == NULL_TREE
)
1920 gimple_add_tmp_var (decl
);
1922 if (init
&& init
!= error_mark_node
)
1924 if (!TREE_STATIC (decl
))
1926 DECL_INITIAL (decl
) = NULL_TREE
;
1927 init
= build2 (INIT_EXPR
, void_type_node
, decl
, init
);
1928 gimplify_and_add (init
, seq_p
);
1930 /* Clear TREE_READONLY if we really have an initialization. */
1931 if (!DECL_INITIAL (decl
)
1932 && !omp_privatize_by_reference (decl
))
1933 TREE_READONLY (decl
) = 0;
1936 /* We must still examine initializers for static variables
1937 as they may contain a label address. */
1938 walk_tree (&init
, force_labels_r
, NULL
, NULL
);
1940 /* When there is no explicit initializer, if the user requested,
1941 We should insert an artifical initializer for this automatic
1943 else if (is_var_need_auto_init (decl
)
1944 && !decl_had_value_expr_p
)
1946 gimple_add_init_for_auto_var (decl
,
1950 /* The expanding of a call to the above .DEFERRED_INIT will apply
1951 block initialization to the whole space covered by this variable.
1952 As a result, all the paddings will be initialized to zeroes
1953 for zero initialization and 0xFE byte-repeatable patterns for
1954 pattern initialization.
1955 In order to make the paddings as zeroes for pattern init, We
1956 should add a call to __builtin_clear_padding to clear the
1957 paddings to zero in compatiple with CLANG.
1958 We cannot insert this call if the variable is a gimple register
1959 since __builtin_clear_padding will take the address of the
1960 variable. As a result, if a long double/_Complex long double
1961 variable will spilled into stack later, its padding is 0XFE. */
1962 if (flag_auto_var_init
== AUTO_INIT_PATTERN
1963 && !is_gimple_reg (decl
)
1964 && clear_padding_type_may_have_padding_p (TREE_TYPE (decl
)))
1965 gimple_add_padding_init_for_auto_var (decl
, is_vla
, seq_p
);
1972 /* Gimplify a LOOP_EXPR. Normally this just involves gimplifying the body
1973 and replacing the LOOP_EXPR with goto, but if the loop contains an
1974 EXIT_EXPR, we need to append a label for it to jump to. */
1976 static enum gimplify_status
1977 gimplify_loop_expr (tree
*expr_p
, gimple_seq
*pre_p
)
1979 tree saved_label
= gimplify_ctxp
->exit_label
;
1980 tree start_label
= create_artificial_label (UNKNOWN_LOCATION
);
1982 gimplify_seq_add_stmt (pre_p
, gimple_build_label (start_label
));
1984 gimplify_ctxp
->exit_label
= NULL_TREE
;
1986 gimplify_and_add (LOOP_EXPR_BODY (*expr_p
), pre_p
);
1988 gimplify_seq_add_stmt (pre_p
, gimple_build_goto (start_label
));
1990 if (gimplify_ctxp
->exit_label
)
1991 gimplify_seq_add_stmt (pre_p
,
1992 gimple_build_label (gimplify_ctxp
->exit_label
));
1994 gimplify_ctxp
->exit_label
= saved_label
;
2000 /* Gimplify a statement list onto a sequence. These may be created either
2001 by an enlightened front-end, or by shortcut_cond_expr. */
2003 static enum gimplify_status
2004 gimplify_statement_list (tree
*expr_p
, gimple_seq
*pre_p
)
2006 tree temp
= voidify_wrapper_expr (*expr_p
, NULL
);
2008 tree_stmt_iterator i
= tsi_start (*expr_p
);
2010 while (!tsi_end_p (i
))
2012 gimplify_stmt (tsi_stmt_ptr (i
), pre_p
);
2025 /* Callback for walk_gimple_seq. */
2028 warn_switch_unreachable_r (gimple_stmt_iterator
*gsi_p
, bool *handled_ops_p
,
2029 struct walk_stmt_info
*wi
)
2031 gimple
*stmt
= gsi_stmt (*gsi_p
);
2033 *handled_ops_p
= true;
2034 switch (gimple_code (stmt
))
2037 /* A compiler-generated cleanup or a user-written try block.
2038 If it's empty, don't dive into it--that would result in
2039 worse location info. */
2040 if (gimple_try_eval (stmt
) == NULL
)
2043 return integer_zero_node
;
2048 case GIMPLE_EH_FILTER
:
2049 case GIMPLE_TRANSACTION
:
2050 /* Walk the sub-statements. */
2051 *handled_ops_p
= false;
2055 /* Ignore these. We may generate them before declarations that
2056 are never executed. If there's something to warn about,
2057 there will be non-debug stmts too, and we'll catch those. */
2061 if (gimple_call_internal_p (stmt
, IFN_ASAN_MARK
))
2063 *handled_ops_p
= false;
2068 /* Save the first "real" statement (not a decl/lexical scope/...). */
2070 return integer_zero_node
;
2075 /* Possibly warn about unreachable statements between switch's controlling
2076 expression and the first case. SEQ is the body of a switch expression. */
2079 maybe_warn_switch_unreachable (gimple_seq seq
)
2081 if (!warn_switch_unreachable
2082 /* This warning doesn't play well with Fortran when optimizations
2084 || lang_GNU_Fortran ()
2088 struct walk_stmt_info wi
;
2089 memset (&wi
, 0, sizeof (wi
));
2090 walk_gimple_seq (seq
, warn_switch_unreachable_r
, NULL
, &wi
);
2091 gimple
*stmt
= (gimple
*) wi
.info
;
2093 if (stmt
&& gimple_code (stmt
) != GIMPLE_LABEL
)
2095 if (gimple_code (stmt
) == GIMPLE_GOTO
2096 && TREE_CODE (gimple_goto_dest (stmt
)) == LABEL_DECL
2097 && DECL_ARTIFICIAL (gimple_goto_dest (stmt
)))
2098 /* Don't warn for compiler-generated gotos. These occur
2099 in Duff's devices, for example. */;
2101 warning_at (gimple_location (stmt
), OPT_Wswitch_unreachable
,
2102 "statement will never be executed");
2107 /* A label entry that pairs label and a location. */
2114 /* Find LABEL in vector of label entries VEC. */
2116 static struct label_entry
*
2117 find_label_entry (const auto_vec
<struct label_entry
> *vec
, tree label
)
2120 struct label_entry
*l
;
2122 FOR_EACH_VEC_ELT (*vec
, i
, l
)
2123 if (l
->label
== label
)
2128 /* Return true if LABEL, a LABEL_DECL, represents a case label
2129 in a vector of labels CASES. */
2132 case_label_p (const vec
<tree
> *cases
, tree label
)
2137 FOR_EACH_VEC_ELT (*cases
, i
, l
)
2138 if (CASE_LABEL (l
) == label
)
2143 /* Find the last nondebug statement in a scope STMT. */
2146 last_stmt_in_scope (gimple
*stmt
)
2151 switch (gimple_code (stmt
))
2155 gbind
*bind
= as_a
<gbind
*> (stmt
);
2156 stmt
= gimple_seq_last_nondebug_stmt (gimple_bind_body (bind
));
2157 return last_stmt_in_scope (stmt
);
2162 gtry
*try_stmt
= as_a
<gtry
*> (stmt
);
2163 stmt
= gimple_seq_last_nondebug_stmt (gimple_try_eval (try_stmt
));
2164 gimple
*last_eval
= last_stmt_in_scope (stmt
);
2165 if (gimple_stmt_may_fallthru (last_eval
)
2166 && (last_eval
== NULL
2167 || !gimple_call_internal_p (last_eval
, IFN_FALLTHROUGH
))
2168 && gimple_try_kind (try_stmt
) == GIMPLE_TRY_FINALLY
)
2170 stmt
= gimple_seq_last_nondebug_stmt (gimple_try_cleanup (try_stmt
));
2171 return last_stmt_in_scope (stmt
);
2185 /* Collect interesting labels in LABELS and return the statement preceding
2186 another case label, or a user-defined label. Store a location useful
2187 to give warnings at *PREVLOC (usually the location of the returned
2188 statement or of its surrounding scope). */
2191 collect_fallthrough_labels (gimple_stmt_iterator
*gsi_p
,
2192 auto_vec
<struct label_entry
> *labels
,
2193 location_t
*prevloc
)
2195 gimple
*prev
= NULL
;
2197 *prevloc
= UNKNOWN_LOCATION
;
2200 if (gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_BIND
)
2202 /* Recognize the special GIMPLE_BIND added by gimplify_switch_expr,
2203 which starts on a GIMPLE_SWITCH and ends with a break label.
2204 Handle that as a single statement that can fall through. */
2205 gbind
*bind
= as_a
<gbind
*> (gsi_stmt (*gsi_p
));
2206 gimple
*first
= gimple_seq_first_stmt (gimple_bind_body (bind
));
2207 gimple
*last
= gimple_seq_last_stmt (gimple_bind_body (bind
));
2209 && gimple_code (first
) == GIMPLE_SWITCH
2210 && gimple_code (last
) == GIMPLE_LABEL
)
2212 tree label
= gimple_label_label (as_a
<glabel
*> (last
));
2213 if (SWITCH_BREAK_LABEL_P (label
))
2221 if (gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_BIND
2222 || gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_TRY
)
2224 /* Nested scope. Only look at the last statement of
2225 the innermost scope. */
2226 location_t bind_loc
= gimple_location (gsi_stmt (*gsi_p
));
2227 gimple
*last
= last_stmt_in_scope (gsi_stmt (*gsi_p
));
2231 /* It might be a label without a location. Use the
2232 location of the scope then. */
2233 if (!gimple_has_location (prev
))
2234 *prevloc
= bind_loc
;
2240 /* Ifs are tricky. */
2241 if (gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_COND
)
2243 gcond
*cond_stmt
= as_a
<gcond
*> (gsi_stmt (*gsi_p
));
2244 tree false_lab
= gimple_cond_false_label (cond_stmt
);
2245 location_t if_loc
= gimple_location (cond_stmt
);
2248 if (i > 1) goto <D.2259>; else goto D;
2249 we can't do much with the else-branch. */
2250 if (!DECL_ARTIFICIAL (false_lab
))
2253 /* Go on until the false label, then one step back. */
2254 for (; !gsi_end_p (*gsi_p
); gsi_next (gsi_p
))
2256 gimple
*stmt
= gsi_stmt (*gsi_p
);
2257 if (gimple_code (stmt
) == GIMPLE_LABEL
2258 && gimple_label_label (as_a
<glabel
*> (stmt
)) == false_lab
)
2262 /* Not found? Oops. */
2263 if (gsi_end_p (*gsi_p
))
2266 struct label_entry l
= { false_lab
, if_loc
};
2267 labels
->safe_push (l
);
2269 /* Go to the last statement of the then branch. */
2272 /* if (i != 0) goto <D.1759>; else goto <D.1760>;
2278 if (gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_GOTO
2279 && !gimple_has_location (gsi_stmt (*gsi_p
)))
2281 /* Look at the statement before, it might be
2282 attribute fallthrough, in which case don't warn. */
2284 bool fallthru_before_dest
2285 = gimple_call_internal_p (gsi_stmt (*gsi_p
), IFN_FALLTHROUGH
);
2287 tree goto_dest
= gimple_goto_dest (gsi_stmt (*gsi_p
));
2288 if (!fallthru_before_dest
)
2290 struct label_entry l
= { goto_dest
, if_loc
};
2291 labels
->safe_push (l
);
2294 /* And move back. */
2298 /* Remember the last statement. Skip labels that are of no interest
2300 if (gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_LABEL
)
2302 tree label
= gimple_label_label (as_a
<glabel
*> (gsi_stmt (*gsi_p
)));
2303 if (find_label_entry (labels
, label
))
2304 prev
= gsi_stmt (*gsi_p
);
2306 else if (gimple_call_internal_p (gsi_stmt (*gsi_p
), IFN_ASAN_MARK
))
2308 else if (gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_PREDICT
)
2310 else if (!is_gimple_debug (gsi_stmt (*gsi_p
)))
2311 prev
= gsi_stmt (*gsi_p
);
2314 while (!gsi_end_p (*gsi_p
)
2315 /* Stop if we find a case or a user-defined label. */
2316 && (gimple_code (gsi_stmt (*gsi_p
)) != GIMPLE_LABEL
2317 || !gimple_has_location (gsi_stmt (*gsi_p
))));
2319 if (prev
&& gimple_has_location (prev
))
2320 *prevloc
= gimple_location (prev
);
2324 /* Return true if the switch fallthough warning should occur. LABEL is
2325 the label statement that we're falling through to. */
2328 should_warn_for_implicit_fallthrough (gimple_stmt_iterator
*gsi_p
, tree label
)
2330 gimple_stmt_iterator gsi
= *gsi_p
;
2332 /* Don't warn if the label is marked with a "falls through" comment. */
2333 if (FALLTHROUGH_LABEL_P (label
))
2336 /* Don't warn for non-case labels followed by a statement:
2341 as these are likely intentional. */
2342 if (!case_label_p (&gimplify_ctxp
->case_labels
, label
))
2345 while (!gsi_end_p (gsi
)
2346 && gimple_code (gsi_stmt (gsi
)) == GIMPLE_LABEL
2347 && (l
= gimple_label_label (as_a
<glabel
*> (gsi_stmt (gsi
))))
2348 && !case_label_p (&gimplify_ctxp
->case_labels
, l
))
2349 gsi_next_nondebug (&gsi
);
2350 if (gsi_end_p (gsi
) || gimple_code (gsi_stmt (gsi
)) != GIMPLE_LABEL
)
2354 /* Don't warn for terminated branches, i.e. when the subsequent case labels
2355 immediately breaks. */
2358 /* Skip all immediately following labels. */
2359 while (!gsi_end_p (gsi
)
2360 && (gimple_code (gsi_stmt (gsi
)) == GIMPLE_LABEL
2361 || gimple_code (gsi_stmt (gsi
)) == GIMPLE_PREDICT
))
2362 gsi_next_nondebug (&gsi
);
2364 /* { ... something; default:; } */
2366 /* { ... something; default: break; } or
2367 { ... something; default: goto L; } */
2368 || gimple_code (gsi_stmt (gsi
)) == GIMPLE_GOTO
2369 /* { ... something; default: return; } */
2370 || gimple_code (gsi_stmt (gsi
)) == GIMPLE_RETURN
)
2376 /* Callback for walk_gimple_seq. */
2379 warn_implicit_fallthrough_r (gimple_stmt_iterator
*gsi_p
, bool *handled_ops_p
,
2380 struct walk_stmt_info
*)
2382 gimple
*stmt
= gsi_stmt (*gsi_p
);
2384 *handled_ops_p
= true;
2385 switch (gimple_code (stmt
))
2390 case GIMPLE_EH_FILTER
:
2391 case GIMPLE_TRANSACTION
:
2392 /* Walk the sub-statements. */
2393 *handled_ops_p
= false;
2396 /* Find a sequence of form:
2403 and possibly warn. */
2406 /* Found a label. Skip all immediately following labels. */
2407 while (!gsi_end_p (*gsi_p
)
2408 && gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_LABEL
)
2409 gsi_next_nondebug (gsi_p
);
2411 /* There might be no more statements. */
2412 if (gsi_end_p (*gsi_p
))
2413 return integer_zero_node
;
2415 /* Vector of labels that fall through. */
2416 auto_vec
<struct label_entry
> labels
;
2418 gimple
*prev
= collect_fallthrough_labels (gsi_p
, &labels
, &prevloc
);
2420 /* There might be no more statements. */
2421 if (gsi_end_p (*gsi_p
))
2422 return integer_zero_node
;
2424 gimple
*next
= gsi_stmt (*gsi_p
);
2426 /* If what follows is a label, then we may have a fallthrough. */
2427 if (gimple_code (next
) == GIMPLE_LABEL
2428 && gimple_has_location (next
)
2429 && (label
= gimple_label_label (as_a
<glabel
*> (next
)))
2432 struct label_entry
*l
;
2433 bool warned_p
= false;
2434 auto_diagnostic_group d
;
2435 if (!should_warn_for_implicit_fallthrough (gsi_p
, label
))
2437 else if (gimple_code (prev
) == GIMPLE_LABEL
2438 && (label
= gimple_label_label (as_a
<glabel
*> (prev
)))
2439 && (l
= find_label_entry (&labels
, label
)))
2440 warned_p
= warning_at (l
->loc
, OPT_Wimplicit_fallthrough_
,
2441 "this statement may fall through");
2442 else if (!gimple_call_internal_p (prev
, IFN_FALLTHROUGH
)
2443 /* Try to be clever and don't warn when the statement
2444 can't actually fall through. */
2445 && gimple_stmt_may_fallthru (prev
)
2446 && prevloc
!= UNKNOWN_LOCATION
)
2447 warned_p
= warning_at (prevloc
,
2448 OPT_Wimplicit_fallthrough_
,
2449 "this statement may fall through");
2451 inform (gimple_location (next
), "here");
2453 /* Mark this label as processed so as to prevent multiple
2454 warnings in nested switches. */
2455 FALLTHROUGH_LABEL_P (label
) = true;
2457 /* So that next warn_implicit_fallthrough_r will start looking for
2458 a new sequence starting with this label. */
2469 /* Warn when a switch case falls through. */
2472 maybe_warn_implicit_fallthrough (gimple_seq seq
)
2474 if (!warn_implicit_fallthrough
)
2477 /* This warning is meant for C/C++/ObjC/ObjC++ only. */
2480 || lang_GNU_OBJC ()))
2483 struct walk_stmt_info wi
;
2484 memset (&wi
, 0, sizeof (wi
));
2485 walk_gimple_seq (seq
, warn_implicit_fallthrough_r
, NULL
, &wi
);
2488 /* Callback for walk_gimple_seq. */
2491 expand_FALLTHROUGH_r (gimple_stmt_iterator
*gsi_p
, bool *handled_ops_p
,
2492 struct walk_stmt_info
*wi
)
2494 gimple
*stmt
= gsi_stmt (*gsi_p
);
2496 *handled_ops_p
= true;
2497 switch (gimple_code (stmt
))
2502 case GIMPLE_EH_FILTER
:
2503 case GIMPLE_TRANSACTION
:
2504 /* Walk the sub-statements. */
2505 *handled_ops_p
= false;
2508 if (gimple_call_internal_p (stmt
, IFN_FALLTHROUGH
))
2510 gsi_remove (gsi_p
, true);
2511 if (gsi_end_p (*gsi_p
))
2513 *static_cast<location_t
*>(wi
->info
) = gimple_location (stmt
);
2514 return integer_zero_node
;
2518 location_t loc
= gimple_location (stmt
);
2520 gimple_stmt_iterator gsi2
= *gsi_p
;
2521 stmt
= gsi_stmt (gsi2
);
2522 if (gimple_code (stmt
) == GIMPLE_GOTO
&& !gimple_has_location (stmt
))
2524 /* Go on until the artificial label. */
2525 tree goto_dest
= gimple_goto_dest (stmt
);
2526 for (; !gsi_end_p (gsi2
); gsi_next (&gsi2
))
2528 if (gimple_code (gsi_stmt (gsi2
)) == GIMPLE_LABEL
2529 && gimple_label_label (as_a
<glabel
*> (gsi_stmt (gsi2
)))
2534 /* Not found? Stop. */
2535 if (gsi_end_p (gsi2
))
2538 /* Look one past it. */
2542 /* We're looking for a case label or default label here. */
2543 while (!gsi_end_p (gsi2
))
2545 stmt
= gsi_stmt (gsi2
);
2546 if (gimple_code (stmt
) == GIMPLE_LABEL
)
2548 tree label
= gimple_label_label (as_a
<glabel
*> (stmt
));
2549 if (gimple_has_location (stmt
) && DECL_ARTIFICIAL (label
))
2555 else if (gimple_call_internal_p (stmt
, IFN_ASAN_MARK
))
2557 else if (!is_gimple_debug (stmt
))
2558 /* Anything else is not expected. */
2563 pedwarn (loc
, 0, "attribute %<fallthrough%> not preceding "
2564 "a case label or default label");
2573 /* Expand all FALLTHROUGH () calls in SEQ. */
2576 expand_FALLTHROUGH (gimple_seq
*seq_p
)
2578 struct walk_stmt_info wi
;
2580 memset (&wi
, 0, sizeof (wi
));
2581 wi
.info
= (void *) &loc
;
2582 walk_gimple_seq_mod (seq_p
, expand_FALLTHROUGH_r
, NULL
, &wi
);
2583 if (wi
.callback_result
== integer_zero_node
)
2584 /* We've found [[fallthrough]]; at the end of a switch, which the C++
2585 standard says is ill-formed; see [dcl.attr.fallthrough]. */
2586 pedwarn (loc
, 0, "attribute %<fallthrough%> not preceding "
2587 "a case label or default label");
2591 /* Gimplify a SWITCH_EXPR, and collect the vector of labels it can
2594 static enum gimplify_status
2595 gimplify_switch_expr (tree
*expr_p
, gimple_seq
*pre_p
)
2597 tree switch_expr
= *expr_p
;
2598 gimple_seq switch_body_seq
= NULL
;
2599 enum gimplify_status ret
;
2600 tree index_type
= TREE_TYPE (switch_expr
);
2601 if (index_type
== NULL_TREE
)
2602 index_type
= TREE_TYPE (SWITCH_COND (switch_expr
));
2604 ret
= gimplify_expr (&SWITCH_COND (switch_expr
), pre_p
, NULL
, is_gimple_val
,
2606 if (ret
== GS_ERROR
|| ret
== GS_UNHANDLED
)
2609 if (SWITCH_BODY (switch_expr
))
2612 vec
<tree
> saved_labels
;
2613 hash_set
<tree
> *saved_live_switch_vars
= NULL
;
2614 tree default_case
= NULL_TREE
;
2615 gswitch
*switch_stmt
;
2617 /* Save old labels, get new ones from body, then restore the old
2618 labels. Save all the things from the switch body to append after. */
2619 saved_labels
= gimplify_ctxp
->case_labels
;
2620 gimplify_ctxp
->case_labels
.create (8);
2622 /* Do not create live_switch_vars if SWITCH_BODY is not a BIND_EXPR. */
2623 saved_live_switch_vars
= gimplify_ctxp
->live_switch_vars
;
2624 tree_code body_type
= TREE_CODE (SWITCH_BODY (switch_expr
));
2625 if (body_type
== BIND_EXPR
|| body_type
== STATEMENT_LIST
)
2626 gimplify_ctxp
->live_switch_vars
= new hash_set
<tree
> (4);
2628 gimplify_ctxp
->live_switch_vars
= NULL
;
2630 bool old_in_switch_expr
= gimplify_ctxp
->in_switch_expr
;
2631 gimplify_ctxp
->in_switch_expr
= true;
2633 gimplify_stmt (&SWITCH_BODY (switch_expr
), &switch_body_seq
);
2635 gimplify_ctxp
->in_switch_expr
= old_in_switch_expr
;
2636 maybe_warn_switch_unreachable (switch_body_seq
);
2637 maybe_warn_implicit_fallthrough (switch_body_seq
);
2638 /* Only do this for the outermost GIMPLE_SWITCH. */
2639 if (!gimplify_ctxp
->in_switch_expr
)
2640 expand_FALLTHROUGH (&switch_body_seq
);
2642 labels
= gimplify_ctxp
->case_labels
;
2643 gimplify_ctxp
->case_labels
= saved_labels
;
2645 if (gimplify_ctxp
->live_switch_vars
)
2647 gcc_assert (gimplify_ctxp
->live_switch_vars
->is_empty ());
2648 delete gimplify_ctxp
->live_switch_vars
;
2650 gimplify_ctxp
->live_switch_vars
= saved_live_switch_vars
;
2652 preprocess_case_label_vec_for_gimple (labels
, index_type
,
2655 bool add_bind
= false;
2658 glabel
*new_default
;
2661 = build_case_label (NULL_TREE
, NULL_TREE
,
2662 create_artificial_label (UNKNOWN_LOCATION
));
2663 if (old_in_switch_expr
)
2665 SWITCH_BREAK_LABEL_P (CASE_LABEL (default_case
)) = 1;
2668 new_default
= gimple_build_label (CASE_LABEL (default_case
));
2669 gimplify_seq_add_stmt (&switch_body_seq
, new_default
);
2671 else if (old_in_switch_expr
)
2673 gimple
*last
= gimple_seq_last_stmt (switch_body_seq
);
2674 if (last
&& gimple_code (last
) == GIMPLE_LABEL
)
2676 tree label
= gimple_label_label (as_a
<glabel
*> (last
));
2677 if (SWITCH_BREAK_LABEL_P (label
))
2682 switch_stmt
= gimple_build_switch (SWITCH_COND (switch_expr
),
2683 default_case
, labels
);
2684 /* For the benefit of -Wimplicit-fallthrough, if switch_body_seq
2685 ends with a GIMPLE_LABEL holding SWITCH_BREAK_LABEL_P LABEL_DECL,
2686 wrap the GIMPLE_SWITCH up to that GIMPLE_LABEL into a GIMPLE_BIND,
2687 so that we can easily find the start and end of the switch
2691 gimple_seq bind_body
= NULL
;
2692 gimplify_seq_add_stmt (&bind_body
, switch_stmt
);
2693 gimple_seq_add_seq (&bind_body
, switch_body_seq
);
2694 gbind
*bind
= gimple_build_bind (NULL_TREE
, bind_body
, NULL_TREE
);
2695 gimple_set_location (bind
, EXPR_LOCATION (switch_expr
));
2696 gimplify_seq_add_stmt (pre_p
, bind
);
2700 gimplify_seq_add_stmt (pre_p
, switch_stmt
);
2701 gimplify_seq_add_seq (pre_p
, switch_body_seq
);
2711 /* Gimplify the LABEL_EXPR pointed to by EXPR_P. */
2713 static enum gimplify_status
2714 gimplify_label_expr (tree
*expr_p
, gimple_seq
*pre_p
)
2716 gcc_assert (decl_function_context (LABEL_EXPR_LABEL (*expr_p
))
2717 == current_function_decl
);
2719 tree label
= LABEL_EXPR_LABEL (*expr_p
);
2720 glabel
*label_stmt
= gimple_build_label (label
);
2721 gimple_set_location (label_stmt
, EXPR_LOCATION (*expr_p
));
2722 gimplify_seq_add_stmt (pre_p
, label_stmt
);
2724 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label
)))
2725 gimple_seq_add_stmt (pre_p
, gimple_build_predict (PRED_COLD_LABEL
,
2727 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label
)))
2728 gimple_seq_add_stmt (pre_p
, gimple_build_predict (PRED_HOT_LABEL
,
2734 /* Gimplify the CASE_LABEL_EXPR pointed to by EXPR_P. */
2736 static enum gimplify_status
2737 gimplify_case_label_expr (tree
*expr_p
, gimple_seq
*pre_p
)
2739 struct gimplify_ctx
*ctxp
;
2742 /* Invalid programs can play Duff's Device type games with, for example,
2743 #pragma omp parallel. At least in the C front end, we don't
2744 detect such invalid branches until after gimplification, in the
2745 diagnose_omp_blocks pass. */
2746 for (ctxp
= gimplify_ctxp
; ; ctxp
= ctxp
->prev_context
)
2747 if (ctxp
->case_labels
.exists ())
2750 tree label
= CASE_LABEL (*expr_p
);
2751 label_stmt
= gimple_build_label (label
);
2752 gimple_set_location (label_stmt
, EXPR_LOCATION (*expr_p
));
2753 ctxp
->case_labels
.safe_push (*expr_p
);
2754 gimplify_seq_add_stmt (pre_p
, label_stmt
);
2756 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label
)))
2757 gimple_seq_add_stmt (pre_p
, gimple_build_predict (PRED_COLD_LABEL
,
2759 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label
)))
2760 gimple_seq_add_stmt (pre_p
, gimple_build_predict (PRED_HOT_LABEL
,
2766 /* Build a GOTO to the LABEL_DECL pointed to by LABEL_P, building it first
2770 build_and_jump (tree
*label_p
)
2772 if (label_p
== NULL
)
2773 /* If there's nowhere to jump, just fall through. */
2776 if (*label_p
== NULL_TREE
)
2778 tree label
= create_artificial_label (UNKNOWN_LOCATION
);
2782 return build1 (GOTO_EXPR
, void_type_node
, *label_p
);
2785 /* Gimplify an EXIT_EXPR by converting to a GOTO_EXPR inside a COND_EXPR.
2786 This also involves building a label to jump to and communicating it to
2787 gimplify_loop_expr through gimplify_ctxp->exit_label. */
2789 static enum gimplify_status
2790 gimplify_exit_expr (tree
*expr_p
)
2792 tree cond
= TREE_OPERAND (*expr_p
, 0);
2795 expr
= build_and_jump (&gimplify_ctxp
->exit_label
);
2796 expr
= build3 (COND_EXPR
, void_type_node
, cond
, expr
, NULL_TREE
);
2802 /* *EXPR_P is a COMPONENT_REF being used as an rvalue. If its type is
2803 different from its canonical type, wrap the whole thing inside a
2804 NOP_EXPR and force the type of the COMPONENT_REF to be the canonical
2807 The canonical type of a COMPONENT_REF is the type of the field being
2808 referenced--unless the field is a bit-field which can be read directly
2809 in a smaller mode, in which case the canonical type is the
2810 sign-appropriate type corresponding to that mode. */
2813 canonicalize_component_ref (tree
*expr_p
)
2815 tree expr
= *expr_p
;
2818 gcc_assert (TREE_CODE (expr
) == COMPONENT_REF
);
2820 if (INTEGRAL_TYPE_P (TREE_TYPE (expr
)))
2821 type
= TREE_TYPE (get_unwidened (expr
, NULL_TREE
));
2823 type
= TREE_TYPE (TREE_OPERAND (expr
, 1));
2825 /* One could argue that all the stuff below is not necessary for
2826 the non-bitfield case and declare it a FE error if type
2827 adjustment would be needed. */
2828 if (TREE_TYPE (expr
) != type
)
2830 #ifdef ENABLE_TYPES_CHECKING
2831 tree old_type
= TREE_TYPE (expr
);
2835 /* We need to preserve qualifiers and propagate them from
2837 type_quals
= TYPE_QUALS (type
)
2838 | TYPE_QUALS (TREE_TYPE (TREE_OPERAND (expr
, 0)));
2839 if (TYPE_QUALS (type
) != type_quals
)
2840 type
= build_qualified_type (TYPE_MAIN_VARIANT (type
), type_quals
);
2842 /* Set the type of the COMPONENT_REF to the underlying type. */
2843 TREE_TYPE (expr
) = type
;
2845 #ifdef ENABLE_TYPES_CHECKING
2846 /* It is now a FE error, if the conversion from the canonical
2847 type to the original expression type is not useless. */
2848 gcc_assert (useless_type_conversion_p (old_type
, type
));
2853 /* If a NOP conversion is changing a pointer to array of foo to a pointer
2854 to foo, embed that change in the ADDR_EXPR by converting
2859 where L is the lower bound. For simplicity, only do this for constant
2861 The constraint is that the type of &array[L] is trivially convertible
2865 canonicalize_addr_expr (tree
*expr_p
)
2867 tree expr
= *expr_p
;
2868 tree addr_expr
= TREE_OPERAND (expr
, 0);
2869 tree datype
, ddatype
, pddatype
;
2871 /* We simplify only conversions from an ADDR_EXPR to a pointer type. */
2872 if (!POINTER_TYPE_P (TREE_TYPE (expr
))
2873 || TREE_CODE (addr_expr
) != ADDR_EXPR
)
2876 /* The addr_expr type should be a pointer to an array. */
2877 datype
= TREE_TYPE (TREE_TYPE (addr_expr
));
2878 if (TREE_CODE (datype
) != ARRAY_TYPE
)
2881 /* The pointer to element type shall be trivially convertible to
2882 the expression pointer type. */
2883 ddatype
= TREE_TYPE (datype
);
2884 pddatype
= build_pointer_type (ddatype
);
2885 if (!useless_type_conversion_p (TYPE_MAIN_VARIANT (TREE_TYPE (expr
)),
2889 /* The lower bound and element sizes must be constant. */
2890 if (!TYPE_SIZE_UNIT (ddatype
)
2891 || TREE_CODE (TYPE_SIZE_UNIT (ddatype
)) != INTEGER_CST
2892 || !TYPE_DOMAIN (datype
) || !TYPE_MIN_VALUE (TYPE_DOMAIN (datype
))
2893 || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (datype
))) != INTEGER_CST
)
2896 /* All checks succeeded. Build a new node to merge the cast. */
2897 *expr_p
= build4 (ARRAY_REF
, ddatype
, TREE_OPERAND (addr_expr
, 0),
2898 TYPE_MIN_VALUE (TYPE_DOMAIN (datype
)),
2899 NULL_TREE
, NULL_TREE
);
2900 *expr_p
= build1 (ADDR_EXPR
, pddatype
, *expr_p
);
2902 /* We can have stripped a required restrict qualifier above. */
2903 if (!useless_type_conversion_p (TREE_TYPE (expr
), TREE_TYPE (*expr_p
)))
2904 *expr_p
= fold_convert (TREE_TYPE (expr
), *expr_p
);
2907 /* *EXPR_P is a NOP_EXPR or CONVERT_EXPR. Remove it and/or other conversions
2908 underneath as appropriate. */
2910 static enum gimplify_status
2911 gimplify_conversion (tree
*expr_p
)
2913 location_t loc
= EXPR_LOCATION (*expr_p
);
2914 gcc_assert (CONVERT_EXPR_P (*expr_p
));
2916 /* Then strip away all but the outermost conversion. */
2917 STRIP_SIGN_NOPS (TREE_OPERAND (*expr_p
, 0));
2919 /* And remove the outermost conversion if it's useless. */
2920 if (tree_ssa_useless_type_conversion (*expr_p
))
2921 *expr_p
= TREE_OPERAND (*expr_p
, 0);
2923 /* If we still have a conversion at the toplevel,
2924 then canonicalize some constructs. */
2925 if (CONVERT_EXPR_P (*expr_p
))
2927 tree sub
= TREE_OPERAND (*expr_p
, 0);
2929 /* If a NOP conversion is changing the type of a COMPONENT_REF
2930 expression, then canonicalize its type now in order to expose more
2931 redundant conversions. */
2932 if (TREE_CODE (sub
) == COMPONENT_REF
)
2933 canonicalize_component_ref (&TREE_OPERAND (*expr_p
, 0));
2935 /* If a NOP conversion is changing a pointer to array of foo
2936 to a pointer to foo, embed that change in the ADDR_EXPR. */
2937 else if (TREE_CODE (sub
) == ADDR_EXPR
)
2938 canonicalize_addr_expr (expr_p
);
2941 /* If we have a conversion to a non-register type force the
2942 use of a VIEW_CONVERT_EXPR instead. */
2943 if (CONVERT_EXPR_P (*expr_p
) && !is_gimple_reg_type (TREE_TYPE (*expr_p
)))
2944 *expr_p
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, TREE_TYPE (*expr_p
),
2945 TREE_OPERAND (*expr_p
, 0));
2947 /* Canonicalize CONVERT_EXPR to NOP_EXPR. */
2948 if (TREE_CODE (*expr_p
) == CONVERT_EXPR
)
2949 TREE_SET_CODE (*expr_p
, NOP_EXPR
);
2954 /* Gimplify a VAR_DECL or PARM_DECL. Return GS_OK if we expanded a
2955 DECL_VALUE_EXPR, and it's worth re-examining things. */
2957 static enum gimplify_status
2958 gimplify_var_or_parm_decl (tree
*expr_p
)
2960 tree decl
= *expr_p
;
2962 /* ??? If this is a local variable, and it has not been seen in any
2963 outer BIND_EXPR, then it's probably the result of a duplicate
2964 declaration, for which we've already issued an error. It would
2965 be really nice if the front end wouldn't leak these at all.
2966 Currently the only known culprit is C++ destructors, as seen
2967 in g++.old-deja/g++.jason/binding.C.
2968 Another possible culpit are size expressions for variably modified
2969 types which are lost in the FE or not gimplified correctly. */
2971 && !DECL_SEEN_IN_BIND_EXPR_P (decl
)
2972 && !TREE_STATIC (decl
) && !DECL_EXTERNAL (decl
)
2973 && decl_function_context (decl
) == current_function_decl
)
2975 gcc_assert (seen_error ());
2979 /* When within an OMP context, notice uses of variables. */
2980 if (gimplify_omp_ctxp
&& omp_notice_variable (gimplify_omp_ctxp
, decl
, true))
2983 /* If the decl is an alias for another expression, substitute it now. */
2984 if (DECL_HAS_VALUE_EXPR_P (decl
))
2986 *expr_p
= unshare_expr (DECL_VALUE_EXPR (decl
));
2993 /* Recalculate the value of the TREE_SIDE_EFFECTS flag for T. */
2996 recalculate_side_effects (tree t
)
2998 enum tree_code code
= TREE_CODE (t
);
2999 int len
= TREE_OPERAND_LENGTH (t
);
3002 switch (TREE_CODE_CLASS (code
))
3004 case tcc_expression
:
3010 case PREDECREMENT_EXPR
:
3011 case PREINCREMENT_EXPR
:
3012 case POSTDECREMENT_EXPR
:
3013 case POSTINCREMENT_EXPR
:
3014 /* All of these have side-effects, no matter what their
3023 case tcc_comparison
: /* a comparison expression */
3024 case tcc_unary
: /* a unary arithmetic expression */
3025 case tcc_binary
: /* a binary arithmetic expression */
3026 case tcc_reference
: /* a reference */
3027 case tcc_vl_exp
: /* a function call */
3028 TREE_SIDE_EFFECTS (t
) = TREE_THIS_VOLATILE (t
);
3029 for (i
= 0; i
< len
; ++i
)
3031 tree op
= TREE_OPERAND (t
, i
);
3032 if (op
&& TREE_SIDE_EFFECTS (op
))
3033 TREE_SIDE_EFFECTS (t
) = 1;
3038 /* No side-effects. */
3046 /* Gimplify the COMPONENT_REF, ARRAY_REF, REALPART_EXPR or IMAGPART_EXPR
3050 : min_lval '[' val ']'
3052 | compound_lval '[' val ']'
3053 | compound_lval '.' ID
3055 This is not part of the original SIMPLE definition, which separates
3056 array and member references, but it seems reasonable to handle them
3057 together. Also, this way we don't run into problems with union
3058 aliasing; gcc requires that for accesses through a union to alias, the
3059 union reference must be explicit, which was not always the case when we
3060 were splitting up array and member refs.
3062 PRE_P points to the sequence where side effects that must happen before
3063 *EXPR_P should be stored.
3065 POST_P points to the sequence where side effects that must happen after
3066 *EXPR_P should be stored. */
3068 static enum gimplify_status
3069 gimplify_compound_lval (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
3070 fallback_t fallback
)
3073 enum gimplify_status ret
= GS_ALL_DONE
, tret
;
3075 location_t loc
= EXPR_LOCATION (*expr_p
);
3076 tree expr
= *expr_p
;
3078 /* Create a stack of the subexpressions so later we can walk them in
3079 order from inner to outer. */
3080 auto_vec
<tree
, 10> expr_stack
;
3082 /* We can handle anything that get_inner_reference can deal with. */
3083 for (p
= expr_p
; ; p
= &TREE_OPERAND (*p
, 0))
3086 /* Fold INDIRECT_REFs now to turn them into ARRAY_REFs. */
3087 if (TREE_CODE (*p
) == INDIRECT_REF
)
3088 *p
= fold_indirect_ref_loc (loc
, *p
);
3090 if (handled_component_p (*p
))
3092 /* Expand DECL_VALUE_EXPR now. In some cases that may expose
3093 additional COMPONENT_REFs. */
3094 else if ((VAR_P (*p
) || TREE_CODE (*p
) == PARM_DECL
)
3095 && gimplify_var_or_parm_decl (p
) == GS_OK
)
3100 expr_stack
.safe_push (*p
);
3103 gcc_assert (expr_stack
.length ());
3105 /* Now EXPR_STACK is a stack of pointers to all the refs we've
3106 walked through and P points to the innermost expression.
3108 Java requires that we elaborated nodes in source order. That
3109 means we must gimplify the inner expression followed by each of
3110 the indices, in order. But we can't gimplify the inner
3111 expression until we deal with any variable bounds, sizes, or
3112 positions in order to deal with PLACEHOLDER_EXPRs.
3114 The base expression may contain a statement expression that
3115 has declarations used in size expressions, so has to be
3116 gimplified before gimplifying the size expressions.
3118 So we do this in three steps. First we deal with variable
3119 bounds, sizes, and positions, then we gimplify the base,
3120 then we deal with the annotations for any variables in the
3121 components and any indices, from left to right. */
3123 for (i
= expr_stack
.length () - 1; i
>= 0; i
--)
3125 tree t
= expr_stack
[i
];
3127 if (TREE_CODE (t
) == ARRAY_REF
|| TREE_CODE (t
) == ARRAY_RANGE_REF
)
3129 /* Deal with the low bound and element type size and put them into
3130 the ARRAY_REF. If these values are set, they have already been
3132 if (TREE_OPERAND (t
, 2) == NULL_TREE
)
3134 tree low
= unshare_expr (array_ref_low_bound (t
));
3135 if (!is_gimple_min_invariant (low
))
3137 TREE_OPERAND (t
, 2) = low
;
3141 if (TREE_OPERAND (t
, 3) == NULL_TREE
)
3143 tree elmt_size
= array_ref_element_size (t
);
3144 if (!is_gimple_min_invariant (elmt_size
))
3146 elmt_size
= unshare_expr (elmt_size
);
3147 tree elmt_type
= TREE_TYPE (TREE_TYPE (TREE_OPERAND (t
, 0)));
3148 tree factor
= size_int (TYPE_ALIGN_UNIT (elmt_type
));
3150 /* Divide the element size by the alignment of the element
3152 elmt_size
= size_binop_loc (loc
, EXACT_DIV_EXPR
,
3155 TREE_OPERAND (t
, 3) = elmt_size
;
3159 else if (TREE_CODE (t
) == COMPONENT_REF
)
3161 /* Set the field offset into T and gimplify it. */
3162 if (TREE_OPERAND (t
, 2) == NULL_TREE
)
3164 tree offset
= component_ref_field_offset (t
);
3165 if (!is_gimple_min_invariant (offset
))
3167 offset
= unshare_expr (offset
);
3168 tree field
= TREE_OPERAND (t
, 1);
3170 = size_int (DECL_OFFSET_ALIGN (field
) / BITS_PER_UNIT
);
3172 /* Divide the offset by its alignment. */
3173 offset
= size_binop_loc (loc
, EXACT_DIV_EXPR
,
3176 TREE_OPERAND (t
, 2) = offset
;
3182 /* Step 2 is to gimplify the base expression. Make sure lvalue is set
3183 so as to match the min_lval predicate. Failure to do so may result
3184 in the creation of large aggregate temporaries. */
3185 tret
= gimplify_expr (p
, pre_p
, post_p
, is_gimple_min_lval
,
3186 fallback
| fb_lvalue
);
3187 ret
= MIN (ret
, tret
);
3189 /* Step 3: gimplify size expressions and the indices and operands of
3190 ARRAY_REF. During this loop we also remove any useless conversions. */
3192 for (; expr_stack
.length () > 0; )
3194 tree t
= expr_stack
.pop ();
3196 if (TREE_CODE (t
) == ARRAY_REF
|| TREE_CODE (t
) == ARRAY_RANGE_REF
)
3198 /* Gimplify the low bound and element type size. */
3199 tret
= gimplify_expr (&TREE_OPERAND (t
, 2), pre_p
, post_p
,
3200 is_gimple_reg
, fb_rvalue
);
3201 ret
= MIN (ret
, tret
);
3203 tret
= gimplify_expr (&TREE_OPERAND (t
, 3), pre_p
, post_p
,
3204 is_gimple_reg
, fb_rvalue
);
3205 ret
= MIN (ret
, tret
);
3207 /* Gimplify the dimension. */
3208 tret
= gimplify_expr (&TREE_OPERAND (t
, 1), pre_p
, post_p
,
3209 is_gimple_val
, fb_rvalue
);
3210 ret
= MIN (ret
, tret
);
3212 else if (TREE_CODE (t
) == COMPONENT_REF
)
3214 tret
= gimplify_expr (&TREE_OPERAND (t
, 2), pre_p
, post_p
,
3215 is_gimple_reg
, fb_rvalue
);
3216 ret
= MIN (ret
, tret
);
3219 STRIP_USELESS_TYPE_CONVERSION (TREE_OPERAND (t
, 0));
3221 /* The innermost expression P may have originally had
3222 TREE_SIDE_EFFECTS set which would have caused all the outer
3223 expressions in *EXPR_P leading to P to also have had
3224 TREE_SIDE_EFFECTS set. */
3225 recalculate_side_effects (t
);
3228 /* If the outermost expression is a COMPONENT_REF, canonicalize its type. */
3229 if ((fallback
& fb_rvalue
) && TREE_CODE (*expr_p
) == COMPONENT_REF
)
3231 canonicalize_component_ref (expr_p
);
3234 expr_stack
.release ();
3236 gcc_assert (*expr_p
== expr
|| ret
!= GS_ALL_DONE
);
3241 /* Gimplify the self modifying expression pointed to by EXPR_P
3244 PRE_P points to the list where side effects that must happen before
3245 *EXPR_P should be stored.
3247 POST_P points to the list where side effects that must happen after
3248 *EXPR_P should be stored.
3250 WANT_VALUE is nonzero iff we want to use the value of this expression
3251 in another expression.
3253 ARITH_TYPE is the type the computation should be performed in. */
3255 enum gimplify_status
3256 gimplify_self_mod_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
3257 bool want_value
, tree arith_type
)
3259 enum tree_code code
;
3260 tree lhs
, lvalue
, rhs
, t1
;
3261 gimple_seq post
= NULL
, *orig_post_p
= post_p
;
3263 enum tree_code arith_code
;
3264 enum gimplify_status ret
;
3265 location_t loc
= EXPR_LOCATION (*expr_p
);
3267 code
= TREE_CODE (*expr_p
);
3269 gcc_assert (code
== POSTINCREMENT_EXPR
|| code
== POSTDECREMENT_EXPR
3270 || code
== PREINCREMENT_EXPR
|| code
== PREDECREMENT_EXPR
);
3272 /* Prefix or postfix? */
3273 if (code
== POSTINCREMENT_EXPR
|| code
== POSTDECREMENT_EXPR
)
3274 /* Faster to treat as prefix if result is not used. */
3275 postfix
= want_value
;
3279 /* For postfix, make sure the inner expression's post side effects
3280 are executed after side effects from this expression. */
3284 /* Add or subtract? */
3285 if (code
== PREINCREMENT_EXPR
|| code
== POSTINCREMENT_EXPR
)
3286 arith_code
= PLUS_EXPR
;
3288 arith_code
= MINUS_EXPR
;
3290 /* Gimplify the LHS into a GIMPLE lvalue. */
3291 lvalue
= TREE_OPERAND (*expr_p
, 0);
3292 ret
= gimplify_expr (&lvalue
, pre_p
, post_p
, is_gimple_lvalue
, fb_lvalue
);
3293 if (ret
== GS_ERROR
)
3296 /* Extract the operands to the arithmetic operation. */
3298 rhs
= TREE_OPERAND (*expr_p
, 1);
3300 /* For postfix operator, we evaluate the LHS to an rvalue and then use
3301 that as the result value and in the postqueue operation. */
3304 ret
= gimplify_expr (&lhs
, pre_p
, post_p
, is_gimple_val
, fb_rvalue
);
3305 if (ret
== GS_ERROR
)
3308 lhs
= get_initialized_tmp_var (lhs
, pre_p
);
3311 /* For POINTERs increment, use POINTER_PLUS_EXPR. */
3312 if (POINTER_TYPE_P (TREE_TYPE (lhs
)))
3314 rhs
= convert_to_ptrofftype_loc (loc
, rhs
);
3315 if (arith_code
== MINUS_EXPR
)
3316 rhs
= fold_build1_loc (loc
, NEGATE_EXPR
, TREE_TYPE (rhs
), rhs
);
3317 t1
= fold_build2 (POINTER_PLUS_EXPR
, TREE_TYPE (*expr_p
), lhs
, rhs
);
3320 t1
= fold_convert (TREE_TYPE (*expr_p
),
3321 fold_build2 (arith_code
, arith_type
,
3322 fold_convert (arith_type
, lhs
),
3323 fold_convert (arith_type
, rhs
)));
3327 gimplify_assign (lvalue
, t1
, pre_p
);
3328 gimplify_seq_add_seq (orig_post_p
, post
);
3334 *expr_p
= build2 (MODIFY_EXPR
, TREE_TYPE (lvalue
), lvalue
, t1
);
3339 /* If *EXPR_P has a variable sized type, wrap it in a WITH_SIZE_EXPR. */
3342 maybe_with_size_expr (tree
*expr_p
)
3344 tree expr
= *expr_p
;
3345 tree type
= TREE_TYPE (expr
);
3348 /* If we've already wrapped this or the type is error_mark_node, we can't do
3350 if (TREE_CODE (expr
) == WITH_SIZE_EXPR
3351 || type
== error_mark_node
)
3354 /* If the size isn't known or is a constant, we have nothing to do. */
3355 size
= TYPE_SIZE_UNIT (type
);
3356 if (!size
|| poly_int_tree_p (size
))
3359 /* Otherwise, make a WITH_SIZE_EXPR. */
3360 size
= unshare_expr (size
);
3361 size
= SUBSTITUTE_PLACEHOLDER_IN_EXPR (size
, expr
);
3362 *expr_p
= build2 (WITH_SIZE_EXPR
, type
, expr
, size
);
3365 /* Helper for gimplify_call_expr. Gimplify a single argument *ARG_P
3366 Store any side-effects in PRE_P. CALL_LOCATION is the location of
3367 the CALL_EXPR. If ALLOW_SSA is set the actual parameter may be
3368 gimplified to an SSA name. */
3370 enum gimplify_status
3371 gimplify_arg (tree
*arg_p
, gimple_seq
*pre_p
, location_t call_location
,
3374 bool (*test
) (tree
);
3377 /* In general, we allow lvalues for function arguments to avoid
3378 extra overhead of copying large aggregates out of even larger
3379 aggregates into temporaries only to copy the temporaries to
3380 the argument list. Make optimizers happy by pulling out to
3381 temporaries those types that fit in registers. */
3382 if (is_gimple_reg_type (TREE_TYPE (*arg_p
)))
3383 test
= is_gimple_val
, fb
= fb_rvalue
;
3386 test
= is_gimple_lvalue
, fb
= fb_either
;
3387 /* Also strip a TARGET_EXPR that would force an extra copy. */
3388 if (TREE_CODE (*arg_p
) == TARGET_EXPR
)
3390 tree init
= TARGET_EXPR_INITIAL (*arg_p
);
3392 && !VOID_TYPE_P (TREE_TYPE (init
)))
3397 /* If this is a variable sized type, we must remember the size. */
3398 maybe_with_size_expr (arg_p
);
3400 /* FIXME diagnostics: This will mess up gcc.dg/Warray-bounds.c. */
3401 /* Make sure arguments have the same location as the function call
3403 protected_set_expr_location (*arg_p
, call_location
);
3405 /* There is a sequence point before a function call. Side effects in
3406 the argument list must occur before the actual call. So, when
3407 gimplifying arguments, force gimplify_expr to use an internal
3408 post queue which is then appended to the end of PRE_P. */
3409 return gimplify_expr (arg_p
, pre_p
, NULL
, test
, fb
, allow_ssa
);
3412 /* Don't fold inside offloading or taskreg regions: it can break code by
3413 adding decl references that weren't in the source. We'll do it during
3414 omplower pass instead. */
3417 maybe_fold_stmt (gimple_stmt_iterator
*gsi
)
3419 struct gimplify_omp_ctx
*ctx
;
3420 for (ctx
= gimplify_omp_ctxp
; ctx
; ctx
= ctx
->outer_context
)
3421 if ((ctx
->region_type
& (ORT_TARGET
| ORT_PARALLEL
| ORT_TASK
)) != 0)
3423 else if ((ctx
->region_type
& ORT_HOST_TEAMS
) == ORT_HOST_TEAMS
)
3425 /* Delay folding of builtins until the IL is in consistent state
3426 so the diagnostic machinery can do a better job. */
3427 if (gimple_call_builtin_p (gsi_stmt (*gsi
)))
3429 return fold_stmt (gsi
);
3432 /* Gimplify the CALL_EXPR node *EXPR_P into the GIMPLE sequence PRE_P.
3433 WANT_VALUE is true if the result of the call is desired. */
3435 static enum gimplify_status
3436 gimplify_call_expr (tree
*expr_p
, gimple_seq
*pre_p
, bool want_value
)
3438 tree fndecl
, parms
, p
, fnptrtype
;
3439 enum gimplify_status ret
;
3442 bool builtin_va_start_p
= false;
3443 location_t loc
= EXPR_LOCATION (*expr_p
);
3445 gcc_assert (TREE_CODE (*expr_p
) == CALL_EXPR
);
3447 /* For reliable diagnostics during inlining, it is necessary that
3448 every call_expr be annotated with file and line. */
3449 if (! EXPR_HAS_LOCATION (*expr_p
))
3450 SET_EXPR_LOCATION (*expr_p
, input_location
);
3452 /* Gimplify internal functions created in the FEs. */
3453 if (CALL_EXPR_FN (*expr_p
) == NULL_TREE
)
3458 nargs
= call_expr_nargs (*expr_p
);
3459 enum internal_fn ifn
= CALL_EXPR_IFN (*expr_p
);
3460 auto_vec
<tree
> vargs (nargs
);
3462 for (i
= 0; i
< nargs
; i
++)
3464 gimplify_arg (&CALL_EXPR_ARG (*expr_p
, i
), pre_p
,
3465 EXPR_LOCATION (*expr_p
));
3466 vargs
.quick_push (CALL_EXPR_ARG (*expr_p
, i
));
3469 gcall
*call
= gimple_build_call_internal_vec (ifn
, vargs
);
3470 gimple_call_set_nothrow (call
, TREE_NOTHROW (*expr_p
));
3471 gimplify_seq_add_stmt (pre_p
, call
);
3475 /* This may be a call to a builtin function.
3477 Builtin function calls may be transformed into different
3478 (and more efficient) builtin function calls under certain
3479 circumstances. Unfortunately, gimplification can muck things
3480 up enough that the builtin expanders are not aware that certain
3481 transformations are still valid.
3483 So we attempt transformation/gimplification of the call before
3484 we gimplify the CALL_EXPR. At this time we do not manage to
3485 transform all calls in the same manner as the expanders do, but
3486 we do transform most of them. */
3487 fndecl
= get_callee_fndecl (*expr_p
);
3488 if (fndecl
&& fndecl_built_in_p (fndecl
, BUILT_IN_NORMAL
))
3489 switch (DECL_FUNCTION_CODE (fndecl
))
3491 CASE_BUILT_IN_ALLOCA
:
3492 /* If the call has been built for a variable-sized object, then we
3493 want to restore the stack level when the enclosing BIND_EXPR is
3494 exited to reclaim the allocated space; otherwise, we precisely
3495 need to do the opposite and preserve the latest stack level. */
3496 if (CALL_ALLOCA_FOR_VAR_P (*expr_p
))
3497 gimplify_ctxp
->save_stack
= true;
3499 gimplify_ctxp
->keep_stack
= true;
3502 case BUILT_IN_VA_START
:
3504 builtin_va_start_p
= TRUE
;
3505 if (call_expr_nargs (*expr_p
) < 2)
3507 error ("too few arguments to function %<va_start%>");
3508 *expr_p
= build_empty_stmt (EXPR_LOCATION (*expr_p
));
3512 if (fold_builtin_next_arg (*expr_p
, true))
3514 *expr_p
= build_empty_stmt (EXPR_LOCATION (*expr_p
));
3520 case BUILT_IN_EH_RETURN
:
3521 cfun
->calls_eh_return
= true;
3524 case BUILT_IN_CLEAR_PADDING
:
3525 if (call_expr_nargs (*expr_p
) == 1)
3527 /* Remember the original type of the argument in an internal
3528 dummy second argument, as in GIMPLE pointer conversions are
3529 useless. also mark this call as not for automatic initialization
3530 in the internal dummy third argument. */
3531 p
= CALL_EXPR_ARG (*expr_p
, 0);
3532 bool for_auto_init
= false;
3534 = build_call_expr_loc (EXPR_LOCATION (*expr_p
), fndecl
, 3, p
,
3535 build_zero_cst (TREE_TYPE (p
)),
3536 build_int_cst (integer_type_node
,
3537 (int) for_auto_init
));
3545 if (fndecl
&& fndecl_built_in_p (fndecl
))
3547 tree new_tree
= fold_call_expr (input_location
, *expr_p
, !want_value
);
3548 if (new_tree
&& new_tree
!= *expr_p
)
3550 /* There was a transformation of this call which computes the
3551 same value, but in a more efficient way. Return and try
3558 /* Remember the original function pointer type. */
3559 fnptrtype
= TREE_TYPE (CALL_EXPR_FN (*expr_p
));
3564 && (cfun
->curr_properties
& PROP_gimple_any
) == 0)
3566 tree variant
= omp_resolve_declare_variant (fndecl
);
3567 if (variant
!= fndecl
)
3568 CALL_EXPR_FN (*expr_p
) = build1 (ADDR_EXPR
, fnptrtype
, variant
);
3571 /* There is a sequence point before the call, so any side effects in
3572 the calling expression must occur before the actual call. Force
3573 gimplify_expr to use an internal post queue. */
3574 ret
= gimplify_expr (&CALL_EXPR_FN (*expr_p
), pre_p
, NULL
,
3575 is_gimple_call_addr
, fb_rvalue
);
3577 nargs
= call_expr_nargs (*expr_p
);
3579 /* Get argument types for verification. */
3580 fndecl
= get_callee_fndecl (*expr_p
);
3583 parms
= TYPE_ARG_TYPES (TREE_TYPE (fndecl
));
3585 parms
= TYPE_ARG_TYPES (TREE_TYPE (fnptrtype
));
3587 if (fndecl
&& DECL_ARGUMENTS (fndecl
))
3588 p
= DECL_ARGUMENTS (fndecl
);
3593 for (i
= 0; i
< nargs
&& p
; i
++, p
= TREE_CHAIN (p
))
3596 /* If the last argument is __builtin_va_arg_pack () and it is not
3597 passed as a named argument, decrease the number of CALL_EXPR
3598 arguments and set instead the CALL_EXPR_VA_ARG_PACK flag. */
3601 && TREE_CODE (CALL_EXPR_ARG (*expr_p
, nargs
- 1)) == CALL_EXPR
)
3603 tree last_arg
= CALL_EXPR_ARG (*expr_p
, nargs
- 1);
3604 tree last_arg_fndecl
= get_callee_fndecl (last_arg
);
3607 && fndecl_built_in_p (last_arg_fndecl
, BUILT_IN_VA_ARG_PACK
))
3609 tree call
= *expr_p
;
3612 *expr_p
= build_call_array_loc (loc
, TREE_TYPE (call
),
3613 CALL_EXPR_FN (call
),
3614 nargs
, CALL_EXPR_ARGP (call
));
3616 /* Copy all CALL_EXPR flags, location and block, except
3617 CALL_EXPR_VA_ARG_PACK flag. */
3618 CALL_EXPR_STATIC_CHAIN (*expr_p
) = CALL_EXPR_STATIC_CHAIN (call
);
3619 CALL_EXPR_TAILCALL (*expr_p
) = CALL_EXPR_TAILCALL (call
);
3620 CALL_EXPR_RETURN_SLOT_OPT (*expr_p
)
3621 = CALL_EXPR_RETURN_SLOT_OPT (call
);
3622 CALL_FROM_THUNK_P (*expr_p
) = CALL_FROM_THUNK_P (call
);
3623 SET_EXPR_LOCATION (*expr_p
, EXPR_LOCATION (call
));
3625 /* Set CALL_EXPR_VA_ARG_PACK. */
3626 CALL_EXPR_VA_ARG_PACK (*expr_p
) = 1;
3630 /* If the call returns twice then after building the CFG the call
3631 argument computations will no longer dominate the call because
3632 we add an abnormal incoming edge to the call. So do not use SSA
3634 bool returns_twice
= call_expr_flags (*expr_p
) & ECF_RETURNS_TWICE
;
3636 /* Gimplify the function arguments. */
3639 for (i
= (PUSH_ARGS_REVERSED
? nargs
- 1 : 0);
3640 PUSH_ARGS_REVERSED
? i
>= 0 : i
< nargs
;
3641 PUSH_ARGS_REVERSED
? i
-- : i
++)
3643 enum gimplify_status t
;
3645 /* Avoid gimplifying the second argument to va_start, which needs to
3646 be the plain PARM_DECL. */
3647 if ((i
!= 1) || !builtin_va_start_p
)
3649 t
= gimplify_arg (&CALL_EXPR_ARG (*expr_p
, i
), pre_p
,
3650 EXPR_LOCATION (*expr_p
), ! returns_twice
);
3658 /* Gimplify the static chain. */
3659 if (CALL_EXPR_STATIC_CHAIN (*expr_p
))
3661 if (fndecl
&& !DECL_STATIC_CHAIN (fndecl
))
3662 CALL_EXPR_STATIC_CHAIN (*expr_p
) = NULL
;
3665 enum gimplify_status t
;
3666 t
= gimplify_arg (&CALL_EXPR_STATIC_CHAIN (*expr_p
), pre_p
,
3667 EXPR_LOCATION (*expr_p
), ! returns_twice
);
3673 /* Verify the function result. */
3674 if (want_value
&& fndecl
3675 && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fnptrtype
))))
3677 error_at (loc
, "using result of function returning %<void%>");
3681 /* Try this again in case gimplification exposed something. */
3682 if (ret
!= GS_ERROR
)
3684 tree new_tree
= fold_call_expr (input_location
, *expr_p
, !want_value
);
3686 if (new_tree
&& new_tree
!= *expr_p
)
3688 /* There was a transformation of this call which computes the
3689 same value, but in a more efficient way. Return and try
3697 *expr_p
= error_mark_node
;
3701 /* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its
3702 decl. This allows us to eliminate redundant or useless
3703 calls to "const" functions. */
3704 if (TREE_CODE (*expr_p
) == CALL_EXPR
)
3706 int flags
= call_expr_flags (*expr_p
);
3707 if (flags
& (ECF_CONST
| ECF_PURE
)
3708 /* An infinite loop is considered a side effect. */
3709 && !(flags
& (ECF_LOOPING_CONST_OR_PURE
)))
3710 TREE_SIDE_EFFECTS (*expr_p
) = 0;
3713 /* If the value is not needed by the caller, emit a new GIMPLE_CALL
3714 and clear *EXPR_P. Otherwise, leave *EXPR_P in its gimplified
3715 form and delegate the creation of a GIMPLE_CALL to
3716 gimplify_modify_expr. This is always possible because when
3717 WANT_VALUE is true, the caller wants the result of this call into
3718 a temporary, which means that we will emit an INIT_EXPR in
3719 internal_get_tmp_var which will then be handled by
3720 gimplify_modify_expr. */
3723 /* The CALL_EXPR in *EXPR_P is already in GIMPLE form, so all we
3724 have to do is replicate it as a GIMPLE_CALL tuple. */
3725 gimple_stmt_iterator gsi
;
3726 call
= gimple_build_call_from_tree (*expr_p
, fnptrtype
);
3727 notice_special_calls (call
);
3728 gimplify_seq_add_stmt (pre_p
, call
);
3729 gsi
= gsi_last (*pre_p
);
3730 maybe_fold_stmt (&gsi
);
3731 *expr_p
= NULL_TREE
;
3734 /* Remember the original function type. */
3735 CALL_EXPR_FN (*expr_p
) = build1 (NOP_EXPR
, fnptrtype
,
3736 CALL_EXPR_FN (*expr_p
));
3741 /* Handle shortcut semantics in the predicate operand of a COND_EXPR by
3742 rewriting it into multiple COND_EXPRs, and possibly GOTO_EXPRs.
3744 TRUE_LABEL_P and FALSE_LABEL_P point to the labels to jump to if the
3745 condition is true or false, respectively. If null, we should generate
3746 our own to skip over the evaluation of this specific expression.
3748 LOCUS is the source location of the COND_EXPR.
3750 This function is the tree equivalent of do_jump.
3752 shortcut_cond_r should only be called by shortcut_cond_expr. */
3755 shortcut_cond_r (tree pred
, tree
*true_label_p
, tree
*false_label_p
,
3758 tree local_label
= NULL_TREE
;
3759 tree t
, expr
= NULL
;
3761 /* OK, it's not a simple case; we need to pull apart the COND_EXPR to
3762 retain the shortcut semantics. Just insert the gotos here;
3763 shortcut_cond_expr will append the real blocks later. */
3764 if (TREE_CODE (pred
) == TRUTH_ANDIF_EXPR
)
3766 location_t new_locus
;
3768 /* Turn if (a && b) into
3770 if (a); else goto no;
3771 if (b) goto yes; else goto no;
3774 if (false_label_p
== NULL
)
3775 false_label_p
= &local_label
;
3777 /* Keep the original source location on the first 'if'. */
3778 t
= shortcut_cond_r (TREE_OPERAND (pred
, 0), NULL
, false_label_p
, locus
);
3779 append_to_statement_list (t
, &expr
);
3781 /* Set the source location of the && on the second 'if'. */
3782 new_locus
= rexpr_location (pred
, locus
);
3783 t
= shortcut_cond_r (TREE_OPERAND (pred
, 1), true_label_p
, false_label_p
,
3785 append_to_statement_list (t
, &expr
);
3787 else if (TREE_CODE (pred
) == TRUTH_ORIF_EXPR
)
3789 location_t new_locus
;
3791 /* Turn if (a || b) into
3794 if (b) goto yes; else goto no;
3797 if (true_label_p
== NULL
)
3798 true_label_p
= &local_label
;
3800 /* Keep the original source location on the first 'if'. */
3801 t
= shortcut_cond_r (TREE_OPERAND (pred
, 0), true_label_p
, NULL
, locus
);
3802 append_to_statement_list (t
, &expr
);
3804 /* Set the source location of the || on the second 'if'. */
3805 new_locus
= rexpr_location (pred
, locus
);
3806 t
= shortcut_cond_r (TREE_OPERAND (pred
, 1), true_label_p
, false_label_p
,
3808 append_to_statement_list (t
, &expr
);
3810 else if (TREE_CODE (pred
) == COND_EXPR
3811 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred
, 1)))
3812 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred
, 2))))
3814 location_t new_locus
;
3816 /* As long as we're messing with gotos, turn if (a ? b : c) into
3818 if (b) goto yes; else goto no;
3820 if (c) goto yes; else goto no;
3822 Don't do this if one of the arms has void type, which can happen
3823 in C++ when the arm is throw. */
3825 /* Keep the original source location on the first 'if'. Set the source
3826 location of the ? on the second 'if'. */
3827 new_locus
= rexpr_location (pred
, locus
);
3828 expr
= build3 (COND_EXPR
, void_type_node
, TREE_OPERAND (pred
, 0),
3829 shortcut_cond_r (TREE_OPERAND (pred
, 1), true_label_p
,
3830 false_label_p
, locus
),
3831 shortcut_cond_r (TREE_OPERAND (pred
, 2), true_label_p
,
3832 false_label_p
, new_locus
));
3836 expr
= build3 (COND_EXPR
, void_type_node
, pred
,
3837 build_and_jump (true_label_p
),
3838 build_and_jump (false_label_p
));
3839 SET_EXPR_LOCATION (expr
, locus
);
3844 t
= build1 (LABEL_EXPR
, void_type_node
, local_label
);
3845 append_to_statement_list (t
, &expr
);
3851 /* If EXPR is a GOTO_EXPR, return it. If it is a STATEMENT_LIST, skip
3852 any of its leading DEBUG_BEGIN_STMTS and recurse on the subsequent
3853 statement, if it is the last one. Otherwise, return NULL. */
3856 find_goto (tree expr
)
3861 if (TREE_CODE (expr
) == GOTO_EXPR
)
3864 if (TREE_CODE (expr
) != STATEMENT_LIST
)
3867 tree_stmt_iterator i
= tsi_start (expr
);
3869 while (!tsi_end_p (i
) && TREE_CODE (tsi_stmt (i
)) == DEBUG_BEGIN_STMT
)
3872 if (!tsi_one_before_end_p (i
))
3875 return find_goto (tsi_stmt (i
));
3878 /* Same as find_goto, except that it returns NULL if the destination
3879 is not a LABEL_DECL. */
3882 find_goto_label (tree expr
)
3884 tree dest
= find_goto (expr
);
3885 if (dest
&& TREE_CODE (GOTO_DESTINATION (dest
)) == LABEL_DECL
)
3890 /* Given a conditional expression EXPR with short-circuit boolean
3891 predicates using TRUTH_ANDIF_EXPR or TRUTH_ORIF_EXPR, break the
3892 predicate apart into the equivalent sequence of conditionals. */
3895 shortcut_cond_expr (tree expr
)
3897 tree pred
= TREE_OPERAND (expr
, 0);
3898 tree then_
= TREE_OPERAND (expr
, 1);
3899 tree else_
= TREE_OPERAND (expr
, 2);
3900 tree true_label
, false_label
, end_label
, t
;
3902 tree
*false_label_p
;
3903 bool emit_end
, emit_false
, jump_over_else
;
3904 bool then_se
= then_
&& TREE_SIDE_EFFECTS (then_
);
3905 bool else_se
= else_
&& TREE_SIDE_EFFECTS (else_
);
3907 /* First do simple transformations. */
3910 /* If there is no 'else', turn
3913 if (a) if (b) then c. */
3914 while (TREE_CODE (pred
) == TRUTH_ANDIF_EXPR
)
3916 /* Keep the original source location on the first 'if'. */
3917 location_t locus
= EXPR_LOC_OR_LOC (expr
, input_location
);
3918 TREE_OPERAND (expr
, 0) = TREE_OPERAND (pred
, 1);
3919 /* Set the source location of the && on the second 'if'. */
3920 if (rexpr_has_location (pred
))
3921 SET_EXPR_LOCATION (expr
, rexpr_location (pred
));
3922 then_
= shortcut_cond_expr (expr
);
3923 then_se
= then_
&& TREE_SIDE_EFFECTS (then_
);
3924 pred
= TREE_OPERAND (pred
, 0);
3925 expr
= build3 (COND_EXPR
, void_type_node
, pred
, then_
, NULL_TREE
);
3926 SET_EXPR_LOCATION (expr
, locus
);
3932 /* If there is no 'then', turn
3935 if (a); else if (b); else d. */
3936 while (TREE_CODE (pred
) == TRUTH_ORIF_EXPR
)
3938 /* Keep the original source location on the first 'if'. */
3939 location_t locus
= EXPR_LOC_OR_LOC (expr
, input_location
);
3940 TREE_OPERAND (expr
, 0) = TREE_OPERAND (pred
, 1);
3941 /* Set the source location of the || on the second 'if'. */
3942 if (rexpr_has_location (pred
))
3943 SET_EXPR_LOCATION (expr
, rexpr_location (pred
));
3944 else_
= shortcut_cond_expr (expr
);
3945 else_se
= else_
&& TREE_SIDE_EFFECTS (else_
);
3946 pred
= TREE_OPERAND (pred
, 0);
3947 expr
= build3 (COND_EXPR
, void_type_node
, pred
, NULL_TREE
, else_
);
3948 SET_EXPR_LOCATION (expr
, locus
);
3952 /* If we're done, great. */
3953 if (TREE_CODE (pred
) != TRUTH_ANDIF_EXPR
3954 && TREE_CODE (pred
) != TRUTH_ORIF_EXPR
)
3957 /* Otherwise we need to mess with gotos. Change
3960 if (a); else goto no;
3963 and recursively gimplify the condition. */
3965 true_label
= false_label
= end_label
= NULL_TREE
;
3967 /* If our arms just jump somewhere, hijack those labels so we don't
3968 generate jumps to jumps. */
3970 if (tree then_goto
= find_goto_label (then_
))
3972 true_label
= GOTO_DESTINATION (then_goto
);
3977 if (tree else_goto
= find_goto_label (else_
))
3979 false_label
= GOTO_DESTINATION (else_goto
);
3984 /* If we aren't hijacking a label for the 'then' branch, it falls through. */
3986 true_label_p
= &true_label
;
3988 true_label_p
= NULL
;
3990 /* The 'else' branch also needs a label if it contains interesting code. */
3991 if (false_label
|| else_se
)
3992 false_label_p
= &false_label
;
3994 false_label_p
= NULL
;
3996 /* If there was nothing else in our arms, just forward the label(s). */
3997 if (!then_se
&& !else_se
)
3998 return shortcut_cond_r (pred
, true_label_p
, false_label_p
,
3999 EXPR_LOC_OR_LOC (expr
, input_location
));
4001 /* If our last subexpression already has a terminal label, reuse it. */
4003 t
= expr_last (else_
);
4005 t
= expr_last (then_
);
4008 if (t
&& TREE_CODE (t
) == LABEL_EXPR
)
4009 end_label
= LABEL_EXPR_LABEL (t
);
4011 /* If we don't care about jumping to the 'else' branch, jump to the end
4012 if the condition is false. */
4014 false_label_p
= &end_label
;
4016 /* We only want to emit these labels if we aren't hijacking them. */
4017 emit_end
= (end_label
== NULL_TREE
);
4018 emit_false
= (false_label
== NULL_TREE
);
4020 /* We only emit the jump over the else clause if we have to--if the
4021 then clause may fall through. Otherwise we can wind up with a
4022 useless jump and a useless label at the end of gimplified code,
4023 which will cause us to think that this conditional as a whole
4024 falls through even if it doesn't. If we then inline a function
4025 which ends with such a condition, that can cause us to issue an
4026 inappropriate warning about control reaching the end of a
4027 non-void function. */
4028 jump_over_else
= block_may_fallthru (then_
);
4030 pred
= shortcut_cond_r (pred
, true_label_p
, false_label_p
,
4031 EXPR_LOC_OR_LOC (expr
, input_location
));
4034 append_to_statement_list (pred
, &expr
);
4036 append_to_statement_list (then_
, &expr
);
4041 tree last
= expr_last (expr
);
4042 t
= build_and_jump (&end_label
);
4043 if (rexpr_has_location (last
))
4044 SET_EXPR_LOCATION (t
, rexpr_location (last
));
4045 append_to_statement_list (t
, &expr
);
4049 t
= build1 (LABEL_EXPR
, void_type_node
, false_label
);
4050 append_to_statement_list (t
, &expr
);
4052 append_to_statement_list (else_
, &expr
);
4054 if (emit_end
&& end_label
)
4056 t
= build1 (LABEL_EXPR
, void_type_node
, end_label
);
4057 append_to_statement_list (t
, &expr
);
4063 /* EXPR is used in a boolean context; make sure it has BOOLEAN_TYPE. */
4066 gimple_boolify (tree expr
)
4068 tree type
= TREE_TYPE (expr
);
4069 location_t loc
= EXPR_LOCATION (expr
);
4071 if (TREE_CODE (expr
) == NE_EXPR
4072 && TREE_CODE (TREE_OPERAND (expr
, 0)) == CALL_EXPR
4073 && integer_zerop (TREE_OPERAND (expr
, 1)))
4075 tree call
= TREE_OPERAND (expr
, 0);
4076 tree fn
= get_callee_fndecl (call
);
4078 /* For __builtin_expect ((long) (x), y) recurse into x as well
4079 if x is truth_value_p. */
4081 && fndecl_built_in_p (fn
, BUILT_IN_EXPECT
)
4082 && call_expr_nargs (call
) == 2)
4084 tree arg
= CALL_EXPR_ARG (call
, 0);
4087 if (TREE_CODE (arg
) == NOP_EXPR
4088 && TREE_TYPE (arg
) == TREE_TYPE (call
))
4089 arg
= TREE_OPERAND (arg
, 0);
4090 if (truth_value_p (TREE_CODE (arg
)))
4092 arg
= gimple_boolify (arg
);
4093 CALL_EXPR_ARG (call
, 0)
4094 = fold_convert_loc (loc
, TREE_TYPE (call
), arg
);
4100 switch (TREE_CODE (expr
))
4102 case TRUTH_AND_EXPR
:
4104 case TRUTH_XOR_EXPR
:
4105 case TRUTH_ANDIF_EXPR
:
4106 case TRUTH_ORIF_EXPR
:
4107 /* Also boolify the arguments of truth exprs. */
4108 TREE_OPERAND (expr
, 1) = gimple_boolify (TREE_OPERAND (expr
, 1));
4111 case TRUTH_NOT_EXPR
:
4112 TREE_OPERAND (expr
, 0) = gimple_boolify (TREE_OPERAND (expr
, 0));
4114 /* These expressions always produce boolean results. */
4115 if (TREE_CODE (type
) != BOOLEAN_TYPE
)
4116 TREE_TYPE (expr
) = boolean_type_node
;
4120 switch ((enum annot_expr_kind
) TREE_INT_CST_LOW (TREE_OPERAND (expr
, 1)))
4122 case annot_expr_ivdep_kind
:
4123 case annot_expr_unroll_kind
:
4124 case annot_expr_no_vector_kind
:
4125 case annot_expr_vector_kind
:
4126 case annot_expr_parallel_kind
:
4127 TREE_OPERAND (expr
, 0) = gimple_boolify (TREE_OPERAND (expr
, 0));
4128 if (TREE_CODE (type
) != BOOLEAN_TYPE
)
4129 TREE_TYPE (expr
) = boolean_type_node
;
4136 if (COMPARISON_CLASS_P (expr
))
4138 /* There expressions always prduce boolean results. */
4139 if (TREE_CODE (type
) != BOOLEAN_TYPE
)
4140 TREE_TYPE (expr
) = boolean_type_node
;
4143 /* Other expressions that get here must have boolean values, but
4144 might need to be converted to the appropriate mode. */
4145 if (TREE_CODE (type
) == BOOLEAN_TYPE
)
4147 return fold_convert_loc (loc
, boolean_type_node
, expr
);
4151 /* Given a conditional expression *EXPR_P without side effects, gimplify
4152 its operands. New statements are inserted to PRE_P. */
4154 static enum gimplify_status
4155 gimplify_pure_cond_expr (tree
*expr_p
, gimple_seq
*pre_p
)
4157 tree expr
= *expr_p
, cond
;
4158 enum gimplify_status ret
, tret
;
4159 enum tree_code code
;
4161 cond
= gimple_boolify (COND_EXPR_COND (expr
));
4163 /* We need to handle && and || specially, as their gimplification
4164 creates pure cond_expr, thus leading to an infinite cycle otherwise. */
4165 code
= TREE_CODE (cond
);
4166 if (code
== TRUTH_ANDIF_EXPR
)
4167 TREE_SET_CODE (cond
, TRUTH_AND_EXPR
);
4168 else if (code
== TRUTH_ORIF_EXPR
)
4169 TREE_SET_CODE (cond
, TRUTH_OR_EXPR
);
4170 ret
= gimplify_expr (&cond
, pre_p
, NULL
, is_gimple_condexpr
, fb_rvalue
);
4171 COND_EXPR_COND (*expr_p
) = cond
;
4173 tret
= gimplify_expr (&COND_EXPR_THEN (expr
), pre_p
, NULL
,
4174 is_gimple_val
, fb_rvalue
);
4175 ret
= MIN (ret
, tret
);
4176 tret
= gimplify_expr (&COND_EXPR_ELSE (expr
), pre_p
, NULL
,
4177 is_gimple_val
, fb_rvalue
);
4179 return MIN (ret
, tret
);
4182 /* Return true if evaluating EXPR could trap.
4183 EXPR is GENERIC, while tree_could_trap_p can be called
4187 generic_expr_could_trap_p (tree expr
)
4191 if (!expr
|| is_gimple_val (expr
))
4194 if (!EXPR_P (expr
) || tree_could_trap_p (expr
))
4197 n
= TREE_OPERAND_LENGTH (expr
);
4198 for (i
= 0; i
< n
; i
++)
4199 if (generic_expr_could_trap_p (TREE_OPERAND (expr
, i
)))
4205 /* Convert the conditional expression pointed to by EXPR_P '(p) ? a : b;'
4214 The second form is used when *EXPR_P is of type void.
4216 PRE_P points to the list where side effects that must happen before
4217 *EXPR_P should be stored. */
4219 static enum gimplify_status
4220 gimplify_cond_expr (tree
*expr_p
, gimple_seq
*pre_p
, fallback_t fallback
)
4222 tree expr
= *expr_p
;
4223 tree type
= TREE_TYPE (expr
);
4224 location_t loc
= EXPR_LOCATION (expr
);
4225 tree tmp
, arm1
, arm2
;
4226 enum gimplify_status ret
;
4227 tree label_true
, label_false
, label_cont
;
4228 bool have_then_clause_p
, have_else_clause_p
;
4230 enum tree_code pred_code
;
4231 gimple_seq seq
= NULL
;
4233 /* If this COND_EXPR has a value, copy the values into a temporary within
4235 if (!VOID_TYPE_P (type
))
4237 tree then_
= TREE_OPERAND (expr
, 1), else_
= TREE_OPERAND (expr
, 2);
4240 /* If either an rvalue is ok or we do not require an lvalue, create the
4241 temporary. But we cannot do that if the type is addressable. */
4242 if (((fallback
& fb_rvalue
) || !(fallback
& fb_lvalue
))
4243 && !TREE_ADDRESSABLE (type
))
4245 if (gimplify_ctxp
->allow_rhs_cond_expr
4246 /* If either branch has side effects or could trap, it can't be
4247 evaluated unconditionally. */
4248 && !TREE_SIDE_EFFECTS (then_
)
4249 && !generic_expr_could_trap_p (then_
)
4250 && !TREE_SIDE_EFFECTS (else_
)
4251 && !generic_expr_could_trap_p (else_
))
4252 return gimplify_pure_cond_expr (expr_p
, pre_p
);
4254 tmp
= create_tmp_var (type
, "iftmp");
4258 /* Otherwise, only create and copy references to the values. */
4261 type
= build_pointer_type (type
);
4263 if (!VOID_TYPE_P (TREE_TYPE (then_
)))
4264 then_
= build_fold_addr_expr_loc (loc
, then_
);
4266 if (!VOID_TYPE_P (TREE_TYPE (else_
)))
4267 else_
= build_fold_addr_expr_loc (loc
, else_
);
4270 = build3 (COND_EXPR
, type
, TREE_OPERAND (expr
, 0), then_
, else_
);
4272 tmp
= create_tmp_var (type
, "iftmp");
4273 result
= build_simple_mem_ref_loc (loc
, tmp
);
4276 /* Build the new then clause, `tmp = then_;'. But don't build the
4277 assignment if the value is void; in C++ it can be if it's a throw. */
4278 if (!VOID_TYPE_P (TREE_TYPE (then_
)))
4279 TREE_OPERAND (expr
, 1) = build2 (INIT_EXPR
, type
, tmp
, then_
);
4281 /* Similarly, build the new else clause, `tmp = else_;'. */
4282 if (!VOID_TYPE_P (TREE_TYPE (else_
)))
4283 TREE_OPERAND (expr
, 2) = build2 (INIT_EXPR
, type
, tmp
, else_
);
4285 TREE_TYPE (expr
) = void_type_node
;
4286 recalculate_side_effects (expr
);
4288 /* Move the COND_EXPR to the prequeue. */
4289 gimplify_stmt (&expr
, pre_p
);
4295 /* Remove any COMPOUND_EXPR so the following cases will be caught. */
4296 STRIP_TYPE_NOPS (TREE_OPERAND (expr
, 0));
4297 if (TREE_CODE (TREE_OPERAND (expr
, 0)) == COMPOUND_EXPR
)
4298 gimplify_compound_expr (&TREE_OPERAND (expr
, 0), pre_p
, true);
4300 /* Make sure the condition has BOOLEAN_TYPE. */
4301 TREE_OPERAND (expr
, 0) = gimple_boolify (TREE_OPERAND (expr
, 0));
4303 /* Break apart && and || conditions. */
4304 if (TREE_CODE (TREE_OPERAND (expr
, 0)) == TRUTH_ANDIF_EXPR
4305 || TREE_CODE (TREE_OPERAND (expr
, 0)) == TRUTH_ORIF_EXPR
)
4307 expr
= shortcut_cond_expr (expr
);
4309 if (expr
!= *expr_p
)
4313 /* We can't rely on gimplify_expr to re-gimplify the expanded
4314 form properly, as cleanups might cause the target labels to be
4315 wrapped in a TRY_FINALLY_EXPR. To prevent that, we need to
4316 set up a conditional context. */
4317 gimple_push_condition ();
4318 gimplify_stmt (expr_p
, &seq
);
4319 gimple_pop_condition (pre_p
);
4320 gimple_seq_add_seq (pre_p
, seq
);
4326 /* Now do the normal gimplification. */
4328 /* Gimplify condition. */
4329 ret
= gimplify_expr (&TREE_OPERAND (expr
, 0), pre_p
, NULL
,
4330 is_gimple_condexpr_for_cond
, fb_rvalue
);
4331 if (ret
== GS_ERROR
)
4333 gcc_assert (TREE_OPERAND (expr
, 0) != NULL_TREE
);
4335 gimple_push_condition ();
4337 have_then_clause_p
= have_else_clause_p
= false;
4338 label_true
= find_goto_label (TREE_OPERAND (expr
, 1));
4340 && DECL_CONTEXT (GOTO_DESTINATION (label_true
)) == current_function_decl
4341 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4342 have different locations, otherwise we end up with incorrect
4343 location information on the branches. */
4345 || !EXPR_HAS_LOCATION (expr
)
4346 || !rexpr_has_location (label_true
)
4347 || EXPR_LOCATION (expr
) == rexpr_location (label_true
)))
4349 have_then_clause_p
= true;
4350 label_true
= GOTO_DESTINATION (label_true
);
4353 label_true
= create_artificial_label (UNKNOWN_LOCATION
);
4354 label_false
= find_goto_label (TREE_OPERAND (expr
, 2));
4356 && DECL_CONTEXT (GOTO_DESTINATION (label_false
)) == current_function_decl
4357 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4358 have different locations, otherwise we end up with incorrect
4359 location information on the branches. */
4361 || !EXPR_HAS_LOCATION (expr
)
4362 || !rexpr_has_location (label_false
)
4363 || EXPR_LOCATION (expr
) == rexpr_location (label_false
)))
4365 have_else_clause_p
= true;
4366 label_false
= GOTO_DESTINATION (label_false
);
4369 label_false
= create_artificial_label (UNKNOWN_LOCATION
);
4371 gimple_cond_get_ops_from_tree (COND_EXPR_COND (expr
), &pred_code
, &arm1
,
4373 cond_stmt
= gimple_build_cond (pred_code
, arm1
, arm2
, label_true
,
4375 gimple_set_location (cond_stmt
, EXPR_LOCATION (expr
));
4376 copy_warning (cond_stmt
, COND_EXPR_COND (expr
));
4377 gimplify_seq_add_stmt (&seq
, cond_stmt
);
4378 gimple_stmt_iterator gsi
= gsi_last (seq
);
4379 maybe_fold_stmt (&gsi
);
4381 label_cont
= NULL_TREE
;
4382 if (!have_then_clause_p
)
4384 /* For if (...) {} else { code; } put label_true after
4386 if (TREE_OPERAND (expr
, 1) == NULL_TREE
4387 && !have_else_clause_p
4388 && TREE_OPERAND (expr
, 2) != NULL_TREE
)
4389 label_cont
= label_true
;
4392 gimplify_seq_add_stmt (&seq
, gimple_build_label (label_true
));
4393 have_then_clause_p
= gimplify_stmt (&TREE_OPERAND (expr
, 1), &seq
);
4394 /* For if (...) { code; } else {} or
4395 if (...) { code; } else goto label; or
4396 if (...) { code; return; } else { ... }
4397 label_cont isn't needed. */
4398 if (!have_else_clause_p
4399 && TREE_OPERAND (expr
, 2) != NULL_TREE
4400 && gimple_seq_may_fallthru (seq
))
4403 label_cont
= create_artificial_label (UNKNOWN_LOCATION
);
4405 g
= gimple_build_goto (label_cont
);
4407 /* GIMPLE_COND's are very low level; they have embedded
4408 gotos. This particular embedded goto should not be marked
4409 with the location of the original COND_EXPR, as it would
4410 correspond to the COND_EXPR's condition, not the ELSE or the
4411 THEN arms. To avoid marking it with the wrong location, flag
4412 it as "no location". */
4413 gimple_set_do_not_emit_location (g
);
4415 gimplify_seq_add_stmt (&seq
, g
);
4419 if (!have_else_clause_p
)
4421 gimplify_seq_add_stmt (&seq
, gimple_build_label (label_false
));
4422 have_else_clause_p
= gimplify_stmt (&TREE_OPERAND (expr
, 2), &seq
);
4425 gimplify_seq_add_stmt (&seq
, gimple_build_label (label_cont
));
4427 gimple_pop_condition (pre_p
);
4428 gimple_seq_add_seq (pre_p
, seq
);
4430 if (ret
== GS_ERROR
)
4432 else if (have_then_clause_p
|| have_else_clause_p
)
4436 /* Both arms are empty; replace the COND_EXPR with its predicate. */
4437 expr
= TREE_OPERAND (expr
, 0);
4438 gimplify_stmt (&expr
, pre_p
);
4445 /* Prepare the node pointed to by EXPR_P, an is_gimple_addressable expression,
4446 to be marked addressable.
4448 We cannot rely on such an expression being directly markable if a temporary
4449 has been created by the gimplification. In this case, we create another
4450 temporary and initialize it with a copy, which will become a store after we
4451 mark it addressable. This can happen if the front-end passed us something
4452 that it could not mark addressable yet, like a Fortran pass-by-reference
4453 parameter (int) floatvar. */
4456 prepare_gimple_addressable (tree
*expr_p
, gimple_seq
*seq_p
)
4458 while (handled_component_p (*expr_p
))
4459 expr_p
= &TREE_OPERAND (*expr_p
, 0);
4460 if (is_gimple_reg (*expr_p
))
4462 /* Do not allow an SSA name as the temporary. */
4463 tree var
= get_initialized_tmp_var (*expr_p
, seq_p
, NULL
, false);
4464 DECL_NOT_GIMPLE_REG_P (var
) = 1;
4469 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4470 a call to __builtin_memcpy. */
4472 static enum gimplify_status
4473 gimplify_modify_expr_to_memcpy (tree
*expr_p
, tree size
, bool want_value
,
4476 tree t
, to
, to_ptr
, from
, from_ptr
;
4478 location_t loc
= EXPR_LOCATION (*expr_p
);
4480 to
= TREE_OPERAND (*expr_p
, 0);
4481 from
= TREE_OPERAND (*expr_p
, 1);
4483 /* Mark the RHS addressable. Beware that it may not be possible to do so
4484 directly if a temporary has been created by the gimplification. */
4485 prepare_gimple_addressable (&from
, seq_p
);
4487 mark_addressable (from
);
4488 from_ptr
= build_fold_addr_expr_loc (loc
, from
);
4489 gimplify_arg (&from_ptr
, seq_p
, loc
);
4491 mark_addressable (to
);
4492 to_ptr
= build_fold_addr_expr_loc (loc
, to
);
4493 gimplify_arg (&to_ptr
, seq_p
, loc
);
4495 t
= builtin_decl_implicit (BUILT_IN_MEMCPY
);
4497 gs
= gimple_build_call (t
, 3, to_ptr
, from_ptr
, size
);
4498 gimple_call_set_alloca_for_var (gs
, true);
4502 /* tmp = memcpy() */
4503 t
= create_tmp_var (TREE_TYPE (to_ptr
));
4504 gimple_call_set_lhs (gs
, t
);
4505 gimplify_seq_add_stmt (seq_p
, gs
);
4507 *expr_p
= build_simple_mem_ref (t
);
4511 gimplify_seq_add_stmt (seq_p
, gs
);
4516 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4517 a call to __builtin_memset. In this case we know that the RHS is
4518 a CONSTRUCTOR with an empty element list. */
4520 static enum gimplify_status
4521 gimplify_modify_expr_to_memset (tree
*expr_p
, tree size
, bool want_value
,
4524 tree t
, from
, to
, to_ptr
;
4526 location_t loc
= EXPR_LOCATION (*expr_p
);
4528 /* Assert our assumptions, to abort instead of producing wrong code
4529 silently if they are not met. Beware that the RHS CONSTRUCTOR might
4530 not be immediately exposed. */
4531 from
= TREE_OPERAND (*expr_p
, 1);
4532 if (TREE_CODE (from
) == WITH_SIZE_EXPR
)
4533 from
= TREE_OPERAND (from
, 0);
4535 gcc_assert (TREE_CODE (from
) == CONSTRUCTOR
4536 && vec_safe_is_empty (CONSTRUCTOR_ELTS (from
)));
4539 to
= TREE_OPERAND (*expr_p
, 0);
4541 to_ptr
= build_fold_addr_expr_loc (loc
, to
);
4542 gimplify_arg (&to_ptr
, seq_p
, loc
);
4543 t
= builtin_decl_implicit (BUILT_IN_MEMSET
);
4545 gs
= gimple_build_call (t
, 3, to_ptr
, integer_zero_node
, size
);
4549 /* tmp = memset() */
4550 t
= create_tmp_var (TREE_TYPE (to_ptr
));
4551 gimple_call_set_lhs (gs
, t
);
4552 gimplify_seq_add_stmt (seq_p
, gs
);
4554 *expr_p
= build1 (INDIRECT_REF
, TREE_TYPE (to
), t
);
4558 gimplify_seq_add_stmt (seq_p
, gs
);
4563 /* A subroutine of gimplify_init_ctor_preeval. Called via walk_tree,
4564 determine, cautiously, if a CONSTRUCTOR overlaps the lhs of an
4565 assignment. Return non-null if we detect a potential overlap. */
4567 struct gimplify_init_ctor_preeval_data
4569 /* The base decl of the lhs object. May be NULL, in which case we
4570 have to assume the lhs is indirect. */
4573 /* The alias set of the lhs object. */
4574 alias_set_type lhs_alias_set
;
4578 gimplify_init_ctor_preeval_1 (tree
*tp
, int *walk_subtrees
, void *xdata
)
4580 struct gimplify_init_ctor_preeval_data
*data
4581 = (struct gimplify_init_ctor_preeval_data
*) xdata
;
4584 /* If we find the base object, obviously we have overlap. */
4585 if (data
->lhs_base_decl
== t
)
4588 /* If the constructor component is indirect, determine if we have a
4589 potential overlap with the lhs. The only bits of information we
4590 have to go on at this point are addressability and alias sets. */
4591 if ((INDIRECT_REF_P (t
)
4592 || TREE_CODE (t
) == MEM_REF
)
4593 && (!data
->lhs_base_decl
|| TREE_ADDRESSABLE (data
->lhs_base_decl
))
4594 && alias_sets_conflict_p (data
->lhs_alias_set
, get_alias_set (t
)))
4597 /* If the constructor component is a call, determine if it can hide a
4598 potential overlap with the lhs through an INDIRECT_REF like above.
4599 ??? Ugh - this is completely broken. In fact this whole analysis
4600 doesn't look conservative. */
4601 if (TREE_CODE (t
) == CALL_EXPR
)
4603 tree type
, fntype
= TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (t
)));
4605 for (type
= TYPE_ARG_TYPES (fntype
); type
; type
= TREE_CHAIN (type
))
4606 if (POINTER_TYPE_P (TREE_VALUE (type
))
4607 && (!data
->lhs_base_decl
|| TREE_ADDRESSABLE (data
->lhs_base_decl
))
4608 && alias_sets_conflict_p (data
->lhs_alias_set
,
4610 (TREE_TYPE (TREE_VALUE (type
)))))
4614 if (IS_TYPE_OR_DECL_P (t
))
4619 /* A subroutine of gimplify_init_constructor. Pre-evaluate EXPR,
4620 force values that overlap with the lhs (as described by *DATA)
4621 into temporaries. */
4624 gimplify_init_ctor_preeval (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
4625 struct gimplify_init_ctor_preeval_data
*data
)
4627 enum gimplify_status one
;
4629 /* If the value is constant, then there's nothing to pre-evaluate. */
4630 if (TREE_CONSTANT (*expr_p
))
4632 /* Ensure it does not have side effects, it might contain a reference to
4633 the object we're initializing. */
4634 gcc_assert (!TREE_SIDE_EFFECTS (*expr_p
));
4638 /* If the type has non-trivial constructors, we can't pre-evaluate. */
4639 if (TREE_ADDRESSABLE (TREE_TYPE (*expr_p
)))
4642 /* Recurse for nested constructors. */
4643 if (TREE_CODE (*expr_p
) == CONSTRUCTOR
)
4645 unsigned HOST_WIDE_INT ix
;
4646 constructor_elt
*ce
;
4647 vec
<constructor_elt
, va_gc
> *v
= CONSTRUCTOR_ELTS (*expr_p
);
4649 FOR_EACH_VEC_SAFE_ELT (v
, ix
, ce
)
4650 gimplify_init_ctor_preeval (&ce
->value
, pre_p
, post_p
, data
);
4655 /* If this is a variable sized type, we must remember the size. */
4656 maybe_with_size_expr (expr_p
);
4658 /* Gimplify the constructor element to something appropriate for the rhs
4659 of a MODIFY_EXPR. Given that we know the LHS is an aggregate, we know
4660 the gimplifier will consider this a store to memory. Doing this
4661 gimplification now means that we won't have to deal with complicated
4662 language-specific trees, nor trees like SAVE_EXPR that can induce
4663 exponential search behavior. */
4664 one
= gimplify_expr (expr_p
, pre_p
, post_p
, is_gimple_mem_rhs
, fb_rvalue
);
4665 if (one
== GS_ERROR
)
4671 /* If we gimplified to a bare decl, we can be sure that it doesn't overlap
4672 with the lhs, since "a = { .x=a }" doesn't make sense. This will
4673 always be true for all scalars, since is_gimple_mem_rhs insists on a
4674 temporary variable for them. */
4675 if (DECL_P (*expr_p
))
4678 /* If this is of variable size, we have no choice but to assume it doesn't
4679 overlap since we can't make a temporary for it. */
4680 if (TREE_CODE (TYPE_SIZE (TREE_TYPE (*expr_p
))) != INTEGER_CST
)
4683 /* Otherwise, we must search for overlap ... */
4684 if (!walk_tree (expr_p
, gimplify_init_ctor_preeval_1
, data
, NULL
))
4687 /* ... and if found, force the value into a temporary. */
4688 *expr_p
= get_formal_tmp_var (*expr_p
, pre_p
);
4691 /* A subroutine of gimplify_init_ctor_eval. Create a loop for
4692 a RANGE_EXPR in a CONSTRUCTOR for an array.
4696 object[var] = value;
4703 We increment var _after_ the loop exit check because we might otherwise
4704 fail if upper == TYPE_MAX_VALUE (type for upper).
4706 Note that we never have to deal with SAVE_EXPRs here, because this has
4707 already been taken care of for us, in gimplify_init_ctor_preeval(). */
4709 static void gimplify_init_ctor_eval (tree
, vec
<constructor_elt
, va_gc
> *,
4710 gimple_seq
*, bool);
4713 gimplify_init_ctor_eval_range (tree object
, tree lower
, tree upper
,
4714 tree value
, tree array_elt_type
,
4715 gimple_seq
*pre_p
, bool cleared
)
4717 tree loop_entry_label
, loop_exit_label
, fall_thru_label
;
4718 tree var
, var_type
, cref
, tmp
;
4720 loop_entry_label
= create_artificial_label (UNKNOWN_LOCATION
);
4721 loop_exit_label
= create_artificial_label (UNKNOWN_LOCATION
);
4722 fall_thru_label
= create_artificial_label (UNKNOWN_LOCATION
);
4724 /* Create and initialize the index variable. */
4725 var_type
= TREE_TYPE (upper
);
4726 var
= create_tmp_var (var_type
);
4727 gimplify_seq_add_stmt (pre_p
, gimple_build_assign (var
, lower
));
4729 /* Add the loop entry label. */
4730 gimplify_seq_add_stmt (pre_p
, gimple_build_label (loop_entry_label
));
4732 /* Build the reference. */
4733 cref
= build4 (ARRAY_REF
, array_elt_type
, unshare_expr (object
),
4734 var
, NULL_TREE
, NULL_TREE
);
4736 /* If we are a constructor, just call gimplify_init_ctor_eval to do
4737 the store. Otherwise just assign value to the reference. */
4739 if (TREE_CODE (value
) == CONSTRUCTOR
)
4740 /* NB we might have to call ourself recursively through
4741 gimplify_init_ctor_eval if the value is a constructor. */
4742 gimplify_init_ctor_eval (cref
, CONSTRUCTOR_ELTS (value
),
4746 if (gimplify_expr (&value
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
)
4748 gimplify_seq_add_stmt (pre_p
, gimple_build_assign (cref
, value
));
4751 /* We exit the loop when the index var is equal to the upper bound. */
4752 gimplify_seq_add_stmt (pre_p
,
4753 gimple_build_cond (EQ_EXPR
, var
, upper
,
4754 loop_exit_label
, fall_thru_label
));
4756 gimplify_seq_add_stmt (pre_p
, gimple_build_label (fall_thru_label
));
4758 /* Otherwise, increment the index var... */
4759 tmp
= build2 (PLUS_EXPR
, var_type
, var
,
4760 fold_convert (var_type
, integer_one_node
));
4761 gimplify_seq_add_stmt (pre_p
, gimple_build_assign (var
, tmp
));
4763 /* ...and jump back to the loop entry. */
4764 gimplify_seq_add_stmt (pre_p
, gimple_build_goto (loop_entry_label
));
4766 /* Add the loop exit label. */
4767 gimplify_seq_add_stmt (pre_p
, gimple_build_label (loop_exit_label
));
4770 /* A subroutine of gimplify_init_constructor. Generate individual
4771 MODIFY_EXPRs for a CONSTRUCTOR. OBJECT is the LHS against which the
4772 assignments should happen. ELTS is the CONSTRUCTOR_ELTS of the
4773 CONSTRUCTOR. CLEARED is true if the entire LHS object has been
4777 gimplify_init_ctor_eval (tree object
, vec
<constructor_elt
, va_gc
> *elts
,
4778 gimple_seq
*pre_p
, bool cleared
)
4780 tree array_elt_type
= NULL
;
4781 unsigned HOST_WIDE_INT ix
;
4782 tree purpose
, value
;
4784 if (TREE_CODE (TREE_TYPE (object
)) == ARRAY_TYPE
)
4785 array_elt_type
= TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (object
)));
4787 FOR_EACH_CONSTRUCTOR_ELT (elts
, ix
, purpose
, value
)
4791 /* NULL values are created above for gimplification errors. */
4795 if (cleared
&& initializer_zerop (value
))
4798 /* ??? Here's to hoping the front end fills in all of the indices,
4799 so we don't have to figure out what's missing ourselves. */
4800 gcc_assert (purpose
);
4802 /* Skip zero-sized fields, unless value has side-effects. This can
4803 happen with calls to functions returning a empty type, which
4804 we shouldn't discard. As a number of downstream passes don't
4805 expect sets of empty type fields, we rely on the gimplification of
4806 the MODIFY_EXPR we make below to drop the assignment statement. */
4807 if (!TREE_SIDE_EFFECTS (value
)
4808 && TREE_CODE (purpose
) == FIELD_DECL
4809 && is_empty_type (TREE_TYPE (purpose
)))
4812 /* If we have a RANGE_EXPR, we have to build a loop to assign the
4814 if (TREE_CODE (purpose
) == RANGE_EXPR
)
4816 tree lower
= TREE_OPERAND (purpose
, 0);
4817 tree upper
= TREE_OPERAND (purpose
, 1);
4819 /* If the lower bound is equal to upper, just treat it as if
4820 upper was the index. */
4821 if (simple_cst_equal (lower
, upper
))
4825 gimplify_init_ctor_eval_range (object
, lower
, upper
, value
,
4826 array_elt_type
, pre_p
, cleared
);
4833 /* Do not use bitsizetype for ARRAY_REF indices. */
4834 if (TYPE_DOMAIN (TREE_TYPE (object
)))
4836 = fold_convert (TREE_TYPE (TYPE_DOMAIN (TREE_TYPE (object
))),
4838 cref
= build4 (ARRAY_REF
, array_elt_type
, unshare_expr (object
),
4839 purpose
, NULL_TREE
, NULL_TREE
);
4843 gcc_assert (TREE_CODE (purpose
) == FIELD_DECL
);
4844 cref
= build3 (COMPONENT_REF
, TREE_TYPE (purpose
),
4845 unshare_expr (object
), purpose
, NULL_TREE
);
4848 if (TREE_CODE (value
) == CONSTRUCTOR
4849 && TREE_CODE (TREE_TYPE (value
)) != VECTOR_TYPE
)
4850 gimplify_init_ctor_eval (cref
, CONSTRUCTOR_ELTS (value
),
4854 tree init
= build2 (INIT_EXPR
, TREE_TYPE (cref
), cref
, value
);
4855 gimplify_and_add (init
, pre_p
);
4861 /* Return the appropriate RHS predicate for this LHS. */
4864 rhs_predicate_for (tree lhs
)
4866 if (is_gimple_reg (lhs
))
4867 return is_gimple_reg_rhs_or_call
;
4869 return is_gimple_mem_rhs_or_call
;
4872 /* Return the initial guess for an appropriate RHS predicate for this LHS,
4873 before the LHS has been gimplified. */
4875 static gimple_predicate
4876 initial_rhs_predicate_for (tree lhs
)
4878 if (is_gimple_reg_type (TREE_TYPE (lhs
)))
4879 return is_gimple_reg_rhs_or_call
;
4881 return is_gimple_mem_rhs_or_call
;
4884 /* Gimplify a C99 compound literal expression. This just means adding
4885 the DECL_EXPR before the current statement and using its anonymous
4888 static enum gimplify_status
4889 gimplify_compound_literal_expr (tree
*expr_p
, gimple_seq
*pre_p
,
4890 bool (*gimple_test_f
) (tree
),
4891 fallback_t fallback
)
4893 tree decl_s
= COMPOUND_LITERAL_EXPR_DECL_EXPR (*expr_p
);
4894 tree decl
= DECL_EXPR_DECL (decl_s
);
4895 tree init
= DECL_INITIAL (decl
);
4896 /* Mark the decl as addressable if the compound literal
4897 expression is addressable now, otherwise it is marked too late
4898 after we gimplify the initialization expression. */
4899 if (TREE_ADDRESSABLE (*expr_p
))
4900 TREE_ADDRESSABLE (decl
) = 1;
4901 /* Otherwise, if we don't need an lvalue and have a literal directly
4902 substitute it. Check if it matches the gimple predicate, as
4903 otherwise we'd generate a new temporary, and we can as well just
4904 use the decl we already have. */
4905 else if (!TREE_ADDRESSABLE (decl
)
4906 && !TREE_THIS_VOLATILE (decl
)
4908 && (fallback
& fb_lvalue
) == 0
4909 && gimple_test_f (init
))
4915 /* If the decl is not addressable, then it is being used in some
4916 expression or on the right hand side of a statement, and it can
4917 be put into a readonly data section. */
4918 if (!TREE_ADDRESSABLE (decl
) && (fallback
& fb_lvalue
) == 0)
4919 TREE_READONLY (decl
) = 1;
4921 /* This decl isn't mentioned in the enclosing block, so add it to the
4922 list of temps. FIXME it seems a bit of a kludge to say that
4923 anonymous artificial vars aren't pushed, but everything else is. */
4924 if (DECL_NAME (decl
) == NULL_TREE
&& !DECL_SEEN_IN_BIND_EXPR_P (decl
))
4925 gimple_add_tmp_var (decl
);
4927 gimplify_and_add (decl_s
, pre_p
);
4932 /* Optimize embedded COMPOUND_LITERAL_EXPRs within a CONSTRUCTOR,
4933 return a new CONSTRUCTOR if something changed. */
4936 optimize_compound_literals_in_ctor (tree orig_ctor
)
4938 tree ctor
= orig_ctor
;
4939 vec
<constructor_elt
, va_gc
> *elts
= CONSTRUCTOR_ELTS (ctor
);
4940 unsigned int idx
, num
= vec_safe_length (elts
);
4942 for (idx
= 0; idx
< num
; idx
++)
4944 tree value
= (*elts
)[idx
].value
;
4945 tree newval
= value
;
4946 if (TREE_CODE (value
) == CONSTRUCTOR
)
4947 newval
= optimize_compound_literals_in_ctor (value
);
4948 else if (TREE_CODE (value
) == COMPOUND_LITERAL_EXPR
)
4950 tree decl_s
= COMPOUND_LITERAL_EXPR_DECL_EXPR (value
);
4951 tree decl
= DECL_EXPR_DECL (decl_s
);
4952 tree init
= DECL_INITIAL (decl
);
4954 if (!TREE_ADDRESSABLE (value
)
4955 && !TREE_ADDRESSABLE (decl
)
4957 && TREE_CODE (init
) == CONSTRUCTOR
)
4958 newval
= optimize_compound_literals_in_ctor (init
);
4960 if (newval
== value
)
4963 if (ctor
== orig_ctor
)
4965 ctor
= copy_node (orig_ctor
);
4966 CONSTRUCTOR_ELTS (ctor
) = vec_safe_copy (elts
);
4967 elts
= CONSTRUCTOR_ELTS (ctor
);
4969 (*elts
)[idx
].value
= newval
;
4974 /* A subroutine of gimplify_modify_expr. Break out elements of a
4975 CONSTRUCTOR used as an initializer into separate MODIFY_EXPRs.
4977 Note that we still need to clear any elements that don't have explicit
4978 initializers, so if not all elements are initialized we keep the
4979 original MODIFY_EXPR, we just remove all of the constructor elements.
4981 If NOTIFY_TEMP_CREATION is true, do not gimplify, just return
4982 GS_ERROR if we would have to create a temporary when gimplifying
4983 this constructor. Otherwise, return GS_OK.
4985 If NOTIFY_TEMP_CREATION is false, just do the gimplification. */
4987 static enum gimplify_status
4988 gimplify_init_constructor (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
4989 bool want_value
, bool notify_temp_creation
)
4991 tree object
, ctor
, type
;
4992 enum gimplify_status ret
;
4993 vec
<constructor_elt
, va_gc
> *elts
;
4994 bool cleared
= false;
4995 bool is_empty_ctor
= false;
4996 bool is_init_expr
= (TREE_CODE (*expr_p
) == INIT_EXPR
);
4998 gcc_assert (TREE_CODE (TREE_OPERAND (*expr_p
, 1)) == CONSTRUCTOR
);
5000 if (!notify_temp_creation
)
5002 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
5003 is_gimple_lvalue
, fb_lvalue
);
5004 if (ret
== GS_ERROR
)
5008 object
= TREE_OPERAND (*expr_p
, 0);
5009 ctor
= TREE_OPERAND (*expr_p
, 1)
5010 = optimize_compound_literals_in_ctor (TREE_OPERAND (*expr_p
, 1));
5011 type
= TREE_TYPE (ctor
);
5012 elts
= CONSTRUCTOR_ELTS (ctor
);
5015 switch (TREE_CODE (type
))
5019 case QUAL_UNION_TYPE
:
5022 /* Use readonly data for initializers of this or smaller size
5023 regardless of the num_nonzero_elements / num_unique_nonzero_elements
5025 const HOST_WIDE_INT min_unique_size
= 64;
5026 /* If num_nonzero_elements / num_unique_nonzero_elements ratio
5027 is smaller than this, use readonly data. */
5028 const int unique_nonzero_ratio
= 8;
5029 /* True if a single access of the object must be ensured. This is the
5030 case if the target is volatile, the type is non-addressable and more
5031 than one field need to be assigned. */
5032 const bool ensure_single_access
5033 = TREE_THIS_VOLATILE (object
)
5034 && !TREE_ADDRESSABLE (type
)
5035 && vec_safe_length (elts
) > 1;
5036 struct gimplify_init_ctor_preeval_data preeval_data
;
5037 HOST_WIDE_INT num_ctor_elements
, num_nonzero_elements
;
5038 HOST_WIDE_INT num_unique_nonzero_elements
;
5039 bool complete_p
, valid_const_initializer
;
5041 /* Aggregate types must lower constructors to initialization of
5042 individual elements. The exception is that a CONSTRUCTOR node
5043 with no elements indicates zero-initialization of the whole. */
5044 if (vec_safe_is_empty (elts
))
5046 if (notify_temp_creation
)
5048 is_empty_ctor
= true;
5052 /* Fetch information about the constructor to direct later processing.
5053 We might want to make static versions of it in various cases, and
5054 can only do so if it known to be a valid constant initializer. */
5055 valid_const_initializer
5056 = categorize_ctor_elements (ctor
, &num_nonzero_elements
,
5057 &num_unique_nonzero_elements
,
5058 &num_ctor_elements
, &complete_p
);
5060 /* If a const aggregate variable is being initialized, then it
5061 should never be a lose to promote the variable to be static. */
5062 if (valid_const_initializer
5063 && num_nonzero_elements
> 1
5064 && TREE_READONLY (object
)
5066 && !DECL_REGISTER (object
)
5067 && (flag_merge_constants
>= 2 || !TREE_ADDRESSABLE (object
))
5068 /* For ctors that have many repeated nonzero elements
5069 represented through RANGE_EXPRs, prefer initializing
5070 those through runtime loops over copies of large amounts
5071 of data from readonly data section. */
5072 && (num_unique_nonzero_elements
5073 > num_nonzero_elements
/ unique_nonzero_ratio
5074 || ((unsigned HOST_WIDE_INT
) int_size_in_bytes (type
)
5075 <= (unsigned HOST_WIDE_INT
) min_unique_size
)))
5077 if (notify_temp_creation
)
5080 DECL_INITIAL (object
) = ctor
;
5081 TREE_STATIC (object
) = 1;
5082 if (!DECL_NAME (object
))
5083 DECL_NAME (object
) = create_tmp_var_name ("C");
5084 walk_tree (&DECL_INITIAL (object
), force_labels_r
, NULL
, NULL
);
5086 /* ??? C++ doesn't automatically append a .<number> to the
5087 assembler name, and even when it does, it looks at FE private
5088 data structures to figure out what that number should be,
5089 which are not set for this variable. I suppose this is
5090 important for local statics for inline functions, which aren't
5091 "local" in the object file sense. So in order to get a unique
5092 TU-local symbol, we must invoke the lhd version now. */
5093 lhd_set_decl_assembler_name (object
);
5095 *expr_p
= NULL_TREE
;
5099 /* If there are "lots" of initialized elements, even discounting
5100 those that are not address constants (and thus *must* be
5101 computed at runtime), then partition the constructor into
5102 constant and non-constant parts. Block copy the constant
5103 parts in, then generate code for the non-constant parts. */
5104 /* TODO. There's code in cp/typeck.c to do this. */
5106 if (int_size_in_bytes (TREE_TYPE (ctor
)) < 0)
5107 /* store_constructor will ignore the clearing of variable-sized
5108 objects. Initializers for such objects must explicitly set
5109 every field that needs to be set. */
5111 else if (!complete_p
)
5112 /* If the constructor isn't complete, clear the whole object
5113 beforehand, unless CONSTRUCTOR_NO_CLEARING is set on it.
5115 ??? This ought not to be needed. For any element not present
5116 in the initializer, we should simply set them to zero. Except
5117 we'd need to *find* the elements that are not present, and that
5118 requires trickery to avoid quadratic compile-time behavior in
5119 large cases or excessive memory use in small cases. */
5120 cleared
= !CONSTRUCTOR_NO_CLEARING (ctor
);
5121 else if (num_ctor_elements
- num_nonzero_elements
5122 > CLEAR_RATIO (optimize_function_for_speed_p (cfun
))
5123 && num_nonzero_elements
< num_ctor_elements
/ 4)
5124 /* If there are "lots" of zeros, it's more efficient to clear
5125 the memory and then set the nonzero elements. */
5127 else if (ensure_single_access
&& num_nonzero_elements
== 0)
5128 /* If a single access to the target must be ensured and all elements
5129 are zero, then it's optimal to clear whatever their number. */
5134 /* If there are "lots" of initialized elements, and all of them
5135 are valid address constants, then the entire initializer can
5136 be dropped to memory, and then memcpy'd out. Don't do this
5137 for sparse arrays, though, as it's more efficient to follow
5138 the standard CONSTRUCTOR behavior of memset followed by
5139 individual element initialization. Also don't do this for small
5140 all-zero initializers (which aren't big enough to merit
5141 clearing), and don't try to make bitwise copies of
5142 TREE_ADDRESSABLE types. */
5143 if (valid_const_initializer
5145 && !(cleared
|| num_nonzero_elements
== 0)
5146 && !TREE_ADDRESSABLE (type
))
5148 HOST_WIDE_INT size
= int_size_in_bytes (type
);
5151 /* ??? We can still get unbounded array types, at least
5152 from the C++ front end. This seems wrong, but attempt
5153 to work around it for now. */
5156 size
= int_size_in_bytes (TREE_TYPE (object
));
5158 TREE_TYPE (ctor
) = type
= TREE_TYPE (object
);
5161 /* Find the maximum alignment we can assume for the object. */
5162 /* ??? Make use of DECL_OFFSET_ALIGN. */
5163 if (DECL_P (object
))
5164 align
= DECL_ALIGN (object
);
5166 align
= TYPE_ALIGN (type
);
5168 /* Do a block move either if the size is so small as to make
5169 each individual move a sub-unit move on average, or if it
5170 is so large as to make individual moves inefficient. */
5172 && num_nonzero_elements
> 1
5173 /* For ctors that have many repeated nonzero elements
5174 represented through RANGE_EXPRs, prefer initializing
5175 those through runtime loops over copies of large amounts
5176 of data from readonly data section. */
5177 && (num_unique_nonzero_elements
5178 > num_nonzero_elements
/ unique_nonzero_ratio
5179 || size
<= min_unique_size
)
5180 && (size
< num_nonzero_elements
5181 || !can_move_by_pieces (size
, align
)))
5183 if (notify_temp_creation
)
5186 walk_tree (&ctor
, force_labels_r
, NULL
, NULL
);
5187 ctor
= tree_output_constant_def (ctor
);
5188 if (!useless_type_conversion_p (type
, TREE_TYPE (ctor
)))
5189 ctor
= build1 (VIEW_CONVERT_EXPR
, type
, ctor
);
5190 TREE_OPERAND (*expr_p
, 1) = ctor
;
5192 /* This is no longer an assignment of a CONSTRUCTOR, but
5193 we still may have processing to do on the LHS. So
5194 pretend we didn't do anything here to let that happen. */
5195 return GS_UNHANDLED
;
5199 /* If a single access to the target must be ensured and there are
5200 nonzero elements or the zero elements are not assigned en masse,
5201 initialize the target from a temporary. */
5202 if (ensure_single_access
&& (num_nonzero_elements
> 0 || !cleared
))
5204 if (notify_temp_creation
)
5207 tree temp
= create_tmp_var (TYPE_MAIN_VARIANT (type
));
5208 TREE_OPERAND (*expr_p
, 0) = temp
;
5209 *expr_p
= build2 (COMPOUND_EXPR
, TREE_TYPE (*expr_p
),
5211 build2 (MODIFY_EXPR
, void_type_node
,
5216 if (notify_temp_creation
)
5219 /* If there are nonzero elements and if needed, pre-evaluate to capture
5220 elements overlapping with the lhs into temporaries. We must do this
5221 before clearing to fetch the values before they are zeroed-out. */
5222 if (num_nonzero_elements
> 0 && TREE_CODE (*expr_p
) != INIT_EXPR
)
5224 preeval_data
.lhs_base_decl
= get_base_address (object
);
5225 if (!DECL_P (preeval_data
.lhs_base_decl
))
5226 preeval_data
.lhs_base_decl
= NULL
;
5227 preeval_data
.lhs_alias_set
= get_alias_set (object
);
5229 gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p
, 1),
5230 pre_p
, post_p
, &preeval_data
);
5233 bool ctor_has_side_effects_p
5234 = TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p
, 1));
5238 /* Zap the CONSTRUCTOR element list, which simplifies this case.
5239 Note that we still have to gimplify, in order to handle the
5240 case of variable sized types. Avoid shared tree structures. */
5241 CONSTRUCTOR_ELTS (ctor
) = NULL
;
5242 TREE_SIDE_EFFECTS (ctor
) = 0;
5243 object
= unshare_expr (object
);
5244 gimplify_stmt (expr_p
, pre_p
);
5247 /* If we have not block cleared the object, or if there are nonzero
5248 elements in the constructor, or if the constructor has side effects,
5249 add assignments to the individual scalar fields of the object. */
5251 || num_nonzero_elements
> 0
5252 || ctor_has_side_effects_p
)
5253 gimplify_init_ctor_eval (object
, elts
, pre_p
, cleared
);
5255 *expr_p
= NULL_TREE
;
5263 if (notify_temp_creation
)
5266 /* Extract the real and imaginary parts out of the ctor. */
5267 gcc_assert (elts
->length () == 2);
5268 r
= (*elts
)[0].value
;
5269 i
= (*elts
)[1].value
;
5270 if (r
== NULL
|| i
== NULL
)
5272 tree zero
= build_zero_cst (TREE_TYPE (type
));
5279 /* Complex types have either COMPLEX_CST or COMPLEX_EXPR to
5280 represent creation of a complex value. */
5281 if (TREE_CONSTANT (r
) && TREE_CONSTANT (i
))
5283 ctor
= build_complex (type
, r
, i
);
5284 TREE_OPERAND (*expr_p
, 1) = ctor
;
5288 ctor
= build2 (COMPLEX_EXPR
, type
, r
, i
);
5289 TREE_OPERAND (*expr_p
, 1) = ctor
;
5290 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 1),
5293 rhs_predicate_for (TREE_OPERAND (*expr_p
, 0)),
5301 unsigned HOST_WIDE_INT ix
;
5302 constructor_elt
*ce
;
5304 if (notify_temp_creation
)
5307 /* Go ahead and simplify constant constructors to VECTOR_CST. */
5308 if (TREE_CONSTANT (ctor
))
5310 bool constant_p
= true;
5313 /* Even when ctor is constant, it might contain non-*_CST
5314 elements, such as addresses or trapping values like
5315 1.0/0.0 - 1.0/0.0. Such expressions don't belong
5316 in VECTOR_CST nodes. */
5317 FOR_EACH_CONSTRUCTOR_VALUE (elts
, ix
, value
)
5318 if (!CONSTANT_CLASS_P (value
))
5326 TREE_OPERAND (*expr_p
, 1) = build_vector_from_ctor (type
, elts
);
5330 TREE_CONSTANT (ctor
) = 0;
5333 /* Vector types use CONSTRUCTOR all the way through gimple
5334 compilation as a general initializer. */
5335 FOR_EACH_VEC_SAFE_ELT (elts
, ix
, ce
)
5337 enum gimplify_status tret
;
5338 tret
= gimplify_expr (&ce
->value
, pre_p
, post_p
, is_gimple_val
,
5340 if (tret
== GS_ERROR
)
5342 else if (TREE_STATIC (ctor
)
5343 && !initializer_constant_valid_p (ce
->value
,
5344 TREE_TYPE (ce
->value
)))
5345 TREE_STATIC (ctor
) = 0;
5347 recompute_constructor_flags (ctor
);
5348 if (!is_gimple_reg (TREE_OPERAND (*expr_p
, 0)))
5349 TREE_OPERAND (*expr_p
, 1) = get_formal_tmp_var (ctor
, pre_p
);
5354 /* So how did we get a CONSTRUCTOR for a scalar type? */
5358 if (ret
== GS_ERROR
)
5360 /* If we have gimplified both sides of the initializer but have
5361 not emitted an assignment, do so now. */
5364 tree lhs
= TREE_OPERAND (*expr_p
, 0);
5365 tree rhs
= TREE_OPERAND (*expr_p
, 1);
5366 if (want_value
&& object
== lhs
)
5367 lhs
= unshare_expr (lhs
);
5368 gassign
*init
= gimple_build_assign (lhs
, rhs
);
5369 gimplify_seq_add_stmt (pre_p
, init
);
5382 /* If the user requests to initialize automatic variables, we
5383 should initialize paddings inside the variable. Add a call to
5384 __builtin_clear_pading (&object, 0, for_auto_init = true) to
5385 initialize paddings of object always to zero regardless of
5386 INIT_TYPE. Note, we will not insert this call if the aggregate
5387 variable has be completely cleared already or it's initialized
5388 with an empty constructor. We cannot insert this call if the
5389 variable is a gimple register since __builtin_clear_padding will take
5390 the address of the variable. As a result, if a long double/_Complex long
5391 double variable will be spilled into stack later, its padding cannot
5392 be cleared with __builtin_clear_padding. We should clear its padding
5393 when it is spilled into memory. */
5395 && !is_gimple_reg (object
)
5396 && clear_padding_type_may_have_padding_p (type
)
5397 && ((AGGREGATE_TYPE_P (type
) && !cleared
&& !is_empty_ctor
)
5398 || !AGGREGATE_TYPE_P (type
))
5399 && is_var_need_auto_init (object
))
5400 gimple_add_padding_init_for_auto_var (object
, false, pre_p
);
5405 /* Given a pointer value OP0, return a simplified version of an
5406 indirection through OP0, or NULL_TREE if no simplification is
5407 possible. This may only be applied to a rhs of an expression.
5408 Note that the resulting type may be different from the type pointed
5409 to in the sense that it is still compatible from the langhooks
5413 gimple_fold_indirect_ref_rhs (tree t
)
5415 return gimple_fold_indirect_ref (t
);
5418 /* Subroutine of gimplify_modify_expr to do simplifications of
5419 MODIFY_EXPRs based on the code of the RHS. We loop for as long as
5420 something changes. */
5422 static enum gimplify_status
5423 gimplify_modify_expr_rhs (tree
*expr_p
, tree
*from_p
, tree
*to_p
,
5424 gimple_seq
*pre_p
, gimple_seq
*post_p
,
5427 enum gimplify_status ret
= GS_UNHANDLED
;
5433 switch (TREE_CODE (*from_p
))
5436 /* If we're assigning from a read-only variable initialized with
5437 a constructor and not volatile, do the direct assignment from
5438 the constructor, but only if the target is not volatile either
5439 since this latter assignment might end up being done on a per
5440 field basis. However, if the target is volatile and the type
5441 is aggregate and non-addressable, gimplify_init_constructor
5442 knows that it needs to ensure a single access to the target
5443 and it will return GS_OK only in this case. */
5444 if (TREE_READONLY (*from_p
)
5445 && DECL_INITIAL (*from_p
)
5446 && TREE_CODE (DECL_INITIAL (*from_p
)) == CONSTRUCTOR
5447 && !TREE_THIS_VOLATILE (*from_p
)
5448 && (!TREE_THIS_VOLATILE (*to_p
)
5449 || (AGGREGATE_TYPE_P (TREE_TYPE (*to_p
))
5450 && !TREE_ADDRESSABLE (TREE_TYPE (*to_p
)))))
5452 tree old_from
= *from_p
;
5453 enum gimplify_status subret
;
5455 /* Move the constructor into the RHS. */
5456 *from_p
= unshare_expr (DECL_INITIAL (*from_p
));
5458 /* Let's see if gimplify_init_constructor will need to put
5460 subret
= gimplify_init_constructor (expr_p
, NULL
, NULL
,
5462 if (subret
== GS_ERROR
)
5464 /* If so, revert the change. */
5476 /* If we have code like
5480 where the type of "x" is a (possibly cv-qualified variant
5481 of "A"), treat the entire expression as identical to "x".
5482 This kind of code arises in C++ when an object is bound
5483 to a const reference, and if "x" is a TARGET_EXPR we want
5484 to take advantage of the optimization below. */
5485 bool volatile_p
= TREE_THIS_VOLATILE (*from_p
);
5486 tree t
= gimple_fold_indirect_ref_rhs (TREE_OPERAND (*from_p
, 0));
5489 if (TREE_THIS_VOLATILE (t
) != volatile_p
)
5492 t
= build_simple_mem_ref_loc (EXPR_LOCATION (*from_p
),
5493 build_fold_addr_expr (t
));
5494 if (REFERENCE_CLASS_P (t
))
5495 TREE_THIS_VOLATILE (t
) = volatile_p
;
5506 /* If we are initializing something from a TARGET_EXPR, strip the
5507 TARGET_EXPR and initialize it directly, if possible. This can't
5508 be done if the initializer is void, since that implies that the
5509 temporary is set in some non-trivial way.
5511 ??? What about code that pulls out the temp and uses it
5512 elsewhere? I think that such code never uses the TARGET_EXPR as
5513 an initializer. If I'm wrong, we'll die because the temp won't
5514 have any RTL. In that case, I guess we'll need to replace
5515 references somehow. */
5516 tree init
= TARGET_EXPR_INITIAL (*from_p
);
5519 && (TREE_CODE (*expr_p
) != MODIFY_EXPR
5520 || !TARGET_EXPR_NO_ELIDE (*from_p
))
5521 && !VOID_TYPE_P (TREE_TYPE (init
)))
5531 /* Remove any COMPOUND_EXPR in the RHS so the following cases will be
5533 gimplify_compound_expr (from_p
, pre_p
, true);
5539 /* If we already made some changes, let the front end have a
5540 crack at this before we break it down. */
5541 if (ret
!= GS_UNHANDLED
)
5544 /* If we're initializing from a CONSTRUCTOR, break this into
5545 individual MODIFY_EXPRs. */
5546 ret
= gimplify_init_constructor (expr_p
, pre_p
, post_p
, want_value
,
5551 /* If we're assigning to a non-register type, push the assignment
5552 down into the branches. This is mandatory for ADDRESSABLE types,
5553 since we cannot generate temporaries for such, but it saves a
5554 copy in other cases as well. */
5555 if (!is_gimple_reg_type (TREE_TYPE (*from_p
)))
5557 /* This code should mirror the code in gimplify_cond_expr. */
5558 enum tree_code code
= TREE_CODE (*expr_p
);
5559 tree cond
= *from_p
;
5560 tree result
= *to_p
;
5562 ret
= gimplify_expr (&result
, pre_p
, post_p
,
5563 is_gimple_lvalue
, fb_lvalue
);
5564 if (ret
!= GS_ERROR
)
5567 /* If we are going to write RESULT more than once, clear
5568 TREE_READONLY flag, otherwise we might incorrectly promote
5569 the variable to static const and initialize it at compile
5570 time in one of the branches. */
5572 && TREE_TYPE (TREE_OPERAND (cond
, 1)) != void_type_node
5573 && TREE_TYPE (TREE_OPERAND (cond
, 2)) != void_type_node
)
5574 TREE_READONLY (result
) = 0;
5575 if (TREE_TYPE (TREE_OPERAND (cond
, 1)) != void_type_node
)
5576 TREE_OPERAND (cond
, 1)
5577 = build2 (code
, void_type_node
, result
,
5578 TREE_OPERAND (cond
, 1));
5579 if (TREE_TYPE (TREE_OPERAND (cond
, 2)) != void_type_node
)
5580 TREE_OPERAND (cond
, 2)
5581 = build2 (code
, void_type_node
, unshare_expr (result
),
5582 TREE_OPERAND (cond
, 2));
5584 TREE_TYPE (cond
) = void_type_node
;
5585 recalculate_side_effects (cond
);
5589 gimplify_and_add (cond
, pre_p
);
5590 *expr_p
= unshare_expr (result
);
5599 /* For calls that return in memory, give *to_p as the CALL_EXPR's
5600 return slot so that we don't generate a temporary. */
5601 if (!CALL_EXPR_RETURN_SLOT_OPT (*from_p
)
5602 && aggregate_value_p (*from_p
, *from_p
))
5606 if (!(rhs_predicate_for (*to_p
))(*from_p
))
5607 /* If we need a temporary, *to_p isn't accurate. */
5609 /* It's OK to use the return slot directly unless it's an NRV. */
5610 else if (TREE_CODE (*to_p
) == RESULT_DECL
5611 && DECL_NAME (*to_p
) == NULL_TREE
5612 && needs_to_live_in_memory (*to_p
))
5614 else if (is_gimple_reg_type (TREE_TYPE (*to_p
))
5615 || (DECL_P (*to_p
) && DECL_REGISTER (*to_p
)))
5616 /* Don't force regs into memory. */
5618 else if (TREE_CODE (*expr_p
) == INIT_EXPR
)
5619 /* It's OK to use the target directly if it's being
5622 else if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p
)))
5624 /* Always use the target and thus RSO for variable-sized types.
5625 GIMPLE cannot deal with a variable-sized assignment
5626 embedded in a call statement. */
5628 else if (TREE_CODE (*to_p
) != SSA_NAME
5629 && (!is_gimple_variable (*to_p
)
5630 || needs_to_live_in_memory (*to_p
)))
5631 /* Don't use the original target if it's already addressable;
5632 if its address escapes, and the called function uses the
5633 NRV optimization, a conforming program could see *to_p
5634 change before the called function returns; see c++/19317.
5635 When optimizing, the return_slot pass marks more functions
5636 as safe after we have escape info. */
5643 CALL_EXPR_RETURN_SLOT_OPT (*from_p
) = 1;
5644 mark_addressable (*to_p
);
5649 case WITH_SIZE_EXPR
:
5650 /* Likewise for calls that return an aggregate of non-constant size,
5651 since we would not be able to generate a temporary at all. */
5652 if (TREE_CODE (TREE_OPERAND (*from_p
, 0)) == CALL_EXPR
)
5654 *from_p
= TREE_OPERAND (*from_p
, 0);
5655 /* We don't change ret in this case because the
5656 WITH_SIZE_EXPR might have been added in
5657 gimplify_modify_expr, so returning GS_OK would lead to an
5663 /* If we're initializing from a container, push the initialization
5665 case CLEANUP_POINT_EXPR
:
5667 case STATEMENT_LIST
:
5669 tree wrap
= *from_p
;
5672 ret
= gimplify_expr (to_p
, pre_p
, post_p
, is_gimple_min_lval
,
5674 if (ret
!= GS_ERROR
)
5677 t
= voidify_wrapper_expr (wrap
, *expr_p
);
5678 gcc_assert (t
== *expr_p
);
5682 gimplify_and_add (wrap
, pre_p
);
5683 *expr_p
= unshare_expr (*to_p
);
5691 /* Pull out compound literal expressions from a NOP_EXPR.
5692 Those are created in the C FE to drop qualifiers during
5693 lvalue conversion. */
5694 if ((TREE_CODE (TREE_OPERAND (*from_p
, 0)) == COMPOUND_LITERAL_EXPR
)
5695 && tree_ssa_useless_type_conversion (*from_p
))
5697 *from_p
= TREE_OPERAND (*from_p
, 0);
5703 case COMPOUND_LITERAL_EXPR
:
5705 tree complit
= TREE_OPERAND (*expr_p
, 1);
5706 tree decl_s
= COMPOUND_LITERAL_EXPR_DECL_EXPR (complit
);
5707 tree decl
= DECL_EXPR_DECL (decl_s
);
5708 tree init
= DECL_INITIAL (decl
);
5710 /* struct T x = (struct T) { 0, 1, 2 } can be optimized
5711 into struct T x = { 0, 1, 2 } if the address of the
5712 compound literal has never been taken. */
5713 if (!TREE_ADDRESSABLE (complit
)
5714 && !TREE_ADDRESSABLE (decl
)
5717 *expr_p
= copy_node (*expr_p
);
5718 TREE_OPERAND (*expr_p
, 1) = init
;
5733 /* Return true if T looks like a valid GIMPLE statement. */
5736 is_gimple_stmt (tree t
)
5738 const enum tree_code code
= TREE_CODE (t
);
5743 /* The only valid NOP_EXPR is the empty statement. */
5744 return IS_EMPTY_STMT (t
);
5748 /* These are only valid if they're void. */
5749 return TREE_TYPE (t
) == NULL
|| VOID_TYPE_P (TREE_TYPE (t
));
5755 case CASE_LABEL_EXPR
:
5756 case TRY_CATCH_EXPR
:
5757 case TRY_FINALLY_EXPR
:
5758 case EH_FILTER_EXPR
:
5761 case STATEMENT_LIST
:
5766 case OACC_HOST_DATA
:
5769 case OACC_ENTER_DATA
:
5770 case OACC_EXIT_DATA
:
5775 case OMP_DISTRIBUTE
:
5790 case OMP_TARGET_DATA
:
5791 case OMP_TARGET_UPDATE
:
5792 case OMP_TARGET_ENTER_DATA
:
5793 case OMP_TARGET_EXIT_DATA
:
5796 /* These are always void. */
5802 /* These are valid regardless of their type. */
5811 /* Promote partial stores to COMPLEX variables to total stores. *EXPR_P is
5812 a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a gimple register.
5814 IMPORTANT NOTE: This promotion is performed by introducing a load of the
5815 other, unmodified part of the complex object just before the total store.
5816 As a consequence, if the object is still uninitialized, an undefined value
5817 will be loaded into a register, which may result in a spurious exception
5818 if the register is floating-point and the value happens to be a signaling
5819 NaN for example. Then the fully-fledged complex operations lowering pass
5820 followed by a DCE pass are necessary in order to fix things up. */
5822 static enum gimplify_status
5823 gimplify_modify_expr_complex_part (tree
*expr_p
, gimple_seq
*pre_p
,
5826 enum tree_code code
, ocode
;
5827 tree lhs
, rhs
, new_rhs
, other
, realpart
, imagpart
;
5829 lhs
= TREE_OPERAND (*expr_p
, 0);
5830 rhs
= TREE_OPERAND (*expr_p
, 1);
5831 code
= TREE_CODE (lhs
);
5832 lhs
= TREE_OPERAND (lhs
, 0);
5834 ocode
= code
== REALPART_EXPR
? IMAGPART_EXPR
: REALPART_EXPR
;
5835 other
= build1 (ocode
, TREE_TYPE (rhs
), lhs
);
5836 suppress_warning (other
);
5837 other
= get_formal_tmp_var (other
, pre_p
);
5839 realpart
= code
== REALPART_EXPR
? rhs
: other
;
5840 imagpart
= code
== REALPART_EXPR
? other
: rhs
;
5842 if (TREE_CONSTANT (realpart
) && TREE_CONSTANT (imagpart
))
5843 new_rhs
= build_complex (TREE_TYPE (lhs
), realpart
, imagpart
);
5845 new_rhs
= build2 (COMPLEX_EXPR
, TREE_TYPE (lhs
), realpart
, imagpart
);
5847 gimplify_seq_add_stmt (pre_p
, gimple_build_assign (lhs
, new_rhs
));
5848 *expr_p
= (want_value
) ? rhs
: NULL_TREE
;
5853 /* Gimplify the MODIFY_EXPR node pointed to by EXPR_P.
5859 PRE_P points to the list where side effects that must happen before
5860 *EXPR_P should be stored.
5862 POST_P points to the list where side effects that must happen after
5863 *EXPR_P should be stored.
5865 WANT_VALUE is nonzero iff we want to use the value of this expression
5866 in another expression. */
5868 static enum gimplify_status
5869 gimplify_modify_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
5872 tree
*from_p
= &TREE_OPERAND (*expr_p
, 1);
5873 tree
*to_p
= &TREE_OPERAND (*expr_p
, 0);
5874 enum gimplify_status ret
= GS_UNHANDLED
;
5876 location_t loc
= EXPR_LOCATION (*expr_p
);
5877 gimple_stmt_iterator gsi
;
5879 gcc_assert (TREE_CODE (*expr_p
) == MODIFY_EXPR
5880 || TREE_CODE (*expr_p
) == INIT_EXPR
);
5882 /* Trying to simplify a clobber using normal logic doesn't work,
5883 so handle it here. */
5884 if (TREE_CLOBBER_P (*from_p
))
5886 ret
= gimplify_expr (to_p
, pre_p
, post_p
, is_gimple_lvalue
, fb_lvalue
);
5887 if (ret
== GS_ERROR
)
5889 gcc_assert (!want_value
);
5890 if (!VAR_P (*to_p
) && TREE_CODE (*to_p
) != MEM_REF
)
5892 tree addr
= get_initialized_tmp_var (build_fold_addr_expr (*to_p
),
5894 *to_p
= build_simple_mem_ref_loc (EXPR_LOCATION (*to_p
), addr
);
5896 gimplify_seq_add_stmt (pre_p
, gimple_build_assign (*to_p
, *from_p
));
5901 /* Insert pointer conversions required by the middle-end that are not
5902 required by the frontend. This fixes middle-end type checking for
5903 for example gcc.dg/redecl-6.c. */
5904 if (POINTER_TYPE_P (TREE_TYPE (*to_p
)))
5906 STRIP_USELESS_TYPE_CONVERSION (*from_p
);
5907 if (!useless_type_conversion_p (TREE_TYPE (*to_p
), TREE_TYPE (*from_p
)))
5908 *from_p
= fold_convert_loc (loc
, TREE_TYPE (*to_p
), *from_p
);
5911 /* See if any simplifications can be done based on what the RHS is. */
5912 ret
= gimplify_modify_expr_rhs (expr_p
, from_p
, to_p
, pre_p
, post_p
,
5914 if (ret
!= GS_UNHANDLED
)
5917 /* For empty types only gimplify the left hand side and right hand
5918 side as statements and throw away the assignment. Do this after
5919 gimplify_modify_expr_rhs so we handle TARGET_EXPRs of addressable
5921 if (is_empty_type (TREE_TYPE (*from_p
))
5923 /* Don't do this for calls that return addressable types, expand_call
5924 relies on those having a lhs. */
5925 && !(TREE_ADDRESSABLE (TREE_TYPE (*from_p
))
5926 && TREE_CODE (*from_p
) == CALL_EXPR
))
5928 gimplify_stmt (from_p
, pre_p
);
5929 gimplify_stmt (to_p
, pre_p
);
5930 *expr_p
= NULL_TREE
;
5934 /* If the value being copied is of variable width, compute the length
5935 of the copy into a WITH_SIZE_EXPR. Note that we need to do this
5936 before gimplifying any of the operands so that we can resolve any
5937 PLACEHOLDER_EXPRs in the size. Also note that the RTL expander uses
5938 the size of the expression to be copied, not of the destination, so
5939 that is what we must do here. */
5940 maybe_with_size_expr (from_p
);
5942 /* As a special case, we have to temporarily allow for assignments
5943 with a CALL_EXPR on the RHS. Since in GIMPLE a function call is
5944 a toplevel statement, when gimplifying the GENERIC expression
5945 MODIFY_EXPR <a, CALL_EXPR <foo>>, we cannot create the tuple
5946 GIMPLE_ASSIGN <a, GIMPLE_CALL <foo>>.
5948 Instead, we need to create the tuple GIMPLE_CALL <a, foo>. To
5949 prevent gimplify_expr from trying to create a new temporary for
5950 foo's LHS, we tell it that it should only gimplify until it
5951 reaches the CALL_EXPR. On return from gimplify_expr, the newly
5952 created GIMPLE_CALL <foo> will be the last statement in *PRE_P
5953 and all we need to do here is set 'a' to be its LHS. */
5955 /* Gimplify the RHS first for C++17 and bug 71104. */
5956 gimple_predicate initial_pred
= initial_rhs_predicate_for (*to_p
);
5957 ret
= gimplify_expr (from_p
, pre_p
, post_p
, initial_pred
, fb_rvalue
);
5958 if (ret
== GS_ERROR
)
5961 /* Then gimplify the LHS. */
5962 /* If we gimplified the RHS to a CALL_EXPR and that call may return
5963 twice we have to make sure to gimplify into non-SSA as otherwise
5964 the abnormal edge added later will make those defs not dominate
5966 ??? Technically this applies only to the registers used in the
5967 resulting non-register *TO_P. */
5968 bool saved_into_ssa
= gimplify_ctxp
->into_ssa
;
5970 && TREE_CODE (*from_p
) == CALL_EXPR
5971 && call_expr_flags (*from_p
) & ECF_RETURNS_TWICE
)
5972 gimplify_ctxp
->into_ssa
= false;
5973 ret
= gimplify_expr (to_p
, pre_p
, post_p
, is_gimple_lvalue
, fb_lvalue
);
5974 gimplify_ctxp
->into_ssa
= saved_into_ssa
;
5975 if (ret
== GS_ERROR
)
5978 /* Now that the LHS is gimplified, re-gimplify the RHS if our initial
5979 guess for the predicate was wrong. */
5980 gimple_predicate final_pred
= rhs_predicate_for (*to_p
);
5981 if (final_pred
!= initial_pred
)
5983 ret
= gimplify_expr (from_p
, pre_p
, post_p
, final_pred
, fb_rvalue
);
5984 if (ret
== GS_ERROR
)
5988 /* In case of va_arg internal fn wrappped in a WITH_SIZE_EXPR, add the type
5989 size as argument to the call. */
5990 if (TREE_CODE (*from_p
) == WITH_SIZE_EXPR
)
5992 tree call
= TREE_OPERAND (*from_p
, 0);
5993 tree vlasize
= TREE_OPERAND (*from_p
, 1);
5995 if (TREE_CODE (call
) == CALL_EXPR
5996 && CALL_EXPR_IFN (call
) == IFN_VA_ARG
)
5998 int nargs
= call_expr_nargs (call
);
5999 tree type
= TREE_TYPE (call
);
6000 tree ap
= CALL_EXPR_ARG (call
, 0);
6001 tree tag
= CALL_EXPR_ARG (call
, 1);
6002 tree aptag
= CALL_EXPR_ARG (call
, 2);
6003 tree newcall
= build_call_expr_internal_loc (EXPR_LOCATION (call
),
6007 TREE_OPERAND (*from_p
, 0) = newcall
;
6011 /* Now see if the above changed *from_p to something we handle specially. */
6012 ret
= gimplify_modify_expr_rhs (expr_p
, from_p
, to_p
, pre_p
, post_p
,
6014 if (ret
!= GS_UNHANDLED
)
6017 /* If we've got a variable sized assignment between two lvalues (i.e. does
6018 not involve a call), then we can make things a bit more straightforward
6019 by converting the assignment to memcpy or memset. */
6020 if (TREE_CODE (*from_p
) == WITH_SIZE_EXPR
)
6022 tree from
= TREE_OPERAND (*from_p
, 0);
6023 tree size
= TREE_OPERAND (*from_p
, 1);
6025 if (TREE_CODE (from
) == CONSTRUCTOR
)
6026 return gimplify_modify_expr_to_memset (expr_p
, size
, want_value
, pre_p
);
6028 if (is_gimple_addressable (from
))
6031 return gimplify_modify_expr_to_memcpy (expr_p
, size
, want_value
,
6036 /* Transform partial stores to non-addressable complex variables into
6037 total stores. This allows us to use real instead of virtual operands
6038 for these variables, which improves optimization. */
6039 if ((TREE_CODE (*to_p
) == REALPART_EXPR
6040 || TREE_CODE (*to_p
) == IMAGPART_EXPR
)
6041 && is_gimple_reg (TREE_OPERAND (*to_p
, 0)))
6042 return gimplify_modify_expr_complex_part (expr_p
, pre_p
, want_value
);
6044 /* Try to alleviate the effects of the gimplification creating artificial
6045 temporaries (see for example is_gimple_reg_rhs) on the debug info, but
6046 make sure not to create DECL_DEBUG_EXPR links across functions. */
6047 if (!gimplify_ctxp
->into_ssa
6049 && DECL_IGNORED_P (*from_p
)
6051 && !DECL_IGNORED_P (*to_p
)
6052 && decl_function_context (*to_p
) == current_function_decl
6053 && decl_function_context (*from_p
) == current_function_decl
)
6055 if (!DECL_NAME (*from_p
) && DECL_NAME (*to_p
))
6057 = create_tmp_var_name (IDENTIFIER_POINTER (DECL_NAME (*to_p
)));
6058 DECL_HAS_DEBUG_EXPR_P (*from_p
) = 1;
6059 SET_DECL_DEBUG_EXPR (*from_p
, *to_p
);
6062 if (want_value
&& TREE_THIS_VOLATILE (*to_p
))
6063 *from_p
= get_initialized_tmp_var (*from_p
, pre_p
, post_p
);
6065 if (TREE_CODE (*from_p
) == CALL_EXPR
)
6067 /* Since the RHS is a CALL_EXPR, we need to create a GIMPLE_CALL
6068 instead of a GIMPLE_ASSIGN. */
6070 if (CALL_EXPR_FN (*from_p
) == NULL_TREE
)
6072 /* Gimplify internal functions created in the FEs. */
6073 int nargs
= call_expr_nargs (*from_p
), i
;
6074 enum internal_fn ifn
= CALL_EXPR_IFN (*from_p
);
6075 auto_vec
<tree
> vargs (nargs
);
6077 for (i
= 0; i
< nargs
; i
++)
6079 gimplify_arg (&CALL_EXPR_ARG (*from_p
, i
), pre_p
,
6080 EXPR_LOCATION (*from_p
));
6081 vargs
.quick_push (CALL_EXPR_ARG (*from_p
, i
));
6083 call_stmt
= gimple_build_call_internal_vec (ifn
, vargs
);
6084 gimple_call_set_nothrow (call_stmt
, TREE_NOTHROW (*from_p
));
6085 gimple_set_location (call_stmt
, EXPR_LOCATION (*expr_p
));
6089 tree fnptrtype
= TREE_TYPE (CALL_EXPR_FN (*from_p
));
6090 CALL_EXPR_FN (*from_p
) = TREE_OPERAND (CALL_EXPR_FN (*from_p
), 0);
6091 STRIP_USELESS_TYPE_CONVERSION (CALL_EXPR_FN (*from_p
));
6092 tree fndecl
= get_callee_fndecl (*from_p
);
6094 && fndecl_built_in_p (fndecl
, BUILT_IN_EXPECT
)
6095 && call_expr_nargs (*from_p
) == 3)
6096 call_stmt
= gimple_build_call_internal (IFN_BUILTIN_EXPECT
, 3,
6097 CALL_EXPR_ARG (*from_p
, 0),
6098 CALL_EXPR_ARG (*from_p
, 1),
6099 CALL_EXPR_ARG (*from_p
, 2));
6102 call_stmt
= gimple_build_call_from_tree (*from_p
, fnptrtype
);
6105 notice_special_calls (call_stmt
);
6106 if (!gimple_call_noreturn_p (call_stmt
) || !should_remove_lhs_p (*to_p
))
6107 gimple_call_set_lhs (call_stmt
, *to_p
);
6108 else if (TREE_CODE (*to_p
) == SSA_NAME
)
6109 /* The above is somewhat premature, avoid ICEing later for a
6110 SSA name w/o a definition. We may have uses in the GIMPLE IL.
6111 ??? This doesn't make it a default-def. */
6112 SSA_NAME_DEF_STMT (*to_p
) = gimple_build_nop ();
6118 assign
= gimple_build_assign (*to_p
, *from_p
);
6119 gimple_set_location (assign
, EXPR_LOCATION (*expr_p
));
6120 if (COMPARISON_CLASS_P (*from_p
))
6121 copy_warning (assign
, *from_p
);
6124 if (gimplify_ctxp
->into_ssa
&& is_gimple_reg (*to_p
))
6126 /* We should have got an SSA name from the start. */
6127 gcc_assert (TREE_CODE (*to_p
) == SSA_NAME
6128 || ! gimple_in_ssa_p (cfun
));
6131 gimplify_seq_add_stmt (pre_p
, assign
);
6132 gsi
= gsi_last (*pre_p
);
6133 maybe_fold_stmt (&gsi
);
6137 *expr_p
= TREE_THIS_VOLATILE (*to_p
) ? *from_p
: unshare_expr (*to_p
);
6146 /* Gimplify a comparison between two variable-sized objects. Do this
6147 with a call to BUILT_IN_MEMCMP. */
6149 static enum gimplify_status
6150 gimplify_variable_sized_compare (tree
*expr_p
)
6152 location_t loc
= EXPR_LOCATION (*expr_p
);
6153 tree op0
= TREE_OPERAND (*expr_p
, 0);
6154 tree op1
= TREE_OPERAND (*expr_p
, 1);
6155 tree t
, arg
, dest
, src
, expr
;
6157 arg
= TYPE_SIZE_UNIT (TREE_TYPE (op0
));
6158 arg
= unshare_expr (arg
);
6159 arg
= SUBSTITUTE_PLACEHOLDER_IN_EXPR (arg
, op0
);
6160 src
= build_fold_addr_expr_loc (loc
, op1
);
6161 dest
= build_fold_addr_expr_loc (loc
, op0
);
6162 t
= builtin_decl_implicit (BUILT_IN_MEMCMP
);
6163 t
= build_call_expr_loc (loc
, t
, 3, dest
, src
, arg
);
6166 = build2 (TREE_CODE (*expr_p
), TREE_TYPE (*expr_p
), t
, integer_zero_node
);
6167 SET_EXPR_LOCATION (expr
, loc
);
6173 /* Gimplify a comparison between two aggregate objects of integral scalar
6174 mode as a comparison between the bitwise equivalent scalar values. */
6176 static enum gimplify_status
6177 gimplify_scalar_mode_aggregate_compare (tree
*expr_p
)
6179 location_t loc
= EXPR_LOCATION (*expr_p
);
6180 tree op0
= TREE_OPERAND (*expr_p
, 0);
6181 tree op1
= TREE_OPERAND (*expr_p
, 1);
6183 tree type
= TREE_TYPE (op0
);
6184 tree scalar_type
= lang_hooks
.types
.type_for_mode (TYPE_MODE (type
), 1);
6186 op0
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, scalar_type
, op0
);
6187 op1
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, scalar_type
, op1
);
6190 = fold_build2_loc (loc
, TREE_CODE (*expr_p
), TREE_TYPE (*expr_p
), op0
, op1
);
6195 /* Gimplify an expression sequence. This function gimplifies each
6196 expression and rewrites the original expression with the last
6197 expression of the sequence in GIMPLE form.
6199 PRE_P points to the list where the side effects for all the
6200 expressions in the sequence will be emitted.
6202 WANT_VALUE is true when the result of the last COMPOUND_EXPR is used. */
6204 static enum gimplify_status
6205 gimplify_compound_expr (tree
*expr_p
, gimple_seq
*pre_p
, bool want_value
)
6211 tree
*sub_p
= &TREE_OPERAND (t
, 0);
6213 if (TREE_CODE (*sub_p
) == COMPOUND_EXPR
)
6214 gimplify_compound_expr (sub_p
, pre_p
, false);
6216 gimplify_stmt (sub_p
, pre_p
);
6218 t
= TREE_OPERAND (t
, 1);
6220 while (TREE_CODE (t
) == COMPOUND_EXPR
);
6227 gimplify_stmt (expr_p
, pre_p
);
6232 /* Gimplify a SAVE_EXPR node. EXPR_P points to the expression to
6233 gimplify. After gimplification, EXPR_P will point to a new temporary
6234 that holds the original value of the SAVE_EXPR node.
6236 PRE_P points to the list where side effects that must happen before
6237 *EXPR_P should be stored. */
6239 static enum gimplify_status
6240 gimplify_save_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
)
6242 enum gimplify_status ret
= GS_ALL_DONE
;
6245 gcc_assert (TREE_CODE (*expr_p
) == SAVE_EXPR
);
6246 val
= TREE_OPERAND (*expr_p
, 0);
6248 if (TREE_TYPE (val
) == error_mark_node
)
6251 /* If the SAVE_EXPR has not been resolved, then evaluate it once. */
6252 if (!SAVE_EXPR_RESOLVED_P (*expr_p
))
6254 /* The operand may be a void-valued expression. It is
6255 being executed only for its side-effects. */
6256 if (TREE_TYPE (val
) == void_type_node
)
6258 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
6259 is_gimple_stmt
, fb_none
);
6263 /* The temporary may not be an SSA name as later abnormal and EH
6264 control flow may invalidate use/def domination. When in SSA
6265 form then assume there are no such issues and SAVE_EXPRs only
6266 appear via GENERIC foldings. */
6267 val
= get_initialized_tmp_var (val
, pre_p
, post_p
,
6268 gimple_in_ssa_p (cfun
));
6270 TREE_OPERAND (*expr_p
, 0) = val
;
6271 SAVE_EXPR_RESOLVED_P (*expr_p
) = 1;
6279 /* Rewrite the ADDR_EXPR node pointed to by EXPR_P
6286 PRE_P points to the list where side effects that must happen before
6287 *EXPR_P should be stored.
6289 POST_P points to the list where side effects that must happen after
6290 *EXPR_P should be stored. */
6292 static enum gimplify_status
6293 gimplify_addr_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
)
6295 tree expr
= *expr_p
;
6296 tree op0
= TREE_OPERAND (expr
, 0);
6297 enum gimplify_status ret
;
6298 location_t loc
= EXPR_LOCATION (*expr_p
);
6300 switch (TREE_CODE (op0
))
6304 /* Check if we are dealing with an expression of the form '&*ptr'.
6305 While the front end folds away '&*ptr' into 'ptr', these
6306 expressions may be generated internally by the compiler (e.g.,
6307 builtins like __builtin_va_end). */
6308 /* Caution: the silent array decomposition semantics we allow for
6309 ADDR_EXPR means we can't always discard the pair. */
6310 /* Gimplification of the ADDR_EXPR operand may drop
6311 cv-qualification conversions, so make sure we add them if
6314 tree op00
= TREE_OPERAND (op0
, 0);
6315 tree t_expr
= TREE_TYPE (expr
);
6316 tree t_op00
= TREE_TYPE (op00
);
6318 if (!useless_type_conversion_p (t_expr
, t_op00
))
6319 op00
= fold_convert_loc (loc
, TREE_TYPE (expr
), op00
);
6325 case VIEW_CONVERT_EXPR
:
6326 /* Take the address of our operand and then convert it to the type of
6329 ??? The interactions of VIEW_CONVERT_EXPR and aliasing is not at
6330 all clear. The impact of this transformation is even less clear. */
6332 /* If the operand is a useless conversion, look through it. Doing so
6333 guarantees that the ADDR_EXPR and its operand will remain of the
6335 if (tree_ssa_useless_type_conversion (TREE_OPERAND (op0
, 0)))
6336 op0
= TREE_OPERAND (op0
, 0);
6338 *expr_p
= fold_convert_loc (loc
, TREE_TYPE (expr
),
6339 build_fold_addr_expr_loc (loc
,
6340 TREE_OPERAND (op0
, 0)));
6345 if (integer_zerop (TREE_OPERAND (op0
, 1)))
6346 goto do_indirect_ref
;
6351 /* If we see a call to a declared builtin or see its address
6352 being taken (we can unify those cases here) then we can mark
6353 the builtin for implicit generation by GCC. */
6354 if (TREE_CODE (op0
) == FUNCTION_DECL
6355 && fndecl_built_in_p (op0
, BUILT_IN_NORMAL
)
6356 && builtin_decl_declared_p (DECL_FUNCTION_CODE (op0
)))
6357 set_builtin_decl_implicit_p (DECL_FUNCTION_CODE (op0
), true);
6359 /* We use fb_either here because the C frontend sometimes takes
6360 the address of a call that returns a struct; see
6361 gcc.dg/c99-array-lval-1.c. The gimplifier will correctly make
6362 the implied temporary explicit. */
6364 /* Make the operand addressable. */
6365 ret
= gimplify_expr (&TREE_OPERAND (expr
, 0), pre_p
, post_p
,
6366 is_gimple_addressable
, fb_either
);
6367 if (ret
== GS_ERROR
)
6370 /* Then mark it. Beware that it may not be possible to do so directly
6371 if a temporary has been created by the gimplification. */
6372 prepare_gimple_addressable (&TREE_OPERAND (expr
, 0), pre_p
);
6374 op0
= TREE_OPERAND (expr
, 0);
6376 /* For various reasons, the gimplification of the expression
6377 may have made a new INDIRECT_REF. */
6378 if (TREE_CODE (op0
) == INDIRECT_REF
6379 || (TREE_CODE (op0
) == MEM_REF
6380 && integer_zerop (TREE_OPERAND (op0
, 1))))
6381 goto do_indirect_ref
;
6383 mark_addressable (TREE_OPERAND (expr
, 0));
6385 /* The FEs may end up building ADDR_EXPRs early on a decl with
6386 an incomplete type. Re-build ADDR_EXPRs in canonical form
6388 if (!types_compatible_p (TREE_TYPE (op0
), TREE_TYPE (TREE_TYPE (expr
))))
6389 *expr_p
= build_fold_addr_expr (op0
);
6391 /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly. */
6392 recompute_tree_invariant_for_addr_expr (*expr_p
);
6394 /* If we re-built the ADDR_EXPR add a conversion to the original type
6396 if (!useless_type_conversion_p (TREE_TYPE (expr
), TREE_TYPE (*expr_p
)))
6397 *expr_p
= fold_convert (TREE_TYPE (expr
), *expr_p
);
6405 /* Gimplify the operands of an ASM_EXPR. Input operands should be a gimple
6406 value; output operands should be a gimple lvalue. */
6408 static enum gimplify_status
6409 gimplify_asm_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
)
6413 const char **oconstraints
;
6416 const char *constraint
;
6417 bool allows_mem
, allows_reg
, is_inout
;
6418 enum gimplify_status ret
, tret
;
6420 vec
<tree
, va_gc
> *inputs
;
6421 vec
<tree
, va_gc
> *outputs
;
6422 vec
<tree
, va_gc
> *clobbers
;
6423 vec
<tree
, va_gc
> *labels
;
6427 noutputs
= list_length (ASM_OUTPUTS (expr
));
6428 oconstraints
= (const char **) alloca ((noutputs
) * sizeof (const char *));
6436 link_next
= NULL_TREE
;
6437 for (i
= 0, link
= ASM_OUTPUTS (expr
); link
; ++i
, link
= link_next
)
6440 size_t constraint_len
;
6442 link_next
= TREE_CHAIN (link
);
6446 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link
)));
6447 constraint_len
= strlen (constraint
);
6448 if (constraint_len
== 0)
6451 ok
= parse_output_constraint (&constraint
, i
, 0, 0,
6452 &allows_mem
, &allows_reg
, &is_inout
);
6459 /* If we can't make copies, we can only accept memory.
6460 Similarly for VLAs. */
6461 tree outtype
= TREE_TYPE (TREE_VALUE (link
));
6462 if (outtype
!= error_mark_node
6463 && (TREE_ADDRESSABLE (outtype
)
6464 || !COMPLETE_TYPE_P (outtype
)
6465 || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (outtype
))))
6471 error ("impossible constraint in %<asm%>");
6472 error ("non-memory output %d must stay in memory", i
);
6477 if (!allows_reg
&& allows_mem
)
6478 mark_addressable (TREE_VALUE (link
));
6480 tree orig
= TREE_VALUE (link
);
6481 tret
= gimplify_expr (&TREE_VALUE (link
), pre_p
, post_p
,
6482 is_inout
? is_gimple_min_lval
: is_gimple_lvalue
,
6483 fb_lvalue
| fb_mayfail
);
6484 if (tret
== GS_ERROR
)
6486 if (orig
!= error_mark_node
)
6487 error ("invalid lvalue in %<asm%> output %d", i
);
6491 /* If the constraint does not allow memory make sure we gimplify
6492 it to a register if it is not already but its base is. This
6493 happens for complex and vector components. */
6496 tree op
= TREE_VALUE (link
);
6497 if (! is_gimple_val (op
)
6498 && is_gimple_reg_type (TREE_TYPE (op
))
6499 && is_gimple_reg (get_base_address (op
)))
6501 tree tem
= create_tmp_reg (TREE_TYPE (op
));
6505 ass
= build2 (MODIFY_EXPR
, TREE_TYPE (tem
),
6506 tem
, unshare_expr (op
));
6507 gimplify_and_add (ass
, pre_p
);
6509 ass
= build2 (MODIFY_EXPR
, TREE_TYPE (tem
), op
, tem
);
6510 gimplify_and_add (ass
, post_p
);
6512 TREE_VALUE (link
) = tem
;
6517 vec_safe_push (outputs
, link
);
6518 TREE_CHAIN (link
) = NULL_TREE
;
6522 /* An input/output operand. To give the optimizers more
6523 flexibility, split it into separate input and output
6526 /* Buffer big enough to format a 32-bit UINT_MAX into. */
6529 /* Turn the in/out constraint into an output constraint. */
6530 char *p
= xstrdup (constraint
);
6532 TREE_VALUE (TREE_PURPOSE (link
)) = build_string (constraint_len
, p
);
6534 /* And add a matching input constraint. */
6537 sprintf (buf
, "%u", i
);
6539 /* If there are multiple alternatives in the constraint,
6540 handle each of them individually. Those that allow register
6541 will be replaced with operand number, the others will stay
6543 if (strchr (p
, ',') != NULL
)
6545 size_t len
= 0, buflen
= strlen (buf
);
6546 char *beg
, *end
, *str
, *dst
;
6550 end
= strchr (beg
, ',');
6552 end
= strchr (beg
, '\0');
6553 if ((size_t) (end
- beg
) < buflen
)
6556 len
+= end
- beg
+ 1;
6563 str
= (char *) alloca (len
);
6564 for (beg
= p
+ 1, dst
= str
;;)
6567 bool mem_p
, reg_p
, inout_p
;
6569 end
= strchr (beg
, ',');
6574 parse_output_constraint (&tem
, i
, 0, 0,
6575 &mem_p
, ®_p
, &inout_p
);
6580 memcpy (dst
, buf
, buflen
);
6589 memcpy (dst
, beg
, len
);
6598 input
= build_string (dst
- str
, str
);
6601 input
= build_string (strlen (buf
), buf
);
6604 input
= build_string (constraint_len
- 1, constraint
+ 1);
6608 input
= build_tree_list (build_tree_list (NULL_TREE
, input
),
6609 unshare_expr (TREE_VALUE (link
)));
6610 ASM_INPUTS (expr
) = chainon (ASM_INPUTS (expr
), input
);
6614 link_next
= NULL_TREE
;
6615 for (link
= ASM_INPUTS (expr
); link
; ++i
, link
= link_next
)
6617 link_next
= TREE_CHAIN (link
);
6618 constraint
= TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link
)));
6619 parse_input_constraint (&constraint
, 0, 0, noutputs
, 0,
6620 oconstraints
, &allows_mem
, &allows_reg
);
6622 /* If we can't make copies, we can only accept memory. */
6623 tree intype
= TREE_TYPE (TREE_VALUE (link
));
6624 if (intype
!= error_mark_node
6625 && (TREE_ADDRESSABLE (intype
)
6626 || !COMPLETE_TYPE_P (intype
)
6627 || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (intype
))))
6633 error ("impossible constraint in %<asm%>");
6634 error ("non-memory input %d must stay in memory", i
);
6639 /* If the operand is a memory input, it should be an lvalue. */
6640 if (!allows_reg
&& allows_mem
)
6642 tree inputv
= TREE_VALUE (link
);
6643 STRIP_NOPS (inputv
);
6644 if (TREE_CODE (inputv
) == PREDECREMENT_EXPR
6645 || TREE_CODE (inputv
) == PREINCREMENT_EXPR
6646 || TREE_CODE (inputv
) == POSTDECREMENT_EXPR
6647 || TREE_CODE (inputv
) == POSTINCREMENT_EXPR
6648 || TREE_CODE (inputv
) == MODIFY_EXPR
)
6649 TREE_VALUE (link
) = error_mark_node
;
6650 tret
= gimplify_expr (&TREE_VALUE (link
), pre_p
, post_p
,
6651 is_gimple_lvalue
, fb_lvalue
| fb_mayfail
);
6652 if (tret
!= GS_ERROR
)
6654 /* Unlike output operands, memory inputs are not guaranteed
6655 to be lvalues by the FE, and while the expressions are
6656 marked addressable there, if it is e.g. a statement
6657 expression, temporaries in it might not end up being
6658 addressable. They might be already used in the IL and thus
6659 it is too late to make them addressable now though. */
6660 tree x
= TREE_VALUE (link
);
6661 while (handled_component_p (x
))
6662 x
= TREE_OPERAND (x
, 0);
6663 if (TREE_CODE (x
) == MEM_REF
6664 && TREE_CODE (TREE_OPERAND (x
, 0)) == ADDR_EXPR
)
6665 x
= TREE_OPERAND (TREE_OPERAND (x
, 0), 0);
6667 || TREE_CODE (x
) == PARM_DECL
6668 || TREE_CODE (x
) == RESULT_DECL
)
6669 && !TREE_ADDRESSABLE (x
)
6670 && is_gimple_reg (x
))
6672 warning_at (EXPR_LOC_OR_LOC (TREE_VALUE (link
),
6674 "memory input %d is not directly addressable",
6676 prepare_gimple_addressable (&TREE_VALUE (link
), pre_p
);
6679 mark_addressable (TREE_VALUE (link
));
6680 if (tret
== GS_ERROR
)
6682 if (inputv
!= error_mark_node
)
6683 error_at (EXPR_LOC_OR_LOC (TREE_VALUE (link
), input_location
),
6684 "memory input %d is not directly addressable", i
);
6690 tret
= gimplify_expr (&TREE_VALUE (link
), pre_p
, post_p
,
6691 is_gimple_asm_val
, fb_rvalue
);
6692 if (tret
== GS_ERROR
)
6696 TREE_CHAIN (link
) = NULL_TREE
;
6697 vec_safe_push (inputs
, link
);
6700 link_next
= NULL_TREE
;
6701 for (link
= ASM_CLOBBERS (expr
); link
; ++i
, link
= link_next
)
6703 link_next
= TREE_CHAIN (link
);
6704 TREE_CHAIN (link
) = NULL_TREE
;
6705 vec_safe_push (clobbers
, link
);
6708 link_next
= NULL_TREE
;
6709 for (link
= ASM_LABELS (expr
); link
; ++i
, link
= link_next
)
6711 link_next
= TREE_CHAIN (link
);
6712 TREE_CHAIN (link
) = NULL_TREE
;
6713 vec_safe_push (labels
, link
);
6716 /* Do not add ASMs with errors to the gimple IL stream. */
6717 if (ret
!= GS_ERROR
)
6719 stmt
= gimple_build_asm_vec (TREE_STRING_POINTER (ASM_STRING (expr
)),
6720 inputs
, outputs
, clobbers
, labels
);
6722 gimple_asm_set_volatile (stmt
, ASM_VOLATILE_P (expr
) || noutputs
== 0);
6723 gimple_asm_set_input (stmt
, ASM_INPUT_P (expr
));
6724 gimple_asm_set_inline (stmt
, ASM_INLINE_P (expr
));
6726 gimplify_seq_add_stmt (pre_p
, stmt
);
6732 /* Gimplify a CLEANUP_POINT_EXPR. Currently this works by adding
6733 GIMPLE_WITH_CLEANUP_EXPRs to the prequeue as we encounter cleanups while
6734 gimplifying the body, and converting them to TRY_FINALLY_EXPRs when we
6735 return to this function.
6737 FIXME should we complexify the prequeue handling instead? Or use flags
6738 for all the cleanups and let the optimizer tighten them up? The current
6739 code seems pretty fragile; it will break on a cleanup within any
6740 non-conditional nesting. But any such nesting would be broken, anyway;
6741 we can't write a TRY_FINALLY_EXPR that starts inside a nesting construct
6742 and continues out of it. We can do that at the RTL level, though, so
6743 having an optimizer to tighten up try/finally regions would be a Good
6746 static enum gimplify_status
6747 gimplify_cleanup_point_expr (tree
*expr_p
, gimple_seq
*pre_p
)
6749 gimple_stmt_iterator iter
;
6750 gimple_seq body_sequence
= NULL
;
6752 tree temp
= voidify_wrapper_expr (*expr_p
, NULL
);
6754 /* We only care about the number of conditions between the innermost
6755 CLEANUP_POINT_EXPR and the cleanup. So save and reset the count and
6756 any cleanups collected outside the CLEANUP_POINT_EXPR. */
6757 int old_conds
= gimplify_ctxp
->conditions
;
6758 gimple_seq old_cleanups
= gimplify_ctxp
->conditional_cleanups
;
6759 bool old_in_cleanup_point_expr
= gimplify_ctxp
->in_cleanup_point_expr
;
6760 gimplify_ctxp
->conditions
= 0;
6761 gimplify_ctxp
->conditional_cleanups
= NULL
;
6762 gimplify_ctxp
->in_cleanup_point_expr
= true;
6764 gimplify_stmt (&TREE_OPERAND (*expr_p
, 0), &body_sequence
);
6766 gimplify_ctxp
->conditions
= old_conds
;
6767 gimplify_ctxp
->conditional_cleanups
= old_cleanups
;
6768 gimplify_ctxp
->in_cleanup_point_expr
= old_in_cleanup_point_expr
;
6770 for (iter
= gsi_start (body_sequence
); !gsi_end_p (iter
); )
6772 gimple
*wce
= gsi_stmt (iter
);
6774 if (gimple_code (wce
) == GIMPLE_WITH_CLEANUP_EXPR
)
6776 if (gsi_one_before_end_p (iter
))
6778 /* Note that gsi_insert_seq_before and gsi_remove do not
6779 scan operands, unlike some other sequence mutators. */
6780 if (!gimple_wce_cleanup_eh_only (wce
))
6781 gsi_insert_seq_before_without_update (&iter
,
6782 gimple_wce_cleanup (wce
),
6784 gsi_remove (&iter
, true);
6791 enum gimple_try_flags kind
;
6793 if (gimple_wce_cleanup_eh_only (wce
))
6794 kind
= GIMPLE_TRY_CATCH
;
6796 kind
= GIMPLE_TRY_FINALLY
;
6797 seq
= gsi_split_seq_after (iter
);
6799 gtry
= gimple_build_try (seq
, gimple_wce_cleanup (wce
), kind
);
6800 /* Do not use gsi_replace here, as it may scan operands.
6801 We want to do a simple structural modification only. */
6802 gsi_set_stmt (&iter
, gtry
);
6803 iter
= gsi_start (gtry
->eval
);
6810 gimplify_seq_add_seq (pre_p
, body_sequence
);
6823 /* Insert a cleanup marker for gimplify_cleanup_point_expr. CLEANUP
6824 is the cleanup action required. EH_ONLY is true if the cleanup should
6825 only be executed if an exception is thrown, not on normal exit.
6826 If FORCE_UNCOND is true perform the cleanup unconditionally; this is
6827 only valid for clobbers. */
6830 gimple_push_cleanup (tree var
, tree cleanup
, bool eh_only
, gimple_seq
*pre_p
,
6831 bool force_uncond
= false)
6834 gimple_seq cleanup_stmts
= NULL
;
6836 /* Errors can result in improperly nested cleanups. Which results in
6837 confusion when trying to resolve the GIMPLE_WITH_CLEANUP_EXPR. */
6841 if (gimple_conditional_context ())
6843 /* If we're in a conditional context, this is more complex. We only
6844 want to run the cleanup if we actually ran the initialization that
6845 necessitates it, but we want to run it after the end of the
6846 conditional context. So we wrap the try/finally around the
6847 condition and use a flag to determine whether or not to actually
6848 run the destructor. Thus
6852 becomes (approximately)
6856 if (test) { A::A(temp); flag = 1; val = f(temp); }
6859 if (flag) A::~A(temp);
6865 gimplify_stmt (&cleanup
, &cleanup_stmts
);
6866 wce
= gimple_build_wce (cleanup_stmts
);
6867 gimplify_seq_add_stmt (&gimplify_ctxp
->conditional_cleanups
, wce
);
6871 tree flag
= create_tmp_var (boolean_type_node
, "cleanup");
6872 gassign
*ffalse
= gimple_build_assign (flag
, boolean_false_node
);
6873 gassign
*ftrue
= gimple_build_assign (flag
, boolean_true_node
);
6875 cleanup
= build3 (COND_EXPR
, void_type_node
, flag
, cleanup
, NULL
);
6876 gimplify_stmt (&cleanup
, &cleanup_stmts
);
6877 wce
= gimple_build_wce (cleanup_stmts
);
6879 gimplify_seq_add_stmt (&gimplify_ctxp
->conditional_cleanups
, ffalse
);
6880 gimplify_seq_add_stmt (&gimplify_ctxp
->conditional_cleanups
, wce
);
6881 gimplify_seq_add_stmt (pre_p
, ftrue
);
6883 /* Because of this manipulation, and the EH edges that jump
6884 threading cannot redirect, the temporary (VAR) will appear
6885 to be used uninitialized. Don't warn. */
6886 suppress_warning (var
, OPT_Wuninitialized
);
6891 gimplify_stmt (&cleanup
, &cleanup_stmts
);
6892 wce
= gimple_build_wce (cleanup_stmts
);
6893 gimple_wce_set_cleanup_eh_only (wce
, eh_only
);
6894 gimplify_seq_add_stmt (pre_p
, wce
);
6898 /* Gimplify a TARGET_EXPR which doesn't appear on the rhs of an INIT_EXPR. */
6900 static enum gimplify_status
6901 gimplify_target_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
)
6903 tree targ
= *expr_p
;
6904 tree temp
= TARGET_EXPR_SLOT (targ
);
6905 tree init
= TARGET_EXPR_INITIAL (targ
);
6906 enum gimplify_status ret
;
6908 bool unpoison_empty_seq
= false;
6909 gimple_stmt_iterator unpoison_it
;
6913 tree cleanup
= NULL_TREE
;
6915 /* TARGET_EXPR temps aren't part of the enclosing block, so add it
6916 to the temps list. Handle also variable length TARGET_EXPRs. */
6917 if (!poly_int_tree_p (DECL_SIZE (temp
)))
6919 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (temp
)))
6920 gimplify_type_sizes (TREE_TYPE (temp
), pre_p
);
6921 /* FIXME: this is correct only when the size of the type does
6922 not depend on expressions evaluated in init. */
6923 gimplify_vla_decl (temp
, pre_p
);
6927 /* Save location where we need to place unpoisoning. It's possible
6928 that a variable will be converted to needs_to_live_in_memory. */
6929 unpoison_it
= gsi_last (*pre_p
);
6930 unpoison_empty_seq
= gsi_end_p (unpoison_it
);
6932 gimple_add_tmp_var (temp
);
6935 /* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the
6936 expression is supposed to initialize the slot. */
6937 if (VOID_TYPE_P (TREE_TYPE (init
)))
6938 ret
= gimplify_expr (&init
, pre_p
, post_p
, is_gimple_stmt
, fb_none
);
6941 tree init_expr
= build2 (INIT_EXPR
, void_type_node
, temp
, init
);
6943 ret
= gimplify_expr (&init
, pre_p
, post_p
, is_gimple_stmt
, fb_none
);
6945 ggc_free (init_expr
);
6947 if (ret
== GS_ERROR
)
6949 /* PR c++/28266 Make sure this is expanded only once. */
6950 TARGET_EXPR_INITIAL (targ
) = NULL_TREE
;
6954 gimplify_and_add (init
, pre_p
);
6956 /* If needed, push the cleanup for the temp. */
6957 if (TARGET_EXPR_CLEANUP (targ
))
6959 if (CLEANUP_EH_ONLY (targ
))
6960 gimple_push_cleanup (temp
, TARGET_EXPR_CLEANUP (targ
),
6961 CLEANUP_EH_ONLY (targ
), pre_p
);
6963 cleanup
= TARGET_EXPR_CLEANUP (targ
);
6966 /* Add a clobber for the temporary going out of scope, like
6967 gimplify_bind_expr. */
6968 if (gimplify_ctxp
->in_cleanup_point_expr
6969 && needs_to_live_in_memory (temp
))
6971 if (flag_stack_reuse
== SR_ALL
)
6973 tree clobber
= build_clobber (TREE_TYPE (temp
));
6974 clobber
= build2 (MODIFY_EXPR
, TREE_TYPE (temp
), temp
, clobber
);
6975 gimple_push_cleanup (temp
, clobber
, false, pre_p
, true);
6977 if (asan_poisoned_variables
6978 && DECL_ALIGN (temp
) <= MAX_SUPPORTED_STACK_ALIGNMENT
6979 && !TREE_STATIC (temp
)
6980 && dbg_cnt (asan_use_after_scope
)
6981 && !gimplify_omp_ctxp
)
6983 tree asan_cleanup
= build_asan_poison_call_expr (temp
);
6986 if (unpoison_empty_seq
)
6987 unpoison_it
= gsi_start (*pre_p
);
6989 asan_poison_variable (temp
, false, &unpoison_it
,
6990 unpoison_empty_seq
);
6991 gimple_push_cleanup (temp
, asan_cleanup
, false, pre_p
);
6996 gimple_push_cleanup (temp
, cleanup
, false, pre_p
);
6998 /* Only expand this once. */
6999 TREE_OPERAND (targ
, 3) = init
;
7000 TARGET_EXPR_INITIAL (targ
) = NULL_TREE
;
7003 /* We should have expanded this before. */
7004 gcc_assert (DECL_SEEN_IN_BIND_EXPR_P (temp
));
7010 /* Gimplification of expression trees. */
7012 /* Gimplify an expression which appears at statement context. The
7013 corresponding GIMPLE statements are added to *SEQ_P. If *SEQ_P is
7014 NULL, a new sequence is allocated.
7016 Return true if we actually added a statement to the queue. */
7019 gimplify_stmt (tree
*stmt_p
, gimple_seq
*seq_p
)
7021 gimple_seq_node last
;
7023 last
= gimple_seq_last (*seq_p
);
7024 gimplify_expr (stmt_p
, seq_p
, NULL
, is_gimple_stmt
, fb_none
);
7025 return last
!= gimple_seq_last (*seq_p
);
7028 /* Add FIRSTPRIVATE entries for DECL in the OpenMP the surrounding parallels
7029 to CTX. If entries already exist, force them to be some flavor of private.
7030 If there is no enclosing parallel, do nothing. */
7033 omp_firstprivatize_variable (struct gimplify_omp_ctx
*ctx
, tree decl
)
7037 if (decl
== NULL
|| !DECL_P (decl
) || ctx
->region_type
== ORT_NONE
)
7042 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
)decl
);
7045 if (n
->value
& GOVD_SHARED
)
7046 n
->value
= GOVD_FIRSTPRIVATE
| (n
->value
& GOVD_SEEN
);
7047 else if (n
->value
& GOVD_MAP
)
7048 n
->value
|= GOVD_MAP_TO_ONLY
;
7052 else if ((ctx
->region_type
& ORT_TARGET
) != 0)
7054 if (ctx
->defaultmap
[GDMK_SCALAR
] & GOVD_FIRSTPRIVATE
)
7055 omp_add_variable (ctx
, decl
, GOVD_FIRSTPRIVATE
);
7057 omp_add_variable (ctx
, decl
, GOVD_MAP
| GOVD_MAP_TO_ONLY
);
7059 else if (ctx
->region_type
!= ORT_WORKSHARE
7060 && ctx
->region_type
!= ORT_TASKGROUP
7061 && ctx
->region_type
!= ORT_SIMD
7062 && ctx
->region_type
!= ORT_ACC
7063 && !(ctx
->region_type
& ORT_TARGET_DATA
))
7064 omp_add_variable (ctx
, decl
, GOVD_FIRSTPRIVATE
);
7066 ctx
= ctx
->outer_context
;
7071 /* Similarly for each of the type sizes of TYPE. */
7074 omp_firstprivatize_type_sizes (struct gimplify_omp_ctx
*ctx
, tree type
)
7076 if (type
== NULL
|| type
== error_mark_node
)
7078 type
= TYPE_MAIN_VARIANT (type
);
7080 if (ctx
->privatized_types
->add (type
))
7083 switch (TREE_CODE (type
))
7089 case FIXED_POINT_TYPE
:
7090 omp_firstprivatize_variable (ctx
, TYPE_MIN_VALUE (type
));
7091 omp_firstprivatize_variable (ctx
, TYPE_MAX_VALUE (type
));
7095 omp_firstprivatize_type_sizes (ctx
, TREE_TYPE (type
));
7096 omp_firstprivatize_type_sizes (ctx
, TYPE_DOMAIN (type
));
7101 case QUAL_UNION_TYPE
:
7104 for (field
= TYPE_FIELDS (type
); field
; field
= DECL_CHAIN (field
))
7105 if (TREE_CODE (field
) == FIELD_DECL
)
7107 omp_firstprivatize_variable (ctx
, DECL_FIELD_OFFSET (field
));
7108 omp_firstprivatize_type_sizes (ctx
, TREE_TYPE (field
));
7114 case REFERENCE_TYPE
:
7115 omp_firstprivatize_type_sizes (ctx
, TREE_TYPE (type
));
7122 omp_firstprivatize_variable (ctx
, TYPE_SIZE (type
));
7123 omp_firstprivatize_variable (ctx
, TYPE_SIZE_UNIT (type
));
7124 lang_hooks
.types
.omp_firstprivatize_type_sizes (ctx
, type
);
7127 /* Add an entry for DECL in the OMP context CTX with FLAGS. */
7130 omp_add_variable (struct gimplify_omp_ctx
*ctx
, tree decl
, unsigned int flags
)
7133 unsigned int nflags
;
7136 if (error_operand_p (decl
) || ctx
->region_type
== ORT_NONE
)
7139 /* Never elide decls whose type has TREE_ADDRESSABLE set. This means
7140 there are constructors involved somewhere. Exception is a shared clause,
7141 there is nothing privatized in that case. */
7142 if ((flags
& GOVD_SHARED
) == 0
7143 && (TREE_ADDRESSABLE (TREE_TYPE (decl
))
7144 || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl
))))
7147 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
)decl
);
7148 if (n
!= NULL
&& (n
->value
& GOVD_DATA_SHARE_CLASS
) != 0)
7150 /* We shouldn't be re-adding the decl with the same data
7152 gcc_assert ((n
->value
& GOVD_DATA_SHARE_CLASS
& flags
) == 0);
7153 nflags
= n
->value
| flags
;
7154 /* The only combination of data sharing classes we should see is
7155 FIRSTPRIVATE and LASTPRIVATE. However, OpenACC permits
7156 reduction variables to be used in data sharing clauses. */
7157 gcc_assert ((ctx
->region_type
& ORT_ACC
) != 0
7158 || ((nflags
& GOVD_DATA_SHARE_CLASS
)
7159 == (GOVD_FIRSTPRIVATE
| GOVD_LASTPRIVATE
))
7160 || (flags
& GOVD_DATA_SHARE_CLASS
) == 0);
7165 /* When adding a variable-sized variable, we have to handle all sorts
7166 of additional bits of data: the pointer replacement variable, and
7167 the parameters of the type. */
7168 if (DECL_SIZE (decl
) && TREE_CODE (DECL_SIZE (decl
)) != INTEGER_CST
)
7170 /* Add the pointer replacement variable as PRIVATE if the variable
7171 replacement is private, else FIRSTPRIVATE since we'll need the
7172 address of the original variable either for SHARED, or for the
7173 copy into or out of the context. */
7174 if (!(flags
& GOVD_LOCAL
) && ctx
->region_type
!= ORT_TASKGROUP
)
7176 if (flags
& GOVD_MAP
)
7177 nflags
= GOVD_MAP
| GOVD_MAP_TO_ONLY
| GOVD_EXPLICIT
;
7178 else if (flags
& GOVD_PRIVATE
)
7179 nflags
= GOVD_PRIVATE
;
7180 else if (((ctx
->region_type
& (ORT_TARGET
| ORT_TARGET_DATA
)) != 0
7181 && (flags
& GOVD_FIRSTPRIVATE
))
7182 || (ctx
->region_type
== ORT_TARGET_DATA
7183 && (flags
& GOVD_DATA_SHARE_CLASS
) == 0))
7184 nflags
= GOVD_PRIVATE
| GOVD_EXPLICIT
;
7186 nflags
= GOVD_FIRSTPRIVATE
;
7187 nflags
|= flags
& GOVD_SEEN
;
7188 t
= DECL_VALUE_EXPR (decl
);
7189 gcc_assert (TREE_CODE (t
) == INDIRECT_REF
);
7190 t
= TREE_OPERAND (t
, 0);
7191 gcc_assert (DECL_P (t
));
7192 omp_add_variable (ctx
, t
, nflags
);
7195 /* Add all of the variable and type parameters (which should have
7196 been gimplified to a formal temporary) as FIRSTPRIVATE. */
7197 omp_firstprivatize_variable (ctx
, DECL_SIZE_UNIT (decl
));
7198 omp_firstprivatize_variable (ctx
, DECL_SIZE (decl
));
7199 omp_firstprivatize_type_sizes (ctx
, TREE_TYPE (decl
));
7201 /* The variable-sized variable itself is never SHARED, only some form
7202 of PRIVATE. The sharing would take place via the pointer variable
7203 which we remapped above. */
7204 if (flags
& GOVD_SHARED
)
7205 flags
= GOVD_SHARED
| GOVD_DEBUG_PRIVATE
7206 | (flags
& (GOVD_SEEN
| GOVD_EXPLICIT
));
7208 /* We're going to make use of the TYPE_SIZE_UNIT at least in the
7209 alloca statement we generate for the variable, so make sure it
7210 is available. This isn't automatically needed for the SHARED
7211 case, since we won't be allocating local storage then.
7212 For local variables TYPE_SIZE_UNIT might not be gimplified yet,
7213 in this case omp_notice_variable will be called later
7214 on when it is gimplified. */
7215 else if (! (flags
& (GOVD_LOCAL
| GOVD_MAP
))
7216 && DECL_P (TYPE_SIZE_UNIT (TREE_TYPE (decl
))))
7217 omp_notice_variable (ctx
, TYPE_SIZE_UNIT (TREE_TYPE (decl
)), true);
7219 else if ((flags
& (GOVD_MAP
| GOVD_LOCAL
)) == 0
7220 && omp_privatize_by_reference (decl
))
7222 omp_firstprivatize_type_sizes (ctx
, TREE_TYPE (decl
));
7224 /* Similar to the direct variable sized case above, we'll need the
7225 size of references being privatized. */
7226 if ((flags
& GOVD_SHARED
) == 0)
7228 t
= TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl
)));
7229 if (t
&& DECL_P (t
))
7230 omp_notice_variable (ctx
, t
, true);
7237 splay_tree_insert (ctx
->variables
, (splay_tree_key
)decl
, flags
);
7239 /* For reductions clauses in OpenACC loop directives, by default create a
7240 copy clause on the enclosing parallel construct for carrying back the
7242 if (ctx
->region_type
== ORT_ACC
&& (flags
& GOVD_REDUCTION
))
7244 struct gimplify_omp_ctx
*outer_ctx
= ctx
->outer_context
;
7247 n
= splay_tree_lookup (outer_ctx
->variables
, (splay_tree_key
)decl
);
7250 /* Ignore local variables and explicitly declared clauses. */
7251 if (n
->value
& (GOVD_LOCAL
| GOVD_EXPLICIT
))
7253 else if (outer_ctx
->region_type
== ORT_ACC_KERNELS
)
7255 /* According to the OpenACC spec, such a reduction variable
7256 should already have a copy map on a kernels construct,
7257 verify that here. */
7258 gcc_assert (!(n
->value
& GOVD_FIRSTPRIVATE
)
7259 && (n
->value
& GOVD_MAP
));
7261 else if (outer_ctx
->region_type
== ORT_ACC_PARALLEL
)
7263 /* Remove firstprivate and make it a copy map. */
7264 n
->value
&= ~GOVD_FIRSTPRIVATE
;
7265 n
->value
|= GOVD_MAP
;
7268 else if (outer_ctx
->region_type
== ORT_ACC_PARALLEL
)
7270 splay_tree_insert (outer_ctx
->variables
, (splay_tree_key
)decl
,
7271 GOVD_MAP
| GOVD_SEEN
);
7274 outer_ctx
= outer_ctx
->outer_context
;
7279 /* Notice a threadprivate variable DECL used in OMP context CTX.
7280 This just prints out diagnostics about threadprivate variable uses
7281 in untied tasks. If DECL2 is non-NULL, prevent this warning
7282 on that variable. */
7285 omp_notice_threadprivate_variable (struct gimplify_omp_ctx
*ctx
, tree decl
,
7289 struct gimplify_omp_ctx
*octx
;
7291 for (octx
= ctx
; octx
; octx
= octx
->outer_context
)
7292 if ((octx
->region_type
& ORT_TARGET
) != 0
7293 || octx
->order_concurrent
)
7295 n
= splay_tree_lookup (octx
->variables
, (splay_tree_key
)decl
);
7298 if (octx
->order_concurrent
)
7300 error ("threadprivate variable %qE used in a region with"
7301 " %<order(concurrent)%> clause", DECL_NAME (decl
));
7302 inform (octx
->location
, "enclosing region");
7306 error ("threadprivate variable %qE used in target region",
7308 inform (octx
->location
, "enclosing target region");
7310 splay_tree_insert (octx
->variables
, (splay_tree_key
)decl
, 0);
7313 splay_tree_insert (octx
->variables
, (splay_tree_key
)decl2
, 0);
7316 if (ctx
->region_type
!= ORT_UNTIED_TASK
)
7318 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
)decl
);
7321 error ("threadprivate variable %qE used in untied task",
7323 inform (ctx
->location
, "enclosing task");
7324 splay_tree_insert (ctx
->variables
, (splay_tree_key
)decl
, 0);
7327 splay_tree_insert (ctx
->variables
, (splay_tree_key
)decl2
, 0);
7331 /* Return true if global var DECL is device resident. */
7334 device_resident_p (tree decl
)
7336 tree attr
= lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (decl
));
7341 for (tree t
= TREE_VALUE (attr
); t
; t
= TREE_PURPOSE (t
))
7343 tree c
= TREE_VALUE (t
);
7344 if (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_DEVICE_RESIDENT
)
7351 /* Return true if DECL has an ACC DECLARE attribute. */
7354 is_oacc_declared (tree decl
)
7356 tree t
= TREE_CODE (decl
) == MEM_REF
? TREE_OPERAND (decl
, 0) : decl
;
7357 tree declared
= lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (t
));
7358 return declared
!= NULL_TREE
;
7361 /* Determine outer default flags for DECL mentioned in an OMP region
7362 but not declared in an enclosing clause.
7364 ??? Some compiler-generated variables (like SAVE_EXPRs) could be
7365 remapped firstprivate instead of shared. To some extent this is
7366 addressed in omp_firstprivatize_type_sizes, but not
7370 omp_default_clause (struct gimplify_omp_ctx
*ctx
, tree decl
,
7371 bool in_code
, unsigned flags
)
7373 enum omp_clause_default_kind default_kind
= ctx
->default_kind
;
7374 enum omp_clause_default_kind kind
;
7376 kind
= lang_hooks
.decls
.omp_predetermined_sharing (decl
);
7377 if (ctx
->region_type
& ORT_TASK
)
7379 tree detach_clause
= omp_find_clause (ctx
->clauses
, OMP_CLAUSE_DETACH
);
7381 /* The event-handle specified by a detach clause should always be firstprivate,
7382 regardless of the current default. */
7383 if (detach_clause
&& OMP_CLAUSE_DECL (detach_clause
) == decl
)
7384 kind
= OMP_CLAUSE_DEFAULT_FIRSTPRIVATE
;
7386 if (kind
!= OMP_CLAUSE_DEFAULT_UNSPECIFIED
)
7387 default_kind
= kind
;
7388 else if (VAR_P (decl
) && TREE_STATIC (decl
) && DECL_IN_CONSTANT_POOL (decl
))
7389 default_kind
= OMP_CLAUSE_DEFAULT_SHARED
;
7390 /* For C/C++ default({,first}private), variables with static storage duration
7391 declared in a namespace or global scope and referenced in construct
7392 must be explicitly specified, i.e. acts as default(none). */
7393 else if ((default_kind
== OMP_CLAUSE_DEFAULT_PRIVATE
7394 || default_kind
== OMP_CLAUSE_DEFAULT_FIRSTPRIVATE
)
7396 && is_global_var (decl
)
7397 && (DECL_FILE_SCOPE_P (decl
)
7398 || (DECL_CONTEXT (decl
)
7399 && TREE_CODE (DECL_CONTEXT (decl
)) == NAMESPACE_DECL
))
7400 && !lang_GNU_Fortran ())
7401 default_kind
= OMP_CLAUSE_DEFAULT_NONE
;
7403 switch (default_kind
)
7405 case OMP_CLAUSE_DEFAULT_NONE
:
7409 if (ctx
->region_type
& ORT_PARALLEL
)
7411 else if ((ctx
->region_type
& ORT_TASKLOOP
) == ORT_TASKLOOP
)
7413 else if (ctx
->region_type
& ORT_TASK
)
7415 else if (ctx
->region_type
& ORT_TEAMS
)
7420 error ("%qE not specified in enclosing %qs",
7421 DECL_NAME (lang_hooks
.decls
.omp_report_decl (decl
)), rtype
);
7422 inform (ctx
->location
, "enclosing %qs", rtype
);
7425 case OMP_CLAUSE_DEFAULT_SHARED
:
7426 flags
|= GOVD_SHARED
;
7428 case OMP_CLAUSE_DEFAULT_PRIVATE
:
7429 flags
|= GOVD_PRIVATE
;
7431 case OMP_CLAUSE_DEFAULT_FIRSTPRIVATE
:
7432 flags
|= GOVD_FIRSTPRIVATE
;
7434 case OMP_CLAUSE_DEFAULT_UNSPECIFIED
:
7435 /* decl will be either GOVD_FIRSTPRIVATE or GOVD_SHARED. */
7436 gcc_assert ((ctx
->region_type
& ORT_TASK
) != 0);
7437 if (struct gimplify_omp_ctx
*octx
= ctx
->outer_context
)
7439 omp_notice_variable (octx
, decl
, in_code
);
7440 for (; octx
; octx
= octx
->outer_context
)
7444 n2
= splay_tree_lookup (octx
->variables
, (splay_tree_key
) decl
);
7445 if ((octx
->region_type
& (ORT_TARGET_DATA
| ORT_TARGET
)) != 0
7446 && (n2
== NULL
|| (n2
->value
& GOVD_DATA_SHARE_CLASS
) == 0))
7448 if (n2
&& (n2
->value
& GOVD_DATA_SHARE_CLASS
) != GOVD_SHARED
)
7450 flags
|= GOVD_FIRSTPRIVATE
;
7453 if ((octx
->region_type
& (ORT_PARALLEL
| ORT_TEAMS
)) != 0)
7455 flags
|= GOVD_SHARED
;
7461 if (TREE_CODE (decl
) == PARM_DECL
7462 || (!is_global_var (decl
)
7463 && DECL_CONTEXT (decl
) == current_function_decl
))
7464 flags
|= GOVD_FIRSTPRIVATE
;
7466 flags
|= GOVD_SHARED
;
7478 /* Determine outer default flags for DECL mentioned in an OACC region
7479 but not declared in an enclosing clause. */
7482 oacc_default_clause (struct gimplify_omp_ctx
*ctx
, tree decl
, unsigned flags
)
7485 bool on_device
= false;
7486 bool is_private
= false;
7487 bool declared
= is_oacc_declared (decl
);
7488 tree type
= TREE_TYPE (decl
);
7490 if (omp_privatize_by_reference (decl
))
7491 type
= TREE_TYPE (type
);
7493 /* For Fortran COMMON blocks, only used variables in those blocks are
7494 transfered and remapped. The block itself will have a private clause to
7495 avoid transfering the data twice.
7496 The hook evaluates to false by default. For a variable in Fortran's COMMON
7497 or EQUIVALENCE block, returns 'true' (as we have shared=false) - as only
7498 the variables in such a COMMON/EQUIVALENCE block shall be privatized not
7499 the whole block. For C++ and Fortran, it can also be true under certain
7500 other conditions, if DECL_HAS_VALUE_EXPR. */
7501 if (RECORD_OR_UNION_TYPE_P (type
))
7502 is_private
= lang_hooks
.decls
.omp_disregard_value_expr (decl
, false);
7504 if ((ctx
->region_type
& (ORT_ACC_PARALLEL
| ORT_ACC_KERNELS
)) != 0
7505 && is_global_var (decl
)
7506 && device_resident_p (decl
)
7510 flags
|= GOVD_MAP_TO_ONLY
;
7513 switch (ctx
->region_type
)
7515 case ORT_ACC_KERNELS
:
7519 flags
|= GOVD_FIRSTPRIVATE
;
7520 else if (AGGREGATE_TYPE_P (type
))
7522 /* Aggregates default to 'present_or_copy', or 'present'. */
7523 if (ctx
->default_kind
!= OMP_CLAUSE_DEFAULT_PRESENT
)
7526 flags
|= GOVD_MAP
| GOVD_MAP_FORCE_PRESENT
;
7529 /* Scalars default to 'copy'. */
7530 flags
|= GOVD_MAP
| GOVD_MAP_FORCE
;
7534 case ORT_ACC_PARALLEL
:
7535 case ORT_ACC_SERIAL
:
7536 rkind
= ctx
->region_type
== ORT_ACC_PARALLEL
? "parallel" : "serial";
7539 flags
|= GOVD_FIRSTPRIVATE
;
7540 else if (on_device
|| declared
)
7542 else if (AGGREGATE_TYPE_P (type
))
7544 /* Aggregates default to 'present_or_copy', or 'present'. */
7545 if (ctx
->default_kind
!= OMP_CLAUSE_DEFAULT_PRESENT
)
7548 flags
|= GOVD_MAP
| GOVD_MAP_FORCE_PRESENT
;
7551 /* Scalars default to 'firstprivate'. */
7552 flags
|= GOVD_FIRSTPRIVATE
;
7560 if (DECL_ARTIFICIAL (decl
))
7561 ; /* We can get compiler-generated decls, and should not complain
7563 else if (ctx
->default_kind
== OMP_CLAUSE_DEFAULT_NONE
)
7565 error ("%qE not specified in enclosing OpenACC %qs construct",
7566 DECL_NAME (lang_hooks
.decls
.omp_report_decl (decl
)), rkind
);
7567 inform (ctx
->location
, "enclosing OpenACC %qs construct", rkind
);
7569 else if (ctx
->default_kind
== OMP_CLAUSE_DEFAULT_PRESENT
)
7570 ; /* Handled above. */
7572 gcc_checking_assert (ctx
->default_kind
== OMP_CLAUSE_DEFAULT_SHARED
);
7577 /* Record the fact that DECL was used within the OMP context CTX.
7578 IN_CODE is true when real code uses DECL, and false when we should
7579 merely emit default(none) errors. Return true if DECL is going to
7580 be remapped and thus DECL shouldn't be gimplified into its
7581 DECL_VALUE_EXPR (if any). */
7584 omp_notice_variable (struct gimplify_omp_ctx
*ctx
, tree decl
, bool in_code
)
7587 unsigned flags
= in_code
? GOVD_SEEN
: 0;
7588 bool ret
= false, shared
;
7590 if (error_operand_p (decl
))
7593 if (ctx
->region_type
== ORT_NONE
)
7594 return lang_hooks
.decls
.omp_disregard_value_expr (decl
, false);
7596 if (is_global_var (decl
))
7598 /* Threadprivate variables are predetermined. */
7599 if (DECL_THREAD_LOCAL_P (decl
))
7600 return omp_notice_threadprivate_variable (ctx
, decl
, NULL_TREE
);
7602 if (DECL_HAS_VALUE_EXPR_P (decl
))
7604 if (ctx
->region_type
& ORT_ACC
)
7605 /* For OpenACC, defer expansion of value to avoid transfering
7606 privatized common block data instead of im-/explicitly transfered
7607 variables which are in common blocks. */
7611 tree value
= get_base_address (DECL_VALUE_EXPR (decl
));
7613 if (value
&& DECL_P (value
) && DECL_THREAD_LOCAL_P (value
))
7614 return omp_notice_threadprivate_variable (ctx
, decl
, value
);
7618 if (gimplify_omp_ctxp
->outer_context
== NULL
7620 && oacc_get_fn_attrib (current_function_decl
))
7622 location_t loc
= DECL_SOURCE_LOCATION (decl
);
7624 if (lookup_attribute ("omp declare target link",
7625 DECL_ATTRIBUTES (decl
)))
7628 "%qE with %<link%> clause used in %<routine%> function",
7632 else if (!lookup_attribute ("omp declare target",
7633 DECL_ATTRIBUTES (decl
)))
7636 "%qE requires a %<declare%> directive for use "
7637 "in a %<routine%> function", DECL_NAME (decl
));
7643 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
)decl
);
7644 if ((ctx
->region_type
& ORT_TARGET
) != 0)
7646 if (ctx
->region_type
& ORT_ACC
)
7647 /* For OpenACC, as remarked above, defer expansion. */
7652 ret
= lang_hooks
.decls
.omp_disregard_value_expr (decl
, shared
);
7655 unsigned nflags
= flags
;
7656 if ((ctx
->region_type
& ORT_ACC
) == 0)
7658 bool is_declare_target
= false;
7659 if (is_global_var (decl
)
7660 && varpool_node::get_create (decl
)->offloadable
)
7662 struct gimplify_omp_ctx
*octx
;
7663 for (octx
= ctx
->outer_context
;
7664 octx
; octx
= octx
->outer_context
)
7666 n
= splay_tree_lookup (octx
->variables
,
7667 (splay_tree_key
)decl
);
7669 && (n
->value
& GOVD_DATA_SHARE_CLASS
) != GOVD_SHARED
7670 && (n
->value
& GOVD_DATA_SHARE_CLASS
) != 0)
7673 is_declare_target
= octx
== NULL
;
7675 if (!is_declare_target
)
7678 enum omp_clause_defaultmap_kind kind
;
7679 if (lang_hooks
.decls
.omp_allocatable_p (decl
))
7680 gdmk
= GDMK_ALLOCATABLE
;
7681 else if (lang_hooks
.decls
.omp_scalar_target_p (decl
))
7682 gdmk
= GDMK_SCALAR_TARGET
;
7683 else if (lang_hooks
.decls
.omp_scalar_p (decl
, false))
7685 else if (TREE_CODE (TREE_TYPE (decl
)) == POINTER_TYPE
7686 || (TREE_CODE (TREE_TYPE (decl
)) == REFERENCE_TYPE
7687 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl
)))
7689 gdmk
= GDMK_POINTER
;
7691 gdmk
= GDMK_AGGREGATE
;
7692 kind
= lang_hooks
.decls
.omp_predetermined_mapping (decl
);
7693 if (kind
!= OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
)
7695 if (kind
== OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE
)
7696 nflags
|= GOVD_FIRSTPRIVATE
;
7697 else if (kind
== OMP_CLAUSE_DEFAULTMAP_TO
)
7698 nflags
|= GOVD_MAP
| GOVD_MAP_TO_ONLY
;
7702 else if (ctx
->defaultmap
[gdmk
] == 0)
7704 tree d
= lang_hooks
.decls
.omp_report_decl (decl
);
7705 error ("%qE not specified in enclosing %<target%>",
7707 inform (ctx
->location
, "enclosing %<target%>");
7709 else if (ctx
->defaultmap
[gdmk
]
7710 & (GOVD_MAP_0LEN_ARRAY
| GOVD_FIRSTPRIVATE
))
7711 nflags
|= ctx
->defaultmap
[gdmk
];
7714 gcc_assert (ctx
->defaultmap
[gdmk
] & GOVD_MAP
);
7715 nflags
|= ctx
->defaultmap
[gdmk
] & ~GOVD_MAP
;
7720 struct gimplify_omp_ctx
*octx
= ctx
->outer_context
;
7721 if ((ctx
->region_type
& ORT_ACC
) && octx
)
7723 /* Look in outer OpenACC contexts, to see if there's a
7724 data attribute for this variable. */
7725 omp_notice_variable (octx
, decl
, in_code
);
7727 for (; octx
; octx
= octx
->outer_context
)
7729 if (!(octx
->region_type
& (ORT_TARGET_DATA
| ORT_TARGET
)))
7732 = splay_tree_lookup (octx
->variables
,
7733 (splay_tree_key
) decl
);
7736 if (octx
->region_type
== ORT_ACC_HOST_DATA
)
7737 error ("variable %qE declared in enclosing "
7738 "%<host_data%> region", DECL_NAME (decl
));
7740 if (octx
->region_type
== ORT_ACC_DATA
7741 && (n2
->value
& GOVD_MAP_0LEN_ARRAY
))
7742 nflags
|= GOVD_MAP_0LEN_ARRAY
;
7748 if ((nflags
& ~(GOVD_MAP_TO_ONLY
| GOVD_MAP_FROM_ONLY
7749 | GOVD_MAP_ALLOC_ONLY
)) == flags
)
7751 tree type
= TREE_TYPE (decl
);
7753 if (gimplify_omp_ctxp
->target_firstprivatize_array_bases
7754 && omp_privatize_by_reference (decl
))
7755 type
= TREE_TYPE (type
);
7756 if (!lang_hooks
.types
.omp_mappable_type (type
))
7758 error ("%qD referenced in target region does not have "
7759 "a mappable type", decl
);
7760 nflags
|= GOVD_MAP
| GOVD_EXPLICIT
;
7764 if ((ctx
->region_type
& ORT_ACC
) != 0)
7765 nflags
= oacc_default_clause (ctx
, decl
, flags
);
7771 omp_add_variable (ctx
, decl
, nflags
);
7775 /* If nothing changed, there's nothing left to do. */
7776 if ((n
->value
& flags
) == flags
)
7786 if (ctx
->region_type
== ORT_WORKSHARE
7787 || ctx
->region_type
== ORT_TASKGROUP
7788 || ctx
->region_type
== ORT_SIMD
7789 || ctx
->region_type
== ORT_ACC
7790 || (ctx
->region_type
& ORT_TARGET_DATA
) != 0)
7793 flags
= omp_default_clause (ctx
, decl
, in_code
, flags
);
7795 if ((flags
& GOVD_PRIVATE
)
7796 && lang_hooks
.decls
.omp_private_outer_ref (decl
))
7797 flags
|= GOVD_PRIVATE_OUTER_REF
;
7799 omp_add_variable (ctx
, decl
, flags
);
7801 shared
= (flags
& GOVD_SHARED
) != 0;
7802 ret
= lang_hooks
.decls
.omp_disregard_value_expr (decl
, shared
);
7806 /* Don't mark as GOVD_SEEN addressable temporaries seen only in simd
7807 lb, b or incr expressions, those shouldn't be turned into simd arrays. */
7808 if (ctx
->region_type
== ORT_SIMD
7809 && ctx
->in_for_exprs
7810 && ((n
->value
& (GOVD_PRIVATE
| GOVD_SEEN
| GOVD_EXPLICIT
))
7812 flags
&= ~GOVD_SEEN
;
7814 if ((n
->value
& (GOVD_SEEN
| GOVD_LOCAL
)) == 0
7815 && (flags
& (GOVD_SEEN
| GOVD_LOCAL
)) == GOVD_SEEN
7816 && DECL_SIZE (decl
))
7818 if (TREE_CODE (DECL_SIZE (decl
)) != INTEGER_CST
)
7821 tree t
= DECL_VALUE_EXPR (decl
);
7822 gcc_assert (TREE_CODE (t
) == INDIRECT_REF
);
7823 t
= TREE_OPERAND (t
, 0);
7824 gcc_assert (DECL_P (t
));
7825 n2
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) t
);
7826 n2
->value
|= GOVD_SEEN
;
7828 else if (omp_privatize_by_reference (decl
)
7829 && TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl
)))
7830 && (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl
))))
7834 tree t
= TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl
)));
7835 gcc_assert (DECL_P (t
));
7836 n2
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) t
);
7838 omp_notice_variable (ctx
, t
, true);
7842 if (ctx
->region_type
& ORT_ACC
)
7843 /* For OpenACC, as remarked above, defer expansion. */
7846 shared
= ((flags
| n
->value
) & GOVD_SHARED
) != 0;
7847 ret
= lang_hooks
.decls
.omp_disregard_value_expr (decl
, shared
);
7849 /* If nothing changed, there's nothing left to do. */
7850 if ((n
->value
& flags
) == flags
)
7856 /* If the variable is private in the current context, then we don't
7857 need to propagate anything to an outer context. */
7858 if ((flags
& GOVD_PRIVATE
) && !(flags
& GOVD_PRIVATE_OUTER_REF
))
7860 if ((flags
& (GOVD_LINEAR
| GOVD_LINEAR_LASTPRIVATE_NO_OUTER
))
7861 == (GOVD_LINEAR
| GOVD_LINEAR_LASTPRIVATE_NO_OUTER
))
7863 if ((flags
& (GOVD_FIRSTPRIVATE
| GOVD_LASTPRIVATE
7864 | GOVD_LINEAR_LASTPRIVATE_NO_OUTER
))
7865 == (GOVD_LASTPRIVATE
| GOVD_LINEAR_LASTPRIVATE_NO_OUTER
))
7867 if (ctx
->outer_context
7868 && omp_notice_variable (ctx
->outer_context
, decl
, in_code
))
7873 /* Verify that DECL is private within CTX. If there's specific information
7874 to the contrary in the innermost scope, generate an error. */
7877 omp_is_private (struct gimplify_omp_ctx
*ctx
, tree decl
, int simd
)
7881 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
)decl
);
7884 if (n
->value
& GOVD_SHARED
)
7886 if (ctx
== gimplify_omp_ctxp
)
7889 error ("iteration variable %qE is predetermined linear",
7892 error ("iteration variable %qE should be private",
7894 n
->value
= GOVD_PRIVATE
;
7900 else if ((n
->value
& GOVD_EXPLICIT
) != 0
7901 && (ctx
== gimplify_omp_ctxp
7902 || (ctx
->region_type
== ORT_COMBINED_PARALLEL
7903 && gimplify_omp_ctxp
->outer_context
== ctx
)))
7905 if ((n
->value
& GOVD_FIRSTPRIVATE
) != 0)
7906 error ("iteration variable %qE should not be firstprivate",
7908 else if ((n
->value
& GOVD_REDUCTION
) != 0)
7909 error ("iteration variable %qE should not be reduction",
7911 else if (simd
!= 1 && (n
->value
& GOVD_LINEAR
) != 0)
7912 error ("iteration variable %qE should not be linear",
7915 return (ctx
== gimplify_omp_ctxp
7916 || (ctx
->region_type
== ORT_COMBINED_PARALLEL
7917 && gimplify_omp_ctxp
->outer_context
== ctx
));
7920 if (ctx
->region_type
!= ORT_WORKSHARE
7921 && ctx
->region_type
!= ORT_TASKGROUP
7922 && ctx
->region_type
!= ORT_SIMD
7923 && ctx
->region_type
!= ORT_ACC
)
7925 else if (ctx
->outer_context
)
7926 return omp_is_private (ctx
->outer_context
, decl
, simd
);
7930 /* Return true if DECL is private within a parallel region
7931 that binds to the current construct's context or in parallel
7932 region's REDUCTION clause. */
7935 omp_check_private (struct gimplify_omp_ctx
*ctx
, tree decl
, bool copyprivate
)
7941 ctx
= ctx
->outer_context
;
7944 if (is_global_var (decl
))
7947 /* References might be private, but might be shared too,
7948 when checking for copyprivate, assume they might be
7949 private, otherwise assume they might be shared. */
7953 if (omp_privatize_by_reference (decl
))
7956 /* Treat C++ privatized non-static data members outside
7957 of the privatization the same. */
7958 if (omp_member_access_dummy_var (decl
))
7964 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
7966 if ((ctx
->region_type
& (ORT_TARGET
| ORT_TARGET_DATA
)) != 0
7967 && (n
== NULL
|| (n
->value
& GOVD_DATA_SHARE_CLASS
) == 0))
7969 if ((ctx
->region_type
& ORT_TARGET_DATA
) != 0
7971 || (n
->value
& GOVD_MAP
) == 0)
7978 if ((n
->value
& GOVD_LOCAL
) != 0
7979 && omp_member_access_dummy_var (decl
))
7981 return (n
->value
& GOVD_SHARED
) == 0;
7984 if (ctx
->region_type
== ORT_WORKSHARE
7985 || ctx
->region_type
== ORT_TASKGROUP
7986 || ctx
->region_type
== ORT_SIMD
7987 || ctx
->region_type
== ORT_ACC
)
7996 /* Callback for walk_tree to find a DECL_EXPR for the given DECL. */
7999 find_decl_expr (tree
*tp
, int *walk_subtrees
, void *data
)
8003 /* If this node has been visited, unmark it and keep looking. */
8004 if (TREE_CODE (t
) == DECL_EXPR
&& DECL_EXPR_DECL (t
) == (tree
) data
)
8007 if (IS_TYPE_OR_DECL_P (t
))
8013 /* Gimplify the affinity clause but effectively ignore it.
8016 if ((step > 1) ? var <= end : var > end)
8017 locatator_var_expr; */
8020 gimplify_omp_affinity (tree
*list_p
, gimple_seq
*pre_p
)
8022 tree last_iter
= NULL_TREE
;
8023 tree last_bind
= NULL_TREE
;
8024 tree label
= NULL_TREE
;
8025 tree
*last_body
= NULL
;
8026 for (tree c
= *list_p
; c
; c
= OMP_CLAUSE_CHAIN (c
))
8027 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_AFFINITY
)
8029 tree t
= OMP_CLAUSE_DECL (c
);
8030 if (TREE_CODE (t
) == TREE_LIST
8032 && TREE_CODE (TREE_PURPOSE (t
)) == TREE_VEC
)
8034 if (TREE_VALUE (t
) == null_pointer_node
)
8036 if (TREE_PURPOSE (t
) != last_iter
)
8040 append_to_statement_list (label
, last_body
);
8041 gimplify_and_add (last_bind
, pre_p
);
8042 last_bind
= NULL_TREE
;
8044 for (tree it
= TREE_PURPOSE (t
); it
; it
= TREE_CHAIN (it
))
8046 if (gimplify_expr (&TREE_VEC_ELT (it
, 1), pre_p
, NULL
,
8047 is_gimple_val
, fb_rvalue
) == GS_ERROR
8048 || gimplify_expr (&TREE_VEC_ELT (it
, 2), pre_p
, NULL
,
8049 is_gimple_val
, fb_rvalue
) == GS_ERROR
8050 || gimplify_expr (&TREE_VEC_ELT (it
, 3), pre_p
, NULL
,
8051 is_gimple_val
, fb_rvalue
) == GS_ERROR
8052 || (gimplify_expr (&TREE_VEC_ELT (it
, 4), pre_p
, NULL
,
8053 is_gimple_val
, fb_rvalue
)
8057 last_iter
= TREE_PURPOSE (t
);
8058 tree block
= TREE_VEC_ELT (TREE_PURPOSE (t
), 5);
8059 last_bind
= build3 (BIND_EXPR
, void_type_node
, BLOCK_VARS (block
),
8061 last_body
= &BIND_EXPR_BODY (last_bind
);
8062 tree cond
= NULL_TREE
;
8063 location_t loc
= OMP_CLAUSE_LOCATION (c
);
8064 for (tree it
= TREE_PURPOSE (t
); it
; it
= TREE_CHAIN (it
))
8066 tree var
= TREE_VEC_ELT (it
, 0);
8067 tree begin
= TREE_VEC_ELT (it
, 1);
8068 tree end
= TREE_VEC_ELT (it
, 2);
8069 tree step
= TREE_VEC_ELT (it
, 3);
8070 loc
= DECL_SOURCE_LOCATION (var
);
8071 tree tem
= build2_loc (loc
, MODIFY_EXPR
, void_type_node
,
8073 append_to_statement_list_force (tem
, last_body
);
8075 tree cond1
= fold_build2_loc (loc
, GT_EXPR
, boolean_type_node
,
8076 step
, build_zero_cst (TREE_TYPE (step
)));
8077 tree cond2
= fold_build2_loc (loc
, LE_EXPR
, boolean_type_node
,
8079 tree cond3
= fold_build2_loc (loc
, GT_EXPR
, boolean_type_node
,
8081 cond1
= fold_build3_loc (loc
, COND_EXPR
, boolean_type_node
,
8082 cond1
, cond2
, cond3
);
8084 cond
= fold_build2_loc (loc
, TRUTH_AND_EXPR
,
8085 boolean_type_node
, cond
, cond1
);
8089 tree cont_label
= create_artificial_label (loc
);
8090 label
= build1 (LABEL_EXPR
, void_type_node
, cont_label
);
8091 tree tem
= fold_build3_loc (loc
, COND_EXPR
, void_type_node
, cond
,
8093 build_and_jump (&cont_label
));
8094 append_to_statement_list_force (tem
, last_body
);
8096 if (TREE_CODE (TREE_VALUE (t
)) == COMPOUND_EXPR
)
8098 append_to_statement_list (TREE_OPERAND (TREE_VALUE (t
), 0),
8100 TREE_VALUE (t
) = TREE_OPERAND (TREE_VALUE (t
), 1);
8102 if (error_operand_p (TREE_VALUE (t
)))
8104 append_to_statement_list_force (TREE_VALUE (t
), last_body
);
8105 TREE_VALUE (t
) = null_pointer_node
;
8111 append_to_statement_list (label
, last_body
);
8112 gimplify_and_add (last_bind
, pre_p
);
8113 last_bind
= NULL_TREE
;
8115 if (TREE_CODE (OMP_CLAUSE_DECL (c
)) == COMPOUND_EXPR
)
8117 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c
), 0), pre_p
,
8118 NULL
, is_gimple_val
, fb_rvalue
);
8119 OMP_CLAUSE_DECL (c
) = TREE_OPERAND (OMP_CLAUSE_DECL (c
), 1);
8121 if (error_operand_p (OMP_CLAUSE_DECL (c
)))
8123 if (gimplify_expr (&OMP_CLAUSE_DECL (c
), pre_p
, NULL
,
8124 is_gimple_val
, fb_rvalue
) == GS_ERROR
)
8126 gimplify_and_add (OMP_CLAUSE_DECL (c
), pre_p
);
8131 append_to_statement_list (label
, last_body
);
8132 gimplify_and_add (last_bind
, pre_p
);
8137 /* If *LIST_P contains any OpenMP depend clauses with iterators,
8138 lower all the depend clauses by populating corresponding depend
8139 array. Returns 0 if there are no such depend clauses, or
8140 2 if all depend clauses should be removed, 1 otherwise. */
8143 gimplify_omp_depend (tree
*list_p
, gimple_seq
*pre_p
)
8147 size_t n
[4] = { 0, 0, 0, 0 };
8149 tree counts
[4] = { NULL_TREE
, NULL_TREE
, NULL_TREE
, NULL_TREE
};
8150 tree last_iter
= NULL_TREE
, last_count
= NULL_TREE
;
8152 location_t first_loc
= UNKNOWN_LOCATION
;
8154 for (c
= *list_p
; c
; c
= OMP_CLAUSE_CHAIN (c
))
8155 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEPEND
)
8157 switch (OMP_CLAUSE_DEPEND_KIND (c
))
8159 case OMP_CLAUSE_DEPEND_IN
:
8162 case OMP_CLAUSE_DEPEND_OUT
:
8163 case OMP_CLAUSE_DEPEND_INOUT
:
8166 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET
:
8169 case OMP_CLAUSE_DEPEND_DEPOBJ
:
8172 case OMP_CLAUSE_DEPEND_SOURCE
:
8173 case OMP_CLAUSE_DEPEND_SINK
:
8178 tree t
= OMP_CLAUSE_DECL (c
);
8179 if (first_loc
== UNKNOWN_LOCATION
)
8180 first_loc
= OMP_CLAUSE_LOCATION (c
);
8181 if (TREE_CODE (t
) == TREE_LIST
8183 && TREE_CODE (TREE_PURPOSE (t
)) == TREE_VEC
)
8185 if (TREE_PURPOSE (t
) != last_iter
)
8187 tree tcnt
= size_one_node
;
8188 for (tree it
= TREE_PURPOSE (t
); it
; it
= TREE_CHAIN (it
))
8190 if (gimplify_expr (&TREE_VEC_ELT (it
, 1), pre_p
, NULL
,
8191 is_gimple_val
, fb_rvalue
) == GS_ERROR
8192 || gimplify_expr (&TREE_VEC_ELT (it
, 2), pre_p
, NULL
,
8193 is_gimple_val
, fb_rvalue
) == GS_ERROR
8194 || gimplify_expr (&TREE_VEC_ELT (it
, 3), pre_p
, NULL
,
8195 is_gimple_val
, fb_rvalue
) == GS_ERROR
8196 || (gimplify_expr (&TREE_VEC_ELT (it
, 4), pre_p
, NULL
,
8197 is_gimple_val
, fb_rvalue
)
8200 tree var
= TREE_VEC_ELT (it
, 0);
8201 tree begin
= TREE_VEC_ELT (it
, 1);
8202 tree end
= TREE_VEC_ELT (it
, 2);
8203 tree step
= TREE_VEC_ELT (it
, 3);
8204 tree orig_step
= TREE_VEC_ELT (it
, 4);
8205 tree type
= TREE_TYPE (var
);
8206 tree stype
= TREE_TYPE (step
);
8207 location_t loc
= DECL_SOURCE_LOCATION (var
);
8209 /* Compute count for this iterator as
8211 ? (begin < end ? (end - begin + (step - 1)) / step : 0)
8212 : (begin > end ? (end - begin + (step + 1)) / step : 0)
8213 and compute product of those for the entire depend
8215 if (POINTER_TYPE_P (type
))
8216 endmbegin
= fold_build2_loc (loc
, POINTER_DIFF_EXPR
,
8219 endmbegin
= fold_build2_loc (loc
, MINUS_EXPR
, type
,
8221 tree stepm1
= fold_build2_loc (loc
, MINUS_EXPR
, stype
,
8223 build_int_cst (stype
, 1));
8224 tree stepp1
= fold_build2_loc (loc
, PLUS_EXPR
, stype
, step
,
8225 build_int_cst (stype
, 1));
8226 tree pos
= fold_build2_loc (loc
, PLUS_EXPR
, stype
,
8227 unshare_expr (endmbegin
),
8229 pos
= fold_build2_loc (loc
, TRUNC_DIV_EXPR
, stype
,
8231 tree neg
= fold_build2_loc (loc
, PLUS_EXPR
, stype
,
8233 if (TYPE_UNSIGNED (stype
))
8235 neg
= fold_build1_loc (loc
, NEGATE_EXPR
, stype
, neg
);
8236 step
= fold_build1_loc (loc
, NEGATE_EXPR
, stype
, step
);
8238 neg
= fold_build2_loc (loc
, TRUNC_DIV_EXPR
, stype
,
8241 tree cond
= fold_build2_loc (loc
, LT_EXPR
,
8244 pos
= fold_build3_loc (loc
, COND_EXPR
, stype
, cond
, pos
,
8245 build_int_cst (stype
, 0));
8246 cond
= fold_build2_loc (loc
, LT_EXPR
, boolean_type_node
,
8248 neg
= fold_build3_loc (loc
, COND_EXPR
, stype
, cond
, neg
,
8249 build_int_cst (stype
, 0));
8250 tree osteptype
= TREE_TYPE (orig_step
);
8251 cond
= fold_build2_loc (loc
, GT_EXPR
, boolean_type_node
,
8253 build_int_cst (osteptype
, 0));
8254 tree cnt
= fold_build3_loc (loc
, COND_EXPR
, stype
,
8256 cnt
= fold_convert_loc (loc
, sizetype
, cnt
);
8257 if (gimplify_expr (&cnt
, pre_p
, NULL
, is_gimple_val
,
8258 fb_rvalue
) == GS_ERROR
)
8260 tcnt
= size_binop_loc (loc
, MULT_EXPR
, tcnt
, cnt
);
8262 if (gimplify_expr (&tcnt
, pre_p
, NULL
, is_gimple_val
,
8263 fb_rvalue
) == GS_ERROR
)
8265 last_iter
= TREE_PURPOSE (t
);
8268 if (counts
[i
] == NULL_TREE
)
8269 counts
[i
] = last_count
;
8271 counts
[i
] = size_binop_loc (OMP_CLAUSE_LOCATION (c
),
8272 PLUS_EXPR
, counts
[i
], last_count
);
8277 for (i
= 0; i
< 4; i
++)
8283 tree total
= size_zero_node
;
8284 for (i
= 0; i
< 4; i
++)
8286 unused
[i
] = counts
[i
] == NULL_TREE
&& n
[i
] == 0;
8287 if (counts
[i
] == NULL_TREE
)
8288 counts
[i
] = size_zero_node
;
8290 counts
[i
] = size_binop (PLUS_EXPR
, counts
[i
], size_int (n
[i
]));
8291 if (gimplify_expr (&counts
[i
], pre_p
, NULL
, is_gimple_val
,
8292 fb_rvalue
) == GS_ERROR
)
8294 total
= size_binop (PLUS_EXPR
, total
, counts
[i
]);
8297 if (gimplify_expr (&total
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
)
8300 bool is_old
= unused
[1] && unused
[3];
8301 tree totalpx
= size_binop (PLUS_EXPR
, unshare_expr (total
),
8302 size_int (is_old
? 1 : 4));
8303 tree type
= build_array_type (ptr_type_node
, build_index_type (totalpx
));
8304 tree array
= create_tmp_var_raw (type
);
8305 TREE_ADDRESSABLE (array
) = 1;
8306 if (!poly_int_tree_p (totalpx
))
8308 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (array
)))
8309 gimplify_type_sizes (TREE_TYPE (array
), pre_p
);
8310 if (gimplify_omp_ctxp
)
8312 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
8314 && (ctx
->region_type
== ORT_WORKSHARE
8315 || ctx
->region_type
== ORT_TASKGROUP
8316 || ctx
->region_type
== ORT_SIMD
8317 || ctx
->region_type
== ORT_ACC
))
8318 ctx
= ctx
->outer_context
;
8320 omp_add_variable (ctx
, array
, GOVD_LOCAL
| GOVD_SEEN
);
8322 gimplify_vla_decl (array
, pre_p
);
8325 gimple_add_tmp_var (array
);
8326 tree r
= build4 (ARRAY_REF
, ptr_type_node
, array
, size_int (0), NULL_TREE
,
8331 tem
= build2 (MODIFY_EXPR
, void_type_node
, r
,
8332 build_int_cst (ptr_type_node
, 0));
8333 gimplify_and_add (tem
, pre_p
);
8334 r
= build4 (ARRAY_REF
, ptr_type_node
, array
, size_int (1), NULL_TREE
,
8337 tem
= build2 (MODIFY_EXPR
, void_type_node
, r
,
8338 fold_convert (ptr_type_node
, total
));
8339 gimplify_and_add (tem
, pre_p
);
8340 for (i
= 1; i
< (is_old
? 2 : 4); i
++)
8342 r
= build4 (ARRAY_REF
, ptr_type_node
, array
, size_int (i
+ !is_old
),
8343 NULL_TREE
, NULL_TREE
);
8344 tem
= build2 (MODIFY_EXPR
, void_type_node
, r
, counts
[i
- 1]);
8345 gimplify_and_add (tem
, pre_p
);
8352 for (i
= 0; i
< 4; i
++)
8354 if (i
&& (i
>= j
|| unused
[i
- 1]))
8356 cnts
[i
] = cnts
[i
- 1];
8359 cnts
[i
] = create_tmp_var (sizetype
);
8361 g
= gimple_build_assign (cnts
[i
], size_int (is_old
? 2 : 5));
8366 t
= size_binop (PLUS_EXPR
, counts
[0], size_int (2));
8368 t
= size_binop (PLUS_EXPR
, cnts
[i
- 1], counts
[i
- 1]);
8369 if (gimplify_expr (&t
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
)
8372 g
= gimple_build_assign (cnts
[i
], t
);
8374 gimple_seq_add_stmt (pre_p
, g
);
8377 last_iter
= NULL_TREE
;
8378 tree last_bind
= NULL_TREE
;
8379 tree
*last_body
= NULL
;
8380 for (c
= *list_p
; c
; c
= OMP_CLAUSE_CHAIN (c
))
8381 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEPEND
)
8383 switch (OMP_CLAUSE_DEPEND_KIND (c
))
8385 case OMP_CLAUSE_DEPEND_IN
:
8388 case OMP_CLAUSE_DEPEND_OUT
:
8389 case OMP_CLAUSE_DEPEND_INOUT
:
8392 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET
:
8395 case OMP_CLAUSE_DEPEND_DEPOBJ
:
8398 case OMP_CLAUSE_DEPEND_SOURCE
:
8399 case OMP_CLAUSE_DEPEND_SINK
:
8404 tree t
= OMP_CLAUSE_DECL (c
);
8405 if (TREE_CODE (t
) == TREE_LIST
8407 && TREE_CODE (TREE_PURPOSE (t
)) == TREE_VEC
)
8409 if (TREE_PURPOSE (t
) != last_iter
)
8412 gimplify_and_add (last_bind
, pre_p
);
8413 tree block
= TREE_VEC_ELT (TREE_PURPOSE (t
), 5);
8414 last_bind
= build3 (BIND_EXPR
, void_type_node
,
8415 BLOCK_VARS (block
), NULL
, block
);
8416 TREE_SIDE_EFFECTS (last_bind
) = 1;
8417 SET_EXPR_LOCATION (last_bind
, OMP_CLAUSE_LOCATION (c
));
8418 tree
*p
= &BIND_EXPR_BODY (last_bind
);
8419 for (tree it
= TREE_PURPOSE (t
); it
; it
= TREE_CHAIN (it
))
8421 tree var
= TREE_VEC_ELT (it
, 0);
8422 tree begin
= TREE_VEC_ELT (it
, 1);
8423 tree end
= TREE_VEC_ELT (it
, 2);
8424 tree step
= TREE_VEC_ELT (it
, 3);
8425 tree orig_step
= TREE_VEC_ELT (it
, 4);
8426 tree type
= TREE_TYPE (var
);
8427 location_t loc
= DECL_SOURCE_LOCATION (var
);
8435 if (orig_step > 0) {
8436 if (var < end) goto beg_label;
8438 if (var > end) goto beg_label;
8440 for each iterator, with inner iterators added to
8442 tree beg_label
= create_artificial_label (loc
);
8443 tree cond_label
= NULL_TREE
;
8444 tem
= build2_loc (loc
, MODIFY_EXPR
, void_type_node
,
8446 append_to_statement_list_force (tem
, p
);
8447 tem
= build_and_jump (&cond_label
);
8448 append_to_statement_list_force (tem
, p
);
8449 tem
= build1 (LABEL_EXPR
, void_type_node
, beg_label
);
8450 append_to_statement_list (tem
, p
);
8451 tree bind
= build3 (BIND_EXPR
, void_type_node
, NULL_TREE
,
8452 NULL_TREE
, NULL_TREE
);
8453 TREE_SIDE_EFFECTS (bind
) = 1;
8454 SET_EXPR_LOCATION (bind
, loc
);
8455 append_to_statement_list_force (bind
, p
);
8456 if (POINTER_TYPE_P (type
))
8457 tem
= build2_loc (loc
, POINTER_PLUS_EXPR
, type
,
8458 var
, fold_convert_loc (loc
, sizetype
,
8461 tem
= build2_loc (loc
, PLUS_EXPR
, type
, var
, step
);
8462 tem
= build2_loc (loc
, MODIFY_EXPR
, void_type_node
,
8464 append_to_statement_list_force (tem
, p
);
8465 tem
= build1 (LABEL_EXPR
, void_type_node
, cond_label
);
8466 append_to_statement_list (tem
, p
);
8467 tree cond
= fold_build2_loc (loc
, LT_EXPR
,
8471 = fold_build3_loc (loc
, COND_EXPR
, void_type_node
,
8472 cond
, build_and_jump (&beg_label
),
8474 cond
= fold_build2_loc (loc
, GT_EXPR
, boolean_type_node
,
8477 = fold_build3_loc (loc
, COND_EXPR
, void_type_node
,
8478 cond
, build_and_jump (&beg_label
),
8480 tree osteptype
= TREE_TYPE (orig_step
);
8481 cond
= fold_build2_loc (loc
, GT_EXPR
, boolean_type_node
,
8483 build_int_cst (osteptype
, 0));
8484 tem
= fold_build3_loc (loc
, COND_EXPR
, void_type_node
,
8486 append_to_statement_list_force (tem
, p
);
8487 p
= &BIND_EXPR_BODY (bind
);
8491 last_iter
= TREE_PURPOSE (t
);
8492 if (TREE_CODE (TREE_VALUE (t
)) == COMPOUND_EXPR
)
8494 append_to_statement_list (TREE_OPERAND (TREE_VALUE (t
),
8496 TREE_VALUE (t
) = TREE_OPERAND (TREE_VALUE (t
), 1);
8498 if (error_operand_p (TREE_VALUE (t
)))
8500 TREE_VALUE (t
) = build_fold_addr_expr (TREE_VALUE (t
));
8501 r
= build4 (ARRAY_REF
, ptr_type_node
, array
, cnts
[i
],
8502 NULL_TREE
, NULL_TREE
);
8503 tem
= build2_loc (OMP_CLAUSE_LOCATION (c
), MODIFY_EXPR
,
8504 void_type_node
, r
, TREE_VALUE (t
));
8505 append_to_statement_list_force (tem
, last_body
);
8506 tem
= build2_loc (OMP_CLAUSE_LOCATION (c
), MODIFY_EXPR
,
8507 void_type_node
, cnts
[i
],
8508 size_binop (PLUS_EXPR
, cnts
[i
], size_int (1)));
8509 append_to_statement_list_force (tem
, last_body
);
8510 TREE_VALUE (t
) = null_pointer_node
;
8516 gimplify_and_add (last_bind
, pre_p
);
8517 last_bind
= NULL_TREE
;
8519 if (TREE_CODE (OMP_CLAUSE_DECL (c
)) == COMPOUND_EXPR
)
8521 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c
), 0), pre_p
,
8522 NULL
, is_gimple_val
, fb_rvalue
);
8523 OMP_CLAUSE_DECL (c
) = TREE_OPERAND (OMP_CLAUSE_DECL (c
), 1);
8525 if (error_operand_p (OMP_CLAUSE_DECL (c
)))
8527 OMP_CLAUSE_DECL (c
) = build_fold_addr_expr (OMP_CLAUSE_DECL (c
));
8528 if (gimplify_expr (&OMP_CLAUSE_DECL (c
), pre_p
, NULL
,
8529 is_gimple_val
, fb_rvalue
) == GS_ERROR
)
8531 r
= build4 (ARRAY_REF
, ptr_type_node
, array
, cnts
[i
],
8532 NULL_TREE
, NULL_TREE
);
8533 tem
= build2 (MODIFY_EXPR
, void_type_node
, r
, OMP_CLAUSE_DECL (c
));
8534 gimplify_and_add (tem
, pre_p
);
8535 g
= gimple_build_assign (cnts
[i
], size_binop (PLUS_EXPR
, cnts
[i
],
8537 gimple_seq_add_stmt (pre_p
, g
);
8541 gimplify_and_add (last_bind
, pre_p
);
8542 tree cond
= boolean_false_node
;
8546 cond
= build2_loc (first_loc
, NE_EXPR
, boolean_type_node
, cnts
[0],
8547 size_binop_loc (first_loc
, PLUS_EXPR
, counts
[0],
8550 cond
= build2_loc (first_loc
, TRUTH_OR_EXPR
, boolean_type_node
, cond
,
8551 build2_loc (first_loc
, NE_EXPR
, boolean_type_node
,
8553 size_binop_loc (first_loc
, PLUS_EXPR
,
8559 tree prev
= size_int (5);
8560 for (i
= 0; i
< 4; i
++)
8564 prev
= size_binop_loc (first_loc
, PLUS_EXPR
, counts
[i
], prev
);
8565 cond
= build2_loc (first_loc
, TRUTH_OR_EXPR
, boolean_type_node
, cond
,
8566 build2_loc (first_loc
, NE_EXPR
, boolean_type_node
,
8567 cnts
[i
], unshare_expr (prev
)));
8570 tem
= build3_loc (first_loc
, COND_EXPR
, void_type_node
, cond
,
8571 build_call_expr_loc (first_loc
,
8572 builtin_decl_explicit (BUILT_IN_TRAP
),
8574 gimplify_and_add (tem
, pre_p
);
8575 c
= build_omp_clause (UNKNOWN_LOCATION
, OMP_CLAUSE_DEPEND
);
8576 OMP_CLAUSE_DEPEND_KIND (c
) = OMP_CLAUSE_DEPEND_LAST
;
8577 OMP_CLAUSE_DECL (c
) = build_fold_addr_expr (array
);
8578 OMP_CLAUSE_CHAIN (c
) = *list_p
;
8583 /* Insert a GOMP_MAP_ALLOC or GOMP_MAP_RELEASE node following a
8584 GOMP_MAP_STRUCT mapping. C is an always_pointer mapping. STRUCT_NODE is
8585 the struct node to insert the new mapping after (when the struct node is
8586 initially created). PREV_NODE is the first of two or three mappings for a
8587 pointer, and is either:
8588 - the node before C, when a pair of mappings is used, e.g. for a C/C++
8590 - not the node before C. This is true when we have a reference-to-pointer
8591 type (with a mapping for the reference and for the pointer), or for
8592 Fortran derived-type mappings with a GOMP_MAP_TO_PSET.
8593 If SCP is non-null, the new node is inserted before *SCP.
8594 if SCP is null, the new node is inserted before PREV_NODE.
8596 - PREV_NODE, if SCP is non-null.
8597 - The newly-created ALLOC or RELEASE node, if SCP is null.
8598 - The second newly-created ALLOC or RELEASE node, if we are mapping a
8599 reference to a pointer. */
8602 insert_struct_comp_map (enum tree_code code
, tree c
, tree struct_node
,
8603 tree prev_node
, tree
*scp
)
8605 enum gomp_map_kind mkind
8606 = (code
== OMP_TARGET_EXIT_DATA
|| code
== OACC_EXIT_DATA
)
8607 ? GOMP_MAP_RELEASE
: GOMP_MAP_ALLOC
;
8609 tree c2
= build_omp_clause (OMP_CLAUSE_LOCATION (c
), OMP_CLAUSE_MAP
);
8610 tree cl
= scp
? prev_node
: c2
;
8611 OMP_CLAUSE_SET_MAP_KIND (c2
, mkind
);
8612 OMP_CLAUSE_DECL (c2
) = unshare_expr (OMP_CLAUSE_DECL (c
));
8613 OMP_CLAUSE_CHAIN (c2
) = scp
? *scp
: prev_node
;
8614 if (OMP_CLAUSE_CHAIN (prev_node
) != c
8615 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (prev_node
)) == OMP_CLAUSE_MAP
8616 && (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node
))
8617 == GOMP_MAP_TO_PSET
))
8618 OMP_CLAUSE_SIZE (c2
) = OMP_CLAUSE_SIZE (OMP_CLAUSE_CHAIN (prev_node
));
8620 OMP_CLAUSE_SIZE (c2
) = TYPE_SIZE_UNIT (ptr_type_node
);
8622 OMP_CLAUSE_CHAIN (struct_node
) = c2
;
8624 /* We might need to create an additional mapping if we have a reference to a
8625 pointer (in C++). Don't do this if we have something other than a
8626 GOMP_MAP_ALWAYS_POINTER though, i.e. a GOMP_MAP_TO_PSET. */
8627 if (OMP_CLAUSE_CHAIN (prev_node
) != c
8628 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (prev_node
)) == OMP_CLAUSE_MAP
8629 && ((OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node
))
8630 == GOMP_MAP_ALWAYS_POINTER
)
8631 || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node
))
8632 == GOMP_MAP_ATTACH_DETACH
)))
8634 tree c4
= OMP_CLAUSE_CHAIN (prev_node
);
8635 tree c3
= build_omp_clause (OMP_CLAUSE_LOCATION (c
), OMP_CLAUSE_MAP
);
8636 OMP_CLAUSE_SET_MAP_KIND (c3
, mkind
);
8637 OMP_CLAUSE_DECL (c3
) = unshare_expr (OMP_CLAUSE_DECL (c4
));
8638 OMP_CLAUSE_SIZE (c3
) = TYPE_SIZE_UNIT (ptr_type_node
);
8639 OMP_CLAUSE_CHAIN (c3
) = prev_node
;
8641 OMP_CLAUSE_CHAIN (c2
) = c3
;
8652 /* Strip ARRAY_REFS or an indirect ref off BASE, find the containing object,
8653 and set *BITPOSP and *POFFSETP to the bit offset of the access.
8654 If BASE_REF is non-NULL and the containing object is a reference, set
8655 *BASE_REF to that reference before dereferencing the object.
8656 If BASE_REF is NULL, check that the containing object is a COMPONENT_REF or
8657 has array type, else return NULL. */
8660 extract_base_bit_offset (tree base
, tree
*base_ref
, poly_int64
*bitposp
,
8661 poly_offset_int
*poffsetp
)
8664 poly_int64 bitsize
, bitpos
;
8666 int unsignedp
, reversep
, volatilep
= 0;
8667 poly_offset_int poffset
;
8671 *base_ref
= NULL_TREE
;
8673 while (TREE_CODE (base
) == ARRAY_REF
)
8674 base
= TREE_OPERAND (base
, 0);
8676 if (TREE_CODE (base
) == INDIRECT_REF
)
8677 base
= TREE_OPERAND (base
, 0);
8681 if (TREE_CODE (base
) == ARRAY_REF
)
8683 while (TREE_CODE (base
) == ARRAY_REF
)
8684 base
= TREE_OPERAND (base
, 0);
8685 if (TREE_CODE (base
) != COMPONENT_REF
8686 || TREE_CODE (TREE_TYPE (base
)) != ARRAY_TYPE
)
8689 else if (TREE_CODE (base
) == INDIRECT_REF
8690 && TREE_CODE (TREE_OPERAND (base
, 0)) == COMPONENT_REF
8691 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (base
, 0)))
8693 base
= TREE_OPERAND (base
, 0);
8696 base
= get_inner_reference (base
, &bitsize
, &bitpos
, &offset
, &mode
,
8697 &unsignedp
, &reversep
, &volatilep
);
8699 tree orig_base
= base
;
8701 if ((TREE_CODE (base
) == INDIRECT_REF
8702 || (TREE_CODE (base
) == MEM_REF
8703 && integer_zerop (TREE_OPERAND (base
, 1))))
8704 && DECL_P (TREE_OPERAND (base
, 0))
8705 && TREE_CODE (TREE_TYPE (TREE_OPERAND (base
, 0))) == REFERENCE_TYPE
)
8706 base
= TREE_OPERAND (base
, 0);
8708 gcc_assert (offset
== NULL_TREE
|| poly_int_tree_p (offset
));
8711 poffset
= wi::to_poly_offset (offset
);
8715 if (maybe_ne (bitpos
, 0))
8716 poffset
+= bits_to_bytes_round_down (bitpos
);
8719 *poffsetp
= poffset
;
8721 /* Set *BASE_REF if BASE was a dereferenced reference variable. */
8722 if (base_ref
&& orig_base
!= base
)
8723 *base_ref
= orig_base
;
8728 /* Returns true if EXPR is or contains (as a sub-component) BASE_PTR. */
8731 is_or_contains_p (tree expr
, tree base_ptr
)
8733 while (expr
!= base_ptr
)
8734 if (TREE_CODE (base_ptr
) == COMPONENT_REF
)
8735 base_ptr
= TREE_OPERAND (base_ptr
, 0);
8738 return expr
== base_ptr
;
8741 /* Implement OpenMP 5.x map ordering rules for target directives. There are
8742 several rules, and with some level of ambiguity, hopefully we can at least
8743 collect the complexity here in one place. */
8746 omp_target_reorder_clauses (tree
*list_p
)
8748 /* Collect refs to alloc/release/delete maps. */
8749 auto_vec
<tree
, 32> ard
;
8751 while (*cp
!= NULL_TREE
)
8752 if (OMP_CLAUSE_CODE (*cp
) == OMP_CLAUSE_MAP
8753 && (OMP_CLAUSE_MAP_KIND (*cp
) == GOMP_MAP_ALLOC
8754 || OMP_CLAUSE_MAP_KIND (*cp
) == GOMP_MAP_RELEASE
8755 || OMP_CLAUSE_MAP_KIND (*cp
) == GOMP_MAP_DELETE
))
8757 /* Unlink cp and push to ard. */
8759 tree nc
= OMP_CLAUSE_CHAIN (c
);
8763 /* Any associated pointer type maps should also move along. */
8764 while (*cp
!= NULL_TREE
8765 && OMP_CLAUSE_CODE (*cp
) == OMP_CLAUSE_MAP
8766 && (OMP_CLAUSE_MAP_KIND (*cp
) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
8767 || OMP_CLAUSE_MAP_KIND (*cp
) == GOMP_MAP_FIRSTPRIVATE_POINTER
8768 || OMP_CLAUSE_MAP_KIND (*cp
) == GOMP_MAP_ATTACH_DETACH
8769 || OMP_CLAUSE_MAP_KIND (*cp
) == GOMP_MAP_POINTER
8770 || OMP_CLAUSE_MAP_KIND (*cp
) == GOMP_MAP_ALWAYS_POINTER
8771 || OMP_CLAUSE_MAP_KIND (*cp
) == GOMP_MAP_TO_PSET
))
8774 nc
= OMP_CLAUSE_CHAIN (c
);
8780 cp
= &OMP_CLAUSE_CHAIN (*cp
);
8782 /* Link alloc/release/delete maps to the end of list. */
8783 for (unsigned int i
= 0; i
< ard
.length (); i
++)
8786 cp
= &OMP_CLAUSE_CHAIN (ard
[i
]);
8790 /* OpenMP 5.0 requires that pointer variables are mapped before
8791 its use as a base-pointer. */
8792 auto_vec
<tree
*, 32> atf
;
8793 for (tree
*cp
= list_p
; *cp
; cp
= &OMP_CLAUSE_CHAIN (*cp
))
8794 if (OMP_CLAUSE_CODE (*cp
) == OMP_CLAUSE_MAP
)
8796 /* Collect alloc, to, from, to/from clause tree pointers. */
8797 gomp_map_kind k
= OMP_CLAUSE_MAP_KIND (*cp
);
8798 if (k
== GOMP_MAP_ALLOC
8800 || k
== GOMP_MAP_FROM
8801 || k
== GOMP_MAP_TOFROM
8802 || k
== GOMP_MAP_ALWAYS_TO
8803 || k
== GOMP_MAP_ALWAYS_FROM
8804 || k
== GOMP_MAP_ALWAYS_TOFROM
)
8808 for (unsigned int i
= 0; i
< atf
.length (); i
++)
8812 tree decl
= OMP_CLAUSE_DECL (*cp
);
8813 if (TREE_CODE (decl
) == INDIRECT_REF
|| TREE_CODE (decl
) == MEM_REF
)
8815 tree base_ptr
= TREE_OPERAND (decl
, 0);
8816 STRIP_TYPE_NOPS (base_ptr
);
8817 for (unsigned int j
= i
+ 1; j
< atf
.length (); j
++)
8820 tree decl2
= OMP_CLAUSE_DECL (*cp2
);
8821 if (is_or_contains_p (decl2
, base_ptr
))
8823 /* Move *cp2 to before *cp. */
8825 *cp2
= OMP_CLAUSE_CHAIN (c
);
8826 OMP_CLAUSE_CHAIN (c
) = *cp
;
8835 /* DECL is supposed to have lastprivate semantics in the outer contexts
8836 of combined/composite constructs, starting with OCTX.
8837 Add needed lastprivate, shared or map clause if no data sharing or
8838 mapping clause are present. IMPLICIT_P is true if it is an implicit
8839 clause (IV on simd), in which case the lastprivate will not be
8840 copied to some constructs. */
8843 omp_lastprivate_for_combined_outer_constructs (struct gimplify_omp_ctx
*octx
,
8844 tree decl
, bool implicit_p
)
8846 struct gimplify_omp_ctx
*orig_octx
= octx
;
8847 for (; octx
; octx
= octx
->outer_context
)
8849 if ((octx
->region_type
== ORT_COMBINED_PARALLEL
8850 || (octx
->region_type
& ORT_COMBINED_TEAMS
) == ORT_COMBINED_TEAMS
)
8851 && splay_tree_lookup (octx
->variables
,
8852 (splay_tree_key
) decl
) == NULL
)
8854 omp_add_variable (octx
, decl
, GOVD_SHARED
| GOVD_SEEN
);
8857 if ((octx
->region_type
& ORT_TASK
) != 0
8858 && octx
->combined_loop
8859 && splay_tree_lookup (octx
->variables
,
8860 (splay_tree_key
) decl
) == NULL
)
8862 omp_add_variable (octx
, decl
, GOVD_LASTPRIVATE
| GOVD_SEEN
);
8866 && octx
->region_type
== ORT_WORKSHARE
8867 && octx
->combined_loop
8868 && splay_tree_lookup (octx
->variables
,
8869 (splay_tree_key
) decl
) == NULL
8870 && octx
->outer_context
8871 && octx
->outer_context
->region_type
== ORT_COMBINED_PARALLEL
8872 && splay_tree_lookup (octx
->outer_context
->variables
,
8873 (splay_tree_key
) decl
) == NULL
)
8875 octx
= octx
->outer_context
;
8876 omp_add_variable (octx
, decl
, GOVD_LASTPRIVATE
| GOVD_SEEN
);
8879 if ((octx
->region_type
== ORT_WORKSHARE
|| octx
->region_type
== ORT_ACC
)
8880 && octx
->combined_loop
8881 && splay_tree_lookup (octx
->variables
,
8882 (splay_tree_key
) decl
) == NULL
8883 && !omp_check_private (octx
, decl
, false))
8885 omp_add_variable (octx
, decl
, GOVD_LASTPRIVATE
| GOVD_SEEN
);
8888 if (octx
->region_type
== ORT_COMBINED_TARGET
)
8890 splay_tree_node n
= splay_tree_lookup (octx
->variables
,
8891 (splay_tree_key
) decl
);
8894 omp_add_variable (octx
, decl
, GOVD_MAP
| GOVD_SEEN
);
8895 octx
= octx
->outer_context
;
8897 else if (!implicit_p
8898 && (n
->value
& GOVD_FIRSTPRIVATE_IMPLICIT
))
8900 n
->value
&= ~(GOVD_FIRSTPRIVATE
8901 | GOVD_FIRSTPRIVATE_IMPLICIT
8903 omp_add_variable (octx
, decl
, GOVD_MAP
| GOVD_SEEN
);
8904 octx
= octx
->outer_context
;
8909 if (octx
&& (implicit_p
|| octx
!= orig_octx
))
8910 omp_notice_variable (octx
, decl
, true);
8913 /* Scan the OMP clauses in *LIST_P, installing mappings into a new
8914 and previous omp contexts. */
8917 gimplify_scan_omp_clauses (tree
*list_p
, gimple_seq
*pre_p
,
8918 enum omp_region_type region_type
,
8919 enum tree_code code
)
8921 struct gimplify_omp_ctx
*ctx
, *outer_ctx
;
8923 hash_map
<tree
, tree
> *struct_map_to_clause
= NULL
;
8924 hash_set
<tree
> *struct_deref_set
= NULL
;
8925 tree
*prev_list_p
= NULL
, *orig_list_p
= list_p
;
8926 int handled_depend_iterators
= -1;
8929 ctx
= new_omp_context (region_type
);
8931 outer_ctx
= ctx
->outer_context
;
8932 if (code
== OMP_TARGET
)
8934 if (!lang_GNU_Fortran ())
8935 ctx
->defaultmap
[GDMK_POINTER
] = GOVD_MAP
| GOVD_MAP_0LEN_ARRAY
;
8936 ctx
->defaultmap
[GDMK_SCALAR
] = GOVD_FIRSTPRIVATE
;
8937 ctx
->defaultmap
[GDMK_SCALAR_TARGET
] = (lang_GNU_Fortran ()
8938 ? GOVD_MAP
: GOVD_FIRSTPRIVATE
);
8940 if (!lang_GNU_Fortran ())
8944 case OMP_TARGET_DATA
:
8945 case OMP_TARGET_ENTER_DATA
:
8946 case OMP_TARGET_EXIT_DATA
:
8948 case OACC_HOST_DATA
:
8951 ctx
->target_firstprivatize_array_bases
= true;
8956 if (code
== OMP_TARGET
8957 || code
== OMP_TARGET_DATA
8958 || code
== OMP_TARGET_ENTER_DATA
8959 || code
== OMP_TARGET_EXIT_DATA
)
8960 omp_target_reorder_clauses (list_p
);
8962 while ((c
= *list_p
) != NULL
)
8964 bool remove
= false;
8965 bool notice_outer
= true;
8966 const char *check_non_private
= NULL
;
8970 switch (OMP_CLAUSE_CODE (c
))
8972 case OMP_CLAUSE_PRIVATE
:
8973 flags
= GOVD_PRIVATE
| GOVD_EXPLICIT
;
8974 if (lang_hooks
.decls
.omp_private_outer_ref (OMP_CLAUSE_DECL (c
)))
8976 flags
|= GOVD_PRIVATE_OUTER_REF
;
8977 OMP_CLAUSE_PRIVATE_OUTER_REF (c
) = 1;
8980 notice_outer
= false;
8982 case OMP_CLAUSE_SHARED
:
8983 flags
= GOVD_SHARED
| GOVD_EXPLICIT
;
8985 case OMP_CLAUSE_FIRSTPRIVATE
:
8986 flags
= GOVD_FIRSTPRIVATE
| GOVD_EXPLICIT
;
8987 check_non_private
= "firstprivate";
8988 if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c
))
8990 gcc_assert (code
== OMP_TARGET
);
8991 flags
|= GOVD_FIRSTPRIVATE_IMPLICIT
;
8994 case OMP_CLAUSE_LASTPRIVATE
:
8995 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
))
8998 case OMP_DISTRIBUTE
:
8999 error_at (OMP_CLAUSE_LOCATION (c
),
9000 "conditional %<lastprivate%> clause on "
9001 "%qs construct", "distribute");
9002 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
) = 0;
9005 error_at (OMP_CLAUSE_LOCATION (c
),
9006 "conditional %<lastprivate%> clause on "
9007 "%qs construct", "taskloop");
9008 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
) = 0;
9013 flags
= GOVD_LASTPRIVATE
| GOVD_SEEN
| GOVD_EXPLICIT
;
9014 if (code
!= OMP_LOOP
)
9015 check_non_private
= "lastprivate";
9016 decl
= OMP_CLAUSE_DECL (c
);
9017 if (error_operand_p (decl
))
9019 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
)
9020 && !lang_hooks
.decls
.omp_scalar_p (decl
, true))
9022 error_at (OMP_CLAUSE_LOCATION (c
),
9023 "non-scalar variable %qD in conditional "
9024 "%<lastprivate%> clause", decl
);
9025 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
) = 0;
9027 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
))
9028 flags
|= GOVD_LASTPRIVATE_CONDITIONAL
;
9029 omp_lastprivate_for_combined_outer_constructs (outer_ctx
, decl
,
9032 case OMP_CLAUSE_REDUCTION
:
9033 if (OMP_CLAUSE_REDUCTION_TASK (c
))
9035 if (region_type
== ORT_WORKSHARE
|| code
== OMP_SCOPE
)
9038 nowait
= omp_find_clause (*list_p
,
9039 OMP_CLAUSE_NOWAIT
) != NULL_TREE
;
9041 && (outer_ctx
== NULL
9042 || outer_ctx
->region_type
!= ORT_COMBINED_PARALLEL
))
9044 error_at (OMP_CLAUSE_LOCATION (c
),
9045 "%<task%> reduction modifier on a construct "
9046 "with a %<nowait%> clause");
9047 OMP_CLAUSE_REDUCTION_TASK (c
) = 0;
9050 else if ((region_type
& ORT_PARALLEL
) != ORT_PARALLEL
)
9052 error_at (OMP_CLAUSE_LOCATION (c
),
9053 "invalid %<task%> reduction modifier on construct "
9054 "other than %<parallel%>, %qs, %<sections%> or "
9055 "%<scope%>", lang_GNU_Fortran () ? "do" : "for");
9056 OMP_CLAUSE_REDUCTION_TASK (c
) = 0;
9059 if (OMP_CLAUSE_REDUCTION_INSCAN (c
))
9063 error_at (OMP_CLAUSE_LOCATION (c
),
9064 "%<inscan%> %<reduction%> clause on "
9065 "%qs construct", "sections");
9066 OMP_CLAUSE_REDUCTION_INSCAN (c
) = 0;
9069 error_at (OMP_CLAUSE_LOCATION (c
),
9070 "%<inscan%> %<reduction%> clause on "
9071 "%qs construct", "parallel");
9072 OMP_CLAUSE_REDUCTION_INSCAN (c
) = 0;
9075 error_at (OMP_CLAUSE_LOCATION (c
),
9076 "%<inscan%> %<reduction%> clause on "
9077 "%qs construct", "teams");
9078 OMP_CLAUSE_REDUCTION_INSCAN (c
) = 0;
9081 error_at (OMP_CLAUSE_LOCATION (c
),
9082 "%<inscan%> %<reduction%> clause on "
9083 "%qs construct", "taskloop");
9084 OMP_CLAUSE_REDUCTION_INSCAN (c
) = 0;
9087 error_at (OMP_CLAUSE_LOCATION (c
),
9088 "%<inscan%> %<reduction%> clause on "
9089 "%qs construct", "scope");
9090 OMP_CLAUSE_REDUCTION_INSCAN (c
) = 0;
9096 case OMP_CLAUSE_IN_REDUCTION
:
9097 case OMP_CLAUSE_TASK_REDUCTION
:
9098 flags
= GOVD_REDUCTION
| GOVD_SEEN
| GOVD_EXPLICIT
;
9099 /* OpenACC permits reductions on private variables. */
9100 if (!(region_type
& ORT_ACC
)
9101 /* taskgroup is actually not a worksharing region. */
9102 && code
!= OMP_TASKGROUP
)
9103 check_non_private
= omp_clause_code_name
[OMP_CLAUSE_CODE (c
)];
9104 decl
= OMP_CLAUSE_DECL (c
);
9105 if (TREE_CODE (decl
) == MEM_REF
)
9107 tree type
= TREE_TYPE (decl
);
9108 bool saved_into_ssa
= gimplify_ctxp
->into_ssa
;
9109 gimplify_ctxp
->into_ssa
= false;
9110 if (gimplify_expr (&TYPE_MAX_VALUE (TYPE_DOMAIN (type
)), pre_p
,
9111 NULL
, is_gimple_val
, fb_rvalue
, false)
9114 gimplify_ctxp
->into_ssa
= saved_into_ssa
;
9118 gimplify_ctxp
->into_ssa
= saved_into_ssa
;
9119 tree v
= TYPE_MAX_VALUE (TYPE_DOMAIN (type
));
9122 omp_firstprivatize_variable (ctx
, v
);
9123 omp_notice_variable (ctx
, v
, true);
9125 decl
= TREE_OPERAND (decl
, 0);
9126 if (TREE_CODE (decl
) == POINTER_PLUS_EXPR
)
9128 gimplify_ctxp
->into_ssa
= false;
9129 if (gimplify_expr (&TREE_OPERAND (decl
, 1), pre_p
,
9130 NULL
, is_gimple_val
, fb_rvalue
, false)
9133 gimplify_ctxp
->into_ssa
= saved_into_ssa
;
9137 gimplify_ctxp
->into_ssa
= saved_into_ssa
;
9138 v
= TREE_OPERAND (decl
, 1);
9141 omp_firstprivatize_variable (ctx
, v
);
9142 omp_notice_variable (ctx
, v
, true);
9144 decl
= TREE_OPERAND (decl
, 0);
9146 if (TREE_CODE (decl
) == ADDR_EXPR
9147 || TREE_CODE (decl
) == INDIRECT_REF
)
9148 decl
= TREE_OPERAND (decl
, 0);
9151 case OMP_CLAUSE_LINEAR
:
9152 if (gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c
), pre_p
, NULL
,
9153 is_gimple_val
, fb_rvalue
) == GS_ERROR
)
9160 if (code
== OMP_SIMD
9161 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c
))
9163 struct gimplify_omp_ctx
*octx
= outer_ctx
;
9165 && octx
->region_type
== ORT_WORKSHARE
9166 && octx
->combined_loop
9167 && !octx
->distribute
)
9169 if (octx
->outer_context
9170 && (octx
->outer_context
->region_type
9171 == ORT_COMBINED_PARALLEL
))
9172 octx
= octx
->outer_context
->outer_context
;
9174 octx
= octx
->outer_context
;
9177 && octx
->region_type
== ORT_WORKSHARE
9178 && octx
->combined_loop
9179 && octx
->distribute
)
9181 error_at (OMP_CLAUSE_LOCATION (c
),
9182 "%<linear%> clause for variable other than "
9183 "loop iterator specified on construct "
9184 "combined with %<distribute%>");
9189 /* For combined #pragma omp parallel for simd, need to put
9190 lastprivate and perhaps firstprivate too on the
9191 parallel. Similarly for #pragma omp for simd. */
9192 struct gimplify_omp_ctx
*octx
= outer_ctx
;
9193 bool taskloop_seen
= false;
9197 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c
)
9198 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c
))
9200 decl
= OMP_CLAUSE_DECL (c
);
9201 if (error_operand_p (decl
))
9207 if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c
))
9208 flags
|= GOVD_FIRSTPRIVATE
;
9209 if (!OMP_CLAUSE_LINEAR_NO_COPYOUT (c
))
9210 flags
|= GOVD_LASTPRIVATE
;
9212 && octx
->region_type
== ORT_WORKSHARE
9213 && octx
->combined_loop
)
9215 if (octx
->outer_context
9216 && (octx
->outer_context
->region_type
9217 == ORT_COMBINED_PARALLEL
))
9218 octx
= octx
->outer_context
;
9219 else if (omp_check_private (octx
, decl
, false))
9223 && (octx
->region_type
& ORT_TASK
) != 0
9224 && octx
->combined_loop
)
9225 taskloop_seen
= true;
9227 && octx
->region_type
== ORT_COMBINED_PARALLEL
9228 && ((ctx
->region_type
== ORT_WORKSHARE
9229 && octx
== outer_ctx
)
9231 flags
= GOVD_SEEN
| GOVD_SHARED
;
9233 && ((octx
->region_type
& ORT_COMBINED_TEAMS
)
9234 == ORT_COMBINED_TEAMS
))
9235 flags
= GOVD_SEEN
| GOVD_SHARED
;
9237 && octx
->region_type
== ORT_COMBINED_TARGET
)
9239 if (flags
& GOVD_LASTPRIVATE
)
9240 flags
= GOVD_SEEN
| GOVD_MAP
;
9245 = splay_tree_lookup (octx
->variables
,
9246 (splay_tree_key
) decl
);
9247 if (on
&& (on
->value
& GOVD_DATA_SHARE_CLASS
) != 0)
9252 omp_add_variable (octx
, decl
, flags
);
9253 if (octx
->outer_context
== NULL
)
9255 octx
= octx
->outer_context
;
9260 && (!OMP_CLAUSE_LINEAR_NO_COPYIN (c
)
9261 || !OMP_CLAUSE_LINEAR_NO_COPYOUT (c
)))
9262 omp_notice_variable (octx
, decl
, true);
9264 flags
= GOVD_LINEAR
| GOVD_EXPLICIT
;
9265 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c
)
9266 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c
))
9268 notice_outer
= false;
9269 flags
|= GOVD_LINEAR_LASTPRIVATE_NO_OUTER
;
9273 case OMP_CLAUSE_MAP
:
9274 decl
= OMP_CLAUSE_DECL (c
);
9275 if (error_operand_p (decl
))
9282 if (TREE_CODE (TREE_TYPE (decl
)) != ARRAY_TYPE
)
9285 case OMP_TARGET_DATA
:
9286 case OMP_TARGET_ENTER_DATA
:
9287 case OMP_TARGET_EXIT_DATA
:
9288 case OACC_ENTER_DATA
:
9289 case OACC_EXIT_DATA
:
9290 case OACC_HOST_DATA
:
9291 if (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_FIRSTPRIVATE_POINTER
9292 || (OMP_CLAUSE_MAP_KIND (c
)
9293 == GOMP_MAP_FIRSTPRIVATE_REFERENCE
))
9294 /* For target {,enter ,exit }data only the array slice is
9295 mapped, but not the pointer to it. */
9301 /* For Fortran, not only the pointer to the data is mapped but also
9302 the address of the pointer, the array descriptor etc.; for
9303 'exit data' - and in particular for 'delete:' - having an 'alloc:'
9304 does not make sense. Likewise, for 'update' only transferring the
9305 data itself is needed as the rest has been handled in previous
9306 directives. However, for 'exit data', the array descriptor needs
9307 to be delete; hence, we turn the MAP_TO_PSET into a MAP_DELETE.
9309 NOTE: Generally, it is not safe to perform "enter data" operations
9310 on arrays where the data *or the descriptor* may go out of scope
9311 before a corresponding "exit data" operation -- and such a
9312 descriptor may be synthesized temporarily, e.g. to pass an
9313 explicit-shape array to a function expecting an assumed-shape
9314 argument. Performing "enter data" inside the called function
9315 would thus be problematic. */
9316 if (code
== OMP_TARGET_EXIT_DATA
9317 && OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_TO_PSET
)
9318 OMP_CLAUSE_SET_MAP_KIND (c
, OMP_CLAUSE_MAP_KIND (*prev_list_p
)
9320 ? GOMP_MAP_DELETE
: GOMP_MAP_RELEASE
);
9321 else if ((code
== OMP_TARGET_EXIT_DATA
|| code
== OMP_TARGET_UPDATE
)
9322 && (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_POINTER
9323 || OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_TO_PSET
))
9328 if (DECL_P (decl
) && outer_ctx
&& (region_type
& ORT_ACC
))
9330 struct gimplify_omp_ctx
*octx
;
9331 for (octx
= outer_ctx
; octx
; octx
= octx
->outer_context
)
9333 if (octx
->region_type
!= ORT_ACC_HOST_DATA
)
9336 = splay_tree_lookup (octx
->variables
,
9337 (splay_tree_key
) decl
);
9339 error_at (OMP_CLAUSE_LOCATION (c
), "variable %qE "
9340 "declared in enclosing %<host_data%> region",
9344 if (OMP_CLAUSE_SIZE (c
) == NULL_TREE
)
9345 OMP_CLAUSE_SIZE (c
) = DECL_P (decl
) ? DECL_SIZE_UNIT (decl
)
9346 : TYPE_SIZE_UNIT (TREE_TYPE (decl
));
9347 if (gimplify_expr (&OMP_CLAUSE_SIZE (c
), pre_p
,
9348 NULL
, is_gimple_val
, fb_rvalue
) == GS_ERROR
)
9353 else if ((OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_FIRSTPRIVATE_POINTER
9354 || (OMP_CLAUSE_MAP_KIND (c
)
9355 == GOMP_MAP_FIRSTPRIVATE_REFERENCE
)
9356 || OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ATTACH_DETACH
)
9357 && TREE_CODE (OMP_CLAUSE_SIZE (c
)) != INTEGER_CST
)
9360 = get_initialized_tmp_var (OMP_CLAUSE_SIZE (c
), pre_p
, NULL
,
9362 if ((region_type
& ORT_TARGET
) != 0)
9363 omp_add_variable (ctx
, OMP_CLAUSE_SIZE (c
),
9364 GOVD_FIRSTPRIVATE
| GOVD_SEEN
);
9370 if (TREE_CODE (d
) == ARRAY_REF
)
9372 while (TREE_CODE (d
) == ARRAY_REF
)
9373 d
= TREE_OPERAND (d
, 0);
9374 if (TREE_CODE (d
) == COMPONENT_REF
9375 && TREE_CODE (TREE_TYPE (d
)) == ARRAY_TYPE
)
9378 pd
= &OMP_CLAUSE_DECL (c
);
9380 && TREE_CODE (decl
) == INDIRECT_REF
9381 && TREE_CODE (TREE_OPERAND (decl
, 0)) == COMPONENT_REF
9382 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl
, 0)))
9385 pd
= &TREE_OPERAND (decl
, 0);
9386 decl
= TREE_OPERAND (decl
, 0);
9388 bool indir_p
= false;
9389 tree orig_decl
= decl
;
9390 tree decl_ref
= NULL_TREE
;
9391 if ((region_type
& (ORT_ACC
| ORT_TARGET
| ORT_TARGET_DATA
)) != 0
9392 && TREE_CODE (*pd
) == COMPONENT_REF
9393 && OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ATTACH_DETACH
9394 && code
!= OACC_UPDATE
)
9396 while (TREE_CODE (decl
) == COMPONENT_REF
)
9398 decl
= TREE_OPERAND (decl
, 0);
9399 if (((TREE_CODE (decl
) == MEM_REF
9400 && integer_zerop (TREE_OPERAND (decl
, 1)))
9401 || INDIRECT_REF_P (decl
))
9402 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl
, 0)))
9406 decl
= TREE_OPERAND (decl
, 0);
9408 if (TREE_CODE (decl
) == INDIRECT_REF
9409 && DECL_P (TREE_OPERAND (decl
, 0))
9410 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl
, 0)))
9414 decl
= TREE_OPERAND (decl
, 0);
9418 else if (TREE_CODE (decl
) == COMPONENT_REF
)
9420 while (TREE_CODE (decl
) == COMPONENT_REF
)
9421 decl
= TREE_OPERAND (decl
, 0);
9422 if (TREE_CODE (decl
) == INDIRECT_REF
9423 && DECL_P (TREE_OPERAND (decl
, 0))
9424 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl
, 0)))
9426 decl
= TREE_OPERAND (decl
, 0);
9428 if (decl
!= orig_decl
&& DECL_P (decl
) && indir_p
)
9431 = ((code
== OACC_EXIT_DATA
|| code
== OMP_TARGET_EXIT_DATA
)
9432 ? GOMP_MAP_DETACH
: GOMP_MAP_ATTACH
);
9433 /* We have a dereference of a struct member. Make this an
9434 attach/detach operation, and ensure the base pointer is
9435 mapped as a FIRSTPRIVATE_POINTER. */
9436 OMP_CLAUSE_SET_MAP_KIND (c
, k
);
9437 flags
= GOVD_MAP
| GOVD_SEEN
| GOVD_EXPLICIT
;
9438 tree next_clause
= OMP_CLAUSE_CHAIN (c
);
9439 if (k
== GOMP_MAP_ATTACH
9440 && code
!= OACC_ENTER_DATA
9441 && code
!= OMP_TARGET_ENTER_DATA
9443 || (OMP_CLAUSE_CODE (next_clause
) != OMP_CLAUSE_MAP
)
9444 || (OMP_CLAUSE_MAP_KIND (next_clause
)
9445 != GOMP_MAP_POINTER
)
9446 || OMP_CLAUSE_DECL (next_clause
) != decl
)
9447 && (!struct_deref_set
9448 || !struct_deref_set
->contains (decl
)))
9450 if (!struct_deref_set
)
9451 struct_deref_set
= new hash_set
<tree
> ();
9452 /* As well as the attach, we also need a
9453 FIRSTPRIVATE_POINTER clause to properly map the
9454 pointer to the struct base. */
9455 tree c2
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
9457 OMP_CLAUSE_SET_MAP_KIND (c2
, GOMP_MAP_ALLOC
);
9458 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (c2
)
9461 = build_int_cst (build_pointer_type (char_type_node
),
9463 OMP_CLAUSE_DECL (c2
)
9464 = build2 (MEM_REF
, char_type_node
,
9465 decl_ref
? decl_ref
: decl
, charptr_zero
);
9466 OMP_CLAUSE_SIZE (c2
) = size_zero_node
;
9467 tree c3
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
9469 OMP_CLAUSE_SET_MAP_KIND (c3
,
9470 GOMP_MAP_FIRSTPRIVATE_POINTER
);
9471 OMP_CLAUSE_DECL (c3
) = decl
;
9472 OMP_CLAUSE_SIZE (c3
) = size_zero_node
;
9473 tree mapgrp
= *prev_list_p
;
9475 OMP_CLAUSE_CHAIN (c3
) = mapgrp
;
9476 OMP_CLAUSE_CHAIN (c2
) = c3
;
9478 struct_deref_set
->add (decl
);
9482 /* An "attach/detach" operation on an update directive should
9483 behave as a GOMP_MAP_ALWAYS_POINTER. Beware that
9484 unlike attach or detach map kinds, GOMP_MAP_ALWAYS_POINTER
9485 depends on the previous mapping. */
9486 if (code
== OACC_UPDATE
9487 && OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ATTACH_DETACH
)
9488 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_ALWAYS_POINTER
);
9490 && OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_TO_PSET
9491 && OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_ATTACH
9492 && OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_DETACH
9493 && code
!= OACC_UPDATE
9494 && code
!= OMP_TARGET_UPDATE
)
9496 if (error_operand_p (decl
))
9502 tree stype
= TREE_TYPE (decl
);
9503 if (TREE_CODE (stype
) == REFERENCE_TYPE
)
9504 stype
= TREE_TYPE (stype
);
9505 if (TYPE_SIZE_UNIT (stype
) == NULL
9506 || TREE_CODE (TYPE_SIZE_UNIT (stype
)) != INTEGER_CST
)
9508 error_at (OMP_CLAUSE_LOCATION (c
),
9509 "mapping field %qE of variable length "
9510 "structure", OMP_CLAUSE_DECL (c
));
9515 if (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ALWAYS_POINTER
9516 || OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ATTACH_DETACH
)
9518 /* Error recovery. */
9519 if (prev_list_p
== NULL
)
9524 if (OMP_CLAUSE_CHAIN (*prev_list_p
) != c
)
9526 tree ch
= OMP_CLAUSE_CHAIN (*prev_list_p
);
9527 if (ch
== NULL_TREE
|| OMP_CLAUSE_CHAIN (ch
) != c
)
9535 poly_offset_int offset1
;
9540 = extract_base_bit_offset (OMP_CLAUSE_DECL (c
), &base_ref
,
9541 &bitpos1
, &offset1
);
9543 gcc_assert (base
== decl
);
9546 = splay_tree_lookup (ctx
->variables
, (splay_tree_key
)decl
);
9547 bool ptr
= (OMP_CLAUSE_MAP_KIND (c
)
9548 == GOMP_MAP_ALWAYS_POINTER
);
9549 bool attach_detach
= (OMP_CLAUSE_MAP_KIND (c
)
9550 == GOMP_MAP_ATTACH_DETACH
);
9551 bool attach
= OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ATTACH
9552 || OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_DETACH
;
9553 bool has_attachments
= false;
9554 /* For OpenACC, pointers in structs should trigger an
9557 && ((region_type
& (ORT_ACC
| ORT_TARGET
| ORT_TARGET_DATA
))
9558 || code
== OMP_TARGET_ENTER_DATA
9559 || code
== OMP_TARGET_EXIT_DATA
))
9562 /* Turn a GOMP_MAP_ATTACH_DETACH clause into a
9563 GOMP_MAP_ATTACH or GOMP_MAP_DETACH clause after we
9564 have detected a case that needs a GOMP_MAP_STRUCT
9567 = ((code
== OACC_EXIT_DATA
|| code
== OMP_TARGET_EXIT_DATA
)
9568 ? GOMP_MAP_DETACH
: GOMP_MAP_ATTACH
);
9569 OMP_CLAUSE_SET_MAP_KIND (c
, k
);
9570 has_attachments
= true;
9572 if (n
== NULL
|| (n
->value
& GOVD_MAP
) == 0)
9574 tree l
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
9576 gomp_map_kind k
= attach
? GOMP_MAP_FORCE_PRESENT
9579 OMP_CLAUSE_SET_MAP_KIND (l
, k
);
9581 OMP_CLAUSE_DECL (l
) = unshare_expr (base_ref
);
9583 OMP_CLAUSE_DECL (l
) = decl
;
9587 : DECL_P (OMP_CLAUSE_DECL (l
))
9588 ? DECL_SIZE_UNIT (OMP_CLAUSE_DECL (l
))
9589 : TYPE_SIZE_UNIT (TREE_TYPE (OMP_CLAUSE_DECL (l
))));
9590 if (struct_map_to_clause
== NULL
)
9591 struct_map_to_clause
= new hash_map
<tree
, tree
>;
9592 struct_map_to_clause
->put (decl
, l
);
9593 if (ptr
|| attach_detach
)
9595 insert_struct_comp_map (code
, c
, l
, *prev_list_p
,
9602 OMP_CLAUSE_CHAIN (l
) = c
;
9604 list_p
= &OMP_CLAUSE_CHAIN (l
);
9606 if (base_ref
&& code
== OMP_TARGET
)
9608 tree c2
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
9610 enum gomp_map_kind mkind
9611 = GOMP_MAP_FIRSTPRIVATE_REFERENCE
;
9612 OMP_CLAUSE_SET_MAP_KIND (c2
, mkind
);
9613 OMP_CLAUSE_DECL (c2
) = decl
;
9614 OMP_CLAUSE_SIZE (c2
) = size_zero_node
;
9615 OMP_CLAUSE_CHAIN (c2
) = OMP_CLAUSE_CHAIN (l
);
9616 OMP_CLAUSE_CHAIN (l
) = c2
;
9618 flags
= GOVD_MAP
| GOVD_EXPLICIT
;
9619 if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c
))
9623 if (has_attachments
)
9624 flags
|= GOVD_MAP_HAS_ATTACHMENTS
;
9627 else if (struct_map_to_clause
)
9629 tree
*osc
= struct_map_to_clause
->get (decl
);
9630 tree
*sc
= NULL
, *scp
= NULL
;
9631 if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c
))
9634 n
->value
|= GOVD_SEEN
;
9635 sc
= &OMP_CLAUSE_CHAIN (*osc
);
9637 && (OMP_CLAUSE_MAP_KIND (*sc
)
9638 == GOMP_MAP_FIRSTPRIVATE_REFERENCE
))
9639 sc
= &OMP_CLAUSE_CHAIN (*sc
);
9640 /* Here "prev_list_p" is the end of the inserted
9641 alloc/release nodes after the struct node, OSC. */
9642 for (; *sc
!= c
; sc
= &OMP_CLAUSE_CHAIN (*sc
))
9643 if ((ptr
|| attach_detach
) && sc
== prev_list_p
)
9645 else if (TREE_CODE (OMP_CLAUSE_DECL (*sc
))
9647 && (TREE_CODE (OMP_CLAUSE_DECL (*sc
))
9649 && (TREE_CODE (OMP_CLAUSE_DECL (*sc
))
9654 tree sc_decl
= OMP_CLAUSE_DECL (*sc
);
9655 poly_offset_int offsetn
;
9658 = extract_base_bit_offset (sc_decl
, NULL
,
9659 &bitposn
, &offsetn
);
9664 if ((region_type
& ORT_ACC
) != 0)
9666 /* This duplicate checking code is currently only
9667 enabled for OpenACC. */
9668 tree d1
= OMP_CLAUSE_DECL (*sc
);
9669 tree d2
= OMP_CLAUSE_DECL (c
);
9670 while (TREE_CODE (d1
) == ARRAY_REF
)
9671 d1
= TREE_OPERAND (d1
, 0);
9672 while (TREE_CODE (d2
) == ARRAY_REF
)
9673 d2
= TREE_OPERAND (d2
, 0);
9674 if (TREE_CODE (d1
) == INDIRECT_REF
)
9675 d1
= TREE_OPERAND (d1
, 0);
9676 if (TREE_CODE (d2
) == INDIRECT_REF
)
9677 d2
= TREE_OPERAND (d2
, 0);
9678 while (TREE_CODE (d1
) == COMPONENT_REF
)
9679 if (TREE_CODE (d2
) == COMPONENT_REF
9680 && TREE_OPERAND (d1
, 1)
9681 == TREE_OPERAND (d2
, 1))
9683 d1
= TREE_OPERAND (d1
, 0);
9684 d2
= TREE_OPERAND (d2
, 0);
9690 error_at (OMP_CLAUSE_LOCATION (c
),
9691 "%qE appears more than once in map "
9692 "clauses", OMP_CLAUSE_DECL (c
));
9697 if (maybe_lt (offset1
, offsetn
)
9698 || (known_eq (offset1
, offsetn
)
9699 && maybe_lt (bitpos1
, bitposn
)))
9701 if (ptr
|| attach_detach
)
9710 OMP_CLAUSE_SIZE (*osc
)
9711 = size_binop (PLUS_EXPR
, OMP_CLAUSE_SIZE (*osc
),
9713 if (ptr
|| attach_detach
)
9715 tree cl
= insert_struct_comp_map (code
, c
, NULL
,
9717 if (sc
== prev_list_p
)
9724 *prev_list_p
= OMP_CLAUSE_CHAIN (c
);
9725 list_p
= prev_list_p
;
9727 OMP_CLAUSE_CHAIN (c
) = *sc
;
9734 *list_p
= OMP_CLAUSE_CHAIN (c
);
9735 OMP_CLAUSE_CHAIN (c
) = *sc
;
9741 else if ((code
== OACC_ENTER_DATA
9742 || code
== OACC_EXIT_DATA
9743 || code
== OACC_DATA
9744 || code
== OACC_PARALLEL
9745 || code
== OACC_KERNELS
9746 || code
== OACC_SERIAL
)
9747 && OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ATTACH_DETACH
)
9749 gomp_map_kind k
= (code
== OACC_EXIT_DATA
9750 ? GOMP_MAP_DETACH
: GOMP_MAP_ATTACH
);
9751 OMP_CLAUSE_SET_MAP_KIND (c
, k
);
9754 if (code
== OMP_TARGET
&& OMP_CLAUSE_MAP_IN_REDUCTION (c
))
9756 /* Don't gimplify *pd fully at this point, as the base
9757 will need to be adjusted during omp lowering. */
9758 auto_vec
<tree
, 10> expr_stack
;
9760 while (handled_component_p (*p
)
9761 || TREE_CODE (*p
) == INDIRECT_REF
9762 || TREE_CODE (*p
) == ADDR_EXPR
9763 || TREE_CODE (*p
) == MEM_REF
9764 || TREE_CODE (*p
) == NON_LVALUE_EXPR
)
9766 expr_stack
.safe_push (*p
);
9767 p
= &TREE_OPERAND (*p
, 0);
9769 for (int i
= expr_stack
.length () - 1; i
>= 0; i
--)
9771 tree t
= expr_stack
[i
];
9772 if (TREE_CODE (t
) == ARRAY_REF
9773 || TREE_CODE (t
) == ARRAY_RANGE_REF
)
9775 if (TREE_OPERAND (t
, 2) == NULL_TREE
)
9777 tree low
= unshare_expr (array_ref_low_bound (t
));
9778 if (!is_gimple_min_invariant (low
))
9780 TREE_OPERAND (t
, 2) = low
;
9781 if (gimplify_expr (&TREE_OPERAND (t
, 2),
9784 fb_rvalue
) == GS_ERROR
)
9788 else if (gimplify_expr (&TREE_OPERAND (t
, 2), pre_p
,
9789 NULL
, is_gimple_reg
,
9790 fb_rvalue
) == GS_ERROR
)
9792 if (TREE_OPERAND (t
, 3) == NULL_TREE
)
9794 tree elmt_size
= array_ref_element_size (t
);
9795 if (!is_gimple_min_invariant (elmt_size
))
9797 elmt_size
= unshare_expr (elmt_size
);
9799 = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t
,
9802 = size_int (TYPE_ALIGN_UNIT (elmt_type
));
9804 = size_binop (EXACT_DIV_EXPR
, elmt_size
,
9806 TREE_OPERAND (t
, 3) = elmt_size
;
9807 if (gimplify_expr (&TREE_OPERAND (t
, 3),
9810 fb_rvalue
) == GS_ERROR
)
9814 else if (gimplify_expr (&TREE_OPERAND (t
, 3), pre_p
,
9815 NULL
, is_gimple_reg
,
9816 fb_rvalue
) == GS_ERROR
)
9819 else if (TREE_CODE (t
) == COMPONENT_REF
)
9821 if (TREE_OPERAND (t
, 2) == NULL_TREE
)
9823 tree offset
= component_ref_field_offset (t
);
9824 if (!is_gimple_min_invariant (offset
))
9826 offset
= unshare_expr (offset
);
9827 tree field
= TREE_OPERAND (t
, 1);
9829 = size_int (DECL_OFFSET_ALIGN (field
)
9831 offset
= size_binop (EXACT_DIV_EXPR
, offset
,
9833 TREE_OPERAND (t
, 2) = offset
;
9834 if (gimplify_expr (&TREE_OPERAND (t
, 2),
9837 fb_rvalue
) == GS_ERROR
)
9841 else if (gimplify_expr (&TREE_OPERAND (t
, 2), pre_p
,
9842 NULL
, is_gimple_reg
,
9843 fb_rvalue
) == GS_ERROR
)
9847 for (; expr_stack
.length () > 0; )
9849 tree t
= expr_stack
.pop ();
9851 if (TREE_CODE (t
) == ARRAY_REF
9852 || TREE_CODE (t
) == ARRAY_RANGE_REF
)
9854 if (!is_gimple_min_invariant (TREE_OPERAND (t
, 1))
9855 && gimplify_expr (&TREE_OPERAND (t
, 1), pre_p
,
9856 NULL
, is_gimple_val
,
9857 fb_rvalue
) == GS_ERROR
)
9862 else if (gimplify_expr (pd
, pre_p
, NULL
, is_gimple_lvalue
,
9863 fb_lvalue
) == GS_ERROR
)
9870 && OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_ALWAYS_POINTER
9871 && OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_ATTACH_DETACH
9872 && OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_TO_PSET
9873 && OMP_CLAUSE_CHAIN (c
)
9874 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (c
)) == OMP_CLAUSE_MAP
9875 && ((OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c
))
9876 == GOMP_MAP_ALWAYS_POINTER
)
9877 || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c
))
9878 == GOMP_MAP_ATTACH_DETACH
)
9879 || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c
))
9880 == GOMP_MAP_TO_PSET
)))
9881 prev_list_p
= list_p
;
9887 /* DECL_P (decl) == true */
9889 if (struct_map_to_clause
9890 && (sc
= struct_map_to_clause
->get (decl
)) != NULL
9891 && OMP_CLAUSE_MAP_KIND (*sc
) == GOMP_MAP_STRUCT
9892 && decl
== OMP_CLAUSE_DECL (*sc
))
9894 /* We have found a map of the whole structure after a
9895 leading GOMP_MAP_STRUCT has been created, so refill the
9896 leading clause into a map of the whole structure
9897 variable, and remove the current one.
9898 TODO: we should be able to remove some maps of the
9899 following structure element maps if they are of
9900 compatible TO/FROM/ALLOC type. */
9901 OMP_CLAUSE_SET_MAP_KIND (*sc
, OMP_CLAUSE_MAP_KIND (c
));
9902 OMP_CLAUSE_SIZE (*sc
) = unshare_expr (OMP_CLAUSE_SIZE (c
));
9907 flags
= GOVD_MAP
| GOVD_EXPLICIT
;
9908 if (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ALWAYS_TO
9909 || OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ALWAYS_TOFROM
)
9910 flags
|= GOVD_MAP_ALWAYS_TO
;
9912 if ((code
== OMP_TARGET
9913 || code
== OMP_TARGET_DATA
9914 || code
== OMP_TARGET_ENTER_DATA
9915 || code
== OMP_TARGET_EXIT_DATA
)
9916 && OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ATTACH_DETACH
)
9918 for (struct gimplify_omp_ctx
*octx
= outer_ctx
; octx
;
9919 octx
= octx
->outer_context
)
9922 = splay_tree_lookup (octx
->variables
,
9923 (splay_tree_key
) OMP_CLAUSE_DECL (c
));
9924 /* If this is contained in an outer OpenMP region as a
9925 firstprivate value, remove the attach/detach. */
9926 if (n
&& (n
->value
& GOVD_FIRSTPRIVATE
))
9928 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_FIRSTPRIVATE_POINTER
);
9933 enum gomp_map_kind map_kind
= (code
== OMP_TARGET_EXIT_DATA
9936 OMP_CLAUSE_SET_MAP_KIND (c
, map_kind
);
9941 case OMP_CLAUSE_AFFINITY
:
9942 gimplify_omp_affinity (list_p
, pre_p
);
9945 case OMP_CLAUSE_DEPEND
:
9946 if (OMP_CLAUSE_DEPEND_KIND (c
) == OMP_CLAUSE_DEPEND_SINK
)
9948 tree deps
= OMP_CLAUSE_DECL (c
);
9949 while (deps
&& TREE_CODE (deps
) == TREE_LIST
)
9951 if (TREE_CODE (TREE_PURPOSE (deps
)) == TRUNC_DIV_EXPR
9952 && DECL_P (TREE_OPERAND (TREE_PURPOSE (deps
), 1)))
9953 gimplify_expr (&TREE_OPERAND (TREE_PURPOSE (deps
), 1),
9954 pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
9955 deps
= TREE_CHAIN (deps
);
9959 else if (OMP_CLAUSE_DEPEND_KIND (c
) == OMP_CLAUSE_DEPEND_SOURCE
)
9961 if (handled_depend_iterators
== -1)
9962 handled_depend_iterators
= gimplify_omp_depend (list_p
, pre_p
);
9963 if (handled_depend_iterators
)
9965 if (handled_depend_iterators
== 2)
9969 if (TREE_CODE (OMP_CLAUSE_DECL (c
)) == COMPOUND_EXPR
)
9971 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c
), 0), pre_p
,
9972 NULL
, is_gimple_val
, fb_rvalue
);
9973 OMP_CLAUSE_DECL (c
) = TREE_OPERAND (OMP_CLAUSE_DECL (c
), 1);
9975 if (error_operand_p (OMP_CLAUSE_DECL (c
)))
9980 OMP_CLAUSE_DECL (c
) = build_fold_addr_expr (OMP_CLAUSE_DECL (c
));
9981 if (gimplify_expr (&OMP_CLAUSE_DECL (c
), pre_p
, NULL
,
9982 is_gimple_val
, fb_rvalue
) == GS_ERROR
)
9987 if (code
== OMP_TASK
)
9988 ctx
->has_depend
= true;
9992 case OMP_CLAUSE_FROM
:
9993 case OMP_CLAUSE__CACHE_
:
9994 decl
= OMP_CLAUSE_DECL (c
);
9995 if (error_operand_p (decl
))
10000 if (OMP_CLAUSE_SIZE (c
) == NULL_TREE
)
10001 OMP_CLAUSE_SIZE (c
) = DECL_P (decl
) ? DECL_SIZE_UNIT (decl
)
10002 : TYPE_SIZE_UNIT (TREE_TYPE (decl
));
10003 if (gimplify_expr (&OMP_CLAUSE_SIZE (c
), pre_p
,
10004 NULL
, is_gimple_val
, fb_rvalue
) == GS_ERROR
)
10009 if (!DECL_P (decl
))
10011 if (gimplify_expr (&OMP_CLAUSE_DECL (c
), pre_p
,
10012 NULL
, is_gimple_lvalue
, fb_lvalue
)
10022 case OMP_CLAUSE_USE_DEVICE_PTR
:
10023 case OMP_CLAUSE_USE_DEVICE_ADDR
:
10024 flags
= GOVD_EXPLICIT
;
10027 case OMP_CLAUSE_IS_DEVICE_PTR
:
10028 flags
= GOVD_FIRSTPRIVATE
| GOVD_EXPLICIT
;
10032 decl
= OMP_CLAUSE_DECL (c
);
10034 if (error_operand_p (decl
))
10039 if (DECL_NAME (decl
) == NULL_TREE
&& (flags
& GOVD_SHARED
) == 0)
10041 tree t
= omp_member_access_dummy_var (decl
);
10044 tree v
= DECL_VALUE_EXPR (decl
);
10045 DECL_NAME (decl
) = DECL_NAME (TREE_OPERAND (v
, 1));
10047 omp_notice_variable (outer_ctx
, t
, true);
10050 if (code
== OACC_DATA
10051 && OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_MAP
10052 && OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_FIRSTPRIVATE_POINTER
)
10053 flags
|= GOVD_MAP_0LEN_ARRAY
;
10054 omp_add_variable (ctx
, decl
, flags
);
10055 if ((OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
10056 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_IN_REDUCTION
10057 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_TASK_REDUCTION
)
10058 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
))
10060 struct gimplify_omp_ctx
*pctx
10061 = code
== OMP_TARGET
? outer_ctx
: ctx
;
10063 omp_add_variable (pctx
, OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
),
10064 GOVD_LOCAL
| GOVD_SEEN
);
10066 && OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c
)
10067 && walk_tree (&OMP_CLAUSE_REDUCTION_INIT (c
),
10069 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c
),
10070 NULL
) == NULL_TREE
)
10071 omp_add_variable (pctx
,
10072 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c
),
10073 GOVD_LOCAL
| GOVD_SEEN
);
10074 gimplify_omp_ctxp
= pctx
;
10075 push_gimplify_context ();
10077 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c
) = NULL
;
10078 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c
) = NULL
;
10080 gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c
),
10081 &OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c
));
10082 pop_gimplify_context
10083 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c
)));
10084 push_gimplify_context ();
10085 gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c
),
10086 &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c
));
10087 pop_gimplify_context
10088 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c
)));
10089 OMP_CLAUSE_REDUCTION_INIT (c
) = NULL_TREE
;
10090 OMP_CLAUSE_REDUCTION_MERGE (c
) = NULL_TREE
;
10092 gimplify_omp_ctxp
= outer_ctx
;
10094 else if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
10095 && OMP_CLAUSE_LASTPRIVATE_STMT (c
))
10097 gimplify_omp_ctxp
= ctx
;
10098 push_gimplify_context ();
10099 if (TREE_CODE (OMP_CLAUSE_LASTPRIVATE_STMT (c
)) != BIND_EXPR
)
10101 tree bind
= build3 (BIND_EXPR
, void_type_node
, NULL
,
10103 TREE_SIDE_EFFECTS (bind
) = 1;
10104 BIND_EXPR_BODY (bind
) = OMP_CLAUSE_LASTPRIVATE_STMT (c
);
10105 OMP_CLAUSE_LASTPRIVATE_STMT (c
) = bind
;
10107 gimplify_and_add (OMP_CLAUSE_LASTPRIVATE_STMT (c
),
10108 &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
));
10109 pop_gimplify_context
10110 (gimple_seq_first_stmt (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
)));
10111 OMP_CLAUSE_LASTPRIVATE_STMT (c
) = NULL_TREE
;
10113 gimplify_omp_ctxp
= outer_ctx
;
10115 else if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINEAR
10116 && OMP_CLAUSE_LINEAR_STMT (c
))
10118 gimplify_omp_ctxp
= ctx
;
10119 push_gimplify_context ();
10120 if (TREE_CODE (OMP_CLAUSE_LINEAR_STMT (c
)) != BIND_EXPR
)
10122 tree bind
= build3 (BIND_EXPR
, void_type_node
, NULL
,
10124 TREE_SIDE_EFFECTS (bind
) = 1;
10125 BIND_EXPR_BODY (bind
) = OMP_CLAUSE_LINEAR_STMT (c
);
10126 OMP_CLAUSE_LINEAR_STMT (c
) = bind
;
10128 gimplify_and_add (OMP_CLAUSE_LINEAR_STMT (c
),
10129 &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c
));
10130 pop_gimplify_context
10131 (gimple_seq_first_stmt (OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c
)));
10132 OMP_CLAUSE_LINEAR_STMT (c
) = NULL_TREE
;
10134 gimplify_omp_ctxp
= outer_ctx
;
10140 case OMP_CLAUSE_COPYIN
:
10141 case OMP_CLAUSE_COPYPRIVATE
:
10142 decl
= OMP_CLAUSE_DECL (c
);
10143 if (error_operand_p (decl
))
10148 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_COPYPRIVATE
10150 && !omp_check_private (ctx
, decl
, true))
10153 if (is_global_var (decl
))
10155 if (DECL_THREAD_LOCAL_P (decl
))
10157 else if (DECL_HAS_VALUE_EXPR_P (decl
))
10159 tree value
= get_base_address (DECL_VALUE_EXPR (decl
));
10163 && DECL_THREAD_LOCAL_P (value
))
10168 error_at (OMP_CLAUSE_LOCATION (c
),
10169 "copyprivate variable %qE is not threadprivate"
10170 " or private in outer context", DECL_NAME (decl
));
10173 if ((OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
10174 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_FIRSTPRIVATE
10175 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
)
10177 && ((region_type
& ORT_TASKLOOP
) == ORT_TASKLOOP
10178 || (region_type
== ORT_WORKSHARE
10179 && OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
10180 && (OMP_CLAUSE_REDUCTION_INSCAN (c
)
10181 || code
== OMP_LOOP
)))
10182 && (outer_ctx
->region_type
== ORT_COMBINED_PARALLEL
10183 || (code
== OMP_LOOP
10184 && OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
10185 && ((outer_ctx
->region_type
& ORT_COMBINED_TEAMS
)
10186 == ORT_COMBINED_TEAMS
))))
10189 = splay_tree_lookup (outer_ctx
->variables
,
10190 (splay_tree_key
)decl
);
10191 if (on
== NULL
|| (on
->value
& GOVD_DATA_SHARE_CLASS
) == 0)
10193 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
10194 && TREE_CODE (OMP_CLAUSE_DECL (c
)) == MEM_REF
10195 && (TREE_CODE (TREE_TYPE (decl
)) == POINTER_TYPE
10196 || (TREE_CODE (TREE_TYPE (decl
)) == REFERENCE_TYPE
10197 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl
)))
10198 == POINTER_TYPE
))))
10199 omp_firstprivatize_variable (outer_ctx
, decl
);
10202 omp_add_variable (outer_ctx
, decl
,
10203 GOVD_SEEN
| GOVD_SHARED
);
10204 if (outer_ctx
->outer_context
)
10205 omp_notice_variable (outer_ctx
->outer_context
, decl
,
10211 omp_notice_variable (outer_ctx
, decl
, true);
10212 if (check_non_private
10213 && (region_type
== ORT_WORKSHARE
|| code
== OMP_SCOPE
)
10214 && (OMP_CLAUSE_CODE (c
) != OMP_CLAUSE_REDUCTION
10215 || decl
== OMP_CLAUSE_DECL (c
)
10216 || (TREE_CODE (OMP_CLAUSE_DECL (c
)) == MEM_REF
10217 && (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c
), 0))
10219 || (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c
), 0))
10220 == POINTER_PLUS_EXPR
10221 && (TREE_CODE (TREE_OPERAND (TREE_OPERAND
10222 (OMP_CLAUSE_DECL (c
), 0), 0))
10224 && omp_check_private (ctx
, decl
, false))
10226 error ("%s variable %qE is private in outer context",
10227 check_non_private
, DECL_NAME (decl
));
10232 case OMP_CLAUSE_DETACH
:
10233 flags
= GOVD_FIRSTPRIVATE
| GOVD_SEEN
;
10236 case OMP_CLAUSE_IF
:
10237 if (OMP_CLAUSE_IF_MODIFIER (c
) != ERROR_MARK
10238 && OMP_CLAUSE_IF_MODIFIER (c
) != code
)
10241 for (int i
= 0; i
< 2; i
++)
10242 switch (i
? OMP_CLAUSE_IF_MODIFIER (c
) : code
)
10244 case VOID_CST
: p
[i
] = "cancel"; break;
10245 case OMP_PARALLEL
: p
[i
] = "parallel"; break;
10246 case OMP_SIMD
: p
[i
] = "simd"; break;
10247 case OMP_TASK
: p
[i
] = "task"; break;
10248 case OMP_TASKLOOP
: p
[i
] = "taskloop"; break;
10249 case OMP_TARGET_DATA
: p
[i
] = "target data"; break;
10250 case OMP_TARGET
: p
[i
] = "target"; break;
10251 case OMP_TARGET_UPDATE
: p
[i
] = "target update"; break;
10252 case OMP_TARGET_ENTER_DATA
:
10253 p
[i
] = "target enter data"; break;
10254 case OMP_TARGET_EXIT_DATA
: p
[i
] = "target exit data"; break;
10255 default: gcc_unreachable ();
10257 error_at (OMP_CLAUSE_LOCATION (c
),
10258 "expected %qs %<if%> clause modifier rather than %qs",
10262 /* Fall through. */
10264 case OMP_CLAUSE_FINAL
:
10265 OMP_CLAUSE_OPERAND (c
, 0)
10266 = gimple_boolify (OMP_CLAUSE_OPERAND (c
, 0));
10267 /* Fall through. */
10269 case OMP_CLAUSE_NUM_TEAMS
:
10270 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_NUM_TEAMS
10271 && OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c
)
10272 && !is_gimple_min_invariant (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c
)))
10274 if (error_operand_p (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c
)))
10279 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c
)
10280 = get_initialized_tmp_var (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c
),
10281 pre_p
, NULL
, true);
10283 /* Fall through. */
10285 case OMP_CLAUSE_SCHEDULE
:
10286 case OMP_CLAUSE_NUM_THREADS
:
10287 case OMP_CLAUSE_THREAD_LIMIT
:
10288 case OMP_CLAUSE_DIST_SCHEDULE
:
10289 case OMP_CLAUSE_DEVICE
:
10290 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEVICE
10291 && OMP_CLAUSE_DEVICE_ANCESTOR (c
))
10293 if (code
!= OMP_TARGET
)
10295 error_at (OMP_CLAUSE_LOCATION (c
),
10296 "%<device%> clause with %<ancestor%> is only "
10297 "allowed on %<target%> construct");
10302 tree clauses
= *orig_list_p
;
10303 for (; clauses
; clauses
= OMP_CLAUSE_CHAIN (clauses
))
10304 if (OMP_CLAUSE_CODE (clauses
) != OMP_CLAUSE_DEVICE
10305 && OMP_CLAUSE_CODE (clauses
) != OMP_CLAUSE_FIRSTPRIVATE
10306 && OMP_CLAUSE_CODE (clauses
) != OMP_CLAUSE_PRIVATE
10307 && OMP_CLAUSE_CODE (clauses
) != OMP_CLAUSE_DEFAULTMAP
10308 && OMP_CLAUSE_CODE (clauses
) != OMP_CLAUSE_MAP
10311 error_at (OMP_CLAUSE_LOCATION (c
),
10312 "with %<ancestor%>, only the %<device%>, "
10313 "%<firstprivate%>, %<private%>, %<defaultmap%>, "
10314 "and %<map%> clauses may appear on the "
10320 /* Fall through. */
10322 case OMP_CLAUSE_PRIORITY
:
10323 case OMP_CLAUSE_GRAINSIZE
:
10324 case OMP_CLAUSE_NUM_TASKS
:
10325 case OMP_CLAUSE_FILTER
:
10326 case OMP_CLAUSE_HINT
:
10327 case OMP_CLAUSE_ASYNC
:
10328 case OMP_CLAUSE_WAIT
:
10329 case OMP_CLAUSE_NUM_GANGS
:
10330 case OMP_CLAUSE_NUM_WORKERS
:
10331 case OMP_CLAUSE_VECTOR_LENGTH
:
10332 case OMP_CLAUSE_WORKER
:
10333 case OMP_CLAUSE_VECTOR
:
10334 if (OMP_CLAUSE_OPERAND (c
, 0)
10335 && !is_gimple_min_invariant (OMP_CLAUSE_OPERAND (c
, 0)))
10337 if (error_operand_p (OMP_CLAUSE_OPERAND (c
, 0)))
10342 /* All these clauses care about value, not a particular decl,
10343 so try to force it into a SSA_NAME or fresh temporary. */
10344 OMP_CLAUSE_OPERAND (c
, 0)
10345 = get_initialized_tmp_var (OMP_CLAUSE_OPERAND (c
, 0),
10346 pre_p
, NULL
, true);
10350 case OMP_CLAUSE_GANG
:
10351 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c
, 0), pre_p
, NULL
,
10352 is_gimple_val
, fb_rvalue
) == GS_ERROR
)
10354 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c
, 1), pre_p
, NULL
,
10355 is_gimple_val
, fb_rvalue
) == GS_ERROR
)
10359 case OMP_CLAUSE_NOWAIT
:
10363 case OMP_CLAUSE_ORDERED
:
10364 case OMP_CLAUSE_UNTIED
:
10365 case OMP_CLAUSE_COLLAPSE
:
10366 case OMP_CLAUSE_TILE
:
10367 case OMP_CLAUSE_AUTO
:
10368 case OMP_CLAUSE_SEQ
:
10369 case OMP_CLAUSE_INDEPENDENT
:
10370 case OMP_CLAUSE_MERGEABLE
:
10371 case OMP_CLAUSE_PROC_BIND
:
10372 case OMP_CLAUSE_SAFELEN
:
10373 case OMP_CLAUSE_SIMDLEN
:
10374 case OMP_CLAUSE_NOGROUP
:
10375 case OMP_CLAUSE_THREADS
:
10376 case OMP_CLAUSE_SIMD
:
10377 case OMP_CLAUSE_BIND
:
10378 case OMP_CLAUSE_IF_PRESENT
:
10379 case OMP_CLAUSE_FINALIZE
:
10382 case OMP_CLAUSE_ORDER
:
10383 ctx
->order_concurrent
= true;
10386 case OMP_CLAUSE_DEFAULTMAP
:
10387 enum gimplify_defaultmap_kind gdmkmin
, gdmkmax
;
10388 switch (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
))
10390 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
:
10391 gdmkmin
= GDMK_SCALAR
;
10392 gdmkmax
= GDMK_POINTER
;
10394 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR
:
10395 gdmkmin
= GDMK_SCALAR
;
10396 gdmkmax
= GDMK_SCALAR_TARGET
;
10398 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE
:
10399 gdmkmin
= gdmkmax
= GDMK_AGGREGATE
;
10401 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALLOCATABLE
:
10402 gdmkmin
= gdmkmax
= GDMK_ALLOCATABLE
;
10404 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER
:
10405 gdmkmin
= gdmkmax
= GDMK_POINTER
;
10408 gcc_unreachable ();
10410 for (int gdmk
= gdmkmin
; gdmk
<= gdmkmax
; gdmk
++)
10411 switch (OMP_CLAUSE_DEFAULTMAP_BEHAVIOR (c
))
10413 case OMP_CLAUSE_DEFAULTMAP_ALLOC
:
10414 ctx
->defaultmap
[gdmk
] = GOVD_MAP
| GOVD_MAP_ALLOC_ONLY
;
10416 case OMP_CLAUSE_DEFAULTMAP_TO
:
10417 ctx
->defaultmap
[gdmk
] = GOVD_MAP
| GOVD_MAP_TO_ONLY
;
10419 case OMP_CLAUSE_DEFAULTMAP_FROM
:
10420 ctx
->defaultmap
[gdmk
] = GOVD_MAP
| GOVD_MAP_FROM_ONLY
;
10422 case OMP_CLAUSE_DEFAULTMAP_TOFROM
:
10423 ctx
->defaultmap
[gdmk
] = GOVD_MAP
;
10425 case OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE
:
10426 ctx
->defaultmap
[gdmk
] = GOVD_FIRSTPRIVATE
;
10428 case OMP_CLAUSE_DEFAULTMAP_NONE
:
10429 ctx
->defaultmap
[gdmk
] = 0;
10431 case OMP_CLAUSE_DEFAULTMAP_DEFAULT
:
10435 ctx
->defaultmap
[gdmk
] = GOVD_FIRSTPRIVATE
;
10437 case GDMK_SCALAR_TARGET
:
10438 ctx
->defaultmap
[gdmk
] = (lang_GNU_Fortran ()
10439 ? GOVD_MAP
: GOVD_FIRSTPRIVATE
);
10441 case GDMK_AGGREGATE
:
10442 case GDMK_ALLOCATABLE
:
10443 ctx
->defaultmap
[gdmk
] = GOVD_MAP
;
10446 ctx
->defaultmap
[gdmk
] = GOVD_MAP
;
10447 if (!lang_GNU_Fortran ())
10448 ctx
->defaultmap
[gdmk
] |= GOVD_MAP_0LEN_ARRAY
;
10451 gcc_unreachable ();
10455 gcc_unreachable ();
10459 case OMP_CLAUSE_ALIGNED
:
10460 decl
= OMP_CLAUSE_DECL (c
);
10461 if (error_operand_p (decl
))
10466 if (gimplify_expr (&OMP_CLAUSE_ALIGNED_ALIGNMENT (c
), pre_p
, NULL
,
10467 is_gimple_val
, fb_rvalue
) == GS_ERROR
)
10472 if (!is_global_var (decl
)
10473 && TREE_CODE (TREE_TYPE (decl
)) == POINTER_TYPE
)
10474 omp_add_variable (ctx
, decl
, GOVD_ALIGNED
);
10477 case OMP_CLAUSE_NONTEMPORAL
:
10478 decl
= OMP_CLAUSE_DECL (c
);
10479 if (error_operand_p (decl
))
10484 omp_add_variable (ctx
, decl
, GOVD_NONTEMPORAL
);
10487 case OMP_CLAUSE_ALLOCATE
:
10488 decl
= OMP_CLAUSE_DECL (c
);
10489 if (error_operand_p (decl
))
10494 if (gimplify_expr (&OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
), pre_p
, NULL
,
10495 is_gimple_val
, fb_rvalue
) == GS_ERROR
)
10500 else if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
) == NULL_TREE
10501 || (TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
))
10504 else if (code
== OMP_TASKLOOP
10505 || !DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
)))
10506 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
)
10507 = get_initialized_tmp_var (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
),
10508 pre_p
, NULL
, false);
10511 case OMP_CLAUSE_DEFAULT
:
10512 ctx
->default_kind
= OMP_CLAUSE_DEFAULT_KIND (c
);
10515 case OMP_CLAUSE_INCLUSIVE
:
10516 case OMP_CLAUSE_EXCLUSIVE
:
10517 decl
= OMP_CLAUSE_DECL (c
);
10519 splay_tree_node n
= splay_tree_lookup (outer_ctx
->variables
,
10520 (splay_tree_key
) decl
);
10521 if (n
== NULL
|| (n
->value
& GOVD_REDUCTION
) == 0)
10523 error_at (OMP_CLAUSE_LOCATION (c
),
10524 "%qD specified in %qs clause but not in %<inscan%> "
10525 "%<reduction%> clause on the containing construct",
10526 decl
, omp_clause_code_name
[OMP_CLAUSE_CODE (c
)]);
10531 n
->value
|= GOVD_REDUCTION_INSCAN
;
10532 if (outer_ctx
->region_type
== ORT_SIMD
10533 && outer_ctx
->outer_context
10534 && outer_ctx
->outer_context
->region_type
== ORT_WORKSHARE
)
10536 n
= splay_tree_lookup (outer_ctx
->outer_context
->variables
,
10537 (splay_tree_key
) decl
);
10538 if (n
&& (n
->value
& GOVD_REDUCTION
) != 0)
10539 n
->value
|= GOVD_REDUCTION_INSCAN
;
10545 case OMP_CLAUSE_NOHOST
:
10547 gcc_unreachable ();
10550 if (code
== OACC_DATA
10551 && OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_MAP
10552 && (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_FIRSTPRIVATE_POINTER
10553 || OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
))
10556 *list_p
= OMP_CLAUSE_CHAIN (c
);
10558 list_p
= &OMP_CLAUSE_CHAIN (c
);
10561 ctx
->clauses
= *orig_list_p
;
10562 gimplify_omp_ctxp
= ctx
;
10563 if (struct_map_to_clause
)
10564 delete struct_map_to_clause
;
10565 if (struct_deref_set
)
10566 delete struct_deref_set
;
10569 /* Return true if DECL is a candidate for shared to firstprivate
10570 optimization. We only consider non-addressable scalars, not
10571 too big, and not references. */
10574 omp_shared_to_firstprivate_optimizable_decl_p (tree decl
)
10576 if (TREE_ADDRESSABLE (decl
))
10578 tree type
= TREE_TYPE (decl
);
10579 if (!is_gimple_reg_type (type
)
10580 || TREE_CODE (type
) == REFERENCE_TYPE
10581 || TREE_ADDRESSABLE (type
))
10583 /* Don't optimize too large decls, as each thread/task will have
10585 HOST_WIDE_INT len
= int_size_in_bytes (type
);
10586 if (len
== -1 || len
> 4 * POINTER_SIZE
/ BITS_PER_UNIT
)
10588 if (omp_privatize_by_reference (decl
))
10593 /* Helper function of omp_find_stores_op and gimplify_adjust_omp_clauses*.
10594 For omp_shared_to_firstprivate_optimizable_decl_p decl mark it as
10595 GOVD_WRITTEN in outer contexts. */
10598 omp_mark_stores (struct gimplify_omp_ctx
*ctx
, tree decl
)
10600 for (; ctx
; ctx
= ctx
->outer_context
)
10602 splay_tree_node n
= splay_tree_lookup (ctx
->variables
,
10603 (splay_tree_key
) decl
);
10606 else if (n
->value
& GOVD_SHARED
)
10608 n
->value
|= GOVD_WRITTEN
;
10611 else if (n
->value
& GOVD_DATA_SHARE_CLASS
)
10616 /* Helper callback for walk_gimple_seq to discover possible stores
10617 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
10618 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
10622 omp_find_stores_op (tree
*tp
, int *walk_subtrees
, void *data
)
10624 struct walk_stmt_info
*wi
= (struct walk_stmt_info
*) data
;
10626 *walk_subtrees
= 0;
10633 if (handled_component_p (op
))
10634 op
= TREE_OPERAND (op
, 0);
10635 else if ((TREE_CODE (op
) == MEM_REF
|| TREE_CODE (op
) == TARGET_MEM_REF
)
10636 && TREE_CODE (TREE_OPERAND (op
, 0)) == ADDR_EXPR
)
10637 op
= TREE_OPERAND (TREE_OPERAND (op
, 0), 0);
10642 if (!DECL_P (op
) || !omp_shared_to_firstprivate_optimizable_decl_p (op
))
10645 omp_mark_stores (gimplify_omp_ctxp
, op
);
10649 /* Helper callback for walk_gimple_seq to discover possible stores
10650 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
10651 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
10655 omp_find_stores_stmt (gimple_stmt_iterator
*gsi_p
,
10656 bool *handled_ops_p
,
10657 struct walk_stmt_info
*wi
)
10659 gimple
*stmt
= gsi_stmt (*gsi_p
);
10660 switch (gimple_code (stmt
))
10662 /* Don't recurse on OpenMP constructs for which
10663 gimplify_adjust_omp_clauses already handled the bodies,
10664 except handle gimple_omp_for_pre_body. */
10665 case GIMPLE_OMP_FOR
:
10666 *handled_ops_p
= true;
10667 if (gimple_omp_for_pre_body (stmt
))
10668 walk_gimple_seq (gimple_omp_for_pre_body (stmt
),
10669 omp_find_stores_stmt
, omp_find_stores_op
, wi
);
10671 case GIMPLE_OMP_PARALLEL
:
10672 case GIMPLE_OMP_TASK
:
10673 case GIMPLE_OMP_SECTIONS
:
10674 case GIMPLE_OMP_SINGLE
:
10675 case GIMPLE_OMP_SCOPE
:
10676 case GIMPLE_OMP_TARGET
:
10677 case GIMPLE_OMP_TEAMS
:
10678 case GIMPLE_OMP_CRITICAL
:
10679 *handled_ops_p
= true;
10687 struct gimplify_adjust_omp_clauses_data
10693 /* For all variables that were not actually used within the context,
10694 remove PRIVATE, SHARED, and FIRSTPRIVATE clauses. */
10697 gimplify_adjust_omp_clauses_1 (splay_tree_node n
, void *data
)
10699 tree
*list_p
= ((struct gimplify_adjust_omp_clauses_data
*) data
)->list_p
;
10701 = ((struct gimplify_adjust_omp_clauses_data
*) data
)->pre_p
;
10702 tree decl
= (tree
) n
->key
;
10703 unsigned flags
= n
->value
;
10704 enum omp_clause_code code
;
10706 bool private_debug
;
10708 if (gimplify_omp_ctxp
->region_type
== ORT_COMBINED_PARALLEL
10709 && (flags
& GOVD_LASTPRIVATE_CONDITIONAL
) != 0)
10710 flags
= GOVD_SHARED
| GOVD_SEEN
| GOVD_WRITTEN
;
10711 if (flags
& (GOVD_EXPLICIT
| GOVD_LOCAL
))
10713 if ((flags
& GOVD_SEEN
) == 0)
10715 if ((flags
& GOVD_MAP_HAS_ATTACHMENTS
) != 0)
10717 if (flags
& GOVD_DEBUG_PRIVATE
)
10719 gcc_assert ((flags
& GOVD_DATA_SHARE_CLASS
) == GOVD_SHARED
);
10720 private_debug
= true;
10722 else if (flags
& GOVD_MAP
)
10723 private_debug
= false;
10726 = lang_hooks
.decls
.omp_private_debug_clause (decl
,
10727 !!(flags
& GOVD_SHARED
));
10729 code
= OMP_CLAUSE_PRIVATE
;
10730 else if (flags
& GOVD_MAP
)
10732 code
= OMP_CLAUSE_MAP
;
10733 if ((gimplify_omp_ctxp
->region_type
& ORT_ACC
) == 0
10734 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl
))))
10736 error ("%<_Atomic%> %qD in implicit %<map%> clause", decl
);
10740 && DECL_IN_CONSTANT_POOL (decl
)
10741 && !lookup_attribute ("omp declare target",
10742 DECL_ATTRIBUTES (decl
)))
10744 tree id
= get_identifier ("omp declare target");
10745 DECL_ATTRIBUTES (decl
)
10746 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (decl
));
10747 varpool_node
*node
= varpool_node::get (decl
);
10750 node
->offloadable
= 1;
10751 if (ENABLE_OFFLOADING
)
10752 g
->have_offload
= true;
10756 else if (flags
& GOVD_SHARED
)
10758 if (is_global_var (decl
))
10760 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
->outer_context
;
10761 while (ctx
!= NULL
)
10764 = splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
10765 if (on
&& (on
->value
& (GOVD_FIRSTPRIVATE
| GOVD_LASTPRIVATE
10766 | GOVD_PRIVATE
| GOVD_REDUCTION
10767 | GOVD_LINEAR
| GOVD_MAP
)) != 0)
10769 ctx
= ctx
->outer_context
;
10774 code
= OMP_CLAUSE_SHARED
;
10775 /* Don't optimize shared into firstprivate for read-only vars
10776 on tasks with depend clause, we shouldn't try to copy them
10777 until the dependencies are satisfied. */
10778 if (gimplify_omp_ctxp
->has_depend
)
10779 flags
|= GOVD_WRITTEN
;
10781 else if (flags
& GOVD_PRIVATE
)
10782 code
= OMP_CLAUSE_PRIVATE
;
10783 else if (flags
& GOVD_FIRSTPRIVATE
)
10785 code
= OMP_CLAUSE_FIRSTPRIVATE
;
10786 if ((gimplify_omp_ctxp
->region_type
& ORT_TARGET
)
10787 && (gimplify_omp_ctxp
->region_type
& ORT_ACC
) == 0
10788 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl
))))
10790 error ("%<_Atomic%> %qD in implicit %<firstprivate%> clause on "
10791 "%<target%> construct", decl
);
10795 else if (flags
& GOVD_LASTPRIVATE
)
10796 code
= OMP_CLAUSE_LASTPRIVATE
;
10797 else if (flags
& (GOVD_ALIGNED
| GOVD_NONTEMPORAL
))
10799 else if (flags
& GOVD_CONDTEMP
)
10801 code
= OMP_CLAUSE__CONDTEMP_
;
10802 gimple_add_tmp_var (decl
);
10805 gcc_unreachable ();
10807 if (((flags
& GOVD_LASTPRIVATE
)
10808 || (code
== OMP_CLAUSE_SHARED
&& (flags
& GOVD_WRITTEN
)))
10809 && omp_shared_to_firstprivate_optimizable_decl_p (decl
))
10810 omp_mark_stores (gimplify_omp_ctxp
->outer_context
, decl
);
10812 tree chain
= *list_p
;
10813 clause
= build_omp_clause (input_location
, code
);
10814 OMP_CLAUSE_DECL (clause
) = decl
;
10815 OMP_CLAUSE_CHAIN (clause
) = chain
;
10817 OMP_CLAUSE_PRIVATE_DEBUG (clause
) = 1;
10818 else if (code
== OMP_CLAUSE_PRIVATE
&& (flags
& GOVD_PRIVATE_OUTER_REF
))
10819 OMP_CLAUSE_PRIVATE_OUTER_REF (clause
) = 1;
10820 else if (code
== OMP_CLAUSE_SHARED
10821 && (flags
& GOVD_WRITTEN
) == 0
10822 && omp_shared_to_firstprivate_optimizable_decl_p (decl
))
10823 OMP_CLAUSE_SHARED_READONLY (clause
) = 1;
10824 else if (code
== OMP_CLAUSE_FIRSTPRIVATE
&& (flags
& GOVD_EXPLICIT
) == 0)
10825 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (clause
) = 1;
10826 else if (code
== OMP_CLAUSE_MAP
&& (flags
& GOVD_MAP_0LEN_ARRAY
) != 0)
10828 tree nc
= build_omp_clause (input_location
, OMP_CLAUSE_MAP
);
10829 OMP_CLAUSE_DECL (nc
) = decl
;
10830 if (TREE_CODE (TREE_TYPE (decl
)) == REFERENCE_TYPE
10831 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl
))) == POINTER_TYPE
)
10832 OMP_CLAUSE_DECL (clause
)
10833 = build_simple_mem_ref_loc (input_location
, decl
);
10834 OMP_CLAUSE_DECL (clause
)
10835 = build2 (MEM_REF
, char_type_node
, OMP_CLAUSE_DECL (clause
),
10836 build_int_cst (build_pointer_type (char_type_node
), 0));
10837 OMP_CLAUSE_SIZE (clause
) = size_zero_node
;
10838 OMP_CLAUSE_SIZE (nc
) = size_zero_node
;
10839 OMP_CLAUSE_SET_MAP_KIND (clause
, GOMP_MAP_ALLOC
);
10840 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (clause
) = 1;
10841 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_FIRSTPRIVATE_POINTER
);
10842 OMP_CLAUSE_CHAIN (nc
) = chain
;
10843 OMP_CLAUSE_CHAIN (clause
) = nc
;
10844 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
10845 gimplify_omp_ctxp
= ctx
->outer_context
;
10846 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (clause
), 0),
10847 pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
10848 gimplify_omp_ctxp
= ctx
;
10850 else if (code
== OMP_CLAUSE_MAP
)
10853 /* Not all combinations of these GOVD_MAP flags are actually valid. */
10854 switch (flags
& (GOVD_MAP_TO_ONLY
10856 | GOVD_MAP_FORCE_PRESENT
10857 | GOVD_MAP_ALLOC_ONLY
10858 | GOVD_MAP_FROM_ONLY
))
10861 kind
= GOMP_MAP_TOFROM
;
10863 case GOVD_MAP_FORCE
:
10864 kind
= GOMP_MAP_TOFROM
| GOMP_MAP_FLAG_FORCE
;
10866 case GOVD_MAP_TO_ONLY
:
10867 kind
= GOMP_MAP_TO
;
10869 case GOVD_MAP_FROM_ONLY
:
10870 kind
= GOMP_MAP_FROM
;
10872 case GOVD_MAP_ALLOC_ONLY
:
10873 kind
= GOMP_MAP_ALLOC
;
10875 case GOVD_MAP_TO_ONLY
| GOVD_MAP_FORCE
:
10876 kind
= GOMP_MAP_TO
| GOMP_MAP_FLAG_FORCE
;
10878 case GOVD_MAP_FORCE_PRESENT
:
10879 kind
= GOMP_MAP_FORCE_PRESENT
;
10882 gcc_unreachable ();
10884 OMP_CLAUSE_SET_MAP_KIND (clause
, kind
);
10885 /* Setting of the implicit flag for the runtime is currently disabled for
10887 if ((gimplify_omp_ctxp
->region_type
& ORT_ACC
) == 0)
10888 OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (clause
) = 1;
10889 if (DECL_SIZE (decl
)
10890 && TREE_CODE (DECL_SIZE (decl
)) != INTEGER_CST
)
10892 tree decl2
= DECL_VALUE_EXPR (decl
);
10893 gcc_assert (TREE_CODE (decl2
) == INDIRECT_REF
);
10894 decl2
= TREE_OPERAND (decl2
, 0);
10895 gcc_assert (DECL_P (decl2
));
10896 tree mem
= build_simple_mem_ref (decl2
);
10897 OMP_CLAUSE_DECL (clause
) = mem
;
10898 OMP_CLAUSE_SIZE (clause
) = TYPE_SIZE_UNIT (TREE_TYPE (decl
));
10899 if (gimplify_omp_ctxp
->outer_context
)
10901 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
->outer_context
;
10902 omp_notice_variable (ctx
, decl2
, true);
10903 omp_notice_variable (ctx
, OMP_CLAUSE_SIZE (clause
), true);
10905 tree nc
= build_omp_clause (OMP_CLAUSE_LOCATION (clause
),
10907 OMP_CLAUSE_DECL (nc
) = decl
;
10908 OMP_CLAUSE_SIZE (nc
) = size_zero_node
;
10909 if (gimplify_omp_ctxp
->target_firstprivatize_array_bases
)
10910 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_FIRSTPRIVATE_POINTER
);
10912 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_POINTER
);
10913 OMP_CLAUSE_CHAIN (nc
) = OMP_CLAUSE_CHAIN (clause
);
10914 OMP_CLAUSE_CHAIN (clause
) = nc
;
10916 else if (gimplify_omp_ctxp
->target_firstprivatize_array_bases
10917 && omp_privatize_by_reference (decl
))
10919 OMP_CLAUSE_DECL (clause
) = build_simple_mem_ref (decl
);
10920 OMP_CLAUSE_SIZE (clause
)
10921 = unshare_expr (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl
))));
10922 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
10923 gimplify_omp_ctxp
= ctx
->outer_context
;
10924 gimplify_expr (&OMP_CLAUSE_SIZE (clause
),
10925 pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
10926 gimplify_omp_ctxp
= ctx
;
10927 tree nc
= build_omp_clause (OMP_CLAUSE_LOCATION (clause
),
10929 OMP_CLAUSE_DECL (nc
) = decl
;
10930 OMP_CLAUSE_SIZE (nc
) = size_zero_node
;
10931 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_FIRSTPRIVATE_REFERENCE
);
10932 OMP_CLAUSE_CHAIN (nc
) = OMP_CLAUSE_CHAIN (clause
);
10933 OMP_CLAUSE_CHAIN (clause
) = nc
;
10936 OMP_CLAUSE_SIZE (clause
) = DECL_SIZE_UNIT (decl
);
10938 if (code
== OMP_CLAUSE_FIRSTPRIVATE
&& (flags
& GOVD_LASTPRIVATE
) != 0)
10940 tree nc
= build_omp_clause (input_location
, OMP_CLAUSE_LASTPRIVATE
);
10941 OMP_CLAUSE_DECL (nc
) = decl
;
10942 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (nc
) = 1;
10943 OMP_CLAUSE_CHAIN (nc
) = chain
;
10944 OMP_CLAUSE_CHAIN (clause
) = nc
;
10945 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
10946 gimplify_omp_ctxp
= ctx
->outer_context
;
10947 lang_hooks
.decls
.omp_finish_clause (nc
, pre_p
,
10948 (ctx
->region_type
& ORT_ACC
) != 0);
10949 gimplify_omp_ctxp
= ctx
;
10952 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
10953 gimplify_omp_ctxp
= ctx
->outer_context
;
10954 /* Don't call omp_finish_clause on implicitly added OMP_CLAUSE_PRIVATE
10955 in simd. Those are only added for the local vars inside of simd body
10956 and they don't need to be e.g. default constructible. */
10957 if (code
!= OMP_CLAUSE_PRIVATE
|| ctx
->region_type
!= ORT_SIMD
)
10958 lang_hooks
.decls
.omp_finish_clause (clause
, pre_p
,
10959 (ctx
->region_type
& ORT_ACC
) != 0);
10960 if (gimplify_omp_ctxp
)
10961 for (; clause
!= chain
; clause
= OMP_CLAUSE_CHAIN (clause
))
10962 if (OMP_CLAUSE_CODE (clause
) == OMP_CLAUSE_MAP
10963 && DECL_P (OMP_CLAUSE_SIZE (clause
)))
10964 omp_notice_variable (gimplify_omp_ctxp
, OMP_CLAUSE_SIZE (clause
),
10966 gimplify_omp_ctxp
= ctx
;
10971 gimplify_adjust_omp_clauses (gimple_seq
*pre_p
, gimple_seq body
, tree
*list_p
,
10972 enum tree_code code
)
10974 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
10975 tree
*orig_list_p
= list_p
;
10977 bool has_inscan_reductions
= false;
10981 struct gimplify_omp_ctx
*octx
;
10982 for (octx
= ctx
; octx
; octx
= octx
->outer_context
)
10983 if ((octx
->region_type
& (ORT_PARALLEL
| ORT_TASK
| ORT_TEAMS
)) != 0)
10987 struct walk_stmt_info wi
;
10988 memset (&wi
, 0, sizeof (wi
));
10989 walk_gimple_seq (body
, omp_find_stores_stmt
,
10990 omp_find_stores_op
, &wi
);
10994 if (ctx
->add_safelen1
)
10996 /* If there are VLAs in the body of simd loop, prevent
10998 gcc_assert (ctx
->region_type
== ORT_SIMD
);
10999 c
= build_omp_clause (UNKNOWN_LOCATION
, OMP_CLAUSE_SAFELEN
);
11000 OMP_CLAUSE_SAFELEN_EXPR (c
) = integer_one_node
;
11001 OMP_CLAUSE_CHAIN (c
) = *list_p
;
11003 list_p
= &OMP_CLAUSE_CHAIN (c
);
11006 if (ctx
->region_type
== ORT_WORKSHARE
11007 && ctx
->outer_context
11008 && ctx
->outer_context
->region_type
== ORT_COMBINED_PARALLEL
)
11010 for (c
= ctx
->outer_context
->clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
11011 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
11012 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
))
11014 decl
= OMP_CLAUSE_DECL (c
);
11016 = splay_tree_lookup (ctx
->outer_context
->variables
,
11017 (splay_tree_key
) decl
);
11018 gcc_checking_assert (!splay_tree_lookup (ctx
->variables
,
11019 (splay_tree_key
) decl
));
11020 omp_add_variable (ctx
, decl
, n
->value
);
11021 tree c2
= copy_node (c
);
11022 OMP_CLAUSE_CHAIN (c2
) = *list_p
;
11024 if ((n
->value
& GOVD_FIRSTPRIVATE
) == 0)
11026 c2
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
11027 OMP_CLAUSE_FIRSTPRIVATE
);
11028 OMP_CLAUSE_DECL (c2
) = decl
;
11029 OMP_CLAUSE_CHAIN (c2
) = *list_p
;
11033 while ((c
= *list_p
) != NULL
)
11036 bool remove
= false;
11038 switch (OMP_CLAUSE_CODE (c
))
11040 case OMP_CLAUSE_FIRSTPRIVATE
:
11041 if ((ctx
->region_type
& ORT_TARGET
)
11042 && (ctx
->region_type
& ORT_ACC
) == 0
11043 && TYPE_ATOMIC (strip_array_types
11044 (TREE_TYPE (OMP_CLAUSE_DECL (c
)))))
11046 error_at (OMP_CLAUSE_LOCATION (c
),
11047 "%<_Atomic%> %qD in %<firstprivate%> clause on "
11048 "%<target%> construct", OMP_CLAUSE_DECL (c
));
11052 if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c
))
11054 decl
= OMP_CLAUSE_DECL (c
);
11055 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
11056 if ((n
->value
& GOVD_MAP
) != 0)
11061 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT_TARGET (c
) = 0;
11062 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c
) = 0;
11065 case OMP_CLAUSE_PRIVATE
:
11066 case OMP_CLAUSE_SHARED
:
11067 case OMP_CLAUSE_LINEAR
:
11068 decl
= OMP_CLAUSE_DECL (c
);
11069 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
11070 remove
= !(n
->value
& GOVD_SEEN
);
11071 if ((n
->value
& GOVD_LASTPRIVATE_CONDITIONAL
) != 0
11072 && code
== OMP_PARALLEL
11073 && OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_FIRSTPRIVATE
)
11077 bool shared
= OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_SHARED
;
11078 if ((n
->value
& GOVD_DEBUG_PRIVATE
)
11079 || lang_hooks
.decls
.omp_private_debug_clause (decl
, shared
))
11081 gcc_assert ((n
->value
& GOVD_DEBUG_PRIVATE
) == 0
11082 || ((n
->value
& GOVD_DATA_SHARE_CLASS
)
11084 OMP_CLAUSE_SET_CODE (c
, OMP_CLAUSE_PRIVATE
);
11085 OMP_CLAUSE_PRIVATE_DEBUG (c
) = 1;
11087 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_SHARED
11090 n
->value
|= GOVD_WRITTEN
;
11091 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_SHARED
11092 && (n
->value
& GOVD_WRITTEN
) == 0
11094 && omp_shared_to_firstprivate_optimizable_decl_p (decl
))
11095 OMP_CLAUSE_SHARED_READONLY (c
) = 1;
11096 else if (DECL_P (decl
)
11097 && ((OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_SHARED
11098 && (n
->value
& GOVD_WRITTEN
) != 0)
11099 || (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINEAR
11100 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c
)))
11101 && omp_shared_to_firstprivate_optimizable_decl_p (decl
))
11102 omp_mark_stores (gimplify_omp_ctxp
->outer_context
, decl
);
11105 n
->value
&= ~GOVD_EXPLICIT
;
11108 case OMP_CLAUSE_LASTPRIVATE
:
11109 /* Make sure OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE is set to
11110 accurately reflect the presence of a FIRSTPRIVATE clause. */
11111 decl
= OMP_CLAUSE_DECL (c
);
11112 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
11113 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
)
11114 = (n
->value
& GOVD_FIRSTPRIVATE
) != 0;
11115 if (code
== OMP_DISTRIBUTE
11116 && OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
))
11119 error_at (OMP_CLAUSE_LOCATION (c
),
11120 "same variable used in %<firstprivate%> and "
11121 "%<lastprivate%> clauses on %<distribute%> "
11125 && OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
11127 && omp_shared_to_firstprivate_optimizable_decl_p (decl
))
11128 omp_mark_stores (gimplify_omp_ctxp
->outer_context
, decl
);
11129 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
) && code
== OMP_PARALLEL
)
11133 case OMP_CLAUSE_ALIGNED
:
11134 decl
= OMP_CLAUSE_DECL (c
);
11135 if (!is_global_var (decl
))
11137 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
11138 remove
= n
== NULL
|| !(n
->value
& GOVD_SEEN
);
11139 if (!remove
&& TREE_CODE (TREE_TYPE (decl
)) == POINTER_TYPE
)
11141 struct gimplify_omp_ctx
*octx
;
11143 && (n
->value
& (GOVD_DATA_SHARE_CLASS
11144 & ~GOVD_FIRSTPRIVATE
)))
11147 for (octx
= ctx
->outer_context
; octx
;
11148 octx
= octx
->outer_context
)
11150 n
= splay_tree_lookup (octx
->variables
,
11151 (splay_tree_key
) decl
);
11154 if (n
->value
& GOVD_LOCAL
)
11156 /* We have to avoid assigning a shared variable
11157 to itself when trying to add
11158 __builtin_assume_aligned. */
11159 if (n
->value
& GOVD_SHARED
)
11167 else if (TREE_CODE (TREE_TYPE (decl
)) == ARRAY_TYPE
)
11169 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
11170 if (n
!= NULL
&& (n
->value
& GOVD_DATA_SHARE_CLASS
) != 0)
11175 case OMP_CLAUSE_NONTEMPORAL
:
11176 decl
= OMP_CLAUSE_DECL (c
);
11177 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
11178 remove
= n
== NULL
|| !(n
->value
& GOVD_SEEN
);
11181 case OMP_CLAUSE_MAP
:
11182 if (code
== OMP_TARGET_EXIT_DATA
11183 && OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ALWAYS_POINTER
)
11188 decl
= OMP_CLAUSE_DECL (c
);
11189 /* Data clauses associated with reductions must be
11190 compatible with present_or_copy. Warn and adjust the clause
11191 if that is not the case. */
11192 if (ctx
->region_type
== ORT_ACC_PARALLEL
11193 || ctx
->region_type
== ORT_ACC_SERIAL
)
11195 tree t
= DECL_P (decl
) ? decl
: TREE_OPERAND (decl
, 0);
11199 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) t
);
11201 if (n
&& (n
->value
& GOVD_REDUCTION
))
11203 enum gomp_map_kind kind
= OMP_CLAUSE_MAP_KIND (c
);
11205 OMP_CLAUSE_MAP_IN_REDUCTION (c
) = 1;
11206 if ((kind
& GOMP_MAP_TOFROM
) != GOMP_MAP_TOFROM
11207 && kind
!= GOMP_MAP_FORCE_PRESENT
11208 && kind
!= GOMP_MAP_POINTER
)
11210 warning_at (OMP_CLAUSE_LOCATION (c
), 0,
11211 "incompatible data clause with reduction "
11212 "on %qE; promoting to %<present_or_copy%>",
11214 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_TOFROM
);
11218 if (!DECL_P (decl
))
11220 if ((ctx
->region_type
& ORT_TARGET
) != 0
11221 && OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_FIRSTPRIVATE_POINTER
)
11223 if (TREE_CODE (decl
) == INDIRECT_REF
11224 && TREE_CODE (TREE_OPERAND (decl
, 0)) == COMPONENT_REF
11225 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl
, 0)))
11226 == REFERENCE_TYPE
))
11227 decl
= TREE_OPERAND (decl
, 0);
11228 if (TREE_CODE (decl
) == COMPONENT_REF
)
11230 while (TREE_CODE (decl
) == COMPONENT_REF
)
11231 decl
= TREE_OPERAND (decl
, 0);
11234 n
= splay_tree_lookup (ctx
->variables
,
11235 (splay_tree_key
) decl
);
11236 if (!(n
->value
& GOVD_SEEN
))
11243 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
11244 if ((ctx
->region_type
& ORT_TARGET
) != 0
11245 && !(n
->value
& GOVD_SEEN
)
11246 && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c
)) == 0
11247 && (!is_global_var (decl
)
11248 || !lookup_attribute ("omp declare target link",
11249 DECL_ATTRIBUTES (decl
))))
11252 /* For struct element mapping, if struct is never referenced
11253 in target block and none of the mapping has always modifier,
11254 remove all the struct element mappings, which immediately
11255 follow the GOMP_MAP_STRUCT map clause. */
11256 if (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_STRUCT
)
11258 HOST_WIDE_INT cnt
= tree_to_shwi (OMP_CLAUSE_SIZE (c
));
11260 OMP_CLAUSE_CHAIN (c
)
11261 = OMP_CLAUSE_CHAIN (OMP_CLAUSE_CHAIN (c
));
11264 else if (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_STRUCT
11265 && (code
== OMP_TARGET_EXIT_DATA
11266 || code
== OACC_EXIT_DATA
))
11268 else if (DECL_SIZE (decl
)
11269 && TREE_CODE (DECL_SIZE (decl
)) != INTEGER_CST
11270 && OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_POINTER
11271 && OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_FIRSTPRIVATE_POINTER
11272 && (OMP_CLAUSE_MAP_KIND (c
)
11273 != GOMP_MAP_FIRSTPRIVATE_REFERENCE
))
11275 /* For GOMP_MAP_FORCE_DEVICEPTR, we'll never enter here, because
11276 for these, TREE_CODE (DECL_SIZE (decl)) will always be
11278 gcc_assert (OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_FORCE_DEVICEPTR
);
11280 tree decl2
= DECL_VALUE_EXPR (decl
);
11281 gcc_assert (TREE_CODE (decl2
) == INDIRECT_REF
);
11282 decl2
= TREE_OPERAND (decl2
, 0);
11283 gcc_assert (DECL_P (decl2
));
11284 tree mem
= build_simple_mem_ref (decl2
);
11285 OMP_CLAUSE_DECL (c
) = mem
;
11286 OMP_CLAUSE_SIZE (c
) = TYPE_SIZE_UNIT (TREE_TYPE (decl
));
11287 if (ctx
->outer_context
)
11289 omp_notice_variable (ctx
->outer_context
, decl2
, true);
11290 omp_notice_variable (ctx
->outer_context
,
11291 OMP_CLAUSE_SIZE (c
), true);
11293 if (((ctx
->region_type
& ORT_TARGET
) != 0
11294 || !ctx
->target_firstprivatize_array_bases
)
11295 && ((n
->value
& GOVD_SEEN
) == 0
11296 || (n
->value
& (GOVD_PRIVATE
| GOVD_FIRSTPRIVATE
)) == 0))
11298 tree nc
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
11300 OMP_CLAUSE_DECL (nc
) = decl
;
11301 OMP_CLAUSE_SIZE (nc
) = size_zero_node
;
11302 if (ctx
->target_firstprivatize_array_bases
)
11303 OMP_CLAUSE_SET_MAP_KIND (nc
,
11304 GOMP_MAP_FIRSTPRIVATE_POINTER
);
11306 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_POINTER
);
11307 OMP_CLAUSE_CHAIN (nc
) = OMP_CLAUSE_CHAIN (c
);
11308 OMP_CLAUSE_CHAIN (c
) = nc
;
11314 if (OMP_CLAUSE_SIZE (c
) == NULL_TREE
)
11315 OMP_CLAUSE_SIZE (c
) = DECL_SIZE_UNIT (decl
);
11316 gcc_assert ((n
->value
& GOVD_SEEN
) == 0
11317 || ((n
->value
& (GOVD_PRIVATE
| GOVD_FIRSTPRIVATE
))
11322 case OMP_CLAUSE_TO
:
11323 case OMP_CLAUSE_FROM
:
11324 case OMP_CLAUSE__CACHE_
:
11325 decl
= OMP_CLAUSE_DECL (c
);
11326 if (!DECL_P (decl
))
11328 if (DECL_SIZE (decl
)
11329 && TREE_CODE (DECL_SIZE (decl
)) != INTEGER_CST
)
11331 tree decl2
= DECL_VALUE_EXPR (decl
);
11332 gcc_assert (TREE_CODE (decl2
) == INDIRECT_REF
);
11333 decl2
= TREE_OPERAND (decl2
, 0);
11334 gcc_assert (DECL_P (decl2
));
11335 tree mem
= build_simple_mem_ref (decl2
);
11336 OMP_CLAUSE_DECL (c
) = mem
;
11337 OMP_CLAUSE_SIZE (c
) = TYPE_SIZE_UNIT (TREE_TYPE (decl
));
11338 if (ctx
->outer_context
)
11340 omp_notice_variable (ctx
->outer_context
, decl2
, true);
11341 omp_notice_variable (ctx
->outer_context
,
11342 OMP_CLAUSE_SIZE (c
), true);
11345 else if (OMP_CLAUSE_SIZE (c
) == NULL_TREE
)
11346 OMP_CLAUSE_SIZE (c
) = DECL_SIZE_UNIT (decl
);
11349 case OMP_CLAUSE_REDUCTION
:
11350 if (OMP_CLAUSE_REDUCTION_INSCAN (c
))
11352 decl
= OMP_CLAUSE_DECL (c
);
11353 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
11354 if ((n
->value
& GOVD_REDUCTION_INSCAN
) == 0)
11357 error_at (OMP_CLAUSE_LOCATION (c
),
11358 "%qD specified in %<inscan%> %<reduction%> clause "
11359 "but not in %<scan%> directive clause", decl
);
11362 has_inscan_reductions
= true;
11365 case OMP_CLAUSE_IN_REDUCTION
:
11366 case OMP_CLAUSE_TASK_REDUCTION
:
11367 decl
= OMP_CLAUSE_DECL (c
);
11368 /* OpenACC reductions need a present_or_copy data clause.
11369 Add one if necessary. Emit error when the reduction is private. */
11370 if (ctx
->region_type
== ORT_ACC_PARALLEL
11371 || ctx
->region_type
== ORT_ACC_SERIAL
)
11373 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
11374 if (n
->value
& (GOVD_PRIVATE
| GOVD_FIRSTPRIVATE
))
11377 error_at (OMP_CLAUSE_LOCATION (c
), "invalid private "
11378 "reduction on %qE", DECL_NAME (decl
));
11380 else if ((n
->value
& GOVD_MAP
) == 0)
11382 tree next
= OMP_CLAUSE_CHAIN (c
);
11383 tree nc
= build_omp_clause (UNKNOWN_LOCATION
, OMP_CLAUSE_MAP
);
11384 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_TOFROM
);
11385 OMP_CLAUSE_DECL (nc
) = decl
;
11386 OMP_CLAUSE_CHAIN (c
) = nc
;
11387 lang_hooks
.decls
.omp_finish_clause (nc
, pre_p
,
11392 OMP_CLAUSE_MAP_IN_REDUCTION (nc
) = 1;
11393 if (OMP_CLAUSE_CHAIN (nc
) == NULL
)
11395 nc
= OMP_CLAUSE_CHAIN (nc
);
11397 OMP_CLAUSE_CHAIN (nc
) = next
;
11398 n
->value
|= GOVD_MAP
;
11402 && omp_shared_to_firstprivate_optimizable_decl_p (decl
))
11403 omp_mark_stores (gimplify_omp_ctxp
->outer_context
, decl
);
11406 case OMP_CLAUSE_ALLOCATE
:
11407 decl
= OMP_CLAUSE_DECL (c
);
11408 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
11409 if (n
!= NULL
&& !(n
->value
& GOVD_SEEN
))
11411 if ((n
->value
& (GOVD_PRIVATE
| GOVD_FIRSTPRIVATE
| GOVD_LINEAR
))
11413 && (n
->value
& (GOVD_REDUCTION
| GOVD_LASTPRIVATE
)) == 0)
11417 && OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
)
11418 && TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
)) != INTEGER_CST
11419 && ((ctx
->region_type
& (ORT_PARALLEL
| ORT_TARGET
)) != 0
11420 || (ctx
->region_type
& ORT_TASKLOOP
) == ORT_TASK
11421 || (ctx
->region_type
& ORT_HOST_TEAMS
) == ORT_HOST_TEAMS
))
11423 tree allocator
= OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
);
11424 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) allocator
);
11427 enum omp_clause_default_kind default_kind
11428 = ctx
->default_kind
;
11429 ctx
->default_kind
= OMP_CLAUSE_DEFAULT_FIRSTPRIVATE
;
11430 omp_notice_variable (ctx
, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
),
11432 ctx
->default_kind
= default_kind
;
11435 omp_notice_variable (ctx
, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
),
11440 case OMP_CLAUSE_COPYIN
:
11441 case OMP_CLAUSE_COPYPRIVATE
:
11442 case OMP_CLAUSE_IF
:
11443 case OMP_CLAUSE_NUM_THREADS
:
11444 case OMP_CLAUSE_NUM_TEAMS
:
11445 case OMP_CLAUSE_THREAD_LIMIT
:
11446 case OMP_CLAUSE_DIST_SCHEDULE
:
11447 case OMP_CLAUSE_DEVICE
:
11448 case OMP_CLAUSE_SCHEDULE
:
11449 case OMP_CLAUSE_NOWAIT
:
11450 case OMP_CLAUSE_ORDERED
:
11451 case OMP_CLAUSE_DEFAULT
:
11452 case OMP_CLAUSE_UNTIED
:
11453 case OMP_CLAUSE_COLLAPSE
:
11454 case OMP_CLAUSE_FINAL
:
11455 case OMP_CLAUSE_MERGEABLE
:
11456 case OMP_CLAUSE_PROC_BIND
:
11457 case OMP_CLAUSE_SAFELEN
:
11458 case OMP_CLAUSE_SIMDLEN
:
11459 case OMP_CLAUSE_DEPEND
:
11460 case OMP_CLAUSE_PRIORITY
:
11461 case OMP_CLAUSE_GRAINSIZE
:
11462 case OMP_CLAUSE_NUM_TASKS
:
11463 case OMP_CLAUSE_NOGROUP
:
11464 case OMP_CLAUSE_THREADS
:
11465 case OMP_CLAUSE_SIMD
:
11466 case OMP_CLAUSE_FILTER
:
11467 case OMP_CLAUSE_HINT
:
11468 case OMP_CLAUSE_DEFAULTMAP
:
11469 case OMP_CLAUSE_ORDER
:
11470 case OMP_CLAUSE_BIND
:
11471 case OMP_CLAUSE_DETACH
:
11472 case OMP_CLAUSE_USE_DEVICE_PTR
:
11473 case OMP_CLAUSE_USE_DEVICE_ADDR
:
11474 case OMP_CLAUSE_IS_DEVICE_PTR
:
11475 case OMP_CLAUSE_ASYNC
:
11476 case OMP_CLAUSE_WAIT
:
11477 case OMP_CLAUSE_INDEPENDENT
:
11478 case OMP_CLAUSE_NUM_GANGS
:
11479 case OMP_CLAUSE_NUM_WORKERS
:
11480 case OMP_CLAUSE_VECTOR_LENGTH
:
11481 case OMP_CLAUSE_GANG
:
11482 case OMP_CLAUSE_WORKER
:
11483 case OMP_CLAUSE_VECTOR
:
11484 case OMP_CLAUSE_AUTO
:
11485 case OMP_CLAUSE_SEQ
:
11486 case OMP_CLAUSE_TILE
:
11487 case OMP_CLAUSE_IF_PRESENT
:
11488 case OMP_CLAUSE_FINALIZE
:
11489 case OMP_CLAUSE_INCLUSIVE
:
11490 case OMP_CLAUSE_EXCLUSIVE
:
11493 case OMP_CLAUSE_NOHOST
:
11495 gcc_unreachable ();
11499 *list_p
= OMP_CLAUSE_CHAIN (c
);
11501 list_p
= &OMP_CLAUSE_CHAIN (c
);
11504 /* Add in any implicit data sharing. Implicit clauses are added at the start
11505 of the clause list, but after any non-map clauses. */
11506 struct gimplify_adjust_omp_clauses_data data
;
11507 tree
*implicit_add_list_p
= orig_list_p
;
11508 while (*implicit_add_list_p
11509 && OMP_CLAUSE_CODE (*implicit_add_list_p
) != OMP_CLAUSE_MAP
)
11510 implicit_add_list_p
= &OMP_CLAUSE_CHAIN (*implicit_add_list_p
);
11512 data
.list_p
= implicit_add_list_p
;
11513 data
.pre_p
= pre_p
;
11514 splay_tree_foreach (ctx
->variables
, gimplify_adjust_omp_clauses_1
, &data
);
11516 if (has_inscan_reductions
)
11517 for (c
= *orig_list_p
; c
; c
= OMP_CLAUSE_CHAIN (c
))
11518 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINEAR
11519 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c
))
11521 error_at (OMP_CLAUSE_LOCATION (c
),
11522 "%<inscan%> %<reduction%> clause used together with "
11523 "%<linear%> clause for a variable other than loop "
11528 gimplify_omp_ctxp
= ctx
->outer_context
;
11529 delete_omp_context (ctx
);
11532 /* Return 0 if CONSTRUCTS selectors don't match the OpenMP context,
11533 -1 if unknown yet (simd is involved, won't be known until vectorization)
11534 and 1 if they do. If SCORES is non-NULL, it should point to an array
11535 of at least 2*NCONSTRUCTS+2 ints, and will be filled with the positions
11536 of the CONSTRUCTS (position -1 if it will never match) followed by
11537 number of constructs in the OpenMP context construct trait. If the
11538 score depends on whether it will be in a declare simd clone or not,
11539 the function returns 2 and there will be two sets of the scores, the first
11540 one for the case that it is not in a declare simd clone, the other
11541 that it is in a declare simd clone. */
11544 omp_construct_selector_matches (enum tree_code
*constructs
, int nconstructs
,
11547 int matched
= 0, cnt
= 0;
11548 bool simd_seen
= false;
11549 bool target_seen
= false;
11550 int declare_simd_cnt
= -1;
11551 auto_vec
<enum tree_code
, 16> codes
;
11552 for (struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
; ctx
;)
11554 if (((ctx
->region_type
& ORT_PARALLEL
) && ctx
->code
== OMP_PARALLEL
)
11555 || ((ctx
->region_type
& (ORT_TARGET
| ORT_IMPLICIT_TARGET
| ORT_ACC
))
11556 == ORT_TARGET
&& ctx
->code
== OMP_TARGET
)
11557 || ((ctx
->region_type
& ORT_TEAMS
) && ctx
->code
== OMP_TEAMS
)
11558 || (ctx
->region_type
== ORT_WORKSHARE
&& ctx
->code
== OMP_FOR
)
11559 || (ctx
->region_type
== ORT_SIMD
11560 && ctx
->code
== OMP_SIMD
11561 && !omp_find_clause (ctx
->clauses
, OMP_CLAUSE_BIND
)))
11565 codes
.safe_push (ctx
->code
);
11566 else if (matched
< nconstructs
&& ctx
->code
== constructs
[matched
])
11568 if (ctx
->code
== OMP_SIMD
)
11576 if (ctx
->code
== OMP_TARGET
)
11578 if (scores
== NULL
)
11579 return matched
< nconstructs
? 0 : simd_seen
? -1 : 1;
11580 target_seen
= true;
11584 else if (ctx
->region_type
== ORT_WORKSHARE
11585 && ctx
->code
== OMP_LOOP
11586 && ctx
->outer_context
11587 && ctx
->outer_context
->region_type
== ORT_COMBINED_PARALLEL
11588 && ctx
->outer_context
->outer_context
11589 && ctx
->outer_context
->outer_context
->code
== OMP_LOOP
11590 && ctx
->outer_context
->outer_context
->distribute
)
11591 ctx
= ctx
->outer_context
->outer_context
;
11592 ctx
= ctx
->outer_context
;
11595 && lookup_attribute ("omp declare simd",
11596 DECL_ATTRIBUTES (current_function_decl
)))
11598 /* Declare simd is a maybe case, it is supposed to be added only to the
11599 omp-simd-clone.c added clones and not to the base function. */
11600 declare_simd_cnt
= cnt
++;
11602 codes
.safe_push (OMP_SIMD
);
11604 && constructs
[0] == OMP_SIMD
)
11606 gcc_assert (matched
== 0);
11608 if (++matched
== nconstructs
)
11612 if (tree attr
= lookup_attribute ("omp declare variant variant",
11613 DECL_ATTRIBUTES (current_function_decl
)))
11615 enum tree_code variant_constructs
[5];
11616 int variant_nconstructs
= 0;
11618 variant_nconstructs
11619 = omp_constructor_traits_to_codes (TREE_VALUE (attr
),
11620 variant_constructs
);
11621 for (int i
= 0; i
< variant_nconstructs
; i
++)
11625 codes
.safe_push (variant_constructs
[i
]);
11626 else if (matched
< nconstructs
11627 && variant_constructs
[i
] == constructs
[matched
])
11629 if (variant_constructs
[i
] == OMP_SIMD
)
11640 && lookup_attribute ("omp declare target block",
11641 DECL_ATTRIBUTES (current_function_decl
)))
11644 codes
.safe_push (OMP_TARGET
);
11645 else if (matched
< nconstructs
&& constructs
[matched
] == OMP_TARGET
)
11650 for (int pass
= 0; pass
< (declare_simd_cnt
== -1 ? 1 : 2); pass
++)
11652 int j
= codes
.length () - 1;
11653 for (int i
= nconstructs
- 1; i
>= 0; i
--)
11656 && (pass
!= 0 || declare_simd_cnt
!= j
)
11657 && constructs
[i
] != codes
[j
])
11659 if (pass
== 0 && declare_simd_cnt
!= -1 && j
> declare_simd_cnt
)
11664 *scores
++ = ((pass
== 0 && declare_simd_cnt
!= -1)
11665 ? codes
.length () - 1 : codes
.length ());
11667 return declare_simd_cnt
== -1 ? 1 : 2;
11669 if (matched
== nconstructs
)
11670 return simd_seen
? -1 : 1;
11674 /* Gimplify OACC_CACHE. */
11677 gimplify_oacc_cache (tree
*expr_p
, gimple_seq
*pre_p
)
11679 tree expr
= *expr_p
;
11681 gimplify_scan_omp_clauses (&OACC_CACHE_CLAUSES (expr
), pre_p
, ORT_ACC
,
11683 gimplify_adjust_omp_clauses (pre_p
, NULL
, &OACC_CACHE_CLAUSES (expr
),
11686 /* TODO: Do something sensible with this information. */
11688 *expr_p
= NULL_TREE
;
11691 /* Helper function of gimplify_oacc_declare. The helper's purpose is to,
11692 if required, translate 'kind' in CLAUSE into an 'entry' kind and 'exit'
11693 kind. The entry kind will replace the one in CLAUSE, while the exit
11694 kind will be used in a new omp_clause and returned to the caller. */
11697 gimplify_oacc_declare_1 (tree clause
)
11699 HOST_WIDE_INT kind
, new_op
;
11703 kind
= OMP_CLAUSE_MAP_KIND (clause
);
11707 case GOMP_MAP_ALLOC
:
11708 new_op
= GOMP_MAP_RELEASE
;
11712 case GOMP_MAP_FROM
:
11713 OMP_CLAUSE_SET_MAP_KIND (clause
, GOMP_MAP_FORCE_ALLOC
);
11714 new_op
= GOMP_MAP_FROM
;
11718 case GOMP_MAP_TOFROM
:
11719 OMP_CLAUSE_SET_MAP_KIND (clause
, GOMP_MAP_TO
);
11720 new_op
= GOMP_MAP_FROM
;
11724 case GOMP_MAP_DEVICE_RESIDENT
:
11725 case GOMP_MAP_FORCE_DEVICEPTR
:
11726 case GOMP_MAP_FORCE_PRESENT
:
11727 case GOMP_MAP_LINK
:
11728 case GOMP_MAP_POINTER
:
11733 gcc_unreachable ();
11739 c
= build_omp_clause (OMP_CLAUSE_LOCATION (clause
), OMP_CLAUSE_MAP
);
11740 OMP_CLAUSE_SET_MAP_KIND (c
, new_op
);
11741 OMP_CLAUSE_DECL (c
) = OMP_CLAUSE_DECL (clause
);
11747 /* Gimplify OACC_DECLARE. */
11750 gimplify_oacc_declare (tree
*expr_p
, gimple_seq
*pre_p
)
11752 tree expr
= *expr_p
;
11754 tree clauses
, t
, decl
;
11756 clauses
= OACC_DECLARE_CLAUSES (expr
);
11758 gimplify_scan_omp_clauses (&clauses
, pre_p
, ORT_TARGET_DATA
, OACC_DECLARE
);
11759 gimplify_adjust_omp_clauses (pre_p
, NULL
, &clauses
, OACC_DECLARE
);
11761 for (t
= clauses
; t
; t
= OMP_CLAUSE_CHAIN (t
))
11763 decl
= OMP_CLAUSE_DECL (t
);
11765 if (TREE_CODE (decl
) == MEM_REF
)
11766 decl
= TREE_OPERAND (decl
, 0);
11768 if (VAR_P (decl
) && !is_oacc_declared (decl
))
11770 tree attr
= get_identifier ("oacc declare target");
11771 DECL_ATTRIBUTES (decl
) = tree_cons (attr
, NULL_TREE
,
11772 DECL_ATTRIBUTES (decl
));
11776 && !is_global_var (decl
)
11777 && DECL_CONTEXT (decl
) == current_function_decl
)
11779 tree c
= gimplify_oacc_declare_1 (t
);
11782 if (oacc_declare_returns
== NULL
)
11783 oacc_declare_returns
= new hash_map
<tree
, tree
>;
11785 oacc_declare_returns
->put (decl
, c
);
11789 if (gimplify_omp_ctxp
)
11790 omp_add_variable (gimplify_omp_ctxp
, decl
, GOVD_SEEN
);
11793 stmt
= gimple_build_omp_target (NULL
, GF_OMP_TARGET_KIND_OACC_DECLARE
,
11796 gimplify_seq_add_stmt (pre_p
, stmt
);
11798 *expr_p
= NULL_TREE
;
11801 /* Gimplify the contents of an OMP_PARALLEL statement. This involves
11802 gimplification of the body, as well as scanning the body for used
11803 variables. We need to do this scan now, because variable-sized
11804 decls will be decomposed during gimplification. */
11807 gimplify_omp_parallel (tree
*expr_p
, gimple_seq
*pre_p
)
11809 tree expr
= *expr_p
;
11811 gimple_seq body
= NULL
;
11813 gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr
), pre_p
,
11814 OMP_PARALLEL_COMBINED (expr
)
11815 ? ORT_COMBINED_PARALLEL
11816 : ORT_PARALLEL
, OMP_PARALLEL
);
11818 push_gimplify_context ();
11820 g
= gimplify_and_return_first (OMP_PARALLEL_BODY (expr
), &body
);
11821 if (gimple_code (g
) == GIMPLE_BIND
)
11822 pop_gimplify_context (g
);
11824 pop_gimplify_context (NULL
);
11826 gimplify_adjust_omp_clauses (pre_p
, body
, &OMP_PARALLEL_CLAUSES (expr
),
11829 g
= gimple_build_omp_parallel (body
,
11830 OMP_PARALLEL_CLAUSES (expr
),
11831 NULL_TREE
, NULL_TREE
);
11832 if (OMP_PARALLEL_COMBINED (expr
))
11833 gimple_omp_set_subcode (g
, GF_OMP_PARALLEL_COMBINED
);
11834 gimplify_seq_add_stmt (pre_p
, g
);
11835 *expr_p
= NULL_TREE
;
11838 /* Gimplify the contents of an OMP_TASK statement. This involves
11839 gimplification of the body, as well as scanning the body for used
11840 variables. We need to do this scan now, because variable-sized
11841 decls will be decomposed during gimplification. */
11844 gimplify_omp_task (tree
*expr_p
, gimple_seq
*pre_p
)
11846 tree expr
= *expr_p
;
11848 gimple_seq body
= NULL
;
11850 if (OMP_TASK_BODY (expr
) == NULL_TREE
)
11851 for (tree c
= OMP_TASK_CLAUSES (expr
); c
; c
= OMP_CLAUSE_CHAIN (c
))
11852 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEPEND
11853 && OMP_CLAUSE_DEPEND_KIND (c
) == OMP_CLAUSE_DEPEND_MUTEXINOUTSET
)
11855 error_at (OMP_CLAUSE_LOCATION (c
),
11856 "%<mutexinoutset%> kind in %<depend%> clause on a "
11857 "%<taskwait%> construct");
11861 gimplify_scan_omp_clauses (&OMP_TASK_CLAUSES (expr
), pre_p
,
11862 omp_find_clause (OMP_TASK_CLAUSES (expr
),
11864 ? ORT_UNTIED_TASK
: ORT_TASK
, OMP_TASK
);
11866 if (OMP_TASK_BODY (expr
))
11868 push_gimplify_context ();
11870 g
= gimplify_and_return_first (OMP_TASK_BODY (expr
), &body
);
11871 if (gimple_code (g
) == GIMPLE_BIND
)
11872 pop_gimplify_context (g
);
11874 pop_gimplify_context (NULL
);
11877 gimplify_adjust_omp_clauses (pre_p
, body
, &OMP_TASK_CLAUSES (expr
),
11880 g
= gimple_build_omp_task (body
,
11881 OMP_TASK_CLAUSES (expr
),
11882 NULL_TREE
, NULL_TREE
,
11883 NULL_TREE
, NULL_TREE
, NULL_TREE
);
11884 if (OMP_TASK_BODY (expr
) == NULL_TREE
)
11885 gimple_omp_task_set_taskwait_p (g
, true);
11886 gimplify_seq_add_stmt (pre_p
, g
);
11887 *expr_p
= NULL_TREE
;
11890 /* Helper function for gimplify_omp_for. If *TP is not a gimple constant,
11891 force it into a temporary initialized in PRE_P and add firstprivate clause
11892 to ORIG_FOR_STMT. */
11895 gimplify_omp_taskloop_expr (tree type
, tree
*tp
, gimple_seq
*pre_p
,
11896 tree orig_for_stmt
)
11898 if (*tp
== NULL
|| is_gimple_constant (*tp
))
11901 *tp
= get_initialized_tmp_var (*tp
, pre_p
, NULL
, false);
11902 /* Reference to pointer conversion is considered useless,
11903 but is significant for firstprivate clause. Force it
11906 && TREE_CODE (type
) == POINTER_TYPE
11907 && TREE_CODE (TREE_TYPE (*tp
)) == REFERENCE_TYPE
)
11909 tree v
= create_tmp_var (TYPE_MAIN_VARIANT (type
));
11910 tree m
= build2 (INIT_EXPR
, TREE_TYPE (v
), v
, *tp
);
11911 gimplify_and_add (m
, pre_p
);
11915 tree c
= build_omp_clause (input_location
, OMP_CLAUSE_FIRSTPRIVATE
);
11916 OMP_CLAUSE_DECL (c
) = *tp
;
11917 OMP_CLAUSE_CHAIN (c
) = OMP_FOR_CLAUSES (orig_for_stmt
);
11918 OMP_FOR_CLAUSES (orig_for_stmt
) = c
;
11921 /* Gimplify the gross structure of an OMP_FOR statement. */
11923 static enum gimplify_status
11924 gimplify_omp_for (tree
*expr_p
, gimple_seq
*pre_p
)
11926 tree for_stmt
, orig_for_stmt
, inner_for_stmt
= NULL_TREE
, decl
, var
, t
;
11927 enum gimplify_status ret
= GS_ALL_DONE
;
11928 enum gimplify_status tret
;
11930 gimple_seq for_body
, for_pre_body
;
11932 bitmap has_decl_expr
= NULL
;
11933 enum omp_region_type ort
= ORT_WORKSHARE
;
11934 bool openacc
= TREE_CODE (*expr_p
) == OACC_LOOP
;
11936 orig_for_stmt
= for_stmt
= *expr_p
;
11938 bool loop_p
= (omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_BIND
)
11940 if (OMP_FOR_INIT (for_stmt
) == NULL_TREE
)
11942 tree
*data
[4] = { NULL
, NULL
, NULL
, NULL
};
11943 gcc_assert (TREE_CODE (for_stmt
) != OACC_LOOP
);
11944 inner_for_stmt
= walk_tree (&OMP_FOR_BODY (for_stmt
),
11945 find_combined_omp_for
, data
, NULL
);
11946 if (inner_for_stmt
== NULL_TREE
)
11948 gcc_assert (seen_error ());
11949 *expr_p
= NULL_TREE
;
11952 if (data
[2] && OMP_FOR_PRE_BODY (*data
[2]))
11954 append_to_statement_list_force (OMP_FOR_PRE_BODY (*data
[2]),
11955 &OMP_FOR_PRE_BODY (for_stmt
));
11956 OMP_FOR_PRE_BODY (*data
[2]) = NULL_TREE
;
11958 if (OMP_FOR_PRE_BODY (inner_for_stmt
))
11960 append_to_statement_list_force (OMP_FOR_PRE_BODY (inner_for_stmt
),
11961 &OMP_FOR_PRE_BODY (for_stmt
));
11962 OMP_FOR_PRE_BODY (inner_for_stmt
) = NULL_TREE
;
11967 /* We have some statements or variable declarations in between
11968 the composite construct directives. Move them around the
11971 for (i
= 0; i
< 3; i
++)
11975 if (i
< 2 && data
[i
+ 1] == &OMP_BODY (t
))
11976 data
[i
+ 1] = data
[i
];
11977 *data
[i
] = OMP_BODY (t
);
11978 tree body
= build3 (BIND_EXPR
, void_type_node
, NULL_TREE
,
11979 NULL_TREE
, make_node (BLOCK
));
11980 OMP_BODY (t
) = body
;
11981 append_to_statement_list_force (inner_for_stmt
,
11982 &BIND_EXPR_BODY (body
));
11984 data
[3] = tsi_stmt_ptr (tsi_start (BIND_EXPR_BODY (body
)));
11985 gcc_assert (*data
[3] == inner_for_stmt
);
11990 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt
)); i
++)
11992 && OMP_FOR_ORIG_DECLS (inner_for_stmt
)
11993 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
),
11995 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
),
11998 tree orig
= TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
), i
);
11999 /* Class iterators aren't allowed on OMP_SIMD, so the only
12000 case we need to solve is distribute parallel for. They are
12001 allowed on the loop construct, but that is already handled
12002 in gimplify_omp_loop. */
12003 gcc_assert (TREE_CODE (inner_for_stmt
) == OMP_FOR
12004 && TREE_CODE (for_stmt
) == OMP_DISTRIBUTE
12006 tree orig_decl
= TREE_PURPOSE (orig
);
12007 tree last
= TREE_VALUE (orig
);
12009 for (pc
= &OMP_FOR_CLAUSES (inner_for_stmt
);
12010 *pc
; pc
= &OMP_CLAUSE_CHAIN (*pc
))
12011 if ((OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_PRIVATE
12012 || OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_LASTPRIVATE
)
12013 && OMP_CLAUSE_DECL (*pc
) == orig_decl
)
12015 if (*pc
== NULL_TREE
)
12018 for (spc
= &OMP_PARALLEL_CLAUSES (*data
[1]);
12019 *spc
; spc
= &OMP_CLAUSE_CHAIN (*spc
))
12020 if (OMP_CLAUSE_CODE (*spc
) == OMP_CLAUSE_PRIVATE
12021 && OMP_CLAUSE_DECL (*spc
) == orig_decl
)
12026 *spc
= OMP_CLAUSE_CHAIN (c
);
12027 OMP_CLAUSE_CHAIN (c
) = NULL_TREE
;
12031 if (*pc
== NULL_TREE
)
12033 else if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_PRIVATE
)
12035 /* private clause will appear only on inner_for_stmt.
12036 Change it into firstprivate, and add private clause
12038 tree c
= copy_node (*pc
);
12039 OMP_CLAUSE_CHAIN (c
) = OMP_FOR_CLAUSES (for_stmt
);
12040 OMP_FOR_CLAUSES (for_stmt
) = c
;
12041 OMP_CLAUSE_CODE (*pc
) = OMP_CLAUSE_FIRSTPRIVATE
;
12042 lang_hooks
.decls
.omp_finish_clause (*pc
, pre_p
, openacc
);
12046 /* lastprivate clause will appear on both inner_for_stmt
12047 and for_stmt. Add firstprivate clause to
12049 tree c
= build_omp_clause (OMP_CLAUSE_LOCATION (*pc
),
12050 OMP_CLAUSE_FIRSTPRIVATE
);
12051 OMP_CLAUSE_DECL (c
) = OMP_CLAUSE_DECL (*pc
);
12052 OMP_CLAUSE_CHAIN (c
) = *pc
;
12054 lang_hooks
.decls
.omp_finish_clause (*pc
, pre_p
, openacc
);
12056 tree c
= build_omp_clause (UNKNOWN_LOCATION
,
12057 OMP_CLAUSE_FIRSTPRIVATE
);
12058 OMP_CLAUSE_DECL (c
) = last
;
12059 OMP_CLAUSE_CHAIN (c
) = OMP_PARALLEL_CLAUSES (*data
[1]);
12060 OMP_PARALLEL_CLAUSES (*data
[1]) = c
;
12061 c
= build_omp_clause (UNKNOWN_LOCATION
,
12062 *pc
? OMP_CLAUSE_SHARED
12063 : OMP_CLAUSE_FIRSTPRIVATE
);
12064 OMP_CLAUSE_DECL (c
) = orig_decl
;
12065 OMP_CLAUSE_CHAIN (c
) = OMP_PARALLEL_CLAUSES (*data
[1]);
12066 OMP_PARALLEL_CLAUSES (*data
[1]) = c
;
12068 /* Similarly, take care of C++ range for temporaries, those should
12069 be firstprivate on OMP_PARALLEL if any. */
12071 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt
)); i
++)
12072 if (OMP_FOR_ORIG_DECLS (inner_for_stmt
)
12073 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
),
12075 && TREE_CHAIN (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
),
12079 = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
), i
);
12080 tree v
= TREE_CHAIN (orig
);
12081 tree c
= build_omp_clause (UNKNOWN_LOCATION
,
12082 OMP_CLAUSE_FIRSTPRIVATE
);
12083 /* First add firstprivate clause for the __for_end artificial
12085 OMP_CLAUSE_DECL (c
) = TREE_VEC_ELT (v
, 1);
12086 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c
)))
12088 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c
) = 1;
12089 OMP_CLAUSE_CHAIN (c
) = OMP_PARALLEL_CLAUSES (*data
[1]);
12090 OMP_PARALLEL_CLAUSES (*data
[1]) = c
;
12091 if (TREE_VEC_ELT (v
, 0))
12093 /* And now the same for __for_range artificial decl if it
12095 c
= build_omp_clause (UNKNOWN_LOCATION
,
12096 OMP_CLAUSE_FIRSTPRIVATE
);
12097 OMP_CLAUSE_DECL (c
) = TREE_VEC_ELT (v
, 0);
12098 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c
)))
12100 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c
) = 1;
12101 OMP_CLAUSE_CHAIN (c
) = OMP_PARALLEL_CLAUSES (*data
[1]);
12102 OMP_PARALLEL_CLAUSES (*data
[1]) = c
;
12107 switch (TREE_CODE (for_stmt
))
12110 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt
? inner_for_stmt
: for_stmt
))
12112 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt
),
12113 OMP_CLAUSE_SCHEDULE
))
12114 error_at (EXPR_LOCATION (for_stmt
),
12115 "%qs clause may not appear on non-rectangular %qs",
12116 "schedule", "for");
12117 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_ORDERED
))
12118 error_at (EXPR_LOCATION (for_stmt
),
12119 "%qs clause may not appear on non-rectangular %qs",
12123 case OMP_DISTRIBUTE
:
12124 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt
? inner_for_stmt
: for_stmt
)
12125 && omp_find_clause (OMP_FOR_CLAUSES (for_stmt
),
12126 OMP_CLAUSE_DIST_SCHEDULE
))
12127 error_at (EXPR_LOCATION (for_stmt
),
12128 "%qs clause may not appear on non-rectangular %qs",
12129 "dist_schedule", "distribute");
12135 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_UNTIED
))
12136 ort
= ORT_UNTIED_TASKLOOP
;
12138 ort
= ORT_TASKLOOP
;
12144 gcc_unreachable ();
12147 /* Set OMP_CLAUSE_LINEAR_NO_COPYIN flag on explicit linear
12148 clause for the IV. */
12149 if (ort
== ORT_SIMD
&& TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)) == 1)
12151 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), 0);
12152 gcc_assert (TREE_CODE (t
) == MODIFY_EXPR
);
12153 decl
= TREE_OPERAND (t
, 0);
12154 for (tree c
= OMP_FOR_CLAUSES (for_stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
12155 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINEAR
12156 && OMP_CLAUSE_DECL (c
) == decl
)
12158 OMP_CLAUSE_LINEAR_NO_COPYIN (c
) = 1;
12163 if (TREE_CODE (for_stmt
) != OMP_TASKLOOP
)
12164 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt
), pre_p
, ort
,
12165 loop_p
&& TREE_CODE (for_stmt
) != OMP_SIMD
12166 ? OMP_LOOP
: TREE_CODE (for_stmt
));
12168 if (TREE_CODE (for_stmt
) == OMP_DISTRIBUTE
)
12169 gimplify_omp_ctxp
->distribute
= true;
12171 /* Handle OMP_FOR_INIT. */
12172 for_pre_body
= NULL
;
12173 if ((ort
== ORT_SIMD
12174 || (inner_for_stmt
&& TREE_CODE (inner_for_stmt
) == OMP_SIMD
))
12175 && OMP_FOR_PRE_BODY (for_stmt
))
12177 has_decl_expr
= BITMAP_ALLOC (NULL
);
12178 if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt
)) == DECL_EXPR
12179 && TREE_CODE (DECL_EXPR_DECL (OMP_FOR_PRE_BODY (for_stmt
)))
12182 t
= OMP_FOR_PRE_BODY (for_stmt
);
12183 bitmap_set_bit (has_decl_expr
, DECL_UID (DECL_EXPR_DECL (t
)));
12185 else if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt
)) == STATEMENT_LIST
)
12187 tree_stmt_iterator si
;
12188 for (si
= tsi_start (OMP_FOR_PRE_BODY (for_stmt
)); !tsi_end_p (si
);
12192 if (TREE_CODE (t
) == DECL_EXPR
12193 && TREE_CODE (DECL_EXPR_DECL (t
)) == VAR_DECL
)
12194 bitmap_set_bit (has_decl_expr
, DECL_UID (DECL_EXPR_DECL (t
)));
12198 if (OMP_FOR_PRE_BODY (for_stmt
))
12200 if (TREE_CODE (for_stmt
) != OMP_TASKLOOP
|| gimplify_omp_ctxp
)
12201 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt
), &for_pre_body
);
12204 struct gimplify_omp_ctx ctx
;
12205 memset (&ctx
, 0, sizeof (ctx
));
12206 ctx
.region_type
= ORT_NONE
;
12207 gimplify_omp_ctxp
= &ctx
;
12208 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt
), &for_pre_body
);
12209 gimplify_omp_ctxp
= NULL
;
12212 OMP_FOR_PRE_BODY (for_stmt
) = NULL_TREE
;
12214 if (OMP_FOR_INIT (for_stmt
) == NULL_TREE
)
12215 for_stmt
= inner_for_stmt
;
12217 /* For taskloop, need to gimplify the start, end and step before the
12218 taskloop, outside of the taskloop omp context. */
12219 if (TREE_CODE (orig_for_stmt
) == OMP_TASKLOOP
)
12221 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
12223 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), i
);
12224 gimple_seq
*for_pre_p
= (gimple_seq_empty_p (for_pre_body
)
12225 ? pre_p
: &for_pre_body
);
12226 tree type
= TREE_TYPE (TREE_OPERAND (t
, 0));
12227 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
)
12229 tree v
= TREE_OPERAND (t
, 1);
12230 gimplify_omp_taskloop_expr (type
, &TREE_VEC_ELT (v
, 1),
12231 for_pre_p
, orig_for_stmt
);
12232 gimplify_omp_taskloop_expr (type
, &TREE_VEC_ELT (v
, 2),
12233 for_pre_p
, orig_for_stmt
);
12236 gimplify_omp_taskloop_expr (type
, &TREE_OPERAND (t
, 1), for_pre_p
,
12239 /* Handle OMP_FOR_COND. */
12240 t
= TREE_VEC_ELT (OMP_FOR_COND (for_stmt
), i
);
12241 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
)
12243 tree v
= TREE_OPERAND (t
, 1);
12244 gimplify_omp_taskloop_expr (type
, &TREE_VEC_ELT (v
, 1),
12245 for_pre_p
, orig_for_stmt
);
12246 gimplify_omp_taskloop_expr (type
, &TREE_VEC_ELT (v
, 2),
12247 for_pre_p
, orig_for_stmt
);
12250 gimplify_omp_taskloop_expr (type
, &TREE_OPERAND (t
, 1), for_pre_p
,
12253 /* Handle OMP_FOR_INCR. */
12254 t
= TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
);
12255 if (TREE_CODE (t
) == MODIFY_EXPR
)
12257 decl
= TREE_OPERAND (t
, 0);
12258 t
= TREE_OPERAND (t
, 1);
12259 tree
*tp
= &TREE_OPERAND (t
, 1);
12260 if (TREE_CODE (t
) == PLUS_EXPR
&& *tp
== decl
)
12261 tp
= &TREE_OPERAND (t
, 0);
12263 gimplify_omp_taskloop_expr (NULL_TREE
, tp
, for_pre_p
,
12268 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (orig_for_stmt
), pre_p
, ort
,
12272 if (orig_for_stmt
!= for_stmt
)
12273 gimplify_omp_ctxp
->combined_loop
= true;
12276 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
))
12277 == TREE_VEC_LENGTH (OMP_FOR_COND (for_stmt
)));
12278 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
))
12279 == TREE_VEC_LENGTH (OMP_FOR_INCR (for_stmt
)));
12281 tree c
= omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_ORDERED
);
12282 bool is_doacross
= false;
12283 if (c
&& OMP_CLAUSE_ORDERED_EXPR (c
))
12285 is_doacross
= true;
12286 gimplify_omp_ctxp
->loop_iter_var
.create (TREE_VEC_LENGTH
12287 (OMP_FOR_INIT (for_stmt
))
12290 int collapse
= 1, tile
= 0;
12291 c
= omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_COLLAPSE
);
12293 collapse
= tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (c
));
12294 c
= omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_TILE
);
12296 tile
= list_length (OMP_CLAUSE_TILE_LIST (c
));
12297 c
= omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_ALLOCATE
);
12298 hash_set
<tree
> *allocate_uids
= NULL
;
12301 allocate_uids
= new hash_set
<tree
>;
12302 for (; c
; c
= OMP_CLAUSE_CHAIN (c
))
12303 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_ALLOCATE
)
12304 allocate_uids
->add (OMP_CLAUSE_DECL (c
));
12306 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
12308 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), i
);
12309 gcc_assert (TREE_CODE (t
) == MODIFY_EXPR
);
12310 decl
= TREE_OPERAND (t
, 0);
12311 gcc_assert (DECL_P (decl
));
12312 gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl
))
12313 || POINTER_TYPE_P (TREE_TYPE (decl
)));
12316 if (TREE_CODE (for_stmt
) == OMP_FOR
&& OMP_FOR_ORIG_DECLS (for_stmt
))
12318 tree orig_decl
= TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
), i
);
12319 if (TREE_CODE (orig_decl
) == TREE_LIST
)
12321 orig_decl
= TREE_PURPOSE (orig_decl
);
12325 gimplify_omp_ctxp
->loop_iter_var
.quick_push (orig_decl
);
12328 gimplify_omp_ctxp
->loop_iter_var
.quick_push (decl
);
12329 gimplify_omp_ctxp
->loop_iter_var
.quick_push (decl
);
12332 if (for_stmt
== orig_for_stmt
)
12334 tree orig_decl
= decl
;
12335 if (OMP_FOR_ORIG_DECLS (for_stmt
))
12337 tree orig_decl
= TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
), i
);
12338 if (TREE_CODE (orig_decl
) == TREE_LIST
)
12340 orig_decl
= TREE_PURPOSE (orig_decl
);
12345 if (is_global_var (orig_decl
) && DECL_THREAD_LOCAL_P (orig_decl
))
12346 error_at (EXPR_LOCATION (for_stmt
),
12347 "threadprivate iteration variable %qD", orig_decl
);
12350 /* Make sure the iteration variable is private. */
12351 tree c
= NULL_TREE
;
12352 tree c2
= NULL_TREE
;
12353 if (orig_for_stmt
!= for_stmt
)
12355 /* Preserve this information until we gimplify the inner simd. */
12357 && bitmap_bit_p (has_decl_expr
, DECL_UID (decl
)))
12358 TREE_PRIVATE (t
) = 1;
12360 else if (ort
== ORT_SIMD
)
12362 splay_tree_node n
= splay_tree_lookup (gimplify_omp_ctxp
->variables
,
12363 (splay_tree_key
) decl
);
12364 omp_is_private (gimplify_omp_ctxp
, decl
,
12365 1 + (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
))
12367 if (n
!= NULL
&& (n
->value
& GOVD_DATA_SHARE_CLASS
) != 0)
12369 omp_notice_variable (gimplify_omp_ctxp
, decl
, true);
12370 if (n
->value
& GOVD_LASTPRIVATE_CONDITIONAL
)
12371 for (tree c3
= omp_find_clause (OMP_FOR_CLAUSES (for_stmt
),
12372 OMP_CLAUSE_LASTPRIVATE
);
12373 c3
; c3
= omp_find_clause (OMP_CLAUSE_CHAIN (c3
),
12374 OMP_CLAUSE_LASTPRIVATE
))
12375 if (OMP_CLAUSE_DECL (c3
) == decl
)
12377 warning_at (OMP_CLAUSE_LOCATION (c3
), 0,
12378 "conditional %<lastprivate%> on loop "
12379 "iterator %qD ignored", decl
);
12380 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3
) = 0;
12381 n
->value
&= ~GOVD_LASTPRIVATE_CONDITIONAL
;
12384 else if (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)) == 1 && !loop_p
)
12386 c
= build_omp_clause (input_location
, OMP_CLAUSE_LINEAR
);
12387 OMP_CLAUSE_LINEAR_NO_COPYIN (c
) = 1;
12388 unsigned int flags
= GOVD_LINEAR
| GOVD_EXPLICIT
| GOVD_SEEN
;
12390 && bitmap_bit_p (has_decl_expr
, DECL_UID (decl
)))
12391 || TREE_PRIVATE (t
))
12393 OMP_CLAUSE_LINEAR_NO_COPYOUT (c
) = 1;
12394 flags
|= GOVD_LINEAR_LASTPRIVATE_NO_OUTER
;
12396 struct gimplify_omp_ctx
*outer
12397 = gimplify_omp_ctxp
->outer_context
;
12398 if (outer
&& !OMP_CLAUSE_LINEAR_NO_COPYOUT (c
))
12400 if (outer
->region_type
== ORT_WORKSHARE
12401 && outer
->combined_loop
)
12403 n
= splay_tree_lookup (outer
->variables
,
12404 (splay_tree_key
)decl
);
12405 if (n
!= NULL
&& (n
->value
& GOVD_LOCAL
) != 0)
12407 OMP_CLAUSE_LINEAR_NO_COPYOUT (c
) = 1;
12408 flags
|= GOVD_LINEAR_LASTPRIVATE_NO_OUTER
;
12412 struct gimplify_omp_ctx
*octx
= outer
->outer_context
;
12414 && octx
->region_type
== ORT_COMBINED_PARALLEL
12415 && octx
->outer_context
12416 && (octx
->outer_context
->region_type
12418 && octx
->outer_context
->combined_loop
)
12420 octx
= octx
->outer_context
;
12421 n
= splay_tree_lookup (octx
->variables
,
12422 (splay_tree_key
)decl
);
12423 if (n
!= NULL
&& (n
->value
& GOVD_LOCAL
) != 0)
12425 OMP_CLAUSE_LINEAR_NO_COPYOUT (c
) = 1;
12426 flags
|= GOVD_LINEAR_LASTPRIVATE_NO_OUTER
;
12433 OMP_CLAUSE_DECL (c
) = decl
;
12434 OMP_CLAUSE_CHAIN (c
) = OMP_FOR_CLAUSES (for_stmt
);
12435 OMP_FOR_CLAUSES (for_stmt
) = c
;
12436 omp_add_variable (gimplify_omp_ctxp
, decl
, flags
);
12437 if (outer
&& !OMP_CLAUSE_LINEAR_NO_COPYOUT (c
))
12438 omp_lastprivate_for_combined_outer_constructs (outer
, decl
,
12445 || !bitmap_bit_p (has_decl_expr
, DECL_UID (decl
)));
12446 if (TREE_PRIVATE (t
))
12447 lastprivate
= false;
12448 if (loop_p
&& OMP_FOR_ORIG_DECLS (for_stmt
))
12450 tree elt
= TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
), i
);
12451 if (TREE_CODE (elt
) == TREE_LIST
&& TREE_PURPOSE (elt
))
12452 lastprivate
= false;
12455 struct gimplify_omp_ctx
*outer
12456 = gimplify_omp_ctxp
->outer_context
;
12457 if (outer
&& lastprivate
)
12458 omp_lastprivate_for_combined_outer_constructs (outer
, decl
,
12461 c
= build_omp_clause (input_location
,
12462 lastprivate
? OMP_CLAUSE_LASTPRIVATE
12463 : OMP_CLAUSE_PRIVATE
);
12464 OMP_CLAUSE_DECL (c
) = decl
;
12465 OMP_CLAUSE_CHAIN (c
) = OMP_FOR_CLAUSES (for_stmt
);
12466 OMP_FOR_CLAUSES (for_stmt
) = c
;
12467 omp_add_variable (gimplify_omp_ctxp
, decl
,
12468 (lastprivate
? GOVD_LASTPRIVATE
: GOVD_PRIVATE
)
12469 | GOVD_EXPLICIT
| GOVD_SEEN
);
12473 else if (omp_is_private (gimplify_omp_ctxp
, decl
, 0))
12475 omp_notice_variable (gimplify_omp_ctxp
, decl
, true);
12476 splay_tree_node n
= splay_tree_lookup (gimplify_omp_ctxp
->variables
,
12477 (splay_tree_key
) decl
);
12478 if (n
&& (n
->value
& GOVD_LASTPRIVATE_CONDITIONAL
))
12479 for (tree c3
= omp_find_clause (OMP_FOR_CLAUSES (for_stmt
),
12480 OMP_CLAUSE_LASTPRIVATE
);
12481 c3
; c3
= omp_find_clause (OMP_CLAUSE_CHAIN (c3
),
12482 OMP_CLAUSE_LASTPRIVATE
))
12483 if (OMP_CLAUSE_DECL (c3
) == decl
)
12485 warning_at (OMP_CLAUSE_LOCATION (c3
), 0,
12486 "conditional %<lastprivate%> on loop "
12487 "iterator %qD ignored", decl
);
12488 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3
) = 0;
12489 n
->value
&= ~GOVD_LASTPRIVATE_CONDITIONAL
;
12493 omp_add_variable (gimplify_omp_ctxp
, decl
, GOVD_PRIVATE
| GOVD_SEEN
);
12495 /* If DECL is not a gimple register, create a temporary variable to act
12496 as an iteration counter. This is valid, since DECL cannot be
12497 modified in the body of the loop. Similarly for any iteration vars
12498 in simd with collapse > 1 where the iterator vars must be
12499 lastprivate. And similarly for vars mentioned in allocate clauses. */
12500 if (orig_for_stmt
!= for_stmt
)
12502 else if (!is_gimple_reg (decl
)
12503 || (ort
== ORT_SIMD
12504 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)) > 1)
12505 || (allocate_uids
&& allocate_uids
->contains (decl
)))
12507 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
12508 /* Make sure omp_add_variable is not called on it prematurely.
12509 We call it ourselves a few lines later. */
12510 gimplify_omp_ctxp
= NULL
;
12511 var
= create_tmp_var (TREE_TYPE (decl
), get_name (decl
));
12512 gimplify_omp_ctxp
= ctx
;
12513 TREE_OPERAND (t
, 0) = var
;
12515 gimplify_seq_add_stmt (&for_body
, gimple_build_assign (decl
, var
));
12517 if (ort
== ORT_SIMD
12518 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)) == 1)
12520 c2
= build_omp_clause (input_location
, OMP_CLAUSE_LINEAR
);
12521 OMP_CLAUSE_LINEAR_NO_COPYIN (c2
) = 1;
12522 OMP_CLAUSE_LINEAR_NO_COPYOUT (c2
) = 1;
12523 OMP_CLAUSE_DECL (c2
) = var
;
12524 OMP_CLAUSE_CHAIN (c2
) = OMP_FOR_CLAUSES (for_stmt
);
12525 OMP_FOR_CLAUSES (for_stmt
) = c2
;
12526 omp_add_variable (gimplify_omp_ctxp
, var
,
12527 GOVD_LINEAR
| GOVD_EXPLICIT
| GOVD_SEEN
);
12528 if (c
== NULL_TREE
)
12535 omp_add_variable (gimplify_omp_ctxp
, var
,
12536 GOVD_PRIVATE
| GOVD_SEEN
);
12541 gimplify_omp_ctxp
->in_for_exprs
= true;
12542 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
)
12544 tree lb
= TREE_OPERAND (t
, 1);
12545 tret
= gimplify_expr (&TREE_VEC_ELT (lb
, 1), &for_pre_body
, NULL
,
12546 is_gimple_val
, fb_rvalue
, false);
12547 ret
= MIN (ret
, tret
);
12548 tret
= gimplify_expr (&TREE_VEC_ELT (lb
, 2), &for_pre_body
, NULL
,
12549 is_gimple_val
, fb_rvalue
, false);
12552 tret
= gimplify_expr (&TREE_OPERAND (t
, 1), &for_pre_body
, NULL
,
12553 is_gimple_val
, fb_rvalue
, false);
12554 gimplify_omp_ctxp
->in_for_exprs
= false;
12555 ret
= MIN (ret
, tret
);
12556 if (ret
== GS_ERROR
)
12559 /* Handle OMP_FOR_COND. */
12560 t
= TREE_VEC_ELT (OMP_FOR_COND (for_stmt
), i
);
12561 gcc_assert (COMPARISON_CLASS_P (t
));
12562 gcc_assert (TREE_OPERAND (t
, 0) == decl
);
12564 gimplify_omp_ctxp
->in_for_exprs
= true;
12565 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
)
12567 tree ub
= TREE_OPERAND (t
, 1);
12568 tret
= gimplify_expr (&TREE_VEC_ELT (ub
, 1), &for_pre_body
, NULL
,
12569 is_gimple_val
, fb_rvalue
, false);
12570 ret
= MIN (ret
, tret
);
12571 tret
= gimplify_expr (&TREE_VEC_ELT (ub
, 2), &for_pre_body
, NULL
,
12572 is_gimple_val
, fb_rvalue
, false);
12575 tret
= gimplify_expr (&TREE_OPERAND (t
, 1), &for_pre_body
, NULL
,
12576 is_gimple_val
, fb_rvalue
, false);
12577 gimplify_omp_ctxp
->in_for_exprs
= false;
12578 ret
= MIN (ret
, tret
);
12580 /* Handle OMP_FOR_INCR. */
12581 t
= TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
);
12582 switch (TREE_CODE (t
))
12584 case PREINCREMENT_EXPR
:
12585 case POSTINCREMENT_EXPR
:
12587 tree decl
= TREE_OPERAND (t
, 0);
12588 /* c_omp_for_incr_canonicalize_ptr() should have been
12589 called to massage things appropriately. */
12590 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl
)));
12592 if (orig_for_stmt
!= for_stmt
)
12594 t
= build_int_cst (TREE_TYPE (decl
), 1);
12596 OMP_CLAUSE_LINEAR_STEP (c
) = t
;
12597 t
= build2 (PLUS_EXPR
, TREE_TYPE (decl
), var
, t
);
12598 t
= build2 (MODIFY_EXPR
, TREE_TYPE (var
), var
, t
);
12599 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
) = t
;
12603 case PREDECREMENT_EXPR
:
12604 case POSTDECREMENT_EXPR
:
12605 /* c_omp_for_incr_canonicalize_ptr() should have been
12606 called to massage things appropriately. */
12607 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl
)));
12608 if (orig_for_stmt
!= for_stmt
)
12610 t
= build_int_cst (TREE_TYPE (decl
), -1);
12612 OMP_CLAUSE_LINEAR_STEP (c
) = t
;
12613 t
= build2 (PLUS_EXPR
, TREE_TYPE (decl
), var
, t
);
12614 t
= build2 (MODIFY_EXPR
, TREE_TYPE (var
), var
, t
);
12615 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
) = t
;
12619 gcc_assert (TREE_OPERAND (t
, 0) == decl
);
12620 TREE_OPERAND (t
, 0) = var
;
12622 t
= TREE_OPERAND (t
, 1);
12623 switch (TREE_CODE (t
))
12626 if (TREE_OPERAND (t
, 1) == decl
)
12628 TREE_OPERAND (t
, 1) = TREE_OPERAND (t
, 0);
12629 TREE_OPERAND (t
, 0) = var
;
12635 case POINTER_PLUS_EXPR
:
12636 gcc_assert (TREE_OPERAND (t
, 0) == decl
);
12637 TREE_OPERAND (t
, 0) = var
;
12640 gcc_unreachable ();
12643 gimplify_omp_ctxp
->in_for_exprs
= true;
12644 tret
= gimplify_expr (&TREE_OPERAND (t
, 1), &for_pre_body
, NULL
,
12645 is_gimple_val
, fb_rvalue
, false);
12646 ret
= MIN (ret
, tret
);
12649 tree step
= TREE_OPERAND (t
, 1);
12650 tree stept
= TREE_TYPE (decl
);
12651 if (POINTER_TYPE_P (stept
))
12653 step
= fold_convert (stept
, step
);
12654 if (TREE_CODE (t
) == MINUS_EXPR
)
12655 step
= fold_build1 (NEGATE_EXPR
, stept
, step
);
12656 OMP_CLAUSE_LINEAR_STEP (c
) = step
;
12657 if (step
!= TREE_OPERAND (t
, 1))
12659 tret
= gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c
),
12660 &for_pre_body
, NULL
,
12661 is_gimple_val
, fb_rvalue
, false);
12662 ret
= MIN (ret
, tret
);
12665 gimplify_omp_ctxp
->in_for_exprs
= false;
12669 gcc_unreachable ();
12675 OMP_CLAUSE_LINEAR_STEP (c2
) = OMP_CLAUSE_LINEAR_STEP (c
);
12678 if ((var
!= decl
|| collapse
> 1 || tile
) && orig_for_stmt
== for_stmt
)
12680 for (c
= OMP_FOR_CLAUSES (for_stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
12681 if (((OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
12682 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
) == NULL
)
12683 || (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINEAR
12684 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c
)
12685 && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c
) == NULL
))
12686 && OMP_CLAUSE_DECL (c
) == decl
)
12688 if (is_doacross
&& (collapse
== 1 || i
>= collapse
))
12692 t
= TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
);
12693 gcc_assert (TREE_CODE (t
) == MODIFY_EXPR
);
12694 gcc_assert (TREE_OPERAND (t
, 0) == var
);
12695 t
= TREE_OPERAND (t
, 1);
12696 gcc_assert (TREE_CODE (t
) == PLUS_EXPR
12697 || TREE_CODE (t
) == MINUS_EXPR
12698 || TREE_CODE (t
) == POINTER_PLUS_EXPR
);
12699 gcc_assert (TREE_OPERAND (t
, 0) == var
);
12700 t
= build2 (TREE_CODE (t
), TREE_TYPE (decl
),
12701 is_doacross
? var
: decl
,
12702 TREE_OPERAND (t
, 1));
12705 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
)
12706 seq
= &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
);
12708 seq
= &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c
);
12709 push_gimplify_context ();
12710 gimplify_assign (decl
, t
, seq
);
12711 gimple
*bind
= NULL
;
12712 if (gimplify_ctxp
->temps
)
12714 bind
= gimple_build_bind (NULL_TREE
, *seq
, NULL_TREE
);
12716 gimplify_seq_add_stmt (seq
, bind
);
12718 pop_gimplify_context (bind
);
12721 if (OMP_FOR_NON_RECTANGULAR (for_stmt
) && var
!= decl
)
12722 for (int j
= i
+ 1; j
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); j
++)
12724 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), j
);
12725 gcc_assert (TREE_CODE (t
) == MODIFY_EXPR
);
12726 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
12727 && TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) == decl
)
12728 TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) = var
;
12729 t
= TREE_VEC_ELT (OMP_FOR_COND (for_stmt
), j
);
12730 gcc_assert (COMPARISON_CLASS_P (t
));
12731 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
12732 && TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) == decl
)
12733 TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) = var
;
12737 BITMAP_FREE (has_decl_expr
);
12738 delete allocate_uids
;
12740 if (TREE_CODE (orig_for_stmt
) == OMP_TASKLOOP
12741 || (loop_p
&& orig_for_stmt
== for_stmt
))
12743 push_gimplify_context ();
12744 if (TREE_CODE (OMP_FOR_BODY (orig_for_stmt
)) != BIND_EXPR
)
12746 OMP_FOR_BODY (orig_for_stmt
)
12747 = build3 (BIND_EXPR
, void_type_node
, NULL
,
12748 OMP_FOR_BODY (orig_for_stmt
), NULL
);
12749 TREE_SIDE_EFFECTS (OMP_FOR_BODY (orig_for_stmt
)) = 1;
12753 gimple
*g
= gimplify_and_return_first (OMP_FOR_BODY (orig_for_stmt
),
12756 if (TREE_CODE (orig_for_stmt
) == OMP_TASKLOOP
12757 || (loop_p
&& orig_for_stmt
== for_stmt
))
12759 if (gimple_code (g
) == GIMPLE_BIND
)
12760 pop_gimplify_context (g
);
12762 pop_gimplify_context (NULL
);
12765 if (orig_for_stmt
!= for_stmt
)
12766 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
12768 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), i
);
12769 decl
= TREE_OPERAND (t
, 0);
12770 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
12771 if (TREE_CODE (orig_for_stmt
) == OMP_TASKLOOP
)
12772 gimplify_omp_ctxp
= ctx
->outer_context
;
12773 var
= create_tmp_var (TREE_TYPE (decl
), get_name (decl
));
12774 gimplify_omp_ctxp
= ctx
;
12775 omp_add_variable (gimplify_omp_ctxp
, var
, GOVD_PRIVATE
| GOVD_SEEN
);
12776 TREE_OPERAND (t
, 0) = var
;
12777 t
= TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
);
12778 TREE_OPERAND (t
, 1) = copy_node (TREE_OPERAND (t
, 1));
12779 TREE_OPERAND (TREE_OPERAND (t
, 1), 0) = var
;
12780 if (OMP_FOR_NON_RECTANGULAR (for_stmt
))
12781 for (int j
= i
+ 1;
12782 j
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); j
++)
12784 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), j
);
12785 gcc_assert (TREE_CODE (t
) == MODIFY_EXPR
);
12786 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
12787 && TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) == decl
)
12789 TREE_OPERAND (t
, 1) = copy_node (TREE_OPERAND (t
, 1));
12790 TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) = var
;
12792 t
= TREE_VEC_ELT (OMP_FOR_COND (for_stmt
), j
);
12793 gcc_assert (COMPARISON_CLASS_P (t
));
12794 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
12795 && TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) == decl
)
12797 TREE_OPERAND (t
, 1) = copy_node (TREE_OPERAND (t
, 1));
12798 TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) = var
;
12803 gimplify_adjust_omp_clauses (pre_p
, for_body
,
12804 &OMP_FOR_CLAUSES (orig_for_stmt
),
12805 TREE_CODE (orig_for_stmt
));
12808 switch (TREE_CODE (orig_for_stmt
))
12810 case OMP_FOR
: kind
= GF_OMP_FOR_KIND_FOR
; break;
12811 case OMP_SIMD
: kind
= GF_OMP_FOR_KIND_SIMD
; break;
12812 case OMP_DISTRIBUTE
: kind
= GF_OMP_FOR_KIND_DISTRIBUTE
; break;
12813 case OMP_TASKLOOP
: kind
= GF_OMP_FOR_KIND_TASKLOOP
; break;
12814 case OACC_LOOP
: kind
= GF_OMP_FOR_KIND_OACC_LOOP
; break;
12816 gcc_unreachable ();
12818 if (loop_p
&& kind
== GF_OMP_FOR_KIND_SIMD
)
12820 gimplify_seq_add_seq (pre_p
, for_pre_body
);
12821 for_pre_body
= NULL
;
12823 gfor
= gimple_build_omp_for (for_body
, kind
, OMP_FOR_CLAUSES (orig_for_stmt
),
12824 TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)),
12826 if (orig_for_stmt
!= for_stmt
)
12827 gimple_omp_for_set_combined_p (gfor
, true);
12828 if (gimplify_omp_ctxp
12829 && (gimplify_omp_ctxp
->combined_loop
12830 || (gimplify_omp_ctxp
->region_type
== ORT_COMBINED_PARALLEL
12831 && gimplify_omp_ctxp
->outer_context
12832 && gimplify_omp_ctxp
->outer_context
->combined_loop
)))
12834 gimple_omp_for_set_combined_into_p (gfor
, true);
12835 if (gimplify_omp_ctxp
->combined_loop
)
12836 gcc_assert (TREE_CODE (orig_for_stmt
) == OMP_SIMD
);
12838 gcc_assert (TREE_CODE (orig_for_stmt
) == OMP_FOR
);
12841 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
12843 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), i
);
12844 gimple_omp_for_set_index (gfor
, i
, TREE_OPERAND (t
, 0));
12845 gimple_omp_for_set_initial (gfor
, i
, TREE_OPERAND (t
, 1));
12846 t
= TREE_VEC_ELT (OMP_FOR_COND (for_stmt
), i
);
12847 gimple_omp_for_set_cond (gfor
, i
, TREE_CODE (t
));
12848 gimple_omp_for_set_final (gfor
, i
, TREE_OPERAND (t
, 1));
12849 t
= TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
);
12850 gimple_omp_for_set_incr (gfor
, i
, TREE_OPERAND (t
, 1));
12853 /* OMP_TASKLOOP is gimplified as two GIMPLE_OMP_FOR taskloop
12854 constructs with GIMPLE_OMP_TASK sandwiched in between them.
12855 The outer taskloop stands for computing the number of iterations,
12856 counts for collapsed loops and holding taskloop specific clauses.
12857 The task construct stands for the effect of data sharing on the
12858 explicit task it creates and the inner taskloop stands for expansion
12859 of the static loop inside of the explicit task construct. */
12860 if (TREE_CODE (orig_for_stmt
) == OMP_TASKLOOP
)
12862 tree
*gfor_clauses_ptr
= gimple_omp_for_clauses_ptr (gfor
);
12863 tree task_clauses
= NULL_TREE
;
12864 tree c
= *gfor_clauses_ptr
;
12865 tree
*gtask_clauses_ptr
= &task_clauses
;
12866 tree outer_for_clauses
= NULL_TREE
;
12867 tree
*gforo_clauses_ptr
= &outer_for_clauses
;
12868 bitmap lastprivate_uids
= NULL
;
12869 if (omp_find_clause (c
, OMP_CLAUSE_ALLOCATE
))
12871 c
= omp_find_clause (c
, OMP_CLAUSE_LASTPRIVATE
);
12874 lastprivate_uids
= BITMAP_ALLOC (NULL
);
12875 for (; c
; c
= omp_find_clause (OMP_CLAUSE_CHAIN (c
),
12876 OMP_CLAUSE_LASTPRIVATE
))
12877 bitmap_set_bit (lastprivate_uids
,
12878 DECL_UID (OMP_CLAUSE_DECL (c
)));
12880 c
= *gfor_clauses_ptr
;
12882 for (; c
; c
= OMP_CLAUSE_CHAIN (c
))
12883 switch (OMP_CLAUSE_CODE (c
))
12885 /* These clauses are allowed on task, move them there. */
12886 case OMP_CLAUSE_SHARED
:
12887 case OMP_CLAUSE_FIRSTPRIVATE
:
12888 case OMP_CLAUSE_DEFAULT
:
12889 case OMP_CLAUSE_IF
:
12890 case OMP_CLAUSE_UNTIED
:
12891 case OMP_CLAUSE_FINAL
:
12892 case OMP_CLAUSE_MERGEABLE
:
12893 case OMP_CLAUSE_PRIORITY
:
12894 case OMP_CLAUSE_REDUCTION
:
12895 case OMP_CLAUSE_IN_REDUCTION
:
12896 *gtask_clauses_ptr
= c
;
12897 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
12899 case OMP_CLAUSE_PRIVATE
:
12900 if (OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c
))
12902 /* We want private on outer for and firstprivate
12905 = build_omp_clause (OMP_CLAUSE_LOCATION (c
),
12906 OMP_CLAUSE_FIRSTPRIVATE
);
12907 OMP_CLAUSE_DECL (*gtask_clauses_ptr
) = OMP_CLAUSE_DECL (c
);
12908 lang_hooks
.decls
.omp_finish_clause (*gtask_clauses_ptr
, NULL
,
12910 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr
);
12911 *gforo_clauses_ptr
= c
;
12912 gforo_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
12916 *gtask_clauses_ptr
= c
;
12917 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
12920 /* These clauses go into outer taskloop clauses. */
12921 case OMP_CLAUSE_GRAINSIZE
:
12922 case OMP_CLAUSE_NUM_TASKS
:
12923 case OMP_CLAUSE_NOGROUP
:
12924 *gforo_clauses_ptr
= c
;
12925 gforo_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
12927 /* Collapse clause we duplicate on both taskloops. */
12928 case OMP_CLAUSE_COLLAPSE
:
12929 *gfor_clauses_ptr
= c
;
12930 gfor_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
12931 *gforo_clauses_ptr
= copy_node (c
);
12932 gforo_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr
);
12934 /* For lastprivate, keep the clause on inner taskloop, and add
12935 a shared clause on task. If the same decl is also firstprivate,
12936 add also firstprivate clause on the inner taskloop. */
12937 case OMP_CLAUSE_LASTPRIVATE
:
12938 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c
))
12940 /* For taskloop C++ lastprivate IVs, we want:
12941 1) private on outer taskloop
12942 2) firstprivate and shared on task
12943 3) lastprivate on inner taskloop */
12945 = build_omp_clause (OMP_CLAUSE_LOCATION (c
),
12946 OMP_CLAUSE_FIRSTPRIVATE
);
12947 OMP_CLAUSE_DECL (*gtask_clauses_ptr
) = OMP_CLAUSE_DECL (c
);
12948 lang_hooks
.decls
.omp_finish_clause (*gtask_clauses_ptr
, NULL
,
12950 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr
);
12951 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
) = 1;
12952 *gforo_clauses_ptr
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
12953 OMP_CLAUSE_PRIVATE
);
12954 OMP_CLAUSE_DECL (*gforo_clauses_ptr
) = OMP_CLAUSE_DECL (c
);
12955 OMP_CLAUSE_PRIVATE_TASKLOOP_IV (*gforo_clauses_ptr
) = 1;
12956 TREE_TYPE (*gforo_clauses_ptr
) = TREE_TYPE (c
);
12957 gforo_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr
);
12959 *gfor_clauses_ptr
= c
;
12960 gfor_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
12962 = build_omp_clause (OMP_CLAUSE_LOCATION (c
), OMP_CLAUSE_SHARED
);
12963 OMP_CLAUSE_DECL (*gtask_clauses_ptr
) = OMP_CLAUSE_DECL (c
);
12964 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
))
12965 OMP_CLAUSE_SHARED_FIRSTPRIVATE (*gtask_clauses_ptr
) = 1;
12967 = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr
);
12969 /* Allocate clause we duplicate on task and inner taskloop
12970 if the decl is lastprivate, otherwise just put on task. */
12971 case OMP_CLAUSE_ALLOCATE
:
12972 if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
)
12973 && DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
)))
12975 /* Additionally, put firstprivate clause on task
12976 for the allocator if it is not constant. */
12978 = build_omp_clause (OMP_CLAUSE_LOCATION (c
),
12979 OMP_CLAUSE_FIRSTPRIVATE
);
12980 OMP_CLAUSE_DECL (*gtask_clauses_ptr
)
12981 = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
);
12982 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr
);
12984 if (lastprivate_uids
12985 && bitmap_bit_p (lastprivate_uids
,
12986 DECL_UID (OMP_CLAUSE_DECL (c
))))
12988 *gfor_clauses_ptr
= c
;
12989 gfor_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
12990 *gtask_clauses_ptr
= copy_node (c
);
12991 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr
);
12995 *gtask_clauses_ptr
= c
;
12996 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
13000 gcc_unreachable ();
13002 *gfor_clauses_ptr
= NULL_TREE
;
13003 *gtask_clauses_ptr
= NULL_TREE
;
13004 *gforo_clauses_ptr
= NULL_TREE
;
13005 BITMAP_FREE (lastprivate_uids
);
13006 g
= gimple_build_bind (NULL_TREE
, gfor
, NULL_TREE
);
13007 g
= gimple_build_omp_task (g
, task_clauses
, NULL_TREE
, NULL_TREE
,
13008 NULL_TREE
, NULL_TREE
, NULL_TREE
);
13009 gimple_omp_task_set_taskloop_p (g
, true);
13010 g
= gimple_build_bind (NULL_TREE
, g
, NULL_TREE
);
13012 = gimple_build_omp_for (g
, GF_OMP_FOR_KIND_TASKLOOP
, outer_for_clauses
,
13013 gimple_omp_for_collapse (gfor
),
13014 gimple_omp_for_pre_body (gfor
));
13015 gimple_omp_for_set_pre_body (gfor
, NULL
);
13016 gimple_omp_for_set_combined_p (gforo
, true);
13017 gimple_omp_for_set_combined_into_p (gfor
, true);
13018 for (i
= 0; i
< (int) gimple_omp_for_collapse (gfor
); i
++)
13020 tree type
= TREE_TYPE (gimple_omp_for_index (gfor
, i
));
13021 tree v
= create_tmp_var (type
);
13022 gimple_omp_for_set_index (gforo
, i
, v
);
13023 t
= unshare_expr (gimple_omp_for_initial (gfor
, i
));
13024 gimple_omp_for_set_initial (gforo
, i
, t
);
13025 gimple_omp_for_set_cond (gforo
, i
,
13026 gimple_omp_for_cond (gfor
, i
));
13027 t
= unshare_expr (gimple_omp_for_final (gfor
, i
));
13028 gimple_omp_for_set_final (gforo
, i
, t
);
13029 t
= unshare_expr (gimple_omp_for_incr (gfor
, i
));
13030 gcc_assert (TREE_OPERAND (t
, 0) == gimple_omp_for_index (gfor
, i
));
13031 TREE_OPERAND (t
, 0) = v
;
13032 gimple_omp_for_set_incr (gforo
, i
, t
);
13033 t
= build_omp_clause (input_location
, OMP_CLAUSE_PRIVATE
);
13034 OMP_CLAUSE_DECL (t
) = v
;
13035 OMP_CLAUSE_CHAIN (t
) = gimple_omp_for_clauses (gforo
);
13036 gimple_omp_for_set_clauses (gforo
, t
);
13037 if (OMP_FOR_NON_RECTANGULAR (for_stmt
))
13039 tree
*p1
= NULL
, *p2
= NULL
;
13040 t
= gimple_omp_for_initial (gforo
, i
);
13041 if (TREE_CODE (t
) == TREE_VEC
)
13042 p1
= &TREE_VEC_ELT (t
, 0);
13043 t
= gimple_omp_for_final (gforo
, i
);
13044 if (TREE_CODE (t
) == TREE_VEC
)
13047 p2
= &TREE_VEC_ELT (t
, 0);
13049 p1
= &TREE_VEC_ELT (t
, 0);
13054 for (j
= 0; j
< i
; j
++)
13055 if (*p1
== gimple_omp_for_index (gfor
, j
))
13057 *p1
= gimple_omp_for_index (gforo
, j
);
13062 gcc_assert (j
< i
);
13066 gimplify_seq_add_stmt (pre_p
, gforo
);
13069 gimplify_seq_add_stmt (pre_p
, gfor
);
13071 if (TREE_CODE (orig_for_stmt
) == OMP_FOR
)
13073 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
13074 unsigned lastprivate_conditional
= 0;
13076 && (ctx
->region_type
== ORT_TARGET_DATA
13077 || ctx
->region_type
== ORT_TASKGROUP
))
13078 ctx
= ctx
->outer_context
;
13079 if (ctx
&& (ctx
->region_type
& ORT_PARALLEL
) != 0)
13080 for (tree c
= gimple_omp_for_clauses (gfor
);
13081 c
; c
= OMP_CLAUSE_CHAIN (c
))
13082 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
13083 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
))
13084 ++lastprivate_conditional
;
13085 if (lastprivate_conditional
)
13087 struct omp_for_data fd
;
13088 omp_extract_for_data (gfor
, &fd
, NULL
);
13089 tree type
= build_array_type_nelts (unsigned_type_for (fd
.iter_type
),
13090 lastprivate_conditional
);
13091 tree var
= create_tmp_var_raw (type
);
13092 tree c
= build_omp_clause (UNKNOWN_LOCATION
, OMP_CLAUSE__CONDTEMP_
);
13093 OMP_CLAUSE_DECL (c
) = var
;
13094 OMP_CLAUSE_CHAIN (c
) = gimple_omp_for_clauses (gfor
);
13095 gimple_omp_for_set_clauses (gfor
, c
);
13096 omp_add_variable (ctx
, var
, GOVD_CONDTEMP
| GOVD_SEEN
);
13099 else if (TREE_CODE (orig_for_stmt
) == OMP_SIMD
)
13101 unsigned lastprivate_conditional
= 0;
13102 for (tree c
= gimple_omp_for_clauses (gfor
); c
; c
= OMP_CLAUSE_CHAIN (c
))
13103 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
13104 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
))
13105 ++lastprivate_conditional
;
13106 if (lastprivate_conditional
)
13108 struct omp_for_data fd
;
13109 omp_extract_for_data (gfor
, &fd
, NULL
);
13110 tree type
= unsigned_type_for (fd
.iter_type
);
13111 while (lastprivate_conditional
--)
13113 tree c
= build_omp_clause (UNKNOWN_LOCATION
,
13114 OMP_CLAUSE__CONDTEMP_
);
13115 OMP_CLAUSE_DECL (c
) = create_tmp_var (type
);
13116 OMP_CLAUSE_CHAIN (c
) = gimple_omp_for_clauses (gfor
);
13117 gimple_omp_for_set_clauses (gfor
, c
);
13122 if (ret
!= GS_ALL_DONE
)
13124 *expr_p
= NULL_TREE
;
13125 return GS_ALL_DONE
;
13128 /* Helper for gimplify_omp_loop, called through walk_tree. */
13131 note_no_context_vars (tree
*tp
, int *, void *data
)
13134 && DECL_CONTEXT (*tp
) == NULL_TREE
13135 && !is_global_var (*tp
))
13137 vec
<tree
> *d
= (vec
<tree
> *) data
;
13138 d
->safe_push (*tp
);
13139 DECL_CONTEXT (*tp
) = current_function_decl
;
13144 /* Gimplify the gross structure of an OMP_LOOP statement. */
13146 static enum gimplify_status
13147 gimplify_omp_loop (tree
*expr_p
, gimple_seq
*pre_p
)
13149 tree for_stmt
= *expr_p
;
13150 tree clauses
= OMP_FOR_CLAUSES (for_stmt
);
13151 struct gimplify_omp_ctx
*octx
= gimplify_omp_ctxp
;
13152 enum omp_clause_bind_kind kind
= OMP_CLAUSE_BIND_THREAD
;
13155 /* If order is not present, the behavior is as if order(concurrent)
13157 tree order
= omp_find_clause (clauses
, OMP_CLAUSE_ORDER
);
13158 if (order
== NULL_TREE
)
13160 order
= build_omp_clause (UNKNOWN_LOCATION
, OMP_CLAUSE_ORDER
);
13161 OMP_CLAUSE_CHAIN (order
) = clauses
;
13162 OMP_FOR_CLAUSES (for_stmt
) = clauses
= order
;
13165 tree bind
= omp_find_clause (clauses
, OMP_CLAUSE_BIND
);
13166 if (bind
== NULL_TREE
)
13168 if (!flag_openmp
) /* flag_openmp_simd */
13170 else if (octx
&& (octx
->region_type
& ORT_TEAMS
) != 0)
13171 kind
= OMP_CLAUSE_BIND_TEAMS
;
13172 else if (octx
&& (octx
->region_type
& ORT_PARALLEL
) != 0)
13173 kind
= OMP_CLAUSE_BIND_PARALLEL
;
13176 for (; octx
; octx
= octx
->outer_context
)
13178 if ((octx
->region_type
& ORT_ACC
) != 0
13179 || octx
->region_type
== ORT_NONE
13180 || octx
->region_type
== ORT_IMPLICIT_TARGET
)
13184 if (octx
== NULL
&& !in_omp_construct
)
13185 error_at (EXPR_LOCATION (for_stmt
),
13186 "%<bind%> clause not specified on a %<loop%> "
13187 "construct not nested inside another OpenMP construct");
13189 bind
= build_omp_clause (UNKNOWN_LOCATION
, OMP_CLAUSE_BIND
);
13190 OMP_CLAUSE_CHAIN (bind
) = clauses
;
13191 OMP_CLAUSE_BIND_KIND (bind
) = kind
;
13192 OMP_FOR_CLAUSES (for_stmt
) = bind
;
13195 switch (OMP_CLAUSE_BIND_KIND (bind
))
13197 case OMP_CLAUSE_BIND_THREAD
:
13199 case OMP_CLAUSE_BIND_PARALLEL
:
13200 if (!flag_openmp
) /* flag_openmp_simd */
13202 OMP_CLAUSE_BIND_KIND (bind
) = OMP_CLAUSE_BIND_THREAD
;
13205 for (; octx
; octx
= octx
->outer_context
)
13206 if (octx
->region_type
== ORT_SIMD
13207 && omp_find_clause (octx
->clauses
, OMP_CLAUSE_BIND
) == NULL_TREE
)
13209 error_at (EXPR_LOCATION (for_stmt
),
13210 "%<bind(parallel)%> on a %<loop%> construct nested "
13211 "inside %<simd%> construct");
13212 OMP_CLAUSE_BIND_KIND (bind
) = OMP_CLAUSE_BIND_THREAD
;
13215 kind
= OMP_CLAUSE_BIND_PARALLEL
;
13217 case OMP_CLAUSE_BIND_TEAMS
:
13218 if (!flag_openmp
) /* flag_openmp_simd */
13220 OMP_CLAUSE_BIND_KIND (bind
) = OMP_CLAUSE_BIND_THREAD
;
13224 && octx
->region_type
!= ORT_IMPLICIT_TARGET
13225 && octx
->region_type
!= ORT_NONE
13226 && (octx
->region_type
& ORT_TEAMS
) == 0)
13227 || in_omp_construct
)
13229 error_at (EXPR_LOCATION (for_stmt
),
13230 "%<bind(teams)%> on a %<loop%> region not strictly "
13231 "nested inside of a %<teams%> region");
13232 OMP_CLAUSE_BIND_KIND (bind
) = OMP_CLAUSE_BIND_THREAD
;
13235 kind
= OMP_CLAUSE_BIND_TEAMS
;
13238 gcc_unreachable ();
13241 for (tree
*pc
= &OMP_FOR_CLAUSES (for_stmt
); *pc
; )
13242 switch (OMP_CLAUSE_CODE (*pc
))
13244 case OMP_CLAUSE_REDUCTION
:
13245 if (OMP_CLAUSE_REDUCTION_INSCAN (*pc
))
13247 error_at (OMP_CLAUSE_LOCATION (*pc
),
13248 "%<inscan%> %<reduction%> clause on "
13249 "%qs construct", "loop");
13250 OMP_CLAUSE_REDUCTION_INSCAN (*pc
) = 0;
13252 if (OMP_CLAUSE_REDUCTION_TASK (*pc
))
13254 error_at (OMP_CLAUSE_LOCATION (*pc
),
13255 "invalid %<task%> reduction modifier on construct "
13256 "other than %<parallel%>, %qs or %<sections%>",
13257 lang_GNU_Fortran () ? "do" : "for");
13258 OMP_CLAUSE_REDUCTION_TASK (*pc
) = 0;
13260 pc
= &OMP_CLAUSE_CHAIN (*pc
);
13262 case OMP_CLAUSE_LASTPRIVATE
:
13263 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
13265 tree t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), i
);
13266 gcc_assert (TREE_CODE (t
) == MODIFY_EXPR
);
13267 if (OMP_CLAUSE_DECL (*pc
) == TREE_OPERAND (t
, 0))
13269 if (OMP_FOR_ORIG_DECLS (for_stmt
)
13270 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
),
13272 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
),
13275 tree orig
= TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
), i
);
13276 if (OMP_CLAUSE_DECL (*pc
) == TREE_PURPOSE (orig
))
13280 if (i
== TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)))
13282 error_at (OMP_CLAUSE_LOCATION (*pc
),
13283 "%<lastprivate%> clause on a %<loop%> construct refers "
13284 "to a variable %qD which is not the loop iterator",
13285 OMP_CLAUSE_DECL (*pc
));
13286 *pc
= OMP_CLAUSE_CHAIN (*pc
);
13289 pc
= &OMP_CLAUSE_CHAIN (*pc
);
13292 pc
= &OMP_CLAUSE_CHAIN (*pc
);
13296 TREE_SET_CODE (for_stmt
, OMP_SIMD
);
13301 case OMP_CLAUSE_BIND_THREAD
: last
= 0; break;
13302 case OMP_CLAUSE_BIND_PARALLEL
: last
= 1; break;
13303 case OMP_CLAUSE_BIND_TEAMS
: last
= 2; break;
13305 for (int pass
= 1; pass
<= last
; pass
++)
13309 tree bind
= build3 (BIND_EXPR
, void_type_node
, NULL
, NULL
,
13310 make_node (BLOCK
));
13311 append_to_statement_list (*expr_p
, &BIND_EXPR_BODY (bind
));
13312 *expr_p
= make_node (OMP_PARALLEL
);
13313 TREE_TYPE (*expr_p
) = void_type_node
;
13314 OMP_PARALLEL_BODY (*expr_p
) = bind
;
13315 OMP_PARALLEL_COMBINED (*expr_p
) = 1;
13316 SET_EXPR_LOCATION (*expr_p
, EXPR_LOCATION (for_stmt
));
13317 tree
*pc
= &OMP_PARALLEL_CLAUSES (*expr_p
);
13318 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
13319 if (OMP_FOR_ORIG_DECLS (for_stmt
)
13320 && (TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
), i
))
13323 tree elt
= TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
), i
);
13324 if (TREE_PURPOSE (elt
) && TREE_VALUE (elt
))
13326 *pc
= build_omp_clause (UNKNOWN_LOCATION
,
13327 OMP_CLAUSE_FIRSTPRIVATE
);
13328 OMP_CLAUSE_DECL (*pc
) = TREE_VALUE (elt
);
13329 pc
= &OMP_CLAUSE_CHAIN (*pc
);
13333 tree t
= make_node (pass
== 2 ? OMP_DISTRIBUTE
: OMP_FOR
);
13334 tree
*pc
= &OMP_FOR_CLAUSES (t
);
13335 TREE_TYPE (t
) = void_type_node
;
13336 OMP_FOR_BODY (t
) = *expr_p
;
13337 SET_EXPR_LOCATION (t
, EXPR_LOCATION (for_stmt
));
13338 for (tree c
= OMP_FOR_CLAUSES (for_stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
13339 switch (OMP_CLAUSE_CODE (c
))
13341 case OMP_CLAUSE_BIND
:
13342 case OMP_CLAUSE_ORDER
:
13343 case OMP_CLAUSE_COLLAPSE
:
13344 *pc
= copy_node (c
);
13345 pc
= &OMP_CLAUSE_CHAIN (*pc
);
13347 case OMP_CLAUSE_PRIVATE
:
13348 case OMP_CLAUSE_FIRSTPRIVATE
:
13349 /* Only needed on innermost. */
13351 case OMP_CLAUSE_LASTPRIVATE
:
13352 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c
) && pass
!= last
)
13354 *pc
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
13355 OMP_CLAUSE_FIRSTPRIVATE
);
13356 OMP_CLAUSE_DECL (*pc
) = OMP_CLAUSE_DECL (c
);
13357 lang_hooks
.decls
.omp_finish_clause (*pc
, NULL
, false);
13358 pc
= &OMP_CLAUSE_CHAIN (*pc
);
13360 *pc
= copy_node (c
);
13361 OMP_CLAUSE_LASTPRIVATE_STMT (*pc
) = NULL_TREE
;
13362 TREE_TYPE (*pc
) = unshare_expr (TREE_TYPE (c
));
13363 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c
))
13366 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (*pc
) = 1;
13368 lang_hooks
.decls
.omp_finish_clause (*pc
, NULL
, false);
13369 OMP_CLAUSE_LASTPRIVATE_LOOP_IV (*pc
) = 0;
13371 pc
= &OMP_CLAUSE_CHAIN (*pc
);
13373 case OMP_CLAUSE_REDUCTION
:
13374 *pc
= copy_node (c
);
13375 OMP_CLAUSE_DECL (*pc
) = unshare_expr (OMP_CLAUSE_DECL (c
));
13376 TREE_TYPE (*pc
) = unshare_expr (TREE_TYPE (c
));
13377 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc
))
13379 auto_vec
<tree
> no_context_vars
;
13380 int walk_subtrees
= 0;
13381 note_no_context_vars (&OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
),
13382 &walk_subtrees
, &no_context_vars
);
13383 if (tree p
= OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c
))
13384 note_no_context_vars (&p
, &walk_subtrees
, &no_context_vars
);
13385 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_INIT (c
),
13386 note_no_context_vars
,
13388 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_MERGE (c
),
13389 note_no_context_vars
,
13392 OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc
)
13393 = copy_node (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
));
13394 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc
))
13395 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc
)
13396 = copy_node (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c
));
13398 hash_map
<tree
, tree
> decl_map
;
13399 decl_map
.put (OMP_CLAUSE_DECL (c
), OMP_CLAUSE_DECL (c
));
13400 decl_map
.put (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
),
13401 OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc
));
13402 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc
))
13403 decl_map
.put (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c
),
13404 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc
));
13407 memset (&id
, 0, sizeof (id
));
13408 id
.src_fn
= current_function_decl
;
13409 id
.dst_fn
= current_function_decl
;
13410 id
.src_cfun
= cfun
;
13411 id
.decl_map
= &decl_map
;
13412 id
.copy_decl
= copy_decl_no_change
;
13413 id
.transform_call_graph_edges
= CB_CGE_DUPLICATE
;
13414 id
.transform_new_cfg
= true;
13415 id
.transform_return_to_modify
= false;
13417 walk_tree (&OMP_CLAUSE_REDUCTION_INIT (*pc
), copy_tree_body_r
,
13419 walk_tree (&OMP_CLAUSE_REDUCTION_MERGE (*pc
), copy_tree_body_r
,
13422 for (tree d
: no_context_vars
)
13424 DECL_CONTEXT (d
) = NULL_TREE
;
13425 DECL_CONTEXT (*decl_map
.get (d
)) = NULL_TREE
;
13430 OMP_CLAUSE_REDUCTION_INIT (*pc
)
13431 = unshare_expr (OMP_CLAUSE_REDUCTION_INIT (c
));
13432 OMP_CLAUSE_REDUCTION_MERGE (*pc
)
13433 = unshare_expr (OMP_CLAUSE_REDUCTION_MERGE (c
));
13435 pc
= &OMP_CLAUSE_CHAIN (*pc
);
13438 gcc_unreachable ();
13443 return gimplify_omp_for (expr_p
, pre_p
);
13447 /* Helper function of optimize_target_teams, find OMP_TEAMS inside
13448 of OMP_TARGET's body. */
13451 find_omp_teams (tree
*tp
, int *walk_subtrees
, void *)
13453 *walk_subtrees
= 0;
13454 switch (TREE_CODE (*tp
))
13459 case STATEMENT_LIST
:
13460 *walk_subtrees
= 1;
13468 /* Helper function of optimize_target_teams, determine if the expression
13469 can be computed safely before the target construct on the host. */
13472 computable_teams_clause (tree
*tp
, int *walk_subtrees
, void *)
13478 *walk_subtrees
= 0;
13481 switch (TREE_CODE (*tp
))
13486 *walk_subtrees
= 0;
13487 if (error_operand_p (*tp
)
13488 || !INTEGRAL_TYPE_P (TREE_TYPE (*tp
))
13489 || DECL_HAS_VALUE_EXPR_P (*tp
)
13490 || DECL_THREAD_LOCAL_P (*tp
)
13491 || TREE_SIDE_EFFECTS (*tp
)
13492 || TREE_THIS_VOLATILE (*tp
))
13494 if (is_global_var (*tp
)
13495 && (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (*tp
))
13496 || lookup_attribute ("omp declare target link",
13497 DECL_ATTRIBUTES (*tp
))))
13500 && !DECL_SEEN_IN_BIND_EXPR_P (*tp
)
13501 && !is_global_var (*tp
)
13502 && decl_function_context (*tp
) == current_function_decl
)
13504 n
= splay_tree_lookup (gimplify_omp_ctxp
->variables
,
13505 (splay_tree_key
) *tp
);
13508 if (gimplify_omp_ctxp
->defaultmap
[GDMK_SCALAR
] & GOVD_FIRSTPRIVATE
)
13512 else if (n
->value
& GOVD_LOCAL
)
13514 else if (n
->value
& GOVD_FIRSTPRIVATE
)
13516 else if ((n
->value
& (GOVD_MAP
| GOVD_MAP_ALWAYS_TO
))
13517 == (GOVD_MAP
| GOVD_MAP_ALWAYS_TO
))
13521 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp
)))
13525 if (TARGET_EXPR_INITIAL (*tp
)
13526 || TREE_CODE (TARGET_EXPR_SLOT (*tp
)) != VAR_DECL
)
13528 return computable_teams_clause (&TARGET_EXPR_SLOT (*tp
),
13529 walk_subtrees
, NULL
);
13530 /* Allow some reasonable subset of integral arithmetics. */
13534 case TRUNC_DIV_EXPR
:
13535 case CEIL_DIV_EXPR
:
13536 case FLOOR_DIV_EXPR
:
13537 case ROUND_DIV_EXPR
:
13538 case TRUNC_MOD_EXPR
:
13539 case CEIL_MOD_EXPR
:
13540 case FLOOR_MOD_EXPR
:
13541 case ROUND_MOD_EXPR
:
13543 case EXACT_DIV_EXPR
:
13554 case NON_LVALUE_EXPR
:
13556 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp
)))
13559 /* And disallow anything else, except for comparisons. */
13561 if (COMPARISON_CLASS_P (*tp
))
13567 /* Try to determine if the num_teams and/or thread_limit expressions
13568 can have their values determined already before entering the
13570 INTEGER_CSTs trivially are,
13571 integral decls that are firstprivate (explicitly or implicitly)
13572 or explicitly map(always, to:) or map(always, tofrom:) on the target
13573 region too, and expressions involving simple arithmetics on those
13574 too, function calls are not ok, dereferencing something neither etc.
13575 Add NUM_TEAMS and THREAD_LIMIT clauses to the OMP_CLAUSES of
13576 EXPR based on what we find:
13577 0 stands for clause not specified at all, use implementation default
13578 -1 stands for value that can't be determined easily before entering
13579 the target construct.
13580 If teams construct is not present at all, use 1 for num_teams
13581 and 0 for thread_limit (only one team is involved, and the thread
13582 limit is implementation defined. */
13585 optimize_target_teams (tree target
, gimple_seq
*pre_p
)
13587 tree body
= OMP_BODY (target
);
13588 tree teams
= walk_tree (&body
, find_omp_teams
, NULL
, NULL
);
13589 tree num_teams_lower
= NULL_TREE
;
13590 tree num_teams_upper
= integer_zero_node
;
13591 tree thread_limit
= integer_zero_node
;
13592 location_t num_teams_loc
= EXPR_LOCATION (target
);
13593 location_t thread_limit_loc
= EXPR_LOCATION (target
);
13595 struct gimplify_omp_ctx
*target_ctx
= gimplify_omp_ctxp
;
13597 if (teams
== NULL_TREE
)
13598 num_teams_upper
= integer_one_node
;
13600 for (c
= OMP_TEAMS_CLAUSES (teams
); c
; c
= OMP_CLAUSE_CHAIN (c
))
13602 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_NUM_TEAMS
)
13604 p
= &num_teams_upper
;
13605 num_teams_loc
= OMP_CLAUSE_LOCATION (c
);
13606 if (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c
))
13608 expr
= OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c
);
13609 if (TREE_CODE (expr
) == INTEGER_CST
)
13610 num_teams_lower
= expr
;
13611 else if (walk_tree (&expr
, computable_teams_clause
,
13613 num_teams_lower
= integer_minus_one_node
;
13616 num_teams_lower
= expr
;
13617 gimplify_omp_ctxp
= gimplify_omp_ctxp
->outer_context
;
13618 if (gimplify_expr (&num_teams_lower
, pre_p
, NULL
,
13619 is_gimple_val
, fb_rvalue
, false)
13622 gimplify_omp_ctxp
= target_ctx
;
13623 num_teams_lower
= integer_minus_one_node
;
13627 gimplify_omp_ctxp
= target_ctx
;
13628 if (!DECL_P (expr
) && TREE_CODE (expr
) != TARGET_EXPR
)
13629 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c
)
13635 else if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_THREAD_LIMIT
)
13638 thread_limit_loc
= OMP_CLAUSE_LOCATION (c
);
13642 expr
= OMP_CLAUSE_OPERAND (c
, 0);
13643 if (TREE_CODE (expr
) == INTEGER_CST
)
13648 if (walk_tree (&expr
, computable_teams_clause
, NULL
, NULL
))
13650 *p
= integer_minus_one_node
;
13654 gimplify_omp_ctxp
= gimplify_omp_ctxp
->outer_context
;
13655 if (gimplify_expr (p
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
, false)
13658 gimplify_omp_ctxp
= target_ctx
;
13659 *p
= integer_minus_one_node
;
13662 gimplify_omp_ctxp
= target_ctx
;
13663 if (!DECL_P (expr
) && TREE_CODE (expr
) != TARGET_EXPR
)
13664 OMP_CLAUSE_OPERAND (c
, 0) = *p
;
13666 if (!omp_find_clause (OMP_TARGET_CLAUSES (target
), OMP_CLAUSE_THREAD_LIMIT
))
13668 c
= build_omp_clause (thread_limit_loc
, OMP_CLAUSE_THREAD_LIMIT
);
13669 OMP_CLAUSE_THREAD_LIMIT_EXPR (c
) = thread_limit
;
13670 OMP_CLAUSE_CHAIN (c
) = OMP_TARGET_CLAUSES (target
);
13671 OMP_TARGET_CLAUSES (target
) = c
;
13673 c
= build_omp_clause (num_teams_loc
, OMP_CLAUSE_NUM_TEAMS
);
13674 OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c
) = num_teams_upper
;
13675 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c
) = num_teams_lower
;
13676 OMP_CLAUSE_CHAIN (c
) = OMP_TARGET_CLAUSES (target
);
13677 OMP_TARGET_CLAUSES (target
) = c
;
13680 /* Gimplify the gross structure of several OMP constructs. */
13683 gimplify_omp_workshare (tree
*expr_p
, gimple_seq
*pre_p
)
13685 tree expr
= *expr_p
;
13687 gimple_seq body
= NULL
;
13688 enum omp_region_type ort
;
13690 switch (TREE_CODE (expr
))
13694 ort
= ORT_WORKSHARE
;
13697 ort
= ORT_TASKGROUP
;
13700 ort
= OMP_TARGET_COMBINED (expr
) ? ORT_COMBINED_TARGET
: ORT_TARGET
;
13703 ort
= ORT_ACC_KERNELS
;
13705 case OACC_PARALLEL
:
13706 ort
= ORT_ACC_PARALLEL
;
13709 ort
= ORT_ACC_SERIAL
;
13712 ort
= ORT_ACC_DATA
;
13714 case OMP_TARGET_DATA
:
13715 ort
= ORT_TARGET_DATA
;
13718 ort
= OMP_TEAMS_COMBINED (expr
) ? ORT_COMBINED_TEAMS
: ORT_TEAMS
;
13719 if (gimplify_omp_ctxp
== NULL
13720 || gimplify_omp_ctxp
->region_type
== ORT_IMPLICIT_TARGET
)
13721 ort
= (enum omp_region_type
) (ort
| ORT_HOST_TEAMS
);
13723 case OACC_HOST_DATA
:
13724 ort
= ORT_ACC_HOST_DATA
;
13727 gcc_unreachable ();
13730 bool save_in_omp_construct
= in_omp_construct
;
13731 if ((ort
& ORT_ACC
) == 0)
13732 in_omp_construct
= false;
13733 gimplify_scan_omp_clauses (&OMP_CLAUSES (expr
), pre_p
, ort
,
13735 if (TREE_CODE (expr
) == OMP_TARGET
)
13736 optimize_target_teams (expr
, pre_p
);
13737 if ((ort
& (ORT_TARGET
| ORT_TARGET_DATA
)) != 0
13738 || (ort
& ORT_HOST_TEAMS
) == ORT_HOST_TEAMS
)
13740 push_gimplify_context ();
13741 gimple
*g
= gimplify_and_return_first (OMP_BODY (expr
), &body
);
13742 if (gimple_code (g
) == GIMPLE_BIND
)
13743 pop_gimplify_context (g
);
13745 pop_gimplify_context (NULL
);
13746 if ((ort
& ORT_TARGET_DATA
) != 0)
13748 enum built_in_function end_ix
;
13749 switch (TREE_CODE (expr
))
13752 case OACC_HOST_DATA
:
13753 end_ix
= BUILT_IN_GOACC_DATA_END
;
13755 case OMP_TARGET_DATA
:
13756 end_ix
= BUILT_IN_GOMP_TARGET_END_DATA
;
13759 gcc_unreachable ();
13761 tree fn
= builtin_decl_explicit (end_ix
);
13762 g
= gimple_build_call (fn
, 0);
13763 gimple_seq cleanup
= NULL
;
13764 gimple_seq_add_stmt (&cleanup
, g
);
13765 g
= gimple_build_try (body
, cleanup
, GIMPLE_TRY_FINALLY
);
13767 gimple_seq_add_stmt (&body
, g
);
13771 gimplify_and_add (OMP_BODY (expr
), &body
);
13772 gimplify_adjust_omp_clauses (pre_p
, body
, &OMP_CLAUSES (expr
),
13774 in_omp_construct
= save_in_omp_construct
;
13776 switch (TREE_CODE (expr
))
13779 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_OACC_DATA
,
13780 OMP_CLAUSES (expr
));
13782 case OACC_HOST_DATA
:
13783 if (omp_find_clause (OMP_CLAUSES (expr
), OMP_CLAUSE_IF_PRESENT
))
13785 for (tree c
= OMP_CLAUSES (expr
); c
; c
= OMP_CLAUSE_CHAIN (c
))
13786 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_USE_DEVICE_PTR
)
13787 OMP_CLAUSE_USE_DEVICE_PTR_IF_PRESENT (c
) = 1;
13790 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_OACC_HOST_DATA
,
13791 OMP_CLAUSES (expr
));
13794 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_OACC_KERNELS
,
13795 OMP_CLAUSES (expr
));
13797 case OACC_PARALLEL
:
13798 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_OACC_PARALLEL
,
13799 OMP_CLAUSES (expr
));
13802 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_OACC_SERIAL
,
13803 OMP_CLAUSES (expr
));
13806 stmt
= gimple_build_omp_sections (body
, OMP_CLAUSES (expr
));
13809 stmt
= gimple_build_omp_single (body
, OMP_CLAUSES (expr
));
13812 stmt
= gimple_build_omp_scope (body
, OMP_CLAUSES (expr
));
13815 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_REGION
,
13816 OMP_CLAUSES (expr
));
13818 case OMP_TARGET_DATA
:
13819 /* Put use_device_{ptr,addr} clauses last, as map clauses are supposed
13820 to be evaluated before the use_device_{ptr,addr} clauses if they
13821 refer to the same variables. */
13823 tree use_device_clauses
;
13824 tree
*pc
, *uc
= &use_device_clauses
;
13825 for (pc
= &OMP_CLAUSES (expr
); *pc
; )
13826 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_USE_DEVICE_PTR
13827 || OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_USE_DEVICE_ADDR
)
13830 *pc
= OMP_CLAUSE_CHAIN (*pc
);
13831 uc
= &OMP_CLAUSE_CHAIN (*uc
);
13834 pc
= &OMP_CLAUSE_CHAIN (*pc
);
13836 *pc
= use_device_clauses
;
13837 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_DATA
,
13838 OMP_CLAUSES (expr
));
13842 stmt
= gimple_build_omp_teams (body
, OMP_CLAUSES (expr
));
13843 if ((ort
& ORT_HOST_TEAMS
) == ORT_HOST_TEAMS
)
13844 gimple_omp_teams_set_host (as_a
<gomp_teams
*> (stmt
), true);
13847 gcc_unreachable ();
13850 gimplify_seq_add_stmt (pre_p
, stmt
);
13851 *expr_p
= NULL_TREE
;
13854 /* Gimplify the gross structure of OpenACC enter/exit data, update, and OpenMP
13855 target update constructs. */
13858 gimplify_omp_target_update (tree
*expr_p
, gimple_seq
*pre_p
)
13860 tree expr
= *expr_p
;
13863 enum omp_region_type ort
= ORT_WORKSHARE
;
13865 switch (TREE_CODE (expr
))
13867 case OACC_ENTER_DATA
:
13868 kind
= GF_OMP_TARGET_KIND_OACC_ENTER_DATA
;
13871 case OACC_EXIT_DATA
:
13872 kind
= GF_OMP_TARGET_KIND_OACC_EXIT_DATA
;
13876 kind
= GF_OMP_TARGET_KIND_OACC_UPDATE
;
13879 case OMP_TARGET_UPDATE
:
13880 kind
= GF_OMP_TARGET_KIND_UPDATE
;
13882 case OMP_TARGET_ENTER_DATA
:
13883 kind
= GF_OMP_TARGET_KIND_ENTER_DATA
;
13885 case OMP_TARGET_EXIT_DATA
:
13886 kind
= GF_OMP_TARGET_KIND_EXIT_DATA
;
13889 gcc_unreachable ();
13891 gimplify_scan_omp_clauses (&OMP_STANDALONE_CLAUSES (expr
), pre_p
,
13892 ort
, TREE_CODE (expr
));
13893 gimplify_adjust_omp_clauses (pre_p
, NULL
, &OMP_STANDALONE_CLAUSES (expr
),
13895 if (TREE_CODE (expr
) == OACC_UPDATE
13896 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr
),
13897 OMP_CLAUSE_IF_PRESENT
))
13899 /* The runtime uses GOMP_MAP_{TO,FROM} to denote the if_present
13901 for (tree c
= OMP_STANDALONE_CLAUSES (expr
); c
; c
= OMP_CLAUSE_CHAIN (c
))
13902 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_MAP
)
13903 switch (OMP_CLAUSE_MAP_KIND (c
))
13905 case GOMP_MAP_FORCE_TO
:
13906 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_TO
);
13908 case GOMP_MAP_FORCE_FROM
:
13909 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_FROM
);
13915 else if (TREE_CODE (expr
) == OACC_EXIT_DATA
13916 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr
),
13917 OMP_CLAUSE_FINALIZE
))
13919 /* Use GOMP_MAP_DELETE/GOMP_MAP_FORCE_FROM to denote "finalize"
13921 bool have_clause
= false;
13922 for (tree c
= OMP_STANDALONE_CLAUSES (expr
); c
; c
= OMP_CLAUSE_CHAIN (c
))
13923 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_MAP
)
13924 switch (OMP_CLAUSE_MAP_KIND (c
))
13926 case GOMP_MAP_FROM
:
13927 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_FORCE_FROM
);
13928 have_clause
= true;
13930 case GOMP_MAP_RELEASE
:
13931 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_DELETE
);
13932 have_clause
= true;
13934 case GOMP_MAP_TO_PSET
:
13935 /* Fortran arrays with descriptors must map that descriptor when
13936 doing standalone "attach" operations (in OpenACC). In that
13937 case GOMP_MAP_TO_PSET appears by itself with no preceding
13938 clause (see trans-openmp.c:gfc_trans_omp_clauses). */
13940 case GOMP_MAP_POINTER
:
13941 /* TODO PR92929: we may see these here, but they'll always follow
13942 one of the clauses above, and will be handled by libgomp as
13943 one group, so no handling required here. */
13944 gcc_assert (have_clause
);
13946 case GOMP_MAP_DETACH
:
13947 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_FORCE_DETACH
);
13948 have_clause
= false;
13950 case GOMP_MAP_STRUCT
:
13951 have_clause
= false;
13954 gcc_unreachable ();
13957 stmt
= gimple_build_omp_target (NULL
, kind
, OMP_STANDALONE_CLAUSES (expr
));
13959 gimplify_seq_add_stmt (pre_p
, stmt
);
13960 *expr_p
= NULL_TREE
;
13963 /* A subroutine of gimplify_omp_atomic. The front end is supposed to have
13964 stabilized the lhs of the atomic operation as *ADDR. Return true if
13965 EXPR is this stabilized form. */
13968 goa_lhs_expr_p (tree expr
, tree addr
)
13970 /* Also include casts to other type variants. The C front end is fond
13971 of adding these for e.g. volatile variables. This is like
13972 STRIP_TYPE_NOPS but includes the main variant lookup. */
13973 STRIP_USELESS_TYPE_CONVERSION (expr
);
13975 if (TREE_CODE (expr
) == INDIRECT_REF
)
13977 expr
= TREE_OPERAND (expr
, 0);
13978 while (expr
!= addr
13979 && (CONVERT_EXPR_P (expr
)
13980 || TREE_CODE (expr
) == NON_LVALUE_EXPR
)
13981 && TREE_CODE (expr
) == TREE_CODE (addr
)
13982 && types_compatible_p (TREE_TYPE (expr
), TREE_TYPE (addr
)))
13984 expr
= TREE_OPERAND (expr
, 0);
13985 addr
= TREE_OPERAND (addr
, 0);
13989 return (TREE_CODE (addr
) == ADDR_EXPR
13990 && TREE_CODE (expr
) == ADDR_EXPR
13991 && TREE_OPERAND (addr
, 0) == TREE_OPERAND (expr
, 0));
13993 if (TREE_CODE (addr
) == ADDR_EXPR
&& expr
== TREE_OPERAND (addr
, 0))
13998 /* Walk *EXPR_P and replace appearances of *LHS_ADDR with LHS_VAR. If an
13999 expression does not involve the lhs, evaluate it into a temporary.
14000 Return 1 if the lhs appeared as a subexpression, 0 if it did not,
14001 or -1 if an error was encountered. */
14004 goa_stabilize_expr (tree
*expr_p
, gimple_seq
*pre_p
, tree lhs_addr
,
14005 tree lhs_var
, tree
&target_expr
, bool rhs
, int depth
)
14007 tree expr
= *expr_p
;
14010 if (goa_lhs_expr_p (expr
, lhs_addr
))
14016 if (is_gimple_val (expr
))
14019 /* Maximum depth of lhs in expression is for the
14020 __builtin_clear_padding (...), __builtin_clear_padding (...),
14021 __builtin_memcmp (&TARGET_EXPR <lhs, >, ...) == 0 ? ... : lhs; */
14025 switch (TREE_CODE_CLASS (TREE_CODE (expr
)))
14028 case tcc_comparison
:
14029 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 1), pre_p
, lhs_addr
,
14030 lhs_var
, target_expr
, true, depth
);
14033 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 0), pre_p
, lhs_addr
,
14034 lhs_var
, target_expr
, true, depth
);
14036 case tcc_expression
:
14037 switch (TREE_CODE (expr
))
14039 case TRUTH_ANDIF_EXPR
:
14040 case TRUTH_ORIF_EXPR
:
14041 case TRUTH_AND_EXPR
:
14042 case TRUTH_OR_EXPR
:
14043 case TRUTH_XOR_EXPR
:
14044 case BIT_INSERT_EXPR
:
14045 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 1), pre_p
,
14046 lhs_addr
, lhs_var
, target_expr
, true,
14049 case TRUTH_NOT_EXPR
:
14050 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 0), pre_p
,
14051 lhs_addr
, lhs_var
, target_expr
, true,
14055 if (pre_p
&& !goa_stabilize_expr (expr_p
, NULL
, lhs_addr
, lhs_var
,
14056 target_expr
, true, depth
))
14058 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 1), pre_p
,
14059 lhs_addr
, lhs_var
, target_expr
, true,
14061 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 0), pre_p
,
14062 lhs_addr
, lhs_var
, target_expr
, false,
14067 if (pre_p
&& !goa_stabilize_expr (expr_p
, NULL
, lhs_addr
, lhs_var
,
14068 target_expr
, true, depth
))
14070 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 0), pre_p
,
14071 lhs_addr
, lhs_var
, target_expr
, false,
14074 case COMPOUND_EXPR
:
14075 /* Break out any preevaluations from cp_build_modify_expr. */
14076 for (; TREE_CODE (expr
) == COMPOUND_EXPR
;
14077 expr
= TREE_OPERAND (expr
, 1))
14079 /* Special-case __builtin_clear_padding call before
14080 __builtin_memcmp. */
14081 if (TREE_CODE (TREE_OPERAND (expr
, 0)) == CALL_EXPR
)
14083 tree fndecl
= get_callee_fndecl (TREE_OPERAND (expr
, 0));
14085 && fndecl_built_in_p (fndecl
, BUILT_IN_CLEAR_PADDING
)
14086 && VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (expr
, 0)))
14088 || goa_stabilize_expr (&TREE_OPERAND (expr
, 0), NULL
,
14090 target_expr
, true, depth
)))
14094 saw_lhs
= goa_stabilize_expr (&TREE_OPERAND (expr
, 0),
14095 pre_p
, lhs_addr
, lhs_var
,
14096 target_expr
, true, depth
);
14097 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 1),
14098 pre_p
, lhs_addr
, lhs_var
,
14099 target_expr
, rhs
, depth
);
14105 gimplify_stmt (&TREE_OPERAND (expr
, 0), pre_p
);
14108 return goa_stabilize_expr (&expr
, pre_p
, lhs_addr
, lhs_var
,
14109 target_expr
, rhs
, depth
);
14111 return goa_stabilize_expr (expr_p
, pre_p
, lhs_addr
, lhs_var
,
14112 target_expr
, rhs
, depth
);
14114 if (!goa_stabilize_expr (&TREE_OPERAND (expr
, 0), NULL
, lhs_addr
,
14115 lhs_var
, target_expr
, true, depth
))
14117 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 0), pre_p
,
14118 lhs_addr
, lhs_var
, target_expr
, true,
14120 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 1), pre_p
,
14121 lhs_addr
, lhs_var
, target_expr
, true,
14123 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 2), pre_p
,
14124 lhs_addr
, lhs_var
, target_expr
, true,
14128 if (TARGET_EXPR_INITIAL (expr
))
14130 if (pre_p
&& !goa_stabilize_expr (expr_p
, NULL
, lhs_addr
,
14131 lhs_var
, target_expr
, true,
14134 if (expr
== target_expr
)
14138 saw_lhs
= goa_stabilize_expr (&TARGET_EXPR_INITIAL (expr
),
14139 pre_p
, lhs_addr
, lhs_var
,
14140 target_expr
, true, depth
);
14141 if (saw_lhs
&& target_expr
== NULL_TREE
&& pre_p
)
14142 target_expr
= expr
;
14150 case tcc_reference
:
14151 if (TREE_CODE (expr
) == BIT_FIELD_REF
14152 || TREE_CODE (expr
) == VIEW_CONVERT_EXPR
)
14153 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 0), pre_p
,
14154 lhs_addr
, lhs_var
, target_expr
, true,
14158 if (TREE_CODE (expr
) == CALL_EXPR
)
14160 if (tree fndecl
= get_callee_fndecl (expr
))
14161 if (fndecl_built_in_p (fndecl
, BUILT_IN_CLEAR_PADDING
)
14162 || fndecl_built_in_p (fndecl
, BUILT_IN_MEMCMP
))
14164 int nargs
= call_expr_nargs (expr
);
14165 for (int i
= 0; i
< nargs
; i
++)
14166 saw_lhs
|= goa_stabilize_expr (&CALL_EXPR_ARG (expr
, i
),
14167 pre_p
, lhs_addr
, lhs_var
,
14168 target_expr
, true, depth
);
14177 if (saw_lhs
== 0 && pre_p
)
14179 enum gimplify_status gs
;
14180 if (TREE_CODE (expr
) == CALL_EXPR
&& VOID_TYPE_P (TREE_TYPE (expr
)))
14182 gimplify_stmt (&expr
, pre_p
);
14186 gs
= gimplify_expr (expr_p
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
14188 gs
= gimplify_expr (expr_p
, pre_p
, NULL
, is_gimple_lvalue
, fb_lvalue
);
14189 if (gs
!= GS_ALL_DONE
)
14196 /* Gimplify an OMP_ATOMIC statement. */
14198 static enum gimplify_status
14199 gimplify_omp_atomic (tree
*expr_p
, gimple_seq
*pre_p
)
14201 tree addr
= TREE_OPERAND (*expr_p
, 0);
14202 tree rhs
= TREE_CODE (*expr_p
) == OMP_ATOMIC_READ
14203 ? NULL
: TREE_OPERAND (*expr_p
, 1);
14204 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr
)));
14206 gomp_atomic_load
*loadstmt
;
14207 gomp_atomic_store
*storestmt
;
14208 tree target_expr
= NULL_TREE
;
14210 tmp_load
= create_tmp_reg (type
);
14212 && goa_stabilize_expr (&rhs
, pre_p
, addr
, tmp_load
, target_expr
,
14216 if (gimplify_expr (&addr
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
)
14220 loadstmt
= gimple_build_omp_atomic_load (tmp_load
, addr
,
14221 OMP_ATOMIC_MEMORY_ORDER (*expr_p
));
14222 gimplify_seq_add_stmt (pre_p
, loadstmt
);
14225 /* BIT_INSERT_EXPR is not valid for non-integral bitfield
14226 representatives. Use BIT_FIELD_REF on the lhs instead. */
14228 if (TREE_CODE (rhs
) == COND_EXPR
)
14229 rhsarg
= TREE_OPERAND (rhs
, 1);
14230 if (TREE_CODE (rhsarg
) == BIT_INSERT_EXPR
14231 && !INTEGRAL_TYPE_P (TREE_TYPE (tmp_load
)))
14233 tree bitpos
= TREE_OPERAND (rhsarg
, 2);
14234 tree op1
= TREE_OPERAND (rhsarg
, 1);
14236 tree tmp_store
= tmp_load
;
14237 if (TREE_CODE (*expr_p
) == OMP_ATOMIC_CAPTURE_OLD
)
14238 tmp_store
= get_initialized_tmp_var (tmp_load
, pre_p
);
14239 if (INTEGRAL_TYPE_P (TREE_TYPE (op1
)))
14240 bitsize
= bitsize_int (TYPE_PRECISION (TREE_TYPE (op1
)));
14242 bitsize
= TYPE_SIZE (TREE_TYPE (op1
));
14243 gcc_assert (TREE_OPERAND (rhsarg
, 0) == tmp_load
);
14244 tree t
= build2_loc (EXPR_LOCATION (rhsarg
),
14245 MODIFY_EXPR
, void_type_node
,
14246 build3_loc (EXPR_LOCATION (rhsarg
),
14247 BIT_FIELD_REF
, TREE_TYPE (op1
),
14248 tmp_store
, bitsize
, bitpos
), op1
);
14249 if (TREE_CODE (rhs
) == COND_EXPR
)
14250 t
= build3_loc (EXPR_LOCATION (rhs
), COND_EXPR
, void_type_node
,
14251 TREE_OPERAND (rhs
, 0), t
, void_node
);
14252 gimplify_and_add (t
, pre_p
);
14255 bool save_allow_rhs_cond_expr
= gimplify_ctxp
->allow_rhs_cond_expr
;
14256 if (TREE_CODE (rhs
) == COND_EXPR
)
14257 gimplify_ctxp
->allow_rhs_cond_expr
= true;
14258 enum gimplify_status gs
= gimplify_expr (&rhs
, pre_p
, NULL
,
14259 is_gimple_val
, fb_rvalue
);
14260 gimplify_ctxp
->allow_rhs_cond_expr
= save_allow_rhs_cond_expr
;
14261 if (gs
!= GS_ALL_DONE
)
14265 if (TREE_CODE (*expr_p
) == OMP_ATOMIC_READ
)
14268 = gimple_build_omp_atomic_store (rhs
, OMP_ATOMIC_MEMORY_ORDER (*expr_p
));
14269 if (TREE_CODE (*expr_p
) != OMP_ATOMIC_READ
&& OMP_ATOMIC_WEAK (*expr_p
))
14271 gimple_omp_atomic_set_weak (loadstmt
);
14272 gimple_omp_atomic_set_weak (storestmt
);
14274 gimplify_seq_add_stmt (pre_p
, storestmt
);
14275 switch (TREE_CODE (*expr_p
))
14277 case OMP_ATOMIC_READ
:
14278 case OMP_ATOMIC_CAPTURE_OLD
:
14279 *expr_p
= tmp_load
;
14280 gimple_omp_atomic_set_need_value (loadstmt
);
14282 case OMP_ATOMIC_CAPTURE_NEW
:
14284 gimple_omp_atomic_set_need_value (storestmt
);
14291 return GS_ALL_DONE
;
14294 /* Gimplify a TRANSACTION_EXPR. This involves gimplification of the
14295 body, and adding some EH bits. */
14297 static enum gimplify_status
14298 gimplify_transaction (tree
*expr_p
, gimple_seq
*pre_p
)
14300 tree expr
= *expr_p
, temp
, tbody
= TRANSACTION_EXPR_BODY (expr
);
14302 gtransaction
*trans_stmt
;
14303 gimple_seq body
= NULL
;
14306 /* Wrap the transaction body in a BIND_EXPR so we have a context
14307 where to put decls for OMP. */
14308 if (TREE_CODE (tbody
) != BIND_EXPR
)
14310 tree bind
= build3 (BIND_EXPR
, void_type_node
, NULL
, tbody
, NULL
);
14311 TREE_SIDE_EFFECTS (bind
) = 1;
14312 SET_EXPR_LOCATION (bind
, EXPR_LOCATION (tbody
));
14313 TRANSACTION_EXPR_BODY (expr
) = bind
;
14316 push_gimplify_context ();
14317 temp
= voidify_wrapper_expr (*expr_p
, NULL
);
14319 body_stmt
= gimplify_and_return_first (TRANSACTION_EXPR_BODY (expr
), &body
);
14320 pop_gimplify_context (body_stmt
);
14322 trans_stmt
= gimple_build_transaction (body
);
14323 if (TRANSACTION_EXPR_OUTER (expr
))
14324 subcode
= GTMA_IS_OUTER
;
14325 else if (TRANSACTION_EXPR_RELAXED (expr
))
14326 subcode
= GTMA_IS_RELAXED
;
14327 gimple_transaction_set_subcode (trans_stmt
, subcode
);
14329 gimplify_seq_add_stmt (pre_p
, trans_stmt
);
14337 *expr_p
= NULL_TREE
;
14338 return GS_ALL_DONE
;
14341 /* Gimplify an OMP_ORDERED construct. EXPR is the tree version. BODY
14342 is the OMP_BODY of the original EXPR (which has already been
14343 gimplified so it's not present in the EXPR).
14345 Return the gimplified GIMPLE_OMP_ORDERED tuple. */
14348 gimplify_omp_ordered (tree expr
, gimple_seq body
)
14353 tree source_c
= NULL_TREE
;
14354 tree sink_c
= NULL_TREE
;
14356 if (gimplify_omp_ctxp
)
14358 for (c
= OMP_ORDERED_CLAUSES (expr
); c
; c
= OMP_CLAUSE_CHAIN (c
))
14359 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEPEND
14360 && gimplify_omp_ctxp
->loop_iter_var
.is_empty ()
14361 && (OMP_CLAUSE_DEPEND_KIND (c
) == OMP_CLAUSE_DEPEND_SINK
14362 || OMP_CLAUSE_DEPEND_KIND (c
) == OMP_CLAUSE_DEPEND_SOURCE
))
14364 error_at (OMP_CLAUSE_LOCATION (c
),
14365 "%<ordered%> construct with %<depend%> clause must be "
14366 "closely nested inside a loop with %<ordered%> clause "
14367 "with a parameter");
14370 else if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEPEND
14371 && OMP_CLAUSE_DEPEND_KIND (c
) == OMP_CLAUSE_DEPEND_SINK
)
14374 for (decls
= OMP_CLAUSE_DECL (c
), i
= 0;
14375 decls
&& TREE_CODE (decls
) == TREE_LIST
;
14376 decls
= TREE_CHAIN (decls
), ++i
)
14377 if (i
>= gimplify_omp_ctxp
->loop_iter_var
.length () / 2)
14379 else if (TREE_VALUE (decls
)
14380 != gimplify_omp_ctxp
->loop_iter_var
[2 * i
])
14382 error_at (OMP_CLAUSE_LOCATION (c
),
14383 "variable %qE is not an iteration "
14384 "of outermost loop %d, expected %qE",
14385 TREE_VALUE (decls
), i
+ 1,
14386 gimplify_omp_ctxp
->loop_iter_var
[2 * i
]);
14392 = gimplify_omp_ctxp
->loop_iter_var
[2 * i
+ 1];
14393 if (!fail
&& i
!= gimplify_omp_ctxp
->loop_iter_var
.length () / 2)
14395 error_at (OMP_CLAUSE_LOCATION (c
),
14396 "number of variables in %<depend%> clause with "
14397 "%<sink%> modifier does not match number of "
14398 "iteration variables");
14403 else if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEPEND
14404 && OMP_CLAUSE_DEPEND_KIND (c
) == OMP_CLAUSE_DEPEND_SOURCE
)
14408 error_at (OMP_CLAUSE_LOCATION (c
),
14409 "more than one %<depend%> clause with %<source%> "
14410 "modifier on an %<ordered%> construct");
14417 if (source_c
&& sink_c
)
14419 error_at (OMP_CLAUSE_LOCATION (source_c
),
14420 "%<depend%> clause with %<source%> modifier specified "
14421 "together with %<depend%> clauses with %<sink%> modifier "
14422 "on the same construct");
14427 return gimple_build_nop ();
14428 return gimple_build_omp_ordered (body
, OMP_ORDERED_CLAUSES (expr
));
14431 /* Convert the GENERIC expression tree *EXPR_P to GIMPLE. If the
14432 expression produces a value to be used as an operand inside a GIMPLE
14433 statement, the value will be stored back in *EXPR_P. This value will
14434 be a tree of class tcc_declaration, tcc_constant, tcc_reference or
14435 an SSA_NAME. The corresponding sequence of GIMPLE statements is
14436 emitted in PRE_P and POST_P.
14438 Additionally, this process may overwrite parts of the input
14439 expression during gimplification. Ideally, it should be
14440 possible to do non-destructive gimplification.
14442 EXPR_P points to the GENERIC expression to convert to GIMPLE. If
14443 the expression needs to evaluate to a value to be used as
14444 an operand in a GIMPLE statement, this value will be stored in
14445 *EXPR_P on exit. This happens when the caller specifies one
14446 of fb_lvalue or fb_rvalue fallback flags.
14448 PRE_P will contain the sequence of GIMPLE statements corresponding
14449 to the evaluation of EXPR and all the side-effects that must
14450 be executed before the main expression. On exit, the last
14451 statement of PRE_P is the core statement being gimplified. For
14452 instance, when gimplifying 'if (++a)' the last statement in
14453 PRE_P will be 'if (t.1)' where t.1 is the result of
14454 pre-incrementing 'a'.
14456 POST_P will contain the sequence of GIMPLE statements corresponding
14457 to the evaluation of all the side-effects that must be executed
14458 after the main expression. If this is NULL, the post
14459 side-effects are stored at the end of PRE_P.
14461 The reason why the output is split in two is to handle post
14462 side-effects explicitly. In some cases, an expression may have
14463 inner and outer post side-effects which need to be emitted in
14464 an order different from the one given by the recursive
14465 traversal. For instance, for the expression (*p--)++ the post
14466 side-effects of '--' must actually occur *after* the post
14467 side-effects of '++'. However, gimplification will first visit
14468 the inner expression, so if a separate POST sequence was not
14469 used, the resulting sequence would be:
14476 However, the post-decrement operation in line #2 must not be
14477 evaluated until after the store to *p at line #4, so the
14478 correct sequence should be:
14485 So, by specifying a separate post queue, it is possible
14486 to emit the post side-effects in the correct order.
14487 If POST_P is NULL, an internal queue will be used. Before
14488 returning to the caller, the sequence POST_P is appended to
14489 the main output sequence PRE_P.
14491 GIMPLE_TEST_F points to a function that takes a tree T and
14492 returns nonzero if T is in the GIMPLE form requested by the
14493 caller. The GIMPLE predicates are in gimple.c.
14495 FALLBACK tells the function what sort of a temporary we want if
14496 gimplification cannot produce an expression that complies with
14499 fb_none means that no temporary should be generated
14500 fb_rvalue means that an rvalue is OK to generate
14501 fb_lvalue means that an lvalue is OK to generate
14502 fb_either means that either is OK, but an lvalue is preferable.
14503 fb_mayfail means that gimplification may fail (in which case
14504 GS_ERROR will be returned)
14506 The return value is either GS_ERROR or GS_ALL_DONE, since this
14507 function iterates until EXPR is completely gimplified or an error
14510 enum gimplify_status
14511 gimplify_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
14512 bool (*gimple_test_f
) (tree
), fallback_t fallback
)
14515 gimple_seq internal_pre
= NULL
;
14516 gimple_seq internal_post
= NULL
;
14519 location_t saved_location
;
14520 enum gimplify_status ret
;
14521 gimple_stmt_iterator pre_last_gsi
, post_last_gsi
;
14524 save_expr
= *expr_p
;
14525 if (save_expr
== NULL_TREE
)
14526 return GS_ALL_DONE
;
14528 /* If we are gimplifying a top-level statement, PRE_P must be valid. */
14529 is_statement
= gimple_test_f
== is_gimple_stmt
;
14531 gcc_assert (pre_p
);
14533 /* Consistency checks. */
14534 if (gimple_test_f
== is_gimple_reg
)
14535 gcc_assert (fallback
& (fb_rvalue
| fb_lvalue
));
14536 else if (gimple_test_f
== is_gimple_val
14537 || gimple_test_f
== is_gimple_call_addr
14538 || gimple_test_f
== is_gimple_condexpr
14539 || gimple_test_f
== is_gimple_condexpr_for_cond
14540 || gimple_test_f
== is_gimple_mem_rhs
14541 || gimple_test_f
== is_gimple_mem_rhs_or_call
14542 || gimple_test_f
== is_gimple_reg_rhs
14543 || gimple_test_f
== is_gimple_reg_rhs_or_call
14544 || gimple_test_f
== is_gimple_asm_val
14545 || gimple_test_f
== is_gimple_mem_ref_addr
)
14546 gcc_assert (fallback
& fb_rvalue
);
14547 else if (gimple_test_f
== is_gimple_min_lval
14548 || gimple_test_f
== is_gimple_lvalue
)
14549 gcc_assert (fallback
& fb_lvalue
);
14550 else if (gimple_test_f
== is_gimple_addressable
)
14551 gcc_assert (fallback
& fb_either
);
14552 else if (gimple_test_f
== is_gimple_stmt
)
14553 gcc_assert (fallback
== fb_none
);
14556 /* We should have recognized the GIMPLE_TEST_F predicate to
14557 know what kind of fallback to use in case a temporary is
14558 needed to hold the value or address of *EXPR_P. */
14559 gcc_unreachable ();
14562 /* We used to check the predicate here and return immediately if it
14563 succeeds. This is wrong; the design is for gimplification to be
14564 idempotent, and for the predicates to only test for valid forms, not
14565 whether they are fully simplified. */
14567 pre_p
= &internal_pre
;
14569 if (post_p
== NULL
)
14570 post_p
= &internal_post
;
14572 /* Remember the last statements added to PRE_P and POST_P. Every
14573 new statement added by the gimplification helpers needs to be
14574 annotated with location information. To centralize the
14575 responsibility, we remember the last statement that had been
14576 added to both queues before gimplifying *EXPR_P. If
14577 gimplification produces new statements in PRE_P and POST_P, those
14578 statements will be annotated with the same location information
14580 pre_last_gsi
= gsi_last (*pre_p
);
14581 post_last_gsi
= gsi_last (*post_p
);
14583 saved_location
= input_location
;
14584 if (save_expr
!= error_mark_node
14585 && EXPR_HAS_LOCATION (*expr_p
))
14586 input_location
= EXPR_LOCATION (*expr_p
);
14588 /* Loop over the specific gimplifiers until the toplevel node
14589 remains the same. */
14592 /* Strip away as many useless type conversions as possible
14593 at the toplevel. */
14594 STRIP_USELESS_TYPE_CONVERSION (*expr_p
);
14596 /* Remember the expr. */
14597 save_expr
= *expr_p
;
14599 /* Die, die, die, my darling. */
14600 if (error_operand_p (save_expr
))
14606 /* Do any language-specific gimplification. */
14607 ret
= ((enum gimplify_status
)
14608 lang_hooks
.gimplify_expr (expr_p
, pre_p
, post_p
));
14611 if (*expr_p
== NULL_TREE
)
14613 if (*expr_p
!= save_expr
)
14616 else if (ret
!= GS_UNHANDLED
)
14619 /* Make sure that all the cases set 'ret' appropriately. */
14620 ret
= GS_UNHANDLED
;
14621 switch (TREE_CODE (*expr_p
))
14623 /* First deal with the special cases. */
14625 case POSTINCREMENT_EXPR
:
14626 case POSTDECREMENT_EXPR
:
14627 case PREINCREMENT_EXPR
:
14628 case PREDECREMENT_EXPR
:
14629 ret
= gimplify_self_mod_expr (expr_p
, pre_p
, post_p
,
14630 fallback
!= fb_none
,
14631 TREE_TYPE (*expr_p
));
14634 case VIEW_CONVERT_EXPR
:
14635 if ((fallback
& fb_rvalue
)
14636 && is_gimple_reg_type (TREE_TYPE (*expr_p
))
14637 && is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (*expr_p
, 0))))
14639 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
14640 post_p
, is_gimple_val
, fb_rvalue
);
14641 recalculate_side_effects (*expr_p
);
14647 case ARRAY_RANGE_REF
:
14648 case REALPART_EXPR
:
14649 case IMAGPART_EXPR
:
14650 case COMPONENT_REF
:
14651 ret
= gimplify_compound_lval (expr_p
, pre_p
, post_p
,
14652 fallback
? fallback
: fb_rvalue
);
14656 ret
= gimplify_cond_expr (expr_p
, pre_p
, fallback
);
14658 /* C99 code may assign to an array in a structure value of a
14659 conditional expression, and this has undefined behavior
14660 only on execution, so create a temporary if an lvalue is
14662 if (fallback
== fb_lvalue
)
14664 *expr_p
= get_initialized_tmp_var (*expr_p
, pre_p
, post_p
, false);
14665 mark_addressable (*expr_p
);
14671 ret
= gimplify_call_expr (expr_p
, pre_p
, fallback
!= fb_none
);
14673 /* C99 code may assign to an array in a structure returned
14674 from a function, and this has undefined behavior only on
14675 execution, so create a temporary if an lvalue is
14677 if (fallback
== fb_lvalue
)
14679 *expr_p
= get_initialized_tmp_var (*expr_p
, pre_p
, post_p
, false);
14680 mark_addressable (*expr_p
);
14686 gcc_unreachable ();
14688 case COMPOUND_EXPR
:
14689 ret
= gimplify_compound_expr (expr_p
, pre_p
, fallback
!= fb_none
);
14692 case COMPOUND_LITERAL_EXPR
:
14693 ret
= gimplify_compound_literal_expr (expr_p
, pre_p
,
14694 gimple_test_f
, fallback
);
14699 ret
= gimplify_modify_expr (expr_p
, pre_p
, post_p
,
14700 fallback
!= fb_none
);
14703 case TRUTH_ANDIF_EXPR
:
14704 case TRUTH_ORIF_EXPR
:
14706 /* Preserve the original type of the expression and the
14707 source location of the outer expression. */
14708 tree org_type
= TREE_TYPE (*expr_p
);
14709 *expr_p
= gimple_boolify (*expr_p
);
14710 *expr_p
= build3_loc (input_location
, COND_EXPR
,
14714 org_type
, boolean_true_node
),
14717 org_type
, boolean_false_node
));
14722 case TRUTH_NOT_EXPR
:
14724 tree type
= TREE_TYPE (*expr_p
);
14725 /* The parsers are careful to generate TRUTH_NOT_EXPR
14726 only with operands that are always zero or one.
14727 We do not fold here but handle the only interesting case
14728 manually, as fold may re-introduce the TRUTH_NOT_EXPR. */
14729 *expr_p
= gimple_boolify (*expr_p
);
14730 if (TYPE_PRECISION (TREE_TYPE (*expr_p
)) == 1)
14731 *expr_p
= build1_loc (input_location
, BIT_NOT_EXPR
,
14732 TREE_TYPE (*expr_p
),
14733 TREE_OPERAND (*expr_p
, 0));
14735 *expr_p
= build2_loc (input_location
, BIT_XOR_EXPR
,
14736 TREE_TYPE (*expr_p
),
14737 TREE_OPERAND (*expr_p
, 0),
14738 build_int_cst (TREE_TYPE (*expr_p
), 1));
14739 if (!useless_type_conversion_p (type
, TREE_TYPE (*expr_p
)))
14740 *expr_p
= fold_convert_loc (input_location
, type
, *expr_p
);
14746 ret
= gimplify_addr_expr (expr_p
, pre_p
, post_p
);
14749 case ANNOTATE_EXPR
:
14751 tree cond
= TREE_OPERAND (*expr_p
, 0);
14752 tree kind
= TREE_OPERAND (*expr_p
, 1);
14753 tree data
= TREE_OPERAND (*expr_p
, 2);
14754 tree type
= TREE_TYPE (cond
);
14755 if (!INTEGRAL_TYPE_P (type
))
14761 tree tmp
= create_tmp_var (type
);
14762 gimplify_arg (&cond
, pre_p
, EXPR_LOCATION (*expr_p
));
14764 = gimple_build_call_internal (IFN_ANNOTATE
, 3, cond
, kind
, data
);
14765 gimple_call_set_lhs (call
, tmp
);
14766 gimplify_seq_add_stmt (pre_p
, call
);
14773 ret
= gimplify_va_arg_expr (expr_p
, pre_p
, post_p
);
14777 if (IS_EMPTY_STMT (*expr_p
))
14783 if (VOID_TYPE_P (TREE_TYPE (*expr_p
))
14784 || fallback
== fb_none
)
14786 /* Just strip a conversion to void (or in void context) and
14788 *expr_p
= TREE_OPERAND (*expr_p
, 0);
14793 ret
= gimplify_conversion (expr_p
);
14794 if (ret
== GS_ERROR
)
14796 if (*expr_p
!= save_expr
)
14800 case FIX_TRUNC_EXPR
:
14801 /* unary_expr: ... | '(' cast ')' val | ... */
14802 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
14803 is_gimple_val
, fb_rvalue
);
14804 recalculate_side_effects (*expr_p
);
14809 bool volatilep
= TREE_THIS_VOLATILE (*expr_p
);
14810 bool notrap
= TREE_THIS_NOTRAP (*expr_p
);
14811 tree saved_ptr_type
= TREE_TYPE (TREE_OPERAND (*expr_p
, 0));
14813 *expr_p
= fold_indirect_ref_loc (input_location
, *expr_p
);
14814 if (*expr_p
!= save_expr
)
14820 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
14821 is_gimple_reg
, fb_rvalue
);
14822 if (ret
== GS_ERROR
)
14825 recalculate_side_effects (*expr_p
);
14826 *expr_p
= fold_build2_loc (input_location
, MEM_REF
,
14827 TREE_TYPE (*expr_p
),
14828 TREE_OPERAND (*expr_p
, 0),
14829 build_int_cst (saved_ptr_type
, 0));
14830 TREE_THIS_VOLATILE (*expr_p
) = volatilep
;
14831 TREE_THIS_NOTRAP (*expr_p
) = notrap
;
14836 /* We arrive here through the various re-gimplifcation paths. */
14838 /* First try re-folding the whole thing. */
14839 tmp
= fold_binary (MEM_REF
, TREE_TYPE (*expr_p
),
14840 TREE_OPERAND (*expr_p
, 0),
14841 TREE_OPERAND (*expr_p
, 1));
14844 REF_REVERSE_STORAGE_ORDER (tmp
)
14845 = REF_REVERSE_STORAGE_ORDER (*expr_p
);
14847 recalculate_side_effects (*expr_p
);
14851 /* Avoid re-gimplifying the address operand if it is already
14852 in suitable form. Re-gimplifying would mark the address
14853 operand addressable. Always gimplify when not in SSA form
14854 as we still may have to gimplify decls with value-exprs. */
14855 if (!gimplify_ctxp
|| !gimple_in_ssa_p (cfun
)
14856 || !is_gimple_mem_ref_addr (TREE_OPERAND (*expr_p
, 0)))
14858 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
14859 is_gimple_mem_ref_addr
, fb_rvalue
);
14860 if (ret
== GS_ERROR
)
14863 recalculate_side_effects (*expr_p
);
14867 /* Constants need not be gimplified. */
14874 /* Drop the overflow flag on constants, we do not want
14875 that in the GIMPLE IL. */
14876 if (TREE_OVERFLOW_P (*expr_p
))
14877 *expr_p
= drop_tree_overflow (*expr_p
);
14882 /* If we require an lvalue, such as for ADDR_EXPR, retain the
14883 CONST_DECL node. Otherwise the decl is replaceable by its
14885 /* ??? Should be == fb_lvalue, but ADDR_EXPR passes fb_either. */
14886 if (fallback
& fb_lvalue
)
14890 *expr_p
= DECL_INITIAL (*expr_p
);
14896 ret
= gimplify_decl_expr (expr_p
, pre_p
);
14900 ret
= gimplify_bind_expr (expr_p
, pre_p
);
14904 ret
= gimplify_loop_expr (expr_p
, pre_p
);
14908 ret
= gimplify_switch_expr (expr_p
, pre_p
);
14912 ret
= gimplify_exit_expr (expr_p
);
14916 /* If the target is not LABEL, then it is a computed jump
14917 and the target needs to be gimplified. */
14918 if (TREE_CODE (GOTO_DESTINATION (*expr_p
)) != LABEL_DECL
)
14920 ret
= gimplify_expr (&GOTO_DESTINATION (*expr_p
), pre_p
,
14921 NULL
, is_gimple_val
, fb_rvalue
);
14922 if (ret
== GS_ERROR
)
14925 gimplify_seq_add_stmt (pre_p
,
14926 gimple_build_goto (GOTO_DESTINATION (*expr_p
)));
14931 gimplify_seq_add_stmt (pre_p
,
14932 gimple_build_predict (PREDICT_EXPR_PREDICTOR (*expr_p
),
14933 PREDICT_EXPR_OUTCOME (*expr_p
)));
14938 ret
= gimplify_label_expr (expr_p
, pre_p
);
14939 label
= LABEL_EXPR_LABEL (*expr_p
);
14940 gcc_assert (decl_function_context (label
) == current_function_decl
);
14942 /* If the label is used in a goto statement, or address of the label
14943 is taken, we need to unpoison all variables that were seen so far.
14944 Doing so would prevent us from reporting a false positives. */
14945 if (asan_poisoned_variables
14946 && asan_used_labels
!= NULL
14947 && asan_used_labels
->contains (label
)
14948 && !gimplify_omp_ctxp
)
14949 asan_poison_variables (asan_poisoned_variables
, false, pre_p
);
14952 case CASE_LABEL_EXPR
:
14953 ret
= gimplify_case_label_expr (expr_p
, pre_p
);
14955 if (gimplify_ctxp
->live_switch_vars
)
14956 asan_poison_variables (gimplify_ctxp
->live_switch_vars
, false,
14961 ret
= gimplify_return_expr (*expr_p
, pre_p
);
14965 /* Don't reduce this in place; let gimplify_init_constructor work its
14966 magic. Buf if we're just elaborating this for side effects, just
14967 gimplify any element that has side-effects. */
14968 if (fallback
== fb_none
)
14970 unsigned HOST_WIDE_INT ix
;
14972 tree temp
= NULL_TREE
;
14973 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (*expr_p
), ix
, val
)
14974 if (TREE_SIDE_EFFECTS (val
))
14975 append_to_statement_list (val
, &temp
);
14978 ret
= temp
? GS_OK
: GS_ALL_DONE
;
14980 /* C99 code may assign to an array in a constructed
14981 structure or union, and this has undefined behavior only
14982 on execution, so create a temporary if an lvalue is
14984 else if (fallback
== fb_lvalue
)
14986 *expr_p
= get_initialized_tmp_var (*expr_p
, pre_p
, post_p
, false);
14987 mark_addressable (*expr_p
);
14994 /* The following are special cases that are not handled by the
14995 original GIMPLE grammar. */
14997 /* SAVE_EXPR nodes are converted into a GIMPLE identifier and
15000 ret
= gimplify_save_expr (expr_p
, pre_p
, post_p
);
15003 case BIT_FIELD_REF
:
15004 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
15005 post_p
, is_gimple_lvalue
, fb_either
);
15006 recalculate_side_effects (*expr_p
);
15009 case TARGET_MEM_REF
:
15011 enum gimplify_status r0
= GS_ALL_DONE
, r1
= GS_ALL_DONE
;
15013 if (TMR_BASE (*expr_p
))
15014 r0
= gimplify_expr (&TMR_BASE (*expr_p
), pre_p
,
15015 post_p
, is_gimple_mem_ref_addr
, fb_either
);
15016 if (TMR_INDEX (*expr_p
))
15017 r1
= gimplify_expr (&TMR_INDEX (*expr_p
), pre_p
,
15018 post_p
, is_gimple_val
, fb_rvalue
);
15019 if (TMR_INDEX2 (*expr_p
))
15020 r1
= gimplify_expr (&TMR_INDEX2 (*expr_p
), pre_p
,
15021 post_p
, is_gimple_val
, fb_rvalue
);
15022 /* TMR_STEP and TMR_OFFSET are always integer constants. */
15023 ret
= MIN (r0
, r1
);
15027 case NON_LVALUE_EXPR
:
15028 /* This should have been stripped above. */
15029 gcc_unreachable ();
15032 ret
= gimplify_asm_expr (expr_p
, pre_p
, post_p
);
15035 case TRY_FINALLY_EXPR
:
15036 case TRY_CATCH_EXPR
:
15038 gimple_seq eval
, cleanup
;
15041 /* Calls to destructors are generated automatically in FINALLY/CATCH
15042 block. They should have location as UNKNOWN_LOCATION. However,
15043 gimplify_call_expr will reset these call stmts to input_location
15044 if it finds stmt's location is unknown. To prevent resetting for
15045 destructors, we set the input_location to unknown.
15046 Note that this only affects the destructor calls in FINALLY/CATCH
15047 block, and will automatically reset to its original value by the
15048 end of gimplify_expr. */
15049 input_location
= UNKNOWN_LOCATION
;
15050 eval
= cleanup
= NULL
;
15051 gimplify_and_add (TREE_OPERAND (*expr_p
, 0), &eval
);
15052 if (TREE_CODE (*expr_p
) == TRY_FINALLY_EXPR
15053 && TREE_CODE (TREE_OPERAND (*expr_p
, 1)) == EH_ELSE_EXPR
)
15055 gimple_seq n
= NULL
, e
= NULL
;
15056 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p
, 1),
15058 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p
, 1),
15060 if (!gimple_seq_empty_p (n
) && !gimple_seq_empty_p (e
))
15062 geh_else
*stmt
= gimple_build_eh_else (n
, e
);
15063 gimple_seq_add_stmt (&cleanup
, stmt
);
15067 gimplify_and_add (TREE_OPERAND (*expr_p
, 1), &cleanup
);
15068 /* Don't create bogus GIMPLE_TRY with empty cleanup. */
15069 if (gimple_seq_empty_p (cleanup
))
15071 gimple_seq_add_seq (pre_p
, eval
);
15075 try_
= gimple_build_try (eval
, cleanup
,
15076 TREE_CODE (*expr_p
) == TRY_FINALLY_EXPR
15077 ? GIMPLE_TRY_FINALLY
15078 : GIMPLE_TRY_CATCH
);
15079 if (EXPR_HAS_LOCATION (save_expr
))
15080 gimple_set_location (try_
, EXPR_LOCATION (save_expr
));
15081 else if (LOCATION_LOCUS (saved_location
) != UNKNOWN_LOCATION
)
15082 gimple_set_location (try_
, saved_location
);
15083 if (TREE_CODE (*expr_p
) == TRY_CATCH_EXPR
)
15084 gimple_try_set_catch_is_cleanup (try_
,
15085 TRY_CATCH_IS_CLEANUP (*expr_p
));
15086 gimplify_seq_add_stmt (pre_p
, try_
);
15091 case CLEANUP_POINT_EXPR
:
15092 ret
= gimplify_cleanup_point_expr (expr_p
, pre_p
);
15096 ret
= gimplify_target_expr (expr_p
, pre_p
, post_p
);
15102 gimple_seq handler
= NULL
;
15103 gimplify_and_add (CATCH_BODY (*expr_p
), &handler
);
15104 c
= gimple_build_catch (CATCH_TYPES (*expr_p
), handler
);
15105 gimplify_seq_add_stmt (pre_p
, c
);
15110 case EH_FILTER_EXPR
:
15113 gimple_seq failure
= NULL
;
15115 gimplify_and_add (EH_FILTER_FAILURE (*expr_p
), &failure
);
15116 ehf
= gimple_build_eh_filter (EH_FILTER_TYPES (*expr_p
), failure
);
15117 copy_warning (ehf
, *expr_p
);
15118 gimplify_seq_add_stmt (pre_p
, ehf
);
15125 enum gimplify_status r0
, r1
;
15126 r0
= gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p
), pre_p
,
15127 post_p
, is_gimple_val
, fb_rvalue
);
15128 r1
= gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p
), pre_p
,
15129 post_p
, is_gimple_val
, fb_rvalue
);
15130 TREE_SIDE_EFFECTS (*expr_p
) = 0;
15131 ret
= MIN (r0
, r1
);
15136 /* We get here when taking the address of a label. We mark
15137 the label as "forced"; meaning it can never be removed and
15138 it is a potential target for any computed goto. */
15139 FORCED_LABEL (*expr_p
) = 1;
15143 case STATEMENT_LIST
:
15144 ret
= gimplify_statement_list (expr_p
, pre_p
);
15147 case WITH_SIZE_EXPR
:
15149 gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
15150 post_p
== &internal_post
? NULL
: post_p
,
15151 gimple_test_f
, fallback
);
15152 gimplify_expr (&TREE_OPERAND (*expr_p
, 1), pre_p
, post_p
,
15153 is_gimple_val
, fb_rvalue
);
15160 ret
= gimplify_var_or_parm_decl (expr_p
);
15164 /* When within an OMP context, notice uses of variables. */
15165 if (gimplify_omp_ctxp
)
15166 omp_notice_variable (gimplify_omp_ctxp
, *expr_p
, true);
15170 case DEBUG_EXPR_DECL
:
15171 gcc_unreachable ();
15173 case DEBUG_BEGIN_STMT
:
15174 gimplify_seq_add_stmt (pre_p
,
15175 gimple_build_debug_begin_stmt
15176 (TREE_BLOCK (*expr_p
),
15177 EXPR_LOCATION (*expr_p
)));
15183 /* Allow callbacks into the gimplifier during optimization. */
15188 gimplify_omp_parallel (expr_p
, pre_p
);
15193 gimplify_omp_task (expr_p
, pre_p
);
15199 case OMP_DISTRIBUTE
:
15202 ret
= gimplify_omp_for (expr_p
, pre_p
);
15206 ret
= gimplify_omp_loop (expr_p
, pre_p
);
15210 gimplify_oacc_cache (expr_p
, pre_p
);
15215 gimplify_oacc_declare (expr_p
, pre_p
);
15219 case OACC_HOST_DATA
:
15222 case OACC_PARALLEL
:
15228 case OMP_TARGET_DATA
:
15230 gimplify_omp_workshare (expr_p
, pre_p
);
15234 case OACC_ENTER_DATA
:
15235 case OACC_EXIT_DATA
:
15237 case OMP_TARGET_UPDATE
:
15238 case OMP_TARGET_ENTER_DATA
:
15239 case OMP_TARGET_EXIT_DATA
:
15240 gimplify_omp_target_update (expr_p
, pre_p
);
15251 gimple_seq body
= NULL
;
15253 bool saved_in_omp_construct
= in_omp_construct
;
15255 in_omp_construct
= true;
15256 gimplify_and_add (OMP_BODY (*expr_p
), &body
);
15257 in_omp_construct
= saved_in_omp_construct
;
15258 switch (TREE_CODE (*expr_p
))
15261 g
= gimple_build_omp_section (body
);
15264 g
= gimple_build_omp_master (body
);
15267 g
= gimplify_omp_ordered (*expr_p
, body
);
15270 gimplify_scan_omp_clauses (&OMP_MASKED_CLAUSES (*expr_p
),
15271 pre_p
, ORT_WORKSHARE
, OMP_MASKED
);
15272 gimplify_adjust_omp_clauses (pre_p
, body
,
15273 &OMP_MASKED_CLAUSES (*expr_p
),
15275 g
= gimple_build_omp_masked (body
,
15276 OMP_MASKED_CLAUSES (*expr_p
));
15279 gimplify_scan_omp_clauses (&OMP_CRITICAL_CLAUSES (*expr_p
),
15280 pre_p
, ORT_WORKSHARE
, OMP_CRITICAL
);
15281 gimplify_adjust_omp_clauses (pre_p
, body
,
15282 &OMP_CRITICAL_CLAUSES (*expr_p
),
15284 g
= gimple_build_omp_critical (body
,
15285 OMP_CRITICAL_NAME (*expr_p
),
15286 OMP_CRITICAL_CLAUSES (*expr_p
));
15289 gimplify_scan_omp_clauses (&OMP_SCAN_CLAUSES (*expr_p
),
15290 pre_p
, ORT_WORKSHARE
, OMP_SCAN
);
15291 gimplify_adjust_omp_clauses (pre_p
, body
,
15292 &OMP_SCAN_CLAUSES (*expr_p
),
15294 g
= gimple_build_omp_scan (body
, OMP_SCAN_CLAUSES (*expr_p
));
15297 gcc_unreachable ();
15299 gimplify_seq_add_stmt (pre_p
, g
);
15304 case OMP_TASKGROUP
:
15306 gimple_seq body
= NULL
;
15308 tree
*pclauses
= &OMP_TASKGROUP_CLAUSES (*expr_p
);
15309 bool saved_in_omp_construct
= in_omp_construct
;
15310 gimplify_scan_omp_clauses (pclauses
, pre_p
, ORT_TASKGROUP
,
15312 gimplify_adjust_omp_clauses (pre_p
, NULL
, pclauses
, OMP_TASKGROUP
);
15314 in_omp_construct
= true;
15315 gimplify_and_add (OMP_BODY (*expr_p
), &body
);
15316 in_omp_construct
= saved_in_omp_construct
;
15317 gimple_seq cleanup
= NULL
;
15318 tree fn
= builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_END
);
15319 gimple
*g
= gimple_build_call (fn
, 0);
15320 gimple_seq_add_stmt (&cleanup
, g
);
15321 g
= gimple_build_try (body
, cleanup
, GIMPLE_TRY_FINALLY
);
15323 gimple_seq_add_stmt (&body
, g
);
15324 g
= gimple_build_omp_taskgroup (body
, *pclauses
);
15325 gimplify_seq_add_stmt (pre_p
, g
);
15331 case OMP_ATOMIC_READ
:
15332 case OMP_ATOMIC_CAPTURE_OLD
:
15333 case OMP_ATOMIC_CAPTURE_NEW
:
15334 ret
= gimplify_omp_atomic (expr_p
, pre_p
);
15337 case TRANSACTION_EXPR
:
15338 ret
= gimplify_transaction (expr_p
, pre_p
);
15341 case TRUTH_AND_EXPR
:
15342 case TRUTH_OR_EXPR
:
15343 case TRUTH_XOR_EXPR
:
15345 tree orig_type
= TREE_TYPE (*expr_p
);
15346 tree new_type
, xop0
, xop1
;
15347 *expr_p
= gimple_boolify (*expr_p
);
15348 new_type
= TREE_TYPE (*expr_p
);
15349 if (!useless_type_conversion_p (orig_type
, new_type
))
15351 *expr_p
= fold_convert_loc (input_location
, orig_type
, *expr_p
);
15356 /* Boolified binary truth expressions are semantically equivalent
15357 to bitwise binary expressions. Canonicalize them to the
15358 bitwise variant. */
15359 switch (TREE_CODE (*expr_p
))
15361 case TRUTH_AND_EXPR
:
15362 TREE_SET_CODE (*expr_p
, BIT_AND_EXPR
);
15364 case TRUTH_OR_EXPR
:
15365 TREE_SET_CODE (*expr_p
, BIT_IOR_EXPR
);
15367 case TRUTH_XOR_EXPR
:
15368 TREE_SET_CODE (*expr_p
, BIT_XOR_EXPR
);
15373 /* Now make sure that operands have compatible type to
15374 expression's new_type. */
15375 xop0
= TREE_OPERAND (*expr_p
, 0);
15376 xop1
= TREE_OPERAND (*expr_p
, 1);
15377 if (!useless_type_conversion_p (new_type
, TREE_TYPE (xop0
)))
15378 TREE_OPERAND (*expr_p
, 0) = fold_convert_loc (input_location
,
15381 if (!useless_type_conversion_p (new_type
, TREE_TYPE (xop1
)))
15382 TREE_OPERAND (*expr_p
, 1) = fold_convert_loc (input_location
,
15385 /* Continue classified as tcc_binary. */
15389 case VEC_COND_EXPR
:
15392 case VEC_PERM_EXPR
:
15393 /* Classified as tcc_expression. */
15396 case BIT_INSERT_EXPR
:
15397 /* Argument 3 is a constant. */
15400 case POINTER_PLUS_EXPR
:
15402 enum gimplify_status r0
, r1
;
15403 r0
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
15404 post_p
, is_gimple_val
, fb_rvalue
);
15405 r1
= gimplify_expr (&TREE_OPERAND (*expr_p
, 1), pre_p
,
15406 post_p
, is_gimple_val
, fb_rvalue
);
15407 recalculate_side_effects (*expr_p
);
15408 ret
= MIN (r0
, r1
);
15413 switch (TREE_CODE_CLASS (TREE_CODE (*expr_p
)))
15415 case tcc_comparison
:
15416 /* Handle comparison of objects of non scalar mode aggregates
15417 with a call to memcmp. It would be nice to only have to do
15418 this for variable-sized objects, but then we'd have to allow
15419 the same nest of reference nodes we allow for MODIFY_EXPR and
15420 that's too complex.
15422 Compare scalar mode aggregates as scalar mode values. Using
15423 memcmp for them would be very inefficient at best, and is
15424 plain wrong if bitfields are involved. */
15426 tree type
= TREE_TYPE (TREE_OPERAND (*expr_p
, 1));
15428 /* Vector comparisons need no boolification. */
15429 if (TREE_CODE (type
) == VECTOR_TYPE
)
15431 else if (!AGGREGATE_TYPE_P (type
))
15433 tree org_type
= TREE_TYPE (*expr_p
);
15434 *expr_p
= gimple_boolify (*expr_p
);
15435 if (!useless_type_conversion_p (org_type
,
15436 TREE_TYPE (*expr_p
)))
15438 *expr_p
= fold_convert_loc (input_location
,
15439 org_type
, *expr_p
);
15445 else if (TYPE_MODE (type
) != BLKmode
)
15446 ret
= gimplify_scalar_mode_aggregate_compare (expr_p
);
15448 ret
= gimplify_variable_sized_compare (expr_p
);
15453 /* If *EXPR_P does not need to be special-cased, handle it
15454 according to its class. */
15456 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
15457 post_p
, is_gimple_val
, fb_rvalue
);
15463 enum gimplify_status r0
, r1
;
15465 r0
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
15466 post_p
, is_gimple_val
, fb_rvalue
);
15467 r1
= gimplify_expr (&TREE_OPERAND (*expr_p
, 1), pre_p
,
15468 post_p
, is_gimple_val
, fb_rvalue
);
15470 ret
= MIN (r0
, r1
);
15476 enum gimplify_status r0
, r1
, r2
;
15478 r0
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
15479 post_p
, is_gimple_val
, fb_rvalue
);
15480 r1
= gimplify_expr (&TREE_OPERAND (*expr_p
, 1), pre_p
,
15481 post_p
, is_gimple_val
, fb_rvalue
);
15482 r2
= gimplify_expr (&TREE_OPERAND (*expr_p
, 2), pre_p
,
15483 post_p
, is_gimple_val
, fb_rvalue
);
15485 ret
= MIN (MIN (r0
, r1
), r2
);
15489 case tcc_declaration
:
15492 goto dont_recalculate
;
15495 gcc_unreachable ();
15498 recalculate_side_effects (*expr_p
);
15504 gcc_assert (*expr_p
|| ret
!= GS_OK
);
15506 while (ret
== GS_OK
);
15508 /* If we encountered an error_mark somewhere nested inside, either
15509 stub out the statement or propagate the error back out. */
15510 if (ret
== GS_ERROR
)
15517 /* This was only valid as a return value from the langhook, which
15518 we handled. Make sure it doesn't escape from any other context. */
15519 gcc_assert (ret
!= GS_UNHANDLED
);
15521 if (fallback
== fb_none
&& *expr_p
&& !is_gimple_stmt (*expr_p
))
15523 /* We aren't looking for a value, and we don't have a valid
15524 statement. If it doesn't have side-effects, throw it away.
15525 We can also get here with code such as "*&&L;", where L is
15526 a LABEL_DECL that is marked as FORCED_LABEL. */
15527 if (TREE_CODE (*expr_p
) == LABEL_DECL
15528 || !TREE_SIDE_EFFECTS (*expr_p
))
15530 else if (!TREE_THIS_VOLATILE (*expr_p
))
15532 /* This is probably a _REF that contains something nested that
15533 has side effects. Recurse through the operands to find it. */
15534 enum tree_code code
= TREE_CODE (*expr_p
);
15538 case COMPONENT_REF
:
15539 case REALPART_EXPR
:
15540 case IMAGPART_EXPR
:
15541 case VIEW_CONVERT_EXPR
:
15542 gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
15543 gimple_test_f
, fallback
);
15547 case ARRAY_RANGE_REF
:
15548 gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
15549 gimple_test_f
, fallback
);
15550 gimplify_expr (&TREE_OPERAND (*expr_p
, 1), pre_p
, post_p
,
15551 gimple_test_f
, fallback
);
15555 /* Anything else with side-effects must be converted to
15556 a valid statement before we get here. */
15557 gcc_unreachable ();
15562 else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p
))
15563 && TYPE_MODE (TREE_TYPE (*expr_p
)) != BLKmode
15564 && !is_empty_type (TREE_TYPE (*expr_p
)))
15566 /* Historically, the compiler has treated a bare reference
15567 to a non-BLKmode volatile lvalue as forcing a load. */
15568 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p
));
15570 /* Normally, we do not want to create a temporary for a
15571 TREE_ADDRESSABLE type because such a type should not be
15572 copied by bitwise-assignment. However, we make an
15573 exception here, as all we are doing here is ensuring that
15574 we read the bytes that make up the type. We use
15575 create_tmp_var_raw because create_tmp_var will abort when
15576 given a TREE_ADDRESSABLE type. */
15577 tree tmp
= create_tmp_var_raw (type
, "vol");
15578 gimple_add_tmp_var (tmp
);
15579 gimplify_assign (tmp
, *expr_p
, pre_p
);
15583 /* We can't do anything useful with a volatile reference to
15584 an incomplete type, so just throw it away. Likewise for
15585 a BLKmode type, since any implicit inner load should
15586 already have been turned into an explicit one by the
15587 gimplification process. */
15591 /* If we are gimplifying at the statement level, we're done. Tack
15592 everything together and return. */
15593 if (fallback
== fb_none
|| is_statement
)
15595 /* Since *EXPR_P has been converted into a GIMPLE tuple, clear
15596 it out for GC to reclaim it. */
15597 *expr_p
= NULL_TREE
;
15599 if (!gimple_seq_empty_p (internal_pre
)
15600 || !gimple_seq_empty_p (internal_post
))
15602 gimplify_seq_add_seq (&internal_pre
, internal_post
);
15603 gimplify_seq_add_seq (pre_p
, internal_pre
);
15606 /* The result of gimplifying *EXPR_P is going to be the last few
15607 statements in *PRE_P and *POST_P. Add location information
15608 to all the statements that were added by the gimplification
15610 if (!gimple_seq_empty_p (*pre_p
))
15611 annotate_all_with_location_after (*pre_p
, pre_last_gsi
, input_location
);
15613 if (!gimple_seq_empty_p (*post_p
))
15614 annotate_all_with_location_after (*post_p
, post_last_gsi
,
15620 #ifdef ENABLE_GIMPLE_CHECKING
15623 enum tree_code code
= TREE_CODE (*expr_p
);
15624 /* These expressions should already be in gimple IR form. */
15625 gcc_assert (code
!= MODIFY_EXPR
15626 && code
!= ASM_EXPR
15627 && code
!= BIND_EXPR
15628 && code
!= CATCH_EXPR
15629 && (code
!= COND_EXPR
|| gimplify_ctxp
->allow_rhs_cond_expr
)
15630 && code
!= EH_FILTER_EXPR
15631 && code
!= GOTO_EXPR
15632 && code
!= LABEL_EXPR
15633 && code
!= LOOP_EXPR
15634 && code
!= SWITCH_EXPR
15635 && code
!= TRY_FINALLY_EXPR
15636 && code
!= EH_ELSE_EXPR
15637 && code
!= OACC_PARALLEL
15638 && code
!= OACC_KERNELS
15639 && code
!= OACC_SERIAL
15640 && code
!= OACC_DATA
15641 && code
!= OACC_HOST_DATA
15642 && code
!= OACC_DECLARE
15643 && code
!= OACC_UPDATE
15644 && code
!= OACC_ENTER_DATA
15645 && code
!= OACC_EXIT_DATA
15646 && code
!= OACC_CACHE
15647 && code
!= OMP_CRITICAL
15649 && code
!= OACC_LOOP
15650 && code
!= OMP_MASTER
15651 && code
!= OMP_MASKED
15652 && code
!= OMP_TASKGROUP
15653 && code
!= OMP_ORDERED
15654 && code
!= OMP_PARALLEL
15655 && code
!= OMP_SCAN
15656 && code
!= OMP_SECTIONS
15657 && code
!= OMP_SECTION
15658 && code
!= OMP_SINGLE
15659 && code
!= OMP_SCOPE
);
15663 /* Otherwise we're gimplifying a subexpression, so the resulting
15664 value is interesting. If it's a valid operand that matches
15665 GIMPLE_TEST_F, we're done. Unless we are handling some
15666 post-effects internally; if that's the case, we need to copy into
15667 a temporary before adding the post-effects to POST_P. */
15668 if (gimple_seq_empty_p (internal_post
) && (*gimple_test_f
) (*expr_p
))
15671 /* Otherwise, we need to create a new temporary for the gimplified
15674 /* We can't return an lvalue if we have an internal postqueue. The
15675 object the lvalue refers to would (probably) be modified by the
15676 postqueue; we need to copy the value out first, which means an
15678 if ((fallback
& fb_lvalue
)
15679 && gimple_seq_empty_p (internal_post
)
15680 && is_gimple_addressable (*expr_p
))
15682 /* An lvalue will do. Take the address of the expression, store it
15683 in a temporary, and replace the expression with an INDIRECT_REF of
15685 tree ref_alias_type
= reference_alias_ptr_type (*expr_p
);
15686 unsigned int ref_align
= get_object_alignment (*expr_p
);
15687 tree ref_type
= TREE_TYPE (*expr_p
);
15688 tmp
= build_fold_addr_expr_loc (input_location
, *expr_p
);
15689 gimplify_expr (&tmp
, pre_p
, post_p
, is_gimple_reg
, fb_rvalue
);
15690 if (TYPE_ALIGN (ref_type
) != ref_align
)
15691 ref_type
= build_aligned_type (ref_type
, ref_align
);
15692 *expr_p
= build2 (MEM_REF
, ref_type
,
15693 tmp
, build_zero_cst (ref_alias_type
));
15695 else if ((fallback
& fb_rvalue
) && is_gimple_reg_rhs_or_call (*expr_p
))
15697 /* An rvalue will do. Assign the gimplified expression into a
15698 new temporary TMP and replace the original expression with
15699 TMP. First, make sure that the expression has a type so that
15700 it can be assigned into a temporary. */
15701 gcc_assert (!VOID_TYPE_P (TREE_TYPE (*expr_p
)));
15702 *expr_p
= get_formal_tmp_var (*expr_p
, pre_p
);
15706 #ifdef ENABLE_GIMPLE_CHECKING
15707 if (!(fallback
& fb_mayfail
))
15709 fprintf (stderr
, "gimplification failed:\n");
15710 print_generic_expr (stderr
, *expr_p
);
15711 debug_tree (*expr_p
);
15712 internal_error ("gimplification failed");
15715 gcc_assert (fallback
& fb_mayfail
);
15717 /* If this is an asm statement, and the user asked for the
15718 impossible, don't die. Fail and let gimplify_asm_expr
15724 /* Make sure the temporary matches our predicate. */
15725 gcc_assert ((*gimple_test_f
) (*expr_p
));
15727 if (!gimple_seq_empty_p (internal_post
))
15729 annotate_all_with_location (internal_post
, input_location
);
15730 gimplify_seq_add_seq (pre_p
, internal_post
);
15734 input_location
= saved_location
;
15738 /* Like gimplify_expr but make sure the gimplified result is not itself
15739 a SSA name (but a decl if it were). Temporaries required by
15740 evaluating *EXPR_P may be still SSA names. */
15742 static enum gimplify_status
15743 gimplify_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
15744 bool (*gimple_test_f
) (tree
), fallback_t fallback
,
15747 enum gimplify_status ret
= gimplify_expr (expr_p
, pre_p
, post_p
,
15748 gimple_test_f
, fallback
);
15750 && TREE_CODE (*expr_p
) == SSA_NAME
)
15751 *expr_p
= get_initialized_tmp_var (*expr_p
, pre_p
, NULL
, false);
15755 /* Look through TYPE for variable-sized objects and gimplify each such
15756 size that we find. Add to LIST_P any statements generated. */
15759 gimplify_type_sizes (tree type
, gimple_seq
*list_p
)
15761 if (type
== NULL
|| type
== error_mark_node
)
15764 const bool ignored_p
15766 && TREE_CODE (TYPE_NAME (type
)) == TYPE_DECL
15767 && DECL_IGNORED_P (TYPE_NAME (type
));
15770 /* We first do the main variant, then copy into any other variants. */
15771 type
= TYPE_MAIN_VARIANT (type
);
15773 /* Avoid infinite recursion. */
15774 if (TYPE_SIZES_GIMPLIFIED (type
))
15777 TYPE_SIZES_GIMPLIFIED (type
) = 1;
15779 switch (TREE_CODE (type
))
15782 case ENUMERAL_TYPE
:
15785 case FIXED_POINT_TYPE
:
15786 gimplify_one_sizepos (&TYPE_MIN_VALUE (type
), list_p
);
15787 gimplify_one_sizepos (&TYPE_MAX_VALUE (type
), list_p
);
15789 for (t
= TYPE_NEXT_VARIANT (type
); t
; t
= TYPE_NEXT_VARIANT (t
))
15791 TYPE_MIN_VALUE (t
) = TYPE_MIN_VALUE (type
);
15792 TYPE_MAX_VALUE (t
) = TYPE_MAX_VALUE (type
);
15797 /* These types may not have declarations, so handle them here. */
15798 gimplify_type_sizes (TREE_TYPE (type
), list_p
);
15799 gimplify_type_sizes (TYPE_DOMAIN (type
), list_p
);
15800 /* Ensure VLA bounds aren't removed, for -O0 they should be variables
15801 with assigned stack slots, for -O1+ -g they should be tracked
15804 && TYPE_DOMAIN (type
)
15805 && INTEGRAL_TYPE_P (TYPE_DOMAIN (type
)))
15807 t
= TYPE_MIN_VALUE (TYPE_DOMAIN (type
));
15808 if (t
&& VAR_P (t
) && DECL_ARTIFICIAL (t
))
15809 DECL_IGNORED_P (t
) = 0;
15810 t
= TYPE_MAX_VALUE (TYPE_DOMAIN (type
));
15811 if (t
&& VAR_P (t
) && DECL_ARTIFICIAL (t
))
15812 DECL_IGNORED_P (t
) = 0;
15818 case QUAL_UNION_TYPE
:
15819 for (tree field
= TYPE_FIELDS (type
); field
; field
= DECL_CHAIN (field
))
15820 if (TREE_CODE (field
) == FIELD_DECL
)
15822 gimplify_one_sizepos (&DECL_FIELD_OFFSET (field
), list_p
);
15823 /* Likewise, ensure variable offsets aren't removed. */
15825 && (t
= DECL_FIELD_OFFSET (field
))
15827 && DECL_ARTIFICIAL (t
))
15828 DECL_IGNORED_P (t
) = 0;
15829 gimplify_one_sizepos (&DECL_SIZE (field
), list_p
);
15830 gimplify_one_sizepos (&DECL_SIZE_UNIT (field
), list_p
);
15831 gimplify_type_sizes (TREE_TYPE (field
), list_p
);
15836 case REFERENCE_TYPE
:
15837 /* We used to recurse on the pointed-to type here, which turned out to
15838 be incorrect because its definition might refer to variables not
15839 yet initialized at this point if a forward declaration is involved.
15841 It was actually useful for anonymous pointed-to types to ensure
15842 that the sizes evaluation dominates every possible later use of the
15843 values. Restricting to such types here would be safe since there
15844 is no possible forward declaration around, but would introduce an
15845 undesirable middle-end semantic to anonymity. We then defer to
15846 front-ends the responsibility of ensuring that the sizes are
15847 evaluated both early and late enough, e.g. by attaching artificial
15848 type declarations to the tree. */
15855 gimplify_one_sizepos (&TYPE_SIZE (type
), list_p
);
15856 gimplify_one_sizepos (&TYPE_SIZE_UNIT (type
), list_p
);
15858 for (t
= TYPE_NEXT_VARIANT (type
); t
; t
= TYPE_NEXT_VARIANT (t
))
15860 TYPE_SIZE (t
) = TYPE_SIZE (type
);
15861 TYPE_SIZE_UNIT (t
) = TYPE_SIZE_UNIT (type
);
15862 TYPE_SIZES_GIMPLIFIED (t
) = 1;
15866 /* A subroutine of gimplify_type_sizes to make sure that *EXPR_P,
15867 a size or position, has had all of its SAVE_EXPRs evaluated.
15868 We add any required statements to *STMT_P. */
15871 gimplify_one_sizepos (tree
*expr_p
, gimple_seq
*stmt_p
)
15873 tree expr
= *expr_p
;
15875 /* We don't do anything if the value isn't there, is constant, or contains
15876 A PLACEHOLDER_EXPR. We also don't want to do anything if it's already
15877 a VAR_DECL. If it's a VAR_DECL from another function, the gimplifier
15878 will want to replace it with a new variable, but that will cause problems
15879 if this type is from outside the function. It's OK to have that here. */
15880 if (expr
== NULL_TREE
15881 || is_gimple_constant (expr
)
15882 || TREE_CODE (expr
) == VAR_DECL
15883 || CONTAINS_PLACEHOLDER_P (expr
))
15886 *expr_p
= unshare_expr (expr
);
15888 /* SSA names in decl/type fields are a bad idea - they'll get reclaimed
15889 if the def vanishes. */
15890 gimplify_expr (expr_p
, stmt_p
, NULL
, is_gimple_val
, fb_rvalue
, false);
15892 /* If expr wasn't already is_gimple_sizepos or is_gimple_constant from the
15893 FE, ensure that it is a VAR_DECL, otherwise we might handle some decls
15894 as gimplify_vla_decl even when they would have all sizes INTEGER_CSTs. */
15895 if (is_gimple_constant (*expr_p
))
15896 *expr_p
= get_initialized_tmp_var (*expr_p
, stmt_p
, NULL
, false);
15899 /* Gimplify the body of statements of FNDECL and return a GIMPLE_BIND node
15900 containing the sequence of corresponding GIMPLE statements. If DO_PARMS
15901 is true, also gimplify the parameters. */
15904 gimplify_body (tree fndecl
, bool do_parms
)
15906 location_t saved_location
= input_location
;
15907 gimple_seq parm_stmts
, parm_cleanup
= NULL
, seq
;
15908 gimple
*outer_stmt
;
15911 timevar_push (TV_TREE_GIMPLIFY
);
15913 init_tree_ssa (cfun
);
15915 /* Initialize for optimize_insn_for_s{ize,peed}_p possibly called during
15917 default_rtl_profile ();
15919 gcc_assert (gimplify_ctxp
== NULL
);
15920 push_gimplify_context (true);
15922 if (flag_openacc
|| flag_openmp
)
15924 gcc_assert (gimplify_omp_ctxp
== NULL
);
15925 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (fndecl
)))
15926 gimplify_omp_ctxp
= new_omp_context (ORT_IMPLICIT_TARGET
);
15929 /* Unshare most shared trees in the body and in that of any nested functions.
15930 It would seem we don't have to do this for nested functions because
15931 they are supposed to be output and then the outer function gimplified
15932 first, but the g++ front end doesn't always do it that way. */
15933 unshare_body (fndecl
);
15934 unvisit_body (fndecl
);
15936 /* Make sure input_location isn't set to something weird. */
15937 input_location
= DECL_SOURCE_LOCATION (fndecl
);
15939 /* Resolve callee-copies. This has to be done before processing
15940 the body so that DECL_VALUE_EXPR gets processed correctly. */
15941 parm_stmts
= do_parms
? gimplify_parameters (&parm_cleanup
) : NULL
;
15943 /* Gimplify the function's body. */
15945 gimplify_stmt (&DECL_SAVED_TREE (fndecl
), &seq
);
15946 outer_stmt
= gimple_seq_first_nondebug_stmt (seq
);
15949 outer_stmt
= gimple_build_nop ();
15950 gimplify_seq_add_stmt (&seq
, outer_stmt
);
15953 /* The body must contain exactly one statement, a GIMPLE_BIND. If this is
15954 not the case, wrap everything in a GIMPLE_BIND to make it so. */
15955 if (gimple_code (outer_stmt
) == GIMPLE_BIND
15956 && (gimple_seq_first_nondebug_stmt (seq
)
15957 == gimple_seq_last_nondebug_stmt (seq
)))
15959 outer_bind
= as_a
<gbind
*> (outer_stmt
);
15960 if (gimple_seq_first_stmt (seq
) != outer_stmt
15961 || gimple_seq_last_stmt (seq
) != outer_stmt
)
15963 /* If there are debug stmts before or after outer_stmt, move them
15964 inside of outer_bind body. */
15965 gimple_stmt_iterator gsi
= gsi_for_stmt (outer_stmt
, &seq
);
15966 gimple_seq second_seq
= NULL
;
15967 if (gimple_seq_first_stmt (seq
) != outer_stmt
15968 && gimple_seq_last_stmt (seq
) != outer_stmt
)
15970 second_seq
= gsi_split_seq_after (gsi
);
15971 gsi_remove (&gsi
, false);
15973 else if (gimple_seq_first_stmt (seq
) != outer_stmt
)
15974 gsi_remove (&gsi
, false);
15977 gsi_remove (&gsi
, false);
15981 gimple_seq_add_seq_without_update (&seq
,
15982 gimple_bind_body (outer_bind
));
15983 gimple_seq_add_seq_without_update (&seq
, second_seq
);
15984 gimple_bind_set_body (outer_bind
, seq
);
15988 outer_bind
= gimple_build_bind (NULL_TREE
, seq
, NULL
);
15990 DECL_SAVED_TREE (fndecl
) = NULL_TREE
;
15992 /* If we had callee-copies statements, insert them at the beginning
15993 of the function and clear DECL_VALUE_EXPR_P on the parameters. */
15994 if (!gimple_seq_empty_p (parm_stmts
))
15998 gimplify_seq_add_seq (&parm_stmts
, gimple_bind_body (outer_bind
));
16001 gtry
*g
= gimple_build_try (parm_stmts
, parm_cleanup
,
16002 GIMPLE_TRY_FINALLY
);
16004 gimple_seq_add_stmt (&parm_stmts
, g
);
16006 gimple_bind_set_body (outer_bind
, parm_stmts
);
16008 for (parm
= DECL_ARGUMENTS (current_function_decl
);
16009 parm
; parm
= DECL_CHAIN (parm
))
16010 if (DECL_HAS_VALUE_EXPR_P (parm
))
16012 DECL_HAS_VALUE_EXPR_P (parm
) = 0;
16013 DECL_IGNORED_P (parm
) = 0;
16017 if ((flag_openacc
|| flag_openmp
|| flag_openmp_simd
)
16018 && gimplify_omp_ctxp
)
16020 delete_omp_context (gimplify_omp_ctxp
);
16021 gimplify_omp_ctxp
= NULL
;
16024 pop_gimplify_context (outer_bind
);
16025 gcc_assert (gimplify_ctxp
== NULL
);
16027 if (flag_checking
&& !seen_error ())
16028 verify_gimple_in_seq (gimple_bind_body (outer_bind
));
16030 timevar_pop (TV_TREE_GIMPLIFY
);
16031 input_location
= saved_location
;
16036 typedef char *char_p
; /* For DEF_VEC_P. */
16038 /* Return whether we should exclude FNDECL from instrumentation. */
16041 flag_instrument_functions_exclude_p (tree fndecl
)
16045 v
= (vec
<char_p
> *) flag_instrument_functions_exclude_functions
;
16046 if (v
&& v
->length () > 0)
16052 name
= lang_hooks
.decl_printable_name (fndecl
, 1);
16053 FOR_EACH_VEC_ELT (*v
, i
, s
)
16054 if (strstr (name
, s
) != NULL
)
16058 v
= (vec
<char_p
> *) flag_instrument_functions_exclude_files
;
16059 if (v
&& v
->length () > 0)
16065 name
= DECL_SOURCE_FILE (fndecl
);
16066 FOR_EACH_VEC_ELT (*v
, i
, s
)
16067 if (strstr (name
, s
) != NULL
)
16074 /* Entry point to the gimplification pass. FNDECL is the FUNCTION_DECL
16075 node for the function we want to gimplify.
16077 Return the sequence of GIMPLE statements corresponding to the body
16081 gimplify_function_tree (tree fndecl
)
16086 gcc_assert (!gimple_body (fndecl
));
16088 if (DECL_STRUCT_FUNCTION (fndecl
))
16089 push_cfun (DECL_STRUCT_FUNCTION (fndecl
));
16091 push_struct_function (fndecl
);
16093 /* Tentatively set PROP_gimple_lva here, and reset it in gimplify_va_arg_expr
16095 cfun
->curr_properties
|= PROP_gimple_lva
;
16097 if (asan_sanitize_use_after_scope ())
16098 asan_poisoned_variables
= new hash_set
<tree
> ();
16099 bind
= gimplify_body (fndecl
, true);
16100 if (asan_poisoned_variables
)
16102 delete asan_poisoned_variables
;
16103 asan_poisoned_variables
= NULL
;
16106 /* The tree body of the function is no longer needed, replace it
16107 with the new GIMPLE body. */
16109 gimple_seq_add_stmt (&seq
, bind
);
16110 gimple_set_body (fndecl
, seq
);
16112 /* If we're instrumenting function entry/exit, then prepend the call to
16113 the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to
16114 catch the exit hook. */
16115 /* ??? Add some way to ignore exceptions for this TFE. */
16116 if (flag_instrument_function_entry_exit
16117 && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl
)
16118 /* Do not instrument extern inline functions. */
16119 && !(DECL_DECLARED_INLINE_P (fndecl
)
16120 && DECL_EXTERNAL (fndecl
)
16121 && DECL_DISREGARD_INLINE_LIMITS (fndecl
))
16122 && !flag_instrument_functions_exclude_p (fndecl
))
16127 gimple_seq cleanup
= NULL
, body
= NULL
;
16128 tree tmp_var
, this_fn_addr
;
16131 /* The instrumentation hooks aren't going to call the instrumented
16132 function and the address they receive is expected to be matchable
16133 against symbol addresses. Make sure we don't create a trampoline,
16134 in case the current function is nested. */
16135 this_fn_addr
= build_fold_addr_expr (current_function_decl
);
16136 TREE_NO_TRAMPOLINE (this_fn_addr
) = 1;
16138 x
= builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS
);
16139 call
= gimple_build_call (x
, 1, integer_zero_node
);
16140 tmp_var
= create_tmp_var (ptr_type_node
, "return_addr");
16141 gimple_call_set_lhs (call
, tmp_var
);
16142 gimplify_seq_add_stmt (&cleanup
, call
);
16143 x
= builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_EXIT
);
16144 call
= gimple_build_call (x
, 2, this_fn_addr
, tmp_var
);
16145 gimplify_seq_add_stmt (&cleanup
, call
);
16146 tf
= gimple_build_try (seq
, cleanup
, GIMPLE_TRY_FINALLY
);
16148 x
= builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS
);
16149 call
= gimple_build_call (x
, 1, integer_zero_node
);
16150 tmp_var
= create_tmp_var (ptr_type_node
, "return_addr");
16151 gimple_call_set_lhs (call
, tmp_var
);
16152 gimplify_seq_add_stmt (&body
, call
);
16153 x
= builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_ENTER
);
16154 call
= gimple_build_call (x
, 2, this_fn_addr
, tmp_var
);
16155 gimplify_seq_add_stmt (&body
, call
);
16156 gimplify_seq_add_stmt (&body
, tf
);
16157 new_bind
= gimple_build_bind (NULL
, body
, NULL
);
16159 /* Replace the current function body with the body
16160 wrapped in the try/finally TF. */
16162 gimple_seq_add_stmt (&seq
, new_bind
);
16163 gimple_set_body (fndecl
, seq
);
16167 if (sanitize_flags_p (SANITIZE_THREAD
)
16168 && param_tsan_instrument_func_entry_exit
)
16170 gcall
*call
= gimple_build_call_internal (IFN_TSAN_FUNC_EXIT
, 0);
16171 gimple
*tf
= gimple_build_try (seq
, call
, GIMPLE_TRY_FINALLY
);
16172 gbind
*new_bind
= gimple_build_bind (NULL
, tf
, NULL
);
16173 /* Replace the current function body with the body
16174 wrapped in the try/finally TF. */
16176 gimple_seq_add_stmt (&seq
, new_bind
);
16177 gimple_set_body (fndecl
, seq
);
16180 DECL_SAVED_TREE (fndecl
) = NULL_TREE
;
16181 cfun
->curr_properties
|= PROP_gimple_any
;
16185 dump_function (TDI_gimple
, fndecl
);
16188 /* Return a dummy expression of type TYPE in order to keep going after an
16192 dummy_object (tree type
)
16194 tree t
= build_int_cst (build_pointer_type (type
), 0);
16195 return build2 (MEM_REF
, type
, t
, t
);
16198 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
16199 builtin function, but a very special sort of operator. */
16201 enum gimplify_status
16202 gimplify_va_arg_expr (tree
*expr_p
, gimple_seq
*pre_p
,
16203 gimple_seq
*post_p ATTRIBUTE_UNUSED
)
16205 tree promoted_type
, have_va_type
;
16206 tree valist
= TREE_OPERAND (*expr_p
, 0);
16207 tree type
= TREE_TYPE (*expr_p
);
16208 tree t
, tag
, aptag
;
16209 location_t loc
= EXPR_LOCATION (*expr_p
);
16211 /* Verify that valist is of the proper type. */
16212 have_va_type
= TREE_TYPE (valist
);
16213 if (have_va_type
== error_mark_node
)
16215 have_va_type
= targetm
.canonical_va_list_type (have_va_type
);
16216 if (have_va_type
== NULL_TREE
16217 && POINTER_TYPE_P (TREE_TYPE (valist
)))
16218 /* Handle 'Case 1: Not an array type' from c-common.c/build_va_arg. */
16220 = targetm
.canonical_va_list_type (TREE_TYPE (TREE_TYPE (valist
)));
16221 gcc_assert (have_va_type
!= NULL_TREE
);
16223 /* Generate a diagnostic for requesting data of a type that cannot
16224 be passed through `...' due to type promotion at the call site. */
16225 if ((promoted_type
= lang_hooks
.types
.type_promotes_to (type
))
16228 static bool gave_help
;
16230 /* Use the expansion point to handle cases such as passing bool (defined
16231 in a system header) through `...'. */
16233 = expansion_point_location_if_in_system_header (loc
);
16235 /* Unfortunately, this is merely undefined, rather than a constraint
16236 violation, so we cannot make this an error. If this call is never
16237 executed, the program is still strictly conforming. */
16238 auto_diagnostic_group d
;
16239 warned
= warning_at (xloc
, 0,
16240 "%qT is promoted to %qT when passed through %<...%>",
16241 type
, promoted_type
);
16242 if (!gave_help
&& warned
)
16245 inform (xloc
, "(so you should pass %qT not %qT to %<va_arg%>)",
16246 promoted_type
, type
);
16249 /* We can, however, treat "undefined" any way we please.
16250 Call abort to encourage the user to fix the program. */
16252 inform (xloc
, "if this code is reached, the program will abort");
16253 /* Before the abort, allow the evaluation of the va_list
16254 expression to exit or longjmp. */
16255 gimplify_and_add (valist
, pre_p
);
16256 t
= build_call_expr_loc (loc
,
16257 builtin_decl_implicit (BUILT_IN_TRAP
), 0);
16258 gimplify_and_add (t
, pre_p
);
16260 /* This is dead code, but go ahead and finish so that the
16261 mode of the result comes out right. */
16262 *expr_p
= dummy_object (type
);
16263 return GS_ALL_DONE
;
16266 tag
= build_int_cst (build_pointer_type (type
), 0);
16267 aptag
= build_int_cst (TREE_TYPE (valist
), 0);
16269 *expr_p
= build_call_expr_internal_loc (loc
, IFN_VA_ARG
, type
, 3,
16270 valist
, tag
, aptag
);
16272 /* Clear the tentatively set PROP_gimple_lva, to indicate that IFN_VA_ARG
16273 needs to be expanded. */
16274 cfun
->curr_properties
&= ~PROP_gimple_lva
;
16279 /* Build a new GIMPLE_ASSIGN tuple and append it to the end of *SEQ_P.
16281 DST/SRC are the destination and source respectively. You can pass
16282 ungimplified trees in DST or SRC, in which case they will be
16283 converted to a gimple operand if necessary.
16285 This function returns the newly created GIMPLE_ASSIGN tuple. */
16288 gimplify_assign (tree dst
, tree src
, gimple_seq
*seq_p
)
16290 tree t
= build2 (MODIFY_EXPR
, TREE_TYPE (dst
), dst
, src
);
16291 gimplify_and_add (t
, seq_p
);
16293 return gimple_seq_last_stmt (*seq_p
);
16297 gimplify_hasher::hash (const elt_t
*p
)
16300 return iterative_hash_expr (t
, 0);
16304 gimplify_hasher::equal (const elt_t
*p1
, const elt_t
*p2
)
16308 enum tree_code code
= TREE_CODE (t1
);
16310 if (TREE_CODE (t2
) != code
16311 || TREE_TYPE (t1
) != TREE_TYPE (t2
))
16314 if (!operand_equal_p (t1
, t2
, 0))
16317 /* Only allow them to compare equal if they also hash equal; otherwise
16318 results are nondeterminate, and we fail bootstrap comparison. */
16319 gcc_checking_assert (hash (p1
) == hash (p2
));