extend DECL_GIMPLE_REG_P to all types

This extends DECL_GIMPLE_REG_P to all types so we can clear
TREE_ADDRESSABLE even for integers with partial defs, not just
complex and vector variables.  To make that transition easier
the patch inverts DECL_GIMPLE_REG_P to DECL_NOT_GIMPLE_REG_P
since that makes the default the current state for all other
types besides complex and vectors.

For the testcase in PR94703 we're able to expand the partial
def'ed local integer to a register then, producing a single
movl rather than going through the stack.

On i?86 this execute FAILs gcc.dg/torture/pr71522.c because
we now expand a round-trip through a long double automatic var
to a register fld/fst which normalizes the value.  For that
during RTL expansion we're looking for problematic punnings
of decls and avoid pseudos for those - I chose integer or
BLKmode accesses on decls with modes where precision doesn't
match bitsize which covers the XFmode case.

2020-05-07  Richard Biener  <rguenther@suse.de>

	PR middle-end/94703
	* tree-core.h (tree_decl_common::gimple_reg_flag): Rename ...
	(tree_decl_common::not_gimple_reg_flag): ... to this.
	* tree.h (DECL_GIMPLE_REG_P): Rename ...
	(DECL_NOT_GIMPLE_REG_P): ... to this.
	* gimple-expr.c (copy_var_decl): Copy DECL_NOT_GIMPLE_REG_P.
	(create_tmp_reg): Simplify.
	(create_tmp_reg_fn): Likewise.
	(is_gimple_reg): Check DECL_NOT_GIMPLE_REG_P for all regs.
	* gimplify.c (create_tmp_from_val): Simplify.
	(gimplify_bind_expr): Likewise.
	(gimplify_compound_literal_expr): Likewise.
	(gimplify_function_tree): Likewise.
	(prepare_gimple_addressable): Set DECL_NOT_GIMPLE_REG_P.
	* asan.c (create_odr_indicator): Do not clear DECL_GIMPLE_REG_P.
	(asan_add_global): Copy it.
	* cgraphunit.c (cgraph_node::expand_thunk): Force args
	to be GIMPLE regs.
	* function.c (gimplify_parameters): Copy
	DECL_NOT_GIMPLE_REG_P.
	* ipa-param-manipulation.c
	(ipa_param_body_adjustments::common_initialization): Simplify.
	(ipa_param_body_adjustments::reset_debug_stmts): Copy
	DECL_NOT_GIMPLE_REG_P.
	* omp-low.c (lower_omp_for_scan): Do not set DECL_GIMPLE_REG_P.
	* sanopt.c (sanitize_rewrite_addressable_params): Likewise.
	* tree-cfg.c (make_blocks_1): Simplify.
	(verify_address): Do not verify DECL_GIMPLE_REG_P setting.
	* tree-eh.c (lower_eh_constructs_2): Simplify.
	* tree-inline.c (declare_return_variable): Adjust and
	generalize.
	(copy_decl_to_var): Copy DECL_NOT_GIMPLE_REG_P.
	(copy_result_decl_to_var): Likewise.
	* tree-into-ssa.c (pass_build_ssa::execute): Adjust comment.
	* tree-nested.c (create_tmp_var_for): Simplify.
	* tree-parloops.c (separate_decls_in_region_name): Copy
	DECL_NOT_GIMPLE_REG_P.
	* tree-sra.c (create_access_replacement): Adjust and
	generalize partial def support.
	* tree-ssa-forwprop.c (pass_forwprop::execute): Set
	DECL_NOT_GIMPLE_REG_P on decls we introduce partial defs on.
	* tree-ssa.c (maybe_optimize_var): Handle clearing of
	TREE_ADDRESSABLE and setting/clearing DECL_NOT_GIMPLE_REG_P
	independently.
	* lto-streamer-out.c (hash_tree): Hash DECL_NOT_GIMPLE_REG_P.
	* tree-streamer-out.c (pack_ts_decl_common_value_fields): Stream
	DECL_NOT_GIMPLE_REG_P.
	* tree-streamer-in.c (unpack_ts_decl_common_value_fields): Likewise.
	* cfgexpand.c (avoid_type_punning_on_regs): New.
	(discover_nonconstant_array_refs): Call
	avoid_type_punning_on_regs to avoid unsupported mode punning.

	lto/
	* lto-common.c (compare_tree_sccs_1): Compare
	DECL_NOT_GIMPLE_REG_P.

	c/
	* gimple-parser.c (c_parser_parse_ssa_name): Do not set
	DECL_GIMPLE_REG_P.

	cp/
	* optimize.c (update_cloned_parm): Copy DECL_NOT_GIMPLE_REG_P.

	* gcc.dg/tree-ssa/pr94703.c: New testcase.
This commit is contained in:
Richard Biener 2020-04-22 10:40:51 +02:00
parent 1d865b29ab
commit eb72dc663e
32 changed files with 194 additions and 164 deletions

View File

