---
 gcc/cif-code.def                          |  6 ++++++
 gcc/common.opt                            |  4 ++++
 gcc/doc/invoke.texi                       | 10 +++++++++-
 gcc/ipa-inline.c                          |  6 ++++++
 gcc/testsuite/gcc.dg/inline_only_static.c | 22 ++++++++++++++++++++++
 5 files changed, 47 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/inline_only_static.c

diff --git a/gcc/cif-code.def b/gcc/cif-code.def
index 19a7621..64b2b1a 100644
--- a/gcc/cif-code.def
+++ b/gcc/cif-code.def
@@ -132,6 +132,12 @@ DEFCIFCODE(USES_COMDAT_LOCAL, CIF_FINAL_ERROR,
 DEFCIFCODE(ATTRIBUTE_MISMATCH, CIF_FINAL_ERROR,
 	   N_("function attribute mismatch"))
 
+/* We can't inline because the user requests only inlining static function 
+   but the function is external visible.  */
+DEFCIFCODE(FUNCTION_EXTERN, CIF_FINAL_ERROR,
+	   N_("function is external visible when the user requests only"
+	      " inlining static"))
+
 /* We proved that the call is unreachable.  */
 DEFCIFCODE(UNREACHABLE, CIF_FINAL_ERROR,
 	   N_("unreachable"))
diff --git a/gcc/common.opt b/gcc/common.opt
index ef6a630..9c66a56 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -1633,6 +1633,10 @@ finline-atomics
 Common Report Var(flag_inline_atomics) Init(1) Optimization
 Inline __atomic operations when a lock free instruction sequence is available.
 
+finline-only-static
+Common RejectNegative Var(flag_inline_only_static) Init(0) 
+Inline functions only when they are declared \"static\". 
+
 fcf-protection
 Common RejectNegative Alias(fcf-protection=,full)
 
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index ec12711..c2d9941 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -407,7 +407,8 @@ Objective-C and Objective-C++ Dialects}.
 -fgcse-sm  -fhoist-adjacent-loads  -fif-conversion @gol
 -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
+-finline-only-static @gol
+-finline-small-functions -fipa-cp  -fipa-cp-clone @gol
 -fipa-bit-cp -fipa-vrp @gol
 -fipa-pta  -fipa-profile  -fipa-pure-const  -fipa-reference  -fipa-icf @gol
 -fira-algorithm=@var{algorithm} @gol
@@ -8066,6 +8067,13 @@ having large chains of nested wrapper functions.
 
 Enabled by default.
 
+@item -finline-only-static
+@opindex finline-only-static
+By default, GCC inlines functions without considering whether they are static 
+or not. This flag guides inliner to only inline static functions. 
+
+Off by default.
+
 @item -fipa-sra
 @opindex fipa-sra
 Perform interprocedural scalar replacement of aggregates, removal of
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index 0257885..f432243 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -376,6 +376,12 @@ can_inline_edge_p (struct cgraph_edge *e, bool report,
       e->inline_failed = CIF_ATTRIBUTE_MISMATCH;
       inlinable = false;
     }
+  else if (callee->externally_visible 
+	   && flag_inline_only_static) 
+    {
+      e->inline_failed = CIF_FUNCTION_EXTERN;
+      inlinable = false;
+    }
   if (!inlinable && report)
     report_inline_failed_reason (e);
   return inlinable;
diff --git a/gcc/testsuite/gcc.dg/inline_only_static.c b/gcc/testsuite/gcc.dg/inline_only_static.c
new file mode 100644
index 0000000..70fd36c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/inline_only_static.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -finline-only-static -fdump-tree-einline" } */
+
+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-tree-dump "not inlinable: main/2 -> foo/0, function is external visible when the user requests only inlining static"  "einline" } } */
-- 
1.9.1
