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. */
11505 struct gimplify_adjust_omp_clauses_data data
;
11506 if ((gimplify_omp_ctxp
->region_type
& ORT_ACC
) == 0)
11508 /* OpenMP. Implicit clauses are added at the start of the clause list,
11509 but after any non-map clauses. */
11510 tree
*implicit_add_list_p
= orig_list_p
;
11511 while (*implicit_add_list_p
11512 && OMP_CLAUSE_CODE (*implicit_add_list_p
) != OMP_CLAUSE_MAP
)
11513 implicit_add_list_p
= &OMP_CLAUSE_CHAIN (*implicit_add_list_p
);
11514 data
.list_p
= implicit_add_list_p
;
11518 data
.list_p
= list_p
;
11519 data
.pre_p
= pre_p
;
11520 splay_tree_foreach (ctx
->variables
, gimplify_adjust_omp_clauses_1
, &data
);
11522 if (has_inscan_reductions
)
11523 for (c
= *orig_list_p
; c
; c
= OMP_CLAUSE_CHAIN (c
))
11524 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINEAR
11525 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c
))
11527 error_at (OMP_CLAUSE_LOCATION (c
),
11528 "%<inscan%> %<reduction%> clause used together with "
11529 "%<linear%> clause for a variable other than loop "
11534 gimplify_omp_ctxp
= ctx
->outer_context
;
11535 delete_omp_context (ctx
);
11538 /* Return 0 if CONSTRUCTS selectors don't match the OpenMP context,
11539 -1 if unknown yet (simd is involved, won't be known until vectorization)
11540 and 1 if they do. If SCORES is non-NULL, it should point to an array
11541 of at least 2*NCONSTRUCTS+2 ints, and will be filled with the positions
11542 of the CONSTRUCTS (position -1 if it will never match) followed by
11543 number of constructs in the OpenMP context construct trait. If the
11544 score depends on whether it will be in a declare simd clone or not,
11545 the function returns 2 and there will be two sets of the scores, the first
11546 one for the case that it is not in a declare simd clone, the other
11547 that it is in a declare simd clone. */
11550 omp_construct_selector_matches (enum tree_code
*constructs
, int nconstructs
,
11553 int matched
= 0, cnt
= 0;
11554 bool simd_seen
= false;
11555 bool target_seen
= false;
11556 int declare_simd_cnt
= -1;
11557 auto_vec
<enum tree_code
, 16> codes
;
11558 for (struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
; ctx
;)
11560 if (((ctx
->region_type
& ORT_PARALLEL
) && ctx
->code
== OMP_PARALLEL
)
11561 || ((ctx
->region_type
& (ORT_TARGET
| ORT_IMPLICIT_TARGET
| ORT_ACC
))
11562 == ORT_TARGET
&& ctx
->code
== OMP_TARGET
)
11563 || ((ctx
->region_type
& ORT_TEAMS
) && ctx
->code
== OMP_TEAMS
)
11564 || (ctx
->region_type
== ORT_WORKSHARE
&& ctx
->code
== OMP_FOR
)
11565 || (ctx
->region_type
== ORT_SIMD
11566 && ctx
->code
== OMP_SIMD
11567 && !omp_find_clause (ctx
->clauses
, OMP_CLAUSE_BIND
)))
11571 codes
.safe_push (ctx
->code
);
11572 else if (matched
< nconstructs
&& ctx
->code
== constructs
[matched
])
11574 if (ctx
->code
== OMP_SIMD
)
11582 if (ctx
->code
== OMP_TARGET
)
11584 if (scores
== NULL
)
11585 return matched
< nconstructs
? 0 : simd_seen
? -1 : 1;
11586 target_seen
= true;
11590 else if (ctx
->region_type
== ORT_WORKSHARE
11591 && ctx
->code
== OMP_LOOP
11592 && ctx
->outer_context
11593 && ctx
->outer_context
->region_type
== ORT_COMBINED_PARALLEL
11594 && ctx
->outer_context
->outer_context
11595 && ctx
->outer_context
->outer_context
->code
== OMP_LOOP
11596 && ctx
->outer_context
->outer_context
->distribute
)
11597 ctx
= ctx
->outer_context
->outer_context
;
11598 ctx
= ctx
->outer_context
;
11601 && lookup_attribute ("omp declare simd",
11602 DECL_ATTRIBUTES (current_function_decl
)))
11604 /* Declare simd is a maybe case, it is supposed to be added only to the
11605 omp-simd-clone.c added clones and not to the base function. */
11606 declare_simd_cnt
= cnt
++;
11608 codes
.safe_push (OMP_SIMD
);
11610 && constructs
[0] == OMP_SIMD
)
11612 gcc_assert (matched
== 0);
11614 if (++matched
== nconstructs
)
11618 if (tree attr
= lookup_attribute ("omp declare variant variant",
11619 DECL_ATTRIBUTES (current_function_decl
)))
11621 enum tree_code variant_constructs
[5];
11622 int variant_nconstructs
= 0;
11624 variant_nconstructs
11625 = omp_constructor_traits_to_codes (TREE_VALUE (attr
),
11626 variant_constructs
);
11627 for (int i
= 0; i
< variant_nconstructs
; i
++)
11631 codes
.safe_push (variant_constructs
[i
]);
11632 else if (matched
< nconstructs
11633 && variant_constructs
[i
] == constructs
[matched
])
11635 if (variant_constructs
[i
] == OMP_SIMD
)
11646 && lookup_attribute ("omp declare target block",
11647 DECL_ATTRIBUTES (current_function_decl
)))
11650 codes
.safe_push (OMP_TARGET
);
11651 else if (matched
< nconstructs
&& constructs
[matched
] == OMP_TARGET
)
11656 for (int pass
= 0; pass
< (declare_simd_cnt
== -1 ? 1 : 2); pass
++)
11658 int j
= codes
.length () - 1;
11659 for (int i
= nconstructs
- 1; i
>= 0; i
--)
11662 && (pass
!= 0 || declare_simd_cnt
!= j
)
11663 && constructs
[i
] != codes
[j
])
11665 if (pass
== 0 && declare_simd_cnt
!= -1 && j
> declare_simd_cnt
)
11670 *scores
++ = ((pass
== 0 && declare_simd_cnt
!= -1)
11671 ? codes
.length () - 1 : codes
.length ());
11673 return declare_simd_cnt
== -1 ? 1 : 2;
11675 if (matched
== nconstructs
)
11676 return simd_seen
? -1 : 1;
11680 /* Gimplify OACC_CACHE. */
11683 gimplify_oacc_cache (tree
*expr_p
, gimple_seq
*pre_p
)
11685 tree expr
= *expr_p
;
11687 gimplify_scan_omp_clauses (&OACC_CACHE_CLAUSES (expr
), pre_p
, ORT_ACC
,
11689 gimplify_adjust_omp_clauses (pre_p
, NULL
, &OACC_CACHE_CLAUSES (expr
),
11692 /* TODO: Do something sensible with this information. */
11694 *expr_p
= NULL_TREE
;
11697 /* Helper function of gimplify_oacc_declare. The helper's purpose is to,
11698 if required, translate 'kind' in CLAUSE into an 'entry' kind and 'exit'
11699 kind. The entry kind will replace the one in CLAUSE, while the exit
11700 kind will be used in a new omp_clause and returned to the caller. */
11703 gimplify_oacc_declare_1 (tree clause
)
11705 HOST_WIDE_INT kind
, new_op
;
11709 kind
= OMP_CLAUSE_MAP_KIND (clause
);
11713 case GOMP_MAP_ALLOC
:
11714 new_op
= GOMP_MAP_RELEASE
;
11718 case GOMP_MAP_FROM
:
11719 OMP_CLAUSE_SET_MAP_KIND (clause
, GOMP_MAP_FORCE_ALLOC
);
11720 new_op
= GOMP_MAP_FROM
;
11724 case GOMP_MAP_TOFROM
:
11725 OMP_CLAUSE_SET_MAP_KIND (clause
, GOMP_MAP_TO
);
11726 new_op
= GOMP_MAP_FROM
;
11730 case GOMP_MAP_DEVICE_RESIDENT
:
11731 case GOMP_MAP_FORCE_DEVICEPTR
:
11732 case GOMP_MAP_FORCE_PRESENT
:
11733 case GOMP_MAP_LINK
:
11734 case GOMP_MAP_POINTER
:
11739 gcc_unreachable ();
11745 c
= build_omp_clause (OMP_CLAUSE_LOCATION (clause
), OMP_CLAUSE_MAP
);
11746 OMP_CLAUSE_SET_MAP_KIND (c
, new_op
);
11747 OMP_CLAUSE_DECL (c
) = OMP_CLAUSE_DECL (clause
);
11753 /* Gimplify OACC_DECLARE. */
11756 gimplify_oacc_declare (tree
*expr_p
, gimple_seq
*pre_p
)
11758 tree expr
= *expr_p
;
11760 tree clauses
, t
, decl
;
11762 clauses
= OACC_DECLARE_CLAUSES (expr
);
11764 gimplify_scan_omp_clauses (&clauses
, pre_p
, ORT_TARGET_DATA
, OACC_DECLARE
);
11765 gimplify_adjust_omp_clauses (pre_p
, NULL
, &clauses
, OACC_DECLARE
);
11767 for (t
= clauses
; t
; t
= OMP_CLAUSE_CHAIN (t
))
11769 decl
= OMP_CLAUSE_DECL (t
);
11771 if (TREE_CODE (decl
) == MEM_REF
)
11772 decl
= TREE_OPERAND (decl
, 0);
11774 if (VAR_P (decl
) && !is_oacc_declared (decl
))
11776 tree attr
= get_identifier ("oacc declare target");
11777 DECL_ATTRIBUTES (decl
) = tree_cons (attr
, NULL_TREE
,
11778 DECL_ATTRIBUTES (decl
));
11782 && !is_global_var (decl
)
11783 && DECL_CONTEXT (decl
) == current_function_decl
)
11785 tree c
= gimplify_oacc_declare_1 (t
);
11788 if (oacc_declare_returns
== NULL
)
11789 oacc_declare_returns
= new hash_map
<tree
, tree
>;
11791 oacc_declare_returns
->put (decl
, c
);
11795 if (gimplify_omp_ctxp
)
11796 omp_add_variable (gimplify_omp_ctxp
, decl
, GOVD_SEEN
);
11799 stmt
= gimple_build_omp_target (NULL
, GF_OMP_TARGET_KIND_OACC_DECLARE
,
11802 gimplify_seq_add_stmt (pre_p
, stmt
);
11804 *expr_p
= NULL_TREE
;
11807 /* Gimplify the contents of an OMP_PARALLEL statement. This involves
11808 gimplification of the body, as well as scanning the body for used
11809 variables. We need to do this scan now, because variable-sized
11810 decls will be decomposed during gimplification. */
11813 gimplify_omp_parallel (tree
*expr_p
, gimple_seq
*pre_p
)
11815 tree expr
= *expr_p
;
11817 gimple_seq body
= NULL
;
11819 gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr
), pre_p
,
11820 OMP_PARALLEL_COMBINED (expr
)
11821 ? ORT_COMBINED_PARALLEL
11822 : ORT_PARALLEL
, OMP_PARALLEL
);
11824 push_gimplify_context ();
11826 g
= gimplify_and_return_first (OMP_PARALLEL_BODY (expr
), &body
);
11827 if (gimple_code (g
) == GIMPLE_BIND
)
11828 pop_gimplify_context (g
);
11830 pop_gimplify_context (NULL
);
11832 gimplify_adjust_omp_clauses (pre_p
, body
, &OMP_PARALLEL_CLAUSES (expr
),
11835 g
= gimple_build_omp_parallel (body
,
11836 OMP_PARALLEL_CLAUSES (expr
),
11837 NULL_TREE
, NULL_TREE
);
11838 if (OMP_PARALLEL_COMBINED (expr
))
11839 gimple_omp_set_subcode (g
, GF_OMP_PARALLEL_COMBINED
);
11840 gimplify_seq_add_stmt (pre_p
, g
);
11841 *expr_p
= NULL_TREE
;
11844 /* Gimplify the contents of an OMP_TASK statement. This involves
11845 gimplification of the body, as well as scanning the body for used
11846 variables. We need to do this scan now, because variable-sized
11847 decls will be decomposed during gimplification. */
11850 gimplify_omp_task (tree
*expr_p
, gimple_seq
*pre_p
)
11852 tree expr
= *expr_p
;
11854 gimple_seq body
= NULL
;
11856 if (OMP_TASK_BODY (expr
) == NULL_TREE
)
11857 for (tree c
= OMP_TASK_CLAUSES (expr
); c
; c
= OMP_CLAUSE_CHAIN (c
))
11858 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEPEND
11859 && OMP_CLAUSE_DEPEND_KIND (c
) == OMP_CLAUSE_DEPEND_MUTEXINOUTSET
)
11861 error_at (OMP_CLAUSE_LOCATION (c
),
11862 "%<mutexinoutset%> kind in %<depend%> clause on a "
11863 "%<taskwait%> construct");
11867 gimplify_scan_omp_clauses (&OMP_TASK_CLAUSES (expr
), pre_p
,
11868 omp_find_clause (OMP_TASK_CLAUSES (expr
),
11870 ? ORT_UNTIED_TASK
: ORT_TASK
, OMP_TASK
);
11872 if (OMP_TASK_BODY (expr
))
11874 push_gimplify_context ();
11876 g
= gimplify_and_return_first (OMP_TASK_BODY (expr
), &body
);
11877 if (gimple_code (g
) == GIMPLE_BIND
)
11878 pop_gimplify_context (g
);
11880 pop_gimplify_context (NULL
);
11883 gimplify_adjust_omp_clauses (pre_p
, body
, &OMP_TASK_CLAUSES (expr
),
11886 g
= gimple_build_omp_task (body
,
11887 OMP_TASK_CLAUSES (expr
),
11888 NULL_TREE
, NULL_TREE
,
11889 NULL_TREE
, NULL_TREE
, NULL_TREE
);
11890 if (OMP_TASK_BODY (expr
) == NULL_TREE
)
11891 gimple_omp_task_set_taskwait_p (g
, true);
11892 gimplify_seq_add_stmt (pre_p
, g
);
11893 *expr_p
= NULL_TREE
;
11896 /* Helper function for gimplify_omp_for. If *TP is not a gimple constant,
11897 force it into a temporary initialized in PRE_P and add firstprivate clause
11898 to ORIG_FOR_STMT. */
11901 gimplify_omp_taskloop_expr (tree type
, tree
*tp
, gimple_seq
*pre_p
,
11902 tree orig_for_stmt
)
11904 if (*tp
== NULL
|| is_gimple_constant (*tp
))
11907 *tp
= get_initialized_tmp_var (*tp
, pre_p
, NULL
, false);
11908 /* Reference to pointer conversion is considered useless,
11909 but is significant for firstprivate clause. Force it
11912 && TREE_CODE (type
) == POINTER_TYPE
11913 && TREE_CODE (TREE_TYPE (*tp
)) == REFERENCE_TYPE
)
11915 tree v
= create_tmp_var (TYPE_MAIN_VARIANT (type
));
11916 tree m
= build2 (INIT_EXPR
, TREE_TYPE (v
), v
, *tp
);
11917 gimplify_and_add (m
, pre_p
);
11921 tree c
= build_omp_clause (input_location
, OMP_CLAUSE_FIRSTPRIVATE
);
11922 OMP_CLAUSE_DECL (c
) = *tp
;
11923 OMP_CLAUSE_CHAIN (c
) = OMP_FOR_CLAUSES (orig_for_stmt
);
11924 OMP_FOR_CLAUSES (orig_for_stmt
) = c
;
11927 /* Gimplify the gross structure of an OMP_FOR statement. */
11929 static enum gimplify_status
11930 gimplify_omp_for (tree
*expr_p
, gimple_seq
*pre_p
)
11932 tree for_stmt
, orig_for_stmt
, inner_for_stmt
= NULL_TREE
, decl
, var
, t
;
11933 enum gimplify_status ret
= GS_ALL_DONE
;
11934 enum gimplify_status tret
;
11936 gimple_seq for_body
, for_pre_body
;
11938 bitmap has_decl_expr
= NULL
;
11939 enum omp_region_type ort
= ORT_WORKSHARE
;
11940 bool openacc
= TREE_CODE (*expr_p
) == OACC_LOOP
;
11942 orig_for_stmt
= for_stmt
= *expr_p
;
11944 bool loop_p
= (omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_BIND
)
11946 if (OMP_FOR_INIT (for_stmt
) == NULL_TREE
)
11948 tree
*data
[4] = { NULL
, NULL
, NULL
, NULL
};
11949 gcc_assert (TREE_CODE (for_stmt
) != OACC_LOOP
);
11950 inner_for_stmt
= walk_tree (&OMP_FOR_BODY (for_stmt
),
11951 find_combined_omp_for
, data
, NULL
);
11952 if (inner_for_stmt
== NULL_TREE
)
11954 gcc_assert (seen_error ());
11955 *expr_p
= NULL_TREE
;
11958 if (data
[2] && OMP_FOR_PRE_BODY (*data
[2]))
11960 append_to_statement_list_force (OMP_FOR_PRE_BODY (*data
[2]),
11961 &OMP_FOR_PRE_BODY (for_stmt
));
11962 OMP_FOR_PRE_BODY (*data
[2]) = NULL_TREE
;
11964 if (OMP_FOR_PRE_BODY (inner_for_stmt
))
11966 append_to_statement_list_force (OMP_FOR_PRE_BODY (inner_for_stmt
),
11967 &OMP_FOR_PRE_BODY (for_stmt
));
11968 OMP_FOR_PRE_BODY (inner_for_stmt
) = NULL_TREE
;
11973 /* We have some statements or variable declarations in between
11974 the composite construct directives. Move them around the
11977 for (i
= 0; i
< 3; i
++)
11981 if (i
< 2 && data
[i
+ 1] == &OMP_BODY (t
))
11982 data
[i
+ 1] = data
[i
];
11983 *data
[i
] = OMP_BODY (t
);
11984 tree body
= build3 (BIND_EXPR
, void_type_node
, NULL_TREE
,
11985 NULL_TREE
, make_node (BLOCK
));
11986 OMP_BODY (t
) = body
;
11987 append_to_statement_list_force (inner_for_stmt
,
11988 &BIND_EXPR_BODY (body
));
11990 data
[3] = tsi_stmt_ptr (tsi_start (BIND_EXPR_BODY (body
)));
11991 gcc_assert (*data
[3] == inner_for_stmt
);
11996 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt
)); i
++)
11998 && OMP_FOR_ORIG_DECLS (inner_for_stmt
)
11999 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
),
12001 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
),
12004 tree orig
= TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
), i
);
12005 /* Class iterators aren't allowed on OMP_SIMD, so the only
12006 case we need to solve is distribute parallel for. They are
12007 allowed on the loop construct, but that is already handled
12008 in gimplify_omp_loop. */
12009 gcc_assert (TREE_CODE (inner_for_stmt
) == OMP_FOR
12010 && TREE_CODE (for_stmt
) == OMP_DISTRIBUTE
12012 tree orig_decl
= TREE_PURPOSE (orig
);
12013 tree last
= TREE_VALUE (orig
);
12015 for (pc
= &OMP_FOR_CLAUSES (inner_for_stmt
);
12016 *pc
; pc
= &OMP_CLAUSE_CHAIN (*pc
))
12017 if ((OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_PRIVATE
12018 || OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_LASTPRIVATE
)
12019 && OMP_CLAUSE_DECL (*pc
) == orig_decl
)
12021 if (*pc
== NULL_TREE
)
12024 for (spc
= &OMP_PARALLEL_CLAUSES (*data
[1]);
12025 *spc
; spc
= &OMP_CLAUSE_CHAIN (*spc
))
12026 if (OMP_CLAUSE_CODE (*spc
) == OMP_CLAUSE_PRIVATE
12027 && OMP_CLAUSE_DECL (*spc
) == orig_decl
)
12032 *spc
= OMP_CLAUSE_CHAIN (c
);
12033 OMP_CLAUSE_CHAIN (c
) = NULL_TREE
;
12037 if (*pc
== NULL_TREE
)
12039 else if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_PRIVATE
)
12041 /* private clause will appear only on inner_for_stmt.
12042 Change it into firstprivate, and add private clause
12044 tree c
= copy_node (*pc
);
12045 OMP_CLAUSE_CHAIN (c
) = OMP_FOR_CLAUSES (for_stmt
);
12046 OMP_FOR_CLAUSES (for_stmt
) = c
;
12047 OMP_CLAUSE_CODE (*pc
) = OMP_CLAUSE_FIRSTPRIVATE
;
12048 lang_hooks
.decls
.omp_finish_clause (*pc
, pre_p
, openacc
);
12052 /* lastprivate clause will appear on both inner_for_stmt
12053 and for_stmt. Add firstprivate clause to
12055 tree c
= build_omp_clause (OMP_CLAUSE_LOCATION (*pc
),
12056 OMP_CLAUSE_FIRSTPRIVATE
);
12057 OMP_CLAUSE_DECL (c
) = OMP_CLAUSE_DECL (*pc
);
12058 OMP_CLAUSE_CHAIN (c
) = *pc
;
12060 lang_hooks
.decls
.omp_finish_clause (*pc
, pre_p
, openacc
);
12062 tree c
= build_omp_clause (UNKNOWN_LOCATION
,
12063 OMP_CLAUSE_FIRSTPRIVATE
);
12064 OMP_CLAUSE_DECL (c
) = last
;
12065 OMP_CLAUSE_CHAIN (c
) = OMP_PARALLEL_CLAUSES (*data
[1]);
12066 OMP_PARALLEL_CLAUSES (*data
[1]) = c
;
12067 c
= build_omp_clause (UNKNOWN_LOCATION
,
12068 *pc
? OMP_CLAUSE_SHARED
12069 : OMP_CLAUSE_FIRSTPRIVATE
);
12070 OMP_CLAUSE_DECL (c
) = orig_decl
;
12071 OMP_CLAUSE_CHAIN (c
) = OMP_PARALLEL_CLAUSES (*data
[1]);
12072 OMP_PARALLEL_CLAUSES (*data
[1]) = c
;
12074 /* Similarly, take care of C++ range for temporaries, those should
12075 be firstprivate on OMP_PARALLEL if any. */
12077 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt
)); i
++)
12078 if (OMP_FOR_ORIG_DECLS (inner_for_stmt
)
12079 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
),
12081 && TREE_CHAIN (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
),
12085 = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
), i
);
12086 tree v
= TREE_CHAIN (orig
);
12087 tree c
= build_omp_clause (UNKNOWN_LOCATION
,
12088 OMP_CLAUSE_FIRSTPRIVATE
);
12089 /* First add firstprivate clause for the __for_end artificial
12091 OMP_CLAUSE_DECL (c
) = TREE_VEC_ELT (v
, 1);
12092 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c
)))
12094 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c
) = 1;
12095 OMP_CLAUSE_CHAIN (c
) = OMP_PARALLEL_CLAUSES (*data
[1]);
12096 OMP_PARALLEL_CLAUSES (*data
[1]) = c
;
12097 if (TREE_VEC_ELT (v
, 0))
12099 /* And now the same for __for_range artificial decl if it
12101 c
= build_omp_clause (UNKNOWN_LOCATION
,
12102 OMP_CLAUSE_FIRSTPRIVATE
);
12103 OMP_CLAUSE_DECL (c
) = TREE_VEC_ELT (v
, 0);
12104 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c
)))
12106 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c
) = 1;
12107 OMP_CLAUSE_CHAIN (c
) = OMP_PARALLEL_CLAUSES (*data
[1]);
12108 OMP_PARALLEL_CLAUSES (*data
[1]) = c
;
12113 switch (TREE_CODE (for_stmt
))
12116 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt
? inner_for_stmt
: for_stmt
))
12118 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt
),
12119 OMP_CLAUSE_SCHEDULE
))
12120 error_at (EXPR_LOCATION (for_stmt
),
12121 "%qs clause may not appear on non-rectangular %qs",
12122 "schedule", "for");
12123 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_ORDERED
))
12124 error_at (EXPR_LOCATION (for_stmt
),
12125 "%qs clause may not appear on non-rectangular %qs",
12129 case OMP_DISTRIBUTE
:
12130 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt
? inner_for_stmt
: for_stmt
)
12131 && omp_find_clause (OMP_FOR_CLAUSES (for_stmt
),
12132 OMP_CLAUSE_DIST_SCHEDULE
))
12133 error_at (EXPR_LOCATION (for_stmt
),
12134 "%qs clause may not appear on non-rectangular %qs",
12135 "dist_schedule", "distribute");
12141 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_UNTIED
))
12142 ort
= ORT_UNTIED_TASKLOOP
;
12144 ort
= ORT_TASKLOOP
;
12150 gcc_unreachable ();
12153 /* Set OMP_CLAUSE_LINEAR_NO_COPYIN flag on explicit linear
12154 clause for the IV. */
12155 if (ort
== ORT_SIMD
&& TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)) == 1)
12157 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), 0);
12158 gcc_assert (TREE_CODE (t
) == MODIFY_EXPR
);
12159 decl
= TREE_OPERAND (t
, 0);
12160 for (tree c
= OMP_FOR_CLAUSES (for_stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
12161 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINEAR
12162 && OMP_CLAUSE_DECL (c
) == decl
)
12164 OMP_CLAUSE_LINEAR_NO_COPYIN (c
) = 1;
12169 if (TREE_CODE (for_stmt
) != OMP_TASKLOOP
)
12170 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt
), pre_p
, ort
,
12171 loop_p
&& TREE_CODE (for_stmt
) != OMP_SIMD
12172 ? OMP_LOOP
: TREE_CODE (for_stmt
));
12174 if (TREE_CODE (for_stmt
) == OMP_DISTRIBUTE
)
12175 gimplify_omp_ctxp
->distribute
= true;
12177 /* Handle OMP_FOR_INIT. */
12178 for_pre_body
= NULL
;
12179 if ((ort
== ORT_SIMD
12180 || (inner_for_stmt
&& TREE_CODE (inner_for_stmt
) == OMP_SIMD
))
12181 && OMP_FOR_PRE_BODY (for_stmt
))
12183 has_decl_expr
= BITMAP_ALLOC (NULL
);
12184 if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt
)) == DECL_EXPR
12185 && TREE_CODE (DECL_EXPR_DECL (OMP_FOR_PRE_BODY (for_stmt
)))
12188 t
= OMP_FOR_PRE_BODY (for_stmt
);
12189 bitmap_set_bit (has_decl_expr
, DECL_UID (DECL_EXPR_DECL (t
)));
12191 else if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt
)) == STATEMENT_LIST
)
12193 tree_stmt_iterator si
;
12194 for (si
= tsi_start (OMP_FOR_PRE_BODY (for_stmt
)); !tsi_end_p (si
);
12198 if (TREE_CODE (t
) == DECL_EXPR
12199 && TREE_CODE (DECL_EXPR_DECL (t
)) == VAR_DECL
)
12200 bitmap_set_bit (has_decl_expr
, DECL_UID (DECL_EXPR_DECL (t
)));
12204 if (OMP_FOR_PRE_BODY (for_stmt
))
12206 if (TREE_CODE (for_stmt
) != OMP_TASKLOOP
|| gimplify_omp_ctxp
)
12207 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt
), &for_pre_body
);
12210 struct gimplify_omp_ctx ctx
;
12211 memset (&ctx
, 0, sizeof (ctx
));
12212 ctx
.region_type
= ORT_NONE
;
12213 gimplify_omp_ctxp
= &ctx
;
12214 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt
), &for_pre_body
);
12215 gimplify_omp_ctxp
= NULL
;
12218 OMP_FOR_PRE_BODY (for_stmt
) = NULL_TREE
;
12220 if (OMP_FOR_INIT (for_stmt
) == NULL_TREE
)
12221 for_stmt
= inner_for_stmt
;
12223 /* For taskloop, need to gimplify the start, end and step before the
12224 taskloop, outside of the taskloop omp context. */
12225 if (TREE_CODE (orig_for_stmt
) == OMP_TASKLOOP
)
12227 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
12229 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), i
);
12230 gimple_seq
*for_pre_p
= (gimple_seq_empty_p (for_pre_body
)
12231 ? pre_p
: &for_pre_body
);
12232 tree type
= TREE_TYPE (TREE_OPERAND (t
, 0));
12233 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
)
12235 tree v
= TREE_OPERAND (t
, 1);
12236 gimplify_omp_taskloop_expr (type
, &TREE_VEC_ELT (v
, 1),
12237 for_pre_p
, orig_for_stmt
);
12238 gimplify_omp_taskloop_expr (type
, &TREE_VEC_ELT (v
, 2),
12239 for_pre_p
, orig_for_stmt
);
12242 gimplify_omp_taskloop_expr (type
, &TREE_OPERAND (t
, 1), for_pre_p
,
12245 /* Handle OMP_FOR_COND. */
12246 t
= TREE_VEC_ELT (OMP_FOR_COND (for_stmt
), i
);
12247 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
)
12249 tree v
= TREE_OPERAND (t
, 1);
12250 gimplify_omp_taskloop_expr (type
, &TREE_VEC_ELT (v
, 1),
12251 for_pre_p
, orig_for_stmt
);
12252 gimplify_omp_taskloop_expr (type
, &TREE_VEC_ELT (v
, 2),
12253 for_pre_p
, orig_for_stmt
);
12256 gimplify_omp_taskloop_expr (type
, &TREE_OPERAND (t
, 1), for_pre_p
,
12259 /* Handle OMP_FOR_INCR. */
12260 t
= TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
);
12261 if (TREE_CODE (t
) == MODIFY_EXPR
)
12263 decl
= TREE_OPERAND (t
, 0);
12264 t
= TREE_OPERAND (t
, 1);
12265 tree
*tp
= &TREE_OPERAND (t
, 1);
12266 if (TREE_CODE (t
) == PLUS_EXPR
&& *tp
== decl
)
12267 tp
= &TREE_OPERAND (t
, 0);
12269 gimplify_omp_taskloop_expr (NULL_TREE
, tp
, for_pre_p
,
12274 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (orig_for_stmt
), pre_p
, ort
,
12278 if (orig_for_stmt
!= for_stmt
)
12279 gimplify_omp_ctxp
->combined_loop
= true;
12282 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
))
12283 == TREE_VEC_LENGTH (OMP_FOR_COND (for_stmt
)));
12284 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
))
12285 == TREE_VEC_LENGTH (OMP_FOR_INCR (for_stmt
)));
12287 tree c
= omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_ORDERED
);
12288 bool is_doacross
= false;
12289 if (c
&& OMP_CLAUSE_ORDERED_EXPR (c
))
12291 is_doacross
= true;
12292 gimplify_omp_ctxp
->loop_iter_var
.create (TREE_VEC_LENGTH
12293 (OMP_FOR_INIT (for_stmt
))
12296 int collapse
= 1, tile
= 0;
12297 c
= omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_COLLAPSE
);
12299 collapse
= tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (c
));
12300 c
= omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_TILE
);
12302 tile
= list_length (OMP_CLAUSE_TILE_LIST (c
));
12303 c
= omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_ALLOCATE
);
12304 hash_set
<tree
> *allocate_uids
= NULL
;
12307 allocate_uids
= new hash_set
<tree
>;
12308 for (; c
; c
= OMP_CLAUSE_CHAIN (c
))
12309 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_ALLOCATE
)
12310 allocate_uids
->add (OMP_CLAUSE_DECL (c
));
12312 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
12314 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), i
);
12315 gcc_assert (TREE_CODE (t
) == MODIFY_EXPR
);
12316 decl
= TREE_OPERAND (t
, 0);
12317 gcc_assert (DECL_P (decl
));
12318 gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl
))
12319 || POINTER_TYPE_P (TREE_TYPE (decl
)));
12322 if (TREE_CODE (for_stmt
) == OMP_FOR
&& OMP_FOR_ORIG_DECLS (for_stmt
))
12324 tree orig_decl
= TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
), i
);
12325 if (TREE_CODE (orig_decl
) == TREE_LIST
)
12327 orig_decl
= TREE_PURPOSE (orig_decl
);
12331 gimplify_omp_ctxp
->loop_iter_var
.quick_push (orig_decl
);
12334 gimplify_omp_ctxp
->loop_iter_var
.quick_push (decl
);
12335 gimplify_omp_ctxp
->loop_iter_var
.quick_push (decl
);
12338 if (for_stmt
== orig_for_stmt
)
12340 tree orig_decl
= decl
;
12341 if (OMP_FOR_ORIG_DECLS (for_stmt
))
12343 tree orig_decl
= TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
), i
);
12344 if (TREE_CODE (orig_decl
) == TREE_LIST
)
12346 orig_decl
= TREE_PURPOSE (orig_decl
);
12351 if (is_global_var (orig_decl
) && DECL_THREAD_LOCAL_P (orig_decl
))
12352 error_at (EXPR_LOCATION (for_stmt
),
12353 "threadprivate iteration variable %qD", orig_decl
);
12356 /* Make sure the iteration variable is private. */
12357 tree c
= NULL_TREE
;
12358 tree c2
= NULL_TREE
;
12359 if (orig_for_stmt
!= for_stmt
)
12361 /* Preserve this information until we gimplify the inner simd. */
12363 && bitmap_bit_p (has_decl_expr
, DECL_UID (decl
)))
12364 TREE_PRIVATE (t
) = 1;
12366 else if (ort
== ORT_SIMD
)
12368 splay_tree_node n
= splay_tree_lookup (gimplify_omp_ctxp
->variables
,
12369 (splay_tree_key
) decl
);
12370 omp_is_private (gimplify_omp_ctxp
, decl
,
12371 1 + (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
))
12373 if (n
!= NULL
&& (n
->value
& GOVD_DATA_SHARE_CLASS
) != 0)
12375 omp_notice_variable (gimplify_omp_ctxp
, decl
, true);
12376 if (n
->value
& GOVD_LASTPRIVATE_CONDITIONAL
)
12377 for (tree c3
= omp_find_clause (OMP_FOR_CLAUSES (for_stmt
),
12378 OMP_CLAUSE_LASTPRIVATE
);
12379 c3
; c3
= omp_find_clause (OMP_CLAUSE_CHAIN (c3
),
12380 OMP_CLAUSE_LASTPRIVATE
))
12381 if (OMP_CLAUSE_DECL (c3
) == decl
)
12383 warning_at (OMP_CLAUSE_LOCATION (c3
), 0,
12384 "conditional %<lastprivate%> on loop "
12385 "iterator %qD ignored", decl
);
12386 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3
) = 0;
12387 n
->value
&= ~GOVD_LASTPRIVATE_CONDITIONAL
;
12390 else if (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)) == 1 && !loop_p
)
12392 c
= build_omp_clause (input_location
, OMP_CLAUSE_LINEAR
);
12393 OMP_CLAUSE_LINEAR_NO_COPYIN (c
) = 1;
12394 unsigned int flags
= GOVD_LINEAR
| GOVD_EXPLICIT
| GOVD_SEEN
;
12396 && bitmap_bit_p (has_decl_expr
, DECL_UID (decl
)))
12397 || TREE_PRIVATE (t
))
12399 OMP_CLAUSE_LINEAR_NO_COPYOUT (c
) = 1;
12400 flags
|= GOVD_LINEAR_LASTPRIVATE_NO_OUTER
;
12402 struct gimplify_omp_ctx
*outer
12403 = gimplify_omp_ctxp
->outer_context
;
12404 if (outer
&& !OMP_CLAUSE_LINEAR_NO_COPYOUT (c
))
12406 if (outer
->region_type
== ORT_WORKSHARE
12407 && outer
->combined_loop
)
12409 n
= splay_tree_lookup (outer
->variables
,
12410 (splay_tree_key
)decl
);
12411 if (n
!= NULL
&& (n
->value
& GOVD_LOCAL
) != 0)
12413 OMP_CLAUSE_LINEAR_NO_COPYOUT (c
) = 1;
12414 flags
|= GOVD_LINEAR_LASTPRIVATE_NO_OUTER
;
12418 struct gimplify_omp_ctx
*octx
= outer
->outer_context
;
12420 && octx
->region_type
== ORT_COMBINED_PARALLEL
12421 && octx
->outer_context
12422 && (octx
->outer_context
->region_type
12424 && octx
->outer_context
->combined_loop
)
12426 octx
= octx
->outer_context
;
12427 n
= splay_tree_lookup (octx
->variables
,
12428 (splay_tree_key
)decl
);
12429 if (n
!= NULL
&& (n
->value
& GOVD_LOCAL
) != 0)
12431 OMP_CLAUSE_LINEAR_NO_COPYOUT (c
) = 1;
12432 flags
|= GOVD_LINEAR_LASTPRIVATE_NO_OUTER
;
12439 OMP_CLAUSE_DECL (c
) = decl
;
12440 OMP_CLAUSE_CHAIN (c
) = OMP_FOR_CLAUSES (for_stmt
);
12441 OMP_FOR_CLAUSES (for_stmt
) = c
;
12442 omp_add_variable (gimplify_omp_ctxp
, decl
, flags
);
12443 if (outer
&& !OMP_CLAUSE_LINEAR_NO_COPYOUT (c
))
12444 omp_lastprivate_for_combined_outer_constructs (outer
, decl
,
12451 || !bitmap_bit_p (has_decl_expr
, DECL_UID (decl
)));
12452 if (TREE_PRIVATE (t
))
12453 lastprivate
= false;
12454 if (loop_p
&& OMP_FOR_ORIG_DECLS (for_stmt
))
12456 tree elt
= TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
), i
);
12457 if (TREE_CODE (elt
) == TREE_LIST
&& TREE_PURPOSE (elt
))
12458 lastprivate
= false;
12461 struct gimplify_omp_ctx
*outer
12462 = gimplify_omp_ctxp
->outer_context
;
12463 if (outer
&& lastprivate
)
12464 omp_lastprivate_for_combined_outer_constructs (outer
, decl
,
12467 c
= build_omp_clause (input_location
,
12468 lastprivate
? OMP_CLAUSE_LASTPRIVATE
12469 : OMP_CLAUSE_PRIVATE
);
12470 OMP_CLAUSE_DECL (c
) = decl
;
12471 OMP_CLAUSE_CHAIN (c
) = OMP_FOR_CLAUSES (for_stmt
);
12472 OMP_FOR_CLAUSES (for_stmt
) = c
;
12473 omp_add_variable (gimplify_omp_ctxp
, decl
,
12474 (lastprivate
? GOVD_LASTPRIVATE
: GOVD_PRIVATE
)
12475 | GOVD_EXPLICIT
| GOVD_SEEN
);
12479 else if (omp_is_private (gimplify_omp_ctxp
, decl
, 0))
12481 omp_notice_variable (gimplify_omp_ctxp
, decl
, true);
12482 splay_tree_node n
= splay_tree_lookup (gimplify_omp_ctxp
->variables
,
12483 (splay_tree_key
) decl
);
12484 if (n
&& (n
->value
& GOVD_LASTPRIVATE_CONDITIONAL
))
12485 for (tree c3
= omp_find_clause (OMP_FOR_CLAUSES (for_stmt
),
12486 OMP_CLAUSE_LASTPRIVATE
);
12487 c3
; c3
= omp_find_clause (OMP_CLAUSE_CHAIN (c3
),
12488 OMP_CLAUSE_LASTPRIVATE
))
12489 if (OMP_CLAUSE_DECL (c3
) == decl
)
12491 warning_at (OMP_CLAUSE_LOCATION (c3
), 0,
12492 "conditional %<lastprivate%> on loop "
12493 "iterator %qD ignored", decl
);
12494 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3
) = 0;
12495 n
->value
&= ~GOVD_LASTPRIVATE_CONDITIONAL
;
12499 omp_add_variable (gimplify_omp_ctxp
, decl
, GOVD_PRIVATE
| GOVD_SEEN
);
12501 /* If DECL is not a gimple register, create a temporary variable to act
12502 as an iteration counter. This is valid, since DECL cannot be
12503 modified in the body of the loop. Similarly for any iteration vars
12504 in simd with collapse > 1 where the iterator vars must be
12505 lastprivate. And similarly for vars mentioned in allocate clauses. */
12506 if (orig_for_stmt
!= for_stmt
)
12508 else if (!is_gimple_reg (decl
)
12509 || (ort
== ORT_SIMD
12510 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)) > 1)
12511 || (allocate_uids
&& allocate_uids
->contains (decl
)))
12513 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
12514 /* Make sure omp_add_variable is not called on it prematurely.
12515 We call it ourselves a few lines later. */
12516 gimplify_omp_ctxp
= NULL
;
12517 var
= create_tmp_var (TREE_TYPE (decl
), get_name (decl
));
12518 gimplify_omp_ctxp
= ctx
;
12519 TREE_OPERAND (t
, 0) = var
;
12521 gimplify_seq_add_stmt (&for_body
, gimple_build_assign (decl
, var
));
12523 if (ort
== ORT_SIMD
12524 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)) == 1)
12526 c2
= build_omp_clause (input_location
, OMP_CLAUSE_LINEAR
);
12527 OMP_CLAUSE_LINEAR_NO_COPYIN (c2
) = 1;
12528 OMP_CLAUSE_LINEAR_NO_COPYOUT (c2
) = 1;
12529 OMP_CLAUSE_DECL (c2
) = var
;
12530 OMP_CLAUSE_CHAIN (c2
) = OMP_FOR_CLAUSES (for_stmt
);
12531 OMP_FOR_CLAUSES (for_stmt
) = c2
;
12532 omp_add_variable (gimplify_omp_ctxp
, var
,
12533 GOVD_LINEAR
| GOVD_EXPLICIT
| GOVD_SEEN
);
12534 if (c
== NULL_TREE
)
12541 omp_add_variable (gimplify_omp_ctxp
, var
,
12542 GOVD_PRIVATE
| GOVD_SEEN
);
12547 gimplify_omp_ctxp
->in_for_exprs
= true;
12548 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
)
12550 tree lb
= TREE_OPERAND (t
, 1);
12551 tret
= gimplify_expr (&TREE_VEC_ELT (lb
, 1), &for_pre_body
, NULL
,
12552 is_gimple_val
, fb_rvalue
, false);
12553 ret
= MIN (ret
, tret
);
12554 tret
= gimplify_expr (&TREE_VEC_ELT (lb
, 2), &for_pre_body
, NULL
,
12555 is_gimple_val
, fb_rvalue
, false);
12558 tret
= gimplify_expr (&TREE_OPERAND (t
, 1), &for_pre_body
, NULL
,
12559 is_gimple_val
, fb_rvalue
, false);
12560 gimplify_omp_ctxp
->in_for_exprs
= false;
12561 ret
= MIN (ret
, tret
);
12562 if (ret
== GS_ERROR
)
12565 /* Handle OMP_FOR_COND. */
12566 t
= TREE_VEC_ELT (OMP_FOR_COND (for_stmt
), i
);
12567 gcc_assert (COMPARISON_CLASS_P (t
));
12568 gcc_assert (TREE_OPERAND (t
, 0) == decl
);
12570 gimplify_omp_ctxp
->in_for_exprs
= true;
12571 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
)
12573 tree ub
= TREE_OPERAND (t
, 1);
12574 tret
= gimplify_expr (&TREE_VEC_ELT (ub
, 1), &for_pre_body
, NULL
,
12575 is_gimple_val
, fb_rvalue
, false);
12576 ret
= MIN (ret
, tret
);
12577 tret
= gimplify_expr (&TREE_VEC_ELT (ub
, 2), &for_pre_body
, NULL
,
12578 is_gimple_val
, fb_rvalue
, false);
12581 tret
= gimplify_expr (&TREE_OPERAND (t
, 1), &for_pre_body
, NULL
,
12582 is_gimple_val
, fb_rvalue
, false);
12583 gimplify_omp_ctxp
->in_for_exprs
= false;
12584 ret
= MIN (ret
, tret
);
12586 /* Handle OMP_FOR_INCR. */
12587 t
= TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
);
12588 switch (TREE_CODE (t
))
12590 case PREINCREMENT_EXPR
:
12591 case POSTINCREMENT_EXPR
:
12593 tree decl
= TREE_OPERAND (t
, 0);
12594 /* c_omp_for_incr_canonicalize_ptr() should have been
12595 called to massage things appropriately. */
12596 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl
)));
12598 if (orig_for_stmt
!= for_stmt
)
12600 t
= build_int_cst (TREE_TYPE (decl
), 1);
12602 OMP_CLAUSE_LINEAR_STEP (c
) = t
;
12603 t
= build2 (PLUS_EXPR
, TREE_TYPE (decl
), var
, t
);
12604 t
= build2 (MODIFY_EXPR
, TREE_TYPE (var
), var
, t
);
12605 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
) = t
;
12609 case PREDECREMENT_EXPR
:
12610 case POSTDECREMENT_EXPR
:
12611 /* c_omp_for_incr_canonicalize_ptr() should have been
12612 called to massage things appropriately. */
12613 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl
)));
12614 if (orig_for_stmt
!= for_stmt
)
12616 t
= build_int_cst (TREE_TYPE (decl
), -1);
12618 OMP_CLAUSE_LINEAR_STEP (c
) = t
;
12619 t
= build2 (PLUS_EXPR
, TREE_TYPE (decl
), var
, t
);
12620 t
= build2 (MODIFY_EXPR
, TREE_TYPE (var
), var
, t
);
12621 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
) = t
;
12625 gcc_assert (TREE_OPERAND (t
, 0) == decl
);
12626 TREE_OPERAND (t
, 0) = var
;
12628 t
= TREE_OPERAND (t
, 1);
12629 switch (TREE_CODE (t
))
12632 if (TREE_OPERAND (t
, 1) == decl
)
12634 TREE_OPERAND (t
, 1) = TREE_OPERAND (t
, 0);
12635 TREE_OPERAND (t
, 0) = var
;
12641 case POINTER_PLUS_EXPR
:
12642 gcc_assert (TREE_OPERAND (t
, 0) == decl
);
12643 TREE_OPERAND (t
, 0) = var
;
12646 gcc_unreachable ();
12649 gimplify_omp_ctxp
->in_for_exprs
= true;
12650 tret
= gimplify_expr (&TREE_OPERAND (t
, 1), &for_pre_body
, NULL
,
12651 is_gimple_val
, fb_rvalue
, false);
12652 ret
= MIN (ret
, tret
);
12655 tree step
= TREE_OPERAND (t
, 1);
12656 tree stept
= TREE_TYPE (decl
);
12657 if (POINTER_TYPE_P (stept
))
12659 step
= fold_convert (stept
, step
);
12660 if (TREE_CODE (t
) == MINUS_EXPR
)
12661 step
= fold_build1 (NEGATE_EXPR
, stept
, step
);
12662 OMP_CLAUSE_LINEAR_STEP (c
) = step
;
12663 if (step
!= TREE_OPERAND (t
, 1))
12665 tret
= gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c
),
12666 &for_pre_body
, NULL
,
12667 is_gimple_val
, fb_rvalue
, false);
12668 ret
= MIN (ret
, tret
);
12671 gimplify_omp_ctxp
->in_for_exprs
= false;
12675 gcc_unreachable ();
12681 OMP_CLAUSE_LINEAR_STEP (c2
) = OMP_CLAUSE_LINEAR_STEP (c
);
12684 if ((var
!= decl
|| collapse
> 1 || tile
) && orig_for_stmt
== for_stmt
)
12686 for (c
= OMP_FOR_CLAUSES (for_stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
12687 if (((OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
12688 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
) == NULL
)
12689 || (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINEAR
12690 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c
)
12691 && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c
) == NULL
))
12692 && OMP_CLAUSE_DECL (c
) == decl
)
12694 if (is_doacross
&& (collapse
== 1 || i
>= collapse
))
12698 t
= TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
);
12699 gcc_assert (TREE_CODE (t
) == MODIFY_EXPR
);
12700 gcc_assert (TREE_OPERAND (t
, 0) == var
);
12701 t
= TREE_OPERAND (t
, 1);
12702 gcc_assert (TREE_CODE (t
) == PLUS_EXPR
12703 || TREE_CODE (t
) == MINUS_EXPR
12704 || TREE_CODE (t
) == POINTER_PLUS_EXPR
);
12705 gcc_assert (TREE_OPERAND (t
, 0) == var
);
12706 t
= build2 (TREE_CODE (t
), TREE_TYPE (decl
),
12707 is_doacross
? var
: decl
,
12708 TREE_OPERAND (t
, 1));
12711 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
)
12712 seq
= &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
);
12714 seq
= &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c
);
12715 push_gimplify_context ();
12716 gimplify_assign (decl
, t
, seq
);
12717 gimple
*bind
= NULL
;
12718 if (gimplify_ctxp
->temps
)
12720 bind
= gimple_build_bind (NULL_TREE
, *seq
, NULL_TREE
);
12722 gimplify_seq_add_stmt (seq
, bind
);
12724 pop_gimplify_context (bind
);
12727 if (OMP_FOR_NON_RECTANGULAR (for_stmt
) && var
!= decl
)
12728 for (int j
= i
+ 1; j
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); j
++)
12730 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), j
);
12731 gcc_assert (TREE_CODE (t
) == MODIFY_EXPR
);
12732 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
12733 && TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) == decl
)
12734 TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) = var
;
12735 t
= TREE_VEC_ELT (OMP_FOR_COND (for_stmt
), j
);
12736 gcc_assert (COMPARISON_CLASS_P (t
));
12737 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
12738 && TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) == decl
)
12739 TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) = var
;
12743 BITMAP_FREE (has_decl_expr
);
12744 delete allocate_uids
;
12746 if (TREE_CODE (orig_for_stmt
) == OMP_TASKLOOP
12747 || (loop_p
&& orig_for_stmt
== for_stmt
))
12749 push_gimplify_context ();
12750 if (TREE_CODE (OMP_FOR_BODY (orig_for_stmt
)) != BIND_EXPR
)
12752 OMP_FOR_BODY (orig_for_stmt
)
12753 = build3 (BIND_EXPR
, void_type_node
, NULL
,
12754 OMP_FOR_BODY (orig_for_stmt
), NULL
);
12755 TREE_SIDE_EFFECTS (OMP_FOR_BODY (orig_for_stmt
)) = 1;
12759 gimple
*g
= gimplify_and_return_first (OMP_FOR_BODY (orig_for_stmt
),
12762 if (TREE_CODE (orig_for_stmt
) == OMP_TASKLOOP
12763 || (loop_p
&& orig_for_stmt
== for_stmt
))
12765 if (gimple_code (g
) == GIMPLE_BIND
)
12766 pop_gimplify_context (g
);
12768 pop_gimplify_context (NULL
);
12771 if (orig_for_stmt
!= for_stmt
)
12772 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
12774 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), i
);
12775 decl
= TREE_OPERAND (t
, 0);
12776 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
12777 if (TREE_CODE (orig_for_stmt
) == OMP_TASKLOOP
)
12778 gimplify_omp_ctxp
= ctx
->outer_context
;
12779 var
= create_tmp_var (TREE_TYPE (decl
), get_name (decl
));
12780 gimplify_omp_ctxp
= ctx
;
12781 omp_add_variable (gimplify_omp_ctxp
, var
, GOVD_PRIVATE
| GOVD_SEEN
);
12782 TREE_OPERAND (t
, 0) = var
;
12783 t
= TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
);
12784 TREE_OPERAND (t
, 1) = copy_node (TREE_OPERAND (t
, 1));
12785 TREE_OPERAND (TREE_OPERAND (t
, 1), 0) = var
;
12786 if (OMP_FOR_NON_RECTANGULAR (for_stmt
))
12787 for (int j
= i
+ 1;
12788 j
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); j
++)
12790 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), j
);
12791 gcc_assert (TREE_CODE (t
) == MODIFY_EXPR
);
12792 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
12793 && TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) == decl
)
12795 TREE_OPERAND (t
, 1) = copy_node (TREE_OPERAND (t
, 1));
12796 TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) = var
;
12798 t
= TREE_VEC_ELT (OMP_FOR_COND (for_stmt
), j
);
12799 gcc_assert (COMPARISON_CLASS_P (t
));
12800 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
12801 && TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) == decl
)
12803 TREE_OPERAND (t
, 1) = copy_node (TREE_OPERAND (t
, 1));
12804 TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) = var
;
12809 gimplify_adjust_omp_clauses (pre_p
, for_body
,
12810 &OMP_FOR_CLAUSES (orig_for_stmt
),
12811 TREE_CODE (orig_for_stmt
));
12814 switch (TREE_CODE (orig_for_stmt
))
12816 case OMP_FOR
: kind
= GF_OMP_FOR_KIND_FOR
; break;
12817 case OMP_SIMD
: kind
= GF_OMP_FOR_KIND_SIMD
; break;
12818 case OMP_DISTRIBUTE
: kind
= GF_OMP_FOR_KIND_DISTRIBUTE
; break;
12819 case OMP_TASKLOOP
: kind
= GF_OMP_FOR_KIND_TASKLOOP
; break;
12820 case OACC_LOOP
: kind
= GF_OMP_FOR_KIND_OACC_LOOP
; break;
12822 gcc_unreachable ();
12824 if (loop_p
&& kind
== GF_OMP_FOR_KIND_SIMD
)
12826 gimplify_seq_add_seq (pre_p
, for_pre_body
);
12827 for_pre_body
= NULL
;
12829 gfor
= gimple_build_omp_for (for_body
, kind
, OMP_FOR_CLAUSES (orig_for_stmt
),
12830 TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)),
12832 if (orig_for_stmt
!= for_stmt
)
12833 gimple_omp_for_set_combined_p (gfor
, true);
12834 if (gimplify_omp_ctxp
12835 && (gimplify_omp_ctxp
->combined_loop
12836 || (gimplify_omp_ctxp
->region_type
== ORT_COMBINED_PARALLEL
12837 && gimplify_omp_ctxp
->outer_context
12838 && gimplify_omp_ctxp
->outer_context
->combined_loop
)))
12840 gimple_omp_for_set_combined_into_p (gfor
, true);
12841 if (gimplify_omp_ctxp
->combined_loop
)
12842 gcc_assert (TREE_CODE (orig_for_stmt
) == OMP_SIMD
);
12844 gcc_assert (TREE_CODE (orig_for_stmt
) == OMP_FOR
);
12847 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
12849 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), i
);
12850 gimple_omp_for_set_index (gfor
, i
, TREE_OPERAND (t
, 0));
12851 gimple_omp_for_set_initial (gfor
, i
, TREE_OPERAND (t
, 1));
12852 t
= TREE_VEC_ELT (OMP_FOR_COND (for_stmt
), i
);
12853 gimple_omp_for_set_cond (gfor
, i
, TREE_CODE (t
));
12854 gimple_omp_for_set_final (gfor
, i
, TREE_OPERAND (t
, 1));
12855 t
= TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
);
12856 gimple_omp_for_set_incr (gfor
, i
, TREE_OPERAND (t
, 1));
12859 /* OMP_TASKLOOP is gimplified as two GIMPLE_OMP_FOR taskloop
12860 constructs with GIMPLE_OMP_TASK sandwiched in between them.
12861 The outer taskloop stands for computing the number of iterations,
12862 counts for collapsed loops and holding taskloop specific clauses.
12863 The task construct stands for the effect of data sharing on the
12864 explicit task it creates and the inner taskloop stands for expansion
12865 of the static loop inside of the explicit task construct. */
12866 if (TREE_CODE (orig_for_stmt
) == OMP_TASKLOOP
)
12868 tree
*gfor_clauses_ptr
= gimple_omp_for_clauses_ptr (gfor
);
12869 tree task_clauses
= NULL_TREE
;
12870 tree c
= *gfor_clauses_ptr
;
12871 tree
*gtask_clauses_ptr
= &task_clauses
;
12872 tree outer_for_clauses
= NULL_TREE
;
12873 tree
*gforo_clauses_ptr
= &outer_for_clauses
;
12874 bitmap lastprivate_uids
= NULL
;
12875 if (omp_find_clause (c
, OMP_CLAUSE_ALLOCATE
))
12877 c
= omp_find_clause (c
, OMP_CLAUSE_LASTPRIVATE
);
12880 lastprivate_uids
= BITMAP_ALLOC (NULL
);
12881 for (; c
; c
= omp_find_clause (OMP_CLAUSE_CHAIN (c
),
12882 OMP_CLAUSE_LASTPRIVATE
))
12883 bitmap_set_bit (lastprivate_uids
,
12884 DECL_UID (OMP_CLAUSE_DECL (c
)));
12886 c
= *gfor_clauses_ptr
;
12888 for (; c
; c
= OMP_CLAUSE_CHAIN (c
))
12889 switch (OMP_CLAUSE_CODE (c
))
12891 /* These clauses are allowed on task, move them there. */
12892 case OMP_CLAUSE_SHARED
:
12893 case OMP_CLAUSE_FIRSTPRIVATE
:
12894 case OMP_CLAUSE_DEFAULT
:
12895 case OMP_CLAUSE_IF
:
12896 case OMP_CLAUSE_UNTIED
:
12897 case OMP_CLAUSE_FINAL
:
12898 case OMP_CLAUSE_MERGEABLE
:
12899 case OMP_CLAUSE_PRIORITY
:
12900 case OMP_CLAUSE_REDUCTION
:
12901 case OMP_CLAUSE_IN_REDUCTION
:
12902 *gtask_clauses_ptr
= c
;
12903 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
12905 case OMP_CLAUSE_PRIVATE
:
12906 if (OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c
))
12908 /* We want private on outer for and firstprivate
12911 = build_omp_clause (OMP_CLAUSE_LOCATION (c
),
12912 OMP_CLAUSE_FIRSTPRIVATE
);
12913 OMP_CLAUSE_DECL (*gtask_clauses_ptr
) = OMP_CLAUSE_DECL (c
);
12914 lang_hooks
.decls
.omp_finish_clause (*gtask_clauses_ptr
, NULL
,
12916 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr
);
12917 *gforo_clauses_ptr
= c
;
12918 gforo_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
12922 *gtask_clauses_ptr
= c
;
12923 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
12926 /* These clauses go into outer taskloop clauses. */
12927 case OMP_CLAUSE_GRAINSIZE
:
12928 case OMP_CLAUSE_NUM_TASKS
:
12929 case OMP_CLAUSE_NOGROUP
:
12930 *gforo_clauses_ptr
= c
;
12931 gforo_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
12933 /* Collapse clause we duplicate on both taskloops. */
12934 case OMP_CLAUSE_COLLAPSE
:
12935 *gfor_clauses_ptr
= c
;
12936 gfor_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
12937 *gforo_clauses_ptr
= copy_node (c
);
12938 gforo_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr
);
12940 /* For lastprivate, keep the clause on inner taskloop, and add
12941 a shared clause on task. If the same decl is also firstprivate,
12942 add also firstprivate clause on the inner taskloop. */
12943 case OMP_CLAUSE_LASTPRIVATE
:
12944 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c
))
12946 /* For taskloop C++ lastprivate IVs, we want:
12947 1) private on outer taskloop
12948 2) firstprivate and shared on task
12949 3) lastprivate on inner taskloop */
12951 = build_omp_clause (OMP_CLAUSE_LOCATION (c
),
12952 OMP_CLAUSE_FIRSTPRIVATE
);
12953 OMP_CLAUSE_DECL (*gtask_clauses_ptr
) = OMP_CLAUSE_DECL (c
);
12954 lang_hooks
.decls
.omp_finish_clause (*gtask_clauses_ptr
, NULL
,
12956 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr
);
12957 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
) = 1;
12958 *gforo_clauses_ptr
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
12959 OMP_CLAUSE_PRIVATE
);
12960 OMP_CLAUSE_DECL (*gforo_clauses_ptr
) = OMP_CLAUSE_DECL (c
);
12961 OMP_CLAUSE_PRIVATE_TASKLOOP_IV (*gforo_clauses_ptr
) = 1;
12962 TREE_TYPE (*gforo_clauses_ptr
) = TREE_TYPE (c
);
12963 gforo_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr
);
12965 *gfor_clauses_ptr
= c
;
12966 gfor_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
12968 = build_omp_clause (OMP_CLAUSE_LOCATION (c
), OMP_CLAUSE_SHARED
);
12969 OMP_CLAUSE_DECL (*gtask_clauses_ptr
) = OMP_CLAUSE_DECL (c
);
12970 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
))
12971 OMP_CLAUSE_SHARED_FIRSTPRIVATE (*gtask_clauses_ptr
) = 1;
12973 = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr
);
12975 /* Allocate clause we duplicate on task and inner taskloop
12976 if the decl is lastprivate, otherwise just put on task. */
12977 case OMP_CLAUSE_ALLOCATE
:
12978 if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
)
12979 && DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
)))
12981 /* Additionally, put firstprivate clause on task
12982 for the allocator if it is not constant. */
12984 = build_omp_clause (OMP_CLAUSE_LOCATION (c
),
12985 OMP_CLAUSE_FIRSTPRIVATE
);
12986 OMP_CLAUSE_DECL (*gtask_clauses_ptr
)
12987 = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
);
12988 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr
);
12990 if (lastprivate_uids
12991 && bitmap_bit_p (lastprivate_uids
,
12992 DECL_UID (OMP_CLAUSE_DECL (c
))))
12994 *gfor_clauses_ptr
= c
;
12995 gfor_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
12996 *gtask_clauses_ptr
= copy_node (c
);
12997 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr
);
13001 *gtask_clauses_ptr
= c
;
13002 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
13006 gcc_unreachable ();
13008 *gfor_clauses_ptr
= NULL_TREE
;
13009 *gtask_clauses_ptr
= NULL_TREE
;
13010 *gforo_clauses_ptr
= NULL_TREE
;
13011 BITMAP_FREE (lastprivate_uids
);
13012 g
= gimple_build_bind (NULL_TREE
, gfor
, NULL_TREE
);
13013 g
= gimple_build_omp_task (g
, task_clauses
, NULL_TREE
, NULL_TREE
,
13014 NULL_TREE
, NULL_TREE
, NULL_TREE
);
13015 gimple_omp_task_set_taskloop_p (g
, true);
13016 g
= gimple_build_bind (NULL_TREE
, g
, NULL_TREE
);
13018 = gimple_build_omp_for (g
, GF_OMP_FOR_KIND_TASKLOOP
, outer_for_clauses
,
13019 gimple_omp_for_collapse (gfor
),
13020 gimple_omp_for_pre_body (gfor
));
13021 gimple_omp_for_set_pre_body (gfor
, NULL
);
13022 gimple_omp_for_set_combined_p (gforo
, true);
13023 gimple_omp_for_set_combined_into_p (gfor
, true);
13024 for (i
= 0; i
< (int) gimple_omp_for_collapse (gfor
); i
++)
13026 tree type
= TREE_TYPE (gimple_omp_for_index (gfor
, i
));
13027 tree v
= create_tmp_var (type
);
13028 gimple_omp_for_set_index (gforo
, i
, v
);
13029 t
= unshare_expr (gimple_omp_for_initial (gfor
, i
));
13030 gimple_omp_for_set_initial (gforo
, i
, t
);
13031 gimple_omp_for_set_cond (gforo
, i
,
13032 gimple_omp_for_cond (gfor
, i
));
13033 t
= unshare_expr (gimple_omp_for_final (gfor
, i
));
13034 gimple_omp_for_set_final (gforo
, i
, t
);
13035 t
= unshare_expr (gimple_omp_for_incr (gfor
, i
));
13036 gcc_assert (TREE_OPERAND (t
, 0) == gimple_omp_for_index (gfor
, i
));
13037 TREE_OPERAND (t
, 0) = v
;
13038 gimple_omp_for_set_incr (gforo
, i
, t
);
13039 t
= build_omp_clause (input_location
, OMP_CLAUSE_PRIVATE
);
13040 OMP_CLAUSE_DECL (t
) = v
;
13041 OMP_CLAUSE_CHAIN (t
) = gimple_omp_for_clauses (gforo
);
13042 gimple_omp_for_set_clauses (gforo
, t
);
13043 if (OMP_FOR_NON_RECTANGULAR (for_stmt
))
13045 tree
*p1
= NULL
, *p2
= NULL
;
13046 t
= gimple_omp_for_initial (gforo
, i
);
13047 if (TREE_CODE (t
) == TREE_VEC
)
13048 p1
= &TREE_VEC_ELT (t
, 0);
13049 t
= gimple_omp_for_final (gforo
, i
);
13050 if (TREE_CODE (t
) == TREE_VEC
)
13053 p2
= &TREE_VEC_ELT (t
, 0);
13055 p1
= &TREE_VEC_ELT (t
, 0);
13060 for (j
= 0; j
< i
; j
++)
13061 if (*p1
== gimple_omp_for_index (gfor
, j
))
13063 *p1
= gimple_omp_for_index (gforo
, j
);
13068 gcc_assert (j
< i
);
13072 gimplify_seq_add_stmt (pre_p
, gforo
);
13075 gimplify_seq_add_stmt (pre_p
, gfor
);
13077 if (TREE_CODE (orig_for_stmt
) == OMP_FOR
)
13079 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
13080 unsigned lastprivate_conditional
= 0;
13082 && (ctx
->region_type
== ORT_TARGET_DATA
13083 || ctx
->region_type
== ORT_TASKGROUP
))
13084 ctx
= ctx
->outer_context
;
13085 if (ctx
&& (ctx
->region_type
& ORT_PARALLEL
) != 0)
13086 for (tree c
= gimple_omp_for_clauses (gfor
);
13087 c
; c
= OMP_CLAUSE_CHAIN (c
))
13088 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
13089 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
))
13090 ++lastprivate_conditional
;
13091 if (lastprivate_conditional
)
13093 struct omp_for_data fd
;
13094 omp_extract_for_data (gfor
, &fd
, NULL
);
13095 tree type
= build_array_type_nelts (unsigned_type_for (fd
.iter_type
),
13096 lastprivate_conditional
);
13097 tree var
= create_tmp_var_raw (type
);
13098 tree c
= build_omp_clause (UNKNOWN_LOCATION
, OMP_CLAUSE__CONDTEMP_
);
13099 OMP_CLAUSE_DECL (c
) = var
;
13100 OMP_CLAUSE_CHAIN (c
) = gimple_omp_for_clauses (gfor
);
13101 gimple_omp_for_set_clauses (gfor
, c
);
13102 omp_add_variable (ctx
, var
, GOVD_CONDTEMP
| GOVD_SEEN
);
13105 else if (TREE_CODE (orig_for_stmt
) == OMP_SIMD
)
13107 unsigned lastprivate_conditional
= 0;
13108 for (tree c
= gimple_omp_for_clauses (gfor
); c
; c
= OMP_CLAUSE_CHAIN (c
))
13109 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
13110 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
))
13111 ++lastprivate_conditional
;
13112 if (lastprivate_conditional
)
13114 struct omp_for_data fd
;
13115 omp_extract_for_data (gfor
, &fd
, NULL
);
13116 tree type
= unsigned_type_for (fd
.iter_type
);
13117 while (lastprivate_conditional
--)
13119 tree c
= build_omp_clause (UNKNOWN_LOCATION
,
13120 OMP_CLAUSE__CONDTEMP_
);
13121 OMP_CLAUSE_DECL (c
) = create_tmp_var (type
);
13122 OMP_CLAUSE_CHAIN (c
) = gimple_omp_for_clauses (gfor
);
13123 gimple_omp_for_set_clauses (gfor
, c
);
13128 if (ret
!= GS_ALL_DONE
)
13130 *expr_p
= NULL_TREE
;
13131 return GS_ALL_DONE
;
13134 /* Helper for gimplify_omp_loop, called through walk_tree. */
13137 note_no_context_vars (tree
*tp
, int *, void *data
)
13140 && DECL_CONTEXT (*tp
) == NULL_TREE
13141 && !is_global_var (*tp
))
13143 vec
<tree
> *d
= (vec
<tree
> *) data
;
13144 d
->safe_push (*tp
);
13145 DECL_CONTEXT (*tp
) = current_function_decl
;
13150 /* Gimplify the gross structure of an OMP_LOOP statement. */
13152 static enum gimplify_status
13153 gimplify_omp_loop (tree
*expr_p
, gimple_seq
*pre_p
)
13155 tree for_stmt
= *expr_p
;
13156 tree clauses
= OMP_FOR_CLAUSES (for_stmt
);
13157 struct gimplify_omp_ctx
*octx
= gimplify_omp_ctxp
;
13158 enum omp_clause_bind_kind kind
= OMP_CLAUSE_BIND_THREAD
;
13161 /* If order is not present, the behavior is as if order(concurrent)
13163 tree order
= omp_find_clause (clauses
, OMP_CLAUSE_ORDER
);
13164 if (order
== NULL_TREE
)
13166 order
= build_omp_clause (UNKNOWN_LOCATION
, OMP_CLAUSE_ORDER
);
13167 OMP_CLAUSE_CHAIN (order
) = clauses
;
13168 OMP_FOR_CLAUSES (for_stmt
) = clauses
= order
;
13171 tree bind
= omp_find_clause (clauses
, OMP_CLAUSE_BIND
);
13172 if (bind
== NULL_TREE
)
13174 if (!flag_openmp
) /* flag_openmp_simd */
13176 else if (octx
&& (octx
->region_type
& ORT_TEAMS
) != 0)
13177 kind
= OMP_CLAUSE_BIND_TEAMS
;
13178 else if (octx
&& (octx
->region_type
& ORT_PARALLEL
) != 0)
13179 kind
= OMP_CLAUSE_BIND_PARALLEL
;
13182 for (; octx
; octx
= octx
->outer_context
)
13184 if ((octx
->region_type
& ORT_ACC
) != 0
13185 || octx
->region_type
== ORT_NONE
13186 || octx
->region_type
== ORT_IMPLICIT_TARGET
)
13190 if (octx
== NULL
&& !in_omp_construct
)
13191 error_at (EXPR_LOCATION (for_stmt
),
13192 "%<bind%> clause not specified on a %<loop%> "
13193 "construct not nested inside another OpenMP construct");
13195 bind
= build_omp_clause (UNKNOWN_LOCATION
, OMP_CLAUSE_BIND
);
13196 OMP_CLAUSE_CHAIN (bind
) = clauses
;
13197 OMP_CLAUSE_BIND_KIND (bind
) = kind
;
13198 OMP_FOR_CLAUSES (for_stmt
) = bind
;
13201 switch (OMP_CLAUSE_BIND_KIND (bind
))
13203 case OMP_CLAUSE_BIND_THREAD
:
13205 case OMP_CLAUSE_BIND_PARALLEL
:
13206 if (!flag_openmp
) /* flag_openmp_simd */
13208 OMP_CLAUSE_BIND_KIND (bind
) = OMP_CLAUSE_BIND_THREAD
;
13211 for (; octx
; octx
= octx
->outer_context
)
13212 if (octx
->region_type
== ORT_SIMD
13213 && omp_find_clause (octx
->clauses
, OMP_CLAUSE_BIND
) == NULL_TREE
)
13215 error_at (EXPR_LOCATION (for_stmt
),
13216 "%<bind(parallel)%> on a %<loop%> construct nested "
13217 "inside %<simd%> construct");
13218 OMP_CLAUSE_BIND_KIND (bind
) = OMP_CLAUSE_BIND_THREAD
;
13221 kind
= OMP_CLAUSE_BIND_PARALLEL
;
13223 case OMP_CLAUSE_BIND_TEAMS
:
13224 if (!flag_openmp
) /* flag_openmp_simd */
13226 OMP_CLAUSE_BIND_KIND (bind
) = OMP_CLAUSE_BIND_THREAD
;
13230 && octx
->region_type
!= ORT_IMPLICIT_TARGET
13231 && octx
->region_type
!= ORT_NONE
13232 && (octx
->region_type
& ORT_TEAMS
) == 0)
13233 || in_omp_construct
)
13235 error_at (EXPR_LOCATION (for_stmt
),
13236 "%<bind(teams)%> on a %<loop%> region not strictly "
13237 "nested inside of a %<teams%> region");
13238 OMP_CLAUSE_BIND_KIND (bind
) = OMP_CLAUSE_BIND_THREAD
;
13241 kind
= OMP_CLAUSE_BIND_TEAMS
;
13244 gcc_unreachable ();
13247 for (tree
*pc
= &OMP_FOR_CLAUSES (for_stmt
); *pc
; )
13248 switch (OMP_CLAUSE_CODE (*pc
))
13250 case OMP_CLAUSE_REDUCTION
:
13251 if (OMP_CLAUSE_REDUCTION_INSCAN (*pc
))
13253 error_at (OMP_CLAUSE_LOCATION (*pc
),
13254 "%<inscan%> %<reduction%> clause on "
13255 "%qs construct", "loop");
13256 OMP_CLAUSE_REDUCTION_INSCAN (*pc
) = 0;
13258 if (OMP_CLAUSE_REDUCTION_TASK (*pc
))
13260 error_at (OMP_CLAUSE_LOCATION (*pc
),
13261 "invalid %<task%> reduction modifier on construct "
13262 "other than %<parallel%>, %qs or %<sections%>",
13263 lang_GNU_Fortran () ? "do" : "for");
13264 OMP_CLAUSE_REDUCTION_TASK (*pc
) = 0;
13266 pc
= &OMP_CLAUSE_CHAIN (*pc
);
13268 case OMP_CLAUSE_LASTPRIVATE
:
13269 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
13271 tree t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), i
);
13272 gcc_assert (TREE_CODE (t
) == MODIFY_EXPR
);
13273 if (OMP_CLAUSE_DECL (*pc
) == TREE_OPERAND (t
, 0))
13275 if (OMP_FOR_ORIG_DECLS (for_stmt
)
13276 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
),
13278 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
),
13281 tree orig
= TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
), i
);
13282 if (OMP_CLAUSE_DECL (*pc
) == TREE_PURPOSE (orig
))
13286 if (i
== TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)))
13288 error_at (OMP_CLAUSE_LOCATION (*pc
),
13289 "%<lastprivate%> clause on a %<loop%> construct refers "
13290 "to a variable %qD which is not the loop iterator",
13291 OMP_CLAUSE_DECL (*pc
));
13292 *pc
= OMP_CLAUSE_CHAIN (*pc
);
13295 pc
= &OMP_CLAUSE_CHAIN (*pc
);
13298 pc
= &OMP_CLAUSE_CHAIN (*pc
);
13302 TREE_SET_CODE (for_stmt
, OMP_SIMD
);
13307 case OMP_CLAUSE_BIND_THREAD
: last
= 0; break;
13308 case OMP_CLAUSE_BIND_PARALLEL
: last
= 1; break;
13309 case OMP_CLAUSE_BIND_TEAMS
: last
= 2; break;
13311 for (int pass
= 1; pass
<= last
; pass
++)
13315 tree bind
= build3 (BIND_EXPR
, void_type_node
, NULL
, NULL
,
13316 make_node (BLOCK
));
13317 append_to_statement_list (*expr_p
, &BIND_EXPR_BODY (bind
));
13318 *expr_p
= make_node (OMP_PARALLEL
);
13319 TREE_TYPE (*expr_p
) = void_type_node
;
13320 OMP_PARALLEL_BODY (*expr_p
) = bind
;
13321 OMP_PARALLEL_COMBINED (*expr_p
) = 1;
13322 SET_EXPR_LOCATION (*expr_p
, EXPR_LOCATION (for_stmt
));
13323 tree
*pc
= &OMP_PARALLEL_CLAUSES (*expr_p
);
13324 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
13325 if (OMP_FOR_ORIG_DECLS (for_stmt
)
13326 && (TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
), i
))
13329 tree elt
= TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
), i
);
13330 if (TREE_PURPOSE (elt
) && TREE_VALUE (elt
))
13332 *pc
= build_omp_clause (UNKNOWN_LOCATION
,
13333 OMP_CLAUSE_FIRSTPRIVATE
);
13334 OMP_CLAUSE_DECL (*pc
) = TREE_VALUE (elt
);
13335 pc
= &OMP_CLAUSE_CHAIN (*pc
);
13339 tree t
= make_node (pass
== 2 ? OMP_DISTRIBUTE
: OMP_FOR
);
13340 tree
*pc
= &OMP_FOR_CLAUSES (t
);
13341 TREE_TYPE (t
) = void_type_node
;
13342 OMP_FOR_BODY (t
) = *expr_p
;
13343 SET_EXPR_LOCATION (t
, EXPR_LOCATION (for_stmt
));
13344 for (tree c
= OMP_FOR_CLAUSES (for_stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
13345 switch (OMP_CLAUSE_CODE (c
))
13347 case OMP_CLAUSE_BIND
:
13348 case OMP_CLAUSE_ORDER
:
13349 case OMP_CLAUSE_COLLAPSE
:
13350 *pc
= copy_node (c
);
13351 pc
= &OMP_CLAUSE_CHAIN (*pc
);
13353 case OMP_CLAUSE_PRIVATE
:
13354 case OMP_CLAUSE_FIRSTPRIVATE
:
13355 /* Only needed on innermost. */
13357 case OMP_CLAUSE_LASTPRIVATE
:
13358 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c
) && pass
!= last
)
13360 *pc
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
13361 OMP_CLAUSE_FIRSTPRIVATE
);
13362 OMP_CLAUSE_DECL (*pc
) = OMP_CLAUSE_DECL (c
);
13363 lang_hooks
.decls
.omp_finish_clause (*pc
, NULL
, false);
13364 pc
= &OMP_CLAUSE_CHAIN (*pc
);
13366 *pc
= copy_node (c
);
13367 OMP_CLAUSE_LASTPRIVATE_STMT (*pc
) = NULL_TREE
;
13368 TREE_TYPE (*pc
) = unshare_expr (TREE_TYPE (c
));
13369 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c
))
13372 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (*pc
) = 1;
13374 lang_hooks
.decls
.omp_finish_clause (*pc
, NULL
, false);
13375 OMP_CLAUSE_LASTPRIVATE_LOOP_IV (*pc
) = 0;
13377 pc
= &OMP_CLAUSE_CHAIN (*pc
);
13379 case OMP_CLAUSE_REDUCTION
:
13380 *pc
= copy_node (c
);
13381 OMP_CLAUSE_DECL (*pc
) = unshare_expr (OMP_CLAUSE_DECL (c
));
13382 TREE_TYPE (*pc
) = unshare_expr (TREE_TYPE (c
));
13383 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc
))
13385 auto_vec
<tree
> no_context_vars
;
13386 int walk_subtrees
= 0;
13387 note_no_context_vars (&OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
),
13388 &walk_subtrees
, &no_context_vars
);
13389 if (tree p
= OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c
))
13390 note_no_context_vars (&p
, &walk_subtrees
, &no_context_vars
);
13391 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_INIT (c
),
13392 note_no_context_vars
,
13394 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_MERGE (c
),
13395 note_no_context_vars
,
13398 OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc
)
13399 = copy_node (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
));
13400 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc
))
13401 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc
)
13402 = copy_node (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c
));
13404 hash_map
<tree
, tree
> decl_map
;
13405 decl_map
.put (OMP_CLAUSE_DECL (c
), OMP_CLAUSE_DECL (c
));
13406 decl_map
.put (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
),
13407 OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc
));
13408 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc
))
13409 decl_map
.put (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c
),
13410 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc
));
13413 memset (&id
, 0, sizeof (id
));
13414 id
.src_fn
= current_function_decl
;
13415 id
.dst_fn
= current_function_decl
;
13416 id
.src_cfun
= cfun
;
13417 id
.decl_map
= &decl_map
;
13418 id
.copy_decl
= copy_decl_no_change
;
13419 id
.transform_call_graph_edges
= CB_CGE_DUPLICATE
;
13420 id
.transform_new_cfg
= true;
13421 id
.transform_return_to_modify
= false;
13423 walk_tree (&OMP_CLAUSE_REDUCTION_INIT (*pc
), copy_tree_body_r
,
13425 walk_tree (&OMP_CLAUSE_REDUCTION_MERGE (*pc
), copy_tree_body_r
,
13428 for (tree d
: no_context_vars
)
13430 DECL_CONTEXT (d
) = NULL_TREE
;
13431 DECL_CONTEXT (*decl_map
.get (d
)) = NULL_TREE
;
13436 OMP_CLAUSE_REDUCTION_INIT (*pc
)
13437 = unshare_expr (OMP_CLAUSE_REDUCTION_INIT (c
));
13438 OMP_CLAUSE_REDUCTION_MERGE (*pc
)
13439 = unshare_expr (OMP_CLAUSE_REDUCTION_MERGE (c
));
13441 pc
= &OMP_CLAUSE_CHAIN (*pc
);
13444 gcc_unreachable ();
13449 return gimplify_omp_for (expr_p
, pre_p
);
13453 /* Helper function of optimize_target_teams, find OMP_TEAMS inside
13454 of OMP_TARGET's body. */
13457 find_omp_teams (tree
*tp
, int *walk_subtrees
, void *)
13459 *walk_subtrees
= 0;
13460 switch (TREE_CODE (*tp
))
13465 case STATEMENT_LIST
:
13466 *walk_subtrees
= 1;
13474 /* Helper function of optimize_target_teams, determine if the expression
13475 can be computed safely before the target construct on the host. */
13478 computable_teams_clause (tree
*tp
, int *walk_subtrees
, void *)
13484 *walk_subtrees
= 0;
13487 switch (TREE_CODE (*tp
))
13492 *walk_subtrees
= 0;
13493 if (error_operand_p (*tp
)
13494 || !INTEGRAL_TYPE_P (TREE_TYPE (*tp
))
13495 || DECL_HAS_VALUE_EXPR_P (*tp
)
13496 || DECL_THREAD_LOCAL_P (*tp
)
13497 || TREE_SIDE_EFFECTS (*tp
)
13498 || TREE_THIS_VOLATILE (*tp
))
13500 if (is_global_var (*tp
)
13501 && (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (*tp
))
13502 || lookup_attribute ("omp declare target link",
13503 DECL_ATTRIBUTES (*tp
))))
13506 && !DECL_SEEN_IN_BIND_EXPR_P (*tp
)
13507 && !is_global_var (*tp
)
13508 && decl_function_context (*tp
) == current_function_decl
)
13510 n
= splay_tree_lookup (gimplify_omp_ctxp
->variables
,
13511 (splay_tree_key
) *tp
);
13514 if (gimplify_omp_ctxp
->defaultmap
[GDMK_SCALAR
] & GOVD_FIRSTPRIVATE
)
13518 else if (n
->value
& GOVD_LOCAL
)
13520 else if (n
->value
& GOVD_FIRSTPRIVATE
)
13522 else if ((n
->value
& (GOVD_MAP
| GOVD_MAP_ALWAYS_TO
))
13523 == (GOVD_MAP
| GOVD_MAP_ALWAYS_TO
))
13527 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp
)))
13531 if (TARGET_EXPR_INITIAL (*tp
)
13532 || TREE_CODE (TARGET_EXPR_SLOT (*tp
)) != VAR_DECL
)
13534 return computable_teams_clause (&TARGET_EXPR_SLOT (*tp
),
13535 walk_subtrees
, NULL
);
13536 /* Allow some reasonable subset of integral arithmetics. */
13540 case TRUNC_DIV_EXPR
:
13541 case CEIL_DIV_EXPR
:
13542 case FLOOR_DIV_EXPR
:
13543 case ROUND_DIV_EXPR
:
13544 case TRUNC_MOD_EXPR
:
13545 case CEIL_MOD_EXPR
:
13546 case FLOOR_MOD_EXPR
:
13547 case ROUND_MOD_EXPR
:
13549 case EXACT_DIV_EXPR
:
13560 case NON_LVALUE_EXPR
:
13562 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp
)))
13565 /* And disallow anything else, except for comparisons. */
13567 if (COMPARISON_CLASS_P (*tp
))
13573 /* Try to determine if the num_teams and/or thread_limit expressions
13574 can have their values determined already before entering the
13576 INTEGER_CSTs trivially are,
13577 integral decls that are firstprivate (explicitly or implicitly)
13578 or explicitly map(always, to:) or map(always, tofrom:) on the target
13579 region too, and expressions involving simple arithmetics on those
13580 too, function calls are not ok, dereferencing something neither etc.
13581 Add NUM_TEAMS and THREAD_LIMIT clauses to the OMP_CLAUSES of
13582 EXPR based on what we find:
13583 0 stands for clause not specified at all, use implementation default
13584 -1 stands for value that can't be determined easily before entering
13585 the target construct.
13586 If teams construct is not present at all, use 1 for num_teams
13587 and 0 for thread_limit (only one team is involved, and the thread
13588 limit is implementation defined. */
13591 optimize_target_teams (tree target
, gimple_seq
*pre_p
)
13593 tree body
= OMP_BODY (target
);
13594 tree teams
= walk_tree (&body
, find_omp_teams
, NULL
, NULL
);
13595 tree num_teams_lower
= NULL_TREE
;
13596 tree num_teams_upper
= integer_zero_node
;
13597 tree thread_limit
= integer_zero_node
;
13598 location_t num_teams_loc
= EXPR_LOCATION (target
);
13599 location_t thread_limit_loc
= EXPR_LOCATION (target
);
13601 struct gimplify_omp_ctx
*target_ctx
= gimplify_omp_ctxp
;
13603 if (teams
== NULL_TREE
)
13604 num_teams_upper
= integer_one_node
;
13606 for (c
= OMP_TEAMS_CLAUSES (teams
); c
; c
= OMP_CLAUSE_CHAIN (c
))
13608 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_NUM_TEAMS
)
13610 p
= &num_teams_upper
;
13611 num_teams_loc
= OMP_CLAUSE_LOCATION (c
);
13612 if (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c
))
13614 expr
= OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c
);
13615 if (TREE_CODE (expr
) == INTEGER_CST
)
13616 num_teams_lower
= expr
;
13617 else if (walk_tree (&expr
, computable_teams_clause
,
13619 num_teams_lower
= integer_minus_one_node
;
13622 num_teams_lower
= expr
;
13623 gimplify_omp_ctxp
= gimplify_omp_ctxp
->outer_context
;
13624 if (gimplify_expr (&num_teams_lower
, pre_p
, NULL
,
13625 is_gimple_val
, fb_rvalue
, false)
13628 gimplify_omp_ctxp
= target_ctx
;
13629 num_teams_lower
= integer_minus_one_node
;
13633 gimplify_omp_ctxp
= target_ctx
;
13634 if (!DECL_P (expr
) && TREE_CODE (expr
) != TARGET_EXPR
)
13635 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c
)
13641 else if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_THREAD_LIMIT
)
13644 thread_limit_loc
= OMP_CLAUSE_LOCATION (c
);
13648 expr
= OMP_CLAUSE_OPERAND (c
, 0);
13649 if (TREE_CODE (expr
) == INTEGER_CST
)
13654 if (walk_tree (&expr
, computable_teams_clause
, NULL
, NULL
))
13656 *p
= integer_minus_one_node
;
13660 gimplify_omp_ctxp
= gimplify_omp_ctxp
->outer_context
;
13661 if (gimplify_expr (p
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
, false)
13664 gimplify_omp_ctxp
= target_ctx
;
13665 *p
= integer_minus_one_node
;
13668 gimplify_omp_ctxp
= target_ctx
;
13669 if (!DECL_P (expr
) && TREE_CODE (expr
) != TARGET_EXPR
)
13670 OMP_CLAUSE_OPERAND (c
, 0) = *p
;
13672 if (!omp_find_clause (OMP_TARGET_CLAUSES (target
), OMP_CLAUSE_THREAD_LIMIT
))
13674 c
= build_omp_clause (thread_limit_loc
, OMP_CLAUSE_THREAD_LIMIT
);
13675 OMP_CLAUSE_THREAD_LIMIT_EXPR (c
) = thread_limit
;
13676 OMP_CLAUSE_CHAIN (c
) = OMP_TARGET_CLAUSES (target
);
13677 OMP_TARGET_CLAUSES (target
) = c
;
13679 c
= build_omp_clause (num_teams_loc
, OMP_CLAUSE_NUM_TEAMS
);
13680 OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c
) = num_teams_upper
;
13681 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c
) = num_teams_lower
;
13682 OMP_CLAUSE_CHAIN (c
) = OMP_TARGET_CLAUSES (target
);
13683 OMP_TARGET_CLAUSES (target
) = c
;
13686 /* Gimplify the gross structure of several OMP constructs. */
13689 gimplify_omp_workshare (tree
*expr_p
, gimple_seq
*pre_p
)
13691 tree expr
= *expr_p
;
13693 gimple_seq body
= NULL
;
13694 enum omp_region_type ort
;
13696 switch (TREE_CODE (expr
))
13700 ort
= ORT_WORKSHARE
;
13703 ort
= ORT_TASKGROUP
;
13706 ort
= OMP_TARGET_COMBINED (expr
) ? ORT_COMBINED_TARGET
: ORT_TARGET
;
13709 ort
= ORT_ACC_KERNELS
;
13711 case OACC_PARALLEL
:
13712 ort
= ORT_ACC_PARALLEL
;
13715 ort
= ORT_ACC_SERIAL
;
13718 ort
= ORT_ACC_DATA
;
13720 case OMP_TARGET_DATA
:
13721 ort
= ORT_TARGET_DATA
;
13724 ort
= OMP_TEAMS_COMBINED (expr
) ? ORT_COMBINED_TEAMS
: ORT_TEAMS
;
13725 if (gimplify_omp_ctxp
== NULL
13726 || gimplify_omp_ctxp
->region_type
== ORT_IMPLICIT_TARGET
)
13727 ort
= (enum omp_region_type
) (ort
| ORT_HOST_TEAMS
);
13729 case OACC_HOST_DATA
:
13730 ort
= ORT_ACC_HOST_DATA
;
13733 gcc_unreachable ();
13736 bool save_in_omp_construct
= in_omp_construct
;
13737 if ((ort
& ORT_ACC
) == 0)
13738 in_omp_construct
= false;
13739 gimplify_scan_omp_clauses (&OMP_CLAUSES (expr
), pre_p
, ort
,
13741 if (TREE_CODE (expr
) == OMP_TARGET
)
13742 optimize_target_teams (expr
, pre_p
);
13743 if ((ort
& (ORT_TARGET
| ORT_TARGET_DATA
)) != 0
13744 || (ort
& ORT_HOST_TEAMS
) == ORT_HOST_TEAMS
)
13746 push_gimplify_context ();
13747 gimple
*g
= gimplify_and_return_first (OMP_BODY (expr
), &body
);
13748 if (gimple_code (g
) == GIMPLE_BIND
)
13749 pop_gimplify_context (g
);
13751 pop_gimplify_context (NULL
);
13752 if ((ort
& ORT_TARGET_DATA
) != 0)
13754 enum built_in_function end_ix
;
13755 switch (TREE_CODE (expr
))
13758 case OACC_HOST_DATA
:
13759 end_ix
= BUILT_IN_GOACC_DATA_END
;
13761 case OMP_TARGET_DATA
:
13762 end_ix
= BUILT_IN_GOMP_TARGET_END_DATA
;
13765 gcc_unreachable ();
13767 tree fn
= builtin_decl_explicit (end_ix
);
13768 g
= gimple_build_call (fn
, 0);
13769 gimple_seq cleanup
= NULL
;
13770 gimple_seq_add_stmt (&cleanup
, g
);
13771 g
= gimple_build_try (body
, cleanup
, GIMPLE_TRY_FINALLY
);
13773 gimple_seq_add_stmt (&body
, g
);
13777 gimplify_and_add (OMP_BODY (expr
), &body
);
13778 gimplify_adjust_omp_clauses (pre_p
, body
, &OMP_CLAUSES (expr
),
13780 in_omp_construct
= save_in_omp_construct
;
13782 switch (TREE_CODE (expr
))
13785 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_OACC_DATA
,
13786 OMP_CLAUSES (expr
));
13788 case OACC_HOST_DATA
:
13789 if (omp_find_clause (OMP_CLAUSES (expr
), OMP_CLAUSE_IF_PRESENT
))
13791 for (tree c
= OMP_CLAUSES (expr
); c
; c
= OMP_CLAUSE_CHAIN (c
))
13792 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_USE_DEVICE_PTR
)
13793 OMP_CLAUSE_USE_DEVICE_PTR_IF_PRESENT (c
) = 1;
13796 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_OACC_HOST_DATA
,
13797 OMP_CLAUSES (expr
));
13800 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_OACC_KERNELS
,
13801 OMP_CLAUSES (expr
));
13803 case OACC_PARALLEL
:
13804 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_OACC_PARALLEL
,
13805 OMP_CLAUSES (expr
));
13808 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_OACC_SERIAL
,
13809 OMP_CLAUSES (expr
));
13812 stmt
= gimple_build_omp_sections (body
, OMP_CLAUSES (expr
));
13815 stmt
= gimple_build_omp_single (body
, OMP_CLAUSES (expr
));
13818 stmt
= gimple_build_omp_scope (body
, OMP_CLAUSES (expr
));
13821 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_REGION
,
13822 OMP_CLAUSES (expr
));
13824 case OMP_TARGET_DATA
:
13825 /* Put use_device_{ptr,addr} clauses last, as map clauses are supposed
13826 to be evaluated before the use_device_{ptr,addr} clauses if they
13827 refer to the same variables. */
13829 tree use_device_clauses
;
13830 tree
*pc
, *uc
= &use_device_clauses
;
13831 for (pc
= &OMP_CLAUSES (expr
); *pc
; )
13832 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_USE_DEVICE_PTR
13833 || OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_USE_DEVICE_ADDR
)
13836 *pc
= OMP_CLAUSE_CHAIN (*pc
);
13837 uc
= &OMP_CLAUSE_CHAIN (*uc
);
13840 pc
= &OMP_CLAUSE_CHAIN (*pc
);
13842 *pc
= use_device_clauses
;
13843 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_DATA
,
13844 OMP_CLAUSES (expr
));
13848 stmt
= gimple_build_omp_teams (body
, OMP_CLAUSES (expr
));
13849 if ((ort
& ORT_HOST_TEAMS
) == ORT_HOST_TEAMS
)
13850 gimple_omp_teams_set_host (as_a
<gomp_teams
*> (stmt
), true);
13853 gcc_unreachable ();
13856 gimplify_seq_add_stmt (pre_p
, stmt
);
13857 *expr_p
= NULL_TREE
;
13860 /* Gimplify the gross structure of OpenACC enter/exit data, update, and OpenMP
13861 target update constructs. */
13864 gimplify_omp_target_update (tree
*expr_p
, gimple_seq
*pre_p
)
13866 tree expr
= *expr_p
;
13869 enum omp_region_type ort
= ORT_WORKSHARE
;
13871 switch (TREE_CODE (expr
))
13873 case OACC_ENTER_DATA
:
13874 kind
= GF_OMP_TARGET_KIND_OACC_ENTER_DATA
;
13877 case OACC_EXIT_DATA
:
13878 kind
= GF_OMP_TARGET_KIND_OACC_EXIT_DATA
;
13882 kind
= GF_OMP_TARGET_KIND_OACC_UPDATE
;
13885 case OMP_TARGET_UPDATE
:
13886 kind
= GF_OMP_TARGET_KIND_UPDATE
;
13888 case OMP_TARGET_ENTER_DATA
:
13889 kind
= GF_OMP_TARGET_KIND_ENTER_DATA
;
13891 case OMP_TARGET_EXIT_DATA
:
13892 kind
= GF_OMP_TARGET_KIND_EXIT_DATA
;
13895 gcc_unreachable ();
13897 gimplify_scan_omp_clauses (&OMP_STANDALONE_CLAUSES (expr
), pre_p
,
13898 ort
, TREE_CODE (expr
));
13899 gimplify_adjust_omp_clauses (pre_p
, NULL
, &OMP_STANDALONE_CLAUSES (expr
),
13901 if (TREE_CODE (expr
) == OACC_UPDATE
13902 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr
),
13903 OMP_CLAUSE_IF_PRESENT
))
13905 /* The runtime uses GOMP_MAP_{TO,FROM} to denote the if_present
13907 for (tree c
= OMP_STANDALONE_CLAUSES (expr
); c
; c
= OMP_CLAUSE_CHAIN (c
))
13908 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_MAP
)
13909 switch (OMP_CLAUSE_MAP_KIND (c
))
13911 case GOMP_MAP_FORCE_TO
:
13912 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_TO
);
13914 case GOMP_MAP_FORCE_FROM
:
13915 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_FROM
);
13921 else if (TREE_CODE (expr
) == OACC_EXIT_DATA
13922 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr
),
13923 OMP_CLAUSE_FINALIZE
))
13925 /* Use GOMP_MAP_DELETE/GOMP_MAP_FORCE_FROM to denote "finalize"
13927 bool have_clause
= false;
13928 for (tree c
= OMP_STANDALONE_CLAUSES (expr
); c
; c
= OMP_CLAUSE_CHAIN (c
))
13929 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_MAP
)
13930 switch (OMP_CLAUSE_MAP_KIND (c
))
13932 case GOMP_MAP_FROM
:
13933 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_FORCE_FROM
);
13934 have_clause
= true;
13936 case GOMP_MAP_RELEASE
:
13937 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_DELETE
);
13938 have_clause
= true;
13940 case GOMP_MAP_TO_PSET
:
13941 /* Fortran arrays with descriptors must map that descriptor when
13942 doing standalone "attach" operations (in OpenACC). In that
13943 case GOMP_MAP_TO_PSET appears by itself with no preceding
13944 clause (see trans-openmp.c:gfc_trans_omp_clauses). */
13946 case GOMP_MAP_POINTER
:
13947 /* TODO PR92929: we may see these here, but they'll always follow
13948 one of the clauses above, and will be handled by libgomp as
13949 one group, so no handling required here. */
13950 gcc_assert (have_clause
);
13952 case GOMP_MAP_DETACH
:
13953 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_FORCE_DETACH
);
13954 have_clause
= false;
13956 case GOMP_MAP_STRUCT
:
13957 have_clause
= false;
13960 gcc_unreachable ();
13963 stmt
= gimple_build_omp_target (NULL
, kind
, OMP_STANDALONE_CLAUSES (expr
));
13965 gimplify_seq_add_stmt (pre_p
, stmt
);
13966 *expr_p
= NULL_TREE
;
13969 /* A subroutine of gimplify_omp_atomic. The front end is supposed to have
13970 stabilized the lhs of the atomic operation as *ADDR. Return true if
13971 EXPR is this stabilized form. */
13974 goa_lhs_expr_p (tree expr
, tree addr
)
13976 /* Also include casts to other type variants. The C front end is fond
13977 of adding these for e.g. volatile variables. This is like
13978 STRIP_TYPE_NOPS but includes the main variant lookup. */
13979 STRIP_USELESS_TYPE_CONVERSION (expr
);
13981 if (TREE_CODE (expr
) == INDIRECT_REF
)
13983 expr
= TREE_OPERAND (expr
, 0);
13984 while (expr
!= addr
13985 && (CONVERT_EXPR_P (expr
)
13986 || TREE_CODE (expr
) == NON_LVALUE_EXPR
)
13987 && TREE_CODE (expr
) == TREE_CODE (addr
)
13988 && types_compatible_p (TREE_TYPE (expr
), TREE_TYPE (addr
)))
13990 expr
= TREE_OPERAND (expr
, 0);
13991 addr
= TREE_OPERAND (addr
, 0);
13995 return (TREE_CODE (addr
) == ADDR_EXPR
13996 && TREE_CODE (expr
) == ADDR_EXPR
13997 && TREE_OPERAND (addr
, 0) == TREE_OPERAND (expr
, 0));
13999 if (TREE_CODE (addr
) == ADDR_EXPR
&& expr
== TREE_OPERAND (addr
, 0))
14004 /* Walk *EXPR_P and replace appearances of *LHS_ADDR with LHS_VAR. If an
14005 expression does not involve the lhs, evaluate it into a temporary.
14006 Return 1 if the lhs appeared as a subexpression, 0 if it did not,
14007 or -1 if an error was encountered. */
14010 goa_stabilize_expr (tree
*expr_p
, gimple_seq
*pre_p
, tree lhs_addr
,
14011 tree lhs_var
, tree
&target_expr
, bool rhs
, int depth
)
14013 tree expr
= *expr_p
;
14016 if (goa_lhs_expr_p (expr
, lhs_addr
))
14022 if (is_gimple_val (expr
))
14025 /* Maximum depth of lhs in expression is for the
14026 __builtin_clear_padding (...), __builtin_clear_padding (...),
14027 __builtin_memcmp (&TARGET_EXPR <lhs, >, ...) == 0 ? ... : lhs; */
14031 switch (TREE_CODE_CLASS (TREE_CODE (expr
)))
14034 case tcc_comparison
:
14035 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 1), pre_p
, lhs_addr
,
14036 lhs_var
, target_expr
, true, depth
);
14039 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 0), pre_p
, lhs_addr
,
14040 lhs_var
, target_expr
, true, depth
);
14042 case tcc_expression
:
14043 switch (TREE_CODE (expr
))
14045 case TRUTH_ANDIF_EXPR
:
14046 case TRUTH_ORIF_EXPR
:
14047 case TRUTH_AND_EXPR
:
14048 case TRUTH_OR_EXPR
:
14049 case TRUTH_XOR_EXPR
:
14050 case BIT_INSERT_EXPR
:
14051 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 1), pre_p
,
14052 lhs_addr
, lhs_var
, target_expr
, true,
14055 case TRUTH_NOT_EXPR
:
14056 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 0), pre_p
,
14057 lhs_addr
, lhs_var
, target_expr
, true,
14061 if (pre_p
&& !goa_stabilize_expr (expr_p
, NULL
, lhs_addr
, lhs_var
,
14062 target_expr
, true, depth
))
14064 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 1), pre_p
,
14065 lhs_addr
, lhs_var
, target_expr
, true,
14067 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 0), pre_p
,
14068 lhs_addr
, lhs_var
, target_expr
, false,
14073 if (pre_p
&& !goa_stabilize_expr (expr_p
, NULL
, lhs_addr
, lhs_var
,
14074 target_expr
, true, depth
))
14076 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 0), pre_p
,
14077 lhs_addr
, lhs_var
, target_expr
, false,
14080 case COMPOUND_EXPR
:
14081 /* Break out any preevaluations from cp_build_modify_expr. */
14082 for (; TREE_CODE (expr
) == COMPOUND_EXPR
;
14083 expr
= TREE_OPERAND (expr
, 1))
14085 /* Special-case __builtin_clear_padding call before
14086 __builtin_memcmp. */
14087 if (TREE_CODE (TREE_OPERAND (expr
, 0)) == CALL_EXPR
)
14089 tree fndecl
= get_callee_fndecl (TREE_OPERAND (expr
, 0));
14091 && fndecl_built_in_p (fndecl
, BUILT_IN_CLEAR_PADDING
)
14092 && VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (expr
, 0)))
14094 || goa_stabilize_expr (&TREE_OPERAND (expr
, 0), NULL
,
14096 target_expr
, true, depth
)))
14100 saw_lhs
= goa_stabilize_expr (&TREE_OPERAND (expr
, 0),
14101 pre_p
, lhs_addr
, lhs_var
,
14102 target_expr
, true, depth
);
14103 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 1),
14104 pre_p
, lhs_addr
, lhs_var
,
14105 target_expr
, rhs
, depth
);
14111 gimplify_stmt (&TREE_OPERAND (expr
, 0), pre_p
);
14114 return goa_stabilize_expr (&expr
, pre_p
, lhs_addr
, lhs_var
,
14115 target_expr
, rhs
, depth
);
14117 return goa_stabilize_expr (expr_p
, pre_p
, lhs_addr
, lhs_var
,
14118 target_expr
, rhs
, depth
);
14120 if (!goa_stabilize_expr (&TREE_OPERAND (expr
, 0), NULL
, lhs_addr
,
14121 lhs_var
, target_expr
, true, depth
))
14123 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 0), pre_p
,
14124 lhs_addr
, lhs_var
, target_expr
, true,
14126 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 1), pre_p
,
14127 lhs_addr
, lhs_var
, target_expr
, true,
14129 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 2), pre_p
,
14130 lhs_addr
, lhs_var
, target_expr
, true,
14134 if (TARGET_EXPR_INITIAL (expr
))
14136 if (pre_p
&& !goa_stabilize_expr (expr_p
, NULL
, lhs_addr
,
14137 lhs_var
, target_expr
, true,
14140 if (expr
== target_expr
)
14144 saw_lhs
= goa_stabilize_expr (&TARGET_EXPR_INITIAL (expr
),
14145 pre_p
, lhs_addr
, lhs_var
,
14146 target_expr
, true, depth
);
14147 if (saw_lhs
&& target_expr
== NULL_TREE
&& pre_p
)
14148 target_expr
= expr
;
14156 case tcc_reference
:
14157 if (TREE_CODE (expr
) == BIT_FIELD_REF
14158 || TREE_CODE (expr
) == VIEW_CONVERT_EXPR
)
14159 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 0), pre_p
,
14160 lhs_addr
, lhs_var
, target_expr
, true,
14164 if (TREE_CODE (expr
) == CALL_EXPR
)
14166 if (tree fndecl
= get_callee_fndecl (expr
))
14167 if (fndecl_built_in_p (fndecl
, BUILT_IN_CLEAR_PADDING
)
14168 || fndecl_built_in_p (fndecl
, BUILT_IN_MEMCMP
))
14170 int nargs
= call_expr_nargs (expr
);
14171 for (int i
= 0; i
< nargs
; i
++)
14172 saw_lhs
|= goa_stabilize_expr (&CALL_EXPR_ARG (expr
, i
),
14173 pre_p
, lhs_addr
, lhs_var
,
14174 target_expr
, true, depth
);
14183 if (saw_lhs
== 0 && pre_p
)
14185 enum gimplify_status gs
;
14186 if (TREE_CODE (expr
) == CALL_EXPR
&& VOID_TYPE_P (TREE_TYPE (expr
)))
14188 gimplify_stmt (&expr
, pre_p
);
14192 gs
= gimplify_expr (expr_p
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
14194 gs
= gimplify_expr (expr_p
, pre_p
, NULL
, is_gimple_lvalue
, fb_lvalue
);
14195 if (gs
!= GS_ALL_DONE
)
14202 /* Gimplify an OMP_ATOMIC statement. */
14204 static enum gimplify_status
14205 gimplify_omp_atomic (tree
*expr_p
, gimple_seq
*pre_p
)
14207 tree addr
= TREE_OPERAND (*expr_p
, 0);
14208 tree rhs
= TREE_CODE (*expr_p
) == OMP_ATOMIC_READ
14209 ? NULL
: TREE_OPERAND (*expr_p
, 1);
14210 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr
)));
14212 gomp_atomic_load
*loadstmt
;
14213 gomp_atomic_store
*storestmt
;
14214 tree target_expr
= NULL_TREE
;
14216 tmp_load
= create_tmp_reg (type
);
14218 && goa_stabilize_expr (&rhs
, pre_p
, addr
, tmp_load
, target_expr
,
14222 if (gimplify_expr (&addr
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
)
14226 loadstmt
= gimple_build_omp_atomic_load (tmp_load
, addr
,
14227 OMP_ATOMIC_MEMORY_ORDER (*expr_p
));
14228 gimplify_seq_add_stmt (pre_p
, loadstmt
);
14231 /* BIT_INSERT_EXPR is not valid for non-integral bitfield
14232 representatives. Use BIT_FIELD_REF on the lhs instead. */
14234 if (TREE_CODE (rhs
) == COND_EXPR
)
14235 rhsarg
= TREE_OPERAND (rhs
, 1);
14236 if (TREE_CODE (rhsarg
) == BIT_INSERT_EXPR
14237 && !INTEGRAL_TYPE_P (TREE_TYPE (tmp_load
)))
14239 tree bitpos
= TREE_OPERAND (rhsarg
, 2);
14240 tree op1
= TREE_OPERAND (rhsarg
, 1);
14242 tree tmp_store
= tmp_load
;
14243 if (TREE_CODE (*expr_p
) == OMP_ATOMIC_CAPTURE_OLD
)
14244 tmp_store
= get_initialized_tmp_var (tmp_load
, pre_p
);
14245 if (INTEGRAL_TYPE_P (TREE_TYPE (op1
)))
14246 bitsize
= bitsize_int (TYPE_PRECISION (TREE_TYPE (op1
)));
14248 bitsize
= TYPE_SIZE (TREE_TYPE (op1
));
14249 gcc_assert (TREE_OPERAND (rhsarg
, 0) == tmp_load
);
14250 tree t
= build2_loc (EXPR_LOCATION (rhsarg
),
14251 MODIFY_EXPR
, void_type_node
,
14252 build3_loc (EXPR_LOCATION (rhsarg
),
14253 BIT_FIELD_REF
, TREE_TYPE (op1
),
14254 tmp_store
, bitsize
, bitpos
), op1
);
14255 if (TREE_CODE (rhs
) == COND_EXPR
)
14256 t
= build3_loc (EXPR_LOCATION (rhs
), COND_EXPR
, void_type_node
,
14257 TREE_OPERAND (rhs
, 0), t
, void_node
);
14258 gimplify_and_add (t
, pre_p
);
14261 bool save_allow_rhs_cond_expr
= gimplify_ctxp
->allow_rhs_cond_expr
;
14262 if (TREE_CODE (rhs
) == COND_EXPR
)
14263 gimplify_ctxp
->allow_rhs_cond_expr
= true;
14264 enum gimplify_status gs
= gimplify_expr (&rhs
, pre_p
, NULL
,
14265 is_gimple_val
, fb_rvalue
);
14266 gimplify_ctxp
->allow_rhs_cond_expr
= save_allow_rhs_cond_expr
;
14267 if (gs
!= GS_ALL_DONE
)
14271 if (TREE_CODE (*expr_p
) == OMP_ATOMIC_READ
)
14274 = gimple_build_omp_atomic_store (rhs
, OMP_ATOMIC_MEMORY_ORDER (*expr_p
));
14275 if (TREE_CODE (*expr_p
) != OMP_ATOMIC_READ
&& OMP_ATOMIC_WEAK (*expr_p
))
14277 gimple_omp_atomic_set_weak (loadstmt
);
14278 gimple_omp_atomic_set_weak (storestmt
);
14280 gimplify_seq_add_stmt (pre_p
, storestmt
);
14281 switch (TREE_CODE (*expr_p
))
14283 case OMP_ATOMIC_READ
:
14284 case OMP_ATOMIC_CAPTURE_OLD
:
14285 *expr_p
= tmp_load
;
14286 gimple_omp_atomic_set_need_value (loadstmt
);
14288 case OMP_ATOMIC_CAPTURE_NEW
:
14290 gimple_omp_atomic_set_need_value (storestmt
);
14297 return GS_ALL_DONE
;
14300 /* Gimplify a TRANSACTION_EXPR. This involves gimplification of the
14301 body, and adding some EH bits. */
14303 static enum gimplify_status
14304 gimplify_transaction (tree
*expr_p
, gimple_seq
*pre_p
)
14306 tree expr
= *expr_p
, temp
, tbody
= TRANSACTION_EXPR_BODY (expr
);
14308 gtransaction
*trans_stmt
;
14309 gimple_seq body
= NULL
;
14312 /* Wrap the transaction body in a BIND_EXPR so we have a context
14313 where to put decls for OMP. */
14314 if (TREE_CODE (tbody
) != BIND_EXPR
)
14316 tree bind
= build3 (BIND_EXPR
, void_type_node
, NULL
, tbody
, NULL
);
14317 TREE_SIDE_EFFECTS (bind
) = 1;
14318 SET_EXPR_LOCATION (bind
, EXPR_LOCATION (tbody
));
14319 TRANSACTION_EXPR_BODY (expr
) = bind
;
14322 push_gimplify_context ();
14323 temp
= voidify_wrapper_expr (*expr_p
, NULL
);
14325 body_stmt
= gimplify_and_return_first (TRANSACTION_EXPR_BODY (expr
), &body
);
14326 pop_gimplify_context (body_stmt
);
14328 trans_stmt
= gimple_build_transaction (body
);
14329 if (TRANSACTION_EXPR_OUTER (expr
))
14330 subcode
= GTMA_IS_OUTER
;
14331 else if (TRANSACTION_EXPR_RELAXED (expr
))
14332 subcode
= GTMA_IS_RELAXED
;
14333 gimple_transaction_set_subcode (trans_stmt
, subcode
);
14335 gimplify_seq_add_stmt (pre_p
, trans_stmt
);
14343 *expr_p
= NULL_TREE
;
14344 return GS_ALL_DONE
;
14347 /* Gimplify an OMP_ORDERED construct. EXPR is the tree version. BODY
14348 is the OMP_BODY of the original EXPR (which has already been
14349 gimplified so it's not present in the EXPR).
14351 Return the gimplified GIMPLE_OMP_ORDERED tuple. */
14354 gimplify_omp_ordered (tree expr
, gimple_seq body
)
14359 tree source_c
= NULL_TREE
;
14360 tree sink_c
= NULL_TREE
;
14362 if (gimplify_omp_ctxp
)
14364 for (c
= OMP_ORDERED_CLAUSES (expr
); c
; c
= OMP_CLAUSE_CHAIN (c
))
14365 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEPEND
14366 && gimplify_omp_ctxp
->loop_iter_var
.is_empty ()
14367 && (OMP_CLAUSE_DEPEND_KIND (c
) == OMP_CLAUSE_DEPEND_SINK
14368 || OMP_CLAUSE_DEPEND_KIND (c
) == OMP_CLAUSE_DEPEND_SOURCE
))
14370 error_at (OMP_CLAUSE_LOCATION (c
),
14371 "%<ordered%> construct with %<depend%> clause must be "
14372 "closely nested inside a loop with %<ordered%> clause "
14373 "with a parameter");
14376 else if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEPEND
14377 && OMP_CLAUSE_DEPEND_KIND (c
) == OMP_CLAUSE_DEPEND_SINK
)
14380 for (decls
= OMP_CLAUSE_DECL (c
), i
= 0;
14381 decls
&& TREE_CODE (decls
) == TREE_LIST
;
14382 decls
= TREE_CHAIN (decls
), ++i
)
14383 if (i
>= gimplify_omp_ctxp
->loop_iter_var
.length () / 2)
14385 else if (TREE_VALUE (decls
)
14386 != gimplify_omp_ctxp
->loop_iter_var
[2 * i
])
14388 error_at (OMP_CLAUSE_LOCATION (c
),
14389 "variable %qE is not an iteration "
14390 "of outermost loop %d, expected %qE",
14391 TREE_VALUE (decls
), i
+ 1,
14392 gimplify_omp_ctxp
->loop_iter_var
[2 * i
]);
14398 = gimplify_omp_ctxp
->loop_iter_var
[2 * i
+ 1];
14399 if (!fail
&& i
!= gimplify_omp_ctxp
->loop_iter_var
.length () / 2)
14401 error_at (OMP_CLAUSE_LOCATION (c
),
14402 "number of variables in %<depend%> clause with "
14403 "%<sink%> modifier does not match number of "
14404 "iteration variables");
14409 else if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEPEND
14410 && OMP_CLAUSE_DEPEND_KIND (c
) == OMP_CLAUSE_DEPEND_SOURCE
)
14414 error_at (OMP_CLAUSE_LOCATION (c
),
14415 "more than one %<depend%> clause with %<source%> "
14416 "modifier on an %<ordered%> construct");
14423 if (source_c
&& sink_c
)
14425 error_at (OMP_CLAUSE_LOCATION (source_c
),
14426 "%<depend%> clause with %<source%> modifier specified "
14427 "together with %<depend%> clauses with %<sink%> modifier "
14428 "on the same construct");
14433 return gimple_build_nop ();
14434 return gimple_build_omp_ordered (body
, OMP_ORDERED_CLAUSES (expr
));
14437 /* Convert the GENERIC expression tree *EXPR_P to GIMPLE. If the
14438 expression produces a value to be used as an operand inside a GIMPLE
14439 statement, the value will be stored back in *EXPR_P. This value will
14440 be a tree of class tcc_declaration, tcc_constant, tcc_reference or
14441 an SSA_NAME. The corresponding sequence of GIMPLE statements is
14442 emitted in PRE_P and POST_P.
14444 Additionally, this process may overwrite parts of the input
14445 expression during gimplification. Ideally, it should be
14446 possible to do non-destructive gimplification.
14448 EXPR_P points to the GENERIC expression to convert to GIMPLE. If
14449 the expression needs to evaluate to a value to be used as
14450 an operand in a GIMPLE statement, this value will be stored in
14451 *EXPR_P on exit. This happens when the caller specifies one
14452 of fb_lvalue or fb_rvalue fallback flags.
14454 PRE_P will contain the sequence of GIMPLE statements corresponding
14455 to the evaluation of EXPR and all the side-effects that must
14456 be executed before the main expression. On exit, the last
14457 statement of PRE_P is the core statement being gimplified. For
14458 instance, when gimplifying 'if (++a)' the last statement in
14459 PRE_P will be 'if (t.1)' where t.1 is the result of
14460 pre-incrementing 'a'.
14462 POST_P will contain the sequence of GIMPLE statements corresponding
14463 to the evaluation of all the side-effects that must be executed
14464 after the main expression. If this is NULL, the post
14465 side-effects are stored at the end of PRE_P.
14467 The reason why the output is split in two is to handle post
14468 side-effects explicitly. In some cases, an expression may have
14469 inner and outer post side-effects which need to be emitted in
14470 an order different from the one given by the recursive
14471 traversal. For instance, for the expression (*p--)++ the post
14472 side-effects of '--' must actually occur *after* the post
14473 side-effects of '++'. However, gimplification will first visit
14474 the inner expression, so if a separate POST sequence was not
14475 used, the resulting sequence would be:
14482 However, the post-decrement operation in line #2 must not be
14483 evaluated until after the store to *p at line #4, so the
14484 correct sequence should be:
14491 So, by specifying a separate post queue, it is possible
14492 to emit the post side-effects in the correct order.
14493 If POST_P is NULL, an internal queue will be used. Before
14494 returning to the caller, the sequence POST_P is appended to
14495 the main output sequence PRE_P.
14497 GIMPLE_TEST_F points to a function that takes a tree T and
14498 returns nonzero if T is in the GIMPLE form requested by the
14499 caller. The GIMPLE predicates are in gimple.c.
14501 FALLBACK tells the function what sort of a temporary we want if
14502 gimplification cannot produce an expression that complies with
14505 fb_none means that no temporary should be generated
14506 fb_rvalue means that an rvalue is OK to generate
14507 fb_lvalue means that an lvalue is OK to generate
14508 fb_either means that either is OK, but an lvalue is preferable.
14509 fb_mayfail means that gimplification may fail (in which case
14510 GS_ERROR will be returned)
14512 The return value is either GS_ERROR or GS_ALL_DONE, since this
14513 function iterates until EXPR is completely gimplified or an error
14516 enum gimplify_status
14517 gimplify_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
14518 bool (*gimple_test_f
) (tree
), fallback_t fallback
)
14521 gimple_seq internal_pre
= NULL
;
14522 gimple_seq internal_post
= NULL
;
14525 location_t saved_location
;
14526 enum gimplify_status ret
;
14527 gimple_stmt_iterator pre_last_gsi
, post_last_gsi
;
14530 save_expr
= *expr_p
;
14531 if (save_expr
== NULL_TREE
)
14532 return GS_ALL_DONE
;
14534 /* If we are gimplifying a top-level statement, PRE_P must be valid. */
14535 is_statement
= gimple_test_f
== is_gimple_stmt
;
14537 gcc_assert (pre_p
);
14539 /* Consistency checks. */
14540 if (gimple_test_f
== is_gimple_reg
)
14541 gcc_assert (fallback
& (fb_rvalue
| fb_lvalue
));
14542 else if (gimple_test_f
== is_gimple_val
14543 || gimple_test_f
== is_gimple_call_addr
14544 || gimple_test_f
== is_gimple_condexpr
14545 || gimple_test_f
== is_gimple_condexpr_for_cond
14546 || gimple_test_f
== is_gimple_mem_rhs
14547 || gimple_test_f
== is_gimple_mem_rhs_or_call
14548 || gimple_test_f
== is_gimple_reg_rhs
14549 || gimple_test_f
== is_gimple_reg_rhs_or_call
14550 || gimple_test_f
== is_gimple_asm_val
14551 || gimple_test_f
== is_gimple_mem_ref_addr
)
14552 gcc_assert (fallback
& fb_rvalue
);
14553 else if (gimple_test_f
== is_gimple_min_lval
14554 || gimple_test_f
== is_gimple_lvalue
)
14555 gcc_assert (fallback
& fb_lvalue
);
14556 else if (gimple_test_f
== is_gimple_addressable
)
14557 gcc_assert (fallback
& fb_either
);
14558 else if (gimple_test_f
== is_gimple_stmt
)
14559 gcc_assert (fallback
== fb_none
);
14562 /* We should have recognized the GIMPLE_TEST_F predicate to
14563 know what kind of fallback to use in case a temporary is
14564 needed to hold the value or address of *EXPR_P. */
14565 gcc_unreachable ();
14568 /* We used to check the predicate here and return immediately if it
14569 succeeds. This is wrong; the design is for gimplification to be
14570 idempotent, and for the predicates to only test for valid forms, not
14571 whether they are fully simplified. */
14573 pre_p
= &internal_pre
;
14575 if (post_p
== NULL
)
14576 post_p
= &internal_post
;
14578 /* Remember the last statements added to PRE_P and POST_P. Every
14579 new statement added by the gimplification helpers needs to be
14580 annotated with location information. To centralize the
14581 responsibility, we remember the last statement that had been
14582 added to both queues before gimplifying *EXPR_P. If
14583 gimplification produces new statements in PRE_P and POST_P, those
14584 statements will be annotated with the same location information
14586 pre_last_gsi
= gsi_last (*pre_p
);
14587 post_last_gsi
= gsi_last (*post_p
);
14589 saved_location
= input_location
;
14590 if (save_expr
!= error_mark_node
14591 && EXPR_HAS_LOCATION (*expr_p
))
14592 input_location
= EXPR_LOCATION (*expr_p
);
14594 /* Loop over the specific gimplifiers until the toplevel node
14595 remains the same. */
14598 /* Strip away as many useless type conversions as possible
14599 at the toplevel. */
14600 STRIP_USELESS_TYPE_CONVERSION (*expr_p
);
14602 /* Remember the expr. */
14603 save_expr
= *expr_p
;
14605 /* Die, die, die, my darling. */
14606 if (error_operand_p (save_expr
))
14612 /* Do any language-specific gimplification. */
14613 ret
= ((enum gimplify_status
)
14614 lang_hooks
.gimplify_expr (expr_p
, pre_p
, post_p
));
14617 if (*expr_p
== NULL_TREE
)
14619 if (*expr_p
!= save_expr
)
14622 else if (ret
!= GS_UNHANDLED
)
14625 /* Make sure that all the cases set 'ret' appropriately. */
14626 ret
= GS_UNHANDLED
;
14627 switch (TREE_CODE (*expr_p
))
14629 /* First deal with the special cases. */
14631 case POSTINCREMENT_EXPR
:
14632 case POSTDECREMENT_EXPR
:
14633 case PREINCREMENT_EXPR
:
14634 case PREDECREMENT_EXPR
:
14635 ret
= gimplify_self_mod_expr (expr_p
, pre_p
, post_p
,
14636 fallback
!= fb_none
,
14637 TREE_TYPE (*expr_p
));
14640 case VIEW_CONVERT_EXPR
:
14641 if ((fallback
& fb_rvalue
)
14642 && is_gimple_reg_type (TREE_TYPE (*expr_p
))
14643 && is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (*expr_p
, 0))))
14645 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
14646 post_p
, is_gimple_val
, fb_rvalue
);
14647 recalculate_side_effects (*expr_p
);
14653 case ARRAY_RANGE_REF
:
14654 case REALPART_EXPR
:
14655 case IMAGPART_EXPR
:
14656 case COMPONENT_REF
:
14657 ret
= gimplify_compound_lval (expr_p
, pre_p
, post_p
,
14658 fallback
? fallback
: fb_rvalue
);
14662 ret
= gimplify_cond_expr (expr_p
, pre_p
, fallback
);
14664 /* C99 code may assign to an array in a structure value of a
14665 conditional expression, and this has undefined behavior
14666 only on execution, so create a temporary if an lvalue is
14668 if (fallback
== fb_lvalue
)
14670 *expr_p
= get_initialized_tmp_var (*expr_p
, pre_p
, post_p
, false);
14671 mark_addressable (*expr_p
);
14677 ret
= gimplify_call_expr (expr_p
, pre_p
, fallback
!= fb_none
);
14679 /* C99 code may assign to an array in a structure returned
14680 from a function, and this has undefined behavior only on
14681 execution, so create a temporary if an lvalue is
14683 if (fallback
== fb_lvalue
)
14685 *expr_p
= get_initialized_tmp_var (*expr_p
, pre_p
, post_p
, false);
14686 mark_addressable (*expr_p
);
14692 gcc_unreachable ();
14694 case COMPOUND_EXPR
:
14695 ret
= gimplify_compound_expr (expr_p
, pre_p
, fallback
!= fb_none
);
14698 case COMPOUND_LITERAL_EXPR
:
14699 ret
= gimplify_compound_literal_expr (expr_p
, pre_p
,
14700 gimple_test_f
, fallback
);
14705 ret
= gimplify_modify_expr (expr_p
, pre_p
, post_p
,
14706 fallback
!= fb_none
);
14709 case TRUTH_ANDIF_EXPR
:
14710 case TRUTH_ORIF_EXPR
:
14712 /* Preserve the original type of the expression and the
14713 source location of the outer expression. */
14714 tree org_type
= TREE_TYPE (*expr_p
);
14715 *expr_p
= gimple_boolify (*expr_p
);
14716 *expr_p
= build3_loc (input_location
, COND_EXPR
,
14720 org_type
, boolean_true_node
),
14723 org_type
, boolean_false_node
));
14728 case TRUTH_NOT_EXPR
:
14730 tree type
= TREE_TYPE (*expr_p
);
14731 /* The parsers are careful to generate TRUTH_NOT_EXPR
14732 only with operands that are always zero or one.
14733 We do not fold here but handle the only interesting case
14734 manually, as fold may re-introduce the TRUTH_NOT_EXPR. */
14735 *expr_p
= gimple_boolify (*expr_p
);
14736 if (TYPE_PRECISION (TREE_TYPE (*expr_p
)) == 1)
14737 *expr_p
= build1_loc (input_location
, BIT_NOT_EXPR
,
14738 TREE_TYPE (*expr_p
),
14739 TREE_OPERAND (*expr_p
, 0));
14741 *expr_p
= build2_loc (input_location
, BIT_XOR_EXPR
,
14742 TREE_TYPE (*expr_p
),
14743 TREE_OPERAND (*expr_p
, 0),
14744 build_int_cst (TREE_TYPE (*expr_p
), 1));
14745 if (!useless_type_conversion_p (type
, TREE_TYPE (*expr_p
)))
14746 *expr_p
= fold_convert_loc (input_location
, type
, *expr_p
);
14752 ret
= gimplify_addr_expr (expr_p
, pre_p
, post_p
);
14755 case ANNOTATE_EXPR
:
14757 tree cond
= TREE_OPERAND (*expr_p
, 0);
14758 tree kind
= TREE_OPERAND (*expr_p
, 1);
14759 tree data
= TREE_OPERAND (*expr_p
, 2);
14760 tree type
= TREE_TYPE (cond
);
14761 if (!INTEGRAL_TYPE_P (type
))
14767 tree tmp
= create_tmp_var (type
);
14768 gimplify_arg (&cond
, pre_p
, EXPR_LOCATION (*expr_p
));
14770 = gimple_build_call_internal (IFN_ANNOTATE
, 3, cond
, kind
, data
);
14771 gimple_call_set_lhs (call
, tmp
);
14772 gimplify_seq_add_stmt (pre_p
, call
);
14779 ret
= gimplify_va_arg_expr (expr_p
, pre_p
, post_p
);
14783 if (IS_EMPTY_STMT (*expr_p
))
14789 if (VOID_TYPE_P (TREE_TYPE (*expr_p
))
14790 || fallback
== fb_none
)
14792 /* Just strip a conversion to void (or in void context) and
14794 *expr_p
= TREE_OPERAND (*expr_p
, 0);
14799 ret
= gimplify_conversion (expr_p
);
14800 if (ret
== GS_ERROR
)
14802 if (*expr_p
!= save_expr
)
14806 case FIX_TRUNC_EXPR
:
14807 /* unary_expr: ... | '(' cast ')' val | ... */
14808 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
14809 is_gimple_val
, fb_rvalue
);
14810 recalculate_side_effects (*expr_p
);
14815 bool volatilep
= TREE_THIS_VOLATILE (*expr_p
);
14816 bool notrap
= TREE_THIS_NOTRAP (*expr_p
);
14817 tree saved_ptr_type
= TREE_TYPE (TREE_OPERAND (*expr_p
, 0));
14819 *expr_p
= fold_indirect_ref_loc (input_location
, *expr_p
);
14820 if (*expr_p
!= save_expr
)
14826 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
14827 is_gimple_reg
, fb_rvalue
);
14828 if (ret
== GS_ERROR
)
14831 recalculate_side_effects (*expr_p
);
14832 *expr_p
= fold_build2_loc (input_location
, MEM_REF
,
14833 TREE_TYPE (*expr_p
),
14834 TREE_OPERAND (*expr_p
, 0),
14835 build_int_cst (saved_ptr_type
, 0));
14836 TREE_THIS_VOLATILE (*expr_p
) = volatilep
;
14837 TREE_THIS_NOTRAP (*expr_p
) = notrap
;
14842 /* We arrive here through the various re-gimplifcation paths. */
14844 /* First try re-folding the whole thing. */
14845 tmp
= fold_binary (MEM_REF
, TREE_TYPE (*expr_p
),
14846 TREE_OPERAND (*expr_p
, 0),
14847 TREE_OPERAND (*expr_p
, 1));
14850 REF_REVERSE_STORAGE_ORDER (tmp
)
14851 = REF_REVERSE_STORAGE_ORDER (*expr_p
);
14853 recalculate_side_effects (*expr_p
);
14857 /* Avoid re-gimplifying the address operand if it is already
14858 in suitable form. Re-gimplifying would mark the address
14859 operand addressable. Always gimplify when not in SSA form
14860 as we still may have to gimplify decls with value-exprs. */
14861 if (!gimplify_ctxp
|| !gimple_in_ssa_p (cfun
)
14862 || !is_gimple_mem_ref_addr (TREE_OPERAND (*expr_p
, 0)))
14864 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
14865 is_gimple_mem_ref_addr
, fb_rvalue
);
14866 if (ret
== GS_ERROR
)
14869 recalculate_side_effects (*expr_p
);
14873 /* Constants need not be gimplified. */
14880 /* Drop the overflow flag on constants, we do not want
14881 that in the GIMPLE IL. */
14882 if (TREE_OVERFLOW_P (*expr_p
))
14883 *expr_p
= drop_tree_overflow (*expr_p
);
14888 /* If we require an lvalue, such as for ADDR_EXPR, retain the
14889 CONST_DECL node. Otherwise the decl is replaceable by its
14891 /* ??? Should be == fb_lvalue, but ADDR_EXPR passes fb_either. */
14892 if (fallback
& fb_lvalue
)
14896 *expr_p
= DECL_INITIAL (*expr_p
);
14902 ret
= gimplify_decl_expr (expr_p
, pre_p
);
14906 ret
= gimplify_bind_expr (expr_p
, pre_p
);
14910 ret
= gimplify_loop_expr (expr_p
, pre_p
);
14914 ret
= gimplify_switch_expr (expr_p
, pre_p
);
14918 ret
= gimplify_exit_expr (expr_p
);
14922 /* If the target is not LABEL, then it is a computed jump
14923 and the target needs to be gimplified. */
14924 if (TREE_CODE (GOTO_DESTINATION (*expr_p
)) != LABEL_DECL
)
14926 ret
= gimplify_expr (&GOTO_DESTINATION (*expr_p
), pre_p
,
14927 NULL
, is_gimple_val
, fb_rvalue
);
14928 if (ret
== GS_ERROR
)
14931 gimplify_seq_add_stmt (pre_p
,
14932 gimple_build_goto (GOTO_DESTINATION (*expr_p
)));
14937 gimplify_seq_add_stmt (pre_p
,
14938 gimple_build_predict (PREDICT_EXPR_PREDICTOR (*expr_p
),
14939 PREDICT_EXPR_OUTCOME (*expr_p
)));
14944 ret
= gimplify_label_expr (expr_p
, pre_p
);
14945 label
= LABEL_EXPR_LABEL (*expr_p
);
14946 gcc_assert (decl_function_context (label
) == current_function_decl
);
14948 /* If the label is used in a goto statement, or address of the label
14949 is taken, we need to unpoison all variables that were seen so far.
14950 Doing so would prevent us from reporting a false positives. */
14951 if (asan_poisoned_variables
14952 && asan_used_labels
!= NULL
14953 && asan_used_labels
->contains (label
)
14954 && !gimplify_omp_ctxp
)
14955 asan_poison_variables (asan_poisoned_variables
, false, pre_p
);
14958 case CASE_LABEL_EXPR
:
14959 ret
= gimplify_case_label_expr (expr_p
, pre_p
);
14961 if (gimplify_ctxp
->live_switch_vars
)
14962 asan_poison_variables (gimplify_ctxp
->live_switch_vars
, false,
14967 ret
= gimplify_return_expr (*expr_p
, pre_p
);
14971 /* Don't reduce this in place; let gimplify_init_constructor work its
14972 magic. Buf if we're just elaborating this for side effects, just
14973 gimplify any element that has side-effects. */
14974 if (fallback
== fb_none
)
14976 unsigned HOST_WIDE_INT ix
;
14978 tree temp
= NULL_TREE
;
14979 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (*expr_p
), ix
, val
)
14980 if (TREE_SIDE_EFFECTS (val
))
14981 append_to_statement_list (val
, &temp
);
14984 ret
= temp
? GS_OK
: GS_ALL_DONE
;
14986 /* C99 code may assign to an array in a constructed
14987 structure or union, and this has undefined behavior only
14988 on execution, so create a temporary if an lvalue is
14990 else if (fallback
== fb_lvalue
)
14992 *expr_p
= get_initialized_tmp_var (*expr_p
, pre_p
, post_p
, false);
14993 mark_addressable (*expr_p
);
15000 /* The following are special cases that are not handled by the
15001 original GIMPLE grammar. */
15003 /* SAVE_EXPR nodes are converted into a GIMPLE identifier and
15006 ret
= gimplify_save_expr (expr_p
, pre_p
, post_p
);
15009 case BIT_FIELD_REF
:
15010 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
15011 post_p
, is_gimple_lvalue
, fb_either
);
15012 recalculate_side_effects (*expr_p
);
15015 case TARGET_MEM_REF
:
15017 enum gimplify_status r0
= GS_ALL_DONE
, r1
= GS_ALL_DONE
;
15019 if (TMR_BASE (*expr_p
))
15020 r0
= gimplify_expr (&TMR_BASE (*expr_p
), pre_p
,
15021 post_p
, is_gimple_mem_ref_addr
, fb_either
);
15022 if (TMR_INDEX (*expr_p
))
15023 r1
= gimplify_expr (&TMR_INDEX (*expr_p
), pre_p
,
15024 post_p
, is_gimple_val
, fb_rvalue
);
15025 if (TMR_INDEX2 (*expr_p
))
15026 r1
= gimplify_expr (&TMR_INDEX2 (*expr_p
), pre_p
,
15027 post_p
, is_gimple_val
, fb_rvalue
);
15028 /* TMR_STEP and TMR_OFFSET are always integer constants. */
15029 ret
= MIN (r0
, r1
);
15033 case NON_LVALUE_EXPR
:
15034 /* This should have been stripped above. */
15035 gcc_unreachable ();
15038 ret
= gimplify_asm_expr (expr_p
, pre_p
, post_p
);
15041 case TRY_FINALLY_EXPR
:
15042 case TRY_CATCH_EXPR
:
15044 gimple_seq eval
, cleanup
;
15047 /* Calls to destructors are generated automatically in FINALLY/CATCH
15048 block. They should have location as UNKNOWN_LOCATION. However,
15049 gimplify_call_expr will reset these call stmts to input_location
15050 if it finds stmt's location is unknown. To prevent resetting for
15051 destructors, we set the input_location to unknown.
15052 Note that this only affects the destructor calls in FINALLY/CATCH
15053 block, and will automatically reset to its original value by the
15054 end of gimplify_expr. */
15055 input_location
= UNKNOWN_LOCATION
;
15056 eval
= cleanup
= NULL
;
15057 gimplify_and_add (TREE_OPERAND (*expr_p
, 0), &eval
);
15058 if (TREE_CODE (*expr_p
) == TRY_FINALLY_EXPR
15059 && TREE_CODE (TREE_OPERAND (*expr_p
, 1)) == EH_ELSE_EXPR
)
15061 gimple_seq n
= NULL
, e
= NULL
;
15062 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p
, 1),
15064 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p
, 1),
15066 if (!gimple_seq_empty_p (n
) && !gimple_seq_empty_p (e
))
15068 geh_else
*stmt
= gimple_build_eh_else (n
, e
);
15069 gimple_seq_add_stmt (&cleanup
, stmt
);
15073 gimplify_and_add (TREE_OPERAND (*expr_p
, 1), &cleanup
);
15074 /* Don't create bogus GIMPLE_TRY with empty cleanup. */
15075 if (gimple_seq_empty_p (cleanup
))
15077 gimple_seq_add_seq (pre_p
, eval
);
15081 try_
= gimple_build_try (eval
, cleanup
,
15082 TREE_CODE (*expr_p
) == TRY_FINALLY_EXPR
15083 ? GIMPLE_TRY_FINALLY
15084 : GIMPLE_TRY_CATCH
);
15085 if (EXPR_HAS_LOCATION (save_expr
))
15086 gimple_set_location (try_
, EXPR_LOCATION (save_expr
));
15087 else if (LOCATION_LOCUS (saved_location
) != UNKNOWN_LOCATION
)
15088 gimple_set_location (try_
, saved_location
);
15089 if (TREE_CODE (*expr_p
) == TRY_CATCH_EXPR
)
15090 gimple_try_set_catch_is_cleanup (try_
,
15091 TRY_CATCH_IS_CLEANUP (*expr_p
));
15092 gimplify_seq_add_stmt (pre_p
, try_
);
15097 case CLEANUP_POINT_EXPR
:
15098 ret
= gimplify_cleanup_point_expr (expr_p
, pre_p
);
15102 ret
= gimplify_target_expr (expr_p
, pre_p
, post_p
);
15108 gimple_seq handler
= NULL
;
15109 gimplify_and_add (CATCH_BODY (*expr_p
), &handler
);
15110 c
= gimple_build_catch (CATCH_TYPES (*expr_p
), handler
);
15111 gimplify_seq_add_stmt (pre_p
, c
);
15116 case EH_FILTER_EXPR
:
15119 gimple_seq failure
= NULL
;
15121 gimplify_and_add (EH_FILTER_FAILURE (*expr_p
), &failure
);
15122 ehf
= gimple_build_eh_filter (EH_FILTER_TYPES (*expr_p
), failure
);
15123 copy_warning (ehf
, *expr_p
);
15124 gimplify_seq_add_stmt (pre_p
, ehf
);
15131 enum gimplify_status r0
, r1
;
15132 r0
= gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p
), pre_p
,
15133 post_p
, is_gimple_val
, fb_rvalue
);
15134 r1
= gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p
), pre_p
,
15135 post_p
, is_gimple_val
, fb_rvalue
);
15136 TREE_SIDE_EFFECTS (*expr_p
) = 0;
15137 ret
= MIN (r0
, r1
);
15142 /* We get here when taking the address of a label. We mark
15143 the label as "forced"; meaning it can never be removed and
15144 it is a potential target for any computed goto. */
15145 FORCED_LABEL (*expr_p
) = 1;
15149 case STATEMENT_LIST
:
15150 ret
= gimplify_statement_list (expr_p
, pre_p
);
15153 case WITH_SIZE_EXPR
:
15155 gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
15156 post_p
== &internal_post
? NULL
: post_p
,
15157 gimple_test_f
, fallback
);
15158 gimplify_expr (&TREE_OPERAND (*expr_p
, 1), pre_p
, post_p
,
15159 is_gimple_val
, fb_rvalue
);
15166 ret
= gimplify_var_or_parm_decl (expr_p
);
15170 /* When within an OMP context, notice uses of variables. */
15171 if (gimplify_omp_ctxp
)
15172 omp_notice_variable (gimplify_omp_ctxp
, *expr_p
, true);
15176 case DEBUG_EXPR_DECL
:
15177 gcc_unreachable ();
15179 case DEBUG_BEGIN_STMT
:
15180 gimplify_seq_add_stmt (pre_p
,
15181 gimple_build_debug_begin_stmt
15182 (TREE_BLOCK (*expr_p
),
15183 EXPR_LOCATION (*expr_p
)));
15189 /* Allow callbacks into the gimplifier during optimization. */
15194 gimplify_omp_parallel (expr_p
, pre_p
);
15199 gimplify_omp_task (expr_p
, pre_p
);
15205 case OMP_DISTRIBUTE
:
15208 ret
= gimplify_omp_for (expr_p
, pre_p
);
15212 ret
= gimplify_omp_loop (expr_p
, pre_p
);
15216 gimplify_oacc_cache (expr_p
, pre_p
);
15221 gimplify_oacc_declare (expr_p
, pre_p
);
15225 case OACC_HOST_DATA
:
15228 case OACC_PARALLEL
:
15234 case OMP_TARGET_DATA
:
15236 gimplify_omp_workshare (expr_p
, pre_p
);
15240 case OACC_ENTER_DATA
:
15241 case OACC_EXIT_DATA
:
15243 case OMP_TARGET_UPDATE
:
15244 case OMP_TARGET_ENTER_DATA
:
15245 case OMP_TARGET_EXIT_DATA
:
15246 gimplify_omp_target_update (expr_p
, pre_p
);
15257 gimple_seq body
= NULL
;
15259 bool saved_in_omp_construct
= in_omp_construct
;
15261 in_omp_construct
= true;
15262 gimplify_and_add (OMP_BODY (*expr_p
), &body
);
15263 in_omp_construct
= saved_in_omp_construct
;
15264 switch (TREE_CODE (*expr_p
))
15267 g
= gimple_build_omp_section (body
);
15270 g
= gimple_build_omp_master (body
);
15273 g
= gimplify_omp_ordered (*expr_p
, body
);
15276 gimplify_scan_omp_clauses (&OMP_MASKED_CLAUSES (*expr_p
),
15277 pre_p
, ORT_WORKSHARE
, OMP_MASKED
);
15278 gimplify_adjust_omp_clauses (pre_p
, body
,
15279 &OMP_MASKED_CLAUSES (*expr_p
),
15281 g
= gimple_build_omp_masked (body
,
15282 OMP_MASKED_CLAUSES (*expr_p
));
15285 gimplify_scan_omp_clauses (&OMP_CRITICAL_CLAUSES (*expr_p
),
15286 pre_p
, ORT_WORKSHARE
, OMP_CRITICAL
);
15287 gimplify_adjust_omp_clauses (pre_p
, body
,
15288 &OMP_CRITICAL_CLAUSES (*expr_p
),
15290 g
= gimple_build_omp_critical (body
,
15291 OMP_CRITICAL_NAME (*expr_p
),
15292 OMP_CRITICAL_CLAUSES (*expr_p
));
15295 gimplify_scan_omp_clauses (&OMP_SCAN_CLAUSES (*expr_p
),
15296 pre_p
, ORT_WORKSHARE
, OMP_SCAN
);
15297 gimplify_adjust_omp_clauses (pre_p
, body
,
15298 &OMP_SCAN_CLAUSES (*expr_p
),
15300 g
= gimple_build_omp_scan (body
, OMP_SCAN_CLAUSES (*expr_p
));
15303 gcc_unreachable ();
15305 gimplify_seq_add_stmt (pre_p
, g
);
15310 case OMP_TASKGROUP
:
15312 gimple_seq body
= NULL
;
15314 tree
*pclauses
= &OMP_TASKGROUP_CLAUSES (*expr_p
);
15315 bool saved_in_omp_construct
= in_omp_construct
;
15316 gimplify_scan_omp_clauses (pclauses
, pre_p
, ORT_TASKGROUP
,
15318 gimplify_adjust_omp_clauses (pre_p
, NULL
, pclauses
, OMP_TASKGROUP
);
15320 in_omp_construct
= true;
15321 gimplify_and_add (OMP_BODY (*expr_p
), &body
);
15322 in_omp_construct
= saved_in_omp_construct
;
15323 gimple_seq cleanup
= NULL
;
15324 tree fn
= builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_END
);
15325 gimple
*g
= gimple_build_call (fn
, 0);
15326 gimple_seq_add_stmt (&cleanup
, g
);
15327 g
= gimple_build_try (body
, cleanup
, GIMPLE_TRY_FINALLY
);
15329 gimple_seq_add_stmt (&body
, g
);
15330 g
= gimple_build_omp_taskgroup (body
, *pclauses
);
15331 gimplify_seq_add_stmt (pre_p
, g
);
15337 case OMP_ATOMIC_READ
:
15338 case OMP_ATOMIC_CAPTURE_OLD
:
15339 case OMP_ATOMIC_CAPTURE_NEW
:
15340 ret
= gimplify_omp_atomic (expr_p
, pre_p
);
15343 case TRANSACTION_EXPR
:
15344 ret
= gimplify_transaction (expr_p
, pre_p
);
15347 case TRUTH_AND_EXPR
:
15348 case TRUTH_OR_EXPR
:
15349 case TRUTH_XOR_EXPR
:
15351 tree orig_type
= TREE_TYPE (*expr_p
);
15352 tree new_type
, xop0
, xop1
;
15353 *expr_p
= gimple_boolify (*expr_p
);
15354 new_type
= TREE_TYPE (*expr_p
);
15355 if (!useless_type_conversion_p (orig_type
, new_type
))
15357 *expr_p
= fold_convert_loc (input_location
, orig_type
, *expr_p
);
15362 /* Boolified binary truth expressions are semantically equivalent
15363 to bitwise binary expressions. Canonicalize them to the
15364 bitwise variant. */
15365 switch (TREE_CODE (*expr_p
))
15367 case TRUTH_AND_EXPR
:
15368 TREE_SET_CODE (*expr_p
, BIT_AND_EXPR
);
15370 case TRUTH_OR_EXPR
:
15371 TREE_SET_CODE (*expr_p
, BIT_IOR_EXPR
);
15373 case TRUTH_XOR_EXPR
:
15374 TREE_SET_CODE (*expr_p
, BIT_XOR_EXPR
);
15379 /* Now make sure that operands have compatible type to
15380 expression's new_type. */
15381 xop0
= TREE_OPERAND (*expr_p
, 0);
15382 xop1
= TREE_OPERAND (*expr_p
, 1);
15383 if (!useless_type_conversion_p (new_type
, TREE_TYPE (xop0
)))
15384 TREE_OPERAND (*expr_p
, 0) = fold_convert_loc (input_location
,
15387 if (!useless_type_conversion_p (new_type
, TREE_TYPE (xop1
)))
15388 TREE_OPERAND (*expr_p
, 1) = fold_convert_loc (input_location
,
15391 /* Continue classified as tcc_binary. */
15395 case VEC_COND_EXPR
:
15398 case VEC_PERM_EXPR
:
15399 /* Classified as tcc_expression. */
15402 case BIT_INSERT_EXPR
:
15403 /* Argument 3 is a constant. */
15406 case POINTER_PLUS_EXPR
:
15408 enum gimplify_status r0
, r1
;
15409 r0
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
15410 post_p
, is_gimple_val
, fb_rvalue
);
15411 r1
= gimplify_expr (&TREE_OPERAND (*expr_p
, 1), pre_p
,
15412 post_p
, is_gimple_val
, fb_rvalue
);
15413 recalculate_side_effects (*expr_p
);
15414 ret
= MIN (r0
, r1
);
15419 switch (TREE_CODE_CLASS (TREE_CODE (*expr_p
)))
15421 case tcc_comparison
:
15422 /* Handle comparison of objects of non scalar mode aggregates
15423 with a call to memcmp. It would be nice to only have to do
15424 this for variable-sized objects, but then we'd have to allow
15425 the same nest of reference nodes we allow for MODIFY_EXPR and
15426 that's too complex.
15428 Compare scalar mode aggregates as scalar mode values. Using
15429 memcmp for them would be very inefficient at best, and is
15430 plain wrong if bitfields are involved. */
15432 tree type
= TREE_TYPE (TREE_OPERAND (*expr_p
, 1));
15434 /* Vector comparisons need no boolification. */
15435 if (TREE_CODE (type
) == VECTOR_TYPE
)
15437 else if (!AGGREGATE_TYPE_P (type
))
15439 tree org_type
= TREE_TYPE (*expr_p
);
15440 *expr_p
= gimple_boolify (*expr_p
);
15441 if (!useless_type_conversion_p (org_type
,
15442 TREE_TYPE (*expr_p
)))
15444 *expr_p
= fold_convert_loc (input_location
,
15445 org_type
, *expr_p
);
15451 else if (TYPE_MODE (type
) != BLKmode
)
15452 ret
= gimplify_scalar_mode_aggregate_compare (expr_p
);
15454 ret
= gimplify_variable_sized_compare (expr_p
);
15459 /* If *EXPR_P does not need to be special-cased, handle it
15460 according to its class. */
15462 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
15463 post_p
, is_gimple_val
, fb_rvalue
);
15469 enum gimplify_status r0
, r1
;
15471 r0
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
15472 post_p
, is_gimple_val
, fb_rvalue
);
15473 r1
= gimplify_expr (&TREE_OPERAND (*expr_p
, 1), pre_p
,
15474 post_p
, is_gimple_val
, fb_rvalue
);
15476 ret
= MIN (r0
, r1
);
15482 enum gimplify_status r0
, r1
, r2
;
15484 r0
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
15485 post_p
, is_gimple_val
, fb_rvalue
);
15486 r1
= gimplify_expr (&TREE_OPERAND (*expr_p
, 1), pre_p
,
15487 post_p
, is_gimple_val
, fb_rvalue
);
15488 r2
= gimplify_expr (&TREE_OPERAND (*expr_p
, 2), pre_p
,
15489 post_p
, is_gimple_val
, fb_rvalue
);
15491 ret
= MIN (MIN (r0
, r1
), r2
);
15495 case tcc_declaration
:
15498 goto dont_recalculate
;
15501 gcc_unreachable ();
15504 recalculate_side_effects (*expr_p
);
15510 gcc_assert (*expr_p
|| ret
!= GS_OK
);
15512 while (ret
== GS_OK
);
15514 /* If we encountered an error_mark somewhere nested inside, either
15515 stub out the statement or propagate the error back out. */
15516 if (ret
== GS_ERROR
)
15523 /* This was only valid as a return value from the langhook, which
15524 we handled. Make sure it doesn't escape from any other context. */
15525 gcc_assert (ret
!= GS_UNHANDLED
);
15527 if (fallback
== fb_none
&& *expr_p
&& !is_gimple_stmt (*expr_p
))
15529 /* We aren't looking for a value, and we don't have a valid
15530 statement. If it doesn't have side-effects, throw it away.
15531 We can also get here with code such as "*&&L;", where L is
15532 a LABEL_DECL that is marked as FORCED_LABEL. */
15533 if (TREE_CODE (*expr_p
) == LABEL_DECL
15534 || !TREE_SIDE_EFFECTS (*expr_p
))
15536 else if (!TREE_THIS_VOLATILE (*expr_p
))
15538 /* This is probably a _REF that contains something nested that
15539 has side effects. Recurse through the operands to find it. */
15540 enum tree_code code
= TREE_CODE (*expr_p
);
15544 case COMPONENT_REF
:
15545 case REALPART_EXPR
:
15546 case IMAGPART_EXPR
:
15547 case VIEW_CONVERT_EXPR
:
15548 gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
15549 gimple_test_f
, fallback
);
15553 case ARRAY_RANGE_REF
:
15554 gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
15555 gimple_test_f
, fallback
);
15556 gimplify_expr (&TREE_OPERAND (*expr_p
, 1), pre_p
, post_p
,
15557 gimple_test_f
, fallback
);
15561 /* Anything else with side-effects must be converted to
15562 a valid statement before we get here. */
15563 gcc_unreachable ();
15568 else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p
))
15569 && TYPE_MODE (TREE_TYPE (*expr_p
)) != BLKmode
15570 && !is_empty_type (TREE_TYPE (*expr_p
)))
15572 /* Historically, the compiler has treated a bare reference
15573 to a non-BLKmode volatile lvalue as forcing a load. */
15574 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p
));
15576 /* Normally, we do not want to create a temporary for a
15577 TREE_ADDRESSABLE type because such a type should not be
15578 copied by bitwise-assignment. However, we make an
15579 exception here, as all we are doing here is ensuring that
15580 we read the bytes that make up the type. We use
15581 create_tmp_var_raw because create_tmp_var will abort when
15582 given a TREE_ADDRESSABLE type. */
15583 tree tmp
= create_tmp_var_raw (type
, "vol");
15584 gimple_add_tmp_var (tmp
);
15585 gimplify_assign (tmp
, *expr_p
, pre_p
);
15589 /* We can't do anything useful with a volatile reference to
15590 an incomplete type, so just throw it away. Likewise for
15591 a BLKmode type, since any implicit inner load should
15592 already have been turned into an explicit one by the
15593 gimplification process. */
15597 /* If we are gimplifying at the statement level, we're done. Tack
15598 everything together and return. */
15599 if (fallback
== fb_none
|| is_statement
)
15601 /* Since *EXPR_P has been converted into a GIMPLE tuple, clear
15602 it out for GC to reclaim it. */
15603 *expr_p
= NULL_TREE
;
15605 if (!gimple_seq_empty_p (internal_pre
)
15606 || !gimple_seq_empty_p (internal_post
))
15608 gimplify_seq_add_seq (&internal_pre
, internal_post
);
15609 gimplify_seq_add_seq (pre_p
, internal_pre
);
15612 /* The result of gimplifying *EXPR_P is going to be the last few
15613 statements in *PRE_P and *POST_P. Add location information
15614 to all the statements that were added by the gimplification
15616 if (!gimple_seq_empty_p (*pre_p
))
15617 annotate_all_with_location_after (*pre_p
, pre_last_gsi
, input_location
);
15619 if (!gimple_seq_empty_p (*post_p
))
15620 annotate_all_with_location_after (*post_p
, post_last_gsi
,
15626 #ifdef ENABLE_GIMPLE_CHECKING
15629 enum tree_code code
= TREE_CODE (*expr_p
);
15630 /* These expressions should already be in gimple IR form. */
15631 gcc_assert (code
!= MODIFY_EXPR
15632 && code
!= ASM_EXPR
15633 && code
!= BIND_EXPR
15634 && code
!= CATCH_EXPR
15635 && (code
!= COND_EXPR
|| gimplify_ctxp
->allow_rhs_cond_expr
)
15636 && code
!= EH_FILTER_EXPR
15637 && code
!= GOTO_EXPR
15638 && code
!= LABEL_EXPR
15639 && code
!= LOOP_EXPR
15640 && code
!= SWITCH_EXPR
15641 && code
!= TRY_FINALLY_EXPR
15642 && code
!= EH_ELSE_EXPR
15643 && code
!= OACC_PARALLEL
15644 && code
!= OACC_KERNELS
15645 && code
!= OACC_SERIAL
15646 && code
!= OACC_DATA
15647 && code
!= OACC_HOST_DATA
15648 && code
!= OACC_DECLARE
15649 && code
!= OACC_UPDATE
15650 && code
!= OACC_ENTER_DATA
15651 && code
!= OACC_EXIT_DATA
15652 && code
!= OACC_CACHE
15653 && code
!= OMP_CRITICAL
15655 && code
!= OACC_LOOP
15656 && code
!= OMP_MASTER
15657 && code
!= OMP_MASKED
15658 && code
!= OMP_TASKGROUP
15659 && code
!= OMP_ORDERED
15660 && code
!= OMP_PARALLEL
15661 && code
!= OMP_SCAN
15662 && code
!= OMP_SECTIONS
15663 && code
!= OMP_SECTION
15664 && code
!= OMP_SINGLE
15665 && code
!= OMP_SCOPE
);
15669 /* Otherwise we're gimplifying a subexpression, so the resulting
15670 value is interesting. If it's a valid operand that matches
15671 GIMPLE_TEST_F, we're done. Unless we are handling some
15672 post-effects internally; if that's the case, we need to copy into
15673 a temporary before adding the post-effects to POST_P. */
15674 if (gimple_seq_empty_p (internal_post
) && (*gimple_test_f
) (*expr_p
))
15677 /* Otherwise, we need to create a new temporary for the gimplified
15680 /* We can't return an lvalue if we have an internal postqueue. The
15681 object the lvalue refers to would (probably) be modified by the
15682 postqueue; we need to copy the value out first, which means an
15684 if ((fallback
& fb_lvalue
)
15685 && gimple_seq_empty_p (internal_post
)
15686 && is_gimple_addressable (*expr_p
))
15688 /* An lvalue will do. Take the address of the expression, store it
15689 in a temporary, and replace the expression with an INDIRECT_REF of
15691 tree ref_alias_type
= reference_alias_ptr_type (*expr_p
);
15692 unsigned int ref_align
= get_object_alignment (*expr_p
);
15693 tree ref_type
= TREE_TYPE (*expr_p
);
15694 tmp
= build_fold_addr_expr_loc (input_location
, *expr_p
);
15695 gimplify_expr (&tmp
, pre_p
, post_p
, is_gimple_reg
, fb_rvalue
);
15696 if (TYPE_ALIGN (ref_type
) != ref_align
)
15697 ref_type
= build_aligned_type (ref_type
, ref_align
);
15698 *expr_p
= build2 (MEM_REF
, ref_type
,
15699 tmp
, build_zero_cst (ref_alias_type
));
15701 else if ((fallback
& fb_rvalue
) && is_gimple_reg_rhs_or_call (*expr_p
))
15703 /* An rvalue will do. Assign the gimplified expression into a
15704 new temporary TMP and replace the original expression with
15705 TMP. First, make sure that the expression has a type so that
15706 it can be assigned into a temporary. */
15707 gcc_assert (!VOID_TYPE_P (TREE_TYPE (*expr_p
)));
15708 *expr_p
= get_formal_tmp_var (*expr_p
, pre_p
);
15712 #ifdef ENABLE_GIMPLE_CHECKING
15713 if (!(fallback
& fb_mayfail
))
15715 fprintf (stderr
, "gimplification failed:\n");
15716 print_generic_expr (stderr
, *expr_p
);
15717 debug_tree (*expr_p
);
15718 internal_error ("gimplification failed");
15721 gcc_assert (fallback
& fb_mayfail
);
15723 /* If this is an asm statement, and the user asked for the
15724 impossible, don't die. Fail and let gimplify_asm_expr
15730 /* Make sure the temporary matches our predicate. */
15731 gcc_assert ((*gimple_test_f
) (*expr_p
));
15733 if (!gimple_seq_empty_p (internal_post
))
15735 annotate_all_with_location (internal_post
, input_location
);
15736 gimplify_seq_add_seq (pre_p
, internal_post
);
15740 input_location
= saved_location
;
15744 /* Like gimplify_expr but make sure the gimplified result is not itself
15745 a SSA name (but a decl if it were). Temporaries required by
15746 evaluating *EXPR_P may be still SSA names. */
15748 static enum gimplify_status
15749 gimplify_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
15750 bool (*gimple_test_f
) (tree
), fallback_t fallback
,
15753 enum gimplify_status ret
= gimplify_expr (expr_p
, pre_p
, post_p
,
15754 gimple_test_f
, fallback
);
15756 && TREE_CODE (*expr_p
) == SSA_NAME
)
15757 *expr_p
= get_initialized_tmp_var (*expr_p
, pre_p
, NULL
, false);
15761 /* Look through TYPE for variable-sized objects and gimplify each such
15762 size that we find. Add to LIST_P any statements generated. */
15765 gimplify_type_sizes (tree type
, gimple_seq
*list_p
)
15767 if (type
== NULL
|| type
== error_mark_node
)
15770 const bool ignored_p
15772 && TREE_CODE (TYPE_NAME (type
)) == TYPE_DECL
15773 && DECL_IGNORED_P (TYPE_NAME (type
));
15776 /* We first do the main variant, then copy into any other variants. */
15777 type
= TYPE_MAIN_VARIANT (type
);
15779 /* Avoid infinite recursion. */
15780 if (TYPE_SIZES_GIMPLIFIED (type
))
15783 TYPE_SIZES_GIMPLIFIED (type
) = 1;
15785 switch (TREE_CODE (type
))
15788 case ENUMERAL_TYPE
:
15791 case FIXED_POINT_TYPE
:
15792 gimplify_one_sizepos (&TYPE_MIN_VALUE (type
), list_p
);
15793 gimplify_one_sizepos (&TYPE_MAX_VALUE (type
), list_p
);
15795 for (t
= TYPE_NEXT_VARIANT (type
); t
; t
= TYPE_NEXT_VARIANT (t
))
15797 TYPE_MIN_VALUE (t
) = TYPE_MIN_VALUE (type
);
15798 TYPE_MAX_VALUE (t
) = TYPE_MAX_VALUE (type
);
15803 /* These types may not have declarations, so handle them here. */
15804 gimplify_type_sizes (TREE_TYPE (type
), list_p
);
15805 gimplify_type_sizes (TYPE_DOMAIN (type
), list_p
);
15806 /* Ensure VLA bounds aren't removed, for -O0 they should be variables
15807 with assigned stack slots, for -O1+ -g they should be tracked
15810 && TYPE_DOMAIN (type
)
15811 && INTEGRAL_TYPE_P (TYPE_DOMAIN (type
)))
15813 t
= TYPE_MIN_VALUE (TYPE_DOMAIN (type
));
15814 if (t
&& VAR_P (t
) && DECL_ARTIFICIAL (t
))
15815 DECL_IGNORED_P (t
) = 0;
15816 t
= TYPE_MAX_VALUE (TYPE_DOMAIN (type
));
15817 if (t
&& VAR_P (t
) && DECL_ARTIFICIAL (t
))
15818 DECL_IGNORED_P (t
) = 0;
15824 case QUAL_UNION_TYPE
:
15825 for (tree field
= TYPE_FIELDS (type
); field
; field
= DECL_CHAIN (field
))
15826 if (TREE_CODE (field
) == FIELD_DECL
)
15828 gimplify_one_sizepos (&DECL_FIELD_OFFSET (field
), list_p
);
15829 /* Likewise, ensure variable offsets aren't removed. */
15831 && (t
= DECL_FIELD_OFFSET (field
))
15833 && DECL_ARTIFICIAL (t
))
15834 DECL_IGNORED_P (t
) = 0;
15835 gimplify_one_sizepos (&DECL_SIZE (field
), list_p
);
15836 gimplify_one_sizepos (&DECL_SIZE_UNIT (field
), list_p
);
15837 gimplify_type_sizes (TREE_TYPE (field
), list_p
);
15842 case REFERENCE_TYPE
:
15843 /* We used to recurse on the pointed-to type here, which turned out to
15844 be incorrect because its definition might refer to variables not
15845 yet initialized at this point if a forward declaration is involved.
15847 It was actually useful for anonymous pointed-to types to ensure
15848 that the sizes evaluation dominates every possible later use of the
15849 values. Restricting to such types here would be safe since there
15850 is no possible forward declaration around, but would introduce an
15851 undesirable middle-end semantic to anonymity. We then defer to
15852 front-ends the responsibility of ensuring that the sizes are
15853 evaluated both early and late enough, e.g. by attaching artificial
15854 type declarations to the tree. */
15861 gimplify_one_sizepos (&TYPE_SIZE (type
), list_p
);
15862 gimplify_one_sizepos (&TYPE_SIZE_UNIT (type
), list_p
);
15864 for (t
= TYPE_NEXT_VARIANT (type
); t
; t
= TYPE_NEXT_VARIANT (t
))
15866 TYPE_SIZE (t
) = TYPE_SIZE (type
);
15867 TYPE_SIZE_UNIT (t
) = TYPE_SIZE_UNIT (type
);
15868 TYPE_SIZES_GIMPLIFIED (t
) = 1;
15872 /* A subroutine of gimplify_type_sizes to make sure that *EXPR_P,
15873 a size or position, has had all of its SAVE_EXPRs evaluated.
15874 We add any required statements to *STMT_P. */
15877 gimplify_one_sizepos (tree
*expr_p
, gimple_seq
*stmt_p
)
15879 tree expr
= *expr_p
;
15881 /* We don't do anything if the value isn't there, is constant, or contains
15882 A PLACEHOLDER_EXPR. We also don't want to do anything if it's already
15883 a VAR_DECL. If it's a VAR_DECL from another function, the gimplifier
15884 will want to replace it with a new variable, but that will cause problems
15885 if this type is from outside the function. It's OK to have that here. */
15886 if (expr
== NULL_TREE
15887 || is_gimple_constant (expr
)
15888 || TREE_CODE (expr
) == VAR_DECL
15889 || CONTAINS_PLACEHOLDER_P (expr
))
15892 *expr_p
= unshare_expr (expr
);
15894 /* SSA names in decl/type fields are a bad idea - they'll get reclaimed
15895 if the def vanishes. */
15896 gimplify_expr (expr_p
, stmt_p
, NULL
, is_gimple_val
, fb_rvalue
, false);
15898 /* If expr wasn't already is_gimple_sizepos or is_gimple_constant from the
15899 FE, ensure that it is a VAR_DECL, otherwise we might handle some decls
15900 as gimplify_vla_decl even when they would have all sizes INTEGER_CSTs. */
15901 if (is_gimple_constant (*expr_p
))
15902 *expr_p
= get_initialized_tmp_var (*expr_p
, stmt_p
, NULL
, false);
15905 /* Gimplify the body of statements of FNDECL and return a GIMPLE_BIND node
15906 containing the sequence of corresponding GIMPLE statements. If DO_PARMS
15907 is true, also gimplify the parameters. */
15910 gimplify_body (tree fndecl
, bool do_parms
)
15912 location_t saved_location
= input_location
;
15913 gimple_seq parm_stmts
, parm_cleanup
= NULL
, seq
;
15914 gimple
*outer_stmt
;
15917 timevar_push (TV_TREE_GIMPLIFY
);
15919 init_tree_ssa (cfun
);
15921 /* Initialize for optimize_insn_for_s{ize,peed}_p possibly called during
15923 default_rtl_profile ();
15925 gcc_assert (gimplify_ctxp
== NULL
);
15926 push_gimplify_context (true);
15928 if (flag_openacc
|| flag_openmp
)
15930 gcc_assert (gimplify_omp_ctxp
== NULL
);
15931 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (fndecl
)))
15932 gimplify_omp_ctxp
= new_omp_context (ORT_IMPLICIT_TARGET
);
15935 /* Unshare most shared trees in the body and in that of any nested functions.
15936 It would seem we don't have to do this for nested functions because
15937 they are supposed to be output and then the outer function gimplified
15938 first, but the g++ front end doesn't always do it that way. */
15939 unshare_body (fndecl
);
15940 unvisit_body (fndecl
);
15942 /* Make sure input_location isn't set to something weird. */
15943 input_location
= DECL_SOURCE_LOCATION (fndecl
);
15945 /* Resolve callee-copies. This has to be done before processing
15946 the body so that DECL_VALUE_EXPR gets processed correctly. */
15947 parm_stmts
= do_parms
? gimplify_parameters (&parm_cleanup
) : NULL
;
15949 /* Gimplify the function's body. */
15951 gimplify_stmt (&DECL_SAVED_TREE (fndecl
), &seq
);
15952 outer_stmt
= gimple_seq_first_nondebug_stmt (seq
);
15955 outer_stmt
= gimple_build_nop ();
15956 gimplify_seq_add_stmt (&seq
, outer_stmt
);
15959 /* The body must contain exactly one statement, a GIMPLE_BIND. If this is
15960 not the case, wrap everything in a GIMPLE_BIND to make it so. */
15961 if (gimple_code (outer_stmt
) == GIMPLE_BIND
15962 && (gimple_seq_first_nondebug_stmt (seq
)
15963 == gimple_seq_last_nondebug_stmt (seq
)))
15965 outer_bind
= as_a
<gbind
*> (outer_stmt
);
15966 if (gimple_seq_first_stmt (seq
) != outer_stmt
15967 || gimple_seq_last_stmt (seq
) != outer_stmt
)
15969 /* If there are debug stmts before or after outer_stmt, move them
15970 inside of outer_bind body. */
15971 gimple_stmt_iterator gsi
= gsi_for_stmt (outer_stmt
, &seq
);
15972 gimple_seq second_seq
= NULL
;
15973 if (gimple_seq_first_stmt (seq
) != outer_stmt
15974 && gimple_seq_last_stmt (seq
) != outer_stmt
)
15976 second_seq
= gsi_split_seq_after (gsi
);
15977 gsi_remove (&gsi
, false);
15979 else if (gimple_seq_first_stmt (seq
) != outer_stmt
)
15980 gsi_remove (&gsi
, false);
15983 gsi_remove (&gsi
, false);
15987 gimple_seq_add_seq_without_update (&seq
,
15988 gimple_bind_body (outer_bind
));
15989 gimple_seq_add_seq_without_update (&seq
, second_seq
);
15990 gimple_bind_set_body (outer_bind
, seq
);
15994 outer_bind
= gimple_build_bind (NULL_TREE
, seq
, NULL
);
15996 DECL_SAVED_TREE (fndecl
) = NULL_TREE
;
15998 /* If we had callee-copies statements, insert them at the beginning
15999 of the function and clear DECL_VALUE_EXPR_P on the parameters. */
16000 if (!gimple_seq_empty_p (parm_stmts
))
16004 gimplify_seq_add_seq (&parm_stmts
, gimple_bind_body (outer_bind
));
16007 gtry
*g
= gimple_build_try (parm_stmts
, parm_cleanup
,
16008 GIMPLE_TRY_FINALLY
);
16010 gimple_seq_add_stmt (&parm_stmts
, g
);
16012 gimple_bind_set_body (outer_bind
, parm_stmts
);
16014 for (parm
= DECL_ARGUMENTS (current_function_decl
);
16015 parm
; parm
= DECL_CHAIN (parm
))
16016 if (DECL_HAS_VALUE_EXPR_P (parm
))
16018 DECL_HAS_VALUE_EXPR_P (parm
) = 0;
16019 DECL_IGNORED_P (parm
) = 0;
16023 if ((flag_openacc
|| flag_openmp
|| flag_openmp_simd
)
16024 && gimplify_omp_ctxp
)
16026 delete_omp_context (gimplify_omp_ctxp
);
16027 gimplify_omp_ctxp
= NULL
;
16030 pop_gimplify_context (outer_bind
);
16031 gcc_assert (gimplify_ctxp
== NULL
);
16033 if (flag_checking
&& !seen_error ())
16034 verify_gimple_in_seq (gimple_bind_body (outer_bind
));
16036 timevar_pop (TV_TREE_GIMPLIFY
);
16037 input_location
= saved_location
;
16042 typedef char *char_p
; /* For DEF_VEC_P. */
16044 /* Return whether we should exclude FNDECL from instrumentation. */
16047 flag_instrument_functions_exclude_p (tree fndecl
)
16051 v
= (vec
<char_p
> *) flag_instrument_functions_exclude_functions
;
16052 if (v
&& v
->length () > 0)
16058 name
= lang_hooks
.decl_printable_name (fndecl
, 1);
16059 FOR_EACH_VEC_ELT (*v
, i
, s
)
16060 if (strstr (name
, s
) != NULL
)
16064 v
= (vec
<char_p
> *) flag_instrument_functions_exclude_files
;
16065 if (v
&& v
->length () > 0)
16071 name
= DECL_SOURCE_FILE (fndecl
);
16072 FOR_EACH_VEC_ELT (*v
, i
, s
)
16073 if (strstr (name
, s
) != NULL
)
16080 /* Entry point to the gimplification pass. FNDECL is the FUNCTION_DECL
16081 node for the function we want to gimplify.
16083 Return the sequence of GIMPLE statements corresponding to the body
16087 gimplify_function_tree (tree fndecl
)
16092 gcc_assert (!gimple_body (fndecl
));
16094 if (DECL_STRUCT_FUNCTION (fndecl
))
16095 push_cfun (DECL_STRUCT_FUNCTION (fndecl
));
16097 push_struct_function (fndecl
);
16099 /* Tentatively set PROP_gimple_lva here, and reset it in gimplify_va_arg_expr
16101 cfun
->curr_properties
|= PROP_gimple_lva
;
16103 if (asan_sanitize_use_after_scope ())
16104 asan_poisoned_variables
= new hash_set
<tree
> ();
16105 bind
= gimplify_body (fndecl
, true);
16106 if (asan_poisoned_variables
)
16108 delete asan_poisoned_variables
;
16109 asan_poisoned_variables
= NULL
;
16112 /* The tree body of the function is no longer needed, replace it
16113 with the new GIMPLE body. */
16115 gimple_seq_add_stmt (&seq
, bind
);
16116 gimple_set_body (fndecl
, seq
);
16118 /* If we're instrumenting function entry/exit, then prepend the call to
16119 the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to
16120 catch the exit hook. */
16121 /* ??? Add some way to ignore exceptions for this TFE. */
16122 if (flag_instrument_function_entry_exit
16123 && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl
)
16124 /* Do not instrument extern inline functions. */
16125 && !(DECL_DECLARED_INLINE_P (fndecl
)
16126 && DECL_EXTERNAL (fndecl
)
16127 && DECL_DISREGARD_INLINE_LIMITS (fndecl
))
16128 && !flag_instrument_functions_exclude_p (fndecl
))
16133 gimple_seq cleanup
= NULL
, body
= NULL
;
16134 tree tmp_var
, this_fn_addr
;
16137 /* The instrumentation hooks aren't going to call the instrumented
16138 function and the address they receive is expected to be matchable
16139 against symbol addresses. Make sure we don't create a trampoline,
16140 in case the current function is nested. */
16141 this_fn_addr
= build_fold_addr_expr (current_function_decl
);
16142 TREE_NO_TRAMPOLINE (this_fn_addr
) = 1;
16144 x
= builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS
);
16145 call
= gimple_build_call (x
, 1, integer_zero_node
);
16146 tmp_var
= create_tmp_var (ptr_type_node
, "return_addr");
16147 gimple_call_set_lhs (call
, tmp_var
);
16148 gimplify_seq_add_stmt (&cleanup
, call
);
16149 x
= builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_EXIT
);
16150 call
= gimple_build_call (x
, 2, this_fn_addr
, tmp_var
);
16151 gimplify_seq_add_stmt (&cleanup
, call
);
16152 tf
= gimple_build_try (seq
, cleanup
, GIMPLE_TRY_FINALLY
);
16154 x
= builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS
);
16155 call
= gimple_build_call (x
, 1, integer_zero_node
);
16156 tmp_var
= create_tmp_var (ptr_type_node
, "return_addr");
16157 gimple_call_set_lhs (call
, tmp_var
);
16158 gimplify_seq_add_stmt (&body
, call
);
16159 x
= builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_ENTER
);
16160 call
= gimple_build_call (x
, 2, this_fn_addr
, tmp_var
);
16161 gimplify_seq_add_stmt (&body
, call
);
16162 gimplify_seq_add_stmt (&body
, tf
);
16163 new_bind
= gimple_build_bind (NULL
, body
, NULL
);
16165 /* Replace the current function body with the body
16166 wrapped in the try/finally TF. */
16168 gimple_seq_add_stmt (&seq
, new_bind
);
16169 gimple_set_body (fndecl
, seq
);
16173 if (sanitize_flags_p (SANITIZE_THREAD
)
16174 && param_tsan_instrument_func_entry_exit
)
16176 gcall
*call
= gimple_build_call_internal (IFN_TSAN_FUNC_EXIT
, 0);
16177 gimple
*tf
= gimple_build_try (seq
, call
, GIMPLE_TRY_FINALLY
);
16178 gbind
*new_bind
= gimple_build_bind (NULL
, tf
, NULL
);
16179 /* Replace the current function body with the body
16180 wrapped in the try/finally TF. */
16182 gimple_seq_add_stmt (&seq
, new_bind
);
16183 gimple_set_body (fndecl
, seq
);
16186 DECL_SAVED_TREE (fndecl
) = NULL_TREE
;
16187 cfun
->curr_properties
|= PROP_gimple_any
;
16191 dump_function (TDI_gimple
, fndecl
);
16194 /* Return a dummy expression of type TYPE in order to keep going after an
16198 dummy_object (tree type
)
16200 tree t
= build_int_cst (build_pointer_type (type
), 0);
16201 return build2 (MEM_REF
, type
, t
, t
);
16204 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
16205 builtin function, but a very special sort of operator. */
16207 enum gimplify_status
16208 gimplify_va_arg_expr (tree
*expr_p
, gimple_seq
*pre_p
,
16209 gimple_seq
*post_p ATTRIBUTE_UNUSED
)
16211 tree promoted_type
, have_va_type
;
16212 tree valist
= TREE_OPERAND (*expr_p
, 0);
16213 tree type
= TREE_TYPE (*expr_p
);
16214 tree t
, tag
, aptag
;
16215 location_t loc
= EXPR_LOCATION (*expr_p
);
16217 /* Verify that valist is of the proper type. */
16218 have_va_type
= TREE_TYPE (valist
);
16219 if (have_va_type
== error_mark_node
)
16221 have_va_type
= targetm
.canonical_va_list_type (have_va_type
);
16222 if (have_va_type
== NULL_TREE
16223 && POINTER_TYPE_P (TREE_TYPE (valist
)))
16224 /* Handle 'Case 1: Not an array type' from c-common.c/build_va_arg. */
16226 = targetm
.canonical_va_list_type (TREE_TYPE (TREE_TYPE (valist
)));
16227 gcc_assert (have_va_type
!= NULL_TREE
);
16229 /* Generate a diagnostic for requesting data of a type that cannot
16230 be passed through `...' due to type promotion at the call site. */
16231 if ((promoted_type
= lang_hooks
.types
.type_promotes_to (type
))
16234 static bool gave_help
;
16236 /* Use the expansion point to handle cases such as passing bool (defined
16237 in a system header) through `...'. */
16239 = expansion_point_location_if_in_system_header (loc
);
16241 /* Unfortunately, this is merely undefined, rather than a constraint
16242 violation, so we cannot make this an error. If this call is never
16243 executed, the program is still strictly conforming. */
16244 auto_diagnostic_group d
;
16245 warned
= warning_at (xloc
, 0,
16246 "%qT is promoted to %qT when passed through %<...%>",
16247 type
, promoted_type
);
16248 if (!gave_help
&& warned
)
16251 inform (xloc
, "(so you should pass %qT not %qT to %<va_arg%>)",
16252 promoted_type
, type
);
16255 /* We can, however, treat "undefined" any way we please.
16256 Call abort to encourage the user to fix the program. */
16258 inform (xloc
, "if this code is reached, the program will abort");
16259 /* Before the abort, allow the evaluation of the va_list
16260 expression to exit or longjmp. */
16261 gimplify_and_add (valist
, pre_p
);
16262 t
= build_call_expr_loc (loc
,
16263 builtin_decl_implicit (BUILT_IN_TRAP
), 0);
16264 gimplify_and_add (t
, pre_p
);
16266 /* This is dead code, but go ahead and finish so that the
16267 mode of the result comes out right. */
16268 *expr_p
= dummy_object (type
);
16269 return GS_ALL_DONE
;
16272 tag
= build_int_cst (build_pointer_type (type
), 0);
16273 aptag
= build_int_cst (TREE_TYPE (valist
), 0);
16275 *expr_p
= build_call_expr_internal_loc (loc
, IFN_VA_ARG
, type
, 3,
16276 valist
, tag
, aptag
);
16278 /* Clear the tentatively set PROP_gimple_lva, to indicate that IFN_VA_ARG
16279 needs to be expanded. */
16280 cfun
->curr_properties
&= ~PROP_gimple_lva
;
16285 /* Build a new GIMPLE_ASSIGN tuple and append it to the end of *SEQ_P.
16287 DST/SRC are the destination and source respectively. You can pass
16288 ungimplified trees in DST or SRC, in which case they will be
16289 converted to a gimple operand if necessary.
16291 This function returns the newly created GIMPLE_ASSIGN tuple. */
16294 gimplify_assign (tree dst
, tree src
, gimple_seq
*seq_p
)
16296 tree t
= build2 (MODIFY_EXPR
, TREE_TYPE (dst
), dst
, src
);
16297 gimplify_and_add (t
, seq_p
);
16299 return gimple_seq_last_stmt (*seq_p
);
16303 gimplify_hasher::hash (const elt_t
*p
)
16306 return iterative_hash_expr (t
, 0);
16310 gimplify_hasher::equal (const elt_t
*p1
, const elt_t
*p2
)
16314 enum tree_code code
= TREE_CODE (t1
);
16316 if (TREE_CODE (t2
) != code
16317 || TREE_TYPE (t1
) != TREE_TYPE (t2
))
16320 if (!operand_equal_p (t1
, t2
, 0))
16323 /* Only allow them to compare equal if they also hash equal; otherwise
16324 results are nondeterminate, and we fail bootstrap comparison. */
16325 gcc_checking_assert (hash (p1
) == hash (p2
));