Blame SOURCES/gcc8-rh1668903-1.patch

f56e54
commit 126dab7c9d84294f256b1f7bf91c24a9e7103249
f56e54
Author: qinzhao <qinzhao@138bc75d-0d04-0410-961f-82ee72b054a4>
f56e54
Date:   Thu Nov 29 16:06:03 2018 +0000
f56e54
f56e54
    Add a new option -flive-patching={inline-only-static|inline-clone}
f56e54
    to support live patching in GCC.
f56e54
    
f56e54
    2018-11-29  qing zhao  <qing.zhao@oracle.com>
f56e54
    
f56e54
    gcc/ChangeLog:
f56e54
    
f56e54
            * cif-code.def (EXTERN_LIVE_ONLY_STATIC): New CIF code.
f56e54
            * common.opt: Add -flive-patching flag.
f56e54
            * doc/invoke.texi: Document -flive-patching.
f56e54
            * flag-types.h (enum live_patching_level): New enum.
f56e54
            * ipa-inline.c (can_inline_edge_p): Disable external functions from
f56e54
            inlining when flag_live_patching is LIVE_PATCHING_INLINE_ONLY_STATIC.
f56e54
            * opts.c (control_options_for_live_patching): New function.
f56e54
            (finish_options): Make flag_live_patching incompatible with flag_lto.
f56e54
            Control IPA optimizations based on different levels of
f56e54
            flag_live_patching.
f56e54
    
f56e54
    gcc/testsuite/ChangeLog:
f56e54
    
f56e54
            * gcc.dg/live-patching-1.c: New test.
f56e54
            * gcc.dg/live-patching-2.c: New test.
f56e54
            * gcc.dg/live-patching-3.c: New test.
f56e54
            * gcc.dg/tree-ssa/writeonly-3.c: New test.
f56e54
            * gcc.target/i386/ipa-stack-alignment-2.c: New test.
f56e54
    
f56e54
    
f56e54
    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@266627 138bc75d-0d04-0410-961f-82ee72b054a4
f56e54
f56e54
--- gcc/cif-code.def
f56e54
+++ gcc/cif-code.def
f56e54
@@ -132,6 +132,12 @@ DEFCIFCODE(USES_COMDAT_LOCAL, CIF_FINAL_ERROR,
f56e54
 DEFCIFCODE(ATTRIBUTE_MISMATCH, CIF_FINAL_ERROR,
f56e54
 	   N_("function attribute mismatch"))
f56e54
 
f56e54
+/* We can't inline because the user requests only static functions
f56e54
+   but the function has external linkage for live patching purpose.  */
f56e54
+DEFCIFCODE(EXTERN_LIVE_ONLY_STATIC, CIF_FINAL_ERROR,
f56e54
+	   N_("function has external linkage when the user requests only"
f56e54
+	      " inlining static for live patching"))
f56e54
+
f56e54
 /* We proved that the call is unreachable.  */
f56e54
 DEFCIFCODE(UNREACHABLE, CIF_FINAL_ERROR,
f56e54
 	   N_("unreachable"))
f56e54
--- gcc/common.opt
f56e54
+++ gcc/common.opt
f56e54
@@ -2181,6 +2181,24 @@ starts and when the destructor finishes.
f56e54
 flifetime-dse=
f56e54
 Common Joined RejectNegative UInteger Var(flag_lifetime_dse) Optimization IntegerRange(0, 2)
f56e54
 
f56e54
+flive-patching
f56e54
+Common RejectNegative Alias(flive-patching=,inline-clone) Optimization
f56e54
+
f56e54
+flive-patching=
f56e54
+Common Report Joined RejectNegative Enum(live_patching_level) Var(flag_live_patching) Init(LIVE_PATCHING_NONE) Optimization
f56e54
+-flive-patching=[inline-only-static|inline-clone]	Control IPA
f56e54
+optimizations to provide a safe compilation for live-patching.  At the same
f56e54
+time, provides multiple-level control on the enabled IPA optimizations.
f56e54
+
f56e54
+Enum
f56e54
+Name(live_patching_level) Type(enum live_patching_level) UnknownError(unknown Live-Patching Level %qs)
f56e54
+
f56e54
+EnumValue
f56e54
+Enum(live_patching_level) String(inline-only-static) Value(LIVE_PATCHING_INLINE_ONLY_STATIC)
f56e54
+
f56e54
+EnumValue
f56e54
+Enum(live_patching_level) String(inline-clone) Value(LIVE_PATCHING_INLINE_CLONE)
f56e54
+
f56e54
 flive-range-shrinkage
f56e54
 Common Report Var(flag_live_range_shrinkage) Init(0) Optimization
f56e54
 Relief of register pressure through live range shrinkage.
f56e54
--- gcc/doc/invoke.texi
f56e54
+++ gcc/doc/invoke.texi
f56e54
@@ -389,6 +389,7 @@ Objective-C and Objective-C++ Dialects}.
f56e54
 -fipa-bit-cp -fipa-vrp @gol
