* [PATCH] IPA REF: alias refactoring
@ 2014-06-27 10:05 Martin Liška
2014-06-28 6:50 ` Jan Hubicka
0 siblings, 1 reply; 5+ messages in thread
From: Martin Liška @ 2014-06-27 10:05 UTC (permalink / raw)
To: GCC Patches
[-- Attachment #1: Type: text/plain, Size: 1318 bytes --]
Hi,
this patch enhances alias manipulation for symtab_node. Honza suggested following changes.
Patch is pre approved, will be committed if no comments and regressions.
Bootstrapped on x86_64-pc-linux-gnu, regression tests have been running.
Thanks,
Martin
gcc/ChangeLog:
* 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_referring_alias): New function.
(last_referring_alias): 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.
gcc/lto/ChangeLog:
* lto-partition.c (add_symbol_to_partition_1): Usage of
FOR_EACH_ALIAS added.
[-- Attachment #2: ipa-ref-alias.patch --]
[-- Type: text/x-patch, Size: 13658 bytes --]
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 7360f77..568eb45 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -2194,8 +2194,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;
@@ -2206,16 +2205,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;
}
@@ -2229,21 +2228,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;
}
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 0761e26..3ab0516 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -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. */
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 76b2fda1..b0478cb 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -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. */
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index 81030f3..c4095ec 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -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)
diff --git a/gcc/ipa-ref.c b/gcc/ipa-ref.c
index 1be173a..8df6b81 100644
--- a/gcc/ipa-ref.c
+++ b/gcc/ipa-ref.c
@@ -38,12 +38,23 @@ ipa_ref::remove_reference ()
struct ipa_ref *last;
gcc_assert (list->referring[referred_index] == this);
+
last = list->referring.last ();
if (this != last)
{
+ /* 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_referring_alias ();
+
+ if (last_alias && referred_index < last_alias->referred_index)
+ {
+ list->referring[referred_index] = last_alias;
+ list->referring[referred_index]->referred_index = referred_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 ();
diff --git a/gcc/ipa-ref.h b/gcc/ipa-ref.h
index d2de006..65f1f30 100644
--- a/gcc/ipa-ref.h
+++ b/gcc/ipa-ref.h
@@ -82,6 +82,26 @@ public:
return referring[0];
}
+ /* Return first referring alias. */
+ struct ipa_ref *first_referring_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_referring_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];
+ }
+
/* Clear reference list. */
void clear (void)
{
diff --git a/gcc/lto/lto-partition.c b/gcc/lto/lto-partition.c
index 4d19ef6..944943c 100644
--- a/gcc/lto/lto-partition.c
+++ b/gcc/lto/lto-partition.c
@@ -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. */
diff --git a/gcc/symtab.c b/gcc/symtab.c
index 89591ee..fd83604 100644
--- a/gcc/symtab.c
+++ b/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 put 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. */
diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c
index af8bc09..12c0b35 100644
--- a/gcc/trans-mem.c
+++ b/gcc/trans-mem.c
@@ -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);
diff --git a/gcc/varpool.c b/gcc/varpool.c
index 04ac870..79f07bf 100644
--- a/gcc/varpool.c
+++ b/gcc/varpool.c
@@ -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;
}
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] IPA REF: alias refactoring
2014-06-27 10:05 [PATCH] IPA REF: alias refactoring Martin Liška
@ 2014-06-28 6:50 ` Jan Hubicka
2014-06-30 21:17 ` Martin Liška
0 siblings, 1 reply; 5+ messages in thread
From: Jan Hubicka @ 2014-06-28 6:50 UTC (permalink / raw)
To: Martin Liška; +Cc: GCC Patches
> Hi,
> this patch enhances alias manipulation for symtab_node. Honza suggested following changes.
>
> Patch is pre approved, will be committed if no comments and regressions.
> Bootstrapped on x86_64-pc-linux-gnu, regression tests have been running.
>
> Thanks,
> Martin
>
> gcc/ChangeLog:
>
> * 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_referring_alias): New function.
> (last_referring_alias): Likewise.
I missed it last time around, I think first_alias/last_alias are better names.
first_alias is unused. If you added it I guess FOR_EACH_ALIAS should use it.
We probably also can bring has_aliases_p inline and implement it using
first_referring_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_referring_alias ();
You can avoid walking to last alias when the removed item is not IPA_REF_ALIAS.
> +
> + /* IPA_REF_ALIAS is always put at the beginning of the list. */
inserted?
OK with these changes (or if you already comitted, just do them incrementally)
Honza
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] IPA REF: alias refactoring
2014-06-28 6:50 ` Jan Hubicka
@ 2014-06-30 21:17 ` Martin Liška
2014-06-30 22:21 ` Jan Hubicka
0 siblings, 1 reply; 5+ messages in thread
From: Martin Liška @ 2014-06-30 21:17 UTC (permalink / raw)
To: Jan Hubicka; +Cc: GCC Patches
[-- Attachment #1: Type: text/plain, Size: 3222 bytes --]
On 06/28/2014 08:49 AM, Jan Hubicka wrote:
>> Hi,
>> this patch enhances alias manipulation for symtab_node. Honza suggested following changes.
>>
>> Patch is pre approved, will be committed if no comments and regressions.
>> Bootstrapped on x86_64-pc-linux-gnu, regression tests have been running.
>>
>> Thanks,
>> Martin
>>
>> gcc/ChangeLog:
>>
>> * 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_referring_alias): New function.
>> (last_referring_alias): Likewise.
> I missed it last time around, I think first_alias/last_alias are better names.
> first_alias is unused. If you added it I guess FOR_EACH_ALIAS should use it.
Hello,
I renamed these functions as you suggested and has_aliases_p
predication was also added.
Previous patch has an error in ipa_ref::remove_refence, this patch has
been regtested and the problem is removed.
>
> We probably also can bring has_aliases_p inline and implement it using
> first_referring_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_referring_alias ();
> You can avoid walking to last alias when the removed item is not IPA_REF_ALIAS.
>
>> +
>> + /* IPA_REF_ALIAS is always put at the beginning of the list. */
> inserted?
Type fixed.
If no other comments will come, I consider the patch as preapproved.
Thanks,
Martin
gcc/ChangeLog:
* 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.
gcc/lto/ChangeLog:
* lto-partition.c (add_symbol_to_partition_1): Usage of
FOR_EACH_ALIAS added.
>
> OK with these changes (or if you already comitted, just do them incrementally)
>
> Honza
[-- Attachment #2: ipa-ref-alias4.patch --]
[-- Type: text/x-patch, Size: 14318 bytes --]
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 43428be..41dcaf9 100644
--- a/gcc/cgraph.c
+++ b/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;
}
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 0761e26..3ab0516 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -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. */
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index d7e8038..f7980ed 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -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. */
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index 81030f3..c4095ec 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -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)
diff --git a/gcc/ipa-ref.c b/gcc/ipa-ref.c
index 1be173a..3c10011 100644
--- a/gcc/ipa-ref.c
+++ b/gcc/ipa-ref.c
@@ -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);
diff --git a/gcc/ipa-ref.h b/gcc/ipa-ref.h
index d2de006..b8b1f9e 100644
--- a/gcc/ipa-ref.h
+++ b/gcc/ipa-ref.h
@@ -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)
{
diff --git a/gcc/lto/lto-partition.c b/gcc/lto/lto-partition.c
index 4d19ef6..944943c 100644
--- a/gcc/lto/lto-partition.c
+++ b/gcc/lto/lto-partition.c
@@ -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. */
diff --git a/gcc/symtab.c b/gcc/symtab.c
index 89591ee..80ea94a 100644
--- a/gcc/symtab.c
+++ b/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. */
diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c
index af8bc09..12c0b35 100644
--- a/gcc/trans-mem.c
+++ b/gcc/trans-mem.c
@@ -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);
diff --git a/gcc/varpool.c b/gcc/varpool.c
index 04ac870..79f07bf 100644
--- a/gcc/varpool.c
+++ b/gcc/varpool.c
@@ -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;
}
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] IPA REF: alias refactoring
2014-06-30 21:17 ` Martin Liška
@ 2014-06-30 22:21 ` Jan Hubicka
2014-07-01 6:48 ` Martin Liška
0 siblings, 1 reply; 5+ messages in thread
From: Jan Hubicka @ 2014-06-30 22:21 UTC (permalink / raw)
To: Martin Liška; +Cc: Jan Hubicka, GCC Patches
>
> gcc/ChangeLog:
>
> * 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.
>
> gcc/lto/ChangeLog:
>
> * lto-partition.c (add_symbol_to_partition_1): Usage of
> FOR_EACH_ALIAS added.
OK, thanks!
Honza
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] IPA REF: alias refactoring
2014-06-30 22:21 ` Jan Hubicka
@ 2014-07-01 6:48 ` Martin Liška
0 siblings, 0 replies; 5+ messages in thread
From: Martin Liška @ 2014-07-01 6:48 UTC (permalink / raw)
To: gcc-patches
On 07/01/2014 12:21 AM, Jan Hubicka wrote:
>> gcc/ChangeLog:
>>
>> * 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.
>>
>> gcc/lto/ChangeLog:
>>
>> * lto-partition.c (add_symbol_to_partition_1): Usage of
>> FOR_EACH_ALIAS added.
> OK, thanks!
>
> Honza
Thanks,
patch has been just commited.
Martin
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2014-07-01 6:48 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-06-27 10:05 [PATCH] IPA REF: alias refactoring Martin Liška
2014-06-28 6:50 ` Jan Hubicka
2014-06-30 21:17 ` Martin Liška
2014-06-30 22:21 ` Jan Hubicka
2014-07-01 6:48 ` Martin Liška
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).