This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: If-conversion misses many cases


From: Jim Wilson <wilson@specifixinc.com>
Jan Hoogerbrugge wrote:
I see differences in the modified_in_p (test, insn) test in
cond_exec_process_insns. For IA64, this tests returns false, for my target
(TriMedia) it returns true, which causes that must_be_last is set and
that causes that cond_exec_process_insns returns false.

You should probably step through modified_in_p to see why it isn't working for your target.

The final decision that makes that no if conversion is done in the following case:

int s;
void foo(int a) { int *p = &s; if(a > 0) *p = 0; }

is made in refers_to_regno_p. The call stack is:

#0 refers_to_regno_p (regno=6, endregno=7, x=0x4007b330, loc=0x0)
at rtlanal.c:1514
#1 0x081fa48c in reg_overlap_mentioned_p (x=0x4007b360, in=0x4007b330)
at rtlanal.c:1554
#2 0x081f99dd in set_of_1 (x=0x4007b330, pat=0x40078420, data1=0xbfffe120)
at rtlanal.c:1173
#3 0x081fa841 in note_stores (x=0x40078420, fun=0x81f999a <set_of_1>,
data=0xbfffe120) at rtlanal.c:1685
#4 0x081f9a3a in set_of (pat=0x4007b360, insn=0x4001c398) at rtlanal.c:1186
#5 0x081f9350 in reg_set_p (reg=0x4007b360, insn=0x4001c398) at rtlanal.c:960
#6 0x081f97de in modified_in_p (x=0x4007b360, insn=0x4001c398)
at rtlanal.c:1106
#7 0x081f9831 in modified_in_p (x=0x40078930, insn=0x4001c398)
at rtlanal.c:1115
#8 0x082b1c3d in cond_exec_process_insns (ce_info=0xbfffe290, start=0x7,
end=0x4001c320, test=0x40078930, prob_val=0x40060540, mod_ok=1)
at ifcvt.c:293
#9 0x082b20f6 in cond_exec_process_if_block (ce_info=0xbfffe290,
do_multiple_p=1) at ifcvt.c:544
#10 0x082b4900 in process_if_block (ce_info=0xbfffe290) at ifcvt.c:2070


What worries me is that if-conversion is not happening in the following cases:

 void foo(int a) { int *p = &s; if(a > 0) *p = 0; }
 void foo2(int dummy, int a) { int *p = &s; if(a > 0) *p = 0; }

While it does happen in the following cases:

void foo3(int dummy, int dummy2, int a) { int *p = &s; if(a > 0) *p = 0; }
void foo4(int dummy, int dummy2, int dummy3, int a) { int *p = &s; if(a > 0) *p = 0; }


foo3 leads to the following code:

_foo3:
       .function
       /***************************/
       ileqi(0) r7 -> r7
       if !r7 uimm(_s) -> r6
       if !r7 st32 r6 r0               [ID=1019][REGION=1]
       /***************************/
       ijmpf r0 r2     /* return */
       .endfunction


It seems that if-conversion is blocked in the first two cases because of unlucky register allocation. If that is true, then is this a weakness of the if-conversion algorithm? Or could I make this less likely by some measures? I changed REG_ALLOC_ORDER so that function argument registers are not used first for register allocation but that did not help.


Another issue.... In the assembly code above you see that the instruction that loads the address of s in a register is also predicated. (That is also happening in the ia64 port). This is not necessary. In fact, it makes it dependent on the compare instruction which means less parallelism.

Jan

_________________________________________________________________
Play online games with your friends with MSN Messenger http://messenger.msn.nl/



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]