diff options
-rw-r--r-- | gcc/ChangeLog.lto | 34 | ||||
-rw-r--r-- | gcc/Makefile.in | 10 | ||||
-rw-r--r-- | gcc/lto-function-out.c | 536 | ||||
-rw-r--r-- | gcc/lto-section-out.c | 265 | ||||
-rw-r--r-- | gcc/lto-section-out.h | 78 | ||||
-rw-r--r-- | gcc/lto-tags.h | 2 | ||||
-rw-r--r-- | gcc/lto/ChangeLog | 24 | ||||
-rw-r--r-- | gcc/lto/Make-lang.in | 15 | ||||
-rw-r--r-- | gcc/lto/lto-function-in.c (renamed from gcc/lto/lto-read.c) | 441 | ||||
-rw-r--r-- | gcc/lto/lto-section-in.c | 266 | ||||
-rw-r--r-- | gcc/lto/lto-section-in.h | 42 |
11 files changed, 993 insertions, 720 deletions
diff --git a/gcc/ChangeLog.lto b/gcc/ChangeLog.lto index ba6f87c6790..f06ecb4a5dc 100644 --- a/gcc/ChangeLog.lto +++ b/gcc/ChangeLog.lto @@ -1,3 +1,36 @@ +<<<<<<< .mine +2008-01-14 Kenneth Zadeck <zadeck@naturalbridge.com> + * lto-function-out (lto_debug_context, output_stream, + LTO_SET_DEBUGGING_STREAM): Moved to lto_section_out.h. + (debug_out_fun): Renamed lto_debug_out_fun and moved to + lto_section_out.c. + (write_stream): Renamed lto_write_stream and moved to + lto_section_out.c. + (output_1_stream): Renamed lto_output_1_stream and moved to + lto_section_out.c. + (output_uleb128_stream): Renamed lto_output_uleb128 and moved to + lto_section_out.c. + (output_widest_uint_uleb128_stream): Renamed + lto_output_widest_uint_uleb128_stream and moved to + lto_section_out.c. + (output_sleb128_stream): Renamed lto_output_sleb128_stream and + moved to lto_section_out.c. + (output_string, output_decl_index, output_record_start, + output_constructor, output_expr_operand, output_local_vars, + output_local_vars_index, output_ssa_names, output_bb, produce_asm, + output_function, output_constructor_or_init): Renamed all calls as above. + (output_integer): Guts moved to lto_output_integer_stream. + (output_expr_operand, output_local_var, output_cfg, output_phi, + output_bb, output_function): + Added stmt_num parameter. + * lto-tags.h (lto_debug_context): Added. + * lto-section-out.c: New file that contains functions moved and + renamed from lto-function-out. + * lto-section-out.h: New file that contains declarations in + lto-section-out.c. + * Makefile.in (lto-section-out.o): New rule. + +======= 2008-01-07 Diego Novillo <dnovillo@google.com> http://gcc.gnu.org/ml/gcc-patches/2008-01/msg00263.html @@ -5,6 +38,7 @@ * dwarf2out.c (force_decl_die): Initialize SAVED_IGNORED_FLAG. * dwarf2.h (enum dwarf_type): Remove trailing comma. +>>>>>>> .r131525 2007-12-29 Nathan Froyd <froydnj@codesourcery.com> * collect2.c (scan_prog_file): Read all the output when reading diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 7506756c74f..86d9fc9e916 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1087,6 +1087,7 @@ OBJS-common = \ loop-unswitch.o \ lower-subreg.o \ lto-function-out.o \ + lto-section-out.o \ lto-stream-debug.o \ mode-switching.o \ modulo-sched.o \ @@ -1966,8 +1967,13 @@ lto-function-out.o : lto-function-out.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TM_H) toplev.h $(TREE_H) $(EXPR_H) $(FLAGS_H) $(PARAMS_H) input.h \ $(VARRAY_H) $(HASHTAB_H) langhooks.h $(BASIC_BLOCK_H) tree-iterator.h \ tree-pass.h tree-flow.h $(CGRAPH_H) $(FUNCTION_H) $(GGC_H) $(DIAGNOSTIC_H) \ - except.h debug.h $(TIMEVAR_H) $(LTO_TAGS_H) lto-tree-flags.def \ - lto-tree-tags.def output.h dwarf2asm.h dwarf2out.h + except.h debug.h $(TIMEVAR_H) $(LTO_TAGS_H) lto-tree-flags.def lto-tree-tags.def \ + lto-tags.h lto-section-out.h output.h dwarf2asm.h dwarf2out.h +lto-section-out.o : lto-section-out.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(TM_H) toplev.h $(TREE_H) $(EXPR_H) $(FLAGS_H) $(PARAMS_H) input.h \ + $(VARRAY_H) $(HASHTAB_H) langhooks.h $(BASIC_BLOCK_H) tree-iterator.h \ + tree-pass.h tree-flow.h $(CGRAPH_H) $(FUNCTION_H) $(GGC_H) $(DIAGNOSTIC_H) \ + except.h debug.h $(TIMEVAR_H) lto-section-out.h output.h dwarf2asm.h dwarf2out.h langhooks.o : langhooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TREE_H) toplev.h $(TREE_INLINE_H) $(RTL_H) insn-config.h $(INTEGRATE_H) \ langhooks.h $(LANGHOOKS_DEF_H) $(FLAGS_H) $(GGC_H) $(DIAGNOSTIC_H) intl.h \ diff --git a/gcc/lto-function-out.c b/gcc/lto-function-out.c index d13da808880..b99c1990eb7 100644 --- a/gcc/lto-function-out.c +++ b/gcc/lto-function-out.c @@ -51,6 +51,7 @@ Boston, MA 02110-1301, USA. */ #include "dwarf2out.h" #include "output.h" #include "lto-tags.h" +#include "lto-section-out.h" #include <ctype.h> @@ -59,9 +60,6 @@ sbitmap lto_types_needed_for; #ifdef LTO_STREAM_DEBUGGING const char *LTO_tag_names[LTO_last_tag]; - -static struct lto_debug_context lto_debug_context; -static void debug_out_fun (struct lto_debug_context *, char); #endif @@ -187,63 +185,38 @@ eq_string_slot_node (const void *p1, const void *p2) else return 0; } - -struct char_ptr_base -{ - char *ptr; -}; - -/* An incore byte stream to buffer the various parts of the -function. The entire structure should be zeroed when created. The -record consists of a set of blocks. The first sizeof (ptr) bytes are -used as a chain, and the rest store the bytes to be written. */ - -struct output_stream -{ - /* The pointer to the first block in the stream. */ - struct char_ptr_base * first_block; - /* The pointer to the last and current block in the stream. */ - struct char_ptr_base * current_block; - /* The pointer to where the next char should be written. */ - char * current_pointer; - /* The number of characters left in the current block. */ - unsigned int left_in_block; - /* The block size of the last block allocated. */ - unsigned int block_size; - /* The total number of characters written. */ - unsigned int total_size; -}; +/* The fields written to a function or extern variable header. */ struct output_block { /* The stream that the main tree codes are written to. */ - struct output_stream *main_stream; + struct lto_output_stream *main_stream; /* The stream that contains the indexes for the local name table. */ - struct output_stream *local_decl_index_stream; + struct lto_output_stream *local_decl_index_stream; /* The stream that contains the local name table. */ - struct output_stream *local_decl_stream; + struct lto_output_stream *local_decl_stream; /* The stream that contains the names for the named_labels. */ - struct output_stream *named_label_stream; + struct lto_output_stream *named_label_stream; /* The stream that contains the string table. */ - struct output_stream *string_stream; + struct lto_output_stream *string_stream; /* The stream that contains the ssa_names table. */ - struct output_stream *ssa_names_stream; + struct lto_output_stream *ssa_names_stream; /* The stream that contains the cfg. */ - struct output_stream *cfg_stream; + struct lto_output_stream *cfg_stream; #ifdef LTO_STREAM_DEBUGGING /* The stream that contains the local decls index debugging information. */ - struct output_stream *debug_decl_index_stream; + struct lto_output_stream *debug_decl_index_stream; /* The stream that contains the local decls debugging information. */ - struct output_stream *debug_decl_stream; + struct lto_output_stream *debug_decl_stream; /* The stream that contains the labels debugging information. */ - struct output_stream *debug_label_stream; + struct lto_output_stream *debug_label_stream; /* The stream that contains the ssa_names debugging information. */ - struct output_stream *debug_ssa_names_stream; + struct lto_output_stream *debug_ssa_names_stream; /* The stream that contains the cfg debugging information. */ - struct output_stream *debug_cfg_stream; + struct lto_output_stream *debug_cfg_stream; /* The stream that contains the gimple debugging information. */ - struct output_stream *debug_main_stream; + struct lto_output_stream *debug_main_stream; #endif /* The hash table that contains the set of labels we have seen so @@ -318,24 +291,7 @@ struct output_block /* The output stream that contains the abbrev table for all of the functions in this compilation unit. */ -static void output_expr_operand (struct output_block *, tree); - - -#ifdef LTO_STREAM_DEBUGGING -#define LTO_SET_DEBUGGING_STREAM(STREAM,CONTEXT) \ -do { \ - ob-> STREAM = xcalloc (1, sizeof (struct output_stream)); \ - lto_debug_context. CONTEXT = ob-> STREAM; \ - lto_debug_context.current_data = ob-> STREAM; \ - gcc_assert (lto_debug_context.indent == 0); \ -} while (0) -#define LTO_CLEAR_DEBUGGING_STREAM(STREAM) \ - free (ob-> STREAM) -#else -#define LTO_SET_DEBUGGING_STREAM(STREAM,CONTEXT) -#define LTO_CLEAR_DEBUGGING_STREAM(STREAM) (void)0 -#endif - +static void output_expr_operand (struct output_block *, tree, unsigned int); /* Clear the line info stored in DATA_IN. */ @@ -358,18 +314,18 @@ create_output_block (bool is_function) { struct output_block *ob = xcalloc (1, sizeof (struct output_block)); - ob->main_stream = xcalloc (1, sizeof (struct output_stream)); - ob->string_stream = xcalloc (1, sizeof (struct output_stream)); + ob->main_stream = xcalloc (1, sizeof (struct lto_output_stream)); + ob->string_stream = xcalloc (1, sizeof (struct lto_output_stream)); if (is_function) { - ob->local_decl_index_stream = xcalloc (1, sizeof (struct output_stream)); - ob->local_decl_stream = xcalloc (1, sizeof (struct output_stream)); - ob->named_label_stream = xcalloc (1, sizeof (struct output_stream)); - ob->ssa_names_stream = xcalloc (1, sizeof (struct output_stream)); - ob->cfg_stream = xcalloc (1, sizeof (struct output_stream)); + ob->local_decl_index_stream = xcalloc (1, sizeof (struct lto_output_stream)); + ob->local_decl_stream = xcalloc (1, sizeof (struct lto_output_stream)); + ob->named_label_stream = xcalloc (1, sizeof (struct lto_output_stream)); + ob->ssa_names_stream = xcalloc (1, sizeof (struct lto_output_stream)); + ob->cfg_stream = xcalloc (1, sizeof (struct lto_output_stream)); } #ifdef LTO_STREAM_DEBUGGING - lto_debug_context.out = debug_out_fun; + lto_debug_context.out = lto_debug_out_fun; lto_debug_context.indent = 0; #endif @@ -459,189 +415,6 @@ destroy_output_block (struct output_block * ob, bool is_function) free (ob); } -/* Write all of the chars in OBS to the assembler. Recycle the blocks - in obs as this is being done. */ - -static void -write_stream (struct output_stream *obs) -{ - unsigned int block_size = 1024; - unsigned int num_chars; - struct char_ptr_base *block; - if (!obs->first_block) - return; - - block = obs->first_block; - while (block) - { - const char *base = ((char *)block) + sizeof (struct char_ptr_base); - struct char_ptr_base *old_block = block; - block = (struct char_ptr_base *)block->ptr; - /* If there is a next block, then this one is full, if there is - not a next block, then the left_in_block field says how many - chars there are in this block. */ - num_chars = block_size - sizeof (struct char_ptr_base); - if (!block) - num_chars = num_chars - obs->left_in_block; - - assemble_string (base, num_chars); - free (old_block); - block_size *= 2; - } -} - - -/* Write a character to the output block. */ - -static void -output_1_stream (struct output_stream *obs, char c) -{ - /* No space left. */ - if (obs->left_in_block == 0) - { - struct char_ptr_base *new_block; - - if (obs->first_block == NULL) - { - /* This is the first time the stream has been written - into. */ - obs->block_size = 1024; - new_block = (struct char_ptr_base*) xmalloc (obs->block_size); - obs->first_block = new_block; - } - else - { - struct char_ptr_base *tptr; - /* Get a new block that is twice as big as the last block - and link it into the list. */ - obs->block_size *= 2; - new_block = (struct char_ptr_base*) xmalloc (obs->block_size); - /* The first bytes of the block are reserved as a pointer to - the next block. Set the chain of the full block to the - pointer to the new block. */ - tptr = obs->current_block; - tptr->ptr = (char *)new_block; - } - - /* Set the place for the next char at the first position after the - chain to the next block. */ - obs->current_pointer - = ((char *)new_block) + sizeof (struct char_ptr_base); - obs->current_block = new_block; - /* Null out the newly allocated block's pointer to the next block. */ - new_block->ptr = NULL; - obs->left_in_block = obs->block_size - sizeof (struct char_ptr_base); - } - - /* Write the actual character. */ - *obs->current_pointer = c; - obs->current_pointer++; - obs->total_size++; - obs->left_in_block--; -} - - -/* Write a zero to the output stream. */ - -static void -output_zero (struct output_block *ob) -{ - LTO_DEBUG_WIDE ("U", 0); - output_1_stream (ob->main_stream, 0); -} - - -/* Output an unsigned LEB128 quantity to OBS. */ - -static void -output_uleb128_stream (struct output_stream *obs, unsigned HOST_WIDE_INT work) -{ - LTO_DEBUG_WIDE ("U", work); - do - { - unsigned int byte = (work & 0x7f); - work >>= 7; - if (work != 0) - /* More bytes to follow. */ - byte |= 0x80; - - output_1_stream (obs, byte); - } - while (work != 0); -} - -/* Identical to output_uleb128_stream above except using unsigned - HOST_WIDEST_INT type. For efficiency on host where unsigned HOST_WIDEST_INT - is not native, we only use this if we know that HOST_WIDE_INT is not wide - enough. */ - -static void -output_widest_uint_uleb128_stream (struct output_stream *obs, - unsigned HOST_WIDEST_INT work) -{ - LTO_DEBUG_WIDE ("U", work); - do - { - unsigned int byte = (work & 0x7f); - work >>= 7; - if (work != 0) - /* More bytes to follow. */ - byte |= 0x80; - - output_1_stream (obs, byte); - } - while (work != 0); -} - - -/* Output an unsigned LEB128 quantity to OB->main_stream. */ - -static void -output_uleb128 (struct output_block *ob, unsigned HOST_WIDE_INT work) -{ - output_uleb128_stream (ob->main_stream, work); -} - -/* HOST_WIDEST_INT version of output_uleb128. OB and WORK are as in - output_uleb128. */ - -static void -output_widest_uint_uleb128 (struct output_block *ob, - unsigned HOST_WIDEST_INT work) -{ - output_widest_uint_uleb128_stream (ob->main_stream, work); -} - -/* Output a signed LEB128 quantity. */ - -static void -output_sleb128_stream (struct output_stream *obs, HOST_WIDE_INT work) -{ - int more, byte; - LTO_DEBUG_WIDE ("S", work); - do - { - byte = (work & 0x7f); - /* arithmetic shift */ - work >>= 7; - more = !((work == 0 && (byte & 0x40) == 0) - || (work == -1 && (byte & 0x40) != 0)); - if (more) - byte |= 0x80; - - output_1_stream (obs, byte); - } - while (more); -} - - -/* Output a signed LEB128 quantity to OB->main_stream. */ - -static void -output_sleb128 (struct output_block *ob, HOST_WIDE_INT work) -{ - output_sleb128_stream (ob->main_stream, work); -} /* Output STRING of LEN to the string table in OB. Then put the index @@ -649,7 +422,7 @@ output_sleb128 (struct output_block *ob, HOST_WIDE_INT work) static void output_string (struct output_block *ob, - struct output_stream *index_stream, + struct lto_output_stream *index_stream, const char *string, unsigned int len) { @@ -661,7 +434,7 @@ output_string (struct output_block *ob, slot = htab_find_slot (ob->string_hash_table, &s_slot, INSERT); if (*slot == NULL) { - struct output_stream *string_stream = ob->string_stream; + struct lto_output_stream *string_stream = ob->string_stream; unsigned int start = string_stream->total_size; struct string_slot *new_slot = xmalloc (sizeof (struct string_slot)); @@ -670,15 +443,15 @@ output_string (struct output_block *ob, new_slot->s = string; new_slot->slot_num = start; *slot = new_slot; - output_uleb128_stream (index_stream, start); - output_uleb128_stream (string_stream, len); + lto_output_uleb128_stream (index_stream, start); + lto_output_uleb128_stream (string_stream, len); for (i=0; i<len; i++) - output_1_stream (string_stream, string[i]); + lto_output_1_stream (string_stream, string[i]); } else { struct string_slot *old_slot = (struct string_slot *)*slot; - output_uleb128_stream (index_stream, old_slot->slot_num); + lto_output_uleb128_stream (index_stream, old_slot->slot_num); /* From the debugging protocol's point of view, the entry needs to look the same reguardless of whether this is the first @@ -705,53 +478,51 @@ output_real (struct output_block *ob, tree t) } -/* Put out a integer constant. These are stored as two HOST_WIDE_INTS - so games may have to be played to shift the data from the high to - the low value. */ +/* Write a zero to the output stream. */ static void -output_integer (struct output_block *ob, tree t) +output_zero (struct output_block *ob) { - struct output_stream *obs = ob->main_stream; - HOST_WIDE_INT low = TREE_INT_CST_LOW (t); - HOST_WIDE_INT high = TREE_INT_CST_HIGH (t); - int more, byte; - - /* Of course if the high value is just sign bits for the signed low - value, we can just punt and call output_sleb128 and be done with - it. */ - if (((high == -1) && (low < 0)) - || ((high == 0) && (low >= 0))) - { - output_sleb128_stream (obs, low); - return; - } + LTO_DEBUG_WIDE ("U", 0); + lto_output_1_stream (ob->main_stream, 0); +} - LTO_DEBUG_INTEGER ("SS", high, low); - /* This is just a copy of the output_sleb128 code with extra - operations to transfer the low 7 bits of the high value to the - top 7 bits of the low value, shift the high down by 7 and then do - a slightly more complex exit test. */ - do - { - unsigned HOST_WIDE_INT transfer = (high & 0x7f); - high = ((unsigned HOST_WIDE_INT) high) >> 7; - transfer <<= (HOST_BITS_PER_WIDE_INT - 7); +/* Output an unsigned LEB128 quantity to OB->main_stream. */ - byte = (low & 0x7f); +static void +output_uleb128 (struct output_block *ob, unsigned HOST_WIDE_INT work) +{ + lto_output_uleb128_stream (ob->main_stream, work); +} - /* Logical shift. */ - low = ((unsigned HOST_WIDE_INT) low) >> 7; - low |= transfer; - more = !((high == 0 && low == 0 && (byte & 0x40) == 0) - || (high == -1 && low == -1 && (byte & 0x40) != 0)); - if (more) - byte |= 0x80; - output_1_stream (obs, byte); - } - while (more); +/* Output a signed LEB128 quantity to OB->main_stream. */ + +static void +output_sleb128 (struct output_block *ob, HOST_WIDE_INT work) +{ + lto_output_sleb128_stream (ob->main_stream, work); +} + +/* HOST_WIDEST_INT version of output_uleb128. OB and WORK are as in + output_uleb128. */ + +static void +output_widest_uint_uleb128 (struct output_block *ob, + unsigned HOST_WIDEST_INT work) +{ + lto_output_widest_uint_uleb128_stream (ob->main_stream, work); +} + +/* Put out a integer constant. These are stored as two HOST_WIDE_INTS + so games may have to be played to shift the data from the high to + the low value. */ + +static void +output_integer (struct output_block *ob, tree t) +{ + lto_output_integer_stream (ob->main_stream, t); } @@ -763,7 +534,7 @@ output_integer (struct output_block *ob, tree t) If OBS is NULL, the only action is to add NAME to the table. */ static bool -output_decl_index (struct output_stream * obs, htab_t table, +output_decl_index (struct lto_output_stream * obs, htab_t table, unsigned int *next_index, tree name, unsigned int *this_index) { @@ -782,7 +553,7 @@ output_decl_index (struct output_stream * obs, htab_t table, *this_index = index; *slot = new_slot; if (obs) - output_uleb128_stream (obs, index); + lto_output_uleb128_stream (obs, index); return true; } else @@ -790,7 +561,7 @@ output_decl_index (struct output_stream * obs, htab_t table, struct decl_slot *old_slot = (struct decl_slot *)*slot; *this_index = old_slot->slot_num; if (obs) - output_uleb128_stream (obs, old_slot->slot_num); + lto_output_uleb128_stream (obs, old_slot->slot_num); return false; } } @@ -1055,7 +826,7 @@ static void output_record_start (struct output_block *ob, tree expr, tree value, unsigned int tag) { - output_1_stream (ob->main_stream, tag); + lto_output_1_stream (ob->main_stream, tag); LTO_DEBUG_INDENT (tag); if (expr) { @@ -1248,7 +1019,7 @@ output_constructor (struct output_block *ob, tree ctor) FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), idx, purpose, value) { if (purpose) - output_expr_operand (ob, purpose); + output_expr_operand (ob, purpose, 0); else output_zero (ob); @@ -1258,14 +1029,14 @@ output_constructor (struct output_block *ob, tree ctor) LTO_DEBUG_UNDENT (); } else - output_expr_operand (ob, value); + output_expr_operand (ob, value, 0); } } /* Output EXPR to the main stream in OB. */ static void -output_expr_operand (struct output_block *ob, tree expr) +output_expr_operand (struct output_block *ob, tree expr, unsigned int stmt_num) { enum tree_code code; enum tree_code_class class; @@ -1373,9 +1144,9 @@ output_expr_operand (struct output_block *ob, tree expr) LTO_case_label_expr0 + variant); if (CASE_LOW (expr) != NULL_TREE) - output_expr_operand (ob, CASE_LOW (expr)); + output_expr_operand (ob, CASE_LOW (expr), stmt_num); if (CASE_HIGH (expr) != NULL_TREE) - output_expr_operand (ob, CASE_HIGH (expr)); + output_expr_operand (ob, CASE_HIGH (expr), stmt_num); output_label_ref (ob, CASE_LABEL (expr)); } break; @@ -1473,14 +1244,14 @@ output_expr_operand (struct output_block *ob, tree expr) if (TREE_OPERAND (expr, 1)) { output_record_start (ob, expr, expr, LTO_cond_expr0); - output_expr_operand (ob, TREE_OPERAND (expr, 0)); - output_expr_operand (ob, TREE_OPERAND (expr, 1)); - output_expr_operand (ob, TREE_OPERAND (expr, 2)); + output_expr_operand (ob, TREE_OPERAND (expr, 0), stmt_num); + output_expr_operand (ob, TREE_OPERAND (expr, 1), stmt_num); + output_expr_operand (ob, TREE_OPERAND (expr, 2), stmt_num); } else { output_record_start (ob, expr, expr, LTO_cond_expr1); - output_expr_operand (ob, TREE_OPERAND (expr, 0)); + output_expr_operand (ob, TREE_OPERAND (expr, 0), stmt_num); } break; @@ -1490,8 +1261,8 @@ output_expr_operand (struct output_block *ob, tree expr) case COMPONENT_REF: output_record_start (ob, expr, expr, tag); - output_expr_operand (ob, TREE_OPERAND (expr, 0)); - output_expr_operand (ob, TREE_OPERAND (expr, 1)); + output_expr_operand (ob, TREE_OPERAND (expr, 0), stmt_num); + output_expr_operand (ob, TREE_OPERAND (expr, 1), stmt_num); /* Ignore 3 because it can be recomputed. */ break; @@ -1505,16 +1276,16 @@ output_expr_operand (struct output_block *ob, tree expr) { output_record_start (ob, expr, expr, LTO_call_expr1); output_uleb128 (ob, count); - output_expr_operand (ob, TREE_OPERAND (expr, 2)); + output_expr_operand (ob, TREE_OPERAND (expr, 2), stmt_num); } else { output_record_start (ob, expr, expr, LTO_call_expr0); output_uleb128 (ob, count); } - output_expr_operand (ob, TREE_OPERAND (expr, 1)); + output_expr_operand (ob, TREE_OPERAND (expr, 1), stmt_num); for (i = 3; i < count; i++) - output_expr_operand (ob, TREE_OPERAND (expr, i)); + output_expr_operand (ob, TREE_OPERAND (expr, i), stmt_num); } break; @@ -1529,15 +1300,15 @@ output_expr_operand (struct output_block *ob, tree expr) LTO_bit_field_ref1); output_uleb128 (ob, TREE_INT_CST_LOW (op1)); output_uleb128 (ob, TREE_INT_CST_LOW (op2)); - output_expr_operand (ob, TREE_OPERAND (expr, 0)); + output_expr_operand (ob, TREE_OPERAND (expr, 0), stmt_num); } else { output_record_start (ob, expr, expr, LTO_bit_field_ref0); - output_expr_operand (ob, TREE_OPERAND (expr, 0)); - output_expr_operand (ob, op1); - output_expr_operand (ob, op2); + output_expr_operand (ob, TREE_OPERAND (expr, 0), stmt_num); + output_expr_operand (ob, op1, stmt_num); + output_expr_operand (ob, op2, stmt_num); } } break; @@ -1547,8 +1318,8 @@ output_expr_operand (struct output_block *ob, tree expr) /* Ignore operands 2 and 3 for ARRAY_REF and ARRAY_RANGE REF because they can be recomputed. */ output_record_start (ob, expr, expr, tag); - output_expr_operand (ob, TREE_OPERAND (expr, 0)); - output_expr_operand (ob, TREE_OPERAND (expr, 1)); + output_expr_operand (ob, TREE_OPERAND (expr, 0), stmt_num); + output_expr_operand (ob, TREE_OPERAND (expr, 1), stmt_num); break; @@ -1560,17 +1331,17 @@ output_expr_operand (struct output_block *ob, tree expr) TREE_STRING_POINTER (string_cst), TREE_STRING_LENGTH (string_cst)); if (ASM_INPUTS (expr)) - output_expr_operand (ob, ASM_INPUTS (expr)); + output_expr_operand (ob, ASM_INPUTS (expr), stmt_num); else output_zero (ob); if (ASM_OUTPUTS (expr)) - output_expr_operand (ob, ASM_OUTPUTS (expr)); + output_expr_operand (ob, ASM_OUTPUTS (expr), stmt_num); else output_zero (ob); if (ASM_CLOBBERS (expr)) - output_expr_operand (ob, ASM_CLOBBERS (expr)); + output_expr_operand (ob, ASM_CLOBBERS (expr), stmt_num); else output_zero (ob); } @@ -1606,8 +1377,8 @@ output_expr_operand (struct output_block *ob, tree expr) /* Form return a = b; */ output_record_start (ob, expr, expr, LTO_return_expr2); - output_expr_operand (ob, TREE_OPERAND (t, 0)); - output_expr_operand (ob, TREE_OPERAND (t, 1)); + output_expr_operand (ob, TREE_OPERAND (t, 0), stmt_num); + output_expr_operand (ob, TREE_OPERAND (t, 1), stmt_num); } else { @@ -1622,15 +1393,15 @@ output_expr_operand (struct output_block *ob, tree expr) if (t == DECL_RESULT (current_function_decl)) output_zero (ob); else - output_expr_operand (ob, t); + output_expr_operand (ob, t, stmt_num); } } break; case GIMPLE_MODIFY_STMT: output_record_start (ob, expr, NULL, tag); - output_expr_operand (ob, GIMPLE_STMT_OPERAND (expr, 0)); - output_expr_operand (ob, GIMPLE_STMT_OPERAND (expr, 1)); + output_expr_operand (ob, GIMPLE_STMT_OPERAND (expr, 0), stmt_num); + output_expr_operand (ob, GIMPLE_STMT_OPERAND (expr, 1), stmt_num); break; case SWITCH_EXPR: @@ -1640,11 +1411,11 @@ output_expr_operand (struct output_block *ob, tree expr) size_t i; output_record_start (ob, expr, expr, tag); output_uleb128 (ob, len); - output_expr_operand (ob, TREE_OPERAND (expr, 0)); + output_expr_operand (ob, TREE_OPERAND (expr, 0), stmt_num); gcc_assert (TREE_OPERAND (expr, 1) == NULL); for (i = 0; i < len; ++i) - output_expr_operand (ob, TREE_VEC_ELT (label_vec, i)); + output_expr_operand (ob, TREE_VEC_ELT (label_vec, i), stmt_num); } break; @@ -1662,12 +1433,12 @@ output_expr_operand (struct output_block *ob, tree expr) for (tl = expr; tl; tl = TREE_CHAIN (tl)) { if (TREE_VALUE (tl) != NULL_TREE) - output_expr_operand (ob, TREE_VALUE (tl)); + output_expr_operand (ob, TREE_VALUE (tl), stmt_num); else output_zero (ob); if (TREE_PURPOSE (tl)) - output_expr_operand (ob, TREE_PURPOSE (tl)); + output_expr_operand (ob, TREE_PURPOSE (tl), stmt_num); else output_zero (ob); } @@ -1688,7 +1459,7 @@ output_expr_operand (struct output_block *ob, tree expr) #undef SET_NAME output_record_start (ob, expr, expr, tag); for (i = 0; i < TREE_CODE_LENGTH (TREE_CODE (expr)); i++) - output_expr_operand (ob, TREE_OPERAND (expr, i)); + output_expr_operand (ob, TREE_OPERAND (expr, i), stmt_num); break; } @@ -1772,7 +1543,7 @@ output_local_var (struct output_block *ob, int index) { LTO_DEBUG_INDENT_TOKEN ("init"); if (DECL_INITIAL (decl)) - output_expr_operand (ob, DECL_INITIAL (decl)); + output_expr_operand (ob, DECL_INITIAL (decl), 0); else output_zero (ob); /* Index in unexpanded_vars_list. */ @@ -1785,7 +1556,7 @@ output_local_var (struct output_block *ob, int index) /* The chain is only necessary for parm_decls. */ LTO_DEBUG_TOKEN ("chain"); if (TREE_CHAIN (decl)) - output_expr_operand (ob, TREE_CHAIN (decl)); + output_expr_operand (ob, TREE_CHAIN (decl), 0); else output_zero (ob); } @@ -1795,7 +1566,7 @@ output_local_var (struct output_block *ob, int index) LTO_DEBUG_TOKEN ("context"); if (DECL_CONTEXT (decl)) - output_expr_operand (ob, DECL_CONTEXT (decl)); + output_expr_operand (ob, DECL_CONTEXT (decl), 0); else output_zero (ob); @@ -1804,18 +1575,18 @@ output_local_var (struct output_block *ob, int index) /* Put out the subtrees. */ LTO_DEBUG_TOKEN ("size"); - output_expr_operand (ob, DECL_SIZE (decl)); + output_expr_operand (ob, DECL_SIZE (decl), 0); if (DECL_ATTRIBUTES (decl)!= NULL_TREE) { LTO_DEBUG_TOKEN ("attributes"); - output_expr_operand (ob, DECL_ATTRIBUTES (decl)); + output_expr_operand (ob, DECL_ATTRIBUTES (decl), 0); } if (DECL_SIZE_UNIT (decl) != NULL_TREE) - output_expr_operand (ob, DECL_SIZE_UNIT (decl)); + output_expr_operand (ob, DECL_SIZE_UNIT (decl), 0); if (needs_backing_var) - output_expr_operand (ob, DECL_DEBUG_EXPR (decl)); + output_expr_operand (ob, DECL_DEBUG_EXPR (decl), 0); if (DECL_ABSTRACT_ORIGIN (decl) != NULL_TREE) - output_expr_operand (ob, DECL_ABSTRACT_ORIGIN (decl)); + output_expr_operand (ob, DECL_ABSTRACT_ORIGIN (decl), 0); LTO_DEBUG_UNDENT(); } @@ -1829,7 +1600,7 @@ output_local_vars (struct output_block *ob, struct function *fn) unsigned int index = 0; tree t; int i = 0; - struct output_stream *tmp_stream = ob->main_stream; + struct lto_output_stream *tmp_stream = ob->main_stream; bitmap local_statics = BITMAP_ALLOC (NULL); ob->main_stream = ob->local_decl_stream; @@ -1853,7 +1624,7 @@ output_local_vars (struct output_block *ob, struct function *fn) if (!bitmap_bit_p (local_statics, DECL_UID (lv))) { bitmap_set_bit (local_statics, DECL_UID (lv)); - output_expr_operand (ob, lv); + output_expr_operand (ob, lv, 0); if (DECL_CONTEXT (lv) == fn->decl) { output_uleb128 (ob, 1); /* Restore context. */ @@ -1863,7 +1634,7 @@ output_local_vars (struct output_block *ob, struct function *fn) output_zero (ob); /* Restore context. */ } if (DECL_INITIAL (lv)) - output_expr_operand (ob, DECL_INITIAL (lv)); + output_expr_operand (ob, DECL_INITIAL (lv), 0); else output_zero (ob); /* DECL_INITIAL. */ } @@ -1905,7 +1676,7 @@ output_local_vars_index (struct output_block *ob) unsigned int index = 0; unsigned int stop; - struct output_stream *tmp_stream = ob->main_stream; + struct lto_output_stream *tmp_stream = ob->main_stream; ob->main_stream = ob->local_decl_index_stream; stop = VEC_length (int, ob->local_decls_index); @@ -1946,7 +1717,7 @@ output_ssa_names (struct output_block *ob, struct function *fn) { /* Switch streams so we can use output_expr_operand to write the SSA_NAME_VAR. */ - struct output_stream *tmp_stream = ob->main_stream; + struct lto_output_stream *tmp_stream = ob->main_stream; unsigned int i; unsigned int len = VEC_length (tree, SSANAMES (fn)); @@ -1961,7 +1732,7 @@ output_ssa_names (struct output_block *ob, struct function *fn) continue; output_uleb128 (ob, i); - output_expr_operand (ob, SSA_NAME_VAR (ptr)); + output_expr_operand (ob, SSA_NAME_VAR (ptr), 0); /* Use code 0 to force flags to be output. */ output_tree_flags (ob, 0, ptr, false); } @@ -1976,7 +1747,7 @@ output_ssa_names (struct output_block *ob, struct function *fn) static void output_cfg (struct output_block *ob, struct function *fn) { - struct output_stream *tmp_stream = ob->main_stream; + struct lto_output_stream *tmp_stream = ob->main_stream; basic_block bb; ob->main_stream = ob->cfg_stream; @@ -2025,7 +1796,7 @@ output_cfg (struct output_block *ob, struct function *fn) /* Output a phi function to the main stream in OB. */ static void -output_phi (struct output_block *ob, tree expr) +output_phi (struct output_block *ob, tree expr, unsigned int stmt_num) { int len = PHI_NUM_ARGS (expr); int i; @@ -2035,7 +1806,7 @@ output_phi (struct output_block *ob, tree expr) for (i = 0; i < len; i++) { - output_expr_operand (ob, PHI_ARG_DEF (expr, i)); + output_expr_operand (ob, PHI_ARG_DEF (expr, i), stmt_num); output_uleb128 (ob, PHI_ARG_EDGE (expr, i)->src->index); } LTO_DEBUG_UNDENT (); @@ -2044,8 +1815,9 @@ output_phi (struct output_block *ob, tree expr) /* Output a basic block BB to the main stream in OB for this FN. */ -static void -output_bb (struct output_block *ob, basic_block bb, struct function *fn) +static int +output_bb (struct output_block *ob, basic_block bb, + struct function *fn, int stmt_num) { block_stmt_iterator bsi = bsi_start (bb); @@ -2068,7 +1840,9 @@ output_bb (struct output_block *ob, basic_block bb, struct function *fn) tree stmt = bsi_stmt (bsi); LTO_DEBUG_INDENT_TOKEN ("stmt"); - output_expr_operand (ob, stmt); + output_uleb128 (ob, stmt_num); + + output_expr_operand (ob, stmt, stmt_num); /* We only need to set the region number of the tree that could throw if the region number is different from the @@ -2086,6 +1860,7 @@ output_bb (struct output_block *ob, basic_block bb, struct function *fn) last_eh_region_seen = region; } } + stmt_num++; } LTO_DEBUG_INDENT_TOKEN ("stmt"); @@ -2094,7 +1869,9 @@ output_bb (struct output_block *ob, basic_block bb, struct function *fn) for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi)) { LTO_DEBUG_INDENT_TOKEN ("phi"); - output_phi (ob, phi); + output_uleb128 (ob, stmt_num); + output_phi (ob, phi, stmt_num); + stmt_num++; } LTO_DEBUG_INDENT_TOKEN ("phi"); @@ -2106,6 +1883,7 @@ output_bb (struct output_block *ob, basic_block bb, struct function *fn) #ifdef LTO_STREAM_DEBUGGING gcc_assert (lto_debug_context.indent == 1); #endif + return stmt_num; } /* Write the references for the objects in V to section SEC in the @@ -2215,24 +1993,24 @@ produce_asm (struct output_block *ob, tree t, bool is_function) block of text. */ if (is_function) { - write_stream (ob->named_label_stream); - write_stream (ob->ssa_names_stream); - write_stream (ob->cfg_stream); - write_stream (ob->local_decl_index_stream); - write_stream (ob->local_decl_stream); + lto_write_stream (ob->named_label_stream); + lto_write_stream (ob->ssa_names_stream); + lto_write_stream (ob->cfg_stream); + lto_write_stream (ob->local_decl_index_stream); + lto_write_stream (ob->local_decl_stream); } - write_stream (ob->main_stream); - write_stream (ob->string_stream); + lto_write_stream (ob->main_stream); + lto_write_stream (ob->string_stream); #ifdef LTO_STREAM_DEBUGGING if (is_function) { - write_stream (ob->debug_decl_index_stream); - write_stream (ob->debug_decl_stream); - write_stream (ob->debug_label_stream); - write_stream (ob->debug_ssa_names_stream); - write_stream (ob->debug_cfg_stream); + lto_write_stream (ob->debug_decl_index_stream); + lto_write_stream (ob->debug_decl_stream); + lto_write_stream (ob->debug_label_stream); + lto_write_stream (ob->debug_ssa_names_stream); + lto_write_stream (ob->debug_cfg_stream); } - write_stream (ob->debug_main_stream); + lto_write_stream (ob->debug_main_stream); #endif } @@ -2356,6 +2134,7 @@ output_function (tree function) struct function *fn = DECL_STRUCT_FUNCTION (function); basic_block bb; struct output_block *ob = create_output_block (true); + unsigned int stmt_num = 1; LTO_SET_DEBUGGING_STREAM (debug_main_stream, main_data); clear_line_info (ob); @@ -2370,7 +2149,7 @@ output_function (tree function) generate_early_dwarf_information (function); /* Make string 0 be a NULL string. */ - output_1_stream (ob->string_stream, 0); + lto_output_1_stream (ob->string_stream, 0); last_eh_region_seen = 0; @@ -2382,19 +2161,19 @@ output_function (tree function) /* Output the head of the arguments list. */ LTO_DEBUG_INDENT_TOKEN ("decl_arguments"); if (DECL_ARGUMENTS (function)) - output_expr_operand (ob, DECL_ARGUMENTS (function)); + output_expr_operand (ob, DECL_ARGUMENTS (function), 0); else output_zero (ob); LTO_DEBUG_INDENT_TOKEN ("decl_context"); if (DECL_CONTEXT (function)) - output_expr_operand (ob, DECL_CONTEXT (function)); + output_expr_operand (ob, DECL_CONTEXT (function), 0); else output_zero (ob); /* Output the code for the function. */ FOR_ALL_BB_FN (bb, fn) - output_bb (ob, bb, fn); + stmt_num = output_bb (ob, bb, fn, stmt_num); /* The terminator for this function. */ output_zero (ob); @@ -2438,10 +2217,10 @@ output_constructor_or_init (tree var) clear_line_info (ob); /* Make string 0 be a NULL string. */ - output_1_stream (ob->string_stream, 0); + lto_output_1_stream (ob->string_stream, 0); LTO_DEBUG_INDENT_TOKEN ("init"); - output_expr_operand (ob, DECL_INITIAL (var)); + output_expr_operand (ob, DECL_INITIAL (var), 0); /* The terminator for the constructor. */ output_zero (ob); @@ -2518,17 +2297,6 @@ struct tree_opt_pass pass_ipa_lto_out = #ifdef LTO_STREAM_DEBUGGING - -/* The low level output routine to print a single character to the - debugging stream. */ - -static void -debug_out_fun (struct lto_debug_context *context, char c) -{ - struct output_stream * stream - = (struct output_stream *)context->current_data; - output_1_stream (stream, c); -} /* Print the tree flags to the debugging stream. */ void diff --git a/gcc/lto-section-out.c b/gcc/lto-section-out.c new file mode 100644 index 00000000000..33d9e2372bd --- /dev/null +++ b/gcc/lto-section-out.c @@ -0,0 +1,265 @@ +/* LTO output code. + Copyright (C) 2007, 2008 Free Software Foundation, Inc. + Contributed by Kenneth Zadeck <zadeck@naturalbridge.com> + +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 "toplev.h" +#include "tree.h" +#include "expr.h" +#include "flags.h" +#include "params.h" +#include "input.h" +#include "varray.h" +#include "hashtab.h" +#include "langhooks.h" +#include "basic-block.h" +#include "tree-iterator.h" +#include "tree-pass.h" +#include "tree-flow.h" +#include "cgraph.h" +#include "function.h" +#include "ggc.h" +#include "diagnostic.h" +#include "except.h" +#include "debug.h" +#include "vec.h" +#include "tree-vectorizer.h" +#include "timevar.h" +#include "dwarf2asm.h" +#include "dwarf2out.h" +#include "output.h" +#include "lto-tags.h" +#include "lto-section-out.h" +#include <ctype.h> + +/* Write all of the chars in OBS to the assembler. Recycle the blocks + in obs as this is being done. */ + +void +lto_write_stream (struct lto_output_stream *obs) +{ + unsigned int block_size = 1024; + unsigned int num_chars; + struct lto_char_ptr_base *block; + if (!obs->first_block) + return; + + block = obs->first_block; + while (block) + { + const char *base = ((char *)block) + sizeof (struct lto_char_ptr_base); + struct lto_char_ptr_base *old_block = block; + block = (struct lto_char_ptr_base *)block->ptr; + /* If there is a next block, then this one is full, if there is + not a next block, then the left_in_block field says how many + chars there are in this block. */ + num_chars = block_size - sizeof (struct lto_char_ptr_base); + if (!block) + num_chars = num_chars - obs->left_in_block; + + assemble_string (base, num_chars); + free (old_block); + block_size *= 2; + } +} + + +/* Write a character to the output block. */ + +void +lto_output_1_stream (struct lto_output_stream *obs, char c) +{ + /* No space left. */ + if (obs->left_in_block == 0) + { + struct lto_char_ptr_base *new_block; + + if (obs->first_block == NULL) + { + /* This is the first time the stream has been written + into. */ + obs->block_size = 1024; + new_block = (struct lto_char_ptr_base*) xmalloc (obs->block_size); + obs->first_block = new_block; + } + else + { + struct lto_char_ptr_base *tptr; + /* Get a new block that is twice as big as the last block + and link it into the list. */ + obs->block_size *= 2; + new_block = (struct lto_char_ptr_base*) xmalloc (obs->block_size); + /* The first bytes of the block are reserved as a pointer to + the next block. Set the chain of the full block to the + pointer to the new block. */ + tptr = obs->current_block; + tptr->ptr = (char *)new_block; + } + + /* Set the place for the next char at the first position after the + chain to the next block. */ + obs->current_pointer + = ((char *)new_block) + sizeof (struct lto_char_ptr_base); + obs->current_block = new_block; + /* Null out the newly allocated block's pointer to the next block. */ + new_block->ptr = NULL; + obs->left_in_block = obs->block_size - sizeof (struct lto_char_ptr_base); + } + + /* Write the actual character. */ + *obs->current_pointer = c; + obs->current_pointer++; + obs->total_size++; + obs->left_in_block--; +} + + +/* Output an unsigned LEB128 quantity to OBS. */ + +void +lto_output_uleb128_stream (struct lto_output_stream *obs, unsigned HOST_WIDE_INT work) +{ + LTO_DEBUG_WIDE ("U", work); + do + { + unsigned int byte = (work & 0x7f); + work >>= 7; + if (work != 0) + /* More bytes to follow. */ + byte |= 0x80; + + lto_output_1_stream (obs, byte); + } + while (work != 0); +} + +/* Identical to output_uleb128_stream above except using unsigned + HOST_WIDEST_INT type. For efficiency on host where unsigned HOST_WIDEST_INT + is not native, we only use this if we know that HOST_WIDE_INT is not wide + enough. */ + +void +lto_output_widest_uint_uleb128_stream (struct lto_output_stream *obs, + unsigned HOST_WIDEST_INT work) +{ + LTO_DEBUG_WIDE ("U", work); + do + { + unsigned int byte = (work & 0x7f); + work >>= 7; + if (work != 0) + /* More bytes to follow. */ + byte |= 0x80; + + lto_output_1_stream (obs, byte); + } + while (work != 0); +} + + +/* Output a signed LEB128 quantity. */ + +void +lto_output_sleb128_stream (struct lto_output_stream *obs, HOST_WIDE_INT work) +{ + int more, byte; + LTO_DEBUG_WIDE ("S", work); + do + { + byte = (work & 0x7f); + /* arithmetic shift */ + work >>= 7; + more = !((work == 0 && (byte & 0x40) == 0) + || (work == -1 && (byte & 0x40) != 0)); + if (more) + byte |= 0x80; + + lto_output_1_stream (obs, byte); + } + while (more); +} + + +/* Put out a integer constant. These are stored as two HOST_WIDE_INTS + so games may have to be played to shift the data from the high to + the low value. */ + +void +lto_output_integer_stream (struct lto_output_stream *obs, tree t) +{ + HOST_WIDE_INT low = TREE_INT_CST_LOW (t); + HOST_WIDE_INT high = TREE_INT_CST_HIGH (t); + int more, byte; + + /* Of course if the high value is just sign bits for the signed low + value, we can just punt and call lto_output_sleb128 and be done with + it. */ + if (((high == -1) && (low < 0)) + || ((high == 0) && (low >= 0))) + { + lto_output_sleb128_stream (obs, low); + return; + } + + LTO_DEBUG_INTEGER ("SS", high, low); + + /* This is just a copy of the lto_output_sleb128 code with extra + operations to transfer the low 7 bits of the high value to the + top 7 bits of the low value, shift the high down by 7 and then do + a slightly more complex exit test. */ + do + { + unsigned HOST_WIDE_INT transfer = (high & 0x7f); + high = ((unsigned HOST_WIDE_INT) high) >> 7; + transfer <<= (HOST_BITS_PER_WIDE_INT - 7); + + byte = (low & 0x7f); + + /* Logical shift. */ + low = ((unsigned HOST_WIDE_INT) low) >> 7; + low |= transfer; + more = !((high == 0 && low == 0 && (byte & 0x40) == 0) + || (high == -1 && low == -1 && (byte & 0x40) != 0)); + if (more) + byte |= 0x80; + + lto_output_1_stream (obs, byte); + } + while (more); +} + +#ifdef LTO_STREAM_DEBUGGING + +struct lto_debug_context lto_debug_context; + +/* The low level output routine to print a single character to the + debugging stream. */ + +void +lto_debug_out_fun (struct lto_debug_context *context, char c) +{ + struct lto_output_stream * stream + = (struct lto_output_stream *)context->current_data; + lto_output_1_stream (stream, c); +} + +#endif diff --git a/gcc/lto-section-out.h b/gcc/lto-section-out.h new file mode 100644 index 00000000000..4bc4d814c4d --- /dev/null +++ b/gcc/lto-section-out.h @@ -0,0 +1,78 @@ +/* LTO output code. + Copyright (C) 2007, 2008 Free Software Foundation, Inc. + Contributed by Kenneth Zadeck <zadeck@naturalbridge.com> + +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/>. */ + +#ifndef GCC_LTO_SECTION_OUT_H +#define GCC_LTO_SECTION_OUT_H + +#ifdef LTO_STREAM_DEBUGGING +void lto_debug_out_fun (struct lto_debug_context *, char); +#endif + +struct lto_char_ptr_base +{ + char *ptr; +}; + +/* An incore byte stream to buffer the various parts of the +function. The entire structure should be zeroed when created. The +record consists of a set of blocks. The first sizeof (ptr) bytes are +used as a chain, and the rest store the bytes to be written. */ + +struct lto_output_stream +{ + /* The pointer to the first block in the stream. */ + struct lto_char_ptr_base * first_block; + /* The pointer to the last and current block in the stream. */ + struct lto_char_ptr_base * current_block; + /* The pointer to where the next char should be written. */ + char * current_pointer; + /* The number of characters left in the current block. */ + unsigned int left_in_block; + /* The block size of the last block allocated. */ + unsigned int block_size; + /* The total number of characters written. */ + unsigned int total_size; +}; + +#ifdef LTO_STREAM_DEBUGGING +#define LTO_SET_DEBUGGING_STREAM(STREAM,CONTEXT) \ +do { \ + ob-> STREAM = xcalloc (1, sizeof (struct lto_output_stream)); \ + lto_debug_context. CONTEXT = ob-> STREAM; \ + lto_debug_context.current_data = ob-> STREAM; \ + gcc_assert (lto_debug_context.indent == 0); \ +} while (0) +#define LTO_CLEAR_DEBUGGING_STREAM(STREAM) \ + free (ob-> STREAM) +#else +#define LTO_SET_DEBUGGING_STREAM(STREAM,CONTEXT) +#define LTO_CLEAR_DEBUGGING_STREAM(STREAM) (void)0 +#endif + + +void lto_write_stream (struct lto_output_stream *); +void lto_output_1_stream (struct lto_output_stream *, char); +void lto_output_uleb128_stream (struct lto_output_stream *, unsigned HOST_WIDE_INT); +void lto_output_widest_uint_uleb128_stream (struct lto_output_stream *, + unsigned HOST_WIDEST_INT); +void lto_output_sleb128_stream (struct lto_output_stream *, HOST_WIDE_INT); +void lto_output_integer_stream (struct lto_output_stream *, tree); + +#endif /* GCC_LTO_SECTION_OUT_H */ diff --git a/gcc/lto-tags.h b/gcc/lto-tags.h index 36f4a1ec533..52f6c1b2a0e 100644 --- a/gcc/lto-tags.h +++ b/gcc/lto-tags.h @@ -526,6 +526,8 @@ struct lto_debug_context void * main_data; }; +extern struct lto_debug_context lto_debug_context; + /* The VAR_DECL tree code has more than 32 bits in flags. On some hosts, HOST_WIDE_INT is not wide enough. */ typedef unsigned HOST_WIDEST_INT lto_flags_type; diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog index 69612f0ec39..957ce09bd8e 100644 --- a/gcc/lto/ChangeLog +++ b/gcc/lto/ChangeLog @@ -1,3 +1,27 @@ +2008-01-14 Kenneth Zadeck <zadeck@naturalbridge.com> + + * lto-read.c: Renamed to lto-function-in.c. + (input_1_unsigned): Moved to lto-section-in.c and renamed + lto_input_1_unsigned. + (input_uleb128): Moved to lto-section-in.c and renamed + lto_input_uleb128. + (input_widest_uint_uleb128): Moved to lto-section-in.c and renamed + lto_input_widest_uint_uleb128. + (input_sleb128): Moved to lto-section-in.c and renamed + lto_input_sleb128. + (input_integer): Moved to lto-section-in.c and renamed + lto_input_integer. + (debug_in_fun): Moved to lto-section-in.c and renamed + lto_debug_in_fun. + (input_block): Moved to lto-section-in.h and renamed + lto_input_block. + (input_expr_operand): Fixed to allow lists with more than one + element. + * lto-section-in.h: New file. + * lto-section-in.c: New file with changes from above. + * Make-lang.in (lto-read.o): Renamed lto-function-in.c. + (lto-section-in.o): New rule. + 2007-12-29 Nathan Froyd <froydnj@codesourcery.com> * lto-read.c (input_expr_operand): Mark static and external diff --git a/gcc/lto/Make-lang.in b/gcc/lto/Make-lang.in index c062337cd63..9ecfa8cf043 100644 --- a/gcc/lto/Make-lang.in +++ b/gcc/lto/Make-lang.in @@ -26,8 +26,8 @@ # The name of the LTO compiler. LTO_EXE = lto1$(exeext) # The LTO-specific object files inclued in $(LTO_EXE). -LTO_OBJS = lto/lto-lang.o lto/lto.o lto/lto-elf.o lto/lto-read.o \ - lto/lto-symtab.o attribs.o +LTO_OBJS = lto/lto-lang.o lto/lto.o lto/lto-elf.o lto/lto-function-in.o \ + lto/lto-section-in.o lto/lto-symtab.o attribs.o LTO_H = lto/lto.h $(HASHTAB_H) $(TREE_H) ######################################################################## @@ -86,10 +86,17 @@ lto/lto-elf.o: lto/lto-elf.c $(CONFIG_H) coretypes.h $(SYSTEM_H) \ toplev.h $(LTO_H) $(LTO_TAGS_H) $(TM_H) lto/lto-symtab.o: lto/lto-symtab.c $(CONFIG_H) coretypes.h \ $(SYSTEM_H) toplev.h $(LTO_H) lto/lto-tree.h -lto/lto-read.o: lto/lto-read.c $(CONFIG_H) $(SYSTEM_H) \ +lto/lto-function-in.o: lto/lto-function-in.c $(CONFIG_H) $(SYSTEM_H) \ coretypes.h $(TM_H) toplev.h $(LTO_H) $(EXPR_H) $(FLAGS_H) \ $(PARAMS_H) input.h $(VARRAY_H) $(HASHTAB_H) langhooks.h \ $(BASIC_BLOCK_H) tree-iterator.h tree-pass.h tree-flow.h \ $(CGRAPH_H) $(FUNCTION_H) $(GGC_H) $(DIAGNOSTIC_H) \ except.h debug.h $(TIMEVAR_H) $(LTO_TAGS_H) lto-tree-flags.def \ - lto-tree-tags.def output.h dwarf2asm.h dwarf2out.h + lto-tree-tags.def lto/lto-section-in.h output.h dwarf2asm.h dwarf2out.h +lto/lto-section-in.o: lto/lto-section-in.c $(CONFIG_H) $(SYSTEM_H) \ + coretypes.h $(TM_H) toplev.h $(LTO_H) $(EXPR_H) $(FLAGS_H) \ + $(PARAMS_H) input.h $(VARRAY_H) $(HASHTAB_H) langhooks.h \ + $(BASIC_BLOCK_H) tree-iterator.h tree-pass.h tree-flow.h \ + $(CGRAPH_H) $(FUNCTION_H) $(GGC_H) $(DIAGNOSTIC_H) \ + except.h debug.h $(TIMEVAR_H) $(LTO_TAGS_H) lto-tree-flags.def \ + lto-tree-tags.def lto/lto-section-in.h output.h dwarf2asm.h dwarf2out.h diff --git a/gcc/lto/lto-read.c b/gcc/lto/lto-function-in.c index 4b3a1ce4eb7..e7f00ded12d 100644 --- a/gcc/lto/lto-read.c +++ b/gcc/lto/lto-function-in.c @@ -1,7 +1,7 @@ /* Read the gimple representation of a function and it's local variables from the memory mapped representation of a a .o file. - Copyright 2006 Free Software Foundation, Inc. + Copyright 2006, 2007, 2008 Free Software Foundation, Inc. Contributed by Kenneth Zadeck <zadeck@naturalbridge.com> This file is part of GCC. @@ -51,6 +51,7 @@ Boston, MA 02110-1301, USA. */ #include "output.h" #include "lto-tags.h" #include "lto.h" +#include "lto-section-in.h" #include <ctype.h> #include "cpplib.h" @@ -124,117 +125,25 @@ eq_string_slot_node (const void *p1, const void *p2) /* The table to hold the file_names. */ static htab_t file_name_hash_table; -struct input_block -{ - const char *data; - unsigned int p; - unsigned int len; -}; - - -#ifdef LTO_STREAM_DEBUGGING -static struct lto_debug_context lto_debug_context; -static void debug_out_fun (struct lto_debug_context *, char); -static void dump_debug_stream (struct input_block *, char, char); -#endif - static tree -input_expr_operand (struct input_block *, struct data_in *, struct function *, +input_expr_operand (struct lto_input_block *, struct data_in *, struct function *, enum LTO_tags); static tree -input_local_var (struct input_block *, struct data_in *, struct function *, unsigned int i); +input_local_var (struct lto_input_block *, struct data_in *, struct function *, unsigned int i); /* Return the next character of input from IB. Abort if you overrun. */ -static unsigned char -input_1_unsigned (struct input_block *ib) -{ - gcc_assert (ib->p < ib->len); - return (ib->data[ib->p++]); -} - - -/* Read an ULEB128 Number of IB. */ - -static unsigned HOST_WIDE_INT -input_uleb128 (struct input_block *ib) -{ - unsigned HOST_WIDE_INT result = 0; - int shift = 0; - unsigned HOST_WIDE_INT byte; - - while (true) - { - byte = input_1_unsigned (ib); - result |= (byte & 0x7f) << shift; - shift += 7; - if ((byte & 0x80) == 0) - { - LTO_DEBUG_WIDE ("U", result); - return result; - } - } -} - -/* HOST_WIDEST_INT version of input_uleb128. IB is as in input_uleb128. */ - -static unsigned HOST_WIDEST_INT -input_widest_uint_uleb128 (struct input_block *ib) -{ - unsigned HOST_WIDEST_INT result = 0; - int shift = 0; - unsigned HOST_WIDEST_INT byte; - - while (true) - { - byte = input_1_unsigned (ib); - result |= (byte & 0x7f) << shift; - shift += 7; - if ((byte & 0x80) == 0) - { - LTO_DEBUG_WIDE ("U", result); - return result; - } - } -} - -/* Read an SLEB128 Number of IB. */ - -static HOST_WIDE_INT -input_sleb128 (struct input_block *ib) -{ - HOST_WIDE_INT result = 0; - int shift = 0; - unsigned HOST_WIDE_INT byte; - - while (true) - { - byte = input_1_unsigned (ib); - result |= (byte & 0x7f) << shift; - shift += 7; - if ((byte & 0x80) == 0) - { - if ((shift < HOST_BITS_PER_WIDE_INT) && (byte & 0x40)) - result |= - ((HOST_WIDE_INT)1 << shift); - - LTO_DEBUG_WIDE ("S", result); - return result; - } - } -} - - /* Read the string at LOC from the string table in DATA_IN. */ static const char * input_string_internal (struct data_in *data_in, unsigned int loc, unsigned int *rlen) { - struct input_block str_tab + struct lto_input_block str_tab = {data_in->strings, loc, data_in->strings_len}; - unsigned int len = input_uleb128 (&str_tab); + unsigned int len = lto_input_uleb128 (&str_tab); const char * result; *rlen = len; @@ -260,7 +169,7 @@ input_string (struct data_in *data_in, unsigned int loc) /* Input a real constant of TYPE at LOC. */ static tree -input_real (struct input_block *ib, struct data_in *data_in, tree type) +input_real (struct lto_input_block *ib, struct data_in *data_in, tree type) { unsigned int loc; unsigned int len; @@ -269,7 +178,7 @@ input_real (struct input_block *ib, struct data_in *data_in, tree type) static char buffer[1000]; LTO_DEBUG_TOKEN ("real"); - loc = input_uleb128 (ib); + loc = lto_input_uleb128 (ib); str = input_string_internal (data_in, loc, &len); /* Copy over to make sure real_from_string doesn't see peculiar trailing characters in the exponent. */ @@ -280,67 +189,12 @@ input_real (struct input_block *ib, struct data_in *data_in, tree type) } -/* Input the next integer constant of TYPE in IB. */ - -static tree -input_integer (struct input_block *ib, tree type) -{ - HOST_WIDE_INT low = 0; - HOST_WIDE_INT high = 0; - int shift = 0; - unsigned HOST_WIDE_INT byte; - - while (true) - { - byte = input_1_unsigned (ib); - if (shift < HOST_BITS_PER_WIDE_INT - 7) - /* Working on the low part. */ - low |= (byte & 0x7f) << shift; - else if (shift >= HOST_BITS_PER_WIDE_INT) - /* Working on the high part. */ - high |= (byte & 0x7f) << (shift - HOST_BITS_PER_WIDE_INT); - else - { - /* Working on the transition between the low and high parts. */ - low |= (byte & 0x7f) << shift; - high |= (byte & 0x7f) >> (HOST_BITS_PER_WIDE_INT - shift); - } - - shift += 7; - if ((byte & 0x80) == 0) - { - if (byte & 0x40) - { - /* The number is negative. */ - if (shift < HOST_BITS_PER_WIDE_INT) - { - low |= - ((HOST_WIDE_INT)1 << shift); - high = -1; - } - else if (shift < (2 * HOST_BITS_PER_WIDE_INT)) - high |= - ((HOST_WIDE_INT)1 << (shift - HOST_BITS_PER_WIDE_INT)); - } - -#ifdef LTO_STREAM_DEBUGGING - /* Have to match the quick out in the lto writer. */ - if (((high == -1) && (low < 0)) - || ((high == 0) && (low >= 0))) - LTO_DEBUG_WIDE ("S", low); - else - LTO_DEBUG_INTEGER ("SS", high, low); -#endif - return build_int_cst_wide (type, low, high); - } - } -} - - /* Return the next tag in the input block IB. */ static enum LTO_tags -input_record_start (struct input_block *ib) +input_record_start (struct lto_input_block *ib) { - enum LTO_tags tag = input_1_unsigned (ib); + enum LTO_tags tag = lto_input_1_unsigned (ib); #ifdef LTO_STREAM_DEBUGGING if (tag) @@ -355,9 +209,9 @@ input_record_start (struct input_block *ib) /* Get the label referenced by the next token in IB. */ static tree -get_label_decl (struct data_in *data_in, struct input_block *ib) +get_label_decl (struct data_in *data_in, struct lto_input_block *ib) { - int index = input_sleb128 (ib); + int index = lto_input_sleb128 (ib); if (index >= 0) return data_in->labels[index]; else @@ -368,12 +222,12 @@ get_label_decl (struct data_in *data_in, struct input_block *ib) /* Get the type referenced by the next token in IB. */ static tree -input_type_ref (struct data_in *data_in, struct input_block *ib) +input_type_ref (struct data_in *data_in, struct lto_input_block *ib) { int index; LTO_DEBUG_TOKEN ("type"); - index = input_uleb128 (ib); + index = lto_input_uleb128 (ib); return data_in->types[index]; } @@ -384,14 +238,14 @@ input_type_ref (struct data_in *data_in, struct input_block *ib) /* Read the tree flags for CODE from IB. */ static lto_flags_type -input_tree_flags (struct input_block *ib, enum tree_code code, bool force) +input_tree_flags (struct lto_input_block *ib, enum tree_code code, bool force) { lto_flags_type flags; if (force || TEST_BIT (lto_flags_needed_for, code)) { LTO_DEBUG_TOKEN ("flags"); - flags = input_widest_uint_uleb128 (ib); + flags = lto_input_widest_uint_uleb128 (ib); LTO_DEBUG_TREE_FLAGS (code, flags); } else @@ -501,7 +355,7 @@ canon_file_name (const char *string) fields in DATA_IN. */ static bool -input_line_info (struct input_block *ib, struct data_in *data_in, +input_line_info (struct lto_input_block *ib, struct data_in *data_in, lto_flags_type flags) { #ifdef USE_MAPPED_LOCATION @@ -513,12 +367,12 @@ input_line_info (struct input_block *ib, struct data_in *data_in, LTO_DEBUG_TOKEN ("file"); data_in->current_file - = canon_file_name (input_string_internal (data_in, input_uleb128 (ib), &len)); + = canon_file_name (input_string_internal (data_in, lto_input_uleb128 (ib), &len)); } if (flags & LTO_SOURCE_LINE) { LTO_DEBUG_TOKEN ("line"); - data_in->current_line = input_uleb128 (ib); + data_in->current_line = lto_input_uleb128 (ib); if (!(flags & LTO_SOURCE_FILE)) linemap_line_start (line_table, data_in->current_line, 80); @@ -529,7 +383,7 @@ input_line_info (struct input_block *ib, struct data_in *data_in, if (flags & LTO_SOURCE_COL) { LTO_DEBUG_TOKEN ("col"); - data_in->current_col = input_uleb128 (ib); + data_in->current_col = lto_input_uleb128 (ib); } #else if (flags & LTO_SOURCE_FILE) @@ -537,12 +391,12 @@ input_line_info (struct input_block *ib, struct data_in *data_in, unsigned int len; LTO_DEBUG_TOKEN ("file"); data_in->current_file - = input_string_internal (data_in, input_uleb128 (ib), &len); + = input_string_internal (data_in, lto_input_uleb128 (ib), &len); } if (flags & LTO_SOURCE_LINE) { LTO_DEBUG_TOKEN ("line"); - data_in->current_line = input_uleb128 (ib); + data_in->current_line = lto_input_uleb128 (ib); } #endif return (flags & LTO_SOURCE_HAS_LOC) != 0; @@ -594,7 +448,7 @@ clear_line_info (struct data_in *data_in) read. */ static tree -input_expr_operand (struct input_block *ib, struct data_in *data_in, +input_expr_operand (struct lto_input_block *ib, struct data_in *data_in, struct function *fn, enum LTO_tags tag) { enum tree_code code = tag_to_expr[tag]; @@ -627,14 +481,14 @@ input_expr_operand (struct input_block *ib, struct data_in *data_in, } else { - TREE_REALPART (result) = input_integer (ib, elt_type); - TREE_IMAGPART (result) = input_integer (ib, elt_type); + TREE_REALPART (result) = lto_input_integer (ib, elt_type); + TREE_IMAGPART (result) = lto_input_integer (ib, elt_type); } } break; case INTEGER_CST: - result = input_integer (ib, type); + result = lto_input_integer (ib, type); break; case REAL_CST: @@ -642,14 +496,14 @@ input_expr_operand (struct input_block *ib, struct data_in *data_in, break; case STRING_CST: - result = input_string (data_in, input_uleb128 (ib)); + result = input_string (data_in, lto_input_uleb128 (ib)); TREE_TYPE (result) = type; break; case IDENTIFIER_NODE: { unsigned int len; - const char * ptr = input_string_internal (data_in, input_uleb128 (ib), &len); + const char * ptr = input_string_internal (data_in, lto_input_uleb128 (ib), &len); result = get_identifier_with_length (ptr, len); } break; @@ -657,7 +511,7 @@ input_expr_operand (struct input_block *ib, struct data_in *data_in, case VECTOR_CST: { tree chain = NULL_TREE; - int len = input_uleb128 (ib); + int len = lto_input_uleb128 (ib); tree elt_type = input_type_ref (data_in, ib); if (len && tag == LTO_vector_cst1) @@ -677,12 +531,12 @@ input_expr_operand (struct input_block *ib, struct data_in *data_in, else { int i; - tree last = build_tree_list (NULL_TREE, input_integer (ib, elt_type)); + tree last = build_tree_list (NULL_TREE, lto_input_integer (ib, elt_type)); chain = last; for (i = 1; i < len; i++) { tree t - = build_tree_list (NULL_TREE, input_integer (ib, elt_type)); + = build_tree_list (NULL_TREE, lto_input_integer (ib, elt_type)); TREE_CHAIN (last) = t; last = t; } @@ -713,7 +567,7 @@ input_expr_operand (struct input_block *ib, struct data_in *data_in, case CONSTRUCTOR: { VEC(constructor_elt,gc) *vec = NULL; - unsigned int len = input_uleb128 (ib); + unsigned int len = lto_input_uleb128 (ib); if (len) { @@ -740,7 +594,7 @@ input_expr_operand (struct input_block *ib, struct data_in *data_in, break; case SSA_NAME: - result = VEC_index (tree, SSANAMES (fn), input_uleb128 (ib)); + result = VEC_index (tree, SSANAMES (fn), lto_input_uleb128 (ib)); add_referenced_var (SSA_NAME_VAR (result)); break; @@ -749,16 +603,16 @@ input_expr_operand (struct input_block *ib, struct data_in *data_in, break; case FIELD_DECL: - result = data_in->field_decls [input_uleb128 (ib)]; + result = data_in->field_decls [lto_input_uleb128 (ib)]; break; case FUNCTION_DECL: - result = data_in->fn_decls [input_uleb128 (ib)]; + result = data_in->fn_decls [lto_input_uleb128 (ib)]; gcc_assert (result); break; case TYPE_DECL: - result = data_in->type_decls [input_uleb128 (ib)]; + result = data_in->type_decls [lto_input_uleb128 (ib)]; gcc_assert (result); break; @@ -767,13 +621,13 @@ input_expr_operand (struct input_block *ib, struct data_in *data_in, if (tag == LTO_var_decl1) { /* Static or externs are here. */ - result = data_in->var_decls [input_uleb128 (ib)]; + result = data_in->var_decls [lto_input_uleb128 (ib)]; varpool_mark_needed_node (varpool_node (result)); } else { /* Locals are here. */ - int lv_index = input_uleb128 (ib); + int lv_index = lto_input_uleb128 (ib); result = data_in->local_decls [lv_index]; if (result == NULL) { @@ -781,11 +635,11 @@ input_expr_operand (struct input_block *ib, struct data_in *data_in, it does not disturb the position of the code that is calling for the local variable. This allows locals to refer to other locals. */ - struct input_block lib; + struct lto_input_block lib; #ifdef LTO_STREAM_DEBUGGING - struct input_block *current = lto_debug_context.current_data; - struct input_block debug; + struct lto_input_block *current = lto_debug_context.current_data; + struct lto_input_block debug; int current_indent = lto_debug_context.indent; debug.data = current->data; @@ -867,7 +721,7 @@ input_expr_operand (struct input_block *ib, struct data_in *data_in, case CALL_EXPR: { unsigned int i; - unsigned int count = input_uleb128 (ib); + unsigned int count = lto_input_uleb128 (ib); tree op1; tree op2 = NULL_TREE; @@ -898,8 +752,8 @@ input_expr_operand (struct input_block *ib, struct data_in *data_in, tree op2; if (tag == LTO_bit_field_ref1) { - op1 = build_int_cst_wide (sizetype, input_uleb128 (ib), 0); - op2 = build_int_cst_wide (bitsizetype, input_uleb128 (ib), 0); + op1 = build_int_cst_wide (sizetype, lto_input_uleb128 (ib), 0); + op2 = build_int_cst_wide (bitsizetype, lto_input_uleb128 (ib), 0); op0 = input_expr_operand (ib, data_in, fn, input_record_start (ib)); } @@ -931,7 +785,7 @@ input_expr_operand (struct input_block *ib, struct data_in *data_in, case ASM_EXPR: { - tree str = input_string (data_in, input_uleb128 (ib)); + tree str = input_string (data_in, lto_input_uleb128 (ib)); tree ins = NULL_TREE; tree outs = NULL_TREE; tree clobbers = NULL_TREE; @@ -956,7 +810,7 @@ input_expr_operand (struct input_block *ib, struct data_in *data_in, break; case RESX_EXPR: - result = build1 (code, void_type_node, input_integer (ib, NULL_TREE)); + result = build1 (code, void_type_node, lto_input_integer (ib, NULL_TREE)); break; case RETURN_EXPR: @@ -1005,8 +859,8 @@ input_expr_operand (struct input_block *ib, struct data_in *data_in, case RANGE_EXPR: { - tree op0 = input_integer (ib, input_type_ref (data_in, ib)); - tree op1 = input_integer (ib, input_type_ref (data_in, ib)); + tree op0 = lto_input_integer (ib, input_type_ref (data_in, ib)); + tree op1 = lto_input_integer (ib, input_type_ref (data_in, ib)); result = build2 (RANGE_EXPR, sizetype, op0, op1); } break; @@ -1026,7 +880,7 @@ input_expr_operand (struct input_block *ib, struct data_in *data_in, case SWITCH_EXPR: { - unsigned int len = input_uleb128 (ib); + unsigned int len = lto_input_uleb128 (ib); unsigned int i; tree op0 = input_expr_operand (ib, data_in, fn, input_record_start (ib)); @@ -1042,14 +896,14 @@ input_expr_operand (struct input_block *ib, struct data_in *data_in, case TREE_LIST: { - unsigned int count = input_uleb128 (ib); + unsigned int count = lto_input_uleb128 (ib); + tree next = NULL; result = NULL_TREE; while (count--) { tree value; tree purpose; - tree next = NULL; tree elt; enum LTO_tags tag = input_record_start (ib); @@ -1230,7 +1084,7 @@ input_globals (struct lto_header * header, labels from DATA segment SIZE bytes long using DATA_IN. */ static void -input_labels (struct input_block *ib, struct data_in *data_in, +input_labels (struct lto_input_block *ib, struct data_in *data_in, unsigned int named_count, unsigned int unnamed_count) { unsigned int i; @@ -1243,7 +1097,7 @@ input_labels (struct input_block *ib, struct data_in *data_in, data_in->labels = xcalloc (named_count + unnamed_count, sizeof (tree*)); for (i = 0; i < named_count; i++) { - unsigned int name_index = input_uleb128 (ib); + unsigned int name_index = lto_input_uleb128 (ib); unsigned int len; const char *s = input_string_internal (data_in, name_index, &len); tree name = get_identifier_with_length (s, len); @@ -1260,7 +1114,7 @@ input_labels (struct input_block *ib, struct data_in *data_in, static void -input_local_vars_index (struct input_block *ib, struct data_in *data_in, +input_local_vars_index (struct lto_input_block *ib, struct data_in *data_in, unsigned int count) { unsigned int i; @@ -1271,9 +1125,9 @@ input_local_vars_index (struct input_block *ib, struct data_in *data_in, for (i = 0; i < count; i++) { - data_in->local_decls_index[i] = input_uleb128 (ib); + data_in->local_decls_index[i] = lto_input_uleb128 (ib); #ifdef LTO_STREAM_DEBUGGING - data_in->local_decls_index_d[i] = input_uleb128 (ib); + data_in->local_decls_index_d[i] = lto_input_uleb128 (ib); #endif } } @@ -1282,7 +1136,7 @@ input_local_vars_index (struct input_block *ib, struct data_in *data_in, /* Input local var I for FN from IB. */ static tree -input_local_var (struct input_block *ib, struct data_in *data_in, +input_local_var (struct lto_input_block *ib, struct data_in *data_in, struct function *fn, unsigned int i) { enum LTO_tags tag; @@ -1303,7 +1157,7 @@ input_local_var (struct input_block *ib, struct data_in *data_in, variant = tag & 0xF; is_var = ((tag & 0xFFF0) == LTO_local_var_decl_body0); - name_index = input_uleb128 (ib); + name_index = lto_input_uleb128 (ib); if (name_index) { unsigned int len; @@ -1333,7 +1187,7 @@ input_local_var (struct input_block *ib, struct data_in *data_in, DECL_INITIAL (result) = input_expr_operand (ib, data_in, fn, tag); LTO_DEBUG_INDENT_TOKEN ("unexpanded index"); - index = input_sleb128 (ib); + index = lto_input_sleb128 (ib); if (index != -1) data_in->unexpanded_indexes[index] = i; } @@ -1362,7 +1216,7 @@ input_local_var (struct input_block *ib, struct data_in *data_in, DECL_CONTEXT (result) = context; LTO_DEBUG_TOKEN ("align"); - DECL_ALIGN (result) = input_uleb128 (ib); + DECL_ALIGN (result) = lto_input_uleb128 (ib); LTO_DEBUG_TOKEN ("size"); DECL_SIZE (result) = input_expr_operand (ib, data_in, fn, input_record_start (ib)); @@ -1394,7 +1248,7 @@ input_local_var (struct input_block *ib, struct data_in *data_in, bytes long using DATA_IN. */ static void -input_local_vars (struct input_block *ib, struct data_in *data_in, +input_local_vars (struct lto_input_block *ib, struct data_in *data_in, struct function *fn, unsigned int count) { int i; @@ -1416,7 +1270,7 @@ input_local_vars (struct input_block *ib, struct data_in *data_in, fn->unexpanded_var_list = tree_cons (NULL_TREE, var, fn->unexpanded_var_list); - if (input_uleb128 (ib)) + if (lto_input_uleb128 (ib)) DECL_CONTEXT (var) = fn->decl; /* DECL_INITIAL. */ @@ -1438,7 +1292,7 @@ input_local_vars (struct input_block *ib, struct data_in *data_in, if (!data_in->local_decls[i]) { #ifdef LTO_STREAM_DEBUGGING - ((struct input_block *)lto_debug_context.current_data)->p + ((struct lto_input_block *)lto_debug_context.current_data)->p = data_in->local_decls_index_d[i]; #endif ib->p = data_in->local_decls_index[i]; @@ -1461,12 +1315,12 @@ input_local_vars (struct input_block *ib, struct data_in *data_in, /* Read the exception table. */ static void -input_eh_regions (struct input_block *ib, +input_eh_regions (struct lto_input_block *ib, struct function *fn ATTRIBUTE_UNUSED, struct data_in *data_in ATTRIBUTE_UNUSED) { /* Not ready to read exception records yet. */ - input_uleb128 (ib); + lto_input_uleb128 (ib); } @@ -1489,7 +1343,7 @@ make_new_block (struct function *fn, unsigned int index) /* Set up the cfg for THIS_FUN. */ static void -input_cfg (struct input_block *ib, struct function *fn) +input_cfg (struct lto_input_block *ib, struct function *fn) { unsigned int bb_count; basic_block p_bb; @@ -1500,7 +1354,7 @@ input_cfg (struct input_block *ib, struct function *fn) init_ssa_operands (); LTO_DEBUG_TOKEN ("lastbb"); - bb_count = input_uleb128 (ib); + bb_count = lto_input_uleb128 (ib); last_basic_block_for_function (fn) = bb_count; if (bb_count > VEC_length (basic_block, @@ -1513,7 +1367,7 @@ input_cfg (struct input_block *ib, struct function *fn) label_to_block_map_for_function (fn), bb_count); LTO_DEBUG_TOKEN ("bbindex"); - index = input_sleb128 (ib); + index = lto_input_sleb128 (ib); while (index != -1) { basic_block bb = BASIC_BLOCK_FOR_FUNCTION (fn, index); @@ -1523,7 +1377,7 @@ input_cfg (struct input_block *ib, struct function *fn) bb = make_new_block (fn, index); LTO_DEBUG_TOKEN ("edgecount"); - edge_count = input_uleb128 (ib); + edge_count = lto_input_uleb128 (ib); /* Connect up the cfg. */ for (i = 0; i < edge_count; i++) @@ -1533,9 +1387,9 @@ input_cfg (struct input_block *ib, struct function *fn) basic_block dest; LTO_DEBUG_TOKEN ("dest"); - dest_index = input_uleb128 (ib); + dest_index = lto_input_uleb128 (ib); LTO_DEBUG_TOKEN ("eflags"); - edge_flags = input_uleb128 (ib); + edge_flags = lto_input_uleb128 (ib); dest = BASIC_BLOCK_FOR_FUNCTION (fn, dest_index); if (dest == NULL) @@ -1544,12 +1398,12 @@ input_cfg (struct input_block *ib, struct function *fn) } LTO_DEBUG_TOKEN ("bbindex"); - index = input_sleb128 (ib); + index = lto_input_sleb128 (ib); } p_bb = ENTRY_BLOCK_PTR_FOR_FUNCTION(fn); LTO_DEBUG_TOKEN ("bbchain"); - index = input_sleb128 (ib); + index = lto_input_sleb128 (ib); while (index != -1) { basic_block bb = BASIC_BLOCK_FOR_FUNCTION (fn, index); @@ -1557,7 +1411,7 @@ input_cfg (struct input_block *ib, struct function *fn) p_bb->next_bb = bb; p_bb = bb; LTO_DEBUG_TOKEN ("bbchain"); - index = input_sleb128 (ib); + index = lto_input_sleb128 (ib); } } @@ -1565,12 +1419,12 @@ input_cfg (struct input_block *ib, struct function *fn) /* Input the next phi function for BB. */ static tree -input_phi (struct input_block *ib, basic_block bb, +input_phi (struct lto_input_block *ib, basic_block bb, struct data_in *data_in, struct function *fn) { lto_flags_type flags = input_tree_flags (ib, PHI_NODE, false); - tree phi_result = VEC_index (tree, SSANAMES (fn), input_uleb128 (ib)); + tree phi_result = VEC_index (tree, SSANAMES (fn), lto_input_uleb128 (ib)); int len = EDGE_COUNT (bb->preds); int i; tree result = create_phi_node (phi_result, bb); @@ -1583,7 +1437,7 @@ input_phi (struct input_block *ib, basic_block bb, for (i = 0; i < len; i++) { tree def = input_expr_operand (ib, data_in, fn, input_record_start (ib)); - int src_index = input_uleb128 (ib); + int src_index = lto_input_uleb128 (ib); basic_block sbb = BASIC_BLOCK_FOR_FUNCTION (fn, src_index); edge e = NULL; @@ -1611,13 +1465,13 @@ input_phi (struct input_block *ib, basic_block bb, /* Read in the ssa_names array from IB. */ static void -input_ssa_names (struct input_block *ib, struct data_in *data_in, struct function *fn) +input_ssa_names (struct lto_input_block *ib, struct data_in *data_in, struct function *fn) { unsigned int i; - int size = input_uleb128 (ib); + int size = lto_input_uleb128 (ib); init_ssanames (fn, size); - i = input_uleb128 (ib); + i = lto_input_uleb128 (ib); while (i) { @@ -1636,7 +1490,7 @@ input_ssa_names (struct input_block *ib, struct data_in *data_in, struct functio process_tree_flags (ssa_name, flags); if (SSA_NAME_IS_DEFAULT_DEF (ssa_name)) set_default_def (SSA_NAME_VAR (ssa_name), ssa_name); - i = input_uleb128 (ib); + i = lto_input_uleb128 (ib); } } @@ -1644,15 +1498,16 @@ input_ssa_names (struct input_block *ib, struct data_in *data_in, struct functio /* Read in the next basic block. */ static void -input_bb (struct input_block *ib, enum LTO_tags tag, +input_bb (struct lto_input_block *ib, enum LTO_tags tag, struct data_in *data_in, struct function *fn) { unsigned int index; basic_block bb; block_stmt_iterator bsi; + unsigned int stmt_num; LTO_DEBUG_TOKEN ("bbindex"); - index = input_uleb128 (ib); + index = lto_input_uleb128 (ib); bb = BASIC_BLOCK_FOR_FUNCTION (fn, index); /* LTO_bb1 has stmts, LTO_bb0 does not. */ @@ -1664,23 +1519,27 @@ input_bb (struct input_block *ib, enum LTO_tags tag, bsi = bsi_start (bb); LTO_DEBUG_INDENT_TOKEN ("stmt"); - tag = input_record_start (ib); - while (tag) + stmt_num = lto_input_uleb128 (ib); + while (stmt_num) { - tree stmt = input_expr_operand (ib, data_in, fn, tag); + tree stmt; + + tag = input_record_start (ib); + stmt = input_expr_operand (ib, data_in, fn, tag); bsi_insert_after (&bsi, stmt, BSI_NEW_STMT); LTO_DEBUG_INDENT_TOKEN ("stmt"); - tag = input_record_start (ib); + stmt_num = lto_input_uleb128 (ib); /* FIXME, add code to handle the exception. */ } - LTO_DEBUG_INDENT_TOKEN ("phi"); - tag = input_record_start (ib); - while (tag) + LTO_DEBUG_INDENT_TOKEN ("phi"); + stmt_num = lto_input_uleb128 (ib); + while (stmt_num) { + tag = input_record_start (ib); input_phi (ib, bb, data_in, fn); LTO_DEBUG_INDENT_TOKEN ("phi"); - tag = input_record_start (ib); + stmt_num = lto_input_uleb128 (ib); } LTO_DEBUG_UNDENT(); @@ -1691,7 +1550,7 @@ input_bb (struct input_block *ib, enum LTO_tags tag, static void input_function (tree fn_decl, struct data_in *data_in, - struct input_block *ib) + struct lto_input_block *ib) { struct function *fn = DECL_STRUCT_FUNCTION (fn_decl); enum LTO_tags tag = input_record_start (ib); @@ -1730,7 +1589,7 @@ input_function (tree fn_decl, struct data_in *data_in, static void input_constructor (tree var, struct data_in *data_in, - struct input_block *ib) + struct lto_input_block *ib) { enum LTO_tags tag; @@ -1893,20 +1752,20 @@ lto_read_body (lto_info_fd *fd, int32_t debug_cfg_offset = debug_ssa_names_offset + header->debug_ssa_names_size; int32_t debug_main_offset = debug_cfg_offset + header->debug_cfg_size; - struct input_block debug_decl_index + struct lto_input_block debug_decl_index = {data + debug_decl_index_offset, 0, header->debug_decl_index_size}; - struct input_block debug_decl + struct lto_input_block debug_decl = {data + debug_decl_offset, 0, header->debug_decl_size}; - struct input_block debug_label + struct lto_input_block debug_label = {data + debug_label_offset, 0, header->debug_label_size}; - struct input_block debug_ssa_names + struct lto_input_block debug_ssa_names = {data + debug_ssa_names_offset, 0, header->debug_ssa_names_size}; - struct input_block debug_cfg + struct lto_input_block debug_cfg = {data + debug_cfg_offset, 0, header->debug_cfg_size}; - struct input_block debug_main + struct lto_input_block debug_main = {data + debug_main_offset, 0, header->debug_main_size}; - lto_debug_context.out = debug_out_fun; + lto_debug_context.out = lto_debug_in_fun; lto_debug_context.indent = 0; #endif @@ -1916,17 +1775,17 @@ lto_read_body (lto_info_fd *fd, lto_ref *in_type_decls = (lto_ref*)(data + type_decls_offset); lto_ref *in_types = (lto_ref*)(data + types_offset); - struct input_block ib_named_labels + struct lto_input_block ib_named_labels = {data + named_label_offset, 0, header->named_label_size}; - struct input_block ib_ssa_names + struct lto_input_block ib_ssa_names = {data + ssa_names_offset, 0, header->ssa_names_size}; - struct input_block ib_cfg + struct lto_input_block ib_cfg = {data + cfg_offset, 0, header->cfg_size}; - struct input_block ib_local_decls_index + struct lto_input_block ib_local_decls_index = {data + local_decls_index_offset, 0, header->local_decls_index_size}; - struct input_block ib_local_decls + struct lto_input_block ib_local_decls = {data + local_decls_offset, 0, header->local_decls_size}; - struct input_block ib_main + struct lto_input_block ib_main = {data + main_offset, 0, header->main_size}; memset (&data_in, 0, sizeof (struct data_in)); @@ -2047,81 +1906,3 @@ lto_read_var_init (lto_info_fd *fd, lto_read_body (fd, context, var_decl, data, false); } -/* Dump the debug STREAM, and two characters B and C. */ - -static void -dump_debug_stream (struct input_block *stream, char b, char c) -{ - unsigned int i = 0; - bool new_line = true; - int chars = 0; - int hit_pos = -1; - fprintf (stderr, - "stream failure: looking for a '%c'[0x%x] in the debug stream.\nHowever the data translated into a '%c'[0x%x]at position%d\n\n", - c, c, b, b, stream->p); - - while (i < stream->len) - { - char x; - - if (new_line) - { - if (hit_pos >= 0) - { - int j; - fprintf (stderr, " "); - for (j=0; j<hit_pos; j++) - fputc (' ', stderr); - fprintf (stderr, "^\n "); - for (j=0; j<hit_pos; j++) - fputc (' ', stderr); - fprintf (stderr, "|\n"); - hit_pos = -1; - } - - fprintf (stderr, "%6d -->>", i); - new_line = false; - chars = 0; - } - - x = stream->data[i++]; - if (x == '\n') - { - fprintf (stderr, "<<--\n"); - new_line = true; - } - else - fputc (x, stderr); - - if (i == stream->p) - hit_pos = chars; - chars++; - } -} - - -#ifdef LTO_STREAM_DEBUGGING - -/* The low level output routine to for a single character. Unlike the - version on the writing side, this does interesting processing. - - This call checks that the debugging information generated by - lto-function-out matches the debugging information generated by the - reader. Each character is checked and a call to abort is generated - when the first mismatch is found. - */ - -static void -debug_out_fun (struct lto_debug_context *context, char c) -{ - struct input_block *stream = (struct input_block *)context->current_data; - char b = input_1_unsigned (stream); - - if (b != c) - { - dump_debug_stream (stream, b, c); - gcc_unreachable (); - } -} - -#endif diff --git a/gcc/lto/lto-section-in.c b/gcc/lto/lto-section-in.c new file mode 100644 index 00000000000..e5b815e3dbd --- /dev/null +++ b/gcc/lto/lto-section-in.c @@ -0,0 +1,266 @@ +/* Input functions for reading lto sections. + + Copyright 2006, 2007, 2008 Free Software Foundation, Inc. + Contributed by Kenneth Zadeck <zadeck@naturalbridge.com> + +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 2, 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 COPYING. If not, write to +the Free Software Foundation, 51 Franklin Street, Fifth Floor, +Boston, MA 02110-1301, USA. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "toplev.h" +#include "tree.h" +#include "expr.h" +#include "flags.h" +#include "params.h" +#include "input.h" +#include "varray.h" +#include "hashtab.h" +#include "langhooks.h" +#include "basic-block.h" +#include "tree-iterator.h" +#include "tree-pass.h" +#include "tree-flow.h" +#include "cgraph.h" +#include "function.h" +#include "ggc.h" +#include "diagnostic.h" +#include "except.h" +#include "debug.h" +#include "vec.h" +#include "timevar.h" +#include "dwarf2asm.h" +#include "dwarf2out.h" +#include "output.h" +#include "lto-tags.h" +#include "lto.h" +#include "lto-section-in.h" +#include <ctype.h> +#include "cpplib.h" + +unsigned char +lto_input_1_unsigned (struct lto_input_block *ib) +{ + gcc_assert (ib->p < ib->len); + return (ib->data[ib->p++]); +} + + +/* Read an ULEB128 Number of IB. */ + +unsigned HOST_WIDE_INT +lto_input_uleb128 (struct lto_input_block *ib) +{ + unsigned HOST_WIDE_INT result = 0; + int shift = 0; + unsigned HOST_WIDE_INT byte; + + while (true) + { + byte = lto_input_1_unsigned (ib); + result |= (byte & 0x7f) << shift; + shift += 7; + if ((byte & 0x80) == 0) + { + LTO_DEBUG_WIDE ("U", result); + return result; + } + } +} + +/* HOST_WIDEST_INT version of lto_input_uleb128. IB is as in lto_input_uleb128. */ + +unsigned HOST_WIDEST_INT +lto_input_widest_uint_uleb128 (struct lto_input_block *ib) +{ + unsigned HOST_WIDEST_INT result = 0; + int shift = 0; + unsigned HOST_WIDEST_INT byte; + + while (true) + { + byte = lto_input_1_unsigned (ib); + result |= (byte & 0x7f) << shift; + shift += 7; + if ((byte & 0x80) == 0) + { + LTO_DEBUG_WIDE ("U", result); + return result; + } + } +} + +/* Read an SLEB128 Number of IB. */ + +HOST_WIDE_INT +lto_input_sleb128 (struct lto_input_block *ib) +{ + HOST_WIDE_INT result = 0; + int shift = 0; + unsigned HOST_WIDE_INT byte; + + while (true) + { + byte = lto_input_1_unsigned (ib); + result |= (byte & 0x7f) << shift; + shift += 7; + if ((byte & 0x80) == 0) + { + if ((shift < HOST_BITS_PER_WIDE_INT) && (byte & 0x40)) + result |= - ((HOST_WIDE_INT)1 << shift); + + LTO_DEBUG_WIDE ("S", result); + return result; + } + } +} + + +/* Input the next integer constant of TYPE in IB. */ + +tree +lto_input_integer (struct lto_input_block *ib, tree type) +{ + HOST_WIDE_INT low = 0; + HOST_WIDE_INT high = 0; + int shift = 0; + unsigned HOST_WIDE_INT byte; + + while (true) + { + byte = lto_input_1_unsigned (ib); + if (shift < HOST_BITS_PER_WIDE_INT - 7) + /* Working on the low part. */ + low |= (byte & 0x7f) << shift; + else if (shift >= HOST_BITS_PER_WIDE_INT) + /* Working on the high part. */ + high |= (byte & 0x7f) << (shift - HOST_BITS_PER_WIDE_INT); + else + { + /* Working on the transition between the low and high parts. */ + low |= (byte & 0x7f) << shift; + high |= (byte & 0x7f) >> (HOST_BITS_PER_WIDE_INT - shift); + } + + shift += 7; + if ((byte & 0x80) == 0) + { + if (byte & 0x40) + { + /* The number is negative. */ + if (shift < HOST_BITS_PER_WIDE_INT) + { + low |= - ((HOST_WIDE_INT)1 << shift); + high = -1; + } + else if (shift < (2 * HOST_BITS_PER_WIDE_INT)) + high |= - ((HOST_WIDE_INT)1 << (shift - HOST_BITS_PER_WIDE_INT)); + } + +#ifdef LTO_STREAM_DEBUGGING + /* Have to match the quick out in the lto writer. */ + if (((high == -1) && (low < 0)) + || ((high == 0) && (low >= 0))) + LTO_DEBUG_WIDE ("S", low); + else + LTO_DEBUG_INTEGER ("SS", high, low); +#endif + return build_int_cst_wide (type, low, high); + } + } +} + +#ifdef LTO_STREAM_DEBUGGING + +/* Dump the debug STREAM, and two characters B and C. */ + +void +dump_debug_stream (struct lto_input_block *stream, char b, char c) +{ + unsigned int i = 0; + bool new_line = true; + int chars = 0; + int hit_pos = -1; + fprintf (stderr, + "stream failure: looking for a '%c'[0x%x] in the debug stream.\nHowever the data translated into a '%c'[0x%x]at position%d\n\n", + c, c, b, b, stream->p); + + while (i < stream->len) + { + char x; + + if (new_line) + { + if (hit_pos >= 0) + { + int j; + fprintf (stderr, " "); + for (j=0; j<hit_pos; j++) + fputc (' ', stderr); + fprintf (stderr, "^\n "); + for (j=0; j<hit_pos; j++) + fputc (' ', stderr); + fprintf (stderr, "|\n"); + hit_pos = -1; + } + + fprintf (stderr, "%6d -->>", i); + new_line = false; + chars = 0; + } + + x = stream->data[i++]; + if (x == '\n') + { + fprintf (stderr, "<<--\n"); + new_line = true; + } + else + fputc (x, stderr); + + if (i == stream->p) + hit_pos = chars; + chars++; + } +} + + +/* The low level output routine to for a single character. Unlike the + version on the writing side, this does interesting processing. + + This call checks that the debugging information generated by + lto-function-out matches the debugging information generated by the + reader. Each character is checked and a call to abort is generated + when the first mismatch is found. + */ + +void +lto_debug_in_fun (struct lto_debug_context *context, char c) +{ + struct lto_input_block *stream = (struct lto_input_block *)context->current_data; + char b = lto_input_1_unsigned (stream); + + if (b != c) + { + dump_debug_stream (stream, b, c); + gcc_unreachable (); + } +} + +#endif diff --git a/gcc/lto/lto-section-in.h b/gcc/lto/lto-section-in.h new file mode 100644 index 00000000000..e0b9100d25b --- /dev/null +++ b/gcc/lto/lto-section-in.h @@ -0,0 +1,42 @@ +/* LTO input code. + Copyright (C) 2007, 2008 Free Software Foundation, Inc. + Contributed by Kenneth Zadeck <zadeck@naturalbridge.com> + +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/>. */ + +#ifndef GCC_LTO_SECTION_IN_H +#define GCC_LTO_SECTION_IN_H + +struct lto_input_block +{ + const char *data; + unsigned int p; + unsigned int len; +}; + +unsigned char lto_input_1_unsigned (struct lto_input_block *); +unsigned HOST_WIDE_INT lto_input_uleb128 (struct lto_input_block *); +unsigned HOST_WIDEST_INT lto_input_widest_uint_uleb128 (struct lto_input_block *); +HOST_WIDE_INT lto_input_sleb128 (struct lto_input_block *); +tree lto_input_integer (struct lto_input_block *, tree); + +#ifdef LTO_STREAM_DEBUGGING +void lto_debug_in_fun (struct lto_debug_context *, char); +void dump_debug_stream (struct lto_input_block *, char, char); +#endif + +#endif /* GCC_LTO_SECTION_IN_H */ |