Commit f4088621 by Richard Guenther Committed by Richard Biener

re PR middle-end/15988 (ICE in fold_convert with pointer-to-member-function)

2007-07-02  Richard Guenther  <rguenther@suse.de>

	* tree-flow.h (types_compatible_p): Declare.
	* tree-ssa.c (types_compatible_p): New function.
	* ipa-type-escape.c (discover_unique_type): Use
	types_compatible_p instead of lang_hooks.types_compatible_p.
	* tree-ssa-copyrename.c (copy_rename_partition_coalesce): Likewise.
	* tree-vn.c (expressions_equal_p): Likewise.
	* tree.c (fields_compatible_p): Likewise.
	* tree-ssa-dom.c (avail_expr_eq): Likewise.
	(cprop_operand): Use useless_type_conversion_p instead of
	lang_hooks.types_compatible_p.
	* tree-inline.c (setup_one_parameter): Likewise.
	(declare_return_variable): Likewise.
	* tree-nrv.c (tree_nrv): Likewise.
	* tree-ssa-ccp.c (maybe_fold_offset_to_array_ref): Likewise.
	(maybe_fold_offset_to_component_ref): Likewise.
	(maybe_fold_offset_to_reference): Likewise.
	* tree-ssa-copy.c (may_propagate_copy): Likewise.
	(merge_alias_info): Likewise.
	* tree-ssa-forwprop.c (forward_propagate_addr_expr_1): Likewise.
	* tree-ssa-phiopt.c (conditional_replacement): Likewise.
	* tree-ssa-reassoc.c (optimize_ops_list): Likewise.
	* tree-tailcall.c (find_tail_calls): Likewise.
	* tree-vect-generic.c (expand_vector_operations_1): Likewise.
	* gimplify.c (canonicalize_addr_expr): Likewise.
	(fold_indirect_ref_rhs): Likewise.
	(gimplify_addr_expr): Likewise.  Swap parameters to cpt_same_type.
	(cpt_same_type): Likewise.
	(check_pointer_types_r): Swap parameters to cpt_same_type
	where appropriate.
	* fold-const.c (fold_convert): Revert fix for PR15988.
	* tree-inline.c (setup_one_parameter): Instead fix it here by
	using fold_build1 instead of fold_convert and checking for
	error_mark_node.  Convert only if the conversion is necessary.

