>       * config/i386/i386.c (avoid_plt_to_call): New function.
>       (ix86_output_call_insn): Generate indirect call for functions
>       marked with "noplt" attribute.
>       (attribute_spec ix86_attribute_): Define new attribute "noplt".
>       * doc/extend.texi: Document new attribute "noplt".
>       * gcc.target/i386/noplt-1.c: New testcase.
>       * gcc.target/i386/noplt-2.c: New testcase.
> 
> Index: config/i386/i386.c
> ===================================================================
> --- config/i386/i386.c        (revision 223720)
> +++ config/i386/i386.c        (working copy)
> @@ -25599,6 +25599,24 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx call
>    return call;
>  }
>  
> +/* Return true if the function being called was marked with attribute
> +   "noplt".  If this function is defined, this should return false.  */
> +static bool
> +avoid_plt_to_call (rtx call_op)
> +{
> +  if (SYMBOL_REF_LOCAL_P (call_op))
> +    return false;
> +
> +  tree symbol_decl = SYMBOL_REF_DECL (call_op);
> +
> +  if (symbol_decl != NULL_TREE
> +      && TREE_CODE (symbol_decl) == FUNCTION_DECL
> +      && lookup_attribute ("noplt", DECL_ATTRIBUTES (symbol_decl)))
> +    return true;
> +
> +  return false;
> +}

OK, now we have __attribute__ (optimize("noplt")) which binds to the caller and 
makes
all calls in the function to skip PLT and __attribute__ ("noplt") which binds 
to callee
and makes all calls to function to not use PLT.

That sort of makes sense to me, but why "noplt" attribute is not implemented at 
generic level
just like -fplt? Is it only because every target supporting PLT would need 
update in its
call expansion patterns?

Also I think the PLT calls have EBX in call fusage wich is added by 
ix86_expand_call.
  else                                                                          
    {                                                                           
      /* Static functions and indirect calls don't need the pic register.  */   
      if (flag_pic                                                              
          && (!TARGET_64BIT                                                     
              || (ix86_cmodel == CM_LARGE_PIC                                   
                  && DEFAULT_ABI != MS_ABI))                                    
          && GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF                          
          && ! SYMBOL_REF_LOCAL_P (XEXP (fnaddr, 0)))                           
        {                                                                       
          use_reg (&use, gen_rtx_REG (Pmode, REAL_PIC_OFFSET_TABLE_REGNUM));    
          if (ix86_use_pseudo_pic_reg ())                                       
            emit_move_insn (gen_rtx_REG (Pmode, REAL_PIC_OFFSET_TABLE_REGNUM),  
                            pic_offset_table_rtx);                              
        }                                                                       

I think you want to take that away from FUSAGE there just like we do for local 
calls
(and in fact the code should already check flag_pic && flag_plt I suppose.

Honza

Reply via email to