Streaming of toplevel extended assembly was missing implementation.

gcc/ChangeLog:

        * lto-streamer-in.cc (lto_input_asm_ref): New.
        (lto_input_toplevel_asms): Input extended asm_node.
        * lto-streamer-out.cc (lto_output_asm_ref): New.
        (lto_is_streamable): Add ASM_EXPR.
        (lto_output_toplevel_asms): Output extended asm_node.
---
 gcc/lto-streamer-in.cc  | 17 +++++++++++++++--
 gcc/lto-streamer-out.cc | 37 ++++++++++++++++++++-----------------
 2 files changed, 35 insertions(+), 19 deletions(-)

diff --git a/gcc/lto-streamer-in.cc b/gcc/lto-streamer-in.cc
index 2efa1f33967..f89617da2fc 100644
--- a/gcc/lto-streamer-in.cc
+++ b/gcc/lto-streamer-in.cc
@@ -687,6 +687,18 @@ lto_input_fn_decl_ref (lto_input_block *ib, 
lto_file_decl_data *file_data)
   return result;
 }
 
+/* Read toplevel assembly reference to DATA from IB.  */
+
+tree
+lto_input_asm_ref (lto_input_block *ib, lto_file_decl_data *file_data)
+{
+  unsigned int ix_u = streamer_read_uhwi (ib);
+  tree result = (*file_data->current_decl_state
+                ->streams[LTO_DECL_STREAM])[ix_u];
+  gcc_assert (TREE_CODE (result) == STRING_CST
+             || TREE_CODE (result) == ASM_EXPR);
+  return result;
+}
 
 /* Read and return a double-linked list of catch handlers from input
    block IB, using descriptors in DATA_IN.  */
@@ -1987,7 +1999,6 @@ lto_input_toplevel_asms (struct lto_file_decl_data 
*file_data, int order_base)
     = (const struct lto_simple_header_with_strings *) data;
   int string_offset;
   class data_in *data_in;
-  tree str;
 
   if (! data)
     return;
@@ -2000,8 +2011,10 @@ lto_input_toplevel_asms (struct lto_file_decl_data 
*file_data, int order_base)
   data_in = lto_data_in_create (file_data, data + string_offset,
                              header->string_size, vNULL);
 
-  while ((str = streamer_read_string_cst (data_in, &ib)))
+  unsigned asm_count = streamer_read_uhwi (&ib);
+  for (unsigned i = 0; i < asm_count; i++)
     {
+      tree str = lto_input_asm_ref (&ib, file_data);
       asm_node *node = symtab->finalize_toplevel_asm (str);
       node->order = streamer_read_hwi (&ib) + order_base;
       node->lto_file_data = file_data;
diff --git a/gcc/lto-streamer-out.cc b/gcc/lto-streamer-out.cc
index d03c41f38e4..484fc22793d 100644
--- a/gcc/lto-streamer-out.cc
+++ b/gcc/lto-streamer-out.cc
@@ -364,6 +364,17 @@ lto_output_fn_decl_ref (struct lto_out_decl_state 
*decl_state,
      (obs, lto_get_index (&decl_state->streams[LTO_DECL_STREAM], decl));
 }
 
+/* Output toplevel assembly to OBS.  */
+
+void
+lto_output_asm_ref (struct lto_out_decl_state *decl_state,
+                   struct lto_output_stream * obs, tree decl)
+{
+  gcc_assert (TREE_CODE (decl) == STRING_CST || TREE_CODE (decl) == ASM_EXPR);
+  streamer_write_uhwi_stream
+     (obs, lto_get_index (&decl_state->streams[LTO_DECL_STREAM], decl));
+}
+
 /* Return true if EXPR is a tree node that can be written to disk.  */
 
 static inline bool
@@ -384,6 +395,7 @@ lto_is_streamable (tree expr)
         && code != STATEMENT_LIST
         && (code == CASE_LABEL_EXPR
             || code == DECL_EXPR
+            || code == ASM_EXPR
             || TREE_CODE_CLASS (code) != tcc_statement);
 }
 
@@ -2560,19 +2572,18 @@ lto_output_toplevel_asms (lto_symtab_encoder_t encoder)
   char *section_name;
   struct lto_simple_header_with_strings header;
 
-  bool any_asm = false;
+  unsigned asm_count = 0;
   for (int i = 0; i < lto_symtab_encoder_size (encoder); i++)
     if (is_a <asm_node*> (lto_symtab_encoder_deref (encoder, i)))
-      any_asm = true;
+      asm_count++;
 
-  if (!any_asm)
+  if (!asm_count)
     return;
 
   ob = create_output_block (LTO_section_asm);
 
-  /* Make string 0 be a NULL string.  */
-  streamer_write_char_stream (ob->string_stream, 0);
-
+  /* Stream the length.  */
+  streamer_write_uhwi (ob, asm_count);
   for (int i = 0; i < lto_symtab_encoder_size (encoder); i++)
     {
       toplevel_node *tnode = lto_symtab_encoder_deref (encoder, i);
@@ -2580,19 +2591,11 @@ lto_output_toplevel_asms (lto_symtab_encoder_t encoder)
       if (!anode)
        continue;
 
-      if (TREE_CODE (anode->asm_str) != STRING_CST)
-       {
-         sorry_at (EXPR_LOCATION (anode->asm_str),
-                   "LTO streaming of toplevel extended %<asm%> "
-                   "unimplemented");
-         continue;
-       }
-      streamer_write_string_cst (ob, ob->main_stream, anode->asm_str);
-      streamer_write_hwi (ob, anode->order);
+      int output_order = *encoder->order_remap->get (anode->order);
+      lto_output_asm_ref (ob->decl_state, ob->main_stream, anode->asm_str);
+      streamer_write_hwi (ob, output_order);
     }
 
-  streamer_write_string_cst (ob, ob->main_stream, NULL_TREE);
-
   section_name = lto_get_section_name (LTO_section_asm, NULL, 0, NULL);
   lto_begin_section (section_name, !flag_wpa);
   free (section_name);
-- 
2.51.1

Reply via email to