Add patch_area_size and patch_area_entry to crtl
Currently patchable area is at the wrong place. It is placed immediately after function label and before .cfi_startproc. A backend should be able to add a pseudo patchable area instruction durectly into RTL. This patch adds patch_area_size and patch_area_entry to crtl so that the patchable area info is available in RTL passes. It also limits patch_area_size and patch_area_entry to 65535, which is a reasonable maximum size for patchable area. gcc/ PR target/93492 * cfgexpand.c (pass_expand::execute): Set crtl->patch_area_size and crtl->patch_area_entry. * emit-rtl.h (rtl_data): Add patch_area_size and patch_area_entry. * opts.c (common_handle_option): Limit function_entry_patch_area_size and function_entry_patch_area_start to USHRT_MAX. Fix a typo in error message. * varasm.c (assemble_start_function): Use crtl->patch_area_size and crtl->patch_area_entry. * doc/invoke.texi: Document the maximum value for -fpatchable-function-entry. gcc/c-family/ PR target/93492 * c-attribs.c (handle_patchable_function_entry_attribute): Limit value to USHRT_MAX (65535). gcc/testsuite/ PR target/93492 * c-c++-common/patchable_function_entry-error-1.c: New test. * c-c++-common/patchable_function_entry-error-2.c: Likewise. * c-c++-common/patchable_function_entry-error-3.c: Likewise.
This commit is contained in:
parent
23c42a01bc
commit
6607bdd999
@ -1,3 +1,17 @@
|
|||||||
|
2020-05-01 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
|
PR target/93492
|
||||||
|
* cfgexpand.c (pass_expand::execute): Set crtl->patch_area_size
|
||||||
|
and crtl->patch_area_entry.
|
||||||
|
* emit-rtl.h (rtl_data): Add patch_area_size and patch_area_entry.
|
||||||
|
* opts.c (common_handle_option): Limit
|
||||||
|
function_entry_patch_area_size and function_entry_patch_area_start
|
||||||
|
to USHRT_MAX. Fix a typo in error message.
|
||||||
|
* varasm.c (assemble_start_function): Use crtl->patch_area_size
|
||||||
|
and crtl->patch_area_entry.
|
||||||
|
* doc/invoke.texi: Document the maximum value for
|
||||||
|
-fpatchable-function-entry.
|
||||||
|
|
||||||
2020-05-01 Iain Sandoe <iain@sandoe.co.uk>
|
2020-05-01 Iain Sandoe <iain@sandoe.co.uk>
|
||||||
|
|
||||||
* config/i386/darwin.h: Repair SUBTARGET_INIT_BUILTINS.
|
* config/i386/darwin.h: Repair SUBTARGET_INIT_BUILTINS.
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
2020-05-01 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
|
PR target/93492
|
||||||
|
* c-attribs.c (handle_patchable_function_entry_attribute): Limit
|
||||||
|
value to USHRT_MAX (65535).
|
||||||
|
|
||||||
2020-04-29 Jakub Jelinek <jakub@redhat.com>
|
2020-04-29 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
* c-format.c (PP_FORMAT_CHAR_TABLE): Add %{ and %}.
|
* c-format.c (PP_FORMAT_CHAR_TABLE): Add %{ and %}.
|
||||||
|
@ -4553,6 +4553,15 @@ handle_patchable_function_entry_attribute (tree *, tree name, tree args,
|
|||||||
*no_add_attrs = true;
|
*no_add_attrs = true;
|
||||||
return NULL_TREE;
|
return NULL_TREE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tree_to_uhwi (val) > USHRT_MAX)
|
||||||
|
{
|
||||||
|
warning (OPT_Wattributes,
|
||||||
|
"%qE attribute argument %qE is out of range (> 65535)",
|
||||||
|
name, val);
|
||||||
|
*no_add_attrs = true;
|
||||||
|
return NULL_TREE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return NULL_TREE;
|
return NULL_TREE;
|
||||||
}
|
}
|
||||||
|
@ -6656,6 +6656,39 @@ pass_expand::execute (function *fun)
|
|||||||
if (crtl->tail_call_emit)
|
if (crtl->tail_call_emit)
|
||||||
fixup_tail_calls ();
|
fixup_tail_calls ();
|
||||||
|
|
||||||
|
unsigned HOST_WIDE_INT patch_area_size = function_entry_patch_area_size;
|
||||||
|
unsigned HOST_WIDE_INT patch_area_entry = function_entry_patch_area_start;
|
||||||
|
|
||||||
|
tree patchable_function_entry_attr
|
||||||
|
= lookup_attribute ("patchable_function_entry",
|
||||||
|
DECL_ATTRIBUTES (cfun->decl));
|
||||||
|
if (patchable_function_entry_attr)
|
||||||
|
{
|
||||||
|
tree pp_val = TREE_VALUE (patchable_function_entry_attr);
|
||||||
|
tree patchable_function_entry_value1 = TREE_VALUE (pp_val);
|
||||||
|
|
||||||
|
patch_area_size = tree_to_uhwi (patchable_function_entry_value1);
|
||||||
|
patch_area_entry = 0;
|
||||||
|
if (TREE_CHAIN (pp_val) != NULL_TREE)
|
||||||
|
{
|
||||||
|
tree patchable_function_entry_value2
|
||||||
|
= TREE_VALUE (TREE_CHAIN (pp_val));
|
||||||
|
patch_area_entry = tree_to_uhwi (patchable_function_entry_value2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (patch_area_entry > patch_area_size)
|
||||||
|
{
|
||||||
|
if (patch_area_size > 0)
|
||||||
|
warning (OPT_Wattributes,
|
||||||
|
"patchable function entry %wu exceeds size %wu",
|
||||||
|
patch_area_entry, patch_area_size);
|
||||||
|
patch_area_entry = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
crtl->patch_area_size = patch_area_size;
|
||||||
|
crtl->patch_area_entry = patch_area_entry;
|
||||||
|
|
||||||
/* BB subdivision may have created basic blocks that are only reachable
|
/* BB subdivision may have created basic blocks that are only reachable
|
||||||
from unlikely bbs but not marked as such in the profile. */
|
from unlikely bbs but not marked as such in the profile. */
|
||||||
if (optimize)
|
if (optimize)
|
||||||
|
@ -14112,6 +14112,7 @@ If @code{N=0}, no pad location is recorded.
|
|||||||
The NOP instructions are inserted at---and maybe before, depending on
|
The NOP instructions are inserted at---and maybe before, depending on
|
||||||
@var{M}---the function entry address, even before the prologue.
|
@var{M}---the function entry address, even before the prologue.
|
||||||
|
|
||||||
|
The maximum value of @var{N} and @var{M} is 65535.
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
|
|
||||||
|
@ -173,6 +173,12 @@ struct GTY(()) rtl_data {
|
|||||||
local stack. */
|
local stack. */
|
||||||
unsigned int stack_alignment_estimated;
|
unsigned int stack_alignment_estimated;
|
||||||
|
|
||||||
|
/* How many NOP insns to place at each function entry by default. */
|
||||||
|
unsigned short patch_area_size;
|
||||||
|
|
||||||
|
/* How far the real asm entry point is into this area. */
|
||||||
|
unsigned short patch_area_entry;
|
||||||
|
|
||||||
/* For reorg. */
|
/* For reorg. */
|
||||||
|
|
||||||
/* Nonzero if function being compiled called builtin_return_addr or
|
/* Nonzero if function being compiled called builtin_return_addr or
|
||||||
|
@ -2615,10 +2615,12 @@ common_handle_option (struct gcc_options *opts,
|
|||||||
function_entry_patch_area_start = 0;
|
function_entry_patch_area_start = 0;
|
||||||
}
|
}
|
||||||
if (function_entry_patch_area_size < 0
|
if (function_entry_patch_area_size < 0
|
||||||
|
|| function_entry_patch_area_size > USHRT_MAX
|
||||||
|| function_entry_patch_area_start < 0
|
|| function_entry_patch_area_start < 0
|
||||||
|
|| function_entry_patch_area_start > USHRT_MAX
|
||||||
|| function_entry_patch_area_size
|
|| function_entry_patch_area_size
|
||||||
< function_entry_patch_area_start)
|
< function_entry_patch_area_start)
|
||||||
error ("invalid arguments for %<-fpatchable_function_entry%>");
|
error ("invalid arguments for %<-fpatchable-function-entry%>");
|
||||||
free (patch_area_arg);
|
free (patch_area_arg);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1,3 +1,10 @@
|
|||||||
|
2020-05-01 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
|
PR target/93492
|
||||||
|
* c-c++-common/patchable_function_entry-error-1.c: New test.
|
||||||
|
* c-c++-common/patchable_function_entry-error-2.c: Likewise.
|
||||||
|
* c-c++-common/patchable_function_entry-error-3.c: Likewise.
|
||||||
|
|
||||||
2020-05-01 Patrick Palka <ppalka@redhat.com>
|
2020-05-01 Patrick Palka <ppalka@redhat.com>
|
||||||
|
|
||||||
PR c++/90880
|
PR c++/90880
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
/* { dg-do compile { target { ! { nvptx*-*-* visium-*-* } } } } */
|
||||||
|
/* { dg-options "-O2 -fpatchable-function-entry=65536,1" } */
|
||||||
|
/* { dg-additional-options "-fno-pie" { target sparc*-*-* } } */
|
||||||
|
/* { dg-error "invalid arguments for '-fpatchable-function-entry'" "" { target *-*-* } 0 } */
|
||||||
|
|
||||||
|
void
|
||||||
|
foo (void)
|
||||||
|
{
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
/* { dg-do compile { target { ! { nvptx*-*-* visium-*-* } } } } */
|
||||||
|
/* { dg-options "-O2 -fpatchable-function-entry=1,65536" } */
|
||||||
|
/* { dg-additional-options "-fno-pie" { target sparc*-*-* } } */
|
||||||
|
/* { dg-error "invalid arguments for '-fpatchable-function-entry'" "" { target *-*-* } 0 } */
|
||||||
|
|
||||||
|
void
|
||||||
|
foo (void)
|
||||||
|
{
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
/* { dg-do compile { target { ! { nvptx*-*-* visium-*-* } } } } */
|
||||||
|
/* { dg-additional-options "-fno-pie" { target sparc*-*-* } } */
|
||||||
|
|
||||||
|
void
|
||||||
|
__attribute__((patchable_function_entry(65536)))
|
||||||
|
foo1 (void) { /* { dg-warning "'patchable_function_entry' attribute argument '65536' is out of range" } */
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
__attribute__((patchable_function_entry(65536,1)))
|
||||||
|
foo2 (void) { /* { dg-warning "'patchable_function_entry' attribute argument '65536' is out of range" } */
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
__attribute__((patchable_function_entry(65536,65536)))
|
||||||
|
foo3 (void) { /* { dg-warning "'patchable_function_entry' attribute argument '65536' is out of range" } */
|
||||||
|
}
|
30
gcc/varasm.c
30
gcc/varasm.c
@ -1857,34 +1857,8 @@ assemble_start_function (tree decl, const char *fnname)
|
|||||||
if (DECL_PRESERVE_P (decl))
|
if (DECL_PRESERVE_P (decl))
|
||||||
targetm.asm_out.mark_decl_preserved (fnname);
|
targetm.asm_out.mark_decl_preserved (fnname);
|
||||||
|
|
||||||
unsigned HOST_WIDE_INT patch_area_size = function_entry_patch_area_size;
|
unsigned short patch_area_size = crtl->patch_area_size;
|
||||||
unsigned HOST_WIDE_INT patch_area_entry = function_entry_patch_area_start;
|
unsigned short patch_area_entry = crtl->patch_area_entry;
|
||||||
|
|
||||||
tree patchable_function_entry_attr
|
|
||||||
= lookup_attribute ("patchable_function_entry", DECL_ATTRIBUTES (decl));
|
|
||||||
if (patchable_function_entry_attr)
|
|
||||||
{
|
|
||||||
tree pp_val = TREE_VALUE (patchable_function_entry_attr);
|
|
||||||
tree patchable_function_entry_value1 = TREE_VALUE (pp_val);
|
|
||||||
|
|
||||||
patch_area_size = tree_to_uhwi (patchable_function_entry_value1);
|
|
||||||
patch_area_entry = 0;
|
|
||||||
if (TREE_CHAIN (pp_val) != NULL_TREE)
|
|
||||||
{
|
|
||||||
tree patchable_function_entry_value2
|
|
||||||
= TREE_VALUE (TREE_CHAIN (pp_val));
|
|
||||||
patch_area_entry = tree_to_uhwi (patchable_function_entry_value2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (patch_area_entry > patch_area_size)
|
|
||||||
{
|
|
||||||
if (patch_area_size > 0)
|
|
||||||
warning (OPT_Wattributes,
|
|
||||||
"patchable function entry %wu exceeds size %wu",
|
|
||||||
patch_area_entry, patch_area_size);
|
|
||||||
patch_area_entry = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Emit the patching area before the entry label, if any. */
|
/* Emit the patching area before the entry label, if any. */
|
||||||
if (patch_area_entry > 0)
|
if (patch_area_entry > 0)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user