summaryrefslogtreecommitdiff
path: root/gcc/tree-outof-ssa.c
diff options
context:
space:
mode:
authormatz <matz@138bc75d-0d04-0410-961f-82ee72b054a4>2010-03-15 16:13:28 +0000
committermatz <matz@138bc75d-0d04-0410-961f-82ee72b054a4>2010-03-15 16:13:28 +0000
commit5b6554fe6b055223340c34dab17087bece883928 (patch)
tree5a505839c11d52bcf64285b3e5d865e171c3e908 /gcc/tree-outof-ssa.c
parentb090365431fecbd240a2cf6bd0713f9f7421927d (diff)
downloadgcc-5b6554fe6b055223340c34dab17087bece883928.tar.gz
PR middle-end/43300
* tree-outof-ssa.c (emit_partition_copy): New argument sizeexp, use it to expand block copies. (insert_partition_copy_on_edge, insert_rtx_to_part_on_edge, insert_part_to_rtx_on_edge): Adjust callers of emit_partition_copy. (insert_value_copy_on_edge): Use store_expr for BLKmode values. testsuite/ * gcc.dg/pr43300.c: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@157461 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-outof-ssa.c')
-rw-r--r--gcc/tree-outof-ssa.c39
1 files changed, 30 insertions, 9 deletions
diff --git a/gcc/tree-outof-ssa.c b/gcc/tree-outof-ssa.c
index 32aa464948b..ac1641fc8e8 100644
--- a/gcc/tree-outof-ssa.c
+++ b/gcc/tree-outof-ssa.c
@@ -140,10 +140,12 @@ set_location_for_edge (edge e)
}
}
-/* 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;
@@ -151,7 +153,13 @@ emit_partition_copy (rtx dest, rtx src, int unsignedsrcp)
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 ();
@@ -164,6 +172,7 @@ emit_partition_copy (rtx dest, rtx src, int unsignedsrcp)
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))
{
@@ -183,10 +192,11 @@ insert_partition_copy_on_edge (edge e, int dest, int src, source_location locus)
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);
}
@@ -232,6 +242,11 @@ insert_value_copy_on_edge (edge e, int dest, tree src, source_location locus)
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);
@@ -269,9 +284,13 @@ insert_rtx_to_part_on_edge (edge e, int dest, rtx src, int unsignedsrcp,
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);
}
@@ -282,6 +301,7 @@ insert_rtx_to_part_on_edge (edge e, int dest, rtx src, int unsignedsrcp,
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))
{
@@ -300,10 +320,11 @@ insert_part_to_rtx_on_edge (edge e, rtx dest, int src, source_location locus)
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);
}