From-SVN: r126198
parent e51917ae
2007-07-02 Richard Guenther <rguenther@suse.de>
* tree-flow.h (types_compatible_p): Declare.
* tree-ssa.c (types_compatible_p): New function.
* ipa-type-escape.c (discover_unique_type): Use
types_compatible_p instead of lang_hooks.types_compatible_p.
* tree-ssa-copyrename.c (copy_rename_partition_coalesce): Likewise.
* tree-vn.c (expressions_equal_p): Likewise.
* tree.c (fields_compatible_p): Likewise.
* tree-ssa-dom.c (avail_expr_eq): Likewise.
(cprop_operand): Use useless_type_conversion_p instead of
lang_hooks.types_compatible_p.
* tree-inline.c (setup_one_parameter): Likewise.
(declare_return_variable): Likewise.
* tree-nrv.c (tree_nrv): Likewise.
* tree-ssa-ccp.c (maybe_fold_offset_to_array_ref): Likewise.
(maybe_fold_offset_to_component_ref): Likewise.
(maybe_fold_offset_to_reference): Likewise.
* tree-ssa-copy.c (may_propagate_copy): Likewise.
(merge_alias_info): Likewise.
* tree-ssa-forwprop.c (forward_propagate_addr_expr_1): Likewise.
* tree-ssa-phiopt.c (conditional_replacement): Likewise.
* tree-ssa-reassoc.c (optimize_ops_list): Likewise.
* tree-tailcall.c (find_tail_calls): Likewise.
* tree-vect-generic.c (expand_vector_operations_1): Likewise.
* gimplify.c (canonicalize_addr_expr): Likewise.
(fold_indirect_ref_rhs): Likewise.
(gimplify_addr_expr): Likewise. Swap parameters to cpt_same_type.
(cpt_same_type): Likewise.
(check_pointer_types_r): Swap parameters to cpt_same_type
where appropriate.
* fold-const.c (fold_convert): Revert fix for PR15988.
* tree-inline.c (setup_one_parameter): Instead fix it here by
using fold_build1 instead of fold_convert and checking for
error_mark_node. Convert only if the conversion is necessary.
2007-07-02 Joseph Myers <joseph@codesourcery.com> 2007-07-02 Joseph Myers <joseph@codesourcery.com>
* configure.ac: Check for .gnu_attribute on Power. * configure.ac: Check for .gnu_attribute on Power.
......
...@@ -2262,9 +2262,7 @@ fold_convert (tree type, tree arg) ...@@ -2262,9 +2262,7 @@ fold_convert (tree type, tree arg)
|| TREE_CODE (orig) == ERROR_MARK) || TREE_CODE (orig) == ERROR_MARK)
return error_mark_node; return error_mark_node;
if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (orig) if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (orig))
|| lang_hooks.types_compatible_p (TYPE_MAIN_VARIANT (type),
TYPE_MAIN_VARIANT (orig)))
return fold_build1 (NOP_EXPR, type, arg); return fold_build1 (NOP_EXPR, type, arg);
switch (TREE_CODE (type)) switch (TREE_CODE (type))
......
...@@ -1599,13 +1599,13 @@ canonicalize_addr_expr (tree *expr_p) ...@@ -1599,13 +1599,13 @@ canonicalize_addr_expr (tree *expr_p)
/* Both cast and addr_expr types should address the same object type. */ /* Both cast and addr_expr types should address the same object type. */
dctype = TREE_TYPE (ctype); dctype = TREE_TYPE (ctype);
ddatype = TREE_TYPE (datype); ddatype = TREE_TYPE (datype);
if (!lang_hooks.types_compatible_p (ddatype, dctype)) if (!useless_type_conversion_p (dctype, ddatype))
return; return;
/* The addr_expr and the object type should match. */ /* The addr_expr and the object type should match. */
obj_expr = TREE_OPERAND (addr_expr, 0); obj_expr = TREE_OPERAND (addr_expr, 0);
otype = TREE_TYPE (obj_expr); otype = TREE_TYPE (obj_expr);
if (!lang_hooks.types_compatible_p (otype, datype)) if (!useless_type_conversion_p (datype, otype))
return; return;
/* The lower bound and element sizes must be constant. */ /* The lower bound and element sizes must be constant. */
...@@ -3304,11 +3304,11 @@ fold_indirect_ref_rhs (tree t) ...@@ -3304,11 +3304,11 @@ fold_indirect_ref_rhs (tree t)
tree op = TREE_OPERAND (sub, 0); tree op = TREE_OPERAND (sub, 0);
tree optype = TREE_TYPE (op); tree optype = TREE_TYPE (op);
/* *&p => p */ /* *&p => p */
if (lang_hooks.types_compatible_p (type, optype)) if (useless_type_conversion_p (type, optype))
return op; return op;
/* *(foo *)&fooarray => fooarray[0] */ /* *(foo *)&fooarray => fooarray[0] */
else if (TREE_CODE (optype) == ARRAY_TYPE else if (TREE_CODE (optype) == ARRAY_TYPE
&& lang_hooks.types_compatible_p (type, TREE_TYPE (optype))) && useless_type_conversion_p (type, TREE_TYPE (optype)))
{ {
tree type_domain = TYPE_DOMAIN (optype); tree type_domain = TYPE_DOMAIN (optype);
tree min_val = size_zero_node; tree min_val = size_zero_node;
...@@ -3320,7 +3320,7 @@ fold_indirect_ref_rhs (tree t) ...@@ -3320,7 +3320,7 @@ fold_indirect_ref_rhs (tree t)
/* *(foo *)fooarrptr => (*fooarrptr)[0] */ /* *(foo *)fooarrptr => (*fooarrptr)[0] */
if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE
&& lang_hooks.types_compatible_p (type, TREE_TYPE (TREE_TYPE (subtype)))) && useless_type_conversion_p (type, TREE_TYPE (TREE_TYPE (subtype))))
{ {
tree type_domain; tree type_domain;
tree min_val = size_zero_node; tree min_val = size_zero_node;
...@@ -3974,14 +3974,15 @@ gimplify_addr_expr (tree *expr_p, tree *pre_p, tree *post_p) ...@@ -3974,14 +3974,15 @@ gimplify_addr_expr (tree *expr_p, tree *pre_p, tree *post_p)
tree t_expr = TREE_TYPE (expr); tree t_expr = TREE_TYPE (expr);
tree t_op00 = TREE_TYPE (op00); tree t_op00 = TREE_TYPE (op00);
if (!lang_hooks.types_compatible_p (t_expr, t_op00)) if (!useless_type_conversion_p (t_expr, t_op00))
{ {
#ifdef ENABLE_CHECKING #ifdef ENABLE_CHECKING
tree t_op0 = TREE_TYPE (op0); tree t_op0 = TREE_TYPE (op0);
gcc_assert (POINTER_TYPE_P (t_expr) gcc_assert (POINTER_TYPE_P (t_expr)
&& cpt_same_type (TREE_CODE (t_op0) == ARRAY_TYPE && (cpt_same_type (TREE_TYPE (t_expr), t_op0)
? TREE_TYPE (t_op0) : t_op0, || (TREE_CODE (t_op0) == ARRAY_TYPE
TREE_TYPE (t_expr)) && cpt_same_type (TREE_TYPE (t_expr),
TREE_TYPE (t_op0))))
&& POINTER_TYPE_P (t_op00) && POINTER_TYPE_P (t_op00)
&& cpt_same_type (t_op0, TREE_TYPE (t_op00))); && cpt_same_type (t_op0, TREE_TYPE (t_op00)));
#endif #endif
...@@ -6385,7 +6386,7 @@ gimplify_one_sizepos (tree *expr_p, tree *stmt_p) ...@@ -6385,7 +6386,7 @@ gimplify_one_sizepos (tree *expr_p, tree *stmt_p)
static bool static bool
cpt_same_type (tree a, tree b) cpt_same_type (tree a, tree b)
{ {
if (lang_hooks.types_compatible_p (a, b)) if (useless_type_conversion_p (a, b))
return true; return true;
/* ??? The C++ FE decomposes METHOD_TYPES to FUNCTION_TYPES and doesn't /* ??? The C++ FE decomposes METHOD_TYPES to FUNCTION_TYPES and doesn't
...@@ -6436,7 +6437,7 @@ check_pointer_types_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, ...@@ -6436,7 +6437,7 @@ check_pointer_types_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
ptype = TREE_TYPE (t); ptype = TREE_TYPE (t);
otype = TREE_TYPE (TREE_OPERAND (t, 0)); otype = TREE_TYPE (TREE_OPERAND (t, 0));
dtype = TREE_TYPE (ptype); dtype = TREE_TYPE (ptype);
if (!cpt_same_type (otype, dtype)) if (!cpt_same_type (dtype, otype))
{ {
/* &array is allowed to produce a pointer to the element, rather than /* &array is allowed to produce a pointer to the element, rather than
a pointer to the array type. We must allow this in order to a pointer to the array type. We must allow this in order to
...@@ -6444,7 +6445,7 @@ check_pointer_types_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, ...@@ -6444,7 +6445,7 @@ check_pointer_types_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
pointer to the element type. */ pointer to the element type. */
gcc_assert (TREE_CODE (otype) == ARRAY_TYPE gcc_assert (TREE_CODE (otype) == ARRAY_TYPE
&& POINTER_TYPE_P (ptype) && POINTER_TYPE_P (ptype)
&& cpt_same_type (TREE_TYPE (otype), dtype)); && cpt_same_type (dtype, TREE_TYPE (otype)));
break; break;
} }
break; break;
......
...@@ -219,7 +219,7 @@ discover_unique_type (tree type) ...@@ -219,7 +219,7 @@ discover_unique_type (tree type)
/* Create an alias since this is just the same as /* Create an alias since this is just the same as
other_type. */ other_type. */
tree other_type = (tree) result->value; tree other_type = (tree) result->value;
if (lang_hooks.types_compatible_p (type, other_type) == 1) if (types_compatible_p (type, other_type))
{ {
free (brand); free (brand);
/* Insert this new type as an alias for other_type. */ /* Insert this new type as an alias for other_type. */
......
...@@ -869,6 +869,7 @@ extern edge ssa_redirect_edge (edge, basic_block); ...@@ -869,6 +869,7 @@ extern edge ssa_redirect_edge (edge, basic_block);
extern void flush_pending_stmts (edge); extern void flush_pending_stmts (edge);
extern bool tree_ssa_useless_type_conversion (tree); extern bool tree_ssa_useless_type_conversion (tree);
extern bool useless_type_conversion_p (tree, tree); extern bool useless_type_conversion_p (tree, tree);
extern bool types_compatible_p (tree, tree);
extern void verify_ssa (bool); extern void verify_ssa (bool);
extern void delete_tree_ssa (void); extern void delete_tree_ssa (void);
extern void walk_use_def_chains (tree, walk_use_def_chains_fn, void *, bool); extern void walk_use_def_chains (tree, walk_use_def_chains_fn, void *, bool);
......
...@@ -1278,10 +1278,15 @@ setup_one_parameter (copy_body_data *id, tree p, tree value, tree fn, ...@@ -1278,10 +1278,15 @@ setup_one_parameter (copy_body_data *id, tree p, tree value, tree fn,
tree init_stmt; tree init_stmt;
tree var; tree var;
tree var_sub; tree var_sub;
tree rhs = value ? fold_convert (TREE_TYPE (p), value) : NULL; tree rhs = value;
tree def = (gimple_in_ssa_p (cfun) tree def = (gimple_in_ssa_p (cfun)
? gimple_default_def (id->src_cfun, p) : NULL); ? gimple_default_def (id->src_cfun, p) : NULL);
if (value
&& value != error_mark_node
&& !useless_type_conversion_p (TREE_TYPE (p), TREE_TYPE (value)))
rhs = fold_build1 (NOP_EXPR, TREE_TYPE (p), value);
/* If the parameter is never assigned to, has no SSA_NAMEs created, /* If the parameter is never assigned to, has no SSA_NAMEs created,
we may not need to create a new variable here at all. Instead, we may we may not need to create a new variable here at all. Instead, we may
be able to just use the argument value. */ be able to just use the argument value. */
...@@ -1295,7 +1300,8 @@ setup_one_parameter (copy_body_data *id, tree p, tree value, tree fn, ...@@ -1295,7 +1300,8 @@ setup_one_parameter (copy_body_data *id, tree p, tree value, tree fn,
It is not big deal to prohibit constant propagation here as It is not big deal to prohibit constant propagation here as
we will constant propagate in DOM1 pass anyway. */ we will constant propagate in DOM1 pass anyway. */
if (is_gimple_min_invariant (value) if (is_gimple_min_invariant (value)
&& lang_hooks.types_compatible_p (TREE_TYPE (value), TREE_TYPE (p)) && useless_type_conversion_p (TREE_TYPE (p),
TREE_TYPE (value))
/* We have to be very careful about ADDR_EXPR. Make sure /* We have to be very careful about ADDR_EXPR. Make sure
the base variable isn't a local variable of the inlined the base variable isn't a local variable of the inlined
function, e.g., when doing recursive inlining, direct or function, e.g., when doing recursive inlining, direct or
...@@ -1573,7 +1579,7 @@ declare_return_variable (copy_body_data *id, tree return_slot, tree modify_dest, ...@@ -1573,7 +1579,7 @@ declare_return_variable (copy_body_data *id, tree return_slot, tree modify_dest,
bool use_it = false; bool use_it = false;
/* We can't use MODIFY_DEST if there's type promotion involved. */ /* We can't use MODIFY_DEST if there's type promotion involved. */
if (!lang_hooks.types_compatible_p (caller_type, callee_type)) if (!useless_type_conversion_p (callee_type, caller_type))
use_it = false; use_it = false;
/* ??? If we're assigning to a variable sized type, then we must /* ??? If we're assigning to a variable sized type, then we must
...@@ -1637,7 +1643,7 @@ declare_return_variable (copy_body_data *id, tree return_slot, tree modify_dest, ...@@ -1637,7 +1643,7 @@ declare_return_variable (copy_body_data *id, tree return_slot, tree modify_dest,
/* Build the use expr. If the return type of the function was /* Build the use expr. If the return type of the function was
promoted, convert it back to the expected type. */ promoted, convert it back to the expected type. */
use = var; use = var;
if (!lang_hooks.types_compatible_p (TREE_TYPE (var), caller_type)) if (!useless_type_conversion_p (caller_type, TREE_TYPE (var)))
use = fold_convert (caller_type, var); use = fold_convert (caller_type, var);
STRIP_USELESS_TYPE_CONVERSION (use); STRIP_USELESS_TYPE_CONVERSION (use);
......
...@@ -159,8 +159,8 @@ tree_nrv (void) ...@@ -159,8 +159,8 @@ tree_nrv (void)
|| TREE_STATIC (found) || TREE_STATIC (found)
|| TREE_ADDRESSABLE (found) || TREE_ADDRESSABLE (found)
|| DECL_ALIGN (found) > DECL_ALIGN (result) || DECL_ALIGN (found) > DECL_ALIGN (result)
|| !lang_hooks.types_compatible_p (TREE_TYPE (found), || !useless_type_conversion_p (result_type,
result_type)) TREE_TYPE (found)))
return 0; return 0;
} }
else if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT) else if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
......
...@@ -1575,7 +1575,7 @@ maybe_fold_offset_to_array_ref (tree base, tree offset, tree orig_type) ...@@ -1575,7 +1575,7 @@ maybe_fold_offset_to_array_ref (tree base, tree offset, tree orig_type)
if (TREE_CODE (array_type) != ARRAY_TYPE) if (TREE_CODE (array_type) != ARRAY_TYPE)
return NULL_TREE; return NULL_TREE;
elt_type = TREE_TYPE (array_type); elt_type = TREE_TYPE (array_type);
if (!lang_hooks.types_compatible_p (orig_type, elt_type)) if (!useless_type_conversion_p (orig_type, elt_type))
return NULL_TREE; return NULL_TREE;
/* Use signed size type for intermediate computation on the index. */ /* Use signed size type for intermediate computation on the index. */
...@@ -1666,7 +1666,7 @@ maybe_fold_offset_to_component_ref (tree record_type, tree base, tree offset, ...@@ -1666,7 +1666,7 @@ maybe_fold_offset_to_component_ref (tree record_type, tree base, tree offset,
return NULL_TREE; return NULL_TREE;
/* Short-circuit silly cases. */ /* Short-circuit silly cases. */
if (lang_hooks.types_compatible_p (record_type, orig_type)) if (useless_type_conversion_p (record_type, orig_type))
return NULL_TREE; return NULL_TREE;
tail_array_field = NULL_TREE; tail_array_field = NULL_TREE;
...@@ -1704,7 +1704,7 @@ maybe_fold_offset_to_component_ref (tree record_type, tree base, tree offset, ...@@ -1704,7 +1704,7 @@ maybe_fold_offset_to_component_ref (tree record_type, tree base, tree offset,
/* Here we exactly match the offset being checked. If the types match, /* Here we exactly match the offset being checked. If the types match,
then we can return that field. */ then we can return that field. */
if (cmp == 0 if (cmp == 0
&& lang_hooks.types_compatible_p (orig_type, field_type)) && useless_type_conversion_p (orig_type, field_type))
{ {
if (base_is_ptr) if (base_is_ptr)
base = build1 (INDIRECT_REF, record_type, base); base = build1 (INDIRECT_REF, record_type, base);
...@@ -1809,7 +1809,7 @@ maybe_fold_offset_to_reference (tree base, tree offset, tree orig_type) ...@@ -1809,7 +1809,7 @@ maybe_fold_offset_to_reference (tree base, tree offset, tree orig_type)
sub_offset / BITS_PER_UNIT), 1); sub_offset / BITS_PER_UNIT), 1);
} }
} }
if (lang_hooks.types_compatible_p (orig_type, TREE_TYPE (base)) if (useless_type_conversion_p (orig_type, TREE_TYPE (base))
&& integer_zerop (offset)) && integer_zerop (offset))
return base; return base;
type = TREE_TYPE (base); type = TREE_TYPE (base);
......
...@@ -130,7 +130,7 @@ may_propagate_copy (tree dest, tree orig) ...@@ -130,7 +130,7 @@ may_propagate_copy (tree dest, tree orig)
tree mt_orig = symbol_mem_tag (SSA_NAME_VAR (orig)); tree mt_orig = symbol_mem_tag (SSA_NAME_VAR (orig));
if (mt_dest && mt_orig && mt_dest != mt_orig) if (mt_dest && mt_orig && mt_dest != mt_orig)
return false; return false;
else if (!lang_hooks.types_compatible_p (type_d, type_o)) else if (!useless_type_conversion_p (type_d, type_o))
return false; return false;
else if (get_alias_set (TREE_TYPE (type_d)) != else if (get_alias_set (TREE_TYPE (type_d)) !=
get_alias_set (TREE_TYPE (type_o))) get_alias_set (TREE_TYPE (type_o)))
...@@ -222,8 +222,8 @@ merge_alias_info (tree orig_name, tree new_name) ...@@ -222,8 +222,8 @@ merge_alias_info (tree orig_name, tree new_name)
gcc_assert (POINTER_TYPE_P (TREE_TYPE (new_name))); gcc_assert (POINTER_TYPE_P (TREE_TYPE (new_name)));
#if defined ENABLE_CHECKING #if defined ENABLE_CHECKING
gcc_assert (lang_hooks.types_compatible_p (TREE_TYPE (orig_name), gcc_assert (useless_type_conversion_p (TREE_TYPE (orig_name),
TREE_TYPE (new_name))); TREE_TYPE (new_name)));
/* If the pointed-to alias sets are different, these two pointers /* If the pointed-to alias sets are different, these two pointers
would never have the same memory tag. In this case, NEW should would never have the same memory tag. In this case, NEW should
......
...@@ -240,7 +240,7 @@ copy_rename_partition_coalesce (var_map map, tree var1, tree var2, FILE *debug) ...@@ -240,7 +240,7 @@ copy_rename_partition_coalesce (var_map map, tree var1, tree var2, FILE *debug)
} }
/* Don't coalesce if the two variables aren't type compatible. */ /* Don't coalesce if the two variables aren't type compatible. */
if (!lang_hooks.types_compatible_p (TREE_TYPE (root1), TREE_TYPE (root2))) if (!types_compatible_p (TREE_TYPE (root1), TREE_TYPE (root2)))
{ {
if (debug) if (debug)
fprintf (debug, " : Incompatible types. No coalesce.\n"); fprintf (debug, " : Incompatible types. No coalesce.\n");
......
...@@ -1680,7 +1680,7 @@ cprop_operand (tree stmt, use_operand_p op_p) ...@@ -1680,7 +1680,7 @@ cprop_operand (tree stmt, use_operand_p op_p)
propagation opportunity. */ propagation opportunity. */
if (TREE_CODE (val) != SSA_NAME) if (TREE_CODE (val) != SSA_NAME)
{ {
if (!lang_hooks.types_compatible_p (op_type, val_type)) if (!useless_type_conversion_p (op_type, val_type))
{ {
val = fold_convert (TREE_TYPE (op), val); val = fold_convert (TREE_TYPE (op), val);
if (!is_gimple_min_invariant (val)) if (!is_gimple_min_invariant (val))
...@@ -2048,8 +2048,7 @@ avail_expr_eq (const void *p1, const void *p2) ...@@ -2048,8 +2048,7 @@ avail_expr_eq (const void *p1, const void *p2)
/* In case of a collision, both RHS have to be identical and have the /* In case of a collision, both RHS have to be identical and have the
same VUSE operands. */ same VUSE operands. */
if ((TREE_TYPE (rhs1) == TREE_TYPE (rhs2) if (types_compatible_p (TREE_TYPE (rhs1), TREE_TYPE (rhs2))
|| lang_hooks.types_compatible_p (TREE_TYPE (rhs1), TREE_TYPE (rhs2)))
&& operand_equal_p (rhs1, rhs2, OEP_PURE_SAME)) && operand_equal_p (rhs1, rhs2, OEP_PURE_SAME))
{ {
bool ret = compare_ssa_operands_equal (stmt1, stmt2, SSA_OP_VUSE); bool ret = compare_ssa_operands_equal (stmt1, stmt2, SSA_OP_VUSE);
......
...@@ -670,7 +670,7 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs, tree use_stmt, ...@@ -670,7 +670,7 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs, tree use_stmt,
&& TREE_CODE (TREE_OPERAND (rhs, 1)) == SSA_NAME && TREE_CODE (TREE_OPERAND (rhs, 1)) == SSA_NAME
/* Avoid problems with IVopts creating PLUS_EXPRs with a /* Avoid problems with IVopts creating PLUS_EXPRs with a
different type than their operands. */ different type than their operands. */
&& lang_hooks.types_compatible_p (TREE_TYPE (name), TREE_TYPE (rhs))) && useless_type_conversion_p (TREE_TYPE (rhs), TREE_TYPE (name)))
{ {
bool res; bool res;
......
...@@ -401,7 +401,7 @@ conditional_replacement (basic_block cond_bb, basic_block middle_bb, ...@@ -401,7 +401,7 @@ conditional_replacement (basic_block cond_bb, basic_block middle_bb,
cond = COND_EXPR_COND (last_stmt (cond_bb)); cond = COND_EXPR_COND (last_stmt (cond_bb));
result = PHI_RESULT (phi); result = PHI_RESULT (phi);
if (TREE_CODE (cond) != SSA_NAME if (TREE_CODE (cond) != SSA_NAME
&& !lang_hooks.types_compatible_p (TREE_TYPE (cond), TREE_TYPE (result))) && !useless_type_conversion_p (TREE_TYPE (result), TREE_TYPE (cond)))
{ {
tree tmp; tree tmp;
...@@ -418,7 +418,7 @@ conditional_replacement (basic_block cond_bb, basic_block middle_bb, ...@@ -418,7 +418,7 @@ conditional_replacement (basic_block cond_bb, basic_block middle_bb,
/* If the condition was a naked SSA_NAME and the type is not the /* If the condition was a naked SSA_NAME and the type is not the
same as the type of the result, then convert the type of the same as the type of the result, then convert the type of the
condition. */ condition. */
if (!lang_hooks.types_compatible_p (TREE_TYPE (cond), TREE_TYPE (result))) if (!useless_type_conversion_p (TREE_TYPE (result), TREE_TYPE (cond)))
cond = fold_convert (TREE_TYPE (result), cond); cond = fold_convert (TREE_TYPE (result), cond);
/* We need to know which is the true edge and which is the false /* We need to know which is the true edge and which is the false
......
...@@ -727,8 +727,8 @@ optimize_ops_list (enum tree_code opcode, ...@@ -727,8 +727,8 @@ optimize_ops_list (enum tree_code opcode,
if (oelm1->rank == 0 if (oelm1->rank == 0
&& is_gimple_min_invariant (oelm1->op) && is_gimple_min_invariant (oelm1->op)
&& lang_hooks.types_compatible_p (TREE_TYPE (oelm1->op), && useless_type_conversion_p (TREE_TYPE (oelm1->op),
TREE_TYPE (oelast->op))) TREE_TYPE (oelast->op)))
{ {
tree folded = fold_binary (opcode, TREE_TYPE (oelm1->op), tree folded = fold_binary (opcode, TREE_TYPE (oelm1->op),
oelm1->op, oelast->op); oelm1->op, oelast->op);
......
...@@ -971,6 +971,17 @@ useless_type_conversion_p (tree outer_type, tree inner_type) ...@@ -971,6 +971,17 @@ useless_type_conversion_p (tree outer_type, tree inner_type)
return false; return false;
} }
/* Return true if a conversion from either type of TYPE1 and TYPE2
to the other is not required. Otherwise return false. */
bool
types_compatible_p (tree type1, tree type2)
{
return (type1 == type2
|| (useless_type_conversion_p (type1, type2)
&& useless_type_conversion_p (type2, type1)));
}
/* Return true if EXPR is a useless type conversion, otherwise return /* Return true if EXPR is a useless type conversion, otherwise return
false. */ false. */
......
...@@ -448,8 +448,8 @@ find_tail_calls (basic_block bb, struct tailcall **ret) ...@@ -448,8 +448,8 @@ find_tail_calls (basic_block bb, struct tailcall **ret)
equivalent types. The latter requirement could be relaxed if equivalent types. The latter requirement could be relaxed if
we emitted a suitable type conversion statement. */ we emitted a suitable type conversion statement. */
if (!is_gimple_reg_type (TREE_TYPE (param)) if (!is_gimple_reg_type (TREE_TYPE (param))
|| !lang_hooks.types_compatible_p (TREE_TYPE (param), || !useless_type_conversion_p (TREE_TYPE (param),
TREE_TYPE (arg))) TREE_TYPE (arg)))
break; break;
/* The parameter should be a real operand, so that phi node /* The parameter should be a real operand, so that phi node
......
...@@ -469,7 +469,7 @@ expand_vector_operations_1 (block_stmt_iterator *bsi) ...@@ -469,7 +469,7 @@ expand_vector_operations_1 (block_stmt_iterator *bsi)
gcc_assert (code != VEC_LSHIFT_EXPR && code != VEC_RSHIFT_EXPR); gcc_assert (code != VEC_LSHIFT_EXPR && code != VEC_RSHIFT_EXPR);
rhs = expand_vector_operation (bsi, type, compute_type, rhs, code); rhs = expand_vector_operation (bsi, type, compute_type, rhs, code);
if (lang_hooks.types_compatible_p (TREE_TYPE (lhs), TREE_TYPE (rhs))) if (useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
*p_rhs = rhs; *p_rhs = rhs;
else else
*p_rhs = gimplify_build1 (bsi, VIEW_CONVERT_EXPR, TREE_TYPE (lhs), rhs); *p_rhs = gimplify_build1 (bsi, VIEW_CONVERT_EXPR, TREE_TYPE (lhs), rhs);
......
...@@ -84,7 +84,8 @@ expressions_equal_p (tree e1, tree e2) ...@@ -84,7 +84,8 @@ expressions_equal_p (tree e1, tree e2)
} }
else if (TREE_CODE (e1) == TREE_CODE (e2) else if (TREE_CODE (e1) == TREE_CODE (e2)
&& (te1 == te2 || lang_hooks.types_compatible_p (te1, te2)) && (te1 == te2
|| types_compatible_p (te1, te2))
&& operand_equal_p (e1, e2, OEP_PURE_SAME)) && operand_equal_p (e1, e2, OEP_PURE_SAME))
return true; return true;
......
...@@ -7714,7 +7714,7 @@ fields_compatible_p (tree f1, tree f2) ...@@ -7714,7 +7714,7 @@ fields_compatible_p (tree f1, tree f2)
DECL_FIELD_OFFSET (f2), OEP_ONLY_CONST)) DECL_FIELD_OFFSET (f2), OEP_ONLY_CONST))
return false; return false;
if (!lang_hooks.types_compatible_p (TREE_TYPE (f1), TREE_TYPE (f2))) if (!types_compatible_p (TREE_TYPE (f1), TREE_TYPE (f2)))
return false; return false;
return true; return true;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment