aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid S. Miller <davem@redhat.com>1999-12-16 06:55:20 -0800
committerDavid S. Miller <davem@gcc.gnu.org>1999-12-16 06:55:20 -0800
commit235ae7be493fb15e5d2e4a91d4cee93b936892fe (patch)
tree8b10d0d0570d060cfccda5f4153ec233e94bf95b
parent5b772bbdc0d20de1c4ab781611b5e5566ec45ecc (diff)
downloadgcc-235ae7be493fb15e5d2e4a91d4cee93b936892fe.zip
gcc-235ae7be493fb15e5d2e4a91d4cee93b936892fe.tar.gz
gcc-235ae7be493fb15e5d2e4a91d4cee93b936892fe.tar.bz2
expr.c (emit_move_insn_1): Only emit clobbers if one of the outputs is a SUBREG.
* expr.c (emit_move_insn_1): Only emit clobbers if one of the outputs is a SUBREG. * rtlanal.c (reg_overlap_mentioned_p): Revert December 15th change. From-SVN: r30979
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/expr.c49
-rw-r--r--gcc/rtlanal.c7
3 files changed, 44 insertions, 19 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8e5cf15..5ffd5e2 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+1999-12-16 David S. Miller <davem@redhat.com>
+
+ * expr.c (emit_move_insn_1): Only emit clobbers if one of
+ the outputs is a SUBREG.
+ * rtlanal.c (reg_overlap_mentioned_p): Revert December 15th
+ change.
+
Thu Dec 16 11:33:57 MET 1999 Jan Hubicka <hubicka@freesoft.cz>
* toplev.c (rest_of_compilation): Run branch shortening after
diff --git a/gcc/expr.c b/gcc/expr.c
index 902c624..ac01d28 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -2638,6 +2638,9 @@ emit_move_insn_1 (x, y)
}
else
{
+ rtx realpart_x, realpart_y;
+ rtx imagpart_x, imagpart_y;
+
/* If this is a complex value with each part being smaller than a
word, the usual calling sequence will likely pack the pieces into
a single register. Unfortunately, SUBREG of hard registers only
@@ -2687,19 +2690,27 @@ emit_move_insn_1 (x, y)
}
}
- /* Show the output dies here. This is necessary for pseudos;
+ realpart_x = gen_realpart (submode, x);
+ realpart_y = gen_realpart (submode, y);
+ imagpart_x = gen_imagpart (submode, x);
+ imagpart_y = gen_imagpart (submode, y);
+
+ /* Show the output dies here. This is necessary for SUBREGs
+ of pseudos since we cannot track their lifetimes correctly;
hard regs shouldn't appear here except as return values.
We never want to emit such a clobber after reload. */
if (x != y
- && ! (reload_in_progress || reload_completed))
+ && ! (reload_in_progress || reload_completed)
+ && (GET_CODE (realpart_x) == SUBREG
+ || GET_CODE (imagpart_x) == SUBREG))
{
emit_insn (gen_rtx_CLOBBER (VOIDmode, x));
}
emit_insn (GEN_FCN (mov_optab->handlers[(int) submode].insn_code)
- (gen_realpart (submode, x), gen_realpart (submode, y)));
+ (realpart_x, realpart_y));
emit_insn (GEN_FCN (mov_optab->handlers[(int) submode].insn_code)
- (gen_imagpart (submode, x), gen_imagpart (submode, y)));
+ (imagpart_x, imagpart_y));
}
return get_last_insn ();
@@ -2711,6 +2722,8 @@ emit_move_insn_1 (x, y)
else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
{
rtx last_insn = 0;
+ rtx seq;
+ int need_clobber;
#ifdef PUSH_ROUNDING
@@ -2723,15 +2736,9 @@ emit_move_insn_1 (x, y)
}
#endif
- /* Show the output dies here. This is necessary for pseudos;
- hard regs shouldn't appear here except as return values.
- We never want to emit such a clobber after reload. */
- if (x != y
- && ! (reload_in_progress || reload_completed))
- {
- emit_insn (gen_rtx_CLOBBER (VOIDmode, x));
- }
+ start_sequence ();
+ need_clobber = 0;
for (i = 0;
i < (GET_MODE_SIZE (mode) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD;
i++)
@@ -2753,9 +2760,27 @@ emit_move_insn_1 (x, y)
if (xpart == 0 || ypart == 0)
abort ();
+ need_clobber |= (GET_CODE (xpart) == SUBREG);
+
last_insn = emit_move_insn (xpart, ypart);
}
+ seq = gen_sequence ();
+ end_sequence ();
+
+ /* Show the output dies here. This is necessary for SUBREGs
+ of pseudos since we cannot track their lifetimes correctly;
+ hard regs shouldn't appear here except as return values.
+ We never want to emit such a clobber after reload. */
+ if (x != y
+ && ! (reload_in_progress || reload_completed)
+ && need_clobber != 0)
+ {
+ emit_insn (gen_rtx_CLOBBER (VOIDmode, x));
+ }
+
+ emit_insn (seq);
+
return last_insn;
}
else
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index 63bff3d..838ca9da 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -964,13 +964,6 @@ reg_overlap_mentioned_p (x, in)
return 1;
return 0;
}
- else if (GET_CODE (x) == CONCAT)
- {
- if (reg_overlap_mentioned_p (XEXP (x, 0), in)
- || reg_overlap_mentioned_p (XEXP (x, 1), in))
- return 1;
- return 0;
- }
else
abort ();