diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
index 876556c..e339d88 100644
--- a/gcc/ada/gcc-interface/utils.c
+++ b/gcc/ada/gcc-interface/utils.c
@@ -4646,6 +4646,9 @@ gnat_write_global_declarations (void)
      FIXME: shouldn't be the front end's responsibility to call this.  */
   cgraph_finalize_compilation_unit ();
 
+  if (flag_lto_slim)
+    return;
+
   /* Emit debug info for all global declarations.  */
   emit_debug_global_declarations (VEC_address (tree, global_decls),
 				  VEC_length (tree, global_decls));
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index e9d1f1d..103a724 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -1730,7 +1730,7 @@ ipa_passes (void)
   if (flag_generate_lto)
     targetm.asm_out.lto_end ();
 
-  if (!flag_ltrans)
+  if (!flag_ltrans && !flag_lto_slim)
     execute_ipa_pass_list (all_regular_ipa_passes);
   invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_END, NULL);
 
@@ -1775,6 +1775,17 @@ cgraph_optimize (void)
       return;
     }
 
+  if (flag_lto_slim)
+    {
+      if (!quiet_flag)
+	fprintf (stderr, "In slim LTO mode. Stopping output.\n");
+      timevar_pop (TV_CGRAPHOPT);
+      /* Release the trees here? Right now it doesn't matter because
+	 we exit soon. */
+      return;
+    }
+
+
   /* This pass remove bodies of extern inline functions we never inlined.
      Do this later so other IPA passes see what is really going on.  */
   cgraph_remove_unreachable_nodes (false, dump_file);
diff --git a/gcc/common.opt b/gcc/common.opt
index b0e40c1..37d2eff 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -1089,6 +1089,11 @@ flto-report
 Common Report Var(flag_lto_report) Init(0) Optimization
 Report various link-time optimization statistics
 
+flto-slim
+Common Report Var(flag_lto_slim) Init(0) Optimization
+Only generate LTO output, no assembler. This flag is ignored for the LTO
+frontend. Will only work with -fuse-linker-plugin.
+
 fmath-errno
 Common Report Var(flag_errno_math) Init(1) Optimization
 Set errno after built-in math functions
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index fcc83fb..ebac286 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -3934,8 +3934,9 @@ cp_write_global_declarations (void)
     {
       check_global_declarations (VEC_address (tree, pending_statics),
 				 VEC_length (tree, pending_statics));
-      emit_debug_global_declarations (VEC_address (tree, pending_statics),
-				      VEC_length (tree, pending_statics));
+      if (!flag_lto_slim)
+        emit_debug_global_declarations (VEC_address (tree, pending_statics),
+	  			        VEC_length (tree, pending_statics));
     }
 
   perform_deferred_noexcept_checks ();
@@ -3943,7 +3944,8 @@ cp_write_global_declarations (void)
   /* Generate hidden aliases for Java.  */
   if (candidates)
     {
-      build_java_method_aliases (candidates);
+      if (!flag_lto_slim)
+        build_java_method_aliases (candidates);
       pointer_set_destroy (candidates);
     }
 
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 776fdd0..33548b1 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -355,7 +355,7 @@ Objective-C and Objective-C++ Dialects}.
 -fivopts -fkeep-inline-functions -fkeep-static-consts @gol
 -floop-block -floop-flatten -floop-interchange -floop-strip-mine @gol
 -floop-parallelize-all -flto -flto-compression-level -flto-partition=@var{alg} @gol
--flto-report -fltrans -fltrans-output-list -fmerge-all-constants @gol
+-flto-report -flto-slim -fltrans -fltrans-output-list -fmerge-all-constants @gol
 -fmerge-constants -fmodulo-sched -fmodulo-sched-allow-regmoves @gol
 -fmove-loop-invariants fmudflap -fmudflapir -fmudflapth -fno-branch-count-reg @gol
 -fno-default-inline @gol
@@ -7655,6 +7655,14 @@ files in LTO mode (via @option{-fwhopr} or @option{-flto}).
 
 Disabled by default.
 
+@item -flto-slim
+Only generate LTO output, no assembler. The result is that the assembler
+code is only generated once for a LTO build. This flag is ignored for the LTO
+frontend. Will only work with the @option{-fuse-linker-plugin} and
+with the @command{gold} linker.
+
+Disabled by default
+
 @item -fuse-linker-plugin
 Enables the extraction of objects with GIMPLE bytecode information
 from library archives.  This option relies on features available only
diff --git a/gcc/langhooks.c b/gcc/langhooks.c
index 2217a24..1032ceb 100644
--- a/gcc/langhooks.c
+++ b/gcc/langhooks.c
@@ -323,9 +323,12 @@ write_global_declarations (void)
   for (i = 0, decl = globals; i < len; i++, decl = DECL_CHAIN (decl))
     vec[len - i - 1] = decl;
 
-  wrapup_global_declarations (vec, len);
+  if (!flag_lto_slim)
+    wrapup_global_declarations (vec, len);
   check_global_declarations (vec, len);
-  emit_debug_global_declarations (vec, len);
+
+  if (!flag_lto_slim)
+    emit_debug_global_declarations (vec, len);
 
   /* Clean up.  */
   free (vec);
diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c
index 3baea80..aec50ae 100644
--- a/gcc/lto/lto.c
+++ b/gcc/lto/lto.c
@@ -2424,6 +2424,9 @@ lto_main (int debug_p ATTRIBUTE_UNUSED)
 
   lto_init_reader ();
 
+  /* In LTO mode don't ever be slim */
+  flag_lto_slim = 0;
+
   /* Read all the symbols and call graph from all the files in the
      command line.  */
   read_cgraph_and_symbols (num_in_fnames, in_fnames);
diff --git a/gcc/toplev.c b/gcc/toplev.c
index a6c13f1..e9404de 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -930,8 +930,11 @@ compile_file (void)
   /* This must also call cgraph_finalize_compilation_unit.  */
   lang_hooks.decls.final_write_globals ();
 
-  if (seen_error ())
-    return;
+  if (seen_error () || flag_lto_slim)
+    {
+      invoke_plugin_callbacks (PLUGIN_FINISH_UNIT, NULL);
+      return;
+    }
 
   varpool_assemble_pending_decls ();
   finish_aliases_2 ();
