Re: [PATCH v5] add -fprolog-pad=N,M option

2017-02-17 Thread Torsten Duwe
On Wed, Feb 08, 2017 at 12:48:56PM +0100, Jakub Jelinek wrote:
> 
> First of all, GCC is in stage4 and this isn't a fix for a regression, so it
> is not acceptable at this point.  Next stage1 will start in April or so.

I had gotten the impression there were sort of branches in the SCM; this
of course should go to HEAD / trunk / master or whatever it's called.

> The length of nop varies greatly across different architectures,
> some architectures have different spelling for it (e.g.
> ia64, s390{,x} use nop 0 and mmix uses swym 0), some architectures have
> tons of different nops with different sizes (see e.g. x86_64/i686), for some
> longer sizes it is often beneficial to emit a jump around the rest of nops
> instead of just tons of nops.
> 
> Even if it is counted always in nops and only nops are emitted (not really
> efficient, and I guess kernel cares about efficiency), the above is

Yes, efficiency is a goal, but not unchallenged. Besides, out of order micro-
architectures hardly suffer from NOPs inserted other than their occupation of
cache space and memory bandwidth. The worst impact I found on some in-order
aarch64 CPUs was a penalty of 1 clock cycle for 2 NOPs.

Note that this is a "you asked for it -- you get it" feature. Only if you
explicitly request those NOPs they will be inserted; normal operation is
unaffected.

> definitely not acceptable for a generic hook implementation, it contains too
> many ELF specific details as well as 64-bit target specific details etc.
> For the label, you should use something like:
>   static int ppad_no;
>   char tmp_label[...];
>   ASM_GENERATE_INTERNAL_LABEL (tmp_label, "LPPAD", ppad_no);
>   ppad_no++;
>   ASM_OUTPUT_LABEL (file, tmp_label);
> the "a",@progbits is not generic enough, you want
>   switch_to_section (get_section ("__prolog_pads_loc", 0, NULL));
> or so.  .previous doesn't work on many targets, you need to actuall switch
> to the previously current section.  .quad is not supported by many
> assemblers, you want assemble_integer, with the appropriate size (say
> derived from size of pointer), decide whether in that section everything is
> aligned or unaligned, emit aligning directive if the former.

Thanks a lot for this blueprint! It saved me half of the work for the rewrite!

> There are many other ways in which the ABI can check, e.g.
> see how i386.c (ix86_function_regparm) can change ABI if
>   cgraph_local_info *i = >local;
>   if (i && i->local && i->can_change_signature)
> So you'd e.g. need to make sure that functions you emit the padding for
> can't change signature.  Bet you won't be able to handle e.g. IPA cp or many
> other IPA optimizations that change signature too, while the function from
> the source may still be around, perhaps nothing will call it because the
> callers have been changed to call its clone with different arguments.
> Or say IPA-ICF, if you want to live-patch only some function and not another
> function which happens to have identical bogy in the end.

Indeed. Live patching needs to take more care. But as I wrote, it is only
_my_ current use case; the feature itself should be usable more widely.
I wouldn't want to restrict future users on what they can optimise and what
they can't. Maybe someone wants to measure exactly these effects?

The point is: whatever instructions are to replace those NOPs, they will
very likely need a register or two. With IPA-RA, all bets are off. Without,
you can assume the caller-save regs, the scratch regs and some intra-procedure
regs to be available. Please let's leave this all to the framework
implementers. The same goes for nops before or after the entry point. This
is only a _mechanism_.

Torsten



Re: [PATCH v5] add -fprolog-pad=N,M option

2017-02-17 Thread Torsten Duwe
On Wed, Feb 15, 2017 at 11:01:16AM +, Richard Earnshaw (lists) wrote:
> On 13/01/17 12:19, Torsten Duwe wrote:
> 
> > +++ b/gcc/doc/invoke.texi
> > @@ -11341,6 +11341,27 @@ of the function name, it is considered to be a 
> > match.  For C99 and C++
> >  extended identifiers, the function name must be given in UTF-8, not
> >  using universal character names.
> >  
> > +@item -fprolog-pad=@var{N},@var{M}
> This needs to make it clear that M is optional.  Then below state that
> if omitted, M defaults to zero.

It was mentioned, further down in the paragraph. I moved it up.

