This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Fix PR middle-end/28690, indexed load/store performance + reload bug
On Thu, Dec 07, 2006 at 06:00:30PM +0100, Ulrich Weigand wrote:
> Merge the two branches of the "if" into something like:
>
> if (offset == 0 || plus_src)
> {
> ... modeled after the current offset == 0 case, except
> for replacing to_rtx with plus_constant (to_rtx, offset)
> in this line:
>
> PATTERN (insn) = gen_rtx_SET (VOIDmode,
> SET_DEST (old_set),
> to_rtx);
>
> }
> else
> break;
It fixed the reported problem, but now we hit a problem during bootstrap.
Using the diff below, the problematic call to eliminate_regs_in_insn
sees this insn:
(insn:HI 176 157 267 4 (set (reg/f:SI 65 lr [265])
(plus:SI (reg/f:SI 113 sfp)
(const_int 12 [0xc]))) 79 {*addsi3_internal1} (nil)
(expr_list:REG_EQUIV (plus:SI (reg/f:SI 113 sfp)
(const_int 12 [0xc]))
(nil)))
We end up in the modified code below with the "eliminated" insn now looking
like:
(insn:HI 176 157 267 4 (set (reg/f:SI 65 lr [265])
(plus:SI (reg/f:SI 1 1)
(const_int 12 [0xc]))) 79 {*addsi3_internal1} (nil)
(expr_list:REG_EQUIV (plus:SI (reg/f:SI 113 sfp)
(const_int 12 [0xc]))
(nil)))
So we haven't eliminated the regs in the REG_EQUIV note. We then die in
the gcc_assert (INSN_CODE (insn) >= 0). I thought it might be due to
the REG_EQUIV not be "eliminate"'d before calling recog, but that doesn't
seem to be the case, since I used to debugger to manually eliminate it
before calling recog(), and we still end up dying. Any idea what's
wrong now?
Peter
Index: reload1.c
===================================================================
--- reload1.c (revision 119613)
+++ reload1.c (working copy)
@@ -3098,7 +3098,7 @@
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)
+ if (offset == 0 || plus_src)
{
int num_clobbers;
/* We assume here that if we need a PARALLEL with
@@ -3107,7 +3107,7 @@
There's not much we can do if that doesn't work. */
PATTERN (insn) = gen_rtx_SET (VOIDmode,
SET_DEST (old_set),
- to_rtx);
+ plus_constant (to_rtx, offset));
num_clobbers = 0;
INSN_CODE (insn) = recog (PATTERN (insn), insn, &num_clobbers);
if (num_clobbers)
@@ -3120,26 +3120,6 @@
}
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)
- {
- new_body = old_body;
- if (! replace)
- {
- new_body = copy_insn (old_body);
- if (REG_NOTES (insn))
- REG_NOTES (insn) = copy_insn_1 (REG_NOTES (insn));
- }
- 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);
- }
else
break;