1 /* Tree lowering pass. This pass converts the GENERIC functions-as-trees
2 tree representation into the GIMPLE form.
3 Copyright (C) 2002-2023 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-iterator.h"
46 #include "gimple-fold.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 "tree-hash-traits.h"
57 #include "omp-general.h"
59 #include "gimple-low.h"
60 #include "gomp-constants.h"
61 #include "splay-tree.h"
62 #include "gimple-walk.h"
63 #include "langhooks-def.h" /* FIXME: for lhd_set_decl_assembler_name */
65 #include "stringpool.h"
69 #include "omp-offload.h"
71 #include "tree-nested.h"
73 /* Hash set of poisoned variables in a bind expr. */
74 static hash_set
<tree
> *asan_poisoned_variables
= NULL
;
76 enum gimplify_omp_var_data
79 GOVD_EXPLICIT
= 0x000002,
80 GOVD_SHARED
= 0x000004,
81 GOVD_PRIVATE
= 0x000008,
82 GOVD_FIRSTPRIVATE
= 0x000010,
83 GOVD_LASTPRIVATE
= 0x000020,
84 GOVD_REDUCTION
= 0x000040,
87 GOVD_DEBUG_PRIVATE
= 0x000200,
88 GOVD_PRIVATE_OUTER_REF
= 0x000400,
89 GOVD_LINEAR
= 0x000800,
90 GOVD_ALIGNED
= 0x001000,
92 /* Flag for GOVD_MAP: don't copy back. */
93 GOVD_MAP_TO_ONLY
= 0x002000,
95 /* Flag for GOVD_LINEAR or GOVD_LASTPRIVATE: no outer reference. */
96 GOVD_LINEAR_LASTPRIVATE_NO_OUTER
= 0x004000,
98 GOVD_MAP_0LEN_ARRAY
= 0x008000,
100 /* Flag for GOVD_MAP, if it is always, to or always, tofrom mapping. */
101 GOVD_MAP_ALWAYS_TO
= 0x010000,
103 /* Flag for shared vars that are or might be stored to in the region. */
104 GOVD_WRITTEN
= 0x020000,
106 /* Flag for GOVD_MAP, if it is a forced mapping. */
107 GOVD_MAP_FORCE
= 0x040000,
109 /* Flag for GOVD_MAP: must be present already. */
110 GOVD_MAP_FORCE_PRESENT
= 0x080000,
112 /* Flag for GOVD_MAP: only allocate. */
113 GOVD_MAP_ALLOC_ONLY
= 0x100000,
115 /* Flag for GOVD_MAP: only copy back. */
116 GOVD_MAP_FROM_ONLY
= 0x200000,
118 GOVD_NONTEMPORAL
= 0x400000,
120 /* Flag for GOVD_LASTPRIVATE: conditional modifier. */
121 GOVD_LASTPRIVATE_CONDITIONAL
= 0x800000,
123 GOVD_CONDTEMP
= 0x1000000,
125 /* Flag for GOVD_REDUCTION: inscan seen in {in,ex}clusive clause. */
126 GOVD_REDUCTION_INSCAN
= 0x2000000,
128 /* Flag for GOVD_FIRSTPRIVATE: OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT. */
129 GOVD_FIRSTPRIVATE_IMPLICIT
= 0x4000000,
131 GOVD_DATA_SHARE_CLASS
= (GOVD_SHARED
| GOVD_PRIVATE
| GOVD_FIRSTPRIVATE
132 | GOVD_LASTPRIVATE
| GOVD_REDUCTION
| GOVD_LINEAR
139 ORT_WORKSHARE
= 0x00,
140 ORT_TASKGROUP
= 0x01,
144 ORT_COMBINED_PARALLEL
= ORT_PARALLEL
| 1,
147 ORT_UNTIED_TASK
= ORT_TASK
| 1,
148 ORT_TASKLOOP
= ORT_TASK
| 2,
149 ORT_UNTIED_TASKLOOP
= ORT_UNTIED_TASK
| 2,
152 ORT_COMBINED_TEAMS
= ORT_TEAMS
| 1,
153 ORT_HOST_TEAMS
= ORT_TEAMS
| 2,
154 ORT_COMBINED_HOST_TEAMS
= ORT_COMBINED_TEAMS
| 2,
157 ORT_TARGET_DATA
= 0x40,
159 /* Data region with offloading. */
161 ORT_COMBINED_TARGET
= ORT_TARGET
| 1,
162 ORT_IMPLICIT_TARGET
= ORT_TARGET
| 2,
164 /* OpenACC variants. */
165 ORT_ACC
= 0x100, /* A generic OpenACC region. */
166 ORT_ACC_DATA
= ORT_ACC
| ORT_TARGET_DATA
, /* Data construct. */
167 ORT_ACC_PARALLEL
= ORT_ACC
| ORT_TARGET
, /* Parallel construct */
168 ORT_ACC_KERNELS
= ORT_ACC
| ORT_TARGET
| 2, /* Kernels construct. */
169 ORT_ACC_SERIAL
= ORT_ACC
| ORT_TARGET
| 4, /* Serial construct. */
170 ORT_ACC_HOST_DATA
= ORT_ACC
| ORT_TARGET_DATA
| 2, /* Host data. */
172 /* Dummy OpenMP region, used to disable expansion of
173 DECL_VALUE_EXPRs in taskloop pre body. */
177 /* Gimplify hashtable helper. */
179 struct gimplify_hasher
: free_ptr_hash
<elt_t
>
181 static inline hashval_t
hash (const elt_t
*);
182 static inline bool equal (const elt_t
*, const elt_t
*);
187 struct gimplify_ctx
*prev_context
;
189 vec
<gbind
*> bind_expr_stack
;
191 gimple_seq conditional_cleanups
;
195 vec
<tree
> case_labels
;
196 hash_set
<tree
> *live_switch_vars
;
197 /* The formal temporary table. Should this be persistent? */
198 hash_table
<gimplify_hasher
> *temp_htab
;
201 unsigned into_ssa
: 1;
202 unsigned allow_rhs_cond_expr
: 1;
203 unsigned in_cleanup_point_expr
: 1;
204 unsigned keep_stack
: 1;
205 unsigned save_stack
: 1;
206 unsigned in_switch_expr
: 1;
209 enum gimplify_defaultmap_kind
212 GDMK_SCALAR_TARGET
, /* w/ Fortran's target attr, implicit mapping, only. */
218 struct gimplify_omp_ctx
220 struct gimplify_omp_ctx
*outer_context
;
221 splay_tree variables
;
222 hash_set
<tree
> *privatized_types
;
224 /* Iteration variables in an OMP_FOR. */
225 vec
<tree
> loop_iter_var
;
227 enum omp_clause_default_kind default_kind
;
228 enum omp_region_type region_type
;
232 bool target_firstprivatize_array_bases
;
234 bool order_concurrent
;
240 static struct gimplify_ctx
*gimplify_ctxp
;
241 static struct gimplify_omp_ctx
*gimplify_omp_ctxp
;
242 static bool in_omp_construct
;
244 /* Forward declaration. */
245 static enum gimplify_status
gimplify_compound_expr (tree
*, gimple_seq
*, bool);
246 static hash_map
<tree
, tree
> *oacc_declare_returns
;
247 static enum gimplify_status
gimplify_expr (tree
*, gimple_seq
*, gimple_seq
*,
248 bool (*) (tree
), fallback_t
, bool);
249 static void prepare_gimple_addressable (tree
*, gimple_seq
*);
251 /* Shorter alias name for the above function for use in gimplify.cc
255 gimplify_seq_add_stmt (gimple_seq
*seq_p
, gimple
*gs
)
257 gimple_seq_add_stmt_without_update (seq_p
, gs
);
260 /* Append sequence SRC to the end of sequence *DST_P. If *DST_P is
261 NULL, a new sequence is allocated. This function is
262 similar to gimple_seq_add_seq, but does not scan the operands.
263 During gimplification, we need to manipulate statement sequences
264 before the def/use vectors have been constructed. */
267 gimplify_seq_add_seq (gimple_seq
*dst_p
, gimple_seq src
)
269 gimple_stmt_iterator si
;
274 si
= gsi_last (*dst_p
);
275 gsi_insert_seq_after_without_update (&si
, src
, GSI_NEW_STMT
);
279 /* Pointer to a list of allocated gimplify_ctx structs to be used for pushing
280 and popping gimplify contexts. */
282 static struct gimplify_ctx
*ctx_pool
= NULL
;
284 /* Return a gimplify context struct from the pool. */
286 static inline struct gimplify_ctx
*
289 struct gimplify_ctx
* c
= ctx_pool
;
292 ctx_pool
= c
->prev_context
;
294 c
= XNEW (struct gimplify_ctx
);
296 memset (c
, '\0', sizeof (*c
));
300 /* Put gimplify context C back into the pool. */
303 ctx_free (struct gimplify_ctx
*c
)
305 c
->prev_context
= ctx_pool
;
309 /* Free allocated ctx stack memory. */
312 free_gimplify_stack (void)
314 struct gimplify_ctx
*c
;
316 while ((c
= ctx_pool
))
318 ctx_pool
= c
->prev_context
;
324 /* Set up a context for the gimplifier. */
327 push_gimplify_context (bool in_ssa
, bool rhs_cond_ok
)
329 struct gimplify_ctx
*c
= ctx_alloc ();
331 c
->prev_context
= gimplify_ctxp
;
333 gimplify_ctxp
->into_ssa
= in_ssa
;
334 gimplify_ctxp
->allow_rhs_cond_expr
= rhs_cond_ok
;
337 /* Tear down a context for the gimplifier. If BODY is non-null, then
338 put the temporaries into the outer BIND_EXPR. Otherwise, put them
341 BODY is not a sequence, but the first tuple in a sequence. */
344 pop_gimplify_context (gimple
*body
)
346 struct gimplify_ctx
*c
= gimplify_ctxp
;
349 && (!c
->bind_expr_stack
.exists ()
350 || c
->bind_expr_stack
.is_empty ()));
351 c
->bind_expr_stack
.release ();
352 gimplify_ctxp
= c
->prev_context
;
355 declare_vars (c
->temps
, body
, false);
357 record_vars (c
->temps
);
364 /* Push a GIMPLE_BIND tuple onto the stack of bindings. */
367 gimple_push_bind_expr (gbind
*bind_stmt
)
369 gimplify_ctxp
->bind_expr_stack
.reserve (8);
370 gimplify_ctxp
->bind_expr_stack
.safe_push (bind_stmt
);
373 /* Pop the first element off the stack of bindings. */
376 gimple_pop_bind_expr (void)
378 gimplify_ctxp
->bind_expr_stack
.pop ();
381 /* Return the first element of the stack of bindings. */
384 gimple_current_bind_expr (void)
386 return gimplify_ctxp
->bind_expr_stack
.last ();
389 /* Return the stack of bindings created during gimplification. */
392 gimple_bind_expr_stack (void)
394 return gimplify_ctxp
->bind_expr_stack
;
397 /* Return true iff there is a COND_EXPR between us and the innermost
398 CLEANUP_POINT_EXPR. This info is used by gimple_push_cleanup. */
401 gimple_conditional_context (void)
403 return gimplify_ctxp
->conditions
> 0;
406 /* Note that we've entered a COND_EXPR. */
409 gimple_push_condition (void)
411 #ifdef ENABLE_GIMPLE_CHECKING
412 if (gimplify_ctxp
->conditions
== 0)
413 gcc_assert (gimple_seq_empty_p (gimplify_ctxp
->conditional_cleanups
));
415 ++(gimplify_ctxp
->conditions
);
418 /* Note that we've left a COND_EXPR. If we're back at unconditional scope
419 now, add any conditional cleanups we've seen to the prequeue. */
422 gimple_pop_condition (gimple_seq
*pre_p
)
424 int conds
= --(gimplify_ctxp
->conditions
);
426 gcc_assert (conds
>= 0);
429 gimplify_seq_add_seq (pre_p
, gimplify_ctxp
->conditional_cleanups
);
430 gimplify_ctxp
->conditional_cleanups
= NULL
;
434 /* A stable comparison routine for use with splay trees and DECLs. */
437 splay_tree_compare_decl_uid (splay_tree_key xa
, splay_tree_key xb
)
442 return DECL_UID (a
) - DECL_UID (b
);
445 /* Create a new omp construct that deals with variable remapping. */
447 static struct gimplify_omp_ctx
*
448 new_omp_context (enum omp_region_type region_type
)
450 struct gimplify_omp_ctx
*c
;
452 c
= XCNEW (struct gimplify_omp_ctx
);
453 c
->outer_context
= gimplify_omp_ctxp
;
454 c
->variables
= splay_tree_new (splay_tree_compare_decl_uid
, 0, 0);
455 c
->privatized_types
= new hash_set
<tree
>;
456 c
->location
= input_location
;
457 c
->region_type
= region_type
;
458 if ((region_type
& ORT_TASK
) == 0)
459 c
->default_kind
= OMP_CLAUSE_DEFAULT_SHARED
;
461 c
->default_kind
= OMP_CLAUSE_DEFAULT_UNSPECIFIED
;
462 c
->defaultmap
[GDMK_SCALAR
] = GOVD_MAP
;
463 c
->defaultmap
[GDMK_SCALAR_TARGET
] = GOVD_MAP
;
464 c
->defaultmap
[GDMK_AGGREGATE
] = GOVD_MAP
;
465 c
->defaultmap
[GDMK_ALLOCATABLE
] = GOVD_MAP
;
466 c
->defaultmap
[GDMK_POINTER
] = GOVD_MAP
;
471 /* Destroy an omp construct that deals with variable remapping. */
474 delete_omp_context (struct gimplify_omp_ctx
*c
)
476 splay_tree_delete (c
->variables
);
477 delete c
->privatized_types
;
478 c
->loop_iter_var
.release ();
482 static void omp_add_variable (struct gimplify_omp_ctx
*, tree
, unsigned int);
483 static bool omp_notice_variable (struct gimplify_omp_ctx
*, tree
, bool);
485 /* Both gimplify the statement T and append it to *SEQ_P. This function
486 behaves exactly as gimplify_stmt, but you don't have to pass T as a
490 gimplify_and_add (tree t
, gimple_seq
*seq_p
)
492 gimplify_stmt (&t
, seq_p
);
495 /* Gimplify statement T into sequence *SEQ_P, and return the first
496 tuple in the sequence of generated tuples for this statement.
497 Return NULL if gimplifying T produced no tuples. */
500 gimplify_and_return_first (tree t
, gimple_seq
*seq_p
)
502 gimple_stmt_iterator last
= gsi_last (*seq_p
);
504 gimplify_and_add (t
, seq_p
);
506 if (!gsi_end_p (last
))
509 return gsi_stmt (last
);
512 return gimple_seq_first_stmt (*seq_p
);
515 /* Returns true iff T is a valid RHS for an assignment to an un-renamed
516 LHS, or for a call argument. */
519 is_gimple_mem_rhs (tree t
)
521 /* If we're dealing with a renamable type, either source or dest must be
522 a renamed variable. */
523 if (is_gimple_reg_type (TREE_TYPE (t
)))
524 return is_gimple_val (t
);
526 return is_gimple_val (t
) || is_gimple_lvalue (t
);
529 /* Return true if T is a CALL_EXPR or an expression that can be
530 assigned to a temporary. Note that this predicate should only be
531 used during gimplification. See the rationale for this in
532 gimplify_modify_expr. */
535 is_gimple_reg_rhs_or_call (tree t
)
537 return (get_gimple_rhs_class (TREE_CODE (t
)) != GIMPLE_INVALID_RHS
538 || TREE_CODE (t
) == CALL_EXPR
);
541 /* Return true if T is a valid memory RHS or a CALL_EXPR. Note that
542 this predicate should only be used during gimplification. See the
543 rationale for this in gimplify_modify_expr. */
546 is_gimple_mem_rhs_or_call (tree t
)
548 /* If we're dealing with a renamable type, either source or dest must be
549 a renamed variable. */
550 if (is_gimple_reg_type (TREE_TYPE (t
)))
551 return is_gimple_val (t
);
553 return (is_gimple_val (t
)
554 || is_gimple_lvalue (t
)
555 || TREE_CLOBBER_P (t
)
556 || TREE_CODE (t
) == CALL_EXPR
);
559 /* Create a temporary with a name derived from VAL. Subroutine of
560 lookup_tmp_var; nobody else should call this function. */
563 create_tmp_from_val (tree val
)
565 /* Drop all qualifiers and address-space information from the value type. */
566 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (val
));
567 tree var
= create_tmp_var (type
, get_name (val
));
571 /* Create a temporary to hold the value of VAL. If IS_FORMAL, try to reuse
572 an existing expression temporary. If NOT_GIMPLE_REG, mark it as such. */
575 lookup_tmp_var (tree val
, bool is_formal
, bool not_gimple_reg
)
579 /* We cannot mark a formal temporary with DECL_NOT_GIMPLE_REG_P. */
580 gcc_assert (!is_formal
|| !not_gimple_reg
);
582 /* If not optimizing, never really reuse a temporary. local-alloc
583 won't allocate any variable that is used in more than one basic
584 block, which means it will go into memory, causing much extra
585 work in reload and final and poorer code generation, outweighing
586 the extra memory allocation here. */
587 if (!optimize
|| !is_formal
|| TREE_SIDE_EFFECTS (val
))
589 ret
= create_tmp_from_val (val
);
590 DECL_NOT_GIMPLE_REG_P (ret
) = not_gimple_reg
;
598 if (!gimplify_ctxp
->temp_htab
)
599 gimplify_ctxp
->temp_htab
= new hash_table
<gimplify_hasher
> (1000);
600 slot
= gimplify_ctxp
->temp_htab
->find_slot (&elt
, INSERT
);
603 elt_p
= XNEW (elt_t
);
605 elt_p
->temp
= ret
= create_tmp_from_val (val
);
618 /* Helper for get_formal_tmp_var and get_initialized_tmp_var. */
621 internal_get_tmp_var (tree val
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
622 bool is_formal
, bool allow_ssa
, bool not_gimple_reg
)
626 /* Notice that we explicitly allow VAL to be a CALL_EXPR so that we
627 can create an INIT_EXPR and convert it into a GIMPLE_CALL below. */
628 gimplify_expr (&val
, pre_p
, post_p
, is_gimple_reg_rhs_or_call
,
632 && gimplify_ctxp
->into_ssa
633 && is_gimple_reg_type (TREE_TYPE (val
)))
635 t
= make_ssa_name (TYPE_MAIN_VARIANT (TREE_TYPE (val
)));
636 if (! gimple_in_ssa_p (cfun
))
638 const char *name
= get_name (val
);
640 SET_SSA_NAME_VAR_OR_IDENTIFIER (t
, create_tmp_var_name (name
));
644 t
= lookup_tmp_var (val
, is_formal
, not_gimple_reg
);
646 mod
= build2 (INIT_EXPR
, TREE_TYPE (t
), t
, unshare_expr (val
));
648 SET_EXPR_LOCATION (mod
, EXPR_LOC_OR_LOC (val
, input_location
));
650 /* gimplify_modify_expr might want to reduce this further. */
651 gimplify_and_add (mod
, pre_p
);
657 /* Return a formal temporary variable initialized with VAL. PRE_P is as
658 in gimplify_expr. Only use this function if:
660 1) The value of the unfactored expression represented by VAL will not
661 change between the initialization and use of the temporary, and
662 2) The temporary will not be otherwise modified.
664 For instance, #1 means that this is inappropriate for SAVE_EXPR temps,
665 and #2 means it is inappropriate for && temps.
667 For other cases, use get_initialized_tmp_var instead. */
670 get_formal_tmp_var (tree val
, gimple_seq
*pre_p
)
672 return internal_get_tmp_var (val
, pre_p
, NULL
, true, true, false);
675 /* Return a temporary variable initialized with VAL. PRE_P and POST_P
676 are as in gimplify_expr. */
679 get_initialized_tmp_var (tree val
, gimple_seq
*pre_p
,
680 gimple_seq
*post_p
/* = NULL */,
681 bool allow_ssa
/* = true */)
683 return internal_get_tmp_var (val
, pre_p
, post_p
, false, allow_ssa
, false);
686 /* Declare all the variables in VARS in SCOPE. If DEBUG_INFO is true,
687 generate debug info for them; otherwise don't. */
690 declare_vars (tree vars
, gimple
*gs
, bool debug_info
)
697 gbind
*scope
= as_a
<gbind
*> (gs
);
699 temps
= nreverse (last
);
701 block
= gimple_bind_block (scope
);
702 gcc_assert (!block
|| TREE_CODE (block
) == BLOCK
);
703 if (!block
|| !debug_info
)
705 DECL_CHAIN (last
) = gimple_bind_vars (scope
);
706 gimple_bind_set_vars (scope
, temps
);
710 /* We need to attach the nodes both to the BIND_EXPR and to its
711 associated BLOCK for debugging purposes. The key point here
712 is that the BLOCK_VARS of the BIND_EXPR_BLOCK of a BIND_EXPR
713 is a subchain of the BIND_EXPR_VARS of the BIND_EXPR. */
714 if (BLOCK_VARS (block
))
715 BLOCK_VARS (block
) = chainon (BLOCK_VARS (block
), temps
);
718 gimple_bind_set_vars (scope
,
719 chainon (gimple_bind_vars (scope
), temps
));
720 BLOCK_VARS (block
) = temps
;
726 /* For VAR a VAR_DECL of variable size, try to find a constant upper bound
727 for the size and adjust DECL_SIZE/DECL_SIZE_UNIT accordingly. Abort if
728 no such upper bound can be obtained. */
731 force_constant_size (tree var
)
733 /* The only attempt we make is by querying the maximum size of objects
734 of the variable's type. */
736 HOST_WIDE_INT max_size
;
738 gcc_assert (VAR_P (var
));
740 max_size
= max_int_size_in_bytes (TREE_TYPE (var
));
742 gcc_assert (max_size
>= 0);
745 = build_int_cst (TREE_TYPE (DECL_SIZE_UNIT (var
)), max_size
);
747 = build_int_cst (TREE_TYPE (DECL_SIZE (var
)), max_size
* BITS_PER_UNIT
);
750 /* Push the temporary variable TMP into the current binding. */
753 gimple_add_tmp_var_fn (struct function
*fn
, tree tmp
)
755 gcc_assert (!DECL_CHAIN (tmp
) && !DECL_SEEN_IN_BIND_EXPR_P (tmp
));
757 /* Later processing assumes that the object size is constant, which might
758 not be true at this point. Force the use of a constant upper bound in
760 if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp
)))
761 force_constant_size (tmp
);
763 DECL_CONTEXT (tmp
) = fn
->decl
;
764 DECL_SEEN_IN_BIND_EXPR_P (tmp
) = 1;
766 record_vars_into (tmp
, fn
->decl
);
769 /* Push the temporary variable TMP into the current binding. */
772 gimple_add_tmp_var (tree tmp
)
774 gcc_assert (!DECL_CHAIN (tmp
) && !DECL_SEEN_IN_BIND_EXPR_P (tmp
));
776 /* Later processing assumes that the object size is constant, which might
777 not be true at this point. Force the use of a constant upper bound in
779 if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp
)))
780 force_constant_size (tmp
);
782 DECL_CONTEXT (tmp
) = current_function_decl
;
783 DECL_SEEN_IN_BIND_EXPR_P (tmp
) = 1;
787 DECL_CHAIN (tmp
) = gimplify_ctxp
->temps
;
788 gimplify_ctxp
->temps
= tmp
;
790 /* Mark temporaries local within the nearest enclosing parallel. */
791 if (gimplify_omp_ctxp
)
793 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
794 int flag
= GOVD_LOCAL
| GOVD_SEEN
;
796 && (ctx
->region_type
== ORT_WORKSHARE
797 || ctx
->region_type
== ORT_TASKGROUP
798 || ctx
->region_type
== ORT_SIMD
799 || ctx
->region_type
== ORT_ACC
))
801 if (ctx
->region_type
== ORT_SIMD
802 && TREE_ADDRESSABLE (tmp
)
803 && !TREE_STATIC (tmp
))
805 if (TREE_CODE (DECL_SIZE_UNIT (tmp
)) != INTEGER_CST
)
806 ctx
->add_safelen1
= true;
807 else if (ctx
->in_for_exprs
)
810 flag
= GOVD_PRIVATE
| GOVD_SEEN
;
813 ctx
= ctx
->outer_context
;
816 omp_add_variable (ctx
, tmp
, flag
);
825 /* This case is for nested functions. We need to expose the locals
827 body_seq
= gimple_body (current_function_decl
);
828 declare_vars (tmp
, gimple_seq_first_stmt (body_seq
), false);
834 /* This page contains routines to unshare tree nodes, i.e. to duplicate tree
835 nodes that are referenced more than once in GENERIC functions. This is
836 necessary because gimplification (translation into GIMPLE) is performed
837 by modifying tree nodes in-place, so gimplication of a shared node in a
838 first context could generate an invalid GIMPLE form in a second context.
840 This is achieved with a simple mark/copy/unmark algorithm that walks the
841 GENERIC representation top-down, marks nodes with TREE_VISITED the first
842 time it encounters them, duplicates them if they already have TREE_VISITED
843 set, and finally removes the TREE_VISITED marks it has set.
845 The algorithm works only at the function level, i.e. it generates a GENERIC
846 representation of a function with no nodes shared within the function when
847 passed a GENERIC function (except for nodes that are allowed to be shared).
849 At the global level, it is also necessary to unshare tree nodes that are
850 referenced in more than one function, for the same aforementioned reason.
851 This requires some cooperation from the front-end. There are 2 strategies:
853 1. Manual unsharing. The front-end needs to call unshare_expr on every
854 expression that might end up being shared across functions.
856 2. Deep unsharing. This is an extension of regular unsharing. Instead
857 of calling unshare_expr on expressions that might be shared across
858 functions, the front-end pre-marks them with TREE_VISITED. This will
859 ensure that they are unshared on the first reference within functions
860 when the regular unsharing algorithm runs. The counterpart is that
861 this algorithm must look deeper than for manual unsharing, which is
862 specified by LANG_HOOKS_DEEP_UNSHARING.
864 If there are only few specific cases of node sharing across functions, it is
865 probably easier for a front-end to unshare the expressions manually. On the
866 contrary, if the expressions generated at the global level are as widespread
867 as expressions generated within functions, deep unsharing is very likely the
870 /* Similar to copy_tree_r but do not copy SAVE_EXPR or TARGET_EXPR nodes.
871 These nodes model computations that must be done once. If we were to
872 unshare something like SAVE_EXPR(i++), the gimplification process would
873 create wrong code. However, if DATA is non-null, it must hold a pointer
874 set that is used to unshare the subtrees of these nodes. */
877 mostly_copy_tree_r (tree
*tp
, int *walk_subtrees
, void *data
)
880 enum tree_code code
= TREE_CODE (t
);
882 /* Do not copy SAVE_EXPR, TARGET_EXPR or BIND_EXPR nodes themselves, but
883 copy their subtrees if we can make sure to do it only once. */
884 if (code
== SAVE_EXPR
|| code
== TARGET_EXPR
|| code
== BIND_EXPR
)
886 if (data
&& !((hash_set
<tree
> *)data
)->add (t
))
892 /* Stop at types, decls, constants like copy_tree_r. */
893 else if (TREE_CODE_CLASS (code
) == tcc_type
894 || TREE_CODE_CLASS (code
) == tcc_declaration
895 || TREE_CODE_CLASS (code
) == tcc_constant
)
898 /* Cope with the statement expression extension. */
899 else if (code
== STATEMENT_LIST
)
902 /* Leave the bulk of the work to copy_tree_r itself. */
904 copy_tree_r (tp
, walk_subtrees
, NULL
);
909 /* Callback for walk_tree to unshare most of the shared trees rooted at *TP.
910 If *TP has been visited already, then *TP is deeply copied by calling
911 mostly_copy_tree_r. DATA is passed to mostly_copy_tree_r unmodified. */
914 copy_if_shared_r (tree
*tp
, int *walk_subtrees
, void *data
)
917 enum tree_code code
= TREE_CODE (t
);
919 /* Skip types, decls, and constants. But we do want to look at their
920 types and the bounds of types. Mark them as visited so we properly
921 unmark their subtrees on the unmark pass. If we've already seen them,
922 don't look down further. */
923 if (TREE_CODE_CLASS (code
) == tcc_type
924 || TREE_CODE_CLASS (code
) == tcc_declaration
925 || TREE_CODE_CLASS (code
) == tcc_constant
)
927 if (TREE_VISITED (t
))
930 TREE_VISITED (t
) = 1;
933 /* If this node has been visited already, unshare it and don't look
935 else if (TREE_VISITED (t
))
937 walk_tree (tp
, mostly_copy_tree_r
, data
, NULL
);
941 /* Otherwise, mark the node as visited and keep looking. */
943 TREE_VISITED (t
) = 1;
948 /* Unshare most of the shared trees rooted at *TP. DATA is passed to the
949 copy_if_shared_r callback unmodified. */
952 copy_if_shared (tree
*tp
, void *data
)
954 walk_tree (tp
, copy_if_shared_r
, data
, NULL
);
957 /* Unshare all the trees in the body of FNDECL, as well as in the bodies of
958 any nested functions. */
961 unshare_body (tree fndecl
)
963 struct cgraph_node
*cgn
= cgraph_node::get (fndecl
);
964 /* If the language requires deep unsharing, we need a pointer set to make
965 sure we don't repeatedly unshare subtrees of unshareable nodes. */
966 hash_set
<tree
> *visited
967 = lang_hooks
.deep_unsharing
? new hash_set
<tree
> : NULL
;
969 copy_if_shared (&DECL_SAVED_TREE (fndecl
), visited
);
970 copy_if_shared (&DECL_SIZE (DECL_RESULT (fndecl
)), visited
);
971 copy_if_shared (&DECL_SIZE_UNIT (DECL_RESULT (fndecl
)), visited
);
976 for (cgn
= first_nested_function (cgn
); cgn
;
977 cgn
= next_nested_function (cgn
))
978 unshare_body (cgn
->decl
);
981 /* Callback for walk_tree to unmark the visited trees rooted at *TP.
982 Subtrees are walked until the first unvisited node is encountered. */
985 unmark_visited_r (tree
*tp
, int *walk_subtrees
, void *data ATTRIBUTE_UNUSED
)
989 /* If this node has been visited, unmark it and keep looking. */
990 if (TREE_VISITED (t
))
991 TREE_VISITED (t
) = 0;
993 /* Otherwise, don't look any deeper. */
1000 /* Unmark the visited trees rooted at *TP. */
1003 unmark_visited (tree
*tp
)
1005 walk_tree (tp
, unmark_visited_r
, NULL
, NULL
);
1008 /* Likewise, but mark all trees as not visited. */
1011 unvisit_body (tree fndecl
)
1013 struct cgraph_node
*cgn
= cgraph_node::get (fndecl
);
1015 unmark_visited (&DECL_SAVED_TREE (fndecl
));
1016 unmark_visited (&DECL_SIZE (DECL_RESULT (fndecl
)));
1017 unmark_visited (&DECL_SIZE_UNIT (DECL_RESULT (fndecl
)));
1020 for (cgn
= first_nested_function (cgn
);
1021 cgn
; cgn
= next_nested_function (cgn
))
1022 unvisit_body (cgn
->decl
);
1025 /* Unconditionally make an unshared copy of EXPR. This is used when using
1026 stored expressions which span multiple functions, such as BINFO_VTABLE,
1027 as the normal unsharing process can't tell that they're shared. */
1030 unshare_expr (tree expr
)
1032 walk_tree (&expr
, mostly_copy_tree_r
, NULL
, NULL
);
1036 /* Worker for unshare_expr_without_location. */
1039 prune_expr_location (tree
*tp
, int *walk_subtrees
, void *)
1042 SET_EXPR_LOCATION (*tp
, UNKNOWN_LOCATION
);
1048 /* Similar to unshare_expr but also prune all expression locations
1052 unshare_expr_without_location (tree expr
)
1054 walk_tree (&expr
, mostly_copy_tree_r
, NULL
, NULL
);
1056 walk_tree (&expr
, prune_expr_location
, NULL
, NULL
);
1060 /* Return the EXPR_LOCATION of EXPR, if it (maybe recursively) has
1061 one, OR_ELSE otherwise. The location of a STATEMENT_LISTs
1062 comprising at least one DEBUG_BEGIN_STMT followed by exactly one
1063 EXPR is the location of the EXPR. */
1066 rexpr_location (tree expr
, location_t or_else
= UNKNOWN_LOCATION
)
1071 if (EXPR_HAS_LOCATION (expr
))
1072 return EXPR_LOCATION (expr
);
1074 if (TREE_CODE (expr
) != STATEMENT_LIST
)
1077 tree_stmt_iterator i
= tsi_start (expr
);
1080 while (!tsi_end_p (i
) && TREE_CODE (tsi_stmt (i
)) == DEBUG_BEGIN_STMT
)
1086 if (!found
|| !tsi_one_before_end_p (i
))
1089 return rexpr_location (tsi_stmt (i
), or_else
);
1092 /* Return TRUE iff EXPR (maybe recursively) has a location; see
1093 rexpr_location for the potential recursion. */
1096 rexpr_has_location (tree expr
)
1098 return rexpr_location (expr
) != UNKNOWN_LOCATION
;
1102 /* WRAPPER is a code such as BIND_EXPR or CLEANUP_POINT_EXPR which can both
1103 contain statements and have a value. Assign its value to a temporary
1104 and give it void_type_node. Return the temporary, or NULL_TREE if
1105 WRAPPER was already void. */
1108 voidify_wrapper_expr (tree wrapper
, tree temp
)
1110 tree type
= TREE_TYPE (wrapper
);
1111 if (type
&& !VOID_TYPE_P (type
))
1115 /* Set p to point to the body of the wrapper. Loop until we find
1116 something that isn't a wrapper. */
1117 for (p
= &wrapper
; p
&& *p
; )
1119 switch (TREE_CODE (*p
))
1122 TREE_SIDE_EFFECTS (*p
) = 1;
1123 TREE_TYPE (*p
) = void_type_node
;
1124 /* For a BIND_EXPR, the body is operand 1. */
1125 p
= &BIND_EXPR_BODY (*p
);
1128 case CLEANUP_POINT_EXPR
:
1129 case TRY_FINALLY_EXPR
:
1130 case TRY_CATCH_EXPR
:
1131 TREE_SIDE_EFFECTS (*p
) = 1;
1132 TREE_TYPE (*p
) = void_type_node
;
1133 p
= &TREE_OPERAND (*p
, 0);
1136 case STATEMENT_LIST
:
1138 tree_stmt_iterator i
= tsi_last (*p
);
1139 TREE_SIDE_EFFECTS (*p
) = 1;
1140 TREE_TYPE (*p
) = void_type_node
;
1141 p
= tsi_end_p (i
) ? NULL
: tsi_stmt_ptr (i
);
1146 /* Advance to the last statement. Set all container types to
1148 for (; TREE_CODE (*p
) == COMPOUND_EXPR
; p
= &TREE_OPERAND (*p
, 1))
1150 TREE_SIDE_EFFECTS (*p
) = 1;
1151 TREE_TYPE (*p
) = void_type_node
;
1155 case TRANSACTION_EXPR
:
1156 TREE_SIDE_EFFECTS (*p
) = 1;
1157 TREE_TYPE (*p
) = void_type_node
;
1158 p
= &TRANSACTION_EXPR_BODY (*p
);
1162 /* Assume that any tree upon which voidify_wrapper_expr is
1163 directly called is a wrapper, and that its body is op0. */
1166 TREE_SIDE_EFFECTS (*p
) = 1;
1167 TREE_TYPE (*p
) = void_type_node
;
1168 p
= &TREE_OPERAND (*p
, 0);
1176 if (p
== NULL
|| IS_EMPTY_STMT (*p
))
1180 /* The wrapper is on the RHS of an assignment that we're pushing
1182 gcc_assert (TREE_CODE (temp
) == INIT_EXPR
1183 || TREE_CODE (temp
) == MODIFY_EXPR
);
1184 TREE_OPERAND (temp
, 1) = *p
;
1189 temp
= create_tmp_var (type
, "retval");
1190 *p
= build2 (INIT_EXPR
, type
, temp
, *p
);
1199 /* Prepare calls to builtins to SAVE and RESTORE the stack as well as
1200 a temporary through which they communicate. */
1203 build_stack_save_restore (gcall
**save
, gcall
**restore
)
1207 *save
= gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_SAVE
), 0);
1208 tmp_var
= create_tmp_var (ptr_type_node
, "saved_stack");
1209 gimple_call_set_lhs (*save
, tmp_var
);
1212 = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_RESTORE
),
1216 /* Generate IFN_ASAN_MARK call that poisons shadow of a for DECL variable. */
1219 build_asan_poison_call_expr (tree decl
)
1221 /* Do not poison variables that have size equal to zero. */
1222 tree unit_size
= DECL_SIZE_UNIT (decl
);
1223 if (zerop (unit_size
))
1226 tree base
= build_fold_addr_expr (decl
);
1228 return build_call_expr_internal_loc (UNKNOWN_LOCATION
, IFN_ASAN_MARK
,
1230 build_int_cst (integer_type_node
,
1235 /* Generate IFN_ASAN_MARK call that would poison or unpoison, depending
1236 on POISON flag, shadow memory of a DECL variable. The call will be
1237 put on location identified by IT iterator, where BEFORE flag drives
1238 position where the stmt will be put. */
1241 asan_poison_variable (tree decl
, bool poison
, gimple_stmt_iterator
*it
,
1244 tree unit_size
= DECL_SIZE_UNIT (decl
);
1245 tree base
= build_fold_addr_expr (decl
);
1247 /* Do not poison variables that have size equal to zero. */
1248 if (zerop (unit_size
))
1251 /* It's necessary to have all stack variables aligned to ASAN granularity
1253 gcc_assert (!hwasan_sanitize_p () || hwasan_sanitize_stack_p ());
1254 unsigned shadow_granularity
1255 = hwasan_sanitize_p () ? HWASAN_TAG_GRANULE_SIZE
: ASAN_SHADOW_GRANULARITY
;
1256 if (DECL_ALIGN_UNIT (decl
) <= shadow_granularity
)
1257 SET_DECL_ALIGN (decl
, BITS_PER_UNIT
* shadow_granularity
);
1259 HOST_WIDE_INT flags
= poison
? ASAN_MARK_POISON
: ASAN_MARK_UNPOISON
;
1262 = gimple_build_call_internal (IFN_ASAN_MARK
, 3,
1263 build_int_cst (integer_type_node
, flags
),
1267 gsi_insert_before (it
, g
, GSI_NEW_STMT
);
1269 gsi_insert_after (it
, g
, GSI_NEW_STMT
);
1272 /* Generate IFN_ASAN_MARK internal call that depending on POISON flag
1273 either poisons or unpoisons a DECL. Created statement is appended
1274 to SEQ_P gimple sequence. */
1277 asan_poison_variable (tree decl
, bool poison
, gimple_seq
*seq_p
)
1279 gimple_stmt_iterator it
= gsi_last (*seq_p
);
1280 bool before
= false;
1285 asan_poison_variable (decl
, poison
, &it
, before
);
1288 /* Sort pair of VAR_DECLs A and B by DECL_UID. */
1291 sort_by_decl_uid (const void *a
, const void *b
)
1293 const tree
*t1
= (const tree
*)a
;
1294 const tree
*t2
= (const tree
*)b
;
1296 int uid1
= DECL_UID (*t1
);
1297 int uid2
= DECL_UID (*t2
);
1301 else if (uid1
> uid2
)
1307 /* Generate IFN_ASAN_MARK internal call for all VARIABLES
1308 depending on POISON flag. Created statement is appended
1309 to SEQ_P gimple sequence. */
1312 asan_poison_variables (hash_set
<tree
> *variables
, bool poison
, gimple_seq
*seq_p
)
1314 unsigned c
= variables
->elements ();
1318 auto_vec
<tree
> sorted_variables (c
);
1320 for (hash_set
<tree
>::iterator it
= variables
->begin ();
1321 it
!= variables
->end (); ++it
)
1322 sorted_variables
.safe_push (*it
);
1324 sorted_variables
.qsort (sort_by_decl_uid
);
1328 FOR_EACH_VEC_ELT (sorted_variables
, i
, var
)
1330 asan_poison_variable (var
, poison
, seq_p
);
1332 /* Add use_after_scope_memory attribute for the variable in order
1333 to prevent re-written into SSA. */
1334 if (!lookup_attribute (ASAN_USE_AFTER_SCOPE_ATTRIBUTE
,
1335 DECL_ATTRIBUTES (var
)))
1336 DECL_ATTRIBUTES (var
)
1337 = tree_cons (get_identifier (ASAN_USE_AFTER_SCOPE_ATTRIBUTE
),
1339 DECL_ATTRIBUTES (var
));
1343 /* Gimplify a BIND_EXPR. Just voidify and recurse. */
1345 static enum gimplify_status
1346 gimplify_bind_expr (tree
*expr_p
, gimple_seq
*pre_p
)
1348 tree bind_expr
= *expr_p
;
1349 bool old_keep_stack
= gimplify_ctxp
->keep_stack
;
1350 bool old_save_stack
= gimplify_ctxp
->save_stack
;
1353 gimple_seq body
, cleanup
;
1355 location_t start_locus
= 0, end_locus
= 0;
1356 tree ret_clauses
= NULL
;
1358 tree temp
= voidify_wrapper_expr (bind_expr
, NULL
);
1360 /* Mark variables seen in this bind expr. */
1361 for (t
= BIND_EXPR_VARS (bind_expr
); t
; t
= DECL_CHAIN (t
))
1365 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
1367 /* Mark variable as local. */
1368 if (ctx
&& ctx
->region_type
!= ORT_NONE
&& !DECL_EXTERNAL (t
))
1370 if (! DECL_SEEN_IN_BIND_EXPR_P (t
)
1371 || splay_tree_lookup (ctx
->variables
,
1372 (splay_tree_key
) t
) == NULL
)
1374 int flag
= GOVD_LOCAL
;
1375 if (ctx
->region_type
== ORT_SIMD
1376 && TREE_ADDRESSABLE (t
)
1377 && !TREE_STATIC (t
))
1379 if (TREE_CODE (DECL_SIZE_UNIT (t
)) != INTEGER_CST
)
1380 ctx
->add_safelen1
= true;
1382 flag
= GOVD_PRIVATE
;
1384 omp_add_variable (ctx
, t
, flag
| GOVD_SEEN
);
1386 /* Static locals inside of target construct or offloaded
1387 routines need to be "omp declare target". */
1388 if (TREE_STATIC (t
))
1389 for (; ctx
; ctx
= ctx
->outer_context
)
1390 if ((ctx
->region_type
& ORT_TARGET
) != 0)
1392 if (!lookup_attribute ("omp declare target",
1393 DECL_ATTRIBUTES (t
)))
1395 tree id
= get_identifier ("omp declare target");
1397 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (t
));
1398 varpool_node
*node
= varpool_node::get (t
);
1401 node
->offloadable
= 1;
1402 if (ENABLE_OFFLOADING
&& !DECL_EXTERNAL (t
))
1404 g
->have_offload
= true;
1406 vec_safe_push (offload_vars
, t
);
1414 DECL_SEEN_IN_BIND_EXPR_P (t
) = 1;
1416 if (DECL_HARD_REGISTER (t
) && !is_global_var (t
) && cfun
)
1417 cfun
->has_local_explicit_reg_vars
= true;
1421 bind_stmt
= gimple_build_bind (BIND_EXPR_VARS (bind_expr
), NULL
,
1422 BIND_EXPR_BLOCK (bind_expr
));
1423 gimple_push_bind_expr (bind_stmt
);
1425 gimplify_ctxp
->keep_stack
= false;
1426 gimplify_ctxp
->save_stack
= false;
1428 /* Gimplify the body into the GIMPLE_BIND tuple's body. */
1430 gimplify_stmt (&BIND_EXPR_BODY (bind_expr
), &body
);
1431 gimple_bind_set_body (bind_stmt
, body
);
1433 /* Source location wise, the cleanup code (stack_restore and clobbers)
1434 belongs to the end of the block, so propagate what we have. The
1435 stack_save operation belongs to the beginning of block, which we can
1436 infer from the bind_expr directly if the block has no explicit
1438 if (BIND_EXPR_BLOCK (bind_expr
))
1440 end_locus
= BLOCK_SOURCE_END_LOCATION (BIND_EXPR_BLOCK (bind_expr
));
1441 start_locus
= BLOCK_SOURCE_LOCATION (BIND_EXPR_BLOCK (bind_expr
));
1443 if (start_locus
== 0)
1444 start_locus
= EXPR_LOCATION (bind_expr
);
1449 /* If the code both contains VLAs and calls alloca, then we cannot reclaim
1450 the stack space allocated to the VLAs. */
1451 if (gimplify_ctxp
->save_stack
&& !gimplify_ctxp
->keep_stack
)
1453 gcall
*stack_restore
;
1455 /* Save stack on entry and restore it on exit. Add a try_finally
1456 block to achieve this. */
1457 build_stack_save_restore (&stack_save
, &stack_restore
);
1459 gimple_set_location (stack_save
, start_locus
);
1460 gimple_set_location (stack_restore
, end_locus
);
1462 gimplify_seq_add_stmt (&cleanup
, stack_restore
);
1465 /* Add clobbers for all variables that go out of scope. */
1466 for (t
= BIND_EXPR_VARS (bind_expr
); t
; t
= DECL_CHAIN (t
))
1469 && !is_global_var (t
)
1470 && DECL_CONTEXT (t
) == current_function_decl
)
1472 if (!DECL_HARD_REGISTER (t
)
1473 && !TREE_THIS_VOLATILE (t
)
1474 && !DECL_HAS_VALUE_EXPR_P (t
)
1475 /* Only care for variables that have to be in memory. Others
1476 will be rewritten into SSA names, hence moved to the
1478 && !is_gimple_reg (t
)
1479 && flag_stack_reuse
!= SR_NONE
)
1481 tree clobber
= build_clobber (TREE_TYPE (t
), CLOBBER_EOL
);
1482 gimple
*clobber_stmt
;
1483 clobber_stmt
= gimple_build_assign (t
, clobber
);
1484 gimple_set_location (clobber_stmt
, end_locus
);
1485 gimplify_seq_add_stmt (&cleanup
, clobber_stmt
);
1488 if (flag_openacc
&& oacc_declare_returns
!= NULL
)
1491 if (DECL_HAS_VALUE_EXPR_P (key
))
1493 key
= DECL_VALUE_EXPR (key
);
1494 if (INDIRECT_REF_P (key
))
1495 key
= TREE_OPERAND (key
, 0);
1497 tree
*c
= oacc_declare_returns
->get (key
);
1501 OMP_CLAUSE_CHAIN (*c
) = ret_clauses
;
1503 ret_clauses
= unshare_expr (*c
);
1505 oacc_declare_returns
->remove (key
);
1507 if (oacc_declare_returns
->is_empty ())
1509 delete oacc_declare_returns
;
1510 oacc_declare_returns
= NULL
;
1516 if (asan_poisoned_variables
!= NULL
1517 && asan_poisoned_variables
->contains (t
))
1519 asan_poisoned_variables
->remove (t
);
1520 asan_poison_variable (t
, true, &cleanup
);
1523 if (gimplify_ctxp
->live_switch_vars
!= NULL
1524 && gimplify_ctxp
->live_switch_vars
->contains (t
))
1525 gimplify_ctxp
->live_switch_vars
->remove (t
);
1531 gimple_stmt_iterator si
= gsi_start (cleanup
);
1533 stmt
= gimple_build_omp_target (NULL
, GF_OMP_TARGET_KIND_OACC_DECLARE
,
1535 gsi_insert_seq_before_without_update (&si
, stmt
, GSI_NEW_STMT
);
1541 gimple_seq new_body
;
1544 gs
= gimple_build_try (gimple_bind_body (bind_stmt
), cleanup
,
1545 GIMPLE_TRY_FINALLY
);
1548 gimplify_seq_add_stmt (&new_body
, stack_save
);
1549 gimplify_seq_add_stmt (&new_body
, gs
);
1550 gimple_bind_set_body (bind_stmt
, new_body
);
1553 /* keep_stack propagates all the way up to the outermost BIND_EXPR. */
1554 if (!gimplify_ctxp
->keep_stack
)
1555 gimplify_ctxp
->keep_stack
= old_keep_stack
;
1556 gimplify_ctxp
->save_stack
= old_save_stack
;
1558 gimple_pop_bind_expr ();
1560 gimplify_seq_add_stmt (pre_p
, bind_stmt
);
1568 *expr_p
= NULL_TREE
;
1572 /* Maybe add early return predict statement to PRE_P sequence. */
1575 maybe_add_early_return_predict_stmt (gimple_seq
*pre_p
)
1577 /* If we are not in a conditional context, add PREDICT statement. */
1578 if (gimple_conditional_context ())
1580 gimple
*predict
= gimple_build_predict (PRED_TREE_EARLY_RETURN
,
1582 gimplify_seq_add_stmt (pre_p
, predict
);
1586 /* Gimplify a RETURN_EXPR. If the expression to be returned is not a
1587 GIMPLE value, it is assigned to a new temporary and the statement is
1588 re-written to return the temporary.
1590 PRE_P points to the sequence where side effects that must happen before
1591 STMT should be stored. */
1593 static enum gimplify_status
1594 gimplify_return_expr (tree stmt
, gimple_seq
*pre_p
)
1597 tree ret_expr
= TREE_OPERAND (stmt
, 0);
1598 tree result_decl
, result
;
1600 if (ret_expr
== error_mark_node
)
1604 || TREE_CODE (ret_expr
) == RESULT_DECL
)
1606 maybe_add_early_return_predict_stmt (pre_p
);
1607 greturn
*ret
= gimple_build_return (ret_expr
);
1608 copy_warning (ret
, stmt
);
1609 gimplify_seq_add_stmt (pre_p
, ret
);
1613 if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl
))))
1614 result_decl
= NULL_TREE
;
1615 else if (TREE_CODE (ret_expr
) == COMPOUND_EXPR
)
1617 /* Used in C++ for handling EH cleanup of the return value if a local
1618 cleanup throws. Assume the front-end knows what it's doing. */
1619 result_decl
= DECL_RESULT (current_function_decl
);
1620 /* But crash if we end up trying to modify ret_expr below. */
1621 ret_expr
= NULL_TREE
;
1625 result_decl
= TREE_OPERAND (ret_expr
, 0);
1627 /* See through a return by reference. */
1628 if (INDIRECT_REF_P (result_decl
))
1629 result_decl
= TREE_OPERAND (result_decl
, 0);
1631 gcc_assert ((TREE_CODE (ret_expr
) == MODIFY_EXPR
1632 || TREE_CODE (ret_expr
) == INIT_EXPR
)
1633 && TREE_CODE (result_decl
) == RESULT_DECL
);
1636 /* If aggregate_value_p is true, then we can return the bare RESULT_DECL.
1637 Recall that aggregate_value_p is FALSE for any aggregate type that is
1638 returned in registers. If we're returning values in registers, then
1639 we don't want to extend the lifetime of the RESULT_DECL, particularly
1640 across another call. In addition, for those aggregates for which
1641 hard_function_value generates a PARALLEL, we'll die during normal
1642 expansion of structure assignments; there's special code in expand_return
1643 to handle this case that does not exist in expand_expr. */
1646 else if (aggregate_value_p (result_decl
, TREE_TYPE (current_function_decl
)))
1648 if (!poly_int_tree_p (DECL_SIZE (result_decl
)))
1650 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (result_decl
)))
1651 gimplify_type_sizes (TREE_TYPE (result_decl
), pre_p
);
1652 /* Note that we don't use gimplify_vla_decl because the RESULT_DECL
1653 should be effectively allocated by the caller, i.e. all calls to
1654 this function must be subject to the Return Slot Optimization. */
1655 gimplify_one_sizepos (&DECL_SIZE (result_decl
), pre_p
);
1656 gimplify_one_sizepos (&DECL_SIZE_UNIT (result_decl
), pre_p
);
1658 result
= result_decl
;
1660 else if (gimplify_ctxp
->return_temp
)
1661 result
= gimplify_ctxp
->return_temp
;
1664 result
= create_tmp_reg (TREE_TYPE (result_decl
));
1666 /* ??? With complex control flow (usually involving abnormal edges),
1667 we can wind up warning about an uninitialized value for this. Due
1668 to how this variable is constructed and initialized, this is never
1669 true. Give up and never warn. */
1670 suppress_warning (result
, OPT_Wuninitialized
);
1672 gimplify_ctxp
->return_temp
= result
;
1675 /* Smash the lhs of the MODIFY_EXPR to the temporary we plan to use.
1676 Then gimplify the whole thing. */
1677 if (result
!= result_decl
)
1678 TREE_OPERAND (ret_expr
, 0) = result
;
1680 gimplify_and_add (TREE_OPERAND (stmt
, 0), pre_p
);
1682 maybe_add_early_return_predict_stmt (pre_p
);
1683 ret
= gimple_build_return (result
);
1684 copy_warning (ret
, stmt
);
1685 gimplify_seq_add_stmt (pre_p
, ret
);
1690 /* Gimplify a variable-length array DECL. */
1693 gimplify_vla_decl (tree decl
, gimple_seq
*seq_p
)
1695 /* This is a variable-sized decl. Simplify its size and mark it
1696 for deferred expansion. */
1697 tree t
, addr
, ptr_type
;
1699 gimplify_one_sizepos (&DECL_SIZE (decl
), seq_p
);
1700 gimplify_one_sizepos (&DECL_SIZE_UNIT (decl
), seq_p
);
1702 /* Don't mess with a DECL_VALUE_EXPR set by the front-end. */
1703 if (DECL_HAS_VALUE_EXPR_P (decl
))
1706 /* All occurrences of this decl in final gimplified code will be
1707 replaced by indirection. Setting DECL_VALUE_EXPR does two
1708 things: First, it lets the rest of the gimplifier know what
1709 replacement to use. Second, it lets the debug info know
1710 where to find the value. */
1711 ptr_type
= build_pointer_type (TREE_TYPE (decl
));
1712 addr
= create_tmp_var (ptr_type
, get_name (decl
));
1713 DECL_IGNORED_P (addr
) = 0;
1714 t
= build_fold_indirect_ref (addr
);
1715 TREE_THIS_NOTRAP (t
) = 1;
1716 SET_DECL_VALUE_EXPR (decl
, t
);
1717 DECL_HAS_VALUE_EXPR_P (decl
) = 1;
1719 t
= build_alloca_call_expr (DECL_SIZE_UNIT (decl
), DECL_ALIGN (decl
),
1720 max_int_size_in_bytes (TREE_TYPE (decl
)));
1721 /* The call has been built for a variable-sized object. */
1722 CALL_ALLOCA_FOR_VAR_P (t
) = 1;
1723 t
= fold_convert (ptr_type
, t
);
1724 t
= build2 (MODIFY_EXPR
, TREE_TYPE (addr
), addr
, t
);
1726 gimplify_and_add (t
, seq_p
);
1728 /* Record the dynamic allocation associated with DECL if requested. */
1729 if (flag_callgraph_info
& CALLGRAPH_INFO_DYNAMIC_ALLOC
)
1730 record_dynamic_alloc (decl
);
1733 /* A helper function to be called via walk_tree. Mark all labels under *TP
1734 as being forced. To be called for DECL_INITIAL of static variables. */
1737 force_labels_r (tree
*tp
, int *walk_subtrees
, void *data ATTRIBUTE_UNUSED
)
1741 if (TREE_CODE (*tp
) == LABEL_DECL
)
1743 FORCED_LABEL (*tp
) = 1;
1744 cfun
->has_forced_label_in_static
= 1;
1750 /* Generate an initialization to automatic variable DECL based on INIT_TYPE.
1751 Build a call to internal const function DEFERRED_INIT:
1752 1st argument: SIZE of the DECL;
1753 2nd argument: INIT_TYPE;
1754 3rd argument: NAME of the DECL;
1756 as LHS = DEFERRED_INIT (SIZE of the DECL, INIT_TYPE, NAME of the DECL). */
1759 gimple_add_init_for_auto_var (tree decl
,
1760 enum auto_init_type init_type
,
1763 gcc_assert (auto_var_p (decl
));
1764 gcc_assert (init_type
> AUTO_INIT_UNINITIALIZED
);
1765 location_t loc
= EXPR_LOCATION (decl
);
1766 tree decl_size
= TYPE_SIZE_UNIT (TREE_TYPE (decl
));
1769 = build_int_cst (integer_type_node
, (int) init_type
);
1771 tree decl_name
= NULL_TREE
;
1772 if (DECL_NAME (decl
))
1774 decl_name
= build_string_literal (DECL_NAME (decl
));
1778 char decl_name_anonymous
[3 + (HOST_BITS_PER_INT
+ 2) / 3];
1779 sprintf (decl_name_anonymous
, "D.%u", DECL_UID (decl
));
1780 decl_name
= build_string_literal (decl_name_anonymous
);
1783 tree call
= build_call_expr_internal_loc (loc
, IFN_DEFERRED_INIT
,
1784 TREE_TYPE (decl
), 3,
1785 decl_size
, init_type_node
,
1788 gimplify_assign (decl
, call
, seq_p
);
1791 /* Generate padding initialization for automatic vairable DECL.
1792 C guarantees that brace-init with fewer initializers than members
1793 aggregate will initialize the rest of the aggregate as-if it were
1794 static initialization. In turn static initialization guarantees
1795 that padding is initialized to zero. So, we always initialize paddings
1796 to zeroes regardless INIT_TYPE.
1797 To do the padding initialization, we insert a call to
1798 __builtin_clear_padding (&decl, 0, for_auto_init = true).
1799 Note, we add an additional dummy argument for __builtin_clear_padding,
1800 'for_auto_init' to distinguish whether this call is for automatic
1801 variable initialization or not.
1804 gimple_add_padding_init_for_auto_var (tree decl
, bool is_vla
,
1807 tree addr_of_decl
= NULL_TREE
;
1808 tree fn
= builtin_decl_explicit (BUILT_IN_CLEAR_PADDING
);
1812 /* The temporary address variable for this vla should be
1813 created in gimplify_vla_decl. */
1814 gcc_assert (DECL_HAS_VALUE_EXPR_P (decl
));
1815 gcc_assert (INDIRECT_REF_P (DECL_VALUE_EXPR (decl
)));
1816 addr_of_decl
= TREE_OPERAND (DECL_VALUE_EXPR (decl
), 0);
1820 mark_addressable (decl
);
1821 addr_of_decl
= build_fold_addr_expr (decl
);
1824 gimple
*call
= gimple_build_call (fn
, 2, addr_of_decl
,
1825 build_one_cst (TREE_TYPE (addr_of_decl
)));
1826 gimplify_seq_add_stmt (seq_p
, call
);
1829 /* Return true if the DECL need to be automaticly initialized by the
1832 is_var_need_auto_init (tree decl
)
1834 if (auto_var_p (decl
)
1835 && (TREE_CODE (decl
) != VAR_DECL
1836 || !DECL_HARD_REGISTER (decl
))
1837 && (flag_auto_var_init
> AUTO_INIT_UNINITIALIZED
)
1838 && (!lookup_attribute ("uninitialized", DECL_ATTRIBUTES (decl
)))
1839 && !OPAQUE_TYPE_P (TREE_TYPE (decl
))
1840 && !is_empty_type (TREE_TYPE (decl
)))
1845 /* Gimplify a DECL_EXPR node *STMT_P by making any necessary allocation
1846 and initialization explicit. */
1848 static enum gimplify_status
1849 gimplify_decl_expr (tree
*stmt_p
, gimple_seq
*seq_p
)
1851 tree stmt
= *stmt_p
;
1852 tree decl
= DECL_EXPR_DECL (stmt
);
1854 *stmt_p
= NULL_TREE
;
1856 if (TREE_TYPE (decl
) == error_mark_node
)
1859 if ((TREE_CODE (decl
) == TYPE_DECL
1861 && !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl
)))
1863 gimplify_type_sizes (TREE_TYPE (decl
), seq_p
);
1864 if (TREE_CODE (TREE_TYPE (decl
)) == REFERENCE_TYPE
)
1865 gimplify_type_sizes (TREE_TYPE (TREE_TYPE (decl
)), seq_p
);
1868 /* ??? DECL_ORIGINAL_TYPE is streamed for LTO so it needs to be gimplified
1869 in case its size expressions contain problematic nodes like CALL_EXPR. */
1870 if (TREE_CODE (decl
) == TYPE_DECL
1871 && DECL_ORIGINAL_TYPE (decl
)
1872 && !TYPE_SIZES_GIMPLIFIED (DECL_ORIGINAL_TYPE (decl
)))
1874 gimplify_type_sizes (DECL_ORIGINAL_TYPE (decl
), seq_p
);
1875 if (TREE_CODE (DECL_ORIGINAL_TYPE (decl
)) == REFERENCE_TYPE
)
1876 gimplify_type_sizes (TREE_TYPE (DECL_ORIGINAL_TYPE (decl
)), seq_p
);
1879 if (VAR_P (decl
) && !DECL_EXTERNAL (decl
))
1881 tree init
= DECL_INITIAL (decl
);
1882 bool is_vla
= false;
1883 /* Check whether a decl has FE created VALUE_EXPR here BEFORE
1884 gimplify_vla_decl creates VALUE_EXPR for a vla decl.
1885 If the decl has VALUE_EXPR that was created by FE (usually
1886 C++FE), it's a proxy varaible, and FE already initialized
1887 the VALUE_EXPR of it, we should not initialize it anymore. */
1888 bool decl_had_value_expr_p
= DECL_HAS_VALUE_EXPR_P (decl
);
1891 if (!poly_int_tree_p (DECL_SIZE_UNIT (decl
), &size
)
1892 || (!TREE_STATIC (decl
)
1893 && flag_stack_check
== GENERIC_STACK_CHECK
1895 (unsigned HOST_WIDE_INT
) STACK_CHECK_MAX_VAR_SIZE
)))
1897 gimplify_vla_decl (decl
, seq_p
);
1901 if (asan_poisoned_variables
1903 && TREE_ADDRESSABLE (decl
)
1904 && !TREE_STATIC (decl
)
1905 && !DECL_HAS_VALUE_EXPR_P (decl
)
1906 && DECL_ALIGN (decl
) <= MAX_SUPPORTED_STACK_ALIGNMENT
1907 && dbg_cnt (asan_use_after_scope
)
1908 && !gimplify_omp_ctxp
1909 /* GNAT introduces temporaries to hold return values of calls in
1910 initializers of variables defined in other units, so the
1911 declaration of the variable is discarded completely. We do not
1912 want to issue poison calls for such dropped variables. */
1913 && (DECL_SEEN_IN_BIND_EXPR_P (decl
)
1914 || (DECL_ARTIFICIAL (decl
) && DECL_NAME (decl
) == NULL_TREE
)))
1916 asan_poisoned_variables
->add (decl
);
1917 asan_poison_variable (decl
, false, seq_p
);
1918 if (!DECL_ARTIFICIAL (decl
) && gimplify_ctxp
->live_switch_vars
)
1919 gimplify_ctxp
->live_switch_vars
->add (decl
);
1922 /* Some front ends do not explicitly declare all anonymous
1923 artificial variables. We compensate here by declaring the
1924 variables, though it would be better if the front ends would
1925 explicitly declare them. */
1926 if (!DECL_SEEN_IN_BIND_EXPR_P (decl
)
1927 && DECL_ARTIFICIAL (decl
) && DECL_NAME (decl
) == NULL_TREE
)
1928 gimple_add_tmp_var (decl
);
1930 if (init
&& init
!= error_mark_node
)
1932 if (!TREE_STATIC (decl
))
1934 DECL_INITIAL (decl
) = NULL_TREE
;
1935 init
= build2 (INIT_EXPR
, void_type_node
, decl
, init
);
1936 gimplify_and_add (init
, seq_p
);
1938 /* Clear TREE_READONLY if we really have an initialization. */
1939 if (!DECL_INITIAL (decl
)
1940 && !omp_privatize_by_reference (decl
))
1941 TREE_READONLY (decl
) = 0;
1944 /* We must still examine initializers for static variables
1945 as they may contain a label address. */
1946 walk_tree (&init
, force_labels_r
, NULL
, NULL
);
1948 /* When there is no explicit initializer, if the user requested,
1949 We should insert an artifical initializer for this automatic
1951 else if (is_var_need_auto_init (decl
)
1952 && !decl_had_value_expr_p
)
1954 gimple_add_init_for_auto_var (decl
,
1957 /* The expanding of a call to the above .DEFERRED_INIT will apply
1958 block initialization to the whole space covered by this variable.
1959 As a result, all the paddings will be initialized to zeroes
1960 for zero initialization and 0xFE byte-repeatable patterns for
1961 pattern initialization.
1962 In order to make the paddings as zeroes for pattern init, We
1963 should add a call to __builtin_clear_padding to clear the
1964 paddings to zero in compatiple with CLANG.
1965 We cannot insert this call if the variable is a gimple register
1966 since __builtin_clear_padding will take the address of the
1967 variable. As a result, if a long double/_Complex long double
1968 variable will spilled into stack later, its padding is 0XFE. */
1969 if (flag_auto_var_init
== AUTO_INIT_PATTERN
1970 && !is_gimple_reg (decl
)
1971 && clear_padding_type_may_have_padding_p (TREE_TYPE (decl
)))
1972 gimple_add_padding_init_for_auto_var (decl
, is_vla
, seq_p
);
1979 /* Gimplify a LOOP_EXPR. Normally this just involves gimplifying the body
1980 and replacing the LOOP_EXPR with goto, but if the loop contains an
1981 EXIT_EXPR, we need to append a label for it to jump to. */
1983 static enum gimplify_status
1984 gimplify_loop_expr (tree
*expr_p
, gimple_seq
*pre_p
)
1986 tree saved_label
= gimplify_ctxp
->exit_label
;
1987 tree start_label
= create_artificial_label (UNKNOWN_LOCATION
);
1989 gimplify_seq_add_stmt (pre_p
, gimple_build_label (start_label
));
1991 gimplify_ctxp
->exit_label
= NULL_TREE
;
1993 gimplify_and_add (LOOP_EXPR_BODY (*expr_p
), pre_p
);
1995 gimplify_seq_add_stmt (pre_p
, gimple_build_goto (start_label
));
1997 if (gimplify_ctxp
->exit_label
)
1998 gimplify_seq_add_stmt (pre_p
,
1999 gimple_build_label (gimplify_ctxp
->exit_label
));
2001 gimplify_ctxp
->exit_label
= saved_label
;
2007 /* Gimplify a statement list onto a sequence. These may be created either
2008 by an enlightened front-end, or by shortcut_cond_expr. */
2010 static enum gimplify_status
2011 gimplify_statement_list (tree
*expr_p
, gimple_seq
*pre_p
)
2013 tree temp
= voidify_wrapper_expr (*expr_p
, NULL
);
2015 tree_stmt_iterator i
= tsi_start (*expr_p
);
2017 while (!tsi_end_p (i
))
2019 gimplify_stmt (tsi_stmt_ptr (i
), pre_p
);
2033 /* Emit warning for the unreachable statment STMT if needed.
2034 Return the gimple itself when the warning is emitted, otherwise
2037 emit_warn_switch_unreachable (gimple
*stmt
)
2039 if (gimple_code (stmt
) == GIMPLE_GOTO
2040 && TREE_CODE (gimple_goto_dest (stmt
)) == LABEL_DECL
2041 && DECL_ARTIFICIAL (gimple_goto_dest (stmt
)))
2042 /* Don't warn for compiler-generated gotos. These occur
2043 in Duff's devices, for example. */
2045 else if ((flag_auto_var_init
> AUTO_INIT_UNINITIALIZED
)
2046 && ((gimple_call_internal_p (stmt
, IFN_DEFERRED_INIT
))
2047 || (gimple_call_builtin_p (stmt
, BUILT_IN_CLEAR_PADDING
)
2048 && (bool) TREE_INT_CST_LOW (gimple_call_arg (stmt
, 1)))
2049 || (is_gimple_assign (stmt
)
2050 && gimple_assign_single_p (stmt
)
2051 && (TREE_CODE (gimple_assign_rhs1 (stmt
)) == SSA_NAME
)
2052 && gimple_call_internal_p (
2053 SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt
)),
2054 IFN_DEFERRED_INIT
))))
2055 /* Don't warn for compiler-generated initializations for
2056 -ftrivial-auto-var-init.
2058 case 1: a call to .DEFERRED_INIT;
2059 case 2: a call to __builtin_clear_padding with the 2nd argument is
2060 present and non-zero;
2061 case 3: a gimple assign store right after the call to .DEFERRED_INIT
2062 that has the LHS of .DEFERRED_INIT as the RHS as following:
2063 _1 = .DEFERRED_INIT (4, 2, &"i1"[0]);
2067 warning_at (gimple_location (stmt
), OPT_Wswitch_unreachable
,
2068 "statement will never be executed");
2072 /* Callback for walk_gimple_seq. */
2075 warn_switch_unreachable_and_auto_init_r (gimple_stmt_iterator
*gsi_p
,
2076 bool *handled_ops_p
,
2077 struct walk_stmt_info
*wi
)
2079 gimple
*stmt
= gsi_stmt (*gsi_p
);
2080 bool unreachable_issued
= wi
->info
!= NULL
;
2082 *handled_ops_p
= true;
2083 switch (gimple_code (stmt
))
2086 /* A compiler-generated cleanup or a user-written try block.
2087 If it's empty, don't dive into it--that would result in
2088 worse location info. */
2089 if (gimple_try_eval (stmt
) == NULL
)
2091 if (warn_switch_unreachable
&& !unreachable_issued
)
2092 wi
->info
= emit_warn_switch_unreachable (stmt
);
2094 /* Stop when auto var init warning is not on. */
2095 if (!warn_trivial_auto_var_init
)
2096 return integer_zero_node
;
2101 case GIMPLE_EH_FILTER
:
2102 case GIMPLE_TRANSACTION
:
2103 /* Walk the sub-statements. */
2104 *handled_ops_p
= false;
2108 /* Ignore these. We may generate them before declarations that
2109 are never executed. If there's something to warn about,
2110 there will be non-debug stmts too, and we'll catch those. */
2114 /* Stop till the first Label. */
2115 return integer_zero_node
;
2117 if (gimple_call_internal_p (stmt
, IFN_ASAN_MARK
))
2119 *handled_ops_p
= false;
2122 if (warn_trivial_auto_var_init
2123 && flag_auto_var_init
> AUTO_INIT_UNINITIALIZED
2124 && gimple_call_internal_p (stmt
, IFN_DEFERRED_INIT
))
2126 /* Get the variable name from the 3rd argument of call. */
2127 tree var_name
= gimple_call_arg (stmt
, 2);
2128 var_name
= TREE_OPERAND (TREE_OPERAND (var_name
, 0), 0);
2129 const char *var_name_str
= TREE_STRING_POINTER (var_name
);
2131 warning_at (gimple_location (stmt
), OPT_Wtrivial_auto_var_init
,
2132 "%qs cannot be initialized with"
2133 "%<-ftrivial-auto-var_init%>",
2140 /* check the first "real" statement (not a decl/lexical scope/...), issue
2141 warning if needed. */
2142 if (warn_switch_unreachable
&& !unreachable_issued
)
2143 wi
->info
= emit_warn_switch_unreachable (stmt
);
2144 /* Stop when auto var init warning is not on. */
2145 if (!warn_trivial_auto_var_init
)
2146 return integer_zero_node
;
2153 /* Possibly warn about unreachable statements between switch's controlling
2154 expression and the first case. Also warn about -ftrivial-auto-var-init
2155 cannot initialize the auto variable under such situation.
2156 SEQ is the body of a switch expression. */
2159 maybe_warn_switch_unreachable_and_auto_init (gimple_seq seq
)
2161 if ((!warn_switch_unreachable
&& !warn_trivial_auto_var_init
)
2162 /* This warning doesn't play well with Fortran when optimizations
2164 || lang_GNU_Fortran ()
2168 struct walk_stmt_info wi
;
2170 memset (&wi
, 0, sizeof (wi
));
2171 walk_gimple_seq (seq
, warn_switch_unreachable_and_auto_init_r
, NULL
, &wi
);
2175 /* A label entry that pairs label and a location. */
2182 /* Find LABEL in vector of label entries VEC. */
2184 static struct label_entry
*
2185 find_label_entry (const auto_vec
<struct label_entry
> *vec
, tree label
)
2188 struct label_entry
*l
;
2190 FOR_EACH_VEC_ELT (*vec
, i
, l
)
2191 if (l
->label
== label
)
2196 /* Return true if LABEL, a LABEL_DECL, represents a case label
2197 in a vector of labels CASES. */
2200 case_label_p (const vec
<tree
> *cases
, tree label
)
2205 FOR_EACH_VEC_ELT (*cases
, i
, l
)
2206 if (CASE_LABEL (l
) == label
)
2211 /* Find the last nondebug statement in a scope STMT. */
2214 last_stmt_in_scope (gimple
*stmt
)
2219 switch (gimple_code (stmt
))
2223 gbind
*bind
= as_a
<gbind
*> (stmt
);
2224 stmt
= gimple_seq_last_nondebug_stmt (gimple_bind_body (bind
));
2225 return last_stmt_in_scope (stmt
);
2230 gtry
*try_stmt
= as_a
<gtry
*> (stmt
);
2231 stmt
= gimple_seq_last_nondebug_stmt (gimple_try_eval (try_stmt
));
2232 gimple
*last_eval
= last_stmt_in_scope (stmt
);
2233 if (gimple_stmt_may_fallthru (last_eval
)
2234 && (last_eval
== NULL
2235 || !gimple_call_internal_p (last_eval
, IFN_FALLTHROUGH
))
2236 && gimple_try_kind (try_stmt
) == GIMPLE_TRY_FINALLY
)
2238 stmt
= gimple_seq_last_nondebug_stmt (gimple_try_cleanup (try_stmt
));
2239 return last_stmt_in_scope (stmt
);
2253 /* Collect labels that may fall through into LABELS and return the statement
2254 preceding another case label, or a user-defined label. Store a location
2255 useful to give warnings at *PREVLOC (usually the location of the returned
2256 statement or of its surrounding scope). */
2259 collect_fallthrough_labels (gimple_stmt_iterator
*gsi_p
,
2260 auto_vec
<struct label_entry
> *labels
,
2261 location_t
*prevloc
)
2263 gimple
*prev
= NULL
;
2265 *prevloc
= UNKNOWN_LOCATION
;
2268 if (gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_BIND
)
2270 /* Recognize the special GIMPLE_BIND added by gimplify_switch_expr,
2271 which starts on a GIMPLE_SWITCH and ends with a break label.
2272 Handle that as a single statement that can fall through. */
2273 gbind
*bind
= as_a
<gbind
*> (gsi_stmt (*gsi_p
));
2274 gimple
*first
= gimple_seq_first_stmt (gimple_bind_body (bind
));
2275 gimple
*last
= gimple_seq_last_stmt (gimple_bind_body (bind
));
2277 && gimple_code (first
) == GIMPLE_SWITCH
2278 && gimple_code (last
) == GIMPLE_LABEL
)
2280 tree label
= gimple_label_label (as_a
<glabel
*> (last
));
2281 if (SWITCH_BREAK_LABEL_P (label
))
2289 if (gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_BIND
2290 || gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_TRY
)
2292 /* Nested scope. Only look at the last statement of
2293 the innermost scope. */
2294 location_t bind_loc
= gimple_location (gsi_stmt (*gsi_p
));
2295 gimple
*last
= last_stmt_in_scope (gsi_stmt (*gsi_p
));
2299 /* It might be a label without a location. Use the
2300 location of the scope then. */
2301 if (!gimple_has_location (prev
))
2302 *prevloc
= bind_loc
;
2308 /* Ifs are tricky. */
2309 if (gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_COND
)
2311 gcond
*cond_stmt
= as_a
<gcond
*> (gsi_stmt (*gsi_p
));
2312 tree false_lab
= gimple_cond_false_label (cond_stmt
);
2313 location_t if_loc
= gimple_location (cond_stmt
);
2316 if (i > 1) goto <D.2259>; else goto D;
2317 we can't do much with the else-branch. */
2318 if (!DECL_ARTIFICIAL (false_lab
))
2321 /* Go on until the false label, then one step back. */
2322 for (; !gsi_end_p (*gsi_p
); gsi_next (gsi_p
))
2324 gimple
*stmt
= gsi_stmt (*gsi_p
);
2325 if (gimple_code (stmt
) == GIMPLE_LABEL
2326 && gimple_label_label (as_a
<glabel
*> (stmt
)) == false_lab
)
2330 /* Not found? Oops. */
2331 if (gsi_end_p (*gsi_p
))
2334 /* A dead label can't fall through. */
2335 if (!UNUSED_LABEL_P (false_lab
))
2337 struct label_entry l
= { false_lab
, if_loc
};
2338 labels
->safe_push (l
);
2341 /* Go to the last statement of the then branch. */
2344 /* if (i != 0) goto <D.1759>; else goto <D.1760>;
2350 if (gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_GOTO
2351 && !gimple_has_location (gsi_stmt (*gsi_p
)))
2353 /* Look at the statement before, it might be
2354 attribute fallthrough, in which case don't warn. */
2356 bool fallthru_before_dest
2357 = gimple_call_internal_p (gsi_stmt (*gsi_p
), IFN_FALLTHROUGH
);
2359 tree goto_dest
= gimple_goto_dest (gsi_stmt (*gsi_p
));
2360 if (!fallthru_before_dest
)
2362 struct label_entry l
= { goto_dest
, if_loc
};
2363 labels
->safe_push (l
);
2366 /* This case is about
2367 if (1 != 0) goto <D.2022>; else goto <D.2023>;
2372 where #2 is UNUSED_LABEL_P and we want to warn about #1 falling
2373 through to #3. So set PREV to #1. */
2374 else if (UNUSED_LABEL_P (false_lab
))
2375 prev
= gsi_stmt (*gsi_p
);
2377 /* And move back. */
2381 /* Remember the last statement. Skip labels that are of no interest
2383 if (gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_LABEL
)
2385 tree label
= gimple_label_label (as_a
<glabel
*> (gsi_stmt (*gsi_p
)));
2386 if (find_label_entry (labels
, label
))
2387 prev
= gsi_stmt (*gsi_p
);
2389 else if (gimple_call_internal_p (gsi_stmt (*gsi_p
), IFN_ASAN_MARK
))
2391 else if (gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_PREDICT
)
2393 else if (!is_gimple_debug (gsi_stmt (*gsi_p
)))
2394 prev
= gsi_stmt (*gsi_p
);
2397 while (!gsi_end_p (*gsi_p
)
2398 /* Stop if we find a case or a user-defined label. */
2399 && (gimple_code (gsi_stmt (*gsi_p
)) != GIMPLE_LABEL
2400 || !gimple_has_location (gsi_stmt (*gsi_p
))));
2402 if (prev
&& gimple_has_location (prev
))
2403 *prevloc
= gimple_location (prev
);
2407 /* Return true if the switch fallthough warning should occur. LABEL is
2408 the label statement that we're falling through to. */
2411 should_warn_for_implicit_fallthrough (gimple_stmt_iterator
*gsi_p
, tree label
)
2413 gimple_stmt_iterator gsi
= *gsi_p
;
2415 /* Don't warn if the label is marked with a "falls through" comment. */
2416 if (FALLTHROUGH_LABEL_P (label
))
2419 /* Don't warn for non-case labels followed by a statement:
2424 as these are likely intentional. */
2425 if (!case_label_p (&gimplify_ctxp
->case_labels
, label
))
2428 while (!gsi_end_p (gsi
)
2429 && gimple_code (gsi_stmt (gsi
)) == GIMPLE_LABEL
2430 && (l
= gimple_label_label (as_a
<glabel
*> (gsi_stmt (gsi
))))
2431 && !case_label_p (&gimplify_ctxp
->case_labels
, l
))
2432 gsi_next_nondebug (&gsi
);
2433 if (gsi_end_p (gsi
) || gimple_code (gsi_stmt (gsi
)) != GIMPLE_LABEL
)
2437 /* Don't warn for terminated branches, i.e. when the subsequent case labels
2438 immediately breaks. */
2441 /* Skip all immediately following labels. */
2442 while (!gsi_end_p (gsi
)
2443 && (gimple_code (gsi_stmt (gsi
)) == GIMPLE_LABEL
2444 || gimple_code (gsi_stmt (gsi
)) == GIMPLE_PREDICT
))
2445 gsi_next_nondebug (&gsi
);
2447 /* { ... something; default:; } */
2449 /* { ... something; default: break; } or
2450 { ... something; default: goto L; } */
2451 || gimple_code (gsi_stmt (gsi
)) == GIMPLE_GOTO
2452 /* { ... something; default: return; } */
2453 || gimple_code (gsi_stmt (gsi
)) == GIMPLE_RETURN
)
2459 /* Callback for walk_gimple_seq. */
2462 warn_implicit_fallthrough_r (gimple_stmt_iterator
*gsi_p
, bool *handled_ops_p
,
2463 struct walk_stmt_info
*)
2465 gimple
*stmt
= gsi_stmt (*gsi_p
);
2467 *handled_ops_p
= true;
2468 switch (gimple_code (stmt
))
2473 case GIMPLE_EH_FILTER
:
2474 case GIMPLE_TRANSACTION
:
2475 /* Walk the sub-statements. */
2476 *handled_ops_p
= false;
2479 /* Find a sequence of form:
2486 and possibly warn. */
2489 /* Found a label. Skip all immediately following labels. */
2490 while (!gsi_end_p (*gsi_p
)
2491 && gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_LABEL
)
2492 gsi_next_nondebug (gsi_p
);
2494 /* There might be no more statements. */
2495 if (gsi_end_p (*gsi_p
))
2496 return integer_zero_node
;
2498 /* Vector of labels that fall through. */
2499 auto_vec
<struct label_entry
> labels
;
2501 gimple
*prev
= collect_fallthrough_labels (gsi_p
, &labels
, &prevloc
);
2503 /* There might be no more statements. */
2504 if (gsi_end_p (*gsi_p
))
2505 return integer_zero_node
;
2507 gimple
*next
= gsi_stmt (*gsi_p
);
2509 /* If what follows is a label, then we may have a fallthrough. */
2510 if (gimple_code (next
) == GIMPLE_LABEL
2511 && gimple_has_location (next
)
2512 && (label
= gimple_label_label (as_a
<glabel
*> (next
)))
2515 struct label_entry
*l
;
2516 bool warned_p
= false;
2517 auto_diagnostic_group d
;
2518 if (!should_warn_for_implicit_fallthrough (gsi_p
, label
))
2520 else if (gimple_code (prev
) == GIMPLE_LABEL
2521 && (label
= gimple_label_label (as_a
<glabel
*> (prev
)))
2522 && (l
= find_label_entry (&labels
, label
)))
2523 warned_p
= warning_at (l
->loc
, OPT_Wimplicit_fallthrough_
,
2524 "this statement may fall through");
2525 else if (!gimple_call_internal_p (prev
, IFN_FALLTHROUGH
)
2526 /* Try to be clever and don't warn when the statement
2527 can't actually fall through. */
2528 && gimple_stmt_may_fallthru (prev
)
2529 && prevloc
!= UNKNOWN_LOCATION
)
2530 warned_p
= warning_at (prevloc
,
2531 OPT_Wimplicit_fallthrough_
,
2532 "this statement may fall through");
2534 inform (gimple_location (next
), "here");
2536 /* Mark this label as processed so as to prevent multiple
2537 warnings in nested switches. */
2538 FALLTHROUGH_LABEL_P (label
) = true;
2540 /* So that next warn_implicit_fallthrough_r will start looking for
2541 a new sequence starting with this label. */
2552 /* Warn when a switch case falls through. */
2555 maybe_warn_implicit_fallthrough (gimple_seq seq
)
2557 if (!warn_implicit_fallthrough
)
2560 /* This warning is meant for C/C++/ObjC/ObjC++ only. */
2563 || lang_GNU_OBJC ()))
2566 struct walk_stmt_info wi
;
2567 memset (&wi
, 0, sizeof (wi
));
2568 walk_gimple_seq (seq
, warn_implicit_fallthrough_r
, NULL
, &wi
);
2571 /* Callback for walk_gimple_seq. */
2574 expand_FALLTHROUGH_r (gimple_stmt_iterator
*gsi_p
, bool *handled_ops_p
,
2575 struct walk_stmt_info
*wi
)
2577 gimple
*stmt
= gsi_stmt (*gsi_p
);
2579 *handled_ops_p
= true;
2580 switch (gimple_code (stmt
))
2585 case GIMPLE_EH_FILTER
:
2586 case GIMPLE_TRANSACTION
:
2587 /* Walk the sub-statements. */
2588 *handled_ops_p
= false;
2591 if (gimple_call_internal_p (stmt
, IFN_FALLTHROUGH
))
2593 gsi_remove (gsi_p
, true);
2594 if (gsi_end_p (*gsi_p
))
2596 *static_cast<location_t
*>(wi
->info
) = gimple_location (stmt
);
2597 return integer_zero_node
;
2601 location_t loc
= gimple_location (stmt
);
2603 gimple_stmt_iterator gsi2
= *gsi_p
;
2604 stmt
= gsi_stmt (gsi2
);
2605 if (gimple_code (stmt
) == GIMPLE_GOTO
&& !gimple_has_location (stmt
))
2607 /* Go on until the artificial label. */
2608 tree goto_dest
= gimple_goto_dest (stmt
);
2609 for (; !gsi_end_p (gsi2
); gsi_next (&gsi2
))
2611 if (gimple_code (gsi_stmt (gsi2
)) == GIMPLE_LABEL
2612 && gimple_label_label (as_a
<glabel
*> (gsi_stmt (gsi2
)))
2617 /* Not found? Stop. */
2618 if (gsi_end_p (gsi2
))
2621 /* Look one past it. */
2625 /* We're looking for a case label or default label here. */
2626 while (!gsi_end_p (gsi2
))
2628 stmt
= gsi_stmt (gsi2
);
2629 if (gimple_code (stmt
) == GIMPLE_LABEL
)
2631 tree label
= gimple_label_label (as_a
<glabel
*> (stmt
));
2632 if (gimple_has_location (stmt
) && DECL_ARTIFICIAL (label
))
2638 else if (gimple_call_internal_p (stmt
, IFN_ASAN_MARK
))
2640 else if (!is_gimple_debug (stmt
))
2641 /* Anything else is not expected. */
2646 pedwarn (loc
, 0, "attribute %<fallthrough%> not preceding "
2647 "a case label or default label");
2656 /* Expand all FALLTHROUGH () calls in SEQ. */
2659 expand_FALLTHROUGH (gimple_seq
*seq_p
)
2661 struct walk_stmt_info wi
;
2663 memset (&wi
, 0, sizeof (wi
));
2664 wi
.info
= (void *) &loc
;
2665 walk_gimple_seq_mod (seq_p
, expand_FALLTHROUGH_r
, NULL
, &wi
);
2666 if (wi
.callback_result
== integer_zero_node
)
2667 /* We've found [[fallthrough]]; at the end of a switch, which the C++
2668 standard says is ill-formed; see [dcl.attr.fallthrough]. */
2669 pedwarn (loc
, 0, "attribute %<fallthrough%> not preceding "
2670 "a case label or default label");
2674 /* Gimplify a SWITCH_EXPR, and collect the vector of labels it can
2677 static enum gimplify_status
2678 gimplify_switch_expr (tree
*expr_p
, gimple_seq
*pre_p
)
2680 tree switch_expr
= *expr_p
;
2681 gimple_seq switch_body_seq
= NULL
;
2682 enum gimplify_status ret
;
2683 tree index_type
= TREE_TYPE (switch_expr
);
2684 if (index_type
== NULL_TREE
)
2685 index_type
= TREE_TYPE (SWITCH_COND (switch_expr
));
2687 ret
= gimplify_expr (&SWITCH_COND (switch_expr
), pre_p
, NULL
, is_gimple_val
,
2689 if (ret
== GS_ERROR
|| ret
== GS_UNHANDLED
)
2692 if (SWITCH_BODY (switch_expr
))
2695 vec
<tree
> saved_labels
;
2696 hash_set
<tree
> *saved_live_switch_vars
= NULL
;
2697 tree default_case
= NULL_TREE
;
2698 gswitch
*switch_stmt
;
2700 /* Save old labels, get new ones from body, then restore the old
2701 labels. Save all the things from the switch body to append after. */
2702 saved_labels
= gimplify_ctxp
->case_labels
;
2703 gimplify_ctxp
->case_labels
.create (8);
2705 /* Do not create live_switch_vars if SWITCH_BODY is not a BIND_EXPR. */
2706 saved_live_switch_vars
= gimplify_ctxp
->live_switch_vars
;
2707 tree_code body_type
= TREE_CODE (SWITCH_BODY (switch_expr
));
2708 if (body_type
== BIND_EXPR
|| body_type
== STATEMENT_LIST
)
2709 gimplify_ctxp
->live_switch_vars
= new hash_set
<tree
> (4);
2711 gimplify_ctxp
->live_switch_vars
= NULL
;
2713 bool old_in_switch_expr
= gimplify_ctxp
->in_switch_expr
;
2714 gimplify_ctxp
->in_switch_expr
= true;
2716 gimplify_stmt (&SWITCH_BODY (switch_expr
), &switch_body_seq
);
2718 gimplify_ctxp
->in_switch_expr
= old_in_switch_expr
;
2719 maybe_warn_switch_unreachable_and_auto_init (switch_body_seq
);
2720 maybe_warn_implicit_fallthrough (switch_body_seq
);
2721 /* Only do this for the outermost GIMPLE_SWITCH. */
2722 if (!gimplify_ctxp
->in_switch_expr
)
2723 expand_FALLTHROUGH (&switch_body_seq
);
2725 labels
= gimplify_ctxp
->case_labels
;
2726 gimplify_ctxp
->case_labels
= saved_labels
;
2728 if (gimplify_ctxp
->live_switch_vars
)
2730 gcc_assert (gimplify_ctxp
->live_switch_vars
->is_empty ());
2731 delete gimplify_ctxp
->live_switch_vars
;
2733 gimplify_ctxp
->live_switch_vars
= saved_live_switch_vars
;
2735 preprocess_case_label_vec_for_gimple (labels
, index_type
,
2738 bool add_bind
= false;
2741 glabel
*new_default
;
2744 = build_case_label (NULL_TREE
, NULL_TREE
,
2745 create_artificial_label (UNKNOWN_LOCATION
));
2746 if (old_in_switch_expr
)
2748 SWITCH_BREAK_LABEL_P (CASE_LABEL (default_case
)) = 1;
2751 new_default
= gimple_build_label (CASE_LABEL (default_case
));
2752 gimplify_seq_add_stmt (&switch_body_seq
, new_default
);
2754 else if (old_in_switch_expr
)
2756 gimple
*last
= gimple_seq_last_stmt (switch_body_seq
);
2757 if (last
&& gimple_code (last
) == GIMPLE_LABEL
)
2759 tree label
= gimple_label_label (as_a
<glabel
*> (last
));
2760 if (SWITCH_BREAK_LABEL_P (label
))
2765 switch_stmt
= gimple_build_switch (SWITCH_COND (switch_expr
),
2766 default_case
, labels
);
2767 /* For the benefit of -Wimplicit-fallthrough, if switch_body_seq
2768 ends with a GIMPLE_LABEL holding SWITCH_BREAK_LABEL_P LABEL_DECL,
2769 wrap the GIMPLE_SWITCH up to that GIMPLE_LABEL into a GIMPLE_BIND,
2770 so that we can easily find the start and end of the switch
2774 gimple_seq bind_body
= NULL
;
2775 gimplify_seq_add_stmt (&bind_body
, switch_stmt
);
2776 gimple_seq_add_seq (&bind_body
, switch_body_seq
);
2777 gbind
*bind
= gimple_build_bind (NULL_TREE
, bind_body
, NULL_TREE
);
2778 gimple_set_location (bind
, EXPR_LOCATION (switch_expr
));
2779 gimplify_seq_add_stmt (pre_p
, bind
);
2783 gimplify_seq_add_stmt (pre_p
, switch_stmt
);
2784 gimplify_seq_add_seq (pre_p
, switch_body_seq
);
2794 /* Gimplify the LABEL_EXPR pointed to by EXPR_P. */
2796 static enum gimplify_status
2797 gimplify_label_expr (tree
*expr_p
, gimple_seq
*pre_p
)
2799 gcc_assert (decl_function_context (LABEL_EXPR_LABEL (*expr_p
))
2800 == current_function_decl
);
2802 tree label
= LABEL_EXPR_LABEL (*expr_p
);
2803 glabel
*label_stmt
= gimple_build_label (label
);
2804 gimple_set_location (label_stmt
, EXPR_LOCATION (*expr_p
));
2805 gimplify_seq_add_stmt (pre_p
, label_stmt
);
2807 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label
)))
2808 gimple_seq_add_stmt (pre_p
, gimple_build_predict (PRED_COLD_LABEL
,
2810 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label
)))
2811 gimple_seq_add_stmt (pre_p
, gimple_build_predict (PRED_HOT_LABEL
,
2817 /* Gimplify the CASE_LABEL_EXPR pointed to by EXPR_P. */
2819 static enum gimplify_status
2820 gimplify_case_label_expr (tree
*expr_p
, gimple_seq
*pre_p
)
2822 struct gimplify_ctx
*ctxp
;
2825 /* Invalid programs can play Duff's Device type games with, for example,
2826 #pragma omp parallel. At least in the C front end, we don't
2827 detect such invalid branches until after gimplification, in the
2828 diagnose_omp_blocks pass. */
2829 for (ctxp
= gimplify_ctxp
; ; ctxp
= ctxp
->prev_context
)
2830 if (ctxp
->case_labels
.exists ())
2833 tree label
= CASE_LABEL (*expr_p
);
2834 label_stmt
= gimple_build_label (label
);
2835 gimple_set_location (label_stmt
, EXPR_LOCATION (*expr_p
));
2836 ctxp
->case_labels
.safe_push (*expr_p
);
2837 gimplify_seq_add_stmt (pre_p
, label_stmt
);
2839 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label
)))
2840 gimple_seq_add_stmt (pre_p
, gimple_build_predict (PRED_COLD_LABEL
,
2842 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label
)))
2843 gimple_seq_add_stmt (pre_p
, gimple_build_predict (PRED_HOT_LABEL
,
2849 /* Build a GOTO to the LABEL_DECL pointed to by LABEL_P, building it first
2853 build_and_jump (tree
*label_p
)
2855 if (label_p
== NULL
)
2856 /* If there's nowhere to jump, just fall through. */
2859 if (*label_p
== NULL_TREE
)
2861 tree label
= create_artificial_label (UNKNOWN_LOCATION
);
2865 return build1 (GOTO_EXPR
, void_type_node
, *label_p
);
2868 /* Gimplify an EXIT_EXPR by converting to a GOTO_EXPR inside a COND_EXPR.
2869 This also involves building a label to jump to and communicating it to
2870 gimplify_loop_expr through gimplify_ctxp->exit_label. */
2872 static enum gimplify_status
2873 gimplify_exit_expr (tree
*expr_p
)
2875 tree cond
= TREE_OPERAND (*expr_p
, 0);
2878 expr
= build_and_jump (&gimplify_ctxp
->exit_label
);
2879 expr
= build3 (COND_EXPR
, void_type_node
, cond
, expr
, NULL_TREE
);
2885 /* *EXPR_P is a COMPONENT_REF being used as an rvalue. If its type is
2886 different from its canonical type, wrap the whole thing inside a
2887 NOP_EXPR and force the type of the COMPONENT_REF to be the canonical
2890 The canonical type of a COMPONENT_REF is the type of the field being
2891 referenced--unless the field is a bit-field which can be read directly
2892 in a smaller mode, in which case the canonical type is the
2893 sign-appropriate type corresponding to that mode. */
2896 canonicalize_component_ref (tree
*expr_p
)
2898 tree expr
= *expr_p
;
2901 gcc_assert (TREE_CODE (expr
) == COMPONENT_REF
);
2903 if (INTEGRAL_TYPE_P (TREE_TYPE (expr
)))
2904 type
= TREE_TYPE (get_unwidened (expr
, NULL_TREE
));
2906 type
= TREE_TYPE (TREE_OPERAND (expr
, 1));
2908 /* One could argue that all the stuff below is not necessary for
2909 the non-bitfield case and declare it a FE error if type
2910 adjustment would be needed. */
2911 if (TREE_TYPE (expr
) != type
)
2913 #ifdef ENABLE_TYPES_CHECKING
2914 tree old_type
= TREE_TYPE (expr
);
2918 /* We need to preserve qualifiers and propagate them from
2920 type_quals
= TYPE_QUALS (type
)
2921 | TYPE_QUALS (TREE_TYPE (TREE_OPERAND (expr
, 0)));
2922 if (TYPE_QUALS (type
) != type_quals
)
2923 type
= build_qualified_type (TYPE_MAIN_VARIANT (type
), type_quals
);
2925 /* Set the type of the COMPONENT_REF to the underlying type. */
2926 TREE_TYPE (expr
) = type
;
2928 #ifdef ENABLE_TYPES_CHECKING
2929 /* It is now a FE error, if the conversion from the canonical
2930 type to the original expression type is not useless. */
2931 gcc_assert (useless_type_conversion_p (old_type
, type
));
2936 /* If a NOP conversion is changing a pointer to array of foo to a pointer
2937 to foo, embed that change in the ADDR_EXPR by converting
2942 where L is the lower bound. For simplicity, only do this for constant
2944 The constraint is that the type of &array[L] is trivially convertible
2948 canonicalize_addr_expr (tree
*expr_p
)
2950 tree expr
= *expr_p
;
2951 tree addr_expr
= TREE_OPERAND (expr
, 0);
2952 tree datype
, ddatype
, pddatype
;
2954 /* We simplify only conversions from an ADDR_EXPR to a pointer type. */
2955 if (!POINTER_TYPE_P (TREE_TYPE (expr
))
2956 || TREE_CODE (addr_expr
) != ADDR_EXPR
)
2959 /* The addr_expr type should be a pointer to an array. */
2960 datype
= TREE_TYPE (TREE_TYPE (addr_expr
));
2961 if (TREE_CODE (datype
) != ARRAY_TYPE
)
2964 /* The pointer to element type shall be trivially convertible to
2965 the expression pointer type. */
2966 ddatype
= TREE_TYPE (datype
);
2967 pddatype
= build_pointer_type (ddatype
);
2968 if (!useless_type_conversion_p (TYPE_MAIN_VARIANT (TREE_TYPE (expr
)),
2972 /* The lower bound and element sizes must be constant. */
2973 if (!TYPE_SIZE_UNIT (ddatype
)
2974 || TREE_CODE (TYPE_SIZE_UNIT (ddatype
)) != INTEGER_CST
2975 || !TYPE_DOMAIN (datype
) || !TYPE_MIN_VALUE (TYPE_DOMAIN (datype
))
2976 || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (datype
))) != INTEGER_CST
)
2979 /* All checks succeeded. Build a new node to merge the cast. */
2980 *expr_p
= build4 (ARRAY_REF
, ddatype
, TREE_OPERAND (addr_expr
, 0),
2981 TYPE_MIN_VALUE (TYPE_DOMAIN (datype
)),
2982 NULL_TREE
, NULL_TREE
);
2983 *expr_p
= build1 (ADDR_EXPR
, pddatype
, *expr_p
);
2985 /* We can have stripped a required restrict qualifier above. */
2986 if (!useless_type_conversion_p (TREE_TYPE (expr
), TREE_TYPE (*expr_p
)))
2987 *expr_p
= fold_convert (TREE_TYPE (expr
), *expr_p
);
2990 /* *EXPR_P is a NOP_EXPR or CONVERT_EXPR. Remove it and/or other conversions
2991 underneath as appropriate. */
2993 static enum gimplify_status
2994 gimplify_conversion (tree
*expr_p
)
2996 location_t loc
= EXPR_LOCATION (*expr_p
);
2997 gcc_assert (CONVERT_EXPR_P (*expr_p
));
2999 /* Then strip away all but the outermost conversion. */
3000 STRIP_SIGN_NOPS (TREE_OPERAND (*expr_p
, 0));
3002 /* And remove the outermost conversion if it's useless. */
3003 if (tree_ssa_useless_type_conversion (*expr_p
))
3004 *expr_p
= TREE_OPERAND (*expr_p
, 0);
3006 /* If we still have a conversion at the toplevel,
3007 then canonicalize some constructs. */
3008 if (CONVERT_EXPR_P (*expr_p
))
3010 tree sub
= TREE_OPERAND (*expr_p
, 0);
3012 /* If a NOP conversion is changing the type of a COMPONENT_REF
3013 expression, then canonicalize its type now in order to expose more
3014 redundant conversions. */
3015 if (TREE_CODE (sub
) == COMPONENT_REF
)
3016 canonicalize_component_ref (&TREE_OPERAND (*expr_p
, 0));
3018 /* If a NOP conversion is changing a pointer to array of foo
3019 to a pointer to foo, embed that change in the ADDR_EXPR. */
3020 else if (TREE_CODE (sub
) == ADDR_EXPR
)
3021 canonicalize_addr_expr (expr_p
);
3024 /* If we have a conversion to a non-register type force the
3025 use of a VIEW_CONVERT_EXPR instead. */
3026 if (CONVERT_EXPR_P (*expr_p
) && !is_gimple_reg_type (TREE_TYPE (*expr_p
)))
3027 *expr_p
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, TREE_TYPE (*expr_p
),
3028 TREE_OPERAND (*expr_p
, 0));
3030 /* Canonicalize CONVERT_EXPR to NOP_EXPR. */
3031 if (TREE_CODE (*expr_p
) == CONVERT_EXPR
)
3032 TREE_SET_CODE (*expr_p
, NOP_EXPR
);
3037 /* Gimplify a VAR_DECL or PARM_DECL. Return GS_OK if we expanded a
3038 DECL_VALUE_EXPR, and it's worth re-examining things. */
3040 static enum gimplify_status
3041 gimplify_var_or_parm_decl (tree
*expr_p
)
3043 tree decl
= *expr_p
;
3045 /* ??? If this is a local variable, and it has not been seen in any
3046 outer BIND_EXPR, then it's probably the result of a duplicate
3047 declaration, for which we've already issued an error. It would
3048 be really nice if the front end wouldn't leak these at all.
3049 Currently the only known culprit is C++ destructors, as seen
3050 in g++.old-deja/g++.jason/binding.C.
3051 Another possible culpit are size expressions for variably modified
3052 types which are lost in the FE or not gimplified correctly. */
3054 && !DECL_SEEN_IN_BIND_EXPR_P (decl
)
3055 && !TREE_STATIC (decl
) && !DECL_EXTERNAL (decl
)
3056 && decl_function_context (decl
) == current_function_decl
)
3058 gcc_assert (seen_error ());
3062 /* When within an OMP context, notice uses of variables. */
3063 if (gimplify_omp_ctxp
&& omp_notice_variable (gimplify_omp_ctxp
, decl
, true))
3066 /* If the decl is an alias for another expression, substitute it now. */
3067 if (DECL_HAS_VALUE_EXPR_P (decl
))
3069 *expr_p
= unshare_expr (DECL_VALUE_EXPR (decl
));
3076 /* Recalculate the value of the TREE_SIDE_EFFECTS flag for T. */
3079 recalculate_side_effects (tree t
)
3081 enum tree_code code
= TREE_CODE (t
);
3082 int len
= TREE_OPERAND_LENGTH (t
);
3085 switch (TREE_CODE_CLASS (code
))
3087 case tcc_expression
:
3093 case PREDECREMENT_EXPR
:
3094 case PREINCREMENT_EXPR
:
3095 case POSTDECREMENT_EXPR
:
3096 case POSTINCREMENT_EXPR
:
3097 /* All of these have side-effects, no matter what their
3106 case tcc_comparison
: /* a comparison expression */
3107 case tcc_unary
: /* a unary arithmetic expression */
3108 case tcc_binary
: /* a binary arithmetic expression */
3109 case tcc_reference
: /* a reference */
3110 case tcc_vl_exp
: /* a function call */
3111 TREE_SIDE_EFFECTS (t
) = TREE_THIS_VOLATILE (t
);
3112 for (i
= 0; i
< len
; ++i
)
3114 tree op
= TREE_OPERAND (t
, i
);
3115 if (op
&& TREE_SIDE_EFFECTS (op
))
3116 TREE_SIDE_EFFECTS (t
) = 1;
3121 /* No side-effects. */
3129 /* Gimplify the COMPONENT_REF, ARRAY_REF, REALPART_EXPR or IMAGPART_EXPR
3133 : min_lval '[' val ']'
3135 | compound_lval '[' val ']'
3136 | compound_lval '.' ID
3138 This is not part of the original SIMPLE definition, which separates
3139 array and member references, but it seems reasonable to handle them
3140 together. Also, this way we don't run into problems with union
3141 aliasing; gcc requires that for accesses through a union to alias, the
3142 union reference must be explicit, which was not always the case when we
3143 were splitting up array and member refs.
3145 PRE_P points to the sequence where side effects that must happen before
3146 *EXPR_P should be stored.
3148 POST_P points to the sequence where side effects that must happen after
3149 *EXPR_P should be stored. */
3151 static enum gimplify_status
3152 gimplify_compound_lval (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
3153 fallback_t fallback
)
3156 enum gimplify_status ret
= GS_ALL_DONE
, tret
;
3158 location_t loc
= EXPR_LOCATION (*expr_p
);
3159 tree expr
= *expr_p
;
3161 /* Create a stack of the subexpressions so later we can walk them in
3162 order from inner to outer. */
3163 auto_vec
<tree
, 10> expr_stack
;
3165 /* We can handle anything that get_inner_reference can deal with. */
3166 for (p
= expr_p
; ; p
= &TREE_OPERAND (*p
, 0))
3169 /* Fold INDIRECT_REFs now to turn them into ARRAY_REFs. */
3170 if (TREE_CODE (*p
) == INDIRECT_REF
)
3171 *p
= fold_indirect_ref_loc (loc
, *p
);
3173 if (handled_component_p (*p
))
3175 /* Expand DECL_VALUE_EXPR now. In some cases that may expose
3176 additional COMPONENT_REFs. */
3177 else if ((VAR_P (*p
) || TREE_CODE (*p
) == PARM_DECL
)
3178 && gimplify_var_or_parm_decl (p
) == GS_OK
)
3183 expr_stack
.safe_push (*p
);
3186 gcc_assert (expr_stack
.length ());
3188 /* Now EXPR_STACK is a stack of pointers to all the refs we've
3189 walked through and P points to the innermost expression.
3191 Java requires that we elaborated nodes in source order. That
3192 means we must gimplify the inner expression followed by each of
3193 the indices, in order. But we can't gimplify the inner
3194 expression until we deal with any variable bounds, sizes, or
3195 positions in order to deal with PLACEHOLDER_EXPRs.
3197 The base expression may contain a statement expression that
3198 has declarations used in size expressions, so has to be
3199 gimplified before gimplifying the size expressions.
3201 So we do this in three steps. First we deal with variable
3202 bounds, sizes, and positions, then we gimplify the base and
3203 ensure it is memory if needed, then we deal with the annotations
3204 for any variables in the components and any indices, from left
3207 bool need_non_reg
= false;
3208 for (i
= expr_stack
.length () - 1; i
>= 0; i
--)
3210 tree t
= expr_stack
[i
];
3212 if (error_operand_p (TREE_OPERAND (t
, 0)))
3215 if (TREE_CODE (t
) == ARRAY_REF
|| TREE_CODE (t
) == ARRAY_RANGE_REF
)
3217 /* Deal with the low bound and element type size and put them into
3218 the ARRAY_REF. If these values are set, they have already been
3220 if (TREE_OPERAND (t
, 2) == NULL_TREE
)
3222 tree low
= unshare_expr (array_ref_low_bound (t
));
3223 if (!is_gimple_min_invariant (low
))
3225 TREE_OPERAND (t
, 2) = low
;
3229 if (TREE_OPERAND (t
, 3) == NULL_TREE
)
3231 tree elmt_size
= array_ref_element_size (t
);
3232 if (!is_gimple_min_invariant (elmt_size
))
3234 elmt_size
= unshare_expr (elmt_size
);
3235 tree elmt_type
= TREE_TYPE (TREE_TYPE (TREE_OPERAND (t
, 0)));
3236 tree factor
= size_int (TYPE_ALIGN_UNIT (elmt_type
));
3238 /* Divide the element size by the alignment of the element
3240 elmt_size
= size_binop_loc (loc
, EXACT_DIV_EXPR
,
3243 TREE_OPERAND (t
, 3) = elmt_size
;
3246 need_non_reg
= true;
3248 else if (TREE_CODE (t
) == COMPONENT_REF
)
3250 /* Set the field offset into T and gimplify it. */
3251 if (TREE_OPERAND (t
, 2) == NULL_TREE
)
3253 tree offset
= component_ref_field_offset (t
);
3254 if (!is_gimple_min_invariant (offset
))
3256 offset
= unshare_expr (offset
);
3257 tree field
= TREE_OPERAND (t
, 1);
3259 = size_int (DECL_OFFSET_ALIGN (field
) / BITS_PER_UNIT
);
3261 /* Divide the offset by its alignment. */
3262 offset
= size_binop_loc (loc
, EXACT_DIV_EXPR
,
3265 TREE_OPERAND (t
, 2) = offset
;
3268 need_non_reg
= true;
3270 else if (!is_gimple_reg_type (TREE_TYPE (t
)))
3271 /* When the result of an operation, in particular a VIEW_CONVERT_EXPR
3272 is a non-register type then require the base object to be a
3273 non-register as well. */
3274 need_non_reg
= true;
3277 /* Step 2 is to gimplify the base expression. Make sure lvalue is set
3278 so as to match the min_lval predicate. Failure to do so may result
3279 in the creation of large aggregate temporaries. */
3280 tret
= gimplify_expr (p
, pre_p
, post_p
, is_gimple_min_lval
,
3281 fallback
| fb_lvalue
);
3282 ret
= MIN (ret
, tret
);
3283 if (ret
== GS_ERROR
)
3286 /* Step 2a: if we have component references we do not support on
3287 registers then make sure the base isn't a register. Of course
3288 we can only do so if an rvalue is OK. */
3289 if (need_non_reg
&& (fallback
& fb_rvalue
))
3290 prepare_gimple_addressable (p
, pre_p
);
3293 /* Step 3: gimplify size expressions and the indices and operands of
3294 ARRAY_REF. During this loop we also remove any useless conversions.
3295 If we operate on a register also make sure to properly gimplify
3296 to individual operations. */
3298 bool reg_operations
= is_gimple_reg (*p
);
3299 for (; expr_stack
.length () > 0; )
3301 tree t
= expr_stack
.pop ();
3303 if (TREE_CODE (t
) == ARRAY_REF
|| TREE_CODE (t
) == ARRAY_RANGE_REF
)
3305 gcc_assert (!reg_operations
);
3307 /* Gimplify the low bound and element type size. */
3308 tret
= gimplify_expr (&TREE_OPERAND (t
, 2), pre_p
, post_p
,
3309 is_gimple_reg
, fb_rvalue
);
3310 ret
= MIN (ret
, tret
);
3312 tret
= gimplify_expr (&TREE_OPERAND (t
, 3), pre_p
, post_p
,
3313 is_gimple_reg
, fb_rvalue
);
3314 ret
= MIN (ret
, tret
);
3316 /* Gimplify the dimension. */
3317 tret
= gimplify_expr (&TREE_OPERAND (t
, 1), pre_p
, post_p
,
3318 is_gimple_val
, fb_rvalue
);
3319 ret
= MIN (ret
, tret
);
3321 else if (TREE_CODE (t
) == COMPONENT_REF
)
3323 gcc_assert (!reg_operations
);
3325 tret
= gimplify_expr (&TREE_OPERAND (t
, 2), pre_p
, post_p
,
3326 is_gimple_reg
, fb_rvalue
);
3327 ret
= MIN (ret
, tret
);
3329 else if (reg_operations
)
3331 tret
= gimplify_expr (&TREE_OPERAND (t
, 0), pre_p
, post_p
,
3332 is_gimple_val
, fb_rvalue
);
3333 ret
= MIN (ret
, tret
);
3336 STRIP_USELESS_TYPE_CONVERSION (TREE_OPERAND (t
, 0));
3338 /* The innermost expression P may have originally had
3339 TREE_SIDE_EFFECTS set which would have caused all the outer
3340 expressions in *EXPR_P leading to P to also have had
3341 TREE_SIDE_EFFECTS set. */
3342 recalculate_side_effects (t
);
3345 /* If the outermost expression is a COMPONENT_REF, canonicalize its type. */
3346 if ((fallback
& fb_rvalue
) && TREE_CODE (*expr_p
) == COMPONENT_REF
)
3348 canonicalize_component_ref (expr_p
);
3351 expr_stack
.release ();
3353 gcc_assert (*expr_p
== expr
|| ret
!= GS_ALL_DONE
);
3358 /* Gimplify the self modifying expression pointed to by EXPR_P
3361 PRE_P points to the list where side effects that must happen before
3362 *EXPR_P should be stored.
3364 POST_P points to the list where side effects that must happen after
3365 *EXPR_P should be stored.
3367 WANT_VALUE is nonzero iff we want to use the value of this expression
3368 in another expression.
3370 ARITH_TYPE is the type the computation should be performed in. */
3372 enum gimplify_status
3373 gimplify_self_mod_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
3374 bool want_value
, tree arith_type
)
3376 enum tree_code code
;
3377 tree lhs
, lvalue
, rhs
, t1
;
3378 gimple_seq post
= NULL
, *orig_post_p
= post_p
;
3380 enum tree_code arith_code
;
3381 enum gimplify_status ret
;
3382 location_t loc
= EXPR_LOCATION (*expr_p
);
3384 code
= TREE_CODE (*expr_p
);
3386 gcc_assert (code
== POSTINCREMENT_EXPR
|| code
== POSTDECREMENT_EXPR
3387 || code
== PREINCREMENT_EXPR
|| code
== PREDECREMENT_EXPR
);
3389 /* Prefix or postfix? */
3390 if (code
== POSTINCREMENT_EXPR
|| code
== POSTDECREMENT_EXPR
)
3391 /* Faster to treat as prefix if result is not used. */
3392 postfix
= want_value
;
3396 /* For postfix, make sure the inner expression's post side effects
3397 are executed after side effects from this expression. */
3401 /* Add or subtract? */
3402 if (code
== PREINCREMENT_EXPR
|| code
== POSTINCREMENT_EXPR
)
3403 arith_code
= PLUS_EXPR
;
3405 arith_code
= MINUS_EXPR
;
3407 /* Gimplify the LHS into a GIMPLE lvalue. */
3408 lvalue
= TREE_OPERAND (*expr_p
, 0);
3409 ret
= gimplify_expr (&lvalue
, pre_p
, post_p
, is_gimple_lvalue
, fb_lvalue
);
3410 if (ret
== GS_ERROR
)
3413 /* Extract the operands to the arithmetic operation. */
3415 rhs
= TREE_OPERAND (*expr_p
, 1);
3417 /* For postfix operator, we evaluate the LHS to an rvalue and then use
3418 that as the result value and in the postqueue operation. */
3421 ret
= gimplify_expr (&lhs
, pre_p
, post_p
, is_gimple_val
, fb_rvalue
);
3422 if (ret
== GS_ERROR
)
3425 lhs
= get_initialized_tmp_var (lhs
, pre_p
);
3428 /* For POINTERs increment, use POINTER_PLUS_EXPR. */
3429 if (POINTER_TYPE_P (TREE_TYPE (lhs
)))
3431 rhs
= convert_to_ptrofftype_loc (loc
, rhs
);
3432 if (arith_code
== MINUS_EXPR
)
3433 rhs
= fold_build1_loc (loc
, NEGATE_EXPR
, TREE_TYPE (rhs
), rhs
);
3434 t1
= fold_build2 (POINTER_PLUS_EXPR
, TREE_TYPE (*expr_p
), lhs
, rhs
);
3437 t1
= fold_convert (TREE_TYPE (*expr_p
),
3438 fold_build2 (arith_code
, arith_type
,
3439 fold_convert (arith_type
, lhs
),
3440 fold_convert (arith_type
, rhs
)));
3444 gimplify_assign (lvalue
, t1
, pre_p
);
3445 gimplify_seq_add_seq (orig_post_p
, post
);
3451 *expr_p
= build2 (MODIFY_EXPR
, TREE_TYPE (lvalue
), lvalue
, t1
);
3456 /* If *EXPR_P has a variable sized type, wrap it in a WITH_SIZE_EXPR. */
3459 maybe_with_size_expr (tree
*expr_p
)
3461 tree expr
= *expr_p
;
3462 tree type
= TREE_TYPE (expr
);
3465 /* If we've already wrapped this or the type is error_mark_node, we can't do
3467 if (TREE_CODE (expr
) == WITH_SIZE_EXPR
3468 || type
== error_mark_node
)
3471 /* If the size isn't known or is a constant, we have nothing to do. */
3472 size
= TYPE_SIZE_UNIT (type
);
3473 if (!size
|| poly_int_tree_p (size
))
3476 /* Otherwise, make a WITH_SIZE_EXPR. */
3477 size
= unshare_expr (size
);
3478 size
= SUBSTITUTE_PLACEHOLDER_IN_EXPR (size
, expr
);
3479 *expr_p
= build2 (WITH_SIZE_EXPR
, type
, expr
, size
);
3482 /* Helper for gimplify_call_expr. Gimplify a single argument *ARG_P
3483 Store any side-effects in PRE_P. CALL_LOCATION is the location of
3484 the CALL_EXPR. If ALLOW_SSA is set the actual parameter may be
3485 gimplified to an SSA name. */
3487 enum gimplify_status
3488 gimplify_arg (tree
*arg_p
, gimple_seq
*pre_p
, location_t call_location
,
3491 bool (*test
) (tree
);
3494 /* In general, we allow lvalues for function arguments to avoid
3495 extra overhead of copying large aggregates out of even larger
3496 aggregates into temporaries only to copy the temporaries to
3497 the argument list. Make optimizers happy by pulling out to
3498 temporaries those types that fit in registers. */
3499 if (is_gimple_reg_type (TREE_TYPE (*arg_p
)))
3500 test
= is_gimple_val
, fb
= fb_rvalue
;
3503 test
= is_gimple_lvalue
, fb
= fb_either
;
3504 /* Also strip a TARGET_EXPR that would force an extra copy. */
3505 if (TREE_CODE (*arg_p
) == TARGET_EXPR
)
3507 tree init
= TARGET_EXPR_INITIAL (*arg_p
);
3509 && !VOID_TYPE_P (TREE_TYPE (init
)))
3514 /* If this is a variable sized type, we must remember the size. */
3515 maybe_with_size_expr (arg_p
);
3517 /* FIXME diagnostics: This will mess up gcc.dg/Warray-bounds.c. */
3518 /* Make sure arguments have the same location as the function call
3520 protected_set_expr_location (*arg_p
, call_location
);
3522 /* There is a sequence point before a function call. Side effects in
3523 the argument list must occur before the actual call. So, when
3524 gimplifying arguments, force gimplify_expr to use an internal
3525 post queue which is then appended to the end of PRE_P. */
3526 return gimplify_expr (arg_p
, pre_p
, NULL
, test
, fb
, allow_ssa
);
3529 /* Don't fold inside offloading or taskreg regions: it can break code by
3530 adding decl references that weren't in the source. We'll do it during
3531 omplower pass instead. */
3534 maybe_fold_stmt (gimple_stmt_iterator
*gsi
)
3536 struct gimplify_omp_ctx
*ctx
;
3537 for (ctx
= gimplify_omp_ctxp
; ctx
; ctx
= ctx
->outer_context
)
3538 if ((ctx
->region_type
& (ORT_TARGET
| ORT_PARALLEL
| ORT_TASK
)) != 0)
3540 else if ((ctx
->region_type
& ORT_HOST_TEAMS
) == ORT_HOST_TEAMS
)
3542 /* Delay folding of builtins until the IL is in consistent state
3543 so the diagnostic machinery can do a better job. */
3544 if (gimple_call_builtin_p (gsi_stmt (*gsi
)))
3546 return fold_stmt (gsi
);
3549 /* Gimplify the CALL_EXPR node *EXPR_P into the GIMPLE sequence PRE_P.
3550 WANT_VALUE is true if the result of the call is desired. */
3552 static enum gimplify_status
3553 gimplify_call_expr (tree
*expr_p
, gimple_seq
*pre_p
, bool want_value
)
3555 tree fndecl
, parms
, p
, fnptrtype
;
3556 enum gimplify_status ret
;
3559 bool builtin_va_start_p
= false;
3560 location_t loc
= EXPR_LOCATION (*expr_p
);
3562 gcc_assert (TREE_CODE (*expr_p
) == CALL_EXPR
);
3564 /* For reliable diagnostics during inlining, it is necessary that
3565 every call_expr be annotated with file and line. */
3566 if (! EXPR_HAS_LOCATION (*expr_p
))
3567 SET_EXPR_LOCATION (*expr_p
, input_location
);
3569 /* Gimplify internal functions created in the FEs. */
3570 if (CALL_EXPR_FN (*expr_p
) == NULL_TREE
)
3575 nargs
= call_expr_nargs (*expr_p
);
3576 enum internal_fn ifn
= CALL_EXPR_IFN (*expr_p
);
3577 auto_vec
<tree
> vargs (nargs
);
3579 if (ifn
== IFN_ASSUME
)
3581 if (simple_condition_p (CALL_EXPR_ARG (*expr_p
, 0)))
3583 /* If the [[assume (cond)]]; condition is simple
3584 enough and can be evaluated unconditionally
3585 without side-effects, expand it as
3586 if (!cond) __builtin_unreachable (); */
3587 tree fndecl
= builtin_decl_explicit (BUILT_IN_UNREACHABLE
);
3588 *expr_p
= build3 (COND_EXPR
, void_type_node
,
3589 CALL_EXPR_ARG (*expr_p
, 0), void_node
,
3590 build_call_expr_loc (EXPR_LOCATION (*expr_p
),
3594 /* If not optimizing, ignore the assumptions. */
3595 if (!optimize
|| seen_error ())
3597 *expr_p
= NULL_TREE
;
3600 /* Temporarily, until gimple lowering, transform
3607 such that gimple lowering can outline the condition into
3608 a separate function easily. */
3609 tree guard
= create_tmp_var (boolean_type_node
);
3610 *expr_p
= build2 (MODIFY_EXPR
, void_type_node
, guard
,
3611 gimple_boolify (CALL_EXPR_ARG (*expr_p
, 0)));
3612 *expr_p
= build3 (BIND_EXPR
, void_type_node
, NULL
, *expr_p
, NULL
);
3613 push_gimplify_context ();
3614 gimple_seq body
= NULL
;
3615 gimple
*g
= gimplify_and_return_first (*expr_p
, &body
);
3616 pop_gimplify_context (g
);
3617 g
= gimple_build_assume (guard
, body
);
3618 gimple_set_location (g
, loc
);
3619 gimplify_seq_add_stmt (pre_p
, g
);
3620 *expr_p
= NULL_TREE
;
3624 for (i
= 0; i
< nargs
; i
++)
3626 gimplify_arg (&CALL_EXPR_ARG (*expr_p
, i
), pre_p
,
3627 EXPR_LOCATION (*expr_p
));
3628 vargs
.quick_push (CALL_EXPR_ARG (*expr_p
, i
));
3631 gcall
*call
= gimple_build_call_internal_vec (ifn
, vargs
);
3632 gimple_call_set_nothrow (call
, TREE_NOTHROW (*expr_p
));
3633 gimplify_seq_add_stmt (pre_p
, call
);
3637 /* This may be a call to a builtin function.
3639 Builtin function calls may be transformed into different
3640 (and more efficient) builtin function calls under certain
3641 circumstances. Unfortunately, gimplification can muck things
3642 up enough that the builtin expanders are not aware that certain
3643 transformations are still valid.
3645 So we attempt transformation/gimplification of the call before
3646 we gimplify the CALL_EXPR. At this time we do not manage to
3647 transform all calls in the same manner as the expanders do, but
3648 we do transform most of them. */
3649 fndecl
= get_callee_fndecl (*expr_p
);
3650 if (fndecl
&& fndecl_built_in_p (fndecl
, BUILT_IN_NORMAL
))
3651 switch (DECL_FUNCTION_CODE (fndecl
))
3653 CASE_BUILT_IN_ALLOCA
:
3654 /* If the call has been built for a variable-sized object, then we
3655 want to restore the stack level when the enclosing BIND_EXPR is
3656 exited to reclaim the allocated space; otherwise, we precisely
3657 need to do the opposite and preserve the latest stack level. */
3658 if (CALL_ALLOCA_FOR_VAR_P (*expr_p
))
3659 gimplify_ctxp
->save_stack
= true;
3661 gimplify_ctxp
->keep_stack
= true;
3664 case BUILT_IN_VA_START
:
3666 builtin_va_start_p
= TRUE
;
3667 if (call_expr_nargs (*expr_p
) < 2)
3669 error ("too few arguments to function %<va_start%>");
3670 *expr_p
= build_empty_stmt (EXPR_LOCATION (*expr_p
));
3674 if (fold_builtin_next_arg (*expr_p
, true))
3676 *expr_p
= build_empty_stmt (EXPR_LOCATION (*expr_p
));
3682 case BUILT_IN_EH_RETURN
:
3683 cfun
->calls_eh_return
= true;
3686 case BUILT_IN_CLEAR_PADDING
:
3687 if (call_expr_nargs (*expr_p
) == 1)
3689 /* Remember the original type of the argument in an internal
3690 dummy second argument, as in GIMPLE pointer conversions are
3691 useless. Also mark this call as not for automatic
3692 initialization in the internal dummy third argument. */
3693 p
= CALL_EXPR_ARG (*expr_p
, 0);
3695 = build_call_expr_loc (EXPR_LOCATION (*expr_p
), fndecl
, 2, p
,
3696 build_zero_cst (TREE_TYPE (p
)));
3704 if (fndecl
&& fndecl_built_in_p (fndecl
))
3706 tree new_tree
= fold_call_expr (input_location
, *expr_p
, !want_value
);
3707 if (new_tree
&& new_tree
!= *expr_p
)
3709 /* There was a transformation of this call which computes the
3710 same value, but in a more efficient way. Return and try
3717 /* Remember the original function pointer type. */
3718 fnptrtype
= TREE_TYPE (CALL_EXPR_FN (*expr_p
));
3723 && (cfun
->curr_properties
& PROP_gimple_any
) == 0)
3725 tree variant
= omp_resolve_declare_variant (fndecl
);
3726 if (variant
!= fndecl
)
3727 CALL_EXPR_FN (*expr_p
) = build1 (ADDR_EXPR
, fnptrtype
, variant
);
3730 /* There is a sequence point before the call, so any side effects in
3731 the calling expression must occur before the actual call. Force
3732 gimplify_expr to use an internal post queue. */
3733 ret
= gimplify_expr (&CALL_EXPR_FN (*expr_p
), pre_p
, NULL
,
3734 is_gimple_call_addr
, fb_rvalue
);
3736 if (ret
== GS_ERROR
)
3739 nargs
= call_expr_nargs (*expr_p
);
3741 /* Get argument types for verification. */
3742 fndecl
= get_callee_fndecl (*expr_p
);
3745 parms
= TYPE_ARG_TYPES (TREE_TYPE (fndecl
));
3747 parms
= TYPE_ARG_TYPES (TREE_TYPE (fnptrtype
));
3749 if (fndecl
&& DECL_ARGUMENTS (fndecl
))
3750 p
= DECL_ARGUMENTS (fndecl
);
3755 for (i
= 0; i
< nargs
&& p
; i
++, p
= TREE_CHAIN (p
))
3758 /* If the last argument is __builtin_va_arg_pack () and it is not
3759 passed as a named argument, decrease the number of CALL_EXPR
3760 arguments and set instead the CALL_EXPR_VA_ARG_PACK flag. */
3763 && TREE_CODE (CALL_EXPR_ARG (*expr_p
, nargs
- 1)) == CALL_EXPR
)
3765 tree last_arg
= CALL_EXPR_ARG (*expr_p
, nargs
- 1);
3766 tree last_arg_fndecl
= get_callee_fndecl (last_arg
);
3769 && fndecl_built_in_p (last_arg_fndecl
, BUILT_IN_VA_ARG_PACK
))
3771 tree call
= *expr_p
;
3774 *expr_p
= build_call_array_loc (loc
, TREE_TYPE (call
),
3775 CALL_EXPR_FN (call
),
3776 nargs
, CALL_EXPR_ARGP (call
));
3778 /* Copy all CALL_EXPR flags, location and block, except
3779 CALL_EXPR_VA_ARG_PACK flag. */
3780 CALL_EXPR_STATIC_CHAIN (*expr_p
) = CALL_EXPR_STATIC_CHAIN (call
);
3781 CALL_EXPR_TAILCALL (*expr_p
) = CALL_EXPR_TAILCALL (call
);
3782 CALL_EXPR_RETURN_SLOT_OPT (*expr_p
)
3783 = CALL_EXPR_RETURN_SLOT_OPT (call
);
3784 CALL_FROM_THUNK_P (*expr_p
) = CALL_FROM_THUNK_P (call
);
3785 SET_EXPR_LOCATION (*expr_p
, EXPR_LOCATION (call
));
3787 /* Set CALL_EXPR_VA_ARG_PACK. */
3788 CALL_EXPR_VA_ARG_PACK (*expr_p
) = 1;
3792 /* If the call returns twice then after building the CFG the call
3793 argument computations will no longer dominate the call because
3794 we add an abnormal incoming edge to the call. So do not use SSA
3796 bool returns_twice
= call_expr_flags (*expr_p
) & ECF_RETURNS_TWICE
;
3798 /* Gimplify the function arguments. */
3801 for (i
= (PUSH_ARGS_REVERSED
? nargs
- 1 : 0);
3802 PUSH_ARGS_REVERSED
? i
>= 0 : i
< nargs
;
3803 PUSH_ARGS_REVERSED
? i
-- : i
++)
3805 enum gimplify_status t
;
3807 /* Avoid gimplifying the second argument to va_start, which needs to
3808 be the plain PARM_DECL. */
3809 if ((i
!= 1) || !builtin_va_start_p
)
3811 t
= gimplify_arg (&CALL_EXPR_ARG (*expr_p
, i
), pre_p
,
3812 EXPR_LOCATION (*expr_p
), ! returns_twice
);
3820 /* Gimplify the static chain. */
3821 if (CALL_EXPR_STATIC_CHAIN (*expr_p
))
3823 if (fndecl
&& !DECL_STATIC_CHAIN (fndecl
))
3824 CALL_EXPR_STATIC_CHAIN (*expr_p
) = NULL
;
3827 enum gimplify_status t
;
3828 t
= gimplify_arg (&CALL_EXPR_STATIC_CHAIN (*expr_p
), pre_p
,
3829 EXPR_LOCATION (*expr_p
), ! returns_twice
);
3835 /* Verify the function result. */
3836 if (want_value
&& fndecl
3837 && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fnptrtype
))))
3839 error_at (loc
, "using result of function returning %<void%>");
3843 /* Try this again in case gimplification exposed something. */
3844 if (ret
!= GS_ERROR
)
3846 tree new_tree
= fold_call_expr (input_location
, *expr_p
, !want_value
);
3848 if (new_tree
&& new_tree
!= *expr_p
)
3850 /* There was a transformation of this call which computes the
3851 same value, but in a more efficient way. Return and try
3859 *expr_p
= error_mark_node
;
3863 /* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its
3864 decl. This allows us to eliminate redundant or useless
3865 calls to "const" functions. */
3866 if (TREE_CODE (*expr_p
) == CALL_EXPR
)
3868 int flags
= call_expr_flags (*expr_p
);
3869 if (flags
& (ECF_CONST
| ECF_PURE
)
3870 /* An infinite loop is considered a side effect. */
3871 && !(flags
& (ECF_LOOPING_CONST_OR_PURE
)))
3872 TREE_SIDE_EFFECTS (*expr_p
) = 0;
3875 /* If the value is not needed by the caller, emit a new GIMPLE_CALL
3876 and clear *EXPR_P. Otherwise, leave *EXPR_P in its gimplified
3877 form and delegate the creation of a GIMPLE_CALL to
3878 gimplify_modify_expr. This is always possible because when
3879 WANT_VALUE is true, the caller wants the result of this call into
3880 a temporary, which means that we will emit an INIT_EXPR in
3881 internal_get_tmp_var which will then be handled by
3882 gimplify_modify_expr. */
3885 /* The CALL_EXPR in *EXPR_P is already in GIMPLE form, so all we
3886 have to do is replicate it as a GIMPLE_CALL tuple. */
3887 gimple_stmt_iterator gsi
;
3888 call
= gimple_build_call_from_tree (*expr_p
, fnptrtype
);
3889 notice_special_calls (call
);
3890 gimplify_seq_add_stmt (pre_p
, call
);
3891 gsi
= gsi_last (*pre_p
);
3892 maybe_fold_stmt (&gsi
);
3893 *expr_p
= NULL_TREE
;
3896 /* Remember the original function type. */
3897 CALL_EXPR_FN (*expr_p
) = build1 (NOP_EXPR
, fnptrtype
,
3898 CALL_EXPR_FN (*expr_p
));
3903 /* Handle shortcut semantics in the predicate operand of a COND_EXPR by
3904 rewriting it into multiple COND_EXPRs, and possibly GOTO_EXPRs.
3906 TRUE_LABEL_P and FALSE_LABEL_P point to the labels to jump to if the
3907 condition is true or false, respectively. If null, we should generate
3908 our own to skip over the evaluation of this specific expression.
3910 LOCUS is the source location of the COND_EXPR.
3912 This function is the tree equivalent of do_jump.
3914 shortcut_cond_r should only be called by shortcut_cond_expr. */
3917 shortcut_cond_r (tree pred
, tree
*true_label_p
, tree
*false_label_p
,
3920 tree local_label
= NULL_TREE
;
3921 tree t
, expr
= NULL
;
3923 /* OK, it's not a simple case; we need to pull apart the COND_EXPR to
3924 retain the shortcut semantics. Just insert the gotos here;
3925 shortcut_cond_expr will append the real blocks later. */
3926 if (TREE_CODE (pred
) == TRUTH_ANDIF_EXPR
)
3928 location_t new_locus
;
3930 /* Turn if (a && b) into
3932 if (a); else goto no;
3933 if (b) goto yes; else goto no;
3936 if (false_label_p
== NULL
)
3937 false_label_p
= &local_label
;
3939 /* Keep the original source location on the first 'if'. */
3940 t
= shortcut_cond_r (TREE_OPERAND (pred
, 0), NULL
, false_label_p
, locus
);
3941 append_to_statement_list (t
, &expr
);
3943 /* Set the source location of the && on the second 'if'. */
3944 new_locus
= rexpr_location (pred
, locus
);
3945 t
= shortcut_cond_r (TREE_OPERAND (pred
, 1), true_label_p
, false_label_p
,
3947 append_to_statement_list (t
, &expr
);
3949 else if (TREE_CODE (pred
) == TRUTH_ORIF_EXPR
)
3951 location_t new_locus
;
3953 /* Turn if (a || b) into
3956 if (b) goto yes; else goto no;
3959 if (true_label_p
== NULL
)
3960 true_label_p
= &local_label
;
3962 /* Keep the original source location on the first 'if'. */
3963 t
= shortcut_cond_r (TREE_OPERAND (pred
, 0), true_label_p
, NULL
, locus
);
3964 append_to_statement_list (t
, &expr
);
3966 /* Set the source location of the || on the second 'if'. */
3967 new_locus
= rexpr_location (pred
, locus
);
3968 t
= shortcut_cond_r (TREE_OPERAND (pred
, 1), true_label_p
, false_label_p
,
3970 append_to_statement_list (t
, &expr
);
3972 else if (TREE_CODE (pred
) == COND_EXPR
3973 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred
, 1)))
3974 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred
, 2))))
3976 location_t new_locus
;
3978 /* As long as we're messing with gotos, turn if (a ? b : c) into
3980 if (b) goto yes; else goto no;
3982 if (c) goto yes; else goto no;
3984 Don't do this if one of the arms has void type, which can happen
3985 in C++ when the arm is throw. */
3987 /* Keep the original source location on the first 'if'. Set the source
3988 location of the ? on the second 'if'. */
3989 new_locus
= rexpr_location (pred
, locus
);
3990 expr
= build3 (COND_EXPR
, void_type_node
, TREE_OPERAND (pred
, 0),
3991 shortcut_cond_r (TREE_OPERAND (pred
, 1), true_label_p
,
3992 false_label_p
, locus
),
3993 shortcut_cond_r (TREE_OPERAND (pred
, 2), true_label_p
,
3994 false_label_p
, new_locus
));
3998 expr
= build3 (COND_EXPR
, void_type_node
, pred
,
3999 build_and_jump (true_label_p
),
4000 build_and_jump (false_label_p
));
4001 SET_EXPR_LOCATION (expr
, locus
);
4006 t
= build1 (LABEL_EXPR
, void_type_node
, local_label
);
4007 append_to_statement_list (t
, &expr
);
4013 /* If EXPR is a GOTO_EXPR, return it. If it is a STATEMENT_LIST, skip
4014 any of its leading DEBUG_BEGIN_STMTS and recurse on the subsequent
4015 statement, if it is the last one. Otherwise, return NULL. */
4018 find_goto (tree expr
)
4023 if (TREE_CODE (expr
) == GOTO_EXPR
)
4026 if (TREE_CODE (expr
) != STATEMENT_LIST
)
4029 tree_stmt_iterator i
= tsi_start (expr
);
4031 while (!tsi_end_p (i
) && TREE_CODE (tsi_stmt (i
)) == DEBUG_BEGIN_STMT
)
4034 if (!tsi_one_before_end_p (i
))
4037 return find_goto (tsi_stmt (i
));
4040 /* Same as find_goto, except that it returns NULL if the destination
4041 is not a LABEL_DECL. */
4044 find_goto_label (tree expr
)
4046 tree dest
= find_goto (expr
);
4047 if (dest
&& TREE_CODE (GOTO_DESTINATION (dest
)) == LABEL_DECL
)
4052 /* Given a conditional expression EXPR with short-circuit boolean
4053 predicates using TRUTH_ANDIF_EXPR or TRUTH_ORIF_EXPR, break the
4054 predicate apart into the equivalent sequence of conditionals. */
4057 shortcut_cond_expr (tree expr
)
4059 tree pred
= TREE_OPERAND (expr
, 0);
4060 tree then_
= TREE_OPERAND (expr
, 1);
4061 tree else_
= TREE_OPERAND (expr
, 2);
4062 tree true_label
, false_label
, end_label
, t
;
4064 tree
*false_label_p
;
4065 bool emit_end
, emit_false
, jump_over_else
;
4066 bool then_se
= then_
&& TREE_SIDE_EFFECTS (then_
);
4067 bool else_se
= else_
&& TREE_SIDE_EFFECTS (else_
);
4069 /* First do simple transformations. */
4072 /* If there is no 'else', turn
4075 if (a) if (b) then c. */
4076 while (TREE_CODE (pred
) == TRUTH_ANDIF_EXPR
)
4078 /* Keep the original source location on the first 'if'. */
4079 location_t locus
= EXPR_LOC_OR_LOC (expr
, input_location
);
4080 TREE_OPERAND (expr
, 0) = TREE_OPERAND (pred
, 1);
4081 /* Set the source location of the && on the second 'if'. */
4082 if (rexpr_has_location (pred
))
4083 SET_EXPR_LOCATION (expr
, rexpr_location (pred
));
4084 then_
= shortcut_cond_expr (expr
);
4085 then_se
= then_
&& TREE_SIDE_EFFECTS (then_
);
4086 pred
= TREE_OPERAND (pred
, 0);
4087 expr
= build3 (COND_EXPR
, void_type_node
, pred
, then_
, NULL_TREE
);
4088 SET_EXPR_LOCATION (expr
, locus
);
4094 /* If there is no 'then', turn
4097 if (a); else if (b); else d. */
4098 while (TREE_CODE (pred
) == TRUTH_ORIF_EXPR
)
4100 /* Keep the original source location on the first 'if'. */
4101 location_t locus
= EXPR_LOC_OR_LOC (expr
, input_location
);
4102 TREE_OPERAND (expr
, 0) = TREE_OPERAND (pred
, 1);
4103 /* Set the source location of the || on the second 'if'. */
4104 if (rexpr_has_location (pred
))
4105 SET_EXPR_LOCATION (expr
, rexpr_location (pred
));
4106 else_
= shortcut_cond_expr (expr
);
4107 else_se
= else_
&& TREE_SIDE_EFFECTS (else_
);
4108 pred
= TREE_OPERAND (pred
, 0);
4109 expr
= build3 (COND_EXPR
, void_type_node
, pred
, NULL_TREE
, else_
);
4110 SET_EXPR_LOCATION (expr
, locus
);
4114 /* If we're done, great. */
4115 if (TREE_CODE (pred
) != TRUTH_ANDIF_EXPR
4116 && TREE_CODE (pred
) != TRUTH_ORIF_EXPR
)
4119 /* Otherwise we need to mess with gotos. Change
4122 if (a); else goto no;
4125 and recursively gimplify the condition. */
4127 true_label
= false_label
= end_label
= NULL_TREE
;
4129 /* If our arms just jump somewhere, hijack those labels so we don't
4130 generate jumps to jumps. */
4132 if (tree then_goto
= find_goto_label (then_
))
4134 true_label
= GOTO_DESTINATION (then_goto
);
4139 if (tree else_goto
= find_goto_label (else_
))
4141 false_label
= GOTO_DESTINATION (else_goto
);
4146 /* If we aren't hijacking a label for the 'then' branch, it falls through. */
4148 true_label_p
= &true_label
;
4150 true_label_p
= NULL
;
4152 /* The 'else' branch also needs a label if it contains interesting code. */
4153 if (false_label
|| else_se
)
4154 false_label_p
= &false_label
;
4156 false_label_p
= NULL
;
4158 /* If there was nothing else in our arms, just forward the label(s). */
4159 if (!then_se
&& !else_se
)
4160 return shortcut_cond_r (pred
, true_label_p
, false_label_p
,
4161 EXPR_LOC_OR_LOC (expr
, input_location
));
4163 /* If our last subexpression already has a terminal label, reuse it. */
4165 t
= expr_last (else_
);
4167 t
= expr_last (then_
);
4170 if (t
&& TREE_CODE (t
) == LABEL_EXPR
)
4171 end_label
= LABEL_EXPR_LABEL (t
);
4173 /* If we don't care about jumping to the 'else' branch, jump to the end
4174 if the condition is false. */
4176 false_label_p
= &end_label
;
4178 /* We only want to emit these labels if we aren't hijacking them. */
4179 emit_end
= (end_label
== NULL_TREE
);
4180 emit_false
= (false_label
== NULL_TREE
);
4182 /* We only emit the jump over the else clause if we have to--if the
4183 then clause may fall through. Otherwise we can wind up with a
4184 useless jump and a useless label at the end of gimplified code,
4185 which will cause us to think that this conditional as a whole
4186 falls through even if it doesn't. If we then inline a function
4187 which ends with such a condition, that can cause us to issue an
4188 inappropriate warning about control reaching the end of a
4189 non-void function. */
4190 jump_over_else
= block_may_fallthru (then_
);
4192 pred
= shortcut_cond_r (pred
, true_label_p
, false_label_p
,
4193 EXPR_LOC_OR_LOC (expr
, input_location
));
4196 append_to_statement_list (pred
, &expr
);
4198 append_to_statement_list (then_
, &expr
);
4203 tree last
= expr_last (expr
);
4204 t
= build_and_jump (&end_label
);
4205 if (rexpr_has_location (last
))
4206 SET_EXPR_LOCATION (t
, rexpr_location (last
));
4207 append_to_statement_list (t
, &expr
);
4211 t
= build1 (LABEL_EXPR
, void_type_node
, false_label
);
4212 append_to_statement_list (t
, &expr
);
4214 append_to_statement_list (else_
, &expr
);
4216 if (emit_end
&& end_label
)
4218 t
= build1 (LABEL_EXPR
, void_type_node
, end_label
);
4219 append_to_statement_list (t
, &expr
);
4225 /* EXPR is used in a boolean context; make sure it has BOOLEAN_TYPE. */
4228 gimple_boolify (tree expr
)
4230 tree type
= TREE_TYPE (expr
);
4231 location_t loc
= EXPR_LOCATION (expr
);
4233 if (TREE_CODE (expr
) == NE_EXPR
4234 && TREE_CODE (TREE_OPERAND (expr
, 0)) == CALL_EXPR
4235 && integer_zerop (TREE_OPERAND (expr
, 1)))
4237 tree call
= TREE_OPERAND (expr
, 0);
4238 tree fn
= get_callee_fndecl (call
);
4240 /* For __builtin_expect ((long) (x), y) recurse into x as well
4241 if x is truth_value_p. */
4243 && fndecl_built_in_p (fn
, BUILT_IN_EXPECT
)
4244 && call_expr_nargs (call
) == 2)
4246 tree arg
= CALL_EXPR_ARG (call
, 0);
4249 if (TREE_CODE (arg
) == NOP_EXPR
4250 && TREE_TYPE (arg
) == TREE_TYPE (call
))
4251 arg
= TREE_OPERAND (arg
, 0);
4252 if (truth_value_p (TREE_CODE (arg
)))
4254 arg
= gimple_boolify (arg
);
4255 CALL_EXPR_ARG (call
, 0)
4256 = fold_convert_loc (loc
, TREE_TYPE (call
), arg
);
4262 switch (TREE_CODE (expr
))
4264 case TRUTH_AND_EXPR
:
4266 case TRUTH_XOR_EXPR
:
4267 case TRUTH_ANDIF_EXPR
:
4268 case TRUTH_ORIF_EXPR
:
4269 /* Also boolify the arguments of truth exprs. */
4270 TREE_OPERAND (expr
, 1) = gimple_boolify (TREE_OPERAND (expr
, 1));
4273 case TRUTH_NOT_EXPR
:
4274 TREE_OPERAND (expr
, 0) = gimple_boolify (TREE_OPERAND (expr
, 0));
4276 /* These expressions always produce boolean results. */
4277 if (TREE_CODE (type
) != BOOLEAN_TYPE
)
4278 TREE_TYPE (expr
) = boolean_type_node
;
4282 switch ((enum annot_expr_kind
) TREE_INT_CST_LOW (TREE_OPERAND (expr
, 1)))
4284 case annot_expr_ivdep_kind
:
4285 case annot_expr_unroll_kind
:
4286 case annot_expr_no_vector_kind
:
4287 case annot_expr_vector_kind
:
4288 case annot_expr_parallel_kind
:
4289 TREE_OPERAND (expr
, 0) = gimple_boolify (TREE_OPERAND (expr
, 0));
4290 if (TREE_CODE (type
) != BOOLEAN_TYPE
)
4291 TREE_TYPE (expr
) = boolean_type_node
;
4298 if (COMPARISON_CLASS_P (expr
))
4300 /* These expressions always produce boolean results. */
4301 if (TREE_CODE (type
) != BOOLEAN_TYPE
)
4302 TREE_TYPE (expr
) = boolean_type_node
;
4305 /* Other expressions that get here must have boolean values, but
4306 might need to be converted to the appropriate mode. */
4307 if (TREE_CODE (type
) == BOOLEAN_TYPE
)
4309 return fold_convert_loc (loc
, boolean_type_node
, expr
);
4313 /* Given a conditional expression *EXPR_P without side effects, gimplify
4314 its operands. New statements are inserted to PRE_P. */
4316 static enum gimplify_status
4317 gimplify_pure_cond_expr (tree
*expr_p
, gimple_seq
*pre_p
)
4319 tree expr
= *expr_p
, cond
;
4320 enum gimplify_status ret
, tret
;
4321 enum tree_code code
;
4323 cond
= gimple_boolify (COND_EXPR_COND (expr
));
4325 /* We need to handle && and || specially, as their gimplification
4326 creates pure cond_expr, thus leading to an infinite cycle otherwise. */
4327 code
= TREE_CODE (cond
);
4328 if (code
== TRUTH_ANDIF_EXPR
)
4329 TREE_SET_CODE (cond
, TRUTH_AND_EXPR
);
4330 else if (code
== TRUTH_ORIF_EXPR
)
4331 TREE_SET_CODE (cond
, TRUTH_OR_EXPR
);
4332 ret
= gimplify_expr (&cond
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
4333 COND_EXPR_COND (*expr_p
) = cond
;
4335 tret
= gimplify_expr (&COND_EXPR_THEN (expr
), pre_p
, NULL
,
4336 is_gimple_val
, fb_rvalue
);
4337 ret
= MIN (ret
, tret
);
4338 tret
= gimplify_expr (&COND_EXPR_ELSE (expr
), pre_p
, NULL
,
4339 is_gimple_val
, fb_rvalue
);
4341 return MIN (ret
, tret
);
4344 /* Return true if evaluating EXPR could trap.
4345 EXPR is GENERIC, while tree_could_trap_p can be called
4349 generic_expr_could_trap_p (tree expr
)
4353 if (!expr
|| is_gimple_val (expr
))
4356 if (!EXPR_P (expr
) || tree_could_trap_p (expr
))
4359 n
= TREE_OPERAND_LENGTH (expr
);
4360 for (i
= 0; i
< n
; i
++)
4361 if (generic_expr_could_trap_p (TREE_OPERAND (expr
, i
)))
4367 /* Convert the conditional expression pointed to by EXPR_P '(p) ? a : b;'
4376 The second form is used when *EXPR_P is of type void.
4378 PRE_P points to the list where side effects that must happen before
4379 *EXPR_P should be stored. */
4381 static enum gimplify_status
4382 gimplify_cond_expr (tree
*expr_p
, gimple_seq
*pre_p
, fallback_t fallback
)
4384 tree expr
= *expr_p
;
4385 tree type
= TREE_TYPE (expr
);
4386 location_t loc
= EXPR_LOCATION (expr
);
4387 tree tmp
, arm1
, arm2
;
4388 enum gimplify_status ret
;
4389 tree label_true
, label_false
, label_cont
;
4390 bool have_then_clause_p
, have_else_clause_p
;
4392 enum tree_code pred_code
;
4393 gimple_seq seq
= NULL
;
4395 /* If this COND_EXPR has a value, copy the values into a temporary within
4397 if (!VOID_TYPE_P (type
))
4399 tree then_
= TREE_OPERAND (expr
, 1), else_
= TREE_OPERAND (expr
, 2);
4402 /* If either an rvalue is ok or we do not require an lvalue, create the
4403 temporary. But we cannot do that if the type is addressable. */
4404 if (((fallback
& fb_rvalue
) || !(fallback
& fb_lvalue
))
4405 && !TREE_ADDRESSABLE (type
))
4407 if (gimplify_ctxp
->allow_rhs_cond_expr
4408 /* If either branch has side effects or could trap, it can't be
4409 evaluated unconditionally. */
4410 && !TREE_SIDE_EFFECTS (then_
)
4411 && !generic_expr_could_trap_p (then_
)
4412 && !TREE_SIDE_EFFECTS (else_
)
4413 && !generic_expr_could_trap_p (else_
))
4414 return gimplify_pure_cond_expr (expr_p
, pre_p
);
4416 tmp
= create_tmp_var (type
, "iftmp");
4420 /* Otherwise, only create and copy references to the values. */
4423 type
= build_pointer_type (type
);
4425 if (!VOID_TYPE_P (TREE_TYPE (then_
)))
4426 then_
= build_fold_addr_expr_loc (loc
, then_
);
4428 if (!VOID_TYPE_P (TREE_TYPE (else_
)))
4429 else_
= build_fold_addr_expr_loc (loc
, else_
);
4432 = build3 (COND_EXPR
, type
, TREE_OPERAND (expr
, 0), then_
, else_
);
4434 tmp
= create_tmp_var (type
, "iftmp");
4435 result
= build_simple_mem_ref_loc (loc
, tmp
);
4438 /* Build the new then clause, `tmp = then_;'. But don't build the
4439 assignment if the value is void; in C++ it can be if it's a throw. */
4440 if (!VOID_TYPE_P (TREE_TYPE (then_
)))
4441 TREE_OPERAND (expr
, 1) = build2 (INIT_EXPR
, type
, tmp
, then_
);
4443 /* Similarly, build the new else clause, `tmp = else_;'. */
4444 if (!VOID_TYPE_P (TREE_TYPE (else_
)))
4445 TREE_OPERAND (expr
, 2) = build2 (INIT_EXPR
, type
, tmp
, else_
);
4447 TREE_TYPE (expr
) = void_type_node
;
4448 recalculate_side_effects (expr
);
4450 /* Move the COND_EXPR to the prequeue. */
4451 gimplify_stmt (&expr
, pre_p
);
4457 /* Remove any COMPOUND_EXPR so the following cases will be caught. */
4458 STRIP_TYPE_NOPS (TREE_OPERAND (expr
, 0));
4459 if (TREE_CODE (TREE_OPERAND (expr
, 0)) == COMPOUND_EXPR
)
4460 gimplify_compound_expr (&TREE_OPERAND (expr
, 0), pre_p
, true);
4462 /* Make sure the condition has BOOLEAN_TYPE. */
4463 TREE_OPERAND (expr
, 0) = gimple_boolify (TREE_OPERAND (expr
, 0));
4465 /* Break apart && and || conditions. */
4466 if (TREE_CODE (TREE_OPERAND (expr
, 0)) == TRUTH_ANDIF_EXPR
4467 || TREE_CODE (TREE_OPERAND (expr
, 0)) == TRUTH_ORIF_EXPR
)
4469 expr
= shortcut_cond_expr (expr
);
4471 if (expr
!= *expr_p
)
4475 /* We can't rely on gimplify_expr to re-gimplify the expanded
4476 form properly, as cleanups might cause the target labels to be
4477 wrapped in a TRY_FINALLY_EXPR. To prevent that, we need to
4478 set up a conditional context. */
4479 gimple_push_condition ();
4480 gimplify_stmt (expr_p
, &seq
);
4481 gimple_pop_condition (pre_p
);
4482 gimple_seq_add_seq (pre_p
, seq
);
4488 /* Now do the normal gimplification. */
4490 /* Gimplify condition. */
4491 ret
= gimplify_expr (&TREE_OPERAND (expr
, 0), pre_p
, NULL
,
4492 is_gimple_condexpr_for_cond
, fb_rvalue
);
4493 if (ret
== GS_ERROR
)
4495 gcc_assert (TREE_OPERAND (expr
, 0) != NULL_TREE
);
4497 gimple_push_condition ();
4499 have_then_clause_p
= have_else_clause_p
= false;
4500 label_true
= find_goto_label (TREE_OPERAND (expr
, 1));
4502 && DECL_CONTEXT (GOTO_DESTINATION (label_true
)) == current_function_decl
4503 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4504 have different locations, otherwise we end up with incorrect
4505 location information on the branches. */
4507 || !EXPR_HAS_LOCATION (expr
)
4508 || !rexpr_has_location (label_true
)
4509 || EXPR_LOCATION (expr
) == rexpr_location (label_true
)))
4511 have_then_clause_p
= true;
4512 label_true
= GOTO_DESTINATION (label_true
);
4515 label_true
= create_artificial_label (UNKNOWN_LOCATION
);
4516 label_false
= find_goto_label (TREE_OPERAND (expr
, 2));
4518 && DECL_CONTEXT (GOTO_DESTINATION (label_false
)) == current_function_decl
4519 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4520 have different locations, otherwise we end up with incorrect
4521 location information on the branches. */
4523 || !EXPR_HAS_LOCATION (expr
)
4524 || !rexpr_has_location (label_false
)
4525 || EXPR_LOCATION (expr
) == rexpr_location (label_false
)))
4527 have_else_clause_p
= true;
4528 label_false
= GOTO_DESTINATION (label_false
);
4531 label_false
= create_artificial_label (UNKNOWN_LOCATION
);
4533 gimple_cond_get_ops_from_tree (COND_EXPR_COND (expr
), &pred_code
, &arm1
,
4535 cond_stmt
= gimple_build_cond (pred_code
, arm1
, arm2
, label_true
,
4537 gimple_set_location (cond_stmt
, EXPR_LOCATION (expr
));
4538 copy_warning (cond_stmt
, COND_EXPR_COND (expr
));
4539 gimplify_seq_add_stmt (&seq
, cond_stmt
);
4540 gimple_stmt_iterator gsi
= gsi_last (seq
);
4541 maybe_fold_stmt (&gsi
);
4543 label_cont
= NULL_TREE
;
4544 if (!have_then_clause_p
)
4546 /* For if (...) {} else { code; } put label_true after
4548 if (TREE_OPERAND (expr
, 1) == NULL_TREE
4549 && !have_else_clause_p
4550 && TREE_OPERAND (expr
, 2) != NULL_TREE
)
4552 /* For if (0) {} else { code; } tell -Wimplicit-fallthrough
4553 handling that label_cont == label_true can be only reached
4554 through fallthrough from { code; }. */
4555 if (integer_zerop (COND_EXPR_COND (expr
)))
4556 UNUSED_LABEL_P (label_true
) = 1;
4557 label_cont
= label_true
;
4561 bool then_side_effects
4562 = (TREE_OPERAND (expr
, 1)
4563 && TREE_SIDE_EFFECTS (TREE_OPERAND (expr
, 1)));
4564 gimplify_seq_add_stmt (&seq
, gimple_build_label (label_true
));
4565 have_then_clause_p
= gimplify_stmt (&TREE_OPERAND (expr
, 1), &seq
);
4566 /* For if (...) { code; } else {} or
4567 if (...) { code; } else goto label; or
4568 if (...) { code; return; } else { ... }
4569 label_cont isn't needed. */
4570 if (!have_else_clause_p
4571 && TREE_OPERAND (expr
, 2) != NULL_TREE
4572 && gimple_seq_may_fallthru (seq
))
4575 label_cont
= create_artificial_label (UNKNOWN_LOCATION
);
4577 /* For if (0) { non-side-effect-code } else { code }
4578 tell -Wimplicit-fallthrough handling that label_cont can
4579 be only reached through fallthrough from { code }. */
4580 if (integer_zerop (COND_EXPR_COND (expr
)))
4582 UNUSED_LABEL_P (label_true
) = 1;
4583 if (!then_side_effects
)
4584 UNUSED_LABEL_P (label_cont
) = 1;
4587 g
= gimple_build_goto (label_cont
);
4589 /* GIMPLE_COND's are very low level; they have embedded
4590 gotos. This particular embedded goto should not be marked
4591 with the location of the original COND_EXPR, as it would
4592 correspond to the COND_EXPR's condition, not the ELSE or the
4593 THEN arms. To avoid marking it with the wrong location, flag
4594 it as "no location". */
4595 gimple_set_do_not_emit_location (g
);
4597 gimplify_seq_add_stmt (&seq
, g
);
4601 if (!have_else_clause_p
)
4603 /* For if (1) { code } or if (1) { code } else { non-side-effect-code }
4604 tell -Wimplicit-fallthrough handling that label_false can be only
4605 reached through fallthrough from { code }. */
4606 if (integer_nonzerop (COND_EXPR_COND (expr
))
4607 && (TREE_OPERAND (expr
, 2) == NULL_TREE
4608 || !TREE_SIDE_EFFECTS (TREE_OPERAND (expr
, 2))))
4609 UNUSED_LABEL_P (label_false
) = 1;
4610 gimplify_seq_add_stmt (&seq
, gimple_build_label (label_false
));
4611 have_else_clause_p
= gimplify_stmt (&TREE_OPERAND (expr
, 2), &seq
);
4614 gimplify_seq_add_stmt (&seq
, gimple_build_label (label_cont
));
4616 gimple_pop_condition (pre_p
);
4617 gimple_seq_add_seq (pre_p
, seq
);
4619 if (ret
== GS_ERROR
)
4621 else if (have_then_clause_p
|| have_else_clause_p
)
4625 /* Both arms are empty; replace the COND_EXPR with its predicate. */
4626 expr
= TREE_OPERAND (expr
, 0);
4627 gimplify_stmt (&expr
, pre_p
);
4634 /* Prepare the node pointed to by EXPR_P, an is_gimple_addressable expression,
4635 to be marked addressable.
4637 We cannot rely on such an expression being directly markable if a temporary
4638 has been created by the gimplification. In this case, we create another
4639 temporary and initialize it with a copy, which will become a store after we
4640 mark it addressable. This can happen if the front-end passed us something
4641 that it could not mark addressable yet, like a Fortran pass-by-reference
4642 parameter (int) floatvar. */
4645 prepare_gimple_addressable (tree
*expr_p
, gimple_seq
*seq_p
)
4647 while (handled_component_p (*expr_p
))
4648 expr_p
= &TREE_OPERAND (*expr_p
, 0);
4650 /* Do not allow an SSA name as the temporary. */
4651 if (is_gimple_reg (*expr_p
))
4652 *expr_p
= internal_get_tmp_var (*expr_p
, seq_p
, NULL
, false, false, true);
4655 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4656 a call to __builtin_memcpy. */
4658 static enum gimplify_status
4659 gimplify_modify_expr_to_memcpy (tree
*expr_p
, tree size
, bool want_value
,
4662 tree t
, to
, to_ptr
, from
, from_ptr
;
4664 location_t loc
= EXPR_LOCATION (*expr_p
);
4666 to
= TREE_OPERAND (*expr_p
, 0);
4667 from
= TREE_OPERAND (*expr_p
, 1);
4669 /* Mark the RHS addressable. Beware that it may not be possible to do so
4670 directly if a temporary has been created by the gimplification. */
4671 prepare_gimple_addressable (&from
, seq_p
);
4673 mark_addressable (from
);
4674 from_ptr
= build_fold_addr_expr_loc (loc
, from
);
4675 gimplify_arg (&from_ptr
, seq_p
, loc
);
4677 mark_addressable (to
);
4678 to_ptr
= build_fold_addr_expr_loc (loc
, to
);
4679 gimplify_arg (&to_ptr
, seq_p
, loc
);
4681 t
= builtin_decl_implicit (BUILT_IN_MEMCPY
);
4683 gs
= gimple_build_call (t
, 3, to_ptr
, from_ptr
, size
);
4684 gimple_call_set_alloca_for_var (gs
, true);
4688 /* tmp = memcpy() */
4689 t
= create_tmp_var (TREE_TYPE (to_ptr
));
4690 gimple_call_set_lhs (gs
, t
);
4691 gimplify_seq_add_stmt (seq_p
, gs
);
4693 *expr_p
= build_simple_mem_ref (t
);
4697 gimplify_seq_add_stmt (seq_p
, gs
);
4702 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4703 a call to __builtin_memset. In this case we know that the RHS is
4704 a CONSTRUCTOR with an empty element list. */
4706 static enum gimplify_status
4707 gimplify_modify_expr_to_memset (tree
*expr_p
, tree size
, bool want_value
,
4710 tree t
, from
, to
, to_ptr
;
4712 location_t loc
= EXPR_LOCATION (*expr_p
);
4714 /* Assert our assumptions, to abort instead of producing wrong code
4715 silently if they are not met. Beware that the RHS CONSTRUCTOR might
4716 not be immediately exposed. */
4717 from
= TREE_OPERAND (*expr_p
, 1);
4718 if (TREE_CODE (from
) == WITH_SIZE_EXPR
)
4719 from
= TREE_OPERAND (from
, 0);
4721 gcc_assert (TREE_CODE (from
) == CONSTRUCTOR
4722 && vec_safe_is_empty (CONSTRUCTOR_ELTS (from
)));
4725 to
= TREE_OPERAND (*expr_p
, 0);
4727 to_ptr
= build_fold_addr_expr_loc (loc
, to
);
4728 gimplify_arg (&to_ptr
, seq_p
, loc
);
4729 t
= builtin_decl_implicit (BUILT_IN_MEMSET
);
4731 gs
= gimple_build_call (t
, 3, to_ptr
, integer_zero_node
, size
);
4735 /* tmp = memset() */
4736 t
= create_tmp_var (TREE_TYPE (to_ptr
));
4737 gimple_call_set_lhs (gs
, t
);
4738 gimplify_seq_add_stmt (seq_p
, gs
);
4740 *expr_p
= build1 (INDIRECT_REF
, TREE_TYPE (to
), t
);
4744 gimplify_seq_add_stmt (seq_p
, gs
);
4749 /* A subroutine of gimplify_init_ctor_preeval. Called via walk_tree,
4750 determine, cautiously, if a CONSTRUCTOR overlaps the lhs of an
4751 assignment. Return non-null if we detect a potential overlap. */
4753 struct gimplify_init_ctor_preeval_data
4755 /* The base decl of the lhs object. May be NULL, in which case we
4756 have to assume the lhs is indirect. */
4759 /* The alias set of the lhs object. */
4760 alias_set_type lhs_alias_set
;
4764 gimplify_init_ctor_preeval_1 (tree
*tp
, int *walk_subtrees
, void *xdata
)
4766 struct gimplify_init_ctor_preeval_data
*data
4767 = (struct gimplify_init_ctor_preeval_data
*) xdata
;
4770 /* If we find the base object, obviously we have overlap. */
4771 if (data
->lhs_base_decl
== t
)
4774 /* If the constructor component is indirect, determine if we have a
4775 potential overlap with the lhs. The only bits of information we
4776 have to go on at this point are addressability and alias sets. */
4777 if ((INDIRECT_REF_P (t
)
4778 || TREE_CODE (t
) == MEM_REF
)
4779 && (!data
->lhs_base_decl
|| TREE_ADDRESSABLE (data
->lhs_base_decl
))
4780 && alias_sets_conflict_p (data
->lhs_alias_set
, get_alias_set (t
)))
4783 /* If the constructor component is a call, determine if it can hide a
4784 potential overlap with the lhs through an INDIRECT_REF like above.
4785 ??? Ugh - this is completely broken. In fact this whole analysis
4786 doesn't look conservative. */
4787 if (TREE_CODE (t
) == CALL_EXPR
)
4789 tree type
, fntype
= TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (t
)));
4791 for (type
= TYPE_ARG_TYPES (fntype
); type
; type
= TREE_CHAIN (type
))
4792 if (POINTER_TYPE_P (TREE_VALUE (type
))
4793 && (!data
->lhs_base_decl
|| TREE_ADDRESSABLE (data
->lhs_base_decl
))
4794 && alias_sets_conflict_p (data
->lhs_alias_set
,
4796 (TREE_TYPE (TREE_VALUE (type
)))))
4800 if (IS_TYPE_OR_DECL_P (t
))
4805 /* A subroutine of gimplify_init_constructor. Pre-evaluate EXPR,
4806 force values that overlap with the lhs (as described by *DATA)
4807 into temporaries. */
4810 gimplify_init_ctor_preeval (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
4811 struct gimplify_init_ctor_preeval_data
*data
)
4813 enum gimplify_status one
;
4815 /* If the value is constant, then there's nothing to pre-evaluate. */
4816 if (TREE_CONSTANT (*expr_p
))
4818 /* Ensure it does not have side effects, it might contain a reference to
4819 the object we're initializing. */
4820 gcc_assert (!TREE_SIDE_EFFECTS (*expr_p
));
4824 /* If the type has non-trivial constructors, we can't pre-evaluate. */
4825 if (TREE_ADDRESSABLE (TREE_TYPE (*expr_p
)))
4828 /* Recurse for nested constructors. */
4829 if (TREE_CODE (*expr_p
) == CONSTRUCTOR
)
4831 unsigned HOST_WIDE_INT ix
;
4832 constructor_elt
*ce
;
4833 vec
<constructor_elt
, va_gc
> *v
= CONSTRUCTOR_ELTS (*expr_p
);
4835 FOR_EACH_VEC_SAFE_ELT (v
, ix
, ce
)
4836 gimplify_init_ctor_preeval (&ce
->value
, pre_p
, post_p
, data
);
4841 /* If this is a variable sized type, we must remember the size. */
4842 maybe_with_size_expr (expr_p
);
4844 /* Gimplify the constructor element to something appropriate for the rhs
4845 of a MODIFY_EXPR. Given that we know the LHS is an aggregate, we know
4846 the gimplifier will consider this a store to memory. Doing this
4847 gimplification now means that we won't have to deal with complicated
4848 language-specific trees, nor trees like SAVE_EXPR that can induce
4849 exponential search behavior. */
4850 one
= gimplify_expr (expr_p
, pre_p
, post_p
, is_gimple_mem_rhs
, fb_rvalue
);
4851 if (one
== GS_ERROR
)
4857 /* If we gimplified to a bare decl, we can be sure that it doesn't overlap
4858 with the lhs, since "a = { .x=a }" doesn't make sense. This will
4859 always be true for all scalars, since is_gimple_mem_rhs insists on a
4860 temporary variable for them. */
4861 if (DECL_P (*expr_p
))
4864 /* If this is of variable size, we have no choice but to assume it doesn't
4865 overlap since we can't make a temporary for it. */
4866 if (TREE_CODE (TYPE_SIZE (TREE_TYPE (*expr_p
))) != INTEGER_CST
)
4869 /* Otherwise, we must search for overlap ... */
4870 if (!walk_tree (expr_p
, gimplify_init_ctor_preeval_1
, data
, NULL
))
4873 /* ... and if found, force the value into a temporary. */
4874 *expr_p
= get_formal_tmp_var (*expr_p
, pre_p
);
4877 /* A subroutine of gimplify_init_ctor_eval. Create a loop for
4878 a RANGE_EXPR in a CONSTRUCTOR for an array.
4882 object[var] = value;
4889 We increment var _after_ the loop exit check because we might otherwise
4890 fail if upper == TYPE_MAX_VALUE (type for upper).
4892 Note that we never have to deal with SAVE_EXPRs here, because this has
4893 already been taken care of for us, in gimplify_init_ctor_preeval(). */
4895 static void gimplify_init_ctor_eval (tree
, vec
<constructor_elt
, va_gc
> *,
4896 gimple_seq
*, bool);
4899 gimplify_init_ctor_eval_range (tree object
, tree lower
, tree upper
,
4900 tree value
, tree array_elt_type
,
4901 gimple_seq
*pre_p
, bool cleared
)
4903 tree loop_entry_label
, loop_exit_label
, fall_thru_label
;
4904 tree var
, var_type
, cref
, tmp
;
4906 loop_entry_label
= create_artificial_label (UNKNOWN_LOCATION
);
4907 loop_exit_label
= create_artificial_label (UNKNOWN_LOCATION
);
4908 fall_thru_label
= create_artificial_label (UNKNOWN_LOCATION
);
4910 /* Create and initialize the index variable. */
4911 var_type
= TREE_TYPE (upper
);
4912 var
= create_tmp_var (var_type
);
4913 gimplify_seq_add_stmt (pre_p
, gimple_build_assign (var
, lower
));
4915 /* Add the loop entry label. */
4916 gimplify_seq_add_stmt (pre_p
, gimple_build_label (loop_entry_label
));
4918 /* Build the reference. */
4919 cref
= build4 (ARRAY_REF
, array_elt_type
, unshare_expr (object
),
4920 var
, NULL_TREE
, NULL_TREE
);
4922 /* If we are a constructor, just call gimplify_init_ctor_eval to do
4923 the store. Otherwise just assign value to the reference. */
4925 if (TREE_CODE (value
) == CONSTRUCTOR
)
4926 /* NB we might have to call ourself recursively through
4927 gimplify_init_ctor_eval if the value is a constructor. */
4928 gimplify_init_ctor_eval (cref
, CONSTRUCTOR_ELTS (value
),
4932 if (gimplify_expr (&value
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
)
4934 gimplify_seq_add_stmt (pre_p
, gimple_build_assign (cref
, value
));
4937 /* We exit the loop when the index var is equal to the upper bound. */
4938 gimplify_seq_add_stmt (pre_p
,
4939 gimple_build_cond (EQ_EXPR
, var
, upper
,
4940 loop_exit_label
, fall_thru_label
));
4942 gimplify_seq_add_stmt (pre_p
, gimple_build_label (fall_thru_label
));
4944 /* Otherwise, increment the index var... */
4945 tmp
= build2 (PLUS_EXPR
, var_type
, var
,
4946 fold_convert (var_type
, integer_one_node
));
4947 gimplify_seq_add_stmt (pre_p
, gimple_build_assign (var
, tmp
));
4949 /* ...and jump back to the loop entry. */
4950 gimplify_seq_add_stmt (pre_p
, gimple_build_goto (loop_entry_label
));
4952 /* Add the loop exit label. */
4953 gimplify_seq_add_stmt (pre_p
, gimple_build_label (loop_exit_label
));
4956 /* A subroutine of gimplify_init_constructor. Generate individual
4957 MODIFY_EXPRs for a CONSTRUCTOR. OBJECT is the LHS against which the
4958 assignments should happen. ELTS is the CONSTRUCTOR_ELTS of the
4959 CONSTRUCTOR. CLEARED is true if the entire LHS object has been
4963 gimplify_init_ctor_eval (tree object
, vec
<constructor_elt
, va_gc
> *elts
,
4964 gimple_seq
*pre_p
, bool cleared
)
4966 tree array_elt_type
= NULL
;
4967 unsigned HOST_WIDE_INT ix
;
4968 tree purpose
, value
;
4970 if (TREE_CODE (TREE_TYPE (object
)) == ARRAY_TYPE
)
4971 array_elt_type
= TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (object
)));
4973 FOR_EACH_CONSTRUCTOR_ELT (elts
, ix
, purpose
, value
)
4977 /* NULL values are created above for gimplification errors. */
4981 if (cleared
&& initializer_zerop (value
))
4984 /* ??? Here's to hoping the front end fills in all of the indices,
4985 so we don't have to figure out what's missing ourselves. */
4986 gcc_assert (purpose
);
4988 /* Skip zero-sized fields, unless value has side-effects. This can
4989 happen with calls to functions returning a empty type, which
4990 we shouldn't discard. As a number of downstream passes don't
4991 expect sets of empty type fields, we rely on the gimplification of
4992 the MODIFY_EXPR we make below to drop the assignment statement. */
4993 if (!TREE_SIDE_EFFECTS (value
)
4994 && TREE_CODE (purpose
) == FIELD_DECL
4995 && is_empty_type (TREE_TYPE (purpose
)))
4998 /* If we have a RANGE_EXPR, we have to build a loop to assign the
5000 if (TREE_CODE (purpose
) == RANGE_EXPR
)
5002 tree lower
= TREE_OPERAND (purpose
, 0);
5003 tree upper
= TREE_OPERAND (purpose
, 1);
5005 /* If the lower bound is equal to upper, just treat it as if
5006 upper was the index. */
5007 if (simple_cst_equal (lower
, upper
))
5011 gimplify_init_ctor_eval_range (object
, lower
, upper
, value
,
5012 array_elt_type
, pre_p
, cleared
);
5019 /* Do not use bitsizetype for ARRAY_REF indices. */
5020 if (TYPE_DOMAIN (TREE_TYPE (object
)))
5022 = fold_convert (TREE_TYPE (TYPE_DOMAIN (TREE_TYPE (object
))),
5024 cref
= build4 (ARRAY_REF
, array_elt_type
, unshare_expr (object
),
5025 purpose
, NULL_TREE
, NULL_TREE
);
5029 gcc_assert (TREE_CODE (purpose
) == FIELD_DECL
);
5030 cref
= build3 (COMPONENT_REF
, TREE_TYPE (purpose
),
5031 unshare_expr (object
), purpose
, NULL_TREE
);
5034 if (TREE_CODE (value
) == CONSTRUCTOR
5035 && TREE_CODE (TREE_TYPE (value
)) != VECTOR_TYPE
)
5036 gimplify_init_ctor_eval (cref
, CONSTRUCTOR_ELTS (value
),
5040 tree init
= build2 (INIT_EXPR
, TREE_TYPE (cref
), cref
, value
);
5041 gimplify_and_add (init
, pre_p
);
5047 /* Return the appropriate RHS predicate for this LHS. */
5050 rhs_predicate_for (tree lhs
)
5052 if (is_gimple_reg (lhs
))
5053 return is_gimple_reg_rhs_or_call
;
5055 return is_gimple_mem_rhs_or_call
;
5058 /* Return the initial guess for an appropriate RHS predicate for this LHS,
5059 before the LHS has been gimplified. */
5061 static gimple_predicate
5062 initial_rhs_predicate_for (tree lhs
)
5064 if (is_gimple_reg_type (TREE_TYPE (lhs
)))
5065 return is_gimple_reg_rhs_or_call
;
5067 return is_gimple_mem_rhs_or_call
;
5070 /* Gimplify a C99 compound literal expression. This just means adding
5071 the DECL_EXPR before the current statement and using its anonymous
5074 static enum gimplify_status
5075 gimplify_compound_literal_expr (tree
*expr_p
, gimple_seq
*pre_p
,
5076 bool (*gimple_test_f
) (tree
),
5077 fallback_t fallback
)
5079 tree decl_s
= COMPOUND_LITERAL_EXPR_DECL_EXPR (*expr_p
);
5080 tree decl
= DECL_EXPR_DECL (decl_s
);
5081 tree init
= DECL_INITIAL (decl
);
5082 /* Mark the decl as addressable if the compound literal
5083 expression is addressable now, otherwise it is marked too late
5084 after we gimplify the initialization expression. */
5085 if (TREE_ADDRESSABLE (*expr_p
))
5086 TREE_ADDRESSABLE (decl
) = 1;
5087 /* Otherwise, if we don't need an lvalue and have a literal directly
5088 substitute it. Check if it matches the gimple predicate, as
5089 otherwise we'd generate a new temporary, and we can as well just
5090 use the decl we already have. */
5091 else if (!TREE_ADDRESSABLE (decl
)
5092 && !TREE_THIS_VOLATILE (decl
)
5094 && (fallback
& fb_lvalue
) == 0
5095 && gimple_test_f (init
))
5101 /* If the decl is not addressable, then it is being used in some
5102 expression or on the right hand side of a statement, and it can
5103 be put into a readonly data section. */
5104 if (!TREE_ADDRESSABLE (decl
) && (fallback
& fb_lvalue
) == 0)
5105 TREE_READONLY (decl
) = 1;
5107 /* This decl isn't mentioned in the enclosing block, so add it to the
5108 list of temps. FIXME it seems a bit of a kludge to say that
5109 anonymous artificial vars aren't pushed, but everything else is. */
5110 if (DECL_NAME (decl
) == NULL_TREE
&& !DECL_SEEN_IN_BIND_EXPR_P (decl
))
5111 gimple_add_tmp_var (decl
);
5113 gimplify_and_add (decl_s
, pre_p
);
5118 /* Optimize embedded COMPOUND_LITERAL_EXPRs within a CONSTRUCTOR,
5119 return a new CONSTRUCTOR if something changed. */
5122 optimize_compound_literals_in_ctor (tree orig_ctor
)
5124 tree ctor
= orig_ctor
;
5125 vec
<constructor_elt
, va_gc
> *elts
= CONSTRUCTOR_ELTS (ctor
);
5126 unsigned int idx
, num
= vec_safe_length (elts
);
5128 for (idx
= 0; idx
< num
; idx
++)
5130 tree value
= (*elts
)[idx
].value
;
5131 tree newval
= value
;
5132 if (TREE_CODE (value
) == CONSTRUCTOR
)
5133 newval
= optimize_compound_literals_in_ctor (value
);
5134 else if (TREE_CODE (value
) == COMPOUND_LITERAL_EXPR
)
5136 tree decl_s
= COMPOUND_LITERAL_EXPR_DECL_EXPR (value
);
5137 tree decl
= DECL_EXPR_DECL (decl_s
);
5138 tree init
= DECL_INITIAL (decl
);
5140 if (!TREE_ADDRESSABLE (value
)
5141 && !TREE_ADDRESSABLE (decl
)
5143 && TREE_CODE (init
) == CONSTRUCTOR
)
5144 newval
= optimize_compound_literals_in_ctor (init
);
5146 if (newval
== value
)
5149 if (ctor
== orig_ctor
)
5151 ctor
= copy_node (orig_ctor
);
5152 CONSTRUCTOR_ELTS (ctor
) = vec_safe_copy (elts
);
5153 elts
= CONSTRUCTOR_ELTS (ctor
);
5155 (*elts
)[idx
].value
= newval
;
5160 /* A subroutine of gimplify_modify_expr. Break out elements of a
5161 CONSTRUCTOR used as an initializer into separate MODIFY_EXPRs.
5163 Note that we still need to clear any elements that don't have explicit
5164 initializers, so if not all elements are initialized we keep the
5165 original MODIFY_EXPR, we just remove all of the constructor elements.
5167 If NOTIFY_TEMP_CREATION is true, do not gimplify, just return
5168 GS_ERROR if we would have to create a temporary when gimplifying
5169 this constructor. Otherwise, return GS_OK.
5171 If NOTIFY_TEMP_CREATION is false, just do the gimplification. */
5173 static enum gimplify_status
5174 gimplify_init_constructor (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
5175 bool want_value
, bool notify_temp_creation
)
5177 tree object
, ctor
, type
;
5178 enum gimplify_status ret
;
5179 vec
<constructor_elt
, va_gc
> *elts
;
5180 bool cleared
= false;
5181 bool is_empty_ctor
= false;
5182 bool is_init_expr
= (TREE_CODE (*expr_p
) == INIT_EXPR
);
5184 gcc_assert (TREE_CODE (TREE_OPERAND (*expr_p
, 1)) == CONSTRUCTOR
);
5186 if (!notify_temp_creation
)
5188 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
5189 is_gimple_lvalue
, fb_lvalue
);
5190 if (ret
== GS_ERROR
)
5194 object
= TREE_OPERAND (*expr_p
, 0);
5195 ctor
= TREE_OPERAND (*expr_p
, 1)
5196 = optimize_compound_literals_in_ctor (TREE_OPERAND (*expr_p
, 1));
5197 type
= TREE_TYPE (ctor
);
5198 elts
= CONSTRUCTOR_ELTS (ctor
);
5201 switch (TREE_CODE (type
))
5205 case QUAL_UNION_TYPE
:
5208 /* Use readonly data for initializers of this or smaller size
5209 regardless of the num_nonzero_elements / num_unique_nonzero_elements
5211 const HOST_WIDE_INT min_unique_size
= 64;
5212 /* If num_nonzero_elements / num_unique_nonzero_elements ratio
5213 is smaller than this, use readonly data. */
5214 const int unique_nonzero_ratio
= 8;
5215 /* True if a single access of the object must be ensured. This is the
5216 case if the target is volatile, the type is non-addressable and more
5217 than one field need to be assigned. */
5218 const bool ensure_single_access
5219 = TREE_THIS_VOLATILE (object
)
5220 && !TREE_ADDRESSABLE (type
)
5221 && vec_safe_length (elts
) > 1;
5222 struct gimplify_init_ctor_preeval_data preeval_data
;
5223 HOST_WIDE_INT num_ctor_elements
, num_nonzero_elements
;
5224 HOST_WIDE_INT num_unique_nonzero_elements
;
5225 bool complete_p
, valid_const_initializer
;
5227 /* Aggregate types must lower constructors to initialization of
5228 individual elements. The exception is that a CONSTRUCTOR node
5229 with no elements indicates zero-initialization of the whole. */
5230 if (vec_safe_is_empty (elts
))
5232 if (notify_temp_creation
)
5235 /* The var will be initialized and so appear on lhs of
5236 assignment, it can't be TREE_READONLY anymore. */
5238 TREE_READONLY (object
) = 0;
5240 is_empty_ctor
= true;
5244 /* Fetch information about the constructor to direct later processing.
5245 We might want to make static versions of it in various cases, and
5246 can only do so if it known to be a valid constant initializer. */
5247 valid_const_initializer
5248 = categorize_ctor_elements (ctor
, &num_nonzero_elements
,
5249 &num_unique_nonzero_elements
,
5250 &num_ctor_elements
, &complete_p
);
5252 /* If a const aggregate variable is being initialized, then it
5253 should never be a lose to promote the variable to be static. */
5254 if (valid_const_initializer
5255 && num_nonzero_elements
> 1
5256 && TREE_READONLY (object
)
5258 && !DECL_REGISTER (object
)
5259 && (flag_merge_constants
>= 2 || !TREE_ADDRESSABLE (object
)
5260 || DECL_MERGEABLE (object
))
5261 /* For ctors that have many repeated nonzero elements
5262 represented through RANGE_EXPRs, prefer initializing
5263 those through runtime loops over copies of large amounts
5264 of data from readonly data section. */
5265 && (num_unique_nonzero_elements
5266 > num_nonzero_elements
/ unique_nonzero_ratio
5267 || ((unsigned HOST_WIDE_INT
) int_size_in_bytes (type
)
5268 <= (unsigned HOST_WIDE_INT
) min_unique_size
)))
5270 if (notify_temp_creation
)
5273 DECL_INITIAL (object
) = ctor
;
5274 TREE_STATIC (object
) = 1;
5275 if (!DECL_NAME (object
))
5276 DECL_NAME (object
) = create_tmp_var_name ("C");
5277 walk_tree (&DECL_INITIAL (object
), force_labels_r
, NULL
, NULL
);
5279 /* ??? C++ doesn't automatically append a .<number> to the
5280 assembler name, and even when it does, it looks at FE private
5281 data structures to figure out what that number should be,
5282 which are not set for this variable. I suppose this is
5283 important for local statics for inline functions, which aren't
5284 "local" in the object file sense. So in order to get a unique
5285 TU-local symbol, we must invoke the lhd version now. */
5286 lhd_set_decl_assembler_name (object
);
5288 *expr_p
= NULL_TREE
;
5292 /* The var will be initialized and so appear on lhs of
5293 assignment, it can't be TREE_READONLY anymore. */
5294 if (VAR_P (object
) && !notify_temp_creation
)
5295 TREE_READONLY (object
) = 0;
5297 /* If there are "lots" of initialized elements, even discounting
5298 those that are not address constants (and thus *must* be
5299 computed at runtime), then partition the constructor into
5300 constant and non-constant parts. Block copy the constant
5301 parts in, then generate code for the non-constant parts. */
5302 /* TODO. There's code in cp/typeck.cc to do this. */
5304 if (int_size_in_bytes (TREE_TYPE (ctor
)) < 0)
5305 /* store_constructor will ignore the clearing of variable-sized
5306 objects. Initializers for such objects must explicitly set
5307 every field that needs to be set. */
5309 else if (!complete_p
)
5310 /* If the constructor isn't complete, clear the whole object
5311 beforehand, unless CONSTRUCTOR_NO_CLEARING is set on it.
5313 ??? This ought not to be needed. For any element not present
5314 in the initializer, we should simply set them to zero. Except
5315 we'd need to *find* the elements that are not present, and that
5316 requires trickery to avoid quadratic compile-time behavior in
5317 large cases or excessive memory use in small cases. */
5318 cleared
= !CONSTRUCTOR_NO_CLEARING (ctor
);
5319 else if (num_ctor_elements
- num_nonzero_elements
5320 > CLEAR_RATIO (optimize_function_for_speed_p (cfun
))
5321 && num_nonzero_elements
< num_ctor_elements
/ 4)
5322 /* If there are "lots" of zeros, it's more efficient to clear
5323 the memory and then set the nonzero elements. */
5325 else if (ensure_single_access
&& num_nonzero_elements
== 0)
5326 /* If a single access to the target must be ensured and all elements
5327 are zero, then it's optimal to clear whatever their number. */
5332 /* If there are "lots" of initialized elements, and all of them
5333 are valid address constants, then the entire initializer can
5334 be dropped to memory, and then memcpy'd out. Don't do this
5335 for sparse arrays, though, as it's more efficient to follow
5336 the standard CONSTRUCTOR behavior of memset followed by
5337 individual element initialization. Also don't do this for small
5338 all-zero initializers (which aren't big enough to merit
5339 clearing), and don't try to make bitwise copies of
5340 TREE_ADDRESSABLE types. */
5341 if (valid_const_initializer
5343 && !(cleared
|| num_nonzero_elements
== 0)
5344 && !TREE_ADDRESSABLE (type
))
5346 HOST_WIDE_INT size
= int_size_in_bytes (type
);
5349 /* ??? We can still get unbounded array types, at least
5350 from the C++ front end. This seems wrong, but attempt
5351 to work around it for now. */
5354 size
= int_size_in_bytes (TREE_TYPE (object
));
5356 TREE_TYPE (ctor
) = type
= TREE_TYPE (object
);
5359 /* Find the maximum alignment we can assume for the object. */
5360 /* ??? Make use of DECL_OFFSET_ALIGN. */
5361 if (DECL_P (object
))
5362 align
= DECL_ALIGN (object
);
5364 align
= TYPE_ALIGN (type
);
5366 /* Do a block move either if the size is so small as to make
5367 each individual move a sub-unit move on average, or if it
5368 is so large as to make individual moves inefficient. */
5370 && num_nonzero_elements
> 1
5371 /* For ctors that have many repeated nonzero elements
5372 represented through RANGE_EXPRs, prefer initializing
5373 those through runtime loops over copies of large amounts
5374 of data from readonly data section. */
5375 && (num_unique_nonzero_elements
5376 > num_nonzero_elements
/ unique_nonzero_ratio
5377 || size
<= min_unique_size
)
5378 && (size
< num_nonzero_elements
5379 || !can_move_by_pieces (size
, align
)))
5381 if (notify_temp_creation
)
5384 walk_tree (&ctor
, force_labels_r
, NULL
, NULL
);
5385 ctor
= tree_output_constant_def (ctor
);
5386 if (!useless_type_conversion_p (type
, TREE_TYPE (ctor
)))
5387 ctor
= build1 (VIEW_CONVERT_EXPR
, type
, ctor
);
5388 TREE_OPERAND (*expr_p
, 1) = ctor
;
5390 /* This is no longer an assignment of a CONSTRUCTOR, but
5391 we still may have processing to do on the LHS. So
5392 pretend we didn't do anything here to let that happen. */
5393 return GS_UNHANDLED
;
5397 /* If a single access to the target must be ensured and there are
5398 nonzero elements or the zero elements are not assigned en masse,
5399 initialize the target from a temporary. */
5400 if (ensure_single_access
&& (num_nonzero_elements
> 0 || !cleared
))
5402 if (notify_temp_creation
)
5405 tree temp
= create_tmp_var (TYPE_MAIN_VARIANT (type
));
5406 TREE_OPERAND (*expr_p
, 0) = temp
;
5407 *expr_p
= build2 (COMPOUND_EXPR
, TREE_TYPE (*expr_p
),
5409 build2 (MODIFY_EXPR
, void_type_node
,
5414 if (notify_temp_creation
)
5417 /* If there are nonzero elements and if needed, pre-evaluate to capture
5418 elements overlapping with the lhs into temporaries. We must do this
5419 before clearing to fetch the values before they are zeroed-out. */
5420 if (num_nonzero_elements
> 0 && TREE_CODE (*expr_p
) != INIT_EXPR
)
5422 preeval_data
.lhs_base_decl
= get_base_address (object
);
5423 if (!DECL_P (preeval_data
.lhs_base_decl
))
5424 preeval_data
.lhs_base_decl
= NULL
;
5425 preeval_data
.lhs_alias_set
= get_alias_set (object
);
5427 gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p
, 1),
5428 pre_p
, post_p
, &preeval_data
);
5431 bool ctor_has_side_effects_p
5432 = TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p
, 1));
5436 /* Zap the CONSTRUCTOR element list, which simplifies this case.
5437 Note that we still have to gimplify, in order to handle the
5438 case of variable sized types. Avoid shared tree structures. */
5439 CONSTRUCTOR_ELTS (ctor
) = NULL
;
5440 TREE_SIDE_EFFECTS (ctor
) = 0;
5441 object
= unshare_expr (object
);
5442 gimplify_stmt (expr_p
, pre_p
);
5445 /* If we have not block cleared the object, or if there are nonzero
5446 elements in the constructor, or if the constructor has side effects,
5447 add assignments to the individual scalar fields of the object. */
5449 || num_nonzero_elements
> 0
5450 || ctor_has_side_effects_p
)
5451 gimplify_init_ctor_eval (object
, elts
, pre_p
, cleared
);
5453 *expr_p
= NULL_TREE
;
5461 if (notify_temp_creation
)
5464 /* Extract the real and imaginary parts out of the ctor. */
5465 gcc_assert (elts
->length () == 2);
5466 r
= (*elts
)[0].value
;
5467 i
= (*elts
)[1].value
;
5468 if (r
== NULL
|| i
== NULL
)
5470 tree zero
= build_zero_cst (TREE_TYPE (type
));
5477 /* Complex types have either COMPLEX_CST or COMPLEX_EXPR to
5478 represent creation of a complex value. */
5479 if (TREE_CONSTANT (r
) && TREE_CONSTANT (i
))
5481 ctor
= build_complex (type
, r
, i
);
5482 TREE_OPERAND (*expr_p
, 1) = ctor
;
5486 ctor
= build2 (COMPLEX_EXPR
, type
, r
, i
);
5487 TREE_OPERAND (*expr_p
, 1) = ctor
;
5488 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 1),
5491 rhs_predicate_for (TREE_OPERAND (*expr_p
, 0)),
5499 unsigned HOST_WIDE_INT ix
;
5500 constructor_elt
*ce
;
5502 if (notify_temp_creation
)
5505 /* Vector types use CONSTRUCTOR all the way through gimple
5506 compilation as a general initializer. */
5507 FOR_EACH_VEC_SAFE_ELT (elts
, ix
, ce
)
5509 enum gimplify_status tret
;
5510 tret
= gimplify_expr (&ce
->value
, pre_p
, post_p
, is_gimple_val
,
5512 if (tret
== GS_ERROR
)
5514 else if (TREE_STATIC (ctor
)
5515 && !initializer_constant_valid_p (ce
->value
,
5516 TREE_TYPE (ce
->value
)))
5517 TREE_STATIC (ctor
) = 0;
5519 recompute_constructor_flags (ctor
);
5521 /* Go ahead and simplify constant constructors to VECTOR_CST. */
5522 if (TREE_CONSTANT (ctor
))
5524 bool constant_p
= true;
5527 /* Even when ctor is constant, it might contain non-*_CST
5528 elements, such as addresses or trapping values like
5529 1.0/0.0 - 1.0/0.0. Such expressions don't belong
5530 in VECTOR_CST nodes. */
5531 FOR_EACH_CONSTRUCTOR_VALUE (elts
, ix
, value
)
5532 if (!CONSTANT_CLASS_P (value
))
5540 TREE_OPERAND (*expr_p
, 1) = build_vector_from_ctor (type
, elts
);
5545 if (!is_gimple_reg (TREE_OPERAND (*expr_p
, 0)))
5546 TREE_OPERAND (*expr_p
, 1) = get_formal_tmp_var (ctor
, pre_p
);
5551 /* So how did we get a CONSTRUCTOR for a scalar type? */
5555 if (ret
== GS_ERROR
)
5557 /* If we have gimplified both sides of the initializer but have
5558 not emitted an assignment, do so now. */
5560 /* If the type is an empty type, we don't need to emit the
5562 && !is_empty_type (TREE_TYPE (TREE_OPERAND (*expr_p
, 0))))
5564 tree lhs
= TREE_OPERAND (*expr_p
, 0);
5565 tree rhs
= TREE_OPERAND (*expr_p
, 1);
5566 if (want_value
&& object
== lhs
)
5567 lhs
= unshare_expr (lhs
);
5568 gassign
*init
= gimple_build_assign (lhs
, rhs
);
5569 gimplify_seq_add_stmt (pre_p
, init
);
5582 /* If the user requests to initialize automatic variables, we
5583 should initialize paddings inside the variable. Add a call to
5584 __builtin_clear_pading (&object, 0, for_auto_init = true) to
5585 initialize paddings of object always to zero regardless of
5586 INIT_TYPE. Note, we will not insert this call if the aggregate
5587 variable has be completely cleared already or it's initialized
5588 with an empty constructor. We cannot insert this call if the
5589 variable is a gimple register since __builtin_clear_padding will take
5590 the address of the variable. As a result, if a long double/_Complex long
5591 double variable will be spilled into stack later, its padding cannot
5592 be cleared with __builtin_clear_padding. We should clear its padding
5593 when it is spilled into memory. */
5595 && !is_gimple_reg (object
)
5596 && clear_padding_type_may_have_padding_p (type
)
5597 && ((AGGREGATE_TYPE_P (type
) && !cleared
&& !is_empty_ctor
)
5598 || !AGGREGATE_TYPE_P (type
))
5599 && is_var_need_auto_init (object
))
5600 gimple_add_padding_init_for_auto_var (object
, false, pre_p
);
5605 /* Given a pointer value OP0, return a simplified version of an
5606 indirection through OP0, or NULL_TREE if no simplification is
5607 possible. This may only be applied to a rhs of an expression.
5608 Note that the resulting type may be different from the type pointed
5609 to in the sense that it is still compatible from the langhooks
5613 gimple_fold_indirect_ref_rhs (tree t
)
5615 return gimple_fold_indirect_ref (t
);
5618 /* Subroutine of gimplify_modify_expr to do simplifications of
5619 MODIFY_EXPRs based on the code of the RHS. We loop for as long as
5620 something changes. */
5622 static enum gimplify_status
5623 gimplify_modify_expr_rhs (tree
*expr_p
, tree
*from_p
, tree
*to_p
,
5624 gimple_seq
*pre_p
, gimple_seq
*post_p
,
5627 enum gimplify_status ret
= GS_UNHANDLED
;
5633 switch (TREE_CODE (*from_p
))
5636 /* If we're assigning from a read-only variable initialized with
5637 a constructor and not volatile, do the direct assignment from
5638 the constructor, but only if the target is not volatile either
5639 since this latter assignment might end up being done on a per
5640 field basis. However, if the target is volatile and the type
5641 is aggregate and non-addressable, gimplify_init_constructor
5642 knows that it needs to ensure a single access to the target
5643 and it will return GS_OK only in this case. */
5644 if (TREE_READONLY (*from_p
)
5645 && DECL_INITIAL (*from_p
)
5646 && TREE_CODE (DECL_INITIAL (*from_p
)) == CONSTRUCTOR
5647 && !TREE_THIS_VOLATILE (*from_p
)
5648 && (!TREE_THIS_VOLATILE (*to_p
)
5649 || (AGGREGATE_TYPE_P (TREE_TYPE (*to_p
))
5650 && !TREE_ADDRESSABLE (TREE_TYPE (*to_p
)))))
5652 tree old_from
= *from_p
;
5653 enum gimplify_status subret
;
5655 /* Move the constructor into the RHS. */
5656 *from_p
= unshare_expr (DECL_INITIAL (*from_p
));
5658 /* Let's see if gimplify_init_constructor will need to put
5660 subret
= gimplify_init_constructor (expr_p
, NULL
, NULL
,
5662 if (subret
== GS_ERROR
)
5664 /* If so, revert the change. */
5675 if (!TREE_ADDRESSABLE (TREE_TYPE (*from_p
)))
5676 /* If we have code like
5680 where the type of "x" is a (possibly cv-qualified variant
5681 of "A"), treat the entire expression as identical to "x".
5682 This kind of code arises in C++ when an object is bound
5683 to a const reference, and if "x" is a TARGET_EXPR we want
5684 to take advantage of the optimization below. But not if
5685 the type is TREE_ADDRESSABLE; then C++17 says that the
5686 TARGET_EXPR needs to be a temporary. */
5688 = gimple_fold_indirect_ref_rhs (TREE_OPERAND (*from_p
, 0)))
5690 bool volatile_p
= TREE_THIS_VOLATILE (*from_p
);
5691 if (TREE_THIS_VOLATILE (t
) != volatile_p
)
5694 t
= build_simple_mem_ref_loc (EXPR_LOCATION (*from_p
),
5695 build_fold_addr_expr (t
));
5696 if (REFERENCE_CLASS_P (t
))
5697 TREE_THIS_VOLATILE (t
) = volatile_p
;
5707 /* If we are initializing something from a TARGET_EXPR, strip the
5708 TARGET_EXPR and initialize it directly, if possible. This can't
5709 be done if the initializer is void, since that implies that the
5710 temporary is set in some non-trivial way.
5712 ??? What about code that pulls out the temp and uses it
5713 elsewhere? I think that such code never uses the TARGET_EXPR as
5714 an initializer. If I'm wrong, we'll die because the temp won't
5715 have any RTL. In that case, I guess we'll need to replace
5716 references somehow. */
5717 tree init
= TARGET_EXPR_INITIAL (*from_p
);
5720 && (TREE_CODE (*expr_p
) != MODIFY_EXPR
5721 || !TARGET_EXPR_NO_ELIDE (*from_p
))
5722 && !VOID_TYPE_P (TREE_TYPE (init
)))
5732 /* Remove any COMPOUND_EXPR in the RHS so the following cases will be
5734 gimplify_compound_expr (from_p
, pre_p
, true);
5740 /* If we already made some changes, let the front end have a
5741 crack at this before we break it down. */
5742 if (ret
!= GS_UNHANDLED
)
5745 /* If we're initializing from a CONSTRUCTOR, break this into
5746 individual MODIFY_EXPRs. */
5747 ret
= gimplify_init_constructor (expr_p
, pre_p
, post_p
, want_value
,
5752 /* If we're assigning to a non-register type, push the assignment
5753 down into the branches. This is mandatory for ADDRESSABLE types,
5754 since we cannot generate temporaries for such, but it saves a
5755 copy in other cases as well. */
5756 if (!is_gimple_reg_type (TREE_TYPE (*from_p
)))
5758 /* This code should mirror the code in gimplify_cond_expr. */
5759 enum tree_code code
= TREE_CODE (*expr_p
);
5760 tree cond
= *from_p
;
5761 tree result
= *to_p
;
5763 ret
= gimplify_expr (&result
, pre_p
, post_p
,
5764 is_gimple_lvalue
, fb_lvalue
);
5765 if (ret
!= GS_ERROR
)
5768 /* If we are going to write RESULT more than once, clear
5769 TREE_READONLY flag, otherwise we might incorrectly promote
5770 the variable to static const and initialize it at compile
5771 time in one of the branches. */
5773 && TREE_TYPE (TREE_OPERAND (cond
, 1)) != void_type_node
5774 && TREE_TYPE (TREE_OPERAND (cond
, 2)) != void_type_node
)
5775 TREE_READONLY (result
) = 0;
5776 if (TREE_TYPE (TREE_OPERAND (cond
, 1)) != void_type_node
)
5777 TREE_OPERAND (cond
, 1)
5778 = build2 (code
, void_type_node
, result
,
5779 TREE_OPERAND (cond
, 1));
5780 if (TREE_TYPE (TREE_OPERAND (cond
, 2)) != void_type_node
)
5781 TREE_OPERAND (cond
, 2)
5782 = build2 (code
, void_type_node
, unshare_expr (result
),
5783 TREE_OPERAND (cond
, 2));
5785 TREE_TYPE (cond
) = void_type_node
;
5786 recalculate_side_effects (cond
);
5790 gimplify_and_add (cond
, pre_p
);
5791 *expr_p
= unshare_expr (result
);
5800 /* For calls that return in memory, give *to_p as the CALL_EXPR's
5801 return slot so that we don't generate a temporary. */
5802 if (!CALL_EXPR_RETURN_SLOT_OPT (*from_p
)
5803 && aggregate_value_p (*from_p
, *from_p
))
5807 if (!(rhs_predicate_for (*to_p
))(*from_p
))
5808 /* If we need a temporary, *to_p isn't accurate. */
5810 /* It's OK to use the return slot directly unless it's an NRV. */
5811 else if (TREE_CODE (*to_p
) == RESULT_DECL
5812 && DECL_NAME (*to_p
) == NULL_TREE
5813 && needs_to_live_in_memory (*to_p
))
5815 else if (is_gimple_reg_type (TREE_TYPE (*to_p
))
5816 || (DECL_P (*to_p
) && DECL_REGISTER (*to_p
)))
5817 /* Don't force regs into memory. */
5819 else if (TREE_CODE (*expr_p
) == INIT_EXPR
)
5820 /* It's OK to use the target directly if it's being
5823 else if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p
)))
5825 /* Always use the target and thus RSO for variable-sized types.
5826 GIMPLE cannot deal with a variable-sized assignment
5827 embedded in a call statement. */
5829 else if (TREE_CODE (*to_p
) != SSA_NAME
5830 && (!is_gimple_variable (*to_p
)
5831 || needs_to_live_in_memory (*to_p
)))
5832 /* Don't use the original target if it's already addressable;
5833 if its address escapes, and the called function uses the
5834 NRV optimization, a conforming program could see *to_p
5835 change before the called function returns; see c++/19317.
5836 When optimizing, the return_slot pass marks more functions
5837 as safe after we have escape info. */
5844 CALL_EXPR_RETURN_SLOT_OPT (*from_p
) = 1;
5845 mark_addressable (*to_p
);
5850 case WITH_SIZE_EXPR
:
5851 /* Likewise for calls that return an aggregate of non-constant size,
5852 since we would not be able to generate a temporary at all. */
5853 if (TREE_CODE (TREE_OPERAND (*from_p
, 0)) == CALL_EXPR
)
5855 *from_p
= TREE_OPERAND (*from_p
, 0);
5856 /* We don't change ret in this case because the
5857 WITH_SIZE_EXPR might have been added in
5858 gimplify_modify_expr, so returning GS_OK would lead to an
5864 /* If we're initializing from a container, push the initialization
5866 case CLEANUP_POINT_EXPR
:
5868 case STATEMENT_LIST
:
5870 tree wrap
= *from_p
;
5873 ret
= gimplify_expr (to_p
, pre_p
, post_p
, is_gimple_min_lval
,
5875 if (ret
!= GS_ERROR
)
5878 t
= voidify_wrapper_expr (wrap
, *expr_p
);
5879 gcc_assert (t
== *expr_p
);
5883 gimplify_and_add (wrap
, pre_p
);
5884 *expr_p
= unshare_expr (*to_p
);
5892 /* Pull out compound literal expressions from a NOP_EXPR.
5893 Those are created in the C FE to drop qualifiers during
5894 lvalue conversion. */
5895 if ((TREE_CODE (TREE_OPERAND (*from_p
, 0)) == COMPOUND_LITERAL_EXPR
)
5896 && tree_ssa_useless_type_conversion (*from_p
))
5898 *from_p
= TREE_OPERAND (*from_p
, 0);
5904 case COMPOUND_LITERAL_EXPR
:
5906 tree complit
= TREE_OPERAND (*expr_p
, 1);
5907 tree decl_s
= COMPOUND_LITERAL_EXPR_DECL_EXPR (complit
);
5908 tree decl
= DECL_EXPR_DECL (decl_s
);
5909 tree init
= DECL_INITIAL (decl
);
5911 /* struct T x = (struct T) { 0, 1, 2 } can be optimized
5912 into struct T x = { 0, 1, 2 } if the address of the
5913 compound literal has never been taken. */
5914 if (!TREE_ADDRESSABLE (complit
)
5915 && !TREE_ADDRESSABLE (decl
)
5918 *expr_p
= copy_node (*expr_p
);
5919 TREE_OPERAND (*expr_p
, 1) = init
;
5934 /* Return true if T looks like a valid GIMPLE statement. */
5937 is_gimple_stmt (tree t
)
5939 const enum tree_code code
= TREE_CODE (t
);
5944 /* The only valid NOP_EXPR is the empty statement. */
5945 return IS_EMPTY_STMT (t
);
5949 /* These are only valid if they're void. */
5950 return TREE_TYPE (t
) == NULL
|| VOID_TYPE_P (TREE_TYPE (t
));
5956 case CASE_LABEL_EXPR
:
5957 case TRY_CATCH_EXPR
:
5958 case TRY_FINALLY_EXPR
:
5959 case EH_FILTER_EXPR
:
5962 case STATEMENT_LIST
:
5967 case OACC_HOST_DATA
:
5970 case OACC_ENTER_DATA
:
5971 case OACC_EXIT_DATA
:
5976 case OMP_DISTRIBUTE
:
5991 case OMP_TARGET_DATA
:
5992 case OMP_TARGET_UPDATE
:
5993 case OMP_TARGET_ENTER_DATA
:
5994 case OMP_TARGET_EXIT_DATA
:
5997 /* These are always void. */
6003 /* These are valid regardless of their type. */
6012 /* Promote partial stores to COMPLEX variables to total stores. *EXPR_P is
6013 a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a gimple register.
6015 IMPORTANT NOTE: This promotion is performed by introducing a load of the
6016 other, unmodified part of the complex object just before the total store.
6017 As a consequence, if the object is still uninitialized, an undefined value
6018 will be loaded into a register, which may result in a spurious exception
6019 if the register is floating-point and the value happens to be a signaling
6020 NaN for example. Then the fully-fledged complex operations lowering pass
6021 followed by a DCE pass are necessary in order to fix things up. */
6023 static enum gimplify_status
6024 gimplify_modify_expr_complex_part (tree
*expr_p
, gimple_seq
*pre_p
,
6027 enum tree_code code
, ocode
;
6028 tree lhs
, rhs
, new_rhs
, other
, realpart
, imagpart
;
6030 lhs
= TREE_OPERAND (*expr_p
, 0);
6031 rhs
= TREE_OPERAND (*expr_p
, 1);
6032 code
= TREE_CODE (lhs
);
6033 lhs
= TREE_OPERAND (lhs
, 0);
6035 ocode
= code
== REALPART_EXPR
? IMAGPART_EXPR
: REALPART_EXPR
;
6036 other
= build1 (ocode
, TREE_TYPE (rhs
), lhs
);
6037 suppress_warning (other
);
6038 other
= get_formal_tmp_var (other
, pre_p
);
6040 realpart
= code
== REALPART_EXPR
? rhs
: other
;
6041 imagpart
= code
== REALPART_EXPR
? other
: rhs
;
6043 if (TREE_CONSTANT (realpart
) && TREE_CONSTANT (imagpart
))
6044 new_rhs
= build_complex (TREE_TYPE (lhs
), realpart
, imagpart
);
6046 new_rhs
= build2 (COMPLEX_EXPR
, TREE_TYPE (lhs
), realpart
, imagpart
);
6048 gimplify_seq_add_stmt (pre_p
, gimple_build_assign (lhs
, new_rhs
));
6049 *expr_p
= (want_value
) ? rhs
: NULL_TREE
;
6054 /* Gimplify the MODIFY_EXPR node pointed to by EXPR_P.
6060 PRE_P points to the list where side effects that must happen before
6061 *EXPR_P should be stored.
6063 POST_P points to the list where side effects that must happen after
6064 *EXPR_P should be stored.
6066 WANT_VALUE is nonzero iff we want to use the value of this expression
6067 in another expression. */
6069 static enum gimplify_status
6070 gimplify_modify_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
6073 tree
*from_p
= &TREE_OPERAND (*expr_p
, 1);
6074 tree
*to_p
= &TREE_OPERAND (*expr_p
, 0);
6075 enum gimplify_status ret
= GS_UNHANDLED
;
6077 location_t loc
= EXPR_LOCATION (*expr_p
);
6078 gimple_stmt_iterator gsi
;
6080 if (error_operand_p (*from_p
) || error_operand_p (*to_p
))
6083 gcc_assert (TREE_CODE (*expr_p
) == MODIFY_EXPR
6084 || TREE_CODE (*expr_p
) == INIT_EXPR
);
6086 /* Trying to simplify a clobber using normal logic doesn't work,
6087 so handle it here. */
6088 if (TREE_CLOBBER_P (*from_p
))
6090 ret
= gimplify_expr (to_p
, pre_p
, post_p
, is_gimple_lvalue
, fb_lvalue
);
6091 if (ret
== GS_ERROR
)
6093 gcc_assert (!want_value
);
6094 if (!VAR_P (*to_p
) && TREE_CODE (*to_p
) != MEM_REF
)
6096 tree addr
= get_initialized_tmp_var (build_fold_addr_expr (*to_p
),
6098 *to_p
= build_simple_mem_ref_loc (EXPR_LOCATION (*to_p
), addr
);
6100 gimplify_seq_add_stmt (pre_p
, gimple_build_assign (*to_p
, *from_p
));
6105 /* Convert initialization from an empty variable-size CONSTRUCTOR to
6107 if (TREE_TYPE (*from_p
) != error_mark_node
6108 && TYPE_SIZE_UNIT (TREE_TYPE (*from_p
))
6109 && !poly_int_tree_p (TYPE_SIZE_UNIT (TREE_TYPE (*from_p
)))
6110 && TREE_CODE (*from_p
) == CONSTRUCTOR
6111 && CONSTRUCTOR_NELTS (*from_p
) == 0)
6113 maybe_with_size_expr (from_p
);
6114 gcc_assert (TREE_CODE (*from_p
) == WITH_SIZE_EXPR
);
6115 return gimplify_modify_expr_to_memset (expr_p
,
6116 TREE_OPERAND (*from_p
, 1),
6120 /* Insert pointer conversions required by the middle-end that are not
6121 required by the frontend. This fixes middle-end type checking for
6122 for example gcc.dg/redecl-6.c. */
6123 if (POINTER_TYPE_P (TREE_TYPE (*to_p
)))
6125 STRIP_USELESS_TYPE_CONVERSION (*from_p
);
6126 if (!useless_type_conversion_p (TREE_TYPE (*to_p
), TREE_TYPE (*from_p
)))
6127 *from_p
= fold_convert_loc (loc
, TREE_TYPE (*to_p
), *from_p
);
6130 /* See if any simplifications can be done based on what the RHS is. */
6131 ret
= gimplify_modify_expr_rhs (expr_p
, from_p
, to_p
, pre_p
, post_p
,
6133 if (ret
!= GS_UNHANDLED
)
6136 /* For empty types only gimplify the left hand side and right hand
6137 side as statements and throw away the assignment. Do this after
6138 gimplify_modify_expr_rhs so we handle TARGET_EXPRs of addressable
6140 if (is_empty_type (TREE_TYPE (*from_p
))
6142 /* Don't do this for calls that return addressable types, expand_call
6143 relies on those having a lhs. */
6144 && !(TREE_ADDRESSABLE (TREE_TYPE (*from_p
))
6145 && TREE_CODE (*from_p
) == CALL_EXPR
))
6147 gimplify_stmt (from_p
, pre_p
);
6148 gimplify_stmt (to_p
, pre_p
);
6149 *expr_p
= NULL_TREE
;
6153 /* If the value being copied is of variable width, compute the length
6154 of the copy into a WITH_SIZE_EXPR. Note that we need to do this
6155 before gimplifying any of the operands so that we can resolve any
6156 PLACEHOLDER_EXPRs in the size. Also note that the RTL expander uses
6157 the size of the expression to be copied, not of the destination, so
6158 that is what we must do here. */
6159 maybe_with_size_expr (from_p
);
6161 /* As a special case, we have to temporarily allow for assignments
6162 with a CALL_EXPR on the RHS. Since in GIMPLE a function call is
6163 a toplevel statement, when gimplifying the GENERIC expression
6164 MODIFY_EXPR <a, CALL_EXPR <foo>>, we cannot create the tuple
6165 GIMPLE_ASSIGN <a, GIMPLE_CALL <foo>>.
6167 Instead, we need to create the tuple GIMPLE_CALL <a, foo>. To
6168 prevent gimplify_expr from trying to create a new temporary for
6169 foo's LHS, we tell it that it should only gimplify until it
6170 reaches the CALL_EXPR. On return from gimplify_expr, the newly
6171 created GIMPLE_CALL <foo> will be the last statement in *PRE_P
6172 and all we need to do here is set 'a' to be its LHS. */
6174 /* Gimplify the RHS first for C++17 and bug 71104. */
6175 gimple_predicate initial_pred
= initial_rhs_predicate_for (*to_p
);
6176 ret
= gimplify_expr (from_p
, pre_p
, post_p
, initial_pred
, fb_rvalue
);
6177 if (ret
== GS_ERROR
)
6180 /* Then gimplify the LHS. */
6181 /* If we gimplified the RHS to a CALL_EXPR and that call may return
6182 twice we have to make sure to gimplify into non-SSA as otherwise
6183 the abnormal edge added later will make those defs not dominate
6185 ??? Technically this applies only to the registers used in the
6186 resulting non-register *TO_P. */
6187 bool saved_into_ssa
= gimplify_ctxp
->into_ssa
;
6189 && TREE_CODE (*from_p
) == CALL_EXPR
6190 && call_expr_flags (*from_p
) & ECF_RETURNS_TWICE
)
6191 gimplify_ctxp
->into_ssa
= false;
6192 ret
= gimplify_expr (to_p
, pre_p
, post_p
, is_gimple_lvalue
, fb_lvalue
);
6193 gimplify_ctxp
->into_ssa
= saved_into_ssa
;
6194 if (ret
== GS_ERROR
)
6197 /* Now that the LHS is gimplified, re-gimplify the RHS if our initial
6198 guess for the predicate was wrong. */
6199 gimple_predicate final_pred
= rhs_predicate_for (*to_p
);
6200 if (final_pred
!= initial_pred
)
6202 ret
= gimplify_expr (from_p
, pre_p
, post_p
, final_pred
, fb_rvalue
);
6203 if (ret
== GS_ERROR
)
6207 /* In case of va_arg internal fn wrappped in a WITH_SIZE_EXPR, add the type
6208 size as argument to the call. */
6209 if (TREE_CODE (*from_p
) == WITH_SIZE_EXPR
)
6211 tree call
= TREE_OPERAND (*from_p
, 0);
6212 tree vlasize
= TREE_OPERAND (*from_p
, 1);
6214 if (TREE_CODE (call
) == CALL_EXPR
6215 && CALL_EXPR_IFN (call
) == IFN_VA_ARG
)
6217 int nargs
= call_expr_nargs (call
);
6218 tree type
= TREE_TYPE (call
);
6219 tree ap
= CALL_EXPR_ARG (call
, 0);
6220 tree tag
= CALL_EXPR_ARG (call
, 1);
6221 tree aptag
= CALL_EXPR_ARG (call
, 2);
6222 tree newcall
= build_call_expr_internal_loc (EXPR_LOCATION (call
),
6226 TREE_OPERAND (*from_p
, 0) = newcall
;
6230 /* Now see if the above changed *from_p to something we handle specially. */
6231 ret
= gimplify_modify_expr_rhs (expr_p
, from_p
, to_p
, pre_p
, post_p
,
6233 if (ret
!= GS_UNHANDLED
)
6236 /* If we've got a variable sized assignment between two lvalues (i.e. does
6237 not involve a call), then we can make things a bit more straightforward
6238 by converting the assignment to memcpy or memset. */
6239 if (TREE_CODE (*from_p
) == WITH_SIZE_EXPR
)
6241 tree from
= TREE_OPERAND (*from_p
, 0);
6242 tree size
= TREE_OPERAND (*from_p
, 1);
6244 if (TREE_CODE (from
) == CONSTRUCTOR
)
6245 return gimplify_modify_expr_to_memset (expr_p
, size
, want_value
, pre_p
);
6247 if (is_gimple_addressable (from
))
6250 return gimplify_modify_expr_to_memcpy (expr_p
, size
, want_value
,
6255 /* Transform partial stores to non-addressable complex variables into
6256 total stores. This allows us to use real instead of virtual operands
6257 for these variables, which improves optimization. */
6258 if ((TREE_CODE (*to_p
) == REALPART_EXPR
6259 || TREE_CODE (*to_p
) == IMAGPART_EXPR
)
6260 && is_gimple_reg (TREE_OPERAND (*to_p
, 0)))
6261 return gimplify_modify_expr_complex_part (expr_p
, pre_p
, want_value
);
6263 /* Try to alleviate the effects of the gimplification creating artificial
6264 temporaries (see for example is_gimple_reg_rhs) on the debug info, but
6265 make sure not to create DECL_DEBUG_EXPR links across functions. */
6266 if (!gimplify_ctxp
->into_ssa
6268 && DECL_IGNORED_P (*from_p
)
6270 && !DECL_IGNORED_P (*to_p
)
6271 && decl_function_context (*to_p
) == current_function_decl
6272 && decl_function_context (*from_p
) == current_function_decl
)
6274 if (!DECL_NAME (*from_p
) && DECL_NAME (*to_p
))
6276 = create_tmp_var_name (IDENTIFIER_POINTER (DECL_NAME (*to_p
)));
6277 DECL_HAS_DEBUG_EXPR_P (*from_p
) = 1;
6278 SET_DECL_DEBUG_EXPR (*from_p
, *to_p
);
6281 if (want_value
&& TREE_THIS_VOLATILE (*to_p
))
6282 *from_p
= get_initialized_tmp_var (*from_p
, pre_p
, post_p
);
6284 if (TREE_CODE (*from_p
) == CALL_EXPR
)
6286 /* Since the RHS is a CALL_EXPR, we need to create a GIMPLE_CALL
6287 instead of a GIMPLE_ASSIGN. */
6289 if (CALL_EXPR_FN (*from_p
) == NULL_TREE
)
6291 /* Gimplify internal functions created in the FEs. */
6292 int nargs
= call_expr_nargs (*from_p
), i
;
6293 enum internal_fn ifn
= CALL_EXPR_IFN (*from_p
);
6294 auto_vec
<tree
> vargs (nargs
);
6296 for (i
= 0; i
< nargs
; i
++)
6298 gimplify_arg (&CALL_EXPR_ARG (*from_p
, i
), pre_p
,
6299 EXPR_LOCATION (*from_p
));
6300 vargs
.quick_push (CALL_EXPR_ARG (*from_p
, i
));
6302 call_stmt
= gimple_build_call_internal_vec (ifn
, vargs
);
6303 gimple_call_set_nothrow (call_stmt
, TREE_NOTHROW (*from_p
));
6304 gimple_set_location (call_stmt
, EXPR_LOCATION (*expr_p
));
6308 tree fnptrtype
= TREE_TYPE (CALL_EXPR_FN (*from_p
));
6309 CALL_EXPR_FN (*from_p
) = TREE_OPERAND (CALL_EXPR_FN (*from_p
), 0);
6310 STRIP_USELESS_TYPE_CONVERSION (CALL_EXPR_FN (*from_p
));
6311 tree fndecl
= get_callee_fndecl (*from_p
);
6313 && fndecl_built_in_p (fndecl
, BUILT_IN_EXPECT
)
6314 && call_expr_nargs (*from_p
) == 3)
6315 call_stmt
= gimple_build_call_internal (IFN_BUILTIN_EXPECT
, 3,
6316 CALL_EXPR_ARG (*from_p
, 0),
6317 CALL_EXPR_ARG (*from_p
, 1),
6318 CALL_EXPR_ARG (*from_p
, 2));
6321 call_stmt
= gimple_build_call_from_tree (*from_p
, fnptrtype
);
6324 notice_special_calls (call_stmt
);
6325 if (!gimple_call_noreturn_p (call_stmt
) || !should_remove_lhs_p (*to_p
))
6326 gimple_call_set_lhs (call_stmt
, *to_p
);
6327 else if (TREE_CODE (*to_p
) == SSA_NAME
)
6328 /* The above is somewhat premature, avoid ICEing later for a
6329 SSA name w/o a definition. We may have uses in the GIMPLE IL.
6330 ??? This doesn't make it a default-def. */
6331 SSA_NAME_DEF_STMT (*to_p
) = gimple_build_nop ();
6337 assign
= gimple_build_assign (*to_p
, *from_p
);
6338 gimple_set_location (assign
, EXPR_LOCATION (*expr_p
));
6339 if (COMPARISON_CLASS_P (*from_p
))
6340 copy_warning (assign
, *from_p
);
6343 if (gimplify_ctxp
->into_ssa
&& is_gimple_reg (*to_p
))
6345 /* We should have got an SSA name from the start. */
6346 gcc_assert (TREE_CODE (*to_p
) == SSA_NAME
6347 || ! gimple_in_ssa_p (cfun
));
6350 gimplify_seq_add_stmt (pre_p
, assign
);
6351 gsi
= gsi_last (*pre_p
);
6352 maybe_fold_stmt (&gsi
);
6356 *expr_p
= TREE_THIS_VOLATILE (*to_p
) ? *from_p
: unshare_expr (*to_p
);
6365 /* Gimplify a comparison between two variable-sized objects. Do this
6366 with a call to BUILT_IN_MEMCMP. */
6368 static enum gimplify_status
6369 gimplify_variable_sized_compare (tree
*expr_p
)
6371 location_t loc
= EXPR_LOCATION (*expr_p
);
6372 tree op0
= TREE_OPERAND (*expr_p
, 0);
6373 tree op1
= TREE_OPERAND (*expr_p
, 1);
6374 tree t
, arg
, dest
, src
, expr
;
6376 arg
= TYPE_SIZE_UNIT (TREE_TYPE (op0
));
6377 arg
= unshare_expr (arg
);
6378 arg
= SUBSTITUTE_PLACEHOLDER_IN_EXPR (arg
, op0
);
6379 src
= build_fold_addr_expr_loc (loc
, op1
);
6380 dest
= build_fold_addr_expr_loc (loc
, op0
);
6381 t
= builtin_decl_implicit (BUILT_IN_MEMCMP
);
6382 t
= build_call_expr_loc (loc
, t
, 3, dest
, src
, arg
);
6385 = build2 (TREE_CODE (*expr_p
), TREE_TYPE (*expr_p
), t
, integer_zero_node
);
6386 SET_EXPR_LOCATION (expr
, loc
);
6392 /* Gimplify a comparison between two aggregate objects of integral scalar
6393 mode as a comparison between the bitwise equivalent scalar values. */
6395 static enum gimplify_status
6396 gimplify_scalar_mode_aggregate_compare (tree
*expr_p
)
6398 location_t loc
= EXPR_LOCATION (*expr_p
);
6399 tree op0
= TREE_OPERAND (*expr_p
, 0);
6400 tree op1
= TREE_OPERAND (*expr_p
, 1);
6402 tree type
= TREE_TYPE (op0
);
6403 tree scalar_type
= lang_hooks
.types
.type_for_mode (TYPE_MODE (type
), 1);
6405 op0
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, scalar_type
, op0
);
6406 op1
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, scalar_type
, op1
);
6409 = fold_build2_loc (loc
, TREE_CODE (*expr_p
), TREE_TYPE (*expr_p
), op0
, op1
);
6414 /* Gimplify an expression sequence. This function gimplifies each
6415 expression and rewrites the original expression with the last
6416 expression of the sequence in GIMPLE form.
6418 PRE_P points to the list where the side effects for all the
6419 expressions in the sequence will be emitted.
6421 WANT_VALUE is true when the result of the last COMPOUND_EXPR is used. */
6423 static enum gimplify_status
6424 gimplify_compound_expr (tree
*expr_p
, gimple_seq
*pre_p
, bool want_value
)
6430 tree
*sub_p
= &TREE_OPERAND (t
, 0);
6432 if (TREE_CODE (*sub_p
) == COMPOUND_EXPR
)
6433 gimplify_compound_expr (sub_p
, pre_p
, false);
6435 gimplify_stmt (sub_p
, pre_p
);
6437 t
= TREE_OPERAND (t
, 1);
6439 while (TREE_CODE (t
) == COMPOUND_EXPR
);
6446 gimplify_stmt (expr_p
, pre_p
);
6451 /* Gimplify a SAVE_EXPR node. EXPR_P points to the expression to
6452 gimplify. After gimplification, EXPR_P will point to a new temporary
6453 that holds the original value of the SAVE_EXPR node.
6455 PRE_P points to the list where side effects that must happen before
6456 *EXPR_P should be stored. */
6458 static enum gimplify_status
6459 gimplify_save_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
)
6461 enum gimplify_status ret
= GS_ALL_DONE
;
6464 gcc_assert (TREE_CODE (*expr_p
) == SAVE_EXPR
);
6465 val
= TREE_OPERAND (*expr_p
, 0);
6467 if (val
&& TREE_TYPE (val
) == error_mark_node
)
6470 /* If the SAVE_EXPR has not been resolved, then evaluate it once. */
6471 if (!SAVE_EXPR_RESOLVED_P (*expr_p
))
6473 /* The operand may be a void-valued expression. It is
6474 being executed only for its side-effects. */
6475 if (TREE_TYPE (val
) == void_type_node
)
6477 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
6478 is_gimple_stmt
, fb_none
);
6482 /* The temporary may not be an SSA name as later abnormal and EH
6483 control flow may invalidate use/def domination. When in SSA
6484 form then assume there are no such issues and SAVE_EXPRs only
6485 appear via GENERIC foldings. */
6486 val
= get_initialized_tmp_var (val
, pre_p
, post_p
,
6487 gimple_in_ssa_p (cfun
));
6489 TREE_OPERAND (*expr_p
, 0) = val
;
6490 SAVE_EXPR_RESOLVED_P (*expr_p
) = 1;
6498 /* Rewrite the ADDR_EXPR node pointed to by EXPR_P
6505 PRE_P points to the list where side effects that must happen before
6506 *EXPR_P should be stored.
6508 POST_P points to the list where side effects that must happen after
6509 *EXPR_P should be stored. */
6511 static enum gimplify_status
6512 gimplify_addr_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
)
6514 tree expr
= *expr_p
;
6515 tree op0
= TREE_OPERAND (expr
, 0);
6516 enum gimplify_status ret
;
6517 location_t loc
= EXPR_LOCATION (*expr_p
);
6519 switch (TREE_CODE (op0
))
6523 /* Check if we are dealing with an expression of the form '&*ptr'.
6524 While the front end folds away '&*ptr' into 'ptr', these
6525 expressions may be generated internally by the compiler (e.g.,
6526 builtins like __builtin_va_end). */
6527 /* Caution: the silent array decomposition semantics we allow for
6528 ADDR_EXPR means we can't always discard the pair. */
6529 /* Gimplification of the ADDR_EXPR operand may drop
6530 cv-qualification conversions, so make sure we add them if
6533 tree op00
= TREE_OPERAND (op0
, 0);
6534 tree t_expr
= TREE_TYPE (expr
);
6535 tree t_op00
= TREE_TYPE (op00
);
6537 if (!useless_type_conversion_p (t_expr
, t_op00
))
6538 op00
= fold_convert_loc (loc
, TREE_TYPE (expr
), op00
);
6544 case VIEW_CONVERT_EXPR
:
6545 /* Take the address of our operand and then convert it to the type of
6548 ??? The interactions of VIEW_CONVERT_EXPR and aliasing is not at
6549 all clear. The impact of this transformation is even less clear. */
6551 /* If the operand is a useless conversion, look through it. Doing so
6552 guarantees that the ADDR_EXPR and its operand will remain of the
6554 if (tree_ssa_useless_type_conversion (TREE_OPERAND (op0
, 0)))
6555 op0
= TREE_OPERAND (op0
, 0);
6557 *expr_p
= fold_convert_loc (loc
, TREE_TYPE (expr
),
6558 build_fold_addr_expr_loc (loc
,
6559 TREE_OPERAND (op0
, 0)));
6564 if (integer_zerop (TREE_OPERAND (op0
, 1)))
6565 goto do_indirect_ref
;
6570 /* If we see a call to a declared builtin or see its address
6571 being taken (we can unify those cases here) then we can mark
6572 the builtin for implicit generation by GCC. */
6573 if (TREE_CODE (op0
) == FUNCTION_DECL
6574 && fndecl_built_in_p (op0
, BUILT_IN_NORMAL
)
6575 && builtin_decl_declared_p (DECL_FUNCTION_CODE (op0
)))
6576 set_builtin_decl_implicit_p (DECL_FUNCTION_CODE (op0
), true);
6578 /* We use fb_either here because the C frontend sometimes takes
6579 the address of a call that returns a struct; see
6580 gcc.dg/c99-array-lval-1.c. The gimplifier will correctly make
6581 the implied temporary explicit. */
6583 /* Make the operand addressable. */
6584 ret
= gimplify_expr (&TREE_OPERAND (expr
, 0), pre_p
, post_p
,
6585 is_gimple_addressable
, fb_either
);
6586 if (ret
== GS_ERROR
)
6589 /* Then mark it. Beware that it may not be possible to do so directly
6590 if a temporary has been created by the gimplification. */
6591 prepare_gimple_addressable (&TREE_OPERAND (expr
, 0), pre_p
);
6593 op0
= TREE_OPERAND (expr
, 0);
6595 /* For various reasons, the gimplification of the expression
6596 may have made a new INDIRECT_REF. */
6597 if (INDIRECT_REF_P (op0
)
6598 || (TREE_CODE (op0
) == MEM_REF
6599 && integer_zerop (TREE_OPERAND (op0
, 1))))
6600 goto do_indirect_ref
;
6602 mark_addressable (TREE_OPERAND (expr
, 0));
6604 /* The FEs may end up building ADDR_EXPRs early on a decl with
6605 an incomplete type. Re-build ADDR_EXPRs in canonical form
6607 if (!types_compatible_p (TREE_TYPE (op0
), TREE_TYPE (TREE_TYPE (expr
))))
6608 *expr_p
= build_fold_addr_expr (op0
);
6610 /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly. */
6611 recompute_tree_invariant_for_addr_expr (*expr_p
);
6613 /* If we re-built the ADDR_EXPR add a conversion to the original type
6615 if (!useless_type_conversion_p (TREE_TYPE (expr
), TREE_TYPE (*expr_p
)))
6616 *expr_p
= fold_convert (TREE_TYPE (expr
), *expr_p
);
6624 /* Gimplify the operands of an ASM_EXPR. Input operands should be a gimple
6625 value; output operands should be a gimple lvalue. */
6627 static enum gimplify_status
6628 gimplify_asm_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
)
6632 const char **oconstraints
;
6635 const char *constraint
;
6636 bool allows_mem
, allows_reg
, is_inout
;
6637 enum gimplify_status ret
, tret
;
6639 vec
<tree
, va_gc
> *inputs
;
6640 vec
<tree
, va_gc
> *outputs
;
6641 vec
<tree
, va_gc
> *clobbers
;
6642 vec
<tree
, va_gc
> *labels
;
6646 noutputs
= list_length (ASM_OUTPUTS (expr
));
6647 oconstraints
= (const char **) alloca ((noutputs
) * sizeof (const char *));
6655 link_next
= NULL_TREE
;
6656 for (i
= 0, link
= ASM_OUTPUTS (expr
); link
; ++i
, link
= link_next
)
6659 size_t constraint_len
;
6661 link_next
= TREE_CHAIN (link
);
6665 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link
)));
6666 constraint_len
= strlen (constraint
);
6667 if (constraint_len
== 0)
6670 ok
= parse_output_constraint (&constraint
, i
, 0, 0,
6671 &allows_mem
, &allows_reg
, &is_inout
);
6678 /* If we can't make copies, we can only accept memory.
6679 Similarly for VLAs. */
6680 tree outtype
= TREE_TYPE (TREE_VALUE (link
));
6681 if (outtype
!= error_mark_node
6682 && (TREE_ADDRESSABLE (outtype
)
6683 || !COMPLETE_TYPE_P (outtype
)
6684 || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (outtype
))))
6690 error ("impossible constraint in %<asm%>");
6691 error ("non-memory output %d must stay in memory", i
);
6696 if (!allows_reg
&& allows_mem
)
6697 mark_addressable (TREE_VALUE (link
));
6699 tree orig
= TREE_VALUE (link
);
6700 tret
= gimplify_expr (&TREE_VALUE (link
), pre_p
, post_p
,
6701 is_inout
? is_gimple_min_lval
: is_gimple_lvalue
,
6702 fb_lvalue
| fb_mayfail
);
6703 if (tret
== GS_ERROR
)
6705 if (orig
!= error_mark_node
)
6706 error ("invalid lvalue in %<asm%> output %d", i
);
6710 /* If the constraint does not allow memory make sure we gimplify
6711 it to a register if it is not already but its base is. This
6712 happens for complex and vector components. */
6715 tree op
= TREE_VALUE (link
);
6716 if (! is_gimple_val (op
)
6717 && is_gimple_reg_type (TREE_TYPE (op
))
6718 && is_gimple_reg (get_base_address (op
)))
6720 tree tem
= create_tmp_reg (TREE_TYPE (op
));
6724 ass
= build2 (MODIFY_EXPR
, TREE_TYPE (tem
),
6725 tem
, unshare_expr (op
));
6726 gimplify_and_add (ass
, pre_p
);
6728 ass
= build2 (MODIFY_EXPR
, TREE_TYPE (tem
), op
, tem
);
6729 gimplify_and_add (ass
, post_p
);
6731 TREE_VALUE (link
) = tem
;
6736 vec_safe_push (outputs
, link
);
6737 TREE_CHAIN (link
) = NULL_TREE
;
6741 /* An input/output operand. To give the optimizers more
6742 flexibility, split it into separate input and output
6745 /* Buffer big enough to format a 32-bit UINT_MAX into. */
6748 /* Turn the in/out constraint into an output constraint. */
6749 char *p
= xstrdup (constraint
);
6751 TREE_VALUE (TREE_PURPOSE (link
)) = build_string (constraint_len
, p
);
6753 /* And add a matching input constraint. */
6756 sprintf (buf
, "%u", i
);
6758 /* If there are multiple alternatives in the constraint,
6759 handle each of them individually. Those that allow register
6760 will be replaced with operand number, the others will stay
6762 if (strchr (p
, ',') != NULL
)
6764 size_t len
= 0, buflen
= strlen (buf
);
6765 char *beg
, *end
, *str
, *dst
;
6769 end
= strchr (beg
, ',');
6771 end
= strchr (beg
, '\0');
6772 if ((size_t) (end
- beg
) < buflen
)
6775 len
+= end
- beg
+ 1;
6782 str
= (char *) alloca (len
);
6783 for (beg
= p
+ 1, dst
= str
;;)
6786 bool mem_p
, reg_p
, inout_p
;
6788 end
= strchr (beg
, ',');
6793 parse_output_constraint (&tem
, i
, 0, 0,
6794 &mem_p
, ®_p
, &inout_p
);
6799 memcpy (dst
, buf
, buflen
);
6808 memcpy (dst
, beg
, len
);
6817 input
= build_string (dst
- str
, str
);
6820 input
= build_string (strlen (buf
), buf
);
6823 input
= build_string (constraint_len
- 1, constraint
+ 1);
6827 input
= build_tree_list (build_tree_list (NULL_TREE
, input
),
6828 unshare_expr (TREE_VALUE (link
)));
6829 ASM_INPUTS (expr
) = chainon (ASM_INPUTS (expr
), input
);
6833 link_next
= NULL_TREE
;
6834 for (link
= ASM_INPUTS (expr
); link
; ++i
, link
= link_next
)
6836 link_next
= TREE_CHAIN (link
);
6837 constraint
= TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link
)));
6838 parse_input_constraint (&constraint
, 0, 0, noutputs
, 0,
6839 oconstraints
, &allows_mem
, &allows_reg
);
6841 /* If we can't make copies, we can only accept memory. */
6842 tree intype
= TREE_TYPE (TREE_VALUE (link
));
6843 if (intype
!= error_mark_node
6844 && (TREE_ADDRESSABLE (intype
)
6845 || !COMPLETE_TYPE_P (intype
)
6846 || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (intype
))))
6852 error ("impossible constraint in %<asm%>");
6853 error ("non-memory input %d must stay in memory", i
);
6858 /* If the operand is a memory input, it should be an lvalue. */
6859 if (!allows_reg
&& allows_mem
)
6861 tree inputv
= TREE_VALUE (link
);
6862 STRIP_NOPS (inputv
);
6863 if (TREE_CODE (inputv
) == PREDECREMENT_EXPR
6864 || TREE_CODE (inputv
) == PREINCREMENT_EXPR
6865 || TREE_CODE (inputv
) == POSTDECREMENT_EXPR
6866 || TREE_CODE (inputv
) == POSTINCREMENT_EXPR
6867 || TREE_CODE (inputv
) == MODIFY_EXPR
)
6868 TREE_VALUE (link
) = error_mark_node
;
6869 tret
= gimplify_expr (&TREE_VALUE (link
), pre_p
, post_p
,
6870 is_gimple_lvalue
, fb_lvalue
| fb_mayfail
);
6871 if (tret
!= GS_ERROR
)
6873 /* Unlike output operands, memory inputs are not guaranteed
6874 to be lvalues by the FE, and while the expressions are
6875 marked addressable there, if it is e.g. a statement
6876 expression, temporaries in it might not end up being
6877 addressable. They might be already used in the IL and thus
6878 it is too late to make them addressable now though. */
6879 tree x
= TREE_VALUE (link
);
6880 while (handled_component_p (x
))
6881 x
= TREE_OPERAND (x
, 0);
6882 if (TREE_CODE (x
) == MEM_REF
6883 && TREE_CODE (TREE_OPERAND (x
, 0)) == ADDR_EXPR
)
6884 x
= TREE_OPERAND (TREE_OPERAND (x
, 0), 0);
6886 || TREE_CODE (x
) == PARM_DECL
6887 || TREE_CODE (x
) == RESULT_DECL
)
6888 && !TREE_ADDRESSABLE (x
)
6889 && is_gimple_reg (x
))
6891 warning_at (EXPR_LOC_OR_LOC (TREE_VALUE (link
),
6893 "memory input %d is not directly addressable",
6895 prepare_gimple_addressable (&TREE_VALUE (link
), pre_p
);
6898 mark_addressable (TREE_VALUE (link
));
6899 if (tret
== GS_ERROR
)
6901 if (inputv
!= error_mark_node
)
6902 error_at (EXPR_LOC_OR_LOC (TREE_VALUE (link
), input_location
),
6903 "memory input %d is not directly addressable", i
);
6909 tret
= gimplify_expr (&TREE_VALUE (link
), pre_p
, post_p
,
6910 is_gimple_asm_val
, fb_rvalue
);
6911 if (tret
== GS_ERROR
)
6915 TREE_CHAIN (link
) = NULL_TREE
;
6916 vec_safe_push (inputs
, link
);
6919 link_next
= NULL_TREE
;
6920 for (link
= ASM_CLOBBERS (expr
); link
; ++i
, link
= link_next
)
6922 link_next
= TREE_CHAIN (link
);
6923 TREE_CHAIN (link
) = NULL_TREE
;
6924 vec_safe_push (clobbers
, link
);
6927 link_next
= NULL_TREE
;
6928 for (link
= ASM_LABELS (expr
); link
; ++i
, link
= link_next
)
6930 link_next
= TREE_CHAIN (link
);
6931 TREE_CHAIN (link
) = NULL_TREE
;
6932 vec_safe_push (labels
, link
);
6935 /* Do not add ASMs with errors to the gimple IL stream. */
6936 if (ret
!= GS_ERROR
)
6938 stmt
= gimple_build_asm_vec (TREE_STRING_POINTER (ASM_STRING (expr
)),
6939 inputs
, outputs
, clobbers
, labels
);
6941 /* asm is volatile if it was marked by the user as volatile or
6942 there are no outputs or this is an asm goto. */
6943 gimple_asm_set_volatile (stmt
,
6944 ASM_VOLATILE_P (expr
)
6947 gimple_asm_set_input (stmt
, ASM_INPUT_P (expr
));
6948 gimple_asm_set_inline (stmt
, ASM_INLINE_P (expr
));
6950 gimplify_seq_add_stmt (pre_p
, stmt
);
6956 /* Gimplify a CLEANUP_POINT_EXPR. Currently this works by adding
6957 GIMPLE_WITH_CLEANUP_EXPRs to the prequeue as we encounter cleanups while
6958 gimplifying the body, and converting them to TRY_FINALLY_EXPRs when we
6959 return to this function.
6961 FIXME should we complexify the prequeue handling instead? Or use flags
6962 for all the cleanups and let the optimizer tighten them up? The current
6963 code seems pretty fragile; it will break on a cleanup within any
6964 non-conditional nesting. But any such nesting would be broken, anyway;
6965 we can't write a TRY_FINALLY_EXPR that starts inside a nesting construct
6966 and continues out of it. We can do that at the RTL level, though, so
6967 having an optimizer to tighten up try/finally regions would be a Good
6970 static enum gimplify_status
6971 gimplify_cleanup_point_expr (tree
*expr_p
, gimple_seq
*pre_p
)
6973 gimple_stmt_iterator iter
;
6974 gimple_seq body_sequence
= NULL
;
6976 tree temp
= voidify_wrapper_expr (*expr_p
, NULL
);
6978 /* We only care about the number of conditions between the innermost
6979 CLEANUP_POINT_EXPR and the cleanup. So save and reset the count and
6980 any cleanups collected outside the CLEANUP_POINT_EXPR. */
6981 int old_conds
= gimplify_ctxp
->conditions
;
6982 gimple_seq old_cleanups
= gimplify_ctxp
->conditional_cleanups
;
6983 bool old_in_cleanup_point_expr
= gimplify_ctxp
->in_cleanup_point_expr
;
6984 gimplify_ctxp
->conditions
= 0;
6985 gimplify_ctxp
->conditional_cleanups
= NULL
;
6986 gimplify_ctxp
->in_cleanup_point_expr
= true;
6988 gimplify_stmt (&TREE_OPERAND (*expr_p
, 0), &body_sequence
);
6990 gimplify_ctxp
->conditions
= old_conds
;
6991 gimplify_ctxp
->conditional_cleanups
= old_cleanups
;
6992 gimplify_ctxp
->in_cleanup_point_expr
= old_in_cleanup_point_expr
;
6994 for (iter
= gsi_start (body_sequence
); !gsi_end_p (iter
); )
6996 gimple
*wce
= gsi_stmt (iter
);
6998 if (gimple_code (wce
) == GIMPLE_WITH_CLEANUP_EXPR
)
7000 if (gsi_one_before_end_p (iter
))
7002 /* Note that gsi_insert_seq_before and gsi_remove do not
7003 scan operands, unlike some other sequence mutators. */
7004 if (!gimple_wce_cleanup_eh_only (wce
))
7005 gsi_insert_seq_before_without_update (&iter
,
7006 gimple_wce_cleanup (wce
),
7008 gsi_remove (&iter
, true);
7015 enum gimple_try_flags kind
;
7017 if (gimple_wce_cleanup_eh_only (wce
))
7018 kind
= GIMPLE_TRY_CATCH
;
7020 kind
= GIMPLE_TRY_FINALLY
;
7021 seq
= gsi_split_seq_after (iter
);
7023 gtry
= gimple_build_try (seq
, gimple_wce_cleanup (wce
), kind
);
7024 /* Do not use gsi_replace here, as it may scan operands.
7025 We want to do a simple structural modification only. */
7026 gsi_set_stmt (&iter
, gtry
);
7027 iter
= gsi_start (gtry
->eval
);
7034 gimplify_seq_add_seq (pre_p
, body_sequence
);
7047 /* Insert a cleanup marker for gimplify_cleanup_point_expr. CLEANUP
7048 is the cleanup action required. EH_ONLY is true if the cleanup should
7049 only be executed if an exception is thrown, not on normal exit.
7050 If FORCE_UNCOND is true perform the cleanup unconditionally; this is
7051 only valid for clobbers. */
7054 gimple_push_cleanup (tree var
, tree cleanup
, bool eh_only
, gimple_seq
*pre_p
,
7055 bool force_uncond
= false)
7058 gimple_seq cleanup_stmts
= NULL
;
7060 /* Errors can result in improperly nested cleanups. Which results in
7061 confusion when trying to resolve the GIMPLE_WITH_CLEANUP_EXPR. */
7065 if (gimple_conditional_context ())
7067 /* If we're in a conditional context, this is more complex. We only
7068 want to run the cleanup if we actually ran the initialization that
7069 necessitates it, but we want to run it after the end of the
7070 conditional context. So we wrap the try/finally around the
7071 condition and use a flag to determine whether or not to actually
7072 run the destructor. Thus
7076 becomes (approximately)
7080 if (test) { A::A(temp); flag = 1; val = f(temp); }
7083 if (flag) A::~A(temp);
7089 gimplify_stmt (&cleanup
, &cleanup_stmts
);
7090 wce
= gimple_build_wce (cleanup_stmts
);
7091 gimplify_seq_add_stmt (&gimplify_ctxp
->conditional_cleanups
, wce
);
7095 tree flag
= create_tmp_var (boolean_type_node
, "cleanup");
7096 gassign
*ffalse
= gimple_build_assign (flag
, boolean_false_node
);
7097 gassign
*ftrue
= gimple_build_assign (flag
, boolean_true_node
);
7099 cleanup
= build3 (COND_EXPR
, void_type_node
, flag
, cleanup
, NULL
);
7100 gimplify_stmt (&cleanup
, &cleanup_stmts
);
7101 wce
= gimple_build_wce (cleanup_stmts
);
7102 gimple_wce_set_cleanup_eh_only (wce
, eh_only
);
7104 gimplify_seq_add_stmt (&gimplify_ctxp
->conditional_cleanups
, ffalse
);
7105 gimplify_seq_add_stmt (&gimplify_ctxp
->conditional_cleanups
, wce
);
7106 gimplify_seq_add_stmt (pre_p
, ftrue
);
7108 /* Because of this manipulation, and the EH edges that jump
7109 threading cannot redirect, the temporary (VAR) will appear
7110 to be used uninitialized. Don't warn. */
7111 suppress_warning (var
, OPT_Wuninitialized
);
7116 gimplify_stmt (&cleanup
, &cleanup_stmts
);
7117 wce
= gimple_build_wce (cleanup_stmts
);
7118 gimple_wce_set_cleanup_eh_only (wce
, eh_only
);
7119 gimplify_seq_add_stmt (pre_p
, wce
);
7123 /* Gimplify a TARGET_EXPR which doesn't appear on the rhs of an INIT_EXPR. */
7125 static enum gimplify_status
7126 gimplify_target_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
)
7128 tree targ
= *expr_p
;
7129 tree temp
= TARGET_EXPR_SLOT (targ
);
7130 tree init
= TARGET_EXPR_INITIAL (targ
);
7131 enum gimplify_status ret
;
7133 bool unpoison_empty_seq
= false;
7134 gimple_stmt_iterator unpoison_it
;
7138 gimple_seq init_pre_p
= NULL
;
7140 /* TARGET_EXPR temps aren't part of the enclosing block, so add it
7141 to the temps list. Handle also variable length TARGET_EXPRs. */
7142 if (!poly_int_tree_p (DECL_SIZE (temp
)))
7144 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (temp
)))
7145 gimplify_type_sizes (TREE_TYPE (temp
), &init_pre_p
);
7146 /* FIXME: this is correct only when the size of the type does
7147 not depend on expressions evaluated in init. */
7148 gimplify_vla_decl (temp
, &init_pre_p
);
7152 /* Save location where we need to place unpoisoning. It's possible
7153 that a variable will be converted to needs_to_live_in_memory. */
7154 unpoison_it
= gsi_last (*pre_p
);
7155 unpoison_empty_seq
= gsi_end_p (unpoison_it
);
7157 gimple_add_tmp_var (temp
);
7160 /* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the
7161 expression is supposed to initialize the slot. */
7162 if (VOID_TYPE_P (TREE_TYPE (init
)))
7163 ret
= gimplify_expr (&init
, &init_pre_p
, post_p
, is_gimple_stmt
,
7167 tree init_expr
= build2 (INIT_EXPR
, void_type_node
, temp
, init
);
7169 ret
= gimplify_expr (&init
, &init_pre_p
, post_p
, is_gimple_stmt
,
7172 ggc_free (init_expr
);
7174 if (ret
== GS_ERROR
)
7176 /* PR c++/28266 Make sure this is expanded only once. */
7177 TARGET_EXPR_INITIAL (targ
) = NULL_TREE
;
7182 gimplify_and_add (init
, &init_pre_p
);
7184 /* Add a clobber for the temporary going out of scope, like
7185 gimplify_bind_expr. But only if we did not promote the
7186 temporary to static storage. */
7187 if (gimplify_ctxp
->in_cleanup_point_expr
7188 && !TREE_STATIC (temp
)
7189 && needs_to_live_in_memory (temp
))
7191 if (flag_stack_reuse
== SR_ALL
)
7193 tree clobber
= build_clobber (TREE_TYPE (temp
), CLOBBER_EOL
);
7194 clobber
= build2 (MODIFY_EXPR
, TREE_TYPE (temp
), temp
, clobber
);
7195 gimple_push_cleanup (temp
, clobber
, false, pre_p
, true);
7197 if (asan_poisoned_variables
7198 && DECL_ALIGN (temp
) <= MAX_SUPPORTED_STACK_ALIGNMENT
7199 && !TREE_STATIC (temp
)
7200 && dbg_cnt (asan_use_after_scope
)
7201 && !gimplify_omp_ctxp
)
7203 tree asan_cleanup
= build_asan_poison_call_expr (temp
);
7206 if (unpoison_empty_seq
)
7207 unpoison_it
= gsi_start (*pre_p
);
7209 asan_poison_variable (temp
, false, &unpoison_it
,
7210 unpoison_empty_seq
);
7211 gimple_push_cleanup (temp
, asan_cleanup
, false, pre_p
);
7216 gimple_seq_add_seq (pre_p
, init_pre_p
);
7218 /* If needed, push the cleanup for the temp. */
7219 if (TARGET_EXPR_CLEANUP (targ
))
7220 gimple_push_cleanup (temp
, TARGET_EXPR_CLEANUP (targ
),
7221 CLEANUP_EH_ONLY (targ
), pre_p
);
7223 /* Only expand this once. */
7224 TREE_OPERAND (targ
, 3) = init
;
7225 TARGET_EXPR_INITIAL (targ
) = NULL_TREE
;
7228 /* We should have expanded this before. */
7229 gcc_assert (DECL_SEEN_IN_BIND_EXPR_P (temp
));
7235 /* Gimplification of expression trees. */
7237 /* Gimplify an expression which appears at statement context. The
7238 corresponding GIMPLE statements are added to *SEQ_P. If *SEQ_P is
7239 NULL, a new sequence is allocated.
7241 Return true if we actually added a statement to the queue. */
7244 gimplify_stmt (tree
*stmt_p
, gimple_seq
*seq_p
)
7246 gimple_seq_node last
;
7248 last
= gimple_seq_last (*seq_p
);
7249 gimplify_expr (stmt_p
, seq_p
, NULL
, is_gimple_stmt
, fb_none
);
7250 return last
!= gimple_seq_last (*seq_p
);
7253 /* Add FIRSTPRIVATE entries for DECL in the OpenMP the surrounding parallels
7254 to CTX. If entries already exist, force them to be some flavor of private.
7255 If there is no enclosing parallel, do nothing. */
7258 omp_firstprivatize_variable (struct gimplify_omp_ctx
*ctx
, tree decl
)
7262 if (decl
== NULL
|| !DECL_P (decl
) || ctx
->region_type
== ORT_NONE
)
7267 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
)decl
);
7270 if (n
->value
& GOVD_SHARED
)
7271 n
->value
= GOVD_FIRSTPRIVATE
| (n
->value
& GOVD_SEEN
);
7272 else if (n
->value
& GOVD_MAP
)
7273 n
->value
|= GOVD_MAP_TO_ONLY
;
7277 else if ((ctx
->region_type
& ORT_TARGET
) != 0)
7279 if (ctx
->defaultmap
[GDMK_SCALAR
] & GOVD_FIRSTPRIVATE
)
7280 omp_add_variable (ctx
, decl
, GOVD_FIRSTPRIVATE
);
7282 omp_add_variable (ctx
, decl
, GOVD_MAP
| GOVD_MAP_TO_ONLY
);
7284 else if (ctx
->region_type
!= ORT_WORKSHARE
7285 && ctx
->region_type
!= ORT_TASKGROUP
7286 && ctx
->region_type
!= ORT_SIMD
7287 && ctx
->region_type
!= ORT_ACC
7288 && !(ctx
->region_type
& ORT_TARGET_DATA
))
7289 omp_add_variable (ctx
, decl
, GOVD_FIRSTPRIVATE
);
7291 ctx
= ctx
->outer_context
;
7296 /* Similarly for each of the type sizes of TYPE. */
7299 omp_firstprivatize_type_sizes (struct gimplify_omp_ctx
*ctx
, tree type
)
7301 if (type
== NULL
|| type
== error_mark_node
)
7303 type
= TYPE_MAIN_VARIANT (type
);
7305 if (ctx
->privatized_types
->add (type
))
7308 switch (TREE_CODE (type
))
7314 case FIXED_POINT_TYPE
:
7315 omp_firstprivatize_variable (ctx
, TYPE_MIN_VALUE (type
));
7316 omp_firstprivatize_variable (ctx
, TYPE_MAX_VALUE (type
));
7320 omp_firstprivatize_type_sizes (ctx
, TREE_TYPE (type
));
7321 omp_firstprivatize_type_sizes (ctx
, TYPE_DOMAIN (type
));
7326 case QUAL_UNION_TYPE
:
7329 for (field
= TYPE_FIELDS (type
); field
; field
= DECL_CHAIN (field
))
7330 if (TREE_CODE (field
) == FIELD_DECL
)
7332 omp_firstprivatize_variable (ctx
, DECL_FIELD_OFFSET (field
));
7333 omp_firstprivatize_type_sizes (ctx
, TREE_TYPE (field
));
7339 case REFERENCE_TYPE
:
7340 omp_firstprivatize_type_sizes (ctx
, TREE_TYPE (type
));
7347 omp_firstprivatize_variable (ctx
, TYPE_SIZE (type
));
7348 omp_firstprivatize_variable (ctx
, TYPE_SIZE_UNIT (type
));
7349 lang_hooks
.types
.omp_firstprivatize_type_sizes (ctx
, type
);
7352 /* Add an entry for DECL in the OMP context CTX with FLAGS. */
7355 omp_add_variable (struct gimplify_omp_ctx
*ctx
, tree decl
, unsigned int flags
)
7358 unsigned int nflags
;
7361 if (error_operand_p (decl
) || ctx
->region_type
== ORT_NONE
)
7364 /* Never elide decls whose type has TREE_ADDRESSABLE set. This means
7365 there are constructors involved somewhere. Exception is a shared clause,
7366 there is nothing privatized in that case. */
7367 if ((flags
& GOVD_SHARED
) == 0
7368 && (TREE_ADDRESSABLE (TREE_TYPE (decl
))
7369 || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl
))))
7372 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
)decl
);
7373 if (n
!= NULL
&& (n
->value
& GOVD_DATA_SHARE_CLASS
) != 0)
7375 /* We shouldn't be re-adding the decl with the same data
7377 gcc_assert ((n
->value
& GOVD_DATA_SHARE_CLASS
& flags
) == 0);
7378 nflags
= n
->value
| flags
;
7379 /* The only combination of data sharing classes we should see is
7380 FIRSTPRIVATE and LASTPRIVATE. However, OpenACC permits
7381 reduction variables to be used in data sharing clauses. */
7382 gcc_assert ((ctx
->region_type
& ORT_ACC
) != 0
7383 || ((nflags
& GOVD_DATA_SHARE_CLASS
)
7384 == (GOVD_FIRSTPRIVATE
| GOVD_LASTPRIVATE
))
7385 || (flags
& GOVD_DATA_SHARE_CLASS
) == 0);
7390 /* When adding a variable-sized variable, we have to handle all sorts
7391 of additional bits of data: the pointer replacement variable, and
7392 the parameters of the type. */
7393 if (DECL_SIZE (decl
) && TREE_CODE (DECL_SIZE (decl
)) != INTEGER_CST
)
7395 /* Add the pointer replacement variable as PRIVATE if the variable
7396 replacement is private, else FIRSTPRIVATE since we'll need the
7397 address of the original variable either for SHARED, or for the
7398 copy into or out of the context. */
7399 if (!(flags
& GOVD_LOCAL
) && ctx
->region_type
!= ORT_TASKGROUP
)
7401 if (flags
& GOVD_MAP
)
7402 nflags
= GOVD_MAP
| GOVD_MAP_TO_ONLY
| GOVD_EXPLICIT
;
7403 else if (flags
& GOVD_PRIVATE
)
7404 nflags
= GOVD_PRIVATE
;
7405 else if (((ctx
->region_type
& (ORT_TARGET
| ORT_TARGET_DATA
)) != 0
7406 && (flags
& GOVD_FIRSTPRIVATE
))
7407 || (ctx
->region_type
== ORT_TARGET_DATA
7408 && (flags
& GOVD_DATA_SHARE_CLASS
) == 0))
7409 nflags
= GOVD_PRIVATE
| GOVD_EXPLICIT
;
7411 nflags
= GOVD_FIRSTPRIVATE
;
7412 nflags
|= flags
& GOVD_SEEN
;
7413 t
= DECL_VALUE_EXPR (decl
);
7414 gcc_assert (INDIRECT_REF_P (t
));
7415 t
= TREE_OPERAND (t
, 0);
7416 gcc_assert (DECL_P (t
));
7417 omp_add_variable (ctx
, t
, nflags
);
7420 /* Add all of the variable and type parameters (which should have
7421 been gimplified to a formal temporary) as FIRSTPRIVATE. */
7422 omp_firstprivatize_variable (ctx
, DECL_SIZE_UNIT (decl
));
7423 omp_firstprivatize_variable (ctx
, DECL_SIZE (decl
));
7424 omp_firstprivatize_type_sizes (ctx
, TREE_TYPE (decl
));
7426 /* The variable-sized variable itself is never SHARED, only some form
7427 of PRIVATE. The sharing would take place via the pointer variable
7428 which we remapped above. */
7429 if (flags
& GOVD_SHARED
)
7430 flags
= GOVD_SHARED
| GOVD_DEBUG_PRIVATE
7431 | (flags
& (GOVD_SEEN
| GOVD_EXPLICIT
));
7433 /* We're going to make use of the TYPE_SIZE_UNIT at least in the
7434 alloca statement we generate for the variable, so make sure it
7435 is available. This isn't automatically needed for the SHARED
7436 case, since we won't be allocating local storage then.
7437 For local variables TYPE_SIZE_UNIT might not be gimplified yet,
7438 in this case omp_notice_variable will be called later
7439 on when it is gimplified. */
7440 else if (! (flags
& (GOVD_LOCAL
| GOVD_MAP
))
7441 && DECL_P (TYPE_SIZE_UNIT (TREE_TYPE (decl
))))
7442 omp_notice_variable (ctx
, TYPE_SIZE_UNIT (TREE_TYPE (decl
)), true);
7444 else if ((flags
& (GOVD_MAP
| GOVD_LOCAL
)) == 0
7445 && omp_privatize_by_reference (decl
))
7447 omp_firstprivatize_type_sizes (ctx
, TREE_TYPE (decl
));
7449 /* Similar to the direct variable sized case above, we'll need the
7450 size of references being privatized. */
7451 if ((flags
& GOVD_SHARED
) == 0)
7453 t
= TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl
)));
7454 if (t
&& DECL_P (t
))
7455 omp_notice_variable (ctx
, t
, true);
7462 splay_tree_insert (ctx
->variables
, (splay_tree_key
)decl
, flags
);
7464 /* For reductions clauses in OpenACC loop directives, by default create a
7465 copy clause on the enclosing parallel construct for carrying back the
7467 if (ctx
->region_type
== ORT_ACC
&& (flags
& GOVD_REDUCTION
))
7469 struct gimplify_omp_ctx
*outer_ctx
= ctx
->outer_context
;
7472 n
= splay_tree_lookup (outer_ctx
->variables
, (splay_tree_key
)decl
);
7475 /* Ignore local variables and explicitly declared clauses. */
7476 if (n
->value
& (GOVD_LOCAL
| GOVD_EXPLICIT
))
7478 else if (outer_ctx
->region_type
== ORT_ACC_KERNELS
)
7480 /* According to the OpenACC spec, such a reduction variable
7481 should already have a copy map on a kernels construct,
7482 verify that here. */
7483 gcc_assert (!(n
->value
& GOVD_FIRSTPRIVATE
)
7484 && (n
->value
& GOVD_MAP
));
7486 else if (outer_ctx
->region_type
== ORT_ACC_PARALLEL
)
7488 /* Remove firstprivate and make it a copy map. */
7489 n
->value
&= ~GOVD_FIRSTPRIVATE
;
7490 n
->value
|= GOVD_MAP
;
7493 else if (outer_ctx
->region_type
== ORT_ACC_PARALLEL
)
7495 splay_tree_insert (outer_ctx
->variables
, (splay_tree_key
)decl
,
7496 GOVD_MAP
| GOVD_SEEN
);
7499 outer_ctx
= outer_ctx
->outer_context
;
7504 /* Notice a threadprivate variable DECL used in OMP context CTX.
7505 This just prints out diagnostics about threadprivate variable uses
7506 in untied tasks. If DECL2 is non-NULL, prevent this warning
7507 on that variable. */
7510 omp_notice_threadprivate_variable (struct gimplify_omp_ctx
*ctx
, tree decl
,
7514 struct gimplify_omp_ctx
*octx
;
7516 for (octx
= ctx
; octx
; octx
= octx
->outer_context
)
7517 if ((octx
->region_type
& ORT_TARGET
) != 0
7518 || octx
->order_concurrent
)
7520 n
= splay_tree_lookup (octx
->variables
, (splay_tree_key
)decl
);
7523 if (octx
->order_concurrent
)
7525 error ("threadprivate variable %qE used in a region with"
7526 " %<order(concurrent)%> clause", DECL_NAME (decl
));
7527 inform (octx
->location
, "enclosing region");
7531 error ("threadprivate variable %qE used in target region",
7533 inform (octx
->location
, "enclosing target region");
7535 splay_tree_insert (octx
->variables
, (splay_tree_key
)decl
, 0);
7538 splay_tree_insert (octx
->variables
, (splay_tree_key
)decl2
, 0);
7541 if (ctx
->region_type
!= ORT_UNTIED_TASK
)
7543 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
)decl
);
7546 error ("threadprivate variable %qE used in untied task",
7548 inform (ctx
->location
, "enclosing task");
7549 splay_tree_insert (ctx
->variables
, (splay_tree_key
)decl
, 0);
7552 splay_tree_insert (ctx
->variables
, (splay_tree_key
)decl2
, 0);
7556 /* Return true if global var DECL is device resident. */
7559 device_resident_p (tree decl
)
7561 tree attr
= lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (decl
));
7566 for (tree t
= TREE_VALUE (attr
); t
; t
= TREE_PURPOSE (t
))
7568 tree c
= TREE_VALUE (t
);
7569 if (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_DEVICE_RESIDENT
)
7576 /* Return true if DECL has an ACC DECLARE attribute. */
7579 is_oacc_declared (tree decl
)
7581 tree t
= TREE_CODE (decl
) == MEM_REF
? TREE_OPERAND (decl
, 0) : decl
;
7582 tree declared
= lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (t
));
7583 return declared
!= NULL_TREE
;
7586 /* Determine outer default flags for DECL mentioned in an OMP region
7587 but not declared in an enclosing clause.
7589 ??? Some compiler-generated variables (like SAVE_EXPRs) could be
7590 remapped firstprivate instead of shared. To some extent this is
7591 addressed in omp_firstprivatize_type_sizes, but not
7595 omp_default_clause (struct gimplify_omp_ctx
*ctx
, tree decl
,
7596 bool in_code
, unsigned flags
)
7598 enum omp_clause_default_kind default_kind
= ctx
->default_kind
;
7599 enum omp_clause_default_kind kind
;
7601 kind
= lang_hooks
.decls
.omp_predetermined_sharing (decl
);
7602 if (ctx
->region_type
& ORT_TASK
)
7604 tree detach_clause
= omp_find_clause (ctx
->clauses
, OMP_CLAUSE_DETACH
);
7606 /* The event-handle specified by a detach clause should always be firstprivate,
7607 regardless of the current default. */
7608 if (detach_clause
&& OMP_CLAUSE_DECL (detach_clause
) == decl
)
7609 kind
= OMP_CLAUSE_DEFAULT_FIRSTPRIVATE
;
7611 if (kind
!= OMP_CLAUSE_DEFAULT_UNSPECIFIED
)
7612 default_kind
= kind
;
7613 else if (VAR_P (decl
) && TREE_STATIC (decl
) && DECL_IN_CONSTANT_POOL (decl
))
7614 default_kind
= OMP_CLAUSE_DEFAULT_SHARED
;
7615 /* For C/C++ default({,first}private), variables with static storage duration
7616 declared in a namespace or global scope and referenced in construct
7617 must be explicitly specified, i.e. acts as default(none). */
7618 else if ((default_kind
== OMP_CLAUSE_DEFAULT_PRIVATE
7619 || default_kind
== OMP_CLAUSE_DEFAULT_FIRSTPRIVATE
)
7621 && is_global_var (decl
)
7622 && (DECL_FILE_SCOPE_P (decl
)
7623 || (DECL_CONTEXT (decl
)
7624 && TREE_CODE (DECL_CONTEXT (decl
)) == NAMESPACE_DECL
))
7625 && !lang_GNU_Fortran ())
7626 default_kind
= OMP_CLAUSE_DEFAULT_NONE
;
7628 switch (default_kind
)
7630 case OMP_CLAUSE_DEFAULT_NONE
:
7634 if (ctx
->region_type
& ORT_PARALLEL
)
7636 else if ((ctx
->region_type
& ORT_TASKLOOP
) == ORT_TASKLOOP
)
7638 else if (ctx
->region_type
& ORT_TASK
)
7640 else if (ctx
->region_type
& ORT_TEAMS
)
7645 error ("%qE not specified in enclosing %qs",
7646 DECL_NAME (lang_hooks
.decls
.omp_report_decl (decl
)), rtype
);
7647 inform (ctx
->location
, "enclosing %qs", rtype
);
7650 case OMP_CLAUSE_DEFAULT_SHARED
:
7651 flags
|= GOVD_SHARED
;
7653 case OMP_CLAUSE_DEFAULT_PRIVATE
:
7654 flags
|= GOVD_PRIVATE
;
7656 case OMP_CLAUSE_DEFAULT_FIRSTPRIVATE
:
7657 flags
|= GOVD_FIRSTPRIVATE
;
7659 case OMP_CLAUSE_DEFAULT_UNSPECIFIED
:
7660 /* decl will be either GOVD_FIRSTPRIVATE or GOVD_SHARED. */
7661 gcc_assert ((ctx
->region_type
& ORT_TASK
) != 0);
7662 if (struct gimplify_omp_ctx
*octx
= ctx
->outer_context
)
7664 omp_notice_variable (octx
, decl
, in_code
);
7665 for (; octx
; octx
= octx
->outer_context
)
7669 n2
= splay_tree_lookup (octx
->variables
, (splay_tree_key
) decl
);
7670 if ((octx
->region_type
& (ORT_TARGET_DATA
| ORT_TARGET
)) != 0
7671 && (n2
== NULL
|| (n2
->value
& GOVD_DATA_SHARE_CLASS
) == 0))
7673 if (n2
&& (n2
->value
& GOVD_DATA_SHARE_CLASS
) != GOVD_SHARED
)
7675 flags
|= GOVD_FIRSTPRIVATE
;
7678 if ((octx
->region_type
& (ORT_PARALLEL
| ORT_TEAMS
)) != 0)
7680 flags
|= GOVD_SHARED
;
7686 if (TREE_CODE (decl
) == PARM_DECL
7687 || (!is_global_var (decl
)
7688 && DECL_CONTEXT (decl
) == current_function_decl
))
7689 flags
|= GOVD_FIRSTPRIVATE
;
7691 flags
|= GOVD_SHARED
;
7702 /* Return string name for types of OpenACC constructs from ORT_* values. */
7705 oacc_region_type_name (enum omp_region_type region_type
)
7707 switch (region_type
)
7711 case ORT_ACC_PARALLEL
:
7713 case ORT_ACC_KERNELS
:
7715 case ORT_ACC_SERIAL
:
7722 /* Determine outer default flags for DECL mentioned in an OACC region
7723 but not declared in an enclosing clause. */
7726 oacc_default_clause (struct gimplify_omp_ctx
*ctx
, tree decl
, unsigned flags
)
7728 struct gimplify_omp_ctx
*ctx_default
= ctx
;
7729 /* If no 'default' clause appears on this compute construct... */
7730 if (ctx_default
->default_kind
== OMP_CLAUSE_DEFAULT_SHARED
)
7732 /* ..., see if one appears on a lexically containing 'data'
7734 while ((ctx_default
= ctx_default
->outer_context
))
7736 if (ctx_default
->region_type
== ORT_ACC_DATA
7737 && ctx_default
->default_kind
!= OMP_CLAUSE_DEFAULT_SHARED
)
7740 /* If not, reset. */
7745 bool on_device
= false;
7746 bool is_private
= false;
7747 bool declared
= is_oacc_declared (decl
);
7748 tree type
= TREE_TYPE (decl
);
7750 if (omp_privatize_by_reference (decl
))
7751 type
= TREE_TYPE (type
);
7753 /* For Fortran COMMON blocks, only used variables in those blocks are
7754 transfered and remapped. The block itself will have a private clause to
7755 avoid transfering the data twice.
7756 The hook evaluates to false by default. For a variable in Fortran's COMMON
7757 or EQUIVALENCE block, returns 'true' (as we have shared=false) - as only
7758 the variables in such a COMMON/EQUIVALENCE block shall be privatized not
7759 the whole block. For C++ and Fortran, it can also be true under certain
7760 other conditions, if DECL_HAS_VALUE_EXPR. */
7761 if (RECORD_OR_UNION_TYPE_P (type
))
7762 is_private
= lang_hooks
.decls
.omp_disregard_value_expr (decl
, false);
7764 if ((ctx
->region_type
& (ORT_ACC_PARALLEL
| ORT_ACC_KERNELS
)) != 0
7765 && is_global_var (decl
)
7766 && device_resident_p (decl
)
7770 flags
|= GOVD_MAP_TO_ONLY
;
7773 switch (ctx
->region_type
)
7775 case ORT_ACC_KERNELS
:
7777 flags
|= GOVD_FIRSTPRIVATE
;
7778 else if (AGGREGATE_TYPE_P (type
))
7780 /* Aggregates default to 'present_or_copy', or 'present'. */
7781 if (ctx_default
->default_kind
!= OMP_CLAUSE_DEFAULT_PRESENT
)
7784 flags
|= GOVD_MAP
| GOVD_MAP_FORCE_PRESENT
;
7787 /* Scalars default to 'copy'. */
7788 flags
|= GOVD_MAP
| GOVD_MAP_FORCE
;
7792 case ORT_ACC_PARALLEL
:
7793 case ORT_ACC_SERIAL
:
7795 flags
|= GOVD_FIRSTPRIVATE
;
7796 else if (on_device
|| declared
)
7798 else if (AGGREGATE_TYPE_P (type
))
7800 /* Aggregates default to 'present_or_copy', or 'present'. */
7801 if (ctx_default
->default_kind
!= OMP_CLAUSE_DEFAULT_PRESENT
)
7804 flags
|= GOVD_MAP
| GOVD_MAP_FORCE_PRESENT
;
7807 /* Scalars default to 'firstprivate'. */
7808 flags
|= GOVD_FIRSTPRIVATE
;
7816 if (DECL_ARTIFICIAL (decl
))
7817 ; /* We can get compiler-generated decls, and should not complain
7819 else if (ctx_default
->default_kind
== OMP_CLAUSE_DEFAULT_NONE
)
7821 error ("%qE not specified in enclosing OpenACC %qs construct",
7822 DECL_NAME (lang_hooks
.decls
.omp_report_decl (decl
)),
7823 oacc_region_type_name (ctx
->region_type
));
7824 if (ctx_default
!= ctx
)
7825 inform (ctx
->location
, "enclosing OpenACC %qs construct and",
7826 oacc_region_type_name (ctx
->region_type
));
7827 inform (ctx_default
->location
,
7828 "enclosing OpenACC %qs construct with %qs clause",
7829 oacc_region_type_name (ctx_default
->region_type
),
7832 else if (ctx_default
->default_kind
== OMP_CLAUSE_DEFAULT_PRESENT
)
7833 ; /* Handled above. */
7835 gcc_checking_assert (ctx_default
->default_kind
== OMP_CLAUSE_DEFAULT_SHARED
);
7840 /* Record the fact that DECL was used within the OMP context CTX.
7841 IN_CODE is true when real code uses DECL, and false when we should
7842 merely emit default(none) errors. Return true if DECL is going to
7843 be remapped and thus DECL shouldn't be gimplified into its
7844 DECL_VALUE_EXPR (if any). */
7847 omp_notice_variable (struct gimplify_omp_ctx
*ctx
, tree decl
, bool in_code
)
7850 unsigned flags
= in_code
? GOVD_SEEN
: 0;
7851 bool ret
= false, shared
;
7853 if (error_operand_p (decl
))
7856 if (ctx
->region_type
== ORT_NONE
)
7857 return lang_hooks
.decls
.omp_disregard_value_expr (decl
, false);
7859 if (is_global_var (decl
))
7861 /* Threadprivate variables are predetermined. */
7862 if (DECL_THREAD_LOCAL_P (decl
))
7863 return omp_notice_threadprivate_variable (ctx
, decl
, NULL_TREE
);
7865 if (DECL_HAS_VALUE_EXPR_P (decl
))
7867 if (ctx
->region_type
& ORT_ACC
)
7868 /* For OpenACC, defer expansion of value to avoid transfering
7869 privatized common block data instead of im-/explicitly transfered
7870 variables which are in common blocks. */
7874 tree value
= get_base_address (DECL_VALUE_EXPR (decl
));
7876 if (value
&& DECL_P (value
) && DECL_THREAD_LOCAL_P (value
))
7877 return omp_notice_threadprivate_variable (ctx
, decl
, value
);
7881 if (gimplify_omp_ctxp
->outer_context
== NULL
7883 && oacc_get_fn_attrib (current_function_decl
))
7885 location_t loc
= DECL_SOURCE_LOCATION (decl
);
7887 if (lookup_attribute ("omp declare target link",
7888 DECL_ATTRIBUTES (decl
)))
7891 "%qE with %<link%> clause used in %<routine%> function",
7895 else if (!lookup_attribute ("omp declare target",
7896 DECL_ATTRIBUTES (decl
)))
7899 "%qE requires a %<declare%> directive for use "
7900 "in a %<routine%> function", DECL_NAME (decl
));
7906 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
)decl
);
7907 if ((ctx
->region_type
& ORT_TARGET
) != 0)
7909 if (ctx
->region_type
& ORT_ACC
)
7910 /* For OpenACC, as remarked above, defer expansion. */
7915 ret
= lang_hooks
.decls
.omp_disregard_value_expr (decl
, shared
);
7918 unsigned nflags
= flags
;
7919 if ((ctx
->region_type
& ORT_ACC
) == 0)
7921 bool is_declare_target
= false;
7922 if (is_global_var (decl
)
7923 && varpool_node::get_create (decl
)->offloadable
)
7925 struct gimplify_omp_ctx
*octx
;
7926 for (octx
= ctx
->outer_context
;
7927 octx
; octx
= octx
->outer_context
)
7929 n
= splay_tree_lookup (octx
->variables
,
7930 (splay_tree_key
)decl
);
7932 && (n
->value
& GOVD_DATA_SHARE_CLASS
) != GOVD_SHARED
7933 && (n
->value
& GOVD_DATA_SHARE_CLASS
) != 0)
7936 is_declare_target
= octx
== NULL
;
7938 if (!is_declare_target
)
7941 enum omp_clause_defaultmap_kind kind
;
7942 if (lang_hooks
.decls
.omp_allocatable_p (decl
))
7943 gdmk
= GDMK_ALLOCATABLE
;
7944 else if (lang_hooks
.decls
.omp_scalar_target_p (decl
))
7945 gdmk
= GDMK_SCALAR_TARGET
;
7946 else if (lang_hooks
.decls
.omp_scalar_p (decl
, false))
7948 else if (TREE_CODE (TREE_TYPE (decl
)) == POINTER_TYPE
7949 || (TREE_CODE (TREE_TYPE (decl
)) == REFERENCE_TYPE
7950 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl
)))
7952 gdmk
= GDMK_POINTER
;
7954 gdmk
= GDMK_AGGREGATE
;
7955 kind
= lang_hooks
.decls
.omp_predetermined_mapping (decl
);
7956 if (kind
!= OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
)
7958 if (kind
== OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE
)
7959 nflags
|= GOVD_FIRSTPRIVATE
;
7960 else if (kind
== OMP_CLAUSE_DEFAULTMAP_TO
)
7961 nflags
|= GOVD_MAP
| GOVD_MAP_TO_ONLY
;
7965 else if (ctx
->defaultmap
[gdmk
] == 0)
7967 tree d
= lang_hooks
.decls
.omp_report_decl (decl
);
7968 error ("%qE not specified in enclosing %<target%>",
7970 inform (ctx
->location
, "enclosing %<target%>");
7972 else if (ctx
->defaultmap
[gdmk
]
7973 & (GOVD_MAP_0LEN_ARRAY
| GOVD_FIRSTPRIVATE
))
7974 nflags
|= ctx
->defaultmap
[gdmk
];
7975 else if (ctx
->defaultmap
[gdmk
] & GOVD_MAP_FORCE_PRESENT
)
7977 gcc_assert (ctx
->defaultmap
[gdmk
] & GOVD_MAP
);
7978 nflags
|= ctx
->defaultmap
[gdmk
] | GOVD_MAP_ALLOC_ONLY
;
7982 gcc_assert (ctx
->defaultmap
[gdmk
] & GOVD_MAP
);
7983 nflags
|= ctx
->defaultmap
[gdmk
] & ~GOVD_MAP
;
7988 struct gimplify_omp_ctx
*octx
= ctx
->outer_context
;
7989 if ((ctx
->region_type
& ORT_ACC
) && octx
)
7991 /* Look in outer OpenACC contexts, to see if there's a
7992 data attribute for this variable. */
7993 omp_notice_variable (octx
, decl
, in_code
);
7995 for (; octx
; octx
= octx
->outer_context
)
7997 if (!(octx
->region_type
& (ORT_TARGET_DATA
| ORT_TARGET
)))
8000 = splay_tree_lookup (octx
->variables
,
8001 (splay_tree_key
) decl
);
8004 if (octx
->region_type
== ORT_ACC_HOST_DATA
)
8005 error ("variable %qE declared in enclosing "
8006 "%<host_data%> region", DECL_NAME (decl
));
8008 if (octx
->region_type
== ORT_ACC_DATA
8009 && (n2
->value
& GOVD_MAP_0LEN_ARRAY
))
8010 nflags
|= GOVD_MAP_0LEN_ARRAY
;
8016 if ((nflags
& ~(GOVD_MAP_TO_ONLY
| GOVD_MAP_FROM_ONLY
8017 | GOVD_MAP_ALLOC_ONLY
)) == flags
)
8019 tree type
= TREE_TYPE (decl
);
8021 if (gimplify_omp_ctxp
->target_firstprivatize_array_bases
8022 && omp_privatize_by_reference (decl
))
8023 type
= TREE_TYPE (type
);
8024 if (!omp_mappable_type (type
))
8026 error ("%qD referenced in target region does not have "
8027 "a mappable type", decl
);
8028 nflags
|= GOVD_MAP
| GOVD_EXPLICIT
;
8032 if ((ctx
->region_type
& ORT_ACC
) != 0)
8033 nflags
= oacc_default_clause (ctx
, decl
, flags
);
8039 omp_add_variable (ctx
, decl
, nflags
);
8043 /* If nothing changed, there's nothing left to do. */
8044 if ((n
->value
& flags
) == flags
)
8054 if (ctx
->region_type
== ORT_WORKSHARE
8055 || ctx
->region_type
== ORT_TASKGROUP
8056 || ctx
->region_type
== ORT_SIMD
8057 || ctx
->region_type
== ORT_ACC
8058 || (ctx
->region_type
& ORT_TARGET_DATA
) != 0)
8061 flags
= omp_default_clause (ctx
, decl
, in_code
, flags
);
8063 if ((flags
& GOVD_PRIVATE
)
8064 && lang_hooks
.decls
.omp_private_outer_ref (decl
))
8065 flags
|= GOVD_PRIVATE_OUTER_REF
;
8067 omp_add_variable (ctx
, decl
, flags
);
8069 shared
= (flags
& GOVD_SHARED
) != 0;
8070 ret
= lang_hooks
.decls
.omp_disregard_value_expr (decl
, shared
);
8074 /* Don't mark as GOVD_SEEN addressable temporaries seen only in simd
8075 lb, b or incr expressions, those shouldn't be turned into simd arrays. */
8076 if (ctx
->region_type
== ORT_SIMD
8077 && ctx
->in_for_exprs
8078 && ((n
->value
& (GOVD_PRIVATE
| GOVD_SEEN
| GOVD_EXPLICIT
))
8080 flags
&= ~GOVD_SEEN
;
8082 if ((n
->value
& (GOVD_SEEN
| GOVD_LOCAL
)) == 0
8083 && (flags
& (GOVD_SEEN
| GOVD_LOCAL
)) == GOVD_SEEN
8084 && DECL_SIZE (decl
))
8086 if (TREE_CODE (DECL_SIZE (decl
)) != INTEGER_CST
)
8089 tree t
= DECL_VALUE_EXPR (decl
);
8090 gcc_assert (INDIRECT_REF_P (t
));
8091 t
= TREE_OPERAND (t
, 0);
8092 gcc_assert (DECL_P (t
));
8093 n2
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) t
);
8094 n2
->value
|= GOVD_SEEN
;
8096 else if (omp_privatize_by_reference (decl
)
8097 && TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl
)))
8098 && (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl
))))
8102 tree t
= TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl
)));
8103 gcc_assert (DECL_P (t
));
8104 n2
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) t
);
8106 omp_notice_variable (ctx
, t
, true);
8110 if (ctx
->region_type
& ORT_ACC
)
8111 /* For OpenACC, as remarked above, defer expansion. */
8114 shared
= ((flags
| n
->value
) & GOVD_SHARED
) != 0;
8115 ret
= lang_hooks
.decls
.omp_disregard_value_expr (decl
, shared
);
8117 /* If nothing changed, there's nothing left to do. */
8118 if ((n
->value
& flags
) == flags
)
8124 /* If the variable is private in the current context, then we don't
8125 need to propagate anything to an outer context. */
8126 if ((flags
& GOVD_PRIVATE
) && !(flags
& GOVD_PRIVATE_OUTER_REF
))
8128 if ((flags
& (GOVD_LINEAR
| GOVD_LINEAR_LASTPRIVATE_NO_OUTER
))
8129 == (GOVD_LINEAR
| GOVD_LINEAR_LASTPRIVATE_NO_OUTER
))
8131 if ((flags
& (GOVD_FIRSTPRIVATE
| GOVD_LASTPRIVATE
8132 | GOVD_LINEAR_LASTPRIVATE_NO_OUTER
))
8133 == (GOVD_LASTPRIVATE
| GOVD_LINEAR_LASTPRIVATE_NO_OUTER
))
8135 if (ctx
->outer_context
8136 && omp_notice_variable (ctx
->outer_context
, decl
, in_code
))
8141 /* Verify that DECL is private within CTX. If there's specific information
8142 to the contrary in the innermost scope, generate an error. */
8145 omp_is_private (struct gimplify_omp_ctx
*ctx
, tree decl
, int simd
)
8149 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
)decl
);
8152 if (n
->value
& GOVD_SHARED
)
8154 if (ctx
== gimplify_omp_ctxp
)
8157 error ("iteration variable %qE is predetermined linear",
8160 error ("iteration variable %qE should be private",
8162 n
->value
= GOVD_PRIVATE
;
8168 else if ((n
->value
& GOVD_EXPLICIT
) != 0
8169 && (ctx
== gimplify_omp_ctxp
8170 || (ctx
->region_type
== ORT_COMBINED_PARALLEL
8171 && gimplify_omp_ctxp
->outer_context
== ctx
)))
8173 if ((n
->value
& GOVD_FIRSTPRIVATE
) != 0)
8174 error ("iteration variable %qE should not be firstprivate",
8176 else if ((n
->value
& GOVD_REDUCTION
) != 0)
8177 error ("iteration variable %qE should not be reduction",
8179 else if (simd
!= 1 && (n
->value
& GOVD_LINEAR
) != 0)
8180 error ("iteration variable %qE should not be linear",
8183 return (ctx
== gimplify_omp_ctxp
8184 || (ctx
->region_type
== ORT_COMBINED_PARALLEL
8185 && gimplify_omp_ctxp
->outer_context
== ctx
));
8188 if (ctx
->region_type
!= ORT_WORKSHARE
8189 && ctx
->region_type
!= ORT_TASKGROUP
8190 && ctx
->region_type
!= ORT_SIMD
8191 && ctx
->region_type
!= ORT_ACC
)
8193 else if (ctx
->outer_context
)
8194 return omp_is_private (ctx
->outer_context
, decl
, simd
);
8198 /* Return true if DECL is private within a parallel region
8199 that binds to the current construct's context or in parallel
8200 region's REDUCTION clause. */
8203 omp_check_private (struct gimplify_omp_ctx
*ctx
, tree decl
, bool copyprivate
)
8209 ctx
= ctx
->outer_context
;
8212 if (is_global_var (decl
))
8215 /* References might be private, but might be shared too,
8216 when checking for copyprivate, assume they might be
8217 private, otherwise assume they might be shared. */
8221 if (omp_privatize_by_reference (decl
))
8224 /* Treat C++ privatized non-static data members outside
8225 of the privatization the same. */
8226 if (omp_member_access_dummy_var (decl
))
8232 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
8234 if ((ctx
->region_type
& (ORT_TARGET
| ORT_TARGET_DATA
)) != 0
8235 && (n
== NULL
|| (n
->value
& GOVD_DATA_SHARE_CLASS
) == 0))
8237 if ((ctx
->region_type
& ORT_TARGET_DATA
) != 0
8239 || (n
->value
& GOVD_MAP
) == 0)
8246 if ((n
->value
& GOVD_LOCAL
) != 0
8247 && omp_member_access_dummy_var (decl
))
8249 return (n
->value
& GOVD_SHARED
) == 0;
8252 if (ctx
->region_type
== ORT_WORKSHARE
8253 || ctx
->region_type
== ORT_TASKGROUP
8254 || ctx
->region_type
== ORT_SIMD
8255 || ctx
->region_type
== ORT_ACC
)
8264 /* Callback for walk_tree to find a DECL_EXPR for the given DECL. */
8267 find_decl_expr (tree
*tp
, int *walk_subtrees
, void *data
)
8271 /* If this node has been visited, unmark it and keep looking. */
8272 if (TREE_CODE (t
) == DECL_EXPR
&& DECL_EXPR_DECL (t
) == (tree
) data
)
8275 if (IS_TYPE_OR_DECL_P (t
))
8281 /* Gimplify the affinity clause but effectively ignore it.
8284 if ((step > 1) ? var <= end : var > end)
8285 locatator_var_expr; */
8288 gimplify_omp_affinity (tree
*list_p
, gimple_seq
*pre_p
)
8290 tree last_iter
= NULL_TREE
;
8291 tree last_bind
= NULL_TREE
;
8292 tree label
= NULL_TREE
;
8293 tree
*last_body
= NULL
;
8294 for (tree c
= *list_p
; c
; c
= OMP_CLAUSE_CHAIN (c
))
8295 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_AFFINITY
)
8297 tree t
= OMP_CLAUSE_DECL (c
);
8298 if (TREE_CODE (t
) == TREE_LIST
8300 && TREE_CODE (TREE_PURPOSE (t
)) == TREE_VEC
)
8302 if (TREE_VALUE (t
) == null_pointer_node
)
8304 if (TREE_PURPOSE (t
) != last_iter
)
8308 append_to_statement_list (label
, last_body
);
8309 gimplify_and_add (last_bind
, pre_p
);
8310 last_bind
= NULL_TREE
;
8312 for (tree it
= TREE_PURPOSE (t
); it
; it
= TREE_CHAIN (it
))
8314 if (gimplify_expr (&TREE_VEC_ELT (it
, 1), pre_p
, NULL
,
8315 is_gimple_val
, fb_rvalue
) == GS_ERROR
8316 || gimplify_expr (&TREE_VEC_ELT (it
, 2), pre_p
, NULL
,
8317 is_gimple_val
, fb_rvalue
) == GS_ERROR
8318 || gimplify_expr (&TREE_VEC_ELT (it
, 3), pre_p
, NULL
,
8319 is_gimple_val
, fb_rvalue
) == GS_ERROR
8320 || (gimplify_expr (&TREE_VEC_ELT (it
, 4), pre_p
, NULL
,
8321 is_gimple_val
, fb_rvalue
)
8325 last_iter
= TREE_PURPOSE (t
);
8326 tree block
= TREE_VEC_ELT (TREE_PURPOSE (t
), 5);
8327 last_bind
= build3 (BIND_EXPR
, void_type_node
, BLOCK_VARS (block
),
8329 last_body
= &BIND_EXPR_BODY (last_bind
);
8330 tree cond
= NULL_TREE
;
8331 location_t loc
= OMP_CLAUSE_LOCATION (c
);
8332 for (tree it
= TREE_PURPOSE (t
); it
; it
= TREE_CHAIN (it
))
8334 tree var
= TREE_VEC_ELT (it
, 0);
8335 tree begin
= TREE_VEC_ELT (it
, 1);
8336 tree end
= TREE_VEC_ELT (it
, 2);
8337 tree step
= TREE_VEC_ELT (it
, 3);
8338 loc
= DECL_SOURCE_LOCATION (var
);
8339 tree tem
= build2_loc (loc
, MODIFY_EXPR
, void_type_node
,
8341 append_to_statement_list_force (tem
, last_body
);
8343 tree cond1
= fold_build2_loc (loc
, GT_EXPR
, boolean_type_node
,
8344 step
, build_zero_cst (TREE_TYPE (step
)));
8345 tree cond2
= fold_build2_loc (loc
, LE_EXPR
, boolean_type_node
,
8347 tree cond3
= fold_build2_loc (loc
, GT_EXPR
, boolean_type_node
,
8349 cond1
= fold_build3_loc (loc
, COND_EXPR
, boolean_type_node
,
8350 cond1
, cond2
, cond3
);
8352 cond
= fold_build2_loc (loc
, TRUTH_AND_EXPR
,
8353 boolean_type_node
, cond
, cond1
);
8357 tree cont_label
= create_artificial_label (loc
);
8358 label
= build1 (LABEL_EXPR
, void_type_node
, cont_label
);
8359 tree tem
= fold_build3_loc (loc
, COND_EXPR
, void_type_node
, cond
,
8361 build_and_jump (&cont_label
));
8362 append_to_statement_list_force (tem
, last_body
);
8364 if (TREE_CODE (TREE_VALUE (t
)) == COMPOUND_EXPR
)
8366 append_to_statement_list (TREE_OPERAND (TREE_VALUE (t
), 0),
8368 TREE_VALUE (t
) = TREE_OPERAND (TREE_VALUE (t
), 1);
8370 if (error_operand_p (TREE_VALUE (t
)))
8372 append_to_statement_list_force (TREE_VALUE (t
), last_body
);
8373 TREE_VALUE (t
) = null_pointer_node
;
8379 append_to_statement_list (label
, last_body
);
8380 gimplify_and_add (last_bind
, pre_p
);
8381 last_bind
= NULL_TREE
;
8383 if (TREE_CODE (OMP_CLAUSE_DECL (c
)) == COMPOUND_EXPR
)
8385 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c
), 0), pre_p
,
8386 NULL
, is_gimple_val
, fb_rvalue
);
8387 OMP_CLAUSE_DECL (c
) = TREE_OPERAND (OMP_CLAUSE_DECL (c
), 1);
8389 if (error_operand_p (OMP_CLAUSE_DECL (c
)))
8391 if (gimplify_expr (&OMP_CLAUSE_DECL (c
), pre_p
, NULL
,
8392 is_gimple_lvalue
, fb_lvalue
) == GS_ERROR
)
8394 gimplify_and_add (OMP_CLAUSE_DECL (c
), pre_p
);
8399 append_to_statement_list (label
, last_body
);
8400 gimplify_and_add (last_bind
, pre_p
);
8405 /* If *LIST_P contains any OpenMP depend clauses with iterators,
8406 lower all the depend clauses by populating corresponding depend
8407 array. Returns 0 if there are no such depend clauses, or
8408 2 if all depend clauses should be removed, 1 otherwise. */
8411 gimplify_omp_depend (tree
*list_p
, gimple_seq
*pre_p
)
8415 size_t n
[5] = { 0, 0, 0, 0, 0 };
8417 tree counts
[5] = { NULL_TREE
, NULL_TREE
, NULL_TREE
, NULL_TREE
, NULL_TREE
};
8418 tree last_iter
= NULL_TREE
, last_count
= NULL_TREE
;
8420 location_t first_loc
= UNKNOWN_LOCATION
;
8422 for (c
= *list_p
; c
; c
= OMP_CLAUSE_CHAIN (c
))
8423 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEPEND
)
8425 switch (OMP_CLAUSE_DEPEND_KIND (c
))
8427 case OMP_CLAUSE_DEPEND_IN
:
8430 case OMP_CLAUSE_DEPEND_OUT
:
8431 case OMP_CLAUSE_DEPEND_INOUT
:
8434 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET
:
8437 case OMP_CLAUSE_DEPEND_DEPOBJ
:
8440 case OMP_CLAUSE_DEPEND_INOUTSET
:
8446 tree t
= OMP_CLAUSE_DECL (c
);
8447 if (first_loc
== UNKNOWN_LOCATION
)
8448 first_loc
= OMP_CLAUSE_LOCATION (c
);
8449 if (TREE_CODE (t
) == TREE_LIST
8451 && TREE_CODE (TREE_PURPOSE (t
)) == TREE_VEC
)
8453 if (TREE_PURPOSE (t
) != last_iter
)
8455 tree tcnt
= size_one_node
;
8456 for (tree it
= TREE_PURPOSE (t
); it
; it
= TREE_CHAIN (it
))
8458 if (gimplify_expr (&TREE_VEC_ELT (it
, 1), pre_p
, NULL
,
8459 is_gimple_val
, fb_rvalue
) == GS_ERROR
8460 || gimplify_expr (&TREE_VEC_ELT (it
, 2), pre_p
, NULL
,
8461 is_gimple_val
, fb_rvalue
) == GS_ERROR
8462 || gimplify_expr (&TREE_VEC_ELT (it
, 3), pre_p
, NULL
,
8463 is_gimple_val
, fb_rvalue
) == GS_ERROR
8464 || (gimplify_expr (&TREE_VEC_ELT (it
, 4), pre_p
, NULL
,
8465 is_gimple_val
, fb_rvalue
)
8468 tree var
= TREE_VEC_ELT (it
, 0);
8469 tree begin
= TREE_VEC_ELT (it
, 1);
8470 tree end
= TREE_VEC_ELT (it
, 2);
8471 tree step
= TREE_VEC_ELT (it
, 3);
8472 tree orig_step
= TREE_VEC_ELT (it
, 4);
8473 tree type
= TREE_TYPE (var
);
8474 tree stype
= TREE_TYPE (step
);
8475 location_t loc
= DECL_SOURCE_LOCATION (var
);
8477 /* Compute count for this iterator as
8479 ? (begin < end ? (end - begin + (step - 1)) / step : 0)
8480 : (begin > end ? (end - begin + (step + 1)) / step : 0)
8481 and compute product of those for the entire depend
8483 if (POINTER_TYPE_P (type
))
8484 endmbegin
= fold_build2_loc (loc
, POINTER_DIFF_EXPR
,
8487 endmbegin
= fold_build2_loc (loc
, MINUS_EXPR
, type
,
8489 tree stepm1
= fold_build2_loc (loc
, MINUS_EXPR
, stype
,
8491 build_int_cst (stype
, 1));
8492 tree stepp1
= fold_build2_loc (loc
, PLUS_EXPR
, stype
, step
,
8493 build_int_cst (stype
, 1));
8494 tree pos
= fold_build2_loc (loc
, PLUS_EXPR
, stype
,
8495 unshare_expr (endmbegin
),
8497 pos
= fold_build2_loc (loc
, TRUNC_DIV_EXPR
, stype
,
8499 tree neg
= fold_build2_loc (loc
, PLUS_EXPR
, stype
,
8501 if (TYPE_UNSIGNED (stype
))
8503 neg
= fold_build1_loc (loc
, NEGATE_EXPR
, stype
, neg
);
8504 step
= fold_build1_loc (loc
, NEGATE_EXPR
, stype
, step
);
8506 neg
= fold_build2_loc (loc
, TRUNC_DIV_EXPR
, stype
,
8509 tree cond
= fold_build2_loc (loc
, LT_EXPR
,
8512 pos
= fold_build3_loc (loc
, COND_EXPR
, stype
, cond
, pos
,
8513 build_int_cst (stype
, 0));
8514 cond
= fold_build2_loc (loc
, LT_EXPR
, boolean_type_node
,
8516 neg
= fold_build3_loc (loc
, COND_EXPR
, stype
, cond
, neg
,
8517 build_int_cst (stype
, 0));
8518 tree osteptype
= TREE_TYPE (orig_step
);
8519 cond
= fold_build2_loc (loc
, GT_EXPR
, boolean_type_node
,
8521 build_int_cst (osteptype
, 0));
8522 tree cnt
= fold_build3_loc (loc
, COND_EXPR
, stype
,
8524 cnt
= fold_convert_loc (loc
, sizetype
, cnt
);
8525 if (gimplify_expr (&cnt
, pre_p
, NULL
, is_gimple_val
,
8526 fb_rvalue
) == GS_ERROR
)
8528 tcnt
= size_binop_loc (loc
, MULT_EXPR
, tcnt
, cnt
);
8530 if (gimplify_expr (&tcnt
, pre_p
, NULL
, is_gimple_val
,
8531 fb_rvalue
) == GS_ERROR
)
8533 last_iter
= TREE_PURPOSE (t
);
8536 if (counts
[i
] == NULL_TREE
)
8537 counts
[i
] = last_count
;
8539 counts
[i
] = size_binop_loc (OMP_CLAUSE_LOCATION (c
),
8540 PLUS_EXPR
, counts
[i
], last_count
);
8545 for (i
= 0; i
< 5; i
++)
8551 tree total
= size_zero_node
;
8552 for (i
= 0; i
< 5; i
++)
8554 unused
[i
] = counts
[i
] == NULL_TREE
&& n
[i
] == 0;
8555 if (counts
[i
] == NULL_TREE
)
8556 counts
[i
] = size_zero_node
;
8558 counts
[i
] = size_binop (PLUS_EXPR
, counts
[i
], size_int (n
[i
]));
8559 if (gimplify_expr (&counts
[i
], pre_p
, NULL
, is_gimple_val
,
8560 fb_rvalue
) == GS_ERROR
)
8562 total
= size_binop (PLUS_EXPR
, total
, counts
[i
]);
8565 if (gimplify_expr (&total
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
)
8568 bool is_old
= unused
[1] && unused
[3] && unused
[4];
8569 tree totalpx
= size_binop (PLUS_EXPR
, unshare_expr (total
),
8570 size_int (is_old
? 1 : 4));
8572 totalpx
= size_binop (PLUS_EXPR
, totalpx
,
8573 size_binop (MULT_EXPR
, counts
[4], size_int (2)));
8574 tree type
= build_array_type (ptr_type_node
, build_index_type (totalpx
));
8575 tree array
= create_tmp_var_raw (type
);
8576 TREE_ADDRESSABLE (array
) = 1;
8577 if (!poly_int_tree_p (totalpx
))
8579 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (array
)))
8580 gimplify_type_sizes (TREE_TYPE (array
), pre_p
);
8581 if (gimplify_omp_ctxp
)
8583 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
8585 && (ctx
->region_type
== ORT_WORKSHARE
8586 || ctx
->region_type
== ORT_TASKGROUP
8587 || ctx
->region_type
== ORT_SIMD
8588 || ctx
->region_type
== ORT_ACC
))
8589 ctx
= ctx
->outer_context
;
8591 omp_add_variable (ctx
, array
, GOVD_LOCAL
| GOVD_SEEN
);
8593 gimplify_vla_decl (array
, pre_p
);
8596 gimple_add_tmp_var (array
);
8597 tree r
= build4 (ARRAY_REF
, ptr_type_node
, array
, size_int (0), NULL_TREE
,
8602 tem
= build2 (MODIFY_EXPR
, void_type_node
, r
,
8603 build_int_cst (ptr_type_node
, 0));
8604 gimplify_and_add (tem
, pre_p
);
8605 r
= build4 (ARRAY_REF
, ptr_type_node
, array
, size_int (1), NULL_TREE
,
8608 tem
= build2 (MODIFY_EXPR
, void_type_node
, r
,
8609 fold_convert (ptr_type_node
, total
));
8610 gimplify_and_add (tem
, pre_p
);
8611 for (i
= 1; i
< (is_old
? 2 : 4); i
++)
8613 r
= build4 (ARRAY_REF
, ptr_type_node
, array
, size_int (i
+ !is_old
),
8614 NULL_TREE
, NULL_TREE
);
8615 tem
= build2 (MODIFY_EXPR
, void_type_node
, r
, counts
[i
- 1]);
8616 gimplify_and_add (tem
, pre_p
);
8623 for (i
= 0; i
< 5; i
++)
8625 if (i
&& (i
>= j
|| unused
[i
- 1]))
8627 cnts
[i
] = cnts
[i
- 1];
8630 cnts
[i
] = create_tmp_var (sizetype
);
8632 g
= gimple_build_assign (cnts
[i
], size_int (is_old
? 2 : 5));
8637 t
= size_binop (PLUS_EXPR
, counts
[0], size_int (2));
8639 t
= size_binop (PLUS_EXPR
, cnts
[i
- 1], counts
[i
- 1]);
8640 if (gimplify_expr (&t
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
)
8643 g
= gimple_build_assign (cnts
[i
], t
);
8645 gimple_seq_add_stmt (pre_p
, g
);
8648 cnts
[5] = NULL_TREE
;
8651 tree t
= size_binop (PLUS_EXPR
, total
, size_int (5));
8652 cnts
[5] = create_tmp_var (sizetype
);
8653 g
= gimple_build_assign (cnts
[i
], t
);
8654 gimple_seq_add_stmt (pre_p
, g
);
8657 last_iter
= NULL_TREE
;
8658 tree last_bind
= NULL_TREE
;
8659 tree
*last_body
= NULL
;
8660 for (c
= *list_p
; c
; c
= OMP_CLAUSE_CHAIN (c
))
8661 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEPEND
)
8663 switch (OMP_CLAUSE_DEPEND_KIND (c
))
8665 case OMP_CLAUSE_DEPEND_IN
:
8668 case OMP_CLAUSE_DEPEND_OUT
:
8669 case OMP_CLAUSE_DEPEND_INOUT
:
8672 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET
:
8675 case OMP_CLAUSE_DEPEND_DEPOBJ
:
8678 case OMP_CLAUSE_DEPEND_INOUTSET
:
8684 tree t
= OMP_CLAUSE_DECL (c
);
8685 if (TREE_CODE (t
) == TREE_LIST
8687 && TREE_CODE (TREE_PURPOSE (t
)) == TREE_VEC
)
8689 if (TREE_PURPOSE (t
) != last_iter
)
8692 gimplify_and_add (last_bind
, pre_p
);
8693 tree block
= TREE_VEC_ELT (TREE_PURPOSE (t
), 5);
8694 last_bind
= build3 (BIND_EXPR
, void_type_node
,
8695 BLOCK_VARS (block
), NULL
, block
);
8696 TREE_SIDE_EFFECTS (last_bind
) = 1;
8697 SET_EXPR_LOCATION (last_bind
, OMP_CLAUSE_LOCATION (c
));
8698 tree
*p
= &BIND_EXPR_BODY (last_bind
);
8699 for (tree it
= TREE_PURPOSE (t
); it
; it
= TREE_CHAIN (it
))
8701 tree var
= TREE_VEC_ELT (it
, 0);
8702 tree begin
= TREE_VEC_ELT (it
, 1);
8703 tree end
= TREE_VEC_ELT (it
, 2);
8704 tree step
= TREE_VEC_ELT (it
, 3);
8705 tree orig_step
= TREE_VEC_ELT (it
, 4);
8706 tree type
= TREE_TYPE (var
);
8707 location_t loc
= DECL_SOURCE_LOCATION (var
);
8715 if (orig_step > 0) {
8716 if (var < end) goto beg_label;
8718 if (var > end) goto beg_label;
8720 for each iterator, with inner iterators added to
8722 tree beg_label
= create_artificial_label (loc
);
8723 tree cond_label
= NULL_TREE
;
8724 tem
= build2_loc (loc
, MODIFY_EXPR
, void_type_node
,
8726 append_to_statement_list_force (tem
, p
);
8727 tem
= build_and_jump (&cond_label
);
8728 append_to_statement_list_force (tem
, p
);
8729 tem
= build1 (LABEL_EXPR
, void_type_node
, beg_label
);
8730 append_to_statement_list (tem
, p
);
8731 tree bind
= build3 (BIND_EXPR
, void_type_node
, NULL_TREE
,
8732 NULL_TREE
, NULL_TREE
);
8733 TREE_SIDE_EFFECTS (bind
) = 1;
8734 SET_EXPR_LOCATION (bind
, loc
);
8735 append_to_statement_list_force (bind
, p
);
8736 if (POINTER_TYPE_P (type
))
8737 tem
= build2_loc (loc
, POINTER_PLUS_EXPR
, type
,
8738 var
, fold_convert_loc (loc
, sizetype
,
8741 tem
= build2_loc (loc
, PLUS_EXPR
, type
, var
, step
);
8742 tem
= build2_loc (loc
, MODIFY_EXPR
, void_type_node
,
8744 append_to_statement_list_force (tem
, p
);
8745 tem
= build1 (LABEL_EXPR
, void_type_node
, cond_label
);
8746 append_to_statement_list (tem
, p
);
8747 tree cond
= fold_build2_loc (loc
, LT_EXPR
,
8751 = fold_build3_loc (loc
, COND_EXPR
, void_type_node
,
8752 cond
, build_and_jump (&beg_label
),
8754 cond
= fold_build2_loc (loc
, GT_EXPR
, boolean_type_node
,
8757 = fold_build3_loc (loc
, COND_EXPR
, void_type_node
,
8758 cond
, build_and_jump (&beg_label
),
8760 tree osteptype
= TREE_TYPE (orig_step
);
8761 cond
= fold_build2_loc (loc
, GT_EXPR
, boolean_type_node
,
8763 build_int_cst (osteptype
, 0));
8764 tem
= fold_build3_loc (loc
, COND_EXPR
, void_type_node
,
8766 append_to_statement_list_force (tem
, p
);
8767 p
= &BIND_EXPR_BODY (bind
);
8771 last_iter
= TREE_PURPOSE (t
);
8772 if (TREE_CODE (TREE_VALUE (t
)) == COMPOUND_EXPR
)
8774 append_to_statement_list (TREE_OPERAND (TREE_VALUE (t
),
8776 TREE_VALUE (t
) = TREE_OPERAND (TREE_VALUE (t
), 1);
8778 if (error_operand_p (TREE_VALUE (t
)))
8780 if (TREE_VALUE (t
) != null_pointer_node
)
8781 TREE_VALUE (t
) = build_fold_addr_expr (TREE_VALUE (t
));
8784 r
= build4 (ARRAY_REF
, ptr_type_node
, array
, cnts
[i
],
8785 NULL_TREE
, NULL_TREE
);
8786 tree r2
= build4 (ARRAY_REF
, ptr_type_node
, array
, cnts
[5],
8787 NULL_TREE
, NULL_TREE
);
8788 r2
= build_fold_addr_expr_with_type (r2
, ptr_type_node
);
8789 tem
= build2_loc (OMP_CLAUSE_LOCATION (c
), MODIFY_EXPR
,
8790 void_type_node
, r
, r2
);
8791 append_to_statement_list_force (tem
, last_body
);
8792 tem
= build2_loc (OMP_CLAUSE_LOCATION (c
), MODIFY_EXPR
,
8793 void_type_node
, cnts
[i
],
8794 size_binop (PLUS_EXPR
, cnts
[i
],
8796 append_to_statement_list_force (tem
, last_body
);
8799 r
= build4 (ARRAY_REF
, ptr_type_node
, array
, cnts
[i
],
8800 NULL_TREE
, NULL_TREE
);
8801 tem
= build2_loc (OMP_CLAUSE_LOCATION (c
), MODIFY_EXPR
,
8802 void_type_node
, r
, TREE_VALUE (t
));
8803 append_to_statement_list_force (tem
, last_body
);
8806 r
= build4 (ARRAY_REF
, ptr_type_node
, array
,
8807 size_binop (PLUS_EXPR
, cnts
[i
], size_int (1)),
8808 NULL_TREE
, NULL_TREE
);
8809 tem
= build_int_cst (ptr_type_node
, GOMP_DEPEND_INOUTSET
);
8810 tem
= build2_loc (OMP_CLAUSE_LOCATION (c
), MODIFY_EXPR
,
8811 void_type_node
, r
, tem
);
8812 append_to_statement_list_force (tem
, last_body
);
8814 tem
= build2_loc (OMP_CLAUSE_LOCATION (c
), MODIFY_EXPR
,
8815 void_type_node
, cnts
[i
],
8816 size_binop (PLUS_EXPR
, cnts
[i
],
8817 size_int (1 + (i
== 5))));
8818 append_to_statement_list_force (tem
, last_body
);
8819 TREE_VALUE (t
) = null_pointer_node
;
8825 gimplify_and_add (last_bind
, pre_p
);
8826 last_bind
= NULL_TREE
;
8828 if (TREE_CODE (OMP_CLAUSE_DECL (c
)) == COMPOUND_EXPR
)
8830 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c
), 0), pre_p
,
8831 NULL
, is_gimple_val
, fb_rvalue
);
8832 OMP_CLAUSE_DECL (c
) = TREE_OPERAND (OMP_CLAUSE_DECL (c
), 1);
8834 if (error_operand_p (OMP_CLAUSE_DECL (c
)))
8836 if (OMP_CLAUSE_DECL (c
) != null_pointer_node
)
8837 OMP_CLAUSE_DECL (c
) = build_fold_addr_expr (OMP_CLAUSE_DECL (c
));
8838 if (gimplify_expr (&OMP_CLAUSE_DECL (c
), pre_p
, NULL
,
8839 is_gimple_val
, fb_rvalue
) == GS_ERROR
)
8843 r
= build4 (ARRAY_REF
, ptr_type_node
, array
, cnts
[i
],
8844 NULL_TREE
, NULL_TREE
);
8845 tree r2
= build4 (ARRAY_REF
, ptr_type_node
, array
, cnts
[5],
8846 NULL_TREE
, NULL_TREE
);
8847 r2
= build_fold_addr_expr_with_type (r2
, ptr_type_node
);
8848 tem
= build2 (MODIFY_EXPR
, void_type_node
, r
, r2
);
8849 gimplify_and_add (tem
, pre_p
);
8850 g
= gimple_build_assign (cnts
[i
], size_binop (PLUS_EXPR
,
8853 gimple_seq_add_stmt (pre_p
, g
);
8856 r
= build4 (ARRAY_REF
, ptr_type_node
, array
, cnts
[i
],
8857 NULL_TREE
, NULL_TREE
);
8858 tem
= build2 (MODIFY_EXPR
, void_type_node
, r
, OMP_CLAUSE_DECL (c
));
8859 gimplify_and_add (tem
, pre_p
);
8862 r
= build4 (ARRAY_REF
, ptr_type_node
, array
,
8863 size_binop (PLUS_EXPR
, cnts
[i
], size_int (1)),
8864 NULL_TREE
, NULL_TREE
);
8865 tem
= build_int_cst (ptr_type_node
, GOMP_DEPEND_INOUTSET
);
8866 tem
= build2 (MODIFY_EXPR
, void_type_node
, r
, tem
);
8867 append_to_statement_list_force (tem
, last_body
);
8868 gimplify_and_add (tem
, pre_p
);
8870 g
= gimple_build_assign (cnts
[i
],
8871 size_binop (PLUS_EXPR
, cnts
[i
],
8872 size_int (1 + (i
== 5))));
8873 gimple_seq_add_stmt (pre_p
, g
);
8877 gimplify_and_add (last_bind
, pre_p
);
8878 tree cond
= boolean_false_node
;
8882 cond
= build2_loc (first_loc
, NE_EXPR
, boolean_type_node
, cnts
[0],
8883 size_binop_loc (first_loc
, PLUS_EXPR
, counts
[0],
8886 cond
= build2_loc (first_loc
, TRUTH_OR_EXPR
, boolean_type_node
, cond
,
8887 build2_loc (first_loc
, NE_EXPR
, boolean_type_node
,
8889 size_binop_loc (first_loc
, PLUS_EXPR
,
8895 tree prev
= size_int (5);
8896 for (i
= 0; i
< 5; i
++)
8900 prev
= size_binop_loc (first_loc
, PLUS_EXPR
, counts
[i
], prev
);
8901 cond
= build2_loc (first_loc
, TRUTH_OR_EXPR
, boolean_type_node
, cond
,
8902 build2_loc (first_loc
, NE_EXPR
, boolean_type_node
,
8903 cnts
[i
], unshare_expr (prev
)));
8906 tem
= build3_loc (first_loc
, COND_EXPR
, void_type_node
, cond
,
8907 build_call_expr_loc (first_loc
,
8908 builtin_decl_explicit (BUILT_IN_TRAP
),
8910 gimplify_and_add (tem
, pre_p
);
8911 c
= build_omp_clause (UNKNOWN_LOCATION
, OMP_CLAUSE_DEPEND
);
8912 OMP_CLAUSE_DEPEND_KIND (c
) = OMP_CLAUSE_DEPEND_LAST
;
8913 OMP_CLAUSE_DECL (c
) = build_fold_addr_expr (array
);
8914 OMP_CLAUSE_CHAIN (c
) = *list_p
;
8919 /* For a set of mappings describing an array section pointed to by a struct
8920 (or derived type, etc.) component, create an "alloc" or "release" node to
8921 insert into a list following a GOMP_MAP_STRUCT node. For some types of
8922 mapping (e.g. Fortran arrays with descriptors), an additional mapping may
8923 be created that is inserted into the list of mapping nodes attached to the
8924 directive being processed -- not part of the sorted list of nodes after
8927 CODE is the code of the directive being processed. GRP_START and GRP_END
8928 are the first and last of two or three nodes representing this array section
8929 mapping (e.g. a data movement node like GOMP_MAP_{TO,FROM}, optionally a
8930 GOMP_MAP_TO_PSET, and finally a GOMP_MAP_ALWAYS_POINTER). EXTRA_NODE is
8931 filled with the additional node described above, if needed.
8933 This function does not add the new nodes to any lists itself. It is the
8934 responsibility of the caller to do that. */
8937 build_omp_struct_comp_nodes (enum tree_code code
, tree grp_start
, tree grp_end
,
8940 enum gomp_map_kind mkind
8941 = (code
== OMP_TARGET_EXIT_DATA
|| code
== OACC_EXIT_DATA
)
8942 ? GOMP_MAP_RELEASE
: GOMP_MAP_ALLOC
;
8944 gcc_assert (grp_start
!= grp_end
);
8946 tree c2
= build_omp_clause (OMP_CLAUSE_LOCATION (grp_end
), OMP_CLAUSE_MAP
);
8947 OMP_CLAUSE_SET_MAP_KIND (c2
, mkind
);
8948 OMP_CLAUSE_DECL (c2
) = unshare_expr (OMP_CLAUSE_DECL (grp_end
));
8949 OMP_CLAUSE_CHAIN (c2
) = NULL_TREE
;
8950 tree grp_mid
= NULL_TREE
;
8951 if (OMP_CLAUSE_CHAIN (grp_start
) != grp_end
)
8952 grp_mid
= OMP_CLAUSE_CHAIN (grp_start
);
8955 && OMP_CLAUSE_CODE (grp_mid
) == OMP_CLAUSE_MAP
8956 && OMP_CLAUSE_MAP_KIND (grp_mid
) == GOMP_MAP_TO_PSET
)
8957 OMP_CLAUSE_SIZE (c2
) = OMP_CLAUSE_SIZE (grp_mid
);
8959 OMP_CLAUSE_SIZE (c2
) = TYPE_SIZE_UNIT (ptr_type_node
);
8962 && OMP_CLAUSE_CODE (grp_mid
) == OMP_CLAUSE_MAP
8963 && (OMP_CLAUSE_MAP_KIND (grp_mid
) == GOMP_MAP_ALWAYS_POINTER
8964 || OMP_CLAUSE_MAP_KIND (grp_mid
) == GOMP_MAP_ATTACH_DETACH
))
8967 = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end
), OMP_CLAUSE_MAP
);
8968 OMP_CLAUSE_SET_MAP_KIND (c3
, mkind
);
8969 OMP_CLAUSE_DECL (c3
) = unshare_expr (OMP_CLAUSE_DECL (grp_mid
));
8970 OMP_CLAUSE_SIZE (c3
) = TYPE_SIZE_UNIT (ptr_type_node
);
8971 OMP_CLAUSE_CHAIN (c3
) = NULL_TREE
;
8976 *extra_node
= NULL_TREE
;
8981 /* Strip ARRAY_REFS or an indirect ref off BASE, find the containing object,
8982 and set *BITPOSP and *POFFSETP to the bit offset of the access.
8983 If BASE_REF is non-NULL and the containing object is a reference, set
8984 *BASE_REF to that reference before dereferencing the object.
8985 If BASE_REF is NULL, check that the containing object is a COMPONENT_REF or
8986 has array type, else return NULL. */
8989 extract_base_bit_offset (tree base
, poly_int64
*bitposp
,
8990 poly_offset_int
*poffsetp
)
8993 poly_int64 bitsize
, bitpos
;
8995 int unsignedp
, reversep
, volatilep
= 0;
8996 poly_offset_int poffset
;
9000 base
= get_inner_reference (base
, &bitsize
, &bitpos
, &offset
, &mode
,
9001 &unsignedp
, &reversep
, &volatilep
);
9005 if (offset
&& poly_int_tree_p (offset
))
9007 poffset
= wi::to_poly_offset (offset
);
9013 if (maybe_ne (bitpos
, 0))
9014 poffset
+= bits_to_bytes_round_down (bitpos
);
9017 *poffsetp
= poffset
;
9022 /* Used for topological sorting of mapping groups. UNVISITED means we haven't
9023 started processing the group yet. The TEMPORARY mark is used when we first
9024 encounter a group on a depth-first traversal, and the PERMANENT mark is used
9025 when we have processed all the group's children (i.e. all the base pointers
9026 referred to by the group's mapping nodes, recursively). */
9028 enum omp_tsort_mark
{
9034 /* Hash for trees based on operand_equal_p. Like tree_operand_hash
9035 but ignores side effects in the equality comparisons. */
9037 struct tree_operand_hash_no_se
: tree_operand_hash
9039 static inline bool equal (const value_type
&,
9040 const compare_type
&);
9044 tree_operand_hash_no_se::equal (const value_type
&t1
,
9045 const compare_type
&t2
)
9047 return operand_equal_p (t1
, t2
, OEP_MATCH_SIDE_EFFECTS
);
9050 /* A group of OMP_CLAUSE_MAP nodes that correspond to a single "map"
9053 struct omp_mapping_group
{
9056 omp_tsort_mark mark
;
9057 /* If we've removed the group but need to reindex, mark the group as
9060 struct omp_mapping_group
*sibling
;
9061 struct omp_mapping_group
*next
;
9065 debug_mapping_group (omp_mapping_group
*grp
)
9067 tree tmp
= OMP_CLAUSE_CHAIN (grp
->grp_end
);
9068 OMP_CLAUSE_CHAIN (grp
->grp_end
) = NULL
;
9069 debug_generic_expr (*grp
->grp_start
);
9070 OMP_CLAUSE_CHAIN (grp
->grp_end
) = tmp
;
9073 /* Return the OpenMP "base pointer" of an expression EXPR, or NULL if there
9077 omp_get_base_pointer (tree expr
)
9079 while (TREE_CODE (expr
) == ARRAY_REF
9080 || TREE_CODE (expr
) == COMPONENT_REF
)
9081 expr
= TREE_OPERAND (expr
, 0);
9083 if (INDIRECT_REF_P (expr
)
9084 || (TREE_CODE (expr
) == MEM_REF
9085 && integer_zerop (TREE_OPERAND (expr
, 1))))
9087 expr
= TREE_OPERAND (expr
, 0);
9088 while (TREE_CODE (expr
) == COMPOUND_EXPR
)
9089 expr
= TREE_OPERAND (expr
, 1);
9090 if (TREE_CODE (expr
) == POINTER_PLUS_EXPR
)
9091 expr
= TREE_OPERAND (expr
, 0);
9092 if (TREE_CODE (expr
) == SAVE_EXPR
)
9093 expr
= TREE_OPERAND (expr
, 0);
9101 /* Remove COMPONENT_REFS and indirections from EXPR. */
9104 omp_strip_components_and_deref (tree expr
)
9106 while (TREE_CODE (expr
) == COMPONENT_REF
9107 || INDIRECT_REF_P (expr
)
9108 || (TREE_CODE (expr
) == MEM_REF
9109 && integer_zerop (TREE_OPERAND (expr
, 1)))
9110 || TREE_CODE (expr
) == POINTER_PLUS_EXPR
9111 || TREE_CODE (expr
) == COMPOUND_EXPR
)
9112 if (TREE_CODE (expr
) == COMPOUND_EXPR
)
9113 expr
= TREE_OPERAND (expr
, 1);
9115 expr
= TREE_OPERAND (expr
, 0);
9123 omp_strip_indirections (tree expr
)
9125 while (INDIRECT_REF_P (expr
)
9126 || (TREE_CODE (expr
) == MEM_REF
9127 && integer_zerop (TREE_OPERAND (expr
, 1))))
9128 expr
= TREE_OPERAND (expr
, 0);
9133 /* An attach or detach operation depends directly on the address being
9134 attached/detached. Return that address, or none if there are no
9135 attachments/detachments. */
9138 omp_get_attachment (omp_mapping_group
*grp
)
9140 tree node
= *grp
->grp_start
;
9142 switch (OMP_CLAUSE_MAP_KIND (node
))
9146 case GOMP_MAP_TOFROM
:
9147 case GOMP_MAP_ALWAYS_FROM
:
9148 case GOMP_MAP_ALWAYS_TO
:
9149 case GOMP_MAP_ALWAYS_TOFROM
:
9150 case GOMP_MAP_FORCE_FROM
:
9151 case GOMP_MAP_FORCE_TO
:
9152 case GOMP_MAP_FORCE_TOFROM
:
9153 case GOMP_MAP_FORCE_PRESENT
:
9154 case GOMP_MAP_PRESENT_ALLOC
:
9155 case GOMP_MAP_PRESENT_FROM
:
9156 case GOMP_MAP_PRESENT_TO
:
9157 case GOMP_MAP_PRESENT_TOFROM
:
9158 case GOMP_MAP_ALWAYS_PRESENT_FROM
:
9159 case GOMP_MAP_ALWAYS_PRESENT_TO
:
9160 case GOMP_MAP_ALWAYS_PRESENT_TOFROM
:
9161 case GOMP_MAP_ALLOC
:
9162 case GOMP_MAP_RELEASE
:
9163 case GOMP_MAP_DELETE
:
9164 case GOMP_MAP_FORCE_ALLOC
:
9165 if (node
== grp
->grp_end
)
9168 node
= OMP_CLAUSE_CHAIN (node
);
9169 if (node
&& OMP_CLAUSE_MAP_KIND (node
) == GOMP_MAP_TO_PSET
)
9171 gcc_assert (node
!= grp
->grp_end
);
9172 node
= OMP_CLAUSE_CHAIN (node
);
9175 switch (OMP_CLAUSE_MAP_KIND (node
))
9177 case GOMP_MAP_POINTER
:
9178 case GOMP_MAP_ALWAYS_POINTER
:
9179 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
9180 case GOMP_MAP_FIRSTPRIVATE_REFERENCE
:
9181 case GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION
:
9184 case GOMP_MAP_ATTACH_DETACH
:
9185 case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION
:
9186 return OMP_CLAUSE_DECL (node
);
9189 internal_error ("unexpected mapping node");
9191 return error_mark_node
;
9193 case GOMP_MAP_TO_PSET
:
9194 gcc_assert (node
!= grp
->grp_end
);
9195 node
= OMP_CLAUSE_CHAIN (node
);
9196 if (OMP_CLAUSE_MAP_KIND (node
) == GOMP_MAP_ATTACH
9197 || OMP_CLAUSE_MAP_KIND (node
) == GOMP_MAP_DETACH
)
9198 return OMP_CLAUSE_DECL (node
);
9200 internal_error ("unexpected mapping node");
9201 return error_mark_node
;
9203 case GOMP_MAP_ATTACH
:
9204 case GOMP_MAP_DETACH
:
9205 node
= OMP_CLAUSE_CHAIN (node
);
9206 if (!node
|| *grp
->grp_start
== grp
->grp_end
)
9207 return OMP_CLAUSE_DECL (*grp
->grp_start
);
9208 if (OMP_CLAUSE_MAP_KIND (node
) == GOMP_MAP_FIRSTPRIVATE_POINTER
9209 || OMP_CLAUSE_MAP_KIND (node
) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
)
9210 return OMP_CLAUSE_DECL (*grp
->grp_start
);
9212 internal_error ("unexpected mapping node");
9213 return error_mark_node
;
9215 case GOMP_MAP_STRUCT
:
9216 case GOMP_MAP_FORCE_DEVICEPTR
:
9217 case GOMP_MAP_DEVICE_RESIDENT
:
9219 case GOMP_MAP_IF_PRESENT
:
9220 case GOMP_MAP_FIRSTPRIVATE
:
9221 case GOMP_MAP_FIRSTPRIVATE_INT
:
9222 case GOMP_MAP_USE_DEVICE_PTR
:
9223 case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION
:
9227 internal_error ("unexpected mapping node");
9230 return error_mark_node
;
9233 /* Given a pointer START_P to the start of a group of related (e.g. pointer)
9234 mappings, return the chain pointer to the end of that group in the list. */
9237 omp_group_last (tree
*start_p
)
9239 tree c
= *start_p
, nc
, *grp_last_p
= start_p
;
9241 gcc_assert (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_MAP
);
9243 nc
= OMP_CLAUSE_CHAIN (c
);
9245 if (!nc
|| OMP_CLAUSE_CODE (nc
) != OMP_CLAUSE_MAP
)
9248 switch (OMP_CLAUSE_MAP_KIND (c
))
9252 && OMP_CLAUSE_CODE (nc
) == OMP_CLAUSE_MAP
9253 && (OMP_CLAUSE_MAP_KIND (nc
) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
9254 || OMP_CLAUSE_MAP_KIND (nc
) == GOMP_MAP_FIRSTPRIVATE_POINTER
9255 || OMP_CLAUSE_MAP_KIND (nc
) == GOMP_MAP_ATTACH_DETACH
9256 || OMP_CLAUSE_MAP_KIND (nc
) == GOMP_MAP_POINTER
9257 || (OMP_CLAUSE_MAP_KIND (nc
)
9258 == GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION
)
9259 || (OMP_CLAUSE_MAP_KIND (nc
)
9260 == GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION
)
9261 || OMP_CLAUSE_MAP_KIND (nc
) == GOMP_MAP_ALWAYS_POINTER
9262 || OMP_CLAUSE_MAP_KIND (nc
) == GOMP_MAP_TO_PSET
))
9264 grp_last_p
= &OMP_CLAUSE_CHAIN (c
);
9266 tree nc2
= OMP_CLAUSE_CHAIN (nc
);
9268 && OMP_CLAUSE_CODE (nc2
) == OMP_CLAUSE_MAP
9269 && (OMP_CLAUSE_MAP_KIND (nc
)
9270 == GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION
)
9271 && OMP_CLAUSE_MAP_KIND (nc2
) == GOMP_MAP_ATTACH
)
9273 grp_last_p
= &OMP_CLAUSE_CHAIN (nc
);
9275 nc2
= OMP_CLAUSE_CHAIN (nc2
);
9281 case GOMP_MAP_ATTACH
:
9282 case GOMP_MAP_DETACH
:
9283 /* This is a weird artifact of how directives are parsed: bare attach or
9284 detach clauses get a subsequent (meaningless) FIRSTPRIVATE_POINTER or
9285 FIRSTPRIVATE_REFERENCE node. FIXME. */
9287 && OMP_CLAUSE_CODE (nc
) == OMP_CLAUSE_MAP
9288 && (OMP_CLAUSE_MAP_KIND (nc
) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
9289 || OMP_CLAUSE_MAP_KIND (nc
) == GOMP_MAP_FIRSTPRIVATE_POINTER
))
9290 grp_last_p
= &OMP_CLAUSE_CHAIN (c
);
9293 case GOMP_MAP_TO_PSET
:
9294 if (OMP_CLAUSE_CODE (nc
) == OMP_CLAUSE_MAP
9295 && (OMP_CLAUSE_MAP_KIND (nc
) == GOMP_MAP_ATTACH
9296 || OMP_CLAUSE_MAP_KIND (nc
) == GOMP_MAP_DETACH
))
9297 grp_last_p
= &OMP_CLAUSE_CHAIN (c
);
9300 case GOMP_MAP_STRUCT
:
9302 unsigned HOST_WIDE_INT num_mappings
9303 = tree_to_uhwi (OMP_CLAUSE_SIZE (c
));
9304 if (OMP_CLAUSE_MAP_KIND (nc
) == GOMP_MAP_FIRSTPRIVATE_POINTER
9305 || OMP_CLAUSE_MAP_KIND (nc
) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
9306 || OMP_CLAUSE_MAP_KIND (nc
) == GOMP_MAP_ATTACH_DETACH
)
9307 grp_last_p
= &OMP_CLAUSE_CHAIN (*grp_last_p
);
9308 for (unsigned i
= 0; i
< num_mappings
; i
++)
9309 grp_last_p
= &OMP_CLAUSE_CHAIN (*grp_last_p
);
9317 /* Walk through LIST_P, and return a list of groups of mappings found (e.g.
9318 OMP_CLAUSE_MAP with GOMP_MAP_{TO/FROM/TOFROM} followed by one or two
9319 associated GOMP_MAP_POINTER mappings). Return a vector of omp_mapping_group
9320 if we have more than one such group, else return NULL. */
9323 omp_gather_mapping_groups_1 (tree
*list_p
, vec
<omp_mapping_group
> *groups
,
9324 tree gather_sentinel
)
9326 for (tree
*cp
= list_p
;
9327 *cp
&& *cp
!= gather_sentinel
;
9328 cp
= &OMP_CLAUSE_CHAIN (*cp
))
9330 if (OMP_CLAUSE_CODE (*cp
) != OMP_CLAUSE_MAP
)
9333 tree
*grp_last_p
= omp_group_last (cp
);
9334 omp_mapping_group grp
;
9337 grp
.grp_end
= *grp_last_p
;
9338 grp
.mark
= UNVISITED
;
9340 grp
.deleted
= false;
9342 groups
->safe_push (grp
);
9348 static vec
<omp_mapping_group
> *
9349 omp_gather_mapping_groups (tree
*list_p
)
9351 vec
<omp_mapping_group
> *groups
= new vec
<omp_mapping_group
> ();
9353 omp_gather_mapping_groups_1 (list_p
, groups
, NULL_TREE
);
9355 if (groups
->length () > 0)
9364 /* A pointer mapping group GRP may define a block of memory starting at some
9365 base address, and maybe also define a firstprivate pointer or firstprivate
9366 reference that points to that block. The return value is a node containing
9367 the former, and the *FIRSTPRIVATE pointer is set if we have the latter.
9368 If we define several base pointers, i.e. for a GOMP_MAP_STRUCT mapping,
9369 return the number of consecutive chained nodes in CHAINED. */
9372 omp_group_base (omp_mapping_group
*grp
, unsigned int *chained
,
9375 tree node
= *grp
->grp_start
;
9377 *firstprivate
= NULL_TREE
;
9380 switch (OMP_CLAUSE_MAP_KIND (node
))
9384 case GOMP_MAP_TOFROM
:
9385 case GOMP_MAP_ALWAYS_FROM
:
9386 case GOMP_MAP_ALWAYS_TO
:
9387 case GOMP_MAP_ALWAYS_TOFROM
:
9388 case GOMP_MAP_FORCE_FROM
:
9389 case GOMP_MAP_FORCE_TO
:
9390 case GOMP_MAP_FORCE_TOFROM
:
9391 case GOMP_MAP_FORCE_PRESENT
:
9392 case GOMP_MAP_PRESENT_ALLOC
:
9393 case GOMP_MAP_PRESENT_FROM
:
9394 case GOMP_MAP_PRESENT_TO
:
9395 case GOMP_MAP_PRESENT_TOFROM
:
9396 case GOMP_MAP_ALWAYS_PRESENT_FROM
:
9397 case GOMP_MAP_ALWAYS_PRESENT_TO
:
9398 case GOMP_MAP_ALWAYS_PRESENT_TOFROM
:
9399 case GOMP_MAP_ALLOC
:
9400 case GOMP_MAP_RELEASE
:
9401 case GOMP_MAP_DELETE
:
9402 case GOMP_MAP_FORCE_ALLOC
:
9403 case GOMP_MAP_IF_PRESENT
:
9404 if (node
== grp
->grp_end
)
9407 node
= OMP_CLAUSE_CHAIN (node
);
9408 if (node
&& OMP_CLAUSE_MAP_KIND (node
) == GOMP_MAP_TO_PSET
)
9410 if (node
== grp
->grp_end
)
9411 return *grp
->grp_start
;
9412 node
= OMP_CLAUSE_CHAIN (node
);
9415 switch (OMP_CLAUSE_MAP_KIND (node
))
9417 case GOMP_MAP_POINTER
:
9418 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
9419 case GOMP_MAP_FIRSTPRIVATE_REFERENCE
:
9420 case GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION
:
9421 *firstprivate
= OMP_CLAUSE_DECL (node
);
9422 return *grp
->grp_start
;
9424 case GOMP_MAP_ALWAYS_POINTER
:
9425 case GOMP_MAP_ATTACH_DETACH
:
9426 case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION
:
9427 return *grp
->grp_start
;
9430 internal_error ("unexpected mapping node");
9433 internal_error ("unexpected mapping node");
9434 return error_mark_node
;
9436 case GOMP_MAP_TO_PSET
:
9437 gcc_assert (node
!= grp
->grp_end
);
9438 node
= OMP_CLAUSE_CHAIN (node
);
9439 if (OMP_CLAUSE_MAP_KIND (node
) == GOMP_MAP_ATTACH
9440 || OMP_CLAUSE_MAP_KIND (node
) == GOMP_MAP_DETACH
)
9443 internal_error ("unexpected mapping node");
9444 return error_mark_node
;
9446 case GOMP_MAP_ATTACH
:
9447 case GOMP_MAP_DETACH
:
9448 node
= OMP_CLAUSE_CHAIN (node
);
9449 if (!node
|| *grp
->grp_start
== grp
->grp_end
)
9451 if (OMP_CLAUSE_MAP_KIND (node
) == GOMP_MAP_FIRSTPRIVATE_POINTER
9452 || OMP_CLAUSE_MAP_KIND (node
) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
)
9454 /* We're mapping the base pointer itself in a bare attach or detach
9455 node. This is a side effect of how parsing works, and the mapping
9456 will be removed anyway (at least for enter/exit data directives).
9457 We should ignore the mapping here. FIXME. */
9461 internal_error ("unexpected mapping node");
9462 return error_mark_node
;
9464 case GOMP_MAP_STRUCT
:
9466 unsigned HOST_WIDE_INT num_mappings
9467 = tree_to_uhwi (OMP_CLAUSE_SIZE (node
));
9468 node
= OMP_CLAUSE_CHAIN (node
);
9469 if (OMP_CLAUSE_MAP_KIND (node
) == GOMP_MAP_FIRSTPRIVATE_POINTER
9470 || OMP_CLAUSE_MAP_KIND (node
) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
)
9472 *firstprivate
= OMP_CLAUSE_DECL (node
);
9473 node
= OMP_CLAUSE_CHAIN (node
);
9475 *chained
= num_mappings
;
9479 case GOMP_MAP_FORCE_DEVICEPTR
:
9480 case GOMP_MAP_DEVICE_RESIDENT
:
9482 case GOMP_MAP_FIRSTPRIVATE
:
9483 case GOMP_MAP_FIRSTPRIVATE_INT
:
9484 case GOMP_MAP_USE_DEVICE_PTR
:
9485 case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION
:
9488 case GOMP_MAP_FIRSTPRIVATE_POINTER
:
9489 case GOMP_MAP_FIRSTPRIVATE_REFERENCE
:
9490 case GOMP_MAP_POINTER
:
9491 case GOMP_MAP_ALWAYS_POINTER
:
9492 case GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION
:
9493 /* These shouldn't appear by themselves. */
9495 internal_error ("unexpected pointer mapping node");
9496 return error_mark_node
;
9502 return error_mark_node
;
9505 /* Given a vector of omp_mapping_groups, build a hash table so we can look up
9506 nodes by tree_operand_hash_no_se. */
9509 omp_index_mapping_groups_1 (hash_map
<tree_operand_hash_no_se
,
9510 omp_mapping_group
*> *grpmap
,
9511 vec
<omp_mapping_group
> *groups
,
9512 tree reindex_sentinel
)
9514 omp_mapping_group
*grp
;
9516 bool reindexing
= reindex_sentinel
!= NULL_TREE
, above_hwm
= false;
9518 FOR_EACH_VEC_ELT (*groups
, i
, grp
)
9520 if (reindexing
&& *grp
->grp_start
== reindex_sentinel
)
9523 if (reindexing
&& !above_hwm
)
9527 unsigned int chained
;
9528 tree node
= omp_group_base (grp
, &chained
, &fpp
);
9530 if (node
== error_mark_node
|| (!node
&& !fpp
))
9533 for (unsigned j
= 0;
9534 node
&& j
< chained
;
9535 node
= OMP_CLAUSE_CHAIN (node
), j
++)
9537 tree decl
= OMP_CLAUSE_DECL (node
);
9538 /* Sometimes we see zero-offset MEM_REF instead of INDIRECT_REF,
9539 meaning node-hash lookups don't work. This is a workaround for
9540 that, but ideally we should just create the INDIRECT_REF at
9541 source instead. FIXME. */
9542 if (TREE_CODE (decl
) == MEM_REF
9543 && integer_zerop (TREE_OPERAND (decl
, 1)))
9544 decl
= build_fold_indirect_ref (TREE_OPERAND (decl
, 0));
9546 omp_mapping_group
**prev
= grpmap
->get (decl
);
9548 if (prev
&& *prev
== grp
)
9552 /* Mapping the same thing twice is normally diagnosed as an error,
9553 but can happen under some circumstances, e.g. in pr99928-16.c,
9556 #pragma omp target simd reduction(+:a[:3]) \
9557 map(always, tofrom: a[:6])
9560 will result in two "a[0]" mappings (of different sizes). */
9562 grp
->sibling
= (*prev
)->sibling
;
9563 (*prev
)->sibling
= grp
;
9566 grpmap
->put (decl
, grp
);
9572 omp_mapping_group
**prev
= grpmap
->get (fpp
);
9573 if (prev
&& *prev
!= grp
)
9575 grp
->sibling
= (*prev
)->sibling
;
9576 (*prev
)->sibling
= grp
;
9579 grpmap
->put (fpp
, grp
);
9583 static hash_map
<tree_operand_hash_no_se
, omp_mapping_group
*> *
9584 omp_index_mapping_groups (vec
<omp_mapping_group
> *groups
)
9586 hash_map
<tree_operand_hash_no_se
, omp_mapping_group
*> *grpmap
9587 = new hash_map
<tree_operand_hash_no_se
, omp_mapping_group
*>;
9589 omp_index_mapping_groups_1 (grpmap
, groups
, NULL_TREE
);
9594 /* Rebuild group map from partially-processed clause list (during
9595 omp_build_struct_sibling_lists). We have already processed nodes up until
9596 a high-water mark (HWM). This is a bit tricky because the list is being
9597 reordered as it is scanned, but we know:
9599 1. The list after HWM has not been touched yet, so we can reindex it safely.
9601 2. The list before and including HWM has been altered, but remains
9602 well-formed throughout the sibling-list building operation.
9604 so, we can do the reindex operation in two parts, on the processed and
9605 then the unprocessed halves of the list. */
9607 static hash_map
<tree_operand_hash_no_se
, omp_mapping_group
*> *
9608 omp_reindex_mapping_groups (tree
*list_p
,
9609 vec
<omp_mapping_group
> *groups
,
9610 vec
<omp_mapping_group
> *processed_groups
,
9613 hash_map
<tree_operand_hash_no_se
, omp_mapping_group
*> *grpmap
9614 = new hash_map
<tree_operand_hash_no_se
, omp_mapping_group
*>;
9616 processed_groups
->truncate (0);
9618 omp_gather_mapping_groups_1 (list_p
, processed_groups
, sentinel
);
9619 omp_index_mapping_groups_1 (grpmap
, processed_groups
, NULL_TREE
);
9621 omp_index_mapping_groups_1 (grpmap
, groups
, sentinel
);
9626 /* Find the immediately-containing struct for a component ref (etc.)
9630 omp_containing_struct (tree expr
)
9636 /* Note: don't strip NOPs unless we're also stripping off array refs or a
9638 if (TREE_CODE (expr
) != ARRAY_REF
&& TREE_CODE (expr
) != COMPONENT_REF
)
9641 while (TREE_CODE (expr
) == ARRAY_REF
)
9642 expr
= TREE_OPERAND (expr
, 0);
9644 if (TREE_CODE (expr
) == COMPONENT_REF
)
9645 expr
= TREE_OPERAND (expr
, 0);
9650 /* Return TRUE if DECL describes a component that is part of a whole structure
9651 that is mapped elsewhere in GRPMAP. *MAPPED_BY_GROUP is set to the group
9652 that maps that structure, if present. */
9655 omp_mapped_by_containing_struct (hash_map
<tree_operand_hash_no_se
,
9656 omp_mapping_group
*> *grpmap
,
9658 omp_mapping_group
**mapped_by_group
)
9660 tree wsdecl
= NULL_TREE
;
9662 *mapped_by_group
= NULL
;
9666 wsdecl
= omp_containing_struct (decl
);
9669 omp_mapping_group
**wholestruct
= grpmap
->get (wsdecl
);
9671 && TREE_CODE (wsdecl
) == MEM_REF
9672 && integer_zerop (TREE_OPERAND (wsdecl
, 1)))
9674 tree deref
= TREE_OPERAND (wsdecl
, 0);
9675 deref
= build_fold_indirect_ref (deref
);
9676 wholestruct
= grpmap
->get (deref
);
9680 *mapped_by_group
= *wholestruct
;
9689 /* Helper function for omp_tsort_mapping_groups. Returns TRUE on success, or
9693 omp_tsort_mapping_groups_1 (omp_mapping_group
***outlist
,
9694 vec
<omp_mapping_group
> *groups
,
9695 hash_map
<tree_operand_hash_no_se
,
9696 omp_mapping_group
*> *grpmap
,
9697 omp_mapping_group
*grp
)
9699 if (grp
->mark
== PERMANENT
)
9701 if (grp
->mark
== TEMPORARY
)
9703 fprintf (stderr
, "when processing group:\n");
9704 debug_mapping_group (grp
);
9705 internal_error ("base pointer cycle detected");
9708 grp
->mark
= TEMPORARY
;
9710 tree attaches_to
= omp_get_attachment (grp
);
9714 omp_mapping_group
**basep
= grpmap
->get (attaches_to
);
9716 if (basep
&& *basep
!= grp
)
9718 for (omp_mapping_group
*w
= *basep
; w
; w
= w
->sibling
)
9719 if (!omp_tsort_mapping_groups_1 (outlist
, groups
, grpmap
, w
))
9724 tree decl
= OMP_CLAUSE_DECL (*grp
->grp_start
);
9728 tree base
= omp_get_base_pointer (decl
);
9733 omp_mapping_group
**innerp
= grpmap
->get (base
);
9734 omp_mapping_group
*wholestruct
;
9736 /* We should treat whole-structure mappings as if all (pointer, in this
9737 case) members are mapped as individual list items. Check if we have
9738 such a whole-structure mapping, if we don't have an explicit reference
9739 to the pointer member itself. */
9741 && TREE_CODE (base
) == COMPONENT_REF
9742 && omp_mapped_by_containing_struct (grpmap
, base
, &wholestruct
))
9743 innerp
= &wholestruct
;
9745 if (innerp
&& *innerp
!= grp
)
9747 for (omp_mapping_group
*w
= *innerp
; w
; w
= w
->sibling
)
9748 if (!omp_tsort_mapping_groups_1 (outlist
, groups
, grpmap
, w
))
9756 grp
->mark
= PERMANENT
;
9758 /* Emit grp to output list. */
9761 *outlist
= &grp
->next
;
9766 /* Topologically sort GROUPS, so that OMP 5.0-defined base pointers come
9767 before mappings that use those pointers. This is an implementation of the
9768 depth-first search algorithm, described e.g. at:
9770 https://en.wikipedia.org/wiki/Topological_sorting
9773 static omp_mapping_group
*
9774 omp_tsort_mapping_groups (vec
<omp_mapping_group
> *groups
,
9775 hash_map
<tree_operand_hash_no_se
, omp_mapping_group
*>
9778 omp_mapping_group
*grp
, *outlist
= NULL
, **cursor
;
9783 FOR_EACH_VEC_ELT (*groups
, i
, grp
)
9785 if (grp
->mark
!= PERMANENT
)
9786 if (!omp_tsort_mapping_groups_1 (&cursor
, groups
, grpmap
, grp
))
9793 /* Split INLIST into two parts, moving groups corresponding to
9794 ALLOC/RELEASE/DELETE mappings to one list, and other mappings to another.
9795 The former list is then appended to the latter. Each sub-list retains the
9796 order of the original list.
9797 Note that ATTACH nodes are later moved to the end of the list in
9798 gimplify_adjust_omp_clauses, for target regions. */
9800 static omp_mapping_group
*
9801 omp_segregate_mapping_groups (omp_mapping_group
*inlist
)
9803 omp_mapping_group
*ard_groups
= NULL
, *tf_groups
= NULL
;
9804 omp_mapping_group
**ard_tail
= &ard_groups
, **tf_tail
= &tf_groups
;
9806 for (omp_mapping_group
*w
= inlist
; w
;)
9808 tree c
= *w
->grp_start
;
9809 omp_mapping_group
*next
= w
->next
;
9811 gcc_assert (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_MAP
);
9813 switch (OMP_CLAUSE_MAP_KIND (c
))
9815 case GOMP_MAP_ALLOC
:
9816 case GOMP_MAP_RELEASE
:
9817 case GOMP_MAP_DELETE
:
9820 ard_tail
= &w
->next
;
9832 /* Now splice the lists together... */
9833 *tf_tail
= ard_groups
;
9838 /* Given a list LIST_P containing groups of mappings given by GROUPS, reorder
9839 those groups based on the output list of omp_tsort_mapping_groups --
9840 singly-linked, threaded through each element's NEXT pointer starting at
9841 HEAD. Each list element appears exactly once in that linked list.
9843 Each element of GROUPS may correspond to one or several mapping nodes.
9844 Node groups are kept together, and in the reordered list, the positions of
9845 the original groups are reused for the positions of the reordered list.
9846 Hence if we have e.g.
9848 {to ptr ptr} firstprivate {tofrom ptr} ...
9850 first group non-"map" second group
9852 and say the second group contains a base pointer for the first so must be
9853 moved before it, the resulting list will contain:
9855 {tofrom ptr} firstprivate {to ptr ptr} ...
9856 ^ prev. second group ^ prev. first group
9860 omp_reorder_mapping_groups (vec
<omp_mapping_group
> *groups
,
9861 omp_mapping_group
*head
,
9864 omp_mapping_group
*grp
;
9866 unsigned numgroups
= groups
->length ();
9867 auto_vec
<tree
> old_heads (numgroups
);
9868 auto_vec
<tree
*> old_headps (numgroups
);
9869 auto_vec
<tree
> new_heads (numgroups
);
9870 auto_vec
<tree
> old_succs (numgroups
);
9871 bool map_at_start
= (list_p
== (*groups
)[0].grp_start
);
9873 tree
*new_grp_tail
= NULL
;
9875 /* Stash the start & end nodes of each mapping group before we start
9876 modifying the list. */
9877 FOR_EACH_VEC_ELT (*groups
, i
, grp
)
9879 old_headps
.quick_push (grp
->grp_start
);
9880 old_heads
.quick_push (*grp
->grp_start
);
9881 old_succs
.quick_push (OMP_CLAUSE_CHAIN (grp
->grp_end
));
9884 /* And similarly, the heads of the groups in the order we want to rearrange
9886 for (omp_mapping_group
*w
= head
; w
; w
= w
->next
)
9887 new_heads
.quick_push (*w
->grp_start
);
9889 FOR_EACH_VEC_ELT (*groups
, i
, grp
)
9893 if (new_grp_tail
&& old_succs
[i
- 1] == old_heads
[i
])
9895 /* a {b c d} {e f g} h i j (original)
9897 a {k l m} {e f g} h i j (inserted new group on last iter)
9899 a {k l m} {n o p} h i j (this time, chain last group to new one)
9902 *new_grp_tail
= new_heads
[i
];
9904 else if (new_grp_tail
)
9906 /* a {b c d} e {f g h} i j k (original)
9908 a {l m n} e {f g h} i j k (gap after last iter's group)
9910 a {l m n} e {o p q} h i j (chain last group to old successor)
9913 *new_grp_tail
= old_succs
[i
- 1];
9914 *old_headps
[i
] = new_heads
[i
];
9918 /* The first inserted group -- point to new group, and leave end
9924 *grp
->grp_start
= new_heads
[i
];
9927 new_grp_tail
= &OMP_CLAUSE_CHAIN (head
->grp_end
);
9933 *new_grp_tail
= old_succs
[numgroups
- 1];
9937 return map_at_start
? (*groups
)[0].grp_start
: list_p
;
9940 /* DECL is supposed to have lastprivate semantics in the outer contexts
9941 of combined/composite constructs, starting with OCTX.
9942 Add needed lastprivate, shared or map clause if no data sharing or
9943 mapping clause are present. IMPLICIT_P is true if it is an implicit
9944 clause (IV on simd), in which case the lastprivate will not be
9945 copied to some constructs. */
9948 omp_lastprivate_for_combined_outer_constructs (struct gimplify_omp_ctx
*octx
,
9949 tree decl
, bool implicit_p
)
9951 struct gimplify_omp_ctx
*orig_octx
= octx
;
9952 for (; octx
; octx
= octx
->outer_context
)
9954 if ((octx
->region_type
== ORT_COMBINED_PARALLEL
9955 || (octx
->region_type
& ORT_COMBINED_TEAMS
) == ORT_COMBINED_TEAMS
)
9956 && splay_tree_lookup (octx
->variables
,
9957 (splay_tree_key
) decl
) == NULL
)
9959 omp_add_variable (octx
, decl
, GOVD_SHARED
| GOVD_SEEN
);
9962 if ((octx
->region_type
& ORT_TASK
) != 0
9963 && octx
->combined_loop
9964 && splay_tree_lookup (octx
->variables
,
9965 (splay_tree_key
) decl
) == NULL
)
9967 omp_add_variable (octx
, decl
, GOVD_LASTPRIVATE
| GOVD_SEEN
);
9971 && octx
->region_type
== ORT_WORKSHARE
9972 && octx
->combined_loop
9973 && splay_tree_lookup (octx
->variables
,
9974 (splay_tree_key
) decl
) == NULL
9975 && octx
->outer_context
9976 && octx
->outer_context
->region_type
== ORT_COMBINED_PARALLEL
9977 && splay_tree_lookup (octx
->outer_context
->variables
,
9978 (splay_tree_key
) decl
) == NULL
)
9980 octx
= octx
->outer_context
;
9981 omp_add_variable (octx
, decl
, GOVD_LASTPRIVATE
| GOVD_SEEN
);
9984 if ((octx
->region_type
== ORT_WORKSHARE
|| octx
->region_type
== ORT_ACC
)
9985 && octx
->combined_loop
9986 && splay_tree_lookup (octx
->variables
,
9987 (splay_tree_key
) decl
) == NULL
9988 && !omp_check_private (octx
, decl
, false))
9990 omp_add_variable (octx
, decl
, GOVD_LASTPRIVATE
| GOVD_SEEN
);
9993 if (octx
->region_type
== ORT_COMBINED_TARGET
)
9995 splay_tree_node n
= splay_tree_lookup (octx
->variables
,
9996 (splay_tree_key
) decl
);
9999 omp_add_variable (octx
, decl
, GOVD_MAP
| GOVD_SEEN
);
10000 octx
= octx
->outer_context
;
10002 else if (!implicit_p
10003 && (n
->value
& GOVD_FIRSTPRIVATE_IMPLICIT
))
10005 n
->value
&= ~(GOVD_FIRSTPRIVATE
10006 | GOVD_FIRSTPRIVATE_IMPLICIT
10008 omp_add_variable (octx
, decl
, GOVD_MAP
| GOVD_SEEN
);
10009 octx
= octx
->outer_context
;
10014 if (octx
&& (implicit_p
|| octx
!= orig_octx
))
10015 omp_notice_variable (octx
, decl
, true);
10018 /* If we have mappings INNER and OUTER, where INNER is a component access and
10019 OUTER is a mapping of the whole containing struct, check that the mappings
10020 are compatible. We'll be deleting the inner mapping, so we need to make
10021 sure the outer mapping does (at least) the same transfers to/from the device
10022 as the inner mapping. */
10025 omp_check_mapping_compatibility (location_t loc
,
10026 omp_mapping_group
*outer
,
10027 omp_mapping_group
*inner
)
10029 tree first_outer
= *outer
->grp_start
, first_inner
= *inner
->grp_start
;
10031 gcc_assert (OMP_CLAUSE_CODE (first_outer
) == OMP_CLAUSE_MAP
);
10032 gcc_assert (OMP_CLAUSE_CODE (first_inner
) == OMP_CLAUSE_MAP
);
10034 enum gomp_map_kind outer_kind
= OMP_CLAUSE_MAP_KIND (first_outer
);
10035 enum gomp_map_kind inner_kind
= OMP_CLAUSE_MAP_KIND (first_inner
);
10037 if (outer_kind
== inner_kind
)
10040 switch (outer_kind
)
10042 case GOMP_MAP_ALWAYS_TO
:
10043 if (inner_kind
== GOMP_MAP_FORCE_PRESENT
10044 || inner_kind
== GOMP_MAP_ALLOC
10045 || inner_kind
== GOMP_MAP_TO
)
10049 case GOMP_MAP_ALWAYS_FROM
:
10050 if (inner_kind
== GOMP_MAP_FORCE_PRESENT
10051 || inner_kind
== GOMP_MAP_ALLOC
10052 || inner_kind
== GOMP_MAP_FROM
)
10057 case GOMP_MAP_FROM
:
10058 if (inner_kind
== GOMP_MAP_FORCE_PRESENT
10059 || inner_kind
== GOMP_MAP_ALLOC
)
10063 case GOMP_MAP_ALWAYS_TOFROM
:
10064 case GOMP_MAP_TOFROM
:
10065 if (inner_kind
== GOMP_MAP_FORCE_PRESENT
10066 || inner_kind
== GOMP_MAP_ALLOC
10067 || inner_kind
== GOMP_MAP_TO
10068 || inner_kind
== GOMP_MAP_FROM
10069 || inner_kind
== GOMP_MAP_TOFROM
)
10077 error_at (loc
, "data movement for component %qE is not compatible with "
10078 "movement for struct %qE", OMP_CLAUSE_DECL (first_inner
),
10079 OMP_CLAUSE_DECL (first_outer
));
10084 /* Similar to omp_resolve_clause_dependencies, but for OpenACC. The only
10085 clause dependencies we handle for now are struct element mappings and
10086 whole-struct mappings on the same directive, and duplicate clause
10090 oacc_resolve_clause_dependencies (vec
<omp_mapping_group
> *groups
,
10091 hash_map
<tree_operand_hash_no_se
,
10092 omp_mapping_group
*> *grpmap
)
10095 omp_mapping_group
*grp
;
10096 hash_set
<tree_operand_hash
> *seen_components
= NULL
;
10097 hash_set
<tree_operand_hash
> *shown_error
= NULL
;
10099 FOR_EACH_VEC_ELT (*groups
, i
, grp
)
10101 tree grp_end
= grp
->grp_end
;
10102 tree decl
= OMP_CLAUSE_DECL (grp_end
);
10104 gcc_assert (OMP_CLAUSE_CODE (grp_end
) == OMP_CLAUSE_MAP
);
10106 if (DECL_P (grp_end
))
10109 tree c
= OMP_CLAUSE_DECL (*grp
->grp_start
);
10110 while (TREE_CODE (c
) == ARRAY_REF
)
10111 c
= TREE_OPERAND (c
, 0);
10112 if (TREE_CODE (c
) != COMPONENT_REF
)
10114 if (!seen_components
)
10115 seen_components
= new hash_set
<tree_operand_hash
> ();
10117 shown_error
= new hash_set
<tree_operand_hash
> ();
10118 if (seen_components
->contains (c
)
10119 && !shown_error
->contains (c
))
10121 error_at (OMP_CLAUSE_LOCATION (grp_end
),
10122 "%qE appears more than once in map clauses",
10123 OMP_CLAUSE_DECL (grp_end
));
10124 shown_error
->add (c
);
10127 seen_components
->add (c
);
10129 omp_mapping_group
*struct_group
;
10130 if (omp_mapped_by_containing_struct (grpmap
, decl
, &struct_group
)
10131 && *grp
->grp_start
== grp_end
)
10133 omp_check_mapping_compatibility (OMP_CLAUSE_LOCATION (grp_end
),
10134 struct_group
, grp
);
10135 /* Remove the whole of this mapping -- redundant. */
10136 grp
->deleted
= true;
10140 if (seen_components
)
10141 delete seen_components
;
10143 delete shown_error
;
10146 /* Link node NEWNODE so it is pointed to by chain INSERT_AT. NEWNODE's chain
10147 is linked to the previous node pointed to by INSERT_AT. */
10150 omp_siblist_insert_node_after (tree newnode
, tree
*insert_at
)
10152 OMP_CLAUSE_CHAIN (newnode
) = *insert_at
;
10153 *insert_at
= newnode
;
10154 return &OMP_CLAUSE_CHAIN (newnode
);
10157 /* Move NODE (which is currently pointed to by the chain OLD_POS) so it is
10158 pointed to by chain MOVE_AFTER instead. */
10161 omp_siblist_move_node_after (tree node
, tree
*old_pos
, tree
*move_after
)
10163 gcc_assert (node
== *old_pos
);
10164 *old_pos
= OMP_CLAUSE_CHAIN (node
);
10165 OMP_CLAUSE_CHAIN (node
) = *move_after
;
10166 *move_after
= node
;
10169 /* Move nodes from FIRST_PTR (pointed to by previous node's chain) to
10170 LAST_NODE to after MOVE_AFTER chain. Similar to below function, but no
10171 new nodes are prepended to the list before splicing into the new position.
10172 Return the position we should continue scanning the list at, or NULL to
10173 stay where we were. */
10176 omp_siblist_move_nodes_after (tree
*first_ptr
, tree last_node
,
10179 if (first_ptr
== move_after
)
10182 tree tmp
= *first_ptr
;
10183 *first_ptr
= OMP_CLAUSE_CHAIN (last_node
);
10184 OMP_CLAUSE_CHAIN (last_node
) = *move_after
;
10190 /* Concatenate two lists described by [FIRST_NEW, LAST_NEW_TAIL] and
10191 [FIRST_PTR, LAST_NODE], and insert them in the OMP clause list after chain
10192 pointer MOVE_AFTER.
10194 The latter list was previously part of the OMP clause list, and the former
10195 (prepended) part is comprised of new nodes.
10197 We start with a list of nodes starting with a struct mapping node. We
10198 rearrange the list so that new nodes starting from FIRST_NEW and whose last
10199 node's chain is LAST_NEW_TAIL comes directly after MOVE_AFTER, followed by
10200 the group of mapping nodes we are currently processing (from the chain
10201 FIRST_PTR to LAST_NODE). The return value is the pointer to the next chain
10202 we should continue processing from, or NULL to stay where we were.
10204 The transformation (in the case where MOVE_AFTER and FIRST_PTR are
10205 different) is worked through below. Here we are processing LAST_NODE, and
10206 FIRST_PTR points at the preceding mapping clause:
10208 #. mapping node chain
10209 ---------------------------------------------------
10210 A. struct_node [->B]
10212 C. comp_2 [->D (move_after)]
10214 E. attach_3 [->F (first_ptr)]
10215 F. map_to_4 [->G (continue_at)]
10216 G. attach_4 (last_node) [->H]
10219 *last_new_tail = *first_ptr;
10221 I. new_node (first_new) [->F (last_new_tail)]
10223 *first_ptr = OMP_CLAUSE_CHAIN (last_node)
10225 #. mapping node chain
10226 ----------------------------------------------------
10227 A. struct_node [->B]
10229 C. comp_2 [->D (move_after)]
10231 E. attach_3 [->H (first_ptr)]
10232 F. map_to_4 [->G (continue_at)]
10233 G. attach_4 (last_node) [->H]
10236 I. new_node (first_new) [->F (last_new_tail)]
10238 OMP_CLAUSE_CHAIN (last_node) = *move_after;
10240 #. mapping node chain
10241 ---------------------------------------------------
10242 A. struct_node [->B]
10244 C. comp_2 [->D (move_after)]
10246 E. attach_3 [->H (continue_at)]
10248 G. attach_4 (last_node) [->D]
10251 I. new_node (first_new) [->F (last_new_tail)]
10253 *move_after = first_new;
10255 #. mapping node chain
10256 ---------------------------------------------------
10257 A. struct_node [->B]
10259 C. comp_2 [->I (move_after)]
10261 E. attach_3 [->H (continue_at)]
10263 G. attach_4 (last_node) [->D]
10265 I. new_node (first_new) [->F (last_new_tail)]
10269 #. mapping node chain
10270 ---------------------------------------------------
10271 A. struct_node [->B]
10273 C. comp_2 [->I (move_after)]
10274 I. new_node (first_new) [->F (last_new_tail)]
10276 G. attach_4 (last_node) [->D]
10278 E. attach_3 [->H (continue_at)]
10283 omp_siblist_move_concat_nodes_after (tree first_new
, tree
*last_new_tail
,
10284 tree
*first_ptr
, tree last_node
,
10287 tree
*continue_at
= NULL
;
10288 *last_new_tail
= *first_ptr
;
10289 if (first_ptr
== move_after
)
10290 *move_after
= first_new
;
10293 *first_ptr
= OMP_CLAUSE_CHAIN (last_node
);
10294 continue_at
= first_ptr
;
10295 OMP_CLAUSE_CHAIN (last_node
) = *move_after
;
10296 *move_after
= first_new
;
10298 return continue_at
;
10301 /* Mapping struct members causes an additional set of nodes to be created,
10302 starting with GOMP_MAP_STRUCT followed by a number of mappings equal to the
10303 number of members being mapped, in order of ascending position (address or
10306 We scan through the list of mapping clauses, calling this function for each
10307 struct member mapping we find, and build up the list of mappings after the
10308 initial GOMP_MAP_STRUCT node. For pointer members, these will be
10309 newly-created ALLOC nodes. For non-pointer members, the existing mapping is
10310 moved into place in the sorted list.
10319 #pragma (acc|omp directive) copy(struct.a[0:n], struct.b[0:n], struct.c,
10322 GOMP_MAP_STRUCT (4)
10323 [GOMP_MAP_FIRSTPRIVATE_REFERENCE -- for refs to structs]
10324 GOMP_MAP_ALLOC (struct.a)
10325 GOMP_MAP_ALLOC (struct.b)
10326 GOMP_MAP_TO (struct.c)
10327 GOMP_MAP_ALLOC (struct.d)
10330 In the case where we are mapping references to pointers, or in Fortran if
10331 we are mapping an array with a descriptor, additional nodes may be created
10332 after the struct node list also.
10334 The return code is either a pointer to the next node to process (if the
10335 list has been rearranged), else NULL to continue with the next node in the
10339 omp_accumulate_sibling_list (enum omp_region_type region_type
,
10340 enum tree_code code
,
10341 hash_map
<tree_operand_hash
, tree
>
10342 *&struct_map_to_clause
, tree
*grp_start_p
,
10343 tree grp_end
, tree
*inner
)
10345 poly_offset_int coffset
;
10346 poly_int64 cbitpos
;
10347 tree ocd
= OMP_CLAUSE_DECL (grp_end
);
10348 bool openmp
= !(region_type
& ORT_ACC
);
10349 tree
*continue_at
= NULL
;
10351 while (TREE_CODE (ocd
) == ARRAY_REF
)
10352 ocd
= TREE_OPERAND (ocd
, 0);
10354 if (INDIRECT_REF_P (ocd
))
10355 ocd
= TREE_OPERAND (ocd
, 0);
10357 tree base
= extract_base_bit_offset (ocd
, &cbitpos
, &coffset
);
10359 bool ptr
= (OMP_CLAUSE_MAP_KIND (grp_end
) == GOMP_MAP_ALWAYS_POINTER
);
10360 bool attach_detach
= ((OMP_CLAUSE_MAP_KIND (grp_end
)
10361 == GOMP_MAP_ATTACH_DETACH
)
10362 || (OMP_CLAUSE_MAP_KIND (grp_end
)
10363 == GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION
));
10364 bool attach
= (OMP_CLAUSE_MAP_KIND (grp_end
) == GOMP_MAP_ATTACH
10365 || OMP_CLAUSE_MAP_KIND (grp_end
) == GOMP_MAP_DETACH
);
10367 /* FIXME: If we're not mapping the base pointer in some other clause on this
10368 directive, I think we want to create ALLOC/RELEASE here -- i.e. not
10370 if (openmp
&& attach_detach
)
10373 if (!struct_map_to_clause
|| struct_map_to_clause
->get (base
) == NULL
)
10375 tree l
= build_omp_clause (OMP_CLAUSE_LOCATION (grp_end
), OMP_CLAUSE_MAP
);
10376 gomp_map_kind k
= attach
? GOMP_MAP_FORCE_PRESENT
: GOMP_MAP_STRUCT
;
10378 OMP_CLAUSE_SET_MAP_KIND (l
, k
);
10380 OMP_CLAUSE_DECL (l
) = unshare_expr (base
);
10382 OMP_CLAUSE_SIZE (l
)
10383 = (!attach
? size_int (1)
10384 : (DECL_P (OMP_CLAUSE_DECL (l
))
10385 ? DECL_SIZE_UNIT (OMP_CLAUSE_DECL (l
))
10386 : TYPE_SIZE_UNIT (TREE_TYPE (OMP_CLAUSE_DECL (l
)))));
10387 if (struct_map_to_clause
== NULL
)
10388 struct_map_to_clause
= new hash_map
<tree_operand_hash
, tree
>;
10389 struct_map_to_clause
->put (base
, l
);
10391 if (ptr
|| attach_detach
)
10395 = build_omp_struct_comp_nodes (code
, *grp_start_p
, grp_end
,
10397 OMP_CLAUSE_CHAIN (l
) = alloc_node
;
10399 tree
*insert_node_pos
= grp_start_p
;
10403 OMP_CLAUSE_CHAIN (extra_node
) = *insert_node_pos
;
10404 OMP_CLAUSE_CHAIN (alloc_node
) = extra_node
;
10407 OMP_CLAUSE_CHAIN (alloc_node
) = *insert_node_pos
;
10409 *insert_node_pos
= l
;
10413 gcc_assert (*grp_start_p
== grp_end
);
10414 grp_start_p
= omp_siblist_insert_node_after (l
, grp_start_p
);
10417 tree noind
= omp_strip_indirections (base
);
10420 && (region_type
& ORT_TARGET
)
10421 && TREE_CODE (noind
) == COMPONENT_REF
)
10423 /* The base for this component access is a struct component access
10424 itself. Insert a node to be processed on the next iteration of
10425 our caller's loop, which will subsequently be turned into a new,
10426 inner GOMP_MAP_STRUCT mapping.
10428 We need to do this else the non-DECL_P base won't be
10429 rewritten correctly in the offloaded region. */
10430 tree c2
= build_omp_clause (OMP_CLAUSE_LOCATION (grp_end
),
10432 OMP_CLAUSE_SET_MAP_KIND (c2
, GOMP_MAP_FORCE_PRESENT
);
10433 OMP_CLAUSE_DECL (c2
) = unshare_expr (noind
);
10434 OMP_CLAUSE_SIZE (c2
) = TYPE_SIZE_UNIT (TREE_TYPE (noind
));
10439 tree sdecl
= omp_strip_components_and_deref (base
);
10441 if (POINTER_TYPE_P (TREE_TYPE (sdecl
)) && (region_type
& ORT_TARGET
))
10443 tree c2
= build_omp_clause (OMP_CLAUSE_LOCATION (grp_end
),
10446 = (INDIRECT_REF_P (base
)
10447 && ((TREE_CODE (TREE_TYPE (TREE_OPERAND (base
, 0)))
10449 || (INDIRECT_REF_P (TREE_OPERAND (base
, 0))
10450 && (TREE_CODE (TREE_TYPE (TREE_OPERAND
10451 (TREE_OPERAND (base
, 0), 0)))
10452 == REFERENCE_TYPE
))));
10453 enum gomp_map_kind mkind
= base_ref
? GOMP_MAP_FIRSTPRIVATE_REFERENCE
10454 : GOMP_MAP_FIRSTPRIVATE_POINTER
;
10455 OMP_CLAUSE_SET_MAP_KIND (c2
, mkind
);
10456 OMP_CLAUSE_DECL (c2
) = sdecl
;
10457 tree baddr
= build_fold_addr_expr (base
);
10458 baddr
= fold_convert_loc (OMP_CLAUSE_LOCATION (grp_end
),
10459 ptrdiff_type_node
, baddr
);
10460 /* This isn't going to be good enough when we add support for more
10461 complicated lvalue expressions. FIXME. */
10462 if (TREE_CODE (TREE_TYPE (sdecl
)) == REFERENCE_TYPE
10463 && TREE_CODE (TREE_TYPE (TREE_TYPE (sdecl
))) == POINTER_TYPE
)
10464 sdecl
= build_simple_mem_ref (sdecl
);
10465 tree decladdr
= fold_convert_loc (OMP_CLAUSE_LOCATION (grp_end
),
10466 ptrdiff_type_node
, sdecl
);
10467 OMP_CLAUSE_SIZE (c2
)
10468 = fold_build2_loc (OMP_CLAUSE_LOCATION (grp_end
), MINUS_EXPR
,
10469 ptrdiff_type_node
, baddr
, decladdr
);
10470 /* Insert after struct node. */
10471 OMP_CLAUSE_CHAIN (c2
) = OMP_CLAUSE_CHAIN (l
);
10472 OMP_CLAUSE_CHAIN (l
) = c2
;
10477 else if (struct_map_to_clause
)
10479 tree
*osc
= struct_map_to_clause
->get (base
);
10480 tree
*sc
= NULL
, *scp
= NULL
;
10481 sc
= &OMP_CLAUSE_CHAIN (*osc
);
10482 /* The struct mapping might be immediately followed by a
10483 FIRSTPRIVATE_POINTER and/or FIRSTPRIVATE_REFERENCE -- if it's an
10484 indirect access or a reference, or both. (This added node is removed
10485 in omp-low.c after it has been processed there.) */
10487 && (OMP_CLAUSE_MAP_KIND (*sc
) == GOMP_MAP_FIRSTPRIVATE_POINTER
10488 || OMP_CLAUSE_MAP_KIND (*sc
) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
))
10489 sc
= &OMP_CLAUSE_CHAIN (*sc
);
10490 for (; *sc
!= grp_end
; sc
= &OMP_CLAUSE_CHAIN (*sc
))
10491 if ((ptr
|| attach_detach
) && sc
== grp_start_p
)
10493 else if (TREE_CODE (OMP_CLAUSE_DECL (*sc
)) != COMPONENT_REF
10494 && TREE_CODE (OMP_CLAUSE_DECL (*sc
)) != INDIRECT_REF
10495 && TREE_CODE (OMP_CLAUSE_DECL (*sc
)) != ARRAY_REF
)
10499 tree sc_decl
= OMP_CLAUSE_DECL (*sc
);
10500 poly_offset_int offset
;
10503 if (TREE_CODE (sc_decl
) == ARRAY_REF
)
10505 while (TREE_CODE (sc_decl
) == ARRAY_REF
)
10506 sc_decl
= TREE_OPERAND (sc_decl
, 0);
10507 if (TREE_CODE (sc_decl
) != COMPONENT_REF
10508 || TREE_CODE (TREE_TYPE (sc_decl
)) != ARRAY_TYPE
)
10511 else if (INDIRECT_REF_P (sc_decl
)
10512 && TREE_CODE (TREE_OPERAND (sc_decl
, 0)) == COMPONENT_REF
10513 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (sc_decl
, 0)))
10514 == REFERENCE_TYPE
))
10515 sc_decl
= TREE_OPERAND (sc_decl
, 0);
10517 tree base2
= extract_base_bit_offset (sc_decl
, &bitpos
, &offset
);
10518 if (!base2
|| !operand_equal_p (base2
, base
, 0))
10522 if (maybe_lt (coffset
, offset
)
10523 || (known_eq (coffset
, offset
)
10524 && maybe_lt (cbitpos
, bitpos
)))
10526 if (ptr
|| attach_detach
)
10534 OMP_CLAUSE_SIZE (*osc
)
10535 = size_binop (PLUS_EXPR
, OMP_CLAUSE_SIZE (*osc
), size_one_node
);
10536 if (ptr
|| attach_detach
)
10538 tree cl
= NULL_TREE
, extra_node
;
10539 tree alloc_node
= build_omp_struct_comp_nodes (code
, *grp_start_p
,
10540 grp_end
, &extra_node
);
10541 tree
*tail_chain
= NULL
;
10545 grp_end : the last (or only) node in this group.
10546 grp_start_p : pointer to the first node in a pointer mapping group
10547 up to and including GRP_END.
10548 sc : pointer to the chain for the end of the struct component
10550 scp : pointer to the chain for the sorted position at which we
10551 should insert in the middle of the struct component list
10552 (else NULL to insert at end).
10553 alloc_node : the "alloc" node for the structure (pointer-type)
10554 component. We insert at SCP (if present), else SC
10555 (the end of the struct component list).
10556 extra_node : a newly-synthesized node for an additional indirect
10557 pointer mapping or a Fortran pointer set, if needed.
10558 cl : first node to prepend before grp_start_p.
10559 tail_chain : pointer to chain of last prepended node.
10561 The general idea is we move the nodes for this struct mapping
10562 together: the alloc node goes into the sorted list directly after
10563 the struct mapping, and any extra nodes (together with the nodes
10564 mapping arrays pointed to by struct components) get moved after
10565 that list. When SCP is NULL, we insert the nodes at SC, i.e. at
10566 the end of the struct component mapping list. It's important that
10567 the alloc_node comes first in that case because it's part of the
10568 sorted component mapping list (but subsequent nodes are not!). */
10571 omp_siblist_insert_node_after (alloc_node
, scp
);
10573 /* Make [cl,tail_chain] a list of the alloc node (if we haven't
10574 already inserted it) and the extra_node (if it is present). The
10575 list can be empty if we added alloc_node above and there is no
10577 if (scp
&& extra_node
)
10580 tail_chain
= &OMP_CLAUSE_CHAIN (extra_node
);
10582 else if (extra_node
)
10584 OMP_CLAUSE_CHAIN (alloc_node
) = extra_node
;
10586 tail_chain
= &OMP_CLAUSE_CHAIN (extra_node
);
10591 tail_chain
= &OMP_CLAUSE_CHAIN (alloc_node
);
10595 = cl
? omp_siblist_move_concat_nodes_after (cl
, tail_chain
,
10596 grp_start_p
, grp_end
,
10598 : omp_siblist_move_nodes_after (grp_start_p
, grp_end
, sc
);
10600 else if (*sc
!= grp_end
)
10602 gcc_assert (*grp_start_p
== grp_end
);
10604 /* We are moving the current node back to a previous struct node:
10605 the node that used to point to the current node will now point to
10607 continue_at
= grp_start_p
;
10608 /* In the non-pointer case, the mapping clause itself is moved into
10609 the correct position in the struct component list, which in this
10610 case is just SC. */
10611 omp_siblist_move_node_after (*grp_start_p
, grp_start_p
, sc
);
10614 return continue_at
;
10617 /* Scan through GROUPS, and create sorted structure sibling lists without
10621 omp_build_struct_sibling_lists (enum tree_code code
,
10622 enum omp_region_type region_type
,
10623 vec
<omp_mapping_group
> *groups
,
10624 hash_map
<tree_operand_hash_no_se
,
10625 omp_mapping_group
*> **grpmap
,
10629 omp_mapping_group
*grp
;
10630 hash_map
<tree_operand_hash
, tree
> *struct_map_to_clause
= NULL
;
10631 bool success
= true;
10632 tree
*new_next
= NULL
;
10633 tree
*tail
= &OMP_CLAUSE_CHAIN ((*groups
)[groups
->length () - 1].grp_end
);
10634 auto_vec
<omp_mapping_group
> pre_hwm_groups
;
10636 FOR_EACH_VEC_ELT (*groups
, i
, grp
)
10638 tree c
= grp
->grp_end
;
10639 tree decl
= OMP_CLAUSE_DECL (c
);
10640 tree grp_end
= grp
->grp_end
;
10641 tree sentinel
= OMP_CLAUSE_CHAIN (grp_end
);
10644 grp
->grp_start
= new_next
;
10648 tree
*grp_start_p
= grp
->grp_start
;
10653 /* Skip groups we marked for deletion in
10654 oacc_resolve_clause_dependencies. */
10658 if (OMP_CLAUSE_CHAIN (*grp_start_p
)
10659 && OMP_CLAUSE_CHAIN (*grp_start_p
) != grp_end
)
10661 /* Don't process an array descriptor that isn't inside a derived type
10662 as a struct (the GOMP_MAP_POINTER following will have the form
10663 "var.data", but such mappings are handled specially). */
10664 tree grpmid
= OMP_CLAUSE_CHAIN (*grp_start_p
);
10665 if (OMP_CLAUSE_CODE (grpmid
) == OMP_CLAUSE_MAP
10666 && OMP_CLAUSE_MAP_KIND (grpmid
) == GOMP_MAP_TO_PSET
10667 && DECL_P (OMP_CLAUSE_DECL (grpmid
)))
10672 if (TREE_CODE (d
) == ARRAY_REF
)
10674 while (TREE_CODE (d
) == ARRAY_REF
)
10675 d
= TREE_OPERAND (d
, 0);
10676 if (TREE_CODE (d
) == COMPONENT_REF
10677 && TREE_CODE (TREE_TYPE (d
)) == ARRAY_TYPE
)
10681 && INDIRECT_REF_P (decl
)
10682 && TREE_CODE (TREE_OPERAND (decl
, 0)) == COMPONENT_REF
10683 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl
, 0)))
10685 && (OMP_CLAUSE_MAP_KIND (c
)
10686 != GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION
))
10687 decl
= TREE_OPERAND (decl
, 0);
10691 if (TREE_CODE (decl
) != COMPONENT_REF
)
10694 /* If we're mapping the whole struct in another node, skip adding this
10695 node to a sibling list. */
10696 omp_mapping_group
*wholestruct
;
10697 if (omp_mapped_by_containing_struct (*grpmap
, OMP_CLAUSE_DECL (c
),
10700 if (!(region_type
& ORT_ACC
)
10701 && *grp_start_p
== grp_end
)
10702 /* Remove the whole of this mapping -- redundant. */
10703 grp
->deleted
= true;
10708 if (OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_TO_PSET
10709 && OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_ATTACH
10710 && OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_DETACH
10711 && code
!= OACC_UPDATE
10712 && code
!= OMP_TARGET_UPDATE
)
10714 if (error_operand_p (decl
))
10720 tree stype
= TREE_TYPE (decl
);
10721 if (TREE_CODE (stype
) == REFERENCE_TYPE
)
10722 stype
= TREE_TYPE (stype
);
10723 if (TYPE_SIZE_UNIT (stype
) == NULL
10724 || TREE_CODE (TYPE_SIZE_UNIT (stype
)) != INTEGER_CST
)
10726 error_at (OMP_CLAUSE_LOCATION (c
),
10727 "mapping field %qE of variable length "
10728 "structure", OMP_CLAUSE_DECL (c
));
10733 tree inner
= NULL_TREE
;
10736 = omp_accumulate_sibling_list (region_type
, code
,
10737 struct_map_to_clause
, grp_start_p
,
10742 if (new_next
&& *new_next
== NULL_TREE
)
10747 OMP_CLAUSE_CHAIN (inner
) = NULL_TREE
;
10748 omp_mapping_group newgrp
;
10749 newgrp
.grp_start
= new_next
? new_next
: tail
;
10750 newgrp
.grp_end
= inner
;
10751 newgrp
.mark
= UNVISITED
;
10752 newgrp
.sibling
= NULL
;
10753 newgrp
.deleted
= false;
10754 newgrp
.next
= NULL
;
10755 groups
->safe_push (newgrp
);
10757 /* !!! Growing GROUPS might invalidate the pointers in the group
10758 map. Rebuild it here. This is a bit inefficient, but
10759 shouldn't happen very often. */
10762 = omp_reindex_mapping_groups (list_p
, groups
, &pre_hwm_groups
,
10765 tail
= &OMP_CLAUSE_CHAIN (inner
);
10770 /* Delete groups marked for deletion above. At this point the order of the
10771 groups may no longer correspond to the order of the underlying list,
10772 which complicates this a little. First clear out OMP_CLAUSE_DECL for
10773 deleted nodes... */
10775 FOR_EACH_VEC_ELT (*groups
, i
, grp
)
10777 for (tree d
= *grp
->grp_start
;
10778 d
!= OMP_CLAUSE_CHAIN (grp
->grp_end
);
10779 d
= OMP_CLAUSE_CHAIN (d
))
10780 OMP_CLAUSE_DECL (d
) = NULL_TREE
;
10782 /* ...then sweep through the list removing the now-empty nodes. */
10787 if (OMP_CLAUSE_CODE (*tail
) == OMP_CLAUSE_MAP
10788 && OMP_CLAUSE_DECL (*tail
) == NULL_TREE
)
10789 *tail
= OMP_CLAUSE_CHAIN (*tail
);
10791 tail
= &OMP_CLAUSE_CHAIN (*tail
);
10795 if (struct_map_to_clause
)
10796 delete struct_map_to_clause
;
10801 /* Scan the OMP clauses in *LIST_P, installing mappings into a new
10802 and previous omp contexts. */
10805 gimplify_scan_omp_clauses (tree
*list_p
, gimple_seq
*pre_p
,
10806 enum omp_region_type region_type
,
10807 enum tree_code code
)
10809 struct gimplify_omp_ctx
*ctx
, *outer_ctx
;
10811 tree
*orig_list_p
= list_p
;
10812 int handled_depend_iterators
= -1;
10815 ctx
= new_omp_context (region_type
);
10817 outer_ctx
= ctx
->outer_context
;
10818 if (code
== OMP_TARGET
)
10820 if (!lang_GNU_Fortran ())
10821 ctx
->defaultmap
[GDMK_POINTER
] = GOVD_MAP
| GOVD_MAP_0LEN_ARRAY
;
10822 ctx
->defaultmap
[GDMK_SCALAR
] = GOVD_FIRSTPRIVATE
;
10823 ctx
->defaultmap
[GDMK_SCALAR_TARGET
] = (lang_GNU_Fortran ()
10824 ? GOVD_MAP
: GOVD_FIRSTPRIVATE
);
10826 if (!lang_GNU_Fortran ())
10830 case OMP_TARGET_DATA
:
10831 case OMP_TARGET_ENTER_DATA
:
10832 case OMP_TARGET_EXIT_DATA
:
10834 case OACC_HOST_DATA
:
10835 case OACC_PARALLEL
:
10837 ctx
->target_firstprivatize_array_bases
= true;
10842 if (code
== OMP_TARGET
10843 || code
== OMP_TARGET_DATA
10844 || code
== OMP_TARGET_ENTER_DATA
10845 || code
== OMP_TARGET_EXIT_DATA
)
10847 vec
<omp_mapping_group
> *groups
;
10848 groups
= omp_gather_mapping_groups (list_p
);
10851 hash_map
<tree_operand_hash_no_se
, omp_mapping_group
*> *grpmap
;
10852 grpmap
= omp_index_mapping_groups (groups
);
10854 omp_build_struct_sibling_lists (code
, region_type
, groups
, &grpmap
,
10857 omp_mapping_group
*outlist
= NULL
;
10859 /* Topological sorting may fail if we have duplicate nodes, which
10860 we should have detected and shown an error for already. Skip
10861 sorting in that case. */
10868 /* Rebuild now we have struct sibling lists. */
10869 groups
= omp_gather_mapping_groups (list_p
);
10870 grpmap
= omp_index_mapping_groups (groups
);
10872 outlist
= omp_tsort_mapping_groups (groups
, grpmap
);
10873 outlist
= omp_segregate_mapping_groups (outlist
);
10874 list_p
= omp_reorder_mapping_groups (groups
, outlist
, list_p
);
10881 /* OpenMP map clauses with 'present' need to go in front of those
10883 tree present_map_head
= NULL
;
10884 tree
*present_map_tail_p
= &present_map_head
;
10885 tree
*first_map_clause_p
= NULL
;
10887 for (tree
*c_p
= list_p
; *c_p
; )
10890 tree
*next_c_p
= &OMP_CLAUSE_CHAIN (c
);
10892 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_MAP
)
10894 if (!first_map_clause_p
)
10895 first_map_clause_p
= c_p
;
10896 switch (OMP_CLAUSE_MAP_KIND (c
))
10898 case GOMP_MAP_PRESENT_ALLOC
:
10899 case GOMP_MAP_PRESENT_FROM
:
10900 case GOMP_MAP_PRESENT_TO
:
10901 case GOMP_MAP_PRESENT_TOFROM
:
10903 *c_p
= OMP_CLAUSE_CHAIN (c
);
10905 OMP_CLAUSE_CHAIN (c
) = NULL
;
10906 *present_map_tail_p
= c
;
10907 present_map_tail_p
= &OMP_CLAUSE_CHAIN (c
);
10918 if (first_map_clause_p
&& present_map_head
)
10920 tree next
= *first_map_clause_p
;
10921 *first_map_clause_p
= present_map_head
;
10922 *present_map_tail_p
= next
;
10925 else if (region_type
& ORT_ACC
)
10927 vec
<omp_mapping_group
> *groups
;
10928 groups
= omp_gather_mapping_groups (list_p
);
10931 hash_map
<tree_operand_hash_no_se
, omp_mapping_group
*> *grpmap
;
10932 grpmap
= omp_index_mapping_groups (groups
);
10934 oacc_resolve_clause_dependencies (groups
, grpmap
);
10935 omp_build_struct_sibling_lists (code
, region_type
, groups
, &grpmap
,
10943 while ((c
= *list_p
) != NULL
)
10945 bool remove
= false;
10946 bool notice_outer
= true;
10947 const char *check_non_private
= NULL
;
10948 unsigned int flags
;
10951 switch (OMP_CLAUSE_CODE (c
))
10953 case OMP_CLAUSE_PRIVATE
:
10954 flags
= GOVD_PRIVATE
| GOVD_EXPLICIT
;
10955 if (lang_hooks
.decls
.omp_private_outer_ref (OMP_CLAUSE_DECL (c
)))
10957 flags
|= GOVD_PRIVATE_OUTER_REF
;
10958 OMP_CLAUSE_PRIVATE_OUTER_REF (c
) = 1;
10961 notice_outer
= false;
10963 case OMP_CLAUSE_SHARED
:
10964 flags
= GOVD_SHARED
| GOVD_EXPLICIT
;
10966 case OMP_CLAUSE_FIRSTPRIVATE
:
10967 flags
= GOVD_FIRSTPRIVATE
| GOVD_EXPLICIT
;
10968 check_non_private
= "firstprivate";
10969 if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c
))
10971 gcc_assert (code
== OMP_TARGET
);
10972 flags
|= GOVD_FIRSTPRIVATE_IMPLICIT
;
10975 case OMP_CLAUSE_LASTPRIVATE
:
10976 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
))
10979 case OMP_DISTRIBUTE
:
10980 error_at (OMP_CLAUSE_LOCATION (c
),
10981 "conditional %<lastprivate%> clause on "
10982 "%qs construct", "distribute");
10983 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
) = 0;
10986 error_at (OMP_CLAUSE_LOCATION (c
),
10987 "conditional %<lastprivate%> clause on "
10988 "%qs construct", "taskloop");
10989 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
) = 0;
10994 flags
= GOVD_LASTPRIVATE
| GOVD_SEEN
| GOVD_EXPLICIT
;
10995 if (code
!= OMP_LOOP
)
10996 check_non_private
= "lastprivate";
10997 decl
= OMP_CLAUSE_DECL (c
);
10998 if (error_operand_p (decl
))
11000 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
)
11001 && !lang_hooks
.decls
.omp_scalar_p (decl
, true))
11003 error_at (OMP_CLAUSE_LOCATION (c
),
11004 "non-scalar variable %qD in conditional "
11005 "%<lastprivate%> clause", decl
);
11006 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
) = 0;
11008 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
))
11009 flags
|= GOVD_LASTPRIVATE_CONDITIONAL
;
11010 omp_lastprivate_for_combined_outer_constructs (outer_ctx
, decl
,
11013 case OMP_CLAUSE_REDUCTION
:
11014 if (OMP_CLAUSE_REDUCTION_TASK (c
))
11016 if (region_type
== ORT_WORKSHARE
|| code
== OMP_SCOPE
)
11019 nowait
= omp_find_clause (*list_p
,
11020 OMP_CLAUSE_NOWAIT
) != NULL_TREE
;
11022 && (outer_ctx
== NULL
11023 || outer_ctx
->region_type
!= ORT_COMBINED_PARALLEL
))
11025 error_at (OMP_CLAUSE_LOCATION (c
),
11026 "%<task%> reduction modifier on a construct "
11027 "with a %<nowait%> clause");
11028 OMP_CLAUSE_REDUCTION_TASK (c
) = 0;
11031 else if ((region_type
& ORT_PARALLEL
) != ORT_PARALLEL
)
11033 error_at (OMP_CLAUSE_LOCATION (c
),
11034 "invalid %<task%> reduction modifier on construct "
11035 "other than %<parallel%>, %qs, %<sections%> or "
11036 "%<scope%>", lang_GNU_Fortran () ? "do" : "for");
11037 OMP_CLAUSE_REDUCTION_TASK (c
) = 0;
11040 if (OMP_CLAUSE_REDUCTION_INSCAN (c
))
11044 error_at (OMP_CLAUSE_LOCATION (c
),
11045 "%<inscan%> %<reduction%> clause on "
11046 "%qs construct", "sections");
11047 OMP_CLAUSE_REDUCTION_INSCAN (c
) = 0;
11050 error_at (OMP_CLAUSE_LOCATION (c
),
11051 "%<inscan%> %<reduction%> clause on "
11052 "%qs construct", "parallel");
11053 OMP_CLAUSE_REDUCTION_INSCAN (c
) = 0;
11056 error_at (OMP_CLAUSE_LOCATION (c
),
11057 "%<inscan%> %<reduction%> clause on "
11058 "%qs construct", "teams");
11059 OMP_CLAUSE_REDUCTION_INSCAN (c
) = 0;
11062 error_at (OMP_CLAUSE_LOCATION (c
),
11063 "%<inscan%> %<reduction%> clause on "
11064 "%qs construct", "taskloop");
11065 OMP_CLAUSE_REDUCTION_INSCAN (c
) = 0;
11068 error_at (OMP_CLAUSE_LOCATION (c
),
11069 "%<inscan%> %<reduction%> clause on "
11070 "%qs construct", "scope");
11071 OMP_CLAUSE_REDUCTION_INSCAN (c
) = 0;
11077 case OMP_CLAUSE_IN_REDUCTION
:
11078 case OMP_CLAUSE_TASK_REDUCTION
:
11079 flags
= GOVD_REDUCTION
| GOVD_SEEN
| GOVD_EXPLICIT
;
11080 /* OpenACC permits reductions on private variables. */
11081 if (!(region_type
& ORT_ACC
)
11082 /* taskgroup is actually not a worksharing region. */
11083 && code
!= OMP_TASKGROUP
)
11084 check_non_private
= omp_clause_code_name
[OMP_CLAUSE_CODE (c
)];
11085 decl
= OMP_CLAUSE_DECL (c
);
11086 if (TREE_CODE (decl
) == MEM_REF
)
11088 tree type
= TREE_TYPE (decl
);
11089 bool saved_into_ssa
= gimplify_ctxp
->into_ssa
;
11090 gimplify_ctxp
->into_ssa
= false;
11091 if (gimplify_expr (&TYPE_MAX_VALUE (TYPE_DOMAIN (type
)), pre_p
,
11092 NULL
, is_gimple_val
, fb_rvalue
, false)
11095 gimplify_ctxp
->into_ssa
= saved_into_ssa
;
11099 gimplify_ctxp
->into_ssa
= saved_into_ssa
;
11100 tree v
= TYPE_MAX_VALUE (TYPE_DOMAIN (type
));
11103 omp_firstprivatize_variable (ctx
, v
);
11104 omp_notice_variable (ctx
, v
, true);
11106 decl
= TREE_OPERAND (decl
, 0);
11107 if (TREE_CODE (decl
) == POINTER_PLUS_EXPR
)
11109 gimplify_ctxp
->into_ssa
= false;
11110 if (gimplify_expr (&TREE_OPERAND (decl
, 1), pre_p
,
11111 NULL
, is_gimple_val
, fb_rvalue
, false)
11114 gimplify_ctxp
->into_ssa
= saved_into_ssa
;
11118 gimplify_ctxp
->into_ssa
= saved_into_ssa
;
11119 v
= TREE_OPERAND (decl
, 1);
11122 omp_firstprivatize_variable (ctx
, v
);
11123 omp_notice_variable (ctx
, v
, true);
11125 decl
= TREE_OPERAND (decl
, 0);
11127 if (TREE_CODE (decl
) == ADDR_EXPR
11128 || TREE_CODE (decl
) == INDIRECT_REF
)
11129 decl
= TREE_OPERAND (decl
, 0);
11132 case OMP_CLAUSE_LINEAR
:
11133 if (gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c
), pre_p
, NULL
,
11134 is_gimple_val
, fb_rvalue
) == GS_ERROR
)
11141 if (code
== OMP_SIMD
11142 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c
))
11144 struct gimplify_omp_ctx
*octx
= outer_ctx
;
11146 && octx
->region_type
== ORT_WORKSHARE
11147 && octx
->combined_loop
11148 && !octx
->distribute
)
11150 if (octx
->outer_context
11151 && (octx
->outer_context
->region_type
11152 == ORT_COMBINED_PARALLEL
))
11153 octx
= octx
->outer_context
->outer_context
;
11155 octx
= octx
->outer_context
;
11158 && octx
->region_type
== ORT_WORKSHARE
11159 && octx
->combined_loop
11160 && octx
->distribute
)
11162 error_at (OMP_CLAUSE_LOCATION (c
),
11163 "%<linear%> clause for variable other than "
11164 "loop iterator specified on construct "
11165 "combined with %<distribute%>");
11170 /* For combined #pragma omp parallel for simd, need to put
11171 lastprivate and perhaps firstprivate too on the
11172 parallel. Similarly for #pragma omp for simd. */
11173 struct gimplify_omp_ctx
*octx
= outer_ctx
;
11174 bool taskloop_seen
= false;
11178 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c
)
11179 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c
))
11181 decl
= OMP_CLAUSE_DECL (c
);
11182 if (error_operand_p (decl
))
11188 if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c
))
11189 flags
|= GOVD_FIRSTPRIVATE
;
11190 if (!OMP_CLAUSE_LINEAR_NO_COPYOUT (c
))
11191 flags
|= GOVD_LASTPRIVATE
;
11193 && octx
->region_type
== ORT_WORKSHARE
11194 && octx
->combined_loop
)
11196 if (octx
->outer_context
11197 && (octx
->outer_context
->region_type
11198 == ORT_COMBINED_PARALLEL
))
11199 octx
= octx
->outer_context
;
11200 else if (omp_check_private (octx
, decl
, false))
11204 && (octx
->region_type
& ORT_TASK
) != 0
11205 && octx
->combined_loop
)
11206 taskloop_seen
= true;
11208 && octx
->region_type
== ORT_COMBINED_PARALLEL
11209 && ((ctx
->region_type
== ORT_WORKSHARE
11210 && octx
== outer_ctx
)
11212 flags
= GOVD_SEEN
| GOVD_SHARED
;
11214 && ((octx
->region_type
& ORT_COMBINED_TEAMS
)
11215 == ORT_COMBINED_TEAMS
))
11216 flags
= GOVD_SEEN
| GOVD_SHARED
;
11218 && octx
->region_type
== ORT_COMBINED_TARGET
)
11220 if (flags
& GOVD_LASTPRIVATE
)
11221 flags
= GOVD_SEEN
| GOVD_MAP
;
11226 = splay_tree_lookup (octx
->variables
,
11227 (splay_tree_key
) decl
);
11228 if (on
&& (on
->value
& GOVD_DATA_SHARE_CLASS
) != 0)
11233 omp_add_variable (octx
, decl
, flags
);
11234 if (octx
->outer_context
== NULL
)
11236 octx
= octx
->outer_context
;
11241 && (!OMP_CLAUSE_LINEAR_NO_COPYIN (c
)
11242 || !OMP_CLAUSE_LINEAR_NO_COPYOUT (c
)))
11243 omp_notice_variable (octx
, decl
, true);
11245 flags
= GOVD_LINEAR
| GOVD_EXPLICIT
;
11246 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c
)
11247 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c
))
11249 notice_outer
= false;
11250 flags
|= GOVD_LINEAR_LASTPRIVATE_NO_OUTER
;
11254 case OMP_CLAUSE_MAP
:
11255 decl
= OMP_CLAUSE_DECL (c
);
11256 if (error_operand_p (decl
))
11263 if (TREE_CODE (TREE_TYPE (decl
)) != ARRAY_TYPE
)
11266 case OMP_TARGET_DATA
:
11267 case OMP_TARGET_ENTER_DATA
:
11268 case OMP_TARGET_EXIT_DATA
:
11269 case OACC_ENTER_DATA
:
11270 case OACC_EXIT_DATA
:
11271 case OACC_HOST_DATA
:
11272 if (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_FIRSTPRIVATE_POINTER
11273 || (OMP_CLAUSE_MAP_KIND (c
)
11274 == GOMP_MAP_FIRSTPRIVATE_REFERENCE
))
11275 /* For target {,enter ,exit }data only the array slice is
11276 mapped, but not the pointer to it. */
11284 if (DECL_P (decl
) && outer_ctx
&& (region_type
& ORT_ACC
))
11286 struct gimplify_omp_ctx
*octx
;
11287 for (octx
= outer_ctx
; octx
; octx
= octx
->outer_context
)
11289 if (octx
->region_type
!= ORT_ACC_HOST_DATA
)
11292 = splay_tree_lookup (octx
->variables
,
11293 (splay_tree_key
) decl
);
11295 error_at (OMP_CLAUSE_LOCATION (c
), "variable %qE "
11296 "declared in enclosing %<host_data%> region",
11300 if (OMP_CLAUSE_SIZE (c
) == NULL_TREE
)
11301 OMP_CLAUSE_SIZE (c
) = DECL_P (decl
) ? DECL_SIZE_UNIT (decl
)
11302 : TYPE_SIZE_UNIT (TREE_TYPE (decl
));
11303 if (gimplify_expr (&OMP_CLAUSE_SIZE (c
), pre_p
,
11304 NULL
, is_gimple_val
, fb_rvalue
) == GS_ERROR
)
11309 else if ((OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_FIRSTPRIVATE_POINTER
11310 || (OMP_CLAUSE_MAP_KIND (c
)
11311 == GOMP_MAP_FIRSTPRIVATE_REFERENCE
)
11312 || OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ATTACH_DETACH
)
11313 && TREE_CODE (OMP_CLAUSE_SIZE (c
)) != INTEGER_CST
)
11315 OMP_CLAUSE_SIZE (c
)
11316 = get_initialized_tmp_var (OMP_CLAUSE_SIZE (c
), pre_p
, NULL
,
11318 if ((region_type
& ORT_TARGET
) != 0)
11319 omp_add_variable (ctx
, OMP_CLAUSE_SIZE (c
),
11320 GOVD_FIRSTPRIVATE
| GOVD_SEEN
);
11323 if (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_STRUCT
)
11325 tree base
= omp_strip_components_and_deref (decl
);
11330 = splay_tree_lookup (ctx
->variables
,
11331 (splay_tree_key
) decl
);
11334 && (n
->value
& (GOVD_MAP
| GOVD_FIRSTPRIVATE
)) != 0)
11339 flags
= GOVD_MAP
| GOVD_EXPLICIT
;
11345 if (TREE_CODE (decl
) == TARGET_EXPR
)
11347 if (gimplify_expr (&OMP_CLAUSE_DECL (c
), pre_p
, NULL
,
11348 is_gimple_lvalue
, fb_lvalue
)
11352 else if (!DECL_P (decl
))
11354 tree d
= decl
, *pd
;
11355 if (TREE_CODE (d
) == ARRAY_REF
)
11357 while (TREE_CODE (d
) == ARRAY_REF
)
11358 d
= TREE_OPERAND (d
, 0);
11359 if (TREE_CODE (d
) == COMPONENT_REF
11360 && TREE_CODE (TREE_TYPE (d
)) == ARRAY_TYPE
)
11363 pd
= &OMP_CLAUSE_DECL (c
);
11365 && TREE_CODE (decl
) == INDIRECT_REF
11366 && TREE_CODE (TREE_OPERAND (decl
, 0)) == COMPONENT_REF
11367 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl
, 0)))
11369 && (OMP_CLAUSE_MAP_KIND (c
)
11370 != GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION
))
11372 pd
= &TREE_OPERAND (decl
, 0);
11373 decl
= TREE_OPERAND (decl
, 0);
11375 /* An "attach/detach" operation on an update directive should
11376 behave as a GOMP_MAP_ALWAYS_POINTER. Beware that
11377 unlike attach or detach map kinds, GOMP_MAP_ALWAYS_POINTER
11378 depends on the previous mapping. */
11379 if (code
== OACC_UPDATE
11380 && OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ATTACH_DETACH
)
11381 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_ALWAYS_POINTER
);
11383 if (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ATTACH_DETACH
)
11385 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c
)))
11390 gomp_map_kind k
= ((code
== OACC_EXIT_DATA
11391 || code
== OMP_TARGET_EXIT_DATA
)
11392 ? GOMP_MAP_DETACH
: GOMP_MAP_ATTACH
);
11393 OMP_CLAUSE_SET_MAP_KIND (c
, k
);
11399 while (TREE_CODE (cref
) == ARRAY_REF
)
11400 cref
= TREE_OPERAND (cref
, 0);
11402 if (TREE_CODE (cref
) == INDIRECT_REF
)
11403 cref
= TREE_OPERAND (cref
, 0);
11405 if (TREE_CODE (cref
) == COMPONENT_REF
)
11408 while (base
&& !DECL_P (base
))
11410 tree innerbase
= omp_get_base_pointer (base
);
11417 && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c
))
11418 && POINTER_TYPE_P (TREE_TYPE (base
)))
11421 = splay_tree_lookup (ctx
->variables
,
11422 (splay_tree_key
) base
);
11423 n
->value
|= GOVD_SEEN
;
11427 if (code
== OMP_TARGET
&& OMP_CLAUSE_MAP_IN_REDUCTION (c
))
11429 /* Don't gimplify *pd fully at this point, as the base
11430 will need to be adjusted during omp lowering. */
11431 auto_vec
<tree
, 10> expr_stack
;
11433 while (handled_component_p (*p
)
11434 || TREE_CODE (*p
) == INDIRECT_REF
11435 || TREE_CODE (*p
) == ADDR_EXPR
11436 || TREE_CODE (*p
) == MEM_REF
11437 || TREE_CODE (*p
) == NON_LVALUE_EXPR
)
11439 expr_stack
.safe_push (*p
);
11440 p
= &TREE_OPERAND (*p
, 0);
11442 for (int i
= expr_stack
.length () - 1; i
>= 0; i
--)
11444 tree t
= expr_stack
[i
];
11445 if (TREE_CODE (t
) == ARRAY_REF
11446 || TREE_CODE (t
) == ARRAY_RANGE_REF
)
11448 if (TREE_OPERAND (t
, 2) == NULL_TREE
)
11450 tree low
= unshare_expr (array_ref_low_bound (t
));
11451 if (!is_gimple_min_invariant (low
))
11453 TREE_OPERAND (t
, 2) = low
;
11454 if (gimplify_expr (&TREE_OPERAND (t
, 2),
11457 fb_rvalue
) == GS_ERROR
)
11461 else if (gimplify_expr (&TREE_OPERAND (t
, 2), pre_p
,
11462 NULL
, is_gimple_reg
,
11463 fb_rvalue
) == GS_ERROR
)
11465 if (TREE_OPERAND (t
, 3) == NULL_TREE
)
11467 tree elmt_size
= array_ref_element_size (t
);
11468 if (!is_gimple_min_invariant (elmt_size
))
11470 elmt_size
= unshare_expr (elmt_size
);
11472 = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t
,
11475 = size_int (TYPE_ALIGN_UNIT (elmt_type
));
11477 = size_binop (EXACT_DIV_EXPR
, elmt_size
,
11479 TREE_OPERAND (t
, 3) = elmt_size
;
11480 if (gimplify_expr (&TREE_OPERAND (t
, 3),
11483 fb_rvalue
) == GS_ERROR
)
11487 else if (gimplify_expr (&TREE_OPERAND (t
, 3), pre_p
,
11488 NULL
, is_gimple_reg
,
11489 fb_rvalue
) == GS_ERROR
)
11492 else if (TREE_CODE (t
) == COMPONENT_REF
)
11494 if (TREE_OPERAND (t
, 2) == NULL_TREE
)
11496 tree offset
= component_ref_field_offset (t
);
11497 if (!is_gimple_min_invariant (offset
))
11499 offset
= unshare_expr (offset
);
11500 tree field
= TREE_OPERAND (t
, 1);
11502 = size_int (DECL_OFFSET_ALIGN (field
)
11504 offset
= size_binop (EXACT_DIV_EXPR
, offset
,
11506 TREE_OPERAND (t
, 2) = offset
;
11507 if (gimplify_expr (&TREE_OPERAND (t
, 2),
11510 fb_rvalue
) == GS_ERROR
)
11514 else if (gimplify_expr (&TREE_OPERAND (t
, 2), pre_p
,
11515 NULL
, is_gimple_reg
,
11516 fb_rvalue
) == GS_ERROR
)
11520 for (; expr_stack
.length () > 0; )
11522 tree t
= expr_stack
.pop ();
11524 if (TREE_CODE (t
) == ARRAY_REF
11525 || TREE_CODE (t
) == ARRAY_RANGE_REF
)
11527 if (!is_gimple_min_invariant (TREE_OPERAND (t
, 1))
11528 && gimplify_expr (&TREE_OPERAND (t
, 1), pre_p
,
11529 NULL
, is_gimple_val
,
11530 fb_rvalue
) == GS_ERROR
)
11535 else if (gimplify_expr (pd
, pre_p
, NULL
, is_gimple_lvalue
,
11536 fb_lvalue
) == GS_ERROR
)
11543 flags
= GOVD_MAP
| GOVD_EXPLICIT
;
11544 if (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ALWAYS_TO
11545 || OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ALWAYS_TOFROM
)
11546 flags
|= GOVD_MAP_ALWAYS_TO
;
11548 if ((code
== OMP_TARGET
11549 || code
== OMP_TARGET_DATA
11550 || code
== OMP_TARGET_ENTER_DATA
11551 || code
== OMP_TARGET_EXIT_DATA
)
11552 && OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ATTACH_DETACH
)
11554 for (struct gimplify_omp_ctx
*octx
= outer_ctx
; octx
;
11555 octx
= octx
->outer_context
)
11558 = splay_tree_lookup (octx
->variables
,
11559 (splay_tree_key
) OMP_CLAUSE_DECL (c
));
11560 /* If this is contained in an outer OpenMP region as a
11561 firstprivate value, remove the attach/detach. */
11562 if (n
&& (n
->value
& GOVD_FIRSTPRIVATE
))
11564 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_FIRSTPRIVATE_POINTER
);
11569 enum gomp_map_kind map_kind
= (code
== OMP_TARGET_EXIT_DATA
11571 : GOMP_MAP_ATTACH
);
11572 OMP_CLAUSE_SET_MAP_KIND (c
, map_kind
);
11577 case OMP_CLAUSE_AFFINITY
:
11578 gimplify_omp_affinity (list_p
, pre_p
);
11581 case OMP_CLAUSE_DOACROSS
:
11582 if (OMP_CLAUSE_DOACROSS_KIND (c
) == OMP_CLAUSE_DOACROSS_SINK
)
11584 tree deps
= OMP_CLAUSE_DECL (c
);
11585 while (deps
&& TREE_CODE (deps
) == TREE_LIST
)
11587 if (TREE_CODE (TREE_PURPOSE (deps
)) == TRUNC_DIV_EXPR
11588 && DECL_P (TREE_OPERAND (TREE_PURPOSE (deps
), 1)))
11589 gimplify_expr (&TREE_OPERAND (TREE_PURPOSE (deps
), 1),
11590 pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
11591 deps
= TREE_CHAIN (deps
);
11595 gcc_assert (OMP_CLAUSE_DOACROSS_KIND (c
)
11596 == OMP_CLAUSE_DOACROSS_SOURCE
);
11598 case OMP_CLAUSE_DEPEND
:
11599 if (handled_depend_iterators
== -1)
11600 handled_depend_iterators
= gimplify_omp_depend (list_p
, pre_p
);
11601 if (handled_depend_iterators
)
11603 if (handled_depend_iterators
== 2)
11607 if (TREE_CODE (OMP_CLAUSE_DECL (c
)) == COMPOUND_EXPR
)
11609 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c
), 0), pre_p
,
11610 NULL
, is_gimple_val
, fb_rvalue
);
11611 OMP_CLAUSE_DECL (c
) = TREE_OPERAND (OMP_CLAUSE_DECL (c
), 1);
11613 if (error_operand_p (OMP_CLAUSE_DECL (c
)))
11618 if (OMP_CLAUSE_DECL (c
) != null_pointer_node
)
11620 OMP_CLAUSE_DECL (c
) = build_fold_addr_expr (OMP_CLAUSE_DECL (c
));
11621 if (gimplify_expr (&OMP_CLAUSE_DECL (c
), pre_p
, NULL
,
11622 is_gimple_val
, fb_rvalue
) == GS_ERROR
)
11628 if (code
== OMP_TASK
)
11629 ctx
->has_depend
= true;
11632 case OMP_CLAUSE_TO
:
11633 case OMP_CLAUSE_FROM
:
11634 case OMP_CLAUSE__CACHE_
:
11635 decl
= OMP_CLAUSE_DECL (c
);
11636 if (error_operand_p (decl
))
11641 if (OMP_CLAUSE_SIZE (c
) == NULL_TREE
)
11642 OMP_CLAUSE_SIZE (c
) = DECL_P (decl
) ? DECL_SIZE_UNIT (decl
)
11643 : TYPE_SIZE_UNIT (TREE_TYPE (decl
));
11644 if (gimplify_expr (&OMP_CLAUSE_SIZE (c
), pre_p
,
11645 NULL
, is_gimple_val
, fb_rvalue
) == GS_ERROR
)
11650 if (!DECL_P (decl
))
11652 if (gimplify_expr (&OMP_CLAUSE_DECL (c
), pre_p
,
11653 NULL
, is_gimple_lvalue
, fb_lvalue
)
11663 case OMP_CLAUSE_USE_DEVICE_PTR
:
11664 case OMP_CLAUSE_USE_DEVICE_ADDR
:
11665 flags
= GOVD_EXPLICIT
;
11668 case OMP_CLAUSE_HAS_DEVICE_ADDR
:
11669 decl
= OMP_CLAUSE_DECL (c
);
11670 while (TREE_CODE (decl
) == INDIRECT_REF
11671 || TREE_CODE (decl
) == ARRAY_REF
)
11672 decl
= TREE_OPERAND (decl
, 0);
11673 flags
= GOVD_EXPLICIT
;
11676 case OMP_CLAUSE_IS_DEVICE_PTR
:
11677 flags
= GOVD_FIRSTPRIVATE
| GOVD_EXPLICIT
;
11681 decl
= OMP_CLAUSE_DECL (c
);
11683 if (error_operand_p (decl
))
11688 if (DECL_NAME (decl
) == NULL_TREE
&& (flags
& GOVD_SHARED
) == 0)
11690 tree t
= omp_member_access_dummy_var (decl
);
11693 tree v
= DECL_VALUE_EXPR (decl
);
11694 DECL_NAME (decl
) = DECL_NAME (TREE_OPERAND (v
, 1));
11696 omp_notice_variable (outer_ctx
, t
, true);
11699 if (code
== OACC_DATA
11700 && OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_MAP
11701 && OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_FIRSTPRIVATE_POINTER
)
11702 flags
|= GOVD_MAP_0LEN_ARRAY
;
11703 omp_add_variable (ctx
, decl
, flags
);
11704 if ((OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
11705 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_IN_REDUCTION
11706 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_TASK_REDUCTION
)
11707 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
))
11709 struct gimplify_omp_ctx
*pctx
11710 = code
== OMP_TARGET
? outer_ctx
: ctx
;
11712 omp_add_variable (pctx
, OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
),
11713 GOVD_LOCAL
| GOVD_SEEN
);
11715 && OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c
)
11716 && walk_tree (&OMP_CLAUSE_REDUCTION_INIT (c
),
11718 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c
),
11719 NULL
) == NULL_TREE
)
11720 omp_add_variable (pctx
,
11721 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c
),
11722 GOVD_LOCAL
| GOVD_SEEN
);
11723 gimplify_omp_ctxp
= pctx
;
11724 push_gimplify_context ();
11726 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c
) = NULL
;
11727 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c
) = NULL
;
11729 gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c
),
11730 &OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c
));
11731 pop_gimplify_context
11732 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c
)));
11733 push_gimplify_context ();
11734 gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c
),
11735 &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c
));
11736 pop_gimplify_context
11737 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c
)));
11738 OMP_CLAUSE_REDUCTION_INIT (c
) = NULL_TREE
;
11739 OMP_CLAUSE_REDUCTION_MERGE (c
) = NULL_TREE
;
11741 gimplify_omp_ctxp
= outer_ctx
;
11743 else if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
11744 && OMP_CLAUSE_LASTPRIVATE_STMT (c
))
11746 gimplify_omp_ctxp
= ctx
;
11747 push_gimplify_context ();
11748 if (TREE_CODE (OMP_CLAUSE_LASTPRIVATE_STMT (c
)) != BIND_EXPR
)
11750 tree bind
= build3 (BIND_EXPR
, void_type_node
, NULL
,
11752 TREE_SIDE_EFFECTS (bind
) = 1;
11753 BIND_EXPR_BODY (bind
) = OMP_CLAUSE_LASTPRIVATE_STMT (c
);
11754 OMP_CLAUSE_LASTPRIVATE_STMT (c
) = bind
;
11756 gimplify_and_add (OMP_CLAUSE_LASTPRIVATE_STMT (c
),
11757 &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
));
11758 pop_gimplify_context
11759 (gimple_seq_first_stmt (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
)));
11760 OMP_CLAUSE_LASTPRIVATE_STMT (c
) = NULL_TREE
;
11762 gimplify_omp_ctxp
= outer_ctx
;
11764 else if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINEAR
11765 && OMP_CLAUSE_LINEAR_STMT (c
))
11767 gimplify_omp_ctxp
= ctx
;
11768 push_gimplify_context ();
11769 if (TREE_CODE (OMP_CLAUSE_LINEAR_STMT (c
)) != BIND_EXPR
)
11771 tree bind
= build3 (BIND_EXPR
, void_type_node
, NULL
,
11773 TREE_SIDE_EFFECTS (bind
) = 1;
11774 BIND_EXPR_BODY (bind
) = OMP_CLAUSE_LINEAR_STMT (c
);
11775 OMP_CLAUSE_LINEAR_STMT (c
) = bind
;
11777 gimplify_and_add (OMP_CLAUSE_LINEAR_STMT (c
),
11778 &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c
));
11779 pop_gimplify_context
11780 (gimple_seq_first_stmt (OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c
)));
11781 OMP_CLAUSE_LINEAR_STMT (c
) = NULL_TREE
;
11783 gimplify_omp_ctxp
= outer_ctx
;
11789 case OMP_CLAUSE_COPYIN
:
11790 case OMP_CLAUSE_COPYPRIVATE
:
11791 decl
= OMP_CLAUSE_DECL (c
);
11792 if (error_operand_p (decl
))
11797 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_COPYPRIVATE
11799 && !omp_check_private (ctx
, decl
, true))
11802 if (is_global_var (decl
))
11804 if (DECL_THREAD_LOCAL_P (decl
))
11806 else if (DECL_HAS_VALUE_EXPR_P (decl
))
11808 tree value
= get_base_address (DECL_VALUE_EXPR (decl
));
11812 && DECL_THREAD_LOCAL_P (value
))
11817 error_at (OMP_CLAUSE_LOCATION (c
),
11818 "copyprivate variable %qE is not threadprivate"
11819 " or private in outer context", DECL_NAME (decl
));
11822 if ((OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
11823 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_FIRSTPRIVATE
11824 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
)
11826 && ((region_type
& ORT_TASKLOOP
) == ORT_TASKLOOP
11827 || (region_type
== ORT_WORKSHARE
11828 && OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
11829 && (OMP_CLAUSE_REDUCTION_INSCAN (c
)
11830 || code
== OMP_LOOP
)))
11831 && (outer_ctx
->region_type
== ORT_COMBINED_PARALLEL
11832 || (code
== OMP_LOOP
11833 && OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
11834 && ((outer_ctx
->region_type
& ORT_COMBINED_TEAMS
)
11835 == ORT_COMBINED_TEAMS
))))
11838 = splay_tree_lookup (outer_ctx
->variables
,
11839 (splay_tree_key
)decl
);
11840 if (on
== NULL
|| (on
->value
& GOVD_DATA_SHARE_CLASS
) == 0)
11842 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
11843 && TREE_CODE (OMP_CLAUSE_DECL (c
)) == MEM_REF
11844 && (TREE_CODE (TREE_TYPE (decl
)) == POINTER_TYPE
11845 || (TREE_CODE (TREE_TYPE (decl
)) == REFERENCE_TYPE
11846 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl
)))
11847 == POINTER_TYPE
))))
11848 omp_firstprivatize_variable (outer_ctx
, decl
);
11851 omp_add_variable (outer_ctx
, decl
,
11852 GOVD_SEEN
| GOVD_SHARED
);
11853 if (outer_ctx
->outer_context
)
11854 omp_notice_variable (outer_ctx
->outer_context
, decl
,
11860 omp_notice_variable (outer_ctx
, decl
, true);
11861 if (check_non_private
11862 && (region_type
== ORT_WORKSHARE
|| code
== OMP_SCOPE
)
11863 && (OMP_CLAUSE_CODE (c
) != OMP_CLAUSE_REDUCTION
11864 || decl
== OMP_CLAUSE_DECL (c
)
11865 || (TREE_CODE (OMP_CLAUSE_DECL (c
)) == MEM_REF
11866 && (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c
), 0))
11868 || (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c
), 0))
11869 == POINTER_PLUS_EXPR
11870 && (TREE_CODE (TREE_OPERAND (TREE_OPERAND
11871 (OMP_CLAUSE_DECL (c
), 0), 0))
11873 && omp_check_private (ctx
, decl
, false))
11875 error ("%s variable %qE is private in outer context",
11876 check_non_private
, DECL_NAME (decl
));
11881 case OMP_CLAUSE_DETACH
:
11882 flags
= GOVD_FIRSTPRIVATE
| GOVD_SEEN
;
11885 case OMP_CLAUSE_IF
:
11886 if (OMP_CLAUSE_IF_MODIFIER (c
) != ERROR_MARK
11887 && OMP_CLAUSE_IF_MODIFIER (c
) != code
)
11890 for (int i
= 0; i
< 2; i
++)
11891 switch (i
? OMP_CLAUSE_IF_MODIFIER (c
) : code
)
11893 case VOID_CST
: p
[i
] = "cancel"; break;
11894 case OMP_PARALLEL
: p
[i
] = "parallel"; break;
11895 case OMP_SIMD
: p
[i
] = "simd"; break;
11896 case OMP_TASK
: p
[i
] = "task"; break;
11897 case OMP_TASKLOOP
: p
[i
] = "taskloop"; break;
11898 case OMP_TARGET_DATA
: p
[i
] = "target data"; break;
11899 case OMP_TARGET
: p
[i
] = "target"; break;
11900 case OMP_TARGET_UPDATE
: p
[i
] = "target update"; break;
11901 case OMP_TARGET_ENTER_DATA
:
11902 p
[i
] = "target enter data"; break;
11903 case OMP_TARGET_EXIT_DATA
: p
[i
] = "target exit data"; break;
11904 default: gcc_unreachable ();
11906 error_at (OMP_CLAUSE_LOCATION (c
),
11907 "expected %qs %<if%> clause modifier rather than %qs",
11911 /* Fall through. */
11913 case OMP_CLAUSE_FINAL
:
11914 OMP_CLAUSE_OPERAND (c
, 0)
11915 = gimple_boolify (OMP_CLAUSE_OPERAND (c
, 0));
11916 /* Fall through. */
11918 case OMP_CLAUSE_NUM_TEAMS
:
11919 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_NUM_TEAMS
11920 && OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c
)
11921 && !is_gimple_min_invariant (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c
)))
11923 if (error_operand_p (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c
)))
11928 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c
)
11929 = get_initialized_tmp_var (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c
),
11930 pre_p
, NULL
, true);
11932 /* Fall through. */
11934 case OMP_CLAUSE_SCHEDULE
:
11935 case OMP_CLAUSE_NUM_THREADS
:
11936 case OMP_CLAUSE_THREAD_LIMIT
:
11937 case OMP_CLAUSE_DIST_SCHEDULE
:
11938 case OMP_CLAUSE_DEVICE
:
11939 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEVICE
11940 && OMP_CLAUSE_DEVICE_ANCESTOR (c
))
11942 if (code
!= OMP_TARGET
)
11944 error_at (OMP_CLAUSE_LOCATION (c
),
11945 "%<device%> clause with %<ancestor%> is only "
11946 "allowed on %<target%> construct");
11951 tree clauses
= *orig_list_p
;
11952 for (; clauses
; clauses
= OMP_CLAUSE_CHAIN (clauses
))
11953 if (OMP_CLAUSE_CODE (clauses
) != OMP_CLAUSE_DEVICE
11954 && OMP_CLAUSE_CODE (clauses
) != OMP_CLAUSE_FIRSTPRIVATE
11955 && OMP_CLAUSE_CODE (clauses
) != OMP_CLAUSE_PRIVATE
11956 && OMP_CLAUSE_CODE (clauses
) != OMP_CLAUSE_DEFAULTMAP
11957 && OMP_CLAUSE_CODE (clauses
) != OMP_CLAUSE_MAP
11960 error_at (OMP_CLAUSE_LOCATION (c
),
11961 "with %<ancestor%>, only the %<device%>, "
11962 "%<firstprivate%>, %<private%>, %<defaultmap%>, "
11963 "and %<map%> clauses may appear on the "
11969 /* Fall through. */
11971 case OMP_CLAUSE_PRIORITY
:
11972 case OMP_CLAUSE_GRAINSIZE
:
11973 case OMP_CLAUSE_NUM_TASKS
:
11974 case OMP_CLAUSE_FILTER
:
11975 case OMP_CLAUSE_HINT
:
11976 case OMP_CLAUSE_ASYNC
:
11977 case OMP_CLAUSE_WAIT
:
11978 case OMP_CLAUSE_NUM_GANGS
:
11979 case OMP_CLAUSE_NUM_WORKERS
:
11980 case OMP_CLAUSE_VECTOR_LENGTH
:
11981 case OMP_CLAUSE_WORKER
:
11982 case OMP_CLAUSE_VECTOR
:
11983 if (OMP_CLAUSE_OPERAND (c
, 0)
11984 && !is_gimple_min_invariant (OMP_CLAUSE_OPERAND (c
, 0)))
11986 if (error_operand_p (OMP_CLAUSE_OPERAND (c
, 0)))
11991 /* All these clauses care about value, not a particular decl,
11992 so try to force it into a SSA_NAME or fresh temporary. */
11993 OMP_CLAUSE_OPERAND (c
, 0)
11994 = get_initialized_tmp_var (OMP_CLAUSE_OPERAND (c
, 0),
11995 pre_p
, NULL
, true);
11999 case OMP_CLAUSE_GANG
:
12000 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c
, 0), pre_p
, NULL
,
12001 is_gimple_val
, fb_rvalue
) == GS_ERROR
)
12003 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c
, 1), pre_p
, NULL
,
12004 is_gimple_val
, fb_rvalue
) == GS_ERROR
)
12008 case OMP_CLAUSE_NOWAIT
:
12012 case OMP_CLAUSE_ORDERED
:
12013 case OMP_CLAUSE_UNTIED
:
12014 case OMP_CLAUSE_COLLAPSE
:
12015 case OMP_CLAUSE_TILE
:
12016 case OMP_CLAUSE_AUTO
:
12017 case OMP_CLAUSE_SEQ
:
12018 case OMP_CLAUSE_INDEPENDENT
:
12019 case OMP_CLAUSE_MERGEABLE
:
12020 case OMP_CLAUSE_PROC_BIND
:
12021 case OMP_CLAUSE_SAFELEN
:
12022 case OMP_CLAUSE_SIMDLEN
:
12023 case OMP_CLAUSE_NOGROUP
:
12024 case OMP_CLAUSE_THREADS
:
12025 case OMP_CLAUSE_SIMD
:
12026 case OMP_CLAUSE_BIND
:
12027 case OMP_CLAUSE_IF_PRESENT
:
12028 case OMP_CLAUSE_FINALIZE
:
12031 case OMP_CLAUSE_ORDER
:
12032 ctx
->order_concurrent
= true;
12035 case OMP_CLAUSE_DEFAULTMAP
:
12036 enum gimplify_defaultmap_kind gdmkmin
, gdmkmax
;
12037 switch (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
))
12039 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
:
12040 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL
:
12041 gdmkmin
= GDMK_SCALAR
;
12042 gdmkmax
= GDMK_POINTER
;
12044 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR
:
12045 gdmkmin
= GDMK_SCALAR
;
12046 gdmkmax
= GDMK_SCALAR_TARGET
;
12048 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE
:
12049 gdmkmin
= gdmkmax
= GDMK_AGGREGATE
;
12051 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALLOCATABLE
:
12052 gdmkmin
= gdmkmax
= GDMK_ALLOCATABLE
;
12054 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER
:
12055 gdmkmin
= gdmkmax
= GDMK_POINTER
;
12058 gcc_unreachable ();
12060 for (int gdmk
= gdmkmin
; gdmk
<= gdmkmax
; gdmk
++)
12061 switch (OMP_CLAUSE_DEFAULTMAP_BEHAVIOR (c
))
12063 case OMP_CLAUSE_DEFAULTMAP_ALLOC
:
12064 ctx
->defaultmap
[gdmk
] = GOVD_MAP
| GOVD_MAP_ALLOC_ONLY
;
12066 case OMP_CLAUSE_DEFAULTMAP_TO
:
12067 ctx
->defaultmap
[gdmk
] = GOVD_MAP
| GOVD_MAP_TO_ONLY
;
12069 case OMP_CLAUSE_DEFAULTMAP_FROM
:
12070 ctx
->defaultmap
[gdmk
] = GOVD_MAP
| GOVD_MAP_FROM_ONLY
;
12072 case OMP_CLAUSE_DEFAULTMAP_TOFROM
:
12073 ctx
->defaultmap
[gdmk
] = GOVD_MAP
;
12075 case OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE
:
12076 ctx
->defaultmap
[gdmk
] = GOVD_FIRSTPRIVATE
;
12078 case OMP_CLAUSE_DEFAULTMAP_NONE
:
12079 ctx
->defaultmap
[gdmk
] = 0;
12081 case OMP_CLAUSE_DEFAULTMAP_PRESENT
:
12082 ctx
->defaultmap
[gdmk
] = GOVD_MAP
| GOVD_MAP_FORCE_PRESENT
;
12084 case OMP_CLAUSE_DEFAULTMAP_DEFAULT
:
12088 ctx
->defaultmap
[gdmk
] = GOVD_FIRSTPRIVATE
;
12090 case GDMK_SCALAR_TARGET
:
12091 ctx
->defaultmap
[gdmk
] = (lang_GNU_Fortran ()
12092 ? GOVD_MAP
: GOVD_FIRSTPRIVATE
);
12094 case GDMK_AGGREGATE
:
12095 case GDMK_ALLOCATABLE
:
12096 ctx
->defaultmap
[gdmk
] = GOVD_MAP
;
12099 ctx
->defaultmap
[gdmk
] = GOVD_MAP
;
12100 if (!lang_GNU_Fortran ())
12101 ctx
->defaultmap
[gdmk
] |= GOVD_MAP_0LEN_ARRAY
;
12104 gcc_unreachable ();
12108 gcc_unreachable ();
12112 case OMP_CLAUSE_ALIGNED
:
12113 decl
= OMP_CLAUSE_DECL (c
);
12114 if (error_operand_p (decl
))
12119 if (gimplify_expr (&OMP_CLAUSE_ALIGNED_ALIGNMENT (c
), pre_p
, NULL
,
12120 is_gimple_val
, fb_rvalue
) == GS_ERROR
)
12125 if (!is_global_var (decl
)
12126 && TREE_CODE (TREE_TYPE (decl
)) == POINTER_TYPE
)
12127 omp_add_variable (ctx
, decl
, GOVD_ALIGNED
);
12130 case OMP_CLAUSE_NONTEMPORAL
:
12131 decl
= OMP_CLAUSE_DECL (c
);
12132 if (error_operand_p (decl
))
12137 omp_add_variable (ctx
, decl
, GOVD_NONTEMPORAL
);
12140 case OMP_CLAUSE_ALLOCATE
:
12141 decl
= OMP_CLAUSE_DECL (c
);
12142 if (error_operand_p (decl
))
12147 if (gimplify_expr (&OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
), pre_p
, NULL
,
12148 is_gimple_val
, fb_rvalue
) == GS_ERROR
)
12153 else if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
) == NULL_TREE
12154 || (TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
))
12157 else if (code
== OMP_TASKLOOP
12158 || !DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
)))
12159 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
)
12160 = get_initialized_tmp_var (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
),
12161 pre_p
, NULL
, false);
12164 case OMP_CLAUSE_DEFAULT
:
12165 ctx
->default_kind
= OMP_CLAUSE_DEFAULT_KIND (c
);
12168 case OMP_CLAUSE_INCLUSIVE
:
12169 case OMP_CLAUSE_EXCLUSIVE
:
12170 decl
= OMP_CLAUSE_DECL (c
);
12172 splay_tree_node n
= splay_tree_lookup (outer_ctx
->variables
,
12173 (splay_tree_key
) decl
);
12174 if (n
== NULL
|| (n
->value
& GOVD_REDUCTION
) == 0)
12176 error_at (OMP_CLAUSE_LOCATION (c
),
12177 "%qD specified in %qs clause but not in %<inscan%> "
12178 "%<reduction%> clause on the containing construct",
12179 decl
, omp_clause_code_name
[OMP_CLAUSE_CODE (c
)]);
12184 n
->value
|= GOVD_REDUCTION_INSCAN
;
12185 if (outer_ctx
->region_type
== ORT_SIMD
12186 && outer_ctx
->outer_context
12187 && outer_ctx
->outer_context
->region_type
== ORT_WORKSHARE
)
12189 n
= splay_tree_lookup (outer_ctx
->outer_context
->variables
,
12190 (splay_tree_key
) decl
);
12191 if (n
&& (n
->value
& GOVD_REDUCTION
) != 0)
12192 n
->value
|= GOVD_REDUCTION_INSCAN
;
12198 case OMP_CLAUSE_NOHOST
:
12200 gcc_unreachable ();
12203 if (code
== OACC_DATA
12204 && OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_MAP
12205 && (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_FIRSTPRIVATE_POINTER
12206 || OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
))
12209 *list_p
= OMP_CLAUSE_CHAIN (c
);
12211 list_p
= &OMP_CLAUSE_CHAIN (c
);
12214 ctx
->clauses
= *orig_list_p
;
12215 gimplify_omp_ctxp
= ctx
;
12218 /* Return true if DECL is a candidate for shared to firstprivate
12219 optimization. We only consider non-addressable scalars, not
12220 too big, and not references. */
12223 omp_shared_to_firstprivate_optimizable_decl_p (tree decl
)
12225 if (TREE_ADDRESSABLE (decl
))
12227 tree type
= TREE_TYPE (decl
);
12228 if (!is_gimple_reg_type (type
)
12229 || TREE_CODE (type
) == REFERENCE_TYPE
12230 || TREE_ADDRESSABLE (type
))
12232 /* Don't optimize too large decls, as each thread/task will have
12234 HOST_WIDE_INT len
= int_size_in_bytes (type
);
12235 if (len
== -1 || len
> 4 * POINTER_SIZE
/ BITS_PER_UNIT
)
12237 if (omp_privatize_by_reference (decl
))
12242 /* Helper function of omp_find_stores_op and gimplify_adjust_omp_clauses*.
12243 For omp_shared_to_firstprivate_optimizable_decl_p decl mark it as
12244 GOVD_WRITTEN in outer contexts. */
12247 omp_mark_stores (struct gimplify_omp_ctx
*ctx
, tree decl
)
12249 for (; ctx
; ctx
= ctx
->outer_context
)
12251 splay_tree_node n
= splay_tree_lookup (ctx
->variables
,
12252 (splay_tree_key
) decl
);
12255 else if (n
->value
& GOVD_SHARED
)
12257 n
->value
|= GOVD_WRITTEN
;
12260 else if (n
->value
& GOVD_DATA_SHARE_CLASS
)
12265 /* Helper callback for walk_gimple_seq to discover possible stores
12266 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
12267 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
12271 omp_find_stores_op (tree
*tp
, int *walk_subtrees
, void *data
)
12273 struct walk_stmt_info
*wi
= (struct walk_stmt_info
*) data
;
12275 *walk_subtrees
= 0;
12282 if (handled_component_p (op
))
12283 op
= TREE_OPERAND (op
, 0);
12284 else if ((TREE_CODE (op
) == MEM_REF
|| TREE_CODE (op
) == TARGET_MEM_REF
)
12285 && TREE_CODE (TREE_OPERAND (op
, 0)) == ADDR_EXPR
)
12286 op
= TREE_OPERAND (TREE_OPERAND (op
, 0), 0);
12291 if (!DECL_P (op
) || !omp_shared_to_firstprivate_optimizable_decl_p (op
))
12294 omp_mark_stores (gimplify_omp_ctxp
, op
);
12298 /* Helper callback for walk_gimple_seq to discover possible stores
12299 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
12300 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
12304 omp_find_stores_stmt (gimple_stmt_iterator
*gsi_p
,
12305 bool *handled_ops_p
,
12306 struct walk_stmt_info
*wi
)
12308 gimple
*stmt
= gsi_stmt (*gsi_p
);
12309 switch (gimple_code (stmt
))
12311 /* Don't recurse on OpenMP constructs for which
12312 gimplify_adjust_omp_clauses already handled the bodies,
12313 except handle gimple_omp_for_pre_body. */
12314 case GIMPLE_OMP_FOR
:
12315 *handled_ops_p
= true;
12316 if (gimple_omp_for_pre_body (stmt
))
12317 walk_gimple_seq (gimple_omp_for_pre_body (stmt
),
12318 omp_find_stores_stmt
, omp_find_stores_op
, wi
);
12320 case GIMPLE_OMP_PARALLEL
:
12321 case GIMPLE_OMP_TASK
:
12322 case GIMPLE_OMP_SECTIONS
:
12323 case GIMPLE_OMP_SINGLE
:
12324 case GIMPLE_OMP_SCOPE
:
12325 case GIMPLE_OMP_TARGET
:
12326 case GIMPLE_OMP_TEAMS
:
12327 case GIMPLE_OMP_CRITICAL
:
12328 *handled_ops_p
= true;
12336 struct gimplify_adjust_omp_clauses_data
12342 /* For all variables that were not actually used within the context,
12343 remove PRIVATE, SHARED, and FIRSTPRIVATE clauses. */
12346 gimplify_adjust_omp_clauses_1 (splay_tree_node n
, void *data
)
12348 tree
*list_p
= ((struct gimplify_adjust_omp_clauses_data
*) data
)->list_p
;
12350 = ((struct gimplify_adjust_omp_clauses_data
*) data
)->pre_p
;
12351 tree decl
= (tree
) n
->key
;
12352 unsigned flags
= n
->value
;
12353 enum omp_clause_code code
;
12355 bool private_debug
;
12357 if (gimplify_omp_ctxp
->region_type
== ORT_COMBINED_PARALLEL
12358 && (flags
& GOVD_LASTPRIVATE_CONDITIONAL
) != 0)
12359 flags
= GOVD_SHARED
| GOVD_SEEN
| GOVD_WRITTEN
;
12360 if (flags
& (GOVD_EXPLICIT
| GOVD_LOCAL
))
12362 if ((flags
& GOVD_SEEN
) == 0)
12364 if (flags
& GOVD_DEBUG_PRIVATE
)
12366 gcc_assert ((flags
& GOVD_DATA_SHARE_CLASS
) == GOVD_SHARED
);
12367 private_debug
= true;
12369 else if (flags
& GOVD_MAP
)
12370 private_debug
= false;
12373 = lang_hooks
.decls
.omp_private_debug_clause (decl
,
12374 !!(flags
& GOVD_SHARED
));
12376 code
= OMP_CLAUSE_PRIVATE
;
12377 else if (flags
& GOVD_MAP
)
12379 code
= OMP_CLAUSE_MAP
;
12380 if ((gimplify_omp_ctxp
->region_type
& ORT_ACC
) == 0
12381 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl
))))
12383 error ("%<_Atomic%> %qD in implicit %<map%> clause", decl
);
12387 && DECL_IN_CONSTANT_POOL (decl
)
12388 && !lookup_attribute ("omp declare target",
12389 DECL_ATTRIBUTES (decl
)))
12391 tree id
= get_identifier ("omp declare target");
12392 DECL_ATTRIBUTES (decl
)
12393 = tree_cons (id
, NULL_TREE
, DECL_ATTRIBUTES (decl
));
12394 varpool_node
*node
= varpool_node::get (decl
);
12397 node
->offloadable
= 1;
12398 if (ENABLE_OFFLOADING
)
12399 g
->have_offload
= true;
12403 else if (flags
& GOVD_SHARED
)
12405 if (is_global_var (decl
))
12407 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
->outer_context
;
12408 while (ctx
!= NULL
)
12411 = splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
12412 if (on
&& (on
->value
& (GOVD_FIRSTPRIVATE
| GOVD_LASTPRIVATE
12413 | GOVD_PRIVATE
| GOVD_REDUCTION
12414 | GOVD_LINEAR
| GOVD_MAP
)) != 0)
12416 ctx
= ctx
->outer_context
;
12421 code
= OMP_CLAUSE_SHARED
;
12422 /* Don't optimize shared into firstprivate for read-only vars
12423 on tasks with depend clause, we shouldn't try to copy them
12424 until the dependencies are satisfied. */
12425 if (gimplify_omp_ctxp
->has_depend
)
12426 flags
|= GOVD_WRITTEN
;
12428 else if (flags
& GOVD_PRIVATE
)
12429 code
= OMP_CLAUSE_PRIVATE
;
12430 else if (flags
& GOVD_FIRSTPRIVATE
)
12432 code
= OMP_CLAUSE_FIRSTPRIVATE
;
12433 if ((gimplify_omp_ctxp
->region_type
& ORT_TARGET
)
12434 && (gimplify_omp_ctxp
->region_type
& ORT_ACC
) == 0
12435 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl
))))
12437 error ("%<_Atomic%> %qD in implicit %<firstprivate%> clause on "
12438 "%<target%> construct", decl
);
12442 else if (flags
& GOVD_LASTPRIVATE
)
12443 code
= OMP_CLAUSE_LASTPRIVATE
;
12444 else if (flags
& (GOVD_ALIGNED
| GOVD_NONTEMPORAL
))
12446 else if (flags
& GOVD_CONDTEMP
)
12448 code
= OMP_CLAUSE__CONDTEMP_
;
12449 gimple_add_tmp_var (decl
);
12452 gcc_unreachable ();
12454 if (((flags
& GOVD_LASTPRIVATE
)
12455 || (code
== OMP_CLAUSE_SHARED
&& (flags
& GOVD_WRITTEN
)))
12456 && omp_shared_to_firstprivate_optimizable_decl_p (decl
))
12457 omp_mark_stores (gimplify_omp_ctxp
->outer_context
, decl
);
12459 tree chain
= *list_p
;
12460 clause
= build_omp_clause (input_location
, code
);
12461 OMP_CLAUSE_DECL (clause
) = decl
;
12462 OMP_CLAUSE_CHAIN (clause
) = chain
;
12464 OMP_CLAUSE_PRIVATE_DEBUG (clause
) = 1;
12465 else if (code
== OMP_CLAUSE_PRIVATE
&& (flags
& GOVD_PRIVATE_OUTER_REF
))
12466 OMP_CLAUSE_PRIVATE_OUTER_REF (clause
) = 1;
12467 else if (code
== OMP_CLAUSE_SHARED
12468 && (flags
& GOVD_WRITTEN
) == 0
12469 && omp_shared_to_firstprivate_optimizable_decl_p (decl
))
12470 OMP_CLAUSE_SHARED_READONLY (clause
) = 1;
12471 else if (code
== OMP_CLAUSE_FIRSTPRIVATE
&& (flags
& GOVD_EXPLICIT
) == 0)
12472 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (clause
) = 1;
12473 else if (code
== OMP_CLAUSE_MAP
&& (flags
& GOVD_MAP_0LEN_ARRAY
) != 0)
12475 tree nc
= build_omp_clause (input_location
, OMP_CLAUSE_MAP
);
12476 OMP_CLAUSE_DECL (nc
) = decl
;
12477 if (TREE_CODE (TREE_TYPE (decl
)) == REFERENCE_TYPE
12478 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl
))) == POINTER_TYPE
)
12479 OMP_CLAUSE_DECL (clause
)
12480 = build_simple_mem_ref_loc (input_location
, decl
);
12481 OMP_CLAUSE_DECL (clause
)
12482 = build2 (MEM_REF
, char_type_node
, OMP_CLAUSE_DECL (clause
),
12483 build_int_cst (build_pointer_type (char_type_node
), 0));
12484 OMP_CLAUSE_SIZE (clause
) = size_zero_node
;
12485 OMP_CLAUSE_SIZE (nc
) = size_zero_node
;
12486 OMP_CLAUSE_SET_MAP_KIND (clause
, GOMP_MAP_ALLOC
);
12487 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (clause
) = 1;
12488 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_FIRSTPRIVATE_POINTER
);
12489 OMP_CLAUSE_CHAIN (nc
) = chain
;
12490 OMP_CLAUSE_CHAIN (clause
) = nc
;
12491 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
12492 gimplify_omp_ctxp
= ctx
->outer_context
;
12493 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (clause
), 0),
12494 pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
12495 gimplify_omp_ctxp
= ctx
;
12497 else if (code
== OMP_CLAUSE_MAP
)
12500 /* Not all combinations of these GOVD_MAP flags are actually valid. */
12501 switch (flags
& (GOVD_MAP_TO_ONLY
12503 | GOVD_MAP_FORCE_PRESENT
12504 | GOVD_MAP_ALLOC_ONLY
12505 | GOVD_MAP_FROM_ONLY
))
12508 kind
= GOMP_MAP_TOFROM
;
12510 case GOVD_MAP_FORCE
:
12511 kind
= GOMP_MAP_TOFROM
| GOMP_MAP_FLAG_FORCE
;
12513 case GOVD_MAP_TO_ONLY
:
12514 kind
= GOMP_MAP_TO
;
12516 case GOVD_MAP_FROM_ONLY
:
12517 kind
= GOMP_MAP_FROM
;
12519 case GOVD_MAP_ALLOC_ONLY
:
12520 kind
= GOMP_MAP_ALLOC
;
12522 case GOVD_MAP_TO_ONLY
| GOVD_MAP_FORCE
:
12523 kind
= GOMP_MAP_TO
| GOMP_MAP_FLAG_FORCE
;
12525 case GOVD_MAP_FORCE_PRESENT
:
12526 kind
= GOMP_MAP_FORCE_PRESENT
;
12528 case GOVD_MAP_FORCE_PRESENT
| GOVD_MAP_ALLOC_ONLY
:
12529 kind
= GOMP_MAP_FORCE_PRESENT
;
12532 gcc_unreachable ();
12534 OMP_CLAUSE_SET_MAP_KIND (clause
, kind
);
12535 /* Setting of the implicit flag for the runtime is currently disabled for
12537 if ((gimplify_omp_ctxp
->region_type
& ORT_ACC
) == 0)
12538 OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (clause
) = 1;
12539 if (DECL_SIZE (decl
)
12540 && TREE_CODE (DECL_SIZE (decl
)) != INTEGER_CST
)
12542 tree decl2
= DECL_VALUE_EXPR (decl
);
12543 gcc_assert (INDIRECT_REF_P (decl2
));
12544 decl2
= TREE_OPERAND (decl2
, 0);
12545 gcc_assert (DECL_P (decl2
));
12546 tree mem
= build_simple_mem_ref (decl2
);
12547 OMP_CLAUSE_DECL (clause
) = mem
;
12548 OMP_CLAUSE_SIZE (clause
) = TYPE_SIZE_UNIT (TREE_TYPE (decl
));
12549 if (gimplify_omp_ctxp
->outer_context
)
12551 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
->outer_context
;
12552 omp_notice_variable (ctx
, decl2
, true);
12553 omp_notice_variable (ctx
, OMP_CLAUSE_SIZE (clause
), true);
12555 tree nc
= build_omp_clause (OMP_CLAUSE_LOCATION (clause
),
12557 OMP_CLAUSE_DECL (nc
) = decl
;
12558 OMP_CLAUSE_SIZE (nc
) = size_zero_node
;
12559 if (gimplify_omp_ctxp
->target_firstprivatize_array_bases
)
12560 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_FIRSTPRIVATE_POINTER
);
12562 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_POINTER
);
12563 OMP_CLAUSE_CHAIN (nc
) = OMP_CLAUSE_CHAIN (clause
);
12564 OMP_CLAUSE_CHAIN (clause
) = nc
;
12566 else if (gimplify_omp_ctxp
->target_firstprivatize_array_bases
12567 && omp_privatize_by_reference (decl
))
12569 OMP_CLAUSE_DECL (clause
) = build_simple_mem_ref (decl
);
12570 OMP_CLAUSE_SIZE (clause
)
12571 = unshare_expr (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl
))));
12572 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
12573 gimplify_omp_ctxp
= ctx
->outer_context
;
12574 gimplify_expr (&OMP_CLAUSE_SIZE (clause
),
12575 pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
12576 gimplify_omp_ctxp
= ctx
;
12577 tree nc
= build_omp_clause (OMP_CLAUSE_LOCATION (clause
),
12579 OMP_CLAUSE_DECL (nc
) = decl
;
12580 OMP_CLAUSE_SIZE (nc
) = size_zero_node
;
12581 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_FIRSTPRIVATE_REFERENCE
);
12582 OMP_CLAUSE_CHAIN (nc
) = OMP_CLAUSE_CHAIN (clause
);
12583 OMP_CLAUSE_CHAIN (clause
) = nc
;
12586 OMP_CLAUSE_SIZE (clause
) = DECL_SIZE_UNIT (decl
);
12588 if (code
== OMP_CLAUSE_FIRSTPRIVATE
&& (flags
& GOVD_LASTPRIVATE
) != 0)
12590 tree nc
= build_omp_clause (input_location
, OMP_CLAUSE_LASTPRIVATE
);
12591 OMP_CLAUSE_DECL (nc
) = decl
;
12592 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (nc
) = 1;
12593 OMP_CLAUSE_CHAIN (nc
) = chain
;
12594 OMP_CLAUSE_CHAIN (clause
) = nc
;
12595 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
12596 gimplify_omp_ctxp
= ctx
->outer_context
;
12597 lang_hooks
.decls
.omp_finish_clause (nc
, pre_p
,
12598 (ctx
->region_type
& ORT_ACC
) != 0);
12599 gimplify_omp_ctxp
= ctx
;
12602 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
12603 gimplify_omp_ctxp
= ctx
->outer_context
;
12604 /* Don't call omp_finish_clause on implicitly added OMP_CLAUSE_PRIVATE
12605 in simd. Those are only added for the local vars inside of simd body
12606 and they don't need to be e.g. default constructible. */
12607 if (code
!= OMP_CLAUSE_PRIVATE
|| ctx
->region_type
!= ORT_SIMD
)
12608 lang_hooks
.decls
.omp_finish_clause (clause
, pre_p
,
12609 (ctx
->region_type
& ORT_ACC
) != 0);
12610 if (gimplify_omp_ctxp
)
12611 for (; clause
!= chain
; clause
= OMP_CLAUSE_CHAIN (clause
))
12612 if (OMP_CLAUSE_CODE (clause
) == OMP_CLAUSE_MAP
12613 && DECL_P (OMP_CLAUSE_SIZE (clause
)))
12614 omp_notice_variable (gimplify_omp_ctxp
, OMP_CLAUSE_SIZE (clause
),
12616 gimplify_omp_ctxp
= ctx
;
12621 gimplify_adjust_omp_clauses (gimple_seq
*pre_p
, gimple_seq body
, tree
*list_p
,
12622 enum tree_code code
)
12624 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
12625 tree
*orig_list_p
= list_p
;
12627 bool has_inscan_reductions
= false;
12631 struct gimplify_omp_ctx
*octx
;
12632 for (octx
= ctx
; octx
; octx
= octx
->outer_context
)
12633 if ((octx
->region_type
& (ORT_PARALLEL
| ORT_TASK
| ORT_TEAMS
)) != 0)
12637 struct walk_stmt_info wi
;
12638 memset (&wi
, 0, sizeof (wi
));
12639 walk_gimple_seq (body
, omp_find_stores_stmt
,
12640 omp_find_stores_op
, &wi
);
12644 if (ctx
->add_safelen1
)
12646 /* If there are VLAs in the body of simd loop, prevent
12648 gcc_assert (ctx
->region_type
== ORT_SIMD
);
12649 c
= build_omp_clause (UNKNOWN_LOCATION
, OMP_CLAUSE_SAFELEN
);
12650 OMP_CLAUSE_SAFELEN_EXPR (c
) = integer_one_node
;
12651 OMP_CLAUSE_CHAIN (c
) = *list_p
;
12653 list_p
= &OMP_CLAUSE_CHAIN (c
);
12656 if (ctx
->region_type
== ORT_WORKSHARE
12657 && ctx
->outer_context
12658 && ctx
->outer_context
->region_type
== ORT_COMBINED_PARALLEL
)
12660 for (c
= ctx
->outer_context
->clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
12661 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
12662 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
))
12664 decl
= OMP_CLAUSE_DECL (c
);
12666 = splay_tree_lookup (ctx
->outer_context
->variables
,
12667 (splay_tree_key
) decl
);
12668 gcc_checking_assert (!splay_tree_lookup (ctx
->variables
,
12669 (splay_tree_key
) decl
));
12670 omp_add_variable (ctx
, decl
, n
->value
);
12671 tree c2
= copy_node (c
);
12672 OMP_CLAUSE_CHAIN (c2
) = *list_p
;
12674 if ((n
->value
& GOVD_FIRSTPRIVATE
) == 0)
12676 c2
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
12677 OMP_CLAUSE_FIRSTPRIVATE
);
12678 OMP_CLAUSE_DECL (c2
) = decl
;
12679 OMP_CLAUSE_CHAIN (c2
) = *list_p
;
12684 tree attach_list
= NULL_TREE
;
12685 tree
*attach_tail
= &attach_list
;
12687 while ((c
= *list_p
) != NULL
)
12690 bool remove
= false;
12691 bool move_attach
= false;
12693 switch (OMP_CLAUSE_CODE (c
))
12695 case OMP_CLAUSE_FIRSTPRIVATE
:
12696 if ((ctx
->region_type
& ORT_TARGET
)
12697 && (ctx
->region_type
& ORT_ACC
) == 0
12698 && TYPE_ATOMIC (strip_array_types
12699 (TREE_TYPE (OMP_CLAUSE_DECL (c
)))))
12701 error_at (OMP_CLAUSE_LOCATION (c
),
12702 "%<_Atomic%> %qD in %<firstprivate%> clause on "
12703 "%<target%> construct", OMP_CLAUSE_DECL (c
));
12707 if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c
))
12709 decl
= OMP_CLAUSE_DECL (c
);
12710 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
12711 if ((n
->value
& GOVD_MAP
) != 0)
12716 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT_TARGET (c
) = 0;
12717 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c
) = 0;
12720 case OMP_CLAUSE_PRIVATE
:
12721 case OMP_CLAUSE_SHARED
:
12722 case OMP_CLAUSE_LINEAR
:
12723 decl
= OMP_CLAUSE_DECL (c
);
12724 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
12725 remove
= !(n
->value
& GOVD_SEEN
);
12726 if ((n
->value
& GOVD_LASTPRIVATE_CONDITIONAL
) != 0
12727 && code
== OMP_PARALLEL
12728 && OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_FIRSTPRIVATE
)
12732 bool shared
= OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_SHARED
;
12733 if ((n
->value
& GOVD_DEBUG_PRIVATE
)
12734 || lang_hooks
.decls
.omp_private_debug_clause (decl
, shared
))
12736 gcc_assert ((n
->value
& GOVD_DEBUG_PRIVATE
) == 0
12737 || ((n
->value
& GOVD_DATA_SHARE_CLASS
)
12739 OMP_CLAUSE_SET_CODE (c
, OMP_CLAUSE_PRIVATE
);
12740 OMP_CLAUSE_PRIVATE_DEBUG (c
) = 1;
12742 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_SHARED
12745 n
->value
|= GOVD_WRITTEN
;
12746 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_SHARED
12747 && (n
->value
& GOVD_WRITTEN
) == 0
12749 && omp_shared_to_firstprivate_optimizable_decl_p (decl
))
12750 OMP_CLAUSE_SHARED_READONLY (c
) = 1;
12751 else if (DECL_P (decl
)
12752 && ((OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_SHARED
12753 && (n
->value
& GOVD_WRITTEN
) != 0)
12754 || (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINEAR
12755 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c
)))
12756 && omp_shared_to_firstprivate_optimizable_decl_p (decl
))
12757 omp_mark_stores (gimplify_omp_ctxp
->outer_context
, decl
);
12760 n
->value
&= ~GOVD_EXPLICIT
;
12763 case OMP_CLAUSE_LASTPRIVATE
:
12764 /* Make sure OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE is set to
12765 accurately reflect the presence of a FIRSTPRIVATE clause. */
12766 decl
= OMP_CLAUSE_DECL (c
);
12767 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
12768 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
)
12769 = (n
->value
& GOVD_FIRSTPRIVATE
) != 0;
12770 if (code
== OMP_DISTRIBUTE
12771 && OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
))
12774 error_at (OMP_CLAUSE_LOCATION (c
),
12775 "same variable used in %<firstprivate%> and "
12776 "%<lastprivate%> clauses on %<distribute%> "
12780 && OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
12782 && omp_shared_to_firstprivate_optimizable_decl_p (decl
))
12783 omp_mark_stores (gimplify_omp_ctxp
->outer_context
, decl
);
12784 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
) && code
== OMP_PARALLEL
)
12788 case OMP_CLAUSE_ALIGNED
:
12789 decl
= OMP_CLAUSE_DECL (c
);
12790 if (!is_global_var (decl
))
12792 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
12793 remove
= n
== NULL
|| !(n
->value
& GOVD_SEEN
);
12794 if (!remove
&& TREE_CODE (TREE_TYPE (decl
)) == POINTER_TYPE
)
12796 struct gimplify_omp_ctx
*octx
;
12798 && (n
->value
& (GOVD_DATA_SHARE_CLASS
12799 & ~GOVD_FIRSTPRIVATE
)))
12802 for (octx
= ctx
->outer_context
; octx
;
12803 octx
= octx
->outer_context
)
12805 n
= splay_tree_lookup (octx
->variables
,
12806 (splay_tree_key
) decl
);
12809 if (n
->value
& GOVD_LOCAL
)
12811 /* We have to avoid assigning a shared variable
12812 to itself when trying to add
12813 __builtin_assume_aligned. */
12814 if (n
->value
& GOVD_SHARED
)
12822 else if (TREE_CODE (TREE_TYPE (decl
)) == ARRAY_TYPE
)
12824 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
12825 if (n
!= NULL
&& (n
->value
& GOVD_DATA_SHARE_CLASS
) != 0)
12830 case OMP_CLAUSE_HAS_DEVICE_ADDR
:
12831 decl
= OMP_CLAUSE_DECL (c
);
12832 while (INDIRECT_REF_P (decl
)
12833 || TREE_CODE (decl
) == ARRAY_REF
)
12834 decl
= TREE_OPERAND (decl
, 0);
12835 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
12836 remove
= n
== NULL
|| !(n
->value
& GOVD_SEEN
);
12839 case OMP_CLAUSE_IS_DEVICE_PTR
:
12840 case OMP_CLAUSE_NONTEMPORAL
:
12841 decl
= OMP_CLAUSE_DECL (c
);
12842 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
12843 remove
= n
== NULL
|| !(n
->value
& GOVD_SEEN
);
12846 case OMP_CLAUSE_MAP
:
12847 switch (OMP_CLAUSE_MAP_KIND (c
))
12849 case GOMP_MAP_PRESENT_ALLOC
:
12850 case GOMP_MAP_PRESENT_TO
:
12851 case GOMP_MAP_PRESENT_FROM
:
12852 case GOMP_MAP_PRESENT_TOFROM
:
12853 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_FORCE_PRESENT
);
12858 if (code
== OMP_TARGET_EXIT_DATA
12859 && OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ALWAYS_POINTER
)
12864 /* If we have a target region, we can push all the attaches to the
12865 end of the list (we may have standalone "attach" operations
12866 synthesized for GOMP_MAP_STRUCT nodes that must be processed after
12867 the attachment point AND the pointed-to block have been mapped).
12868 If we have something else, e.g. "enter data", we need to keep
12869 "attach" nodes together with the previous node they attach to so
12870 that separate "exit data" operations work properly (see
12871 libgomp/target.c). */
12872 if ((ctx
->region_type
& ORT_TARGET
) != 0
12873 && (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ATTACH
12874 || (OMP_CLAUSE_MAP_KIND (c
)
12875 == GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION
)))
12876 move_attach
= true;
12877 decl
= OMP_CLAUSE_DECL (c
);
12878 /* Data clauses associated with reductions must be
12879 compatible with present_or_copy. Warn and adjust the clause
12880 if that is not the case. */
12881 if (ctx
->region_type
== ORT_ACC_PARALLEL
12882 || ctx
->region_type
== ORT_ACC_SERIAL
)
12884 tree t
= DECL_P (decl
) ? decl
: TREE_OPERAND (decl
, 0);
12888 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) t
);
12890 if (n
&& (n
->value
& GOVD_REDUCTION
))
12892 enum gomp_map_kind kind
= OMP_CLAUSE_MAP_KIND (c
);
12894 OMP_CLAUSE_MAP_IN_REDUCTION (c
) = 1;
12895 if ((kind
& GOMP_MAP_TOFROM
) != GOMP_MAP_TOFROM
12896 && kind
!= GOMP_MAP_FORCE_PRESENT
12897 && kind
!= GOMP_MAP_POINTER
)
12899 warning_at (OMP_CLAUSE_LOCATION (c
), 0,
12900 "incompatible data clause with reduction "
12901 "on %qE; promoting to %<present_or_copy%>",
12903 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_TOFROM
);
12907 if (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_STRUCT
12908 && (code
== OMP_TARGET_EXIT_DATA
|| code
== OACC_EXIT_DATA
))
12913 if (!DECL_P (decl
))
12915 if ((ctx
->region_type
& ORT_TARGET
) != 0
12916 && OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_FIRSTPRIVATE_POINTER
)
12918 if (INDIRECT_REF_P (decl
)
12919 && TREE_CODE (TREE_OPERAND (decl
, 0)) == COMPONENT_REF
12920 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl
, 0)))
12921 == REFERENCE_TYPE
))
12922 decl
= TREE_OPERAND (decl
, 0);
12923 if (TREE_CODE (decl
) == COMPONENT_REF
)
12925 while (TREE_CODE (decl
) == COMPONENT_REF
)
12926 decl
= TREE_OPERAND (decl
, 0);
12929 n
= splay_tree_lookup (ctx
->variables
,
12930 (splay_tree_key
) decl
);
12931 if (!(n
->value
& GOVD_SEEN
))
12938 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
12939 if ((ctx
->region_type
& ORT_TARGET
) != 0
12940 && !(n
->value
& GOVD_SEEN
)
12941 && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c
)) == 0
12942 && (!is_global_var (decl
)
12943 || !lookup_attribute ("omp declare target link",
12944 DECL_ATTRIBUTES (decl
))))
12947 /* For struct element mapping, if struct is never referenced
12948 in target block and none of the mapping has always modifier,
12949 remove all the struct element mappings, which immediately
12950 follow the GOMP_MAP_STRUCT map clause. */
12951 if (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_STRUCT
)
12953 HOST_WIDE_INT cnt
= tree_to_shwi (OMP_CLAUSE_SIZE (c
));
12955 OMP_CLAUSE_CHAIN (c
)
12956 = OMP_CLAUSE_CHAIN (OMP_CLAUSE_CHAIN (c
));
12959 else if (DECL_SIZE (decl
)
12960 && TREE_CODE (DECL_SIZE (decl
)) != INTEGER_CST
12961 && OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_POINTER
12962 && OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_FIRSTPRIVATE_POINTER
12963 && (OMP_CLAUSE_MAP_KIND (c
)
12964 != GOMP_MAP_FIRSTPRIVATE_REFERENCE
))
12966 /* For GOMP_MAP_FORCE_DEVICEPTR, we'll never enter here, because
12967 for these, TREE_CODE (DECL_SIZE (decl)) will always be
12969 gcc_assert (OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_FORCE_DEVICEPTR
);
12971 tree decl2
= DECL_VALUE_EXPR (decl
);
12972 gcc_assert (INDIRECT_REF_P (decl2
));
12973 decl2
= TREE_OPERAND (decl2
, 0);
12974 gcc_assert (DECL_P (decl2
));
12975 tree mem
= build_simple_mem_ref (decl2
);
12976 OMP_CLAUSE_DECL (c
) = mem
;
12977 OMP_CLAUSE_SIZE (c
) = TYPE_SIZE_UNIT (TREE_TYPE (decl
));
12978 if (ctx
->outer_context
)
12980 omp_notice_variable (ctx
->outer_context
, decl2
, true);
12981 omp_notice_variable (ctx
->outer_context
,
12982 OMP_CLAUSE_SIZE (c
), true);
12984 if (((ctx
->region_type
& ORT_TARGET
) != 0
12985 || !ctx
->target_firstprivatize_array_bases
)
12986 && ((n
->value
& GOVD_SEEN
) == 0
12987 || (n
->value
& (GOVD_PRIVATE
| GOVD_FIRSTPRIVATE
)) == 0))
12989 tree nc
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
12991 OMP_CLAUSE_DECL (nc
) = decl
;
12992 OMP_CLAUSE_SIZE (nc
) = size_zero_node
;
12993 if (ctx
->target_firstprivatize_array_bases
)
12994 OMP_CLAUSE_SET_MAP_KIND (nc
,
12995 GOMP_MAP_FIRSTPRIVATE_POINTER
);
12997 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_POINTER
);
12998 OMP_CLAUSE_CHAIN (nc
) = OMP_CLAUSE_CHAIN (c
);
12999 OMP_CLAUSE_CHAIN (c
) = nc
;
13005 if (OMP_CLAUSE_SIZE (c
) == NULL_TREE
)
13006 OMP_CLAUSE_SIZE (c
) = DECL_SIZE_UNIT (decl
);
13007 gcc_assert ((n
->value
& GOVD_SEEN
) == 0
13008 || ((n
->value
& (GOVD_PRIVATE
| GOVD_FIRSTPRIVATE
))
13013 case OMP_CLAUSE_TO
:
13014 case OMP_CLAUSE_FROM
:
13015 case OMP_CLAUSE__CACHE_
:
13016 decl
= OMP_CLAUSE_DECL (c
);
13017 if (!DECL_P (decl
))
13019 if (DECL_SIZE (decl
)
13020 && TREE_CODE (DECL_SIZE (decl
)) != INTEGER_CST
)
13022 tree decl2
= DECL_VALUE_EXPR (decl
);
13023 gcc_assert (INDIRECT_REF_P (decl2
));
13024 decl2
= TREE_OPERAND (decl2
, 0);
13025 gcc_assert (DECL_P (decl2
));
13026 tree mem
= build_simple_mem_ref (decl2
);
13027 OMP_CLAUSE_DECL (c
) = mem
;
13028 OMP_CLAUSE_SIZE (c
) = TYPE_SIZE_UNIT (TREE_TYPE (decl
));
13029 if (ctx
->outer_context
)
13031 omp_notice_variable (ctx
->outer_context
, decl2
, true);
13032 omp_notice_variable (ctx
->outer_context
,
13033 OMP_CLAUSE_SIZE (c
), true);
13036 else if (OMP_CLAUSE_SIZE (c
) == NULL_TREE
)
13037 OMP_CLAUSE_SIZE (c
) = DECL_SIZE_UNIT (decl
);
13040 case OMP_CLAUSE_REDUCTION
:
13041 if (OMP_CLAUSE_REDUCTION_INSCAN (c
))
13043 decl
= OMP_CLAUSE_DECL (c
);
13044 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
13045 if ((n
->value
& GOVD_REDUCTION_INSCAN
) == 0)
13048 error_at (OMP_CLAUSE_LOCATION (c
),
13049 "%qD specified in %<inscan%> %<reduction%> clause "
13050 "but not in %<scan%> directive clause", decl
);
13053 has_inscan_reductions
= true;
13056 case OMP_CLAUSE_IN_REDUCTION
:
13057 case OMP_CLAUSE_TASK_REDUCTION
:
13058 decl
= OMP_CLAUSE_DECL (c
);
13059 /* OpenACC reductions need a present_or_copy data clause.
13060 Add one if necessary. Emit error when the reduction is private. */
13061 if (ctx
->region_type
== ORT_ACC_PARALLEL
13062 || ctx
->region_type
== ORT_ACC_SERIAL
)
13064 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
13065 if (n
->value
& (GOVD_PRIVATE
| GOVD_FIRSTPRIVATE
))
13068 error_at (OMP_CLAUSE_LOCATION (c
), "invalid private "
13069 "reduction on %qE", DECL_NAME (decl
));
13071 else if ((n
->value
& GOVD_MAP
) == 0)
13073 tree next
= OMP_CLAUSE_CHAIN (c
);
13074 tree nc
= build_omp_clause (UNKNOWN_LOCATION
, OMP_CLAUSE_MAP
);
13075 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_TOFROM
);
13076 OMP_CLAUSE_DECL (nc
) = decl
;
13077 OMP_CLAUSE_CHAIN (c
) = nc
;
13078 lang_hooks
.decls
.omp_finish_clause (nc
, pre_p
,
13083 OMP_CLAUSE_MAP_IN_REDUCTION (nc
) = 1;
13084 if (OMP_CLAUSE_CHAIN (nc
) == NULL
)
13086 nc
= OMP_CLAUSE_CHAIN (nc
);
13088 OMP_CLAUSE_CHAIN (nc
) = next
;
13089 n
->value
|= GOVD_MAP
;
13093 && omp_shared_to_firstprivate_optimizable_decl_p (decl
))
13094 omp_mark_stores (gimplify_omp_ctxp
->outer_context
, decl
);
13097 case OMP_CLAUSE_ALLOCATE
:
13098 decl
= OMP_CLAUSE_DECL (c
);
13099 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
13100 if (n
!= NULL
&& !(n
->value
& GOVD_SEEN
))
13102 if ((n
->value
& (GOVD_PRIVATE
| GOVD_FIRSTPRIVATE
| GOVD_LINEAR
))
13104 && (n
->value
& (GOVD_REDUCTION
| GOVD_LASTPRIVATE
)) == 0)
13108 && OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
)
13109 && TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
)) != INTEGER_CST
13110 && ((ctx
->region_type
& (ORT_PARALLEL
| ORT_TARGET
)) != 0
13111 || (ctx
->region_type
& ORT_TASKLOOP
) == ORT_TASK
13112 || (ctx
->region_type
& ORT_HOST_TEAMS
) == ORT_HOST_TEAMS
))
13114 tree allocator
= OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
);
13115 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) allocator
);
13118 enum omp_clause_default_kind default_kind
13119 = ctx
->default_kind
;
13120 ctx
->default_kind
= OMP_CLAUSE_DEFAULT_FIRSTPRIVATE
;
13121 omp_notice_variable (ctx
, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
),
13123 ctx
->default_kind
= default_kind
;
13126 omp_notice_variable (ctx
, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
),
13131 case OMP_CLAUSE_COPYIN
:
13132 case OMP_CLAUSE_COPYPRIVATE
:
13133 case OMP_CLAUSE_IF
:
13134 case OMP_CLAUSE_NUM_THREADS
:
13135 case OMP_CLAUSE_NUM_TEAMS
:
13136 case OMP_CLAUSE_THREAD_LIMIT
:
13137 case OMP_CLAUSE_DIST_SCHEDULE
:
13138 case OMP_CLAUSE_DEVICE
:
13139 case OMP_CLAUSE_SCHEDULE
:
13140 case OMP_CLAUSE_NOWAIT
:
13141 case OMP_CLAUSE_ORDERED
:
13142 case OMP_CLAUSE_DEFAULT
:
13143 case OMP_CLAUSE_UNTIED
:
13144 case OMP_CLAUSE_COLLAPSE
:
13145 case OMP_CLAUSE_FINAL
:
13146 case OMP_CLAUSE_MERGEABLE
:
13147 case OMP_CLAUSE_PROC_BIND
:
13148 case OMP_CLAUSE_SAFELEN
:
13149 case OMP_CLAUSE_SIMDLEN
:
13150 case OMP_CLAUSE_DEPEND
:
13151 case OMP_CLAUSE_DOACROSS
:
13152 case OMP_CLAUSE_PRIORITY
:
13153 case OMP_CLAUSE_GRAINSIZE
:
13154 case OMP_CLAUSE_NUM_TASKS
:
13155 case OMP_CLAUSE_NOGROUP
:
13156 case OMP_CLAUSE_THREADS
:
13157 case OMP_CLAUSE_SIMD
:
13158 case OMP_CLAUSE_FILTER
:
13159 case OMP_CLAUSE_HINT
:
13160 case OMP_CLAUSE_DEFAULTMAP
:
13161 case OMP_CLAUSE_ORDER
:
13162 case OMP_CLAUSE_BIND
:
13163 case OMP_CLAUSE_DETACH
:
13164 case OMP_CLAUSE_USE_DEVICE_PTR
:
13165 case OMP_CLAUSE_USE_DEVICE_ADDR
:
13166 case OMP_CLAUSE_ASYNC
:
13167 case OMP_CLAUSE_WAIT
:
13168 case OMP_CLAUSE_INDEPENDENT
:
13169 case OMP_CLAUSE_NUM_GANGS
:
13170 case OMP_CLAUSE_NUM_WORKERS
:
13171 case OMP_CLAUSE_VECTOR_LENGTH
:
13172 case OMP_CLAUSE_GANG
:
13173 case OMP_CLAUSE_WORKER
:
13174 case OMP_CLAUSE_VECTOR
:
13175 case OMP_CLAUSE_AUTO
:
13176 case OMP_CLAUSE_SEQ
:
13177 case OMP_CLAUSE_TILE
:
13178 case OMP_CLAUSE_IF_PRESENT
:
13179 case OMP_CLAUSE_FINALIZE
:
13180 case OMP_CLAUSE_INCLUSIVE
:
13181 case OMP_CLAUSE_EXCLUSIVE
:
13184 case OMP_CLAUSE_NOHOST
:
13186 gcc_unreachable ();
13190 *list_p
= OMP_CLAUSE_CHAIN (c
);
13191 else if (move_attach
)
13193 /* Remove attach node from here, separate out into its own list. */
13195 *list_p
= OMP_CLAUSE_CHAIN (c
);
13196 OMP_CLAUSE_CHAIN (c
) = NULL_TREE
;
13197 attach_tail
= &OMP_CLAUSE_CHAIN (c
);
13200 list_p
= &OMP_CLAUSE_CHAIN (c
);
13203 /* Splice attach nodes at the end of the list. */
13206 *list_p
= attach_list
;
13207 list_p
= attach_tail
;
13210 /* Add in any implicit data sharing. */
13211 struct gimplify_adjust_omp_clauses_data data
;
13212 if ((gimplify_omp_ctxp
->region_type
& ORT_ACC
) == 0)
13214 /* OpenMP. Implicit clauses are added at the start of the clause list,
13215 but after any non-map clauses. */
13216 tree
*implicit_add_list_p
= orig_list_p
;
13217 while (*implicit_add_list_p
13218 && OMP_CLAUSE_CODE (*implicit_add_list_p
) != OMP_CLAUSE_MAP
)
13219 implicit_add_list_p
= &OMP_CLAUSE_CHAIN (*implicit_add_list_p
);
13220 data
.list_p
= implicit_add_list_p
;
13224 data
.list_p
= list_p
;
13225 data
.pre_p
= pre_p
;
13226 splay_tree_foreach (ctx
->variables
, gimplify_adjust_omp_clauses_1
, &data
);
13228 if (has_inscan_reductions
)
13229 for (c
= *orig_list_p
; c
; c
= OMP_CLAUSE_CHAIN (c
))
13230 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINEAR
13231 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c
))
13233 error_at (OMP_CLAUSE_LOCATION (c
),
13234 "%<inscan%> %<reduction%> clause used together with "
13235 "%<linear%> clause for a variable other than loop "
13240 gimplify_omp_ctxp
= ctx
->outer_context
;
13241 delete_omp_context (ctx
);
13244 /* Return 0 if CONSTRUCTS selectors don't match the OpenMP context,
13245 -1 if unknown yet (simd is involved, won't be known until vectorization)
13246 and 1 if they do. If SCORES is non-NULL, it should point to an array
13247 of at least 2*NCONSTRUCTS+2 ints, and will be filled with the positions
13248 of the CONSTRUCTS (position -1 if it will never match) followed by
13249 number of constructs in the OpenMP context construct trait. If the
13250 score depends on whether it will be in a declare simd clone or not,
13251 the function returns 2 and there will be two sets of the scores, the first
13252 one for the case that it is not in a declare simd clone, the other
13253 that it is in a declare simd clone. */
13256 omp_construct_selector_matches (enum tree_code
*constructs
, int nconstructs
,
13259 int matched
= 0, cnt
= 0;
13260 bool simd_seen
= false;
13261 bool target_seen
= false;
13262 int declare_simd_cnt
= -1;
13263 auto_vec
<enum tree_code
, 16> codes
;
13264 for (struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
; ctx
;)
13266 if (((ctx
->region_type
& ORT_PARALLEL
) && ctx
->code
== OMP_PARALLEL
)
13267 || ((ctx
->region_type
& (ORT_TARGET
| ORT_IMPLICIT_TARGET
| ORT_ACC
))
13268 == ORT_TARGET
&& ctx
->code
== OMP_TARGET
)
13269 || ((ctx
->region_type
& ORT_TEAMS
) && ctx
->code
== OMP_TEAMS
)
13270 || (ctx
->region_type
== ORT_WORKSHARE
&& ctx
->code
== OMP_FOR
)
13271 || (ctx
->region_type
== ORT_SIMD
13272 && ctx
->code
== OMP_SIMD
13273 && !omp_find_clause (ctx
->clauses
, OMP_CLAUSE_BIND
)))
13277 codes
.safe_push (ctx
->code
);
13278 else if (matched
< nconstructs
&& ctx
->code
== constructs
[matched
])
13280 if (ctx
->code
== OMP_SIMD
)
13288 if (ctx
->code
== OMP_TARGET
)
13290 if (scores
== NULL
)
13291 return matched
< nconstructs
? 0 : simd_seen
? -1 : 1;
13292 target_seen
= true;
13296 else if (ctx
->region_type
== ORT_WORKSHARE
13297 && ctx
->code
== OMP_LOOP
13298 && ctx
->outer_context
13299 && ctx
->outer_context
->region_type
== ORT_COMBINED_PARALLEL
13300 && ctx
->outer_context
->outer_context
13301 && ctx
->outer_context
->outer_context
->code
== OMP_LOOP
13302 && ctx
->outer_context
->outer_context
->distribute
)
13303 ctx
= ctx
->outer_context
->outer_context
;
13304 ctx
= ctx
->outer_context
;
13307 && lookup_attribute ("omp declare simd",
13308 DECL_ATTRIBUTES (current_function_decl
)))
13310 /* Declare simd is a maybe case, it is supposed to be added only to the
13311 omp-simd-clone.cc added clones and not to the base function. */
13312 declare_simd_cnt
= cnt
++;
13314 codes
.safe_push (OMP_SIMD
);
13316 && constructs
[0] == OMP_SIMD
)
13318 gcc_assert (matched
== 0);
13320 if (++matched
== nconstructs
)
13324 if (tree attr
= lookup_attribute ("omp declare variant variant",
13325 DECL_ATTRIBUTES (current_function_decl
)))
13327 enum tree_code variant_constructs
[5];
13328 int variant_nconstructs
= 0;
13330 variant_nconstructs
13331 = omp_constructor_traits_to_codes (TREE_VALUE (attr
),
13332 variant_constructs
);
13333 for (int i
= 0; i
< variant_nconstructs
; i
++)
13337 codes
.safe_push (variant_constructs
[i
]);
13338 else if (matched
< nconstructs
13339 && variant_constructs
[i
] == constructs
[matched
])
13341 if (variant_constructs
[i
] == OMP_SIMD
)
13352 && lookup_attribute ("omp declare target block",
13353 DECL_ATTRIBUTES (current_function_decl
)))
13356 codes
.safe_push (OMP_TARGET
);
13357 else if (matched
< nconstructs
&& constructs
[matched
] == OMP_TARGET
)
13362 for (int pass
= 0; pass
< (declare_simd_cnt
== -1 ? 1 : 2); pass
++)
13364 int j
= codes
.length () - 1;
13365 for (int i
= nconstructs
- 1; i
>= 0; i
--)
13368 && (pass
!= 0 || declare_simd_cnt
!= j
)
13369 && constructs
[i
] != codes
[j
])
13371 if (pass
== 0 && declare_simd_cnt
!= -1 && j
> declare_simd_cnt
)
13376 *scores
++ = ((pass
== 0 && declare_simd_cnt
!= -1)
13377 ? codes
.length () - 1 : codes
.length ());
13379 return declare_simd_cnt
== -1 ? 1 : 2;
13381 if (matched
== nconstructs
)
13382 return simd_seen
? -1 : 1;
13386 /* Gimplify OACC_CACHE. */
13389 gimplify_oacc_cache (tree
*expr_p
, gimple_seq
*pre_p
)
13391 tree expr
= *expr_p
;
13393 gimplify_scan_omp_clauses (&OACC_CACHE_CLAUSES (expr
), pre_p
, ORT_ACC
,
13395 gimplify_adjust_omp_clauses (pre_p
, NULL
, &OACC_CACHE_CLAUSES (expr
),
13398 /* TODO: Do something sensible with this information. */
13400 *expr_p
= NULL_TREE
;
13403 /* Helper function of gimplify_oacc_declare. The helper's purpose is to,
13404 if required, translate 'kind' in CLAUSE into an 'entry' kind and 'exit'
13405 kind. The entry kind will replace the one in CLAUSE, while the exit
13406 kind will be used in a new omp_clause and returned to the caller. */
13409 gimplify_oacc_declare_1 (tree clause
)
13411 HOST_WIDE_INT kind
, new_op
;
13415 kind
= OMP_CLAUSE_MAP_KIND (clause
);
13419 case GOMP_MAP_ALLOC
:
13420 new_op
= GOMP_MAP_RELEASE
;
13424 case GOMP_MAP_FROM
:
13425 OMP_CLAUSE_SET_MAP_KIND (clause
, GOMP_MAP_FORCE_ALLOC
);
13426 new_op
= GOMP_MAP_FROM
;
13430 case GOMP_MAP_TOFROM
:
13431 OMP_CLAUSE_SET_MAP_KIND (clause
, GOMP_MAP_TO
);
13432 new_op
= GOMP_MAP_FROM
;
13436 case GOMP_MAP_DEVICE_RESIDENT
:
13437 case GOMP_MAP_FORCE_DEVICEPTR
:
13438 case GOMP_MAP_FORCE_PRESENT
:
13439 case GOMP_MAP_LINK
:
13440 case GOMP_MAP_POINTER
:
13445 gcc_unreachable ();
13451 c
= build_omp_clause (OMP_CLAUSE_LOCATION (clause
), OMP_CLAUSE_MAP
);
13452 OMP_CLAUSE_SET_MAP_KIND (c
, new_op
);
13453 OMP_CLAUSE_DECL (c
) = OMP_CLAUSE_DECL (clause
);
13459 /* Gimplify OACC_DECLARE. */
13462 gimplify_oacc_declare (tree
*expr_p
, gimple_seq
*pre_p
)
13464 tree expr
= *expr_p
;
13466 tree clauses
, t
, decl
;
13468 clauses
= OACC_DECLARE_CLAUSES (expr
);
13470 gimplify_scan_omp_clauses (&clauses
, pre_p
, ORT_TARGET_DATA
, OACC_DECLARE
);
13471 gimplify_adjust_omp_clauses (pre_p
, NULL
, &clauses
, OACC_DECLARE
);
13473 for (t
= clauses
; t
; t
= OMP_CLAUSE_CHAIN (t
))
13475 decl
= OMP_CLAUSE_DECL (t
);
13477 if (TREE_CODE (decl
) == MEM_REF
)
13478 decl
= TREE_OPERAND (decl
, 0);
13480 if (VAR_P (decl
) && !is_oacc_declared (decl
))
13482 tree attr
= get_identifier ("oacc declare target");
13483 DECL_ATTRIBUTES (decl
) = tree_cons (attr
, NULL_TREE
,
13484 DECL_ATTRIBUTES (decl
));
13488 && !is_global_var (decl
)
13489 && DECL_CONTEXT (decl
) == current_function_decl
)
13491 tree c
= gimplify_oacc_declare_1 (t
);
13494 if (oacc_declare_returns
== NULL
)
13495 oacc_declare_returns
= new hash_map
<tree
, tree
>;
13497 oacc_declare_returns
->put (decl
, c
);
13501 if (gimplify_omp_ctxp
)
13502 omp_add_variable (gimplify_omp_ctxp
, decl
, GOVD_SEEN
);
13505 stmt
= gimple_build_omp_target (NULL
, GF_OMP_TARGET_KIND_OACC_DECLARE
,
13508 gimplify_seq_add_stmt (pre_p
, stmt
);
13510 *expr_p
= NULL_TREE
;
13513 /* Gimplify the contents of an OMP_PARALLEL statement. This involves
13514 gimplification of the body, as well as scanning the body for used
13515 variables. We need to do this scan now, because variable-sized
13516 decls will be decomposed during gimplification. */
13519 gimplify_omp_parallel (tree
*expr_p
, gimple_seq
*pre_p
)
13521 tree expr
= *expr_p
;
13523 gimple_seq body
= NULL
;
13525 gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr
), pre_p
,
13526 OMP_PARALLEL_COMBINED (expr
)
13527 ? ORT_COMBINED_PARALLEL
13528 : ORT_PARALLEL
, OMP_PARALLEL
);
13530 push_gimplify_context ();
13532 g
= gimplify_and_return_first (OMP_PARALLEL_BODY (expr
), &body
);
13533 if (gimple_code (g
) == GIMPLE_BIND
)
13534 pop_gimplify_context (g
);
13536 pop_gimplify_context (NULL
);
13538 gimplify_adjust_omp_clauses (pre_p
, body
, &OMP_PARALLEL_CLAUSES (expr
),
13541 g
= gimple_build_omp_parallel (body
,
13542 OMP_PARALLEL_CLAUSES (expr
),
13543 NULL_TREE
, NULL_TREE
);
13544 if (OMP_PARALLEL_COMBINED (expr
))
13545 gimple_omp_set_subcode (g
, GF_OMP_PARALLEL_COMBINED
);
13546 gimplify_seq_add_stmt (pre_p
, g
);
13547 *expr_p
= NULL_TREE
;
13550 /* Gimplify the contents of an OMP_TASK statement. This involves
13551 gimplification of the body, as well as scanning the body for used
13552 variables. We need to do this scan now, because variable-sized
13553 decls will be decomposed during gimplification. */
13556 gimplify_omp_task (tree
*expr_p
, gimple_seq
*pre_p
)
13558 tree expr
= *expr_p
;
13560 gimple_seq body
= NULL
;
13561 bool nowait
= false;
13562 bool has_depend
= false;
13564 if (OMP_TASK_BODY (expr
) == NULL_TREE
)
13566 for (tree c
= OMP_TASK_CLAUSES (expr
); c
; c
= OMP_CLAUSE_CHAIN (c
))
13567 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEPEND
)
13570 if (OMP_CLAUSE_DEPEND_KIND (c
) == OMP_CLAUSE_DEPEND_MUTEXINOUTSET
)
13572 error_at (OMP_CLAUSE_LOCATION (c
),
13573 "%<mutexinoutset%> kind in %<depend%> clause on a "
13574 "%<taskwait%> construct");
13578 else if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_NOWAIT
)
13580 if (nowait
&& !has_depend
)
13582 error_at (EXPR_LOCATION (expr
),
13583 "%<taskwait%> construct with %<nowait%> clause but no "
13584 "%<depend%> clauses");
13585 *expr_p
= NULL_TREE
;
13590 gimplify_scan_omp_clauses (&OMP_TASK_CLAUSES (expr
), pre_p
,
13591 omp_find_clause (OMP_TASK_CLAUSES (expr
),
13593 ? ORT_UNTIED_TASK
: ORT_TASK
, OMP_TASK
);
13595 if (OMP_TASK_BODY (expr
))
13597 push_gimplify_context ();
13599 g
= gimplify_and_return_first (OMP_TASK_BODY (expr
), &body
);
13600 if (gimple_code (g
) == GIMPLE_BIND
)
13601 pop_gimplify_context (g
);
13603 pop_gimplify_context (NULL
);
13606 gimplify_adjust_omp_clauses (pre_p
, body
, &OMP_TASK_CLAUSES (expr
),
13609 g
= gimple_build_omp_task (body
,
13610 OMP_TASK_CLAUSES (expr
),
13611 NULL_TREE
, NULL_TREE
,
13612 NULL_TREE
, NULL_TREE
, NULL_TREE
);
13613 if (OMP_TASK_BODY (expr
) == NULL_TREE
)
13614 gimple_omp_task_set_taskwait_p (g
, true);
13615 gimplify_seq_add_stmt (pre_p
, g
);
13616 *expr_p
= NULL_TREE
;
13619 /* Helper function for gimplify_omp_for. If *TP is not a gimple constant,
13620 force it into a temporary initialized in PRE_P and add firstprivate clause
13621 to ORIG_FOR_STMT. */
13624 gimplify_omp_taskloop_expr (tree type
, tree
*tp
, gimple_seq
*pre_p
,
13625 tree orig_for_stmt
)
13627 if (*tp
== NULL
|| is_gimple_constant (*tp
))
13630 *tp
= get_initialized_tmp_var (*tp
, pre_p
, NULL
, false);
13631 /* Reference to pointer conversion is considered useless,
13632 but is significant for firstprivate clause. Force it
13635 && TREE_CODE (type
) == POINTER_TYPE
13636 && TREE_CODE (TREE_TYPE (*tp
)) == REFERENCE_TYPE
)
13638 tree v
= create_tmp_var (TYPE_MAIN_VARIANT (type
));
13639 tree m
= build2 (INIT_EXPR
, TREE_TYPE (v
), v
, *tp
);
13640 gimplify_and_add (m
, pre_p
);
13644 tree c
= build_omp_clause (input_location
, OMP_CLAUSE_FIRSTPRIVATE
);
13645 OMP_CLAUSE_DECL (c
) = *tp
;
13646 OMP_CLAUSE_CHAIN (c
) = OMP_FOR_CLAUSES (orig_for_stmt
);
13647 OMP_FOR_CLAUSES (orig_for_stmt
) = c
;
13650 /* Helper function of gimplify_omp_for, find OMP_ORDERED with
13651 null OMP_ORDERED_BODY inside of OMP_FOR's body. */
13654 find_standalone_omp_ordered (tree
*tp
, int *walk_subtrees
, void *)
13656 switch (TREE_CODE (*tp
))
13659 if (OMP_ORDERED_BODY (*tp
) == NULL_TREE
)
13665 *walk_subtrees
= 0;
13673 /* Gimplify the gross structure of an OMP_FOR statement. */
13675 static enum gimplify_status
13676 gimplify_omp_for (tree
*expr_p
, gimple_seq
*pre_p
)
13678 tree for_stmt
, orig_for_stmt
, inner_for_stmt
= NULL_TREE
, decl
, var
, t
;
13679 enum gimplify_status ret
= GS_ALL_DONE
;
13680 enum gimplify_status tret
;
13682 gimple_seq for_body
, for_pre_body
;
13684 bitmap has_decl_expr
= NULL
;
13685 enum omp_region_type ort
= ORT_WORKSHARE
;
13686 bool openacc
= TREE_CODE (*expr_p
) == OACC_LOOP
;
13688 orig_for_stmt
= for_stmt
= *expr_p
;
13690 bool loop_p
= (omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_BIND
)
13692 if (OMP_FOR_INIT (for_stmt
) == NULL_TREE
)
13694 tree
*data
[4] = { NULL
, NULL
, NULL
, NULL
};
13695 gcc_assert (TREE_CODE (for_stmt
) != OACC_LOOP
);
13696 inner_for_stmt
= walk_tree (&OMP_FOR_BODY (for_stmt
),
13697 find_combined_omp_for
, data
, NULL
);
13698 if (inner_for_stmt
== NULL_TREE
)
13700 gcc_assert (seen_error ());
13701 *expr_p
= NULL_TREE
;
13704 if (data
[2] && OMP_FOR_PRE_BODY (*data
[2]))
13706 append_to_statement_list_force (OMP_FOR_PRE_BODY (*data
[2]),
13707 &OMP_FOR_PRE_BODY (for_stmt
));
13708 OMP_FOR_PRE_BODY (*data
[2]) = NULL_TREE
;
13710 if (OMP_FOR_PRE_BODY (inner_for_stmt
))
13712 append_to_statement_list_force (OMP_FOR_PRE_BODY (inner_for_stmt
),
13713 &OMP_FOR_PRE_BODY (for_stmt
));
13714 OMP_FOR_PRE_BODY (inner_for_stmt
) = NULL_TREE
;
13719 /* We have some statements or variable declarations in between
13720 the composite construct directives. Move them around the
13723 for (i
= 0; i
< 3; i
++)
13727 if (i
< 2 && data
[i
+ 1] == &OMP_BODY (t
))
13728 data
[i
+ 1] = data
[i
];
13729 *data
[i
] = OMP_BODY (t
);
13730 tree body
= build3 (BIND_EXPR
, void_type_node
, NULL_TREE
,
13731 NULL_TREE
, make_node (BLOCK
));
13732 OMP_BODY (t
) = body
;
13733 append_to_statement_list_force (inner_for_stmt
,
13734 &BIND_EXPR_BODY (body
));
13736 data
[3] = tsi_stmt_ptr (tsi_start (BIND_EXPR_BODY (body
)));
13737 gcc_assert (*data
[3] == inner_for_stmt
);
13742 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt
)); i
++)
13744 && OMP_FOR_ORIG_DECLS (inner_for_stmt
)
13745 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
),
13747 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
),
13750 tree orig
= TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
), i
);
13751 /* Class iterators aren't allowed on OMP_SIMD, so the only
13752 case we need to solve is distribute parallel for. They are
13753 allowed on the loop construct, but that is already handled
13754 in gimplify_omp_loop. */
13755 gcc_assert (TREE_CODE (inner_for_stmt
) == OMP_FOR
13756 && TREE_CODE (for_stmt
) == OMP_DISTRIBUTE
13758 tree orig_decl
= TREE_PURPOSE (orig
);
13759 tree last
= TREE_VALUE (orig
);
13761 for (pc
= &OMP_FOR_CLAUSES (inner_for_stmt
);
13762 *pc
; pc
= &OMP_CLAUSE_CHAIN (*pc
))
13763 if ((OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_PRIVATE
13764 || OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_LASTPRIVATE
)
13765 && OMP_CLAUSE_DECL (*pc
) == orig_decl
)
13767 if (*pc
== NULL_TREE
)
13770 for (spc
= &OMP_PARALLEL_CLAUSES (*data
[1]);
13771 *spc
; spc
= &OMP_CLAUSE_CHAIN (*spc
))
13772 if (OMP_CLAUSE_CODE (*spc
) == OMP_CLAUSE_PRIVATE
13773 && OMP_CLAUSE_DECL (*spc
) == orig_decl
)
13778 *spc
= OMP_CLAUSE_CHAIN (c
);
13779 OMP_CLAUSE_CHAIN (c
) = NULL_TREE
;
13783 if (*pc
== NULL_TREE
)
13785 else if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_PRIVATE
)
13787 /* private clause will appear only on inner_for_stmt.
13788 Change it into firstprivate, and add private clause
13790 tree c
= copy_node (*pc
);
13791 OMP_CLAUSE_CHAIN (c
) = OMP_FOR_CLAUSES (for_stmt
);
13792 OMP_FOR_CLAUSES (for_stmt
) = c
;
13793 OMP_CLAUSE_CODE (*pc
) = OMP_CLAUSE_FIRSTPRIVATE
;
13794 lang_hooks
.decls
.omp_finish_clause (*pc
, pre_p
, openacc
);
13798 /* lastprivate clause will appear on both inner_for_stmt
13799 and for_stmt. Add firstprivate clause to
13801 tree c
= build_omp_clause (OMP_CLAUSE_LOCATION (*pc
),
13802 OMP_CLAUSE_FIRSTPRIVATE
);
13803 OMP_CLAUSE_DECL (c
) = OMP_CLAUSE_DECL (*pc
);
13804 OMP_CLAUSE_CHAIN (c
) = *pc
;
13806 lang_hooks
.decls
.omp_finish_clause (*pc
, pre_p
, openacc
);
13808 tree c
= build_omp_clause (UNKNOWN_LOCATION
,
13809 OMP_CLAUSE_FIRSTPRIVATE
);
13810 OMP_CLAUSE_DECL (c
) = last
;
13811 OMP_CLAUSE_CHAIN (c
) = OMP_PARALLEL_CLAUSES (*data
[1]);
13812 OMP_PARALLEL_CLAUSES (*data
[1]) = c
;
13813 c
= build_omp_clause (UNKNOWN_LOCATION
,
13814 *pc
? OMP_CLAUSE_SHARED
13815 : OMP_CLAUSE_FIRSTPRIVATE
);
13816 OMP_CLAUSE_DECL (c
) = orig_decl
;
13817 OMP_CLAUSE_CHAIN (c
) = OMP_PARALLEL_CLAUSES (*data
[1]);
13818 OMP_PARALLEL_CLAUSES (*data
[1]) = c
;
13820 /* Similarly, take care of C++ range for temporaries, those should
13821 be firstprivate on OMP_PARALLEL if any. */
13823 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt
)); i
++)
13824 if (OMP_FOR_ORIG_DECLS (inner_for_stmt
)
13825 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
),
13827 && TREE_CHAIN (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
),
13831 = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
), i
);
13832 tree v
= TREE_CHAIN (orig
);
13833 tree c
= build_omp_clause (UNKNOWN_LOCATION
,
13834 OMP_CLAUSE_FIRSTPRIVATE
);
13835 /* First add firstprivate clause for the __for_end artificial
13837 OMP_CLAUSE_DECL (c
) = TREE_VEC_ELT (v
, 1);
13838 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c
)))
13840 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c
) = 1;
13841 OMP_CLAUSE_CHAIN (c
) = OMP_PARALLEL_CLAUSES (*data
[1]);
13842 OMP_PARALLEL_CLAUSES (*data
[1]) = c
;
13843 if (TREE_VEC_ELT (v
, 0))
13845 /* And now the same for __for_range artificial decl if it
13847 c
= build_omp_clause (UNKNOWN_LOCATION
,
13848 OMP_CLAUSE_FIRSTPRIVATE
);
13849 OMP_CLAUSE_DECL (c
) = TREE_VEC_ELT (v
, 0);
13850 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c
)))
13852 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c
) = 1;
13853 OMP_CLAUSE_CHAIN (c
) = OMP_PARALLEL_CLAUSES (*data
[1]);
13854 OMP_PARALLEL_CLAUSES (*data
[1]) = c
;
13859 switch (TREE_CODE (for_stmt
))
13862 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt
? inner_for_stmt
: for_stmt
))
13864 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt
),
13865 OMP_CLAUSE_SCHEDULE
))
13866 error_at (EXPR_LOCATION (for_stmt
),
13867 "%qs clause may not appear on non-rectangular %qs",
13868 "schedule", lang_GNU_Fortran () ? "do" : "for");
13869 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_ORDERED
))
13870 error_at (EXPR_LOCATION (for_stmt
),
13871 "%qs clause may not appear on non-rectangular %qs",
13872 "ordered", lang_GNU_Fortran () ? "do" : "for");
13875 case OMP_DISTRIBUTE
:
13876 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt
? inner_for_stmt
: for_stmt
)
13877 && omp_find_clause (OMP_FOR_CLAUSES (for_stmt
),
13878 OMP_CLAUSE_DIST_SCHEDULE
))
13879 error_at (EXPR_LOCATION (for_stmt
),
13880 "%qs clause may not appear on non-rectangular %qs",
13881 "dist_schedule", "distribute");
13887 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt
? inner_for_stmt
: for_stmt
))
13889 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt
),
13890 OMP_CLAUSE_GRAINSIZE
))
13891 error_at (EXPR_LOCATION (for_stmt
),
13892 "%qs clause may not appear on non-rectangular %qs",
13893 "grainsize", "taskloop");
13894 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt
),
13895 OMP_CLAUSE_NUM_TASKS
))
13896 error_at (EXPR_LOCATION (for_stmt
),
13897 "%qs clause may not appear on non-rectangular %qs",
13898 "num_tasks", "taskloop");
13900 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_UNTIED
))
13901 ort
= ORT_UNTIED_TASKLOOP
;
13903 ort
= ORT_TASKLOOP
;
13909 gcc_unreachable ();
13912 /* Set OMP_CLAUSE_LINEAR_NO_COPYIN flag on explicit linear
13913 clause for the IV. */
13914 if (ort
== ORT_SIMD
&& TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)) == 1)
13916 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), 0);
13917 gcc_assert (TREE_CODE (t
) == MODIFY_EXPR
);
13918 decl
= TREE_OPERAND (t
, 0);
13919 for (tree c
= OMP_FOR_CLAUSES (for_stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
13920 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINEAR
13921 && OMP_CLAUSE_DECL (c
) == decl
)
13923 OMP_CLAUSE_LINEAR_NO_COPYIN (c
) = 1;
13928 if (TREE_CODE (for_stmt
) != OMP_TASKLOOP
)
13929 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt
), pre_p
, ort
,
13930 loop_p
&& TREE_CODE (for_stmt
) != OMP_SIMD
13931 ? OMP_LOOP
: TREE_CODE (for_stmt
));
13933 if (TREE_CODE (for_stmt
) == OMP_DISTRIBUTE
)
13934 gimplify_omp_ctxp
->distribute
= true;
13936 /* Handle OMP_FOR_INIT. */
13937 for_pre_body
= NULL
;
13938 if ((ort
== ORT_SIMD
13939 || (inner_for_stmt
&& TREE_CODE (inner_for_stmt
) == OMP_SIMD
))
13940 && OMP_FOR_PRE_BODY (for_stmt
))
13942 has_decl_expr
= BITMAP_ALLOC (NULL
);
13943 if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt
)) == DECL_EXPR
13944 && VAR_P (DECL_EXPR_DECL (OMP_FOR_PRE_BODY (for_stmt
))))
13946 t
= OMP_FOR_PRE_BODY (for_stmt
);
13947 bitmap_set_bit (has_decl_expr
, DECL_UID (DECL_EXPR_DECL (t
)));
13949 else if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt
)) == STATEMENT_LIST
)
13951 tree_stmt_iterator si
;
13952 for (si
= tsi_start (OMP_FOR_PRE_BODY (for_stmt
)); !tsi_end_p (si
);
13956 if (TREE_CODE (t
) == DECL_EXPR
13957 && VAR_P (DECL_EXPR_DECL (t
)))
13958 bitmap_set_bit (has_decl_expr
, DECL_UID (DECL_EXPR_DECL (t
)));
13962 if (OMP_FOR_PRE_BODY (for_stmt
))
13964 if (TREE_CODE (for_stmt
) != OMP_TASKLOOP
|| gimplify_omp_ctxp
)
13965 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt
), &for_pre_body
);
13968 struct gimplify_omp_ctx ctx
;
13969 memset (&ctx
, 0, sizeof (ctx
));
13970 ctx
.region_type
= ORT_NONE
;
13971 gimplify_omp_ctxp
= &ctx
;
13972 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt
), &for_pre_body
);
13973 gimplify_omp_ctxp
= NULL
;
13976 OMP_FOR_PRE_BODY (for_stmt
) = NULL_TREE
;
13978 if (OMP_FOR_INIT (for_stmt
) == NULL_TREE
)
13979 for_stmt
= inner_for_stmt
;
13981 /* For taskloop, need to gimplify the start, end and step before the
13982 taskloop, outside of the taskloop omp context. */
13983 if (TREE_CODE (orig_for_stmt
) == OMP_TASKLOOP
)
13985 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
13987 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), i
);
13988 gimple_seq
*for_pre_p
= (gimple_seq_empty_p (for_pre_body
)
13989 ? pre_p
: &for_pre_body
);
13990 tree type
= TREE_TYPE (TREE_OPERAND (t
, 0));
13991 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
)
13993 tree v
= TREE_OPERAND (t
, 1);
13994 gimplify_omp_taskloop_expr (type
, &TREE_VEC_ELT (v
, 1),
13995 for_pre_p
, orig_for_stmt
);
13996 gimplify_omp_taskloop_expr (type
, &TREE_VEC_ELT (v
, 2),
13997 for_pre_p
, orig_for_stmt
);
14000 gimplify_omp_taskloop_expr (type
, &TREE_OPERAND (t
, 1), for_pre_p
,
14003 /* Handle OMP_FOR_COND. */
14004 t
= TREE_VEC_ELT (OMP_FOR_COND (for_stmt
), i
);
14005 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
)
14007 tree v
= TREE_OPERAND (t
, 1);
14008 gimplify_omp_taskloop_expr (type
, &TREE_VEC_ELT (v
, 1),
14009 for_pre_p
, orig_for_stmt
);
14010 gimplify_omp_taskloop_expr (type
, &TREE_VEC_ELT (v
, 2),
14011 for_pre_p
, orig_for_stmt
);
14014 gimplify_omp_taskloop_expr (type
, &TREE_OPERAND (t
, 1), for_pre_p
,
14017 /* Handle OMP_FOR_INCR. */
14018 t
= TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
);
14019 if (TREE_CODE (t
) == MODIFY_EXPR
)
14021 decl
= TREE_OPERAND (t
, 0);
14022 t
= TREE_OPERAND (t
, 1);
14023 tree
*tp
= &TREE_OPERAND (t
, 1);
14024 if (TREE_CODE (t
) == PLUS_EXPR
&& *tp
== decl
)
14025 tp
= &TREE_OPERAND (t
, 0);
14027 gimplify_omp_taskloop_expr (NULL_TREE
, tp
, for_pre_p
,
14032 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (orig_for_stmt
), pre_p
, ort
,
14036 if (orig_for_stmt
!= for_stmt
)
14037 gimplify_omp_ctxp
->combined_loop
= true;
14040 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
))
14041 == TREE_VEC_LENGTH (OMP_FOR_COND (for_stmt
)));
14042 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
))
14043 == TREE_VEC_LENGTH (OMP_FOR_INCR (for_stmt
)));
14045 tree c
= omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_ORDERED
);
14046 bool is_doacross
= false;
14047 if (c
&& walk_tree_without_duplicates (&OMP_FOR_BODY (for_stmt
),
14048 find_standalone_omp_ordered
, NULL
))
14050 OMP_CLAUSE_ORDERED_DOACROSS (c
) = 1;
14051 is_doacross
= true;
14052 int len
= TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
));
14053 gimplify_omp_ctxp
->loop_iter_var
.create (len
* 2);
14054 for (tree
*pc
= &OMP_FOR_CLAUSES (for_stmt
); *pc
; )
14055 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_LINEAR
)
14057 error_at (OMP_CLAUSE_LOCATION (*pc
),
14058 "%<linear%> clause may not be specified together "
14059 "with %<ordered%> clause if stand-alone %<ordered%> "
14060 "construct is nested in it");
14061 *pc
= OMP_CLAUSE_CHAIN (*pc
);
14064 pc
= &OMP_CLAUSE_CHAIN (*pc
);
14066 int collapse
= 1, tile
= 0;
14067 c
= omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_COLLAPSE
);
14069 collapse
= tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (c
));
14070 c
= omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_TILE
);
14072 tile
= list_length (OMP_CLAUSE_TILE_LIST (c
));
14073 c
= omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_ALLOCATE
);
14074 hash_set
<tree
> *allocate_uids
= NULL
;
14077 allocate_uids
= new hash_set
<tree
>;
14078 for (; c
; c
= OMP_CLAUSE_CHAIN (c
))
14079 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_ALLOCATE
)
14080 allocate_uids
->add (OMP_CLAUSE_DECL (c
));
14082 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
14084 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), i
);
14085 gcc_assert (TREE_CODE (t
) == MODIFY_EXPR
);
14086 decl
= TREE_OPERAND (t
, 0);
14087 gcc_assert (DECL_P (decl
));
14088 gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl
))
14089 || POINTER_TYPE_P (TREE_TYPE (decl
)));
14092 if (TREE_CODE (for_stmt
) == OMP_FOR
&& OMP_FOR_ORIG_DECLS (for_stmt
))
14094 tree orig_decl
= TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
), i
);
14095 if (TREE_CODE (orig_decl
) == TREE_LIST
)
14097 orig_decl
= TREE_PURPOSE (orig_decl
);
14101 gimplify_omp_ctxp
->loop_iter_var
.quick_push (orig_decl
);
14104 gimplify_omp_ctxp
->loop_iter_var
.quick_push (decl
);
14105 gimplify_omp_ctxp
->loop_iter_var
.quick_push (decl
);
14108 if (for_stmt
== orig_for_stmt
)
14110 tree orig_decl
= decl
;
14111 if (OMP_FOR_ORIG_DECLS (for_stmt
))
14113 tree orig_decl
= TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
), i
);
14114 if (TREE_CODE (orig_decl
) == TREE_LIST
)
14116 orig_decl
= TREE_PURPOSE (orig_decl
);
14121 if (is_global_var (orig_decl
) && DECL_THREAD_LOCAL_P (orig_decl
))
14122 error_at (EXPR_LOCATION (for_stmt
),
14123 "threadprivate iteration variable %qD", orig_decl
);
14126 /* Make sure the iteration variable is private. */
14127 tree c
= NULL_TREE
;
14128 tree c2
= NULL_TREE
;
14129 if (orig_for_stmt
!= for_stmt
)
14131 /* Preserve this information until we gimplify the inner simd. */
14133 && bitmap_bit_p (has_decl_expr
, DECL_UID (decl
)))
14134 TREE_PRIVATE (t
) = 1;
14136 else if (ort
== ORT_SIMD
)
14138 splay_tree_node n
= splay_tree_lookup (gimplify_omp_ctxp
->variables
,
14139 (splay_tree_key
) decl
);
14140 omp_is_private (gimplify_omp_ctxp
, decl
,
14141 1 + (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
))
14143 if (n
!= NULL
&& (n
->value
& GOVD_DATA_SHARE_CLASS
) != 0)
14145 omp_notice_variable (gimplify_omp_ctxp
, decl
, true);
14146 if (n
->value
& GOVD_LASTPRIVATE_CONDITIONAL
)
14147 for (tree c3
= omp_find_clause (OMP_FOR_CLAUSES (for_stmt
),
14148 OMP_CLAUSE_LASTPRIVATE
);
14149 c3
; c3
= omp_find_clause (OMP_CLAUSE_CHAIN (c3
),
14150 OMP_CLAUSE_LASTPRIVATE
))
14151 if (OMP_CLAUSE_DECL (c3
) == decl
)
14153 warning_at (OMP_CLAUSE_LOCATION (c3
), 0,
14154 "conditional %<lastprivate%> on loop "
14155 "iterator %qD ignored", decl
);
14156 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3
) = 0;
14157 n
->value
&= ~GOVD_LASTPRIVATE_CONDITIONAL
;
14160 else if (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)) == 1 && !loop_p
)
14162 c
= build_omp_clause (input_location
, OMP_CLAUSE_LINEAR
);
14163 OMP_CLAUSE_LINEAR_NO_COPYIN (c
) = 1;
14164 unsigned int flags
= GOVD_LINEAR
| GOVD_EXPLICIT
| GOVD_SEEN
;
14166 && bitmap_bit_p (has_decl_expr
, DECL_UID (decl
)))
14167 || TREE_PRIVATE (t
))
14169 OMP_CLAUSE_LINEAR_NO_COPYOUT (c
) = 1;
14170 flags
|= GOVD_LINEAR_LASTPRIVATE_NO_OUTER
;
14172 struct gimplify_omp_ctx
*outer
14173 = gimplify_omp_ctxp
->outer_context
;
14174 if (outer
&& !OMP_CLAUSE_LINEAR_NO_COPYOUT (c
))
14176 if (outer
->region_type
== ORT_WORKSHARE
14177 && outer
->combined_loop
)
14179 n
= splay_tree_lookup (outer
->variables
,
14180 (splay_tree_key
)decl
);
14181 if (n
!= NULL
&& (n
->value
& GOVD_LOCAL
) != 0)
14183 OMP_CLAUSE_LINEAR_NO_COPYOUT (c
) = 1;
14184 flags
|= GOVD_LINEAR_LASTPRIVATE_NO_OUTER
;
14188 struct gimplify_omp_ctx
*octx
= outer
->outer_context
;
14190 && octx
->region_type
== ORT_COMBINED_PARALLEL
14191 && octx
->outer_context
14192 && (octx
->outer_context
->region_type
14194 && octx
->outer_context
->combined_loop
)
14196 octx
= octx
->outer_context
;
14197 n
= splay_tree_lookup (octx
->variables
,
14198 (splay_tree_key
)decl
);
14199 if (n
!= NULL
&& (n
->value
& GOVD_LOCAL
) != 0)
14201 OMP_CLAUSE_LINEAR_NO_COPYOUT (c
) = 1;
14202 flags
|= GOVD_LINEAR_LASTPRIVATE_NO_OUTER
;
14209 OMP_CLAUSE_DECL (c
) = decl
;
14210 OMP_CLAUSE_CHAIN (c
) = OMP_FOR_CLAUSES (for_stmt
);
14211 OMP_FOR_CLAUSES (for_stmt
) = c
;
14212 omp_add_variable (gimplify_omp_ctxp
, decl
, flags
);
14213 if (outer
&& !OMP_CLAUSE_LINEAR_NO_COPYOUT (c
))
14214 omp_lastprivate_for_combined_outer_constructs (outer
, decl
,
14221 || !bitmap_bit_p (has_decl_expr
, DECL_UID (decl
)));
14222 if (TREE_PRIVATE (t
))
14223 lastprivate
= false;
14224 if (loop_p
&& OMP_FOR_ORIG_DECLS (for_stmt
))
14226 tree elt
= TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
), i
);
14227 if (TREE_CODE (elt
) == TREE_LIST
&& TREE_PURPOSE (elt
))
14228 lastprivate
= false;
14231 struct gimplify_omp_ctx
*outer
14232 = gimplify_omp_ctxp
->outer_context
;
14233 if (outer
&& lastprivate
)
14234 omp_lastprivate_for_combined_outer_constructs (outer
, decl
,
14237 c
= build_omp_clause (input_location
,
14238 lastprivate
? OMP_CLAUSE_LASTPRIVATE
14239 : OMP_CLAUSE_PRIVATE
);
14240 OMP_CLAUSE_DECL (c
) = decl
;
14241 OMP_CLAUSE_CHAIN (c
) = OMP_FOR_CLAUSES (for_stmt
);
14242 OMP_FOR_CLAUSES (for_stmt
) = c
;
14243 omp_add_variable (gimplify_omp_ctxp
, decl
,
14244 (lastprivate
? GOVD_LASTPRIVATE
: GOVD_PRIVATE
)
14245 | GOVD_EXPLICIT
| GOVD_SEEN
);
14249 else if (omp_is_private (gimplify_omp_ctxp
, decl
, 0))
14251 omp_notice_variable (gimplify_omp_ctxp
, decl
, true);
14252 splay_tree_node n
= splay_tree_lookup (gimplify_omp_ctxp
->variables
,
14253 (splay_tree_key
) decl
);
14254 if (n
&& (n
->value
& GOVD_LASTPRIVATE_CONDITIONAL
))
14255 for (tree c3
= omp_find_clause (OMP_FOR_CLAUSES (for_stmt
),
14256 OMP_CLAUSE_LASTPRIVATE
);
14257 c3
; c3
= omp_find_clause (OMP_CLAUSE_CHAIN (c3
),
14258 OMP_CLAUSE_LASTPRIVATE
))
14259 if (OMP_CLAUSE_DECL (c3
) == decl
)
14261 warning_at (OMP_CLAUSE_LOCATION (c3
), 0,
14262 "conditional %<lastprivate%> on loop "
14263 "iterator %qD ignored", decl
);
14264 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3
) = 0;
14265 n
->value
&= ~GOVD_LASTPRIVATE_CONDITIONAL
;
14269 omp_add_variable (gimplify_omp_ctxp
, decl
, GOVD_PRIVATE
| GOVD_SEEN
);
14271 /* If DECL is not a gimple register, create a temporary variable to act
14272 as an iteration counter. This is valid, since DECL cannot be
14273 modified in the body of the loop. Similarly for any iteration vars
14274 in simd with collapse > 1 where the iterator vars must be
14275 lastprivate. And similarly for vars mentioned in allocate clauses. */
14276 if (orig_for_stmt
!= for_stmt
)
14278 else if (!is_gimple_reg (decl
)
14279 || (ort
== ORT_SIMD
14280 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)) > 1)
14281 || (allocate_uids
&& allocate_uids
->contains (decl
)))
14283 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
14284 /* Make sure omp_add_variable is not called on it prematurely.
14285 We call it ourselves a few lines later. */
14286 gimplify_omp_ctxp
= NULL
;
14287 var
= create_tmp_var (TREE_TYPE (decl
), get_name (decl
));
14288 gimplify_omp_ctxp
= ctx
;
14289 TREE_OPERAND (t
, 0) = var
;
14291 gimplify_seq_add_stmt (&for_body
, gimple_build_assign (decl
, var
));
14293 if (ort
== ORT_SIMD
14294 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)) == 1)
14296 c2
= build_omp_clause (input_location
, OMP_CLAUSE_LINEAR
);
14297 OMP_CLAUSE_LINEAR_NO_COPYIN (c2
) = 1;
14298 OMP_CLAUSE_LINEAR_NO_COPYOUT (c2
) = 1;
14299 OMP_CLAUSE_DECL (c2
) = var
;
14300 OMP_CLAUSE_CHAIN (c2
) = OMP_FOR_CLAUSES (for_stmt
);
14301 OMP_FOR_CLAUSES (for_stmt
) = c2
;
14302 omp_add_variable (gimplify_omp_ctxp
, var
,
14303 GOVD_LINEAR
| GOVD_EXPLICIT
| GOVD_SEEN
);
14304 if (c
== NULL_TREE
)
14311 omp_add_variable (gimplify_omp_ctxp
, var
,
14312 GOVD_PRIVATE
| GOVD_SEEN
);
14317 gimplify_omp_ctxp
->in_for_exprs
= true;
14318 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
)
14320 tree lb
= TREE_OPERAND (t
, 1);
14321 tret
= gimplify_expr (&TREE_VEC_ELT (lb
, 1), &for_pre_body
, NULL
,
14322 is_gimple_val
, fb_rvalue
, false);
14323 ret
= MIN (ret
, tret
);
14324 tret
= gimplify_expr (&TREE_VEC_ELT (lb
, 2), &for_pre_body
, NULL
,
14325 is_gimple_val
, fb_rvalue
, false);
14328 tret
= gimplify_expr (&TREE_OPERAND (t
, 1), &for_pre_body
, NULL
,
14329 is_gimple_val
, fb_rvalue
, false);
14330 gimplify_omp_ctxp
->in_for_exprs
= false;
14331 ret
= MIN (ret
, tret
);
14332 if (ret
== GS_ERROR
)
14335 /* Handle OMP_FOR_COND. */
14336 t
= TREE_VEC_ELT (OMP_FOR_COND (for_stmt
), i
);
14337 gcc_assert (COMPARISON_CLASS_P (t
));
14338 gcc_assert (TREE_OPERAND (t
, 0) == decl
);
14340 gimplify_omp_ctxp
->in_for_exprs
= true;
14341 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
)
14343 tree ub
= TREE_OPERAND (t
, 1);
14344 tret
= gimplify_expr (&TREE_VEC_ELT (ub
, 1), &for_pre_body
, NULL
,
14345 is_gimple_val
, fb_rvalue
, false);
14346 ret
= MIN (ret
, tret
);
14347 tret
= gimplify_expr (&TREE_VEC_ELT (ub
, 2), &for_pre_body
, NULL
,
14348 is_gimple_val
, fb_rvalue
, false);
14351 tret
= gimplify_expr (&TREE_OPERAND (t
, 1), &for_pre_body
, NULL
,
14352 is_gimple_val
, fb_rvalue
, false);
14353 gimplify_omp_ctxp
->in_for_exprs
= false;
14354 ret
= MIN (ret
, tret
);
14356 /* Handle OMP_FOR_INCR. */
14357 t
= TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
);
14358 switch (TREE_CODE (t
))
14360 case PREINCREMENT_EXPR
:
14361 case POSTINCREMENT_EXPR
:
14363 tree decl
= TREE_OPERAND (t
, 0);
14364 /* c_omp_for_incr_canonicalize_ptr() should have been
14365 called to massage things appropriately. */
14366 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl
)));
14368 if (orig_for_stmt
!= for_stmt
)
14370 t
= build_int_cst (TREE_TYPE (decl
), 1);
14372 OMP_CLAUSE_LINEAR_STEP (c
) = t
;
14373 t
= build2 (PLUS_EXPR
, TREE_TYPE (decl
), var
, t
);
14374 t
= build2 (MODIFY_EXPR
, TREE_TYPE (var
), var
, t
);
14375 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
) = t
;
14379 case PREDECREMENT_EXPR
:
14380 case POSTDECREMENT_EXPR
:
14381 /* c_omp_for_incr_canonicalize_ptr() should have been
14382 called to massage things appropriately. */
14383 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl
)));
14384 if (orig_for_stmt
!= for_stmt
)
14386 t
= build_int_cst (TREE_TYPE (decl
), -1);
14388 OMP_CLAUSE_LINEAR_STEP (c
) = t
;
14389 t
= build2 (PLUS_EXPR
, TREE_TYPE (decl
), var
, t
);
14390 t
= build2 (MODIFY_EXPR
, TREE_TYPE (var
), var
, t
);
14391 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
) = t
;
14395 gcc_assert (TREE_OPERAND (t
, 0) == decl
);
14396 TREE_OPERAND (t
, 0) = var
;
14398 t
= TREE_OPERAND (t
, 1);
14399 switch (TREE_CODE (t
))
14402 if (TREE_OPERAND (t
, 1) == decl
)
14404 TREE_OPERAND (t
, 1) = TREE_OPERAND (t
, 0);
14405 TREE_OPERAND (t
, 0) = var
;
14411 case POINTER_PLUS_EXPR
:
14412 gcc_assert (TREE_OPERAND (t
, 0) == decl
);
14413 TREE_OPERAND (t
, 0) = var
;
14416 gcc_unreachable ();
14419 gimplify_omp_ctxp
->in_for_exprs
= true;
14420 tret
= gimplify_expr (&TREE_OPERAND (t
, 1), &for_pre_body
, NULL
,
14421 is_gimple_val
, fb_rvalue
, false);
14422 ret
= MIN (ret
, tret
);
14425 tree step
= TREE_OPERAND (t
, 1);
14426 tree stept
= TREE_TYPE (decl
);
14427 if (POINTER_TYPE_P (stept
))
14429 step
= fold_convert (stept
, step
);
14430 if (TREE_CODE (t
) == MINUS_EXPR
)
14431 step
= fold_build1 (NEGATE_EXPR
, stept
, step
);
14432 OMP_CLAUSE_LINEAR_STEP (c
) = step
;
14433 if (step
!= TREE_OPERAND (t
, 1))
14435 tret
= gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c
),
14436 &for_pre_body
, NULL
,
14437 is_gimple_val
, fb_rvalue
, false);
14438 ret
= MIN (ret
, tret
);
14441 gimplify_omp_ctxp
->in_for_exprs
= false;
14445 gcc_unreachable ();
14451 OMP_CLAUSE_LINEAR_STEP (c2
) = OMP_CLAUSE_LINEAR_STEP (c
);
14454 if ((var
!= decl
|| collapse
> 1 || tile
) && orig_for_stmt
== for_stmt
)
14456 for (c
= OMP_FOR_CLAUSES (for_stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
14457 if (((OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
14458 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
) == NULL
)
14459 || (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINEAR
14460 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c
)
14461 && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c
) == NULL
))
14462 && OMP_CLAUSE_DECL (c
) == decl
)
14464 if (is_doacross
&& (collapse
== 1 || i
>= collapse
))
14468 t
= TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
);
14469 gcc_assert (TREE_CODE (t
) == MODIFY_EXPR
);
14470 gcc_assert (TREE_OPERAND (t
, 0) == var
);
14471 t
= TREE_OPERAND (t
, 1);
14472 gcc_assert (TREE_CODE (t
) == PLUS_EXPR
14473 || TREE_CODE (t
) == MINUS_EXPR
14474 || TREE_CODE (t
) == POINTER_PLUS_EXPR
);
14475 gcc_assert (TREE_OPERAND (t
, 0) == var
);
14476 t
= build2 (TREE_CODE (t
), TREE_TYPE (decl
),
14477 is_doacross
? var
: decl
,
14478 TREE_OPERAND (t
, 1));
14481 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
)
14482 seq
= &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
);
14484 seq
= &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c
);
14485 push_gimplify_context ();
14486 gimplify_assign (decl
, t
, seq
);
14487 gimple
*bind
= NULL
;
14488 if (gimplify_ctxp
->temps
)
14490 bind
= gimple_build_bind (NULL_TREE
, *seq
, NULL_TREE
);
14492 gimplify_seq_add_stmt (seq
, bind
);
14494 pop_gimplify_context (bind
);
14497 if (OMP_FOR_NON_RECTANGULAR (for_stmt
) && var
!= decl
)
14498 for (int j
= i
+ 1; j
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); j
++)
14500 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), j
);
14501 gcc_assert (TREE_CODE (t
) == MODIFY_EXPR
);
14502 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
14503 && TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) == decl
)
14504 TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) = var
;
14505 t
= TREE_VEC_ELT (OMP_FOR_COND (for_stmt
), j
);
14506 gcc_assert (COMPARISON_CLASS_P (t
));
14507 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
14508 && TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) == decl
)
14509 TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) = var
;
14513 BITMAP_FREE (has_decl_expr
);
14514 delete allocate_uids
;
14516 if (TREE_CODE (orig_for_stmt
) == OMP_TASKLOOP
14517 || (loop_p
&& orig_for_stmt
== for_stmt
))
14519 push_gimplify_context ();
14520 if (TREE_CODE (OMP_FOR_BODY (orig_for_stmt
)) != BIND_EXPR
)
14522 OMP_FOR_BODY (orig_for_stmt
)
14523 = build3 (BIND_EXPR
, void_type_node
, NULL
,
14524 OMP_FOR_BODY (orig_for_stmt
), NULL
);
14525 TREE_SIDE_EFFECTS (OMP_FOR_BODY (orig_for_stmt
)) = 1;
14529 gimple
*g
= gimplify_and_return_first (OMP_FOR_BODY (orig_for_stmt
),
14532 if (TREE_CODE (orig_for_stmt
) == OMP_TASKLOOP
14533 || (loop_p
&& orig_for_stmt
== for_stmt
))
14535 if (gimple_code (g
) == GIMPLE_BIND
)
14536 pop_gimplify_context (g
);
14538 pop_gimplify_context (NULL
);
14541 if (orig_for_stmt
!= for_stmt
)
14542 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
14544 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), i
);
14545 decl
= TREE_OPERAND (t
, 0);
14546 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
14547 if (TREE_CODE (orig_for_stmt
) == OMP_TASKLOOP
)
14548 gimplify_omp_ctxp
= ctx
->outer_context
;
14549 var
= create_tmp_var (TREE_TYPE (decl
), get_name (decl
));
14550 gimplify_omp_ctxp
= ctx
;
14551 omp_add_variable (gimplify_omp_ctxp
, var
, GOVD_PRIVATE
| GOVD_SEEN
);
14552 TREE_OPERAND (t
, 0) = var
;
14553 t
= TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
);
14554 TREE_OPERAND (t
, 1) = copy_node (TREE_OPERAND (t
, 1));
14555 TREE_OPERAND (TREE_OPERAND (t
, 1), 0) = var
;
14556 if (OMP_FOR_NON_RECTANGULAR (for_stmt
))
14557 for (int j
= i
+ 1;
14558 j
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); j
++)
14560 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), j
);
14561 gcc_assert (TREE_CODE (t
) == MODIFY_EXPR
);
14562 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
14563 && TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) == decl
)
14565 TREE_OPERAND (t
, 1) = copy_node (TREE_OPERAND (t
, 1));
14566 TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) = var
;
14568 t
= TREE_VEC_ELT (OMP_FOR_COND (for_stmt
), j
);
14569 gcc_assert (COMPARISON_CLASS_P (t
));
14570 if (TREE_CODE (TREE_OPERAND (t
, 1)) == TREE_VEC
14571 && TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) == decl
)
14573 TREE_OPERAND (t
, 1) = copy_node (TREE_OPERAND (t
, 1));
14574 TREE_VEC_ELT (TREE_OPERAND (t
, 1), 0) = var
;
14579 gimplify_adjust_omp_clauses (pre_p
, for_body
,
14580 &OMP_FOR_CLAUSES (orig_for_stmt
),
14581 TREE_CODE (orig_for_stmt
));
14584 switch (TREE_CODE (orig_for_stmt
))
14586 case OMP_FOR
: kind
= GF_OMP_FOR_KIND_FOR
; break;
14587 case OMP_SIMD
: kind
= GF_OMP_FOR_KIND_SIMD
; break;
14588 case OMP_DISTRIBUTE
: kind
= GF_OMP_FOR_KIND_DISTRIBUTE
; break;
14589 case OMP_TASKLOOP
: kind
= GF_OMP_FOR_KIND_TASKLOOP
; break;
14590 case OACC_LOOP
: kind
= GF_OMP_FOR_KIND_OACC_LOOP
; break;
14592 gcc_unreachable ();
14594 if (loop_p
&& kind
== GF_OMP_FOR_KIND_SIMD
)
14596 gimplify_seq_add_seq (pre_p
, for_pre_body
);
14597 for_pre_body
= NULL
;
14599 gfor
= gimple_build_omp_for (for_body
, kind
, OMP_FOR_CLAUSES (orig_for_stmt
),
14600 TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)),
14602 if (orig_for_stmt
!= for_stmt
)
14603 gimple_omp_for_set_combined_p (gfor
, true);
14604 if (gimplify_omp_ctxp
14605 && (gimplify_omp_ctxp
->combined_loop
14606 || (gimplify_omp_ctxp
->region_type
== ORT_COMBINED_PARALLEL
14607 && gimplify_omp_ctxp
->outer_context
14608 && gimplify_omp_ctxp
->outer_context
->combined_loop
)))
14610 gimple_omp_for_set_combined_into_p (gfor
, true);
14611 if (gimplify_omp_ctxp
->combined_loop
)
14612 gcc_assert (TREE_CODE (orig_for_stmt
) == OMP_SIMD
);
14614 gcc_assert (TREE_CODE (orig_for_stmt
) == OMP_FOR
);
14617 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
14619 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), i
);
14620 gimple_omp_for_set_index (gfor
, i
, TREE_OPERAND (t
, 0));
14621 gimple_omp_for_set_initial (gfor
, i
, TREE_OPERAND (t
, 1));
14622 t
= TREE_VEC_ELT (OMP_FOR_COND (for_stmt
), i
);
14623 gimple_omp_for_set_cond (gfor
, i
, TREE_CODE (t
));
14624 gimple_omp_for_set_final (gfor
, i
, TREE_OPERAND (t
, 1));
14625 t
= TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
);
14626 gimple_omp_for_set_incr (gfor
, i
, TREE_OPERAND (t
, 1));
14629 /* OMP_TASKLOOP is gimplified as two GIMPLE_OMP_FOR taskloop
14630 constructs with GIMPLE_OMP_TASK sandwiched in between them.
14631 The outer taskloop stands for computing the number of iterations,
14632 counts for collapsed loops and holding taskloop specific clauses.
14633 The task construct stands for the effect of data sharing on the
14634 explicit task it creates and the inner taskloop stands for expansion
14635 of the static loop inside of the explicit task construct. */
14636 if (TREE_CODE (orig_for_stmt
) == OMP_TASKLOOP
)
14638 tree
*gfor_clauses_ptr
= gimple_omp_for_clauses_ptr (gfor
);
14639 tree task_clauses
= NULL_TREE
;
14640 tree c
= *gfor_clauses_ptr
;
14641 tree
*gtask_clauses_ptr
= &task_clauses
;
14642 tree outer_for_clauses
= NULL_TREE
;
14643 tree
*gforo_clauses_ptr
= &outer_for_clauses
;
14644 bitmap lastprivate_uids
= NULL
;
14645 if (omp_find_clause (c
, OMP_CLAUSE_ALLOCATE
))
14647 c
= omp_find_clause (c
, OMP_CLAUSE_LASTPRIVATE
);
14650 lastprivate_uids
= BITMAP_ALLOC (NULL
);
14651 for (; c
; c
= omp_find_clause (OMP_CLAUSE_CHAIN (c
),
14652 OMP_CLAUSE_LASTPRIVATE
))
14653 bitmap_set_bit (lastprivate_uids
,
14654 DECL_UID (OMP_CLAUSE_DECL (c
)));
14656 c
= *gfor_clauses_ptr
;
14658 for (; c
; c
= OMP_CLAUSE_CHAIN (c
))
14659 switch (OMP_CLAUSE_CODE (c
))
14661 /* These clauses are allowed on task, move them there. */
14662 case OMP_CLAUSE_SHARED
:
14663 case OMP_CLAUSE_FIRSTPRIVATE
:
14664 case OMP_CLAUSE_DEFAULT
:
14665 case OMP_CLAUSE_IF
:
14666 case OMP_CLAUSE_UNTIED
:
14667 case OMP_CLAUSE_FINAL
:
14668 case OMP_CLAUSE_MERGEABLE
:
14669 case OMP_CLAUSE_PRIORITY
:
14670 case OMP_CLAUSE_REDUCTION
:
14671 case OMP_CLAUSE_IN_REDUCTION
:
14672 *gtask_clauses_ptr
= c
;
14673 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
14675 case OMP_CLAUSE_PRIVATE
:
14676 if (OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c
))
14678 /* We want private on outer for and firstprivate
14681 = build_omp_clause (OMP_CLAUSE_LOCATION (c
),
14682 OMP_CLAUSE_FIRSTPRIVATE
);
14683 OMP_CLAUSE_DECL (*gtask_clauses_ptr
) = OMP_CLAUSE_DECL (c
);
14684 lang_hooks
.decls
.omp_finish_clause (*gtask_clauses_ptr
, NULL
,
14686 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr
);
14687 *gforo_clauses_ptr
= c
;
14688 gforo_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
14692 *gtask_clauses_ptr
= c
;
14693 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
14696 /* These clauses go into outer taskloop clauses. */
14697 case OMP_CLAUSE_GRAINSIZE
:
14698 case OMP_CLAUSE_NUM_TASKS
:
14699 case OMP_CLAUSE_NOGROUP
:
14700 *gforo_clauses_ptr
= c
;
14701 gforo_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
14703 /* Collapse clause we duplicate on both taskloops. */
14704 case OMP_CLAUSE_COLLAPSE
:
14705 *gfor_clauses_ptr
= c
;
14706 gfor_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
14707 *gforo_clauses_ptr
= copy_node (c
);
14708 gforo_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr
);
14710 /* For lastprivate, keep the clause on inner taskloop, and add
14711 a shared clause on task. If the same decl is also firstprivate,
14712 add also firstprivate clause on the inner taskloop. */
14713 case OMP_CLAUSE_LASTPRIVATE
:
14714 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c
))
14716 /* For taskloop C++ lastprivate IVs, we want:
14717 1) private on outer taskloop
14718 2) firstprivate and shared on task
14719 3) lastprivate on inner taskloop */
14721 = build_omp_clause (OMP_CLAUSE_LOCATION (c
),
14722 OMP_CLAUSE_FIRSTPRIVATE
);
14723 OMP_CLAUSE_DECL (*gtask_clauses_ptr
) = OMP_CLAUSE_DECL (c
);
14724 lang_hooks
.decls
.omp_finish_clause (*gtask_clauses_ptr
, NULL
,
14726 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr
);
14727 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
) = 1;
14728 *gforo_clauses_ptr
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
14729 OMP_CLAUSE_PRIVATE
);
14730 OMP_CLAUSE_DECL (*gforo_clauses_ptr
) = OMP_CLAUSE_DECL (c
);
14731 OMP_CLAUSE_PRIVATE_TASKLOOP_IV (*gforo_clauses_ptr
) = 1;
14732 TREE_TYPE (*gforo_clauses_ptr
) = TREE_TYPE (c
);
14733 gforo_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr
);
14735 *gfor_clauses_ptr
= c
;
14736 gfor_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
14738 = build_omp_clause (OMP_CLAUSE_LOCATION (c
), OMP_CLAUSE_SHARED
);
14739 OMP_CLAUSE_DECL (*gtask_clauses_ptr
) = OMP_CLAUSE_DECL (c
);
14740 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
))
14741 OMP_CLAUSE_SHARED_FIRSTPRIVATE (*gtask_clauses_ptr
) = 1;
14743 = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr
);
14745 /* Allocate clause we duplicate on task and inner taskloop
14746 if the decl is lastprivate, otherwise just put on task. */
14747 case OMP_CLAUSE_ALLOCATE
:
14748 if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
)
14749 && DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
)))
14751 /* Additionally, put firstprivate clause on task
14752 for the allocator if it is not constant. */
14754 = build_omp_clause (OMP_CLAUSE_LOCATION (c
),
14755 OMP_CLAUSE_FIRSTPRIVATE
);
14756 OMP_CLAUSE_DECL (*gtask_clauses_ptr
)
14757 = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c
);
14758 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr
);
14760 if (lastprivate_uids
14761 && bitmap_bit_p (lastprivate_uids
,
14762 DECL_UID (OMP_CLAUSE_DECL (c
))))
14764 *gfor_clauses_ptr
= c
;
14765 gfor_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
14766 *gtask_clauses_ptr
= copy_node (c
);
14767 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr
);
14771 *gtask_clauses_ptr
= c
;
14772 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
14776 gcc_unreachable ();
14778 *gfor_clauses_ptr
= NULL_TREE
;
14779 *gtask_clauses_ptr
= NULL_TREE
;
14780 *gforo_clauses_ptr
= NULL_TREE
;
14781 BITMAP_FREE (lastprivate_uids
);
14782 gimple_set_location (gfor
, input_location
);
14783 g
= gimple_build_bind (NULL_TREE
, gfor
, NULL_TREE
);
14784 g
= gimple_build_omp_task (g
, task_clauses
, NULL_TREE
, NULL_TREE
,
14785 NULL_TREE
, NULL_TREE
, NULL_TREE
);
14786 gimple_set_location (g
, input_location
);
14787 gimple_omp_task_set_taskloop_p (g
, true);
14788 g
= gimple_build_bind (NULL_TREE
, g
, NULL_TREE
);
14790 = gimple_build_omp_for (g
, GF_OMP_FOR_KIND_TASKLOOP
, outer_for_clauses
,
14791 gimple_omp_for_collapse (gfor
),
14792 gimple_omp_for_pre_body (gfor
));
14793 gimple_omp_for_set_pre_body (gfor
, NULL
);
14794 gimple_omp_for_set_combined_p (gforo
, true);
14795 gimple_omp_for_set_combined_into_p (gfor
, true);
14796 for (i
= 0; i
< (int) gimple_omp_for_collapse (gfor
); i
++)
14798 tree type
= TREE_TYPE (gimple_omp_for_index (gfor
, i
));
14799 tree v
= create_tmp_var (type
);
14800 gimple_omp_for_set_index (gforo
, i
, v
);
14801 t
= unshare_expr (gimple_omp_for_initial (gfor
, i
));
14802 gimple_omp_for_set_initial (gforo
, i
, t
);
14803 gimple_omp_for_set_cond (gforo
, i
,
14804 gimple_omp_for_cond (gfor
, i
));
14805 t
= unshare_expr (gimple_omp_for_final (gfor
, i
));
14806 gimple_omp_for_set_final (gforo
, i
, t
);
14807 t
= unshare_expr (gimple_omp_for_incr (gfor
, i
));
14808 gcc_assert (TREE_OPERAND (t
, 0) == gimple_omp_for_index (gfor
, i
));
14809 TREE_OPERAND (t
, 0) = v
;
14810 gimple_omp_for_set_incr (gforo
, i
, t
);
14811 t
= build_omp_clause (input_location
, OMP_CLAUSE_PRIVATE
);
14812 OMP_CLAUSE_DECL (t
) = v
;
14813 OMP_CLAUSE_CHAIN (t
) = gimple_omp_for_clauses (gforo
);
14814 gimple_omp_for_set_clauses (gforo
, t
);
14815 if (OMP_FOR_NON_RECTANGULAR (for_stmt
))
14817 tree
*p1
= NULL
, *p2
= NULL
;
14818 t
= gimple_omp_for_initial (gforo
, i
);
14819 if (TREE_CODE (t
) == TREE_VEC
)
14820 p1
= &TREE_VEC_ELT (t
, 0);
14821 t
= gimple_omp_for_final (gforo
, i
);
14822 if (TREE_CODE (t
) == TREE_VEC
)
14825 p2
= &TREE_VEC_ELT (t
, 0);
14827 p1
= &TREE_VEC_ELT (t
, 0);
14832 for (j
= 0; j
< i
; j
++)
14833 if (*p1
== gimple_omp_for_index (gfor
, j
))
14835 *p1
= gimple_omp_for_index (gforo
, j
);
14840 gcc_assert (j
< i
);
14844 gimplify_seq_add_stmt (pre_p
, gforo
);
14847 gimplify_seq_add_stmt (pre_p
, gfor
);
14849 if (TREE_CODE (orig_for_stmt
) == OMP_FOR
)
14851 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
14852 unsigned lastprivate_conditional
= 0;
14854 && (ctx
->region_type
== ORT_TARGET_DATA
14855 || ctx
->region_type
== ORT_TASKGROUP
))
14856 ctx
= ctx
->outer_context
;
14857 if (ctx
&& (ctx
->region_type
& ORT_PARALLEL
) != 0)
14858 for (tree c
= gimple_omp_for_clauses (gfor
);
14859 c
; c
= OMP_CLAUSE_CHAIN (c
))
14860 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
14861 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
))
14862 ++lastprivate_conditional
;
14863 if (lastprivate_conditional
)
14865 struct omp_for_data fd
;
14866 omp_extract_for_data (gfor
, &fd
, NULL
);
14867 tree type
= build_array_type_nelts (unsigned_type_for (fd
.iter_type
),
14868 lastprivate_conditional
);
14869 tree var
= create_tmp_var_raw (type
);
14870 tree c
= build_omp_clause (UNKNOWN_LOCATION
, OMP_CLAUSE__CONDTEMP_
);
14871 OMP_CLAUSE_DECL (c
) = var
;
14872 OMP_CLAUSE_CHAIN (c
) = gimple_omp_for_clauses (gfor
);
14873 gimple_omp_for_set_clauses (gfor
, c
);
14874 omp_add_variable (ctx
, var
, GOVD_CONDTEMP
| GOVD_SEEN
);
14877 else if (TREE_CODE (orig_for_stmt
) == OMP_SIMD
)
14879 unsigned lastprivate_conditional
= 0;
14880 for (tree c
= gimple_omp_for_clauses (gfor
); c
; c
= OMP_CLAUSE_CHAIN (c
))
14881 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
14882 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
))
14883 ++lastprivate_conditional
;
14884 if (lastprivate_conditional
)
14886 struct omp_for_data fd
;
14887 omp_extract_for_data (gfor
, &fd
, NULL
);
14888 tree type
= unsigned_type_for (fd
.iter_type
);
14889 while (lastprivate_conditional
--)
14891 tree c
= build_omp_clause (UNKNOWN_LOCATION
,
14892 OMP_CLAUSE__CONDTEMP_
);
14893 OMP_CLAUSE_DECL (c
) = create_tmp_var (type
);
14894 OMP_CLAUSE_CHAIN (c
) = gimple_omp_for_clauses (gfor
);
14895 gimple_omp_for_set_clauses (gfor
, c
);
14900 if (ret
!= GS_ALL_DONE
)
14902 *expr_p
= NULL_TREE
;
14903 return GS_ALL_DONE
;
14906 /* Helper for gimplify_omp_loop, called through walk_tree. */
14909 note_no_context_vars (tree
*tp
, int *, void *data
)
14912 && DECL_CONTEXT (*tp
) == NULL_TREE
14913 && !is_global_var (*tp
))
14915 vec
<tree
> *d
= (vec
<tree
> *) data
;
14916 d
->safe_push (*tp
);
14917 DECL_CONTEXT (*tp
) = current_function_decl
;
14922 /* Gimplify the gross structure of an OMP_LOOP statement. */
14924 static enum gimplify_status
14925 gimplify_omp_loop (tree
*expr_p
, gimple_seq
*pre_p
)
14927 tree for_stmt
= *expr_p
;
14928 tree clauses
= OMP_FOR_CLAUSES (for_stmt
);
14929 struct gimplify_omp_ctx
*octx
= gimplify_omp_ctxp
;
14930 enum omp_clause_bind_kind kind
= OMP_CLAUSE_BIND_THREAD
;
14933 /* If order is not present, the behavior is as if order(concurrent)
14935 tree order
= omp_find_clause (clauses
, OMP_CLAUSE_ORDER
);
14936 if (order
== NULL_TREE
)
14938 order
= build_omp_clause (UNKNOWN_LOCATION
, OMP_CLAUSE_ORDER
);
14939 OMP_CLAUSE_CHAIN (order
) = clauses
;
14940 OMP_FOR_CLAUSES (for_stmt
) = clauses
= order
;
14943 tree bind
= omp_find_clause (clauses
, OMP_CLAUSE_BIND
);
14944 if (bind
== NULL_TREE
)
14946 if (!flag_openmp
) /* flag_openmp_simd */
14948 else if (octx
&& (octx
->region_type
& ORT_TEAMS
) != 0)
14949 kind
= OMP_CLAUSE_BIND_TEAMS
;
14950 else if (octx
&& (octx
->region_type
& ORT_PARALLEL
) != 0)
14951 kind
= OMP_CLAUSE_BIND_PARALLEL
;
14954 for (; octx
; octx
= octx
->outer_context
)
14956 if ((octx
->region_type
& ORT_ACC
) != 0
14957 || octx
->region_type
== ORT_NONE
14958 || octx
->region_type
== ORT_IMPLICIT_TARGET
)
14962 if (octx
== NULL
&& !in_omp_construct
)
14963 error_at (EXPR_LOCATION (for_stmt
),
14964 "%<bind%> clause not specified on a %<loop%> "
14965 "construct not nested inside another OpenMP construct");
14967 bind
= build_omp_clause (UNKNOWN_LOCATION
, OMP_CLAUSE_BIND
);
14968 OMP_CLAUSE_CHAIN (bind
) = clauses
;
14969 OMP_CLAUSE_BIND_KIND (bind
) = kind
;
14970 OMP_FOR_CLAUSES (for_stmt
) = bind
;
14973 switch (OMP_CLAUSE_BIND_KIND (bind
))
14975 case OMP_CLAUSE_BIND_THREAD
:
14977 case OMP_CLAUSE_BIND_PARALLEL
:
14978 if (!flag_openmp
) /* flag_openmp_simd */
14980 OMP_CLAUSE_BIND_KIND (bind
) = OMP_CLAUSE_BIND_THREAD
;
14983 for (; octx
; octx
= octx
->outer_context
)
14984 if (octx
->region_type
== ORT_SIMD
14985 && omp_find_clause (octx
->clauses
, OMP_CLAUSE_BIND
) == NULL_TREE
)
14987 error_at (EXPR_LOCATION (for_stmt
),
14988 "%<bind(parallel)%> on a %<loop%> construct nested "
14989 "inside %<simd%> construct");
14990 OMP_CLAUSE_BIND_KIND (bind
) = OMP_CLAUSE_BIND_THREAD
;
14993 kind
= OMP_CLAUSE_BIND_PARALLEL
;
14995 case OMP_CLAUSE_BIND_TEAMS
:
14996 if (!flag_openmp
) /* flag_openmp_simd */
14998 OMP_CLAUSE_BIND_KIND (bind
) = OMP_CLAUSE_BIND_THREAD
;
15002 && octx
->region_type
!= ORT_IMPLICIT_TARGET
15003 && octx
->region_type
!= ORT_NONE
15004 && (octx
->region_type
& ORT_TEAMS
) == 0)
15005 || in_omp_construct
)
15007 error_at (EXPR_LOCATION (for_stmt
),
15008 "%<bind(teams)%> on a %<loop%> region not strictly "
15009 "nested inside of a %<teams%> region");
15010 OMP_CLAUSE_BIND_KIND (bind
) = OMP_CLAUSE_BIND_THREAD
;
15013 kind
= OMP_CLAUSE_BIND_TEAMS
;
15016 gcc_unreachable ();
15019 for (tree
*pc
= &OMP_FOR_CLAUSES (for_stmt
); *pc
; )
15020 switch (OMP_CLAUSE_CODE (*pc
))
15022 case OMP_CLAUSE_REDUCTION
:
15023 if (OMP_CLAUSE_REDUCTION_INSCAN (*pc
))
15025 error_at (OMP_CLAUSE_LOCATION (*pc
),
15026 "%<inscan%> %<reduction%> clause on "
15027 "%qs construct", "loop");
15028 OMP_CLAUSE_REDUCTION_INSCAN (*pc
) = 0;
15030 if (OMP_CLAUSE_REDUCTION_TASK (*pc
))
15032 error_at (OMP_CLAUSE_LOCATION (*pc
),
15033 "invalid %<task%> reduction modifier on construct "
15034 "other than %<parallel%>, %qs or %<sections%>",
15035 lang_GNU_Fortran () ? "do" : "for");
15036 OMP_CLAUSE_REDUCTION_TASK (*pc
) = 0;
15038 pc
= &OMP_CLAUSE_CHAIN (*pc
);
15040 case OMP_CLAUSE_LASTPRIVATE
:
15041 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
15043 tree t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), i
);
15044 gcc_assert (TREE_CODE (t
) == MODIFY_EXPR
);
15045 if (OMP_CLAUSE_DECL (*pc
) == TREE_OPERAND (t
, 0))
15047 if (OMP_FOR_ORIG_DECLS (for_stmt
)
15048 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
),
15050 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
),
15053 tree orig
= TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
), i
);
15054 if (OMP_CLAUSE_DECL (*pc
) == TREE_PURPOSE (orig
))
15058 if (i
== TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)))
15060 error_at (OMP_CLAUSE_LOCATION (*pc
),
15061 "%<lastprivate%> clause on a %<loop%> construct refers "
15062 "to a variable %qD which is not the loop iterator",
15063 OMP_CLAUSE_DECL (*pc
));
15064 *pc
= OMP_CLAUSE_CHAIN (*pc
);
15067 pc
= &OMP_CLAUSE_CHAIN (*pc
);
15070 pc
= &OMP_CLAUSE_CHAIN (*pc
);
15074 TREE_SET_CODE (for_stmt
, OMP_SIMD
);
15079 case OMP_CLAUSE_BIND_THREAD
: last
= 0; break;
15080 case OMP_CLAUSE_BIND_PARALLEL
: last
= 1; break;
15081 case OMP_CLAUSE_BIND_TEAMS
: last
= 2; break;
15083 for (int pass
= 1; pass
<= last
; pass
++)
15087 tree bind
= build3 (BIND_EXPR
, void_type_node
, NULL
, NULL
,
15088 make_node (BLOCK
));
15089 append_to_statement_list (*expr_p
, &BIND_EXPR_BODY (bind
));
15090 *expr_p
= make_node (OMP_PARALLEL
);
15091 TREE_TYPE (*expr_p
) = void_type_node
;
15092 OMP_PARALLEL_BODY (*expr_p
) = bind
;
15093 OMP_PARALLEL_COMBINED (*expr_p
) = 1;
15094 SET_EXPR_LOCATION (*expr_p
, EXPR_LOCATION (for_stmt
));
15095 tree
*pc
= &OMP_PARALLEL_CLAUSES (*expr_p
);
15096 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
15097 if (OMP_FOR_ORIG_DECLS (for_stmt
)
15098 && (TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
), i
))
15101 tree elt
= TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
), i
);
15102 if (TREE_PURPOSE (elt
) && TREE_VALUE (elt
))
15104 *pc
= build_omp_clause (UNKNOWN_LOCATION
,
15105 OMP_CLAUSE_FIRSTPRIVATE
);
15106 OMP_CLAUSE_DECL (*pc
) = TREE_VALUE (elt
);
15107 pc
= &OMP_CLAUSE_CHAIN (*pc
);
15111 tree t
= make_node (pass
== 2 ? OMP_DISTRIBUTE
: OMP_FOR
);
15112 tree
*pc
= &OMP_FOR_CLAUSES (t
);
15113 TREE_TYPE (t
) = void_type_node
;
15114 OMP_FOR_BODY (t
) = *expr_p
;
15115 SET_EXPR_LOCATION (t
, EXPR_LOCATION (for_stmt
));
15116 for (tree c
= OMP_FOR_CLAUSES (for_stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
15117 switch (OMP_CLAUSE_CODE (c
))
15119 case OMP_CLAUSE_BIND
:
15120 case OMP_CLAUSE_ORDER
:
15121 case OMP_CLAUSE_COLLAPSE
:
15122 *pc
= copy_node (c
);
15123 pc
= &OMP_CLAUSE_CHAIN (*pc
);
15125 case OMP_CLAUSE_PRIVATE
:
15126 case OMP_CLAUSE_FIRSTPRIVATE
:
15127 /* Only needed on innermost. */
15129 case OMP_CLAUSE_LASTPRIVATE
:
15130 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c
) && pass
!= last
)
15132 *pc
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
15133 OMP_CLAUSE_FIRSTPRIVATE
);
15134 OMP_CLAUSE_DECL (*pc
) = OMP_CLAUSE_DECL (c
);
15135 lang_hooks
.decls
.omp_finish_clause (*pc
, NULL
, false);
15136 pc
= &OMP_CLAUSE_CHAIN (*pc
);
15138 *pc
= copy_node (c
);
15139 OMP_CLAUSE_LASTPRIVATE_STMT (*pc
) = NULL_TREE
;
15140 TREE_TYPE (*pc
) = unshare_expr (TREE_TYPE (c
));
15141 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c
))
15144 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (*pc
) = 1;
15146 lang_hooks
.decls
.omp_finish_clause (*pc
, NULL
, false);
15147 OMP_CLAUSE_LASTPRIVATE_LOOP_IV (*pc
) = 0;
15149 pc
= &OMP_CLAUSE_CHAIN (*pc
);
15151 case OMP_CLAUSE_REDUCTION
:
15152 *pc
= copy_node (c
);
15153 OMP_CLAUSE_DECL (*pc
) = unshare_expr (OMP_CLAUSE_DECL (c
));
15154 TREE_TYPE (*pc
) = unshare_expr (TREE_TYPE (c
));
15155 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc
))
15157 auto_vec
<tree
> no_context_vars
;
15158 int walk_subtrees
= 0;
15159 note_no_context_vars (&OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
),
15160 &walk_subtrees
, &no_context_vars
);
15161 if (tree p
= OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c
))
15162 note_no_context_vars (&p
, &walk_subtrees
, &no_context_vars
);
15163 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_INIT (c
),
15164 note_no_context_vars
,
15166 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_MERGE (c
),
15167 note_no_context_vars
,
15170 OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc
)
15171 = copy_node (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
));
15172 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc
))
15173 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc
)
15174 = copy_node (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c
));
15176 hash_map
<tree
, tree
> decl_map
;
15177 decl_map
.put (OMP_CLAUSE_DECL (c
), OMP_CLAUSE_DECL (c
));
15178 decl_map
.put (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
),
15179 OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc
));
15180 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc
))
15181 decl_map
.put (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c
),
15182 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc
));
15185 memset (&id
, 0, sizeof (id
));
15186 id
.src_fn
= current_function_decl
;
15187 id
.dst_fn
= current_function_decl
;
15188 id
.src_cfun
= cfun
;
15189 id
.decl_map
= &decl_map
;
15190 id
.copy_decl
= copy_decl_no_change
;
15191 id
.transform_call_graph_edges
= CB_CGE_DUPLICATE
;
15192 id
.transform_new_cfg
= true;
15193 id
.transform_return_to_modify
= false;
15195 walk_tree (&OMP_CLAUSE_REDUCTION_INIT (*pc
), copy_tree_body_r
,
15197 walk_tree (&OMP_CLAUSE_REDUCTION_MERGE (*pc
), copy_tree_body_r
,
15200 for (tree d
: no_context_vars
)
15202 DECL_CONTEXT (d
) = NULL_TREE
;
15203 DECL_CONTEXT (*decl_map
.get (d
)) = NULL_TREE
;
15208 OMP_CLAUSE_REDUCTION_INIT (*pc
)
15209 = unshare_expr (OMP_CLAUSE_REDUCTION_INIT (c
));
15210 OMP_CLAUSE_REDUCTION_MERGE (*pc
)
15211 = unshare_expr (OMP_CLAUSE_REDUCTION_MERGE (c
));
15213 pc
= &OMP_CLAUSE_CHAIN (*pc
);
15216 gcc_unreachable ();
15221 return gimplify_expr (expr_p
, pre_p
, NULL
, is_gimple_stmt
, fb_none
);
15225 /* Helper function of optimize_target_teams, find OMP_TEAMS inside
15226 of OMP_TARGET's body. */
15229 find_omp_teams (tree
*tp
, int *walk_subtrees
, void *)
15231 *walk_subtrees
= 0;
15232 switch (TREE_CODE (*tp
))
15237 case STATEMENT_LIST
:
15238 *walk_subtrees
= 1;
15246 /* Helper function of optimize_target_teams, determine if the expression
15247 can be computed safely before the target construct on the host. */
15250 computable_teams_clause (tree
*tp
, int *walk_subtrees
, void *)
15256 *walk_subtrees
= 0;
15259 switch (TREE_CODE (*tp
))
15264 *walk_subtrees
= 0;
15265 if (error_operand_p (*tp
)
15266 || !INTEGRAL_TYPE_P (TREE_TYPE (*tp
))
15267 || DECL_HAS_VALUE_EXPR_P (*tp
)
15268 || DECL_THREAD_LOCAL_P (*tp
)
15269 || TREE_SIDE_EFFECTS (*tp
)
15270 || TREE_THIS_VOLATILE (*tp
))
15272 if (is_global_var (*tp
)
15273 && (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (*tp
))
15274 || lookup_attribute ("omp declare target link",
15275 DECL_ATTRIBUTES (*tp
))))
15278 && !DECL_SEEN_IN_BIND_EXPR_P (*tp
)
15279 && !is_global_var (*tp
)
15280 && decl_function_context (*tp
) == current_function_decl
)
15282 n
= splay_tree_lookup (gimplify_omp_ctxp
->variables
,
15283 (splay_tree_key
) *tp
);
15286 if (gimplify_omp_ctxp
->defaultmap
[GDMK_SCALAR
] & GOVD_FIRSTPRIVATE
)
15290 else if (n
->value
& GOVD_LOCAL
)
15292 else if (n
->value
& GOVD_FIRSTPRIVATE
)
15294 else if ((n
->value
& (GOVD_MAP
| GOVD_MAP_ALWAYS_TO
))
15295 == (GOVD_MAP
| GOVD_MAP_ALWAYS_TO
))
15299 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp
)))
15303 if (TARGET_EXPR_INITIAL (*tp
)
15304 || TREE_CODE (TARGET_EXPR_SLOT (*tp
)) != VAR_DECL
)
15306 return computable_teams_clause (&TARGET_EXPR_SLOT (*tp
),
15307 walk_subtrees
, NULL
);
15308 /* Allow some reasonable subset of integral arithmetics. */
15312 case TRUNC_DIV_EXPR
:
15313 case CEIL_DIV_EXPR
:
15314 case FLOOR_DIV_EXPR
:
15315 case ROUND_DIV_EXPR
:
15316 case TRUNC_MOD_EXPR
:
15317 case CEIL_MOD_EXPR
:
15318 case FLOOR_MOD_EXPR
:
15319 case ROUND_MOD_EXPR
:
15321 case EXACT_DIV_EXPR
:
15332 case NON_LVALUE_EXPR
:
15334 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp
)))
15337 /* And disallow anything else, except for comparisons. */
15339 if (COMPARISON_CLASS_P (*tp
))
15345 /* Try to determine if the num_teams and/or thread_limit expressions
15346 can have their values determined already before entering the
15348 INTEGER_CSTs trivially are,
15349 integral decls that are firstprivate (explicitly or implicitly)
15350 or explicitly map(always, to:) or map(always, tofrom:) on the target
15351 region too, and expressions involving simple arithmetics on those
15352 too, function calls are not ok, dereferencing something neither etc.
15353 Add NUM_TEAMS and THREAD_LIMIT clauses to the OMP_CLAUSES of
15354 EXPR based on what we find:
15355 0 stands for clause not specified at all, use implementation default
15356 -1 stands for value that can't be determined easily before entering
15357 the target construct.
15358 -2 means that no explicit teams construct was specified
15359 If teams construct is not present at all, use 1 for num_teams
15360 and 0 for thread_limit (only one team is involved, and the thread
15361 limit is implementation defined. */
15364 optimize_target_teams (tree target
, gimple_seq
*pre_p
)
15366 tree body
= OMP_BODY (target
);
15367 tree teams
= walk_tree (&body
, find_omp_teams
, NULL
, NULL
);
15368 tree num_teams_lower
= NULL_TREE
;
15369 tree num_teams_upper
= integer_zero_node
;
15370 tree thread_limit
= integer_zero_node
;
15371 location_t num_teams_loc
= EXPR_LOCATION (target
);
15372 location_t thread_limit_loc
= EXPR_LOCATION (target
);
15374 struct gimplify_omp_ctx
*target_ctx
= gimplify_omp_ctxp
;
15376 if (teams
== NULL_TREE
)
15377 num_teams_upper
= build_int_cst (integer_type_node
, -2);
15379 for (c
= OMP_TEAMS_CLAUSES (teams
); c
; c
= OMP_CLAUSE_CHAIN (c
))
15381 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_NUM_TEAMS
)
15383 p
= &num_teams_upper
;
15384 num_teams_loc
= OMP_CLAUSE_LOCATION (c
);
15385 if (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c
))
15387 expr
= OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c
);
15388 if (TREE_CODE (expr
) == INTEGER_CST
)
15389 num_teams_lower
= expr
;
15390 else if (walk_tree (&expr
, computable_teams_clause
,
15392 num_teams_lower
= integer_minus_one_node
;
15395 num_teams_lower
= expr
;
15396 gimplify_omp_ctxp
= gimplify_omp_ctxp
->outer_context
;
15397 if (gimplify_expr (&num_teams_lower
, pre_p
, NULL
,
15398 is_gimple_val
, fb_rvalue
, false)
15401 gimplify_omp_ctxp
= target_ctx
;
15402 num_teams_lower
= integer_minus_one_node
;
15406 gimplify_omp_ctxp
= target_ctx
;
15407 if (!DECL_P (expr
) && TREE_CODE (expr
) != TARGET_EXPR
)
15408 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c
)
15414 else if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_THREAD_LIMIT
)
15417 thread_limit_loc
= OMP_CLAUSE_LOCATION (c
);
15421 expr
= OMP_CLAUSE_OPERAND (c
, 0);
15422 if (TREE_CODE (expr
) == INTEGER_CST
)
15427 if (walk_tree (&expr
, computable_teams_clause
, NULL
, NULL
))
15429 *p
= integer_minus_one_node
;
15433 gimplify_omp_ctxp
= gimplify_omp_ctxp
->outer_context
;
15434 if (gimplify_expr (p
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
, false)
15437 gimplify_omp_ctxp
= target_ctx
;
15438 *p
= integer_minus_one_node
;
15441 gimplify_omp_ctxp
= target_ctx
;
15442 if (!DECL_P (expr
) && TREE_CODE (expr
) != TARGET_EXPR
)
15443 OMP_CLAUSE_OPERAND (c
, 0) = *p
;
15445 if (!omp_find_clause (OMP_TARGET_CLAUSES (target
), OMP_CLAUSE_THREAD_LIMIT
))
15447 c
= build_omp_clause (thread_limit_loc
, OMP_CLAUSE_THREAD_LIMIT
);
15448 OMP_CLAUSE_THREAD_LIMIT_EXPR (c
) = thread_limit
;
15449 OMP_CLAUSE_CHAIN (c
) = OMP_TARGET_CLAUSES (target
);
15450 OMP_TARGET_CLAUSES (target
) = c
;
15452 c
= build_omp_clause (num_teams_loc
, OMP_CLAUSE_NUM_TEAMS
);
15453 OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c
) = num_teams_upper
;
15454 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c
) = num_teams_lower
;
15455 OMP_CLAUSE_CHAIN (c
) = OMP_TARGET_CLAUSES (target
);
15456 OMP_TARGET_CLAUSES (target
) = c
;
15459 /* Gimplify the gross structure of several OMP constructs. */
15462 gimplify_omp_workshare (tree
*expr_p
, gimple_seq
*pre_p
)
15464 tree expr
= *expr_p
;
15466 gimple_seq body
= NULL
;
15467 enum omp_region_type ort
;
15469 switch (TREE_CODE (expr
))
15473 ort
= ORT_WORKSHARE
;
15476 ort
= ORT_TASKGROUP
;
15479 ort
= OMP_TARGET_COMBINED (expr
) ? ORT_COMBINED_TARGET
: ORT_TARGET
;
15482 ort
= ORT_ACC_KERNELS
;
15484 case OACC_PARALLEL
:
15485 ort
= ORT_ACC_PARALLEL
;
15488 ort
= ORT_ACC_SERIAL
;
15491 ort
= ORT_ACC_DATA
;
15493 case OMP_TARGET_DATA
:
15494 ort
= ORT_TARGET_DATA
;
15497 ort
= OMP_TEAMS_COMBINED (expr
) ? ORT_COMBINED_TEAMS
: ORT_TEAMS
;
15498 if (gimplify_omp_ctxp
== NULL
15499 || gimplify_omp_ctxp
->region_type
== ORT_IMPLICIT_TARGET
)
15500 ort
= (enum omp_region_type
) (ort
| ORT_HOST_TEAMS
);
15502 case OACC_HOST_DATA
:
15503 ort
= ORT_ACC_HOST_DATA
;
15506 gcc_unreachable ();
15509 bool save_in_omp_construct
= in_omp_construct
;
15510 if ((ort
& ORT_ACC
) == 0)
15511 in_omp_construct
= false;
15512 gimplify_scan_omp_clauses (&OMP_CLAUSES (expr
), pre_p
, ort
,
15514 if (TREE_CODE (expr
) == OMP_TARGET
)
15515 optimize_target_teams (expr
, pre_p
);
15516 if ((ort
& (ORT_TARGET
| ORT_TARGET_DATA
)) != 0
15517 || (ort
& ORT_HOST_TEAMS
) == ORT_HOST_TEAMS
)
15519 push_gimplify_context ();
15520 gimple
*g
= gimplify_and_return_first (OMP_BODY (expr
), &body
);
15521 if (gimple_code (g
) == GIMPLE_BIND
)
15522 pop_gimplify_context (g
);
15524 pop_gimplify_context (NULL
);
15525 if ((ort
& ORT_TARGET_DATA
) != 0)
15527 enum built_in_function end_ix
;
15528 switch (TREE_CODE (expr
))
15531 case OACC_HOST_DATA
:
15532 end_ix
= BUILT_IN_GOACC_DATA_END
;
15534 case OMP_TARGET_DATA
:
15535 end_ix
= BUILT_IN_GOMP_TARGET_END_DATA
;
15538 gcc_unreachable ();
15540 tree fn
= builtin_decl_explicit (end_ix
);
15541 g
= gimple_build_call (fn
, 0);
15542 gimple_seq cleanup
= NULL
;
15543 gimple_seq_add_stmt (&cleanup
, g
);
15544 g
= gimple_build_try (body
, cleanup
, GIMPLE_TRY_FINALLY
);
15546 gimple_seq_add_stmt (&body
, g
);
15550 gimplify_and_add (OMP_BODY (expr
), &body
);
15551 gimplify_adjust_omp_clauses (pre_p
, body
, &OMP_CLAUSES (expr
),
15553 in_omp_construct
= save_in_omp_construct
;
15555 switch (TREE_CODE (expr
))
15558 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_OACC_DATA
,
15559 OMP_CLAUSES (expr
));
15561 case OACC_HOST_DATA
:
15562 if (omp_find_clause (OMP_CLAUSES (expr
), OMP_CLAUSE_IF_PRESENT
))
15564 for (tree c
= OMP_CLAUSES (expr
); c
; c
= OMP_CLAUSE_CHAIN (c
))
15565 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_USE_DEVICE_PTR
)
15566 OMP_CLAUSE_USE_DEVICE_PTR_IF_PRESENT (c
) = 1;
15569 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_OACC_HOST_DATA
,
15570 OMP_CLAUSES (expr
));
15573 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_OACC_KERNELS
,
15574 OMP_CLAUSES (expr
));
15576 case OACC_PARALLEL
:
15577 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_OACC_PARALLEL
,
15578 OMP_CLAUSES (expr
));
15581 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_OACC_SERIAL
,
15582 OMP_CLAUSES (expr
));
15585 stmt
= gimple_build_omp_sections (body
, OMP_CLAUSES (expr
));
15588 stmt
= gimple_build_omp_single (body
, OMP_CLAUSES (expr
));
15591 stmt
= gimple_build_omp_scope (body
, OMP_CLAUSES (expr
));
15594 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_REGION
,
15595 OMP_CLAUSES (expr
));
15597 case OMP_TARGET_DATA
:
15598 /* Put use_device_{ptr,addr} clauses last, as map clauses are supposed
15599 to be evaluated before the use_device_{ptr,addr} clauses if they
15600 refer to the same variables. */
15602 tree use_device_clauses
;
15603 tree
*pc
, *uc
= &use_device_clauses
;
15604 for (pc
= &OMP_CLAUSES (expr
); *pc
; )
15605 if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_USE_DEVICE_PTR
15606 || OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_USE_DEVICE_ADDR
)
15609 *pc
= OMP_CLAUSE_CHAIN (*pc
);
15610 uc
= &OMP_CLAUSE_CHAIN (*uc
);
15613 pc
= &OMP_CLAUSE_CHAIN (*pc
);
15615 *pc
= use_device_clauses
;
15616 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_DATA
,
15617 OMP_CLAUSES (expr
));
15621 stmt
= gimple_build_omp_teams (body
, OMP_CLAUSES (expr
));
15622 if ((ort
& ORT_HOST_TEAMS
) == ORT_HOST_TEAMS
)
15623 gimple_omp_teams_set_host (as_a
<gomp_teams
*> (stmt
), true);
15626 gcc_unreachable ();
15629 gimplify_seq_add_stmt (pre_p
, stmt
);
15630 *expr_p
= NULL_TREE
;
15633 /* Gimplify the gross structure of OpenACC enter/exit data, update, and OpenMP
15634 target update constructs. */
15637 gimplify_omp_target_update (tree
*expr_p
, gimple_seq
*pre_p
)
15639 tree expr
= *expr_p
;
15642 enum omp_region_type ort
= ORT_WORKSHARE
;
15644 switch (TREE_CODE (expr
))
15646 case OACC_ENTER_DATA
:
15647 kind
= GF_OMP_TARGET_KIND_OACC_ENTER_DATA
;
15650 case OACC_EXIT_DATA
:
15651 kind
= GF_OMP_TARGET_KIND_OACC_EXIT_DATA
;
15655 kind
= GF_OMP_TARGET_KIND_OACC_UPDATE
;
15658 case OMP_TARGET_UPDATE
:
15659 kind
= GF_OMP_TARGET_KIND_UPDATE
;
15661 case OMP_TARGET_ENTER_DATA
:
15662 kind
= GF_OMP_TARGET_KIND_ENTER_DATA
;
15664 case OMP_TARGET_EXIT_DATA
:
15665 kind
= GF_OMP_TARGET_KIND_EXIT_DATA
;
15668 gcc_unreachable ();
15670 gimplify_scan_omp_clauses (&OMP_STANDALONE_CLAUSES (expr
), pre_p
,
15671 ort
, TREE_CODE (expr
));
15672 gimplify_adjust_omp_clauses (pre_p
, NULL
, &OMP_STANDALONE_CLAUSES (expr
),
15674 if (TREE_CODE (expr
) == OACC_UPDATE
15675 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr
),
15676 OMP_CLAUSE_IF_PRESENT
))
15678 /* The runtime uses GOMP_MAP_{TO,FROM} to denote the if_present
15680 for (tree c
= OMP_STANDALONE_CLAUSES (expr
); c
; c
= OMP_CLAUSE_CHAIN (c
))
15681 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_MAP
)
15682 switch (OMP_CLAUSE_MAP_KIND (c
))
15684 case GOMP_MAP_FORCE_TO
:
15685 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_TO
);
15687 case GOMP_MAP_FORCE_FROM
:
15688 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_FROM
);
15694 else if (TREE_CODE (expr
) == OACC_EXIT_DATA
15695 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr
),
15696 OMP_CLAUSE_FINALIZE
))
15698 /* Use GOMP_MAP_DELETE/GOMP_MAP_FORCE_FROM to denote "finalize"
15700 bool have_clause
= false;
15701 for (tree c
= OMP_STANDALONE_CLAUSES (expr
); c
; c
= OMP_CLAUSE_CHAIN (c
))
15702 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_MAP
)
15703 switch (OMP_CLAUSE_MAP_KIND (c
))
15705 case GOMP_MAP_FROM
:
15706 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_FORCE_FROM
);
15707 have_clause
= true;
15709 case GOMP_MAP_RELEASE
:
15710 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_DELETE
);
15711 have_clause
= true;
15713 case GOMP_MAP_TO_PSET
:
15714 /* Fortran arrays with descriptors must map that descriptor when
15715 doing standalone "attach" operations (in OpenACC). In that
15716 case GOMP_MAP_TO_PSET appears by itself with no preceding
15717 clause (see trans-openmp.cc:gfc_trans_omp_clauses). */
15719 case GOMP_MAP_POINTER
:
15720 /* TODO PR92929: we may see these here, but they'll always follow
15721 one of the clauses above, and will be handled by libgomp as
15722 one group, so no handling required here. */
15723 gcc_assert (have_clause
);
15725 case GOMP_MAP_DETACH
:
15726 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_FORCE_DETACH
);
15727 have_clause
= false;
15729 case GOMP_MAP_STRUCT
:
15730 have_clause
= false;
15733 gcc_unreachable ();
15736 stmt
= gimple_build_omp_target (NULL
, kind
, OMP_STANDALONE_CLAUSES (expr
));
15738 gimplify_seq_add_stmt (pre_p
, stmt
);
15739 *expr_p
= NULL_TREE
;
15742 /* A subroutine of gimplify_omp_atomic. The front end is supposed to have
15743 stabilized the lhs of the atomic operation as *ADDR. Return true if
15744 EXPR is this stabilized form. */
15747 goa_lhs_expr_p (tree expr
, tree addr
)
15749 /* Also include casts to other type variants. The C front end is fond
15750 of adding these for e.g. volatile variables. This is like
15751 STRIP_TYPE_NOPS but includes the main variant lookup. */
15752 STRIP_USELESS_TYPE_CONVERSION (expr
);
15754 if (INDIRECT_REF_P (expr
))
15756 expr
= TREE_OPERAND (expr
, 0);
15757 while (expr
!= addr
15758 && (CONVERT_EXPR_P (expr
)
15759 || TREE_CODE (expr
) == NON_LVALUE_EXPR
)
15760 && TREE_CODE (expr
) == TREE_CODE (addr
)
15761 && types_compatible_p (TREE_TYPE (expr
), TREE_TYPE (addr
)))
15763 expr
= TREE_OPERAND (expr
, 0);
15764 addr
= TREE_OPERAND (addr
, 0);
15768 return (TREE_CODE (addr
) == ADDR_EXPR
15769 && TREE_CODE (expr
) == ADDR_EXPR
15770 && TREE_OPERAND (addr
, 0) == TREE_OPERAND (expr
, 0));
15772 if (TREE_CODE (addr
) == ADDR_EXPR
&& expr
== TREE_OPERAND (addr
, 0))
15777 /* Walk *EXPR_P and replace appearances of *LHS_ADDR with LHS_VAR. If an
15778 expression does not involve the lhs, evaluate it into a temporary.
15779 Return 1 if the lhs appeared as a subexpression, 0 if it did not,
15780 or -1 if an error was encountered. */
15783 goa_stabilize_expr (tree
*expr_p
, gimple_seq
*pre_p
, tree lhs_addr
,
15784 tree lhs_var
, tree
&target_expr
, bool rhs
, int depth
)
15786 tree expr
= *expr_p
;
15789 if (goa_lhs_expr_p (expr
, lhs_addr
))
15795 if (is_gimple_val (expr
))
15798 /* Maximum depth of lhs in expression is for the
15799 __builtin_clear_padding (...), __builtin_clear_padding (...),
15800 __builtin_memcmp (&TARGET_EXPR <lhs, >, ...) == 0 ? ... : lhs; */
15804 switch (TREE_CODE_CLASS (TREE_CODE (expr
)))
15807 case tcc_comparison
:
15808 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 1), pre_p
, lhs_addr
,
15809 lhs_var
, target_expr
, true, depth
);
15812 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 0), pre_p
, lhs_addr
,
15813 lhs_var
, target_expr
, true, depth
);
15815 case tcc_expression
:
15816 switch (TREE_CODE (expr
))
15818 case TRUTH_ANDIF_EXPR
:
15819 case TRUTH_ORIF_EXPR
:
15820 case TRUTH_AND_EXPR
:
15821 case TRUTH_OR_EXPR
:
15822 case TRUTH_XOR_EXPR
:
15823 case BIT_INSERT_EXPR
:
15824 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 1), pre_p
,
15825 lhs_addr
, lhs_var
, target_expr
, true,
15828 case TRUTH_NOT_EXPR
:
15829 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 0), pre_p
,
15830 lhs_addr
, lhs_var
, target_expr
, true,
15834 if (pre_p
&& !goa_stabilize_expr (expr_p
, NULL
, lhs_addr
, lhs_var
,
15835 target_expr
, true, depth
))
15837 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 1), pre_p
,
15838 lhs_addr
, lhs_var
, target_expr
, true,
15840 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 0), pre_p
,
15841 lhs_addr
, lhs_var
, target_expr
, false,
15846 if (pre_p
&& !goa_stabilize_expr (expr_p
, NULL
, lhs_addr
, lhs_var
,
15847 target_expr
, true, depth
))
15849 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 0), pre_p
,
15850 lhs_addr
, lhs_var
, target_expr
, false,
15853 case COMPOUND_EXPR
:
15854 /* Break out any preevaluations from cp_build_modify_expr. */
15855 for (; TREE_CODE (expr
) == COMPOUND_EXPR
;
15856 expr
= TREE_OPERAND (expr
, 1))
15858 /* Special-case __builtin_clear_padding call before
15859 __builtin_memcmp. */
15860 if (TREE_CODE (TREE_OPERAND (expr
, 0)) == CALL_EXPR
)
15862 tree fndecl
= get_callee_fndecl (TREE_OPERAND (expr
, 0));
15864 && fndecl_built_in_p (fndecl
, BUILT_IN_CLEAR_PADDING
)
15865 && VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (expr
, 0)))
15867 || goa_stabilize_expr (&TREE_OPERAND (expr
, 0), NULL
,
15869 target_expr
, true, depth
)))
15873 saw_lhs
= goa_stabilize_expr (&TREE_OPERAND (expr
, 0),
15874 pre_p
, lhs_addr
, lhs_var
,
15875 target_expr
, true, depth
);
15876 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 1),
15877 pre_p
, lhs_addr
, lhs_var
,
15878 target_expr
, rhs
, depth
);
15884 gimplify_stmt (&TREE_OPERAND (expr
, 0), pre_p
);
15887 return goa_stabilize_expr (&expr
, pre_p
, lhs_addr
, lhs_var
,
15888 target_expr
, rhs
, depth
);
15890 return goa_stabilize_expr (expr_p
, pre_p
, lhs_addr
, lhs_var
,
15891 target_expr
, rhs
, depth
);
15893 if (!goa_stabilize_expr (&TREE_OPERAND (expr
, 0), NULL
, lhs_addr
,
15894 lhs_var
, target_expr
, true, depth
))
15896 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 0), pre_p
,
15897 lhs_addr
, lhs_var
, target_expr
, true,
15899 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 1), pre_p
,
15900 lhs_addr
, lhs_var
, target_expr
, true,
15902 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 2), pre_p
,
15903 lhs_addr
, lhs_var
, target_expr
, true,
15907 if (TARGET_EXPR_INITIAL (expr
))
15909 if (pre_p
&& !goa_stabilize_expr (expr_p
, NULL
, lhs_addr
,
15910 lhs_var
, target_expr
, true,
15913 if (expr
== target_expr
)
15917 saw_lhs
= goa_stabilize_expr (&TARGET_EXPR_INITIAL (expr
),
15918 pre_p
, lhs_addr
, lhs_var
,
15919 target_expr
, true, depth
);
15920 if (saw_lhs
&& target_expr
== NULL_TREE
&& pre_p
)
15921 target_expr
= expr
;
15929 case tcc_reference
:
15930 if (TREE_CODE (expr
) == BIT_FIELD_REF
15931 || TREE_CODE (expr
) == VIEW_CONVERT_EXPR
)
15932 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 0), pre_p
,
15933 lhs_addr
, lhs_var
, target_expr
, true,
15937 if (TREE_CODE (expr
) == CALL_EXPR
)
15939 if (tree fndecl
= get_callee_fndecl (expr
))
15940 if (fndecl_built_in_p (fndecl
, BUILT_IN_CLEAR_PADDING
,
15943 int nargs
= call_expr_nargs (expr
);
15944 for (int i
= 0; i
< nargs
; i
++)
15945 saw_lhs
|= goa_stabilize_expr (&CALL_EXPR_ARG (expr
, i
),
15946 pre_p
, lhs_addr
, lhs_var
,
15947 target_expr
, true, depth
);
15956 if (saw_lhs
== 0 && pre_p
)
15958 enum gimplify_status gs
;
15959 if (TREE_CODE (expr
) == CALL_EXPR
&& VOID_TYPE_P (TREE_TYPE (expr
)))
15961 gimplify_stmt (&expr
, pre_p
);
15965 gs
= gimplify_expr (expr_p
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
15967 gs
= gimplify_expr (expr_p
, pre_p
, NULL
, is_gimple_lvalue
, fb_lvalue
);
15968 if (gs
!= GS_ALL_DONE
)
15975 /* Gimplify an OMP_ATOMIC statement. */
15977 static enum gimplify_status
15978 gimplify_omp_atomic (tree
*expr_p
, gimple_seq
*pre_p
)
15980 tree addr
= TREE_OPERAND (*expr_p
, 0);
15981 tree rhs
= TREE_CODE (*expr_p
) == OMP_ATOMIC_READ
15982 ? NULL
: TREE_OPERAND (*expr_p
, 1);
15983 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr
)));
15985 gomp_atomic_load
*loadstmt
;
15986 gomp_atomic_store
*storestmt
;
15987 tree target_expr
= NULL_TREE
;
15989 tmp_load
= create_tmp_reg (type
);
15991 && goa_stabilize_expr (&rhs
, pre_p
, addr
, tmp_load
, target_expr
,
15995 if (gimplify_expr (&addr
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
)
15999 loadstmt
= gimple_build_omp_atomic_load (tmp_load
, addr
,
16000 OMP_ATOMIC_MEMORY_ORDER (*expr_p
));
16001 gimplify_seq_add_stmt (pre_p
, loadstmt
);
16004 /* BIT_INSERT_EXPR is not valid for non-integral bitfield
16005 representatives. Use BIT_FIELD_REF on the lhs instead. */
16007 if (TREE_CODE (rhs
) == COND_EXPR
)
16008 rhsarg
= TREE_OPERAND (rhs
, 1);
16009 if (TREE_CODE (rhsarg
) == BIT_INSERT_EXPR
16010 && !INTEGRAL_TYPE_P (TREE_TYPE (tmp_load
)))
16012 tree bitpos
= TREE_OPERAND (rhsarg
, 2);
16013 tree op1
= TREE_OPERAND (rhsarg
, 1);
16015 tree tmp_store
= tmp_load
;
16016 if (TREE_CODE (*expr_p
) == OMP_ATOMIC_CAPTURE_OLD
)
16017 tmp_store
= get_initialized_tmp_var (tmp_load
, pre_p
);
16018 if (INTEGRAL_TYPE_P (TREE_TYPE (op1
)))
16019 bitsize
= bitsize_int (TYPE_PRECISION (TREE_TYPE (op1
)));
16021 bitsize
= TYPE_SIZE (TREE_TYPE (op1
));
16022 gcc_assert (TREE_OPERAND (rhsarg
, 0) == tmp_load
);
16023 tree t
= build2_loc (EXPR_LOCATION (rhsarg
),
16024 MODIFY_EXPR
, void_type_node
,
16025 build3_loc (EXPR_LOCATION (rhsarg
),
16026 BIT_FIELD_REF
, TREE_TYPE (op1
),
16027 tmp_store
, bitsize
, bitpos
), op1
);
16028 if (TREE_CODE (rhs
) == COND_EXPR
)
16029 t
= build3_loc (EXPR_LOCATION (rhs
), COND_EXPR
, void_type_node
,
16030 TREE_OPERAND (rhs
, 0), t
, void_node
);
16031 gimplify_and_add (t
, pre_p
);
16034 bool save_allow_rhs_cond_expr
= gimplify_ctxp
->allow_rhs_cond_expr
;
16035 if (TREE_CODE (rhs
) == COND_EXPR
)
16036 gimplify_ctxp
->allow_rhs_cond_expr
= true;
16037 enum gimplify_status gs
= gimplify_expr (&rhs
, pre_p
, NULL
,
16038 is_gimple_val
, fb_rvalue
);
16039 gimplify_ctxp
->allow_rhs_cond_expr
= save_allow_rhs_cond_expr
;
16040 if (gs
!= GS_ALL_DONE
)
16044 if (TREE_CODE (*expr_p
) == OMP_ATOMIC_READ
)
16047 = gimple_build_omp_atomic_store (rhs
, OMP_ATOMIC_MEMORY_ORDER (*expr_p
));
16048 if (TREE_CODE (*expr_p
) != OMP_ATOMIC_READ
&& OMP_ATOMIC_WEAK (*expr_p
))
16050 gimple_omp_atomic_set_weak (loadstmt
);
16051 gimple_omp_atomic_set_weak (storestmt
);
16053 gimplify_seq_add_stmt (pre_p
, storestmt
);
16054 switch (TREE_CODE (*expr_p
))
16056 case OMP_ATOMIC_READ
:
16057 case OMP_ATOMIC_CAPTURE_OLD
:
16058 *expr_p
= tmp_load
;
16059 gimple_omp_atomic_set_need_value (loadstmt
);
16061 case OMP_ATOMIC_CAPTURE_NEW
:
16063 gimple_omp_atomic_set_need_value (storestmt
);
16070 return GS_ALL_DONE
;
16073 /* Gimplify a TRANSACTION_EXPR. This involves gimplification of the
16074 body, and adding some EH bits. */
16076 static enum gimplify_status
16077 gimplify_transaction (tree
*expr_p
, gimple_seq
*pre_p
)
16079 tree expr
= *expr_p
, temp
, tbody
= TRANSACTION_EXPR_BODY (expr
);
16081 gtransaction
*trans_stmt
;
16082 gimple_seq body
= NULL
;
16085 /* Wrap the transaction body in a BIND_EXPR so we have a context
16086 where to put decls for OMP. */
16087 if (TREE_CODE (tbody
) != BIND_EXPR
)
16089 tree bind
= build3 (BIND_EXPR
, void_type_node
, NULL
, tbody
, NULL
);
16090 TREE_SIDE_EFFECTS (bind
) = 1;
16091 SET_EXPR_LOCATION (bind
, EXPR_LOCATION (tbody
));
16092 TRANSACTION_EXPR_BODY (expr
) = bind
;
16095 push_gimplify_context ();
16096 temp
= voidify_wrapper_expr (*expr_p
, NULL
);
16098 body_stmt
= gimplify_and_return_first (TRANSACTION_EXPR_BODY (expr
), &body
);
16099 pop_gimplify_context (body_stmt
);
16101 trans_stmt
= gimple_build_transaction (body
);
16102 if (TRANSACTION_EXPR_OUTER (expr
))
16103 subcode
= GTMA_IS_OUTER
;
16104 else if (TRANSACTION_EXPR_RELAXED (expr
))
16105 subcode
= GTMA_IS_RELAXED
;
16106 gimple_transaction_set_subcode (trans_stmt
, subcode
);
16108 gimplify_seq_add_stmt (pre_p
, trans_stmt
);
16116 *expr_p
= NULL_TREE
;
16117 return GS_ALL_DONE
;
16120 /* Gimplify an OMP_ORDERED construct. EXPR is the tree version. BODY
16121 is the OMP_BODY of the original EXPR (which has already been
16122 gimplified so it's not present in the EXPR).
16124 Return the gimplified GIMPLE_OMP_ORDERED tuple. */
16127 gimplify_omp_ordered (tree expr
, gimple_seq body
)
16132 tree source_c
= NULL_TREE
;
16133 tree sink_c
= NULL_TREE
;
16135 if (gimplify_omp_ctxp
)
16137 for (c
= OMP_ORDERED_CLAUSES (expr
); c
; c
= OMP_CLAUSE_CHAIN (c
))
16138 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DOACROSS
16139 && gimplify_omp_ctxp
->loop_iter_var
.is_empty ())
16141 error_at (OMP_CLAUSE_LOCATION (c
),
16142 "%<ordered%> construct with %qs clause must be "
16143 "closely nested inside a loop with %<ordered%> clause",
16144 OMP_CLAUSE_DOACROSS_DEPEND (c
) ? "depend" : "doacross");
16147 else if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DOACROSS
16148 && OMP_CLAUSE_DOACROSS_KIND (c
) == OMP_CLAUSE_DOACROSS_SINK
)
16152 if (OMP_CLAUSE_DECL (c
) == NULL_TREE
)
16153 continue; /* omp_cur_iteration - 1 */
16154 for (decls
= OMP_CLAUSE_DECL (c
), i
= 0;
16155 decls
&& TREE_CODE (decls
) == TREE_LIST
;
16156 decls
= TREE_CHAIN (decls
), ++i
)
16157 if (i
>= gimplify_omp_ctxp
->loop_iter_var
.length () / 2)
16159 else if (TREE_VALUE (decls
)
16160 != gimplify_omp_ctxp
->loop_iter_var
[2 * i
])
16162 error_at (OMP_CLAUSE_LOCATION (c
),
16163 "variable %qE is not an iteration "
16164 "of outermost loop %d, expected %qE",
16165 TREE_VALUE (decls
), i
+ 1,
16166 gimplify_omp_ctxp
->loop_iter_var
[2 * i
]);
16172 = gimplify_omp_ctxp
->loop_iter_var
[2 * i
+ 1];
16173 if (!fail
&& i
!= gimplify_omp_ctxp
->loop_iter_var
.length () / 2)
16175 error_at (OMP_CLAUSE_LOCATION (c
),
16176 "number of variables in %qs clause with "
16177 "%<sink%> modifier does not match number of "
16178 "iteration variables",
16179 OMP_CLAUSE_DOACROSS_DEPEND (c
)
16180 ? "depend" : "doacross");
16184 else if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DOACROSS
16185 && OMP_CLAUSE_DOACROSS_KIND (c
) == OMP_CLAUSE_DOACROSS_SOURCE
)
16189 error_at (OMP_CLAUSE_LOCATION (c
),
16190 "more than one %qs clause with %<source%> "
16191 "modifier on an %<ordered%> construct",
16192 OMP_CLAUSE_DOACROSS_DEPEND (source_c
)
16193 ? "depend" : "doacross");
16200 if (source_c
&& sink_c
)
16202 error_at (OMP_CLAUSE_LOCATION (source_c
),
16203 "%qs clause with %<source%> modifier specified "
16204 "together with %qs clauses with %<sink%> modifier "
16205 "on the same construct",
16206 OMP_CLAUSE_DOACROSS_DEPEND (source_c
) ? "depend" : "doacross",
16207 OMP_CLAUSE_DOACROSS_DEPEND (sink_c
) ? "depend" : "doacross");
16212 return gimple_build_nop ();
16213 return gimple_build_omp_ordered (body
, OMP_ORDERED_CLAUSES (expr
));
16216 /* Convert the GENERIC expression tree *EXPR_P to GIMPLE. If the
16217 expression produces a value to be used as an operand inside a GIMPLE
16218 statement, the value will be stored back in *EXPR_P. This value will
16219 be a tree of class tcc_declaration, tcc_constant, tcc_reference or
16220 an SSA_NAME. The corresponding sequence of GIMPLE statements is
16221 emitted in PRE_P and POST_P.
16223 Additionally, this process may overwrite parts of the input
16224 expression during gimplification. Ideally, it should be
16225 possible to do non-destructive gimplification.
16227 EXPR_P points to the GENERIC expression to convert to GIMPLE. If
16228 the expression needs to evaluate to a value to be used as
16229 an operand in a GIMPLE statement, this value will be stored in
16230 *EXPR_P on exit. This happens when the caller specifies one
16231 of fb_lvalue or fb_rvalue fallback flags.
16233 PRE_P will contain the sequence of GIMPLE statements corresponding
16234 to the evaluation of EXPR and all the side-effects that must
16235 be executed before the main expression. On exit, the last
16236 statement of PRE_P is the core statement being gimplified. For
16237 instance, when gimplifying 'if (++a)' the last statement in
16238 PRE_P will be 'if (t.1)' where t.1 is the result of
16239 pre-incrementing 'a'.
16241 POST_P will contain the sequence of GIMPLE statements corresponding
16242 to the evaluation of all the side-effects that must be executed
16243 after the main expression. If this is NULL, the post
16244 side-effects are stored at the end of PRE_P.
16246 The reason why the output is split in two is to handle post
16247 side-effects explicitly. In some cases, an expression may have
16248 inner and outer post side-effects which need to be emitted in
16249 an order different from the one given by the recursive
16250 traversal. For instance, for the expression (*p--)++ the post
16251 side-effects of '--' must actually occur *after* the post
16252 side-effects of '++'. However, gimplification will first visit
16253 the inner expression, so if a separate POST sequence was not
16254 used, the resulting sequence would be:
16261 However, the post-decrement operation in line #2 must not be
16262 evaluated until after the store to *p at line #4, so the
16263 correct sequence should be:
16270 So, by specifying a separate post queue, it is possible
16271 to emit the post side-effects in the correct order.
16272 If POST_P is NULL, an internal queue will be used. Before
16273 returning to the caller, the sequence POST_P is appended to
16274 the main output sequence PRE_P.
16276 GIMPLE_TEST_F points to a function that takes a tree T and
16277 returns nonzero if T is in the GIMPLE form requested by the
16278 caller. The GIMPLE predicates are in gimple.cc.
16280 FALLBACK tells the function what sort of a temporary we want if
16281 gimplification cannot produce an expression that complies with
16284 fb_none means that no temporary should be generated
16285 fb_rvalue means that an rvalue is OK to generate
16286 fb_lvalue means that an lvalue is OK to generate
16287 fb_either means that either is OK, but an lvalue is preferable.
16288 fb_mayfail means that gimplification may fail (in which case
16289 GS_ERROR will be returned)
16291 The return value is either GS_ERROR or GS_ALL_DONE, since this
16292 function iterates until EXPR is completely gimplified or an error
16295 enum gimplify_status
16296 gimplify_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
16297 bool (*gimple_test_f
) (tree
), fallback_t fallback
)
16300 gimple_seq internal_pre
= NULL
;
16301 gimple_seq internal_post
= NULL
;
16304 location_t saved_location
;
16305 enum gimplify_status ret
;
16306 gimple_stmt_iterator pre_last_gsi
, post_last_gsi
;
16309 save_expr
= *expr_p
;
16310 if (save_expr
== NULL_TREE
)
16311 return GS_ALL_DONE
;
16313 /* If we are gimplifying a top-level statement, PRE_P must be valid. */
16314 is_statement
= gimple_test_f
== is_gimple_stmt
;
16316 gcc_assert (pre_p
);
16318 /* Consistency checks. */
16319 if (gimple_test_f
== is_gimple_reg
)
16320 gcc_assert (fallback
& (fb_rvalue
| fb_lvalue
));
16321 else if (gimple_test_f
== is_gimple_val
16322 || gimple_test_f
== is_gimple_call_addr
16323 || gimple_test_f
== is_gimple_condexpr_for_cond
16324 || gimple_test_f
== is_gimple_mem_rhs
16325 || gimple_test_f
== is_gimple_mem_rhs_or_call
16326 || gimple_test_f
== is_gimple_reg_rhs
16327 || gimple_test_f
== is_gimple_reg_rhs_or_call
16328 || gimple_test_f
== is_gimple_asm_val
16329 || gimple_test_f
== is_gimple_mem_ref_addr
)
16330 gcc_assert (fallback
& fb_rvalue
);
16331 else if (gimple_test_f
== is_gimple_min_lval
16332 || gimple_test_f
== is_gimple_lvalue
)
16333 gcc_assert (fallback
& fb_lvalue
);
16334 else if (gimple_test_f
== is_gimple_addressable
)
16335 gcc_assert (fallback
& fb_either
);
16336 else if (gimple_test_f
== is_gimple_stmt
)
16337 gcc_assert (fallback
== fb_none
);
16340 /* We should have recognized the GIMPLE_TEST_F predicate to
16341 know what kind of fallback to use in case a temporary is
16342 needed to hold the value or address of *EXPR_P. */
16343 gcc_unreachable ();
16346 /* We used to check the predicate here and return immediately if it
16347 succeeds. This is wrong; the design is for gimplification to be
16348 idempotent, and for the predicates to only test for valid forms, not
16349 whether they are fully simplified. */
16351 pre_p
= &internal_pre
;
16353 if (post_p
== NULL
)
16354 post_p
= &internal_post
;
16356 /* Remember the last statements added to PRE_P and POST_P. Every
16357 new statement added by the gimplification helpers needs to be
16358 annotated with location information. To centralize the
16359 responsibility, we remember the last statement that had been
16360 added to both queues before gimplifying *EXPR_P. If
16361 gimplification produces new statements in PRE_P and POST_P, those
16362 statements will be annotated with the same location information
16364 pre_last_gsi
= gsi_last (*pre_p
);
16365 post_last_gsi
= gsi_last (*post_p
);
16367 saved_location
= input_location
;
16368 if (save_expr
!= error_mark_node
16369 && EXPR_HAS_LOCATION (*expr_p
))
16370 input_location
= EXPR_LOCATION (*expr_p
);
16372 /* Loop over the specific gimplifiers until the toplevel node
16373 remains the same. */
16376 /* Strip away as many useless type conversions as possible
16377 at the toplevel. */
16378 STRIP_USELESS_TYPE_CONVERSION (*expr_p
);
16380 /* Remember the expr. */
16381 save_expr
= *expr_p
;
16383 /* Die, die, die, my darling. */
16384 if (error_operand_p (save_expr
))
16390 /* Do any language-specific gimplification. */
16391 ret
= ((enum gimplify_status
)
16392 lang_hooks
.gimplify_expr (expr_p
, pre_p
, post_p
));
16395 if (*expr_p
== NULL_TREE
)
16397 if (*expr_p
!= save_expr
)
16400 else if (ret
!= GS_UNHANDLED
)
16403 /* Make sure that all the cases set 'ret' appropriately. */
16404 ret
= GS_UNHANDLED
;
16405 switch (TREE_CODE (*expr_p
))
16407 /* First deal with the special cases. */
16409 case POSTINCREMENT_EXPR
:
16410 case POSTDECREMENT_EXPR
:
16411 case PREINCREMENT_EXPR
:
16412 case PREDECREMENT_EXPR
:
16413 ret
= gimplify_self_mod_expr (expr_p
, pre_p
, post_p
,
16414 fallback
!= fb_none
,
16415 TREE_TYPE (*expr_p
));
16418 case VIEW_CONVERT_EXPR
:
16419 if ((fallback
& fb_rvalue
)
16420 && is_gimple_reg_type (TREE_TYPE (*expr_p
))
16421 && is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (*expr_p
, 0))))
16423 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
16424 post_p
, is_gimple_val
, fb_rvalue
);
16425 recalculate_side_effects (*expr_p
);
16431 case ARRAY_RANGE_REF
:
16432 case REALPART_EXPR
:
16433 case IMAGPART_EXPR
:
16434 case COMPONENT_REF
:
16435 ret
= gimplify_compound_lval (expr_p
, pre_p
, post_p
,
16436 fallback
? fallback
: fb_rvalue
);
16440 ret
= gimplify_cond_expr (expr_p
, pre_p
, fallback
);
16442 /* C99 code may assign to an array in a structure value of a
16443 conditional expression, and this has undefined behavior
16444 only on execution, so create a temporary if an lvalue is
16446 if (fallback
== fb_lvalue
)
16448 *expr_p
= get_initialized_tmp_var (*expr_p
, pre_p
, post_p
, false);
16449 mark_addressable (*expr_p
);
16455 ret
= gimplify_call_expr (expr_p
, pre_p
, fallback
!= fb_none
);
16457 /* C99 code may assign to an array in a structure returned
16458 from a function, and this has undefined behavior only on
16459 execution, so create a temporary if an lvalue is
16461 if (fallback
== fb_lvalue
)
16463 *expr_p
= get_initialized_tmp_var (*expr_p
, pre_p
, post_p
, false);
16464 mark_addressable (*expr_p
);
16470 gcc_unreachable ();
16472 case COMPOUND_EXPR
:
16473 ret
= gimplify_compound_expr (expr_p
, pre_p
, fallback
!= fb_none
);
16476 case COMPOUND_LITERAL_EXPR
:
16477 ret
= gimplify_compound_literal_expr (expr_p
, pre_p
,
16478 gimple_test_f
, fallback
);
16483 ret
= gimplify_modify_expr (expr_p
, pre_p
, post_p
,
16484 fallback
!= fb_none
);
16487 case TRUTH_ANDIF_EXPR
:
16488 case TRUTH_ORIF_EXPR
:
16490 /* Preserve the original type of the expression and the
16491 source location of the outer expression. */
16492 tree org_type
= TREE_TYPE (*expr_p
);
16493 *expr_p
= gimple_boolify (*expr_p
);
16494 *expr_p
= build3_loc (input_location
, COND_EXPR
,
16498 org_type
, boolean_true_node
),
16501 org_type
, boolean_false_node
));
16506 case TRUTH_NOT_EXPR
:
16508 tree type
= TREE_TYPE (*expr_p
);
16509 /* The parsers are careful to generate TRUTH_NOT_EXPR
16510 only with operands that are always zero or one.
16511 We do not fold here but handle the only interesting case
16512 manually, as fold may re-introduce the TRUTH_NOT_EXPR. */
16513 *expr_p
= gimple_boolify (*expr_p
);
16514 if (TYPE_PRECISION (TREE_TYPE (*expr_p
)) == 1)
16515 *expr_p
= build1_loc (input_location
, BIT_NOT_EXPR
,
16516 TREE_TYPE (*expr_p
),
16517 TREE_OPERAND (*expr_p
, 0));
16519 *expr_p
= build2_loc (input_location
, BIT_XOR_EXPR
,
16520 TREE_TYPE (*expr_p
),
16521 TREE_OPERAND (*expr_p
, 0),
16522 build_int_cst (TREE_TYPE (*expr_p
), 1));
16523 if (!useless_type_conversion_p (type
, TREE_TYPE (*expr_p
)))
16524 *expr_p
= fold_convert_loc (input_location
, type
, *expr_p
);
16530 ret
= gimplify_addr_expr (expr_p
, pre_p
, post_p
);
16533 case ANNOTATE_EXPR
:
16535 tree cond
= TREE_OPERAND (*expr_p
, 0);
16536 tree kind
= TREE_OPERAND (*expr_p
, 1);
16537 tree data
= TREE_OPERAND (*expr_p
, 2);
16538 tree type
= TREE_TYPE (cond
);
16539 if (!INTEGRAL_TYPE_P (type
))
16545 tree tmp
= create_tmp_var (type
);
16546 gimplify_arg (&cond
, pre_p
, EXPR_LOCATION (*expr_p
));
16548 = gimple_build_call_internal (IFN_ANNOTATE
, 3, cond
, kind
, data
);
16549 gimple_call_set_lhs (call
, tmp
);
16550 gimplify_seq_add_stmt (pre_p
, call
);
16557 ret
= gimplify_va_arg_expr (expr_p
, pre_p
, post_p
);
16561 if (IS_EMPTY_STMT (*expr_p
))
16567 if (VOID_TYPE_P (TREE_TYPE (*expr_p
))
16568 || fallback
== fb_none
)
16570 /* Just strip a conversion to void (or in void context) and
16572 *expr_p
= TREE_OPERAND (*expr_p
, 0);
16577 ret
= gimplify_conversion (expr_p
);
16578 if (ret
== GS_ERROR
)
16580 if (*expr_p
!= save_expr
)
16584 case FIX_TRUNC_EXPR
:
16585 /* unary_expr: ... | '(' cast ')' val | ... */
16586 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
16587 is_gimple_val
, fb_rvalue
);
16588 recalculate_side_effects (*expr_p
);
16593 bool volatilep
= TREE_THIS_VOLATILE (*expr_p
);
16594 bool notrap
= TREE_THIS_NOTRAP (*expr_p
);
16595 tree saved_ptr_type
= TREE_TYPE (TREE_OPERAND (*expr_p
, 0));
16597 *expr_p
= fold_indirect_ref_loc (input_location
, *expr_p
);
16598 if (*expr_p
!= save_expr
)
16604 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
16605 is_gimple_reg
, fb_rvalue
);
16606 if (ret
== GS_ERROR
)
16609 recalculate_side_effects (*expr_p
);
16610 *expr_p
= fold_build2_loc (input_location
, MEM_REF
,
16611 TREE_TYPE (*expr_p
),
16612 TREE_OPERAND (*expr_p
, 0),
16613 build_int_cst (saved_ptr_type
, 0));
16614 TREE_THIS_VOLATILE (*expr_p
) = volatilep
;
16615 TREE_THIS_NOTRAP (*expr_p
) = notrap
;
16620 /* We arrive here through the various re-gimplifcation paths. */
16622 /* First try re-folding the whole thing. */
16623 tmp
= fold_binary (MEM_REF
, TREE_TYPE (*expr_p
),
16624 TREE_OPERAND (*expr_p
, 0),
16625 TREE_OPERAND (*expr_p
, 1));
16628 REF_REVERSE_STORAGE_ORDER (tmp
)
16629 = REF_REVERSE_STORAGE_ORDER (*expr_p
);
16631 recalculate_side_effects (*expr_p
);
16635 /* Avoid re-gimplifying the address operand if it is already
16636 in suitable form. Re-gimplifying would mark the address
16637 operand addressable. Always gimplify when not in SSA form
16638 as we still may have to gimplify decls with value-exprs. */
16639 if (!gimplify_ctxp
|| !gimple_in_ssa_p (cfun
)
16640 || !is_gimple_mem_ref_addr (TREE_OPERAND (*expr_p
, 0)))
16642 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
16643 is_gimple_mem_ref_addr
, fb_rvalue
);
16644 if (ret
== GS_ERROR
)
16647 recalculate_side_effects (*expr_p
);
16651 /* Constants need not be gimplified. */
16658 /* Drop the overflow flag on constants, we do not want
16659 that in the GIMPLE IL. */
16660 if (TREE_OVERFLOW_P (*expr_p
))
16661 *expr_p
= drop_tree_overflow (*expr_p
);
16666 /* If we require an lvalue, such as for ADDR_EXPR, retain the
16667 CONST_DECL node. Otherwise the decl is replaceable by its
16669 /* ??? Should be == fb_lvalue, but ADDR_EXPR passes fb_either. */
16670 if (fallback
& fb_lvalue
)
16674 *expr_p
= DECL_INITIAL (*expr_p
);
16680 ret
= gimplify_decl_expr (expr_p
, pre_p
);
16684 ret
= gimplify_bind_expr (expr_p
, pre_p
);
16688 ret
= gimplify_loop_expr (expr_p
, pre_p
);
16692 ret
= gimplify_switch_expr (expr_p
, pre_p
);
16696 ret
= gimplify_exit_expr (expr_p
);
16700 /* If the target is not LABEL, then it is a computed jump
16701 and the target needs to be gimplified. */
16702 if (TREE_CODE (GOTO_DESTINATION (*expr_p
)) != LABEL_DECL
)
16704 ret
= gimplify_expr (&GOTO_DESTINATION (*expr_p
), pre_p
,
16705 NULL
, is_gimple_val
, fb_rvalue
);
16706 if (ret
== GS_ERROR
)
16709 gimplify_seq_add_stmt (pre_p
,
16710 gimple_build_goto (GOTO_DESTINATION (*expr_p
)));
16715 gimplify_seq_add_stmt (pre_p
,
16716 gimple_build_predict (PREDICT_EXPR_PREDICTOR (*expr_p
),
16717 PREDICT_EXPR_OUTCOME (*expr_p
)));
16722 ret
= gimplify_label_expr (expr_p
, pre_p
);
16723 label
= LABEL_EXPR_LABEL (*expr_p
);
16724 gcc_assert (decl_function_context (label
) == current_function_decl
);
16726 /* If the label is used in a goto statement, or address of the label
16727 is taken, we need to unpoison all variables that were seen so far.
16728 Doing so would prevent us from reporting a false positives. */
16729 if (asan_poisoned_variables
16730 && asan_used_labels
!= NULL
16731 && asan_used_labels
->contains (label
)
16732 && !gimplify_omp_ctxp
)
16733 asan_poison_variables (asan_poisoned_variables
, false, pre_p
);
16736 case CASE_LABEL_EXPR
:
16737 ret
= gimplify_case_label_expr (expr_p
, pre_p
);
16739 if (gimplify_ctxp
->live_switch_vars
)
16740 asan_poison_variables (gimplify_ctxp
->live_switch_vars
, false,
16745 ret
= gimplify_return_expr (*expr_p
, pre_p
);
16749 /* Don't reduce this in place; let gimplify_init_constructor work its
16750 magic. Buf if we're just elaborating this for side effects, just
16751 gimplify any element that has side-effects. */
16752 if (fallback
== fb_none
)
16754 unsigned HOST_WIDE_INT ix
;
16756 tree temp
= NULL_TREE
;
16757 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (*expr_p
), ix
, val
)
16758 if (TREE_SIDE_EFFECTS (val
))
16759 append_to_statement_list (val
, &temp
);
16762 ret
= temp
? GS_OK
: GS_ALL_DONE
;
16764 /* C99 code may assign to an array in a constructed
16765 structure or union, and this has undefined behavior only
16766 on execution, so create a temporary if an lvalue is
16768 else if (fallback
== fb_lvalue
)
16770 *expr_p
= get_initialized_tmp_var (*expr_p
, pre_p
, post_p
, false);
16771 mark_addressable (*expr_p
);
16778 /* The following are special cases that are not handled by the
16779 original GIMPLE grammar. */
16781 /* SAVE_EXPR nodes are converted into a GIMPLE identifier and
16784 ret
= gimplify_save_expr (expr_p
, pre_p
, post_p
);
16787 case BIT_FIELD_REF
:
16788 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
16789 post_p
, is_gimple_lvalue
, fb_either
);
16790 recalculate_side_effects (*expr_p
);
16793 case TARGET_MEM_REF
:
16795 enum gimplify_status r0
= GS_ALL_DONE
, r1
= GS_ALL_DONE
;
16797 if (TMR_BASE (*expr_p
))
16798 r0
= gimplify_expr (&TMR_BASE (*expr_p
), pre_p
,
16799 post_p
, is_gimple_mem_ref_addr
, fb_either
);
16800 if (TMR_INDEX (*expr_p
))
16801 r1
= gimplify_expr (&TMR_INDEX (*expr_p
), pre_p
,
16802 post_p
, is_gimple_val
, fb_rvalue
);
16803 if (TMR_INDEX2 (*expr_p
))
16804 r1
= gimplify_expr (&TMR_INDEX2 (*expr_p
), pre_p
,
16805 post_p
, is_gimple_val
, fb_rvalue
);
16806 /* TMR_STEP and TMR_OFFSET are always integer constants. */
16807 ret
= MIN (r0
, r1
);
16811 case NON_LVALUE_EXPR
:
16812 /* This should have been stripped above. */
16813 gcc_unreachable ();
16816 ret
= gimplify_asm_expr (expr_p
, pre_p
, post_p
);
16819 case TRY_FINALLY_EXPR
:
16820 case TRY_CATCH_EXPR
:
16822 gimple_seq eval
, cleanup
;
16825 /* Calls to destructors are generated automatically in FINALLY/CATCH
16826 block. They should have location as UNKNOWN_LOCATION. However,
16827 gimplify_call_expr will reset these call stmts to input_location
16828 if it finds stmt's location is unknown. To prevent resetting for
16829 destructors, we set the input_location to unknown.
16830 Note that this only affects the destructor calls in FINALLY/CATCH
16831 block, and will automatically reset to its original value by the
16832 end of gimplify_expr. */
16833 input_location
= UNKNOWN_LOCATION
;
16834 eval
= cleanup
= NULL
;
16835 gimplify_and_add (TREE_OPERAND (*expr_p
, 0), &eval
);
16836 if (TREE_CODE (*expr_p
) == TRY_FINALLY_EXPR
16837 && TREE_CODE (TREE_OPERAND (*expr_p
, 1)) == EH_ELSE_EXPR
)
16839 gimple_seq n
= NULL
, e
= NULL
;
16840 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p
, 1),
16842 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p
, 1),
16844 if (!gimple_seq_empty_p (n
) && !gimple_seq_empty_p (e
))
16846 geh_else
*stmt
= gimple_build_eh_else (n
, e
);
16847 gimple_seq_add_stmt (&cleanup
, stmt
);
16851 gimplify_and_add (TREE_OPERAND (*expr_p
, 1), &cleanup
);
16852 /* Don't create bogus GIMPLE_TRY with empty cleanup. */
16853 if (gimple_seq_empty_p (cleanup
))
16855 gimple_seq_add_seq (pre_p
, eval
);
16859 try_
= gimple_build_try (eval
, cleanup
,
16860 TREE_CODE (*expr_p
) == TRY_FINALLY_EXPR
16861 ? GIMPLE_TRY_FINALLY
16862 : GIMPLE_TRY_CATCH
);
16863 if (EXPR_HAS_LOCATION (save_expr
))
16864 gimple_set_location (try_
, EXPR_LOCATION (save_expr
));
16865 else if (LOCATION_LOCUS (saved_location
) != UNKNOWN_LOCATION
)
16866 gimple_set_location (try_
, saved_location
);
16867 if (TREE_CODE (*expr_p
) == TRY_CATCH_EXPR
)
16868 gimple_try_set_catch_is_cleanup (try_
,
16869 TRY_CATCH_IS_CLEANUP (*expr_p
));
16870 gimplify_seq_add_stmt (pre_p
, try_
);
16875 case CLEANUP_POINT_EXPR
:
16876 ret
= gimplify_cleanup_point_expr (expr_p
, pre_p
);
16880 ret
= gimplify_target_expr (expr_p
, pre_p
, post_p
);
16886 gimple_seq handler
= NULL
;
16887 gimplify_and_add (CATCH_BODY (*expr_p
), &handler
);
16888 c
= gimple_build_catch (CATCH_TYPES (*expr_p
), handler
);
16889 gimplify_seq_add_stmt (pre_p
, c
);
16894 case EH_FILTER_EXPR
:
16897 gimple_seq failure
= NULL
;
16899 gimplify_and_add (EH_FILTER_FAILURE (*expr_p
), &failure
);
16900 ehf
= gimple_build_eh_filter (EH_FILTER_TYPES (*expr_p
), failure
);
16901 copy_warning (ehf
, *expr_p
);
16902 gimplify_seq_add_stmt (pre_p
, ehf
);
16909 enum gimplify_status r0
, r1
;
16910 r0
= gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p
), pre_p
,
16911 post_p
, is_gimple_val
, fb_rvalue
);
16912 r1
= gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p
), pre_p
,
16913 post_p
, is_gimple_val
, fb_rvalue
);
16914 TREE_SIDE_EFFECTS (*expr_p
) = 0;
16915 ret
= MIN (r0
, r1
);
16920 /* We get here when taking the address of a label. We mark
16921 the label as "forced"; meaning it can never be removed and
16922 it is a potential target for any computed goto. */
16923 FORCED_LABEL (*expr_p
) = 1;
16927 case STATEMENT_LIST
:
16928 ret
= gimplify_statement_list (expr_p
, pre_p
);
16931 case WITH_SIZE_EXPR
:
16933 gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
16934 post_p
== &internal_post
? NULL
: post_p
,
16935 gimple_test_f
, fallback
);
16936 gimplify_expr (&TREE_OPERAND (*expr_p
, 1), pre_p
, post_p
,
16937 is_gimple_val
, fb_rvalue
);
16944 ret
= gimplify_var_or_parm_decl (expr_p
);
16948 /* When within an OMP context, notice uses of variables. */
16949 if (gimplify_omp_ctxp
)
16950 omp_notice_variable (gimplify_omp_ctxp
, *expr_p
, true);
16954 case DEBUG_EXPR_DECL
:
16955 gcc_unreachable ();
16957 case DEBUG_BEGIN_STMT
:
16958 gimplify_seq_add_stmt (pre_p
,
16959 gimple_build_debug_begin_stmt
16960 (TREE_BLOCK (*expr_p
),
16961 EXPR_LOCATION (*expr_p
)));
16967 /* Allow callbacks into the gimplifier during optimization. */
16972 gimplify_omp_parallel (expr_p
, pre_p
);
16977 gimplify_omp_task (expr_p
, pre_p
);
16983 /* Temporarily disable into_ssa, as scan_omp_simd
16984 which calls copy_gimple_seq_and_replace_locals can't deal
16985 with SSA_NAMEs defined outside of the body properly. */
16986 bool saved_into_ssa
= gimplify_ctxp
->into_ssa
;
16987 gimplify_ctxp
->into_ssa
= false;
16988 ret
= gimplify_omp_for (expr_p
, pre_p
);
16989 gimplify_ctxp
->into_ssa
= saved_into_ssa
;
16994 case OMP_DISTRIBUTE
:
16997 ret
= gimplify_omp_for (expr_p
, pre_p
);
17001 ret
= gimplify_omp_loop (expr_p
, pre_p
);
17005 gimplify_oacc_cache (expr_p
, pre_p
);
17010 gimplify_oacc_declare (expr_p
, pre_p
);
17014 case OACC_HOST_DATA
:
17017 case OACC_PARALLEL
:
17023 case OMP_TARGET_DATA
:
17025 gimplify_omp_workshare (expr_p
, pre_p
);
17029 case OACC_ENTER_DATA
:
17030 case OACC_EXIT_DATA
:
17032 case OMP_TARGET_UPDATE
:
17033 case OMP_TARGET_ENTER_DATA
:
17034 case OMP_TARGET_EXIT_DATA
:
17035 gimplify_omp_target_update (expr_p
, pre_p
);
17046 gimple_seq body
= NULL
;
17048 bool saved_in_omp_construct
= in_omp_construct
;
17050 in_omp_construct
= true;
17051 gimplify_and_add (OMP_BODY (*expr_p
), &body
);
17052 in_omp_construct
= saved_in_omp_construct
;
17053 switch (TREE_CODE (*expr_p
))
17056 g
= gimple_build_omp_section (body
);
17059 g
= gimple_build_omp_master (body
);
17062 g
= gimplify_omp_ordered (*expr_p
, body
);
17063 if (OMP_BODY (*expr_p
) == NULL_TREE
17064 && gimple_code (g
) == GIMPLE_OMP_ORDERED
)
17065 gimple_omp_ordered_standalone (g
);
17068 gimplify_scan_omp_clauses (&OMP_MASKED_CLAUSES (*expr_p
),
17069 pre_p
, ORT_WORKSHARE
, OMP_MASKED
);
17070 gimplify_adjust_omp_clauses (pre_p
, body
,
17071 &OMP_MASKED_CLAUSES (*expr_p
),
17073 g
= gimple_build_omp_masked (body
,
17074 OMP_MASKED_CLAUSES (*expr_p
));
17077 gimplify_scan_omp_clauses (&OMP_CRITICAL_CLAUSES (*expr_p
),
17078 pre_p
, ORT_WORKSHARE
, OMP_CRITICAL
);
17079 gimplify_adjust_omp_clauses (pre_p
, body
,
17080 &OMP_CRITICAL_CLAUSES (*expr_p
),
17082 g
= gimple_build_omp_critical (body
,
17083 OMP_CRITICAL_NAME (*expr_p
),
17084 OMP_CRITICAL_CLAUSES (*expr_p
));
17087 gimplify_scan_omp_clauses (&OMP_SCAN_CLAUSES (*expr_p
),
17088 pre_p
, ORT_WORKSHARE
, OMP_SCAN
);
17089 gimplify_adjust_omp_clauses (pre_p
, body
,
17090 &OMP_SCAN_CLAUSES (*expr_p
),
17092 g
= gimple_build_omp_scan (body
, OMP_SCAN_CLAUSES (*expr_p
));
17095 gcc_unreachable ();
17097 gimplify_seq_add_stmt (pre_p
, g
);
17102 case OMP_TASKGROUP
:
17104 gimple_seq body
= NULL
;
17106 tree
*pclauses
= &OMP_TASKGROUP_CLAUSES (*expr_p
);
17107 bool saved_in_omp_construct
= in_omp_construct
;
17108 gimplify_scan_omp_clauses (pclauses
, pre_p
, ORT_TASKGROUP
,
17110 gimplify_adjust_omp_clauses (pre_p
, NULL
, pclauses
, OMP_TASKGROUP
);
17112 in_omp_construct
= true;
17113 gimplify_and_add (OMP_BODY (*expr_p
), &body
);
17114 in_omp_construct
= saved_in_omp_construct
;
17115 gimple_seq cleanup
= NULL
;
17116 tree fn
= builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_END
);
17117 gimple
*g
= gimple_build_call (fn
, 0);
17118 gimple_seq_add_stmt (&cleanup
, g
);
17119 g
= gimple_build_try (body
, cleanup
, GIMPLE_TRY_FINALLY
);
17121 gimple_seq_add_stmt (&body
, g
);
17122 g
= gimple_build_omp_taskgroup (body
, *pclauses
);
17123 gimplify_seq_add_stmt (pre_p
, g
);
17129 case OMP_ATOMIC_READ
:
17130 case OMP_ATOMIC_CAPTURE_OLD
:
17131 case OMP_ATOMIC_CAPTURE_NEW
:
17132 ret
= gimplify_omp_atomic (expr_p
, pre_p
);
17135 case TRANSACTION_EXPR
:
17136 ret
= gimplify_transaction (expr_p
, pre_p
);
17139 case TRUTH_AND_EXPR
:
17140 case TRUTH_OR_EXPR
:
17141 case TRUTH_XOR_EXPR
:
17143 tree orig_type
= TREE_TYPE (*expr_p
);
17144 tree new_type
, xop0
, xop1
;
17145 *expr_p
= gimple_boolify (*expr_p
);
17146 new_type
= TREE_TYPE (*expr_p
);
17147 if (!useless_type_conversion_p (orig_type
, new_type
))
17149 *expr_p
= fold_convert_loc (input_location
, orig_type
, *expr_p
);
17154 /* Boolified binary truth expressions are semantically equivalent
17155 to bitwise binary expressions. Canonicalize them to the
17156 bitwise variant. */
17157 switch (TREE_CODE (*expr_p
))
17159 case TRUTH_AND_EXPR
:
17160 TREE_SET_CODE (*expr_p
, BIT_AND_EXPR
);
17162 case TRUTH_OR_EXPR
:
17163 TREE_SET_CODE (*expr_p
, BIT_IOR_EXPR
);
17165 case TRUTH_XOR_EXPR
:
17166 TREE_SET_CODE (*expr_p
, BIT_XOR_EXPR
);
17171 /* Now make sure that operands have compatible type to
17172 expression's new_type. */
17173 xop0
= TREE_OPERAND (*expr_p
, 0);
17174 xop1
= TREE_OPERAND (*expr_p
, 1);
17175 if (!useless_type_conversion_p (new_type
, TREE_TYPE (xop0
)))
17176 TREE_OPERAND (*expr_p
, 0) = fold_convert_loc (input_location
,
17179 if (!useless_type_conversion_p (new_type
, TREE_TYPE (xop1
)))
17180 TREE_OPERAND (*expr_p
, 1) = fold_convert_loc (input_location
,
17183 /* Continue classified as tcc_binary. */
17187 case VEC_COND_EXPR
:
17190 case VEC_PERM_EXPR
:
17191 /* Classified as tcc_expression. */
17194 case BIT_INSERT_EXPR
:
17195 /* Argument 3 is a constant. */
17198 case POINTER_PLUS_EXPR
:
17200 enum gimplify_status r0
, r1
;
17201 r0
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
17202 post_p
, is_gimple_val
, fb_rvalue
);
17203 r1
= gimplify_expr (&TREE_OPERAND (*expr_p
, 1), pre_p
,
17204 post_p
, is_gimple_val
, fb_rvalue
);
17205 recalculate_side_effects (*expr_p
);
17206 ret
= MIN (r0
, r1
);
17211 switch (TREE_CODE_CLASS (TREE_CODE (*expr_p
)))
17213 case tcc_comparison
:
17214 /* Handle comparison of objects of non scalar mode aggregates
17215 with a call to memcmp. It would be nice to only have to do
17216 this for variable-sized objects, but then we'd have to allow
17217 the same nest of reference nodes we allow for MODIFY_EXPR and
17218 that's too complex.
17220 Compare scalar mode aggregates as scalar mode values. Using
17221 memcmp for them would be very inefficient at best, and is
17222 plain wrong if bitfields are involved. */
17223 if (error_operand_p (TREE_OPERAND (*expr_p
, 1)))
17227 tree type
= TREE_TYPE (TREE_OPERAND (*expr_p
, 1));
17229 /* Vector comparisons need no boolification. */
17230 if (TREE_CODE (type
) == VECTOR_TYPE
)
17232 else if (!AGGREGATE_TYPE_P (type
))
17234 tree org_type
= TREE_TYPE (*expr_p
);
17235 *expr_p
= gimple_boolify (*expr_p
);
17236 if (!useless_type_conversion_p (org_type
,
17237 TREE_TYPE (*expr_p
)))
17239 *expr_p
= fold_convert_loc (input_location
,
17240 org_type
, *expr_p
);
17246 else if (TYPE_MODE (type
) != BLKmode
)
17247 ret
= gimplify_scalar_mode_aggregate_compare (expr_p
);
17249 ret
= gimplify_variable_sized_compare (expr_p
);
17253 /* If *EXPR_P does not need to be special-cased, handle it
17254 according to its class. */
17256 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
17257 post_p
, is_gimple_val
, fb_rvalue
);
17263 enum gimplify_status r0
, r1
;
17265 r0
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
17266 post_p
, is_gimple_val
, fb_rvalue
);
17267 r1
= gimplify_expr (&TREE_OPERAND (*expr_p
, 1), pre_p
,
17268 post_p
, is_gimple_val
, fb_rvalue
);
17270 ret
= MIN (r0
, r1
);
17276 enum gimplify_status r0
, r1
, r2
;
17278 r0
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
17279 post_p
, is_gimple_val
, fb_rvalue
);
17280 r1
= gimplify_expr (&TREE_OPERAND (*expr_p
, 1), pre_p
,
17281 post_p
, is_gimple_val
, fb_rvalue
);
17282 r2
= gimplify_expr (&TREE_OPERAND (*expr_p
, 2), pre_p
,
17283 post_p
, is_gimple_val
, fb_rvalue
);
17285 ret
= MIN (MIN (r0
, r1
), r2
);
17289 case tcc_declaration
:
17292 goto dont_recalculate
;
17295 gcc_unreachable ();
17298 recalculate_side_effects (*expr_p
);
17304 gcc_assert (*expr_p
|| ret
!= GS_OK
);
17306 while (ret
== GS_OK
);
17308 /* If we encountered an error_mark somewhere nested inside, either
17309 stub out the statement or propagate the error back out. */
17310 if (ret
== GS_ERROR
)
17317 /* This was only valid as a return value from the langhook, which
17318 we handled. Make sure it doesn't escape from any other context. */
17319 gcc_assert (ret
!= GS_UNHANDLED
);
17321 if (fallback
== fb_none
&& *expr_p
&& !is_gimple_stmt (*expr_p
))
17323 /* We aren't looking for a value, and we don't have a valid
17324 statement. If it doesn't have side-effects, throw it away.
17325 We can also get here with code such as "*&&L;", where L is
17326 a LABEL_DECL that is marked as FORCED_LABEL. */
17327 if (TREE_CODE (*expr_p
) == LABEL_DECL
17328 || !TREE_SIDE_EFFECTS (*expr_p
))
17330 else if (!TREE_THIS_VOLATILE (*expr_p
))
17332 /* This is probably a _REF that contains something nested that
17333 has side effects. Recurse through the operands to find it. */
17334 enum tree_code code
= TREE_CODE (*expr_p
);
17338 case COMPONENT_REF
:
17339 case REALPART_EXPR
:
17340 case IMAGPART_EXPR
:
17341 case VIEW_CONVERT_EXPR
:
17342 gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
17343 gimple_test_f
, fallback
);
17347 case ARRAY_RANGE_REF
:
17348 gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
17349 gimple_test_f
, fallback
);
17350 gimplify_expr (&TREE_OPERAND (*expr_p
, 1), pre_p
, post_p
,
17351 gimple_test_f
, fallback
);
17355 /* Anything else with side-effects must be converted to
17356 a valid statement before we get here. */
17357 gcc_unreachable ();
17362 else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p
))
17363 && TYPE_MODE (TREE_TYPE (*expr_p
)) != BLKmode
17364 && !is_empty_type (TREE_TYPE (*expr_p
)))
17366 /* Historically, the compiler has treated a bare reference
17367 to a non-BLKmode volatile lvalue as forcing a load. */
17368 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p
));
17370 /* Normally, we do not want to create a temporary for a
17371 TREE_ADDRESSABLE type because such a type should not be
17372 copied by bitwise-assignment. However, we make an
17373 exception here, as all we are doing here is ensuring that
17374 we read the bytes that make up the type. We use
17375 create_tmp_var_raw because create_tmp_var will abort when
17376 given a TREE_ADDRESSABLE type. */
17377 tree tmp
= create_tmp_var_raw (type
, "vol");
17378 gimple_add_tmp_var (tmp
);
17379 gimplify_assign (tmp
, *expr_p
, pre_p
);
17383 /* We can't do anything useful with a volatile reference to
17384 an incomplete type, so just throw it away. Likewise for
17385 a BLKmode type, since any implicit inner load should
17386 already have been turned into an explicit one by the
17387 gimplification process. */
17391 /* If we are gimplifying at the statement level, we're done. Tack
17392 everything together and return. */
17393 if (fallback
== fb_none
|| is_statement
)
17395 /* Since *EXPR_P has been converted into a GIMPLE tuple, clear
17396 it out for GC to reclaim it. */
17397 *expr_p
= NULL_TREE
;
17399 if (!gimple_seq_empty_p (internal_pre
)
17400 || !gimple_seq_empty_p (internal_post
))
17402 gimplify_seq_add_seq (&internal_pre
, internal_post
);
17403 gimplify_seq_add_seq (pre_p
, internal_pre
);
17406 /* The result of gimplifying *EXPR_P is going to be the last few
17407 statements in *PRE_P and *POST_P. Add location information
17408 to all the statements that were added by the gimplification
17410 if (!gimple_seq_empty_p (*pre_p
))
17411 annotate_all_with_location_after (*pre_p
, pre_last_gsi
, input_location
);
17413 if (!gimple_seq_empty_p (*post_p
))
17414 annotate_all_with_location_after (*post_p
, post_last_gsi
,
17420 #ifdef ENABLE_GIMPLE_CHECKING
17423 enum tree_code code
= TREE_CODE (*expr_p
);
17424 /* These expressions should already be in gimple IR form. */
17425 gcc_assert (code
!= MODIFY_EXPR
17426 && code
!= ASM_EXPR
17427 && code
!= BIND_EXPR
17428 && code
!= CATCH_EXPR
17429 && (code
!= COND_EXPR
|| gimplify_ctxp
->allow_rhs_cond_expr
)
17430 && code
!= EH_FILTER_EXPR
17431 && code
!= GOTO_EXPR
17432 && code
!= LABEL_EXPR
17433 && code
!= LOOP_EXPR
17434 && code
!= SWITCH_EXPR
17435 && code
!= TRY_FINALLY_EXPR
17436 && code
!= EH_ELSE_EXPR
17437 && code
!= OACC_PARALLEL
17438 && code
!= OACC_KERNELS
17439 && code
!= OACC_SERIAL
17440 && code
!= OACC_DATA
17441 && code
!= OACC_HOST_DATA
17442 && code
!= OACC_DECLARE
17443 && code
!= OACC_UPDATE
17444 && code
!= OACC_ENTER_DATA
17445 && code
!= OACC_EXIT_DATA
17446 && code
!= OACC_CACHE
17447 && code
!= OMP_CRITICAL
17449 && code
!= OACC_LOOP
17450 && code
!= OMP_MASTER
17451 && code
!= OMP_MASKED
17452 && code
!= OMP_TASKGROUP
17453 && code
!= OMP_ORDERED
17454 && code
!= OMP_PARALLEL
17455 && code
!= OMP_SCAN
17456 && code
!= OMP_SECTIONS
17457 && code
!= OMP_SECTION
17458 && code
!= OMP_SINGLE
17459 && code
!= OMP_SCOPE
);
17463 /* Otherwise we're gimplifying a subexpression, so the resulting
17464 value is interesting. If it's a valid operand that matches
17465 GIMPLE_TEST_F, we're done. Unless we are handling some
17466 post-effects internally; if that's the case, we need to copy into
17467 a temporary before adding the post-effects to POST_P. */
17468 if (gimple_seq_empty_p (internal_post
) && (*gimple_test_f
) (*expr_p
))
17471 /* Otherwise, we need to create a new temporary for the gimplified
17474 /* We can't return an lvalue if we have an internal postqueue. The
17475 object the lvalue refers to would (probably) be modified by the
17476 postqueue; we need to copy the value out first, which means an
17478 if ((fallback
& fb_lvalue
)
17479 && gimple_seq_empty_p (internal_post
)
17480 && is_gimple_addressable (*expr_p
))
17482 /* An lvalue will do. Take the address of the expression, store it
17483 in a temporary, and replace the expression with an INDIRECT_REF of
17485 tree ref_alias_type
= reference_alias_ptr_type (*expr_p
);
17486 unsigned int ref_align
= get_object_alignment (*expr_p
);
17487 tree ref_type
= TREE_TYPE (*expr_p
);
17488 tmp
= build_fold_addr_expr_loc (input_location
, *expr_p
);
17489 gimplify_expr (&tmp
, pre_p
, post_p
, is_gimple_reg
, fb_rvalue
);
17490 if (TYPE_ALIGN (ref_type
) != ref_align
)
17491 ref_type
= build_aligned_type (ref_type
, ref_align
);
17492 *expr_p
= build2 (MEM_REF
, ref_type
,
17493 tmp
, build_zero_cst (ref_alias_type
));
17495 else if ((fallback
& fb_rvalue
) && is_gimple_reg_rhs_or_call (*expr_p
))
17497 /* An rvalue will do. Assign the gimplified expression into a
17498 new temporary TMP and replace the original expression with
17499 TMP. First, make sure that the expression has a type so that
17500 it can be assigned into a temporary. */
17501 gcc_assert (!VOID_TYPE_P (TREE_TYPE (*expr_p
)));
17502 *expr_p
= get_formal_tmp_var (*expr_p
, pre_p
);
17506 #ifdef ENABLE_GIMPLE_CHECKING
17507 if (!(fallback
& fb_mayfail
))
17509 fprintf (stderr
, "gimplification failed:\n");
17510 print_generic_expr (stderr
, *expr_p
);
17511 debug_tree (*expr_p
);
17512 internal_error ("gimplification failed");
17515 gcc_assert (fallback
& fb_mayfail
);
17517 /* If this is an asm statement, and the user asked for the
17518 impossible, don't die. Fail and let gimplify_asm_expr
17524 /* Make sure the temporary matches our predicate. */
17525 gcc_assert ((*gimple_test_f
) (*expr_p
));
17527 if (!gimple_seq_empty_p (internal_post
))
17529 annotate_all_with_location (internal_post
, input_location
);
17530 gimplify_seq_add_seq (pre_p
, internal_post
);
17534 input_location
= saved_location
;
17538 /* Like gimplify_expr but make sure the gimplified result is not itself
17539 a SSA name (but a decl if it were). Temporaries required by
17540 evaluating *EXPR_P may be still SSA names. */
17542 static enum gimplify_status
17543 gimplify_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
17544 bool (*gimple_test_f
) (tree
), fallback_t fallback
,
17547 enum gimplify_status ret
= gimplify_expr (expr_p
, pre_p
, post_p
,
17548 gimple_test_f
, fallback
);
17550 && TREE_CODE (*expr_p
) == SSA_NAME
)
17551 *expr_p
= get_initialized_tmp_var (*expr_p
, pre_p
, NULL
, false);
17555 /* Look through TYPE for variable-sized objects and gimplify each such
17556 size that we find. Add to LIST_P any statements generated. */
17559 gimplify_type_sizes (tree type
, gimple_seq
*list_p
)
17561 if (type
== NULL
|| type
== error_mark_node
)
17564 const bool ignored_p
17566 && TREE_CODE (TYPE_NAME (type
)) == TYPE_DECL
17567 && DECL_IGNORED_P (TYPE_NAME (type
));
17570 /* We first do the main variant, then copy into any other variants. */
17571 type
= TYPE_MAIN_VARIANT (type
);
17573 /* Avoid infinite recursion. */
17574 if (TYPE_SIZES_GIMPLIFIED (type
))
17577 TYPE_SIZES_GIMPLIFIED (type
) = 1;
17579 switch (TREE_CODE (type
))
17582 case ENUMERAL_TYPE
:
17585 case FIXED_POINT_TYPE
:
17586 gimplify_one_sizepos (&TYPE_MIN_VALUE (type
), list_p
);
17587 gimplify_one_sizepos (&TYPE_MAX_VALUE (type
), list_p
);
17589 for (t
= TYPE_NEXT_VARIANT (type
); t
; t
= TYPE_NEXT_VARIANT (t
))
17591 TYPE_MIN_VALUE (t
) = TYPE_MIN_VALUE (type
);
17592 TYPE_MAX_VALUE (t
) = TYPE_MAX_VALUE (type
);
17597 /* These types may not have declarations, so handle them here. */
17598 gimplify_type_sizes (TREE_TYPE (type
), list_p
);
17599 gimplify_type_sizes (TYPE_DOMAIN (type
), list_p
);
17600 /* Ensure VLA bounds aren't removed, for -O0 they should be variables
17601 with assigned stack slots, for -O1+ -g they should be tracked
17604 && TYPE_DOMAIN (type
)
17605 && INTEGRAL_TYPE_P (TYPE_DOMAIN (type
)))
17607 t
= TYPE_MIN_VALUE (TYPE_DOMAIN (type
));
17608 if (t
&& VAR_P (t
) && DECL_ARTIFICIAL (t
))
17609 DECL_IGNORED_P (t
) = 0;
17610 t
= TYPE_MAX_VALUE (TYPE_DOMAIN (type
));
17611 if (t
&& VAR_P (t
) && DECL_ARTIFICIAL (t
))
17612 DECL_IGNORED_P (t
) = 0;
17618 case QUAL_UNION_TYPE
:
17619 for (tree field
= TYPE_FIELDS (type
); field
; field
= DECL_CHAIN (field
))
17620 if (TREE_CODE (field
) == FIELD_DECL
)
17622 gimplify_one_sizepos (&DECL_FIELD_OFFSET (field
), list_p
);
17623 /* Likewise, ensure variable offsets aren't removed. */
17625 && (t
= DECL_FIELD_OFFSET (field
))
17627 && DECL_ARTIFICIAL (t
))
17628 DECL_IGNORED_P (t
) = 0;
17629 gimplify_one_sizepos (&DECL_SIZE (field
), list_p
);
17630 gimplify_one_sizepos (&DECL_SIZE_UNIT (field
), list_p
);
17631 gimplify_type_sizes (TREE_TYPE (field
), list_p
);
17636 case REFERENCE_TYPE
:
17637 /* We used to recurse on the pointed-to type here, which turned out to
17638 be incorrect because its definition might refer to variables not
17639 yet initialized at this point if a forward declaration is involved.
17641 It was actually useful for anonymous pointed-to types to ensure
17642 that the sizes evaluation dominates every possible later use of the
17643 values. Restricting to such types here would be safe since there
17644 is no possible forward declaration around, but would introduce an
17645 undesirable middle-end semantic to anonymity. We then defer to
17646 front-ends the responsibility of ensuring that the sizes are
17647 evaluated both early and late enough, e.g. by attaching artificial
17648 type declarations to the tree. */
17655 gimplify_one_sizepos (&TYPE_SIZE (type
), list_p
);
17656 gimplify_one_sizepos (&TYPE_SIZE_UNIT (type
), list_p
);
17658 for (t
= TYPE_NEXT_VARIANT (type
); t
; t
= TYPE_NEXT_VARIANT (t
))
17660 TYPE_SIZE (t
) = TYPE_SIZE (type
);
17661 TYPE_SIZE_UNIT (t
) = TYPE_SIZE_UNIT (type
);
17662 TYPE_SIZES_GIMPLIFIED (t
) = 1;
17666 /* A subroutine of gimplify_type_sizes to make sure that *EXPR_P,
17667 a size or position, has had all of its SAVE_EXPRs evaluated.
17668 We add any required statements to *STMT_P. */
17671 gimplify_one_sizepos (tree
*expr_p
, gimple_seq
*stmt_p
)
17673 tree expr
= *expr_p
;
17675 /* We don't do anything if the value isn't there, is constant, or contains
17676 A PLACEHOLDER_EXPR. We also don't want to do anything if it's already
17677 a VAR_DECL. If it's a VAR_DECL from another function, the gimplifier
17678 will want to replace it with a new variable, but that will cause problems
17679 if this type is from outside the function. It's OK to have that here. */
17680 if (expr
== NULL_TREE
17681 || is_gimple_constant (expr
)
17683 || CONTAINS_PLACEHOLDER_P (expr
))
17686 *expr_p
= unshare_expr (expr
);
17688 /* SSA names in decl/type fields are a bad idea - they'll get reclaimed
17689 if the def vanishes. */
17690 gimplify_expr (expr_p
, stmt_p
, NULL
, is_gimple_val
, fb_rvalue
, false);
17692 /* If expr wasn't already is_gimple_sizepos or is_gimple_constant from the
17693 FE, ensure that it is a VAR_DECL, otherwise we might handle some decls
17694 as gimplify_vla_decl even when they would have all sizes INTEGER_CSTs. */
17695 if (is_gimple_constant (*expr_p
))
17696 *expr_p
= get_initialized_tmp_var (*expr_p
, stmt_p
, NULL
, false);
17699 /* Gimplify the body of statements of FNDECL and return a GIMPLE_BIND node
17700 containing the sequence of corresponding GIMPLE statements. If DO_PARMS
17701 is true, also gimplify the parameters. */
17704 gimplify_body (tree fndecl
, bool do_parms
)
17706 location_t saved_location
= input_location
;
17707 gimple_seq parm_stmts
, parm_cleanup
= NULL
, seq
;
17708 gimple
*outer_stmt
;
17711 timevar_push (TV_TREE_GIMPLIFY
);
17713 init_tree_ssa (cfun
);
17715 /* Initialize for optimize_insn_for_s{ize,peed}_p possibly called during
17717 default_rtl_profile ();
17719 gcc_assert (gimplify_ctxp
== NULL
);
17720 push_gimplify_context (true);
17722 if (flag_openacc
|| flag_openmp
)
17724 gcc_assert (gimplify_omp_ctxp
== NULL
);
17725 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (fndecl
)))
17726 gimplify_omp_ctxp
= new_omp_context (ORT_IMPLICIT_TARGET
);
17729 /* Unshare most shared trees in the body and in that of any nested functions.
17730 It would seem we don't have to do this for nested functions because
17731 they are supposed to be output and then the outer function gimplified
17732 first, but the g++ front end doesn't always do it that way. */
17733 unshare_body (fndecl
);
17734 unvisit_body (fndecl
);
17736 /* Make sure input_location isn't set to something weird. */
17737 input_location
= DECL_SOURCE_LOCATION (fndecl
);
17739 /* Resolve callee-copies. This has to be done before processing
17740 the body so that DECL_VALUE_EXPR gets processed correctly. */
17741 parm_stmts
= do_parms
? gimplify_parameters (&parm_cleanup
) : NULL
;
17743 /* Gimplify the function's body. */
17745 gimplify_stmt (&DECL_SAVED_TREE (fndecl
), &seq
);
17746 outer_stmt
= gimple_seq_first_nondebug_stmt (seq
);
17749 outer_stmt
= gimple_build_nop ();
17750 gimplify_seq_add_stmt (&seq
, outer_stmt
);
17753 /* The body must contain exactly one statement, a GIMPLE_BIND. If this is
17754 not the case, wrap everything in a GIMPLE_BIND to make it so. */
17755 if (gimple_code (outer_stmt
) == GIMPLE_BIND
17756 && (gimple_seq_first_nondebug_stmt (seq
)
17757 == gimple_seq_last_nondebug_stmt (seq
)))
17759 outer_bind
= as_a
<gbind
*> (outer_stmt
);
17760 if (gimple_seq_first_stmt (seq
) != outer_stmt
17761 || gimple_seq_last_stmt (seq
) != outer_stmt
)
17763 /* If there are debug stmts before or after outer_stmt, move them
17764 inside of outer_bind body. */
17765 gimple_stmt_iterator gsi
= gsi_for_stmt (outer_stmt
, &seq
);
17766 gimple_seq second_seq
= NULL
;
17767 if (gimple_seq_first_stmt (seq
) != outer_stmt
17768 && gimple_seq_last_stmt (seq
) != outer_stmt
)
17770 second_seq
= gsi_split_seq_after (gsi
);
17771 gsi_remove (&gsi
, false);
17773 else if (gimple_seq_first_stmt (seq
) != outer_stmt
)
17774 gsi_remove (&gsi
, false);
17777 gsi_remove (&gsi
, false);
17781 gimple_seq_add_seq_without_update (&seq
,
17782 gimple_bind_body (outer_bind
));
17783 gimple_seq_add_seq_without_update (&seq
, second_seq
);
17784 gimple_bind_set_body (outer_bind
, seq
);
17788 outer_bind
= gimple_build_bind (NULL_TREE
, seq
, NULL
);
17790 DECL_SAVED_TREE (fndecl
) = NULL_TREE
;
17792 /* If we had callee-copies statements, insert them at the beginning
17793 of the function and clear DECL_VALUE_EXPR_P on the parameters. */
17794 if (!gimple_seq_empty_p (parm_stmts
))
17798 gimplify_seq_add_seq (&parm_stmts
, gimple_bind_body (outer_bind
));
17801 gtry
*g
= gimple_build_try (parm_stmts
, parm_cleanup
,
17802 GIMPLE_TRY_FINALLY
);
17804 gimple_seq_add_stmt (&parm_stmts
, g
);
17806 gimple_bind_set_body (outer_bind
, parm_stmts
);
17808 for (parm
= DECL_ARGUMENTS (current_function_decl
);
17809 parm
; parm
= DECL_CHAIN (parm
))
17810 if (DECL_HAS_VALUE_EXPR_P (parm
))
17812 DECL_HAS_VALUE_EXPR_P (parm
) = 0;
17813 DECL_IGNORED_P (parm
) = 0;
17817 if ((flag_openacc
|| flag_openmp
|| flag_openmp_simd
)
17818 && gimplify_omp_ctxp
)
17820 delete_omp_context (gimplify_omp_ctxp
);
17821 gimplify_omp_ctxp
= NULL
;
17824 pop_gimplify_context (outer_bind
);
17825 gcc_assert (gimplify_ctxp
== NULL
);
17827 if (flag_checking
&& !seen_error ())
17828 verify_gimple_in_seq (gimple_bind_body (outer_bind
));
17830 timevar_pop (TV_TREE_GIMPLIFY
);
17831 input_location
= saved_location
;
17836 typedef char *char_p
; /* For DEF_VEC_P. */
17838 /* Return whether we should exclude FNDECL from instrumentation. */
17841 flag_instrument_functions_exclude_p (tree fndecl
)
17845 v
= (vec
<char_p
> *) flag_instrument_functions_exclude_functions
;
17846 if (v
&& v
->length () > 0)
17852 name
= lang_hooks
.decl_printable_name (fndecl
, 1);
17853 FOR_EACH_VEC_ELT (*v
, i
, s
)
17854 if (strstr (name
, s
) != NULL
)
17858 v
= (vec
<char_p
> *) flag_instrument_functions_exclude_files
;
17859 if (v
&& v
->length () > 0)
17865 name
= DECL_SOURCE_FILE (fndecl
);
17866 FOR_EACH_VEC_ELT (*v
, i
, s
)
17867 if (strstr (name
, s
) != NULL
)
17874 /* Build a call to the instrumentation function FNCODE and add it to SEQ.
17875 If COND_VAR is not NULL, it is a boolean variable guarding the call to
17876 the instrumentation function. IF STMT is not NULL, it is a statement
17877 to be executed just before the call to the instrumentation function. */
17880 build_instrumentation_call (gimple_seq
*seq
, enum built_in_function fncode
,
17881 tree cond_var
, gimple
*stmt
)
17883 /* The instrumentation hooks aren't going to call the instrumented
17884 function and the address they receive is expected to be matchable
17885 against symbol addresses. Make sure we don't create a trampoline,
17886 in case the current function is nested. */
17887 tree this_fn_addr
= build_fold_addr_expr (current_function_decl
);
17888 TREE_NO_TRAMPOLINE (this_fn_addr
) = 1;
17890 tree label_true
, label_false
;
17893 label_true
= create_artificial_label (UNKNOWN_LOCATION
);
17894 label_false
= create_artificial_label (UNKNOWN_LOCATION
);
17895 gcond
*cond
= gimple_build_cond (EQ_EXPR
, cond_var
, boolean_false_node
,
17896 label_true
, label_false
);
17897 gimplify_seq_add_stmt (seq
, cond
);
17898 gimplify_seq_add_stmt (seq
, gimple_build_label (label_true
));
17899 gimplify_seq_add_stmt (seq
, gimple_build_predict (PRED_COLD_LABEL
,
17904 gimplify_seq_add_stmt (seq
, stmt
);
17906 tree x
= builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS
);
17907 gcall
*call
= gimple_build_call (x
, 1, integer_zero_node
);
17908 tree tmp_var
= create_tmp_var (ptr_type_node
, "return_addr");
17909 gimple_call_set_lhs (call
, tmp_var
);
17910 gimplify_seq_add_stmt (seq
, call
);
17911 x
= builtin_decl_implicit (fncode
);
17912 call
= gimple_build_call (x
, 2, this_fn_addr
, tmp_var
);
17913 gimplify_seq_add_stmt (seq
, call
);
17916 gimplify_seq_add_stmt (seq
, gimple_build_label (label_false
));
17919 /* Entry point to the gimplification pass. FNDECL is the FUNCTION_DECL
17920 node for the function we want to gimplify.
17922 Return the sequence of GIMPLE statements corresponding to the body
17926 gimplify_function_tree (tree fndecl
)
17931 gcc_assert (!gimple_body (fndecl
));
17933 if (DECL_STRUCT_FUNCTION (fndecl
))
17934 push_cfun (DECL_STRUCT_FUNCTION (fndecl
));
17936 push_struct_function (fndecl
);
17938 /* Tentatively set PROP_gimple_lva here, and reset it in gimplify_va_arg_expr
17940 cfun
->curr_properties
|= PROP_gimple_lva
;
17942 if (asan_sanitize_use_after_scope ())
17943 asan_poisoned_variables
= new hash_set
<tree
> ();
17944 bind
= gimplify_body (fndecl
, true);
17945 if (asan_poisoned_variables
)
17947 delete asan_poisoned_variables
;
17948 asan_poisoned_variables
= NULL
;
17951 /* The tree body of the function is no longer needed, replace it
17952 with the new GIMPLE body. */
17954 gimple_seq_add_stmt (&seq
, bind
);
17955 gimple_set_body (fndecl
, seq
);
17957 /* If we're instrumenting function entry/exit, then prepend the call to
17958 the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to
17959 catch the exit hook. */
17960 /* ??? Add some way to ignore exceptions for this TFE. */
17961 if (flag_instrument_function_entry_exit
17962 && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl
)
17963 /* Do not instrument extern inline functions. */
17964 && !(DECL_DECLARED_INLINE_P (fndecl
)
17965 && DECL_EXTERNAL (fndecl
)
17966 && DECL_DISREGARD_INLINE_LIMITS (fndecl
))
17967 && !flag_instrument_functions_exclude_p (fndecl
))
17969 gimple_seq body
= NULL
, cleanup
= NULL
;
17973 /* If -finstrument-functions-once is specified, generate:
17975 static volatile bool C.0 = false;
17982 [call profiling enter function]
17985 without specific protection for data races. */
17986 if (flag_instrument_function_entry_exit
> 1)
17989 = build_decl (DECL_SOURCE_LOCATION (current_function_decl
),
17991 create_tmp_var_name ("C"),
17992 boolean_type_node
);
17993 DECL_ARTIFICIAL (first_var
) = 1;
17994 DECL_IGNORED_P (first_var
) = 1;
17995 TREE_STATIC (first_var
) = 1;
17996 TREE_THIS_VOLATILE (first_var
) = 1;
17997 TREE_USED (first_var
) = 1;
17998 DECL_INITIAL (first_var
) = boolean_false_node
;
17999 varpool_node::add (first_var
);
18001 cond_var
= create_tmp_var (boolean_type_node
, "tmp_called");
18002 assign
= gimple_build_assign (cond_var
, first_var
);
18003 gimplify_seq_add_stmt (&body
, assign
);
18005 assign
= gimple_build_assign (first_var
, boolean_true_node
);
18010 cond_var
= NULL_TREE
;
18014 build_instrumentation_call (&body
, BUILT_IN_PROFILE_FUNC_ENTER
,
18017 /* If -finstrument-functions-once is specified, generate:
18020 [call profiling exit function]
18022 without specific protection for data races. */
18023 build_instrumentation_call (&cleanup
, BUILT_IN_PROFILE_FUNC_EXIT
,
18026 gimple
*tf
= gimple_build_try (seq
, cleanup
, GIMPLE_TRY_FINALLY
);
18027 gimplify_seq_add_stmt (&body
, tf
);
18028 gbind
*new_bind
= gimple_build_bind (NULL
, body
, NULL
);
18030 /* Replace the current function body with the body
18031 wrapped in the try/finally TF. */
18033 gimple_seq_add_stmt (&seq
, new_bind
);
18034 gimple_set_body (fndecl
, seq
);
18038 if (sanitize_flags_p (SANITIZE_THREAD
)
18039 && param_tsan_instrument_func_entry_exit
)
18041 gcall
*call
= gimple_build_call_internal (IFN_TSAN_FUNC_EXIT
, 0);
18042 gimple
*tf
= gimple_build_try (seq
, call
, GIMPLE_TRY_FINALLY
);
18043 gbind
*new_bind
= gimple_build_bind (NULL
, tf
, NULL
);
18044 /* Replace the current function body with the body
18045 wrapped in the try/finally TF. */
18047 gimple_seq_add_stmt (&seq
, new_bind
);
18048 gimple_set_body (fndecl
, seq
);
18051 DECL_SAVED_TREE (fndecl
) = NULL_TREE
;
18052 cfun
->curr_properties
|= PROP_gimple_any
;
18056 dump_function (TDI_gimple
, fndecl
);
18059 /* Return a dummy expression of type TYPE in order to keep going after an
18063 dummy_object (tree type
)
18065 tree t
= build_int_cst (build_pointer_type (type
), 0);
18066 return build2 (MEM_REF
, type
, t
, t
);
18069 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
18070 builtin function, but a very special sort of operator. */
18072 enum gimplify_status
18073 gimplify_va_arg_expr (tree
*expr_p
, gimple_seq
*pre_p
,
18074 gimple_seq
*post_p ATTRIBUTE_UNUSED
)
18076 tree promoted_type
, have_va_type
;
18077 tree valist
= TREE_OPERAND (*expr_p
, 0);
18078 tree type
= TREE_TYPE (*expr_p
);
18079 tree t
, tag
, aptag
;
18080 location_t loc
= EXPR_LOCATION (*expr_p
);
18082 /* Verify that valist is of the proper type. */
18083 have_va_type
= TREE_TYPE (valist
);
18084 if (have_va_type
== error_mark_node
)
18086 have_va_type
= targetm
.canonical_va_list_type (have_va_type
);
18087 if (have_va_type
== NULL_TREE
18088 && POINTER_TYPE_P (TREE_TYPE (valist
)))
18089 /* Handle 'Case 1: Not an array type' from c-common.cc/build_va_arg. */
18091 = targetm
.canonical_va_list_type (TREE_TYPE (TREE_TYPE (valist
)));
18092 gcc_assert (have_va_type
!= NULL_TREE
);
18094 /* Generate a diagnostic for requesting data of a type that cannot
18095 be passed through `...' due to type promotion at the call site. */
18096 if ((promoted_type
= lang_hooks
.types
.type_promotes_to (type
))
18099 static bool gave_help
;
18101 /* Use the expansion point to handle cases such as passing bool (defined
18102 in a system header) through `...'. */
18104 = expansion_point_location_if_in_system_header (loc
);
18106 /* Unfortunately, this is merely undefined, rather than a constraint
18107 violation, so we cannot make this an error. If this call is never
18108 executed, the program is still strictly conforming. */
18109 auto_diagnostic_group d
;
18110 warned
= warning_at (xloc
, 0,
18111 "%qT is promoted to %qT when passed through %<...%>",
18112 type
, promoted_type
);
18113 if (!gave_help
&& warned
)
18116 inform (xloc
, "(so you should pass %qT not %qT to %<va_arg%>)",
18117 promoted_type
, type
);
18120 /* We can, however, treat "undefined" any way we please.
18121 Call abort to encourage the user to fix the program. */
18123 inform (xloc
, "if this code is reached, the program will abort");
18124 /* Before the abort, allow the evaluation of the va_list
18125 expression to exit or longjmp. */
18126 gimplify_and_add (valist
, pre_p
);
18127 t
= build_call_expr_loc (loc
,
18128 builtin_decl_implicit (BUILT_IN_TRAP
), 0);
18129 gimplify_and_add (t
, pre_p
);
18131 /* This is dead code, but go ahead and finish so that the
18132 mode of the result comes out right. */
18133 *expr_p
= dummy_object (type
);
18134 return GS_ALL_DONE
;
18137 tag
= build_int_cst (build_pointer_type (type
), 0);
18138 aptag
= build_int_cst (TREE_TYPE (valist
), 0);
18140 *expr_p
= build_call_expr_internal_loc (loc
, IFN_VA_ARG
, type
, 3,
18141 valist
, tag
, aptag
);
18143 /* Clear the tentatively set PROP_gimple_lva, to indicate that IFN_VA_ARG
18144 needs to be expanded. */
18145 cfun
->curr_properties
&= ~PROP_gimple_lva
;
18150 /* Build a new GIMPLE_ASSIGN tuple and append it to the end of *SEQ_P.
18152 DST/SRC are the destination and source respectively. You can pass
18153 ungimplified trees in DST or SRC, in which case they will be
18154 converted to a gimple operand if necessary.
18156 This function returns the newly created GIMPLE_ASSIGN tuple. */
18159 gimplify_assign (tree dst
, tree src
, gimple_seq
*seq_p
)
18161 tree t
= build2 (MODIFY_EXPR
, TREE_TYPE (dst
), dst
, src
);
18162 gimplify_and_add (t
, seq_p
);
18164 return gimple_seq_last_stmt (*seq_p
);
18168 gimplify_hasher::hash (const elt_t
*p
)
18171 return iterative_hash_expr (t
, 0);
18175 gimplify_hasher::equal (const elt_t
*p1
, const elt_t
*p2
)
18179 enum tree_code code
= TREE_CODE (t1
);
18181 if (TREE_CODE (t2
) != code
18182 || TREE_TYPE (t1
) != TREE_TYPE (t2
))
18185 if (!operand_equal_p (t1
, t2
, 0))
18188 /* Only allow them to compare equal if they also hash equal; otherwise
18189 results are nondeterminate, and we fail bootstrap comparison. */
18190 gcc_checking_assert (hash (p1
) == hash (p2
));