> > --- a/gcc/opts.c
> > +++ b/gcc/opts.c
> > @@ -2157,6 +2157,26 @@ common_handle_option (struct gcc_options *opts,
> >  opts->x_flag_ipa_reference = false;
> >break;
> >  
> > +case OPT_fprolog_pad_:
> > +  {
> > +   const char *comma = strchr (arg, ',');
> > +   if (comma)
> > + {
> > +   prolog_nop_pad_size = atoi (arg);
> > +   prolog_nop_pad_entry = atoi (comma + 1);
> > + }
> > +   else
> > + {
> > +   prolog_nop_pad_size = atoi (arg);
> > +   prolog_nop_pad_entry = 0;
> > + }
> 
> Where's the error checking?  If I write gibberish after the option name
> then atoi will silently fail and return zero.  I'm not overly familiar
> with the option handling code, but I'm sure we have routines to do the
> heavy lifting here.

Yes, I had already found integral_argument, but that's unsuitable for a
comma separated list, and arg is const so I could' punch a \0 there.
Using atoi was just lazy, admittedly.

> > +default_print_prolog_pad (FILE *file, unsigned HOST_WIDE_INT pad_size,
> > + bool record_p)
> > +{
> > +  if (record_p)
> > +fprintf (file, "1:");
> > +
> > +  unsigned i;
> > +  for (i = 0; i < pad_size; ++i)
> > +fprintf (file, "\tnop\n");
> > +
> > +  if (record_p)
> > +{
> > +  fprintf (file, "\t.section __prolog_pads_loc, \"a\",@progbits\n");
> > +  fprintf (file, "\t.quad 1b\n");
> > +  fprintf (file, "\t.previous\n");
> > +}
> > +}
> 
> NO!  Almost everything in this function is wrong, it needs to be done
> through suitable hooks that call into the machine back-ends that
> understand assembly flavours supported.

That was already mentioned in a previous version. That code assumes GAS+ELF.
It was the quick and dirty solution to get a working prototype.

Torsten



Re: [PATCH v5] add -fprolog-pad=N,M option

2017-02-15 Thread Richard Earnshaw (lists)
On 15/02/17 11:12, Marek Polacek wrote:
> On Wed, Feb 15, 2017 at 11:01:16AM +, Richard Earnshaw (lists) wrote:
>> On 13/01/17 12:19, Torsten Duwe wrote:
>>> Changes since v4: hopefully addressed all of Sandra's requests
>>> and suggestions concerning the documentation snippets, thanks
>>> for the feedback.  If it still isn't clear, feel free to rephrase
>>> -- I'm a programmer, not a technical writer.
>>>
>>
>> Generally, I find 'pad' somewhat confusing.  It's OK for the option name
>> itself, but more generally, we should be talking about either space or
>> number of instructions according to context.
>>
>>> 2017-01-13  Torsten Duwe : 
>>
>> Two spaces between date and name, two more between name and email, no
>> colon at the end.
>>
>>>
>>>  * c-family/c-attribs.c : introduce prolog_pad attribute and create
>>>a handler for it.
>>>
>>
>>
>> Don't leave blank lines between files mentioned here.  All lines should
>> be indented by /exactly/ one tab; don't add extra indentation for
>> continuation lines.  No space before colon.  Capital letter at start of
>> sentences, full stop at the end of each one.  Which function, or data
>> structure did you change (put the name in brackets before the colon)?
>> Document each function or variable changed.
>>
>> The above entry should read:
>>
>>  * c-family/c-attribs.c (c_common_attribute_table): Add entry
>>  for "prolog_pad".
>>  (handle_prolog_pad_attribute): New function.
> 
> Except that the c-family/ prefix shouldn't be there.
> 

Ah, I'd missed that it has its own ChangeLog file and thus needs to be
recorded separately.  Ergo, the LTO entry can't use Likewise since the
context for that will not be immediately above that entry...

R.

>   Marek
> 



Re: [PATCH v5] add -fprolog-pad=N,M option

2017-02-15 Thread Marek Polacek
On Wed, Feb 15, 2017 at 11:01:16AM +, Richard Earnshaw (lists) wrote:
> On 13/01/17 12:19, Torsten Duwe wrote:
> > Changes since v4: hopefully addressed all of Sandra's requests
> > and suggestions concerning the documentation snippets, thanks
> > for the feedback.  If it still isn't clear, feel free to rephrase
> > -- I'm a programmer, not a technical writer.
> > 
> 
> Generally, I find 'pad' somewhat confusing.  It's OK for the option name
> itself, but more generally, we should be talking about either space or
> number of instructions according to context.
> 
> > 2017-01-13  Torsten Duwe : 
> 
> Two spaces between date and name, two more between name and email, no
> colon at the end.
> 
> > 
> >  * c-family/c-attribs.c : introduce prolog_pad attribute and create
> >a handler for it.
> > 
> 
> 
> Don't leave blank lines between files mentioned here.  All lines should
> be indented by /exactly/ one tab; don't add extra indentation for
> continuation lines.  No space before colon.  Capital letter at start of
> sentences, full stop at the end of each one.  Which function, or data
> structure did you change (put the name in brackets before the colon)?
> Document each function or variable changed.
> 
> The above entry should read:
> 
>   * c-family/c-attribs.c (c_common_attribute_table): Add entry
>   for "prolog_pad".
>   (handle_prolog_pad_attribute): New function.

Except that the c-family/ prefix shouldn't be there.

Marek


Re: [PATCH v5] add -fprolog-pad=N,M option

2017-02-15 Thread Richard Earnshaw (lists)
On 13/01/17 12:19, Torsten Duwe wrote:
> Changes since v4: hopefully addressed all of Sandra's requests
> and suggestions concerning the documentation snippets, thanks
> for the feedback.  If it still isn't clear, feel free to rephrase
> -- I'm a programmer, not a technical writer.
> 

Generally, I find 'pad' somewhat confusing.  It's OK for the option name
itself, but more generally, we should be talking about either space or
number of instructions according to context.

> 2017-01-13Torsten Duwe : 

Two spaces between date and name, two more between name and email, no
colon at the end.

> 
>* c-family/c-attribs.c : introduce prolog_pad attribute and create
>  a handler for it.
> 


Don't leave blank lines between files mentioned here.  All lines should
be indented by /exactly/ one tab; don't add extra indentation for
continuation lines.  No space before colon.  Capital letter at start of
sentences, full stop at the end of each one.  Which function, or data
structure did you change (put the name in brackets before the colon)?
Document each function or variable changed.

The above entry should read:

* c-family/c-attribs.c (c_common_attribute_table): Add entry
for "prolog_pad".
(handle_prolog_pad_attribute): New function.

>* lto/lto-lang.c : Likewise.
You still need to name the objects affected, even if you can then use
likewise to refer to the immediately preceding entry.

> 
>* common.opt : introduce -fprolog_pad command line option
>  and its variables prolog_nop_pad_size and prolog_nop_pad_entry.
> 
>* doc/extend.texi : document prolog_pad attribute.
> 
>* doc/invoke.texi : document -fprolog_pad command line option.
> 
>* opts.c (OPT_fprolog_pad_): add parser.
> 
>* doc/tm.texi.in (TARGET_ASM_PRINT_PROLOG_PAD): new target hook
> 
>* doc/tm.texi : Likewise.
> 
>* target.def (print_prolog_pad): Likewise.
> 
>* targhooks.h (default_print_prolog_pad): new function.
> 
>* targhooks.c (default_print_prolog_pad): Likewise.
> 
>* testsuite/c-c++-common/attribute-prolog_pad-1.c : New test.
> 
>* toplev.c (process_options): Switch off IPA-RA if
>  prolog pads are being generated.
> 
>* varasm.c (assemble_start_function): look at prolog-pad command
>  line switch and function attributes and maybe generate NOP
>  pads by calling print_prolog_pad.
> 
> diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c
> index ce7fcaa..5c6cf1c 100644
> --- a/gcc/c-family/c-attribs.c
> +++ b/gcc/c-family/c-attribs.c
> @@ -139,6 +139,7 @@ static tree handle_bnd_variable_size_attribute (tree *, 
> tree, tree, int, bool *)
>  static tree handle_bnd_legacy (tree *, tree, tree, int, bool *);
>  static tree handle_bnd_instrument (tree *, tree, tree, int, bool *);
>  static tree handle_fallthrough_attribute (tree *, tree, tree, int, bool *);
> +static tree handle_prolog_pad_attribute (tree *, tree, tree, int, bool *);
>  
>  /* Table of machine-independent attributes common to all C-like languages.
>  
> @@ -345,6 +346,8 @@ const struct attribute_spec c_common_attribute_table[] =
> handle_bnd_instrument, false },
>{ "fallthrough", 0, 0, false, false, false,
> handle_fallthrough_attribute, false },
> +  { "prolog_pad",  1, 2, true, false, false,
> +   handle_prolog_pad_attribute, false },
>{ NULL, 0, 0, false, false, false, NULL, false }
>  };
>  
> @@ -3173,3 +3176,10 @@ handle_fallthrough_attribute (tree *, tree name, tree, 
> int,
>*no_add_attrs = true;
>return NULL_TREE;
>  }
> +
> +static tree
> +handle_prolog_pad_attribute (tree *, tree, tree, int,
> +  bool *)
> +{
> +  return NULL_TREE;
> +}
> diff --git a/gcc/common.opt b/gcc/common.opt
> index 8ad5b77..37d4009 100644
> --- a/gcc/common.opt
> +++ b/gcc/common.opt
> @@ -163,6 +163,13 @@ bool flag_stack_usage_info = false
>  Variable
>  int flag_debug_asm
>  
> +; If we should generate NOP pads before each function prologue

'If' suggests this is a boolean, but the declaration is for a count, so
this should be "Number of NOP instructions to insert before each
function prologue."

> +Variable
> +HOST_WIDE_INT prolog_nop_pad_size
> +
> +; And how far the asm entry point is into this pad
> +Variable
> +HOST_WIDE_INT prolog_nop_pad_entry
>  
>  ; Balance between GNAT encodings and standard DWARF to emit.
>  Variable
> @@ -2019,6 +2026,10 @@ fprofile-reorder-functions
>  Common Report Var(flag_profile_reorder_functions)
>  Enable function reordering that improves code placement.
>  
> +fprolog-pad=
> +Common Joined Optimization
> +Pad NOPs before each function prologue.
> +

Insert NOP instructions before ...

>  frandom-seed
>  Common Var(common_deferred_options) Defer
>  
> diff --git a/gcc/doc/extend.texi 

Re: [PATCH v5] add -fprolog-pad=N,M option

2017-02-08 Thread Jakub Jelinek
On Wed, Feb 08, 2017 at 12:18:05PM +0100, Torsten Duwe wrote:
> On Mon, Jan 23, 2017 at 05:25:45PM +0100, Bernd Schmidt wrote:
> > There's still a a few details that need addressing, and some questions I
> > have. Also Ccing Jakub to have another pair of eyes on the name of the
> > section - I don't know if we want some sort of .gnu.something name.
> 
> So Jakub, Richard E., what's the outcome?
> 
> Is this all the feedback the "gcc developers" will provide? Bernd, don't
> get me wrong, I also consider it important to watch the coding style in a 
> project, I've seen cases were nobody cared ... not good.
> 
> But OTOH some of the code you rightfully criticised in the previous run
> just went away after some smart feedback from Richard Biener (thanks!);
> I'd rather sort out the design issues first before I polish the code.
> 
> So, can I please have a statement from a responsible maintainer (if such
> a person really exists for this area) about whether this feature would be
> acceptable at all?

First of all, GCC is in stage4 and this isn't a fix for a regression, so it
is not acceptable at this point.  Next stage1 will start in April or so.
Second thing that is questionable is what units are the arguments of the
option or attribute.
+  if (record_p)
   
+fprintf (file, "1:");  
   
+   
   
+  unsigned i;  
   
+  for (i = 0; i < pad_size; ++i)   
   
+fprintf (file, "\tnop\n"); 
   
+   
   
+  if (record_p)
   
+{  
   
+  fprintf (file, "\t.section __prolog_pads_loc, \"a\",@progbits\n");   
   
+  fprintf (file, "\t.quad 1b\n");  
   
+  fprintf (file, "\t.previous\n"); 
   
+}  
   
suggests that it is at least by default the number of nops, whatever that
means.  The length of nop varies greatly across different architectures,
some architectures have different spelling for it (e.g.
ia64, s390{,x} use nop 0 and mmix uses swym 0), some architectures have
tons of different nops with different sizes (see e.g. x86_64/i686), for some
longer sizes it is often beneficial to emit a jump around the rest of nops
instead of just tons of nops.

Even if it is counted always in nops and only nops are emitted (not really
efficient, and I guess kernel cares about efficiency), the above is
definitely not acceptable for a generic hook implementation, it contains too
many ELF specific details as well as 64-bit target specific details etc.
For the label, you should use something like:
  static int ppad_no;
  char tmp_label[...];
  ASM_GENERATE_INTERNAL_LABEL (tmp_label, "LPPAD", ppad_no);
  ppad_no++;
  ASM_OUTPUT_LABEL (file, tmp_label);
the "a",@progbits is not generic enough, you want
  switch_to_section (get_section ("__prolog_pads_loc", 0, NULL));
or so.  .previous doesn't work on many targets, you need to actuall switch
to the previously current section.  .quad is not supported by many
assemblers, you want assemble_integer, with the appropriate size (say
derived from size of pointer), decide whether in that section everything is
aligned or unaligned, emit aligning directive if the former.

> I thought that was obvious, sorry. Instrumentation / profiling will need
> some registers, and live patching (the current use case) may allocate
> different registers for the replacement functions. You will probably want
> to replace the NOPs with a standardised code snippet etc. Conclusion: do not
> make any assumptions about callee's register utilisation and strictly stick
> to 

Re: [PATCH v5] add -fprolog-pad=N,M option

2017-02-08 Thread Torsten Duwe
On Mon, Jan 23, 2017 at 05:25:45PM +0100, Bernd Schmidt wrote:
> There's still a a few details that need addressing, and some questions I
> have. Also Ccing Jakub to have another pair of eyes on the name of the
> section - I don't know if we want some sort of .gnu.something name.

So Jakub, Richard E., what's the outcome?

Is this all the feedback the "gcc developers" will provide? Bernd, don't
get me wrong, I also consider it important to watch the coding style in a 
project, I've seen cases were nobody cared ... not good.

But OTOH some of the code you rightfully criticised in the previous run
just went away after some smart feedback from Richard Biener (thanks!);
I'd rather sort out the design issues first before I polish the code.

So, can I please have a statement from a responsible maintainer (if such
a person really exists for this area) about whether this feature would be
acceptable at all?

Thank you very much in advance.

> >diff --git a/gcc/testsuite/c-c++-common/attribute-prolog_pad-1.c 
> >b/gcc/testsuite/c-c++-common/attribute-prolog_pad-1.c
> >new file mode 100644
> >index 000..2236aa8
> >--- /dev/null
> >+++ b/gcc/testsuite/c-c++-common/attribute-prolog_pad-1.c
> >@@ -0,0 +1,34 @@
> >+/* { dg-do compile } */
> >+/* { dg-options "-fprolog-pad=3,1" } */
> 
> This test does not actually seem to verify that the padding has the expected
> size.

Honestly, I do not know how to complete that test case, this is a mere sketch.
Shame on me I'm really not familiar with that framework; suggestions welcome.

> >  /* Do not use IPA optimizations for register allocation if profiler is 
> > active
> >+or prolog pads are inserted for run-time instrumentation
> > or port does not emit prologue and epilogue as RTL.  */
> >-  if (profile_flag || !targetm.have_prologue () || !targetm.have_epilogue 
> >())
> >+  if (profile_flag || prolog_nop_pad_size
> >+  || !targetm.have_prologue () || !targetm.have_epilogue ())
> > flag_ipa_ra = 0;
> 
> Was this explained? Why would ipa-ra be a problem?

I thought that was obvious, sorry. Instrumentation / profiling will need
some registers, and live patching (the current use case) may allocate
different registers for the replacement functions. You will probably want
to replace the NOPs with a standardised code snippet etc. Conclusion: do not
make any assumptions about callee's register utilisation and strictly stick
to the ABI! I remember to have discussed this, maybe not here.

Torsten



Re: [PATCH v5] add -fprolog-pad=N,M option

2017-01-23 Thread Bernd Schmidt
There's still a a few details that need addressing, and some questions I 
have. Also Ccing Jakub to have another pair of eyes on the name of the 
section - I don't know if we want some sort of .gnu.something name.


On 01/13/2017 01:19 PM, Torsten Duwe wrote:


2017-01-13  Torsten Duwe :


First, some people seem to care, so I'll have to ask to please check the 
correct formatting of this line (spacing and all) by looking at existing 
entries. Also remove some of the blank lines in the ChangeLog, you could 
still group the doc entries separately from the code ones.



 * c-family/c-attribs.c : introduce prolog_pad attribute and create
   a handler for it.

 * lto/lto-lang.c : Likewise.


> * testsuite/c-c++-common/attribute-prolog_pad-1.c : New test.

These three directories have separate ChangeLogs. The top-level 
directory name should be stripped and the entries added to the 
appropriate file.



+  for (it = _ATTRIBUTES (newdecl); *it; it = _CHAIN(*it))
+   {
+ if (IDENTIFIER_LENGTH (get_attribute_name (*it)) !=
+ strlen("prolog_pad"))


Still several instances of bad formatting, in the entire block of code. 
Please refer to my previous email.



+static tree
+handle_prolog_pad_attribute (tree *, tree, tree, int,
+bool *)
+{
+  /* Nothing to be done here.  */
+  return NULL_TREE;
+}


Should still add at least one-liner comments before these empty 
functions to say what interface they're implementing. Also, probably 
don't need to wrap the line containing the arguments.



diff --git a/gcc/testsuite/c-c++-common/attribute-prolog_pad-1.c 
b/gcc/testsuite/c-c++-common/attribute-prolog_pad-1.c
new file mode 100644
index 000..2236aa8
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/attribute-prolog_pad-1.c
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-options "-fprolog-pad=3,1" } */


This test does not actually seem to verify that the padding has the 
expected size.



  /* Do not use IPA optimizations for register allocation if profiler is active
+or prolog pads are inserted for run-time instrumentation
 or port does not emit prologue and epilogue as RTL.  */
-  if (profile_flag || !targetm.have_prologue () || !targetm.have_epilogue ())
+  if (profile_flag || prolog_nop_pad_size
+  || !targetm.have_prologue () || !targetm.have_epilogue ())
 flag_ipa_ra = 0;


Was this explained? Why would ipa-ra be a problem?


+  if (pad_size > pad_entry)
+targetm.asm_out.print_prolog_pad (asm_out_file, pad_size-pad_entry,
+ (pad_entry == 0));


Unnecessary parens around the last argument, and missing spaces around 
operators.



Bernd


Re: [PATCH v5] add -fprolog-pad=N,M option

2017-01-23 Thread Torsten Duwe
And what's next now?

Maxim mentioned in this thread you should sort of formally approve(?)
a global feature, have you had a look at it yet?

I should emphasize that this code can substitute the -fentry for arm64 for
the purpose of kernel live patching that was discussed in the beginning,
as well as for some other architectures, plus the yet-to-be-discovered use
cases as a general instrumentation. In other words, it could save some work
in the future :-)

Torsten



Re: [PATCH v5] add -fprolog-pad=N,M option

2017-01-15 Thread Sandra Loosemore

On 01/13/2017 05:19 AM, Torsten Duwe wrote:

Changes since v4: hopefully addressed all of Sandra's requests
and suggestions concerning the documentation snippets, thanks
for the feedback.  If it still isn't clear, feel free to rephrase
-- I'm a programmer, not a technical writer.


Thanks, this makes more sense to me now.  :-)