@ -1,3 +1,57 @@
2020-05-07 Richard Biener <rguenther@suse.de>
PR middle-end/94703
* tree-core.h (tree_decl_common::gimple_reg_flag): Rename ...
(tree_decl_common::not_gimple_reg_flag): ... to this.
* tree.h (DECL_GIMPLE_REG_P): Rename ...
(DECL_NOT_GIMPLE_REG_P): ... to this.
* gimple-expr.c (copy_var_decl): Copy DECL_NOT_GIMPLE_REG_P.
(create_tmp_reg): Simplify.
(create_tmp_reg_fn): Likewise.
(is_gimple_reg): Check DECL_NOT_GIMPLE_REG_P for all regs.
* gimplify.c (create_tmp_from_val): Simplify.
(gimplify_bind_expr): Likewise.
(gimplify_compound_literal_expr): Likewise.
(gimplify_function_tree): Likewise.
(prepare_gimple_addressable): Set DECL_NOT_GIMPLE_REG_P.
* asan.c (create_odr_indicator): Do not clear DECL_GIMPLE_REG_P.
(asan_add_global): Copy it.
* cgraphunit.c (cgraph_node::expand_thunk): Force args
to be GIMPLE regs.
* function.c (gimplify_parameters): Copy
DECL_NOT_GIMPLE_REG_P.
* ipa-param-manipulation.c
(ipa_param_body_adjustments::common_initialization): Simplify.
(ipa_param_body_adjustments::reset_debug_stmts): Copy
DECL_NOT_GIMPLE_REG_P.
* omp-low.c (lower_omp_for_scan): Do not set DECL_GIMPLE_REG_P.
* sanopt.c (sanitize_rewrite_addressable_params): Likewise.
* tree-cfg.c (make_blocks_1): Simplify.
(verify_address): Do not verify DECL_GIMPLE_REG_P setting.
* tree-eh.c (lower_eh_constructs_2): Simplify.
* tree-inline.c (declare_return_variable): Adjust and
generalize.
(copy_decl_to_var): Copy DECL_NOT_GIMPLE_REG_P.
(copy_result_decl_to_var): Likewise.
* tree-into-ssa.c (pass_build_ssa::execute): Adjust comment.
* tree-nested.c (create_tmp_var_for): Simplify.
* tree-parloops.c (separate_decls_in_region_name): Copy
DECL_NOT_GIMPLE_REG_P.
* tree-sra.c (create_access_replacement): Adjust and
generalize partial def support.
* tree-ssa-forwprop.c (pass_forwprop::execute): Set
DECL_NOT_GIMPLE_REG_P on decls we introduce partial defs on.
* tree-ssa.c (maybe_optimize_var): Handle clearing of
TREE_ADDRESSABLE and setting/clearing DECL_NOT_GIMPLE_REG_P
independently.
* lto-streamer-out.c (hash_tree): Hash DECL_NOT_GIMPLE_REG_P.
* tree-streamer-out.c (pack_ts_decl_common_value_fields): Stream
DECL_NOT_GIMPLE_REG_P.
* tree-streamer-in.c (unpack_ts_decl_common_value_fields): Likewise.
* cfgexpand.c (avoid_type_punning_on_regs): New.
(discover_nonconstant_array_refs): Call
avoid_type_punning_on_regs to avoid unsupported mode punning.
2020-05-07 Alex Coplan <alex.coplan@arm.com>
* config/arm/arm.c (arm_add_stmt_cost): Fix declaration, remove class

View File

@ -2696,7 +2696,6 @@ create_odr_indicator (tree decl, tree type)
TREE_ADDRESSABLE (var) = 1;
TREE_READONLY (var) = 0;
TREE_THIS_VOLATILE (var) = 1;
DECL_GIMPLE_REG_P (var) = 0;
DECL_ARTIFICIAL (var) = 1;
DECL_IGNORED_P (var) = 1;
TREE_STATIC (var) = 1;
@ -2766,7 +2765,7 @@ asan_add_global (tree decl, tree type, vec<constructor_elt, va_gc> *v)
TREE_ADDRESSABLE (refdecl) = TREE_ADDRESSABLE (decl);
TREE_READONLY (refdecl) = TREE_READONLY (decl);
TREE_THIS_VOLATILE (refdecl) = TREE_THIS_VOLATILE (decl);
DECL_GIMPLE_REG_P (refdecl) = DECL_GIMPLE_REG_P (decl);
DECL_NOT_GIMPLE_REG_P (refdecl) = DECL_NOT_GIMPLE_REG_P (decl);
DECL_ARTIFICIAL (refdecl) = DECL_ARTIFICIAL (decl);
DECL_IGNORED_P (refdecl) = DECL_IGNORED_P (decl);
TREE_STATIC (refdecl) = 1;

View File

@ -1,3 +1,9 @@
2020-05-07 Richard Biener <rguenther@suse.de>
PR middle-end/94703
* gimple-parser.c (c_parser_parse_ssa_name): Do not set
DECL_GIMPLE_REG_P.
2020-04-30 Jakub Jelinek <jakub@redhat.com>
PR c/94842

View File

