diff options
author | Rishi Raj <rishiraj45035@gmail.com> | 2023-07-06 18:43:51 +0530 |
---|---|---|
committer | Rishi Raj <rishiraj45035@gmail.com> | 2023-07-06 18:43:51 +0530 |
commit | b13c0682ab290166a4a4c25513fec96beab5e211 (patch) | |
tree | 5c158a13efc4f44cf1e2a821bb08477d1640c4a7 /gcc/lto | |
parent | acaa441a98bebc5216334557cf8d09d63087ce37 (diff) | |
download | gcc-b13c0682ab290166a4a4c25513fec96beab5e211.zip gcc-b13c0682ab290166a4a4c25513fec96beab5e211.tar.gz gcc-b13c0682ab290166a4a4c25513fec96beab5e211.tar.bz2 |
lto: Bypass assembler when generating LTO object files.
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>
Diffstat (limited to 'gcc/lto')
-rw-r--r-- | gcc/lto/Make-lang.in | 4 | ||||
-rw-r--r-- | gcc/lto/lto-common.cc | 3 | ||||
-rw-r--r-- | gcc/lto/lto-lang.cc | 1 | ||||
-rw-r--r-- | gcc/lto/lto-object.cc | 374 | ||||
-rw-r--r-- | gcc/lto/lto.h | 38 |
5 files changed, 5 insertions, 415 deletions
diff --git a/gcc/lto/Make-lang.in b/gcc/lto/Make-lang.in index 98aa9f4..70144ce 100644 --- a/gcc/lto/Make-lang.in +++ b/gcc/lto/Make-lang.in @@ -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 diff --git a/gcc/lto/lto-common.cc b/gcc/lto/lto-common.cc index 703e665..1ec488a 100644 --- a/gcc/lto/lto-common.cc +++ b/gcc/lto/lto-common.cc @@ -2326,7 +2326,8 @@ lto_file_read (lto_file *file, FILE *resolution_file, int *count) struct lto_section_list section_list; memset (§ion_list, 0, sizeof (struct lto_section_list)); - section_hash_table = lto_obj_build_section_table (file, §ion_list); + section_hash_table = lto_obj_create_section_hash_table (); + section_hash_table = lto_obj_build_section_table (file, §ion_list, section_hash_table); /* Dump the details of LTO objects. */ if (flag_lto_dump_objects) diff --git a/gcc/lto/lto-lang.cc b/gcc/lto/lto-lang.cc index 14d419c..cf33bf1 100644 --- a/gcc/lto/lto-lang.cc +++ b/gcc/lto/lto-lang.cc @@ -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" diff --git a/gcc/lto/lto-object.cc b/gcc/lto/lto-object.cc deleted file mode 100644 index 965d31e..0000000 --- a/gcc/lto/lto-object.cc +++ /dev/null @@ -1,374 +0,0 @@ -/* LTO routines to use object files. - Copyright (C) 2010-2023 Free Software Foundation, Inc. - Written by Ian Lance Taylor, Google. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -<http://www.gnu.org/licenses/>. */ - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "tm.h" -#include "diagnostic-core.h" -#include "lto.h" -#include "lto-section-names.h" -#include "simple-object.h" - -/* An LTO file wrapped around an simple_object. */ - -struct lto_simple_object -{ - /* The base information. */ - lto_file base; - - /* The system file descriptor. */ - int fd; - - /* The simple_object if we are reading the file. */ - simple_object_read *sobj_r; - - /* The simple_object if we are writing the file. */ - simple_object_write *sobj_w; - - /* The currently active section. */ - simple_object_write_section *section; -}; - -/* Saved simple_object attributes. FIXME: Once set, this is never - cleared. */ - -static simple_object_attributes *saved_attributes; - -/* Initialize FILE, an LTO file object for FILENAME. */ - -static void -lto_file_init (lto_file *file, const char *filename, off_t offset) -{ - file->filename = filename; - file->offset = offset; -} - -/* Open the file FILENAME. It WRITABLE is true, the file is opened - for write and, if necessary, created. Otherwise, the file is - opened for reading. Returns the opened file. */ - -lto_file * -lto_obj_file_open (const char *filename, bool writable) -{ - const char *offset_p; - long loffset; - int consumed; - char *fname; - off_t offset; - struct lto_simple_object *lo; - const char *errmsg; - int err; - - offset_p = strrchr (filename, '@'); - if (offset_p != NULL - && offset_p != filename - && sscanf (offset_p, "@%li%n", &loffset, &consumed) >= 1 - && strlen (offset_p) == (unsigned int) consumed) - { - fname = XNEWVEC (char, offset_p - filename + 1); - memcpy (fname, filename, offset_p - filename); - fname[offset_p - filename] = '\0'; - offset = (off_t) loffset; - } - else - { - fname = xstrdup (filename); - offset = 0; - } - - lo = XCNEW (struct lto_simple_object); - lto_file_init ((lto_file *) lo, fname, offset); - - lo->fd = open (fname, - (writable - ? O_WRONLY | O_CREAT | O_BINARY - : O_RDONLY | O_BINARY), - 0666); - if (lo->fd == -1) - fatal_error (input_location, "open %s failed: %s", fname, xstrerror (errno)); - - if (!writable) - { - simple_object_attributes *attrs; - - lo->sobj_r = simple_object_start_read (lo->fd, offset, LTO_SEGMENT_NAME, - &errmsg, &err); - if (lo->sobj_r == NULL) - goto fail_errmsg; - - attrs = simple_object_fetch_attributes (lo->sobj_r, &errmsg, &err); - if (attrs == NULL) - goto fail_errmsg; - - if (saved_attributes == NULL) - saved_attributes = attrs; - else - { - errmsg = simple_object_attributes_merge (saved_attributes, attrs, - &err); - if (errmsg != NULL) - { - free (attrs); - goto fail_errmsg; - } - } - } - else - { - gcc_assert (saved_attributes != NULL); - lo->sobj_w = simple_object_start_write (saved_attributes, - LTO_SEGMENT_NAME, - &errmsg, &err); - if (lo->sobj_w == NULL) - goto fail_errmsg; - } - - return &lo->base; - -fail_errmsg: - if (err == 0) - error ("%s: %s", fname, errmsg); - else - error ("%s: %s: %s", fname, errmsg, xstrerror (err)); - - if (lo->fd != -1) - lto_obj_file_close ((lto_file *) lo); - free (lo); - return NULL; -} - - -/* Close FILE. If FILE was opened for writing, it is written out - now. */ - -void -lto_obj_file_close (lto_file *file) -{ - struct lto_simple_object *lo = (struct lto_simple_object *) file; - - if (lo->sobj_r != NULL) - simple_object_release_read (lo->sobj_r); - else if (lo->sobj_w != NULL) - { - const char *errmsg; - int err; - - gcc_assert (lo->base.offset == 0); - - errmsg = simple_object_write_to_file (lo->sobj_w, lo->fd, &err); - if (errmsg != NULL) - { - if (err == 0) - fatal_error (input_location, "%s", errmsg); - else - fatal_error (input_location, "%s: %s", errmsg, xstrerror (err)); - } - - simple_object_release_write (lo->sobj_w); - } - - if (lo->fd != -1) - { - if (close (lo->fd) < 0) - fatal_error (input_location, "close: %s", xstrerror (errno)); - } -} - -/* This is passed to lto_obj_add_section. */ - -struct lto_obj_add_section_data -{ - /* The hash table of sections. */ - htab_t section_hash_table; - /* The offset of this file. */ - off_t base_offset; - /* List in linker order */ - struct lto_section_list *list; -}; - -/* This is called for each section in the file. */ - -static int -lto_obj_add_section (void *data, const char *name, off_t offset, - off_t length) -{ - struct lto_obj_add_section_data *loasd = - (struct lto_obj_add_section_data *) data; - htab_t section_hash_table = (htab_t) loasd->section_hash_table; - char *new_name; - struct lto_section_slot s_slot; - void **slot; - struct lto_section_list *list = loasd->list; - - if (strncmp (name, section_name_prefix, strlen (section_name_prefix))) - return 1; - - new_name = xstrdup (name); - s_slot.name = new_name; - slot = htab_find_slot (section_hash_table, &s_slot, INSERT); - if (*slot == NULL) - { - struct lto_section_slot *new_slot = XCNEW (struct lto_section_slot); - - new_slot->name = new_name; - new_slot->start = loasd->base_offset + offset; - new_slot->len = length; - *slot = new_slot; - - if (list != NULL) - { - if (!list->first) - list->first = new_slot; - if (list->last) - list->last->next = new_slot; - list->last = new_slot; - } - } - else - { - error ("two or more sections for %s", new_name); - return 0; - } - - return 1; -} - -/* Build a hash table whose key is the section name and whose data is - 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) -{ - 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; - loasd.base_offset = lo->base.offset; - loasd.list = list; - errmsg = simple_object_find_sections (lo->sobj_r, lto_obj_add_section, - &loasd, &err); - if (errmsg != NULL) - { - if (err == 0) - error ("%s", errmsg); - else - error ("%s: %s", errmsg, xstrerror (err)); - htab_delete (section_hash_table); - return NULL; - } - - return section_hash_table; -} - -/* The current output file. */ - -static lto_file *current_out_file; - -/* Set the current output file. Return the old one. */ - -lto_file * -lto_set_current_out_file (lto_file *file) -{ - lto_file *old_file; - - old_file = current_out_file; - current_out_file = file; - return old_file; -} - -/* Return the current output file. */ - -lto_file * -lto_get_current_out_file (void) -{ - return current_out_file; -} - -/* Begin writing a new section named NAME in the current output - file. */ - -void -lto_obj_begin_section (const char *name) -{ - struct lto_simple_object *lo; - int align; - const char *errmsg; - int err; - - lo = (struct lto_simple_object *) current_out_file; - gcc_assert (lo != NULL - && lo->sobj_r == NULL - && lo->sobj_w != NULL - && lo->section == NULL); - - align = ceil_log2 (POINTER_SIZE_UNITS); - lo->section = simple_object_write_create_section (lo->sobj_w, name, align, - &errmsg, &err); - if (lo->section == NULL) - { - if (err == 0) - fatal_error (input_location, "%s", errmsg); - else - fatal_error (input_location, "%s: %s", errmsg, xstrerror (errno)); - } -} - -/* Add data to a section. BLOCK is a pointer to memory containing - DATA. */ - -void -lto_obj_append_data (const void *data, size_t len, void *) -{ - struct lto_simple_object *lo; - const char *errmsg; - int err; - - lo = (struct lto_simple_object *) current_out_file; - gcc_assert (lo != NULL && lo->section != NULL); - - errmsg = simple_object_write_add_data (lo->sobj_w, lo->section, data, len, - 1, &err); - if (errmsg != NULL) - { - if (err == 0) - fatal_error (input_location, "%s", errmsg); - else - fatal_error (input_location, "%s: %s", errmsg, xstrerror (errno)); - } -} - -/* Stop writing to the current output section. */ - -void -lto_obj_end_section (void) -{ - struct lto_simple_object *lo; - - lo = (struct lto_simple_object *) current_out_file; - gcc_assert (lo != NULL && lo->section != NULL); - lo->section = NULL; -} diff --git a/gcc/lto/lto.h b/gcc/lto/lto.h index 810d662..4c3c84b 100644 --- a/gcc/lto/lto.h +++ b/gcc/lto/lto.h @@ -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 */ |