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?


On 09/02/16 14:56, Ilya Enkovich wrote:
> 2016-02-09 17:27 GMT+03:00 Bin.Cheng <amker.cheng@gmail.com>:
>> On Fri, Feb 5, 2016 at 10:32 AM, Ilya Enkovich <enkovich.gnu@gmail.com> wrote:
>>> 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.
>>
>> 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.
> 
> I agree it looks inconsistent.  But I don't think PIC_OFFSET_TABLE_REGNUM is
> supposed to return pseudo regno.  Using EBX_REG value for this macro was a
> workaround for problem of NULL pic_offset_table_rtx usage in cost
> functions. I think
> we should try to initialize pic_offset_table_rtx with some pseudo
> register in i386
> target for cost estimation purposes and always return INVALID_REG for
> PIC_OFFSET_TABLE_REGNUM.
> 

The ARM port has been using a pseudo for P_O_T_R for many years now.  It
needs some care to establish it correctly in the prologue when needed,
but otherwise works very well.  It means that leaf functions in
particular can be made much more efficient as they can pick a
call-clobbered register when that's desirable.

R.

> Thanks,
> Ilya
> 
>>
>> Thanks,
>> bin
>>>
>>> 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]