+2011-04-03 Michael Matz <matz@suse.de>
+
+ * lto-streamer.h (struct lto_streamer_cache_d): Remove offsets
+ and next_slot members.
+ (lto_streamer_cache_insert, lto_streamer_cache_insert_at,
+ lto_streamer_cache_lookup, lto_streamer_cache_get): Adjust prototypes.
+ (lto_streamer_cache_append): Declare.
+ * lto-streamer.c (lto_streamer_cache_add_to_node_array): Use
+ unsigned index, remove offset parameter, ensure that we append
+ or update existing entries.
+ (lto_streamer_cache_insert_1): Use unsigned index, remove offset_p
+ parameter, update next_slot for append.
+ (lto_streamer_cache_insert): Use unsigned index, remove offset_p
+ parameter.
+ (lto_streamer_cache_insert_at): Likewise.
+ (lto_streamer_cache_append): New function.
+ (lto_streamer_cache_lookup): Use unsigned index.
+ (lto_streamer_cache_get): Likewise.
+ (lto_record_common_node): Don't test tree_node_can_be_shared.
+ (preload_common_node): Adjust call to lto_streamer_cache_insert.
+ (lto_streamer_cache_delete): Don't free offsets member.
+ * lto-streamer-out.c (eq_string_slot_node): Use memcmp.
+ (lto_output_string_with_length): Use lto_output_data_stream.
+ (lto_output_tree_header): Remove ix parameter, don't write it.
+ (lto_output_builtin_tree): Likewise.
+ (lto_write_tree): Adjust callers to above, don't track and write
+ offset, write unsigned index.
+ (output_unreferenced_globals): Don't emit all global vars.
+ (write_global_references): Use unsigned indices.
+ (lto_output_decl_state_refs): Likewise.
+ (write_symbol): Likewise.
+ * lto-streamer-in.c (lto_input_chain): Move earlier.
+ (input_function): Use unsigned index.
+ (input_alias_pairs): Don't read and then ignore all global vars.
+ (lto_materialize_tree): Remove ix_p parameter, don't read index,
+ don't pass it back, use lto_streamer_cache_append.
+ (lto_register_var_decl_in_symtab): Use unsigned index.
+ (lto_register_function_decl_in_symtab): Likewise.
+ (lto_get_pickled_tree): Don't read in or handle offset, read unsigned
+ index.
+ (lto_get_builtin_tree): Don't read index, use
+ lto_streamer_cache_append.
+ (lto_read_tree): Adjust call to lto_materialize_tree.
+
+ * ipa-inline.c (cgraph_edge_badness): Move growth calculaton,
+ don't use function calls in arguments to MIN.
+
+ * varasm.c (decl_binds_to_current_def_p): Don't check TREE_PUBLIC
+ twice.
+
+ * gimple.c (gimple_type_leader_entry): Mark deletable.
+
2011-04-03 Alan Modra <amodra@gmail.com>
* dwarf2out.c (mem_loc_descriptor): Recurse on LO_SUM.
} gimple_type_leader_entry;
#define GIMPLE_TYPE_LEADER_SIZE 16381
-static GTY((length("GIMPLE_TYPE_LEADER_SIZE"))) gimple_type_leader_entry
- *gimple_type_leader;
+static GTY((deletable, length("GIMPLE_TYPE_LEADER_SIZE")))
+ gimple_type_leader_entry *gimple_type_leader;
/* Lookup an existing leader for T and return it or NULL_TREE, if
there is none in the cache. */
cgraph_edge_badness (struct cgraph_edge *edge, bool dump)
{
gcov_type badness;
- int growth =
- (cgraph_estimate_size_after_inlining (edge->caller, edge->callee)
- - edge->caller->global.size);
+ int growth;
if (edge->callee->local.disregard_inline_limits)
return INT_MIN;
+ growth =
+ (cgraph_estimate_size_after_inlining (edge->caller, edge->callee)
+ - edge->caller->global.size);
+
if (dump)
{
fprintf (dump_file, " Badness calculation for %s -> %s\n",
int growth_for_all;
badness = growth * 10000;
benefitperc =
- MIN (100 * inline_summary (edge->callee)->time_inlining_benefit /
- (edge->callee->global.time + 1) +1, 100);
+ 100 * inline_summary (edge->callee)->time_inlining_benefit
+ / (edge->callee->global.time + 1) +1;
+ benefitperc = MIN (benefitperc, 100);
div *= benefitperc;
-
/* Decrease badness if call is nested. */
/* Compress the range so we don't overflow. */
if (div > 10000)
}
+/* Read a chain of tree nodes from input block IB. DATA_IN contains
+ tables and descriptors for the file being read. */
+
+static tree
+lto_input_chain (struct lto_input_block *ib, struct data_in *data_in)
+{
+ int i, count;
+ tree first, prev, curr;
+
+ first = prev = NULL_TREE;
+ count = lto_input_sleb128 (ib);
+ for (i = 0; i < count; i++)
+ {
+ curr = lto_input_tree (ib, data_in);
+ if (prev)
+ TREE_CHAIN (prev) = curr;
+ else
+ first = curr;
+
+ TREE_CHAIN (curr) = NULL_TREE;
+ prev = curr;
+ }
+
+ return first;
+}
+
+
/* Read and return a double-linked list of catch handlers from input
block IB, using descriptors in DATA_IN. */
oarg && narg;
oarg = TREE_CHAIN (oarg), narg = TREE_CHAIN (narg))
{
- int ix;
+ unsigned ix;
bool res;
res = lto_streamer_cache_lookup (data_in->reader_cache, oarg, &ix);
gcc_assert (res);
clear_line_info (data_in);
- /* Skip over all the unreferenced globals. */
- do
- var = lto_input_tree (ib, data_in);
- while (var);
-
var = lto_input_tree (ib, data_in);
while (var)
{
static tree
lto_materialize_tree (struct lto_input_block *ib, struct data_in *data_in,
- enum LTO_tags tag, int *ix_p)
+ enum LTO_tags tag)
{
struct bitpack_d bp;
enum tree_code code;
#ifdef LTO_STREAMER_DEBUG
HOST_WIDEST_INT orig_address_in_writer;
#endif
- HOST_WIDE_INT ix;
result = NULL_TREE;
- /* Read the header of the node we are about to create. */
- ix = lto_input_sleb128 (ib);
- gcc_assert ((int) ix == ix);
- *ix_p = (int) ix;
-
#ifdef LTO_STREAMER_DEBUG
/* Read the word representing the memory address for the tree
as it was written by the writer. This is useful when
}
else
{
- /* All other nodes can be materialized with a raw make_node
- call. */
+ /* All other nodes can be materialized with a raw make_node call. */
result = make_node (code);
}
/* Enter RESULT in the reader cache. This will make RESULT
available so that circular references in the rest of the tree
structure can be resolved in subsequent calls to lto_input_tree. */
- lto_streamer_cache_insert_at (data_in->reader_cache, result, ix);
+ lto_streamer_cache_append (data_in->reader_cache, result);
return result;
}
-/* Read a chain of tree nodes from input block IB. DATA_IN contains
- tables and descriptors for the file being read. */
-
-static tree
-lto_input_chain (struct lto_input_block *ib, struct data_in *data_in)
-{
- int i, count;
- tree first, prev, curr;
-
- first = prev = NULL_TREE;
- count = lto_input_sleb128 (ib);
- for (i = 0; i < count; i++)
- {
- curr = lto_input_tree (ib, data_in);
- if (prev)
- TREE_CHAIN (prev) = curr;
- else
- first = curr;
-
- TREE_CHAIN (curr) = NULL_TREE;
- prev = curr;
- }
-
- return first;
-}
-
-
/* Read all pointer fields in the TS_COMMON structure of EXPR from input
block IB. DATA_IN contains tables and descriptors for the
file being read. */
declaration for merging. */
if (TREE_PUBLIC (decl))
{
- int ix;
+ unsigned ix;
if (!lto_streamer_cache_lookup (data_in->reader_cache, decl, &ix))
gcc_unreachable ();
lto_symtab_register_decl (decl, get_resolution (data_in, ix),
declaration for merging. */
if (TREE_PUBLIC (decl) && !DECL_ABSTRACT (decl))
{
- int ix;
+ unsigned ix;
if (!lto_streamer_cache_lookup (data_in->reader_cache, decl, &ix))
gcc_unreachable ();
lto_symtab_register_decl (decl, get_resolution (data_in, ix),
static tree
lto_get_pickled_tree (struct lto_input_block *ib, struct data_in *data_in)
{
- HOST_WIDE_INT ix;
+ unsigned HOST_WIDE_INT ix;
tree result;
enum LTO_tags expected_tag;
- unsigned HOST_WIDE_INT orig_offset;
- ix = lto_input_sleb128 (ib);
+ ix = lto_input_uleb128 (ib);
expected_tag = (enum LTO_tags) lto_input_uleb128 (ib);
- orig_offset = lto_input_uleb128 (ib);
- gcc_assert (orig_offset == (unsigned) orig_offset);
-
result = lto_streamer_cache_get (data_in->reader_cache, ix);
- if (result == NULL_TREE)
- {
- /* We have not yet read the cache slot IX. Go to the offset
- in the stream where the physical tree node is, and materialize
- it from there. */
- struct lto_input_block fwd_ib;
-
- /* If we are trying to go back in the stream, something is wrong.
- We should've read the node at the earlier position already. */
- if (ib->p >= orig_offset)
- internal_error ("bytecode stream: tried to jump backwards in the "
- "stream");
-
- LTO_INIT_INPUT_BLOCK (fwd_ib, ib->data, orig_offset, ib->len);
- result = lto_input_tree (&fwd_ib, data_in);
- }
-
gcc_assert (result
&& TREE_CODE (result) == lto_tag_to_tree_code (expected_tag));
enum built_in_function fcode;
const char *asmname;
tree result;
- int ix;
fclass = (enum built_in_class) lto_input_uleb128 (ib);
gcc_assert (fclass == BUILT_IN_NORMAL || fclass == BUILT_IN_MD);
fcode = (enum built_in_function) lto_input_uleb128 (ib);
- ix = lto_input_sleb128 (ib);
- gcc_assert (ix == (int) ix);
-
if (fclass == BUILT_IN_NORMAL)
{
gcc_assert (fcode < END_BUILTINS);
if (asmname)
set_builtin_user_assembler_name (result, asmname);
- lto_streamer_cache_insert_at (data_in->reader_cache, result, ix);
+ lto_streamer_cache_append (data_in->reader_cache, result);
return result;
}
enum LTO_tags tag)
{
tree result;
- int ix;
- result = lto_materialize_tree (ib, data_in, tag, &ix);
+ result = lto_materialize_tree (ib, data_in, tag);
/* Read all the pointer fields in RESULT. */
lto_input_tree_pointers (ib, data_in, result);
const struct string_slot *ds2 = (const struct string_slot *) p2;
if (ds1->len == ds2->len)
- {
- int i;
- for (i = 0; i < ds1->len; i++)
- if (ds1->s[i] != ds2->s[i])
- return 0;
- return 1;
- }
+ return memcmp (ds1->s, ds2->s, ds1->len) == 0;
return 0;
}
unsigned int start = string_stream->total_size;
struct string_slot *new_slot
= (struct string_slot *) xmalloc (sizeof (struct string_slot));
- unsigned int i;
new_slot->s = string;
new_slot->len = len;
*slot = new_slot;
lto_output_uleb128_stream (index_stream, start);
lto_output_uleb128_stream (string_stream, len);
- for (i = 0; i < len; i++)
- lto_output_1_stream (string_stream, string[i]);
+ lto_output_data_stream (string_stream, string, len);
}
else
{
- struct string_slot *old_slot = (struct string_slot *)*slot;
+ struct string_slot *old_slot = *slot;
lto_output_uleb128_stream (index_stream, old_slot->slot_num);
free (string);
}
where EXPR is stored. REF_P is as in lto_output_tree. */
static void
-lto_output_tree_header (struct output_block *ob, tree expr, int ix)
+lto_output_tree_header (struct output_block *ob, tree expr)
{
enum LTO_tags tag;
enum tree_code code;
variable sized nodes). */
tag = lto_tree_code_to_tag (code);
output_record_start (ob, tag);
- output_sleb128 (ob, ix);
/* The following will cause bootstrap miscomparisons. Enable with care. */
#ifdef LTO_STREAMER_DEBUG
the index into the streamer cache where EXPR is stored.*/
static void
-lto_output_builtin_tree (struct output_block *ob, tree expr, int ix)
+lto_output_builtin_tree (struct output_block *ob, tree expr)
{
gcc_assert (lto_stream_as_builtin_p (expr));
output_record_start (ob, LTO_builtin_decl);
output_uleb128 (ob, DECL_BUILT_IN_CLASS (expr));
output_uleb128 (ob, DECL_FUNCTION_CODE (expr));
- output_sleb128 (ob, ix);
if (DECL_ASSEMBLER_NAME_SET_P (expr))
{
where EXPR is stored. */
static void
-lto_write_tree (struct output_block *ob, tree expr, bool ref_p, int ix)
+lto_write_tree (struct output_block *ob, tree expr, bool ref_p)
{
struct bitpack_d bp;
/* Write the header, containing everything needed to materialize
EXPR on the reading side. */
- lto_output_tree_header (ob, expr, ix);
+ lto_output_tree_header (ob, expr);
/* Pack all the non-pointer fields in EXPR into a bitpack and write
the resulting bitpack. */
void
lto_output_tree (struct output_block *ob, tree expr, bool ref_p)
{
- int ix;
+ unsigned ix;
bool existed_p;
- unsigned offset;
if (expr == NULL_TREE)
{
return;
}
- /* Determine the offset in the stream where EXPR will be written.
- This is used when emitting pickle references so the reader knows
- where to reconstruct the pickled object from. This allows
- circular and forward references within the same stream. */
- offset = ob->main_stream->total_size;
-
- existed_p = lto_streamer_cache_insert (ob->writer_cache, expr, &ix, &offset);
+ existed_p = lto_streamer_cache_insert (ob->writer_cache, expr, &ix);
if (existed_p)
{
/* If a node has already been streamed out, make sure that
we don't write it more than once. Otherwise, the reader
will instantiate two different nodes for the same object. */
output_record_start (ob, LTO_tree_pickle_reference);
- output_sleb128 (ob, ix);
+ output_uleb128 (ob, ix);
output_uleb128 (ob, lto_tree_code_to_tag (TREE_CODE (expr)));
- output_uleb128 (ob, offset);
}
else if (lto_stream_as_builtin_p (expr))
{
compiler on startup. The only builtins that need to
be written out are BUILT_IN_FRONTEND. For all other
builtins, we simply write the class and code. */
- lto_output_builtin_tree (ob, expr, ix);
+ lto_output_builtin_tree (ob, expr);
}
else
{
/* This is the first time we see EXPR, write its fields
to OB. */
- lto_write_tree (ob, expr, ref_p, ix);
+ lto_write_tree (ob, expr, ref_p);
}
}
struct output_block *ob;
alias_pair *p;
unsigned i;
- struct varpool_node *vnode;
symbol_alias_set_t *defined;
struct sets setdata;
/* Make string 0 be a NULL string. */
lto_output_1_stream (ob->string_stream, 0);
- /* Emit references for all the global symbols. If a global symbol
- was never referenced in any of the functions of this file, it
- would not be emitted otherwise. This will result in unreferenced
- symbols at link time if a file defines a global symbol but
- never references it. */
- FOR_EACH_STATIC_VARIABLE (vnode)
- if (vnode->needed && varpool_node_in_set_p (vnode, vset))
- {
- tree var = vnode->decl;
-
- if (TREE_CODE (var) == VAR_DECL)
- {
- /* Output the object in order to output references used in the
- initialization. */
- lto_output_tree (ob, var, true);
-
- /* If it is public we also need a reference to the object itself. */
- if (TREE_PUBLIC (var))
- lto_output_tree_ref (ob, var);
- }
- }
-
- output_zero (ob);
-
/* We really need to propagate in both directoins:
for normal aliases we propagate from first defined alias to
all aliases defined based on it. For weakrefs we propagate in
struct lto_tree_ref_encoder *encoder)
{
tree t;
- int32_t index;
- const int32_t size = lto_tree_ref_encoder_size (encoder);
+ uint32_t index;
+ const uint32_t size = lto_tree_ref_encoder_size (encoder);
/* Write size as 32-bit unsigned. */
lto_output_data_stream (ref_stream, &size, sizeof (int32_t));
for (index = 0; index < size; index++)
{
- int32_t slot_num;
+ uint32_t slot_num;
t = lto_tree_ref_encoder_get_tree (encoder, index);
lto_streamer_cache_lookup (ob->writer_cache, t, &slot_num);
- gcc_assert (slot_num >= 0);
+ gcc_assert (slot_num != (unsigned)-1);
lto_output_data_stream (ref_stream, &slot_num, sizeof slot_num);
}
}
struct lto_out_decl_state *state)
{
unsigned i;
- int32_t ref;
+ uint32_t ref;
tree decl;
/* Write reference to FUNCTION_DECL. If there is not function,
write reference to void_type_node. */
decl = (state->fn_decl) ? state->fn_decl : void_type_node;
lto_streamer_cache_lookup (ob->writer_cache, decl, &ref);
- gcc_assert (ref >= 0);
- lto_output_data_stream (out_stream, &ref, sizeof (int32_t));
+ gcc_assert (ref != (unsigned)-1);
+ lto_output_data_stream (out_stream, &ref, sizeof (uint32_t));
for (i = 0; i < LTO_N_DECL_STREAMS; i++)
write_global_references (ob, out_stream, &state->streams[i]);
const char *name;
enum gcc_plugin_symbol_kind kind;
enum gcc_plugin_symbol_visibility visibility;
- int slot_num;
+ unsigned slot_num;
uint64_t size;
const char *comdat;
unsigned char c;
pointer_set_insert (seen, name);
lto_streamer_cache_lookup (cache, t, &slot_num);
- gcc_assert (slot_num >= 0);
+ gcc_assert (slot_num != (unsigned)-1);
if (DECL_EXTERNAL (t))
{
memset (&stream, 0, sizeof (stream));
/* Write all functions.
- First write all defined functions and the write all used functions.
+ First write all defined functions and then write all used functions.
This is done so only to handle duplicated symbols in cgraph. */
for (i = 0; i < lto_cgraph_encoder_size (encoder); i++)
{
/* Helper for lto_streamer_cache_insert_1. Add T to CACHE->NODES at
- slot IX. Add OFFSET to CACHE->OFFSETS at slot IX. */
+ slot IX. */
static void
lto_streamer_cache_add_to_node_array (struct lto_streamer_cache_d *cache,
- int ix, tree t, unsigned offset)
+ unsigned ix, tree t)
{
- gcc_assert (ix >= 0);
+ /* Make sure we're either replacing an old element or
+ appending consecutively. */
+ gcc_assert (ix <= VEC_length (tree, cache->nodes));
- /* Grow the array of nodes and offsets to accomodate T at IX. */
- if (ix >= (int) VEC_length (tree, cache->nodes))
- {
- size_t sz = ix + (20 + ix) / 4;
- VEC_safe_grow_cleared (tree, heap, cache->nodes, sz);
- VEC_safe_grow_cleared (unsigned, heap, cache->offsets, sz);
- }
-
- VEC_replace (tree, cache->nodes, ix, t);
- VEC_replace (unsigned, cache->offsets, ix, offset);
+ if (ix == VEC_length (tree, cache->nodes))
+ VEC_safe_push (tree, heap, cache->nodes, t);
+ else
+ VEC_replace (tree, cache->nodes, ix, t);
}
/* Helper for lto_streamer_cache_insert and lto_streamer_cache_insert_at.
- CACHE, T, IX_P and OFFSET_P are as in lto_streamer_cache_insert.
+ CACHE, T, and IX_P are as in lto_streamer_cache_insert.
If INSERT_AT_NEXT_SLOT_P is true, T is inserted at the next available
slot in the cache. Otherwise, T is inserted at the position indicated
static bool
lto_streamer_cache_insert_1 (struct lto_streamer_cache_d *cache,
- tree t, int *ix_p, unsigned *offset_p,
+ tree t, unsigned *ix_p,
bool insert_at_next_slot_p)
{
void **slot;
struct tree_int_map d_entry, *entry;
- int ix;
- unsigned offset;
+ unsigned ix;
bool existed_p;
gcc_assert (t);
{
/* Determine the next slot to use in the cache. */
if (insert_at_next_slot_p)
- ix = cache->next_slot++;
+ ix = VEC_length (tree, cache->nodes);
else
ix = *ix_p;
entry = (struct tree_int_map *)pool_alloc (cache->node_map_entries);
entry->base.from = t;
- entry->to = (unsigned) ix;
+ entry->to = ix;
*slot = entry;
- /* If no offset was given, store the invalid offset -1. */
- offset = (offset_p) ? *offset_p : (unsigned) -1;
-
- lto_streamer_cache_add_to_node_array (cache, ix, t, offset);
+ lto_streamer_cache_add_to_node_array (cache, ix, t);
/* Indicate that the item was not present in the cache. */
existed_p = false;
else
{
entry = (struct tree_int_map *) *slot;
- ix = (int) entry->to;
- offset = VEC_index (unsigned, cache->offsets, ix);
+ ix = entry->to;
if (!insert_at_next_slot_p && ix != *ix_p)
{
gcc_assert (lto_stream_as_builtin_p (t));
ix = *ix_p;
- /* Since we are storing a builtin, the offset into the
- stream is not necessary as we will not need to read
- forward in the stream. */
- lto_streamer_cache_add_to_node_array (cache, ix, t, -1);
+ lto_streamer_cache_add_to_node_array (cache, ix, t);
}
/* Indicate that T was already in the cache. */
if (ix_p)
*ix_p = ix;
- if (offset_p)
- *offset_p = offset;
-
return existed_p;
}
return true. Otherwise, return false.
If IX_P is non-null, update it with the index into the cache where
- T has been stored.
-
- *OFFSET_P represents the offset in the stream where T is physically
- written out. The first time T is added to the cache, *OFFSET_P is
- recorded in the cache together with T. But if T already existed
- in the cache, *OFFSET_P is updated with the value that was recorded
- the first time T was added to the cache.
-
- If OFFSET_P is NULL, it is ignored. */
+ T has been stored. */
bool
lto_streamer_cache_insert (struct lto_streamer_cache_d *cache, tree t,
- int *ix_p, unsigned *offset_p)
+ unsigned *ix_p)
{
- return lto_streamer_cache_insert_1 (cache, t, ix_p, offset_p, true);
+ return lto_streamer_cache_insert_1 (cache, t, ix_p, true);
}
bool
lto_streamer_cache_insert_at (struct lto_streamer_cache_d *cache,
- tree t, int ix)
+ tree t, unsigned ix)
{
- return lto_streamer_cache_insert_1 (cache, t, &ix, NULL, false);
+ return lto_streamer_cache_insert_1 (cache, t, &ix, false);
}
-/* Return true if tree node T exists in CACHE. If IX_P is
+/* Appends tree node T to CACHE, even if T already existed in it. */
+
+void
+lto_streamer_cache_append (struct lto_streamer_cache_d *cache, tree t)
+{
+ unsigned ix = VEC_length (tree, cache->nodes);
+ lto_streamer_cache_insert_1 (cache, t, &ix, false);
+}
+
+/* Return true if tree node T exists in CACHE, otherwise false. If IX_P is
not NULL, write to *IX_P the index into the cache where T is stored
- (-1 if T is not found). */
+ ((unsigned)-1 if T is not found). */
bool
lto_streamer_cache_lookup (struct lto_streamer_cache_d *cache, tree t,
- int *ix_p)
+ unsigned *ix_p)
{
void **slot;
struct tree_int_map d_slot;
bool retval;
- int ix;
+ unsigned ix;
gcc_assert (t);
else
{
retval = true;
- ix = (int) ((struct tree_int_map *) *slot)->to;
+ ix = ((struct tree_int_map *) *slot)->to;
}
if (ix_p)
/* Return the tree node at slot IX in CACHE. */
tree
-lto_streamer_cache_get (struct lto_streamer_cache_d *cache, int ix)
+lto_streamer_cache_get (struct lto_streamer_cache_d *cache, unsigned ix)
{
gcc_assert (cache);
- /* If the reader is requesting an index beyond the length of the
- cache, it will need to read ahead. Return NULL_TREE to indicate
- that. */
- if ((unsigned) ix >= VEC_length (tree, cache->nodes))
- return NULL_TREE;
+ /* Make sure we're not requesting something we don't have. */
+ gcc_assert (ix < VEC_length (tree, cache->nodes));
- return VEC_index (tree, cache->nodes, (unsigned) ix);
+ return VEC_index (tree, cache->nodes, ix);
}
VEC_safe_push (tree, heap, *common_nodes, node);
- if (tree_node_can_be_shared (node))
- {
- if (POINTER_TYPE_P (node)
- || TREE_CODE (node) == COMPLEX_TYPE
- || TREE_CODE (node) == ARRAY_TYPE)
- lto_record_common_node (&TREE_TYPE (node), common_nodes, seen_nodes);
- }
+ if (POINTER_TYPE_P (node)
+ || TREE_CODE (node) == COMPLEX_TYPE
+ || TREE_CODE (node) == ARRAY_TYPE)
+ lto_record_common_node (&TREE_TYPE (node), common_nodes, seen_nodes);
}
{
gcc_assert (t);
- lto_streamer_cache_insert (cache, t, NULL, NULL);
+ lto_streamer_cache_insert (cache, t, NULL);
/* The FIELD_DECLs of structures should be shared, so that every
COMPONENT_REF uses the same tree node when referencing a field.
htab_delete (c->node_map);
free_alloc_pool (c->node_map_entries);
VEC_free (tree, heap, c->nodes);
- VEC_free (unsigned, heap, c->offsets);
free (c);
}
/* Node map to store entries into. */
alloc_pool node_map_entries;
- /* Next available slot in the nodes and offsets arrays. */
- unsigned next_slot;
-
/* The nodes pickled so far. */
VEC(tree,heap) *nodes;
-
- /* Offset into the stream where the nodes have been written. */
- VEC(unsigned,heap) *offsets;
};
extern char *lto_get_section_name (int, const char *, struct lto_file_decl_data *);
extern void print_lto_report (void);
extern bool lto_streamer_cache_insert (struct lto_streamer_cache_d *, tree,
- int *, unsigned *);
+ unsigned *);
extern bool lto_streamer_cache_insert_at (struct lto_streamer_cache_d *, tree,
- int);
+ unsigned);
+extern void lto_streamer_cache_append (struct lto_streamer_cache_d *, tree);
extern bool lto_streamer_cache_lookup (struct lto_streamer_cache_d *, tree,
- int *);
-extern tree lto_streamer_cache_get (struct lto_streamer_cache_d *, int);
+ unsigned *);
+extern tree lto_streamer_cache_get (struct lto_streamer_cache_d *, unsigned);
extern struct lto_streamer_cache_d *lto_streamer_cache_create (void);
extern void lto_streamer_cache_delete (struct lto_streamer_cache_d *);
extern void lto_streamer_init (void);
+2011-04-03 Michael Matz <matz@suse.de>
+
+ * lto.c (lto_materialize_function): Don't read and then discard
+ sections in WPA mode.
+ (lto_read_in_decl_state): Adjust call to lto_streamer_cache_get.
+
+ * lto-lang.c (registered_builtin_fndecls): Remove.
+ (lto_getdecls): Return NULL_TREE.
+ (lto_builtin_function): Don't remember in registered_builtin_fndecls.
+
2011-03-31 Richard Guenther <rguenther@suse.de>
PR lto/48246
static GTY(()) tree registered_builtin_types;
-/* A chain of builtin functions that we need to recognize. We will
- assume that all other function names we see will be defined by the
- user's program. */
-static GTY(()) tree registered_builtin_fndecls;
-
/* Language hooks. */
static unsigned int
static tree
lto_getdecls (void)
{
- return registered_builtin_fndecls;
+ /* We have our own write_globals langhook, hence the getdecls
+ langhook shouldn't be used, except by dbxout.c, so we can't
+ just abort here. */
+ return NULL_TREE;
}
static void
static tree
lto_builtin_function (tree decl)
{
- /* Record it. */
- TREE_CHAIN (decl) = registered_builtin_fndecls;
- registered_builtin_fndecls = decl;
-
return decl;
}
/* Clones don't need to be read. */
if (node->clone_of)
return;
- file_data = node->local.lto_file_data;
- name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
-
- /* We may have renamed the declaration, e.g., a static function. */
- name = lto_get_decl_name_mapping (file_data, name);
-
- data = lto_get_section_data (file_data, LTO_section_function_body,
- name, &len);
- if (!data)
- fatal_error ("%s: section %s is missing",
- file_data->file_name,
- name);
-
- gcc_assert (DECL_STRUCT_FUNCTION (decl) == NULL);
/* Load the function body only if not operating in WPA mode. In
WPA mode, the body of the function is not needed. */
if (!flag_wpa)
{
+ file_data = node->local.lto_file_data;
+ name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+
+ /* We may have renamed the declaration, e.g., a static function. */
+ name = lto_get_decl_name_mapping (file_data, name);
+
+ data = lto_get_section_data (file_data, LTO_section_function_body,
+ name, &len);
+ if (!data)
+ fatal_error ("%s: section %s is missing",
+ file_data->file_name,
+ name);
+
+ gcc_assert (DECL_STRUCT_FUNCTION (decl) == NULL);
+
allocate_struct_function (decl, false);
announce_function (decl);
lto_input_function_body (file_data, decl, data);
if (DECL_FUNCTION_PERSONALITY (decl) && !first_personality_decl)
first_personality_decl = DECL_FUNCTION_PERSONALITY (decl);
lto_stats.num_function_bodies++;
+ lto_free_section_data (file_data, LTO_section_function_body, name,
+ data, len);
+ ggc_collect ();
}
-
- lto_free_section_data (file_data, LTO_section_function_body, name,
- data, len);
- if (!flag_wpa)
- ggc_collect ();
}
/* Let the middle end know about the function. */
uint32_t i, j;
ix = *data++;
- decl = lto_streamer_cache_get (data_in->reader_cache, (int) ix);
+ decl = lto_streamer_cache_get (data_in->reader_cache, ix);
if (TREE_CODE (decl) != FUNCTION_DECL)
{
gcc_assert (decl == void_type_node);
current module (shared library or executable), that is to binds_local_p.
We use this fact to avoid need for another target hook and implement
the logic using binds_local_p and just special cases where
- decl_binds_to_current_def_p is stronger than binds local_p. In particular
+ decl_binds_to_current_def_p is stronger than binds_local_p. In particular
the weak definitions (that can be overwritten at linktime by other
definition from different object file) and when resolution info is available
we simply use the knowledge passed to us by linker plugin. */
if (!targetm.binds_local_p (decl))
return false;
/* When resolution is available, just use it. */
- if (TREE_CODE (decl) == VAR_DECL && TREE_PUBLIC (decl)
+ if (TREE_CODE (decl) == VAR_DECL
&& (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
{
struct varpool_node *vnode = varpool_get_node (decl);
&& vnode->resolution != LDPR_UNKNOWN)
return resolution_to_local_definition_p (vnode->resolution);
}
- else if (TREE_CODE (decl) == FUNCTION_DECL && TREE_PUBLIC (decl))
+ else if (TREE_CODE (decl) == FUNCTION_DECL)
{
struct cgraph_node *node = cgraph_get_node_or_alias (decl);
if (node