]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
lto: Bypass assembler when generating LTO object files.
authorRishi Raj <rishiraj45035@gmail.com>
Thu, 6 Jul 2023 13:13:51 +0000 (18:43 +0530)
committerRishi Raj <rishiraj45035@gmail.com>
Thu, 6 Jul 2023 13:13:51 +0000 (18:43 +0530)
    This patch applies Jan Hubicka previous patch on current sources.
    Now compiler is able to produce object files without assembler although
    a lot of things are missing such as __lto_slim symbol, debug symbols
    etc. They will be added in future patches. To test this current patch,
    use these command below.
    1) ./xgcc -B ./ -O3 a.c -flto -S -fbypass-asm=crtbegin.o  -o a.o
    2) ./xgcc -B ./ -O2 a.o -flto
    3)  ./a.out

    We are currntly working with elf-only support (mach-o, coff, xcoff etc
    will be dealt later) so this will only work on a linux machine. I have tested
    this on my machine ( Arch linux, Machine: Advanced Micro Devices X86-64) and
    all LTO test cases passed as expected.

    gcc/ChangeLog:

            * Makefile.in:
            * common.opt:
            * langhooks.cc (lhd_begin_section):
            (lhd_append_data):
            (lhd_end_section):
            * lto/lto-object.cc: Moved to...
            * lto-object.cc: ...here.
            * lto-streamer.h (struct lto_section_slot):
            (struct lto_section_list):
            (struct lto_file):
            (lto_obj_file_open):
            (lto_obj_file_close):
            (lto_obj_build_section_table):
            (lto_obj_create_section_hash_table):
            (lto_obj_begin_section):
            (lto_obj_append_data):
            (lto_obj_end_section):
            (lto_set_current_out_file):
            (lto_get_current_out_file):
            * toplev.cc (compile_file):
            (lang_dependent_init):

    gcc/lto/ChangeLog:

            * Make-lang.in:
            * lto-common.cc (lto_file_read):
            * lto-lang.cc:
            * lto.h (struct lto_file):
            (lto_obj_file_open):
            (lto_obj_file_close):
            (struct lto_section_list):
            (lto_obj_build_section_table):
            (lto_obj_create_section_hash_table):
            (lto_obj_begin_section):
            (lto_obj_append_data):
            (lto_obj_end_section):
            (lto_set_current_out_file):
            (lto_get_current_out_file):
            (struct lto_section_slot):

Signed-off-by: Rishi Raj <rishiraj45035@gmail.com>
gcc/Makefile.in
gcc/common.opt
gcc/langhooks.cc
gcc/lto-object.cc [moved from gcc/lto/lto-object.cc with 94% similarity]
gcc/lto-streamer.h
gcc/lto/Make-lang.in
gcc/lto/lto-common.cc
gcc/lto/lto-lang.cc
gcc/lto/lto.h
gcc/toplev.cc

index c478ec852013eae65b9f3ec0a443e023c7d8b452..c9ae222fb5955bd9a69fa888e28a511cf65d02c0 100644 (file)
@@ -1560,6 +1560,7 @@ OBJS = \
        lto-section-out.o \
        lto-opts.o \
        lto-compress.o \
+       lto-object.o \
        mcf.o \
        mode-switching.o \
        modulo-sched.o \
index 25f650e2dae465e859561b0ddc2b83b355388587..ba7a18ece8c170c2952d6a6e58c72b9855e2658b 100644 (file)
@@ -1169,6 +1169,9 @@ fbtr-bb-exclusive
 Common Ignore
 Does nothing.  Preserved for backward compatibility.
 
+fbypass-asm=
+Common Joined Var(flag_bypass_asm)
+
 fcallgraph-info
 Common RejectNegative Var(flag_callgraph_info) Init(NO_CALLGRAPH_INFO);
 Output callgraph information on a per-file basis.
index 9a1a9eccca9639531b57237015cfc2942efc1475..a76ed974d58bfa14c2df9d954d263bc8b011c129 100644 (file)
@@ -38,6 +38,10 @@ along with GCC; see the file COPYING3.  If not see
 #include "stor-layout.h"
 #include "cgraph.h"
 #include "debug.h"
