This is the mail archive of the gcc-patches@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: [PATCH] x86-64: Load external function address via GOT slot


On Mon, Jun 20, 2016 at 9:19 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Mon, Jun 20, 2016 at 12:13 PM, Uros Bizjak <ubizjak@gmail.com> wrote:
>> On Mon, Jun 20, 2016 at 7:05 PM, H.J. Lu <hongjiu.lu@intel.com> wrote:
>>> Hi,
>>>
>>> This patch implements the alternate code sequence recommended in
>>>
>>> https://groups.google.com/forum/#!topic/x86-64-abi/de5_KnLHxtI
>>>
>>> to load external function address via GOT slot with
>>>
>>> movq func@GOTPCREL(%rip), %rax
>>>
>>> so that linker won't create an PLT entry for extern function
>>> address.
>>>
>>> Tested on x86-64.  OK for trunk?
>>
>>> +  else if (ix86_force_load_from_GOT_p (op1))
>>> +    {
>>> +      /* Load the external function address via the GOT slot to
>>> +        avoid PLT.  */
>>> +      op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op1),
>>> +                           (TARGET_64BIT
>>> +                            ? UNSPEC_GOTPCREL
>>> +                            : UNSPEC_GOT));
>>> +      op1 = gen_rtx_CONST (Pmode, op1);
>>> +      op1 = gen_const_mem (Pmode, op1);
>>> +      /* This symbol must be referenced via a load from the Global
>>> +        Offset Table.  */
>>> +      set_mem_alias_set (op1, ix86_GOT_alias_set ());
>>> +      op1 = convert_to_mode (mode, op1, 1);
>>> +      op1 = force_reg (mode, op1);
>>> +      emit_insn (gen_rtx_SET (op0, op1));
>>> +      /* Generate a CLOBBER so that there will be no REG_EQUAL note
>>> +        on the last insn to prevent cse and fwprop from replacing
>>> +        a GOT load with a constant.  */
>>> +      rtx tmp = gen_reg_rtx (Pmode);
>>> +      emit_clobber (tmp);
>>> +      return;
>>
>> Jeff, is this the recommended way to prevent CSE, as far as RTL
>> infrastructure is concerned? I didn't find any example of this
>> approach with other targets.
>>
>
> FWIW, the similar approach is used in ix86_expand_vector_move_misalign,
> ix86_expand_convert_uns_didf_sse and ix86_expand_vector_init_general
> as well as other targets:
>
> frv/frv.c:  emit_clobber (op0);
> frv/frv.c:  emit_clobber (op1);
> im32c/m32c.c:  /*  emit_clobber (gen_rtx_REG (HImode, R0L_REGNO)); */
> s390/s390.c:  emit_clobber (addr);
> s390/s390.md:  emit_clobber (reg0);
> s390/s390.md:  emit_clobber (reg1);
> s390/s390.md:  emit_clobber (reg0);
> s390/s390.md:  emit_clobber (reg0);
> s390/s390.md:  emit_clobber (reg1);

These usages mark the whole register as being "clobbered"
(=undefined), before only a part of register is written, e.g.:

      emit_clobber (int_xmm);
      emit_move_insn (gen_lowpart (DImode, int_xmm), input);

They aren't used to prevent unwanted CSE.

Uros.


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