2016-02-09 17:27 GMT+03:00 Bin.Cheng <amker.ch...@gmail.com>: > 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.
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. Thanks, Ilya > > Thanks, > bin >> >> Thanks, >> Ilya >> >>> >>> Thanks, >>> bin >>>> >>>> Thanks, >>>> Ilya >>>> >>>>> >>>>> Thanks, >>>>> bin