f56e54
 -fipa-pta  -fipa-profile  -fipa-pure-const  -fipa-reference  -fipa-icf @gol
f56e54
 -fira-algorithm=@var{algorithm} @gol
f56e54
+-flive-patching=@var{level} @gol
f56e54
 -fira-region=@var{region}  -fira-hoist-pressure @gol
f56e54
 -fira-loop-pressure  -fno-ira-share-save-slots @gol
f56e54
 -fno-ira-share-spill-slots @gol
f56e54
@@ -9291,6 +9292,65 @@ equivalences that are found only by GCC and equivalences found only by Gold.
f56e54
 
f56e54
 This flag is enabled by default at @option{-O2} and @option{-Os}.
f56e54
 
f56e54
+@item -flive-patching=@var{level}
f56e54
+@opindex flive-patching
f56e54
+Control GCC's optimizations to provide a safe compilation for live-patching.
f56e54
+
f56e54
+If the compiler's optimization uses a function's body or information extracted
f56e54
+from its body to optimize/change another function, the latter is called an
f56e54
+impacted function of the former.  If a function is patched, its impacted
f56e54
+functions should be patched too.
f56e54
+
f56e54
+The impacted functions are decided by the compiler's interprocedural
f56e54
+optimizations.  For example, inlining a function into its caller, cloning
f56e54
+a function and changing its caller to call this new clone, or extracting
f56e54
+a function's pureness/constness information to optimize its direct or
f56e54
+indirect callers, etc.
f56e54
+
f56e54
+Usually, the more IPA optimizations enabled, the larger the number of
f56e54
+impacted functions for each function.  In order to control the number of
f56e54
+impacted functions and computed the list of impacted function easily,
f56e54
+we provide control to partially enable IPA optimizations on two different
f56e54
+levels.
f56e54
+
f56e54
+The @var{level} argument should be one of the following:
f56e54
+
f56e54
+@table @samp
f56e54
+
f56e54
+@item inline-clone
f56e54
+
f56e54
+Only enable inlining and cloning optimizations, which includes inlining,
f56e54
+cloning, interprocedural scalar replacement of aggregates and partial inlining.
f56e54
+As a result, when patching a function, all its callers and its clones'
f56e54
+callers need to be patched as well.
f56e54
+
f56e54
+@option{-flive-patching=inline-clone} disables the following optimization flags:
f56e54
+@gccoptlist{-fwhole-program  -fipa-pta  -fipa-reference  -fipa-ra @gol
f56e54
+-fipa-icf  -fipa-icf-functions  -fipa-icf-variables @gol
f56e54
+-fipa-bit-cp  -fipa-vrp  -fipa-pure-const  -fipa-reference-addressable @gol
f56e54
+-fipa-stack-alignment}
f56e54
+
f56e54
+@item inline-only-static
f56e54
+
f56e54
+Only enable inlining of static functions.
f56e54
+As a result, when patching a static function, all its callers need to be
f56e54
+patches as well.
f56e54
+
f56e54
+In addition to all the flags that -flive-patching=inline-clone disables,
f56e54
+@option{-flive-patching=inline-only-static} disables the following additional
f56e54
+optimization flags:
f56e54
+@gccoptlist{-fipa-cp-clone  -fipa-sra  -fpartial-inlining  -fipa-cp}
f56e54
+
f56e54
+@end table
f56e54
+
f56e54
+When -flive-patching specified without any value, the default value
f56e54
+is "inline-clone".
f56e54
+
f56e54
+This flag is disabled by default.
f56e54
+
f56e54
+Note that -flive-patching is not supported with link-time optimizer.
f56e54
+(@option{-flto}).
f56e54
+
f56e54
 @item -fisolate-erroneous-paths-dereference
f56e54
 @opindex fisolate-erroneous-paths-dereference
f56e54
 Detect paths that trigger erroneous or undefined behavior due to
