This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Inconsistent initialization for pic_offset_table_rtx?
- From: "Bin.Cheng" <amker dot cheng at gmail dot com>
- To: Ilya Enkovich <enkovich dot gnu at gmail dot com>
- Cc: "gcc at gcc dot gnu dot org" <gcc at gcc dot gnu dot org>
- Date: Tue, 9 Feb 2016 15:13:35 +0000
- Subject: Re: Inconsistent initialization for pic_offset_table_rtx?
- Authentication-results: sourceware.org; auth=none
- References: <CAHFci28XosGqkHXjA1_=XU3f6M2anq4NTwCntY5adV+JKeD-Zw at mail dot gmail dot com> <CAMbmDYbN7DJJuXPhQ-8TpYh2Yj9bFcP1MyncNr9iaS9LX9L1+Q at mail dot gmail dot com> <CAHFci2-Qb1NadLD+CUEOSBcbqrc74cMaQV_=fatw9AB47dFakQ at mail dot gmail dot com> <CAMbmDYaeO1RCjZUV5EMC3Q2ip1r=Sggymd=8qqwRPpUGYvEB4w at mail dot gmail dot com> <CAHFci2992=9Y8qNiKskbyaS770zJng7tDoqDaGnCg69w=fXePw at mail dot gmail dot com> <CAMbmDYYX3UUCHsaOLyTyjRb=nt0Y6axF4XZedLVBPG2DBo7KAA at mail dot gmail dot com>
On Tue, Feb 9, 2016 at 2:56 PM, Ilya Enkovich <enkovich.gnu@gmail.com> 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.
Hi IIya,
Could you please test a patch in this way? You are more experienced
than me here.
Thanks,
bin
>
> Thanks,
> Ilya
>
>>
>> Thanks,
>> bin
>>>
>>> Thanks,
>>> Ilya
>>>
>>>>
>>>> Thanks,
>>>> bin
>>>>>
>>>>> Thanks,
>>>>> Ilya
>>>>>
>>>>>>
>>>>>> Thanks,
>>>>>> bin