This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch committed SH] Fix PR target/43744
- From: Kaz Kojima <kkojima at rr dot iij4u dot or dot jp>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 23 Apr 2010 07:04:22 +0900 (JST)
- Subject: [patch committed SH] Fix PR target/43744
Hi,
I've committed the attached patch on mainline to fix
PR target/43744
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43744.
The PR is reported against 4.4 and looks latent for 4.5 and
trunk. The patch is a bit overkill in theory, but I can't
find any regressions in code size and performance for CSiBE
and some other tests with -fpic -O2. So this simple patch
would be enough to fix that corner case. I'll apply it on
4.4 and 4.5 when it's tested successfully on those branches.
Regards,
kaz
--
2010-04-22 Kaz Kojima <kkojima@gcc.gnu.org>
PR target/43744
* config/sh/sh.c (find_barrier): Don't emit a constant pool
in the middle of insns for casesi_worker_2.
--- ORIG/trunk/gcc/config/sh/sh.c 2010-04-18 10:27:25.000000000 +0900
+++ trunk/gcc/config/sh/sh.c 2010-04-18 20:54:32.000000000 +0900
@@ -4410,6 +4410,7 @@ find_barrier (int num_mova, rtx mova, rt
int hi_limit;
rtx orig = from;
rtx last_got = NULL_RTX;
+ rtx last_symoff = NULL_RTX;
/* For HImode: range is 510, add 4 because pc counts from address of
second instruction after this one, subtract 2 for the jump instruction
@@ -4551,6 +4552,16 @@ find_barrier (int num_mova, rtx mova, rt
{
switch (untangle_mova (&num_mova, &mova, from))
{
+ case 1:
+ if (flag_pic)
+ {
+ rtx src = SET_SRC (PATTERN (from));
+ if (GET_CODE (src) == CONST
+ && GET_CODE (XEXP (src, 0)) == UNSPEC
+ && XINT (XEXP (src, 0), 1) == UNSPEC_SYMOFF)
+ last_symoff = from;
+ }
+ break;
case 0: return find_barrier (0, 0, mova);
case 2:
{
@@ -4654,6 +4665,12 @@ find_barrier (int num_mova, rtx mova, rt
so we'll make one. */
rtx label = gen_label_rtx ();
+ /* Don't emit a constant table in the middle of insns for
+ casesi_worker_2. This is a bit overkill but is enough
+ because casesi_worker_2 wouldn't appear so frequently. */
+ if (last_symoff)
+ from = last_symoff;
+
/* If we exceeded the range, then we must back up over the last
instruction we looked at. Otherwise, we just need to undo the
NEXT_INSN at the end of the loop. */