f56e54
--- gcc/flag-types.h
f56e54
+++ gcc/flag-types.h
f56e54
@@ -123,6 +123,14 @@ enum stack_reuse_level
f56e54
   SR_ALL
f56e54
 };
f56e54
 
f56e54
+/* The live patching level.  */
f56e54
+enum live_patching_level
f56e54
+{
f56e54
+  LIVE_PATCHING_NONE = 0,
f56e54
+  LIVE_PATCHING_INLINE_ONLY_STATIC,
f56e54
+  LIVE_PATCHING_INLINE_CLONE
f56e54
+};
f56e54
+
f56e54
 /* The algorithm used for basic block reordering.  */
f56e54
 enum reorder_blocks_algorithm
f56e54
 {
f56e54
--- gcc/ipa-inline.c
f56e54
+++ gcc/ipa-inline.c
f56e54
@@ -379,6 +379,12 @@ can_inline_edge_p (struct cgraph_edge *e, bool report,
f56e54
       e->inline_failed = CIF_ATTRIBUTE_MISMATCH;
f56e54
       inlinable = false;
f56e54
     }
f56e54
+  else if (callee->externally_visible
f56e54
+	   && flag_live_patching == LIVE_PATCHING_INLINE_ONLY_STATIC)
f56e54
+    {
f56e54
+      e->inline_failed = CIF_EXTERN_LIVE_ONLY_STATIC;
f56e54
+      inlinable = false;
f56e54
+    }
f56e54
   if (!inlinable && report)
f56e54
     report_inline_failed_reason (e);
f56e54
   return inlinable;
f56e54
--- gcc/opts.c
f56e54
+++ gcc/opts.c
f56e54
@@ -699,6 +699,152 @@ default_options_optimization (struct gcc
f56e54
 			 lang_mask, handlers, loc, dc);
f56e54
 }
f56e54
 
