Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP1:GA
cross-ppc-gcc48-icecream-backend.12815
gcc48-flive-patching.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File gcc48-flive-patching.patch of Package cross-ppc-gcc48-icecream-backend.12815
diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 8ab7ae18102..6cede317c17 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -724,7 +724,7 @@ void varpool_node_set_remove (varpool_node_set, struct varpool_node *); void dump_varpool_node_set (FILE *, varpool_node_set); void debug_varpool_node_set (varpool_node_set); void free_varpool_node_set (varpool_node_set); -void ipa_discover_readonly_nonaddressable_vars (void); +void ipa_discover_variable_flags (void); bool cgraph_comdat_can_be_unshared_p (struct cgraph_node *); bool varpool_externally_visible_p (struct varpool_node *, bool); diff --git a/gcc/cif-code.def b/gcc/cif-code.def index 55e0ef45b3b..75e5b4d8bbe 100644 --- a/gcc/cif-code.def +++ b/gcc/cif-code.def @@ -106,3 +106,9 @@ /* We know that the call will be optimized out. */ DEFCIFCODE(NEVER_EXECUTED, N_("never executed")) + +/* We can't inline because the user requests only static functions + but the function has external linkage for live patching purpose. */ +DEFCIFCODE(EXTERN_LIVE_ONLY_STATIC, + N_("function has external linkage when the user requests only" + " inlining static for live patching")) diff --git a/gcc/common.opt b/gcc/common.opt index ec4cafc448b..816e10e7a9d 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -1206,6 +1206,24 @@ Common Report Var(flag_hoist_adjacent_loads) Optimization Enable hoisting adjacent loads to encourage generating conditional move instructions +flive-patching +Common RejectNegative Alias(flive-patching=,inline-clone) Optimization + +flive-patching= +Common Report Joined RejectNegative Enum(live_patching_level) Var(flag_live_patching) Init(LIVE_PATCHING_NONE) Optimization +-flive-patching=[inline-only-static|inline-clone] Control IPA +optimizations to provide a safe compilation for live-patching. At the same +time, provides multiple-level control on the enabled IPA optimizations. + +Enum +Name(live_patching_level) Type(enum live_patching_level) UnknownError(unknown Live-Patching Level %qs) + +EnumValue +Enum(live_patching_level) String(inline-only-static) Value(LIVE_PATCHING_INLINE_ONLY_STATIC) + +EnumValue +Enum(live_patching_level) String(inline-clone) Value(LIVE_PATCHING_INLINE_CLONE) + floop-parallelize-all Common Report Var(flag_loop_parallelize_all) Optimization Mark all loops as parallel @@ -1361,7 +1379,15 @@ Discover pure and const functions fipa-reference Common Report Var(flag_ipa_reference) Init(0) Optimization -Discover readonly and non addressable static variables +Discover read-only and non addressable static variables. + +fipa-reference-addressable +Common Report Var(flag_ipa_reference_addressable) Init(0) Optimization +Discover read-only, write-only and non-addressable static variables. + +fipa-stack-alignment +Common Report Var(flag_ipa_stack_alignment) Init(1) Optimization +Reduce stack alignment on call sites if possible. fipa-matrix-reorg Common Ignore diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index caf06c82d1d..4e8867ebf30 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -370,8 +370,9 @@ Objective-C and Objective-C++ Dialects}. -fif-conversion2 -findirect-inlining @gol -finline-functions -finline-functions-called-once -finline-limit=@var{n} @gol -finline-small-functions -fipa-cp -fipa-cp-clone @gol --fipa-pta -fipa-profile -fipa-pure-const -fipa-reference @gol --fira-algorithm=@var{algorithm} @gol +-fipa-pta -fipa-profile -fipa-pure-const -fipa-reference -fipa-reference-addressable @gol +-fipa-stack-alignment -fira-algorithm=@var{algorithm} @gol +-flive-patching=@var{level} @gol -fira-region=@var{region} -fira-hoist-pressure @gol -fira-loop-pressure -fno-ira-share-save-slots @gol -fno-ira-share-spill-slots -fira-verbose=@var{n} @gol @@ -6522,6 +6523,7 @@ compilation time. -fipa-pure-const @gol -fipa-profile @gol -fipa-reference @gol +-fipa-reference-addressable @gol -fmerge-constants -fsplit-wide-types @gol -ftree-bit-ccp @gol @@ -7111,6 +7113,65 @@ Perform a number of minor optimizations that are relatively expensive. Enabled at levels @option{-O2}, @option{-O3}, @option{-Os}. +@item -flive-patching=@var{level} +@opindex flive-patching +Control GCC's optimizations to provide a safe compilation for live-patching. + +If the compiler's optimization uses a function's body or information extracted +from its body to optimize/change another function, the latter is called an +impacted function of the former. If a function is patched, its impacted +functions should be patched too. + +The impacted functions are decided by the compiler's interprocedural +optimizations. For example, inlining a function into its caller, cloning +a function and changing its caller to call this new clone, or extracting +a function's pureness/constness information to optimize its direct or +indirect callers, etc. + +Usually, the more IPA optimizations enabled, the larger the number of +impacted functions for each function. In order to control the number of +impacted functions and computed the list of impacted function easily, +we provide control to partially enable IPA optimizations on two different +levels. + +The @var{level} argument should be one of the following: + +@table @samp + +@item inline-clone + +Only enable inlining and cloning optimizations, which includes inlining, +cloning, interprocedural scalar replacement of aggregates and partial inlining. +As a result, when patching a function, all its callers and its clones' +callers need to be patched as well. + +@option{-flive-patching=inline-clone} disables the following optimization flags: +@gccoptlist{-fwhole-program -fipa-pta -fipa-reference -fipa-ra @gol +-fipa-icf -fipa-icf-functions -fipa-icf-variables @gol +-fipa-bit-cp -fipa-vrp -fipa-pure-const -fipa-reference-addressable @gol +-fipa-stack-alignment} + +@item inline-only-static + +Only enable inlining of static functions. +As a result, when patching a static function, all its callers need to be +patches as well. + +In addition to all the flags that -flive-patching=inline-clone disables, +@option{-flive-patching=inline-only-static} disables the following additional +optimization flags: +@gccoptlist{-fipa-cp-clone -fipa-sra -fpartial-inlining -fipa-cp} + +@end table + +When -flive-patching specified without any value, the default value +is "inline-clone". + +This flag is disabled by default. + +Note that -flive-patching is not supported with link-time optimizer. +(@option{-flto}). + @item -free @opindex free Attempt to remove redundant extension instructions. This is especially @@ -7459,6 +7520,16 @@ Discover which static variables do not escape the compilation unit. Enabled by default at @option{-O} and higher. +@item -fipa-reference-addressable +@opindex fipa-reference-addressable +Discover read-only, write-only and non-addressable static variables. +Enabled by default at @option{-O} and higher. + +@item -fipa-stack-alignment +@opindex fipa-stack-alignment +Reduce stack alignment on call sites if possible. +Enabled by default. + @item -fipa-pta @opindex fipa-pta Perform interprocedural pointer analysis and interprocedural modification diff --git a/gcc/final.c b/gcc/final.c index d25b8e0b7e4..cf22d390945 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -4540,7 +4540,8 @@ rest_of_clean_state (void) /* We can reduce stack alignment on call site only when we are sure that the function body just produced will be actually used in the final executable. */ - if (decl_binds_to_current_def_p (current_function_decl)) + if (flag_ipa_stack_alignment + && decl_binds_to_current_def_p (current_function_decl)) { unsigned int pref = crtl->preferred_stack_boundary; if (crtl->stack_alignment_needed > crtl->preferred_stack_boundary) diff --git a/gcc/flag-types.h b/gcc/flag-types.h index 4fc5d33348e..590071f99ba 100644 --- a/gcc/flag-types.h +++ b/gcc/flag-types.h @@ -112,6 +112,14 @@ enum stack_reuse_level SR_ALL }; +/* The live patching level. */ +enum live_patching_level +{ + LIVE_PATCHING_NONE = 0, + LIVE_PATCHING_INLINE_ONLY_STATIC, + LIVE_PATCHING_INLINE_CLONE +}; + /* The algorithm used for the integrated register allocator (IRA). */ enum ira_algorithm { diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 90b2a13fce9..33589cfab16 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -316,6 +316,13 @@ can_inline_edge_p (struct cgraph_edge *e, bool report) : e->caller->symbol.decl)) && !caller_growth_limits (e)) inlinable = false; + else if (callee->symbol.externally_visible + && !DECL_DISREGARD_INLINE_LIMITS (callee->symbol.decl) + && flag_live_patching == LIVE_PATCHING_INLINE_ONLY_STATIC) + { + e->inline_failed = CIF_EXTERN_LIVE_ONLY_STATIC; + inlinable = false; + } /* Don't inline a function with a higher optimization level than the caller. FIXME: this is really just tip of iceberg of handling optimization attribute. */ diff --git a/gcc/ipa-reference.c b/gcc/ipa-reference.c index f3c483f67f9..3463b7655e9 100644 --- a/gcc/ipa-reference.c +++ b/gcc/ipa-reference.c @@ -675,7 +675,7 @@ propagate (void) if (dump_file) dump_cgraph (dump_file); - ipa_discover_readonly_nonaddressable_vars (); + ipa_discover_variable_flags (); generate_summary (); /* Now we know what vars are really statics; prune out those that aren't. */ diff --git a/gcc/ipa.c b/gcc/ipa.c index be377a70e1d..6bd215f35e6 100644 --- a/gcc/ipa.c +++ b/gcc/ipa.c @@ -474,7 +474,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file) make sense to do it before early optimizations. */ void -ipa_discover_readonly_nonaddressable_vars (void) +ipa_discover_variable_flags (void) { struct varpool_node *vnode; if (dump_file) @@ -1018,7 +1018,7 @@ whole_program_function_and_variable_visibility (void) { function_and_variable_visibility (flag_whole_program); if (optimize) - ipa_discover_readonly_nonaddressable_vars (); + ipa_discover_variable_flags (); return 0; } diff --git a/gcc/opts.c b/gcc/opts.c index 55cd965282d..78a79daa6dc 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -429,6 +429,7 @@ static const struct default_options default_options_table[] = { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fif_conversion2, NULL, 1 }, { OPT_LEVELS_1_PLUS, OPT_fipa_pure_const, NULL, 1 }, { OPT_LEVELS_1_PLUS, OPT_fipa_reference, NULL, 1 }, + { OPT_LEVELS_1_PLUS, OPT_fipa_reference_addressable, NULL, 1 }, { OPT_LEVELS_1_PLUS, OPT_fipa_profile, NULL, 1 }, { OPT_LEVELS_1_PLUS, OPT_fmerge_constants, NULL, 1 }, { OPT_LEVELS_1_PLUS, OPT_fshrink_wrap, NULL, 1 }, @@ -623,6 +624,106 @@ default_options_optimization (struct gcc_options *opts, lang_mask, handlers, loc, dc); } +/* Control IPA optimizations based on different live patching LEVEL. */ +static void +control_options_for_live_patching (struct gcc_options *opts, + struct gcc_options *opts_set, + enum live_patching_level level, + location_t loc) +{ + gcc_assert (level > LIVE_PATCHING_NONE); + + switch (level) + { + case LIVE_PATCHING_INLINE_ONLY_STATIC: + if (opts_set->x_flag_ipa_cp_clone && opts->x_flag_ipa_cp_clone) + error_at (loc, + "%<-fipa-cp-clone%> is incompatible with " + "%<-flive-patching=inline-only-static%>"); + else + opts->x_flag_ipa_cp_clone = 0; + + if (opts_set->x_flag_ipa_sra && opts->x_flag_ipa_sra) + error_at (loc, + "%<-fipa-sra%> is incompatible with " + "%<-flive-patching=inline-only-static%>"); + else + opts->x_flag_ipa_sra = 0; + + if (opts_set->x_flag_partial_inlining && opts->x_flag_partial_inlining) + error_at (loc, + "%<-fpartial-inlining%> is incompatible with " + "%<-flive-patching=inline-only-static%>"); + else + opts->x_flag_partial_inlining = 0; + + if (opts_set->x_flag_ipa_cp && opts->x_flag_ipa_cp) + error_at (loc, + "%<-fipa-cp%> is incompatible with " + "%<-flive-patching=inline-only-static%>"); + else + opts->x_flag_ipa_cp = 0; + + /* FALLTHROUGH. */ + case LIVE_PATCHING_INLINE_CLONE: + /* live patching should disable whole-program optimization. */ + if (opts_set->x_flag_whole_program && opts->x_flag_whole_program) + error_at (loc, + "%<-fwhole-program%> is incompatible with " + "%<-flive-patching=inline-only-static|inline-clone%>"); + else + opts->x_flag_whole_program = 0; + + /* visibility change should be excluded by !flag_whole_program + && !in_lto_p && !flag_ipa_cp_clone && !flag_ipa_sra + && !flag_partial_inlining. */ + + if (opts_set->x_flag_ipa_pta && opts->x_flag_ipa_pta) + error_at (loc, + "%<-fipa-pta%> is incompatible with " + "%<-flive-patching=inline-only-static|inline-clone%>"); + else + opts->x_flag_ipa_pta = 0; + + if (opts_set->x_flag_ipa_reference && opts->x_flag_ipa_reference) + error_at (loc, + "%<-fipa-reference%> is incompatible with " + "%<-flive-patching=inline-only-static|inline-clone%>"); + else + opts->x_flag_ipa_reference = 0; + + if (opts_set->x_flag_ipa_pure_const && opts->x_flag_ipa_pure_const) + error_at (loc, + "%<-fipa-pure-const%> is incompatible with " + "%<-flive-patching=inline-only-static|inline-clone%>"); + else + opts->x_flag_ipa_pure_const = 0; + + /* FIXME: disable unreachable code removal. */ + + /* discovery of functions/variables with no address taken. */ + if (opts_set->x_flag_ipa_reference_addressable + && opts->x_flag_ipa_reference_addressable) + error_at (loc, + "%<-fipa-reference-addressable%> is incompatible with " + "%<-flive-patching=inline-only-static|inline-clone%>"); + else + opts->x_flag_ipa_reference_addressable = 0; + + /* ipa stack alignment propagation. */ + if (opts_set->x_flag_ipa_stack_alignment + && opts->x_flag_ipa_stack_alignment) + error_at (loc, + "%<-fipa-stack-alignment%> is incompatible with " + "%<-flive-patching=inline-only-static|inline-clone%>"); + else + opts->x_flag_ipa_stack_alignment = 0; + break; + default: + gcc_unreachable (); + } +} + /* After all options at LOC have been read into OPTS and OPTS_SET, finalize settings of those options and diagnose incompatible combinations. */ @@ -831,6 +932,18 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set, /* The -gsplit-dwarf option requires -gpubnames. */ if (opts->x_dwarf_split_debug_info) opts->x_debug_generate_pub_sections = 1; + + /* Currently live patching is not support for LTO. */ + if (opts->x_flag_live_patching && opts->x_flag_lto) + sorry ("live patching is not supported with LTO"); + + /* Control IPA optimizations based on different -flive-patching level. */ + if (opts->x_flag_live_patching) + { + control_options_for_live_patching (opts, opts_set, + opts->x_flag_live_patching, + loc); + } } #define LEFT_COLUMN 27 diff --git a/gcc/testsuite/gcc.dg/live-patching-1.c b/gcc/testsuite/gcc.dg/live-patching-1.c new file mode 100644 index 00000000000..ab4738119b8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/live-patching-1.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -flive-patching=inline-only-static -fdump-ipa-inline" } */ + +extern int sum, n, m; + +int foo (int a) +{ + return a + n; +} + +static int bar (int b) +{ + return b * m; +} + +int main() +{ + sum = foo (m) + bar (n); + return 0; +} + +/* { dg-final { scan-ipa-dump "foo/0 function has external linkage when the user requests only inlining static for live patching" "inline" } } */ diff --git a/gcc/testsuite/gcc.dg/live-patching-2.c b/gcc/testsuite/gcc.dg/live-patching-2.c new file mode 100644 index 00000000000..0dde4e9e0c0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/live-patching-2.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target lto } */ +/* { dg-options "-O2 -flive-patching -flto" } */ + +int main() +{ + return 0; +} + +/* { dg-message "sorry, unimplemented: live patching is not supported with LTO" "-flive-patching and -flto together" { target *-*-* } 0 } */ diff --git a/gcc/testsuite/gcc.dg/live-patching-3.c b/gcc/testsuite/gcc.dg/live-patching-3.c new file mode 100644 index 00000000000..b86f3c6e08a --- /dev/null +++ b/gcc/testsuite/gcc.dg/live-patching-3.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -flive-patching -fwhole-program" } */ + +int main() +{ + return 0; +} + +/* { dg-message "'-fwhole-program' is incompatible with '-flive-patching=inline-only-static|inline-clone’" "" {target "*-*-*"} 0 } */ diff --git a/gcc/testsuite/gcc.dg/live-patching-4.c b/gcc/testsuite/gcc.dg/live-patching-4.c new file mode 100644 index 00000000000..c3862a5bd7e --- /dev/null +++ b/gcc/testsuite/gcc.dg/live-patching-4.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -flive-patching=inline-only-static -fdump-tree-einline" } */ + +extern int sum, n, m; + +extern inline __attribute__((always_inline)) int foo (int a); +inline __attribute__((always_inline)) int foo (int a) +{ + return a + n; +} + +static int bar (int b) +{ + return b * m; +} + +int main() +{ + sum = foo (m) + bar (n); + return 0; +} + +/* { dg-final { scan-tree-dump "Inlining foo into main" "einline" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/writeonly-2.c b/gcc/testsuite/gcc.dg/tree-ssa/writeonly-2.c new file mode 100644 index 00000000000..78893bd7fb8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/writeonly-2.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-optimized -fno-ipa-reference-addressable" } */ +static struct a {int magic1,b;} a; +volatile int magic2; +static struct b {int a,b,c,d,e,f;} magic3; + +struct b foo(); + +void +t() +{ + a.magic1 = 1; + magic2 = 1; + magic3 = foo(); +} +/* { dg-final { scan-tree-dump "magic1" "optimized"} } */ +/* { dg-final { scan-tree-dump "magic3" "optimized"} } */ +/* { dg-final { scan-tree-dump "magic2" "optimized"} } */ +/* { dg-final { scan-tree-dump "foo" "optimized"} } */ + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/writeonly-3.c b/gcc/testsuite/gcc.dg/tree-ssa/writeonly-3.c new file mode 100644 index 00000000000..b42d9374fe9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/writeonly-3.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-optimized -flive-patching" } */ +static struct a {int magic1,b;} a; +volatile int magic2; +static struct b {int a,b,c,d,e,f;} magic3; + +struct b foo(); + +void +t() +{ + a.magic1 = 1; + magic2 = 1; + magic3 = foo(); +} +/* { dg-final { scan-tree-dump "magic1" "optimized"} } */ +/* { dg-final { scan-tree-dump "magic3" "optimized"} } */ +/* { dg-final { scan-tree-dump "magic2" "optimized"} } */ +/* { dg-final { scan-tree-dump "foo" "optimized"} } */ + diff --git a/gcc/testsuite/gcc.target/i386/ipa-stack-alignment-2.c b/gcc/testsuite/gcc.target/i386/ipa-stack-alignment-2.c new file mode 100644 index 00000000000..8ba70000b7e --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/ipa-stack-alignment-2.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-flive-patching -O" } */ + +typedef struct { + long a; + long b[]; +} c; + +c *d; +void e() { d->b[0] = 5; } +void f() { e(); } + +/* { dg-final { scan-assembler "sub.*%.sp" } } */ diff --git a/gcc/testsuite/gcc.target/i386/ipa-stack-alignment.c b/gcc/testsuite/gcc.target/i386/ipa-stack-alignment.c new file mode 100644 index 00000000000..1176b59aa5f --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/ipa-stack-alignment.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-fno-ipa-stack-alignment -O" } */ + +typedef struct { + long a; + long b[]; +} c; + +c *d; +void e() { d->b[0] = 5; } +void f() { e(); } + +/* { dg-final { scan-assembler "sub.*%.sp" } } */
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor