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: Inconsistent initialization for pic_offset_table_rtx?


2016-02-04 19:16 GMT+03:00 Bin.Cheng <amker.cheng@gmail.com>:
> On Thu, Feb 4, 2016 at 3:18 PM, Ilya Enkovich <enkovich.gnu@gmail.com> wrote:
>> 2016-02-04 17:12 GMT+03:00 Bin.Cheng <amker.cheng@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.

Thanks,
Ilya

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


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