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>
lto-section-out.o \
lto-opts.o \
lto-compress.o \
+ lto-object.o \
mcf.o \
mode-switching.o \
modulo-sched.o \
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.
#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. */
{
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;
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);
void
lhd_end_section (void)
{
+ if (flag_bypass_asm)
+ {
+ lto_obj_end_section ();
+ return;
+ }
if (saved_section)
{
switch_to_section (saved_section);
#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"
}
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);
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);
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;
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 (
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;
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
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)
#include "lto-tree.h"
#include "lto.h"
#include "lto-common.h"
+#include "lto-streamer.h"
#include "stringpool.h"
#include "attribs.h"
#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;
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 */
#include "ipa-modref.h"
#include "ipa-param-manipulation.h"
#include "dbgcnt.h"
+#include "lto-streamer.h"
#include "selftest.h"
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);
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;
/* 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);
}
if (!flag_wpa)
{
- init_asm_output (name);
+ if (!flag_bypass_asm)
+ init_asm_output (name);
if (!flag_generate_lto && !flag_compare_debug)
{