mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-08 14:41:14 +08:00
IPA REF alias refactoring
* cgraph.h (iterate_direct_aliases): New function. (FOR_EACH_ALIAS): New macro iterates all direct aliases for a node. * cgraph.c (cgraph_for_node_thunks_and_aliases): Usage of FOR_EACH_ALIAS added. (cgraph_for_node_and_aliases): Likewise. * cgraphunit.c (assemble_thunks_and_aliases): Likewise. * ipa-inline.c (reset_edge_caches): Likewise. (update_caller_keys): Likewise. * trans-mem.c (ipa_tm_execute): Likewise. *varpool.c (varpool_analyze_node): Likewise. (varpool_for_node_and_aliases): Likewise. * ipa-ref.h (first_alias): New function. (last_alias): Likewise. (has_aliases_p): Likewise. * ipa-ref.c (ipa_ref::remove_reference): Removal function is sensitive to IPA_REF_ALIASes. * symtab.c (symtab_node::add_reference): Node of IPA_REF_ALIAS type are put at the beginning of the list. (symtab_node::iterate_direct_aliases): New function. * lto-partition.c (add_symbol_to_partition_1): Usage of FOR_EACH_ALIAS added. From-SVN: r212191
This commit is contained in:
parent
705c7d5709
commit
e55637b715
@ -1,3 +1,26 @@
|
||||
2014-07-01 Martin Liska <mliska@suse.cz>
|
||||
|
||||
IPA REF alias refactoring
|
||||
* cgraph.h (iterate_direct_aliases): New function.
|
||||
(FOR_EACH_ALIAS): New macro iterates all direct aliases for a node.
|
||||
* cgraph.c (cgraph_for_node_thunks_and_aliases): Usage of
|
||||
FOR_EACH_ALIAS added.
|
||||
(cgraph_for_node_and_aliases): Likewise.
|
||||
* cgraphunit.c (assemble_thunks_and_aliases): Likewise.
|
||||
* ipa-inline.c (reset_edge_caches): Likewise.
|
||||
(update_caller_keys): Likewise.
|
||||
* trans-mem.c (ipa_tm_execute): Likewise.
|
||||
*varpool.c (varpool_analyze_node): Likewise.
|
||||
(varpool_for_node_and_aliases): Likewise.
|
||||
* ipa-ref.h (first_alias): New function.
|
||||
(last_alias): Likewise.
|
||||
(has_aliases_p): Likewise.
|
||||
* ipa-ref.c (ipa_ref::remove_reference): Removal function
|
||||
is sensitive to IPA_REF_ALIASes.
|
||||
* symtab.c (symtab_node::add_reference): Node of IPA_REF_ALIAS type
|
||||
are put at the beginning of the list.
|
||||
(symtab_node::iterate_direct_aliases): New function.
|
||||
|
||||
2014-06-28 Jan Hubicka <hubicka@ucw.cz>
|
||||
|
||||
Revert:
|
||||
|
46
gcc/cgraph.c
46
gcc/cgraph.c
@ -2198,8 +2198,7 @@ cgraph_for_node_thunks_and_aliases (struct cgraph_node *node,
|
||||
bool include_overwritable)
|
||||
{
|
||||
struct cgraph_edge *e;
|
||||
int i;
|
||||
struct ipa_ref *ref = NULL;
|
||||
struct ipa_ref *ref;
|
||||
|
||||
if (callback (node, data))
|
||||
return true;
|
||||
@ -2210,16 +2209,16 @@ cgraph_for_node_thunks_and_aliases (struct cgraph_node *node,
|
||||
if (cgraph_for_node_thunks_and_aliases (e->caller, callback, data,
|
||||
include_overwritable))
|
||||
return true;
|
||||
for (i = 0; node->iterate_referring (i, ref); i++)
|
||||
if (ref->use == IPA_REF_ALIAS)
|
||||
{
|
||||
struct cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
|
||||
if (include_overwritable
|
||||
|| cgraph_function_body_availability (alias) > AVAIL_OVERWRITABLE)
|
||||
if (cgraph_for_node_thunks_and_aliases (alias, callback, data,
|
||||
include_overwritable))
|
||||
return true;
|
||||
}
|
||||
|
||||
FOR_EACH_ALIAS (node, ref)
|
||||
{
|
||||
struct cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
|
||||
if (include_overwritable
|
||||
|| cgraph_function_body_availability (alias) > AVAIL_OVERWRITABLE)
|
||||
if (cgraph_for_node_thunks_and_aliases (alias, callback, data,
|
||||
include_overwritable))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2233,21 +2232,20 @@ cgraph_for_node_and_aliases (struct cgraph_node *node,
|
||||
void *data,
|
||||
bool include_overwritable)
|
||||
{
|
||||
int i;
|
||||
struct ipa_ref *ref = NULL;
|
||||
struct ipa_ref *ref;
|
||||
|
||||
if (callback (node, data))
|
||||
return true;
|
||||
for (i = 0; node->iterate_referring (i, ref); i++)
|
||||
if (ref->use == IPA_REF_ALIAS)
|
||||
{
|
||||
struct cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
|
||||
if (include_overwritable
|
||||
|| cgraph_function_body_availability (alias) > AVAIL_OVERWRITABLE)
|
||||
if (cgraph_for_node_and_aliases (alias, callback, data,
|
||||
include_overwritable))
|
||||
return true;
|
||||
}
|
||||
|
||||
FOR_EACH_ALIAS (node, ref)
|
||||
{
|
||||
struct cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
|
||||
if (include_overwritable
|
||||
|| cgraph_function_body_availability (alias) > AVAIL_OVERWRITABLE)
|
||||
if (cgraph_for_node_and_aliases (alias, callback, data,
|
||||
include_overwritable))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -254,6 +254,9 @@ public:
|
||||
/* Iterates I-th referring item in the list, REF is also set. */
|
||||
struct ipa_ref *iterate_referring (unsigned i, struct ipa_ref *&ref);
|
||||
|
||||
/* Iterates I-th referring alias item in the list, REF is also set. */
|
||||
struct ipa_ref *iterate_direct_aliases (unsigned i, struct ipa_ref *&ref);
|
||||
|
||||
/* Vectors of referring and referenced entities. */
|
||||
struct ipa_ref_list ref_list;
|
||||
|
||||
@ -281,6 +284,10 @@ public:
|
||||
priority_type get_init_priority ();
|
||||
};
|
||||
|
||||
/* Walk all aliases for NODE. */
|
||||
#define FOR_EACH_ALIAS(node, alias) \
|
||||
for (unsigned x_i = 0; node->iterate_direct_aliases (x_i, alias); x_i++)
|
||||
|
||||
enum availability
|
||||
{
|
||||
/* Not yet set by cgraph_function_body_availability. */
|
||||
|
@ -1711,8 +1711,7 @@ static void
|
||||
assemble_thunks_and_aliases (struct cgraph_node *node)
|
||||
{
|
||||
struct cgraph_edge *e;
|
||||
int i;
|
||||
struct ipa_ref *ref = NULL;
|
||||
struct ipa_ref *ref;
|
||||
|
||||
for (e = node->callers; e;)
|
||||
if (e->caller->thunk.thunk_p)
|
||||
@ -1725,20 +1724,20 @@ assemble_thunks_and_aliases (struct cgraph_node *node)
|
||||
}
|
||||
else
|
||||
e = e->next_caller;
|
||||
for (i = 0; node->iterate_referring (i, ref); i++)
|
||||
if (ref->use == IPA_REF_ALIAS)
|
||||
{
|
||||
struct cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
|
||||
bool saved_written = TREE_ASM_WRITTEN (node->decl);
|
||||
|
||||
/* Force assemble_alias to really output the alias this time instead
|
||||
of buffering it in same alias pairs. */
|
||||
TREE_ASM_WRITTEN (node->decl) = 1;
|
||||
do_assemble_alias (alias->decl,
|
||||
DECL_ASSEMBLER_NAME (node->decl));
|
||||
assemble_thunks_and_aliases (alias);
|
||||
TREE_ASM_WRITTEN (node->decl) = saved_written;
|
||||
}
|
||||
FOR_EACH_ALIAS (node, ref)
|
||||
{
|
||||
struct cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
|
||||
bool saved_written = TREE_ASM_WRITTEN (node->decl);
|
||||
|
||||
/* Force assemble_alias to really output the alias this time instead
|
||||
of buffering it in same alias pairs. */
|
||||
TREE_ASM_WRITTEN (node->decl) = 1;
|
||||
do_assemble_alias (alias->decl,
|
||||
DECL_ASSEMBLER_NAME (node->decl));
|
||||
assemble_thunks_and_aliases (alias);
|
||||
TREE_ASM_WRITTEN (node->decl) = saved_written;
|
||||
}
|
||||
}
|
||||
|
||||
/* Expand function specified by NODE. */
|
||||
|
@ -1119,8 +1119,7 @@ reset_edge_caches (struct cgraph_node *node)
|
||||
struct cgraph_edge *edge;
|
||||
struct cgraph_edge *e = node->callees;
|
||||
struct cgraph_node *where = node;
|
||||
int i;
|
||||
struct ipa_ref *ref = NULL;
|
||||
struct ipa_ref *ref;
|
||||
|
||||
if (where->global.inlined_to)
|
||||
where = where->global.inlined_to;
|
||||
@ -1131,9 +1130,9 @@ reset_edge_caches (struct cgraph_node *node)
|
||||
for (edge = where->callers; edge; edge = edge->next_caller)
|
||||
if (edge->inline_failed)
|
||||
reset_edge_growth_cache (edge);
|
||||
for (i = 0; where->iterate_referring (i, ref); i++)
|
||||
if (ref->use == IPA_REF_ALIAS)
|
||||
reset_edge_caches (dyn_cast <cgraph_node *> (ref->referring));
|
||||
|
||||
FOR_EACH_ALIAS (where, ref)
|
||||
reset_edge_caches (dyn_cast <cgraph_node *> (ref->referring));
|
||||
|
||||
if (!e)
|
||||
return;
|
||||
@ -1172,8 +1171,7 @@ update_caller_keys (fibheap_t heap, struct cgraph_node *node,
|
||||
struct cgraph_edge *check_inlinablity_for)
|
||||
{
|
||||
struct cgraph_edge *edge;
|
||||
int i;
|
||||
struct ipa_ref *ref = NULL;
|
||||
struct ipa_ref *ref;
|
||||
|
||||
if ((!node->alias && !inline_summary (node)->inlinable)
|
||||
|| node->global.inlined_to)
|
||||
@ -1181,12 +1179,11 @@ update_caller_keys (fibheap_t heap, struct cgraph_node *node,
|
||||
if (!bitmap_set_bit (updated_nodes, node->uid))
|
||||
return;
|
||||
|
||||
for (i = 0; node->iterate_referring (i, ref); i++)
|
||||
if (ref->use == IPA_REF_ALIAS)
|
||||
{
|
||||
struct cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
|
||||
update_caller_keys (heap, alias, updated_nodes, check_inlinablity_for);
|
||||
}
|
||||
FOR_EACH_ALIAS (node, ref)
|
||||
{
|
||||
struct cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
|
||||
update_caller_keys (heap, alias, updated_nodes, check_inlinablity_for);
|
||||
}
|
||||
|
||||
for (edge = node->callers; edge; edge = edge->next_caller)
|
||||
if (edge->inline_failed)
|
||||
|
@ -38,12 +38,33 @@ ipa_ref::remove_reference ()
|
||||
struct ipa_ref *last;
|
||||
|
||||
gcc_assert (list->referring[referred_index] == this);
|
||||
|
||||
last = list->referring.last ();
|
||||
if (this != last)
|
||||
{
|
||||
if (use == IPA_REF_ALIAS)
|
||||
{
|
||||
/* If deleted item is IPA_REF_ALIAS, we have to move last
|
||||
item of IPA_REF_LIST type to the deleted position. After that
|
||||
we replace last node with deletion slot. */
|
||||
struct ipa_ref *last_alias = list->last_alias ();
|
||||
|
||||
if (last_alias && referred_index < last_alias->referred_index
|
||||
&& last_alias != last)
|
||||
{
|
||||
unsigned last_alias_index = last_alias->referred_index;
|
||||
|
||||
list->referring[referred_index] = last_alias;
|
||||
list->referring[referred_index]->referred_index = referred_index;
|
||||
|
||||
/* New position for replacement is previous index
|
||||
of the last_alias. */
|
||||
referred_index = last_alias_index;
|
||||
}
|
||||
}
|
||||
|
||||
list->referring[referred_index] = list->referring.last ();
|
||||
list->referring[referred_index]->referred_index
|
||||
= referred_index;
|
||||
list->referring[referred_index]->referred_index= referred_index;
|
||||
}
|
||||
list->referring.pop ();
|
||||
|
||||
@ -54,7 +75,7 @@ ipa_ref::remove_reference ()
|
||||
if (ref != last)
|
||||
{
|
||||
*ref = *last;
|
||||
referred_ref_list ()->referring[referred_index] = ref;
|
||||
ref->referred_ref_list ()->referring[referred_index] = ref;
|
||||
}
|
||||
list2->references->pop ();
|
||||
gcc_assert (list2->references == old_references);
|
||||
|
@ -82,6 +82,32 @@ public:
|
||||
return referring[0];
|
||||
}
|
||||
|
||||
/* Return first referring alias. */
|
||||
struct ipa_ref *first_alias (void)
|
||||
{
|
||||
struct ipa_ref *r = first_referring ();
|
||||
|
||||
return r && r->use == IPA_REF_ALIAS ? r : NULL;
|
||||
}
|
||||
|
||||
/* Return last referring alias. */
|
||||
struct ipa_ref *last_alias (void)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
|
||||
for(i = 0; i < referring.length (); i++)
|
||||
if (referring[i]->use != IPA_REF_ALIAS)
|
||||
break;
|
||||
|
||||
return i == 0 ? NULL : referring[i - 1];
|
||||
}
|
||||
|
||||
/* Return true if the symbol has an alias. */
|
||||
bool inline has_aliases_p (void)
|
||||
{
|
||||
return first_alias ();
|
||||
}
|
||||
|
||||
/* Clear reference list. */
|
||||
void clear (void)
|
||||
{
|
||||
|
@ -1,3 +1,9 @@
|
||||
2014-07-01 Martin Liska <mliska@suse.cz>
|
||||
|
||||
IPA REF alias refactoring
|
||||
* lto-partition.c (add_symbol_to_partition_1): Usage of
|
||||
FOR_EACH_ALIAS added.
|
||||
|
||||
2014-06-28 Jan Hubicka <hubicka@ucw.cz>
|
||||
|
||||
Revert:
|
||||
|
@ -113,8 +113,7 @@ static bool
|
||||
add_symbol_to_partition_1 (ltrans_partition part, symtab_node *node)
|
||||
{
|
||||
enum symbol_partitioning_class c = symtab_get_symbol_partitioning_class (node);
|
||||
int i;
|
||||
struct ipa_ref *ref = NULL;
|
||||
struct ipa_ref *ref;
|
||||
symtab_node *node1;
|
||||
|
||||
/* If NODE is already there, we have nothing to do. */
|
||||
@ -168,8 +167,9 @@ add_symbol_to_partition_1 (ltrans_partition part, symtab_node *node)
|
||||
add_references_to_partition (part, node);
|
||||
|
||||
/* Add all aliases associated with the symbol. */
|
||||
for (i = 0; node->iterate_referring (i, ref); i++)
|
||||
if (ref->use == IPA_REF_ALIAS && !node->weakref)
|
||||
|
||||
FOR_EACH_ALIAS (node, ref)
|
||||
if (!node->weakref)
|
||||
add_symbol_to_partition_1 (part, ref->referring);
|
||||
|
||||
/* Ensure that SAME_COMDAT_GROUP lists all allways added in a group. */
|
||||
|
32
gcc/symtab.c
32
gcc/symtab.c
@ -558,8 +558,22 @@ symtab_node::add_reference (symtab_node *referred_node,
|
||||
ref = &list->references->last ();
|
||||
|
||||
list2 = &referred_node->ref_list;
|
||||
list2->referring.safe_push (ref);
|
||||
ref->referred_index = list2->referring.length () - 1;
|
||||
|
||||
/* IPA_REF_ALIAS is always inserted at the beginning of the list. */
|
||||
if(use_type == IPA_REF_ALIAS)
|
||||
{
|
||||
list2->referring.safe_insert (0, ref);
|
||||
ref->referred_index = 0;
|
||||
|
||||
for (unsigned int i = 1; i < list2->referring.length (); i++)
|
||||
list2->referring[i]->referred_index = i;
|
||||
}
|
||||
else
|
||||
{
|
||||
list2->referring.safe_push (ref);
|
||||
ref->referred_index = list2->referring.length () - 1;
|
||||
}
|
||||
|
||||
ref->referring = this;
|
||||
ref->referred = referred_node;
|
||||
ref->stmt = stmt;
|
||||
@ -796,6 +810,20 @@ symtab_node::iterate_referring (unsigned i, struct ipa_ref *&ref)
|
||||
return ref;
|
||||
}
|
||||
|
||||
/* Iterates I-th referring alias item in the list, REF is also set. */
|
||||
|
||||
struct ipa_ref *
|
||||
symtab_node::iterate_direct_aliases (unsigned i, struct ipa_ref *&ref)
|
||||
{
|
||||
ref_list.referring.iterate (i, &ref);
|
||||
|
||||
if (ref && ref->use != IPA_REF_ALIAS)
|
||||
return NULL;
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
|
||||
static const char * const symtab_type_names[] = {"symbol", "function", "variable"};
|
||||
|
||||
/* Dump base fields of symtab nodes. Not to be used directly. */
|
||||
|
@ -5439,8 +5439,7 @@ ipa_tm_execute (void)
|
||||
{
|
||||
struct cgraph_node *caller;
|
||||
struct cgraph_edge *e;
|
||||
struct ipa_ref *ref = NULL;
|
||||
unsigned j;
|
||||
struct ipa_ref *ref;
|
||||
|
||||
if (i > 256 && i == irr_worklist.length () / 8)
|
||||
{
|
||||
@ -5466,11 +5465,10 @@ ipa_tm_execute (void)
|
||||
}
|
||||
|
||||
/* Propagate back to referring aliases as well. */
|
||||
for (j = 0; node->iterate_referring (j, ref); j++)
|
||||
FOR_EACH_ALIAS (node, ref)
|
||||
{
|
||||
caller = cgraph (ref->referring);
|
||||
if (ref->use == IPA_REF_ALIAS
|
||||
&& !caller->local.tm_may_enter_irr)
|
||||
if (!caller->local.tm_may_enter_irr)
|
||||
{
|
||||
/* ?? Do not traverse aliases here. */
|
||||
d = get_cg_data (&caller, false);
|
||||
|
@ -424,17 +424,15 @@ varpool_analyze_node (varpool_node *node)
|
||||
static void
|
||||
assemble_aliases (varpool_node *node)
|
||||
{
|
||||
int i;
|
||||
struct ipa_ref *ref = NULL;
|
||||
struct ipa_ref *ref;
|
||||
|
||||
for (i = 0; node->iterate_referring (i, ref); i++)
|
||||
if (ref->use == IPA_REF_ALIAS)
|
||||
{
|
||||
varpool_node *alias = dyn_cast <varpool_node *> (ref->referring);
|
||||
do_assemble_alias (alias->decl,
|
||||
DECL_ASSEMBLER_NAME (node->decl));
|
||||
assemble_aliases (alias);
|
||||
}
|
||||
FOR_EACH_ALIAS (node, ref)
|
||||
{
|
||||
varpool_node *alias = dyn_cast <varpool_node *> (ref->referring);
|
||||
do_assemble_alias (alias->decl,
|
||||
DECL_ASSEMBLER_NAME (node->decl));
|
||||
assemble_aliases (alias);
|
||||
}
|
||||
}
|
||||
|
||||
/* Output one variable, if necessary. Return whether we output it. */
|
||||
@ -694,20 +692,19 @@ varpool_for_node_and_aliases (varpool_node *node,
|
||||
void *data,
|
||||
bool include_overwritable)
|
||||
{
|
||||
int i;
|
||||
struct ipa_ref *ref = NULL;
|
||||
struct ipa_ref *ref;
|
||||
|
||||
if (callback (node, data))
|
||||
return true;
|
||||
for (i = 0; node->iterate_referring (i, ref); i++)
|
||||
if (ref->use == IPA_REF_ALIAS)
|
||||
{
|
||||
varpool_node *alias = dyn_cast <varpool_node *> (ref->referring);
|
||||
if (include_overwritable
|
||||
|| cgraph_variable_initializer_availability (alias) > AVAIL_OVERWRITABLE)
|
||||
if (varpool_for_node_and_aliases (alias, callback, data,
|
||||
include_overwritable))
|
||||
return true;
|
||||
}
|
||||
|
||||
FOR_EACH_ALIAS (node, ref)
|
||||
{
|
||||
varpool_node *alias = dyn_cast <varpool_node *> (ref->referring);
|
||||
if (include_overwritable
|
||||
|| cgraph_variable_initializer_availability (alias) > AVAIL_OVERWRITABLE)
|
||||
if (varpool_for_node_and_aliases (alias, callback, data,
|
||||
include_overwritable))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user