f56e54
+/* Control IPA optimizations based on different live patching LEVEL.  */
f56e54
+static void
f56e54
+control_options_for_live_patching (struct gcc_options *opts,
f56e54
+				   struct gcc_options *opts_set,
f56e54
+				   enum live_patching_level level,
f56e54
+				   location_t loc)
f56e54
+{
f56e54
+  gcc_assert (level > LIVE_PATCHING_NONE);
f56e54
+
f56e54
+  switch (level)
f56e54
+    {
f56e54
+    case LIVE_PATCHING_INLINE_ONLY_STATIC:
f56e54
+      if (opts_set->x_flag_ipa_cp_clone && opts->x_flag_ipa_cp_clone)
f56e54
+	error_at (loc,
f56e54
+		  "%<-fipa-cp-clone%> is incompatible with "
f56e54
+		  "%<-flive-patching=inline-only-static%>");
f56e54
+      else
f56e54
+	opts->x_flag_ipa_cp_clone = 0;
f56e54
+
f56e54
+      if (opts_set->x_flag_ipa_sra && opts->x_flag_ipa_sra)
f56e54
+	error_at (loc,
f56e54
+		  "%<-fipa-sra%> is incompatible with "
f56e54
+		  "%<-flive-patching=inline-only-static%>");
f56e54
+      else
f56e54
+	opts->x_flag_ipa_sra = 0;
f56e54
+
f56e54
+      if (opts_set->x_flag_partial_inlining && opts->x_flag_partial_inlining)
f56e54
+	error_at (loc,
f56e54
+		  "%<-fpartial-inlining%> is incompatible with "
f56e54
+		  "%<-flive-patching=inline-only-static%>");
f56e54
+      else
f56e54
+	opts->x_flag_partial_inlining = 0;
f56e54
+
f56e54
+      if (opts_set->x_flag_ipa_cp && opts->x_flag_ipa_cp)
f56e54
+	error_at (loc,
f56e54
+		  "%<-fipa-cp%> is incompatible with "
f56e54
+		  "%<-flive-patching=inline-only-static%>");
f56e54
+      else
f56e54
+	opts->x_flag_ipa_cp = 0;
f56e54
+
f56e54
+      /* FALLTHROUGH.  */
f56e54
+    case LIVE_PATCHING_INLINE_CLONE:
f56e54
+      /* live patching should disable whole-program optimization.  */
f56e54
+      if (opts_set->x_flag_whole_program && opts->x_flag_whole_program)
f56e54
+	error_at (loc,
f56e54
+		  "%<-fwhole-program%> is incompatible with "
f56e54
+		  "%<-flive-patching=inline-only-static|inline-clone%>");
f56e54
+      else
f56e54
+	opts->x_flag_whole_program = 0;
f56e54
+
f56e54
+      /* visibility change should be excluded by !flag_whole_program
f56e54
+	 && !in_lto_p && !flag_ipa_cp_clone && !flag_ipa_sra
f56e54
+	 && !flag_partial_inlining.  */
f56e54
+
f56e54
+      if (opts_set->x_flag_ipa_pta && opts->x_flag_ipa_pta)
f56e54
+	error_at (loc,
f56e54
+		  "%<-fipa-pta%> is incompatible with "
f56e54
+		  "%<-flive-patching=inline-only-static|inline-clone%>");
f56e54
+      else
f56e54
+	opts->x_flag_ipa_pta = 0;
f56e54
+
f56e54
+      if (opts_set->x_flag_ipa_reference && opts->x_flag_ipa_reference)
f56e54
+	error_at (loc,
f56e54
+		  "%<-fipa-reference%> is incompatible with "
f56e54
+		  "%<-flive-patching=inline-only-static|inline-clone%>");
f56e54
+      else
f56e54
+	opts->x_flag_ipa_reference = 0;
f56e54
+
f56e54
+      if (opts_set->x_flag_ipa_ra && opts->x_flag_ipa_ra)
f56e54
+	error_at (loc,
f56e54
+		  "%<-fipa-ra%> is incompatible with "
f56e54
+		  "%<-flive-patching=inline-only-static|inline-clone%>");
f56e54
+      else
f56e54
+	opts->x_flag_ipa_ra = 0;
f56e54
+
f56e54
+      if (opts_set->x_flag_ipa_icf && opts->x_flag_ipa_icf)
f56e54
+	error_at (loc,
f56e54
+		  "%<-fipa-icf%> is incompatible with "
f56e54
+		  "%<-flive-patching=inline-only-static|inline-clone%>");
f56e54
+      else
f56e54
+	opts->x_flag_ipa_icf = 0;
f56e54
+
f56e54
+      if (opts_set->x_flag_ipa_icf_functions && opts->x_flag_ipa_icf_functions)
f56e54
+	error_at (loc,
f56e54
+		  "%<-fipa-icf-functions%> is incompatible with "
f56e54
+		  "%<-flive-patching=inline-only-static|inline-clone%>");
f56e54
+      else
f56e54
+	opts->x_flag_ipa_icf_functions = 0;
f56e54
+
f56e54
+      if (opts_set->x_flag_ipa_icf_variables && opts->x_flag_ipa_icf_variables)
f56e54
+	error_at (loc,
f56e54
+		  "%<-fipa-icf-variables%> is incompatible with "
f56e54
+		  "%<-flive-patching=inline-only-static|inline-clone%>");
f56e54
+      else
f56e54
+	opts->x_flag_ipa_icf_variables = 0;
f56e54
+
f56e54
+      if (opts_set->x_flag_ipa_bit_cp && opts->x_flag_ipa_bit_cp)
f56e54
+	error_at (loc,
f56e54
+		  "%<-fipa-bit-cp%> is incompatible with "
f56e54
+		  "%<-flive-patching=inline-only-static|inline-clone%>");
f56e54
+      else
f56e54
+	opts->x_flag_ipa_bit_cp = 0;
f56e54
+
f56e54
+      if (opts_set->x_flag_ipa_vrp && opts->x_flag_ipa_vrp)
f56e54
+	error_at (loc,
f56e54
+		  "%<-fipa-vrp%> is incompatible with "
f56e54
+		  "%<-flive-patching=inline-only-static|inline-clone%>");
f56e54
+      else
f56e54
+	opts->x_flag_ipa_vrp = 0;
f56e54
+
f56e54
+      if (opts_set->x_flag_ipa_pure_const && opts->x_flag_ipa_pure_const)
f56e54
+	error_at (loc,
f56e54
+		  "%<-fipa-pure-const%> is incompatible with "
f56e54
+		  "%<-flive-patching=inline-only-static|inline-clone%>");
f56e54
+      else
f56e54
+	opts->x_flag_ipa_pure_const = 0;
f56e54
+
f56e54
+      /* FIXME: disable unreachable code removal.  */
f56e54
+
f56e54
+      /* discovery of functions/variables with no address taken.  */
f56e54
+// GCC 8 doesn't have these options.
f56e54
+#if 0
f56e54
+      if (opts_set->x_flag_ipa_reference_addressable
f56e54
+	  && opts->x_flag_ipa_reference_addressable)
f56e54
+	error_at (loc,
f56e54
+		  "%<-fipa-reference-addressable%> is incompatible with "
f56e54
+		  "%<-flive-patching=inline-only-static|inline-clone%>");
f56e54
+      else
f56e54
+	opts->x_flag_ipa_reference_addressable = 0;
f56e54
+
f56e54
+      /* ipa stack alignment propagation.  */
f56e54
+      if (opts_set->x_flag_ipa_stack_alignment
f56e54
+	  && opts->x_flag_ipa_stack_alignment)
f56e54
+	error_at (loc,
f56e54
+		  "%<-fipa-stack-alignment%> is incompatible with "
f56e54
+		  "%<-flive-patching=inline-only-static|inline-clone%>");
f56e54
+      else
f56e54
+	opts->x_flag_ipa_stack_alignment = 0;
f56e54
+#endif
f56e54
+
f56e54
+      break;
f56e54
+    default:
f56e54
+      gcc_unreachable ();
f56e54
+    }
f56e54
+}
f56e54
+
f56e54
 /* After all options at LOC have been read into OPTS and OPTS_SET,
f56e54
    finalize settings of those options and diagnose incompatible
f56e54
    combinations.  */
