summaryrefslogtreecommitdiff
path: root/gcc/gimple-expr.c
diff options
context:
space:
mode:
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2015-10-07 22:54:35 +0000
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2015-10-07 22:54:35 +0000
commit54ac7405ce75c141dae33532d491d5793fb583e3 (patch)
tree42a9c5df71558c4b9f561422da10083a7fc6fc6c /gcc/gimple-expr.c
parent5b4ada2a11ab19842d77296fc4b75971ddb07434 (diff)
downloadgcc-54ac7405ce75c141dae33532d491d5793fb583e3.tar.gz
* expr.c (store_expr_with_bounds): Handle aggregate moves from
BLKmode. * gimple-expr.c (useless_type_conversion_p): Do not use TYPE_CANONICAL to define gimple type system; compare aggregates only by size. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@228586 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/gimple-expr.c')
-rw-r--r--gcc/gimple-expr.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/gcc/gimple-expr.c b/gcc/gimple-expr.c
index baed63011fa..2a6ba1aadb9 100644
--- a/gcc/gimple-expr.c
+++ b/gcc/gimple-expr.c
@@ -87,11 +87,6 @@ useless_type_conversion_p (tree outer_type, tree inner_type)
if (inner_type == outer_type)
return true;
- /* If we know the canonical types, compare them. */
- if (TYPE_CANONICAL (inner_type)
- && TYPE_CANONICAL (inner_type) == TYPE_CANONICAL (outer_type))
- return true;
-
/* Changes in machine mode are never useless conversions unless we
deal with aggregate types in which case we defer to later checks. */
if (TYPE_MODE (inner_type) != TYPE_MODE (outer_type)
@@ -270,12 +265,23 @@ useless_type_conversion_p (tree outer_type, tree inner_type)
return true;
}
- /* For aggregates we rely on TYPE_CANONICAL exclusively and require
- explicit conversions for types involving to be structurally
- compared types. */
+ /* For aggregates compare only the size. Accesses to fields do have
+ a type information by themselves and thus we only care if we can i.e.
+ use the types in move operations. */
else if (AGGREGATE_TYPE_P (inner_type)
&& TREE_CODE (inner_type) == TREE_CODE (outer_type))
- return false;
+ return (!TYPE_SIZE (outer_type)
+ || (TYPE_SIZE (inner_type)
+ && operand_equal_p (TYPE_SIZE (inner_type),
+ TYPE_SIZE (outer_type), 0)));
+
+ else if (TREE_CODE (inner_type) == OFFSET_TYPE
+ && TREE_CODE (outer_type) == OFFSET_TYPE)
+ return useless_type_conversion_p (TREE_TYPE (outer_type),
+ TREE_TYPE (inner_type))
+ && useless_type_conversion_p
+ (TYPE_OFFSET_BASETYPE (outer_type),
+ TYPE_OFFSET_BASETYPE (inner_type));
return false;
}