@ -1272,9 +1272,6 @@ c_parser_parse_ssa_name (gimple_parser &parser,
error ("invalid base %qE for SSA name", parent);
return error_mark_node;
}
if (VECTOR_TYPE_P (TREE_TYPE (parent))
|| TREE_CODE (TREE_TYPE (parent)) == COMPLEX_TYPE)
DECL_GIMPLE_REG_P (parent) = 1;
name = make_ssa_name_fn (cfun, parent,
gimple_build_nop (), version);
}

View File

@ -6126,6 +6126,29 @@ discover_nonconstant_array_refs_r (tree * tp, int *walk_subtrees,
return NULL_TREE;
}
/* If there's a chance to get a pseudo for t then if it would be of float mode
and the actual access is via an integer mode (lowered memcpy or similar
access) then avoid the register expansion if the mode likely is not storage
suitable for raw bits processing (like XFmode on i?86). */
static void
avoid_type_punning_on_regs (tree t)
{
machine_mode access_mode = TYPE_MODE (TREE_TYPE (t));
if (access_mode != BLKmode
&& !SCALAR_INT_MODE_P (access_mode))
return;
tree base = get_base_address (t);
if (DECL_P (base)
&& !TREE_ADDRESSABLE (base)
&& FLOAT_MODE_P (DECL_MODE (base))
&& maybe_lt (GET_MODE_PRECISION (DECL_MODE (base)),
GET_MODE_BITSIZE (GET_MODE_INNER (DECL_MODE (base))))
/* Double check in the expensive way we really would get a pseudo. */
&& use_register_for_decl (base))
TREE_ADDRESSABLE (base) = 1;
}
/* RTL expansion is not able to compile array references with variable
offsets for arrays stored in single register. Discover such
expressions and mark variables as addressable to avoid this
@ -6159,6 +6182,12 @@ discover_nonconstant_array_refs (void)
default:
break;
}
if (gimple_vdef (stmt))
{
tree t = gimple_get_lhs (stmt);
if (t && REFERENCE_CLASS_P (t))
avoid_type_punning_on_regs (t);
}
}
}
}

View File

@ -2058,10 +2058,7 @@ cgraph_node::expand_thunk (bool output_asm_thunks, bool force_gimple_thunk)
for (; i < nargs; i++, arg = DECL_CHAIN (arg))
{
tree tmp = arg;
if (VECTOR_TYPE_P (TREE_TYPE (arg))
|| TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
DECL_GIMPLE_REG_P (arg) = 1;
DECL_NOT_GIMPLE_REG_P (arg) = 0;
if (!is_gimple_val (arg))
{
tmp = create_tmp_reg (TYPE_MAIN_VARIANT

View File

@ -1,3 +1,8 @@
2020-05-07 Richard Biener <rguenther@suse.de>
PR middle-end/94703
* optimize.c (update_cloned_parm): Copy DECL_NOT_GIMPLE_REG_P.
2020-05-06 Marek Polacek <polacek@redhat.com>
PR c++/94938

View File

@ -58,7 +58,7 @@ update_cloned_parm (tree parm, tree cloned_parm, bool first)
DECL_SOURCE_LOCATION (cloned_parm) = DECL_SOURCE_LOCATION (parm);
TREE_TYPE (cloned_parm) = TREE_TYPE (parm);
DECL_GIMPLE_REG_P (cloned_parm) = DECL_GIMPLE_REG_P (parm);
DECL_NOT_GIMPLE_REG_P (cloned_parm) = DECL_NOT_GIMPLE_REG_P (parm);
}
/* Like copy_decl_no_change, but handle DECL_OMP_PRIVATIZED_MEMBER

View File

@ -3913,9 +3913,8 @@ gimplify_parameters (gimple_seq *cleanup)
as we'll query that flag during gimplification. */
if (TREE_ADDRESSABLE (parm))
TREE_ADDRESSABLE (local) = 1;
else if (TREE_CODE (type) == COMPLEX_TYPE
|| TREE_CODE (type) == VECTOR_TYPE)
DECL_GIMPLE_REG_P (local) = 1;
if (DECL_NOT_GIMPLE_REG_P (parm))
DECL_NOT_GIMPLE_REG_P (local) = 1;
if (!is_gimple_reg (local)
&& flag_stack_reuse != SR_NONE)

View File

@ -373,7 +373,7 @@ copy_var_decl (tree var, tree name, tree type)
TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (var);
TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (var);
DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (var);
DECL_NOT_GIMPLE_REG_P (copy) = DECL_NOT_GIMPLE_REG_P (var);
DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (var);
DECL_IGNORED_P (copy) = DECL_IGNORED_P (var);
DECL_CONTEXT (copy) = DECL_CONTEXT (var);
@ -493,14 +493,7 @@ create_tmp_var (tree type, const char *prefix)
tree
create_tmp_reg (tree type, const char *prefix)
{
tree tmp;
tmp = create_tmp_var (type, prefix);
if (TREE_CODE (type) == COMPLEX_TYPE
|| TREE_CODE (type) == VECTOR_TYPE)
DECL_GIMPLE_REG_P (tmp) = 1;
return tmp;
return create_tmp_var (type, prefix);
}
/* Create a new temporary variable declaration of type TYPE by calling
@ -514,9 +507,6 @@ create_tmp_reg_fn (struct function *fn, tree type, const char *prefix)
tmp = create_tmp_var_raw (type, prefix);
gimple_add_tmp_var_fn (fn, tmp);
if (TREE_CODE (type) == COMPLEX_TYPE
|| TREE_CODE (type) == VECTOR_TYPE)
DECL_GIMPLE_REG_P (tmp) = 1;
return tmp;
}
@ -792,13 +782,9 @@ is_gimple_reg (tree t)
if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t))
return false;
/* Complex and vector values must have been put into SSA-like form.
That is, no assignments to the individual components. */
if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE
|| TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
return DECL_GIMPLE_REG_P (t);
return true;
/* Variables can be marked as having partial definitions, avoid
putting them into SSA form. */
return !DECL_NOT_GIMPLE_REG_P (t);
}

View File

@ -559,9 +559,6 @@ create_tmp_from_val (tree val)
/* Drop all qualifiers and address-space information from the value type. */
tree type = TYPE_MAIN_VARIANT (TREE_TYPE (val));
tree var = create_tmp_var (type, get_name (val));
if (TREE_CODE (TREE_TYPE (var)) == COMPLEX_TYPE
|| TREE_CODE (TREE_TYPE (var)) == VECTOR_TYPE)
DECL_GIMPLE_REG_P (var) = 1;
return var;
}
@ -1400,16 +1397,6 @@ gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p)
if (DECL_HARD_REGISTER (t) && !is_global_var (t) && cfun)
cfun->has_local_explicit_reg_vars = true;
}
/* Preliminarily mark non-addressed complex variables as eligible
for promotion to gimple registers. We'll transform their uses
as we find them. */
if ((TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE
|| TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
&& !TREE_THIS_VOLATILE (t)
&& (VAR_P (t) && !DECL_HARD_REGISTER (t))
&& !needs_to_live_in_memory (t))
DECL_GIMPLE_REG_P (t) = 1;
}
bind_stmt = gimple_build_bind (BIND_EXPR_VARS (bind_expr), NULL,
@ -4308,7 +4295,7 @@ prepare_gimple_addressable (tree *expr_p, gimple_seq *seq_p)
{
/* Do not allow an SSA name as the temporary. */
tree var = get_initialized_tmp_var (*expr_p, seq_p, NULL, false);
DECL_GIMPLE_REG_P (var) = 0;
DECL_NOT_GIMPLE_REG_P (var) = 1;
*expr_p = var;
}
}
@ -4774,15 +4761,6 @@ gimplify_compound_literal_expr (tree *expr_p, gimple_seq *pre_p,
return GS_OK;
}
/* Preliminarily mark non-addressed complex variables as eligible
for promotion to gimple registers. We'll transform their uses
as we find them. */
if ((TREE_CODE (TREE_TYPE (decl)) == COMPLEX_TYPE
|| TREE_CODE (TREE_TYPE (decl)) == VECTOR_TYPE)
&& !TREE_THIS_VOLATILE (decl)
&& !needs_to_live_in_memory (decl))
DECL_GIMPLE_REG_P (decl) = 1;
/* If the decl is not addressable, then it is being used in some
expression or on the right hand side of a statement, and it can
be put into a readonly data section. */
@ -5617,8 +5595,7 @@ is_gimple_stmt (tree t)
/* Promote partial stores to COMPLEX variables to total stores. *EXPR_P is
a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a variable with
DECL_GIMPLE_REG_P set.
a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a gimple register.
IMPORTANT NOTE: This promotion is performed by introducing a load of the
other, unmodified part of the complex object just before the total store.
@ -14992,7 +14969,6 @@ flag_instrument_functions_exclude_p (tree fndecl)
void
gimplify_function_tree (tree fndecl)
{
tree parm, ret;
gimple_seq seq;
gbind *bind;
@ -15007,24 +14983,6 @@ gimplify_function_tree (tree fndecl)
if necessary. */
cfun->curr_properties |= PROP_gimple_lva;
for (parm = DECL_ARGUMENTS (fndecl); parm ; parm = DECL_CHAIN (parm))
{
/* Preliminarily mark non-addressed complex variables as eligible
for promotion to gimple registers. We'll transform their uses
as we find them. */
if ((TREE_CODE (TREE_TYPE (parm)) == COMPLEX_TYPE
|| TREE_CODE (TREE_TYPE (parm)) == VECTOR_TYPE)
&& !TREE_THIS_VOLATILE (parm)
&& !needs_to_live_in_memory (parm))
DECL_GIMPLE_REG_P (parm) = 1;
}
ret = DECL_RESULT (fndecl);
if ((TREE_CODE (TREE_TYPE (ret)) == COMPLEX_TYPE
|| TREE_CODE (TREE_TYPE (ret)) == VECTOR_TYPE)
&& !needs_to_live_in_memory (ret))
DECL_GIMPLE_REG_P (ret) = 1;
if (asan_sanitize_use_after_scope () && sanitize_flags_p (SANITIZE_ADDRESS))
asan_poisoned_variables = new hash_set<tree> ();
bind = gimplify_body (fndecl, true);

View File

