1 /* Tree lowering pass. This pass converts the GENERIC functions-as-trees
2 tree representation into the GIMPLE form.
3 Copyright (C) 2002-2018 Free Software Foundation, Inc.
4 Major work done by Sebastian Pop <s.pop@laposte.net>,
5 Diego Novillo <dnovillo@redhat.com> and Jason Merrill <jason@redhat.com>.
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
25 #include "coretypes.h"
33 #include "gimple-predict.h"
34 #include "tree-pass.h" /* FIXME: only for PROP_gimple_any */
37 #include "tree-pretty-print.h"
38 #include "diagnostic-core.h"
40 #include "fold-const.h"
45 #include "gimple-fold.h"
48 #include "gimple-iterator.h"
49 #include "stor-layout.h"
50 #include "print-tree.h"
51 #include "tree-iterator.h"
52 #include "tree-inline.h"
53 #include "langhooks.h"
56 #include "omp-general.h"
58 #include "gimple-low.h"
59 #include "gomp-constants.h"
60 #include "splay-tree.h"
61 #include "gimple-walk.h"
62 #include "langhooks-def.h" /* FIXME: for lhd_set_decl_assembler_name */
64 #include "stringpool.h"
69 /* Hash set of poisoned variables in a bind expr. */
70 static hash_set
<tree
> *asan_poisoned_variables
= NULL
;
72 enum gimplify_omp_var_data
78 GOVD_FIRSTPRIVATE
= 16,
79 GOVD_LASTPRIVATE
= 32,
83 GOVD_DEBUG_PRIVATE
= 512,
84 GOVD_PRIVATE_OUTER_REF
= 1024,
88 /* Flag for GOVD_MAP: don't copy back. */
89 GOVD_MAP_TO_ONLY
= 8192,
91 /* Flag for GOVD_LINEAR or GOVD_LASTPRIVATE: no outer reference. */
92 GOVD_LINEAR_LASTPRIVATE_NO_OUTER
= 16384,
94 GOVD_MAP_0LEN_ARRAY
= 32768,
96 /* Flag for GOVD_MAP, if it is always, to or always, tofrom mapping. */
97 GOVD_MAP_ALWAYS_TO
= 65536,
99 /* Flag for shared vars that are or might be stored to in the region. */
100 GOVD_WRITTEN
= 131072,
102 /* Flag for GOVD_MAP, if it is a forced mapping. */
103 GOVD_MAP_FORCE
= 262144,
105 /* Flag for GOVD_MAP: must be present already. */
106 GOVD_MAP_FORCE_PRESENT
= 524288,
108 /* Flag for GOVD_MAP: only allocate. */
109 GOVD_MAP_ALLOC_ONLY
= 1048576,
111 /* Flag for GOVD_MAP: only copy back. */
112 GOVD_MAP_FROM_ONLY
= 2097152,
114 GOVD_NONTEMPORAL
= 4194304,
116 GOVD_DATA_SHARE_CLASS
= (GOVD_SHARED
| GOVD_PRIVATE
| GOVD_FIRSTPRIVATE
117 | GOVD_LASTPRIVATE
| GOVD_REDUCTION
| GOVD_LINEAR
124 ORT_WORKSHARE
= 0x00,
125 ORT_TASKGROUP
= 0x01,
129 ORT_COMBINED_PARALLEL
= ORT_PARALLEL
| 1,
132 ORT_UNTIED_TASK
= ORT_TASK
| 1,
133 ORT_TASKLOOP
= ORT_TASK
| 2,
134 ORT_UNTIED_TASKLOOP
= ORT_UNTIED_TASK
| 2,
137 ORT_COMBINED_TEAMS
= ORT_TEAMS
| 1,
138 ORT_HOST_TEAMS
= ORT_TEAMS
| 2,
139 ORT_COMBINED_HOST_TEAMS
= ORT_COMBINED_TEAMS
| 2,
142 ORT_TARGET_DATA
= 0x40,
144 /* Data region with offloading. */
146 ORT_COMBINED_TARGET
= ORT_TARGET
| 1,
148 /* OpenACC variants. */
149 ORT_ACC
= 0x100, /* A generic OpenACC region. */
150 ORT_ACC_DATA
= ORT_ACC
| ORT_TARGET_DATA
, /* Data construct. */
151 ORT_ACC_PARALLEL
= ORT_ACC
| ORT_TARGET
, /* Parallel construct */
152 ORT_ACC_KERNELS
= ORT_ACC
| ORT_TARGET
| 2, /* Kernels construct. */
153 ORT_ACC_HOST_DATA
= ORT_ACC
| ORT_TARGET_DATA
| 2, /* Host data. */
155 /* Dummy OpenMP region, used to disable expansion of
156 DECL_VALUE_EXPRs in taskloop pre body. */
160 /* Gimplify hashtable helper. */
162 struct gimplify_hasher
: free_ptr_hash
<elt_t
>
164 static inline hashval_t
hash (const elt_t
*);
165 static inline bool equal (const elt_t
*, const elt_t
*);
170 struct gimplify_ctx
*prev_context
;
172 vec
<gbind
*> bind_expr_stack
;
174 gimple_seq conditional_cleanups
;
178 vec
<tree
> case_labels
;
179 hash_set
<tree
> *live_switch_vars
;
180 /* The formal temporary table. Should this be persistent? */
181 hash_table
<gimplify_hasher
> *temp_htab
;
184 unsigned into_ssa
: 1;
185 unsigned allow_rhs_cond_expr
: 1;
186 unsigned in_cleanup_point_expr
: 1;
187 unsigned keep_stack
: 1;
188 unsigned save_stack
: 1;
189 unsigned in_switch_expr
: 1;
192 enum gimplify_defaultmap_kind
200 struct gimplify_omp_ctx
202 struct gimplify_omp_ctx
*outer_context
;
203 splay_tree variables
;
204 hash_set
<tree
> *privatized_types
;
205 /* Iteration variables in an OMP_FOR. */
206 vec
<tree
> loop_iter_var
;
208 enum omp_clause_default_kind default_kind
;
209 enum omp_region_type region_type
;
212 bool target_firstprivatize_array_bases
;
216 static struct gimplify_ctx
*gimplify_ctxp
;
217 static struct gimplify_omp_ctx
*gimplify_omp_ctxp
;
219 /* Forward declaration. */
220 static enum gimplify_status
gimplify_compound_expr (tree
*, gimple_seq
*, bool);
221 static hash_map
<tree
, tree
> *oacc_declare_returns
;
222 static enum gimplify_status
gimplify_expr (tree
*, gimple_seq
*, gimple_seq
*,
223 bool (*) (tree
), fallback_t
, bool);
225 /* Shorter alias name for the above function for use in gimplify.c
229 gimplify_seq_add_stmt (gimple_seq
*seq_p
, gimple
*gs
)
231 gimple_seq_add_stmt_without_update (seq_p
, gs
);
234 /* Append sequence SRC to the end of sequence *DST_P. If *DST_P is
235 NULL, a new sequence is allocated. This function is
236 similar to gimple_seq_add_seq, but does not scan the operands.
237 During gimplification, we need to manipulate statement sequences
238 before the def/use vectors have been constructed. */
241 gimplify_seq_add_seq (gimple_seq
*dst_p
, gimple_seq src
)
243 gimple_stmt_iterator si
;
248 si
= gsi_last (*dst_p
);
249 gsi_insert_seq_after_without_update (&si
, src
, GSI_NEW_STMT
);
253 /* Pointer to a list of allocated gimplify_ctx structs to be used for pushing
254 and popping gimplify contexts. */
256 static struct gimplify_ctx
*ctx_pool
= NULL
;
258 /* Return a gimplify context struct from the pool. */
260 static inline struct gimplify_ctx
*
263 struct gimplify_ctx
* c
= ctx_pool
;
266 ctx_pool
= c
->prev_context
;
268 c
= XNEW (struct gimplify_ctx
);
270 memset (c
, '\0', sizeof (*c
));
274 /* Put gimplify context C back into the pool. */
277 ctx_free (struct gimplify_ctx
*c
)
279 c
->prev_context
= ctx_pool
;
283 /* Free allocated ctx stack memory. */
286 free_gimplify_stack (void)
288 struct gimplify_ctx
*c
;
290 while ((c
= ctx_pool
))
292 ctx_pool
= c
->prev_context
;
298 /* Set up a context for the gimplifier. */
301 push_gimplify_context (bool in_ssa
, bool rhs_cond_ok
)
303 struct gimplify_ctx
*c
= ctx_alloc ();
305 c
->prev_context
= gimplify_ctxp
;
307 gimplify_ctxp
->into_ssa
= in_ssa
;
308 gimplify_ctxp
->allow_rhs_cond_expr
= rhs_cond_ok
;
311 /* Tear down a context for the gimplifier. If BODY is non-null, then
312 put the temporaries into the outer BIND_EXPR. Otherwise, put them
315 BODY is not a sequence, but the first tuple in a sequence. */
318 pop_gimplify_context (gimple
*body
)
320 struct gimplify_ctx
*c
= gimplify_ctxp
;
323 && (!c
->bind_expr_stack
.exists ()
324 || c
->bind_expr_stack
.is_empty ()));
325 c
->bind_expr_stack
.release ();
326 gimplify_ctxp
= c
->prev_context
;
329 declare_vars (c
->temps
, body
, false);
331 record_vars (c
->temps
);
338 /* Push a GIMPLE_BIND tuple onto the stack of bindings. */
341 gimple_push_bind_expr (gbind
*bind_stmt
)
343 gimplify_ctxp
->bind_expr_stack
.reserve (8);
344 gimplify_ctxp
->bind_expr_stack
.safe_push (bind_stmt
);
347 /* Pop the first element off the stack of bindings. */
350 gimple_pop_bind_expr (void)
352 gimplify_ctxp
->bind_expr_stack
.pop ();
355 /* Return the first element of the stack of bindings. */
358 gimple_current_bind_expr (void)
360 return gimplify_ctxp
->bind_expr_stack
.last ();
363 /* Return the stack of bindings created during gimplification. */
366 gimple_bind_expr_stack (void)
368 return gimplify_ctxp
->bind_expr_stack
;
371 /* Return true iff there is a COND_EXPR between us and the innermost
372 CLEANUP_POINT_EXPR. This info is used by gimple_push_cleanup. */
375 gimple_conditional_context (void)
377 return gimplify_ctxp
->conditions
> 0;
380 /* Note that we've entered a COND_EXPR. */
383 gimple_push_condition (void)
385 #ifdef ENABLE_GIMPLE_CHECKING
386 if (gimplify_ctxp
->conditions
== 0)
387 gcc_assert (gimple_seq_empty_p (gimplify_ctxp
->conditional_cleanups
));
389 ++(gimplify_ctxp
->conditions
);
392 /* Note that we've left a COND_EXPR. If we're back at unconditional scope
393 now, add any conditional cleanups we've seen to the prequeue. */
396 gimple_pop_condition (gimple_seq
*pre_p
)
398 int conds
= --(gimplify_ctxp
->conditions
);
400 gcc_assert (conds
>= 0);
403 gimplify_seq_add_seq (pre_p
, gimplify_ctxp
->conditional_cleanups
);
404 gimplify_ctxp
->conditional_cleanups
= NULL
;
408 /* A stable comparison routine for use with splay trees and DECLs. */
411 splay_tree_compare_decl_uid (splay_tree_key xa
, splay_tree_key xb
)
416 return DECL_UID (a
) - DECL_UID (b
);
419 /* Create a new omp construct that deals with variable remapping. */
421 static struct gimplify_omp_ctx
*
422 new_omp_context (enum omp_region_type region_type
)
424 struct gimplify_omp_ctx
*c
;
426 c
= XCNEW (struct gimplify_omp_ctx
);
427 c
->outer_context
= gimplify_omp_ctxp
;
428 c
->variables
= splay_tree_new (splay_tree_compare_decl_uid
, 0, 0);
429 c
->privatized_types
= new hash_set
<tree
>;
430 c
->location
= input_location
;
431 c
->region_type
= region_type
;
432 if ((region_type
& ORT_TASK
) == 0)
433 c
->default_kind
= OMP_CLAUSE_DEFAULT_SHARED
;
435 c
->default_kind
= OMP_CLAUSE_DEFAULT_UNSPECIFIED
;
436 c
->defaultmap
[GDMK_SCALAR
] = GOVD_MAP
;
437 c
->defaultmap
[GDMK_AGGREGATE
] = GOVD_MAP
;
438 c
->defaultmap
[GDMK_ALLOCATABLE
] = GOVD_MAP
;
439 c
->defaultmap
[GDMK_POINTER
] = GOVD_MAP
;
444 /* Destroy an omp construct that deals with variable remapping. */
447 delete_omp_context (struct gimplify_omp_ctx
*c
)
449 splay_tree_delete (c
->variables
);
450 delete c
->privatized_types
;
451 c
->loop_iter_var
.release ();
455 static void omp_add_variable (struct gimplify_omp_ctx
*, tree
, unsigned int);
456 static bool omp_notice_variable (struct gimplify_omp_ctx
*, tree
, bool);
458 /* Both gimplify the statement T and append it to *SEQ_P. This function
459 behaves exactly as gimplify_stmt, but you don't have to pass T as a
463 gimplify_and_add (tree t
, gimple_seq
*seq_p
)
465 gimplify_stmt (&t
, seq_p
);
468 /* Gimplify statement T into sequence *SEQ_P, and return the first
469 tuple in the sequence of generated tuples for this statement.
470 Return NULL if gimplifying T produced no tuples. */
473 gimplify_and_return_first (tree t
, gimple_seq
*seq_p
)
475 gimple_stmt_iterator last
= gsi_last (*seq_p
);
477 gimplify_and_add (t
, seq_p
);
479 if (!gsi_end_p (last
))
482 return gsi_stmt (last
);
485 return gimple_seq_first_stmt (*seq_p
);
488 /* Returns true iff T is a valid RHS for an assignment to an un-renamed
489 LHS, or for a call argument. */
492 is_gimple_mem_rhs (tree t
)
494 /* If we're dealing with a renamable type, either source or dest must be
495 a renamed variable. */
496 if (is_gimple_reg_type (TREE_TYPE (t
)))
497 return is_gimple_val (t
);
499 return is_gimple_val (t
) || is_gimple_lvalue (t
);
502 /* Return true if T is a CALL_EXPR or an expression that can be
503 assigned to a temporary. Note that this predicate should only be
504 used during gimplification. See the rationale for this in
505 gimplify_modify_expr. */
508 is_gimple_reg_rhs_or_call (tree t
)
510 return (get_gimple_rhs_class (TREE_CODE (t
)) != GIMPLE_INVALID_RHS
511 || TREE_CODE (t
) == CALL_EXPR
);
514 /* Return true if T is a valid memory RHS or a CALL_EXPR. Note that
515 this predicate should only be used during gimplification. See the
516 rationale for this in gimplify_modify_expr. */
519 is_gimple_mem_rhs_or_call (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
)
527 || is_gimple_lvalue (t
)
528 || TREE_CLOBBER_P (t
)
529 || TREE_CODE (t
) == CALL_EXPR
);
532 /* Create a temporary with a name derived from VAL. Subroutine of
533 lookup_tmp_var; nobody else should call this function. */
536 create_tmp_from_val (tree val
)
538 /* Drop all qualifiers and address-space information from the value type. */
539 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (val
));
540 tree var
= create_tmp_var (type
, get_name (val
));
541 if (TREE_CODE (TREE_TYPE (var
)) == COMPLEX_TYPE
542 || TREE_CODE (TREE_TYPE (var
)) == VECTOR_TYPE
)
543 DECL_GIMPLE_REG_P (var
) = 1;
547 /* Create a temporary to hold the value of VAL. If IS_FORMAL, try to reuse
548 an existing expression temporary. */
551 lookup_tmp_var (tree val
, bool is_formal
)
555 /* If not optimizing, never really reuse a temporary. local-alloc
556 won't allocate any variable that is used in more than one basic
557 block, which means it will go into memory, causing much extra
558 work in reload and final and poorer code generation, outweighing
559 the extra memory allocation here. */
560 if (!optimize
|| !is_formal
|| TREE_SIDE_EFFECTS (val
))
561 ret
= create_tmp_from_val (val
);
568 if (!gimplify_ctxp
->temp_htab
)
569 gimplify_ctxp
->temp_htab
= new hash_table
<gimplify_hasher
> (1000);
570 slot
= gimplify_ctxp
->temp_htab
->find_slot (&elt
, INSERT
);
573 elt_p
= XNEW (elt_t
);
575 elt_p
->temp
= ret
= create_tmp_from_val (val
);
588 /* Helper for get_formal_tmp_var and get_initialized_tmp_var. */
591 internal_get_tmp_var (tree val
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
592 bool is_formal
, bool allow_ssa
)
596 /* Notice that we explicitly allow VAL to be a CALL_EXPR so that we
597 can create an INIT_EXPR and convert it into a GIMPLE_CALL below. */
598 gimplify_expr (&val
, pre_p
, post_p
, is_gimple_reg_rhs_or_call
,
602 && gimplify_ctxp
->into_ssa
603 && is_gimple_reg_type (TREE_TYPE (val
)))
605 t
= make_ssa_name (TYPE_MAIN_VARIANT (TREE_TYPE (val
)));
606 if (! gimple_in_ssa_p (cfun
))
608 const char *name
= get_name (val
);
610 SET_SSA_NAME_VAR_OR_IDENTIFIER (t
, create_tmp_var_name (name
));
614 t
= lookup_tmp_var (val
, is_formal
);
616 mod
= build2 (INIT_EXPR
, TREE_TYPE (t
), t
, unshare_expr (val
));
618 SET_EXPR_LOCATION (mod
, EXPR_LOC_OR_LOC (val
, input_location
));
620 /* gimplify_modify_expr might want to reduce this further. */
621 gimplify_and_add (mod
, pre_p
);
627 /* Return a formal temporary variable initialized with VAL. PRE_P is as
628 in gimplify_expr. Only use this function if:
630 1) The value of the unfactored expression represented by VAL will not
631 change between the initialization and use of the temporary, and
632 2) The temporary will not be otherwise modified.
634 For instance, #1 means that this is inappropriate for SAVE_EXPR temps,
635 and #2 means it is inappropriate for && temps.
637 For other cases, use get_initialized_tmp_var instead. */
640 get_formal_tmp_var (tree val
, gimple_seq
*pre_p
)
642 return internal_get_tmp_var (val
, pre_p
, NULL
, true, true);
645 /* Return a temporary variable initialized with VAL. PRE_P and POST_P
646 are as in gimplify_expr. */
649 get_initialized_tmp_var (tree val
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
652 return internal_get_tmp_var (val
, pre_p
, post_p
, false, allow_ssa
);
655 /* Declare all the variables in VARS in SCOPE. If DEBUG_INFO is true,
656 generate debug info for them; otherwise don't. */
659 declare_vars (tree vars
, gimple
*gs
, bool debug_info
)
666 gbind
*scope
= as_a
<gbind
*> (gs
);
668 temps
= nreverse (last
);
670 block
= gimple_bind_block (scope
);
671 gcc_assert (!block
|| TREE_CODE (block
) == BLOCK
);
672 if (!block
|| !debug_info
)
674 DECL_CHAIN (last
) = gimple_bind_vars (scope
);
675 gimple_bind_set_vars (scope
, temps
);
679 /* We need to attach the nodes both to the BIND_EXPR and to its
680 associated BLOCK for debugging purposes. The key point here
681 is that the BLOCK_VARS of the BIND_EXPR_BLOCK of a BIND_EXPR
682 is a subchain of the BIND_EXPR_VARS of the BIND_EXPR. */
683 if (BLOCK_VARS (block
))
684 BLOCK_VARS (block
) = chainon (BLOCK_VARS (block
), temps
);
687 gimple_bind_set_vars (scope
,
688 chainon (gimple_bind_vars (scope
), temps
));
689 BLOCK_VARS (block
) = temps
;
695 /* For VAR a VAR_DECL of variable size, try to find a constant upper bound
696 for the size and adjust DECL_SIZE/DECL_SIZE_UNIT accordingly. Abort if
697 no such upper bound can be obtained. */
700 force_constant_size (tree var
)
702 /* The only attempt we make is by querying the maximum size of objects
703 of the variable's type. */
705 HOST_WIDE_INT max_size
;
707 gcc_assert (VAR_P (var
));
709 max_size
= max_int_size_in_bytes (TREE_TYPE (var
));
711 gcc_assert (max_size
>= 0);
714 = build_int_cst (TREE_TYPE (DECL_SIZE_UNIT (var
)), max_size
);
716 = build_int_cst (TREE_TYPE (DECL_SIZE (var
)), max_size
* BITS_PER_UNIT
);
719 /* Push the temporary variable TMP into the current binding. */
722 gimple_add_tmp_var_fn (struct function
*fn
, tree tmp
)
724 gcc_assert (!DECL_CHAIN (tmp
) && !DECL_SEEN_IN_BIND_EXPR_P (tmp
));
726 /* Later processing assumes that the object size is constant, which might
727 not be true at this point. Force the use of a constant upper bound in
729 if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp
)))
730 force_constant_size (tmp
);
732 DECL_CONTEXT (tmp
) = fn
->decl
;
733 DECL_SEEN_IN_BIND_EXPR_P (tmp
) = 1;
735 record_vars_into (tmp
, fn
->decl
);
738 /* Push the temporary variable TMP into the current binding. */
741 gimple_add_tmp_var (tree tmp
)
743 gcc_assert (!DECL_CHAIN (tmp
) && !DECL_SEEN_IN_BIND_EXPR_P (tmp
));
745 /* Later processing assumes that the object size is constant, which might
746 not be true at this point. Force the use of a constant upper bound in
748 if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp
)))
749 force_constant_size (tmp
);
751 DECL_CONTEXT (tmp
) = current_function_decl
;
752 DECL_SEEN_IN_BIND_EXPR_P (tmp
) = 1;
756 DECL_CHAIN (tmp
) = gimplify_ctxp
->temps
;
757 gimplify_ctxp
->temps
= tmp
;
759 /* Mark temporaries local within the nearest enclosing parallel. */
760 if (gimplify_omp_ctxp
)
762 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
764 && (ctx
->region_type
== ORT_WORKSHARE
765 || ctx
->region_type
== ORT_TASKGROUP
766 || ctx
->region_type
== ORT_SIMD
767 || ctx
->region_type
== ORT_ACC
))
768 ctx
= ctx
->outer_context
;
770 omp_add_variable (ctx
, tmp
, GOVD_LOCAL
| GOVD_SEEN
);
779 /* This case is for nested functions. We need to expose the locals
781 body_seq
= gimple_body (current_function_decl
);
782 declare_vars (tmp
, gimple_seq_first_stmt (body_seq
), false);
788 /* This page contains routines to unshare tree nodes, i.e. to duplicate tree
789 nodes that are referenced more than once in GENERIC functions. This is
790 necessary because gimplification (translation into GIMPLE) is performed
791 by modifying tree nodes in-place, so gimplication of a shared node in a
792 first context could generate an invalid GIMPLE form in a second context.
794 This is achieved with a simple mark/copy/unmark algorithm that walks the
795 GENERIC representation top-down, marks nodes with TREE_VISITED the first
796 time it encounters them, duplicates them if they already have TREE_VISITED
797 set, and finally removes the TREE_VISITED marks it has set.
799 The algorithm works only at the function level, i.e. it generates a GENERIC
800 representation of a function with no nodes shared within the function when
801 passed a GENERIC function (except for nodes that are allowed to be shared).
803 At the global level, it is also necessary to unshare tree nodes that are
804 referenced in more than one function, for the same aforementioned reason.
805 This requires some cooperation from the front-end. There are 2 strategies:
807 1. Manual unsharing. The front-end needs to call unshare_expr on every
808 expression that might end up being shared across functions.
810 2. Deep unsharing. This is an extension of regular unsharing. Instead
811 of calling unshare_expr on expressions that might be shared across
812 functions, the front-end pre-marks them with TREE_VISITED. This will
813 ensure that they are unshared on the first reference within functions
814 when the regular unsharing algorithm runs. The counterpart is that
815 this algorithm must look deeper than for manual unsharing, which is
816 specified by LANG_HOOKS_DEEP_UNSHARING.
818 If there are only few specific cases of node sharing across functions, it is
819 probably easier for a front-end to unshare the expressions manually. On the
820 contrary, if the expressions generated at the global level are as widespread
821 as expressions generated within functions, deep unsharing is very likely the
824 /* Similar to copy_tree_r but do not copy SAVE_EXPR or TARGET_EXPR nodes.
825 These nodes model computations that must be done once. If we were to
826 unshare something like SAVE_EXPR(i++), the gimplification process would
827 create wrong code. However, if DATA is non-null, it must hold a pointer
828 set that is used to unshare the subtrees of these nodes. */
831 mostly_copy_tree_r (tree
*tp
, int *walk_subtrees
, void *data
)
834 enum tree_code code
= TREE_CODE (t
);
836 /* Do not copy SAVE_EXPR, TARGET_EXPR or BIND_EXPR nodes themselves, but
837 copy their subtrees if we can make sure to do it only once. */
838 if (code
== SAVE_EXPR
|| code
== TARGET_EXPR
|| code
== BIND_EXPR
)
840 if (data
&& !((hash_set
<tree
> *)data
)->add (t
))
846 /* Stop at types, decls, constants like copy_tree_r. */
847 else if (TREE_CODE_CLASS (code
) == tcc_type
848 || TREE_CODE_CLASS (code
) == tcc_declaration
849 || TREE_CODE_CLASS (code
) == tcc_constant
)
852 /* Cope with the statement expression extension. */
853 else if (code
== STATEMENT_LIST
)
856 /* Leave the bulk of the work to copy_tree_r itself. */
858 copy_tree_r (tp
, walk_subtrees
, NULL
);
863 /* Callback for walk_tree to unshare most of the shared trees rooted at *TP.
864 If *TP has been visited already, then *TP is deeply copied by calling
865 mostly_copy_tree_r. DATA is passed to mostly_copy_tree_r unmodified. */
868 copy_if_shared_r (tree
*tp
, int *walk_subtrees
, void *data
)
871 enum tree_code code
= TREE_CODE (t
);
873 /* Skip types, decls, and constants. But we do want to look at their
874 types and the bounds of types. Mark them as visited so we properly
875 unmark their subtrees on the unmark pass. If we've already seen them,
876 don't look down further. */
877 if (TREE_CODE_CLASS (code
) == tcc_type
878 || TREE_CODE_CLASS (code
) == tcc_declaration
879 || TREE_CODE_CLASS (code
) == tcc_constant
)
881 if (TREE_VISITED (t
))
884 TREE_VISITED (t
) = 1;
887 /* If this node has been visited already, unshare it and don't look
889 else if (TREE_VISITED (t
))
891 walk_tree (tp
, mostly_copy_tree_r
, data
, NULL
);
895 /* Otherwise, mark the node as visited and keep looking. */
897 TREE_VISITED (t
) = 1;
902 /* Unshare most of the shared trees rooted at *TP. DATA is passed to the
903 copy_if_shared_r callback unmodified. */
906 copy_if_shared (tree
*tp
, void *data
)
908 walk_tree (tp
, copy_if_shared_r
, data
, NULL
);
911 /* Unshare all the trees in the body of FNDECL, as well as in the bodies of
912 any nested functions. */
915 unshare_body (tree fndecl
)
917 struct cgraph_node
*cgn
= cgraph_node::get (fndecl
);
918 /* If the language requires deep unsharing, we need a pointer set to make
919 sure we don't repeatedly unshare subtrees of unshareable nodes. */
920 hash_set
<tree
> *visited
921 = lang_hooks
.deep_unsharing
? new hash_set
<tree
> : NULL
;
923 copy_if_shared (&DECL_SAVED_TREE (fndecl
), visited
);
924 copy_if_shared (&DECL_SIZE (DECL_RESULT (fndecl
)), visited
);
925 copy_if_shared (&DECL_SIZE_UNIT (DECL_RESULT (fndecl
)), visited
);
930 for (cgn
= cgn
->nested
; cgn
; cgn
= cgn
->next_nested
)
931 unshare_body (cgn
->decl
);
934 /* Callback for walk_tree to unmark the visited trees rooted at *TP.
935 Subtrees are walked until the first unvisited node is encountered. */
938 unmark_visited_r (tree
*tp
, int *walk_subtrees
, void *data ATTRIBUTE_UNUSED
)
942 /* If this node has been visited, unmark it and keep looking. */
943 if (TREE_VISITED (t
))
944 TREE_VISITED (t
) = 0;
946 /* Otherwise, don't look any deeper. */
953 /* Unmark the visited trees rooted at *TP. */
956 unmark_visited (tree
*tp
)
958 walk_tree (tp
, unmark_visited_r
, NULL
, NULL
);
961 /* Likewise, but mark all trees as not visited. */
964 unvisit_body (tree fndecl
)
966 struct cgraph_node
*cgn
= cgraph_node::get (fndecl
);
968 unmark_visited (&DECL_SAVED_TREE (fndecl
));
969 unmark_visited (&DECL_SIZE (DECL_RESULT (fndecl
)));
970 unmark_visited (&DECL_SIZE_UNIT (DECL_RESULT (fndecl
)));
973 for (cgn
= cgn
->nested
; cgn
; cgn
= cgn
->next_nested
)
974 unvisit_body (cgn
->decl
);
977 /* Unconditionally make an unshared copy of EXPR. This is used when using
978 stored expressions which span multiple functions, such as BINFO_VTABLE,
979 as the normal unsharing process can't tell that they're shared. */
982 unshare_expr (tree expr
)
984 walk_tree (&expr
, mostly_copy_tree_r
, NULL
, NULL
);
988 /* Worker for unshare_expr_without_location. */
991 prune_expr_location (tree
*tp
, int *walk_subtrees
, void *)
994 SET_EXPR_LOCATION (*tp
, UNKNOWN_LOCATION
);
1000 /* Similar to unshare_expr but also prune all expression locations
1004 unshare_expr_without_location (tree expr
)
1006 walk_tree (&expr
, mostly_copy_tree_r
, NULL
, NULL
);
1008 walk_tree (&expr
, prune_expr_location
, NULL
, NULL
);
1012 /* Return the EXPR_LOCATION of EXPR, if it (maybe recursively) has
1013 one, OR_ELSE otherwise. The location of a STATEMENT_LISTs
1014 comprising at least one DEBUG_BEGIN_STMT followed by exactly one
1015 EXPR is the location of the EXPR. */
1018 rexpr_location (tree expr
, location_t or_else
= UNKNOWN_LOCATION
)
1023 if (EXPR_HAS_LOCATION (expr
))
1024 return EXPR_LOCATION (expr
);
1026 if (TREE_CODE (expr
) != STATEMENT_LIST
)
1029 tree_stmt_iterator i
= tsi_start (expr
);
1032 while (!tsi_end_p (i
) && TREE_CODE (tsi_stmt (i
)) == DEBUG_BEGIN_STMT
)
1038 if (!found
|| !tsi_one_before_end_p (i
))
1041 return rexpr_location (tsi_stmt (i
), or_else
);
1044 /* Return TRUE iff EXPR (maybe recursively) has a location; see
1045 rexpr_location for the potential recursion. */
1048 rexpr_has_location (tree expr
)
1050 return rexpr_location (expr
) != UNKNOWN_LOCATION
;
1054 /* WRAPPER is a code such as BIND_EXPR or CLEANUP_POINT_EXPR which can both
1055 contain statements and have a value. Assign its value to a temporary
1056 and give it void_type_node. Return the temporary, or NULL_TREE if
1057 WRAPPER was already void. */
1060 voidify_wrapper_expr (tree wrapper
, tree temp
)
1062 tree type
= TREE_TYPE (wrapper
);
1063 if (type
&& !VOID_TYPE_P (type
))
1067 /* Set p to point to the body of the wrapper. Loop until we find
1068 something that isn't a wrapper. */
1069 for (p
= &wrapper
; p
&& *p
; )
1071 switch (TREE_CODE (*p
))
1074 TREE_SIDE_EFFECTS (*p
) = 1;
1075 TREE_TYPE (*p
) = void_type_node
;
1076 /* For a BIND_EXPR, the body is operand 1. */
1077 p
= &BIND_EXPR_BODY (*p
);
1080 case CLEANUP_POINT_EXPR
:
1081 case TRY_FINALLY_EXPR
:
1082 case TRY_CATCH_EXPR
:
1083 TREE_SIDE_EFFECTS (*p
) = 1;
1084 TREE_TYPE (*p
) = void_type_node
;
1085 p
= &TREE_OPERAND (*p
, 0);
1088 case STATEMENT_LIST
:
1090 tree_stmt_iterator i
= tsi_last (*p
);
1091 TREE_SIDE_EFFECTS (*p
) = 1;
1092 TREE_TYPE (*p
) = void_type_node
;
1093 p
= tsi_end_p (i
) ? NULL
: tsi_stmt_ptr (i
);
1098 /* Advance to the last statement. Set all container types to
1100 for (; TREE_CODE (*p
) == COMPOUND_EXPR
; p
= &TREE_OPERAND (*p
, 1))
1102 TREE_SIDE_EFFECTS (*p
) = 1;
1103 TREE_TYPE (*p
) = void_type_node
;
1107 case TRANSACTION_EXPR
:
1108 TREE_SIDE_EFFECTS (*p
) = 1;
1109 TREE_TYPE (*p
) = void_type_node
;
1110 p
= &TRANSACTION_EXPR_BODY (*p
);
1114 /* Assume that any tree upon which voidify_wrapper_expr is
1115 directly called is a wrapper, and that its body is op0. */
1118 TREE_SIDE_EFFECTS (*p
) = 1;
1119 TREE_TYPE (*p
) = void_type_node
;
1120 p
= &TREE_OPERAND (*p
, 0);
1128 if (p
== NULL
|| IS_EMPTY_STMT (*p
))
1132 /* The wrapper is on the RHS of an assignment that we're pushing
1134 gcc_assert (TREE_CODE (temp
) == INIT_EXPR
1135 || TREE_CODE (temp
) == MODIFY_EXPR
);
1136 TREE_OPERAND (temp
, 1) = *p
;
1141 temp
= create_tmp_var (type
, "retval");
1142 *p
= build2 (INIT_EXPR
, type
, temp
, *p
);
1151 /* Prepare calls to builtins to SAVE and RESTORE the stack as well as
1152 a temporary through which they communicate. */
1155 build_stack_save_restore (gcall
**save
, gcall
**restore
)
1159 *save
= gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_SAVE
), 0);
1160 tmp_var
= create_tmp_var (ptr_type_node
, "saved_stack");
1161 gimple_call_set_lhs (*save
, tmp_var
);
1164 = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_RESTORE
),
1168 /* Generate IFN_ASAN_MARK call that poisons shadow of a for DECL variable. */
1171 build_asan_poison_call_expr (tree decl
)
1173 /* Do not poison variables that have size equal to zero. */
1174 tree unit_size
= DECL_SIZE_UNIT (decl
);
1175 if (zerop (unit_size
))
1178 tree base
= build_fold_addr_expr (decl
);
1180 return build_call_expr_internal_loc (UNKNOWN_LOCATION
, IFN_ASAN_MARK
,
1182 build_int_cst (integer_type_node
,
1187 /* Generate IFN_ASAN_MARK call that would poison or unpoison, depending
1188 on POISON flag, shadow memory of a DECL variable. The call will be
1189 put on location identified by IT iterator, where BEFORE flag drives
1190 position where the stmt will be put. */
1193 asan_poison_variable (tree decl
, bool poison
, gimple_stmt_iterator
*it
,
1196 tree unit_size
= DECL_SIZE_UNIT (decl
);
1197 tree base
= build_fold_addr_expr (decl
);
1199 /* Do not poison variables that have size equal to zero. */
1200 if (zerop (unit_size
))
1203 /* It's necessary to have all stack variables aligned to ASAN granularity
1205 if (DECL_ALIGN_UNIT (decl
) <= ASAN_SHADOW_GRANULARITY
)
1206 SET_DECL_ALIGN (decl
, BITS_PER_UNIT
* ASAN_SHADOW_GRANULARITY
);
1208 HOST_WIDE_INT flags
= poison
? ASAN_MARK_POISON
: ASAN_MARK_UNPOISON
;
1211 = gimple_build_call_internal (IFN_ASAN_MARK
, 3,
1212 build_int_cst (integer_type_node
, flags
),
1216 gsi_insert_before (it
, g
, GSI_NEW_STMT
);
1218 gsi_insert_after (it
, g
, GSI_NEW_STMT
);
1221 /* Generate IFN_ASAN_MARK internal call that depending on POISON flag
1222 either poisons or unpoisons a DECL. Created statement is appended
1223 to SEQ_P gimple sequence. */
1226 asan_poison_variable (tree decl
, bool poison
, gimple_seq
*seq_p
)
1228 gimple_stmt_iterator it
= gsi_last (*seq_p
);
1229 bool before
= false;
1234 asan_poison_variable (decl
, poison
, &it
, before
);
1237 /* Sort pair of VAR_DECLs A and B by DECL_UID. */
1240 sort_by_decl_uid (const void *a
, const void *b
)
1242 const tree
*t1
= (const tree
*)a
;
1243 const tree
*t2
= (const tree
*)b
;
1245 int uid1
= DECL_UID (*t1
);
1246 int uid2
= DECL_UID (*t2
);
1250 else if (uid1
> uid2
)
1256 /* Generate IFN_ASAN_MARK internal call for all VARIABLES
1257 depending on POISON flag. Created statement is appended
1258 to SEQ_P gimple sequence. */
1261 asan_poison_variables (hash_set
<tree
> *variables
, bool poison
, gimple_seq
*seq_p
)
1263 unsigned c
= variables
->elements ();
1267 auto_vec
<tree
> sorted_variables (c
);
1269 for (hash_set
<tree
>::iterator it
= variables
->begin ();
1270 it
!= variables
->end (); ++it
)
1271 sorted_variables
.safe_push (*it
);
1273 sorted_variables
.qsort (sort_by_decl_uid
);
1277 FOR_EACH_VEC_ELT (sorted_variables
, i
, var
)
1279 asan_poison_variable (var
, poison
, seq_p
);
1281 /* Add use_after_scope_memory attribute for the variable in order
1282 to prevent re-written into SSA. */
1283 if (!lookup_attribute (ASAN_USE_AFTER_SCOPE_ATTRIBUTE
,
1284 DECL_ATTRIBUTES (var
)))
1285 DECL_ATTRIBUTES (var
)
1286 = tree_cons (get_identifier (ASAN_USE_AFTER_SCOPE_ATTRIBUTE
),
1288 DECL_ATTRIBUTES (var
));
1292 /* Gimplify a BIND_EXPR. Just voidify and recurse. */
1294 static enum gimplify_status
1295 gimplify_bind_expr (tree
*expr_p
, gimple_seq
*pre_p
)
1297 tree bind_expr
= *expr_p
;
1298 bool old_keep_stack
= gimplify_ctxp
->keep_stack
;
1299 bool old_save_stack
= gimplify_ctxp
->save_stack
;
1302 gimple_seq body
, cleanup
;
1304 location_t start_locus
= 0, end_locus
= 0;
1305 tree ret_clauses
= NULL
;
1307 tree temp
= voidify_wrapper_expr (bind_expr
, NULL
);
1309 /* Mark variables seen in this bind expr. */
1310 for (t
= BIND_EXPR_VARS (bind_expr
); t
; t
= DECL_CHAIN (t
))
1314 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
1316 /* Mark variable as local. */
1317 if (ctx
&& ctx
->region_type
!= ORT_NONE
&& !DECL_EXTERNAL (t
)
1318 && (! DECL_SEEN_IN_BIND_EXPR_P (t
)
1319 || splay_tree_lookup (ctx
->variables
,
1320 (splay_tree_key
) t
) == NULL
))
1322 if (ctx
->region_type
== ORT_SIMD
1323 && TREE_ADDRESSABLE (t
)
1324 && !TREE_STATIC (t
))
1325 omp_add_variable (ctx
, t
, GOVD_PRIVATE
| GOVD_SEEN
);
1327 omp_add_variable (ctx
, t
, GOVD_LOCAL
| GOVD_SEEN
);
1330 DECL_SEEN_IN_BIND_EXPR_P (t
) = 1;
1332 if (DECL_HARD_REGISTER (t
) && !is_global_var (t
) && cfun
)
1333 cfun
->has_local_explicit_reg_vars
= true;
1336 /* Preliminarily mark non-addressed complex variables as eligible
1337 for promotion to gimple registers. We'll transform their uses
1339 if ((TREE_CODE (TREE_TYPE (t
)) == COMPLEX_TYPE
1340 || TREE_CODE (TREE_TYPE (t
)) == VECTOR_TYPE
)
1341 && !TREE_THIS_VOLATILE (t
)
1342 && (VAR_P (t
) && !DECL_HARD_REGISTER (t
))
1343 && !needs_to_live_in_memory (t
))
1344 DECL_GIMPLE_REG_P (t
) = 1;
1347 bind_stmt
= gimple_build_bind (BIND_EXPR_VARS (bind_expr
), NULL
,
1348 BIND_EXPR_BLOCK (bind_expr
));
1349 gimple_push_bind_expr (bind_stmt
);
1351 gimplify_ctxp
->keep_stack
= false;
1352 gimplify_ctxp
->save_stack
= false;
1354 /* Gimplify the body into the GIMPLE_BIND tuple's body. */
1356 gimplify_stmt (&BIND_EXPR_BODY (bind_expr
), &body
);
1357 gimple_bind_set_body (bind_stmt
, body
);
1359 /* Source location wise, the cleanup code (stack_restore and clobbers)
1360 belongs to the end of the block, so propagate what we have. The
1361 stack_save operation belongs to the beginning of block, which we can
1362 infer from the bind_expr directly if the block has no explicit
1364 if (BIND_EXPR_BLOCK (bind_expr
))
1366 end_locus
= BLOCK_SOURCE_END_LOCATION (BIND_EXPR_BLOCK (bind_expr
));
1367 start_locus
= BLOCK_SOURCE_LOCATION (BIND_EXPR_BLOCK (bind_expr
));
1369 if (start_locus
== 0)
1370 start_locus
= EXPR_LOCATION (bind_expr
);
1375 /* If the code both contains VLAs and calls alloca, then we cannot reclaim
1376 the stack space allocated to the VLAs. */
1377 if (gimplify_ctxp
->save_stack
&& !gimplify_ctxp
->keep_stack
)
1379 gcall
*stack_restore
;
1381 /* Save stack on entry and restore it on exit. Add a try_finally
1382 block to achieve this. */
1383 build_stack_save_restore (&stack_save
, &stack_restore
);
1385 gimple_set_location (stack_save
, start_locus
);
1386 gimple_set_location (stack_restore
, end_locus
);
1388 gimplify_seq_add_stmt (&cleanup
, stack_restore
);
1391 /* Add clobbers for all variables that go out of scope. */
1392 for (t
= BIND_EXPR_VARS (bind_expr
); t
; t
= DECL_CHAIN (t
))
1395 && !is_global_var (t
)
1396 && DECL_CONTEXT (t
) == current_function_decl
)
1398 if (!DECL_HARD_REGISTER (t
)
1399 && !TREE_THIS_VOLATILE (t
)
1400 && !DECL_HAS_VALUE_EXPR_P (t
)
1401 /* Only care for variables that have to be in memory. Others
1402 will be rewritten into SSA names, hence moved to the
1404 && !is_gimple_reg (t
)
1405 && flag_stack_reuse
!= SR_NONE
)
1407 tree clobber
= build_clobber (TREE_TYPE (t
));
1408 gimple
*clobber_stmt
;
1409 clobber_stmt
= gimple_build_assign (t
, clobber
);
1410 gimple_set_location (clobber_stmt
, end_locus
);
1411 gimplify_seq_add_stmt (&cleanup
, clobber_stmt
);
1414 if (flag_openacc
&& oacc_declare_returns
!= NULL
)
1416 tree
*c
= oacc_declare_returns
->get (t
);
1420 OMP_CLAUSE_CHAIN (*c
) = ret_clauses
;
1424 oacc_declare_returns
->remove (t
);
1426 if (oacc_declare_returns
->elements () == 0)
1428 delete oacc_declare_returns
;
1429 oacc_declare_returns
= NULL
;
1435 if (asan_poisoned_variables
!= NULL
1436 && asan_poisoned_variables
->contains (t
))
1438 asan_poisoned_variables
->remove (t
);
1439 asan_poison_variable (t
, true, &cleanup
);
1442 if (gimplify_ctxp
->live_switch_vars
!= NULL
1443 && gimplify_ctxp
->live_switch_vars
->contains (t
))
1444 gimplify_ctxp
->live_switch_vars
->remove (t
);
1450 gimple_stmt_iterator si
= gsi_start (cleanup
);
1452 stmt
= gimple_build_omp_target (NULL
, GF_OMP_TARGET_KIND_OACC_DECLARE
,
1454 gsi_insert_seq_before_without_update (&si
, stmt
, GSI_NEW_STMT
);
1460 gimple_seq new_body
;
1463 gs
= gimple_build_try (gimple_bind_body (bind_stmt
), cleanup
,
1464 GIMPLE_TRY_FINALLY
);
1467 gimplify_seq_add_stmt (&new_body
, stack_save
);
1468 gimplify_seq_add_stmt (&new_body
, gs
);
1469 gimple_bind_set_body (bind_stmt
, new_body
);
1472 /* keep_stack propagates all the way up to the outermost BIND_EXPR. */
1473 if (!gimplify_ctxp
->keep_stack
)
1474 gimplify_ctxp
->keep_stack
= old_keep_stack
;
1475 gimplify_ctxp
->save_stack
= old_save_stack
;
1477 gimple_pop_bind_expr ();
1479 gimplify_seq_add_stmt (pre_p
, bind_stmt
);
1487 *expr_p
= NULL_TREE
;
1491 /* Maybe add early return predict statement to PRE_P sequence. */
1494 maybe_add_early_return_predict_stmt (gimple_seq
*pre_p
)
1496 /* If we are not in a conditional context, add PREDICT statement. */
1497 if (gimple_conditional_context ())
1499 gimple
*predict
= gimple_build_predict (PRED_TREE_EARLY_RETURN
,
1501 gimplify_seq_add_stmt (pre_p
, predict
);
1505 /* Gimplify a RETURN_EXPR. If the expression to be returned is not a
1506 GIMPLE value, it is assigned to a new temporary and the statement is
1507 re-written to return the temporary.
1509 PRE_P points to the sequence where side effects that must happen before
1510 STMT should be stored. */
1512 static enum gimplify_status
1513 gimplify_return_expr (tree stmt
, gimple_seq
*pre_p
)
1516 tree ret_expr
= TREE_OPERAND (stmt
, 0);
1517 tree result_decl
, result
;
1519 if (ret_expr
== error_mark_node
)
1523 || TREE_CODE (ret_expr
) == RESULT_DECL
)
1525 maybe_add_early_return_predict_stmt (pre_p
);
1526 greturn
*ret
= gimple_build_return (ret_expr
);
1527 gimple_set_no_warning (ret
, TREE_NO_WARNING (stmt
));
1528 gimplify_seq_add_stmt (pre_p
, ret
);
1532 if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl
))))
1533 result_decl
= NULL_TREE
;
1536 result_decl
= TREE_OPERAND (ret_expr
, 0);
1538 /* See through a return by reference. */
1539 if (TREE_CODE (result_decl
) == INDIRECT_REF
)
1540 result_decl
= TREE_OPERAND (result_decl
, 0);
1542 gcc_assert ((TREE_CODE (ret_expr
) == MODIFY_EXPR
1543 || TREE_CODE (ret_expr
) == INIT_EXPR
)
1544 && TREE_CODE (result_decl
) == RESULT_DECL
);
1547 /* If aggregate_value_p is true, then we can return the bare RESULT_DECL.
1548 Recall that aggregate_value_p is FALSE for any aggregate type that is
1549 returned in registers. If we're returning values in registers, then
1550 we don't want to extend the lifetime of the RESULT_DECL, particularly
1551 across another call. In addition, for those aggregates for which
1552 hard_function_value generates a PARALLEL, we'll die during normal
1553 expansion of structure assignments; there's special code in expand_return
1554 to handle this case that does not exist in expand_expr. */
1557 else if (aggregate_value_p (result_decl
, TREE_TYPE (current_function_decl
)))
1559 if (TREE_CODE (DECL_SIZE (result_decl
)) != INTEGER_CST
)
1561 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (result_decl
)))
1562 gimplify_type_sizes (TREE_TYPE (result_decl
), pre_p
);
1563 /* Note that we don't use gimplify_vla_decl because the RESULT_DECL
1564 should be effectively allocated by the caller, i.e. all calls to
1565 this function must be subject to the Return Slot Optimization. */
1566 gimplify_one_sizepos (&DECL_SIZE (result_decl
), pre_p
);
1567 gimplify_one_sizepos (&DECL_SIZE_UNIT (result_decl
), pre_p
);
1569 result
= result_decl
;
1571 else if (gimplify_ctxp
->return_temp
)
1572 result
= gimplify_ctxp
->return_temp
;
1575 result
= create_tmp_reg (TREE_TYPE (result_decl
));
1577 /* ??? With complex control flow (usually involving abnormal edges),
1578 we can wind up warning about an uninitialized value for this. Due
1579 to how this variable is constructed and initialized, this is never
1580 true. Give up and never warn. */
1581 TREE_NO_WARNING (result
) = 1;
1583 gimplify_ctxp
->return_temp
= result
;
1586 /* Smash the lhs of the MODIFY_EXPR to the temporary we plan to use.
1587 Then gimplify the whole thing. */
1588 if (result
!= result_decl
)
1589 TREE_OPERAND (ret_expr
, 0) = result
;
1591 gimplify_and_add (TREE_OPERAND (stmt
, 0), pre_p
);
1593 maybe_add_early_return_predict_stmt (pre_p
);
1594 ret
= gimple_build_return (result
);
1595 gimple_set_no_warning (ret
, TREE_NO_WARNING (stmt
));
1596 gimplify_seq_add_stmt (pre_p
, ret
);
1601 /* Gimplify a variable-length array DECL. */
1604 gimplify_vla_decl (tree decl
, gimple_seq
*seq_p
)
1606 /* This is a variable-sized decl. Simplify its size and mark it
1607 for deferred expansion. */
1608 tree t
, addr
, ptr_type
;
1610 gimplify_one_sizepos (&DECL_SIZE (decl
), seq_p
);
1611 gimplify_one_sizepos (&DECL_SIZE_UNIT (decl
), seq_p
);
1613 /* Don't mess with a DECL_VALUE_EXPR set by the front-end. */
1614 if (DECL_HAS_VALUE_EXPR_P (decl
))
1617 /* All occurrences of this decl in final gimplified code will be
1618 replaced by indirection. Setting DECL_VALUE_EXPR does two
1619 things: First, it lets the rest of the gimplifier know what
1620 replacement to use. Second, it lets the debug info know
1621 where to find the value. */
1622 ptr_type
= build_pointer_type (TREE_TYPE (decl
));
1623 addr
= create_tmp_var (ptr_type
, get_name (decl
));
1624 DECL_IGNORED_P (addr
) = 0;
1625 t
= build_fold_indirect_ref (addr
);
1626 TREE_THIS_NOTRAP (t
) = 1;
1627 SET_DECL_VALUE_EXPR (decl
, t
);
1628 DECL_HAS_VALUE_EXPR_P (decl
) = 1;
1630 t
= build_alloca_call_expr (DECL_SIZE_UNIT (decl
), DECL_ALIGN (decl
),
1631 max_int_size_in_bytes (TREE_TYPE (decl
)));
1632 /* The call has been built for a variable-sized object. */
1633 CALL_ALLOCA_FOR_VAR_P (t
) = 1;
1634 t
= fold_convert (ptr_type
, t
);
1635 t
= build2 (MODIFY_EXPR
, TREE_TYPE (addr
), addr
, t
);
1637 gimplify_and_add (t
, seq_p
);
1640 /* A helper function to be called via walk_tree. Mark all labels under *TP
1641 as being forced. To be called for DECL_INITIAL of static variables. */
1644 force_labels_r (tree
*tp
, int *walk_subtrees
, void *data ATTRIBUTE_UNUSED
)
1648 if (TREE_CODE (*tp
) == LABEL_DECL
)
1650 FORCED_LABEL (*tp
) = 1;
1651 cfun
->has_forced_label_in_static
= 1;
1657 /* Gimplify a DECL_EXPR node *STMT_P by making any necessary allocation
1658 and initialization explicit. */
1660 static enum gimplify_status
1661 gimplify_decl_expr (tree
*stmt_p
, gimple_seq
*seq_p
)
1663 tree stmt
= *stmt_p
;
1664 tree decl
= DECL_EXPR_DECL (stmt
);
1666 *stmt_p
= NULL_TREE
;
1668 if (TREE_TYPE (decl
) == error_mark_node
)
1671 if ((TREE_CODE (decl
) == TYPE_DECL
1673 && !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl
)))
1675 gimplify_type_sizes (TREE_TYPE (decl
), seq_p
);
1676 if (TREE_CODE (TREE_TYPE (decl
)) == REFERENCE_TYPE
)
1677 gimplify_type_sizes (TREE_TYPE (TREE_TYPE (decl
)), seq_p
);
1680 /* ??? DECL_ORIGINAL_TYPE is streamed for LTO so it needs to be gimplified
1681 in case its size expressions contain problematic nodes like CALL_EXPR. */
1682 if (TREE_CODE (decl
) == TYPE_DECL
1683 && DECL_ORIGINAL_TYPE (decl
)
1684 && !TYPE_SIZES_GIMPLIFIED (DECL_ORIGINAL_TYPE (decl
)))
1686 gimplify_type_sizes (DECL_ORIGINAL_TYPE (decl
), seq_p
);
1687 if (TREE_CODE (DECL_ORIGINAL_TYPE (decl
)) == REFERENCE_TYPE
)
1688 gimplify_type_sizes (TREE_TYPE (DECL_ORIGINAL_TYPE (decl
)), seq_p
);
1691 if (VAR_P (decl
) && !DECL_EXTERNAL (decl
))
1693 tree init
= DECL_INITIAL (decl
);
1694 bool is_vla
= false;
1696 if (TREE_CODE (DECL_SIZE_UNIT (decl
)) != INTEGER_CST
1697 || (!TREE_STATIC (decl
)
1698 && flag_stack_check
== GENERIC_STACK_CHECK
1699 && compare_tree_int (DECL_SIZE_UNIT (decl
),
1700 STACK_CHECK_MAX_VAR_SIZE
) > 0))
1702 gimplify_vla_decl (decl
, seq_p
);
1706 if (asan_poisoned_variables
1708 && TREE_ADDRESSABLE (decl
)
1709 && !TREE_STATIC (decl
)
1710 && !DECL_HAS_VALUE_EXPR_P (decl
)
1711 && DECL_ALIGN (decl
) <= MAX_SUPPORTED_STACK_ALIGNMENT
1712 && dbg_cnt (asan_use_after_scope
)
1713 && !gimplify_omp_ctxp
)
1715 asan_poisoned_variables
->add (decl
);
1716 asan_poison_variable (decl
, false, seq_p
);
1717 if (!DECL_ARTIFICIAL (decl
) && gimplify_ctxp
->live_switch_vars
)
1718 gimplify_ctxp
->live_switch_vars
->add (decl
);
1721 /* Some front ends do not explicitly declare all anonymous
1722 artificial variables. We compensate here by declaring the
1723 variables, though it would be better if the front ends would
1724 explicitly declare them. */
1725 if (!DECL_SEEN_IN_BIND_EXPR_P (decl
)
1726 && DECL_ARTIFICIAL (decl
) && DECL_NAME (decl
) == NULL_TREE
)
1727 gimple_add_tmp_var (decl
);
1729 if (init
&& init
!= error_mark_node
)
1731 if (!TREE_STATIC (decl
))
1733 DECL_INITIAL (decl
) = NULL_TREE
;
1734 init
= build2 (INIT_EXPR
, void_type_node
, decl
, init
);
1735 gimplify_and_add (init
, seq_p
);
1739 /* We must still examine initializers for static variables
1740 as they may contain a label address. */
1741 walk_tree (&init
, force_labels_r
, NULL
, NULL
);
1748 /* Gimplify a LOOP_EXPR. Normally this just involves gimplifying the body
1749 and replacing the LOOP_EXPR with goto, but if the loop contains an
1750 EXIT_EXPR, we need to append a label for it to jump to. */
1752 static enum gimplify_status
1753 gimplify_loop_expr (tree
*expr_p
, gimple_seq
*pre_p
)
1755 tree saved_label
= gimplify_ctxp
->exit_label
;
1756 tree start_label
= create_artificial_label (UNKNOWN_LOCATION
);
1758 gimplify_seq_add_stmt (pre_p
, gimple_build_label (start_label
));
1760 gimplify_ctxp
->exit_label
= NULL_TREE
;
1762 gimplify_and_add (LOOP_EXPR_BODY (*expr_p
), pre_p
);
1764 gimplify_seq_add_stmt (pre_p
, gimple_build_goto (start_label
));
1766 if (gimplify_ctxp
->exit_label
)
1767 gimplify_seq_add_stmt (pre_p
,
1768 gimple_build_label (gimplify_ctxp
->exit_label
));
1770 gimplify_ctxp
->exit_label
= saved_label
;
1776 /* Gimplify a statement list onto a sequence. These may be created either
1777 by an enlightened front-end, or by shortcut_cond_expr. */
1779 static enum gimplify_status
1780 gimplify_statement_list (tree
*expr_p
, gimple_seq
*pre_p
)
1782 tree temp
= voidify_wrapper_expr (*expr_p
, NULL
);
1784 tree_stmt_iterator i
= tsi_start (*expr_p
);
1786 while (!tsi_end_p (i
))
1788 gimplify_stmt (tsi_stmt_ptr (i
), pre_p
);
1801 /* Callback for walk_gimple_seq. */
1804 warn_switch_unreachable_r (gimple_stmt_iterator
*gsi_p
, bool *handled_ops_p
,
1805 struct walk_stmt_info
*wi
)
1807 gimple
*stmt
= gsi_stmt (*gsi_p
);
1809 *handled_ops_p
= true;
1810 switch (gimple_code (stmt
))
1813 /* A compiler-generated cleanup or a user-written try block.
1814 If it's empty, don't dive into it--that would result in
1815 worse location info. */
1816 if (gimple_try_eval (stmt
) == NULL
)
1819 return integer_zero_node
;
1824 case GIMPLE_EH_FILTER
:
1825 case GIMPLE_TRANSACTION
:
1826 /* Walk the sub-statements. */
1827 *handled_ops_p
= false;
1831 /* Ignore these. We may generate them before declarations that
1832 are never executed. If there's something to warn about,
1833 there will be non-debug stmts too, and we'll catch those. */
1837 if (gimple_call_internal_p (stmt
, IFN_ASAN_MARK
))
1839 *handled_ops_p
= false;
1844 /* Save the first "real" statement (not a decl/lexical scope/...). */
1846 return integer_zero_node
;
1851 /* Possibly warn about unreachable statements between switch's controlling
1852 expression and the first case. SEQ is the body of a switch expression. */
1855 maybe_warn_switch_unreachable (gimple_seq seq
)
1857 if (!warn_switch_unreachable
1858 /* This warning doesn't play well with Fortran when optimizations
1860 || lang_GNU_Fortran ()
1864 struct walk_stmt_info wi
;
1865 memset (&wi
, 0, sizeof (wi
));
1866 walk_gimple_seq (seq
, warn_switch_unreachable_r
, NULL
, &wi
);
1867 gimple
*stmt
= (gimple
*) wi
.info
;
1869 if (stmt
&& gimple_code (stmt
) != GIMPLE_LABEL
)
1871 if (gimple_code (stmt
) == GIMPLE_GOTO
1872 && TREE_CODE (gimple_goto_dest (stmt
)) == LABEL_DECL
1873 && DECL_ARTIFICIAL (gimple_goto_dest (stmt
)))
1874 /* Don't warn for compiler-generated gotos. These occur
1875 in Duff's devices, for example. */;
1877 warning_at (gimple_location (stmt
), OPT_Wswitch_unreachable
,
1878 "statement will never be executed");
1883 /* A label entry that pairs label and a location. */
1890 /* Find LABEL in vector of label entries VEC. */
1892 static struct label_entry
*
1893 find_label_entry (const auto_vec
<struct label_entry
> *vec
, tree label
)
1896 struct label_entry
*l
;
1898 FOR_EACH_VEC_ELT (*vec
, i
, l
)
1899 if (l
->label
== label
)
1904 /* Return true if LABEL, a LABEL_DECL, represents a case label
1905 in a vector of labels CASES. */
1908 case_label_p (const vec
<tree
> *cases
, tree label
)
1913 FOR_EACH_VEC_ELT (*cases
, i
, l
)
1914 if (CASE_LABEL (l
) == label
)
1919 /* Find the last nondebug statement in a scope STMT. */
1922 last_stmt_in_scope (gimple
*stmt
)
1927 switch (gimple_code (stmt
))
1931 gbind
*bind
= as_a
<gbind
*> (stmt
);
1932 stmt
= gimple_seq_last_nondebug_stmt (gimple_bind_body (bind
));
1933 return last_stmt_in_scope (stmt
);
1938 gtry
*try_stmt
= as_a
<gtry
*> (stmt
);
1939 stmt
= gimple_seq_last_nondebug_stmt (gimple_try_eval (try_stmt
));
1940 gimple
*last_eval
= last_stmt_in_scope (stmt
);
1941 if (gimple_stmt_may_fallthru (last_eval
)
1942 && (last_eval
== NULL
1943 || !gimple_call_internal_p (last_eval
, IFN_FALLTHROUGH
))
1944 && gimple_try_kind (try_stmt
) == GIMPLE_TRY_FINALLY
)
1946 stmt
= gimple_seq_last_nondebug_stmt (gimple_try_cleanup (try_stmt
));
1947 return last_stmt_in_scope (stmt
);
1961 /* Collect interesting labels in LABELS and return the statement preceding
1962 another case label, or a user-defined label. */
1965 collect_fallthrough_labels (gimple_stmt_iterator
*gsi_p
,
1966 auto_vec
<struct label_entry
> *labels
)
1968 gimple
*prev
= NULL
;
1972 if (gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_BIND
)
1974 /* Recognize the special GIMPLE_BIND added by gimplify_switch_expr,
1975 which starts on a GIMPLE_SWITCH and ends with a break label.
1976 Handle that as a single statement that can fall through. */
1977 gbind
*bind
= as_a
<gbind
*> (gsi_stmt (*gsi_p
));
1978 gimple
*first
= gimple_seq_first_stmt (gimple_bind_body (bind
));
1979 gimple
*last
= gimple_seq_last_stmt (gimple_bind_body (bind
));
1981 && gimple_code (first
) == GIMPLE_SWITCH
1982 && gimple_code (last
) == GIMPLE_LABEL
)
1984 tree label
= gimple_label_label (as_a
<glabel
*> (last
));
1985 if (SWITCH_BREAK_LABEL_P (label
))
1993 if (gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_BIND
1994 || gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_TRY
)
1996 /* Nested scope. Only look at the last statement of
1997 the innermost scope. */
1998 location_t bind_loc
= gimple_location (gsi_stmt (*gsi_p
));
1999 gimple
*last
= last_stmt_in_scope (gsi_stmt (*gsi_p
));
2003 /* It might be a label without a location. Use the
2004 location of the scope then. */
2005 if (!gimple_has_location (prev
))
2006 gimple_set_location (prev
, bind_loc
);
2012 /* Ifs are tricky. */
2013 if (gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_COND
)
2015 gcond
*cond_stmt
= as_a
<gcond
*> (gsi_stmt (*gsi_p
));
2016 tree false_lab
= gimple_cond_false_label (cond_stmt
);
2017 location_t if_loc
= gimple_location (cond_stmt
);
2020 if (i > 1) goto <D.2259>; else goto D;
2021 we can't do much with the else-branch. */
2022 if (!DECL_ARTIFICIAL (false_lab
))
2025 /* Go on until the false label, then one step back. */
2026 for (; !gsi_end_p (*gsi_p
); gsi_next (gsi_p
))
2028 gimple
*stmt
= gsi_stmt (*gsi_p
);
2029 if (gimple_code (stmt
) == GIMPLE_LABEL
2030 && gimple_label_label (as_a
<glabel
*> (stmt
)) == false_lab
)
2034 /* Not found? Oops. */
2035 if (gsi_end_p (*gsi_p
))
2038 struct label_entry l
= { false_lab
, if_loc
};
2039 labels
->safe_push (l
);
2041 /* Go to the last statement of the then branch. */
2044 /* if (i != 0) goto <D.1759>; else goto <D.1760>;
2050 if (gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_GOTO
2051 && !gimple_has_location (gsi_stmt (*gsi_p
)))
2053 /* Look at the statement before, it might be
2054 attribute fallthrough, in which case don't warn. */
2056 bool fallthru_before_dest
2057 = gimple_call_internal_p (gsi_stmt (*gsi_p
), IFN_FALLTHROUGH
);
2059 tree goto_dest
= gimple_goto_dest (gsi_stmt (*gsi_p
));
2060 if (!fallthru_before_dest
)
2062 struct label_entry l
= { goto_dest
, if_loc
};
2063 labels
->safe_push (l
);
2066 /* And move back. */
2070 /* Remember the last statement. Skip labels that are of no interest
2072 if (gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_LABEL
)
2074 tree label
= gimple_label_label (as_a
<glabel
*> (gsi_stmt (*gsi_p
)));
2075 if (find_label_entry (labels
, label
))
2076 prev
= gsi_stmt (*gsi_p
);
2078 else if (gimple_call_internal_p (gsi_stmt (*gsi_p
), IFN_ASAN_MARK
))
2080 else if (!is_gimple_debug (gsi_stmt (*gsi_p
)))
2081 prev
= gsi_stmt (*gsi_p
);
2084 while (!gsi_end_p (*gsi_p
)
2085 /* Stop if we find a case or a user-defined label. */
2086 && (gimple_code (gsi_stmt (*gsi_p
)) != GIMPLE_LABEL
2087 || !gimple_has_location (gsi_stmt (*gsi_p
))));
2092 /* Return true if the switch fallthough warning should occur. LABEL is
2093 the label statement that we're falling through to. */
2096 should_warn_for_implicit_fallthrough (gimple_stmt_iterator
*gsi_p
, tree label
)
2098 gimple_stmt_iterator gsi
= *gsi_p
;
2100 /* Don't warn if the label is marked with a "falls through" comment. */
2101 if (FALLTHROUGH_LABEL_P (label
))
2104 /* Don't warn for non-case labels followed by a statement:
2109 as these are likely intentional. */
2110 if (!case_label_p (&gimplify_ctxp
->case_labels
, label
))
2113 while (!gsi_end_p (gsi
)
2114 && gimple_code (gsi_stmt (gsi
)) == GIMPLE_LABEL
2115 && (l
= gimple_label_label (as_a
<glabel
*> (gsi_stmt (gsi
))))
2116 && !case_label_p (&gimplify_ctxp
->case_labels
, l
))
2117 gsi_next_nondebug (&gsi
);
2118 if (gsi_end_p (gsi
) || gimple_code (gsi_stmt (gsi
)) != GIMPLE_LABEL
)
2122 /* Don't warn for terminated branches, i.e. when the subsequent case labels
2123 immediately breaks. */
2126 /* Skip all immediately following labels. */
2127 while (!gsi_end_p (gsi
)
2128 && (gimple_code (gsi_stmt (gsi
)) == GIMPLE_LABEL
2129 || gimple_code (gsi_stmt (gsi
)) == GIMPLE_PREDICT
))
2130 gsi_next_nondebug (&gsi
);
2132 /* { ... something; default:; } */
2134 /* { ... something; default: break; } or
2135 { ... something; default: goto L; } */
2136 || gimple_code (gsi_stmt (gsi
)) == GIMPLE_GOTO
2137 /* { ... something; default: return; } */
2138 || gimple_code (gsi_stmt (gsi
)) == GIMPLE_RETURN
)
2144 /* Callback for walk_gimple_seq. */
2147 warn_implicit_fallthrough_r (gimple_stmt_iterator
*gsi_p
, bool *handled_ops_p
,
2148 struct walk_stmt_info
*)
2150 gimple
*stmt
= gsi_stmt (*gsi_p
);
2152 *handled_ops_p
= true;
2153 switch (gimple_code (stmt
))
2158 case GIMPLE_EH_FILTER
:
2159 case GIMPLE_TRANSACTION
:
2160 /* Walk the sub-statements. */
2161 *handled_ops_p
= false;
2164 /* Find a sequence of form:
2171 and possibly warn. */
2174 /* Found a label. Skip all immediately following labels. */
2175 while (!gsi_end_p (*gsi_p
)
2176 && gimple_code (gsi_stmt (*gsi_p
)) == GIMPLE_LABEL
)
2177 gsi_next_nondebug (gsi_p
);
2179 /* There might be no more statements. */
2180 if (gsi_end_p (*gsi_p
))
2181 return integer_zero_node
;
2183 /* Vector of labels that fall through. */
2184 auto_vec
<struct label_entry
> labels
;
2185 gimple
*prev
= collect_fallthrough_labels (gsi_p
, &labels
);
2187 /* There might be no more statements. */
2188 if (gsi_end_p (*gsi_p
))
2189 return integer_zero_node
;
2191 gimple
*next
= gsi_stmt (*gsi_p
);
2193 /* If what follows is a label, then we may have a fallthrough. */
2194 if (gimple_code (next
) == GIMPLE_LABEL
2195 && gimple_has_location (next
)
2196 && (label
= gimple_label_label (as_a
<glabel
*> (next
)))
2199 struct label_entry
*l
;
2200 bool warned_p
= false;
2201 auto_diagnostic_group d
;
2202 if (!should_warn_for_implicit_fallthrough (gsi_p
, label
))
2204 else if (gimple_code (prev
) == GIMPLE_LABEL
2205 && (label
= gimple_label_label (as_a
<glabel
*> (prev
)))
2206 && (l
= find_label_entry (&labels
, label
)))
2207 warned_p
= warning_at (l
->loc
, OPT_Wimplicit_fallthrough_
,
2208 "this statement may fall through");
2209 else if (!gimple_call_internal_p (prev
, IFN_FALLTHROUGH
)
2210 /* Try to be clever and don't warn when the statement
2211 can't actually fall through. */
2212 && gimple_stmt_may_fallthru (prev
)
2213 && gimple_has_location (prev
))
2214 warned_p
= warning_at (gimple_location (prev
),
2215 OPT_Wimplicit_fallthrough_
,
2216 "this statement may fall through");
2218 inform (gimple_location (next
), "here");
2220 /* Mark this label as processed so as to prevent multiple
2221 warnings in nested switches. */
2222 FALLTHROUGH_LABEL_P (label
) = true;
2224 /* So that next warn_implicit_fallthrough_r will start looking for
2225 a new sequence starting with this label. */
2236 /* Warn when a switch case falls through. */
2239 maybe_warn_implicit_fallthrough (gimple_seq seq
)
2241 if (!warn_implicit_fallthrough
)
2244 /* This warning is meant for C/C++/ObjC/ObjC++ only. */
2247 || lang_GNU_OBJC ()))
2250 struct walk_stmt_info wi
;
2251 memset (&wi
, 0, sizeof (wi
));
2252 walk_gimple_seq (seq
, warn_implicit_fallthrough_r
, NULL
, &wi
);
2255 /* Callback for walk_gimple_seq. */
2258 expand_FALLTHROUGH_r (gimple_stmt_iterator
*gsi_p
, bool *handled_ops_p
,
2259 struct walk_stmt_info
*)
2261 gimple
*stmt
= gsi_stmt (*gsi_p
);
2263 *handled_ops_p
= true;
2264 switch (gimple_code (stmt
))
2269 case GIMPLE_EH_FILTER
:
2270 case GIMPLE_TRANSACTION
:
2271 /* Walk the sub-statements. */
2272 *handled_ops_p
= false;
2275 if (gimple_call_internal_p (stmt
, IFN_FALLTHROUGH
))
2277 gsi_remove (gsi_p
, true);
2278 if (gsi_end_p (*gsi_p
))
2279 return integer_zero_node
;
2282 location_t loc
= gimple_location (stmt
);
2284 gimple_stmt_iterator gsi2
= *gsi_p
;
2285 stmt
= gsi_stmt (gsi2
);
2286 if (gimple_code (stmt
) == GIMPLE_GOTO
&& !gimple_has_location (stmt
))
2288 /* Go on until the artificial label. */
2289 tree goto_dest
= gimple_goto_dest (stmt
);
2290 for (; !gsi_end_p (gsi2
); gsi_next (&gsi2
))
2292 if (gimple_code (gsi_stmt (gsi2
)) == GIMPLE_LABEL
2293 && gimple_label_label (as_a
<glabel
*> (gsi_stmt (gsi2
)))
2298 /* Not found? Stop. */
2299 if (gsi_end_p (gsi2
))
2302 /* Look one past it. */
2306 /* We're looking for a case label or default label here. */
2307 while (!gsi_end_p (gsi2
))
2309 stmt
= gsi_stmt (gsi2
);
2310 if (gimple_code (stmt
) == GIMPLE_LABEL
)
2312 tree label
= gimple_label_label (as_a
<glabel
*> (stmt
));
2313 if (gimple_has_location (stmt
) && DECL_ARTIFICIAL (label
))
2319 else if (gimple_call_internal_p (stmt
, IFN_ASAN_MARK
))
2321 else if (!is_gimple_debug (stmt
))
2322 /* Anything else is not expected. */
2327 warning_at (loc
, 0, "attribute %<fallthrough%> not preceding "
2328 "a case label or default label");
2337 /* Expand all FALLTHROUGH () calls in SEQ. */
2340 expand_FALLTHROUGH (gimple_seq
*seq_p
)
2342 struct walk_stmt_info wi
;
2343 memset (&wi
, 0, sizeof (wi
));
2344 walk_gimple_seq_mod (seq_p
, expand_FALLTHROUGH_r
, NULL
, &wi
);
2348 /* Gimplify a SWITCH_EXPR, and collect the vector of labels it can
2351 static enum gimplify_status
2352 gimplify_switch_expr (tree
*expr_p
, gimple_seq
*pre_p
)
2354 tree switch_expr
= *expr_p
;
2355 gimple_seq switch_body_seq
= NULL
;
2356 enum gimplify_status ret
;
2357 tree index_type
= TREE_TYPE (switch_expr
);
2358 if (index_type
== NULL_TREE
)
2359 index_type
= TREE_TYPE (SWITCH_COND (switch_expr
));
2361 ret
= gimplify_expr (&SWITCH_COND (switch_expr
), pre_p
, NULL
, is_gimple_val
,
2363 if (ret
== GS_ERROR
|| ret
== GS_UNHANDLED
)
2366 if (SWITCH_BODY (switch_expr
))
2369 vec
<tree
> saved_labels
;
2370 hash_set
<tree
> *saved_live_switch_vars
= NULL
;
2371 tree default_case
= NULL_TREE
;
2372 gswitch
*switch_stmt
;
2374 /* Save old labels, get new ones from body, then restore the old
2375 labels. Save all the things from the switch body to append after. */
2376 saved_labels
= gimplify_ctxp
->case_labels
;
2377 gimplify_ctxp
->case_labels
.create (8);
2379 /* Do not create live_switch_vars if SWITCH_BODY is not a BIND_EXPR. */
2380 saved_live_switch_vars
= gimplify_ctxp
->live_switch_vars
;
2381 tree_code body_type
= TREE_CODE (SWITCH_BODY (switch_expr
));
2382 if (body_type
== BIND_EXPR
|| body_type
== STATEMENT_LIST
)
2383 gimplify_ctxp
->live_switch_vars
= new hash_set
<tree
> (4);
2385 gimplify_ctxp
->live_switch_vars
= NULL
;
2387 bool old_in_switch_expr
= gimplify_ctxp
->in_switch_expr
;
2388 gimplify_ctxp
->in_switch_expr
= true;
2390 gimplify_stmt (&SWITCH_BODY (switch_expr
), &switch_body_seq
);
2392 gimplify_ctxp
->in_switch_expr
= old_in_switch_expr
;
2393 maybe_warn_switch_unreachable (switch_body_seq
);
2394 maybe_warn_implicit_fallthrough (switch_body_seq
);
2395 /* Only do this for the outermost GIMPLE_SWITCH. */
2396 if (!gimplify_ctxp
->in_switch_expr
)
2397 expand_FALLTHROUGH (&switch_body_seq
);
2399 labels
= gimplify_ctxp
->case_labels
;
2400 gimplify_ctxp
->case_labels
= saved_labels
;
2402 if (gimplify_ctxp
->live_switch_vars
)
2404 gcc_assert (gimplify_ctxp
->live_switch_vars
->elements () == 0);
2405 delete gimplify_ctxp
->live_switch_vars
;
2407 gimplify_ctxp
->live_switch_vars
= saved_live_switch_vars
;
2409 preprocess_case_label_vec_for_gimple (labels
, index_type
,
2412 bool add_bind
= false;
2415 glabel
*new_default
;
2418 = build_case_label (NULL_TREE
, NULL_TREE
,
2419 create_artificial_label (UNKNOWN_LOCATION
));
2420 if (old_in_switch_expr
)
2422 SWITCH_BREAK_LABEL_P (CASE_LABEL (default_case
)) = 1;
2425 new_default
= gimple_build_label (CASE_LABEL (default_case
));
2426 gimplify_seq_add_stmt (&switch_body_seq
, new_default
);
2428 else if (old_in_switch_expr
)
2430 gimple
*last
= gimple_seq_last_stmt (switch_body_seq
);
2431 if (last
&& gimple_code (last
) == GIMPLE_LABEL
)
2433 tree label
= gimple_label_label (as_a
<glabel
*> (last
));
2434 if (SWITCH_BREAK_LABEL_P (label
))
2439 switch_stmt
= gimple_build_switch (SWITCH_COND (switch_expr
),
2440 default_case
, labels
);
2441 /* For the benefit of -Wimplicit-fallthrough, if switch_body_seq
2442 ends with a GIMPLE_LABEL holding SWITCH_BREAK_LABEL_P LABEL_DECL,
2443 wrap the GIMPLE_SWITCH up to that GIMPLE_LABEL into a GIMPLE_BIND,
2444 so that we can easily find the start and end of the switch
2448 gimple_seq bind_body
= NULL
;
2449 gimplify_seq_add_stmt (&bind_body
, switch_stmt
);
2450 gimple_seq_add_seq (&bind_body
, switch_body_seq
);
2451 gbind
*bind
= gimple_build_bind (NULL_TREE
, bind_body
, NULL_TREE
);
2452 gimple_set_location (bind
, EXPR_LOCATION (switch_expr
));
2453 gimplify_seq_add_stmt (pre_p
, bind
);
2457 gimplify_seq_add_stmt (pre_p
, switch_stmt
);
2458 gimplify_seq_add_seq (pre_p
, switch_body_seq
);
2468 /* Gimplify the LABEL_EXPR pointed to by EXPR_P. */
2470 static enum gimplify_status
2471 gimplify_label_expr (tree
*expr_p
, gimple_seq
*pre_p
)
2473 gcc_assert (decl_function_context (LABEL_EXPR_LABEL (*expr_p
))
2474 == current_function_decl
);
2476 tree label
= LABEL_EXPR_LABEL (*expr_p
);
2477 glabel
*label_stmt
= gimple_build_label (label
);
2478 gimple_set_location (label_stmt
, EXPR_LOCATION (*expr_p
));
2479 gimplify_seq_add_stmt (pre_p
, label_stmt
);
2481 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label
)))
2482 gimple_seq_add_stmt (pre_p
, gimple_build_predict (PRED_COLD_LABEL
,
2484 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label
)))
2485 gimple_seq_add_stmt (pre_p
, gimple_build_predict (PRED_HOT_LABEL
,
2491 /* Gimplify the CASE_LABEL_EXPR pointed to by EXPR_P. */
2493 static enum gimplify_status
2494 gimplify_case_label_expr (tree
*expr_p
, gimple_seq
*pre_p
)
2496 struct gimplify_ctx
*ctxp
;
2499 /* Invalid programs can play Duff's Device type games with, for example,
2500 #pragma omp parallel. At least in the C front end, we don't
2501 detect such invalid branches until after gimplification, in the
2502 diagnose_omp_blocks pass. */
2503 for (ctxp
= gimplify_ctxp
; ; ctxp
= ctxp
->prev_context
)
2504 if (ctxp
->case_labels
.exists ())
2507 label_stmt
= gimple_build_label (CASE_LABEL (*expr_p
));
2508 gimple_set_location (label_stmt
, EXPR_LOCATION (*expr_p
));
2509 ctxp
->case_labels
.safe_push (*expr_p
);
2510 gimplify_seq_add_stmt (pre_p
, label_stmt
);
2515 /* Build a GOTO to the LABEL_DECL pointed to by LABEL_P, building it first
2519 build_and_jump (tree
*label_p
)
2521 if (label_p
== NULL
)
2522 /* If there's nowhere to jump, just fall through. */
2525 if (*label_p
== NULL_TREE
)
2527 tree label
= create_artificial_label (UNKNOWN_LOCATION
);
2531 return build1 (GOTO_EXPR
, void_type_node
, *label_p
);
2534 /* Gimplify an EXIT_EXPR by converting to a GOTO_EXPR inside a COND_EXPR.
2535 This also involves building a label to jump to and communicating it to
2536 gimplify_loop_expr through gimplify_ctxp->exit_label. */
2538 static enum gimplify_status
2539 gimplify_exit_expr (tree
*expr_p
)
2541 tree cond
= TREE_OPERAND (*expr_p
, 0);
2544 expr
= build_and_jump (&gimplify_ctxp
->exit_label
);
2545 expr
= build3 (COND_EXPR
, void_type_node
, cond
, expr
, NULL_TREE
);
2551 /* *EXPR_P is a COMPONENT_REF being used as an rvalue. If its type is
2552 different from its canonical type, wrap the whole thing inside a
2553 NOP_EXPR and force the type of the COMPONENT_REF to be the canonical
2556 The canonical type of a COMPONENT_REF is the type of the field being
2557 referenced--unless the field is a bit-field which can be read directly
2558 in a smaller mode, in which case the canonical type is the
2559 sign-appropriate type corresponding to that mode. */
2562 canonicalize_component_ref (tree
*expr_p
)
2564 tree expr
= *expr_p
;
2567 gcc_assert (TREE_CODE (expr
) == COMPONENT_REF
);
2569 if (INTEGRAL_TYPE_P (TREE_TYPE (expr
)))
2570 type
= TREE_TYPE (get_unwidened (expr
, NULL_TREE
));
2572 type
= TREE_TYPE (TREE_OPERAND (expr
, 1));
2574 /* One could argue that all the stuff below is not necessary for
2575 the non-bitfield case and declare it a FE error if type
2576 adjustment would be needed. */
2577 if (TREE_TYPE (expr
) != type
)
2579 #ifdef ENABLE_TYPES_CHECKING
2580 tree old_type
= TREE_TYPE (expr
);
2584 /* We need to preserve qualifiers and propagate them from
2586 type_quals
= TYPE_QUALS (type
)
2587 | TYPE_QUALS (TREE_TYPE (TREE_OPERAND (expr
, 0)));
2588 if (TYPE_QUALS (type
) != type_quals
)
2589 type
= build_qualified_type (TYPE_MAIN_VARIANT (type
), type_quals
);
2591 /* Set the type of the COMPONENT_REF to the underlying type. */
2592 TREE_TYPE (expr
) = type
;
2594 #ifdef ENABLE_TYPES_CHECKING
2595 /* It is now a FE error, if the conversion from the canonical
2596 type to the original expression type is not useless. */
2597 gcc_assert (useless_type_conversion_p (old_type
, type
));
2602 /* If a NOP conversion is changing a pointer to array of foo to a pointer
2603 to foo, embed that change in the ADDR_EXPR by converting
2608 where L is the lower bound. For simplicity, only do this for constant
2610 The constraint is that the type of &array[L] is trivially convertible
2614 canonicalize_addr_expr (tree
*expr_p
)
2616 tree expr
= *expr_p
;
2617 tree addr_expr
= TREE_OPERAND (expr
, 0);
2618 tree datype
, ddatype
, pddatype
;
2620 /* We simplify only conversions from an ADDR_EXPR to a pointer type. */
2621 if (!POINTER_TYPE_P (TREE_TYPE (expr
))
2622 || TREE_CODE (addr_expr
) != ADDR_EXPR
)
2625 /* The addr_expr type should be a pointer to an array. */
2626 datype
= TREE_TYPE (TREE_TYPE (addr_expr
));
2627 if (TREE_CODE (datype
) != ARRAY_TYPE
)
2630 /* The pointer to element type shall be trivially convertible to
2631 the expression pointer type. */
2632 ddatype
= TREE_TYPE (datype
);
2633 pddatype
= build_pointer_type (ddatype
);
2634 if (!useless_type_conversion_p (TYPE_MAIN_VARIANT (TREE_TYPE (expr
)),
2638 /* The lower bound and element sizes must be constant. */
2639 if (!TYPE_SIZE_UNIT (ddatype
)
2640 || TREE_CODE (TYPE_SIZE_UNIT (ddatype
)) != INTEGER_CST
2641 || !TYPE_DOMAIN (datype
) || !TYPE_MIN_VALUE (TYPE_DOMAIN (datype
))
2642 || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (datype
))) != INTEGER_CST
)
2645 /* All checks succeeded. Build a new node to merge the cast. */
2646 *expr_p
= build4 (ARRAY_REF
, ddatype
, TREE_OPERAND (addr_expr
, 0),
2647 TYPE_MIN_VALUE (TYPE_DOMAIN (datype
)),
2648 NULL_TREE
, NULL_TREE
);
2649 *expr_p
= build1 (ADDR_EXPR
, pddatype
, *expr_p
);
2651 /* We can have stripped a required restrict qualifier above. */
2652 if (!useless_type_conversion_p (TREE_TYPE (expr
), TREE_TYPE (*expr_p
)))
2653 *expr_p
= fold_convert (TREE_TYPE (expr
), *expr_p
);
2656 /* *EXPR_P is a NOP_EXPR or CONVERT_EXPR. Remove it and/or other conversions
2657 underneath as appropriate. */
2659 static enum gimplify_status
2660 gimplify_conversion (tree
*expr_p
)
2662 location_t loc
= EXPR_LOCATION (*expr_p
);
2663 gcc_assert (CONVERT_EXPR_P (*expr_p
));
2665 /* Then strip away all but the outermost conversion. */
2666 STRIP_SIGN_NOPS (TREE_OPERAND (*expr_p
, 0));
2668 /* And remove the outermost conversion if it's useless. */
2669 if (tree_ssa_useless_type_conversion (*expr_p
))
2670 *expr_p
= TREE_OPERAND (*expr_p
, 0);
2672 /* If we still have a conversion at the toplevel,
2673 then canonicalize some constructs. */
2674 if (CONVERT_EXPR_P (*expr_p
))
2676 tree sub
= TREE_OPERAND (*expr_p
, 0);
2678 /* If a NOP conversion is changing the type of a COMPONENT_REF
2679 expression, then canonicalize its type now in order to expose more
2680 redundant conversions. */
2681 if (TREE_CODE (sub
) == COMPONENT_REF
)
2682 canonicalize_component_ref (&TREE_OPERAND (*expr_p
, 0));
2684 /* If a NOP conversion is changing a pointer to array of foo
2685 to a pointer to foo, embed that change in the ADDR_EXPR. */
2686 else if (TREE_CODE (sub
) == ADDR_EXPR
)
2687 canonicalize_addr_expr (expr_p
);
2690 /* If we have a conversion to a non-register type force the
2691 use of a VIEW_CONVERT_EXPR instead. */
2692 if (CONVERT_EXPR_P (*expr_p
) && !is_gimple_reg_type (TREE_TYPE (*expr_p
)))
2693 *expr_p
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, TREE_TYPE (*expr_p
),
2694 TREE_OPERAND (*expr_p
, 0));
2696 /* Canonicalize CONVERT_EXPR to NOP_EXPR. */
2697 if (TREE_CODE (*expr_p
) == CONVERT_EXPR
)
2698 TREE_SET_CODE (*expr_p
, NOP_EXPR
);
2703 /* Gimplify a VAR_DECL or PARM_DECL. Return GS_OK if we expanded a
2704 DECL_VALUE_EXPR, and it's worth re-examining things. */
2706 static enum gimplify_status
2707 gimplify_var_or_parm_decl (tree
*expr_p
)
2709 tree decl
= *expr_p
;
2711 /* ??? If this is a local variable, and it has not been seen in any
2712 outer BIND_EXPR, then it's probably the result of a duplicate
2713 declaration, for which we've already issued an error. It would
2714 be really nice if the front end wouldn't leak these at all.
2715 Currently the only known culprit is C++ destructors, as seen
2716 in g++.old-deja/g++.jason/binding.C. */
2718 && !DECL_SEEN_IN_BIND_EXPR_P (decl
)
2719 && !TREE_STATIC (decl
) && !DECL_EXTERNAL (decl
)
2720 && decl_function_context (decl
) == current_function_decl
)
2722 gcc_assert (seen_error ());
2726 /* When within an OMP context, notice uses of variables. */
2727 if (gimplify_omp_ctxp
&& omp_notice_variable (gimplify_omp_ctxp
, decl
, true))
2730 /* If the decl is an alias for another expression, substitute it now. */
2731 if (DECL_HAS_VALUE_EXPR_P (decl
))
2733 *expr_p
= unshare_expr (DECL_VALUE_EXPR (decl
));
2740 /* Recalculate the value of the TREE_SIDE_EFFECTS flag for T. */
2743 recalculate_side_effects (tree t
)
2745 enum tree_code code
= TREE_CODE (t
);
2746 int len
= TREE_OPERAND_LENGTH (t
);
2749 switch (TREE_CODE_CLASS (code
))
2751 case tcc_expression
:
2757 case PREDECREMENT_EXPR
:
2758 case PREINCREMENT_EXPR
:
2759 case POSTDECREMENT_EXPR
:
2760 case POSTINCREMENT_EXPR
:
2761 /* All of these have side-effects, no matter what their
2770 case tcc_comparison
: /* a comparison expression */
2771 case tcc_unary
: /* a unary arithmetic expression */
2772 case tcc_binary
: /* a binary arithmetic expression */
2773 case tcc_reference
: /* a reference */
2774 case tcc_vl_exp
: /* a function call */
2775 TREE_SIDE_EFFECTS (t
) = TREE_THIS_VOLATILE (t
);
2776 for (i
= 0; i
< len
; ++i
)
2778 tree op
= TREE_OPERAND (t
, i
);
2779 if (op
&& TREE_SIDE_EFFECTS (op
))
2780 TREE_SIDE_EFFECTS (t
) = 1;
2785 /* No side-effects. */
2793 /* Gimplify the COMPONENT_REF, ARRAY_REF, REALPART_EXPR or IMAGPART_EXPR
2797 : min_lval '[' val ']'
2799 | compound_lval '[' val ']'
2800 | compound_lval '.' ID
2802 This is not part of the original SIMPLE definition, which separates
2803 array and member references, but it seems reasonable to handle them
2804 together. Also, this way we don't run into problems with union
2805 aliasing; gcc requires that for accesses through a union to alias, the
2806 union reference must be explicit, which was not always the case when we
2807 were splitting up array and member refs.
2809 PRE_P points to the sequence where side effects that must happen before
2810 *EXPR_P should be stored.
2812 POST_P points to the sequence where side effects that must happen after
2813 *EXPR_P should be stored. */
2815 static enum gimplify_status
2816 gimplify_compound_lval (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
2817 fallback_t fallback
)
2820 enum gimplify_status ret
= GS_ALL_DONE
, tret
;
2822 location_t loc
= EXPR_LOCATION (*expr_p
);
2823 tree expr
= *expr_p
;
2825 /* Create a stack of the subexpressions so later we can walk them in
2826 order from inner to outer. */
2827 auto_vec
<tree
, 10> expr_stack
;
2829 /* We can handle anything that get_inner_reference can deal with. */
2830 for (p
= expr_p
; ; p
= &TREE_OPERAND (*p
, 0))
2833 /* Fold INDIRECT_REFs now to turn them into ARRAY_REFs. */
2834 if (TREE_CODE (*p
) == INDIRECT_REF
)
2835 *p
= fold_indirect_ref_loc (loc
, *p
);
2837 if (handled_component_p (*p
))
2839 /* Expand DECL_VALUE_EXPR now. In some cases that may expose
2840 additional COMPONENT_REFs. */
2841 else if ((VAR_P (*p
) || TREE_CODE (*p
) == PARM_DECL
)
2842 && gimplify_var_or_parm_decl (p
) == GS_OK
)
2847 expr_stack
.safe_push (*p
);
2850 gcc_assert (expr_stack
.length ());
2852 /* Now EXPR_STACK is a stack of pointers to all the refs we've
2853 walked through and P points to the innermost expression.
2855 Java requires that we elaborated nodes in source order. That
2856 means we must gimplify the inner expression followed by each of
2857 the indices, in order. But we can't gimplify the inner
2858 expression until we deal with any variable bounds, sizes, or
2859 positions in order to deal with PLACEHOLDER_EXPRs.
2861 So we do this in three steps. First we deal with the annotations
2862 for any variables in the components, then we gimplify the base,
2863 then we gimplify any indices, from left to right. */
2864 for (i
= expr_stack
.length () - 1; i
>= 0; i
--)
2866 tree t
= expr_stack
[i
];
2868 if (TREE_CODE (t
) == ARRAY_REF
|| TREE_CODE (t
) == ARRAY_RANGE_REF
)
2870 /* Gimplify the low bound and element type size and put them into
2871 the ARRAY_REF. If these values are set, they have already been
2873 if (TREE_OPERAND (t
, 2) == NULL_TREE
)
2875 tree low
= unshare_expr (array_ref_low_bound (t
));
2876 if (!is_gimple_min_invariant (low
))
2878 TREE_OPERAND (t
, 2) = low
;
2879 tret
= gimplify_expr (&TREE_OPERAND (t
, 2), pre_p
,
2880 post_p
, is_gimple_reg
,
2882 ret
= MIN (ret
, tret
);
2887 tret
= gimplify_expr (&TREE_OPERAND (t
, 2), pre_p
, post_p
,
2888 is_gimple_reg
, fb_rvalue
);
2889 ret
= MIN (ret
, tret
);
2892 if (TREE_OPERAND (t
, 3) == NULL_TREE
)
2894 tree elmt_type
= TREE_TYPE (TREE_TYPE (TREE_OPERAND (t
, 0)));
2895 tree elmt_size
= unshare_expr (array_ref_element_size (t
));
2896 tree factor
= size_int (TYPE_ALIGN_UNIT (elmt_type
));
2898 /* Divide the element size by the alignment of the element
2901 = size_binop_loc (loc
, EXACT_DIV_EXPR
, elmt_size
, factor
);
2903 if (!is_gimple_min_invariant (elmt_size
))
2905 TREE_OPERAND (t
, 3) = elmt_size
;
2906 tret
= gimplify_expr (&TREE_OPERAND (t
, 3), pre_p
,
2907 post_p
, is_gimple_reg
,
2909 ret
= MIN (ret
, tret
);
2914 tret
= gimplify_expr (&TREE_OPERAND (t
, 3), pre_p
, post_p
,
2915 is_gimple_reg
, fb_rvalue
);
2916 ret
= MIN (ret
, tret
);
2919 else if (TREE_CODE (t
) == COMPONENT_REF
)
2921 /* Set the field offset into T and gimplify it. */
2922 if (TREE_OPERAND (t
, 2) == NULL_TREE
)
2924 tree offset
= unshare_expr (component_ref_field_offset (t
));
2925 tree field
= TREE_OPERAND (t
, 1);
2927 = size_int (DECL_OFFSET_ALIGN (field
) / BITS_PER_UNIT
);
2929 /* Divide the offset by its alignment. */
2930 offset
= size_binop_loc (loc
, EXACT_DIV_EXPR
, offset
, factor
);
2932 if (!is_gimple_min_invariant (offset
))
2934 TREE_OPERAND (t
, 2) = offset
;
2935 tret
= gimplify_expr (&TREE_OPERAND (t
, 2), pre_p
,
2936 post_p
, is_gimple_reg
,
2938 ret
= MIN (ret
, tret
);
2943 tret
= gimplify_expr (&TREE_OPERAND (t
, 2), pre_p
, post_p
,
2944 is_gimple_reg
, fb_rvalue
);
2945 ret
= MIN (ret
, tret
);
2950 /* Step 2 is to gimplify the base expression. Make sure lvalue is set
2951 so as to match the min_lval predicate. Failure to do so may result
2952 in the creation of large aggregate temporaries. */
2953 tret
= gimplify_expr (p
, pre_p
, post_p
, is_gimple_min_lval
,
2954 fallback
| fb_lvalue
);
2955 ret
= MIN (ret
, tret
);
2957 /* And finally, the indices and operands of ARRAY_REF. During this
2958 loop we also remove any useless conversions. */
2959 for (; expr_stack
.length () > 0; )
2961 tree t
= expr_stack
.pop ();
2963 if (TREE_CODE (t
) == ARRAY_REF
|| TREE_CODE (t
) == ARRAY_RANGE_REF
)
2965 /* Gimplify the dimension. */
2966 if (!is_gimple_min_invariant (TREE_OPERAND (t
, 1)))
2968 tret
= gimplify_expr (&TREE_OPERAND (t
, 1), pre_p
, post_p
,
2969 is_gimple_val
, fb_rvalue
);
2970 ret
= MIN (ret
, tret
);
2974 STRIP_USELESS_TYPE_CONVERSION (TREE_OPERAND (t
, 0));
2976 /* The innermost expression P may have originally had
2977 TREE_SIDE_EFFECTS set which would have caused all the outer
2978 expressions in *EXPR_P leading to P to also have had
2979 TREE_SIDE_EFFECTS set. */
2980 recalculate_side_effects (t
);
2983 /* If the outermost expression is a COMPONENT_REF, canonicalize its type. */
2984 if ((fallback
& fb_rvalue
) && TREE_CODE (*expr_p
) == COMPONENT_REF
)
2986 canonicalize_component_ref (expr_p
);
2989 expr_stack
.release ();
2991 gcc_assert (*expr_p
== expr
|| ret
!= GS_ALL_DONE
);
2996 /* Gimplify the self modifying expression pointed to by EXPR_P
2999 PRE_P points to the list where side effects that must happen before
3000 *EXPR_P should be stored.
3002 POST_P points to the list where side effects that must happen after
3003 *EXPR_P should be stored.
3005 WANT_VALUE is nonzero iff we want to use the value of this expression
3006 in another expression.
3008 ARITH_TYPE is the type the computation should be performed in. */
3010 enum gimplify_status
3011 gimplify_self_mod_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
3012 bool want_value
, tree arith_type
)
3014 enum tree_code code
;
3015 tree lhs
, lvalue
, rhs
, t1
;
3016 gimple_seq post
= NULL
, *orig_post_p
= post_p
;
3018 enum tree_code arith_code
;
3019 enum gimplify_status ret
;
3020 location_t loc
= EXPR_LOCATION (*expr_p
);
3022 code
= TREE_CODE (*expr_p
);
3024 gcc_assert (code
== POSTINCREMENT_EXPR
|| code
== POSTDECREMENT_EXPR
3025 || code
== PREINCREMENT_EXPR
|| code
== PREDECREMENT_EXPR
);
3027 /* Prefix or postfix? */
3028 if (code
== POSTINCREMENT_EXPR
|| code
== POSTDECREMENT_EXPR
)
3029 /* Faster to treat as prefix if result is not used. */
3030 postfix
= want_value
;
3034 /* For postfix, make sure the inner expression's post side effects
3035 are executed after side effects from this expression. */
3039 /* Add or subtract? */
3040 if (code
== PREINCREMENT_EXPR
|| code
== POSTINCREMENT_EXPR
)
3041 arith_code
= PLUS_EXPR
;
3043 arith_code
= MINUS_EXPR
;
3045 /* Gimplify the LHS into a GIMPLE lvalue. */
3046 lvalue
= TREE_OPERAND (*expr_p
, 0);
3047 ret
= gimplify_expr (&lvalue
, pre_p
, post_p
, is_gimple_lvalue
, fb_lvalue
);
3048 if (ret
== GS_ERROR
)
3051 /* Extract the operands to the arithmetic operation. */
3053 rhs
= TREE_OPERAND (*expr_p
, 1);
3055 /* For postfix operator, we evaluate the LHS to an rvalue and then use
3056 that as the result value and in the postqueue operation. */
3059 ret
= gimplify_expr (&lhs
, pre_p
, post_p
, is_gimple_val
, fb_rvalue
);
3060 if (ret
== GS_ERROR
)
3063 lhs
= get_initialized_tmp_var (lhs
, pre_p
, NULL
);
3066 /* For POINTERs increment, use POINTER_PLUS_EXPR. */
3067 if (POINTER_TYPE_P (TREE_TYPE (lhs
)))
3069 rhs
= convert_to_ptrofftype_loc (loc
, rhs
);
3070 if (arith_code
== MINUS_EXPR
)
3071 rhs
= fold_build1_loc (loc
, NEGATE_EXPR
, TREE_TYPE (rhs
), rhs
);
3072 t1
= fold_build2 (POINTER_PLUS_EXPR
, TREE_TYPE (*expr_p
), lhs
, rhs
);
3075 t1
= fold_convert (TREE_TYPE (*expr_p
),
3076 fold_build2 (arith_code
, arith_type
,
3077 fold_convert (arith_type
, lhs
),
3078 fold_convert (arith_type
, rhs
)));
3082 gimplify_assign (lvalue
, t1
, pre_p
);
3083 gimplify_seq_add_seq (orig_post_p
, post
);
3089 *expr_p
= build2 (MODIFY_EXPR
, TREE_TYPE (lvalue
), lvalue
, t1
);
3094 /* If *EXPR_P has a variable sized type, wrap it in a WITH_SIZE_EXPR. */
3097 maybe_with_size_expr (tree
*expr_p
)
3099 tree expr
= *expr_p
;
3100 tree type
= TREE_TYPE (expr
);
3103 /* If we've already wrapped this or the type is error_mark_node, we can't do
3105 if (TREE_CODE (expr
) == WITH_SIZE_EXPR
3106 || type
== error_mark_node
)
3109 /* If the size isn't known or is a constant, we have nothing to do. */
3110 size
= TYPE_SIZE_UNIT (type
);
3111 if (!size
|| poly_int_tree_p (size
))
3114 /* Otherwise, make a WITH_SIZE_EXPR. */
3115 size
= unshare_expr (size
);
3116 size
= SUBSTITUTE_PLACEHOLDER_IN_EXPR (size
, expr
);
3117 *expr_p
= build2 (WITH_SIZE_EXPR
, type
, expr
, size
);
3120 /* Helper for gimplify_call_expr. Gimplify a single argument *ARG_P
3121 Store any side-effects in PRE_P. CALL_LOCATION is the location of
3122 the CALL_EXPR. If ALLOW_SSA is set the actual parameter may be
3123 gimplified to an SSA name. */
3125 enum gimplify_status
3126 gimplify_arg (tree
*arg_p
, gimple_seq
*pre_p
, location_t call_location
,
3129 bool (*test
) (tree
);
3132 /* In general, we allow lvalues for function arguments to avoid
3133 extra overhead of copying large aggregates out of even larger
3134 aggregates into temporaries only to copy the temporaries to
3135 the argument list. Make optimizers happy by pulling out to
3136 temporaries those types that fit in registers. */
3137 if (is_gimple_reg_type (TREE_TYPE (*arg_p
)))
3138 test
= is_gimple_val
, fb
= fb_rvalue
;
3141 test
= is_gimple_lvalue
, fb
= fb_either
;
3142 /* Also strip a TARGET_EXPR that would force an extra copy. */
3143 if (TREE_CODE (*arg_p
) == TARGET_EXPR
)
3145 tree init
= TARGET_EXPR_INITIAL (*arg_p
);
3147 && !VOID_TYPE_P (TREE_TYPE (init
)))
3152 /* If this is a variable sized type, we must remember the size. */
3153 maybe_with_size_expr (arg_p
);
3155 /* FIXME diagnostics: This will mess up gcc.dg/Warray-bounds.c. */
3156 /* Make sure arguments have the same location as the function call
3158 protected_set_expr_location (*arg_p
, call_location
);
3160 /* There is a sequence point before a function call. Side effects in
3161 the argument list must occur before the actual call. So, when
3162 gimplifying arguments, force gimplify_expr to use an internal
3163 post queue which is then appended to the end of PRE_P. */
3164 return gimplify_expr (arg_p
, pre_p
, NULL
, test
, fb
, allow_ssa
);
3167 /* Don't fold inside offloading or taskreg regions: it can break code by
3168 adding decl references that weren't in the source. We'll do it during
3169 omplower pass instead. */
3172 maybe_fold_stmt (gimple_stmt_iterator
*gsi
)
3174 struct gimplify_omp_ctx
*ctx
;
3175 for (ctx
= gimplify_omp_ctxp
; ctx
; ctx
= ctx
->outer_context
)
3176 if ((ctx
->region_type
& (ORT_TARGET
| ORT_PARALLEL
| ORT_TASK
)) != 0)
3178 else if ((ctx
->region_type
& ORT_HOST_TEAMS
) == ORT_HOST_TEAMS
)
3180 return fold_stmt (gsi
);
3183 /* Gimplify the CALL_EXPR node *EXPR_P into the GIMPLE sequence PRE_P.
3184 WANT_VALUE is true if the result of the call is desired. */
3186 static enum gimplify_status
3187 gimplify_call_expr (tree
*expr_p
, gimple_seq
*pre_p
, bool want_value
)
3189 tree fndecl
, parms
, p
, fnptrtype
;
3190 enum gimplify_status ret
;
3193 bool builtin_va_start_p
= false;
3194 location_t loc
= EXPR_LOCATION (*expr_p
);
3196 gcc_assert (TREE_CODE (*expr_p
) == CALL_EXPR
);
3198 /* For reliable diagnostics during inlining, it is necessary that
3199 every call_expr be annotated with file and line. */
3200 if (! EXPR_HAS_LOCATION (*expr_p
))
3201 SET_EXPR_LOCATION (*expr_p
, input_location
);
3203 /* Gimplify internal functions created in the FEs. */
3204 if (CALL_EXPR_FN (*expr_p
) == NULL_TREE
)
3209 nargs
= call_expr_nargs (*expr_p
);
3210 enum internal_fn ifn
= CALL_EXPR_IFN (*expr_p
);
3211 auto_vec
<tree
> vargs (nargs
);
3213 for (i
= 0; i
< nargs
; i
++)
3215 gimplify_arg (&CALL_EXPR_ARG (*expr_p
, i
), pre_p
,
3216 EXPR_LOCATION (*expr_p
));
3217 vargs
.quick_push (CALL_EXPR_ARG (*expr_p
, i
));
3220 gcall
*call
= gimple_build_call_internal_vec (ifn
, vargs
);
3221 gimple_call_set_nothrow (call
, TREE_NOTHROW (*expr_p
));
3222 gimplify_seq_add_stmt (pre_p
, call
);
3226 /* This may be a call to a builtin function.
3228 Builtin function calls may be transformed into different
3229 (and more efficient) builtin function calls under certain
3230 circumstances. Unfortunately, gimplification can muck things
3231 up enough that the builtin expanders are not aware that certain
3232 transformations are still valid.
3234 So we attempt transformation/gimplification of the call before
3235 we gimplify the CALL_EXPR. At this time we do not manage to
3236 transform all calls in the same manner as the expanders do, but
3237 we do transform most of them. */
3238 fndecl
= get_callee_fndecl (*expr_p
);
3239 if (fndecl
&& fndecl_built_in_p (fndecl
, BUILT_IN_NORMAL
))
3240 switch (DECL_FUNCTION_CODE (fndecl
))
3242 CASE_BUILT_IN_ALLOCA
:
3243 /* If the call has been built for a variable-sized object, then we
3244 want to restore the stack level when the enclosing BIND_EXPR is
3245 exited to reclaim the allocated space; otherwise, we precisely
3246 need to do the opposite and preserve the latest stack level. */
3247 if (CALL_ALLOCA_FOR_VAR_P (*expr_p
))
3248 gimplify_ctxp
->save_stack
= true;
3250 gimplify_ctxp
->keep_stack
= true;
3253 case BUILT_IN_VA_START
:
3255 builtin_va_start_p
= TRUE
;
3256 if (call_expr_nargs (*expr_p
) < 2)
3258 error ("too few arguments to function %<va_start%>");
3259 *expr_p
= build_empty_stmt (EXPR_LOCATION (*expr_p
));
3263 if (fold_builtin_next_arg (*expr_p
, true))
3265 *expr_p
= build_empty_stmt (EXPR_LOCATION (*expr_p
));
3274 if (fndecl
&& fndecl_built_in_p (fndecl
))
3276 tree new_tree
= fold_call_expr (input_location
, *expr_p
, !want_value
);
3277 if (new_tree
&& new_tree
!= *expr_p
)
3279 /* There was a transformation of this call which computes the
3280 same value, but in a more efficient way. Return and try
3287 /* Remember the original function pointer type. */
3288 fnptrtype
= TREE_TYPE (CALL_EXPR_FN (*expr_p
));
3290 /* There is a sequence point before the call, so any side effects in
3291 the calling expression must occur before the actual call. Force
3292 gimplify_expr to use an internal post queue. */
3293 ret
= gimplify_expr (&CALL_EXPR_FN (*expr_p
), pre_p
, NULL
,
3294 is_gimple_call_addr
, fb_rvalue
);
3296 nargs
= call_expr_nargs (*expr_p
);
3298 /* Get argument types for verification. */
3299 fndecl
= get_callee_fndecl (*expr_p
);
3302 parms
= TYPE_ARG_TYPES (TREE_TYPE (fndecl
));
3304 parms
= TYPE_ARG_TYPES (TREE_TYPE (fnptrtype
));
3306 if (fndecl
&& DECL_ARGUMENTS (fndecl
))
3307 p
= DECL_ARGUMENTS (fndecl
);
3312 for (i
= 0; i
< nargs
&& p
; i
++, p
= TREE_CHAIN (p
))
3315 /* If the last argument is __builtin_va_arg_pack () and it is not
3316 passed as a named argument, decrease the number of CALL_EXPR
3317 arguments and set instead the CALL_EXPR_VA_ARG_PACK flag. */
3320 && TREE_CODE (CALL_EXPR_ARG (*expr_p
, nargs
- 1)) == CALL_EXPR
)
3322 tree last_arg
= CALL_EXPR_ARG (*expr_p
, nargs
- 1);
3323 tree last_arg_fndecl
= get_callee_fndecl (last_arg
);
3326 && fndecl_built_in_p (last_arg_fndecl
, BUILT_IN_VA_ARG_PACK
))
3328 tree call
= *expr_p
;
3331 *expr_p
= build_call_array_loc (loc
, TREE_TYPE (call
),
3332 CALL_EXPR_FN (call
),
3333 nargs
, CALL_EXPR_ARGP (call
));
3335 /* Copy all CALL_EXPR flags, location and block, except
3336 CALL_EXPR_VA_ARG_PACK flag. */
3337 CALL_EXPR_STATIC_CHAIN (*expr_p
) = CALL_EXPR_STATIC_CHAIN (call
);
3338 CALL_EXPR_TAILCALL (*expr_p
) = CALL_EXPR_TAILCALL (call
);
3339 CALL_EXPR_RETURN_SLOT_OPT (*expr_p
)
3340 = CALL_EXPR_RETURN_SLOT_OPT (call
);
3341 CALL_FROM_THUNK_P (*expr_p
) = CALL_FROM_THUNK_P (call
);
3342 SET_EXPR_LOCATION (*expr_p
, EXPR_LOCATION (call
));
3344 /* Set CALL_EXPR_VA_ARG_PACK. */
3345 CALL_EXPR_VA_ARG_PACK (*expr_p
) = 1;
3349 /* If the call returns twice then after building the CFG the call
3350 argument computations will no longer dominate the call because
3351 we add an abnormal incoming edge to the call. So do not use SSA
3353 bool returns_twice
= call_expr_flags (*expr_p
) & ECF_RETURNS_TWICE
;
3355 /* Gimplify the function arguments. */
3358 for (i
= (PUSH_ARGS_REVERSED
? nargs
- 1 : 0);
3359 PUSH_ARGS_REVERSED
? i
>= 0 : i
< nargs
;
3360 PUSH_ARGS_REVERSED
? i
-- : i
++)
3362 enum gimplify_status t
;
3364 /* Avoid gimplifying the second argument to va_start, which needs to
3365 be the plain PARM_DECL. */
3366 if ((i
!= 1) || !builtin_va_start_p
)
3368 t
= gimplify_arg (&CALL_EXPR_ARG (*expr_p
, i
), pre_p
,
3369 EXPR_LOCATION (*expr_p
), ! returns_twice
);
3377 /* Gimplify the static chain. */
3378 if (CALL_EXPR_STATIC_CHAIN (*expr_p
))
3380 if (fndecl
&& !DECL_STATIC_CHAIN (fndecl
))
3381 CALL_EXPR_STATIC_CHAIN (*expr_p
) = NULL
;
3384 enum gimplify_status t
;
3385 t
= gimplify_arg (&CALL_EXPR_STATIC_CHAIN (*expr_p
), pre_p
,
3386 EXPR_LOCATION (*expr_p
), ! returns_twice
);
3392 /* Verify the function result. */
3393 if (want_value
&& fndecl
3394 && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fnptrtype
))))
3396 error_at (loc
, "using result of function returning %<void%>");
3400 /* Try this again in case gimplification exposed something. */
3401 if (ret
!= GS_ERROR
)
3403 tree new_tree
= fold_call_expr (input_location
, *expr_p
, !want_value
);
3405 if (new_tree
&& new_tree
!= *expr_p
)
3407 /* There was a transformation of this call which computes the
3408 same value, but in a more efficient way. Return and try
3416 *expr_p
= error_mark_node
;
3420 /* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its
3421 decl. This allows us to eliminate redundant or useless
3422 calls to "const" functions. */
3423 if (TREE_CODE (*expr_p
) == CALL_EXPR
)
3425 int flags
= call_expr_flags (*expr_p
);
3426 if (flags
& (ECF_CONST
| ECF_PURE
)
3427 /* An infinite loop is considered a side effect. */
3428 && !(flags
& (ECF_LOOPING_CONST_OR_PURE
)))
3429 TREE_SIDE_EFFECTS (*expr_p
) = 0;
3432 /* If the value is not needed by the caller, emit a new GIMPLE_CALL
3433 and clear *EXPR_P. Otherwise, leave *EXPR_P in its gimplified
3434 form and delegate the creation of a GIMPLE_CALL to
3435 gimplify_modify_expr. This is always possible because when
3436 WANT_VALUE is true, the caller wants the result of this call into
3437 a temporary, which means that we will emit an INIT_EXPR in
3438 internal_get_tmp_var which will then be handled by
3439 gimplify_modify_expr. */
3442 /* The CALL_EXPR in *EXPR_P is already in GIMPLE form, so all we
3443 have to do is replicate it as a GIMPLE_CALL tuple. */
3444 gimple_stmt_iterator gsi
;
3445 call
= gimple_build_call_from_tree (*expr_p
, fnptrtype
);
3446 notice_special_calls (call
);
3447 gimplify_seq_add_stmt (pre_p
, call
);
3448 gsi
= gsi_last (*pre_p
);
3449 maybe_fold_stmt (&gsi
);
3450 *expr_p
= NULL_TREE
;
3453 /* Remember the original function type. */
3454 CALL_EXPR_FN (*expr_p
) = build1 (NOP_EXPR
, fnptrtype
,
3455 CALL_EXPR_FN (*expr_p
));
3460 /* Handle shortcut semantics in the predicate operand of a COND_EXPR by
3461 rewriting it into multiple COND_EXPRs, and possibly GOTO_EXPRs.
3463 TRUE_LABEL_P and FALSE_LABEL_P point to the labels to jump to if the
3464 condition is true or false, respectively. If null, we should generate
3465 our own to skip over the evaluation of this specific expression.
3467 LOCUS is the source location of the COND_EXPR.
3469 This function is the tree equivalent of do_jump.
3471 shortcut_cond_r should only be called by shortcut_cond_expr. */
3474 shortcut_cond_r (tree pred
, tree
*true_label_p
, tree
*false_label_p
,
3477 tree local_label
= NULL_TREE
;
3478 tree t
, expr
= NULL
;
3480 /* OK, it's not a simple case; we need to pull apart the COND_EXPR to
3481 retain the shortcut semantics. Just insert the gotos here;
3482 shortcut_cond_expr will append the real blocks later. */
3483 if (TREE_CODE (pred
) == TRUTH_ANDIF_EXPR
)
3485 location_t new_locus
;
3487 /* Turn if (a && b) into
3489 if (a); else goto no;
3490 if (b) goto yes; else goto no;
3493 if (false_label_p
== NULL
)
3494 false_label_p
= &local_label
;
3496 /* Keep the original source location on the first 'if'. */
3497 t
= shortcut_cond_r (TREE_OPERAND (pred
, 0), NULL
, false_label_p
, locus
);
3498 append_to_statement_list (t
, &expr
);
3500 /* Set the source location of the && on the second 'if'. */
3501 new_locus
= rexpr_location (pred
, locus
);
3502 t
= shortcut_cond_r (TREE_OPERAND (pred
, 1), true_label_p
, false_label_p
,
3504 append_to_statement_list (t
, &expr
);
3506 else if (TREE_CODE (pred
) == TRUTH_ORIF_EXPR
)
3508 location_t new_locus
;
3510 /* Turn if (a || b) into
3513 if (b) goto yes; else goto no;
3516 if (true_label_p
== NULL
)
3517 true_label_p
= &local_label
;
3519 /* Keep the original source location on the first 'if'. */
3520 t
= shortcut_cond_r (TREE_OPERAND (pred
, 0), true_label_p
, NULL
, locus
);
3521 append_to_statement_list (t
, &expr
);
3523 /* Set the source location of the || on the second 'if'. */
3524 new_locus
= rexpr_location (pred
, locus
);
3525 t
= shortcut_cond_r (TREE_OPERAND (pred
, 1), true_label_p
, false_label_p
,
3527 append_to_statement_list (t
, &expr
);
3529 else if (TREE_CODE (pred
) == COND_EXPR
3530 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred
, 1)))
3531 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred
, 2))))
3533 location_t new_locus
;
3535 /* As long as we're messing with gotos, turn if (a ? b : c) into
3537 if (b) goto yes; else goto no;
3539 if (c) goto yes; else goto no;
3541 Don't do this if one of the arms has void type, which can happen
3542 in C++ when the arm is throw. */
3544 /* Keep the original source location on the first 'if'. Set the source
3545 location of the ? on the second 'if'. */
3546 new_locus
= rexpr_location (pred
, locus
);
3547 expr
= build3 (COND_EXPR
, void_type_node
, TREE_OPERAND (pred
, 0),
3548 shortcut_cond_r (TREE_OPERAND (pred
, 1), true_label_p
,
3549 false_label_p
, locus
),
3550 shortcut_cond_r (TREE_OPERAND (pred
, 2), true_label_p
,
3551 false_label_p
, new_locus
));
3555 expr
= build3 (COND_EXPR
, void_type_node
, pred
,
3556 build_and_jump (true_label_p
),
3557 build_and_jump (false_label_p
));
3558 SET_EXPR_LOCATION (expr
, locus
);
3563 t
= build1 (LABEL_EXPR
, void_type_node
, local_label
);
3564 append_to_statement_list (t
, &expr
);
3570 /* If EXPR is a GOTO_EXPR, return it. If it is a STATEMENT_LIST, skip
3571 any of its leading DEBUG_BEGIN_STMTS and recurse on the subsequent
3572 statement, if it is the last one. Otherwise, return NULL. */
3575 find_goto (tree expr
)
3580 if (TREE_CODE (expr
) == GOTO_EXPR
)
3583 if (TREE_CODE (expr
) != STATEMENT_LIST
)
3586 tree_stmt_iterator i
= tsi_start (expr
);
3588 while (!tsi_end_p (i
) && TREE_CODE (tsi_stmt (i
)) == DEBUG_BEGIN_STMT
)
3591 if (!tsi_one_before_end_p (i
))
3594 return find_goto (tsi_stmt (i
));
3597 /* Same as find_goto, except that it returns NULL if the destination
3598 is not a LABEL_DECL. */
3601 find_goto_label (tree expr
)
3603 tree dest
= find_goto (expr
);
3604 if (dest
&& TREE_CODE (GOTO_DESTINATION (dest
)) == LABEL_DECL
)
3609 /* Given a conditional expression EXPR with short-circuit boolean
3610 predicates using TRUTH_ANDIF_EXPR or TRUTH_ORIF_EXPR, break the
3611 predicate apart into the equivalent sequence of conditionals. */
3614 shortcut_cond_expr (tree expr
)
3616 tree pred
= TREE_OPERAND (expr
, 0);
3617 tree then_
= TREE_OPERAND (expr
, 1);
3618 tree else_
= TREE_OPERAND (expr
, 2);
3619 tree true_label
, false_label
, end_label
, t
;
3621 tree
*false_label_p
;
3622 bool emit_end
, emit_false
, jump_over_else
;
3623 bool then_se
= then_
&& TREE_SIDE_EFFECTS (then_
);
3624 bool else_se
= else_
&& TREE_SIDE_EFFECTS (else_
);
3626 /* First do simple transformations. */
3629 /* If there is no 'else', turn
3632 if (a) if (b) then c. */
3633 while (TREE_CODE (pred
) == TRUTH_ANDIF_EXPR
)
3635 /* Keep the original source location on the first 'if'. */
3636 location_t locus
= EXPR_LOC_OR_LOC (expr
, input_location
);
3637 TREE_OPERAND (expr
, 0) = TREE_OPERAND (pred
, 1);
3638 /* Set the source location of the && on the second 'if'. */
3639 if (rexpr_has_location (pred
))
3640 SET_EXPR_LOCATION (expr
, rexpr_location (pred
));
3641 then_
= shortcut_cond_expr (expr
);
3642 then_se
= then_
&& TREE_SIDE_EFFECTS (then_
);
3643 pred
= TREE_OPERAND (pred
, 0);
3644 expr
= build3 (COND_EXPR
, void_type_node
, pred
, then_
, NULL_TREE
);
3645 SET_EXPR_LOCATION (expr
, locus
);
3651 /* If there is no 'then', turn
3654 if (a); else if (b); else d. */
3655 while (TREE_CODE (pred
) == TRUTH_ORIF_EXPR
)
3657 /* Keep the original source location on the first 'if'. */
3658 location_t locus
= EXPR_LOC_OR_LOC (expr
, input_location
);
3659 TREE_OPERAND (expr
, 0) = TREE_OPERAND (pred
, 1);
3660 /* Set the source location of the || on the second 'if'. */
3661 if (rexpr_has_location (pred
))
3662 SET_EXPR_LOCATION (expr
, rexpr_location (pred
));
3663 else_
= shortcut_cond_expr (expr
);
3664 else_se
= else_
&& TREE_SIDE_EFFECTS (else_
);
3665 pred
= TREE_OPERAND (pred
, 0);
3666 expr
= build3 (COND_EXPR
, void_type_node
, pred
, NULL_TREE
, else_
);
3667 SET_EXPR_LOCATION (expr
, locus
);
3671 /* If we're done, great. */
3672 if (TREE_CODE (pred
) != TRUTH_ANDIF_EXPR
3673 && TREE_CODE (pred
) != TRUTH_ORIF_EXPR
)
3676 /* Otherwise we need to mess with gotos. Change
3679 if (a); else goto no;
3682 and recursively gimplify the condition. */
3684 true_label
= false_label
= end_label
= NULL_TREE
;
3686 /* If our arms just jump somewhere, hijack those labels so we don't
3687 generate jumps to jumps. */
3689 if (tree then_goto
= find_goto_label (then_
))
3691 true_label
= GOTO_DESTINATION (then_goto
);
3696 if (tree else_goto
= find_goto_label (else_
))
3698 false_label
= GOTO_DESTINATION (else_goto
);
3703 /* If we aren't hijacking a label for the 'then' branch, it falls through. */
3705 true_label_p
= &true_label
;
3707 true_label_p
= NULL
;
3709 /* The 'else' branch also needs a label if it contains interesting code. */
3710 if (false_label
|| else_se
)
3711 false_label_p
= &false_label
;
3713 false_label_p
= NULL
;
3715 /* If there was nothing else in our arms, just forward the label(s). */
3716 if (!then_se
&& !else_se
)
3717 return shortcut_cond_r (pred
, true_label_p
, false_label_p
,
3718 EXPR_LOC_OR_LOC (expr
, input_location
));
3720 /* If our last subexpression already has a terminal label, reuse it. */
3722 t
= expr_last (else_
);
3724 t
= expr_last (then_
);
3727 if (t
&& TREE_CODE (t
) == LABEL_EXPR
)
3728 end_label
= LABEL_EXPR_LABEL (t
);
3730 /* If we don't care about jumping to the 'else' branch, jump to the end
3731 if the condition is false. */
3733 false_label_p
= &end_label
;
3735 /* We only want to emit these labels if we aren't hijacking them. */
3736 emit_end
= (end_label
== NULL_TREE
);
3737 emit_false
= (false_label
== NULL_TREE
);
3739 /* We only emit the jump over the else clause if we have to--if the
3740 then clause may fall through. Otherwise we can wind up with a
3741 useless jump and a useless label at the end of gimplified code,
3742 which will cause us to think that this conditional as a whole
3743 falls through even if it doesn't. If we then inline a function
3744 which ends with such a condition, that can cause us to issue an
3745 inappropriate warning about control reaching the end of a
3746 non-void function. */
3747 jump_over_else
= block_may_fallthru (then_
);
3749 pred
= shortcut_cond_r (pred
, true_label_p
, false_label_p
,
3750 EXPR_LOC_OR_LOC (expr
, input_location
));
3753 append_to_statement_list (pred
, &expr
);
3755 append_to_statement_list (then_
, &expr
);
3760 tree last
= expr_last (expr
);
3761 t
= build_and_jump (&end_label
);
3762 if (rexpr_has_location (last
))
3763 SET_EXPR_LOCATION (t
, rexpr_location (last
));
3764 append_to_statement_list (t
, &expr
);
3768 t
= build1 (LABEL_EXPR
, void_type_node
, false_label
);
3769 append_to_statement_list (t
, &expr
);
3771 append_to_statement_list (else_
, &expr
);
3773 if (emit_end
&& end_label
)
3775 t
= build1 (LABEL_EXPR
, void_type_node
, end_label
);
3776 append_to_statement_list (t
, &expr
);
3782 /* EXPR is used in a boolean context; make sure it has BOOLEAN_TYPE. */
3785 gimple_boolify (tree expr
)
3787 tree type
= TREE_TYPE (expr
);
3788 location_t loc
= EXPR_LOCATION (expr
);
3790 if (TREE_CODE (expr
) == NE_EXPR
3791 && TREE_CODE (TREE_OPERAND (expr
, 0)) == CALL_EXPR
3792 && integer_zerop (TREE_OPERAND (expr
, 1)))
3794 tree call
= TREE_OPERAND (expr
, 0);
3795 tree fn
= get_callee_fndecl (call
);
3797 /* For __builtin_expect ((long) (x), y) recurse into x as well
3798 if x is truth_value_p. */
3800 && fndecl_built_in_p (fn
, BUILT_IN_EXPECT
)
3801 && call_expr_nargs (call
) == 2)
3803 tree arg
= CALL_EXPR_ARG (call
, 0);
3806 if (TREE_CODE (arg
) == NOP_EXPR
3807 && TREE_TYPE (arg
) == TREE_TYPE (call
))
3808 arg
= TREE_OPERAND (arg
, 0);
3809 if (truth_value_p (TREE_CODE (arg
)))
3811 arg
= gimple_boolify (arg
);
3812 CALL_EXPR_ARG (call
, 0)
3813 = fold_convert_loc (loc
, TREE_TYPE (call
), arg
);
3819 switch (TREE_CODE (expr
))
3821 case TRUTH_AND_EXPR
:
3823 case TRUTH_XOR_EXPR
:
3824 case TRUTH_ANDIF_EXPR
:
3825 case TRUTH_ORIF_EXPR
:
3826 /* Also boolify the arguments of truth exprs. */
3827 TREE_OPERAND (expr
, 1) = gimple_boolify (TREE_OPERAND (expr
, 1));
3830 case TRUTH_NOT_EXPR
:
3831 TREE_OPERAND (expr
, 0) = gimple_boolify (TREE_OPERAND (expr
, 0));
3833 /* These expressions always produce boolean results. */
3834 if (TREE_CODE (type
) != BOOLEAN_TYPE
)
3835 TREE_TYPE (expr
) = boolean_type_node
;
3839 switch ((enum annot_expr_kind
) TREE_INT_CST_LOW (TREE_OPERAND (expr
, 1)))
3841 case annot_expr_ivdep_kind
:
3842 case annot_expr_unroll_kind
:
3843 case annot_expr_no_vector_kind
:
3844 case annot_expr_vector_kind
:
3845 case annot_expr_parallel_kind
:
3846 TREE_OPERAND (expr
, 0) = gimple_boolify (TREE_OPERAND (expr
, 0));
3847 if (TREE_CODE (type
) != BOOLEAN_TYPE
)
3848 TREE_TYPE (expr
) = boolean_type_node
;
3855 if (COMPARISON_CLASS_P (expr
))
3857 /* There expressions always prduce boolean results. */
3858 if (TREE_CODE (type
) != BOOLEAN_TYPE
)
3859 TREE_TYPE (expr
) = boolean_type_node
;
3862 /* Other expressions that get here must have boolean values, but
3863 might need to be converted to the appropriate mode. */
3864 if (TREE_CODE (type
) == BOOLEAN_TYPE
)
3866 return fold_convert_loc (loc
, boolean_type_node
, expr
);
3870 /* Given a conditional expression *EXPR_P without side effects, gimplify
3871 its operands. New statements are inserted to PRE_P. */
3873 static enum gimplify_status
3874 gimplify_pure_cond_expr (tree
*expr_p
, gimple_seq
*pre_p
)
3876 tree expr
= *expr_p
, cond
;
3877 enum gimplify_status ret
, tret
;
3878 enum tree_code code
;
3880 cond
= gimple_boolify (COND_EXPR_COND (expr
));
3882 /* We need to handle && and || specially, as their gimplification
3883 creates pure cond_expr, thus leading to an infinite cycle otherwise. */
3884 code
= TREE_CODE (cond
);
3885 if (code
== TRUTH_ANDIF_EXPR
)
3886 TREE_SET_CODE (cond
, TRUTH_AND_EXPR
);
3887 else if (code
== TRUTH_ORIF_EXPR
)
3888 TREE_SET_CODE (cond
, TRUTH_OR_EXPR
);
3889 ret
= gimplify_expr (&cond
, pre_p
, NULL
, is_gimple_condexpr
, fb_rvalue
);
3890 COND_EXPR_COND (*expr_p
) = cond
;
3892 tret
= gimplify_expr (&COND_EXPR_THEN (expr
), pre_p
, NULL
,
3893 is_gimple_val
, fb_rvalue
);
3894 ret
= MIN (ret
, tret
);
3895 tret
= gimplify_expr (&COND_EXPR_ELSE (expr
), pre_p
, NULL
,
3896 is_gimple_val
, fb_rvalue
);
3898 return MIN (ret
, tret
);
3901 /* Return true if evaluating EXPR could trap.
3902 EXPR is GENERIC, while tree_could_trap_p can be called
3906 generic_expr_could_trap_p (tree expr
)
3910 if (!expr
|| is_gimple_val (expr
))
3913 if (!EXPR_P (expr
) || tree_could_trap_p (expr
))
3916 n
= TREE_OPERAND_LENGTH (expr
);
3917 for (i
= 0; i
< n
; i
++)
3918 if (generic_expr_could_trap_p (TREE_OPERAND (expr
, i
)))
3924 /* Convert the conditional expression pointed to by EXPR_P '(p) ? a : b;'
3933 The second form is used when *EXPR_P is of type void.
3935 PRE_P points to the list where side effects that must happen before
3936 *EXPR_P should be stored. */
3938 static enum gimplify_status
3939 gimplify_cond_expr (tree
*expr_p
, gimple_seq
*pre_p
, fallback_t fallback
)
3941 tree expr
= *expr_p
;
3942 tree type
= TREE_TYPE (expr
);
3943 location_t loc
= EXPR_LOCATION (expr
);
3944 tree tmp
, arm1
, arm2
;
3945 enum gimplify_status ret
;
3946 tree label_true
, label_false
, label_cont
;
3947 bool have_then_clause_p
, have_else_clause_p
;
3949 enum tree_code pred_code
;
3950 gimple_seq seq
= NULL
;
3952 /* If this COND_EXPR has a value, copy the values into a temporary within
3954 if (!VOID_TYPE_P (type
))
3956 tree then_
= TREE_OPERAND (expr
, 1), else_
= TREE_OPERAND (expr
, 2);
3959 /* If either an rvalue is ok or we do not require an lvalue, create the
3960 temporary. But we cannot do that if the type is addressable. */
3961 if (((fallback
& fb_rvalue
) || !(fallback
& fb_lvalue
))
3962 && !TREE_ADDRESSABLE (type
))
3964 if (gimplify_ctxp
->allow_rhs_cond_expr
3965 /* If either branch has side effects or could trap, it can't be
3966 evaluated unconditionally. */
3967 && !TREE_SIDE_EFFECTS (then_
)
3968 && !generic_expr_could_trap_p (then_
)
3969 && !TREE_SIDE_EFFECTS (else_
)
3970 && !generic_expr_could_trap_p (else_
))
3971 return gimplify_pure_cond_expr (expr_p
, pre_p
);
3973 tmp
= create_tmp_var (type
, "iftmp");
3977 /* Otherwise, only create and copy references to the values. */
3980 type
= build_pointer_type (type
);
3982 if (!VOID_TYPE_P (TREE_TYPE (then_
)))
3983 then_
= build_fold_addr_expr_loc (loc
, then_
);
3985 if (!VOID_TYPE_P (TREE_TYPE (else_
)))
3986 else_
= build_fold_addr_expr_loc (loc
, else_
);
3989 = build3 (COND_EXPR
, type
, TREE_OPERAND (expr
, 0), then_
, else_
);
3991 tmp
= create_tmp_var (type
, "iftmp");
3992 result
= build_simple_mem_ref_loc (loc
, tmp
);
3995 /* Build the new then clause, `tmp = then_;'. But don't build the
3996 assignment if the value is void; in C++ it can be if it's a throw. */
3997 if (!VOID_TYPE_P (TREE_TYPE (then_
)))
3998 TREE_OPERAND (expr
, 1) = build2 (MODIFY_EXPR
, type
, tmp
, then_
);
4000 /* Similarly, build the new else clause, `tmp = else_;'. */
4001 if (!VOID_TYPE_P (TREE_TYPE (else_
)))
4002 TREE_OPERAND (expr
, 2) = build2 (MODIFY_EXPR
, type
, tmp
, else_
);
4004 TREE_TYPE (expr
) = void_type_node
;
4005 recalculate_side_effects (expr
);
4007 /* Move the COND_EXPR to the prequeue. */
4008 gimplify_stmt (&expr
, pre_p
);
4014 /* Remove any COMPOUND_EXPR so the following cases will be caught. */
4015 STRIP_TYPE_NOPS (TREE_OPERAND (expr
, 0));
4016 if (TREE_CODE (TREE_OPERAND (expr
, 0)) == COMPOUND_EXPR
)
4017 gimplify_compound_expr (&TREE_OPERAND (expr
, 0), pre_p
, true);
4019 /* Make sure the condition has BOOLEAN_TYPE. */
4020 TREE_OPERAND (expr
, 0) = gimple_boolify (TREE_OPERAND (expr
, 0));
4022 /* Break apart && and || conditions. */
4023 if (TREE_CODE (TREE_OPERAND (expr
, 0)) == TRUTH_ANDIF_EXPR
4024 || TREE_CODE (TREE_OPERAND (expr
, 0)) == TRUTH_ORIF_EXPR
)
4026 expr
= shortcut_cond_expr (expr
);
4028 if (expr
!= *expr_p
)
4032 /* We can't rely on gimplify_expr to re-gimplify the expanded
4033 form properly, as cleanups might cause the target labels to be
4034 wrapped in a TRY_FINALLY_EXPR. To prevent that, we need to
4035 set up a conditional context. */
4036 gimple_push_condition ();
4037 gimplify_stmt (expr_p
, &seq
);
4038 gimple_pop_condition (pre_p
);
4039 gimple_seq_add_seq (pre_p
, seq
);
4045 /* Now do the normal gimplification. */
4047 /* Gimplify condition. */
4048 ret
= gimplify_expr (&TREE_OPERAND (expr
, 0), pre_p
, NULL
, is_gimple_condexpr
,
4050 if (ret
== GS_ERROR
)
4052 gcc_assert (TREE_OPERAND (expr
, 0) != NULL_TREE
);
4054 gimple_push_condition ();
4056 have_then_clause_p
= have_else_clause_p
= false;
4057 label_true
= find_goto_label (TREE_OPERAND (expr
, 1));
4059 && DECL_CONTEXT (GOTO_DESTINATION (label_true
)) == current_function_decl
4060 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4061 have different locations, otherwise we end up with incorrect
4062 location information on the branches. */
4064 || !EXPR_HAS_LOCATION (expr
)
4065 || !rexpr_has_location (label_true
)
4066 || EXPR_LOCATION (expr
) == rexpr_location (label_true
)))
4068 have_then_clause_p
= true;
4069 label_true
= GOTO_DESTINATION (label_true
);
4072 label_true
= create_artificial_label (UNKNOWN_LOCATION
);
4073 label_false
= find_goto_label (TREE_OPERAND (expr
, 2));
4075 && DECL_CONTEXT (GOTO_DESTINATION (label_false
)) == current_function_decl
4076 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4077 have different locations, otherwise we end up with incorrect
4078 location information on the branches. */
4080 || !EXPR_HAS_LOCATION (expr
)
4081 || !rexpr_has_location (label_false
)
4082 || EXPR_LOCATION (expr
) == rexpr_location (label_false
)))
4084 have_else_clause_p
= true;
4085 label_false
= GOTO_DESTINATION (label_false
);
4088 label_false
= create_artificial_label (UNKNOWN_LOCATION
);
4090 gimple_cond_get_ops_from_tree (COND_EXPR_COND (expr
), &pred_code
, &arm1
,
4092 cond_stmt
= gimple_build_cond (pred_code
, arm1
, arm2
, label_true
,
4094 gimple_set_no_warning (cond_stmt
, TREE_NO_WARNING (COND_EXPR_COND (expr
)));
4095 gimplify_seq_add_stmt (&seq
, cond_stmt
);
4096 gimple_stmt_iterator gsi
= gsi_last (seq
);
4097 maybe_fold_stmt (&gsi
);
4099 label_cont
= NULL_TREE
;
4100 if (!have_then_clause_p
)
4102 /* For if (...) {} else { code; } put label_true after
4104 if (TREE_OPERAND (expr
, 1) == NULL_TREE
4105 && !have_else_clause_p
4106 && TREE_OPERAND (expr
, 2) != NULL_TREE
)
4107 label_cont
= label_true
;
4110 gimplify_seq_add_stmt (&seq
, gimple_build_label (label_true
));
4111 have_then_clause_p
= gimplify_stmt (&TREE_OPERAND (expr
, 1), &seq
);
4112 /* For if (...) { code; } else {} or
4113 if (...) { code; } else goto label; or
4114 if (...) { code; return; } else { ... }
4115 label_cont isn't needed. */
4116 if (!have_else_clause_p
4117 && TREE_OPERAND (expr
, 2) != NULL_TREE
4118 && gimple_seq_may_fallthru (seq
))
4121 label_cont
= create_artificial_label (UNKNOWN_LOCATION
);
4123 g
= gimple_build_goto (label_cont
);
4125 /* GIMPLE_COND's are very low level; they have embedded
4126 gotos. This particular embedded goto should not be marked
4127 with the location of the original COND_EXPR, as it would
4128 correspond to the COND_EXPR's condition, not the ELSE or the
4129 THEN arms. To avoid marking it with the wrong location, flag
4130 it as "no location". */
4131 gimple_set_do_not_emit_location (g
);
4133 gimplify_seq_add_stmt (&seq
, g
);
4137 if (!have_else_clause_p
)
4139 gimplify_seq_add_stmt (&seq
, gimple_build_label (label_false
));
4140 have_else_clause_p
= gimplify_stmt (&TREE_OPERAND (expr
, 2), &seq
);
4143 gimplify_seq_add_stmt (&seq
, gimple_build_label (label_cont
));
4145 gimple_pop_condition (pre_p
);
4146 gimple_seq_add_seq (pre_p
, seq
);
4148 if (ret
== GS_ERROR
)
4150 else if (have_then_clause_p
|| have_else_clause_p
)
4154 /* Both arms are empty; replace the COND_EXPR with its predicate. */
4155 expr
= TREE_OPERAND (expr
, 0);
4156 gimplify_stmt (&expr
, pre_p
);
4163 /* Prepare the node pointed to by EXPR_P, an is_gimple_addressable expression,
4164 to be marked addressable.
4166 We cannot rely on such an expression being directly markable if a temporary
4167 has been created by the gimplification. In this case, we create another
4168 temporary and initialize it with a copy, which will become a store after we
4169 mark it addressable. This can happen if the front-end passed us something
4170 that it could not mark addressable yet, like a Fortran pass-by-reference
4171 parameter (int) floatvar. */
4174 prepare_gimple_addressable (tree
*expr_p
, gimple_seq
*seq_p
)
4176 while (handled_component_p (*expr_p
))
4177 expr_p
= &TREE_OPERAND (*expr_p
, 0);
4178 if (is_gimple_reg (*expr_p
))
4180 /* Do not allow an SSA name as the temporary. */
4181 tree var
= get_initialized_tmp_var (*expr_p
, seq_p
, NULL
, false);
4182 DECL_GIMPLE_REG_P (var
) = 0;
4187 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4188 a call to __builtin_memcpy. */
4190 static enum gimplify_status
4191 gimplify_modify_expr_to_memcpy (tree
*expr_p
, tree size
, bool want_value
,
4194 tree t
, to
, to_ptr
, from
, from_ptr
;
4196 location_t loc
= EXPR_LOCATION (*expr_p
);
4198 to
= TREE_OPERAND (*expr_p
, 0);
4199 from
= TREE_OPERAND (*expr_p
, 1);
4201 /* Mark the RHS addressable. Beware that it may not be possible to do so
4202 directly if a temporary has been created by the gimplification. */
4203 prepare_gimple_addressable (&from
, seq_p
);
4205 mark_addressable (from
);
4206 from_ptr
= build_fold_addr_expr_loc (loc
, from
);
4207 gimplify_arg (&from_ptr
, seq_p
, loc
);
4209 mark_addressable (to
);
4210 to_ptr
= build_fold_addr_expr_loc (loc
, to
);
4211 gimplify_arg (&to_ptr
, seq_p
, loc
);
4213 t
= builtin_decl_implicit (BUILT_IN_MEMCPY
);
4215 gs
= gimple_build_call (t
, 3, to_ptr
, from_ptr
, size
);
4219 /* tmp = memcpy() */
4220 t
= create_tmp_var (TREE_TYPE (to_ptr
));
4221 gimple_call_set_lhs (gs
, t
);
4222 gimplify_seq_add_stmt (seq_p
, gs
);
4224 *expr_p
= build_simple_mem_ref (t
);
4228 gimplify_seq_add_stmt (seq_p
, gs
);
4233 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4234 a call to __builtin_memset. In this case we know that the RHS is
4235 a CONSTRUCTOR with an empty element list. */
4237 static enum gimplify_status
4238 gimplify_modify_expr_to_memset (tree
*expr_p
, tree size
, bool want_value
,
4241 tree t
, from
, to
, to_ptr
;
4243 location_t loc
= EXPR_LOCATION (*expr_p
);
4245 /* Assert our assumptions, to abort instead of producing wrong code
4246 silently if they are not met. Beware that the RHS CONSTRUCTOR might
4247 not be immediately exposed. */
4248 from
= TREE_OPERAND (*expr_p
, 1);
4249 if (TREE_CODE (from
) == WITH_SIZE_EXPR
)
4250 from
= TREE_OPERAND (from
, 0);
4252 gcc_assert (TREE_CODE (from
) == CONSTRUCTOR
4253 && vec_safe_is_empty (CONSTRUCTOR_ELTS (from
)));
4256 to
= TREE_OPERAND (*expr_p
, 0);
4258 to_ptr
= build_fold_addr_expr_loc (loc
, to
);
4259 gimplify_arg (&to_ptr
, seq_p
, loc
);
4260 t
= builtin_decl_implicit (BUILT_IN_MEMSET
);
4262 gs
= gimple_build_call (t
, 3, to_ptr
, integer_zero_node
, size
);
4266 /* tmp = memset() */
4267 t
= create_tmp_var (TREE_TYPE (to_ptr
));
4268 gimple_call_set_lhs (gs
, t
);
4269 gimplify_seq_add_stmt (seq_p
, gs
);
4271 *expr_p
= build1 (INDIRECT_REF
, TREE_TYPE (to
), t
);
4275 gimplify_seq_add_stmt (seq_p
, gs
);
4280 /* A subroutine of gimplify_init_ctor_preeval. Called via walk_tree,
4281 determine, cautiously, if a CONSTRUCTOR overlaps the lhs of an
4282 assignment. Return non-null if we detect a potential overlap. */
4284 struct gimplify_init_ctor_preeval_data
4286 /* The base decl of the lhs object. May be NULL, in which case we
4287 have to assume the lhs is indirect. */
4290 /* The alias set of the lhs object. */
4291 alias_set_type lhs_alias_set
;
4295 gimplify_init_ctor_preeval_1 (tree
*tp
, int *walk_subtrees
, void *xdata
)
4297 struct gimplify_init_ctor_preeval_data
*data
4298 = (struct gimplify_init_ctor_preeval_data
*) xdata
;
4301 /* If we find the base object, obviously we have overlap. */
4302 if (data
->lhs_base_decl
== t
)
4305 /* If the constructor component is indirect, determine if we have a
4306 potential overlap with the lhs. The only bits of information we
4307 have to go on at this point are addressability and alias sets. */
4308 if ((INDIRECT_REF_P (t
)
4309 || TREE_CODE (t
) == MEM_REF
)
4310 && (!data
->lhs_base_decl
|| TREE_ADDRESSABLE (data
->lhs_base_decl
))
4311 && alias_sets_conflict_p (data
->lhs_alias_set
, get_alias_set (t
)))
4314 /* If the constructor component is a call, determine if it can hide a
4315 potential overlap with the lhs through an INDIRECT_REF like above.
4316 ??? Ugh - this is completely broken. In fact this whole analysis
4317 doesn't look conservative. */
4318 if (TREE_CODE (t
) == CALL_EXPR
)
4320 tree type
, fntype
= TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (t
)));
4322 for (type
= TYPE_ARG_TYPES (fntype
); type
; type
= TREE_CHAIN (type
))
4323 if (POINTER_TYPE_P (TREE_VALUE (type
))
4324 && (!data
->lhs_base_decl
|| TREE_ADDRESSABLE (data
->lhs_base_decl
))
4325 && alias_sets_conflict_p (data
->lhs_alias_set
,
4327 (TREE_TYPE (TREE_VALUE (type
)))))
4331 if (IS_TYPE_OR_DECL_P (t
))
4336 /* A subroutine of gimplify_init_constructor. Pre-evaluate EXPR,
4337 force values that overlap with the lhs (as described by *DATA)
4338 into temporaries. */
4341 gimplify_init_ctor_preeval (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
4342 struct gimplify_init_ctor_preeval_data
*data
)
4344 enum gimplify_status one
;
4346 /* If the value is constant, then there's nothing to pre-evaluate. */
4347 if (TREE_CONSTANT (*expr_p
))
4349 /* Ensure it does not have side effects, it might contain a reference to
4350 the object we're initializing. */
4351 gcc_assert (!TREE_SIDE_EFFECTS (*expr_p
));
4355 /* If the type has non-trivial constructors, we can't pre-evaluate. */
4356 if (TREE_ADDRESSABLE (TREE_TYPE (*expr_p
)))
4359 /* Recurse for nested constructors. */
4360 if (TREE_CODE (*expr_p
) == CONSTRUCTOR
)
4362 unsigned HOST_WIDE_INT ix
;
4363 constructor_elt
*ce
;
4364 vec
<constructor_elt
, va_gc
> *v
= CONSTRUCTOR_ELTS (*expr_p
);
4366 FOR_EACH_VEC_SAFE_ELT (v
, ix
, ce
)
4367 gimplify_init_ctor_preeval (&ce
->value
, pre_p
, post_p
, data
);
4372 /* If this is a variable sized type, we must remember the size. */
4373 maybe_with_size_expr (expr_p
);
4375 /* Gimplify the constructor element to something appropriate for the rhs
4376 of a MODIFY_EXPR. Given that we know the LHS is an aggregate, we know
4377 the gimplifier will consider this a store to memory. Doing this
4378 gimplification now means that we won't have to deal with complicated
4379 language-specific trees, nor trees like SAVE_EXPR that can induce
4380 exponential search behavior. */
4381 one
= gimplify_expr (expr_p
, pre_p
, post_p
, is_gimple_mem_rhs
, fb_rvalue
);
4382 if (one
== GS_ERROR
)
4388 /* If we gimplified to a bare decl, we can be sure that it doesn't overlap
4389 with the lhs, since "a = { .x=a }" doesn't make sense. This will
4390 always be true for all scalars, since is_gimple_mem_rhs insists on a
4391 temporary variable for them. */
4392 if (DECL_P (*expr_p
))
4395 /* If this is of variable size, we have no choice but to assume it doesn't
4396 overlap since we can't make a temporary for it. */
4397 if (TREE_CODE (TYPE_SIZE (TREE_TYPE (*expr_p
))) != INTEGER_CST
)
4400 /* Otherwise, we must search for overlap ... */
4401 if (!walk_tree (expr_p
, gimplify_init_ctor_preeval_1
, data
, NULL
))
4404 /* ... and if found, force the value into a temporary. */
4405 *expr_p
= get_formal_tmp_var (*expr_p
, pre_p
);
4408 /* A subroutine of gimplify_init_ctor_eval. Create a loop for
4409 a RANGE_EXPR in a CONSTRUCTOR for an array.
4413 object[var] = value;
4420 We increment var _after_ the loop exit check because we might otherwise
4421 fail if upper == TYPE_MAX_VALUE (type for upper).
4423 Note that we never have to deal with SAVE_EXPRs here, because this has
4424 already been taken care of for us, in gimplify_init_ctor_preeval(). */
4426 static void gimplify_init_ctor_eval (tree
, vec
<constructor_elt
, va_gc
> *,
4427 gimple_seq
*, bool);
4430 gimplify_init_ctor_eval_range (tree object
, tree lower
, tree upper
,
4431 tree value
, tree array_elt_type
,
4432 gimple_seq
*pre_p
, bool cleared
)
4434 tree loop_entry_label
, loop_exit_label
, fall_thru_label
;
4435 tree var
, var_type
, cref
, tmp
;
4437 loop_entry_label
= create_artificial_label (UNKNOWN_LOCATION
);
4438 loop_exit_label
= create_artificial_label (UNKNOWN_LOCATION
);
4439 fall_thru_label
= create_artificial_label (UNKNOWN_LOCATION
);
4441 /* Create and initialize the index variable. */
4442 var_type
= TREE_TYPE (upper
);
4443 var
= create_tmp_var (var_type
);
4444 gimplify_seq_add_stmt (pre_p
, gimple_build_assign (var
, lower
));
4446 /* Add the loop entry label. */
4447 gimplify_seq_add_stmt (pre_p
, gimple_build_label (loop_entry_label
));
4449 /* Build the reference. */
4450 cref
= build4 (ARRAY_REF
, array_elt_type
, unshare_expr (object
),
4451 var
, NULL_TREE
, NULL_TREE
);
4453 /* If we are a constructor, just call gimplify_init_ctor_eval to do
4454 the store. Otherwise just assign value to the reference. */
4456 if (TREE_CODE (value
) == CONSTRUCTOR
)
4457 /* NB we might have to call ourself recursively through
4458 gimplify_init_ctor_eval if the value is a constructor. */
4459 gimplify_init_ctor_eval (cref
, CONSTRUCTOR_ELTS (value
),
4462 gimplify_seq_add_stmt (pre_p
, gimple_build_assign (cref
, value
));
4464 /* We exit the loop when the index var is equal to the upper bound. */
4465 gimplify_seq_add_stmt (pre_p
,
4466 gimple_build_cond (EQ_EXPR
, var
, upper
,
4467 loop_exit_label
, fall_thru_label
));
4469 gimplify_seq_add_stmt (pre_p
, gimple_build_label (fall_thru_label
));
4471 /* Otherwise, increment the index var... */
4472 tmp
= build2 (PLUS_EXPR
, var_type
, var
,
4473 fold_convert (var_type
, integer_one_node
));
4474 gimplify_seq_add_stmt (pre_p
, gimple_build_assign (var
, tmp
));
4476 /* ...and jump back to the loop entry. */
4477 gimplify_seq_add_stmt (pre_p
, gimple_build_goto (loop_entry_label
));
4479 /* Add the loop exit label. */
4480 gimplify_seq_add_stmt (pre_p
, gimple_build_label (loop_exit_label
));
4483 /* Return true if FDECL is accessing a field that is zero sized. */
4486 zero_sized_field_decl (const_tree fdecl
)
4488 if (TREE_CODE (fdecl
) == FIELD_DECL
&& DECL_SIZE (fdecl
)
4489 && integer_zerop (DECL_SIZE (fdecl
)))
4494 /* Return true if TYPE is zero sized. */
4497 zero_sized_type (const_tree type
)
4499 if (AGGREGATE_TYPE_P (type
) && TYPE_SIZE (type
)
4500 && integer_zerop (TYPE_SIZE (type
)))
4505 /* A subroutine of gimplify_init_constructor. Generate individual
4506 MODIFY_EXPRs for a CONSTRUCTOR. OBJECT is the LHS against which the
4507 assignments should happen. ELTS is the CONSTRUCTOR_ELTS of the
4508 CONSTRUCTOR. CLEARED is true if the entire LHS object has been
4512 gimplify_init_ctor_eval (tree object
, vec
<constructor_elt
, va_gc
> *elts
,
4513 gimple_seq
*pre_p
, bool cleared
)
4515 tree array_elt_type
= NULL
;
4516 unsigned HOST_WIDE_INT ix
;
4517 tree purpose
, value
;
4519 if (TREE_CODE (TREE_TYPE (object
)) == ARRAY_TYPE
)
4520 array_elt_type
= TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (object
)));
4522 FOR_EACH_CONSTRUCTOR_ELT (elts
, ix
, purpose
, value
)
4526 /* NULL values are created above for gimplification errors. */
4530 if (cleared
&& initializer_zerop (value
))
4533 /* ??? Here's to hoping the front end fills in all of the indices,
4534 so we don't have to figure out what's missing ourselves. */
4535 gcc_assert (purpose
);
4537 /* Skip zero-sized fields, unless value has side-effects. This can
4538 happen with calls to functions returning a zero-sized type, which
4539 we shouldn't discard. As a number of downstream passes don't
4540 expect sets of zero-sized fields, we rely on the gimplification of
4541 the MODIFY_EXPR we make below to drop the assignment statement. */
4542 if (! TREE_SIDE_EFFECTS (value
) && zero_sized_field_decl (purpose
))
4545 /* If we have a RANGE_EXPR, we have to build a loop to assign the
4547 if (TREE_CODE (purpose
) == RANGE_EXPR
)
4549 tree lower
= TREE_OPERAND (purpose
, 0);
4550 tree upper
= TREE_OPERAND (purpose
, 1);
4552 /* If the lower bound is equal to upper, just treat it as if
4553 upper was the index. */
4554 if (simple_cst_equal (lower
, upper
))
4558 gimplify_init_ctor_eval_range (object
, lower
, upper
, value
,
4559 array_elt_type
, pre_p
, cleared
);
4566 /* Do not use bitsizetype for ARRAY_REF indices. */
4567 if (TYPE_DOMAIN (TREE_TYPE (object
)))
4569 = fold_convert (TREE_TYPE (TYPE_DOMAIN (TREE_TYPE (object
))),
4571 cref
= build4 (ARRAY_REF
, array_elt_type
, unshare_expr (object
),
4572 purpose
, NULL_TREE
, NULL_TREE
);
4576 gcc_assert (TREE_CODE (purpose
) == FIELD_DECL
);
4577 cref
= build3 (COMPONENT_REF
, TREE_TYPE (purpose
),
4578 unshare_expr (object
), purpose
, NULL_TREE
);
4581 if (TREE_CODE (value
) == CONSTRUCTOR
4582 && TREE_CODE (TREE_TYPE (value
)) != VECTOR_TYPE
)
4583 gimplify_init_ctor_eval (cref
, CONSTRUCTOR_ELTS (value
),
4587 tree init
= build2 (INIT_EXPR
, TREE_TYPE (cref
), cref
, value
);
4588 gimplify_and_add (init
, pre_p
);
4594 /* Return the appropriate RHS predicate for this LHS. */
4597 rhs_predicate_for (tree lhs
)
4599 if (is_gimple_reg (lhs
))
4600 return is_gimple_reg_rhs_or_call
;
4602 return is_gimple_mem_rhs_or_call
;
4605 /* Return the initial guess for an appropriate RHS predicate for this LHS,
4606 before the LHS has been gimplified. */
4608 static gimple_predicate
4609 initial_rhs_predicate_for (tree lhs
)
4611 if (is_gimple_reg_type (TREE_TYPE (lhs
)))
4612 return is_gimple_reg_rhs_or_call
;
4614 return is_gimple_mem_rhs_or_call
;
4617 /* Gimplify a C99 compound literal expression. This just means adding
4618 the DECL_EXPR before the current statement and using its anonymous
4621 static enum gimplify_status
4622 gimplify_compound_literal_expr (tree
*expr_p
, gimple_seq
*pre_p
,
4623 bool (*gimple_test_f
) (tree
),
4624 fallback_t fallback
)
4626 tree decl_s
= COMPOUND_LITERAL_EXPR_DECL_EXPR (*expr_p
);
4627 tree decl
= DECL_EXPR_DECL (decl_s
);
4628 tree init
= DECL_INITIAL (decl
);
4629 /* Mark the decl as addressable if the compound literal
4630 expression is addressable now, otherwise it is marked too late
4631 after we gimplify the initialization expression. */
4632 if (TREE_ADDRESSABLE (*expr_p
))
4633 TREE_ADDRESSABLE (decl
) = 1;
4634 /* Otherwise, if we don't need an lvalue and have a literal directly
4635 substitute it. Check if it matches the gimple predicate, as
4636 otherwise we'd generate a new temporary, and we can as well just
4637 use the decl we already have. */
4638 else if (!TREE_ADDRESSABLE (decl
)
4640 && (fallback
& fb_lvalue
) == 0
4641 && gimple_test_f (init
))
4647 /* Preliminarily mark non-addressed complex variables as eligible
4648 for promotion to gimple registers. We'll transform their uses
4650 if ((TREE_CODE (TREE_TYPE (decl
)) == COMPLEX_TYPE
4651 || TREE_CODE (TREE_TYPE (decl
)) == VECTOR_TYPE
)
4652 && !TREE_THIS_VOLATILE (decl
)
4653 && !needs_to_live_in_memory (decl
))
4654 DECL_GIMPLE_REG_P (decl
) = 1;
4656 /* If the decl is not addressable, then it is being used in some
4657 expression or on the right hand side of a statement, and it can
4658 be put into a readonly data section. */
4659 if (!TREE_ADDRESSABLE (decl
) && (fallback
& fb_lvalue
) == 0)
4660 TREE_READONLY (decl
) = 1;
4662 /* This decl isn't mentioned in the enclosing block, so add it to the
4663 list of temps. FIXME it seems a bit of a kludge to say that
4664 anonymous artificial vars aren't pushed, but everything else is. */
4665 if (DECL_NAME (decl
) == NULL_TREE
&& !DECL_SEEN_IN_BIND_EXPR_P (decl
))
4666 gimple_add_tmp_var (decl
);
4668 gimplify_and_add (decl_s
, pre_p
);
4673 /* Optimize embedded COMPOUND_LITERAL_EXPRs within a CONSTRUCTOR,
4674 return a new CONSTRUCTOR if something changed. */
4677 optimize_compound_literals_in_ctor (tree orig_ctor
)
4679 tree ctor
= orig_ctor
;
4680 vec
<constructor_elt
, va_gc
> *elts
= CONSTRUCTOR_ELTS (ctor
);
4681 unsigned int idx
, num
= vec_safe_length (elts
);
4683 for (idx
= 0; idx
< num
; idx
++)
4685 tree value
= (*elts
)[idx
].value
;
4686 tree newval
= value
;
4687 if (TREE_CODE (value
) == CONSTRUCTOR
)
4688 newval
= optimize_compound_literals_in_ctor (value
);
4689 else if (TREE_CODE (value
) == COMPOUND_LITERAL_EXPR
)
4691 tree decl_s
= COMPOUND_LITERAL_EXPR_DECL_EXPR (value
);
4692 tree decl
= DECL_EXPR_DECL (decl_s
);
4693 tree init
= DECL_INITIAL (decl
);
4695 if (!TREE_ADDRESSABLE (value
)
4696 && !TREE_ADDRESSABLE (decl
)
4698 && TREE_CODE (init
) == CONSTRUCTOR
)
4699 newval
= optimize_compound_literals_in_ctor (init
);
4701 if (newval
== value
)
4704 if (ctor
== orig_ctor
)
4706 ctor
= copy_node (orig_ctor
);
4707 CONSTRUCTOR_ELTS (ctor
) = vec_safe_copy (elts
);
4708 elts
= CONSTRUCTOR_ELTS (ctor
);
4710 (*elts
)[idx
].value
= newval
;
4715 /* A subroutine of gimplify_modify_expr. Break out elements of a
4716 CONSTRUCTOR used as an initializer into separate MODIFY_EXPRs.
4718 Note that we still need to clear any elements that don't have explicit
4719 initializers, so if not all elements are initialized we keep the
4720 original MODIFY_EXPR, we just remove all of the constructor elements.
4722 If NOTIFY_TEMP_CREATION is true, do not gimplify, just return
4723 GS_ERROR if we would have to create a temporary when gimplifying
4724 this constructor. Otherwise, return GS_OK.
4726 If NOTIFY_TEMP_CREATION is false, just do the gimplification. */
4728 static enum gimplify_status
4729 gimplify_init_constructor (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
4730 bool want_value
, bool notify_temp_creation
)
4732 tree object
, ctor
, type
;
4733 enum gimplify_status ret
;
4734 vec
<constructor_elt
, va_gc
> *elts
;
4736 gcc_assert (TREE_CODE (TREE_OPERAND (*expr_p
, 1)) == CONSTRUCTOR
);
4738 if (!notify_temp_creation
)
4740 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
4741 is_gimple_lvalue
, fb_lvalue
);
4742 if (ret
== GS_ERROR
)
4746 object
= TREE_OPERAND (*expr_p
, 0);
4747 ctor
= TREE_OPERAND (*expr_p
, 1)
4748 = optimize_compound_literals_in_ctor (TREE_OPERAND (*expr_p
, 1));
4749 type
= TREE_TYPE (ctor
);
4750 elts
= CONSTRUCTOR_ELTS (ctor
);
4753 switch (TREE_CODE (type
))
4757 case QUAL_UNION_TYPE
:
4760 struct gimplify_init_ctor_preeval_data preeval_data
;
4761 HOST_WIDE_INT num_ctor_elements
, num_nonzero_elements
;
4762 bool cleared
, complete_p
, valid_const_initializer
;
4764 /* Aggregate types must lower constructors to initialization of
4765 individual elements. The exception is that a CONSTRUCTOR node
4766 with no elements indicates zero-initialization of the whole. */
4767 if (vec_safe_is_empty (elts
))
4769 if (notify_temp_creation
)
4774 /* Fetch information about the constructor to direct later processing.
4775 We might want to make static versions of it in various cases, and
4776 can only do so if it known to be a valid constant initializer. */
4777 valid_const_initializer
4778 = categorize_ctor_elements (ctor
, &num_nonzero_elements
,
4779 &num_ctor_elements
, &complete_p
);
4781 /* If a const aggregate variable is being initialized, then it
4782 should never be a lose to promote the variable to be static. */
4783 if (valid_const_initializer
4784 && num_nonzero_elements
> 1
4785 && TREE_READONLY (object
)
4787 && (flag_merge_constants
>= 2 || !TREE_ADDRESSABLE (object
)))
4789 if (notify_temp_creation
)
4791 DECL_INITIAL (object
) = ctor
;
4792 TREE_STATIC (object
) = 1;
4793 if (!DECL_NAME (object
))
4794 DECL_NAME (object
) = create_tmp_var_name ("C");
4795 walk_tree (&DECL_INITIAL (object
), force_labels_r
, NULL
, NULL
);
4797 /* ??? C++ doesn't automatically append a .<number> to the
4798 assembler name, and even when it does, it looks at FE private
4799 data structures to figure out what that number should be,
4800 which are not set for this variable. I suppose this is
4801 important for local statics for inline functions, which aren't
4802 "local" in the object file sense. So in order to get a unique
4803 TU-local symbol, we must invoke the lhd version now. */
4804 lhd_set_decl_assembler_name (object
);
4806 *expr_p
= NULL_TREE
;
4810 /* If there are "lots" of initialized elements, even discounting
4811 those that are not address constants (and thus *must* be
4812 computed at runtime), then partition the constructor into
4813 constant and non-constant parts. Block copy the constant
4814 parts in, then generate code for the non-constant parts. */
4815 /* TODO. There's code in cp/typeck.c to do this. */
4817 if (int_size_in_bytes (TREE_TYPE (ctor
)) < 0)
4818 /* store_constructor will ignore the clearing of variable-sized
4819 objects. Initializers for such objects must explicitly set
4820 every field that needs to be set. */
4822 else if (!complete_p
)
4823 /* If the constructor isn't complete, clear the whole object
4824 beforehand, unless CONSTRUCTOR_NO_CLEARING is set on it.
4826 ??? This ought not to be needed. For any element not present
4827 in the initializer, we should simply set them to zero. Except
4828 we'd need to *find* the elements that are not present, and that
4829 requires trickery to avoid quadratic compile-time behavior in
4830 large cases or excessive memory use in small cases. */
4831 cleared
= !CONSTRUCTOR_NO_CLEARING (ctor
);
4832 else if (num_ctor_elements
- num_nonzero_elements
4833 > CLEAR_RATIO (optimize_function_for_speed_p (cfun
))
4834 && num_nonzero_elements
< num_ctor_elements
/ 4)
4835 /* If there are "lots" of zeros, it's more efficient to clear
4836 the memory and then set the nonzero elements. */
4841 /* If there are "lots" of initialized elements, and all of them
4842 are valid address constants, then the entire initializer can
4843 be dropped to memory, and then memcpy'd out. Don't do this
4844 for sparse arrays, though, as it's more efficient to follow
4845 the standard CONSTRUCTOR behavior of memset followed by
4846 individual element initialization. Also don't do this for small
4847 all-zero initializers (which aren't big enough to merit
4848 clearing), and don't try to make bitwise copies of
4849 TREE_ADDRESSABLE types. */
4851 if (valid_const_initializer
4852 && !(cleared
|| num_nonzero_elements
== 0)
4853 && !TREE_ADDRESSABLE (type
))
4855 HOST_WIDE_INT size
= int_size_in_bytes (type
);
4858 /* ??? We can still get unbounded array types, at least
4859 from the C++ front end. This seems wrong, but attempt
4860 to work around it for now. */
4863 size
= int_size_in_bytes (TREE_TYPE (object
));
4865 TREE_TYPE (ctor
) = type
= TREE_TYPE (object
);
4868 /* Find the maximum alignment we can assume for the object. */
4869 /* ??? Make use of DECL_OFFSET_ALIGN. */
4870 if (DECL_P (object
))
4871 align
= DECL_ALIGN (object
);
4873 align
= TYPE_ALIGN (type
);
4875 /* Do a block move either if the size is so small as to make
4876 each individual move a sub-unit move on average, or if it
4877 is so large as to make individual moves inefficient. */
4879 && num_nonzero_elements
> 1
4880 && (size
< num_nonzero_elements
4881 || !can_move_by_pieces (size
, align
)))
4883 if (notify_temp_creation
)
4886 walk_tree (&ctor
, force_labels_r
, NULL
, NULL
);
4887 ctor
= tree_output_constant_def (ctor
);
4888 if (!useless_type_conversion_p (type
, TREE_TYPE (ctor
)))
4889 ctor
= build1 (VIEW_CONVERT_EXPR
, type
, ctor
);
4890 TREE_OPERAND (*expr_p
, 1) = ctor
;
4892 /* This is no longer an assignment of a CONSTRUCTOR, but
4893 we still may have processing to do on the LHS. So
4894 pretend we didn't do anything here to let that happen. */
4895 return GS_UNHANDLED
;
4899 /* If the target is volatile, we have non-zero elements and more than
4900 one field to assign, initialize the target from a temporary. */
4901 if (TREE_THIS_VOLATILE (object
)
4902 && !TREE_ADDRESSABLE (type
)
4903 && num_nonzero_elements
> 0
4904 && vec_safe_length (elts
) > 1)
4906 tree temp
= create_tmp_var (TYPE_MAIN_VARIANT (type
));
4907 TREE_OPERAND (*expr_p
, 0) = temp
;
4908 *expr_p
= build2 (COMPOUND_EXPR
, TREE_TYPE (*expr_p
),
4910 build2 (MODIFY_EXPR
, void_type_node
,
4915 if (notify_temp_creation
)
4918 /* If there are nonzero elements and if needed, pre-evaluate to capture
4919 elements overlapping with the lhs into temporaries. We must do this
4920 before clearing to fetch the values before they are zeroed-out. */
4921 if (num_nonzero_elements
> 0 && TREE_CODE (*expr_p
) != INIT_EXPR
)
4923 preeval_data
.lhs_base_decl
= get_base_address (object
);
4924 if (!DECL_P (preeval_data
.lhs_base_decl
))
4925 preeval_data
.lhs_base_decl
= NULL
;
4926 preeval_data
.lhs_alias_set
= get_alias_set (object
);
4928 gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p
, 1),
4929 pre_p
, post_p
, &preeval_data
);
4932 bool ctor_has_side_effects_p
4933 = TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p
, 1));
4937 /* Zap the CONSTRUCTOR element list, which simplifies this case.
4938 Note that we still have to gimplify, in order to handle the
4939 case of variable sized types. Avoid shared tree structures. */
4940 CONSTRUCTOR_ELTS (ctor
) = NULL
;
4941 TREE_SIDE_EFFECTS (ctor
) = 0;
4942 object
= unshare_expr (object
);
4943 gimplify_stmt (expr_p
, pre_p
);
4946 /* If we have not block cleared the object, or if there are nonzero
4947 elements in the constructor, or if the constructor has side effects,
4948 add assignments to the individual scalar fields of the object. */
4950 || num_nonzero_elements
> 0
4951 || ctor_has_side_effects_p
)
4952 gimplify_init_ctor_eval (object
, elts
, pre_p
, cleared
);
4954 *expr_p
= NULL_TREE
;
4962 if (notify_temp_creation
)
4965 /* Extract the real and imaginary parts out of the ctor. */
4966 gcc_assert (elts
->length () == 2);
4967 r
= (*elts
)[0].value
;
4968 i
= (*elts
)[1].value
;
4969 if (r
== NULL
|| i
== NULL
)
4971 tree zero
= build_zero_cst (TREE_TYPE (type
));
4978 /* Complex types have either COMPLEX_CST or COMPLEX_EXPR to
4979 represent creation of a complex value. */
4980 if (TREE_CONSTANT (r
) && TREE_CONSTANT (i
))
4982 ctor
= build_complex (type
, r
, i
);
4983 TREE_OPERAND (*expr_p
, 1) = ctor
;
4987 ctor
= build2 (COMPLEX_EXPR
, type
, r
, i
);
4988 TREE_OPERAND (*expr_p
, 1) = ctor
;
4989 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 1),
4992 rhs_predicate_for (TREE_OPERAND (*expr_p
, 0)),
5000 unsigned HOST_WIDE_INT ix
;
5001 constructor_elt
*ce
;
5003 if (notify_temp_creation
)
5006 /* Go ahead and simplify constant constructors to VECTOR_CST. */
5007 if (TREE_CONSTANT (ctor
))
5009 bool constant_p
= true;
5012 /* Even when ctor is constant, it might contain non-*_CST
5013 elements, such as addresses or trapping values like
5014 1.0/0.0 - 1.0/0.0. Such expressions don't belong
5015 in VECTOR_CST nodes. */
5016 FOR_EACH_CONSTRUCTOR_VALUE (elts
, ix
, value
)
5017 if (!CONSTANT_CLASS_P (value
))
5025 TREE_OPERAND (*expr_p
, 1) = build_vector_from_ctor (type
, elts
);
5029 TREE_CONSTANT (ctor
) = 0;
5032 /* Vector types use CONSTRUCTOR all the way through gimple
5033 compilation as a general initializer. */
5034 FOR_EACH_VEC_SAFE_ELT (elts
, ix
, ce
)
5036 enum gimplify_status tret
;
5037 tret
= gimplify_expr (&ce
->value
, pre_p
, post_p
, is_gimple_val
,
5039 if (tret
== GS_ERROR
)
5041 else if (TREE_STATIC (ctor
)
5042 && !initializer_constant_valid_p (ce
->value
,
5043 TREE_TYPE (ce
->value
)))
5044 TREE_STATIC (ctor
) = 0;
5046 if (!is_gimple_reg (TREE_OPERAND (*expr_p
, 0)))
5047 TREE_OPERAND (*expr_p
, 1) = get_formal_tmp_var (ctor
, pre_p
);
5052 /* So how did we get a CONSTRUCTOR for a scalar type? */
5056 if (ret
== GS_ERROR
)
5058 /* If we have gimplified both sides of the initializer but have
5059 not emitted an assignment, do so now. */
5062 tree lhs
= TREE_OPERAND (*expr_p
, 0);
5063 tree rhs
= TREE_OPERAND (*expr_p
, 1);
5064 if (want_value
&& object
== lhs
)
5065 lhs
= unshare_expr (lhs
);
5066 gassign
*init
= gimple_build_assign (lhs
, rhs
);
5067 gimplify_seq_add_stmt (pre_p
, init
);
5081 /* Given a pointer value OP0, return a simplified version of an
5082 indirection through OP0, or NULL_TREE if no simplification is
5083 possible. This may only be applied to a rhs of an expression.
5084 Note that the resulting type may be different from the type pointed
5085 to in the sense that it is still compatible from the langhooks
5089 gimple_fold_indirect_ref_rhs (tree t
)
5091 return gimple_fold_indirect_ref (t
);
5094 /* Subroutine of gimplify_modify_expr to do simplifications of
5095 MODIFY_EXPRs based on the code of the RHS. We loop for as long as
5096 something changes. */
5098 static enum gimplify_status
5099 gimplify_modify_expr_rhs (tree
*expr_p
, tree
*from_p
, tree
*to_p
,
5100 gimple_seq
*pre_p
, gimple_seq
*post_p
,
5103 enum gimplify_status ret
= GS_UNHANDLED
;
5109 switch (TREE_CODE (*from_p
))
5112 /* If we're assigning from a read-only variable initialized with
5113 a constructor, do the direct assignment from the constructor,
5114 but only if neither source nor target are volatile since this
5115 latter assignment might end up being done on a per-field basis. */
5116 if (DECL_INITIAL (*from_p
)
5117 && TREE_READONLY (*from_p
)
5118 && !TREE_THIS_VOLATILE (*from_p
)
5119 && !TREE_THIS_VOLATILE (*to_p
)
5120 && TREE_CODE (DECL_INITIAL (*from_p
)) == CONSTRUCTOR
)
5122 tree old_from
= *from_p
;
5123 enum gimplify_status subret
;
5125 /* Move the constructor into the RHS. */
5126 *from_p
= unshare_expr (DECL_INITIAL (*from_p
));
5128 /* Let's see if gimplify_init_constructor will need to put
5130 subret
= gimplify_init_constructor (expr_p
, NULL
, NULL
,
5132 if (subret
== GS_ERROR
)
5134 /* If so, revert the change. */
5146 /* If we have code like
5150 where the type of "x" is a (possibly cv-qualified variant
5151 of "A"), treat the entire expression as identical to "x".
5152 This kind of code arises in C++ when an object is bound
5153 to a const reference, and if "x" is a TARGET_EXPR we want
5154 to take advantage of the optimization below. */
5155 bool volatile_p
= TREE_THIS_VOLATILE (*from_p
);
5156 tree t
= gimple_fold_indirect_ref_rhs (TREE_OPERAND (*from_p
, 0));
5159 if (TREE_THIS_VOLATILE (t
) != volatile_p
)
5162 t
= build_simple_mem_ref_loc (EXPR_LOCATION (*from_p
),
5163 build_fold_addr_expr (t
));
5164 if (REFERENCE_CLASS_P (t
))
5165 TREE_THIS_VOLATILE (t
) = volatile_p
;
5176 /* If we are initializing something from a TARGET_EXPR, strip the
5177 TARGET_EXPR and initialize it directly, if possible. This can't
5178 be done if the initializer is void, since that implies that the
5179 temporary is set in some non-trivial way.
5181 ??? What about code that pulls out the temp and uses it
5182 elsewhere? I think that such code never uses the TARGET_EXPR as
5183 an initializer. If I'm wrong, we'll die because the temp won't
5184 have any RTL. In that case, I guess we'll need to replace
5185 references somehow. */
5186 tree init
= TARGET_EXPR_INITIAL (*from_p
);
5189 && (TREE_CODE (*expr_p
) != MODIFY_EXPR
5190 || !TARGET_EXPR_NO_ELIDE (*from_p
))
5191 && !VOID_TYPE_P (TREE_TYPE (init
)))
5201 /* Remove any COMPOUND_EXPR in the RHS so the following cases will be
5203 gimplify_compound_expr (from_p
, pre_p
, true);
5209 /* If we already made some changes, let the front end have a
5210 crack at this before we break it down. */
5211 if (ret
!= GS_UNHANDLED
)
5213 /* If we're initializing from a CONSTRUCTOR, break this into
5214 individual MODIFY_EXPRs. */
5215 return gimplify_init_constructor (expr_p
, pre_p
, post_p
, want_value
,
5219 /* If we're assigning to a non-register type, push the assignment
5220 down into the branches. This is mandatory for ADDRESSABLE types,
5221 since we cannot generate temporaries for such, but it saves a
5222 copy in other cases as well. */
5223 if (!is_gimple_reg_type (TREE_TYPE (*from_p
)))
5225 /* This code should mirror the code in gimplify_cond_expr. */
5226 enum tree_code code
= TREE_CODE (*expr_p
);
5227 tree cond
= *from_p
;
5228 tree result
= *to_p
;
5230 ret
= gimplify_expr (&result
, pre_p
, post_p
,
5231 is_gimple_lvalue
, fb_lvalue
);
5232 if (ret
!= GS_ERROR
)
5235 /* If we are going to write RESULT more than once, clear
5236 TREE_READONLY flag, otherwise we might incorrectly promote
5237 the variable to static const and initialize it at compile
5238 time in one of the branches. */
5240 && TREE_TYPE (TREE_OPERAND (cond
, 1)) != void_type_node
5241 && TREE_TYPE (TREE_OPERAND (cond
, 2)) != void_type_node
)
5242 TREE_READONLY (result
) = 0;
5243 if (TREE_TYPE (TREE_OPERAND (cond
, 1)) != void_type_node
)
5244 TREE_OPERAND (cond
, 1)
5245 = build2 (code
, void_type_node
, result
,
5246 TREE_OPERAND (cond
, 1));
5247 if (TREE_TYPE (TREE_OPERAND (cond
, 2)) != void_type_node
)
5248 TREE_OPERAND (cond
, 2)
5249 = build2 (code
, void_type_node
, unshare_expr (result
),
5250 TREE_OPERAND (cond
, 2));
5252 TREE_TYPE (cond
) = void_type_node
;
5253 recalculate_side_effects (cond
);
5257 gimplify_and_add (cond
, pre_p
);
5258 *expr_p
= unshare_expr (result
);
5267 /* For calls that return in memory, give *to_p as the CALL_EXPR's
5268 return slot so that we don't generate a temporary. */
5269 if (!CALL_EXPR_RETURN_SLOT_OPT (*from_p
)
5270 && aggregate_value_p (*from_p
, *from_p
))
5274 if (!(rhs_predicate_for (*to_p
))(*from_p
))
5275 /* If we need a temporary, *to_p isn't accurate. */
5277 /* It's OK to use the return slot directly unless it's an NRV. */
5278 else if (TREE_CODE (*to_p
) == RESULT_DECL
5279 && DECL_NAME (*to_p
) == NULL_TREE
5280 && needs_to_live_in_memory (*to_p
))
5282 else if (is_gimple_reg_type (TREE_TYPE (*to_p
))
5283 || (DECL_P (*to_p
) && DECL_REGISTER (*to_p
)))
5284 /* Don't force regs into memory. */
5286 else if (TREE_CODE (*expr_p
) == INIT_EXPR
)
5287 /* It's OK to use the target directly if it's being
5290 else if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p
)))
5292 /* Always use the target and thus RSO for variable-sized types.
5293 GIMPLE cannot deal with a variable-sized assignment
5294 embedded in a call statement. */
5296 else if (TREE_CODE (*to_p
) != SSA_NAME
5297 && (!is_gimple_variable (*to_p
)
5298 || needs_to_live_in_memory (*to_p
)))
5299 /* Don't use the original target if it's already addressable;
5300 if its address escapes, and the called function uses the
5301 NRV optimization, a conforming program could see *to_p
5302 change before the called function returns; see c++/19317.
5303 When optimizing, the return_slot pass marks more functions
5304 as safe after we have escape info. */
5311 CALL_EXPR_RETURN_SLOT_OPT (*from_p
) = 1;
5312 mark_addressable (*to_p
);
5317 case WITH_SIZE_EXPR
:
5318 /* Likewise for calls that return an aggregate of non-constant size,
5319 since we would not be able to generate a temporary at all. */
5320 if (TREE_CODE (TREE_OPERAND (*from_p
, 0)) == CALL_EXPR
)
5322 *from_p
= TREE_OPERAND (*from_p
, 0);
5323 /* We don't change ret in this case because the
5324 WITH_SIZE_EXPR might have been added in
5325 gimplify_modify_expr, so returning GS_OK would lead to an
5331 /* If we're initializing from a container, push the initialization
5333 case CLEANUP_POINT_EXPR
:
5335 case STATEMENT_LIST
:
5337 tree wrap
= *from_p
;
5340 ret
= gimplify_expr (to_p
, pre_p
, post_p
, is_gimple_min_lval
,
5342 if (ret
!= GS_ERROR
)
5345 t
= voidify_wrapper_expr (wrap
, *expr_p
);
5346 gcc_assert (t
== *expr_p
);
5350 gimplify_and_add (wrap
, pre_p
);
5351 *expr_p
= unshare_expr (*to_p
);
5358 case COMPOUND_LITERAL_EXPR
:
5360 tree complit
= TREE_OPERAND (*expr_p
, 1);
5361 tree decl_s
= COMPOUND_LITERAL_EXPR_DECL_EXPR (complit
);
5362 tree decl
= DECL_EXPR_DECL (decl_s
);
5363 tree init
= DECL_INITIAL (decl
);
5365 /* struct T x = (struct T) { 0, 1, 2 } can be optimized
5366 into struct T x = { 0, 1, 2 } if the address of the
5367 compound literal has never been taken. */
5368 if (!TREE_ADDRESSABLE (complit
)
5369 && !TREE_ADDRESSABLE (decl
)
5372 *expr_p
= copy_node (*expr_p
);
5373 TREE_OPERAND (*expr_p
, 1) = init
;
5388 /* Return true if T looks like a valid GIMPLE statement. */
5391 is_gimple_stmt (tree t
)
5393 const enum tree_code code
= TREE_CODE (t
);
5398 /* The only valid NOP_EXPR is the empty statement. */
5399 return IS_EMPTY_STMT (t
);
5403 /* These are only valid if they're void. */
5404 return TREE_TYPE (t
) == NULL
|| VOID_TYPE_P (TREE_TYPE (t
));
5410 case CASE_LABEL_EXPR
:
5411 case TRY_CATCH_EXPR
:
5412 case TRY_FINALLY_EXPR
:
5413 case EH_FILTER_EXPR
:
5416 case STATEMENT_LIST
:
5420 case OACC_HOST_DATA
:
5423 case OACC_ENTER_DATA
:
5424 case OACC_EXIT_DATA
:
5429 case OMP_DISTRIBUTE
:
5440 case OMP_TARGET_DATA
:
5441 case OMP_TARGET_UPDATE
:
5442 case OMP_TARGET_ENTER_DATA
:
5443 case OMP_TARGET_EXIT_DATA
:
5446 /* These are always void. */
5452 /* These are valid regardless of their type. */
5461 /* Promote partial stores to COMPLEX variables to total stores. *EXPR_P is
5462 a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a variable with
5463 DECL_GIMPLE_REG_P set.
5465 IMPORTANT NOTE: This promotion is performed by introducing a load of the
5466 other, unmodified part of the complex object just before the total store.
5467 As a consequence, if the object is still uninitialized, an undefined value
5468 will be loaded into a register, which may result in a spurious exception
5469 if the register is floating-point and the value happens to be a signaling
5470 NaN for example. Then the fully-fledged complex operations lowering pass
5471 followed by a DCE pass are necessary in order to fix things up. */
5473 static enum gimplify_status
5474 gimplify_modify_expr_complex_part (tree
*expr_p
, gimple_seq
*pre_p
,
5477 enum tree_code code
, ocode
;
5478 tree lhs
, rhs
, new_rhs
, other
, realpart
, imagpart
;
5480 lhs
= TREE_OPERAND (*expr_p
, 0);
5481 rhs
= TREE_OPERAND (*expr_p
, 1);
5482 code
= TREE_CODE (lhs
);
5483 lhs
= TREE_OPERAND (lhs
, 0);
5485 ocode
= code
== REALPART_EXPR
? IMAGPART_EXPR
: REALPART_EXPR
;
5486 other
= build1 (ocode
, TREE_TYPE (rhs
), lhs
);
5487 TREE_NO_WARNING (other
) = 1;
5488 other
= get_formal_tmp_var (other
, pre_p
);
5490 realpart
= code
== REALPART_EXPR
? rhs
: other
;
5491 imagpart
= code
== REALPART_EXPR
? other
: rhs
;
5493 if (TREE_CONSTANT (realpart
) && TREE_CONSTANT (imagpart
))
5494 new_rhs
= build_complex (TREE_TYPE (lhs
), realpart
, imagpart
);
5496 new_rhs
= build2 (COMPLEX_EXPR
, TREE_TYPE (lhs
), realpart
, imagpart
);
5498 gimplify_seq_add_stmt (pre_p
, gimple_build_assign (lhs
, new_rhs
));
5499 *expr_p
= (want_value
) ? rhs
: NULL_TREE
;
5504 /* Gimplify the MODIFY_EXPR node pointed to by EXPR_P.
5510 PRE_P points to the list where side effects that must happen before
5511 *EXPR_P should be stored.
5513 POST_P points to the list where side effects that must happen after
5514 *EXPR_P should be stored.
5516 WANT_VALUE is nonzero iff we want to use the value of this expression
5517 in another expression. */
5519 static enum gimplify_status
5520 gimplify_modify_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
5523 tree
*from_p
= &TREE_OPERAND (*expr_p
, 1);
5524 tree
*to_p
= &TREE_OPERAND (*expr_p
, 0);
5525 enum gimplify_status ret
= GS_UNHANDLED
;
5527 location_t loc
= EXPR_LOCATION (*expr_p
);
5528 gimple_stmt_iterator gsi
;
5530 gcc_assert (TREE_CODE (*expr_p
) == MODIFY_EXPR
5531 || TREE_CODE (*expr_p
) == INIT_EXPR
);
5533 /* Trying to simplify a clobber using normal logic doesn't work,
5534 so handle it here. */
5535 if (TREE_CLOBBER_P (*from_p
))
5537 ret
= gimplify_expr (to_p
, pre_p
, post_p
, is_gimple_lvalue
, fb_lvalue
);
5538 if (ret
== GS_ERROR
)
5540 gcc_assert (!want_value
);
5541 if (!VAR_P (*to_p
) && TREE_CODE (*to_p
) != MEM_REF
)
5543 tree addr
= get_initialized_tmp_var (build_fold_addr_expr (*to_p
),
5545 *to_p
= build_simple_mem_ref_loc (EXPR_LOCATION (*to_p
), addr
);
5547 gimplify_seq_add_stmt (pre_p
, gimple_build_assign (*to_p
, *from_p
));
5552 /* Insert pointer conversions required by the middle-end that are not
5553 required by the frontend. This fixes middle-end type checking for
5554 for example gcc.dg/redecl-6.c. */
5555 if (POINTER_TYPE_P (TREE_TYPE (*to_p
)))
5557 STRIP_USELESS_TYPE_CONVERSION (*from_p
);
5558 if (!useless_type_conversion_p (TREE_TYPE (*to_p
), TREE_TYPE (*from_p
)))
5559 *from_p
= fold_convert_loc (loc
, TREE_TYPE (*to_p
), *from_p
);
5562 /* See if any simplifications can be done based on what the RHS is. */
5563 ret
= gimplify_modify_expr_rhs (expr_p
, from_p
, to_p
, pre_p
, post_p
,
5565 if (ret
!= GS_UNHANDLED
)
5568 /* For zero sized types only gimplify the left hand side and right hand
5569 side as statements and throw away the assignment. Do this after
5570 gimplify_modify_expr_rhs so we handle TARGET_EXPRs of addressable
5572 if (zero_sized_type (TREE_TYPE (*from_p
))
5574 /* Don't do this for calls that return addressable types, expand_call
5575 relies on those having a lhs. */
5576 && !(TREE_ADDRESSABLE (TREE_TYPE (*from_p
))
5577 && TREE_CODE (*from_p
) == CALL_EXPR
))
5579 gimplify_stmt (from_p
, pre_p
);
5580 gimplify_stmt (to_p
, pre_p
);
5581 *expr_p
= NULL_TREE
;
5585 /* If the value being copied is of variable width, compute the length
5586 of the copy into a WITH_SIZE_EXPR. Note that we need to do this
5587 before gimplifying any of the operands so that we can resolve any
5588 PLACEHOLDER_EXPRs in the size. Also note that the RTL expander uses
5589 the size of the expression to be copied, not of the destination, so
5590 that is what we must do here. */
5591 maybe_with_size_expr (from_p
);
5593 /* As a special case, we have to temporarily allow for assignments
5594 with a CALL_EXPR on the RHS. Since in GIMPLE a function call is
5595 a toplevel statement, when gimplifying the GENERIC expression
5596 MODIFY_EXPR <a, CALL_EXPR <foo>>, we cannot create the tuple
5597 GIMPLE_ASSIGN <a, GIMPLE_CALL <foo>>.
5599 Instead, we need to create the tuple GIMPLE_CALL <a, foo>. To
5600 prevent gimplify_expr from trying to create a new temporary for
5601 foo's LHS, we tell it that it should only gimplify until it
5602 reaches the CALL_EXPR. On return from gimplify_expr, the newly
5603 created GIMPLE_CALL <foo> will be the last statement in *PRE_P
5604 and all we need to do here is set 'a' to be its LHS. */
5606 /* Gimplify the RHS first for C++17 and bug 71104. */
5607 gimple_predicate initial_pred
= initial_rhs_predicate_for (*to_p
);
5608 ret
= gimplify_expr (from_p
, pre_p
, post_p
, initial_pred
, fb_rvalue
);
5609 if (ret
== GS_ERROR
)
5612 /* Then gimplify the LHS. */
5613 /* If we gimplified the RHS to a CALL_EXPR and that call may return
5614 twice we have to make sure to gimplify into non-SSA as otherwise
5615 the abnormal edge added later will make those defs not dominate
5617 ??? Technically this applies only to the registers used in the
5618 resulting non-register *TO_P. */
5619 bool saved_into_ssa
= gimplify_ctxp
->into_ssa
;
5621 && TREE_CODE (*from_p
) == CALL_EXPR
5622 && call_expr_flags (*from_p
) & ECF_RETURNS_TWICE
)
5623 gimplify_ctxp
->into_ssa
= false;
5624 ret
= gimplify_expr (to_p
, pre_p
, post_p
, is_gimple_lvalue
, fb_lvalue
);
5625 gimplify_ctxp
->into_ssa
= saved_into_ssa
;
5626 if (ret
== GS_ERROR
)
5629 /* Now that the LHS is gimplified, re-gimplify the RHS if our initial
5630 guess for the predicate was wrong. */
5631 gimple_predicate final_pred
= rhs_predicate_for (*to_p
);
5632 if (final_pred
!= initial_pred
)
5634 ret
= gimplify_expr (from_p
, pre_p
, post_p
, final_pred
, fb_rvalue
);
5635 if (ret
== GS_ERROR
)
5639 /* In case of va_arg internal fn wrappped in a WITH_SIZE_EXPR, add the type
5640 size as argument to the call. */
5641 if (TREE_CODE (*from_p
) == WITH_SIZE_EXPR
)
5643 tree call
= TREE_OPERAND (*from_p
, 0);
5644 tree vlasize
= TREE_OPERAND (*from_p
, 1);
5646 if (TREE_CODE (call
) == CALL_EXPR
5647 && CALL_EXPR_IFN (call
) == IFN_VA_ARG
)
5649 int nargs
= call_expr_nargs (call
);
5650 tree type
= TREE_TYPE (call
);
5651 tree ap
= CALL_EXPR_ARG (call
, 0);
5652 tree tag
= CALL_EXPR_ARG (call
, 1);
5653 tree aptag
= CALL_EXPR_ARG (call
, 2);
5654 tree newcall
= build_call_expr_internal_loc (EXPR_LOCATION (call
),
5658 TREE_OPERAND (*from_p
, 0) = newcall
;
5662 /* Now see if the above changed *from_p to something we handle specially. */
5663 ret
= gimplify_modify_expr_rhs (expr_p
, from_p
, to_p
, pre_p
, post_p
,
5665 if (ret
!= GS_UNHANDLED
)
5668 /* If we've got a variable sized assignment between two lvalues (i.e. does
5669 not involve a call), then we can make things a bit more straightforward
5670 by converting the assignment to memcpy or memset. */
5671 if (TREE_CODE (*from_p
) == WITH_SIZE_EXPR
)
5673 tree from
= TREE_OPERAND (*from_p
, 0);
5674 tree size
= TREE_OPERAND (*from_p
, 1);
5676 if (TREE_CODE (from
) == CONSTRUCTOR
)
5677 return gimplify_modify_expr_to_memset (expr_p
, size
, want_value
, pre_p
);
5679 if (is_gimple_addressable (from
))
5682 return gimplify_modify_expr_to_memcpy (expr_p
, size
, want_value
,
5687 /* Transform partial stores to non-addressable complex variables into
5688 total stores. This allows us to use real instead of virtual operands
5689 for these variables, which improves optimization. */
5690 if ((TREE_CODE (*to_p
) == REALPART_EXPR
5691 || TREE_CODE (*to_p
) == IMAGPART_EXPR
)
5692 && is_gimple_reg (TREE_OPERAND (*to_p
, 0)))
5693 return gimplify_modify_expr_complex_part (expr_p
, pre_p
, want_value
);
5695 /* Try to alleviate the effects of the gimplification creating artificial
5696 temporaries (see for example is_gimple_reg_rhs) on the debug info, but
5697 make sure not to create DECL_DEBUG_EXPR links across functions. */
5698 if (!gimplify_ctxp
->into_ssa
5700 && DECL_IGNORED_P (*from_p
)
5702 && !DECL_IGNORED_P (*to_p
)
5703 && decl_function_context (*to_p
) == current_function_decl
5704 && decl_function_context (*from_p
) == current_function_decl
)
5706 if (!DECL_NAME (*from_p
) && DECL_NAME (*to_p
))
5708 = create_tmp_var_name (IDENTIFIER_POINTER (DECL_NAME (*to_p
)));
5709 DECL_HAS_DEBUG_EXPR_P (*from_p
) = 1;
5710 SET_DECL_DEBUG_EXPR (*from_p
, *to_p
);
5713 if (want_value
&& TREE_THIS_VOLATILE (*to_p
))
5714 *from_p
= get_initialized_tmp_var (*from_p
, pre_p
, post_p
);
5716 if (TREE_CODE (*from_p
) == CALL_EXPR
)
5718 /* Since the RHS is a CALL_EXPR, we need to create a GIMPLE_CALL
5719 instead of a GIMPLE_ASSIGN. */
5721 if (CALL_EXPR_FN (*from_p
) == NULL_TREE
)
5723 /* Gimplify internal functions created in the FEs. */
5724 int nargs
= call_expr_nargs (*from_p
), i
;
5725 enum internal_fn ifn
= CALL_EXPR_IFN (*from_p
);
5726 auto_vec
<tree
> vargs (nargs
);
5728 for (i
= 0; i
< nargs
; i
++)
5730 gimplify_arg (&CALL_EXPR_ARG (*from_p
, i
), pre_p
,
5731 EXPR_LOCATION (*from_p
));
5732 vargs
.quick_push (CALL_EXPR_ARG (*from_p
, i
));
5734 call_stmt
= gimple_build_call_internal_vec (ifn
, vargs
);
5735 gimple_call_set_nothrow (call_stmt
, TREE_NOTHROW (*from_p
));
5736 gimple_set_location (call_stmt
, EXPR_LOCATION (*expr_p
));
5740 tree fnptrtype
= TREE_TYPE (CALL_EXPR_FN (*from_p
));
5741 CALL_EXPR_FN (*from_p
) = TREE_OPERAND (CALL_EXPR_FN (*from_p
), 0);
5742 STRIP_USELESS_TYPE_CONVERSION (CALL_EXPR_FN (*from_p
));
5743 tree fndecl
= get_callee_fndecl (*from_p
);
5745 && fndecl_built_in_p (fndecl
, BUILT_IN_EXPECT
)
5746 && call_expr_nargs (*from_p
) == 3)
5747 call_stmt
= gimple_build_call_internal (IFN_BUILTIN_EXPECT
, 3,
5748 CALL_EXPR_ARG (*from_p
, 0),
5749 CALL_EXPR_ARG (*from_p
, 1),
5750 CALL_EXPR_ARG (*from_p
, 2));
5753 call_stmt
= gimple_build_call_from_tree (*from_p
, fnptrtype
);
5756 notice_special_calls (call_stmt
);
5757 if (!gimple_call_noreturn_p (call_stmt
) || !should_remove_lhs_p (*to_p
))
5758 gimple_call_set_lhs (call_stmt
, *to_p
);
5759 else if (TREE_CODE (*to_p
) == SSA_NAME
)
5760 /* The above is somewhat premature, avoid ICEing later for a
5761 SSA name w/o a definition. We may have uses in the GIMPLE IL.
5762 ??? This doesn't make it a default-def. */
5763 SSA_NAME_DEF_STMT (*to_p
) = gimple_build_nop ();
5769 assign
= gimple_build_assign (*to_p
, *from_p
);
5770 gimple_set_location (assign
, EXPR_LOCATION (*expr_p
));
5771 if (COMPARISON_CLASS_P (*from_p
))
5772 gimple_set_no_warning (assign
, TREE_NO_WARNING (*from_p
));
5775 if (gimplify_ctxp
->into_ssa
&& is_gimple_reg (*to_p
))
5777 /* We should have got an SSA name from the start. */
5778 gcc_assert (TREE_CODE (*to_p
) == SSA_NAME
5779 || ! gimple_in_ssa_p (cfun
));
5782 gimplify_seq_add_stmt (pre_p
, assign
);
5783 gsi
= gsi_last (*pre_p
);
5784 maybe_fold_stmt (&gsi
);
5788 *expr_p
= TREE_THIS_VOLATILE (*to_p
) ? *from_p
: unshare_expr (*to_p
);
5797 /* Gimplify a comparison between two variable-sized objects. Do this
5798 with a call to BUILT_IN_MEMCMP. */
5800 static enum gimplify_status
5801 gimplify_variable_sized_compare (tree
*expr_p
)
5803 location_t loc
= EXPR_LOCATION (*expr_p
);
5804 tree op0
= TREE_OPERAND (*expr_p
, 0);
5805 tree op1
= TREE_OPERAND (*expr_p
, 1);
5806 tree t
, arg
, dest
, src
, expr
;
5808 arg
= TYPE_SIZE_UNIT (TREE_TYPE (op0
));
5809 arg
= unshare_expr (arg
);
5810 arg
= SUBSTITUTE_PLACEHOLDER_IN_EXPR (arg
, op0
);
5811 src
= build_fold_addr_expr_loc (loc
, op1
);
5812 dest
= build_fold_addr_expr_loc (loc
, op0
);
5813 t
= builtin_decl_implicit (BUILT_IN_MEMCMP
);
5814 t
= build_call_expr_loc (loc
, t
, 3, dest
, src
, arg
);
5817 = build2 (TREE_CODE (*expr_p
), TREE_TYPE (*expr_p
), t
, integer_zero_node
);
5818 SET_EXPR_LOCATION (expr
, loc
);
5824 /* Gimplify a comparison between two aggregate objects of integral scalar
5825 mode as a comparison between the bitwise equivalent scalar values. */
5827 static enum gimplify_status
5828 gimplify_scalar_mode_aggregate_compare (tree
*expr_p
)
5830 location_t loc
= EXPR_LOCATION (*expr_p
);
5831 tree op0
= TREE_OPERAND (*expr_p
, 0);
5832 tree op1
= TREE_OPERAND (*expr_p
, 1);
5834 tree type
= TREE_TYPE (op0
);
5835 tree scalar_type
= lang_hooks
.types
.type_for_mode (TYPE_MODE (type
), 1);
5837 op0
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, scalar_type
, op0
);
5838 op1
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, scalar_type
, op1
);
5841 = fold_build2_loc (loc
, TREE_CODE (*expr_p
), TREE_TYPE (*expr_p
), op0
, op1
);
5846 /* Gimplify an expression sequence. This function gimplifies each
5847 expression and rewrites the original expression with the last
5848 expression of the sequence in GIMPLE form.
5850 PRE_P points to the list where the side effects for all the
5851 expressions in the sequence will be emitted.
5853 WANT_VALUE is true when the result of the last COMPOUND_EXPR is used. */
5855 static enum gimplify_status
5856 gimplify_compound_expr (tree
*expr_p
, gimple_seq
*pre_p
, bool want_value
)
5862 tree
*sub_p
= &TREE_OPERAND (t
, 0);
5864 if (TREE_CODE (*sub_p
) == COMPOUND_EXPR
)
5865 gimplify_compound_expr (sub_p
, pre_p
, false);
5867 gimplify_stmt (sub_p
, pre_p
);
5869 t
= TREE_OPERAND (t
, 1);
5871 while (TREE_CODE (t
) == COMPOUND_EXPR
);
5878 gimplify_stmt (expr_p
, pre_p
);
5883 /* Gimplify a SAVE_EXPR node. EXPR_P points to the expression to
5884 gimplify. After gimplification, EXPR_P will point to a new temporary
5885 that holds the original value of the SAVE_EXPR node.
5887 PRE_P points to the list where side effects that must happen before
5888 *EXPR_P should be stored. */
5890 static enum gimplify_status
5891 gimplify_save_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
)
5893 enum gimplify_status ret
= GS_ALL_DONE
;
5896 gcc_assert (TREE_CODE (*expr_p
) == SAVE_EXPR
);
5897 val
= TREE_OPERAND (*expr_p
, 0);
5899 /* If the SAVE_EXPR has not been resolved, then evaluate it once. */
5900 if (!SAVE_EXPR_RESOLVED_P (*expr_p
))
5902 /* The operand may be a void-valued expression. It is
5903 being executed only for its side-effects. */
5904 if (TREE_TYPE (val
) == void_type_node
)
5906 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
5907 is_gimple_stmt
, fb_none
);
5911 /* The temporary may not be an SSA name as later abnormal and EH
5912 control flow may invalidate use/def domination. When in SSA
5913 form then assume there are no such issues and SAVE_EXPRs only
5914 appear via GENERIC foldings. */
5915 val
= get_initialized_tmp_var (val
, pre_p
, post_p
,
5916 gimple_in_ssa_p (cfun
));
5918 TREE_OPERAND (*expr_p
, 0) = val
;
5919 SAVE_EXPR_RESOLVED_P (*expr_p
) = 1;
5927 /* Rewrite the ADDR_EXPR node pointed to by EXPR_P
5934 PRE_P points to the list where side effects that must happen before
5935 *EXPR_P should be stored.
5937 POST_P points to the list where side effects that must happen after
5938 *EXPR_P should be stored. */
5940 static enum gimplify_status
5941 gimplify_addr_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
)
5943 tree expr
= *expr_p
;
5944 tree op0
= TREE_OPERAND (expr
, 0);
5945 enum gimplify_status ret
;
5946 location_t loc
= EXPR_LOCATION (*expr_p
);
5948 switch (TREE_CODE (op0
))
5952 /* Check if we are dealing with an expression of the form '&*ptr'.
5953 While the front end folds away '&*ptr' into 'ptr', these
5954 expressions may be generated internally by the compiler (e.g.,
5955 builtins like __builtin_va_end). */
5956 /* Caution: the silent array decomposition semantics we allow for
5957 ADDR_EXPR means we can't always discard the pair. */
5958 /* Gimplification of the ADDR_EXPR operand may drop
5959 cv-qualification conversions, so make sure we add them if
5962 tree op00
= TREE_OPERAND (op0
, 0);
5963 tree t_expr
= TREE_TYPE (expr
);
5964 tree t_op00
= TREE_TYPE (op00
);
5966 if (!useless_type_conversion_p (t_expr
, t_op00
))
5967 op00
= fold_convert_loc (loc
, TREE_TYPE (expr
), op00
);
5973 case VIEW_CONVERT_EXPR
:
5974 /* Take the address of our operand and then convert it to the type of
5977 ??? The interactions of VIEW_CONVERT_EXPR and aliasing is not at
5978 all clear. The impact of this transformation is even less clear. */
5980 /* If the operand is a useless conversion, look through it. Doing so
5981 guarantees that the ADDR_EXPR and its operand will remain of the
5983 if (tree_ssa_useless_type_conversion (TREE_OPERAND (op0
, 0)))
5984 op0
= TREE_OPERAND (op0
, 0);
5986 *expr_p
= fold_convert_loc (loc
, TREE_TYPE (expr
),
5987 build_fold_addr_expr_loc (loc
,
5988 TREE_OPERAND (op0
, 0)));
5993 if (integer_zerop (TREE_OPERAND (op0
, 1)))
5994 goto do_indirect_ref
;
5999 /* If we see a call to a declared builtin or see its address
6000 being taken (we can unify those cases here) then we can mark
6001 the builtin for implicit generation by GCC. */
6002 if (TREE_CODE (op0
) == FUNCTION_DECL
6003 && fndecl_built_in_p (op0
, BUILT_IN_NORMAL
)
6004 && builtin_decl_declared_p (DECL_FUNCTION_CODE (op0
)))
6005 set_builtin_decl_implicit_p (DECL_FUNCTION_CODE (op0
), true);
6007 /* We use fb_either here because the C frontend sometimes takes
6008 the address of a call that returns a struct; see
6009 gcc.dg/c99-array-lval-1.c. The gimplifier will correctly make
6010 the implied temporary explicit. */
6012 /* Make the operand addressable. */
6013 ret
= gimplify_expr (&TREE_OPERAND (expr
, 0), pre_p
, post_p
,
6014 is_gimple_addressable
, fb_either
);
6015 if (ret
== GS_ERROR
)
6018 /* Then mark it. Beware that it may not be possible to do so directly
6019 if a temporary has been created by the gimplification. */
6020 prepare_gimple_addressable (&TREE_OPERAND (expr
, 0), pre_p
);
6022 op0
= TREE_OPERAND (expr
, 0);
6024 /* For various reasons, the gimplification of the expression
6025 may have made a new INDIRECT_REF. */
6026 if (TREE_CODE (op0
) == INDIRECT_REF
)
6027 goto do_indirect_ref
;
6029 mark_addressable (TREE_OPERAND (expr
, 0));
6031 /* The FEs may end up building ADDR_EXPRs early on a decl with
6032 an incomplete type. Re-build ADDR_EXPRs in canonical form
6034 if (!types_compatible_p (TREE_TYPE (op0
), TREE_TYPE (TREE_TYPE (expr
))))
6035 *expr_p
= build_fold_addr_expr (op0
);
6037 /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly. */
6038 recompute_tree_invariant_for_addr_expr (*expr_p
);
6040 /* If we re-built the ADDR_EXPR add a conversion to the original type
6042 if (!useless_type_conversion_p (TREE_TYPE (expr
), TREE_TYPE (*expr_p
)))
6043 *expr_p
= fold_convert (TREE_TYPE (expr
), *expr_p
);
6051 /* Gimplify the operands of an ASM_EXPR. Input operands should be a gimple
6052 value; output operands should be a gimple lvalue. */
6054 static enum gimplify_status
6055 gimplify_asm_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
)
6059 const char **oconstraints
;
6062 const char *constraint
;
6063 bool allows_mem
, allows_reg
, is_inout
;
6064 enum gimplify_status ret
, tret
;
6066 vec
<tree
, va_gc
> *inputs
;
6067 vec
<tree
, va_gc
> *outputs
;
6068 vec
<tree
, va_gc
> *clobbers
;
6069 vec
<tree
, va_gc
> *labels
;
6073 noutputs
= list_length (ASM_OUTPUTS (expr
));
6074 oconstraints
= (const char **) alloca ((noutputs
) * sizeof (const char *));
6082 link_next
= NULL_TREE
;
6083 for (i
= 0, link
= ASM_OUTPUTS (expr
); link
; ++i
, link
= link_next
)
6086 size_t constraint_len
;
6088 link_next
= TREE_CHAIN (link
);
6092 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link
)));
6093 constraint_len
= strlen (constraint
);
6094 if (constraint_len
== 0)
6097 ok
= parse_output_constraint (&constraint
, i
, 0, 0,
6098 &allows_mem
, &allows_reg
, &is_inout
);
6105 if (!allows_reg
&& allows_mem
)
6106 mark_addressable (TREE_VALUE (link
));
6108 tret
= gimplify_expr (&TREE_VALUE (link
), pre_p
, post_p
,
6109 is_inout
? is_gimple_min_lval
: is_gimple_lvalue
,
6110 fb_lvalue
| fb_mayfail
);
6111 if (tret
== GS_ERROR
)
6113 error ("invalid lvalue in asm output %d", i
);
6117 /* If the constraint does not allow memory make sure we gimplify
6118 it to a register if it is not already but its base is. This
6119 happens for complex and vector components. */
6122 tree op
= TREE_VALUE (link
);
6123 if (! is_gimple_val (op
)
6124 && is_gimple_reg_type (TREE_TYPE (op
))
6125 && is_gimple_reg (get_base_address (op
)))
6127 tree tem
= create_tmp_reg (TREE_TYPE (op
));
6131 ass
= build2 (MODIFY_EXPR
, TREE_TYPE (tem
),
6132 tem
, unshare_expr (op
));
6133 gimplify_and_add (ass
, pre_p
);
6135 ass
= build2 (MODIFY_EXPR
, TREE_TYPE (tem
), op
, tem
);
6136 gimplify_and_add (ass
, post_p
);
6138 TREE_VALUE (link
) = tem
;
6143 vec_safe_push (outputs
, link
);
6144 TREE_CHAIN (link
) = NULL_TREE
;
6148 /* An input/output operand. To give the optimizers more
6149 flexibility, split it into separate input and output
6152 /* Buffer big enough to format a 32-bit UINT_MAX into. */
6155 /* Turn the in/out constraint into an output constraint. */
6156 char *p
= xstrdup (constraint
);
6158 TREE_VALUE (TREE_PURPOSE (link
)) = build_string (constraint_len
, p
);
6160 /* And add a matching input constraint. */
6163 sprintf (buf
, "%u", i
);
6165 /* If there are multiple alternatives in the constraint,
6166 handle each of them individually. Those that allow register
6167 will be replaced with operand number, the others will stay
6169 if (strchr (p
, ',') != NULL
)
6171 size_t len
= 0, buflen
= strlen (buf
);
6172 char *beg
, *end
, *str
, *dst
;
6176 end
= strchr (beg
, ',');
6178 end
= strchr (beg
, '\0');
6179 if ((size_t) (end
- beg
) < buflen
)
6182 len
+= end
- beg
+ 1;
6189 str
= (char *) alloca (len
);
6190 for (beg
= p
+ 1, dst
= str
;;)
6193 bool mem_p
, reg_p
, inout_p
;
6195 end
= strchr (beg
, ',');
6200 parse_output_constraint (&tem
, i
, 0, 0,
6201 &mem_p
, ®_p
, &inout_p
);
6206 memcpy (dst
, buf
, buflen
);
6215 memcpy (dst
, beg
, len
);
6224 input
= build_string (dst
- str
, str
);
6227 input
= build_string (strlen (buf
), buf
);
6230 input
= build_string (constraint_len
- 1, constraint
+ 1);
6234 input
= build_tree_list (build_tree_list (NULL_TREE
, input
),
6235 unshare_expr (TREE_VALUE (link
)));
6236 ASM_INPUTS (expr
) = chainon (ASM_INPUTS (expr
), input
);
6240 link_next
= NULL_TREE
;
6241 for (link
= ASM_INPUTS (expr
); link
; ++i
, link
= link_next
)
6243 link_next
= TREE_CHAIN (link
);
6244 constraint
= TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link
)));
6245 parse_input_constraint (&constraint
, 0, 0, noutputs
, 0,
6246 oconstraints
, &allows_mem
, &allows_reg
);
6248 /* If we can't make copies, we can only accept memory. */
6249 if (TREE_ADDRESSABLE (TREE_TYPE (TREE_VALUE (link
))))
6255 error ("impossible constraint in %<asm%>");
6256 error ("non-memory input %d must stay in memory", i
);
6261 /* If the operand is a memory input, it should be an lvalue. */
6262 if (!allows_reg
&& allows_mem
)
6264 tree inputv
= TREE_VALUE (link
);
6265 STRIP_NOPS (inputv
);
6266 if (TREE_CODE (inputv
) == PREDECREMENT_EXPR
6267 || TREE_CODE (inputv
) == PREINCREMENT_EXPR
6268 || TREE_CODE (inputv
) == POSTDECREMENT_EXPR
6269 || TREE_CODE (inputv
) == POSTINCREMENT_EXPR
6270 || TREE_CODE (inputv
) == MODIFY_EXPR
)
6271 TREE_VALUE (link
) = error_mark_node
;
6272 tret
= gimplify_expr (&TREE_VALUE (link
), pre_p
, post_p
,
6273 is_gimple_lvalue
, fb_lvalue
| fb_mayfail
);
6274 if (tret
!= GS_ERROR
)
6276 /* Unlike output operands, memory inputs are not guaranteed
6277 to be lvalues by the FE, and while the expressions are
6278 marked addressable there, if it is e.g. a statement
6279 expression, temporaries in it might not end up being
6280 addressable. They might be already used in the IL and thus
6281 it is too late to make them addressable now though. */
6282 tree x
= TREE_VALUE (link
);
6283 while (handled_component_p (x
))
6284 x
= TREE_OPERAND (x
, 0);
6285 if (TREE_CODE (x
) == MEM_REF
6286 && TREE_CODE (TREE_OPERAND (x
, 0)) == ADDR_EXPR
)
6287 x
= TREE_OPERAND (TREE_OPERAND (x
, 0), 0);
6289 || TREE_CODE (x
) == PARM_DECL
6290 || TREE_CODE (x
) == RESULT_DECL
)
6291 && !TREE_ADDRESSABLE (x
)
6292 && is_gimple_reg (x
))
6294 warning_at (EXPR_LOC_OR_LOC (TREE_VALUE (link
),
6296 "memory input %d is not directly addressable",
6298 prepare_gimple_addressable (&TREE_VALUE (link
), pre_p
);
6301 mark_addressable (TREE_VALUE (link
));
6302 if (tret
== GS_ERROR
)
6304 error_at (EXPR_LOC_OR_LOC (TREE_VALUE (link
), input_location
),
6305 "memory input %d is not directly addressable", i
);
6311 tret
= gimplify_expr (&TREE_VALUE (link
), pre_p
, post_p
,
6312 is_gimple_asm_val
, fb_rvalue
);
6313 if (tret
== GS_ERROR
)
6317 TREE_CHAIN (link
) = NULL_TREE
;
6318 vec_safe_push (inputs
, link
);
6321 link_next
= NULL_TREE
;
6322 for (link
= ASM_CLOBBERS (expr
); link
; ++i
, link
= link_next
)
6324 link_next
= TREE_CHAIN (link
);
6325 TREE_CHAIN (link
) = NULL_TREE
;
6326 vec_safe_push (clobbers
, link
);
6329 link_next
= NULL_TREE
;
6330 for (link
= ASM_LABELS (expr
); link
; ++i
, link
= link_next
)
6332 link_next
= TREE_CHAIN (link
);
6333 TREE_CHAIN (link
) = NULL_TREE
;
6334 vec_safe_push (labels
, link
);
6337 /* Do not add ASMs with errors to the gimple IL stream. */
6338 if (ret
!= GS_ERROR
)
6340 stmt
= gimple_build_asm_vec (TREE_STRING_POINTER (ASM_STRING (expr
)),
6341 inputs
, outputs
, clobbers
, labels
);
6343 gimple_asm_set_volatile (stmt
, ASM_VOLATILE_P (expr
) || noutputs
== 0);
6344 gimple_asm_set_input (stmt
, ASM_INPUT_P (expr
));
6346 gimplify_seq_add_stmt (pre_p
, stmt
);
6352 /* Gimplify a CLEANUP_POINT_EXPR. Currently this works by adding
6353 GIMPLE_WITH_CLEANUP_EXPRs to the prequeue as we encounter cleanups while
6354 gimplifying the body, and converting them to TRY_FINALLY_EXPRs when we
6355 return to this function.
6357 FIXME should we complexify the prequeue handling instead? Or use flags
6358 for all the cleanups and let the optimizer tighten them up? The current
6359 code seems pretty fragile; it will break on a cleanup within any
6360 non-conditional nesting. But any such nesting would be broken, anyway;
6361 we can't write a TRY_FINALLY_EXPR that starts inside a nesting construct
6362 and continues out of it. We can do that at the RTL level, though, so
6363 having an optimizer to tighten up try/finally regions would be a Good
6366 static enum gimplify_status
6367 gimplify_cleanup_point_expr (tree
*expr_p
, gimple_seq
*pre_p
)
6369 gimple_stmt_iterator iter
;
6370 gimple_seq body_sequence
= NULL
;
6372 tree temp
= voidify_wrapper_expr (*expr_p
, NULL
);
6374 /* We only care about the number of conditions between the innermost
6375 CLEANUP_POINT_EXPR and the cleanup. So save and reset the count and
6376 any cleanups collected outside the CLEANUP_POINT_EXPR. */
6377 int old_conds
= gimplify_ctxp
->conditions
;
6378 gimple_seq old_cleanups
= gimplify_ctxp
->conditional_cleanups
;
6379 bool old_in_cleanup_point_expr
= gimplify_ctxp
->in_cleanup_point_expr
;
6380 gimplify_ctxp
->conditions
= 0;
6381 gimplify_ctxp
->conditional_cleanups
= NULL
;
6382 gimplify_ctxp
->in_cleanup_point_expr
= true;
6384 gimplify_stmt (&TREE_OPERAND (*expr_p
, 0), &body_sequence
);
6386 gimplify_ctxp
->conditions
= old_conds
;
6387 gimplify_ctxp
->conditional_cleanups
= old_cleanups
;
6388 gimplify_ctxp
->in_cleanup_point_expr
= old_in_cleanup_point_expr
;
6390 for (iter
= gsi_start (body_sequence
); !gsi_end_p (iter
); )
6392 gimple
*wce
= gsi_stmt (iter
);
6394 if (gimple_code (wce
) == GIMPLE_WITH_CLEANUP_EXPR
)
6396 if (gsi_one_before_end_p (iter
))
6398 /* Note that gsi_insert_seq_before and gsi_remove do not
6399 scan operands, unlike some other sequence mutators. */
6400 if (!gimple_wce_cleanup_eh_only (wce
))
6401 gsi_insert_seq_before_without_update (&iter
,
6402 gimple_wce_cleanup (wce
),
6404 gsi_remove (&iter
, true);
6411 enum gimple_try_flags kind
;
6413 if (gimple_wce_cleanup_eh_only (wce
))
6414 kind
= GIMPLE_TRY_CATCH
;
6416 kind
= GIMPLE_TRY_FINALLY
;
6417 seq
= gsi_split_seq_after (iter
);
6419 gtry
= gimple_build_try (seq
, gimple_wce_cleanup (wce
), kind
);
6420 /* Do not use gsi_replace here, as it may scan operands.
6421 We want to do a simple structural modification only. */
6422 gsi_set_stmt (&iter
, gtry
);
6423 iter
= gsi_start (gtry
->eval
);
6430 gimplify_seq_add_seq (pre_p
, body_sequence
);
6443 /* Insert a cleanup marker for gimplify_cleanup_point_expr. CLEANUP
6444 is the cleanup action required. EH_ONLY is true if the cleanup should
6445 only be executed if an exception is thrown, not on normal exit.
6446 If FORCE_UNCOND is true perform the cleanup unconditionally; this is
6447 only valid for clobbers. */
6450 gimple_push_cleanup (tree var
, tree cleanup
, bool eh_only
, gimple_seq
*pre_p
,
6451 bool force_uncond
= false)
6454 gimple_seq cleanup_stmts
= NULL
;
6456 /* Errors can result in improperly nested cleanups. Which results in
6457 confusion when trying to resolve the GIMPLE_WITH_CLEANUP_EXPR. */
6461 if (gimple_conditional_context ())
6463 /* If we're in a conditional context, this is more complex. We only
6464 want to run the cleanup if we actually ran the initialization that
6465 necessitates it, but we want to run it after the end of the
6466 conditional context. So we wrap the try/finally around the
6467 condition and use a flag to determine whether or not to actually
6468 run the destructor. Thus
6472 becomes (approximately)
6476 if (test) { A::A(temp); flag = 1; val = f(temp); }
6479 if (flag) A::~A(temp);
6485 gimplify_stmt (&cleanup
, &cleanup_stmts
);
6486 wce
= gimple_build_wce (cleanup_stmts
);
6487 gimplify_seq_add_stmt (&gimplify_ctxp
->conditional_cleanups
, wce
);
6491 tree flag
= create_tmp_var (boolean_type_node
, "cleanup");
6492 gassign
*ffalse
= gimple_build_assign (flag
, boolean_false_node
);
6493 gassign
*ftrue
= gimple_build_assign (flag
, boolean_true_node
);
6495 cleanup
= build3 (COND_EXPR
, void_type_node
, flag
, cleanup
, NULL
);
6496 gimplify_stmt (&cleanup
, &cleanup_stmts
);
6497 wce
= gimple_build_wce (cleanup_stmts
);
6499 gimplify_seq_add_stmt (&gimplify_ctxp
->conditional_cleanups
, ffalse
);
6500 gimplify_seq_add_stmt (&gimplify_ctxp
->conditional_cleanups
, wce
);
6501 gimplify_seq_add_stmt (pre_p
, ftrue
);
6503 /* Because of this manipulation, and the EH edges that jump
6504 threading cannot redirect, the temporary (VAR) will appear
6505 to be used uninitialized. Don't warn. */
6506 TREE_NO_WARNING (var
) = 1;
6511 gimplify_stmt (&cleanup
, &cleanup_stmts
);
6512 wce
= gimple_build_wce (cleanup_stmts
);
6513 gimple_wce_set_cleanup_eh_only (wce
, eh_only
);
6514 gimplify_seq_add_stmt (pre_p
, wce
);
6518 /* Gimplify a TARGET_EXPR which doesn't appear on the rhs of an INIT_EXPR. */
6520 static enum gimplify_status
6521 gimplify_target_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
)
6523 tree targ
= *expr_p
;
6524 tree temp
= TARGET_EXPR_SLOT (targ
);
6525 tree init
= TARGET_EXPR_INITIAL (targ
);
6526 enum gimplify_status ret
;
6528 bool unpoison_empty_seq
= false;
6529 gimple_stmt_iterator unpoison_it
;
6533 tree cleanup
= NULL_TREE
;
6535 /* TARGET_EXPR temps aren't part of the enclosing block, so add it
6536 to the temps list. Handle also variable length TARGET_EXPRs. */
6537 if (TREE_CODE (DECL_SIZE (temp
)) != INTEGER_CST
)
6539 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (temp
)))
6540 gimplify_type_sizes (TREE_TYPE (temp
), pre_p
);
6541 gimplify_vla_decl (temp
, pre_p
);
6545 /* Save location where we need to place unpoisoning. It's possible
6546 that a variable will be converted to needs_to_live_in_memory. */
6547 unpoison_it
= gsi_last (*pre_p
);
6548 unpoison_empty_seq
= gsi_end_p (unpoison_it
);
6550 gimple_add_tmp_var (temp
);
6553 /* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the
6554 expression is supposed to initialize the slot. */
6555 if (VOID_TYPE_P (TREE_TYPE (init
)))
6556 ret
= gimplify_expr (&init
, pre_p
, post_p
, is_gimple_stmt
, fb_none
);
6559 tree init_expr
= build2 (INIT_EXPR
, void_type_node
, temp
, init
);
6561 ret
= gimplify_expr (&init
, pre_p
, post_p
, is_gimple_stmt
, fb_none
);
6563 ggc_free (init_expr
);
6565 if (ret
== GS_ERROR
)
6567 /* PR c++/28266 Make sure this is expanded only once. */
6568 TARGET_EXPR_INITIAL (targ
) = NULL_TREE
;
6572 gimplify_and_add (init
, pre_p
);
6574 /* If needed, push the cleanup for the temp. */
6575 if (TARGET_EXPR_CLEANUP (targ
))
6577 if (CLEANUP_EH_ONLY (targ
))
6578 gimple_push_cleanup (temp
, TARGET_EXPR_CLEANUP (targ
),
6579 CLEANUP_EH_ONLY (targ
), pre_p
);
6581 cleanup
= TARGET_EXPR_CLEANUP (targ
);
6584 /* Add a clobber for the temporary going out of scope, like
6585 gimplify_bind_expr. */
6586 if (gimplify_ctxp
->in_cleanup_point_expr
6587 && needs_to_live_in_memory (temp
))
6589 if (flag_stack_reuse
== SR_ALL
)
6591 tree clobber
= build_clobber (TREE_TYPE (temp
));
6592 clobber
= build2 (MODIFY_EXPR
, TREE_TYPE (temp
), temp
, clobber
);
6593 gimple_push_cleanup (temp
, clobber
, false, pre_p
, true);
6595 if (asan_poisoned_variables
6596 && DECL_ALIGN (temp
) <= MAX_SUPPORTED_STACK_ALIGNMENT
6597 && dbg_cnt (asan_use_after_scope
)
6598 && !gimplify_omp_ctxp
)
6600 tree asan_cleanup
= build_asan_poison_call_expr (temp
);
6603 if (unpoison_empty_seq
)
6604 unpoison_it
= gsi_start (*pre_p
);
6606 asan_poison_variable (temp
, false, &unpoison_it
,
6607 unpoison_empty_seq
);
6608 gimple_push_cleanup (temp
, asan_cleanup
, false, pre_p
);
6613 gimple_push_cleanup (temp
, cleanup
, false, pre_p
);
6615 /* Only expand this once. */
6616 TREE_OPERAND (targ
, 3) = init
;
6617 TARGET_EXPR_INITIAL (targ
) = NULL_TREE
;
6620 /* We should have expanded this before. */
6621 gcc_assert (DECL_SEEN_IN_BIND_EXPR_P (temp
));
6627 /* Gimplification of expression trees. */
6629 /* Gimplify an expression which appears at statement context. The
6630 corresponding GIMPLE statements are added to *SEQ_P. If *SEQ_P is
6631 NULL, a new sequence is allocated.
6633 Return true if we actually added a statement to the queue. */
6636 gimplify_stmt (tree
*stmt_p
, gimple_seq
*seq_p
)
6638 gimple_seq_node last
;
6640 last
= gimple_seq_last (*seq_p
);
6641 gimplify_expr (stmt_p
, seq_p
, NULL
, is_gimple_stmt
, fb_none
);
6642 return last
!= gimple_seq_last (*seq_p
);
6645 /* Add FIRSTPRIVATE entries for DECL in the OpenMP the surrounding parallels
6646 to CTX. If entries already exist, force them to be some flavor of private.
6647 If there is no enclosing parallel, do nothing. */
6650 omp_firstprivatize_variable (struct gimplify_omp_ctx
*ctx
, tree decl
)
6654 if (decl
== NULL
|| !DECL_P (decl
) || ctx
->region_type
== ORT_NONE
)
6659 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
)decl
);
6662 if (n
->value
& GOVD_SHARED
)
6663 n
->value
= GOVD_FIRSTPRIVATE
| (n
->value
& GOVD_SEEN
);
6664 else if (n
->value
& GOVD_MAP
)
6665 n
->value
|= GOVD_MAP_TO_ONLY
;
6669 else if ((ctx
->region_type
& ORT_TARGET
) != 0)
6671 if (ctx
->defaultmap
[GDMK_SCALAR
] & GOVD_FIRSTPRIVATE
)
6672 omp_add_variable (ctx
, decl
, GOVD_FIRSTPRIVATE
);
6674 omp_add_variable (ctx
, decl
, GOVD_MAP
| GOVD_MAP_TO_ONLY
);
6676 else if (ctx
->region_type
!= ORT_WORKSHARE
6677 && ctx
->region_type
!= ORT_TASKGROUP
6678 && ctx
->region_type
!= ORT_SIMD
6679 && ctx
->region_type
!= ORT_ACC
6680 && !(ctx
->region_type
& ORT_TARGET_DATA
))
6681 omp_add_variable (ctx
, decl
, GOVD_FIRSTPRIVATE
);
6683 ctx
= ctx
->outer_context
;
6688 /* Similarly for each of the type sizes of TYPE. */
6691 omp_firstprivatize_type_sizes (struct gimplify_omp_ctx
*ctx
, tree type
)
6693 if (type
== NULL
|| type
== error_mark_node
)
6695 type
= TYPE_MAIN_VARIANT (type
);
6697 if (ctx
->privatized_types
->add (type
))
6700 switch (TREE_CODE (type
))
6706 case FIXED_POINT_TYPE
:
6707 omp_firstprivatize_variable (ctx
, TYPE_MIN_VALUE (type
));
6708 omp_firstprivatize_variable (ctx
, TYPE_MAX_VALUE (type
));
6712 omp_firstprivatize_type_sizes (ctx
, TREE_TYPE (type
));
6713 omp_firstprivatize_type_sizes (ctx
, TYPE_DOMAIN (type
));
6718 case QUAL_UNION_TYPE
:
6721 for (field
= TYPE_FIELDS (type
); field
; field
= DECL_CHAIN (field
))
6722 if (TREE_CODE (field
) == FIELD_DECL
)
6724 omp_firstprivatize_variable (ctx
, DECL_FIELD_OFFSET (field
));
6725 omp_firstprivatize_type_sizes (ctx
, TREE_TYPE (field
));
6731 case REFERENCE_TYPE
:
6732 omp_firstprivatize_type_sizes (ctx
, TREE_TYPE (type
));
6739 omp_firstprivatize_variable (ctx
, TYPE_SIZE (type
));
6740 omp_firstprivatize_variable (ctx
, TYPE_SIZE_UNIT (type
));
6741 lang_hooks
.types
.omp_firstprivatize_type_sizes (ctx
, type
);
6744 /* Add an entry for DECL in the OMP context CTX with FLAGS. */
6747 omp_add_variable (struct gimplify_omp_ctx
*ctx
, tree decl
, unsigned int flags
)
6750 unsigned int nflags
;
6753 if (error_operand_p (decl
) || ctx
->region_type
== ORT_NONE
)
6756 /* Never elide decls whose type has TREE_ADDRESSABLE set. This means
6757 there are constructors involved somewhere. Exception is a shared clause,
6758 there is nothing privatized in that case. */
6759 if ((flags
& GOVD_SHARED
) == 0
6760 && (TREE_ADDRESSABLE (TREE_TYPE (decl
))
6761 || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl
))))
6764 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
)decl
);
6765 if (n
!= NULL
&& (n
->value
& GOVD_DATA_SHARE_CLASS
) != 0)
6767 /* We shouldn't be re-adding the decl with the same data
6769 gcc_assert ((n
->value
& GOVD_DATA_SHARE_CLASS
& flags
) == 0);
6770 nflags
= n
->value
| flags
;
6771 /* The only combination of data sharing classes we should see is
6772 FIRSTPRIVATE and LASTPRIVATE. However, OpenACC permits
6773 reduction variables to be used in data sharing clauses. */
6774 gcc_assert ((ctx
->region_type
& ORT_ACC
) != 0
6775 || ((nflags
& GOVD_DATA_SHARE_CLASS
)
6776 == (GOVD_FIRSTPRIVATE
| GOVD_LASTPRIVATE
))
6777 || (flags
& GOVD_DATA_SHARE_CLASS
) == 0);
6782 /* When adding a variable-sized variable, we have to handle all sorts
6783 of additional bits of data: the pointer replacement variable, and
6784 the parameters of the type. */
6785 if (DECL_SIZE (decl
) && TREE_CODE (DECL_SIZE (decl
)) != INTEGER_CST
)
6787 /* Add the pointer replacement variable as PRIVATE if the variable
6788 replacement is private, else FIRSTPRIVATE since we'll need the
6789 address of the original variable either for SHARED, or for the
6790 copy into or out of the context. */
6791 if (!(flags
& GOVD_LOCAL
) && ctx
->region_type
!= ORT_TASKGROUP
)
6793 if (flags
& GOVD_MAP
)
6794 nflags
= GOVD_MAP
| GOVD_MAP_TO_ONLY
| GOVD_EXPLICIT
;
6795 else if (flags
& GOVD_PRIVATE
)
6796 nflags
= GOVD_PRIVATE
;
6797 else if ((ctx
->region_type
& (ORT_TARGET
| ORT_TARGET_DATA
)) != 0
6798 && (flags
& GOVD_FIRSTPRIVATE
))
6799 nflags
= GOVD_PRIVATE
| GOVD_EXPLICIT
;
6801 nflags
= GOVD_FIRSTPRIVATE
;
6802 nflags
|= flags
& GOVD_SEEN
;
6803 t
= DECL_VALUE_EXPR (decl
);
6804 gcc_assert (TREE_CODE (t
) == INDIRECT_REF
);
6805 t
= TREE_OPERAND (t
, 0);
6806 gcc_assert (DECL_P (t
));
6807 omp_add_variable (ctx
, t
, nflags
);
6810 /* Add all of the variable and type parameters (which should have
6811 been gimplified to a formal temporary) as FIRSTPRIVATE. */
6812 omp_firstprivatize_variable (ctx
, DECL_SIZE_UNIT (decl
));
6813 omp_firstprivatize_variable (ctx
, DECL_SIZE (decl
));
6814 omp_firstprivatize_type_sizes (ctx
, TREE_TYPE (decl
));
6816 /* The variable-sized variable itself is never SHARED, only some form
6817 of PRIVATE. The sharing would take place via the pointer variable
6818 which we remapped above. */
6819 if (flags
& GOVD_SHARED
)
6820 flags
= GOVD_SHARED
| GOVD_DEBUG_PRIVATE
6821 | (flags
& (GOVD_SEEN
| GOVD_EXPLICIT
));
6823 /* We're going to make use of the TYPE_SIZE_UNIT at least in the
6824 alloca statement we generate for the variable, so make sure it
6825 is available. This isn't automatically needed for the SHARED
6826 case, since we won't be allocating local storage then.
6827 For local variables TYPE_SIZE_UNIT might not be gimplified yet,
6828 in this case omp_notice_variable will be called later
6829 on when it is gimplified. */
6830 else if (! (flags
& (GOVD_LOCAL
| GOVD_MAP
))
6831 && DECL_P (TYPE_SIZE_UNIT (TREE_TYPE (decl
))))
6832 omp_notice_variable (ctx
, TYPE_SIZE_UNIT (TREE_TYPE (decl
)), true);
6834 else if ((flags
& (GOVD_MAP
| GOVD_LOCAL
)) == 0
6835 && lang_hooks
.decls
.omp_privatize_by_reference (decl
))
6837 omp_firstprivatize_type_sizes (ctx
, TREE_TYPE (decl
));
6839 /* Similar to the direct variable sized case above, we'll need the
6840 size of references being privatized. */
6841 if ((flags
& GOVD_SHARED
) == 0)
6843 t
= TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl
)));
6845 omp_notice_variable (ctx
, t
, true);
6852 splay_tree_insert (ctx
->variables
, (splay_tree_key
)decl
, flags
);
6854 /* For reductions clauses in OpenACC loop directives, by default create a
6855 copy clause on the enclosing parallel construct for carrying back the
6857 if (ctx
->region_type
== ORT_ACC
&& (flags
& GOVD_REDUCTION
))
6859 struct gimplify_omp_ctx
*outer_ctx
= ctx
->outer_context
;
6862 n
= splay_tree_lookup (outer_ctx
->variables
, (splay_tree_key
)decl
);
6865 /* Ignore local variables and explicitly declared clauses. */
6866 if (n
->value
& (GOVD_LOCAL
| GOVD_EXPLICIT
))
6868 else if (outer_ctx
->region_type
== ORT_ACC_KERNELS
)
6870 /* According to the OpenACC spec, such a reduction variable
6871 should already have a copy map on a kernels construct,
6872 verify that here. */
6873 gcc_assert (!(n
->value
& GOVD_FIRSTPRIVATE
)
6874 && (n
->value
& GOVD_MAP
));
6876 else if (outer_ctx
->region_type
== ORT_ACC_PARALLEL
)
6878 /* Remove firstprivate and make it a copy map. */
6879 n
->value
&= ~GOVD_FIRSTPRIVATE
;
6880 n
->value
|= GOVD_MAP
;
6883 else if (outer_ctx
->region_type
== ORT_ACC_PARALLEL
)
6885 splay_tree_insert (outer_ctx
->variables
, (splay_tree_key
)decl
,
6886 GOVD_MAP
| GOVD_SEEN
);
6889 outer_ctx
= outer_ctx
->outer_context
;
6894 /* Notice a threadprivate variable DECL used in OMP context CTX.
6895 This just prints out diagnostics about threadprivate variable uses
6896 in untied tasks. If DECL2 is non-NULL, prevent this warning
6897 on that variable. */
6900 omp_notice_threadprivate_variable (struct gimplify_omp_ctx
*ctx
, tree decl
,
6904 struct gimplify_omp_ctx
*octx
;
6906 for (octx
= ctx
; octx
; octx
= octx
->outer_context
)
6907 if ((octx
->region_type
& ORT_TARGET
) != 0)
6909 n
= splay_tree_lookup (octx
->variables
, (splay_tree_key
)decl
);
6912 error ("threadprivate variable %qE used in target region",
6914 error_at (octx
->location
, "enclosing target region");
6915 splay_tree_insert (octx
->variables
, (splay_tree_key
)decl
, 0);
6918 splay_tree_insert (octx
->variables
, (splay_tree_key
)decl2
, 0);
6921 if (ctx
->region_type
!= ORT_UNTIED_TASK
)
6923 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
)decl
);
6926 error ("threadprivate variable %qE used in untied task",
6928 error_at (ctx
->location
, "enclosing task");
6929 splay_tree_insert (ctx
->variables
, (splay_tree_key
)decl
, 0);
6932 splay_tree_insert (ctx
->variables
, (splay_tree_key
)decl2
, 0);
6936 /* Return true if global var DECL is device resident. */
6939 device_resident_p (tree decl
)
6941 tree attr
= lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (decl
));
6946 for (tree t
= TREE_VALUE (attr
); t
; t
= TREE_PURPOSE (t
))
6948 tree c
= TREE_VALUE (t
);
6949 if (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_DEVICE_RESIDENT
)
6956 /* Return true if DECL has an ACC DECLARE attribute. */
6959 is_oacc_declared (tree decl
)
6961 tree t
= TREE_CODE (decl
) == MEM_REF
? TREE_OPERAND (decl
, 0) : decl
;
6962 tree declared
= lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (t
));
6963 return declared
!= NULL_TREE
;
6966 /* Determine outer default flags for DECL mentioned in an OMP region
6967 but not declared in an enclosing clause.
6969 ??? Some compiler-generated variables (like SAVE_EXPRs) could be
6970 remapped firstprivate instead of shared. To some extent this is
6971 addressed in omp_firstprivatize_type_sizes, but not
6975 omp_default_clause (struct gimplify_omp_ctx
*ctx
, tree decl
,
6976 bool in_code
, unsigned flags
)
6978 enum omp_clause_default_kind default_kind
= ctx
->default_kind
;
6979 enum omp_clause_default_kind kind
;
6981 kind
= lang_hooks
.decls
.omp_predetermined_sharing (decl
);
6982 if (kind
!= OMP_CLAUSE_DEFAULT_UNSPECIFIED
)
6983 default_kind
= kind
;
6985 switch (default_kind
)
6987 case OMP_CLAUSE_DEFAULT_NONE
:
6991 if (ctx
->region_type
& ORT_PARALLEL
)
6993 else if ((ctx
->region_type
& ORT_TASKLOOP
) == ORT_TASKLOOP
)
6995 else if (ctx
->region_type
& ORT_TASK
)
6997 else if (ctx
->region_type
& ORT_TEAMS
)
7002 error ("%qE not specified in enclosing %qs",
7003 DECL_NAME (lang_hooks
.decls
.omp_report_decl (decl
)), rtype
);
7004 error_at (ctx
->location
, "enclosing %qs", rtype
);
7007 case OMP_CLAUSE_DEFAULT_SHARED
:
7008 flags
|= GOVD_SHARED
;
7010 case OMP_CLAUSE_DEFAULT_PRIVATE
:
7011 flags
|= GOVD_PRIVATE
;
7013 case OMP_CLAUSE_DEFAULT_FIRSTPRIVATE
:
7014 flags
|= GOVD_FIRSTPRIVATE
;
7016 case OMP_CLAUSE_DEFAULT_UNSPECIFIED
:
7017 /* decl will be either GOVD_FIRSTPRIVATE or GOVD_SHARED. */
7018 gcc_assert ((ctx
->region_type
& ORT_TASK
) != 0);
7019 if (struct gimplify_omp_ctx
*octx
= ctx
->outer_context
)
7021 omp_notice_variable (octx
, decl
, in_code
);
7022 for (; octx
; octx
= octx
->outer_context
)
7026 n2
= splay_tree_lookup (octx
->variables
, (splay_tree_key
) decl
);
7027 if ((octx
->region_type
& (ORT_TARGET_DATA
| ORT_TARGET
)) != 0
7028 && (n2
== NULL
|| (n2
->value
& GOVD_DATA_SHARE_CLASS
) == 0))
7030 if (n2
&& (n2
->value
& GOVD_DATA_SHARE_CLASS
) != GOVD_SHARED
)
7032 flags
|= GOVD_FIRSTPRIVATE
;
7035 if ((octx
->region_type
& (ORT_PARALLEL
| ORT_TEAMS
)) != 0)
7037 flags
|= GOVD_SHARED
;
7043 if (TREE_CODE (decl
) == PARM_DECL
7044 || (!is_global_var (decl
)
7045 && DECL_CONTEXT (decl
) == current_function_decl
))
7046 flags
|= GOVD_FIRSTPRIVATE
;
7048 flags
|= GOVD_SHARED
;
7060 /* Determine outer default flags for DECL mentioned in an OACC region
7061 but not declared in an enclosing clause. */
7064 oacc_default_clause (struct gimplify_omp_ctx
*ctx
, tree decl
, unsigned flags
)
7067 bool on_device
= false;
7068 bool declared
= is_oacc_declared (decl
);
7069 tree type
= TREE_TYPE (decl
);
7071 if (lang_hooks
.decls
.omp_privatize_by_reference (decl
))
7072 type
= TREE_TYPE (type
);
7074 if ((ctx
->region_type
& (ORT_ACC_PARALLEL
| ORT_ACC_KERNELS
)) != 0
7075 && is_global_var (decl
)
7076 && device_resident_p (decl
))
7079 flags
|= GOVD_MAP_TO_ONLY
;
7082 switch (ctx
->region_type
)
7084 case ORT_ACC_KERNELS
:
7087 if (AGGREGATE_TYPE_P (type
))
7089 /* Aggregates default to 'present_or_copy', or 'present'. */
7090 if (ctx
->default_kind
!= OMP_CLAUSE_DEFAULT_PRESENT
)
7093 flags
|= GOVD_MAP
| GOVD_MAP_FORCE_PRESENT
;
7096 /* Scalars default to 'copy'. */
7097 flags
|= GOVD_MAP
| GOVD_MAP_FORCE
;
7101 case ORT_ACC_PARALLEL
:
7104 if (on_device
|| declared
)
7106 else if (AGGREGATE_TYPE_P (type
))
7108 /* Aggregates default to 'present_or_copy', or 'present'. */
7109 if (ctx
->default_kind
!= OMP_CLAUSE_DEFAULT_PRESENT
)
7112 flags
|= GOVD_MAP
| GOVD_MAP_FORCE_PRESENT
;
7115 /* Scalars default to 'firstprivate'. */
7116 flags
|= GOVD_FIRSTPRIVATE
;
7124 if (DECL_ARTIFICIAL (decl
))
7125 ; /* We can get compiler-generated decls, and should not complain
7127 else if (ctx
->default_kind
== OMP_CLAUSE_DEFAULT_NONE
)
7129 error ("%qE not specified in enclosing OpenACC %qs construct",
7130 DECL_NAME (lang_hooks
.decls
.omp_report_decl (decl
)), rkind
);
7131 inform (ctx
->location
, "enclosing OpenACC %qs construct", rkind
);
7133 else if (ctx
->default_kind
== OMP_CLAUSE_DEFAULT_PRESENT
)
7134 ; /* Handled above. */
7136 gcc_checking_assert (ctx
->default_kind
== OMP_CLAUSE_DEFAULT_SHARED
);
7141 /* Record the fact that DECL was used within the OMP context CTX.
7142 IN_CODE is true when real code uses DECL, and false when we should
7143 merely emit default(none) errors. Return true if DECL is going to
7144 be remapped and thus DECL shouldn't be gimplified into its
7145 DECL_VALUE_EXPR (if any). */
7148 omp_notice_variable (struct gimplify_omp_ctx
*ctx
, tree decl
, bool in_code
)
7151 unsigned flags
= in_code
? GOVD_SEEN
: 0;
7152 bool ret
= false, shared
;
7154 if (error_operand_p (decl
))
7157 if (ctx
->region_type
== ORT_NONE
)
7158 return lang_hooks
.decls
.omp_disregard_value_expr (decl
, false);
7160 if (is_global_var (decl
))
7162 /* Threadprivate variables are predetermined. */
7163 if (DECL_THREAD_LOCAL_P (decl
))
7164 return omp_notice_threadprivate_variable (ctx
, decl
, NULL_TREE
);
7166 if (DECL_HAS_VALUE_EXPR_P (decl
))
7168 tree value
= get_base_address (DECL_VALUE_EXPR (decl
));
7170 if (value
&& DECL_P (value
) && DECL_THREAD_LOCAL_P (value
))
7171 return omp_notice_threadprivate_variable (ctx
, decl
, value
);
7174 if (gimplify_omp_ctxp
->outer_context
== NULL
7176 && oacc_get_fn_attrib (current_function_decl
))
7178 location_t loc
= DECL_SOURCE_LOCATION (decl
);
7180 if (lookup_attribute ("omp declare target link",
7181 DECL_ATTRIBUTES (decl
)))
7184 "%qE with %<link%> clause used in %<routine%> function",
7188 else if (!lookup_attribute ("omp declare target",
7189 DECL_ATTRIBUTES (decl
)))
7192 "%qE requires a %<declare%> directive for use "
7193 "in a %<routine%> function", DECL_NAME (decl
));
7199 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
)decl
);
7200 if ((ctx
->region_type
& ORT_TARGET
) != 0)
7202 ret
= lang_hooks
.decls
.omp_disregard_value_expr (decl
, true);
7205 unsigned nflags
= flags
;
7206 if ((ctx
->region_type
& ORT_ACC
) == 0)
7208 bool is_declare_target
= false;
7209 if (is_global_var (decl
)
7210 && varpool_node::get_create (decl
)->offloadable
)
7212 struct gimplify_omp_ctx
*octx
;
7213 for (octx
= ctx
->outer_context
;
7214 octx
; octx
= octx
->outer_context
)
7216 n
= splay_tree_lookup (octx
->variables
,
7217 (splay_tree_key
)decl
);
7219 && (n
->value
& GOVD_DATA_SHARE_CLASS
) != GOVD_SHARED
7220 && (n
->value
& GOVD_DATA_SHARE_CLASS
) != 0)
7223 is_declare_target
= octx
== NULL
;
7225 if (!is_declare_target
)
7228 if (TREE_CODE (TREE_TYPE (decl
)) == POINTER_TYPE
7229 || (TREE_CODE (TREE_TYPE (decl
)) == REFERENCE_TYPE
7230 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl
)))
7232 gdmk
= GDMK_POINTER
;
7233 else if (lang_hooks
.decls
.omp_scalar_p (decl
))
7236 gdmk
= GDMK_AGGREGATE
;
7237 if (ctx
->defaultmap
[gdmk
] == 0)
7239 tree d
= lang_hooks
.decls
.omp_report_decl (decl
);
7240 error ("%qE not specified in enclosing %<target%>",
7242 error_at (ctx
->location
, "enclosing %<target%>");
7244 else if (ctx
->defaultmap
[gdmk
]
7245 & (GOVD_MAP_0LEN_ARRAY
| GOVD_FIRSTPRIVATE
))
7246 nflags
|= ctx
->defaultmap
[gdmk
];
7249 gcc_assert (ctx
->defaultmap
[gdmk
] & GOVD_MAP
);
7250 nflags
|= ctx
->defaultmap
[gdmk
] & ~GOVD_MAP
;
7255 struct gimplify_omp_ctx
*octx
= ctx
->outer_context
;
7256 if ((ctx
->region_type
& ORT_ACC
) && octx
)
7258 /* Look in outer OpenACC contexts, to see if there's a
7259 data attribute for this variable. */
7260 omp_notice_variable (octx
, decl
, in_code
);
7262 for (; octx
; octx
= octx
->outer_context
)
7264 if (!(octx
->region_type
& (ORT_TARGET_DATA
| ORT_TARGET
)))
7267 = splay_tree_lookup (octx
->variables
,
7268 (splay_tree_key
) decl
);
7271 if (octx
->region_type
== ORT_ACC_HOST_DATA
)
7272 error ("variable %qE declared in enclosing "
7273 "%<host_data%> region", DECL_NAME (decl
));
7275 if (octx
->region_type
== ORT_ACC_DATA
7276 && (n2
->value
& GOVD_MAP_0LEN_ARRAY
))
7277 nflags
|= GOVD_MAP_0LEN_ARRAY
;
7283 if ((nflags
& ~(GOVD_MAP_TO_ONLY
| GOVD_MAP_FROM_ONLY
7284 | GOVD_MAP_ALLOC_ONLY
)) == flags
)
7286 tree type
= TREE_TYPE (decl
);
7288 if (gimplify_omp_ctxp
->target_firstprivatize_array_bases
7289 && lang_hooks
.decls
.omp_privatize_by_reference (decl
))
7290 type
= TREE_TYPE (type
);
7291 if (!lang_hooks
.types
.omp_mappable_type (type
))
7293 error ("%qD referenced in target region does not have "
7294 "a mappable type", decl
);
7295 nflags
|= GOVD_MAP
| GOVD_EXPLICIT
;
7299 if ((ctx
->region_type
& ORT_ACC
) != 0)
7300 nflags
= oacc_default_clause (ctx
, decl
, flags
);
7306 omp_add_variable (ctx
, decl
, nflags
);
7310 /* If nothing changed, there's nothing left to do. */
7311 if ((n
->value
& flags
) == flags
)
7321 if (ctx
->region_type
== ORT_WORKSHARE
7322 || ctx
->region_type
== ORT_TASKGROUP
7323 || ctx
->region_type
== ORT_SIMD
7324 || ctx
->region_type
== ORT_ACC
7325 || (ctx
->region_type
& ORT_TARGET_DATA
) != 0)
7328 flags
= omp_default_clause (ctx
, decl
, in_code
, flags
);
7330 if ((flags
& GOVD_PRIVATE
)
7331 && lang_hooks
.decls
.omp_private_outer_ref (decl
))
7332 flags
|= GOVD_PRIVATE_OUTER_REF
;
7334 omp_add_variable (ctx
, decl
, flags
);
7336 shared
= (flags
& GOVD_SHARED
) != 0;
7337 ret
= lang_hooks
.decls
.omp_disregard_value_expr (decl
, shared
);
7341 if ((n
->value
& (GOVD_SEEN
| GOVD_LOCAL
)) == 0
7342 && (flags
& (GOVD_SEEN
| GOVD_LOCAL
)) == GOVD_SEEN
7343 && DECL_SIZE (decl
))
7345 if (TREE_CODE (DECL_SIZE (decl
)) != INTEGER_CST
)
7348 tree t
= DECL_VALUE_EXPR (decl
);
7349 gcc_assert (TREE_CODE (t
) == INDIRECT_REF
);
7350 t
= TREE_OPERAND (t
, 0);
7351 gcc_assert (DECL_P (t
));
7352 n2
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) t
);
7353 n2
->value
|= GOVD_SEEN
;
7355 else if (lang_hooks
.decls
.omp_privatize_by_reference (decl
)
7356 && TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl
)))
7357 && (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl
))))
7361 tree t
= TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl
)));
7362 gcc_assert (DECL_P (t
));
7363 n2
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) t
);
7365 omp_notice_variable (ctx
, t
, true);
7369 shared
= ((flags
| n
->value
) & GOVD_SHARED
) != 0;
7370 ret
= lang_hooks
.decls
.omp_disregard_value_expr (decl
, shared
);
7372 /* If nothing changed, there's nothing left to do. */
7373 if ((n
->value
& flags
) == flags
)
7379 /* If the variable is private in the current context, then we don't
7380 need to propagate anything to an outer context. */
7381 if ((flags
& GOVD_PRIVATE
) && !(flags
& GOVD_PRIVATE_OUTER_REF
))
7383 if ((flags
& (GOVD_LINEAR
| GOVD_LINEAR_LASTPRIVATE_NO_OUTER
))
7384 == (GOVD_LINEAR
| GOVD_LINEAR_LASTPRIVATE_NO_OUTER
))
7386 if ((flags
& (GOVD_FIRSTPRIVATE
| GOVD_LASTPRIVATE
7387 | GOVD_LINEAR_LASTPRIVATE_NO_OUTER
))
7388 == (GOVD_LASTPRIVATE
| GOVD_LINEAR_LASTPRIVATE_NO_OUTER
))
7390 if (ctx
->outer_context
7391 && omp_notice_variable (ctx
->outer_context
, decl
, in_code
))
7396 /* Verify that DECL is private within CTX. If there's specific information
7397 to the contrary in the innermost scope, generate an error. */
7400 omp_is_private (struct gimplify_omp_ctx
*ctx
, tree decl
, int simd
)
7404 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
)decl
);
7407 if (n
->value
& GOVD_SHARED
)
7409 if (ctx
== gimplify_omp_ctxp
)
7412 error ("iteration variable %qE is predetermined linear",
7415 error ("iteration variable %qE should be private",
7417 n
->value
= GOVD_PRIVATE
;
7423 else if ((n
->value
& GOVD_EXPLICIT
) != 0
7424 && (ctx
== gimplify_omp_ctxp
7425 || (ctx
->region_type
== ORT_COMBINED_PARALLEL
7426 && gimplify_omp_ctxp
->outer_context
== ctx
)))
7428 if ((n
->value
& GOVD_FIRSTPRIVATE
) != 0)
7429 error ("iteration variable %qE should not be firstprivate",
7431 else if ((n
->value
& GOVD_REDUCTION
) != 0)
7432 error ("iteration variable %qE should not be reduction",
7434 else if (simd
!= 1 && (n
->value
& GOVD_LINEAR
) != 0)
7435 error ("iteration variable %qE should not be linear",
7438 return (ctx
== gimplify_omp_ctxp
7439 || (ctx
->region_type
== ORT_COMBINED_PARALLEL
7440 && gimplify_omp_ctxp
->outer_context
== ctx
));
7443 if (ctx
->region_type
!= ORT_WORKSHARE
7444 && ctx
->region_type
!= ORT_TASKGROUP
7445 && ctx
->region_type
!= ORT_SIMD
7446 && ctx
->region_type
!= ORT_ACC
)
7448 else if (ctx
->outer_context
)
7449 return omp_is_private (ctx
->outer_context
, decl
, simd
);
7453 /* Return true if DECL is private within a parallel region
7454 that binds to the current construct's context or in parallel
7455 region's REDUCTION clause. */
7458 omp_check_private (struct gimplify_omp_ctx
*ctx
, tree decl
, bool copyprivate
)
7464 ctx
= ctx
->outer_context
;
7467 if (is_global_var (decl
))
7470 /* References might be private, but might be shared too,
7471 when checking for copyprivate, assume they might be
7472 private, otherwise assume they might be shared. */
7476 if (lang_hooks
.decls
.omp_privatize_by_reference (decl
))
7479 /* Treat C++ privatized non-static data members outside
7480 of the privatization the same. */
7481 if (omp_member_access_dummy_var (decl
))
7487 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
7489 if ((ctx
->region_type
& (ORT_TARGET
| ORT_TARGET_DATA
)) != 0
7490 && (n
== NULL
|| (n
->value
& GOVD_DATA_SHARE_CLASS
) == 0))
7495 if ((n
->value
& GOVD_LOCAL
) != 0
7496 && omp_member_access_dummy_var (decl
))
7498 return (n
->value
& GOVD_SHARED
) == 0;
7501 while (ctx
->region_type
== ORT_WORKSHARE
7502 || ctx
->region_type
== ORT_TASKGROUP
7503 || ctx
->region_type
== ORT_SIMD
7504 || ctx
->region_type
== ORT_ACC
);
7508 /* Callback for walk_tree to find a DECL_EXPR for the given DECL. */
7511 find_decl_expr (tree
*tp
, int *walk_subtrees
, void *data
)
7515 /* If this node has been visited, unmark it and keep looking. */
7516 if (TREE_CODE (t
) == DECL_EXPR
&& DECL_EXPR_DECL (t
) == (tree
) data
)
7519 if (IS_TYPE_OR_DECL_P (t
))
7524 /* If *LIST_P contains any OpenMP depend clauses with iterators,
7525 lower all the depend clauses by populating corresponding depend
7526 array. Returns 0 if there are no such depend clauses, or
7527 2 if all depend clauses should be removed, 1 otherwise. */
7530 gimplify_omp_depend (tree
*list_p
, gimple_seq
*pre_p
)
7534 size_t n
[4] = { 0, 0, 0, 0 };
7536 tree counts
[4] = { NULL_TREE
, NULL_TREE
, NULL_TREE
, NULL_TREE
};
7537 tree last_iter
= NULL_TREE
, last_count
= NULL_TREE
;
7539 location_t first_loc
= UNKNOWN_LOCATION
;
7541 for (c
= *list_p
; c
; c
= OMP_CLAUSE_CHAIN (c
))
7542 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEPEND
)
7544 switch (OMP_CLAUSE_DEPEND_KIND (c
))
7546 case OMP_CLAUSE_DEPEND_IN
:
7549 case OMP_CLAUSE_DEPEND_OUT
:
7550 case OMP_CLAUSE_DEPEND_INOUT
:
7553 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET
:
7556 case OMP_CLAUSE_DEPEND_DEPOBJ
:
7559 case OMP_CLAUSE_DEPEND_SOURCE
:
7560 case OMP_CLAUSE_DEPEND_SINK
:
7565 tree t
= OMP_CLAUSE_DECL (c
);
7566 if (first_loc
== UNKNOWN_LOCATION
)
7567 first_loc
= OMP_CLAUSE_LOCATION (c
);
7568 if (TREE_CODE (t
) == TREE_LIST
7570 && TREE_CODE (TREE_PURPOSE (t
)) == TREE_VEC
)
7572 if (TREE_PURPOSE (t
) != last_iter
)
7574 tree tcnt
= size_one_node
;
7575 for (tree it
= TREE_PURPOSE (t
); it
; it
= TREE_CHAIN (it
))
7577 if (gimplify_expr (&TREE_VEC_ELT (it
, 1), pre_p
, NULL
,
7578 is_gimple_val
, fb_rvalue
) == GS_ERROR
7579 || gimplify_expr (&TREE_VEC_ELT (it
, 2), pre_p
, NULL
,
7580 is_gimple_val
, fb_rvalue
) == GS_ERROR
7581 || gimplify_expr (&TREE_VEC_ELT (it
, 3), pre_p
, NULL
,
7582 is_gimple_val
, fb_rvalue
) == GS_ERROR
7583 || (gimplify_expr (&TREE_VEC_ELT (it
, 4), pre_p
, NULL
,
7584 is_gimple_val
, fb_rvalue
)
7587 tree var
= TREE_VEC_ELT (it
, 0);
7588 tree begin
= TREE_VEC_ELT (it
, 1);
7589 tree end
= TREE_VEC_ELT (it
, 2);
7590 tree step
= TREE_VEC_ELT (it
, 3);
7591 tree orig_step
= TREE_VEC_ELT (it
, 4);
7592 tree type
= TREE_TYPE (var
);
7593 tree stype
= TREE_TYPE (step
);
7594 location_t loc
= DECL_SOURCE_LOCATION (var
);
7596 /* Compute count for this iterator as
7598 ? (begin < end ? (end - begin + (step - 1)) / step : 0)
7599 : (begin > end ? (end - begin + (step + 1)) / step : 0)
7600 and compute product of those for the entire depend
7602 if (POINTER_TYPE_P (type
))
7603 endmbegin
= fold_build2_loc (loc
, POINTER_DIFF_EXPR
,
7606 endmbegin
= fold_build2_loc (loc
, MINUS_EXPR
, type
,
7608 tree stepm1
= fold_build2_loc (loc
, MINUS_EXPR
, stype
,
7610 build_int_cst (stype
, 1));
7611 tree stepp1
= fold_build2_loc (loc
, PLUS_EXPR
, stype
, step
,
7612 build_int_cst (stype
, 1));
7613 tree pos
= fold_build2_loc (loc
, PLUS_EXPR
, stype
,
7614 unshare_expr (endmbegin
),
7616 pos
= fold_build2_loc (loc
, TRUNC_DIV_EXPR
, stype
,
7618 tree neg
= fold_build2_loc (loc
, PLUS_EXPR
, stype
,
7620 if (TYPE_UNSIGNED (stype
))
7622 neg
= fold_build1_loc (loc
, NEGATE_EXPR
, stype
, neg
);
7623 step
= fold_build1_loc (loc
, NEGATE_EXPR
, stype
, step
);
7625 neg
= fold_build2_loc (loc
, TRUNC_DIV_EXPR
, stype
,
7628 tree cond
= fold_build2_loc (loc
, LT_EXPR
,
7631 pos
= fold_build3_loc (loc
, COND_EXPR
, stype
, cond
, pos
,
7632 build_int_cst (stype
, 0));
7633 cond
= fold_build2_loc (loc
, LT_EXPR
, boolean_type_node
,
7635 neg
= fold_build3_loc (loc
, COND_EXPR
, stype
, cond
, neg
,
7636 build_int_cst (stype
, 0));
7637 tree osteptype
= TREE_TYPE (orig_step
);
7638 cond
= fold_build2_loc (loc
, GT_EXPR
, boolean_type_node
,
7640 build_int_cst (osteptype
, 0));
7641 tree cnt
= fold_build3_loc (loc
, COND_EXPR
, stype
,
7643 cnt
= fold_convert_loc (loc
, sizetype
, cnt
);
7644 if (gimplify_expr (&cnt
, pre_p
, NULL
, is_gimple_val
,
7645 fb_rvalue
) == GS_ERROR
)
7647 tcnt
= size_binop_loc (loc
, MULT_EXPR
, tcnt
, cnt
);
7649 if (gimplify_expr (&tcnt
, pre_p
, NULL
, is_gimple_val
,
7650 fb_rvalue
) == GS_ERROR
)
7652 last_iter
= TREE_PURPOSE (t
);
7655 if (counts
[i
] == NULL_TREE
)
7656 counts
[i
] = last_count
;
7658 counts
[i
] = size_binop_loc (OMP_CLAUSE_LOCATION (c
),
7659 PLUS_EXPR
, counts
[i
], last_count
);
7664 for (i
= 0; i
< 4; i
++)
7670 tree total
= size_zero_node
;
7671 for (i
= 0; i
< 4; i
++)
7673 unused
[i
] = counts
[i
] == NULL_TREE
&& n
[i
] == 0;
7674 if (counts
[i
] == NULL_TREE
)
7675 counts
[i
] = size_zero_node
;
7677 counts
[i
] = size_binop (PLUS_EXPR
, counts
[i
], size_int (n
[i
]));
7678 if (gimplify_expr (&counts
[i
], pre_p
, NULL
, is_gimple_val
,
7679 fb_rvalue
) == GS_ERROR
)
7681 total
= size_binop (PLUS_EXPR
, total
, counts
[i
]);
7684 if (gimplify_expr (&total
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
)
7687 bool is_old
= unused
[1] && unused
[3];
7688 tree totalpx
= size_binop (PLUS_EXPR
, unshare_expr (total
),
7689 size_int (is_old
? 1 : 4));
7690 tree type
= build_array_type (ptr_type_node
, build_index_type (totalpx
));
7691 tree array
= create_tmp_var_raw (type
);
7692 TREE_ADDRESSABLE (array
) = 1;
7693 if (TREE_CODE (totalpx
) != INTEGER_CST
)
7695 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (array
)))
7696 gimplify_type_sizes (TREE_TYPE (array
), pre_p
);
7697 if (gimplify_omp_ctxp
)
7699 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
7701 && (ctx
->region_type
== ORT_WORKSHARE
7702 || ctx
->region_type
== ORT_TASKGROUP
7703 || ctx
->region_type
== ORT_SIMD
7704 || ctx
->region_type
== ORT_ACC
))
7705 ctx
= ctx
->outer_context
;
7707 omp_add_variable (ctx
, array
, GOVD_LOCAL
| GOVD_SEEN
);
7709 gimplify_vla_decl (array
, pre_p
);
7712 gimple_add_tmp_var (array
);
7713 tree r
= build4 (ARRAY_REF
, ptr_type_node
, array
, size_int (0), NULL_TREE
,
7718 tem
= build2 (MODIFY_EXPR
, void_type_node
, r
,
7719 build_int_cst (ptr_type_node
, 0));
7720 gimplify_and_add (tem
, pre_p
);
7721 r
= build4 (ARRAY_REF
, ptr_type_node
, array
, size_int (1), NULL_TREE
,
7724 tem
= build2 (MODIFY_EXPR
, void_type_node
, r
,
7725 fold_convert (ptr_type_node
, total
));
7726 gimplify_and_add (tem
, pre_p
);
7727 for (i
= 1; i
< (is_old
? 2 : 4); i
++)
7729 r
= build4 (ARRAY_REF
, ptr_type_node
, array
, size_int (i
+ !is_old
),
7730 NULL_TREE
, NULL_TREE
);
7731 tem
= build2 (MODIFY_EXPR
, void_type_node
, r
, counts
[i
- 1]);
7732 gimplify_and_add (tem
, pre_p
);
7739 for (i
= 0; i
< 4; i
++)
7741 if (i
&& (i
>= j
|| unused
[i
- 1]))
7743 cnts
[i
] = cnts
[i
- 1];
7746 cnts
[i
] = create_tmp_var (sizetype
);
7748 g
= gimple_build_assign (cnts
[i
], size_int (is_old
? 2 : 5));
7753 t
= size_binop (PLUS_EXPR
, counts
[0], size_int (2));
7755 t
= size_binop (PLUS_EXPR
, cnts
[i
- 1], counts
[i
- 1]);
7756 if (gimplify_expr (&t
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
)
7759 g
= gimple_build_assign (cnts
[i
], t
);
7761 gimple_seq_add_stmt (pre_p
, g
);
7764 last_iter
= NULL_TREE
;
7765 tree last_bind
= NULL_TREE
;
7766 tree
*last_body
= NULL
;
7767 for (c
= *list_p
; c
; c
= OMP_CLAUSE_CHAIN (c
))
7768 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEPEND
)
7770 switch (OMP_CLAUSE_DEPEND_KIND (c
))
7772 case OMP_CLAUSE_DEPEND_IN
:
7775 case OMP_CLAUSE_DEPEND_OUT
:
7776 case OMP_CLAUSE_DEPEND_INOUT
:
7779 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET
:
7782 case OMP_CLAUSE_DEPEND_DEPOBJ
:
7785 case OMP_CLAUSE_DEPEND_SOURCE
:
7786 case OMP_CLAUSE_DEPEND_SINK
:
7791 tree t
= OMP_CLAUSE_DECL (c
);
7792 if (TREE_CODE (t
) == TREE_LIST
7794 && TREE_CODE (TREE_PURPOSE (t
)) == TREE_VEC
)
7796 if (TREE_PURPOSE (t
) != last_iter
)
7799 gimplify_and_add (last_bind
, pre_p
);
7800 tree block
= TREE_VEC_ELT (TREE_PURPOSE (t
), 5);
7801 last_bind
= build3 (BIND_EXPR
, void_type_node
,
7802 BLOCK_VARS (block
), NULL
, block
);
7803 TREE_SIDE_EFFECTS (last_bind
) = 1;
7804 SET_EXPR_LOCATION (last_bind
, OMP_CLAUSE_LOCATION (c
));
7805 tree
*p
= &BIND_EXPR_BODY (last_bind
);
7806 for (tree it
= TREE_PURPOSE (t
); it
; it
= TREE_CHAIN (it
))
7808 tree var
= TREE_VEC_ELT (it
, 0);
7809 tree begin
= TREE_VEC_ELT (it
, 1);
7810 tree end
= TREE_VEC_ELT (it
, 2);
7811 tree step
= TREE_VEC_ELT (it
, 3);
7812 tree orig_step
= TREE_VEC_ELT (it
, 4);
7813 tree type
= TREE_TYPE (var
);
7814 location_t loc
= DECL_SOURCE_LOCATION (var
);
7822 if (orig_step > 0) {
7823 if (var < end) goto beg_label;
7825 if (var > end) goto beg_label;
7827 for each iterator, with inner iterators added to
7829 tree beg_label
= create_artificial_label (loc
);
7830 tree cond_label
= NULL_TREE
;
7831 tem
= build2_loc (loc
, MODIFY_EXPR
, void_type_node
,
7833 append_to_statement_list_force (tem
, p
);
7834 tem
= build_and_jump (&cond_label
);
7835 append_to_statement_list_force (tem
, p
);
7836 tem
= build1 (LABEL_EXPR
, void_type_node
, beg_label
);
7837 append_to_statement_list (tem
, p
);
7838 tree bind
= build3 (BIND_EXPR
, void_type_node
, NULL_TREE
,
7839 NULL_TREE
, NULL_TREE
);
7840 TREE_SIDE_EFFECTS (bind
) = 1;
7841 SET_EXPR_LOCATION (bind
, loc
);
7842 append_to_statement_list_force (bind
, p
);
7843 if (POINTER_TYPE_P (type
))
7844 tem
= build2_loc (loc
, POINTER_PLUS_EXPR
, type
,
7845 var
, fold_convert_loc (loc
, sizetype
,
7848 tem
= build2_loc (loc
, PLUS_EXPR
, type
, var
, step
);
7849 tem
= build2_loc (loc
, MODIFY_EXPR
, void_type_node
,
7851 append_to_statement_list_force (tem
, p
);
7852 tem
= build1 (LABEL_EXPR
, void_type_node
, cond_label
);
7853 append_to_statement_list (tem
, p
);
7854 tree cond
= fold_build2_loc (loc
, LT_EXPR
,
7858 = fold_build3_loc (loc
, COND_EXPR
, void_type_node
,
7859 cond
, build_and_jump (&beg_label
),
7861 cond
= fold_build2_loc (loc
, GT_EXPR
, boolean_type_node
,
7864 = fold_build3_loc (loc
, COND_EXPR
, void_type_node
,
7865 cond
, build_and_jump (&beg_label
),
7867 tree osteptype
= TREE_TYPE (orig_step
);
7868 cond
= fold_build2_loc (loc
, GT_EXPR
, boolean_type_node
,
7870 build_int_cst (osteptype
, 0));
7871 tem
= fold_build3_loc (loc
, COND_EXPR
, void_type_node
,
7873 append_to_statement_list_force (tem
, p
);
7874 p
= &BIND_EXPR_BODY (bind
);
7878 last_iter
= TREE_PURPOSE (t
);
7879 if (TREE_CODE (TREE_VALUE (t
)) == COMPOUND_EXPR
)
7881 append_to_statement_list (TREE_OPERAND (TREE_VALUE (t
),
7883 TREE_VALUE (t
) = TREE_OPERAND (TREE_VALUE (t
), 1);
7885 if (error_operand_p (TREE_VALUE (t
)))
7887 TREE_VALUE (t
) = build_fold_addr_expr (TREE_VALUE (t
));
7888 r
= build4 (ARRAY_REF
, ptr_type_node
, array
, cnts
[i
],
7889 NULL_TREE
, NULL_TREE
);
7890 tem
= build2_loc (OMP_CLAUSE_LOCATION (c
), MODIFY_EXPR
,
7891 void_type_node
, r
, TREE_VALUE (t
));
7892 append_to_statement_list_force (tem
, last_body
);
7893 tem
= build2_loc (OMP_CLAUSE_LOCATION (c
), MODIFY_EXPR
,
7894 void_type_node
, cnts
[i
],
7895 size_binop (PLUS_EXPR
, cnts
[i
], size_int (1)));
7896 append_to_statement_list_force (tem
, last_body
);
7897 TREE_VALUE (t
) = null_pointer_node
;
7903 gimplify_and_add (last_bind
, pre_p
);
7904 last_bind
= NULL_TREE
;
7906 if (TREE_CODE (OMP_CLAUSE_DECL (c
)) == COMPOUND_EXPR
)
7908 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c
), 0), pre_p
,
7909 NULL
, is_gimple_val
, fb_rvalue
);
7910 OMP_CLAUSE_DECL (c
) = TREE_OPERAND (OMP_CLAUSE_DECL (c
), 1);
7912 if (error_operand_p (OMP_CLAUSE_DECL (c
)))
7914 OMP_CLAUSE_DECL (c
) = build_fold_addr_expr (OMP_CLAUSE_DECL (c
));
7915 if (gimplify_expr (&OMP_CLAUSE_DECL (c
), pre_p
, NULL
,
7916 is_gimple_val
, fb_rvalue
) == GS_ERROR
)
7918 r
= build4 (ARRAY_REF
, ptr_type_node
, array
, cnts
[i
],
7919 NULL_TREE
, NULL_TREE
);
7920 tem
= build2 (MODIFY_EXPR
, void_type_node
, r
, OMP_CLAUSE_DECL (c
));
7921 gimplify_and_add (tem
, pre_p
);
7922 g
= gimple_build_assign (cnts
[i
], size_binop (PLUS_EXPR
, cnts
[i
],
7924 gimple_seq_add_stmt (pre_p
, g
);
7928 gimplify_and_add (last_bind
, pre_p
);
7929 tree cond
= boolean_false_node
;
7933 cond
= build2_loc (first_loc
, NE_EXPR
, boolean_type_node
, cnts
[0],
7934 size_binop_loc (first_loc
, PLUS_EXPR
, counts
[0],
7937 cond
= build2_loc (first_loc
, TRUTH_OR_EXPR
, boolean_type_node
, cond
,
7938 build2_loc (first_loc
, NE_EXPR
, boolean_type_node
,
7940 size_binop_loc (first_loc
, PLUS_EXPR
,
7946 tree prev
= size_int (5);
7947 for (i
= 0; i
< 4; i
++)
7951 prev
= size_binop_loc (first_loc
, PLUS_EXPR
, counts
[i
], prev
);
7952 cond
= build2_loc (first_loc
, TRUTH_OR_EXPR
, boolean_type_node
, cond
,
7953 build2_loc (first_loc
, NE_EXPR
, boolean_type_node
,
7954 cnts
[i
], unshare_expr (prev
)));
7957 tem
= build3_loc (first_loc
, COND_EXPR
, void_type_node
, cond
,
7958 build_call_expr_loc (first_loc
,
7959 builtin_decl_explicit (BUILT_IN_TRAP
),
7961 gimplify_and_add (tem
, pre_p
);
7962 c
= build_omp_clause (UNKNOWN_LOCATION
, OMP_CLAUSE_DEPEND
);
7963 OMP_CLAUSE_DEPEND_KIND (c
) = OMP_CLAUSE_DEPEND_LAST
;
7964 OMP_CLAUSE_DECL (c
) = build_fold_addr_expr (array
);
7965 OMP_CLAUSE_CHAIN (c
) = *list_p
;
7970 /* Scan the OMP clauses in *LIST_P, installing mappings into a new
7971 and previous omp contexts. */
7974 gimplify_scan_omp_clauses (tree
*list_p
, gimple_seq
*pre_p
,
7975 enum omp_region_type region_type
,
7976 enum tree_code code
)
7978 struct gimplify_omp_ctx
*ctx
, *outer_ctx
;
7980 hash_map
<tree
, tree
> *struct_map_to_clause
= NULL
;
7981 tree
*prev_list_p
= NULL
;
7982 int handled_depend_iterators
= -1;
7985 ctx
= new_omp_context (region_type
);
7986 outer_ctx
= ctx
->outer_context
;
7987 if (code
== OMP_TARGET
)
7989 if (!lang_GNU_Fortran ())
7990 ctx
->defaultmap
[GDMK_POINTER
] = GOVD_MAP
| GOVD_MAP_0LEN_ARRAY
;
7991 ctx
->defaultmap
[GDMK_SCALAR
] = GOVD_FIRSTPRIVATE
;
7993 if (!lang_GNU_Fortran ())
7997 case OMP_TARGET_DATA
:
7998 case OMP_TARGET_ENTER_DATA
:
7999 case OMP_TARGET_EXIT_DATA
:
8001 case OACC_HOST_DATA
:
8004 ctx
->target_firstprivatize_array_bases
= true;
8009 while ((c
= *list_p
) != NULL
)
8011 bool remove
= false;
8012 bool notice_outer
= true;
8013 const char *check_non_private
= NULL
;
8017 switch (OMP_CLAUSE_CODE (c
))
8019 case OMP_CLAUSE_PRIVATE
:
8020 flags
= GOVD_PRIVATE
| GOVD_EXPLICIT
;
8021 if (lang_hooks
.decls
.omp_private_outer_ref (OMP_CLAUSE_DECL (c
)))
8023 flags
|= GOVD_PRIVATE_OUTER_REF
;
8024 OMP_CLAUSE_PRIVATE_OUTER_REF (c
) = 1;
8027 notice_outer
= false;
8029 case OMP_CLAUSE_SHARED
:
8030 flags
= GOVD_SHARED
| GOVD_EXPLICIT
;
8032 case OMP_CLAUSE_FIRSTPRIVATE
:
8033 flags
= GOVD_FIRSTPRIVATE
| GOVD_EXPLICIT
;
8034 check_non_private
= "firstprivate";
8036 case OMP_CLAUSE_LASTPRIVATE
:
8037 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
))
8040 case OMP_DISTRIBUTE
:
8041 error_at (OMP_CLAUSE_LOCATION (c
),
8042 "conditional %<lastprivate%> clause on "
8043 "%<distribute%> construct");
8044 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
) = 0;
8047 error_at (OMP_CLAUSE_LOCATION (c
),
8048 "conditional %<lastprivate%> clause on "
8049 "%<taskloop%> construct");
8050 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
) = 0;
8055 flags
= GOVD_LASTPRIVATE
| GOVD_SEEN
| GOVD_EXPLICIT
;
8056 check_non_private
= "lastprivate";
8057 decl
= OMP_CLAUSE_DECL (c
);
8058 if (error_operand_p (decl
))
8060 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
)
8061 && !lang_hooks
.decls
.omp_scalar_p (decl
))
8063 error_at (OMP_CLAUSE_LOCATION (c
),
8064 "non-scalar variable %qD in conditional "
8065 "%<lastprivate%> clause", decl
);
8066 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
) = 0;
8069 && (outer_ctx
->region_type
== ORT_COMBINED_PARALLEL
8070 || ((outer_ctx
->region_type
& ORT_COMBINED_TEAMS
)
8071 == ORT_COMBINED_TEAMS
))
8072 && splay_tree_lookup (outer_ctx
->variables
,
8073 (splay_tree_key
) decl
) == NULL
)
8075 omp_add_variable (outer_ctx
, decl
, GOVD_SHARED
| GOVD_SEEN
);
8076 if (outer_ctx
->outer_context
)
8077 omp_notice_variable (outer_ctx
->outer_context
, decl
, true);
8080 && (outer_ctx
->region_type
& ORT_TASK
) != 0
8081 && outer_ctx
->combined_loop
8082 && splay_tree_lookup (outer_ctx
->variables
,
8083 (splay_tree_key
) decl
) == NULL
)
8085 omp_add_variable (outer_ctx
, decl
, GOVD_LASTPRIVATE
| GOVD_SEEN
);
8086 if (outer_ctx
->outer_context
)
8087 omp_notice_variable (outer_ctx
->outer_context
, decl
, true);
8090 && (outer_ctx
->region_type
== ORT_WORKSHARE
8091 || outer_ctx
->region_type
== ORT_ACC
)
8092 && outer_ctx
->combined_loop
8093 && splay_tree_lookup (outer_ctx
->variables
,
8094 (splay_tree_key
) decl
) == NULL
8095 && !omp_check_private (outer_ctx
, decl
, false))
8097 omp_add_variable (outer_ctx
, decl
, GOVD_LASTPRIVATE
| GOVD_SEEN
);
8098 if (outer_ctx
->outer_context
8099 && (outer_ctx
->outer_context
->region_type
8100 == ORT_COMBINED_PARALLEL
)
8101 && splay_tree_lookup (outer_ctx
->outer_context
->variables
,
8102 (splay_tree_key
) decl
) == NULL
)
8104 struct gimplify_omp_ctx
*octx
= outer_ctx
->outer_context
;
8105 omp_add_variable (octx
, decl
, GOVD_SHARED
| GOVD_SEEN
);
8106 if (octx
->outer_context
)
8108 octx
= octx
->outer_context
;
8109 if (octx
->region_type
== ORT_WORKSHARE
8110 && octx
->combined_loop
8111 && splay_tree_lookup (octx
->variables
,
8112 (splay_tree_key
) decl
) == NULL
8113 && !omp_check_private (octx
, decl
, false))
8115 omp_add_variable (octx
, decl
,
8116 GOVD_LASTPRIVATE
| GOVD_SEEN
);
8117 octx
= octx
->outer_context
;
8119 && ((octx
->region_type
& ORT_COMBINED_TEAMS
)
8120 == ORT_COMBINED_TEAMS
)
8121 && (splay_tree_lookup (octx
->variables
,
8122 (splay_tree_key
) decl
)
8125 omp_add_variable (octx
, decl
,
8126 GOVD_SHARED
| GOVD_SEEN
);
8127 octx
= octx
->outer_context
;
8131 omp_notice_variable (octx
, decl
, true);
8134 else if (outer_ctx
->outer_context
)
8135 omp_notice_variable (outer_ctx
->outer_context
, decl
, true);
8138 case OMP_CLAUSE_REDUCTION
:
8139 if (OMP_CLAUSE_REDUCTION_TASK (c
))
8141 if (region_type
== ORT_WORKSHARE
)
8144 nowait
= omp_find_clause (*list_p
,
8145 OMP_CLAUSE_NOWAIT
) != NULL_TREE
;
8147 && (outer_ctx
== NULL
8148 || outer_ctx
->region_type
!= ORT_COMBINED_PARALLEL
))
8150 error_at (OMP_CLAUSE_LOCATION (c
),
8151 "%<task%> reduction modifier on a construct "
8152 "with a %<nowait%> clause");
8153 OMP_CLAUSE_REDUCTION_TASK (c
) = 0;
8156 else if ((region_type
& ORT_PARALLEL
) != ORT_PARALLEL
)
8158 error_at (OMP_CLAUSE_LOCATION (c
),
8159 "invalid %<task%> reduction modifier on construct "
8160 "other than %<parallel%>, %<for%> or %<sections%>");
8161 OMP_CLAUSE_REDUCTION_TASK (c
) = 0;
8165 case OMP_CLAUSE_IN_REDUCTION
:
8166 case OMP_CLAUSE_TASK_REDUCTION
:
8167 flags
= GOVD_REDUCTION
| GOVD_SEEN
| GOVD_EXPLICIT
;
8168 /* OpenACC permits reductions on private variables. */
8169 if (!(region_type
& ORT_ACC
)
8170 /* taskgroup is actually not a worksharing region. */
8171 && code
!= OMP_TASKGROUP
)
8172 check_non_private
= omp_clause_code_name
[OMP_CLAUSE_CODE (c
)];
8173 decl
= OMP_CLAUSE_DECL (c
);
8174 if (TREE_CODE (decl
) == MEM_REF
)
8176 tree type
= TREE_TYPE (decl
);
8177 if (gimplify_expr (&TYPE_MAX_VALUE (TYPE_DOMAIN (type
)), pre_p
,
8178 NULL
, is_gimple_val
, fb_rvalue
, false)
8184 tree v
= TYPE_MAX_VALUE (TYPE_DOMAIN (type
));
8187 omp_firstprivatize_variable (ctx
, v
);
8188 omp_notice_variable (ctx
, v
, true);
8190 decl
= TREE_OPERAND (decl
, 0);
8191 if (TREE_CODE (decl
) == POINTER_PLUS_EXPR
)
8193 if (gimplify_expr (&TREE_OPERAND (decl
, 1), pre_p
,
8194 NULL
, is_gimple_val
, fb_rvalue
, false)
8200 v
= TREE_OPERAND (decl
, 1);
8203 omp_firstprivatize_variable (ctx
, v
);
8204 omp_notice_variable (ctx
, v
, true);
8206 decl
= TREE_OPERAND (decl
, 0);
8208 if (TREE_CODE (decl
) == ADDR_EXPR
8209 || TREE_CODE (decl
) == INDIRECT_REF
)
8210 decl
= TREE_OPERAND (decl
, 0);
8213 case OMP_CLAUSE_LINEAR
:
8214 if (gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c
), pre_p
, NULL
,
8215 is_gimple_val
, fb_rvalue
) == GS_ERROR
)
8222 if (code
== OMP_SIMD
8223 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c
))
8225 struct gimplify_omp_ctx
*octx
= outer_ctx
;
8227 && octx
->region_type
== ORT_WORKSHARE
8228 && octx
->combined_loop
8229 && !octx
->distribute
)
8231 if (octx
->outer_context
8232 && (octx
->outer_context
->region_type
8233 == ORT_COMBINED_PARALLEL
))
8234 octx
= octx
->outer_context
->outer_context
;
8236 octx
= octx
->outer_context
;
8239 && octx
->region_type
== ORT_WORKSHARE
8240 && octx
->combined_loop
8241 && octx
->distribute
)
8243 error_at (OMP_CLAUSE_LOCATION (c
),
8244 "%<linear%> clause for variable other than "
8245 "loop iterator specified on construct "
8246 "combined with %<distribute%>");
8251 /* For combined #pragma omp parallel for simd, need to put
8252 lastprivate and perhaps firstprivate too on the
8253 parallel. Similarly for #pragma omp for simd. */
8254 struct gimplify_omp_ctx
*octx
= outer_ctx
;
8258 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c
)
8259 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c
))
8261 decl
= OMP_CLAUSE_DECL (c
);
8262 if (error_operand_p (decl
))
8268 if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c
))
8269 flags
|= GOVD_FIRSTPRIVATE
;
8270 if (!OMP_CLAUSE_LINEAR_NO_COPYOUT (c
))
8271 flags
|= GOVD_LASTPRIVATE
;
8273 && octx
->region_type
== ORT_WORKSHARE
8274 && octx
->combined_loop
)
8276 if (octx
->outer_context
8277 && (octx
->outer_context
->region_type
8278 == ORT_COMBINED_PARALLEL
))
8279 octx
= octx
->outer_context
;
8280 else if (omp_check_private (octx
, decl
, false))
8284 && (octx
->region_type
& ORT_TASK
) != 0
8285 && octx
->combined_loop
)
8288 && octx
->region_type
== ORT_COMBINED_PARALLEL
8289 && ctx
->region_type
== ORT_WORKSHARE
8290 && octx
== outer_ctx
)
8291 flags
= GOVD_SEEN
| GOVD_SHARED
;
8293 && ((octx
->region_type
& ORT_COMBINED_TEAMS
)
8294 == ORT_COMBINED_TEAMS
))
8295 flags
= GOVD_SEEN
| GOVD_SHARED
;
8297 && octx
->region_type
== ORT_COMBINED_TARGET
)
8299 flags
&= ~GOVD_LASTPRIVATE
;
8300 if (flags
== GOVD_SEEN
)
8306 = splay_tree_lookup (octx
->variables
,
8307 (splay_tree_key
) decl
);
8308 if (on
&& (on
->value
& GOVD_DATA_SHARE_CLASS
) != 0)
8313 omp_add_variable (octx
, decl
, flags
);
8314 if (octx
->outer_context
== NULL
)
8316 octx
= octx
->outer_context
;
8321 && (!OMP_CLAUSE_LINEAR_NO_COPYIN (c
)
8322 || !OMP_CLAUSE_LINEAR_NO_COPYOUT (c
)))
8323 omp_notice_variable (octx
, decl
, true);
8325 flags
= GOVD_LINEAR
| GOVD_EXPLICIT
;
8326 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c
)
8327 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c
))
8329 notice_outer
= false;
8330 flags
|= GOVD_LINEAR_LASTPRIVATE_NO_OUTER
;
8334 case OMP_CLAUSE_MAP
:
8335 decl
= OMP_CLAUSE_DECL (c
);
8336 if (error_operand_p (decl
))
8343 if (TREE_CODE (TREE_TYPE (decl
)) != ARRAY_TYPE
)
8346 case OMP_TARGET_DATA
:
8347 case OMP_TARGET_ENTER_DATA
:
8348 case OMP_TARGET_EXIT_DATA
:
8349 case OACC_ENTER_DATA
:
8350 case OACC_EXIT_DATA
:
8351 case OACC_HOST_DATA
:
8352 if (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_FIRSTPRIVATE_POINTER
8353 || (OMP_CLAUSE_MAP_KIND (c
)
8354 == GOMP_MAP_FIRSTPRIVATE_REFERENCE
))
8355 /* For target {,enter ,exit }data only the array slice is
8356 mapped, but not the pointer to it. */
8364 if (DECL_P (decl
) && outer_ctx
&& (region_type
& ORT_ACC
))
8366 struct gimplify_omp_ctx
*octx
;
8367 for (octx
= outer_ctx
; octx
; octx
= octx
->outer_context
)
8369 if (octx
->region_type
!= ORT_ACC_HOST_DATA
)
8372 = splay_tree_lookup (octx
->variables
,
8373 (splay_tree_key
) decl
);
8375 error_at (OMP_CLAUSE_LOCATION (c
), "variable %qE "
8376 "declared in enclosing %<host_data%> region",
8380 if (OMP_CLAUSE_SIZE (c
) == NULL_TREE
)
8381 OMP_CLAUSE_SIZE (c
) = DECL_P (decl
) ? DECL_SIZE_UNIT (decl
)
8382 : TYPE_SIZE_UNIT (TREE_TYPE (decl
));
8383 if (gimplify_expr (&OMP_CLAUSE_SIZE (c
), pre_p
,
8384 NULL
, is_gimple_val
, fb_rvalue
) == GS_ERROR
)
8389 else if ((OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_FIRSTPRIVATE_POINTER
8390 || (OMP_CLAUSE_MAP_KIND (c
)
8391 == GOMP_MAP_FIRSTPRIVATE_REFERENCE
))
8392 && TREE_CODE (OMP_CLAUSE_SIZE (c
)) != INTEGER_CST
)
8395 = get_initialized_tmp_var (OMP_CLAUSE_SIZE (c
), pre_p
, NULL
,
8397 omp_add_variable (ctx
, OMP_CLAUSE_SIZE (c
),
8398 GOVD_FIRSTPRIVATE
| GOVD_SEEN
);
8403 if (TREE_CODE (d
) == ARRAY_REF
)
8405 while (TREE_CODE (d
) == ARRAY_REF
)
8406 d
= TREE_OPERAND (d
, 0);
8407 if (TREE_CODE (d
) == COMPONENT_REF
8408 && TREE_CODE (TREE_TYPE (d
)) == ARRAY_TYPE
)
8411 pd
= &OMP_CLAUSE_DECL (c
);
8413 && TREE_CODE (decl
) == INDIRECT_REF
8414 && TREE_CODE (TREE_OPERAND (decl
, 0)) == COMPONENT_REF
8415 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl
, 0)))
8418 pd
= &TREE_OPERAND (decl
, 0);
8419 decl
= TREE_OPERAND (decl
, 0);
8421 if (TREE_CODE (decl
) == COMPONENT_REF
)
8423 while (TREE_CODE (decl
) == COMPONENT_REF
)
8424 decl
= TREE_OPERAND (decl
, 0);
8425 if (TREE_CODE (decl
) == INDIRECT_REF
8426 && DECL_P (TREE_OPERAND (decl
, 0))
8427 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl
, 0)))
8429 decl
= TREE_OPERAND (decl
, 0);
8431 if (gimplify_expr (pd
, pre_p
, NULL
, is_gimple_lvalue
, fb_lvalue
)
8439 if (error_operand_p (decl
))
8445 tree stype
= TREE_TYPE (decl
);
8446 if (TREE_CODE (stype
) == REFERENCE_TYPE
)
8447 stype
= TREE_TYPE (stype
);
8448 if (TYPE_SIZE_UNIT (stype
) == NULL
8449 || TREE_CODE (TYPE_SIZE_UNIT (stype
)) != INTEGER_CST
)
8451 error_at (OMP_CLAUSE_LOCATION (c
),
8452 "mapping field %qE of variable length "
8453 "structure", OMP_CLAUSE_DECL (c
));
8458 if (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ALWAYS_POINTER
)
8460 /* Error recovery. */
8461 if (prev_list_p
== NULL
)
8466 if (OMP_CLAUSE_CHAIN (*prev_list_p
) != c
)
8468 tree ch
= OMP_CLAUSE_CHAIN (*prev_list_p
);
8469 if (ch
== NULL_TREE
|| OMP_CLAUSE_CHAIN (ch
) != c
)
8478 poly_int64 bitsize
, bitpos
;
8480 int unsignedp
, reversep
, volatilep
= 0;
8481 tree base
= OMP_CLAUSE_DECL (c
);
8482 while (TREE_CODE (base
) == ARRAY_REF
)
8483 base
= TREE_OPERAND (base
, 0);
8484 if (TREE_CODE (base
) == INDIRECT_REF
)
8485 base
= TREE_OPERAND (base
, 0);
8486 base
= get_inner_reference (base
, &bitsize
, &bitpos
, &offset
,
8487 &mode
, &unsignedp
, &reversep
,
8489 tree orig_base
= base
;
8490 if ((TREE_CODE (base
) == INDIRECT_REF
8491 || (TREE_CODE (base
) == MEM_REF
8492 && integer_zerop (TREE_OPERAND (base
, 1))))
8493 && DECL_P (TREE_OPERAND (base
, 0))
8494 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (base
, 0)))
8496 base
= TREE_OPERAND (base
, 0);
8497 gcc_assert (base
== decl
8498 && (offset
== NULL_TREE
8499 || poly_int_tree_p (offset
)));
8502 = splay_tree_lookup (ctx
->variables
, (splay_tree_key
)decl
);
8503 bool ptr
= (OMP_CLAUSE_MAP_KIND (c
)
8504 == GOMP_MAP_ALWAYS_POINTER
);
8505 if (n
== NULL
|| (n
->value
& GOVD_MAP
) == 0)
8507 tree l
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
8509 OMP_CLAUSE_SET_MAP_KIND (l
, GOMP_MAP_STRUCT
);
8510 if (orig_base
!= base
)
8511 OMP_CLAUSE_DECL (l
) = unshare_expr (orig_base
);
8513 OMP_CLAUSE_DECL (l
) = decl
;
8514 OMP_CLAUSE_SIZE (l
) = size_int (1);
8515 if (struct_map_to_clause
== NULL
)
8516 struct_map_to_clause
= new hash_map
<tree
, tree
>;
8517 struct_map_to_clause
->put (decl
, l
);
8520 enum gomp_map_kind mkind
8521 = code
== OMP_TARGET_EXIT_DATA
8522 ? GOMP_MAP_RELEASE
: GOMP_MAP_ALLOC
;
8523 tree c2
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
8525 OMP_CLAUSE_SET_MAP_KIND (c2
, mkind
);
8526 OMP_CLAUSE_DECL (c2
)
8527 = unshare_expr (OMP_CLAUSE_DECL (c
));
8528 OMP_CLAUSE_CHAIN (c2
) = *prev_list_p
;
8529 OMP_CLAUSE_SIZE (c2
)
8530 = TYPE_SIZE_UNIT (ptr_type_node
);
8531 OMP_CLAUSE_CHAIN (l
) = c2
;
8532 if (OMP_CLAUSE_CHAIN (*prev_list_p
) != c
)
8534 tree c4
= OMP_CLAUSE_CHAIN (*prev_list_p
);
8536 = build_omp_clause (OMP_CLAUSE_LOCATION (c
),
8538 OMP_CLAUSE_SET_MAP_KIND (c3
, mkind
);
8539 OMP_CLAUSE_DECL (c3
)
8540 = unshare_expr (OMP_CLAUSE_DECL (c4
));
8541 OMP_CLAUSE_SIZE (c3
)
8542 = TYPE_SIZE_UNIT (ptr_type_node
);
8543 OMP_CLAUSE_CHAIN (c3
) = *prev_list_p
;
8544 OMP_CLAUSE_CHAIN (c2
) = c3
;
8551 OMP_CLAUSE_CHAIN (l
) = c
;
8553 list_p
= &OMP_CLAUSE_CHAIN (l
);
8555 if (orig_base
!= base
&& code
== OMP_TARGET
)
8557 tree c2
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
8559 enum gomp_map_kind mkind
8560 = GOMP_MAP_FIRSTPRIVATE_REFERENCE
;
8561 OMP_CLAUSE_SET_MAP_KIND (c2
, mkind
);
8562 OMP_CLAUSE_DECL (c2
) = decl
;
8563 OMP_CLAUSE_SIZE (c2
) = size_zero_node
;
8564 OMP_CLAUSE_CHAIN (c2
) = OMP_CLAUSE_CHAIN (l
);
8565 OMP_CLAUSE_CHAIN (l
) = c2
;
8567 flags
= GOVD_MAP
| GOVD_EXPLICIT
;
8568 if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c
)) || ptr
)
8574 tree
*osc
= struct_map_to_clause
->get (decl
);
8575 tree
*sc
= NULL
, *scp
= NULL
;
8576 if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c
)) || ptr
)
8577 n
->value
|= GOVD_SEEN
;
8578 poly_offset_int o1
, o2
;
8580 o1
= wi::to_poly_offset (offset
);
8583 if (maybe_ne (bitpos
, 0))
8584 o1
+= bits_to_bytes_round_down (bitpos
);
8585 sc
= &OMP_CLAUSE_CHAIN (*osc
);
8587 && (OMP_CLAUSE_MAP_KIND (*sc
)
8588 == GOMP_MAP_FIRSTPRIVATE_REFERENCE
))
8589 sc
= &OMP_CLAUSE_CHAIN (*sc
);
8590 for (; *sc
!= c
; sc
= &OMP_CLAUSE_CHAIN (*sc
))
8591 if (ptr
&& sc
== prev_list_p
)
8593 else if (TREE_CODE (OMP_CLAUSE_DECL (*sc
))
8595 && (TREE_CODE (OMP_CLAUSE_DECL (*sc
))
8597 && (TREE_CODE (OMP_CLAUSE_DECL (*sc
))
8603 poly_int64 bitsize2
, bitpos2
;
8604 base
= OMP_CLAUSE_DECL (*sc
);
8605 if (TREE_CODE (base
) == ARRAY_REF
)
8607 while (TREE_CODE (base
) == ARRAY_REF
)
8608 base
= TREE_OPERAND (base
, 0);
8609 if (TREE_CODE (base
) != COMPONENT_REF
8610 || (TREE_CODE (TREE_TYPE (base
))
8614 else if (TREE_CODE (base
) == INDIRECT_REF
8615 && (TREE_CODE (TREE_OPERAND (base
, 0))
8617 && (TREE_CODE (TREE_TYPE
8618 (TREE_OPERAND (base
, 0)))
8620 base
= TREE_OPERAND (base
, 0);
8621 base
= get_inner_reference (base
, &bitsize2
,
8624 &reversep
, &volatilep
);
8625 if ((TREE_CODE (base
) == INDIRECT_REF
8626 || (TREE_CODE (base
) == MEM_REF
8627 && integer_zerop (TREE_OPERAND (base
,
8629 && DECL_P (TREE_OPERAND (base
, 0))
8630 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (base
,
8633 base
= TREE_OPERAND (base
, 0);
8638 gcc_assert (offset
== NULL_TREE
8639 || poly_int_tree_p (offset
));
8640 tree d1
= OMP_CLAUSE_DECL (*sc
);
8641 tree d2
= OMP_CLAUSE_DECL (c
);
8642 while (TREE_CODE (d1
) == ARRAY_REF
)
8643 d1
= TREE_OPERAND (d1
, 0);
8644 while (TREE_CODE (d2
) == ARRAY_REF
)
8645 d2
= TREE_OPERAND (d2
, 0);
8646 if (TREE_CODE (d1
) == INDIRECT_REF
)
8647 d1
= TREE_OPERAND (d1
, 0);
8648 if (TREE_CODE (d2
) == INDIRECT_REF
)
8649 d2
= TREE_OPERAND (d2
, 0);
8650 while (TREE_CODE (d1
) == COMPONENT_REF
)
8651 if (TREE_CODE (d2
) == COMPONENT_REF
8652 && TREE_OPERAND (d1
, 1)
8653 == TREE_OPERAND (d2
, 1))
8655 d1
= TREE_OPERAND (d1
, 0);
8656 d2
= TREE_OPERAND (d2
, 0);
8662 error_at (OMP_CLAUSE_LOCATION (c
),
8663 "%qE appears more than once in map "
8664 "clauses", OMP_CLAUSE_DECL (c
));
8669 o2
= wi::to_poly_offset (offset2
);
8672 o2
+= bits_to_bytes_round_down (bitpos2
);
8673 if (maybe_lt (o1
, o2
)
8674 || (known_eq (o1
, 2)
8675 && maybe_lt (bitpos
, bitpos2
)))
8685 OMP_CLAUSE_SIZE (*osc
)
8686 = size_binop (PLUS_EXPR
, OMP_CLAUSE_SIZE (*osc
),
8690 tree c2
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
8692 tree cl
= NULL_TREE
;
8693 enum gomp_map_kind mkind
8694 = code
== OMP_TARGET_EXIT_DATA
8695 ? GOMP_MAP_RELEASE
: GOMP_MAP_ALLOC
;
8696 OMP_CLAUSE_SET_MAP_KIND (c2
, mkind
);
8697 OMP_CLAUSE_DECL (c2
)
8698 = unshare_expr (OMP_CLAUSE_DECL (c
));
8699 OMP_CLAUSE_CHAIN (c2
) = scp
? *scp
: *prev_list_p
;
8700 OMP_CLAUSE_SIZE (c2
)
8701 = TYPE_SIZE_UNIT (ptr_type_node
);
8702 cl
= scp
? *prev_list_p
: c2
;
8703 if (OMP_CLAUSE_CHAIN (*prev_list_p
) != c
)
8705 tree c4
= OMP_CLAUSE_CHAIN (*prev_list_p
);
8707 = build_omp_clause (OMP_CLAUSE_LOCATION (c
),
8709 OMP_CLAUSE_SET_MAP_KIND (c3
, mkind
);
8710 OMP_CLAUSE_DECL (c3
)
8711 = unshare_expr (OMP_CLAUSE_DECL (c4
));
8712 OMP_CLAUSE_SIZE (c3
)
8713 = TYPE_SIZE_UNIT (ptr_type_node
);
8714 OMP_CLAUSE_CHAIN (c3
) = *prev_list_p
;
8716 OMP_CLAUSE_CHAIN (c2
) = c3
;
8722 if (sc
== prev_list_p
)
8729 *prev_list_p
= OMP_CLAUSE_CHAIN (c
);
8730 list_p
= prev_list_p
;
8732 OMP_CLAUSE_CHAIN (c
) = *sc
;
8739 *list_p
= OMP_CLAUSE_CHAIN (c
);
8740 OMP_CLAUSE_CHAIN (c
) = *sc
;
8747 && OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_ALWAYS_POINTER
8748 && OMP_CLAUSE_CHAIN (c
)
8749 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (c
)) == OMP_CLAUSE_MAP
8750 && (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c
))
8751 == GOMP_MAP_ALWAYS_POINTER
))
8752 prev_list_p
= list_p
;
8755 flags
= GOVD_MAP
| GOVD_EXPLICIT
;
8756 if (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ALWAYS_TO
8757 || OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ALWAYS_TOFROM
)
8758 flags
|= GOVD_MAP_ALWAYS_TO
;
8761 case OMP_CLAUSE_DEPEND
:
8762 if (OMP_CLAUSE_DEPEND_KIND (c
) == OMP_CLAUSE_DEPEND_SINK
)
8764 tree deps
= OMP_CLAUSE_DECL (c
);
8765 while (deps
&& TREE_CODE (deps
) == TREE_LIST
)
8767 if (TREE_CODE (TREE_PURPOSE (deps
)) == TRUNC_DIV_EXPR
8768 && DECL_P (TREE_OPERAND (TREE_PURPOSE (deps
), 1)))
8769 gimplify_expr (&TREE_OPERAND (TREE_PURPOSE (deps
), 1),
8770 pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
8771 deps
= TREE_CHAIN (deps
);
8775 else if (OMP_CLAUSE_DEPEND_KIND (c
) == OMP_CLAUSE_DEPEND_SOURCE
)
8777 if (handled_depend_iterators
== -1)
8778 handled_depend_iterators
= gimplify_omp_depend (list_p
, pre_p
);
8779 if (handled_depend_iterators
)
8781 if (handled_depend_iterators
== 2)
8785 if (TREE_CODE (OMP_CLAUSE_DECL (c
)) == COMPOUND_EXPR
)
8787 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c
), 0), pre_p
,
8788 NULL
, is_gimple_val
, fb_rvalue
);
8789 OMP_CLAUSE_DECL (c
) = TREE_OPERAND (OMP_CLAUSE_DECL (c
), 1);
8791 if (error_operand_p (OMP_CLAUSE_DECL (c
)))
8796 OMP_CLAUSE_DECL (c
) = build_fold_addr_expr (OMP_CLAUSE_DECL (c
));
8797 if (gimplify_expr (&OMP_CLAUSE_DECL (c
), pre_p
, NULL
,
8798 is_gimple_val
, fb_rvalue
) == GS_ERROR
)
8806 case OMP_CLAUSE_FROM
:
8807 case OMP_CLAUSE__CACHE_
:
8808 decl
= OMP_CLAUSE_DECL (c
);
8809 if (error_operand_p (decl
))
8814 if (OMP_CLAUSE_SIZE (c
) == NULL_TREE
)
8815 OMP_CLAUSE_SIZE (c
) = DECL_P (decl
) ? DECL_SIZE_UNIT (decl
)
8816 : TYPE_SIZE_UNIT (TREE_TYPE (decl
));
8817 if (gimplify_expr (&OMP_CLAUSE_SIZE (c
), pre_p
,
8818 NULL
, is_gimple_val
, fb_rvalue
) == GS_ERROR
)
8825 if (gimplify_expr (&OMP_CLAUSE_DECL (c
), pre_p
,
8826 NULL
, is_gimple_lvalue
, fb_lvalue
)
8836 case OMP_CLAUSE_USE_DEVICE_PTR
:
8837 flags
= GOVD_FIRSTPRIVATE
| GOVD_EXPLICIT
;
8839 case OMP_CLAUSE_IS_DEVICE_PTR
:
8840 flags
= GOVD_FIRSTPRIVATE
| GOVD_EXPLICIT
;
8844 decl
= OMP_CLAUSE_DECL (c
);
8846 if (error_operand_p (decl
))
8851 if (DECL_NAME (decl
) == NULL_TREE
&& (flags
& GOVD_SHARED
) == 0)
8853 tree t
= omp_member_access_dummy_var (decl
);
8856 tree v
= DECL_VALUE_EXPR (decl
);
8857 DECL_NAME (decl
) = DECL_NAME (TREE_OPERAND (v
, 1));
8859 omp_notice_variable (outer_ctx
, t
, true);
8862 if (code
== OACC_DATA
8863 && OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_MAP
8864 && OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_FIRSTPRIVATE_POINTER
)
8865 flags
|= GOVD_MAP_0LEN_ARRAY
;
8866 omp_add_variable (ctx
, decl
, flags
);
8867 if ((OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
8868 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_IN_REDUCTION
8869 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_TASK_REDUCTION
)
8870 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
))
8872 omp_add_variable (ctx
, OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
),
8873 GOVD_LOCAL
| GOVD_SEEN
);
8874 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c
)
8875 && walk_tree (&OMP_CLAUSE_REDUCTION_INIT (c
),
8877 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c
),
8879 omp_add_variable (ctx
,
8880 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c
),
8881 GOVD_LOCAL
| GOVD_SEEN
);
8882 gimplify_omp_ctxp
= ctx
;
8883 push_gimplify_context ();
8885 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c
) = NULL
;
8886 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c
) = NULL
;
8888 gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c
),
8889 &OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c
));
8890 pop_gimplify_context
8891 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c
)));
8892 push_gimplify_context ();
8893 gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c
),
8894 &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c
));
8895 pop_gimplify_context
8896 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c
)));
8897 OMP_CLAUSE_REDUCTION_INIT (c
) = NULL_TREE
;
8898 OMP_CLAUSE_REDUCTION_MERGE (c
) = NULL_TREE
;
8900 gimplify_omp_ctxp
= outer_ctx
;
8902 else if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
8903 && OMP_CLAUSE_LASTPRIVATE_STMT (c
))
8905 gimplify_omp_ctxp
= ctx
;
8906 push_gimplify_context ();
8907 if (TREE_CODE (OMP_CLAUSE_LASTPRIVATE_STMT (c
)) != BIND_EXPR
)
8909 tree bind
= build3 (BIND_EXPR
, void_type_node
, NULL
,
8911 TREE_SIDE_EFFECTS (bind
) = 1;
8912 BIND_EXPR_BODY (bind
) = OMP_CLAUSE_LASTPRIVATE_STMT (c
);
8913 OMP_CLAUSE_LASTPRIVATE_STMT (c
) = bind
;
8915 gimplify_and_add (OMP_CLAUSE_LASTPRIVATE_STMT (c
),
8916 &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
));
8917 pop_gimplify_context
8918 (gimple_seq_first_stmt (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
)));
8919 OMP_CLAUSE_LASTPRIVATE_STMT (c
) = NULL_TREE
;
8921 gimplify_omp_ctxp
= outer_ctx
;
8923 else if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINEAR
8924 && OMP_CLAUSE_LINEAR_STMT (c
))
8926 gimplify_omp_ctxp
= ctx
;
8927 push_gimplify_context ();
8928 if (TREE_CODE (OMP_CLAUSE_LINEAR_STMT (c
)) != BIND_EXPR
)
8930 tree bind
= build3 (BIND_EXPR
, void_type_node
, NULL
,
8932 TREE_SIDE_EFFECTS (bind
) = 1;
8933 BIND_EXPR_BODY (bind
) = OMP_CLAUSE_LINEAR_STMT (c
);
8934 OMP_CLAUSE_LINEAR_STMT (c
) = bind
;
8936 gimplify_and_add (OMP_CLAUSE_LINEAR_STMT (c
),
8937 &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c
));
8938 pop_gimplify_context
8939 (gimple_seq_first_stmt (OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c
)));
8940 OMP_CLAUSE_LINEAR_STMT (c
) = NULL_TREE
;
8942 gimplify_omp_ctxp
= outer_ctx
;
8948 case OMP_CLAUSE_COPYIN
:
8949 case OMP_CLAUSE_COPYPRIVATE
:
8950 decl
= OMP_CLAUSE_DECL (c
);
8951 if (error_operand_p (decl
))
8956 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_COPYPRIVATE
8958 && !omp_check_private (ctx
, decl
, true))
8961 if (is_global_var (decl
))
8963 if (DECL_THREAD_LOCAL_P (decl
))
8965 else if (DECL_HAS_VALUE_EXPR_P (decl
))
8967 tree value
= get_base_address (DECL_VALUE_EXPR (decl
));
8971 && DECL_THREAD_LOCAL_P (value
))
8976 error_at (OMP_CLAUSE_LOCATION (c
),
8977 "copyprivate variable %qE is not threadprivate"
8978 " or private in outer context", DECL_NAME (decl
));
8981 if ((region_type
& ORT_TASKLOOP
) == ORT_TASKLOOP
8983 && outer_ctx
->region_type
== ORT_COMBINED_PARALLEL
8984 && (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
8985 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_FIRSTPRIVATE
8986 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
))
8989 = splay_tree_lookup (outer_ctx
->variables
,
8990 (splay_tree_key
)decl
);
8991 if (on
== NULL
|| (on
->value
& GOVD_DATA_SHARE_CLASS
) == 0)
8993 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
8994 && TREE_CODE (OMP_CLAUSE_DECL (c
)) == MEM_REF
8995 && (TREE_CODE (TREE_TYPE (decl
)) == POINTER_TYPE
8996 || (TREE_CODE (TREE_TYPE (decl
)) == REFERENCE_TYPE
8997 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl
)))
8999 omp_firstprivatize_variable (outer_ctx
, decl
);
9001 omp_add_variable (outer_ctx
, decl
,
9002 GOVD_SEEN
| GOVD_SHARED
);
9003 omp_notice_variable (outer_ctx
, decl
, true);
9007 omp_notice_variable (outer_ctx
, decl
, true);
9008 if (check_non_private
9009 && region_type
== ORT_WORKSHARE
9010 && (OMP_CLAUSE_CODE (c
) != OMP_CLAUSE_REDUCTION
9011 || decl
== OMP_CLAUSE_DECL (c
)
9012 || (TREE_CODE (OMP_CLAUSE_DECL (c
)) == MEM_REF
9013 && (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c
), 0))
9015 || (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c
), 0))
9016 == POINTER_PLUS_EXPR
9017 && (TREE_CODE (TREE_OPERAND (TREE_OPERAND
9018 (OMP_CLAUSE_DECL (c
), 0), 0))
9020 && omp_check_private (ctx
, decl
, false))
9022 error ("%s variable %qE is private in outer context",
9023 check_non_private
, DECL_NAME (decl
));
9029 if (OMP_CLAUSE_IF_MODIFIER (c
) != ERROR_MARK
9030 && OMP_CLAUSE_IF_MODIFIER (c
) != code
)
9033 for (int i
= 0; i
< 2; i
++)
9034 switch (i
? OMP_CLAUSE_IF_MODIFIER (c
) : code
)
9036 case VOID_CST
: p
[i
] = "cancel"; break;
9037 case OMP_PARALLEL
: p
[i
] = "parallel"; break;
9038 case OMP_SIMD
: p
[i
] = "simd"; break;
9039 case OMP_TASK
: p
[i
] = "task"; break;
9040 case OMP_TASKLOOP
: p
[i
] = "taskloop"; break;
9041 case OMP_TARGET_DATA
: p
[i
] = "target data"; break;
9042 case OMP_TARGET
: p
[i
] = "target"; break;
9043 case OMP_TARGET_UPDATE
: p
[i
] = "target update"; break;
9044 case OMP_TARGET_ENTER_DATA
:
9045 p
[i
] = "target enter data"; break;
9046 case OMP_TARGET_EXIT_DATA
: p
[i
] = "target exit data"; break;
9047 default: gcc_unreachable ();
9049 error_at (OMP_CLAUSE_LOCATION (c
),
9050 "expected %qs %<if%> clause modifier rather than %qs",
9056 case OMP_CLAUSE_FINAL
:
9057 OMP_CLAUSE_OPERAND (c
, 0)
9058 = gimple_boolify (OMP_CLAUSE_OPERAND (c
, 0));
9061 case OMP_CLAUSE_SCHEDULE
:
9062 case OMP_CLAUSE_NUM_THREADS
:
9063 case OMP_CLAUSE_NUM_TEAMS
:
9064 case OMP_CLAUSE_THREAD_LIMIT
:
9065 case OMP_CLAUSE_DIST_SCHEDULE
:
9066 case OMP_CLAUSE_DEVICE
:
9067 case OMP_CLAUSE_PRIORITY
:
9068 case OMP_CLAUSE_GRAINSIZE
:
9069 case OMP_CLAUSE_NUM_TASKS
:
9070 case OMP_CLAUSE_HINT
:
9071 case OMP_CLAUSE_ASYNC
:
9072 case OMP_CLAUSE_WAIT
:
9073 case OMP_CLAUSE_NUM_GANGS
:
9074 case OMP_CLAUSE_NUM_WORKERS
:
9075 case OMP_CLAUSE_VECTOR_LENGTH
:
9076 case OMP_CLAUSE_WORKER
:
9077 case OMP_CLAUSE_VECTOR
:
9078 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c
, 0), pre_p
, NULL
,
9079 is_gimple_val
, fb_rvalue
) == GS_ERROR
)
9083 case OMP_CLAUSE_GANG
:
9084 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c
, 0), pre_p
, NULL
,
9085 is_gimple_val
, fb_rvalue
) == GS_ERROR
)
9087 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c
, 1), pre_p
, NULL
,
9088 is_gimple_val
, fb_rvalue
) == GS_ERROR
)
9092 case OMP_CLAUSE_NOWAIT
:
9096 case OMP_CLAUSE_ORDERED
:
9097 case OMP_CLAUSE_UNTIED
:
9098 case OMP_CLAUSE_COLLAPSE
:
9099 case OMP_CLAUSE_TILE
:
9100 case OMP_CLAUSE_AUTO
:
9101 case OMP_CLAUSE_SEQ
:
9102 case OMP_CLAUSE_INDEPENDENT
:
9103 case OMP_CLAUSE_MERGEABLE
:
9104 case OMP_CLAUSE_PROC_BIND
:
9105 case OMP_CLAUSE_SAFELEN
:
9106 case OMP_CLAUSE_SIMDLEN
:
9107 case OMP_CLAUSE_NOGROUP
:
9108 case OMP_CLAUSE_THREADS
:
9109 case OMP_CLAUSE_SIMD
:
9110 case OMP_CLAUSE_IF_PRESENT
:
9111 case OMP_CLAUSE_FINALIZE
:
9114 case OMP_CLAUSE_DEFAULTMAP
:
9115 enum gimplify_defaultmap_kind gdmkmin
, gdmkmax
;
9116 switch (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c
))
9118 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
:
9119 gdmkmin
= GDMK_SCALAR
;
9120 gdmkmax
= GDMK_POINTER
;
9122 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR
:
9123 gdmkmin
= gdmkmax
= GDMK_SCALAR
;
9125 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE
:
9126 gdmkmin
= gdmkmax
= GDMK_AGGREGATE
;
9128 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALLOCATABLE
:
9129 gdmkmin
= gdmkmax
= GDMK_ALLOCATABLE
;
9131 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER
:
9132 gdmkmin
= gdmkmax
= GDMK_POINTER
;
9137 for (int gdmk
= gdmkmin
; gdmk
<= gdmkmax
; gdmk
++)
9138 switch (OMP_CLAUSE_DEFAULTMAP_BEHAVIOR (c
))
9140 case OMP_CLAUSE_DEFAULTMAP_ALLOC
:
9141 ctx
->defaultmap
[gdmk
] = GOVD_MAP
| GOVD_MAP_ALLOC_ONLY
;
9143 case OMP_CLAUSE_DEFAULTMAP_TO
:
9144 ctx
->defaultmap
[gdmk
] = GOVD_MAP
| GOVD_MAP_TO_ONLY
;
9146 case OMP_CLAUSE_DEFAULTMAP_FROM
:
9147 ctx
->defaultmap
[gdmk
] = GOVD_MAP
| GOVD_MAP_FROM_ONLY
;
9149 case OMP_CLAUSE_DEFAULTMAP_TOFROM
:
9150 ctx
->defaultmap
[gdmk
] = GOVD_MAP
;
9152 case OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE
:
9153 ctx
->defaultmap
[gdmk
] = GOVD_FIRSTPRIVATE
;
9155 case OMP_CLAUSE_DEFAULTMAP_NONE
:
9156 ctx
->defaultmap
[gdmk
] = 0;
9158 case OMP_CLAUSE_DEFAULTMAP_DEFAULT
:
9162 ctx
->defaultmap
[gdmk
] = GOVD_FIRSTPRIVATE
;
9164 case GDMK_AGGREGATE
:
9165 case GDMK_ALLOCATABLE
:
9166 ctx
->defaultmap
[gdmk
] = GOVD_MAP
;
9169 ctx
->defaultmap
[gdmk
] = GOVD_MAP
| GOVD_MAP_0LEN_ARRAY
;
9180 case OMP_CLAUSE_ALIGNED
:
9181 decl
= OMP_CLAUSE_DECL (c
);
9182 if (error_operand_p (decl
))
9187 if (gimplify_expr (&OMP_CLAUSE_ALIGNED_ALIGNMENT (c
), pre_p
, NULL
,
9188 is_gimple_val
, fb_rvalue
) == GS_ERROR
)
9193 if (!is_global_var (decl
)
9194 && TREE_CODE (TREE_TYPE (decl
)) == POINTER_TYPE
)
9195 omp_add_variable (ctx
, decl
, GOVD_ALIGNED
);
9198 case OMP_CLAUSE_NONTEMPORAL
:
9199 decl
= OMP_CLAUSE_DECL (c
);
9200 if (error_operand_p (decl
))
9205 omp_add_variable (ctx
, decl
, GOVD_NONTEMPORAL
);
9208 case OMP_CLAUSE_DEFAULT
:
9209 ctx
->default_kind
= OMP_CLAUSE_DEFAULT_KIND (c
);
9216 if (code
== OACC_DATA
9217 && OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_MAP
9218 && (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_FIRSTPRIVATE_POINTER
9219 || OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
))
9222 *list_p
= OMP_CLAUSE_CHAIN (c
);
9224 list_p
= &OMP_CLAUSE_CHAIN (c
);
9227 gimplify_omp_ctxp
= ctx
;
9228 if (struct_map_to_clause
)
9229 delete struct_map_to_clause
;
9232 /* Return true if DECL is a candidate for shared to firstprivate
9233 optimization. We only consider non-addressable scalars, not
9234 too big, and not references. */
9237 omp_shared_to_firstprivate_optimizable_decl_p (tree decl
)
9239 if (TREE_ADDRESSABLE (decl
))
9241 tree type
= TREE_TYPE (decl
);
9242 if (!is_gimple_reg_type (type
)
9243 || TREE_CODE (type
) == REFERENCE_TYPE
9244 || TREE_ADDRESSABLE (type
))
9246 /* Don't optimize too large decls, as each thread/task will have
9248 HOST_WIDE_INT len
= int_size_in_bytes (type
);
9249 if (len
== -1 || len
> 4 * POINTER_SIZE
/ BITS_PER_UNIT
)
9251 if (lang_hooks
.decls
.omp_privatize_by_reference (decl
))
9256 /* Helper function of omp_find_stores_op and gimplify_adjust_omp_clauses*.
9257 For omp_shared_to_firstprivate_optimizable_decl_p decl mark it as
9258 GOVD_WRITTEN in outer contexts. */
9261 omp_mark_stores (struct gimplify_omp_ctx
*ctx
, tree decl
)
9263 for (; ctx
; ctx
= ctx
->outer_context
)
9265 splay_tree_node n
= splay_tree_lookup (ctx
->variables
,
9266 (splay_tree_key
) decl
);
9269 else if (n
->value
& GOVD_SHARED
)
9271 n
->value
|= GOVD_WRITTEN
;
9274 else if (n
->value
& GOVD_DATA_SHARE_CLASS
)
9279 /* Helper callback for walk_gimple_seq to discover possible stores
9280 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
9281 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
9285 omp_find_stores_op (tree
*tp
, int *walk_subtrees
, void *data
)
9287 struct walk_stmt_info
*wi
= (struct walk_stmt_info
*) data
;
9296 if (handled_component_p (op
))
9297 op
= TREE_OPERAND (op
, 0);
9298 else if ((TREE_CODE (op
) == MEM_REF
|| TREE_CODE (op
) == TARGET_MEM_REF
)
9299 && TREE_CODE (TREE_OPERAND (op
, 0)) == ADDR_EXPR
)
9300 op
= TREE_OPERAND (TREE_OPERAND (op
, 0), 0);
9305 if (!DECL_P (op
) || !omp_shared_to_firstprivate_optimizable_decl_p (op
))
9308 omp_mark_stores (gimplify_omp_ctxp
, op
);
9312 /* Helper callback for walk_gimple_seq to discover possible stores
9313 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
9314 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
9318 omp_find_stores_stmt (gimple_stmt_iterator
*gsi_p
,
9319 bool *handled_ops_p
,
9320 struct walk_stmt_info
*wi
)
9322 gimple
*stmt
= gsi_stmt (*gsi_p
);
9323 switch (gimple_code (stmt
))
9325 /* Don't recurse on OpenMP constructs for which
9326 gimplify_adjust_omp_clauses already handled the bodies,
9327 except handle gimple_omp_for_pre_body. */
9328 case GIMPLE_OMP_FOR
:
9329 *handled_ops_p
= true;
9330 if (gimple_omp_for_pre_body (stmt
))
9331 walk_gimple_seq (gimple_omp_for_pre_body (stmt
),
9332 omp_find_stores_stmt
, omp_find_stores_op
, wi
);
9334 case GIMPLE_OMP_PARALLEL
:
9335 case GIMPLE_OMP_TASK
:
9336 case GIMPLE_OMP_SECTIONS
:
9337 case GIMPLE_OMP_SINGLE
:
9338 case GIMPLE_OMP_TARGET
:
9339 case GIMPLE_OMP_TEAMS
:
9340 case GIMPLE_OMP_CRITICAL
:
9341 *handled_ops_p
= true;
9349 struct gimplify_adjust_omp_clauses_data
9355 /* For all variables that were not actually used within the context,
9356 remove PRIVATE, SHARED, and FIRSTPRIVATE clauses. */
9359 gimplify_adjust_omp_clauses_1 (splay_tree_node n
, void *data
)
9361 tree
*list_p
= ((struct gimplify_adjust_omp_clauses_data
*) data
)->list_p
;
9363 = ((struct gimplify_adjust_omp_clauses_data
*) data
)->pre_p
;
9364 tree decl
= (tree
) n
->key
;
9365 unsigned flags
= n
->value
;
9366 enum omp_clause_code code
;
9370 if (flags
& (GOVD_EXPLICIT
| GOVD_LOCAL
))
9372 if ((flags
& GOVD_SEEN
) == 0)
9374 if (flags
& GOVD_DEBUG_PRIVATE
)
9376 gcc_assert ((flags
& GOVD_DATA_SHARE_CLASS
) == GOVD_SHARED
);
9377 private_debug
= true;
9379 else if (flags
& GOVD_MAP
)
9380 private_debug
= false;
9383 = lang_hooks
.decls
.omp_private_debug_clause (decl
,
9384 !!(flags
& GOVD_SHARED
));
9386 code
= OMP_CLAUSE_PRIVATE
;
9387 else if (flags
& GOVD_MAP
)
9389 code
= OMP_CLAUSE_MAP
;
9390 if ((gimplify_omp_ctxp
->region_type
& ORT_ACC
) == 0
9391 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl
))))
9393 error ("%<_Atomic%> %qD in implicit %<map%> clause", decl
);
9397 else if (flags
& GOVD_SHARED
)
9399 if (is_global_var (decl
))
9401 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
->outer_context
;
9405 = splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
9406 if (on
&& (on
->value
& (GOVD_FIRSTPRIVATE
| GOVD_LASTPRIVATE
9407 | GOVD_PRIVATE
| GOVD_REDUCTION
9408 | GOVD_LINEAR
| GOVD_MAP
)) != 0)
9410 ctx
= ctx
->outer_context
;
9415 code
= OMP_CLAUSE_SHARED
;
9417 else if (flags
& GOVD_PRIVATE
)
9418 code
= OMP_CLAUSE_PRIVATE
;
9419 else if (flags
& GOVD_FIRSTPRIVATE
)
9421 code
= OMP_CLAUSE_FIRSTPRIVATE
;
9422 if ((gimplify_omp_ctxp
->region_type
& ORT_TARGET
)
9423 && (gimplify_omp_ctxp
->region_type
& ORT_ACC
) == 0
9424 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl
))))
9426 error ("%<_Atomic%> %qD in implicit %<firstprivate%> clause on "
9427 "%<target%> construct", decl
);
9431 else if (flags
& GOVD_LASTPRIVATE
)
9432 code
= OMP_CLAUSE_LASTPRIVATE
;
9433 else if (flags
& (GOVD_ALIGNED
| GOVD_NONTEMPORAL
))
9438 if (((flags
& GOVD_LASTPRIVATE
)
9439 || (code
== OMP_CLAUSE_SHARED
&& (flags
& GOVD_WRITTEN
)))
9440 && omp_shared_to_firstprivate_optimizable_decl_p (decl
))
9441 omp_mark_stores (gimplify_omp_ctxp
->outer_context
, decl
);
9443 tree chain
= *list_p
;
9444 clause
= build_omp_clause (input_location
, code
);
9445 OMP_CLAUSE_DECL (clause
) = decl
;
9446 OMP_CLAUSE_CHAIN (clause
) = chain
;
9448 OMP_CLAUSE_PRIVATE_DEBUG (clause
) = 1;
9449 else if (code
== OMP_CLAUSE_PRIVATE
&& (flags
& GOVD_PRIVATE_OUTER_REF
))
9450 OMP_CLAUSE_PRIVATE_OUTER_REF (clause
) = 1;
9451 else if (code
== OMP_CLAUSE_SHARED
9452 && (flags
& GOVD_WRITTEN
) == 0
9453 && omp_shared_to_firstprivate_optimizable_decl_p (decl
))
9454 OMP_CLAUSE_SHARED_READONLY (clause
) = 1;
9455 else if (code
== OMP_CLAUSE_FIRSTPRIVATE
&& (flags
& GOVD_EXPLICIT
) == 0)
9456 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (clause
) = 1;
9457 else if (code
== OMP_CLAUSE_MAP
&& (flags
& GOVD_MAP_0LEN_ARRAY
) != 0)
9459 tree nc
= build_omp_clause (input_location
, OMP_CLAUSE_MAP
);
9460 OMP_CLAUSE_DECL (nc
) = decl
;
9461 if (TREE_CODE (TREE_TYPE (decl
)) == REFERENCE_TYPE
9462 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl
))) == POINTER_TYPE
)
9463 OMP_CLAUSE_DECL (clause
)
9464 = build_simple_mem_ref_loc (input_location
, decl
);
9465 OMP_CLAUSE_DECL (clause
)
9466 = build2 (MEM_REF
, char_type_node
, OMP_CLAUSE_DECL (clause
),
9467 build_int_cst (build_pointer_type (char_type_node
), 0));
9468 OMP_CLAUSE_SIZE (clause
) = size_zero_node
;
9469 OMP_CLAUSE_SIZE (nc
) = size_zero_node
;
9470 OMP_CLAUSE_SET_MAP_KIND (clause
, GOMP_MAP_ALLOC
);
9471 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (clause
) = 1;
9472 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_FIRSTPRIVATE_POINTER
);
9473 OMP_CLAUSE_CHAIN (nc
) = chain
;
9474 OMP_CLAUSE_CHAIN (clause
) = nc
;
9475 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
9476 gimplify_omp_ctxp
= ctx
->outer_context
;
9477 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (clause
), 0),
9478 pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
9479 gimplify_omp_ctxp
= ctx
;
9481 else if (code
== OMP_CLAUSE_MAP
)
9484 /* Not all combinations of these GOVD_MAP flags are actually valid. */
9485 switch (flags
& (GOVD_MAP_TO_ONLY
9487 | GOVD_MAP_FORCE_PRESENT
9488 | GOVD_MAP_ALLOC_ONLY
9489 | GOVD_MAP_FROM_ONLY
))
9492 kind
= GOMP_MAP_TOFROM
;
9494 case GOVD_MAP_FORCE
:
9495 kind
= GOMP_MAP_TOFROM
| GOMP_MAP_FLAG_FORCE
;
9497 case GOVD_MAP_TO_ONLY
:
9500 case GOVD_MAP_FROM_ONLY
:
9501 kind
= GOMP_MAP_FROM
;
9503 case GOVD_MAP_ALLOC_ONLY
:
9504 kind
= GOMP_MAP_ALLOC
;
9506 case GOVD_MAP_TO_ONLY
| GOVD_MAP_FORCE
:
9507 kind
= GOMP_MAP_TO
| GOMP_MAP_FLAG_FORCE
;
9509 case GOVD_MAP_FORCE_PRESENT
:
9510 kind
= GOMP_MAP_FORCE_PRESENT
;
9515 OMP_CLAUSE_SET_MAP_KIND (clause
, kind
);
9516 if (DECL_SIZE (decl
)
9517 && TREE_CODE (DECL_SIZE (decl
)) != INTEGER_CST
)
9519 tree decl2
= DECL_VALUE_EXPR (decl
);
9520 gcc_assert (TREE_CODE (decl2
) == INDIRECT_REF
);
9521 decl2
= TREE_OPERAND (decl2
, 0);
9522 gcc_assert (DECL_P (decl2
));
9523 tree mem
= build_simple_mem_ref (decl2
);
9524 OMP_CLAUSE_DECL (clause
) = mem
;
9525 OMP_CLAUSE_SIZE (clause
) = TYPE_SIZE_UNIT (TREE_TYPE (decl
));
9526 if (gimplify_omp_ctxp
->outer_context
)
9528 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
->outer_context
;
9529 omp_notice_variable (ctx
, decl2
, true);
9530 omp_notice_variable (ctx
, OMP_CLAUSE_SIZE (clause
), true);
9532 tree nc
= build_omp_clause (OMP_CLAUSE_LOCATION (clause
),
9534 OMP_CLAUSE_DECL (nc
) = decl
;
9535 OMP_CLAUSE_SIZE (nc
) = size_zero_node
;
9536 if (gimplify_omp_ctxp
->target_firstprivatize_array_bases
)
9537 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_FIRSTPRIVATE_POINTER
);
9539 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_POINTER
);
9540 OMP_CLAUSE_CHAIN (nc
) = OMP_CLAUSE_CHAIN (clause
);
9541 OMP_CLAUSE_CHAIN (clause
) = nc
;
9543 else if (gimplify_omp_ctxp
->target_firstprivatize_array_bases
9544 && lang_hooks
.decls
.omp_privatize_by_reference (decl
))
9546 OMP_CLAUSE_DECL (clause
) = build_simple_mem_ref (decl
);
9547 OMP_CLAUSE_SIZE (clause
)
9548 = unshare_expr (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl
))));
9549 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
9550 gimplify_omp_ctxp
= ctx
->outer_context
;
9551 gimplify_expr (&OMP_CLAUSE_SIZE (clause
),
9552 pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
9553 gimplify_omp_ctxp
= ctx
;
9554 tree nc
= build_omp_clause (OMP_CLAUSE_LOCATION (clause
),
9556 OMP_CLAUSE_DECL (nc
) = decl
;
9557 OMP_CLAUSE_SIZE (nc
) = size_zero_node
;
9558 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_FIRSTPRIVATE_REFERENCE
);
9559 OMP_CLAUSE_CHAIN (nc
) = OMP_CLAUSE_CHAIN (clause
);
9560 OMP_CLAUSE_CHAIN (clause
) = nc
;
9563 OMP_CLAUSE_SIZE (clause
) = DECL_SIZE_UNIT (decl
);
9565 if (code
== OMP_CLAUSE_FIRSTPRIVATE
&& (flags
& GOVD_LASTPRIVATE
) != 0)
9567 tree nc
= build_omp_clause (input_location
, OMP_CLAUSE_LASTPRIVATE
);
9568 OMP_CLAUSE_DECL (nc
) = decl
;
9569 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (nc
) = 1;
9570 OMP_CLAUSE_CHAIN (nc
) = chain
;
9571 OMP_CLAUSE_CHAIN (clause
) = nc
;
9572 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
9573 gimplify_omp_ctxp
= ctx
->outer_context
;
9574 lang_hooks
.decls
.omp_finish_clause (nc
, pre_p
);
9575 gimplify_omp_ctxp
= ctx
;
9578 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
9579 gimplify_omp_ctxp
= ctx
->outer_context
;
9580 lang_hooks
.decls
.omp_finish_clause (clause
, pre_p
);
9581 if (gimplify_omp_ctxp
)
9582 for (; clause
!= chain
; clause
= OMP_CLAUSE_CHAIN (clause
))
9583 if (OMP_CLAUSE_CODE (clause
) == OMP_CLAUSE_MAP
9584 && DECL_P (OMP_CLAUSE_SIZE (clause
)))
9585 omp_notice_variable (gimplify_omp_ctxp
, OMP_CLAUSE_SIZE (clause
),
9587 gimplify_omp_ctxp
= ctx
;
9592 gimplify_adjust_omp_clauses (gimple_seq
*pre_p
, gimple_seq body
, tree
*list_p
,
9593 enum tree_code code
)
9595 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
9600 struct gimplify_omp_ctx
*octx
;
9601 for (octx
= ctx
; octx
; octx
= octx
->outer_context
)
9602 if ((octx
->region_type
& (ORT_PARALLEL
| ORT_TASK
| ORT_TEAMS
)) != 0)
9606 struct walk_stmt_info wi
;
9607 memset (&wi
, 0, sizeof (wi
));
9608 walk_gimple_seq (body
, omp_find_stores_stmt
,
9609 omp_find_stores_op
, &wi
);
9612 while ((c
= *list_p
) != NULL
)
9615 bool remove
= false;
9617 switch (OMP_CLAUSE_CODE (c
))
9619 case OMP_CLAUSE_FIRSTPRIVATE
:
9620 if ((ctx
->region_type
& ORT_TARGET
)
9621 && (ctx
->region_type
& ORT_ACC
) == 0
9622 && TYPE_ATOMIC (strip_array_types
9623 (TREE_TYPE (OMP_CLAUSE_DECL (c
)))))
9625 error_at (OMP_CLAUSE_LOCATION (c
),
9626 "%<_Atomic%> %qD in %<firstprivate%> clause on "
9627 "%<target%> construct", OMP_CLAUSE_DECL (c
));
9632 case OMP_CLAUSE_PRIVATE
:
9633 case OMP_CLAUSE_SHARED
:
9634 case OMP_CLAUSE_LINEAR
:
9635 decl
= OMP_CLAUSE_DECL (c
);
9636 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
9637 remove
= !(n
->value
& GOVD_SEEN
);
9640 bool shared
= OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_SHARED
;
9641 if ((n
->value
& GOVD_DEBUG_PRIVATE
)
9642 || lang_hooks
.decls
.omp_private_debug_clause (decl
, shared
))
9644 gcc_assert ((n
->value
& GOVD_DEBUG_PRIVATE
) == 0
9645 || ((n
->value
& GOVD_DATA_SHARE_CLASS
)
9647 OMP_CLAUSE_SET_CODE (c
, OMP_CLAUSE_PRIVATE
);
9648 OMP_CLAUSE_PRIVATE_DEBUG (c
) = 1;
9650 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_SHARED
9651 && (n
->value
& GOVD_WRITTEN
) == 0
9653 && omp_shared_to_firstprivate_optimizable_decl_p (decl
))
9654 OMP_CLAUSE_SHARED_READONLY (c
) = 1;
9655 else if (DECL_P (decl
)
9656 && ((OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_SHARED
9657 && (n
->value
& GOVD_WRITTEN
) != 0)
9658 || (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINEAR
9659 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c
)))
9660 && omp_shared_to_firstprivate_optimizable_decl_p (decl
))
9661 omp_mark_stores (gimplify_omp_ctxp
->outer_context
, decl
);
9665 case OMP_CLAUSE_LASTPRIVATE
:
9666 /* Make sure OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE is set to
9667 accurately reflect the presence of a FIRSTPRIVATE clause. */
9668 decl
= OMP_CLAUSE_DECL (c
);
9669 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
9670 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
)
9671 = (n
->value
& GOVD_FIRSTPRIVATE
) != 0;
9672 if (code
== OMP_DISTRIBUTE
9673 && OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
))
9676 error_at (OMP_CLAUSE_LOCATION (c
),
9677 "same variable used in %<firstprivate%> and "
9678 "%<lastprivate%> clauses on %<distribute%> "
9682 && OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
9684 && omp_shared_to_firstprivate_optimizable_decl_p (decl
))
9685 omp_mark_stores (gimplify_omp_ctxp
->outer_context
, decl
);
9688 case OMP_CLAUSE_ALIGNED
:
9689 decl
= OMP_CLAUSE_DECL (c
);
9690 if (!is_global_var (decl
))
9692 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
9693 remove
= n
== NULL
|| !(n
->value
& GOVD_SEEN
);
9694 if (!remove
&& TREE_CODE (TREE_TYPE (decl
)) == POINTER_TYPE
)
9696 struct gimplify_omp_ctx
*octx
;
9698 && (n
->value
& (GOVD_DATA_SHARE_CLASS
9699 & ~GOVD_FIRSTPRIVATE
)))
9702 for (octx
= ctx
->outer_context
; octx
;
9703 octx
= octx
->outer_context
)
9705 n
= splay_tree_lookup (octx
->variables
,
9706 (splay_tree_key
) decl
);
9709 if (n
->value
& GOVD_LOCAL
)
9711 /* We have to avoid assigning a shared variable
9712 to itself when trying to add
9713 __builtin_assume_aligned. */
9714 if (n
->value
& GOVD_SHARED
)
9722 else if (TREE_CODE (TREE_TYPE (decl
)) == ARRAY_TYPE
)
9724 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
9725 if (n
!= NULL
&& (n
->value
& GOVD_DATA_SHARE_CLASS
) != 0)
9730 case OMP_CLAUSE_NONTEMPORAL
:
9731 decl
= OMP_CLAUSE_DECL (c
);
9732 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
9733 remove
= n
== NULL
|| !(n
->value
& GOVD_SEEN
);
9736 case OMP_CLAUSE_MAP
:
9737 if (code
== OMP_TARGET_EXIT_DATA
9738 && OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_ALWAYS_POINTER
)
9743 decl
= OMP_CLAUSE_DECL (c
);
9744 /* Data clauses associated with acc parallel reductions must be
9745 compatible with present_or_copy. Warn and adjust the clause
9746 if that is not the case. */
9747 if (ctx
->region_type
== ORT_ACC_PARALLEL
)
9749 tree t
= DECL_P (decl
) ? decl
: TREE_OPERAND (decl
, 0);
9753 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) t
);
9755 if (n
&& (n
->value
& GOVD_REDUCTION
))
9757 enum gomp_map_kind kind
= OMP_CLAUSE_MAP_KIND (c
);
9759 OMP_CLAUSE_MAP_IN_REDUCTION (c
) = 1;
9760 if ((kind
& GOMP_MAP_TOFROM
) != GOMP_MAP_TOFROM
9761 && kind
!= GOMP_MAP_FORCE_PRESENT
9762 && kind
!= GOMP_MAP_POINTER
)
9764 warning_at (OMP_CLAUSE_LOCATION (c
), 0,
9765 "incompatible data clause with reduction "
9766 "on %qE; promoting to present_or_copy",
9768 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_TOFROM
);
9774 if ((ctx
->region_type
& ORT_TARGET
) != 0
9775 && OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_FIRSTPRIVATE_POINTER
)
9777 if (TREE_CODE (decl
) == INDIRECT_REF
9778 && TREE_CODE (TREE_OPERAND (decl
, 0)) == COMPONENT_REF
9779 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl
, 0)))
9781 decl
= TREE_OPERAND (decl
, 0);
9782 if (TREE_CODE (decl
) == COMPONENT_REF
)
9784 while (TREE_CODE (decl
) == COMPONENT_REF
)
9785 decl
= TREE_OPERAND (decl
, 0);
9788 n
= splay_tree_lookup (ctx
->variables
,
9789 (splay_tree_key
) decl
);
9790 if (!(n
->value
& GOVD_SEEN
))
9797 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
9798 if ((ctx
->region_type
& ORT_TARGET
) != 0
9799 && !(n
->value
& GOVD_SEEN
)
9800 && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c
)) == 0
9801 && (!is_global_var (decl
)
9802 || !lookup_attribute ("omp declare target link",
9803 DECL_ATTRIBUTES (decl
))))
9806 /* For struct element mapping, if struct is never referenced
9807 in target block and none of the mapping has always modifier,
9808 remove all the struct element mappings, which immediately
9809 follow the GOMP_MAP_STRUCT map clause. */
9810 if (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_STRUCT
)
9812 HOST_WIDE_INT cnt
= tree_to_shwi (OMP_CLAUSE_SIZE (c
));
9814 OMP_CLAUSE_CHAIN (c
)
9815 = OMP_CLAUSE_CHAIN (OMP_CLAUSE_CHAIN (c
));
9818 else if (OMP_CLAUSE_MAP_KIND (c
) == GOMP_MAP_STRUCT
9819 && code
== OMP_TARGET_EXIT_DATA
)
9821 else if (DECL_SIZE (decl
)
9822 && TREE_CODE (DECL_SIZE (decl
)) != INTEGER_CST
9823 && OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_POINTER
9824 && OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_FIRSTPRIVATE_POINTER
9825 && (OMP_CLAUSE_MAP_KIND (c
)
9826 != GOMP_MAP_FIRSTPRIVATE_REFERENCE
))
9828 /* For GOMP_MAP_FORCE_DEVICEPTR, we'll never enter here, because
9829 for these, TREE_CODE (DECL_SIZE (decl)) will always be
9831 gcc_assert (OMP_CLAUSE_MAP_KIND (c
) != GOMP_MAP_FORCE_DEVICEPTR
);
9833 tree decl2
= DECL_VALUE_EXPR (decl
);
9834 gcc_assert (TREE_CODE (decl2
) == INDIRECT_REF
);
9835 decl2
= TREE_OPERAND (decl2
, 0);
9836 gcc_assert (DECL_P (decl2
));
9837 tree mem
= build_simple_mem_ref (decl2
);
9838 OMP_CLAUSE_DECL (c
) = mem
;
9839 OMP_CLAUSE_SIZE (c
) = TYPE_SIZE_UNIT (TREE_TYPE (decl
));
9840 if (ctx
->outer_context
)
9842 omp_notice_variable (ctx
->outer_context
, decl2
, true);
9843 omp_notice_variable (ctx
->outer_context
,
9844 OMP_CLAUSE_SIZE (c
), true);
9846 if (((ctx
->region_type
& ORT_TARGET
) != 0
9847 || !ctx
->target_firstprivatize_array_bases
)
9848 && ((n
->value
& GOVD_SEEN
) == 0
9849 || (n
->value
& (GOVD_PRIVATE
| GOVD_FIRSTPRIVATE
)) == 0))
9851 tree nc
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
9853 OMP_CLAUSE_DECL (nc
) = decl
;
9854 OMP_CLAUSE_SIZE (nc
) = size_zero_node
;
9855 if (ctx
->target_firstprivatize_array_bases
)
9856 OMP_CLAUSE_SET_MAP_KIND (nc
,
9857 GOMP_MAP_FIRSTPRIVATE_POINTER
);
9859 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_POINTER
);
9860 OMP_CLAUSE_CHAIN (nc
) = OMP_CLAUSE_CHAIN (c
);
9861 OMP_CLAUSE_CHAIN (c
) = nc
;
9867 if (OMP_CLAUSE_SIZE (c
) == NULL_TREE
)
9868 OMP_CLAUSE_SIZE (c
) = DECL_SIZE_UNIT (decl
);
9869 gcc_assert ((n
->value
& GOVD_SEEN
) == 0
9870 || ((n
->value
& (GOVD_PRIVATE
| GOVD_FIRSTPRIVATE
))
9876 case OMP_CLAUSE_FROM
:
9877 case OMP_CLAUSE__CACHE_
:
9878 decl
= OMP_CLAUSE_DECL (c
);
9881 if (DECL_SIZE (decl
)
9882 && TREE_CODE (DECL_SIZE (decl
)) != INTEGER_CST
)
9884 tree decl2
= DECL_VALUE_EXPR (decl
);
9885 gcc_assert (TREE_CODE (decl2
) == INDIRECT_REF
);
9886 decl2
= TREE_OPERAND (decl2
, 0);
9887 gcc_assert (DECL_P (decl2
));
9888 tree mem
= build_simple_mem_ref (decl2
);
9889 OMP_CLAUSE_DECL (c
) = mem
;
9890 OMP_CLAUSE_SIZE (c
) = TYPE_SIZE_UNIT (TREE_TYPE (decl
));
9891 if (ctx
->outer_context
)
9893 omp_notice_variable (ctx
->outer_context
, decl2
, true);
9894 omp_notice_variable (ctx
->outer_context
,
9895 OMP_CLAUSE_SIZE (c
), true);
9898 else if (OMP_CLAUSE_SIZE (c
) == NULL_TREE
)
9899 OMP_CLAUSE_SIZE (c
) = DECL_SIZE_UNIT (decl
);
9902 case OMP_CLAUSE_REDUCTION
:
9903 case OMP_CLAUSE_IN_REDUCTION
:
9904 case OMP_CLAUSE_TASK_REDUCTION
:
9905 decl
= OMP_CLAUSE_DECL (c
);
9906 /* OpenACC reductions need a present_or_copy data clause.
9907 Add one if necessary. Emit error when the reduction is private. */
9908 if (ctx
->region_type
== ORT_ACC_PARALLEL
)
9910 n
= splay_tree_lookup (ctx
->variables
, (splay_tree_key
) decl
);
9911 if (n
->value
& (GOVD_PRIVATE
| GOVD_FIRSTPRIVATE
))
9914 error_at (OMP_CLAUSE_LOCATION (c
), "invalid private "
9915 "reduction on %qE", DECL_NAME (decl
));
9917 else if ((n
->value
& GOVD_MAP
) == 0)
9919 tree next
= OMP_CLAUSE_CHAIN (c
);
9920 tree nc
= build_omp_clause (UNKNOWN_LOCATION
, OMP_CLAUSE_MAP
);
9921 OMP_CLAUSE_SET_MAP_KIND (nc
, GOMP_MAP_TOFROM
);
9922 OMP_CLAUSE_DECL (nc
) = decl
;
9923 OMP_CLAUSE_CHAIN (c
) = nc
;
9924 lang_hooks
.decls
.omp_finish_clause (nc
, pre_p
);
9927 OMP_CLAUSE_MAP_IN_REDUCTION (nc
) = 1;
9928 if (OMP_CLAUSE_CHAIN (nc
) == NULL
)
9930 nc
= OMP_CLAUSE_CHAIN (nc
);
9932 OMP_CLAUSE_CHAIN (nc
) = next
;
9933 n
->value
|= GOVD_MAP
;
9937 && omp_shared_to_firstprivate_optimizable_decl_p (decl
))
9938 omp_mark_stores (gimplify_omp_ctxp
->outer_context
, decl
);
9940 case OMP_CLAUSE_COPYIN
:
9941 case OMP_CLAUSE_COPYPRIVATE
:
9943 case OMP_CLAUSE_NUM_THREADS
:
9944 case OMP_CLAUSE_NUM_TEAMS
:
9945 case OMP_CLAUSE_THREAD_LIMIT
:
9946 case OMP_CLAUSE_DIST_SCHEDULE
:
9947 case OMP_CLAUSE_DEVICE
:
9948 case OMP_CLAUSE_SCHEDULE
:
9949 case OMP_CLAUSE_NOWAIT
:
9950 case OMP_CLAUSE_ORDERED
:
9951 case OMP_CLAUSE_DEFAULT
:
9952 case OMP_CLAUSE_UNTIED
:
9953 case OMP_CLAUSE_COLLAPSE
:
9954 case OMP_CLAUSE_FINAL
:
9955 case OMP_CLAUSE_MERGEABLE
:
9956 case OMP_CLAUSE_PROC_BIND
:
9957 case OMP_CLAUSE_SAFELEN
:
9958 case OMP_CLAUSE_SIMDLEN
:
9959 case OMP_CLAUSE_DEPEND
:
9960 case OMP_CLAUSE_PRIORITY
:
9961 case OMP_CLAUSE_GRAINSIZE
:
9962 case OMP_CLAUSE_NUM_TASKS
:
9963 case OMP_CLAUSE_NOGROUP
:
9964 case OMP_CLAUSE_THREADS
:
9965 case OMP_CLAUSE_SIMD
:
9966 case OMP_CLAUSE_HINT
:
9967 case OMP_CLAUSE_DEFAULTMAP
:
9968 case OMP_CLAUSE_USE_DEVICE_PTR
:
9969 case OMP_CLAUSE_IS_DEVICE_PTR
:
9970 case OMP_CLAUSE_ASYNC
:
9971 case OMP_CLAUSE_WAIT
:
9972 case OMP_CLAUSE_INDEPENDENT
:
9973 case OMP_CLAUSE_NUM_GANGS
:
9974 case OMP_CLAUSE_NUM_WORKERS
:
9975 case OMP_CLAUSE_VECTOR_LENGTH
:
9976 case OMP_CLAUSE_GANG
:
9977 case OMP_CLAUSE_WORKER
:
9978 case OMP_CLAUSE_VECTOR
:
9979 case OMP_CLAUSE_AUTO
:
9980 case OMP_CLAUSE_SEQ
:
9981 case OMP_CLAUSE_TILE
:
9982 case OMP_CLAUSE_IF_PRESENT
:
9983 case OMP_CLAUSE_FINALIZE
:
9991 *list_p
= OMP_CLAUSE_CHAIN (c
);
9993 list_p
= &OMP_CLAUSE_CHAIN (c
);
9996 /* Add in any implicit data sharing. */
9997 struct gimplify_adjust_omp_clauses_data data
;
9998 data
.list_p
= list_p
;
10000 splay_tree_foreach (ctx
->variables
, gimplify_adjust_omp_clauses_1
, &data
);
10002 gimplify_omp_ctxp
= ctx
->outer_context
;
10003 delete_omp_context (ctx
);
10006 /* Gimplify OACC_CACHE. */
10009 gimplify_oacc_cache (tree
*expr_p
, gimple_seq
*pre_p
)
10011 tree expr
= *expr_p
;
10013 gimplify_scan_omp_clauses (&OACC_CACHE_CLAUSES (expr
), pre_p
, ORT_ACC
,
10015 gimplify_adjust_omp_clauses (pre_p
, NULL
, &OACC_CACHE_CLAUSES (expr
),
10018 /* TODO: Do something sensible with this information. */
10020 *expr_p
= NULL_TREE
;
10023 /* Helper function of gimplify_oacc_declare. The helper's purpose is to,
10024 if required, translate 'kind' in CLAUSE into an 'entry' kind and 'exit'
10025 kind. The entry kind will replace the one in CLAUSE, while the exit
10026 kind will be used in a new omp_clause and returned to the caller. */
10029 gimplify_oacc_declare_1 (tree clause
)
10031 HOST_WIDE_INT kind
, new_op
;
10035 kind
= OMP_CLAUSE_MAP_KIND (clause
);
10039 case GOMP_MAP_ALLOC
:
10040 new_op
= GOMP_MAP_RELEASE
;
10044 case GOMP_MAP_FROM
:
10045 OMP_CLAUSE_SET_MAP_KIND (clause
, GOMP_MAP_FORCE_ALLOC
);
10046 new_op
= GOMP_MAP_FROM
;
10050 case GOMP_MAP_TOFROM
:
10051 OMP_CLAUSE_SET_MAP_KIND (clause
, GOMP_MAP_TO
);
10052 new_op
= GOMP_MAP_FROM
;
10056 case GOMP_MAP_DEVICE_RESIDENT
:
10057 case GOMP_MAP_FORCE_DEVICEPTR
:
10058 case GOMP_MAP_FORCE_PRESENT
:
10059 case GOMP_MAP_LINK
:
10060 case GOMP_MAP_POINTER
:
10065 gcc_unreachable ();
10071 c
= build_omp_clause (OMP_CLAUSE_LOCATION (clause
), OMP_CLAUSE_MAP
);
10072 OMP_CLAUSE_SET_MAP_KIND (c
, new_op
);
10073 OMP_CLAUSE_DECL (c
) = OMP_CLAUSE_DECL (clause
);
10079 /* Gimplify OACC_DECLARE. */
10082 gimplify_oacc_declare (tree
*expr_p
, gimple_seq
*pre_p
)
10084 tree expr
= *expr_p
;
10086 tree clauses
, t
, decl
;
10088 clauses
= OACC_DECLARE_CLAUSES (expr
);
10090 gimplify_scan_omp_clauses (&clauses
, pre_p
, ORT_TARGET_DATA
, OACC_DECLARE
);
10091 gimplify_adjust_omp_clauses (pre_p
, NULL
, &clauses
, OACC_DECLARE
);
10093 for (t
= clauses
; t
; t
= OMP_CLAUSE_CHAIN (t
))
10095 decl
= OMP_CLAUSE_DECL (t
);
10097 if (TREE_CODE (decl
) == MEM_REF
)
10098 decl
= TREE_OPERAND (decl
, 0);
10100 if (VAR_P (decl
) && !is_oacc_declared (decl
))
10102 tree attr
= get_identifier ("oacc declare target");
10103 DECL_ATTRIBUTES (decl
) = tree_cons (attr
, NULL_TREE
,
10104 DECL_ATTRIBUTES (decl
));
10108 && !is_global_var (decl
)
10109 && DECL_CONTEXT (decl
) == current_function_decl
)
10111 tree c
= gimplify_oacc_declare_1 (t
);
10114 if (oacc_declare_returns
== NULL
)
10115 oacc_declare_returns
= new hash_map
<tree
, tree
>;
10117 oacc_declare_returns
->put (decl
, c
);
10121 if (gimplify_omp_ctxp
)
10122 omp_add_variable (gimplify_omp_ctxp
, decl
, GOVD_SEEN
);
10125 stmt
= gimple_build_omp_target (NULL
, GF_OMP_TARGET_KIND_OACC_DECLARE
,
10128 gimplify_seq_add_stmt (pre_p
, stmt
);
10130 *expr_p
= NULL_TREE
;
10133 /* Gimplify the contents of an OMP_PARALLEL statement. This involves
10134 gimplification of the body, as well as scanning the body for used
10135 variables. We need to do this scan now, because variable-sized
10136 decls will be decomposed during gimplification. */
10139 gimplify_omp_parallel (tree
*expr_p
, gimple_seq
*pre_p
)
10141 tree expr
= *expr_p
;
10143 gimple_seq body
= NULL
;
10145 gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr
), pre_p
,
10146 OMP_PARALLEL_COMBINED (expr
)
10147 ? ORT_COMBINED_PARALLEL
10148 : ORT_PARALLEL
, OMP_PARALLEL
);
10150 push_gimplify_context ();
10152 g
= gimplify_and_return_first (OMP_PARALLEL_BODY (expr
), &body
);
10153 if (gimple_code (g
) == GIMPLE_BIND
)
10154 pop_gimplify_context (g
);
10156 pop_gimplify_context (NULL
);
10158 gimplify_adjust_omp_clauses (pre_p
, body
, &OMP_PARALLEL_CLAUSES (expr
),
10161 g
= gimple_build_omp_parallel (body
,
10162 OMP_PARALLEL_CLAUSES (expr
),
10163 NULL_TREE
, NULL_TREE
);
10164 if (OMP_PARALLEL_COMBINED (expr
))
10165 gimple_omp_set_subcode (g
, GF_OMP_PARALLEL_COMBINED
);
10166 gimplify_seq_add_stmt (pre_p
, g
);
10167 *expr_p
= NULL_TREE
;
10170 /* Gimplify the contents of an OMP_TASK statement. This involves
10171 gimplification of the body, as well as scanning the body for used
10172 variables. We need to do this scan now, because variable-sized
10173 decls will be decomposed during gimplification. */
10176 gimplify_omp_task (tree
*expr_p
, gimple_seq
*pre_p
)
10178 tree expr
= *expr_p
;
10180 gimple_seq body
= NULL
;
10182 if (OMP_TASK_BODY (expr
) == NULL_TREE
)
10183 for (tree c
= OMP_TASK_CLAUSES (expr
); c
; c
= OMP_CLAUSE_CHAIN (c
))
10184 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEPEND
10185 && OMP_CLAUSE_DEPEND_KIND (c
) == OMP_CLAUSE_DEPEND_MUTEXINOUTSET
)
10187 error_at (OMP_CLAUSE_LOCATION (c
),
10188 "%<mutexinoutset%> kind in %<depend%> clause on a "
10189 "%<taskwait%> construct");
10193 gimplify_scan_omp_clauses (&OMP_TASK_CLAUSES (expr
), pre_p
,
10194 omp_find_clause (OMP_TASK_CLAUSES (expr
),
10196 ? ORT_UNTIED_TASK
: ORT_TASK
, OMP_TASK
);
10198 if (OMP_TASK_BODY (expr
))
10200 push_gimplify_context ();
10202 g
= gimplify_and_return_first (OMP_TASK_BODY (expr
), &body
);
10203 if (gimple_code (g
) == GIMPLE_BIND
)
10204 pop_gimplify_context (g
);
10206 pop_gimplify_context (NULL
);
10209 gimplify_adjust_omp_clauses (pre_p
, body
, &OMP_TASK_CLAUSES (expr
),
10212 g
= gimple_build_omp_task (body
,
10213 OMP_TASK_CLAUSES (expr
),
10214 NULL_TREE
, NULL_TREE
,
10215 NULL_TREE
, NULL_TREE
, NULL_TREE
);
10216 if (OMP_TASK_BODY (expr
) == NULL_TREE
)
10217 gimple_omp_task_set_taskwait_p (g
, true);
10218 gimplify_seq_add_stmt (pre_p
, g
);
10219 *expr_p
= NULL_TREE
;
10222 /* Helper function of gimplify_omp_for, find OMP_FOR resp. OMP_SIMD
10223 with non-NULL OMP_FOR_INIT. Also, fill in pdata array,
10224 pdata[0] non-NULL if there is anything non-trivial in between, pdata[1]
10225 is address of OMP_PARALLEL in between if any, pdata[2] is address of
10226 OMP_FOR in between if any and pdata[3] is address of the inner
10227 OMP_FOR/OMP_SIMD. */
10230 find_combined_omp_for (tree
*tp
, int *walk_subtrees
, void *data
)
10232 tree
**pdata
= (tree
**) data
;
10233 *walk_subtrees
= 0;
10234 switch (TREE_CODE (*tp
))
10237 if (OMP_FOR_INIT (*tp
) != NULL_TREE
)
10243 *walk_subtrees
= 1;
10246 if (OMP_FOR_INIT (*tp
) != NULL_TREE
)
10253 if (BIND_EXPR_VARS (*tp
)
10254 || (BIND_EXPR_BLOCK (*tp
)
10255 && BLOCK_VARS (BIND_EXPR_BLOCK (*tp
))))
10257 *walk_subtrees
= 1;
10259 case STATEMENT_LIST
:
10260 if (!tsi_one_before_end_p (tsi_start (*tp
)))
10262 *walk_subtrees
= 1;
10264 case TRY_FINALLY_EXPR
:
10266 *walk_subtrees
= 1;
10270 *walk_subtrees
= 1;
10278 /* Gimplify the gross structure of an OMP_FOR statement. */
10280 static enum gimplify_status
10281 gimplify_omp_for (tree
*expr_p
, gimple_seq
*pre_p
)
10283 tree for_stmt
, orig_for_stmt
, inner_for_stmt
= NULL_TREE
, decl
, var
, t
;
10284 enum gimplify_status ret
= GS_ALL_DONE
;
10285 enum gimplify_status tret
;
10287 gimple_seq for_body
, for_pre_body
;
10289 bitmap has_decl_expr
= NULL
;
10290 enum omp_region_type ort
= ORT_WORKSHARE
;
10292 orig_for_stmt
= for_stmt
= *expr_p
;
10294 if (OMP_FOR_INIT (for_stmt
) == NULL_TREE
)
10296 tree
*data
[4] = { NULL
, NULL
, NULL
, NULL
};
10297 gcc_assert (TREE_CODE (for_stmt
) != OACC_LOOP
);
10298 inner_for_stmt
= walk_tree (&OMP_FOR_BODY (for_stmt
),
10299 find_combined_omp_for
, data
, NULL
);
10300 if (inner_for_stmt
== NULL_TREE
)
10302 gcc_assert (seen_error ());
10303 *expr_p
= NULL_TREE
;
10306 if (data
[2] && OMP_FOR_PRE_BODY (*data
[2]))
10308 append_to_statement_list_force (OMP_FOR_PRE_BODY (*data
[2]),
10309 &OMP_FOR_PRE_BODY (for_stmt
));
10310 OMP_FOR_PRE_BODY (*data
[2]) = NULL_TREE
;
10312 if (OMP_FOR_PRE_BODY (inner_for_stmt
))
10314 append_to_statement_list_force (OMP_FOR_PRE_BODY (inner_for_stmt
),
10315 &OMP_FOR_PRE_BODY (for_stmt
));
10316 OMP_FOR_PRE_BODY (inner_for_stmt
) = NULL_TREE
;
10321 /* We have some statements or variable declarations in between
10322 the composite construct directives. Move them around the
10325 for (i
= 0; i
< 3; i
++)
10329 if (i
< 2 && data
[i
+ 1] == &OMP_BODY (t
))
10330 data
[i
+ 1] = data
[i
];
10331 *data
[i
] = OMP_BODY (t
);
10332 tree body
= build3 (BIND_EXPR
, void_type_node
, NULL_TREE
,
10333 NULL_TREE
, make_node (BLOCK
));
10334 OMP_BODY (t
) = body
;
10335 append_to_statement_list_force (inner_for_stmt
,
10336 &BIND_EXPR_BODY (body
));
10338 data
[3] = tsi_stmt_ptr (tsi_start (BIND_EXPR_BODY (body
)));
10339 gcc_assert (*data
[3] == inner_for_stmt
);
10344 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt
)); i
++)
10345 if (OMP_FOR_ORIG_DECLS (inner_for_stmt
)
10346 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
),
10348 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
),
10351 tree orig
= TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
), i
);
10352 /* Class iterators aren't allowed on OMP_SIMD, so the only
10353 case we need to solve is distribute parallel for. */
10354 gcc_assert (TREE_CODE (inner_for_stmt
) == OMP_FOR
10355 && TREE_CODE (for_stmt
) == OMP_DISTRIBUTE
10357 tree orig_decl
= TREE_PURPOSE (orig
);
10358 tree last
= TREE_VALUE (orig
);
10360 for (pc
= &OMP_FOR_CLAUSES (inner_for_stmt
);
10361 *pc
; pc
= &OMP_CLAUSE_CHAIN (*pc
))
10362 if ((OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_PRIVATE
10363 || OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_LASTPRIVATE
)
10364 && OMP_CLAUSE_DECL (*pc
) == orig_decl
)
10366 if (*pc
== NULL_TREE
)
10368 else if (OMP_CLAUSE_CODE (*pc
) == OMP_CLAUSE_PRIVATE
)
10370 /* private clause will appear only on inner_for_stmt.
10371 Change it into firstprivate, and add private clause
10373 tree c
= copy_node (*pc
);
10374 OMP_CLAUSE_CHAIN (c
) = OMP_FOR_CLAUSES (for_stmt
);
10375 OMP_FOR_CLAUSES (for_stmt
) = c
;
10376 OMP_CLAUSE_CODE (*pc
) = OMP_CLAUSE_FIRSTPRIVATE
;
10377 lang_hooks
.decls
.omp_finish_clause (*pc
, pre_p
);
10381 /* lastprivate clause will appear on both inner_for_stmt
10382 and for_stmt. Add firstprivate clause to
10384 tree c
= build_omp_clause (OMP_CLAUSE_LOCATION (*pc
),
10385 OMP_CLAUSE_FIRSTPRIVATE
);
10386 OMP_CLAUSE_DECL (c
) = OMP_CLAUSE_DECL (*pc
);
10387 OMP_CLAUSE_CHAIN (c
) = *pc
;
10389 lang_hooks
.decls
.omp_finish_clause (*pc
, pre_p
);
10391 tree c
= build_omp_clause (UNKNOWN_LOCATION
,
10392 OMP_CLAUSE_FIRSTPRIVATE
);
10393 OMP_CLAUSE_DECL (c
) = last
;
10394 OMP_CLAUSE_CHAIN (c
) = OMP_PARALLEL_CLAUSES (*data
[1]);
10395 OMP_PARALLEL_CLAUSES (*data
[1]) = c
;
10396 c
= build_omp_clause (UNKNOWN_LOCATION
,
10397 *pc
? OMP_CLAUSE_SHARED
10398 : OMP_CLAUSE_FIRSTPRIVATE
);
10399 OMP_CLAUSE_DECL (c
) = orig_decl
;
10400 OMP_CLAUSE_CHAIN (c
) = OMP_PARALLEL_CLAUSES (*data
[1]);
10401 OMP_PARALLEL_CLAUSES (*data
[1]) = c
;
10403 /* Similarly, take care of C++ range for temporaries, those should
10404 be firstprivate on OMP_PARALLEL if any. */
10406 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt
)); i
++)
10407 if (OMP_FOR_ORIG_DECLS (inner_for_stmt
)
10408 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
),
10410 && TREE_CHAIN (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
),
10414 = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt
), i
);
10415 tree v
= TREE_CHAIN (orig
);
10416 tree c
= build_omp_clause (UNKNOWN_LOCATION
,
10417 OMP_CLAUSE_FIRSTPRIVATE
);
10418 /* First add firstprivate clause for the __for_end artificial
10420 OMP_CLAUSE_DECL (c
) = TREE_VEC_ELT (v
, 1);
10421 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c
)))
10423 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c
) = 1;
10424 OMP_CLAUSE_CHAIN (c
) = OMP_PARALLEL_CLAUSES (*data
[1]);
10425 OMP_PARALLEL_CLAUSES (*data
[1]) = c
;
10426 if (TREE_VEC_ELT (v
, 0))
10428 /* And now the same for __for_range artificial decl if it
10430 c
= build_omp_clause (UNKNOWN_LOCATION
,
10431 OMP_CLAUSE_FIRSTPRIVATE
);
10432 OMP_CLAUSE_DECL (c
) = TREE_VEC_ELT (v
, 0);
10433 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c
)))
10435 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c
) = 1;
10436 OMP_CLAUSE_CHAIN (c
) = OMP_PARALLEL_CLAUSES (*data
[1]);
10437 OMP_PARALLEL_CLAUSES (*data
[1]) = c
;
10442 switch (TREE_CODE (for_stmt
))
10445 case OMP_DISTRIBUTE
:
10451 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_UNTIED
))
10452 ort
= ORT_UNTIED_TASKLOOP
;
10454 ort
= ORT_TASKLOOP
;
10460 gcc_unreachable ();
10463 /* Set OMP_CLAUSE_LINEAR_NO_COPYIN flag on explicit linear
10464 clause for the IV. */
10465 if (ort
== ORT_SIMD
&& TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)) == 1)
10467 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), 0);
10468 gcc_assert (TREE_CODE (t
) == MODIFY_EXPR
);
10469 decl
= TREE_OPERAND (t
, 0);
10470 for (tree c
= OMP_FOR_CLAUSES (for_stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
10471 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINEAR
10472 && OMP_CLAUSE_DECL (c
) == decl
)
10474 OMP_CLAUSE_LINEAR_NO_COPYIN (c
) = 1;
10479 if (TREE_CODE (for_stmt
) != OMP_TASKLOOP
)
10480 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt
), pre_p
, ort
,
10481 TREE_CODE (for_stmt
));
10483 if (TREE_CODE (for_stmt
) == OMP_DISTRIBUTE
)
10484 gimplify_omp_ctxp
->distribute
= true;
10486 /* Handle OMP_FOR_INIT. */
10487 for_pre_body
= NULL
;
10488 if ((ort
== ORT_SIMD
10489 || (inner_for_stmt
&& TREE_CODE (inner_for_stmt
) == OMP_SIMD
))
10490 && OMP_FOR_PRE_BODY (for_stmt
))
10492 has_decl_expr
= BITMAP_ALLOC (NULL
);
10493 if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt
)) == DECL_EXPR
10494 && TREE_CODE (DECL_EXPR_DECL (OMP_FOR_PRE_BODY (for_stmt
)))
10497 t
= OMP_FOR_PRE_BODY (for_stmt
);
10498 bitmap_set_bit (has_decl_expr
, DECL_UID (DECL_EXPR_DECL (t
)));
10500 else if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt
)) == STATEMENT_LIST
)
10502 tree_stmt_iterator si
;
10503 for (si
= tsi_start (OMP_FOR_PRE_BODY (for_stmt
)); !tsi_end_p (si
);
10507 if (TREE_CODE (t
) == DECL_EXPR
10508 && TREE_CODE (DECL_EXPR_DECL (t
)) == VAR_DECL
)
10509 bitmap_set_bit (has_decl_expr
, DECL_UID (DECL_EXPR_DECL (t
)));
10513 if (OMP_FOR_PRE_BODY (for_stmt
))
10515 if (TREE_CODE (for_stmt
) != OMP_TASKLOOP
|| gimplify_omp_ctxp
)
10516 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt
), &for_pre_body
);
10519 struct gimplify_omp_ctx ctx
;
10520 memset (&ctx
, 0, sizeof (ctx
));
10521 ctx
.region_type
= ORT_NONE
;
10522 gimplify_omp_ctxp
= &ctx
;
10523 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt
), &for_pre_body
);
10524 gimplify_omp_ctxp
= NULL
;
10527 OMP_FOR_PRE_BODY (for_stmt
) = NULL_TREE
;
10529 if (OMP_FOR_INIT (for_stmt
) == NULL_TREE
)
10530 for_stmt
= inner_for_stmt
;
10532 /* For taskloop, need to gimplify the start, end and step before the
10533 taskloop, outside of the taskloop omp context. */
10534 if (TREE_CODE (orig_for_stmt
) == OMP_TASKLOOP
)
10536 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
10538 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), i
);
10539 if (!is_gimple_constant (TREE_OPERAND (t
, 1)))
10541 tree type
= TREE_TYPE (TREE_OPERAND (t
, 0));
10542 TREE_OPERAND (t
, 1)
10543 = get_initialized_tmp_var (TREE_OPERAND (t
, 1),
10544 gimple_seq_empty_p (for_pre_body
)
10545 ? pre_p
: &for_pre_body
, NULL
,
10547 /* Reference to pointer conversion is considered useless,
10548 but is significant for firstprivate clause. Force it
10550 if (TREE_CODE (type
) == POINTER_TYPE
10551 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (t
, 1)))
10552 == REFERENCE_TYPE
))
10554 tree v
= create_tmp_var (TYPE_MAIN_VARIANT (type
));
10555 tree m
= build2 (INIT_EXPR
, TREE_TYPE (v
), v
,
10556 TREE_OPERAND (t
, 1));
10557 gimplify_and_add (m
, gimple_seq_empty_p (for_pre_body
)
10558 ? pre_p
: &for_pre_body
);
10559 TREE_OPERAND (t
, 1) = v
;
10561 tree c
= build_omp_clause (input_location
,
10562 OMP_CLAUSE_FIRSTPRIVATE
);
10563 OMP_CLAUSE_DECL (c
) = TREE_OPERAND (t
, 1);
10564 OMP_CLAUSE_CHAIN (c
) = OMP_FOR_CLAUSES (orig_for_stmt
);
10565 OMP_FOR_CLAUSES (orig_for_stmt
) = c
;
10568 /* Handle OMP_FOR_COND. */
10569 t
= TREE_VEC_ELT (OMP_FOR_COND (for_stmt
), i
);
10570 if (!is_gimple_constant (TREE_OPERAND (t
, 1)))
10572 tree type
= TREE_TYPE (TREE_OPERAND (t
, 0));
10573 TREE_OPERAND (t
, 1)
10574 = get_initialized_tmp_var (TREE_OPERAND (t
, 1),
10575 gimple_seq_empty_p (for_pre_body
)
10576 ? pre_p
: &for_pre_body
, NULL
,
10578 /* Reference to pointer conversion is considered useless,
10579 but is significant for firstprivate clause. Force it
10581 if (TREE_CODE (type
) == POINTER_TYPE
10582 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (t
, 1)))
10583 == REFERENCE_TYPE
))
10585 tree v
= create_tmp_var (TYPE_MAIN_VARIANT (type
));
10586 tree m
= build2 (INIT_EXPR
, TREE_TYPE (v
), v
,
10587 TREE_OPERAND (t
, 1));
10588 gimplify_and_add (m
, gimple_seq_empty_p (for_pre_body
)
10589 ? pre_p
: &for_pre_body
);
10590 TREE_OPERAND (t
, 1) = v
;
10592 tree c
= build_omp_clause (input_location
,
10593 OMP_CLAUSE_FIRSTPRIVATE
);
10594 OMP_CLAUSE_DECL (c
) = TREE_OPERAND (t
, 1);
10595 OMP_CLAUSE_CHAIN (c
) = OMP_FOR_CLAUSES (orig_for_stmt
);
10596 OMP_FOR_CLAUSES (orig_for_stmt
) = c
;
10599 /* Handle OMP_FOR_INCR. */
10600 t
= TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
);
10601 if (TREE_CODE (t
) == MODIFY_EXPR
)
10603 decl
= TREE_OPERAND (t
, 0);
10604 t
= TREE_OPERAND (t
, 1);
10605 tree
*tp
= &TREE_OPERAND (t
, 1);
10606 if (TREE_CODE (t
) == PLUS_EXPR
&& *tp
== decl
)
10607 tp
= &TREE_OPERAND (t
, 0);
10609 if (!is_gimple_constant (*tp
))
10611 gimple_seq
*seq
= gimple_seq_empty_p (for_pre_body
)
10612 ? pre_p
: &for_pre_body
;
10613 *tp
= get_initialized_tmp_var (*tp
, seq
, NULL
, false);
10614 tree c
= build_omp_clause (input_location
,
10615 OMP_CLAUSE_FIRSTPRIVATE
);
10616 OMP_CLAUSE_DECL (c
) = *tp
;
10617 OMP_CLAUSE_CHAIN (c
) = OMP_FOR_CLAUSES (orig_for_stmt
);
10618 OMP_FOR_CLAUSES (orig_for_stmt
) = c
;
10623 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (orig_for_stmt
), pre_p
, ort
,
10627 if (orig_for_stmt
!= for_stmt
)
10628 gimplify_omp_ctxp
->combined_loop
= true;
10631 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
))
10632 == TREE_VEC_LENGTH (OMP_FOR_COND (for_stmt
)));
10633 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
))
10634 == TREE_VEC_LENGTH (OMP_FOR_INCR (for_stmt
)));
10636 tree c
= omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_ORDERED
);
10637 bool is_doacross
= false;
10638 if (c
&& OMP_CLAUSE_ORDERED_EXPR (c
))
10640 is_doacross
= true;
10641 gimplify_omp_ctxp
->loop_iter_var
.create (TREE_VEC_LENGTH
10642 (OMP_FOR_INIT (for_stmt
))
10645 int collapse
= 1, tile
= 0;
10646 c
= omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_COLLAPSE
);
10648 collapse
= tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (c
));
10649 c
= omp_find_clause (OMP_FOR_CLAUSES (for_stmt
), OMP_CLAUSE_TILE
);
10651 tile
= list_length (OMP_CLAUSE_TILE_LIST (c
));
10652 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
10654 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), i
);
10655 gcc_assert (TREE_CODE (t
) == MODIFY_EXPR
);
10656 decl
= TREE_OPERAND (t
, 0);
10657 gcc_assert (DECL_P (decl
));
10658 gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl
))
10659 || POINTER_TYPE_P (TREE_TYPE (decl
)));
10662 if (TREE_CODE (for_stmt
) == OMP_FOR
&& OMP_FOR_ORIG_DECLS (for_stmt
))
10664 tree orig_decl
= TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt
), i
);
10665 if (TREE_CODE (orig_decl
) == TREE_LIST
)
10667 orig_decl
= TREE_PURPOSE (orig_decl
);
10671 gimplify_omp_ctxp
->loop_iter_var
.quick_push (orig_decl
);
10674 gimplify_omp_ctxp
->loop_iter_var
.quick_push (decl
);
10675 gimplify_omp_ctxp
->loop_iter_var
.quick_push (decl
);
10678 /* Make sure the iteration variable is private. */
10679 tree c
= NULL_TREE
;
10680 tree c2
= NULL_TREE
;
10681 if (orig_for_stmt
!= for_stmt
)
10683 /* Preserve this information until we gimplify the inner simd. */
10685 && bitmap_bit_p (has_decl_expr
, DECL_UID (decl
)))
10686 TREE_PRIVATE (t
) = 1;
10688 else if (ort
== ORT_SIMD
)
10690 splay_tree_node n
= splay_tree_lookup (gimplify_omp_ctxp
->variables
,
10691 (splay_tree_key
) decl
);
10692 omp_is_private (gimplify_omp_ctxp
, decl
,
10693 1 + (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
))
10695 if (n
!= NULL
&& (n
->value
& GOVD_DATA_SHARE_CLASS
) != 0)
10696 omp_notice_variable (gimplify_omp_ctxp
, decl
, true);
10697 else if (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)) == 1)
10699 c
= build_omp_clause (input_location
, OMP_CLAUSE_LINEAR
);
10700 OMP_CLAUSE_LINEAR_NO_COPYIN (c
) = 1;
10701 unsigned int flags
= GOVD_LINEAR
| GOVD_EXPLICIT
| GOVD_SEEN
;
10703 && bitmap_bit_p (has_decl_expr
, DECL_UID (decl
)))
10704 || TREE_PRIVATE (t
))
10706 OMP_CLAUSE_LINEAR_NO_COPYOUT (c
) = 1;
10707 flags
|= GOVD_LINEAR_LASTPRIVATE_NO_OUTER
;
10709 struct gimplify_omp_ctx
*outer
10710 = gimplify_omp_ctxp
->outer_context
;
10711 if (outer
&& !OMP_CLAUSE_LINEAR_NO_COPYOUT (c
))
10713 if (outer
->region_type
== ORT_WORKSHARE
10714 && outer
->combined_loop
)
10716 n
= splay_tree_lookup (outer
->variables
,
10717 (splay_tree_key
)decl
);
10718 if (n
!= NULL
&& (n
->value
& GOVD_LOCAL
) != 0)
10720 OMP_CLAUSE_LINEAR_NO_COPYOUT (c
) = 1;
10721 flags
|= GOVD_LINEAR_LASTPRIVATE_NO_OUTER
;
10725 struct gimplify_omp_ctx
*octx
= outer
->outer_context
;
10727 && octx
->region_type
== ORT_COMBINED_PARALLEL
10728 && octx
->outer_context
10729 && (octx
->outer_context
->region_type
10731 && octx
->outer_context
->combined_loop
)
10733 octx
= octx
->outer_context
;
10734 n
= splay_tree_lookup (octx
->variables
,
10735 (splay_tree_key
)decl
);
10736 if (n
!= NULL
&& (n
->value
& GOVD_LOCAL
) != 0)
10738 OMP_CLAUSE_LINEAR_NO_COPYOUT (c
) = 1;
10739 flags
|= GOVD_LINEAR_LASTPRIVATE_NO_OUTER
;
10746 OMP_CLAUSE_DECL (c
) = decl
;
10747 OMP_CLAUSE_CHAIN (c
) = OMP_FOR_CLAUSES (for_stmt
);
10748 OMP_FOR_CLAUSES (for_stmt
) = c
;
10749 omp_add_variable (gimplify_omp_ctxp
, decl
, flags
);
10750 if (outer
&& !OMP_CLAUSE_LINEAR_NO_COPYOUT (c
))
10752 if (outer
->region_type
== ORT_WORKSHARE
10753 && outer
->combined_loop
)
10755 if (outer
->outer_context
10756 && (outer
->outer_context
->region_type
10757 == ORT_COMBINED_PARALLEL
))
10758 outer
= outer
->outer_context
;
10759 else if (omp_check_private (outer
, decl
, false))
10762 else if (((outer
->region_type
& ORT_TASKLOOP
)
10764 && outer
->combined_loop
10765 && !omp_check_private (gimplify_omp_ctxp
,
10768 else if (outer
->region_type
!= ORT_COMBINED_PARALLEL
)
10770 omp_notice_variable (outer
, decl
, true);
10775 n
= splay_tree_lookup (outer
->variables
,
10776 (splay_tree_key
)decl
);
10777 if (n
== NULL
|| (n
->value
& GOVD_DATA_SHARE_CLASS
) == 0)
10779 omp_add_variable (outer
, decl
,
10780 GOVD_LASTPRIVATE
| GOVD_SEEN
);
10781 if (outer
->region_type
== ORT_COMBINED_PARALLEL
10782 && outer
->outer_context
10783 && (outer
->outer_context
->region_type
10785 && outer
->outer_context
->combined_loop
)
10787 outer
= outer
->outer_context
;
10788 n
= splay_tree_lookup (outer
->variables
,
10789 (splay_tree_key
)decl
);
10790 if (omp_check_private (outer
, decl
, false))
10793 || ((n
->value
& GOVD_DATA_SHARE_CLASS
)
10795 omp_add_variable (outer
, decl
,
10801 if (outer
&& outer
->outer_context
10802 && ((outer
->outer_context
->region_type
10803 & ORT_COMBINED_TEAMS
) == ORT_COMBINED_TEAMS
10804 || (((outer
->region_type
& ORT_TASKLOOP
)
10806 && (outer
->outer_context
->region_type
10807 == ORT_COMBINED_PARALLEL
))))
10809 outer
= outer
->outer_context
;
10810 n
= splay_tree_lookup (outer
->variables
,
10811 (splay_tree_key
)decl
);
10813 || (n
->value
& GOVD_DATA_SHARE_CLASS
) == 0)
10814 omp_add_variable (outer
, decl
,
10815 GOVD_SHARED
| GOVD_SEEN
);
10819 if (outer
&& outer
->outer_context
)
10820 omp_notice_variable (outer
->outer_context
, decl
,
10830 || !bitmap_bit_p (has_decl_expr
, DECL_UID (decl
)));
10831 if (TREE_PRIVATE (t
))
10832 lastprivate
= false;
10833 struct gimplify_omp_ctx
*outer
10834 = gimplify_omp_ctxp
->outer_context
;
10835 if (outer
&& lastprivate
)
10837 if (outer
->region_type
== ORT_WORKSHARE
10838 && outer
->combined_loop
)
10840 n
= splay_tree_lookup (outer
->variables
,
10841 (splay_tree_key
)decl
);
10842 if (n
!= NULL
&& (n
->value
& GOVD_LOCAL
) != 0)
10844 lastprivate
= false;
10847 else if (outer
->outer_context
10848 && (outer
->outer_context
->region_type
10849 == ORT_COMBINED_PARALLEL
))
10850 outer
= outer
->outer_context
;
10851 else if (omp_check_private (outer
, decl
, false))
10854 else if (((outer
->region_type
& ORT_TASKLOOP
)
10856 && outer
->combined_loop
10857 && !omp_check_private (gimplify_omp_ctxp
,
10860 else if (outer
->region_type
!= ORT_COMBINED_PARALLEL
)
10862 omp_notice_variable (outer
, decl
, true);
10867 n
= splay_tree_lookup (outer
->variables
,
10868 (splay_tree_key
)decl
);
10869 if (n
== NULL
|| (n
->value
& GOVD_DATA_SHARE_CLASS
) == 0)
10871 omp_add_variable (outer
, decl
,
10872 GOVD_LASTPRIVATE
| GOVD_SEEN
);
10873 if (outer
->region_type
== ORT_COMBINED_PARALLEL
10874 && outer
->outer_context
10875 && (outer
->outer_context
->region_type
10877 && outer
->outer_context
->combined_loop
)
10879 outer
= outer
->outer_context
;
10880 n
= splay_tree_lookup (outer
->variables
,
10881 (splay_tree_key
)decl
);
10882 if (omp_check_private (outer
, decl
, false))
10885 || ((n
->value
& GOVD_DATA_SHARE_CLASS
)
10887 omp_add_variable (outer
, decl
,
10893 if (outer
&& outer
->outer_context
10894 && ((outer
->outer_context
->region_type
10895 & ORT_COMBINED_TEAMS
) == ORT_COMBINED_TEAMS
10896 || (((outer
->region_type
& ORT_TASKLOOP
)
10898 && (outer
->outer_context
->region_type
10899 == ORT_COMBINED_PARALLEL
))))
10901 outer
= outer
->outer_context
;
10902 n
= splay_tree_lookup (outer
->variables
,
10903 (splay_tree_key
)decl
);
10905 || (n
->value
& GOVD_DATA_SHARE_CLASS
) == 0)
10906 omp_add_variable (outer
, decl
,
10907 GOVD_SHARED
| GOVD_SEEN
);
10911 if (outer
&& outer
->outer_context
)
10912 omp_notice_variable (outer
->outer_context
, decl
,
10918 c
= build_omp_clause (input_location
,
10919 lastprivate
? OMP_CLAUSE_LASTPRIVATE
10920 : OMP_CLAUSE_PRIVATE
);
10921 OMP_CLAUSE_DECL (c
) = decl
;
10922 OMP_CLAUSE_CHAIN (c
) = OMP_FOR_CLAUSES (for_stmt
);
10923 OMP_FOR_CLAUSES (for_stmt
) = c
;
10924 omp_add_variable (gimplify_omp_ctxp
, decl
,
10925 (lastprivate
? GOVD_LASTPRIVATE
: GOVD_PRIVATE
)
10926 | GOVD_EXPLICIT
| GOVD_SEEN
);
10930 else if (omp_is_private (gimplify_omp_ctxp
, decl
, 0))
10931 omp_notice_variable (gimplify_omp_ctxp
, decl
, true);
10933 omp_add_variable (gimplify_omp_ctxp
, decl
, GOVD_PRIVATE
| GOVD_SEEN
);
10935 /* If DECL is not a gimple register, create a temporary variable to act
10936 as an iteration counter. This is valid, since DECL cannot be
10937 modified in the body of the loop. Similarly for any iteration vars
10938 in simd with collapse > 1 where the iterator vars must be
10940 if (orig_for_stmt
!= for_stmt
)
10942 else if (!is_gimple_reg (decl
)
10943 || (ort
== ORT_SIMD
10944 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)) > 1))
10946 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
10947 /* Make sure omp_add_variable is not called on it prematurely.
10948 We call it ourselves a few lines later. */
10949 gimplify_omp_ctxp
= NULL
;
10950 var
= create_tmp_var (TREE_TYPE (decl
), get_name (decl
));
10951 gimplify_omp_ctxp
= ctx
;
10952 TREE_OPERAND (t
, 0) = var
;
10954 gimplify_seq_add_stmt (&for_body
, gimple_build_assign (decl
, var
));
10956 if (ort
== ORT_SIMD
10957 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)) == 1)
10959 c2
= build_omp_clause (input_location
, OMP_CLAUSE_LINEAR
);
10960 OMP_CLAUSE_LINEAR_NO_COPYIN (c2
) = 1;
10961 OMP_CLAUSE_LINEAR_NO_COPYOUT (c2
) = 1;
10962 OMP_CLAUSE_DECL (c2
) = var
;
10963 OMP_CLAUSE_CHAIN (c2
) = OMP_FOR_CLAUSES (for_stmt
);
10964 OMP_FOR_CLAUSES (for_stmt
) = c2
;
10965 omp_add_variable (gimplify_omp_ctxp
, var
,
10966 GOVD_LINEAR
| GOVD_EXPLICIT
| GOVD_SEEN
);
10967 if (c
== NULL_TREE
)
10974 omp_add_variable (gimplify_omp_ctxp
, var
,
10975 GOVD_PRIVATE
| GOVD_SEEN
);
10980 tret
= gimplify_expr (&TREE_OPERAND (t
, 1), &for_pre_body
, NULL
,
10981 is_gimple_val
, fb_rvalue
, false);
10982 ret
= MIN (ret
, tret
);
10983 if (ret
== GS_ERROR
)
10986 /* Handle OMP_FOR_COND. */
10987 t
= TREE_VEC_ELT (OMP_FOR_COND (for_stmt
), i
);
10988 gcc_assert (COMPARISON_CLASS_P (t
));
10989 gcc_assert (TREE_OPERAND (t
, 0) == decl
);
10991 tret
= gimplify_expr (&TREE_OPERAND (t
, 1), &for_pre_body
, NULL
,
10992 is_gimple_val
, fb_rvalue
, false);
10993 ret
= MIN (ret
, tret
);
10995 /* Handle OMP_FOR_INCR. */
10996 t
= TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
);
10997 switch (TREE_CODE (t
))
10999 case PREINCREMENT_EXPR
:
11000 case POSTINCREMENT_EXPR
:
11002 tree decl
= TREE_OPERAND (t
, 0);
11003 /* c_omp_for_incr_canonicalize_ptr() should have been
11004 called to massage things appropriately. */
11005 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl
)));
11007 if (orig_for_stmt
!= for_stmt
)
11009 t
= build_int_cst (TREE_TYPE (decl
), 1);
11011 OMP_CLAUSE_LINEAR_STEP (c
) = t
;
11012 t
= build2 (PLUS_EXPR
, TREE_TYPE (decl
), var
, t
);
11013 t
= build2 (MODIFY_EXPR
, TREE_TYPE (var
), var
, t
);
11014 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
) = t
;
11018 case PREDECREMENT_EXPR
:
11019 case POSTDECREMENT_EXPR
:
11020 /* c_omp_for_incr_canonicalize_ptr() should have been
11021 called to massage things appropriately. */
11022 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl
)));
11023 if (orig_for_stmt
!= for_stmt
)
11025 t
= build_int_cst (TREE_TYPE (decl
), -1);
11027 OMP_CLAUSE_LINEAR_STEP (c
) = t
;
11028 t
= build2 (PLUS_EXPR
, TREE_TYPE (decl
), var
, t
);
11029 t
= build2 (MODIFY_EXPR
, TREE_TYPE (var
), var
, t
);
11030 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
) = t
;
11034 gcc_assert (TREE_OPERAND (t
, 0) == decl
);
11035 TREE_OPERAND (t
, 0) = var
;
11037 t
= TREE_OPERAND (t
, 1);
11038 switch (TREE_CODE (t
))
11041 if (TREE_OPERAND (t
, 1) == decl
)
11043 TREE_OPERAND (t
, 1) = TREE_OPERAND (t
, 0);
11044 TREE_OPERAND (t
, 0) = var
;
11050 case POINTER_PLUS_EXPR
:
11051 gcc_assert (TREE_OPERAND (t
, 0) == decl
);
11052 TREE_OPERAND (t
, 0) = var
;
11055 gcc_unreachable ();
11058 tret
= gimplify_expr (&TREE_OPERAND (t
, 1), &for_pre_body
, NULL
,
11059 is_gimple_val
, fb_rvalue
, false);
11060 ret
= MIN (ret
, tret
);
11063 tree step
= TREE_OPERAND (t
, 1);
11064 tree stept
= TREE_TYPE (decl
);
11065 if (POINTER_TYPE_P (stept
))
11067 step
= fold_convert (stept
, step
);
11068 if (TREE_CODE (t
) == MINUS_EXPR
)
11069 step
= fold_build1 (NEGATE_EXPR
, stept
, step
);
11070 OMP_CLAUSE_LINEAR_STEP (c
) = step
;
11071 if (step
!= TREE_OPERAND (t
, 1))
11073 tret
= gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c
),
11074 &for_pre_body
, NULL
,
11075 is_gimple_val
, fb_rvalue
, false);
11076 ret
= MIN (ret
, tret
);
11082 gcc_unreachable ();
11088 OMP_CLAUSE_LINEAR_STEP (c2
) = OMP_CLAUSE_LINEAR_STEP (c
);
11091 if ((var
!= decl
|| collapse
> 1 || tile
) && orig_for_stmt
== for_stmt
)
11093 for (c
= OMP_FOR_CLAUSES (for_stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
11094 if (((OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
11095 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
) == NULL
)
11096 || (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINEAR
11097 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c
)
11098 && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c
) == NULL
))
11099 && OMP_CLAUSE_DECL (c
) == decl
)
11101 if (is_doacross
&& (collapse
== 1 || i
>= collapse
))
11105 t
= TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
);
11106 gcc_assert (TREE_CODE (t
) == MODIFY_EXPR
);
11107 gcc_assert (TREE_OPERAND (t
, 0) == var
);
11108 t
= TREE_OPERAND (t
, 1);
11109 gcc_assert (TREE_CODE (t
) == PLUS_EXPR
11110 || TREE_CODE (t
) == MINUS_EXPR
11111 || TREE_CODE (t
) == POINTER_PLUS_EXPR
);
11112 gcc_assert (TREE_OPERAND (t
, 0) == var
);
11113 t
= build2 (TREE_CODE (t
), TREE_TYPE (decl
),
11114 is_doacross
? var
: decl
,
11115 TREE_OPERAND (t
, 1));
11118 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
)
11119 seq
= &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
);
11121 seq
= &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c
);
11122 gimplify_assign (decl
, t
, seq
);
11127 BITMAP_FREE (has_decl_expr
);
11129 if (TREE_CODE (orig_for_stmt
) == OMP_TASKLOOP
)
11131 push_gimplify_context ();
11132 if (TREE_CODE (OMP_FOR_BODY (orig_for_stmt
)) != BIND_EXPR
)
11134 OMP_FOR_BODY (orig_for_stmt
)
11135 = build3 (BIND_EXPR
, void_type_node
, NULL
,
11136 OMP_FOR_BODY (orig_for_stmt
), NULL
);
11137 TREE_SIDE_EFFECTS (OMP_FOR_BODY (orig_for_stmt
)) = 1;
11141 gimple
*g
= gimplify_and_return_first (OMP_FOR_BODY (orig_for_stmt
),
11144 if (TREE_CODE (orig_for_stmt
) == OMP_TASKLOOP
)
11146 if (gimple_code (g
) == GIMPLE_BIND
)
11147 pop_gimplify_context (g
);
11149 pop_gimplify_context (NULL
);
11152 if (orig_for_stmt
!= for_stmt
)
11153 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
11155 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), i
);
11156 decl
= TREE_OPERAND (t
, 0);
11157 struct gimplify_omp_ctx
*ctx
= gimplify_omp_ctxp
;
11158 if (TREE_CODE (orig_for_stmt
) == OMP_TASKLOOP
)
11159 gimplify_omp_ctxp
= ctx
->outer_context
;
11160 var
= create_tmp_var (TREE_TYPE (decl
), get_name (decl
));
11161 gimplify_omp_ctxp
= ctx
;
11162 omp_add_variable (gimplify_omp_ctxp
, var
, GOVD_PRIVATE
| GOVD_SEEN
);
11163 TREE_OPERAND (t
, 0) = var
;
11164 t
= TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
);
11165 TREE_OPERAND (t
, 1) = copy_node (TREE_OPERAND (t
, 1));
11166 TREE_OPERAND (TREE_OPERAND (t
, 1), 0) = var
;
11169 gimplify_adjust_omp_clauses (pre_p
, for_body
,
11170 &OMP_FOR_CLAUSES (orig_for_stmt
),
11171 TREE_CODE (orig_for_stmt
));
11174 switch (TREE_CODE (orig_for_stmt
))
11176 case OMP_FOR
: kind
= GF_OMP_FOR_KIND_FOR
; break;
11177 case OMP_SIMD
: kind
= GF_OMP_FOR_KIND_SIMD
; break;
11178 case OMP_DISTRIBUTE
: kind
= GF_OMP_FOR_KIND_DISTRIBUTE
; break;
11179 case OMP_TASKLOOP
: kind
= GF_OMP_FOR_KIND_TASKLOOP
; break;
11180 case OACC_LOOP
: kind
= GF_OMP_FOR_KIND_OACC_LOOP
; break;
11182 gcc_unreachable ();
11184 gfor
= gimple_build_omp_for (for_body
, kind
, OMP_FOR_CLAUSES (orig_for_stmt
),
11185 TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)),
11187 if (orig_for_stmt
!= for_stmt
)
11188 gimple_omp_for_set_combined_p (gfor
, true);
11189 if (gimplify_omp_ctxp
11190 && (gimplify_omp_ctxp
->combined_loop
11191 || (gimplify_omp_ctxp
->region_type
== ORT_COMBINED_PARALLEL
11192 && gimplify_omp_ctxp
->outer_context
11193 && gimplify_omp_ctxp
->outer_context
->combined_loop
)))
11195 gimple_omp_for_set_combined_into_p (gfor
, true);
11196 if (gimplify_omp_ctxp
->combined_loop
)
11197 gcc_assert (TREE_CODE (orig_for_stmt
) == OMP_SIMD
);
11199 gcc_assert (TREE_CODE (orig_for_stmt
) == OMP_FOR
);
11202 for (i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt
)); i
++)
11204 t
= TREE_VEC_ELT (OMP_FOR_INIT (for_stmt
), i
);
11205 gimple_omp_for_set_index (gfor
, i
, TREE_OPERAND (t
, 0));
11206 gimple_omp_for_set_initial (gfor
, i
, TREE_OPERAND (t
, 1));
11207 t
= TREE_VEC_ELT (OMP_FOR_COND (for_stmt
), i
);
11208 gimple_omp_for_set_cond (gfor
, i
, TREE_CODE (t
));
11209 gimple_omp_for_set_final (gfor
, i
, TREE_OPERAND (t
, 1));
11210 t
= TREE_VEC_ELT (OMP_FOR_INCR (for_stmt
), i
);
11211 gimple_omp_for_set_incr (gfor
, i
, TREE_OPERAND (t
, 1));
11214 /* OMP_TASKLOOP is gimplified as two GIMPLE_OMP_FOR taskloop
11215 constructs with GIMPLE_OMP_TASK sandwiched in between them.
11216 The outer taskloop stands for computing the number of iterations,
11217 counts for collapsed loops and holding taskloop specific clauses.
11218 The task construct stands for the effect of data sharing on the
11219 explicit task it creates and the inner taskloop stands for expansion
11220 of the static loop inside of the explicit task construct. */
11221 if (TREE_CODE (orig_for_stmt
) == OMP_TASKLOOP
)
11223 tree
*gfor_clauses_ptr
= gimple_omp_for_clauses_ptr (gfor
);
11224 tree task_clauses
= NULL_TREE
;
11225 tree c
= *gfor_clauses_ptr
;
11226 tree
*gtask_clauses_ptr
= &task_clauses
;
11227 tree outer_for_clauses
= NULL_TREE
;
11228 tree
*gforo_clauses_ptr
= &outer_for_clauses
;
11229 for (; c
; c
= OMP_CLAUSE_CHAIN (c
))
11230 switch (OMP_CLAUSE_CODE (c
))
11232 /* These clauses are allowed on task, move them there. */
11233 case OMP_CLAUSE_SHARED
:
11234 case OMP_CLAUSE_FIRSTPRIVATE
:
11235 case OMP_CLAUSE_DEFAULT
:
11236 case OMP_CLAUSE_IF
:
11237 case OMP_CLAUSE_UNTIED
:
11238 case OMP_CLAUSE_FINAL
:
11239 case OMP_CLAUSE_MERGEABLE
:
11240 case OMP_CLAUSE_PRIORITY
:
11241 case OMP_CLAUSE_REDUCTION
:
11242 case OMP_CLAUSE_IN_REDUCTION
:
11243 *gtask_clauses_ptr
= c
;
11244 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
11246 case OMP_CLAUSE_PRIVATE
:
11247 if (OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c
))
11249 /* We want private on outer for and firstprivate
11252 = build_omp_clause (OMP_CLAUSE_LOCATION (c
),
11253 OMP_CLAUSE_FIRSTPRIVATE
);
11254 OMP_CLAUSE_DECL (*gtask_clauses_ptr
) = OMP_CLAUSE_DECL (c
);
11255 lang_hooks
.decls
.omp_finish_clause (*gtask_clauses_ptr
, NULL
);
11256 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr
);
11257 *gforo_clauses_ptr
= c
;
11258 gforo_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
11262 *gtask_clauses_ptr
= c
;
11263 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
11266 /* These clauses go into outer taskloop clauses. */
11267 case OMP_CLAUSE_GRAINSIZE
:
11268 case OMP_CLAUSE_NUM_TASKS
:
11269 case OMP_CLAUSE_NOGROUP
:
11270 *gforo_clauses_ptr
= c
;
11271 gforo_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
11273 /* Taskloop clause we duplicate on both taskloops. */
11274 case OMP_CLAUSE_COLLAPSE
:
11275 *gfor_clauses_ptr
= c
;
11276 gfor_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
11277 *gforo_clauses_ptr
= copy_node (c
);
11278 gforo_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr
);
11280 /* For lastprivate, keep the clause on inner taskloop, and add
11281 a shared clause on task. If the same decl is also firstprivate,
11282 add also firstprivate clause on the inner taskloop. */
11283 case OMP_CLAUSE_LASTPRIVATE
:
11284 if (OMP_CLAUSE_LASTPRIVATE_TASKLOOP_IV (c
))
11286 /* For taskloop C++ lastprivate IVs, we want:
11287 1) private on outer taskloop
11288 2) firstprivate and shared on task
11289 3) lastprivate on inner taskloop */
11291 = build_omp_clause (OMP_CLAUSE_LOCATION (c
),
11292 OMP_CLAUSE_FIRSTPRIVATE
);
11293 OMP_CLAUSE_DECL (*gtask_clauses_ptr
) = OMP_CLAUSE_DECL (c
);
11294 lang_hooks
.decls
.omp_finish_clause (*gtask_clauses_ptr
, NULL
);
11295 gtask_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr
);
11296 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
) = 1;
11297 *gforo_clauses_ptr
= build_omp_clause (OMP_CLAUSE_LOCATION (c
),
11298 OMP_CLAUSE_PRIVATE
);
11299 OMP_CLAUSE_DECL (*gforo_clauses_ptr
) = OMP_CLAUSE_DECL (c
);
11300 OMP_CLAUSE_PRIVATE_TASKLOOP_IV (*gforo_clauses_ptr
) = 1;
11301 TREE_TYPE (*gforo_clauses_ptr
) = TREE_TYPE (c
);
11302 gforo_clauses_ptr
= &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr
);
11304 *gfor_clauses_ptr
= c
;
11305 gfor_clauses_ptr
= &OMP_CLAUSE_CHAIN (c
);
11307 = build_omp_clause (OMP_CLAUSE_LOCATION (c
), OMP_CLAUSE_SHARED
);
11308 OMP_CLAUSE_DECL (*gtask_clauses_ptr
) = OMP_CLAUSE_DECL (c
);
11309 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
))
11310 OMP_CLAUSE_SHARED_FIRSTPRIVATE (*gtask_clauses_ptr
) = 1;
11312 = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr
);
11315 gcc_unreachable ();
11317 *gfor_clauses_ptr
= NULL_TREE
;
11318 *gtask_clauses_ptr
= NULL_TREE
;
11319 *gforo_clauses_ptr
= NULL_TREE
;
11320 g
= gimple_build_bind (NULL_TREE
, gfor
, NULL_TREE
);
11321 g
= gimple_build_omp_task (g
, task_clauses
, NULL_TREE
, NULL_TREE
,
11322 NULL_TREE
, NULL_TREE
, NULL_TREE
);
11323 gimple_omp_task_set_taskloop_p (g
, true);
11324 g
= gimple_build_bind (NULL_TREE
, g
, NULL_TREE
);
11326 = gimple_build_omp_for (g
, GF_OMP_FOR_KIND_TASKLOOP
, outer_for_clauses
,
11327 gimple_omp_for_collapse (gfor
),
11328 gimple_omp_for_pre_body (gfor
));
11329 gimple_omp_for_set_pre_body (gfor
, NULL
);
11330 gimple_omp_for_set_combined_p (gforo
, true);
11331 gimple_omp_for_set_combined_into_p (gfor
, true);
11332 for (i
= 0; i
< (int) gimple_omp_for_collapse (gfor
); i
++)
11334 tree type
= TREE_TYPE (gimple_omp_for_index (gfor
, i
));
11335 tree v
= create_tmp_var (type
);
11336 gimple_omp_for_set_index (gforo
, i
, v
);
11337 t
= unshare_expr (gimple_omp_for_initial (gfor
, i
));
11338 gimple_omp_for_set_initial (gforo
, i
, t
);
11339 gimple_omp_for_set_cond (gforo
, i
,
11340 gimple_omp_for_cond (gfor
, i
));
11341 t
= unshare_expr (gimple_omp_for_final (gfor
, i
));
11342 gimple_omp_for_set_final (gforo
, i
, t
);
11343 t
= unshare_expr (gimple_omp_for_incr (gfor
, i
));
11344 gcc_assert (TREE_OPERAND (t
, 0) == gimple_omp_for_index (gfor
, i
));
11345 TREE_OPERAND (t
, 0) = v
;
11346 gimple_omp_for_set_incr (gforo
, i
, t
);
11347 t
= build_omp_clause (input_location
, OMP_CLAUSE_PRIVATE
);
11348 OMP_CLAUSE_DECL (t
) = v
;
11349 OMP_CLAUSE_CHAIN (t
) = gimple_omp_for_clauses (gforo
);
11350 gimple_omp_for_set_clauses (gforo
, t
);
11352 gimplify_seq_add_stmt (pre_p
, gforo
);
11355 gimplify_seq_add_stmt (pre_p
, gfor
);
11356 if (ret
!= GS_ALL_DONE
)
11358 *expr_p
= NULL_TREE
;
11359 return GS_ALL_DONE
;
11362 /* Helper function of optimize_target_teams, find OMP_TEAMS inside
11363 of OMP_TARGET's body. */
11366 find_omp_teams (tree
*tp
, int *walk_subtrees
, void *)
11368 *walk_subtrees
= 0;
11369 switch (TREE_CODE (*tp
))
11374 case STATEMENT_LIST
:
11375 *walk_subtrees
= 1;
11383 /* Helper function of optimize_target_teams, determine if the expression
11384 can be computed safely before the target construct on the host. */
11387 computable_teams_clause (tree
*tp
, int *walk_subtrees
, void *)
11393 *walk_subtrees
= 0;
11396 switch (TREE_CODE (*tp
))
11401 *walk_subtrees
= 0;
11402 if (error_operand_p (*tp
)
11403 || !INTEGRAL_TYPE_P (TREE_TYPE (*tp
))
11404 || DECL_HAS_VALUE_EXPR_P (*tp
)
11405 || DECL_THREAD_LOCAL_P (*tp
)
11406 || TREE_SIDE_EFFECTS (*tp
)
11407 || TREE_THIS_VOLATILE (*tp
))
11409 if (is_global_var (*tp
)
11410 && (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (*tp
))
11411 || lookup_attribute ("omp declare target link",
11412 DECL_ATTRIBUTES (*tp
))))
11415 && !DECL_SEEN_IN_BIND_EXPR_P (*tp
)
11416 && !is_global_var (*tp
)
11417 && decl_function_context (*tp
) == current_function_decl
)
11419 n
= splay_tree_lookup (gimplify_omp_ctxp
->variables
,
11420 (splay_tree_key
) *tp
);
11423 if (gimplify_omp_ctxp
->defaultmap
[GDMK_SCALAR
] & GOVD_FIRSTPRIVATE
)
11427 else if (n
->value
& GOVD_LOCAL
)
11429 else if (n
->value
& GOVD_FIRSTPRIVATE
)
11431 else if ((n
->value
& (GOVD_MAP
| GOVD_MAP_ALWAYS_TO
))
11432 == (GOVD_MAP
| GOVD_MAP_ALWAYS_TO
))
11436 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp
)))
11440 if (TARGET_EXPR_INITIAL (*tp
)
11441 || TREE_CODE (TARGET_EXPR_SLOT (*tp
)) != VAR_DECL
)
11443 return computable_teams_clause (&TARGET_EXPR_SLOT (*tp
),
11444 walk_subtrees
, NULL
);
11445 /* Allow some reasonable subset of integral arithmetics. */
11449 case TRUNC_DIV_EXPR
:
11450 case CEIL_DIV_EXPR
:
11451 case FLOOR_DIV_EXPR
:
11452 case ROUND_DIV_EXPR
:
11453 case TRUNC_MOD_EXPR
:
11454 case CEIL_MOD_EXPR
:
11455 case FLOOR_MOD_EXPR
:
11456 case ROUND_MOD_EXPR
:
11458 case EXACT_DIV_EXPR
:
11469 case NON_LVALUE_EXPR
:
11471 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp
)))
11474 /* And disallow anything else, except for comparisons. */
11476 if (COMPARISON_CLASS_P (*tp
))
11482 /* Try to determine if the num_teams and/or thread_limit expressions
11483 can have their values determined already before entering the
11485 INTEGER_CSTs trivially are,
11486 integral decls that are firstprivate (explicitly or implicitly)
11487 or explicitly map(always, to:) or map(always, tofrom:) on the target
11488 region too, and expressions involving simple arithmetics on those
11489 too, function calls are not ok, dereferencing something neither etc.
11490 Add NUM_TEAMS and THREAD_LIMIT clauses to the OMP_CLAUSES of
11491 EXPR based on what we find:
11492 0 stands for clause not specified at all, use implementation default
11493 -1 stands for value that can't be determined easily before entering
11494 the target construct.
11495 If teams construct is not present at all, use 1 for num_teams
11496 and 0 for thread_limit (only one team is involved, and the thread
11497 limit is implementation defined. */
11500 optimize_target_teams (tree target
, gimple_seq
*pre_p
)
11502 tree body
= OMP_BODY (target
);
11503 tree teams
= walk_tree (&body
, find_omp_teams
, NULL
, NULL
);
11504 tree num_teams
= integer_zero_node
;
11505 tree thread_limit
= integer_zero_node
;
11506 location_t num_teams_loc
= EXPR_LOCATION (target
);
11507 location_t thread_limit_loc
= EXPR_LOCATION (target
);
11509 struct gimplify_omp_ctx
*target_ctx
= gimplify_omp_ctxp
;
11511 if (teams
== NULL_TREE
)
11512 num_teams
= integer_one_node
;
11514 for (c
= OMP_TEAMS_CLAUSES (teams
); c
; c
= OMP_CLAUSE_CHAIN (c
))
11516 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_NUM_TEAMS
)
11519 num_teams_loc
= OMP_CLAUSE_LOCATION (c
);
11521 else if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_THREAD_LIMIT
)
11524 thread_limit_loc
= OMP_CLAUSE_LOCATION (c
);
11528 expr
= OMP_CLAUSE_OPERAND (c
, 0);
11529 if (TREE_CODE (expr
) == INTEGER_CST
)
11534 if (walk_tree (&expr
, computable_teams_clause
, NULL
, NULL
))
11536 *p
= integer_minus_one_node
;
11540 gimplify_omp_ctxp
= gimplify_omp_ctxp
->outer_context
;
11541 if (gimplify_expr (p
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
, false)
11544 gimplify_omp_ctxp
= target_ctx
;
11545 *p
= integer_minus_one_node
;
11548 gimplify_omp_ctxp
= target_ctx
;
11549 if (!DECL_P (expr
) && TREE_CODE (expr
) != TARGET_EXPR
)
11550 OMP_CLAUSE_OPERAND (c
, 0) = *p
;
11552 c
= build_omp_clause (thread_limit_loc
, OMP_CLAUSE_THREAD_LIMIT
);
11553 OMP_CLAUSE_THREAD_LIMIT_EXPR (c
) = thread_limit
;
11554 OMP_CLAUSE_CHAIN (c
) = OMP_TARGET_CLAUSES (target
);
11555 OMP_TARGET_CLAUSES (target
) = c
;
11556 c
= build_omp_clause (num_teams_loc
, OMP_CLAUSE_NUM_TEAMS
);
11557 OMP_CLAUSE_NUM_TEAMS_EXPR (c
) = num_teams
;
11558 OMP_CLAUSE_CHAIN (c
) = OMP_TARGET_CLAUSES (target
);
11559 OMP_TARGET_CLAUSES (target
) = c
;
11562 /* Gimplify the gross structure of several OMP constructs. */
11565 gimplify_omp_workshare (tree
*expr_p
, gimple_seq
*pre_p
)
11567 tree expr
= *expr_p
;
11569 gimple_seq body
= NULL
;
11570 enum omp_region_type ort
;
11572 switch (TREE_CODE (expr
))
11576 ort
= ORT_WORKSHARE
;
11579 ort
= OMP_TARGET_COMBINED (expr
) ? ORT_COMBINED_TARGET
: ORT_TARGET
;
11582 ort
= ORT_ACC_KERNELS
;
11584 case OACC_PARALLEL
:
11585 ort
= ORT_ACC_PARALLEL
;
11588 ort
= ORT_ACC_DATA
;
11590 case OMP_TARGET_DATA
:
11591 ort
= ORT_TARGET_DATA
;
11594 ort
= OMP_TEAMS_COMBINED (expr
) ? ORT_COMBINED_TEAMS
: ORT_TEAMS
;
11595 if (gimplify_omp_ctxp
== NULL
11596 || (gimplify_omp_ctxp
->region_type
== ORT_TARGET
11597 && gimplify_omp_ctxp
->outer_context
== NULL
11598 && lookup_attribute ("omp declare target",
11599 DECL_ATTRIBUTES (current_function_decl
))))
11600 ort
= (enum omp_region_type
) (ort
| ORT_HOST_TEAMS
);
11602 case OACC_HOST_DATA
:
11603 ort
= ORT_ACC_HOST_DATA
;
11606 gcc_unreachable ();
11608 gimplify_scan_omp_clauses (&OMP_CLAUSES (expr
), pre_p
, ort
,
11610 if (TREE_CODE (expr
) == OMP_TARGET
)
11611 optimize_target_teams (expr
, pre_p
);
11612 if ((ort
& (ORT_TARGET
| ORT_TARGET_DATA
)) != 0
11613 || (ort
& ORT_HOST_TEAMS
) == ORT_HOST_TEAMS
)
11615 push_gimplify_context ();
11616 gimple
*g
= gimplify_and_return_first (OMP_BODY (expr
), &body
);
11617 if (gimple_code (g
) == GIMPLE_BIND
)
11618 pop_gimplify_context (g
);
11620 pop_gimplify_context (NULL
);
11621 if ((ort
& ORT_TARGET_DATA
) != 0)
11623 enum built_in_function end_ix
;
11624 switch (TREE_CODE (expr
))
11627 case OACC_HOST_DATA
:
11628 end_ix
= BUILT_IN_GOACC_DATA_END
;
11630 case OMP_TARGET_DATA
:
11631 end_ix
= BUILT_IN_GOMP_TARGET_END_DATA
;
11634 gcc_unreachable ();
11636 tree fn
= builtin_decl_explicit (end_ix
);
11637 g
= gimple_build_call (fn
, 0);
11638 gimple_seq cleanup
= NULL
;
11639 gimple_seq_add_stmt (&cleanup
, g
);
11640 g
= gimple_build_try (body
, cleanup
, GIMPLE_TRY_FINALLY
);
11642 gimple_seq_add_stmt (&body
, g
);
11646 gimplify_and_add (OMP_BODY (expr
), &body
);
11647 gimplify_adjust_omp_clauses (pre_p
, body
, &OMP_CLAUSES (expr
),
11650 switch (TREE_CODE (expr
))
11653 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_OACC_DATA
,
11654 OMP_CLAUSES (expr
));
11657 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_OACC_KERNELS
,
11658 OMP_CLAUSES (expr
));
11660 case OACC_HOST_DATA
:
11661 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_OACC_HOST_DATA
,
11662 OMP_CLAUSES (expr
));
11664 case OACC_PARALLEL
:
11665 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_OACC_PARALLEL
,
11666 OMP_CLAUSES (expr
));
11669 stmt
= gimple_build_omp_sections (body
, OMP_CLAUSES (expr
));
11672 stmt
= gimple_build_omp_single (body
, OMP_CLAUSES (expr
));
11675 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_REGION
,
11676 OMP_CLAUSES (expr
));
11678 case OMP_TARGET_DATA
:
11679 stmt
= gimple_build_omp_target (body
, GF_OMP_TARGET_KIND_DATA
,
11680 OMP_CLAUSES (expr
));
11683 stmt
= gimple_build_omp_teams (body
, OMP_CLAUSES (expr
));
11684 if ((ort
& ORT_HOST_TEAMS
) == ORT_HOST_TEAMS
)
11685 gimple_omp_teams_set_host (as_a
<gomp_teams
*> (stmt
), true);
11688 gcc_unreachable ();
11691 gimplify_seq_add_stmt (pre_p
, stmt
);
11692 *expr_p
= NULL_TREE
;
11695 /* Gimplify the gross structure of OpenACC enter/exit data, update, and OpenMP
11696 target update constructs. */
11699 gimplify_omp_target_update (tree
*expr_p
, gimple_seq
*pre_p
)
11701 tree expr
= *expr_p
;
11704 enum omp_region_type ort
= ORT_WORKSHARE
;
11706 switch (TREE_CODE (expr
))
11708 case OACC_ENTER_DATA
:
11709 case OACC_EXIT_DATA
:
11710 kind
= GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA
;
11714 kind
= GF_OMP_TARGET_KIND_OACC_UPDATE
;
11717 case OMP_TARGET_UPDATE
:
11718 kind
= GF_OMP_TARGET_KIND_UPDATE
;
11720 case OMP_TARGET_ENTER_DATA
:
11721 kind
= GF_OMP_TARGET_KIND_ENTER_DATA
;
11723 case OMP_TARGET_EXIT_DATA
:
11724 kind
= GF_OMP_TARGET_KIND_EXIT_DATA
;
11727 gcc_unreachable ();
11729 gimplify_scan_omp_clauses (&OMP_STANDALONE_CLAUSES (expr
), pre_p
,
11730 ort
, TREE_CODE (expr
));
11731 gimplify_adjust_omp_clauses (pre_p
, NULL
, &OMP_STANDALONE_CLAUSES (expr
),
11733 if (TREE_CODE (expr
) == OACC_UPDATE
11734 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr
),
11735 OMP_CLAUSE_IF_PRESENT
))
11737 /* The runtime uses GOMP_MAP_{TO,FROM} to denote the if_present
11739 for (tree c
= OMP_STANDALONE_CLAUSES (expr
); c
; c
= OMP_CLAUSE_CHAIN (c
))
11740 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_MAP
)
11741 switch (OMP_CLAUSE_MAP_KIND (c
))
11743 case GOMP_MAP_FORCE_TO
:
11744 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_TO
);
11746 case GOMP_MAP_FORCE_FROM
:
11747 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_FROM
);
11753 else if (TREE_CODE (expr
) == OACC_EXIT_DATA
11754 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr
),
11755 OMP_CLAUSE_FINALIZE
))
11757 /* Use GOMP_MAP_DELETE/GOMP_MAP_FORCE_FROM to denote that "finalize"
11758 semantics apply to all mappings of this OpenACC directive. */
11759 bool finalize_marked
= false;
11760 for (tree c
= OMP_STANDALONE_CLAUSES (expr
); c
; c
= OMP_CLAUSE_CHAIN (c
))
11761 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_MAP
)
11762 switch (OMP_CLAUSE_MAP_KIND (c
))
11764 case GOMP_MAP_FROM
:
11765 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_FORCE_FROM
);
11766 finalize_marked
= true;
11768 case GOMP_MAP_RELEASE
:
11769 OMP_CLAUSE_SET_MAP_KIND (c
, GOMP_MAP_DELETE
);
11770 finalize_marked
= true;
11773 /* Check consistency: libgomp relies on the very first data
11774 mapping clause being marked, so make sure we did that before
11775 any other mapping clauses. */
11776 gcc_assert (finalize_marked
);
11780 stmt
= gimple_build_omp_target (NULL
, kind
, OMP_STANDALONE_CLAUSES (expr
));
11782 gimplify_seq_add_stmt (pre_p
, stmt
);
11783 *expr_p
= NULL_TREE
;
11786 /* A subroutine of gimplify_omp_atomic. The front end is supposed to have
11787 stabilized the lhs of the atomic operation as *ADDR. Return true if
11788 EXPR is this stabilized form. */
11791 goa_lhs_expr_p (tree expr
, tree addr
)
11793 /* Also include casts to other type variants. The C front end is fond
11794 of adding these for e.g. volatile variables. This is like
11795 STRIP_TYPE_NOPS but includes the main variant lookup. */
11796 STRIP_USELESS_TYPE_CONVERSION (expr
);
11798 if (TREE_CODE (expr
) == INDIRECT_REF
)
11800 expr
= TREE_OPERAND (expr
, 0);
11801 while (expr
!= addr
11802 && (CONVERT_EXPR_P (expr
)
11803 || TREE_CODE (expr
) == NON_LVALUE_EXPR
)
11804 && TREE_CODE (expr
) == TREE_CODE (addr
)
11805 && types_compatible_p (TREE_TYPE (expr
), TREE_TYPE (addr
)))
11807 expr
= TREE_OPERAND (expr
, 0);
11808 addr
= TREE_OPERAND (addr
, 0);
11812 return (TREE_CODE (addr
) == ADDR_EXPR
11813 && TREE_CODE (expr
) == ADDR_EXPR
11814 && TREE_OPERAND (addr
, 0) == TREE_OPERAND (expr
, 0));
11816 if (TREE_CODE (addr
) == ADDR_EXPR
&& expr
== TREE_OPERAND (addr
, 0))
11821 /* Walk *EXPR_P and replace appearances of *LHS_ADDR with LHS_VAR. If an
11822 expression does not involve the lhs, evaluate it into a temporary.
11823 Return 1 if the lhs appeared as a subexpression, 0 if it did not,
11824 or -1 if an error was encountered. */
11827 goa_stabilize_expr (tree
*expr_p
, gimple_seq
*pre_p
, tree lhs_addr
,
11830 tree expr
= *expr_p
;
11833 if (goa_lhs_expr_p (expr
, lhs_addr
))
11838 if (is_gimple_val (expr
))
11842 switch (TREE_CODE_CLASS (TREE_CODE (expr
)))
11845 case tcc_comparison
:
11846 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 1), pre_p
, lhs_addr
,
11850 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 0), pre_p
, lhs_addr
,
11853 case tcc_expression
:
11854 switch (TREE_CODE (expr
))
11856 case TRUTH_ANDIF_EXPR
:
11857 case TRUTH_ORIF_EXPR
:
11858 case TRUTH_AND_EXPR
:
11859 case TRUTH_OR_EXPR
:
11860 case TRUTH_XOR_EXPR
:
11861 case BIT_INSERT_EXPR
:
11862 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 1), pre_p
,
11863 lhs_addr
, lhs_var
);
11865 case TRUTH_NOT_EXPR
:
11866 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 0), pre_p
,
11867 lhs_addr
, lhs_var
);
11869 case COMPOUND_EXPR
:
11870 /* Break out any preevaluations from cp_build_modify_expr. */
11871 for (; TREE_CODE (expr
) == COMPOUND_EXPR
;
11872 expr
= TREE_OPERAND (expr
, 1))
11873 gimplify_stmt (&TREE_OPERAND (expr
, 0), pre_p
);
11875 return goa_stabilize_expr (expr_p
, pre_p
, lhs_addr
, lhs_var
);
11880 case tcc_reference
:
11881 if (TREE_CODE (expr
) == BIT_FIELD_REF
)
11882 saw_lhs
|= goa_stabilize_expr (&TREE_OPERAND (expr
, 0), pre_p
,
11883 lhs_addr
, lhs_var
);
11891 enum gimplify_status gs
;
11892 gs
= gimplify_expr (expr_p
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
11893 if (gs
!= GS_ALL_DONE
)
11900 /* Gimplify an OMP_ATOMIC statement. */
11902 static enum gimplify_status
11903 gimplify_omp_atomic (tree
*expr_p
, gimple_seq
*pre_p
)
11905 tree addr
= TREE_OPERAND (*expr_p
, 0);
11906 tree rhs
= TREE_CODE (*expr_p
) == OMP_ATOMIC_READ
11907 ? NULL
: TREE_OPERAND (*expr_p
, 1);
11908 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr
)));
11910 gomp_atomic_load
*loadstmt
;
11911 gomp_atomic_store
*storestmt
;
11913 tmp_load
= create_tmp_reg (type
);
11914 if (rhs
&& goa_stabilize_expr (&rhs
, pre_p
, addr
, tmp_load
) < 0)
11917 if (gimplify_expr (&addr
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
)
11921 loadstmt
= gimple_build_omp_atomic_load (tmp_load
, addr
,
11922 OMP_ATOMIC_MEMORY_ORDER (*expr_p
));
11923 gimplify_seq_add_stmt (pre_p
, loadstmt
);
11924 if (rhs
&& gimplify_expr (&rhs
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
)
11928 if (TREE_CODE (*expr_p
) == OMP_ATOMIC_READ
)
11931 = gimple_build_omp_atomic_store (rhs
, OMP_ATOMIC_MEMORY_ORDER (*expr_p
));
11932 gimplify_seq_add_stmt (pre_p
, storestmt
);
11933 switch (TREE_CODE (*expr_p
))
11935 case OMP_ATOMIC_READ
:
11936 case OMP_ATOMIC_CAPTURE_OLD
:
11937 *expr_p
= tmp_load
;
11938 gimple_omp_atomic_set_need_value (loadstmt
);
11940 case OMP_ATOMIC_CAPTURE_NEW
:
11942 gimple_omp_atomic_set_need_value (storestmt
);
11949 return GS_ALL_DONE
;
11952 /* Gimplify a TRANSACTION_EXPR. This involves gimplification of the
11953 body, and adding some EH bits. */
11955 static enum gimplify_status
11956 gimplify_transaction (tree
*expr_p
, gimple_seq
*pre_p
)
11958 tree expr
= *expr_p
, temp
, tbody
= TRANSACTION_EXPR_BODY (expr
);
11960 gtransaction
*trans_stmt
;
11961 gimple_seq body
= NULL
;
11964 /* Wrap the transaction body in a BIND_EXPR so we have a context
11965 where to put decls for OMP. */
11966 if (TREE_CODE (tbody
) != BIND_EXPR
)
11968 tree bind
= build3 (BIND_EXPR
, void_type_node
, NULL
, tbody
, NULL
);
11969 TREE_SIDE_EFFECTS (bind
) = 1;
11970 SET_EXPR_LOCATION (bind
, EXPR_LOCATION (tbody
));
11971 TRANSACTION_EXPR_BODY (expr
) = bind
;
11974 push_gimplify_context ();
11975 temp
= voidify_wrapper_expr (*expr_p
, NULL
);
11977 body_stmt
= gimplify_and_return_first (TRANSACTION_EXPR_BODY (expr
), &body
);
11978 pop_gimplify_context (body_stmt
);
11980 trans_stmt
= gimple_build_transaction (body
);
11981 if (TRANSACTION_EXPR_OUTER (expr
))
11982 subcode
= GTMA_IS_OUTER
;
11983 else if (TRANSACTION_EXPR_RELAXED (expr
))
11984 subcode
= GTMA_IS_RELAXED
;
11985 gimple_transaction_set_subcode (trans_stmt
, subcode
);
11987 gimplify_seq_add_stmt (pre_p
, trans_stmt
);
11995 *expr_p
= NULL_TREE
;
11996 return GS_ALL_DONE
;
11999 /* Gimplify an OMP_ORDERED construct. EXPR is the tree version. BODY
12000 is the OMP_BODY of the original EXPR (which has already been
12001 gimplified so it's not present in the EXPR).
12003 Return the gimplified GIMPLE_OMP_ORDERED tuple. */
12006 gimplify_omp_ordered (tree expr
, gimple_seq body
)
12011 tree source_c
= NULL_TREE
;
12012 tree sink_c
= NULL_TREE
;
12014 if (gimplify_omp_ctxp
)
12016 for (c
= OMP_ORDERED_CLAUSES (expr
); c
; c
= OMP_CLAUSE_CHAIN (c
))
12017 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEPEND
12018 && gimplify_omp_ctxp
->loop_iter_var
.is_empty ()
12019 && (OMP_CLAUSE_DEPEND_KIND (c
) == OMP_CLAUSE_DEPEND_SINK
12020 || OMP_CLAUSE_DEPEND_KIND (c
) == OMP_CLAUSE_DEPEND_SOURCE
))
12022 error_at (OMP_CLAUSE_LOCATION (c
),
12023 "%<ordered%> construct with %<depend%> clause must be "
12024 "closely nested inside a loop with %<ordered%> clause "
12025 "with a parameter");
12028 else if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEPEND
12029 && OMP_CLAUSE_DEPEND_KIND (c
) == OMP_CLAUSE_DEPEND_SINK
)
12032 for (decls
= OMP_CLAUSE_DECL (c
), i
= 0;
12033 decls
&& TREE_CODE (decls
) == TREE_LIST
;
12034 decls
= TREE_CHAIN (decls
), ++i
)
12035 if (i
>= gimplify_omp_ctxp
->loop_iter_var
.length () / 2)
12037 else if (TREE_VALUE (decls
)
12038 != gimplify_omp_ctxp
->loop_iter_var
[2 * i
])
12040 error_at (OMP_CLAUSE_LOCATION (c
),
12041 "variable %qE is not an iteration "
12042 "of outermost loop %d, expected %qE",
12043 TREE_VALUE (decls
), i
+ 1,
12044 gimplify_omp_ctxp
->loop_iter_var
[2 * i
]);
12050 = gimplify_omp_ctxp
->loop_iter_var
[2 * i
+ 1];
12051 if (!fail
&& i
!= gimplify_omp_ctxp
->loop_iter_var
.length () / 2)
12053 error_at (OMP_CLAUSE_LOCATION (c
),
12054 "number of variables in %<depend(sink)%> "
12055 "clause does not match number of "
12056 "iteration variables");
12061 else if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEPEND
12062 && OMP_CLAUSE_DEPEND_KIND (c
) == OMP_CLAUSE_DEPEND_SOURCE
)
12066 error_at (OMP_CLAUSE_LOCATION (c
),
12067 "more than one %<depend(source)%> clause on an "
12068 "%<ordered%> construct");
12075 if (source_c
&& sink_c
)
12077 error_at (OMP_CLAUSE_LOCATION (source_c
),
12078 "%<depend(source)%> clause specified together with "
12079 "%<depend(sink:)%> clauses on the same construct");
12084 return gimple_build_nop ();
12085 return gimple_build_omp_ordered (body
, OMP_ORDERED_CLAUSES (expr
));
12088 /* Convert the GENERIC expression tree *EXPR_P to GIMPLE. If the
12089 expression produces a value to be used as an operand inside a GIMPLE
12090 statement, the value will be stored back in *EXPR_P. This value will
12091 be a tree of class tcc_declaration, tcc_constant, tcc_reference or
12092 an SSA_NAME. The corresponding sequence of GIMPLE statements is
12093 emitted in PRE_P and POST_P.
12095 Additionally, this process may overwrite parts of the input
12096 expression during gimplification. Ideally, it should be
12097 possible to do non-destructive gimplification.
12099 EXPR_P points to the GENERIC expression to convert to GIMPLE. If
12100 the expression needs to evaluate to a value to be used as
12101 an operand in a GIMPLE statement, this value will be stored in
12102 *EXPR_P on exit. This happens when the caller specifies one
12103 of fb_lvalue or fb_rvalue fallback flags.
12105 PRE_P will contain the sequence of GIMPLE statements corresponding
12106 to the evaluation of EXPR and all the side-effects that must
12107 be executed before the main expression. On exit, the last
12108 statement of PRE_P is the core statement being gimplified. For
12109 instance, when gimplifying 'if (++a)' the last statement in
12110 PRE_P will be 'if (t.1)' where t.1 is the result of
12111 pre-incrementing 'a'.
12113 POST_P will contain the sequence of GIMPLE statements corresponding
12114 to the evaluation of all the side-effects that must be executed
12115 after the main expression. If this is NULL, the post
12116 side-effects are stored at the end of PRE_P.
12118 The reason why the output is split in two is to handle post
12119 side-effects explicitly. In some cases, an expression may have
12120 inner and outer post side-effects which need to be emitted in
12121 an order different from the one given by the recursive
12122 traversal. For instance, for the expression (*p--)++ the post
12123 side-effects of '--' must actually occur *after* the post
12124 side-effects of '++'. However, gimplification will first visit
12125 the inner expression, so if a separate POST sequence was not
12126 used, the resulting sequence would be:
12133 However, the post-decrement operation in line #2 must not be
12134 evaluated until after the store to *p at line #4, so the
12135 correct sequence should be:
12142 So, by specifying a separate post queue, it is possible
12143 to emit the post side-effects in the correct order.
12144 If POST_P is NULL, an internal queue will be used. Before
12145 returning to the caller, the sequence POST_P is appended to
12146 the main output sequence PRE_P.
12148 GIMPLE_TEST_F points to a function that takes a tree T and
12149 returns nonzero if T is in the GIMPLE form requested by the
12150 caller. The GIMPLE predicates are in gimple.c.
12152 FALLBACK tells the function what sort of a temporary we want if
12153 gimplification cannot produce an expression that complies with
12156 fb_none means that no temporary should be generated
12157 fb_rvalue means that an rvalue is OK to generate
12158 fb_lvalue means that an lvalue is OK to generate
12159 fb_either means that either is OK, but an lvalue is preferable.
12160 fb_mayfail means that gimplification may fail (in which case
12161 GS_ERROR will be returned)
12163 The return value is either GS_ERROR or GS_ALL_DONE, since this
12164 function iterates until EXPR is completely gimplified or an error
12167 enum gimplify_status
12168 gimplify_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
12169 bool (*gimple_test_f
) (tree
), fallback_t fallback
)
12172 gimple_seq internal_pre
= NULL
;
12173 gimple_seq internal_post
= NULL
;
12176 location_t saved_location
;
12177 enum gimplify_status ret
;
12178 gimple_stmt_iterator pre_last_gsi
, post_last_gsi
;
12181 save_expr
= *expr_p
;
12182 if (save_expr
== NULL_TREE
)
12183 return GS_ALL_DONE
;
12185 /* If we are gimplifying a top-level statement, PRE_P must be valid. */
12186 is_statement
= gimple_test_f
== is_gimple_stmt
;
12188 gcc_assert (pre_p
);
12190 /* Consistency checks. */
12191 if (gimple_test_f
== is_gimple_reg
)
12192 gcc_assert (fallback
& (fb_rvalue
| fb_lvalue
));
12193 else if (gimple_test_f
== is_gimple_val
12194 || gimple_test_f
== is_gimple_call_addr
12195 || gimple_test_f
== is_gimple_condexpr
12196 || gimple_test_f
== is_gimple_mem_rhs
12197 || gimple_test_f
== is_gimple_mem_rhs_or_call
12198 || gimple_test_f
== is_gimple_reg_rhs
12199 || gimple_test_f
== is_gimple_reg_rhs_or_call
12200 || gimple_test_f
== is_gimple_asm_val
12201 || gimple_test_f
== is_gimple_mem_ref_addr
)
12202 gcc_assert (fallback
& fb_rvalue
);
12203 else if (gimple_test_f
== is_gimple_min_lval
12204 || gimple_test_f
== is_gimple_lvalue
)
12205 gcc_assert (fallback
& fb_lvalue
);
12206 else if (gimple_test_f
== is_gimple_addressable
)
12207 gcc_assert (fallback
& fb_either
);
12208 else if (gimple_test_f
== is_gimple_stmt
)
12209 gcc_assert (fallback
== fb_none
);
12212 /* We should have recognized the GIMPLE_TEST_F predicate to
12213 know what kind of fallback to use in case a temporary is
12214 needed to hold the value or address of *EXPR_P. */
12215 gcc_unreachable ();
12218 /* We used to check the predicate here and return immediately if it
12219 succeeds. This is wrong; the design is for gimplification to be
12220 idempotent, and for the predicates to only test for valid forms, not
12221 whether they are fully simplified. */
12223 pre_p
= &internal_pre
;
12225 if (post_p
== NULL
)
12226 post_p
= &internal_post
;
12228 /* Remember the last statements added to PRE_P and POST_P. Every
12229 new statement added by the gimplification helpers needs to be
12230 annotated with location information. To centralize the
12231 responsibility, we remember the last statement that had been
12232 added to both queues before gimplifying *EXPR_P. If
12233 gimplification produces new statements in PRE_P and POST_P, those
12234 statements will be annotated with the same location information
12236 pre_last_gsi
= gsi_last (*pre_p
);
12237 post_last_gsi
= gsi_last (*post_p
);
12239 saved_location
= input_location
;
12240 if (save_expr
!= error_mark_node
12241 && EXPR_HAS_LOCATION (*expr_p
))
12242 input_location
= EXPR_LOCATION (*expr_p
);
12244 /* Loop over the specific gimplifiers until the toplevel node
12245 remains the same. */
12248 /* Strip away as many useless type conversions as possible
12249 at the toplevel. */
12250 STRIP_USELESS_TYPE_CONVERSION (*expr_p
);
12252 /* Remember the expr. */
12253 save_expr
= *expr_p
;
12255 /* Die, die, die, my darling. */
12256 if (error_operand_p (save_expr
))
12262 /* Do any language-specific gimplification. */
12263 ret
= ((enum gimplify_status
)
12264 lang_hooks
.gimplify_expr (expr_p
, pre_p
, post_p
));
12267 if (*expr_p
== NULL_TREE
)
12269 if (*expr_p
!= save_expr
)
12272 else if (ret
!= GS_UNHANDLED
)
12275 /* Make sure that all the cases set 'ret' appropriately. */
12276 ret
= GS_UNHANDLED
;
12277 switch (TREE_CODE (*expr_p
))
12279 /* First deal with the special cases. */
12281 case POSTINCREMENT_EXPR
:
12282 case POSTDECREMENT_EXPR
:
12283 case PREINCREMENT_EXPR
:
12284 case PREDECREMENT_EXPR
:
12285 ret
= gimplify_self_mod_expr (expr_p
, pre_p
, post_p
,
12286 fallback
!= fb_none
,
12287 TREE_TYPE (*expr_p
));
12290 case VIEW_CONVERT_EXPR
:
12291 if (is_gimple_reg_type (TREE_TYPE (*expr_p
))
12292 && is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (*expr_p
, 0))))
12294 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
12295 post_p
, is_gimple_val
, fb_rvalue
);
12296 recalculate_side_effects (*expr_p
);
12302 case ARRAY_RANGE_REF
:
12303 case REALPART_EXPR
:
12304 case IMAGPART_EXPR
:
12305 case COMPONENT_REF
:
12306 ret
= gimplify_compound_lval (expr_p
, pre_p
, post_p
,
12307 fallback
? fallback
: fb_rvalue
);
12311 ret
= gimplify_cond_expr (expr_p
, pre_p
, fallback
);
12313 /* C99 code may assign to an array in a structure value of a
12314 conditional expression, and this has undefined behavior
12315 only on execution, so create a temporary if an lvalue is
12317 if (fallback
== fb_lvalue
)
12319 *expr_p
= get_initialized_tmp_var (*expr_p
, pre_p
, post_p
, false);
12320 mark_addressable (*expr_p
);
12326 ret
= gimplify_call_expr (expr_p
, pre_p
, fallback
!= fb_none
);
12328 /* C99 code may assign to an array in a structure returned
12329 from a function, and this has undefined behavior only on
12330 execution, so create a temporary if an lvalue is
12332 if (fallback
== fb_lvalue
)
12334 *expr_p
= get_initialized_tmp_var (*expr_p
, pre_p
, post_p
, false);
12335 mark_addressable (*expr_p
);
12341 gcc_unreachable ();
12343 case COMPOUND_EXPR
:
12344 ret
= gimplify_compound_expr (expr_p
, pre_p
, fallback
!= fb_none
);
12347 case COMPOUND_LITERAL_EXPR
:
12348 ret
= gimplify_compound_literal_expr (expr_p
, pre_p
,
12349 gimple_test_f
, fallback
);
12354 ret
= gimplify_modify_expr (expr_p
, pre_p
, post_p
,
12355 fallback
!= fb_none
);
12358 case TRUTH_ANDIF_EXPR
:
12359 case TRUTH_ORIF_EXPR
:
12361 /* Preserve the original type of the expression and the
12362 source location of the outer expression. */
12363 tree org_type
= TREE_TYPE (*expr_p
);
12364 *expr_p
= gimple_boolify (*expr_p
);
12365 *expr_p
= build3_loc (input_location
, COND_EXPR
,
12369 org_type
, boolean_true_node
),
12372 org_type
, boolean_false_node
));
12377 case TRUTH_NOT_EXPR
:
12379 tree type
= TREE_TYPE (*expr_p
);
12380 /* The parsers are careful to generate TRUTH_NOT_EXPR
12381 only with operands that are always zero or one.
12382 We do not fold here but handle the only interesting case
12383 manually, as fold may re-introduce the TRUTH_NOT_EXPR. */
12384 *expr_p
= gimple_boolify (*expr_p
);
12385 if (TYPE_PRECISION (TREE_TYPE (*expr_p
)) == 1)
12386 *expr_p
= build1_loc (input_location
, BIT_NOT_EXPR
,
12387 TREE_TYPE (*expr_p
),
12388 TREE_OPERAND (*expr_p
, 0));
12390 *expr_p
= build2_loc (input_location
, BIT_XOR_EXPR
,
12391 TREE_TYPE (*expr_p
),
12392 TREE_OPERAND (*expr_p
, 0),
12393 build_int_cst (TREE_TYPE (*expr_p
), 1));
12394 if (!useless_type_conversion_p (type
, TREE_TYPE (*expr_p
)))
12395 *expr_p
= fold_convert_loc (input_location
, type
, *expr_p
);
12401 ret
= gimplify_addr_expr (expr_p
, pre_p
, post_p
);
12404 case ANNOTATE_EXPR
:
12406 tree cond
= TREE_OPERAND (*expr_p
, 0);
12407 tree kind
= TREE_OPERAND (*expr_p
, 1);
12408 tree data
= TREE_OPERAND (*expr_p
, 2);
12409 tree type
= TREE_TYPE (cond
);
12410 if (!INTEGRAL_TYPE_P (type
))
12416 tree tmp
= create_tmp_var (type
);
12417 gimplify_arg (&cond
, pre_p
, EXPR_LOCATION (*expr_p
));
12419 = gimple_build_call_internal (IFN_ANNOTATE
, 3, cond
, kind
, data
);
12420 gimple_call_set_lhs (call
, tmp
);
12421 gimplify_seq_add_stmt (pre_p
, call
);
12428 ret
= gimplify_va_arg_expr (expr_p
, pre_p
, post_p
);
12432 if (IS_EMPTY_STMT (*expr_p
))
12438 if (VOID_TYPE_P (TREE_TYPE (*expr_p
))
12439 || fallback
== fb_none
)
12441 /* Just strip a conversion to void (or in void context) and
12443 *expr_p
= TREE_OPERAND (*expr_p
, 0);
12448 ret
= gimplify_conversion (expr_p
);
12449 if (ret
== GS_ERROR
)
12451 if (*expr_p
!= save_expr
)
12455 case FIX_TRUNC_EXPR
:
12456 /* unary_expr: ... | '(' cast ')' val | ... */
12457 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
12458 is_gimple_val
, fb_rvalue
);
12459 recalculate_side_effects (*expr_p
);
12464 bool volatilep
= TREE_THIS_VOLATILE (*expr_p
);
12465 bool notrap
= TREE_THIS_NOTRAP (*expr_p
);
12466 tree saved_ptr_type
= TREE_TYPE (TREE_OPERAND (*expr_p
, 0));
12468 *expr_p
= fold_indirect_ref_loc (input_location
, *expr_p
);
12469 if (*expr_p
!= save_expr
)
12475 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
12476 is_gimple_reg
, fb_rvalue
);
12477 if (ret
== GS_ERROR
)
12480 recalculate_side_effects (*expr_p
);
12481 *expr_p
= fold_build2_loc (input_location
, MEM_REF
,
12482 TREE_TYPE (*expr_p
),
12483 TREE_OPERAND (*expr_p
, 0),
12484 build_int_cst (saved_ptr_type
, 0));
12485 TREE_THIS_VOLATILE (*expr_p
) = volatilep
;
12486 TREE_THIS_NOTRAP (*expr_p
) = notrap
;
12491 /* We arrive here through the various re-gimplifcation paths. */
12493 /* First try re-folding the whole thing. */
12494 tmp
= fold_binary (MEM_REF
, TREE_TYPE (*expr_p
),
12495 TREE_OPERAND (*expr_p
, 0),
12496 TREE_OPERAND (*expr_p
, 1));
12499 REF_REVERSE_STORAGE_ORDER (tmp
)
12500 = REF_REVERSE_STORAGE_ORDER (*expr_p
);
12502 recalculate_side_effects (*expr_p
);
12506 /* Avoid re-gimplifying the address operand if it is already
12507 in suitable form. Re-gimplifying would mark the address
12508 operand addressable. Always gimplify when not in SSA form
12509 as we still may have to gimplify decls with value-exprs. */
12510 if (!gimplify_ctxp
|| !gimple_in_ssa_p (cfun
)
12511 || !is_gimple_mem_ref_addr (TREE_OPERAND (*expr_p
, 0)))
12513 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
12514 is_gimple_mem_ref_addr
, fb_rvalue
);
12515 if (ret
== GS_ERROR
)
12518 recalculate_side_effects (*expr_p
);
12522 /* Constants need not be gimplified. */
12529 /* Drop the overflow flag on constants, we do not want
12530 that in the GIMPLE IL. */
12531 if (TREE_OVERFLOW_P (*expr_p
))
12532 *expr_p
= drop_tree_overflow (*expr_p
);
12537 /* If we require an lvalue, such as for ADDR_EXPR, retain the
12538 CONST_DECL node. Otherwise the decl is replaceable by its
12540 /* ??? Should be == fb_lvalue, but ADDR_EXPR passes fb_either. */
12541 if (fallback
& fb_lvalue
)
12545 *expr_p
= DECL_INITIAL (*expr_p
);
12551 ret
= gimplify_decl_expr (expr_p
, pre_p
);
12555 ret
= gimplify_bind_expr (expr_p
, pre_p
);
12559 ret
= gimplify_loop_expr (expr_p
, pre_p
);
12563 ret
= gimplify_switch_expr (expr_p
, pre_p
);
12567 ret
= gimplify_exit_expr (expr_p
);
12571 /* If the target is not LABEL, then it is a computed jump
12572 and the target needs to be gimplified. */
12573 if (TREE_CODE (GOTO_DESTINATION (*expr_p
)) != LABEL_DECL
)
12575 ret
= gimplify_expr (&GOTO_DESTINATION (*expr_p
), pre_p
,
12576 NULL
, is_gimple_val
, fb_rvalue
);
12577 if (ret
== GS_ERROR
)
12580 gimplify_seq_add_stmt (pre_p
,
12581 gimple_build_goto (GOTO_DESTINATION (*expr_p
)));
12586 gimplify_seq_add_stmt (pre_p
,
12587 gimple_build_predict (PREDICT_EXPR_PREDICTOR (*expr_p
),
12588 PREDICT_EXPR_OUTCOME (*expr_p
)));
12593 ret
= gimplify_label_expr (expr_p
, pre_p
);
12594 label
= LABEL_EXPR_LABEL (*expr_p
);
12595 gcc_assert (decl_function_context (label
) == current_function_decl
);
12597 /* If the label is used in a goto statement, or address of the label
12598 is taken, we need to unpoison all variables that were seen so far.
12599 Doing so would prevent us from reporting a false positives. */
12600 if (asan_poisoned_variables
12601 && asan_used_labels
!= NULL
12602 && asan_used_labels
->contains (label
))
12603 asan_poison_variables (asan_poisoned_variables
, false, pre_p
);
12606 case CASE_LABEL_EXPR
:
12607 ret
= gimplify_case_label_expr (expr_p
, pre_p
);
12609 if (gimplify_ctxp
->live_switch_vars
)
12610 asan_poison_variables (gimplify_ctxp
->live_switch_vars
, false,
12615 ret
= gimplify_return_expr (*expr_p
, pre_p
);
12619 /* Don't reduce this in place; let gimplify_init_constructor work its
12620 magic. Buf if we're just elaborating this for side effects, just
12621 gimplify any element that has side-effects. */
12622 if (fallback
== fb_none
)
12624 unsigned HOST_WIDE_INT ix
;
12626 tree temp
= NULL_TREE
;
12627 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (*expr_p
), ix
, val
)
12628 if (TREE_SIDE_EFFECTS (val
))
12629 append_to_statement_list (val
, &temp
);
12632 ret
= temp
? GS_OK
: GS_ALL_DONE
;
12634 /* C99 code may assign to an array in a constructed
12635 structure or union, and this has undefined behavior only
12636 on execution, so create a temporary if an lvalue is
12638 else if (fallback
== fb_lvalue
)
12640 *expr_p
= get_initialized_tmp_var (*expr_p
, pre_p
, post_p
, false);
12641 mark_addressable (*expr_p
);
12648 /* The following are special cases that are not handled by the
12649 original GIMPLE grammar. */
12651 /* SAVE_EXPR nodes are converted into a GIMPLE identifier and
12654 ret
= gimplify_save_expr (expr_p
, pre_p
, post_p
);
12657 case BIT_FIELD_REF
:
12658 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
12659 post_p
, is_gimple_lvalue
, fb_either
);
12660 recalculate_side_effects (*expr_p
);
12663 case TARGET_MEM_REF
:
12665 enum gimplify_status r0
= GS_ALL_DONE
, r1
= GS_ALL_DONE
;
12667 if (TMR_BASE (*expr_p
))
12668 r0
= gimplify_expr (&TMR_BASE (*expr_p
), pre_p
,
12669 post_p
, is_gimple_mem_ref_addr
, fb_either
);
12670 if (TMR_INDEX (*expr_p
))
12671 r1
= gimplify_expr (&TMR_INDEX (*expr_p
), pre_p
,
12672 post_p
, is_gimple_val
, fb_rvalue
);
12673 if (TMR_INDEX2 (*expr_p
))
12674 r1
= gimplify_expr (&TMR_INDEX2 (*expr_p
), pre_p
,
12675 post_p
, is_gimple_val
, fb_rvalue
);
12676 /* TMR_STEP and TMR_OFFSET are always integer constants. */
12677 ret
= MIN (r0
, r1
);
12681 case NON_LVALUE_EXPR
:
12682 /* This should have been stripped above. */
12683 gcc_unreachable ();
12686 ret
= gimplify_asm_expr (expr_p
, pre_p
, post_p
);
12689 case TRY_FINALLY_EXPR
:
12690 case TRY_CATCH_EXPR
:
12692 gimple_seq eval
, cleanup
;
12695 /* Calls to destructors are generated automatically in FINALLY/CATCH
12696 block. They should have location as UNKNOWN_LOCATION. However,
12697 gimplify_call_expr will reset these call stmts to input_location
12698 if it finds stmt's location is unknown. To prevent resetting for
12699 destructors, we set the input_location to unknown.
12700 Note that this only affects the destructor calls in FINALLY/CATCH
12701 block, and will automatically reset to its original value by the
12702 end of gimplify_expr. */
12703 input_location
= UNKNOWN_LOCATION
;
12704 eval
= cleanup
= NULL
;
12705 gimplify_and_add (TREE_OPERAND (*expr_p
, 0), &eval
);
12706 gimplify_and_add (TREE_OPERAND (*expr_p
, 1), &cleanup
);
12707 /* Don't create bogus GIMPLE_TRY with empty cleanup. */
12708 if (gimple_seq_empty_p (cleanup
))
12710 gimple_seq_add_seq (pre_p
, eval
);
12714 try_
= gimple_build_try (eval
, cleanup
,
12715 TREE_CODE (*expr_p
) == TRY_FINALLY_EXPR
12716 ? GIMPLE_TRY_FINALLY
12717 : GIMPLE_TRY_CATCH
);
12718 if (EXPR_HAS_LOCATION (save_expr
))
12719 gimple_set_location (try_
, EXPR_LOCATION (save_expr
));
12720 else if (LOCATION_LOCUS (saved_location
) != UNKNOWN_LOCATION
)
12721 gimple_set_location (try_
, saved_location
);
12722 if (TREE_CODE (*expr_p
) == TRY_CATCH_EXPR
)
12723 gimple_try_set_catch_is_cleanup (try_
,
12724 TRY_CATCH_IS_CLEANUP (*expr_p
));
12725 gimplify_seq_add_stmt (pre_p
, try_
);
12730 case CLEANUP_POINT_EXPR
:
12731 ret
= gimplify_cleanup_point_expr (expr_p
, pre_p
);
12735 ret
= gimplify_target_expr (expr_p
, pre_p
, post_p
);
12741 gimple_seq handler
= NULL
;
12742 gimplify_and_add (CATCH_BODY (*expr_p
), &handler
);
12743 c
= gimple_build_catch (CATCH_TYPES (*expr_p
), handler
);
12744 gimplify_seq_add_stmt (pre_p
, c
);
12749 case EH_FILTER_EXPR
:
12752 gimple_seq failure
= NULL
;
12754 gimplify_and_add (EH_FILTER_FAILURE (*expr_p
), &failure
);
12755 ehf
= gimple_build_eh_filter (EH_FILTER_TYPES (*expr_p
), failure
);
12756 gimple_set_no_warning (ehf
, TREE_NO_WARNING (*expr_p
));
12757 gimplify_seq_add_stmt (pre_p
, ehf
);
12764 enum gimplify_status r0
, r1
;
12765 r0
= gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p
), pre_p
,
12766 post_p
, is_gimple_val
, fb_rvalue
);
12767 r1
= gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p
), pre_p
,
12768 post_p
, is_gimple_val
, fb_rvalue
);
12769 TREE_SIDE_EFFECTS (*expr_p
) = 0;
12770 ret
= MIN (r0
, r1
);
12775 /* We get here when taking the address of a label. We mark
12776 the label as "forced"; meaning it can never be removed and
12777 it is a potential target for any computed goto. */
12778 FORCED_LABEL (*expr_p
) = 1;
12782 case STATEMENT_LIST
:
12783 ret
= gimplify_statement_list (expr_p
, pre_p
);
12786 case WITH_SIZE_EXPR
:
12788 gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
12789 post_p
== &internal_post
? NULL
: post_p
,
12790 gimple_test_f
, fallback
);
12791 gimplify_expr (&TREE_OPERAND (*expr_p
, 1), pre_p
, post_p
,
12792 is_gimple_val
, fb_rvalue
);
12799 ret
= gimplify_var_or_parm_decl (expr_p
);
12803 /* When within an OMP context, notice uses of variables. */
12804 if (gimplify_omp_ctxp
)
12805 omp_notice_variable (gimplify_omp_ctxp
, *expr_p
, true);
12809 case DEBUG_EXPR_DECL
:
12810 gcc_unreachable ();
12812 case DEBUG_BEGIN_STMT
:
12813 gimplify_seq_add_stmt (pre_p
,
12814 gimple_build_debug_begin_stmt
12815 (TREE_BLOCK (*expr_p
),
12816 EXPR_LOCATION (*expr_p
)));
12822 /* Allow callbacks into the gimplifier during optimization. */
12827 gimplify_omp_parallel (expr_p
, pre_p
);
12832 gimplify_omp_task (expr_p
, pre_p
);
12838 case OMP_DISTRIBUTE
:
12841 ret
= gimplify_omp_for (expr_p
, pre_p
);
12845 gimplify_oacc_cache (expr_p
, pre_p
);
12850 gimplify_oacc_declare (expr_p
, pre_p
);
12854 case OACC_HOST_DATA
:
12857 case OACC_PARALLEL
:
12861 case OMP_TARGET_DATA
:
12863 gimplify_omp_workshare (expr_p
, pre_p
);
12867 case OACC_ENTER_DATA
:
12868 case OACC_EXIT_DATA
:
12870 case OMP_TARGET_UPDATE
:
12871 case OMP_TARGET_ENTER_DATA
:
12872 case OMP_TARGET_EXIT_DATA
:
12873 gimplify_omp_target_update (expr_p
, pre_p
);
12882 gimple_seq body
= NULL
;
12885 gimplify_and_add (OMP_BODY (*expr_p
), &body
);
12886 switch (TREE_CODE (*expr_p
))
12889 g
= gimple_build_omp_section (body
);
12892 g
= gimple_build_omp_master (body
);
12895 g
= gimplify_omp_ordered (*expr_p
, body
);
12898 gimplify_scan_omp_clauses (&OMP_CRITICAL_CLAUSES (*expr_p
),
12899 pre_p
, ORT_WORKSHARE
, OMP_CRITICAL
);
12900 gimplify_adjust_omp_clauses (pre_p
, body
,
12901 &OMP_CRITICAL_CLAUSES (*expr_p
),
12903 g
= gimple_build_omp_critical (body
,
12904 OMP_CRITICAL_NAME (*expr_p
),
12905 OMP_CRITICAL_CLAUSES (*expr_p
));
12908 gcc_unreachable ();
12910 gimplify_seq_add_stmt (pre_p
, g
);
12915 case OMP_TASKGROUP
:
12917 gimple_seq body
= NULL
;
12919 tree
*pclauses
= &OMP_TASKGROUP_CLAUSES (*expr_p
);
12920 gimplify_scan_omp_clauses (pclauses
, pre_p
, ORT_TASKGROUP
,
12922 gimplify_adjust_omp_clauses (pre_p
, NULL
, pclauses
, OMP_TASKGROUP
);
12923 gimplify_and_add (OMP_BODY (*expr_p
), &body
);
12924 gimple_seq cleanup
= NULL
;
12925 tree fn
= builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_END
);
12926 gimple
*g
= gimple_build_call (fn
, 0);
12927 gimple_seq_add_stmt (&cleanup
, g
);
12928 g
= gimple_build_try (body
, cleanup
, GIMPLE_TRY_FINALLY
);
12930 gimple_seq_add_stmt (&body
, g
);
12931 g
= gimple_build_omp_taskgroup (body
, *pclauses
);
12932 gimplify_seq_add_stmt (pre_p
, g
);
12938 case OMP_ATOMIC_READ
:
12939 case OMP_ATOMIC_CAPTURE_OLD
:
12940 case OMP_ATOMIC_CAPTURE_NEW
:
12941 ret
= gimplify_omp_atomic (expr_p
, pre_p
);
12944 case TRANSACTION_EXPR
:
12945 ret
= gimplify_transaction (expr_p
, pre_p
);
12948 case TRUTH_AND_EXPR
:
12949 case TRUTH_OR_EXPR
:
12950 case TRUTH_XOR_EXPR
:
12952 tree orig_type
= TREE_TYPE (*expr_p
);
12953 tree new_type
, xop0
, xop1
;
12954 *expr_p
= gimple_boolify (*expr_p
);
12955 new_type
= TREE_TYPE (*expr_p
);
12956 if (!useless_type_conversion_p (orig_type
, new_type
))
12958 *expr_p
= fold_convert_loc (input_location
, orig_type
, *expr_p
);
12963 /* Boolified binary truth expressions are semantically equivalent
12964 to bitwise binary expressions. Canonicalize them to the
12965 bitwise variant. */
12966 switch (TREE_CODE (*expr_p
))
12968 case TRUTH_AND_EXPR
:
12969 TREE_SET_CODE (*expr_p
, BIT_AND_EXPR
);
12971 case TRUTH_OR_EXPR
:
12972 TREE_SET_CODE (*expr_p
, BIT_IOR_EXPR
);
12974 case TRUTH_XOR_EXPR
:
12975 TREE_SET_CODE (*expr_p
, BIT_XOR_EXPR
);
12980 /* Now make sure that operands have compatible type to
12981 expression's new_type. */
12982 xop0
= TREE_OPERAND (*expr_p
, 0);
12983 xop1
= TREE_OPERAND (*expr_p
, 1);
12984 if (!useless_type_conversion_p (new_type
, TREE_TYPE (xop0
)))
12985 TREE_OPERAND (*expr_p
, 0) = fold_convert_loc (input_location
,
12988 if (!useless_type_conversion_p (new_type
, TREE_TYPE (xop1
)))
12989 TREE_OPERAND (*expr_p
, 1) = fold_convert_loc (input_location
,
12992 /* Continue classified as tcc_binary. */
12996 case VEC_COND_EXPR
:
12998 enum gimplify_status r0
, r1
, r2
;
13000 r0
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
13001 post_p
, is_gimple_condexpr
, fb_rvalue
);
13002 r1
= gimplify_expr (&TREE_OPERAND (*expr_p
, 1), pre_p
,
13003 post_p
, is_gimple_val
, fb_rvalue
);
13004 r2
= gimplify_expr (&TREE_OPERAND (*expr_p
, 2), pre_p
,
13005 post_p
, is_gimple_val
, fb_rvalue
);
13007 ret
= MIN (MIN (r0
, r1
), r2
);
13008 recalculate_side_effects (*expr_p
);
13012 case VEC_PERM_EXPR
:
13013 /* Classified as tcc_expression. */
13016 case BIT_INSERT_EXPR
:
13017 /* Argument 3 is a constant. */
13020 case POINTER_PLUS_EXPR
:
13022 enum gimplify_status r0
, r1
;
13023 r0
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
13024 post_p
, is_gimple_val
, fb_rvalue
);
13025 r1
= gimplify_expr (&TREE_OPERAND (*expr_p
, 1), pre_p
,
13026 post_p
, is_gimple_val
, fb_rvalue
);
13027 recalculate_side_effects (*expr_p
);
13028 ret
= MIN (r0
, r1
);
13033 switch (TREE_CODE_CLASS (TREE_CODE (*expr_p
)))
13035 case tcc_comparison
:
13036 /* Handle comparison of objects of non scalar mode aggregates
13037 with a call to memcmp. It would be nice to only have to do
13038 this for variable-sized objects, but then we'd have to allow
13039 the same nest of reference nodes we allow for MODIFY_EXPR and
13040 that's too complex.
13042 Compare scalar mode aggregates as scalar mode values. Using
13043 memcmp for them would be very inefficient at best, and is
13044 plain wrong if bitfields are involved. */
13046 tree type
= TREE_TYPE (TREE_OPERAND (*expr_p
, 1));
13048 /* Vector comparisons need no boolification. */
13049 if (TREE_CODE (type
) == VECTOR_TYPE
)
13051 else if (!AGGREGATE_TYPE_P (type
))
13053 tree org_type
= TREE_TYPE (*expr_p
);
13054 *expr_p
= gimple_boolify (*expr_p
);
13055 if (!useless_type_conversion_p (org_type
,
13056 TREE_TYPE (*expr_p
)))
13058 *expr_p
= fold_convert_loc (input_location
,
13059 org_type
, *expr_p
);
13065 else if (TYPE_MODE (type
) != BLKmode
)
13066 ret
= gimplify_scalar_mode_aggregate_compare (expr_p
);
13068 ret
= gimplify_variable_sized_compare (expr_p
);
13073 /* If *EXPR_P does not need to be special-cased, handle it
13074 according to its class. */
13076 ret
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
13077 post_p
, is_gimple_val
, fb_rvalue
);
13083 enum gimplify_status r0
, r1
;
13085 r0
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
13086 post_p
, is_gimple_val
, fb_rvalue
);
13087 r1
= gimplify_expr (&TREE_OPERAND (*expr_p
, 1), pre_p
,
13088 post_p
, is_gimple_val
, fb_rvalue
);
13090 ret
= MIN (r0
, r1
);
13096 enum gimplify_status r0
, r1
, r2
;
13098 r0
= gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
,
13099 post_p
, is_gimple_val
, fb_rvalue
);
13100 r1
= gimplify_expr (&TREE_OPERAND (*expr_p
, 1), pre_p
,
13101 post_p
, is_gimple_val
, fb_rvalue
);
13102 r2
= gimplify_expr (&TREE_OPERAND (*expr_p
, 2), pre_p
,
13103 post_p
, is_gimple_val
, fb_rvalue
);
13105 ret
= MIN (MIN (r0
, r1
), r2
);
13109 case tcc_declaration
:
13112 goto dont_recalculate
;
13115 gcc_unreachable ();
13118 recalculate_side_effects (*expr_p
);
13124 gcc_assert (*expr_p
|| ret
!= GS_OK
);
13126 while (ret
== GS_OK
);
13128 /* If we encountered an error_mark somewhere nested inside, either
13129 stub out the statement or propagate the error back out. */
13130 if (ret
== GS_ERROR
)
13137 /* This was only valid as a return value from the langhook, which
13138 we handled. Make sure it doesn't escape from any other context. */
13139 gcc_assert (ret
!= GS_UNHANDLED
);
13141 if (fallback
== fb_none
&& *expr_p
&& !is_gimple_stmt (*expr_p
))
13143 /* We aren't looking for a value, and we don't have a valid
13144 statement. If it doesn't have side-effects, throw it away.
13145 We can also get here with code such as "*&&L;", where L is
13146 a LABEL_DECL that is marked as FORCED_LABEL. */
13147 if (TREE_CODE (*expr_p
) == LABEL_DECL
13148 || !TREE_SIDE_EFFECTS (*expr_p
))
13150 else if (!TREE_THIS_VOLATILE (*expr_p
))
13152 /* This is probably a _REF that contains something nested that
13153 has side effects. Recurse through the operands to find it. */
13154 enum tree_code code
= TREE_CODE (*expr_p
);
13158 case COMPONENT_REF
:
13159 case REALPART_EXPR
:
13160 case IMAGPART_EXPR
:
13161 case VIEW_CONVERT_EXPR
:
13162 gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
13163 gimple_test_f
, fallback
);
13167 case ARRAY_RANGE_REF
:
13168 gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
13169 gimple_test_f
, fallback
);
13170 gimplify_expr (&TREE_OPERAND (*expr_p
, 1), pre_p
, post_p
,
13171 gimple_test_f
, fallback
);
13175 /* Anything else with side-effects must be converted to
13176 a valid statement before we get here. */
13177 gcc_unreachable ();
13182 else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p
))
13183 && TYPE_MODE (TREE_TYPE (*expr_p
)) != BLKmode
)
13185 /* Historically, the compiler has treated a bare reference
13186 to a non-BLKmode volatile lvalue as forcing a load. */
13187 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p
));
13189 /* Normally, we do not want to create a temporary for a
13190 TREE_ADDRESSABLE type because such a type should not be
13191 copied by bitwise-assignment. However, we make an
13192 exception here, as all we are doing here is ensuring that
13193 we read the bytes that make up the type. We use
13194 create_tmp_var_raw because create_tmp_var will abort when
13195 given a TREE_ADDRESSABLE type. */
13196 tree tmp
= create_tmp_var_raw (type
, "vol");
13197 gimple_add_tmp_var (tmp
);
13198 gimplify_assign (tmp
, *expr_p
, pre_p
);
13202 /* We can't do anything useful with a volatile reference to
13203 an incomplete type, so just throw it away. Likewise for
13204 a BLKmode type, since any implicit inner load should
13205 already have been turned into an explicit one by the
13206 gimplification process. */
13210 /* If we are gimplifying at the statement level, we're done. Tack
13211 everything together and return. */
13212 if (fallback
== fb_none
|| is_statement
)
13214 /* Since *EXPR_P has been converted into a GIMPLE tuple, clear
13215 it out for GC to reclaim it. */
13216 *expr_p
= NULL_TREE
;
13218 if (!gimple_seq_empty_p (internal_pre
)
13219 || !gimple_seq_empty_p (internal_post
))
13221 gimplify_seq_add_seq (&internal_pre
, internal_post
);
13222 gimplify_seq_add_seq (pre_p
, internal_pre
);
13225 /* The result of gimplifying *EXPR_P is going to be the last few
13226 statements in *PRE_P and *POST_P. Add location information
13227 to all the statements that were added by the gimplification
13229 if (!gimple_seq_empty_p (*pre_p
))
13230 annotate_all_with_location_after (*pre_p
, pre_last_gsi
, input_location
);
13232 if (!gimple_seq_empty_p (*post_p
))
13233 annotate_all_with_location_after (*post_p
, post_last_gsi
,
13239 #ifdef ENABLE_GIMPLE_CHECKING
13242 enum tree_code code
= TREE_CODE (*expr_p
);
13243 /* These expressions should already be in gimple IR form. */
13244 gcc_assert (code
!= MODIFY_EXPR
13245 && code
!= ASM_EXPR
13246 && code
!= BIND_EXPR
13247 && code
!= CATCH_EXPR
13248 && (code
!= COND_EXPR
|| gimplify_ctxp
->allow_rhs_cond_expr
)
13249 && code
!= EH_FILTER_EXPR
13250 && code
!= GOTO_EXPR
13251 && code
!= LABEL_EXPR
13252 && code
!= LOOP_EXPR
13253 && code
!= SWITCH_EXPR
13254 && code
!= TRY_FINALLY_EXPR
13255 && code
!= OACC_PARALLEL
13256 && code
!= OACC_KERNELS
13257 && code
!= OACC_DATA
13258 && code
!= OACC_HOST_DATA
13259 && code
!= OACC_DECLARE
13260 && code
!= OACC_UPDATE
13261 && code
!= OACC_ENTER_DATA
13262 && code
!= OACC_EXIT_DATA
13263 && code
!= OACC_CACHE
13264 && code
!= OMP_CRITICAL
13266 && code
!= OACC_LOOP
13267 && code
!= OMP_MASTER
13268 && code
!= OMP_TASKGROUP
13269 && code
!= OMP_ORDERED
13270 && code
!= OMP_PARALLEL
13271 && code
!= OMP_SECTIONS
13272 && code
!= OMP_SECTION
13273 && code
!= OMP_SINGLE
);
13277 /* Otherwise we're gimplifying a subexpression, so the resulting
13278 value is interesting. If it's a valid operand that matches
13279 GIMPLE_TEST_F, we're done. Unless we are handling some
13280 post-effects internally; if that's the case, we need to copy into
13281 a temporary before adding the post-effects to POST_P. */
13282 if (gimple_seq_empty_p (internal_post
) && (*gimple_test_f
) (*expr_p
))
13285 /* Otherwise, we need to create a new temporary for the gimplified
13288 /* We can't return an lvalue if we have an internal postqueue. The
13289 object the lvalue refers to would (probably) be modified by the
13290 postqueue; we need to copy the value out first, which means an
13292 if ((fallback
& fb_lvalue
)
13293 && gimple_seq_empty_p (internal_post
)
13294 && is_gimple_addressable (*expr_p
))
13296 /* An lvalue will do. Take the address of the expression, store it
13297 in a temporary, and replace the expression with an INDIRECT_REF of
13299 tree ref_alias_type
= reference_alias_ptr_type (*expr_p
);
13300 unsigned int ref_align
= get_object_alignment (*expr_p
);
13301 tree ref_type
= TREE_TYPE (*expr_p
);
13302 tmp
= build_fold_addr_expr_loc (input_location
, *expr_p
);
13303 gimplify_expr (&tmp
, pre_p
, post_p
, is_gimple_reg
, fb_rvalue
);
13304 if (TYPE_ALIGN (ref_type
) != ref_align
)
13305 ref_type
= build_aligned_type (ref_type
, ref_align
);
13306 *expr_p
= build2 (MEM_REF
, ref_type
,
13307 tmp
, build_zero_cst (ref_alias_type
));
13309 else if ((fallback
& fb_rvalue
) && is_gimple_reg_rhs_or_call (*expr_p
))
13311 /* An rvalue will do. Assign the gimplified expression into a
13312 new temporary TMP and replace the original expression with
13313 TMP. First, make sure that the expression has a type so that
13314 it can be assigned into a temporary. */
13315 gcc_assert (!VOID_TYPE_P (TREE_TYPE (*expr_p
)));
13316 *expr_p
= get_formal_tmp_var (*expr_p
, pre_p
);
13320 #ifdef ENABLE_GIMPLE_CHECKING
13321 if (!(fallback
& fb_mayfail
))
13323 fprintf (stderr
, "gimplification failed:\n");
13324 print_generic_expr (stderr
, *expr_p
);
13325 debug_tree (*expr_p
);
13326 internal_error ("gimplification failed");
13329 gcc_assert (fallback
& fb_mayfail
);
13331 /* If this is an asm statement, and the user asked for the
13332 impossible, don't die. Fail and let gimplify_asm_expr
13338 /* Make sure the temporary matches our predicate. */
13339 gcc_assert ((*gimple_test_f
) (*expr_p
));
13341 if (!gimple_seq_empty_p (internal_post
))
13343 annotate_all_with_location (internal_post
, input_location
);
13344 gimplify_seq_add_seq (pre_p
, internal_post
);
13348 input_location
= saved_location
;
13352 /* Like gimplify_expr but make sure the gimplified result is not itself
13353 a SSA name (but a decl if it were). Temporaries required by
13354 evaluating *EXPR_P may be still SSA names. */
13356 static enum gimplify_status
13357 gimplify_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
13358 bool (*gimple_test_f
) (tree
), fallback_t fallback
,
13361 bool was_ssa_name_p
= TREE_CODE (*expr_p
) == SSA_NAME
;
13362 enum gimplify_status ret
= gimplify_expr (expr_p
, pre_p
, post_p
,
13363 gimple_test_f
, fallback
);
13365 && TREE_CODE (*expr_p
) == SSA_NAME
)
13367 tree name
= *expr_p
;
13368 if (was_ssa_name_p
)
13369 *expr_p
= get_initialized_tmp_var (*expr_p
, pre_p
, NULL
, false);
13372 /* Avoid the extra copy if possible. */
13373 *expr_p
= create_tmp_reg (TREE_TYPE (name
));
13374 gimple_set_lhs (SSA_NAME_DEF_STMT (name
), *expr_p
);
13375 release_ssa_name (name
);
13381 /* Look through TYPE for variable-sized objects and gimplify each such
13382 size that we find. Add to LIST_P any statements generated. */
13385 gimplify_type_sizes (tree type
, gimple_seq
*list_p
)
13389 if (type
== NULL
|| type
== error_mark_node
)
13392 /* We first do the main variant, then copy into any other variants. */
13393 type
= TYPE_MAIN_VARIANT (type
);
13395 /* Avoid infinite recursion. */
13396 if (TYPE_SIZES_GIMPLIFIED (type
))
13399 TYPE_SIZES_GIMPLIFIED (type
) = 1;
13401 switch (TREE_CODE (type
))
13404 case ENUMERAL_TYPE
:
13407 case FIXED_POINT_TYPE
:
13408 gimplify_one_sizepos (&TYPE_MIN_VALUE (type
), list_p
);
13409 gimplify_one_sizepos (&TYPE_MAX_VALUE (type
), list_p
);
13411 for (t
= TYPE_NEXT_VARIANT (type
); t
; t
= TYPE_NEXT_VARIANT (t
))
13413 TYPE_MIN_VALUE (t
) = TYPE_MIN_VALUE (type
);
13414 TYPE_MAX_VALUE (t
) = TYPE_MAX_VALUE (type
);
13419 /* These types may not have declarations, so handle them here. */
13420 gimplify_type_sizes (TREE_TYPE (type
), list_p
);
13421 gimplify_type_sizes (TYPE_DOMAIN (type
), list_p
);
13422 /* Ensure VLA bounds aren't removed, for -O0 they should be variables
13423 with assigned stack slots, for -O1+ -g they should be tracked
13425 if (!(TYPE_NAME (type
)
13426 && TREE_CODE (TYPE_NAME (type
)) == TYPE_DECL
13427 && DECL_IGNORED_P (TYPE_NAME (type
)))
13428 && TYPE_DOMAIN (type
)
13429 && INTEGRAL_TYPE_P (TYPE_DOMAIN (type
)))
13431 t
= TYPE_MIN_VALUE (TYPE_DOMAIN (type
));
13432 if (t
&& VAR_P (t
) && DECL_ARTIFICIAL (t
))
13433 DECL_IGNORED_P (t
) = 0;
13434 t
= TYPE_MAX_VALUE (TYPE_DOMAIN (type
));
13435 if (t
&& VAR_P (t
) && DECL_ARTIFICIAL (t
))
13436 DECL_IGNORED_P (t
) = 0;
13442 case QUAL_UNION_TYPE
:
13443 for (field
= TYPE_FIELDS (type
); field
; field
= DECL_CHAIN (field
))
13444 if (TREE_CODE (field
) == FIELD_DECL
)
13446 gimplify_one_sizepos (&DECL_FIELD_OFFSET (field
), list_p
);
13447 gimplify_one_sizepos (&DECL_SIZE (field
), list_p
);
13448 gimplify_one_sizepos (&DECL_SIZE_UNIT (field
), list_p
);
13449 gimplify_type_sizes (TREE_TYPE (field
), list_p
);
13454 case REFERENCE_TYPE
:
13455 /* We used to recurse on the pointed-to type here, which turned out to
13456 be incorrect because its definition might refer to variables not
13457 yet initialized at this point if a forward declaration is involved.
13459 It was actually useful for anonymous pointed-to types to ensure
13460 that the sizes evaluation dominates every possible later use of the
13461 values. Restricting to such types here would be safe since there
13462 is no possible forward declaration around, but would introduce an
13463 undesirable middle-end semantic to anonymity. We then defer to
13464 front-ends the responsibility of ensuring that the sizes are
13465 evaluated both early and late enough, e.g. by attaching artificial
13466 type declarations to the tree. */
13473 gimplify_one_sizepos (&TYPE_SIZE (type
), list_p
);
13474 gimplify_one_sizepos (&TYPE_SIZE_UNIT (type
), list_p
);
13476 for (t
= TYPE_NEXT_VARIANT (type
); t
; t
= TYPE_NEXT_VARIANT (t
))
13478 TYPE_SIZE (t
) = TYPE_SIZE (type
);
13479 TYPE_SIZE_UNIT (t
) = TYPE_SIZE_UNIT (type
);
13480 TYPE_SIZES_GIMPLIFIED (t
) = 1;
13484 /* A subroutine of gimplify_type_sizes to make sure that *EXPR_P,
13485 a size or position, has had all of its SAVE_EXPRs evaluated.
13486 We add any required statements to *STMT_P. */
13489 gimplify_one_sizepos (tree
*expr_p
, gimple_seq
*stmt_p
)
13491 tree expr
= *expr_p
;
13493 /* We don't do anything if the value isn't there, is constant, or contains
13494 A PLACEHOLDER_EXPR. We also don't want to do anything if it's already
13495 a VAR_DECL. If it's a VAR_DECL from another function, the gimplifier
13496 will want to replace it with a new variable, but that will cause problems
13497 if this type is from outside the function. It's OK to have that here. */
13498 if (expr
== NULL_TREE
13499 || is_gimple_constant (expr
)
13500 || TREE_CODE (expr
) == VAR_DECL
13501 || CONTAINS_PLACEHOLDER_P (expr
))
13504 *expr_p
= unshare_expr (expr
);
13506 /* SSA names in decl/type fields are a bad idea - they'll get reclaimed
13507 if the def vanishes. */
13508 gimplify_expr (expr_p
, stmt_p
, NULL
, is_gimple_val
, fb_rvalue
, false);
13510 /* If expr wasn't already is_gimple_sizepos or is_gimple_constant from the
13511 FE, ensure that it is a VAR_DECL, otherwise we might handle some decls
13512 as gimplify_vla_decl even when they would have all sizes INTEGER_CSTs. */
13513 if (is_gimple_constant (*expr_p
))
13514 *expr_p
= get_initialized_tmp_var (*expr_p
, stmt_p
, NULL
, false);
13517 /* Gimplify the body of statements of FNDECL and return a GIMPLE_BIND node
13518 containing the sequence of corresponding GIMPLE statements. If DO_PARMS
13519 is true, also gimplify the parameters. */
13522 gimplify_body (tree fndecl
, bool do_parms
)
13524 location_t saved_location
= input_location
;
13525 gimple_seq parm_stmts
, parm_cleanup
= NULL
, seq
;
13526 gimple
*outer_stmt
;
13529 timevar_push (TV_TREE_GIMPLIFY
);
13531 init_tree_ssa (cfun
);
13533 /* Initialize for optimize_insn_for_s{ize,peed}_p possibly called during
13535 default_rtl_profile ();
13537 gcc_assert (gimplify_ctxp
== NULL
);
13538 push_gimplify_context (true);
13540 if (flag_openacc
|| flag_openmp
)
13542 gcc_assert (gimplify_omp_ctxp
== NULL
);
13543 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (fndecl
)))
13544 gimplify_omp_ctxp
= new_omp_context (ORT_TARGET
);
13547 /* Unshare most shared trees in the body and in that of any nested functions.
13548 It would seem we don't have to do this for nested functions because
13549 they are supposed to be output and then the outer function gimplified
13550 first, but the g++ front end doesn't always do it that way. */
13551 unshare_body (fndecl
);
13552 unvisit_body (fndecl
);
13554 /* Make sure input_location isn't set to something weird. */
13555 input_location
= DECL_SOURCE_LOCATION (fndecl
);
13557 /* Resolve callee-copies. This has to be done before processing
13558 the body so that DECL_VALUE_EXPR gets processed correctly. */
13559 parm_stmts
= do_parms
? gimplify_parameters (&parm_cleanup
) : NULL
;
13561 /* Gimplify the function's body. */
13563 gimplify_stmt (&DECL_SAVED_TREE (fndecl
), &seq
);
13564 outer_stmt
= gimple_seq_first_stmt (seq
);
13567 outer_stmt
= gimple_build_nop ();
13568 gimplify_seq_add_stmt (&seq
, outer_stmt
);
13571 /* The body must contain exactly one statement, a GIMPLE_BIND. If this is
13572 not the case, wrap everything in a GIMPLE_BIND to make it so. */
13573 if (gimple_code (outer_stmt
) == GIMPLE_BIND
13574 && gimple_seq_first (seq
) == gimple_seq_last (seq
))
13575 outer_bind
= as_a
<gbind
*> (outer_stmt
);
13577 outer_bind
= gimple_build_bind (NULL_TREE
, seq
, NULL
);
13579 DECL_SAVED_TREE (fndecl
) = NULL_TREE
;
13581 /* If we had callee-copies statements, insert them at the beginning
13582 of the function and clear DECL_VALUE_EXPR_P on the parameters. */
13583 if (!gimple_seq_empty_p (parm_stmts
))
13587 gimplify_seq_add_seq (&parm_stmts
, gimple_bind_body (outer_bind
));
13590 gtry
*g
= gimple_build_try (parm_stmts
, parm_cleanup
,
13591 GIMPLE_TRY_FINALLY
);
13593 gimple_seq_add_stmt (&parm_stmts
, g
);
13595 gimple_bind_set_body (outer_bind
, parm_stmts
);
13597 for (parm
= DECL_ARGUMENTS (current_function_decl
);
13598 parm
; parm
= DECL_CHAIN (parm
))
13599 if (DECL_HAS_VALUE_EXPR_P (parm
))
13601 DECL_HAS_VALUE_EXPR_P (parm
) = 0;
13602 DECL_IGNORED_P (parm
) = 0;
13606 if ((flag_openacc
|| flag_openmp
|| flag_openmp_simd
)
13607 && gimplify_omp_ctxp
)
13609 delete_omp_context (gimplify_omp_ctxp
);
13610 gimplify_omp_ctxp
= NULL
;
13613 pop_gimplify_context (outer_bind
);
13614 gcc_assert (gimplify_ctxp
== NULL
);
13616 if (flag_checking
&& !seen_error ())
13617 verify_gimple_in_seq (gimple_bind_body (outer_bind
));
13619 timevar_pop (TV_TREE_GIMPLIFY
);
13620 input_location
= saved_location
;
13625 typedef char *char_p
; /* For DEF_VEC_P. */
13627 /* Return whether we should exclude FNDECL from instrumentation. */
13630 flag_instrument_functions_exclude_p (tree fndecl
)
13634 v
= (vec
<char_p
> *) flag_instrument_functions_exclude_functions
;
13635 if (v
&& v
->length () > 0)
13641 name
= lang_hooks
.decl_printable_name (fndecl
, 0);
13642 FOR_EACH_VEC_ELT (*v
, i
, s
)
13643 if (strstr (name
, s
) != NULL
)
13647 v
= (vec
<char_p
> *) flag_instrument_functions_exclude_files
;
13648 if (v
&& v
->length () > 0)
13654 name
= DECL_SOURCE_FILE (fndecl
);
13655 FOR_EACH_VEC_ELT (*v
, i
, s
)
13656 if (strstr (name
, s
) != NULL
)
13663 /* Entry point to the gimplification pass. FNDECL is the FUNCTION_DECL
13664 node for the function we want to gimplify.
13666 Return the sequence of GIMPLE statements corresponding to the body
13670 gimplify_function_tree (tree fndecl
)
13676 gcc_assert (!gimple_body (fndecl
));
13678 if (DECL_STRUCT_FUNCTION (fndecl
))
13679 push_cfun (DECL_STRUCT_FUNCTION (fndecl
));
13681 push_struct_function (fndecl
);
13683 /* Tentatively set PROP_gimple_lva here, and reset it in gimplify_va_arg_expr
13685 cfun
->curr_properties
|= PROP_gimple_lva
;
13687 for (parm
= DECL_ARGUMENTS (fndecl
); parm
; parm
= DECL_CHAIN (parm
))
13689 /* Preliminarily mark non-addressed complex variables as eligible
13690 for promotion to gimple registers. We'll transform their uses
13691 as we find them. */
13692 if ((TREE_CODE (TREE_TYPE (parm
)) == COMPLEX_TYPE
13693 || TREE_CODE (TREE_TYPE (parm
)) == VECTOR_TYPE
)
13694 && !TREE_THIS_VOLATILE (parm
)
13695 && !needs_to_live_in_memory (parm
))
13696 DECL_GIMPLE_REG_P (parm
) = 1;
13699 ret
= DECL_RESULT (fndecl
);
13700 if ((TREE_CODE (TREE_TYPE (ret
)) == COMPLEX_TYPE
13701 || TREE_CODE (TREE_TYPE (ret
)) == VECTOR_TYPE
)
13702 && !needs_to_live_in_memory (ret
))
13703 DECL_GIMPLE_REG_P (ret
) = 1;
13705 if (asan_sanitize_use_after_scope () && sanitize_flags_p (SANITIZE_ADDRESS
))
13706 asan_poisoned_variables
= new hash_set
<tree
> ();
13707 bind
= gimplify_body (fndecl
, true);
13708 if (asan_poisoned_variables
)
13710 delete asan_poisoned_variables
;
13711 asan_poisoned_variables
= NULL
;
13714 /* The tree body of the function is no longer needed, replace it
13715 with the new GIMPLE body. */
13717 gimple_seq_add_stmt (&seq
, bind
);
13718 gimple_set_body (fndecl
, seq
);
13720 /* If we're instrumenting function entry/exit, then prepend the call to
13721 the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to
13722 catch the exit hook. */
13723 /* ??? Add some way to ignore exceptions for this TFE. */
13724 if (flag_instrument_function_entry_exit
13725 && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl
)
13726 /* Do not instrument extern inline functions. */
13727 && !(DECL_DECLARED_INLINE_P (fndecl
)
13728 && DECL_EXTERNAL (fndecl
)
13729 && DECL_DISREGARD_INLINE_LIMITS (fndecl
))
13730 && !flag_instrument_functions_exclude_p (fndecl
))
13735 gimple_seq cleanup
= NULL
, body
= NULL
;
13736 tree tmp_var
, this_fn_addr
;
13739 /* The instrumentation hooks aren't going to call the instrumented
13740 function and the address they receive is expected to be matchable
13741 against symbol addresses. Make sure we don't create a trampoline,
13742 in case the current function is nested. */
13743 this_fn_addr
= build_fold_addr_expr (current_function_decl
);
13744 TREE_NO_TRAMPOLINE (this_fn_addr
) = 1;
13746 x
= builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS
);
13747 call
= gimple_build_call (x
, 1, integer_zero_node
);
13748 tmp_var
= create_tmp_var (ptr_type_node
, "return_addr");
13749 gimple_call_set_lhs (call
, tmp_var
);
13750 gimplify_seq_add_stmt (&cleanup
, call
);
13751 x
= builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_EXIT
);
13752 call
= gimple_build_call (x
, 2, this_fn_addr
, tmp_var
);
13753 gimplify_seq_add_stmt (&cleanup
, call
);
13754 tf
= gimple_build_try (seq
, cleanup
, GIMPLE_TRY_FINALLY
);
13756 x
= builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS
);
13757 call
= gimple_build_call (x
, 1, integer_zero_node
);
13758 tmp_var
= create_tmp_var (ptr_type_node
, "return_addr");
13759 gimple_call_set_lhs (call
, tmp_var
);
13760 gimplify_seq_add_stmt (&body
, call
);
13761 x
= builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_ENTER
);
13762 call
= gimple_build_call (x
, 2, this_fn_addr
, tmp_var
);
13763 gimplify_seq_add_stmt (&body
, call
);
13764 gimplify_seq_add_stmt (&body
, tf
);
13765 new_bind
= gimple_build_bind (NULL
, body
, NULL
);
13767 /* Replace the current function body with the body
13768 wrapped in the try/finally TF. */
13770 gimple_seq_add_stmt (&seq
, new_bind
);
13771 gimple_set_body (fndecl
, seq
);
13775 if (sanitize_flags_p (SANITIZE_THREAD
))
13777 gcall
*call
= gimple_build_call_internal (IFN_TSAN_FUNC_EXIT
, 0);
13778 gimple
*tf
= gimple_build_try (seq
, call
, GIMPLE_TRY_FINALLY
);
13779 gbind
*new_bind
= gimple_build_bind (NULL
, tf
, NULL
);
13780 /* Replace the current function body with the body
13781 wrapped in the try/finally TF. */
13783 gimple_seq_add_stmt (&seq
, new_bind
);
13784 gimple_set_body (fndecl
, seq
);
13787 DECL_SAVED_TREE (fndecl
) = NULL_TREE
;
13788 cfun
->curr_properties
|= PROP_gimple_any
;
13792 dump_function (TDI_gimple
, fndecl
);
13795 /* Return a dummy expression of type TYPE in order to keep going after an
13799 dummy_object (tree type
)
13801 tree t
= build_int_cst (build_pointer_type (type
), 0);
13802 return build2 (MEM_REF
, type
, t
, t
);
13805 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
13806 builtin function, but a very special sort of operator. */
13808 enum gimplify_status
13809 gimplify_va_arg_expr (tree
*expr_p
, gimple_seq
*pre_p
,
13810 gimple_seq
*post_p ATTRIBUTE_UNUSED
)
13812 tree promoted_type
, have_va_type
;
13813 tree valist
= TREE_OPERAND (*expr_p
, 0);
13814 tree type
= TREE_TYPE (*expr_p
);
13815 tree t
, tag
, aptag
;
13816 location_t loc
= EXPR_LOCATION (*expr_p
);
13818 /* Verify that valist is of the proper type. */
13819 have_va_type
= TREE_TYPE (valist
);
13820 if (have_va_type
== error_mark_node
)
13822 have_va_type
= targetm
.canonical_va_list_type (have_va_type
);
13823 if (have_va_type
== NULL_TREE
13824 && POINTER_TYPE_P (TREE_TYPE (valist
)))
13825 /* Handle 'Case 1: Not an array type' from c-common.c/build_va_arg. */
13827 = targetm
.canonical_va_list_type (TREE_TYPE (TREE_TYPE (valist
)));
13828 gcc_assert (have_va_type
!= NULL_TREE
);
13830 /* Generate a diagnostic for requesting data of a type that cannot
13831 be passed through `...' due to type promotion at the call site. */
13832 if ((promoted_type
= lang_hooks
.types
.type_promotes_to (type
))
13835 static bool gave_help
;
13837 /* Use the expansion point to handle cases such as passing bool (defined
13838 in a system header) through `...'. */
13839 source_location xloc
13840 = expansion_point_location_if_in_system_header (loc
);
13842 /* Unfortunately, this is merely undefined, rather than a constraint
13843 violation, so we cannot make this an error. If this call is never
13844 executed, the program is still strictly conforming. */
13845 auto_diagnostic_group d
;
13846 warned
= warning_at (xloc
, 0,
13847 "%qT is promoted to %qT when passed through %<...%>",
13848 type
, promoted_type
);
13849 if (!gave_help
&& warned
)
13852 inform (xloc
, "(so you should pass %qT not %qT to %<va_arg%>)",
13853 promoted_type
, type
);
13856 /* We can, however, treat "undefined" any way we please.
13857 Call abort to encourage the user to fix the program. */
13859 inform (xloc
, "if this code is reached, the program will abort");
13860 /* Before the abort, allow the evaluation of the va_list
13861 expression to exit or longjmp. */
13862 gimplify_and_add (valist
, pre_p
);
13863 t
= build_call_expr_loc (loc
,
13864 builtin_decl_implicit (BUILT_IN_TRAP
), 0);
13865 gimplify_and_add (t
, pre_p
);
13867 /* This is dead code, but go ahead and finish so that the
13868 mode of the result comes out right. */
13869 *expr_p
= dummy_object (type
);
13870 return GS_ALL_DONE
;
13873 tag
= build_int_cst (build_pointer_type (type
), 0);
13874 aptag
= build_int_cst (TREE_TYPE (valist
), 0);
13876 *expr_p
= build_call_expr_internal_loc (loc
, IFN_VA_ARG
, type
, 3,
13877 valist
, tag
, aptag
);
13879 /* Clear the tentatively set PROP_gimple_lva, to indicate that IFN_VA_ARG
13880 needs to be expanded. */
13881 cfun
->curr_properties
&= ~PROP_gimple_lva
;
13886 /* Build a new GIMPLE_ASSIGN tuple and append it to the end of *SEQ_P.
13888 DST/SRC are the destination and source respectively. You can pass
13889 ungimplified trees in DST or SRC, in which case they will be
13890 converted to a gimple operand if necessary.
13892 This function returns the newly created GIMPLE_ASSIGN tuple. */
13895 gimplify_assign (tree dst
, tree src
, gimple_seq
*seq_p
)
13897 tree t
= build2 (MODIFY_EXPR
, TREE_TYPE (dst
), dst
, src
);
13898 gimplify_and_add (t
, seq_p
);
13900 return gimple_seq_last_stmt (*seq_p
);
13904 gimplify_hasher::hash (const elt_t
*p
)
13907 return iterative_hash_expr (t
, 0);
13911 gimplify_hasher::equal (const elt_t
*p1
, const elt_t
*p2
)
13915 enum tree_code code
= TREE_CODE (t1
);
13917 if (TREE_CODE (t2
) != code
13918 || TREE_TYPE (t1
) != TREE_TYPE (t2
))
13921 if (!operand_equal_p (t1
, t2
, 0))
13924 /* Only allow them to compare equal if they also hash equal; otherwise
13925 results are nondeterminate, and we fail bootstrap comparison. */
13926 gcc_checking_assert (hash (p1
) == hash (p2
));