-Sandra



[PATCH v5] add -fprolog-pad=N,M option

2017-01-13 Thread Torsten Duwe
Changes since v4: hopefully addressed all of Sandra's requests
and suggestions concerning the documentation snippets, thanks
for the feedback.  If it still isn't clear, feel free to rephrase
-- I'm a programmer, not a technical writer.

2017-01-13  Torsten Duwe : 

 * c-family/c-attribs.c : introduce prolog_pad attribute and create
   a handler for it.

 * lto/lto-lang.c : Likewise.

 * common.opt : introduce -fprolog_pad command line option
   and its variables prolog_nop_pad_size and prolog_nop_pad_entry.

 * doc/extend.texi : document prolog_pad attribute.

 * doc/invoke.texi : document -fprolog_pad command line option.

 * opts.c (OPT_fprolog_pad_): add parser.

 * doc/tm.texi.in (TARGET_ASM_PRINT_PROLOG_PAD): new target hook

 * doc/tm.texi : Likewise.

 * target.def (print_prolog_pad): Likewise.

 * targhooks.h (default_print_prolog_pad): new function.

 * targhooks.c (default_print_prolog_pad): Likewise.

 * testsuite/c-c++-common/attribute-prolog_pad-1.c : New test.

 * toplev.c (process_options): Switch off IPA-RA if
   prolog pads are being generated.

 * varasm.c (assemble_start_function): look at prolog-pad command
   line switch and function attributes and maybe generate NOP
   pads by calling print_prolog_pad.

diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c
index ce7fcaa..5c6cf1c 100644
--- a/gcc/c-family/c-attribs.c
+++ b/gcc/c-family/c-attribs.c
@@ -139,6 +139,7 @@ static tree handle_bnd_variable_size_attribute (tree *, 
tree, tree, int, bool *)
 static tree handle_bnd_legacy (tree *, tree, tree, int, bool *);
 static tree handle_bnd_instrument (tree *, tree, tree, int, bool *);
 static tree handle_fallthrough_attribute (tree *, tree, tree, int, bool *);
+static tree handle_prolog_pad_attribute (tree *, tree, tree, int, bool *);
 
 /* Table of machine-independent attributes common to all C-like languages.
 
@@ -345,6 +346,8 @@ const struct attribute_spec c_common_attribute_table[] =
  handle_bnd_instrument, false },
   { "fallthrough",   0, 0, false, false, false,
  handle_fallthrough_attribute, false },
+  { "prolog_pad",1, 2, true, false, false,
+ handle_prolog_pad_attribute, false },
   { NULL, 0, 0, false, false, false, NULL, false }
 };
 
@@ -3173,3 +3176,10 @@ handle_fallthrough_attribute (tree *, tree name, tree, 
int,
   *no_add_attrs = true;
   return NULL_TREE;
 }
+
+static tree
+handle_prolog_pad_attribute (tree *, tree, tree, int,
+bool *)
+{
+  return NULL_TREE;
+}
diff --git a/gcc/common.opt b/gcc/common.opt
index 8ad5b77..37d4009 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -163,6 +163,13 @@ bool flag_stack_usage_info = false
 Variable
 int flag_debug_asm
 
+; If we should generate NOP pads before each function prologue
+Variable
+HOST_WIDE_INT prolog_nop_pad_size
+
+; And how far the asm entry point is into this pad
+Variable
+HOST_WIDE_INT prolog_nop_pad_entry
 
 ; Balance between GNAT encodings and standard DWARF to emit.
 Variable
@@ -2019,6 +2026,10 @@ fprofile-reorder-functions
 Common Report Var(flag_profile_reorder_functions)
 Enable function reordering that improves code placement.
 
+fprolog-pad=
+Common Joined Optimization
+Pad NOPs before each function prologue.
+
 frandom-seed
 Common Var(common_deferred_options) Defer
 
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 6be113c..fb7d62d 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -3076,6 +3076,23 @@ that affect more than one function.
 This attribute should be used for debugging purposes only.  It is not
 suitable in production code.
 
+@item prolog_pad
+@cindex @code{prolog_pad} function attribute
+@cindex function entry padded with NOPs
+In case the target's text segment can be made writable at run time
+by any means, padding the function entry with a number of NOPs can
+be used to provide a universal tool for instrumentation.  Usually,
+prolog padding is enabled globally using the @option{-fprolog-pad=N,M}
+command-line switch, and disabled with attribute @code{prolog_pad (0)}
+for functions that are part of the actual instrumentation framework.
+This conveniently avoids an endless recursion.
+Of course the @code{prolog_pad} function attribute can be used to
+change the pad size to any desired value.  The two-value syntax is
+the same as for the command-line switch @option{-fprolog-pad=N,M},
+generating a NOP pad of size @var{N}, with the function entry point
+@var{M} NOP instructions into the pad.  @var{M} defaults to 0
+if omitted e.g. function entry point is the beginning of the pad.
+
 @item pure
 @cindex @code{pure} function attribute
 @cindex functions that have no side effects
diff --git a/gcc/doc/invoke.texi