On Fri, Feb 5, 2016 at 10:32 AM, Ilya Enkovich <enkovich....@gmail.com> wrote:
> 2016-02-04 19:16 GMT+03:00 Bin.Cheng <amker.ch...@gmail.com>:
>> On Thu, Feb 4, 2016 at 3:18 PM, Ilya Enkovich <enkovich....@gmail.com> wrote:
>>> 2016-02-04 17:12 GMT+03:00 Bin.Cheng <amker.ch...@gmail.com>:
>>>> Hi,
>>>> I noticed that pic_offset_table_rtx is initialized twice in GCC.  Take
>>>> x86_32 as an example.
>>>> The first initialization is done in emit_init_regs, with below code:
>>>>
>>>>   pic_offset_table_rtx = NULL_RTX;
>>>>   if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
>>>>     pic_offset_table_rtx = gen_raw_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
>>>>
>>>> On x86_32 with pic, we have:
>>>>
>>>> (gdb) call debug_rtx(this_target_rtl->x_pic_offset_table_rtx)
>>>> (reg:SI 3 bx)
>>>>
>>>> The second initialization is in expand_used_vars, with below code:
>>>>
>>>>   if (targetm.use_pseudo_pic_reg ())
>>>>     pic_offset_table_rtx = gen_reg_rtx (Pmode);
>>>>
>>>> On x86_32 with pic, we have:
>>>>
>>>> (gdb) call debug_rtx(this_target_rtl->x_pic_offset_table_rtx)
>>>> (reg:SI 87)
>>>>
>>>> So basically after expanding the first function, pic_offset_table_rtx
>>>> is set to a pseudo register, rather than the one initialized in
>>>> emit_init_regs.
>>>>
>>>> Also this causes inconsistent compilation for the first/rest functions
>>>> in one compilation unit.
>>>>
>>>> A bug?
>>>
>>> For i386 target PIC_OFFSET_TABLE_REGNUM actually checks
>>> ix86_use_pseudo_pic_reg and is supposed to return INVALID_REGNUM
>>> in case we use pseudo register for PIC. BUT we hit a case when PIC
>>> code is generated for cost estimation via target hooks while performing
>>> some GIMPLE pass. In this case we need to return some register to
>> Thanks IIya.  This is exact the case I ran into.  See PR69042.
>>
>>> generate PIC usage but we don't have any allocated. In this case we
>>> return a hard register. We detect such situation by checking
>>> pic_offset_table_rtx.
>>>
>>> Thus if we use pseudo PIC register but pic_offset_table_rtx is not
>>> initialized yet,
>>> then PIC_OFFSET_TABLE_REGNUM returns a hard register.
>>>
>>> So I suppose we may consider the first assignment as a bug.
>>
>> But I don't quite follow.  So hard register is returned so that gimple
>> passes can construct PIC related addresses?  If this is the case, the
>> first initialization is necessary.
>
> Right, we need some initialization but current way leads to inconsistent
> value and we may 'randomly' get hard or pseudo register for different 
> functions
> which possibly affects some optimizations. We probably need a better
> way to check if we should return a hard reg for PIC register. Or maybe
> reset ix86_use_pseudo_pic_reg to NULL when function is finalized or
> get rid of hard reg at all and always use a pseudo register.
>
>> Another question is about address cost:
>>
>>   if (parts.index
>>       && (!REG_P (parts.index) || REGNO (parts.index) >= 
>> FIRST_PSEUDO_REGISTER)
>>       && (current_pass->type == GIMPLE_PASS
>>       || !pic_offset_table_rtx
>>       || !REG_P (parts.index)
>>       || REGNO (pic_offset_table_rtx) != REGNO (parts.index)))
>>     cost++;
>> Is it a bug in the second sub condition?  Considering
>> "current_pass->type == GIMPLE_PASS" in the third sub condition, can I
>> assume the second is for non-GIMPLE passes only?
>
> There is just a code duplicated for parts.base and parts.index
> registers. We use same
> conditions for both of them because you can easily swap them if scale is 1.
>
> I don't know why we don't try to recognize PIC registers when in GIMPLE pass.

Could we define PIC_OFFSET_TABLE_REGNUM to a pseudo register when
ix86_use_pseudo_pic_reg returns true, as in this case?  Current logic
doesn't look consistent to me.  Of course, I know little about x86.

Thanks,
bin
>
> Thanks,
> Ilya
>
>>
>> Thanks,
>> bin
>>>
>>> Thanks,
>>> Ilya
>>>
>>>>
>>>> Thanks,
>>>> bin

Reply via email to