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:
Martin Liska 2014-07-01 08:45:26 +02:00 committed by Martin Liska
parent 705c7d5709
commit e55637b715
12 changed files with 188 additions and 88 deletions

View File

@ -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:

View File

@ -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;
}

View File

@ -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. */

View File

@ -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. */

View File

@ -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)

View File

@ -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);

View File

@ -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)
{

View File

@ -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:

View File

@ -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. */

View File

@ -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. */

View File

@ -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);

View File

@ -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;
}