}
}
-/* Emit insns to copy SRC into DEST converting SRC if necessary. */
+/* Emit insns to copy SRC into DEST converting SRC if necessary. As
+ SRC/DEST might be BLKmode memory locations SIZEEXP is a tree from
+ which we deduce the size to copy in that case. */
static inline rtx
-emit_partition_copy (rtx dest, rtx src, int unsignedsrcp)
+emit_partition_copy (rtx dest, rtx src, int unsignedsrcp, tree sizeexp)
{
rtx seq;
if (GET_MODE (src) != VOIDmode && GET_MODE (src) != GET_MODE (dest))
src = convert_to_mode (GET_MODE (dest), src, unsignedsrcp);
- emit_move_insn (dest, src);
+ if (GET_MODE (src) == BLKmode)
+ {
+ gcc_assert (GET_MODE (dest) == BLKmode);
+ emit_block_move (dest, src, expr_size (sizeexp), BLOCK_OP_NORMAL);
+ }
+ else
+ emit_move_insn (dest, src);
seq = get_insns ();
end_sequence ();
static void
insert_partition_copy_on_edge (edge e, int dest, int src, source_location locus)
{
+ tree var;
rtx seq;
if (dump_file && (dump_flags & TDF_DETAILS))
{
if (locus)
set_curr_insn_source_location (locus);
+ var = partition_to_var (SA.map, src);
seq = emit_partition_copy (SA.partition_to_pseudo[dest],
SA.partition_to_pseudo[src],
- TYPE_UNSIGNED (TREE_TYPE (
- partition_to_var (SA.map, src))));
+ TYPE_UNSIGNED (TREE_TYPE (var)),
+ var);
insert_insn_on_edge (seq, e);
}
x = expand_expr (src, NULL, src_mode, EXPAND_NORMAL);
x = convert_modes (dest_mode, src_mode, x, unsignedp);
}
+ else if (src_mode == BLKmode)
+ {
+ x = SA.partition_to_pseudo[dest];
+ store_expr (src, x, 0, false);
+ }
else
x = expand_expr (src, SA.partition_to_pseudo[dest],
dest_mode, EXPAND_NORMAL);
if (locus)
set_curr_insn_source_location (locus);
+ /* We give the destination as sizeexp in case src/dest are BLKmode
+ mems. Usually we give the source. As we result from SSA names
+ the left and right size should be the same (and no WITH_SIZE_EXPR
+ involved), so it doesn't matter. */
seq = emit_partition_copy (SA.partition_to_pseudo[dest],
- src,
- unsignedsrcp);
+ src, unsignedsrcp,
+ partition_to_var (SA.map, dest));
insert_insn_on_edge (seq, e);
}
static void
insert_part_to_rtx_on_edge (edge e, rtx dest, int src, source_location locus)
{
+ tree var;
rtx seq;
if (dump_file && (dump_flags & TDF_DETAILS))
{
if (locus)
set_curr_insn_source_location (locus);
+ var = partition_to_var (SA.map, src);
seq = emit_partition_copy (dest,
SA.partition_to_pseudo[src],
- TYPE_UNSIGNED (TREE_TYPE (
- partition_to_var (SA.map, src))));
+ TYPE_UNSIGNED (TREE_TYPE (var)),
+ var);
insert_insn_on_edge (seq, e);
}