> On Apr 27, 2016, at 6:22 PM, Torsten Duwe <d...@suse.de> wrote: > > Hi Maxim, > > thanks for starting the work on this; I have added the missing > command line option. It builds now and the resulting compiler generates > a linux kernel with the desired properties, so work can continue there.
Thanks for working on this! > > Torsten > > diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c > index 9bc02fc..57265c5 100644 > --- a/gcc/c-family/c-common.c > +++ b/gcc/c-family/c-common.c > @@ -393,6 +393,7 @@ static tree handle_designated_init_attribute (tree *, > tree, tree, int, bool *); > 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_prolog_pad_attribute (tree *, tree, tree, int, bool *); > > static void check_function_nonnull (tree, int, tree *); > static void check_nonnull_arg (void *, tree, unsigned HOST_WIDE_INT); > @@ -833,6 +834,8 @@ const struct attribute_spec c_common_attribute_table[] = > handle_bnd_legacy, false }, > { "bnd_instrument", 0, 0, true, false, false, > handle_bnd_instrument, false }, > + { "prolog_pad", 1, 1, false, true, true, > + handle_prolog_pad_attribute, false }, > { NULL, 0, 0, false, false, false, NULL, false } > }; > > @@ -9663,6 +9666,16 @@ handle_designated_init_attribute (tree *node, tree > name, tree, int, > return NULL_TREE; > } > > +static tree > +handle_prolog_pad_attribute (tree *, tree name, tree, int, > + bool *) > +{ > + warning (OPT_Wattributes, > + "%qE attribute is used", name); > + > + return NULL_TREE; > +} > + > > /* Check for valid arguments being passed to a function with FNTYPE. > There are NARGS arguments in the array ARGARRAY. */ > diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c > index 9ae181f..31a8026 100644 > --- a/gcc/c-family/c-opts.c > +++ b/gcc/c-family/c-opts.c > @@ -532,6 +532,10 @@ c_common_handle_option (size_t scode, const char *arg, > int value, > cpp_opts->ext_numeric_literals = value; > break; > > + case OPT_fprolog_pad_: > + prolog_nop_pad_size = value; > + break; As Szabolcs noted in this thread, we need to consider how -fprolog-pad= will play with IPA and LTO. The decision to use __attribute__ to generate prolog pad for a function is specifically to handle LTO builds. The option -fprolog-pad=N should set __attribute__((prolog_pad(N))) on every function in current translation unit, and the rest should be handled by the attribute logic. This is not trivial to implement, and has been what stopped me from finishing the patch. Your current patch is great for experiments for the kernel engineers to check if suggested approaches to code patching will work. Still, I prefer to implement LTO-friendly way of handling -fprolog-pad=N via function attributes. -- Maxim Kuvyrkov www.linaro.org > + > case OPT_idirafter: > add_path (xstrdup (arg), AFTER, 0, true); > break; > diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt > index aafd802..929ebb6 100644 > --- a/gcc/c-family/c.opt > +++ b/gcc/c-family/c.opt > @@ -1407,6 +1407,10 @@ fpreprocessed > C ObjC C++ ObjC++ > Treat the input file as already preprocessed. > > +fprolog-pad= > +C ObjC C++ ObjC++ RejectNegative Joined UInteger Var(prolog_nop_pad_size) > Init(0) > +Pad NOPs before each function prolog > + > ftrack-macro-expansion > C ObjC C++ ObjC++ JoinedOrMissing RejectNegative UInteger > ; converted into ftrack-macro-expansion= > diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi > index 1ce7181..9d10b10 100644 > --- a/gcc/doc/tm.texi > +++ b/gcc/doc/tm.texi > @@ -4553,6 +4553,10 @@ will select the smallest suitable mode. > This section describes the macros that output function entry > (@dfn{prologue}) and exit (@dfn{epilogue}) code. > > +@deftypefn {Target Hook} void TARGET_ASM_PRINT_PROLOG_PAD (FILE *@var{file}, > unsigned HOST_WIDE_INT @var{pad_size}, bool @var{record_p}) > +Generate prologue pad > +@end deftypefn > + > @deftypefn {Target Hook} void TARGET_ASM_FUNCTION_PROLOGUE (FILE *@var{file}, > HOST_WIDE_INT @var{size}) > If defined, a function that outputs the assembler code for entry to a > function. The prologue is responsible for setting up the stack frame, > diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in > index a0a0a81..bda6d5c 100644 > --- a/gcc/doc/tm.texi.in > +++ b/gcc/doc/tm.texi.in > @@ -3662,6 +3662,8 @@ will select the smallest suitable mode. > This section describes the macros that output function entry > (@dfn{prologue}) and exit (@dfn{epilogue}) code. > > +@hook TARGET_ASM_PRINT_PROLOG_PAD > + > @hook TARGET_ASM_FUNCTION_PROLOGUE > > @hook TARGET_ASM_FUNCTION_END_PROLOGUE > diff --git a/gcc/final.c b/gcc/final.c > index 1edc446..e0cff80 100644 > --- a/gcc/final.c > +++ b/gcc/final.c > @@ -1753,6 +1753,7 @@ void > final_start_function (rtx_insn *first, FILE *file, > int optimize_p ATTRIBUTE_UNUSED) > { > + unsigned HOST_WIDE_INT pad_size = prolog_nop_pad_size; > block_depth = 0; > > this_is_asm_operands = 0; > @@ -1765,6 +1766,21 @@ final_start_function (rtx_insn *first, FILE *file, > > high_block_linenum = high_function_linenum = last_linenum; > > + tree prolog_pad_attr > + = lookup_attribute ("prolog_pad", TYPE_ATTRIBUTES (TREE_TYPE > (current_function_decl))); > + if (prolog_pad_attr) > + { > + tree prolog_pad_value = TREE_VALUE (TREE_VALUE (prolog_pad_attr)); > + > + if (tree_fits_uhwi_p (prolog_pad_value)) > + pad_size = tree_to_uhwi (prolog_pad_value); > + else > + gcc_unreachable (); > + > + } > + if (pad_size > 0) > + targetm.asm_out.print_prolog_pad (file, pad_size, true); > + > if (flag_sanitize & SANITIZE_ADDRESS) > asan_function_start (); > > diff --git a/gcc/target.def b/gcc/target.def > index d754337..63d3285 100644 > --- a/gcc/target.def > +++ b/gcc/target.def > @@ -288,6 +288,12 @@ hidden, protected or internal visibility as specified by > @var{visibility}.", > void, (tree decl, int visibility), > default_assemble_visibility) > > +DEFHOOK > +(print_prolog_pad, > + "Generate prologue pad", > + void, (FILE *file, unsigned HOST_WIDE_INT pad_size, bool record_p), > + default_print_prolog_pad) > + > /* Output the assembler code for entry to a function. */ > DEFHOOK > (function_prologue, > diff --git a/gcc/targhooks.c b/gcc/targhooks.c > index dcf0863..05ab26d 100644 > --- a/gcc/targhooks.c > +++ b/gcc/targhooks.c > @@ -1499,6 +1499,23 @@ default_use_by_pieces_infrastructure_p (unsigned > HOST_WIDE_INT size, > return move_by_pieces_ninsns (size, alignment, max_size + 1) < ratio; > } > > +void > +default_print_prolog_pad (FILE *file, unsigned HOST_WIDE_INT pad_size, > + bool record_p) > +{ > + if (record_p) > + fprintf (file, "1:"); > + for (unsigned 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.long %lu\n", pad_size); > + fprintf (file, "\t.previous\n"); > + } > +} > + > bool > default_profile_before_prologue (void) > { > diff --git a/gcc/targhooks.h b/gcc/targhooks.h > index 47b5cfc..d03f993 100644 > --- a/gcc/targhooks.h > +++ b/gcc/targhooks.h > @@ -199,6 +199,7 @@ extern bool default_use_by_pieces_infrastructure_p > (unsigned HOST_WIDE_INT, > enum by_pieces_operation, > bool); > > +extern void default_print_prolog_pad (FILE *, unsigned HOST_WIDE_INT , bool); > extern bool default_profile_before_prologue (void); > extern reg_class_t default_preferred_reload_class (rtx, reg_class_t); > extern reg_class_t default_preferred_output_reload_class (rtx, reg_class_t); > 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 0000000..7404dc5 > --- /dev/null > +++ b/gcc/testsuite/c-c++-common/attribute-prolog_pad-1.c > @@ -0,0 +1,15 @@ > +/* { dg-do compile } */ > + > +void f1(void) __attribute__((prolog_pad(1))); > +void f2(void) __attribute__((prolog_pad(2))); > + > +void > +f1 (void) > +{ > + f2 (); > +} > + > +void f2 (void) > +{ > + f1 (); > +}