mirror of git://gcc.gnu.org/git/gcc.git
Add a new option -flive-patching={inline-only-static|inline-clone}
to support live patching in GCC. 2018-11-29 qing zhao <qing.zhao@oracle.com> gcc/ChangeLog: * cif-code.def (EXTERN_LIVE_ONLY_STATIC): New CIF code. * common.opt: Add -flive-patching flag. * doc/invoke.texi: Document -flive-patching. * flag-types.h (enum live_patching_level): New enum. * ipa-inline.c (can_inline_edge_p): Disable external functions from inlining when flag_live_patching is LIVE_PATCHING_INLINE_ONLY_STATIC. * opts.c (control_options_for_live_patching): New function. (finish_options): Make flag_live_patching incompatible with flag_lto. Control IPA optimizations based on different levels of flag_live_patching. gcc/testsuite/ChangeLog: * gcc.dg/live-patching-1.c: New test. * gcc.dg/live-patching-2.c: New test. * gcc.dg/live-patching-3.c: New test. * gcc.dg/tree-ssa/writeonly-3.c: New test. * gcc.target/i386/ipa-stack-alignment-2.c: New test. From-SVN: r266627
This commit is contained in:
parent
4aff6d1744
commit
6fd6a2ffee
|
|
@ -1,3 +1,16 @@
|
||||||
|
2018-11-29 qing zhao <qing.zhao@oracle.com>
|
||||||
|
|
||||||
|
* cif-code.def (EXTERN_LIVE_ONLY_STATIC): New CIF code.
|
||||||
|
* common.opt: Add -flive-patching flag.
|
||||||
|
* doc/invoke.texi: Document -flive-patching.
|
||||||
|
* flag-types.h (enum live_patching_level): New enum.
|
||||||
|
* ipa-inline.c (can_inline_edge_p): Disable external functions from
|
||||||
|
inlining when flag_live_patching is LIVE_PATCHING_INLINE_ONLY_STATIC.
|
||||||
|
* opts.c (control_options_for_live_patching): New function.
|
||||||
|
(finish_options): Make flag_live_patching incompatible with flag_lto.
|
||||||
|
Control IPA optimizations based on different levels of
|
||||||
|
flag_live_patching.
|
||||||
|
|
||||||
2018-11-29 Giuliano Belinassi <giuliano.belinassi@usp.br>
|
2018-11-29 Giuliano Belinassi <giuliano.belinassi@usp.br>
|
||||||
|
|
||||||
* match.pd (sinh (atanh (x))): New simplification rules.
|
* match.pd (sinh (atanh (x))): New simplification rules.
|
||||||
|
|
|
||||||
|
|
@ -132,6 +132,12 @@ DEFCIFCODE(USES_COMDAT_LOCAL, CIF_FINAL_ERROR,
|
||||||
DEFCIFCODE(ATTRIBUTE_MISMATCH, CIF_FINAL_ERROR,
|
DEFCIFCODE(ATTRIBUTE_MISMATCH, CIF_FINAL_ERROR,
|
||||||
N_("function attribute mismatch"))
|
N_("function attribute mismatch"))
|
||||||
|
|
||||||
|
/* 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, CIF_FINAL_ERROR,
|
||||||
|
N_("function has external linkage when the user requests only"
|
||||||
|
" inlining static for live patching"))
|
||||||
|
|
||||||
/* We proved that the call is unreachable. */
|
/* We proved that the call is unreachable. */
|
||||||
DEFCIFCODE(UNREACHABLE, CIF_FINAL_ERROR,
|
DEFCIFCODE(UNREACHABLE, CIF_FINAL_ERROR,
|
||||||
N_("unreachable"))
|
N_("unreachable"))
|
||||||
|
|
|
||||||
|
|
@ -2181,6 +2181,24 @@ starts and when the destructor finishes.
|
||||||
flifetime-dse=
|
flifetime-dse=
|
||||||
Common Joined RejectNegative UInteger Var(flag_lifetime_dse) Optimization IntegerRange(0, 2)
|
Common Joined RejectNegative UInteger Var(flag_lifetime_dse) Optimization IntegerRange(0, 2)
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
flive-range-shrinkage
|
flive-range-shrinkage
|
||||||
Common Report Var(flag_live_range_shrinkage) Init(0) Optimization
|
Common Report Var(flag_live_range_shrinkage) Init(0) Optimization
|
||||||
Relief of register pressure through live range shrinkage.
|
Relief of register pressure through live range shrinkage.
|
||||||
|
|
|
||||||
|
|
@ -417,6 +417,7 @@ Objective-C and Objective-C++ Dialects}.
|
||||||
-fipa-bit-cp -fipa-vrp -fipa-pta -fipa-profile -fipa-pure-const @gol
|
-fipa-bit-cp -fipa-vrp -fipa-pta -fipa-profile -fipa-pure-const @gol
|
||||||
-fipa-reference -fipa-reference-addressable @gol
|
-fipa-reference -fipa-reference-addressable @gol
|
||||||
-fipa-stack-alignment -fipa-icf -fira-algorithm=@var{algorithm} @gol
|
-fipa-stack-alignment -fipa-icf -fira-algorithm=@var{algorithm} @gol
|
||||||
|
-flive-patching=@var{level} @gol
|
||||||
-fira-region=@var{region} -fira-hoist-pressure @gol
|
-fira-region=@var{region} -fira-hoist-pressure @gol
|
||||||
-fira-loop-pressure -fno-ira-share-save-slots @gol
|
-fira-loop-pressure -fno-ira-share-save-slots @gol
|
||||||
-fno-ira-share-spill-slots @gol
|
-fno-ira-share-spill-slots @gol
|
||||||
|
|
@ -9291,6 +9292,65 @@ equivalences that are found only by GCC and equivalences found only by Gold.
|
||||||
|
|
||||||
This flag is enabled by default at @option{-O2} and @option{-Os}.
|
This flag is enabled by default at @option{-O2} and @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 -fisolate-erroneous-paths-dereference
|
@item -fisolate-erroneous-paths-dereference
|
||||||
@opindex fisolate-erroneous-paths-dereference
|
@opindex fisolate-erroneous-paths-dereference
|
||||||
Detect paths that trigger erroneous or undefined behavior due to
|
Detect paths that trigger erroneous or undefined behavior due to
|
||||||
|
|
|
||||||
|
|
@ -123,6 +123,14 @@ enum stack_reuse_level
|
||||||
SR_ALL
|
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 basic block reordering. */
|
/* The algorithm used for basic block reordering. */
|
||||||
enum reorder_blocks_algorithm
|
enum reorder_blocks_algorithm
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -379,6 +379,12 @@ can_inline_edge_p (struct cgraph_edge *e, bool report,
|
||||||
e->inline_failed = CIF_ATTRIBUTE_MISMATCH;
|
e->inline_failed = CIF_ATTRIBUTE_MISMATCH;
|
||||||
inlinable = false;
|
inlinable = false;
|
||||||
}
|
}
|
||||||
|
else if (callee->externally_visible
|
||||||
|
&& flag_live_patching == LIVE_PATCHING_INLINE_ONLY_STATIC)
|
||||||
|
{
|
||||||
|
e->inline_failed = CIF_EXTERN_LIVE_ONLY_STATIC;
|
||||||
|
inlinable = false;
|
||||||
|
}
|
||||||
if (!inlinable && report)
|
if (!inlinable && report)
|
||||||
report_inline_failed_reason (e);
|
report_inline_failed_reason (e);
|
||||||
return inlinable;
|
return inlinable;
|
||||||
|
|
|
||||||
154
gcc/opts.c
154
gcc/opts.c
|
|
@ -702,6 +702,148 @@ default_options_optimization (struct gcc_options *opts,
|
||||||
lang_mask, handlers, loc, dc);
|
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_ra && opts->x_flag_ipa_ra)
|
||||||
|
error_at (loc,
|
||||||
|
"%<-fipa-ra%> is incompatible with "
|
||||||
|
"%<-flive-patching=inline-only-static|inline-clone%>");
|
||||||
|
else
|
||||||
|
opts->x_flag_ipa_ra = 0;
|
||||||
|
|
||||||
|
if (opts_set->x_flag_ipa_icf && opts->x_flag_ipa_icf)
|
||||||
|
error_at (loc,
|
||||||
|
"%<-fipa-icf%> is incompatible with "
|
||||||
|
"%<-flive-patching=inline-only-static|inline-clone%>");
|
||||||
|
else
|
||||||
|
opts->x_flag_ipa_icf = 0;
|
||||||
|
|
||||||
|
if (opts_set->x_flag_ipa_icf_functions && opts->x_flag_ipa_icf_functions)
|
||||||
|
error_at (loc,
|
||||||
|
"%<-fipa-icf-functions%> is incompatible with "
|
||||||
|
"%<-flive-patching=inline-only-static|inline-clone%>");
|
||||||
|
else
|
||||||
|
opts->x_flag_ipa_icf_functions = 0;
|
||||||
|
|
||||||
|
if (opts_set->x_flag_ipa_icf_variables && opts->x_flag_ipa_icf_variables)
|
||||||
|
error_at (loc,
|
||||||
|
"%<-fipa-icf-variables%> is incompatible with "
|
||||||
|
"%<-flive-patching=inline-only-static|inline-clone%>");
|
||||||
|
else
|
||||||
|
opts->x_flag_ipa_icf_variables = 0;
|
||||||
|
|
||||||
|
if (opts_set->x_flag_ipa_bit_cp && opts->x_flag_ipa_bit_cp)
|
||||||
|
error_at (loc,
|
||||||
|
"%<-fipa-bit-cp%> is incompatible with "
|
||||||
|
"%<-flive-patching=inline-only-static|inline-clone%>");
|
||||||
|
else
|
||||||
|
opts->x_flag_ipa_bit_cp = 0;
|
||||||
|
|
||||||
|
if (opts_set->x_flag_ipa_vrp && opts->x_flag_ipa_vrp)
|
||||||
|
error_at (loc,
|
||||||
|
"%<-fipa-vrp%> is incompatible with "
|
||||||
|
"%<-flive-patching=inline-only-static|inline-clone%>");
|
||||||
|
else
|
||||||
|
opts->x_flag_ipa_vrp = 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,
|
/* After all options at LOC have been read into OPTS and OPTS_SET,
|
||||||
finalize settings of those options and diagnose incompatible
|
finalize settings of those options and diagnose incompatible
|
||||||
combinations. */
|
combinations. */
|
||||||
|
|
@ -1051,6 +1193,18 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set,
|
||||||
if ((opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS) && opts->x_flag_tm)
|
if ((opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS) && opts->x_flag_tm)
|
||||||
sorry ("transactional memory is not supported with "
|
sorry ("transactional memory is not supported with "
|
||||||
"%<-fsanitize=kernel-address%>");
|
"%<-fsanitize=kernel-address%>");
|
||||||
|
|
||||||
|
/* 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
|
#define LEFT_COLUMN 27
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,11 @@
|
||||||
|
2018-11-29 qing zhao <qing.zhao@oracle.com>
|
||||||
|
|
||||||
|
* gcc.dg/live-patching-1.c: New test.
|
||||||
|
* gcc.dg/live-patching-2.c: New test.
|
||||||
|
* gcc.dg/live-patching-3.c: New test.
|
||||||
|
* gcc.dg/tree-ssa/writeonly-3.c: New test.
|
||||||
|
* gcc.target/i386/ipa-stack-alignment-2.c: New test.
|
||||||
|
|
||||||
2018-11-29 Giuliano Belinassi <giuliano.belinassi@usp.br>
|
2018-11-29 Giuliano Belinassi <giuliano.belinassi@usp.br>
|
||||||
|
|
||||||
* gcc.dg/sinhatanh-1.c: New test.
|
* gcc.dg/sinhatanh-1.c: New test.
|
||||||
|
|
|
||||||
|
|
@ -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" } } */
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
/* { dg-do compile } */
|
||||||
|
/* { 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 } */
|
||||||
|
|
@ -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 } */
|
||||||
|
|
@ -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"} } */
|
||||||
|
|
||||||
|
|
@ -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" } } */
|
||||||
Loading…
Reference in New Issue