From: Maxim Kuvyrkov <maxim.kuvyrkov@linaro.org>
To: Maxim Kuvyrkov <maxim.kuvyrkov@linaro.org>
Cc: Torsten Duwe <duwe@suse.de>,
GCC Patches <gcc-patches@gcc.gnu.org>,
Szabolcs Nagy <szabolcs.nagy@arm.com>,
nd@arm.com, Li Bin <huawei.libin@huawei.com>,
Jiri Kosina <jkosina@suse.cz>,
Marcus Shawcroft <Marcus.Shawcroft@arm.com>,
Takahiro Akashi <takahiro.akashi@linaro.org>,
Andrew Wafaa <Andrew.Wafaa@arm.com>,
Richard Earnshaw <Richard.Earnshaw@arm.com>
Subject: Re: [PATCH v2] add -fprolog-pad=N option to c-family
Date: Tue, 06 Dec 2016 14:02:00 -0000 [thread overview]
Message-ID: <75C7C04D-B9A8-4553-9126-7BA5EF1C67AA@linaro.org> (raw)
In-Reply-To: <31609F79-39D1-411D-81C4-4CA16C721F32@linaro.org>
> On Oct 5, 2016, at 12:45 AM, Maxim Kuvyrkov <maxim.kuvyrkov@linaro.org> wrote:
>
>> On Sep 29, 2016, at 11:14 AM, Torsten Duwe <duwe@suse.de> wrote:
>>
>> In case anybody missed it, the Linux kernel side to make use
>> of this has also been finished meanwhile. Of course it can not
>> be accepted without compiler support; and this feature patch
>> is much more versatile than just Linux kernel live patching
>> on a single architecture.
>
> Hi Torsten,
>
> Good job moving -fprolog-pad= forward! I've reviewed your patch, and it looks OK with the minor comments inline. I've CC'ed Richard E. since you will need a global maintainer approval for this change.
Ping?
--
Maxim Kuvyrkov
www.linaro.org
>
> Ideally, I want to improve support for -fprolog-pad=N and __attribute__((prolog_pad(N))) to provide functionality to also output pad before the function label to address use-cases for s390, sparc, etc (what Jose E. Marchesi was referring to). I.e., -fprolog-pad= option would accept both -fprolog-pad=N and -fprolog-pad=M,N forms -- issue M nops before function label and N nops after function label. Similarly for __attribute__((prolog_pad(N,M))). I (or you :-) ) can attempt to implement this functionality before stage1 closes, but it should not block this initial patch.
>
> Comments on the patch below.
>
>>
>> Changes since the previous version
>> (which in turn was based on Maxim's suggestion):
>>
>> * Document the feature in *.texi
>>
>> * Automatically disable IPA-RA, like normal profiling does.
>> You never know in advance what the code patched in at run time will do.
>> Any optimisation here is potentially wrong.
>>
>> * record a prolog_nop_pad_size value specified on the command line
>> in each function's attributes, so that it survives an LTO pipe.
>>
>> Signed-off-by: Torsten Duwe <duwe@suse.de>
>>
>> diff --git a/gcc/attribs.c b/gcc/attribs.c
>> index 16996e9..a5cf2aa 100644
>> --- a/gcc/attribs.c
>> +++ b/gcc/attribs.c
>> @@ -365,6 +365,21 @@ decl_attributes (tree *node, tree attributes, int flags)
>> if (!attributes_initialized)
>> init_attributes ();
>>
>> + /* If we're building NOP pads because of a command line arg, note the size
>> + for LTO builds, unless the attribute has already been overridden. */
>> + if (TREE_CODE (*node) == FUNCTION_DECL && prolog_nop_pad_size > 0)
>> + {
>> + tree pp_attr = lookup_attribute ("prolog_pad", attributes);
>> + if (! pp_attr )
>
> Coding style: should be "if (!pp_attr)"
>
> Also, this clause implies that attribute takes precedence over command-line option, and the two are not attempted to be merged. I agree that this is a reasonable approach, but consider adding a warning if prolog_nop_pad_size is bigger than the value of the existing attribute. Something like ...
>
>> + {
>> + tree pp_size = build_int_cstu (integer_type_node, prolog_nop_pad_size);
>> +
>> + attributes = tree_cons (get_identifier ("prolog_pad"),
>> + tree_cons ( NULL_TREE, pp_size, NULL_TREE),
>> + attributes);
>> + }
>
> ... here:
>
> else if (ATTRIBUTE_VALUE (pp_attr) > prolog_nop_pad_size)
> warning (OPT_Wattributes, "Prologue pad might be truncated: <FUNCTION_NAME>", node);
>
> Also, I suggest to issue a warning here if ipa-ra is not disabled, and adding a comment to the documentation about issues with interoperability of -fprolog-pad/__attribute__((prolog_pad)) and IPA RA..
>
>> + }
>> +
>> /* If this is a function and the user used #pragma GCC optimize, add the
>> options to the attribute((optimize(...))) list. */
>> if (TREE_CODE (*node) == FUNCTION_DECL && current_optimize_pragma)
>> diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
>> index f2846bb..278a99e 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_nonnull_arg (void *, tree, unsigned HOST_WIDE_INT);
>> static bool nonnull_check_p (tree, unsigned HOST_WIDE_INT);
>> @@ -834,6 +835,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 },
>
> The patch also needs to document new attribute in doc/extend.texi
>
>> { NULL, 0, 0, false, false, false, NULL, false }
>> };
>>
>> @@ -9687,6 +9690,14 @@ handle_designated_init_attribute (tree *node, tree name, tree, int,
>> return NULL_TREE;
>> }
>>
>> +static tree
>> +handle_prolog_pad_attribute (tree *, tree, tree, int,
>> + bool *)
>> +{
>> + /* Nothing to be done here. */
>> + return NULL_TREE;
>> +}
>> +
>>
>> /* Check for valid arguments being passed to a function with FNTYPE.
>> There are NARGS arguments in the array ARGARRAY. LOC should be used for
>> diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c
>> index fec58bc..0220faa 100644
>> --- a/gcc/c-family/c-opts.c
>> +++ b/gcc/c-family/c-opts.c
>> @@ -536,6 +536,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;
>> +
>> 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 88038a0..804c654 100644
>> --- a/gcc/c-family/c.opt
>> +++ b/gcc/c-family/c.opt
>> @@ -1427,6 +1427,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/invoke.texi b/gcc/doc/invoke.texi
>> index 2ed9285..463a5a5 100644
>> --- a/gcc/doc/invoke.texi
>> +++ b/gcc/doc/invoke.texi
>> @@ -10387,6 +10387,16 @@ 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=N
>> +@opindex fprolog-pad
>> +Generate a pad of N nops right at the beginning
>> +of each function, which can be used to patch in any desired
>> +instrumentation at run time, provided that the code segment
>> +is writeable. For run time identification, the starting addresses
>> +of these pads, which correspond to their respective functions,
>> +are additionally collected in the @code{__prolog_pads_loc} section
>> +of the resulting binary.
>
> ... Note that value of @code{__attribute__((prolog_pad(N)))} takes precedence over command-line option -fprolog_pad=N.
>
>> +
>> @end table
>>
>>
>> diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
>> index 745910f..f6f9d59 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 f31c763..b9585da 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 55cf509..94bbf8f 100644
>> --- a/gcc/final.c
>> +++ b/gcc/final.c
>> @@ -1754,6 +1754,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;
>
> Declaration of pad_size can be moved under "if (prolog_pad_attr)" clause, since we don't need value of prolog_nop_pad_size here anymore (it's already encoded in the __attribute__).
>
>> block_depth = 0;
>>
>> this_is_asm_operands = 0;
>> @@ -1766,6 +1767,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);
>
> Similarly, this clause can be moved inside "if (prolog_pad_attr)" clause.
>
>> +
>> if (flag_sanitize & SANITIZE_ADDRESS)
>> asan_function_start ();
>>
>> diff --git a/gcc/target.def b/gcc/target.def
>> index 20f2b32..e0a4cc4 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 a342277..41e9850 100644
>> --- a/gcc/targhooks.c
>> +++ b/gcc/targhooks.c
>> @@ -1503,6 +1503,22 @@ 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.previous\n");
>> + }
>> +}
>> +
>> bool
>> default_profile_before_prologue (void)
>> {
>> diff --git a/gcc/targhooks.h b/gcc/targhooks.h
>> index 7687c39..6bb41c4 100644
>> --- a/gcc/targhooks.h
>> +++ b/gcc/targhooks.h
>> @@ -200,6 +200,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 ();
>> +}
>> diff --git a/gcc/toplev.c b/gcc/toplev.c
>> index 8979d26..2339ce8 100644
>> --- a/gcc/toplev.c
>> +++ b/gcc/toplev.c
>> @@ -1580,8 +1580,10 @@ process_options (void)
>> }
>>
>> /* 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;
>>
>> /* Enable -Werror=coverage-mismatch when -Werror and -Wno-error
>
> Thanks!
>
> --
> Maxim Kuvyrkov
> www.linaro.org
next prev parent reply other threads:[~2016-12-06 14:02 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-04-27 15:22 [PATCH] " Torsten Duwe
2016-04-27 16:26 ` Szabolcs Nagy
2016-04-28 8:48 ` Maxim Kuvyrkov
2016-04-28 10:58 ` Szabolcs Nagy
2016-04-28 11:32 ` Torsten Duwe
2016-05-09 5:53 ` AKASHI Takahiro
2016-09-29 15:18 ` [PATCH v2] " Torsten Duwe
2016-09-30 9:59 ` Jose E. Marchesi
2016-09-30 10:22 ` Torsten Duwe
2016-10-03 9:45 ` AKASHI Takahiro
2016-10-04 21:46 ` Maxim Kuvyrkov
2016-12-06 14:02 ` Maxim Kuvyrkov [this message]
2016-04-28 8:40 ` [PATCH] " Maxim Kuvyrkov
2016-04-28 11:18 ` Torsten Duwe
2016-04-28 15:07 ` Jeff Law
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=75C7C04D-B9A8-4553-9126-7BA5EF1C67AA@linaro.org \
--to=maxim.kuvyrkov@linaro.org \
--cc=Andrew.Wafaa@arm.com \
--cc=Marcus.Shawcroft@arm.com \
--cc=Richard.Earnshaw@arm.com \
--cc=duwe@suse.de \
--cc=gcc-patches@gcc.gnu.org \
--cc=huawei.libin@huawei.com \
--cc=jkosina@suse.cz \
--cc=nd@arm.com \
--cc=szabolcs.nagy@arm.com \
--cc=takahiro.akashi@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).