From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 113369 invoked by alias); 13 Nov 2018 21:16:56 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 113246 invoked by uid 89); 13 Nov 2018 21:16:55 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_PASS,UNPARSEABLE_RELAY autolearn=ham version=3.3.2 spammy=mbenes@suse.cz, U*mbenes, mbenessusecz X-HELO: userp2120.oracle.com Received: from userp2120.oracle.com (HELO userp2120.oracle.com) (156.151.31.85) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 13 Nov 2018 21:16:53 +0000 Received: from pps.filterd (userp2120.oracle.com [127.0.0.1]) by userp2120.oracle.com (8.16.0.22/8.16.0.22) with SMTP id wADLEAZ5183222; Tue, 13 Nov 2018 21:16:50 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : message-id : content-type : mime-version : subject : date : in-reply-to : cc : to : references; s=corp-2018-07-02; bh=HEiI8ZZ6/0gxNflFInClELF8kZAe2wcxLRLQtw1ux+4=; b=4oU4rSlCMzN46dGYzUy5Vo+ZDX7+wD3q8KCTTiLITdDwx5o/qWpOk40+Tsybxd4D9bTT Nv6W0ycFpMVYpBpGuS3yEqQCrON0ghkdjrLzedZ34fozPGfXExiM++LubL4ykNztcTwK snOjNtZeiIhxij6InmUQNmqEiHiMHA2tgvvNvr48gqGLVEAAoD6fGwQs/86eZPUR7icM dclStkynyB6tcfnD+DG6edKLAgNh0iCsgTmqX+R77RGXDUB5q+M9yz9k4+eegxfIbVIc 6zWh3JSyqfiXym/HM3nTljwh+HhD2Hhn25ifCZ4O87p+WReNfQSmsdfVufd4Iz+n7ny8 pw== Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp2120.oracle.com with ESMTP id 2nnwc0ne8j-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 13 Nov 2018 21:16:49 +0000 Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userv0022.oracle.com (8.14.4/8.14.4) with ESMTP id wADLGn6r023481 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 13 Nov 2018 21:16:49 GMT Received: from abhmp0010.oracle.com (abhmp0010.oracle.com [141.146.116.16]) by userv0122.oracle.com (8.14.4/8.14.4) with ESMTP id wADLGmv1025056; Tue, 13 Nov 2018 21:16:49 GMT Received: from dhcp-10-159-145-66.vpn.oracle.com (/10.159.145.66) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 13 Nov 2018 13:16:48 -0800 From: Qing Zhao Message-Id: <7FA7E4B3-BF39-4E60-84AD-91161CC4867F@oracle.com> Content-Type: multipart/mixed; boundary="Apple-Mail=_BA0B34C1-774E-48A3-9EC9-EEA5D5443922" Mime-Version: 1.0 (Mac OS X Mail 10.3 \(3273\)) Subject: Re: [PATCH][RFC] Come up with -flive-patching master option. Date: Tue, 13 Nov 2018 21:16:00 -0000 In-Reply-To: Cc: Jan Hubicka , =?utf-8?Q?Martin_Li=C5=A1ka?= , Martin Jambor , live-patching@vger.kernel.org, gcc Patches To: Miroslav Benes References: <1a023bdc-28a6-eb41-b449-4d096f12064f@suse.cz> <048D9997-B7AF-444A-BF7E-79944DE8F174@oracle.com> <3E37D3A8-2D19-41C2-BA8A-8F0EFA1B4D5C@oracle.com> <10a54034-279b-a406-8466-55558effbf24@suse.cz> <20181003090457.GJ57692@kam.mff.cuni.cz> <54a75932-201b-671c-0a63-d1a5d8d7b562@suse.cz> <90c91045-cb9d-0bd2-fad3-d16426ceede6@suse.cz> <20181105095135.j3mnzox6rkktkoto@kam.mff.cuni.cz> <629b20d2-7b0b-9342-a64a-d12eb6e6a6b7@suse.cz> <20181108145909.5eh5ccen7a7elspe@kam.mff.cuni.cz> <173116c6-d51c-3bef-5382-38593e032f82@suse.cz> <8f467934-c088-9b60-c4d3-c19c2e03defd@suse.cz> <2F74DD05-E807-4FB4-80B1-3BBC6FEDF6E8@oracle.com> X-IsSubscribed: yes X-SW-Source: 2018-11/txt/msg01149.txt.bz2 --Apple-Mail=_BA0B34C1-774E-48A3-9EC9-EEA5D5443922 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 Content-length: 4477 Hi, > On Nov 13, 2018, at 1:18 PM, Miroslav Benes wrote: >=20 >> Attached is the patch for new -flive-patching=3D[inline-only-static | in= line-clone] master option. >>=20 >> '-flive-patching=3DLEVEL' >> Control GCC's optimizations to provide a safe compilation for >> live-patching. Provides multiple-level control on how many of the >> optimizations are enabled by users' request. The LEVEL argument >> should be one of the following: >>=20 >> 'inline-only-static' >>=20 >> Only enable inlining of static functions, disable all other >> ipa optimizations/analyses. As a result, when patching a >> static routine, all its callers need to be patches as well. >>=20 >> 'inline-clone' >>=20 >> Only enable inlining and all optimizations that internally >> create clone, for example, cloning, ipa-sra, partial inlining, >> etc.; disable all other ipa optimizations/analyses. As a >> result, when patching a routine, all its callers and its >> clones' callers need to be patched as well. >=20 > Based on our previous discussion I assume that "clone" optimizations are= =20 > safe (for LP) and the others are not. Anyway I'd welcome a note mentionin= g=20 > that disabled optimizations are dangerous for LP. actually, I don=E2=80=99t think that those disabled optimizations are =E2= =80=9Cdangerous=E2=80=9D for live-patching. one of the major reasons we dis= able them is because that currently the compiler does NOT provide a good way to compu= te the impacted function list for those optimizations. therefore, we disable them at this time.=20 many of them could be enabled too if the compiler can report the impacted f= unction list accurately in the future. >=20 > I know it may be the same for you, but it is not for me as a GCC user.=20 > "internally create clone" sounds very... well, internal. It does not=20 > describe the option much for ordinary user whow has no knowledge about GC= C=20 > internals. >=20 > So could you rephrase it a bit, please? I tried to make this clear. please see the following: '-flive-patching=3DLEVEL' 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 LEVEL argument should be one of the following: 'inline-only-static' Only enable inlining of static functions, disable all other interprocedural optimizations/analyses. As a result, when patching a static routine, all its callers need to be patches as well. 'inline-clone' Only enable inlining and cloning optimizations, which includes inlining, cloning, interprocedural scalar replacement of aggregates and partial inlining. Disable all other interprocedural optimizations/analyses. As a result, when patching a routine, all its callers and its clones' callers need to be patched as well. When -flive-patching specified without any value, the default value is "inline-clone". This flag is disabled by default. >=20 >> When -flive-patching specified without any value, the default value >> is "inline-clone". >>=20 >> This flag is disabled by default. >>=20 >> let me know your comments and suggestions on the implementation. >=20 > I compared it to Martin's patch and ipa-icf-variables is not covered in=20 > yours (I may have missed something). Yes, you are right. I added this into my patch. I am attaching the new patch here. --Apple-Mail=_BA0B34C1-774E-48A3-9EC9-EEA5D5443922 Content-Disposition: attachment; filename=flive-patching.patch Content-Type: application/octet-stream; x-unix-mode=0644; name="flive-patching.patch" Content-Transfer-Encoding: quoted-printable Content-length: 12121 >From c0785675eb29599754aaf11c70901c12dd3ea821 Mon Sep 17 00:00:00 2001=0A= From: qing zhao =0A= Date: Tue, 13 Nov 2018 13:02:57 -0800=0A= Subject: [PATCH] Add -flive-patching to support live patching=0A= =0A= ---=0A= gcc/cif-code.def | 6 +++=0A= gcc/common.opt | 18 +++++++++=0A= gcc/doc/invoke.texi | 49 +++++++++++++++++++++++-=0A= gcc/flag-types.h | 8 ++++=0A= gcc/ipa-inline.c | 6 +++=0A= gcc/opts.c | 68 ++++++++++++++++++++++++++++++= ++++=0A= gcc/testsuite/gcc.dg/live-patching-1.c | 22 +++++++++++=0A= 7 files changed, 176 insertions(+), 1 deletion(-)=0A= create mode 100644 gcc/testsuite/gcc.dg/live-patching-1.c=0A= =0A= diff --git a/gcc/cif-code.def b/gcc/cif-code.def=0A= index 19a7621..dffe15f 100644=0A= --- a/gcc/cif-code.def=0A= +++ b/gcc/cif-code.def=0A= @@ -132,6 +132,12 @@ DEFCIFCODE(USES_COMDAT_LOCAL, CIF_FINAL_ERROR,=0A= DEFCIFCODE(ATTRIBUTE_MISMATCH, CIF_FINAL_ERROR,=0A= N_("function attribute mismatch"))=0A= =20=0A= +/* We can't inline because the user requests only static functions=20=0A= + but the function has external linkage for live patching purpose. */=0A= +DEFCIFCODE(EXTERN_LIVE_ONLY_STATIC, CIF_FINAL_ERROR,=0A= + N_("function has external linkage when the user requests only"=0A= + " inlining static for live patching"))=0A= +=0A= /* We proved that the call is unreachable. */=0A= DEFCIFCODE(UNREACHABLE, CIF_FINAL_ERROR,=0A= N_("unreachable"))=0A= diff --git a/gcc/common.opt b/gcc/common.opt=0A= index 98e8eb0..346a361 100644=0A= --- a/gcc/common.opt=0A= +++ b/gcc/common.opt=0A= @@ -2152,6 +2152,24 @@ starts and when the destructor finishes.=0A= flifetime-dse=3D=0A= Common Joined RejectNegative UInteger Var(flag_lifetime_dse) Optimization = IntegerRange(0, 2)=0A= =20=0A= +flive-patching=0A= +Common RejectNegative Alias(flive-patching=3D,inline-clone) Optimization= =0A= +=0A= +flive-patching=3D=0A= +Common Report Joined RejectNegative Enum(live_patching_level) Var(flag_liv= e_patching) Init(LIVE_NONE) Optimization=0A= +-flive-patching=3D[inline-only-static|inline-clone] Control ipa optimizati= ons to provide a=20=0A= +safe compilation for live-patching. At the same time, provides multiple-le= vel control on the=20=20=0A= +enabled optimizations.=20=0A= +=0A= +Enum=0A= +Name(live_patching_level) Type(enum live_patching_level) UnknownError(unkn= own Live-Patching Level %qs)=0A= +=0A= +EnumValue=0A= +Enum(live_patching_level) String(inline-only-static) Value(LIVE_INLINE_ONL= Y_STATIC)=0A= +=0A= +EnumValue=0A= +Enum(live_patching_level) String(inline-clone) Value(LIVE_INLINE_CLONE)=0A= +=0A= flive-range-shrinkage=0A= Common Report Var(flag_live_range_shrinkage) Init(0) Optimization=0A= Relief of register pressure through live range shrinkage.=0A= diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi=0A= index 4ea93a7..c473049 100644=0A= --- a/gcc/doc/invoke.texi=0A= +++ b/gcc/doc/invoke.texi=0A= @@ -411,10 +411,11 @@ Objective-C and Objective-C++ Dialects}.=0A= -fgcse-sm -fhoist-adjacent-loads -fif-conversion @gol=0A= -fif-conversion2 -findirect-inlining @gol=0A= -finline-functions -finline-functions-called-once -finline-limit=3D@var{= n} @gol=0A= --finline-small-functions -fipa-cp -fipa-cp-clone @gol=0A= +-finline-small-functions -fipa-cp -fipa-cp-clone @gol=0A= -fipa-bit-cp -fipa-vrp @gol=0A= -fipa-pta -fipa-profile -fipa-pure-const -fipa-reference -fipa-referen= ce-addressable @gol=0A= -fipa-stack-alignment -fipa-icf -fira-algorithm=3D@var{algorithm} @gol= =0A= +-flive-patching=3D@var{level} @gol=0A= -fira-region=3D@var{region} -fira-hoist-pressure @gol=0A= -fira-loop-pressure -fno-ira-share-save-slots @gol=0A= -fno-ira-share-spill-slots @gol=0A= @@ -8982,6 +8983,52 @@ equivalences that are found only by GCC and equivale= nces found only by Gold.=0A= =20=0A= This flag is enabled by default at @option{-O2} and @option{-Os}.=0A= =20=0A= +@item -flive-patching=3D@var{level}=0A= +@opindex flive-patching=0A= +Control GCC's optimizations to provide a safe compilation for live-patchin= g.=0A= +=0A= +If the compiler's optimization uses a function's body or information extra= cted=20=0A= +from its body to optimize/change another function, the latter is called an= =0A= +impacted function of the former. If a function is patched, its impacted= =0A= +functions should be patched too.=0A= +=0A= +The impacted functions are decided by the compiler's interprocedural=0A= +optimizations. For example, inlining a function into its caller, cloning= =20=0A= +a function and changing its caller to call this new clone, or extracting= =0A= +a function's pureness/constness information to optimize its direct or=20= =0A= +indirect callers, etc.=0A= +=0A= +Usually, the more ipa optimizations enabled, the larger the number of=0A= +impacted functions for each function. In order to control the number of=0A= +impacted functions and computed the list of impacted function easily,=20= =0A= +we provide control to partially enable ipa optimizations on two different= =20=0A= +levels.=0A= +=0A= +The @var{level} argument should be one of the following:=0A= +=0A= +@table @samp=0A= +=0A= +@item inline-only-static=0A= +=0A= +Only enable inlining of static functions, disable all other interprocedura= l=20=0A= +optimizations/analyses. As a result, when patching a static routine,=0A= +all its callers need to be patches as well.=0A= +=0A= +@item inline-clone=20=0A= +=0A= +Only enable inlining and cloning optimizations, which includes inlining,= =20=0A= +cloning, interprocedural scalar replacement of aggregates and partial inli= ning.=0A= +Disable all other interprocedural optimizations/analyses.=0A= +As a result, when patching a routine, all its callers and its clones'=0A= +callers need to be patched as well.=0A= +=0A= +@end table=0A= +=0A= +When -flive-patching specified without any value, the default value=0A= +is "inline-clone".=0A= +=0A= +This flag is disabled by default.=0A= +=0A= @item -fisolate-erroneous-paths-dereference=0A= @opindex fisolate-erroneous-paths-dereference=0A= Detect paths that trigger erroneous or undefined behavior due to=0A= diff --git a/gcc/flag-types.h b/gcc/flag-types.h=0A= index 500f663..72e0f0f 100644=0A= --- a/gcc/flag-types.h=0A= +++ b/gcc/flag-types.h=0A= @@ -123,6 +123,14 @@ enum stack_reuse_level=0A= SR_ALL=0A= };=0A= =20=0A= +/* The live patching level. */=0A= +enum live_patching_level=0A= +{=0A= + LIVE_NONE =3D 0,=0A= + LIVE_INLINE_ONLY_STATIC,=0A= + LIVE_INLINE_CLONE=0A= +};=0A= +=0A= /* The algorithm used for basic block reordering. */=0A= enum reorder_blocks_algorithm=0A= {=0A= diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c=0A= index e04ede7..fadb437 100644=0A= --- a/gcc/ipa-inline.c=0A= +++ b/gcc/ipa-inline.c=0A= @@ -377,6 +377,12 @@ can_inline_edge_p (struct cgraph_edge *e, bool report,= =0A= e->inline_failed =3D CIF_ATTRIBUTE_MISMATCH;=0A= inlinable =3D false;=0A= }=0A= + else if (callee->externally_visible=20=0A= + && flag_live_patching =3D=3D LIVE_INLINE_ONLY_STATIC)=20=0A= + {=0A= + e->inline_failed =3D CIF_EXTERN_LIVE_ONLY_STATIC;=0A= + inlinable =3D false;=0A= + }=0A= if (!inlinable && report)=0A= report_inline_failed_reason (e);=0A= return inlinable;=0A= diff --git a/gcc/opts.c b/gcc/opts.c=0A= index e21967b..281f9f4 100644=0A= --- a/gcc/opts.c=0A= +++ b/gcc/opts.c=0A= @@ -691,6 +691,64 @@ default_options_optimization (struct gcc_options *opts= ,=0A= lang_mask, handlers, loc, dc);=0A= }=0A= =20=0A= +/* Control ipa optimizations based on different live patching LEVEL */=0A= +static void=0A= +control_optimizations_for_live_patching (struct gcc_options *opts,=20=0A= + struct gcc_options *opts_set,=20=0A= + enum live_patching_level level)=0A= +{=0A= + gcc_assert (level > LIVE_NONE);=0A= +=0A= + switch (level)=0A= + {=0A= + case LIVE_INLINE_ONLY_STATIC:=0A= + if (!opts_set->x_flag_ipa_cp_clone)=0A= + opts->x_flag_ipa_cp_clone =3D 0;=20=20=20=20=20=20=0A= + if (!opts_set->x_flag_ipa_sra)=0A= + opts->x_flag_ipa_sra =3D 0;=0A= + if (!opts_set->x_flag_partial_inlining)=0A= + opts->x_flag_partial_inlining =3D 0;=0A= + if (!opts_set->x_flag_ipa_cp)=0A= + opts->x_flag_ipa_cp =3D 0;=20=20=20=20=20=20=0A= + /* FALLTHROUGH */=0A= + case LIVE_INLINE_CLONE:=0A= + /* live patching should disable whole-program optimization. */=0A= + if (!opts_set->x_flag_whole_program)=0A= + opts->x_flag_whole_program =3D 0;=0A= + /* visibility change should be excluded by !flag_whole_program=20=0A= + && !in_lto_p && !flag_ipa_cp_clone && !flag_ipa_sra=20=0A= + && !flag_partial_inlining. */=0A= + if (!opts_set->x_flag_ipa_pta)=0A= + opts->x_flag_ipa_pta =3D 0;=0A= + if (!opts_set->x_flag_ipa_reference)=0A= + opts->x_flag_ipa_reference =3D 0;=0A= + if (!opts_set->x_flag_ipa_ra)=0A= + opts->x_flag_ipa_ra =3D 0;=0A= + if (!opts_set->x_flag_ipa_icf)=0A= + opts->x_flag_ipa_icf =3D 0;=0A= + if (!opts_set->x_flag_ipa_icf_functions)=0A= + opts->x_flag_ipa_icf_functions =3D 0;=0A= + if (!opts_set->x_flag_ipa_icf_variables)=0A= + opts->x_flag_ipa_icf_variables =3D 0;=0A= + if (!opts_set->x_flag_ipa_bit_cp)=0A= + opts->x_flag_ipa_bit_cp =3D 0;=0A= + if (!opts_set->x_flag_ipa_vrp)=0A= + opts->x_flag_ipa_vrp =3D 0;=0A= + if (!opts_set->x_flag_ipa_pure_const)=0A= + opts->x_flag_ipa_pure_const =3D 0;=0A= + /* unreachable code removal. */=0A= + /* discovery of functions/variables with no address taken. */=0A= + if (!opts_set->x_flag_ipa_reference_addressable)=0A= + opts->x_flag_ipa_reference_addressable =3D 0;=0A= + /* ipa stack alignment propagation. */=0A= + if (!opts_set->x_flag_ipa_stack_alignment)=0A= + opts->x_flag_ipa_stack_alignment =3D 0;=0A= + break;=0A= + default:=20=0A= + gcc_assert (0);=20=20=0A= + }=0A= +}=0A= +=0A= /* After all options at LOC have been read into OPTS and OPTS_SET,=0A= finalize settings of those options and diagnose incompatible=0A= combinations. */=0A= @@ -1040,6 +1098,10 @@ finish_options (struct gcc_options *opts, struct gcc= _options *opts_set,=0A= if ((opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS) && opts->x_flag_tm= )=0A= sorry ("transactional memory is not supported with "=0A= "%<-fsanitize=3Dkernel-address%>");=0A= +=0A= + /* Currently live patching is not support for LTO. */=0A= + if (opts->x_flag_live_patching && in_lto_p)=20=0A= + sorry ("live patching is not supported with LTO");=0A= }=0A= =20=0A= #define LEFT_COLUMN 27=0A= @@ -2266,6 +2328,12 @@ common_handle_option (struct gcc_options *opts,=0A= (&opts->x_flag_instrument_functions_exclude_files, arg);=0A= break;=0A= =20=0A= + case OPT_flive_patching_:=0A= + if (value)=0A= + control_optimizations_for_live_patching (opts, opts_set,=0A= + opts->x_flag_live_patching);=0A= + break;=0A= +=0A= case OPT_fmessage_length_:=0A= pp_set_line_maximum_length (dc->printer, value);=0A= diagnostic_set_caret_max_width (dc, value);=0A= diff --git a/gcc/testsuite/gcc.dg/live-patching-1.c b/gcc/testsuite/gcc.dg/= live-patching-1.c=0A= new file mode 100644=0A= index 0000000..6a1ea38=0A= --- /dev/null=0A= +++ b/gcc/testsuite/gcc.dg/live-patching-1.c=0A= @@ -0,0 +1,22 @@=0A= +/* { dg-do compile } */=0A= +/* { dg-options "-O2 -flive-patching=3Dinline-only-static -fdump-ipa-inlin= e" } */=0A= +=0A= +extern int sum, n, m;=0A= +=0A= +int foo (int a)=0A= +{=0A= + return a + n;=0A= +}=0A= +=0A= +static int bar (int b)=0A= +{=0A= + return b * m;=0A= +}=0A= +=0A= +int main()=0A= +{=0A= + sum =3D foo (m) + bar (n);=20=0A= + return 0;=0A= +}=0A= +=0A= +/* { dg-final { scan-ipa-dump "foo/0 function has external linkage when th= e user requests only inlining static for live patching" "inline" } } */=0A= --=20=0A= 1.9.1=0A= --Apple-Mail=_BA0B34C1-774E-48A3-9EC9-EEA5D5443922 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset=us-ascii Content-length: 27 > > Thanks, > Miroslav --Apple-Mail=_BA0B34C1-774E-48A3-9EC9-EEA5D5443922--