f56e54
@@ -1057,6 +1203,18 @@ finish_options (struct gcc_options *opts
f56e54
     sorry ("transactional memory is not supported with "
f56e54
 	   "%<-fsanitize=kernel-address%>");
f56e54
 
f56e54
+  /* Currently live patching is not support for LTO.  */
f56e54
+  if (opts->x_flag_live_patching && opts->x_flag_lto)
f56e54
+    sorry ("live patching is not supported with LTO");
f56e54
+
f56e54
+  /* Control IPA optimizations based on different -flive-patching level.  */
f56e54
+  if (opts->x_flag_live_patching)
f56e54
+    {
f56e54
+      control_options_for_live_patching (opts, opts_set,
f56e54
+					 opts->x_flag_live_patching,
f56e54
+					 loc);
f56e54
+    }
f56e54
+
f56e54
   /* Comes from final.c -- no real reason to change it.  */
f56e54
 #define MAX_CODE_ALIGN 16
f56e54
 #define MAX_CODE_ALIGN_VALUE (1 << MAX_CODE_ALIGN)
f56e54
--- /dev/null
f56e54
+++ gcc/testsuite/gcc.dg/live-patching-1.c
f56e54
@@ -0,0 +1,22 @@
f56e54
+/* { dg-do compile } */
f56e54
+/* { dg-options "-O2 -flive-patching=inline-only-static -fdump-ipa-inline" } */
f56e54
+
f56e54
+extern int sum, n, m;
f56e54
+
f56e54
+int foo (int a)
f56e54
+{
f56e54
+  return a + n;
f56e54
+}
f56e54
+
f56e54
+static int bar (int b)
f56e54
+{
f56e54
+  return b * m;
f56e54
+}
f56e54
+
f56e54
+int main()
f56e54
+{
f56e54
+  sum = foo (m) + bar (n); 
f56e54
+  return 0;
f56e54
+}
f56e54
+
f56e54
+/* { dg-final { scan-ipa-dump "foo/0 function has external linkage when the user requests only inlining static for live patching"  "inline" } } */
f56e54
--- /dev/null
f56e54
+++ gcc/testsuite/gcc.dg/live-patching-2.c
f56e54
@@ -0,0 +1,9 @@
f56e54
+/* { dg-do compile } */
f56e54
+/* { dg-options "-O2 -flive-patching -flto" } */
f56e54
+
f56e54
+int main()
f56e54
+{
f56e54
+  return 0;
f56e54
+}
f56e54
+
f56e54
+/* { dg-message "sorry, unimplemented: live patching is not supported with LTO" "-flive-patching and -flto together" { target *-*-* } 0 } */
f56e54
--- /dev/null
f56e54
+++ gcc/testsuite/gcc.dg/live-patching-3.c
f56e54
@@ -0,0 +1,9 @@
f56e54
+/* { dg-do compile } */
f56e54
+/* { dg-options "-O1 -flive-patching -fwhole-program" } */
f56e54
+
f56e54
+int main()
f56e54
+{
f56e54
+  return 0;
f56e54
+}
f56e54
+
f56e54
+/* { dg-message "'-fwhole-program' is incompatible with '-flive-patching=inline-only-static|inline-clone’" "" {target "*-*-*"} 0 } */