aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Weigand <uweigand@de.ibm.com>2007-02-21 15:05:01 +0000
committerUlrich Weigand <uweigand@gcc.gnu.org>2007-02-21 15:05:01 +0000
commit551d69292f127eb1625d3d4f56d57049876c581f (patch)
treec499bc04c3f21099f3f26ea278da323d2ed87637
parent71d6fc6b0b32ba0b1c1aabe9ccac7ff0e069dbb2 (diff)
downloadgcc-551d69292f127eb1625d3d4f56d57049876c581f.zip
gcc-551d69292f127eb1625d3d4f56d57049876c581f.tar.gz
gcc-551d69292f127eb1625d3d4f56d57049876c581f.tar.bz2
re PR middle-end/30761 (Error: unsupported relocation against sfp)
PR middle-end/30761 * reload1.c (eliminate_regs_in_insn): In the single_set special case, attempt to re-recognize the insn before falling back to having reload fix it up. From-SVN: r122199
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/reload1.c42
2 files changed, 24 insertions, 25 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a9513ed..59d93bb 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2007-02-21 Ulrich Weigand <uweigand@de.ibm.com>
+
+ PR middle-end/30761
+ * reload1.c (eliminate_regs_in_insn): In the single_set special
+ case, attempt to re-recognize the insn before falling back to
+ having reload fix it up.
+
2007-02-20 Eric Christopher <echristo@gmail.com>
* config/frv/frv.c (frv_read_argument): Take a tree and int argument.
diff --git a/gcc/reload1.c b/gcc/reload1.c
index 1ea559e..c86b2bd 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -3105,35 +3105,15 @@ eliminate_regs_in_insn (rtx insn, int replace)
if (GET_CODE (XEXP (plus_cst_src, 0)) == SUBREG)
to_rtx = gen_lowpart (GET_MODE (XEXP (plus_cst_src, 0)),
to_rtx);
- if (offset == 0)
- {
- int num_clobbers;
- /* We assume here that if we need a PARALLEL with
- CLOBBERs for this assignment, we can do with the
- MATCH_SCRATCHes that add_clobbers allocates.
- There's not much we can do if that doesn't work. */
- PATTERN (insn) = gen_rtx_SET (VOIDmode,
- SET_DEST (old_set),
- to_rtx);
- num_clobbers = 0;
- INSN_CODE (insn) = recog (PATTERN (insn), insn, &num_clobbers);
- if (num_clobbers)
- {
- rtvec vec = rtvec_alloc (num_clobbers + 1);
-
- vec->elem[0] = PATTERN (insn);
- PATTERN (insn) = gen_rtx_PARALLEL (VOIDmode, vec);
- add_clobbers (PATTERN (insn), INSN_CODE (insn));
- }
- gcc_assert (INSN_CODE (insn) >= 0);
- }
/* If we have a nonzero offset, and the source is already
a simple REG, the following transformation would
increase the cost of the insn by replacing a simple REG
with (plus (reg sp) CST). So try only when we already
had a PLUS before. */
- else if (plus_src)
+ if (offset == 0 || plus_src)
{
+ rtx new_src = plus_constant (to_rtx, offset);
+
new_body = old_body;
if (! replace)
{
@@ -3144,8 +3124,20 @@ eliminate_regs_in_insn (rtx insn, int replace)
PATTERN (insn) = new_body;
old_set = single_set (insn);
- XEXP (SET_SRC (old_set), 0) = to_rtx;
- XEXP (SET_SRC (old_set), 1) = GEN_INT (offset);
+ /* First see if this insn remains valid when we make the
+ change. If not, try to replace the whole pattern with
+ a simple set (this may help if the original insn was a
+ PARALLEL that was only recognized as single_set due to
+ REG_UNUSED notes). If this isn't valid either, keep
+ the INSN_CODE the same and let reload fix it up. */
+ if (!validate_change (insn, &SET_SRC (old_set), new_src, 0))
+ {
+ rtx new_pat = gen_rtx_SET (VOIDmode,
+ SET_DEST (old_set), new_src);
+
+ if (!validate_change (insn, &PATTERN (insn), new_pat, 0))
+ SET_SRC (old_set) = new_src;
+ }
}
else
break;