[PATCH] Run life analysis after optimize_mode_switching pass.
Uros Bizjak
ubizjak@gmail.com
Tue Jul 12 13:29:00 GMT 2005
Hello!
If optimize_mode_switching pass inserts instructions that change
global registers, they change global register life info at boundaries
of basic blocks. To avoid the mess, global register life data should
be updated just after optimize_mode_switching pass.
Additionally, a global variable mode_switching_completed was added.
This variable is nonzero after mode_switching pass ends (no kidding
:-). This variable can be used in ix86_epilogue_uses (),
ix86_call_insn_uses () and ix86_call_insn_sets () functions, that need
correct emms/efpu insn already inserted to maintain correct register
life data.
By using this flag, these functions are "activated" in just added
register life analysis after mode switching pass, so correct global
register life info is supplied to register allocator.
Without this patch, global register info in loops is wrong for x87/MMX
switching pass, so reload1.c ICEs with 'unable to spill...' message.
Patch was regtested and bootstrapped (with changes to i386.c shown
below) on i686-pc-linux-gnu.
BTW: These problems were found with a follow-up patch to MMX/x87
switching that enables vector operations on MMX registers (with emms
insn placed correctly). With attached patch, I was able to compile
(for example):
#define N 16
int ia[N];
int ic[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
int ib[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
int test () {
int i;
for (i = 0; i < 4; i++)
ia[i] = ib[i] + ic[i];
return 0;
}
with 'gcc -O2 -ftree-vectorize -mmmx' into:
test:
pushl %ebp
xorl %eax, %eax
movl %esp, %ebp
.p2align 4,,15
.L2:
movq ib(,%eax,8), %mm0
paddd ic(,%eax,8), %mm0
movq %mm0, ia(,%eax,8)
incl %eax
cmpl $2, %eax
jne .L2
emms
xorl %eax, %eax
popl %ebp
ret
The relevant part of i386.c should be changed to include
mode_switching_completed flag:
--cut here--
/* Return true to prevent register allocator from allocating registers
from the unit that is not active. */
bool
ix86_epilogue_uses (int regno)
{
int mode;
if (! mode_switching_completed)
return false;
mode = ix86_mode_exit (I387_FPU_MODE);
if (mode == FPU_MODE_MMX)
return TARGET_80387 && FP_REGNO_P (regno);
else
return TARGET_MMX && MMX_REGNO_P (regno);
}
/* Return RTX code of additional register that CALL_INSN uses.
This function is used to maintain correct register life
information before CALL_INSN in case of MMX/x87 switching. */
rtx
ix86_call_insn_uses (rtx insn)
{
int mode;
if (! mode_switching_completed)
return NULL_RTX;
gcc_assert (CALL_P (insn));
mode = ix86_mode_needed (I387_FPU_MODE, insn);
if (mode == FPU_MODE_MMX)
{
if (TARGET_80387)
return gen_rtx_REG (ALLREGSmode, FIRST_FLOAT_REG);
}
else
{
if (TARGET_MMX)
return gen_rtx_REG (ALLREGSmode, FIRST_MMX_REG);
}
return NULL_RTX;
}
/* Return RTX code of additional register that CALL_INSN sets.
This function is used to maintain correct register life
information after CALL_INSN in case of MMX/x87 switching. */
rtx
ix86_call_insn_sets (rtx insn)
{
int mode;
if (! mode_switching_completed)
return NULL_RTX;
gcc_assert (CALL_P (insn));
/* Note that current mode in call to ix86_mode_after
is arbitrary for CALL_INSNs. */
mode = ix86_mode_after (I387_FPU_MODE, 0, insn);
if (mode == FPU_MODE_MMX)
{
if (TARGET_80387)
return gen_rtx_REG (ALLREGSmode, FIRST_FLOAT_REG);
}
else
{
if (TARGET_MMX)
return gen_rtx_REG (ALLREGSmode, FIRST_MMX_REG);
}
return NULL_RTX;
}
--cut here--
2005-07-12 Uros Bizjak <uros@kss-loka.si>
* rtl.h (extern int mode_switching_completed): New.
* mode-switching.c (mode_switching_completed): New global variable.
(rest_of_handle_mode_switching): Set mode_switching_compleded
after optimize_mode_switching pass. Perform life analysis after
optimize_mode_switching pass.
Uros.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: opmode.diff
Type: application/octet-stream
Size: 1360 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20050712/57b6873d/attachment.obj>
More information about the Gcc-patches
mailing list