+#include "function.h"
+#include "basic-block.h"
+#include "gimple.h"
+#include "lto-streamer.h"
 
 /* Do nothing; in many cases the default hook.  */
 
@@ -817,6 +821,19 @@ lhd_begin_section (const char *name)
 {
   section *section;
 
+  if (flag_bypass_asm)
+    {
+      static int initialized = false;
+      if (!initialized)
+       {
+         gcc_assert (asm_out_file == NULL);
+          lto_set_current_out_file (lto_obj_file_open (asm_file_name, true));
+         initialized = true;
+       }
+      lto_obj_begin_section (name);
+      return;
+    }
+
   /* Save the old section so we can restore it in lto_end_asm_section.  */
   gcc_assert (!saved_section);
   saved_section = in_section;
@@ -833,8 +850,13 @@ lhd_begin_section (const char *name)
    implementation just calls assemble_string.  */
 
 void
-lhd_append_data (const void *data, size_t len, void *)
+lhd_append_data (const void *data, size_t len, void *v)
 {
+  if (flag_bypass_asm)
+    {
+      lto_obj_append_data (data, len, v);
+      return;
+    }
   if (data)
     {
       timevar_push (TV_IPA_LTO_OUTPUT);
@@ -851,6 +873,11 @@ lhd_append_data (const void *data, size_t len, void *)
 void
 lhd_end_section (void)
 {
+  if (flag_bypass_asm)
+    {
+      lto_obj_end_section ();
+      return;
+    }
   if (saved_section)
     {
       switch_to_section (saved_section);
similarity index 94%
rename from gcc/lto/lto-object.cc
rename to gcc/lto-object.cc
index 965d31ed084ab9a7cbab075d8945bb2706497b12..cb1c3a6cfb3417efd935889f2399eaceef215095 100644 (file)
@@ -21,9 +21,17 @@ along with GCC; see the file COPYING3.  If not see
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
-#include "tm.h"
+#include "tree.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
+#include "function.h"
+#include "gimple.h"
 #include "diagnostic-core.h"
-#include "lto.h"
+#include "tm.h"
+#include "lto-streamer.h"
 #include "lto-section-names.h"
 #include "simple-object.h"
 
@@ -133,7 +141,13 @@ lto_obj_file_open (const char *filename, bool writable)
     }
   else
     {
-      gcc_assert (saved_attributes != NULL);
+      if (!saved_attributes)
+        {
+          lto_file *tmp = lto_obj_file_open (flag_bypass_asm, false);
+          if (!tmp)
+            goto fail;
+          lto_obj_file_close (tmp);
+        }
       lo->sobj_w = simple_object_start_write (saved_attributes,
                                              LTO_SEGMENT_NAME,
                                              &errmsg, &err);
@@ -148,7 +162,8 @@ fail_errmsg:
     error ("%s: %s", fname, errmsg);
   else
     error ("%s: %s: %s", fname, errmsg, xstrerror (err));
-                                        
+
+fail:
   if (lo->fd != -1)
     lto_obj_file_close ((lto_file *) lo);
   free (lo);
@@ -255,15 +270,15 @@ lto_obj_add_section (void *data, const char *name, off_t offset,
    the start and size of each section in the .o file.  */
 
 htab_t
-lto_obj_build_section_table (lto_file *lto_file, struct lto_section_list *list)
+lto_obj_build_section_table (lto_file *lto_file, struct lto_section_list *list,
+                             htab_t section_hash_table)
 {
   struct lto_simple_object *lo = (struct lto_simple_object *) lto_file;
-  htab_t section_hash_table;
+
   struct lto_obj_add_section_data loasd;
   const char *errmsg;
   int err;
 
-  section_hash_table = lto_obj_create_section_hash_table ();
 
   gcc_assert (lo->sobj_r != NULL && lo->sobj_w == NULL);
   loasd.section_hash_table = section_hash_table;
index 0556b34c837bdf12a09ea080ab715e707a8603d3..0c8e5d663e2c0ecda6a66e8ceaa73f360488a44c 100644 (file)
@@ -764,6 +764,30 @@ public:
   lto_location_cache location_cache;
 };
 
+/* Hash table entry to hold the start offset and length of an LTO
+   section in a .o file.  */
+struct lto_section_slot
+{
+  const char *name;
+  intptr_t start;
+  size_t len;
+  struct lto_section_slot *next;
+};
+
+/* A list of section slots */
+struct lto_section_list
+{
+  struct lto_section_slot *first, *last;
+};
+
+/* A file.  */
+struct lto_file
+{
+  /* The name of the file.  */
+  const char *filename;
+  /* The offset for the object inside an ar archive file (or zero).  */
+  off_t offset;
+};
 
 /* In lto-section-in.cc  */
 extern class lto_input_block * lto_create_simple_input_block (
@@ -903,6 +927,17 @@ void lto_output_location_and_block (struct output_block *, struct bitpack_d *,
 void lto_output_init_mode_table (void);
 void lto_prepare_function_for_streaming (cgraph_node *);
 
+/* In lto-elf.c or lto-coff.c  */
+extern lto_file *lto_obj_file_open (const char *filename, bool writable);
+extern void lto_obj_file_close (lto_file *file);
+struct lto_section_list;
+extern htab_t lto_obj_build_section_table (lto_file *file, struct lto_section_list *list, htab_t section_hash_table);
+extern htab_t lto_obj_create_section_hash_table (void);
+extern void lto_obj_begin_section (const char *name);
+extern void lto_obj_append_data (const void *data, size_t len, void *block);
+extern void lto_obj_end_section (void);
+extern lto_file *lto_set_current_out_file (lto_file *file);
+extern lto_file *lto_get_current_out_file (void);
 
 /* In lto-cgraph.cc  */
 extern bool asm_nodes_output;
index 98aa9f4cc39a1541ea98c89bb837964fe476de29..70144cea88e08fb4ce1016bcfc2c75b38c6b9670 100644 (file)
@@ -24,9 +24,9 @@ LTO_EXE = lto1$(exeext)
 LTO_DUMP_EXE = lto-dump$(exeext)
 LTO_DUMP_INSTALL_NAME := $(shell echo lto-dump|sed '$(program_transform_name)')
 # The LTO-specific object files inclued in $(LTO_EXE).
-LTO_OBJS = lto/lto-lang.o lto/lto.o lto/lto-object.o attribs.o lto/lto-partition.o lto/lto-symtab.o lto/lto-common.o
+LTO_OBJS = lto/lto-lang.o lto/lto.o attribs.o lto/lto-partition.o lto/lto-symtab.o lto/lto-common.o
 lto_OBJS = $(LTO_OBJS)
-LTO_DUMP_OBJS = lto/lto-lang.o lto/lto-object.o attribs.o lto/lto-partition.o lto/lto-symtab.o lto/lto-dump.o lto/lto-common.o
+LTO_DUMP_OBJS = lto/lto-lang.o attribs.o lto/lto-partition.o lto/lto-symtab.o lto/lto-dump.o lto/lto-common.o
 lto_dump_OBJS = $(LTO_DUMP_OBJS)
 
 # this is only useful in a LTO bootstrap, but this does not work right
index 703e665b698fd678566928389c1dc72eb4d135cc..1ec488aaf59150121460178233e59a266dc5fbcb 100644 (file)
@@ -2326,7 +2326,8 @@ lto_file_read (lto_file *file, FILE *resolution_file, int *count)
   struct lto_section_list section_list;
 
   memset (&section_list, 0, sizeof (struct lto_section_list));
-  section_hash_table = lto_obj_build_section_table (file, &section_list);
+  section_hash_table = lto_obj_create_section_hash_table ();
+  section_hash_table = lto_obj_build_section_table (file, &section_list, section_hash_table);
 
   /* Dump the details of LTO objects.  */
   if (flag_lto_dump_objects)
index 14d419c2013d4b9babe09cce2d0cd425e639cacf..cf33bf178c2c3ece45a628cfa86592d924dad2c0 100644 (file)
@@ -35,6 +35,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "lto-tree.h"
 #include "lto.h"
 #include "lto-common.h"
+#include "lto-streamer.h"
 #include "stringpool.h"
 #include "attribs.h"
 
index 810d6622688339da2fd2084eb748b7a45843ab45..4c3c84bf9b899ad165b7165a6930daecae27de2e 100644 (file)
@@ -21,16 +21,6 @@ along with GCC; see the file COPYING3.  If not see
 #ifndef LTO_H
 #define LTO_H
 
-
-/* A file.  */
-struct lto_file
-{
-  /* The name of the file.  */
-  const char *filename;
-  /* The offset for the object inside an ar archive file (or zero).  */
-  off_t offset;
-};
-
 /* In lto-lang.cc  */
 extern const char *resolution_file_name;
 
@@ -39,36 +29,8 @@ extern tree lto_eh_personality (void);
 extern void lto_main (void);
 extern void lto_read_all_file_options (void);
 
-/* In lto-elf.c or lto-coff.c  */
-extern lto_file *lto_obj_file_open (const char *filename, bool writable);
-extern void lto_obj_file_close (lto_file *file);
-struct lto_section_list;
-extern htab_t lto_obj_build_section_table (lto_file *file, struct lto_section_list *list);
-extern htab_t lto_obj_create_section_hash_table (void);
-extern void lto_obj_begin_section (const char *name);
-extern void lto_obj_append_data (const void *data, size_t len, void *block);
-extern void lto_obj_end_section (void);
-extern lto_file *lto_set_current_out_file (lto_file *file);
-extern lto_file *lto_get_current_out_file (void);
-
 extern int lto_link_dump_id, decl_merge_dump_id, partition_dump_id;
 
-/* Hash table entry to hold the start offset and length of an LTO
-   section in a .o file.  */
-struct lto_section_slot
-{
-  const char *name;
-  intptr_t start;
-  size_t len;
-  struct lto_section_slot *next;
-};
-
-/* A list of section slots */
-struct lto_section_list
-{
-  struct lto_section_slot *first, *last;
-};
-
 extern unsigned int lto_option_lang_mask (void);
 
 #endif /* LTO_H */
index 6c1a6f443c16f83f5e76127499a6a8956c79ab29..fec416336615fb59714ebf71b9bd9f104509f25e 100644 (file)
@@ -88,6 +88,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-modref.h"
 #include "ipa-param-manipulation.h"
 #include "dbgcnt.h"
+#include "lto-streamer.h"
 
 #include "selftest.h"
 
@@ -539,6 +540,12 @@ compile_file (void)
      even when user did not ask for it.  */
   if (flag_generate_lto && !flag_fat_lto_objects)
     {
+      if (flag_bypass_asm)
+        {
+          /* TODO  */
+        }
+      else
+        {
 #if defined ASM_OUTPUT_ALIGNED_DECL_COMMON
       ASM_OUTPUT_ALIGNED_DECL_COMMON (asm_out_file, NULL_TREE, "__gnu_lto_slim",
                                      HOST_WIDE_INT_1U, 8);
@@ -550,12 +557,13 @@ compile_file (void)
                         HOST_WIDE_INT_1U,
                         HOST_WIDE_INT_1U);
 #endif
+        }
     }
 
   /* Attach a special .ident directive to the end of the file to identify
      the version of GCC which compiled this code.  The format of the .ident
      string is patterned after the ones produced by native SVR4 compilers.  */
-  if (!flag_no_ident)
+  if (!flag_no_ident && !flag_bypass_asm)
     {
       const char *pkg_version = "(GNU) ";
       char *ident_str;
@@ -577,7 +585,11 @@ compile_file (void)
   /* This must be at the end.  Some target ports emit end of file directives
      into the assembly file here, and hence we cannot output anything to the
      assembly file after this point.  */
-  targetm.asm_out.file_end ();
+
+  if (flag_bypass_asm)
+    lto_obj_file_close (lto_get_current_out_file ());
+  else
+    targetm.asm_out.file_end ();
 
   timevar_stop (TV_PHASE_LATE_ASM);
 }
@@ -1819,7 +1831,8 @@ lang_dependent_init (const char *name)
 
   if (!flag_wpa)
     {
-      init_asm_output (name);
+      if (!flag_bypass_asm)
+        init_asm_output (name);
 
       if (!flag_generate_lto && !flag_compare_debug)
        {