> * 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