@ -1028,10 +1028,6 @@ ipa_param_body_adjustments::common_initialization (tree old_fndecl,
DECL_CONTEXT (new_parm) = m_fndecl;
TREE_USED (new_parm) = 1;
DECL_IGNORED_P (new_parm) = 1;
/* We assume all newly created arguments are not addressable. */
if (TREE_CODE (new_type) == COMPLEX_TYPE
|| TREE_CODE (new_type) == VECTOR_TYPE)
DECL_GIMPLE_REG_P (new_parm) = 1;
layout_decl (new_parm, 0);
m_new_decls.quick_push (new_parm);
@ -1888,7 +1884,7 @@ ipa_param_body_adjustments::reset_debug_stmts ()
TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (decl);
TREE_READONLY (copy) = TREE_READONLY (decl);
TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (decl);
DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (decl);
DECL_NOT_GIMPLE_REG_P (copy) = DECL_NOT_GIMPLE_REG_P (decl);
DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (decl);
DECL_IGNORED_P (copy) = DECL_IGNORED_P (decl);
DECL_ABSTRACT_ORIGIN (copy) = DECL_ORIGIN (decl);

View File

@ -1067,7 +1067,7 @@ hash_tree (struct streamer_tree_cache_d *cache, hash_map<tree, hashval_t> *map,
hstate.add_flag (DECL_USER_ALIGN (t));
hstate.add_flag (DECL_PRESERVE_P (t));
hstate.add_flag (DECL_EXTERNAL (t));
hstate.add_flag (DECL_GIMPLE_REG_P (t));
hstate.add_flag (DECL_NOT_GIMPLE_REG_P (t));
hstate.commit_flag ();
hstate.add_int (DECL_ALIGN (t));
if (code == LABEL_DECL)

View File

@ -1,3 +1,9 @@
2020-05-07 Richard Biener <rguenther@suse.de>
PR middle-end/94703
* lto-common.c (compare_tree_sccs_1): Compare
DECL_NOT_GIMPLE_REG_P.
2020-04-29 Jakub Jelinek <jakub@redhat.com>
PR target/94707

View File

@ -1167,7 +1167,7 @@ compare_tree_sccs_1 (tree t1, tree t2, tree **map)
compare_values (DECL_USER_ALIGN);
compare_values (DECL_PRESERVE_P);
compare_values (DECL_EXTERNAL);
compare_values (DECL_GIMPLE_REG_P);
compare_values (DECL_NOT_GIMPLE_REG_P);
compare_values (DECL_ALIGN);
if (code == LABEL_DECL)
{

View File

@ -10322,7 +10322,6 @@ lower_omp_for_scan (gimple_seq *body_p, gimple_seq *dlist, gomp_for *stmt,
gimple_seq_add_stmt (body_p, g);
tree cplx = create_tmp_var (build_complex_type (unsigned_type_node, false));
DECL_GIMPLE_REG_P (cplx) = 1;
g = gimple_build_call_internal (IFN_MUL_OVERFLOW, 2, thread_nump1, twok);
gimple_call_set_lhs (g, cplx);
gimple_seq_add_stmt (body_p, g);

View File

@ -1189,7 +1189,6 @@ sanitize_rewrite_addressable_params (function *fun)
{
/* We need to create a SSA name that will be used for the
assignment. */
DECL_GIMPLE_REG_P (arg) = 1;
tree tmp = get_or_create_ssa_default_def (cfun, arg);
g = gimple_build_assign (var, tmp);
gimple_set_location (g, DECL_SOURCE_LOCATION (arg));

View File

@ -1,3 +1,8 @@
2020-05-07 Richard Biener <rguenther@suse.de>
PR middle-end/94703
* gcc.dg/tree-ssa/pr94703.c: New testcase.
2020-05-07 Jakub Jelinek <jakub@redhat.com>
PR c++/94946

View File

@ -0,0 +1,11 @@
/* { dg-do compile } */
/* { dg-options "-O -fdump-tree-ssa" } */
unsigned int set_lowpart (unsigned int const *X)
{
unsigned int r = 0;
__builtin_memcpy(&r,X,sizeof (unsigned int) / 2);
return r;
}
/* { dg-final { scan-tree-dump "No longer having address taken: r" "ssa" } } */

View File

@ -577,9 +577,6 @@ make_blocks_1 (gimple_seq seq, basic_block bb)
gimple_set_location (s, gimple_location (stmt));
gimple_set_block (s, gimple_block (stmt));
gimple_set_lhs (stmt, tmp);
if (TREE_CODE (TREE_TYPE (tmp)) == COMPLEX_TYPE
|| TREE_CODE (TREE_TYPE (tmp)) == VECTOR_TYPE)
DECL_GIMPLE_REG_P (tmp) = 1;
gsi_insert_after (&i, s, GSI_SAME_STMT);
}
start_new_block = true;
@ -2983,12 +2980,6 @@ verify_address (tree t, bool verify_addressable)
|| TREE_CODE (base) == RESULT_DECL))
return false;
if (DECL_GIMPLE_REG_P (base))
{
error ("%<DECL_GIMPLE_REG_P%> set on a variable with address taken");
return true;
}
if (verify_addressable && !TREE_ADDRESSABLE (base))
{
error ("address taken but %<TREE_ADDRESSABLE%> bit not set");

View File

@ -1724,7 +1724,7 @@ struct GTY(()) tree_decl_common {
unsigned decl_flag_3 : 1;
/* Logically, these two would go in a theoretical base shared by var and
parm decl. */
unsigned gimple_reg_flag : 1;
unsigned not_gimple_reg_flag : 1;
/* In VAR_DECL, PARM_DECL and RESULT_DECL, this is DECL_BY_REFERENCE. */
unsigned decl_by_reference_flag : 1;
/* In a VAR_DECL and PARM_DECL, this is DECL_READ_P. */

View File

@ -2072,9 +2072,6 @@ lower_eh_constructs_2 (struct leh_state *state, gimple_stmt_iterator *gsi)
gimple_set_location (s, gimple_location (stmt));
gimple_set_block (s, gimple_block (stmt));
gimple_set_lhs (stmt, tmp);
if (TREE_CODE (TREE_TYPE (tmp)) == COMPLEX_TYPE
|| TREE_CODE (TREE_TYPE (tmp)) == VECTOR_TYPE)
DECL_GIMPLE_REG_P (tmp) = 1;
gsi_insert_after (gsi, s, GSI_SAME_STMT);
}
/* Look for things that can throw exceptions, and record them. */

View File

@ -3670,11 +3670,9 @@ declare_return_variable (copy_body_data *id, tree return_slot, tree modify_dest,
if (TREE_ADDRESSABLE (result))
mark_addressable (var);
}
if ((TREE_CODE (TREE_TYPE (result)) == COMPLEX_TYPE
|| TREE_CODE (TREE_TYPE (result)) == VECTOR_TYPE)
&& !DECL_GIMPLE_REG_P (result)
if (DECL_NOT_GIMPLE_REG_P (result)
&& DECL_P (var))
DECL_GIMPLE_REG_P (var) = 0;
DECL_NOT_GIMPLE_REG_P (var) = 1;
if (!useless_type_conversion_p (callee_type, caller_type))
var = build1 (VIEW_CONVERT_EXPR, callee_type, var);
@ -3717,10 +3715,8 @@ declare_return_variable (copy_body_data *id, tree return_slot, tree modify_dest,
use_it = false;
else if (is_global_var (base_m))
use_it = false;
else if ((TREE_CODE (TREE_TYPE (result)) == COMPLEX_TYPE
|| TREE_CODE (TREE_TYPE (result)) == VECTOR_TYPE)
&& !DECL_GIMPLE_REG_P (result)
&& DECL_GIMPLE_REG_P (base_m))
else if (DECL_NOT_GIMPLE_REG_P (result)
&& !DECL_NOT_GIMPLE_REG_P (base_m))
use_it = false;
else if (!TREE_ADDRESSABLE (base_m))
use_it = true;
@ -3760,11 +3756,8 @@ declare_return_variable (copy_body_data *id, tree return_slot, tree modify_dest,
to using a MEM_REF to not leak invalid GIMPLE to the following
passes. */
/* Prevent var from being written into SSA form. */
if (TREE_CODE (TREE_TYPE (var)) == VECTOR_TYPE
|| TREE_CODE (TREE_TYPE (var)) == COMPLEX_TYPE)
DECL_GIMPLE_REG_P (var) = false;
else if (is_gimple_reg_type (TREE_TYPE (var)))
TREE_ADDRESSABLE (var) = true;
if (is_gimple_reg_type (TREE_TYPE (var)))
DECL_NOT_GIMPLE_REG_P (var) = true;
use = fold_build2 (MEM_REF, caller_type,
build_fold_addr_expr (var),
build_int_cst (ptr_type_node, 0));
@ -5930,7 +5923,7 @@ copy_decl_to_var (tree decl, copy_body_data *id)
TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (decl);
TREE_READONLY (copy) = TREE_READONLY (decl);
TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (decl);
DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (decl);
DECL_NOT_GIMPLE_REG_P (copy) = DECL_NOT_GIMPLE_REG_P (decl);
DECL_BY_REFERENCE (copy) = DECL_BY_REFERENCE (decl);
return copy_decl_for_dup_finish (id, decl, copy);
@ -5960,7 +5953,12 @@ copy_result_decl_to_var (tree decl, copy_body_data *id)
if (!DECL_BY_REFERENCE (decl))
{
TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (decl);
DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (decl);
DECL_NOT_GIMPLE_REG_P (copy)
= (DECL_NOT_GIMPLE_REG_P (decl)
/* RESULT_DECLs are treated special by needs_to_live_in_memory,
mirror that to the created VAR_DECL. */
|| (TREE_CODE (decl) == RESULT_DECL
&& aggregate_value_p (decl, id->src_fn)));
}
return copy_decl_for_dup_finish (id, decl, copy);

View File

@ -2430,8 +2430,7 @@ pass_build_ssa::execute (function *fun)
basic_block bb;
/* Increase the set of variables we can rewrite into SSA form
by clearing TREE_ADDRESSABLE and setting DECL_GIMPLE_REG_P
and transform the IL to support this. */
by clearing TREE_ADDRESSABLE and transform the IL to support this. */
if (optimize)
execute_update_addresses_taken ();

View File

@ -160,9 +160,6 @@ create_tmp_var_for (struct nesting_info *info, tree type, const char *prefix)
DECL_CONTEXT (tmp_var) = info->context;
DECL_CHAIN (tmp_var) = info->new_local_var_chain;
DECL_SEEN_IN_BIND_EXPR_P (tmp_var) = 1;
if (TREE_CODE (type) == COMPLEX_TYPE
|| TREE_CODE (type) == VECTOR_TYPE)
DECL_GIMPLE_REG_P (tmp_var) = 1;
info->new_local_var_chain = tmp_var;

View File

@ -1574,7 +1574,7 @@ separate_decls_in_region_name (tree name, name_to_copy_table_type *name_copies,
if (!dslot->to)
{
var_copy = create_tmp_var (TREE_TYPE (var), get_name (var));
DECL_GIMPLE_REG_P (var_copy) = DECL_GIMPLE_REG_P (var);
DECL_NOT_GIMPLE_REG_P (var_copy) = DECL_NOT_GIMPLE_REG_P (var);
dslot->uid = uid;
dslot->to = var_copy;

View File

@ -2168,15 +2168,9 @@ create_access_replacement (struct access *access, tree reg_type = NULL_TREE)
variant. This avoids issues with weirdo ABIs like AAPCS. */
repl = create_tmp_var (build_qualified_type (TYPE_MAIN_VARIANT (type),
TYPE_QUALS (type)), "SR");
if (TREE_CODE (type) == COMPLEX_TYPE
|| TREE_CODE (type) == VECTOR_TYPE)
{
if (!access->grp_partial_lhs)
DECL_GIMPLE_REG_P (repl) = 1;
}
else if (access->grp_partial_lhs
if (access->grp_partial_lhs
&& is_gimple_reg_type (type))
TREE_ADDRESSABLE (repl) = 1;
DECL_NOT_GIMPLE_REG_P (repl) = 1;
DECL_SOURCE_LOCATION (repl) = DECL_SOURCE_LOCATION (access->base);
DECL_ARTIFICIAL (repl) = 1;

View File

@ -2962,6 +2962,8 @@ pass_forwprop::execute (function *fun)
!= TARGET_MEM_REF))
{
tree use_lhs = gimple_assign_lhs (use_stmt);
if (auto_var_p (use_lhs))
DECL_NOT_GIMPLE_REG_P (use_lhs) = 1;
tree new_lhs = build1 (REALPART_EXPR,
TREE_TYPE (TREE_TYPE (use_lhs)),
unshare_expr (use_lhs));
@ -3013,6 +3015,9 @@ pass_forwprop::execute (function *fun)
= tree_to_uhwi (TYPE_SIZE (elt_t));
unsigned HOST_WIDE_INT n
= tree_to_uhwi (TYPE_SIZE (TREE_TYPE (rhs)));
tree use_lhs = gimple_assign_lhs (use_stmt);
if (auto_var_p (use_lhs))
DECL_NOT_GIMPLE_REG_P (use_lhs) = 1;
for (unsigned HOST_WIDE_INT bi = 0; bi < n; bi += elt_w)
{
unsigned HOST_WIDE_INT ci = bi / elt_w;
@ -3021,7 +3026,6 @@ pass_forwprop::execute (function *fun)
new_rhs = CONSTRUCTOR_ELT (rhs, ci)->value;
else
new_rhs = build_zero_cst (elt_t);
tree use_lhs = gimple_assign_lhs (use_stmt);
tree new_lhs = build3 (BIT_FIELD_REF,
elt_t,
unshare_expr (use_lhs),

View File

@ -1583,8 +1583,8 @@ non_rewritable_lvalue_p (tree lhs)
return true;
}
/* When possible, clear TREE_ADDRESSABLE bit or set DECL_GIMPLE_REG_P bit and
mark the variable VAR for conversion into SSA. Return true when updating
/* When possible, clear TREE_ADDRESSABLE bit, set or clear DECL_NOT_GIMPLE_REG_P
and mark the variable VAR for conversion into SSA. Return true when updating
stmts is required. */
static void
@ -1597,24 +1597,11 @@ maybe_optimize_var (tree var, bitmap addresses_taken, bitmap not_reg_needs,
|| bitmap_bit_p (addresses_taken, DECL_UID (var)))
return;
if (TREE_ADDRESSABLE (var)
/* Do not change TREE_ADDRESSABLE if we need to preserve var as
a non-register. Otherwise we are confused and forget to
add virtual operands for it. */
&& (!is_gimple_reg_type (TREE_TYPE (var))
|| TREE_CODE (TREE_TYPE (var)) == VECTOR_TYPE
|| TREE_CODE (TREE_TYPE (var)) == COMPLEX_TYPE
|| !bitmap_bit_p (not_reg_needs, DECL_UID (var))))
bool maybe_reg = false;
if (TREE_ADDRESSABLE (var))
{
TREE_ADDRESSABLE (var) = 0;
/* If we cleared TREE_ADDRESSABLE make sure DECL_GIMPLE_REG_P
is unset if we cannot rewrite the var into SSA. */
if ((TREE_CODE (TREE_TYPE (var)) == VECTOR_TYPE
|| TREE_CODE (TREE_TYPE (var)) == COMPLEX_TYPE)
&& bitmap_bit_p (not_reg_needs, DECL_UID (var)))
DECL_GIMPLE_REG_P (var) = 0;
if (is_gimple_reg (var))
bitmap_set_bit (suitable_for_renaming, DECL_UID (var));
maybe_reg = true;
if (dump_file)
{
fprintf (dump_file, "No longer having address taken: ");
@ -1623,21 +1610,37 @@ maybe_optimize_var (tree var, bitmap addresses_taken, bitmap not_reg_needs,
}
}
if (!DECL_GIMPLE_REG_P (var)
&& !bitmap_bit_p (not_reg_needs, DECL_UID (var))
&& (TREE_CODE (TREE_TYPE (var)) == COMPLEX_TYPE
|| TREE_CODE (TREE_TYPE (var)) == VECTOR_TYPE)
&& !TREE_THIS_VOLATILE (var)
&& (!VAR_P (var) || !DECL_HARD_REGISTER (var)))
/* For register type decls if we do not have any partial defs
we cannot express in SSA form mark them as DECL_NOT_GIMPLE_REG_P
as to avoid SSA rewrite. For the others go ahead and mark
them for renaming. */
if (is_gimple_reg_type (TREE_TYPE (var)))
{
if (bitmap_bit_p (not_reg_needs, DECL_UID (var)))
{
DECL_NOT_GIMPLE_REG_P (var) = 1;
if (dump_file)
{
fprintf (dump_file, "Has partial defs: ");
print_generic_expr (dump_file, var);
fprintf (dump_file, "\n");
}
}
else if (DECL_NOT_GIMPLE_REG_P (var))
{
maybe_reg = true;
DECL_NOT_GIMPLE_REG_P (var) = 0;
}
if (maybe_reg && is_gimple_reg (var))
{
DECL_GIMPLE_REG_P (var) = 1;
bitmap_set_bit (suitable_for_renaming, DECL_UID (var));
if (dump_file)
{
fprintf (dump_file, "Now a gimple register: ");
print_generic_expr (dump_file, var);
fprintf (dump_file, "\n");
}
bitmap_set_bit (suitable_for_renaming, DECL_UID (var));
}
}
}
@ -1669,7 +1672,8 @@ is_asan_mark_p (gimple *stmt)
return false;
}
/* Compute TREE_ADDRESSABLE and DECL_GIMPLE_REG_P for local variables. */
/* Compute TREE_ADDRESSABLE and whether we have unhandled partial defs
for local variables. */
void
execute_update_addresses_taken (void)

View File

@ -236,7 +236,7 @@ unpack_ts_decl_common_value_fields (struct bitpack_d *bp, tree expr)
DECL_USER_ALIGN (expr) = (unsigned) bp_unpack_value (bp, 1);
DECL_PRESERVE_P (expr) = (unsigned) bp_unpack_value (bp, 1);
DECL_EXTERNAL (expr) = (unsigned) bp_unpack_value (bp, 1);
DECL_GIMPLE_REG_P (expr) = (unsigned) bp_unpack_value (bp, 1);
DECL_NOT_GIMPLE_REG_P (expr) = (unsigned) bp_unpack_value (bp, 1);
SET_DECL_ALIGN (expr, (unsigned) bp_unpack_var_len_unsigned (bp));
#ifdef ACCEL_COMPILER
if (DECL_ALIGN (expr) > targetm.absolute_biggest_alignment)

View File

@ -201,7 +201,7 @@ pack_ts_decl_common_value_fields (struct bitpack_d *bp, tree expr)
bp_pack_value (bp, DECL_USER_ALIGN (expr), 1);
bp_pack_value (bp, DECL_PRESERVE_P (expr), 1);
bp_pack_value (bp, DECL_EXTERNAL (expr), 1);
bp_pack_value (bp, DECL_GIMPLE_REG_P (expr), 1);
bp_pack_value (bp, DECL_NOT_GIMPLE_REG_P (expr), 1);
bp_pack_var_len_unsigned (bp, DECL_ALIGN (expr));
if (TREE_CODE (expr) == LABEL_DECL)

View File

@ -2646,8 +2646,8 @@ extern machine_mode vector_type_mode (const_tree);
they are killing assignments. Thus the variable may now
be treated as a GIMPLE register, and use real instead of
virtual ops in SSA form. */
#define DECL_GIMPLE_REG_P(DECL) \
DECL_COMMON_CHECK (DECL)->decl_common.gimple_reg_flag
#define DECL_NOT_GIMPLE_REG_P(DECL) \
DECL_COMMON_CHECK (DECL)->decl_common.not_gimple_reg_flag
extern tree decl_value_expr_lookup (tree);
extern void decl_value_expr_insert (tree, tree);