expr.c (store_expr_with_bounds): Handle aggregate moves from BLKmode.

* 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.

From-SVN: r228586
This commit is contained in:
Jan Hubicka 2015-10-08 00:54:35 +02:00 committed by Jan Hubicka
parent d44bd40ef0
commit ee3db47daa
3 changed files with 30 additions and 10 deletions

View File

@ -1,3 +1,10 @@
2015-10-07 Jan Hubicka <hubicka@ucw.cz>
* 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.
2015-10-07 Jeff Law <law@redhat.com>
* tree-ssa-dom.c (optimize_stmt): Don't set LOOPS_NEED_FIXUP here.
@ -5,7 +12,6 @@
here instead. Tighten test to avoid setting LOOPS_NEED_FIXUP
unnecessarily.
@@ -1848,12 +1848,6 @@ optimize_stmt (basic_block bb, gimple_stmt_iterator si,
2015-10-07 Aditya Kumar <aditya.k7@samsung.com>
Sebastian Pop <s.pop@samsung.com>

View File

@ -5425,6 +5425,14 @@ store_expr_with_bounds (tree exp, rtx target, int call_param_p,
temp = convert_modes (GET_MODE (target), TYPE_MODE (TREE_TYPE (exp)),
temp, TYPE_UNSIGNED (TREE_TYPE (exp)));
/* We allow move between structures of same size but different mode.
If source is in memory and the mode differs, simply change the memory. */
if (GET_MODE (temp) == BLKmode && GET_MODE (target) != BLKmode)
{
gcc_assert (MEM_P (temp));
temp = adjust_address_nv (temp, GET_MODE (target), 0);
}
/* If value was not generated in the target, store it there.
Convert the value to TARGET's type first if necessary and emit the
pending incrementations that have been queued when expanding EXP.

View File

@ -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;
}