If-conversion misses many cases

Jan Hoogerbrugge hoogerbrugge@hotmail.com
Wed Feb 25 12:23:00 GMT 2004


>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/



More information about the Gcc mailing list